Tk Source Code

Changes On Branch core-8-5-branch
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch core-8-5-branch Excluding Merge-Ins

This is equivalent to a diff from 32a9cba038 to cb795a3445

2023-09-21
11:53
Remove .github and .travis-related stuff: No need to build this branch any more Leaf check-in: cb795a3445 user: jan.nijtmans tags: core-8-5-branch
2022-12-02
22:31
upload-artifact@v3 check-in: dd18e6dd37 user: jan.nijtmans tags: core-8-5-branch
2020-10-27
07:08
Rename "trunk" to "main". Add "trunk" propagating tag for backwards compatibility check-in: 0f77b70d50 user: jan.nijtmans tags: trunk, main
01:25
Merge 8.6 Closed-Leaf check-in: 32a9cba038 user: marc_culler tags: trunk
2020-10-26
08:58
Merge 8.6 check-in: 88e0ce578b user: jan.nijtmans tags: trunk
2020-10-25
20:11
Adjustment for Sierra. Closed-Leaf check-in: 77a51c320b user: culler tags: bug-5cc72e002c

Deleted .fossil-settings/crlf-glob.

1
2
win/*.bat
win/*.vc
<
<




Changes to .fossil-settings/crnl-glob.




1
2




win/*.bat
win/*.vc

>
>
>
|
|
>
1
2
3
4
5
6
win/buildall.vc.bat
win/makefile.bc
win/makefile.vc
win/mkd.bat
win/rmd.bat
win/rules.vc

Changes to .fossil-settings/encoding-glob.

1

2

3
4
5
6
7
8
9
win/buildall.vc.bat

win/makefile.vc

win/rules-ext.vc
win/rules.vc
win/targets.vc
win/rc/*.bmp
win/rc/*.cur
win/rc/*.ico
win/rc/*.rc

>

>
|

<




1
2
3
4
5
6

7
8
9
10
win/buildall.vc.bat
win/makefile.bc
win/makefile.vc
win/mkd.bat
win/rmd.bat
win/rules.vc

win/rc/*.bmp
win/rc/*.cur
win/rc/*.ico
win/rc/*.rc

Changes to .fossil-settings/ignore-glob.

16
17
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest*
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk_*.zip


html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out







|



|
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
doc/man.macros
html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out

Changes to .gitignore.

22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
config.status
config.status.lineno
html
manifest.uuid
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest*
*/versions.vc
*/version.vc
*/libtcl.vfs
*/libtcl_*.zip

libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl







|


|
|
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
config.status
config.status.lineno
html
manifest.uuid
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl

Changes to .project.

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>tk8.7</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
	</buildSpec>
	<natures>
	</natures>


|







1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>tk8.5</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
	</buildSpec>
	<natures>
	</natures>

Deleted .travis.yml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
language: c
addons:
  apt:
    sources:
      - ubuntu-toolchain-r-test
    packages:
      - binutils-mingw-w64-i686
      - binutils-mingw-w64-x86-64
      - gcc-mingw-w64
      - gcc-mingw-w64-base
      - gcc-mingw-w64-i686
      - gcc-mingw-w64-x86-64
      - gcc-multilib
      - tcl8.6-dev
      - libx11-dev
      - xvfb
  homebrew:
    packages:
      - tcl-tk
    casks:
      - xquartz
jobs:
  include:
# Testing on Linux GCC
    - name: "Linux/GCC/Shared"
      os: linux
      dist: focal
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
      script: &x11gui
        - make binaries libraries tktest
        - make install
        - make test-classic >out-classic.txt
        - cat out-classic.txt
        - grep -q "Failed	0" out-classic.txt
        - make test-ttk >out-ttk.txt
        - cat out-ttk.txt
        - grep -q "Failed	0" out-ttk.txt
    - name: "Linux/GCC/Shared: NO_DEPRECATED"
      os: linux
      dist: focal
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="CFLAGS=-DTK_NO_DEPRECATED=1"
      script: *x11gui
    - name: "Linux/GCC/Shared/no-xft"
      os: linux
      dist: focal
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-xft"
      script: *x11gui
    - name: "Linux/GCC/Shared/bionic"
      os: linux
      dist: bionic
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
      script: *x11gui
    - name: "Linux/GCC/Shared/xenial"
      os: linux
      dist: xenial
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
      script: *x11gui
    - name: "Linux/GCC/Static"
      os: linux
      dist: focal
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-shared"
    - name: "Linux/GCC/Debug"
      os: linux
      dist: focal
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--enable-symbols"
    - name: "Linux/G++/Shared"
      os: linux
      dist: focal
      compiler: g++
      env:
        - BUILD_DIR=unix
        - CFGOPT="CC=g++ CFLAGS=-Dregister=dont+use+register"
    - name: "Linux/G++/Shared UTF_MAX=4"
      os: linux
      dist: focal
      compiler: g++
      env:
        - BUILD_DIR=unix
        - CFGOPT="CC=g++ CFLAGS=-DTCL_UTF_MAX=4"
    - name: "Linux/G++/Shared UTF_MAX=6"
      os: linux
      dist: focal
      compiler: g++
      env:
        - BUILD_DIR=unix
        - CFGOPT="CC=g++ CFLAGS=-DTCL_UTF_MAX=6"
# Newer/Older versions of GCC
    - name: "Linux/GCC 10/Shared"
      os: linux
      dist: focal
      compiler: gcc-10
      addons:
        apt:
          packages:
            - g++-10
      env:
        - BUILD_DIR=unix
    - name: "Linux/GCC 5/Shared"
      os: linux
      dist: bionic
      compiler: gcc-5
      addons:
        apt:
          packages:
            - g++-5
      env:
        - BUILD_DIR=unix
# Testing on Linux Clang
    - name: "Linux/Clang/Shared"
      os: linux
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
    - name: "Linux/Clang/Shared: NO_DEPRECATED"
      os: linux
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="CFLAGS=-DTK_NO_DEPRECATED=1"
    - name: "Linux/Clang/Shared/no-xft"
      os: linux
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-xft"
    - name: "Linux/Clang/Static"
      os: linux
      dist: focal
      compiler: clang
      env:
        - CFGOPT="--disable-shared"
        - BUILD_DIR=unix
    - name: "Linux/Clang/Debug"
      os: linux
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="--enable-symbols"
# Testing on Mac, various styles
    - name: "macOS/Xcode 12/Shared"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include"
    - name: "macOS/Clang++/Xcode 12/Shared"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib CC=clang++ --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include CPPFLAGS=-D__private_extern__=extern"
    - name: "macOS/Xcode 12/Shared"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: &mactest
        - make all tktest
    - name: "macOS/Xcode 12/Static"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua --disable-shared CFLAGS=-I/usr/local/opt/tcl-tk/include"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
    - name: "macOS/Xcode 12/Debug"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua --enable-symbols CFLAGS=-I/usr/local/opt/tcl-tk/include"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
    - name: "macOS/Xcode 12/Shared/XQuartz"
      os: osx
      osx_image: xcode12
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --disable-corefoundation --x-includes=/opt/X11/include --x-libraries=/opt/X11/lib CFLAGS=-I/usr/local/opt/tcl-tk/include"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
# Older MacOS versions
    - name: "macOS/Xcode 11/Shared"
      os: osx
      osx_image: xcode11.7
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include CPPFLAGS=-mmacosx-version-min=10.14"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
    - name: "macOS/Xcode 10/Shared"
      os: osx
      osx_image: xcode10.3
      addons:
        homebrew:
          packages:
            - tcl-tk
          update: true
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include CPPFLAGS=-mmacosx-version-min=10.14"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
    - name: "macOS/Xcode 9/Shared"
      os: osx
      osx_image: xcode9.4
      addons:
        homebrew:
          packages:
            - tcl-tk
          update: true
      env:
        - BUILD_DIR=unix
        - CFGOPT="--with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CFLAGS=-I/usr/local/opt/tcl-tk/include CPPFLAGS=-mmacosx-version-min=10.13"
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
# Test on Windows with MSVC native
#   - name: "Windows/MSVC/Shared"
#     os: windows
#     compiler: cl
#     env: &vcenv
#       - BUILD_DIR=win
#       - VCDIR="/C/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Auxiliary/Build"
#     before_install: &vcpreinst
#       - PATH="$PATH:$VCDIR"
#       - cd ${BUILD_DIR}
#     install: []
#     script:
#       - cmd.exe //C vcvarsall.bat x64 '&&' nmake '-f' makefile.vc all tktest
# "make dist" only
    - name: "Linux: make dist"
      os: linux
      dist: focal
      compiler: gcc
      env:
        - BUILD_DIR=unix
      script:
        - make dist
before_install:
  - |-
      case $TRAVIS_OS_NAME in
        windows)
          choco install -y magicsplat-tcl-tk
          ;;
      esac
  - cd ${BUILD_DIR}
install:
  - mkdir "$HOME/install dir"
  - ./configure ${CFGOPT} "--prefix=$HOME/install dir" || (cat config.log && exit 1)
script:
  - make all tktest
  - make install
cache:
  directories:
  - $HOME/AppData/Local/Temp/chocolatey
  - $HOME/AppData/Local/Apps/Tcl86
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































Changes to ChangeLog.

more than 10,000 changes

Changes to ChangeLog.2002.

2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
	Removed setting inputContext to null in Tk_MakeWindowExist as it
	was redundant.

	* unix/tkUnixWm.c (CreateWrapper): Removed redundat setting of
	inputContext to null.

	* win/Makefile.in: changed gdb and shell targets to properly build
	all binaries before running (otherwise an error often occurred).

2002-03-28  David Gravereaux <davygrvy@pobox.com>

	* win/.cvsignore (new):
	* win/lamp.bmp (new):
	* win/makefile.vc:
	* win/nmakehlp.c (new):







|







2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
	Removed setting inputContext to null in Tk_MakeWindowExist as it
	was redundant.

	* unix/tkUnixWm.c (CreateWrapper): Removed redundat setting of
	inputContext to null.

	* win/Makefile.in: changed gdb and shell targets to properly build
	all binaries before running (otherwise an error often occured).

2002-03-28  David Gravereaux <davygrvy@pobox.com>

	* win/.cvsignore (new):
	* win/lamp.bmp (new):
	* win/makefile.vc:
	* win/nmakehlp.c (new):
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
	* canvas.test: added test for 5783.
	* generic/tkCanvPoly.c (DisplayPolygon): added checks for the
	polygon fillGC not being empty to prevent segfault. [Bug: 5783]

2000-05-31  Eric Melski  <ericm@scriptics.com>

	* library/bgerror.tcl: Improved bgerror based on work by Donal
	K. Fellows; no longer dependent on tk_dialog; features a
	Windows-esque "Details" button, and a customizable extra function
	button that allows the user to (for example) save the stack trace
	to a file.

2000-05-30  Eric Melski  <ericm@scriptics.com>

	* generic/tkImgGIF.c: Changed defines for GIF87a/GIF89a to be







|







5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
	* canvas.test: added test for 5783.
	* generic/tkCanvPoly.c (DisplayPolygon): added checks for the
	polygon fillGC not being empty to prevent segfault. [Bug: 5783]

2000-05-31  Eric Melski  <ericm@scriptics.com>

	* library/bgerror.tcl: Improved bgerror based on work by Donal
	K. Fellows; no longer dependant on tk_dialog; features a
	Windows-esque "Details" button, and a customizable extra function
	button that allows the user to (for example) save the stack trace
	to a file.

2000-05-30  Eric Melski  <ericm@scriptics.com>

	* generic/tkImgGIF.c: Changed defines for GIF87a/GIF89a to be

Changes to ChangeLog.2004.

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

	* doc/canvas.n: Add paragraph to make clearer what is going on with the
	default canvas origin. [Bug 956681]

2004-07-05  George Peter Staplin <GeorgePS@XMission.com>

	* generic/tkEvent.c: TK_XIM_SPOT preprocessor usage was modified
	slightly to fix a bug that occurred when TK_XIM_SPOT was defined as 0.
	Thanks to Joe Mistachkin for reporting this bug.

2004-07-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	TIP#158 IMPLEMENTATION

	* tests/bind.test:		   Allow Win apps to distinguish keys







|







807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

	* doc/canvas.n: Add paragraph to make clearer what is going on with the
	default canvas origin. [Bug 956681]

2004-07-05  George Peter Staplin <GeorgePS@XMission.com>

	* generic/tkEvent.c: TK_XIM_SPOT preprocessor usage was modified
	slightly to fix a bug that occured when TK_XIM_SPOT was defined as 0.
	Thanks to Joe Mistachkin for reporting this bug.

2004-07-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	TIP#158 IMPLEMENTATION

	* tests/bind.test:		   Allow Win apps to distinguish keys
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
	* win/configure.in:

	* unix/tcl.m4: correct HP-UX ia64 --enable-64bit build flags

2003-02-13  Kevin Kenny	 <kennykb@users.sourceforge.net>

	* doc/wish.n: Added language to describe the handling of the
	end-of-file character \x1A in script files. [Bug 685505]

2003-02-10  Jim Ingham <jingham@apple.com>

	* macosx/tkMacOSXCursor.c (TkMacOSXInstallCursor): Set all theme
	cursors using SetThemeCursor or SetAnimatedThemeCursors.
	(TkGetCursorByName): Use the theme cursors for arrow, ibeam, etc. Allow
	animatedCursor{NUM} form for an animated cursor with count.







|







3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
	* win/configure.in:

	* unix/tcl.m4: correct HP-UX ia64 --enable-64bit build flags

2003-02-13  Kevin Kenny	 <kennykb@users.sourceforge.net>

	* doc/wish.n: Added language to describe the handling of the
	end-of-file character \u001a in script files. [Bug 685505]

2003-02-10  Jim Ingham <jingham@apple.com>

	* macosx/tkMacOSXCursor.c (TkMacOSXInstallCursor): Set all theme
	cursors using SetThemeCursor or SetAnimatedThemeCursors.
	(TkGetCursorByName): Use the theme cursors for arrow, ibeam, etc. Allow
	animatedCursor{NUM} form for an animated cursor with count.

Deleted ChangeLog.2007.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
2007-12-30  Donal K. Fellows  <dkf@users.sf.net>

	* doc/canvas.n: Documented exact behaviour of items with respect to
	when they are the current item. [Bug 1774593] Also documented the
	clipping behaviour of window items.

	* library/demos/nl.msg: Corrected following testing "in the field" by
	Arjen Markus. [Bug 1860802]

2007-12-17  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	*** 8.5.0 TAGGED FOR RELEASE ***

	* doc/canvas.n: Documented -outlineoffset item option. [Bug 1836621]

2007-12-14  Don Porter  <dgp@users.sourceforge.net>

	* changes:	More updates for 8.5.0 release.

2007-12-14  Joe English  <jenglish@users.sourceforge.net>

	* doc/ttk_treeview.n: Fix typo. [Bug 1850713]

2007-12-14  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWinInt.h:    Add in missing function definitions
	* win/tkWinButton.c:  to support plain MSVC6 and use INT_PTR
	* win/tkWinScrlBar.c: rather than LONG_PTR which isn'tr defined
	* win/tkWinWm.c:     in the msvc6 headers.

2007-12-14  Pat Thoyts <patthoyts@users.sourceforge.net>

	* win/nmakehlp.c:  Support compilation with MSVC9 for AMD64.
	* win/makefile.vc:

2007-12-13  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkMenubutton.c (ConfigureMenuButton): trace the
	-textvariable even if an image exists as it may use -compound.

2007-12-12  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkText.c (DeleteIndexRange, TextEditCmd, UpdateDirtyFlag):
	* tests/text.test (text-25.10.1,25.11.[12]):
	Don't require [update idle] to trigger Modified event [Bug 1809538]
	Modified virtual event should only fire on state change [Bug 1799782]
	Make sure we delete chars before triggering <<Modified>> [Bug 1737288]

2007-12-12  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Revert 2007-10-26
	change to window class of transient toplevels that are not also
	overrideredirect. [Bug 1845899]

	* macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Implement more
	* macosx/tkMacOSXMouseEvent.c (BringWindowForward): X11-like transient
	* macosx/tkMacOSXSubwindows.c (XDestroyWindow):  behaviour by
	adding transient windows to a window group owned by the master window,
	this ensures transients always remain in front of and are collapsed
	with the master; bring master to front when selecting transient
	windows; restore default window group of transients if master
	destroyed. [Bug 1845899]

2007-12-12  Joe English  <jenglish@users.sourceforge.net>

	* doc/ttk_intro.n, doc/ttk_style.n, doc/ttk_widget.n:
	Various minor updates.

2007-12-12  Don Porter  <dgp@users.sourceforge.net>

	* changes:		Updated for 8.5.0 release.

2007-12-11  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTheme.c (StyleElementOptionsCmd): Use
	Ttk_GetElement() to find element instead of direct hash table access.

2007-12-11  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkText.c (TextReplaceCmd): Added code to rebuild the from
	index after the deletion phase so that the linePtr field is valid for
	the insertion phase. [Bug 1602537]

2007-12-10  Donal K. Fellows  <dkf@users.sf.net>

	* doc/event.n: Clarify the fact that [event info] only returns the
	names of virtual events that are bound to physical event sequences.
	This follows on from comments on comp.lang.tcl.
	http://groups.google.com/group/comp.lang.tcl/msg/935d2d226ae8a770

2007-12-10  Joe English  <jenglish@users.sourceforge.net>

	* doc/AddOption.3, doc/CrtImgType.3, doc/CrtPhImgFmt.3,
	* doc/InternAtom.3, doc/TextLayout.3, doc/chooseColor.n,
	* doc/chooseDirectory.n, doc/loadTk.n, doc/palette.n,
	* doc/ttk_combobox.n: Various markup fixes (mostly: missing quotes on
	.SH arguments, extraneous .PPs)

	* doc/ttk_entry.n, doc/ttk_scrollbar.n, doc/ttk_treeview.n: Remove
	extra .BEs that got added by mistake somewhere.

2007-12-10  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tk.decls:		use new genstubs 'export' command to
	* generic/tkInt.decls:		mark exported symbols not in stubs
					table [FR 1716117]; cleanup formatting

	* generic/tkIntDecls.h:		regen with new genStubs.tcl.
	* generic/tkIntPlatDecls.h:	[Tcl Bug 1834288]
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c:

2007-12-10  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* tests/safe.test: Ensure list of hidden commands is correct. [Bug
	1847925]

2007-12-10  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWin.h: We must specify the lowest Windows version we intend to
	support. In particular the SystemParametersInfo API doesn't like to
	receive structures that are larger than it expects which affects the
	font assignements. Set to Win98 support.

	* win/tkWinFont.c: Handle failure to read the system parameters. This
	causes ttk/fonts.tcl to set any missing named fonts.

	* win/ttkWinMonitor.c:  Only tkWin.h should include windows.h unless
	* win/ttkWinTheme.c:    we have an explicit override of the WINVER
	* tin/ttkWinXPTheme.c:  macro.

	* win/rules.vc: Handle MSVC 9 (aka: Visual Studio 2008)

	* tests/safe.test: Update for 'unload' as a safe command (tcl 8.5b3+)

2007-12-09  Donal K. Fellows  <dkf@users.sf.net>

	* win/configure.in: Adjusted code so that running configure does not
	generate an error message when the full current directory name
	contains a space.

	* win/tkWinWm.c: Added set of #defs to make this file build with my
	version of the SDK (i.e. with the msys suite we distribute).

2007-12-07  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/altTheme.tcl, library/ttk/classicTheme.tcl:
	s/style/ttk::style/.

2007-12-07  Don Porter  <dgp@users.sourceforge.net>

	* unix/README:  Mention the stub library created by `make` and warn
	about the effect of embedded paths in the installed binaries. Thanks
	to Larry Virden. [Tcl Bug 1794084]

2007-12-05  Joe English  <jenglish@users.sourceforge.net>

	* macosx/ttkMacOSXTheme.c: Fix TCombobox layout so as not to truncate
	long text when combobox is wider than requested. [Bug 1845164]

2007-12-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/demos/widget: reduce start size to 70% of screenheight from
	sh-200 for a more reasonable size.

	* win/tkWinButton.c, win/tkWinDialog.c: use SetWindowLongPtr and
	* win/tkWinScrlbr.c, win/tkWinWm.c:  GetWindowLongPtr only.
	* win/ttkWinMonitor.c:

	* win/tkWinInt.h: remove CS_CLASSDC (not recommended for any apps now)
	* win/tkWinX.c:   and simplify WNDCLASS to one style.
	* win/tkWinWm.c:  Reduce wrapper update for exStyle to toolwindow
	change only and set WS_EX_LAYERED as sticky (once set on a window, do
	not remove it) to reduce alpha transition flicker.

	* win/configure, win/tcl.m4 (LIBS_GUI): mingw needs -lole32 -loleaut32
	but not msvc for Tk's [send]. [Bug 1844749]

2007-12-04  Joe English  <jenglish@users.sourceforge.net>

	* doc/ttk_style.n: Remove nonsense about "this manpage has not yet
	been written"; everything supported is documented.

2007-12-04  Donal K. Fellows  <dkf@users.sf.net>

	* library/msgs/en.msg: Added missing messages. [Patch 1800744]

	* library/msgs/da.msg: Added Danish messages. [Patch 1844143]. Many
	thanks to Torsten Berg <treincke@users.sf.net>.

2007-12-03  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/configure, win/tcl.m4 (LIBS_GUI): remove ole32.lib oleaut32.lib
	(LIBS): add ws2_32.lib for static builds with Tcl.

2007-12-01  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h,
	* generic/ttk/ttkTheme.c, generic/ttk/ttkLayout.c,
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c,
	* generic/ttk/ttkTreeview.c, macosx/ttkMacOSXTheme.c,
	* win/ttkWinTheme.c, win/ttkWinXPTheme.c: Improved macrology for
	statically-initialized layout template tables.

2007-11-28  Don Porter  <dgp@users.sourceforge.net>

	* unix/tkUnixPort.h:	When unix/configure determines whether the
	intptr_t type is available, it has the <inttypes.h> header present.
	It's only fair that we let Tk have it too.

2007-11-26  Kevin Kenny  <kennykb@acm.org>

	* generic/tkImgPPM.c (StringReadPPM): Corrected a comparison whose
	sense was reversed that resulted in reading beyond the end of the
	input buffer on malformed PPM data. [Bug 1822391]
	* library/tkfbox.tcl (VerifyFileName): Corrected a couple of typos in
	handling of bad file names. [Bug 1822076] Thanks to Christoph Bauer
	(fridolin@users.sf.net) for the patch.
	* tests/filebox.test (filebox-7.1, filebox-7.2): Added test cases that
	exercise. [Bug 1822076]
	* tests/imgPPM.test (imgPPM-4.1): Added test case that exercises. [Bug
	1822391]

2007-11-25  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkManager.h, generic/ttk/ttkManager.c,
	* generic/ttk/ttkFrame.c, generic/ttk/ttkNotebook.c,
	* generic/ttk/ttkPanedwindow.c:  Internal Ttk_Manager API updates;
	Fixed [Bug 1343984]; Added [$nb hide] method; [$nb add] on
	already-managed windows no longer throws an error, can be used to
	re-add a hidden tab.

	* doc/ttk_notebook.n, tests/ttk/notebook.test,
	* tests/ttk/panedwindow.test:  Updated docs and test suite.

2007-11-23  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* unix/README: General improvements.

2007-11-21  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/tkfbox.tcl: Better theming in the file list area.

2007-11-19  Don Porter  <dgp@users.sourceforge.net>

	*** 8.5b3 TAGGED FOR RELEASE ***

	* README:		Bump version number to 8.5b3.
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf-2.59
	* win/configure:

	* changes:		Update changes for 8.5b3 release.

2007-11-19  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/ttk/ttkTheme.c:	Fix crash when 'style element create'
	* tests/ttk/ttk.test:		called w/ insufficient args; add tests.

2007-11-18  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkElements.c, macosx/ttkMacOSXTheme.c: Add "fill"
	element: like "background" but only erases parcel.

	* generic/ttk/ttkFrame.c: Use fill element in Labelframe Label
	sublayout. Also improved default labelmargins for -labelanchor w*, e*.

	* generic/ttk/ttkLabel.c: no longer need Labelframe hack.

	* library/ttk/aquaTheme.tcl: ImageTextElement no longer needed.
	TextElement no longer needs '-background' option.

	* generic/ttk/ttkFrame.c: Use sublayout for ttk::labelframe labels
	instead of single element.

	* generic/ttk/ttkLabel.c: Default -anchor for text and label elements
	is now "w" instead of "center". [Bug 1614540]

	* library/ttk/defaults.tcl, library/ttk/*Theme.tcl: Button styles now
	need explicit "-anchor center".

	* generic/ttk/ttkLayout.c (TTKInitPadding): BUGFIX:
	Ttk_GetPaddingFromObj() and Ttk_GetBorderFromObj() returned garbage
	when passed an empty list.

	* macosx/ttkMacOSXTheme.c: Resynchronize with Tile codebase so that
	patches can flow back and forth.

	* library/ttk/aquaTheme.tcl: Extra TButton -padding no longer needed.

2007-11-18  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/ttkWinXPTheme.c: Add support for size information flags for
	scrollbar and combobox buttons. This handles Tile [Patches 1596647 and
	1596657] but a bit more generically.

2007-11-17  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/(tkArgv.c, tkBind.c, tkCipboard.c, tkEntry.c, tkOption.c,
	tkScale.c, tkScrollbar.c, tkTextImage.c, tkVisual.c, tkWindow.c): Tidy
	up some variable types.

	* generic/tkFont.c:	Only check for -displayof if there are
	* test/font.test:	sufficient arguments. This permits checking
				strings like -d.

2007-11-17  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/scrollbar.tcl: Swap in core scrollbars for
	[ttk::scrollbar]s on OSX.

2007-11-16  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* macosx/tkMacOSXFont.c (TkpMeasureCharsInContext): Correct an
	oversight in the bug fix from 2007-11-11. [Bug 1824638]

2007-11-15  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcodeproj/project.pbxproj: add new chanio.test.
	* macosx/Wish.xcode/project.pbxproj:

2007-11-14  Donal K. Fellows  <dkf@users.sf.net>

	* library/msgs/sv.msg: Get the locale declared within the message
	catalog correct! [Bug 1831803]

2007-11-11  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* macosx/tkMacOSXFont.c (TkpMeasureCharsInContext): Fix the case when
	TK_WHOLE_WORDS and TK_AT_LEAST_ONE are both set and maxLength is small.
	[Bug 1824638]

2007-11-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXCarbonEvents.c
	(InstallStandardApplicationEventHandler): on Mac OS X Leopard, replace
	the 2005-11-27 approach of installing the standard application handler
	by calling RAEL and immediately longjmping out of it from an event
	handler, as that now leads to crashes in -[NSView unlockFocus] whenever
	HIToolbox uses Cocoa in Leopard (Help menu, Nav Services, Color
	Picker). Instead call InstallStandardEventHandler() on the application
	and menubar event targets, as Leopard ISEH finally handles these
	correctly. Unfortunately need a HIToolbox-internal SPI to retrieve the
	menubar event target, no public API appears have that functionality.

	* macosx/tkMacOSXDebug.c:	make TkMacOSXInitNamedDebugSymbol()
	* macosx/tkMacOSXDebug.h:	available outside of debug builds as
					the new Leopard ISAEH needs it.

	* macosx/tkMacOSXButton.c:	replace HiliteControl() by modern API
	* macosx/tkMacOSXMenubutton.c:	for activation and enabling;
					distinguish inactive and disabled
					look&feel; correct activation handling
					to match that of container toplevel.

	* macosx/tkMacOSXMenubutton.c:	correct size computation of bevelbutton
					variant to match that of buttons;
					fix crash with bitmap due to NULL GC;
					delay picParams setup until needed;
					formatting cleanup. [Bug 1824521]

	* library/menu.tcl:		correct handling of menubutton "active"
					state on Aqua to match that of buttons.

	* macosx/tkMacOSXDefault.h:	correct button & menubutton active
					foreground and background colors and
					menubutton border width.

	* macosx/tkMacOSXWindowEvent.c:	handle kEventWindowExpanding carbon
	* macosx/tkMacOSXCarbonEvents.c: event instead of kEventWindowExpanded
					to ensure activate event arrives after
					window is remapped, also need to
					process all Tk events generated by
					remapping in the event handler to
					ensure children are remapped before
					activate event is processed.

	* macosx/tkMacOSXSubwindows.c:	add pixmap size field to MacDrawable
	* macosx/tkMacOSXInt.h:		struct; add flag for B&W pixmaps.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXMenu.c:

	* macosx/tkMacOSXPrivate.h:	correct Leopard HIToolboxVersionNumber.

	* macosx/ttkMacOSXTheme.c:	add error checking; cleanup formatting.

	* macosx/tkMacOSXFont.c (TkpGetFontAttrsForChar): panic on false return
					from TkMacOSXSetupDrawingContext().

	* macosx/tkMacOSXButton.c:	sync formatting, whitespace, copyright
	* macosx/tkMacOSXDialog.c:	with core-8-4-branch.
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXWm.c:
	* xlib/xgc.c
	* library/bgerror.tcl:
	* library/console.tcl:
	* library/menu.tcl:

2007-11-07  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTheme.c (Ttk_ElementSize): Fixed longstanding, subtle
	bug that caused element padding to sometimes be counted twice in size
	computations.

	* generic/ttk/ttkElements.c, generic/ttk/ttkClamTheme.c,
	* generic/ttk/ttkDefaultTheme.c, generic/ttk/ttkTreeview.c,
	* generic/ttk/ttkImage.c, macosx/ttkMacOSXTheme.c,
	* win/ttkWinTheme.c, win/ttkWinXPTheme.c:
	Fix ElementSizeProcs affected by previous change.

2007-11-06  Andreas Kupries  <andreask@activestate.com>

	* doc/CrtConsoleChan.3: Fixed markup typo and extended see also
	section per suggestions by Donal.

2007-11-05  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl: Set focus to listbox in <Map> binding
	instead of in Post command (see [Bug 1349811] for info).

2007-11-05  Andreas Kupries  <andreask@activestate.com>

	* doc/CrtConsoleChan.3: New file providing minimal documentation of
	'Tk_InitConsoleChannels()'. [Bug 432435]

2007-11-05  Joe English  <jenglish@users.sourceforge.net>

	* macosx/ttkMacOSXTheme.c (TreeitemLayout): Remove focus ring
	from treeview items on OSX (problem reported by Kevin Walzer).

2007-11-04  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTreeview.c: Use null "treearea" element for treeview
	owner-draw area instead of "client", to avoid nameclash with
	Notebook.client element (this was causing sizing anomalies in XP
	theme, and introduced extraneous padding).
	* generic/ttk/ttkDefaultTheme.c: Treeitem.indicator element needs left
	margin now.

2007-11-04  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXMenus.c: add "Run Widget Demo" menu item to the
	default Edit menu along with associated carbon event handler enabling
	the item only if demo files are installed; cleanup handling of "About"
	and "Source" menu items.

	* library/bgerror.tcl:		fix background of detail text on Aqua.

	* library/console.tcl:		add accelerators and fix Aqua bindings
					of the new font size menu items.

	* library/demos/mclist.tcl:	Aqua GOOBE.
	* library/demos/tree.tcl:
	* library/demos/ttknote.tcl:
	* library/demos/widget:

	* doc/chooseDirectory.n:	remove/correct obsolete Mac OS 9-era
	* doc/getOpenFile.n:		information.
	* doc/menu.n:

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessCommandEvent): fix boolean
	arg

	* macosx/Wish.xcodeproj/project.pbxproj: add new demo file.
	* macosx/Wish.xcode/project.pbxproj:

2007-11-03  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* library/console.tcl: Add menu item and key binding to adjust font.

2007-11-02  Donal K. Fellows  <dkf@users.sf.net>

	* library/demos/mclist.tcl: Added a demo of how to do a multi-column
	sortable listbox.

	* library/msgbox.tcl: Made message dialog use Ttk widgets for better
	L&F.

	* library/tkfbox.tcl (::tk::dialog::file::CompleteEnt): Added <Tab>
	completion. [FR 805091]
	* library/tkfbox.tcl: Made file dialog use Ttk widgets for better L&F.

	* library/demos/sayings.tcl: Better resizing. [Bug 1822410]

2007-11-01  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/textpeer.tcl: Better resizing. [Bug 1822601]

	* doc/colors.n: Added list of Windows system colors. [Bug 945409]

2007-11-01  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXColor.c (GetThemeColor): improve translation of RGB
				pixel values into RGBColor.

	* library/demos/widget:	increase height of main window text widget to
				use more of the available vertical space.

	* doc/bind.n:		document the Option modifier, clarify meaning
				and availability of Command & Option.

	* doc/console.n:	clarify availability of [console] in TkAqua.

2007-11-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* unix/installManPage, doc/*.n: Make documentation use the name that
	scripts use as much as possible. [Bug 1640073]

	* doc/text.n: Fixed mistake in [$t tag remove] docs. [Bug 1792191]

	* doc/bind.n: Documented the Command modifier. [Bug 1232908]

	* doc/console.n, doc/wish.1: Made it clearer when and why the console
	command is present. [Bug 1386955]

2007-10-31  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/entry3.tcl: Improved description/comments so that
	people better understand what is being validated, following suggestion
	from Don Porter.

	* library/demos/image2.tcl (loadImage): Mark non-loadable images as
	such instead of throwing a nasty dialog, following suggestion from Don
	Porter.

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock): More optimization, derived
	from [Patch 224066].

2007-10-30  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl (Unpost): BUGFIX: Unpost can be called with
	no preceding Post.

2007-10-31  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/rules.vc:  Use -fp:strict with msvc8 as -fp:precise fails on
	* generic/tkObj.c:  amd64 builds. Fix the two places in Tk that
	* generic/tkTrig.c: generate errors with msvc8 when using this flag.

2007-10-30  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/choosedir.tcl: only enable OK button when valid in
	conjunction with -mustexist. [Bug 1550528]

	* library/listbox.tcl (::tk::ListboxBeginSelect): ignore -takefocus
	when considering focus on <1>, it is for tab focus.

2007-10-30  Don Porter  <dgp@users.sourceforge.net>

	* generic/tk.h:		Bump version number to 8.5b2.1 to distinguish
	* library/tk.tcl:	CVS development snapshots from the 8.5b2
	* unix/configure.in:	release.
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf (2.59)
	* win/configure:

2007-10-30  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/text.n: fix spelling of -inactiveselectbackground [Bug 1626415]

	* library/entry.tcl: don't error with Clear event. [Bug 1509288]

	* library/ttk/fonts.tcl: use size -12 TkFixedFont (was -10) on X11

2007-10-30  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/unicodeout.tcl: Fixed Arabic and Hebrew rendering on
	Windows. [Bug 1803723]

	* generic/tkImgPhoto.c (ImgPhotoCmd): Rename enumeration for somewhat
	simpler-to-read code. [Bug 1677613]

2007-10-30  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkWidget.c: Split up RedisplayWidget() to factor out
	double-buffering related code.

	* macosx/ttkMacOSXAquaTheme.c: Use SetThemeBackGround/
	kThemeBrushModelessDialogBackground{Active|Inactive} instead of
	ApplyThemeBackground/kThemeBackgroundWindowHeader (advice from DAS).

	* library/ttk/aquaTheme.tcl: Use darker shade for inactive and
	disabled text, to match typical values of most
	kThemeXXXTextColorInactive values.

2007-10-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/selection.n: Clarify UTF8_STRING handling. [Bug 1778563]

	* doc/text.n: Clarify search subccommand docs. [Bug 1622919]

2007-10-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXFont.c (InitSystemFonts):
	* library/ttk/fonts.tcl: use Monaco 11 (was 9) as Aqua TkFixedFont

	* tests/listbox.test, tests/panedwindow.test, tests/scrollbar.test:
	* library/bgerror.tcl, library/dialog.tcl, library/listbox.tcl:
	* library/msgbox.tcl, library/optMenu.tcl, library/tclIndex:
	* library/tkfbox.tcl, library/demos/floor.tcl, library/demos/rmt:
	* library/demos/tcolor, library/demos/text.tcl:
	* library/demos/twind.tcl, library/demos/widget: Buh-bye Motif look
	* library/ttk/fonts.tcl:    Update of Tk default look in 8.5
	* macosx/tkMacOSXDefault.h: Trims border sizes, cleaner X11 look
	* unix/tkUnixDefault.h:  with minor modifications for Win32/Aqua.
	* win/tkWinDefault.h:    Uses Tk*Font definitions throughout for
	* win/tkWinFont.c:     classic widgets. [Bug 1820344]
	* library/obsolete.tcl (::tk::classic::restore): This restores
	changes made to defaults in 8.5 using the 'option' command,
	segmented into logical groups.

	* tests/winfo.test: winfo-4.5 raise .t to above . for Windows

	* tests/unixWm.test: note TIP#142 results and remove unnecessary
	catches.

2007-10-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/*.1, doc/*.n, doc/*.3: Lots more GOOBE work.

2007-10-28  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl: Make popdown window [wm resizable 0 0] on
	OSX, to prevent TkAqua from shrinking the scrollbar to make room for a
	grow box that isn't there.
	* macosx/ttkMacOSXTheme.c, library/ttk/aquaTheme.tcl: Reworked
	combobox layout.

2007-10-26  Don Porter  <dgp@users.sourceforge.net>

	*** 8.5b2 TAGGED FOR RELEASE ***

	* changes:		Update changes for 8.5b2 release.

	* doc/*.1:      Revert doc changes that broke
	* doc/*.3:      `make html` so we can get the release
	* doc/*.n:      out the door.

	* README:		Bump version number to 8.5b2.
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf-2.59
	* win/configure:

2007-10-26  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): fix window class
	of transient toplevels that are not also overrideredirect. [Bug
	1816252]

	* macosx/tkMacOSXDialog.c:	TIP#242 cleanup.
	* library/demos/filebox.tcl: 	demo TIP#242 -typevariable.

2007-10-25  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkNotebook.c: [Bug 1817596]

2007-10-25  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/getOpenFile.n:	TIP#242 implementation of -typevariable to
	* library/tkfbox.tcl:	return type of selected file in file dialogs.
	* library/xmfbox.tcl:	[Bug 1156388]
	* macosx/tkMacOSXDialog.c:
	* tests/filebox.test:
	* tests/winDialog.test:
	* win/tkWinDialog.c:

2007-10-25  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkPlace.c:	Prevent segfault in place geometry manager.
	Thanks to Colin McDonald. [Bug 1818491]

2007-10-24  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/*.c, win/{ttkWinMonitor,ttkWinTheme,ttkWinXPTheme}.c,
	* macosx/ttkMacOSXTheme.c: Move widget layout registration from
	TtkElements_Init() to widget *_Init() routines. Renaming/consistency:
	s/...ElementGeometry()/...ElementSize()/

2007-10-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/*.n, doc/*.3, doc/*.1: Lots of changes to take advantage of the
	new macros.

2007-10-24  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWinDraw.c: Applied [Patch 1723362] for transparent bitmaps.

	* generic/tkWindow.c: permit wm manage of any widget (esp: ttk::frame)

2007-10-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/ttk/combobox.tcl (ttk::combobox::PopdownWindow): redo wm
	transient on each drop to handle reparent-able frames. [Bug 1818441]

2007-10-23  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl: [namespace import ::ttk::scrollbar]
	doesn't work, since ttk::scrollbar isn't [namespace export]ed.

2007-10-23  Don Porter  <dgp@users.sourceforge.net>

	* tests/cursor.test:	Make tests robust against changes in Tcl's
	rules for accepting integers in octal format.

2007-10-23  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* doc/font.n: Added section on the TIP#145 fonts.

2007-10-23  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWinFont.c: Fixed leak in CreateNamedFont spotted by das.

2007-10-23  Daniel Steffen  <das@users.sourceforge.net>

	* library/demos/combo.tcl:	Aqua GOOBE.
	* library/demos/toolbar.tcl:
	* library/demos/tree.tcl:
	* library/demos/ttknote.tcl:
	* library/demos/ttkprogress.tcl:
	* library/demos/widget:

	* macosx/Wish.xcodeproj/project.pbxproj: add new demo files.
	* macosx/Wish.xcode/project.pbxproj:

2007-10-22  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/widget: Added more demos, reorganized to make Tk and
	Ttk demos seem to be more coherent whole. Made localization a bit
	easier by reducing the amount of duplication.
	* library/demos/{combo,toolbar,tree,ttknote,ttkprogress}.tcl: New
	demos of new (mostly) Ttk widgets.
	* library/demos/ttkbut.tcl: Improvements.

2007-10-22  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl:	ttk::combobox overhaul; fixes [Bugs
					1814778, 1780286, 1609168, 1349586]
	* library/ttk/aquaTheme.tcl:	Factored out aqua-specific combobox
					-postposition adjustments.
	* generic/ttk/ttkTrack.c:	Detect [grab]s and unpress pressed
					element; combobox workaround no longer
					needed.

2007-10-22  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXFont.c: 	register named fonts for TIP #145 fonts
					and all theme font IDs.

	* generic/tkFont.c (Tk{Create,Delete}NamedFont): allow NULL interp.

	* library/ttk/fonts.tcl:	check for TIP #145 fonts on all
					platforms; correct aqua font sizes.

	* library/demos/ttkmenu.tcl:	Aqua GOOBE.
	* library/demos/ttkpane.tcl:
	* library/demos/widget:

	* macosx/Wish.xcodeproj/project.pbxproj: add new demo files.
	* macosx/Wish.xcode/project.pbxproj:

2007-10-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/ttkmenu.tcl: Added more demos of Ttk widgets. These
	* library/demos/ttkpane.tcl: ones are of menubuttons, panedwindows and
	a progress bar (indirectly).

2007-10-18  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* library/ttk/fonts.tcl: Create all the TIP #145 font names on all
	platforms (mac and unix get handled in script, windows in C)

2007-10-17  David Gravereaux <davygrvy@pobox.com>

	* bitmaps/*.xbm: Changed CVS storage mode from -kb to -kkv as these
	are really text files, not binaries.
	* win/makefile.vc: Added $(BITMAPDIR) to the search path for the
	depend target.

2007-10-18  Daniel Steffen  <das@users.sourceforge.net>

	* library/demos/widget:		Aqua GOOBE, cleanup icons.
	* library/demos/ttkbut.tcl:
	* library/demos/entry3.tcl:
	* library/demos/msgbox.tcl:

	* library/demos/button.tcl:	restore setting of button
					highlightbackground on Aqua.

	* macosx/ttkMacOSXTheme.c: 	adjust button and separator geometry.

	* macosx/tkMacOSXWm.c:		fix warnings.

	* macosx/Wish.xcodeproj/project.pbxproj: add new demo files.
	* macosx/Wish.xcode/project.pbxproj:

2007-10-17  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/ttkbut.tcl: Added demo of the basic Ttk widgets.

2007-10-16  David Gravereaux <davygrvy@pobox.com>

	* win/makefile.vc: depend target now works and builds a generated
	dependency list with $(TCLTOOLSDIR)/mkdepend.tcl

2007-10-16  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/widget: Made the code for generating the contents of
	the main widget more informative. Added 'new' flagging for wholly new
	demos.

	* doc/text.n: Made it clearer what things are text widget invokations
	and what are not. Also some other clarity improvements.

2007-10-15  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/demos/widget: Use Ttk widgets for the widget demo core, for
	vastly improved look-and-feel on at least one platform (Windows).
	* library/demos/{button,check,style,twind}.tcl: Various tweaks for
	GOOBE...
	* library/demos/textpeer.tcl: New demo script to show off peering as a
	specific feature.

2007-10-15  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkFocus.c, generic/tkFrame.c, generic/tkInt.h:
	* macosx/tkMacOSXButton.c, macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c, unix/tkUnixWm.c, win/tkWinWm.c:
	* doc/wm.n, tests/wm.test: TIP #125 implementation. [Bug 998125]
	Adds [wm manage|forget] for dockable frames.
	Finished X11 and Windows code, needs OS X completion.

2007-10-15  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTreeview.c: Store pointer to column table entry
	instead of column index in columnNames hash table. This avoids the
	need for the evil PTR2INT and INT2PTR macros, and simplifies things a
	bit.

2007-10-15  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkArgv.c:		Fix gcc warnings about 'cast to/from
	* generic/tkCanvUtil.c:		pointer from/to integer of different
	* generic/tkCanvas.c:		size' on 64-bit platforms by casting
	* generic/tkCursor.c:		to intermediate types
	* generic/tkInt.h:		intptr_t/uintptr_t via new PTR2INT(),
	* generic/tkListbox.c:		INT2PTR(), PTR2UINT() and UINT2PTR()
	* generic/tkObj.c:		macros.
	* generic/tkStyle.c:
	* generic/tkTextIndex.c:
	* generic/tkUtil.c:
	* generic/ttk/ttkTheme.h:
	* generic/ttk/ttkTreeview.c:
	* unix/tkUnixMenu.c:
	* unix/configure.in:

	* unix/configure:		autoconf-2.59
	* unix/tkConfig.h.in:		autoheader-2.59

	* macosx/Wish-Common.xcconfig:		add 'tktest-X11' target.
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/Wish.xcodeproj/default.pbxuser:
	* macosx/Wish.xcodeproj/project.pbxproj:

	* unix/configure.in (Darwin):	add support for 64-bit X11.
	* unix/configure:		autoconf-2.59

2007-10-14  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/configure, win/configure.in (TK_WIN_VERSION): Make sure the
	patchlevel doesn't contain extra dotted pairs (eg. interim release)

2007-10-12  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/makefile.vc:  Mine all version information from headers.
	* win/rules.vc:  Sync tcl and tk and bring extension versions
	* win/nmakehlp.c:   closer together. Try and avoid using tclsh
	        to do substitutions as we may cross compile.

	* library/console.tcl:     Use TkFixedFont and ttk widgets

2007-10-12  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDraw.c:	replace all (internal) use of QD region
	* macosx/tkMacOSXSubwindows.c:	API by HIShape API, with conversion to
	* macosx/tkMacOSXWindowEvent.c:	QD regions only when required by legacy
	* macosx/tkMacOSXPrivate.h:	Carbon or Tk API.
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:

	* macosx/tkMacOSXInt.h:		replace MacDrawable's QD RgnHandles
	* macosx/tkMacOSXEmbed.c:	clipRgn, aboveClipRgn & drawRgn by
	* macosx/tkMacOSXMenu.c:	HIShapeRefs visRgn & aboveVisRgn and
	* macosx/tkMacOSXSubwindows.c:	CGRect drawRect.

	* macosx/tkMacOSXWindowEvent.c:	remove use of QD port vis rgn in
	* macosx/tkMacOSXSubwindows.c:	window update rgn calculation,
	* macosx/tkMacOSXWm.c:		manually excise growbox from toplevel
					clip rgn instead.

	* macosx/tkMacOSXDraw.c:	replace use of QD port clip rgn by new
	* macosx/tkMacOSXPrivate.h:	clipRgn fld in TkMacOSXDrawingContext;
					handle QD/CG drawing mismatches in
					XCopyArea, XCopyPlane and TkPutImage;
					cleanup/speedup CGContext setup in
					TkMacOSXSetupDrawingContext().

	* macosx/tkMacOSXDraw.c:	change TkMacOSXSetupDrawingContext()
	* macosx/tkMacOSXEntry.c:	to return boolean indicating whether
	* macosx/tkMacOSXFont.c:	drawing is allowed (and was setup) or
	* macosx/tkMacOSXMenu.c:	not (e.g. when clipRgn is empty).
	* macosx/ttkMacOSXTheme.c:

	* macosx/tkMacOSXSubwindows.c:	signal that drawable is a pixmap via
	* macosx/tkMacOSXInt.h:		new explicit TK_IS_PIXMAP flag instead
					of a NULL cligRgn field.

	* macosx/tkMacOSXRegion.c:	add wrappers for missing/buggy HIShape
	* macosx/tkMacOSXPrivate.h:	API, and private helpers to operate on
					HIShapeRefs & convert to/from TkRegion

	* macosx/tkMacOSXRegion.c:	add Tkp{Retain,Release}Region() API
	* macosx/tkMacOSXInt.h:		for TkRegion.

	* xlib/xgc.c:			factor out alloc/free of GC clip_mask;
	* macosx/tkMacOSXXStubs.c:	manage clip rgn lifetime with new
					Tkp{Retain,Release}Region().

	* macosx/tkMacOSXButton.c:	delay picParams setup until needed.

	* generic/tkTextDisp.c (CharUndisplayProc): fix textDisp.test crash.

2007-10-11  David Gravereaux <davygrvy@pobox.com>

	* win/winMain.c: Replaced incorrect comments in main() to descibe why
	the console widget does not need to be created for this application
	entry point (if used). Must have been a bad copy/paste of WinMain()
	from 10 years back.

2007-10-11  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (TkMacOSXGrowToplevel): manually constrain resize
	limitBounds to maxBounds, works around SectRect() mis-feature (return
	zero rect if input rect has zero height/width). [Bug 1810818]

2007-10-09  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkImage.c:    Make Ttk_GetImage safe if called with NULL
	* tests/ttk/image.test: interp. Added some tests that crash on Windows
				without this fix.

2007-10-02  Don Porter  <dgp@users.sourceforge.net>

	[core-stabilizer-branch]

	* README:        Bump version number to 8.5.0
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:	Updated LOCALES.
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf (2.59)
	* win/configure:

2007-09-30  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/entry.tcl (WordBack, WordForward):
	Fix private routines accidentally defined in global namespace
	[Bug 1803836]

2007-09-26  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/msgs/hu.msg: Added Hungarian message set, from Pader Reszo.
	[Patch 1800742]

2007-09-20  Donal K. Fellows  <dkf@users.sf.net>

	*** 8.5b1 TAGGED FOR RELEASE ***

	* generic/tkTextDisp.c (LayoutDLine):  Only call callbacks that are
	* tests/textDisp.test (textDisp-32.3): not NULL. [Bug 1791052]

2007-09-20  Don Porter  <dgp@users.sourceforge.net>

	* changes: updates for 8.5b1 release.

2007-09-19  Don Porter  <dgp@users.sourceforge.net>

	* README:		Bump version number to 8.5b1.
	* generic/tk.h:		Merge from core-stabilizer-branch.
	* library/tk.tcl:	Stabilizing toward 8.5b1 release now done
	* unix/configure.in:	on the HEAD. core-stabilizer-branch is
	* unix/tk.spec:		now suspended.
	* win/configure.in:

2007-09-19  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkStubLib.: Replaced isdigit with internal implementation.

2007-09-18  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkStubLib.c:	Remove C library calls from Tk_InitStubs()
	* win/makefile.vc:	so that we don't need the C library linked
	in to libtkStub.

2007-09-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* generic/tkImgGIF.c (FileReadGIF, StringReadGIF): Rewrite for greater
	clarity (more comments, saner code arrangement, etc.)

2007-09-18  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* tests/all.tcl:    Made ttk/all.tcl be the same as tk's all.tcl and
	* tests/ttk/all.tcl: make use of file normalize (bugs noted by
	mjanssen and GPS with msys)

2007-09-17  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/makefile.vc: Add crt flags for tkStubLib now it uses C-library
	functions.

2007-09-17  Joe English  <jenglish@users.sourceforge.net>

	* unix/tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable' to
	build shared libraries on current NetBSDs. [Bug 1749251]
	* unix/configure: regenerated (autoconf-2.59).

2007-09-17  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Revised callers of Tcl_InitStubs() to account
	* generic/tkMain.c:	for restored compatible support for the call
	* generic/tkWindow.c:	Tcl_InitStubs(interp, TCL_VERSION, 1). Also
	revised Tcl_PkgRequire() call for Tcl so that, for example, a Tk
	library built against Tcl 8.5.1 headers will not refuse to [load] into
	a Tcl 8.5.0 interpreter. [Tcl Bug 1578344]

	* generic/tk.h:		Revised Tk_InitStubs() to restore Tk 8.4
	* generic/tkStubLib.c:	source compatibility with callers of
	* generic/tkWindow.c:	Tk_InitStubs(interp, TK_VERSION, 1).

2007-09-17  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl:  Try to improve combobox appearance on
	OSX + Tk 8.5. [Bug 1780286]

2007-09-15  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4: 	replace all direct references to compiler by ${CC} to
			enable CC overriding at configure & make time; run
			check for visibility "hidden" with all compilers;
			quoting fixes from TEA tcl.m4.
	(SunOS-5.1x):	replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
			'cc' compiler driver.
	* unix/configure: autoconf-2.59

2007-09-14  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish-Common.xcconfig:		  enable Tcl DTrace support.
	* macosx/Wish.xcodeproj/project.pbxproj:

2007-09-12  Andreas Kupries  <andreask@activestate.com>

	* win/Makefile.in (install-binaries): Fixed missing brace in the
	* win/makefile.vc (install-binaries): generated package index file.
	Note: unix/Makefile.in is good.

2007-09-11  Reinhard Max  <max@suse.de>

	* generic/tkImgGIF.c: Fixed a buffer overrun that got triggered by
	multi-frame interlaced GIFs that contain subsequent frames that are
	smaller than the first one.

	* tests/imgPhoto.test: Added a test for the above.

2007-09-11  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Revised calls to Tcl_InitStubs() and
	* generic/tkMain.c:	[package require Tcl] so that Tk Says What It
	* generic/tkWindow.c:	Means using the new facilties of [package] in
	* library/tk.tcl:	Tcl 8.5 about what version(s) of Tcl it is
	* unix/Makefile.in:	willing to work with. [Bug 1578344]
	* win/Makefile.in:
	* win/makefile.vc:

2007-09-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/README: typo corrections [Bug 1788682]

2007-09-10  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Revise all Tcl_InitStubs() calls to restore
	* generic/tkMain.c:	the traditional practice that a Tk shared
	* generic/tkWindow.c:	library may [load] into a Tcl 8.5 interp at
	any patchlevel.	 This practice also matches the compile time checks of
	TCL_MAJOR_VERSION and TCL_MINOR_VERSION in tk.h. [Bug 1723622]

2007-09-06  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkWindow.c (Initialize):	Moved common Tk initialization
	* generic/tkInitScript.h (removed):	script out of tkInitScript.h
	* macosx/tkMacOSXInit.c:	and multiple TkpInit() routines and
	* unix/Makefile.in:	into the common Initialize() routine in
	* unix/tkUnixInit.c:	generic code. Also removed constraint on
	* win/tkWinInit.c:	ability to define a custom [tkInit] before
	calling Tk_Init(). Until now the custom [tkInit] had to be a proc. Now
	it can be any command. Removal of tkInitScript.h also fixes [Bug
	1656283].

2007-09-06  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcode/project.pbxproj: discontinue unmaintained support
	* macosx/Wish.xcode/default.pbxuser: for Xcode 1.5; replace by Xcode2
	project for use on Tiger (with Wish.xcodeproj to be used on Leopard).

	* macosx/Wish.xcodeproj/project.pbxproj: updates for Xcode 2.5 and 3.0.
	* macosx/Wish.xcodeproj/default.pbxuser:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/Wish-Common.xcconfig:

	* macosx/README: document project changes.

2007-09-04  Joe English  <jenglish@users.sourceforge.net>

	* generic/tkTest.c: Fix for [Bug 1788019] "tkTest.c compiler warning".

2007-09-04  Don Porter  <dgp@users.sourceforge.net>

	* unix/Makefile.in:  It's unreliable to count on the release
	manager to remember to `make genstubs` before `make dist`. Let the
	Makefile remember the dependency for us.

	* unix/Makefile.in:  Corrections to `make dist` dependencies to be
	sure that macosx/configure gets generated whenever it does not exist.

2007-09-03  Daniel Steffen  <das@users.sourceforge.net>

	* generic/ttk/ttkInit.c  (Ttk_Init): register ttk in package database
	to enable extension access to the ttkStubs table.

	* generic/ttk/ttkDecls.h: correct capitalization of ttk package name.

2007-08-28  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	Assorted documentation improvements.
	* doc/button.n: Added examples.
	* doc/checkbutton.n: Added example.
	* doc/console.n: Standardized section ordering.
	* doc/tk.n: Added "See also".
	* doc/ttk_combobox.n: Added keywords.

2007-08-27  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDialog.c (Tk_ChooseColorObjCmd): correct setting of
	interp result [Bug 1782105]; fix -initialcolor overwriting last color
	selection; style cleanup.

2007-08-21  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/rules.vc: Synchronize with tcl rules.vc
	* tests/all.tcl: Fix the line-endings.

2007-08-07  Daniel Steffen  <das@users.sourceforge.net>

	* unix/Makefile.in:	Add support for compile flags specific to
				object files linked directly into executables.

	* unix/configure.in (Darwin): Only use -seg1addr flag when prebinding;
	use -mdynamic-no-pic flag for object files linked directly into exes.

	* unix/configure: autoconf-2.59

2007-08-01  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWinDialog.c:    Fix [Bug 1692927] (buffer length problems)
	* win/tkWinTest.c:    Added 'testfindwindow' and 'testgetwindowinfo'
	and extended 'testwinevent' for WM_COMMAND support to enable testing
	native messagebox dialogs.
	* tests/winMsgbox.test: New Windows native messagebox tests.

2007-07-25  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDialog.c (NavServicesGetFile): Reset interp result on
	nav dialog cancel. [Bug 1743786]

2007-07-09  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/Makefile.in: clarify what the headers installed are, and
	add ttkTheme.h and ttkDecls.h to private headers (later public).

2007-07-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWindowEvent.c (Tk_MacOSXIsAppInFront):	Use process mgr
	* macosx/tkMacOSXMouseEvent.c:				to determine if
	app is in front instead of relying on activate/deactivate events (which
	may arrive after this info is needed, e.g. during window drag/click
	activation); replace other process mgr use to get this info with calls
	to Tk_MacOSXIsAppInFront().

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): Correct
	window click activation, titlebar click handling and background window
	dragging/growing in the presence of grabs or window-/app-modal windows;
	fix window click activation bringing all other app windows to front.

	* macosx/tkMacOSXDraw.c (TkPutImage): Handle non-native XImage byte and
	bit orders; reverse bits via xBitReverseTable instead of InvertByte().

2007-07-06  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/aquaTheme.tcl:	Set -anchor w for TMenubuttons.
					[Bug 1614540]

2007-07-04  Andreas Kupries  <andreask@activestate.com>

	* macosx/tkMacOSXXStubs.c (DestroyImage): Fixed seg.fault in release
	of image data for images coming from XGetImage. Change committed by me
	for Daniel Steffen. See 2007-06-23 for the change which introduced the
	problem.

2007-07-02  Daniel Steffen  <das@users.sourceforge.net>

	* xlib/xgc.c (XCreateGC): Correct black and white pixel values used to
	initialize GC foregrund and background fields.

	* macosx/tkMacOSXColor.c: Add debug messages for unknown pixel values.

	* macosx/tkMacOSXDraw.c (TkMacOSXRestoreDrawingContext): Don't restore
	port state if it wasn't altered by TkMacOSXSetupDrawingContext().

2007-06-29  Daniel Steffen  <das@users.sourceforge.net>

	* xlib/ximage.c:		Bitmaps created from the static .xbm
					arrays always have LSBFirst bit order.

	* unix/configure.in:		Fix flag used to weak-link libXss.
	* unix/configure:		autoconf-2.59

	* macosx/tkMacOSXScrlbr.c: Correct int <-> dobule conversion issues
	that could lead to Carbon getting confused about scrollbar thumb size.

	* macosx/tkMacOSXDraw.c (XCopyArea, XCopyPlane, TkPutImage): Use
	TkMacOSX{Setup,Restore}DrawingContext() to setup/restore clip & colors.
	(TkMacOSXSetupDrawingContext, TkMacOSXRestoreDrawingContext): Add save
	and restore of QD port clip region; factor out clip region code common
	to CG and QD branches; check for port and context validity; handle
	tkPictureIsOpen flag during QD port setup.
	(TkScrollWindow): Remove unnecessary scroll region manipulation

	* macosx/tkMacOSXDraw.c:	Remove second global QD temp region
	* macosx/tkMacOSXInt.h:		(no longer necessary) and rename
	* macosx/tkMacOSXRegion.c:	remaining global QD temp region.
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXDraw.c: 	Make useCGDrawing variable MODULE_SCOPE
	* macosx/tkMacOSXFont.c: 	and respect it for ATSUI font drawing.

	* macosx/tkMacOSXButton.c:	Reduce reliance on current QD port
	* macosx/tkMacOSXColor.c:	setting and remove unnecessary
	* macosx/tkMacOSXDebug.c:	references to a drawable's QD port,
	* macosx/tkMacOSXDebug.h:	notably replace GetWindowFromPort(
	* macosx/tkMacOSXDialog.c:	TkMacOSXGetDrawablePort()) idiom by new
	* macosx/tkMacOSXDraw.c:	TkMacOSXDrawableWindow() and change
	* macosx/tkMacOSXKeyEvent.c:	TkMacOSXSetColorInPort() to take a port
	* macosx/tkMacOSXMenu.c:	argument.
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXInt.h:		  	Factor out macros, declarations
	* macosx/tkMacOSXPrivate.h (new): 	and prototypes that are purely
	internal and private to the 'macosx' sources into a new internal header
	file that does _not_ get installed into Tk.framework/PrivateHeaders.

	* macosx/tkMacOSXButton.c: 		#include new tkMacOSXPrivate.h
	* macosx/tkMacOSXCarbonEvents.c:	instead of tkMacOSXInt.h.
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* macosx/ttkMacOSXTheme.c:

	* macosx/Wish.xcodeproj/project.pbxproj: Improve support for renamed
	* macosx/Wish.xcodeproj/default.pbxuser: tcl and tk source dirs; add
	* macosx/Wish-Common.xcconfig:		 10.5 SDK build config; remove
						 tclMathOp.c.

	* macosx/README: Document Wish.xcodeproj changes.

2007-06-23  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkImgPhoto.c (ImgPhotoConfigureInstance, DisposeInstance):
	Use XDestroyImage instead of XFree to destroy XImage; replace runtime
	endianness determination by compile-time check for WORDS_BIGENDIAN.

	* xlib/ximage.c (XCreateBitmapFromData): Use XCreateImage and
	XDestroyImage instead of creating XImage structure manually.

	* macosx/tkMacOSXXStubs.c (XCreateImage, DestroyImage): Correct XImage
	bytes_per_line/bitmap_pad calculations and endianness setting; free
	image data and XImage structure at destruction; formatting cleanup.

	* macosx/tkMacOSXDialog.c (NavServicesGetFile): Disable app-modal
	sheet variant of nav dialog on OS versions where it causes problems.

2007-06-20  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/ttk/ttk.tcl: Should require Tk before pseudo-providing
	tile 0.8.0.

2007-06-09  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkPanedwindow.c, doc/ttk_panedwindow.n,
	* tests/ttk/panedwindow.test: Added -width and -height options. Added
	'panes' method, return list of managed windows. 'sashpos' method is
	now documented as part of the public interface, and details clarified.
	Should be easier to set initial sash positions now. Alleviates [Bug
	1659067].

2007-06-09  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinWm.c (WmIconphotoCmd): fix wm iconphoto RGBA issues.
	[Bug 1467997] (janssen)

	* win/tkWinMenu.c (TkWinHandleMenuEvent): Improve handling to allow
	for unicode char menu indices and not use CharUpper on Tcl utf
	strings. [Bug 1734223]

2007-06-09  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkManager.h, generic/ttk/ttkManager.c,
	* generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c,
	* generic/ttk/ttkFrame.c: Ttk_Manager API overhaul:
	    + Ttk_Manager no longer responsible for managing slave records
	    + Ttk_Manager structure now opaque
	    + Ttk_Slave structure now private
	    + Pass Ttk_Manager* to Tk_GeomMgr hooks instead of Ttk_Slave*

	* generic/ttk/ttkFrame.c: Simplified -labelwidget management.

	* doc/ttk_panedwindow.n, library/ttk/panedwindow.tcl: Changed
	documentation of ttk::panedwindow 'identify' command to match
	implementation.

	* generic/ttk/ttkNotebook.c, tests/ttk/notebook.test:
	BUGFIX: ttk::noteboook 'insert' command didn't correctly maintain
	current tab.

2007-06-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXColor.c: Fix issues with TK_{IF,ELSE,ENDIF} macros;
	* macosx/tkMacOSXDraw.c:  implement Jaguar equivalent of unavailable
	* macosx/tkMacOSXEntry.c: kHIToolboxVersion global; panic at startup
	* macosx/tkMacOSXEvent.c: if MAC_OS_X_VERSION_MIN_REQUIRED constraint
	* macosx/tkMacOSXInit.c:  is not satisfied.
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDraw.c (XCopyArea, XCopyPlane, TkPutImage)
	(TkMacOSXSetupDrawingContext): Factor out common code and standardize
	setup/restore of port, context and clipping; formatting cleanup.

	* macosx/tkMacOSXWindowEvent.c:	Add error checking.
	* macosx/tkMacOSXMenu.c:	Fix gcc3 warning.
	* macosx/tkMacOSXScrlbr.c:	Fix testsuite crash.
	* macosx/tkMacOSXSubwindows.c:	Formatting cleanup.
	* macosx/tkMacOSXRegion.c:	Fix typos.
	* macosx/tkMacOSXScale.c:

	* macosx/tkMacOSXXStubs.c (Tk_GetUserInactiveTime): Remove superfluous
							    CFRetain/CFRelease.

	* macosx/Wish-Release.xcconfig: Disable tktest release build stripping.

	* macosx/Wish.xcodeproj/project.pbxproj: Add new Tclsh-Info.plist.in.

2007-06-06  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXInt.h: Use native debug message API when available.
	* macosx/Wish-Debug.xcconfig:

	* macosx/tkMacOSXMouseEvent.c (GenerateMouseWheelEvent): Enable
	processing of mousewheel events in background windows.

	* macosx/tkMacOSXScrlbr.c: Modernize checks for active/front window.
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXColor.c: Factor out verbose #ifdef checks of
	* macosx/tkMacOSXDraw.c:  MAC_OS_X_VERSION_{MAX_ALLOWED,MIN_REQUIRED}
	* macosx/tkMacOSXEntry.c: and runtime checks of kHIToolboxVersion into
	* macosx/tkMacOSXEvent.c: new TK_{IF,ELSE,ENDIF}_MAC_OS_X macros.
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDraw.c:  Factor out clip clearing in QD ports;
	* macosx/tkMacOSXEntry.c: Formatting cleanup.

	* macosx/Wish.xcodeproj/project.pbxproj: Add settings for Fix&Continue.

	* unix/configure.in (Darwin): Link the Tk and Wish plists into their
	binaries in all cases; fix 64bit arch removal in fat 32&64bit builds.

	* unix/tcl.m4 (Darwin): Fix CF checks in fat 32&64bit builds.
	* unix/configure: autoconf-2.59

2007-06-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/photo.n: Clarified the fact that base64 support for the -data
	option is not universal. [Bug 1731348] (matzek)

2007-06-03  Daniel Steffen  <das@users.sourceforge.net>

	* unix/Makefile.in: Add datarootdir to silence autoconf-2.6x warning.

	* macosx/Wish.xcodeproj/default.pbxuser: Add ttk tests.

	* macosx/tkMacOSXMenu.c: Add error checking; whitespace cleanup.

	* macosx/tkMacOSXDraw.c:	Comment formatting fixes for Xcode 3.0
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

2007-06-02  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXMenu.c (TkpPostMenu): Ensure cascade menus display in
	posted menus that are not part of the menubar or attached to a
	menubutton (fixes bug reported on tcl-mac by Linus Nyberg).

2007-05-31  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWindowEvent.c (GenerateUpdateEvent): Complete all
	pending idle-time redraws before newly posted Expose events are
	processed; add bounds of redrawn windows to update region to ensure
	all child windows overdrawn by parents are redrawn.

	* macosx/tkMacOSXWindowEvent.c:	Centralize clip and window invalidation
	* macosx/tkMacOSXSubwindows.c: 	after location/size changes in the
	* macosx/tkMacOSXWm.c:		BoundsChanged carbon event handler;
	correct/add window invalidation after window attribute changes.

	* macosx/tkMacOSXSubwindows.c (XResizeWindow, XMoveResizeWindow)
	(XMoveWindow): Factor out common code dealing with embedded and
	non-toplevel windows; remove unnecessary clip and window invalidation.

	* macosx/tkMacOSXButton.c (TkpDisplayButton): Move clip setup closer
	to native button drawing calls.

	* macosx/tkMacOSXWm.c (TkMacOSXIsWindowZoomed, TkMacOSXZoomToplevel):
	Correct handling of gridded windows in max size calculations.

	* macosx/tkMacOSXEvent.c (TkMacOSXFlushWindows): Use HIWindowFlush API
	when available.

	* macosx/tkMacOSXColor.c:	Cleanup whitespace and formatting.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:

	* generic/tkFont.c:	#ifdef out debug msg printing to stderr.
	* generic/tkTextDisp.c:

2007-05-30  Don Porter  <dgp@users.sourceforge.net>

	* generic/tk.h: Correct placement of #include <tcl.h>. [Bug 1723812]

2007-05-30  Daniel Steffen  <das@users.sourceforge.net>

	* library/bgerror.tcl:	Standardize dialog option & button size
	* library/dialog.tcl:	modifications done when running on on Aqua.
	* library/msgbox.tcl:

	* library/demos/button.tcl: Set button highlightbackground on Aqua.

	* macosx/tkMacOSXMenu.c (DrawMenuSeparator): Use DrawingContext API.

	* macosx/tkMacOSXWindowEvent.c (ClearPort): Clip to updateRgn.

	* macosx/tkMacOSXDebug.c:	Factor out debug region flashing.
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXEvent.c:	Cleanup whitespace and formatting.
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* xlib/xgc.c:

	* macosx/Wish.xcodeproj/project.pbxproj: Delete references to removed
	* macosx/Wish.xcodeproj/default.pbxuser: ttk files.

2007-05-28  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* macosx/tkMacOSXFont.c (TkpMeasureCharsInContext): Fix short measures
	with flags=TK_WHOLE_WORDS|TK_AT_LEAST_ONE [Bug 1716141]. Make some
	casts unnecessary by changing variable types.

2007-05-25  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/ttk.tcl: Omit ttk::dialog and dependencies.
	* library/ttk/dialog.tcl, library/ttk/icons.tcl,
	* library/ttk/keynav.tcl: Removed.
	* tests/ttk/misc.test: Removed.
	* doc/ttk_dialog.tcl: Removed.

2007-05-25  Donal K. Fellows  <dkf@users.sf.net>

	* doc/canvas.n: Fixed documentation of default -joinstyle option
	values for line and polygon items. [Bug 1725782]

2007-05-22  Don Porter  <dgp@users.sourceforge.net>

	[core-stabilizer-branch]

	* unix/configure:    autoconf-2.59 (FC6 fork)
	* win/configure:

	* README:        Bump version number to 8.5b1
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

2007-05-18  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkEntry.c(EntrySetValue):  Ensure that widget is in a
	consistent state before setting the linked -textvariable. Previously,
	it was possible for [$e index insert] to point past the end of the
	string, leading to heap corruption. [Bug 1721532]
	* tests/ttk/entry.test(entry-9.1): Add test case for the above.

2007-05-18  Don Porter  <dgp@users.sourceforge.net>

	* unix/configure:    autoconf-2.59 (FC6 fork)
	* win/configure:

	* README:        Bump version number to 8.5a7
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

	* tests/ttk/treetags.test:	Another bit of test suite
	SCIM-tolerance. [Bug 1609316]

2007-05-17  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tk.decls: Workaround 'make checkstubs' failures from
	tkStubLib.c MODULE_SCOPE revert. [Bug 1716117]

	* macosx/Wish.xcodeproj/project.pbxproj: Add tkOldTest.c and remove
						 tkStubImg.c.

2007-05-16  Joe English  <jenglish@users.sourceforge.net>

	* generic/tkStubLib.c:  Change Tk_InitStubs(), tkStubsPtr, and the
	auxilliary stubs table pointers back to public visibility. See [Bug
	1716117] for details.

	Removed TCL_STORAGE_CLASS monkey business, as it had no effect.

2007-05-16  Don Porter  <dgp@users.sourceforge.net>

	* library/choosedir.tcl:	Removed uses of obsolete {expand}
	* library/comdlg.tcl:		syntax; replaced with the now
	* library/tk.tcl:		approved {*}. [Bug 1710633]
	* tests/canvImg.test:
	* tests/imgPhoto.test:

	* tests/bind.test:  Make test suite more SCIM-tolerant. [Bug 1609316]

2007-05-16  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/makefile.vc: Test ttk widgets.

2007-05-15  Joe English  <jenglish@users.sourceforge.net>

	* unix/tkUnixRFont.c: Fix crash introduced by previous fix exposed
	under newer fontconfig libraries [Bug 1717830] again.

2007-05-15  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkGrid.c: Stop crash due to list intrep shimmer [Bug 1677608]

2007-05-15  Joe English  <jenglish@users.sourceforge.net>

	* unix/tkUnixRFont.c: Fix various memory leaks. [Bug 1717830], [Bug
	800149]

2007-05-14  Don Porter  <dgp@users.sourceforge.net>

	[Tk Bug 1712081]

	* unix/Makefile.in:	Updates to account for new and deleted files
	* win/Makefile.in:	tkStubImg.c and tkOldTest.c.
	* win/makefile.bc:
	* win/makefile.vc:

	* generic/tkOldTest.c (new):	New file used to create testing
	* generic/tkTest.c:		commands for testing various Tk
	* tests/constraints.tcl:	legacy interfaces where a separate
	* tests/image.test:		compilation unit is needed in order to
	#define suitable macros during compilation. Only the effect of
	USE_OLD_IMAGE on Tk_CreateImageType() is currently tested, but more
	similar testing commands can be added to this same file. New
	constraint defined to detect presence of the image type provided by
	the new testing code, and a few tests added to exercise it. Having
	USE_OLD_IMAGE support tested by the default test suite should reduce
	chance of a recurrence of this bug.

	* doc/CrtImgType.3:	Revised docs to better indicate the legacy
	* doc/CrtPhImgFmt.3:	nature of the interfaces supported by
	USE_OLD_IMAGE.

	* generic/tkDecls.h:	make genstubs
	* generic/tkStubInit.c:

	* generic/tk.decls:		Reworked USE_OLD_IMAGE support to use
	* generic/tk.h:			the same support mechanisms both with
	* generic/tkStubImg.c (deleted):and without a stub-enabled build. In
	each case, route the legacy calls to Tk_CreateImageType and
	Tk_CreatePhotoImageFormat through the Tk_CreateOldImageType and
	Tk_CreateOldPhotoImageFormat routines. Add those routines to the
	public stub table so they're available to a stub-enabled extension.
	Remove the definition of Tk_InitImageArgs() and use a macro to convert
	any calls to it in source code into a comment.

	* generic/tkImage.c:	Removed the MODULE_SCOPE declarations that
	* generic/tkImgPhoto.c:	broke USE_OLD_IMAGE support.

2007-05-11  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* tests/winButton.test: Avoid font dependencies in results.

	* generic/tkFont.c: propagate error from TkDeleteNamedFont. [Bug
	1716613]

2007-05-09  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkFileFilter.c (AddClause): OSType endianness fixes.

	* library/palette.tcl (tk::RecolorTree): Handle color options with
	empty value, fixes error due to emtpy -selectforeground (reported on
	tcl-mac by Russel E. Owen).

	* macosx/tkMacOSXWindowEvent.c:	Ensure window is brought to the front
	* macosx/tkMacOSXMouseEvent.c:	at the start of a window drag (except
	* macosx/tkMacOSXInt.h:		when cmd key is down); formatting and
					whitespace fixes.

	* macosx/tkMacOSXDialog.c (Tk_GetSaveFileObjCmd): Add -filetypes option
	processing (fixes fileDialog-0.1, fileDialog-0.2 failures).

	* macosx/tkMacOSXEmbed.c (TkpMakeWindow, TkpUseWindow): Fix sending of
	Visibility event for embedded windows (fixes frame-3.9 hang).

	* macosx/tkMacOSXScrlbr.c (ScrollbarBindProc):		Fix testsuite
	* macosx/tkMacOSXSubwindows.c (TkMacOSXUpdateClipRgn):	crashes by
	adding sanity checks.

	* macosx/Wish.xcodeproj/project.pbxproj: Add 'DebugUnthreaded' &
	* macosx/Wish.xcodeproj/default.pbxuser: 'DebugLeaks' targets and env
	var settings needed to run the 'leaks' tool.

	* macosx/tkMacOSXButton.c: Fix debug msg typo.

	* tests/constraints.tcl: Ensure 'nonUnixUserInteraction' constraint is
	set for aqua.

	* tests/choosedir.test:	Add 'notAqua' constraints to X11-only tests;
	* tests/clrpick.test:	add 'nonUnixUserInteraction' to 'unix' tests
	* tests/menuDraw.test:	requiring interaction on aqua.
	* tests/unixMenu.test:
	* tests/unixWm.test:
	* tests/winMenu.test:

2007-05-07  Joe English  <jenglish@users.sourceforge.net>

	* unix/tkUnixRFont.c: Properly cast sentinel arguments to variadic
	function (fixes "warning: missing sentinel in function call", [Bug
	1712001])

2007-05-04  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkFont.c:  TIP #145 implementation -
	* generic/tkFont.h:  Enhanced font handling.
	* win/tkWinDefault.h:
	* win/tkWinFont.c:
	* win/tkWinInt.h:
	* win/tkWinWm.c:
	* library/demos/widget:
	* library/ttk/fonts.tcl:

2007-05-04  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/ttk_treeview.n, doc/ttk_panedwindow.n, doc/ttk_dialog.n:
	* doc/ttk_checkbutton.n, doc/tk.n, doc/menu.n, doc/font.n:
	* doc/canvas.n: Spelling fixes. [Bug 1686210]

2007-05-03  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* generic/tkStubLib.c (Tk_InitStubs):
	* generic/ttk/ttkLabel.c (LabelSetup):
	* unix/tkUnixSelect.c (ConvertSelection):
	* unix/tkUnixEvent.c (TkUnixDoOneXEvent):
	* generic/tkConfig.c (Tk_RestoreSavedOptions):
	* generic/tkCanvPs.c (TkCanvPostscriptCmd):
	* generic/tkOption.c (GetDefaultOptions):
	* unix/tkUnixRFont.c (TkpGetFontAttrsForChar, InitFont)
	(TkpGetFontFamilies, TkpGetSubFonts):
	* unix/tkUnixSend.c (TkpTestsendCmd, RegOpen): Squelch warnings from
	GCC type aliasing. [Bug 1711985 and others]

2007-04-29  Daniel Steffen  <das@users.sourceforge.net>

	* unix/configure.in: Fix for default case in tk debug build detection.
	* unix/configure: autoconf-2.59

2007-04-27  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTreeview.c(TagOptionSpecs): Use TK_OPTION_STRING
	instead of TK_OPTION_FONT to avoid resource leak in tag management.

2007-04-26  Joe English  <jenglish@users.sourceforge.net>

	* macosx/ttkMacOSXTheme.c: Merged OFFSET_RECT processing into
	BoxToRect(); factored out PatternOrigin; resynchronized with Tile
	codebase.

2007-04-26  Jeff Hobbs  <jeffh@ActiveState.com>

	*** 8.5a6 TAGGED FOR RELEASE ***

	* unix/Makefile.in (dist): Correct tests/ttk glob inclusion

2007-04-25  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/Makefile.in (dist): Add tests/ttk dir to src dist

	* unix/tkUnixMenubu.c (TkpDisplayMenuButton): Init width/height to 0

2007-04-25  Daniel Steffen  <das@users.sourceforge.net>

	* unix/Makefile.in (dist): Add macosx/*.xcconfig files to src dist;
	copy license.terms to dist macosx dir; fix autoheader bits.

2007-04-24  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/Makefile.in (dist): Add ttk bits to src dist

	* tests/font.test (font-46.[12]): Correct listification of result

2007-04-23  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkCanvas.c:	Allow -selectforeground option to be None; add
	* generic/tkCanvText.c:	fallback to fgColor when selFgColor is None
	* generic/tkEntry.c:	(new default on aqua to match native L&F).
	* generic/tkListbox.c:
	* generic/tkText.c:

	* generic/tkCanvas.c:	   Add support for bypassing all of Tk's double
	* generic/tkEntry.c:	   buffered drawing into intermediate pixmaps
	* generic/tkFrame.c:	   (via TK_NO_DOUBLE_BUFFERING #define), it is
	* generic/tkListbox.c:	   unnecessary & wasteful on aqua where all
	* generic/tkPanedWindow.c: drawing is already double-buffered by the
	* generic/tkTextDisp.c:	   window server. (Use of this on other
	* generic/ttk/ttkWidget.c: platforms would only require implementation
	* unix/tkUnixScale.c:	   of TkpClipDrawableToRect()).
	* macosx/tkMacOSXPort.h:

	* library/bgerror.tcl:	On aqua, use moveable alert resp. modal dialog
	* library/dialog.tcl:	window class and corresponding system
				background pattern; fix button padding.

	* library/tearoff.tcl:	Correct aqua menu bar height; vertically offset
	* library/tk.tcl:	aqua tearoff floating window to match menu.

	* library/demos/goldberg.tcl: Fix overwriting of widget demo global.

	* library/demos/menu.tcl:   On aqua, use custom MDEF and tearoffs;
	* library/demos/menubu.tcl: correct menubutton toplevel name.

	* library/demos/puzzle.tcl: Fix button size & padding for aqua.
	* library/demos/radio.tcl:

	* macosx/tkMacOSXCarbonEvents.c: Add window event target carbon event
	* macosx/tkMacOSXEvent.c:	 handler for all kEventClassWindow and
	* macosx/tkMacOSXEvent.h:	 kEventClassMouse events; move all
	* macosx/tkMacOSXNotify.c:	 remaining events except for
	* macosx/tkMacOSXWindowEvent.c:	 kEventClassKeyboard from dispatcher to
	application event handler; pass event handler callRef downstream; fix
	debug event tracing; process all tcl event types in carbon event timer;
	delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark
	enter/exit of event tracking loop during which all tcl events but only
	carbon update events should be processed by the timer (replaces various
	calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent()
	to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to
	tkMacOSXCarbonEvents.c and modify it to dequeue only update events
	during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize
	the various ways in use to run the tcl event loop; add handling of
	kEventClassAppearance events (for ScrollBarVariantChanged event).

	* macosx/tkMacOSXDialog.c:	Use new TkMacOSXTrackingLoop() around
	* macosx/tkMacOSXEvent.c:	blocking API that puts up modal dialogs
	* macosx/tkMacOSXMenu.c:	or when entering/exiting menu/control
	* macosx/tkMacOSXMouseEvent.c:	tracking, window dragging and other
	* macosx/tkMacOSXScale.c:	mouse tracking loops.
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:	Use new TkMacOSXRunTclEventLoop()
	* macosx/tkMacOSXScale.c:	instead of Tcl_DoOneEvent(),
	* macosx/tkMacOSXScrlbr.c:	Tcl_ServiceAll(), TclServiceIdle()
	* macosx/tkMacOSXWindowEvent.c:	and Tcl_GlobalEval("update idletasks").

	* macosx/tkMacOSXColor.c: Make available as Tk system colors all
	* macosx/tkMacOSXPort.h:  appearance manager brushes, text colors and
	backgrounds with new and legacy names, as well as the fully transparent
	color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to
	directly set an X pixel color value in the current QD port resp. the
	given CG context without requiring passage through rgb representation
	(lossy for most system colors); modernize/remove Classic-era code;
	replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct().

	* macosx/tkMacOSXButton.c:	Use new TkMacOSXSetColorInPort()
	* macosx/tkMacOSXDraw.c:	instead of setting rgb color directly
	* macosx/tkMacOSXMenubutton.c:	to allow for non-rgb system colors.

	* macosx/tkMacOSXCursor.c: Implement "none" cursor as on other
	platforms [Patch 1615427]; add all missing appearance manager cursors.

	* macosx/tkMacOSXDefault.h: Set SELECT_FG_COLORs to None to match aqua
	L&F; use standard system color names; use new 'menu' system font;
	correct default scrollbar width.

	* macosx/tkMacOSXDraw.c: 	Standardize initialization, use and
	* macosx/tkMacOSXInt.h: 	emptying of various static temp rgns
	* macosx/tkMacOSXRegion.c:	onto two global RgnHandles; in debug
	* macosx/tkMacOSXSubwindows.c:	builds, verify emptiness of these temp
	* macosx/tkMacOSXWindowEvent.c:	rgns before use.

	* macosx/tkMacOSXDraw.c: Add TkMacOSX{Setup,Restore}DrawingContext() to
	* macosx/tkMacOSXInt.h:  abstract common setup & teardown of drawing
	environment (for both CG and QD); save/restore QD theme drawing state;
	handle GC clip region; add TkpClipDrawableToRect() to allow clipped
	drawing into drawable regardless of GC used; use new system color
	"systemWindowHeaderBackground" to setup background in themed toplevels;
	correct implementation of TkMacOSXMakeStippleMap().

	* macosx/tkMacOSXEntry.c:  Use new TkMacOSXSetupDrawingContext() and
	* macosx/tkMacOSXFont.c:   TkMacOSXRestoreDrawingContext() instead of
	* macosx/ttkMacOSXTheme.c: various setup/teardown procs like
	TkMacOSX{SetUp,Release}CGContext(), TkMacOSXQuarz{Start,End}Draw(),
	TkMacOSXSetUpGraphicsPort() etc.

	* macosx/tkMacOSXEmbed.c: Add CG context and drawable clip rgn fields
	* macosx/tkMacOSXInt.h:   to MacDrawable struct.
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXDialog.c: Make -parent option of tk_getOpenFile et al.
	use the sheet version of NavServices dialogs; ensure native parent win
	exists before using StandardSheet API for tk_messageBox [Bug 1677611];
	force sheets to behave like app-modal dialogs via WindowModality() API;
	use more modern ColorPicker API.

	* macosx/tkAboutDlg.r: Use themed movable modal dialog, fix (c) year.

	* macosx/tkMacOSXEntry.c:  Take xOff/yOff of MacDrawable into account
	* macosx/ttkMacOSXTheme.c: when computing locations/bounds to ensure
	correct posititioning when not drawing into intermediate pixmap.

	* macosx/tkMacOSXFont.c: Use appearance manager API to map system font
	* macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for
	menu item text drawing from MDEF; always draw with CG; remove QD
	dependent stippling algorithm; move most header declarations into the
	source file (as they were not used anywhere else).

	* macosx/tkMacOSXMenu.c:		 Large-scale rewrite of custom
	* macosx/tkMacOSXMenu.r (removed):	 MDEF and related code that
	* macosx/Wish.xcode/project.pbxproj:	 restores many longtime-MIA
	* macosx/Wish.xcodeproj/project.pbxproj: features to working order
	* unix/Makefile.in:			 (e.g. images, custom colors &
	fonts in menus etc); implement compound menu items; use Appearance Mgr
	and ThemeText APIs to mimic native MDEF as closely as possible when
	default "menu" system font is used; remove now obsolete SICN drawing
	code and resources.

	* macosx/tkMacOSXCarbonEvents.c: Handle additional menu carbon events
	* macosx/tkMacOSXEvent.c:	 in order to support <<MenuSelect>> in
	* macosx/tkMacOSXMenu.c:	 the menubar and in menus that are not
	* macosx/tkMacOSXMenus.c:	 using the custom MDEF [Bug 1620826];
	fix early and missing clearing of current Tk active menu entry; fix
	extraneous sending of <<MenuSelect>> during active menu entry clearing.

	* macosx/tkMacOSXMouseEvent.c: Add support for async window dragging by
	the window server; set the corresponding window attribute by default.

	* macosx/tkMacOSXMouseEvent.c: Rationalized handling order of
	non-mousedown events; add TkMacOSXModifierState() to retrieve the
	current key modifiers in carbon format.

	* macosx/tkMacOSXScrlbr.c: Use appearance manager API to retrieve
	scrollbar component metrics; add awareness of multiple possibilites for
	scrollbar arrow position in aqua and handle user changes to arrow
	position pref; handle difference in metrics of small & large scrollbar
	variants; handle aqua "jump to here" scrollbar behaviour; correct
	computation of scroll view size and position; enforce min scrollbar
	height to avoid scrollbar component overlap; erase scrollbar area
	outside of standard width; remove broken auto-adjust code; account for
	window class when leaving space for grow box; remove code to manually
	draw grow box; use modern API for thumb scroll proc; replace
	HiliteControl() by modern API; replace control mgr constants with
	appearance mgr equivalents.

	* macosx/tkMacOSXSubwindows.c: Use SetWindowBounds() API instead of
	SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix
	for [Bug 940117] made them dependent on mapping state; remove unneeded
	calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port;
	use native-endian pixmap on intel; remove obsolete pixmap pix locking.

	* macosx/tkMacOSXWindowEvent.c: Handle only the first of a batch of
	kEventAppAvailableWindowBoundsChanged events sent per transaction;
	handle kEventWindowBoundsChanged event to support live window resizing
	and centralized sending of location/size changed ConfigureNotify
	events; ensure HIGrowBox is redrawn after bounds change; constrain
	window after dragging to ensure titlebar is not inacessible
	offscreen or under dock/menubar; handle kEventWindowGetRegion and
	kEventWindowDrawContent for transparent windows to mark resp. paint
	content region as transparent; handle kEventWindowConstrain for
	fullscreen windows to ensure bounds match new screen size; enter/exit
	fullscreen UIMode upon activation/deactivation of fullscreen window.

	* macosx/tkMacOSXWm.c: Use live-resize and async-drag carbon window
	* macosx/tkMacOSXWm.h: attributes for toplevels by default; implement
	new [wm attributes] -topmost, -transparent and -fullscreen; refactor
	WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus
	factored proc to set proxy icon from [wm iconbitmap]; dynamically
	determine default values for toplevel min and max sizes (similar to
	tkWinWm.c impl): min sizes depend on window class & attributes to
	ensure visibility of all titlebar widgets and grow box, max sizes
	depend on maximal window bounds for all active displays; factor out
	code that puts into effect changes to master or override_redirect; use
	RepositionWindow() API to determine staggered initial window bounds;
	correct resize limit calculations, handle gridding and use modern
	resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify
	after resize or zoom (now handled by BoundsChanged handler); correct
	composite carbon window attribute handling, remove currently unusable
	attributes and add new attributes in [tk::unsupported::MacWindowStyle];
	ensure validity of window class and attributes before use; apply
	changes to window class when handling carbon window attribute changes
	(if HIWindowChangeClass() API available); add debug build warning
	message when deprecated window style is used instead of window class;
	use transparent HIGrowBox for resizable windows; avoid unnecessary
	calls to window structure width API; use tcl time API in TkpGetMS();
	add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and
	menubar hidden; restrict wmTracing output to debug builds; remove
	unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD
	port; workaround GetWindowStructureWidths() Carbon bug (bogus results
	for never-mapped floating windows).

	* macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): Add maximal window
	bounds field to Screen record (in ext_data), computed as the union of
	available window positioning bounds of all graphics devices (displays).

	* macosx/tkMacOSXBitmap.c: Fix macRoman encoding leak.
	* macosx/tkMacOSXCursor.c:

	* macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): Use static
	* macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes.

	* macosx/tkMacOSXBitmap.c: Use more efficient QDSwapPort() instead of
	* macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld().
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXColor.c: Use kHIToolboxVersionNumber for runtime OS
	* macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc.
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDraw.c: Remove obsolete and now incorrect
	* macosx/tkMacOSXInt.h:  tkMenuCascadeRgn clipping code.
	* macosx/tkMacOSXMenu.c:

	* macosx/tkMacOSXHLEvents.c: Replace Tcl_GlobalEval() resp. Tcl_Eval()
	* macosx/tkMacOSXScrlbr.c:   by Tcl_EvalEx().
	* macosx/tkMacOSXInit.c:

	* macosx/tkMacOSXInit.c (TkpInit): Reorder initialization steps.

	* macosx/tkMacOSXKeyEvent.c: Remove pre-10.2 support.

	* macosx/tkMacOSXMenus.c: Remove now useless call to
	TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman
	literar chars to allow file to be edited as utf-8.

	* macosx/tkMacOSXScale.c: Replace TrackControl() by modern
	* macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new
	TkMacOSXModifierState()).

	* macosx/tkMacOSXInt.h:		Move all constant #defines needed to
	* macosx/tkMacOSXColor.c:	support building on older OS X releases
	* macosx/tkMacOSXEvent.h:	to a central location in tkMacOSXInt.h.
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/ttkMacOSXTheme.c:

	* macosx/tkMacOSXInt.h:		 Add ChkErr() macro to factor out
	* macosx/tkMacOSXButton.c:	 Carbon OSStatus return value checking
	* macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour
	* macosx/tkMacOSXClipboard.c:	 out debug message output; use these
	* macosx/tkMacOSXColor.c:	 macros to replace #ifdef TK_MAC_DEBUG
	* macosx/tkMacOSXCursor.c:	 blocks & direct printing to stderr,
	* macosx/tkMacOSXDebug.c:	 and to do additional OSStatus return
	* macosx/tkMacOSXDialog.c:	 checking, and to standardize OSStatus
	* macosx/tkMacOSXDraw.c:	 usage.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXSend.c:	Remove duplicate/unused declarations.
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXDebug.c:	Const fixes.
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/Wish-Info.plist.in: Add tcl document extensions/mime types and
	LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys.

	* macosx/Wish-Common.xcconfig: Add Wish's Info.plist as __info_plist
	section to tktest; enable more warnings.

	* macosx/Wish.xcodeproj/project.pbxproj: Add 'DebugMemCompile' build
	configuration that calls configure with --enable-symbols=all; disable
	configure check for __attribute__((__visibility__("hidden"))) in Debug
	configuration to restore availability of ZeroLink.

	* macosx/Wish-Common.xcconfig:	Fix whitespace.
	* macosx/Wish-Debug.xcconfig:
	* macosx/Wish-Release.xcconfig:
	* macosx/tkMacOSXAETE.r:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursors.r:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXSend.c:
	* macosx/ttkMacOSXTheme.c:
	* macosx/tkMacOSXXCursors.r:
	* macosx/README:

	* macosx/GNUmakefile:		Fix/add copyright and license refs.
	* macosx/Tk-Info.plist.in:
	* macosx/Wish-Info.plist.in:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/project.pbxproj:
	* macosx/tkMacOSX.h:

	* unix/configure.in: Install license.terms into Tk.framework; fix tk
	debug build detection.
	* unix/configure: autoconf-2.59

	* doc/colors.n:		Document new Mac OS X system colors.
	* doc/cursors.n:	Document new Mac OS X native cursors.
	* doc/font.n:		Document new Mac OS X 'menu' system font.
	* doc/wm.n:		Document new Mac OS X [wm attributes].
	* doc/ttk_image.n:	Fix 'make html' warning.
	* doc/canvas.n:		Fix nroff typo.

2007-04-21  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXBitmap.c, macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXCarbonEvents.c, macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXCursor.c, macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c, macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c, macosx/tkMacOSXInit.c, macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c, macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c, macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c, macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c: Revert of commits from 2007-04-13 which broke
	the OS X build.

2007-04-17  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkFont.c, generic/tkListbox.c, unix/tkUnixSelect.c:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c: Make
	the format of declarations much more standardized (removing K&R-isms
	and other things like that).

2007-04-13  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* macosx/tkMacOSXInt.h (LOG_MSG, LOG_ON_ERROR): Added macros to make
	the OSX code much less #ifdef-full.

2007-04-12  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/ttk/panedwindow.tcl (ttk::panedwindow::Press): handle Press
	triggering outside sash element boundaries.

2007-04-10  Joe English  <jenglish@users.sourceforge.net>

	* win/ttkWinMonitor.c, win/ttkWinXPTheme.c: Re-sync with Tile codebase
	so patches can flow back and forth.

	* win/ttkWinXPTheme.c: Skip OS version test, should work on Vista/Aero
	now as well as XP. Fixes [Bug 1687299], thanks to George Petasis for
	tracking this down.

2007-03-21  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkLayout.c(Ttk_BuildLayoutTemplate): BUGFIX: Nested
	TTK_GROUP nodes did not work unless they appeared at the end of the
	layout (and only by accident then).

2007-03-08  Joe English  <jenglish@users.sourceforge.net>

	* tests/grid.test(grid-21.7): Reset wm geometry . and pack propagate .
	at end of test. 'pack propagate . 0' was causing cascading failures in
	subsequent tests. [Bug 1676770]

2007-03-07  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkMain.c (Tk_MainEx): Replicate macosx-specific code from
	TkpInit() that ensures the console window appears when wish is started
	from the OS X Finder (i.e. with stdin == /dev/null), jeffh's 2006-11-24
	change rendered the corresponding code in TkpInit() ineffective in wish
	because Tk_MainEx() sets tcl_interactive before calling TkpInit().

	* generic/ttk/ttkGenStubs.tcl (new): Add ttk-specific genstubs.tcl from
	* unix/Makefile.in (genstubs):  tile and run it from 'genstubs'
	target, restores ability to generate all of Tk's stub sources.

	* generic/ttk/ttkTreeview.c: #ifdef out unused declaration.

	* macosx/tkMacOSXDebug.c (TkMacOSXGetNamedDebugSymbol): Add fix for
	libraries loaded with a DYLD_IMAGE_SUFFIX.

	* macosx/Wish.xcodeproj/project.pbxproj: Ensure gcc version used by
	* macosx/Wish.xcodeproj/default.pbxuser: Xcode and configure/make are
	* macosx/Wish-Common.xcconfig:		 consistent and independent of
	gcc_select default and CC env var; fixes for Xcode 3.0.

	* unix/tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in macosx-version-min check.
	* unix/configure: autoconf-2.59

2007-02-25  Peter Spjuth  <peter.spjuth@space.se>

	* generic/tkUtil.c: Fixed grid anchor center problem in labelframes.
	* tests/grid.test:  [Bug 1545765]

2007-02-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/ttk/notebook.tcl (ttk::notebook::enableTraversal): OS X
	needs Option instead of Alt binding

2007-02-19  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/tcl.m4: use SHLIB_SUFFIX=".so" on HP-UX ia64 arch.
	* unix/configure: autoconf-2.59

	* library/tkfbox.tcl (::tk::IconList_Goto): avoid goto issues in empty
	dirs. [Bug 1662959]

2007-02-09  Joe Mistachkin  <joe@mistachkin.com>

	* win/nmakehlp.c: Properly cleanup after nmakehlp, including the
	* win/makefile.vc: vcX0.pch file. Sync up fixed nmakehlp usage from
	Tcl.

2007-02-06  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/ttk.tcl: Add no-op [package ifneeded] script for tile
	0.8.0, so that existing applications that use "package require tile"
	won't fail when run under Tk 8.5.

2007-02-04  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4: Use gcc4's __attribute__((__visibility__("hidden"))) if
	available to define MODULE_SCOPE effective on all platforms.
	* unix/configure.in: add caching to -pipe check.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

2007-02-03  Joe Mistachkin  <joe@mistachkin.com>

	* win/rules.vc: Fix platform specific file copy macros for downlevel
	Windows.
	* win/ttkWinMonitor.c: Windows portability support. Fix "noxp" build
	* win/ttkWinXPTheme.c: option handling and use GetWindowLongPtr and
	SetWindowLongPtr only when needed.

2007-02-02  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/ttkWinXPTheme.c: Support IsAppThemed() call. This is what is
	used when theming is turned off just for an individual application.

2007-01-28  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcodeproj/project.pbxproj:   Extract build settings that
	* macosx/Wish.xcodeproj/default.pbxuser:   were common to multiple
	* macosx/Wish-Common.xcconfig (new file):  configurations into external
	* macosx/Wish-Debug.xcconfig (new file):   xcconfig files; add extra
	* macosx/Wish-Release.xcconfig (new file): configurations for building
	with SDKs; convert legacy jam-based 'Tk' target to native target with
	single script phase; correct syntax of build setting references to use
	$() throughout; remove unused tcltest sources from 'tktest' target.

	* macosx/README: Document new Wish.xcodeproj configurations; other
	minor updates/corrections.

	* generic/tk.h: Update location of version numbers in macosx files.

	* macosx/Wish.xcode/project.pbxproj: Restore 'tktest' target to working
	* macosx/Wish.xcode/default.pbxuser: order by replicating applicable
	changes to Wish.xcodeproj since 2006-07-20.

2007-01-25  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4: Integrate CPPFLAGS into CFLAGS as late as possible and
	move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
	avoid errors about multiple -isysroot flags from some older gcc builds.

	* unix/configure: autoconf-2.59

2007-01-19  Joe Mistachkin  <joe@mistachkin.com>

	* win/makefile.vc: Properly build man2tcl.c for MSVC8.

2007-01-19  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcodeproj/project.pbxproj: Remove libtommath defines.

	* unix/tcl.m4: Ensure CPPFLAGS env var is used when set. [Bug 1586861]
	(Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
	present in CFLAGS to avoid discrepancies between what headers configure
	sees during preprocessing tests and compiling tests.

	* unix/configure: autoconf-2.59

2007-01-11  Jeff Hobbs  <jeffh@activestate.com>

	* unix/tkUnixEvent.c, library/msgs/es.msg: s/CRLF/LF/g

2007-01-11  Joe English  <jenglish@users.sourceforge.net>

	* win/tcl.m4 (CFLAGS_WARNING): Remove "-Wconversion". This was removed
	from unix/tcl.m4 2004-07-16 but not from here.
	* win/configure: Regenerated.

2007-01-11  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkManager.h, generic/ttk/ttk*.c: Revert addition of
	contravariant 'const' qualifiers, to keep in sync with Tile codebase
	(which must remain compatible with Tk 8.4).

2007-01-03  Jan Nijtmans  <nijtmans@users.sf.net>

	* doc/ManageGeom.3,
	* generic/tk.decls,
	* generic/tk.h: Add const to 2nd parameter of Tk_ManageGeometry
	* generic/tkDecls.h: regenerated
	* generic/tkInt.h,
	* generic/tk*.c,
	* generic/ttk/ttk*.c: Added many "const" specifiers in implementation.

2007-01-02  Donal K. Fellows  <dkf@users.sf.net>

	* xlib/*: Made the generic fake-X11 glue layer abide by the formatting
	rules of the core.

2006-12-31  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* macosx/tkMacOSXFont.c: Fill-in TkpGetFontAttrsForChar (TIP #300).
	* macosx/ttkMacOSXTheme.c: Define a constant to make it compile on Mac
	OS X 10.3.

2006-12-28  Mo DeJong  <mdejong@users.sourceforge.net>

	* tests/wm.test: Update wm attributes output so that tests pass after
	addition of -transparentcolor for Win32.

2006-12-26  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkLabel.c: ImageElement clientData no longer needed.

2006-12-22  Donal K. Fellows  <dkf@users.sf.net>

	* unix/tkUnixEvent.c (TkUnixDoOneXEvent): Made correct on AMD64 and
	other similar 64-bit systems where fd_mask is not 'unsigned int' in
	effect. [Bug 1522467]

	* library/msgs/es_ES.msg (removed):
	* library/msgs/es.msg: Fixed translation fault that was present in all
	Spanish-speaking locales. [Bug 1111213]

2006-12-19  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinButton.c (TkpDisplayButton): lint init. [Bug 1618604]

2006-12-19  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch
	flag succeeds before enabling 64bit build.
	* unix/configure: autoconf-2.59

2006-12-18  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTreeview.c, library/ttk/treeview.tcl, doc/treeview.n:
	Added column '-stretch' and '-minwidth' options. Improved column drag
	and resize behavior. Added horizontal scrolling [Bug 1518650]. Row
	height and child indent specifiable on Treeview style. Decreased
	default row height, no default -padding. Use correct heading height
	[Bug 1163349]. Apply tag settings to tree item as well as to data
	columns [NOTE: 'tag configure' still buggy]. Fix off-by-one condition
	when moving nodes forward [Bug 1618142]
	* generic/ttk/ttkScroll.c (TtkScrollTo): Prevent overscroll [Bug
	1173434]
	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl,
	* library/ttk/clamTheme.tcl, library/ttk/classicTheme.tcl,
	* library/ttk/defaults.tcl, library/ttk/winTheme.tcl,
	* library/ttk/xpTheme.tcl: Per-theme treeview settings.
	* macosx/ttkMacOSXTheme.c: Added disclosure triangle element.

2006-12-17  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/combobox.tcl, generic/ttk/ttkEntry.c,
	* doc/ttk_combobox.n: Add combobox -height option; only show scrollbar
	if the listbox needs to scroll. [Bug 1032869]

2006-12-16  Mo DeJong  <mdejong@users.sourceforge.net>

	* doc/cursors.n: Mention "none" in supported cursor list. Fix comment
	that incorrectly claims that the Win32 "no" cursor hides the cursor.
	* tests/cursor.test: Test "none" cursor.
	* unix/tkUnixCursor.c (CreateCursorFromTableOrFile)
	(TkGetCursorByName): Define a table of Tk cursors that is searched in
	addition to the X cursor table. A Tk cursor is loaded from a data
	string and works with the same options as the built in X cursors. This
	code makes it possible to use "none" as a cursor name under Unix.
	* win/rc/cursor9a.cur: Added none Win32 cursor.
	* win/rc/tk_base.rc: Define a built-in Win32 cursor named "none".
	[Patch 1615427]

2006-12-14  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkButton.c, generic/ttk/ttkElements.c,
	* generic/ttk/ttkEntry.c, generic/ttk/ttkFrame.c,
	* generic/ttk/ttkImage.c, generic/ttk/ttkInit.c,
	* generic/ttk/ttkLabel.c, generic/ttk/ttkNotebook.c,
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c,
	* generic/ttk/ttkScale.c, generic/ttk/ttkScrollbar.c,
	* generic/ttk/ttkSeparator.c, generic/ttk/ttkTheme.h,
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.h:
	Global reduction: use per-file *_Init() routines to reduce the number
	of globally-visible initialization records.

2006-12-13  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/Makefile.in (install-doc): intentionally skip ttk_dialog.n
	installation (not for public consumption)

	* doc/scrollbar.n, doc/button.n, doc/checkbutton.n:
	* doc/entry.n, doc/frame.n, doc/label.n, doc/labelframe.n:
	* doc/menu.n, doc/menubutton.n, doc/panedwindow.n:
	* doc/radiobutton.n, doc/scrollbar.n, doc/ttk_*: revamp ttk docs to
	use consist nroff format (not 100% consistent with classic widget
	docs). Add more man page cross-linking "SEE ALSO".

	* generic/ttk/ttkInit.c:
	* generic/ttk/ttkTreeview.c: make treeview exist by default
	* generic/ttk/ttkPanedwindow.c: s/TtkPaned_Init/TtkPanedwindow_Init/

	* win/Makefile.in, unix/Makefile.in (demo): add 'demo' target

2006-12-13  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/ttk.tcl: Try to straighten out theme loading and
	selection logic.
	* generic/ttk/ttkElements.c, library/ttk/defaults.tcl,
	* generic/ttk/ttkClamTheme.c, library/ttk/clamTheme.tcl:
	Provide package in C part instead of Tcl part.

2006-12-12  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/ttk.tcl, generic/ttkTheme.c: Remove nonfunctional code.

2006-12-12  Mo DeJong  <mdejong@users.sourceforge.net>

	* win/tkWinButton.c (InitBoxes): Call Tcl_Panic() if loading of bitmap
	resources fails. This change generates an error if Tk is unable to
	find button widget resources instead of silently failing and then
	drawing widgets incorrectly.
	* win/rc/tk_base.rc: If the user defines BASE_NO_TK_ICON then compile
	the base resources file without a "tk" icon. This change makes it
	easier to replace the default tk icon with a custom icon. [Patch
	1614362]

2006-12-11  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* unix/tkUnixWm.c (TkWmMapWindow, WmClientCmd): Added support for
	_NET_WM_PID property from the EWMH spec. This is only installed when
	the client machine is set.
	(WmProtocolCmd, UpdateWmProtocols, TkWmProtocolEventProc): Added
	support for the _NET_WM_PING protocol from the EWMH spec. Note that
	the support for this is not exposed to the script level as that would
	prevent correct handling.

2006-12-10  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h,
	* generic/ttk/ttk.decls, generic/ttk/ttkTheme.c,
	* generic/ttk/ttkLayout.c, generic/ttk/ttkDecls.h:
	Rename typedef Ttk_Element => Ttk_ElementImpl.

2006-12-09  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkButton.c, generic/ttk/ttkImage.c,
	* generic/ttk/ttkLabel.c, generic/ttk/ttkWidget.h,
	* generic/ttk/ttkTheme.h, generic/ttk/ttkNotebook.c,
	* generic/ttk/ttkTreeview.c, doc/ttk_image.n:
	Merged duplicate functionality between image element factory, image
	element, and -image option processing. Image element factory now takes
	an imageSpec argument instead of a separate image name and -map option
	* tests/ttk/image.test(image-1.1): Can catch this error earlier now.

2006-12-06  Kevin Kenny  <kennykb@acm.org>

	* unix/configure.in: Further changes to avoid attempting to link
	* unix/configure:   against Xft libraries in a non-Xft build
	         [Bug 1609616] (dgp)

2006-12-04  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkListbox.c (ConfigureListboxItem): ListboxWorldChanged not
	needed - just call EventuallyRedrawRange. [Bug 1608046] (rezic)

2006-12-04  Donal K. Fellows  <dkf@users.sf.net>

	TIP #286 IMPLEMENTATION

	* generic/tkMenu.c (MenuWidgetObjCmd, MenuDoXPosition):
	* doc/menu.n, tests/menu.test: Added an [$menu xposition] subcommand
	which is useful in menubars and when menus use multiple columns. Many
	thanks to Schelte Bron for the implementation.

2006-12-01  Kevin Kenny  <kennykb@acm.org>

	TIP #300 IMPLEMENTATION

	* doc/font.n:			Added a [font actual $font $char]
	* generic/tkFont.c:		variant that introspects the font that
	* generic/tkFont.h:		is chosen to render a given character
	* macosx/tkMacOSXFont.c:	in a given nominal font. Added
	* tests/font.test:		documentation and test cases for the
	* unix/tkUnixFont.c:		new command syntax.
	* unix/tkUnixRFont.c:
	* win/tkWinFont.c:

2006-12-01  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/wm.n, tests/winWm.test:
	* win/tkWinWm.c: add -transparentcolor attribute for Windows.

2006-12-01  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkTheme.h, generic/ttk/ttkLayout.c: Dead code removal.

2006-11-30  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDialog.c (Tk_MessageBoxObjCmd): fix inability to use
	buttons with standard Escape key binding as -default button (reported
	on tcl-mac by Hans-Christoph Steiner).

	* macosx/tkMacOSXWm.c (WmAttributesCmd): fix getting [wm attr -alpha].
	[Bug 1581932]

2006-11-28  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/fonts.tcl: Clean up temporary variables.

2006-11-27  Kevin Kenny  <kennykb@acm.org>

	* unix/configure.in: Corrected Xft configuration so that Xft actually
	does get turned on when available.
	* unix/configure: autoconf

2006-11-26  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkWidget.c, generic/ttk/ttkPaned.c: Fix [Bug 1603506]
	* library/ttk/button.tcl, library/ttk/combobox.tcl,
	* library/ttk/utils.tcl: Rename ttk::CopyBindings to ttk::copyBindings
	* generic/ttk/ttkTreeview.c, doc/ttk_treeview.n:
	-displaycolumns {} now means "no columns" instead of "all columns".
	Use -displaycolumns #all for "all columns". [Bug 1547622]

2006-11-26  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Linux): --enable-64bit support.	[Patch 1597389]
	* unix/configure: autoconf-2.59			[Bug 1230558]

2006-11-24  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXInit.c (TkpInit): only set tcl_interactive 1 if it
	isn't already defined. Allows embedders to set it to 0 to prevent the
	console appearing on OS X. [Bug 1487701]

	* unix/tkUnixMenu.c (DrawMenuUnderline): bound Tcl_UtfAtIndex usage
	* tests/menu.test (menu-36.1): [Bug 1599877]

2006-11-24  Joe English  <jenglish@users.sourceforge.net>

	* library/ttk/altTheme.tcl, library/ttk/clamTheme.tcl,
	* library/ttk/defaults.tcl, library/ttk/winTheme.tcl,
	* library/ttk/xpTheme.tcl: explicitly specify -anchor w on TMenubutton
	* tests/ttk/entry.test: Fixed font dependency; test entry-3.2 should
	work on all platforms now.
	* library/classicTheme.tcl: Don't define or use TkClassicDefaultFont.
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkPanedwindow.c: Handle
	missing layouts.

2006-11-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinMenu.c (TkWinHandleMenuEvent, DrawMenuUnderline): Handle
	unichar underlining correctly and safely. [Bug 1599877]

2006-11-20  Joe English  <jenglish@users.sourceforge.net>

	* win/ttkWinXPTheme.c: Add support for alternate/indeterminate
	checkbutton state. Fix various spacing parameters [Bug 1596020, patch
	from Tim Baker]. Remove unused uxtheme hooks.

2006-11-16  Donal K. Fellows  <dkf@users.sf.net>

	* doc/colors.n, doc/wm.n: Minor fixes, added See Also.

	* doc/labelframe.n: Added an example.

2006-11-15  Donal K. Fellows  <dkf@users.sf.net>

	* doc/label.n: Added an example and some See Also refs.

	* doc/ConfigWidg.3, doc/bind.n, doc/grid.n, doc/panedwindow.n:
	* doc/text.n, doc/ttk_Geometry.3, doc/ttk_button.n:
	* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
	* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n, doc/ttk_intro.n:
	* doc/ttk_label.n, doc/ttk_labelframe.n, doc/ttk_menubutton.n:
	* doc/ttk_notebook.n, doc/ttk_panedwindow.n, doc/ttk_progressbar.n:
	* doc/ttk_radiobutton.n, doc/ttk_scrollbar.n, doc/ttk_separator.n:
	* doc/ttk_sizegrip.n, doc/ttk_style.n, doc/ttk_widget.n, doc/wm.n:
	Convert \fP to \fR so that man-page scrapers have an easier time.

2006-11-14  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkDefaultTheme.c: Fix off-by-one bug in tree indicator
	size computation [Bug 1596021, patch from Tim Baker]. Increased
	default size from 7 to 9 pixels.

2006-11-12  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttkScroll.c: *correct* fix for [Bug 1588251].

2006-11-12  Joe English  <jenglish@users.sourceforge.net>

	* tests/ttk/ttk.test(ttk-6.9): Workaround for [Bug 1583038]

2006-11-12  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttkScroll.c: Reworked cleanup procedure; "self-cancelling"
	idle call is not robust, call Tcl_CancelIdleCall() in
	TtkFreeScrollHandle instead. Fixes [Bug 1588251]

2006-11-10  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcodeproj/project.pbxproj: remove tclParseExpr.c and
	bwidget.test.

	* unix/tcl.m4 (Darwin): suppress linker arch warnings when building
	universal for both 32 & 64 bit and no 64bit CoreFoundation is
	available; sync with tcl tcl.m4 change.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

2006-11-08  Kevin Kenny  <kennykb@acm.org>

	* unix/configure.in: Silenced warnings about missing Xft configuration
	unless --enable-xft is requested explicitly. Also added a few basic
	checks that we can actually compile and link against Xft headers and
	libraries. [Bug 1592667]
	* unix/configure: Regen.

2006-11-07  Kevin Kenny  <kennykb@acm.org>

	* unix/configure.in: Made --enable-xft the default.
	* unix/configure: Regen.

2006-11-06  Joe English  <jenglish@users.sourceforge.net>

	* generic/ttk/ttkClassicTheme.c, generic/ttk/ttkPanedwindow.c,
	* generic/ttk/ttkTheme.c, generic/ttk/ttkTreeview.c,
	* win/ttkWinXPTheme.c, library/ttk/entry.tcl,
	* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl,
	* library/ttk/utils.tcl, tests/ttk/entry.test, tests/ttk/bwidget.test:
	Miscellaneous minor changes to re-sync Ttk codebase with Tile CVS: fix
	comments damaged by overzealous search-and-destroy; removed obsolete
	[style default] synonym for [ttk::style configure]; removed other dead
	code.

2006-11-03  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* library/safetk.tcl (::safe::tkTopLevel): Theme it.

	* generic/ttk/ttkLayout.c:   We do not want to require tkInt in all
	* generic/ttk/ttkMananager.h:  the ttk files so added the definition
	* generic/ttk/ttkTheme.h:   of MODULE_SCOPE to ttkTheme.h. Ensures
	* generic/ttk/ttkWinMonitor.c: everyone gets to see the definition
	from someplace.

	* library/ttk/fonts.tcl: In a safe interp there is no osVersion field
	in tcl_platform so work around it.

2006-11-02  Daniel Steffen  <das@users.sourceforge.net>

	* generic/ttk/ttkBlink.c, generic/ttk/ttkButton.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.h:
	* generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c:
	* generic/ttk/ttkProgress.c, generic/ttk/ttkScale.c:
	* generic/ttk/ttkScroll.c, generic/ttk/ttkScrollbar.c:
	* generic/ttk/ttkSeparator.c, generic/ttk/ttkSquare.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTheme.c, generic/ttk/ttkTheme.h:
	* generic/ttk/ttkThemeInt.h, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h, macosx/ttkMacOSXTheme.c:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c: ensure
	all global Ttk symbols have Ttk or ttk prefix; declare all externally
	visible Ttk symbols not contained in stubs table as MODULE_SCOPE (or as
	static when possible); so that 'make check{exports,stubs}' once again
	complete without errors.

	* macosx/tkMacOSXColor.c (TkMacOSXCompareColors): ifdef out when unused

	* macosx/Wish.xcodeproj/project.pbxproj: check autoconf/autoheader exit
	status and stop build if they fail.

	* macosx/tkMacOSXWindowEvent.c (GenerateUpdateEvent): fix handling of
	Carbon Update events: the QuickDraw window update region was being
	ignored and all child TkWindows were sent an Expose XEvent even when
	they did not need to be redrawn. [Patch 1589226]

2006-11-01  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDebug.c: add TkMacOSX prefix to leftover
	* macosx/tkMacOSXDebug.h: macosx-private global symbols without Tk
	* macosx/tkMacOSXEmbed.c: prefix; ifdef out currently unused debug
	* macosx/tkMacOSXEvent.c: procs.
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:

2006-10-31  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/makefile.vc: Added ttk files to msvc build and add manifest
	* win/rules.vc: files to binaries with MSVC8.

2006-10-31  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcodeproj/project.pbxproj: add new Ttk files.

	* macosx/ttkMacOSXTheme.c: standardize header #includes.

	* unix/Makefile (checkstubs, checkexports): check ttk.decls, allow
	export of Ttk prefixed symbols.

	* generic/ttk/tkDefaultTheme.c: fix warnings.

2006-10-30  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/ttk_Geometry.3, doc/ttk_Theme.3, doc/ttk_button.n:
	* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
	* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n:
	* doc/ttk_intro.n, doc/ttk_label.n, doc/ttk_labelframe.n:
	* doc/ttk_menubutton.n, doc/ttk_notebook.n, doc/ttk_panedwindow.n:
	* doc/ttk_progressbar.n, doc/ttk_radiobutton.n, doc/ttk_scrollbar.n:
	* doc/ttk_separator.n, doc/ttk_sizegrip.n, doc/ttk_style.n:
	* doc/ttk_treeview.n, doc/ttk_widget.n,:
	* generic/ttk/ttk.decls, generic/ttk/ttkBlink.c:
	* generic/ttk/ttkButton.c, generic/ttk/ttkCache.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.c:
	* generic/ttk/ttkManager.h, generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c:
	* generic/ttk/ttkScale.c, generic/ttk/ttkScroll.c:
	* generic/ttk/ttkScrollbar.c, generic/ttk/ttkSeparator.c:
	* generic/ttk/ttkSquare.c, generic/ttk/ttkState.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c:
	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h:
	* generic/ttk/ttkTrace.c, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h:
	* library/demos/ttk_demo.tcl, library/demos/ttk_iconlib.tcl:
	* library/demos/ttk_repeater.tcl:
	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl:
	* library/ttk/button.tcl, library/ttk/clamTheme.tcl:
	* library/ttk/classicTheme.tcl, library/ttk/combobox.tcl:
	* library/ttk/cursors.tcl, library/ttk/defaults.tcl:
	* library/ttk/dialog.tcl, library/ttk/entry.tcl:
	* library/ttk/fonts.tcl, library/ttk/icons.tcl:
	* library/ttk/keynav.tcl, library/ttk/menubutton.tcl:
	* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl:
	* library/ttk/progress.tcl, library/ttk/scale.tcl:
	* library/ttk/scrollbar.tcl, library/ttk/sizegrip.tcl:
	* library/ttk/treeview.tcl, library/ttk/ttk.tcl:
	* library/ttk/utils.tcl, library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* macosx/ttkMacOSXTheme.c:
	* tests/ttk/all.tcl, tests/ttk/bwidget.test, tests/ttk/combobox.test:
	* tests/ttk/entry.test, tests/ttk/image.test:
	* tests/ttk/labelframe.test, tests/ttk/layout.test:
	* tests/ttk/misc.test, tests/ttk/notebook.test:
	* tests/ttk/panedwindow.test, tests/ttk/progressbar.test:
	* tests/ttk/scrollbar.test, tests/ttk/treetags.test:
	* tests/ttk/treeview.test, tests/ttk/ttk.test, tests/ttk/validate.test:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c:
	First import of Ttk themed Tk widgets as branched from tile 0.7.8

	* generic/tkInt.h, generic/tkWindow.c: add Ttk_Init call, copy tk
	classic widgets to ::tk namespace.
	* library/tk.tcl: add source of ttk/ttk.tcl, define $::ttk::library.
	* unix/Makefile.in, win/Makefile.in: add Ttk build bits
	* win/configure, win/configure.in: check for uxtheme.h (XP theme).

2006-10-23  Don Porter  <dgp@users.sourceforge.net>

	* README:		Bump version number to 8.5a6
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf-2.59
	* win/configure:

2006-10-19  Pat Thoyts  <patthoyts@users.sourceforge.net>

	*** 8.5a5 TAGGED FOR RELEASE ***

	* generic/tkImgBmap.c: Fixed line endings.
	* win/makefile.vc:  Patched up build system to manage
	* win/rules.vc:  AMD64 with MSVC8
	* win/nmakehlp.c:   Ensure operation without Platform SDK.

2006-10-18  Don Porter  <dgp@users.sourceforge.net>

	* changes:		8.5a5 release date set.

2006-10-17  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/text.n: fix docs to not correct -tabs usage case.

	* generic/tkTextDisp.c (SizeOfTab): fix -tabstyle wordprocessor tab
	alignment to correct tab edge case. [Bug 1578858]

2006-10-17  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkText.c: Applied suggested patch from [Bug 1536735]
	* tests/text.test:  Update test for above patch.
	* tests/textWind.test:  Corrected test to catch all messages
	* tests/safe.test: Silence spurious win32 failure awaiting TIP150
	* tests/winDialog.test: Updated test for file name length check.
	* test/winWm.test: Corrected test expectation for menu wrapping.

2006-10-16  Andreas Kupries  <andreask@activestate.com>

	* doc/WindowId.3: Pat's commit on 2006-10-08 broke the .SH NAME
	information across several lines, breaking the cross-linking of
	manpages during installation for this one. Put everything back on a
	single line, unbreaking it.

2006-10-16  Daniel Steffen  <das@users.sourceforge.net>

	* changes: updates for 8.5a5 release.

	* macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing
	procs so that they now match X11 drawing much more closely [Bug
	1558051]; use Tiger ellipse drawing API when available; fix comments &
	whitespace.

	* macosx/tkMacOSXInit.c: set default linewidth limit for CG
	antialiasing to 0 as thin horizontal/vertical lines look good now.
	* macosx/README: document CG antialiasing limit changes.

	* generic/tkCanvLine.c (ConfigureLine):  on TkAqua, pass outline
	* generic/tkCanvPoly.c (ConfigurePolygon):  linewidth in gc even for
	* generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA).

	* macosx/GNUmakefile: don't redo prebinding of non-prebound binaires.

	* library/demos/pendulum.tcl: fix incorrect setting of toplevel title.

2006-10-10  Don Porter  <dgp@users.sourceforge.net>

	* changes:	Updates for 8.5a5 release

2006-10-08  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkWindow.c:  Implemented TIP #264 - Tk_Interp function.
	* doc/WindowId.3:   Documented Tk_Interp.
	* generic/tk.decls: Added to the stubs interface and
	* generic/tkDecls.h:   regenerated.
	* generic/tkStubsInit.c:

2006-10-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/tkUnixFont.c (Ucs2beToUtfProc, UtfToUcs2beProc):
	(TkpFontPkgInit, encodingAliases): Correct alignment issues in
	encoding conversion. Call ucs-2be "unicode" on big-endian systems.
	[Bug 1122671]

2006-09-27  Andreas Kupries  <andreask@activestate.com>

	* unix/Makefile.in (install-binaries): Added a second guard to the
	* win/Makefile.in: package index file to prevent older versions of Tcl
	* win/makefile.vc: from seeing version numbers which may contain a/b
	information, and then balking on them. This could otherwise happen
	when Tcl/Tk 8.4 and 8.5 are installed in the same directory, seeing
	each other. [Bug 1566418]

2006-09-22  Andreas Kupries  <andreask@activestate.com>

	* generic/tkConsole.c: TIP #268 update regarding registered package
	* generic/tkMain.c: version, now using full patchlevel instead of
	* generic/tkWindow.c:  major.minor
	* library/tk.tcl:
	* unix/configure:
	* unix/Makefile.in:
	* unix/tcl.m4:
	* win/configure:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/rules.vc:
	* win/tcl.m4:

2006-09-20  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinMenu.c (TkpPostMenu): disable menu animation in menus with
	images to avoid clipping bug. [Bug 1329198]

2006-09-21  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkImgBmap.c (ImgBmapPostscript): Change 0 to NULL, since
	they are not interchangable on all platforms in all circumstances.
	[Tcl Bug 1562528]

2006-09-11  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (TkMacOSXMakeRealWindowExist): revert part of
	2006-05-16 change that had set overrideredirect windows to not become
	activated by the window manager, as this prevented interaction with
	native widgets in such windows [Bug 1472624]; apply changes to carbon
	window attributes even if native window has already been created.

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): fix app
	* macosx/tkMacOSXMenu.c (DrawMenuBarWhenIdle): menu item key shortcuts
	* macosx/tkMacOSXInt.h: when custom ".apple" menu is installed.

	* library/demos/widget: on TkAqua, don't install file menu with single
	quit menu item, as the application menu already has a quit item.

	* macosx/tkMacOSXColor.c: fix building on Mac OS X 10.2.

2006-09-10  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXColor.c (TkSetMacColor,TkpGetColor): use AppearanceMgr
	* macosx/tkMacOSXDefault.h: to retrieve platform std colors for text
	* macosx/tkMacOSXPort.h:    selections, add "systemHighlightSecondary"
	color name for standard color of inactive selections, use this color as
	default for text widget -inactiveselectbackground to implement platform
	standard look for inactive text selections.

	* library/text.tcl (aqua): remove focus bindings to set selection color

	* generic/tkTextBTree.c (TkTextIsElided): on TkAqua, don't show
	* generic/tkTextDisp.c (GetStyle):   inactive text selection when
						  text widget is disabled.

	* generic/tkEntry.c (DisplayEntry): change default TkAqua selection
	* macosx/tkMacOSXDefault.h:     relief to "flat" (platform std).

	* generic/tkText.c (CreateWidget): fix bug leading to default text
	selection relief string DEF_TEXT_SELECT_RELIEF being ignored.

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): allow mouse
	event delivery to background windows with kWindowNoActivatesAttribute
	(e.g. overrideredirect windows), as these never come to the foreground
	they would never receive any mouse events otherwise. [Bug 1472624]

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): do not
	send focus events to any windows with kWindowNoActivatesAttribute.

	* macosx/tkMacOSXXStubs.c (XQueryColor, XQueryColors): implement basic
	XColor computation from pixel values, enough to make tkImg's window.c
	happy, fixes img::window failures reported on tcl-mac.

	* macosx/tkMacOSXMenu.c (DrawMenuEntryLabel): fix leak. [Bug 1554672]

	* macosx/GNUmakefile: workaround bug in 'cp -pRH' on Darwin 6 and
	earlier, fixes 'make embedded' failure reported on tcl-mac; fix error
	from 'make deploy' with same build tree as previous 'make embedded'.

	* macosx/Wish.xcodeproj/project.pbxproj: add new tclUnixCompat.c file.

	* macosx/tkMacOSXEntry.c (TkpDrawEntryBorderAndFocus): fix typo.

	* unix/tcl.m4: sync with tcl/unix/tcl.m4.
	* unix/configure: autoconf-2.59

2006-09-06  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkEntry.c:   move hard-coded ALWAYS_SHOW_SELECTION control
	* generic/tkInt.h:   of entry/text selection display based on focus
	* generic/tkText.c: to the Tcl level, controlled by
	* generic/tkWindow.c:  ::tk::AlwaysShowSelection (boolean, private).
	* library/tk.tcl:   [Bug 1553691]
	* macosx/tkMacOSXDefault.h:
	* unix/tkUnixDefault.h:
	* unix/tkUnixPort.h:
	* win/tkWinDefault.h:

2006-08-30  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinKey.c: Add WM_UNICHAR window message support (used by
	* win/tkWinX.c:   virtual keyboard apps). [Bug 1518677] (petasis)

2006-08-24  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): set native scrollbar
	control bounds only once all size adjustments have been computed.
	Fixes issue with grow icon obscuring scrollbar reported on tcl-mac.

2006-08-21  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXCarbonEvents.c (CarbonTimerProc): avoid starving main
	event loop: limit the number of tcl events processed per invocation.
	Fixes bug reported on tcl-mac by Kevan Hashemi.

2006-08-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* tests/text.test (text-25.15): Added test suggested by Sam
	<baudinm@yahoo.com> on comp.lang.tcl

	* generic/tk.h, generic/tkInt.h: Stylistic improvements. No API change.

2006-08-18  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
	universal builds including x86_64, for 64-bit CoreFoundation on Leopard
	and for use of -mmacosx-version-min instead of MACOSX_DEPLOYMENT_TARGET
	* unix/configure.in (Darwin): remove 64-bit arch flags from CFLAGS for
	combined 32-bit and 64-bit universal builds, as neither TkAqua nor
	TkX11 can be built for 64-bit at present.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/Wish.xcodeproj/project.pbxproj: switch native release targets
	to use DWARF with dSYM, Xcode 3.0 changes.
	* macosx/README: updates for x86_64 support in Tcl.

	* macosx/tkMacOSXInit.c (TkpInit): when available, use public
	TransformProcessType() API instead of CPSEnableForegroundOperation()
	SPI to notify the window server that we are a GUI application.

	* macosx/tkMacOSXWm.c (WmAttrGetTitlePath): use HIWindow API on >=Tiger

	* macosx/tkMacOSXMouseEvent.c (GenerateToolbarButtonEvent):
	* macosx/tkMacOSXMenus.c (GenerateEditEvent):
	* macosx/tkMacOSXMenu.c (MenuSelectEvent): bzero() the XVirtualEvent
	structure before use to ensure all fields are initialized. [Bug
	1542205]

2006-08-16  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXWm.c (WmAttributesCmd): correct OS X result for [wm
	attributes $top].

2006-07-25  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): handle key
	shortcut for kHICommandQuit in the same way as other application menu
	item key shortcuts. [Bug 1516950]

2006-07-24  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (TkWmMapWindow): fix incorrect values of wmInfo
	parentWidth/Height for toplevels by recalculating them once the window
	is mapped (i.e once the window&structure sizes are known). [Bug
	1358663]
	(ParseGeometry): sync with ParseGeometry in tkUnixWm.c/tkWinWm.c.

2006-07-21  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkBind.c (TkBindInit): for REDO_KEYSYM_LOOKUP, change
	keysym-to-string mapping hash to use first name in ks_names.h instead
	of last (if there are multiple possibilities), e.g. "F11" instead of
	"L1".

	* macosx/tkMacOSXKeyboard.c (TkpGetKeySym): correct keysyms for pure
	modifier key presses [Bugs 700311, 1525905]; correct keysym for Enter
	key; add keysyms for new NumLock and Fn modifiers (added 2005-08-09).

2006-07-20  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (WmAttributesCmd, WmIconbitmapCmd): add support
	* unix/tkUnixSend.c (Tk_GetUserInactiveTime):       for weakly
	importing symbols not available on OSX 10.2 or 10.3, enables binaires
	built on later OSX versions to run on earlier ones.
	* macosx/Wish.xcodeproj/project.pbxproj: enable weak-linking; turn on
	                 extra warnings.
	* macosx/README: document how to enable weak-linking; cleanup.
	* unix/configure.in: add check on Darwin-X11 for ld support of -weak-l
	* unix/tcl.m4:  flag and weak-link libXss if possible as it is not
	available before OSX 10.4; enforce requirement of OSX 10.2 for TkAqua;
	move Darwin specific checks & defines that are only relevant to the tcl
	build out of tcl.m4; restrict framework option to Darwin; clean up
	quoting and help messages.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/GNUmakefile: enable xft for TkX11 build.
	* macosx/tkMacOSXFont.c (TkMacOSXQuarzStartDraw, TkMacOSXQuarzEndDraw):
	verify validity of context returned from QDBeginCGContext() before use.
	* macosx/tkMacOSXKeyEvent.c: ifdef out diagnostic messages to stderr.

	* macosx/tkMacOSXEvent.h:   standardize MAC_OS_X_VERSION_MAX_ALLOWED
	* macosx/tkMacOSXMenu.c:    checks per QA1316, ensure define can be
	* macosx/tkMacOSXMenubutton.c: overridden on command line (from default
	* macosx/tkMacOSXMenus.c:   of current OS version).
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWm.c:

	* generic/tkImgGIF.c (ReadImage):
	* macosx/tkMacOSXCursor.c (TkMacOSXCursor):
	* macosx/tkMacOSXDebug.c (TkMacOSXGetNamedDebugSymbol):
	* macosx/tkMacOSXFont.c (TkpMeasureCharsInContext):
	* macosx/tkMacOSXInit.c (Map):
	* xlib/xgc.c (XCreateGC): fix signed-with-unsigned comparison and other
	warnings from gcc4 -Wextra.

2006-07-14  Andreas Kupries  <andreask@activestate.com>

	* generic/tkWindow.c (Initialize): Modify change of 2006-05-25 (jeffh).
	Release mutex a bit earlier, to prevent lock when OS X creates its
	console windows (recursively enters Tk_Init). Patch by JeffH.

2006-07-06  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/tkfbox.tcl: catch scrollbar use of highlightthickness

2006-06-21  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/bgerror.tcl (::tk::dialog::error::bgerror): remove a couple
	of unnecessary hardcoded options

2006-06-14  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkScale.c: Revised variable writing logic to account for
	[scale]'s design that it deals with its value as a formatted string,
	and not as a double. [Bug 891141]

2006-06-14  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXSubwindows.c (TkMacOSXInvalidateWindow): ensure
	invalid clip regions are recreated via TkMacOSXUpdateClipRgn() before
	they are used; correct call order of TkMacOSXInvalidateWindow() and
	TkMacOSXInvalClipRgns() throughout. [Bug 1501922]

	* macosx/tkMacOSXDraw.c (TkPutImage): implement drawing of very wide
	images in slices of less than 4096 pixels to workaround CopyBits
	limitation. [Bug 950121]

2006-06-09  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkMain.c:	Added Tcl_Preserve() call on the master interp
	as crash protection against any Tcl_DeleteInterp() call that might
	happen.

2006-06-01  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Added Tcl_RegisterChannel() calls to bump the
	refcount of channels passed to Tcl_SetStdChannel(). This prevents early
	free-ing of the channels that leads to crashes. [Bug 912571]

2006-05-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinEmbed.c (TkpGetOtherWindow):   Do not panic if no window is
	* unix/tkUnixEmbed.c (TkpGetOtherWindow): found; caller handles. [Bug
	* unix/tkUnixWm.c (Tk_CoordsToWindow, UpdateGeometryInfo): 1212056]

	* tests/entry.test (entry-22.1):
	* tests/listbox.test (listbox-6.15):
	* generic/tkListbox.c (ListboxInsertSubCmd, ListboxDeleteSubCmd):
	Ignore Tcl_SetVar2Ex failure of listVarName, similar to entry widget
	handling. [Bug 1424513]

2006-05-26  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXButton.c (TkMacOSXDrawControl): correct redraw for
	direct transition from disabled to active state. [Bug 706446]

2006-05-25  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinMenu.c (TkWinMenuKeyObjCmd): get eventPtr after we know the
	window is still alive. [AS bug 45987] [Bug 1236306]

	* generic/tkMenu.c (DeleteMenuCloneEntries): Modify entry index
	changes to work around VC6 optimization bug. [Bug 1224330]

	* generic/tkMessage.c (MessageWidgetObjCmd): Correct msgPtr
	preserve/release pairing. [Bug 1485750] (afredd)

	* generic/tkWindow.c (Initialize): Correct mutex (un)lock pairing.
	[Bug 1479587] (loewis)

	* generic/tkBind.c (Tk_BindEvent, TkCopyAndGlobalEval): use Tcl_EvalEx
	instead of Tcl_GlobalEval.

2006-05-16  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): don't send
	focus events to windows of class help or to overrideredirect windows.
	[Bug 1472624]

	* macosx/tkMacOSXWm.c: set overrideredirect windows to not become
	activated by the window manager and to not receive OS activate events
	(should make them behave more like on other platforms); use modern
	window class API for overrideredirect and transient windows; set the
	default class of overrideredirect windows to 'simple' rather than
	'plain' (i.e. no window frame); add missing Panther and Tiger window
	attributes to [::tk::unsupported::MacWindowStyle].

2006-05-12  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Fix
	opt added 2006-03 that caused slowdown for some common cases. [Bug
	1409140]

2006-05-13  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkCanvWind.c (DisplayWinItem, WinItemRequestProc): ensure
	canvas window items are unmapped when canvas is unmapped. [Bug 940117]

	* macosx/tkMacOSXSubwindows.c (TkMacOSXUpdateClipRgn): empty clip
	region of unmapped windows to prevent any drawing into them or into
	their children from becoming visible. [Bug 940117]

	* macosx/tkMacOSXInt.h:     revert Jim's attempt of 2005-03-14 to
	* macosx/tkMacOSXSubwindows.c:  fix Bug 940117 as it disables Map/Unmap
	event propagation to children. [Bug 1480105]

	* macosx/tkMacOSXDraw.c (TkPutImage): handle tkPictureIsOpen flag,
	fixes incorrect positioning of images with complex alpha on native
	buttons; actual alpha blending is still broken in this situation. [Bug
	1155596]

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessCommandEvent):
	* macosx/tkMacOSXMenus.c (TkMacOSXInitMenus): workaround carbon bug
	with key shortcut for 'Preferences' app menu item. [Bug 1481503]

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only check
	for HICommand menu item shortcuts in the application menu.

	* macosx/tkMacOSXInt.h:    initialize keyboard layout setup in
	* macosx/tkMacOSXInit.c:     TkpInit() rather than during handling of
	* macosx/tkMacOSXKeyEvent.c:  first key down event.

	* macosx/tkMacOSXDraw.c:     add optional debug code to flash clip
	* macosx/tkMacOSXSubwindows.c:  regions during update or draw.

2006-05-04  Don Porter  <dgp@users.sourceforge.net>

	* README:		Bump version number to 8.5a5
	* generic/tk.h:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

	* unix/configure:	autoconf-2.59
	* win/configure:

2006-04-28  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (TkWmMapWindow, InitialWindowBounds): fix use of
	potentially stale window position in initial configure event on first
	map of a window. [Bug 1476443]
	(TkMacOSXWindowOffset): use modern GetWindowStructureWidths API.

	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMouseEvent.c (TkGenerateButtonEventForXPointer): new
	internal function to generate button events for current pointer
	directly, without requiring prior call to XQueryPointer().

	* macosx/tkMacOSXMouseEvent.c (XQueryPointer): implement return of
	window-local pointer position.

	* macosx/tkMacOSXInt.h:   use improvements above to avoid calls to
	* macosx/tkMacOSXKeyEvent.c: GlobalToLocal() when the current port
	* macosx/tkMacOSXMenu.c:    might not be set correctly. May fix [Bug
	* macosx/tkMacOSXMenus.c:   1243318]
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:

	* tkAboutDlg.r: update copyright.

	* macosx/tkMacOSXDebug.h: sync #includes with core-8-4-branch.
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.h:

2006-04-26  Don Porter  <dgp@users.sourceforge.net>

	*** 8.5a4 TAGGED FOR RELEASE ***

	* changes:	Updates for next RC

2006-04-25  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* unix/tkUnixFont.c (TkpGetFontFamilies): Fix crash caused when the
	XServer returns invalid font names. [Bug 1475865]

2006-04-23  Vince Darley  <vincentdarley@users.sourceforge.net>

	* tests/scrollbar.test: fix to tkAqua test failures

2006-04-18  Vince Darley  <vincentdarley@users.sourceforge.net>

	* macosx/tkMacOSXEmbed.c: fix to [Bug 1088814] test failures in
	embed.test

	* macosx/tkMacOSXWm.c:
	* tests/constraints.tcl:
	* tests/wm.test: fix to 'wm attributes' test for TkAqua

2006-04-11  Peter Spjuth  <peter.spjuth@space.se>

	* generic/tkWindow.c (Tk_NameToWindow): Allow NULL interp to
	Tk_NameToWindow. This fixes TkGetWindowFromObj which promises to handle
	NULL but didn't.

	* generic/tkGrid.c: Fixed handling of out of bounds row or column.
	* tests/grid.test:  [Bug 1432666]

2006-04-11  Don Porter  <dgp@users.sourceforge.net>

	* unix/Makefile.in:	Updated `make dist` target to be sure the
	message catalogs for the widget demo get packaged into the source code
	distribution. [Bug 1466509]

2006-04-11  Daniel Steffen  <das@users.sourceforge.net>

	* changes: added latest aqua bug fixes.

	* macosx/tkMacOSXDialog.c (Tk_MessageBoxObjCmd): added standard Escape
	key binding for msgbox cancel buttons [Patch 1193614], whitespace.

	* macosx/tkMacOSXCarbonEvents.c: handle kEventCommandUpdateStatus
	* macosx/tkMacOSXEvent.c:     carbon event to dynamically enable
	the 'Preferences' app menu item when proc [::tk::mac::ShowPreferences]
	is defined. [Bug 700316]

	* macosx/tkMacOSXHLEvents.c:    call ::tk::mac::* procs for all
	* macosx/tkMacOSXWindowEvent.c: registered appleevents [FR 1105284],
	implement print applevent handling, style/whitespace cleanup.

	* macosx/tkMacOSXDraw.c (TkMacOSXInitCGDrawing): prevent multiple init

	* macosx/tkMacOSXFont.c: remove #ifdef'd text measuring codepaths now
	* macosx/tkMacOSXInit.c: known to be incorrect, cleanup obsolete text
	* macosx/README:	 antialiasing control code, document ATSUI
				 text antialiasing changes.

	* macosx/tkMacOSXInt.h:     Implemented 'zoomed' window state
	* macosx/tkMacOSXWindowEvent.c: handling for TkAqua, via titlebar
	* macosx/tkMacOSXWm.c:     widget clicks as well as [wm state].
	* doc/wm.n:         [Bug 1073456]

2006-04-10  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/tkfbox.tcl (::tk::IconList_Goto): Fix prefix searching so
	that the start location is reasonable, and the prefix matching is
	using the correct Tcl command for this. [Bug 1467938]

2006-04-10  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* macosx/tkMacOSXFont.c (MeasureStringWidth): Use implementation based
	on ATSUGetGlyphBounds (TK_MAC_USE_GETGLYPHBOUNDS), so we can use
	kATSUseFractionalOrigins. This in turn corrects [Bug 1461650].
	(InitFont): Use "." and "W" instead of "i" and "w" to determine the
	"-fixed" attribute. This prevents "Apple Chancery" from being
	classified as fixed.
	(InitFontFamilies): Only get the font families once.

2006-04-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (WmResizableCmd): propagate window attribute
	changes to Carbon window manager. [FR 1467004]
	(TkSetWMName, TkMacOSXMakeRealWindowExist): allow empty name for
	toplevels, remove bogus initial window name. [Bug 1450800]

2006-04-07  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): fix return
	values, implement window dragging & growing in background (with Command
	key down) and by fronting clicks [Bug 934524], use correct button &
	modifier state API when application is in background (also in
	TkMacOSXButtonKeyState).

	* macosx/tkMacOSXWm.c (TkMacOSXGrowToplevel): ensure QD port is set
	correctly before using API relying on it.

2006-04-06  Vince Darley  <vincentdarley@users.sourceforge.net>

	* macosx/tkMacOSXMouseEvent.c: Now that [wm attributes -titlepath]
	works correctly, add OS support for dragging proxy icons and using the
	titlepath menu.

2006-04-06  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (WmAttributesCmd, WmIconbitmapCmd): fix errors in
	setting/removing window proxy icons via [wm attributes -titlepath] and
	[wm iconbitmap], use HIWindow API on Tiger or later. [Bug 1455241]

	* unix/tcl.m4: remove TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
	define on Darwin. [Tcl Bug 1457515]
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

2006-04-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkWindow.c (Initialize): remove impotent use of
	DeleteWindowsExitProc as a global exit handler.

	* generic/tkMenu.c (TkSetWindowMenuBar): remove extra TkMenuInit call
	that caused finalization panic. [Bug 1456851]
	* win/tkWinMenu.c (FreeID, TkpNewMenu, MenuExitHandler)
	(MenuThreadExitHandler, TkpMenuInit, TkpMenuThreadInit): rework Windows
	menu init/finalization to better respect per-process and per-thread
	boundaries. [Bug 1456851]
	(TkWinMenuKeyObjCmd): Do not error when unknown window is passed in.
	[Bug 1236306]

	* win/tkWinX.c (TkWinXInit): init default keyboard charset correctly.
	[Bug 1374119] (pajas)

	* win/tkWinWm.c (WmProc): pass WM_QUERYENDSESSION message to Tk as
	WM_SAVE_YOURSELF wm protocol callback.

	* tests/textWind.test (textWind-10.6.1): prevent infinite update loop
	in case of test failure.

	* tests/wm.test (wm-attributes-1.2.4): correct expected result.

	* tests/grid.test: fix segfault on empty or "all" index list
	* generic/tkGrid.c (GridRowColumnConfigureCommand): [Bug 1422430]

2006-04-05  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c: fix to crash caused on some platforms by new tests
	introduced to check for [Bug 1414171], which destroy the text widget in
	the dump callback script.

2006-03-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkOption.c (TkOptionDeadWindow): handle OptionThreadExitProc
	being called before DeleteWindowsExitProc.

	* win/Makefile.in: convert _NATIVE paths to use / to avoid ".\"
	path-as-escape issue.

2006-03-29  Don Porter  <dgp@users.sourceforge.net>

	* changes:	Updates for next RC

	* unix/tkUnixDefault.h: Changed "Black" to "#000000" and "White" to
	"#ffffff" to work around the (broken?) X servers that do not accept
	those color names. [Bug 917433]

2006-03-28  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/tcl.m4, win/tcl.m4: []-quote AC_DEFUN functions.

2006-03-26  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c:
	* tests/text.test: Fix for elaborations of [Bug 1414171] for '$text
	dump -command <script>' where script deletes large portions of the
	text widget, or even destroys the widget.

2006-03-28  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcode/default.pbxuser:    add '-singleproc 1' cli arg to
	* macosx/Wish.xcodeproj/default.pbxuser: tktest to ease test debugging.

	* macosx/Wish.xcode/project.pbxproj:    removed $prefix/share from
	* macosx/Wish.xcodeproj/project.pbxproj: TCL_PACKAGE_PATH as per change
	to tcl/unix/configure.in of 2006-03-13.

	* macosx/tkMacOSXDraw.c:   sync whitespace & minor changes with
	* macosx/tkMacOSXEvent.h:  core-8-4-branch.
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXNotify.c:

2006-03-27  Don Porter  <dgp@users.sourceforge.net>

	* changes:	Updates for next RC

2006-03-27  Benjamin Riefenstahl  <b.riefenstahl@turtle-trading.net>

	* generic/tkTextDisp.c (MeasureChars): Fix calculations of start and
	end of string. [Bugs 1325998, 1456157]

2006-03-27  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkImgGIF.c (FileReadGIF): Stop crashes when the first GIF
	frame does not define the overall size of the image. [Bug 1458234]

2006-03-26  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextBTree.c:
	* tests/text.test: Fix for [Bug 1414171] for '$text dump -command
	<script>' where 'script' actually modifies the widget during the
	process.

2006-03-25  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDraw.c (TkMacOSXSetUpCGContext):
	* macosx/tkMacOSXFont.c (TkMacOSXQuarzStartDraw, TkMacOSXQuarzEndDraw):
	performance improvements, sync similar code, formatting & whitespace.

2006-03-24  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkTextDisp.c:   Moved #ifdef MAC_OSX_TK code added by
	* macosx/tkMacOSXColor.c: [Patch 638966] into platform specific files.
	* macosx/tkMacOSXInt.h:

	* macosx/tkMacOSX.h:       Cleaned up & rationalized order of
	* macosx/tkMacOSXBitmap.c:  #includes of tk and carbon headers.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXWm.h:
	* macosx/tkMacOSXXStubs.c:

2006-03-23  Reinhard Max  <max@tclers.tk>

	* unix/tkUnixRFont.c (TkpMeasureCharsInContext): Copied over from
	tkUnixFont.c to fix compiling with --enable-xft .

	* unix/tk.spec: Cleaned up and completed. An RPM can now be built from
	the tk source distribution with "rpmbuild -tb <tarball>".

2006-03-23  Don Porter  <dgp@users.sourceforge.net>

	* tests/textDisp.test: Updated expected error messages to match the
	standardized formats established on 2005-11-17. [Bug 1370296]

2006-03-22  Don Porter  <dgp@users.sourceforge.net>

	* changes:	Updates for next RC

2006-03-21  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkFont.c:       implementation of ATSUI text rendering
	* generic/tkInt.h:      in TkAqua provided by Benjamin
	* generic/tkTextDisp.c:     Riefenstahl. [Patch 638966]
	* library/demos/unicodeout.tcl:
	* macosx/tkMacOSXFont.h (new file):
	* macosx/tkMacOSXFont.c:
	* tests/font.test:
	* unix/tkUnixFont.c:
	* win/tkWinFont.c:

	* generic/tkFont.c:       moved MODULE_SCOPE declarations of font
	* generic/tkFont.h:       helper procs into header files.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXMenubutton.c:

	* macosx/Wish.xcode/project.pbxproj:    add new tkMacOSXFont.h file,
	* macosx/Wish.xcodeproj/project.pbxproj: turn off dead code stripping
	as it interferes with -sectcreate (rdar://4486223).

	* macosx/Wish.xcode/default.pbxuser:    add TCLLIBPATH=/Library/Tcl
	* macosx/Wish.xcodeproj/default.pbxuser: env var setting to tktest.

	* unix/configure.in: fix detection of symbols build when enabling
	TkAqua debug code; filter nm output of libtclstub better to avoid
	error on intel macs. [Bug 1415789]
	* unix/configure: autoconf-2.59

2006-03-20  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Added exit handler to clean up the interp where
	the console window lives. Also added code to handle multiple calls to
	Tk_CreateConsoleWindow so that the console channels connect to the last
	console window opened, in compatibility with the previous
	implementation.

2006-03-18  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c: Fix for undo/modified status of text widgets when
	empty strings are inserted and undone.

2006-03-17  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* library/clrpick.tcl:   Avoid using abbreviated sub-commands in core
	* library/palette.tcl:   scripts as this can cause problems with
	* library/scale.tcl:    mega-widget libraries like snit.
	* library/scrlbar.tcl:	 [Bug 1451587]
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:

2006-03-16  Don Porter  <dgp@users.sourceforge.net>

	* generic/tkConsole.c:	Substantial rewrite of [console] support.
	* generic/tkInt.h:	Included Obj-ification of the [console] and
	[consoleinterp] commands, and reworking of all the supporting data
	structures for cleaner sharing and lifetime management especially in
	multi-threaded configurations.

2006-03-16  Donal K. Fellows  <dkf@users.sf.net>

	* library/msgs/pt.msg: Messages for Portuguese (strictly just for
	Brazilian Portuguese, but they'll do until we get other Portuguese
	speakers localize) from Ricardo Jorge <ricardoj@users.sf.net> and Silas
	Justiano <silasj@users.sf.net>. Many thanks! [Bug 1405069]

	* generic/tkImgPhoto.c (ImgPhotoCmd, Tk_PhotoPutBlock)
	(Tk_PhotoPutZoomedBlock): Added hack to detect copying of a photo with
	a simple alpha channel and skip calling ToggleComplexAlphaIfNeeded.
	This should speed up many photo-to-photo copies, keeping the cost of
	the alpha channel down.

2006-03-15  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Try
	to squelch performance issue with code that writes to large images by
	single pixels. Masses of thanks to George Staplin for helping to trace
	this down to the COMPLEX_ALPHA flag handling code. [Bug 1409140]

2006-03-13  Don Porter  <dgp@users.sourceforge.net>

	* tests/scrollbar.test: Corrected several broken calls to [testmetrics]
	that were crashing the test suite.

	* tests/constraints.tcl:     Added notAqua constraint to canvPs-3.1
	* tests/canvPs.test:      to stop test suite crash on Mac OSX.
					[Bug 1088807]

	* generic/tkCmds.c:		Purged remaining references to errno,
	* macosx/tkMacOSXPort.h:	and errno.h. Standardized the logic
	* macosx/tkMacOSXWm.c:		for using header files from the compat
	* macosx/tkMacOSXWm.h:		directory. Thanks Joe English for the
	* unix/tkUnixPort.h:		patch. [Patch 1445404]

2006-03-08  Don Porter	<dgp@users.sourceforge.net>

	* unix/Makefile.in: Update `make dist` to copy the image files needed
	by the test suite into the source distro. This was overlooked in the
	2005-10-12 commit.

	* changes:	Update in prep. for 8.5a4 release.

2006-03-07  Joe English  <jenglish@users.sourceforge.net>

	* unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the other
	*BSD variants. [Bug 1334613]
	* unix/configure: Regenerated.

2006-03-07  Donal K. Fellows  <dkf@users.sf.net>

	* doc/canvas.n: Added note that stipples are not well-supported on
	non-X11 platforms. [Bug 220787] It's not a great solution, but it does
	indicate the state of affairs that has existed for years anyway; not
	much modern software uses stipples anyway.

2006-03-02  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXDraw.c (TkPutImage): Fix endian issue on OS X x86
	displaying images. Bitmap images still have a black/white reversal
	issue, appears to be a general OS X issue (as seen in frogger demo).

2006-02-27  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkBitmap.c (Tk_GetBitmapFromData): Improve thread-safety.
	[Bug 470322]

	* generic/tkImgBmap.c (ImgBmapConfigureInstance): Force creation of new
	Pixmaps before deletion of old ones to prevent stupid caching problems.
	[Bug 480862]

2006-02-09  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tk.decls:       fix signature of TkMacOSXInvalClipRgns
	* generic/tkPlatDecls.h:     to use Tk_Window instead of internal
	* macosx/tkMacOSXSubwindows.c:  type TkWindow (which led to any include
	* macosx/tkMacOSXWindowEvent.c: of public header tkMacOSX.h requiring
	* macosx/tkMacOSXWm.c:     prior include of tkInt.h).

	* generic/tk.h:      move TkAqua specific REDO_KEYSYM_LOOKUP define
	* macosx/tkMacOSXPort.h: out of tk.h into platform header.

2006-01-31  Donal K. Fellows  <dkf@users.sf.net>

	* library/bgerror.tcl (::tk::dialog::error::bgerror): Finish the
	internationalization of the error dialog. [Bug 1409264]

2006-01-25  Don Porter	<dgp@users.sourceforge.net>

	* library/bgerror.tcl: Updates to use Tcl 8.4 features. [Patch 1237759]
	* library/choosedir.tcl:
	* library/comdlg.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/focus.tcl:
	* library/msgbox.tcl:
	* library/palette.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:

2006-01-23  Daniel Steffen  <das@users.sourceforge.net>

	* unix/configure:   minor fix to Darwin specific code removing
	* unix/configure.in: 64bit flags from CFLAGS for Tk build.

2006-01-20  Joe English  <jenglish@users.sourceforge.net>

	* generic/tkEvent.c, unix/tkUnixEvent.c: XIM fixes [See 905830, patch
	tk84-xim-fixes.patch], and revert 2005-12-05 patch disabling XIM when
	SCIM in use, and make sure all X events get passed to XFilterEvent,
	including those without a corresponding Tk window.

2006-01-13  Anton Kovalenko  <a_kovalenko@users.sourceforge.net>

	* generic/tkUndo.c (TkUndoSetDepth): Don't free TkUndoSubAtoms for
	separator entries that are deleted: there is some unpredictable garbage
	instead of subatoms.

	Free both 'apply' and 'revert' action chains for non-separator entries.

2006-01-12  Donal K. Fellows  <dkf@users.sf.net>

	TIP #260 IMPLEMENTATION

	* generic/tkCanvText.c (TextItem, CreateText, DisplayCanvText):
	* doc/canvas.n:		Code, docs and tests to implement an -underline
	* tests/canvText.test:	option for canvases' text items.

2006-01-11  Peter Spjuth  <peter.spjuth@space.se>

	* generic/tkGrid.c: Removed a lingering error message from TIP#147
	implementation.

2006-01-10  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDebug.c: add TkMacOSXGetNamedDebugSymbol() function
	* macosx/tkMacOSXDebug.h: that finds unexported symbols in loaded
	libraries by manually walking their symbol table; only to be used for
	debugging purposes, may break unexpectedly in the future. Needed to get
	access to private_extern internal debugging functions in HIToolbox.

	* macosx/tkMacOSXCarbonEvents.c: fix debug event tracing on Tiger.
	* macosx/tkMacOSXMenu.c: add debug menu printing during reconfigure.
	* macosx/tkMacOSXInit.c: conditionalize 64bit-unsafe dyld code.
	* macosx/GNUmakefile: add 'wish8.x' symlink to SYMROOT.

	* macosx/Wish.xcode/project.pbxproj:    fix copy to tktest resource
	* macosx/Wish.xcodeproj/project.pbxproj: fork when zerolinked.

	* macosx/Wish.xcode/default.pbxuser:    add widget demo as argument to
	* macosx/Wish.xcodeproj/default.pbxuser: executables (on by default).

	* unix/configure:   add caching, use AC_CACHE_CHECK instead of
	* unix/configure.in: AC_CACHE_VAL where possible, consistent message
	* unix/tcl.m4:  quoting, sync relevant tclconfig/tcl.m4 changes
	and gratuitous formatting differences, fix SC_CONFIG_MANPAGES with
	default argument, Darwin improvements to SC_LOAD_*CONFIG.

2005-12-28  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkUndo.c (TkUndoSetDepth): Apply [Patch 1391939] from Ludwig
	Callewaert to fix [Bug 1380427].

2005-12-14  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/project.pbxproj: add new tclTomMath* files.

2005-12-13  Daniel Steffen  <das@users.sourceforge.net>

	* library/demos/cscroll.tcl: add MouseWheel bindings for aqua.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent)
	(GenerateMouseWheelEvent): add support for kEventMouseScroll events
	(smooth mouse wheel scrolling from mighty mouse or scrolling trackpad)
	by handling kEventMouseWheelMoved on application target as well as on
	dispatcher, in order to pick up synthesized MouseWheel events from
	HIObject handler (c.f. QA1453); add support for horizontal scrolling
	events by generating MouseWheel XEvent with Shift modifier.

2005-12-12  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/tcl.m4, unix/configure: Fix sh quoting error reported in
	bash-3.1+ [Bug 1377619] (schafer)

2005-12-09  Mo DeJong  <mdejong@users.sourceforge.net>

	* win/tkWinWm.c (WinSetIcon): Don't check result of SetClassLong() or
	SetClassLongPtr() since it was generating an incorrect error and the
	MSDN docs indicate that the result need not be checked.

2005-12-09  Mo DeJong  <mdejong@users.sourceforge.net>

	* win/configure: Regen.
	* win/tcl.m4 (SC_CONFIG_CFLAGS): Define MACHINE for gcc builds. The
	lack of a definition of this variable in the manifest file was causing
	a runtime error in wish built with gcc.

2005-12-09  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkInt.decls:  Move all platform test sources from tk lib into
	* generic/tkTest.c:  tktest directly, removes requirement to export
	* macosx/tkMacOSXTest.c:TkplatformtestInit from internal stubs table.
	* unix/Makefile.in:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/tkWinTest.c:

	* generic/tkIntPlatDecls.h:
	* generic/tkStubInit.c: regen.

2005-12-08  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tcl.m4:    Add build support for Windows-x64 builds.
	* win/configure:    --enable-64bit now accepts =amd64|ia64 for
	* win/Makefile.in:  Windows 64-bit build variants (default: amd64)
	* win/makefile.vc:  [Bug 1369597]
	(TKOBJS): add tkWinTest.obj to regular Tk obj for TkplatformtestInit

	* win/configure.in: Add CE build support (some C code fixes needed)
	* win/wish.exe.manifest.in (new):    manifest must map in MACHINE and
	* win/rc/wish.exe.manifest (removed): VERSION to be correct.
	* unix/Makefile.in: fix dist target for manifest dir change

	* generic/tkTextTag.c (TkTextTagCmd): use correct arraySize for peered
	text widgets in [$text tag names]. [Bugs 1375069, 1374935]

2005-12-08  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDraw.c:  Remove inclusion of tclInt.h and use of tcl
	* macosx/tkMacOSXFont.c:  internals wherever possible in tk/macosx, the
	* macosx/tkMacOSXInit.c:  only remaining tcl internals in TkAqua are
	* macosx/tkMacOSXNotify.c:TclServiceIdle() in tkMacOSXScrlbr.c and
	* macosx/tkMacOSXScrlbr.c:Tcl_Get/SetStartupScript() in tkMacOSXInit.c
				  [RFE 1336531]

	* macosx/tkMacOSXInt.h: sync comments with core-8-4-branch.

2005-12-07  Jeff Hobbs  <jeffh@ActiveState.com>

	* unix/tkUnixEvent.c (OpenIM): remove extraneous const

2005-12-06  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* doc/ConfigWidg.3 (TK_CONFIG_OPTION_SPECIFIED): Mentioned that the
	flag is deprecated because it is not thread-safe.

2005-12-05  Reinhard Max  <max@suse.de>

	* unix/tkUnixEvent.c (OpenIM): Added a workaround to allow at least
	ASCII and the Compose key when typing into text and entry widgets on a
	system that uses SCIM. This has to be taken out again once the SCIM
	problems have been fixed.

2005-12-01  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
	* unix/configure: regen.

2005-11-30  Jeff Hobbs  <jeffh@ActiveState.com>

	* win/tkWinWm.c (WmAttributesCmd): set (no)topmost window aspect before
	rewrapping. [Bug 1086049]

	* macosx/tkMacOSXXStubs.c (TkpOpenDisplay, TkMacOSXDisplayChanged):
	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXEvent.h: Trap kEventAppAvailableWindowBoundsChanged
	* macosx/tkMacOSXInt.h:   event to watch for change in display size and
	adjust internal state appropriately.

	* doc/checkbutton.n: fix -selectcolor docs. [Bug 1083838]

	* generic/tkImgGIF.c: cast calls to blockOut

	* win/Makefile.in: place TCL_BIN_DIR first in PATH for targets to get
	Tcl built dll first.
	Add tkWinTest.obj to tk84.dll to handle some needed test functions
	being defined in stubs (TkplatformtestInit).

	* tests/scrollbar.test (6.22): fix rounding-error sensitive test

2005-11-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/console.tcl (::tk::ConsoleInit): improve work-around to avoid
	'% ' from tclMain.c. [Bug 1252259]

2005-11-27  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
	add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
	configure (flag can't be present twice, so can't be in both CFLAGS and
	LDFLAGS during configure), don't use -prebind when deploying on 10.4,
	define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
	(SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
	autoconf macros. Sync with tcl/unix/tcl.m4.

	* unix/configure.in: fix obsolete autoconf macros, sync gratuitous
	formatting/ordering differences with tcl/unix/configure.in.

	* unix/Makefile.in: add CFLAGS to wish/tktest link to make executable
	linking the same as during configure (needed to avoid loosing any
	linker relevant flags in CFLAGS, in particular flags that can't be in
	LDFLAGS). Avoid concurrent linking of wish and compiling of
	tkTestInit.o during parallel make, fix dependencies and flags for
	building tkMacOSXInit.o
	(checkstubs, checkexports): dependency and Darwin fixes
	(dist): add new macosx files.

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessEvent):
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent):
	* macosx/tkMacOSXCarbonEvents.c: install standard application event
	handler, add & call functions to start and stop carbon even timer that
	runs the tcl event loop periodically during a nested carbon event loop
	in the toolbox (e.g. during menutracking) to ensure tcl timers etc.
	continue to fire, register app event handler for menu tracking and HI
	command carbon events, move menu event handling to new handlers for
	those carbon events, no longer register for/handle appleevent carbon
	event (now dealt with by standard application event handler), event
	debugging code dynamically acquires carbon event debugging functions to
	allow use on Tiger where they are no longer exported from HIToolbox.

	* macosx/tkMacOSXFont.c (TkMacOSXUseAntialiasedText):
	* macosx/tkMacOSXKeyEvent.c (GetKeyboardLayout):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: abstract common code to dynamically acquire
	address of a named symbol (from a loaded dynamic library) into new
	function TkMacOSXGetNamedSymbol() and macro TkMacOSXInitNamedSymbol.

	* macosx/tkMacOSXMenu.c (TkpNewMenu):
	* macosx/tkMacOSXMenubutton.c (MenuButtonInitControl):
	* macosx/tkMacOSXMenus.c (TkMacOSXHandleMenuSelect): switch to modern
	utf-8 aware menu manager API, remove obsolete code, add error handling.

	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c: define OSX 10.3 or later only constants
	if necessary to allow compilation on OSX 10.2

	* macosx/tkMacOSXWm.c (UpdateSizeHints): remove code that is never
	executed.

	* xlib/xgc.c (XCreateGC): sync with core-8-4-branch change.

	* generic/tk.h: add/correct location of version numbers in macosx files

	* generic/tkInt.h: clarify fat compile comment.

	* macosx/Wish.pbproj/default.pbxuser (new):
	* macosx/Wish.pbproj/jingham.pbxuser:
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/default.pbxuser (new):
	* macosx/Wish.xcodeproj/project.pbxproj (new): new/updated projects for
	Xcode 2.2 on 10.4, Xcode 1.5 on 10.3 & ProjectBuilder on 10.2, with
	native tktest targets and support for universal (fat) compiles.

	* macosx/Tk-Info.plist (removed):
	* macosx/Wish-Info.plist (removed):
	* macosx/buildTkConfig.tcl (removed): remove obsolete build files.

	* macosx/README: clarification/cleanup, document new Xcode projects and
	universal (fat) builds via CFLAGS (i.e. ppc and i386 at the same time).

	* unix/Makefile.in:
	* unix/aclocal.m4:
	* unix/configure.in:
	* macosx/configure.ac (new): add support for inclusion of
	unix/configure.in by macosx/configure.ac, allows generation of a
	config headers enabled configure script in macosx (required by Xcode
	projects).

	* macosx/GNUmakefile: rename from Makefile to avoid overwriting by
	configure run in tk/macosx, add support for reusing configure cache,
	build target fixes.

	* generic/tk3d.h:
	* generic/tkButton.h:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h:
	* generic/tkColor.h:
	* generic/tkEntry.h:
	* generic/tkFileFilter.h:
	* generic/tkFont.c:
	* generic/tkFont.h:
	* generic/tkImage.c:
	* generic/tkImgPhoto.c:
	* generic/tkInt.h:
	* generic/tkMenu.c:
	* generic/tkMenu.h:
	* generic/tkMenubutton.h:
	* generic/tkScale.h:
	* generic/tkScrollbar.h:
	* generic/tkSelect.h:
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* generic/tkText.h:
	* generic/tkUndo.h:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixMenu.c:
	* xlib/xgc.c: ensure externally visible symbols not contained in stubs
	table are declared as MODULE_SCOPE (or as static if not used outside of
	own source file), #ifdef out a few Xlib and aqua functions that are
	never called. These changes allow 'make checkstubs' to complete without
	error on Darwin with gcc 4.

	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXPort.h:
	* win/tkWinTest.c:
	* generic/tkInt.decls: add functions needed by tktest to internal stubs
	table, correct signature of TkMacOSXHandleMenuSelect, add XSync to aqua
	Xlib stubs.

	* unix/tkUnixSend.c:
	* generic/tkText.c:
	* generic/tkTest.c: #ifdef unix only declarations.
	(TestmetricsCmd): unify win and mac implementation.
	(TestsendCmd): move to tkUnixSend.c to avoid access to global var.
	(TesttextCmd): move to tkText.c to avoid having to put all the internal
	text functions it uses into the stubs table.

	* generic/tkTextDisp.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXXStubs.c: fix gcc 4 warnings.

	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXScrlbr.c: sync with core-8-4-branch.

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c:
	* unix/configure:
	* unix/tkConfig.h.in: regen.

2005-11-22  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/tkfbox.tcl: Remove all references to data(curItem), as it is
	no longer used. [Bug 600313]
	(::tk::IconList_CurSelection): Renamed for clarity.

	* doc/GetFont.3: Revert previous fix; a NULL interp is now legal.
	* generic/tkFont.c (ParseFontNameObj, GetAttributeInfoObj): Allow these
	functions to work with a NULL interp by making them check when
	generating error messages. [Bug 1151523]

	* library/tkfbox.tcl (::tk::dialog::file::): Correct the quoting of the
	script used in variable traces so that widget names with spaces in will
	work. [Bug 1335485]

2005-11-16  Vince Darley  <vincentdarley@users.sourceforge.net>

	* doc/text.n: clarify left to right interpretation of index modifiers,
	including the fact that validation occurs after each step. [Bug
	1357575]

2005-11-15  Joe English  <jenglish@users.sourceforge.net>

	* unix/tkUnixWm.c, tests/unixWm.test, doc/wm.n: Support for [wm
	attributes] on X11. [TIP#231, Patch 1062022]

2005-11-14  Joe English  <jenglish@users.sourceforge.net>

	* library/bgerror.tcl: Truncate error messages at 45 characters
	instead of 30. [Bug 1224235]

2005-11-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkSelect.c (TkSelDefaultSelection): Test select-9.5
	highlighted further brokenness in this function.

2005-11-13  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* unix/tkUnixSelect.c (SelCvtToX): Arrange for the parsing code to use
	Tcl's list parsing code, another simplification that enables testing
	of the [Bug 1353414] fix.

	* unix/tkUnixSelect.c (SelCvtFromX): Generate string forms of the
	advanced selection types in a Tcl_DString. This makes fixing [Bug
	1353414] trivial, and simplifies the code at the same time.
	* tests/select.test (select-9.5): Added test for [Bug 1353414]

2005-11-10  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkBind.c (ChangeScreen):		More DString fixes from
	* generic/tkTextWind.c (EmbWinLayoutProc):	[Bug 1353022]
	* win/tkWinMenu.c (SetDefaults):

	* win/tkWinDialog.c (ConvertExternalFilename): Factored out the
	encoding conversion and de-backslash-ing code that is used in many
	places in this file.
	(GetFileNameW, GetFileNameA, ChooseDirectoryValidateProc): Make sure
	that data is freed correctly and that certain (hopefully impossible)
	failure modes won't cause crashes. [Bug 1353022]

2005-11-06  Pat Thoyts  <pat@zsplat.freeserve.co.uk>

	* unix/tcl.m4:  Fix SHLIB_LD_LIBS for building tclkit on OpenBSD.
	* unix/configure: regenerated

2005-10-31  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c
	* tests/textDisp.test: fix and test for [Bug 1333951] in '.text count
	-displaylines'.

2005-10-18  Don Porter	<dgp@users.sourceforge.net>

	* generic/tkMain.c: Rewrote code that sets the ::argv value to be sure
	conversion from the system encoding is complete before any processing
	sensitive to list-special characters is done. [Bug 1328926]

2005-10-17  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): check geomMgrPtr is
	valid before checking type

2005-10-15  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/menu.tcl (::tk::MenuUnpost): remove leftover ] from string
	equal mods of 2005-07-25. (sowadsky)

2005-10-14  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* win/tkWinSend.c:  Avoid using tcl internal headers and fix to
	* win/tkWinSendCom.h: correctly link on all types of build (was
	* win/tkWinSendCom.c: broken in static,msvcrt builds).

2005-10-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* tests/canvPs.test, tests/canvPsBmap.tcl, tests/canvPsImg.tcl:
	* tests/imgPhoto.test, tests/menu.test: Arrange for the test suite to
	only ever refer to images in the same directory as the tests. This
	makes it possible to package the test suite itself as a starkit. Thanks
	to David Zolli for suggesting this.

2005-10-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* generic/tkConfig.c (Tk_DeleteOptionTable, Tk_CreateOptionTable):
	properly alloc/delete one more option. [Bug 1319720] (melbardis)

	* macosx/tkMacOSXInt.h: Move MODULE_SCOPE defn to tkInt.h and add
	* generic/tkInt.h:    WORDS_BIGENDIAN checks that will work with OS X
	universal binary compiles. (steffen)

	* generic/tkMenu.c (TkSetWindowMenuBar): do not call TkMenuInit if the
	winPtr indicates TK_ALREADY_DEAD. This prevents reinit that creates a
	Tk exit handler after all exit handlers should be called. [Bug 749908,
	1322294]

2005-10-10  Vince Darley  <vincentdarley@users.sourceforge.net>

	TIP #256 IMPLEMENTATION

	* doc/text.n
	* generic/tkText.c
	* generic/tkText.h
	* generic/tkTextBTree.c
	* generic/tkTextDisp.c
	* generic/tkTextImage.c
	* generic/tkTextIndex.c
	* generic/tkTextMark.c
	* generic/tkTextTag.c
	* generic/tkTextWind.c
	* macosx/tkMacOSXDefault.h
	* tests/text.test
	* tests/textDisp.test
	* unix/tkUnixDefault.h
	* win/tkWinDefault.h: Implementation of TIP#256, adding a new text
	widget configuration option '-tabstyle', with new tests and
	documentation.

	Also a fix for [Bug 1281228] (documentation and full implementation of
	-strictlimits), and [Bug 1288677] (corrected elide behaviour), again
	with more tests.

2005-10-04  Jeff Hobbs  <jeffh@ActiveState.com>

	* library/dialog.tcl (::tk_dialog): add tkwait visibility before grab.
	[Bug 1216775]

	* win/tkWinDialog.c (ChooseDirectoryValidateProc): reset stored path to
	"" if it doesn't exist and -mustexist is true. [Bug 1309218] Remove
	old-style dir chooser (no longer used).

	* macosx/tkMacOSXInt.h: add MODULE_SCOPE definition check for extension
	writers that access private headers on OS X and don't define it in
	configure.

2005-09-28  Don Porter	<dgp@users.sourceforge.net>

	* unix/tkUnixPort.h:	Disabled inclusion of the private Tcl header
	* win/tkWinPort.h:	file tclInt.h. Tk ought to have a tiny and
	shrinking number of calls of private Tcl routines. Each Tk source file
	doing this should follow the convention in the macosx port and have its
	own #include "tclInt.h".

	* generic/tkEvent.c:	Disabled calls to private Tcl routine
	TclInExit(). See comment in TkCreateExitHandler() for full rationale.

2005-09-21  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkEvent.c (TkCreateThreadExitHandler, TkFinalizeThread)
	(TkDeleteThreadExitHandler): New internal API (from Joe Mistachkin) to
	allow Tk to finalize itself correctly in a multi-threaded
	environment. [Bug 749908]

2005-09-14  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkOldConfig.c (GetCachedSpecs): Split out the code to
	manipulate the cached writable specs so that it can be reused from all
	the public Tk_Configure* functions.
	(Tk_ConfigureInfo, Tk_ConfigureWidget, Tk_ConfigureValue): Use the
	factored out code everywhere, so we always manipulate the cache
	correctly. [Bug 1288128]

2005-09-13  Don Porter	<dgp@users.sourceforge.net>

	* win/winMain.c (WishPanic): Replaced TCL_VARARGS* macros with direct
	use of stdarg.h conventions.

2005-09-11  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): check if
	process is in front on MouseDown, otherwise request process activation
	from BringWindowForward() via new isFrontProcess param.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents): register
	our event handler on the dispatcher target for all carbon events of
	interest to TkAqua; this replaces event processing directly from the
	event queue and thus allows to capture events that are syntesized by
	Carbon and sent directly to the dispatcher and not to the event queue.

	* macosx/tkMacOSXEvent.c: remove TkMacOSXCountAndProcessMacEvents(),
	rename ReceiveAndProcessEvent() to TkMacOSXReceiveAndProcessEvent().
	(TkMacOSXReceiveAndProcessEvent): remove tk event processing before
	sending events to the dispatcher, all events of interest are now
	processed in our dispatcher target event handler.

	* macosx/tkMacOSXNotify.c (CarbonEventsCheckProc): dispatch events
	directly via TkMacOSXReceiveAndProcessEvent(), but dispatch no more
	than four carbon events at one time to avoid starving other event
	sources.

	* macosx/tkMacOSXEvent.c: formatting cleanup, move XSync() to XStubs,
	* macosx/tkMacOSXEvent.h: removed obsolete kEventClassWish handling.
	* macosx/tkMacOSXXStubs.c

	* macosx/tkMacOSXEvent.h: declare macosx internal procs as MODULE_SCOPE
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXButton.c: conditionalize all debug message printing to
	* macosx/tkMacOSXCursor.c: stderr via TK_MAC_DEBUG define.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* unix/configure.in: define TK_MAC_DEBUG on aqua when symbols enabled.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* library/listbox.tcl: synced aqua MouseWheel bindings with
	* library/scrlbar.tcl: core-8-4-branch.
	* library/text.tcl:

	* xlib/xcolors.c: fixed warning

2005-08-25  Daniel Steffen  <das@users.sourceforge.net>

	* unix/Makefile.in (html): reverted/amended changes of 2005-08-23 that
	broke TkAqua 'make install'; added BUILD_HTML_FLAGS optional var like
	in tcl/unix/Makefile.in.

2005-08-24  Donal K. Fellows  <dkf@users.sf.net>

	* tests/text.test (text-8.18): Fix punctuation of error message to
	match good practice (actual message already fixed). [Bug 1267484]

2005-08-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* macosx/tkMacOSXDialog.c: make dialogs ignore -initialfile "" and
	-initialdir "" instead of error.

2005-08-23  Mo DeJong  <mdejong@users.sourceforge.net>

	* win/tkWin32Dll.c (DllMain): Replace old asm SEH approach with Kenny's
	new SEH implementation. [Tcl Bug 1235544]

2005-08-23  Mo DeJong  <mdejong@users.sourceforge.net>

	* unix/Makefile.in: Subst BUILD_TCLSH and TCL_EXE.
	* unix/configure: Regen.
	* unix/configure.in: Update minimum autoconf version to 2.59. Invoke
	SC_PROG_TCLSH and SC_BUILD_TCLSH.
	* unix/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
	* win/Makefile.in: Subst BUILD_TCLSH and TCL_EXE.
	* win/configure: Regen.
	* win/configure.in: Update minimum autoconf version to 2.59. Invoke
	SC_BUILD_TCLSH.
	* win/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH): Split confused search
	for tclsh on PATH and build and install locations into two macros.
	SC_PROG_TCLSH searches just the PATH. SC_BUILD_TCLSH determines the
	name of the tclsh executable in the Tcl build directory. [Tcl Bug
	1160114] [Tcl Patch 1244153]

2005-08-22  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c: fix warnings.

2005-08-20  Joe Mistachkin  <joe@mistachkin.com>

	* win/tkWinX.c: Fixed bad cast. [Bug 1216006]

2005-08-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* doc/GetFont.3: Reworded to reflect the truth. [Bug 1151523]

2005-08-16 George Peter Staplin  <GeorgePS@XMission.com>

	* doc/CrtItemType.3 prototypes were lacking [] after objv. Thus the man
	page was wrong about the actual prototypes. This was verified by
	studying tkCanvBmap.c.

2005-08-13 Chengye Mao  <chengye.geo@yahoo.com>

	* generic/tkOldConfig.c: Fixed [Bug 1258604]. This bug was introduced
	into the modfied Tk_ConfigureWidget. It failed to properly handle the
	specFlags' bit TK_CONFIG_OPTION_SPECIFIED.

2005-08-12  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkOldConfig.c (Tk_ConfigureWidget): Stop storing per-thread
	data in global data structures. Store it in per-interpreter data (i.e.
	per-thread data) instead. [Bug 749908]

2005-08-10  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkFrame.c (CreateFrame) and others: Don't use size_t when
	working with Tcl_GetStringFromObj because it is not 64-bit clean. [Bug
	1252702]

2005-08-04  Vince Darley  <vincentdarley@users.sourceforge.net>

	* doc/text.n: Clarify behaviour of tab stops (as per [Bug 1247835])

2005-08-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXCarbonEvents.c (AppEventHandlerProc): handle carbon
	events sent directly to application event target via the general
	TkMacOSXProcessEvent() in the same way as events posted to the event
	loop. Moved existing app event handlers to tkMacOSXWindowEvent.c.
	(TkMacOSXInitCarbonEvents): register our application event handler for
	kEventWindowExpanded events to deal with uncollapsing from the dock.

	* macosx/tkMacOSXEvent.h: made TkMacOSXProcessEvent() non-static, added
	* macosx/tkMacOSXEvent.c: new interp field to TkMacOSXEvent struct for
				  use by app event handler.

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): retrieve
	current window, partCode, modifiers and local cursor position from
	carbon mouse event if possible. Use new static GenerateButtonEvent()
	taking a MouseEventData struct instead of TkGenerateButtonEvent() to
	avoid recomputing already known values. Move process activation on
	MouseDown into BringWindowForward() to allow clicking on window
	titlebar widgets without activating process. Move code dealing with
	clicks in window titelbar into separate function
	HandleWindowTitlebarMouseDown() to avoid code duplication. Avoid
	repeated calls to TkMacOSXGetXWindow() by storing result in
	MouseEventData struct.
	(TkMacOSXButtonKeyState, XQueryPointer): try to get button and modifier
	state from currently processed carbon event (to avoid unnecessary IPC
	with the window server), otherwise use modern carbon API to get this
	info instead of Button() and GetKeys(); only retrieve info caller asks
	for (via non-NULL ptr passed to XQueryPointer).
	(ButtonModifiers2State): new static function converting carbon button
	and modifier state into tk state, allows detection of more than 3 mouse
	buttons (tk supports up to 5) and of NumLock and Fn modifier keys
	(NumLock is mapped to Mod3 and Fn to Mod4).

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent):
	handle kEventWindowExpanded event to deal with window uncollapsing from
	the dock by generating tk Map event, handle kEventAppHidden and
	kEventAppShown events (moved here from tkMacOSXCarbonEvents.c).

	* macosx/tkMacOSXSubwindows.c (XUnmapWindow): only hide window when it
	is not iconified to avoid window flashing on collapse.

	* macosx/tkMacOSXWm.c: replaced Tk_DoWhenIdle() by Tcl_DoWhenIdle().
	(TkMacOSXZoomToplevel): remove call to TrackBox(), now done in
	HandleWindowTitlebarMouseDown() in tkMacOSXMouseEvent.c.
	(TkpWmSetState): avoid window flashing on collapse by unmapping after
	calling CollapseWindow(); only uncollapse window if it is collapsed.

	* generic/tkInt.decls: changed TkMacOSXZoomToplevel() signature.
	* generic/tkIntPlatDecls.h:

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only call
	GetMenuItemCommandID() on KeyDown or KeyRepeat events.

	* macosx/tkMacOSXMenu.c (ReconfigureMacintoshMenu): remove call to
	obsolete AppendResMenu() API.

	* macosx/tkMacOSXKeyEvent.c: replaced all direct uses of expensive
	* macosx/tkMacOSXMenu.c:    GetMouse() and TkMacOSXButtonKeyState()
	* macosx/tkMacOSXMenus.c:   APIs by calls to XQueryPointer()
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:   replaced use of FrontNonFloatingWindow()
	* macosx/tkMacOSXKeyEvent.c: by ActiveNonFloatingWindow() as
	* macosx/tkMacOSXMenu.c:    recommended by Carbon docs.
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c: fixed warnings
	* macosx/tkMacOSXTest.c:

	* macosx/tkMacOSXCarbonEvents.c: added CVS Id line to file header.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.h:

	* macosx/tkMacOSXInt.h: declare macosx internal procs as MODULE_SCOPE.
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXWindowEvent.c

	* library/bgerror.tcl: sync with core-8-4-branch changes of 2005-07-28.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXMouseEvent.c:

	* generic/tkFrame.c:   sync with core-8-4-branch changes of 2005-07-27.
	* generic/tkIntDecls.h:
	* generic/tkStubInit.c:
	* generic/tkFrame.c:
	* win/tkWinDraw.c:
	* unix/tkUnixDraw.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXButton.c: sync with core-8-4-branch.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXScale.c:

	* library/demos/menu.tcl: removed errant '}'.

2005-08-04  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* doc/clipboard.n: Add example demonstrating custom types of clipboard
	data.

2005-07-25  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* library/*.tcl: Updated to use more 8.4 and 8.5 features as part of
	resolving [Patch 1237759].

2005-07-22  Mo DeJong  <mdejong@users.sourceforge.net>

	* win/tkWinX.c: Define _WIN32_WINNT with NT SP 3 data to fix compiler
	error because SendInput was not defined. The new msys_mingw7 release is
	now needed to compile the HEAD with mingw gcc. [Bug 1210712]

2005-07-21  Jeff Hobbs	<jeffh@ActiveState.com>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): corrected if
	expression error (use of = instead of ==).

2005-07-18  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkTextMark.c: fix to segfault in "mark prev"
	* tests/textIndex.test: [Bug 1240221]

	* tests/textWind.test: make test more robust to avoid infinite loop

2005-07-06  Jeff Hobbs	<jeffh@ActiveState.com>

	* doc/getOpenFile.n: correct -multiple docs (takes boolean)

2005-07-05  Don Porter	<dgp@users.sourceforge.net>

	* unix/Makefile.in:	Purged use of TCLTESTARGS. [RFE 1161550]

2005-06-23  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkConsole.c (TkConsolePrint): prevent potential NULL deref.

	* macosx/tkMacOSXDefault.h: change ENTRY_BORDER defaults to from 5 to 2
	to make default entry widgets in TkAqua look like in other aqua apps
	(and have same border dimensions as other platforms). [Bug 1176610]

2005-06-21  Donal K. Fellows  <dkf@users.sf.net>

	* doc/GetBitmap.3: Fix silly error in SYNOPSIS. [Bug 1224983]

2005-06-19  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkImgGIF.c: Cleanse all static (i.e. non-thread-safe) data
	at a miniscule performance hit.

2005-06-18  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Makefile: for X11 build, add -X11 suffix to unversioned wish
	symbolic link.

	* unix/tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
	ensure we can always relocate binaries with install_name_tool.

	* unix/configure: autoconf-2.59

2005-06-07  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	Bump patchlevel to a4 to distinguish from a3 release.

2005-06-04  Jeff Hobbs	<jeffh@ActiveState.com>

	*** 8.5a3 TAGGED FOR RELEASE ***

2005-06-02  Jim Ingham	<jingham@apple.com>

	* generic/tkEvent.c (InvokeFocusHandlers): On Mac OS X the scrollwheel
	events are sent to the window under the mouse, not to the focus window

	Another patch from M. Kirkham.

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc, ScrollBarBindProc): Record
	the first mouse down point, and compute differences from that, rather
	than getting the mouse down each time through the loop. The old method
	would get fooled if you moved the mouse less than a text line height in
	the text widget. [Bug 1083728]

2005-06-03  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/Makefile: fixed 'embedded' target.

2005-06-02  Reinhard Max  <max@suse.de>

	* unix/tkUnix.c (Tk_GetUserInactiveTime): Improvements to get it
	working on Solaris, and panic if we run out of memory.
	* unix/configure.in: Rework the searching for Xss, to make it work on
	Solaris and provide more useful output. Use AC_HELP_STRING where
	appropriate.
	* unix/tcl.m4: synced from Tcl.
	* unix/configure: regenerated with autoconf 2.59.

2005-06-01  Jeff Hobbs	<jeffh@ActiveState.com>

	* win/tkWinInt.h: added private decls of Tk_GetEmbeddedMenuHWND,
	Tk_GetMenuHWND, TkWinCleanupContainerList, and TkpWmGetState to that
	are used across source files.

	* win/tkWinX.c (Tk_ResetUserInactiveTime): cast to squelch compiler
	warning.

2005-05-31  Reinhard Max  <max@suse.de>

	* doc/Inactive.3 (new file): C level API documentationn for
	TIP#245 (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime).
	* tests/tk.test: Added tests for the TIP#245 implementation.

2005-05-30  Jeff Hobbs	<jeffh@ActiveState.com>

	* generic/tkPanedWindow.c, tests/panedwindow.test: batch of fixes to
	panedwindow from Daniel South. Improved auto-size to fit internal
	windows, fixed sash placement at edge of pane, fixed calculation of
	stretch amount for internal windows. [Bug 1124198, 1161543, 1054117,
	1010941, 795869, 690169, 1192323]

	* generic/tkMenu.c (MenuCmd): create event handler earlier to ensure
	proper destruction of menu through DestroyNotify. [Bug 1159367]

	* library/console.tcl (::tk::ConsoleInit): print out first prompt and
	swallow the extra "% " that comes once from Tcl on Windows.

2005-05-29  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXFont.c: use Tcl_Panic instead of panic.

	* unix/configure.in: added description of HAVE_XSS for autoheader.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/project.pbxproj: added missing FRAMEWORK defines
	introduced with configure/make based build.

	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: fixed warnings.

	* generic/tkDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: ran missing 'make genstubs' for TIP245 changes
	to tk.decls

	* macosx/tkMacOSXXStubs.c (Tk_ResetUserInactiveTime): use symbolic
	constant argument in call to UpdateSystemActivity();

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/project.pbxproj:
	* unix/configure.in: added/corrected linking to IOKit.framework for
	TIP245.

	* unix/configure.in: skip X11 configure checks when building tk_aqua.
	* unix/configure: autoconf-2.59

2005-05-28  Donal K. Fellows  <dkf@users.sf.net>

	TIP #245 IMPLEMENTATION from Reinhard Max <max@suse.de>

	* doc/tk.n: Documentation of [tk inactivity].
	* win/tkWinX.c (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime):
	* unix/tkUnix.c (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime):
	* macosx/tkMacOSXXStubs.c:	Implementations of the core API for
	(Tk_GetUserInactiveTime):	determining how long as user's left
	(Tk_ResetUserInactiveTime):	her machine alone.
	* unix/configure.in: Test for XScreenSaver support.
	* generic/tkCmds.c (Tk_TkObjCmd): Implementation of [tk inactivity].

2005-05-27  Todd Helfter  <tmh@users.sourceforge.net>

	* library/menu.tcl: correct the sticky behavior of menus posted by
	tk_popup so that they "stick" after the initial <ButtonRelease>
	following the post, that is not over an active menu entry.

2005-05-26  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXInit.c (TkpInit): fixed resource file extraction from
	__tk_rsrc section to work with non-prebound .dylib and .bundle.

	* macosx/Makefile: corrected EMBEDDED_BUILD check, use separate Tcl and
	Tk version vars to properly support tk/x11 framework version
	overriding, rewrite tkConfig.sh when overriding tk version, corrected
	Wish.app symlink in tk build dir.

	* unix/configure.in: corrected framework finalization to softlink stub
	library to Versions/8.x subdir instead of Versions/Current.
	* unix/configure: autoconf-2.59

2005-05-25  Jeff Hobbs	<jeffh@ActiveState.com>

	* unix/Makefile.in (install-libraries): protect possible empty list in
	for with list= trick for older shells.

2005-05-23  Jeff Hobbs	<jeffh@ActiveState.com>

	* generic/tkFileFilter.c (FreeGlobPatterns): s/null/NULL/

2005-05-24  Daniel Steffen  <das@users.sourceforge.net>

	* generic/tkTest.c: disable commands not available on TkAqua.

	* macosx/Makefile:
	* macosx/README:
	* macosx/Tk-Info.plist.in (new file):
	* macosx/Wish-Info.plist.in (new file):
	* unix/Makefile.in:
	* unix/configure.in:
	* unix/tcl.m4:
	* unix/tkUnixInit.c: moved all Darwin framework and TkAqua build
	support from macosx/Wish.pbproj and macosx/Makefile into the standard
	unix configure/make buildsystem, the project and macosx/Makefile are no
	longer required to build Tk.framework and/or TkAqua. TkAqua is now
	enabled by the --enable-aqua configure option, and static and
	non-framework builds of TkAqua are now available via the standard
	configure switches. Tk/X11 can also be built as a framework. The
	macosx/Makefile now wraps the unix buildsystem and no longer uses the
	projects, embedded builds are still only available via this Makefile,
	but for other builds it is not longer required (but its current
	functionality is still available for backwards compatibility). The
	projects currently do not call through to the Makefile to build (unlike
	Tcl.pbproj) so project builds may differ from makefile builds. Due to
	issues with spaces in pathnames, 'Wish Shell.app' has been renamed to
	'Wish.app', the macosx/Makefile installs backwards compatibility
	symlinks for the old name.
	* macosx/tkMacOSXInit.c (TkpInit): added support for Tk resource file
	in non-framework and static builds: the resource file is copied into a
	__tk_rsrc MachO section of the library or executable at link time and
	extracted into a temporary location at initialization.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in (new file): autoheader-2.59

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Tk-Info.plist:
	* macosx/Wish-Info.plist:
	* macosx/tkAboutDlg.r: updated copyright years to 2005.

2005-05-22  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkFileFilter.c (TkGetFileFilters): Add all filters, not just
	the first one. [Bug 1206133]

2005-05-15  Jim Ingham	<jingham@apple.com>

	Fixes from Michael Kirkham:

	* macosx/tkMacOSXMenu.c (TkpConfigureMenuEntry): Thinko in clearing the
	ENTRY_ACCEL_MASK before re-parsing it. [Bug 1012852]

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): Don't set the control
	value BEFORE setting the min and max or the control manager will reset
	it for you. [Bug 1202181]

	* macosx/tkMacOSXXStubs.c (TkMacOSXXGetPixel, TkMacOSXXPutPixel):
	Restore the port to what it was before putting we were called. [Bug
	1202223]

2005-05-14  Jim Ingham  <jingham@apple.com>

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc): Missing Tcl_Release.

2005-05-14  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: introduction of new tcl notifier based on
	CFRunLoop allows replacement of the custom TkAqua notifier by a
	standard tcl event source. Removes requirement of threaded tcl core
	for TkAqua, allows to stub-link TkAqua against Tcl by removing use of
	the unstubbed TclInitNotifier & TclFinalizeNotifier. [Tcl Patch
	1202052]

	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.pbproj/project.pbxproj: stub-link TkAqua: build with
	USE_TCL_STUBS and link against libtclstub instead of Tcl.framework,
	unexport libtclstub symbols from Tk to avoid duplicate symbol warnings
	when linking with both Tcl and Tk, fixes for gcc4.0 warnings.

	* macosx/Wish.xcode/project.pbxproj: sync with Wish.pbproj changes
	since 2004-11-19.
	NOTE: to use this project, need to uncomment the tclConfig.h settings
	at the top of tcl/unix/configure.in, autoconf and rebuild tcl !

	* macosx/tkMacOSXBitmap.c:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c: fixed gcc 4.0 warnings.

	* unix/tcl.m4: sync with tcl
	* unix/configure: autoconf-2.59

2005-05-10  Vince Darley  <vincentdarley@users.sourceforge.net>

	* library/text.tcl: test and fix to TextPrevPara to avoid infinite loop
	* tests/textIndex.test: at start of widget. [Bug 1191895]

	* generic/tkTextDisp.c: better synchronisation between explicit and
	implicit pixel line-height calculations. [Bug 1186558]

2005-05-10  Don Porter	<dgp@users.sourceforge.net>

	* generic/tkTextDisp.c (GetXView): Improved numerical precision of
	calculation of [.t xview] return values.
	* tests/textDisp.test: Match greater precisions of [.t xview] and
	[.t yview] values in tests.

2005-05-06  Jeff Hobbs	<jeffh@ActiveState.com>

	* unix/configure: regen
	* unix/configure.in: Add AC_C_BIGENDIAN check and pkg-config xft checks
	to extend xft search.
	* unix/tcl.m4: Correct Solaris 10 (5.10) check and add support for
	x86_64 Solaris cc builds.

2005-04-28  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* macosx/tkMacOSXNotify.c (TkMacOSXWaitForEvent): Fix for typo in
	waitTime computation. [Bug 1191097]
	(AlertNotifier): Factor out the core of the notifier alerting code.

2005-04-25  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXNotify.c: sync with tclUnixNotfy.c changes since
	2004-06-22, added compile time check for threaded tcl core, removed
	unthreaded code paths as they are never used anyway, fixed
	TkMacOSXAlertNotifier() implementation.

	* unix/Makefile.in: added TCL_STUB_LIB_FILE, needed for unexporting of
	symbols from libtclstub to avoid duplicate symbol warnings.

	* unix/tcl.m4 (Darwin): added configure checks for recently added
	linker flags -single_module and -search_paths_first to allow building
	with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD
	and not just T{CL,K}_SHLIB_LD_EXTRAS, added unexporting from Tk of
	symbols from libtclstub to avoid duplicate symbol warnings, added
	PLAT_SRCS definition for Mac OS X, defined MODULE_SCOPE to
	__private_extern__.
	(SC_MISSING_POSIX_HEADERS): added caching of dirent.h check.

	* unix/configure: autoconf-2.59

2005-04-22  George Peter Staplin  <GeorgePS@XMission.com>

	* doc/FontId.3: I fixed a typo. "linespace" was used instead of
	"ascent". I also added a .PP before the paragraph to make the
	formatting look better for the ascent paragraph.

2003-04-18  Joe English	 <jenglish@users.sourceforge.net>

	* unix/tkUnixRFont.c(Tk_MeasureChars): Use Tcl_UtfToUnichar() for lax
	UTF-8 parsing instead of strict parsing with FcUtf8ToUcs4()
	[fix/workaround for Bug 1185640]

2003-04-18  Vince Darley  <vincentdarley@users.sourceforge.net>

	* library/text.tcl
	* doc/text.n: corrected 'Home' and 'End' and Control-a/e handling to
	work with display lines. This was an ommission of the previous tip155
	patch. Clarified the documentation on this point.

2005-04-14  Jeff Hobbs	<jeffh@ActiveState.com>

	* unix/tkUnixFont.c (FontMapLoadPage): reorder char[] decls to avoid
	possible segv. Minimal fix for [Bug 1122671]

2005-04-12  Jeff Hobbs	<jeffh@ActiveState.com>

	* library/tkfbox.tcl (::tk::dialog::file::): fix typeMenuLab ref. Add
	undoc'd ::tk::dialog::file::showHiddenBtn var (default 0) that will add
	a "Show Hidden" checkbutton to tk_get*File and tk_chooseDirectory if
	set to true.
	* library/choosedir.tcl (::tk::dialog::file::chooseDir::): fix
	cancelBtn ref, add hiddenBtn ref for "Show Hidden" button.

2005-04-09  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/README: updated requirements for OS & developer tool versions
	+ other small fixes/cleanup.

	* macosx/tkMacOSXEntry.c (ComputeIncDecParameters): manually define
	constants present only in 10.3 headers so that we can build on 10.2.

	* macosx/Wish.pbproj/project.pbxproj: fixed absolute path to tkEntry.h
	that confused 10.2 PBX.

	* unix/tcl.m4 (Darwin): added -single_module linker flag to
	TCL_SHLIB_LD_EXTRAS and TK_SHLIB_LD_EXTRAS.
	* unix/configure: autoconf-2.59

2005-04-07  Mo DeJong  <mdejong@users.sourceforge.net>

	* macosx/tkMacOSXWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	* unix/tkUnixWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	* win/tkWinWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	Fix panic in wm stackorder when a toplevel is created on another
	display. The code now ignores toplevels that have a display that does
	not match the display of the parent window. [Bug 1152809]

2005-04-06  Donal K. Fellows  <dkf@users.sf.net>

	* doc/wm.n, doc/winfo.n, doc/tk.n, doc/send.n, doc/selection.n:
	* doc/radiobutton.n, doc/photo.n, doc/options.n, doc/menu.n:
	* doc/listbox.n, doc/getOpenFile.n, doc/font.n, doc/event.n:
	* doc/entry.n, doc/clipboard.n, doc/checkbutton.n, doc/canvas.n:
	* doc/button.n, doc/bind.n, doc/TextLayout.3, doc/MeasureChar.3:
	* doc/GetRelief.3, doc/GetPixels.3, doc/GetJustify.3, doc/GetFont.3:
	* doc/GetCursor.3, doc/GetColor.3, doc/GetBitmap.3, doc/GetAnchor.3:
	* doc/FontId.3, doc/CrtWindow.3, doc/CrtImgType.3, doc/ConfigWidg.3:
	* doc/3DBorder.3: Purge old .VS/.VE macro instances.

2005-04-04  Don Porter	<dgp@users.sourceforge.net>

	* library/comdlg.tcl: Added Macintosh file type validation to
	[::tk::FDGetFileTypes]. [Bug 1083878] (Thanks, Vince Darley)

2005-04-04  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c:
	* tests/text.test: fix to elide searching problems [Bug 1174269] and
	disappearing cursor with insertofftime 0. [Bug 1169429]

2005-04-03  Peter Spjuth  <peter.spjuth@space.se>

	* tests/grid.test:
	* generic/tkGrid.c: Fixed bug in geometry calculations for widgets that
	span multiple columns/row. Bug was introduced in 8.5a1 when fixing
	792387. [Bug 1175092]

2005-03-29  Jeff Hobbs	<jeffh@ActiveState.com>

	* win/tcl.m4, win/configure: do not require cygpath in macros to allow
	msys alone as an alternative.

2005-03-27  Vince Darley  <vincentdarley@users.sourceforge.net>

	* tests/textDisp.test: added test for fix of 2005-03-15.

2005-03-24  Jim Ingham	<jingham@apple.com>

	* macosx/tkMacOSXEntry.c (TkpDrawEntryBorderAndFocus): Dopey bug - do
	not reset the width for entry widgets - we didn't change it for them.

2005-03-23  Jim Ingham	<jingham@apple.com>

	These changes allow us to draw the Entry and Spinbox widget with a
	native look and feel on Mac OS X.

	* generic/tkEntry.h: New file, extracting the definitions of Entry and
	Spinbox.
	* generic/tkEntry.c (DisplayEntry): Call out to TkpDrawSpinboxButtons
	and TkpDrawEntryBorderAndFocus. Also provide default implementations
	for X11 & Win.
	* macosx/tkMacOSXEntry.c: New file, implements the entry & focus and
	spinbox button drawing.
	* tkMacOSXDefaults.h: Change the Mac OS X defaults so they fit the
	native widget shapes.

	This is cleanup thanks to Neil Madden <nem@cs.nott.ac.uk>.

	* macosx/tkMacOSXWm.c (TkMacOSXWinStyle) New function.
	(TkUnsupported1ObjCmd): New function, replaces the un-objectified
	version of the command.
	* generic/tkInt.h: Swap TkUnsupported1Cmd for TkUnsupported1ObjCmd.
	* generic/tkWindow.c (): Ditto.

	This adds a "-notify" flag to "wm attributes" that will bounce the
	dock icon on Mac OS X.	This is from Revar Desmera <revarbat@gmail.com>

	* macosx/tkMacOSXWm.c (WmAttrGetNotifyStatus, WmAttrSetNotifyStatus):
	New functions.
	(WmAttributesCmd): Add the -notify.
	* doc/wm.n: Document -notify.

2005-03-19  Donal K. Fellows  <dkf@users.sf.net>

	* generic/tkConsole.c (Tk_CreateConsoleWindow,TkConsolePrint): Rewrite
	so that TkConsolePrint cannot become detached from the console when the
	[console] command is renamed. [Bug 1016385]

2005-03-15  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkTextDisp.c: fix for [Bug 1143776] in adjusting displayed
	lines when running into the bottom of the window.

2005-03-14  Jim Ingham	<jingham@apple.com>

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc): No need to use "update
	idletasks" here, TclServiceIdle will do as well and it is simpler.

	These changes implement a change on the Mac OS X side. When we unmap a
	window we mark all its children as unmapped (not following toplevels.
	But we preserve whether they had been mapped before, and when the
	parent is remapped, we remap the children as well. [Bug 940117]

	* macosx/tkMacOSXInt.h: Added TK_MAPPED_IN_PARENT
	* macosx/tkMacOSXSubwindows.c (FixMappingFlags): New function.
	(XMapWindow): Call FixMappingFlags.
	(XUnMapWindow): Ditto.

	* macosx/tkMacOSXSubwindows.c (XMoveResizeWindow): Update the xOff &
	yOff data in the Macdrawable even if the native window hasn't been
	created yet. [Bug 700305]
	(XMoveWindow): Ditto.
	(XResizeWindow): Ditto.

2005-03-15  Pat Thoyts	<patthoyts@users.sourceforge.net>

	* unix/tcl.m4:	  Updated the OpenBSD configuration and regenerated the
	* unix/configure: configure script.

2005-03-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkEvent.c (InvokeClientMessageHandlers): Ensure that client
	messages are handled correctly. Thanks to George Petasis for tracking
	this down. [Bug 1162356]

2005-03-11  Jim Ingham	<jingham@apple.com>

	* macosx/tkMacOSXButton.c (TkpDisplayButton): Set the port to the
	Button window's port BEFORE you set the clip, otherwise you are setting
	the clip on the wrong window!
	Also, a little cleanup - move x & y into the branches where they are
	used, and don't compute the TextAnchor if we are using the native
	button text, since we aren't going to use it.
	(TkMacOSXDrawControl): Call ShowControl & SetControlVisibility in a
	more logical order.

	* tkMacOSXInt.h: Add TkMacOSXGenerateFocusEvent.
	* tkMacOSXSubwindows.c (XDestroyWindow): We don't get Activate events
	for the remaining windows when a Floating window is destroyed. This can
	cause the focus to disappear. So catch this case when the window is
	being destroyed and move the focus here.

	* tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): Make this public
	(used to be GenerateFocusEvent) since we need it here and in
	tkMacOSXSubwindows.c. Then change the name everywhere it is used. [Bug
	1124237]

2005-03-10  Jim Ingham	<jingham@apple.com>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): In the
	inDrag section, set the GrafPort to the drag window's GrafPort before
	doing LocalToGlobal. [Bug 1160025]

2005-03-09  Jim Ingham	<jingham@apple.com>

	* macosx/tkMacOSXInit.c (TkpInit): Check to see if the environment
	variable XCNOSTDIN is set, and if so, close stdin & stdout. This is
	necessary to make remote debugging under Xcode work properly.

2005-03-08  Jeff Hobbs	<jeffh@ActiveState.com>

	* win/tkWinWm.c (WinSetIcon): fix GCLP_ICONSM -> GCLP_HICONSM.

	* win/makefile.vc: clarify necessary defined vars that can come from
	MSVC or the Platform SDK.

2005-02-28  Jeff Hobbs	<jeffh@ActiveState.com>

	* win/tkWinX.c (GenerateXEvent): correct %A translation on MouseWheel.
	[Bug 1118340]

2005-02-24  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSX.h: fixed incorrect inclusion of internal header.
	* macosx/tkMacOSXNotify.c: corrected included headers.

2005-02-22  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXDialog.c (Tk_GetSaveFileObjCmd, NavServicesGetFile):
	fixed encoding problems with -initialfile & -filetypes and corrected
	potential buffer overrun with -initialdir/-initialfile. [Bug 1146057]

2005-02-16  Mo DeJong  <mdejong@users.sourceforge.net>

	TIP#223 IMPLEMENTATION

	* doc/wm.n: Add documentation for -fullscreen attribute.
	* tests/winWm.test: Add -fullscreen to wm attribute usage message.
	* tests/wm.test: Add -fullscreen to wm attribute usage message. Add
	-fullscreen attribute test cases for Windows.
	* win/tkWinWm.c (WmInfo, UpdateWrapper, TkpWmSetFullScreen)
	(WmAttributesCmd, UpdateGeometryInfo):
	Implement TIP 223 [wm attributes -fullscreen].

2005-02-14  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextDisp.c:
	* generic/tkTextIndex.c:
	* generic/tkTextBTree.c:
	* doc/text.n:
	* tests/textDisp.test:
	* tests/textIndex.test: fix of longstanding elide problem when eliding
	a newline without eliding the entire logical line. [Bug 443848]

2005-02-14  Jeff Hobbs	<jeffh@ActiveState.com>

	* doc/options.n: note -cursor {} behavior. [Bug 965618]

2005-02-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* tests/all.tcl: Add a [package require Tk] so that a missing display
	causes an early failure and keeps the error trace short. Issue observed
	in [FRQ 11122147], even though that's unrelated.

2005-02-11  Jeff Hobbs	<jeffh@ActiveState.com>

	* library/panedwindow.tcl (::tk::panedwindow::Cursor): check window
	existence on delayed call. [Bug 949792]

	* doc/text.n: note 'image' key in 'dump' command. [Bug 1115907]

	* win/tkWinWm.c (TkWinGetIcon): fix toplevel retrieval for determining
	icon ref (potential crash). [Bug 1105738]

	* generic/tkCanvBmap.c (ConfigureBitmap, ComputeBitmapBbox): Fixed
	possible crash with disabled bmap and bbox handling [Bug 1119460]
	(BitmapToPostscript): made aware of various bitmap types

	* unix/Makefile.in: remove SHLIB_LD_FLAGS (only for AIX, inlined into
	* unix/tcl.m4:	    SHLIB_LD). Combine AIX-* and AIX-5 branches in
	* unix/configure:   SC_CONFIG_CFLAGS. Correct gcc builds for AIX-4+ and
	HP-UX-11. autoconf-2.59 gen'd.

2005-02-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* tests/wm.test: Convert to use more tcltest2 features.

2005-02-07  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkCanvas.c (CanvasWidgetCmd): Fix stupid mistake in variable
	names, reported by Andreas Leitgeb.

2005-02-03  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkCanvas.c (GetStaticUids): New function to manage the
	thread-specific data detailing the list of all uids in a thread.
	(typeList): Protect this (the other piece of global data) with a mutex.
	[Bug 1114977]

2005-01-31  Jeff Hobbs	<jeffh@ActiveState.com>

	* unix/tcl.m4, unix/configure: add solaris-64 gcc build support. [Bug
	1021871]

2005-01-31  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* generic/tkImgPhoto.c (PhotoFormatThreadExitProc): Made the comments
	in the code more relevant to the function they were documenting! [Bug
	1110553]

	* library/msgs/es_ES.msg: Added more localization for Spanish Spanish.
	[Bug 1111213]

2005-01-25  Daniel Steffen  <das@users.sourceforge.net>

	* macosx/tkMacOSXInit.c (TkpInit): set tcl_interactive to 1 to show
	console at startup instead of directly calling [console show].

	* unix/tcl.m4 (Darwin): fixed bug with static build linking to dynamic
	library in /usr/lib etc instead of linking to static library earlier in
	search path. [Tcl Bug 956908]
	Removed obsolete references to Rhapsody.
	* unix/configure: autoconf-2.57

2005-01-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* library/demos/menu.tcl: Reworked to make dialogs children of the
	demo widget so that they are properly visible. Issue reported by Keith
	Nash <k.j.nash@usa.net>

2005-01-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* library/tkfbox.tcl (IconList_Selection, IconList_Create):
	(IconList_Arrange): Assorted tk_getOpenFile fixes. [part of Bug 600313]
	(IconList_ShiftMotion1): Also fix shift-drag.

2005-01-12  Don Porter	<dgp@users.sourceforge.net>

	* unix/tcl.m4:		Sync'ed to Tcl's copy.
	* unix/configure:	autoconf-2.57

2005-01-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/event.n: Added section on predefined virtual events. [Bug 608115]

2005-01-11  Vince Darley  <vincentdarley@users.sourceforge.net>

	* generic/tkTextDisp.c: fix to scrollbar height calculations of text
	widgets containing a single very long (wrapped) line. This fixes at
	least part of [Bug 1093631].

2005-01-11  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* generic/tkObj.c (TkParsePadAmount):
	* generic/tkPack.c: Moved function to tkObj.c and rewrote so that it
	takes advantage of Tcl_Objs properly and cannot leave objects in an
	inconsistent state. [Bug 1098779]

2005-01-10  Joe English	 <jenglish@users.sourceforge.net>

	* unix/Makefile.in, unix/configure.in, unix/tkConfig.sh.in:
	Remove ${DBGX}, ${TK_DBGX} from Tk build system. [Patch 1081595]
	* unix/tcl.m4: re-synced with tcl/unix/tcl.m4
	* unix/configure: Regenerated.

2005-01-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* generic/tkWindow.c (GetScreen): Make sure the result is reset on all
	error paths to stop strange errors. [Bug 697915]

2005-01-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/loadTk.n, doc/toplevel.n: Convert to other form of emacs mode
	control comment to prevent problems with old versions of man. [Bug
	1085127]

2005-01-03  Jeff Hobbs	<jeffh@ActiveState.com>

	* win/tkWinWm.c (TkWinWmCleanup): clean up layered window class. This
	caused crash in reinit of Tk (as seen in plugin).

	******************************************************************
	*** CHANGELOG ENTRIES FOR 2004 AND 2003 IN "ChangeLog.2004"    ***
	*** CHANGELOG ENTRIES FOR 2002 AND EARLIER IN "ChangeLog.2002" ***
	******************************************************************
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to README.md.

1
2
3
4
5
6
7




8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# README:  Tk

This is the **Tk 8.7a4** source distribution.

You can get any source release of Tk from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).






## <a id="intro">1.</a> Introduction

This directory contains the sources and documentation for Tk, a
cross-platform GUI toolkit implemented with the Tcl scripting language.

For details on features, incompatibilities, and potential problems with
this release, see [the Tcl/Tk 8.7 Web page](https://www.tcl.tk/software/tcltk/8.7.html)
or refer to the "changes" file in this directory, which contains a
historical record of all changes to Tk.

Tk is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at [core.tcl-lang.org](https://core.tcl-lang.org/).
Tcl/Tk release and mailing list services are [hosted by


|




>
>
>
>







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# README:  Tk

This is the **Tk 8.5.19** source distribution.

You can get any source release of Tk from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).

Build Status: 8.5.19
[![Build and Test Status: Linux 8.5](https://github.com/tcltk/tk/workflows/Linux/badge.svg?branch=core-8-5-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Acore-8-5-branch)
[![Build and Test Status: Windows 8.5](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=core-8-5-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Acore-8-5-branch)
[![Build and Test Status: macOS 8.5](https://github.com/tcltk/tk/workflows/macOS/badge.svg?branch=core-8-5-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22macOS%22+branch%3Acore-8-5-branch)

## <a id="intro">1.</a> Introduction

This directory contains the sources and documentation for Tk, a
cross-platform GUI toolkit implemented with the Tcl scripting language.

For details on features, incompatibilities, and potential problems with
this release, see [the Tcl/Tk 8.5 Web page](https://www.tcl.tk/software/tcltk/8.5.html)
or refer to the "changes" file in this directory, which contains a
historical record of all changes to Tk.

Tk is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at [core.tcl-lang.org](https://core.tcl-lang.org/).
Tcl/Tk release and mailing list services are [hosted by

Changes to changes.

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
is necessary in order to allow several menu buttons to share the
same menu.
*** POTENTIAL INCOMPATIBILITY ***

4/12/92 (bug fix) Fixed core dump that occurred in tkError.c when
removing the first error record from the error list.

4/15/92 (bug fix) Fixed bug in tkBind.c that prevented <Key-1>
event specifications from being processed correctly:  the "1" was
treated as a button name rather than a keysym.

4/18/92 (new feature) Added Tk_DefineCursor and Tk_UndefineCursor
procedures.

4/18/92 (new feature) Major revision to listboxes.  Can now scroll and







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
is necessary in order to allow several menu buttons to share the
same menu.
*** POTENTIAL INCOMPATIBILITY ***

4/12/92 (bug fix) Fixed core dump that occurred in tkError.c when
removing the first error record from the error list.

4/15/92 (bug fix) Fixed bug in tkBind.c that prevented <KeyPress-1>
event specifications from being processed correctly:  the "1" was
treated as a button name rather than a keysym.

4/18/92 (new feature) Added Tk_DefineCursor and Tk_UndefineCursor
procedures.

4/18/92 (new feature) Major revision to listboxes.  Can now scroll and
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
canvases) so that it correctly prints all of the characters in the
ISO Latin-1 character set.

2/19/94 (bug fix) Modified tkBind.c to save and restore the interpreter's
result across the execution of binding scripts.  Otherwise if an event
triggers in the middle of some other script (e.g. a destroy event during
window creation, because there was an error in the creation command),
the interpreter's result gets lost.

2/19/94 (bug fix) Fixed bug in dealing with results of sent command
that could cause them to get lost in some situations.

2/21/94 (bug fix) Don't let user close a dialog window created by
tk_dialog, since this would cause tk_dialog to hang:  force the user
to select one of the dialog's buttons.







|







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
canvases) so that it correctly prints all of the characters in the
ISO Latin-1 character set.

2/19/94 (bug fix) Modified tkBind.c to save and restore the interpreter's
result across the execution of binding scripts.  Otherwise if an event
triggers in the middle of some other script (e.g. a destroy event during
window creation, because there was an error in the creation command),
the intepreter's result gets lost.

2/19/94 (bug fix) Fixed bug in dealing with results of sent command
that could cause them to get lost in some situations.

2/21/94 (bug fix) Don't let user close a dialog window created by
tk_dialog, since this would cause tk_dialog to hang:  force the user
to select one of the dialog's buttons.
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

10/18/96 (new features) A -menu option has been added to the toplevel
widget command, which allows a menu to operate as a menubar. On the
Macintosh, the menubar is displayed accross the top of the main monitor,
just like with other applications. Under Windows and Unix, the menu is
attached to the toplevel window. Also, changed some semantics.
Tearoff menus will now reflect changes to the menu it was
torn off from, and are deleted when the main menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

10/31/96 (bug fix) Under Windows, missing system cursors would
generate an error instead of falling through to the Tk cursor of the
same name. (SS)








|







3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

10/18/96 (new features) A -menu option has been added to the toplevel
widget command, which allows a menu to operate as a menubar. On the
Macintosh, the menubar is displayed accross the top of the main monitor,
just like with other applications. Under Windows and Unix, the menu is
attached to the toplevel window. Also, changed some semantics.
Tearoff menus will now reflect changes to the menu it was
torn off from, and are deleted when the master menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

10/31/96 (bug fix) Under Windows, missing system cursors would
generate an error instead of falling through to the Tk cursor of the
same name. (SS)

3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
into account the "-displayof" option.  This problem also existed for the
"font metrics" and "font measure" commands. (CCS)

9/16/97 (new feature) Added "resource delete" and "resource files"
command to the Mac.  Also fixed "resource write" when the resource
was specified by id and already existed. (JI)

9/16/97 (bug fix) Added null bindings to <Command-Key> for the
text and entry widget on the Macintosh.  This prevents unbound command
key sequences from having the character echoed to the widget. Also
fixed Cut & Copy bindings.  (JI) (RJ)

9/18/97 (bug fix) Revamped Macintosh focus code.  Cut, Copy & Paste
virtual events now go to the correct (focus) window. (RJ)








|







3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
into account the "-displayof" option.  This problem also existed for the
"font metrics" and "font measure" commands. (CCS)

9/16/97 (new feature) Added "resource delete" and "resource files"
command to the Mac.  Also fixed "resource write" when the resource
was specified by id and already existed. (JI)

9/16/97 (bug fix) Added null bindings to <Command-KeyPress> for the
text and entry widget on the Macintosh.  This prevents unbound command
key sequences from having the character echoed to the widget. Also
fixed Cut & Copy bindings.  (JI) (RJ)

9/18/97 (bug fix) Revamped Macintosh focus code.  Cut, Copy & Paste
virtual events now go to the correct (focus) window. (RJ)

5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
correctly. (hobbs)

2001-08-28 (bug fix) fixed tk_chooseDirectory crash on Win95. (baker)

2001-08-28 (bug fix) removed 2 second 'raise' delay seen by some Unix
window managers. (hobbs, baker)

2001-09-14 (bug fix) fixed memory leaks that occurred if errors were
thrown while initializing the channel for an image. (darley)

2001-09-20 (new feature) --enable-64bit support was added for HP 11 when
using the native compiler.

2001-10-03 (new feature) finalized Win64 support with latest RC1 release
and SDK. (hobbs, stacy)







|







5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
correctly. (hobbs)

2001-08-28 (bug fix) fixed tk_chooseDirectory crash on Win95. (baker)

2001-08-28 (bug fix) removed 2 second 'raise' delay seen by some Unix
window managers. (hobbs, baker)

2001-09-14 (bug fix) fixed memory leaks that occured if errors were
thrown while initializing the channel for an image. (darley)

2001-09-20 (new feature) --enable-64bit support was added for HP 11 when
using the native compiler.

2001-10-03 (new feature) finalized Win64 support with latest RC1 release
and SDK. (hobbs, stacy)
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558

6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573



6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786


6787
6788
6789
6790
6791
6792
6793


6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912

2008-03-27 (platform support)[1921166] Solaris 64bit build fixes (steffen)

2008-03-27 (bug fix) restored [::safe::loadTk] (hobbs)

--- Released 8.5.2, March 28, 2008 --- See ChangeLog for details ---

2008-04-01 (interface)[1819422] tkStubsPtr no longer in libtk (porter)
	*** POTENTIAL INCOMPATIBILITY ***

2008-04-02 (interface)[1819422] libtkstub symbols MODULE_SCOPE (steffen)

2008-04-07 (bug fix)[1937135] Tk_ParseArgv() double free crash (hobbs)

2008-04-07 (bug fix)[1936238] wish -h mem explosion (bachmann,kenny)

2008-04-08 (new feature) Win: visual-styles API element engine (thoyts)

2008-04-09 (enhancement) real LZW compression in GIF writer (nijtmans)

2008-04-14 (bug fix)[1941740] [tk_chooseColor -title] (thoyts)

2008-04-16 (interface)[1938497] make stubs tables 'static const' (steffen)

2008-04-17 (bug fix)[1327482] canvas item <Enter> events (wangnick)

2008-05-23 (bug fix)[1967576] ttk::label height or width 0 panic (lawlor)

2008-06-10 (enhancement)[1986818] Use Xutf8LookupString when possible (english)

2008-06-12 (bug fix)[1991932] global grab segfault (steffen)

2008-06-12 (platform support) Solaris/amd64 gcc 64bit support (steffen)

2008-06-13 (new feature)[TIP 285] [tkwait] and [update] are now
[interp cancel]able (mistachkin)

2008-06-18 (bug fix) Aqua: missing focus on first map (steffen)

--- Released 8.6a1, June 25, 2008 --- See ChangeLog for details ---

2008-07-04 (bug fix)[2009213] crash in [ttk::scale] (polo,english)

2008-07-24 (bug fix)[2021443] consistent "wrong # args" messages (nijtmans)

2008-07-26 (bug fix)[2026405] portability of [winfo id] (uchida,thoyts)

2008-07-31 (bug fix) export Tk_PkgInitStubsCheck; fixes Tk embed on Windows

2008-08-01 (bug fix)[2009788,2028703] unmapped toplevel crashes (thoyts)

2008-08-05 (bug fix)[2010422] Tk header files revised to accommodate
incompatible changes in recent X.org releases of X11 headers. (jenglish)

2008-08-19 (bug fix) revised number format in -[xy]scrollcommand callbacks
and [xy]view methods (jenglish)
        *** POTENTIAL INCOMPATIBILITY ***

2008-08-19 (enhancement) removed obsolete XID management code (staplin)

Test suite modernization by Ania Pawelczyk.

--- Released 8.6a2, August 25, 2008 --- See ChangeLog for details ---


2008-08-25 (bug fix)[1936220] fix [tk_getOpenFile -multiple 1] on unix (helfter)

2008-08-25 (bug fix)[1023955] default menu cursor: no more Motif (helfter)

2008-08-28 (bug fix) correct TK_LIBS value to include Xft (porter)

2008-09-03 (support) Dropped support for pre-ANSI compilers. (porter)

2008-10-01 (new feature)[TIP 236] [$canvas moveto] (mckay,fellows)

2008-10-05 (bug fix)[2112563] format double values explicitly in double
format, avoiding sensitivity to locale setting. (fellows)
        *** POTENTIAL INCOMPATIBILITY ***




--- Released 8.6a3, October 10, 2008 --- See ChangeLog for details ---

2008-10-17 (enhancement) keyboard bindings for ttk::scale (thoyts)

2008-10-18 (bug fix)[1825353] Russian Windows tiny fonts problem (thoyts)

2008-10-18 (new feature)[TIP 321] [tk busy] (decoster,fellows)

2008-10-28 (bug fix)[1534835,2054562] use of more correct cursors (english)

2008-11-01 (new feature) New [ttk::spinbox] widget (thoyts)

2008-11-01 (new feature)[TIP 97] [$canvas imove] [$canvas rchars] (fellows)

2008-11-09 (bug fix)[2207435] [ttk::entry .t -textvar ::noexist::x] (english)

2008-11-11 (bug fix)[2312027] Tk_Create*ImageType() thread safety (nijtmans)

2008-11-11 (bug fix)[2264732] crash using nondefault visual (english)

2008-11-12 (bug fix)[1777362] permit [text] names containing "-" (thoyts)

2008-11-14 (bug fix)[2239034] limit [wm manage] to Frames (thoyts)

2008-11-22 (new feature)[TIP 119] -angle option for canvas text items (fellows)

2008-11-22 (bug fix)[1939129,1991930] combobox behind other windows (thoyts)

2008-11-22 (new feature) Demo ctext.tcl now demos angled text (fellows)

2008-11-23 (bug fix)[1389270] made [event generate <Focus*>] work (thoyts)

2008-11-28 (bug fix)[1813597,2218964] eliminate unnecessary units conversion
in screen distances, reducing precision loss (ferrieux)

2008-12-03 (enhancement) new "hover" state for proper Vista visuals (thoyts)

2008-12-05 (bug fix)[2107938] no negative font size in PS (fellows)

2008-12-05 (enhancement) new "vista" theme (thoyts)

2008-12-06 (new feature)[TIP 197] [$text -insertunfocussed] (edwards,fellows)

2008-12-06 (new feature)[TIP 337] handle non-error bg exceptions (porter)

2008-12-10 (new feature)[TIP 324] [tk fontchooser](thoyts,vetter,robert,steffen)

2008-12-12 (new feature) Demo fontchoose.tcl demos [tk fontchooser] (thoyts)

2008-12-18 (enhancement)[24442309] Updated German messages (haertel)

--- Released 8.6b1, December 19, 2008 --- See ChangeLog for details ---

2008-12-27 (bug fix)[2381555] horiz. scroll [$treeview identify] (english)

2008-12-28 (new feature)[TIP 244] PNG photo format support (fellows)

2008-12-28 (new feature)[TIP 171] <MouseWheel> event handling (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2008-12-31 (bug fix)[2003310] radio|check button indicator color (english)

2009-01-06 (bug fix)[2484771] messagebox: system to task modal (ferrieux,thoyts,mjanssen)

2009-01-06 (enhancement)[1539990] optimize photo building (jepler)

2009-01-07 (bug fix)[2473120] chooseDir syntax error (bron)

2009-01-07 (bug fix)[1847002] Win: prevent grab bypass (thoyts)

2009-01-11 (bug fix)[2496162] crash calling Tk_DeleteOptionTable() (english)

2009-01-11 (bug fix) crash on XCreateIC failure (staplin)

2009-01-14 (bug fix)[2507326] Restore aMSN compat (nijtmans)

2009-01-19 (new feature) CONFIG_INSTALL_DIR - where tkConfig.sh goes (cassoff)

2009-01-19 (platform support) better tools for BSD ports (cassoff)

2009-02-08 (bug fix)[2431428] panic computing layout on active widget (english)

2009-02-17 (platform support) MSVC and _WIN64 (hobbs)

2009-02-21 (bug fix)[2546087] [console] display of true UTF-8 \0 (thoyts)

2009-02-23 (bug fix)[1329198,456299,2507419] menu image display (mcdonald)

2009-02-23 (bug fix)[2513104] fix cursor hotspots (mcdonald)

2009-02-23 (bug fix)[2542828] Win: standard question_arrow cursor (danckaert)

2009-02-27 (bug fix)[2645457] crash in Tk_MakeWindowExist() (thoyts)

2009-03-09 (bug fix)[2548661] crash in GetFontFamilyName (riefenstahl)

2009-03-25 (bug fix)[2178820] stop zero-size allocs in ttk (fellows)

2009-03-25 (bug fix)[1871101] blurry large fonts on Vista (garvey,fellows)

2009-04-03 (bug fix)[1789819] stop panic on unexpected wm stack order (english)

2009-04-10 (bug fix)[2116837] std virtual events with Caps Lock (fellows)

2009-04-10 (platform) sse Darwin SUSv3 extensions if available (steffen)

2009-04-10 (bug fix) Motif checkbutton on X11 only (steffen)

2009-04-10 (bug fix) remove TkAqua Quit menu item on [console] (steffen)

2009-04-10 (bug fix) crash deleting char range from [text] (steffen)

2009-04-23 (bug fix)[2779910] updated Win chooseDir (hobbs)

2009-04-24 (bug fix) prevent delete of selected folder in Win dialog (hobbs)

2009-04-30 (bug fix)[2080533] panedwindow sash draw crash (fellows)

2009-04-30 (bug fix)[2504402] iconphoto on non-32-bit displays (mcdonald,thoyts)

2009-05-01 (bug fix)[2777019] anchor for text rotation (gavilán,fellows)

2009-05-03 (bug fix)[2785744] broken flag twiddling (baker,fellows)

2009-05-13 (bug fix)[2791352] XLFD parsing error (thoyts)

2009-05-14 (new feature) Vista theme support (thoyts)

2009-05-14 (bug fix)[1923684] confused checkbutton state (thoyts)

2009-05-17 (new feature)[1470246] notebook tab orientation control (english)

2009-05-21 (bug fix)[2794778] Win menu keyboard traversal (thoyts)

2009-06-02 (bug fix)[2799589] crash on delayed window activation (thoyts)

2009-06-23 (bug fix)[220935] canvas dash update problem (nijtmans)

2009-06-23 (platform) new subdir 'carbon' preserved for OSX 10.4-
use --enable-aqua=carbon option to unix/configure to enable (steffen)

2009-06-29 (new feature) source in `macosx` now built on Cocoa (steffen)
	*** POTENTIAL INCOMPATIBILITY ***

2009-06-30 (platform support) clang static analyzer macros (steffen)

2009-07-15 (bug fix)[2821962] photo image copy/paste (rib,fellows)

2009-07-21 (bug fix)[2356057] rotated underlined text (fellows)

2009-07-22 (bug fix)[2496114] focus in dead window crash (griffin,fellows)

2009-07-23 (bug fix)[2441988] report errors in selection handlers (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2009-08-01 (bug fix)[2830420] X iconphoto for big endian (misch,fellows)

2009-08-04 (bug fix) [text] word-wrap of non-breaking space (fellows)

2009-08-14 (bug fix) copy from unmapped toplevel crash (alaoui,steffen)

2009-08-19 (bug fix)[2475855] prevent grid & pack on same master (spjuth)

2009-08-24 (bug fix)[2821084] Cocoa: let WM_DELETE_WINDOW handler stop window
deletion (walzer,steffen)

2009-08-24 (bug fix) tk::MessageBox bindings for ttk::buttons (steiner,fellows)

2009-08-25 (bug fix)[1909931] [send] update for Fedora 8 (fellows)

2009-09-10 (bug fix) font allocation crash (berezhnoy,fellows)

2009-09-14 (bug fix)[873608] win tearoff menu, no submenu arrows (traum,hobbs)

2009-09-14 (bug fix)[873613] win tearoff menu repeat select (traum,hobbs)

2009-09-25 (bug fix) grayscale from images (vetter,fellows)

2009-10-07 (bug fix)[2088597] min scrollbar slider size (danckaert,fellows)

2009-10-07 (bug fix)[2787164] combobox/menubutton arrow size (thoyts)

2009-10-08 (bug fix)[2870648] file dialog cursor (danckaert,fellows)

2009-10-10 (feature)[1961455] underline, overstrike Xft fonts (caffin,fellows)

2009-10-20 (enhancement) Updates to Polish messages (pawlak)

2009-10-22 (bug fix)[2168768] file dialog -typevariable scope (danckaert)

2009-10-22 (bug fix)[1469210] [text] modified error (danckaert)

2009-10-22 (bug fix)[2883712] 64-bit Aqua progress bar (haffner)

2009-10-24 (bug fix)[1530276] X checkbutton -selectcolor (danckaert)

2009-10-25 (bug fix)[1854913] [.t delete] before -startindex (danckaert)

2009-10-25 (bug fix)[2809525] prevent X crash on overlong color name (goth)

2009-10-29 (bug fix)[1825353] Russian Windows tiny fonts problem (thoyts)

2009-11-01 (new feature) Ttk: [$w identify] now an ensemble (jenglish)

2009-11-19 (bug fix)[2899685] fix [imove] redraw logic (schekin,ferrieux)

2009-11-22 (bug fix)[2899949] crash on widget destroy (meier,thoyts)

2009-11-23 (bug fix)[2902573] Update Safe Tk to new Safe Base (kurpies)

2009-11-24 (bug fix)[2902814] fix [wm iconphoto] on LP64 systems (fellows)

2009-12-08 (bug fix)[2864685] Compiz menu item animation (gavilán,thoyts)



2009-12-11 (bug fix)[2912473] accept :: in DISPLAY name (fellows)

2009-12-15 (bug fix)[2492179] Tcl_ObjType "option" no longer registered (porter)
	*** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("option") ***

2009-12-20 (bug fix)[2917663] [send] accept SI:* on auth list (fellows)



2009-12-22 (bug fix)[2912356] [ttk::sizegrip] accommodate Compiz (english)

2009-12-25 (bug fix)[2977688,2546779] tab selection focus (english)

2009-12-27 (bug fix)[2879927] Win: cascade menu highlight (pawlak,thoyts)

2010-01-01 (bug fix)[1924761] stop [event generate] / XIM conflict (fellows)

2010-01-03 (bug fix)[2848897] ODS_NOACCEL flag support (kovalenko,thoyts)

2010-01-04 (bug fix)[2811266] <Return> binding in [tk_dialog] (thoyts)

2010-01-04 (bug fix)[2727476] font dialog appearance (thoyts)

2010-01-05 (bug fix)[220950] [$menu delete] bounds check (fellows)

2010-01-05 [2898255] unlimited multi-file select (pawlak,fellows,thoyts)

2010-01-06 (bug fix)[1163496] X: [wm transient] fix (bateman,fellows)

2010-01-09 (new feature)[TIP 360] Modernize X11 Menus (thoyts)

2010-01-18 (bug fix)[2932808] canvas update on state change (mcdonald,nijtmans)

2010-01-19 (new feature)[TIP 359] Extended Window Manager Hint Support (thoyts)

2010-01-19 (bug fix)[2931374] overflow in complex tag search (schmitz)

2010-02-17 (bug fix)[2952745] crash in menu deletion (english)

2010-02-20 (performance) treeview stop quadratic common case (english)

2010-03-02 (enhancement) -fvisibility-hidden build support (nijtmans)

2010-03-06 (bug fix)[2949774] cascade menu unpost (thoyts)

2010-03-11 (bug fix)[2968379] crash in peer text dump (fellows)

2010-03-17 (bug fix)[2971663] Cocoa entry <Up>, <Down> (goddard,fellows)

2010-03-28 (new feature) [$treeview tag names|add|remove] (english)

2010-04-09 (new feature)[2983824] [$image write -file] use extension of file
name to select image format (fellows)

2010-04-19 [2898255] unlimited multi-file select (pawlak,fellows,thoyts)

2010-05-31 (bug fix)[3006842] crash on empty bind scripts (english)

2010-06-15 (bug fix)[2585265] text <Delete>,<Backspace> note selection (fellows)

2010-06-15 (new package)[3016598] Tk now provides "tile 0.8.6" (english)

2010-07-19 (new feature) [$photo data -format GIF] (fellows)

2010-08-03 (bug fix) entry validation compat with Itcl scope (hobbs)

2010-08-11 (platform) Drop pre-aix 4.2 support, ldAix (hobbs)

2010-08-21 (patch)[3034251] genStubs steal features of ttkGenStubs (nijtmans)

2010-08-26 (bug fix)[1230554] configure, OSF-1 problems, windows manifest issues (hobbs)

2010-08-31 fixed manifest handling on windows (hobbs, kupries)

2010-09-02 (bug fix)[3057573] specify combobox text fg color (english)

2010-09-05 (enhancement)[3046742,3046750] Improved error dialog UI (fellows)

2010-09-08 (bug fix)[2829363] [$tv see] open item -> sched display (english)

2010-09-13 (platform) limit support to Win2000+ (nijtmans)

2010-10-01 (bug fix)[3078902] no hang operating on zero-size subimages (fellows)

2010-10-05 (bug fix)[3080953] corrupt multibyte char in %A subst (nijtmans)

2010-10-11 (bug fix)[3085489] crash in [tag add/remove] (english)

2010-10-11 (enhancement)[491789] Unicode command line support on Win (nijtmans)

2010-11-03 windows build with -UNICODE (nijtmans)

2010-11-05 Message catalogs reworked to use unicode copyright char (nijtmans)

2010-11-06 Message catalogs resorted, updates to NL (nijtmans)

2010-11-16 (platform) VS 2005 SP1 MSVC compiler (nijtmans)

2010-11-24 (bug fix)[3071836] crash in tk_getSaveFile (twylite)

2010-12-03 (enhancement)[3116490] mingw x-compile improvements (nijtmans)

2010-12-12 (platform) OpenBSD build improvements (cassoff)

2010-12-17 (platform) Revisions to support rpm 4.4.2 (cassoff)

2011-01-06 (bug fix)[2857300] Cocoa: correct text width rounding (walzer)

2011-01-06 (bug fix)[3086887] Cocoa: textured bg windows (walzer)

2011-01-13 (bug fix)[3154705] tk_messageBox close button disabled (skylera)

2011-01-22 (enhancement) add [ttk::entry validate] (schelte,english)

2011-01-24 (bug fix)[2907388] OSX: composite character entry crash (berg,walzer)

2011-03-02 (new doc) tk_mac.n: OS X specific functions (walzer)

2011-03-03 (bug fix)[3175610] incomplete line item refresh (ferrieux)

2011-03-10 (bug fix)[3205260] crash in [wm manage] (boudaillier, thoyts)

2011-03-16 (bug fix)[3181181] tearoff submenu fix (menez, thoyts)

2011-03-19 (bug fix)[3205464] [wm forget] loses window (boudaillier,thoyts)

2011-03-19 (bug fix)[3223850] ttk button state disabled during click (thoyts)







<
<
<
<
<




<
<
<
<


<
<










<
<
<


|



<
<









|
<
<

|
|
<
|
<
>







<
<
<
<


|

>
>
>
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

|



<
<
<
<
|


<
<
|

<
|
<

<
|
<

<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<




|



<
<


<
<








<
<




<
<


<
|
<
<
<
<
<









<
<








<
<






<
<
<
<
<
<
<
<


<
<


<
<
<




<
<
<
<
<
<
<




















|





|









|

|



|

|

|
>
>



|
<


>
>



<
<






<
<
<
<










<
<


<
|
<

<
|
<



<
<
<
<
<
<
<
<
<


<
<
<
<
<
<


|

|

<
|
<



<
<


<
<
<
<
<
<


<
|
<
<
<
<
<





<
<




<
<
<
<




<
<
<
<
<
<







6496
6497
6498
6499
6500
6501
6502





6503
6504
6505
6506




6507
6508


6509
6510
6511
6512
6513
6514
6515
6516
6517
6518



6519
6520
6521
6522
6523
6524


6525
6526
6527
6528
6529
6530
6531
6532
6533
6534


6535
6536
6537

6538

6539
6540
6541
6542
6543
6544
6545
6546




6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
















6558
6559
6560
6561
6562
6563
6564
6565




6566
6567
6568


6569
6570

6571

6572

6573

6574




6575
6576















6577
6578


6579
6580
6581
6582
6583
6584
6585
6586


6587
6588


6589
6590
6591
6592
6593
6594
6595
6596


6597
6598
6599
6600


6601
6602

6603





6604
6605
6606
6607
6608
6609
6610
6611
6612


6613
6614
6615
6616
6617
6618
6619
6620


6621
6622
6623
6624
6625
6626








6627
6628


6629
6630



6631
6632
6633
6634







6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687

6688
6689
6690
6691
6692
6693
6694


6695
6696
6697
6698
6699
6700




6701
6702
6703
6704
6705
6706
6707
6708
6709
6710


6711
6712

6713

6714

6715

6716
6717
6718









6719
6720






6721
6722
6723
6724
6725
6726

6727

6728
6729
6730


6731
6732






6733
6734

6735





6736
6737
6738
6739
6740


6741
6742
6743
6744




6745
6746
6747
6748






6749
6750
6751
6752
6753
6754
6755

2008-03-27 (platform support)[1921166] Solaris 64bit build fixes (steffen)

2008-03-27 (bug fix) restored [::safe::loadTk] (hobbs)

--- Released 8.5.2, March 28, 2008 --- See ChangeLog for details ---






2008-04-07 (bug fix)[1937135] Tk_ParseArgv() double free crash (hobbs)

2008-04-07 (bug fix)[1936238] wish -h mem explosion (bachmann,kenny)





2008-04-14 (bug fix)[1941740] [tk_chooseColor -title] (thoyts)



2008-04-17 (bug fix)[1327482] canvas item <Enter> events (wangnick)

2008-05-23 (bug fix)[1967576] ttk::label height or width 0 panic (lawlor)

2008-06-10 (enhancement)[1986818] Use Xutf8LookupString when possible (english)

2008-06-12 (bug fix)[1991932] global grab segfault (steffen)

2008-06-12 (platform support) Solaris/amd64 gcc 64bit support (steffen)




2008-06-18 (bug fix) Aqua: missing focus on first map (steffen)

--- Released 8.5.3, June 30, 2008 --- See ChangeLog for details ---

2008-07-04 (bug fix)[2009213] crash in [ttk::scale] (polo,english)



2008-07-26 (bug fix)[2026405] portability of [winfo id] (uchida,thoyts)

2008-07-31 (bug fix) export Tk_PkgInitStubsCheck; fixes Tk embed on Windows

2008-08-01 (bug fix)[2009788,2028703] unmapped toplevel crashes (thoyts)

2008-08-05 (bug fix)[2010422] Tk header files revised to accommodate
incompatible changes in recent X.org releases of X11 headers. (jenglish)

--- Released 8.5.4, August 15, 2008 --- See ChangeLog for details ---



2008-08-19 (behavior change) arguments passed to -[xy]scrollcommand
callbacks, and values returned by [xy]view methods are explicitly

formatted as doubles.  (english)

	*** POTENTIAL INCOMPATIBILITY ***

2008-08-25 (bug fix)[1936220] fix [tk_getOpenFile -multiple 1] on unix (helfter)

2008-08-25 (bug fix)[1023955] default menu cursor: no more Motif (helfter)

2008-08-28 (bug fix) correct TK_LIBS value to include Xft (porter)





2008-10-05 (bug fix)[2112563] format double values explicitly in double
format, avoiding sensitivity to locale setting. (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2008-10-10 (bug fix)[1894038] [package require] any Tk 8.5.* in any Tcl 8.5.*
(porter)

--- Released 8.5.5, October 15, 2008 --- See ChangeLog for details ---

2008-10-17 (enhancement) keyboard bindings for ttk::scale (thoyts)

















2008-11-12 (bug fix)[1777362] permit [text] names containing "-" (thoyts)

2008-11-15 (bug fix)[2239034] limit [wm manage] to Frames (thoyts)

2008-11-19 (bug fix)[2312027] Tk_Create*ImageType() thread safety (nijtmans)

2008-11-22 (bug fix)[1939129,1991930] combobox behind other windows (thoyts)





2008-12-22 (bug fix)[1813597,2218964] eliminate unnecessary units conversion
in screen distances, reducing precision loss (ferrieux)



2008-12-22 (bug fix)[2107938] no negative font size in PS (fellows)


2008-12-22 (bug fix)[2264732] crash using nondefault visual (english)



2008-12-22 (bug fix)[2207435] [ttk::entry .t -textvar ::noexist::x] (english)






--- Released 8.5.6, December 23, 2008 --- See ChangeLog for details ---
















2009-01-07 (bug fix)[1847002] Win: prevent grab bypass (thoyts)



2009-01-11 (bug fix) crash on XCreateIC failure (staplin)

2009-01-14 (bug fix)[2507326] Restore aMSN compat (nijtmans)

2009-01-19 (new feature) CONFIG_INSTALL_DIR - where tclConfig.sh goes (cassoff)

2009-01-19 (platform support) better tools for BSD ports (cassoff)



2009-02-17 (platform support) MSVC and _WIN64 (hobbs)



2009-02-23 (bug fix)[1329198,456299,2507419] menu image display (mcdonald)

2009-02-23 (bug fix)[2513104] fix cursor hotspots (mcdonald)

2009-02-23 (bug fix)[2542828] Win: standard question_arrow cursor (danckaert)

2009-02-27 (bug fix)[2645457] crash in Tk_MakeWindowExist() (thoyts)



2009-03-25 (bug fix)[2178820] stop zero-size allocs in ttk (fellows)

2009-03-25 (bug fix)[1871101] blurry large fonts on Vista (garvey,fellows)



2009-04-10 (bug fix)[2116837] std virtual events with Caps Lock (fellows)


--- Released 8.5.7, April 15, 2009 --- See ChangeLog for details ---






2009-04-23 (bug fix)[2779910] updated Win chooseDir (hobbs)

2009-04-24 (bug fix) prevent delete of selected folder in Win dialog (hobbs)

2009-04-30 (bug fix)[2080533] panedwindow sash draw crash (fellows)

2009-04-30 (bug fix)[2504402] iconphoto on non-32-bit displays (mcdonald,thoyts)



2009-05-03 (bug fix)[2785744] broken flag twiddling (baker,fellows)

2009-05-13 (bug fix)[2791352] XLFD parsing error (thoyts)

2009-05-14 (new feature) Vista theme support (thoyts)

2009-05-14 (bug fix)[1923684] confused checkbutton state (thoyts)



2009-05-21 (bug fix)[2794778] Win menu keyboard traversal (thoyts)

2009-06-02 (bug fix)[2799589] crash on delayed window activation (thoyts)

2009-06-23 (bug fix)[220935] canvas dash update problem (nijtmans)









2009-07-15 (bug fix)[2821962] photo image copy/paste (rib,fellows)



2009-07-22 (bug fix)[2496114] focus in dead window crash (griffin,fellows)




2009-08-01 (bug fix)[2830420] X iconphoto for big endian (misch,fellows)

2009-08-04 (bug fix) [text] word-wrap of non-breaking space (fellows)








2009-08-24 (bug fix) tk::MessageBox bindings for ttk::buttons (steiner,fellows)

2009-08-25 (bug fix)[1909931] [send] update for Fedora 8 (fellows)

2009-09-10 (bug fix) font allocation crash (berezhnoy,fellows)

2009-09-14 (bug fix)[873608] win tearoff menu, no submenu arrows (traum,hobbs)

2009-09-14 (bug fix)[873613] win tearoff menu repeat select (traum,hobbs)

2009-09-25 (bug fix) grayscale from images (vetter,fellows)

2009-10-07 (bug fix)[2088597] min scrollbar slider size (danckaert,fellows)

2009-10-07 (bug fix)[2787164] combobox/menubutton arrow size (thoyts)

2009-10-08 (bug fix)[2870648] file dialog cursor (danckaert,fellows)

2009-10-10 (feature)[1961455] underline, overstrike Xft fonts (caffin,fellows)

2009-10-15 (feature)[2794032] permit [load] into Tcl 8.6+ interps (porter)

2009-10-22 (bug fix)[2168768] file dialog -typevariable scope (danckaert)

2009-10-22 (bug fix)[1469210] [text] modified error (danckaert)

2009-10-24 (bug fix)[2883712] 64-bit Aqua progress bar (haffner)

2009-10-24 (bug fix)[1530276] X checkbutton -selectcolor (danckaert)

2009-10-25 (bug fix)[1854913] [.t delete] before -startindex (danckaert)

2009-10-25 (bug fix)[2809525] prevent X crash on overlong color name (goth)

2009-10-29 (bug fix)[1825353] Russian Windows tiny fonts problem (thoyts)

2009-11-03 (bug fix)[2891541] fix grab behaviour for main window (thoyts)

--- Released 8.5.8, November 16, 2009 --- See ChangeLog for details ---

2009-11-22 (bug fix)[2899949] crash on widget destroy (meier,thoyts)

2009-11-24 (bug fix)[2902814] fix [wm iconphoto] on LP64 systems (fellows)

2009-12-06 (bug fix)[2548661] crash in GetFontFamilyName (riefenstahl)

2009-12-06 (bug fix)[2864685] Compiz menu item animation (gavilán,thoyts)

2009-12-09 (bug fix)[2902573] Update Safe Tk to new Safe Base (kurpies)

2009-12-11 (bug fix)[2912473] accept :: in DISPLAY name (fellows)

2009-12-16 (bug fix)[2496162] crash calling Tk_DeleteOptionTable() (english)


2009-12-20 (bug fix)[2917663] [send] accept SI:* on auth list (fellows)

2009-12-22 (bug fix)[2919205] syntax bug in [tk_messageBox] (zaroo)

2009-12-22 (bug fix)[2912356] [ttk::sizegrip] accommodate Compiz (english)



2009-12-27 (bug fix)[2879927] Win: cascade menu highlight (pawlak,thoyts)

2010-01-01 (bug fix)[1924761] stop [event generate] / XIM conflict (fellows)

2010-01-03 (bug fix)[2848897] ODS_NOACCEL flag support (kovalenko,thoyts)





2010-01-05 (bug fix)[220950] [$menu delete] bounds check (fellows)

2010-01-05 [2898255] unlimited multi-file select (pawlak,fellows,thoyts)

2010-01-06 (bug fix)[1163496] X: [wm transient] fix (bateman,fellows)

2010-01-09 (new feature)[TIP 360] Modernize X11 Menus (thoyts)

2010-01-18 (bug fix)[2932808] canvas update on state change (mcdonald,nijtmans)



2010-01-19 (bug fix)[2931374] overflow in complex tag search (schmitz)


2010-01-19 (new feature)[TIP 359] Extended Window Manager Hint Support (thoyts)



2010-02-17 (bug fix)[2952745] crash in menu deletion (english)


2010-03-11 (bug fix)[2968379] crash in peer text dump (fellows)










2010-05-31 (bug fix)[3006842] crash on empty bind scripts (english)







2010-08-03 (bug fix) entry validation compat with Itcl scope (hobbs)

2010-08-12 (bug fix)[2585265] text <Delete>,<Backspace> note selection (fellows)

2010-08-25 (feature)[3053320] update Ttk to tile 0.8.6 feature set (hobbs)


--- Released 8.5.9, September 6, 2010 --- See ChangeLog for details ---


2010-09-02 (bug fix)[3057573] specify combobox text fg color (english)



2010-09-08 (bug fix)[2829363] [$tv see] open item -> sched display (english)







2010-10-11 (bug fix)[3085489] crash in [tag add/remove] (english)


2010-11-04 (enhancement) Updated German messages. (haertel,nijtmans)






2010-11-16 (platform) VS 2005 SP1 MSVC compiler (nijtmans)

2010-11-24 (bug fix)[3071836] crash in tk_getSaveFile (twylite)



2010-12-12 (platform) OpenBSD build improvements (cassoff)

2010-12-17 (platform) Revisions to support rpm 4.4.2 (cassoff)





2011-01-13 (bug fix)[3154705] tk_messageBox close button disabled (skylera)

2011-01-22 (enhancement) add [ttk::entry validate] (schelte,english)







2011-03-10 (bug fix)[3205260] crash in [wm manage] (boudaillier, thoyts)

2011-03-16 (bug fix)[3181181] tearoff submenu fix (menez, thoyts)

2011-03-19 (bug fix)[3205464] [wm forget] loses window (boudaillier,thoyts)

2011-03-19 (bug fix)[3223850] ttk button state disabled during click (thoyts)
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933


6934
6935
6936
6937
6938
6939

6940

6941
6942
6943
6944
6945
6946




6947
6948
6949
6950
6951
6952
6953
2011-04-04 (feature change)[2997657] No -container for [labelframe] (spjuth)

2011-04-04 (bug fix)[723765] [grid remove] lost -in value (saye,spjuth)

2011-04-22 (bug fix)[3291543] mem corrupt when [$canvas dchars] removes all
coords of a polygon (rogers,spjuth)

2011-04-29 (platform support) [wm forget|manage] on OS X (walzer)

2011-06-06 (bug fix)[2546087] [console] treatment of '\0' (porter)

2011-06-07 (bug fix)[2358545] Restore "08" in spinbox configured with -from
and -to (porter)



2011-06-10 (bug fix)[3315731] fix [$entry -invcmd] (porter)

2011-06-17 (bug fix)[3062331] crash in unset traces (macdonald,porter)

2011-08-03 (bug fix)[2891541] fix grab behaviour for main window (thoyts)


--- Released 8.6b2, August 8, 2011 --- See ChangeLog for details ---


2011-09-22 (bug fix)[3404541] -takefocus option (dzach,english)

2011-10-24 (new feature)[TIP 382] -confirmoverwrite on save dialog (porter)

2011-10-25 (bug fix)[3410609] AltGr keysyms on Swiss keyboard (tasser,kenny)





2011-11-17 (bug fix)[3437816] return code of [canvas lower] (hirner,ferrieux)

2011-12-22 (bug fix)[3235256] correct menu failure on Windows (mcdonald)

2012-01-19 (bug fix)[3021557] cursor freeze in elided text (vogel)








|






>
>
|



|

>
|
>






>
>
>
>







6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
2011-04-04 (feature change)[2997657] No -container for [labelframe] (spjuth)

2011-04-04 (bug fix)[723765] [grid remove] lost -in value (saye,spjuth)

2011-04-22 (bug fix)[3291543] mem corrupt when [$canvas dchars] removes all
coords of a polygon (rogers,spjuth)

2011-04-30 (bug fix)[2949774] cascade menu unpost (thoyts)

2011-06-06 (bug fix)[2546087] [console] treatment of '\0' (porter)

2011-06-07 (bug fix)[2358545] Restore "08" in spinbox configured with -from
and -to (porter)

2011-06-07 (bug fix)[2484771] modal dialog settings (hoff, thoyts)

2011-06-10 (bug fix)[3175610] incomplete line item refresh (ferrieux)

2011-06-17 (bug fix)[3062331] crash in unset traces (macdonald,porter)

--- Released 8.5.10, June 23, 2011 --- See ChangeLog for details ---

2011-06-29 (bug fix)[3341056] new crash in unset traces (militaru,porter)

2011-08-03 (bug fix)[3314770] restore file dialog resizeability (nijtmans)

2011-09-22 (bug fix)[3404541] -takefocus option (dzach,english)

2011-10-24 (new feature)[TIP 382] -confirmoverwrite on save dialog (porter)

2011-10-25 (bug fix)[3410609] AltGr keysyms on Swiss keyboard (tasser,kenny)

2011-11-02 (performance)[3431491] improved "pixels" shimmer logic (fellows)

--- Released 8.5.11, November 4, 2011 --- See ChangeLog for details ---

2011-11-17 (bug fix)[3437816] return code of [canvas lower] (hirner,ferrieux)

2011-12-22 (bug fix)[3235256] correct menu failure on Windows (mcdonald)

2012-01-19 (bug fix)[3021557] cursor freeze in elided text (vogel)

6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000

7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058


7059
7060
7061
7062
7063
7064


7065
7066


7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214

2012-06-11 (bug fix)[3294450] ttk text element clipping (oehlmann,fellows)

2012-07-02 (bug fix) Make sure all index tables are static (kirkham,english)

2012-07-23 (bug fix)[3546073] DisplayString() -> DefaultDisplay() (english)

2012-08-11 (bug fix)[3554273] text elide and tags (vogel)

2012-08-15 (enhancement)[3555324] Win:Ctrl-A now means Select-All (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***

2012-08-22 (new feature)[TIP 403] Use Web color definitions (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***


2012-08-23 (enhancement)[3555644] better use of virtual events (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***

2012-08-24 (bug fix)[3558535] file dialog filtering (fellows)

2012-08-25 (bug fix)[3554026,3561016] crash with tearoff menus (gavilán)

2012-09-11 (bug fix)[3566594] stop clip region leaks (fellows)

2012-09-15 (bug fix)[3567778] stop hang in wrapped label (porter)

2012-09-17 (bug fix)[3567786] stop segfault in [wm forget] (porter)

Many revisions to better support a Cygwin environment (nijtmans)

--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---

2012-10-02 (bug fix)[3572016] menu enable after modal dialog (berg,walzer)

2012-10-08 Remove Carbon support

2012-10-24 (bug fix)[3574893] crash in [wm forget] (porter)

2012-11-07 (bug fix)[3574708] crash in focus handling (fellows)

2012-11-14 (bug fix)[3500545] fix [tk_getOpenFile -multiple] (bruederlin)

2012-12-04 (bug fix)[3588824] Support weird image names in [text] (vogel)

2012-12-06 (bug fix)[3592736] stop pink greys from buggy mingw builds (fellows)

--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---

2013-01-04 (bug fix) Tk_InitStubs("8.6") rejected in 8.60 interp (nijtmans)

2013-01-10 (bug fix)[3600251] Mac <Control-v> binding (kjnash,nijtmans)

2013-01-10 (bug fix)[3600260] <<SelectNextPara>> binding (kjnash,nijtmans)

2013-01-13 (bug fix)[3600290] restore $tk_strictMotif respect (kjnash,nijtmans)

2013-01-22 (bug fix)[3601782] Tcl_InitStubs failure message (nijtmans)

2013-01-31 (bug fix)[3599928] use XKeycodeToKeysym on old systems (cassoff)

2013-02-04 (bug fix)[3603077] treeview update on tag add/remove (english)

2013-02-28 (bug fix)[3599312] First Alt key event is lost (mcdonald)

2013-03-11 (bug fix)[3607326] Crash [listbox .l -listvariable $array] (porter)

2013-03-13 (enhancement) better build support for Debian arch (shadura)

2013-03-27 (bug fix)[3608074] button, listbox, menu <<Invoke>> (nijtmans)

2013-04-01 (bug fix)[3607830] Xkb runtime checks (griffin)



2013-05-19 (platform support) FreeBSD updates (cerutti)

2013-06-05 (bug fix)[3613759] [ttk::entry .e; .e xview end] (nijtmans)

2013-06-05 (bug fix)[2100430] [ttk::entry .e; .e xview insert] (nijtmans)



2013-06-28 (bug fix)[2501278] reverse ttk::scale key bindings {mcdonald)



2013-07-02 (bug fix)[32afa6] corrected dirent64 check (griffin)

2013-08-14 (bug fix)[069c9e] "option" value refcount crash (tim,nijtmans)

2013-08-15 (bug fix)[c597acd] [$pb step] work with traces (english)

2013-08-25 (bug fix)[3016181] Cocoa: [destroy $scrollbar] => crash (goddard)

--- Released 8.6.1, September 19, 2013 --- https://core.tcl-lang.org/tk/ for details

2013-10-27 (bug fix) OSX drawing lags (deily,steffen,walzer)

2013-10-28 (bug fix)[3603436] png wrong component indices (nijtmans)

2013-10-31 (bug fix) C++ friendly stubs struct declarations (nijtmans)

2013-10-31 (bug fix)[c0cc9fd] PNG parser accept uppercase -format (nijtmans)

2013-10-31 (bug fix) double free of a TkFont (nijtmans)

2013-11-03 (bug fix)[1632447] support PPM maxval up to 65535 (fellows)

2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans)

2013-11-11 (bug fix)[f214b8a] multi-interp font teardown double free (porter)

2013-11-11 (bug fix)[0aa5e85] option file \n syntax support (nijtmans)

2013-11-20 (platforms) Support for Windows 8.1 (nijtmans)

2014-01-23 (bug fix)[3606644] X: correct fontconfig dependence (venable)

2014-01-23 (bug fix) FreeBSD build fixes (cerutti)

2014-02-06 (bug fix)[3279221] [menu] event race (danckaert,kupries)

2014-02-07 (bug fix)[6867cc1] creative writing in [tk fontchooser] (nijtmans)

2014-02-11 (bug fix)[52ca3e7] XkbOpenDisplay macro correction (nijtmans)

2014-03-16 (bug fix) Xcode 5.1 update; Retina displays (walzer)

2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans)

2014-04-01 (bug fix)[5bcb502] @TK_LIBS@ in pkgconfig (badshah400,nijtmans)

2014-05-27 (bug fix)[a80f5d7] autoscroll initiation (crogers,english)

2014-07-07 (bug fix) OSX alpha channel rendering (culler,walzer)

2014-07-08 (workaround)[4955f5d] Ocaml trouble with tailcall splice (nijtmans)

2014-07-24 (bug fix) OSX [text] image display & scrolling (culler,walzer)

2014-08-01 (bug fix) OSX font config crash (rob@bitkeeper)

--- Released 8.6.2, August 27, 2014 --- https://core.tcl-lang.org/tk/ for details

2014-08-27 (bug) Cocoa: Crash after [$button destroy] (walzer)

2014-09-23 (bug) Cocoa: button and scroll display fixes (walzer)

2014-09-24 (bug) Cocoa: improved drawing performance (walzer)

2014-10-11 (bug)[9e487e] Phony button clicks from browsers to plugin (nijtmans)

2014-10-11 (bug)[810c43] [text] elide changes advance epoch (vogel)

2014-10-14 (bug)[fb35eb] fix PNG transparency appearance (walton,culler)

2014-10-18 (feature)[TIP 432] Win: updated file dialogs (nadkarni)

2014-10-26 Support for Windows 10 (nijtmans)

2014-10-28 (bug) OSX: Improved ttk notebook tab metrics for Yosemite (walzer)

2014-10-30 (bug)[3417012] [scale -digits $bigValue] segfault (vogel)

2014-11-07 (bug)[3529885] [scale] handling of negative resolution (vogel)

--- Released 8.6.3, November 12, 2014 --- https://core.tcl-lang.org/tk/ for details

2014-11-14 (bug)[d43a10] shimmer-related crash in [tk_getOpenFile] (nadkarni)

2014-11-23 (bug)[1c0d6e] Win build trouble with SIGDN (keene)

2014-12-03 (bug)[4a0451] [tk_getOpenFile] result (nadkarni)

2014-12-13 fix header files installation on OS X (houben)

2015-01-02 (bug) Stop bit loss in [winfo id] on 64-bit Cocoa (porter)

2015-02-06 (bug) several fixes to elided context in [text] (vogel)

2015-02-06 (new feature)[TIP 433] %M binding substitution (mistachkin)
        *** POTENTIAL INCOMPATIBILITY ***

2015-02-22 (bug)[ab6dab] corrupt dashed lines in postscript (porter)

Tk Cocoa 2.0: App Store enabled (walzer,culler,desmera,owen,nyberg,reincke)
        *** POTENTIAL INCOMPATIBILITY ***

--- Released 8.6.4, March 12, 2015 --- https://core.tcl-lang.org/tk/ for details

2015-03-10 (bug) Cocoa: premature image free crash (walzer)

2015-03-15 (bug) Cocoa: wish launches in front. [focus -force] works (culler)

2015-04-09 (bug)[e4ed00] [$text index "1.0 display wordstart"] crash (vogel)

2015-04-09 (bug)[562118] Unicode support of "wordstart" modifier (vogel)

2015-05-05 (bug)[06c3fc] PNG alpha error corrupted output file (gauthier,porter)

2015-05-20 (bug)[dece63] various mem corruptions in images (mic42,porter)

2015-05-24 (bug)[53f8fc] panedwindow geometry management (vogel)

2015-05-26 (bug)[1641721] tk_getOpenFile symlink display doubled (nijtmans)

2015-06-01 (bug)[d7bad5][2368195][3592454][1714535][1292219][3592454]
                panedwindow fixes (vogel)

2015-06-25 (bug)[805cff] Tk_ConfigureWidget() segfault (aspect,nijtmans)

2015-07-13 (bug)[3f179a] Text widget crash with elided text (vogel)

2015-07-16 (bug)[2886436] Stop [$text delete] acting before start index (vogel)

2015-07-28 (bug)[1236306] TraverseToMenu error bound to toplevel destroy (vogel)

2015-08-20 (bug)[00189c] MSVC 14: semi-static UCRT support (dower,nijtmans)

2015-09-13 (bug)[cc0ba3] PNG read buffer overflow (maxjarek,porter)

2015-09-29 (bug)[1501749] Crash embedded window delete bound to <Map> (vogel)

2015-10-04 (license) Replace icons that lacked clear free license (cowals)

2015-10-06 (bug)[46c83f] Win: tk_getOpenFile -initialdir (koend,nadkarni)

2015-10-08 (new feature)[TIP 437] New panedwindow options (vogel)

2015-10-09 (bug)[1669632] [text] autoseparator placement (nash,vogel)

2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel)

2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel)







|

|
<

<
<
>

|
<





|

<
|
<

<
|
<



<
<


|

<
<
<
<
<
<
|

<
|
<

<
|
<

















>
>






>
>


>
>


|

|

|

|







<
<






<
<










<
<












<
<




|













|







<
|
<

<
|
<
<
<
<
<






|

<
<

|

|











<
<





|











<
<


<
<
<
<







6838
6839
6840
6841
6842
6843
6844
6845
6846
6847

6848


6849
6850
6851

6852
6853
6854
6855
6856
6857
6858

6859

6860

6861

6862
6863
6864


6865
6866
6867
6868






6869
6870

6871

6872

6873

6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920


6921
6922
6923
6924
6925
6926


6927
6928
6929
6930
6931
6932
6933
6934
6935
6936


6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948


6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974

6975

6976

6977





6978
6979
6980
6981
6982
6983
6984
6985


6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000


7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017


7018
7019




7020
7021
7022
7023
7024
7025
7026

2012-06-11 (bug fix)[3294450] ttk text element clipping (oehlmann,fellows)

2012-07-02 (bug fix) Make sure all index tables are static (kirkham,english)

2012-07-23 (bug fix)[3546073] DisplayString() -> DefaultDisplay() (english)

Many revisions to better support a Cygwin environment (nijtmans)

--- Released 8.5.12, July 27, 2012 --- See ChangeLog for details ---




2012-07-31 (update)[3551802] XKeycodeToKeysym deprecation (fellows)

2012-08-11 (bug fix)[3554273] text elide and tags (vogel)


2012-08-24 (bug fix)[3558535] file dialog filtering (fellows)

2012-08-25 (bug fix)[3554026,3561016] crash with tearoff menus (gavilán)

2012-08-28 (bug fix)[3562426] Context menu goes off screen (nijtmans)


2012-09-11 (bug fix)[3566594] stop clip region leaks (fellows)



2012-09-28 New colors: aqua crimson fuchsia indigo lime olive silver teal


2012-10-02 (bug fix)[3572016] menu enable after modal dialog (berg,walzer)



2012-10-24 (bug fix)[3574893] crash in [wm forget] (porter)

2012-11-07 (bug fix)[3574708] TkSetFocusWin() crash on XP (mcdonald)







--- Released 8.5.13, November 12, 2012 --- See ChangeLog for details ---


2012-12-04 (bug fix)[3588824] text index of images with weird names (gavilan)



2012-12-06 (bug fix) avoid buggy syscall to parse hex color values (fellows)


2013-01-22 (bug fix)[3601782] Tcl_InitStubs failure message (nijtmans)

2013-01-31 (bug fix)[3599928] use XKeycodeToKeysym on old systems (cassoff)

2013-02-04 (bug fix)[3603077] treeview update on tag add/remove (english)

2013-02-28 (bug fix)[3599312] First Alt key event is lost (mcdonald)

2013-03-11 (bug fix)[3607326] Crash [listbox .l -listvariable $array] (porter)

2013-03-13 (enhancement) better build support for Debian arch (shadura)

2013-03-27 (bug fix)[3608074] button, listbox, menu <<Invoke>> (nijtmans)

2013-04-01 (bug fix)[3607830] Xkb runtime checks (griffin)

--- Released 8.5.14, April 3, 2013 --- See ChangeLog for details ---

2013-05-19 (platform support) FreeBSD updates (cerutti)

2013-06-05 (bug fix)[3613759] [ttk::entry .e; .e xview end] (nijtmans)

2013-06-05 (bug fix)[2100430] [ttk::entry .e; .e xview insert] (nijtmans)

2013-06-07 (bug fix)[1913750,3500545,3416492,3095112] file dialogs (nijtmans)

2013-06-28 (bug fix)[2501278] reverse ttk::scale key bindings {mcdonald)

2013-06-28 (bug fix)[3588364] crash loading Tk 64-bit windows (nijtmans)

2013-07-02 (bug fix)[32afa6] corrected dirent64 check (griffin)

2013-08-25 (bug fix)[3016181] Cocoa: [destroy $scrollbar] => crash (goddard)

2013-08-26 (bug fix)[c597acd] [$pb step] work with traces (english)

2013-09-15 (bug fix)[8eb5671] macosx Tk compile errors w/clang (deily)

--- Released 8.5.15, September 18, 2013 --- http://core.tcl.tk/tk/ for details

2013-10-27 (bug fix) OSX drawing lags (deily,steffen,walzer)

2013-10-28 (bug fix)[3603436] png wrong component indices (nijtmans)

2013-10-31 (bug fix) C++ friendly stubs struct declarations (nijtmans)



2013-10-31 (bug fix) double free of a TkFont (nijtmans)

2013-11-03 (bug fix)[1632447] support PPM maxval up to 65535 (fellows)

2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans)



2013-11-11 (bug fix)[0aa5e85] option file \n syntax support (nijtmans)

2013-11-20 (platforms) Support for Windows 8.1 (nijtmans)

2014-01-23 (bug fix)[3606644] X: correct fontconfig dependence (venable)

2014-01-23 (bug fix) FreeBSD build fixes (cerutti)

2014-02-06 (bug fix)[3279221] [menu] event race (danckaert,kupries)



2014-02-11 (bug fix)[52ca3e7] XkbOpenDisplay macro correction (nijtmans)

2014-03-16 (bug fix) Xcode 5.1 update; Retina displays (walzer)

2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans)

2014-04-01 (bug fix)[5bcb502] @TK_LIBS@ in pkgconfig (badshah400,nijtmans)

2014-05-27 (bug fix)[a80f5d7] autoscroll initiation (crogers,english)

2014-07-07 (bug fix) OSX alpha channel rendering (culler,walzer)



2014-07-24 (bug fix) OSX [text] image display & scrolling (culler,walzer)

2014-08-01 (bug fix) OSX font config crash (rob@bitkeeper)

--- Released 8.5.16, August 25, 2014 --- http://core.tcl.tk/tk/ for details

2014-08-27 (bug) Cocoa: Crash after [$button destroy] (walzer)

2014-09-23 (bug) Cocoa: button and scroll display fixes (walzer)

2014-09-24 (bug) Cocoa: improved drawing performance (walzer)

2014-10-11 (bug)[9e487e] Phony button clicks from browsers to plugin (nijtmans)

2014-10-11 (bug)[810c43] [text] elide changes advance epoch (vogel)

2014-10-14 (bug)[fb35eb] fix PNG transparency appearance (walton,culler)

--- Released 8.5.17, October 25, 2014 --- http://core.tcl.tk/tk/ for details

2014-10-26 Support for Windows 10 (nijtmans)

2014-10-28 (bug) OSX: Improved ttk notebook tab metrics for Yosemite (walzer)

2014-10-30 (bug)[3417012] [scale -digits $bigValue] segfault (vogel)


2014-11-06 (bug)[9d72dc] memleak in Cocoa buttons (revol)



2014-11-07 (bug)[3529885] [scale] handling of negative resolution (vogel)






2015-01-02 (bug) Stop bit loss in [winfo id] on 64-bit Cocoa (porter)

2015-02-06 (bug) several fixes to elided context in [text] (vogel)

2015-02-06 (new feature)[TIP 433] %M binding substitution (mistachkin)
	*** POTENTIAL INCOMPATIBILITY ***



Tk Cocoa 2.0: App Store enabled (walzer,culler,desmera,owen,nyberg,reincke)
	*** POTENTIAL INCOMPATIBILITY ***

--- Released 8.5.18, March 6, 2015 --- http://core.tcl.tk/tk/ for details

2015-03-10 (bug) Cocoa: premature image free crash (walzer)

2015-03-15 (bug) Cocoa: wish launches in front. [focus -force] works (culler)

2015-04-09 (bug)[e4ed00] [$text index "1.0 display wordstart"] crash (vogel)

2015-04-09 (bug)[562118] Unicode support of "wordstart" modifier (vogel)

2015-05-05 (bug)[06c3fc] PNG alpha error corrupted output file (gauthier,porter)



2015-05-24 (bug)[53f8fc] panedwindow geometry management (vogel)

2015-05-26 (bug)[1641721] tk_getOpenFile symlink display doubled (nijtmans)

2015-06-01 (bug)[d7bad5][2368195][3592454][1714535][1292219][3592454]
		panedwindow fixes (vogel)

2015-06-25 (bug)[805cff] Tk_ConfigureWidget() segfault (aspect,nijtmans)

2015-07-13 (bug)[3f179a] Text widget crash with elided text (vogel)

2015-07-16 (bug)[2886436] Stop [$text delete] acting before start index (vogel)

2015-07-28 (bug)[1236306] TraverseToMenu error bound to toplevel destroy (vogel)

2015-08-20 (bug)[00189c] MSVC 14: semi-static UCRT support (dower,nijtmans)



2015-09-29 (bug)[1501749] Crash embedded window delete bound to <Map> (vogel)





2015-10-08 (new feature)[TIP 437] New panedwindow options (vogel)

2015-10-09 (bug)[1669632] [text] autoseparator placement (nash,vogel)

2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel)

2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel)
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760

2016-01-09 (bug)[1927212] Mousewheel/scrollbar bindings (vogel)

2016-01-11 (bug)[63c354] Cocoa message boxes (culler)

2016-01-12 (bug)[2049429] get more $text options from database (vogel)

2016-01-22 (TIP 441) New option [listbox ... -justify] (vogel)

2016-01-25 (bug) OBOE in ttk::notebook options parsing (bromley,english)

2016-02-08 (enhance) [option readile] expects utf-8 file (oehlmann,nijtmans)

2016-02-08 (bug) crash in [$text delete] (griffin,vogel)

Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)

--- Released 8.6.5, February 29, 2016 --- https://core.tcl-lang.org/tk/ for details

2016-03-07 (bug)[3137232] spinbox teardown hygiene (vogel)

2016-03-07 (bug)[2981253] spinbox rapid button action (vogel)

2016-03-07 (bug)[2262543] scale initialization callbacks (vogel)

2016-03-07 (bug)[e9112e] incomplete [wm forget] (vogel)

2016-03-11 (bug)[d95e5d] <Map> from hidden panes (vogel)

2016-03-20 (TIP 443) More configuration options for text tags (vogel)

2016-03-20 (bug)[487861] menu: cascade/accelerator appearance (vogel)

2016-03-27 (bug)[1192095] active index from toplevel menus (vogel)

2016-03-27 (bug)[18c08d] revised final newline behavior in [text] (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2016-04-29 (bug)[fd3a4d] <<Modified>> delivery to text peers (vogel)

2016-05-03 (bug)[b36218,011706] event reentrancy / widget destruction (vogel)

2016-05-12 (bug)[64261b] mouse events after double click (nadmarki,nijtmans)

2016-05-18 (bug)[545f10] Xft color font speed (bonfield,davies,girffin,vogel)

2016-05-25 (bug)[109865] event reentrancy / widget destruction (vogel)

2016-05-30 (TIP 446)[1273358] [$text edit (canundo|canredo)] (vogel)

2016-05-30 (bug)[79549a] crash in mouse pointer warping (vogel)

2016-06-22 (bug)[787adc] Modernize Tk_Init() (porter)

2016-07-06 (bug) Aqua: excess lable padding (lanam,walzer)

2016-07-08 (bug) Aqua: bitmap distortion (culler,walzer)

2016-07-15 (bug) Aqua/Retina: fix alpha rendering of images (culler,walzer)

2016-07-17 (bug)[c84f66] Aqua: crash: overflow in geometry calc (culler,walzer)

2016-07-21 (bug)[450bb0] Aqua: memory corruption from [tk busy] (porter)

--- Released 8.6.6, July 27, 2016 --- https://core.tcl-lang.org/tk/ for details

2016-08-23 (bug)[a2abc4] Wrong warp cursor position on 2nd display (vogel)

2016-08-29 (bug)[fa3229] menu-38.1 (calvo,vogel)

2016-08-29 (bug)[2cf3d6] button-5.24 (vogel)

2016-09-04 (bug)[1534455,2945130] Key release events get _L vs _R right. (vogel)

2016-09-10 (bug)[8c4216] listbox-4.1 (vogel)

2016-09-10 (bug)[eb2681] listbox-13.1 (vogel)

2016-09-21 (bug)[3126428] ttk::button react to image change (thoyts)

2016-10-09 (bug)[1082213] wrapped text don't start lines with whitespace (vogel)

2016-10-12 (bug)[3217462] tri-state button on non-native theme (vogel)

2016-10-30 (bug)[3588460] Fix file dialog -typevariable (vogel)

2016-11-01 (bug)[e36963] event generate .e <diaeresis> (matthias,vogel)

2016-11-05 (bug)[6aea69] grid-23 (danckaert,vogel)

2016-11-18 (bug)[f60c54] combobox-3 (panza,vogel)

2017-01-03 (bug)[f32502] crash drawing many dashed objects (reithofer,werner)

2017-01-05 (bug)[dac92f] text-2.[89] (vogel)

2017-01-07 (bug)[3df559] OSX: Negative bbox width (vogel)

2017-01-07 (bug)[28a453] OSX: text widget index OBOE (vogel)

2017-01-07 (bug)[c12af7] OSX: text-21.1 (vogel)

2017-01-08 (bug)[7a838c] X11 ring buffer overflow (werner)

2017-01-11 (bug)[d4fb4e] imgPhoto-4.75 (nijtmans)

2017-01-18 (bug)[fab5fe] OSX: repair textDisp failures (vogel)

2017-01-23 (bug)[89a638] OSX: textDisp-15.8 (vogel)

2017-01-25 (bug)[1403ea] Limits on text line size on Windows (spjuth)

2017-02-05 (bug)[ae32eb] textDisp fails in text custom config (vogel)

2017-02-05 (bug)[7d967c] crash after IME restart (lanam,nijtmans)

2017-02-22 (bug)[c492c9] disabled combobox arrow appearance (danckaert)

2017-03-06 (bug)[6b3644] Fix -alpha for 16-bit color PNG (LemonMan)

2017-03-11 (bug)[775273] artifacts on Ubuntu 16.10+ (nemethi)

2017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel)

2017-03-29 (bug)[28a3c3] test BTree memleaks plugged (anonymous)

2017-04-06 (bug)[db8c54] Stop freed mem access in warp pointer callback (porter)

2017-04-07 (bugs) Fix calculation of ttk::notebook tab widths (vogel)

2017-04-07 (bug)[291296] notebook tab management (decoster)

2017-04-08 (bug)[f0188a] Win reject invalid hex color codes (bachmann)

2017-04-10 (bug)[3f323b] variable struct size on XCode 8.3.1 (auriocus)

2017-04-20 (bug)[061bf9] OSX scrollbar draw position (reincke,walzer,joye)

2017-05-01 (bug) restore -initialfile for OSX file dialogs (reincke,gollwitzer)

2017-05-06 (bug) OSX file dialog type filters (walzer)

2017-05-10 (bug)[a5ba1c] race condition on Win clipboard cleanup (donchenko)

2017-05-18 (bug)[2433781] center image on button (cramer)

2017-05-19 (bug)[434d29] type mismatch with recent Xft (nijtmans,werner)

2017-06-02 (bug)[bc43fd] paneconfigure get pane heights right (vogel)

2017-06-21 (bug)[adc028] menu avoid unreleasable global grab (nash)

2017-06-30 (bug)[92e028,c5eb90] User switch forced theme reset (lanam)

2017-06-30 (bug)[62c5b7] segfault in [text] replace (werner)

2017-07-03 (bug)[8afc6c] OSX crash in save/open dialogs (simpson,walzer)

2017-08-02 (bug)[b601ce] Resource exhaustion processing corrupt GIF (nash)

2017-08-03 (bug)[9eab54] Fix -initialdir for OSX file dialogs (gollwitzer)

2017-08-08 (bug)[28d0b8] Follow ICCCM advice on X selection protocol (donchenko)

2017-08-08 (bug)[4966ca] Scidb race in notebook tab selection (cramer)

--- Released 8.6.7, August 9, 2017 --- https://core.tcl-lang.org/tk/ for details

Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7,
plus the following, which focuses on the high-level feature changes
in this changeset (new minor version) rather than bug fixes:

2016-03-07 (feature)[841280] spinbox autoswap -to/-from to get ordering (vogel)

2016-03-27 (feature)[38dc27] Support <Button-6> & <Button-7> (nijtmans)

2016-08-29 (TIP 449) [text] undo/redo return character range (vogel)

2016-11-02 (feature) Removed undocumented command [tk_getFileType] (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2017-02-05 (bug)[c0dbdd] Compatibility fonts shadowed system fonts (vogel)

2017-03-21 (TIP 442) display text in a progressbar (zaumseil)

2017-04-13 \u escaped content in msg files converted to true utf-8 (nijtmans)

2017-08-28 (TIP 166) Extended color notation for alpha channel (bachmann)

--- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tk/ for details

2017-08-24 (bug)[f1a3ca] Memory leak in [text] B-tree (edhume3)

2017-08-24 (bug)[ee40fd] Report [console] init errors (the)

2017-08-24 (bug)[3295446] Improve history visibility in [console] (goth)

2017-08-24 (bug) canvas closed polylines fully honor -joinstyle (vogel)

2017-08-24 (bug)[cc42cc] out of mem crash in tests imgPhoto-18.* (vogel)

2017-09-16 (bug)[3406785] fix coords rounding when drawing canvas items (vogel)

2017-09-24 (bug)[8277e1] linux fontchooser sync with available fonts (vogel)

2017-09-24 (bug)[5239fd] Segfault copying a photo image to itself (bachmann)

2017-09-24 (bug)[514ff6] canvas rotated text overlap detection (vogel)

2017-09-24 (bug)[1e0db2] canvas rchars artifacts (bruchie,vogel)

2017-10-07 (bug)[d9fdfa] display of Long non-wrapped lines in text (cramer)

2017-10-07 (bug)[dd9667] text anchor not set (vogel)

2017-10-11 (bugs) memleaks and other changes for macOS 10.13 support (culler)

2017-10-11 (bug)[111de2] macOS colorspace improvement (walzer,culler)

2017-10-13 (bug) macOS scrolling issues (culler)

2017-10-15 (bug) clipping regions in scrolling and drawing on macOS (culler)

2017-10-15 (bug) macOS redraw artifacts (culler)

2017-10-22 (bug)[bb6b40] ::tk::AmpMenuArgs and 'entryconf' (vogel)

2017-10-22 (bug)[55b95f] Crash [scale] with a bignum value (vogel)

2017-10-28 (bug)[ce62c8] text-37.1 fails (vogel)

2017-11-03 (bug)[0ef1c5] OS X - tests menu-22.[345] hang (vogel)

2017-11-04 (bug)[c8c52b] repair OBOE in menu.test on macOS (vogel)

2017-11-11 (feature) Implement [wm_iconphoto] on macOS (walzer)

2017-11-11 (bug) display of embedded toplevels (culler)

2017-11-19 (bug)[73ba07] Correct property type for MULTIPLE conversion (dpb)

2017-11-20 (bug) Memory leak in tkImgPhoto.c. (werner)

2017-11-21 (bug) Defeat zombie toplevels (culler)

2017-11-25 (bug) macOS resposive menu bar for command line apps (culler)

2017-11-25 (bug)[1c659e] support png from mac screenshots (vogel)

2017-11-25 (bug)[de4af1] macOS file selector "all types" setting (culler)

2017-11-26 (bug) [wm withdraw] on Window and Dock menus (walzer)

2017-11-27 (feature) Drop support for macOS 10.5 (culler)

2017-11-30 (bug)[164c1b] Fixes [raise] on macOS (culler)

2017-11-30 (bug)[13d63d] macOS support of menu -postcommand (culler)

2017-12-05 (bug) enable custom icon display on macOS (walzer)

2017-12-05 (bug)[1088805,0feb63] macOS bind failures (culler)

2017-12-05 (bug)[3382424] Suppress noisy messages on macOS (culler)

2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni)

2017-12-18 (bug)[b77626] Make [tk busy -cursor] silent no-op on macOS (vogel)

--- Released 8.6.8, December 22, 2017 --- https://core.tcl-lang.org/tk/ for details

2017-12-31 (bug)[aa7679] crash using window after master destroyed (vogel)

2017-12-31 (bug)[6525e1] encoding leak in tkMacOSXProcessFiles (werner)

2018-01-07 (bug)[925262] New option -state for ttk::scale (vogel)

2018-01-07 (bug)[fa8de7] Crash [ttk::checkbutton .x -variable {}] (werner)

2018-01-16 (bug)[382712] Crash in [event generate . <Key>] (werner)

2018-01-19 (bug)[657c38] Crash in menu destroy with checkbutton entry (werner)

2018-01-25 (bug)[de156e] Deny PRIMARY selection access in safe interps (nash)

2018-01-28 (bug)[b68710] Fixes in [text] bindings (nash)

2018-01-28 (bug)[e20d5c] Stop failures of textTag-18.1 (vogel)

2018-02-04 (bug)[5d991b] Fortify var traces against deleted vars (vogel)

2018-02-10 (bug)[1821174] Stop RenderBadPicture X error (werner)

2018-02-11 (bug)[502e74] Stop X errors on untrusted connections (werner)

2018-03-07 (bug)[71b131] Regression in Tk_DrawChars() (werner,cramer)

2018-04-03 (bug)[59fccb] menu flaws when empty menubar clicked (vogel,mcdonald)

2018-04-28 (bug)[7423f9] improved legacy support for [tk_setPalette] (bll)

2018-04-30 (bug)[6d5042] enable [tk inactive] on Mac OSX (culler)

2018-05-03 (bug)[75d38f] fix touchpad scroll of listbox on win notebook (vogel)

2018-06-16 (bug)[de01e2] Crash in [$text replace] (vogel)

2018-07-04 (bug)[6ca257] Fix [wm resizable] on Mac OSX (culler)

2018-07-04 (bug)[135696] Crash in [wm transient] (culler)

2018-07-04 (bug)[309b42] Improve ttk high-contrast-mode support (lemburg,vogel)

2018-07-17 (bug)[1088825] fix frame-2.17,3.9,3.10 on Mac (vogel)

2018-07-27 (bug)[fbaed1] GIF photo support for "deferred clear code" (vogel)

2018-08-08 (feature) Modern full-screen support on Mac OSX (walzer)

2018-08-12 (bug)[1875c1] scrollbar on Mac OSX (walzer)

2018-08-14 (bug)[1ba71a] KeyRelease events on Mac OSX(walzer)

2018-09-02 (bug)[3441086] error message in layout-2 (vogel)

2018-09-07 (bug)[05bd7f] vista theme for combobox (vogel)

2018-09-08 (bug)[382712] crash in KeyPress event handling (vogel,werner)

2018-09-08 (bug)[6fcaaa] insertion cursor visibility in ttk::entry (nemethi)

2018-09-30 (bug)[822923] cascade menu indicator color (mcdonald)

2018-10-06 (bug)[9658bc] borderwidth calculations on menu items (vogel)

2018-10-17 (bug)[ca403f] treeview border drawing (vogel)

2018-10-17 (bug)[4b555a] hang in [$text search -all] (vogel,danckaert)

2018-10-30 (new platform) port to system changes in Mac OSX 10.14 (culler)

2018-11-04 (bug)[6b22d4] [treeview] binding fix (ohagan)

- Released 8.6.9, November 16, 2018 - https://core.tcl-lang.org/tk/ for details

2018-11-19 (bug)[0a9c91] crash in text-11a.22 (vogel)

2018-11-20 (bug)[9705d1] crash activating "Alt" theme (culler)

2018-11-24 (bug)[e3b954] cursor offset at full screen display (culler)

2019-01-04 (bug)[18a4ba] cross-platform [winfo containing] (culler)

2019-01-08 (feature) local grab on Mac OSX (culler)

2019-01-10 (build) 'None', 'ControlMask' symbol conflicts (nijtmans)

2019-01-20 (bug)[509caf] [treeview tag configure] regression (mcdonald,vogel)

2019-01-26 (bug)[3003895] [scale] res rounds and -from (tischler,pieper,vogel)

2019-02-02 (new)[TIP 533] [$mb post x y idx] (culler,vogel)

2019-02-08 (bug)[1529659] embed toplevel blocks outer menu (culler)

2019-02-10 (bug)[8814bd] crash in [NSMenu size] (culler)

2019-02-13 (bug)[b389df] Aqua: mouse position on dual screen (culler)

2019-02-23 (bug)[56a182] Aqua: [tk_getOpenFile] causes off-screen toplevels (culler,walzer)

2019-02-23 (bug)[9771ae] Aqua: workaround incompatible transient window models (culler,walzer)

2019-03-01 (bug)[1951ab] Prevent transient window cycles (crashed on Aqua) (culler,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-03-04 (bug)[4da219] Incomplete read of multi-image GIF (oehlmann)

2019-03-14 (bug)[609e00] Aqua: wrong coords from MouseWheel binding (vogel,culler)

2019-03-25 (bug)[48c394] Aqua: recompute text layout for empty string (culler)

2019-03-31 (new)[TIP 535] Precision of ::scale widget tick mark values (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-03-31 (bug)[da3914] [$treeview identify element] failure (ulfalizer,vogel)

2019-04-06 (bug)[897ffe] Prevent cross-manager loops of geom management (culler,vogel)

2019-04-11 (new) Apple Dark Mode support (culler)

2019-04-14 (new) Aqua: Use color names consistent with NSColor (culler)
        *** POTENTIAL INCOMPATIBILITY ***

2019-04-14 (new) Aqua: [tk::unsupported::MacWindowStyle isdark] (culler)

2019-04-19 (bug)[368fa4] Prevent toggle of hidden treeview indicators (ulfalizer,vogel)

2019-04-24 (bug)[4d2e8d] Aqua: notebook pane redraws (culler)

2019-04-24 (bug)[928652] Apply TIP 533 for ttk::menubutton (culler,vogel)

2019-04-24 (bug)[1001070] X-platform rework of label options -highlight* (seal,culler,vogel)

2019-04-28 (bug)[6286fd] checkbutton handling of -selectcolor (ralfixx)

2019-04-30 (bug)[4f9a99] Win: crash in [style element create] (oehlman,vogel)

2019-05-08 (bug) Ttk scrolling bugs, see tests treeview-9.1, entry-3.[3-6] (vogel)

2019-05-08 (bug)[51b4b1] Aqua: combobox use native ttk scrollbar (bll,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-05-18 (new)[eb2996] Win: support for horizontal scrolling (chavez,vogel)

2019-05-26 (new)[TIP 541] [combobox current] support "end" index (vogel)

2019-05-26 (bug)[2a6c62] <<TreeviewSelect>> trigger on item delete (vogel)

2019-06-05 (bug)[9ebc6f] Aqua: fix incorrect reports of mouse coords (chavez, culler)

2019-06-14 (bug)[436ad6] Corrected Aqua regressions in [wm manage] (walzer, culler)

2019-06-15 (bug)[75b8fb] Crash with some [event generate]d <ButtonRelease> (leunissen,vogel)

2019-06-15 (new)[TIP 536] New tk::mac::* commands for IPC on Mac OSX (walzer)

2019-07-13 (bug)[4566e2] Aqua: Make default background color of Tk and Ttk agree (walzer,culler)
        *** POTENTIAL INCOMPATIBILITY ***

2019-07-16 (bug)[5ddeca] Stop app switching exposing withdrawn windows as zombies (culler)

2019-07-25 (new)[1fb7af] Win support for buttons 4 and 5 (chavez,vogel,nijtmans)

2019-08-18 (new) Refactor all MouseWheel bindings (nijtmans)
        *** POTENTIAL INCOMPATIBILITY ***

2019-08-21 (bug)[c8ccd1] up array key in [text] takes to index 1.0 (ulfalizer,vogel)

2019-08-28 (new)[TIP 532] Tk event loop rewrite to prevent ring overflow (cramer)
        *** POTENTIAL INCOMPATIBILITY ***

2019-08-28 (bug)[943d5e] Win: embedded widget destruction cancels window resize (nemethi,vogel,nijtmans)

2019-09-12 (bug)[2834776] Stop disabled spinbox from generating <<Increment>> & <<Decrement>> (vogel)

2019-09-24 (bug)[96bce5] Aqua: Prevent crash drawing 1x1 rounded rectangles (bll,culler)

2019-10-03 (bug)[3ed5b6] Win: root window position with highlightthickness>0 (leunissem,vogel,nijtmans)

2019-10-09 (bug)[a01b6f7] Workaround XWayland bug reporting screen width (werner,nijtmans)

2019-10-10 (bug) Aqua: Prevent crash deactivating menu during menu deletion (culler)

2019-10-21 (bug)[aea00b] Aqua: Better handling of resolution changes (chavez, culler)

2019-10-25 (bug)[b82bd4] Fix [style configure -compound] (culler,vogel)

2019-10-27 (bug)[f7a4f7] Aqua: embedded toplevel, forced focus and mouse coords (naaus,culler)

2019-11-13 (new) Win: keycodes Mail, AudioMedia, Launch0, Launch1 (nijtmans)

2019-11-15 (bug)[69b48f] failing test textTag-18.1 (vogel)

2019-11-17 (bug)[c4abd2] panic in stackorder command (culler)

2019-11-17 (bug)[53d280] [wm iconphoto] crash on empty image (culler)

2019-11-17 [90d555] workaround NSFontManager bad selections (culler)

2019-11-19 (new) Partial Emoji support in text displays (nijtmans,culler)

- Released 8.6.10, Nov 21, 2019 - https://core.tcl-lang.org/tk/ for details

Changes to 8.7a3 include all changes to the 8.6 line through 8.6.10,
plus the following, which focuses on the high-level feature changes
in this changeset (new minor version) rather than bug fixes:

2017-11-25 [TIP 161] $menu -tearoff default changed to false (roseman,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2017-12-07 [TIP 487] End support for pre-XP Windows (nijtmans)

2018-03-04 [TIP 489] New subcommand [$canvas image] (pitcher,vogel)

2018-05-13 [TIP 496] New options -placeholder* for entries (zaumseil,vogel)

2018-09-23 [TIP 517] New option -activerelief for menus (vogel)

2018-11-03 [TIP 512] Deprecate stub for Tk_MainEx() (nijtmans)

2018-11-06 [TIP 415] New option -height for [$canvas create arc] (geard)

2018-11-06 [TIP 518] New event <<NoMangedChild>> (oehlmann)

2019-04-14 [TIP 164] New subcommand [$canvas rotate] (fellows)

2019-04-14 [TIP 507] New photo image format 'svg' (zaumseil)

2019-04-14 [TIP 483] Record more configuration items (cassoff)

2019-04-14 [TIP 482] Record configured directory for demos (cassoff)

2019-05-25 [TIP 262] New frame options -backgroundimage, -tile (fellows)

2019-06-15 [TIP 528] Deprecate Tk_Offset() (nijtmans)

2019-08-19 [TIP 545] Revised options for photo image format 'svg' (oehlmann)

--- Released 8.7a3, November 25, 2019 --- http://core.tcl.tk/tk/ for details







<
<


<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
7063
7064
7065
7066
7067
7068
7069


7070
7071




7072
7073












































































































































































7074

































































































































































































































































































































2016-01-09 (bug)[1927212] Mousewheel/scrollbar bindings (vogel)

2016-01-11 (bug)[63c354] Cocoa message boxes (culler)

2016-01-12 (bug)[2049429] get more $text options from database (vogel)



2016-01-25 (bug) OBOE in ttk::notebook options parsing (bromley,english)





Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)













































































































































































--- Released 8.5.19, February 12, 2016 --- http://core.tcl.tk/tk/ for details
































































































































































































































































































































Added compat/limits.h.













































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * limits.h --
 *
 *	This is a dummy header file to #include in Tcl when there
 *	is no limits.h in /usr/include.  There are only a few
 *	definitions here;  also see tclPort.h, which already
 *	#defines some of the things here if they're not arleady
 *	defined.
 *
 * Copyright (c) 1991 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.
 */

#define LONG_MIN		0x80000000
#define LONG_MAX		0x7fffffff
#define INT_MIN			0x80000000
#define INT_MAX			0x7fffffff
#define SHRT_MIN		0x8000
#define SHRT_MAX		0x7fff

Deleted compat/stdbool.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*===---- stdbool.h - Standard header for booleans -------------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* Modified for use by pre-C99 compilers. (c) Jan Nijtmans.
*
*===-----------------------------------------------------------------------===
*/

#ifndef __STDBOOL_H
#define __STDBOOL_H

/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define bool _Bool
#else
#define bool unsigned char
#endif
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool as a GNU extension. */
#define _Bool bool
#if __cplusplus < 201103L
/* For C++98, define bool, false, true as a GNU extension. */
#define bool  bool
#define false false
#define true  true
#endif
#endif

#define __bool_true_false_are_defined 1

#endif /* __STDBOOL_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted compat/stdint.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
/*  A portable stdint.h
 ****************************************************************************
 *  BSD License:
 ****************************************************************************
 *
 *  Copyright (c) 2005-2016 Paul Hsieh
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************
 *
 *  Version 0.1.16.0
 *
 *  The ANSI C standard committee, for the C99 standard, specified the
 *  inclusion of a new standard include file called stdint.h.  This is
 *  a very useful and long desired include file which contains several
 *  very precise definitions for integer scalar types that is critically
 *  important for making several classes of applications portable
 *  including cryptography, hashing, variable length integer libraries
 *  and so on.  But for most developers its likely useful just for
 *  programming sanity.
 *
 *  The problem is that some compiler vendors chose to ignore the C99
 *  standard and some older compilers have no opportunity to be updated.
 *  Because of this situation, simply including stdint.h in your code
 *  makes it unportable.
 *
 *  So that's what this file is all about.  It's an attempt to build a
 *  single universal include file that works on as many platforms as
 *  possible to deliver what stdint.h is supposed to.  Even compilers
 *  that already come with stdint.h can use this file instead without
 *  any loss of functionality.  A few things that should be noted about
 *  this file:
 *
 *    1) It is not guaranteed to be portable and/or present an identical
 *       interface on all platforms.  The extreme variability of the
 *       ANSI C standard makes this an impossibility right from the
 *       very get go. Its really only meant to be useful for the vast
 *       majority of platforms that possess the capability of
 *       implementing usefully and precisely defined, standard sized
 *       integer scalars.  Systems which are not intrinsically 2s
 *       complement may produce invalid constants.
 *
 *    2) There is an unavoidable use of non-reserved symbols.
 *
 *    3) Other standard include files are invoked.
 *
 *    4) This file may come in conflict with future platforms that do
 *       include stdint.h.  The hope is that one or the other can be
 *       used with no real difference.
 *
 *    5) In the current version, if your platform can't represent
 *       int32_t, int16_t and int8_t, it just dumps out with a compiler
 *       error.
 *
 *    6) 64 bit integers may or may not be defined.  Test for their
 *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
 *       Note that this is different from the C99 specification which
 *       requires the existence of 64 bit support in the compiler.  If
 *       this is not defined for your platform, yet it is capable of
 *       dealing with 64 bits then it is because this file has not yet
 *       been extended to cover all of your system's capabilities.
 *
 *    7) (u)intptr_t may or may not be defined.  Test for its presence
 *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
 *       for your platform, then it is because this file has not yet
 *       been extended to cover all of your system's capabilities, not
 *       because its optional.
 *
 *    8) The following might not been defined even if your platform is
 *       capable of defining it:
 *
 *       WCHAR_MIN
 *       WCHAR_MAX
 *       (u)int64_t
 *       PTRDIFF_MIN
 *       PTRDIFF_MAX
 *       (u)intptr_t
 *
 *    9) The following have not been defined:
 *
 *       WINT_MIN
 *       WINT_MAX
 *
 *   10) The criteria for defining (u)int_least(*)_t isn't clear,
 *       except for systems which don't have a type that precisely
 *       defined 8, 16, or 32 bit types (which this include file does
 *       not support anyways). Default definitions have been given.
 *
 *   11) The criteria for defining (u)int_fast(*)_t isn't something I
 *       would trust to any particular compiler vendor or the ANSI C
 *       committee.  It is well known that "compatible systems" are
 *       commonly created that have very different performance
 *       characteristics from the systems they are compatible with,
 *       especially those whose vendors make both the compiler and the
 *       system.  Default definitions have been given, but its strongly
 *       recommended that users never use these definitions for any
 *       reason (they do *NOT* deliver any serious guarantee of
 *       improved performance -- not in this file, nor any vendor's
 *       stdint.h).
 *
 *   12) The following macros:
 *
 *       PRINTF_INTMAX_MODIFIER
 *       PRINTF_INT64_MODIFIER
 *       PRINTF_INT32_MODIFIER
 *       PRINTF_INT16_MODIFIER
 *       PRINTF_LEAST64_MODIFIER
 *       PRINTF_LEAST32_MODIFIER
 *       PRINTF_LEAST16_MODIFIER
 *       PRINTF_INTPTR_MODIFIER
 *
 *       are strings which have been defined as the modifiers required
 *       for the "d", "u" and "x" printf formats to correctly output
 *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
 *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
 *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
 *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
 *       defined if INT64_MAX is not defined.  These are an extension
 *       beyond what C99 specifies must be in stdint.h.
 *
 *       In addition, the following macros are defined:
 *
 *       PRINTF_INTMAX_HEX_WIDTH
 *       PRINTF_INT64_HEX_WIDTH
 *       PRINTF_INT32_HEX_WIDTH
 *       PRINTF_INT16_HEX_WIDTH
 *       PRINTF_INT8_HEX_WIDTH
 *       PRINTF_INTMAX_DEC_WIDTH
 *       PRINTF_INT64_DEC_WIDTH
 *       PRINTF_INT32_DEC_WIDTH
 *       PRINTF_INT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *       PRINTF_UINTMAX_DEC_WIDTH
 *       PRINTF_UINT64_DEC_WIDTH
 *       PRINTF_UINT32_DEC_WIDTH
 *       PRINTF_UINT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *
 *       Which specifies the maximum number of characters required to
 *       print the number of that type in either hexadecimal or decimal.
 *       These are an extension beyond what C99 specifies must be in
 *       stdint.h.
 *
 *  Compilers tested (all with 0 warnings at their highest respective
 *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
 *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
 *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
 *
 *  This file should be considered a work in progress.  Suggestions for
 *  improvements, especially those which increase coverage are strongly
 *  encouraged.
 *
 *  Acknowledgements
 *
 *  The following people have made significant contributions to the
 *  development and testing of this file:
 *
 *  Chris Howie
 *  John Steele Scott
 *  Dave Thorup
 *  John Dill
 *  Florian Wobbe
 *  Christopher Sean Morrison
 *  Mikkel Fahnoe Jorgensen
 *
 */

#include <stddef.h>
#include <limits.h>
#include <signal.h>

/*
 *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
 *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
 */

#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
#include <stdint.h>
#define _PSTDINT_H_INCLUDED
# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "l"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   define PRINTF_INT32_MODIFIER ""
#  endif
# else
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   if (UINT_MAX == UINT32_MAX)
#    define PRINTF_INT32_MODIFIER ""
#   else
#    define PRINTF_INT32_MODIFIER "l"
#   endif
#  endif
# endif
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
# ifndef PRINTF_INTMAX_MODIFIER
#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INT64_HEX_WIDTH
#  define PRINTF_INT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_UINT64_HEX_WIDTH
#  define PRINTF_UINT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_INT32_HEX_WIDTH
#  define PRINTF_INT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_UINT32_HEX_WIDTH
#  define PRINTF_UINT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_INT16_HEX_WIDTH
#  define PRINTF_INT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_UINT16_HEX_WIDTH
#  define PRINTF_UINT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_INT8_HEX_WIDTH
#  define PRINTF_INT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_UINT8_HEX_WIDTH
#  define PRINTF_UINT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_INT64_DEC_WIDTH
#  define PRINTF_INT64_DEC_WIDTH "19"
# endif
# ifndef PRINTF_UINT64_DEC_WIDTH
#  define PRINTF_UINT64_DEC_WIDTH "20"
# endif
# ifndef PRINTF_INT32_DEC_WIDTH
#  define PRINTF_INT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_UINT32_DEC_WIDTH
#  define PRINTF_UINT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_INT16_DEC_WIDTH
#  define PRINTF_INT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_UINT16_DEC_WIDTH
#  define PRINTF_UINT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_INT8_DEC_WIDTH
#  define PRINTF_INT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_UINT8_DEC_WIDTH
#  define PRINTF_UINT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_UINTMAX_HEX_WIDTH
#  define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif
# ifndef PRINTF_UINTMAX_DEC_WIDTH
#  define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif

/*
 *  Something really weird is going on with Open Watcom.  Just pull some of
 *  these duplicated definitions from Open Watcom's stdint.h file for now.
 */

# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
#  if !defined (INT64_C)
#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
#  endif
#  if !defined (UINT64_C)
#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
#  endif
#  if !defined (INT32_C)
#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
#  endif
#  if !defined (UINT32_C)
#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
#  endif
#  if !defined (INT16_C)
#   define INT16_C(x)   (x)
#  endif
#  if !defined (UINT16_C)
#   define UINT16_C(x)  (x)
#  endif
#  if !defined (INT8_C)
#   define INT8_C(x)   (x)
#  endif
#  if !defined (UINT8_C)
#   define UINT8_C(x)  (x)
#  endif
#  if !defined (UINT64_MAX)
#   define UINT64_MAX  18446744073709551615ULL
#  endif
#  if !defined (INT64_MAX)
#   define INT64_MAX  9223372036854775807LL
#  endif
#  if !defined (UINT32_MAX)
#   define UINT32_MAX  4294967295UL
#  endif
#  if !defined (INT32_MAX)
#   define INT32_MAX  2147483647L
#  endif
#  if !defined (INTMAX_MAX)
#   define INTMAX_MAX INT64_MAX
#  endif
#  if !defined (INTMAX_MIN)
#   define INTMAX_MIN INT64_MIN
#  endif
# endif
#endif

/*
 *  I have no idea what is the truly correct thing to do on older Solaris.
 *  From some online discussions, this seems to be what is being
 *  recommended.  For people who actually are developing on older Solaris,
 *  what I would like to know is, does this define all of the relevant
 *  macros of a complete stdint.h?  Remember, in pstdint.h 64 bit is
 *  considered optional.
 */

#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
#include <sys/inttypes.h>
#define _PSTDINT_H_INCLUDED
#endif

#ifndef _PSTDINT_H_INCLUDED
#define _PSTDINT_H_INCLUDED

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t)-1)
#endif

/*
 *  Deduce the type assignments from limits.h under the assumption that
 *  integer sizes in bits are powers of 2, and follow the ANSI
 *  definitions.
 */

#ifndef UINT8_MAX
# define UINT8_MAX 0xff
#endif
#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
    typedef unsigned char uint8_t;
#   define UINT8_C(v) ((uint8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef INT8_MAX
# define INT8_MAX 0x7f
#endif
#ifndef INT8_MIN
# define INT8_MIN INT8_C(0x80)
#endif
#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
    typedef signed char int8_t;
#   define INT8_C(v) ((int8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef UINT16_MAX
# define UINT16_MAX 0xffff
#endif
#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
  typedef unsigned int uint16_t;
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
# define UINT16_C(v) ((uint16_t) (v))
#elif (USHRT_MAX == UINT16_MAX)
  typedef unsigned short uint16_t;
# define UINT16_C(v) ((uint16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT16_MAX
# define INT16_MAX 0x7fff
#endif
#ifndef INT16_MIN
# define INT16_MIN INT16_C(0x8000)
#endif
#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
  typedef signed int int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
#elif (SHRT_MAX == INT16_MAX)
  typedef signed short int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffffUL)
#endif
#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
  typedef unsigned long uint32_t;
# define UINT32_C(v) v ## UL
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (UINT_MAX == UINT32_MAX)
  typedef unsigned int uint32_t;
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
# define UINT32_C(v) v ## U
#elif (USHRT_MAX == UINT32_MAX)
  typedef unsigned short uint32_t;
# define UINT32_C(v) ((unsigned short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT32_MAX
# define INT32_MAX (0x7fffffffL)
#endif
#ifndef INT32_MIN
# define INT32_MIN INT32_C(0x80000000)
#endif
#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
  typedef signed long int32_t;
# define INT32_C(v) v ## L
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (INT_MAX == INT32_MAX)
  typedef signed int int32_t;
# define INT32_C(v) v
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#elif (SHRT_MAX == INT32_MAX)
  typedef signed short int32_t;
# define INT32_C(v) ((short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

/*
 *  The macro stdint_int64_defined is temporarily used to record
 *  whether or not 64 integer support is available.  It must be
 *  defined for any 64 integer extensions for new platforms that are
 *  added.
 */

#undef stdint_int64_defined
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# endif
#endif

#if !defined (stdint_int64_defined)
# if defined(__GNUC__) && !defined(vxWorks)
#  define stdint_int64_defined
   __extension__ typedef long long int64_t;
   __extension__ typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
#  define stdint_int64_defined
   typedef __int64 int64_t;
   typedef unsigned __int64 uint64_t;
#  define UINT64_C(v) v ## UI64
#  define  INT64_C(v) v ## I64
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "I64"
#  endif
# endif
#endif

#if !defined (LONG_LONG_MAX) && defined (INT64_C)
# define LONG_LONG_MAX INT64_C (9223372036854775807)
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
#endif

#if !defined (INT64_MAX) && defined (INT64_C)
# define INT64_MAX INT64_C (9223372036854775807)
#endif
#if !defined (INT64_MIN) && defined (INT64_C)
# define INT64_MIN INT64_C (-9223372036854775808)
#endif
#if !defined (UINT64_MAX) && defined (INT64_C)
# define UINT64_MAX UINT64_C (18446744073709551615)
#endif

/*
 *  Width of hexadecimal for number field.
 */

#ifndef PRINTF_INT64_HEX_WIDTH
# define PRINTF_INT64_HEX_WIDTH "16"
#endif
#ifndef PRINTF_INT32_HEX_WIDTH
# define PRINTF_INT32_HEX_WIDTH "8"
#endif
#ifndef PRINTF_INT16_HEX_WIDTH
# define PRINTF_INT16_HEX_WIDTH "4"
#endif
#ifndef PRINTF_INT8_HEX_WIDTH
# define PRINTF_INT8_HEX_WIDTH "2"
#endif
#ifndef PRINTF_INT64_DEC_WIDTH
# define PRINTF_INT64_DEC_WIDTH "19"
#endif
#ifndef PRINTF_INT32_DEC_WIDTH
# define PRINTF_INT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_INT16_DEC_WIDTH
# define PRINTF_INT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_INT8_DEC_WIDTH
# define PRINTF_INT8_DEC_WIDTH "3"
#endif
#ifndef PRINTF_UINT64_DEC_WIDTH
# define PRINTF_UINT64_DEC_WIDTH "20"
#endif
#ifndef PRINTF_UINT32_DEC_WIDTH
# define PRINTF_UINT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_UINT16_DEC_WIDTH
# define PRINTF_UINT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_UINT8_DEC_WIDTH
# define PRINTF_UINT8_DEC_WIDTH "3"
#endif

/*
 *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
 *  we don't need to worry about that until about 2040 at which point
 *  we'll have bigger things to worry about.
 */

#ifdef stdint_int64_defined
  typedef int64_t intmax_t;
  typedef uint64_t uintmax_t;
# define  INTMAX_MAX   INT64_MAX
# define  INTMAX_MIN   INT64_MIN
# define UINTMAX_MAX  UINT64_MAX
# define UINTMAX_C(v) UINT64_C(v)
# define  INTMAX_C(v)  INT64_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
#else
  typedef int32_t intmax_t;
  typedef uint32_t uintmax_t;
# define  INTMAX_MAX   INT32_MAX
# define UINTMAX_MAX  UINT32_MAX
# define UINTMAX_C(v) UINT32_C(v)
# define  INTMAX_C(v)  INT32_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
# endif
#endif

/*
 *  Because this file currently only supports platforms which have
 *  precise powers of 2 as bit sizes for the default integers, the
 *  least definitions are all trivial.  Its possible that a future
 *  version of this file could have different definitions.
 */

#ifndef stdint_least_defined
  typedef   int8_t   int_least8_t;
  typedef  uint8_t  uint_least8_t;
  typedef  int16_t  int_least16_t;
  typedef uint16_t uint_least16_t;
  typedef  int32_t  int_least32_t;
  typedef uint32_t uint_least32_t;
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
# define  UINT_LEAST8_MAX  UINT8_MAX
# define   INT_LEAST8_MAX   INT8_MAX
# define UINT_LEAST16_MAX UINT16_MAX
# define  INT_LEAST16_MAX  INT16_MAX
# define UINT_LEAST32_MAX UINT32_MAX
# define  INT_LEAST32_MAX  INT32_MAX
# define   INT_LEAST8_MIN   INT8_MIN
# define  INT_LEAST16_MIN  INT16_MIN
# define  INT_LEAST32_MIN  INT32_MIN
# ifdef stdint_int64_defined
    typedef  int64_t  int_least64_t;
    typedef uint64_t uint_least64_t;
#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
#   define UINT_LEAST64_MAX UINT64_MAX
#   define  INT_LEAST64_MAX  INT64_MAX
#   define  INT_LEAST64_MIN  INT64_MIN
# endif
#endif
#undef stdint_least_defined

/*
 *  The ANSI C committee has defined *int*_fast*_t types as well.  This,
 *  of course, defies rationality -- you can't know what will be fast
 *  just from the type itself.  Even for a given architecture, compatible
 *  implementations might have different performance characteristics.
 *  Developers are warned to stay away from these types when using this
 *  or any other stdint.h.
 */

typedef   int_least8_t   int_fast8_t;
typedef  uint_least8_t  uint_fast8_t;
typedef  int_least16_t  int_fast16_t;
typedef uint_least16_t uint_fast16_t;
typedef  int_least32_t  int_fast32_t;
typedef uint_least32_t uint_fast32_t;
#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
#define   INT_FAST8_MAX   INT_LEAST8_MAX
#define UINT_FAST16_MAX UINT_LEAST16_MAX
#define  INT_FAST16_MAX  INT_LEAST16_MAX
#define UINT_FAST32_MAX UINT_LEAST32_MAX
#define  INT_FAST32_MAX  INT_LEAST32_MAX
#define   INT_FAST8_MIN   INT_LEAST8_MIN
#define  INT_FAST16_MIN  INT_LEAST16_MIN
#define  INT_FAST32_MIN  INT_LEAST32_MIN
#ifdef stdint_int64_defined
  typedef  int_least64_t  int_fast64_t;
  typedef uint_least64_t uint_fast64_t;
# define UINT_FAST64_MAX UINT_LEAST64_MAX
# define  INT_FAST64_MAX  INT_LEAST64_MAX
# define  INT_FAST64_MIN  INT_LEAST64_MIN
#endif

#undef stdint_int64_defined

/*
 *  Whatever piecemeal, per compiler thing we can do about the wchar_t
 *  type limits.
 */

#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
# include <wchar.h>
# ifndef WCHAR_MIN
#  define WCHAR_MIN 0
# endif
# ifndef WCHAR_MAX
#  define WCHAR_MAX ((wchar_t)-1)
# endif
#endif

/*
 *  Whatever piecemeal, per compiler/platform thing we can do about the
 *  (u)intptr_t types and limits.
 */

#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
# define STDINT_H_UINTPTR_T_DEFINED
#endif

#ifndef STDINT_H_UINTPTR_T_DEFINED
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
#  define stdint_intptr_bits 64
# elif defined (__WATCOMC__) || defined (__TURBOC__)
#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#    define stdint_intptr_bits 16
#  else
#    define stdint_intptr_bits 32
#  endif
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
#  define stdint_intptr_bits 32
# elif defined (__INTEL_COMPILER)
/* TODO -- what did Intel do about x86-64? */
# else
/* #error "This platform might not be supported yet" */
# endif

# ifdef stdint_intptr_bits
#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
#  ifndef PRINTF_INTPTR_MODIFIER
#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
#  endif
#  ifndef PTRDIFF_MAX
#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef PTRDIFF_MIN
#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef UINTPTR_MAX
#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MAX
#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MIN
#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef INTPTR_C
#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
#  endif
#  ifndef UINTPTR_C
#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
#  endif
  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
# else
/* TODO -- This following is likely wrong for some platforms, and does
   nothing for the definition of uintptr_t. */
  typedef ptrdiff_t intptr_t;
# endif
# define STDINT_H_UINTPTR_T_DEFINED
#endif

/*
 *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
 */

#ifndef SIG_ATOMIC_MAX
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
#endif

#endif

#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)

/*
 *  Please compile with the maximum warning settings to make sure macros are
 *  not defined more than once.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define glue3_aux(x,y,z) x ## y ## z
#define glue3(x,y,z) glue3_aux(x,y,z)

#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);

#define DECL(us,bits) glue3(DECL,us,) (bits)

#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)

#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }

#define X_SIZE_MAX ((size_t)-1)

int main () {
	int err_n = 0;
	int err_first = 0;
	DECL(I,8)
	DECL(U,8)
	DECL(I,16)
	DECL(U,16)
	DECL(I,32)
	DECL(U,32)
#ifdef INT64_MAX
	DECL(I,64)
	DECL(U,64)
#endif
	intmax_t imax = INTMAX_C(0);
	uintmax_t umax = UINTMAX_C(0);
	char str0[256], str1[256];

	sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
	if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
	sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
	if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
	if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
	if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
#endif

	sprintf (str0, "%d %x\n", 0, ~0);

	sprintf (str1, "%d %x\n",  i8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
	sprintf (str1, "%d %x\n",  i16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n",  i32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n",  u32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n",  i64, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
#endif
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n",  imax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n",  umax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));

	TESTUMAX(8);
	TESTUMAX(16);
	TESTUMAX(32);
#ifdef INT64_MAX
	TESTUMAX(64);
#endif

#define STR(v) #v
#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
	if (err_n) {
		printf ("pstdint.h is not correct.  Please use sizes below to correct it:\n");
	}

	Q(int)
	Q(unsigned)
	Q(long int)
	Q(short int)
	Q(int8_t)
	Q(int16_t)
	Q(int32_t)
#ifdef INT64_MAX
	Q(int64_t)
#endif

#if UINT_MAX < X_SIZE_MAX
	printf ("UINT_MAX < X_SIZE_MAX\n");
#else
	printf ("UINT_MAX >= X_SIZE_MAX\n");
#endif
	printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX);

	return EXIT_SUCCESS;
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added compat/stdlib.h.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * stdlib.h --
 *
 *	Declares facilities exported by the "stdlib" portion of
 *	the C library.  This file isn't complete in the ANSI-C
 *	sense;  it only declares things that are needed by Tcl.
 *	This file is needed even on many systems with their own
 *	stdlib.h (e.g. SunOS) because not all stdlib.h files
 *	declare all the procedures needed here (such as strtod).
 *
 * Copyright (c) 1991 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.
 */

#ifndef _STDLIB
#define _STDLIB

#include <tcl.h>

extern void		abort _ANSI_ARGS_((void));
extern double		atof _ANSI_ARGS_((CONST char *string));
extern int		atoi _ANSI_ARGS_((CONST char *string));
extern long		atol _ANSI_ARGS_((CONST char *string));
extern char *		calloc _ANSI_ARGS_((unsigned int numElements,
			    unsigned int size));
extern void		exit _ANSI_ARGS_((int status));
extern int		free _ANSI_ARGS_((char *blockPtr));
extern char *		getenv _ANSI_ARGS_((CONST char *name));
extern char *		malloc _ANSI_ARGS_((unsigned int numBytes));
extern void		qsort _ANSI_ARGS_((VOID *base, int n, int size,
			    int (*compar)(CONST VOID *element1, CONST VOID
			    *element2)));
extern char *		realloc _ANSI_ARGS_((char *ptr, unsigned int numBytes));
extern double		strtod _ANSI_ARGS_((CONST char *string, char **endPtr));
extern long		strtol _ANSI_ARGS_((CONST char *string, char **endPtr,
			    int base));
extern unsigned long	strtoul _ANSI_ARGS_((CONST char *string,
			    char **endPtr, int base));

#endif /* _STDLIB */

Added compat/unistd.h.





































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * unistd.h --
 *
 *      Macros, CONSTants and prototypes for Posix conformance.
 *
 * Copyright 1989 Regents of the University of California
 * 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.  The University of California
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 */

#ifndef _UNISTD
#define _UNISTD

#include <sys/types.h>
#ifndef _TCL
#   include "tcl.h"
#endif

#ifndef NULL
#define NULL    0
#endif

/*
 * Strict POSIX stuff goes here.  Extensions go down below, in the
 * ifndef _POSIX_SOURCE section.
 */

extern void _exit _ANSI_ARGS_((int status));
extern int access _ANSI_ARGS_((CONST char *path, int mode));
extern int chdir _ANSI_ARGS_((CONST char *path));
extern int chown _ANSI_ARGS_((CONST char *path, uid_t owner, gid_t group));
extern int close _ANSI_ARGS_((int fd));
extern int dup _ANSI_ARGS_((int oldfd));
extern int dup2 _ANSI_ARGS_((int oldfd, int newfd));
extern int execl _ANSI_ARGS_((CONST char *path, ...));
extern int execle _ANSI_ARGS_((CONST char *path, ...));
extern int execlp _ANSI_ARGS_((CONST char *file, ...));
extern int execv _ANSI_ARGS_((CONST char *path, char **argv));
extern int execve _ANSI_ARGS_((CONST char *path, char **argv, char **envp));
extern int execvp _ANSI_ARGS_((CONST char *file, char **argv));
extern pid_t fork _ANSI_ARGS_((void));
extern char *getcwd _ANSI_ARGS_((char *buf, size_t size));
extern gid_t getegid _ANSI_ARGS_((void));
extern uid_t geteuid _ANSI_ARGS_((void));
extern gid_t getgid _ANSI_ARGS_((void));
extern int getgroups _ANSI_ARGS_((int bufSize, int *buffer));
extern pid_t getpid _ANSI_ARGS_((void));
extern uid_t getuid _ANSI_ARGS_((void));
extern int isatty _ANSI_ARGS_((int fd));
extern long lseek _ANSI_ARGS_((int fd, long offset, int whence));
extern int pipe _ANSI_ARGS_((int *fildes));
extern int read _ANSI_ARGS_((int fd, char *buf, size_t size));
extern int setgid _ANSI_ARGS_((gid_t group));
extern int setuid _ANSI_ARGS_((uid_t user));
extern unsigned sleep _ANSI_ARGS_ ((unsigned seconds));
extern char *ttyname _ANSI_ARGS_((int fd));
extern int unlink _ANSI_ARGS_((CONST char *path));
extern int write _ANSI_ARGS_((int fd, CONST char *buf, size_t size));

#ifndef	_POSIX_SOURCE
extern char *crypt _ANSI_ARGS_((CONST char *, CONST char *));
extern int fchown _ANSI_ARGS_((int fd, uid_t owner, gid_t group));
extern int flock _ANSI_ARGS_((int fd, int operation));
extern int ftruncate _ANSI_ARGS_((int fd, unsigned long length));
extern int ioctl _ANSI_ARGS_((int fd, int request, ...));
extern int readlink _ANSI_ARGS_((CONST char *path, char *buf, int bufsize));
extern int setegid _ANSI_ARGS_((gid_t group));
extern int seteuid _ANSI_ARGS_((uid_t user));
extern int setreuid _ANSI_ARGS_((int ruid, int euid));
extern int symlink _ANSI_ARGS_((CONST char *, CONST char *));
extern int ttyslot _ANSI_ARGS_((void));
extern int truncate _ANSI_ARGS_((CONST char *path, unsigned long length));
extern int vfork _ANSI_ARGS_((void));
#endif /* _POSIX_SOURCE */

#endif /* _UNISTD */

Changes to doc/3DBorder.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 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.
'\"
.TH Tk_Alloc3DBorderFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Alloc3DBorderFromObj, Tk_Get3DBorder, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 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.
'\" 
.TH Tk_Alloc3DBorderFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Alloc3DBorderFromObj, Tk_Get3DBorder, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance
.SH SYNOPSIS
.nf
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
.AS "Tk_3DBorder" borderWidth
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window (for all procedures except \fBTk_Get3DBorder\fR,
must be the window for which the border was allocated).
.AP Tcl_Obj *objPtr in
Pointer to value whose value describes color corresponding to
background (flat areas).  Illuminated edges will be brighter than
this and shadowed edges will be darker than this.
.AP char *colorName in
Same as \fIobjPtr\fR except value is supplied as a string rather
than a value.
.AP Drawable drawable in
X token for window or pixmap;  indicates where graphics are to be drawn.
Must either be the X window for \fItkwin\fR or a pixmap with the
same screen and depth as \fItkwin\fR.
.AP Tk_3DBorder border in
Token for border previously allocated in call to \fBTk_Get3DBorder\fR.
.AP int x in







|




|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
.AS "Tk_3DBorder" borderWidth
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window (for all procedures except \fBTk_Get3DBorder\fR,
must be the window for which the border was allocated).
.AP Tcl_Obj *objPtr in
Pointer to object whose value describes color corresponding to
background (flat areas).  Illuminated edges will be brighter than
this and shadowed edges will be darker than this.
.AP char *colorName in
Same as \fIobjPtr\fR except value is supplied as a string rather
than an object.
.AP Drawable drawable in
X token for window or pixmap;  indicates where graphics are to be drawn.
Must either be the X window for \fItkwin\fR or a pixmap with the
same screen and depth as \fItkwin\fR.
.AP Tk_3DBorder border in
Token for border previously allocated in call to \fBTk_Get3DBorder\fR.
.AP int x in
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
.AP int height in
Height of rectangle describing border or bevel, in pixels.
.AP int borderWidth in
Width of border in pixels. Positive means border is inside rectangle
given by \fIx\fR, \fIy\fR, \fIwidth\fR, \fIheight\fR, negative means
border is outside rectangle.
.AP int relief in
Indicates 3-D position of interior of value relative to exterior;
should be \fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR,
\fBTK_RELIEF_SOLID\fR, or \fBTK_RELIEF_RIDGE\fR (may also be \fBTK_RELIEF_FLAT\fR
for \fBTk_Fill3DRectangle\fR).
.AP XPoint *pointPtr in
Pointer to array of points describing the set of vertices in a polygon.
The polygon need not be closed (it will be closed automatically if it
is not).







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
.AP int height in
Height of rectangle describing border or bevel, in pixels.
.AP int borderWidth in
Width of border in pixels. Positive means border is inside rectangle
given by \fIx\fR, \fIy\fR, \fIwidth\fR, \fIheight\fR, negative means
border is outside rectangle.
.AP int relief in
Indicates 3-D position of interior of object relative to exterior;
should be \fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR,
\fBTK_RELIEF_SOLID\fR, or \fBTK_RELIEF_RIDGE\fR (may also be \fBTK_RELIEF_FLAT\fR
for \fBTk_Fill3DRectangle\fR).
.AP XPoint *pointPtr in
Pointer to array of points describing the set of vertices in a polygon.
The polygon need not be closed (it will be closed automatically if it
is not).
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
Height of left side of polygon's path relative to right.  \fBTK_RELIEF_RAISED\fR
means left side should appear higher and \fBTK_RELIEF_SUNKEN\fR means right side
should appear higher;
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean the obvious things.
For \fBTk_Fill3DPolygon\fR, \fBTK_RELIEF_FLAT\fR may also be specified to
indicate no difference in height.
.AP int leftBevel in
Non-zero means this bevel forms the left side of the value;  zero means
it forms the right side.
.AP int leftIn in
Non-zero means that the left edge of the horizontal bevel angles in,
so that the bottom of the edge is farther to the right than
the top.
Zero means the edge angles out, so that the bottom is farther to the
left than the top.
.AP int rightIn in
Non-zero means that the right edge of the horizontal bevel angles in,
so that the bottom of the edge is farther to the left than the top.
Zero means the edge angles out, so that the bottom is farther to the
right than the top.
.AP int topBevel in
Non-zero means this bevel forms the top side of the value;  zero means
it forms the bottom side.
.AP int which in
Specifies which of the border's graphics contexts is desired.
Must be \fBTK_3D_FLAT_GC\fR, \fBTK_3D_LIGHT_GC\fR, or \fBTK_3D_DARK_GC\fR.
.BE

.SH DESCRIPTION
.PP
These procedures provide facilities for drawing window borders in a
way that produces a three-dimensional appearance.
\fBTk_Alloc3DBorderFromObj\fR
allocates colors and Pixmaps needed to draw a border in the window
given by the \fItkwin\fR argument.  The value of \fIobjPtr\fR
is a standard Tk color name that determines the border colors.
The color indicated by \fIobjPtr\fR will not actually be used in
the border;  it indicates the background color for the window
(i.e. a color for flat surfaces).
The illuminated portions of the border will appear brighter than indicated
by \fIobjPtr\fR, and the shadowed portions of the border will appear
darker than \fIobjPtr\fR.
.PP
\fBTk_Alloc3DBorderFromObj\fR returns a token that may be used in later calls
to \fBTk_Draw3DRectangle\fR.  If an error occurs in allocating information
for the border (e.g. a bogus color name was given)
then NULL is returned and an error message is left as the result of
interpreter \fIinterp\fR.
If it returns successfully, \fBTk_Alloc3DBorderFromObj\fR caches
information about the return value in \fIobjPtr\fR, which speeds up
future calls to \fBTk_Alloc3DBorderFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.
.PP
\fBTk_Get3DBorder\fR is identical to \fBTk_Alloc3DBorderFromObj\fR except
that the color is specified with a string instead of a value.  This
prevents \fBTk_Get3DBorder\fR from caching the return value, so
\fBTk_Get3DBorder\fR is less efficient than \fBTk_Alloc3DBorderFromObj\fR.
.PP
\fBTk_Get3DBorderFromObj\fR returns the token for an existing border, given
the window and color name used to create the border.
\fBTk_Get3DBorderFromObj\fR does not actually create the border; it must
already have been created with a previous call to







|













|





>


















|
<






|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
Height of left side of polygon's path relative to right.  \fBTK_RELIEF_RAISED\fR
means left side should appear higher and \fBTK_RELIEF_SUNKEN\fR means right side
should appear higher;
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean the obvious things.
For \fBTk_Fill3DPolygon\fR, \fBTK_RELIEF_FLAT\fR may also be specified to
indicate no difference in height.
.AP int leftBevel in
Non-zero means this bevel forms the left side of the object;  zero means
it forms the right side.
.AP int leftIn in
Non-zero means that the left edge of the horizontal bevel angles in,
so that the bottom of the edge is farther to the right than
the top.
Zero means the edge angles out, so that the bottom is farther to the
left than the top.
.AP int rightIn in
Non-zero means that the right edge of the horizontal bevel angles in,
so that the bottom of the edge is farther to the left than the top.
Zero means the edge angles out, so that the bottom is farther to the
right than the top.
.AP int topBevel in
Non-zero means this bevel forms the top side of the object;  zero means
it forms the bottom side.
.AP int which in
Specifies which of the border's graphics contexts is desired.
Must be \fBTK_3D_FLAT_GC\fR, \fBTK_3D_LIGHT_GC\fR, or \fBTK_3D_DARK_GC\fR.
.BE

.SH DESCRIPTION
.PP
These procedures provide facilities for drawing window borders in a
way that produces a three-dimensional appearance.
\fBTk_Alloc3DBorderFromObj\fR
allocates colors and Pixmaps needed to draw a border in the window
given by the \fItkwin\fR argument.  The value of \fIobjPtr\fR
is a standard Tk color name that determines the border colors.
The color indicated by \fIobjPtr\fR will not actually be used in
the border;  it indicates the background color for the window
(i.e. a color for flat surfaces).
The illuminated portions of the border will appear brighter than indicated
by \fIobjPtr\fR, and the shadowed portions of the border will appear
darker than \fIobjPtr\fR.
.PP
\fBTk_Alloc3DBorderFromObj\fR returns a token that may be used in later calls
to \fBTk_Draw3DRectangle\fR.  If an error occurs in allocating information
for the border (e.g. a bogus color name was given)
then NULL is returned and an error message is left in \fIinterp->result\fR.

If it returns successfully, \fBTk_Alloc3DBorderFromObj\fR caches
information about the return value in \fIobjPtr\fR, which speeds up
future calls to \fBTk_Alloc3DBorderFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.
.PP
\fBTk_Get3DBorder\fR is identical to \fBTk_Alloc3DBorderFromObj\fR except
that the color is specified with a string instead of an object.  This
prevents \fBTk_Get3DBorder\fR from caching the return value, so
\fBTk_Get3DBorder\fR is less efficient than \fBTk_Alloc3DBorderFromObj\fR.
.PP
\fBTk_Get3DBorderFromObj\fR returns the token for an existing border, given
the window and color name used to create the border.
\fBTk_Get3DBorderFromObj\fR does not actually create the border; it must
already have been created with a previous call to
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
rectangle.
Each procedure takes \fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
arguments that describe the rectangular area of the beveled edge
(e.g., \fIwidth\fR is the border width for \fBTk_3DVerticalBevel\fR).
The \fIleftBorder\fR and \fItopBorder\fR arguments indicate the
position of the border relative to the
.QW inside
of the value, and
\fIrelief\fR indicates the relief of the inside of the value relative
to the outside.
\fBTk_3DVerticalBevel\fR just draws a rectangular region.
\fBTk_3DHorizontalBevel\fR draws a trapezoidal region to generate
mitered corners;  it should be called after \fBTk_3DVerticalBevel\fR
(otherwise \fBTk_3DVerticalBevel\fR will overwrite the mitering in
the corner).
The \fIleftIn\fR and \fIrightIn\fR arguments to \fBTk_3DHorizontalBevel\fR







|
|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
rectangle.
Each procedure takes \fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
arguments that describe the rectangular area of the beveled edge
(e.g., \fIwidth\fR is the border width for \fBTk_3DVerticalBevel\fR).
The \fIleftBorder\fR and \fItopBorder\fR arguments indicate the
position of the border relative to the
.QW inside
of the object, and
\fIrelief\fR indicates the relief of the inside of the object relative
to the outside.
\fBTk_3DVerticalBevel\fR just draws a rectangular region.
\fBTk_3DHorizontalBevel\fR draws a trapezoidal region to generate
mitered corners;  it should be called after \fBTk_3DVerticalBevel\fR
(otherwise \fBTk_3DVerticalBevel\fR will overwrite the mitering in
the corner).
The \fIleftIn\fR and \fIrightIn\fR arguments to \fBTk_3DHorizontalBevel\fR
286
287
288
289
290
291
292

293
294
For \fBTk_Free3DBorderFromObj\fR the border to release is specified
with the window and color name used to create the
border; for \fBTk_Free3DBorder\fR the border to release is specified
with the Tk_3DBorder token for the border.
There should be exactly one call to \fBTk_Free3DBorderFromObj\fR or
\fBTk_Free3DBorder\fR for each call to \fBTk_Alloc3DBorderFromObj\fR
or \fBTk_Get3DBorder\fR.

.SH KEYWORDS
3D, background, border, color, depressed, illumination, value, polygon, raised, shadow, three-dimensional effect







>

|
286
287
288
289
290
291
292
293
294
295
For \fBTk_Free3DBorderFromObj\fR the border to release is specified
with the window and color name used to create the
border; for \fBTk_Free3DBorder\fR the border to release is specified
with the Tk_3DBorder token for the border.
There should be exactly one call to \fBTk_Free3DBorderFromObj\fR or
\fBTk_Free3DBorder\fR for each call to \fBTk_Alloc3DBorderFromObj\fR
or \fBTk_Get3DBorder\fR.

.SH KEYWORDS
3D, background, border, color, depressed, illumination, object, polygon, raised, shadow, three-dimensional effect

Changes to doc/AddOption.3.

19
20
21
22
23
24
25

26
27
28
29
30
31
32
.AP "const char" *name in
Multi-element name of option.
.AP "const char" *value in
Value of option.
.AP int priority in
Overall priority level to use for option.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked to add an option to the database
associated with \fItkwin\fR's main window.  \fIName\fR
contains the option being specified and consists of names and/or
classes separated by asterisks or dots, in the usual X format.
\fIValue\fR contains the text string to associate with \fIname\fR;







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.AP "const char" *name in
Multi-element name of option.
.AP "const char" *value in
Value of option.
.AP int priority in
Overall priority level to use for option.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked to add an option to the database
associated with \fItkwin\fR's main window.  \fIName\fR
contains the option being specified and consists of names and/or
classes separated by asterisks or dots, in the usual X format.
\fIValue\fR contains the text string to associate with \fIname\fR;
42
43
44
45
46
47
48

49
50
.IP 60
Used for options specified in user-specific defaults files, such as
\fB.Xdefaults\fR, resource databases loaded into the X server, or
user-specific startup files.
.IP 80
Used for options specified interactively after the application starts
running.

.SH KEYWORDS
class, name, option, add







>


43
44
45
46
47
48
49
50
51
52
.IP 60
Used for options specified in user-specific defaults files, such as
\fB.Xdefaults\fR, resource databases loaded into the X server, or
user-specific startup files.
.IP 80
Used for options specified interactively after the application starts
running.

.SH KEYWORDS
class, name, option, add

Changes to doc/BindTable.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateBindingTable 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateBindingTable, Tk_DeleteBindingTable, Tk_CreateBinding, Tk_DeleteBinding, Tk_GetBinding, Tk_GetAllBindings, Tk_DeleteAllBindings, Tk_BindEvent \- invoke scripts in response to X events
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateBindingTable 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateBindingTable, Tk_DeleteBindingTable, Tk_CreateBinding, Tk_DeleteBinding, Tk_GetBinding, Tk_GetAllBindings, Tk_DeleteAllBindings, Tk_BindEvent \- invoke scripts in response to X events
.SH SYNOPSIS
.nf
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
.AP Tk_BindingTable bindingTable in
Token for binding table;  must have been returned by some previous
call to \fBTk_CreateBindingTable\fR.
.AP ClientData object in
Identifies object with which binding is associated.
.AP "const char" *eventString in
String describing event sequence.
.AP "const char" *script in
Tcl script to invoke when binding triggers.
.AP int append in
Non-zero means append \fIscript\fR to existing script for binding,
if any; zero means replace existing script with new one.
.AP XEvent *eventPtr in
X event to match against bindings in \fIbindingTable\fR.
.AP Tk_Window tkwin in
Identifier for any window on the display where the event occurred.
Used to find display-related information such as key maps.
.AP int numObjects in
Number of object identifiers pointed to by \fIobjectPtr\fR.
.AP ClientData *objectPtr in
Points to an array of object identifiers:  bindings will be considered
for each of these objects in order from first to last.
.BE

.SH DESCRIPTION
.PP
These procedures provide a general-purpose mechanism for creating
and invoking bindings.
Bindings are organized in terms of \fIbinding tables\fR.
A binding table consists of a collection of bindings plus a history
of recent events.







|















>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
.AP Tk_BindingTable bindingTable in
Token for binding table;  must have been returned by some previous
call to \fBTk_CreateBindingTable\fR.
.AP ClientData object in
Identifies object with which binding is associated.
.AP "const char" *eventString in
String describing event sequence.
.AP char *script in
Tcl script to invoke when binding triggers.
.AP int append in
Non-zero means append \fIscript\fR to existing script for binding,
if any; zero means replace existing script with new one.
.AP XEvent *eventPtr in
X event to match against bindings in \fIbindingTable\fR.
.AP Tk_Window tkwin in
Identifier for any window on the display where the event occurred.
Used to find display-related information such as key maps.
.AP int numObjects in
Number of object identifiers pointed to by \fIobjectPtr\fR.
.AP ClientData *objectPtr in
Points to an array of object identifiers:  bindings will be considered
for each of these objects in order from first to last.
.BE

.SH DESCRIPTION
.PP
These procedures provide a general-purpose mechanism for creating
and invoking bindings.
Bindings are organized in terms of \fIbinding tables\fR.
A binding table consists of a collection of bindings plus a history
of recent events.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
\fBTk_CreateBinding\fR returns an X event mask for all the events
associated with the bindings.
This information may be useful to invoke \fBXSelectInput\fR to
select relevant events, or to disallow the use of certain events
in bindings.
If an error occurred while creating the binding (e.g., \fIeventString\fR
refers to a non-existent event), then 0 is returned and an error
message is left as the result of interpreter \fIinterp\fR.
.PP
\fBTk_DeleteBinding\fR removes from \fIbindingTable\fR the
binding given by \fIobject\fR and \fIeventString\fR, if
such a binding exists.
\fBTk_DeleteBinding\fR always returns \fBTCL_OK\fR.
In some cases it may reset the interpreter result to the default
empty value.
.PP
\fBTk_GetBinding\fR returns a pointer to the script associated
with \fIeventString\fR and \fIobject\fR in \fIbindingTable\fR.
If no such binding exists then NULL is returned and an error
message is left as the result of interpreter \fIinterp\fR.
.PP
\fBTk_GetAllBindings\fR returns in \fIinterp\fR's result a list
of all the event strings for which there are bindings in
\fIbindingTable\fR associated with \fIobject\fR.
If there are no bindings for \fIobject\fR, the result will be an empty
string.
.PP
\fBTk_DeleteAllBindings\fR deletes all of the bindings in
\fIbindingTable\fR that are associated with \fIobject\fR.
.PP
\fBTk_BindEvent\fR is called to process an event.
It makes a copy of the event in an internal history list associated
with the binding table, then it checks for bindings that match
the event.
\fBTk_BindEvent\fR processes each of the objects pointed to
by \fIobjectPtr\fR in turn.
For each object, it finds all the bindings that match the current
event history, selects the most specific binding using the priority
mechanism described in the documentation for \fBbind\fR,
and invokes the script for that binding.
If there are no matching bindings for a particular object, then
the object is skipped.
\fBTk_BindEvent\fR continues through all of the objects, handling
exceptions such as errors, \fBbreak\fR, and \fBcontinue\fR as
described in the documentation for \fBbind\fR.

.SH KEYWORDS
binding, event, object, script







|





|





|

|


|
|



















>


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
\fBTk_CreateBinding\fR returns an X event mask for all the events
associated with the bindings.
This information may be useful to invoke \fBXSelectInput\fR to
select relevant events, or to disallow the use of certain events
in bindings.
If an error occurred while creating the binding (e.g., \fIeventString\fR
refers to a non-existent event), then 0 is returned and an error
message is left in \fIinterp->result\fR.
.PP
\fBTk_DeleteBinding\fR removes from \fIbindingTable\fR the
binding given by \fIobject\fR and \fIeventString\fR, if
such a binding exists.
\fBTk_DeleteBinding\fR always returns \fBTCL_OK\fR.
In some cases it may reset \fIinterp->result\fR to the default
empty value.
.PP
\fBTk_GetBinding\fR returns a pointer to the script associated
with \fIeventString\fR and \fIobject\fR in \fIbindingTable\fR.
If no such binding exists then NULL is returned and an error
message is left in \fIinterp->result\fR.
.PP
\fBTk_GetAllBindings\fR returns in \fIinterp->result\fR a list
of all the event strings for which there are bindings in
\fIbindingTable\fR associated with \fIobject\fR.
If there are no bindings for \fIobject\fR then an empty
string is returned in \fIinterp->result\fR.
.PP
\fBTk_DeleteAllBindings\fR deletes all of the bindings in
\fIbindingTable\fR that are associated with \fIobject\fR.
.PP
\fBTk_BindEvent\fR is called to process an event.
It makes a copy of the event in an internal history list associated
with the binding table, then it checks for bindings that match
the event.
\fBTk_BindEvent\fR processes each of the objects pointed to
by \fIobjectPtr\fR in turn.
For each object, it finds all the bindings that match the current
event history, selects the most specific binding using the priority
mechanism described in the documentation for \fBbind\fR,
and invokes the script for that binding.
If there are no matching bindings for a particular object, then
the object is skipped.
\fBTk_BindEvent\fR continues through all of the objects, handling
exceptions such as errors, \fBbreak\fR, and \fBcontinue\fR as
described in the documentation for \fBbind\fR.

.SH KEYWORDS
binding, event, object, script

Changes to doc/CanvPsY.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CanvasPs 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasPsY, Tk_CanvasPsBitmap, Tk_CanvasPsColor, Tk_CanvasPsFont, Tk_CanvasPsPath, Tk_CanvasPsStipple \- utility procedures for generating Postscript for canvases
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CanvasPs 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasPsY, Tk_CanvasPsBitmap, Tk_CanvasPsColor, Tk_CanvasPsFont, Tk_CanvasPsPath, Tk_CanvasPsStipple \- utility procedures for generating Postscript for canvases
.SH SYNOPSIS
.nf
57
58
59
60
61
62
63

64
65
66
67
68
69
70
Pointer to an array of coordinates for one or more
points specified in canvas coordinates.
The order of values in \fIcoordPtr\fR is x1, y1, x2, y2, x3, y3,
and so on.
.AP int numPoints in
Number of points at \fIcoordPtr\fR.
.BE

.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to carry out
common functions related to generating Postscript.
Most of the procedures take a \fIcanvas\fR argument, which
refers to a canvas widget for which Postscript is being
generated.







>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Pointer to an array of coordinates for one or more
points specified in canvas coordinates.
The order of values in \fIcoordPtr\fR is x1, y1, x2, y2, x3, y3,
and so on.
.AP int numPoints in
Number of points at \fIcoordPtr\fR.
.BE

.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to carry out
common functions related to generating Postscript.
Most of the procedures take a \fIcanvas\fR argument, which
refers to a canvas widget for which Postscript is being
generated.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
Canvas x coordinates can be used directly in Postscript without
transformation.
.PP
\fBTk_CanvasPsBitmap\fR generates Postscript to describe a region
of a bitmap.
The Postscript is generated in proper image data format for Postscript,
i.e., as data between angle brackets, one bit per pixel.
The Postscript is appended to the result of interpreter \fIinterp\fR
and \fBTCL_OK\fR is returned unless an error occurs, in which case
\fBTCL_ERROR\fR is returned and the interpreter result is overwritten
with an error message.
.PP
\fBTk_CanvasPsColor\fR generates Postscript to set the current color
to correspond to its \fIcolorPtr\fR argument, taking into account any
color map specified in the \fBpostscript\fR command.
It appends the Postscript to the interpreter \fIinterp\fR's result and returns
\fBTCL_OK\fR unless an error occurs, in which case \fBTCL_ERROR\fR is
returned and the interpreter's result is overwritten with an error message.
.PP
\fBTk_CanvasPsFont\fR generates Postscript that sets the current font
to match \fItkFont\fR as closely as possible.
\fBTk_CanvasPsFont\fR takes into account any font map specified
in the \fBpostscript\fR command, and it does
the best it can at mapping X fonts to Postscript fonts.
It appends the Postscript to interpreter \fIinterp\fR's result and
returns \fBTCL_OK\fR unless an error occurs, in which case
\fBTCL_ERROR\fR is returned and the interpreter's result is
overwritten with an error message.
.PP
\fBTk_CanvasPsPath\fR generates Postscript to set the current path
to the set of points given by \fIcoordPtr\fR and \fInumPoints\fR.
It appends the resulting Postscript to the result of interpreter \fIinterp\fR.
.PP
\fBTk_CanvasPsStipple\fR generates Postscript that will fill the
current path in stippled fashion.
It uses \fIbitmap\fR as the stipple pattern and the current Postscript
color;  ones in the stipple bitmap are drawn in the current color, and
zeroes are not drawn at all.
The Postscript is appended to interpreter \fIinterp\fR's result and
\fBTCL_OK\fR is returned, unless an error occurs, in which case
\fBTCL_ERROR\fR is returned and the interpreter's result is
overwritten with an error message.

.SH KEYWORDS
bitmap, canvas, color, font, path, Postscript, stipple







|
|
<
|




|
|
|






|
|
<
|



|






|
|
<
|
>


79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
Canvas x coordinates can be used directly in Postscript without
transformation.
.PP
\fBTk_CanvasPsBitmap\fR generates Postscript to describe a region
of a bitmap.
The Postscript is generated in proper image data format for Postscript,
i.e., as data between angle brackets, one bit per pixel.
The Postscript is appended to \fIinterp->result\fR and \fBTCL_OK\fR is returned
unless an error occurs, in which case \fBTCL_ERROR\fR is returned and

\fIinterp->result\fR is overwritten with an error message.
.PP
\fBTk_CanvasPsColor\fR generates Postscript to set the current color
to correspond to its \fIcolorPtr\fR argument, taking into account any
color map specified in the \fBpostscript\fR command.
It appends the Postscript to \fIinterp->result\fR and returns
\fBTCL_OK\fR unless an error occurs, in which case \fBTCL_ERROR\fR is returned and
\fIinterp->result\fR is overwritten with an error message.
.PP
\fBTk_CanvasPsFont\fR generates Postscript that sets the current font
to match \fItkFont\fR as closely as possible.
\fBTk_CanvasPsFont\fR takes into account any font map specified
in the \fBpostscript\fR command, and it does
the best it can at mapping X fonts to Postscript fonts.
It appends the Postscript to \fIinterp->result\fR and returns \fBTCL_OK\fR
unless an error occurs, in which case \fBTCL_ERROR\fR is returned and

\fIinterp->result\fR is overwritten with an error message.
.PP
\fBTk_CanvasPsPath\fR generates Postscript to set the current path
to the set of points given by \fIcoordPtr\fR and \fInumPoints\fR.
It appends the resulting Postscript to \fIinterp->result\fR.
.PP
\fBTk_CanvasPsStipple\fR generates Postscript that will fill the
current path in stippled fashion.
It uses \fIbitmap\fR as the stipple pattern and the current Postscript
color;  ones in the stipple bitmap are drawn in the current color, and
zeroes are not drawn at all.
The Postscript is appended to \fIinterp->result\fR and \fBTCL_OK\fR is
returned, unless an error occurs, in which case \fBTCL_ERROR\fR is returned and

\fIinterp->result\fR is overwritten with an error message.

.SH KEYWORDS
bitmap, canvas, color, font, path, Postscript, stipple

Changes to doc/CanvTkwin.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CanvasTkwin 3 4.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasTkwin, Tk_CanvasGetCoord, Tk_CanvasDrawableCoords, Tk_CanvasSetStippleOrigin, Tk_CanvasWindowCoords, Tk_CanvasEventuallyRedraw, Tk_CanvasTagsOption \- utility procedures for canvas type managers
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CanvasTkwin 3 4.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasTkwin, Tk_CanvasGetCoord, Tk_CanvasDrawableCoords, Tk_CanvasSetStippleOrigin, Tk_CanvasWindowCoords, Tk_CanvasEventuallyRedraw, Tk_CanvasTagsOption \- utility procedures for canvas type managers
.SH SYNOPSIS
.nf
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
.AP int x2 in
Right edge of the region that needs redisplay.  Only pixels to
the left of this coordinate need to be redisplayed.
.AP int y2 in
Bottom edge of the region that needs redisplay.  Only pixels above
this coordinate need to be redisplayed.
.BE

.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to perform various
utility functions.
.PP
\fBTk_CanvasTkwin\fR returns the Tk_Window associated with a particular
canvas.
.PP
\fBTk_CanvasGetCoord\fR translates a string specification of a
coordinate (such as \fB2p\fR or \fB1.6c\fR) into a double-precision
canvas coordinate.
If \fIstring\fR is a valid coordinate description then \fBTk_CanvasGetCoord\fR
stores the corresponding canvas coordinate at *\fIdoublePtr\fR
and returns \fBTCL_OK\fR.
Otherwise it stores an error message in the interpreter result and
returns \fBTCL_ERROR\fR.
.PP
\fBTk_CanvasDrawableCoords\fR is called by type managers during
redisplay to compute where to draw things.
Given \fIx\fR and \fIy\fR coordinates in the space of the
canvas, \fBTk_CanvasDrawableCoords\fR computes the corresponding
pixel in the drawable that is currently being used for redisplay;







>














|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
.AP int x2 in
Right edge of the region that needs redisplay.  Only pixels to
the left of this coordinate need to be redisplayed.
.AP int y2 in
Bottom edge of the region that needs redisplay.  Only pixels above
this coordinate need to be redisplayed.
.BE

.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to perform various
utility functions.
.PP
\fBTk_CanvasTkwin\fR returns the Tk_Window associated with a particular
canvas.
.PP
\fBTk_CanvasGetCoord\fR translates a string specification of a
coordinate (such as \fB2p\fR or \fB1.6c\fR) into a double-precision
canvas coordinate.
If \fIstring\fR is a valid coordinate description then \fBTk_CanvasGetCoord\fR
stores the corresponding canvas coordinate at *\fIdoublePtr\fR
and returns \fBTCL_OK\fR.
Otherwise it stores an error message in \fIinterp->result\fR and
returns \fBTCL_ERROR\fR.
.PP
\fBTk_CanvasDrawableCoords\fR is called by type managers during
redisplay to compute where to draw things.
Given \fIx\fR and \fIy\fR coordinates in the space of the
canvas, \fBTk_CanvasDrawableCoords\fR computes the corresponding
pixel in the drawable that is currently being used for redisplay;
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
.PP
\fBTk_CanvasTagsParseProc\fR and \fBTk_CanvasTagsPrintProc\fR are
procedures that handle the \fB\-tags\fR option for canvas items.
The code of a canvas type manager will not call these procedures
directly, but will use their addresses to create a \fBTk_CustomOption\fR
structure for the \fB\-tags\fR option.   The code typically looks
like this:
.PP
.CS
static const Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    ...
    {TK_CONFIG_CUSTOM, "\-tags", NULL, NULL,
        NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    ...
};
.CE

.SH KEYWORDS
canvas, focus, item type, redisplay, selection, type manager







<

|
|


|

|
|



>


138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
.PP
\fBTk_CanvasTagsParseProc\fR and \fBTk_CanvasTagsPrintProc\fR are
procedures that handle the \fB\-tags\fR option for canvas items.
The code of a canvas type manager will not call these procedures
directly, but will use their addresses to create a \fBTk_CustomOption\fR
structure for the \fB\-tags\fR option.   The code typically looks
like this:

.CS
static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    ...
    {TK_CONFIG_CUSTOM, "\-tags", (char *) NULL, (char *) NULL,
        (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    ...
};
.CE

.SH KEYWORDS
canvas, focus, item type, redisplay, selection, type manager

Changes to doc/CanvTxtInfo.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
'\"
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CanvasTextInfo 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasTextInfo \- additional information for managing text items in canvases
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_CanvasTextInfo *
\fBTk_CanvasGetTextInfo\fR(\fIcanvas\fR)
.SH ARGUMENTS
.AS Tk_Canvas canvas
.AP Tk_Canvas canvas in
A token that identifies a particular canvas widget.
.BE

.SH DESCRIPTION
.PP
Textual canvas items are somewhat more complicated to manage than
other items, due to things like the selection and the input focus.
\fBTk_CanvasGetTextInfo\fR may be invoked by a type manager
to obtain additional information needed for items that display text.
The return value from \fBTk_CanvasGetTextInfo\fR is a pointer to





|
















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CanvasTextInfo 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CanvasTextInfo \- additional information for managing text items in canvases
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_CanvasTextInfo *
\fBTk_CanvasGetTextInfo\fR(\fIcanvas\fR)
.SH ARGUMENTS
.AS Tk_Canvas canvas
.AP Tk_Canvas canvas in
A token that identifies a particular canvas widget.
.BE

.SH DESCRIPTION
.PP
Textual canvas items are somewhat more complicated to manage than
other items, due to things like the selection and the input focus.
\fBTk_CanvasGetTextInfo\fR may be invoked by a type manager
to obtain additional information needed for items that display text.
The return value from \fBTk_CanvasGetTextInfo\fR is a pointer to
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    int \fIselectAnchor\fR;
    Tk_3DBorder \fIinsertBorder\fR;
    int \fIinsertWidth\fR;
    int \fIinsertBorderWidth\fR;
    Tk_Item *\fIfocusItemPtr\fR;
    int \fIgotFocus\fR;
    int \fIcursorOn\fR;
} \fBTk_CanvasTextInfo\fR;
.CE
The \fBselBorder\fR field identifies a Tk_3DBorder that should be
used for drawing the background under selected text.
\fIselBorderWidth\fR gives the width of the raised border around
selected text, in pixels.
\fIselFgColorPtr\fR points to an XColor that describes the foreground
color to be used when drawing selected text.







|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    int \fIselectAnchor\fR;
    Tk_3DBorder \fIinsertBorder\fR;
    int \fIinsertWidth\fR;
    int \fIinsertBorderWidth\fR;
    Tk_Item *\fIfocusItemPtr\fR;
    int \fIgotFocus\fR;
    int \fIcursorOn\fR;
} Tk_CanvasTextInfo;
.CE
The \fBselBorder\fR field identifies a Tk_3DBorder that should be
used for drawing the background under selected text.
\fIselBorderWidth\fR gives the width of the raised border around
selected text, in pixels.
\fIselFgColorPtr\fR points to an XColor that describes the foreground
color to be used when drawing selected text.
92
93
94
95
96
97
98

99
100
Type managers may change \fIselectFirst\fR, \fIselectLast\fR, and
\fIselectAnchor\fR to adjust for insertions and deletions in the
item (but only if the item is the current owner of the selection or
anchor, as determined by \fIselItemPtr\fR or \fIanchorItemPtr\fR).
If all of the selected text in the item is deleted, the item should
set \fIselItemPtr\fR to NULL to indicate that there is no longer a
selection.

.SH KEYWORDS
canvas, focus, insertion cursor, selection, selection anchor, text







>


93
94
95
96
97
98
99
100
101
102
Type managers may change \fIselectFirst\fR, \fIselectLast\fR, and
\fIselectAnchor\fR to adjust for insertions and deletions in the
item (but only if the item is the current owner of the selection or
anchor, as determined by \fIselItemPtr\fR or \fIanchorItemPtr\fR).
If all of the selected text in the item is deleted, the item should
set \fIselItemPtr\fR to NULL to indicate that there is no longer a
selection.

.SH KEYWORDS
canvas, focus, insertion cursor, selection, selection anchor, text

Changes to doc/Clipboard.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ClipboardClear 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ClipboardClear, Tk_ClipboardAppend \- Manage the clipboard
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ClipboardClear 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ClipboardClear, Tk_ClipboardAppend \- Manage the clipboard
.SH SYNOPSIS
.nf
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
Window that determines which display's clipboard to manipulate.
.AP Atom target in
Conversion type for this clipboard item;  has same meaning as
\fItarget\fR argument to \fBTk_CreateSelHandler\fR.
.AP Atom format in
Representation to use when data is retrieved;  has same meaning as
\fIformat\fR argument to \fBTk_CreateSelHandler\fR.
.AP "const char" *buffer in
Null terminated string containing the data to be appended to the clipboard.
.BE

.SH DESCRIPTION
.PP
These two procedures manage the clipboard for Tk.
The clipboard is typically managed by calling \fBTk_ClipboardClear\fR
once, then calling \fBTk_ClipboardAppend\fR to add data for any
number of targets.
.PP
\fBTk_ClipboardClear\fR claims the CLIPBOARD selection and frees any
data items previously stored on the clipboard in this application.
It normally returns \fBTCL_OK\fR, but if an error occurs it returns
\fBTCL_ERROR\fR and leaves an error message in interpreter
\fIinterp\fR's result.
\fBTk_ClipboardClear\fR must be called before a sequence of
\fBTk_ClipboardAppend\fR calls can be issued.
.PP
\fBTk_ClipboardAppend\fR appends a buffer of data to the clipboard.
The first buffer for a given \fItarget\fR determines the \fIformat\fR
for that \fItarget\fR.
Any successive appends for that \fItarget\fR must have
the same format or an error will be returned.
\fBTk_ClipboardAppend\fR returns \fBTCL_OK\fR if the buffer is
successfully copied onto the clipboard.  If the clipboard is not
currently owned by the application, either
because \fBTk_ClipboardClear\fR has not been called or because
ownership of the clipboard has changed since the last call to
\fBTk_ClipboardClear\fR,
\fBTk_ClipboardAppend\fR returns \fBTCL_ERROR\fR and leaves an error
message in the result of interpreter \fIinterp\fR.
.PP
In order to guarantee atomicity, no event handling should occur
between \fBTk_ClipboardClear\fR and the following
\fBTk_ClipboardAppend\fR calls (otherwise someone could retrieve
a partially completed clipboard or claim ownership away from
this application).
.PP
\fBTk_ClipboardClear\fR may invoke callbacks, including arbitrary
Tcl scripts, as a result of losing the CLIPBOARD selection, so
any calling function should take care to be re-entrant at the point
\fBTk_ClipboardClear\fR is invoked.

.SH KEYWORDS
append, clipboard, clear, format, type







|


>








|

|
<














|
|









|

>


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Window that determines which display's clipboard to manipulate.
.AP Atom target in
Conversion type for this clipboard item;  has same meaning as
\fItarget\fR argument to \fBTk_CreateSelHandler\fR.
.AP Atom format in
Representation to use when data is retrieved;  has same meaning as
\fIformat\fR argument to \fBTk_CreateSelHandler\fR.
.AP char *buffer in
Null terminated string containing the data to be appended to the clipboard.
.BE

.SH DESCRIPTION
.PP
These two procedures manage the clipboard for Tk.
The clipboard is typically managed by calling \fBTk_ClipboardClear\fR
once, then calling \fBTk_ClipboardAppend\fR to add data for any
number of targets.
.PP
\fBTk_ClipboardClear\fR claims the CLIPBOARD selection and frees any
data items previously stored on the clipboard in this application.  
It normally returns \fBTCL_OK\fR, but if an error occurs it returns
\fBTCL_ERROR\fR and leaves an error message in \fIinterp->result\fR.

\fBTk_ClipboardClear\fR must be called before a sequence of
\fBTk_ClipboardAppend\fR calls can be issued.
.PP
\fBTk_ClipboardAppend\fR appends a buffer of data to the clipboard.
The first buffer for a given \fItarget\fR determines the \fIformat\fR
for that \fItarget\fR.
Any successive appends for that \fItarget\fR must have
the same format or an error will be returned.
\fBTk_ClipboardAppend\fR returns \fBTCL_OK\fR if the buffer is
successfully copied onto the clipboard.  If the clipboard is not
currently owned by the application, either
because \fBTk_ClipboardClear\fR has not been called or because
ownership of the clipboard has changed since the last call to
\fBTk_ClipboardClear\fR,
\fBTk_ClipboardAppend\fR returns \fBTCL_ERROR\fR and leaves an error message in
\fIinterp->result\fR.
.PP
In order to guarantee atomicity, no event handling should occur
between \fBTk_ClipboardClear\fR and the following
\fBTk_ClipboardAppend\fR calls (otherwise someone could retrieve
a partially completed clipboard or claim ownership away from
this application).
.PP
\fBTk_ClipboardClear\fR may invoke callbacks, including arbitrary
Tcl scripts, as a result of losing the CLIPBOARD selection, so
any calling function should take care to be reentrant at the point
\fBTk_ClipboardClear\fR is invoked.

.SH KEYWORDS
append, clipboard, clear, format, type

Changes to doc/ClrSelect.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36

37
38
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ClearSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ClearSelection \- Deselect a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ClearSelection\fR(\fItkwin, selection\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
The selection will be cleared from the display containing this
window.
.AP Atom selection in
The name of selection to be cleared.
.BE

.SH DESCRIPTION
.PP
\fBTk_ClearSelection\fR cancels the selection specified by the atom
\fIselection\fR for the display containing \fItkwin\fR.
The selection need not be in \fItkwin\fR itself or even in
\fItkwin\fR's application.
If there is a window anywhere on \fItkwin\fR's display that
owns \fIselection\fR, the window will be notified and the
selection will be cleared.
If there is no owner for \fIselection\fR on the display, then the
procedure has no effect.

.SH KEYWORDS
clear, selection






|


















>


|








>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ClearSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ClearSelection \- Deselect a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ClearSelection\fR(\fItkwin, selection\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
The selection will be cleared from the display containing this
window.
.AP Atom selection in
The name of selection to be cleared.
.BE

.SH DESCRIPTION
.PP
\fBTk_ClearSelection\fR cancels the selection specified by the atom 
\fIselection\fR for the display containing \fItkwin\fR.
The selection need not be in \fItkwin\fR itself or even in
\fItkwin\fR's application.
If there is a window anywhere on \fItkwin\fR's display that
owns \fIselection\fR, the window will be notified and the
selection will be cleared.
If there is no owner for \fIselection\fR on the display, then the
procedure has no effect.

.SH KEYWORDS
clear, selection

Changes to doc/ConfigWidg.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ConfigureWidget 3 4.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, Tk_FreeOptions \- process configuration options for widgets
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ConfigureWidget(\fIinterp, tkwin, specs, argc, argv, widgRec, flags\fB)\fR
.sp
int
\fBTk_ConfigureInfo(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
int
\fBTk_ConfigureValue(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
\fBTk_FreeOptions(\fIspecs, widgRec, display, flags\fB)\fR
.SH ARGUMENTS
.AS char *widgRec in/out
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window used to represent widget (needed to set up X resources).
.AP "const Tk_ConfigSpec" *specs in
Pointer to table specifying legal configuration options for this
widget.
.AP int argc in
Number of arguments in \fIargv\fR.
.AP "const char" **argv in
Command-line options for configuring widget.
.AP char *widgRec in/out






|




















|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ConfigureWidget 3 4.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, Tk_FreeOptions \- process configuration options for widgets
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ConfigureWidget(\fIinterp, tkwin, specs, argc, argv, widgRec, flags\fB)\fR
.sp
int
\fBTk_ConfigureInfo(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
int
\fBTk_ConfigureValue(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
\fBTk_FreeOptions(\fIspecs, widgRec, display, flags\fB)\fR
.SH ARGUMENTS
.AS Tk_ConfigSpec *widgRec in/out
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window used to represent widget (needed to set up X resources).
.AP Tk_ConfigSpec *specs in
Pointer to table specifying legal configuration options for this
widget.
.AP int argc in
Number of arguments in \fIargv\fR.
.AP "const char" **argv in
Command-line options for configuring widget.
.AP char *widgRec in/out
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
option.  If NULL, then information is returned for all available
options.
.AP Display *display in
Display containing widget whose record is being freed;  needed in
order to free up resources.
.BE
.SH DESCRIPTION
.PP
Note: \fBTk_ConfigureWidget\fR should be replaced with the new
\fBTcl_Obj\fR based API \fBTk_SetOptions\fR.  The old interface is
retained for backward compatibility.
.PP
\fBTk_ConfigureWidget\fR is called to configure various aspects of a
widget, such as colors, fonts, border width, etc.
It is intended as a convenience procedure to reduce the amount







|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
option.  If NULL, then information is returned for all available
options.
.AP Display *display in
Display containing widget whose record is being freed;  needed in
order to free up resources.
.BE
.SH DESCRIPTION
.PP 
Note: \fBTk_ConfigureWidget\fR should be replaced with the new
\fBTcl_Obj\fR based API \fBTk_SetOptions\fR.  The old interface is
retained for backward compatibility.
.PP
\fBTk_ConfigureWidget\fR is called to configure various aspects of a
widget, such as colors, fonts, border width, etc.
It is intended as a convenience procedure to reduce the amount
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
\fIargv\fR) to fill in fields of a record (\fIwidgRec\fR).
It uses the option database and defaults specified in \fIspecs\fR
to fill in fields of \fIwidgRec\fR that are not specified in \fIargv\fR.
\fBTk_ConfigureWidget\fR normally returns the value \fBTCL_OK\fR; in this
case it does not modify \fIinterp\fR.
If an error
occurs then \fBTCL_ERROR\fR is returned and \fBTk_ConfigureWidget\fR will
leave an error message in interpreter \fIinterp\fR's result in the standard Tcl
fashion.
In the event of an error return, some of the fields of \fIwidgRec\fR
could already have been set, if configuration information for them
was successfully processed before the error occurred.
The other fields will be set to reasonable initial values so that
\fBTk_FreeOptions\fR can be called for cleanup.
.PP
The \fIspecs\fR array specifies the kinds of configuration options
expected by the widget.  Each of its entries specifies one configuration
option and has the following structure:
.CS
typedef struct {
    int \fItype\fR;
    const char *\fIargvName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    size_t \fIoffset\fR;
    int \fIspecFlags\fR;
    const Tk_CustomOption *\fIcustomPtr\fR;
} \fBTk_ConfigSpec\fR;
.CE
The \fItype\fR field indicates what type of configuration option this is
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the
value of the option (more on this below).
The \fIargvName\fR field is a string such as
.QW \-font







|













|
|
|
|
|

|
|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
\fIargv\fR) to fill in fields of a record (\fIwidgRec\fR).
It uses the option database and defaults specified in \fIspecs\fR
to fill in fields of \fIwidgRec\fR that are not specified in \fIargv\fR.
\fBTk_ConfigureWidget\fR normally returns the value \fBTCL_OK\fR; in this
case it does not modify \fIinterp\fR.
If an error
occurs then \fBTCL_ERROR\fR is returned and \fBTk_ConfigureWidget\fR will
leave an error message in \fIinterp->result\fR in the standard Tcl
fashion.
In the event of an error return, some of the fields of \fIwidgRec\fR
could already have been set, if configuration information for them
was successfully processed before the error occurred.
The other fields will be set to reasonable initial values so that
\fBTk_FreeOptions\fR can be called for cleanup.
.PP
The \fIspecs\fR array specifies the kinds of configuration options
expected by the widget.  Each of its entries specifies one configuration
option and has the following structure:
.CS
typedef struct {
    int \fItype\fR;
    char *\fIargvName\fR;
    char *\fIdbName\fR;
    char *\fIdbClass\fR;
    char *\fIdefValue\fR;
    int \fIoffset\fR;
    int \fIspecFlags\fR;
    Tk_CustomOption *\fIcustomPtr\fR;
} Tk_ConfigSpec;
.CE
The \fItype\fR field indicates what type of configuration option this is
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the
value of the option (more on this below).
The \fIargvName\fR field is a string such as
.QW \-font
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to
contain information relevant to the manager of the widget;  its exact
type is unknown to \fBTk_ConfigureWidget\fR.  The \fIoffset\fR field
of each \fIspecs\fR entry indicates where in \fIwidgRec\fR to store
the information about this configuration option.  You should use the
\fBoffsetof\fR macro to generate \fIoffset\fR values.  The location

indicated by \fIwidgRec\fR and \fIoffset\fR will be referred to as the
.QW target
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR
The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR.
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.







|
>
|










|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to
contain information relevant to the manager of the widget;  its exact
type is unknown to \fBTk_ConfigureWidget\fR.  The \fIoffset\fR field
of each \fIspecs\fR entry indicates where in \fIwidgRec\fR to store
the information about this configuration option.  You should use the
\fBTk_Offset\fR macro to generate \fIoffset\fR values (see below for
a description of \fBTk_Offset\fR).  The location indicated by
\fIwidgRec\fR and \fIoffset\fR will be referred to as the
.QW target
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR
The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR. 
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR and the value
is an empty string then the target will be set to NULL.
.TP
\fBTK_CONFIG_WINDOW\fR
The value must be a window path name.  It is translated to a
\fBTk_Window\fR token and the token is stored in the target.

.SH "GROUPED ENTRIES"
.PP
In some cases it is useful to generate multiple resources from
a single configuration value.  For example, a color name might
be used both to generate the background color for a widget (using
\fBTK_CONFIG_COLOR\fR) and to generate a 3-D border to draw around the
widget (using \fBTK_CONFIG_BORDER\fR).  In cases like this it is possible
to specify that several consecutive entries in \fIspecs\fR are to
be treated as a group.  The first entry is used to determine a value
(using its \fIargvName\fR, \fIdbName\fR,
\fIdbClass\fR, and \fIdefValue\fR fields).  The value will be processed
several times (one for each entry in the group), generating multiple
different resources and modifying multiple targets within \fIwidgRec\fR.
Each of the entries after the first must have a NULL value in its
\fIargvName\fR field;  this indicates that the entry is to be grouped
with the entry that precedes it.  Only the \fItype\fR and \fIoffset\fR
fields are used from these follow-on entries.

.SH "FLAGS"
.PP
The \fIflags\fR argument passed to \fBTk_ConfigureWidget\fR is used
in conjunction with the \fIspecFlags\fR fields in the entries of \fIspecs\fR
to provide additional control over the processing of configuration
options.  These values are used in three different ways as
described below.







>

















>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR and the value
is an empty string then the target will be set to NULL.
.TP
\fBTK_CONFIG_WINDOW\fR
The value must be a window path name.  It is translated to a
\fBTk_Window\fR token and the token is stored in the target.

.SH "GROUPED ENTRIES"
.PP
In some cases it is useful to generate multiple resources from
a single configuration value.  For example, a color name might
be used both to generate the background color for a widget (using
\fBTK_CONFIG_COLOR\fR) and to generate a 3-D border to draw around the
widget (using \fBTK_CONFIG_BORDER\fR).  In cases like this it is possible
to specify that several consecutive entries in \fIspecs\fR are to
be treated as a group.  The first entry is used to determine a value
(using its \fIargvName\fR, \fIdbName\fR,
\fIdbClass\fR, and \fIdefValue\fR fields).  The value will be processed
several times (one for each entry in the group), generating multiple
different resources and modifying multiple targets within \fIwidgRec\fR.
Each of the entries after the first must have a NULL value in its
\fIargvName\fR field;  this indicates that the entry is to be grouped
with the entry that precedes it.  Only the \fItype\fR and \fIoffset\fR
fields are used from these follow-on entries.

.SH "FLAGS"
.PP
The \fIflags\fR argument passed to \fBTk_ConfigureWidget\fR is used
in conjunction with the \fIspecFlags\fR fields in the entries of \fIspecs\fR
to provide additional control over the processing of configuration
options.  These values are used in three different ways as
described below.
427
428
429
430
431
432
433

434
435
436
437
438

439
440
441
442
443
444
445
This flag provides a performance optimization where it is expensive
to process the default string:  the client can compute the default
once, save the value, and provide it before calling
\fBTk_ConfigureWidget\fR.
.TP
\fBTK_CONFIG_OPTION_SPECIFIED\fR
This bit is

deprecated. It used to be set and cleared by \fBTk_ConfigureWidget\fR
so that callers could detect what entries were specified in
\fIargv\fR, but it was removed because it was inherently
thread-unsafe. Code that wishes to detect what options were specified
should use \fBTk_SetOptions\fR instead.

.PP
The \fBTK_CONFIG_MONO_ONLY\fR and \fBTK_CONFIG_COLOR_ONLY\fR flags are typically
used to specify different default values for
monochrome and color displays.  This is done by creating two
entries in \fIspecs\fR that are identical except for their
\fIdefValue\fR and \fIspecFlags\fR fields.  One entry should have
the value \fBTK_CONFIG_MONO_ONLY\fR in its \fIspecFlags\fR and the







>





>







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
This flag provides a performance optimization where it is expensive
to process the default string:  the client can compute the default
once, save the value, and provide it before calling
\fBTk_ConfigureWidget\fR.
.TP
\fBTK_CONFIG_OPTION_SPECIFIED\fR
This bit is
.VS 8.5
deprecated. It used to be set and cleared by \fBTk_ConfigureWidget\fR
so that callers could detect what entries were specified in
\fIargv\fR, but it was removed because it was inherently
thread-unsafe. Code that wishes to detect what options were specified
should use \fBTk_SetOptions\fR instead.
.VE 8.5
.PP
The \fBTK_CONFIG_MONO_ONLY\fR and \fBTK_CONFIG_COLOR_ONLY\fR flags are typically
used to specify different default values for
monochrome and color displays.  This is done by creating two
entries in \fIspecs\fR that are identical except for their
\fIdefValue\fR and \fIspecFlags\fR fields.  One entry should have
the value \fBTK_CONFIG_MONO_ONLY\fR in its \fIspecFlags\fR and the
464
465
466
467
468
469
470









471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
for N different widget types, then N of the high-order bits will
be used.  Each \fIspecs\fR entry will have one of more of those
bits set in its \fIspecFlags\fR field to indicate the widget types
for which this entry is valid.  When calling \fBTk_ConfigureWidget\fR,
\fIflags\fR will have a single one of these bits set to select the
entries for the desired widget type.  For a working example of
this feature, see the code in tkButton.c.









.SH TK_CONFIGUREINFO
.PP
The \fBTk_ConfigureInfo\fR procedure may be used to obtain
information about one or all of the options for a given widget.
Given a token for a window (\fItkwin\fR), a table describing the
configuration options for a class of widgets (\fIspecs\fR), a
pointer to a widget record containing the current information for
a widget (\fIwidgRec\fR), and a NULL \fIargvName\fR argument,
\fBTk_ConfigureInfo\fR generates a string describing all of the
configuration options for the window.  The string is placed
in interpreter \fIinterp\fR's result.  Under normal circumstances
it returns \fBTCL_OK\fR;  if an error occurs then it returns \fBTCL_ERROR\fR
and the interpreter's result will contain an error message.
.PP
If \fIargvName\fR is NULL, then the value left in
the interpreter's result by \fBTk_ConfigureInfo\fR
consists of a list of one or more entries, each of which describes
one configuration option (i.e. one entry in \fIspecs\fR).  Each
entry in the list will contain either two or five values.  If the
corresponding entry in \fIspecs\fR has type \fBTK_CONFIG_SYNONYM\fR, then
the list will contain two values:  the \fIargvName\fR for the entry
and the \fIdbName\fR (synonym name).  Otherwise the list will contain
five values:  \fIargvName\fR, \fIdbName\fR, \fIdbClass\fR, \fIdefValue\fR,
and current value.  The current value is computed from the appropriate
field of \fIwidgRec\fR by calling procedures like \fBTk_NameOfColor\fR.
.PP
If the \fIargvName\fR argument to \fBTk_ConfigureInfo\fR is non-NULL,
then it indicates a single option, and information is returned only
for that option.  The string placed in the interpreter's result will be
a list containing two or five values as described above;  this will
be identical to the corresponding sublist that would have been returned
if \fIargvName\fR had been NULL.
.PP
The \fIflags\fR argument to \fBTk_ConfigureInfo\fR is used to restrict
the \fIspecs\fR entries to consider, just as for \fBTk_ConfigureWidget\fR.

.SH TK_CONFIGUREVALUE
.PP
\fBTk_ConfigureValue\fR takes arguments similar to \fBTk_ConfigureInfo\fR;
instead of returning a list of values, it just returns the current value
of the option given by \fIargvName\fR (\fIargvName\fR must not be NULL).
The value is returned in interpreter \fIinterp\fR's result and \fBTCL_OK\fR is
normally returned as the procedure's result.
If an error occurs in \fBTk_ConfigureValue\fR (e.g., \fIargvName\fR is
not a valid option name), \fBTCL_ERROR\fR is returned and an error message
is left in the interpreter's result.
This procedure is typically called to implement \fBcget\fR widget
commands.

.SH TK_FREEOPTIONS
.PP
The \fBTk_FreeOptions\fR procedure may be invoked during widget cleanup
to release all of the resources associated with configuration options.
It scans through \fIspecs\fR and for each entry corresponding to a
resource that must be explicitly freed (e.g. those with
type \fBTK_CONFIG_COLOR\fR), it frees the resource in the widget record.
If the field in the widget record does not refer to a resource (e.g.
it contains a null pointer) then no resource is freed for that
entry.
After freeing a resource, \fBTk_FreeOptions\fR sets the
corresponding field of the widget record to null.

.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with additional
configuration types by writing procedures to parse and print options
of the a type and creating a structure pointing to those procedures:
.CS
typedef struct Tk_CustomOption {
    Tk_OptionParseProc *\fIparseProc\fR;
    Tk_OptionPrintProc *\fIprintProc\fR;
    ClientData \fIclientData\fR;
} \fBTk_CustomOption\fR;

typedef int \fBTk_OptionParseProc\fR(
        ClientData \fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        Tk_Window \fItkwin\fR,
        char *\fIvalue\fR,
        char *\fIwidgRec\fR,
        int \fIoffset\fR);

typedef const char *\fBTk_OptionPrintProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR,
        char *\fIwidgRec\fR,
        int \fIoffset\fR,
        Tcl_FreeProc **\fIfreeProcPtr\fR);
.CE
The Tk_CustomOption structure contains three fields, which are pointers
to the two procedures and a \fIclientData\fR value to be passed to those
procedures when they are invoked.  The \fIclientData\fR value typically
points to a structure containing information that is needed by the
procedures when they are parsing and printing options.
.PP







>
>
>
>
>
>
>
>
>










|

|


|












|






>





|



|


>












>










|

|
|
|
|
|
|
|

|
|
|
|
|
|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
for N different widget types, then N of the high-order bits will
be used.  Each \fIspecs\fR entry will have one of more of those
bits set in its \fIspecFlags\fR field to indicate the widget types
for which this entry is valid.  When calling \fBTk_ConfigureWidget\fR,
\fIflags\fR will have a single one of these bits set to select the
entries for the desired widget type.  For a working example of
this feature, see the code in tkButton.c.

.SH TK_OFFSET
.PP
The \fBTk_Offset\fR macro is provided as a safe way of generating
the \fIoffset\fR values for entries in Tk_ConfigSpec structures.
It takes two arguments:  the name of a type of record, and the
name of a field in that record.  It returns the byte offset of
the named field in records of the given type.

.SH TK_CONFIGUREINFO
.PP
The \fBTk_ConfigureInfo\fR procedure may be used to obtain
information about one or all of the options for a given widget.
Given a token for a window (\fItkwin\fR), a table describing the
configuration options for a class of widgets (\fIspecs\fR), a
pointer to a widget record containing the current information for
a widget (\fIwidgRec\fR), and a NULL \fIargvName\fR argument,
\fBTk_ConfigureInfo\fR generates a string describing all of the
configuration options for the window.  The string is placed
in \fIinterp->result\fR.  Under normal circumstances
it returns \fBTCL_OK\fR;  if an error occurs then it returns \fBTCL_ERROR\fR
and \fIinterp->result\fR contains an error message.
.PP
If \fIargvName\fR is NULL, then the value left in
\fIinterp->result\fR by \fBTk_ConfigureInfo\fR
consists of a list of one or more entries, each of which describes
one configuration option (i.e. one entry in \fIspecs\fR).  Each
entry in the list will contain either two or five values.  If the
corresponding entry in \fIspecs\fR has type \fBTK_CONFIG_SYNONYM\fR, then
the list will contain two values:  the \fIargvName\fR for the entry
and the \fIdbName\fR (synonym name).  Otherwise the list will contain
five values:  \fIargvName\fR, \fIdbName\fR, \fIdbClass\fR, \fIdefValue\fR,
and current value.  The current value is computed from the appropriate
field of \fIwidgRec\fR by calling procedures like \fBTk_NameOfColor\fR.
.PP
If the \fIargvName\fR argument to \fBTk_ConfigureInfo\fR is non-NULL,
then it indicates a single option, and information is returned only
for that option.  The string placed in \fIinterp->result\fR will be
a list containing two or five values as described above;  this will
be identical to the corresponding sublist that would have been returned
if \fIargvName\fR had been NULL.
.PP
The \fIflags\fR argument to \fBTk_ConfigureInfo\fR is used to restrict
the \fIspecs\fR entries to consider, just as for \fBTk_ConfigureWidget\fR.

.SH TK_CONFIGUREVALUE
.PP
\fBTk_ConfigureValue\fR takes arguments similar to \fBTk_ConfigureInfo\fR;
instead of returning a list of values, it just returns the current value
of the option given by \fIargvName\fR (\fIargvName\fR must not be NULL).
The value is returned in \fIinterp->result\fR and \fBTCL_OK\fR is
normally returned as the procedure's result.
If an error occurs in \fBTk_ConfigureValue\fR (e.g., \fIargvName\fR is
not a valid option name), \fBTCL_ERROR\fR is returned and an error message
is left in \fIinterp->result\fR.
This procedure is typically called to implement \fBcget\fR widget
commands.

.SH TK_FREEOPTIONS
.PP
The \fBTk_FreeOptions\fR procedure may be invoked during widget cleanup
to release all of the resources associated with configuration options.
It scans through \fIspecs\fR and for each entry corresponding to a
resource that must be explicitly freed (e.g. those with
type \fBTK_CONFIG_COLOR\fR), it frees the resource in the widget record.
If the field in the widget record does not refer to a resource (e.g.
it contains a null pointer) then no resource is freed for that
entry.
After freeing a resource, \fBTk_FreeOptions\fR sets the
corresponding field of the widget record to null.

.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with additional
configuration types by writing procedures to parse and print options
of the a type and creating a structure pointing to those procedures:
.CS
typedef struct Tk_CustomOption {
    Tk_OptionParseProc *\fIparseProc\fR;
    Tk_OptionPrintProc *\fIprintProc\fR;
    ClientData \fIclientData\fR;
} Tk_CustomOption;

typedef int Tk_OptionParseProc(
    ClientData \fIclientData\fR,
    Tcl_Interp *\fIinterp\fR,
    Tk_Window \fItkwin\fR,
    char *\fIvalue\fR,
    char *\fIwidgRec\fR,
    int \fIoffset\fR);

typedef char *Tk_OptionPrintProc(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIwidgRec\fR,
    int \fIoffset\fR,
    Tcl_FreeProc **\fIfreeProcPtr\fR);
.CE
The Tk_CustomOption structure contains three fields, which are pointers
to the two procedures and a \fIclientData\fR value to be passed to those
procedures when they are invoked.  The \fIclientData\fR value typically
points to a structure containing information that is needed by the
procedures when they are parsing and printing options.
.PP
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
record to modify.
The last argument, \fIoffset\fR, gives the offset in bytes from the start
of the widget record to the location where the option value is to
be placed.  The procedure should translate the string to whatever
form is appropriate for the option and store the value in the widget
record.  It should normally return \fBTCL_OK\fR, but if an error occurs
in translating the string to a value then it should return \fBTCL_ERROR\fR
and store an error message in interpreter \fIinterp\fR's result.
.PP
The \fIprintProc\fR procedure is called
by \fBTk_ConfigureInfo\fR to produce a string value describing an
existing option.
Its \fIclientData\fR, \fItkwin\fR, \fIwidgRec\fR, and \fIoffset\fR
arguments all have the same meaning as for Tk_OptionParseProc
procedures.







|







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
record to modify.
The last argument, \fIoffset\fR, gives the offset in bytes from the start
of the widget record to the location where the option value is to
be placed.  The procedure should translate the string to whatever
form is appropriate for the option and store the value in the widget
record.  It should normally return \fBTCL_OK\fR, but if an error occurs
in translating the string to a value then it should return \fBTCL_ERROR\fR
and store an error message in \fIinterp->result\fR.
.PP
The \fIprintProc\fR procedure is called
by \fBTk_ConfigureInfo\fR to produce a string value describing an
existing option.
Its \fIclientData\fR, \fItkwin\fR, \fIwidgRec\fR, and \fIoffset\fR
arguments all have the same meaning as for Tk_OptionParseProc
procedures.
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615
616
617

618
619

620
621
622
623
need not do anything with the \fIfreeProcPtr\fR argument.
.PP
Once \fIparseProc\fR and \fIprintProc\fR have been defined and a
Tk_CustomOption structure has been created for them, options of this
new type may be manipulated with Tk_ConfigSpec entries whose \fItype\fR
fields are \fBTK_CONFIG_CUSTOM\fR and whose \fIcustomPtr\fR fields point
to the Tk_CustomOption structure.

.SH EXAMPLES
.PP
Although the explanation of \fBTk_ConfigureWidget\fR is fairly
complicated, its actual use is pretty straightforward.
The easiest way to get started is to copy the code
from an existing widget.
The library implementation of frames
(tkFrame.c) has a simple configuration table, and the library
implementation of buttons (tkButton.c) has a much more complex
table that uses many of the fancy \fIspecFlags\fR mechanisms.

.SH "SEE ALSO"
Tk_SetOptions(3)

.SH KEYWORDS
anchor, bitmap, boolean, border, cap style, color, configuration options,
cursor, custom, double, font, integer, join style, justify, millimeters,
pixels, relief, synonym, uid







>










>


>




618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
need not do anything with the \fIfreeProcPtr\fR argument.
.PP
Once \fIparseProc\fR and \fIprintProc\fR have been defined and a
Tk_CustomOption structure has been created for them, options of this
new type may be manipulated with Tk_ConfigSpec entries whose \fItype\fR
fields are \fBTK_CONFIG_CUSTOM\fR and whose \fIcustomPtr\fR fields point
to the Tk_CustomOption structure.

.SH EXAMPLES
.PP
Although the explanation of \fBTk_ConfigureWidget\fR is fairly
complicated, its actual use is pretty straightforward.
The easiest way to get started is to copy the code
from an existing widget.
The library implementation of frames
(tkFrame.c) has a simple configuration table, and the library
implementation of buttons (tkButton.c) has a much more complex
table that uses many of the fancy \fIspecFlags\fR mechanisms.

.SH "SEE ALSO"
Tk_SetOptions(3)

.SH KEYWORDS
anchor, bitmap, boolean, border, cap style, color, configuration options,
cursor, custom, double, font, integer, join style, justify, millimeters,
pixels, relief, synonym, uid

Changes to doc/ConfigWind.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ConfigureWindow 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ConfigureWindow, Tk_MoveWindow, Tk_ResizeWindow, Tk_MoveResizeWindow, Tk_SetWindowBorderWidth, Tk_ChangeWindowAttributes, Tk_SetWindowBackground, Tk_SetWindowBackgroundPixmap, Tk_SetWindowBorder, Tk_SetWindowBorderPixmap, Tk_SetWindowColormap, Tk_DefineCursor, Tk_UndefineCursor \- change window configuration or attributes
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ConfigureWindow 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ConfigureWindow, Tk_MoveWindow, Tk_ResizeWindow, Tk_MoveResizeWindow, Tk_SetWindowBorderWidth, Tk_ChangeWindowAttributes, Tk_SetWindowBackground, Tk_SetWindowBackgroundPixmap, Tk_SetWindowBorder, Tk_SetWindowBorderPixmap, Tk_SetWindowColormap, Tk_DefineCursor, Tk_UndefineCursor \- change window configuration or attributes
.SH SYNOPSIS
.nf

Changes to doc/CoordToWin.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CoordsToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CoordsToWindow \- Find window containing a point
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_CoordsToWindow\fR(\fIrootX, rootY, tkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP int rootX in
X-coordinate (in root window coordinates).
.AP int rootY in
Y-coordinate (in root window coordinates).
.AP Tk_Window tkwin in
Token for window that identifies application.
.BE

.SH DESCRIPTION
.PP
\fBTk_CoordsToWindow\fR locates the window that contains a given point.
The point is specified in root coordinates with \fIrootX\fR and
\fIrootY\fR (if a virtual-root window manager is in use then
\fIrootX\fR and \fIrootY\fR are in the coordinate system of the
virtual root window).
The return value from the procedure is a token for the window that
contains the given point.
If the point is not in any window, or if the containing window
is not in the same application as \fItkwin\fR, then NULL is
returned.
.PP
The containing window is decided using the same rules that determine
which window contains the mouse cursor:  if a parent and a child both
contain the point then the child gets preference, and if two siblings
both contain the point then the highest one in the stacking order
(i.e. the one that's visible on the screen) gets preference.

.SH KEYWORDS
containing, coordinates, root window






|




















>


















>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CoordsToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CoordsToWindow \- Find window containing a point
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_CoordsToWindow\fR(\fIrootX, rootY, tkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP int rootX in
X-coordinate (in root window coordinates).
.AP int rootY in
Y-coordinate (in root window coordinates).
.AP Tk_Window tkwin in
Token for window that identifies application.
.BE

.SH DESCRIPTION
.PP
\fBTk_CoordsToWindow\fR locates the window that contains a given point.
The point is specified in root coordinates with \fIrootX\fR and
\fIrootY\fR (if a virtual-root window manager is in use then
\fIrootX\fR and \fIrootY\fR are in the coordinate system of the
virtual root window).
The return value from the procedure is a token for the window that
contains the given point.
If the point is not in any window, or if the containing window
is not in the same application as \fItkwin\fR, then NULL is
returned.
.PP
The containing window is decided using the same rules that determine
which window contains the mouse cursor:  if a parent and a child both
contain the point then the child gets preference, and if two siblings
both contain the point then the highest one in the stacking order
(i.e. the one that's visible on the screen) gets preference.

.SH KEYWORDS
containing, coordinates, root window

Changes to doc/CrtCmHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
'\"
'\" 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.
'\"
.TH Tk_CreateClientMessageHandler 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateClientMessageHandler, Tk_DeleteClientMessageHandler \- associate procedure callback with ClientMessage type X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateClientMessageHandler\fR(\fIproc\fR)
.sp
\fBTk_DeleteClientMessageHandler\fR(\fIproc\fR)
.SH ARGUMENTS
.AP Tk_ClientMessageProc *proc in
Procedure to invoke whenever a ClientMessage X event occurs on any display.
.BE

.SH DESCRIPTION
.PP

\fBTk_CreateClientMessageHandler\fR arranges for \fIproc\fR to be invoked
in the future whenever a ClientMessage X event occurs that is not handled by
\fBWM_PROTOCOL\fR.  \fBTk_CreateClientMessageHandler\fR is intended for use
by applications which need to watch X ClientMessage events, such as drag and
drop applications.
.PP
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_ClientMessageProc\fR:
.CS
typedef int \fBTk_ClientMessageProc\fR(
        Tk_Window \fItkwin\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fItkwin\fR parameter to \fIproc\fR is the Tk window which is
associated with this event.  \fIEventPtr\fR is a pointer to the X event.
.PP
Whenever an X ClientMessage event is processed by \fBTk_HandleEvent\fR,
the \fIproc\fR is called if it was not handled as a \fBWM_PROTOCOL\fR.
The return value from \fIproc\fR is normally 0.
A non-zero return value indicates that the event is not to be handled
further; that is, \fIproc\fR has done all processing that is to be
allowed for the event.
.PP
If there are multiple ClientMessage event handlers, each one is called
for each event, in the order in which they were established.
.PP
\fBTk_DeleteClientMessageHandler\fR may be called to delete a
previously-created ClientMessage event handler: it deletes each handler it
finds that matches the \fIproc\fR argument.  If no such handler exists,
then \fBTk_DeleteClientMessageHandler\fR returns without doing anything.
Although Tk supports it, it's probably a bad idea to have more than one
callback with the same \fIproc\fR argument.

.SH KEYWORDS
bind, callback, event, handler





|
















>


>















|
|
|




















>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'\"
'\" 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.
'\" 
.TH Tk_CreateClientMessageHandler 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateClientMessageHandler, Tk_DeleteClientMessageHandler \- associate procedure callback with ClientMessage type X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateClientMessageHandler\fR(\fIproc\fR)
.sp
\fBTk_DeleteClientMessageHandler\fR(\fIproc\fR)
.SH ARGUMENTS
.AP Tk_ClientMessageProc *proc in
Procedure to invoke whenever a ClientMessage X event occurs on any display.
.BE

.SH DESCRIPTION
.PP

\fBTk_CreateClientMessageHandler\fR arranges for \fIproc\fR to be invoked
in the future whenever a ClientMessage X event occurs that is not handled by
\fBWM_PROTOCOL\fR.  \fBTk_CreateClientMessageHandler\fR is intended for use
by applications which need to watch X ClientMessage events, such as drag and
drop applications.
.PP
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_ClientMessageProc\fR:
.CS
typedef int Tk_ClientMessageProc(
    Tk_Window \fItkwin\fR,
    XEvent *\fIeventPtr\fR);
.CE
The \fItkwin\fR parameter to \fIproc\fR is the Tk window which is
associated with this event.  \fIEventPtr\fR is a pointer to the X event.
.PP
Whenever an X ClientMessage event is processed by \fBTk_HandleEvent\fR,
the \fIproc\fR is called if it was not handled as a \fBWM_PROTOCOL\fR.
The return value from \fIproc\fR is normally 0.
A non-zero return value indicates that the event is not to be handled
further; that is, \fIproc\fR has done all processing that is to be
allowed for the event.
.PP
If there are multiple ClientMessage event handlers, each one is called
for each event, in the order in which they were established.
.PP
\fBTk_DeleteClientMessageHandler\fR may be called to delete a
previously-created ClientMessage event handler: it deletes each handler it
finds that matches the \fIproc\fR argument.  If no such handler exists,
then \fBTk_DeleteClientMessageHandler\fR returns without doing anything.
Although Tk supports it, it's probably a bad idea to have more than one
callback with the same \fIproc\fR argument.

.SH KEYWORDS
bind, callback, event, handler

Changes to doc/CrtConsoleChan.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2007 ActiveState Software Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_InitConsoleChannels 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InitConsoleChannels \- Install the console channels as standard channels
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2007 ActiveState Software Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH Tk_InitConsoleChannels 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InitConsoleChannels \- Install the console channels as standard channels
.SH SYNOPSIS
.nf

Changes to doc/CrtErrHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateErrorHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateErrorHandler, Tk_DeleteErrorHandler \- handle X protocol errors
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateErrorHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateErrorHandler, Tk_DeleteErrorHandler \- handle X protocol errors
.SH SYNOPSIS
.nf
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
.IP [5]
The protocol request to which the error pertains must have been
made when the handler was active (see below for more information).
.PP
\fIProc\fR should have arguments and result that match the
following type:
.CS
typedef int \fBTk_ErrorProc\fR(
        ClientData \fIclientData\fR,
        XErrorEvent *\fIerrEventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTcl_CreateErrorHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to deal with the error.  \fIErrEventPtr\fR is
a pointer to the X error event.







|
|
|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
.IP [5]
The protocol request to which the error pertains must have been
made when the handler was active (see below for more information).
.PP
\fIProc\fR should have arguments and result that match the
following type:
.CS
typedef int Tk_ErrorProc(
    ClientData \fIclientData\fR,
    XErrorEvent *\fIerrEventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTcl_CreateErrorHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to deal with the error.  \fIErrEventPtr\fR is
a pointer to the X error event.
132
133
134
135
136
137
138

139
140
it requires communication to and from the X server.  After the
\fBXSync\fR call Tk is guaranteed not to call any error
handlers deleted before the \fBXSync\fR call.
.PP
For the Tk error handling mechanism to work properly, it is essential
that application code never calls \fBXSetErrorHandler\fR directly;
applications should use only \fBTk_CreateErrorHandler\fR.

.SH KEYWORDS
callback, error, event, handler







>


132
133
134
135
136
137
138
139
140
141
it requires communication to and from the X server.  After the
\fBXSync\fR call Tk is guaranteed not to call any error
handlers deleted before the \fBXSync\fR call.
.PP
For the Tk error handling mechanism to work properly, it is essential
that application code never calls \fBXSetErrorHandler\fR directly;
applications should use only \fBTk_CreateErrorHandler\fR.

.SH KEYWORDS
callback, error, event, handler

Changes to doc/CrtGenHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateGenericHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateGenericHandler, Tk_DeleteGenericHandler \- associate procedure callback with all X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateGenericHandler\fR(\fIproc, clientData\fR)
.sp
\fBTk_DeleteGenericHandler\fR(\fIproc, clientData\fR)
.SH ARGUMENTS
.AS "Tk_GenericProc" clientData
.AP Tk_GenericProc *proc in
Procedure to invoke whenever any X event occurs on any display.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateGenericHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever any X event occurs.  This mechanism is
\fInot\fR intended for dispatching X events on windows managed by Tk
(you should use \fBTk_CreateEventHandler\fR for this purpose).
\fBTk_CreateGenericHandler\fR is intended for other purposes, such
as tracing X events, monitoring events on windows not owned by Tk,
accessing X-related libraries that were not originally designed for
use with Tk, and so on.
.PP
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_GenericProc\fR:
.CS
typedef int \fBTk_GenericProc\fR(
        ClientData \fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateGenericHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
how to handle events.
\fIEventPtr\fR is a pointer to the X event.






|



















>




















|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateGenericHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateGenericHandler, Tk_DeleteGenericHandler \- associate procedure callback with all X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateGenericHandler\fR(\fIproc, clientData\fR)
.sp
\fBTk_DeleteGenericHandler\fR(\fIproc, clientData\fR)
.SH ARGUMENTS
.AS "Tk_GenericProc" clientData
.AP Tk_GenericProc *proc in
Procedure to invoke whenever any X event occurs on any display.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateGenericHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever any X event occurs.  This mechanism is
\fInot\fR intended for dispatching X events on windows managed by Tk
(you should use \fBTk_CreateEventHandler\fR for this purpose).
\fBTk_CreateGenericHandler\fR is intended for other purposes, such
as tracing X events, monitoring events on windows not owned by Tk,
accessing X-related libraries that were not originally designed for
use with Tk, and so on.
.PP
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_GenericProc\fR:
.CS
typedef int Tk_GenericProc(
    ClientData \fIclientData\fR,
    XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateGenericHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
how to handle events.
\fIEventPtr\fR is a pointer to the X event.

Changes to doc/CrtImgType.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
'\"
'\" 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.
'\"
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageModelData, Tk_InitImageArgs \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
ClientData
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
\fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR)
.SH ARGUMENTS
.AS "const Tk_ImageType" *typePtrPtr
.AP "const Tk_ImageType" *typePtr in
Structure that defines the new type of image.
For Tk 8.4 and earlier this must be static: a
pointer to this structure is retained by the image code.
In Tk 8.5, this limitation was relaxed.
.AP Tcl_Interp *interp in
Interpreter in which image was created.
.AP "const char" *name in
Name of existing image.
.AP Tk_ImageType **typePtrPtr out
Points to word in which to store a pointer to type information for
the given image, if it exists.
.AP int argc in
Number of arguments
.AP char ***argvPtr in/out
Pointer to argument list
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateImageType\fR is invoked to define a new kind of image.
An image type corresponds to a particular value of the \fItype\fR
argument for the \fBimage create\fR command.  There may exist
any number of different image types, and new types may be defined
dynamically by calling \fBTk_CreateImageType\fR.
For example, there might be one type for 2-color bitmaps,
another for multi-color images, another for dithered images,
another for video, and so on.
.PP
The code that implements a new image type is called an
\fIimage manager\fR.
It consists of a collection of procedures plus three different
kinds of data structures.
The first data structure is a Tk_ImageType structure, which contains
the name of the image type and pointers to five procedures provided
by the image manager to deal with images of this type:
.CS
typedef struct Tk_ImageType {
    const char *\fIname\fR;
    Tk_ImageCreateProc *\fIcreateProc\fR;
    Tk_ImageGetProc *\fIgetProc\fR;
    Tk_ImageDisplayProc *\fIdisplayProc\fR;
    Tk_ImageFreeProc *\fIfreeProc\fR;
    Tk_ImageDeleteProc *\fIdeleteProc\fR;
} \fBTk_ImageType\fR;
.CE
The fields of this structure will be described in later subsections
of this entry.
.PP
The second major data structure manipulated by an image manager
is called an \fIimage model\fR;  it contains overall information
about a particular image, such as the values of the configuration
options specified in an \fBimage create\fR command.
There will usually be one of these structures for each
invocation of the \fBimage create\fR command.
.PP
The third data structure related to images is an \fIimage instance\fR.
There will usually be one of these structures for each usage of an
image in a particular widget.
It is possible for a single image to appear simultaneously
in multiple widgets, or even multiple times in the same widget.
Furthermore, different instances may be on different screens
or displays.
The image instance data structure describes things that may
vary from instance to instance, such as colors and graphics
contexts for redisplay.
There is usually one instance structure for each \fB\-image\fR
option specified for a widget or canvas item.
.PP
The following subsections describe the fields of a Tk_ImageType
in more detail.

.SS NAME
.PP
\fItypePtr->name\fR provides a name for the image type.
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBimage create\fR commands to create images of the new
type.
If there already existed an image type by this name then
the new image type replaces the old one.

.SS CREATEPROC
.PP
\fItypePtr->createProc\fR provides the address of a procedure for
Tk to call whenever \fBimage create\fR is invoked to create
an image of the new type.
\fItypePtr->createProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIname\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        const Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration
options for the new image (everything after the name argument to
\fBimage\fR).
The \fImodel\fR argument is a token that refers to Tk's information
about this image;  the image manager must return this token to
Tk when invoking the \fBTk_ImageChanged\fR procedure.
Typically \fIcreateProc\fR will parse \fIobjc\fR and \fIobjv\fR
and create an image model data structure for the new image.
\fIcreateProc\fR may store an arbitrary one-word value at
*\fImodelDataPtr\fR, which will be passed back to the
image manager when other callbacks are invoked.
Typically the value is a pointer to the model data
structure for the image.
.PP
If \fIcreateProc\fR encounters an error, it should leave an error
message in the interpreter result and return \fBTCL_ERROR\fR;  otherwise
it should return \fBTCL_OK\fR.
.PP
\fIcreateProc\fR should call \fBTk_ImageChanged\fR in order to set the
size of the image and request an initial redisplay.

.SS GETPROC
.PP
\fItypePtr->getProc\fR is invoked by Tk whenever a widget
calls \fBTk_GetImage\fR to use a particular image.
This procedure must match the following prototype:
.CS
typedef ClientData \fBTk_ImageGetProc\fR(
        Tk_Window \fItkwin\fR,
        ClientData \fImodelData\fR);
.CE
The \fItkwin\fR argument identifies the window in which the
image will be used and \fImodelData\fR is the value
returned by \fIcreateProc\fR when the image model was created.
\fIgetProc\fR will usually create a data structure for the new
instance, including such things as the resources needed to
display the image in the given window.
\fIgetProc\fR returns a one-word token for the instance, which
is typically the address of the instance data structure.
Tk will pass this value back to the image manager when invoking
its \fIdisplayProc\fR and \fIfreeProc\fR procedures.

.SS DISPLAYPROC
.PP
\fItypePtr->displayProc\fR is invoked by Tk whenever an image needs
to be displayed (i.e., whenever a widget calls \fBTk_RedrawImage\fR).
\fIdisplayProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDisplayProc\fR(
        ClientData \fIinstanceData\fR,
        Display *\fIdisplay\fR,
        Drawable \fIdrawable\fR,
        int \fIimageX\fR,
        int \fIimageY\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIdrawableX\fR,
        int \fIdrawableY\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created.
\fIdisplay\fR and \fIdrawable\fR indicate where to display the
image;  \fIdrawable\fR may be a pixmap rather than
the window specified to \fIgetProc\fR (this is usually the case,
since most widgets double-buffer their redisplay to get smoother
visual effects).
\fIimageX\fR, \fIimageY\fR, \fIwidth\fR, and \fIheight\fR
identify the region of the image that must be redisplayed.
This region will always be within the size of the image
as specified in the most recent call to \fBTk_ImageChanged\fR.
\fIdrawableX\fR and \fIdrawableY\fR indicate where in \fIdrawable\fR
the image should be displayed;  \fIdisplayProc\fR should display
the given region of the image so that point (\fIimageX\fR, \fIimageY\fR)
in the image appears at (\fIdrawableX\fR, \fIdrawableY\fR) in \fIdrawable\fR.

.SS FREEPROC
.PP
\fItypePtr->freeProc\fR contains the address of a procedure that
Tk will invoke when an image instance is released (i.e., when
\fBTk_FreeImage\fR is invoked).
This can happen, for example, when a widget is deleted or a image item
in a canvas is deleted, or when the image displayed in a widget or
canvas item is changed.
\fIfreeProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageFreeProc\fR(
        ClientData \fIinstanceData\fR,
        Display *\fIdisplay\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created, and \fIdisplay\fR
is the display containing the window for the instance.
\fIfreeProc\fR should release any resources associated with the
image instance, since the instance will never be used again.

.SS DELETEPROC
.PP
\fItypePtr->deleteProc\fR is a procedure that Tk invokes when an
image is being deleted (i.e. when the \fBimage delete\fR command
is invoked).
Before invoking \fIdeleteProc\fR Tk will invoke \fIfreeProc\fR for
each of the image's instances.
\fIdeleteProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDeleteProc\fR(
        ClientData \fImodelData\fR);
.CE
The \fImodelData\fR argument will be the same as the value
stored in \fI*modelDataPtr\fR by \fIcreateProc\fR when the
image was created.
\fIdeleteProc\fR should release any resources associated with
the image.

.SH TK_GETIMAGEMODELDATA
.PP
The procedure \fBTk_GetImageModelData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image model data for an image.
If there exists an image named \fIname\fR
in the interpreter given by \fIinterp\fR, then \fI*typePtrPtr\fR is
filled in with type information for the image (the \fItypePtr\fR value
passed to \fBTk_CreateImageType\fR when the image type was registered)
and the return value is the ClientData value returned by the
\fIcreateProc\fR when the image was created (this is typically a
pointer to the image model data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.

.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of \fBTk_ImageCreateProc\fR
was incompatibly different, with the following prototype:
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        char *\fIname\fR,
        int \fIargc\fR,
        char **\fIargv\fR,
        Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
Legacy programs and libraries dating from those days may still
contain code that defines extended Tk image types using the old
interface.  The Tk header file will still support this legacy
interface if the code is compiled with the macro \fBUSE_OLD_IMAGE\fR
defined.
.PP






|




|







|



|
|

|

<












>




















|





|





|




















>








>

<





|
|
|
|
|
|
|
|








|



|

|

|








>






|
|
|


|
|







>






|
|
|
|
|
|
|
|
|
|
















>










|
|
|






>









|
|

|
|



>
|

|

|






|

>

<



|
|
|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
'\"
'\" 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.
'\" 
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageMasterData, Tk_InitImageArgs \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
ClientData
\fBTk_GetImageMasterData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
\fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR)
.SH ARGUMENTS
.AS Tk_ImageType *typePtrPtr
.AP Tk_ImageType *typePtr in
Structure that defines the new type of image.
Must be static: a
pointer to this structure is retained by the image code.

.AP Tcl_Interp *interp in
Interpreter in which image was created.
.AP "const char" *name in
Name of existing image.
.AP Tk_ImageType **typePtrPtr out
Points to word in which to store a pointer to type information for
the given image, if it exists.
.AP int argc in
Number of arguments
.AP char ***argvPtr in/out
Pointer to argument list
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateImageType\fR is invoked to define a new kind of image.
An image type corresponds to a particular value of the \fItype\fR
argument for the \fBimage create\fR command.  There may exist
any number of different image types, and new types may be defined
dynamically by calling \fBTk_CreateImageType\fR.
For example, there might be one type for 2-color bitmaps,
another for multi-color images, another for dithered images,
another for video, and so on.
.PP
The code that implements a new image type is called an
\fIimage manager\fR.
It consists of a collection of procedures plus three different
kinds of data structures.
The first data structure is a Tk_ImageType structure, which contains
the name of the image type and pointers to five procedures provided
by the image manager to deal with images of this type:
.CS
typedef struct Tk_ImageType {
    char *\fIname\fR;
    Tk_ImageCreateProc *\fIcreateProc\fR;
    Tk_ImageGetProc *\fIgetProc\fR;
    Tk_ImageDisplayProc *\fIdisplayProc\fR;
    Tk_ImageFreeProc *\fIfreeProc\fR;
    Tk_ImageDeleteProc *\fIdeleteProc\fR;
} Tk_ImageType;
.CE
The fields of this structure will be described in later subsections
of this entry.
.PP
The second major data structure manipulated by an image manager
is called an \fIimage master\fR;  it contains overall information
about a particular image, such as the values of the configuration
options specified in an \fBimage create\fR command.
There will usually be one of these structures for each
invocation of the \fBimage create\fR command.
.PP
The third data structure related to images is an \fIimage instance\fR.
There will usually be one of these structures for each usage of an
image in a particular widget.
It is possible for a single image to appear simultaneously
in multiple widgets, or even multiple times in the same widget.
Furthermore, different instances may be on different screens
or displays.
The image instance data structure describes things that may
vary from instance to instance, such as colors and graphics
contexts for redisplay.
There is usually one instance structure for each \fB\-image\fR
option specified for a widget or canvas item.
.PP
The following subsections describe the fields of a Tk_ImageType
in more detail.

.SS NAME
.PP
\fItypePtr->name\fR provides a name for the image type.
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBimage create\fR commands to create images of the new
type.
If there already existed an image type by this name then
the new image type replaces the old one.

.SS CREATEPROC

\fItypePtr->createProc\fR provides the address of a procedure for
Tk to call whenever \fBimage create\fR is invoked to create
an image of the new type.
\fItypePtr->createProc\fR must match the following prototype:
.CS
typedef int Tk_ImageCreateProc(
    Tcl_Interp *\fIinterp\fR,
    char *\fIname\fR,
    int \fIobjc\fR,
    Tcl_Obj *const \fIobjv\fR[],
    Tk_ImageType *\fItypePtr\fR,
    Tk_ImageMaster \fImaster\fR,
    ClientData *\fImasterDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration
options for the new image (everything after the name argument to
\fBimage\fR).
The \fImaster\fR argument is a token that refers to Tk's information
about this image;  the image manager must return this token to
Tk when invoking the \fBTk_ImageChanged\fR procedure.
Typically \fIcreateProc\fR will parse \fIobjc\fR and \fIobjv\fR
and create an image master data structure for the new image.
\fIcreateProc\fR may store an arbitrary one-word value at
*\fImasterDataPtr\fR, which will be passed back to the
image manager when other callbacks are invoked.
Typically the value is a pointer to the master data
structure for the image.
.PP
If \fIcreateProc\fR encounters an error, it should leave an error
message in the interpreter result and return \fBTCL_ERROR\fR;  otherwise
it should return \fBTCL_OK\fR.
.PP
\fIcreateProc\fR should call \fBTk_ImageChanged\fR in order to set the
size of the image and request an initial redisplay.

.SS GETPROC
.PP
\fItypePtr->getProc\fR is invoked by Tk whenever a widget
calls \fBTk_GetImage\fR to use a particular image.
This procedure must match the following prototype:
.CS
typedef ClientData Tk_ImageGetProc(
    Tk_Window \fItkwin\fR,
    ClientData \fImasterData\fR);
.CE
The \fItkwin\fR argument identifies the window in which the
image will be used and \fImasterData\fR is the value
returned by \fIcreateProc\fR when the image master was created.
\fIgetProc\fR will usually create a data structure for the new
instance, including such things as the resources needed to
display the image in the given window.
\fIgetProc\fR returns a one-word token for the instance, which
is typically the address of the instance data structure.
Tk will pass this value back to the image manager when invoking
its \fIdisplayProc\fR and \fIfreeProc\fR procedures.

.SS DISPLAYPROC
.PP
\fItypePtr->displayProc\fR is invoked by Tk whenever an image needs
to be displayed (i.e., whenever a widget calls \fBTk_RedrawImage\fR).
\fIdisplayProc\fR must match the following prototype:
.CS
typedef void Tk_ImageDisplayProc(
    ClientData \fIinstanceData\fR,
    Display *\fIdisplay\fR,
    Drawable \fIdrawable\fR,
    int \fIimageX\fR,
    int \fIimageY\fR,
    int \fIwidth\fR,
    int \fIheight\fR,
    int \fIdrawableX\fR,
    int \fIdrawableY\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created.
\fIdisplay\fR and \fIdrawable\fR indicate where to display the
image;  \fIdrawable\fR may be a pixmap rather than
the window specified to \fIgetProc\fR (this is usually the case,
since most widgets double-buffer their redisplay to get smoother
visual effects).
\fIimageX\fR, \fIimageY\fR, \fIwidth\fR, and \fIheight\fR
identify the region of the image that must be redisplayed.
This region will always be within the size of the image
as specified in the most recent call to \fBTk_ImageChanged\fR.
\fIdrawableX\fR and \fIdrawableY\fR indicate where in \fIdrawable\fR
the image should be displayed;  \fIdisplayProc\fR should display
the given region of the image so that point (\fIimageX\fR, \fIimageY\fR)
in the image appears at (\fIdrawableX\fR, \fIdrawableY\fR) in \fIdrawable\fR.

.SS FREEPROC
.PP
\fItypePtr->freeProc\fR contains the address of a procedure that
Tk will invoke when an image instance is released (i.e., when
\fBTk_FreeImage\fR is invoked).
This can happen, for example, when a widget is deleted or a image item
in a canvas is deleted, or when the image displayed in a widget or
canvas item is changed.
\fIfreeProc\fR must match the following prototype:
.CS
typedef void Tk_ImageFreeProc(
    ClientData \fIinstanceData\fR,
    Display *\fIdisplay\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created, and \fIdisplay\fR
is the display containing the window for the instance.
\fIfreeProc\fR should release any resources associated with the
image instance, since the instance will never be used again.

.SS DELETEPROC
.PP
\fItypePtr->deleteProc\fR is a procedure that Tk invokes when an
image is being deleted (i.e. when the \fBimage delete\fR command
is invoked).
Before invoking \fIdeleteProc\fR Tk will invoke \fIfreeProc\fR for
each of the image's instances.
\fIdeleteProc\fR must match the following prototype:
.CS
typedef void Tk_ImageDeleteProc(
    ClientData \fImasterData\fR);
.CE
The \fImasterData\fR argument will be the same as the value
stored in \fI*masterDataPtr\fR by \fIcreateProc\fR when the
image was created.
\fIdeleteProc\fR should release any resources associated with
the image.

.SH TK_GETIMAGEMASTERDATA
.PP
The procedure \fBTk_GetImageMasterData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image master data for an image.
If there exists an image named \fIname\fR
in the interpreter given by \fIinterp\fR, then \fI*typePtrPtr\fR is
filled in with type information for the image (the \fItypePtr\fR value
passed to \fBTk_CreateImageType\fR when the image type was registered)
and the return value is the ClientData value returned by the
\fIcreateProc\fR when the image was created (this is typically a
pointer to the image master data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.

.SH "LEGACY INTERFACE SUPPORT"

In Tk 8.2 and earlier, the definition of \fBTk_ImageCreateProc\fR
was incompatibly different, with the following prototype:
.CS
typedef int Tk_ImageCreateProc(
    Tcl_Interp *\fIinterp\fR,
    char *\fIname\fR,
    int \fIargc\fR,
    char **\fIargv\fR,
    Tk_ImageType *\fItypePtr\fR,
    Tk_ImageMaster \fImaster\fR,
    ClientData *\fImasterDataPtr\fR);
.CE
Legacy programs and libraries dating from those days may still
contain code that defines extended Tk image types using the old
interface.  The Tk header file will still support this legacy
interface if the code is compiled with the macro \fBUSE_OLD_IMAGE\fR
defined.
.PP
273
274
275
276
277
278
279

280
281

282
283
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.

.SH "SEE ALSO"
Tk_ImageChanged, Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, Tk_SizeOfImage

.SH KEYWORDS
image manager, image type, instance, model







>


>

|
279
280
281
282
283
284
285
286
287
288
289
290
291
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.

.SH "SEE ALSO"
Tk_ImageChanged, Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, Tk_SizeOfImage

.SH KEYWORDS
image manager, image type, instance, master

Changes to doc/CrtItemType.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_CreateItemType 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateItemType, Tk_GetItemTypes \- define new kind of canvas item
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_CreateItemType 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateItemType, Tk_GetItemTypes \- define new kind of canvas item
.SH SYNOPSIS
.nf
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
of all item types currently defined for canvases.
The entries in the list are linked together through their
\fInextPtr\fR fields, with the end of the list marked by a
NULL \fInextPtr\fR.
.PP
You may find it easier to understand the rest of this manual entry
by looking at the code for an existing canvas item type such as
bitmap (in the file tkCanvBmap.c) or text (tkCanvText.c).
The easiest way to create a new type manager is to copy the code
for an existing type and modify it for the new type.
.PP
Tk provides a number of utility procedures for the use of canvas
type managers, such as \fBTk_CanvasCoords\fR and \fBTk_CanvasPsColor\fR;
these are described in separate manual entries.
.SH "DATA STRUCTURES"
.PP
A type manager consists of a collection of procedures that provide a
standard set of operations on items of that type.
The type manager deals with three kinds of data
structures.
The first data structure is a Tk_ItemType; it contains
information such as the name of the type and pointers to
the standard procedures implemented by the type manager:
.PP
.CS
typedef struct Tk_ItemType {
    const char *\fIname\fR;
    size_t \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    const Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIalwaysRedraw\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;
.VS "8.7, TIP164"
    Tk_ItemRotateProc *\fIrotateProc\fR;
.VE "8.7, TIP164"
} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized
except \fInextPtr\fR, which Tk sets to link all the types together
into a list.
The structure must be in permanent memory (either statically
allocated or dynamically allocated but never freed); Tk retains
a pointer to this structure.
.PP
The second data structure manipulated by a type manager is an
\fIitem record\fR.
For each item in a canvas there exists one item record.
All of the items of a given type generally have item records with
the same structure, but different types usually have different
formats for their item records.
The first part of each item record is a header with a standard structure
defined by Tk via the type Tk_Item; the rest of the item
record is defined by the type manager.
A type manager must define its item records with a Tk_Item as
the first field.
For example, the item record for bitmap items is defined as follows:
.PP
.CS
typedef struct BitmapItem {
    Tk_Item \fIheader\fR;
    double \fIx\fR, \fIy\fR;
    Tk_Anchor \fIanchor\fR;
    Pixmap \fIbitmap\fR;
    XColor *\fIfgColor\fR;
    XColor *\fIbgColor\fR;
    GC \fIgc\fR;
} \fBBitmapItem\fR;
.CE
.PP
The \fIheader\fR substructure contains information used by Tk
to manage the item, such as its identifier, its tags, its type,
and its bounding box.
The fields starting with \fIx\fR belong to the type manager:
Tk will never read or write them.
The type manager should not need to read or write any of the
fields in the header except for four fields
whose names are \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
These fields give a bounding box for the items using integer
canvas coordinates: the item should not cover any pixels
with x-coordinate lower than \fIx1\fR or y-coordinate
lower than \fIy1\fR, nor should it cover any pixels with
x-coordinate greater than or equal to \fIx2\fR or y-coordinate
greater than or equal to \fIy2\fR.
It is up to the type manager to keep the bounding box up to
date as the item is moved and reconfigured.
.PP
Whenever Tk calls a procedure in a type manager it passes in a pointer
to an item record.
The argument is always passed as a pointer to a Tk_Item; the type
manager will typically cast this into a pointer to its own specific
type, such as BitmapItem.
.PP
The third data structure used by type managers has type
Tk_Canvas; it serves as an opaque handle for the canvas widget
as a whole.
Type managers need not know anything about the contents of this
structure.
A Tk_Canvas handle is typically passed in to the
procedures of a type manager, and the type manager can pass the
handle back to library procedures such as Tk_CanvasTkwin
to fetch information about the canvas.
.SH "TK_ITEMTYPE FIELDS"
.SS NAME
.PP
This section and the ones that follow describe each of the fields
in a Tk_ItemType structure in detail.
The \fIname\fR field provides a string name for the item type.
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBcreate\fR widget commands to create items of the new
type.
If there already existed an item type by this name then
the new item type replaces the old one.
.SS "FLAGS (IN ALWAYSREDRAW)"
.PP
The \fItypePtr\->alwaysRedraw\fR field (so named for historic reasons)
contains a collection of flag bits that modify how the canvas core interacts
with the item. The following bits are defined:
.TP
\fB1\fR
.
Indicates that the item should always be redrawn when any part of the canvas
is redrawn, rather than only when the bounding box of the item overlaps the
area being redrawn. This is used by window items, for example, which need to
unmap subwindows that are not on the screen.
.TP
\fBTK_CONFIG_OBJS\fR
.
Indicates that operations which would otherwise take a string (or array of
strings) actually take a Tcl_Obj reference (or an array of such references).
The operations to which this applies are the \fIconfigProc\fR, the
\fIcoordProc\fR, the \fIcreateProc\fR, the \fIindexProc\fR and the
\fIinsertProc\fR.
.TP
\fBTK_MOVABLE_POINTS\fR
.VS 8.6
Indicates that the item supports the \fIdCharsProc\fR, \fIindexProc\fR and
\fIinsertProc\fR with the same semantics as Tk's built-in line and polygon
types, and that hence individual coordinate points can be moved. Must not be
set if any of the above methods is NULL.
.VE 8.6
.SS ITEMSIZE
.PP
\fItypePtr\->itemSize\fR gives the size in bytes of item records
of this type, including the Tk_Item header.
Tk uses this size to allocate memory space for items of the type.
All of the item records for a given type must have the same size.
If variable length fields are needed for an item (such as a list
of points for a polygon), the type manager can allocate a separate
object of variable length and keep a pointer to it in the item record.
.SS CREATEPROC
.PP
\fItypePtr\->createProc\fR points to a procedure for
Tk to call whenever a new item of this type is created.
\fItypePtr\->createProc\fR must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[]);
.CE
.PP
The \fIinterp\fR argument is the interpreter in which the canvas's
\fBcreate\fR widget command was invoked, and \fIcanvas\fR is a
handle for the canvas widget.
\fIitemPtr\fR is a pointer to a newly-allocated item of
size \fItypePtr\->itemSize\fR.
Tk has already initialized the item's header (the first
\fBsizeof(Tk_ItemType)\fR bytes).
The \fIobjc\fR and \fIobjv\fR arguments describe all of the
arguments to the \fBcreate\fR command after the \fItype\fR
argument.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, in the widget command:
.PP
.CS
\fB\&.c create rectangle 10 20 50 50 \-fill black\fR
.CE
.PP
\fIobjc\fR will be \fB6\fR and \fIobjv\fR[0] will contain the
integer object \fB10\fR.
.PP
\fIcreateProc\fR should use \fIobjc\fR and \fIobjv\fR to initialize
the type-specific parts of the item record and set an initial value
for the bounding box in the item's header.
It should return a standard Tcl completion code and leave an
error message in the interpreter result if an error occurs.
If an error occurs Tk will free the item record, so \fIcreateProc\fR
must be sure to leave the item record in a clean state if it returns an error
(e.g., it must free any additional memory that it allocated for
the item).
.SS CONFIGSPECS
.PP
Each type manager must provide a standard table describing its
configuration options, in a form suitable for use with
\fBTk_ConfigureWidget\fR.
This table will normally be used by \fItypePtr\->createProc\fR
and \fItypePtr\->configProc\fR, but Tk also uses it directly
to retrieve option information in the \fBitemcget\fR and
\fBitemconfigure\fR widget commands.
\fItypePtr\->configSpecs\fR must point to the configuration table
for this type.
Note: Tk provides a custom option type \fBtk_CanvasTagsOption\fR
for implementing the \fB\-tags\fR option; see an existing type
manager for an example of how to use it in \fIconfigSpecs\fR.
.SS CONFIGPROC
.PP
\fItypePtr\->configProc\fR is called by Tk whenever the
\fBitemconfigure\fR widget command is invoked to change the
configuration options for a canvas item.
This procedure must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemConfigureProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        int \fIflags\fR);
.CE
.PP
The \fIinterp\fR argument identifies the interpreter in which the
widget command was invoked, \fIcanvas\fR is a handle for the canvas
widget, and \fIitemPtr\fR is a pointer to the item being configured.
\fIobjc\fR and \fIobjv\fR contain the configuration options.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, if the following command is invoked:
.PP
.CS
\fB\&.c itemconfigure 2 \-fill red \-outline black\fR
.CE
.PP
\fIobjc\fR is \fB4\fR and \fIobjv\fR contains the string objects \fB\-fill\fR
through \fBblack\fR.
\fIobjc\fR will always be an even value.
The \fIflags\fR argument contains flags to pass to \fBTk_ConfigureWidget\fR;
currently this value is always \fBTK_CONFIG_ARGV_ONLY\fR when Tk
invokes \fItypePtr\->configProc\fR, but the type manager's \fIcreateProc\fR
procedure will usually invoke \fIconfigProc\fR with different flag values.
.PP
\fItypePtr\->configProc\fR returns a standard Tcl completion code and
leaves an error message in the interpreter result if an error occurs.
It must update the item's bounding box to reflect the new configuration
options.
.SS COORDPROC
.PP
\fItypePtr\->coordProc\fR is invoked by Tk to implement the \fBcoords\fR
widget command for an item.
It must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemCoordProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[]);
.CE
.PP
The arguments \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR
all have the standard meanings, and \fIobjc\fR and \fIobjv\fR
describe the coordinate arguments.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, if the following widget command is invoked:
.PP
.CS
\fB\&.c coords 2 30 90\fR
.CE
.PP
\fIobjc\fR will be \fB2\fR and \fBobjv\fR will contain the integer objects
\fB30\fR and \fB90\fR.
.PP
The \fIcoordProc\fR procedure should process the new coordinates,
update the item appropriately (e.g., it must reset the bounding
box in the item's header), and return a standard Tcl completion
code.
If an error occurs, \fIcoordProc\fR must leave an error message in
the interpreter result.
.SS DELETEPROC
.PP
\fItypePtr\->deleteProc\fR is invoked by Tk to delete an item
and free any resources allocated to it.
It must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemDeleteProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        Display *\fIdisplay\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual
interpretations, and \fIdisplay\fR identifies the X display containing
the canvas.
\fIdeleteProc\fR must free up any resources allocated for the item,
so that Tk can free the item record.
\fIdeleteProc\fR should not actually free the item record; this will
be done by Tk when \fIdeleteProc\fR returns.
.SS "DISPLAYPROC"
.PP
\fItypePtr\->displayProc\fR is invoked by Tk to redraw an item
on the screen.
It must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemDisplayProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        Display *\fIdisplay\fR,
        Drawable \fIdst\fR,
        int \fIx\fR,
        int \fIy\fR,
        int \fIwidth\fR,
        int \fIheight\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIdisplay\fR identifies the display containing the canvas, and
\fIdst\fR specifies a drawable in which the item should be rendered;
typically this is an off-screen pixmap, which Tk will copy into
the canvas's window once all relevant items have been drawn.
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR specify a rectangular
region in canvas coordinates, which is the area to be redrawn;







|















<


|
|

|
















<
<
<
|









|









|




<









|

<









|









|




|







<










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|








|

|
<

|
|
|
|
|
|

<




|





<
<
<
|
<



<







|









|
|


|


|



|



<

|
|
|
|
|
|
|

<
|
|

|
<
<
<
|
<



<



|

|


|
|




|


<

|
|
|
|
|
|

<



<
<
<

<



<








|


|


<

|
|
|
|

<





|

|

|


<

|
|
|
|
|
|
|
|
|

<







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162




























163

164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193



194

195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238

239
240
241
242



243

244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271

272
273
274



275

276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
of all item types currently defined for canvases.
The entries in the list are linked together through their
\fInextPtr\fR fields, with the end of the list marked by a
NULL \fInextPtr\fR.
.PP
You may find it easier to understand the rest of this manual entry
by looking at the code for an existing canvas item type such as
bitmap (file tkCanvBmap.c) or text (tkCanvText.c).
The easiest way to create a new type manager is to copy the code
for an existing type and modify it for the new type.
.PP
Tk provides a number of utility procedures for the use of canvas
type managers, such as \fBTk_CanvasCoords\fR and \fBTk_CanvasPsColor\fR;
these are described in separate manual entries.
.SH "DATA STRUCTURES"
.PP
A type manager consists of a collection of procedures that provide a
standard set of operations on items of that type.
The type manager deals with three kinds of data
structures.
The first data structure is a Tk_ItemType; it contains
information such as the name of the type and pointers to
the standard procedures implemented by the type manager:

.CS
typedef struct Tk_ItemType {
    char *\fIname\fR;
    int \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIalwaysRedraw\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;



} Tk_ItemType;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized
except \fInextPtr\fR, which Tk sets to link all the types together
into a list.
The structure must be in permanent memory (either statically
allocated or dynamically allocated but never freed);  Tk retains
a pointer to this structure.
.PP
The second data structure manipulated by a type manager is an
\fIitem record\fR.
For each item in a canvas there exists one item record.
All of the items of a given type generally have item records with
the same structure, but different types usually have different
formats for their item records.
The first part of each item record is a header with a standard structure
defined by Tk via the type Tk_Item;  the rest of the item
record is defined by the type manager.
A type manager must define its item records with a Tk_Item as
the first field.
For example, the item record for bitmap items is defined as follows:

.CS
typedef struct BitmapItem {
    Tk_Item \fIheader\fR;
    double \fIx\fR, \fIy\fR;
    Tk_Anchor \fIanchor\fR;
    Pixmap \fIbitmap\fR;
    XColor *\fIfgColor\fR;
    XColor *\fIbgColor\fR;
    GC \fIgc\fR;
} BitmapItem;
.CE

The \fIheader\fR substructure contains information used by Tk
to manage the item, such as its identifier, its tags, its type,
and its bounding box.
The fields starting with \fIx\fR belong to the type manager:
Tk will never read or write them.
The type manager should not need to read or write any of the
fields in the header except for four fields
whose names are \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
These fields give a bounding box for the items using integer
canvas coordinates:  the item should not cover any pixels
with x-coordinate lower than \fIx1\fR or y-coordinate
lower than \fIy1\fR, nor should it cover any pixels with
x-coordinate greater than or equal to \fIx2\fR or y-coordinate
greater than or equal to \fIy2\fR.
It is up to the type manager to keep the bounding box up to
date as the item is moved and reconfigured.
.PP
Whenever Tk calls a procedure in a type manager it passes in a pointer
to an item record.
The argument is always passed as a pointer to a Tk_Item;  the type
manager will typically cast this into a pointer to its own specific
type, such as BitmapItem.
.PP
The third data structure used by type managers has type
Tk_Canvas;  it serves as an opaque handle for the canvas widget
as a whole.
Type managers need not know anything about the contents of this
structure.
A Tk_Canvas handle is typically passed in to the
procedures of a type manager, and the type manager can pass the
handle back to library procedures such as Tk_CanvasTkwin
to fetch information about the canvas.

.SS NAME
.PP
This section and the ones that follow describe each of the fields
in a Tk_ItemType structure in detail.
The \fIname\fR field provides a string name for the item type.
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBcreate\fR widget commands to create items of the new
type.
If there already existed an item type by this name then
the new item type replaces the old one.




























.SS ITEMSIZE

\fItypePtr->itemSize\fR gives the size in bytes of item records
of this type, including the Tk_Item header.
Tk uses this size to allocate memory space for items of the type.
All of the item records for a given type must have the same size.
If variable length fields are needed for an item (such as a list
of points for a polygon), the type manager can allocate a separate
object of variable length and keep a pointer to it in the item record.
.SS CREATEPROC
.PP
\fItypePtr->createProc\fR points to a procedure for
Tk to call whenever a new item of this type is created.
\fItypePtr->createProc\fR must match the following prototype:

.CS
typedef int Tk_ItemCreateProc(
    Tcl_Interp *\fIinterp\fR,
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIobjc\fR,
    Tcl_Obj* const \fIobjv\fR[]);
.CE

The \fIinterp\fR argument is the interpreter in which the canvas's
\fBcreate\fR widget command was invoked, and \fIcanvas\fR is a
handle for the canvas widget.
\fIitemPtr\fR is a pointer to a newly-allocated item of
size \fItypePtr->itemSize\fR.
Tk has already initialized the item's header (the first
\fBsizeof(Tk_ItemType)\fR bytes).
The \fIobjc\fR and \fIobjv\fR arguments describe all of the
arguments to the \fBcreate\fR command after the \fItype\fR
argument.



For example, in the widget command

.CS
\fB\&.c create rectangle 10 20 50 50 \-fill black\fR
.CE

\fIobjc\fR will be \fB6\fR and \fIobjv\fR[0] will contain the
integer object \fB10\fR.
.PP
\fIcreateProc\fR should use \fIobjc\fR and \fIobjv\fR to initialize
the type-specific parts of the item record and set an initial value
for the bounding box in the item's header.
It should return a standard Tcl completion code and leave an
error message in \fIinterp->result\fR if an error occurs.
If an error occurs Tk will free the item record, so \fIcreateProc\fR
must be sure to leave the item record in a clean state if it returns an error
(e.g., it must free any additional memory that it allocated for
the item).
.SS CONFIGSPECS
.PP
Each type manager must provide a standard table describing its
configuration options, in a form suitable for use with
\fBTk_ConfigureWidget\fR.
This table will normally be used by \fItypePtr->createProc\fR
and \fItypePtr->configProc\fR, but Tk also uses it directly
to retrieve option information in the \fBitemcget\fR and
\fBitemconfigure\fR widget commands.
\fItypePtr->configSpecs\fR must point to the configuration table
for this type.
Note: Tk provides a custom option type \fBtk_CanvasTagsOption\fR
for implementing the \fB\-tags\fR option;  see an existing type
manager for an example of how to use it in \fIconfigSpecs\fR.
.SS CONFIGPROC
.PP
\fItypePtr->configProc\fR is called by Tk whenever the
\fBitemconfigure\fR widget command is invoked to change the
configuration options for a canvas item.
This procedure must match the following prototype:

.CS
typedef int Tk_ItemConfigureProc(
    Tcl_Interp *\fIinterp\fR,
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIobjc\fR,
    Tcl_Obj* const \fIobjv\fR[],
    int \fIflags\fR);
.CE

The \fIinterp\fR objument identifies the interpreter in which the
widget command was invoked,  \fIcanvas\fR is a handle for the canvas
widget, and \fIitemPtr\fR is a pointer to the item being configured.
\fIobjc\fR and \fIobjv\fR contain the configuration options.  For



example, if the following command is invoked:

.CS
\fB\&.c itemconfigure 2 \-fill red \-outline black\fR
.CE

\fIobjc\fR is \fB4\fR and \fIobjv\fR contains the string objects \fB\-fill\fR
through \fBblack\fR.
\fIobjc\fR will always be an even value.
The  \fIflags\fR argument contains flags to pass to \fBTk_ConfigureWidget\fR;
currently this value is always \fBTK_CONFIG_ARGV_ONLY\fR when Tk
invokes \fItypePtr->configProc\fR, but the type manager's \fIcreateProc\fR
procedure will usually invoke \fIconfigProc\fR with different flag values.
.PP
\fItypePtr->configProc\fR returns a standard Tcl completion code and
leaves an error message in \fIinterp->result\fR if an error occurs.
It must update the item's bounding box to reflect the new configuration
options.
.SS COORDPROC
.PP
\fItypePtr->coordProc\fR is invoked by Tk to implement the \fBcoords\fR
widget command for an item.
It must match the following prototype:

.CS
typedef int Tk_ItemCoordProc(
    Tcl_Interp *\fIinterp\fR,
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIobjc\fR,
    Tcl_Obj* const \fIobjv\fR[]);
.CE

The arguments \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR
all have the standard meanings, and \fIobjc\fR and \fIobjv\fR
describe the coordinate arguments.



For example, if the following widget command is invoked:

.CS
\fB\&.c coords 2 30 90\fR
.CE

\fIobjc\fR will be \fB2\fR and \fBobjv\fR will contain the integer objects
\fB30\fR and \fB90\fR.
.PP
The \fIcoordProc\fR procedure should process the new coordinates,
update the item appropriately (e.g., it must reset the bounding
box in the item's header), and return a standard Tcl completion
code.
If an error occurs, \fIcoordProc\fR must leave an error message in
\fIinterp->result\fR.
.SS DELETEPROC
.PP
\fItypePtr->deleteProc\fR is invoked by Tk to delete an item
and free any resources allocated to it.
It must match the following prototype:

.CS
typedef void Tk_ItemDeleteProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    Display *\fIdisplay\fR);
.CE

The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual
interpretations, and \fIdisplay\fR identifies the X display containing
the canvas.
\fIdeleteProc\fR must free up any resources allocated for the item,
so that Tk can free the item record.
\fIdeleteProc\fR should not actually free the item record;  this will
be done by Tk when \fIdeleteProc\fR returns.
.SS "DISPLAYPROC AND ALWAYSREDRAW"
.PP
\fItypePtr->displayProc\fR is invoked by Tk to redraw an item
on the screen.
It must match the following prototype:

.CS
typedef void Tk_ItemDisplayProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    Display *\fIdisplay\fR,
    Drawable \fIdst\fR,
    int \fIx\fR,
    int \fIy\fR,
    int \fIwidth\fR,
    int \fIheight\fR);
.CE

The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIdisplay\fR identifies the display containing the canvas, and
\fIdst\fR specifies a drawable in which the item should be rendered;
typically this is an off-screen pixmap, which Tk will copy into
the canvas's window once all relevant items have been drawn.
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR specify a rectangular
region in canvas coordinates, which is the area to be redrawn;
397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
will not necessarily be the same as those in the canvas.
\fIdisplayProc\fR should call \fBTk_CanvasDrawableCoords\fR
to transform coordinates from those of the canvas to those
of \fIdst\fR.
.PP
Normally an item's \fIdisplayProc\fR is only invoked if the item
overlaps the area being displayed.
However, if bit zero of \fItypePtr\->alwaysRedraw\fR is 1,
(i.e.\|
.QW "\fItypePtr\->alwaysRedraw & 1 == 1\fR" )
then \fIdisplayProc\fR is invoked during every redisplay operation,
even if the item does not overlap the area of redisplay; this is useful for

cases such as window items, where the subwindow needs to be unmapped when it
is off the screen.
.SS POINTPROC
.PP
\fItypePtr\->pointProc\fR is invoked by Tk to find out how close
a given point is to a canvas item.
Tk uses this procedure for purposes such as locating the item
under the mouse or finding the closest item to a given point.
The procedure must match the following prototype:
.PP
.CS
typedef double \fBTk_ItemPointProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double *\fIpointPtr\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meaning.
\fIpointPtr\fR points to an array of two numbers giving
the x and y coordinates of a point.
\fIpointProc\fR must return a real value giving the distance
from the point to the item, or 0 if the point lies inside
the item.
.SS AREAPROC
.PP
\fItypePtr\->areaProc\fR is invoked by Tk to find out the relationship
between an item and a rectangular area.
It must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemAreaProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double *\fIrectPtr\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meaning.
\fIrectPtr\fR points to an array of four real numbers;
the first two give the x and y coordinates of the upper left
corner of a rectangle, and the second two give the x and y
coordinates of the lower right corner.
\fIareaProc\fR must return \-1 if the item lies entirely outside
the given area, 0 if it lies partially inside and partially
outside the area, and 1 if it lies entirely inside the area.
.SS POSTSCRIPTPROC
.PP
\fItypePtr\->postscriptProc\fR is invoked by Tk to generate
Postscript for an item during the \fBpostscript\fR widget command.
If the type manager is not capable of generating Postscript then
\fItypePtr\->postscriptProc\fR should be NULL.
The procedure must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemPostscriptProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIprepass\fR);
.CE
.PP
The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all have
standard meanings; \fIprepass\fR will be described below.
If \fIpostscriptProc\fR completes successfully, it should append
Postscript for the item to the information in the interpreter result
(e.g. by calling \fBTcl_AppendResult\fR, not \fBTcl_SetResult\fR)
and return \fBTCL_OK\fR.
If an error occurs, \fIpostscriptProc\fR should clear the result
and replace its contents with an error message; then it should
return \fBTCL_ERROR\fR.
.PP
Tk provides a collection of utility procedures to simplify
\fIpostscriptProc\fR.
For example, \fBTk_CanvasPsColor\fR will generate Postscript to set
the current color to a given Tk color and \fBTk_CanvasPsFont\fR will
set up font information.







|
<
<
|
|
>
|
|


|




<

|
|
|
|

<








|


<

|
|
|
|

<










|


|

<

|
|
|
|
|

<

|

|



|







336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
will not necessarily be the same as those in the canvas.
\fIdisplayProc\fR should call \fBTk_CanvasDrawableCoords\fR
to transform coordinates from those of the canvas to those
of \fIdst\fR.
.PP
Normally an item's \fIdisplayProc\fR is only invoked if the item
overlaps the area being displayed.
However, if \fItypePtr->alwaysRedraw\fR has a non-zero value, then


\fIdisplayProc\fR is invoked during every redisplay operation,
even if the item does not overlap the area of redisplay.
\fIalwaysRedraw\fR should normally be set to 0;  it is only
set to 1 in special cases such as window items that need to be
unmapped when they are off-screen.
.SS POINTPROC
.PP
\fItypePtr->pointProc\fR is invoked by Tk to find out how close
a given point is to a canvas item.
Tk uses this procedure for purposes such as locating the item
under the mouse or finding the closest item to a given point.
The procedure must match the following prototype:

.CS
typedef double Tk_ItemPointProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    double *\fIpointPtr\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meaning.
\fIpointPtr\fR points to an array of two numbers giving
the x and y coordinates of a point.
\fIpointProc\fR must return a real value giving the distance
from the point to the item, or 0 if the point lies inside
the item.
.SS AREAPROC
.PP
\fItypePtr->areaProc\fR is invoked by Tk to find out the relationship
between an item and a rectangular area.
It must match the following prototype:

.CS
typedef int Tk_ItemAreaProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    double *\fIrectPtr\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meaning.
\fIrectPtr\fR points to an array of four real numbers;
the first two give the x and y coordinates of the upper left
corner of a rectangle, and the second two give the x and y
coordinates of the lower right corner.
\fIareaProc\fR must return \-1 if the item lies entirely outside
the given area, 0 if it lies partially inside and partially
outside the area, and 1 if it lies entirely inside the area.
.SS POSTSCRIPTPROC
.PP
\fItypePtr->postscriptProc\fR is invoked by Tk to generate
Postscript for an item during the \fBpostscript\fR widget command.
If the type manager is not capable of generating Postscript then
\fItypePtr->postscriptProc\fR should be NULL.
The procedure must match the following prototype:

.CS
typedef int Tk_ItemPostscriptProc(
    Tcl_Interp *\fIinterp\fR,
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIprepass\fR);
.CE

The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all have
standard meanings;  \fIprepass\fR will be described below.
If \fIpostscriptProc\fR completes successfully, it should append
Postscript for the item to the information in \fIinterp->result\fR
(e.g. by calling \fBTcl_AppendResult\fR, not \fBTcl_SetResult\fR)
and return \fBTCL_OK\fR.
If an error occurs, \fIpostscriptProc\fR should clear the result
and replace its contents with an error message;  then it should
return \fBTCL_ERROR\fR.
.PP
Tk provides a collection of utility procedures to simplify
\fIpostscriptProc\fR.
For example, \fBTk_CanvasPsColor\fR will generate Postscript to set
the current color to a given Tk color and \fBTk_CanvasPsFont\fR will
set up font information.
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
upper left) to the space of Postscript (where the origin is at the
lower left).
.PP
In order to generate Postscript that complies with the Adobe Document
Structuring Conventions, Tk actually generates Postscript in two passes.
It calls each item's \fIpostscriptProc\fR in each pass.
The only purpose of the first pass is to collect font information
(which is done by \fBTk_CanvasPsFont\fR); the actual Postscript is
discarded.
Tk sets the \fIprepass\fR argument to \fIpostscriptProc\fR to 1
during the first pass; the type manager can use \fIprepass\fR to skip
all Postscript generation except for calls to \fBTk_CanvasPsFont\fR.
During the second pass \fIprepass\fR will be 0, so the type manager
must generate complete Postscript.
.SS SCALEPROC
.PP
\fItypePtr\->scaleProc\fR is invoked by Tk to rescale a canvas item
during the \fBscale\fR widget command.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemScaleProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double \fIoriginX\fR,
        double \fIoriginY\fR,
        double \fIscaleX\fR,
        double \fIscaleY\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIoriginX\fR and \fIoriginY\fR specify an origin relative to which
the item is to be scaled, and \fIscaleX\fR and \fIscaleY\fR give the
x and y scale factors.
The item should adjust its coordinates so that a point in the item
that used to have coordinates \fIx\fR and \fIy\fR will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIx\(fm\fR = \fIoriginX\fR + \fIscaleX\fR \(mu (\fIx\fR \(mi \fIoriginX\fR)
\fIy\(fm\fR = \fIoriginY\fR + \fIscaleY\fR \(mu (\fIy\fR \(mi \fIoriginY\fR)
.CE
.PP
\fIscaleProc\fR must also update the bounding box in the item's
header.
.SS TRANSLATEPROC
.PP
\fItypePtr\->translateProc\fR is invoked by Tk to translate a canvas item
during the \fBmove\fR widget command.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemTranslateProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double \fIdeltaX\fR,
        double \fIdeltaY\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.
.SS ROTATEPROC
.VS "8.7, TIP164"
.PP
\fItypePtr\->rotateProc\fR is invoked by Tk to rotate a canvas item
during the \fBrotate\fR widget command.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemRotateProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double \fIoriginX\fR,
        double \fIoriginY\fR,
        double \fIangleRad\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIoriginX\fR and \fIoriginY\fR specify an origin relative to which
the item is to be rotated, and \fIangleRad\fR gives the anticlockwise
rotation to be applied in radians.
The item should adjust the coordinates of its control points so that where
they used to have coordinates \fIx\fR and \fIy\fR, they will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIrelX\fR = \fIx\fR - \fIoriginX\fR
\fIrelY\fR = \fIy\fR - \fIoriginY\fR
\fIx\(fm\fR = \fIoriginX\fR + \fIrelX\fR \(mu cos(\fIangleRad\fR) + \fIrelY\fR \(mu sin(\fIangleRad\fR)
\fIy\(fm\fR = \fIoriginY\fR \(mi \fIrelX\fR \(mu sin(\fIangleRad\fR) + \fIrelY\fR \(mu cos(\fIangleRad\fR)
.CE
.PP
The control points for an item are not necessarily the coordinates provided to
the item when it is created (or via the \fItypePtr\->coordProc\fR), but could
instead be derived from them.
\fIrotateProc\fR must also update the bounding box in the item's header.
.PP
Item types do not need to provide a \fItypePtr\->rotateProc\fR. If the
\fItypePtr\->rotateProc\fR is NULL, the \fItypePtr\->coordProc\fR will be
used instead to retrieve and update the list of coordinates.
.VE "8.7, TIP164"
.SS INDEXPROC
.PP
\fItypePtr\->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text or coordinates;
\fItypePtr\->indexProc\fR may be specified as NULL for non-textual
item types if they do not support detailed coordinate addressing.
The procedure must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemIndexProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        Tcl_Obj *\fIindexObj\fR,
        int *\fIindexPtr\fR);
.CE
.PP
The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all
have the usual meaning.
\fIindexObj\fR contains a textual description of an index,
and \fIindexPtr\fR points to an integer value that should be
filled in with a numerical index.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIindexObj\fR parameter will
actually contain a pointer to a constant string.
It is up to the type manager to decide what forms of index
are supported (e.g., numbers, \fBinsert\fR, \fBsel.first\fR,
\fBend\fR, etc.).
\fIindexProc\fR should return a Tcl completion code and set
the interpreter result in the event of an error.
.SS ICURSORPROC
.PP
\fItypePtr\->icursorProc\fR is invoked by Tk during
the \fBicursor\fR widget command to set the position of the
insertion cursor in a textual item.
It is only relevant for item types that support an insertion cursor;
\fItypePtr\->icursorProc\fR may be specified as NULL for item types
that do not support an insertion cursor.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemCursorProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIindex\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings, and
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr\->insertProc\fR.
The type manager should position the insertion cursor in the
item just before the character given by \fIindex\fR.
Whether or not to actually display the insertion cursor is
determined by other information provided by \fBTk_CanvasGetTextInfo\fR.
.SS SELECTIONPROC
.PP
\fItypePtr\->selectionProc\fR is invoked by Tk during selection
retrievals; it must return part or all of the selected text in
the item (if any).
It is only relevant for item types that support text;
\fItypePtr\->selectionProc\fR may be specified as NULL for non-textual
item types.
The procedure must match the following prototype:
.PP
.CS
typedef int \fBTk_ItemSelectionProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIoffset\fR,
        char *\fIbuffer\fR,
        int \fImaxBytes\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIoffset\fR is an offset in bytes into the selection where 0 refers
to the first byte of the selection; it identifies
the first character that is to be returned in this call.
\fIbuffer\fR points to an area of memory in which to store the
requested bytes, and \fImaxBytes\fR specifies the maximum number
of bytes to return.
\fIselectionProc\fR should extract up to \fImaxBytes\fR characters
from the selection and copy them to \fImaxBytes\fR; it should
return a count of the number of bytes actually copied, which may
be less than \fImaxBytes\fR if there are not \fIoffset+maxBytes\fR bytes
in the selection.
.SS INSERTPROC
.PP
\fItypePtr\->insertProc\fR is invoked by Tk during
the \fBinsert\fR widget command to insert new text or coordinates into a
canvas item.
It is only relevant for item types that support the \fBinsert\fR method;
\fItypePtr\->insertProc\fR may be specified as NULL for other
item types.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemInsertProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIindex\fR,
        Tcl_Obj *\fIobj\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr\->insertProc\fR, and \fIobj\fR
contains new text to insert just before the character given
by \fIindex\fR.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobj\fR parameter will
actually contain a pointer to a constant string to be inserted.
If the item supports modification of the coordinates list by this
.PP
The type manager should insert the text and recompute the bounding
box in the item's header.
.SS DCHARSPROC
.PP
\fItypePtr\->dCharsProc\fR is invoked by Tk during the \fBdchars\fR
widget command to delete a range of text from a canvas item or a range of
coordinates from a pathed item.
It is only relevant for item types that support text;
\fItypePtr\->dCharsProc\fR may be specified as NULL for non-textual
item types that do not want to support coordinate deletion.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemDCharsProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        int \fIfirst\fR,
        int \fIlast\fR);
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIfirst\fR and \fIlast\fR give the indices of the first and last bytes
to be deleted, as returned by previous calls to \fItypePtr\->indexProc\fR.
The type manager should delete the specified characters and update
the bounding box in the item's header.
.SH "SEE ALSO"
Tk_CanvasPsY, Tk_CanvasTextInfo, Tk_CanvasTkwin
.SH KEYWORDS
canvas, focus, item type, selection, type manager







|


|




<
|


<

|
|
|
|
|
|
|

<







<

|
|

<



<
|


<

|
|
|
|
|

<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|


|
|
|

<

|
|
|
|
|
|

<


|


<
<
<

|


|


|



|


<

|
|
|
|

<


|






|
|


|


<

|
|
|
|
|
|

<


|





|





|
|

|
|


<

|
|
|
|
|

<


|


<
<
<
<
<




|
|
<

|
|

<

|
|
|
|
|

<


|






423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

438
439
440

441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456

457
458
459
460

461
462
463

464
465
466

467
468
469
470
471
472
473

474
475
476
477
478








































479

480
481
482
483
484
485
486

487
488
489
490
491
492
493
494

495
496
497
498
499



500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564

565
566
567
568
569
570
571

572
573
574
575
576





577
578
579
580
581
582

583
584
585
586

587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
upper left) to the space of Postscript (where the origin is at the
lower left).
.PP
In order to generate Postscript that complies with the Adobe Document
Structuring Conventions, Tk actually generates Postscript in two passes.
It calls each item's \fIpostscriptProc\fR in each pass.
The only purpose of the first pass is to collect font information
(which is done by \fBTk_CanvasPsFont\fR);  the actual Postscript is
discarded.
Tk sets the \fIprepass\fR argument to \fIpostscriptProc\fR to 1
during the first pass;  the type manager can use \fIprepass\fR to skip
all Postscript generation except for calls to \fBTk_CanvasPsFont\fR.
During the second pass \fIprepass\fR will be 0, so the type manager
must generate complete Postscript.
.SS SCALEPROC

\fItypePtr->scaleProc\fR is invoked by Tk to rescale a canvas item
during the \fBscale\fR widget command.
The procedure must match the following prototype:

.CS
typedef void Tk_ItemScaleProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    double \fIoriginX\fR,
    double \fIoriginY\fR,
    double \fIscaleX\fR,
    double \fIscaleY\fR);
.CE

The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIoriginX\fR and \fIoriginY\fR specify an origin relative to which
the item is to be scaled, and \fIscaleX\fR and \fIscaleY\fR give the
x and y scale factors.
The item should adjust its coordinates so that a point in the item
that used to have coordinates \fIx\fR and \fIy\fR will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where

.CS
\fIx\(fm = originX  + scaleX*(x-originX)
y\(fm = originY + scaleY*(y-originY)\fR
.CE

\fIscaleProc\fR must also update the bounding box in the item's
header.
.SS TRANSLATEPROC

\fItypePtr->translateProc\fR is invoked by Tk to translate a canvas item
during the \fBmove\fR widget command.
The procedure must match the following prototype:

.CS
typedef void Tk_ItemTranslateProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    double \fIdeltaX\fR,
    double \fIdeltaY\fR);
.CE

The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.








































.SS INDEXPROC

\fItypePtr->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text;
\fItypePtr->indexProc\fR may be specified as NULL for non-textual
item types.
The procedure must match the following prototype:

.CS
typedef int Tk_ItemIndexProc(
    Tcl_Interp *\fIinterp\fR,
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    char \fIindexString\fR,
    int *\fIindexPtr\fR);
.CE

The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all
have the usual meaning.
\fIindexString\fR contains a textual description of an index,
and \fIindexPtr\fR points to an integer value that should be
filled in with a numerical index.



It is up to the type manager to decide what forms of index
are supported (e.g., numbers, \fBinsert\fR,  \fBsel.first\fR,
\fBend\fR, etc.).
\fIindexProc\fR should return a Tcl completion code and set
\fIinterp->result\fR in the event of an error.
.SS ICURSORPROC
.PP
\fItypePtr->icursorProc\fR is invoked by Tk during
the \fBicursor\fR widget command to set the position of the
insertion cursor in a textual item.
It is only relevant for item types that support an insertion cursor;
\fItypePtr->icursorProc\fR may be specified as NULL for item types
that do not support an insertion cursor.
The procedure must match the following prototype:

.CS
typedef void Tk_ItemCursorProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIindex\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meanings, and
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr->insertProc\fR.
The type manager should position the insertion cursor in the
item just before the character given by \fIindex\fR.
Whether or not to actually display the insertion cursor is
determined by other information provided by \fBTk_CanvasGetTextInfo\fR.
.SS SELECTIONPROC
.PP
\fItypePtr->selectionProc\fR is invoked by Tk during selection
retrievals;  it must return part or all of the selected text in
the item (if any).
It is only relevant for item types that support text;
\fItypePtr->selectionProc\fR may be specified as NULL for non-textual
item types.
The procedure must match the following prototype:

.CS
typedef int Tk_ItemSelectionProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIoffset\fR,
    char *\fIbuffer\fR,
    int \fImaxBytes\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIoffset\fR is an offset in bytes into the selection where 0 refers
to the first byte of the selection;  it identifies
the first character that is to be returned in this call.
\fIbuffer\fR points to an area of memory in which to store the
requested bytes, and \fImaxBytes\fR specifies the maximum number
of bytes to return.
\fIselectionProc\fR should extract up to \fImaxBytes\fR characters
from the selection and copy them to \fImaxBytes\fR;  it should
return a count of the number of bytes actually copied, which may
be less than \fImaxBytes\fR if there are not \fIoffset+maxBytes\fR bytes
in the selection.
.SS INSERTPROC
.PP
\fItypePtr->insertProc\fR is invoked by Tk during
the \fBinsert\fR widget command to insert new text into a
canvas item.
It is only relevant for item types that support text;
\fItypePtr->insertProc\fR may be specified as NULL for non-textual
item types.
The procedure must match the following prototype:

.CS
typedef void Tk_ItemInsertProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIindex\fR,
    char *\fIstring\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr->insertProc\fR, and \fIstring\fR
contains new text to insert just before the character given
by \fIindex\fR.





The type manager should insert the text and recompute the bounding
box in the item's header.
.SS DCHARSPROC
.PP
\fItypePtr->dCharsProc\fR is invoked by Tk during the \fBdchars\fR
widget command to delete a range of text from a canvas item.

It is only relevant for item types that support text;
\fItypePtr->dCharsProc\fR may be specified as NULL for non-textual
item types.
The procedure must match the following prototype:

.CS
typedef void Tk_ItemDCharsProc(
    Tk_Canvas \fIcanvas\fR,
    Tk_Item *\fIitemPtr\fR,
    int \fIfirst\fR,
    int \fIlast\fR);
.CE

\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIfirst\fR and \fIlast\fR give the indices of the first and last bytes
to be deleted, as returned by previous calls to \fItypePtr->indexProc\fR.
The type manager should delete the specified characters and update
the bounding box in the item's header.
.SH "SEE ALSO"
Tk_CanvasPsY, Tk_CanvasTextInfo, Tk_CanvasTkwin
.SH KEYWORDS
canvas, focus, item type, selection, type manager

Changes to doc/CrtPhImgFmt.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
'\"
'\" 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.
'\"
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH Tk_CreatePhotoImageFormat 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreatePhotoImageFormat \- define new file format for photo images
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreatePhotoImageFormat\fR(\fIformatPtr\fR)
.SH ARGUMENTS
.AS "const Tk_PhotoImageFormat" *formatPtr
.AP "const Tk_PhotoImageFormat" *formatPtr in
Structure that defines the new file format.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreatePhotoImageFormat\fR is invoked to define a new file format
for image data for use with photo images.  The code that implements an
image file format is called an image file format handler, or
handler for short.  The photo image code
maintains a list of handlers that can be used to read and






|















|
|


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'\"
'\" 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.
'\" 
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH Tk_CreatePhotoImageFormat 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreatePhotoImageFormat \- define new file format for photo images
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreatePhotoImageFormat\fR(\fIformatPtr\fR)
.SH ARGUMENTS
.AS Tk_PhotoImageFormat *formatPtr
.AP Tk_PhotoImageFormat *formatPtr in
Structure that defines the new file format.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreatePhotoImageFormat\fR is invoked to define a new file format
for image data for use with photo images.  The code that implements an
image file format is called an image file format handler, or
handler for short.  The photo image code
maintains a list of handlers that can be used to read and
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
An image file format handler consists of a collection of procedures
plus a Tk_PhotoImageFormat structure, which contains the name of the
image file format and pointers to six procedures provided by the
handler to deal with files and strings in this format.  The
Tk_PhotoImageFormat structure contains the following fields:
.CS
typedef struct Tk_PhotoImageFormat {
    const char *\fIname\fR;
    Tk_ImageFileMatchProc *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProc *\fIstringMatchProc\fR;
    Tk_ImageFileReadProc *\fIfileReadProc\fR;
    Tk_ImageStringReadProc *\fIstringReadProc\fR;
    Tk_ImageFileWriteProc *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProc *\fIstringWriteProc\fR;
} \fBTk_PhotoImageFormat\fR;
.CE
.PP
The handler need not provide implementations of all six procedures.
For example, the procedures that handle string data would not be
provided for a format in which the image data are stored in binary,
and could therefore contain null characters.  If any procedure is not
implemented, the corresponding pointer in the Tk_PhotoImageFormat
structure should be set to NULL.  The handler must provide the
\fIfileMatchProc\fR procedure if it provides the \fIfileReadProc\fR
procedure, and the \fIstringMatchProc\fR procedure if it provides the
\fIstringReadProc\fR procedure.

.SS NAME
.PP
\fIformatPtr->name\fR provides a name for the image type.
Once \fBTk_CreatePhotoImageFormat\fR returns, this name may be used
in the \fB\-format\fR photo image configuration and subcommand option.
The manual page for the photo image (photo(n)) describes how image
file formats are chosen based on their names and the value given to
the \fB\-format\fR option. The first character of \fIformatPtr->name\fR
must not be an uppercase character from the ASCII character set
(that is, one of the characters \fBA\fR-\fBZ\fR).  Such names are used
only for legacy interface support (see below).

.SS FILEMATCHPROC
.PP
\fIformatPtr->fileMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler
suitable for reading data in a given file.
\fIformatPtr->fileMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileMatchProc\fR(
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
The \fIfileName\fR argument is the name of the file containing the
image data, which is open for reading as \fIchan\fR.  The
\fIformat\fR argument contains the value given for the
\fB\-format\fR option, or NULL if the option was not specified.
If the data in the file appears to be in the format supported by this
handler, the \fIformatPtr->fileMatchProc\fR procedure should store the
width and height of the image in *\fIwidthPtr\fR and *\fIheightPtr\fR
respectively, and return 1.  Otherwise it should return 0.

.SS STRINGMATCHPROC
.PP
\fIformatPtr->stringMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler for
suitable for reading data from a given string.
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringMatchProc\fR(
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
The \fIdata\fR argument points to the object containing the image
data.  The \fIformat\fR argument contains the value given for
the \fB\-format\fR option, or NULL if the option was not specified.
If the data in the string appears to be in the format supported by
this handler, the \fIformatPtr->stringMatchProc\fR procedure should
store the width and height of the image in *\fIwidthPtr\fR and
*\fIheightPtr\fR respectively, and return 1.  Otherwise it should
return 0.

.SS FILEREADPROC
.PP
\fIformatPtr->fileReadProc\fR provides the address of a procedure for
Tk to call to read data from an image file into a photo image.
\fIformatPtr->fileReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The image data is in the file named \fIfileName\fR, which is open for
reading as \fIchan\fR.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the file, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the file is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
The return value is a standard Tcl return value.

.SS STRINGREADPROC
.PP
\fIformatPtr->stringReadProc\fR provides the address of a procedure for
Tk to call to read data from a string into a photo image.
\fIformatPtr->stringReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The \fIdata\fR argument points to the image data in object form.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the string, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the string is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
The return value is a standard Tcl return value.

.SS FILEWRITEPROC
.PP
\fIformatPtr->fileWriteProc\fR provides the address of a procedure for
Tk to call to write data from a photo image to a file.
\fIformatPtr->fileWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to write the image; it should be used for reporting errors.
The image data to be written are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The \fIfileName\fR argument
points to the string giving the name of the file in which to write the
image data.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->fileWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
The return value is a standard Tcl return value.

.SS STRINGWRITEPROC
.PP
\fIformatPtr->stringWriteProc\fR provides the address of a procedure for
Tk to call to translate image data from a photo image into a string.
\fIformatPtr->stringWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIformat\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to convert the image; it should be used for reporting errors.
The image data to be converted are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The data for the string
should be put in the interpreter \fIinterp\fR result.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->stringWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
The return value is a standard Tcl return value.

.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of all the function pointer
types stored in fields of a \fBTk_PhotoImageFormat\fR struct were
incompatibly different.  Legacy programs and libraries dating from
those days may still contain code that defines extended Tk photo image
formats using the old interface.  The Tk header file will still support
this legacy interface if the code is compiled with the
macro \fBUSE_OLD_IMAGE\fR defined.  Alternatively, the legacy interfaces







|






|











>
|










>
|
<





|
|
|
|
|
|
|









>
|
<





|
|
|
|
|
|









>
|
<




|
|
|
|
|
|
|
|
|














>
|
<




|
|
|
|
|
|
|
|














>
|
<




|
|
|
|
|














>
|
<




|
|
|
|














>

<







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
An image file format handler consists of a collection of procedures
plus a Tk_PhotoImageFormat structure, which contains the name of the
image file format and pointers to six procedures provided by the
handler to deal with files and strings in this format.  The
Tk_PhotoImageFormat structure contains the following fields:
.CS
typedef struct Tk_PhotoImageFormat {
    char *\fIname\fR;
    Tk_ImageFileMatchProc *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProc *\fIstringMatchProc\fR;
    Tk_ImageFileReadProc *\fIfileReadProc\fR;
    Tk_ImageStringReadProc *\fIstringReadProc\fR;
    Tk_ImageFileWriteProc *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProc *\fIstringWriteProc\fR;
} Tk_PhotoImageFormat;
.CE
.PP
The handler need not provide implementations of all six procedures.
For example, the procedures that handle string data would not be
provided for a format in which the image data are stored in binary,
and could therefore contain null characters.  If any procedure is not
implemented, the corresponding pointer in the Tk_PhotoImageFormat
structure should be set to NULL.  The handler must provide the
\fIfileMatchProc\fR procedure if it provides the \fIfileReadProc\fR
procedure, and the \fIstringMatchProc\fR procedure if it provides the
\fIstringReadProc\fR procedure.

.SH NAME
.PP
\fIformatPtr->name\fR provides a name for the image type.
Once \fBTk_CreatePhotoImageFormat\fR returns, this name may be used
in the \fB\-format\fR photo image configuration and subcommand option.
The manual page for the photo image (photo(n)) describes how image
file formats are chosen based on their names and the value given to
the \fB\-format\fR option. The first character of \fIformatPtr->name\fR
must not be an uppercase character from the ASCII character set
(that is, one of the characters \fBA\fR-\fBZ\fR).  Such names are used
only for legacy interface support (see below).

.SH FILEMATCHPROC

\fIformatPtr->fileMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler
suitable for reading data in a given file.
\fIformatPtr->fileMatchProc\fR must match the following prototype:
.CS
typedef int Tk_ImageFileMatchProc(
    Tcl_Channel \fIchan\fR,
    const char *\fIfileName\fR,
    Tcl_Obj *\fIformat\fR,
    int *\fIwidthPtr\fR,
    int *\fIheightPtr\fR,
    Tcl_Interp *\fIinterp\fR);
.CE
The \fIfileName\fR argument is the name of the file containing the
image data, which is open for reading as \fIchan\fR.  The
\fIformat\fR argument contains the value given for the
\fB\-format\fR option, or NULL if the option was not specified.
If the data in the file appears to be in the format supported by this
handler, the \fIformatPtr->fileMatchProc\fR procedure should store the
width and height of the image in *\fIwidthPtr\fR and *\fIheightPtr\fR
respectively, and return 1.  Otherwise it should return 0.

.SH STRINGMATCHPROC

\fIformatPtr->stringMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler for
suitable for reading data from a given string.
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
typedef int Tk_ImageStringMatchProc(
    Tcl_Obj *\fIdata\fR,
    Tcl_Obj *\fIformat\fR,
    int *\fIwidthPtr\fR,
    int *\fIheightPtr\fR,
    Tcl_Interp *\fIinterp\fR);
.CE
The \fIdata\fR argument points to the object containing the image
data.  The \fIformat\fR argument contains the value given for
the \fB\-format\fR option, or NULL if the option was not specified.
If the data in the string appears to be in the format supported by
this handler, the \fIformatPtr->stringMatchProc\fR procedure should
store the width and height of the image in *\fIwidthPtr\fR and
*\fIheightPtr\fR respectively, and return 1.  Otherwise it should
return 0.

.SH FILEREADPROC

\fIformatPtr->fileReadProc\fR provides the address of a procedure for
Tk to call to read data from an image file into a photo image.
\fIformatPtr->fileReadProc\fR must match the following prototype:
.CS
typedef int Tk_ImageFileReadProc(
    Tcl_Interp *\fIinterp\fR,
    Tcl_Channel \fIchan\fR,
    const char *\fIfileName\fR,
    Tcl_Obj *\fIformat\fR,
    PhotoHandle \fIimageHandle\fR,
    int \fIdestX\fR, int \fIdestY\fR,
    int \fIwidth\fR, int \fIheight\fR,
    int \fIsrcX\fR, int \fIsrcY\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The image data is in the file named \fIfileName\fR, which is open for
reading as \fIchan\fR.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the file, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the file is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
The return value is a standard Tcl return value.

.SH STRINGREADPROC

\fIformatPtr->stringReadProc\fR provides the address of a procedure for
Tk to call to read data from a string into a photo image.
\fIformatPtr->stringReadProc\fR must match the following prototype:
.CS
typedef int Tk_ImageStringReadProc(
    Tcl_Interp *\fIinterp\fR,
    Tcl_Obj *\fIdata\fR,
    Tcl_Obj *\fIformat\fR,
    PhotoHandle \fIimageHandle\fR,
    int \fIdestX\fR, int \fIdestY\fR,
    int \fIwidth\fR, int \fIheight\fR,
    int \fIsrcX\fR, int \fIsrcY\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The \fIdata\fR argument points to the image data in object form.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the string, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the string is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
The return value is a standard Tcl return value.

.SH FILEWRITEPROC

\fIformatPtr->fileWriteProc\fR provides the address of a procedure for
Tk to call to write data from a photo image to a file.
\fIformatPtr->fileWriteProc\fR must match the following prototype:
.CS
typedef int Tk_ImageFileWriteProc(
    Tcl_Interp *\fIinterp\fR,
    const char *\fIfileName\fR,
    Tcl_Obj *\fIformat\fR,
    Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to write the image; it should be used for reporting errors.
The image data to be written are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The \fIfileName\fR argument
points to the string giving the name of the file in which to write the
image data.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->fileWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
The return value is a standard Tcl return value.

.SH STRINGWRITEPROC

\fIformatPtr->stringWriteProc\fR provides the address of a procedure for
Tk to call to translate image data from a photo image into a string.
\fIformatPtr->stringWriteProc\fR must match the following prototype:
.CS
typedef int Tk_ImageStringWriteProc(
    Tcl_Interp *\fIinterp\fR,
    Tcl_Obj *\fIformat\fR,
    Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to convert the image; it should be used for reporting errors.
The image data to be converted are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The data for the string
should be put in the interpreter \fIinterp\fR result.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->stringWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
The return value is a standard Tcl return value.

.SH "LEGACY INTERFACE SUPPORT"

In Tk 8.2 and earlier, the definition of all the function pointer
types stored in fields of a \fBTk_PhotoImageFormat\fR struct were
incompatibly different.  Legacy programs and libraries dating from
those days may still contain code that defines extended Tk photo image
formats using the old interface.  The Tk header file will still support
this legacy interface if the code is compiled with the
macro \fBUSE_OLD_IMAGE\fR defined.  Alternatively, the legacy interfaces
260
261
262
263
264
265
266

267
268

269
270
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.

.SH "SEE ALSO"
Tk_FindPhoto, Tk_PhotoPutBlock

.SH KEYWORDS
photo image, image file







>


>


262
263
264
265
266
267
268
269
270
271
272
273
274
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.

.SH "SEE ALSO"
Tk_FindPhoto, Tk_PhotoPutBlock

.SH KEYWORDS
photo image, image file

Changes to doc/CrtSelHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateSelHandler 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateSelHandler, Tk_DeleteSelHandler \- arrange to handle requests for a selection
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateSelHandler 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateSelHandler, Tk_DeleteSelHandler \- arrange to handle requests for a selection
.SH SYNOPSIS
.nf
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
requestor.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateSelHandler\fR arranges for a particular procedure
(\fIproc\fR) to be called whenever \fIselection\fR is owned by
\fItkwin\fR and the selection contents are requested in the
form given by \fItarget\fR.
\fITarget\fR should be one of
the entries defined in the left column of Table 2 of the
X Inter-Client Communication Conventions Manual (ICCCM) or
any other form in which an application is willing to present
the selection.  The most common form is STRING.
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_SelectionProc\fR:
.CS
typedef int \fBTk_SelectionProc\fR(
        ClientData \fIclientData\fR,
        int \fIoffset\fR,
        char *\fIbuffer\fR,
        int \fImaxBytes\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_CreateSelHandler\fR.
Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to retrieve the selection.  \fIOffset\fR specifies an
offset position into the selection, \fIbuffer\fR specifies a







|









|
|
|
|
|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
requestor.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateSelHandler\fR arranges for a particular procedure
(\fIproc\fR) to be called whenever \fIselection\fR is owned by
\fItkwin\fR and the selection contents are requested in the
form given by \fItarget\fR. 
\fITarget\fR should be one of
the entries defined in the left column of Table 2 of the
X Inter-Client Communication Conventions Manual (ICCCM) or
any other form in which an application is willing to present
the selection.  The most common form is STRING.
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_SelectionProc\fR:
.CS
typedef int Tk_SelectionProc(
    ClientData \fIclientData\fR,
    int \fIoffset\fR,
    char *\fIbuffer\fR,
    int \fImaxBytes\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_CreateSelHandler\fR.
Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to retrieve the selection.  \fIOffset\fR specifies an
offset position into the selection, \fIbuffer\fR specifies a
108
109
110
111
112
113
114

115
116
If \fBTk_CreateSelHandler\fR is called when there already exists a
handler for \fIselection\fR and \fItarget\fR on \fItkwin\fR, then the
existing handler is replaced with a new one.
.PP
\fBTk_DeleteSelHandler\fR removes the handler given by \fItkwin\fR,
\fIselection\fR, and \fItarget\fR, if such a handler exists.
If there is no such handler then it has no effect.

.SH KEYWORDS
format, handler, selection, target







>


108
109
110
111
112
113
114
115
116
117
If \fBTk_CreateSelHandler\fR is called when there already exists a
handler for \fIselection\fR and \fItarget\fR on \fItkwin\fR, then the
existing handler is replaced with a new one.
.PP
\fBTk_DeleteSelHandler\fR removes the handler given by \fItkwin\fR,
\fIselection\fR, and \fItarget\fR, if such a handler exists.
If there is no such handler then it has no effect.

.SH KEYWORDS
format, handler, selection, target

Changes to doc/CrtWindow.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateWindow 3 4.2 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateWindow, Tk_CreateWindowFromPath, Tk_DestroyWindow, Tk_MakeWindowExist \- create or delete window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateWindow 3 4.2 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateWindow, Tk_CreateWindowFromPath, Tk_DestroyWindow, Tk_MakeWindowExist \- create or delete window
.SH SYNOPSIS
.nf
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Token for window.
.AP "const char" *pathName in
Name of new window, specified as path name within application
(e.g. \fB.a.b.c\fR).
.BE
.SH DESCRIPTION
.PP
The procedures \fBTk_CreateWindow\fR,
\fBTk_CreateAnonymousWindow\fR, and \fBTk_CreateWindowFromPath\fR
are used to create new windows for
use in Tk-based applications.  Each of the procedures returns a token
that can be used to manipulate the window in other calls to the Tk
library.  If the window could not be created successfully, then NULL
is returned and the result of interpreter \fIinterp\fR is modified to
hold an error message.
.PP
Tk supports two different kinds of windows:  internal
windows and top-level windows.
An internal window is an interior window of a Tk application, such as a
scrollbar or menu bar or button.  A top-level window is one that is
created as a child of a screen's root window, rather than as an
interior window, but which is logically part of some existing main







|





|
|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Token for window.
.AP "const char" *pathName in
Name of new window, specified as path name within application
(e.g. \fB.a.b.c\fR).
.BE
.SH DESCRIPTION
.PP
The procedures \fBTk_CreateWindow\fR, 
\fBTk_CreateAnonymousWindow\fR, and \fBTk_CreateWindowFromPath\fR
are used to create new windows for
use in Tk-based applications.  Each of the procedures returns a token
that can be used to manipulate the window in other calls to the Tk
library.  If the window could not be created successfully, then NULL
is returned and \fIinterp->result\fR is modified to hold an error
message.
.PP
Tk supports two different kinds of windows:  internal
windows and top-level windows.
An internal window is an interior window of a Tk application, such as a
scrollbar or menu bar or button.  A top-level window is one that is
created as a child of a screen's root window, rather than as an
interior window, but which is logically part of some existing main
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
The only difference is that new X window for a top-level window
will not be a child of \fIparent\fR's X window.  For example, a pull-down
menu's \fIparent\fR would be the button-like window used to invoke it,
which would in turn be a child of the menu bar window.  A dialog box might
have the application's main window as its parent.
.PP
\fBTk_CreateAnonymousWindow\fR differs from \fBTk_CreateWindow\fR in
that it creates an unnamed window.  This window will be manipulatable
only using C interfaces, and will not be visible to Tcl scripts.  Both
interior windows and top-level windows may be created with
\fBTk_CreateAnonymousWindow\fR.
.PP
\fBTk_CreateWindowFromPath\fR offers an alternate way of specifying
new windows.  In \fBTk_CreateWindowFromPath\fR the new
window is specified with a token for any window in the target







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
The only difference is that new X window for a top-level window
will not be a child of \fIparent\fR's X window.  For example, a pull-down
menu's \fIparent\fR would be the button-like window used to invoke it,
which would in turn be a child of the menu bar window.  A dialog box might
have the application's main window as its parent.
.PP
\fBTk_CreateAnonymousWindow\fR differs from \fBTk_CreateWindow\fR in
that it creates an unnamed window.  This window will be manipulable
only using C interfaces, and will not be visible to Tcl scripts.  Both
interior windows and top-level windows may be created with
\fBTk_CreateAnonymousWindow\fR.
.PP
\fBTk_CreateWindowFromPath\fR offers an alternate way of specifying
new windows.  In \fBTk_CreateWindowFromPath\fR the new
window is specified with a token for any window in the target
137
138
139
140
141
142
143

144
145
146
the request and returned an event for it.
.PP
If a window has been created
but has not been mapped, so no X window exists, it is
possible to force the creation of the X window by
calling \fBTk_MakeWindowExist\fR.  This procedure issues
the X commands to instantiate the window given by \fItkwin\fR.

.SH KEYWORDS
create, deferred creation, destroy, display, internal window,
screen, top-level window, window







>



137
138
139
140
141
142
143
144
145
146
147
the request and returned an event for it.
.PP
If a window has been created
but has not been mapped, so no X window exists, it is
possible to force the creation of the X window by
calling \fBTk_MakeWindowExist\fR.  This procedure issues
the X commands to instantiate the window given by \fItkwin\fR.

.SH KEYWORDS
create, deferred creation, destroy, display, internal window,
screen, top-level window, window

Changes to doc/DeleteImg.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29

30
31
'\"
'\" 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.
'\"
.TH Tk_DeleteImage 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_DeleteImage \- Destroy an image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DeleteImage\fR(\fIinterp, name\fR)
.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter for which the image was created.
.AP "const char" *name in
Name of the image.
.BE

.SH DESCRIPTION
.PP
\fBTk_DeleteImage\fR deletes the image given by \fIinterp\fR
and \fIname\fR, if there is one.  All instances of that image
will redisplay as empty regions.  If the given image does not
exist then the procedure has no effect.

.SH KEYWORDS
delete image, image manager





|

















>






>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'\"
'\" 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.
'\" 
.TH Tk_DeleteImage 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_DeleteImage \- Destroy an image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DeleteImage\fR(\fIinterp, name\fR)
.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter for which the image was created.
.AP "const char" *name in
Name of the image.
.BE

.SH DESCRIPTION
.PP
\fBTk_DeleteImage\fR deletes the image given by \fIinterp\fR
and \fIname\fR, if there is one.  All instances of that image
will redisplay as empty regions.  If the given image does not
exist then the procedure has no effect.

.SH KEYWORDS
delete image, image manager

Changes to doc/DrawFocHlt.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_DrawFocusHighlight 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_DrawFocusHighlight \- draw the traversal highlight ring for a widget
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_DrawFocusHighlight 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_DrawFocusHighlight \- draw the traversal highlight ring for a widget
.SH SYNOPSIS
.nf
23
24
25
26
27
28
29

30
31
32
33
34

35
36
Graphics context to use for drawing the highlight.
.AP int width in
Width of the highlight ring, in pixels.
.AP Drawable drawable in
Drawable in which to draw the highlight;  usually an offscreen
pixmap for double buffering.
.BE

.SH DESCRIPTION
.PP
\fBTk_DrawFocusHighlight\fR is a utility procedure that draws the
traversal highlight ring for a widget.
It is typically invoked by widgets during redisplay.

.SH KEYWORDS
focus, traversal highlight







>





>


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Graphics context to use for drawing the highlight.
.AP int width in
Width of the highlight ring, in pixels.
.AP Drawable drawable in
Drawable in which to draw the highlight;  usually an offscreen
pixmap for double buffering.
.BE

.SH DESCRIPTION
.PP
\fBTk_DrawFocusHighlight\fR is a utility procedure that draws the
traversal highlight ring for a widget.
It is typically invoked by widgets during redisplay.

.SH KEYWORDS
focus, traversal highlight

Changes to doc/EventHndlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateEventHandler, Tk_DeleteEventHandler, Tk_GetButtonMask, Tk_SendVirtualEvent \- associate procedure callback with an X event
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_GetButtonMask\fR(\fIbutton\fR)
.sp
\fBTk_SendVirtualEvent\fR(\fItkwin, eventName, detail\fR)
.SH ARGUMENTS
.AS "unsigned long" clientData
.AP unsigned button in
Button number.
.AP "const char" *eventName in
The name of the virtual event.
.AP Tcl_Obj *detail in
Detail information for the virtual event.
.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
in the window given by \fItkwin\fR.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateEventHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever one of the event types specified
by \fImask\fR occurs in the window specified by \fItkwin\fR.
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_EventProc\fR:
.CS
typedef void \fBTk_EventProc\fR(
        ClientData \fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateEventHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
the window in which the event occurred.  \fIEventPtr\fR is
a pointer to the X event, which will be one of the ones






|




|







<
<
<
<


<
<
<
<
<
<











>














|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19




20
21






22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateEventHandler, Tk_DeleteEventHandler \- associate procedure callback with an X event
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)




.SH ARGUMENTS
.AS "unsigned long" clientData






.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
in the window given by \fItkwin\fR.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_CreateEventHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever one of the event types specified
by \fImask\fR occurs in the window specified by \fItkwin\fR.
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_EventProc\fR:
.CS
typedef void Tk_EventProc(
    ClientData \fIclientData\fR,
    XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateEventHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
the window in which the event occurred.  \fIEventPtr\fR is
a pointer to the X event, which will be one of the ones
77
78
79
80
81
82
83
84
85
86
87
88
89
90
When a window is deleted all of its handlers will be deleted
automatically;  in this case there is no need to call
\fBTk_DeleteEventHandler\fR.
.PP
If multiple handlers are declared for the same type of X event
on the same window, then the handlers will be invoked in the
order they were created.
.PP
\fBTk_GetButtonMask\fR returns the button mask corresponding to
the button. E.g it will return \fIButton1Mask\fR for button \fIButton1\fR.
.PP
\fBTk_SendVirtualEvent\fR sends a virtual event to Tk's event queue.
.SH KEYWORDS
bind, callback, event, handler







|
<
<
<
<


68
69
70
71
72
73
74
75




76
77
When a window is deleted all of its handlers will be deleted
automatically;  in this case there is no need to call
\fBTk_DeleteEventHandler\fR.
.PP
If multiple handlers are declared for the same type of X event
on the same window, then the handlers will be invoked in the
order they were created.





.SH KEYWORDS
bind, callback, event, handler

Changes to doc/FindPhoto.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30

31
32
33
34
35
36
37

38
39

40
41
42
43

44
45

46
47
48
49
50
51
52
'\"
'\" Copyright (c) 1994 The Australian National University
'\" Copyright (c) 1994-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.
'\"
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH Tk_FindPhoto 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FindPhoto, Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock, Tk_PhotoGetImage, Tk_PhotoBlank, Tk_PhotoExpand, Tk_PhotoGetSize, Tk_PhotoSetSize \- manipulate the image data stored in a photo image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_PhotoHandle
\fBTk_FindPhoto\fR(\fIinterp, imageName\fR)
.sp

int
\fBTk_PhotoPutBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
compRule\fR)
.sp
int
\fBTk_PhotoPutZoomedBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
zoomX, zoomY, subsampleX, subsampleY, compRule\fR)

.sp
int
\fBTk_PhotoGetImage\fR(\fIhandle, blockPtr\fR)
.sp
void
\fBTk_PhotoBlank\fR(\fIhandle\fR)
.sp

int
\fBTk_PhotoExpand\fR(\fIinterp, handle, width, height\fR)

.sp
void
\fBTk_PhotoGetSize\fR(\fIhandle, widthPtr, heightPtr\fR)
.sp

int
\fBTk_PhotoSetSize\fR(\fIinterp. handle, width, height\fR)

.SH ARGUMENTS
.AS Tk_PhotoImageBlock window_path
.AP Tcl_Interp *interp in
Interpreter in which image was created and in which error reporting is
to be done.
.AP "const char" *imageName in
Name of the photo image.






|
















>







>







>


>




>


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
'\"
'\" Copyright (c) 1994 The Australian National University
'\" Copyright (c) 1994-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.
'\" 
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH Tk_FindPhoto 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FindPhoto, Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock, Tk_PhotoGetImage, Tk_PhotoBlank, Tk_PhotoExpand, Tk_PhotoGetSize, Tk_PhotoSetSize \- manipulate the image data stored in a photo image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_PhotoHandle
\fBTk_FindPhoto\fR(\fIinterp, imageName\fR)
.sp
.VS 8.5
int
\fBTk_PhotoPutBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
compRule\fR)
.sp
int
\fBTk_PhotoPutZoomedBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
zoomX, zoomY, subsampleX, subsampleY, compRule\fR)
.VE 8.5
.sp
int
\fBTk_PhotoGetImage\fR(\fIhandle, blockPtr\fR)
.sp
void
\fBTk_PhotoBlank\fR(\fIhandle\fR)
.sp
.VS 8.5
int
\fBTk_PhotoExpand\fR(\fIinterp, handle, width, height\fR)
.VE 8.5
.sp
void
\fBTk_PhotoGetSize\fR(\fIhandle, widthPtr, heightPtr\fR)
.sp
.VS 8.5
int
\fBTk_PhotoSetSize\fR(\fIinterp. handle, width, height\fR)
.VE 8.5
.SH ARGUMENTS
.AS Tk_PhotoImageBlock window_path
.AP Tcl_Interp *interp in
Interpreter in which image was created and in which error reporting is
to be done.
.AP "const char" *imageName in
Name of the photo image.
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
.AP int zoomX in
Specifies the zoom factor to be applied in the X direction to pixels
being written to the photo image.
.AP int zoomY in
Specifies the zoom factor to be applied in the Y direction to pixels
being written to the photo image.
.BE

.SH DESCRIPTION
.PP
\fBTk_FindPhoto\fR returns an opaque handle that is used to identify a
particular photo image to the other procedures.  The parameter is the
name of the image, that is, the name specified to the \fBimage create
photo\fR command, or assigned by that command if no name was specified.
If \fIimageName\fR does not exist or is not a photo image,
\fBTk_FindPhoto\fR returns NULL.
.PP
\fBTk_PhotoPutBlock\fR is used to supply blocks of image data to be
displayed.  The call affects an area of the image of size
\fIwidth\fR x \fIheight\fR pixels, with its top-left corner at
coordinates (\fIx\fR,\fIy\fR).  All of \fIwidth\fR, \fIheight\fR,
\fIx\fR, and \fIy\fR must be non-negative.
If part of this area lies outside the







>






<
<







95
96
97
98
99
100
101
102
103
104
105
106
107
108


109
110
111
112
113
114
115
.AP int zoomX in
Specifies the zoom factor to be applied in the X direction to pixels
being written to the photo image.
.AP int zoomY in
Specifies the zoom factor to be applied in the Y direction to pixels
being written to the photo image.
.BE

.SH DESCRIPTION
.PP
\fBTk_FindPhoto\fR returns an opaque handle that is used to identify a
particular photo image to the other procedures.  The parameter is the
name of the image, that is, the name specified to the \fBimage create
photo\fR command, or assigned by that command if no name was specified.


.PP
\fBTk_PhotoPutBlock\fR is used to supply blocks of image data to be
displayed.  The call affects an area of the image of size
\fIwidth\fR x \fIheight\fR pixels, with its top-left corner at
coordinates (\fIx\fR,\fIy\fR).  All of \fIwidth\fR, \fIheight\fR,
\fIx\fR, and \fIy\fR must be non-negative.
If part of this area lies outside the
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171

172
173
174
175
176
177
178
.CS
typedef struct {
    unsigned char *\fIpixelPtr\fR;
    int \fIwidth\fR;
    int \fIheight\fR;
    int \fIpitch\fR;
    int \fIpixelSize\fR;
    int \fIoffset\fR[4];
} \fBTk_PhotoImageBlock\fR;
.CE
The \fIpixelPtr\fR field points to the first pixel, that is, the
top-left pixel in the block.
The \fIwidth\fR and \fIheight\fR fields specify the dimensions of the
block of pixels.  The \fIpixelSize\fR field specifies the address
difference between two horizontally adjacent pixels.  It should be 4 for
RGB and 2 for grayscale image data.  Other values are possible, if the
offsets in the \fIoffset\fR array are adjusted accordingly (e.g. for
red, green and blue data stored in different planes).  Using such a
layout is strongly discouraged, though. Due to a bug, it might not work
correctly if an alpha channel is provided. (see the \fBBUGS\fR section
below). The \fIpitch\fR field specifies the
address difference between two vertically adjacent pixels.  The
\fIoffset\fR array contains the offsets from the address of a pixel
to the addresses of the bytes containing the red, green, blue and alpha
(transparency) components.  If the offsets for red, green and blue are
equal, the image is interpreted as grayscale. If they differ, RGB data
is assumed. Normally the offsets will be 0, 1, 2, 3 for RGB data
and 0, 0, 0, 1 for grayscale.  It is possible to provide image data
without an alpha channel by setting the offset for alpha to a negative
value and adjusting the \fIpixelSize\fR field accordingly. This use is
discouraged, though (see the \fBBUGS\fR section below).
.PP
The \fIcompRule\fR parameter to \fBTk_PhotoPutBlock\fR specifies a
compositing rule that says what to do with transparent pixels.  The
value \fBTK_PHOTO_COMPOSITE_OVERLAY\fR says that the previous contents of
the photo image should show through, and the value
\fBTK_PHOTO_COMPOSITE_SET\fR says that the previous contents of the photo
image should be completely ignored, and the values from the block be
copied directly across.  The behavior in Tk8.3 and earlier was
equivalent to having \fBTK_PHOTO_COMPOSITE_OVERLAY\fR as a compositing rule.
.PP
The value given for the \fIwidth\fR and \fIheight\fR parameters to
\fBTk_PhotoPutBlock\fR do not have to correspond to the values specified
in \fIblock\fR.  If they are smaller, \fBTk_PhotoPutBlock\fR extracts a
sub-block from the image data supplied.  If they are larger, the data
given are replicated (in a tiled fashion) to fill the specified area.
These rules operate independently in the horizontal and vertical
directions.
.PP

\fBTk_PhotoPutBlock\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.

.PP
\fBTk_PhotoPutZoomedBlock\fR works like \fBTk_PhotoPutBlock\fR except that
the image can be reduced or enlarged for display.  The
\fIsubsampleX\fR and \fIsubsampleY\fR parameters allow the size of the
image to be reduced by subsampling.
\fBTk_PhotoPutZoomedBlock\fR will use only pixels from the input image
whose X coordinates are multiples of \fIsubsampleX\fR, and whose Y







|
|





|
<
<
<
<
<
|



|
|
<
<
<
|
<


















>




>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138





139
140
141
142
143
144



145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
.CS
typedef struct {
    unsigned char *\fIpixelPtr\fR;
    int \fIwidth\fR;
    int \fIheight\fR;
    int \fIpitch\fR;
    int \fIpixelSize\fR;
    int \fIoffset[4]\fR;
} Tk_PhotoImageBlock;
.CE
The \fIpixelPtr\fR field points to the first pixel, that is, the
top-left pixel in the block.
The \fIwidth\fR and \fIheight\fR fields specify the dimensions of the
block of pixels.  The \fIpixelSize\fR field specifies the address
difference between two horizontally adjacent pixels.  Often it is 3





or 4, but it can have any value.  The \fIpitch\fR field specifies the
address difference between two vertically adjacent pixels.  The
\fIoffset\fR array contains the offsets from the address of a pixel
to the addresses of the bytes containing the red, green, blue and alpha
(transparency) components.  These are normally 0, 1, 2 and 3, but can
have other values, e.g., for images that are stored as separate red,



green and blue planes.

.PP
The \fIcompRule\fR parameter to \fBTk_PhotoPutBlock\fR specifies a
compositing rule that says what to do with transparent pixels.  The
value \fBTK_PHOTO_COMPOSITE_OVERLAY\fR says that the previous contents of
the photo image should show through, and the value
\fBTK_PHOTO_COMPOSITE_SET\fR says that the previous contents of the photo
image should be completely ignored, and the values from the block be
copied directly across.  The behavior in Tk8.3 and earlier was
equivalent to having \fBTK_PHOTO_COMPOSITE_OVERLAY\fR as a compositing rule.
.PP
The value given for the \fIwidth\fR and \fIheight\fR parameters to
\fBTk_PhotoPutBlock\fR do not have to correspond to the values specified
in \fIblock\fR.  If they are smaller, \fBTk_PhotoPutBlock\fR extracts a
sub-block from the image data supplied.  If they are larger, the data
given are replicated (in a tiled fashion) to fill the specified area.
These rules operate independently in the horizontal and vertical
directions.
.PP
.VS 8.5
\fBTk_PhotoPutBlock\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.
.VE 8.5
.PP
\fBTk_PhotoPutZoomedBlock\fR works like \fBTk_PhotoPutBlock\fR except that
the image can be reduced or enlarged for display.  The
\fIsubsampleX\fR and \fIsubsampleY\fR parameters allow the size of the
image to be reduced by subsampling.
\fBTk_PhotoPutZoomedBlock\fR will use only pixels from the input image
whose X coordinates are multiples of \fIsubsampleX\fR, and whose Y
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227

228
229
230
231
232
233
234
235
236

237
238
239
240

241
242
243

244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
.PP
\fBTk_PhotoGetImage\fR can be used to retrieve image data from a photo
image.  \fBTk_PhotoGetImage\fR fills
in the structure pointed to by the \fIblockPtr\fR parameter with values
that describe the address and layout of the image data that the
photo image has stored internally.  The values are valid
until the image is destroyed or its size is changed.
.PP
It is possible to modify an image by writing directly to the data
the \fIpixelPtr\fR field points to. The size of the image cannot be
changed this way, though.
Also, changes made by writing directly to \fIpixelPtr\fR will not be
immediately visible, but only after a call to
\fBTk_ImageChanged\fR or after an event that causes the interested
widgets to redraw themselves.
For these reasons usually it is preferable to make changes to
a copy of the image data and write it back with
\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR.
.PP
\fBTk_PhotoGetImage\fR returns 1 for compatibility with the
corresponding procedure in the old photo widget.
.PP
\fBTk_PhotoBlank\fR blanks the entire area of the
photo image.  Blank areas of a photo image are transparent.
.PP
\fBTk_PhotoExpand\fR requests that the widget's image be expanded to be
at least \fIwidth\fR x \fIheight\fR pixels in size.  The width and/or
height are unchanged if the user has specified an explicit image width
or height with the \fB\-width\fR and/or \fB\-height\fR configuration
options, respectively.
If the image data
are being supplied in many small blocks, it is more efficient to use
\fBTk_PhotoExpand\fR or \fBTk_PhotoSetSize\fR at the beginning rather than
allowing the image to expand in many small increments as image blocks
are supplied.
.PP

\fBTk_PhotoExpand\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.

.PP
\fBTk_PhotoSetSize\fR specifies the size of the image, as if the user
had specified the given \fIwidth\fR and \fIheight\fR values to the
\fB\-width\fR and \fB\-height\fR configuration options.  A value of
zero for \fIwidth\fR or \fIheight\fR does not change the image's width
or height, but allows the width or height to be changed by subsequent
calls to \fBTk_PhotoPutBlock\fR, \fBTk_PhotoPutZoomedBlock\fR or
\fBTk_PhotoExpand\fR.
.PP

\fBTk_PhotoSetSize\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.

.PP
\fBTk_PhotoGetSize\fR returns the dimensions of the image in
*\fIwidthPtr\fR and *\fIheightPtr\fR.

.SH PORTABILITY
.PP
In Tk 8.3 and earlier, \fBTk_PhotoPutBlock\fR and
\fBTk_PhotoPutZoomedBlock\fR had different signatures. If you want to
compile code that uses the old interface against 8.4 without updating
your code, compile it with the flag
-DUSE_COMPOSITELESS_PHOTO_PUT_BLOCK.  Code linked using Stubs against
older versions of Tk will continue to work.
.PP

In Tk 8.4, \fBTk_PhotoPutBlock\fR, \fBTk_PhotoPutZoomedBlock\fR,
\fBTk_PhotoExpand\fR and \fBTk_PhotoSetSize\fR did not take an
\fIinterp\fR argument or return any result code.  If insufficient
memory was available for an image, Tk would panic.  This behaviour is
still supported if you compile your extension with the additional flag
-DUSE_PANIC_ON_PHOTO_ALLOC_FAILURE.  Code linked using Stubs against
older versions of Tk will continue to work.
.SH BUGS
The \fBTk_PhotoImageBlock\fR structure used to provide image data to
\fBTk_PhotoPutBlock\fR promises great flexibility in the layout of the
data (e.g. separate planes for the red, green, blue and alpha
channels).  Unfortunately, the implementation fails to hold this
promise.  The problem is that the \fIpixelSize\fR field is
(incorrectly) used to determine whether the image has an alpha channel.
Currently, if the offset for the alpha channel is greater or equal than
\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is
present and makes the image fully opaque.  This means that for layouts
where the channels are separate (or any other exotic layout where
\fIpixelSize\fR has to be smaller than the alpha offset), the alpha
channel will not be read correctly.  In order to be on the safe side
if this issue will be corrected in a future release, it is strongly
recommended you always provide alpha data - even if the image has no
transparency - and only use the "standard" layout with a
\fIpixelSize\fR of 2 for grayscale and 4 for RGB data with
\fIoffset\fRs of 0, 0, 0, 1 or 0, 1, 2, 3 respectively.
.SH CREDITS
.PP
The code for the photo image type was developed by Paul Mackerras,
based on his earlier photo widget code.

.SH KEYWORDS
photo, image







<
<
<
<
<
<
<
<
<
<
<
<

















>




>









>




>



>









>







|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




>


186
187
188
189
190
191
192












193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
















254
255
256
257
258
259
260
.PP
\fBTk_PhotoGetImage\fR can be used to retrieve image data from a photo
image.  \fBTk_PhotoGetImage\fR fills
in the structure pointed to by the \fIblockPtr\fR parameter with values
that describe the address and layout of the image data that the
photo image has stored internally.  The values are valid
until the image is destroyed or its size is changed.












\fBTk_PhotoGetImage\fR returns 1 for compatibility with the
corresponding procedure in the old photo widget.
.PP
\fBTk_PhotoBlank\fR blanks the entire area of the
photo image.  Blank areas of a photo image are transparent.
.PP
\fBTk_PhotoExpand\fR requests that the widget's image be expanded to be
at least \fIwidth\fR x \fIheight\fR pixels in size.  The width and/or
height are unchanged if the user has specified an explicit image width
or height with the \fB\-width\fR and/or \fB\-height\fR configuration
options, respectively.
If the image data
are being supplied in many small blocks, it is more efficient to use
\fBTk_PhotoExpand\fR or \fBTk_PhotoSetSize\fR at the beginning rather than
allowing the image to expand in many small increments as image blocks
are supplied.
.PP
.VS 8.5
\fBTk_PhotoExpand\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.
.VE 8.5
.PP
\fBTk_PhotoSetSize\fR specifies the size of the image, as if the user
had specified the given \fIwidth\fR and \fIheight\fR values to the
\fB\-width\fR and \fB\-height\fR configuration options.  A value of
zero for \fIwidth\fR or \fIheight\fR does not change the image's width
or height, but allows the width or height to be changed by subsequent
calls to \fBTk_PhotoPutBlock\fR, \fBTk_PhotoPutZoomedBlock\fR or
\fBTk_PhotoExpand\fR.
.PP
.VS 8.5
\fBTk_PhotoSetSize\fR normally returns \fBTCL_OK\fR, though if it cannot
allocate sufficient memory to hold the resulting image, \fBTCL_ERROR\fR is
returned instead and, if the \fIinterp\fR argument is non-NULL, an
error message is placed in the interpreter's result.
.VE 8.5
.PP
\fBTk_PhotoGetSize\fR returns the dimensions of the image in
*\fIwidthPtr\fR and *\fIheightPtr\fR.

.SH PORTABILITY
.PP
In Tk 8.3 and earlier, \fBTk_PhotoPutBlock\fR and
\fBTk_PhotoPutZoomedBlock\fR had different signatures. If you want to
compile code that uses the old interface against 8.4 without updating
your code, compile it with the flag
-DUSE_COMPOSITELESS_PHOTO_PUT_BLOCK.  Code linked using Stubs against
older versions of Tk will continue to work.
.PP
.VS 8.5
In Tk 8.4, \fBTk_PhotoPutBlock\fR, \fBTk_PhotoPutZoomedBlock\fR,
\fBTk_PhotoExpand\fR and \fBTk_PhotoSetSize\fR did not take an
\fIinterp\fR argument or return any result code.  If insufficient
memory was available for an image, Tk would panic.  This behaviour is
still supported if you compile your extension with the additional flag
-DUSE_PANIC_ON_PHOTO_ALLOC_FAILURE.  Code linked using Stubs against
older versions of Tk will continue to work.
.VE 8.5

















.SH CREDITS
.PP
The code for the photo image type was developed by Paul Mackerras,
based on his earlier photo widget code.

.SH KEYWORDS
photo, image

Changes to doc/FontId.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" 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.
'\"
.TH Tk_FontId 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for
fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Font
\fBTk_FontId(\fItkfont\fB)\fR





|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" 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.
'\" 
.TH Tk_FontId 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for 
fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Font
\fBTk_FontId(\fItkfont\fB)\fR
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Pointer to an initialized \fBTcl_DString\fR to which the name of the
Postscript font that corresponds to \fItkfont\fR will be appended.
.BE
.SH DESCRIPTION
.PP
Given a \fItkfont\fR, \fBTk_FontId\fR returns the token that should be
selected into an XGCValues structure in order to construct a graphics
context that can be used to draw text in the specified font.
.PP
\fBTk_GetFontMetrics\fR computes the ascent, descent, and linespace of the
\fItkfont\fR in pixels and stores those values in the structure pointer to by
\fIfmPtr\fR.  These values can be used in computations such as to space
multiple lines of text, to align the baselines of text in different
fonts, and to vertically align text in a given region.  See the
documentation for the \fBfont\fR command for definitions of the terms
ascent, descent, and linespace, used in font metrics.
.PP
\fBTk_PostscriptFontName\fR maps a \fItkfont\fR to the corresponding
Postscript font name that should be used when printing.  The return value
is the size in points of the \fItkfont\fR and the Postscript font name is
appended to \fIdsPtr\fR.  \fIDsPtr\fR must refer to an initialized
\fBTcl_DString\fR.  Given a
.QW reasonable
Postscript printer, the
following screen font families should print correctly:
.IP
\fBAvant Garde\fR, \fBArial\fR, \fBBookman\fR, \fBCourier\fR,
\fBCourier New\fR, \fBGeneva\fR, \fBHelvetica\fR, \fBMonaco\fR,
\fBNew Century Schoolbook\fR, \fBNew York\fR, \fBPalatino\fR, \fBSymbol\fR,
\fBTimes\fR, \fBTimes New Roman\fR, \fBZapf Chancery\fR, and
\fBZapf Dingbats\fR.
.PP
Any other font families may not print correctly because the computed
Postscript font name may be incorrect or not exist on the printer.
.SH "DATA STRUCTURES"
.PP
The \fBTk_FontMetrics\fR data structure is used by \fBTk_GetFontMetrics\fR to
return information about a font and is defined as follows:
.CS
typedef struct Tk_FontMetrics {
    int \fIascent\fR;
    int \fIdescent\fR;
    int \fIlinespace\fR;
} \fBTk_FontMetrics\fR;
.CE
.PP
The \fIascent\fR field is the amount in pixels that the tallest
letter sticks up above the baseline, plus any extra blank space added
by the designer of the font.
.PP
The \fIdescent\fR is the largest amount in pixels that any letter







|







|










|


|





<







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Pointer to an initialized \fBTcl_DString\fR to which the name of the
Postscript font that corresponds to \fItkfont\fR will be appended.
.BE
.SH DESCRIPTION
.PP
Given a \fItkfont\fR, \fBTk_FontId\fR returns the token that should be
selected into an XGCValues structure in order to construct a graphics
context that can be used to draw text in the specified font.  
.PP
\fBTk_GetFontMetrics\fR computes the ascent, descent, and linespace of the
\fItkfont\fR in pixels and stores those values in the structure pointer to by
\fIfmPtr\fR.  These values can be used in computations such as to space
multiple lines of text, to align the baselines of text in different
fonts, and to vertically align text in a given region.  See the
documentation for the \fBfont\fR command for definitions of the terms
ascent, descent, and linespace, used in font metrics.  
.PP
\fBTk_PostscriptFontName\fR maps a \fItkfont\fR to the corresponding
Postscript font name that should be used when printing.  The return value
is the size in points of the \fItkfont\fR and the Postscript font name is
appended to \fIdsPtr\fR.  \fIDsPtr\fR must refer to an initialized
\fBTcl_DString\fR.  Given a
.QW reasonable
Postscript printer, the
following screen font families should print correctly:
.IP
\fBAvant Garde\fR, \fBArial\fR, \fBBookman\fR, \fBCourier\fR, 
\fBCourier New\fR, \fBGeneva\fR, \fBHelvetica\fR, \fBMonaco\fR,
\fBNew Century Schoolbook\fR, \fBNew York\fR, \fBPalatino\fR, \fBSymbol\fR,
\fBTimes\fR, \fBTimes New Roman\fR, \fBZapf Chancery\fR, and 
\fBZapf Dingbats\fR.
.PP
Any other font families may not print correctly because the computed
Postscript font name may be incorrect or not exist on the printer.
.SH "DATA STRUCTURES"

The \fBTk_FontMetrics\fR data structure is used by \fBTk_GetFontMetrics\fR to
return information about a font and is defined as follows:
.CS
typedef struct Tk_FontMetrics {
    int \fIascent\fR;
    int \fIdescent\fR;
    int \fIlinespace\fR;
} Tk_FontMetrics;
.CE
.PP
The \fIascent\fR field is the amount in pixels that the tallest
letter sticks up above the baseline, plus any extra blank space added
by the designer of the font.
.PP
The \fIdescent\fR is the largest amount in pixels that any letter

Changes to doc/FreeXId.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


















29
30
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_FreeXId 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FreeXId \- make X resource identifier available for reuse
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_FreeXId(\fIdisplay, id\fB)\fR
.SH ARGUMENTS
.AS Display *display out
.AP Display *display in
Display for which \fIid\fR was allocated.
.AP XID id in
Identifier of X resource (window, font, pixmap, cursor, graphics
context, or colormap) that is no longer in use.
.BE
.SH DESCRIPTION
.PP
This function is deprecated, it doesn't do anything since 2008-08-19.


















.SH KEYWORDS
resource identifier






|




















|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_FreeXId 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FreeXId \- make X resource identifier available for reuse
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_FreeXId(\fIdisplay, id\fB)\fR
.SH ARGUMENTS
.AS Display *display out
.AP Display *display in
Display for which \fIid\fR was allocated.
.AP XID id in
Identifier of X resource (window, font, pixmap, cursor, graphics
context, or colormap) that is no longer in use.
.BE
.SH DESCRIPTION
.PP
The default allocator for resource identifiers provided by Xlib is very
simple-minded and does not allow resource identifiers to be re-used.
If a long-running application reaches the end of the resource id
space, it will generate an X protocol error and crash.
Tk replaces the default id allocator with its own allocator, which
allows identifiers to be reused.
In order for this to work, \fBTk_FreeXId\fR must be called to
tell the allocator about resources that have been freed.
Tk automatically calls \fBTk_FreeXId\fR whenever it frees a
resource, so if you use procedures like \fBTk_GetFont\fR,
\fBTk_GetGC\fR, and \fBTk_GetPixmap\fR then you need not call
\fBTk_FreeXId\fR.
However, if you allocate resources directly from Xlib, for example
by calling \fBXCreatePixmap\fR, then you should call \fBTk_FreeXId\fR
when you call the corresponding Xlib free procedure, such as
\fBXFreePixmap\fR.
If you do not call \fBTk_FreeXId\fR then the resource identifier will
be lost, which could cause problems if the application runs long enough
to lose all of the available identifiers.
.SH KEYWORDS
resource identifier

Changes to doc/GeomReq.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GeometryRequest 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GeometryRequest, Tk_SetMinimumRequestSize, Tk_SetInternalBorder, Tk_SetInternalBorderEx \- specify desired geometry or internal border for a window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GeometryRequest 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GeometryRequest, Tk_SetMinimumRequestSize, Tk_SetInternalBorder, Tk_SetInternalBorderEx \- specify desired geometry or internal border for a window
.SH SYNOPSIS
.nf
40
41
42
43
44
45
46

47
48
49
50
51
52
53
.AP int right in
Space to leave for right side of internal border for \fItkwin\fR, in pixel units.
.AP int top in
Space to leave for top side of internal border for \fItkwin\fR, in pixel units.
.AP int bottom in
Space to leave for bottom side of internal border for \fItkwin\fR, in pixel units.
.BE

.SH DESCRIPTION
.PP
\fBTk_GeometryRequest\fR is called by widget code to indicate its
preference for the dimensions of a particular window.  The arguments
to \fBTk_GeometryRequest\fR are made available to the geometry
manager for the window, which then decides on the actual geometry
for the window.  Although geometry managers generally try to satisfy







>







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.AP int right in
Space to leave for right side of internal border for \fItkwin\fR, in pixel units.
.AP int top in
Space to leave for top side of internal border for \fItkwin\fR, in pixel units.
.AP int bottom in
Space to leave for bottom side of internal border for \fItkwin\fR, in pixel units.
.BE

.SH DESCRIPTION
.PP
\fBTk_GeometryRequest\fR is called by widget code to indicate its
preference for the dimensions of a particular window.  The arguments
to \fBTk_GeometryRequest\fR are made available to the geometry
manager for the window, which then decides on the actual geometry
for the window.  Although geometry managers generally try to satisfy
84
85
86
87
88
89
90

91
92
\fBTk_SetMinimumRequestSize\fR, \fBTk_SetInternalBorder\fR and
\fBTk_SetInternalBorderEx\fR can be retrieved using the macros
\fBTk_ReqWidth\fR, \fBTk_ReqHeight\fR, \fBTk_MinReqWidth\fR,
\fBTk_MinReqHeight\fR, \fBTk_MinReqWidth\fR, \fBTk_InternalBorderLeft\fR,
\fBTk_InternalBorderRight\fR, \fBTk_InternalBorderTop\fR and
\fBTk_InternalBorderBottom\fR.
See the \fBTk_WindowId\fR manual entry for details.

.SH KEYWORDS
geometry, request







>


85
86
87
88
89
90
91
92
93
94
\fBTk_SetMinimumRequestSize\fR, \fBTk_SetInternalBorder\fR and
\fBTk_SetInternalBorderEx\fR can be retrieved using the macros
\fBTk_ReqWidth\fR, \fBTk_ReqHeight\fR, \fBTk_MinReqWidth\fR,
\fBTk_MinReqHeight\fR, \fBTk_MinReqWidth\fR, \fBTk_InternalBorderLeft\fR,
\fBTk_InternalBorderRight\fR, \fBTk_InternalBorderTop\fR and
\fBTk_InternalBorderBottom\fR.
See the \fBTk_WindowId\fR manual entry for details.

.SH KEYWORDS
geometry, request

Changes to doc/GetAnchor.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_GetAnchorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetAnchorFromObj, Tk_GetAnchor, Tk_NameOfAnchor \- translate between strings and anchor positions
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_GetAnchorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetAnchorFromObj, Tk_GetAnchor, Tk_NameOfAnchor \- translate between strings and anchor positions
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
\fBTk_NameOfAnchor(\fIanchor\fB)\fR
.SH ARGUMENTS
.AS "Tk_Anchor" *anchorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of anchor point:
.QW \fBn\fR  ,
.QW \fBne\fR ,
.QW \fBe\fR  ,
.QW \fBse\fR ,
.QW \fBs\fR  ,
.QW \fBsw\fR ,
.QW \fBw\fR  ,
.QW \fBnw\fR ,
or
.QW \fBcenter\fR ;
internal rep will be modified to cache corresponding Tk_Anchor. In the
case of
.QW \fBcenter\fR
on input, a non-empty abbreviation of it may also be used on input.
.AP "const char" *string in
Same as \fIobjPtr\fR except description of anchor point is passed as
a string.
.AP int *anchorPtr out
Pointer to location in which to store anchor position corresponding to
\fIobjPtr\fR or \fIstring\fR.
.AP Tk_Anchor anchor in







|
|
|
|
|
|
|
|

|
|
<
<
<







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41



42
43
44
45
46
47
48
\fBTk_NameOfAnchor(\fIanchor\fB)\fR
.SH ARGUMENTS
.AS "Tk_Anchor" *anchorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of anchor point:
.QW n  ,
.QW ne ,
.QW e  ,
.QW se ,
.QW s  ,
.QW sw ,
.QW w  ,
.QW nw ,
or
.QW center ;
internal rep will be modified to cache corresponding Tk_Anchor.



.AP "const char" *string in
Same as \fIobjPtr\fR except description of anchor point is passed as
a string.
.AP int *anchorPtr out
Pointer to location in which to store anchor position corresponding to
\fIobjPtr\fR or \fIstring\fR.
.AP Tk_Anchor anchor in

Changes to doc/GetBitmap.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_AllocBitmapFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocBitmapFromObj, Tk_GetBitmap, Tk_GetBitmapFromObj, Tk_DefineBitmap, Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeBitmapFromObj, Tk_FreeBitmap \- maintain database of single-plane pixmaps
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_AllocBitmapFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocBitmapFromObj, Tk_GetBitmap, Tk_GetBitmapFromObj, Tk_DefineBitmap, Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeBitmapFromObj, Tk_FreeBitmap \- maintain database of single-plane pixmaps
.SH SYNOPSIS
.nf
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
String value describes desired bitmap; internal rep will be
modified to cache pointer to corresponding Pixmap.
.AP "const char" *info in
Same as \fIobjPtr\fR except description of bitmap is passed as a string and
resulting Pixmap is not cached.
.AP "const char" *name in
Name for new bitmap to be defined.
.AP "const void" *source in
Data for bitmap, in standard bitmap format.
Must be stored in static memory whose value will never change.
.AP "int" width in
Width of bitmap.
.AP "int" height in
Height of bitmap.
.AP "int" *widthPtr out
Pointer to word to fill in with \fIbitmap\fR's width.
.AP "int" *heightPtr out
Pointer to word to fill in with \fIbitmap\fR's height.
.AP Display *display in
Display for which \fIbitmap\fR was allocated.
.AP Pixmap bitmap in
Identifier for a bitmap allocated by \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.BE

.SH DESCRIPTION
.PP
These procedures manage a collection of bitmaps (one-plane pixmaps)
being used by an application.  The procedures allow bitmaps to be
re-used efficiently, thereby avoiding server overhead, and also
allow bitmaps to be named with character strings.
.PP
\fBTk_AllocBitmapFromObj\fR returns a Pixmap identifier for a bitmap
that matches the description in \fIobjPtr\fR and is suitable for use
in \fItkwin\fR.  It re-uses an existing bitmap, if possible, and
creates a new one otherwise.  \fIObjPtr\fR's value must have one
of the following forms:
.TP 20
\fB@\fIfileName\fR
\fIFileName\fR must be the name of a file containing a bitmap
description in the standard X11 format.
.TP 20
\fIname\fR
\fIName\fR must be the name of a bitmap defined previously with
a call to \fBTk_DefineBitmap\fR.  The following names are pre-defined
by Tk:
.RS
.TP 12







|
















>















|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
String value describes desired bitmap; internal rep will be
modified to cache pointer to corresponding Pixmap.
.AP "const char" *info in
Same as \fIobjPtr\fR except description of bitmap is passed as a string and
resulting Pixmap is not cached.
.AP "const char" *name in
Name for new bitmap to be defined.
.AP "const char" *source in
Data for bitmap, in standard bitmap format.
Must be stored in static memory whose value will never change.
.AP "int" width in
Width of bitmap.
.AP "int" height in
Height of bitmap.
.AP "int" *widthPtr out
Pointer to word to fill in with \fIbitmap\fR's width.
.AP "int" *heightPtr out
Pointer to word to fill in with \fIbitmap\fR's height.
.AP Display *display in
Display for which \fIbitmap\fR was allocated.
.AP Pixmap bitmap in
Identifier for a bitmap allocated by \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.BE

.SH DESCRIPTION
.PP
These procedures manage a collection of bitmaps (one-plane pixmaps)
being used by an application.  The procedures allow bitmaps to be
re-used efficiently, thereby avoiding server overhead, and also
allow bitmaps to be named with character strings.
.PP
\fBTk_AllocBitmapFromObj\fR returns a Pixmap identifier for a bitmap
that matches the description in \fIobjPtr\fR and is suitable for use
in \fItkwin\fR.  It re-uses an existing bitmap, if possible, and
creates a new one otherwise.  \fIObjPtr\fR's value must have one
of the following forms:
.TP 20
\fB@\fIfileName\fR
\fIFileName\fR must be the name of a file containing a bitmap
description in the standard X11 or X10 format.
.TP 20
\fIname\fR
\fIName\fR must be the name of a bitmap defined previously with
a call to \fBTk_DefineBitmap\fR.  The following names are pre-defined
by Tk:
.RS
.TP 12
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
argument gives a name for the bitmap;  it must not previously
have been used in a call to \fBTk_DefineBitmap\fR.
The arguments \fIsource\fR, \fIwidth\fR, and \fIheight\fR
describe the bitmap.
\fBTk_DefineBitmap\fR normally returns \fBTCL_OK\fR; if an error occurs
(e.g. a bitmap named \fInameId\fR has already been defined) then
\fBTCL_ERROR\fR is returned and an error message is left in
interpreter \fIinterp\fR's result.
Note:  \fBTk_DefineBitmap\fR expects the memory pointed to by
\fIsource\fR to be static:  \fBTk_DefineBitmap\fR does not make
a private copy of this memory, but uses the bytes pointed to
by \fIsource\fR later in calls to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.PP
Typically \fBTk_DefineBitmap\fR is used by \fB#include\fR-ing a







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
argument gives a name for the bitmap;  it must not previously
have been used in a call to \fBTk_DefineBitmap\fR.
The arguments \fIsource\fR, \fIwidth\fR, and \fIheight\fR
describe the bitmap.
\fBTk_DefineBitmap\fR normally returns \fBTCL_OK\fR; if an error occurs
(e.g. a bitmap named \fInameId\fR has already been defined) then
\fBTCL_ERROR\fR is returned and an error message is left in
\fIinterp->result\fR.
Note:  \fBTk_DefineBitmap\fR expects the memory pointed to by
\fIsource\fR to be static:  \fBTk_DefineBitmap\fR does not make
a private copy of this memory, but uses the bytes pointed to
by \fIsource\fR later in calls to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.PP
Typically \fBTk_DefineBitmap\fR is used by \fB#include\fR-ing a
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294

295
296
For \fBTk_FreeBitmapFromObj\fR the bitmap to release is specified
with the same information used to create it; for
\fBTk_FreeBitmap\fR the bitmap to release is specified
with its Pixmap token.
There should be exactly one call to \fBTk_FreeBitmapFromObj\fR
or \fBTk_FreeBitmap\fR for each call to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.

.SH BUGS
.PP
In determining whether an existing bitmap can be used to satisfy
a new request, \fBTk_AllocBitmapFromObj\fR and \fBTk_GetBitmap\fR
consider only the immediate value of the string description.  For
example, when a file name is passed to \fBTk_GetBitmap\fR,
\fBTk_GetBitmap\fR will assume it is safe to re-use an existing
bitmap created from the same file name:  it will not check to
see whether the file itself has changed, or whether the current
directory has changed, thereby causing the name to refer to
a different file.

.SH KEYWORDS
bitmap, pixmap







>

<









>


278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
For \fBTk_FreeBitmapFromObj\fR the bitmap to release is specified
with the same information used to create it; for
\fBTk_FreeBitmap\fR the bitmap to release is specified
with its Pixmap token.
There should be exactly one call to \fBTk_FreeBitmapFromObj\fR
or \fBTk_FreeBitmap\fR for each call to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.

.SH BUGS

In determining whether an existing bitmap can be used to satisfy
a new request, \fBTk_AllocBitmapFromObj\fR and \fBTk_GetBitmap\fR
consider only the immediate value of the string description.  For
example, when a file name is passed to \fBTk_GetBitmap\fR,
\fBTk_GetBitmap\fR will assume it is safe to re-use an existing
bitmap created from the same file name:  it will not check to
see whether the file itself has changed, or whether the current
directory has changed, thereby causing the name to refer to
a different file.

.SH KEYWORDS
bitmap, pixmap

Changes to doc/GetCapStyl.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetCapStyle 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetCapStyle, Tk_NameOfCapStyle \- translate between strings and cap styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetCapStyle(\fIinterp, string, capPtr\fB)\fR
.sp
const char *
\fBTk_NameOfCapStyle(\fIcap\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *capPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of cap style \- one of
.QW \fBbutt\fR ,
.QW \fBprojecting\fR ,
or
.QW \fBround\fR
\- or a unique abbreviation of one.
.AP int *capPtr out
Pointer to location in which to store X cap style corresponding to
\fIstring\fR.
.AP int cap in
Cap style: one of \fBCapButt\fR, \fBCapProjecting\fR, or \fBCapRound\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetCapStyle\fR places in \fI*capPtr\fR the X cap style
corresponding to \fIstring\fR.
This will be one of the values
\fBCapButt\fR, \fBCapProjecting\fR, or \fBCapRound\fR.
Cap styles are typically used in X graphics contexts to indicate
how the end-points of lines should be capped.
See the X documentation for information on what each style
implies.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIstring\fR does not contain a valid cap style
or an abbreviation of one of these names, then an error message is
stored in interpreter \fIinterp\fR's result, \fBTCL_ERROR\fR is returned, and
\fI*capPtr\fR is unmodified.
.PP
\fBTk_NameOfCapStyle\fR is the logical inverse of \fBTk_GetCapStyle\fR.
Given a cap style such as \fBCapButt\fR it returns a
statically-allocated string corresponding to \fIcap\fR.
If \fIcap\fR is not a legal cap style, then
.QW "unknown cap style"
is returned.

.SH KEYWORDS
butt, cap style, projecting, round






|



















|
|
|

|
<






>















|








>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetCapStyle 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetCapStyle, Tk_NameOfCapStyle \- translate between strings and cap styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetCapStyle(\fIinterp, string, capPtr\fB)\fR
.sp
const char *
\fBTk_NameOfCapStyle(\fIcap\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *capPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of cap style: one of
.QW butt ,
.QW projecting ,
or
.QW round .

.AP int *capPtr out
Pointer to location in which to store X cap style corresponding to
\fIstring\fR.
.AP int cap in
Cap style: one of \fBCapButt\fR, \fBCapProjecting\fR, or \fBCapRound\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetCapStyle\fR places in \fI*capPtr\fR the X cap style
corresponding to \fIstring\fR.
This will be one of the values
\fBCapButt\fR, \fBCapProjecting\fR, or \fBCapRound\fR.
Cap styles are typically used in X graphics contexts to indicate
how the end-points of lines should be capped.
See the X documentation for information on what each style
implies.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIstring\fR does not contain a valid cap style
or an abbreviation of one of these names, then an error message is
stored in \fIinterp->result\fR, \fBTCL_ERROR\fR is returned, and
\fI*capPtr\fR is unmodified.
.PP
\fBTk_NameOfCapStyle\fR is the logical inverse of \fBTk_GetCapStyle\fR.
Given a cap style such as \fBCapButt\fR it returns a
statically-allocated string corresponding to \fIcap\fR.
If \fIcap\fR is not a legal cap style, then
.QW "unknown cap style"
is returned.

.SH KEYWORDS
butt, cap style, projecting, round

Changes to doc/GetClrmap.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetColormap 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetColormap, Tk_PreserveColormap, Tk_FreeColormap \- allocate and free colormaps
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetColormap 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetColormap, Tk_PreserveColormap, Tk_FreeColormap \- allocate and free colormaps
.SH SYNOPSIS
.nf

Changes to doc/GetColor.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1991 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.
'\"
.TH Tk_AllocColorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1991 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.
'\" 
.TH Tk_AllocColorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Pointer to X color information.  Must have been allocated by previous
call to \fBTk_AllocColorFromObj\fR, \fBTk_GetColor\fR or
\fBTk_GetColorByValue\fR, except when passed to \fBTk_NameOfColor\fR.
.AP Drawable drawable in
Drawable in which the result graphics context will be used.  Must have
same screen and depth as the window for which the color was allocated.
.BE

.SH DESCRIPTION
.PP
These procedures manage the colors being used by a Tk application.
They allow colors to be shared whenever possible, so that colormap
space is preserved, and they pick closest available colors when
colormap space is exhausted.
.PP
Given a textual description of a color, \fBTk_AllocColorFromObj\fR
locates a pixel value that may be used to render the color
in a particular window.  The desired color is specified with a
value whose string value must have one of the following forms:
.TP 20
\fIcolorname\fR
Any of the valid textual names for a color defined in the
server's color database file, such as \fBred\fR or \fBPeachPuff\fR.
.TP 20
\fB#\fIRGB\fR
.TP 20







>









|
|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Pointer to X color information.  Must have been allocated by previous
call to \fBTk_AllocColorFromObj\fR, \fBTk_GetColor\fR or
\fBTk_GetColorByValue\fR, except when passed to \fBTk_NameOfColor\fR.
.AP Drawable drawable in
Drawable in which the result graphics context will be used.  Must have
same screen and depth as the window for which the color was allocated.
.BE

.SH DESCRIPTION
.PP
These procedures manage the colors being used by a Tk application.
They allow colors to be shared whenever possible, so that colormap
space is preserved, and they pick closest available colors when
colormap space is exhausted.
.PP
Given a textual description of a color, \fBTk_AllocColorFromObj\fR
locates a pixel value that may be used to render the color
in a particular window.  The desired color is specified with an
object whose string value must have one of the following forms:
.TP 20
\fIcolorname\fR
Any of the valid textual names for a color defined in the
server's color database file, such as \fBred\fR or \fBPeachPuff\fR.
.TP 20
\fB#\fIRGB\fR
.TP 20
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
will use the closest existing color in the colormap.
\fBTk_AllocColorFromObj\fR caches information about
the return value in \fIobjPtr\fR, which speeds up future calls to procedures
such as \fBTk_AllocColorFromObj\fR and \fBTk_GetColorFromObj\fR.
.PP
\fBTk_GetColor\fR is identical to \fBTk_AllocColorFromObj\fR except
that the description of the color is specified with a string instead
of a value.  This prevents \fBTk_GetColor\fR from caching the
return value, so \fBTk_GetColor\fR is less efficient than
\fBTk_AllocColorFromObj\fR.
.PP
\fBTk_GetColorFromObj\fR returns the token for an existing color, given
the window and description used to create the color.
\fBTk_GetColorFromObj\fR does not actually create the color; the color
must already have been created with a previous call to
\fBTk_AllocColorFromObj\fR or \fBTk_GetColor\fR.  The return
value is cached in \fIobjPtr\fR, which speeds up
future calls to \fBTk_GetColorFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.
.PP
\fBTk_GetColorByValue\fR is similar to \fBTk_GetColor\fR except that
the desired color is indicated with the \fIred\fR, \fIgreen\fR, and
\fIblue\fR fields of the structure pointed to by \fIcolorPtr\fR.
.PP
This package maintains a database
of all the colors currently in use.
If the same color is requested multiple times from
\fBTk_GetColor\fR or \fBTk_AllocColorFromObj\fR (e.g. by different
windows), or if the
same intensities are requested multiple times from
\fBTk_GetColorByValue\fR, then existing pixel values will
be re-used.  Re-using an existing pixel avoids any interaction
with the window server, which makes the allocation much more
efficient.  These procedures also provide a portable interface that
works across all platforms.  For this reason, you should generally use
\fBTk_AllocColorFromObj\fR, \fBTk_GetColor\fR, or \fBTk_GetColorByValue\fR







|




















|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
will use the closest existing color in the colormap.
\fBTk_AllocColorFromObj\fR caches information about
the return value in \fIobjPtr\fR, which speeds up future calls to procedures
such as \fBTk_AllocColorFromObj\fR and \fBTk_GetColorFromObj\fR.
.PP
\fBTk_GetColor\fR is identical to \fBTk_AllocColorFromObj\fR except
that the description of the color is specified with a string instead
of an object.  This prevents \fBTk_GetColor\fR from caching the
return value, so \fBTk_GetColor\fR is less efficient than
\fBTk_AllocColorFromObj\fR.
.PP
\fBTk_GetColorFromObj\fR returns the token for an existing color, given
the window and description used to create the color.
\fBTk_GetColorFromObj\fR does not actually create the color; the color
must already have been created with a previous call to
\fBTk_AllocColorFromObj\fR or \fBTk_GetColor\fR.  The return
value is cached in \fIobjPtr\fR, which speeds up
future calls to \fBTk_GetColorFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.
.PP
\fBTk_GetColorByValue\fR is similar to \fBTk_GetColor\fR except that
the desired color is indicated with the \fIred\fR, \fIgreen\fR, and
\fIblue\fR fields of the structure pointed to by \fIcolorPtr\fR.
.PP
This package maintains a database
of all the colors currently in use.
If the same color is requested multiple times from
\fBTk_GetColor\fR or \fBTk_AllocColorFromObj\fR (e.g. by different
windows), or if the 
same intensities are requested multiple times from
\fBTk_GetColorByValue\fR, then existing pixel values will
be re-used.  Re-using an existing pixel avoids any interaction
with the window server, which makes the allocation much more
efficient.  These procedures also provide a portable interface that
works across all platforms.  For this reason, you should generally use
\fBTk_AllocColorFromObj\fR, \fBTk_GetColor\fR, or \fBTk_GetColorByValue\fR
169
170
171
172
173
174
175
176
with the same information used to create it; for
\fBTk_FreeColor\fR the color to release is specified
with a pointer to its XColor structure.
There should be exactly one call to \fBTk_FreeColorFromObj\fR
or \fBTk_FreeColor\fR for each call to \fBTk_AllocColorFromObj\fR,
\fBTk_GetColor\fR, or \fBTk_GetColorByValue\fR.
.SH KEYWORDS
color, intensity, value, pixel value







|
170
171
172
173
174
175
176
177
with the same information used to create it; for
\fBTk_FreeColor\fR the color to release is specified
with a pointer to its XColor structure.
There should be exactly one call to \fBTk_FreeColorFromObj\fR
or \fBTk_FreeColor\fR for each call to \fBTk_AllocColorFromObj\fR,
\fBTk_GetColor\fR, or \fBTk_GetColorByValue\fR.
.SH KEYWORDS
color, intensity, object, pixel value

Changes to doc/GetCursor.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_AllocCursorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_AllocCursorFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf
63
64
65
66
67
68
69

70
71
72
73
74
75
76
.AP Display *display in
Display for which \fIcursor\fR was allocated.
.AP Tk_Cursor cursor in
Opaque Tk identifier for cursor.  If passed to \fBTk_FreeCursor\fR, must
have been returned by some previous call to \fBTk_GetCursor\fR or
\fBTk_GetCursorFromData\fR.
.BE

.SH DESCRIPTION
.PP
These procedures manage a collection of cursors
being used by an application.  The procedures allow cursors to be
re-used efficiently, thereby avoiding server overhead, and also
allow cursors to be named with character strings.
.PP







>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
.AP Display *display in
Display for which \fIcursor\fR was allocated.
.AP Tk_Cursor cursor in
Opaque Tk identifier for cursor.  If passed to \fBTk_FreeCursor\fR, must
have been returned by some previous call to \fBTk_GetCursor\fR or
\fBTk_GetCursorFromData\fR.
.BE

.SH DESCRIPTION
.PP
These procedures manage a collection of cursors
being used by an application.  The procedures allow cursors to be
re-used efficiently, thereby avoiding server overhead, and also
allow cursors to be named with character strings.
.PP
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
cursor.  If there are conflicts color cursors will always be loaded
in preference to black and white cursors.
.RE
.TP
\fB@\fIsourceName\0maskName\0fgColor\0bgColor\fR
In this form, \fIsourceName\fR and \fImaskName\fR are the names of
files describing cursors for the cursor's source bits and mask.
Each file must be in standard X11 cursor format.
\fIFgColor\fR and \fIbgColor\fR
indicate the colors to use for the
cursor, in any of the forms acceptable to \fBTk_GetColor\fR.  This
form of the command will not work on Macintosh or Windows computers.
.TP
\fB@\fIsourceName\0fgColor\fR
This form is similar to the one above, except that the source is
used as mask also.  This means that the cursor's background is







|
|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
cursor.  If there are conflicts color cursors will always be loaded
in preference to black and white cursors.
.RE
.TP
\fB@\fIsourceName\0maskName\0fgColor\0bgColor\fR
In this form, \fIsourceName\fR and \fImaskName\fR are the names of
files describing cursors for the cursor's source bits and mask.
Each file must be in standard X11 or X10 cursor format.
\fIFgColor\fR and \fIbgColor\fR 
indicate the colors to use for the
cursor, in any of the forms acceptable to \fBTk_GetColor\fR.  This
form of the command will not work on Macintosh or Windows computers.
.TP
\fB@\fIsourceName\0fgColor\fR
This form is similar to the one above, except that the source is
used as mask also.  This means that the cursor's background is
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
For \fBTk_FreeCursorFromObj\fR the cursor to release is specified
with the same information used to create it; for
\fBTk_FreeCursor\fR the cursor to release is specified
with its Tk_Cursor token.
There should be exactly one call to \fBTk_FreeCursor\fR for
each call to \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
or \fBTk_GetCursorFromData\fR.

.SH BUGS
.PP
In determining whether an existing cursor can be used to satisfy
a new request, \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
and \fBTk_GetCursorFromData\fR
consider only the immediate values of their arguments.  For
example, when a file name is passed to \fBTk_GetCursor\fR,
\fBTk_GetCursor\fR will assume it is safe to re-use an existing
cursor created from the same file name:  it will not check to
see whether the file itself has changed, or whether the current
directory has changed, thereby causing the name to refer to
a different file.  Similarly, \fBTk_GetCursorFromData\fR assumes
that if the same \fIsource\fR pointer is used in two different calls,
then the pointers refer to the same data;  it does not check to
see if the actual data values have changed.

.SH KEYWORDS
cursor







>

<













>


209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
For \fBTk_FreeCursorFromObj\fR the cursor to release is specified
with the same information used to create it; for
\fBTk_FreeCursor\fR the cursor to release is specified
with its Tk_Cursor token.
There should be exactly one call to \fBTk_FreeCursor\fR for
each call to \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
or \fBTk_GetCursorFromData\fR.

.SH BUGS

In determining whether an existing cursor can be used to satisfy
a new request, \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
and \fBTk_GetCursorFromData\fR
consider only the immediate values of their arguments.  For
example, when a file name is passed to \fBTk_GetCursor\fR,
\fBTk_GetCursor\fR will assume it is safe to re-use an existing
cursor created from the same file name:  it will not check to
see whether the file itself has changed, or whether the current
directory has changed, thereby causing the name to refer to
a different file.  Similarly, \fBTk_GetCursorFromData\fR assumes
that if the same \fIsource\fR pointer is used in two different calls,
then the pointers refer to the same data;  it does not check to
see if the actual data values have changed.

.SH KEYWORDS
cursor

Changes to doc/GetDash.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetDash 3 8.3 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetDash \- convert from string to valid dash structure.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR

int
\fBTk_GetDash\fR(\fIinterp, string, dashPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_Dash *dashPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
Textual value to be converted.
.AP Tk_Dash *dashPtr out
Points to place to store the dash pattern
value converted from \fIstring\fR. Must not be NULL.
.BE

.SH DESCRIPTION
.PP
These procedure parses the string and fills in the result in the
Tk_Dash structure. The string can be a list of integers or a
character string containing only
.QW \fB.,-_\fR
and spaces. If all
goes well, \fBTCL_OK\fR is returned and a dash descriptor is stored
in the variable pointed to by \fIdashPtr\fR.
If \fIstring\fR does not have the
proper syntax then \fBTCL_ERROR\fR is returned, an error message is left
in the interpreter's result, and nothing is stored at *\fIdashPtr\fR.
.PP
The first possible syntax is a list of integers. Each element
represents the number of pixels of a line segment. Only the odd
segments are drawn using the
.QW outline
color. The other segments are drawn transparent.
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and can not
occur in the first position of the string. Some examples:
.PP
.CS
    \-dash .     = \-dash {2 4}
    \-dash -     = \-dash {6 4}
    \-dash -.    = \-dash {6 4 2 4}
    \-dash -..   = \-dash {6 4 2 4 2 4}
    \-dash {. }  = \-dash {2 8}
    \-dash ,     = \-dash {4 4}
.CE
.PP
The main difference between this syntax and the numeric is that it
is shape-conserving. This means that all values in the dash
list will be multiplied by the line width before display. This
ensures that
.QW .
will always be displayed as a dot and
.QW -
always as a dash regardless of the line width.
.PP
On systems where only a limited set of dash patterns, the dash
pattern will be displayed as the most close dash pattern that
is available. For example, on Windows only the first 4 of the
above examples are available; the last 2 examples will be
displayed identically to the first one.
.SH "SEE ALSO"
canvas(n), Tk_CreateItemType(3)
.SH KEYWORDS
dash, conversion






|








|


<




|



|

>





|
|
|
<
<











|


|
<


|
|
|




|


|


|





|
|
|
<


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetDash 3 8.3 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetDash \- convert from string to valid dash structure.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetDash\fR(\fIinterp, string, dashPtr\fR)

.SH ARGUMENTS
.AS Tk_Dash *dashPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char *" string in
Textual value to be converted.
.AP Tk_Dash *dashPtr out
Points to place to store the dash pattern
value converted from \fIstring\fR.
.BE

.SH DESCRIPTION
.PP
These procedure parses the string and fills in the result in the
Tk_Dash structure. The string can be a list of integers or a
character string containing only
.QW \fB.,\-_\fR
or spaces. If all
goes well, \fBTCL_OK\fR is returned. If \fIstring\fR does not have the


proper syntax then \fBTCL_ERROR\fR is returned, an error message is left
in the interpreter's result, and nothing is stored at *\fIdashPtr\fR.
.PP
The first possible syntax is a list of integers. Each element
represents the number of pixels of a line segment. Only the odd
segments are drawn using the
.QW outline
color. The other segments are drawn transparent.
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,\-_ \fR" .
The space can be used
to enlarge the space between other line elements, and can not
occur as the first position in the string. Some examples:

.CS
    \-dash .     = \-dash {2 4}
    \-dash \-     = \-dash {6 4}
    \-dash \-.    = \-dash {6 4 2 4}
    \-dash \-..   = \-dash {6 4 2 4 2 4}
    \-dash {. }  = \-dash {2 8}
    \-dash ,     = \-dash {4 4}
.CE
.PP
The main difference of this syntax with the previous is that it
is shape-conserving. This means that all values in the dash
list will be multiplied by the line width before display. This
assures that
.QW .
will always be displayed as a dot and
.QW \-
always as a dash regardless of the line width.
.PP
On systems where only a limited set of dash patterns, the dash
pattern will be displayed as the most close dash pattern that
is available. For example, on Windows only the first 4 of the
above examples are available. The last 2 examples will be
displayed identically as the first one.


.SH KEYWORDS
dash, conversion

Changes to doc/GetFont.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
'\"
'\" Copyright (c) 1990-1992 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.
'\"
.TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FontGetDescription, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font
\fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Font
\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR
.sp
Tk_Font
\fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
Tcl_Obj *
\fBTk_FontGetDescription(\fItkfont\fB)\fR
.sp
const char *
\fBTk_NameOfFont(\fItkfont\fB)\fR
.sp
Tk_Font
\fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
\fBTk_FreeFont(\fItkfont\fB)\fR

.SH ARGUMENTS
.AS "const char" *tkfont
.AP "Tcl_Interp" *interp in
Interpreter to use for error reporting.  If \fBNULL\fR, then no error
messages are left after errors.
.AP Tk_Window tkwin in
Token for window in which font will be used.






|




|




|


|
|

|

<
<
<




|




>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'\"
'\" Copyright (c) 1990-1992 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.
'\" 
.TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font 
\fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Font 
\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR 
.sp
Tk_Font 
\fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR



.sp
const char *
\fBTk_NameOfFont(\fItkfont\fB)\fR
.sp
Tk_Font 
\fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
\fBTk_FreeFont(\fItkfont\fB)\fR

.SH ARGUMENTS
.AS "const char" *tkfont
.AP "Tcl_Interp" *interp in
Interpreter to use for error reporting.  If \fBNULL\fR, then no error
messages are left after errors.
.AP Tk_Window tkwin in
Token for window in which font will be used.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
.SH DESCRIPTION
.PP
\fBTk_AllocFontFromObj\fR finds the font indicated by \fIobjPtr\fR and
returns a token that represents the font.  The return value can be used
in subsequent calls to procedures such as \fBTk_GetFontMetrics\fR,
\fBTk_MeasureChars\fR, and \fBTk_FreeFont\fR.  The Tk_Font token
will remain valid until
\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR is called to release it.
\fIObjPtr\fR can contain either a symbolic name or a font description; see
the documentation for the \fBfont\fR command for a description of the
valid formats.  If \fBTk_AllocFontFromObj\fR is unsuccessful (because,
for example, \fIobjPtr\fR did not contain a valid font specification) then it
returns \fBNULL\fR and leaves an error message in \fIinterp\fR's result
if \fIinterp\fR is not \fBNULL\fR.  \fBTk_AllocFontFromObj\fR caches
information about the return







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
.SH DESCRIPTION
.PP
\fBTk_AllocFontFromObj\fR finds the font indicated by \fIobjPtr\fR and
returns a token that represents the font.  The return value can be used
in subsequent calls to procedures such as \fBTk_GetFontMetrics\fR,
\fBTk_MeasureChars\fR, and \fBTk_FreeFont\fR.  The Tk_Font token
will remain valid until
\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR is called to release it. 
\fIObjPtr\fR can contain either a symbolic name or a font description; see
the documentation for the \fBfont\fR command for a description of the
valid formats.  If \fBTk_AllocFontFromObj\fR is unsuccessful (because,
for example, \fIobjPtr\fR did not contain a valid font specification) then it
returns \fBNULL\fR and leaves an error message in \fIinterp\fR's result
if \fIinterp\fR is not \fBNULL\fR.  \fBTk_AllocFontFromObj\fR caches
information about the return
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
\fBTk_AllocFontFromObj\fR and \fBTk_GetFont\fR maintain
a database of all fonts they have allocated.  If
the same font is requested multiple times (e.g. by different
windows or for different purposes), then a single Tk_Font will be
shared for all uses.  The underlying resources will be freed automatically
when no-one is using the font anymore.
.PP
The procedure \fBTk_FontGetDescription\fR returns information about the font
description as a Tcl list. One possible result is "{{DejaVu Sans} -16 bold underline}".
.PP
The procedure \fBTk_NameOfFont\fR is roughly the inverse of
\fBTk_GetFont\fR.  Given a \fItkfont\fR that was created by
\fBTk_GetFont\fR (or \fBTk_AllocFontFromObj\fR), the return value is
the \fIstring\fR argument that was
passed to \fBTk_GetFont\fR to create the font.  The string returned by
\fBTk_NameOfFont\fR is only guaranteed to persist until the \fItkfont\fR
is deleted.  The caller must not modify this string.
.PP
When a font is no longer needed,
\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR should be called to
release it.  For \fBTk_FreeFontFromObj\fR the font to release is specified
with the same information used to create it; for
\fBTk_FreeFont\fR the font to release is specified
with its Tk_Font token.  There should be
exactly one call to \fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR
for each call to \fBTk_AllocFontFromObj\fR or \fBTk_GetFont\fR.

.SH "SEE ALSO"
Tk_FontId(3)
.SH KEYWORDS
font







<
<
<
















>




85
86
87
88
89
90
91



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
\fBTk_AllocFontFromObj\fR and \fBTk_GetFont\fR maintain
a database of all fonts they have allocated.  If
the same font is requested multiple times (e.g. by different
windows or for different purposes), then a single Tk_Font will be
shared for all uses.  The underlying resources will be freed automatically
when no-one is using the font anymore.
.PP



The procedure \fBTk_NameOfFont\fR is roughly the inverse of
\fBTk_GetFont\fR.  Given a \fItkfont\fR that was created by
\fBTk_GetFont\fR (or \fBTk_AllocFontFromObj\fR), the return value is
the \fIstring\fR argument that was
passed to \fBTk_GetFont\fR to create the font.  The string returned by
\fBTk_NameOfFont\fR is only guaranteed to persist until the \fItkfont\fR
is deleted.  The caller must not modify this string.
.PP
When a font is no longer needed,
\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR should be called to
release it.  For \fBTk_FreeFontFromObj\fR the font to release is specified
with the same information used to create it; for
\fBTk_FreeFont\fR the font to release is specified
with its Tk_Font token.  There should be
exactly one call to \fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR
for each call to \fBTk_AllocFontFromObj\fR or \fBTk_GetFont\fR.

.SH "SEE ALSO"
Tk_FontId(3)
.SH KEYWORDS
font

Changes to doc/GetGC.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetGC 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetGC, Tk_FreeGC \- maintain database of read-only graphics contexts
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetGC 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetGC, Tk_FreeGC \- maintain database of read-only graphics contexts
.SH SYNOPSIS
.nf
30
31
32
33
34
35
36

37
38
39
40
41
42
43
graphics context.
.AP Display *display in
Display for which \fIgc\fR was allocated.
.AP GC gc in
X identifier for graphics context that is no longer needed.
Must have been allocated by \fBTk_GetGC\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetGC\fR and \fBTk_FreeGC\fR manage a collection of graphics contexts
being used by an application.  The procedures allow graphics contexts to be
shared, thereby avoiding the server overhead that would be incurred
if a separate GC were created for each use.  \fBTk_GetGC\fR takes arguments
describing the desired graphics context and returns an X identifier







>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
graphics context.
.AP Display *display in
Display for which \fIgc\fR was allocated.
.AP GC gc in
X identifier for graphics context that is no longer needed.
Must have been allocated by \fBTk_GetGC\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetGC\fR and \fBTk_FreeGC\fR manage a collection of graphics contexts
being used by an application.  The procedures allow graphics contexts to be
shared, thereby avoiding the server overhead that would be incurred
if a separate GC were created for each use.  \fBTk_GetGC\fR takes arguments
describing the desired graphics context and returns an X identifier
62
63
64
65
66
67
68

69
70
When a graphics context
is no longer needed, \fBTk_FreeGC\fR should be called to release it.
There should be exactly one call to \fBTk_FreeGC\fR for
each call to \fBTk_GetGC\fR.
When a graphics context is no longer in use anywhere (i.e. it has
been freed as many times as it has been gotten) \fBTk_FreeGC\fR
will release it to the X server and delete it from the database.

.SH KEYWORDS
graphics context







>


63
64
65
66
67
68
69
70
71
72
When a graphics context
is no longer needed, \fBTk_FreeGC\fR should be called to release it.
There should be exactly one call to \fBTk_FreeGC\fR for
each call to \fBTk_GetGC\fR.
When a graphics context is no longer in use anywhere (i.e. it has
been freed as many times as it has been gotten) \fBTk_FreeGC\fR
will release it to the X server and delete it from the database.

.SH KEYWORDS
graphics context

Changes to doc/GetHINSTANCE.3.

1
2
3
4
5
6
7
8
9
10
11
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_GetHISTANCE 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHINSTANCE \- retrieve the global application instance handle
.SH SYNOPSIS
.nf



|







1
2
3
4
5
6
7
8
9
10
11
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH Tk_GetHISTANCE 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHINSTANCE \- retrieve the global application instance handle
.SH SYNOPSIS
.nf

Changes to doc/GetHWND.3.

1
2
3
4
5
6
7
8
9
10
11
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH HWND 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHWND, Tk_AttachHWND \- manage interactions between the Windows handle and an X window
.SH SYNOPSIS
.nf



|







1
2
3
4
5
6
7
8
9
10
11
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH HWND 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHWND, Tk_AttachHWND \- manage interactions between the Windows handle and an X window
.SH SYNOPSIS
.nf
28
29
30
31
32
33
34

35
36
.PP
\fBTk_GetHWND\fR returns the Windows HWND identifier for X Windows
window given by \fIwindow\fR.
.PP
\fBTk_AttachHWND\fR binds the Windows HWND identifier to the
specified Tk_Window given by \fItkwin\fR. It returns an X Windows
window that encapsulates the HWND.

.SH KEYWORDS
identifier, window







>


28
29
30
31
32
33
34
35
36
37
.PP
\fBTk_GetHWND\fR returns the Windows HWND identifier for X Windows
window given by \fIwindow\fR.
.PP
\fBTk_AttachHWND\fR binds the Windows HWND identifier to the
specified Tk_Window given by \fItkwin\fR. It returns an X Windows
window that encapsulates the HWND.

.SH KEYWORDS
identifier, window

Changes to doc/GetImage.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetImage 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetImage, Tk_RedrawImage, Tk_SizeOfImage, Tk_FreeImage \- use an image in a widget
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetImage 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetImage, Tk_RedrawImage, Tk_SizeOfImage, Tk_FreeImage \- use an image in a widget
.SH SYNOPSIS
.nf
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
in \fIdrawable\fR where y-coordinate \fIimageY\fR of the image
should be displayed.
.AP "int" widthPtr out
Store width of \fIimage\fR (in pixels) here.
.AP "int" heightPtr out
Store height of \fIimage\fR (in pixels) here.
.BE

.SH DESCRIPTION
.PP
These procedures are invoked by widgets that wish to display images.
\fBTk_GetImage\fR is invoked by a widget when it first decides to
display an image.
\fIname\fR gives the name of the desired image and \fItkwin\fR
identifies the window where the image will be displayed.
\fBTk_GetImage\fR looks up the image in the table of existing
images and returns a token for a new instance of the image.
If the image does not exist then \fBTk_GetImage\fR returns NULL
and leaves an error message in interpreter \fIinterp\fR's result.
.PP
When a widget wishes to actually display an image it must
call \fBTk_RedrawImage\fR, identifying the image (\fIimage\fR),
a region within the image to redisplay (\fIimageX\fR, \fIimageY\fR,
\fIwidth\fR, and \fIheight\fR), and a place to display the
image (\fIdrawable\fR, \fIdrawableX\fR, and \fIdrawableY\fR).
Tk will then invoke the appropriate image manager, which will







>










|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
in \fIdrawable\fR where y-coordinate \fIimageY\fR of the image
should be displayed.
.AP "int" widthPtr out
Store width of \fIimage\fR (in pixels) here.
.AP "int" heightPtr out
Store height of \fIimage\fR (in pixels) here.
.BE

.SH DESCRIPTION
.PP
These procedures are invoked by widgets that wish to display images.
\fBTk_GetImage\fR is invoked by a widget when it first decides to
display an image.
\fIname\fR gives the name of the desired image and \fItkwin\fR
identifies the window where the image will be displayed.
\fBTk_GetImage\fR looks up the image in the table of existing
images and returns a token for a new instance of the image.
If the image does not exist then \fBTk_GetImage\fR returns NULL
and leaves an error message in \fIinterp->result\fR.
.PP
When a widget wishes to actually display an image it must
call \fBTk_RedrawImage\fR, identifying the image (\fIimage\fR),
a region within the image to redisplay (\fIimageX\fR, \fIimageY\fR,
\fIwidth\fR, and \fIheight\fR), and a place to display the
image (\fIdrawable\fR, \fIdrawableX\fR, and \fIdrawableY\fR).
Tk will then invoke the appropriate image manager, which will
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128

129
130
using the image will need to find out about the changes so that
they can redisplay themselves.
The \fIchangeProc\fR and \fIclientData\fR arguments to
\fBTk_GetImage\fR are used for this purpose.
\fIchangeProc\fR will be called by Tk whenever a change occurs
in the image;  it must match the following prototype:
.CS
typedef void \fBTk_ImageChangedProc\fR(
        ClientData \fIclientData\fR,
        int \fIx\fR,
        int \fIy\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIimageWidth\fR,
        int \fIimageHeight\fR);
.CE
The \fIclientData\fR argument to \fIchangeProc\fR is the same as the
\fIclientData\fR argument to \fBTk_GetImage\fR.
It is usually a pointer to the widget record for the widget or
some other data structure managed by the widget.
The arguments \fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
identify a region within the image that must be redisplayed;
they are specified in pixels measured from the upper-left
corner of the image.
The arguments \fIimageWidth\fR and \fIimageHeight\fR give
the image's (new) size.

.SH "SEE ALSO"
Tk_CreateImageType

.SH KEYWORDS
images, redisplay







|
|
|
|
|
|
|
|











>


>


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using the image will need to find out about the changes so that
they can redisplay themselves.
The \fIchangeProc\fR and \fIclientData\fR arguments to
\fBTk_GetImage\fR are used for this purpose.
\fIchangeProc\fR will be called by Tk whenever a change occurs
in the image;  it must match the following prototype:
.CS
typedef void Tk_ImageChangedProc(
    ClientData \fIclientData\fR,
    int \fIx\fR,
    int \fIy\fR,
    int \fIwidth\fR,
    int \fIheight\fR,
    int \fIimageWidth\fR,
    int \fIimageHeight\fR);
.CE
The \fIclientData\fR argument to \fIchangeProc\fR is the same as the
\fIclientData\fR argument to \fBTk_GetImage\fR.
It is usually a pointer to the widget record for the widget or
some other data structure managed by the widget.
The arguments \fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
identify a region within the image that must be redisplayed;
they are specified in pixels measured from the upper-left
corner of the image.
The arguments \fIimageWidth\fR and \fIimageHeight\fR give
the image's (new) size.

.SH "SEE ALSO"
Tk_CreateImageType

.SH KEYWORDS
images, redisplay

Changes to doc/GetJoinStl.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetJoinStyle 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetJoinStyle, Tk_NameOfJoinStyle \- translate between strings and join styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJoinStyle(\fIinterp, string, joinPtr\fB)\fR
.sp
const char *
\fBTk_NameOfJoinStyle(\fIjoin\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of join style \- one of
.QW \fBbevel\fR ,
.QW \fBmiter\fR ,
or
.QW \fBround\fR
\- or a unique abbreviation of one.
.AP int *joinPtr out
Pointer to location in which to store X join style corresponding to
\fIstring\fR.
.AP int join in
Join style: one of \fBJoinBevel\fR, \fBJoinMiter\fR, \fBJoinRound\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetJoinStyle\fR places in \fI*joinPtr\fR the X join style
corresponding to \fIstring\fR, which will be one of
\fBJoinBevel\fR, \fBJoinMiter\fR, or \fBJoinRound\fR.
Join styles are typically used in X graphics contexts to indicate
how adjacent line segments should be joined together.
See the X documentation for information on what each style
implies.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIstring\fR does not contain a valid join style
or an abbreviation of one of these names, then an error message is
stored in interpreter \fIinterp\fR's result, \fBTCL_ERROR\fR is returned, and
\fI*joinPtr\fR is unmodified.
.PP
\fBTk_NameOfJoinStyle\fR is the logical inverse of \fBTk_GetJoinStyle\fR.
Given a join style such as \fBJoinBevel\fR it returns a
statically-allocated string corresponding to \fIjoin\fR.
If \fIjoin\fR is not a legal join style, then
.QW "unknown join style"
is returned.

.SH KEYWORDS
bevel, join style, miter, round






|



















|
|
|

|
<






>














|








>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetJoinStyle 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetJoinStyle, Tk_NameOfJoinStyle \- translate between strings and join styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJoinStyle(\fIinterp, string, joinPtr\fB)\fR
.sp
const char *
\fBTk_NameOfJoinStyle(\fIjoin\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of join style: one of
.QW bevel ,
.QW miter ,
or
.QW round .

.AP int *joinPtr out
Pointer to location in which to store X join style corresponding to
\fIstring\fR.
.AP int join in
Join style: one of \fBJoinBevel\fR, \fBJoinMiter\fR, \fBJoinRound\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetJoinStyle\fR places in \fI*joinPtr\fR the X join style
corresponding to \fIstring\fR, which will be one of
\fBJoinBevel\fR, \fBJoinMiter\fR, or \fBJoinRound\fR.
Join styles are typically used in X graphics contexts to indicate
how adjacent line segments should be joined together.
See the X documentation for information on what each style
implies.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIstring\fR does not contain a valid join style
or an abbreviation of one of these names, then an error message is
stored in \fIinterp->result\fR, \fBTCL_ERROR\fR is returned, and
\fI*joinPtr\fR is unmodified.
.PP
\fBTk_NameOfJoinStyle\fR is the logical inverse of \fBTk_GetJoinStyle\fR.
Given a join style such as \fBJoinBevel\fR it returns a
statically-allocated string corresponding to \fIjoin\fR.
If \fIjoin\fR is not a legal join style, then
.QW "unknown join style"
is returned.

.SH KEYWORDS
bevel, join style, miter, round

Changes to doc/GetJustify.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\"
.TH Tk_GetJustifyFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetJustifyFromObj, Tk_GetJustify, Tk_NameOfJustify \- translate between strings and justification styles
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
.TH Tk_GetJustifyFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetJustifyFromObj, Tk_GetJustify, Tk_NameOfJustify \- translate between strings and justification styles
.SH SYNOPSIS
.nf
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const char *
\fBTk_NameOfJustify(\fIjustify\fB)\fR
.SH ARGUMENTS
.AS "Tk_Justify" *justifyPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of justification style \- one of
.QW \fBleft\fR ,
.QW \fBright\fR ,
or
.QW \fBcenter\fR
\- or a unique abbreviation of one.
The internal rep will be modified to cache corresponding justify value.
.AP "const char" *string in
Same as \fIobjPtr\fR except description of justification style is passed as
a string.
.AP int *justifyPtr out
Pointer to location in which to store justify value corresponding to
\fIobjPtr\fR or \fIstring\fR.







|
|
|

|
<







23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
const char *
\fBTk_NameOfJustify(\fIjustify\fB)\fR
.SH ARGUMENTS
.AS "Tk_Justify" *justifyPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of justification style, one of
.QW left ,
.QW right ,
or
.QW center .

The internal rep will be modified to cache corresponding justify value.
.AP "const char" *string in
Same as \fIobjPtr\fR except description of justification style is passed as
a string.
.AP int *justifyPtr out
Pointer to location in which to store justify value corresponding to
\fIobjPtr\fR or \fIstring\fR.
79
80
81
82
83
84
85

86
87
.PP
\fBTk_NameOfJustify\fR is the logical inverse of \fBTk_GetJustify\fR.
Given a justify value it returns a statically-allocated string
corresponding to \fIjustify\fR.
If \fIjustify\fR is not a legal justify value, then
.QW "unknown justification style"
is returned.

.SH KEYWORDS
center, fill, justification, string







>


78
79
80
81
82
83
84
85
86
87
.PP
\fBTk_NameOfJustify\fR is the logical inverse of \fBTk_GetJustify\fR.
Given a justify value it returns a statically-allocated string
corresponding to \fIjustify\fR.
If \fIjustify\fR is not a legal justify value, then
.QW "unknown justification style"
is returned.

.SH KEYWORDS
center, fill, justification, string

Changes to doc/GetOption.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetOption 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetOption \- retrieve an option from the option database
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetOption 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetOption \- retrieve an option from the option database
.SH SYNOPSIS
.nf
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40

41
42
Token for window.
.AP "const char" *name in
Name of desired option.
.AP "const char" *class in
Class of desired option.  Null means there is no class for
this option;  do lookup based on name only.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked to retrieve an option from the database
associated with \fItkwin\fR's main window.  If there is an option
for \fItkwin\fR that matches the given \fIname\fR or \fIclass\fR,
then it is returned in the form of a Tk_Uid.  If multiple options
match \fIname\fR and \fIclass\fR, then the highest-priority one
is returned.  If no option matches, then NULL is returned.
.PP
\fBTk_GetOption\fR caches options related to \fItkwin\fR so that
successive calls for the same \fItkwin\fR will execute much more
quickly than successive calls for different windows.

.SH KEYWORDS
class, name, option, retrieve







>












>


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Token for window.
.AP "const char" *name in
Name of desired option.
.AP "const char" *class in
Class of desired option.  Null means there is no class for
this option;  do lookup based on name only.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked to retrieve an option from the database
associated with \fItkwin\fR's main window.  If there is an option
for \fItkwin\fR that matches the given \fIname\fR or \fIclass\fR,
then it is returned in the form of a Tk_Uid.  If multiple options
match \fIname\fR and \fIclass\fR, then the highest-priority one
is returned.  If no option matches, then NULL is returned.
.PP
\fBTk_GetOption\fR caches options related to \fItkwin\fR so that
successive calls for the same \fItkwin\fR will execute much more
quickly than successive calls for different windows.

.SH KEYWORDS
class, name, option, retrieve

Changes to doc/GetPixels.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp
int
\fBTk_GetDoublePixelsFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int






|




|







<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19



20
21
22
23
24
25
26
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp



int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
42
43
44
45
46
47
48

49
50
51
52
53
54
55
Same as \fIobjPtr\fR except specification of distance is passed as
a string.
.AP int *intPtr out
Pointer to location in which to store converted distance in pixels.
.AP double *doublePtr out
Pointer to location in which to store converted distance in millimeters.
.BE

.SH DESCRIPTION
.PP
These procedures take as argument a specification of distance on
the screen (\fIobjPtr\fR or \fIstring\fR) and compute the
corresponding distance either in integer pixels or floating-point millimeters.
In either case,
\fIobjPtr\fR or \fIstring\fR







>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Same as \fIobjPtr\fR except specification of distance is passed as
a string.
.AP int *intPtr out
Pointer to location in which to store converted distance in pixels.
.AP double *doublePtr out
Pointer to location in which to store converted distance in millimeters.
.BE

.SH DESCRIPTION
.PP
These procedures take as argument a specification of distance on
the screen (\fIobjPtr\fR or \fIstring\fR) and compute the
corresponding distance either in integer pixels or floating-point millimeters.
In either case,
\fIobjPtr\fR or \fIstring\fR
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
by a character that is not one of the ones above) then
\fBTCL_ERROR\fR is returned and an error message is left
in \fIinterp\fR's result if \fIinterp\fR is not NULL.
\fBTk_GetPixelsFromObj\fR caches information about the return
value in \fIobjPtr\fR, which speeds up future calls to
\fBTk_GetPixelsFromObj\fR with the same \fIobjPtr\fR.
.PP
\fBTk_GetDoublePixelsFromObj\fR is identical to \fBTk_GetPixelsFromObj\fR
except it returns a double not rounded to the nearest integer.
.PP
\fBTk_GetPixels\fR is identical to \fBTk_GetPixelsFromObj\fR except
that the screen distance is specified with a string instead
of an object.  This prevents \fBTk_GetPixels\fR from caching the
return value, so \fBTk_GetPixels\fR is less efficient than
\fBTk_GetPixelsFromObj\fR.
.PP
\fBTk_GetMMFromObj\fR and \fBTk_GetScreenMM\fR are similar to
\fBTk_GetPixelsFromObj\fR and \fBTk_GetPixels\fR (respectively) except
that they convert the screen distance to millimeters and
store a double-precision floating-point result at \fI*doublePtr\fR.

.SH KEYWORDS
centimeters, convert, inches, millimeters, pixels, points, screen units







<
<
<



|






>


78
79
80
81
82
83
84



85
86
87
88
89
90
91
92
93
94
95
96
97
by a character that is not one of the ones above) then
\fBTCL_ERROR\fR is returned and an error message is left
in \fIinterp\fR's result if \fIinterp\fR is not NULL.
\fBTk_GetPixelsFromObj\fR caches information about the return
value in \fIobjPtr\fR, which speeds up future calls to
\fBTk_GetPixelsFromObj\fR with the same \fIobjPtr\fR.
.PP



\fBTk_GetPixels\fR is identical to \fBTk_GetPixelsFromObj\fR except
that the screen distance is specified with a string instead
of an object.  This prevents \fBTk_GetPixels\fR from caching the
return value, so \fBTk_GetAnchor\fR is less efficient than
\fBTk_GetPixelsFromObj\fR.
.PP
\fBTk_GetMMFromObj\fR and \fBTk_GetScreenMM\fR are similar to
\fBTk_GetPixelsFromObj\fR and \fBTk_GetPixels\fR (respectively) except
that they convert the screen distance to millimeters and
store a double-precision floating-point result at \fI*doublePtr\fR.

.SH KEYWORDS
centimeters, convert, inches, millimeters, pixels, points, screen units

Changes to doc/GetPixmap.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetPixmap 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixmap, Tk_FreePixmap \- allocate and free pixmaps
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetPixmap 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixmap, Tk_FreePixmap \- allocate and free pixmaps
.SH SYNOPSIS
.nf
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
.AP "int" height in
Height of pixmap.
.AP "int" depth in
Number of bits per pixel in pixmap.
.AP Pixmap pixmap in
Pixmap to destroy.
.BE

.SH DESCRIPTION
.PP
These procedures are identical to the Xlib procedures \fBXCreatePixmap\fR
and \fBXFreePixmap\fR, except that they have extra code to manage X
resource identifiers so that identifiers for deleted pixmaps can be
reused in the future.
It is important for Tk applications to use these procedures rather
than \fBXCreatePixmap\fR and \fBXFreePixmap\fR;  otherwise long-running
applications may run out of resource identifiers.
.PP
\fBTk_GetPixmap\fR creates a pixmap suitable for drawing in \fId\fR,
with dimensions given by \fIwidth\fR, \fIheight\fR, and \fIdepth\fR,
and returns its identifier.
\fBTk_FreePixmap\fR destroys the pixmap given by \fIpixmap\fR and makes
its resource identifier available for reuse.

.SH KEYWORDS
pixmap, resource identifier







>















>


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.AP "int" height in
Height of pixmap.
.AP "int" depth in
Number of bits per pixel in pixmap.
.AP Pixmap pixmap in
Pixmap to destroy.
.BE

.SH DESCRIPTION
.PP
These procedures are identical to the Xlib procedures \fBXCreatePixmap\fR
and \fBXFreePixmap\fR, except that they have extra code to manage X
resource identifiers so that identifiers for deleted pixmaps can be
reused in the future.
It is important for Tk applications to use these procedures rather
than \fBXCreatePixmap\fR and \fBXFreePixmap\fR;  otherwise long-running
applications may run out of resource identifiers.
.PP
\fBTk_GetPixmap\fR creates a pixmap suitable for drawing in \fId\fR,
with dimensions given by \fIwidth\fR, \fIheight\fR, and \fIdepth\fR,
and returns its identifier.
\fBTk_FreePixmap\fR destroys the pixmap given by \fIpixmap\fR and makes
its resource identifier available for reuse.

.SH KEYWORDS
pixmap, resource identifier

Changes to doc/GetRelief.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_GetReliefFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_GetReliefFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
\fBTk_NameOfRelief(\fIrelief\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *reliefPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in/out
String value contains name of relief, one of
.QW \fBflat\fR ,
.QW \fBgroove\fR ,
.QW \fBraised\fR ,
.QW \fBridge\fR ,
.QW \fBsolid\fR ,
or
.QW \fBsunken\fR
(or any unique abbreviation thereof on input);
the internal rep will be modified to cache corresponding relief value.
.AP char *string in
Same as \fIobjPtr\fR except description of relief is passed as
a string.
.AP int *reliefPtr out
Pointer to location in which to store relief value corresponding to
\fIobjPtr\fR or \fIname\fR.







|
|
|
|
|

|
<







24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
\fBTk_NameOfRelief(\fIrelief\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *reliefPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in/out
String value contains name of relief, one of
.QW flat ,
.QW groove ,
.QW raised ,
.QW ridge ,
.QW solid ,
or
.QW sunken ;

the internal rep will be modified to cache corresponding relief value.
.AP char *string in
Same as \fIobjPtr\fR except description of relief is passed as
a string.
.AP int *reliefPtr out
Pointer to location in which to store relief value corresponding to
\fIobjPtr\fR or \fIname\fR.

Changes to doc/GetRootCrd.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetRootCoords 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetRootCoords \- Compute root-window coordinates of window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetRootCoords 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetRootCoords \- Compute root-window coordinates of window
.SH SYNOPSIS
.nf

Changes to doc/GetScroll.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25






26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetScrollInfo 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetScrollInfoObj, Tk_GetScrollInfo \- parse arguments for scrolling commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetScrollInfoObj(\fIinterp, objc, objv, fractionPtr, stepsPtr\fB)\fR
.sp
int
\fBTk_GetScrollInfo(\fIinterp, argc, argv, fractionPtr, stepsPtr\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *fractionPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.






.AP int objc in
Number of Tcl_Obj's in \fIobjv\fR array.
.AP "Tcl_Obj *const *" objv in
Argument objects.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP int argc in
Number of strings in \fIargv\fR array.
.AP "const char **" argv in
Argument strings.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP double *fractionPtr out
Filled in with fraction from \fBmoveto\fR option, if any.
.AP int *stepsPtr out
Filled in with line or page count from \fBscroll\fR option, if any.
The value may be negative.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetScrollInfoObj\fR parses the arguments expected by widget
scrolling commands such as \fBxview\fR and \fByview\fR.
It receives the entire list of words that make up a widget command
and parses the words starting with \fIobjv\fR[2].
The words starting with \fIobjv\fR[2] must have one of the following forms:
.CS
\fBmoveto \fIfraction\fR
\fBscroll \fInumber\fB pages\fR
\fBscroll \fInumber\fB units\fR
.CE
.LP
Any of the \fBmoveto\fR, \fBscroll\fR, \fBpages\fR, and \fBunits\fR
keywords may be abbreviated.
If \fIobjv\fR has the \fBmoveto\fR form, \fBTK_SCROLL_MOVETO\fR
is returned as result and \fI*fractionPtr\fR is filled in with the
\fIfraction\fR argument to the command, which must be a proper real
value.
If \fIobjv\fR has the \fBscroll\fR form, \fBTK_SCROLL_PAGES\fR
or \fBTK_SCROLL_UNITS\fR is returned and \fI*stepsPtr\fR is filled
in with the \fInumber\fR value, which must be a  integer or a float,
but if it is a float then it is converted to an integer, rounded away from 0.
If an error occurs in parsing the arguments, \fBTK_SCROLL_ERROR\fR
is returned and an error message is left in interpreter
\fIinterp\fR's result.
.PP
\fBTk_GetScrollInfo\fR is identical in function to
\fBTk_GetScrollInfoObj\fR.  However, \fBTk_GetScrollInfo\fR accepts
string arguments, making it more appropriate for use with legacy

widgets.
.SH KEYWORDS
parse, scrollbar, scrolling command, xview, yview






|




|





|


|

|


>
>
>
>
>
>


|



<
<
<
<
<
<
|

|



>


|


|
|


|
|


|

|
|


|
|
|
<

|
<

|
|
|
>
|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37






38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68

69
70
71
72
73
74
75
76
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetScrollInfo 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetScrollInfo, Tk_GetScrollInfoObj \- parse arguments for scrolling commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetScrollInfo(\fIinterp, argc, argv, dblPtr, intPtr\fB)\fR
.sp
int
\fBTk_GetScrollInfoObj(\fIinterp, objc, objv, dblPtr, intPtr\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *dblPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP int argc in
Number of strings in \fIargv\fR array.
.AP "const char" *argv[] in
Argument strings.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP int objc in
Number of Tcl_Obj's in \fIobjv\fR array.
.AP "Tcl_Obj *const" objv[] in
Argument objects.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.






.AP double *dblPtr out
Filled in with fraction from \fBmoveto\fR option, if any.
.AP int *intPtr out
Filled in with line or page count from \fBscroll\fR option, if any.
The value may be negative.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetScrollInfo\fR parses the arguments expected by widget
scrolling commands such as \fBxview\fR and \fByview\fR.
It receives the entire list of words that make up a widget command
and parses the words starting with \fIargv\fR[2].
The words starting with \fIargv\fR[2] must have one of the following forms:
.CS
\fBmoveto \fIfraction\fR
\fBscroll \fInumber\fB units\fR
\fBscroll \fInumber\fB pages\fR
.CE
.LP
Any of the \fBmoveto\fR, \fBscroll\fR, \fBunits\fR, and \fBpages\fR
keywords may be abbreviated.
If \fIargv\fR has the \fBmoveto\fR form, \fBTK_SCROLL_MOVETO\fR
is returned as result and \fI*dblPtr\fR is filled in with the
\fIfraction\fR argument to the command, which must be a proper real
value.
If \fIargv\fR has the \fBscroll\fR form, \fBTK_SCROLL_UNITS\fR
or \fBTK_SCROLL_PAGES\fR is returned and \fI*intPtr\fR is filled
in with the \fInumber\fR value, which must be a proper integer.

If an error occurs in parsing the arguments, \fBTK_SCROLL_ERROR\fR
is returned and an error message is left in \fIinterp->result\fR.

.PP
\fBTk_GetScrollInfoObj\fR is identical in function to
\fBTk_GetScrollInfo\fR.  However, \fBTk_GetScrollInfoObj\fR accepts
Tcl_Obj style arguments, making it more appropriate for use with new
development.

.SH KEYWORDS
parse, scrollbar, scrolling command, xview, yview

Changes to doc/GetSelect.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetSelection \- retrieve the contents of a selection
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetSelection \- retrieve the contents of a selection
.SH SYNOPSIS
.nf
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Form in which to retrieve selection.
.AP Tk_GetSelProc *proc in
Procedure to invoke to process pieces of the selection as they
are retrieved.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetSelection\fR retrieves the selection specified by the atom
\fIselection\fR in the format specified by \fItarget\fR.  The
selection may actually be retrieved in several pieces; as each piece
is retrieved, \fIproc\fR is called to process the piece.  \fIProc\fR
should have arguments and result that match the type
\fBTk_GetSelProc\fR:
.PP
.CS
typedef int \fBTk_GetSelProc\fR(
        ClientData \fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        char *\fIportion\fR);
.CE
.PP
The \fIclientData\fR and \fIinterp\fR parameters to \fIproc\fR
will be copies of the corresponding arguments to
\fBTk_GetSelection\fR.  \fIPortion\fR will be a pointer to
a string containing part or all of the selection.  For large
selections, \fIproc\fR will be called several times with successive
portions of the selection.  The X Inter-Client Communication
Conventions Manual allows a selection to be returned in formats
other than strings, e.g. as an array of atoms or integers.  If
this happens, Tk converts the selection back into a string
before calling \fIproc\fR.  If a selection is returned as an
array of atoms, Tk converts it to a string containing the atom names
separated by white space.  For any other format besides string,
Tk converts a selection to a string containing hexadecimal
values separated by white space.
.PP
\fBTk_GetSelection\fR returns to its caller when the selection has
been completely retrieved and processed by \fIproc\fR, or when a
fatal error has occurred (e.g. the selection owner did not respond
promptly).  \fBTk_GetSelection\fR normally returns \fBTCL_OK\fR;  if
an error occurs, it returns \fBTCL_ERROR\fR and leaves an error message
in interpreter \fIinterp\fR's result.  \fIProc\fR should also return either
\fBTCL_OK\fR or \fBTCL_ERROR\fR.  If \fIproc\fR encounters an error in
dealing with the selection, it should leave an error message in the
interpreter result and return \fBTCL_ERROR\fR;  this will abort the
selection retrieval.
.SH KEYWORDS
format, get, selection retrieval







>








<

|
|
|
|

<
|



















|
|
|
|
|


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Form in which to retrieve selection.
.AP Tk_GetSelProc *proc in
Procedure to invoke to process pieces of the selection as they
are retrieved.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetSelection\fR retrieves the selection specified by the atom
\fIselection\fR in the format specified by \fItarget\fR.  The
selection may actually be retrieved in several pieces; as each piece
is retrieved, \fIproc\fR is called to process the piece.  \fIProc\fR
should have arguments and result that match the type
\fBTk_GetSelProc\fR:

.CS
typedef int Tk_GetSelProc(
    ClientData \fIclientData\fR,
    Tcl_Interp *\fIinterp\fR,
    char *\fIportion\fR);
.CE

The \fIclientData\fR and \fIinterp\fR parameters to \fIproc\fR 
will be copies of the corresponding arguments to
\fBTk_GetSelection\fR.  \fIPortion\fR will be a pointer to
a string containing part or all of the selection.  For large
selections, \fIproc\fR will be called several times with successive
portions of the selection.  The X Inter-Client Communication
Conventions Manual allows a selection to be returned in formats
other than strings, e.g. as an array of atoms or integers.  If
this happens, Tk converts the selection back into a string
before calling \fIproc\fR.  If a selection is returned as an
array of atoms, Tk converts it to a string containing the atom names
separated by white space.  For any other format besides string,
Tk converts a selection to a string containing hexadecimal
values separated by white space.
.PP
\fBTk_GetSelection\fR returns to its caller when the selection has
been completely retrieved and processed by \fIproc\fR, or when a
fatal error has occurred (e.g. the selection owner did not respond
promptly).  \fBTk_GetSelection\fR normally returns \fBTCL_OK\fR;  if
an error occurs, it returns \fBTCL_ERROR\fR and leaves an error message
in \fIinterp->result\fR.  \fIProc\fR should also return either
\fBTCL_OK\fR or \fBTCL_ERROR\fR. If \fIproc\fR encounters an error in dealing with the
selection, it should leave an error message in \fIinterp->result\fR
and return \fBTCL_ERROR\fR;  this will abort the selection retrieval.

.SH KEYWORDS
format, get, selection retrieval

Changes to doc/GetUid.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetUid 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUid, Tk_Uid \- convert from string to unique identifier
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetUid\fR(\fIstring\fR)
.SH ARGUMENTS
.AP char *string in
String for which the corresponding unique identifier is
desired.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetUid\fR returns the unique identifier corresponding
to \fIstring\fR.
Unique identifiers are similar to atoms in Lisp, and are used
in Tk to speed up comparisons and
searches.  A unique identifier (type Tk_Uid) is a string pointer
and may be used anywhere that a variable of type
.QW "char *"
could be used.  However, there is guaranteed to be exactly
one unique identifier for any given string value.  If \fBTk_GetUid\fR
is called twice, once with string \fIa\fR and once with string
\fIb\fR, and if \fIa\fR and \fIb\fR have the same string value
(strcmp(a, b) == 0), then \fBTk_GetUid\fR will return exactly
the same Tk_Uid value for each call (Tk_GetUid(a) == Tk_GetUid(b)).
This means that variables of type
Tk_Uid may be compared directly (x == y) without having to call
\fBstrcmp\fR.
In addition, the return value from \fBTk_GetUid\fR will have the
same string value as its argument (strcmp(Tk_GetUid(a), a) == 0).

.SH KEYWORDS
atom, unique identifier






|
















>




















>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetUid 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUid, Tk_Uid \- convert from string to unique identifier
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetUid\fR(\fIstring\fR)
.SH ARGUMENTS
.AP char *string in
String for which the corresponding unique identifier is
desired.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetUid\fR returns the unique identifier corresponding
to \fIstring\fR.
Unique identifiers are similar to atoms in Lisp, and are used
in Tk to speed up comparisons and
searches.  A unique identifier (type Tk_Uid) is a string pointer
and may be used anywhere that a variable of type
.QW "char *"
could be used.  However, there is guaranteed to be exactly
one unique identifier for any given string value.  If \fBTk_GetUid\fR
is called twice, once with string \fIa\fR and once with string
\fIb\fR, and if \fIa\fR and \fIb\fR have the same string value
(strcmp(a, b) == 0), then \fBTk_GetUid\fR will return exactly
the same Tk_Uid value for each call (Tk_GetUid(a) == Tk_GetUid(b)).
This means that variables of type
Tk_Uid may be compared directly (x == y) without having to call
\fBstrcmp\fR.
In addition, the return value from \fBTk_GetUid\fR will have the
same string value as its argument (strcmp(Tk_GetUid(a), a) == 0).

.SH KEYWORDS
atom, unique identifier

Changes to doc/GetVRoot.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetVRootGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetVRootGeometry \- Get location and size of virtual root for window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetVRootGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetVRootGeometry \- Get location and size of virtual root for window
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
.AP int yPtr out
Points to word in which to store y-offset of virtual root.
.AP "int" widthPtr out
Points to word in which to store width of virtual root.
.AP "int" heightPtr out
Points to word in which to store height of virtual root.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetVRootGeometry\fR returns geometry information about the virtual
root window associated with \fItkwin\fR.  The
.QW associated
virtual root is the one in which \fItkwin\fR's nearest top-level ancestor (or
\fItkwin\fR itself if it is a top-level window) has
been reparented by the window manager.  This window is identified by
a \fB__SWM_ROOT\fR or \fB__WM_ROOT\fR property placed on the top-level
window by the window manager.
If \fItkwin\fR is not associated with a virtual root (e.g.
because the window manager does not use virtual roots) then *\fIxPtr\fR and
*\fIyPtr\fR will be set to 0 and *\fIwidthPtr\fR and *\fIheightPtr\fR
will be set to the dimensions of the screen containing \fItkwin\fR.

.SH KEYWORDS
geometry, height, location, virtual root, width, window manager







>














>


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
.AP int yPtr out
Points to word in which to store y-offset of virtual root.
.AP "int" widthPtr out
Points to word in which to store width of virtual root.
.AP "int" heightPtr out
Points to word in which to store height of virtual root.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetVRootGeometry\fR returns geometry information about the virtual
root window associated with \fItkwin\fR.  The
.QW associated
virtual root is the one in which \fItkwin\fR's nearest top-level ancestor (or
\fItkwin\fR itself if it is a top-level window) has
been reparented by the window manager.  This window is identified by
a \fB__SWM_ROOT\fR or \fB__WM_ROOT\fR property placed on the top-level
window by the window manager.
If \fItkwin\fR is not associated with a virtual root (e.g.
because the window manager does not use virtual roots) then *\fIxPtr\fR and
*\fIyPtr\fR will be set to 0 and *\fIwidthPtr\fR and *\fIheightPtr\fR
will be set to the dimensions of the screen containing \fItkwin\fR.

.SH KEYWORDS
geometry, height, location, virtual root, width, window manager

Changes to doc/GetVisual.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_GetVisual 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetVisual \- translate from string to visual
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_GetVisual 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetVisual \- translate from string to visual
.SH SYNOPSIS
.nf
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
.PP
\fBTk_GetVisual\fR takes a string description of a visual and
finds a suitable X Visual for use in \fItkwin\fR, if there is one.
It returns a pointer to the X Visual structure for the visual
and stores the number of bits per pixel for it at \fI*depthPtr\fR.
If \fIstring\fR is unrecognizable or if no suitable visual could
be found, then NULL is returned and \fBTk_GetVisual\fR leaves
an error message in interpreter \fIinterp\fR's result.
If \fIcolormap\fR is non-NULL then \fBTk_GetVisual\fR
also locates an appropriate colormap for use with the result visual
and stores its X identifier at \fI*colormapPtr\fR.
.PP
The \fIstring\fR argument specifies the desired visual in one
of the following ways:
.TP 15







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
.PP
\fBTk_GetVisual\fR takes a string description of a visual and
finds a suitable X Visual for use in \fItkwin\fR, if there is one.
It returns a pointer to the X Visual structure for the visual
and stores the number of bits per pixel for it at \fI*depthPtr\fR.
If \fIstring\fR is unrecognizable or if no suitable visual could
be found, then NULL is returned and \fBTk_GetVisual\fR leaves
an error message in \fIinterp->result\fR.
If \fIcolormap\fR is non-NULL then \fBTk_GetVisual\fR
also locates an appropriate colormap for use with the result visual
and stores its X identifier at \fI*colormapPtr\fR.
.PP
The \fIstring\fR argument specifies the desired visual in one
of the following ways:
.TP 15

Changes to doc/Grab.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56

57
58
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_Grab 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Grab, Tk_Ungrab \- manipulate grab state in an application
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Grab\fR(\fIinterp, tkwin, grabGlobal\fR)
.sp
void
\fBTk_Ungrab\fR(\fItkwin\fR)

.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter to use for error reporting
.AP Tk_Window tkwin in
Window on whose behalf the pointer is to be grabbed or released
.AP int grabGlobal in
Boolean indicating whether the grab is global or application local
.BE

.SH DESCRIPTION
.PP
These functions are used to set or release a global or
application local grab.  When a grab is set on a particular window
in a Tk application, mouse and keyboard events can only be received by
that window and its descendants.  Mouse and keyboard events for
windows outside the tree rooted at \fItkwin\fR will be redirected to
\fItkwin\fR.  If the grab is global, then all mouse and keyboard
events for windows outside the tree rooted at \fItkwin\fR (even those
intended for windows in other applications) will be redirected to
\fItkwin\fR.  If the grab is application local, only mouse and
keyboard events intended for a windows within the same application
(but outside the tree rooted at \fItkwin\fR) will be redirected.

.PP
\fBTk_Grab\fR sets a grab on a particular window.  \fITkwin\fR
specifies the window on whose behalf the pointer is to be grabbed.
\fIGrabGlobal\fR indicates whether the grab should be global or
application local; if it is non-zero, it means the grab should be
global.  Normally, \fBTk_Grab\fR returns \fBTCL_OK\fR; if an error occurs
and the grab cannot be set, \fBTCL_ERROR\fR is returned and an error message
is left if \fIinterp\fR's result.  Once this call completes
successfully, no window outside the tree rooted at \fItkwin\fR will
receive pointer- or keyboard-related events until the next call to
Tk_Ungrab.  If a previous grab was in effect within the application,
then it is replaced with a new one.

.PP
\fBTk_Ungrab\fR releases a grab on the mouse pointer and keyboard, if
there is one set on the window given by \fItkwin\fR.  Once a grab is
released, pointer and keyboard events will start being delivered to
other windows again.

.SH KEYWORDS
grab, window



|














>








>













>












>

|



>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH Tk_Grab 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Grab, Tk_Ungrab \- manipulate grab state in an application
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Grab\fR(\fIinterp, tkwin, grabGlobal\fR)
.sp
void
\fBTk_Ungrab\fR(\fItkwin\fR)

.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter to use for error reporting
.AP Tk_Window tkwin in
Window on whose behalf the pointer is to be grabbed or released
.AP int grabGlobal in
Boolean indicating whether the grab is global or application local
.BE

.SH DESCRIPTION
.PP
These functions are used to set or release a global or
application local grab.  When a grab is set on a particular window
in a Tk application, mouse and keyboard events can only be received by
that window and its descendants.  Mouse and keyboard events for
windows outside the tree rooted at \fItkwin\fR will be redirected to
\fItkwin\fR.  If the grab is global, then all mouse and keyboard
events for windows outside the tree rooted at \fItkwin\fR (even those
intended for windows in other applications) will be redirected to
\fItkwin\fR.  If the grab is application local, only mouse and
keyboard events intended for a windows within the same application
(but outside the tree rooted at \fItkwin\fR) will be redirected.

.PP
\fBTk_Grab\fR sets a grab on a particular window.  \fITkwin\fR
specifies the window on whose behalf the pointer is to be grabbed.
\fIGrabGlobal\fR indicates whether the grab should be global or
application local; if it is non-zero, it means the grab should be
global.  Normally, \fBTk_Grab\fR returns \fBTCL_OK\fR; if an error occurs
and the grab cannot be set, \fBTCL_ERROR\fR is returned and an error message
is left if \fIinterp\fR's result.  Once this call completes
successfully, no window outside the tree rooted at \fItkwin\fR will
receive pointer- or keyboard-related events until the next call to
Tk_Ungrab.  If a previous grab was in effect within the application,
then it is replaced with a new one.

.PP
\fBTcl_Ungrab\fR releases a grab on the mouse pointer and keyboard, if
there is one set on the window given by \fItkwin\fR.  Once a grab is
released, pointer and keyboard events will start being delivered to
other windows again.

.SH KEYWORDS
grab, window

Changes to doc/HWNDToWindow.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24

25
26
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_HWNDToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HWNDToWindow \- Find Tk's window information for a Windows window
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
Tk_Window
\fBTk_HWNDToWindow\fR(\fIhwnd\fR)
.SH ARGUMENTS
.AP HWND hwnd in
Windows handle for the window.
.BE

.SH DESCRIPTION
.PP
Given a Windows HWND window identifier, this procedure returns the
corresponding Tk_Window handle. If there is no Tk_Window corresponding
to \fIhwnd\fR then NULL is returned.

.SH KEYWORDS
Windows window id



|















>





>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH Tk_HWNDToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HWNDToWindow \- Find Tk's window information for a Windows window
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
Tk_Window
\fBTk_HWNDToWindow\fR(\fIhwnd\fR)
.SH ARGUMENTS
.AP HWND hwnd in
Windows handle for the window.
.BE

.SH DESCRIPTION
.PP
Given a Windows HWND window identifier, this procedure returns the
corresponding Tk_Window handle. If there is no Tk_Window corresponding
to \fIhwnd\fR then NULL is returned.

.SH KEYWORDS
Windows window id

Changes to doc/HandleEvent.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_HandleEvent 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HandleEvent \- invoke event handlers for window system events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_HandleEvent\fR(\fIeventPtr\fR)
.SH ARGUMENTS
.AS XEvent *eventPtr
.AP XEvent *eventPtr in
Pointer to X event to dispatch to relevant handler(s). It is important
that all unused fields of the structure be set to zero.
.BE

.SH DESCRIPTION
.PP
\fBTk_HandleEvent\fR is a lower-level procedure that deals with window
events.  It is called by \fBTcl_ServiceEvent\fR (and indirectly by
\fBTcl_DoOneEvent\fR), and in a few other cases within Tk.
It makes callbacks to any window event
handlers (created by calls to \fBTk_CreateEventHandler\fR)






|
















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_HandleEvent 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HandleEvent \- invoke event handlers for window system events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_HandleEvent\fR(\fIeventPtr\fR)
.SH ARGUMENTS
.AS XEvent *eventPtr
.AP XEvent *eventPtr in
Pointer to X event to dispatch to relevant handler(s). It is important
that all unused fields of the structure be set to zero.
.BE

.SH DESCRIPTION
.PP
\fBTk_HandleEvent\fR is a lower-level procedure that deals with window
events.  It is called by \fBTcl_ServiceEvent\fR (and indirectly by
\fBTcl_DoOneEvent\fR), and in a few other cases within Tk.
It makes callbacks to any window event
handlers (created by calls to \fBTk_CreateEventHandler\fR)
38
39
40
41
42
43
44

45
46
it is possible to invoke \fBTk_HandleEvent\fR recursively
from a handler called by \fBTk_HandleEvent\fR.  This sort
of operation is useful in some modal situations, such
as when a
notifier has been popped up and an application wishes to
wait for the user to click a button in the notifier before
doing anything else.

.SH KEYWORDS
callback, event, handler, window







>


39
40
41
42
43
44
45
46
47
48
it is possible to invoke \fBTk_HandleEvent\fR recursively
from a handler called by \fBTk_HandleEvent\fR.  This sort
of operation is useful in some modal situations, such
as when a
notifier has been popped up and an application wishes to
wait for the user to click a button in the notifier before
doing anything else.

.SH KEYWORDS
callback, event, handler, window

Changes to doc/IdToWindow.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30

31
32
'\"
'\" 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.
'\"
.TH Tk_IdToWindow 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_IdToWindow \- Find Tk's window information for an X window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_IdToWindow\fR(\fIdisplay, window\fR)
.SH ARGUMENTS
.AS Tk_Window display
.AP Display *display in
X display containing the window.
.AP Window window in
X id for window.
.BE

.SH DESCRIPTION
.PP
Given an X window identifier and the X display it corresponds to,
this procedure returns the corresponding Tk_Window handle.
If there is no Tk_Window corresponding to \fIwindow\fR then
NULL is returned.

.SH KEYWORDS
X window id





|


















>






>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'\"
'\" 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.
'\" 
.TH Tk_IdToWindow 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_IdToWindow \- Find Tk's window information for an X window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_IdToWindow\fR(\fIdisplay, window\fR)
.SH ARGUMENTS
.AS Tk_Window display
.AP Display *display in
X display containing the window.
.AP Window window in
X id for window.
.BE

.SH DESCRIPTION
.PP
Given an X window identifier and the X display it corresponds to,
this procedure returns the corresponding Tk_Window handle.
If there is no Tk_Window corresponding to \fIwindow\fR then
NULL is returned.

.SH KEYWORDS
X window id

Changes to doc/ImgChanged.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62

63
64
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ImageChanged 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)
.SH ARGUMENTS
.AS Tk_ImageModel imageHeight
.AP Tk_ImageModel model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP int y in
Y-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP "int" width in
Width of region that needs to be redrawn, in pixels.
.AP "int" height in
Height of region that needs to be redrawn, in pixels.
.AP "int" imageWidth in
Current width of image, in pixels.
.AP "int" imageHeight in
Current height of image, in pixels.
.BE

.SH DESCRIPTION
.PP
An image manager calls \fBTk_ImageChanged\fR for an image
whenever anything happens that requires the image to be redrawn.
As a result of calling \fBTk_ImageChanged\fR, any widgets using
the image are notified so that they can redisplay themselves
appropriately.
The \fImodel\fR argument identifies the image, and
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
specify a rectangular region within the image that needs to
be redrawn.
\fIimageWidth\fR and \fIimageHeight\fR specify the image's (new) size.
.PP
An image manager should call \fBTk_ImageChanged\fR during
its \fIcreateProc\fR to specify the image's initial size and to
force redisplay if there are existing instances for the image.
If any of the pixel values in the image should change later on,
\fBTk_ImageChanged\fR should be called again with \fIx\fR, \fIy\fR,
\fIwidth\fR, and \fIheight\fR values that cover all the pixels
that changed.
If the size of the image should change, then \fBTk_ImageChanged\fR
must be called to indicate the new size, even if no pixels
need to be redisplayed.

.SH "SEE ALSO"
Tk_CreateImageType

.SH KEYWORDS
images, redisplay, image size changes






|









|

|
|

















>







|















>


>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ImageChanged 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fIimageMaster, x, y, width, height, imageWidth, imageHeight\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageHeight
.AP Tk_ImageMaster imageMaster in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP int y in
Y-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP "int" width in
Width of region that needs to be redrawn, in pixels.
.AP "int" height in
Height of region that needs to be redrawn, in pixels.
.AP "int" imageWidth in
Current width of image, in pixels.
.AP "int" imageHeight in
Current height of image, in pixels.
.BE

.SH DESCRIPTION
.PP
An image manager calls \fBTk_ImageChanged\fR for an image
whenever anything happens that requires the image to be redrawn.
As a result of calling \fBTk_ImageChanged\fR, any widgets using
the image are notified so that they can redisplay themselves
appropriately.
The \fIimageMaster\fR argument identifies the image, and
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
specify a rectangular region within the image that needs to
be redrawn.
\fIimageWidth\fR and \fIimageHeight\fR specify the image's (new) size.
.PP
An image manager should call \fBTk_ImageChanged\fR during
its \fIcreateProc\fR to specify the image's initial size and to
force redisplay if there are existing instances for the image.
If any of the pixel values in the image should change later on,
\fBTk_ImageChanged\fR should be called again with \fIx\fR, \fIy\fR,
\fIwidth\fR, and \fIheight\fR values that cover all the pixels
that changed.
If the size of the image should change, then \fBTk_ImageChanged\fR
must be called to indicate the new size, even if no pixels
need to be redisplayed.

.SH "SEE ALSO"
Tk_CreateImageType

.SH KEYWORDS
images, redisplay, image size changes

Changes to doc/Inactive.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32

33
34
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_GetUserInactiveTime 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime \- discover user inactivity time
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.sp
\fBTk_ResetUserInactiveTime(\fIdisplay\fB)\fR
.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetUserInactiveTime\fR returns the number of milliseconds that
have passed since the last user interaction (usually via keyboard or
mouse) with the respective display. On systems and displays that do not
support querying the user inactivity time, \fB\-1\fR is returned.
\fBTk_ResetUserInactiveTime\fR resets the user inactivity timer of the
given display to zero.  On windowing systems that do not support
multiple displays \fIdisplay\fR can be passed as \fBNULL\fR.

.SH KEYWORDS
idle, inactive



|












|






>





|
|


>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH Tk_GetUserInactiveTime 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime \- discover user inactivity time
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.sp
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE

.SH DESCRIPTION
.PP
\fBTk_GetUserInactiveTime\fR returns the number of milliseconds that
have passed since the last user interaction (usually via keyboard or
mouse) with the respective display. On systems and displays that do not
support querying the user inactiviy time, \fB\-1\fR is returned.
\fBTk_GetUserInactiveTime\fR resets the user inactivity timer of the
given display to zero.  On windowing systems that do not support
multiple displays \fIdisplay\fR can be passed as \fBNULL\fR.

.SH KEYWORDS
idle, inactive

Changes to doc/InternAtom.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_InternAtom 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InternAtom, Tk_GetAtomName \- manage cache of X atoms
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_InternAtom 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InternAtom, Tk_GetAtomName \- manage cache of X atoms
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30

31
32
33
34
35
36
37
.AP Tk_Window tkwin in
Token for window.  Used to map atom or name relative to a particular display.
.AP "const char" *name in
String name for which atom is desired.
.AP Atom atom in
Atom for which corresponding string name is desired.
.BE

.SH DESCRIPTION
.PP
These procedures are similar to the Xlib procedures
\fBXInternAtom\fR and \fBXGetAtomName\fR.  \fBTk_InternAtom\fR
returns the atom identifier associated with string given by
\fIname\fR;  the atom identifier is only valid for the display
associated with \fItkwin\fR.







>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.AP Tk_Window tkwin in
Token for window.  Used to map atom or name relative to a particular display.
.AP "const char" *name in
String name for which atom is desired.
.AP Atom atom in
Atom for which corresponding string name is desired.
.BE

.SH DESCRIPTION
.PP
These procedures are similar to the Xlib procedures
\fBXInternAtom\fR and \fBXGetAtomName\fR.  \fBTk_InternAtom\fR
returns the atom identifier associated with string given by
\fIname\fR;  the atom identifier is only valid for the display
associated with \fItkwin\fR.
47
48
49
50
51
52
53

54
55
Tk caches
the information returned by \fBTk_InternAtom\fR and \fBTk_GetAtomName\fR
so that future calls
for the same information can be serviced from the cache without
contacting the server.  Thus \fBTk_InternAtom\fR and \fBTk_GetAtomName\fR
are generally much faster than their Xlib counterparts, and they
should be used in place of the Xlib procedures.

.SH KEYWORDS
atom, cache, display







>


48
49
50
51
52
53
54
55
56
57
Tk caches
the information returned by \fBTk_InternAtom\fR and \fBTk_GetAtomName\fR
so that future calls
for the same information can be serviced from the cache without
contacting the server.  Thus \fBTk_InternAtom\fR and \fBTk_GetAtomName\fR
are generally much faster than their Xlib counterparts, and they
should be used in place of the Xlib procedures.

.SH KEYWORDS
atom, cache, display

Changes to doc/MainLoop.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26

27
28
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_MainLoop 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MainLoop \- loop for events until all windows are deleted
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MainLoop\fR()
.BE

.SH DESCRIPTION
.PP
\fBTk_MainLoop\fR is a procedure that loops repeatedly calling
\fBTcl_DoOneEvent\fR.  It returns only when there are no applications
left in this process (i.e. no main windows exist anymore).  Most
windowing applications will call \fBTk_MainLoop\fR after
initialization; the main execution of the application will consist
entirely of callbacks invoked via \fBTcl_DoOneEvent\fR.

.SH KEYWORDS
application, event, main loop






|











>








>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_MainLoop 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MainLoop \- loop for events until all windows are deleted
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MainLoop\fR()
.BE

.SH DESCRIPTION
.PP
\fBTk_MainLoop\fR is a procedure that loops repeatedly calling
\fBTcl_DoOneEvent\fR.  It returns only when there are no applications
left in this process (i.e. no main windows exist anymore).  Most
windowing applications will call \fBTk_MainLoop\fR after
initialization; the main execution of the application will consist
entirely of callbacks invoked via \fBTcl_DoOneEvent\fR.

.SH KEYWORDS
application, event, main loop

Changes to doc/MainWin.3.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21

22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38

39
40
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_MainWindow 3 7.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MainWindow, Tk_GetNumMainWindows \- functions for querying main window information

.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MainWindow\fR(\fIinterp\fR)
.sp
int
\fBTk_GetNumMainWindows\fR()

.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tcl_Interp *interp in/out
Interpreter associated with the application.
.BE

.SH DESCRIPTION
.PP
A main window is a special kind of toplevel window used as the
outermost window in an application.
.PP
If \fIinterp\fR is associated with a Tk application then \fBTk_MainWindow\fR
returns the application's main window. If there is no Tk application
associated with \fIinterp\fR then \fBTk_MainWindow\fR returns NULL and
leaves an error message in interpreter \fIinterp\fR's result.
.PP
\fBTk_GetNumMainWindows\fR returns a count of the number of main
windows currently open in the current thread.

.SH KEYWORDS
application, main window






|




|
>









>





>








|


|
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_MainWindow 3 7.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MainWindow, Tk_GetNumMainWindows \- functions for querying main
window information
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MainWindow\fR(\fIinterp\fR)
.sp
int
\fBTk_GetNumMainWindows\fR()

.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tcl_Interp *interp in/out
Interpreter associated with the application.
.BE

.SH DESCRIPTION
.PP
A main window is a special kind of toplevel window used as the
outermost window in an application.
.PP
If \fIinterp\fR is associated with a Tk application then \fBTk_MainWindow\fR
returns the application's main window. If there is no Tk application
associated with \fIinterp\fR then \fBTk_MainWindow\fR returns NULL and
leaves an error message in \fIinterp->result\fR.
.PP
\fBTk_GetNumMainWindows\fR returns a count of the number of main
windows currently open in the process.

.SH KEYWORDS
application, main window

Changes to doc/MaintGeom.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_MaintainGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MaintainGeometry, Tk_UnmaintainGeometry \- maintain geometry of one window relative to another
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MaintainGeometry\fR(\fIwindow, container, x, y, width, height\fR)
.sp
\fBTk_UnmaintainGeometry\fR(\fIwindow, container\fR)
.SH ARGUMENTS
.AS Tk_Window container
.AP Tk_Window window in
Window whose geometry is to be controlled.
.AP Tk_Window container in
Window relative to which \fIwindow\fR's geometry will be controlled.
.AP int x in
Desired x-coordinate of \fIwindow\fR in \fIcontainer\fR, measured in pixels
from the inside of \fIcontainer\fR's left border to the outside of
\fIwindow\fR's left border.
.AP int y in
Desired y-coordinate of \fIwindow\fR in \fIcontainer\fR, measured in pixels
from the inside of \fIcontainer\fR's top border to the outside of
\fIwindow\fR's top border.
.AP int width in
Desired width for \fIwindow\fR, in pixels.
.AP int height in
Desired height for \fIwindow\fR, in pixels.
.BE

.SH DESCRIPTION
.PP
\fBTk_MaintainGeometry\fR and \fBTk_UnmaintainGeometry\fR make it
easier for geometry managers to deal with windows whose containers are not
their parents.
Three problems arise if the container for a window is not its parent:
.IP [1]
The x- and y-position of the window must be translated from the
coordinate system of the container to that of the parent before
positioning the window.
.IP [2]
If the container window, or any of its ancestors up to the window's
parent, is moved, then the window must be repositioned within its
parent in order to maintain the correct position relative to the
container.
.IP [3]
If the container or one of its ancestors is mapped or unmapped, then
the window must be mapped or unmapped to correspond.
.LP
None of these problems is an issue if the parent and container are
the same.  For example, if the container or one of its ancestors
is unmapped, the window is automatically removed by the screen
by X.
.PP
\fBTk_MaintainGeometry\fR deals with these problems for windows
whose containers are not their parents, as well as handling the simpler
case of windows whose container are their parents.
\fBTk_MaintainGeometry\fR is typically called by a window manager
once it has decided where a window should be positioned relative
to its container.
\fBTk_MaintainGeometry\fR translates the coordinates to the
coordinate system of \fIwindow\fR's parent and then moves and
resizes the window appropriately.
Furthermore, it remembers the desired position and creates event
handlers to monitor the container and all of its ancestors up
to (but not including) the window's parent.
If any of these windows is moved, mapped, or unmapped,
the window will be adjusted so that it is mapped only when the
container is mapped and its geometry relative to the container
remains as specified by \fIx\fR, \fIy\fR, \fIwidth\fR, and
\fIheight\fR.
.PP
When a window manager relinquishes control over a window, or
if it decides that it does not want the window to appear on the
screen under any conditions, it calls \fBTk_UnmaintainGeometry\fR.
\fBTk_UnmaintainGeometry\fR unmaps the window and cancels any
previous calls to \fBTk_MaintainGeometry\fR for the
\fIcontainer\fR\-\fIwindow\fR pair, so that the window's
geometry and mapped state are no longer maintained
automatically.
\fBTk_UnmaintainGeometry\fR need not be called by a geometry
manager if the window, the container, or any of the container's ancestors
is destroyed:  Tk will call it automatically.
.PP
If \fBTk_MaintainGeometry\fR is called repeatedly for the same
\fIcontainer\fR\-\fIwindow\fR pair, the information from the most
recent call supersedes any older information.
If \fBTk_UnmaintainGeometry\fR is called for a \fIcontainer\fR\-\fIwindow\fR
pair that is is not currently managed, the call has no effect.
.SH KEYWORDS
geometry manager, map, container, parent, position, window, unmap






|









|

|

|
|

|
|

|
|
|

|
|
|

|

|

>



|

|

|
|
|

|
|

|

|
|

|
|
|


|
|
|

|
|

|
|

|
|

|
|








|



|



|

|


|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_MaintainGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MaintainGeometry, Tk_UnmaintainGeometry \- maintain geometry of one window relative to another
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MaintainGeometry\fR(\fIslave, master, x, y, width, height\fR)
.sp
\fBTk_UnmaintainGeometry\fR(\fIslave, master\fR)
.SH ARGUMENTS
.AS Tk_Window master
.AP Tk_Window slave in
Window whose geometry is to be controlled.
.AP Tk_Window master in
Window relative to which \fIslave\fR's geometry will be controlled.
.AP int x in
Desired x-coordinate of \fIslave\fR in \fImaster\fR, measured in pixels
from the inside of \fImaster\fR's left border to the outside of
\fIslave\fR's left border.
.AP int y in
Desired y-coordinate of \fIslave\fR in \fImaster\fR, measured in pixels
from the inside of \fImaster\fR's top border to the outside of
\fIslave\fR's top border.
.AP int width in
Desired width for \fIslave\fR, in pixels.
.AP int height in
Desired height for \fIslave\fR, in pixels.
.BE

.SH DESCRIPTION
.PP
\fBTk_MaintainGeometry\fR and \fBTk_UnmaintainGeometry\fR make it
easier for geometry managers to deal with slaves whose masters are not
their parents.
Three problems arise if the master for a slave is not its parent:
.IP [1]
The x- and y-position of the slave must be translated from the
coordinate system of the master to that of the parent before
positioning the slave.
.IP [2]
If the master window, or any of its ancestors up to the slave's
parent, is moved, then the slave must be repositioned within its
parent in order to maintain the correct position relative to the
master.
.IP [3]
If the master or one of its ancestors is mapped or unmapped, then
the slave must be mapped or unmapped to correspond.
.LP
None of these problems is an issue if the parent and master are
the same.  For example, if the master or one of its ancestors
is unmapped, the slave is automatically removed by the screen
by X.
.PP
\fBTk_MaintainGeometry\fR deals with these problems for slaves
whose masters are not their parents, as well as handling the simpler
case of slaves whose masters are their parents.
\fBTk_MaintainGeometry\fR is typically called by a window manager
once it has decided where a slave should be positioned relative
to its master.
\fBTk_MaintainGeometry\fR translates the coordinates to the
coordinate system of \fIslave\fR's parent and then moves and
resizes the slave appropriately.
Furthermore, it remembers the desired position and creates event
handlers to monitor the master and all of its ancestors up
to (but not including) the slave's parent.
If any of these windows is moved, mapped, or unmapped,
the slave will be adjusted so that it is mapped only when the
master is mapped and its geometry relative to the master
remains as specified by \fIx\fR, \fIy\fR, \fIwidth\fR, and
\fIheight\fR.
.PP
When a window manager relinquishes control over a window, or
if it decides that it does not want the window to appear on the
screen under any conditions, it calls \fBTk_UnmaintainGeometry\fR.
\fBTk_UnmaintainGeometry\fR unmaps the window and cancels any
previous calls to \fBTk_MaintainGeometry\fR for the
\fImaster\fR\-\fIslave\fR pair, so that the slave's
geometry and mapped state are no longer maintained
automatically.
\fBTk_UnmaintainGeometry\fR need not be called by a geometry
manager if the slave, the master, or any of the master's ancestors
is destroyed:  Tk will call it automatically.
.PP
If \fBTk_MaintainGeometry\fR is called repeatedly for the same
\fImaster\fR\-\fIslave\fR pair, the information from the most
recent call supersedes any older information.
If \fBTk_UnmaintainGeometry\fR is called for a \fImaster\fR\-\fIslave\fR
pair that is is not currently managed, the call has no effect.
.SH KEYWORDS
geometry manager, map, master, parent, position, slave, unmap

Changes to doc/ManageGeom.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ManageGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ManageGeometry \- arrange to handle geometry requests for a window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ManageGeometry 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ManageGeometry \- arrange to handle geometry requests for a window
.SH SYNOPSIS
.nf
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
.AP ClientData clientData in
Arbitrary one-word value to pass to geometry manager callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_ManageGeometry\fR arranges for a particular geometry manager,
described by the \fImgrPtr\fR argument, to control the geometry
of a particular content window, given by \fItkwin\fR.
If \fItkwin\fR was previously managed by some other geometry manager,
the previous manager loses control in favor of the new one.
If \fImgrPtr\fR is NULL, geometry management is cancelled for
\fItkwin\fR.
.PP
The structure pointed to by \fImgrPtr\fR contains information about
the geometry manager:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_GeomRequestProc *\fIrequestProc\fR;
    Tk_GeomLostContentProc *\fIlostContentProc\fR;
} \fBTk_GeomMgr\fR;
.CE
The \fIname\fR field is the textual name for the geometry manager,
such as \fBpack\fR or \fBplace\fR;  this value will be returned
by the command \fBwinfo manager\fR.
.PP
\fIrequestProc\fR is a procedure in the geometry manager that
will be invoked whenever \fBTk_GeometryRequest\fR is called by the
content window to change its desired geometry.
\fIrequestProc\fR should have arguments and results that match the
type \fBTk_GeomRequestProc\fR:
.CS
typedef void \fBTk_GeomRequestProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.
.PP
The \fIlostContentProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostContentProc\fR if some other manager
calls \fBTk_ManageGeometry\fR to claim
\fItkwin\fR away from the current geometry manager.
\fIlostContentProc\fR is not invoked if \fBTk_ManageGeometry\fR is
called with a NULL value for \fImgrPtr\fR (presumably the current
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostContentProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostContentProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostContentProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.

.SH KEYWORDS
callback, geometry, managed, request, unmanaged







|











|
|







|



|
|
|







|

|


|




|


|
|
|

|

>


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
.AP ClientData clientData in
Arbitrary one-word value to pass to geometry manager callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_ManageGeometry\fR arranges for a particular geometry manager,
described by the \fImgrPtr\fR argument, to control the geometry
of a particular slave window, given by \fItkwin\fR.
If \fItkwin\fR was previously managed by some other geometry manager,
the previous manager loses control in favor of the new one.
If \fImgrPtr\fR is NULL, geometry management is cancelled for
\fItkwin\fR.
.PP
The structure pointed to by \fImgrPtr\fR contains information about
the geometry manager:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_GeomRequestProc *\fIrequestProc\fR;
    Tk_GeomLostSlaveProc *\fIlostSlaveProc\fR;
} Tk_GeomMgr;
.CE
The \fIname\fR field is the textual name for the geometry manager,
such as \fBpack\fR or \fBplace\fR;  this value will be returned
by the command \fBwinfo manager\fR.
.PP
\fIrequestProc\fR is a procedure in the geometry manager that
will be invoked whenever \fBTk_GeometryRequest\fR is called by the
slave to change its desired geometry.
\fIrequestProc\fR should have arguments and results that match the
type \fBTk_GeomRequestProc\fR:
.CS
typedef void Tk_GeomRequestProc(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR);
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.
.PP
The \fIlostSlaveProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostSlaveProc\fR if some other manager
calls \fBTk_ManageGeometry\fR to claim
\fItkwin\fR away from the current geometry manager.
\fIlostSlaveProc\fR is not invoked if \fBTk_ManageGeometry\fR is
called with a NULL value for \fImgrPtr\fR (presumably the current
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostSlaveProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void Tk_GeomLostSlaveProc(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostSlaveProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.

.SH KEYWORDS
callback, geometry, managed, request, unmanaged

Changes to doc/MapWindow.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_MapWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MapWindow, Tk_UnmapWindow \- map or unmap a window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MapWindow\fR(\fItkwin\fR)
.sp
\fBTk_UnmapWindow\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
These procedures may be used to map and unmap windows
managed by Tk.  \fBTk_MapWindow\fR maps the window given
by \fItkwin\fR, and also creates an X window corresponding
to \fItkwin\fR if it does not already exist.  See the
\fBTk_CreateWindow\fR manual entry for information on
deferred window creation.
\fBTk_UnmapWindow\fR unmaps \fItkwin\fR's window
from the screen.
.PP
If \fItkwin\fR is a child window (i.e. \fBTk_CreateWindow\fR was
used to create a child window), then event handlers interested in map
and unmap events are invoked immediately.  If \fItkwin\fR is not an
internal window, then the event handlers will be invoked later, after
X has seen the request and returned an event for it.
.PP
These procedures should be used in place of the X procedures
\fBXMapWindow\fR and \fBXUnmapWindow\fR, since they update
Tk's local data structure for \fItkwin\fR.  Applications
using Tk should not invoke \fBXMapWindow\fR and \fBXUnmapWindow\fR
directly.

.SH KEYWORDS
map, unmap, window






|


















>












|
|
|







>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_MapWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MapWindow, Tk_UnmapWindow \- map or unmap a window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MapWindow\fR(\fItkwin\fR)
.sp
\fBTk_UnmapWindow\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
These procedures may be used to map and unmap windows
managed by Tk.  \fBTk_MapWindow\fR maps the window given
by \fItkwin\fR, and also creates an X window corresponding
to \fItkwin\fR if it does not already exist.  See the
\fBTk_CreateWindow\fR manual entry for information on
deferred window creation.
\fBTk_UnmapWindow\fR unmaps \fItkwin\fR's window
from the screen.
.PP
If \fItkwin\fR is a child window (i.e. \fBTk_CreateWindow\fR was
used to create a child window), then event handlers interested in map 
and unmap events are invoked immediately.  If \fItkwin\fR is not an 
internal window, then the event handlers will be invoked later, after 
X has seen the request and returned an event for it.
.PP
These procedures should be used in place of the X procedures
\fBXMapWindow\fR and \fBXUnmapWindow\fR, since they update
Tk's local data structure for \fItkwin\fR.  Applications
using Tk should not invoke \fBXMapWindow\fR and \fBXUnmapWindow\fR
directly.

.SH KEYWORDS
map, unmap, window

Changes to doc/MeasureChar.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_MeasureChars 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MeasureChars, Tk_TextWidth, Tk_DrawChars, Tk_UnderlineChars \- routines to measure and display simple single-line strings.
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_MeasureChars 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MeasureChars, Tk_TextWidth, Tk_DrawChars, Tk_UnderlineChars \- routines to measure and display simple single-line strings.
.SH SYNOPSIS
.nf
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.AP Tk_Font tkfont in
Token for font in which text is to be drawn or measured.  Must have been
returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Text to be measured or displayed.  Need not be null terminated.  Any
non-printing meta-characters in the string (such as tabs, newlines, and
other control characters) will be measured or displayed in a
platform-dependent manner.
.AP int numBytes in
The maximum number of bytes to consider when measuring or drawing
\fIstring\fR.  Must be greater than or equal to 0.
.AP int maxPixels in
If \fImaxPixels\fR is >= 0, it specifies the longest permissible
line length in pixels.  Characters from \fIstring\fR are processed only
until this many pixels have been covered.  If \fImaxPixels\fR is < 0, then







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.AP Tk_Font tkfont in
Token for font in which text is to be drawn or measured.  Must have been
returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Text to be measured or displayed.  Need not be null terminated.  Any
non-printing meta-characters in the string (such as tabs, newlines, and
other control characters) will be measured or displayed in a
platform-dependent manner.  
.AP int numBytes in
The maximum number of bytes to consider when measuring or drawing
\fIstring\fR.  Must be greater than or equal to 0.
.AP int maxPixels in
If \fImaxPixels\fR is >= 0, it specifies the longest permissible
line length in pixels.  Characters from \fIstring\fR are processed only
until this many pixels have been covered.  If \fImaxPixels\fR is < 0, then
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
Filled with the number of pixels occupied by the number of characters
returned as the result of \fBTk_MeasureChars\fR.
.AP Display *display in
Display on which to draw.
.AP Drawable drawable in
Window or pixmap in which to draw.
.AP GC gc in
Graphics context for drawing characters.  The font selected into this GC
must be the same as the \fItkfont\fR.
.AP int "x, y" in
Coordinates at which to place the left edge of the baseline when displaying
\fIstring\fR.
.AP int firstByte in
The index of the first byte of the first character to underline in the
\fIstring\fR.  Underlining begins at the left edge of this character.
.AP int lastByte in
The index of the first byte of the last character up to which the
underline will be drawn.  The character specified by \fIlastByte\fR
will not itself be underlined.
.BE
.SH DESCRIPTION
.PP
These routines are for measuring and displaying simple single-font,
single-line strings.  To measure and display single-font, multi-line,
justified text, refer to the documentation for \fBTk_ComputeTextLayout\fR.
There is no programming interface in the core of Tk that supports
multi-font, multi-line text; support for that behavior must be built on
top of simpler layers.
Note that the interfaces described here are
byte-oriented not character-oriented, so index values coming from Tcl
scripts need to be converted to byte offsets using the
\fBTcl_UtfAtIndex\fR and related routines.
.PP
A glyph is the displayable picture of a letter, number, or some other
symbol.  Not all character codes in a given font have a glyph.
Characters such as tabs, newlines/returns, and control characters that
have no glyph are measured and displayed by these procedures in a
platform-dependent manner; under X, they are replaced with backslashed
escape sequences, while under Windows and Macintosh hollow or solid boxes
may be substituted.  Refer to the documentation for
\fBTk_ComputeTextLayout\fR for a programming interface that supports the
platform-independent expansion of tab characters into columns and
newlines/returns into multi-line text.
.PP
\fBTk_MeasureChars\fR is used both to compute the length of a given
string and to compute how many characters from a string fit in a given
amount of space.  The return value is the number of bytes from
\fIstring\fR that fit in the space specified by \fImaxPixels\fR subject to
the conditions described by \fIflags\fR.  If all characters fit, the return
value will be \fInumBytes\fR.  \fI*lengthPtr\fR is filled with the computed
width, in pixels, of the portion of the string that was measured.  For
example, if the return value is 5, then \fI*lengthPtr\fR is filled with the
distance between the left edge of \fIstring\fR[0] and the right edge of
\fIstring\fR[4].
.PP
\fBTk_TextWidth\fR is a wrapper function that provides a simpler interface
to the \fBTk_MeasureChars\fR function.  The return value is how much
space in pixels the given \fIstring\fR needs.
.PP
\fBTk_DrawChars\fR draws the \fIstring\fR at the given location in the
given \fIdrawable\fR.
.PP
\fBTk_UnderlineChars\fR underlines the given range of characters in the
given \fIstring\fR.  It does not draw the characters (which are assumed to
have been displayed previously by \fBTk_DrawChars\fR); it just draws the
underline.  This procedure is used to underline a few characters without
having to construct an underlined font.  To produce natively underlined
text, the appropriate underlined font should be constructed and used.
.SH "SEE ALSO"
font(n), FontId(3)
.SH KEYWORDS
font, measurement







|



|















|














|










|




|








|




56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
Filled with the number of pixels occupied by the number of characters
returned as the result of \fBTk_MeasureChars\fR.
.AP Display *display in
Display on which to draw.
.AP Drawable drawable in
Window or pixmap in which to draw.
.AP GC gc in
Graphics context for drawing characters.  The font selected into this GC 
must be the same as the \fItkfont\fR.
.AP int "x, y" in
Coordinates at which to place the left edge of the baseline when displaying
\fIstring\fR.  
.AP int firstByte in
The index of the first byte of the first character to underline in the
\fIstring\fR.  Underlining begins at the left edge of this character.
.AP int lastByte in
The index of the first byte of the last character up to which the
underline will be drawn.  The character specified by \fIlastByte\fR
will not itself be underlined.
.BE
.SH DESCRIPTION
.PP
These routines are for measuring and displaying simple single-font,
single-line strings.  To measure and display single-font, multi-line,
justified text, refer to the documentation for \fBTk_ComputeTextLayout\fR.
There is no programming interface in the core of Tk that supports
multi-font, multi-line text; support for that behavior must be built on
top of simpler layers.  
Note that the interfaces described here are
byte-oriented not character-oriented, so index values coming from Tcl
scripts need to be converted to byte offsets using the
\fBTcl_UtfAtIndex\fR and related routines.
.PP
A glyph is the displayable picture of a letter, number, or some other
symbol.  Not all character codes in a given font have a glyph.
Characters such as tabs, newlines/returns, and control characters that
have no glyph are measured and displayed by these procedures in a
platform-dependent manner; under X, they are replaced with backslashed
escape sequences, while under Windows and Macintosh hollow or solid boxes
may be substituted.  Refer to the documentation for
\fBTk_ComputeTextLayout\fR for a programming interface that supports the
platform-independent expansion of tab characters into columns and
newlines/returns into multi-line text.  
.PP
\fBTk_MeasureChars\fR is used both to compute the length of a given
string and to compute how many characters from a string fit in a given
amount of space.  The return value is the number of bytes from
\fIstring\fR that fit in the space specified by \fImaxPixels\fR subject to
the conditions described by \fIflags\fR.  If all characters fit, the return
value will be \fInumBytes\fR.  \fI*lengthPtr\fR is filled with the computed
width, in pixels, of the portion of the string that was measured.  For
example, if the return value is 5, then \fI*lengthPtr\fR is filled with the
distance between the left edge of \fIstring\fR[0] and the right edge of
\fIstring\fR[4]. 
.PP
\fBTk_TextWidth\fR is a wrapper function that provides a simpler interface
to the \fBTk_MeasureChars\fR function.  The return value is how much
space in pixels the given \fIstring\fR needs.
.PP 
\fBTk_DrawChars\fR draws the \fIstring\fR at the given location in the
given \fIdrawable\fR.
.PP
\fBTk_UnderlineChars\fR underlines the given range of characters in the
given \fIstring\fR.  It does not draw the characters (which are assumed to
have been displayed previously by \fBTk_DrawChars\fR); it just draws the
underline.  This procedure is used to underline a few characters without
having to construct an underlined font.  To produce natively underlined
text, the appropriate underlined font should be constructed and used. 
.SH "SEE ALSO"
font(n), FontId(3)
.SH KEYWORDS
font, measurement

Changes to doc/MoveToplev.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_MoveToplevelWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MoveToplevelWindow \- Adjust the position of a top-level window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_MoveToplevelWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_MoveToplevelWindow \- Adjust the position of a top-level window
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
top-left pixel of the decorative border supplied for \fItkwin\fR by the
window manager, if there is one.
.AP int y in
New y-coordinate for the top-left pixel of \fItkwin\fR's border, or the
top-left pixel of the decorative border supplied for \fItkwin\fR by the
window manager, if there is one.
.BE

.SH DESCRIPTION
.PP
In general, a window should never set its own position;  this should be
done only by the geometry manger that is responsible for the window.
For top-level windows the window manager is effectively the geometry
manager;  Tk provides interface code between the application and the
window manager to convey the application's desires to the geometry
manager.  The desired size for a top-level window is conveyed using
the usual \fBTk_GeometryRequest\fR mechanism.  The procedure
\fBTk_MoveToplevelWindow\fR may be used by an application to request
a particular position for a top-level window;  this procedure is
similar in function to the \fBwm geometry\fR Tcl command except that
negative offsets cannot be specified.  It is invoked by widgets such as
menus that want to appear at a particular place on the screen.
.PP
When \fBTk_MoveToplevelWindow\fR is called it does not immediately
pass on the new desired location to the window manager;  it defers
this action until all other outstanding work has been completed,
using the \fBTcl_DoWhenIdle\fR mechanism.

.SH KEYWORDS
position, top-level window, window manager







>



















>


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
top-left pixel of the decorative border supplied for \fItkwin\fR by the
window manager, if there is one.
.AP int y in
New y-coordinate for the top-left pixel of \fItkwin\fR's border, or the
top-left pixel of the decorative border supplied for \fItkwin\fR by the
window manager, if there is one.
.BE

.SH DESCRIPTION
.PP
In general, a window should never set its own position;  this should be
done only by the geometry manger that is responsible for the window.
For top-level windows the window manager is effectively the geometry
manager;  Tk provides interface code between the application and the
window manager to convey the application's desires to the geometry
manager.  The desired size for a top-level window is conveyed using
the usual \fBTk_GeometryRequest\fR mechanism.  The procedure
\fBTk_MoveToplevelWindow\fR may be used by an application to request
a particular position for a top-level window;  this procedure is
similar in function to the \fBwm geometry\fR Tcl command except that
negative offsets cannot be specified.  It is invoked by widgets such as
menus that want to appear at a particular place on the screen.
.PP
When \fBTk_MoveToplevelWindow\fR is called it does not immediately
pass on the new desired location to the window manager;  it defers
this action until all other outstanding work has been completed,
using the \fBTcl_DoWhenIdle\fR mechanism.

.SH KEYWORDS
position, top-level window, window manager

Changes to doc/Name.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\"
.TH Tk_Name 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Name, Tk_PathName, Tk_NameToWindow \- convert between names and window tokens
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH Tk_Name 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Name, Tk_PathName, Tk_NameToWindow \- convert between names and window tokens
.SH SYNOPSIS
.nf
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
.AP Tk_Window tkwin in
Token for window.
.AP Tcl_Interp *interp out
Interpreter to use for error reporting.
.AP "const char" *pathName in
Character string containing path name of window.
.BE

.SH DESCRIPTION
.PP
Each window managed by Tk has two names, a short name that identifies
a window among children of the same parent, and a path name that
identifies the window uniquely among all the windows belonging to the
same main window.  The path name is used more often in Tk than the
short name;  many commands, like \fBbind\fR, expect path names as
arguments.
.PP
The \fBTk_Name\fR macro returns a window's
short name, which is the same as the \fIname\fR argument
passed to \fBTk_CreateWindow\fR when
the window was created.  The value is returned
as a Tk_Uid, which may be used just like a string pointer but also has
the properties of a unique identifier (see the manual entry for
\fBTk_GetUid\fR for details).
.PP
The \fBTk_PathName\fR macro returns a hierarchical name for \fItkwin\fR.

Path names have a structure similar to file names in Unix but with
dots between elements instead of slashes:  the main window for
an application has the path name
.QW . ;
its children have names like
.QW .a
and







>

















|
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
.AP Tk_Window tkwin in
Token for window.
.AP Tcl_Interp *interp out
Interpreter to use for error reporting.
.AP "const char" *pathName in
Character string containing path name of window.
.BE

.SH DESCRIPTION
.PP
Each window managed by Tk has two names, a short name that identifies
a window among children of the same parent, and a path name that
identifies the window uniquely among all the windows belonging to the
same main window.  The path name is used more often in Tk than the
short name;  many commands, like \fBbind\fR, expect path names as
arguments.
.PP
The \fBTk_Name\fR macro returns a window's
short name, which is the same as the \fIname\fR argument
passed to \fBTk_CreateWindow\fR when
the window was created.  The value is returned
as a Tk_Uid, which may be used just like a string pointer but also has
the properties of a unique identifier (see the manual entry for
\fBTk_GetUid\fR for details).
.PP
The \fBTk_PathName\fR macro returns a
hierarchical name for \fItkwin\fR.
Path names have a structure similar to file names in Unix but with
dots between elements instead of slashes:  the main window for
an application has the path name
.QW . ;
its children have names like
.QW .a
and
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
is created as a child of the root window, but its logical parent will
usually be a window within the application.
.PP
The procedure \fBTk_NameToWindow\fR returns the token for a window
given its path name (the \fIpathName\fR argument) and another window
belonging to the same main window (\fItkwin\fR).  It normally
returns a token for the named window, but if no such window exists
\fBTk_NameToWindow\fR leaves an error message in interpreter
\fIinterp\fR's result
and returns NULL.  The \fItkwin\fR argument to \fBTk_NameToWindow\fR
is needed because path names are only unique within a single
application hierarchy.  If, for example, a single process has opened
two main windows, each will have a separate naming hierarchy and the
same path name might appear in each of the hierarchies.  Normally
\fItkwin\fR is the main window of the desired hierarchy, but this
need not be the case:  any window in the desired hierarchy may be used.

.SH KEYWORDS
name, path name, token, window







|
<







>


71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
is created as a child of the root window, but its logical parent will
usually be a window within the application.
.PP
The procedure \fBTk_NameToWindow\fR returns the token for a window
given its path name (the \fIpathName\fR argument) and another window
belonging to the same main window (\fItkwin\fR).  It normally
returns a token for the named window, but if no such window exists
\fBTk_NameToWindow\fR leaves an error message in \fIinterp->result\fR

and returns NULL.  The \fItkwin\fR argument to \fBTk_NameToWindow\fR
is needed because path names are only unique within a single
application hierarchy.  If, for example, a single process has opened
two main windows, each will have a separate naming hierarchy and the
same path name might appear in each of the hierarchies.  Normally
\fItkwin\fR is the main window of the desired hierarchy, but this
need not be the case:  any window in the desired hierarchy may be used.

.SH KEYWORDS
name, path name, token, window

Changes to doc/NameOfImg.3.

10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28

29
30
.SH NAME
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageModel\fR)
.SH ARGUMENTS
.AS Tk_ImageModel imageModel
.AP Tk_ImageModel imageModel in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked by image managers to find out the name
of an image.  Given the token for the image, it returns the
string name for the image.

.SH KEYWORDS
image manager, image name







|

|
|



>





>


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.SH NAME
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageMaster\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageMaster
.AP Tk_ImageMaster imageMaster in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE

.SH DESCRIPTION
.PP
This procedure is invoked by image managers to find out the name
of an image.  Given the token for the image, it returns the
string name for the image.

.SH KEYWORDS
image manager, image name

Changes to doc/OwnSelect.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_OwnSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_OwnSelection \- make a window the owner of the primary selection
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_OwnSelection 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_OwnSelection \- make a window the owner of the primary selection
.SH SYNOPSIS
.nf
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
.AP Atom selection in
The name of the selection to be owned, such as XA_PRIMARY.
.AP Tk_LostSelProc *proc in
Procedure to invoke when \fItkwin\fR loses selection ownership later.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_OwnSelection\fR arranges for \fItkwin\fR to become the
new owner of the selection specified by the atom
\fIselection\fR.  After this call completes, future requests
for the selection will be directed to handlers created for
\fItkwin\fR using \fBTk_CreateSelHandler\fR.  When \fItkwin\fR
eventually loses the selection ownership, \fIproc\fR will be
invoked so that the window can clean itself up (e.g. by
unhighlighting the selection).  \fIProc\fR should have arguments and
result that match the type \fBTk_LostSelProc\fR:
.CS
typedef void \fBTk_LostSelProc\fR(
        ClientData \fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_OwnSelection\fR, and is
usually a pointer to a data structure containing application-specific
information about \fItkwin\fR.

.SH KEYWORDS
own, selection owner







>












<
|





>


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
.AP Atom selection in
The name of the selection to be owned, such as XA_PRIMARY.
.AP Tk_LostSelProc *proc in
Procedure to invoke when \fItkwin\fR loses selection ownership later.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_OwnSelection\fR arranges for \fItkwin\fR to become the
new owner of the selection specified by the atom
\fIselection\fR.  After this call completes, future requests
for the selection will be directed to handlers created for
\fItkwin\fR using \fBTk_CreateSelHandler\fR.  When \fItkwin\fR
eventually loses the selection ownership, \fIproc\fR will be
invoked so that the window can clean itself up (e.g. by
unhighlighting the selection).  \fIProc\fR should have arguments and
result that match the type \fBTk_LostSelProc\fR:
.CS

typedef void Tk_LostSelProc(ClientData \fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_OwnSelection\fR, and is
usually a pointer to a data structure containing application-specific
information about \fItkwin\fR.

.SH KEYWORDS
own, selection owner

Changes to doc/ParseArgv.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_ParseArgv 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ParseArgv \- process command-line options
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_ParseArgv 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ParseArgv \- process command-line options
.SH SYNOPSIS
.nf
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
an argument that does not match \fIargTable\fR and returned to the
caller;  however, if the \fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR bit is set in
\fIflags\fR then \fIargv[0]\fR will be processed just like the other
elements of \fIargv\fR.
.PP
\fBTk_ParseArgv\fR normally returns the value \fBTCL_OK\fR.  If an error
occurs while parsing the arguments, then \fBTCL_ERROR\fR is returned and
\fBTk_ParseArgv\fR will leave an error message in the result of
interpreter \fIinterp\fR in the standard Tcl fashion.  In
the event of an error return, \fI*argvPtr\fR will not have been
modified, but \fIargv\fR could have been partially modified.  The
possible causes of errors are explained below.
.PP
The \fIargTable\fR array specifies the kinds of arguments that are
expected;  each of its entries has the following structure:
.CS
typedef struct {
    const char *\fIkey\fR;
    int \fItype\fR;
    void *\fIsrc\fR;
    void *\fIdst\fR;
    const char *\fIhelp\fR;
} \fBTk_ArgvInfo\fR;
.CE
The \fIkey\fR field is a string such as
.QW \-display
or
.QW \-bg
that is compared with the values in \fIargv\fR.  \fIType\fR
indicates how to process an argument that matches \fIkey\fR







|
|








|

|
|
|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
an argument that does not match \fIargTable\fR and returned to the
caller;  however, if the \fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR bit is set in
\fIflags\fR then \fIargv[0]\fR will be processed just like the other
elements of \fIargv\fR.
.PP
\fBTk_ParseArgv\fR normally returns the value \fBTCL_OK\fR.  If an error
occurs while parsing the arguments, then \fBTCL_ERROR\fR is returned and
\fBTk_ParseArgv\fR will leave an error message in \fIinterp->result\fR
in the standard Tcl fashion.  In
the event of an error return, \fI*argvPtr\fR will not have been
modified, but \fIargv\fR could have been partially modified.  The
possible causes of errors are explained below.
.PP
The \fIargTable\fR array specifies the kinds of arguments that are
expected;  each of its entries has the following structure:
.CS
typedef struct {
    char *\fIkey\fR;
    int \fItype\fR;
    char *\fIsrc\fR;
    char *\fIdst\fR;
    char *\fIhelp\fR;
} Tk_ArgvInfo;
.CE
The \fIkey\fR field is a string such as
.QW \-display
or
.QW \-bg
that is compared with the values in \fIargv\fR.  \fIType\fR
indicates how to process an argument that matches \fIkey\fR
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
arguments are discarded from \fIargv\fR.  If \fItkwin\fR is NULL,
then argument
specifiers of this type are ignored (as if they did not exist).
.TP
\fBTK_ARGV_HELP\fR
When this kind of option is encountered, \fBTk_ParseArgv\fR uses the
\fIhelp\fR fields of \fIargTable\fR to format a message describing
all the valid arguments.  The message is placed in interpreter
\fIinterp\fR's result
and \fBTk_ParseArgv\fR returns \fBTCL_ERROR\fR.  When this happens, the
caller normally prints the help message and aborts.  If the \fIkey\fR
field of a \fBTK_ARGV_HELP\fR specifier is NULL, then the specifier will
never match any arguments;  in this case the specifier simply provides
extra documentation, which will be included when some other
\fBTK_ARGV_HELP\fR entry causes help information to be returned.
.TP







|
<







182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
arguments are discarded from \fIargv\fR.  If \fItkwin\fR is NULL,
then argument
specifiers of this type are ignored (as if they did not exist).
.TP
\fBTK_ARGV_HELP\fR
When this kind of option is encountered, \fBTk_ParseArgv\fR uses the
\fIhelp\fR fields of \fIargTable\fR to format a message describing
all the valid arguments.  The message is placed in \fIinterp->result\fR

and \fBTk_ParseArgv\fR returns \fBTCL_ERROR\fR.  When this happens, the
caller normally prints the help message and aborts.  If the \fIkey\fR
field of a \fBTK_ARGV_HELP\fR specifier is NULL, then the specifier will
never match any arguments;  in this case the specifier simply provides
extra documentation, which will be included when some other
\fBTK_ARGV_HELP\fR entry causes help information to be returned.
.TP
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
\fIArgc\fR and \fIargv\fR refer to all of the options after the
matching one.  \fIGenfunc\fR should behave in a fashion similar
to \fBTk_ParseArgv\fR:  parse as many of the remaining arguments as it can,
then return any that are left by compacting them to the beginning of
\fIargv\fR (starting at \fIargv\fR[0]).  \fIGenfunc\fR
should return a count of how many arguments are left in \fIargv\fR;
\fBTk_ParseArgv\fR will process them.  If \fIgenfunc\fR encounters
an error then it should leave an error message in interpreter
\fIinterp\fR's result,
in the usual Tcl fashion, and return \-1;  when this happens
\fBTk_ParseArgv\fR will abort its processing and return \fBTCL_ERROR\fR.
.RE
.SS "FLAGS"
.TP
\fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR
\fBTk_ParseArgv\fR normally treats \fIargv[0]\fR as a program
or command name, and returns it to the caller just as if it
had not matched \fIargTable\fR.  If this flag is given, then
\fIargv[0]\fR is not given special treatment.
.TP







|
<



|







255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
\fIArgc\fR and \fIargv\fR refer to all of the options after the
matching one.  \fIGenfunc\fR should behave in a fashion similar
to \fBTk_ParseArgv\fR:  parse as many of the remaining arguments as it can,
then return any that are left by compacting them to the beginning of
\fIargv\fR (starting at \fIargv\fR[0]).  \fIGenfunc\fR
should return a count of how many arguments are left in \fIargv\fR;
\fBTk_ParseArgv\fR will process them.  If \fIgenfunc\fR encounters
an error then it should leave an error message in \fIinterp->result\fR,

in the usual Tcl fashion, and return \-1;  when this happens
\fBTk_ParseArgv\fR will abort its processing and return \fBTCL_ERROR\fR.
.RE
.SH "FLAGS"
.TP
\fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR
\fBTk_ParseArgv\fR normally treats \fIargv[0]\fR as a program
or command name, and returns it to the caller just as if it
had not matched \fIargTable\fR.  If this flag is given, then
\fIargv[0]\fR is not given special treatment.
.TP
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
char *fileName = defaultFileName;
Boolean exec = FALSE;

/*
 * Define option descriptions.
 */
Tk_ArgvInfo argTable[] = {
    {"\-X", TK_ARGV_CONSTANT, (char *) 1, &debugFlag,
        "Turn on debugging printfs"},
    {"\-N", TK_ARGV_INT, NULL, &numReps,
        "Number of repetitions"},
    {"\-of", TK_ARGV_STRING, NULL, &fileName,
        "Name of file for output"},
    {"x", TK_ARGV_REST, NULL, &exec,
        "File to exec, followed by any arguments (must be last argument)."},
    {NULL, TK_ARGV_END, NULL, NULL,
        NULL}
};

main(argc, argv)
    int argc;
    char *argv[];
{
    \&...

    if (Tk_ParseArgv(interp, tkwin, &argc, argv, argTable, 0) != TCL_OK) {
        fprintf(stderr, "%s\en", Tcl_GetString(Tcl_GetObjResult(interp)));
        exit(1);
    }

    /*
     * Remainder of the program.
     */
}







|

|

|

|

|
|









|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
char *fileName = defaultFileName;
Boolean exec = FALSE;

/*
 * Define option descriptions.
 */
Tk_ArgvInfo argTable[] = {
    {"\-X", TK_ARGV_CONSTANT, (char *) 1, (char *) &debugFlag,
        "Turn on debugging printfs"},
    {"\-N", TK_ARGV_INT, (char *) NULL, (char *) &numReps,
        "Number of repetitions"},
    {"\-of", TK_ARGV_STRING, (char *) NULL, (char *) &fileName,
        "Name of file for output"},
    {"x", TK_ARGV_REST, (char *) NULL, (char *) &exec,
        "File to exec, followed by any arguments (must be last argument)."},
    {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
        (char *) NULL}
};

main(argc, argv)
    int argc;
    char *argv[];
{
    \&...

    if (Tk_ParseArgv(interp, tkwin, &argc, argv, argTable, 0) != TCL_OK) {
        fprintf(stderr, "%s\en", interp->result);
        exit(1);
    }

    /*
     * Remainder of the program.
     */
}

Changes to doc/QWinEvent.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_QueueWindowEvent 3 7.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CollapseMotionEvents, Tk_QueueWindowEvent \- Add a window event to the Tcl event queue
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_QueueWindowEvent 3 7.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CollapseMotionEvents, Tk_QueueWindowEvent \- Add a window event to the Tcl event queue
.SH SYNOPSIS
.nf
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
.AP XEvent *eventPtr  in
An event to add to the event queue. It is important
that all unused fields of the structure be set to zero.
.AP Tcl_QueuePosition position in
Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR,
\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_QueueWindowEvent\fR places a window event on Tcl's internal event
queue for eventual servicing.  It creates a Tcl_Event structure, copies the
event into that structure, and calls \fBTcl_QueueEvent\fR to add the event
to the queue.  When the event is eventually removed from the queue it is
processed just like all window events.
.PP
When multiple motion events are received for the same window in rapid
succession, they are collapsed by default.  This behavior can be controlled
with \fBTk_CollapseMotionEvents\fR.  \fBTk_CollapseMotionEvents\fR always
returns the previous value for collapse behavior on the \fIdisplay\fR.
.PP
The \fIposition\fR argument to \fBTk_QueueWindowEvent\fR has
the same significance as for \fBTcl_QueueEvent\fR;  see the
documentation for \fBTcl_QueueEvent\fR for details.

.SH KEYWORDS
callback, clock, handler, modal timeout, events







>
















>


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
.AP XEvent *eventPtr  in
An event to add to the event queue. It is important
that all unused fields of the structure be set to zero.
.AP Tcl_QueuePosition position in
Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR,
\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_QueueWindowEvent\fR places a window event on Tcl's internal event
queue for eventual servicing.  It creates a Tcl_Event structure, copies the
event into that structure, and calls \fBTcl_QueueEvent\fR to add the event
to the queue.  When the event is eventually removed from the queue it is
processed just like all window events.
.PP
When multiple motion events are received for the same window in rapid
succession, they are collapsed by default.  This behavior can be controlled
with \fBTk_CollapseMotionEvents\fR.  \fBTk_CollapseMotionEvents\fR always
returns the previous value for collapse behavior on the \fIdisplay\fR.
.PP
The \fIposition\fR argument to \fBTk_QueueWindowEvent\fR has
the same significance as for \fBTcl_QueueEvent\fR;  see the
documentation for \fBTcl_QueueEvent\fR for details.

.SH KEYWORDS
callback, clock, handler, modal timeout, events

Changes to doc/Restack.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_RestackWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_RestackWindow \- Change a window's position in the stacking order
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_RestackWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_RestackWindow \- Change a window's position in the stacking order
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
Indicates new position of \fItkwin\fR relative to \fIother\fR;
must be \fBAbove\fR or \fBBelow\fR.
.AP Tk_Window other in
\fITkwin\fR will be repositioned just above or below this window.
Must be a sibling of \fItkwin\fR or a descendant of a sibling.
If NULL then \fItkwin\fR is restacked above or below all siblings.
.BE

.SH DESCRIPTION
.PP
\fBTk_RestackWindow\fR changes the stacking order of \fIwindow\fR relative
to its siblings.
If \fIother\fR is specified as NULL then \fIwindow\fR is repositioned
at the top or bottom of its stacking order, depending on whether
\fIaboveBelow\fR is \fBAbove\fR or \fBBelow\fR.
If \fIother\fR has a non-NULL value then \fIwindow\fR is repositioned
just above or below \fIother\fR.
.PP
The \fIaboveBelow\fR argument must have one of the symbolic values
\fBAbove\fR or \fBBelow\fR.
Both of these values are defined by the include file <X11/Xlib.h>.

.SH KEYWORDS
above, below, obscure, stacking order







>













>


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Indicates new position of \fItkwin\fR relative to \fIother\fR;
must be \fBAbove\fR or \fBBelow\fR.
.AP Tk_Window other in
\fITkwin\fR will be repositioned just above or below this window.
Must be a sibling of \fItkwin\fR or a descendant of a sibling.
If NULL then \fItkwin\fR is restacked above or below all siblings.
.BE

.SH DESCRIPTION
.PP
\fBTk_RestackWindow\fR changes the stacking order of \fIwindow\fR relative
to its siblings.
If \fIother\fR is specified as NULL then \fIwindow\fR is repositioned
at the top or bottom of its stacking order, depending on whether
\fIaboveBelow\fR is \fBAbove\fR or \fBBelow\fR.
If \fIother\fR has a non-NULL value then \fIwindow\fR is repositioned
just above or below \fIother\fR.
.PP
The \fIaboveBelow\fR argument must have one of the symbolic values
\fBAbove\fR or \fBBelow\fR.
Both of these values are defined by the include file <X11/Xlib.h>.

.SH KEYWORDS
above, below, obscure, stacking order

Changes to doc/RestrictEv.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_RestrictEvents 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_RestrictEvents \- filter and selectively delay X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_RestrictProc *
\fBTk_RestrictEvents\fR(\fIproc, arg, prevArgPtr\fR)
.SH ARGUMENTS
.AS Tk_RestrictProc **prevArgPtr
.AP Tk_RestrictProc *proc in
Predicate procedure to call to filter incoming X events.
NULL means do not restrict events at all.
.AP ClientData arg in
Arbitrary argument to pass to \fIproc\fR.
.AP ClientData *prevArgPtr out
Pointer to place to save argument to previous restrict procedure.
.BE

.SH DESCRIPTION
.PP
This procedure is useful in certain situations where applications
are only prepared to receive certain X events.  After
\fBTk_RestrictEvents\fR is called, \fBTcl_DoOneEvent\fR (and
hence \fBTk_MainLoop\fR) will filter X input events through
\fIproc\fR.  \fIProc\fR indicates whether a
given event is to be processed immediately, deferred until some
later time (e.g. when the event restriction is lifted), or discarded.
\fIProc\fR
is a procedure with arguments and result that match
the type \fBTk_RestrictProc\fR:
.CS
typedef Tk_RestrictAction \fBTk_RestrictProc\fR(
        ClientData \fIarg\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIarg\fR argument is a copy of the \fIarg\fR passed
to \fBTk_RestrictEvents\fR; it may be used to provide \fIproc\fR with
information it needs to filter events.  The \fIeventPtr\fR points to
an event under consideration.  \fIProc\fR returns a restrict action
(enumerated type \fBTk_RestrictAction\fR) that indicates what
\fBTcl_DoOneEvent\fR should do with the event.  If the return value is
\fBTK_PROCESS_EVENT\fR, then the event will be handled immediately.
If the return value is \fBTK_DEFER_EVENT\fR, then the event will be
left on the event queue for later processing.  If the return value is
\fBTK_DISCARD_EVENT\fR, then the event will be removed from the event
queue and discarded without being processed.
.PP
\fBTk_RestrictEvents\fR uses its return value and \fIprevArgPtr\fR
to return information about the current event restriction procedure
(a NULL return value means there are currently no restrictions).
These values may be used to restore the previous restriction state
when there is no longer any need for the current restriction.
.PP
There are very few places where \fBTk_RestrictEvents\fR is needed.
In most cases, the best way to restrict events is by changing the






|










|

|



|

|


>













|
|
|

|











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_RestrictEvents 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_RestrictEvents \- filter and selectively delay X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_RestrictProc *
\fBTk_RestrictEvents\fR(\fIproc, clientData, prevClientDataPtr\fR)
.SH ARGUMENTS
.AS Tk_RestrictProc **prevClientDataPtr
.AP Tk_RestrictProc *proc in
Predicate procedure to call to filter incoming X events.
NULL means do not restrict events at all.
.AP ClientData clientData in
Arbitrary argument to pass to \fIproc\fR.
.AP ClientData *prevClientDataPtr out
Pointer to place to save argument to previous restrict procedure.
.BE

.SH DESCRIPTION
.PP
This procedure is useful in certain situations where applications
are only prepared to receive certain X events.  After
\fBTk_RestrictEvents\fR is called, \fBTcl_DoOneEvent\fR (and
hence \fBTk_MainLoop\fR) will filter X input events through
\fIproc\fR.  \fIProc\fR indicates whether a
given event is to be processed immediately, deferred until some
later time (e.g. when the event restriction is lifted), or discarded.
\fIProc\fR
is a procedure with arguments and result that match
the type \fBTk_RestrictProc\fR:
.CS
typedef Tk_RestrictAction Tk_RestrictProc(
    ClientData \fIclientData\fR,
    XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR argument is a copy of the \fIclientData\fR passed
to \fBTk_RestrictEvents\fR; it may be used to provide \fIproc\fR with
information it needs to filter events.  The \fIeventPtr\fR points to
an event under consideration.  \fIProc\fR returns a restrict action
(enumerated type \fBTk_RestrictAction\fR) that indicates what
\fBTcl_DoOneEvent\fR should do with the event.  If the return value is
\fBTK_PROCESS_EVENT\fR, then the event will be handled immediately.
If the return value is \fBTK_DEFER_EVENT\fR, then the event will be
left on the event queue for later processing.  If the return value is
\fBTK_DISCARD_EVENT\fR, then the event will be removed from the event
queue and discarded without being processed.
.PP
\fBTk_RestrictEvents\fR uses its return value and \fIprevClientDataPtr\fR
to return information about the current event restriction procedure
(a NULL return value means there are currently no restrictions).
These values may be used to restore the previous restriction state
when there is no longer any need for the current restriction.
.PP
There are very few places where \fBTk_RestrictEvents\fR is needed.
In most cases, the best way to restrict events is by changing the

Changes to doc/SetAppName.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
'\"
'\" 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.
'\"
.TH Tk_SetAppName 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetAppName \- Set the name of an application for 'send' commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_SetAppName\fR(\fItkwin, name\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window in application.  Used only to select a particular
application.
.AP "const char" *name in
Name under which to register the application.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetAppName\fR associates a name with a given application and
records that association on the display containing with the application's
main window.
After this procedure has been invoked, other applications on the
display will be able to use the \fBsend\fR command to invoke operations






|



















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'\"
'\" 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.
'\" 
.TH Tk_SetAppName 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetAppName \- Set the name of an application for 'send' commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_SetAppName\fR(\fItkwin, name\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window in application.  Used only to select a particular
application.
.AP "const char" *name in
Name under which to register the application.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetAppName\fR associates a name with a given application and
records that association on the display containing with the application's
main window.
After this procedure has been invoked, other applications on the
display will be able to use the \fBsend\fR command to invoke operations
54
55
56
57
58
59
60

61
62
The application can be made accessible again by calling \fBTk_SetAppName\fR.
.PP
\fBTk_SetAppName\fR is called automatically by \fBTk_Init\fR,
so applications do not normally need to call it explicitly.
.PP
The command \fBtk appname\fR provides Tcl-level access to the
functionality of \fBTk_SetAppName\fR.

.SH KEYWORDS
application, name, register, send command







>


55
56
57
58
59
60
61
62
63
64
The application can be made accessible again by calling \fBTk_SetAppName\fR.
.PP
\fBTk_SetAppName\fR is called automatically by \fBTk_Init\fR,
so applications do not normally need to call it explicitly.
.PP
The command \fBtk appname\fR provides Tcl-level access to the
functionality of \fBTk_SetAppName\fR.

.SH KEYWORDS
application, name, register, send command

Changes to doc/SetCaret.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_SetCaretPos 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetCaretPos \- set the display caret location
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_SetCaretPos 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetCaretPos \- set the display caret location
.SH SYNOPSIS
.nf
21
22
23
24
25
26
27

28
29
30
31
32
33
34

35
36
.AP int x in
Window-relative x coordinate.
.AP int y in
Window-relative y coordinate.
.AP int h in
Height of the caret in the window.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetCaretPos\fR sets the caret location for the display of the
specified Tk_Window \fItkwin\fR.  The caret is the per-display cursor
location used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot XIM
(X Input Methods) or Windows IME windows.

.SH KEYWORDS
caret, cursor







>







>


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.AP int x in
Window-relative x coordinate.
.AP int y in
Window-relative y coordinate.
.AP int h in
Height of the caret in the window.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetCaretPos\fR sets the caret location for the display of the
specified Tk_Window \fItkwin\fR.  The caret is the per-display cursor
location used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot XIM
(X Input Methods) or Windows IME windows.

.SH KEYWORDS
caret, cursor

Changes to doc/SetClass.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_SetClass 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetClass, Tk_Class \- set or retrieve a window's class
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClass\fR(\fItkwin, class\fR)
.sp
Tk_Uid
\fBTk_Class\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.AP char *class in
New class name for window.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetClass\fR is called to associate a class with a particular
window.  The \fIclass\fR string identifies the type of the
window;  all windows with the same general class of behavior
(button, menu, etc.) should have the same class.  By
convention all class names start with a capital letter, and






|




















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_SetClass 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetClass, Tk_Class \- set or retrieve a window's class
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClass\fR(\fItkwin, class\fR)
.sp
Tk_Uid
\fBTk_Class\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.AP char *class in
New class name for window.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetClass\fR is called to associate a class with a particular
window.  The \fIclass\fR string identifies the type of the
window;  all windows with the same general class of behavior
(button, menu, etc.) should have the same class.  By
convention all class names start with a capital letter, and
49
50
51
52
53
54
55

56
57
\fBTk_Class\fR is a macro that returns the
current value of \fItkwin\fR's class.  The value is returned
as a Tk_Uid, which may be used just like a string pointer but also has
the properties of a unique identifier (see the manual entry for
\fBTk_GetUid\fR for details).
If \fItkwin\fR has not yet been given a class, then
\fBTk_Class\fR will return NULL.

.SH KEYWORDS
class, unique identifier, window, window manager







>


50
51
52
53
54
55
56
57
58
59
\fBTk_Class\fR is a macro that returns the
current value of \fItkwin\fR's class.  The value is returned
as a Tk_Uid, which may be used just like a string pointer but also has
the properties of a unique identifier (see the manual entry for
\fBTk_GetUid\fR for details).
If \fItkwin\fR has not yet been given a class, then
\fBTk_Class\fR will return NULL.

.SH KEYWORDS
class, unique identifier, window, window manager

Changes to doc/SetClassProcs.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
'\"
'\" 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.
'\"
.TH Tk_SetClassProcs 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetClassProcs \- register widget specific procedures
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClassProcs\fR(\fItkwin, procs, instanceData\fR)
.SH ARGUMENTS
.AS Tk_ClassProc instanceData
.AP Tk_Window tkwin in
Token for window to modify.
.AP "const Tk_ClassProcs" *procs in
Pointer to data structure containing widget specific procedures.
The data structure pointed to by \fIprocs\fR must be static:
Tk keeps a reference to it as long as the window exists.
.AP ClientData instanceData in
Arbitrary one-word value to pass to widget callbacks.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetClassProcs\fR is called to register a set of procedures that
are used as callbacks in different places.
.PP
The structure pointed to by \fIprocs\fR contains the following:
.CS
typedef struct Tk_ClassProcs {
    size_t \fIsize\fR;
    Tk_ClassWorldChangedProc *\fIworldChangedProc\fR;
    Tk_ClassCreateProc *\fIcreateProc\fR;
    Tk_ClassModalProc *\fImodalProc\fR;
} \fBTk_ClassProcs\fR;
.CE
The \fIsize\fR field is used to simplify future expansion of the
structure. It should always be set to (literally) \fBsizeof(Tk_ClassProcs)\fR.
.PP
\fIworldChangedProc\fR is invoked when the system has altered
in some way that requires some reaction from the widget.  For example,
when a font alias (see the \fBfont\fR manual entry) is reconfigured,
widgets configured to use that font alias must update their display
accordingly.  \fIworldChangedProc\fR should have arguments and results
that match the type \fBTk_ClassWorldChangedProc\fR:
.CS
typedef void \fBTk_ClassWorldChangedProc\fR(
        ClientData \fIinstanceData\fR);
.CE
The \fIinstanceData\fR parameter passed to the \fIworldChangedProc\fR
will be identical to the \fIinstanceData\fR parameter passed to
\fBTk_SetClassProcs\fR.
.PP
\fIcreateProc\fR is used to create platform-dependent windows.  It is
invoked by \fBTk_MakeWindowExist\fR.  \fIcreateProc\fR should have
arguments and results that match the type \fBTk_ClassCreateProc\fR:
.CS
typedef Window \fBTk_ClassCreateProc\fR(
        Tk_Window \fItkwin\fR,
        Window \fIparent\fR,
        ClientData \fIinstanceData\fR);
.CE
The \fItkwin\fR and \fIinstanceData\fR parameters will be identical to
the \fItkwin\fR and \fIinstanceData\fR parameters passed to
\fBTk_SetClassProcs\fR.  The \fIparent\fR parameter will be the parent
of the window to be created.  The \fIcreateProc\fR should return the
created window.
.PP
\fImodalProc\fR is invoked after all bindings on a widget have been
triggered in order to handle a modal loop.  \fImodalProc\fR should
have arguments and results that match the type \fBTk_ClassModalProc\fR:
.CS
typedef void \fBTk_ClassModalProc\fR(
        Tk_Window \fItkwin\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fItkwin\fR parameter to \fImodalProc\fR will be identical to the
\fItkwin\fR parameter passed to \fBTk_SetClassProcs\fR.  The
\fIeventPtr\fR parameter will be a pointer to an XEvent structure
describing the event being processed.

.SH KEYWORDS
callback, class





|














|






>








|



|











|
|





|



|
|
|
|











|
|
|





>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
'\"
'\" 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.
'\" 
.TH Tk_SetClassProcs 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetClassProcs \- register widget specific procedures
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClassProcs\fR(\fItkwin, procs, instanceData\fR)
.SH ARGUMENTS
.AS Tk_ClassProc instanceData
.AP Tk_Window tkwin in
Token for window to modify.
.AP Tk_ClassProcs *procs in
Pointer to data structure containing widget specific procedures.
The data structure pointed to by \fIprocs\fR must be static:
Tk keeps a reference to it as long as the window exists.
.AP ClientData instanceData in
Arbitrary one-word value to pass to widget callbacks.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetClassProcs\fR is called to register a set of procedures that
are used as callbacks in different places.
.PP
The structure pointed to by \fIprocs\fR contains the following:
.CS
typedef struct Tk_ClassProcs {
    unsigned int \fIsize\fR;
    Tk_ClassWorldChangedProc *\fIworldChangedProc\fR;
    Tk_ClassCreateProc *\fIcreateProc\fR;
    Tk_ClassModalProc *\fImodalProc\fR;
} Tk_ClassProcs;
.CE
The \fIsize\fR field is used to simplify future expansion of the
structure. It should always be set to (literally) \fBsizeof(Tk_ClassProcs)\fR.
.PP
\fIworldChangedProc\fR is invoked when the system has altered
in some way that requires some reaction from the widget.  For example,
when a font alias (see the \fBfont\fR manual entry) is reconfigured,
widgets configured to use that font alias must update their display
accordingly.  \fIworldChangedProc\fR should have arguments and results
that match the type \fBTk_ClassWorldChangedProc\fR:
.CS
typedef void Tk_ClassWorldChangedProc(
    ClientData \fIinstanceData\fR);
.CE
The \fIinstanceData\fR parameter passed to the \fIworldChangedProc\fR
will be identical to the \fIinstanceData\fR parameter passed to
\fBTk_SetClassProcs\fR.
.PP
\fIcreateProc\fR is used to create platform-dependant windows.  It is
invoked by \fBTk_MakeWindowExist\fR.  \fIcreateProc\fR should have
arguments and results that match the type \fBTk_ClassCreateProc\fR:
.CS
typedef Window Tk_ClassCreateProc(
    Tk_Window \fItkwin\fR,
    Window \fIparent\fR,
    ClientData \fIinstanceData\fR);
.CE
The \fItkwin\fR and \fIinstanceData\fR parameters will be identical to
the \fItkwin\fR and \fIinstanceData\fR parameters passed to
\fBTk_SetClassProcs\fR.  The \fIparent\fR parameter will be the parent
of the window to be created.  The \fIcreateProc\fR should return the
created window.
.PP
\fImodalProc\fR is invoked after all bindings on a widget have been
triggered in order to handle a modal loop.  \fImodalProc\fR should
have arguments and results that match the type \fBTk_ClassModalProc\fR:
.CS
typedef void Tk_ClassModalProc(
    Tk_Window \fItkwin\fR,
    XEvent *\fIeventPtr\fR);
.CE
The \fItkwin\fR parameter to \fImodalProc\fR will be identical to the
\fItkwin\fR parameter passed to \fBTk_SetClassProcs\fR.  The
\fIeventPtr\fR parameter will be a pointer to an XEvent structure
describing the event being processed.

.SH KEYWORDS
callback, class

Changes to doc/SetGrid.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_SetGrid 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetGrid, Tk_UnsetGrid \- control the grid for interactive resizing
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_SetGrid 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetGrid, Tk_UnsetGrid \- control the grid for interactive resizing
.SH SYNOPSIS
.nf
28
29
30
31
32
33
34

35
36
37
38
39
40
41
Height in grid units that corresponds to the pixel dimension \fItkwin\fR
has requested via \fBTk_GeometryRequest\fR.
.AP int widthInc in
Width of one grid unit, in pixels.
.AP int heightInc in
Height of one grid unit, in pixels.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetGrid\fR turns on gridded geometry management for \fItkwin\fR's
toplevel window and specifies the geometry of the grid.
\fBTk_SetGrid\fR is typically invoked by a widget when its \fBsetGrid\fR
option is true.
It restricts interactive resizing of \fItkwin\fR's toplevel window so







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Height in grid units that corresponds to the pixel dimension \fItkwin\fR
has requested via \fBTk_GeometryRequest\fR.
.AP int widthInc in
Width of one grid unit, in pixels.
.AP int heightInc in
Height of one grid unit, in pixels.
.BE

.SH DESCRIPTION
.PP
\fBTk_SetGrid\fR turns on gridded geometry management for \fItkwin\fR's
toplevel window and specifies the geometry of the grid.
\fBTk_SetGrid\fR is typically invoked by a widget when its \fBsetGrid\fR
option is true.
It restricts interactive resizing of \fItkwin\fR's toplevel window so
55
56
57
58
59
60
61

62
63
with gridding enabled.
If \fBTk_SetGrid\fR or \fBTk_UnsetGrid\fR is invoked when some
other window is already controlling gridding for \fItkwin\fR's
toplevel, the calls for the new window have no effect.
.PP
See the \fBwm\fR manual entry for additional information on gridded geometry
management.

.SH KEYWORDS
grid, window, window manager







>


56
57
58
59
60
61
62
63
64
65
with gridding enabled.
If \fBTk_SetGrid\fR or \fBTk_UnsetGrid\fR is invoked when some
other window is already controlling gridding for \fItkwin\fR's
toplevel, the calls for the new window have no effect.
.PP
See the \fBwm\fR manual entry for additional information on gridded geometry
management.

.SH KEYWORDS
grid, window, window manager

Changes to doc/SetOptions.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 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.
'\"
.TH Tk_SetOptions 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions \- process configuration options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_OptionTable
\fBTk_CreateOptionTable(\fIinterp, templatePtr\fB)\fR
.sp





|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 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.
'\" 
.TH Tk_SetOptions 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions, Tk_Offset \- process configuration options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_OptionTable
\fBTk_CreateOptionTable(\fIinterp, templatePtr\fB)\fR
.sp
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Tcl_Obj *
\fBTk_GetOptionValue(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
Tcl_Obj *
\fBTk_GetOptionInfo(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
\fBTk_FreeConfigOptions(\fIrecordPtr, optionTable, tkwin\fB)\fR



.SH ARGUMENTS
.AS Tk_SavedOptions "*const objv[]" in/out
.AP Tcl_Interp *interp in
A Tcl interpreter.  Most procedures use this only for returning error
messages; if it is NULL then no error messages are returned.  For
\fBTk_CreateOptionTable\fR the value cannot be NULL; it gives the
interpreter in which the option table will be used.
.AP "const Tk_OptionSpec" *templatePtr in
Points to an array of static information that describes the configuration
options that are supported.  Used to build a Tk_OptionTable.  The information
pointed to by this argument must exist for the lifetime of the Tk_OptionTable.
.AP Tk_OptionTable optionTable in
Token for an option table.  Must have been returned by a previous call
to \fBTk_CreateOptionTable\fR.
.AP void *recordPtr in/out
Points to structure in which values of configuration options are stored;
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
this argument.
.AP int objc in
Number of values in \fIobjv\fR.
.AP Tcl_Obj "*const *objv" in
Command-line arguments for setting configuring options.
.AP Tk_SavedOptions *savePtr out
If not NULL, the structure pointed to by this argument is filled
in with the old values of any options that were modified and old
values are restored automatically if an error occurs in \fBTk_SetOptions\fR.
.AP int *maskPtr out
If not NULL, the word pointed to by \fImaskPtr\fR is filled in with the







>
>
>














|










|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Tcl_Obj *
\fBTk_GetOptionValue(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
Tcl_Obj *
\fBTk_GetOptionInfo(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
\fBTk_FreeConfigOptions(\fIrecordPtr, optionTable, tkwin\fB)\fR
.sp
int
\fBTk_Offset(\fItype, field\fB)\fR
.SH ARGUMENTS
.AS Tk_SavedOptions "*const objv[]" in/out
.AP Tcl_Interp *interp in
A Tcl interpreter.  Most procedures use this only for returning error
messages; if it is NULL then no error messages are returned.  For
\fBTk_CreateOptionTable\fR the value cannot be NULL; it gives the
interpreter in which the option table will be used.
.AP "const Tk_OptionSpec" *templatePtr in
Points to an array of static information that describes the configuration
options that are supported.  Used to build a Tk_OptionTable.  The information
pointed to by this argument must exist for the lifetime of the Tk_OptionTable.
.AP Tk_OptionTable optionTable in
Token for an option table.  Must have been returned by a previous call
to \fBTk_CreateOptionTable\fR.
.AP char *recordPtr in/out
Points to structure in which values of configuration options are stored;
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
this argument.
.AP int objc in
Number of values in \fIobjv\fR.
.AP Tcl_Obj "*const objv[]" in
Command-line arguments for setting configuring options.
.AP Tk_SavedOptions *savePtr out
If not NULL, the structure pointed to by this argument is filled
in with the old values of any options that were modified and old
values are restored automatically if an error occurs in \fBTk_SetOptions\fR.
.AP int *maskPtr out
If not NULL, the word pointed to by \fImaskPtr\fR is filled in with the
232
233
234
235
236
237
238






239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
(e.g., because \fInamePtr\fR contains an unknown option name) then NULL
is returned and an error message is left in \fIinterp\fR's result unless
\fIinterp\fR is NULL.
.PP
\fBTk_FreeConfigOptions\fR must be invoked when a widget is deleted.
It frees all of the resources associated with any of the configuration
options defined in \fIrecordPtr\fR by \fIoptionTable\fR.






.SH "TEMPLATES"
.PP
The array of Tk_OptionSpec structures passed to \fBTk_CreateOptionTable\fR
via its \fItemplatePtr\fR argument describes the configuration options
supported by a particular class of widgets.  Each structure specifies
one configuration option and has the following fields:
.CS
typedef struct {
    Tk_OptionType \fItype\fR;
    const char *\fIoptionName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    size_t \fIobjOffset\fR;
    size_t \fIinternalOffset\fR;
    int \fIflags\fR;
    const void *\fIclientData\fR;
    int \fItypeMask\fR;
} \fBTk_OptionSpec\fR;
.CE
The \fItype\fR field indicates what kind of configuration option this is
(e.g. \fBTK_OPTION_COLOR\fR for a color value, or \fBTK_OPTION_INT\fR for
an integer value).  \fIType\fR determines how the
value of the option is parsed (more on this below).
The \fIoptionName\fR field is a string such as \fB\-font\fR or \fB\-bg\fR;
it is the name used for the option in Tcl commands and passed to
procedures via the \fIobjc\fR or \fInamePtr\fR arguments.
The \fIdbName\fR and \fIdbClass\fR fields are used by \fBTk_InitOptions\fR
to look up a default value for this option in the option database; if
\fIdbName\fR is NULL then the option database is not used by
\fBTk_InitOptions\fR for this option.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in the option database.  The \fIobjOffset\fR and
\fIinternalOffset\fR fields indicate where to store the value of this
option in widget records (more on this below); values for the \fIobjOffset\fR
and \fIinternalOffset\fR fields should always be generated with the
\fBoffsetof\fR macro.
The \fIflags\fR field contains additional information
to control the processing of this configuration option (see below
for details).
\fIClientData\fR provides additional type-specific data needed
by certain types.  For instance, for \fBTK_OPTION_COLOR\fR types,
\fIclientData\fR is a string giving the default value to use on
monochrome displays.  See the descriptions of the different types







>
>
>
>
>
>













|
|

|



















|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
(e.g., because \fInamePtr\fR contains an unknown option name) then NULL
is returned and an error message is left in \fIinterp\fR's result unless
\fIinterp\fR is NULL.
.PP
\fBTk_FreeConfigOptions\fR must be invoked when a widget is deleted.
It frees all of the resources associated with any of the configuration
options defined in \fIrecordPtr\fR by \fIoptionTable\fR.
.PP
The \fBTk_Offset\fR macro is provided as a safe way of generating the
\fIobjOffset\fR and \fIinternalOffset\fR values for entries in
Tk_OptionSpec structures.  It takes two arguments: the name of a type
of record, and the name of a field in that record. It returns the byte
offset of the named field in records of the given type.
.SH "TEMPLATES"
.PP
The array of Tk_OptionSpec structures passed to \fBTk_CreateOptionTable\fR
via its \fItemplatePtr\fR argument describes the configuration options
supported by a particular class of widgets.  Each structure specifies
one configuration option and has the following fields:
.CS
typedef struct {
    Tk_OptionType \fItype\fR;
    const char *\fIoptionName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    int \fIobjOffset\fR;
    int \fIinternalOffset\fR;
    int \fIflags\fR;
    ClientData \fIclientData\fR;
    int \fItypeMask\fR;
} \fBTk_OptionSpec\fR;
.CE
The \fItype\fR field indicates what kind of configuration option this is
(e.g. \fBTK_OPTION_COLOR\fR for a color value, or \fBTK_OPTION_INT\fR for
an integer value).  \fIType\fR determines how the
value of the option is parsed (more on this below).
The \fIoptionName\fR field is a string such as \fB\-font\fR or \fB\-bg\fR;
it is the name used for the option in Tcl commands and passed to
procedures via the \fIobjc\fR or \fInamePtr\fR arguments.
The \fIdbName\fR and \fIdbClass\fR fields are used by \fBTk_InitOptions\fR
to look up a default value for this option in the option database; if
\fIdbName\fR is NULL then the option database is not used by
\fBTk_InitOptions\fR for this option.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in the option database.  The \fIobjOffset\fR and
\fIinternalOffset\fR fields indicate where to store the value of this
option in widget records (more on this below); values for the \fIobjOffset\fR
and \fIinternalOffset\fR fields should always be generated with the
\fBTk_Offset\fR macro.
The \fIflags\fR field contains additional information
to control the processing of this configuration option (see below
for details).
\fIClientData\fR provides additional type-specific data needed
by certain types.  For instance, for \fBTK_OPTION_COLOR\fR types,
\fIclientData\fR is a string giving the default value to use on
monochrome displays.  See the descriptions of the different types
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
.TP
\fBTK_OPTION_STRING_TABLE\fR
For this type, \fIclientData\fR is a pointer to an array of strings
suitable for passing to \fBTcl_GetIndexFromObj\fR.  The value must
be one of the strings in the table, or a unique abbreviation of
one of the strings.  The internal form is an integer giving the index
into the table of the matching string, like the return value
from \fBTcl_GetStringFromObj\fR.  This option type supports the
\fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the internal
representation is set to -1.
.TP
\fBTK_OPTION_SYNONYM\fR
This type is used to provide alternative names for an option (for
example, \fB\-bg\fR is often used as a synonym for \fB\-background\fR).
The \fBclientData\fR field is a string that gives the name of another
option in the same table.  Whenever the synonym option is used, the
information from the other option will be used instead.







|
<
<







439
440
441
442
443
444
445
446


447
448
449
450
451
452
453
.TP
\fBTK_OPTION_STRING_TABLE\fR
For this type, \fIclientData\fR is a pointer to an array of strings
suitable for passing to \fBTcl_GetIndexFromObj\fR.  The value must
be one of the strings in the table, or a unique abbreviation of
one of the strings.  The internal form is an integer giving the index
into the table of the matching string, like the return value
from \fBTcl_GetStringFromObj\fR.


.TP
\fBTK_OPTION_SYNONYM\fR
This type is used to provide alternative names for an option (for
example, \fB\-bg\fR is often used as a synonym for \fB\-background\fR).
The \fBclientData\fR field is a string that gives the name of another
option in the same table.  Whenever the synonym option is used, the
information from the other option will be used instead.

Changes to doc/SetVisual.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_SetWindowVisual 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetWindowVisual \- change visual characteristics of window
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_SetWindowVisual 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_SetWindowVisual \- change visual characteristics of window
.SH SYNOPSIS
.nf
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
New visual type to use for \fItkwin\fR.
.AP "int" depth in
Number of bits per pixel desired for \fItkwin\fR.
.AP Colormap colormap in
New colormap for \fItkwin\fR, which must be compatible with
\fIvisual\fR and \fIdepth\fR.
.BE

.SH DESCRIPTION
.PP
When Tk creates a new window it assigns it the default visual
characteristics (visual, depth, and colormap) for its screen.
\fBTk_SetWindowVisual\fR may be called to change them.
\fBTk_SetWindowVisual\fR must be called before the window has
actually been created in X (e.g. before \fBTk_MapWindow\fR or
\fBTk_MakeWindowExist\fR has been invoked for the window).
The safest thing is to call \fBTk_SetWindowVisual\fR immediately
after calling \fBTk_CreateWindow\fR.
If \fItkwin\fR has already been created before \fBTk_SetWindowVisual\fR
is called then it returns 0 and does not make any changes;  otherwise
it returns 1 to signify that the operation
completed successfully.
.PP
Note:  \fBTk_SetWindowVisual\fR should not be called if you just want
to change a window's colormap without changing its visual or depth;
call \fBTk_SetWindowColormap\fR instead.

.SH KEYWORDS
colormap, depth, visual







>


















>


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
New visual type to use for \fItkwin\fR.
.AP "int" depth in
Number of bits per pixel desired for \fItkwin\fR.
.AP Colormap colormap in
New colormap for \fItkwin\fR, which must be compatible with
\fIvisual\fR and \fIdepth\fR.
.BE

.SH DESCRIPTION
.PP
When Tk creates a new window it assigns it the default visual
characteristics (visual, depth, and colormap) for its screen.
\fBTk_SetWindowVisual\fR may be called to change them.
\fBTk_SetWindowVisual\fR must be called before the window has
actually been created in X (e.g. before \fBTk_MapWindow\fR or
\fBTk_MakeWindowExist\fR has been invoked for the window).
The safest thing is to call \fBTk_SetWindowVisual\fR immediately
after calling \fBTk_CreateWindow\fR.
If \fItkwin\fR has already been created before \fBTk_SetWindowVisual\fR
is called then it returns 0 and does not make any changes;  otherwise
it returns 1 to signify that the operation
completed successfully.
.PP
Note:  \fBTk_SetWindowVisual\fR should not be called if you just want
to change a window's colormap without changing its visual or depth;
call \fBTk_SetWindowColormap\fR instead.

.SH KEYWORDS
colormap, depth, visual

Changes to doc/StrictMotif.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
'\"
'\" 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.
'\"
.TH Tk_StrictMotif 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_StrictMotif \- Return value of tk_strictMotif variable
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_StrictMotif\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
This procedure returns the current value of the \fBtk_strictMotif\fR
variable in the interpreter associated with \fItkwin\fR's application.
The value is returned as an integer that is either 0 or 1.
1 means that strict Motif compliance has been requested, so anything
that is not part of the Motif specification should be avoided.
0 means that
.QW Motif-like
is good enough, and extra features are welcome.
.PP
This procedure uses a link to the Tcl variable to provide much
faster access to the variable's value than could be had by calling
\fBTcl_GetVar\fR.

.SH KEYWORDS
Motif compliance, tk_strictMotif variable





|
















>














>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'\"
'\" 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.
'\" 
.TH Tk_StrictMotif 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_StrictMotif \- Return value of tk_strictMotif variable
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_StrictMotif\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
This procedure returns the current value of the \fBtk_strictMotif\fR
variable in the interpreter associated with \fItkwin\fR's application.
The value is returned as an integer that is either 0 or 1.
1 means that strict Motif compliance has been requested, so anything
that is not part of the Motif specification should be avoided.
0 means that
.QW Motif-like
is good enough, and extra features are welcome.
.PP
This procedure uses a link to the Tcl variable to provide much
faster access to the variable's value than could be had by calling
\fBTcl_GetVar\fR.

.SH KEYWORDS
Motif compliance, tk_strictMotif variable

Changes to doc/TextLayout.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Tk_ComputeTextLayout 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ComputeTextLayout, Tk_FreeTextLayout, Tk_DrawTextLayout, Tk_UnderlineTextLayout, Tk_PointToChar, Tk_CharBbox, Tk_DistanceToTextLayout, Tk_IntersectTextLayout, Tk_TextLayoutToPostscript \- routines to measure and display single-font, multi-line, justified text.
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Tk_ComputeTextLayout 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_ComputeTextLayout, Tk_FreeTextLayout, Tk_DrawTextLayout, Tk_UnderlineTextLayout, Tk_PointToChar, Tk_CharBbox, Tk_DistanceToTextLayout, Tk_IntersectTextLayout, Tk_TextLayoutToPostscript \- routines to measure and display single-font, multi-line, justified text.
.SH SYNOPSIS
.nf
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
\fBTk_DistanceToTextLayout(\fIlayout, x, y\fB)\fR
.sp
int
\fBTk_IntersectTextLayout(\fIlayout, x, y, width, height\fB)\fR
.sp
void
\fBTk_TextLayoutToPostscript(\fIinterp, layout\fB)\fR

.SH ARGUMENTS
.AS Tk_TextLayout "*xPtr, *yPtr"
.AP Tk_Font tkfont in
Font to use when constructing and displaying a text layout.  The
\fItkfont\fR must remain valid for the lifetime of the text layout.  Must
have been returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Potentially multi-line string whose dimensions are to be computed and
stored in the text layout.  The \fIstring\fR must remain valid for the
lifetime of the text layout.
.AP int numChars in
The number of characters to consider from \fIstring\fR.  If
\fInumChars\fR is less than 0, then assumes \fIstring\fR is null
terminated and uses \fBTcl_NumUtfChars\fR to determine the length of
\fIstring\fR.
.AP int wrapLength in
Longest permissible line length, in pixels.  Lines in \fIstring\fR will







>









|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
\fBTk_DistanceToTextLayout(\fIlayout, x, y\fB)\fR
.sp
int
\fBTk_IntersectTextLayout(\fIlayout, x, y, width, height\fB)\fR
.sp
void
\fBTk_TextLayoutToPostscript(\fIinterp, layout\fB)\fR

.SH ARGUMENTS
.AS Tk_TextLayout "*xPtr, *yPtr"
.AP Tk_Font tkfont in
Font to use when constructing and displaying a text layout.  The
\fItkfont\fR must remain valid for the lifetime of the text layout.  Must
have been returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Potentially multi-line string whose dimensions are to be computed and
stored in the text layout.  The \fIstring\fR must remain valid for the
lifetime of the text layout.  
.AP int numChars in
The number of characters to consider from \fIstring\fR.  If
\fInumChars\fR is less than 0, then assumes \fIstring\fR is null
terminated and uses \fBTcl_NumUtfChars\fR to determine the length of
\fIstring\fR.
.AP int wrapLength in
Longest permissible line length, in pixels.  Lines in \fIstring\fR will
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
\fBTK_IGNORE_NEWLINES\fR means that newline/return characters should
not cause a line break.  If either tabs or newlines/returns are
ignored, then they will be treated as regular characters, being
measured and displayed in a platform-dependent manner as described in
\fBTk_MeasureChars\fR, and will not have any special behaviors.
.AP int *widthPtr out
If non-NULL, filled with either the width, in pixels, of the widest
line in the text layout, or the width, in pixels, of the bounding box for the
character specified by \fIindex\fR.
.AP int *heightPtr out
If non-NULL, filled with either the total height, in pixels, of all
the lines in the text layout, or the height, in pixels, of the bounding
box for the character specified by \fIindex\fR.
.AP Tk_TextLayout layout in
A token that represents the cached layout information about the single-font,







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
\fBTK_IGNORE_NEWLINES\fR means that newline/return characters should
not cause a line break.  If either tabs or newlines/returns are
ignored, then they will be treated as regular characters, being
measured and displayed in a platform-dependent manner as described in
\fBTk_MeasureChars\fR, and will not have any special behaviors.
.AP int *widthPtr out
If non-NULL, filled with either the width, in pixels, of the widest
line in the text layout, or the width, in pixels, of the bounding box for the 
character specified by \fIindex\fR.
.AP int *heightPtr out
If non-NULL, filled with either the total height, in pixels, of all
the lines in the text layout, or the height, in pixels, of the bounding
box for the character specified by \fIindex\fR.
.AP Tk_TextLayout layout in
A token that represents the cached layout information about the single-font,
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
text layout.
.AP int "x, y" in
Point, in pixels, at which to place the upper-left hand corner of the
text layout when it is being drawn, or the coordinates of a point (with
respect to the upper-left hand corner of the text layout) to check
against the text layout.
.AP int firstChar in
The index of the first character to draw from the given text layout.
The number 0 means to draw from the beginning.
.AP int lastChar in
The index of the last character up to which to draw.  The character
specified by \fIlastChar\fR itself will not be drawn.  A number less
than 0 means to draw all characters in the text layout.
.AP int underline in
Index of the single character to underline in the text layout, or a number
less than 0 for no underline.
.AP int index in
The index of the character whose bounding box is desired.  The bounding
box is computed with respect to the upper-left hand corner of the text layout.
.AP int "*xPtr, *yPtr" out
Filled with the upper-left hand corner, in pixels, of the bounding box
for the character specified by \fIindex\fR.  Either or both \fIxPtr\fR
and \fIyPtr\fR may be NULL, in which case the corresponding value
is not calculated.
.AP int "width, height" in
Specifies the width and height, in pixels, of the rectangular area to
compare for intersection against the text layout.
.AP Tcl_Interp *interp out
Postscript code that will print the text layout is appended to
the result of interpreter \fIinterp\fR.
.BE

.SH DESCRIPTION
.PP
These routines are for measuring and displaying single-font, multi-line,
justified text.  To measure and display simple single-font, single-line
strings, refer to the documentation for \fBTk_MeasureChars\fR.  There is
no programming interface in the core of Tk that supports multi-font,
multi-line text; support for that behavior must be built on top of
simpler layers.
Note that unlike the lower level text display routines, the functions
described here all operate on character-oriented lengths and indices
rather than byte-oriented values.  See the description of
\fBTcl_UtfAtIndex\fR for more details on converting between character
and byte offsets.
.PP
The routines described here are built on top of the programming interface
described in the \fBTk_MeasureChars\fR documentation.  Tab characters and
newline/return characters may be treated specially by these procedures,
but all other characters are passed through to the lower level.
.PP
\fBTk_ComputeTextLayout\fR computes the layout information needed to
display a single-font, multi-line, justified \fIstring\fR of text and
returns a Tk_TextLayout token that holds this information.  This token is
used in subsequent calls to procedures such as \fBTk_DrawTextLayout\fR,
\fBTk_DistanceToTextLayout\fR, and \fBTk_FreeTextLayout\fR.  The
\fIstring\fR and \fItkfont\fR used when computing the layout must remain
valid for the lifetime of this token.
.PP
\fBTk_FreeTextLayout\fR is called to release the storage associated with
\fIlayout\fR when it is no longer needed.  A \fIlayout\fR should not be used
in any other text layout procedures once it has been released.
.PP
\fBTk_DrawTextLayout\fR uses the information in \fIlayout\fR to display a
single-font, multi-line, justified string of text at the specified location.
.PP
\fBTk_UnderlineTextLayout\fR uses the information in \fIlayout\fR to
display an underline below an individual character.  This procedure does
not draw the text, just the underline.  To produce natively underlined







|

















|



|

>







|

















|



|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
text layout.
.AP int "x, y" in
Point, in pixels, at which to place the upper-left hand corner of the
text layout when it is being drawn, or the coordinates of a point (with
respect to the upper-left hand corner of the text layout) to check
against the text layout.
.AP int firstChar in
The index of the first character to draw from the given text layout.  
The number 0 means to draw from the beginning.
.AP int lastChar in
The index of the last character up to which to draw.  The character
specified by \fIlastChar\fR itself will not be drawn.  A number less
than 0 means to draw all characters in the text layout.
.AP int underline in
Index of the single character to underline in the text layout, or a number
less than 0 for no underline.
.AP int index in
The index of the character whose bounding box is desired.  The bounding
box is computed with respect to the upper-left hand corner of the text layout.
.AP int "*xPtr, *yPtr" out
Filled with the upper-left hand corner, in pixels, of the bounding box
for the character specified by \fIindex\fR.  Either or both \fIxPtr\fR
and \fIyPtr\fR may be NULL, in which case the corresponding value
is not calculated.
.AP int "width, height" in
Specifies the width and height, in pixels, of the rectangular area to 
compare for intersection against the text layout.
.AP Tcl_Interp *interp out
Postscript code that will print the text layout is appended to
\fIinterp->result\fR.
.BE

.SH DESCRIPTION
.PP
These routines are for measuring and displaying single-font, multi-line,
justified text.  To measure and display simple single-font, single-line
strings, refer to the documentation for \fBTk_MeasureChars\fR.  There is
no programming interface in the core of Tk that supports multi-font,
multi-line text; support for that behavior must be built on top of
simpler layers.  
Note that unlike the lower level text display routines, the functions
described here all operate on character-oriented lengths and indices
rather than byte-oriented values.  See the description of
\fBTcl_UtfAtIndex\fR for more details on converting between character
and byte offsets.
.PP
The routines described here are built on top of the programming interface
described in the \fBTk_MeasureChars\fR documentation.  Tab characters and
newline/return characters may be treated specially by these procedures,
but all other characters are passed through to the lower level.
.PP
\fBTk_ComputeTextLayout\fR computes the layout information needed to
display a single-font, multi-line, justified \fIstring\fR of text and
returns a Tk_TextLayout token that holds this information.  This token is
used in subsequent calls to procedures such as \fBTk_DrawTextLayout\fR,
\fBTk_DistanceToTextLayout\fR, and \fBTk_FreeTextLayout\fR.  The
\fIstring\fR and \fItkfont\fR used when computing the layout must remain
valid for the lifetime of this token.  
.PP
\fBTk_FreeTextLayout\fR is called to release the storage associated with
\fIlayout\fR when it is no longer needed.  A \fIlayout\fR should not be used
in any other text layout procedures once it has been released. 
.PP
\fBTk_DrawTextLayout\fR uses the information in \fIlayout\fR to display a
single-font, multi-line, justified string of text at the specified location.
.PP
\fBTk_UnderlineTextLayout\fR uses the information in \fIlayout\fR to
display an underline below an individual character.  This procedure does
not draw the text, just the underline.  To produce natively underlined
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
considered closest to the first character in the text layout; any point
whose \fIy\fR-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 \fIx\fR-value is less than 0 will be considered closest to the first
character on that line; any point whose \fIx\fR-value is greater than the
width of the text layout will be considered closest to the last character on
that line.  The return value is the index of the character that was closest
to the point, or one more than the index of any character (to indicate that
the point was after the end of the string and that the corresponding caret
would be at the end of the string).  Given a \fIlayout\fR with no characters,
the value 0 will always be returned, referring to a hypothetical zero-width
placeholder character.
.PP
\fBTk_CharBbox\fR uses the information in \fIlayout\fR to return the
bounding box for the character specified by \fIindex\fR.  The width of the
bounding box is the advance width of the character, and does not include any
left or right bearing.  Any character that extends partially outside of
\fIlayout\fR is considered to be truncated at the edge.  Any character
that would be located completely outside of \fIlayout\fR 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 individual letters is not available.  For measurement purposes, a
\fIlayout\fR that contains no characters is considered to contain a







<
<
|
|
|




|







180
181
182
183
184
185
186


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
considered closest to the first character in the text layout; any point
whose \fIy\fR-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 \fIx\fR-value is less than 0 will be considered closest to the first
character on that line; any point whose \fIx\fR-value is greater than the
width of the text layout will be considered closest to the last character on
that line.  The return value is the index of the character that was closest


to the point.  Given a \fIlayout\fR with no characters, the value 0 will
always be returned, referring to a hypothetical zero-width placeholder
character.  
.PP
\fBTk_CharBbox\fR uses the information in \fIlayout\fR to return the
bounding box for the character specified by \fIindex\fR.  The width of the
bounding box is the advance width of the character, and does not include any
left or right bearing.  Any character that extends partially outside of 
\fIlayout\fR is considered to be truncated at the edge.  Any character
that would be located completely outside of \fIlayout\fR 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 individual letters is not available.  For measurement purposes, a
\fIlayout\fR that contains no characters is considered to contain a
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
entirely inside of the rectangle.
.PP
\fBTk_TextLayoutToPostscript\fR outputs code consisting of a Postscript
array of strings that represent the individual lines in \fIlayout\fR.  It
is the responsibility of the caller to take the Postscript array of
strings and add some Postscript function operate on the array to render
each of the lines.  The code that represents the Postscript array of
strings is appended to interpreter \fIinterp\fR's result.
.SH "DISPLAY MODEL"
.PP
When measuring a text layout, space characters that occur at the end of a
line are ignored.  The space characters still exist and the insertion point
can be positioned amongst them, but their additional width is ignored when
justifying lines or returning the total width of a text layout.  All
end-of-line space characters are considered to be attached to the right edge
of the line; this behavior is logical for left-justified text and reasonable
for center-justified text, but not very useful when editing right-justified







|

<







227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
entirely inside of the rectangle.
.PP
\fBTk_TextLayoutToPostscript\fR outputs code consisting of a Postscript
array of strings that represent the individual lines in \fIlayout\fR.  It
is the responsibility of the caller to take the Postscript array of
strings and add some Postscript function operate on the array to render
each of the lines.  The code that represents the Postscript array of
strings is appended to \fIinterp->result\fR.
.SH "DISPLAY MODEL"

When measuring a text layout, space characters that occur at the end of a
line are ignored.  The space characters still exist and the insertion point
can be positioned amongst them, but their additional width is ignored when
justifying lines or returning the total width of a text layout.  All
end-of-line space characters are considered to be attached to the right edge
of the line; this behavior is logical for left-justified text and reasonable
for center-justified text, but not very useful when editing right-justified
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
of a word is not considered a word break.  \fBTk_ComputeTextLayout\fR
always attempts to place at least one word on each line.  If it cannot
because the \fIwrapLength\fR is too small, the word will be broken and as
much as fits placed on the line and the rest on subsequent line(s).  If
\fIwrapLength\fR is so small that not even one character can fit on a
given line, the \fIwrapLength\fR is ignored for that line and one
character will be placed on the line anyhow.  When wrapping is turned
off, only newline/return characters may cause a line break.
.PP
When a text layout has been created using an underlined \fItkfont\fR,
then any space characters that occur at the end of individual lines,
newlines/returns, and tabs will not be displayed underlined when
\fBTk_DrawTextLayout\fR is called, because those characters are never
actually drawn \- they are merely placeholders maintained in the
\fIlayout\fR.
.SH KEYWORDS
font







|



|


|


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
of a word is not considered a word break.  \fBTk_ComputeTextLayout\fR
always attempts to place at least one word on each line.  If it cannot
because the \fIwrapLength\fR is too small, the word will be broken and as
much as fits placed on the line and the rest on subsequent line(s).  If
\fIwrapLength\fR is so small that not even one character can fit on a
given line, the \fIwrapLength\fR is ignored for that line and one
character will be placed on the line anyhow.  When wrapping is turned
off, only newline/return characters may cause a line break.  
.PP
When a text layout has been created using an underlined \fItkfont\fR,
then any space characters that occur at the end of individual lines,
newlines/returns, and tabs will not be displayed underlined when 
\fBTk_DrawTextLayout\fR is called, because those characters are never
actually drawn \- they are merely placeholders maintained in the
\fIlayout\fR.  
.SH KEYWORDS
font

Changes to doc/TkInitStubs.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1999 Scriptics Corporation
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_InitStubs 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InitStubs \- initialize the Tk stubs mechanism
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1999 Scriptics Corporation
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH Tk_InitStubs 3 8.4 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_InitStubs \- initialize the Tk stubs mechanism
.SH SYNOPSIS
.nf
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
as \fIversion\fR.
.BE
.SH INTRODUCTION
.PP
The Tcl stubs mechanism defines a way to dynamically bind
extensions to a particular Tcl implementation at run time.
the stubs mechanism requires no changes to applications
incorporating Tcl/Tk interpreters.  Only developers creating
C-based Tcl/Tk extensions need to take steps to use the
stubs mechanism with their extensions.
See the \fBTcl_InitStubs\fR page for more information.
.PP
Enabling the stubs mechanism for a Tcl/Tk extension requires the following
steps:
.IP 1) 5
Call \fBTcl_InitStubs\fR in the extension before calling any other
Tcl functions.
.IP 2) 5
Call \fBTk_InitStubs\fR if the extension before calling any other
Tk functions.
.IP 2) 5
Define the \fBUSE_TCL_STUBS\fR and the \fBUSE_TK_STUBS\fR
symbols. Typically, you would include the \fB\-DUSE_TCL_STUBS\fR and
the \fB\-DUSE_TK_STUBS\fR flags when compiling the extension.
.IP 3) 5
Link the extension with the Tcl and Tk stubs libraries instead of the
standard Tcl and Tk libraries.  On Unix platforms, the library names
are \fIlibtclstub8.4.a\fR and \fIlibtkstub8.4.a\fR; on Windows
platforms, the library names are \fItclstub84.lib\fR and
\fItkstub84.lib\fR. Adjust the library names with appropriate version
number but note that the extension may only be used with versions of
Tcl/Tk that have that version number or higher.
.SH DESCRIPTION
.PP
\fBTk_InitStubs\fR attempts to initialize the Tk stub table pointers
and ensure that the correct version of Tk is loaded.  In addition
to an interpreter handle, it accepts as arguments a version number
and a Boolean flag indicating whether the extension requires
an exact version match or not.  If \fIexact\fR is 0, then the
extension is indicating that newer versions of Tk are acceptable
as long as they have the same major version number as \fIversion\fR;







|













|
<
|

|
|
|
|
|
<
<

<







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58


59

60
61
62
63
64
65
66
as \fIversion\fR.
.BE
.SH INTRODUCTION
.PP
The Tcl stubs mechanism defines a way to dynamically bind
extensions to a particular Tcl implementation at run time.
the stubs mechanism requires no changes to applications
incoporating Tcl/Tk interpreters.  Only developers creating
C-based Tcl/Tk extensions need to take steps to use the
stubs mechanism with their extensions.
See the \fBTcl_InitStubs\fR page for more information.
.PP
Enabling the stubs mechanism for a Tcl/Tk extension requires the following
steps:
.IP 1) 5
Call \fBTcl_InitStubs\fR in the extension before calling any other
Tcl functions.
.IP 2) 5
Call \fBTk_InitStubs\fR if the extension before calling any other
Tk functions.
.IP 2) 5
Define the \fBUSE_TCL_STUBS\fR symbol. Typically, you would include the

\fB\-DUSE_TCL_STUBS\fR flag when compiling the extension.
.IP 3) 5
Link the extension with the Tcl and Tk stubs libraries instead of
the standard Tcl and Tk libraries.  On Unix platforms, the library
names are \fIlibtclstub8.4.a\fR and \fIlibtkstub8.4.a\fR; on Windows
platforms, the library names are \fItclstub84.lib\fR and \fItkstub84.lib\fR
(adjust names with appropriate version number).


.SH DESCRIPTION

\fBTk_InitStubs\fR attempts to initialize the Tk stub table pointers
and ensure that the correct version of Tk is loaded.  In addition
to an interpreter handle, it accepts as arguments a version number
and a Boolean flag indicating whether the extension requires
an exact version match or not.  If \fIexact\fR is 0, then the
extension is indicating that newer versions of Tk are acceptable
as long as they have the same major version number as \fIversion\fR;

Changes to doc/Tk_Init.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
'\"
'\" 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.
'\"
.TH Tk_Init 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Init, Tk_SafeInit \- add Tk to an interpreter and make a new Tk application.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Init\fR(\fIinterp\fR)
.sp
int
\fBTk_SafeInit\fR(\fIinterp\fR)
.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter in which to load Tk.  Tk should not already be loaded
in this interpreter.
.BE

.SH DESCRIPTION
.PP
\fBTk_Init\fR is the package initialization procedure for Tk.
It is normally invoked by the \fBTcl_AppInit\fR procedure
for an application or by the \fBload\fR command.
\fBTk_Init\fR adds all of Tk's commands to \fIinterp\fR
and creates a new Tk application, including its main window.
If the initialization is successful \fBTk_Init\fR returns
\fBTCL_OK\fR;  if there is an error it returns \fBTCL_ERROR\fR.
\fBTk_Init\fR also leaves a result or error message
in interpreter \fIinterp\fR's result.
.PP
If there is a variable \fBargv\fR in \fIinterp\fR, \fBTk_Init\fR
treats the contents of this variable as a list of options for the
new Tk application.
The options may have any of the forms documented for the
\fBwish\fR application (in fact, \fBwish\fR uses Tk_Init to process
its command-line arguments).





|



















>










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
'\"
'\" 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.
'\" 
.TH Tk_Init 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Init, Tk_SafeInit \- add Tk to an interpreter and make a new Tk application.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Init\fR(\fIinterp\fR)
.sp
int
\fBTk_SafeInit\fR(\fIinterp\fR)
.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter in which to load Tk.  Tk should not already be loaded
in this interpreter.
.BE

.SH DESCRIPTION
.PP
\fBTk_Init\fR is the package initialization procedure for Tk.
It is normally invoked by the \fBTcl_AppInit\fR procedure
for an application or by the \fBload\fR command.
\fBTk_Init\fR adds all of Tk's commands to \fIinterp\fR
and creates a new Tk application, including its main window.
If the initialization is successful \fBTk_Init\fR returns
\fBTCL_OK\fR;  if there is an error it returns \fBTCL_ERROR\fR.
\fBTk_Init\fR also leaves a result or error message
in \fIinterp->result\fR.
.PP
If there is a variable \fBargv\fR in \fIinterp\fR, \fBTk_Init\fR
treats the contents of this variable as a list of options for the
new Tk application.
The options may have any of the forms documented for the
\fBwish\fR application (in fact, \fBwish\fR uses Tk_Init to process
its command-line arguments).
77
78
79
80
81
82
83

84
85
\fBtoplevel\fR
Toplevels can be used to cover the entire screen and to steal input
from the user.
.TP
\fBwm\fR
If toplevels are ever allowed, wm can be used to remove decorations,
move windows around, etc.

.SH KEYWORDS
safe, application, initialization, load, main window







>


78
79
80
81
82
83
84
85
86
87
\fBtoplevel\fR
Toplevels can be used to cover the entire screen and to steal input
from the user.
.TP
\fBwm\fR
If toplevels are ever allowed, wm can be used to remove decorations,
move windows around, etc.

.SH KEYWORDS
safe, application, initialization, load, main window

Changes to doc/Tk_Main.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH Tk_Main 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Main \- main program for Tk-based applications
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_Main\fR(\fIargc, argv, appInitProc\fR)
.SH ARGUMENTS
.AS Tcl_AppInitProc *appInitProc
.AP int argc in
Number of elements in \fIargv\fR.
.AP char *argv[] in
Array of strings containing command-line arguments. On Windows, when
using -DUNICODE, the parameter type changes to wchar_t *.
.AP Tcl_AppInitProc *appInitProc in
Address of an application-specific initialization procedure.
The value for this argument is usually \fBTcl_AppInit\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_Main\fR acts as the main program for most Tk-based applications.
Starting with Tk 4.0 it is not called \fBmain\fR anymore because it
is part of the Tk library and having a function \fBmain\fR
in a library (particularly a shared library) causes problems on many
systems.
Having \fBmain\fR in the Tk library would also make it hard to use
Tk in C++ programs, since C++ programs must have special C++
\fBmain\fR functions.
.PP
Normally each application contains a small \fBmain\fR function that does
nothing but invoke \fBTk_Main\fR.
\fBTk_Main\fR then does all the work of creating and running a
\fBwish\fR-like application.
.PP
When it is has finished its own initialization, but before
it processes commands, \fBTk_Main\fR calls the procedure given by
the \fIappInitProc\fR argument.  This procedure provides a
.QW hook
for the application to perform its own initialization, such as defining
application-specific commands.  The procedure must have an interface
that matches the type \fBTcl_AppInitProc\fR:
.CS
typedef int \fBTcl_AppInitProc\fR(
        Tcl_Interp *\fIinterp\fR);
.CE
\fIAppInitProc\fR is almost always a pointer to \fBTcl_AppInit\fR;
for more details on this procedure, see the documentation
for \fBTcl_AppInit\fR.
.PP
\fBTk_Main\fR functions much the same as \fBTcl_Main\fR.  In particular,
\fBTk_Main\fR supports both an interactive mode and a startup script
mode, with the file name and encoding of a startup script under the
control of the \fBTcl_SetStartupScript\fR and \fBTcl_GetStartupScript\fR
routines. However it calls \fBTk_MainLoop\fR after processing any
supplied script, and in interactive uses events registered with
\fBTcl_CreateFileHandler\fR to process user input.
.SH "SEE ALSO"
Tcl_DoOneEvent(3)
.SH KEYWORDS
application-specific initialization, command-line arguments, main program






|















|
<




>



|




















<
|




|
<
<
<
<
<
<
<
<
<


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58









59
60
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH Tk_Main 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Main \- main program for Tk-based applications
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_Main\fR(\fIargc, argv, appInitProc\fR)
.SH ARGUMENTS
.AS Tcl_AppInitProc *appInitProc
.AP int argc in
Number of elements in \fIargv\fR.
.AP char *argv[] in
Array of strings containing command-line arguments.

.AP Tcl_AppInitProc *appInitProc in
Address of an application-specific initialization procedure.
The value for this argument is usually \fBTcl_AppInit\fR.
.BE

.SH DESCRIPTION
.PP
\fBTk_Main\fR acts as the main program for most Tk-based applications.
Starting with Tk 4.0 it is not called \fBmain\fR anymore because it 
is part of the Tk library and having a function \fBmain\fR
in a library (particularly a shared library) causes problems on many
systems.
Having \fBmain\fR in the Tk library would also make it hard to use
Tk in C++ programs, since C++ programs must have special C++
\fBmain\fR functions.
.PP
Normally each application contains a small \fBmain\fR function that does
nothing but invoke \fBTk_Main\fR.
\fBTk_Main\fR then does all the work of creating and running a
\fBwish\fR-like application.
.PP
When it is has finished its own initialization, but before
it processes commands, \fBTk_Main\fR calls the procedure given by
the \fIappInitProc\fR argument.  This procedure provides a
.QW hook
for the application to perform its own initialization, such as defining
application-specific commands.  The procedure must have an interface
that matches the type \fBTcl_AppInitProc\fR:
.CS

typedef int Tcl_AppInitProc(Tcl_Interp *\fIinterp\fR);
.CE
\fIAppInitProc\fR is almost always a pointer to \fBTcl_AppInit\fR;
for more details on this procedure, see the documentation
for \fBTcl_AppInit\fR.










.SH KEYWORDS
application-specific initialization, command-line arguments, main program

Changes to doc/WindowId.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'\"
'\" 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.
'\"
.TH Tk_WindowId 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_WindowId, Tk_Parent, Tk_Display, Tk_DisplayName, Tk_ScreenNumber, Tk_AlwaysShowSelection, Tk_Screen, Tk_X, Tk_Y, Tk_Width, Tk_Height, Tk_Changes, Tk_Attributes, Tk_IsContainer, Tk_IsEmbedded, Tk_IsMapped, Tk_IsTopLevel, Tk_ReqWidth, Tk_ReqHeight, Tk_MinReqWidth, Tk_MinReqHeight, Tk_InternalBorderLeft, Tk_InternalBorderRight, Tk_InternalBorderTop, Tk_InternalBorderBottom, Tk_Visual, Tk_Depth, Tk_Colormap, Tk_Interp, Tk_NewWindowObj  \- retrieve information from Tk's local data structure
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Window
\fBTk_WindowId\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_Parent\fR(\fItkwin\fR)
.sp
Display *
\fBTk_Display\fR(\fItkwin\fR)
.sp
const char *
\fBTk_DisplayName\fR(\fItkwin\fR)
.sp
int
\fBTk_ScreenNumber\fR(\fItkwin\fR)
.sp
int
\fBTk_AlwaysShowSelection\fR(\fItkwin\fR)
.sp
Screen *
\fBTk_Screen\fR(\fItkwin\fR)
.sp
int
\fBTk_X\fR(\fItkwin\fR)
.sp
int






|




|



















<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31



32
33
34
35
36
37
38
'\"
'\" 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.
'\" 
.TH Tk_WindowId 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_WindowId, Tk_Parent, Tk_Display, Tk_DisplayName, Tk_ScreenNumber, Tk_Screen, Tk_X, Tk_Y, Tk_Width, Tk_Height, Tk_Changes, Tk_Attributes, Tk_IsContainer, Tk_IsEmbedded, Tk_IsMapped, Tk_IsTopLevel, Tk_ReqWidth, Tk_ReqHeight, Tk_MinReqWidth, Tk_MinReqHeight, Tk_InternalBorderLeft, Tk_InternalBorderRight, Tk_InternalBorderTop, Tk_InternalBorderBottom, Tk_Visual, Tk_Depth, Tk_Colormap, Tk_Interp  \- retrieve information from Tk's local data structure
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Window
\fBTk_WindowId\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_Parent\fR(\fItkwin\fR)
.sp
Display *
\fBTk_Display\fR(\fItkwin\fR)
.sp
const char *
\fBTk_DisplayName\fR(\fItkwin\fR)
.sp
int
\fBTk_ScreenNumber\fR(\fItkwin\fR)
.sp



Screen *
\fBTk_Screen\fR(\fItkwin\fR)
.sp
int
\fBTk_X\fR(\fItkwin\fR)
.sp
int
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
\fBTk_Depth\fR(\fItkwin\fR)
.sp
Colormap
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)
.sp
Tcl_Obj *
\fBTk_NewWindowObj\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
\fBTk_WindowId\fR and the other names listed above are
all macros that return fields from Tk's local data structure
for \fItkwin\fR.  None of these macros requires any
interaction with the server;  it is safe to assume that
all are fast.







<
<
<





>







93
94
95
96
97
98
99



100
101
102
103
104
105
106
107
108
109
110
111
112
\fBTk_Depth\fR(\fItkwin\fR)
.sp
Colormap
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)



.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE

.SH DESCRIPTION
.PP
\fBTk_WindowId\fR and the other names listed above are
all macros that return fields from Tk's local data structure
for \fItkwin\fR.  None of these macros requires any
interaction with the server;  it is safe to assume that
all are fast.
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
.PP
\fBTk_Display\fR returns a pointer to the Xlib display structure
corresponding to \fItkwin\fR.  \fBTk_DisplayName\fR returns an
ASCII string identifying \fItkwin\fR's display.  \fBTk_ScreenNumber\fR
returns the index of \fItkwin\fR's screen among all the screens
of \fItkwin\fR's display.  \fBTk_Screen\fR returns a pointer to
the Xlib structure corresponding to \fItkwin\fR's screen.
\fBTk_AlwaysShowSelection\fR indicates whether text/entry widgets
should always display their selection, regardless of window focus.
.PP
\fBTk_X\fR, \fBTk_Y\fR, \fBTk_Width\fR, and \fBTk_Height\fR
return information about \fItkwin's\fR location within its
parent and its size.  The location information refers to the
upper-left pixel in the window, or its border if there is one.
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR







<
<







124
125
126
127
128
129
130


131
132
133
134
135
136
137
.PP
\fBTk_Display\fR returns a pointer to the Xlib display structure
corresponding to \fItkwin\fR.  \fBTk_DisplayName\fR returns an
ASCII string identifying \fItkwin\fR's display.  \fBTk_ScreenNumber\fR
returns the index of \fItkwin\fR's screen among all the screens
of \fItkwin\fR's display.  \fBTk_Screen\fR returns a pointer to
the Xlib structure corresponding to \fItkwin\fR's screen.


.PP
\fBTk_X\fR, \fBTk_Y\fR, \fBTk_Width\fR, and \fBTk_Height\fR
return information about \fItkwin's\fR location within its
parent and its size.  The location information refers to the
upper-left pixel in the window, or its border if there is one.
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
call to \fBTk_GeometryRequest\fR for \fItkwin\fR.
.PP
\fBTk_MinReqWidth\fR and \fBTk_MinReqHeight\fR return information about
the window's minimum requested size.  These values correspond to the last
call to \fBTk_SetMinimumRequestSize\fR for \fItkwin\fR.
.PP
\fBTk_InternalBorderLeft\fR, \fBTk_InternalBorderRight\fR,
\fBTk_InternalBorderTop\fR and \fBTk_InternalBorderBottom\fR
return the width of one side of the internal border
that has been requested for \fItkwin\fR, or 0 if no internal border was
requested.  The return value is simply the last value passed to
\fBTk_SetInternalBorder\fR or \fBTk_SetInternalBorderEx\fR for \fItkwin\fR.
.PP
\fBTk_Visual\fR, \fBTk_Depth\fR, and \fBTk_Colormap\fR return
information about the visual characteristics of a window.
\fBTk_Visual\fR returns the visual type for
the window, \fBTk_Depth\fR returns the number of bits per pixel,
and \fBTk_Colormap\fR returns the current
colormap for the window.  The visual characteristics are
normally set from the defaults for the window's screen, but
they may be overridden by calling \fBTk_SetWindowVisual\fR.
.PP
\fBTk_NewWindowObj\fR creates a new \fBTcl_Obj\fR from the window.
.SH KEYWORDS
attributes, colormap, depth, display, height, geometry manager,
identifier, mapped, requested size, screen, top-level,
visual, width, window, x, y







|













|
<




165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
call to \fBTk_GeometryRequest\fR for \fItkwin\fR.
.PP
\fBTk_MinReqWidth\fR and \fBTk_MinReqHeight\fR return information about
the window's minimum requested size.  These values correspond to the last
call to \fBTk_SetMinimumRequestSize\fR for \fItkwin\fR.
.PP
\fBTk_InternalBorderLeft\fR, \fBTk_InternalBorderRight\fR,
\fBTk_InternalBorderTop\fR and \fBTk_InternalBorderBottom\fR 
return the width of one side of the internal border
that has been requested for \fItkwin\fR, or 0 if no internal border was
requested.  The return value is simply the last value passed to
\fBTk_SetInternalBorder\fR or \fBTk_SetInternalBorderEx\fR for \fItkwin\fR.
.PP
\fBTk_Visual\fR, \fBTk_Depth\fR, and \fBTk_Colormap\fR return
information about the visual characteristics of a window.
\fBTk_Visual\fR returns the visual type for
the window, \fBTk_Depth\fR returns the number of bits per pixel,
and \fBTk_Colormap\fR returns the current
colormap for the window.  The visual characteristics are
normally set from the defaults for the window's screen, but
they may be overridden by calling \fBTk_SetWindowVisual\fR.


.SH KEYWORDS
attributes, colormap, depth, display, height, geometry manager,
identifier, mapped, requested size, screen, top-level,
visual, width, window, x, y

Changes to doc/bell.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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.
'\"
.TH bell n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bell \- Ring a display's bell
.SH SYNOPSIS
\fBbell \fR?\fB\-displayof \fIwindow\fR? ?\fB\-nice\fR?
.BE

.SH DESCRIPTION
.PP
This command rings the bell on the display for \fIwindow\fR and
returns an empty string.
If the \fB\-displayof\fR option is omitted, the display of the
application's main window is used by default.
The command uses the current bell-related settings for the display, which
may be modified with programs such as \fBxset\fR.
.PP
If \fB\-nice\fR is not specified, this command also resets the screen saver
for the screen.  Some screen savers will ignore this, but others will reset
so that the screen becomes visible again.

.SH KEYWORDS
beep, bell, ring
'\" Local Variables:
'\" mode: nroff
'\" End:







|









>












>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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.
'\" 
.TH bell n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bell \- Ring a display's bell
.SH SYNOPSIS
\fBbell \fR?\fB\-displayof \fIwindow\fR? ?\fB\-nice\fR?
.BE

.SH DESCRIPTION
.PP
This command rings the bell on the display for \fIwindow\fR and
returns an empty string.
If the \fB\-displayof\fR option is omitted, the display of the
application's main window is used by default.
The command uses the current bell-related settings for the display, which
may be modified with programs such as \fBxset\fR.
.PP
If \fB\-nice\fR is not specified, this command also resets the screen saver
for the screen.  Some screen savers will ignore this, but others will reset
so that the screen becomes visible again.

.SH KEYWORDS
beep, bell, ring



Changes to doc/bind.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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.
'\"
.TH bind n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bind \- Arrange for X events to invoke Tcl scripts
.SH SYNOPSIS
\fBbind\fI tag\fR ?\fIsequence\fR? ?\fB+\fR??\fIscript\fR?
.BE
.SH "INTRODUCTION"
.PP
The \fBbind\fR command associates Tcl scripts with X events.
If all three arguments are specified, \fBbind\fR will
arrange for \fIscript\fR (a Tcl script called the
.QW "binding script")
to be evaluated whenever the event(s) given by \fIsequence\fR
occur in the window(s) identified by \fItag\fR.
If \fIscript\fR is prefixed with a
.QW + ,
then it is appended to
any existing binding for \fIsequence\fR;  otherwise \fIscript\fR replaces
any existing binding.
If \fIscript\fR is an empty string then the current binding for
\fIsequence\fR is destroyed, leaving \fIsequence\fR unbound.







|













|
<
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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.
'\" 
.TH bind n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bind \- Arrange for X events to invoke Tcl scripts
.SH SYNOPSIS
\fBbind\fI tag\fR ?\fIsequence\fR? ?\fB+\fR??\fIscript\fR?
.BE
.SH "INTRODUCTION"
.PP
The \fBbind\fR command associates Tcl scripts with X events.
If all three arguments are specified, \fBbind\fR will
arrange for \fIscript\fR (a Tcl script) to be evaluated whenever

the event(s) given by \fIsequence\fR occur in the window(s)
identified by \fItag\fR.
If \fIscript\fR is prefixed with a
.QW + ,
then it is appended to
any existing binding for \fIsequence\fR;  otherwise \fIscript\fR replaces
any existing binding.
If \fIscript\fR is an empty string then the current binding for
\fIsequence\fR is destroyed, leaving \fIsequence\fR unbound.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
.PP
The \fIsequence\fR argument specifies a sequence of one or more
event patterns, with optional white space between the patterns.  Each
event pattern may
take one of three forms.  In the simplest case it is a single
printing ASCII character, such as \fBa\fR or \fB[\fR.  The character
may not be a space character or the character \fB<\fR.  This form of
pattern matches a \fBKey\fR event for the particular
character.  The second form of pattern is longer but more general.
It has the following syntax:
.CS
\fB<\fImodifier\-modifier\-type\-detail\fB>\fR
.CE
The entire event pattern is surrounded by angle brackets.
Inside the angle brackets are zero or more modifiers, an event







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
.PP
The \fIsequence\fR argument specifies a sequence of one or more
event patterns, with optional white space between the patterns.  Each
event pattern may
take one of three forms.  In the simplest case it is a single
printing ASCII character, such as \fBa\fR or \fB[\fR.  The character
may not be a space character or the character \fB<\fR.  This form of
pattern matches a \fBKeyPress\fR event for the particular
character.  The second form of pattern is longer but more general.
It has the following syntax:
.CS
\fB<\fImodifier\-modifier\-type\-detail\fB>\fR
.CE
The entire event pattern is surrounded by angle brackets.
Inside the angle brackets are zero or more modifiers, an event
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
substantial mouse motion in between.  For example, \fB<Double\-Button\-1>\fR
is equivalent to \fB<Button\-1><Button\-1>\fR with the extra time and space
requirement.
.PP
The \fBCommand\fR and \fBOption\fR modifiers are equivalents of \fBMod1\fR
resp. \fBMod2\fR, they correspond to Macintosh-specific modifier keys.
.PP

The \fBExtended\fR modifier is, at present, specific to Windows.  It
appears on events that are associated with the keys on the
.QW "extended keyboard" .
On a US keyboard, the extended keys include the \fBAlt\fR
and \fBControl\fR keys at the right of the keyboard, the cursor keys
in the cluster to the left of the numeric pad, the \fBNumLock\fR key,
the \fBBreak\fR key, the \fBPrintScreen\fR key, and the \fB/\fR and
\fBEnter\fR keys in the numeric keypad.

.SS "EVENT TYPES"
.PP
The \fItype\fR field may be any of the standard X event types, with a
few extra abbreviations.  The \fItype\fR field will also accept a
couple non-standard X event types that were added to better support
the Macintosh and Windows platforms.  Below is a list of all the valid
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButton, ButtonPress\0\0\0\fR'u +\w'\fBKey, KeyPress\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButton\fR, \fBButtonPress\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBCirculateRequest\fR	\fBFocusOut\fR	\fBProperty\fR
\fBColormap\fR	\fBGravity\fR	\fBReparent\fR
\fBConfigure\fR	\fBKey\fR, \fBKeyPress\fR	\fBResizeRequest\fR
\fBConfigureRequest\fR	\fBKeyRelease\fR	\fBUnmap\fR
\fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events







>








>








|

|




|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
substantial mouse motion in between.  For example, \fB<Double\-Button\-1>\fR
is equivalent to \fB<Button\-1><Button\-1>\fR with the extra time and space
requirement.
.PP
The \fBCommand\fR and \fBOption\fR modifiers are equivalents of \fBMod1\fR
resp. \fBMod2\fR, they correspond to Macintosh-specific modifier keys.
.PP
.VS 8.5
The \fBExtended\fR modifier is, at present, specific to Windows.  It
appears on events that are associated with the keys on the
.QW "extended keyboard" .
On a US keyboard, the extended keys include the \fBAlt\fR
and \fBControl\fR keys at the right of the keyboard, the cursor keys
in the cluster to the left of the numeric pad, the \fBNumLock\fR key,
the \fBBreak\fR key, the \fBPrintScreen\fR key, and the \fB/\fR and
\fBEnter\fR keys in the numeric keypad.
.VE 8.5
.SS "EVENT TYPES"
.PP
The \fItype\fR field may be any of the standard X event types, with a
few extra abbreviations.  The \fItype\fR field will also accept a
couple non-standard X event types that were added to better support
the Macintosh and Windows platforms.  Below is a list of all the valid
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButtonPress, Button\0\0\0\fR'u +\w'\fBKeyPress, Key\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButtonPress\fR, \fBButton\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBCirculateRequest\fR	\fBFocusOut\fR	\fBProperty\fR
\fBColormap\fR	\fBGravity\fR	\fBReparent\fR
\fBConfigure\fR	\fBKeyPress\fR, \fBKey\fR	\fBResizeRequest\fR
\fBConfigureRequest\fR	\fBKeyRelease\fR	\fBUnmap\fR
\fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events
197
198
199
200
201
202
203
204
205
206
207
208
209


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
active.  Likewise, the \fBDeactive\fR event is sent when the window's
state changes from active to deactive.  There are no useful percent
substitutions you would make when binding to these events.
.IP \fBMouseWheel\fR 5
Many contemporary mice support a mouse wheel, which is used
for scrolling documents without using the scrollbars.  By rolling the
wheel, the system will generate \fBMouseWheel\fR events that the
application can use to scroll.  The event is routed to the
window currently under the mouse pointer. When the event
is received you can use the \fB%D\fR substitution to get the
\fIdelta\fR field for the event, which is an integer value describing how
the mouse wheel has moved.  The smallest value for which the
system will report is defined by the OS.  The sign of the


value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and negative
right scrolling.
Horizontal scrolling events may fire from
many different hardware units such as tilt wheels or touchpads.  Horizontal
scrolling can also be emulated by holding Shift and scrolling vertically.
.RE
.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR
.IP "\fBKey\fR, \fBKeyRelease\fR" 5
The \fBKey\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKey\fR and \fBKeyRelease\fR
events are sent to the window which currently has the keyboard focus.
.IP "\fBButton\fR, \fBButtonRelease\fR, \fBMotion\fR" 5
The \fBButton\fR and \fBButtonRelease\fR events
are generated when the user presses or releases a mouse button.
\fBMotion\fR events are generated whenever the pointer is moved.
\fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR events are
normally sent to the window containing the pointer.
.RS
.PP
When a mouse button is pressed, the window containing the pointer
automatically obtains a temporary pointer grab.
Subsequent \fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR
events will be sent to that window,
regardless of which window contains the pointer,
until all buttons have been released.
.RE
.IP \fBConfigure\fR 5
A \fBConfigure\fR event is sent to a window whenever its
size, position, or border width changes, and sometimes







|
|

|

|
>
>


<
<
<
<
<
<
<
<
<



<
<
<

|
|


|





|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214









215
216
217



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
active.  Likewise, the \fBDeactive\fR event is sent when the window's
state changes from active to deactive.  There are no useful percent
substitutions you would make when binding to these events.
.IP \fBMouseWheel\fR 5
Many contemporary mice support a mouse wheel, which is used
for scrolling documents without using the scrollbars.  By rolling the
wheel, the system will generate \fBMouseWheel\fR events that the
application can use to scroll.  Like \fBKey\fR events the event is
always routed to the window that currently has focus. When the event
is received you can use the \fB%D\fR substitution to get the
\fIdelta\fR field for the event, which is a integer value describing how
the mouse wheel has moved.  The smallest value for which the
system will report is defined by the OS.  On Windows 95 & 98 machines
this value is at least 120 before it is reported.  However, higher
resolution devices may be available in the future.  The sign of the
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.









.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR



events are sent to the window which currently has the keyboard focus.
.IP "\fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR" 5
The \fBButtonPress\fR and \fBButtonRelease\fR events
are generated when the user presses or releases a mouse button.
\fBMotion\fR events are generated whenever the pointer is moved.
\fBButtonPress\fR, \fBButtonRelease\fR, and \fBMotion\fR events are
normally sent to the window containing the pointer.
.RS
.PP
When a mouse button is pressed, the window containing the pointer
automatically obtains a temporary pointer grab.
Subsequent \fBButtonPress\fR, \fBButtonRelease\fR, and \fBMotion\fR
events will be sent to that window,
regardless of which window contains the pointer,
until all buttons have been released.
.RE
.IP \fBConfigure\fR 5
A \fBConfigure\fR event is sent to a window whenever its
size, position, or border width changes, and sometimes
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
A \fBDestroy\fR event is delivered to a window when
it is destroyed.
.RS
.PP
When the \fBDestroy\fR event is delivered
to a widget, it is in a
.QW half-dead
state: the widget still exists, but operations that involve it
may return invalid results, or return an error.
.RE
.IP "\fBFocusIn\fR, \fBFocusOut\fR" 5
The \fBFocusIn\fR and \fBFocusOut\fR events are generated
whenever the keyboard focus changes.
A \fBFocusOut\fR event is sent to the old focus window,
and a \fBFocusIn\fR event is sent to the new one.
.RS







|
<







269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
A \fBDestroy\fR event is delivered to a window when
it is destroyed.
.RS
.PP
When the \fBDestroy\fR event is delivered
to a widget, it is in a
.QW half-dead
state: the widget still exists, but most operations on it will fail.

.RE
.IP "\fBFocusIn\fR, \fBFocusOut\fR" 5
The \fBFocusIn\fR and \fBFocusOut\fR events are generated
whenever the keyboard focus changes.
A \fBFocusOut\fR event is sent to the old focus window,
and a \fBFocusIn\fR event is sent to the new one.
.RS
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
This event type is included only for completeness;
there is no reliable way to track changes to a window's
position in the stacking order.
.RE
.SS "EVENT DETAILS"
.PP
The last part of a long event specification is \fIdetail\fR.  In the
case of a \fBButton\fR or \fBButtonRelease\fR event, it is the
number of a button (1\-9).  If a button number is given, then only an
event on that particular button will match;  if no button number is
given, then an event on any button will match.  Note:  giving a
specific button number is different than specifying a button modifier;
in the first case, it refers to a button being pressed or released,
while in the second it refers to some other button that is already
depressed when the matching event occurs.  If a button
number is given then \fItype\fR may be omitted:  if will default
to \fBButton\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<Button\-1>\fR.
.PP
If the event type is \fBKey\fR or \fBKeyRelease\fR, then
\fIdetail\fR may be specified in the form of an X keysym.  Keysyms
are textual specifications for particular keys on the keyboard;
they include all the alphanumeric ASCII characters (e.g.
.QW a
is the keysym for the ASCII character
.QW a ),
plus descriptions for non-alphanumeric characters
.PQ comma "is the keysym for the comma character" ,
plus descriptions for all the non-ASCII keys on the keyboard (e.g.
.QW Shift_L
is the keysym for the left shift key, and
.QW F1
is the keysym for the F1 function key, if it exists).  The
complete list of keysyms is not presented here;  it is
available in other X documentation and may vary from system to
system.
If necessary, you can use the \fB%K\fR notation described below
to print out the keysym name for a particular key.
If a keysym \fIdetail\fR is given, then the
\fItype\fR field may be omitted;  it will default to \fBKey\fR.
For example, \fB<Control\-comma>\fR is equivalent to
\fB<Control\-Key\-comma>\fR.
.SH "BINDING SCRIPTS AND SUBSTITUTIONS"
.PP
The \fIscript\fR argument to \fBbind\fR is a Tcl script, called the
.QW "binding script",
which will be executed whenever the given event sequence occurs.
\fICommand\fR will be executed in the same interpreter that the
\fBbind\fR command was executed in, and it will run at global
level (only global variables will be accessible).
If \fIscript\fR contains
any \fB%\fR characters, then the script will not be
executed directly.  Instead, a new script will be







|
|







|
|

|



















|

|


|
<







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
This event type is included only for completeness;
there is no reliable way to track changes to a window's
position in the stacking order.
.RE
.SS "EVENT DETAILS"
.PP
The last part of a long event specification is \fIdetail\fR.  In the
case of a \fBButtonPress\fR or \fBButtonRelease\fR event, it is the
number of a button (1\-5).  If a button number is given, then only an
event on that particular button will match;  if no button number is
given, then an event on any button will match.  Note:  giving a
specific button number is different than specifying a button modifier;
in the first case, it refers to a button being pressed or released,
while in the second it refers to some other button that is already
depressed when the matching event occurs.  If a button
number is given then \fItype\fR may be omitted:  if will default
to \fBButtonPress\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<ButtonPress\-1>\fR.
.PP
If the event type is \fBKeyPress\fR or \fBKeyRelease\fR, then
\fIdetail\fR may be specified in the form of an X keysym.  Keysyms
are textual specifications for particular keys on the keyboard;
they include all the alphanumeric ASCII characters (e.g.
.QW a
is the keysym for the ASCII character
.QW a ),
plus descriptions for non-alphanumeric characters
.PQ comma "is the keysym for the comma character" ,
plus descriptions for all the non-ASCII keys on the keyboard (e.g.
.QW Shift_L
is the keysym for the left shift key, and
.QW F1
is the keysym for the F1 function key, if it exists).  The
complete list of keysyms is not presented here;  it is
available in other X documentation and may vary from system to
system.
If necessary, you can use the \fB%K\fR notation described below
to print out the keysym name for a particular key.
If a keysym \fIdetail\fR is given, then the
\fItype\fR field may be omitted;  it will default to \fBKeyPress\fR.
For example, \fB<Control\-comma>\fR is equivalent to
\fB<Control\-KeyPress\-comma>\fR.
.SH "BINDING SCRIPTS AND SUBSTITUTIONS"
.PP
The \fIscript\fR argument to \fBbind\fR is a Tcl script,

which will be executed whenever the given event sequence occurs.
\fICommand\fR will be executed in the same interpreter that the
\fBbind\fR command was executed in, and it will run at global
level (only global variables will be accessible).
If \fIscript\fR contains
any \fB%\fR characters, then the script will not be
executed directly.  Instead, a new script will be
430
431
432
433
434
435
436
437
438
439
440
441
442
443



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
formatted as a hexadecimal number.
Valid only for \fBConfigure\fR events.
Indicates the sibling window immediately below the receiving window
in the stacking order, or \fB0\fR if the receiving window is at the
bottom.
.IP \fB%b\fR 5
The number of the button that was pressed or released.  Valid only
for \fBButton\fR and \fBButtonRelease\fR events.
.IP \fB%c\fR 5
The \fIcount\fR field from the event.  Valid only for \fBExpose\fR events.
Indicates that there are \fIcount\fR pending \fBExpose\fR events which have not
yet been delivered to the window.
.IP \fB%d\fR 5
The \fIdetail\fR or \fIuser_data\fR



field from the event.  The \fB%d\fR is replaced by
a string identifying the detail.  For \fBEnter\fR,
\fBLeave\fR, \fBFocusIn\fR, and \fBFocusOut\fR events,
the string will be one of the following:
.RS
.DS
.ta 6c
\fBNotifyAncestor\fR	\fBNotifyNonlinearVirtual\fR
\fBNotifyDetailNone\fR	\fBNotifyPointer\fR
\fBNotifyInferior\fR	\fBNotifyPointerRoot\fR
\fBNotifyNonlinear\fR	\fBNotifyVirtual\fR
.DE
For \fBConfigureRequest\fR events, the string will be one of:
.DS
.ta 6c
\fBAbove\fR	\fBOpposite\fR
\fBBelow\fR	\fBNone\fR
\fBBottomIf\fR	\fBTopIf\fR
.DE

For virtual events, the string will be whatever value is stored in the
\fIuser_data\fR field when the event was created (typically with
\fBevent generate\fR), or the empty string if the field is NULL.
Virtual events corresponding to key sequence presses (see \fBevent
add\fR for details) set the \fIuser_data\fR to NULL.

For events other than these, the substituted string is undefined.
.RE
.IP \fB%f\fR 5
The \fIfocus\fR field from the event (\fB0\fR or \fB1\fR).  Valid only
for \fBEnter\fR and \fBLeave\fR events.  \fB1\fR if the receiving
window is the focus window or a descendant of the focus window,
\fB0\fR otherwise.
.IP \fB%h\fR 5
The \fIheight\fR field from the event.  Valid for the \fBConfigure\fR,
\fBConfigureRequest\fR, \fBCreate\fR, \fBResizeRequest\fR, and
\fBExpose\fR events.
Indicates the new or requested height of the window.
.IP \fB%i\fR 5
The \fIwindow\fR field from the event, represented as a hexadecimal
integer.  Valid for all event types.
.IP \fB%k\fR 5
The \fIkeycode\fR field from the event.  Valid only for \fBKey\fR
and \fBKeyRelease\fR events.
.IP \fB%m\fR 5
The \fImode\fR field from the event.  The substituted string is one of
\fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.  Valid only for \fBEnter\fR,
\fBFocusIn\fR, \fBFocusOut\fR, and \fBLeave\fR events.
.IP \fB%o\fR 5
The \fIoverride_redirect\fR field from the event.  Valid only for
\fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
.IP \fB%p\fR 5
The \fIplace\fR field from the event, substituted as one of the
strings \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.  Valid only
for \fBCirculate\fR and \fBCirculateRequest\fR events.
.IP \fB%s\fR 5
The \fIstate\fR field from the event.  For \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBKey\fR, \fBKeyRelease\fR,
\fBLeave\fR, and \fBMotion\fR events, a decimal string
is substituted.  For \fBVisibility\fR, one of the strings
\fBVisibilityUnobscured\fR, \fBVisibilityPartiallyObscured\fR,
and \fBVisibilityFullyObscured\fR is substituted.
For \fBProperty\fR events, substituted with
either the string \fBNewValue\fR (indicating that the property
has been created or modified) or \fBDelete\fR (indicating that







|





|
>
>
>



















>





>
















|














|
|







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
formatted as a hexadecimal number.
Valid only for \fBConfigure\fR events.
Indicates the sibling window immediately below the receiving window
in the stacking order, or \fB0\fR if the receiving window is at the
bottom.
.IP \fB%b\fR 5
The number of the button that was pressed or released.  Valid only
for \fBButtonPress\fR and \fBButtonRelease\fR events.
.IP \fB%c\fR 5
The \fIcount\fR field from the event.  Valid only for \fBExpose\fR events.
Indicates that there are \fIcount\fR pending \fBExpose\fR events which have not
yet been delivered to the window.
.IP \fB%d\fR 5
The \fIdetail\fR
.VS 8.5
or \fIuser_data\fR
.VE 8.5
field from the event.  The \fB%d\fR is replaced by
a string identifying the detail.  For \fBEnter\fR,
\fBLeave\fR, \fBFocusIn\fR, and \fBFocusOut\fR events,
the string will be one of the following:
.RS
.DS
.ta 6c
\fBNotifyAncestor\fR	\fBNotifyNonlinearVirtual\fR
\fBNotifyDetailNone\fR	\fBNotifyPointer\fR
\fBNotifyInferior\fR	\fBNotifyPointerRoot\fR
\fBNotifyNonlinear\fR	\fBNotifyVirtual\fR
.DE
For \fBConfigureRequest\fR events, the string will be one of:
.DS
.ta 6c
\fBAbove\fR	\fBOpposite\fR
\fBBelow\fR	\fBNone\fR
\fBBottomIf\fR	\fBTopIf\fR
.DE
.VS 8.5
For virtual events, the string will be whatever value is stored in the
\fIuser_data\fR field when the event was created (typically with
\fBevent generate\fR), or the empty string if the field is NULL.
Virtual events corresponding to key sequence presses (see \fBevent
add\fR for details) set the \fIuser_data\fR to NULL.
.VE 8.5
For events other than these, the substituted string is undefined.
.RE
.IP \fB%f\fR 5
The \fIfocus\fR field from the event (\fB0\fR or \fB1\fR).  Valid only
for \fBEnter\fR and \fBLeave\fR events.  \fB1\fR if the receiving
window is the focus window or a descendant of the focus window,
\fB0\fR otherwise.
.IP \fB%h\fR 5
The \fIheight\fR field from the event.  Valid for the \fBConfigure\fR,
\fBConfigureRequest\fR, \fBCreate\fR, \fBResizeRequest\fR, and
\fBExpose\fR events.
Indicates the new or requested height of the window.
.IP \fB%i\fR 5
The \fIwindow\fR field from the event, represented as a hexadecimal
integer.  Valid for all event types.
.IP \fB%k\fR 5
The \fIkeycode\fR field from the event.  Valid only for \fBKeyPress\fR
and \fBKeyRelease\fR events.
.IP \fB%m\fR 5
The \fImode\fR field from the event.  The substituted string is one of
\fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.  Valid only for \fBEnter\fR,
\fBFocusIn\fR, \fBFocusOut\fR, and \fBLeave\fR events.
.IP \fB%o\fR 5
The \fIoverride_redirect\fR field from the event.  Valid only for
\fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
.IP \fB%p\fR 5
The \fIplace\fR field from the event, substituted as one of the
strings \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.  Valid only
for \fBCirculate\fR and \fBCirculateRequest\fR events.
.IP \fB%s\fR 5
The \fIstate\fR field from the event.  For \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBKeyPress\fR, \fBKeyRelease\fR,
\fBLeave\fR, and \fBMotion\fR events, a decimal string
is substituted.  For \fBVisibility\fR, one of the strings
\fBVisibilityUnobscured\fR, \fBVisibilityPartiallyObscured\fR,
and \fBVisibilityFullyObscured\fR is substituted.
For \fBProperty\fR events, substituted with
either the string \fBNewValue\fR (indicating that the property
has been created or modified) or \fBDelete\fR (indicating that
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546


547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
The \fIwidth\fR field from the event.
Indicates the new or requested width of the window.
Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, \fBCreate\fR,
\fBResizeRequest\fR, and \fBExpose\fR events.
.IP "\fB%x\fR, \fB%y\fR" 5
The \fIx\fR and \fIy\fR fields from the event.
For \fBButton\fR, \fBButtonRelease\fR, \fBMotion\fR,
\fBKey\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events,
\fB%x\fR and \fB%y\fR indicate the position of the mouse pointer
relative to the receiving window.
For key events on the Macintosh these are the coordinates of the
mouse at the moment when an X11 KeyEvent is sent to Tk, which could
be slightly later than the time of the physical press or release.
For \fBEnter\fR and \fBLeave\fR events, the position where the
mouse pointer crossed the window, relative to the receiving window.
For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR
coordinates of the window relative to its parent window.
.IP \fB%A\fR 5
Substitutes the UNICODE character corresponding to the event, or
the empty string if the event does not correspond to a UNICODE character
(e.g. the shift key was pressed). On X11, \fBXmbLookupString\fR (or
\fBXLookupString\fR when input method support is turned off) does all
the work of translating from the event to a UNICODE character.
On X11, valid only for \fBKey\fR event. On Windows and macOS/aqua,
valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%B\fR 5
The \fIborder_width\fR field from the event.  Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, and \fBCreate\fR events.
.IP \fB%D\fR 5
This reports the \fIdelta\fR value of a \fBMouseWheel\fR event.  The
\fIdelta\fR value represents the rotation units the mouse wheel has


been moved. The sign of the value represents the direction the mouse
wheel was scrolled.
.IP \fB%E\fR 5
The \fIsend_event\fR field from the event.  Valid for all event types.
\fB0\fR indicates that this is a
.QW normal
event, \fB1\fR indicates that it is a
.QW synthetic
event generated by \fBSendEvent\fR.
.IP \fB%K\fR 5
The keysym corresponding to the event, substituted as a textual
string.  Valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%M\fR 5
The number of script-based binding patterns matched so far for the
event.  Valid for all event types.
.IP \fB%N\fR 5
The keysym corresponding to the event, substituted as a decimal
number.  Valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%P\fR 5
The name of the property being updated or deleted (which
may be converted to an XAtom using \fBwinfo atom\fR.) Valid
only for \fBProperty\fR events.
.IP \fB%R\fR 5
The \fIroot\fR window identifier from the event.  Valid only for
events containing a \fIroot\fR field.







|
|


<
<
<







|


<
|






>
>
|










|





|







509
510
511
512
513
514
515
516
517
518
519



520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
The \fIwidth\fR field from the event.
Indicates the new or requested width of the window.
Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, \fBCreate\fR,
\fBResizeRequest\fR, and \fBExpose\fR events.
.IP "\fB%x\fR, \fB%y\fR" 5
The \fIx\fR and \fIy\fR fields from the event.
For \fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR,
\fBKeyPress\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events,
\fB%x\fR and \fB%y\fR indicate the position of the mouse pointer
relative to the receiving window.



For \fBEnter\fR and \fBLeave\fR events, the position where the
mouse pointer crossed the window, relative to the receiving window.
For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR
coordinates of the window relative to its parent window.
.IP \fB%A\fR 5
Substitutes the UNICODE character corresponding to the event, or
the empty string if the event does not correspond to a UNICODE character
(e.g. the shift key was pressed). \fBXmbLookupString\fR (or
\fBXLookupString\fR when input method support is turned off) does all
the work of translating from the event to a UNICODE character.

Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%B\fR 5
The \fIborder_width\fR field from the event.  Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, and \fBCreate\fR events.
.IP \fB%D\fR 5
This reports the \fIdelta\fR value of a \fBMouseWheel\fR event.  The
\fIdelta\fR value represents the rotation units the mouse wheel has
been moved.  On Windows 95 & 98 systems the smallest value for the
delta is 120.  Future systems may support higher resolution values for
the delta.  The sign of the value represents the direction the mouse
wheel was scrolled.
.IP \fB%E\fR 5
The \fIsend_event\fR field from the event.  Valid for all event types.
\fB0\fR indicates that this is a
.QW normal
event, \fB1\fR indicates that it is a
.QW synthetic
event generated by \fBSendEvent\fR.
.IP \fB%K\fR 5
The keysym corresponding to the event, substituted as a textual
string.  Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%M\fR 5
The number of script-based binding patterns matched so far for the
event.  Valid for all event types.
.IP \fB%N\fR 5
The keysym corresponding to the event, substituted as a decimal
number.  Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%P\fR 5
The name of the property being updated or deleted (which
may be converted to an XAtom using \fBwinfo atom\fR.) Valid
only for \fBProperty\fR events.
.IP \fB%R\fR 5
The \fIroot\fR window identifier from the event.  Valid only for
events containing a \fIroot\fR field.
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
The path name of the window to which the event was reported (the
\fIwindow\fR field from the event).  Valid for all event types.
.IP "\fB%X\fR, \fB%Y\fR" 5
The \fIx_root\fR and  \fIy_root\fR fields from the event.
If a virtual-root window manager is being used then the substituted
values are the corresponding x-coordinate and y-coordinate in the virtual root.
Valid only for
\fBButton\fR, \fBButtonRelease\fR, \fBEnter\fR, \fBKey\fR,
\fBKeyRelease\fR, \fBLeave\fR and \fBMotion\fR events.
Same meaning as \fB%x\fR and \fB%y\fR, except relative to the (virtual) root
window.
.LP
The replacement string for a %-replacement is formatted as a proper
Tcl list element.
This means that spaces or special characters such as \fB$\fR and







|







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
The path name of the window to which the event was reported (the
\fIwindow\fR field from the event).  Valid for all event types.
.IP "\fB%X\fR, \fB%Y\fR" 5
The \fIx_root\fR and  \fIy_root\fR fields from the event.
If a virtual-root window manager is being used then the substituted
values are the corresponding x-coordinate and y-coordinate in the virtual root.
Valid only for
\fBButtonPress\fR, \fBButtonRelease\fR, \fBEnter\fR, \fBKeyPress\fR,
\fBKeyRelease\fR, \fBLeave\fR and \fBMotion\fR events.
Same meaning as \fB%x\fR and \fB%y\fR, except relative to the (virtual) root
window.
.LP
The replacement string for a %-replacement is formatted as a proper
Tcl list element.
This means that spaces or special characters such as \fB$\fR and
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
an \fBall\fR binding.
The \fBbindtags\fR command may be used to change this order for
a particular window or to associate additional binding tags with
the window.
.PP
The \fBcontinue\fR and \fBbreak\fR commands may be used inside a
binding script to control the processing of matching scripts.
If \fBcontinue\fR is invoked within a binding script, then this
binding script, including all other
.QW +
appended scripts, is terminated but Tk will continue processing
binding scripts associated with other \fItag\fR's.
If the \fBbreak\fR command is invoked within a binding script,
then that script terminates and no other scripts will be invoked
for the event.
.PP
Within a script called from the binding script, \fBreturn\fR
\fB-code ok\fR may be used to continue processing (including
.QW +
appended scripts), or \fBreturn\fR \fB-code break\fR may be used to
stop processing all other binding scripts.
.PP
If more than one binding matches a particular event and they
have the same \fItag\fR, then the most specific binding
is chosen and its script is evaluated.
The following tests are applied, in order, to determine which of
several matching sequences is more specific:
.RS
.IP (a)
an event pattern that specifies a specific button or key is more specific
than one that does not;
.IP (b)
a sequence with the most highest-ordered patterns (in term of highest
repetition count) is more specific than a sequence with less
highest-ordered patterns;
.IP (c)
if the modifiers specified in one pattern are a subset of the
modifiers in another pattern, then the pattern with more modifiers
is more specific;
.IP (d)
a virtual event whose physical pattern matches the sequence is less
specific than the same physical pattern that is not associated with a
virtual event;
.IP (e)
given a sequence that matches two or more virtual events, one
of the virtual events will be chosen, but the order is undefined.
.RE
.PP
If the matching sequences contain more than one event, then tests
(c)\-(e) are applied in order from the most recent event to the least recent







|
<
<
|
|




<
<
<
<
<
<










|
|
<



|



|







613
614
615
616
617
618
619
620


621
622
623
624
625
626






627
628
629
630
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
an \fBall\fR binding.
The \fBbindtags\fR command may be used to change this order for
a particular window or to associate additional binding tags with
the window.
.PP
The \fBcontinue\fR and \fBbreak\fR commands may be used inside a
binding script to control the processing of matching scripts.
If \fBcontinue\fR is invoked, then the current binding script


is terminated but Tk will continue processing binding scripts
associated with other \fItag\fR's.
If the \fBbreak\fR command is invoked within a binding script,
then that script terminates and no other scripts will be invoked
for the event.
.PP






If more than one binding matches a particular event and they
have the same \fItag\fR, then the most specific binding
is chosen and its script is evaluated.
The following tests are applied, in order, to determine which of
several matching sequences is more specific:
.RS
.IP (a)
an event pattern that specifies a specific button or key is more specific
than one that does not;
.IP (b)
a longer sequence (in terms of number
of events matched) is more specific than a shorter sequence;

.IP (c)
if the modifiers specified in one pattern are a subset of the
modifiers in another pattern, then the pattern with more modifiers
is more specific.
.IP (d)
a virtual event whose physical pattern matches the sequence is less
specific than the same physical pattern that is not associated with a
virtual event.
.IP (e)
given a sequence that matches two or more virtual events, one
of the virtual events will be chosen, but the order is undefined.
.RE
.PP
If the matching sequences contain more than one event, then tests
(c)\-(e) are applied in order from the most recent event to the least recent
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
An unbound event is not considered to be an error.
.SH "MULTI-EVENT SEQUENCES AND IGNORED EVENTS"
.PP
When a \fIsequence\fR specified in a \fBbind\fR command contains
more than one event pattern, then its script is executed whenever
the recent events (leading up to and including the current event)
match the given sequence.  This means, for example, that if button 1 is
clicked repeatedly the sequence \fB<Double\-Button\-1>\fR will match
each button press but the first.
If extraneous events that would prevent a match occur in the middle
of an event sequence then the extraneous events are
ignored unless they are \fBKey\fR or \fBButton\fR events.
For example, \fB<Double\-Button\-1>\fR will match a sequence of
presses of button 1, even though there will be \fBButtonRelease\fR
events (and possibly \fBMotion\fR events) between the
\fBButton\fR events.
Furthermore, a \fBKey\fR event may be preceded by any number
of other \fBKey\fR events for modifier keys without the
modifier keys preventing a match.
For example, the event sequence \fBaB\fR will match a press of the
\fBa\fR key, a release of the \fBa\fR key, a press of the \fBShift\fR
key, and a press of the \fBb\fR key:  the press of \fBShift\fR is
ignored because it is a modifier key.
Finally, if several \fBMotion\fR events occur in a row, only
the last one is used for purposes of matching binding sequences.
.SH "ERRORS"
.PP
If an error occurs in executing the script for a binding then the
\fBbgerror\fR mechanism is used to report the error.
The \fBbgerror\fR command will be executed at global level
(outside the context of any Tcl procedure).
.SH "EXAMPLES"
.PP
Arrange for a string describing the motion of the mouse to be printed
out when the mouse is double-clicked:
.CS
\fBbind\fR . <Double\-1> {
    puts "hi from (%x,%y)"
}
.CE







|



|
|


|
|
|














<







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
An unbound event is not considered to be an error.
.SH "MULTI-EVENT SEQUENCES AND IGNORED EVENTS"
.PP
When a \fIsequence\fR specified in a \fBbind\fR command contains
more than one event pattern, then its script is executed whenever
the recent events (leading up to and including the current event)
match the given sequence.  This means, for example, that if button 1 is
clicked repeatedly the sequence \fB<Double\-ButtonPress\-1>\fR will match
each button press but the first.
If extraneous events that would prevent a match occur in the middle
of an event sequence then the extraneous events are
ignored unless they are \fBKeyPress\fR or \fBButtonPress\fR events.
For example, \fB<Double\-ButtonPress\-1>\fR will match a sequence of
presses of button 1, even though there will be \fBButtonRelease\fR
events (and possibly \fBMotion\fR events) between the
\fBButtonPress\fR events.
Furthermore, a \fBKeyPress\fR event may be preceded by any number
of other \fBKeyPress\fR events for modifier keys without the
modifier keys preventing a match.
For example, the event sequence \fBaB\fR will match a press of the
\fBa\fR key, a release of the \fBa\fR key, a press of the \fBShift\fR
key, and a press of the \fBb\fR key:  the press of \fBShift\fR is
ignored because it is a modifier key.
Finally, if several \fBMotion\fR events occur in a row, only
the last one is used for purposes of matching binding sequences.
.SH "ERRORS"
.PP
If an error occurs in executing the script for a binding then the
\fBbgerror\fR mechanism is used to report the error.
The \fBbgerror\fR command will be executed at global level
(outside the context of any Tcl procedure).
.SH "EXAMPLES"

Arrange for a string describing the motion of the mouse to be printed
out when the mouse is double-clicked:
.CS
\fBbind\fR . <Double\-1> {
    puts "hi from (%x,%y)"
}
.CE
739
740
741
742
743
744
745
746
747
748
    set keysym "You pressed %K"
}
.CE
.SH "SEE ALSO"
bgerror(n), bindtags(n), event(n), focus(n), grab(n), keysyms(n)
.SH KEYWORDS
binding, event
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
721
722
723
724
725
726
727



    set keysym "You pressed %K"
}
.CE
.SH "SEE ALSO"
bgerror(n), bindtags(n), event(n), focus(n), grab(n), keysyms(n)
.SH KEYWORDS
binding, event



Changes to doc/bindtags.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH bindtags n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bindtags \- Determine which bindings apply to a window, and order of evaluation
.SH SYNOPSIS
\fBbindtags \fIwindow \fR?\fItagList\fR?
.BE

.SH DESCRIPTION
.PP
When a binding is created with the \fBbind\fR command, it is
associated either with a particular window such as \fB.a.b.c\fR,
a class name such as \fBButton\fR, the keyword \fBall\fR, or any
other string.
All of these forms are called \fIbinding tags\fR.






|









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH bindtags n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bindtags \- Determine which bindings apply to a window, and order of evaluation
.SH SYNOPSIS
\fBbindtags \fIwindow \fR?\fItagList\fR?
.BE

.SH DESCRIPTION
.PP
When a binding is created with the \fBbind\fR command, it is
associated either with a particular window such as \fB.a.b.c\fR,
a class name such as \fBButton\fR, the keyword \fBall\fR, or any
other string.
All of these forms are called \fIbinding tags\fR.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97

98
99
100
101
102
.CE
replaces the \fBButton\fR tag for \fB.b\fR with \fBTrickyButton\fR.
This means that the default widget bindings for buttons, which are
associated with the \fBButton\fR tag, will no longer apply to \fB.b\fR,
but any bindings associated with \fBTrickyButton\fR (perhaps some
new button behavior) will apply.
.SH EXAMPLE
.PP
If you have a set of nested \fBframe\fR widgets and you want events
sent to a \fBbutton\fR widget to also be delivered to all the widgets
up to the current \fBtoplevel\fR (in contrast to Tk's default
behavior, where events are not delivered to those intermediate
windows) to make it easier to have accelerators that are only active
for part of a window, you could use a helper procedure like this to
help set things up:
.CS
proc setupBindtagsForTreeDelivery {widget} {
    set tags [list $widget [winfo class $widget]]
    set w $widget
    set t [winfo toplevel $w]
    while {$w ne $t} {
        set w [winfo parent $w]
        lappend tags $w
    }
    lappend tags all
    \fBbindtags\fR $widget $tags
}
.CE

.SH "SEE ALSO"
bind(n)

.SH KEYWORDS
binding, event, tag
'\" Local Variables:
'\" mode: nroff
'\" End:







<




















>


>


<
<
<
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101



.CE
replaces the \fBButton\fR tag for \fB.b\fR with \fBTrickyButton\fR.
This means that the default widget bindings for buttons, which are
associated with the \fBButton\fR tag, will no longer apply to \fB.b\fR,
but any bindings associated with \fBTrickyButton\fR (perhaps some
new button behavior) will apply.
.SH EXAMPLE

If you have a set of nested \fBframe\fR widgets and you want events
sent to a \fBbutton\fR widget to also be delivered to all the widgets
up to the current \fBtoplevel\fR (in contrast to Tk's default
behavior, where events are not delivered to those intermediate
windows) to make it easier to have accelerators that are only active
for part of a window, you could use a helper procedure like this to
help set things up:
.CS
proc setupBindtagsForTreeDelivery {widget} {
    set tags [list $widget [winfo class $widget]]
    set w $widget
    set t [winfo toplevel $w]
    while {$w ne $t} {
        set w [winfo parent $w]
        lappend tags $w
    }
    lappend tags all
    \fBbindtags\fR $widget $tags
}
.CE

.SH "SEE ALSO"
bind(n)

.SH KEYWORDS
binding, event, tag



Changes to doc/bitmap.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH bitmap n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bitmap \- Images that display two colors
.SH SYNOPSIS
.nf
\fBimage create bitmap \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBcget\fR \fIoption\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.fi
.BE

.SH DESCRIPTION
.PP
A bitmap is an image whose pixels can display either of two colors
or be transparent.
A bitmap image is defined by four things:  a background color,
a foreground color, and two bitmaps, called the \fIsource\fR
and the \fImask\fR.
Each of the bitmaps specifies 0/1 values for a rectangular
array of pixels, and the two bitmaps must have the same
dimensions.
For pixels where the mask is zero, the image displays nothing,
producing a transparent effect.
For other pixels, the image displays the foreground color if
the source data is one and the background color if the source
data is zero.

.SH "CREATING BITMAPS"
.PP
Like all images, bitmaps are created using the \fBimage create\fR
command.
Bitmaps support the following \fIoptions\fR:
.TP
\fB\-background \fIcolor\fR
.
Specifies a background color for the image in any of the standard
ways accepted by Tk.  If this option is set to an empty string
then the background pixels will be transparent.  This effect
is achieved by using the source bitmap as the mask bitmap, ignoring
any \fB\-maskdata\fR or \fB\-maskfile\fR options.
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the source bitmap as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-data\fR and \fB\-file\fR options are specified,
the \fB\-data\fR option takes precedence.
.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
source bitmap.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
.TP
\fB\-foreground \fIcolor\fR
.
Specifies a foreground color for the image in any of the standard
ways accepted by Tk.
.TP
\fB\-maskdata \fIstring\fR
.
Specifies the contents of the mask as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-maskdata\fR and \fB\-maskfile\fR options are specified,
the \fB\-maskdata\fR option takes precedence.
.TP
\fB\-maskfile \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
mask.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).

.SH "IMAGE COMMAND"
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:
.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBbitmap\fR command.
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBbitmap\fR command.

.SH KEYWORDS
bitmap, image
'\" Local Variables:
'\" mode: nroff
'\" End:






|







<

<
<
<
<

>















>







<







<







<






<




<







<




>








|






<



|


<











|
>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15




16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47

48
49
50
51
52
53
54

55
56
57
58
59
60

61
62
63
64

65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112



'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH bitmap n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bitmap \- Images that display two colors
.SH SYNOPSIS

\fBimage create bitmap \fR?\fIname\fR? ?\fIoptions\fR?




.BE

.SH DESCRIPTION
.PP
A bitmap is an image whose pixels can display either of two colors
or be transparent.
A bitmap image is defined by four things:  a background color,
a foreground color, and two bitmaps, called the \fIsource\fR
and the \fImask\fR.
Each of the bitmaps specifies 0/1 values for a rectangular
array of pixels, and the two bitmaps must have the same
dimensions.
For pixels where the mask is zero, the image displays nothing,
producing a transparent effect.
For other pixels, the image displays the foreground color if
the source data is one and the background color if the source
data is zero.

.SH "CREATING BITMAPS"
.PP
Like all images, bitmaps are created using the \fBimage create\fR
command.
Bitmaps support the following \fIoptions\fR:
.TP
\fB\-background \fIcolor\fR

Specifies a background color for the image in any of the standard
ways accepted by Tk.  If this option is set to an empty string
then the background pixels will be transparent.  This effect
is achieved by using the source bitmap as the mask bitmap, ignoring
any \fB\-maskdata\fR or \fB\-maskfile\fR options.
.TP
\fB\-data \fIstring\fR

Specifies the contents of the source bitmap as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-data\fR and \fB\-file\fR options are specified,
the \fB\-data\fR option takes precedence.
.TP
\fB\-file \fIname\fR

\fIname\fR gives the name of a file whose contents define the
source bitmap.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
.TP
\fB\-foreground \fIcolor\fR

Specifies a foreground color for the image in any of the standard
ways accepted by Tk.
.TP
\fB\-maskdata \fIstring\fR

Specifies the contents of the mask as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-maskdata\fR and \fB\-maskfile\fR options are specified,
the \fB\-maskdata\fR option takes precedence.
.TP
\fB\-maskfile \fIname\fR

\fIname\fR gives the name of a file whose contents define the
mask.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).

.SH "IMAGE COMMAND"
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:
.TP
\fIimageName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create bitmap\fR command.
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create bitmap\fR command.

.SH KEYWORDS
bitmap, image



Deleted doc/busy.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
'\"
'\" Copyright (c) 1993-1998 Lucent Technologies, Inc.
'\" Copyright (c) 2008 Jos Decoster
'\"
'\" 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
'\" the copyright notice and warranty disclaimer appear in supporting
'\" documentation, and that the names of Lucent Technologies any of their
'\" entities not be used in advertising or publicity pertaining to
'\" distribution of the software without specific, written prior permission.
'\"
'\" Lucent Technologies disclaims all warranties with regard to this software,
'\" including all implied warranties of merchantability and fitness. In no
'\" event shall Lucent Technologies be liable for any special, indirect or
'\" consequential damages or any damages whatsoever resulting from loss of
'\" use, data or profits, whether in an action of contract, negligence or
'\" other tortuous action, arising out of or in connection with the use or
'\" performance of this software.
'\"
'\" BLT::busy command created by George Howlett.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH busy n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
busy \- Make Tk widgets busy, temporarily blocking user interactions
.SH SYNOPSIS
\fBtk busy\fR \fIwindow \fR?\fIoptions\fR?
.sp
\fBtk busy busywindow \fIwindow\fR
.sp
\fBtk busy hold\fR \fIwindow \fR?\fIoptions\fR?
.sp
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.sp
\fBtk busy forget\fR \fIwindow \fR?\fIwindow \fR?...
.sp
\fBtk busy current\fR ?\fIpattern\fR?
.sp
\fBtk busy status \fIwindow\fR
.BE
.SH DESCRIPTION
.PP
The \fBtk busy\fR command provides a simple means to block mouse pointer events
from Tk widgets, while overriding the widget's cursor with a configurable busy
cursor. Note this command does not prevent keyboard events from being sent to
the widgets made busy.
.SH INTRODUCTION
.PP
There are many times in applications where you want to temporarily restrict
what actions the user can take. For example, an application could have a
.QW Run
button that when pressed causes some processing to occur. However, while the
application is busy processing, you probably don't want the user to be
able to click the
.QW Run
button again. You may also want restrict the user from other tasks such as
clicking a
.QW Print
button.
.PP
The \fBtk busy\fR command lets you make Tk widgets busy. This means that user
interactions such as button clicks, moving the mouse, typing at the keyboard,
etc.\0are ignored by the widget. You can set a special cursor (like a watch)
that overrides the widget's normal cursor, providing feedback that the
application (widget) is temporarily busy.
.PP
When a widget is made busy, the widget and all of its descendants will ignore
pointer events. It's easy to make an entire panel of widgets busy. You can
simply make the toplevel widget (such as
.QW . )
busy. This is easier and far much more efficient than recursively traversing
the widget hierarchy, disabling each widget and re-configuring its cursor.
.PP
Often, the \fBtk busy\fR command can be used instead of Tk's \fBgrab\fR
command. Unlike \fBgrab\fR which restricts all user interactions to one
widget, with the \fBtk busy\fR command you can have more than one widget
active (for example, a
.QW Cancel
dialog and a
.QW Help
button).
.SS EXAMPLE
.PP
You can make several widgets busy by simply making its ancestor widget busy
using the \fBhold\fR operation.
.PP
.CS
frame .top
button .top.button; canvas .top.canvas
pack .top.button .top.canvas
pack .top
# . . .
\fBtk busy\fR hold .top
update
.CE
.PP
All the widgets within \fB.top\fR (including \fB.top\fR) are now busy. Using
\fBupdate\fR insures that \fBtk busy\fR command will take effect before any
other user events can occur.
.PP
When the application is no longer busy processing, you can allow user
interactions again and free any resources it allocated by the \fBforget\fR
operation.
.PP
.CS
\fBtk busy\fR forget .top
.CE
.PP
The busy window has a configurable cursor. You can change the busy cursor
using the \fBconfigure\fR operation.
.PP
.CS
\fBtk busy\fR configure .top \-cursor "watch"
.CE
.PP
Destroying the widget will also clean up any resources allocated by the \fBtk
busy\fR command.
.PP
.SH OPERATIONS
.PP
The following operations are available for the \fBtk busy\fR command:
.TP
\fBtk busy \fIwindow\fR ?\fIoption value\fR?...
.
Shortcut for \fBtk busy hold\fR command.
.TP
\fBtk busy busywindow \fIwindow\fR
.
Returns the pathname of the busy window (i.e. the transparent window
shielding the window appearing busy) created by the \fBtk busy hold\fR
command for \fIwindow\fR, or the empty string if \fIwindow\fR is not busy.
.TP
\fBtk busy cget \fIwindow\fR \fIoption\fR
.
Queries the \fBtk busy\fR command configuration options for \fIwindow\fR.
\fIWindow\fR must be the path name of a widget previously made busy by the
\fBhold\fR operation. The command returns the present value of the specified
\fIoption\fR. \fIOption\fR may have any of the values accepted by the
\fBhold\fR operation.
.TP
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.
Queries or modifies the \fBtk busy\fR command configuration options for
\fIwindow\fR. \fIWindow\fR must be the path name of a widget previously made
busy by the \fBhold\fR operation.  If no options are specified, a list
describing all of the available options for \fIwindow\fR (see
\fBTk_ConfigureInfo\fR for information on the format of this list) is
returned. If \fIoption\fR is specified with no \fIvalue\fR, then the command
returns a list describing the one named option (this list will be identical to
the corresponding sublist of the value returned if no \fIoption\fR is
specified). If one or more \fIoption\-value\fR pairs are specified, then the
command modifies the given widget option(s) to have the given value(s); in
this case the command returns the empty string. \fIOption\fR may have any of
the values accepted by the \fBhold\fR operation.
.RS
.PP
Please note that the option database is referenced through \fIwindow\fR. For
example, if the widget \fB.frame\fR is to be made busy, the busy cursor can be
specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE
.TP
\fBtk busy current \fR?\fIpattern\fR?
.
Returns the pathnames of all widgets that are currently busy. If a
\fIpattern\fR is given, only the path names of busy widgets matching
\fIpattern\fR are returned.
.TP
\fBtk busy forget \fIwindow\fR ?\fIwindow\fR?...
.
Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR,
including the transparent window. User events will again be received by
\fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed.
\fIWindow\fR must be the name of a widget specified in the \fBhold\fR
operation, otherwise an error is reported.
.TP
\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?...
.
Makes the specified \fIwindow\fR (and its descendants in the Tk window
hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget.
A transparent window is put in front of the specified window. This transparent
window is mapped the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user interactions. Normally
\fBupdate\fR should be called immediately afterward to insure that the hold
operation is in effect before the application starts its processing. The
command returns the pathname of the busy window that was created (i.e. the
transparent window shielding the window appearing busy). The following
configuration options are valid:
.RS
.TP
\fB\-cursor \fIcursorName\fR
.
Specifies the cursor to be displayed when the widget is made busy.
\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The
default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms.
.RE
.TP
\fBtk busy status \fIwindow\fR
.
Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not
receive user interactions, \fB1\fR is returned, otherwise \fB0\fR.
.SH "EVENT HANDLING"
.SS BINDINGS
.PP
The event blocking feature is implemented by creating and mapping a
transparent window that completely covers the widget. When the busy window is
mapped, it invisibly shields the widget and its hierarchy from all events that
may be sent. Like Tk widgets, busy windows have widget names in the Tk window
hierarchy. This means that you can use the \fBbind\fR command to handle
events in the busy window:
.PP
.CS
\fBtk busy\fR hold .frame.canvas
bind [\fBtk busy\fR busywindow .frame.canvas] <Enter> { ... }
.CE
.PP
or
.CS
set busyWin [\fBtk busy\fR hold .frame.canvas]
bind $busyWin <Enter> { ... }
.CE
.SS "ENTER/LEAVE EVENTS"
.PP
Mapping and unmapping busy windows generates Enter/Leave events for all
widgets they cover. Please note this if you are tracking Enter/Leave events in
widgets.
.SS "KEYBOARD EVENTS"
.PP
When a widget is made busy, the widget is prevented from gaining the keyboard
focus by a user clicking on it by the busy window. But if the widget already had
focus, it still may receive keyboard events. The widget can also still receive
focus through keyboard traversal. To prevent this, you must move
focus to another window and make sure the focus can not go back to the widgets
made busy (e.g. but restricting focus to a cancel button).
.PP
.CS
pack [frame .frame]
pack [text .frame.text]
\fBtk busy\fR hold .frame
pack [button .cancel -text "Cancel" -command exit]
focus .cancel
bind .cancel <Tab> {break}
bind .cancel <Shift-Tab> {break}
update
.CE
.PP
The above example moves the focus from .frame immediately after invoking the
\fBhold\fR so that no keyboard events will be sent to \fB.frame\fR or any of
its descendants. It also makes sure it's not possible to leave button
\fB.cancel\fR using the keyboard.
.SH PORTABILITY
.PP
Note that the \fBtk busy\fR command does not currently have any effect on OSX
when Tk is built using Aqua support.
.SH "SEE ALSO"
grab(n)
.SH KEYWORDS
busy, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































Changes to doc/button.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH button n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
button \- Create and manipulate 'button' action widgets
.SH SYNOPSIS
\fBbutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-font	\-relief
\-activeforeground	\-foreground	\-repeatdelay
\-anchor	\-highlightbackground	\-repeatinterval
\-background	\-highlightcolor	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH button n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
button \- Create and manipulate button widgets
.SH SYNOPSIS
\fBbutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-font	\-relief
\-activeforeground	\-foreground	\-repeatdelay
\-anchor	\-highlightbackground	\-repeatinterval
\-background	\-highlightcolor	\-takefocus
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the button.
The empty string is the default value.
.OP \-state state State
Specifies one of three states for the button:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the button is displayed using the
\fB\-foreground\fR and \fB\-background\fR options.  The active state is
typically used when the pointer is over the button.  In active state
the button is displayed using the \fB\-activeforeground\fR and
\fB\-activebackground\fR options.  Disabled state means that the button
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fB\-disabledforeground\fR and
\fB\-background\fR options determine how the button is displayed.
.OP \-width width Width
Specifies a desired width for the button.
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For a text button (no image or with \fB\-compound none\fR) then the width
specifies how much space in characters to allocate for the text label.
If the width is negative then this specifies a minimum width.
If this option is not specified, the button's desired width is computed
from the size of the image or bitmap or text being displayed in it.
.BE

.SH DESCRIPTION
.PP
The \fBbutton\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a button widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the button such as its colors, font,
text, and initial relief.  The \fBbutton\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A button is a widget that displays a textual string, bitmap or image.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fB\-wraplength\fR option) and
one of the characters may optionally be underlined using the
\fB\-underline\fR option.
It can display itself in either of three different ways, according
to
the \fB\-state\fR option;
it can be made to appear raised, sunken, or flat;
and it can be made to flash.  When a user invokes the
button (by pressing mouse button 1 with the cursor over the
button), then the Tcl command specified in the \fB\-command\fR
option is invoked.

.SH "WIDGET COMMAND"
.PP
The \fBbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for button widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given







|

|
|


|
|




|





>
















|

|


|





>







|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the button.
The empty string is the default value.
.OP \-state state State
Specifies one of three states for the button:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the button is displayed using the
\fBforeground\fR and \fBbackground\fR options.  The active state is
typically used when the pointer is over the button.  In active state
the button is displayed using the \fBactiveForeground\fR and
\fBactiveBackground\fR options.  Disabled state means that the button
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fBdisabledForeground\fR and
\fBbackground\fR options determine how the button is displayed.
.OP \-width width Width
Specifies a desired width for the button.
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For a text button (no image or with \fB\-compound none\fR) then the width 
specifies how much space in characters to allocate for the text label.
If the width is negative then this specifies a minimum width.
If this option is not specified, the button's desired width is computed
from the size of the image or bitmap or text being displayed in it.
.BE

.SH DESCRIPTION
.PP
The \fBbutton\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a button widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the button such as its colors, font,
text, and initial relief.  The \fBbutton\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A button is a widget that displays a textual string, bitmap or image.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fBwrapLength\fR option) and
one of the characters may optionally be underlined using the
\fBunderline\fR option.
It can display itself in either of three different ways, according
to
the \fBstate\fR option; 
it can be made to appear raised, sunken, or flat;
and it can be made to flash.  When a user invokes the
button (by pressing mouse button 1 with the cursor over the
button), then the Tcl command specified in the \fB\-command\fR
option is invoked.

.SH "WIDGET COMMAND"
.PP
The \fBbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for button widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.
.TP
\fIpathName \fBflash\fR
Flash the button.  This is accomplished by redisplaying the button
several times, alternating between the configured activebackground
and background colors.  At the end of the flash the button is left
in the same normal/active state as when the command was invoked.
This command is ignored if the button's state is \fBdisabled\fR.
.TP
\fIpathName \fBinvoke\fR
Invoke the Tcl command associated with the button, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the button.
This command is ignored if the button's state is \fBdisabled\fR.

.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for buttons that give them
default behavior:
.IP [1]
A button activates whenever the mouse passes over it and deactivates
whenever the mouse leaves the button.







|
|
|







>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.
.TP
\fIpathName \fBflash\fR
Flash the button.  This is accomplished by redisplaying the button
several times, alternating between active and normal colors.  At
the end of the flash the button is left in the same normal/active
state as when the command was invoked.
This command is ignored if the button's state is \fBdisabled\fR.
.TP
\fIpathName \fBinvoke\fR
Invoke the Tcl command associated with the button, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the button.
This command is ignored if the button's state is \fBdisabled\fR.

.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for buttons that give them
default behavior:
.IP [1]
A button activates whenever the mouse passes over it and deactivates
whenever the mouse leaves the button.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
to be invoked.
.PP
If the button's state is \fBdisabled\fR then none of the above
actions occur:  the button is completely non-responsive.
.PP
The behavior of buttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "PLATFORM NOTES"
.PP
On Aqua/Mac OS X, some configuration options are ignored for the purpose of
drawing of the widget because they would otherwise conflict with platform
guidelines. The \fBconfigure\fR and \fBcget\fR subcommands can still
manipulate the values, but do not cause any variation to the look of the
widget. The options affected notably include \fB\-background\fR and
\fB\-relief\fR.
.SH EXAMPLES
.PP
This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
\fBbutton\fR .b \-text "Hello, World!" \-command exit
pack .b
.CE
.PP
This example demonstrates how to handle button accelerators:
.PP
.CS
\fBbutton\fR .b1 \-text Hello \-underline 0
\fBbutton\fR .b2 \-text World \-underline 0
bind . <Key\-h> {.b1 flash; .b1 invoke}
bind . <Key\-w> {.b2 flash; .b2 invoke}
pack .b1 .b2
.CE
.SH "SEE ALSO"
ttk::button(n)
.SH KEYWORDS
button, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
<
<
<
<
<
<
<

<





|
|





|
|
|
|
|





<
<
<
172
173
174
175
176
177
178
179







180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202



to be invoked.
.PP
If the button's state is \fBdisabled\fR then none of the above
actions occur:  the button is completely non-responsive.
.PP
The behavior of buttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.








.SH EXAMPLES

This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
    \fBbutton\fR .b \-text "Hello, World!" \-command exit
    pack .b
.CE
.PP
This example demonstrates how to handle button accelerators:
.PP
.CS
    \fBbutton\fR .b1 \-text Hello \-underline 0
    \fBbutton\fR .b2 \-text World \-underline 0
    bind . <Key\-h> {.b1 flash; .b1 invoke}
    bind . <Key\-w> {.b2 flash; .b2 invoke}
    pack .b1 .b2
.CE
.SH "SEE ALSO"
ttk::button(n)
.SH KEYWORDS
button, widget



Changes to doc/canvas.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1997-1999 Scriptics Corporation.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH canvas n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
canvas \- Create and manipulate 'canvas' hypergraphics drawing surface widgets
.SH SYNOPSIS
\fBcanvas\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-insertbackground	\-insertborderwidth	\-insertofftime
\-insertontime	\-insertwidth	\-relief













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1997-1999 Scriptics Corporation.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH canvas n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
canvas \- Create and manipulate canvas widgets
.SH SYNOPSIS
\fBcanvas\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-insertbackground	\-insertborderwidth	\-insertofftime
\-insertontime	\-insertwidth	\-relief
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
Specifies a boolean value that indicates whether or not it should be
allowable to set the canvas's view outside the region defined by the
\fBscrollRegion\fR argument.
Defaults to true, which means that the view will
be constrained within the scroll region.
.OP \-height height Height
Specifies a desired window height that the canvas widget should request from
its geometry manager. The value may be specified in any
of the forms described in the \fBCOORDINATES\fR section below.
.OP \-scrollregion scrollRegion ScrollRegion
Specifies a list with four coordinates describing the left, top, right, and
bottom coordinates of a rectangular region.
This region is used for scrolling purposes and is considered to be
the boundary of the information in the canvas.
Each of the coordinates may be specified
in any of the forms given in the \fBCOORDINATES\fR section below.
.OP \-state state State
Modifies the default state of the canvas where \fIstate\fR may be set to
one of: \fBnormal\fR, \fBdisabled\fR, or \fBhidden\fR. Individual canvas
objects all have their own state option which may override the default
state. Many options can take separate specifications such that the
appearance of the item can be different in different situations. The
options that start with \fBactive\fR control the appearance when the mouse
pointer is over it, while the option starting with \fBdisabled\fR controls
the appearance when the state is disabled. Canvas items which are
\fBdisabled\fR will not react to canvas bindings.
.OP \-width width width
Specifies a desired window width that the canvas widget should request from
its geometry manager. The value may be specified in any
of the forms described in the \fBCOORDINATES\fR section below.
.OP \-xscrollincrement xScrollIncrement ScrollIncrement
Specifies an increment for horizontal scrolling, in any of the usual forms
permitted for screen distances. If the value of this option is greater
than zero, the horizontal view in the window will be constrained so that
the canvas x coordinate at the left edge of the window is always an even
multiple of \fBxScrollIncrement\fR; furthermore, the units for scrolling
(e.g., the change in view when the left and right arrows of a scrollbar
are selected) will also be \fBxScrollIncrement\fR. If the value of
this option is less than or equal to zero, then horizontal scrolling
is unconstrained.
.OP \-yscrollincrement yScrollIncrement ScrollIncrement
Specifies an increment for vertical scrolling, in any of the usual forms
permitted for screen distances. If the value of this option is greater
than zero, the vertical view in the window will be constrained so that
the canvas y coordinate at the top edge of the window is always an even
multiple of \fByScrollIncrement\fR; furthermore, the units for scrolling
(e.g., the change in view when the top and bottom arrows of a scrollbar
are selected) will also be \fByScrollIncrement\fR. If the value of
this option is less than or equal to zero, then vertical scrolling
is unconstrained.
.BE
.SH INTRODUCTION
.PP
The \fBcanvas\fR command creates a new window (given
by the \fIpathName\fR argument) and makes it into a canvas widget.
Additional options, described above, may be specified on the
command line or in the option database
to configure aspects of the canvas such as its colors and 3-D relief.
The \fBcanvas\fR command returns its
\fIpathName\fR argument. At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
Canvas widgets implement structured graphics.
A canvas displays any number of \fIitems\fR, which may be things like
rectangles, circles, lines, and text.
Items may be manipulated (e.g. moved or re-colored) and commands may
be associated with items in much the same way that the \fBbind\fR
command allows commands to be bound to widgets. For example,
a particular command may be associated with the <Button-1> event
so that the command is invoked whenever button 1 is pressed with
the mouse cursor over an item.
This means that items in a canvas can have behaviors defined by
the Tcl scripts bound to them.
.SH "DISPLAY LIST"
.PP
The items in a canvas are ordered for purposes of display,
with the first item in the display list being displayed
first, followed by the next item in the list, and so on.
Items later in the display list obscure those that are
earlier in the display list and are sometimes referred to as being
.QW "on top"
of earlier items.
When a new item is created it is placed at the end of the
display list, on top of everything else.
Widget commands may be used to re-arrange the order of the
display list.
.PP
Window items are an exception to the above rules. The underlying
window systems require them always to be drawn on top of other items.
In addition, the stacking order of window items
is not affected by any of the canvas widget commands; you must use
the Tk \fBraise\fR command and \fBlower\fR command instead.
.SH "ITEM IDS AND TAGS"
.PP
Items in a canvas widget may be named in either of two ways:
by id or by tag.
Each item has a unique identifying number, which is assigned to
that item when it is created. The id of an item never changes
and id numbers are never re-used within the lifetime of a
canvas widget.
.PP
Each item may also have any number of \fItags\fR associated
with it. A tag is just a string of characters, and it may
take any form except that of an integer.
For example,
.QW x123
is OK but
.QW 123
is not.
The same tag may be associated with many different items.
This is commonly done to group items in various interesting
ways; for example, all selected items might be given the tag
.QW selected .
.PP
The tag \fBall\fR is implicitly associated with every item
in the canvas; it may be used to invoke operations on
all the items in the canvas.
.PP
The tag \fBcurrent\fR is managed automatically by Tk;
it applies to the \fIcurrent item\fR, which is the
topmost item whose drawn area covers the position of
the mouse cursor (different item types interpret this in varying ways; see the
individual item type documentation for details).







|












|



|



|



|


|

|




|


|

|











|








|



















|



|





|




|








|



|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
Specifies a boolean value that indicates whether or not it should be
allowable to set the canvas's view outside the region defined by the
\fBscrollRegion\fR argument.
Defaults to true, which means that the view will
be constrained within the scroll region.
.OP \-height height Height
Specifies a desired window height that the canvas widget should request from
its geometry manager.  The value may be specified in any
of the forms described in the \fBCOORDINATES\fR section below.
.OP \-scrollregion scrollRegion ScrollRegion
Specifies a list with four coordinates describing the left, top, right, and
bottom coordinates of a rectangular region.
This region is used for scrolling purposes and is considered to be
the boundary of the information in the canvas.
Each of the coordinates may be specified
in any of the forms given in the \fBCOORDINATES\fR section below.
.OP \-state state State
Modifies the default state of the canvas where \fIstate\fR may be set to
one of: \fBnormal\fR, \fBdisabled\fR, or \fBhidden\fR. Individual canvas
objects all have their own state option which may override the default
state.  Many options can take separate specifications such that the
appearance of the item can be different in different situations. The
options that start with \fBactive\fR control the appearance when the mouse
pointer is over it, while the option starting with \fBdisabled\fR controls
the appearance when the state is disabled.  Canvas items which are
\fBdisabled\fR will not react to canvas bindings.
.OP \-width width width
Specifies a desired window width that the canvas widget should request from
its geometry manager.  The value may be specified in any
of the forms described in the \fBCOORDINATES\fR section below.
.OP \-xscrollincrement xScrollIncrement ScrollIncrement
Specifies an increment for horizontal scrolling, in any of the usual forms
permitted for screen distances.  If the value of this option is greater
than zero, the horizontal view in the window will be constrained so that
the canvas x coordinate at the left edge of the window is always an even
multiple of \fBxScrollIncrement\fR;  furthermore, the units for scrolling
(e.g., the change in view when the left and right arrows of a scrollbar
are selected) will also be \fBxScrollIncrement\fR.  If the value of
this option is less than or equal to zero, then horizontal scrolling
is unconstrained.
.OP \-yscrollincrement yScrollIncrement ScrollIncrement
Specifies an increment for vertical scrolling, in any of the usual forms
permitted for screen distances.  If the value of this option is greater
than zero, the vertical view in the window will be constrained so that
the canvas y coordinate at the top edge of the window is always an even
multiple of \fByScrollIncrement\fR;  furthermore, the units for scrolling
(e.g., the change in view when the top and bottom arrows of a scrollbar
are selected) will also be \fByScrollIncrement\fR.  If the value of
this option is less than or equal to zero, then vertical scrolling
is unconstrained.
.BE
.SH INTRODUCTION
.PP
The \fBcanvas\fR command creates a new window (given
by the \fIpathName\fR argument) and makes it into a canvas widget.
Additional options, described above, may be specified on the
command line or in the option database
to configure aspects of the canvas such as its colors and 3-D relief.
The \fBcanvas\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
Canvas widgets implement structured graphics.
A canvas displays any number of \fIitems\fR, which may be things like
rectangles, circles, lines, and text.
Items may be manipulated (e.g. moved or re-colored) and commands may
be associated with items in much the same way that the \fBbind\fR
command allows commands to be bound to widgets.  For example,
a particular command may be associated with the <Button-1> event
so that the command is invoked whenever button 1 is pressed with
the mouse cursor over an item.
This means that items in a canvas can have behaviors defined by
the Tcl scripts bound to them.
.SH "DISPLAY LIST"
.PP
The items in a canvas are ordered for purposes of display,
with the first item in the display list being displayed
first, followed by the next item in the list, and so on.
Items later in the display list obscure those that are
earlier in the display list and are sometimes referred to as being
.QW "on top"
of earlier items.
When a new item is created it is placed at the end of the
display list, on top of everything else.
Widget commands may be used to re-arrange the order of the
display list.
.PP
Window items are an exception to the above rules.  The underlying
window systems require them always to be drawn on top of other items.
In addition, the stacking order of window items
is not affected by any of the canvas widget commands; you must use
the \fBraise\fR and \fBlower\fR Tk commands instead.
.SH "ITEM IDS AND TAGS"
.PP
Items in a canvas widget may be named in either of two ways:
by id or by tag.
Each item has a unique identifying number, which is assigned to
that item when it is created.  The id of an item never changes
and id numbers are never re-used within the lifetime of a
canvas widget.
.PP
Each item may also have any number of \fItags\fR associated
with it.  A tag is just a string of characters, and it may
take any form except that of an integer.
For example,
.QW x123
is OK but
.QW 123
is not.
The same tag may be associated with many different items.
This is commonly done to group items in various interesting
ways;  for example, all selected items might be given the tag
.QW selected .
.PP
The tag \fBall\fR is implicitly associated with every item
in the canvas;  it may be used to invoke operations on
all the items in the canvas.
.PP
The tag \fBcurrent\fR is managed automatically by Tk;
it applies to the \fIcurrent item\fR, which is the
topmost item whose drawn area covers the position of
the mouse cursor (different item types interpret this in varying ways; see the
individual item type documentation for details).
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
.PP
\fItagOrId\fR may contain a logical expressions of
tags by using operators:
.QW \fB&&\fR ,
.QW \fB||\fR ,
.QW \fB^\fR ,
.QW \fB!\fR ,
and parenthesized subexpressions. For example:
.CS
      .c find withtag {(a&&!b)||(!a&&b)}
.CE
or equivalently:
.CS
      .c find withtag {a^b}
.CE
will find only those items with either
.QW a
or
.QW b
tags, but not both.
.PP
Some widget commands only operate on a single item at a
time; if \fItagOrId\fR is specified in a way that
names multiple items, then the normal behavior is for
the command to use the first (lowest) of these items in
the display list that is suitable for the command.
Exceptions are noted in the widget command descriptions
below.
.SH "COORDINATES"
.PP
All coordinates related to canvases are stored as floating-point
numbers.
Coordinates and distances are specified in screen units,
which are floating-point numbers optionally followed
by one of several letters.
If no letter is supplied then the distance is in pixels.
If the letter is \fBm\fR then the distance is in millimeters on
the screen; if it is \fBc\fR then the distance is in centimeters;
\fBi\fR means inches, and \fBp\fR means printers points (1/72 inch).
Larger y-coordinates refer to points lower on the screen; larger
x-coordinates refer to points farther to the right.
Coordinates can be specified either as an even number of parameters,
or as a single list parameter containing an even number of x and y
coordinate values.
.SS TRANSFORMATIONS
.PP
Normally the origin of the canvas coordinate system is at the
upper-left corner of the window containing the canvas.
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands; this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved, scaled
.VS "8.7, TIP164"
or rotated
.VE "8.7, TIP164"
using widget commands
described below.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area. However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and
window border (as controlled by the \fB\-borderwidth\fR option) must
be taken into account before you get to the visible area of the
canvas.
.SH "INDICES"
.PP
Text items support the notion of an \fIindex\fR for identifying
particular positions within the item.
In a similar fashion, line and polygon items support \fIindex\fR for
identifying, inserting and deleting subsets of their coordinates.
Indices are used for commands such as inserting or deleting
a range of characters or coordinates, and setting the insertion
cursor position. An index may be specified in any of a number
of ways, and different types of items may support different forms
for specifying indices.
Text items support the following forms for an index; if you
define new types of text-like items, it would be advisable to
support as many of these forms as practical.
Note that it is possible to refer to the character just after
the last one in the text item; this is necessary for such
tasks as inserting new text at the end of the item.
Lines and Polygons do not support the insertion cursor
and the selection. Their indices are supposed to be even
always, because coordinates always appear in pairs.
.TP 10
\fInumber\fR
.
A decimal number giving the position of the desired character
within the text item.
0 refers to the first character, 1 to the next character, and
so on. If indexes are odd for lines and polygons, they will be
automatically decremented by one.
A number less than 0 is treated as if it were zero, and a
number greater than the length of the text item is treated
as if it were equal to the length of the text item. For
polygons, numbers less than 0 or greater than the length
of the coordinate list will be adjusted by adding or subtracting
the length until the result is between zero and the length,
inclusive.
.TP 10
\fBend\fR
.
Refers to the character or coordinate just after the last one
in the item (same as the number of characters or coordinates
in the item).
.TP 10
\fBinsert\fR
.
Refers to the character just before which the insertion cursor
is drawn in this item. Not valid for lines and polygons.
.TP 10
\fBsel.first\fR
.
Refers to the first selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fBsel.last\fR
.
Refers to the last selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fB@\fIx,y\fR
.
Refers to the character or coordinate at the point given by \fIx\fR and
\fIy\fR, where \fIx\fR and \fIy\fR are specified in the coordinate
system of the canvas.
If \fIx\fR and \fIy\fR lie outside the coordinates covered by the
text item, then they refer to the first or last character in the
line that is closest to the given point.
.SH "DASH PATTERNS"
.PP
Many items support the notion of a dash pattern for outlines.
.PP
The first possible syntax is a list of integers. Each element
represents the number of pixels of a line segment. Only the odd
segments are drawn using the
.QW outline
color. The other segments are drawn transparent.
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:
.PP
.CS
\-dash .     \(-> \-dash {2 4}
\-dash -     \(-> \-dash {6 4}
\-dash -.    \(-> \-dash {6 4 2 4}
\-dash -..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}
.CE
.PP
The main difference of this syntax with the previous is that it
is shape-conserving. This means that all values in the dash
list will be multiplied by the line width before display. This
assures that
.QW .
will always be displayed as a dot and
.QW -
always as a dash regardless of the line width.
.PP
On systems which support only a limited set of dash patterns, the dash
pattern will be displayed as the closest dash pattern that is available.
For example, on Windows only the first 4 of the above examples are
available. The last 2 examples will be displayed identically to the first
one.
.SH "WIDGET COMMAND"
.PP
The \fBcanvas\fR command creates a new Tcl command whose
name is \fIpathName\fR. This
command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
command has no effect.
This command returns an empty string as result.
\fISearchSpec\fR and \fIarg\fR's may take any of the following
forms:
.RS
.TP
\fBabove \fItagOrId\fR
.
Selects the item just after (above) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the last (topmost)
of these items in the display list is used.
.TP
\fBall\fR
.
Selects all the items in the canvas.
.TP
\fBbelow \fItagOrId\fR
.
Selects the item just before (below) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the first (lowest)
of these items in the display list is used.
.TP
\fBclosest \fIx y \fR?\fIhalo\fR? ?\fIstart\fR?
.
Selects the item closest to the point given by \fIx\fR and \fIy\fR.
If more than one item is at the same closest distance (e.g. two
items overlap the point), then the top-most of these items (the
last one in the display list) is used.
If \fIhalo\fR is specified, then it must be a non-negative
value.
Any item closer than \fIhalo\fR to the point is considered to
overlap it.
The \fIstart\fR argument may be used to step circularly through
all the closest items.
If \fIstart\fR is specified, it names an item using a tag or id
(if by tag, it selects the first item in the display list with
the given tag).
Instead of selecting the topmost closest item, this form will
select the topmost closest item that is below \fIstart\fR in
the display list; if no such item exists, then the selection
behaves as if the \fIstart\fR argument had not been specified.
.TP
\fBenclosed\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR
.
Selects all the items completely enclosed within the rectangular
region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBoverlapping\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR
.
Selects all the items that overlap or are enclosed within the
rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR,
and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBwithtag \fItagOrId\fR
.
Selects all the items given by \fItagOrId\fR.
.RE
.TP
\fIpathName \fBbbox \fItagOrId\fR ?\fItagOrId tagOrId ...\fR?
.
Returns a list with four elements giving an approximate bounding box
for all the items named by the \fItagOrId\fR arguments.
The list has the form
.QW "\fIx1 y1 x2 y2\fR"
such that the drawn
areas of all the named elements are within the region bounded by
\fIx1\fR on the left, \fIx2\fR on the right, \fIy1\fR on the top,
and \fIy2\fR on the bottom.
The return value may overestimate the actual bounding box by
a few pixels.
If no items match any of the \fItagOrId\fR arguments or if the
matching items have empty bounding boxes (i.e. they have nothing
to display)
then an empty string is returned.
.TP
\fIpathName \fBbind \fItagOrId\fR ?\fIsequence\fR? ?\fIcommand\fR?
.
This command associates \fIcommand\fR with all the items given by
\fItagOrId\fR such that whenever the event sequence given by
\fIsequence\fR occurs for one of the items the command will
be invoked.
This widget command is similar to the \fBbind\fR command except that
it operates on items in a canvas rather than entire widgets.
See the \fBbind\fR manual entry for complete details







|














|














|

|










|




|
<
<
<
<
|





|















|



|






<








|





<





<




<




<




<


















|



<


|
|
|










|





|




|

|

|





|
<













<






<



<






<















|



<


|



<



|



<




<
















<







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223




224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275

276
277
278
279

280
281
282
283

284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365

366
367
368

369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393

394
395
396
397
398
399

400
401
402
403
404
405
406

407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
.PP
\fItagOrId\fR may contain a logical expressions of
tags by using operators:
.QW \fB&&\fR ,
.QW \fB||\fR ,
.QW \fB^\fR ,
.QW \fB!\fR ,
and parenthesized subexpressions.  For example:
.CS
      .c find withtag {(a&&!b)||(!a&&b)}
.CE
or equivalently:
.CS
      .c find withtag {a^b}
.CE
will find only those items with either
.QW a
or
.QW b
tags, but not both.
.PP
Some widget commands only operate on a single item at a
time;  if \fItagOrId\fR is specified in a way that
names multiple items, then the normal behavior is for
the command to use the first (lowest) of these items in
the display list that is suitable for the command.
Exceptions are noted in the widget command descriptions
below.
.SH "COORDINATES"
.PP
All coordinates related to canvases are stored as floating-point
numbers.
Coordinates and distances are specified in screen units,
which are floating-point numbers optionally followed
by one of several letters.
If no letter is supplied then the distance is in pixels.
If the letter is \fBm\fR then the distance is in millimeters on
the screen;  if it is \fBc\fR then the distance is in centimeters;
\fBi\fR means inches, and \fBp\fR means printers points (1/72 inch).
Larger y-coordinates refer to points lower on the screen;  larger
x-coordinates refer to points farther to the right.
Coordinates can be specified either as an even number of parameters,
or as a single list parameter containing an even number of x and y
coordinate values.
.SS TRANSFORMATIONS
.PP
Normally the origin of the canvas coordinate system is at the
upper-left corner of the window containing the canvas.
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands;  this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved or scaled using widget commands




described below, but they may not be rotated.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area.  However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and
window border (as controlled by the \fB\-borderwidth\fR option) must
be taken into account before you get to the visible area of the
canvas.
.SH "INDICES"
.PP
Text items support the notion of an \fIindex\fR for identifying
particular positions within the item.
In a similar fashion, line and polygon items support \fIindex\fR for
identifying, inserting and deleting subsets of their coordinates.
Indices are used for commands such as inserting or deleting
a range of characters or coordinates, and setting the insertion
cursor position. An index may be specified in any of a number
of ways, and different types of items may support different forms
for specifying indices.
Text items support the following forms for an index;  if you
define new types of text-like items, it would be advisable to
support as many of these forms as practical.
Note that it is possible to refer to the character just after
the last one in the text item;  this is necessary for such
tasks as inserting new text at the end of the item.
Lines and Polygons do not support the insertion cursor
and the selection. Their indices are supposed to be even
always, because coordinates always appear in pairs.
.TP 10
\fInumber\fR

A decimal number giving the position of the desired character
within the text item.
0 refers to the first character, 1 to the next character, and
so on. If indexes are odd for lines and polygons, they will be
automatically decremented by one.
A number less than 0 is treated as if it were zero, and a
number greater than the length of the text item is treated
as if it were equal to the length of the text item. For
polygons, numbers less than 0 or greater then the length
of the coordinate list will be adjusted by adding or subtracting
the length until the result is between zero and the length,
inclusive.
.TP 10
\fBend\fR

Refers to the character or coordinate just after the last one
in the item (same as the number of characters or coordinates
in the item).
.TP 10
\fBinsert\fR

Refers to the character just before which the insertion cursor
is drawn in this item. Not valid for lines and polygons.
.TP 10
\fBsel.first\fR

Refers to the first selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fBsel.last\fR

Refers to the last selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fB@\fIx,y\fR

Refers to the character or coordinate at the point given by \fIx\fR and
\fIy\fR, where \fIx\fR and \fIy\fR are specified in the coordinate
system of the canvas.
If \fIx\fR and \fIy\fR lie outside the coordinates covered by the
text item, then they refer to the first or last character in the
line that is closest to the given point.
.SH "DASH PATTERNS"
.PP
Many items support the notion of a dash pattern for outlines.
.PP
The first possible syntax is a list of integers. Each element
represents the number of pixels of a line segment. Only the odd
segments are drawn using the
.QW outline
color. The other segments are drawn transparent.
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,\-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:

.CS
\-dash .     \(-> \-dash {2 4}
\-dash \-     \(-> \-dash {6 4}
\-dash \-.    \(-> \-dash {6 4 2 4}
\-dash \-..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}
.CE
.PP
The main difference of this syntax with the previous is that it
is shape-conserving. This means that all values in the dash
list will be multiplied by the line width before display. This
assures that
.QW .
will always be displayed as a dot and
.QW \-
always as a dash regardless of the line width.
.PP
On systems which support only a limited set of dash patterns, the dash
pattern will be displayed as the closest dash pattern that is available.
For example, on Windows only the first 4 of the above examples are
available.  The last 2 examples will be displayed identically to the first
one.
.SH "WIDGET COMMAND"
.PP
The \fBcanvas\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg arg ...\fR?

For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
command has no effect.
This command returns an empty string as result.
\fISearchSpec\fR and \fIarg\fR's may take any of the following
forms:
.RS
.TP
\fBabove \fItagOrId\fR

Selects the item just after (above) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the last (topmost)
of these items in the display list is used.
.TP
\fBall\fR

Selects all the items in the canvas.
.TP
\fBbelow \fItagOrId\fR

Selects the item just before (below) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the first (lowest)
of these items in the display list is used.
.TP
\fBclosest \fIx y \fR?\fIhalo\fR? ?\fIstart\fR?

Selects the item closest to the point given by \fIx\fR and \fIy\fR.
If more than one item is at the same closest distance (e.g. two
items overlap the point), then the top-most of these items (the
last one in the display list) is used.
If \fIhalo\fR is specified, then it must be a non-negative
value.
Any item closer than \fIhalo\fR to the point is considered to
overlap it.
The \fIstart\fR argument may be used to step circularly through
all the closest items.
If \fIstart\fR is specified, it names an item using a tag or id
(if by tag, it selects the first item in the display list with
the given tag).
Instead of selecting the topmost closest item, this form will
select the topmost closest item that is below \fIstart\fR in
the display list;  if no such item exists, then the selection
behaves as if the \fIstart\fR argument had not been specified.
.TP
\fBenclosed\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR

Selects all the items completely enclosed within the rectangular
region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
\fIX1\fR must be no greater then \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBoverlapping\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR

Selects all the items that overlap or are enclosed within the
rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR,
and \fIy2\fR.
\fIX1\fR must be no greater then \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBwithtag \fItagOrId\fR

Selects all the items given by \fItagOrId\fR.
.RE
.TP
\fIpathName \fBbbox \fItagOrId\fR ?\fItagOrId tagOrId ...\fR?

Returns a list with four elements giving an approximate bounding box
for all the items named by the \fItagOrId\fR arguments.
The list has the form
.QW "\fIx1 y1 x2 y2\fR"
such that the drawn
areas of all the named elements are within the region bounded by
\fIx1\fR on the left, \fIx2\fR on the right, \fIy1\fR on the top,
and \fIy2\fR on the bottom.
The return value may overestimate the actual bounding box by
a few pixels.
If no items match any of the \fItagOrId\fR arguments or if the
matching items have empty bounding boxes (i.e. they have nothing
to display)
then an empty string is returned.
.TP
\fIpathName \fBbind \fItagOrId\fR ?\fIsequence\fR? ?\fIcommand\fR?

This command associates \fIcommand\fR with all the items given by
\fItagOrId\fR such that whenever the event sequence given by
\fIsequence\fR occurs for one of the items the command will
be invoked.
This widget command is similar to the \fBbind\fR command except that
it operates on items in a canvas rather than entire widgets.
See the \fBbind\fR manual entry for complete details
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
If both \fIcommand\fR and \fIsequence\fR are omitted then the command
returns a list of all the sequences for which bindings have been
defined for \fItagOrId\fR.
.RS
.PP
The only events for which bindings may be specified are those related to
the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
\fBButton\fR, \fBMotion\fR, and \fBKey\fR) or virtual events.
The handling of events in canvases uses the current item defined in
\fBITEM IDS AND TAGS\fR above. \fBEnter\fR and \fBLeave\fR events
trigger for an
item when it becomes the current item or ceases to be the current item;
note that these events are different than \fBEnter\fR and \fBLeave\fR
events for windows. Mouse-related events are directed to the current
item, if any. Keyboard-related events are directed to the focus item, if
any (see the \fBfocus\fR widget command below for more on this). If a
virtual event is used in a binding, that binding can trigger only if the
virtual event is defined by an underlying mouse-related or
keyboard-related event.
.PP
It is possible for multiple bindings to match a particular event.
This could occur, for example, if one binding is associated with the
item's id and another is associated with one of the item's tags.







|

|



|
|
|







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
If both \fIcommand\fR and \fIsequence\fR are omitted then the command
returns a list of all the sequences for which bindings have been
defined for \fItagOrId\fR.
.RS
.PP
The only events for which bindings may be specified are those related to
the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
\fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR) or virtual events.
The handling of events in canvases uses the current item defined in
\fBITEM IDS AND TAGS\fR above.  \fBEnter\fR and \fBLeave\fR events
trigger for an
item when it becomes the current item or ceases to be the current item;
note that these events are different than \fBEnter\fR and \fBLeave\fR
events for windows.  Mouse-related events are directed to the current
item, if any.  Keyboard-related events are directed to the focus item, if
any (see the \fBfocus\fR widget command below for more on this).  If a
virtual event is used in a binding, that binding can trigger only if the
virtual event is defined by an underlying mouse-related or
keyboard-related event.
.PP
It is possible for multiple bindings to match a particular event.
This could occur, for example, if one binding is associated with the
item's id and another is associated with one of the item's tags.
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
command, then they are invoked in addition to bindings created for
the canvas's items using the \fBbind\fR widget command.
The bindings for items will be invoked before any of the bindings
for the window as a whole.
.RE
.TP
\fIpathName \fBcanvasx \fIscreenx\fR ?\fIgridspacing\fR?
.
Given a window x-coordinate in the canvas \fIscreenx\fR, this command returns
the canvas x-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.TP
\fIpathName \fBcanvasy \fIscreeny\fR ?\fIgridspacing\fR?
.
Given a window y-coordinate in the canvas \fIscreeny\fR this command returns
the canvas y-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.TP
\fIpathName \fBconfigure ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified). If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIx0 y0 ...\fR?
.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIcoordList\fR?
.
Query or modify the coordinates that define an item.
If no coordinates are specified, this command returns a list
whose elements are the coordinates of the item named by
\fItagOrId\fR.
If coordinates are specified, then they replace the current
coordinates for the named item.
If \fItagOrId\fR refers to multiple items, then
the first one in the display list is used.
.RS
.PP
Note that for rectangles, ovals and arcs the returned list of coordinates
has a fixed order, namely the left, top, right and bottom coordinates,
which may not be the order originally given. Also the coordinates are always
returned in screen units with no units (that is, in pixels). So if the
original coordinates were specified for instance in centimeters or inches,
the returned values will nevertheless be in pixels.
.RE
.TP
\fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR?
.TP
\fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR?
.
Create a new item in \fIpathName\fR of type \fItype\fR.
The exact format of the arguments after \fItype\fR depends
on \fItype\fR, but usually they consist of the coordinates for
one or more points, followed by specifications for zero or
more item options.
See the subsections on individual item types below for more
on the syntax of this command.
This command returns the id for the new item.
.TP
\fIpathName \fBdchars \fItagOrId first \fR?\fIlast\fR?
.
For each item given by \fItagOrId\fR, delete the characters, or coordinates,
in the range given by \fIfirst\fR and \fIlast\fR, inclusive.
If some of the items given by \fItagOrId\fR do not support
indexing operations then they ignore this operation.
Text items interpret \fIfirst\fR and \fIlast\fR as indices to a character,
line and polygon items interpret them as indices to a coordinate (an x,y pair).
Indices are described in \fBINDICES\fR above.
If \fIlast\fR is omitted, it defaults to \fIfirst\fR.
This command returns an empty string.
.TP
\fIpathName \fBdelete \fR?\fItagOrId tagOrId ...\fR?
.
Delete each of the items given by each \fItagOrId\fR, and return
an empty string.
.TP
\fIpathName \fBdtag \fItagOrId \fR?\fItagToDelete\fR?
.
For each of the items given by \fItagOrId\fR, delete the
tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.
.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg ...\fR?
.
This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.
.TP
\fIpathName \fBfocus \fR?\fItagOrId\fR?
.
Set the keyboard focus for the canvas widget to the item given by
\fItagOrId\fR.
If \fItagOrId\fR refers to several items, then the focus is set
to the first such item in the display list that supports the
insertion cursor.
If \fItagOrId\fR does not refer to any items, or if none of them
support the insertion cursor, then the focus is not changed.







<






<






<






<



|


|

|







<








<
<
<
<
<
<
<
<
<




<

|
|







<



|

|





<




<








|
<








<







480
481
482
483
484
485
486

487
488
489
490
491
492

493
494
495
496
497
498

499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
528









529
530
531
532

533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550
551
552
553

554
555
556
557

558
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
command, then they are invoked in addition to bindings created for
the canvas's items using the \fBbind\fR widget command.
The bindings for items will be invoked before any of the bindings
for the window as a whole.
.RE
.TP
\fIpathName \fBcanvasx \fIscreenx\fR ?\fIgridspacing\fR?

Given a window x-coordinate in the canvas \fIscreenx\fR, this command returns
the canvas x-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.TP
\fIpathName \fBcanvasy \fIscreeny\fR ?\fIgridspacing\fR?

Given a window y-coordinate in the canvas \fIscreeny\fR this command returns
the canvas y-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.TP
\fIpathName \fBconfigure ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIx0 y0 ...\fR?
.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIcoordList\fR?

Query or modify the coordinates that define an item.
If no coordinates are specified, this command returns a list
whose elements are the coordinates of the item named by
\fItagOrId\fR.
If coordinates are specified, then they replace the current
coordinates for the named item.
If \fItagOrId\fR refers to multiple items, then
the first one in the display list is used.









.TP
\fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR?
.TP
\fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR?

Create a new item in \fIpathName\fR of type \fItype\fR.
The exact format of the arguments after \fBtype\fR depends
on \fBtype\fR, but usually they consist of the coordinates for
one or more points, followed by specifications for zero or
more item options.
See the subsections on individual item types below for more
on the syntax of this command.
This command returns the id for the new item.
.TP
\fIpathName \fBdchars \fItagOrId first \fR?\fIlast\fR?

For each item given by \fItagOrId\fR, delete the characters, or coordinates,
in the range given by \fIfirst\fR and \fIlast\fR, inclusive.
If some of the items given by \fItagOrId\fR do not support
indexing operations then they ignore dchars.
Text items interpret \fIfirst\fR and \fIlast\fR as indices to a character,
line and polygon items interpret them indices to a coordinate (an x,y pair).
Indices are described in \fBINDICES\fR above.
If \fIlast\fR is omitted, it defaults to \fIfirst\fR.
This command returns an empty string.
.TP
\fIpathName \fBdelete \fR?\fItagOrId tagOrId ...\fR?

Delete each of the items given by each \fItagOrId\fR, and return
an empty string.
.TP
\fIpathName \fBdtag \fItagOrId \fR?\fItagToDelete\fR?

For each of the items given by \fItagOrId\fR, delete the
tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.
.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg arg ...\fR?

This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.
.TP
\fIpathName \fBfocus \fR?\fItagOrId\fR?

Set the keyboard focus for the canvas widget to the item given by
\fItagOrId\fR.
If \fItagOrId\fR refers to several items, then the focus is set
to the first such item in the display list that supports the
insertion cursor.
If \fItagOrId\fR does not refer to any items, or if none of them
support the insertion cursor, then the focus is not changed.
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153



1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193



1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260


1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313

1314




1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389


1390
1391


1392
1393


1394
1395


1396
1397


1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483









1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541









1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577


1578
1579


1580
1581


1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
within the canvas.
In most cases it is advisable to follow the \fBfocus\fR widget
command with the \fBfocus\fR command to set the focus window to
the canvas (if it was not there already).
.RE
.TP
\fIpathName \fBgettags\fR \fItagOrId\fR
.
Return a list whose elements are the tags associated with the
item given by \fItagOrId\fR.
If \fItagOrId\fR refers to more than one item, then the tags
are returned from the first such item in the display list.
If \fItagOrId\fR does not refer to any items, or if the item
contains no tags, then an empty string is returned.
.TP
\fIpathName \fBicursor \fItagOrId index\fR
.
Set the position of the insertion cursor for the item(s) given by \fItagOrId\fR
to just before the character whose position is given by \fIindex\fR.
If some or all of the items given by \fItagOrId\fR do not support
an insertion cursor then this command has no effect on them.
See \fBINDICES\fR above for a description of the
legal forms for \fIindex\fR.
Note: the insertion cursor is only displayed in an item if
that item currently has the keyboard focus (see the \fBfocus\fR widget
command, above), but the cursor position may
be set even when the item does not have the focus.
This command returns an empty string.
.TP
\fIpathName \fBimage \fIimagename\fR ?\fIsubsample\fR? ?\fIzoom\fR?
.
Draw the canvas into the Tk photo image named \fIimagename\fR. If a \fB-scrollregion\fR
has been defined then this will be the boundaries of the canvas region drawn and the
final size of the photo image. Otherwise the widget width and height with an origin
of 0,0 will be the size of the canvas region drawn and the final size of the photo
image. Optionally an integer \fIsubsample\fR factor may be given and the photo image
will be reduced in size. In addition to the \fIsubsample\fR an integer \fIzoom\fR
factor can also be given and the photo image will be enlarged. The image background
will be filled with the canvas background colour. The canvas widget does not need to
be mapped for this widget command to work, but at least one of it's ancestors must be
mapped.
This command returns an empty string.
.TP
\fIpathName \fBimove \fItagOrId index x y\fR
.
This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.
.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
Text items interpret \fIindex\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
The return value is guaranteed to lie between 0 and the number
of characters, or coordinates, within the item, inclusive.
If \fItagOrId\fR refers to multiple items, then the index
is processed in the first of these items that supports indexing
operations (in display list order).
.TP
\fIpathName \fBinsert \fItagOrId beforeThis string\fR
.
For each of the items given by \fItagOrId\fR, if the item supports
text or coordinate, insertion then \fIstring\fR is inserted into the item's
text just before the character, or coordinate, whose index is \fIbeforeThis\fR.
Text items interpret \fIbeforeThis\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
For lines and polygons the \fIstring\fR must be a valid coordinate
sequence.
See \fBINDICES\fR above for information about the forms allowed
for \fIbeforeThis\fR.
This command returns an empty string.
.TP
\fIpathName \fBitemcget\fR \fItagOrId\fR \fIoption\fR
.
Returns the current value of the configuration option for the
item given by \fItagOrId\fR whose name is \fIoption\fR.
This command is similar to the \fBcget\fR widget command except that
it applies to a particular item rather than the widget as a whole.
\fIOption\fR may have any of the values accepted by the \fBcreate\fR
widget command when the item was created.
If \fItagOrId\fR is a tag that refers to more than one item,
the first (lowest) such item is used.
.TP
\fIpathName \fBitemconfigure \fItagOrId\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fBconfigure\fR widget command except
that it modifies item-specific options for the items given by
\fItagOrId\fR instead of modifying options for the overall
canvas widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the first item given by \fItagOrId\fR
(see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified). If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s) in
each of the items given by \fItagOrId\fR; in
this case the command returns an empty string.
The \fIoption\fRs and \fIvalue\fRs are the same as those permissible
in the \fBcreate\fR widget command when the item(s) were created;
see the sections describing individual item types below for details
on the legal options.
.TP
\fIpathName \fBlower \fItagOrId \fR?\fIbelowThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just before the item given by \fIbelowThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIBelowThis\fR is a tag or id; if it refers to more than one
item then the first (lowest) of these items in the display list is used
as the destination location for the moved items.
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
This command returns an empty string.
.TP
\fIpathName \fBmove \fItagOrId xAmount yAmount\fR
.
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR
.
Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair (the upper-left corner of the
bounding box) of the first item (the lowest in the display list) with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.
.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.
If the interpreter that owns the canvas is marked as safe, the operation
will fail because safe interpreters are not allowed to write files.
If the \fB\-channel\fR option is specified, the argument denotes the name
of a channel already opened for writing. The Postscript is written to
that channel, and the channel is left open for further writing at the end
of the operation.
The Postscript is created in Encapsulated Postscript form using
version 3.0 of the Document Structuring Conventions.
Note: by default Postscript is only generated for information that
appears in the canvas's window on the screen. If the canvas is
freshly created it may still have its initial size of 1x1 pixel
so nothing will appear in the Postscript. To get around this problem
either invoke the \fBupdate\fR command to wait for the canvas window
to reach its final size, or else use the \fB\-width\fR and \fB\-height\fR
options to specify the area of the canvas to print.
The \fIoption\fR\-\fIvalue\fR argument pairs provide additional
information to control the generation of Postscript. The following
options are supported:
.RS
.TP
\fB\-channel \fIchannelName\fR
.
Specifies the name of the channel to which to write the Postscript.
If this option and the \fB\-file\fR option are
not specified then the Postscript is returned as the
result of the command.
.TP
\fB\-colormap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a color mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of Postscript
code to set a particular color value (e.g.
.QW "\fB1.0 1.0 0.0 setrgbcolor\fR" ).
When outputting color information in the Postscript, Tk checks
to see if there is an element of \fIvarName\fR with the same
name as the color.
If so, Tk uses the value of the element as the Postscript command
to set the color.
If this option has not been specified, or if there is no entry
in \fIvarName\fR for a given color, then Tk uses the red, green,
and blue intensities from the X color.
.TP
\fB\-colormode \fImode\fR
.
Specifies how to output color information. \fIMode\fR must be either
\fBcolor\fR (for full color output), \fBgray\fR (convert all colors
to their gray-scale equivalents) or \fBmono\fR (convert all colors
to black or white).
.TP
\fB\-file \fIfileName\fR
.
Specifies the name of the file in which to write the Postscript.
If this option and the \fB\-channel\fR option are
not specified then the Postscript is returned as the
result of the command.
.TP
\fB\-fontmap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a font mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of a Tcl list with
two elements, which are the name and point size of a Postscript font.
When outputting Postscript commands for a particular font, Tk
checks to see if \fIvarName\fR contains an element with the same
name as the font.
If there is such an element, then the font information contained in
that element is used in the Postscript.
Otherwise Tk attempts to guess what Postscript font to use.
Tk's guesses generally only work for well-known fonts such as
Times and Helvetica and Courier, and only if the X font name does not
omit any dashes up through the point size.
For example, \fB\-*\-Courier\-Bold\-R\-Normal\-\-*\-120\-*\fR will work but
\fB*Courier\-Bold\-R\-Normal*120*\fR will not; Tk needs the dashes to
parse the font name).
.TP
\fB\-height \fIsize\fR
.
Specifies the height of the area of the canvas to print.
Defaults to the height of the canvas window.
.TP
\fB\-pageanchor \fIanchor\fR
.
Specifies which point of the printed area of the canvas should appear over
the positioning point on the page (which is given by the \fB\-pagex\fR
and \fB\-pagey\fR options).
For example, \fB\-pageanchor n\fR means that the top center of the
area of the canvas being printed (as it appears in the canvas window)
should be over the positioning point. Defaults to \fBcenter\fR.
.TP
\fB\-pageheight \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR high on the Postscript page.
\fISize\fR consists of a floating-point number followed by
\fBc\fR for centimeters, \fBi\fR for inches, \fBm\fR for millimeters,
or \fBp\fR or nothing for printer's points (1/72 inch).
Defaults to the height of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).
.TP
\fB\-pagewidth \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR wide on the Postscript page.
\fISize\fR has the same form as for \fB\-pageheight\fR.
Defaults to the width of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).
.TP
\fB\-pagex \fIposition\fR
.
\fIPosition\fR gives the x-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagey\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.TP
\fB\-pagey \fIposition\fR
.
\fIPosition\fR gives the y-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagex\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.TP
\fB\-rotate \fIboolean\fR
.
\fIBoolean\fR specifies whether the printed area is to be rotated 90
degrees.
In non-rotated output the x-axis of the printed area runs along
the short dimension of the page
.PQ portrait " orientation" ;
in rotated output the x-axis runs along the long dimension of the page
.PQ landscape " orientation" .
Defaults to non-rotated.
.TP
\fB\-width \fIsize\fR
.
Specifies the width of the area of the canvas to print.
Defaults to the width of the canvas window.
.TP
\fB\-x \fIposition\fR
.
Specifies the x-coordinate of the left edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the left edge of the window.
.TP
\fB\-y \fIposition\fR
.
Specifies the y-coordinate of the top edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the top edge of the window.
.RE
.TP
\fIpathName \fBraise \fItagOrId \fR?\fIaboveThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just after the item given by \fIaboveThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIAboveThis\fR is a tag or id; if it refers to more than one
item then the last (topmost) of these items in the display list is used
as the destination location for the moved items.
This command returns an empty string.
.RS
.PP
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.
.TP
\fIpathName \fBrotate \fItagOrId xOrigin yOrigin angle\fR
.VS "8.7, TIP164"
Rotate the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates
anticlockwise, in degrees. (Negative values rotate clockwise.)
This command returns an empty string.
.RS
.PP
Implementation note: not all item types work the same with rotations. In
particular,\fB bitmap\fR,\fB image\fR,\fB text\fR and\fB window\fR items only
rotate their anchor points and do not rotate the items themselves about those
points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a
computed center point instead of moving the bounding box coordinates directly.
.PP
Some items (currently \fBarc\fR and\fB text\fR) have angles in their options;
this command \fIdoes not\fR affect those options.
.RE
.VE "8.7, TIP164"
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale
factors for x- and y-coordinates, respectively (a scale factor of
1.0 implies no change to that coordinate).
For each of the points defining each item, the x-coordinate is
adjusted to change the distance from \fIxOrigin\fR by a factor
of \fIxScale\fR.
Similarly, each y-coordinate is adjusted to change the distance
from \fIyOrigin\fR by a factor of \fIyScale\fR.
This command returns an empty string.
.RS
.PP
Note that some items have only a single pair of coordinates (e.g., text,
images and windows) and so scaling of them by this command can only move them
around.
.RE
.TP
\fIpathName \fBscan\fR \fIoption args\fR
.
This command is used to implement scanning on canvases. It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.
Records \fIx\fR and \fIy\fR and the canvas's current view; used
in conjunction with later \fBscan dragto\fR commands.
Typically this command is associated with a mouse button press in
the widget and \fIx\fR and \fIy\fR are the coordinates of the
mouse. It returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx y ?gain?\fR
.
This command computes the difference between its \fIx\fR and \fIy\fR
arguments (which are typically mouse coordinates) and the \fIx\fR and
\fIy\fR arguments to the last \fBscan mark\fR command for the widget.
It then adjusts the view by \fIgain\fR times the
difference in coordinates, where \fIgain\fR defaults to 10.
This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the canvas at high speed through its window. The return
value is an empty string.
.RE
.TP
\fIpathName \fBselect \fIoption\fR ?\fItagOrId arg\fR?
.
Manipulates the selection in one of several ways, depending on
\fIoption\fR.
The command may take any of the forms described below.
In all of the descriptions below, \fItagOrId\fR must refer to
an item that supports indexing and selection; if it refers to
multiple items then the first of
these that supports indexing and the selection is used.
\fIIndex\fR gives a textual description of a position
within \fItagOrId\fR, as described in \fBINDICES\fR above.
.RS
.TP
\fIpathName \fBselect adjust \fItagOrId index\fR
.
Locate the end of the selection in \fItagOrId\fR nearest
to the character given by \fIindex\fR, and adjust that
end of the selection to be at \fIindex\fR (i.e. including
but not going beyond \fIindex\fR).
The other end of the selection is made the anchor point
for future \fBselect to\fR commands.
If the selection is not currently in \fItagOrId\fR then
this command behaves the same as the \fBselect to\fR widget
command.
Returns an empty string.
.TP
\fIpathName \fBselect clear\fR
.
Clear the selection if it is in this widget.
If the selection is not in this widget then the command
has no effect.
Returns an empty string.
.TP
\fIpathName \fBselect from \fItagOrId index\fR
.
Set the selection anchor point for the widget to be just
before the character
given by \fIindex\fR in the item given by \fItagOrId\fR.
This command does not change the selection; it just sets
the fixed end of the selection for future \fBselect to\fR
commands.
Returns an empty string.
.TP
\fIpathName \fBselect item\fR
.
Returns the id of the selected item, if the selection is in an
item in this canvas.
If the selection is not in this canvas then an empty string
is returned.
.TP
\fIpathName \fBselect to \fItagOrId index\fR
.
Set the selection to consist of those characters of \fItagOrId\fR
between the selection anchor point and
\fIindex\fR.
The new selection will include the character given by \fIindex\fR;
it will include the character given by the anchor point only if
\fIindex\fR is greater than or equal to the anchor point.
The anchor point is determined by the most recent \fBselect adjust\fR
or \fBselect from\fR command for this widget.
If the selection anchor point for the widget is not currently in
\fItagOrId\fR, then it is set to the same character given
by \fIindex\fR.
Returns an empty string.
.RE
.TP
\fIpathName \fBtype\fI tagOrId\fR
.
Returns the type of the item given by \fItagOrId\fR, such as
\fBrectangle\fR or \fBtext\fR.
If \fItagOrId\fR refers to more than one item, then the type
of the first item in the display list is returned.
If \fItagOrId\fR does not refer to any items at all then
an empty string is returned.
.TP
\fIpathName \fBxview \fR?\fIargs\fR?
.
This command is used to query and change the horizontal position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the canvas's area (as defined by the \fB\-scrollregion\fR option)
is off-screen to the left, the middle 40% is visible
in the window, and 40% of the canvas is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that \fIfraction\fR of the
total width of the canvas is off-screen to the left.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.



If \fIwhat is \fBpages\fR then the view
adjusts in units of nine-tenths the window's width.
If \fInumber\fR is negative then information farther to the left
becomes visible; if it is positive then information farther to the right
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
.RE
.TP
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the vertical span that is visible in the window.
For example, if the first element is .6 and the second element is 1.0,
the lowest 40% of the canvas's area (as defined by the \fB\-scrollregion\fR
option) is visible in the window.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview moveto\fI fraction\fR
.
Adjusts the view in the window so that \fIfraction\fR of the canvas's
area is off-screen to the top.
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.



If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible; if it is positive then lower information
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units
of the \fByScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's height otherwise.
.RE
.SH "OVERVIEW OF ITEM TYPES"
.PP
The sections below describe the various types of items supported
by canvas widgets. Each item type is characterized by two things:
first, the form of the \fBcreate\fR command used to create
instances of the type; and second, a set of configuration options
for items of that type, which may be used in the
\fBcreate\fR and \fBitemconfigure\fR widget commands.
Most items do not support indexing or selection or the commands
related to them, such as \fBindex\fR and \fBinsert\fR.
Where items do support these facilities, it is noted explicitly
in the descriptions below.
At present, text, line and polygon items provide this support.
For lines and polygons the indexing facility is used to manipulate
the coordinates of the item.
.SS "COMMON ITEM OPTIONS"
.PP
Many items share a common set of options. These options are
explained here, and then referred to be each widget type for brevity.
.TP
\fB\-anchor \fIanchorPos\fR
.
\fIAnchorPos\fR tells how to position the item relative to the
positioning point for the item; it may have any of the forms
accepted by \fBTk_GetAnchor\fR. For example, if \fIanchorPos\fR
is \fBcenter\fR then the item is centered on the point; if
\fIanchorPos\fR is \fBn\fR then the item will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.
.TP
\fB\-dash \fIpattern\fR
.TP
\fB\-activedash \fIpattern\fR
.TP
\fB\-disableddash \fIpattern\fR
.
This option specifies dash patterns for the normal, active
state, and disabled state of an item.
\fIpattern\fR may have any of the forms accepted by \fBTk_GetDash\fR.
If the dash options are omitted then the default is a solid outline.
See \fBDASH PATTERNS\fR for more information.
.TP
\fB\-dashoffset \fIoffset\fR
.
The starting \fIoffset\fR in pixels into the pattern provided by the
\fB\-dash\fR option. \fB\-dashoffset\fR is ignored if there is no
\fB\-dash\fR pattern. The \fIoffset\fR may have any of the forms described
in the \fBCOORDINATES\fR section above.
.TP
\fB\-fill \fIcolor\fR
.TP
\fB\-activefill \fIcolor\fR
.TP
\fB\-disabledfill \fIcolor\fR
.
Specifies the color to be used to fill item's area.
in its normal, active, and disabled states,
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.


For the line item, it specifies the color of the line drawn.
For the text item, it specifies the foreground color of the text.
If \fIcolor\fR is an empty string (the default for all canvas items
except line and text), then the item will not be filled.
.TP
\fB\-outline \fIcolor\fR
.TP
\fB\-activeoutline \fIcolor\fR
.TP
\fB\-disabledoutline \fIcolor\fR
.
This option specifies the color that should be used to draw the
outline of the item in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR is specified as an empty string then no outline is drawn
for the item.
.TP
\fB\-offset \fIoffset\fR
.
Specifies the offset of stipples. The offset value can be of the form
\fBx,y\fR or \fIside\fR, where side can be \fBn\fR, \fBne\fR, \fBe\fR,
\fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR. In the
first case the origin is the origin of the toplevel of the current window.
For the canvas itself and canvas objects the origin is the canvas origin,
but putting \fB#\fR in front of the coordinate pair indicates using the
toplevel origin instead. For canvas objects, the \fB\-offset\fR option is
used for stippling as well. For the line and polygon canvas items you can
also specify an index as argument, which connects the stipple origin to one
of the coordinate points of the line/polygon. Note that stipple offsets are
\fIonly supported on X11\fR; they are silently ignored on other platforms.
.TP
\fB\-outlinestipple \fIbitmap\fR
.TP
\fB\-activeoutlinestipple \fIbitmap\fR
.TP
\fB\-disabledoutlinestipple \fIbitmap\fR
.
This option specifies stipple patterns that should be used to draw the
outline of the item in its normal, active and disabled states.
Indicates that the outline for the item should be drawn with a stipple pattern;
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-outline\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then the outline is drawn
in a solid fashion.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.TP
\fB\-outlineoffset \fIoffset\fR
.
Specifies the offset of the stipple pattern used for outlines, in the same way
that the \fB\-outline\fR option controls fill stipples. (See the

\fB\-outline\fR option for a description of the syntax of \fIoffset\fR.)




.TP
\fB\-stipple \fIbitmap\fR
.TP
\fB\-activestipple \fIbitmap\fR
.TP
\fB\-disabledstipple \fIbitmap\fR
.
This option specifies stipple patterns that should be used to fill
the item in its normal, active and disabled states.
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-fill\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then filling is done
in a solid fashion.
For the text item, it affects the actual text.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.TP
\fB\-state \fIstate\fR
.
This allows an item to override the canvas widget's global \fIstate\fR
option. It takes the same values:
\fInormal\fR, \fIdisabled\fR or \fIhidden\fR.
.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the item.
\fITagList\fR consists of a list of tag names, which replace any
existing tags for the item. \fITagList\fR may be an empty list.
.TP
\fB\-width \fIoutlineWidth\fR
.TP
\fB\-activewidth \fIoutlineWidth\fR
.TP
\fB\-disabledwidth \fIoutlineWidth\fR
.
Specifies the width of the outline to be drawn around
the item's region, in its normal, active and disabled states.
\fIoutlineWidth\fR may be in any of the forms described in the
\fBCOORDINATES\fR section above.
If the \fB\-outline\fR option has been specified as an empty string then
this option has no effect. This option defaults to 1.0.
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by either the \fB\-start\fR and \fB\-extent\fR options or the \fB\-height\fR option)
and displayed in one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc (except when
\fB\-height\fR is specified - see below).
.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
.PP
The following standard options are supported by arcs:
.DS
.ta 3i
\fB\-dash\fR	\fB\-activedash\fR
\fB\-disableddash\fR	\fB\-dashoffset\fR


\fB\-fill\fR	\fB\-activefill\fR
\fB\-disabledfill\fR	\fB\-offset\fR


\fB\-outline\fR	\fB\-activeoutline\fR
\fB\-disabledoutline\fR	\fB\-outlineoffset\fR


\fB\-outlinestipple\fR	\fB\-activeoutlinestipple\fR
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR


\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR


\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for arcs:
.TP
\fB\-extent \fIdegrees\fR
Specifies the size of the angular range occupied by the arc.
The arc's range extends for \fIdegrees\fR degrees counter-clockwise
from the starting angle given by the \fB\-start\fR option.
\fIDegrees\fR may be negative.
If it is greater than 360 or less than \-360, then \fIdegrees\fR
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.
.TP
\fB\-height \fIdistance\fR
Provides a shortcut for creating a circular arc segment by defining the
distance of the mid-point of the arc from its chord. When this option
is used the coordinates are interpreted as the start and end coordinates
of the chord, and the options \fB\-start\fR and \fB-extent\fR are ignored.
The value of \fIdistance\fR has the following meaning:
.RS
.PP
.RS
\fIdistance\fR > 0 creates a clockwise arc
.br
\fIdistance\fR < 0 creates an counter-clockwise arc
.br
\fIdistance\fR = 0 creates an arc as if this option had not been specified
.RE
.PP
If you want the arc to have a specific radius, \fIr\fR, use the formula:
.PP
.RS
\fIdistance\fR = \fIr\fR \(+- sqrt(\fIr\fR**2 - (chordLength / 2)**2)
.RE
.PP
choosing the minus sign for the minor arc and the plus sign for the major arc.
.PP
Note that \fBitemcget \-height\fR always returns 0 so that introspection code
can be kept simple.
.RE
.TP
\fB\-style \fItype\fR
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined
by a section of the oval's perimeter plus a single line segment
connecting the two end points of the perimeter section.
If \fItype\fR is \fBarc\fR then the arc's region consists of
a section of the perimeter alone.
In this last case the \fB\-fill\fR option is ignored.
.SS "BITMAP ITEMS"
.PP
Items of type \fBbitmap\fR appear on the display as images with
two colors, foreground and background.
Bitmaps are created with widget commands of the following form:
.CS
\fIpathName \fBcreate bitmap \fIx y \fR?\fIoption value ...\fR?
\fIpathName \fBcreate bitmap \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the bitmap on the display, as controlled by the
\fB\-anchor\fR option.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A bitmap item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by bitmaps:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for bitmaps:
.TP









\fB\-background \fIcolor\fR
.TP
\fB\-activebackground \fIcolor\fR
.TP
\fB\-disabledbackground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 0
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If this option is not specified, or if it is specified as an empty
string, then nothing is displayed where the bitmap pixels are 0; this
produces a transparent effect.
.TP
\fB\-bitmap \fIbitmap\fR
.TP
\fB\-activebitmap \fIbitmap\fR
.TP
\fB\-disabledbitmap \fIbitmap\fR
Specifies the bitmaps to display in the item in its normal, active and
disabled states.
\fIBitmap\fR may have any of the forms accepted by \fBTk_GetBitmap\fR.
.TP
\fB\-foreground \fIcolor\fR
.TP
\fB\-activeforeground \fIcolor\fR
.TP
\fB\-disabledforeground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 1
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.

.SS "IMAGE ITEMS"
.PP
Items of type \fBimage\fR are used to display images on a
canvas.
Images are created with widget commands of the following form:
.CS
\fIpathName \fBcreate image \fIx y \fR?\fIoption value ...\fR?
\fIpathName \fBcreate image \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR specify the coordinates of a
point used to position the image on the display, as controlled by the
\fB\-anchor\fR option.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An image item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by images:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for images:
.TP









\fB\-image \fIname\fR
.TP
\fB\-activeimage \fIname\fR
.TP
\fB\-disabledimage \fIname\fR
Specifies the name of the images to display in the item in is normal,
active and disabled states.
This image must have been created previously with the
\fBimage create\fR command.
.SS "LINE ITEMS"
.PP
Items of type \fBline\fR appear on the display as one or more connected
line segments or curves.
Line items support coordinate indexing operations using the \fBdchars\fR,
\fBindex\fR and \fBinsert\fR widget commands.
Lines are created with widget commands of the following form:
.CS
\fIpathName \fBcreate line \fIx1 y1... xn yn \fR?\fIoption value ...\fR?
\fIpathName \fBcreate line \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR give
the coordinates for a series of two or more points that describe
a series of connected line segments.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A line item is the current item whenever the mouse pointer is
over any segment of the line, whether drawn or not and whether or not the line
is smoothed.
.PP
The following standard options are supported by lines:
.DS
.ta 3i
\fB\-dash\fR	\fB\-activedash\fR
\fB\-disableddash\fR	\fB\-dashoffset\fR


\fB\-fill\fR	\fB\-activefill\fR
\fB\-disabledfill\fR	\fB\-stipple\fR


\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR


\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for lines:
.TP
\fB\-arrow \fIwhere\fR
Indicates whether or not arrowheads are to be drawn at one or both
ends of the line.
\fIWhere\fR must have one of the values \fBnone\fR (for no arrowheads),
\fBfirst\fR (for an arrowhead at the first point of the line),
\fBlast\fR (for an arrowhead at the last point of the line), or
\fBboth\fR (for arrowheads at both ends).
This option defaults to \fBnone\fR.
When requested to draw an arrowhead, Tk internally adjusts the corresponding
line end point so that the rendered line ends at the neck of the arrowhead
rather than at its tip so that the line doesn't extend past the edge of the
arrowhead. This may trigger a \fBLeave\fR event if the mouse is hovering this
line end. Conversely, when removing an arrowhead Tk adjusts the corresponding
line point the other way round, which may trigger an \fBEnter\fR event.
.TP
\fB\-arrowshape \fIshape\fR
This option indicates how to draw arrowheads.
The \fIshape\fR argument must be a list with three elements, each
specifying a distance in any of the forms described in
the \fBCOORDINATES\fR section above.
The first element of the list gives the distance along the line







<








<






|
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<




|








<



|








<










<







|


|


|







<




|


|

|
|



<






<
<
<
<
<
<
<
<
<
<
<
<

<


|










|

|




|



<
<
<
<
<
<
<

<















<
|





<

<
|
|


<














|



<




<








<











<





|



<







<







<




|

|



<




<






<







<




|


<
<
<
|

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<


<
|
|










<
<
<
<
<
<


<
|




<
|



|

|
<







|




<




|







<












<






<



|





<






<















<







|
<






<

|









<





<


|
<
|

>
>
>



|

<
<
<


|
<






<

|








<





<



|
>
>
>



|

<
<
<




|

|











|

<
<
|
<
<
<
<
<
<
<






<







<

|
|







<



>
>


<
<






<



|
|


<
|
|





|

|
<






<














|
|
>
|
>
>
>
>






<













<

|



<


|






<





|


<
|



|
|


|
|



|
<
<


|






|
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|














|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|









|





|
|



|
|


|





|
<
|
|
|


>
>
>
>
>
>
>
>
>










|



















|
>
|





|
|


|
|


|





|
<
|
|
|


>
>
>
>
>
>
>
>
>









|



|
|


|
|






|






|
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|










<
<
<
<
<
<







596
597
598
599
600
601
602

603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622






















623

624
625
626
627
628
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
690
691
692
693

694
695
696
697
698
699












700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724







725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746

747

748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769

770
771
772
773

774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808

809
810
811
812
813
814
815

816
817
818
819
820
821
822
823
824
825

826
827
828
829

830
831
832
833
834
835

836
837
838
839
840
841
842

843
844
845
846
847
848
849



850
851
852
853




















854












855
856

857
858
859
860
861
862
863
864
865
866
867
868






869
870

871
872
873
874
875

876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902
903
904
905
906

907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924

925
926
927
928
929
930
931
932
933

934
935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954

955
956
957
958
959
960
961
962

963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979

980
981
982
983
984

985
986
987

988
989
990
991
992
993
994
995
996
997



998
999
1000

1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033



1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053


1054







1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078
1079
1080
1081
1082
1083
1084


1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159

1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190


1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240




























1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413






1414
1415
1416
1417
1418
1419
1420
within the canvas.
In most cases it is advisable to follow the \fBfocus\fR widget
command with the \fBfocus\fR command to set the focus window to
the canvas (if it was not there already).
.RE
.TP
\fIpathName \fBgettags\fR \fItagOrId\fR

Return a list whose elements are the tags associated with the
item given by \fItagOrId\fR.
If \fItagOrId\fR refers to more than one item, then the tags
are returned from the first such item in the display list.
If \fItagOrId\fR does not refer to any items, or if the item
contains no tags, then an empty string is returned.
.TP
\fIpathName \fBicursor \fItagOrId index\fR

Set the position of the insertion cursor for the item(s) given by \fItagOrId\fR
to just before the character whose position is given by \fIindex\fR.
If some or all of the items given by \fItagOrId\fR do not support
an insertion cursor then this command has no effect on them.
See \fBINDICES\fR above for a description of the
legal forms for \fIindex\fR.
Note:  the insertion cursor is only displayed in an item if
that item currently has the keyboard focus (see the widget
command \fBfocus\fR, below), but the cursor position may
be set even when the item does not have the focus.
This command returns an empty string.
.TP






















\fIpathName \fBindex \fItagOrId index\fR

This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
Text items interpret \fIindex\fR as an index to a  character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
The return value is guaranteed to lie between 0 and the number
of characters, or coordinates, within the item, inclusive.
If \fItagOrId\fR refers to multiple items, then the index
is processed in the first of these items that supports indexing
operations (in display list order).
.TP
\fIpathName \fBinsert \fItagOrId beforeThis string\fR

For each of the items given by \fItagOrId\fR, if the item supports
text or coordinate, insertion then \fIstring\fR is inserted into the item's
text just before the character, or coordinate, whose index is \fIbeforeThis\fR.
Text items interpret \fIbeforeThis\fR as an index to a  character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
For lines and polygons the \fIstring\fR must be a valid coordinate
sequence.
See \fBINDICES\fR above for information about the forms allowed
for \fIbeforeThis\fR.
This command returns an empty string.
.TP
\fIpathName \fBitemcget\fR \fItagOrId\fR \fIoption\fR

Returns the current value of the configuration option for the
item given by \fItagOrId\fR whose name is \fIoption\fR.
This command is similar to the \fBcget\fR widget command except that
it applies to a particular item rather than the widget as a whole.
\fIOption\fR may have any of the values accepted by the \fBcreate\fR
widget command when the item was created.
If \fItagOrId\fR is a tag that refers to more than one item,
the first (lowest) such item is used.
.TP
\fIpathName \fBitemconfigure \fItagOrId\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?

This command is similar to the \fBconfigure\fR widget command except
that it modifies item-specific options for the items given by
\fItagOrId\fR instead of modifying options for the overall
canvas widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the first item given by \fItagOrId\fR
(see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s) in
each of the items given by \fItagOrId\fR;  in
this case the command returns an empty string.
The \fIoption\fRs and \fIvalue\fRs are the same as those permissible
in the \fBcreate\fR widget command when the item(s) were created;
see the sections describing individual item types below for details
on the legal options.
.TP
\fIpathName \fBlower \fItagOrId \fR?\fIbelowThis\fR?

Move all of the items given by \fItagOrId\fR to a new position
in the display list just before the item given by \fIbelowThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIBelowThis\fR is a tag or id;  if it refers to more than one
item then the first (lowest) of these items in the display list is used
as the destination location for the moved items.
Note: this command has no effect on window items.  Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR and \fBlower\fR commands, not the
\fBraise\fR and \fBlower\fR widget commands for canvases.
This command returns an empty string.
.TP
\fIpathName \fBmove \fItagOrId xAmount yAmount\fR

Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.TP












\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?

Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned;  otherwise the Postscript
is returned as the result of the command.
If the interpreter that owns the canvas is marked as safe, the operation
will fail because safe interpreters are not allowed to write files.
If the \fB\-channel\fR option is specified, the argument denotes the name
of a channel already opened for writing. The Postscript is written to
that channel, and the channel is left open for further writing at the end
of the operation.
The Postscript is created in Encapsulated Postscript form using
version 3.0 of the Document Structuring Conventions.
Note: by default Postscript is only generated for information that
appears in the canvas's window on the screen.  If the canvas is
freshly created it may still have its initial size of 1x1 pixel
so nothing will appear in the Postscript.  To get around this problem
either invoke the \fBupdate\fR command to wait for the canvas window
to reach its final size, or else use the \fB\-width\fR and \fB\-height\fR
options to specify the area of the canvas to print.
The \fIoption\fR\-\fIvalue\fR argument pairs provide additional
information to control the generation of Postscript.  The following
options are supported:
.RS
.TP







\fB\-colormap \fIvarName\fR

\fIVarName\fR must be the name of an array variable
that specifies a color mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of Postscript
code to set a particular color value (e.g.
.QW "\fB1.0 1.0 0.0 setrgbcolor\fR" ).
When outputting color information in the Postscript, Tk checks
to see if there is an element of \fIvarName\fR with the same
name as the color.
If so, Tk uses the value of the element as the Postscript command
to set the color.
If this option has not been specified, or if there is no entry
in \fIvarName\fR for a given color, then Tk uses the red, green,
and blue intensities from the X color.
.TP
\fB\-colormode \fImode\fR

Specifies how to output color information.  \fIMode\fR must be either
\fBcolor\fR (for full color output), \fBgray\fR (convert all colors
to their gray-scale equivalents) or \fBmono\fR (convert all colors
to black or white).
.TP
\fB\-file \fIfileName\fR

Specifies the name of the file in which to write the Postscript.

If this option is not specified then the Postscript is returned as the
result of the command instead of being written to a file.
.TP
\fB\-fontmap \fIvarName\fR

\fIVarName\fR must be the name of an array variable
that specifies a font mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of a Tcl list with
two elements, which are the name and point size of a Postscript font.
When outputting Postscript commands for a particular font, Tk
checks to see if \fIvarName\fR contains an element with the same
name as the font.
If there is such an element, then the font information contained in
that element is used in the Postscript.
Otherwise Tk attempts to guess what Postscript font to use.
Tk's guesses generally only work for well-known fonts such as
Times and Helvetica and Courier, and only if the X font name does not
omit any dashes up through the point size.
For example, \fB\-*\-Courier\-Bold\-R\-Normal\-\-*\-120\-*\fR will work but
\fB*Courier\-Bold\-R\-Normal*120*\fR will not;  Tk needs the dashes to
parse the font name).
.TP
\fB\-height \fIsize\fR

Specifies the height of the area of the canvas to print.
Defaults to the height of the canvas window.
.TP
\fB\-pageanchor \fIanchor\fR

Specifies which point of the printed area of the canvas should appear over
the positioning point on the page (which is given by the \fB\-pagex\fR
and \fB\-pagey\fR options).
For example, \fB\-pageanchor n\fR means that the top center of the
area of the canvas being printed (as it appears in the canvas window)
should be over the positioning point. Defaults to \fBcenter\fR.
.TP
\fB\-pageheight \fIsize\fR

Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR high on the Postscript page.
\fISize\fR consists of a floating-point number followed by
\fBc\fR for centimeters, \fBi\fR for inches, \fBm\fR for millimeters,
or \fBp\fR or nothing for printer's points (1/72 inch).
Defaults to the height of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).
.TP
\fB\-pagewidth \fIsize\fR

Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR wide on the Postscript page.
\fISize\fR has the same form as for \fB\-pageheight\fR.
Defaults to the width of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR  is used (non-uniform scaling
is not implemented).
.TP
\fB\-pagex \fIposition\fR

\fIPosition\fR gives the x-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagey\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.TP
\fB\-pagey \fIposition\fR

\fIPosition\fR gives the y-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagex\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.TP
\fB\-rotate \fIboolean\fR

\fIBoolean\fR specifies whether the printed area is to be rotated 90
degrees.
In non-rotated output the x-axis of the printed area runs along
the short dimension of the page
.PQ portrait orientation ;
in rotated output the x-axis runs along the long dimension of the page
.PQ landscape orientation .
Defaults to non-rotated.
.TP
\fB\-width \fIsize\fR

Specifies the width of the area of the canvas to print.
Defaults to the width of the canvas window.
.TP
\fB\-x \fIposition\fR

Specifies the x-coordinate of the left edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the left edge of the window.
.TP
\fB\-y \fIposition\fR

Specifies the y-coordinate of the top edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the top edge of the window.
.RE
.TP
\fIpathName \fBraise \fItagOrId \fR?\fIaboveThis\fR?

Move all of the items given by \fItagOrId\fR to a new position
in the display list just after the item given by \fIaboveThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIAboveThis\fR is a tag or id;  if it refers to more than one
item then the last (topmost) of these items in the display list is used
as the destination location for the moved items.



Note: this command has no effect on window items.  Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR and \fBlower\fR commands, not the
\fBraise\fR and \fBlower\fR widget commands for canvases.




















This command returns an empty string.












.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR

Rescale all of the items given by \fItagOrId\fR in canvas coordinate
space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale
factors for x- and y-coordinates, respectively (a scale factor of
1.0 implies no change to that coordinate).
For each of the points defining each item, the x-coordinate is
adjusted to change the distance from \fIxOrigin\fR by a factor
of \fIxScale\fR.
Similarly, each y-coordinate is adjusted to change the distance
from \fIyOrigin\fR by a factor of \fIyScale\fR.
This command returns an empty string.






.TP
\fIpathName \fBscan\fR \fIoption args\fR

This command is used to implement scanning on canvases.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR

Records \fIx\fR and \fIy\fR and the canvas's current view;  used
in conjunction with later \fBscan dragto\fR commands.
Typically this command is associated with a mouse button press in
the widget and \fIx\fR and \fIy\fR are the coordinates of the
mouse.  It returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx y ?gain?\fR.

This command computes the difference between its \fIx\fR and \fIy\fR
arguments (which are typically mouse coordinates) and the \fIx\fR and
\fIy\fR arguments to the last \fBscan mark\fR command for the widget.
It then adjusts the view by \fIgain\fR times the
difference in coordinates, where \fIgain\fR defaults to 10.
This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the canvas at high speed through its window.  The return
value is an empty string.
.RE
.TP
\fIpathName \fBselect \fIoption\fR ?\fItagOrId arg\fR?

Manipulates the selection in one of several ways, depending on
\fIoption\fR.
The command may take any of the forms described below.
In all of the descriptions below, \fItagOrId\fR must refer to
an item that supports indexing and selection;  if it refers to
multiple items then the first of
these that supports indexing and the selection is used.
\fIIndex\fR gives a textual description of a position
within \fItagOrId\fR, as described in \fBINDICES\fR above.
.RS
.TP
\fIpathName \fBselect adjust \fItagOrId index\fR

Locate the end of the selection in \fItagOrId\fR nearest
to the character given by \fIindex\fR, and adjust that
end of the selection to be at \fIindex\fR (i.e. including
but not going beyond \fIindex\fR).
The other end of the selection is made the anchor point
for future \fBselect to\fR commands.
If the selection is not currently in \fItagOrId\fR then
this command behaves the same as the \fBselect to\fR widget
command.
Returns an empty string.
.TP
\fIpathName \fBselect clear\fR

Clear the selection if it is in this widget.
If the selection is not in this widget then the command
has no effect.
Returns an empty string.
.TP
\fIpathName \fBselect from \fItagOrId index\fR

Set the selection anchor point for the widget to be just
before the character
given by \fIindex\fR in the item given by \fItagOrId\fR.
This command does not change the selection;  it just sets
the fixed end of the selection for future \fBselect to\fR
commands.
Returns an empty string.
.TP
\fIpathName \fBselect item\fR

Returns the id of the selected item, if the selection is in an
item in this canvas.
If the selection is not in this canvas then an empty string
is returned.
.TP
\fIpathName \fBselect to \fItagOrId index\fR

Set the selection to consist of those characters of \fItagOrId\fR
between the selection anchor point and
\fIindex\fR.
The new selection will include the character given by \fIindex\fR;
it will include the character given by the anchor point only if
\fIindex\fR is greater than or equal to the anchor point.
The anchor point is determined by the most recent \fBselect adjust\fR
or \fBselect from\fR command for this widget.
If the selection anchor point for the widget is not currently in
\fItagOrId\fR, then it is set to the same character given
by \fIindex\fR.
Returns an empty string.
.RE
.TP
\fIpathName \fBtype\fI tagOrId\fR

Returns the type of the item given by \fItagOrId\fR, such as
\fBrectangle\fR or \fBtext\fR.
If \fItagOrId\fR refers to more than one item, then the type
of the first item in the display list is returned.
If \fItagOrId\fR does not refer to any items at all then
an empty string is returned.
.TP
\fIpathName \fBxview  \fR?\fIargs\fR?

This command is used to query and change the horizontal position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the canvas's area (as defined by the \fB\-scrollregion\fR option)
is off-screen to the left, the middle 40% is visible
in the window, and 40% of the canvas is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that \fIfraction\fR of the
total width of the canvas is off-screen to the left.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
If \fIwhat is \fBpages\fR then the view
adjusts in units of nine-tenths the window's width.
If \fInumber\fR is negative then information farther to the left
becomes visible;  if it is positive then information farther to the right
becomes visible.



.RE
.TP
\fIpathName \fByview \fI?args\fR?

This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the vertical span that is visible in the window.
For example, if the first element is .6 and the second element is 1.0,
the lowest 40% of the canvas's area (as defined by the \fB\-scrollregion\fR
option) is visible in the window.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview moveto\fI fraction\fR

Adjusts the view in the window so that \fIfraction\fR of the canvas's
area is off-screen to the top.
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR

This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units
of the \fByScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's height otherwise.
If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible;  if it is positive then lower information
becomes visible.



.RE
.SH "OVERVIEW OF ITEM TYPES"
.PP
The sections below describe the various types of items supported
by canvas widgets.  Each item type is characterized by two things:
first, the form of the \fBcreate\fR command used to create
instances of the type;  and second, a set of configuration options
for items of that type, which may be used in the
\fBcreate\fR and \fBitemconfigure\fR widget commands.
Most items do not support indexing or selection or the commands
related to them, such as \fBindex\fR and \fBinsert\fR.
Where items do support these facilities, it is noted explicitly
in the descriptions below.
At present, text, line and polygon items provide this support.
For lines and polygons the indexing facility is used to manipulate
the coordinates of the item.
.SS "COMMON ITEM OPTIONS"
.PP
Many items share a common set of options.  These options are
explained here, and then referred to be each widget type for brevity.


.PP







.TP
\fB\-dash \fIpattern\fR
.TP
\fB\-activedash \fIpattern\fR
.TP
\fB\-disableddash \fIpattern\fR

This option specifies dash patterns for the normal, active
state, and disabled state of an item.
\fIpattern\fR may have any of the forms accepted by \fBTk_GetDash\fR.
If the dash options are omitted then the default is a solid outline.
See \fBDASH PATTERNS\fR for more information.
.TP
\fB\-dashoffset \fIoffset\fR

The starting \fIoffset\fR in pixels into the pattern provided by the
\fB\-dash\fR option.  \fB\-dashoffset\fR is ignored if there is no
\fB\-dash\fR pattern.  The \fIoffset\fR may have any of the forms described
in the \fBCOORDINATES\fR section above.
.TP
\fB\-fill \fIcolor\fR
.TP
\fB\-activefill \fIcolor\fR
.TP
\fB\-disabledfill \fIcolor\fR

Specifies the color to be used to fill item's area.
in its normal, active, and disabled states,
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR is an empty string (the default),
then the item will not be filled.
For the line item, it specifies the color of the line drawn.
For the text item, it specifies the foreground color of the text.


.TP
\fB\-outline \fIcolor\fR
.TP
\fB\-activeoutline \fIcolor\fR
.TP
\fB\-disabledoutline \fIcolor\fR

This option specifies the color that should be used to draw the
outline of the item in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
This option defaults to \fBblack\fR.  If \fIcolor\fR is specified
as an empty string then no outline is drawn for the item.
.TP
\fB\-offset \fIoffset\fR

Specifies the offset of stipples.  The offset value can be of the form
\fBx,y\fR or \fBside\fR, where side can be \fBn\fR, \fBne\fR, \fBe\fR,
\fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR. In the
first case the origin is the origin of the toplevel of the current window.
For the canvas itself and canvas objects the origin is the canvas origin,
but putting \fB#\fR in front of the coordinate pair indicates using the
toplevel origin instead. For canvas objects, the \fB\-offset\fR option is
used for stippling as well.  For the line and polygon canvas items you can
also specify an index as argument, which connects the stipple origin to one
of the coordinate points of the line/polygon.

.TP
\fB\-outlinestipple \fIbitmap\fR
.TP
\fB\-activeoutlinestipple \fIbitmap\fR
.TP
\fB\-disabledoutlinestipple \fIbitmap\fR

This option specifies stipple patterns that should be used to draw the
outline of the item in its normal, active and disabled states.
Indicates that the outline for the item should be drawn with a stipple pattern;
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-outline\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then the outline is drawn
in a solid fashion.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.TP
\fB\-outlineoffset \fIoffset\fR
.
Specifies the offset of the stipple pattern used for outlines. The
offset value can be of the form
.QW \fIx\fB,\fIy\fR
or the description of a side (one of \fBn\fR, \fBne\fR, \fBe\fR,
\fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR). This
option only has an effect when the outline is drawn as a stipple
pattern, and is only supported under X11.
.\" TODO: What does this actually do? What do the acceptable forms mean?!
.TP
\fB\-stipple \fIbitmap\fR
.TP
\fB\-activestipple \fIbitmap\fR
.TP
\fB\-disabledstipple \fIbitmap\fR

This option specifies stipple patterns that should be used to fill
the item in its normal, active and disabled states.
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-fill\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then filling is done
in a solid fashion.
For the text item, it affects the actual text.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.TP
\fB\-state \fIstate\fR

This allows an item to override the canvas widget's global \fIstate\fR
option.  It takes the same values:
\fInormal\fR, \fIdisabled\fR or \fIhidden\fR.
.TP
\fB\-tags \fItagList\fR

Specifies a set of tags to apply to the item.
\fITagList\fR consists of a list of tag names, which replace any
existing tags for the item.  \fITagList\fR may be an empty list.
.TP
\fB\-width \fIoutlineWidth\fR
.TP
\fB\-activewidth \fIoutlineWidth\fR
.TP
\fB\-disabledwidth \fIoutlineWidth\fR

Specifies the width of the outline to be drawn around
the item's region, in its normal, active and disabled states.
\fIoutlineWidth\fR may be in any of the forms described in the
\fBCOORDINATES\fR section above.
If the \fB\-outline\fR option has been specified as an empty string then
this option has no effect.  This option defaults to 1.0.
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.

.SH "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by the \fB\-start\fR and \fB\-extent\fR options) and displayed in
one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc.


After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
.PP
The following standard options are supported by arcs:
.CS
\-dash
\-activedash
\-disableddash
\-dashoffset
\-fill
\-activefill
\-disabledfill
\-offset
\-outline
\-activeoutline
\-disabledoutline
\-outlineoffset
\-outlinestipple
\-activeoutlinestipple
\-disabledoutlinestipple
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
\-width
\-activewidth
\-disabledwidth
.CE
The following extra options are supported for arcs:
.TP
\fB\-extent \fIdegrees\fR
Specifies the size of the angular range occupied by the arc.
The arc's range extends for \fIdegrees\fR degrees counter-clockwise
from the starting angle given by the \fB\-start\fR option.
\fIDegrees\fR may be negative.
If it is greater than 360 or less than \-360, then \fIdegrees\fR
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position;  it may be either positive or negative.
.TP




























\fB\-style \fItype\fR
Specifies how to draw the arc.  If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined
by a section of the oval's perimeter plus a single line segment
connecting the two end points of the perimeter section.
If \fItype\fR is \fBarc\fR then the arc's region consists of
a section of the perimeter alone.
In this last case the \fB\-fill\fR option is ignored.
.SH "BITMAP ITEMS"
.PP
Items of type \fBbitmap\fR appear on the display as images with
two colors, foreground and background.
Bitmaps are created with widget commands of the following form:
.CS
\fIpathName \fBcreate bitmap \fIx y \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate bitmap \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the bitmap on the display (see the \fB\-anchor\fR
option below for more information on how bitmaps are displayed).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A bitmap item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by bitmaps:
.CS

\-state
\-tags
.CE
The following extra options are supported for bitmaps:
.TP
\fB\-anchor \fIanchorPos\fR
\fIAnchorPos\fR tells how to position the bitmap relative to the
positioning point for the item;  it may have any of the forms
accepted by \fBTk_GetAnchor\fR.  For example, if \fIanchorPos\fR
is \fBcenter\fR then the bitmap is centered on the point;  if
\fIanchorPos\fR is \fBn\fR then the bitmap will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.
.TP
\fB\-background \fIcolor\fR
.TP
\fB\-activebackground \fIcolor\fR
.TP
\fB\-disabledbackground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 0
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If this option is not specified, or if it is specified as an empty
string, then nothing is displayed where the bitmap pixels are 0;  this
produces a transparent effect.
.TP
\fB\-bitmap \fIbitmap\fR
.TP
\fB\-activebitmap \fIbitmap\fR
.TP
\fB\-disabledbitmap \fIbitmap\fR
Specifies the bitmaps to display in the item in its normal, active and
disabled states.
\fIBitmap\fR may have any of the forms accepted by \fBTk_GetBitmap\fR.
.TP
\fB\-foreground \fIcolor\fR
.TP
\fB\-activeforeground \fIcolor\fR
.TP
\fB\-disabledforeground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 1
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR and
defaults to \fBblack\fR.
.SH "IMAGE ITEMS"
.PP
Items of type \fBimage\fR are used to display images on a
canvas.
Images are created with widget commands of the following form:
.CS
\fIpathName \fBcreate image \fIx y \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate image \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR specify the coordinates of a
point used to position the image on the display (see the \fB\-anchor\fR
option below for more information).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An image item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by images:
.CS

\-state
\-tags
.CE
The following extra options are supported for images:
.TP
\fB\-anchor \fIanchorPos\fR
\fIAnchorPos\fR tells how to position the image relative to the
positioning point for the item;  it may have any of the forms
accepted by \fBTk_GetAnchor\fR.  For example, if \fIanchorPos\fR
is \fBcenter\fR then the image is centered on the point;  if
\fIanchorPos\fR is \fBn\fR then the image will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.
.TP
\fB\-image \fIname\fR
.TP
\fB\-activeimage \fIname\fR
.TP
\fB\-disabledimage \fIname\fR
Specifies the name of the images to display in the item in is normal,
active and disabled states.
This image must have been created previously with the
\fBimage create\fR command.
.SH "LINE ITEMS"
.PP
Items of type \fBline\fR appear on the display as one or more connected
line segments or curves.
Line items support coordinate indexing operations using the canvas
widget commands: \fBdchars, index, insert.\fR
Lines are created with widget commands of the following form:
.CS
\fIpathName \fBcreate line \fIx1 y1... xn yn \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate line \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR give
the coordinates for a series of two or more points that describe
a series of connected line segments.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A line item is the current item whenever the mouse pointer is
over any segment of the line, whether drawn or not and whether or not the line
is smoothed.
.PP
The following standard options are supported by lines:
.CS
\-dash
\-activedash
\-disableddash
\-dashoffset
\-fill
\-activefill
\-disabledfill
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
\-width
\-activewidth
\-disabledwidth
.CE
The following extra options are supported for lines:
.TP
\fB\-arrow \fIwhere\fR
Indicates whether or not arrowheads are to be drawn at one or both
ends of the line.
\fIWhere\fR must have one of the values \fBnone\fR (for no arrowheads),
\fBfirst\fR (for an arrowhead at the first point of the line),
\fBlast\fR (for an arrowhead at the last point of the line), or
\fBboth\fR (for arrowheads at both ends).
This option defaults to \fBnone\fR.






.TP
\fB\-arrowshape \fIshape\fR
This option indicates how to draw arrowheads.
The \fIshape\fR argument must be a list with three elements, each
specifying a distance in any of the forms described in
the \fBCOORDINATES\fR section above.
The first element of the list gives the distance along the line
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636

1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689


1690
1691


1692
1693


1694
1695


1696
1697


1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730


1731
1732


1733
1734

1735
1736


1737
1738


1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816


1817
1818


1819
1820


1821
1822


1823
1824


1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857

1858

1859
1860

1861
1862
1863
1864
1865
1866
1867
1868
1869

1870


1871
1872
1873
1874
1875
1876
1877
1878
(\fBbutt\fR, \fBprojecting\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBbutt\fR.
Where arrowheads are drawn the cap style is ignored.
.TP
\fB\-joinstyle \fIstyle\fR
Specifies the ways in which joints are to be drawn at the vertices
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
If the line only contains two points then this option is
irrelevant.
.TP
\fB\-smooth \fIsmoothMethod\fR
\fIsmoothMethod\fR must have one of the forms accepted by
\fBTcl_GetBoolean\fR or a line smoothing method.

Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean
false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the line
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the line
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points. If the last point is a
control point and not a knot point, the point is repeated (one or two
times) so that it also becomes a knot point.

.TP
\fB\-splinesteps \fInumber\fR
Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.SS "OVAL ITEMS"
.PP
Items of type \fBoval\fR appear as circular or oval regions on
the display. Each oval may have an outline, a fill, or
both. Ovals are created with widget commands of the
following form:
.CS
\fIpathName \fBcreate oval \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate oval \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval.
The oval will include the top and left edges of the rectangle
not the lower or right edges.
If the region is square then the resulting oval is circular;
otherwise it is elongated in shape.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An oval item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
.PP
The following standard options are supported by ovals:
.DS
.ta 3i
\fB\-dash\fR	\fB\-activedash\fR
\fB\-disableddash\fR	\fB\-dashoffset\fR


\fB\-fill\fR	\fB\-activefill\fR
\fB\-disabledfill\fR	\fB\-offset\fR


\fB\-outline\fR	\fB\-activeoutline\fR
\fB\-disabledoutline\fR	\fB\-outlineoffset\fR


\fB\-outlinestipple\fR	\fB\-activeoutlinestipple\fR
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR


\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR


\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
There are no oval-specific options.
.SS "POLYGON ITEMS"
.PP
Items of type \fBpolygon\fR appear as polygonal or curved filled regions
on the display.
Polygon items support coordinate indexing operations using the \fBdchars\fR,
\fBindex\fR and \fBinsert\fR widget commands.
Polygons are created with widget commands of the following form:
.CS
\fIpathName \fBcreate polygon \fIx1 y1 ... xn yn \fR?\fIoption value ...\fR?
\fIpathName \fBcreate polygon \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR specify the coordinates for
three or more points that define a polygon.
The first point should not be repeated as the last to
close the shape; Tk will automatically close the periphery between
the first and last points.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A polygon item is the current item whenever the mouse pointer
is over any part of the polygon, whether drawn or not and whether or not the
outline is smoothed.
.PP
The following standard options are supported by polygons:
.DS
.ta 3i
\fB\-dash\fR	\fB\-activedash\fR
\fB\-disableddash\fR	\fB\-dashoffset\fR


\fB\-fill\fR	\fB\-activefill\fR
\fB\-disabledfill\fR	\fB\-offset\fR


\fB\-outline\fR	\fB\-activeoutline\fR
\fB\-disabledoutline\fR	\fB\-outlineoffset\fR

\fB\-outlinestipple\fR	\fB\-activeoutlinestipple\fR
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR


\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR


\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for polygons:
.TP
\fB\-joinstyle \fIstyle\fR
Specifies the ways in which joints are to be drawn at the vertices
of the outline.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
.TP
\fB\-smooth \fIboolean\fR
\fIBoolean\fR must have one of the forms accepted by \fBTcl_GetBoolean\fR

or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean
false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the polygon
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the polygon
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be venerated within a curve by making control points
equal to their neighbouring knot points. If the last point is not the
second point of a pair of control points, the point is repeated (one or two
times) so that it also becomes the second point of a pair of control
points (the associated knot point will be the first control point).

.TP
\fB\-splinesteps \fInumber\fR
Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.PP
Polygon items are different from other items such as rectangles, ovals
and arcs in that interior points are considered to be
.QW inside
a polygon (e.g. for purposes of the \fBfind closest\fR and
\fBfind overlapping\fR widget commands) even if it is not filled.
For most other item types, an
interior point is considered to be inside the item only if the item
is filled or if it has neither a fill nor an outline. If you would
like an unfilled polygon whose interior points are not considered
to be inside the polygon, use a line item instead.
.SS "RECTANGLE ITEMS"
.PP
Items of type \fBrectangle\fR appear as rectangular regions on
the display. Each rectangle may have an outline, a fill, or
both. Rectangles are created with widget commands of the
following form:
.CS
\fIpathName \fBcreate rectangle \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate rectangle \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR
(which must have four elements) give
the coordinates of two diagonally opposite corners of the rectangle
(the rectangle will include its upper and left edges but not
its lower or right edges).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A rectangle item becomes the current item when the mouse
pointer is over any part that is painted or (when fully transparent) that
would be painted if both the \fB\-fill\fR and \fB\-outline\fR options were
non-empty.
.PP
The following standard options are supported by rectangles:
.DS
.ta 3i
\fB\-dash\fR	\fB\-activedash\fR
\fB\-disableddash\fR	\fB\-dashoffset\fR


\fB\-fill\fR	\fB\-activefill\fR
\fB\-disabledfill\fR	\fB\-offset\fR


\fB\-outline\fR	\fB\-activeoutline\fR
\fB\-disabledoutline\fR	\fB\-outlineoffset\fR


\fB\-outlinestipple\fR	\fB\-activeoutlinestipple\fR
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR


\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR


\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
There are no rectangle-specific options.
.SS "TEXT ITEMS"
.PP
A text item displays a string of characters on the screen in one
or more lines.
Text items support indexing, editing and selection through the \fBdchars\fR
widget command, the \fBfocus\fR widget command, the \fBicursor\fR widget
command, the \fBindex\fR widget command, the \fBinsert\fR widget command, and
the \fBselect\fR widget command.
Text items are created with widget commands of the following
form:
.CS
\fIpathName \fBcreate text \fIx y \fR?\fIoption value ...\fR?
\fIpathName \fBcreate text \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the text on the display (see the options
below for more information on how text is displayed).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A text item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by text items:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-fill\fR

\fB\-activefill\fR	\fB\-disabledfill\fR

\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR

\fB\-tags\fR
.DE
The following extra options are supported for text items:
.TP
\fB\-angle \fIrotationDegrees\fR
.
\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the

text will be drawn vertically from bottom to top.


This option defaults to \fB0.0\fR.
.TP
\fB\-font \fIfontName\fR
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.TP







|








>

|
|




|





|

|


>


|
|

|


|
|


|
|










|






|
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|
<
|



|
|


|
|








|






|
|
|
|
>
>
|
|
>
>
|
|
>
|
|
>
>
|
|
>
>
|
|
|





|





>

|
|




|





|

|



>


|
|









|


|


|
|


|
|








|







|
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|
<
|



|
|
|
|



|
|







|





|
<
|
>
|
>
|
|
>
|
|


|
<
|
|
|
>
|
>
>
|







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699

1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711

1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
(\fBbutt\fR, \fBprojecting\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBbutt\fR.
Where arrowheads are drawn the cap style is ignored.
.TP
\fB\-joinstyle \fIstyle\fR
Specifies the ways in which joints are to be drawn at the vertices
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetCapStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
If the line only contains two points then this option is
irrelevant.
.TP
\fB\-smooth \fIsmoothMethod\fR
\fIsmoothMethod\fR must have one of the forms accepted by
\fBTcl_GetBoolean\fR or a line smoothing method.
.VS 8.5
Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime.  If a boolean
false value or empty string is given, no smoothing is applied.  A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the line
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on.  Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the line
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve.  Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points.  If the last point is a
control point and not a knot point, the point is repeated (one or two
times) so that it also becomes a knot point.
.VE 8.5
.TP
\fB\-splinesteps \fInumber\fR
Specifies the degree of smoothness desired for curves:  each spline
will be approximated with \fInumber\fR line segments.  This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.SH "OVAL ITEMS"
.PP
Items of type \fBoval\fR appear as circular or oval regions on
the display.  Each oval may have an outline, a fill, or
both.  Ovals are created with widget commands of the
following form:
.CS
\fIpathName \fBcreate oval \fIx1 y1 x2 y2 \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate oval \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval.
The oval will include the top and left edges of the rectangle
not the lower or right edges.
If the region is square then the resulting oval is circular;
otherwise it is elongated in shape.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An oval item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
.PP
The following standard options are supported by ovals:
.CS
\-dash
\-activedash
\-disableddash
\-dashoffset
\-fill
\-activefill
\-disabledfill
\-offset
\-outline
\-activeoutline
\-disabledoutline
\-outlineoffset
\-outlinestipple
\-activeoutlinestipple
\-disabledoutlinestipple
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
\-width
\-activewidth
\-disabledwidth
.CE

.SH "POLYGON ITEMS"
.PP
Items of type \fBpolygon\fR appear as polygonal or curved filled regions
on the display.
Polygon items support coordinate indexing operations using the canvas
widget commands: \fBdchars, index, insert.\fR
Polygons are created with widget commands of the following form:
.CS
\fIpathName \fBcreate polygon \fIx1 y1 ... xn yn \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate polygon \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR specify the coordinates for
three or more points that define a polygon.
The first point should not be repeated as the last to
close the shape; Tk will automatically close the periphery between
the first and last points.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A polygon item is the current item whenever the mouse pointer
is over any part of the polygon, whether drawn or not and whether or not the
outline is smoothed.
.PP
The following standard options are supported by polygons:
.CS
\-dash
\-activedash
\-disableddash
\-dashoffset
\-fill
\-activefill
\-disabledfill
\-offset
\-outline
\-activeoutline
\-disabledoutline
\-outlinestipple
\-activeoutlinestipple
\-disabledoutlinestipple
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
\-width
\-activewidth
\-disabledwidth
.CE
The following extra options are supported for polygons:
.TP
\fB\-joinstyle \fIstyle\fR
Specifies the ways in which joints are to be drawn at the vertices
of the outline.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetCapStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
.TP
\fB\-smooth \fIboolean\fR
\fIBoolean\fR must have one of the forms accepted by \fBTcl_GetBoolean\fR
.VS 8.5
or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime.  If a boolean
false value or empty string is given, no smoothing is applied.  A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the polygon
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on.  Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the polygon
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve.  Straight
line segments can be venerated within a curve by making control points
equal to their neighbouring knot points.  If the last point is not the
second point of a pair of control points, the point is repeated (one or two
times) so that it also becomes the second point of a pair of control
points (the associated knot point will be the first control point).
.VE 8.5
.TP
\fB\-splinesteps \fInumber\fR
Specifies the degree of smoothness desired for curves:  each spline
will be approximated with \fInumber\fR line segments.  This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.PP
Polygon items are different from other items such as rectangles, ovals
and arcs in that interior points are considered to be
.QW inside
a polygon (e.g. for purposes of the \fBfind closest\fR and
\fBfind overlapping\fR widget commands) even if it is not filled.
For most other item types, an
interior point is considered to be inside the item only if the item
is filled or if it has neither a fill nor an outline.  If you would
like an unfilled polygon whose interior points are not considered
to be inside the polygon, use a line item instead.
.SH "RECTANGLE ITEMS"
.PP
Items of type \fBrectangle\fR appear as rectangular regions on
the display.  Each rectangle may have an outline, a fill, or
both.  Rectangles are created with widget commands of the
following form:
.CS
\fIpathName \fBcreate rectangle \fIx1 y1 x2 y2 \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate rectangle \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR
(which must have four elements) give
the coordinates of two diagonally opposite corners of the rectangle
(the rectangle will include its upper and left edges but not
its lower or right edges).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A rectangle item becomes the current item when the mouse
pointer is over any part that is painted or (when fully transparent) that
would be painted if both the \fB\-fill\fR and \fB\-outline\fR options were
non-empty.
.PP
The following standard options are supported by rectangles:
.CS
\-dash
\-activedash
\-disableddash
\-dashoffset
\-fill
\-activefill
\-disabledfill
\-offset
\-outline
\-activeoutline
\-disabledoutline
\-outlineoffset
\-outlinestipple
\-activeoutlinestipple
\-disabledoutlinestipple
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
\-width
\-activewidth
\-disabledwidth
.CE

.SH "TEXT ITEMS"
.PP
A text item displays a string of characters on the screen in one
or more lines.
Text items support indexing and selection, along with the
following text-related canvas widget commands:  \fBdchars\fR,
\fBfocus\fR, \fBicursor\fR, \fBindex\fR, \fBinsert\fR,
\fBselect\fR.
Text items are created with widget commands of the following
form:
.CS
\fIpathName \fBcreate text \fIx y \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate text \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the text on the display (see the options
below for more information on how text is displayed).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. A text item becomes the current item when the mouse pointer
is over any part of its bounding box.
.PP
The following standard options are supported by text items:
.CS

\-fill
\-activefill
\-disabledfill
\-stipple
\-activestipple
\-disabledstipple
\-state
\-tags
.CE
The following extra options are supported for text items:
.TP
\fB\-anchor \fIanchorPos\fR

\fIAnchorPos\fR tells how to position the text relative to the
positioning point for the text;  it may have any of the forms
accepted by \fBTk_GetAnchor\fR.  For example, if \fIanchorPos\fR
is \fBcenter\fR then the text is centered on the point;  if
\fIanchorPos\fR is \fBn\fR then the text will be drawn such that
the top center point of the rectangular region occupied by the
text will be at the positioning point.
This option defaults to \fBcenter\fR.
.TP
\fB\-font \fIfontName\fR
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.TP
1886
1887
1888
1889
1890
1891
1892

1893
1894
1895
1896
1897
1898
1899

1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940










1941
1942
1943
1944
1945
1946
1947
.TP
\fB\-text \fIstring\fR
\fIString\fR specifies the characters to be displayed in the text item.
Newline characters cause line breaks.
The characters in the item may also be changed with the
\fBinsert\fR and \fBdelete\fR widget commands.
This option defaults to an empty string.

.TP
\fB\-underline \fI\fR
Specifies the integer index of a character within the text to be
underlined. 0 corresponds to the first character of the text
displayed, 1 to the next character, and so on. \-1 means that no
underline should be drawn (if the whole text item is to be underlined,
the appropriate font should be used instead).

.TP
\fB\-width \fIlineLength\fR
Specifies a maximum line length for the text, in any of the forms
described in the \fBCOORDINATES\fR section above.
If this option is zero (the default) the text is broken into
lines only at newline characters.
However, if this option is non-zero then any line that would
be longer than \fIlineLength\fR is broken just before a space
character to make the line shorter than \fIlineLength\fR; the
space character is treated as if it were a newline
character.
.SS "WINDOW ITEMS"
.PP
Items of type \fBwindow\fR cause a particular window to be displayed
at a given position on the canvas.
Window items are created with widget commands of the following form:
.CS
\fIpathName \fBcreate window \fIx y \fR?\fIoption value ...\fR?
\fIpathName \fBcreate window \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the window on the display, as controlled by the
\fB\-anchor\fR option.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. Theoretically, a window item becomes the current item when the
mouse pointer is over any part of its bounding box, but in practice this
typically does not happen because the mouse pointer ceases to be over the
canvas at that point.
.PP
The following standard options are supported by window items:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for window items:
.TP










\fB\-height \fIpixels\fR
.
Specifies the height to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever height it requests internally.







>







>








|


|





|
|



|
|


|







|
<
|
|
|


>
>
>
>
>
>
>
>
>
>







1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
.TP
\fB\-text \fIstring\fR
\fIString\fR specifies the characters to be displayed in the text item.
Newline characters cause line breaks.
The characters in the item may also be changed with the
\fBinsert\fR and \fBdelete\fR widget commands.
This option defaults to an empty string.
.VS 8.5
.TP
\fB\-underline \fI\fR
Specifies the integer index of a character within the text to be
underlined. 0 corresponds to the first character of the text
displayed, 1 to the next character, and so on. \-1 means that no
underline should be drawn (if the whole text item is to be underlined,
the appropriate font should be used instead).
.VE 8.5
.TP
\fB\-width \fIlineLength\fR
Specifies a maximum line length for the text, in any of the forms
described in the \fBCOORDINATES\fR section above.
If this option is zero (the default) the text is broken into
lines only at newline characters.
However, if this option is non-zero then any line that would
be longer than \fIlineLength\fR is broken just before a space
character to make the line shorter than \fIlineLength\fR;  the
space character is treated as if it were a newline
character.
.SH "WINDOW ITEMS"
.PP
Items of type \fBwindow\fR cause a particular window to be displayed
at a given position on the canvas.
Window items are created with widget commands of the following form:
.CS
\fIpathName \fBcreate window \fIx y \fR?\fIoption value option value ...\fR?
\fIpathName \fBcreate window \fIcoordList\fR ?\fIoption value option value ...\fR?
.CE
The arguments \fIx\fR and \fIy\fR or \fIcoordList\fR (which must have two
elements) specify the coordinates of a
point used to position the window on the display (see the \fB\-anchor\fR
option below for more information on how bitmaps are displayed).
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item.  These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. Theoretically, a window item becomes the current item when the
mouse pointer is over any part of its bounding box, but in practice this
typically does not happen because the mouse pointer ceases to be over the
canvas at that point.
.PP
The following standard options are supported by window items:
.CS

\-state
\-tags
.CE
The following extra options are supported for window items:
.TP
\fB\-anchor \fIanchorPos\fR
.
\fIAnchorPos\fR tells how to position the window relative to the
positioning point for the item;  it may have any of the forms
accepted by \fBTk_GetAnchor\fR.  For example, if \fIanchorPos\fR
is \fBcenter\fR then the window is centered on the point;  if
\fIanchorPos\fR is \fBn\fR then the window will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.
.TP
\fB\-height \fIpixels\fR
.
Specifies the height to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever height it requests internally.
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
\fB\-window \fIpathName\fR
.
Specifies the window to associate with this item.
The window specified by \fIpathName\fR must either be a child of
the canvas widget or a child of some ancestor of the canvas widget.
\fIPathName\fR may not refer to a top-level window.
.PP
Note: due to restrictions in the ways that windows are managed, it is not
possible to draw other graphical items (such as lines and images) on top
of window items. A window item always obscures any graphics that
overlap it, regardless of their order in the display list. Also note that
window items, unlike other canvas items, are not clipped for display by their
containing canvas's border, and are instead clipped by the parent widget of
the window specified by the \fB\-window\fR option; when the parent widget is
the canvas, this means that the window item can overlap the canvas's border.
.SH "APPLICATION-DEFINED ITEM TYPES"
.PP
It is possible for individual applications to define new item
types for canvas widgets using C code.
See the documentation for \fBTk_CreateItemType\fR.
.SH BINDINGS
.PP
In the current implementation, new canvases are not given any
default behavior: you will have to execute explicit Tcl commands
to give the canvas its behavior.
.SH CREDITS
.PP
Tk's canvas widget is a blatant ripoff of ideas from Joel Bartlett's
\fIezd\fR program. \fIEzd\fR provides structured graphics in a Scheme
environment and preceded canvases by a year or two. Its simple
mechanisms for placing and animating graphical objects inspired the
functions of canvases.
.SH "SEE ALSO"
bind(n), font(n), image(n), scrollbar(n)
.SH KEYWORDS
canvas, widget
'\" Local Variables:
'\" mode: nroff
'\" fill-column: 78
'\" End:







|

|













|




|
|






<
<
<
<
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851




\fB\-window \fIpathName\fR
.
Specifies the window to associate with this item.
The window specified by \fIpathName\fR must either be a child of
the canvas widget or a child of some ancestor of the canvas widget.
\fIPathName\fR may not refer to a top-level window.
.PP
Note:  due to restrictions in the ways that windows are managed, it is not
possible to draw other graphical items (such as lines and images) on top
of window items.  A window item always obscures any graphics that
overlap it, regardless of their order in the display list. Also note that
window items, unlike other canvas items, are not clipped for display by their
containing canvas's border, and are instead clipped by the parent widget of
the window specified by the \fB\-window\fR option; when the parent widget is
the canvas, this means that the window item can overlap the canvas's border.
.SH "APPLICATION-DEFINED ITEM TYPES"
.PP
It is possible for individual applications to define new item
types for canvas widgets using C code.
See the documentation for \fBTk_CreateItemType\fR.
.SH BINDINGS
.PP
In the current implementation, new canvases are not given any
default behavior:  you will have to execute explicit Tcl commands
to give the canvas its behavior.
.SH CREDITS
.PP
Tk's canvas widget is a blatant ripoff of ideas from Joel Bartlett's
\fIezd\fR program.  \fIEzd\fR provides structured graphics in a Scheme
environment and preceded canvases by a year or two.  Its simple
mechanisms for placing and animating graphical objects inspired the
functions of canvases.
.SH "SEE ALSO"
bind(n), font(n), image(n), scrollbar(n)
.SH KEYWORDS
canvas, widget




Changes to doc/checkbutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH checkbutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
checkbutton \- Create and manipulate 'checkbutton' boolean selection widgets
.SH SYNOPSIS
\fBcheckbutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH checkbutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
checkbutton \- Create and manipulate checkbutton widgets
.SH SYNOPSIS
\fBcheckbutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the button's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-indicatoron indicatorOn IndicatorOn
Specifies whether or not the indicator should be drawn.  Must be a
proper boolean value.  If false, the \fB\-relief\fR option is
ignored and the widget's relief is always sunken if the widget is
selected and raised otherwise.
.OP \-offrelief offRelief OffRelief
Specifies the relief for the checkbutton when the indicator is not drawn and
the checkbutton is off.  The default value is
.QW raised .
By setting this option to
.QW flat
and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to
.QW raised ,
the effect is achieved
of having a flat button that raises on mouse-over and which is
depressed when activated.  This is the behavior typically exhibited by
the Bold, Italic, and Underline checkbuttons on the toolbar of a
word-processor, for example.
.OP \-offvalue offValue Value
Specifies value to store in the button's associated variable whenever
this button is deselected.  Defaults to
.QW 0 .
.OP \-onvalue onValue Value
Specifies value to store in the button's associated variable whenever







|













|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the button's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-indicatoron indicatorOn IndicatorOn
Specifies whether or not the indicator should be drawn.  Must be a
proper boolean value.  If false, the \fBrelief\fR option is
ignored and the widget's relief is always sunken if the widget is
selected and raised otherwise.
.OP \-offrelief offRelief OffRelief
Specifies the relief for the checkbutton when the indicator is not drawn and
the checkbutton is off.  The default value is
.QW raised .
By setting this option to
.QW flat
and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to
.QW raised ,
the effect is achieved
of having a flat button that raises on mouse-over and which is
depressed when activated.  This is the behavior typically exhibited by
the Bold, Italic, and Underline checkbuttons on the toolbar of a 
word-processor, for example.
.OP \-offvalue offValue Value
Specifies value to store in the button's associated variable whenever
this button is deselected.  Defaults to
.QW 0 .
.OP \-onvalue onValue Value
Specifies value to store in the button's associated variable whenever
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101

102

103
104
105

106
107
108
109
110
111
112
the indicator regardless of the select state.
If \fBindicatorOn\fR is false, this color is used as the background
for the entire widget, in place of \fBbackground\fR or \fBactiveBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)
when the checkbutton is selected.
This option is ignored unless the \fB\-image\fR option has been
specified.
.OP \-state state State
Specifies one of three states for the checkbutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the checkbutton is displayed using the
\fB\-foreground\fR and \fB\-background\fR options.  The active state is
typically used when the pointer is over the checkbutton.  In active state
the checkbutton is displayed using the \fB\-activeforeground\fR and
\fB\-activebackground\fR options.  Disabled state means that the checkbutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fB\-disabledforeground\fR and
\fB\-background\fR options determine how the checkbutton is displayed.
.OP \-tristateimage tristateImage TristateImage

Specifies an image to display (in place of the \fB\-image\fR option)
when the checkbutton is in tri-state mode.
This option is ignored unless the \fB\-image\fR option has been
specified.

.OP \-tristatevalue tristateValue Value

Specifies the value that causes the checkbutton to display the multi-value
selection, also known as the tri-state mode.  Defaults to
.QW "" .

.OP \-variable variable Variable
Specifies the name of a global variable to set to indicate whether
or not this button is selected.  Defaults to the name of the
button within its parent (i.e. the last element of the button
window's path name).
.OP \-width width Width
Specifies a desired width for the button.







|

|




|

|
|


|
|

>
|

|

>

>
|


>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
the indicator regardless of the select state.
If \fBindicatorOn\fR is false, this color is used as the background
for the entire widget, in place of \fBbackground\fR or \fBactiveBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fBimage\fR option)
when the checkbutton is selected.
This option is ignored unless the \fBimage\fR option has been
specified.
.OP \-state state State
Specifies one of three states for the checkbutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the checkbutton is displayed using the
\fBforeground\fR and \fBbackground\fR options.  The active state is
typically used when the pointer is over the checkbutton.  In active state
the checkbutton is displayed using the \fBactiveForeground\fR and
\fBactiveBackground\fR options.  Disabled state means that the checkbutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fBdisabledForeground\fR and
\fBbackground\fR options determine how the checkbutton is displayed.
.OP \-tristateimage tristateImage TristateImage
.VS 8.5
Specifies an image to display (in place of the \fBimage\fR option)
when the checkbutton is in tri-state mode.
This option is ignored unless the \fBimage\fR option has been
specified.
.VE 8.5
.OP \-tristatevalue tristateValue Value
.VS 8.5
Specifies the value that causes the checkbutton to display the multi-value 
selection, also known as the tri-state mode.  Defaults to
.QW "" .
.VE 8.5
.OP \-variable variable Variable
Specifies the name of a global variable to set to indicate whether
or not this button is selected.  Defaults to the name of the
button within its parent (i.e. the last element of the button
window's path name).
.OP \-width width Width
Specifies a desired width for the button.
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
\fIpathName\fR's parent must exist.
.PP
A checkbutton is a widget
that displays a textual string, bitmap or image
and a square called an \fIindicator\fR.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fB\-wraplength\fR option) and
one of the characters may optionally be underlined using the
\fB\-underline\fR option.
A checkbutton has
all of the behavior of a simple button, including the
following: it can display itself in either of three different
ways, according to the \fB\-state\fR option;
it can be made to appear
raised, sunken, or flat; it can be made to flash; and it invokes
a Tcl command whenever mouse button 1 is clicked over the
checkbutton.
.PP
In addition, checkbuttons can be \fIselected\fR.
If a checkbutton is selected then the indicator is normally
drawn with a selected appearance, and
a Tcl variable associated with the checkbutton is set to a particular
value (normally 1).

The indicator is drawn with a check mark inside.
If the checkbutton is not selected, then the indicator is drawn with a
deselected appearance, and the associated variable is
set to a different value (typically 0).
The indicator is drawn without a check mark inside.  In the special case
where the variable (if specified) has a value that matches the tristatevalue,
the indicator is drawn with a tri-state appearance and is in the tri-state
mode indicating mixed or multiple values.  (This is used when the check
box represents the state of multiple items.)
The indicator is drawn in a platform dependent manner.  Under Unix and
Windows, the background interior of the box is
.QW grayed .
Under Mac, the indicator is drawn with a dash mark inside.
By default, the name of the variable associated with a checkbutton is the
same as the \fIname\fR used to create the checkbutton.
The variable name, and the
.QW on ,







|

|



|










>




|
|
|
|

|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
\fIpathName\fR's parent must exist.
.PP
A checkbutton is a widget
that displays a textual string, bitmap or image
and a square called an \fIindicator\fR.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fBwrapLength\fR option) and
one of the characters may optionally be underlined using the
\fBunderline\fR option.
A checkbutton has
all of the behavior of a simple button, including the
following: it can display itself in either of three different
ways, according to the \fBstate\fR option;
it can be made to appear
raised, sunken, or flat; it can be made to flash; and it invokes
a Tcl command whenever mouse button 1 is clicked over the
checkbutton.
.PP
In addition, checkbuttons can be \fIselected\fR.
If a checkbutton is selected then the indicator is normally
drawn with a selected appearance, and
a Tcl variable associated with the checkbutton is set to a particular
value (normally 1).
.VS 8.5
The indicator is drawn with a check mark inside.
If the checkbutton is not selected, then the indicator is drawn with a
deselected appearance, and the associated variable is
set to a different value (typically 0).
The indicator is drawn without a check mark inside.  In the special case 
where the variable (if specified) has a value that matches the tristatevalue, 
the indicator is drawn with a tri-state appearance and is in the tri-state 
mode indicating mixed or multiple values.  (This is used when the check 
box represents the state of multiple items.)
The indicator is drawn in a platform dependent manner.  Under Unix and 
Windows, the background interior of the box is
.QW grayed .
Under Mac, the indicator is drawn with a dash mark inside.
By default, the name of the variable associated with a checkbutton is the
same as the \fIname\fR used to create the checkbutton.
The variable name, and the
.QW on ,
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
automatically selects and deselects itself when the variables value
changes to and from the button's
.QW on ,
.QW off
and
.QW tristate
values.

.SH "WIDGET COMMAND"
.PP
The \fBcheckbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given







>







|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
automatically selects and deselects itself when the variables value
changes to and from the button's
.QW on ,
.QW off
and
.QW tristate
values.
.VE 8.5
.SH "WIDGET COMMAND"
.PP
The \fBcheckbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
.IP [2]
When mouse button 1 is pressed over a checkbutton, it is invoked (its
selection state toggles and the command associated with the button is
invoked, if there is one).
.IP [3]
When a checkbutton has the input focus, the space key causes the checkbutton
to be invoked.  Under Windows, there are additional key bindings; plus
(\fB+\fR) and equal (\fB=\fR) select the button, and minus (\fB\-\fR)
deselects the button.
.PP
If the checkbutton's state is \fBdisabled\fR then none of the above
actions occur:  the checkbutton is completely non-responsive.
.PP
The behavior of checkbuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH EXAMPLE
.PP
This example shows a group of uncoupled checkbuttons.
.PP
.CS
labelframe .lbl \-text "Steps:"
\fBcheckbutton\fR .c1 \-text Lights  \-variable lights
\fBcheckbutton\fR .c2 \-text Cameras \-variable cameras
\fBcheckbutton\fR .c3 \-text Action! \-variable action
pack .c1 .c2 .c3 \-in .lbl
pack .lbl
.CE
.SH "SEE ALSO"
button(n), options(n), radiobutton(n), ttk::checkbutton(n)
.SH KEYWORDS
checkbutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
|







<



|
|
|
|
|
|





<
<
<
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294



.IP [2]
When mouse button 1 is pressed over a checkbutton, it is invoked (its
selection state toggles and the command associated with the button is
invoked, if there is one).
.IP [3]
When a checkbutton has the input focus, the space key causes the checkbutton
to be invoked.  Under Windows, there are additional key bindings; plus

(+) and equal (=) select the button, and minus (\-) deselects the button.
.PP
If the checkbutton's state is \fBdisabled\fR then none of the above
actions occur:  the checkbutton is completely non-responsive.
.PP
The behavior of checkbuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH EXAMPLE

This example shows a group of uncoupled checkbuttons.
.PP
.CS
    labelframe .lbl \-text "Steps:"
    \fBcheckbutton\fR .c1 \-text Lights  \-variable lights
    \fBcheckbutton\fR .c2 \-text Cameras \-variable cameras
    \fBcheckbutton\fR .c3 \-text Action! \-variable action
    pack .c1 .c2 .c3 \-in .lbl
    pack .lbl
.CE
.SH "SEE ALSO"
button(n), options(n), radiobutton(n), ttk::checkbutton(n)
.SH KEYWORDS
checkbutton, widget



Changes to doc/chooseColor.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
'\"
'\" 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.
'\"
.TH tk_chooseColor n 4.2 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseColor \- pops up a dialog box for the user to select a color.
.SH SYNOPSIS
\fBtk_chooseColor \fR?\fIoption value ...\fR?
.BE

.SH DESCRIPTION
.PP
The procedure \fBtk_chooseColor\fR pops up a dialog box for the
user to select a color. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.TP
\fB\-initialcolor\fR \fIcolor\fR





|









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'\"
'\" 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.
'\" 
.TH tk_chooseColor n 4.2 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseColor \- pops up a dialog box for the user to select a color.
.SH SYNOPSIS
\fBtk_chooseColor \fR?\fIoption value ...\fR?
.BE

.SH DESCRIPTION
.PP
The procedure \fBtk_chooseColor\fR pops up a dialog box for the
user to select a color. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.TP
\fB\-initialcolor\fR \fIcolor\fR
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
option is not specified, then a default title will be displayed.
.LP
If the user selects a color, \fBtk_chooseColor\fR will return the
name of the color in a form acceptable to \fBTk_GetColor\fR.  If the
user cancels the operation, both commands will return the empty
string.
.SH EXAMPLE
.PP
.CS
button .b \-bg [tk_chooseColor \-initialcolor gray \-title "Choose color"]
.CE

.SH KEYWORDS
color, color selection, dialog
'\" Local Variables:
'\" mode: nroff
'\" End:







<



>

|
<
<
<
34
35
36
37
38
39
40

41
42
43
44
45
46



option is not specified, then a default title will be displayed.
.LP
If the user selects a color, \fBtk_chooseColor\fR will return the
name of the color in a form acceptable to \fBTk_GetColor\fR.  If the
user cancels the operation, both commands will return the empty
string.
.SH EXAMPLE

.CS
button .b \-bg [tk_chooseColor \-initialcolor gray \-title "Choose color"]
.CE

.SH KEYWORDS
color selection dialog



Changes to doc/chooseDirectory.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH tk_chooseDirectory n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseDirectory \- pops up a dialog box for the user to select a directory.
.SH SYNOPSIS
\fBtk_chooseDirectory \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the
user to select a directory. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.TP
\fB\-command\fR \fIstring\fR
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.
.TP
\fB\-initialdir\fR \fIdirname\fR
Specifies that the directories in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.TP
\fB\-message\fR \fIstring\fR
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
.TP
\fB\-mustexist\fR \fIboolean\fR
Specifies whether the user may specify non-existent directories.  If
this parameter is true, then the user may only select directories that
already exist.  The default value is \fIfalse\fR.
.TP
\fB\-parent\fR \fIwindow\fR
Makes \fIwindow\fR the logical parent of the dialog. The dialog
is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.TP
\fB\-title\fR \fItitleString\fR
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.SH EXAMPLE
.PP
.CS
set dir [\fBtk_chooseDirectory\fR \e
        \-initialdir ~ \-title "Choose a directory"]
if {$dir eq ""} {
   label .l \-text "No directory selected"
} else {
   label .l \-text "Selected $dir"
}
.CE

.SH "SEE ALSO"
tk_getOpenFile(n), tk_getSaveFile(n)
.SH KEYWORDS
directory, selection, dialog, platform-specific
'\" Local Variables:
'\" mode: nroff
'\" End:



|















<
<
<
<
<
<
<


|
|
<
<
<



<
<
<
<














<









>




<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19







20
21
22
23



24
25
26




27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54



'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
.TH tk_chooseDirectory n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseDirectory \- pops up a dialog box for the user to select a directory.
.SH SYNOPSIS
\fBtk_chooseDirectory \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the
user to select a directory. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.TP







\fB\-initialdir\fR \fIdirname\fR
Specifies that the directories in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified, then
the directories in the current working directory are displayed. If the



parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.TP




\fB\-mustexist\fR \fIboolean\fR
Specifies whether the user may specify non-existent directories.  If
this parameter is true, then the user may only select directories that
already exist.  The default value is \fIfalse\fR.
.TP
\fB\-parent\fR \fIwindow\fR
Makes \fIwindow\fR the logical parent of the dialog. The dialog
is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.TP
\fB\-title\fR \fItitleString\fR
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.SH EXAMPLE

.CS
set dir [\fBtk_chooseDirectory\fR \e
        \-initialdir ~ \-title "Choose a directory"]
if {$dir eq ""} {
   label .l \-text "No directory selected"
} else {
   label .l \-text "Selected $dir"
}
.CE

.SH "SEE ALSO"
tk_getOpenFile(n), tk_getSaveFile(n)
.SH KEYWORDS
directory, selection, dialog, platform-specific



Changes to doc/clipboard.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29

30






31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH clipboard n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clipboard \- Manipulate Tk clipboard
.SH SYNOPSIS
\fBclipboard \fIoption\fR ?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command provides a Tcl interface to the Tk clipboard,
which stores data for later retrieval using the selection mechanism
(via the \fB\-selection CLIPBOARD\fR option).
In order to copy data into the clipboard, \fBclipboard clear\fR must
be called, followed by a sequence of one or more calls to \fBclipboard
append\fR.  To ensure that the clipboard is updated atomically, all
appends should be completed before returning to the event loop.
.PP
The first argument to \fBclipboard\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:

.TP






\fBclipboard append\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-format\fR \fIformat\fR? ?\fB\-type\fR \fItype\fR? ?\fB\-\|\-\fR? \fIdata\fR
.
Appends \fIdata\fR to the clipboard on \fIwindow\fR's
display in the form given by \fItype\fR with the representation given
by \fIformat\fR and claims ownership of the clipboard on \fIwindow\fR's
display.
.RS
.PP
\fIType\fR specifies the form in which the selection is to be returned
(the desired
.QW target
for conversion, in ICCCM terminology), and
should be an atom name such as \fBSTRING\fR or \fBFILE_NAME\fR; see the
Inter-Client Communication Conventions Manual for complete details.
\fIType\fR defaults to \fBSTRING\fR.
.PP
The \fIformat\fR argument specifies the representation that should be
used to transmit the selection to the requester (the second column of
Table 2 of the ICCCM), and defaults to \fBSTRING\fR.  If \fIformat\fR is
\fBSTRING\fR, the selection is transmitted as 8-bit ASCII characters.  If
\fIformat\fR is \fBATOM\fR, then the \fIdata\fR is
divided into fields separated by white space; each field is converted
to its atom value, and the 32-bit atom value is transmitted instead of
the atom name.  For any other \fIformat\fR,  \fIdata\fR is divided
into fields separated by white space and each
field is converted to a 32-bit integer; an array of integers is
transmitted to the selection requester.  Note that strings passed to
\fBclipboard append\fR are concatenated before conversion, so the
caller must take care to ensure appropriate spacing across string
boundaries.  All items appended to the clipboard with the same
\fItype\fR must have the same \fIformat\fR.
.PP
The \fIformat\fR argument is needed only for compatibility with
clipboard requesters that do not use Tk.  If the Tk toolkit is being
used to retrieve the \fBCLIPBOARD\fR selection then the value is
converted back to a string at the requesting end, so \fIformat\fR is
irrelevant.
.PP
A \fB\-\|\-\fR argument may be specified to mark the end of options:  the
next argument will always be used as \fIdata\fR.
This feature may be convenient if, for example, \fIdata\fR starts
with a \fB\-\fR.
.RE
.TP
\fBclipboard clear\fR ?\fB\-displayof\fR \fIwindow\fR?
.
Claims ownership of the clipboard on \fIwindow\fR's display and removes
any previous contents.  \fIWindow\fR defaults to
.QW . .
Returns an empty string.
.TP
\fBclipboard get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-type\fR \fItype\fR?
.
Retrieve data from the clipboard on \fIwindow\fR's display.
\fIWindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which
the data is to be returned and should be an atom name such as \fBSTRING\fR
or \fBFILE_NAME\fR.  \fIType\fR defaults to \fBSTRING\fR.  This command is
equivalent to
.QW "\fBselection get\fR \fB\-selection CLIPBOARD\fR" .
.RS
.PP
Note that on modern X11 systems, the most useful type to retrieve for
transferred strings is not \fBSTRING\fR, but rather \fBUTF8_STRING\fR.
.RE
.SH EXAMPLES
.PP
Get the current contents of the clipboard.
.CS
if {[catch {\fBclipboard get\fR} contents]} {
    # There were no clipboard contents at all
}
.CE
.PP






|







|

>



|









>

>
>
>
>
>
>

<










|

|



|
|
|



|









|
|








<
<
<
<
<
<
<

<




|
|

|






<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81







82

83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH clipboard n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clipboard \- Manipulate Tk clipboard
.SH SYNOPSIS
\fBclipboard \fIoption\fR ?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command provides a Tcl interface to the Tk clipboard,
which stores data for later retrieval using the selection mechanism 
(via the \fB\-selection CLIPBOARD\fR option).
In order to copy data into the clipboard, \fBclipboard clear\fR must
be called, followed by a sequence of one or more calls to \fBclipboard
append\fR.  To ensure that the clipboard is updated atomically, all
appends should be completed before returning to the event loop.
.PP
The first argument to \fBclipboard\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:
.PP
.TP
\fBclipboard clear\fR ?\fB\-displayof\fR \fIwindow\fR?
Claims ownership of the clipboard on \fIwindow\fR's display and removes
any previous contents.  \fIWindow\fR defaults to
.QW . .
Returns an empty string.
.TP
\fBclipboard append\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-format\fR \fIformat\fR? ?\fB\-type\fR \fItype\fR? ?\fB\-\|\-\fR? \fIdata\fR

Appends \fIdata\fR to the clipboard on \fIwindow\fR's
display in the form given by \fItype\fR with the representation given
by \fIformat\fR and claims ownership of the clipboard on \fIwindow\fR's
display.
.RS
.PP
\fIType\fR specifies the form in which the selection is to be returned
(the desired
.QW target
for conversion, in ICCCM terminology), and
should be an atom name such as STRING or FILE_NAME; see the
Inter-Client Communication Conventions Manual for complete details.
\fIType\fR defaults to STRING.
.PP
The \fIformat\fR argument specifies the representation that should be
used to transmit the selection to the requester (the second column of
Table 2 of the ICCCM), and defaults to STRING.  If \fIformat\fR is
STRING, the selection is transmitted as 8-bit ASCII characters.  If
\fIformat\fR is ATOM, then the \fIdata\fR is
divided into fields separated by white space; each field is converted
to its atom value, and the 32-bit atom value is transmitted instead of
the atom name.  For any other \fIformat\fR,  \fIdata\fR is divided
into fields separated by white space and each 
field is converted to a 32-bit integer; an array of integers is
transmitted to the selection requester.  Note that strings passed to
\fBclipboard append\fR are concatenated before conversion, so the
caller must take care to ensure appropriate spacing across string
boundaries.  All items appended to the clipboard with the same
\fItype\fR must have the same \fIformat\fR.
.PP
The \fIformat\fR argument is needed only for compatibility with
clipboard requesters that do not use Tk.  If the Tk toolkit is being
used to retrieve the CLIPBOARD selection then the value is converted back to
a string at the requesting end, so \fIformat\fR is
irrelevant.
.PP
A \fB\-\|\-\fR argument may be specified to mark the end of options:  the
next argument will always be used as \fIdata\fR.
This feature may be convenient if, for example, \fIdata\fR starts
with a \fB\-\fR.
.RE
.TP







\fBclipboard get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-type\fR \fItype\fR?

Retrieve data from the clipboard on \fIwindow\fR's display.
\fIWindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which
the data is to be returned and should be an atom name such as STRING
or FILE_NAME.  \fIType\fR defaults to STRING.  This command is
equivalent to
.QW "\fBselection get \-selection CLIPBOARD\fR" .
.RS
.PP
Note that on modern X11 systems, the most useful type to retrieve for
transferred strings is not \fBSTRING\fR, but rather \fBUTF8_STRING\fR.
.RE
.SH EXAMPLES

Get the current contents of the clipboard.
.CS
if {[catch {\fBclipboard get\fR} contents]} {
    # There were no clipboard contents at all
}
.CE
.PP
144
145
146
147
148
149
150

151
152

153
154
155
156
157
bind $c <<Paste>> {
   catch {
      set canvas %W
      eval [\fBclipboard get \-type\fR TkCanvasItem]
   }
}
.CE

.SH "SEE ALSO"
interp(n), selection(n)

.SH KEYWORDS
clear, format, clipboard, append, selection, type
'\" Local Variables:
'\" mode: nroff
'\" End:







>


>


<
<
<
142
143
144
145
146
147
148
149
150
151
152
153
154



bind $c <<Paste>> {
   catch {
      set canvas %W
      eval [\fBclipboard get \-type\fR TkCanvasItem]
   }
}
.CE

.SH "SEE ALSO"
interp(n), selection(n)

.SH KEYWORDS
clear, format, clipboard, append, selection, type



Changes to doc/colors.n.

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
gold3	205	173 	0
gold4	139	117 	0
goldenrod	218	165 	32
goldenrod1	255	193 	37
goldenrod2	238	180 	34
goldenrod3	205	155 	29
goldenrod4	139	105 	20
gray	128	128	128
gray0	0	0 	0
gray1	3	3 	3
gray2	5	5 	5
gray3	8	8 	8
gray4	10	10 	10
gray5	13	13 	13
gray6	15	15 	15







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
gold3	205	173 	0
gold4	139	117 	0
goldenrod	218	165 	32
goldenrod1	255	193 	37
goldenrod2	238	180 	34
goldenrod3	205	155 	29
goldenrod4	139	105 	20
gray	190	190 	190
gray0	0	0 	0
gray1	3	3 	3
gray2	5	5 	5
gray3	8	8 	8
gray4	10	10 	10
gray5	13	13 	13
gray6	15	15 	15
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
gray94	240	240 	240
gray95	242	242 	242
gray96	245	245 	245
gray97	247	247 	247
gray98	250	250 	250
gray99	252	252 	252
gray100	255	255 	255
green	0	128 	0
green yellow	173	255 	47
green1	0	255 	0
green2	0	238 	0
green3	0	205 	0
green4	0	139 	0
GreenYellow	173	255 	47
grey	128	128	128
grey0	0	0 	0
grey1	3	3 	3
grey2	5	5 	5
grey3	8	8 	8
grey4	10	10 	10
grey5	13	13 	13
grey6	15	15 	15







|






|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
gray94	240	240 	240
gray95	242	242 	242
gray96	245	245 	245
gray97	247	247 	247
gray98	250	250 	250
gray99	252	252 	252
gray100	255	255 	255
green	0	255 	0
green yellow	173	255 	47
green1	0	255 	0
green2	0	238 	0
green3	0	205 	0
green4	0	139 	0
GreenYellow	173	255 	47
grey	190	190 	190
grey0	0	0 	0
grey1	3	3 	3
grey2	5	5 	5
grey3	8	8 	8
grey4	10	10 	10
grey5	13	13 	13
grey6	15	15 	15
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
LimeGreen	50	205 	50
linen	250	240 	230
magenta	255	0 	255
magenta1	255	0 	255
magenta2	238	0 	238
magenta3	205	0 	205
magenta4	139	0 	139
maroon	128	0 	0
maroon1	255	52 	179
maroon2	238	48 	167
maroon3	205	41 	144
maroon4	139	28 	98
medium aquamarine	102	205 	170
medium blue	0	0 	205
medium orchid	186	85 	211







|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
LimeGreen	50	205 	50
linen	250	240 	230
magenta	255	0 	255
magenta1	255	0 	255
magenta2	238	0 	238
magenta3	205	0 	205
magenta4	139	0 	139
maroon	176	48 	96
maroon1	255	52 	179
maroon2	238	48 	167
maroon3	205	41 	144
maroon4	139	28 	98
medium aquamarine	102	205 	170
medium blue	0	0 	205
medium orchid	186	85 	211
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
plum	221	160 	221
plum1	255	187 	255
plum2	238	174 	238
plum3	205	150 	205
plum4	139	102 	139
powder blue	176	224 	230
PowderBlue	176	224 	230
purple	128	0 	128
purple1	155	48 	255
purple2	145	44 	238
purple3	125	38 	205
purple4	85	26 	139
red	255	0 	0
red1	255	0 	0
red2	238	0 	0







|







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
plum	221	160 	221
plum1	255	187 	255
plum2	238	174 	238
plum3	205	150 	205
plum4	139	102 	139
powder blue	176	224 	230
PowderBlue	176	224 	230
purple	160	32 	240
purple1	155	48 	255
purple2	145	44 	238
purple3	125	38 	205
purple4	85	26 	139
red	255	0 	0
red1	255	0 	0
red2	238	0 	0
780
781
782
783
784
785
786
787
788
789
790
791

792
793
794

795
796

797
798
799
800





801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

823

824
825

826


827
828
829
830
831
832
833

834
835


836
837
838
839
840
841


842
843

844
845







846
847

848



849




850
851
852







853






854
855

856
857
858
859
860
861







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBMac OS X\fR
.
On macOS, the following additional system colors are available.  This
first group contains all of the HIBrush colors available in the
HIToolbox library. Note that on macOS 10.14 (Mojave) and later these
colors are unlikely to match the color actually used for the purpose
suggested by the color name.

.RS
.DS
systemActiveAreaFill

systemAlertBackgroundActive
systemAlertBackgroundInactive

systemAlternatePrimaryHighlightColor
systemAppleGuideCoachmark
systemBevelActiveDark
systemBevelActiveLight





systemBevelInactiveDark
systemBevelInactiveLight
systemBlack

systemButtonActiveDarkHighlight
systemButtonActiveDarkShadow
systemButtonActiveLightHighlight
systemButtonActiveLightShadow
systemButtonFace
systemButtonFaceActive
systemButtonFaceInactive
systemButtonFacePressed
systemButtonFrame
systemButtonFrameActive
systemButtonFrameInactive
systemButtonInactiveDarkHighlight
systemButtonInactiveDarkShadow
systemButtonInactiveLightHighlight
systemButtonInactiveLightShadow
systemButtonPressedDarkHighlight
systemButtonPressedDarkShadow
systemButtonPressedLightHighlight
systemButtonPressedLightShadow

systemChasingArrows

systemDialogBackgroundActive
systemDialogBackgroundInactive

systemDocumentWindowBackground


systemDragHilite
systemDrawerBackground
systemFinderWindowBackground
systemFocusHighlight
systemHighlight
systemHighlightAlternate
systemHighlightSecondary

systemIconLabelBackground
systemIconLabelBackgroundSelected


systemListViewBackground
systemListViewColumnDivider
systemListViewEvenRowBackground
systemListViewOddRowBackground
systemListViewSeparator
systemListViewSortColumnBackground


systemMenu
systemMenuActive

systemMenuBackground
systemMenuBackgroundSelected







systemModelessDialogBackgroundActive
systemModelessDialogBackgroundInactive

systemMovableModalBackground



systemNotificationWindowBackground




systemPopupArrowActive
systemPopupArrowInactive
systemPopupArrowPressed







systemPrimaryHighlightColor






systemScrollBarDelimiterActive
systemScrollBarDelimiterInactive

systemSecondaryHighlightColor
systemSelectedTabTextColor
systemSheetBackground
systemSheetBackgroundOpaque
systemSheetBackgroundTransparent
systemStaticAreaFill







systemToolbarBackground
systemTransparent
systemUtilityWindowBackgroundActive
systemUtilityWindowBackgroundInactive
systemWhite
systemWindowBody
.DE
.RE
.
Tk supports all of the NSColors in the macOS System ColorList.  The
convention for naming these colors is that the Tk name is generated by
capitalizing the macOS name and adding the prefix "system".  On OSX
10.14 (Mojave) and later many of these "semantic" colors will appear
differently depending on whether the NSWindow in which they are used has
the Aqua or DarkAqua appearance.  The System ColorList differs between
releases of macOS and some colors, such as systemLinkColor and
systemControlAccentColor, are simulated on older systems which did not
provide them.  All of the colors below are available on all supported
macOS releases, but newer systems will support additional colors.
.RS
.DS
systemControlAccentColor
systemControlTextColor
systemDisabledControlTextColor
systemLabelColor
systemLinkColor
systemPlaceholderTextColor
systemSelectedTextBackgroundColor
systemSelectedTextColor
systemSeparatorColor
systemTextBackgroundColor
systemTextColor
.DE
.RE
.
The numbered systemWindowBackgroundColors below
are used in the \fBttk::notebook\fR and \fBttk::labelframe\fR widgets
to provide a contrasting background.  Each numbered color constrasts
with its predecessor.
.RS
.DS
systemWindowBackgroundColor
systemWindowBackgroundColor1
systemWindowBackgroundColor2
systemWindowBackgroundColor3
systemWindowBackgroundColor4
systemWindowBackgroundColor5
systemWindowBackgroundColor6
systemWindowBackgroundColor7
.DE
.RE
.TP

\fBWindows\fR
.
On Windows, the following additional system colors are available
(note that the actual color values depend on the currently active OS theme):
.RS
.DS
.ta 6c
system3dDarkShadow	systemHighlightText
system3dLight	systemInactiveBorder
systemActiveBorder	systemInactiveCaption
systemActiveCaption	systemInactiveCaptionText
systemAppWorkspace	systemInfoBackground
systemBackground	systemInfoText
systemButtonFace	systemMenu
systemButtonHighlight	systemMenuText
systemButtonShadow	systemPlaceholderText
systemButtonText	systemScrollbar
systemCaptionText	systemWindow
systemDisabledText	systemWindowFrame
systemGrayText	systemWindowText
systemHighlight
.DE
.RE
.SH "SEE ALSO"
options(n), Tk_GetColor(3)
.SH KEYWORDS
color, option
'\" Local Variables:
'\" mode: nroff
'\" End:







|
<
|
<
<
>



>


>




>
>
>
>
>



>



















>

>


>

>
>







>


>
>






>
>


>


>
>
>
>
>
>
>


>

>
>
>

>
>
>
>



>
>
>
>
>
>
>

>
>
>
>
>
>


>

<




>
>
>
>
>
>
>




|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
<



<







|
|
|
|
|
|
|
|
|




<









780
781
782
783
784
785
786
787

788


789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919


















920
921















922
923
924
925




926
927
928

929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948

949
950
951
952
953
954
955
956
957
yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBMac OS X\fR
.
On Mac OS X, the following additional system colors are available

(note that the actual color values depend on the currently active OS theme,


and typically many of these will in fact be patterns rather than pure colors):
.RS
.DS
systemActiveAreaFill
systemAlertActiveText
systemAlertBackgroundActive
systemAlertBackgroundInactive
systemAlertInactiveText
systemAlternatePrimaryHighlightColor
systemAppleGuideCoachmark
systemBevelActiveDark
systemBevelActiveLight
systemBevelButtonActiveText
systemBevelButtonInactiveText
systemBevelButtonPressedText
systemBevelButtonStickyActiveText
systemBevelButtonStickyInactiveText
systemBevelInactiveDark
systemBevelInactiveLight
systemBlack
systemBlackText
systemButtonActiveDarkHighlight
systemButtonActiveDarkShadow
systemButtonActiveLightHighlight
systemButtonActiveLightShadow
systemButtonFace
systemButtonFaceActive
systemButtonFaceInactive
systemButtonFacePressed
systemButtonFrame
systemButtonFrameActive
systemButtonFrameInactive
systemButtonInactiveDarkHighlight
systemButtonInactiveDarkShadow
systemButtonInactiveLightHighlight
systemButtonInactiveLightShadow
systemButtonPressedDarkHighlight
systemButtonPressedDarkShadow
systemButtonPressedLightHighlight
systemButtonPressedLightShadow
systemButtonText
systemChasingArrows
systemDialogActiveText
systemDialogBackgroundActive
systemDialogBackgroundInactive
systemDialogInactiveText
systemDocumentWindowBackground
systemDocumentWindowTitleActiveText
systemDocumentWindowTitleInactiveText
systemDragHilite
systemDrawerBackground
systemFinderWindowBackground
systemFocusHighlight
systemHighlight
systemHighlightAlternate
systemHighlightSecondary
systemHighlightText
systemIconLabelBackground
systemIconLabelBackgroundSelected
systemIconLabelSelectedText
systemIconLabelText
systemListViewBackground
systemListViewColumnDivider
systemListViewEvenRowBackground
systemListViewOddRowBackground
systemListViewSeparator
systemListViewSortColumnBackground
systemListViewText
systemListViewWindowHeaderBackground
systemMenu
systemMenuActive
systemMenuActiveText
systemMenuBackground
systemMenuBackgroundSelected
systemMenuDisabled
systemMenuItemActiveText
systemMenuItemDisabledText
systemMenuItemSelectedText
systemMenuText
systemMetalBackground
systemModelessDialogActiveText
systemModelessDialogBackgroundActive
systemModelessDialogBackgroundInactive
systemModelessDialogInactiveText
systemMovableModalBackground
systemMovableModalWindowTitleActiveText
systemMovableModalWindowTitleInactiveText
systemNotificationText
systemNotificationWindowBackground
systemPlacardActiveText
systemPlacardBackground
systemPlacardInactiveText
systemPlacardPressedText
systemPopupArrowActive
systemPopupArrowInactive
systemPopupArrowPressed
systemPopupButtonActiveText
systemPopupButtonInactiveText
systemPopupButtonPressedText
systemPopupLabelActiveText
systemPopupLabelInactiveText
systemPopupWindowTitleActiveText
systemPopupWindowTitleInactiveText
systemPrimaryHighlightColor
systemPushButtonActiveText
systemPushButtonInactiveText
systemPushButtonPressedText
systemRootMenuActiveText
systemRootMenuDisabledText
systemRootMenuSelectedText
systemScrollBarDelimiterActive
systemScrollBarDelimiterInactive
systemSecondaryGroupBoxBackground
systemSecondaryHighlightColor

systemSheetBackground
systemSheetBackgroundOpaque
systemSheetBackgroundTransparent
systemStaticAreaFill
systemSystemDetailText
systemTabFrontActiveText
systemTabFrontInactiveText
systemTabNonFrontActiveText
systemTabNonFrontInactiveText
systemTabNonFrontPressedText
systemTabPaneBackground
systemToolbarBackground
systemTransparent
systemUtilityWindowBackgroundActive
systemUtilityWindowBackgroundInactive
systemUtilityWindowTitleActiveText
systemUtilityWindowTitleInactiveText


















systemWhite
systemWhiteText















systemWindowBody
systemWindowHeaderActiveText
systemWindowHeaderBackground
systemWindowHeaderInactiveText




.DE
.RE
.TP

\fBWindows\fR
.
On Windows, the following additional system colors are available
(note that the actual color values depend on the currently active OS theme):
.RS
.DS
.ta 6c
system3dDarkShadow	systemHighlight
system3dLight	systemHighlightText
systemActiveBorder	systemInactiveBorder
systemActiveCaption	systemInactiveCaption
systemAppWorkspace	systemInactiveCaptionText
systemBackground	systemInfoBackground
systemButtonFace	systemInfoText
systemButtonHighlight	systemMenu
systemButtonShadow	systemMenuText
systemButtonText	systemScrollbar
systemCaptionText	systemWindow
systemDisabledText	systemWindowFrame
systemGrayText	systemWindowText

.DE
.RE
.SH "SEE ALSO"
options(n), Tk_GetColor(3)
.SH KEYWORDS
color, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/console.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2001 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH console n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
console \- Control the console on systems without a real console
.SH SYNOPSIS





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2001 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH console n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
console \- Control the console on systems without a real console
.SH SYNOPSIS
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Tk toolkit loaded, and control over this interpreter is given through
the \fBconsole\fR command.  The behaviour of the console window is
defined mainly through the contents of the \fIconsole.tcl\fR file in
the Tk library. Except for TkAqua, this command is not available when
Tk is loaded into a tclsh interpreter with
.QW "\fBpackage require Tk\fR" ,
as a conventional terminal is expected to be present in that case.
In TkAqua, this command is disabled when there is a startup script
and stdin is \fB/dev/null\fR (as is the case e.g. when a bundled application
embedding Tk is started by the macOS Launcher).  To enable the command
in that case, define the environment variable \fBTK_CONSOLE\fR.  This can be
done by modifying the Info.plist file by adding the LSEnvironment key
to the main dict and setting its value to be a dict with the key \fBTK_CONSOLE\fR.
.PP
.TP
\fBconsole eval \fIscript\fR
Evaluate the \fIscript\fR argument as a Tcl script in the console
interpreter.  The normal interpreter is accessed through the
\fBconsoleinterp\fR command in the console interpreter.
.TP







|
|
<
<
|
<







21
22
23
24
25
26
27
28
29


30

31
32
33
34
35
36
37
Tk toolkit loaded, and control over this interpreter is given through
the \fBconsole\fR command.  The behaviour of the console window is
defined mainly through the contents of the \fIconsole.tcl\fR file in
the Tk library. Except for TkAqua, this command is not available when
Tk is loaded into a tclsh interpreter with
.QW "\fBpackage require Tk\fR" ,
as a conventional terminal is expected to be present in that case.
In TkAqua, this command is ony available when stdin is \fB/dev/null\fR
(as is the case e.g. when the application embedding Tk is started


from the Mac OS X Finder).

.PP
.TP
\fBconsole eval \fIscript\fR
Evaluate the \fIscript\fR argument as a Tcl script in the console
interpreter.  The normal interpreter is accessed through the
\fBconsoleinterp\fR command in the console interpreter.
.TP
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Pressing F9 rebuilds the console window by destroying all its children
and reloading the Tcl script that defined the console's behaviour.
.PP
Most other behaviour is the same as a conventional text widget except
for the way that the \fI<<Cut>>\fR event is handled identically to the
\fI<<Copy>>\fR event.
.SH EXAMPLE
.PP
Not all platforms have the \fBconsole\fR command, so debugging code
often has the following code fragment in it so output produced by
\fBputs\fR can be seen while during development:
.CS
catch {\fBconsole show\fR}
.CE
.SH "SEE ALSO"
destroy(n), fconfigure(n), history(n), interp(n), puts(n), text(n), wm(n)
.SH KEYWORDS
console, interpreter, window, interactive, output channels
'\" Local Variables:
'\" mode: nroff
'\" End:







<










<
<
<
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141



Pressing F9 rebuilds the console window by destroying all its children
and reloading the Tcl script that defined the console's behaviour.
.PP
Most other behaviour is the same as a conventional text widget except
for the way that the \fI<<Cut>>\fR event is handled identically to the
\fI<<Copy>>\fR event.
.SH EXAMPLE

Not all platforms have the \fBconsole\fR command, so debugging code
often has the following code fragment in it so output produced by
\fBputs\fR can be seen while during development:
.CS
catch {\fBconsole show\fR}
.CE
.SH "SEE ALSO"
destroy(n), fconfigure(n), history(n), interp(n), puts(n), text(n), wm(n)
.SH KEYWORDS
console, interpreter, window, interactive, output channels



Changes to doc/cursors.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
'\" Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
'\"
.TH cursors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
cursors \- mouse cursors available in Tk
.BE



|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\" 
'\" Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
'\" 
.TH cursors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
cursors \- mouse cursors available in Tk
.BE
131
132
133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
.RE
.TP
\fBMac OS X\fR
On Mac OS X systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross
crosshair
tcross
ibeam
none


xterm
.CE
And the following additional native cursors are available:
.CS
copyarrow
aliasarrow
contextualmenuarrow
movearrow
text
cross-hair
hand
openhand
closedhand
fist
pointinghand
resize
resizeleft
resizeright
resizeleftright
resizeup
resizedown
resizeupdown
resizebottomleft
resizetopleft
resizebottomright
resizetopright
notallowed
poof
wait
countinguphand
countingdownhand
countingupanddownhand
spinning
help
bucket
cancel
eyedrop
eyedrop-full
zoom-in
zoom-out
.CE
.RE
.SH KEYWORDS
cursor, option
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<


<


>
>







<


|

<
<

<






<
<
<
<


<




<
<
<
<
<
<
<




<
<
<
131
132
133
134
135
136
137


138
139

140
141
142
143
144
145
146
147
148
149
150

151
152
153
154


155

156
157
158
159
160
161




162
163

164
165
166
167







168
169
170
171



.RE
.TP
\fBMac OS X\fR
On Mac OS X systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow


cross
crosshair

ibeam
none
plus
watch
xterm
.CE
And the following additional native cursors are available:
.CS
copyarrow
aliasarrow
contextualmenuarrow

text
cross-hair
closedhand
openhand


pointinghand

resizeleft
resizeright
resizeleftright
resizeup
resizedown
resizeupdown




notallowed
poof

countinguphand
countingdownhand
countingupanddownhand
spinning







.CE
.RE
.SH KEYWORDS
cursor, option



Changes to doc/destroy.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH destroy n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
destroy \- Destroy one or more windows
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH destroy n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
destroy \- Destroy one or more windows
.SH SYNOPSIS
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
is deleted then all windows will be destroyed and the application will
(normally) exit.
The \fIwindow\fRs are destroyed in order, and if an error occurs
in destroying a window the command aborts without destroying the
remaining windows.
No error is returned if \fIwindow\fR does not exist.
.SH EXAMPLE
.PP
Destroy all checkbuttons that are direct children of the given widget:
.CS
proc killCheckbuttonChildren {parent} {
   foreach w [winfo children $parent] {
      if {[winfo class $w] eq "Checkbutton"} {
         \fBdestroy\fR $w
      }
   }
}
.CE

.SH KEYWORDS
application, destroy, window
'\" Local Variables:
'\" mode: nroff
'\" End:







<










>


<
<
<
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42



is deleted then all windows will be destroyed and the application will
(normally) exit.
The \fIwindow\fRs are destroyed in order, and if an error occurs
in destroying a window the command aborts without destroying the
remaining windows.
No error is returned if \fIwindow\fR does not exist.
.SH EXAMPLE

Destroy all checkbuttons that are direct children of the given widget:
.CS
proc killCheckbuttonChildren {parent} {
   foreach w [winfo children $parent] {
      if {[winfo class $w] eq "Checkbutton"} {
         \fBdestroy\fR $w
      }
   }
}
.CE

.SH KEYWORDS
application, destroy, window



Changes to doc/dialog.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tk_dialog n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_dialog \- Create modal dialog and wait for response
.SH SYNOPSIS
\fBtk_dialog \fIwindow title text bitmap default string string ...\fR
.BE

.SH DESCRIPTION
.PP
This procedure is part of the Tk script library.
It is largely \fIdeprecated\fR by the \fBtk_messageBox\fR.
Its arguments describe a dialog box:
.TP
\fIwindow\fR
Name of top-level window to use for dialog.  Any existing window
by this name is destroyed.
.TP
\fItitle\fR
Text to appear in the window manager's title bar for the dialog.
.TP
\fItext\fR
Message to appear in the top portion of the dialog box.
.TP
\fIbitmap\fR
If non-empty, specifies a bitmap (in a form suitable for Tk_GetBitmap)
to display in the top portion of
the dialog, to the left of the text.
If this is an empty string then no bitmap is displayed in the dialog.
.TP
\fIdefault\fR
If this is an integer greater than or equal to zero, then it gives
the index of the button that is to be the default button for the dialog
(0 for the leftmost button, and so on).






|









>



<













|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tk_dialog n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_dialog \- Create modal dialog and wait for response
.SH SYNOPSIS
\fBtk_dialog \fIwindow title text bitmap default string string ...\fR
.BE

.SH DESCRIPTION
.PP
This procedure is part of the Tk script library.

Its arguments describe a dialog box:
.TP
\fIwindow\fR
Name of top-level window to use for dialog.  Any existing window
by this name is destroyed.
.TP
\fItitle\fR
Text to appear in the window manager's title bar for the dialog.
.TP
\fItext\fR
Message to appear in the top portion of the dialog box.
.TP
\fIbitmap\fR
If non-empty, specifies a bitmap to display in the top portion of

the dialog, to the left of the text.
If this is an empty string then no bitmap is displayed in the dialog.
.TP
\fIdefault\fR
If this is an integer greater than or equal to zero, then it gives
the index of the button that is to be the default button for the dialog
(0 for the leftmost button, and so on).
56
57
58
59
60
61
62
63
64
65
66
67

68
69

70
71
72
73
74
If the dialog's window is destroyed before the user selects one
of the buttons, then \-1 is returned.
.PP
While waiting for the user to respond, \fBtk_dialog\fR sets a local
grab.  This prevents the user from interacting with the application
in any way except to invoke the dialog box.
.SH EXAMPLE
.PP
.CS
set reply [\fBtk_dialog\fR .foo "The Title" "Do you want to say yes?" \e
        questhead 0 Yes No "I'm not sure"]
.CE

.SH "SEE ALSO"
tk_messageBox(n)

.SH KEYWORDS
bitmap, dialog, modal
'\" Local Variables:
'\" mode: nroff
'\" End:







<




>


>


<
<
<
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71



If the dialog's window is destroyed before the user selects one
of the buttons, then \-1 is returned.
.PP
While waiting for the user to respond, \fBtk_dialog\fR sets a local
grab.  This prevents the user from interacting with the application
in any way except to invoke the dialog box.
.SH EXAMPLE

.CS
set reply [\fBtk_dialog\fR .foo "The Title" "Do you want to say yes?" \e
        questhead 0 Yes No "I'm not sure"]
.CE

.SH "SEE ALSO"
tk_messageBox(n)

.SH KEYWORDS
bitmap, dialog, modal



Changes to doc/entry.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH entry n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
entry \- Create and manipulate 'entry' one-line text entry widgets
.SH SYNOPSIS
\fBentry\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-highlightthickness	\-selectbackground
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand
\-highlightbackground	\-justify
\-highlightcolor	\-relief
\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-disabledbackground disabledBackground DisabledBackground
Specifies the background color to use when the entry is disabled.  If
this option is the empty string, the normal background color is used.
.OP \-disabledforeground disabledForeground DisabledForeground
Specifies the foreground color to use when the entry is disabled.  If
this option is the empty string, the normal foreground color is used.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fB\-validatecommand\fR returns 0.
Setting it to {} disables this feature (the default).  The best use
of this option is to set it to \fIbell\fR.  See \fBVALIDATION\fR
below for more information.
.OP \-readonlybackground readonlyBackground ReadonlyBackground
Specifies the background color to use when the entry is readonly.  If
this option is the empty string, the normal background color is used.
.OP \-show show Show
If this option is specified, then the true contents of the entry
are not displayed in the window.







|





|











<









|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH entry n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
entry \- Create and manipulate entry widgets
.SH SYNOPSIS
\fBentry\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-highlightthickness	\-selectbackground
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand
\-highlightbackground	\-justify
\-highlightcolor	\-relief

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-disabledbackground disabledBackground DisabledBackground
Specifies the background color to use when the entry is disabled.  If
this option is the empty string, the normal background color is used.
.OP \-disabledforeground disabledForeground DisabledForeground
Specifies the foreground color to use when the entry is disabled.  If
this option is the empty string, the normal foreground color is used.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fBvalidateCommand\fR returns 0.
Setting it to {} disables this feature (the default).  The best use
of this option is to set it to \fIbell\fR.  See \fBValidation\fR
below for more information.
.OP \-readonlybackground readonlyBackground ReadonlyBackground
Specifies the background color to use when the entry is readonly.  If
this option is the empty string, the normal background color is used.
.OP \-show show Show
If this option is specified, then the true contents of the entry
are not displayed in the window.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
displayed, the contents will not be selectable, and the entry may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBVALIDATION\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand
Specifies a script to eval when you want to validate the input into
the entry widget.  Setting it to {} disables this feature (the default).
This command must return a valid Tcl boolean value.  If it returns 0 (or
the valid Tcl boolean equivalent) then it means you reject the new edition
and it will not occur and the \fB\-invalidcommand\fR will be evaluated if it
is set. If it returns 1, then the new edition occurs.
See \fBVALIDATION\fR below for more information.
.OP \-width width Width
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font.
If the value is less than or equal to zero, the widget picks a
size just large enough to hold its current text.
.BE
.SH DESCRIPTION







|





|

|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
displayed, the contents will not be selectable, and the entry may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBValidation\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand
Specifies a script to eval when you want to validate the input into
the entry widget.  Setting it to {} disables this feature (the default).
This command must return a valid Tcl boolean value.  If it returns 0 (or
the valid Tcl boolean equivalent) then it means you reject the new edition
and it will not occur and the \fBinvalidCommand\fR will be evaluated if it
is set. If it returns 1, then the new edition occurs.
See \fBValidation\fR below for more information.
.OP \-width width Width
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font.
If the value is less than or equal to zero, the widget picks a
size just large enough to hold its current text.
.BE
.SH DESCRIPTION
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
\fIpathName\fR's parent must exist.
.PP
An entry is a widget that displays a one-line text string and
allows that string to be edited using widget commands described below, which
are typically bound to keystrokes and mouse actions.
When first created, an entry's string is empty.
A portion of the entry may be selected as described below.
If an entry is exporting its selection (see the \fB\-exportselection\fR
option), then it will observe the standard X11 protocols for handling the
selection;  entry selections are available as type \fBSTRING\fR.
Entries also observe the standard Tk rules for dealing with the
input focus.  When an entry has the input focus it displays an
\fIinsertion cursor\fR to indicate where new characters will be
inserted.
.PP
Entries are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed;  commands described below
may be used to change the view in the window.  Entries use
the standard \fB\-xscrollcommand\fR mechanism for interacting with
scrollbars (see the description of the \fB\-xscrollcommand\fR option
for details).  They also support scanning, as described below.
.SH VALIDATION
.PP
Validation works by setting the \fB\-validatecommand\fR option to a
script (\fIvalidateCommand\fR) which will be evaluated according to
the \fB\-validate\fR option as follows:
.PP
.IP \fBnone\fR 10
Default.  This means no validation will occur.
.IP \fBfocus\fR 10
\fIvalidateCommand\fR will be called when the entry receives or
loses focus.
.IP \fBfocusin\fR 10
\fIvalidateCommand\fR will be called when the entry receives focus.
.IP \fBfocusout\fR 10
\fIvalidateCommand\fR will be called when the entry loses focus.
.IP \fBkey\fR 10
\fIvalidateCommand\fR will be called when the entry is edited.
.IP \fBall\fR 10
\fIvalidateCommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the value of the
\fB\-validatecommand\fR and \fB\-invalidcommand\fR options,
just as you would in a \fBbind\fR script.  The following substitutions
are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5







|











|
|



|
|
|




|


|

|

|

|

|
|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
\fIpathName\fR's parent must exist.
.PP
An entry is a widget that displays a one-line text string and
allows that string to be edited using widget commands described below, which
are typically bound to keystrokes and mouse actions.
When first created, an entry's string is empty.
A portion of the entry may be selected as described below.
If an entry is exporting its selection (see the \fBexportSelection\fR
option), then it will observe the standard X11 protocols for handling the
selection;  entry selections are available as type \fBSTRING\fR.
Entries also observe the standard Tk rules for dealing with the
input focus.  When an entry has the input focus it displays an
\fIinsertion cursor\fR to indicate where new characters will be
inserted.
.PP
Entries are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed;  commands described below
may be used to change the view in the window.  Entries use
the standard \fBxScrollCommand\fR mechanism for interacting with
scrollbars (see the description of the \fBxScrollCommand\fR option
for details).  They also support scanning, as described below.
.SH VALIDATION
.PP
Validation works by setting the \fBvalidateCommand\fR
option to a script which will be evaluated according to the \fBvalidate\fR
option as follows:
.PP
.IP \fBnone\fR 10
Default.  This means no validation will occur.
.IP \fBfocus\fR 10
\fBvalidateCommand\fR will be called when the entry receives or
loses focus.
.IP \fBfocusin\fR 10
\fBvalidateCommand\fR will be called when the entry receives focus.
.IP \fBfocusout\fR 10
\fBvalidateCommand\fR will be called when the entry loses focus.
.IP \fBkey\fR 10
\fBvalidateCommand\fR will be called when the entry is edited.
.IP \fBall\fR 10
\fBvalidateCommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the \fBvalidateCommand\fR
and \fBinvalidCommand\fR,
just as you would in a \fBbind\fR script.  The following substitutions
are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
The type of validation currently set.
.IP \fB%V\fR 5
The type of validation that triggered the callback
(key, focusin, focusout, forced).
.IP \fB%W\fR 5
The name of the entry widget.
.PP
In general, the \fB\-textvariable\fR and \fB\-validatecommand\fR options can be
dangerous to mix.  Any problems have been overcome so that using the
\fB\-validatecommand\fR will not interfere with the traditional behavior of
the entry widget.  Using the \fB\-textvariable\fR for read-only purposes will
never cause problems.  The danger comes when you try set the
\fB\-textvariable\fR to something that the \fB\-validatecommand\fR would not
accept, which causes \fB\-validate\fR to become \fInone\fR (the
\fB\-invalidcommand\fR will not be triggered).  The same happens
when an error occurs evaluating the \fB\-validatecommand\fR.
.PP
Primarily, an error will occur when the \fB\-validatecommand\fR or
\fB\-invalidcommand\fR encounters an error in its script while evaluating or
\fB\-validatecommand\fR does not return a valid Tcl boolean value.  The
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
entry widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the entry widget (for example set it to {})
during validation and still have the \fB\-validate\fR option set, you should
include the command
.CS
after idle {%W config \-validate %v}
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the entry widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
entry widget to become out of sync with the \fB\-textvariable\fR.
.SH "WIDGET COMMAND"
.PP
The \fBentry\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName subcommand \fR?\fIarg ...\fR?
.CE
\fISubcommand\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for entries take one or more indices as
arguments.  An index specifies a particular character in the entry's







|

|
|

|
|
|
|

|
|
|
|
|
|

|




|

|
|






|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
The type of validation currently set.
.IP \fB%V\fR 5
The type of validation that triggered the callback
(key, focusin, focusout, forced).
.IP \fB%W\fR 5
The name of the entry widget.
.PP
In general, the \fBtextVariable\fR and \fBvalidateCommand\fR can be
dangerous to mix.  Any problems have been overcome so that using the
\fBvalidateCommand\fR will not interfere with the traditional behavior of
the entry widget.  Using the \fBtextVariable\fR for read-only purposes will
never cause problems.  The danger comes when you try set the
\fBtextVariable\fR to something that the \fBvalidateCommand\fR would not
accept, which causes \fBvalidate\fR to become \fInone\fR (the
\fBinvalidCommand\fR will not be triggered).  The same happens
when an error occurs evaluating the \fBvalidateCommand\fR.
.PP
Primarily, an error will occur when the \fBvalidateCommand\fR or
\fBinvalidCommand\fR encounters an error in its script while evaluating or
\fBvalidateCommand\fR does not return a valid Tcl boolean value.  The
\fBvalidate\fR option will also set itself to \fBnone\fR when you edit the
entry widget from within either the \fBvalidateCommand\fR or the
\fBinvalidCommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the entry widget (for example set it to {})
during validation and still have the \fBvalidate\fR option set, you should
include the command
.CS
after idle {%W config \-validate %v}
.CE
in the \fBvalidateCommand\fR or \fBinvalidCommand\fR (whichever one you
were editing the entry widget from).  It is also recommended to not set an
associated \fBtextVariable\fR during validation, as that can cause the
entry widget to become out of sync with the \fBtextVariable\fR.
.SH "WIDGET COMMAND"
.PP
The \fBentry\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName subcommand \fR?\fIarg arg ...\fR?
.CE
\fISubcommand\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for entries take one or more indices as
arguments.  An index specifies a particular character in the entry's
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE
.TP
\fIpathName \fBvalidate\fR
This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS







|
|
|







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE
.TP
\fIpathName \fBvalidate\fR
This command is used to force an evaluation of the \fBvalidateCommand\fR
independent of the conditions specified by the \fBvalidate\fR option.
This is done by temporarily setting the \fBvalidate\fR option to \fBall\fR.
It returns 0 or 1.
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
399
400
401
402
403
404
405
406
407
408
409


410
411
412
413
414
415
416
417
418
419
420
421
422
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left become
visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for entries that give them
the following default behavior. In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or







|
<
|

>
>
|
|
|

<
<







398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413


414
415
416
417
418
419
420
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.


.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for entries that give them
the following default behavior. In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
.IP [5]
Clicking mouse button 1 with the Control key down will position the
insertion cursor in the entry without affecting the selection.
.IP [6]
If any normal printing characters are typed in an entry, they are
inserted at the point of the insertion cursor.
.IP [7]
The view in the entry can be adjusted by dragging with the middle
mouse button (button 2, or button 3 in TkAqua). If the middle mouse
button is clicked without moving the mouse, the selection is copied
into the entry at the position of the mouse cursor.
.IP [8]
If the mouse is dragged out of the entry on the left or right sides
while button 1 is pressed, the entry will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the







|
<
|
|







444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
.IP [5]
Clicking mouse button 1 with the Control key down will position the
insertion cursor in the entry without affecting the selection.
.IP [6]
If any normal printing characters are typed in an entry, they are
inserted at the point of the insertion cursor.
.IP [7]
The view in the entry can be adjusted by dragging with mouse button 2.

If mouse button 2 is clicked without moving the mouse, the selection
is copied into the entry at the position of the mouse cursor.
.IP [8]
If the mouse is dragged out of the entry on the left or right sides
while button 1 is pressed, the entry will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the
533
534
535
536
537
538
539
540
541
542
.PP
The behavior of entries can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::entry(n)
.SH KEYWORDS
entry, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
530
531
532
533
534
535
536



.PP
The behavior of entries can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::entry(n)
.SH KEYWORDS
entry, widget



Changes to doc/event.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'\"
'\" Copyright (c) 1996 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.
'\"
.TH event n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
event \- Miscellaneous event facilities: define virtual events and generate events
.SH SYNOPSIS
\fBevent\fI option \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBevent\fR command provides several facilities for dealing with
window system events, such as defining virtual events and synthesizing
events.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:






|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'\"
'\" Copyright (c) 1996 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.
'\" 
.TH event n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
event \- Miscellaneous event facilities: define virtual events and generate events
.SH SYNOPSIS
\fBevent\fI option \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBevent\fR command provides several facilities for dealing with
window system events, such as defining virtual events and synthesizing
events.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
is a list of all the virtual events that are currently defined.
If \fB<<\fIvirtual\fB>>\fR is specified then the return value is
a list whose elements are the physical event sequences currently
defined for the given virtual event;  if the virtual event is
not defined then an empty string is returned.
.RS
.PP
Note that virtual events that are not bound to physical event
sequences are \fInot\fR returned by \fBevent info\fR.
.RE
.SH "EVENT FIELDS"
.PP
The following options are supported for the \fBevent generate\fR
command.  These correspond to the
.QW %







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
is a list of all the virtual events that are currently defined.
If \fB<<\fIvirtual\fB>>\fR is specified then the return value is
a list whose elements are the physical event sequences currently
defined for the given virtual event;  if the virtual event is
not defined then an empty string is returned.
.RS
.PP
Note that virtual events that that are not bound to physical event
sequences are \fInot\fR returned by \fBevent info\fR.
.RE
.SH "EVENT FIELDS"
.PP
The following options are supported for the \fBevent generate\fR
command.  These correspond to the
.QW %
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115

116
117
118
119
120
121
122
\fISize\fR must be a screen distance;  it specifies the
\fIborder_width\fR field for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%B\fR substitution for binding scripts.
.TP
\fB\-button\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIdetail\fR field
for a \fBButton\fR or \fBButtonRelease\fR event, overriding
any button  number provided in the base \fIevent\fR argument.
Corresponds to the \fB%b\fR substitution for binding scripts.
.TP
\fB\-count\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIcount\fR field
for the event.  Valid for \fBExpose\fR events.
Corresponds to the \fB%c\fR substitution for binding scripts.

.TP
\fB\-data\fI string\fR
\fIString\fR may be any value; it specifies the \fIuser_data\fR field
for the event.  Only valid for virtual events.  Corresponds to the
\fB%d\fR substitution for virtual events in binding scripts.

.TP
\fB\-delta\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIdelta\fR field
for the \fBMouseWheel\fR event.  The \fIdelta\fR refers to the
direction and magnitude the mouse wheel was rotated.  Note the value
is not a screen distance but are units of motion in the mouse wheel.
Typically these values are multiples of 120.  For example, 120 should







|







>





>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
\fISize\fR must be a screen distance;  it specifies the
\fIborder_width\fR field for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%B\fR substitution for binding scripts.
.TP
\fB\-button\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIdetail\fR field
for a \fBButtonPress\fR or \fBButtonRelease\fR event, overriding
any button  number provided in the base \fIevent\fR argument.
Corresponds to the \fB%b\fR substitution for binding scripts.
.TP
\fB\-count\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIcount\fR field
for the event.  Valid for \fBExpose\fR events.
Corresponds to the \fB%c\fR substitution for binding scripts.
.VS 8.5
.TP
\fB\-data\fI string\fR
\fIString\fR may be any value; it specifies the \fIuser_data\fR field
for the event.  Only valid for virtual events.  Corresponds to the
\fB%d\fR substitution for virtual events in binding scripts.
.VE 8.5
.TP
\fB\-delta\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIdelta\fR field
for the \fBMouseWheel\fR event.  The \fIdelta\fR refers to the
direction and magnitude the mouse wheel was rotated.  Note the value
is not a screen distance but are units of motion in the mouse wheel.
Typically these values are multiples of 120.  For example, 120 should
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
\fISize\fR must be a screen distance;  it specifies the \fIheight\fR
field for the event.  Valid for \fBConfigure\fR events.
Corresponds to the \fB%h\fR substitution for binding scripts.
.TP
\fB\-keycode\fI number\fR
\fINumber\fR  must be an integer;  it specifies the \fIkeycode\fR
field for the event.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%k\fR substitution for binding scripts.
.TP
\fB\-keysym\fI name\fR
\fIName\fR must be the name of a valid keysym, such as \fBg\fR,
\fBspace\fR, or \fBReturn\fR;  its corresponding
keycode value is used as the \fIkeycode\fR field for event, overriding
any detail specified in the base \fIevent\fR argument.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%K\fR substitution for binding scripts.
.TP
\fB\-mode\fI notify\fR
\fINotify\fR specifies the \fImode\fR field for the event and must be
one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and
\fBFocusOut\fR events.
Corresponds to the \fB%m\fR substitution for binding scripts.
.TP
\fB\-override\fI boolean\fR
\fIBoolean\fR must be a boolean value;  it specifies the
\fIoverride_redirect\fR field for the event.
Valid for \fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
Corresponds to the \fB%o\fR substitution for binding scripts.
.TP
\fB\-place\fI where\fR
\fIWhere\fR specifies the \fIplace\fR field for the event;  it must be
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.
.TP
\fB\-root\fI window\fR
\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%R\fR substitution for binding scripts.
.TP
\fB\-rootx\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.  Corresponds to the \fB%X\fR substitution for binding scripts.
.TP
\fB\-rooty\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%Y\fR substitution for binding scripts.
.TP
\fB\-sendevent\fI boolean\fR
\fIBoolean\fR must be a boolean value;  it specifies the \fIsend_event\fR
field for the event.  Valid for all events.  Corresponds to the
\fB%E\fR substitution for binding scripts.
.TP
\fB\-serial\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIserial\fR field
for the event.  Valid for all events.
Corresponds to the \fB%#\fR substitution for binding scripts.
.TP
\fB\-state\fI state\fR
\fIState\fR specifies the \fIstate\fR field for the event.
For \fBKey\fR, \fBKeyRelease\fR, \fBButtons\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events
it must be an integer value.
For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR,
\fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR.
This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR
specified in the base \fIevent\fR.
Corresponds to the \fB%s\fR substitution for binding scripts.
.TP
\fB\-subwindow\fI window\fR
\fIWindow\fR specifies the \fIsubwindow\fR field for the event, either
as a path name for a Tk widget or as an integer window identifier.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events.
Similar to \fB%S\fR substitution for binding scripts.
.TP
\fB\-time\fI integer\fR
\fIInteger\fR must be an integer value;  it specifies the \fItime\fR field
for the event. Additonally the special value \fBcurrent\fR is allowed,
this value will be substituted by the current event time.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, \fBMotion\fR,
and \fBProperty\fR events.
Corresponds to the \fB%t\fR substitution for binding scripts.
.TP
\fB\-warp\fI boolean\fR
\fIboolean\fR must be a boolean value;  it specifies whether
the screen pointer should be warped as well.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, and \fBMotion\fR events.  The pointer will
only warp to a window if it is mapped.
.TP
\fB\-width\fI size\fR
\fISize\fR must be a screen distance;  it specifies the \fIwidth\fR field
for the event.
Valid for \fBConfigure\fR events.







|







|








|
















|







|






|
















|


|








|





|
<
|







|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
\fISize\fR must be a screen distance;  it specifies the \fIheight\fR
field for the event.  Valid for \fBConfigure\fR events.
Corresponds to the \fB%h\fR substitution for binding scripts.
.TP
\fB\-keycode\fI number\fR
\fINumber\fR  must be an integer;  it specifies the \fIkeycode\fR
field for the event.
Valid for \fBKeyPress\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%k\fR substitution for binding scripts.
.TP
\fB\-keysym\fI name\fR
\fIName\fR must be the name of a valid keysym, such as \fBg\fR,
\fBspace\fR, or \fBReturn\fR;  its corresponding
keycode value is used as the \fIkeycode\fR field for event, overriding
any detail specified in the base \fIevent\fR argument.
Valid for \fBKeyPress\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%K\fR substitution for binding scripts.
.TP
\fB\-mode\fI notify\fR
\fINotify\fR specifies the \fImode\fR field for the event and must be
one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and
\fBFocusOut\fR events.
Corresponds to the \fB%m\fR substitution for binding scripts.  
.TP
\fB\-override\fI boolean\fR
\fIBoolean\fR must be a boolean value;  it specifies the
\fIoverride_redirect\fR field for the event.
Valid for \fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
Corresponds to the \fB%o\fR substitution for binding scripts.
.TP
\fB\-place\fI where\fR
\fIWhere\fR specifies the \fIplace\fR field for the event;  it must be
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.
.TP
\fB\-root\fI window\fR
\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%R\fR substitution for binding scripts.
.TP
\fB\-rootx\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx_root\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.  Corresponds to the \fB%X\fR substitution for binding scripts.
.TP
\fB\-rooty\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy_root\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%Y\fR substitution for binding scripts.
.TP
\fB\-sendevent\fI boolean\fR
\fIBoolean\fR must be a boolean value;  it specifies the \fIsend_event\fR
field for the event.  Valid for all events.  Corresponds to the
\fB%E\fR substitution for binding scripts.
.TP
\fB\-serial\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIserial\fR field
for the event.  Valid for all events.
Corresponds to the \fB%#\fR substitution for binding scripts.
.TP
\fB\-state\fI state\fR
\fIState\fR specifies the \fIstate\fR field for the event.
For \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events
it must be an integer value.
For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR, 
\fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR.
This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR
specified in the base \fIevent\fR.
Corresponds to the \fB%s\fR substitution for binding scripts.
.TP
\fB\-subwindow\fI window\fR
\fIWindow\fR specifies the \fIsubwindow\fR field for the event, either
as a path name for a Tk widget or as an integer window identifier.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events.
Similar to \fB%S\fR substitution for binding scripts.
.TP
\fB\-time\fI integer\fR
\fIInteger\fR must be an integer value;  it specifies the \fItime\fR field
for the event.

Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, \fBMotion\fR,
and \fBProperty\fR events.
Corresponds to the \fB%t\fR substitution for binding scripts.
.TP
\fB\-warp\fI boolean\fR
\fIboolean\fR must be a boolean value;  it specifies whether
the screen pointer should be warped as well.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, and \fBMotion\fR events.  The pointer will
only warp to a window if it is mapped.
.TP
\fB\-width\fI size\fR
\fISize\fR must be a screen distance;  it specifies the \fIwidth\fR field
for the event.
Valid for \fBConfigure\fR events.
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
This option is useful when generating a series of events that should
be processed in order but at the front of the queue.
.RE
.TP
\fB\-x\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx\fR field
for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%x\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%X\fR substitution
for binding scripts.
.TP
\fB\-y\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%y\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%Y\fR substitution
for binding scripts.
.PP
Any options that are not specified when generating an event are filled
with the value 0, except for \fIserial\fR, which is filled with the
next X event serial number.
.SH "PREDEFINED VIRTUAL EVENTS"
.PP
Tk defines the following virtual events for the purposes of
notification:
.TP
\fB<<AltUnderlined>>\fR
This is sent to widget to notify it that the letter it has underlined
(as an accelerator indicator) with the \fB\-underline\fR option has
been pressed in combination with the Alt key. The usual response to







|











|








|
|
|

<







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
This option is useful when generating a series of events that should
be processed in order but at the front of the queue.
.RE
.TP
\fB\-x\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx\fR field
for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%x\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%X\fR substitution
for binding scripts.
.TP
\fB\-y\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%y\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%Y\fR substitution
for binding scripts.
.PP
Any options that are not specified when generating an event are filled 
with the value 0, except for \fIserial\fR, which is filled with the 
next X event serial number.  
.SH "PREDEFINED VIRTUAL EVENTS"

Tk defines the following virtual events for the purposes of
notification:
.TP
\fB<<AltUnderlined>>\fR
This is sent to widget to notify it that the letter it has underlined
(as an accelerator indicator) with the \fB\-underline\fR option has
been pressed in combination with the Alt key. The usual response to
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

601
602
603
604
605
changed.
.TP
\fB<<Selection>>\fR
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
This is sent to all widgets when the ttk theme changed. The ttk
widgets listen to this event and redisplay themselves when it fires.
The legacy widgets ignore this event.
.TP
\fB<<TraverseIn>>\fR
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<TraverseOut>>\fR
This is sent to a widget when the focus leaves the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<UndoStack>>\fR
This is sent to a text widget when its undo stack or redo stack becomes
empty or unempty.
.TP
\fB<<WidgetViewSync>>\fR
This is sent to a text widget when its internal data become obsolete,
and again when these internal data are back in sync with the widget
view. The detail field (%d substitution) is either true (when the
widget is in sync) or false (when it is not).
.PP
Tk defines the following virtual events for the purposes of unifying
bindings across multiple platforms. Users expect them to behave in the
following way:
.TP
\fB<<Clear>>\fR
Delete the currently selected widget contents.
.TP
\fB<<Copy>>\fR
Copy the currently selected widget contents to the clipboard.
.TP
\fB<<Cut>>\fR
Move the currently selected widget contents to the clipboard.
.TP
\fB<<LineEnd>>\fR
.
Move to the end of the line in the current widget while deselecting any
selected contents.
.TP
\fB<<LineStart>>\fR
.
Move to the start of the line in the current widget while deselecting any
selected contents.
.TP
\fB<<NextChar>>\fR
.
Move to the next item (i.e., visible character) in the current widget while
deselecting any selected contents.
.TP
\fB<<NextLine>>\fR
.
Move to the next line in the current widget while deselecting any selected
contents.
.TP
\fB<<NextPara>>\fR
.
Move to the next paragraph in the current widget while deselecting any
selected contents.
.TP
\fB<<NextWord>>\fR
.
Move to the next group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Paste>>\fR
Replace the currently selected widget contents with the contents of
the clipboard.
.TP
\fB<<PasteSelection>>\fR
Insert the contents of the selection at the mouse location. (This
event has meaningful \fB%x\fR and \fB%y\fR substitutions).
.TP
\fB<<PrevChar>>\fR
.
Move to the previous item (i.e., visible character) in the current widget
while deselecting any selected contents.
.TP
\fB<<PrevLine>>\fR
.
Move to the previous line in the current widget while deselecting any selected
contents.
.TP
\fB<<PrevPara>>\fR
.
Move to the previous paragraph in the current widget while deselecting any
selected contents.
.TP
\fB<<PrevWindow>>\fR
Traverse to the previous window.
.TP
\fB<<PrevWord>>\fR
.
Move to the previous group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Redo>>\fR
Redo one undone action.
.TP
\fB<<SelectAll>>\fR
.
Set the range of selected contents to the complete widget.
.TP
\fB<<SelectLineEnd>>\fR
.
Move to the end of the line in the current widget while extending the range
of selected contents.
.TP
\fB<<SelectLineStart>>\fR
.
Move to the start of the line in the current widget while extending the range
of selected contents.
.TP
\fB<<SelectNextChar>>\fR
.
Move to the next item (i.e., visible character) in the current widget while
extending the range of selected contents.
.TP
\fB<<SelectNextLine>>\fR
.
Move to the next line in the current widget while extending the range of
selected contents.
.TP
\fB<<SelectNextPara>>\fR
.
Move to the next paragraph in the current widget while extending the range
of selected contents.
.TP
\fB<<SelectNextWord>>\fR
.
Move to the next group of items (i.e., visible word) in the current widget
while extending the range of selected contents.
.TP
\fB<<SelectNone>>\fR
.
Reset the range of selected contents to be empty.
.TP
\fB<<SelectPrevChar>>\fR
.
Move to the previous item (i.e., visible character) in the current widget
while extending the range of selected contents.
.TP
\fB<<SelectPrevLine>>\fR
.
Move to the previous line in the current widget while extending the range of
selected contents.
.TP
\fB<<SelectPrevPara>>\fR
.
Move to the previous paragraph in the current widget while extending the
range of selected contents.
.TP
\fB<<SelectPrevWord>>\fR
.
Move to the previous group of items (i.e., visible word) in the current widget
while extending the range of selected contents.
.TP
\fB<<ToggleSelection>>\fR
.
Toggle the selection.
.TP
\fB<<Undo>>\fR
.
Undo the last action.
.SH EXAMPLES
.SS "MAPPING KEYS TO VIRTUAL EVENTS"
.PP
In order for a virtual event binding to trigger, two things must
happen.  First, the virtual event must be defined with the
\fBevent add\fR command.  Second, a binding must be created for
the virtual event with the \fBbind\fR command.
Consider the following virtual event definitions:
.PP
.CS
\fBevent add\fR <<Paste>> <Control-y>
\fBevent add\fR <<Paste>> <Button-2>
\fBevent add\fR <<Save>> <Control-X><Control-S>
\fBevent add\fR <<Save>> <Shift-F12>
if {[tk windowingsystem] eq "aqua"} {
    \fBevent add\fR <<Save>> <Command-s>
}
.CE
.PP
In the \fBbind\fR command, a virtual event can be bound like any other
builtin event type as follows:
.PP
.CS
bind Entry <<Paste>> {%W insert [selection get]}
.CE
.PP
The double angle brackets are used to specify that a virtual event is being
bound.  If the user types Control-y or presses button 2, or if
a \fB<<Paste>>\fR virtual event is synthesized with \fBevent generate\fR,
then the \fB<<Paste>>\fR binding will be invoked.
.PP
If a virtual binding has the exact same sequence as a separate
physical binding, then the physical binding will take precedence.
Consider the following example:
.PP
.CS
\fBevent add\fR <<Paste>> <Control-y> <Meta-Control-y>
bind Entry <Control-y> {puts Control-y}
bind Entry <<Paste>> {puts Paste}
.CE
.PP
When the user types Control-y the \fB<Control-y>\fR binding
will be invoked, because a physical event is considered
more specific than a virtual event, all other things being equal.
However, when the user types Meta-Control-y the
\fB<<Paste>>\fR binding will be invoked, because the
\fBMeta\fR modifier in the physical pattern associated with the
virtual binding is more specific than the \fB<Control-y\fR> sequence for
the physical event.
.PP
Bindings on a virtual event may be created before the virtual event exists.
Indeed, the virtual event never actually needs to be defined, for instance,
on platforms where the specific virtual event would be meaningless or
ungeneratable.
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:
.PP
.CS
bind Entry <Control-y> {}
\fBevent add\fR <<Paste>> <F6>
.CE
.PP
the behavior will change such in two ways.  First, the shadowed
\fB<<Paste>>\fR binding will emerge.
Typing Control-y will no longer invoke the \fB<Control-y>\fR binding,
but instead invoke the virtual event \fB<<Paste>>\fR.  Second,
pressing the F6 key will now also invoke the \fB<<Paste>>\fR binding.
.SS "MOVING THE MOUSE POINTER"
.PP
Sometimes it is useful to be able to really move the mouse pointer. For
example, if you have some software that is capable of demonstrating directly
to the user how to use the program. To do this, you need to
.QW warp
the mouse around by using \fBevent generate\fR, like this:
.PP
.CS
for {set xy 0} {$xy < 200} {incr xy} {
    \fBevent generate\fR . <Motion> -x $xy -y $xy -warp 1
    update
    after 50
}
.CE
.PP
Note that it is usually considered bad style to move the mouse pointer for the
user because it removes control from them. Therefore this technique should be
used with caution. Also note that it is not guaranteed to function on all
platforms.
.SH "SEE ALSO"
bind(n)

.SH KEYWORDS
event, binding, define, handle, virtual event
'\" Local Variables:
'\" mode: nroff
'\" End:







|
<
<












<
<
<
<
<
<
<
<
<
<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<

<
|






<

|
|
|
|
<
<
<

<


<



<








<

|



<





|











<

|
|

<


|


<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<


>


<
<
<
335
336
337
338
339
340
341
342


343
344
345
346
347
348
349
350
351
352
353
354










355
356
357
358
359
360
361
362
363
364
365
366
367
368






























369
370
371
372
373
374
375
376















377
378
379





380
381
382






























































383

384

385
386
387
388
389
390
391

392
393
394
395
396



397

398
399

400
401
402

403
404
405
406
407
408
409
410

411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436

437
438
439
440
441













442






443
444
445
446
447



changed.
.TP
\fB<<Selection>>\fR
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
This is sent to a text widget when the ttk (Tile) theme changed.


.TP
\fB<<TraverseIn>>\fR
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<TraverseOut>>\fR
This is sent to a widget when the focus leaves the widget because of a
user-driven
.QW "tab to widget"
action.










.PP
Tk defines the following virtual events for the purposes of unifying
bindings across multiple platforms. Users expect them to behave in the
following way:
.TP
\fB<<Clear>>\fR
Delete the currently selected widget contents.
.TP
\fB<<Copy>>\fR
Copy the currently selected widget contents to the clipboard.
.TP
\fB<<Cut>>\fR
Move the currently selected widget contents to the clipboard.
.TP






























\fB<<Paste>>\fR
Replace the currently selected widget contents with the contents of
the clipboard.
.TP
\fB<<PasteSelection>>\fR
Insert the contents of the selection at the mouse location. (This
event has meaningful \fB%x\fR and \fB%y\fR substitutions).
.TP















\fB<<PrevWindow>>\fR
Traverse to the previous window.
.TP





\fB<<Redo>>\fR
Redo one undone action.
.TP






























































\fB<<Undo>>\fR

Undo the last action.

.SH "VIRTUAL EVENT EXAMPLES"
.PP
In order for a virtual event binding to trigger, two things must
happen.  First, the virtual event must be defined with the
\fBevent add\fR command.  Second, a binding must be created for
the virtual event with the \fBbind\fR command.
Consider the following virtual event definitions:

.CS
event add <<Paste>> <Control-y>
event add <<Paste>> <Button-2>
event add <<Save>> <Control-X><Control-S>
event add <<Save>> <Shift-F12>



.CE

In the \fBbind\fR command, a virtual event can be bound like any other
builtin event type as follows:

.CS
bind Entry <<Paste>> {%W insert [selection get]}
.CE

The double angle brackets are used to specify that a virtual event is being
bound.  If the user types Control-y or presses button 2, or if
a \fB<<Paste>>\fR virtual event is synthesized with \fBevent generate\fR,
then the \fB<<Paste>>\fR binding will be invoked.
.PP
If a virtual binding has the exact same sequence as a separate
physical binding, then the physical binding will take precedence.
Consider the following example:

.CS
event add <<Paste>> <Control-y> <Meta-Control-y>
bind Entry <Control-y> {puts Control-y}
bind Entry <<Paste>> {puts Paste}
.CE

When the user types Control-y the \fB<Control-y>\fR binding
will be invoked, because a physical event is considered
more specific than a virtual event, all other things being equal.
However, when the user types Meta-Control-y the
\fB<<Paste>>\fR binding will be invoked, because the
\fBMeta\fR modifier in the physical pattern associated with the 
virtual binding is more specific than the \fB<Control-y\fR> sequence for
the physical event.
.PP
Bindings on a virtual event may be created before the virtual event exists.
Indeed, the virtual event never actually needs to be defined, for instance,
on platforms where the specific virtual event would be meaningless or
ungeneratable.
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:

.CS
bind <Entry> <Control-y> {}
event add <<Paste>> <Key-F6>
.CE

the behavior will change such in two ways.  First, the shadowed
\fB<<Paste>>\fR binding will emerge.
Typing Control-y will no longer invoke the \fB<Control-y>\fR binding, 
but instead invoke the virtual event \fB<<Paste>>\fR.  Second,
pressing the F6 key will now also invoke the \fB<<Paste>>\fR binding.




















.SH "SEE ALSO"
bind(n)

.SH KEYWORDS
event, binding, define, handle, virtual event



Changes to doc/focus.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH focus n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
focus \- Manage the input focus
.SH SYNOPSIS
.nf
\fBfocus\fR
\fBfocus \fIwindow\fR
\fBfocus \fIoption\fR ?\fIarg ...\fR?
.fi
.BE

.SH DESCRIPTION
.PP
The \fBfocus\fR command is used to manage the Tk input focus.
At any given time, one window on each display is designated as
the \fIfocus window\fR;  any key press or key release events for the
display are sent to that window.
It is normally up to the window manager to redirect the focus among the






|










|


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH focus n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
focus \- Manage the input focus
.SH SYNOPSIS
.nf
\fBfocus\fR
\fBfocus \fIwindow\fR
\fBfocus \fIoption\fR ?\fIarg arg ...\fR?
.fi
.BE

.SH DESCRIPTION
.PP
The \fBfocus\fR command is used to manage the Tk input focus.
At any given time, one window on each display is designated as
the \fIfocus window\fR;  any key press or key release events for the
display are sent to that window.
It is normally up to the window manager to redirect the focus among the
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
will stay on the top-level window containing the window with the focus.
However, Tk generates FocusIn and FocusOut events just as if the X
focus were on the internal window.   This approach gets around a
number of problems that would occur if the X focus were actually moved;
the fact that the X focus is on the top-level is invisible unless
you use C code to query the X server directly.
.SH "EXAMPLE"
.PP
To make a window that only participates in the focus traversal ring
when a variable is set, add the following bindings to the widgets
\fIbefore\fR and \fIafter\fR it in that focus ring:
.CS
button .before \-text "Before"
button .middle \-text "Middle"
button .after  \-text "After"







<







102
103
104
105
106
107
108

109
110
111
112
113
114
115
will stay on the top-level window containing the window with the focus.
However, Tk generates FocusIn and FocusOut events just as if the X
focus were on the internal window.   This approach gets around a
number of problems that would occur if the X focus were actually moved;
the fact that the X focus is on the top-level is invisible unless
you use C code to query the X server directly.
.SH "EXAMPLE"

To make a window that only participates in the focus traversal ring
when a variable is set, add the following bindings to the widgets
\fIbefore\fR and \fIafter\fR it in that focus ring:
.CS
button .before \-text "Before"
button .middle \-text "Middle"
button .after  \-text "After"
126
127
128
129
130
131
132

133
134
135
136
137
   if {!$traverseToMiddle} {
      \fBfocus\fR .before
      break
   }
}
\fBfocus\fR .before
.CE

.SH KEYWORDS
events, focus, keyboard, top-level, window manager
'\" Local Variables:
'\" mode: nroff
'\" End:







>


<
<
<
126
127
128
129
130
131
132
133
134
135



   if {!$traverseToMiddle} {
      \fBfocus\fR .before
      break
   }
}
\fBfocus\fR .before
.CE

.SH KEYWORDS
events, focus, keyboard, top-level, window manager



Changes to doc/focusNext.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tk_focusNext n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_focusNext, tk_focusPrev, tk_focusFollowsMouse \- Utility procedures for managing the input focus.
.SH SYNOPSIS
\fBtk_focusNext \fIwindow\fR
.sp
\fBtk_focusPrev \fIwindow\fR
.sp
\fBtk_focusFollowsMouse\fR
.BE

.SH DESCRIPTION
.PP
\fBtk_focusNext\fR is a utility procedure used for keyboard traversal.
It returns the
.QW next
window after \fIwindow\fR in focus order. The focus order is determined by
the stacking order of windows and the structure of the window hierarchy.






|













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tk_focusNext n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_focusNext, tk_focusPrev, tk_focusFollowsMouse \- Utility procedures for managing the input focus.
.SH SYNOPSIS
\fBtk_focusNext \fIwindow\fR
.sp
\fBtk_focusPrev \fIwindow\fR
.sp
\fBtk_focusFollowsMouse\fR
.BE

.SH DESCRIPTION
.PP
\fBtk_focusNext\fR is a utility procedure used for keyboard traversal.
It returns the
.QW next
window after \fIwindow\fR in focus order. The focus order is determined by
the stacking order of windows and the structure of the window hierarchy.
49
50
51
52
53
54
55

56
57
58
59
60
The \fBfocus\fR command may be used to move the focus to a window
other than the one under the mouse, but as soon as the mouse moves
into a new window the focus will jump to that window.
Note: at present there is no built-in support for returning the
application to an explicit focus model;  to do this you will have
to write a script that deletes the bindings created by
\fBtk_focusFollowsMouse\fR.

.SH KEYWORDS
focus, keyboard traversal, top-level
'\" Local Variables:
'\" mode: nroff
'\" End:







>


<
<
<
50
51
52
53
54
55
56
57
58
59



The \fBfocus\fR command may be used to move the focus to a window
other than the one under the mouse, but as soon as the mouse moves
into a new window the focus will jump to that window.
Note: at present there is no built-in support for returning the
application to an explicit focus model;  to do this you will have
to write a script that deletes the bindings created by
\fBtk_focusFollowsMouse\fR.

.SH KEYWORDS
focus, keyboard traversal, top-level



Changes to doc/font.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\" Copyright (c) 2006-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.
'\"
.TH font n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
font \- Create and inspect fonts.
.SH SYNOPSIS
\fBfont\fI option \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBfont\fR command provides several facilities for dealing with
fonts, such as defining named fonts and inspecting the actual attributes of
a font.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:
.TP
\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR? ?\fB\-\|\-\fR? ?\fIchar\fR?
.
Returns information about the actual attributes that are obtained when
\fIfont\fR is used on \fIwindow\fR's display; the actual attributes obtained
may differ from the attributes requested due to platform-dependent
limitations, such as the availability of font families and point sizes.
\fIfont\fR is a font description; see \fBFONT DESCRIPTIONS\fR below.  If the
\fIwindow\fR argument is omitted, it defaults to the main window.  If
\fIoption\fR is specified, returns the value of that attribute; if it is
omitted, the return value is a list of all the attributes and their values.
See \fBFONT OPTIONS\fR below for a list of the possible attributes.  If the
\fIchar\fR argument is supplied, it must be a single character. The font
attributes returned will be those of the specific font used to render
that character, which will be different from the base font if the base
font does not contain the given character.  If \fIchar\fR may be a hyphen, it
should be preceded by \fB\-\|\-\fR to distinguish it from a misspelled
\fIoption\fR.
.TP
\fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the desired attributes for the named font called
\fIfontname\fR.  If no \fIoption\fR is specified, returns a list describing
all the options and their values for \fIfontname\fR.  If a single \fIoption\fR
is specified with no \fIvalue\fR, then returns the current value of that
attribute.  If one or more \fIoption\fR\-\fIvalue\fR pairs are specified,
then the command modifies the given named font to have the given values; in
this case, all widgets using that font will redisplay themselves using the
new attributes for the font.  See \fBFONT OPTIONS\fR below for a list of the
possible attributes.
.RS
.PP
Note that on Aqua/Mac OS X, the system fonts (see
\fBPLATFORM SPECIFIC FONTS\fR below) may not be actually altered because they
are implemented by the system theme. To achieve the effect of modification,
use \fBfont actual\fR to get their configuration and \fBfont create\fR to
synthesize a copy of the font which can be modified.
.RE
.TP
\fBfont create\fR ?\fIfontname\fR? ?\fIoption value ...\fR?
.
Creates a new named font and returns its name.  \fIfontname\fR specifies the
name for the font; if it is omitted, then Tk generates a new name of the
form \fBfont\fIx\fR, where \fIx\fR is an integer.  There may be any number
of \fIoption\fR\-\fIvalue\fR pairs, which provide the desired attributes for






|







|













|











|











<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52








53
54
55
56
57
58
59
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\" Copyright (c) 2006-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.
'\" 
.TH font n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
font \- Create and inspect fonts.
.SH SYNOPSIS
\fBfont\fI option \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBfont\fR command provides several facilities for dealing with
fonts, such as defining named fonts and inspecting the actual attributes of
a font.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:
.TP
\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR? ?\fB\-\|\-\fR? ?\fIchar\fR?
.
Returns information about the actual attributes that are obtained when
\fIfont\fR is used on \fIwindow\fR's display; the actual attributes obtained
may differ from the attributes requested due to platform-dependent
limitations, such as the availability of font families and pointsizes.
\fIfont\fR is a font description; see \fBFONT DESCRIPTIONS\fR below.  If the
\fIwindow\fR argument is omitted, it defaults to the main window.  If
\fIoption\fR is specified, returns the value of that attribute; if it is
omitted, the return value is a list of all the attributes and their values.
See \fBFONT OPTIONS\fR below for a list of the possible attributes.  If the
\fIchar\fR argument is supplied, it must be a single character. The font
attributes returned will be those of the specific font used to render
that character, which will be different from the base font if the base
font does not contain the given character.  If \fIchar\fR may be a hyphen, it
should be preceded by \fB\-\|\-\fR to distinguish it from a misspelled
\fIoption\fR.
.TP 
\fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the desired attributes for the named font called
\fIfontname\fR.  If no \fIoption\fR is specified, returns a list describing
all the options and their values for \fIfontname\fR.  If a single \fIoption\fR
is specified with no \fIvalue\fR, then returns the current value of that
attribute.  If one or more \fIoption\fR\-\fIvalue\fR pairs are specified,
then the command modifies the given named font to have the given values; in
this case, all widgets using that font will redisplay themselves using the
new attributes for the font.  See \fBFONT OPTIONS\fR below for a list of the
possible attributes.








.TP
\fBfont create\fR ?\fIfontname\fR? ?\fIoption value ...\fR?
.
Creates a new named font and returns its name.  \fIfontname\fR specifies the
name for the font; if it is omitted, then Tk generates a new name of the
form \fBfont\fIx\fR, where \fIx\fR is an integer.  There may be any number
of \fIoption\fR\-\fIvalue\fR pairs, which provide the desired attributes for
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
omitted, it defaults to the main window.
.TP
\fBfont measure \fIfont\fR ?\fB\-displayof \fIwindow\fR? \fItext\fR
.
Measures the amount of space the string \fItext\fR would use in the given
\fIfont\fR when displayed in \fIwindow\fR.  \fIfont\fR is a font description;
see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR argument is
omitted, it
defaults to the main window.  The return value is the total width in pixels
of \fItext\fR, not including the extra pixels used by highly exaggerated
characters such as cursive
.QW f .
If the string contains newlines or tabs,
those characters are not expanded or treated specially when measuring the
string.







|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
omitted, it defaults to the main window.
.TP
\fBfont measure \fIfont\fR ?\fB\-displayof \fIwindow\fR? \fItext\fR
.
Measures the amount of space the string \fItext\fR would use in the given
\fIfont\fR when displayed in \fIwindow\fR.  \fIfont\fR is a font description;
see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR argument is
omitted, it 
defaults to the main window.  The return value is the total width in pixels
of \fItext\fR, not including the extra pixels used by highly exaggerated
characters such as cursive
.QW f .
If the string contains newlines or tabs,
those characters are not expanded or treated specially when measuring the
string.
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
omitted, it defaults to the main window.  If \fIoption\fR is specified,
returns the value of that metric; if it is omitted, the return value is a
list of all the metrics and their values.  See \fBFONT METRICS\fR
below for a list of the possible metrics.
.TP
\fBfont names\fR
The return value is a list of all the named fonts that are currently defined.
.SH "FONT DESCRIPTIONS"
.PP
The following formats are accepted as a font description anywhere
\fIfont\fR is specified as an argument above; these same forms are also
permitted when specifying the \fB\-font\fR option for widgets.
.TP
[1] \fIfontname\fR
.
The name of a named font, created using the \fBfont create\fR command.  When
a widget uses a named font, it is guaranteed that this will never cause an
error, as long as the named font exists, no matter what potentially invalid
or meaningless set of attributes the named font has.  If the named font
cannot be displayed with exactly the specified attributes, some other close
font will be substituted automatically.
.TP
[2] \fIsystemfont\fR
.
The platform-specific name of a font, interpreted by the graphics server.
This also includes, under X, an XLFD (see [4]) for which a single
.QW \fB*\fR
character was used to elide more than one field in the middle of the
name.  See \fBPLATFORM SPECIFIC FONTS\fR for a list of the system fonts.
.TP
[3] \fIfamily \fR?\fIsize\fR? ?\fIstyle\fR? ?\fIstyle ...\fR?
.
A properly formed list whose first element is the desired font
\fIfamily\fR and whose optional second element is the desired \fIsize\fR.
The interpretation of the \fIsize\fR attribute follows the same rules
described for \fB\-size\fR in \fBFONT OPTIONS\fR below.  Any







|




















|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
omitted, it defaults to the main window.  If \fIoption\fR is specified,
returns the value of that metric; if it is omitted, the return value is a
list of all the metrics and their values.  See \fBFONT METRICS\fR
below for a list of the possible metrics.
.TP
\fBfont names\fR
The return value is a list of all the named fonts that are currently defined.
.SH "FONT DESCRIPTION"
.PP
The following formats are accepted as a font description anywhere
\fIfont\fR is specified as an argument above; these same forms are also
permitted when specifying the \fB\-font\fR option for widgets.
.TP
[1] \fIfontname\fR
.
The name of a named font, created using the \fBfont create\fR command.  When
a widget uses a named font, it is guaranteed that this will never cause an
error, as long as the named font exists, no matter what potentially invalid
or meaningless set of attributes the named font has.  If the named font
cannot be displayed with exactly the specified attributes, some other close
font will be substituted automatically.
.TP
[2] \fIsystemfont\fR
.
The platform-specific name of a font, interpreted by the graphics server.
This also includes, under X, an XLFD (see [4]) for which a single
.QW \fB*\fR
character was used to elide more than one field in the middle of the
name.  See \fBPLATFORM-SPECIFIC\fR issues for a list of the system fonts.
.TP
[3] \fIfamily \fR?\fIsize\fR? ?\fIstyle\fR? ?\fIstyle ...\fR?
.
A properly formed list whose first element is the desired font
\fIfamily\fR and whose optional second element is the desired \fIsize\fR.
The interpretation of the \fIsize\fR attribute follows the same rules
described for \fB\-size\fR in \fBFONT OPTIONS\fR below.  Any
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
system font.  Cases [3], [4], and [5] are accepted on all
platforms and the closest available font will be used.  In some situations
it may not be possible to find any close font (e.g., the font family was
a garbage value); in that case, some system-dependent default font is
chosen.  If the font description does not match any of the above patterns,
an error is generated.
.SH "FONT METRICS"
.PP

The following options are used by the \fBfont metrics\fR command to query
font-specific data determined when the font was created.  These properties are
for the whole font itself and not for individual characters drawn in that
font.  In the following definitions, the
.QW baseline
of a font is the
horizontal line where the bottom of most letters line up; certain letters,







<
>







177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
system font.  Cases [3], [4], and [5] are accepted on all
platforms and the closest available font will be used.  In some situations
it may not be possible to find any close font (e.g., the font family was
a garbage value); in that case, some system-dependent default font is
chosen.  If the font description does not match any of the above patterns,
an error is generated.
.SH "FONT METRICS"

.
The following options are used by the \fBfont metrics\fR command to query
font-specific data determined when the font was created.  These properties are
for the whole font itself and not for individual characters drawn in that
font.  In the following definitions, the
.QW baseline
of a font is the
horizontal line where the bottom of most letters line up; certain letters,
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
characters, or is
.QW \fB0\fR
if this is a proportionally-spaced font, where
individual characters have different widths.  The widths of control
characters, tab characters, and other non-printing characters are not
included when calculating this value.
.SH "FONT OPTIONS"
.PP
The following options are supported on all platforms, and are used when
constructing a named font or when specifying a font using style [5] as
above:
.TP
\fB\-family \fIname\fR
.
The case-insensitive font family name.  Tk guarantees to support the font







<







219
220
221
222
223
224
225

226
227
228
229
230
231
232
characters, or is
.QW \fB0\fR
if this is a proportionally-spaced font, where
individual characters have different widths.  The widths of control
characters, tab characters, and other non-printing characters are not
included when calculating this value.
.SH "FONT OPTIONS"

The following options are supported on all platforms, and are used when
constructing a named font or when specifying a font using style [5] as
above:
.TP
\fB\-family \fIname\fR
.
The case-insensitive font family name.  Tk guarantees to support the font
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
font should be underlined.  The default value for underline is \fBfalse\fR.
.TP
\fB\-overstrike \fIboolean\fR
The value is a boolean flag that specifies whether a horizontal line should
be drawn through the middle of characters in this font.  The default value
for overstrike is \fBfalse\fR.
.SH "STANDARD FONTS"
.PP
The following named fonts are supported on all systems, and default to values
that match appropriate system defaults.
.TP
\fBTkDefaultFont\fR
.
This font is the default for all GUI items not otherwise specified.
.TP







|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
font should be underlined.  The default value for underline is \fBfalse\fR.
.TP
\fB\-overstrike \fIboolean\fR
The value is a boolean flag that specifies whether a horizontal line should
be drawn through the middle of characters in this font.  The default value
for overstrike is \fBfalse\fR.
.SH "STANDARD FONTS"
.LP
The following named fonts are supported on all systems, and default to values
that match appropriate system defaults.
.TP
\fBTkDefaultFont\fR
.
This font is the default for all GUI items not otherwise specified.
.TP
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
\fBTkTooltipFont\fR
.
This font should be used for tooltip windows (transient information windows).
.LP
It is \fInot\fR advised to change these fonts, as they may be modified by Tk
itself in response to system changes. Instead, make a copy of the font and
modify that.
.SH "PLATFORM SPECIFIC FONTS"
.PP
The following system fonts are supported:
.TP
\fBX Windows\fR
All valid X font names, including those listed by xlsfonts(1), are available.
.TP
\fBMS Windows\fR







|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
\fBTkTooltipFont\fR
.
This font should be used for tooltip windows (transient information windows).
.LP
It is \fInot\fR advised to change these fonts, as they may be modified by Tk
itself in response to system changes. Instead, make a copy of the font and
modify that.
.SH "PLATFORM-SPECIFIC FONTS"
.PP
The following system fonts are supported:
.TP
\fBX Windows\fR
All valid X font names, including those listed by xlsfonts(1), are available.
.TP
\fBMS Windows\fR
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404

405
406
407
408
409
\fBsystemPushButtonFont\fR	\fBsystemUtilityWindowTitleFont\fR
\fBsystemAlertHeaderFont\fR	\fBsystemToolbarFont\fR
\fBsystemMiniSystemFont\fR	\fBsystemDetailSystemFont\fR
\fBsystemDetailEmphasizedSystemFont\fR
.DE
.RE
.SH EXAMPLE
.PP
Fill a text widget with lots of font demonstrators, one for every font
family installed on your system:
.CS
pack [text .t \-wrap none] \-fill both \-expand 1
set count 0
set tabwidth 0
foreach family [lsort \-dictionary [\fBfont families\fR]] {
    .t tag configure f[incr count] \-font [list $family 10]
    .t insert end ${family}:\\t {} \e
            "This is a simple sampler\en" f$count
    set w [\fBfont measure\fR [.t cget \-font] ${family}:]
    if {$w+5 > $tabwidth} {
        set tabwidth [expr {$w+5}]
        .t configure \-tabs $tabwidth
    }
}
.CE

.SH "SEE ALSO"
options(n)

.SH KEYWORDS
font
'\" Local Variables:
'\" mode: nroff
'\" End:







<

















>


>


<
<
<
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398



\fBsystemPushButtonFont\fR	\fBsystemUtilityWindowTitleFont\fR
\fBsystemAlertHeaderFont\fR	\fBsystemToolbarFont\fR
\fBsystemMiniSystemFont\fR	\fBsystemDetailSystemFont\fR
\fBsystemDetailEmphasizedSystemFont\fR
.DE
.RE
.SH EXAMPLE

Fill a text widget with lots of font demonstrators, one for every font
family installed on your system:
.CS
pack [text .t \-wrap none] \-fill both \-expand 1
set count 0
set tabwidth 0
foreach family [lsort \-dictionary [\fBfont families\fR]] {
    .t tag configure f[incr count] \-font [list $family 10]
    .t insert end ${family}:\\t {} \e
            "This is a simple sampler\en" f$count
    set w [\fBfont measure\fR [.t cget \-font] ${family}:]
    if {$w+5 > $tabwidth} {
        set tabwidth [expr {$w+5}]
        .t configure \-tabs $tabwidth
    }
}
.CE

.SH "SEE ALSO"
options(n)

.SH KEYWORDS
font



Deleted doc/fontchooser.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
'\"
'\" Copyright (c) 2008 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.
'\"
.TH fontchooser n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fontchooser \- control font selection dialog
.SH SYNOPSIS
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?
.sp
\fBtk fontchooser\fR \fBshow\fR
.sp
\fBtk fontchooser\fR \fBhide\fR
.BE
.SH DESCRIPTION
.PP
The \fBtk fontchooser\fR command controls the Tk font selection dialog. It uses
the native platform font selection dialog where available, or a dialog
implemented in Tcl otherwise.
.PP
Unlike most of the other Tk dialog commands, \fBtk fontchooser\fR does not
return an immediate result, as on some platforms (Mac OS X) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:
.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).
.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.
.TP
\fBtk fontchooser\fR \fBhide\fR
.
Hide the font selection dialog if it is visible and cause any pending
\fBtk fontchooser\fR \fBshow\fR command to return.
.PP
.SH "CONFIGURATION OPTIONS"
.TP
\fB\-parent\fR
Specifies/returns the logical parent window of the font selection dialog
(similar to the \fB\-parent\fR option to other dialogs). The font selection
dialog is hidden if it is visible when the parent window is destroyed.
.TP
\fB\-title\fR
Specifies/returns the title of the dialog. Has no effect on platforms where the
font selection dialog does not support titles.
.TP
\fB\-font\fR
Specifies/returns the font that is currently selected in the dialog if it is
visible, or that will be initially selected when the dialog is shown (if
supported by the platform). Can be set to the empty string to indicate that no
font should be selected. Fonts can be specified in any form given by the "FONT
DESCRIPTION" section in the \fBfont\fR manual page.
.TP
\fB\-command\fR
Specifies/returns the command prefix to be called when a font selection has
been made by the user. The command prefix is evaluated at the global level
after having the specification of the selected font appended. On platforms
where the font selection dialog offers the user control of further font
attributes (such as color), additional key/value pairs may be appended before
evaluation. Can be set to the empty string to indicate that no callback should
be invoked. Fonts are specified by a list of form [3] of the "FONT DESCRIPTION"
section in the \fBfont\fR manual page (i.e. a list of the form
\fI{family size style ?style ...?}\fR).
.TP
\fB\-visible\fR
Read-only option that returns a boolean indicating whether the font selection
dialog is currently visible. Attempting to set this option results in an error.

.PP
.SH "VIRTUAL EVENTS"
.TP
\fB<<TkFontchooserVisibility>>\fR
Sent to the dialog parent whenever the visibility of the font selection dialog
changes, both as a result of user action (e.g. disposing of the dialog via
OK/Cancel button or close box) and of the \fBtk fontchooser\fR
\fBshow\fR/\fBhide\fR commands being called. Binding scripts can determine the
current visibility of the dialog by querying the \fB\-visible\fR configuration
option.
.TP
\fB<<TkFontchooserFontChanged>>\fR
Sent to the dialog parent whenever the font selection dialog is visible and the
selected font changes, both as a result of user action and of the \fB\-font\fR
configuration option being set. Binding scripts can determine the currently
selected font by querying the \fB\-font\fR configuration option.
.PP
.SH NOTES
.PP
Callers should not expect a result from \fBtk fontchooser\fR \fBshow\fR and may
not assume that the dialog has been withdrawn or closed when the command
returns. All user interaction with the dialog is communicated to the caller via
the \fB\-command\fR callback and the \fB<<TkFontchooser*>>\fR virtual events.
It is implementation dependent which exact user actions result in the callback
being called resp. the virtual events being sent. Where an Apply or OK button
is present in the dialog, that button will trigger the \fB\-command\fR callback
and \fB<<TkFontchooserFontChanged>>\fR virtual event. On some implementations
other user actions may also have that effect; on Mac OS X for instance, the
standard font selection dialog immediately reflects all user choices to the
caller.
.PP
In the presence of multiple widgets intended to be influenced by the font
selection dialog, care needs to be taken to correctly handle focus changes: the
font selected in the dialog should always match the current font of the widget
with the focus, and the \fB\-command\fR callback should only act on the widget
with the focus. The recommended practice is to set font dialog \fB\-font\fR and
\fB\-command\fR configuration options in per\-widget \fB<FocusIn>\fR handlers
(and if necessary to unset them \- i.e. set to the empty string \- in
corresponding \fB<FocusOut>\fR handlers). This is particularly important for
implementers of library code using the font selection dialog, to avoid
conflicting with application code that may also want to use the dialog.
.PP
Because the font selection dialog is application-global, in the presence of
multiple interpreters calling \fBtk fontchooser\fR, only the \fB\-command\fR
callback set by the interpreter that most recently called \fBtk fontchooser\fR
\fBconfigure\fR or \fBtk fontchooser\fR \fBshow\fR will be invoked in response
to user action and only the \fB\-parent\fR set by that interpreter will receive
\fB<<TkFontchooser*>>\fR virtual events.
.PP
The font dialog implementation may only store (and return) \fBfont\fR
\fBactual\fR data as the value of the \fB\-font\fR configuration option. This
can be an issue when \fB\-font\fR is set to a named font, if that font is
subsequently changed, the font dialog \fB\-font\fR option needs to be set again
to ensure its selected font matches the new value of the named font.
.PP
.SH EXAMPLE
.PP
.CS
proc fontchooserDemo {} {
    wm title . "Font Chooser Demo"
    \fBtk fontchooser\fR \fBconfigure\fR \-parent .
    button .b \-command fontchooserToggle \-takefocus 0
    fontchooserVisibility .b
    bind . \fB<<TkFontchooserVisibility>>\fR \\
            [list fontchooserVisibility .b]
    foreach w {.t1 .t2} {
        text $w \-width 20 \-height 4 \-borderwidth 1 \-relief solid
        bind $w <FocusIn> [list fontchooserFocus $w]
        $w insert end "Text Widget $w"
    }
    .t1 configure \-font {Courier 14}
    .t2 configure \-font {Times 16}
    pack .b .t1 .t2; focus .t1
}
proc fontchooserToggle {} {
    \fBtk fontchooser\fR [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR \-visible] ?
            "\fBhide\fR" : "\fBshow\fR"}]
}
proc fontchooserVisibility {w} {
    $w configure \-text [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR \-visible] ?
            "Hide Font Dialog" : "Show Font Dialog"}]
}
proc fontchooserFocus {w} {
    \fBtk fontchooser\fR \fBconfigure\fR \-font [$w cget \-font] \\
            \-command [list fontchooserFontSelection $w]
}
proc fontchooserFontSelection {w font args} {
    $w configure \-font [font actual $font]
}
fontchooserDemo
.CE
.SH "SEE ALSO"
font(n), tk(n)
.SH KEYWORDS
dialog, font, font selection, font chooser, font panel
'\" Local Variables:
'\" mode: nroff
'\" End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































Changes to doc/frame.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH frame n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
frame \- Create and manipulate 'frame' simple container widgets
.SH SYNOPSIS
\fBframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.VS "8.7, TIP262"
An empty background will disable drawing the background image.
.OP \-backgroundimage backgroundImage BackgroundImage
This specifies an image to display on the frame's background within
the border of the frame (i.e., the image will be clipped by the
frame's highlight ring and border, if either are present); subwidgets
of the frame will be drawn on top. The image must have been created
with the \fBimage create\fR command. If specified as the empty string,
no image will be displayed.
.VE "8.7, TIP262"
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fB\-colormap\fR option is not specified, the new window
uses the same colormap as its parent.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-container container Container
The value must be a boolean.  If true, it means that this window will
be used as a container in which some other application will be embedded
(for example, a Tk toplevel can be embedded using the \fB\-use\fR option).
The window will support the appropriate window manager protocols for
things like geometry requests.  The window should not have any
children of its own in this application.
This option may not be changed with the \fBconfigure\fR
widget command.
Note that \fB\-borderwidth\fR, \fB\-padx\fR and \fB\-pady\fR are ignored when
configured as a container since a container has no border.
.OP \-height height Height
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total height of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-height\fR should not be used if a propagating
geometry manager, such as \fBgrid\fR or \fBpack\fR, is used within the
frame since the geometry manager will override the height of the frame.
.OP \-tile tile Tile
.VS "8.7, TIP262"
This specifies how to draw the background image (see
\fB\-backgroundimage\fR) on the frame.
If true (according to \fBTcl_GetBoolean\fR), the image will be tiled
to fill the whole frame, with the origin of the first copy of the
image being the top left of the interior of the frame.
If false (the default), the image will be centered within the frame.
.VE "8.7, TIP262"
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fB\-visual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total width of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-width\fR should not be used if a propagating






|





|









|




<
<
<
<
<
<
<
<
<
<





|








|












|









<
<
<
<
<
<
<
<
<





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27










28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64









65
66
67
68
69
70
71
72
73
74
75
76
77
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH frame n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
frame \- Create and manipulate frame widgets
.SH SYNOPSIS
\fBframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fBbackground\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.










.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fBclass\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fBcolormap\fR option is not specified, the new window
uses the same colormap as its parent.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-container container Container
The value must be a boolean.  If true, it means that this window will
be used as a container in which some other application will be embedded
(for example, a Tk toplevel can be embedded using the \fB\-use\fR option).
The window will support the appropriate window manager protocols for
things like geometry requests.  The window should not have any
children of its own in this application.
This option may not be changed with the \fBconfigure\fR
widget command.
Note that \fB-borderwidth\fR, \fB-padx\fR and \fB-pady\fR are ignored when
configured as a container since a container has no border.
.OP \-height height Height
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total height of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-height\fR should not be used if a propagating
geometry manager, such as \fBgrid\fR or \fBpack\fR, is used within the
frame since the geometry manager will override the height of the frame.









.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fBvisual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total width of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-width\fR should not be used if a propagating
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
or in the option database
to configure aspects of the frame such as its background color
and relief.  The \fBframe\fR command returns the
path name of the new window.
.PP
A frame is a simple widget.  Its primary purpose is to act as a
spacer or container for complex window layouts.  The only features
of a frame are its background and an optional 3-D border to make the
frame appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBframe\fR command creates a new Tcl command whose
name is the same as the path name of the frame's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.SH BINDINGS
.PP
When a new frame is created, it has no default event bindings:
frames are not intended to be interactive.
.SH "SEE ALSO"
labelframe(n), toplevel(n), ttk::frame(n)
.SH KEYWORDS
frame, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|







<

|

<






<





|
<




















<
<
<
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104

105
106
107
108
109
110

111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136



or in the option database
to configure aspects of the frame such as its background color
and relief.  The \fBframe\fR command returns the
path name of the new window.
.PP
A frame is a simple widget.  Its primary purpose is to act as a
spacer or container for complex window layouts.  The only features
of a frame are its background color and an optional 3-D border to make the
frame appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBframe\fR command creates a new Tcl command whose
name is the same as the path name of the frame's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:

.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE

\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.SH BINDINGS
.PP
When a new frame is created, it has no default event bindings:
frames are not intended to be interactive.
.SH "SEE ALSO"
labelframe(n), toplevel(n), ttk::frame(n)
.SH KEYWORDS
frame, widget



Changes to doc/getOpenFile.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH tk_getOpenFile n 4.2 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_getOpenFile, tk_getSaveFile \- pop up a dialog box for the user to select a file to open or save.
.SH SYNOPSIS





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH tk_getOpenFile n 4.2 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_getOpenFile, tk_getSaveFile \- pop up a dialog box for the user to select a file to open or save.
.SH SYNOPSIS
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
as\fR command in the \fBFile\fR menu. If the user enters a file that
already exists, the dialog box prompts the user for confirmation
whether the existing file should be overwritten or not.
.PP
The following \fIoption\-value\fR pairs are possible as command line
arguments to these two commands:
.TP
\fB\-command\fR \fIstring\fR
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.
.TP
\fB\-confirmoverwrite\fR \fIboolean\fR
Configures how the Save dialog reacts when the selected file already
exists, and saving would overwrite it.  A true value requests a
confirmation dialog be presented to the user.  A false value requests
that the overwrite take place without confirmation.  Default value is true.
.TP
\fB\-defaultextension\fR \fIextension\fR
.
Specifies a string that will be appended to the filename if the user
enters a filename without an extension. The default value is the empty
string, which means no extension will be appended to the filename in
any case. This option is ignored on Mac OS X, which
does not require extensions to filenames,
and the UNIX implementation guesses reasonable values for this from
the \fB\-filetypes\fR option when this is not supplied.
.TP
\fB\-filetypes\fR \fIfilePatternList\fR
.
If a \fBFile types\fR listbox exists in the file dialog on the particular
platform, this option gives the \fIfiletype\fRs in this listbox. When
the user choose a filetype in the listbox, only the files of that type
are listed. If this option is unspecified, or if it is set to the
empty list, or if the \fBFile types\fR listbox is not supported by the
particular platform then all files are listed regardless of their
types. See the section \fBSPECIFYING FILE PATTERNS\fR below for a
discussion on the contents of \fIfilePatternList\fR.
.TP
\fB\-initialdir\fR \fIdirectory\fR
.
Specifies that the files in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.TP
\fB\-initialfile\fR \fIfilename\fR
.
Specifies a filename to be displayed in the dialog when it pops up.
.TP
\fB\-message\fR \fIstring\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
.TP
\fB\-multiple\fR \fIboolean\fR
.
Allows the user to choose multiple files from the Open dialog.
.TP
\fB\-parent\fR \fIwindow\fR
.
Makes \fIwindow\fR the logical parent of the file dialog. The file
dialog is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.TP
\fB\-title\fR \fItitleString\fR
.
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title is displayed.
.TP
\fB\-typevariable\fR \fIvariableName\fR
.
The global variable \fIvariableName\fR is used to preselect which filter is
used from \fIfilterList\fR when the dialog box is opened and is
updated when the dialog box is closed, to the last selected
filter. The variable is read once at the beginning to select the
appropriate filter. If the variable does not exist, or its value does
not match any filter typename, or is empty (\fB{}\fR), the dialog box
will revert to the default behavior of selecting the first filter in







<
<
<
<
<
<
<







<









<










<

|
|
<
<
<




<



<




<



<





<

|


<







31
32
33
34
35
36
37







38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63

64
65
66



67
68
69
70

71
72
73

74
75
76
77

78
79
80

81
82
83
84
85

86
87
88
89

90
91
92
93
94
95
96
as\fR command in the \fBFile\fR menu. If the user enters a file that
already exists, the dialog box prompts the user for confirmation
whether the existing file should be overwritten or not.
.PP
The following \fIoption\-value\fR pairs are possible as command line
arguments to these two commands:
.TP







\fB\-confirmoverwrite\fR \fIboolean\fR
Configures how the Save dialog reacts when the selected file already
exists, and saving would overwrite it.  A true value requests a
confirmation dialog be presented to the user.  A false value requests
that the overwrite take place without confirmation.  Default value is true.
.TP
\fB\-defaultextension\fR \fIextension\fR

Specifies a string that will be appended to the filename if the user
enters a filename without an extension. The default value is the empty
string, which means no extension will be appended to the filename in
any case. This option is ignored on Mac OS X, which
does not require extensions to filenames,
and the UNIX implementation guesses reasonable values for this from
the \fB\-filetypes\fR option when this is not supplied.
.TP
\fB\-filetypes\fR \fIfilePatternList\fR

If a \fBFile types\fR listbox exists in the file dialog on the particular
platform, this option gives the \fIfiletype\fRs in this listbox. When
the user choose a filetype in the listbox, only the files of that type
are listed. If this option is unspecified, or if it is set to the
empty list, or if the \fBFile types\fR listbox is not supported by the
particular platform then all files are listed regardless of their
types. See the section \fBSPECIFYING FILE PATTERNS\fR below for a
discussion on the contents of \fIfilePatternList\fR.
.TP
\fB\-initialdir\fR \fIdirectory\fR

Specifies that the files in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified, then
the files in the current working directory are displayed. If the



parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.TP
\fB\-initialfile\fR \fIfilename\fR

Specifies a filename to be displayed in the dialog when it pops up.
.TP
\fB\-message\fR \fIstring\fR

Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
.TP
\fB\-multiple\fR \fIboolean\fR

Allows the user to choose multiple files from the Open dialog.
.TP
\fB\-parent\fR \fIwindow\fR

Makes \fIwindow\fR the logical parent of the file dialog. The file
dialog is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.TP
\fB\-title\fR \fItitleString\fR

Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title is displayed. 
.TP
\fB\-typevariable\fR \fIvariableName\fR

The global variable \fIvariableName\fR is used to preselect which filter is
used from \fIfilterList\fR when the dialog box is opened and is
updated when the dialog box is closed, to the last selected
filter. The variable is read once at the beginning to select the
appropriate filter. If the variable does not exist, or its value does
not match any filter typename, or is empty (\fB{}\fR), the dialog box
will revert to the default behavior of selecting the first filter in
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
to ensure portability, wild card characters are not allowed in the
extensions, except as in the special extension
.QW * .
Extensions without a full stop character (e.g.
.QW ~ )
are allowed but may not work on all platforms.
.SH EXAMPLE
.PP
.CS
set types {
    {{Text Files}       {.txt}        }
    {{TCL Scripts}      {.tcl}        }
    {{C Source Files}   {.c}      TEXT}
    {{GIF Files}        {.gif}        }
    {{GIF Files}        {}        GIFF}
    {{All Files}        *             }
}
set filename [\fBtk_getOpenFile\fR \-filetypes $types]

if {$filename ne ""} {
    # Open the file ...
}
.CE
.SH "SEE ALSO"
tk_chooseDirectory
.SH KEYWORDS
file selection dialog
'\" Local Variables:
'\" mode: nroff
'\" End:







<









|

|







<
<
<
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184



to ensure portability, wild card characters are not allowed in the
extensions, except as in the special extension
.QW * .
Extensions without a full stop character (e.g.
.QW ~ )
are allowed but may not work on all platforms.
.SH EXAMPLE

.CS
set types {
    {{Text Files}       {.txt}        }
    {{TCL Scripts}      {.tcl}        }
    {{C Source Files}   {.c}      TEXT}
    {{GIF Files}        {.gif}        }
    {{GIF Files}        {}        GIFF}
    {{All Files}        *             }
}
set filename [tk_getOpenFile \-filetypes $types]

if {$filename != ""} {
    # Open the file ...
}
.CE
.SH "SEE ALSO"
tk_chooseDirectory
.SH KEYWORDS
file selection dialog



Changes to doc/grab.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH grab n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.sp
\fBgrab \fIoption \fR?\fIarg \fR...?
.BE

.SH DESCRIPTION
.PP
This command implements simple pointer and keyboard grabs for Tk.
Tk's grabs are different than the grabs
described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.






|









|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH grab n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.sp
\fBgrab \fIoption \fR?\fIarg arg \fR...?
.BE

.SH DESCRIPTION
.PP
This command implements simple pointer and keyboard grabs for Tk.
Tk's grabs are different than the grabs
described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
redirected to the focus window.
During a global grab Tk grabs the keyboard so that all keyboard events
are always sent to the grabbing application.
The \fBfocus\fR command is still used to determine which window in the
application receives the keyboard events.
The keyboard grab is released when the grab is released.
.PP
On macOS a global grab affects all windows created by one Tk process.
No window in that process other than the grab window can even be
focused, hence no other window receives key or mouse events.  A local
grab on macOS affects all windows created by one Tcl interpreter.  It
is possible to focus any window belonging to the Tk process during a
local grab but the grab window is the only window created by its
interpreter which receives key or mouse events.  Windows belonging to the
same process but created by different interpreters continue to receive
key and mouse events normally.
.PP
Grabs apply to particular displays.  If an application has windows
on multiple displays then it can establish a separate grab on each
display.
The grab on a particular display affects only the windows on
that display.
It is possible for different applications on a single display to have
simultaneous local grabs, but only one application can have a global







<
<
<
<
<
<
<
<
<
<







58
59
60
61
62
63
64










65
66
67
68
69
70
71
redirected to the focus window.
During a global grab Tk grabs the keyboard so that all keyboard events
are always sent to the grabbing application.
The \fBfocus\fR command is still used to determine which window in the
application receives the keyboard events.
The keyboard grab is released when the grab is released.
.PP










Grabs apply to particular displays.  If an application has windows
on multiple displays then it can establish a separate grab on each
display.
The grab on a particular display affects only the windows on
that display.
It is possible for different applications on a single display to have
simultaneous local grabs, but only one application can have a global
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
does nothing.  Returns an empty string.
.TP
\fBgrab status \fIwindow\fR
Returns \fBnone\fR if no grab is currently set on \fIwindow\fR,
\fBlocal\fR if a local grab is set on \fIwindow\fR, and
\fBglobal\fR if a global grab is set.
.SH WARNING
.PP
It is very easy to use global grabs to render a display completely
unusable (e.g. by setting a grab on a widget which does not respond to
events and not providing any mechanism for releasing the grab).  Take
\fIextreme\fR care when using them!
.SH BUGS
.PP
It took an incredibly complex and gross implementation to produce
the simple grab effect described above.
Given the current implementation, it is not safe for applications
to use the Xlib grab facilities at all except through the Tk grab
procedures.
If applications try to manipulate X's grab mechanisms directly,
things will probably break.
.PP
If a single process is managing several different Tk applications,
only one of those applications can have a local grab for a given
display at any given time.  If the applications are in different
processes, this restriction does not exist.
.SH EXAMPLE
.PP
Set a grab so that only one button may be clicked out of a group.  The
other buttons are unresponsive to the mouse until the middle button is
clicked.
.CS
pack [button .b1 \-text "Click me! #1" \-command {destroy .b1}]
pack [button .b2 \-text "Click me! #2" \-command {destroy .b2}]
pack [button .b3 \-text "Click me! #3" \-command {destroy .b3}]
\fBgrab\fR .b2
.CE
.SH "SEE ALSO"
busy(n)
.SH KEYWORDS
grab, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:







<



















<









|
<


<
<
<
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135



does nothing.  Returns an empty string.
.TP
\fBgrab status \fIwindow\fR
Returns \fBnone\fR if no grab is currently set on \fIwindow\fR,
\fBlocal\fR if a local grab is set on \fIwindow\fR, and
\fBglobal\fR if a global grab is set.
.SH WARNING

It is very easy to use global grabs to render a display completely
unusable (e.g. by setting a grab on a widget which does not respond to
events and not providing any mechanism for releasing the grab).  Take
\fIextreme\fR care when using them!
.SH BUGS
.PP
It took an incredibly complex and gross implementation to produce
the simple grab effect described above.
Given the current implementation, it is not safe for applications
to use the Xlib grab facilities at all except through the Tk grab
procedures.
If applications try to manipulate X's grab mechanisms directly,
things will probably break.
.PP
If a single process is managing several different Tk applications,
only one of those applications can have a local grab for a given
display at any given time.  If the applications are in different
processes, this restriction does not exist.
.SH EXAMPLE

Set a grab so that only one button may be clicked out of a group.  The
other buttons are unresponsive to the mouse until the middle button is
clicked.
.CS
pack [button .b1 \-text "Click me! #1" \-command {destroy .b1}]
pack [button .b2 \-text "Click me! #2" \-command {destroy .b2}]
pack [button .b3 \-text "Click me! #3" \-command {destroy .b3}]
\fBgrab\fR .b2
.CE


.SH KEYWORDS
grab, keyboard events, pointer events, window



Changes to doc/grid.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
'\"
'\" 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.
'\"
.TH grid n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grid \- Geometry manager that arranges widgets in a grid
.SH SYNOPSIS
\fBgrid \fIoption arg \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBgrid\fR command is used to communicate with the grid
geometry manager that arranges widgets in rows and columns inside
of another window, called the geometry container (or container window).
The \fBgrid\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBgrid \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
If the first argument to \fBgrid\fR is suitable as the first window
argument to \fBgrid configure\fR, either a window name (any value
starting with \fB.\fR) or one of the characters \fBx\fR or \fB^\fR
(see the \fBRELATIVE PLACEMENT\fR section below), then the command is
processed in the same way as \fBgrid configure\fR.

.TP
\fBgrid anchor \fIwindow\fR ?\fIanchor\fR?
.
The anchor value controls how to place the grid within the container window
when no row/column has any weight.  See \fBTHE GRID ALGORITHM\fR below
for further details.  The default \fIanchor\fR is \fInw\fR.

.TP
\fBgrid bbox \fIwindow\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?
.
With no arguments,
the bounding box (in pixels) of the grid is returned.
The return value consists of 4 integers.  The first two are the pixel
offset from the container window (x then y) of the top-left corner of the
grid, and the second two integers are the width and height of the grid,
also in pixels.  If a single \fIcolumn\fR and \fIrow\fR is specified on
the command line, then the bounding box for that cell is returned, where the
top left cell is numbered from zero.  If both \fIcolumn\fR and \fIrow\fR
arguments are specified, then the bounding box spanning the rows and columns
indicated is returned.
.TP
\fBgrid columnconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the column properties of the \fIindex\fR column of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of column indices to which the configuration options will operate on.

Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all columns currently occupied be content windows. For
a window name, that window must be a content of this container and the options
apply to all columns currently occupied be the content.

The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this column.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
columns.
A weight of zero (0) indicates the column will not deviate from its requested
size.  A column whose weight is two will grow at twice the rate as a column
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the column in a \fIuniform group\fR with other columns that have the
same value for \fB\-uniform\fR.  The space for columns belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "\-option value"
pairs.
.TP
\fBgrid configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
The characters \fB\-\fR,  \fBx\fR and \fB^\fR,
can be specified instead of a window name to alter the default
location of a \fIwindow\fR, as described in the \fBRELATIVE PLACEMENT\fR
section, below.
The following options are supported:
.RS
.TP
\fB\-column \fIn\fR
.
Insert the window so that it occupies the \fIn\fRth column in the grid.
Column numbers start with 0.  If this option is not supplied, then the
window is arranged just to the right of previous window specified on this
call to \fBgrid\fR, or column
.QW 0
if it is the first window.  For each
\fBx\fR that immediately precedes the \fIwindow\fR, the column position
is incremented by one.  Thus the \fBx\fR represents a blank column
for this row in the grid.
.TP
\fB\-columnspan \fIn\fR
.
Insert the window so that it occupies \fIn\fR columns in the grid.
The default is one column, unless the window name is followed by a
\fB\-\fR, in which case the columnspan is incremented once for each immediately
following \fB\-\fR.
.TP
\fB\-in \fIcontainer\fR
.
Insert the window(s) in the container
window given by \fIcontainer\fR.  The default is the first window's
parent window.
.TP
\fB\-ipadx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal internal padding to
leave on each side of the content.  This is space is added
inside the content border.
The \fIamount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR
.
The \fIamount\fR specifies how much vertical internal padding to
leave on the top and bottom of the content.
This space is added inside the content border.
The \fIamount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal external padding to
leave on each side of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for left and right separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.
.TP
\fB\-pady \fIamount\fR
.
The \fIamount\fR specifies how much vertical external padding to
leave on the top and bottom of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.
.TP
\fB\-row \fIn\fR
.
Insert the content so that it occupies the \fIn\fRth row in the grid.
Row numbers start with 0.  If this option is not supplied, then the
content is arranged on the same row as the previous content specified on this
call to \fBgrid\fR, or the next row after the highest occupied row
if this is the first content.
.TP
\fB\-rowspan \fIn\fR
.
Insert the content so that it occupies \fIn\fR rows in the grid.
The default is one row.  If the next \fBgrid\fR command contains
\fB^\fR characters instead of \fIcontent\fR that line up with the columns
of this \fIcontent\fR, then the \fBrowspan\fR of this \fIcontent\fR is
extended by one.
.TP
\fB\-sticky \fIstyle\fR
.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
The string can optionally contain spaces or
commas, but they are ignored.  Each letter refers to a side (north, south,
east, or west) that the content will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR) are
specified, the content will be stretched to fill the entire
height (or width) of its cavity.  The \fB\-sticky\fR option subsumes the
combination of \fB\-anchor\fR and \fB\-fill\fR that is used by \fBpack\fR.
The default is
.QW "" ,
which causes the content to be centered in its cavity, at its requested size.
.LP
If any of the content is already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBgrid forget \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
window is managed once more by the grid geometry manager, the initial
default settings are used.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.TP
\fBgrid info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the content given by \fIwindow\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the windows's container window.
.TP
\fBgrid location \fIwindow x y\fR
.
Given  \fIx\fR and \fIy\fR values in screen units relative to the container window,
the column and row number at that \fIx\fR and \fIy\fR location is returned.
For locations that are above or to the left of the grid, \fB\-1\fR is
returned.
.TP
\fBgrid propagate \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIwindow\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIwindow\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIwindow\fR.
Propagation is enabled by default.
.TP
\fBgrid rowconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the row properties of the \fIindex\fR row of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of row indices to which the configuration options will operate on.

Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied by content windows. For
a window name, that window must be a content window of this container and the options
apply to all rows currently occupied by the container window.

The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
rows.
A weight of zero (0) indicates the row will not deviate from its requested
size.  A row whose weight is two will grow at twice the rate as a row
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the row in a \fIuniform group\fR with other rows that have the
same value for \fB\-uniform\fR.  The space for rows belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that row when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "-option value"
pairs.
.TP
\fBgrid remove \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the content window is managed once more by the grid

geometry manager, the previous values are retained.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.TP
\fBgrid size \fIcontainer\fR
.
Returns the size of the grid (in columns then rows) for \fIcontainer\fR.
The size is determined either by the \fIcontent\fR occupying the largest
row or column, or the largest column or row with a \fB\-minsize\fR,
\fB\-weight\fR, or \fB\-pad\fR that is non-zero.
.TP
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
If no options are supplied, a list of all of the content in \fIwindow\fR
is returned, most recently managed first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the content in the row (or column) specified by \fIvalue\fR
to be returned.
.TP
\fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for . \fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column
information for each content.  This permits content to be rearranged,
added, or removed without the need to explicitly specify row and
column information.
When no column or row information is specified for a \fIcontent\fR,
default values are chosen for
\fB\-column\fR, \fB\-row\fR, \fB\-columnspan\fR and \fB\-rowspan\fR
at the time the \fIcontent\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIcontent\fR
relative to other \fIcontent\fRs in the same grid command, and the presence
of the characters \fB\-\fR, \fBx\fR, and \fB^\fR in \fBgrid\fR
command where \fIcontent\fR names are normally expected.
.RS
.TP
\fB\-\fR
.
This increases the \fB\-columnspan\fR of the \fIcontent\fR to the left.  Several
\fB\-\fR's in a row will successively increase the number of columns spanned. A \fB\-\fR
may not follow a \fB^\fR or a \fBx\fR, nor may it be the first \fIcontent\fR
argument to \fBgrid configure\fR.
.TP
\fBx\fR
.
This leaves an empty column between the \fIcontent\fR on the left and
the \fIcontent\fR on the right.
.TP
\fB^\fR
.
This extends the \fB\-rowspan\fR of the \fIcontent\fR above the \fB^\fR's
in the grid.  The number of \fB^\fR's in a row must match the number of
columns spanned by the \fIcontent\fR above it.
.RE
.SH "THE GRID ALGORITHM"
.PP
The grid geometry manager lays out its content in three steps.
In the first step, the minimum size needed to fit all of the content
is computed, then (if propagation is turned on), a request is made
of the container window to become that size.
In the second step, the requested size is compared against the actual size
of the container.  If the sizes are different, then spaces is added to or taken
away from the layout as needed.
For the final step, each content is positioned in its row(s) and column(s)
based on the setting of its \fIsticky\fR flag.
.PP
To compute the minimum size of a layout, the grid geometry manager
first looks at all content whose \fB\-columnspan\fR and \fB\-rowspan\fR values are one,
and computes the nominal size of each row or column to be either the
\fIminsize\fR for that row or column, or the sum of the \fIpad\fRding
plus the size of the largest content, whichever is greater.  After that
the rows or columns in each uniform group adapt to each other.  Then
the content whose row-spans or column-spans are greater than one are
examined.  If a group of rows or columns need to be increased in size
in order to accommodate these content, then extra space is added to each
row or column in the group according to its \fIweight\fR.  For each
group whose weights are all zero, the additional space is apportioned
equally.
.PP
When multiple rows or columns belong to a uniform group, the space
allocated to them is always in proportion to their weights. (A weight
of zero is considered to be 1.)  In other words, a row or column
configured with \fB\-weight 1 \-uniform a\fR will have exactly the same
size as any other row or column configured with \fB\-weight 1 \-uniform
a\fR.  A row or column configured with \fB\-weight 2 \-uniform b\fR will
be exactly twice as large as one that is configured with \fB\-weight 1
\-uniform b\fR.
.PP
More technically, each row or column in the group will have a size
equal to \fIk*weight\fR for some constant \fIk\fR.  The constant
\fIk\fR is chosen so that no row or column becomes smaller than its
minimum size.  For example, if all rows or columns in a group have the
same weight, then each row or column will have the same size as the
largest row or column in the group.
.PP

For containers whose size is larger than the requested layout, the additional
space is apportioned according to the row and column weights.  If all of
the weights are zero, the layout is placed within its container according to
the \fIanchor\fR value.
For containers whose size is smaller than the requested layout, space is taken
away from columns and rows according to their weights.  However, once a
column or row shrinks to its minsize, its weight is taken to be zero.
If more space needs to be removed from a layout than would be permitted, as
when all the rows or columns are at their minimum sizes, the layout is
placed and clipped according to the \fIanchor\fR value.

.SH "GEOMETRY PROPAGATION"
.PP
The grid geometry manager normally computes how large a container must be to
just exactly meet the needs of its content, and it sets the
requested width and height of the container to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBgrid propagate\fR command may be used to
turn off propagation for one or more containers.
If propagation is disabled then grid will not set
the requested width and height of the container window.
This may be useful if, for example, you wish for a container
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON CONTAINER WINDOWS"
.PP
The container for each content must either be the content's parent
(the default) or a descendant of the content's parent.
This restriction is necessary to guarantee that the
content can be placed over any part of its container that is
visible without danger of the content being clipped by its parent.
In addition, all content in one call to \fBgrid\fR must have the same container.
.SH "STACKING ORDER"
.PP
If the container for a content is not its parent then you must make sure
that the content is higher in the stacking order than the container.
Otherwise the container will obscure the content and it will appear as
if the content has not been managed correctly.
The easiest way to make sure the content is higher than the container is
to create the container window first:  the most recently created window
will be highest in the stacking order.
.SH CREDITS
.PP
The \fBgrid\fR command is based on ideas taken from the \fIGridBag\fR
geometry manager written by Doug. Stein, and the \fBblt_table\fR geometry
manager, written by George Howlett.
.SH EXAMPLES
.PP
A toplevel window containing a text widget and two scrollbars:
.PP
.CS
# Make the widgets
toplevel .t
text .t.txt \-wrap none \-xscroll {.t.h set} \-yscroll {.t.v set}
scrollbar .t.v \-orient vertical   \-command {.t.txt yview}
scrollbar .t.h \-orient horizontal \-command {.t.txt xview}

# Lay them out
\fBgrid\fR .t.txt .t.v \-sticky nsew
\fBgrid\fR .t.h        \-sticky nsew

# Tell the text widget to take all the extra room
\fBgrid rowconfigure\fR    .t .t.txt \-weight 1
\fBgrid columnconfigure\fR .t .t.txt \-weight 1
.CE
.PP
Three widgets of equal width, despite their different
.QW natural
widths:
.PP
.CS
button .b \-text "Foo"
entry .e \-textvariable foo ; set foo "Hello World!"
label .l \-text "This is a fairly long piece of text"

\fBgrid\fR .b .e .l \-sticky ew
\fBgrid columnconfigure\fR . "all" \-uniform allTheSame
.CE
.SH "SEE ALSO"
pack(n), place(n)
.SH KEYWORDS
geometry manager, location, grid, cell, propagation, size, pack
'\" Local Variables:
'\" mode: nroff
'\" End:





|













|



|
<
|

|


>

|
<
|


>

|
<
|


|

|





|
<
|
|


|

>

|
|
|
>




















|




|
<
|

|
|

|





<
|

|


|
|




<
|




|
<
|
|



<

|
|




<

|
|



<

|



|


<

|



|


<
|

|
<
|


<
|

|
|



<
|
|


|

|


|
|



|

|




|
<
|
|
|

|

<
<
<
<
<
<
<
<

|
<

|


|
|

|
<
|




|
<

|


|



|


|
<
|
|


|

>

|
|
|
>




















|




|
<
|
|
|

|
>
|
<
<
<
<
<
<
<
<

|
<
|
|
|
|

|
<
|
|

|

<
<
<
<



|
|


|

|
|
|
|

|



<
|
|
|



<
|
|


<
|

|



|
|

|

|

|



|


|

|

|









|

|








>
|

|

|
|




>


|
|
|




|

|
|

|

|
|

|
|
|


|
|
|
|
|
|







<

<



















<


|









<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116

117
118
119
120
121

122
123
124
125
126
127
128

129
130
131
132
133
134

135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150

151
152
153

154
155
156

157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

186
187
188
189
190
191








192
193

194
195
196
197
198
199
200
201

202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264








265
266

267
268
269
270
271
272

273
274
275
276
277




278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301

302
303
304
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431



'\"
'\" 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.
'\" 
.TH grid n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grid \- Geometry manager that arranges widgets in a grid
.SH SYNOPSIS
\fBgrid \fIoption arg \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBgrid\fR command is used to communicate with the grid
geometry manager that arranges widgets in rows and columns inside
of another window, called the geometry master (or master window).
The \fBgrid\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBgrid \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?

If the first argument to \fBgrid\fR is suitable as the first slave
argument to \fBgrid configure\fR, either a window name (any value
starting with \fB.\fR) or one of the characters \fBx\fR or \fB^\fR 
(see the \fBRELATIVE PLACEMENT\fR section below), then the command is
processed in the same way as \fBgrid configure\fR.
.VS 8.5
.TP
\fBgrid anchor \fImaster\fR ?\fIanchor\fR?

The anchor value controls how to place the grid within the master
when no row/column has any weight.  See \fBTHE GRID ALGORITHM\fR below
for further details.  The default \fIanchor\fR is \fInw\fR.
.VE 8.5
.TP
\fBgrid bbox \fImaster\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?

With no arguments, 
the bounding box (in pixels) of the grid is returned.
The return value consists of 4 integers.  The first two are the pixel
offset from the master window (x then y) of the top-left corner of the
grid, and the second two integers are the width and height of the grid,
also in pixels.  If a single \fIcolumn\fR and \fIrow\fR is specified on 
the command line, then the bounding box for that cell is returned, where the
top left cell is numbered from zero.  If both \fIcolumn\fR and \fIrow\fR
arguments are specified, then the bounding box spanning the rows and columns
indicated is returned.
.TP
\fBgrid columnconfigure \fImaster index \fR?\fI\-option value...\fR?

Query or set the column properties of the \fIindex\fR column of the 
geometry master, \fImaster\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as 
a list of column indices to which the configuration options will operate on.
.VS 8.5
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all columns currently occupied be slave windows. For
a window name, that window must be a slave of this master and the options
apply to all columns currently occupied be the slave.
.VE 8.5
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this column.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
columns.
A weight of zero (0) indicates the column will not deviate from its requested
size.  A column whose weight is two will grow at twice the rate as a column
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the column in a \fIuniform group\fR with other columns that have the
same value for \fB\-uniform\fR.  The space for columns belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the master window and index is specified, all the current settings
are returned in a list of
.QW "\-option value"
pairs.
.TP
\fBgrid configure \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?

The arguments consist of the names of one or more slave windows
followed by pairs of arguments that specify how
to manage the slaves.
The characters \fB\-\fR,  \fBx\fR and \fB^\fR, 
can be specified instead of a window name to alter the default
location of a \fIslave\fR, as described in the \fBRELATIVE PLACEMENT\fR
section, below.
The following options are supported:
.RS
.TP
\fB\-column \fIn\fR

Insert the slave so that it occupies the \fIn\fRth column in the grid.
Column numbers start with 0.  If this option is not supplied, then the
slave is arranged just to the right of previous slave specified on this
call to \fBgrid\fR, or column
.QW 0
if it is the first slave.  For each
\fBx\fR that immediately precedes the \fIslave\fR, the column position
is incremented by one.  Thus the \fBx\fR represents a blank column
for this row in the grid.
.TP
\fB\-columnspan \fIn\fR

Insert the slave so that it occupies \fIn\fR columns in the grid.
The default is one column, unless the window name is followed by a
\fB\-\fR, in which case the columnspan is incremented once for each immediately
following \fB\-\fR.
.TP
\fB\-in \fIother\fR

Insert the slave(s) in the master
window given by \fIother\fR.  The default is the first slave's
parent window.
.TP
\fB\-ipadx \fIamount\fR

The \fIamount\fR specifies how much horizontal internal padding to
leave on each side of the slave(s).  This is space is added
inside the slave(s) border.
The \fIamount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR

The \fIamount\fR specifies how much vertical internal padding to
leave on the top and bottom of the slave(s).
This space is added inside the slave(s) border.
The \fIamount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR

The \fIamount\fR specifies how much horizontal external padding to
leave on each side of the slave(s), in screen units.
\fIAmount\fR may be a list
of two values to specify padding for left and right separately.
The \fIamount\fR defaults to 0.
This space is added outside the slave(s) border.
.TP
\fB\-pady \fIamount\fR

The \fIamount\fR specifies how much vertical external padding to
leave on the top and bottom of the slave(s), in screen units.
\fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
The \fIamount\fR defaults to 0.
This space is added outside the slave(s) border.
.TP
\fB\-row \fIn\fR

Insert the slave so that it occupies the \fIn\fRth row in the grid.
Row numbers start with 0.  If this option is not supplied, then the
slave is arranged on the same row as the previous slave specified on this

call to \fBgrid\fR, or the first unoccupied row if this is the first slave.
.TP
\fB\-rowspan \fIn\fR

Insert the slave so that it occupies \fIn\fR rows in the grid.
The default is one row.  If the next \fBgrid\fR command contains
\fB^\fR characters instead of \fIslaves\fR that line up with the columns
of this \fIslave\fR, then the \fBrowspan\fR of this \fIslave\fR is
extended by one.
.TP
\fB\-sticky \fIstyle\fR

If a slave's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the slave within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
The string can optionally contains spaces or
commas, but they are ignored.  Each letter refers to a side (north, south,
east, or west) that the slave will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR) are
specified, the slave will be stretched to fill the entire
height (or width) of its cavity.  The \fBsticky\fR option subsumes the
combination of \fB\-anchor\fR and \fB\-fill\fR that is used by \fBpack\fR.
The default is
.QW "" ,
which causes the slave to be centered in its cavity, at its requested size.
.LP
If any of the slaves are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBgrid forget \fIslave \fR?\fIslave ...\fR?

Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
slave is managed once more by the grid geometry manager, the initial
default settings are used.








.TP
\fBgrid info \fIslave\fR

Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
.QW "\fB\-in \fImaster\fR"
where \fImaster\fR is the slave's master.
.TP
\fBgrid location \fImaster x y\fR

Given  \fIx\fR and \fIy\fR values in screen units relative to the master window, 
the column and row number at that \fIx\fR and \fIy\fR location is returned.
For locations that are above or to the left of the grid, \fB\-1\fR is
returned.
.TP
\fBgrid propagate \fImaster\fR ?\fIboolean\fR?

If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fImaster\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fImaster\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fImaster\fR.
Propagation is enabled by default.
.TP
\fBgrid rowconfigure \fImaster index \fR?\fI\-option value...\fR?

Query or set the row properties of the \fIindex\fR row of the 
geometry master, \fImaster\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as 
a list of row indices to which the configuration options will operate on.
.VS 8.5
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied be slave windows. For
a window name, that window must be a slave of this master and the options
apply to all rows currently occupied be the slave.
.VE 8.5
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
rows.
A weight of zero (0) indicates the row will not deviate from its requested
size.  A row whose weight is two will grow at twice the rate as a row
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the row in a \fIuniform group\fR with other rows that have the
same value for \fB\-uniform\fR.  The space for rows belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that row when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the master window and index is specified, all the current settings
are returned in a list of
.QW "-option value"
pairs.
.TP
\fBgrid remove \fIslave \fR?\fIslave ...\fR?

Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the
slave is managed once more by the grid geometry manager, the previous
values are retained.








.TP
\fBgrid size \fImaster\fR

Returns the size of the grid (in columns then rows) for \fImaster\fR.
The size is determined either by the \fIslave\fR occupying the largest
row or column, or the largest column or row with a \fBminsize\fR, 
\fBweight\fR, or \fBpad\fR that is non-zero.
.TP
\fBgrid slaves \fImaster\fR ?\fI\-option value\fR?

If no options are supplied, a list of all of the slaves in \fImaster\fR
are returned, most recently manages first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the slaves in the row (or column) specified by \fIvalue\fR
to be returned.




.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column 
information for each slave.  This permits slaves to be rearranged, 
added, or removed without the need to explicitly specify row and
column information.
When no column or row information is specified for a \fIslave\fR, 
default values are chosen for
\fBcolumn\fR, \fBrow\fR, \fBcolumnspan\fR and \fBrowspan\fR
at the time the \fIslave\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIslave\fR
relative to other \fIslave\fRs in the same grid command, and the presence
of the characters \fB\-\fR, \fBx\fR, and \fB^\fR in \fBgrid\fR
command where \fIslave\fR names are normally expected.
.RS
.TP
\fB\-\fR

This increases the columnspan of the \fIslave\fR to the left.  Several
\fB\-\fR's in a row will successively increase the columnspan. A \fB\-\fR
may not follow a \fB^\fR or a \fBx\fR, nor may it be the first \fIslave\fR
argument to \fBgrid configure\fR.
.TP
\fBx\fR

This leaves an empty column between the \fIslave\fR on the left and
the \fIslave\fR on the right.
.TP
\fB^\fR

This extends the \fBrowspan\fR of the \fIslave\fR above the \fB^\fR's
in the grid.  The number of \fB^\fR's in a row must match the number of
columns spanned by the \fIslave\fR above it.
.RE
.SH "THE GRID ALGORITHM"
.PP
The grid geometry manager lays out its slaves in three steps.
In the first step, the minimum size needed to fit all of the slaves
is computed, then (if propagation is turned on), a request is made
of the master window to become that size.
In the second step, the requested size is compared against the actual size
of the master.  If the sizes are different, then spaces is added to or taken
away from the layout as needed.
For the final step, each slave is positioned in its row(s) and column(s)
based on the setting of its \fIsticky\fR flag.
.PP
To compute the minimum size of a layout, the grid geometry manager
first looks at all slaves whose columnspan and rowspan values are one,
and computes the nominal size of each row or column to be either the
\fIminsize\fR for that row or column, or the sum of the \fIpad\fRding
plus the size of the largest slave, whichever is greater.  After that
the rows or columns in each uniform group adapt to each other.  Then
the slaves whose rowspans or columnspans are greater than one are
examined.  If a group of rows or columns need to be increased in size
in order to accommodate these slaves, then extra space is added to each
row or column in the group according to its \fIweight\fR.  For each
group whose weights are all zero, the additional space is apportioned
equally.
.PP
When multiple rows or columns belong to a uniform group, the space
allocated to them is always in proportion to their weights. (A weight
of zero is considered to be 1.)  In other words, a row or column
configured with \fB\-weight 1 \-uniform a\fR will have exactly the same
size as any other row or column configured with \fB\-weight 1 \-uniform
a\fR.  A row or column configured with \fB\-weight 2 \-uniform b\fR will 
be exactly twice as large as one that is configured with \fB\-weight 1
\-uniform b\fR.  
.PP
More technically, each row or column in the group will have a size
equal to \fIk*weight\fR for some constant \fIk\fR.  The constant
\fIk\fR is chosen so that no row or column becomes smaller than its
minimum size.  For example, if all rows or columns in a group have the
same weight, then each row or column will have the same size as the
largest row or column in the group.
.PP
.VS 8.5
For masters whose size is larger than the requested layout, the additional
space is apportioned according to the row and column weights.  If all of
the weights are zero, the layout is placed within its master according to
the \fIanchor\fR value.
For masters whose size is smaller than the requested layout, space is taken
away from columns and rows according to their weights.  However, once a 
column or row shrinks to its minsize, its weight is taken to be zero.
If more space needs to be removed from a layout than would be permitted, as
when all the rows or columns are at their minimum sizes, the layout is
placed and clipped according to the \fIanchor\fR value.
.VE 8.5
.SH "GEOMETRY PROPAGATION"
.PP
The grid geometry manager normally computes how large a master must be to
just exactly meet the needs of its slaves, and it sets the
requested width and height of the master to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBgrid propagate\fR command may be used to
turn off propagation for one or more masters.
If propagation is disabled then grid will not set
the requested width and height of the master window.
This may be useful if, for example, you wish for a master
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON MASTER WINDOWS"
.PP
The master for each slave must either be the slave's parent
(the default) or a descendant of the slave's parent.
This restriction is necessary to guarantee that the
slave can be placed over any part of its master that is
visible without danger of the slave being clipped by its parent.
In addition, all slaves in one call to \fBgrid\fR must have the same master.
.SH "STACKING ORDER"
.PP
If the master for a slave is not its parent then you must make sure
that the slave is higher in the stacking order than the master.
Otherwise the master will obscure the slave and it will appear as
if the slave has not been managed correctly.
The easiest way to make sure the slave is higher than the master is
to create the master window first:  the most recently created window
will be highest in the stacking order.
.SH CREDITS
.PP
The \fBgrid\fR command is based on ideas taken from the \fIGridBag\fR
geometry manager written by Doug. Stein, and the \fBblt_table\fR geometry
manager, written by George Howlett.
.SH EXAMPLES

A toplevel window containing a text widget and two scrollbars:

.CS
# Make the widgets
toplevel .t
text .t.txt \-wrap none \-xscroll {.t.h set} \-yscroll {.t.v set}
scrollbar .t.v \-orient vertical   \-command {.t.txt yview}
scrollbar .t.h \-orient horizontal \-command {.t.txt xview}

# Lay them out
\fBgrid\fR .t.txt .t.v \-sticky nsew
\fBgrid\fR .t.h        \-sticky nsew

# Tell the text widget to take all the extra room
\fBgrid rowconfigure\fR    .t .t.txt \-weight 1
\fBgrid columnconfigure\fR .t .t.txt \-weight 1
.CE
.PP
Three widgets of equal width, despite their different
.QW natural
widths:

.CS
button .b \-text "Foo"
entry .e \-variable foo
label .l \-text "This is a fairly long piece of text"

\fBgrid\fR .b .e .l \-sticky ew
\fBgrid columnconfigure\fR . "all" \-uniform allTheSame
.CE
.SH "SEE ALSO"
pack(n), place(n)
.SH KEYWORDS
geometry manager, location, grid, cell, propagation, size, pack



Changes to doc/image.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH image n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
image \- Create and manipulate images
.SH SYNOPSIS
\fBimage\fR \fIoption \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBimage\fR command is used to create, delete, and query images.
It can take several different forms, depending on the
\fIoption\fR argument.  The legal forms are:
.TP
\fBimage create \fItype \fR?\fIname\fR? ?\fIoption value ...\fR?






|







|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH image n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
image \- Create and manipulate images
.SH SYNOPSIS
\fBimage\fR \fIoption \fR?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBimage\fR command is used to create, delete, and query images.
It can take several different forms, depending on the
\fIoption\fR argument.  The legal forms are:
.TP
\fBimage create \fItype \fR?\fIname\fR? ?\fIoption value ...\fR?
89
90
91
92
93
94
95

96
97

98
99
100
101
102
color, or nothing.
See the \fBbitmap\fR manual entry for more information.
.TP
\fBphoto\fR
Displays a variety of full-color images, using dithering to
approximate colors on displays with limited color capabilities.
See the \fBphoto\fR manual entry for more information.

.SH "SEE ALSO"
bitmap(n), options(n), photo(n)

.SH KEYWORDS
height, image, types of images, width
'\" Local Variables:
'\" mode: nroff
'\" End:







>


>


<
<
<
90
91
92
93
94
95
96
97
98
99
100
101
102



color, or nothing.
See the \fBbitmap\fR manual entry for more information.
.TP
\fBphoto\fR
Displays a variety of full-color images, using dithering to
approximate colors on displays with limited color capabilities.
See the \fBphoto\fR manual entry for more information.

.SH "SEE ALSO"
bitmap(n), options(n), photo(n)

.SH KEYWORDS
height, image, types of images, width



Changes to doc/keysyms.n.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482


483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942


943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413


1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881


1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246

2247
2248

2249
2250
2251
2252
2253
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH keysyms n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
keysyms \- keysyms recognized by Tk
.BE

.SH DESCRIPTION
.PP
Tk recognizes many keysyms when specifying key bindings (e.g.,
.QW "\fBbind\fR \fB. <Key-\fR\fIkeysym\fR\fB>\fR" ).
The following list enumerates the
keysyms that will be recognized by Tk.  Note that not all keysyms will
be valid on all platforms, and some keysyms are also available on
platforms that have a different native name for that key.
For example, on Unix systems, the presence
of a particular keysym is dependent on the configuration of the
keyboard modifier map.  This list shows keysyms along with their
decimal and hexadecimal values.
.PP
.CS
space                               32     0x20
exclam                              33     0x21
quotedbl                            34     0x22
numbersign                          35     0x23
dollar                              36     0x24
percent                             37     0x25
ampersand                           38     0x26
apostrophe                          39     0x27
parenleft                           40     0x28
parenright                          41     0x29
asterisk                            42     0x2A
plus                                43     0x2B
comma                               44     0x2C
minus                               45     0x2D
period                              46     0x2E
slash                               47     0x2F
0                                   48     0x30
1                                   49     0x31
2                                   50     0x32
3                                   51     0x33
4                                   52     0x34
5                                   53     0x35
6                                   54     0x36
7                                   55     0x37
8                                   56     0x38
9                                   57     0x39
colon                               58     0x3A
semicolon                           59     0x3B
less                                60     0x3C
equal                               61     0x3D
greater                             62     0x3E
question                            63     0x3F
at                                  64     0x40
A                                   65     0x41
B                                   66     0x42
C                                   67     0x43
D                                   68     0x44
E                                   69     0x45
F                                   70     0x46
G                                   71     0x47
H                                   72     0x48
I                                   73     0x49
J                                   74     0x4A
K                                   75     0x4B
L                                   76     0x4C
M                                   77     0x4D
N                                   78     0x4E
O                                   79     0x4F
P                                   80     0x50
Q                                   81     0x51
R                                   82     0x52
S                                   83     0x53
T                                   84     0x54
U                                   85     0x55
V                                   86     0x56
W                                   87     0x57
X                                   88     0x58
Y                                   89     0x59
Z                                   90     0x5A
bracketleft                         91     0x5B
backslash                           92     0x5C
bracketright                        93     0x5D
asciicircum                         94     0x5E
underscore                          95     0x5F
grave                               96     0x60
a                                   97     0x61
b                                   98     0x62
c                                   99     0x63
d                                  100     0x64
e                                  101     0x65
f                                  102     0x66
g                                  103     0x67
h                                  104     0x68
i                                  105     0x69
j                                  106     0x6A
k                                  107     0x6B
l                                  108     0x6C
m                                  109     0x6D
n                                  110     0x6E
o                                  111     0x6F
p                                  112     0x70
q                                  113     0x71
r                                  114     0x72
s                                  115     0x73
t                                  116     0x74
u                                  117     0x75
v                                  118     0x76
w                                  119     0x77
x                                  120     0x78
y                                  121     0x79
z                                  122     0x7A
braceleft                          123     0x7B
bar                                124     0x7C
braceright                         125     0x7D
asciitilde                         126     0x7E
nobreakspace                       160     0xA0
exclamdown                         161     0xA1
cent                               162     0xA2
sterling                           163     0xA3
currency                           164     0xA4
yen                                165     0xA5
brokenbar                          166     0xA6
section                            167     0xA7
diaeresis                          168     0xA8
copyright                          169     0xA9
ordfeminine                        170     0xAA
guillemotleft                      171     0xAB
notsign                            172     0xAC
hyphen                             173     0xAD
registered                         174     0xAE
macron                             175     0xAF
degree                             176     0xB0
plusminus                          177     0xB1
twosuperior                        178     0xB2
threesuperior                      179     0xB3
acute                              180     0xB4
mu                                 181     0xB5
paragraph                          182     0xB6
periodcentered                     183     0xB7
cedilla                            184     0xB8
onesuperior                        185     0xB9
masculine                          186     0xBA
guillemotright                     187     0xBB
onequarter                         188     0xBC
onehalf                            189     0xBD
threequarters                      190     0xBE
questiondown                       191     0xBF
Agrave                             192     0xC0
Aacute                             193     0xC1
Acircumflex                        194     0xC2
Atilde                             195     0xC3
Adiaeresis                         196     0xC4
Aring                              197     0xC5
AE                                 198     0xC6
Ccedilla                           199     0xC7
Egrave                             200     0xC8
Eacute                             201     0xC9
Ecircumflex                        202     0xCA
Ediaeresis                         203     0xCB
Igrave                             204     0xCC
Iacute                             205     0xCD
Icircumflex                        206     0xCE
Idiaeresis                         207     0xCF
ETH                                208     0xD0
Ntilde                             209     0xD1
Ograve                             210     0xD2
Oacute                             211     0xD3
Ocircumflex                        212     0xD4
Otilde                             213     0xD5
Odiaeresis                         214     0xD6
multiply                           215     0xD7
Oslash                             216     0xD8
Ugrave                             217     0xD9
Uacute                             218     0xDA
Ucircumflex                        219     0xDB
Udiaeresis                         220     0xDC
Yacute                             221     0xDD
THORN                              222     0xDE
ssharp                             223     0xDF
agrave                             224     0xE0
aacute                             225     0xE1
acircumflex                        226     0xE2
atilde                             227     0xE3
adiaeresis                         228     0xE4
aring                              229     0xE5
ae                                 230     0xE6
ccedilla                           231     0xE7
egrave                             232     0xE8
eacute                             233     0xE9
ecircumflex                        234     0xEA
ediaeresis                         235     0xEB
igrave                             236     0xEC
iacute                             237     0xED
icircumflex                        238     0xEE
idiaeresis                         239     0xEF
eth                                240     0xF0
ntilde                             241     0xF1
ograve                             242     0xF2
oacute                             243     0xF3
ocircumflex                        244     0xF4
otilde                             245     0xF5
odiaeresis                         246     0xF6
division                           247     0xF7
oslash                             248     0xF8
ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC
yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF
Aogonek                            417     0x1A1
breve                              418     0x1A2
Lstroke                            419     0x1A3
Lcaron                             421     0x1A5
Sacute                             422     0x1A6
Scaron                             425     0x1A9
Scedilla                           426     0x1AA
Tcaron                             427     0x1AB
Zacute                             428     0x1AC
.CE
.CS
Zcaron                             430     0x1AE
Zabovedot                          431     0x1AF
aogonek                            433     0x1B1
ogonek                             434     0x1B2
lstroke                            435     0x1B3
lcaron                             437     0x1B5
sacute                             438     0x1B6
caron                              439     0x1B7
scaron                             441     0x1B9
scedilla                           442     0x1BA
tcaron                             443     0x1BB
zacute                             444     0x1BC
doubleacute                        445     0x1BD
zcaron                             446     0x1BE
zabovedot                          447     0x1BF
Racute                             448     0x1C0
Abreve                             451     0x1C3
Lacute                             453     0x1C5
Cacute                             454     0x1C6
Ccaron                             456     0x1C8
Eogonek                            458     0x1CA
Ecaron                             460     0x1CC
Dcaron                             463     0x1CF
Dstroke                            464     0x1D0
Nacute                             465     0x1D1
Ncaron                             466     0x1D2
Odoubleacute                       469     0x1D5
Rcaron                             472     0x1D8
Uring                              473     0x1D9
Udoubleacute                       475     0x1DB
Tcedilla                           478     0x1DE
racute                             480     0x1E0
abreve                             483     0x1E3
lacute                             485     0x1E5
cacute                             486     0x1E6
ccaron                             488     0x1E8
eogonek                            490     0x1EA
ecaron                             492     0x1EC
dcaron                             495     0x1EF
dstroke                            496     0x1F0
nacute                             497     0x1F1
ncaron                             498     0x1F2
odoubleacute                       501     0x1F5
rcaron                             504     0x1F8
uring                              505     0x1F9
udoubleacute                       507     0x1FB
tcedilla                           510     0x1FE
abovedot                           511     0x1FF
Hstroke                            673     0x2A1
Hcircumflex                        678     0x2A6
Iabovedot                          681     0x2A9
Gbreve                             683     0x2AB
Jcircumflex                        684     0x2AC
hstroke                            689     0x2B1
hcircumflex                        694     0x2B6
idotless                           697     0x2B9
gbreve                             699     0x2BB
jcircumflex                        700     0x2BC
Cabovedot                          709     0x2C5
Ccircumflex                        710     0x2C6
Gabovedot                          725     0x2D5
Gcircumflex                        728     0x2D8
Ubreve                             733     0x2DD
Scircumflex                        734     0x2DE
cabovedot                          741     0x2E5
ccircumflex                        742     0x2E6
gabovedot                          757     0x2F5
gcircumflex                        760     0x2F8
ubreve                             765     0x2FD
scircumflex                        766     0x2FE
kra                                930     0x3A2
Rcedilla                           931     0x3A3
Itilde                             933     0x3A5
Lcedilla                           934     0x3A6
Emacron                            938     0x3AA
Gcedilla                           939     0x3AB
Tslash                             940     0x3AC
rcedilla                           947     0x3B3
itilde                             949     0x3B5
lcedilla                           950     0x3B6
emacron                            954     0x3BA
gcedilla                           955     0x3BB
tslash                             956     0x3BC
ENG                                957     0x3BD
eng                                959     0x3BF
Amacron                            960     0x3C0
Iogonek                            967     0x3C7
Eabovedot                          972     0x3CC
Imacron                            975     0x3CF
Ncedilla                           977     0x3D1
Omacron                            978     0x3D2
Kcedilla                           979     0x3D3
Uogonek                            985     0x3D9
Utilde                             989     0x3DD
Umacron                            990     0x3DE
amacron                            992     0x3E0
iogonek                            999     0x3E7
eabovedot                         1004     0x3EC
imacron                           1007     0x3EF
ncedilla                          1009     0x3F1
omacron                           1010     0x3F2
kcedilla                          1011     0x3F3
uogonek                           1017     0x3F9
utilde                            1021     0x3FD
umacron                           1022     0x3FE
overline                          1150     0x47E
kana_fullstop                     1185     0x4A1
kana_openingbracket               1186     0x4A2
kana_closingbracket               1187     0x4A3
kana_comma                        1188     0x4A4
kana_conjunctive                  1189     0x4A5
kana_WO                           1190     0x4A6
kana_a                            1191     0x4A7
kana_i                            1192     0x4A8
kana_u                            1193     0x4A9
kana_e                            1194     0x4AA
kana_o                            1195     0x4AB
kana_ya                           1196     0x4AC
kana_yu                           1197     0x4AD
kana_yo                           1198     0x4AE
kana_tsu                          1199     0x4AF
prolongedsound                    1200     0x4B0
kana_A                            1201     0x4B1
kana_I                            1202     0x4B2
kana_U                            1203     0x4B3
kana_E                            1204     0x4B4
kana_O                            1205     0x4B5
kana_KA                           1206     0x4B6
kana_KI                           1207     0x4B7
kana_KU                           1208     0x4B8
kana_KE                           1209     0x4B9
kana_KO                           1210     0x4BA
kana_SA                           1211     0x4BB
kana_SHI                          1212     0x4BC
kana_SU                           1213     0x4BD
kana_SE                           1214     0x4BE
kana_SO                           1215     0x4BF
kana_TA                           1216     0x4C0
kana_CHI                          1217     0x4C1
kana_TSU                          1218     0x4C2
kana_TE                           1219     0x4C3
kana_TO                           1220     0x4C4
kana_NA                           1221     0x4C5
kana_NI                           1222     0x4C6
kana_NU                           1223     0x4C7
kana_NE                           1224     0x4C8
kana_NO                           1225     0x4C9
kana_HA                           1226     0x4CA
kana_HI                           1227     0x4CB
kana_FU                           1228     0x4CC
kana_HE                           1229     0x4CD
kana_HO                           1230     0x4CE
kana_MA                           1231     0x4CF
kana_MI                           1232     0x4D0
kana_MU                           1233     0x4D1
kana_ME                           1234     0x4D2
kana_MO                           1235     0x4D3
kana_YA                           1236     0x4D4
kana_YU                           1237     0x4D5
kana_YO                           1238     0x4D6
kana_RA                           1239     0x4D7
kana_RI                           1240     0x4D8
kana_RU                           1241     0x4D9
kana_RE                           1242     0x4DA
kana_RO                           1243     0x4DB
kana_WA                           1244     0x4DC
kana_N                            1245     0x4DD
voicedsound                       1246     0x4DE
semivoicedsound                   1247     0x4DF
Arabic_comma                      1452     0x5AC
Arabic_semicolon                  1467     0x5BB
Arabic_question_mark              1471     0x5BF
Arabic_hamza                      1473     0x5C1
Arabic_maddaonalef                1474     0x5C2
Arabic_hamzaonalef                1475     0x5C3
Arabic_hamzaonwaw                 1476     0x5C4
Arabic_hamzaunderalef             1477     0x5C5
Arabic_hamzaonyeh                 1478     0x5C6
Arabic_alef                       1479     0x5C7
Arabic_beh                        1480     0x5C8
Arabic_tehmarbuta                 1481     0x5C9
Arabic_teh                        1482     0x5CA
Arabic_theh                       1483     0x5CB
Arabic_jeem                       1484     0x5CC
Arabic_hah                        1485     0x5CD
Arabic_khah                       1486     0x5CE
Arabic_dal                        1487     0x5CF
Arabic_thal                       1488     0x5D0
Arabic_ra                         1489     0x5D1
Arabic_zain                       1490     0x5D2
Arabic_seen                       1491     0x5D3
Arabic_sheen                      1492     0x5D4
Arabic_sad                        1493     0x5D5
Arabic_dad                        1494     0x5D6
Arabic_tah                        1495     0x5D7
Arabic_zah                        1496     0x5D8
Arabic_ain                        1497     0x5D9
Arabic_ghain                      1498     0x5DA
Arabic_tatweel                    1504     0x5E0
Arabic_feh                        1505     0x5E1
Arabic_qaf                        1506     0x5E2
Arabic_kaf                        1507     0x5E3
Arabic_lam                        1508     0x5E4
Arabic_meem                       1509     0x5E5
.CE
.CS
Arabic_noon                       1510     0x5E6
Arabic_ha                         1511     0x5E7
Arabic_waw                        1512     0x5E8
Arabic_alefmaksura                1513     0x5E9
Arabic_yeh                        1514     0x5EA
Arabic_fathatan                   1515     0x5EB
Arabic_dammatan                   1516     0x5EC
Arabic_kasratan                   1517     0x5ED
Arabic_fatha                      1518     0x5EE
Arabic_damma                      1519     0x5EF
Arabic_kasra                      1520     0x5F0
Arabic_shadda                     1521     0x5F1
Arabic_sukun                      1522     0x5F2
Serbian_dje                       1697     0x6A1
Macedonia_gje                     1698     0x6A2
Cyrillic_io                       1699     0x6A3
Ukrainian_ie                      1700     0x6A4
Macedonia_dse                     1701     0x6A5
Ukrainian_i                       1702     0x6A6
Ukrainian_yi                      1703     0x6A7
Cyrillic_je                       1704     0x6A8
Cyrillic_lje                      1705     0x6A9
Cyrillic_nje                      1706     0x6AA
Serbian_tshe                      1707     0x6AB
Macedonia_kje                     1708     0x6AC
Ukrainian_ghe_with_upturn         1709     0x6AD
Byelorussian_shortu               1710     0x6AE
Cyrillic_dzhe                     1711     0x6AF
numerosign                        1712     0x6B0
Serbian_DJE                       1713     0x6B1
Macedonia_GJE                     1714     0x6B2
Cyrillic_IO                       1715     0x6B3
Ukrainian_IE                      1716     0x6B4
Macedonia_DSE                     1717     0x6B5
Ukrainian_I                       1718     0x6B6
Ukrainian_YI                      1719     0x6B7
Cyrillic_JE                       1720     0x6B8
Cyrillic_LJE                      1721     0x6B9
Cyrillic_NJE                      1722     0x6BA
Serbian_TSHE                      1723     0x6BB
Macedonia_KJE                     1724     0x6BC
Ukrainian_GHE_WITH_UPTURN         1725     0x6BD
Byelorussian_SHORTU               1726     0x6BE
Cyrillic_DZHE                     1727     0x6BF
Cyrillic_yu                       1728     0x6C0
Cyrillic_a                        1729     0x6C1
Cyrillic_be                       1730     0x6C2
Cyrillic_tse                      1731     0x6C3
Cyrillic_de                       1732     0x6C4


Cyrillic_ie                       1733     0x6C5
Cyrillic_ef                       1734     0x6C6
Cyrillic_ghe                      1735     0x6C7
Cyrillic_ha                       1736     0x6C8
Cyrillic_i                        1737     0x6C9
Cyrillic_shorti                   1738     0x6CA
Cyrillic_ka                       1739     0x6CB
Cyrillic_el                       1740     0x6CC
Cyrillic_em                       1741     0x6CD
Cyrillic_en                       1742     0x6CE
Cyrillic_o                        1743     0x6CF
Cyrillic_pe                       1744     0x6D0
Cyrillic_ya                       1745     0x6D1
Cyrillic_er                       1746     0x6D2
Cyrillic_es                       1747     0x6D3
Cyrillic_te                       1748     0x6D4
Cyrillic_u                        1749     0x6D5
Cyrillic_zhe                      1750     0x6D6
Cyrillic_ve                       1751     0x6D7
Cyrillic_softsign                 1752     0x6D8
Cyrillic_yeru                     1753     0x6D9
Cyrillic_ze                       1754     0x6DA
Cyrillic_sha                      1755     0x6DB
Cyrillic_e                        1756     0x6DC
Cyrillic_shcha                    1757     0x6DD
Cyrillic_che                      1758     0x6DE
Cyrillic_hardsign                 1759     0x6DF
Cyrillic_YU                       1760     0x6E0
Cyrillic_A                        1761     0x6E1
Cyrillic_BE                       1762     0x6E2
Cyrillic_TSE                      1763     0x6E3
Cyrillic_DE                       1764     0x6E4
Cyrillic_IE                       1765     0x6E5
Cyrillic_EF                       1766     0x6E6
Cyrillic_GHE                      1767     0x6E7
Cyrillic_HA                       1768     0x6E8
Cyrillic_I                        1769     0x6E9
Cyrillic_SHORTI                   1770     0x6EA
Cyrillic_KA                       1771     0x6EB
Cyrillic_EL                       1772     0x6EC
Cyrillic_EM                       1773     0x6ED
Cyrillic_EN                       1774     0x6EE
Cyrillic_O                        1775     0x6EF
Cyrillic_PE                       1776     0x6F0
Cyrillic_YA                       1777     0x6F1
Cyrillic_ER                       1778     0x6F2
Cyrillic_ES                       1779     0x6F3
Cyrillic_TE                       1780     0x6F4
Cyrillic_U                        1781     0x6F5
Cyrillic_ZHE                      1782     0x6F6
Cyrillic_VE                       1783     0x6F7
Cyrillic_SOFTSIGN                 1784     0x6F8
Cyrillic_YERU                     1785     0x6F9
Cyrillic_ZE                       1786     0x6FA
Cyrillic_SHA                      1787     0x6FB
Cyrillic_E                        1788     0x6FC
Cyrillic_SHCHA                    1789     0x6FD
Cyrillic_CHE                      1790     0x6FE
Cyrillic_HARDSIGN                 1791     0x6FF
Greek_ALPHAaccent                 1953     0x7A1
Greek_EPSILONaccent               1954     0x7A2
Greek_ETAaccent                   1955     0x7A3
Greek_IOTAaccent                  1956     0x7A4
Greek_IOTAdieresis                1957     0x7A5
Greek_OMICRONaccent               1959     0x7A7
Greek_UPSILONaccent               1960     0x7A8
Greek_UPSILONdieresis             1961     0x7A9
Greek_OMEGAaccent                 1963     0x7AB
Greek_accentdieresis              1966     0x7AE
Greek_horizbar                    1967     0x7AF
Greek_alphaaccent                 1969     0x7B1
Greek_epsilonaccent               1970     0x7B2
Greek_etaaccent                   1971     0x7B3
Greek_iotaaccent                  1972     0x7B4
Greek_iotadieresis                1973     0x7B5
Greek_iotaaccentdieresis          1974     0x7B6
Greek_omicronaccent               1975     0x7B7
Greek_upsilonaccent               1976     0x7B8
Greek_upsilondieresis             1977     0x7B9
Greek_upsilonaccentdieresis       1978     0x7BA
Greek_omegaaccent                 1979     0x7BB
Greek_ALPHA                       1985     0x7C1
Greek_BETA                        1986     0x7C2
Greek_GAMMA                       1987     0x7C3
Greek_DELTA                       1988     0x7C4
Greek_EPSILON                     1989     0x7C5
Greek_ZETA                        1990     0x7C6
Greek_ETA                         1991     0x7C7
Greek_THETA                       1992     0x7C8
Greek_IOTA                        1993     0x7C9
Greek_KAPPA                       1994     0x7CA
Greek_LAMDA                       1995     0x7CB
Greek_MU                          1996     0x7CC
Greek_NU                          1997     0x7CD
Greek_XI                          1998     0x7CE
Greek_OMICRON                     1999     0x7CF
Greek_PI                          2000     0x7D0
Greek_RHO                         2001     0x7D1
Greek_SIGMA                       2002     0x7D2
Greek_TAU                         2004     0x7D4
Greek_UPSILON                     2005     0x7D5
Greek_PHI                         2006     0x7D6
Greek_CHI                         2007     0x7D7
Greek_PSI                         2008     0x7D8
Greek_OMEGA                       2009     0x7D9
Greek_alpha                       2017     0x7E1
Greek_beta                        2018     0x7E2
Greek_gamma                       2019     0x7E3
Greek_delta                       2020     0x7E4
Greek_epsilon                     2021     0x7E5
Greek_zeta                        2022     0x7E6
Greek_eta                         2023     0x7E7
Greek_theta                       2024     0x7E8
Greek_iota                        2025     0x7E9
Greek_kappa                       2026     0x7EA
Greek_lamda                       2027     0x7EB
Greek_mu                          2028     0x7EC
Greek_nu                          2029     0x7ED
Greek_xi                          2030     0x7EE
Greek_omicron                     2031     0x7EF
Greek_pi                          2032     0x7F0
Greek_rho                         2033     0x7F1
Greek_sigma                       2034     0x7F2
Greek_finalsmallsigma             2035     0x7F3
Greek_tau                         2036     0x7F4
Greek_upsilon                     2037     0x7F5
Greek_phi                         2038     0x7F6
Greek_chi                         2039     0x7F7
Greek_psi                         2040     0x7F8
Greek_omega                       2041     0x7F9
leftradical                       2209     0x8A1
topleftradical                    2210     0x8A2
horizconnector                    2211     0x8A3
topintegral                       2212     0x8A4
botintegral                       2213     0x8A5
vertconnector                     2214     0x8A6
topleftsqbracket                  2215     0x8A7
botleftsqbracket                  2216     0x8A8
toprightsqbracket                 2217     0x8A9
botrightsqbracket                 2218     0x8AA
topleftparens                     2219     0x8AB
botleftparens                     2220     0x8AC
toprightparens                    2221     0x8AD
botrightparens                    2222     0x8AE
leftmiddlecurlybrace              2223     0x8AF
rightmiddlecurlybrace             2224     0x8B0
topleftsummation                  2225     0x8B1
botleftsummation                  2226     0x8B2
topvertsummationconnector         2227     0x8B3
botvertsummationconnector         2228     0x8B4
toprightsummation                 2229     0x8B5
botrightsummation                 2230     0x8B6
rightmiddlesummation              2231     0x8B7
.CE
.CS
lessthanequal                     2236     0x8BC
notequal                          2237     0x8BD
greaterthanequal                  2238     0x8BE
integral                          2239     0x8BF
therefore                         2240     0x8C0
variation                         2241     0x8C1
infinity                          2242     0x8C2
nabla                             2245     0x8C5
approximate                       2248     0x8C8
similarequal                      2249     0x8C9
ifonlyif                          2253     0x8CD
implies                           2254     0x8CE
identical                         2255     0x8CF
radical                           2262     0x8D6
includedin                        2266     0x8DA
includes                          2267     0x8DB
intersection                      2268     0x8DC
union                             2269     0x8DD
logicaland                        2270     0x8DE
logicalor                         2271     0x8DF
partialderivative                 2287     0x8EF
function                          2294     0x8F6
leftarrow                         2299     0x8FB
uparrow                           2300     0x8FC
rightarrow                        2301     0x8FD
downarrow                         2302     0x8FE
blank                             2527     0x9DF
soliddiamond                      2528     0x9E0
checkerboard                      2529     0x9E1
ht                                2530     0x9E2
ff                                2531     0x9E3
cr                                2532     0x9E4
lf                                2533     0x9E5
nl                                2536     0x9E8
vt                                2537     0x9E9
lowrightcorner                    2538     0x9EA
uprightcorner                     2539     0x9EB
upleftcorner                      2540     0x9EC
lowleftcorner                     2541     0x9ED
crossinglines                     2542     0x9EE
horizlinescan1                    2543     0x9EF
horizlinescan3                    2544     0x9F0
horizlinescan5                    2545     0x9F1
horizlinescan7                    2546     0x9F2
horizlinescan9                    2547     0x9F3
leftt                             2548     0x9F4
rightt                            2549     0x9F5
bott                              2550     0x9F6
topt                              2551     0x9F7
vertbar                           2552     0x9F8
emspace                           2721     0xAA1
enspace                           2722     0xAA2
em3space                          2723     0xAA3
em4space                          2724     0xAA4
digitspace                        2725     0xAA5
punctspace                        2726     0xAA6
thinspace                         2727     0xAA7
hairspace                         2728     0xAA8
emdash                            2729     0xAA9
endash                            2730     0xAAA
signifblank                       2732     0xAAC
ellipsis                          2734     0xAAE
doubbaselinedot                   2735     0xAAF
onethird                          2736     0xAB0
twothirds                         2737     0xAB1
onefifth                          2738     0xAB2
twofifths                         2739     0xAB3
threefifths                       2740     0xAB4
fourfifths                        2741     0xAB5
onesixth                          2742     0xAB6
fivesixths                        2743     0xAB7
careof                            2744     0xAB8
figdash                           2747     0xABB
leftanglebracket                  2748     0xABC
decimalpoint                      2749     0xABD
rightanglebracket                 2750     0xABE
marker                            2751     0xABF
oneeighth                         2755     0xAC3
threeeighths                      2756     0xAC4
fiveeighths                       2757     0xAC5
seveneighths                      2758     0xAC6
trademark                         2761     0xAC9
signaturemark                     2762     0xACA
trademarkincircle                 2763     0xACB
leftopentriangle                  2764     0xACC
rightopentriangle                 2765     0xACD
emopencircle                      2766     0xACE
emopenrectangle                   2767     0xACF
leftsinglequotemark               2768     0xAD0
rightsinglequotemark              2769     0xAD1
leftdoublequotemark               2770     0xAD2
rightdoublequotemark              2771     0xAD3
prescription                      2772     0xAD4
permille                          2773     0xAD5
minutes                           2774     0xAD6
seconds                           2775     0xAD7
latincross                        2777     0xAD9
hexagram                          2778     0xADA
filledrectbullet                  2779     0xADB
filledlefttribullet               2780     0xADC
filledrighttribullet              2781     0xADD
emfilledcircle                    2782     0xADE
emfilledrect                      2783     0xADF
enopencircbullet                  2784     0xAE0
enopensquarebullet                2785     0xAE1
openrectbullet                    2786     0xAE2
opentribulletup                   2787     0xAE3
opentribulletdown                 2788     0xAE4
openstar                          2789     0xAE5
enfilledcircbullet                2790     0xAE6
enfilledsqbullet                  2791     0xAE7
filledtribulletup                 2792     0xAE8
filledtribulletdown               2793     0xAE9
leftpointer                       2794     0xAEA
rightpointer                      2795     0xAEB
club                              2796     0xAEC
diamond                           2797     0xAED
heart                             2798     0xAEE
maltesecross                      2800     0xAF0
dagger                            2801     0xAF1
doubledagger                      2802     0xAF2
checkmark                         2803     0xAF3
ballotcross                       2804     0xAF4
musicalsharp                      2805     0xAF5
musicalflat                       2806     0xAF6
malesymbol                        2807     0xAF7
femalesymbol                      2808     0xAF8
telephone                         2809     0xAF9
telephonerecorder                 2810     0xAFA
phonographcopyright               2811     0xAFB
caret                             2812     0xAFC
singlelowquotemark                2813     0xAFD
doublelowquotemark                2814     0xAFE
cursor                            2815     0xAFF
leftcaret                         2979     0xBA3
rightcaret                        2982     0xBA6
downcaret                         2984     0xBA8
upcaret                           2985     0xBA9
overbar                           3008     0xBC0
downtack                          3010     0xBC2
upshoe                            3011     0xBC3
downstile                         3012     0xBC4
underbar                          3014     0xBC6
jot                               3018     0xBCA
quad                              3020     0xBCC
uptack                            3022     0xBCE
circle                            3023     0xBCF
upstile                           3027     0xBD3
downshoe                          3030     0xBD6
rightshoe                         3032     0xBD8
leftshoe                          3034     0xBDA
lefttack                          3036     0xBDC
righttack                         3068     0xBFC
hebrew_doublelowline              3295     0xCDF
hebrew_aleph                      3296     0xCE0
hebrew_bet                        3297     0xCE1
hebrew_gimel                      3298     0xCE2
hebrew_dalet                      3299     0xCE3
hebrew_he                         3300     0xCE4
hebrew_waw                        3301     0xCE5
hebrew_zain                       3302     0xCE6
hebrew_chet                       3303     0xCE7
hebrew_tet                        3304     0xCE8
hebrew_yod                        3305     0xCE9
hebrew_finalkaph                  3306     0xCEA
hebrew_kaph                       3307     0xCEB
hebrew_lamed                      3308     0xCEC
hebrew_finalmem                   3309     0xCED
hebrew_mem                        3310     0xCEE
hebrew_finalnun                   3311     0xCEF
hebrew_nun                        3312     0xCF0
hebrew_samech                     3313     0xCF1
hebrew_ayin                       3314     0xCF2
hebrew_finalpe                    3315     0xCF3
hebrew_pe                         3316     0xCF4
hebrew_finalzade                  3317     0xCF5
hebrew_zade                       3318     0xCF6
hebrew_qoph                       3319     0xCF7
hebrew_resh                       3320     0xCF8
hebrew_shin                       3321     0xCF9
hebrew_taw                        3322     0xCFA
Thai_kokai                        3489     0xDA1
Thai_khokhai                      3490     0xDA2
Thai_khokhuat                     3491     0xDA3
Thai_khokhwai                     3492     0xDA4
Thai_khokhon                      3493     0xDA5
Thai_khorakhang                   3494     0xDA6
Thai_ngongu                       3495     0xDA7
Thai_chochan                      3496     0xDA8
Thai_choching                     3497     0xDA9
Thai_chochang                     3498     0xDAA
Thai_soso                         3499     0xDAB
Thai_chochoe                      3500     0xDAC
Thai_yoying                       3501     0xDAD
Thai_dochada                      3502     0xDAE
Thai_topatak                      3503     0xDAF
Thai_thothan                      3504     0xDB0
Thai_thonangmontho                3505     0xDB1
Thai_thophuthao                   3506     0xDB2
Thai_nonen                        3507     0xDB3
Thai_dodek                        3508     0xDB4
Thai_totao                        3509     0xDB5
Thai_thothung                     3510     0xDB6
Thai_thothahan                    3511     0xDB7
Thai_thothong                     3512     0xDB8
Thai_nonu                         3513     0xDB9
Thai_bobaimai                     3514     0xDBA
Thai_popla                        3515     0xDBB
Thai_phophung                     3516     0xDBC
Thai_fofa                         3517     0xDBD
Thai_phophan                      3518     0xDBE
Thai_fofan                        3519     0xDBF
Thai_phosamphao                   3520     0xDC0
Thai_moma                         3521     0xDC1
Thai_yoyak                        3522     0xDC2
Thai_rorua                        3523     0xDC3
Thai_ru                           3524     0xDC4
Thai_loling                       3525     0xDC5
Thai_lu                           3526     0xDC6
Thai_wowaen                       3527     0xDC7
Thai_sosala                       3528     0xDC8
Thai_sorusi                       3529     0xDC9
Thai_sosua                        3530     0xDCA
Thai_hohip                        3531     0xDCB
Thai_lochula                      3532     0xDCC
Thai_oang                         3533     0xDCD
Thai_honokhuk                     3534     0xDCE
Thai_paiyannoi                    3535     0xDCF
Thai_saraa                        3536     0xDD0
Thai_maihanakat                   3537     0xDD1
Thai_saraaa                       3538     0xDD2
Thai_saraam                       3539     0xDD3
Thai_sarai                        3540     0xDD4
Thai_saraii                       3541     0xDD5
Thai_saraue                       3542     0xDD6
Thai_sarauee                      3543     0xDD7
Thai_sarau                        3544     0xDD8
Thai_sarauu                       3545     0xDD9
Thai_phinthu                      3546     0xDDA
Thai_maihanakat_maitho            3550     0xDDE
Thai_baht                         3551     0xDDF
Thai_sarae                        3552     0xDE0
Thai_saraae                       3553     0xDE1
Thai_sarao                        3554     0xDE2
Thai_saraaimaimuan                3555     0xDE3
Thai_saraaimaimalai               3556     0xDE4
Thai_lakkhangyao                  3557     0xDE5
Thai_maiyamok                     3558     0xDE6
Thai_maitaikhu                    3559     0xDE7
Thai_maiek                        3560     0xDE8
Thai_maitho                       3561     0xDE9
Thai_maitri                       3562     0xDEA
Thai_maichattawa                  3563     0xDEB
Thai_thanthakhat                  3564     0xDEC
Thai_nikhahit                     3565     0xDED
Thai_leksun                       3568     0xDF0
Thai_leknung                      3569     0xDF1
Thai_leksong                      3570     0xDF2
Thai_leksam                       3571     0xDF3
Thai_leksi                        3572     0xDF4
Thai_lekha                        3573     0xDF5
Thai_lekhok                       3574     0xDF6
Thai_lekchet                      3575     0xDF7
Thai_lekpaet                      3576     0xDF8
Thai_lekkao                       3577     0xDF9
Hangul_Kiyeog                     3745     0xEA1
Hangul_SsangKiyeog                3746     0xEA2
Hangul_KiyeogSios                 3747     0xEA3
Hangul_Nieun                      3748     0xEA4
Hangul_NieunJieuj                 3749     0xEA5
Hangul_NieunHieuh                 3750     0xEA6
Hangul_Dikeud                     3751     0xEA7
Hangul_SsangDikeud                3752     0xEA8
Hangul_Rieul                      3753     0xEA9
Hangul_RieulKiyeog                3754     0xEAA
Hangul_RieulMieum                 3755     0xEAB
Hangul_RieulPieub                 3756     0xEAC
Hangul_RieulSios                  3757     0xEAD
Hangul_RieulTieut                 3758     0xEAE
Hangul_RieulPhieuf                3759     0xEAF
Hangul_RieulHieuh                 3760     0xEB0
Hangul_Mieum                      3761     0xEB1
Hangul_Pieub                      3762     0xEB2
Hangul_SsangPieub                 3763     0xEB3
Hangul_PieubSios                  3764     0xEB4
Hangul_Sios                       3765     0xEB5
Hangul_SsangSios                  3766     0xEB6
Hangul_Ieung                      3767     0xEB7
Hangul_Jieuj                      3768     0xEB8
Hangul_SsangJieuj                 3769     0xEB9
Hangul_Cieuc                      3770     0xEBA
Hangul_Khieuq                     3771     0xEBB
Hangul_Tieut                      3772     0xEBC
Hangul_Phieuf                     3773     0xEBD
Hangul_Hieuh                      3774     0xEBE
Hangul_A                          3775     0xEBF
Hangul_AE                         3776     0xEC0
Hangul_YA                         3777     0xEC1
Hangul_YAE                        3778     0xEC2
Hangul_EO                         3779     0xEC3
Hangul_E                          3780     0xEC4
Hangul_YEO                        3781     0xEC5
Hangul_YE                         3782     0xEC6
Hangul_O                          3783     0xEC7
Hangul_WA                         3784     0xEC8


Hangul_WAE                        3785     0xEC9
Hangul_OE                         3786     0xECA
Hangul_YO                         3787     0xECB
Hangul_U                          3788     0xECC
Hangul_WEO                        3789     0xECD
Hangul_WE                         3790     0xECE
Hangul_WI                         3791     0xECF
Hangul_YU                         3792     0xED0
Hangul_EU                         3793     0xED1
Hangul_YI                         3794     0xED2
Hangul_I                          3795     0xED3
Hangul_J_Kiyeog                   3796     0xED4
Hangul_J_SsangKiyeog              3797     0xED5
Hangul_J_KiyeogSios               3798     0xED6
Hangul_J_Nieun                    3799     0xED7
Hangul_J_NieunJieuj               3800     0xED8
Hangul_J_NieunHieuh               3801     0xED9
Hangul_J_Dikeud                   3802     0xEDA
Hangul_J_Rieul                    3803     0xEDB
Hangul_J_RieulKiyeog              3804     0xEDC
Hangul_J_RieulMieum               3805     0xEDD
Hangul_J_RieulPieub               3806     0xEDE
Hangul_J_RieulSios                3807     0xEDF
Hangul_J_RieulTieut               3808     0xEE0
Hangul_J_RieulPhieuf              3809     0xEE1
Hangul_J_RieulHieuh               3810     0xEE2
Hangul_J_Mieum                    3811     0xEE3
Hangul_J_Pieub                    3812     0xEE4
Hangul_J_PieubSios                3813     0xEE5
Hangul_J_Sios                     3814     0xEE6
Hangul_J_SsangSios                3815     0xEE7
Hangul_J_Ieung                    3816     0xEE8
Hangul_J_Jieuj                    3817     0xEE9
Hangul_J_Cieuc                    3818     0xEEA
Hangul_J_Khieuq                   3819     0xEEB
Hangul_J_Tieut                    3820     0xEEC
Hangul_J_Phieuf                   3821     0xEED
Hangul_J_Hieuh                    3822     0xEEE
Hangul_RieulYeorinHieuh           3823     0xEEF
Hangul_SunkyeongeumMieum          3824     0xEF0
Hangul_SunkyeongeumPieub          3825     0xEF1
Hangul_PanSios                    3826     0xEF2
Hangul_KkogjiDalrinIeung          3827     0xEF3
Hangul_SunkyeongeumPhieuf         3828     0xEF4
Hangul_YeorinHieuh                3829     0xEF5
Hangul_AraeA                      3830     0xEF6
Hangul_AraeAE                     3831     0xEF7
Hangul_J_PanSios                  3832     0xEF8
Hangul_J_KkogjiDalrinIeung        3833     0xEF9
Hangul_J_YeorinHieuh              3834     0xEFA
Korean_Won                        3839     0xEFF
OE                                5052     0x13BC
oe                                5053     0x13BD
Ydiaeresis                        5054     0x13BE
EuroSign                          8364     0x20AC
3270_Duplicate                   64769     0xFD01
3270_FieldMark                   64770     0xFD02
3270_Right2                      64771     0xFD03
3270_Left2                       64772     0xFD04
3270_BackTab                     64773     0xFD05
3270_EraseEOF                    64774     0xFD06
3270_EraseInput                  64775     0xFD07
3270_Reset                       64776     0xFD08
3270_Quit                        64777     0xFD09
3270_PA1                         64778     0xFD0A
3270_PA2                         64779     0xFD0B
3270_PA3                         64780     0xFD0C
3270_Test                        64781     0xFD0D
3270_Attn                        64782     0xFD0E
3270_CursorBlink                 64783     0xFD0F
3270_AltCursor                   64784     0xFD10
3270_KeyClick                    64785     0xFD11
3270_Jump                        64786     0xFD12
3270_Ident                       64787     0xFD13
3270_Rule                        64788     0xFD14
3270_Copy                        64789     0xFD15
3270_Play                        64790     0xFD16
3270_Setup                       64791     0xFD17
3270_Record                      64792     0xFD18
3270_ChangeScreen                64793     0xFD19
3270_DeleteWord                  64794     0xFD1A
3270_ExSelect                    64795     0xFD1B
3270_CursorSelect                64796     0xFD1C
3270_PrintScreen                 64797     0xFD1D
3270_Enter                       64798     0xFD1E
ISO_Lock                         65025     0xFE01
ISO_Level2_Latch                 65026     0xFE02
ISO_Level3_Shift                 65027     0xFE03
ISO_Level3_Latch                 65028     0xFE04
ISO_Level3_Lock                  65029     0xFE05
ISO_Group_Latch                  65030     0xFE06
ISO_Group_Lock                   65031     0xFE07
ISO_Next_Group                   65032     0xFE08
ISO_Next_Group_Lock              65033     0xFE09
ISO_Prev_Group                   65034     0xFE0A
ISO_Prev_Group_Lock              65035     0xFE0B
ISO_First_Group                  65036     0xFE0C
ISO_First_Group_Lock             65037     0xFE0D
ISO_Last_Group                   65038     0xFE0E
ISO_Last_Group_Lock              65039     0xFE0F
ISO_Level5_Shift                 65041     0xFE11
ISO_Level5_Latch                 65042     0xFE12
ISO_Level5_Lock                  65043     0xFE13
ISO_Left_Tab                     65056     0xFE20
ISO_Move_Line_Up                 65057     0xFE21
ISO_Move_Line_Down               65058     0xFE22
ISO_Partial_Line_Up              65059     0xFE23
ISO_Partial_Line_Down            65060     0xFE24
ISO_Partial_Space_Left           65061     0xFE25
ISO_Partial_Space_Right          65062     0xFE26
ISO_Set_Margin_Left              65063     0xFE27
ISO_Set_Margin_Right             65064     0xFE28
ISO_Release_Margin_Left          65065     0xFE29
ISO_Release_Margin_Right         65066     0xFE2A
ISO_Release_Both_Margins         65067     0xFE2B
ISO_Fast_Cursor_Left             65068     0xFE2C
ISO_Fast_Cursor_Right            65069     0xFE2D
ISO_Fast_Cursor_Up               65070     0xFE2E
ISO_Fast_Cursor_Down             65071     0xFE2F
ISO_Continuous_Underline         65072     0xFE30
ISO_Discontinuous_Underline      65073     0xFE31
ISO_Emphasize                    65074     0xFE32
ISO_Center_Object                65075     0xFE33
ISO_Enter                        65076     0xFE34
dead_grave                       65104     0xFE50
dead_acute                       65105     0xFE51
dead_circumflex                  65106     0xFE52
dead_tilde                       65107     0xFE53
dead_macron                      65108     0xFE54
dead_breve                       65109     0xFE55
dead_abovedot                    65110     0xFE56
dead_diaeresis                   65111     0xFE57
dead_abovering                   65112     0xFE58
dead_doubleacute                 65113     0xFE59
dead_caron                       65114     0xFE5A
dead_cedilla                     65115     0xFE5B
dead_ogonek                      65116     0xFE5C
dead_iota                        65117     0xFE5D
dead_voiced_sound                65118     0xFE5E
dead_semivoiced_sound            65119     0xFE5F
dead_belowdot                    65120     0xFE60
dead_hook                        65121     0xFE61
dead_horn                        65122     0xFE62
dead_stroke                      65123     0xFE63
dead_abovecomma                  65124     0xFE64
dead_abovereversedcomma          65125     0xFE65
dead_doublegrave                 65126     0xFE66
dead_belowring                   65127     0xFE67
dead_belowmacron                 65128     0xFE68
dead_belowcircumflex             65129     0xFE69
dead_belowtilde                  65130     0xFE6A
dead_belowbreve                  65131     0xFE6B
dead_belowdiaeresis              65132     0xFE6C
dead_invertedbreve               65133     0xFE6D
dead_belowcomma                  65134     0xFE6E
dead_currency                    65135     0xFE6F
AccessX_Enable                   65136     0xFE70
AccessX_Feedback_Enable          65137     0xFE71
RepeatKeys_Enable                65138     0xFE72
SlowKeys_Enable                  65139     0xFE73
BounceKeys_Enable                65140     0xFE74
StickyKeys_Enable                65141     0xFE75
MouseKeys_Enable                 65142     0xFE76
MouseKeys_Accel_Enable           65143     0xFE77
Overlay1_Enable                  65144     0xFE78
Overlay2_Enable                  65145     0xFE79
AudibleBell_Enable               65146     0xFE7A
dead_a                           65152     0xFE80
dead_A                           65153     0xFE81
dead_e                           65154     0xFE82
dead_E                           65155     0xFE83
dead_i                           65156     0xFE84
dead_I                           65157     0xFE85
dead_o                           65158     0xFE86
dead_O                           65159     0xFE87
dead_u                           65160     0xFE88
dead_U                           65161     0xFE89
dead_small_schwa                 65162     0xFE8A
dead_capital_schwa               65163     0xFE8B
dead_greek                       65164     0xFE8C
dead_lowline                     65168     0xFE90
dead_aboveverticalline           65169     0xFE91
dead_belowverticalline           65170     0xFE92
dead_longsolidusoverlay          65171     0xFE93
ch                               65184     0xFEA0
Ch                               65185     0xFEA1
CH                               65186     0xFEA2
c_h                              65187     0xFEA3
C_h                              65188     0xFEA4
C_H                              65189     0xFEA5
First_Virtual_Screen             65232     0xFED0
Prev_Virtual_Screen              65233     0xFED1
Next_Virtual_Screen              65234     0xFED2
Last_Virtual_Screen              65236     0xFED4
Terminate_Server                 65237     0xFED5
Pointer_Left                     65248     0xFEE0
Pointer_Right                    65249     0xFEE1
Pointer_Up                       65250     0xFEE2
Pointer_Down                     65251     0xFEE3
Pointer_UpLeft                   65252     0xFEE4
Pointer_UpRight                  65253     0xFEE5
Pointer_DownLeft                 65254     0xFEE6
Pointer_DownRight                65255     0xFEE7
Pointer_Button_Dflt              65256     0xFEE8
Pointer_Button1                  65257     0xFEE9
Pointer_Button2                  65258     0xFEEA
Pointer_Button3                  65259     0xFEEB
Pointer_Button4                  65260     0xFEEC
Pointer_Button5                  65261     0xFEED
Pointer_DblClick_Dflt            65262     0xFEEE
Pointer_DblClick1                65263     0xFEEF
Pointer_DblClick2                65264     0xFEF0
Pointer_DblClick3                65265     0xFEF1
Pointer_DblClick4                65266     0xFEF2
Pointer_DblClick5                65267     0xFEF3
Pointer_Drag_Dflt                65268     0xFEF4
Pointer_Drag1                    65269     0xFEF5
Pointer_Drag2                    65270     0xFEF6
Pointer_Drag3                    65271     0xFEF7
Pointer_Drag4                    65272     0xFEF8
Pointer_EnableKeys               65273     0xFEF9
Pointer_Accelerate               65274     0xFEFA
Pointer_DfltBtnNext              65275     0xFEFB
Pointer_DfltBtnPrev              65276     0xFEFC
Pointer_Drag5                    65277     0xFEFD
BackSpace                        65288     0xFF08
Tab                              65289     0xFF09
Linefeed                         65290     0xFF0A
Clear                            65291     0xFF0B
Return                           65293     0xFF0D
Pause                            65299     0xFF13
Scroll_Lock                      65300     0xFF14
Sys_Req                          65301     0xFF15
Escape                           65307     0xFF1B
Multi_key                        65312     0xFF20
Kanji                            65313     0xFF21
Muhenkan                         65314     0xFF22
Henkan_Mode                      65315     0xFF23
Romaji                           65316     0xFF24
Hiragana                         65317     0xFF25
Katakana                         65318     0xFF26
Hiragana_Katakana                65319     0xFF27
Zenkaku                          65320     0xFF28
Hankaku                          65321     0xFF29
Zenkaku_Hankaku                  65322     0xFF2A
Touroku                          65323     0xFF2B
Massyo                           65324     0xFF2C
Kana_Lock                        65325     0xFF2D
Kana_Shift                       65326     0xFF2E
Eisu_Shift                       65327     0xFF2F
Eisu_toggle                      65328     0xFF30
Hangul                           65329     0xFF31
Hangul_Start                     65330     0xFF32
Hangul_End                       65331     0xFF33
Hangul_Hanja                     65332     0xFF34
Hangul_Jamo                      65333     0xFF35
Hangul_Romaja                    65334     0xFF36
Codeinput                        65335     0xFF37
Hangul_Jeonja                    65336     0xFF38
Hangul_Banja                     65337     0xFF39
Hangul_PreHanja                  65338     0xFF3A
Hangul_PostHanja                 65339     0xFF3B
SingleCandidate                  65340     0xFF3C
MultipleCandidate                65341     0xFF3D
PreviousCandidate                65342     0xFF3E
Hangul_Special                   65343     0xFF3F
Home                             65360     0xFF50
Left                             65361     0xFF51
Up                               65362     0xFF52
Right                            65363     0xFF53
Down                             65364     0xFF54
Prior                            65365     0xFF55
Next                             65366     0xFF56
End                              65367     0xFF57
Begin                            65368     0xFF58
Win_L                            65371     0xFF5B
Win_R                            65372     0xFF5C
.CE
.CS
App                              65373     0xFF5D
Select                           65376     0xFF60
Print                            65377     0xFF61
Execute                          65378     0xFF62
Insert                           65379     0xFF63
Undo                             65381     0xFF65
Redo                             65382     0xFF66
Menu                             65383     0xFF67
Find                             65384     0xFF68
Cancel                           65385     0xFF69
Help                             65386     0xFF6A
Break                            65387     0xFF6B
Mode_switch                      65406     0xFF7E
Num_Lock                         65407     0xFF7F
KP_Space                         65408     0xFF80
KP_Tab                           65417     0xFF89
KP_Enter                         65421     0xFF8D
KP_F1                            65425     0xFF91
KP_F2                            65426     0xFF92
KP_F3                            65427     0xFF93
KP_F4                            65428     0xFF94
KP_Home                          65429     0xFF95
KP_Left                          65430     0xFF96
KP_Up                            65431     0xFF97
KP_Right                         65432     0xFF98
KP_Down                          65433     0xFF99
KP_Prior                         65434     0xFF9A
KP_Next                          65435     0xFF9B
KP_End                           65436     0xFF9C
KP_Begin                         65437     0xFF9D
KP_Insert                        65438     0xFF9E
KP_Delete                        65439     0xFF9F
KP_Multiply                      65450     0xFFAA
KP_Add                           65451     0xFFAB
KP_Separator                     65452     0xFFAC
KP_Subtract                      65453     0xFFAD
KP_Decimal                       65454     0xFFAE
KP_Divide                        65455     0xFFAF
KP_0                             65456     0xFFB0
KP_1                             65457     0xFFB1
KP_2                             65458     0xFFB2
KP_3                             65459     0xFFB3
KP_4                             65460     0xFFB4
KP_5                             65461     0xFFB5
KP_6                             65462     0xFFB6
KP_7                             65463     0xFFB7
KP_8                             65464     0xFFB8
KP_9                             65465     0xFFB9
KP_Equal                         65469     0xFFBD
F1                               65470     0xFFBE
F2                               65471     0xFFBF
F3                               65472     0xFFC0
F4                               65473     0xFFC1
F5                               65474     0xFFC2
F6                               65475     0xFFC3
F7                               65476     0xFFC4
F8                               65477     0xFFC5
F9                               65478     0xFFC6
F10                              65479     0xFFC7
F11                              65480     0xFFC8
F12                              65481     0xFFC9
F13                              65482     0xFFCA
F14                              65483     0xFFCB
F15                              65484     0xFFCC
F16                              65485     0xFFCD
F17                              65486     0xFFCE
F18                              65487     0xFFCF
F19                              65488     0xFFD0
F20                              65489     0xFFD1
F21                              65490     0xFFD2
F22                              65491     0xFFD3
F23                              65492     0xFFD4
F24                              65493     0xFFD5
F25                              65494     0xFFD6
F26                              65495     0xFFD7
F27                              65496     0xFFD8
F28                              65497     0xFFD9
F29                              65498     0xFFDA
F30                              65499     0xFFDB
F31                              65500     0xFFDC
F32                              65501     0xFFDD
F33                              65502     0xFFDE
F34                              65503     0xFFDF
F35                              65504     0xFFE0
Shift_L                          65505     0xFFE1
Shift_R                          65506     0xFFE2
Control_L                        65507     0xFFE3
Control_R                        65508     0xFFE4
Caps_Lock                        65509     0xFFE5
Shift_Lock                       65510     0xFFE6
Meta_L                           65511     0xFFE7
Meta_R                           65512     0xFFE8
Alt_L                            65513     0xFFE9
Alt_R                            65514     0xFFEA
Super_L                          65515     0xFFEB
Super_R                          65516     0xFFEC
Hyper_L                          65517     0xFFED
Hyper_R                          65518     0xFFEE
braille_dot_1                    65521     0xFFF1
braille_dot_2                    65522     0xFFF2
braille_dot_3                    65523     0xFFF3
braille_dot_4                    65524     0xFFF4
braille_dot_5                    65525     0xFFF5
braille_dot_6                    65526     0xFFF6
braille_dot_7                    65527     0xFFF7
braille_dot_8                    65528     0xFFF8
braille_dot_9                    65529     0xFFF9
braille_dot_10                   65530     0xFFFA
Delete                           65535     0xFFFF
Ibreve                        16777516     0x100012C
ibreve                        16777517     0x100012D
Wcircumflex                   16777588     0x1000174
wcircumflex                   16777589     0x1000175
Ycircumflex                   16777590     0x1000176
ycircumflex                   16777591     0x1000177
SCHWA                         16777615     0x100018F
Obarred                       16777631     0x100019F
Ohorn                         16777632     0x10001A0
ohorn                         16777633     0x10001A1
Uhorn                         16777647     0x10001AF
uhorn                         16777648     0x10001B0
Zstroke                       16777653     0x10001B5
zstroke                       16777654     0x10001B6
EZH                           16777655     0x10001B7
Ocaron                        16777681     0x10001D1
ocaron                        16777682     0x10001D2
Gcaron                        16777702     0x10001E6
gcaron                        16777703     0x10001E7
schwa                         16777817     0x1000259
obarred                       16777845     0x1000275
ezh                           16777874     0x1000292
Cyrillic_GHE_bar              16778386     0x1000492
Cyrillic_ghe_bar              16778387     0x1000493
Cyrillic_ZHE_descender        16778390     0x1000496
Cyrillic_zhe_descender        16778391     0x1000497
Cyrillic_KA_descender         16778394     0x100049A
Cyrillic_ka_descender         16778395     0x100049B
Cyrillic_KA_vertstroke        16778396     0x100049C
Cyrillic_ka_vertstroke        16778397     0x100049D
Cyrillic_EN_descender         16778402     0x10004A2
Cyrillic_en_descender         16778403     0x10004A3
Cyrillic_U_straight           16778414     0x10004AE
Cyrillic_u_straight           16778415     0x10004AF
Cyrillic_U_straight_bar       16778416     0x10004B0
Cyrillic_u_straight_bar       16778417     0x10004B1
Cyrillic_HA_descender         16778418     0x10004B2
Cyrillic_ha_descender         16778419     0x10004B3
Cyrillic_CHE_descender        16778422     0x10004B6
Cyrillic_che_descender        16778423     0x10004B7
Cyrillic_CHE_vertstroke       16778424     0x10004B8
Cyrillic_che_vertstroke       16778425     0x10004B9
Cyrillic_SHHA                 16778426     0x10004BA
Cyrillic_shha                 16778427     0x10004BB
Cyrillic_SCHWA                16778456     0x10004D8
Cyrillic_schwa                16778457     0x10004D9
Cyrillic_I_macron             16778466     0x10004E2
Cyrillic_i_macron             16778467     0x10004E3
Cyrillic_O_bar                16778472     0x10004E8
Cyrillic_o_bar                16778473     0x10004E9
Cyrillic_U_macron             16778478     0x10004EE
Cyrillic_u_macron             16778479     0x10004EF
Armenian_AYB                  16778545     0x1000531
Armenian_BEN                  16778546     0x1000532
Armenian_GIM                  16778547     0x1000533
Armenian_DA                   16778548     0x1000534
Armenian_YECH                 16778549     0x1000535
Armenian_ZA                   16778550     0x1000536
Armenian_E                    16778551     0x1000537
Armenian_AT                   16778552     0x1000538
Armenian_TO                   16778553     0x1000539
Armenian_ZHE                  16778554     0x100053A
Armenian_INI                  16778555     0x100053B
Armenian_LYUN                 16778556     0x100053C
Armenian_KHE                  16778557     0x100053D
Armenian_TSA                  16778558     0x100053E
Armenian_KEN                  16778559     0x100053F
Armenian_HO                   16778560     0x1000540
Armenian_DZA                  16778561     0x1000541
Armenian_GHAT                 16778562     0x1000542
Armenian_TCHE                 16778563     0x1000543
Armenian_MEN                  16778564     0x1000544
Armenian_HI                   16778565     0x1000545
Armenian_NU                   16778566     0x1000546
Armenian_SHA                  16778567     0x1000547
Armenian_VO                   16778568     0x1000548
Armenian_CHA                  16778569     0x1000549
Armenian_PE                   16778570     0x100054A
Armenian_JE                   16778571     0x100054B
Armenian_RA                   16778572     0x100054C
Armenian_SE                   16778573     0x100054D
Armenian_VEV                  16778574     0x100054E
Armenian_TYUN                 16778575     0x100054F


Armenian_RE                   16778576     0x1000550
Armenian_TSO                  16778577     0x1000551
Armenian_VYUN                 16778578     0x1000552
Armenian_PYUR                 16778579     0x1000553
Armenian_KE                   16778580     0x1000554
Armenian_O                    16778581     0x1000555
Armenian_FE                   16778582     0x1000556
Armenian_apostrophe           16778586     0x100055A
Armenian_accent               16778587     0x100055B
Armenian_exclam               16778588     0x100055C
Armenian_separation_mark      16778589     0x100055D
Armenian_question             16778590     0x100055E
Armenian_ayb                  16778593     0x1000561
Armenian_ben                  16778594     0x1000562
Armenian_gim                  16778595     0x1000563
Armenian_da                   16778596     0x1000564
Armenian_yech                 16778597     0x1000565
Armenian_za                   16778598     0x1000566
Armenian_e                    16778599     0x1000567
Armenian_at                   16778600     0x1000568
Armenian_to                   16778601     0x1000569
Armenian_zhe                  16778602     0x100056A
Armenian_ini                  16778603     0x100056B
Armenian_lyun                 16778604     0x100056C
Armenian_khe                  16778605     0x100056D
Armenian_tsa                  16778606     0x100056E
Armenian_ken                  16778607     0x100056F
Armenian_ho                   16778608     0x1000570
Armenian_dza                  16778609     0x1000571
Armenian_ghat                 16778610     0x1000572
Armenian_tche                 16778611     0x1000573
Armenian_men                  16778612     0x1000574
Armenian_hi                   16778613     0x1000575
Armenian_nu                   16778614     0x1000576
Armenian_sha                  16778615     0x1000577
Armenian_vo                   16778616     0x1000578
Armenian_cha                  16778617     0x1000579
Armenian_pe                   16778618     0x100057A
Armenian_je                   16778619     0x100057B
Armenian_ra                   16778620     0x100057C
Armenian_se                   16778621     0x100057D
Armenian_vev                  16778622     0x100057E
Armenian_tyun                 16778623     0x100057F
Armenian_re                   16778624     0x1000580
Armenian_tso                  16778625     0x1000581
Armenian_vyun                 16778626     0x1000582
Armenian_pyur                 16778627     0x1000583
Armenian_ke                   16778628     0x1000584
Armenian_o                    16778629     0x1000585
Armenian_fe                   16778630     0x1000586
Armenian_ligature_ew          16778631     0x1000587
Armenian_full_stop            16778633     0x1000589
Armenian_hyphen               16778634     0x100058A
Arabic_madda_above            16778835     0x1000653
Arabic_hamza_above            16778836     0x1000654
Arabic_hamza_below            16778837     0x1000655
Arabic_0                      16778848     0x1000660
Arabic_1                      16778849     0x1000661
Arabic_2                      16778850     0x1000662
Arabic_3                      16778851     0x1000663
Arabic_4                      16778852     0x1000664
Arabic_5                      16778853     0x1000665
Arabic_6                      16778854     0x1000666
Arabic_7                      16778855     0x1000667
Arabic_8                      16778856     0x1000668
Arabic_9                      16778857     0x1000669
Arabic_percent                16778858     0x100066A
Arabic_superscript_alef       16778864     0x1000670
Arabic_tteh                   16778873     0x1000679
Arabic_peh                    16778878     0x100067E
Arabic_tcheh                  16778886     0x1000686
Arabic_ddal                   16778888     0x1000688
Arabic_rreh                   16778897     0x1000691
Arabic_jeh                    16778904     0x1000698
Arabic_veh                    16778916     0x10006A4
Arabic_keheh                  16778921     0x10006A9
Arabic_gaf                    16778927     0x10006AF
Arabic_noon_ghunna            16778938     0x10006BA
Arabic_heh_doachashmee        16778942     0x10006BE
Arabic_heh_goal               16778945     0x10006C1
Farsi_yeh                     16778956     0x10006CC
Arabic_yeh_baree              16778962     0x10006D2
Arabic_fullstop               16778964     0x10006D4
Farsi_0                       16778992     0x10006F0
Farsi_1                       16778993     0x10006F1
Farsi_2                       16778994     0x10006F2
Farsi_3                       16778995     0x10006F3
Farsi_4                       16778996     0x10006F4
Farsi_5                       16778997     0x10006F5
Farsi_6                       16778998     0x10006F6
Farsi_7                       16778999     0x10006F7
Farsi_8                       16779000     0x10006F8
Farsi_9                       16779001     0x10006F9
Sinh_ng                       16780674     0x1000D82
Sinh_h2                       16780675     0x1000D83
Sinh_a                        16780677     0x1000D85
Sinh_aa                       16780678     0x1000D86
Sinh_ae                       16780679     0x1000D87
Sinh_aee                      16780680     0x1000D88
Sinh_i                        16780681     0x1000D89
Sinh_ii                       16780682     0x1000D8A
Sinh_u                        16780683     0x1000D8B
Sinh_uu                       16780684     0x1000D8C
Sinh_ri                       16780685     0x1000D8D
Sinh_rii                      16780686     0x1000D8E
Sinh_lu                       16780687     0x1000D8F
Sinh_luu                      16780688     0x1000D90
Sinh_e                        16780689     0x1000D91
Sinh_ee                       16780690     0x1000D92
Sinh_ai                       16780691     0x1000D93
Sinh_o                        16780692     0x1000D94
Sinh_oo                       16780693     0x1000D95
Sinh_au                       16780694     0x1000D96
Sinh_ka                       16780698     0x1000D9A
Sinh_kha                      16780699     0x1000D9B
Sinh_ga                       16780700     0x1000D9C
Sinh_gha                      16780701     0x1000D9D
Sinh_ng2                      16780702     0x1000D9E
Sinh_nga                      16780703     0x1000D9F
Sinh_ca                       16780704     0x1000DA0
Sinh_cha                      16780705     0x1000DA1
Sinh_ja                       16780706     0x1000DA2
Sinh_jha                      16780707     0x1000DA3
Sinh_nya                      16780708     0x1000DA4
Sinh_jnya                     16780709     0x1000DA5
Sinh_nja                      16780710     0x1000DA6
Sinh_tta                      16780711     0x1000DA7
Sinh_ttha                     16780712     0x1000DA8
Sinh_dda                      16780713     0x1000DA9
Sinh_ddha                     16780714     0x1000DAA
Sinh_nna                      16780715     0x1000DAB
Sinh_ndda                     16780716     0x1000DAC
Sinh_tha                      16780717     0x1000DAD
Sinh_thha                     16780718     0x1000DAE
Sinh_dha                      16780719     0x1000DAF
Sinh_dhha                     16780720     0x1000DB0
Sinh_na                       16780721     0x1000DB1
Sinh_ndha                     16780723     0x1000DB3
Sinh_pa                       16780724     0x1000DB4
Sinh_pha                      16780725     0x1000DB5
Sinh_ba                       16780726     0x1000DB6
Sinh_bha                      16780727     0x1000DB7
Sinh_ma                       16780728     0x1000DB8
Sinh_mba                      16780729     0x1000DB9
Sinh_ya                       16780730     0x1000DBA
Sinh_ra                       16780731     0x1000DBB
Sinh_la                       16780733     0x1000DBD
Sinh_va                       16780736     0x1000DC0
Sinh_sha                      16780737     0x1000DC1
Sinh_ssha                     16780738     0x1000DC2
Sinh_sa                       16780739     0x1000DC3
Sinh_ha                       16780740     0x1000DC4
Sinh_lla                      16780741     0x1000DC5
Sinh_fa                       16780742     0x1000DC6
Sinh_al                       16780746     0x1000DCA
Sinh_aa2                      16780751     0x1000DCF
Sinh_ae2                      16780752     0x1000DD0
Sinh_aee2                     16780753     0x1000DD1
Sinh_i2                       16780754     0x1000DD2
Sinh_ii2                      16780755     0x1000DD3
Sinh_u2                       16780756     0x1000DD4
Sinh_uu2                      16780758     0x1000DD6
Sinh_ru2                      16780760     0x1000DD8
Sinh_e2                       16780761     0x1000DD9
Sinh_ee2                      16780762     0x1000DDA
Sinh_ai2                      16780763     0x1000DDB
Sinh_o2                       16780764     0x1000DDC
Sinh_oo2                      16780765     0x1000DDD
Sinh_au2                      16780766     0x1000DDE
Sinh_lu2                      16780767     0x1000DDF
Sinh_ruu2                     16780786     0x1000DF2
Sinh_luu2                     16780787     0x1000DF3
Sinh_kunddaliya               16780788     0x1000DF4
Georgian_an                   16781520     0x10010D0
Georgian_ban                  16781521     0x10010D1
Georgian_gan                  16781522     0x10010D2
Georgian_don                  16781523     0x10010D3
Georgian_en                   16781524     0x10010D4
Georgian_vin                  16781525     0x10010D5
Georgian_zen                  16781526     0x10010D6
Georgian_tan                  16781527     0x10010D7
Georgian_in                   16781528     0x10010D8
Georgian_kan                  16781529     0x10010D9
Georgian_las                  16781530     0x10010DA
Georgian_man                  16781531     0x10010DB
Georgian_nar                  16781532     0x10010DC
Georgian_on                   16781533     0x10010DD
Georgian_par                  16781534     0x10010DE
Georgian_zhar                 16781535     0x10010DF
Georgian_rae                  16781536     0x10010E0
Georgian_san                  16781537     0x10010E1
Georgian_tar                  16781538     0x10010E2
Georgian_un                   16781539     0x10010E3
Georgian_phar                 16781540     0x10010E4
Georgian_khar                 16781541     0x10010E5
Georgian_ghan                 16781542     0x10010E6
Georgian_qar                  16781543     0x10010E7
Georgian_shin                 16781544     0x10010E8
Georgian_chin                 16781545     0x10010E9
Georgian_can                  16781546     0x10010EA
Georgian_jil                  16781547     0x10010EB
Georgian_cil                  16781548     0x10010EC
Georgian_char                 16781549     0x10010ED
Georgian_xan                  16781550     0x10010EE
Georgian_jhan                 16781551     0x10010EF
Georgian_hae                  16781552     0x10010F0
Georgian_he                   16781553     0x10010F1
Georgian_hie                  16781554     0x10010F2
Georgian_we                   16781555     0x10010F3
Georgian_har                  16781556     0x10010F4
Georgian_hoe                  16781557     0x10010F5
Georgian_fi                   16781558     0x10010F6
Babovedot                     16784898     0x1001E02
babovedot                     16784899     0x1001E03
Dabovedot                     16784906     0x1001E0A
dabovedot                     16784907     0x1001E0B
Fabovedot                     16784926     0x1001E1E
fabovedot                     16784927     0x1001E1F
Lbelowdot                     16784950     0x1001E36
lbelowdot                     16784951     0x1001E37
Mabovedot                     16784960     0x1001E40
mabovedot                     16784961     0x1001E41
Pabovedot                     16784982     0x1001E56
pabovedot                     16784983     0x1001E57
Sabovedot                     16784992     0x1001E60
sabovedot                     16784993     0x1001E61
Tabovedot                     16785002     0x1001E6A
tabovedot                     16785003     0x1001E6B
Wgrave                        16785024     0x1001E80
wgrave                        16785025     0x1001E81
Wacute                        16785026     0x1001E82
wacute                        16785027     0x1001E83
Wdiaeresis                    16785028     0x1001E84
wdiaeresis                    16785029     0x1001E85
Xabovedot                     16785034     0x1001E8A
xabovedot                     16785035     0x1001E8B
Abelowdot                     16785056     0x1001EA0
abelowdot                     16785057     0x1001EA1
Ahook                         16785058     0x1001EA2
ahook                         16785059     0x1001EA3
Acircumflexacute              16785060     0x1001EA4
acircumflexacute              16785061     0x1001EA5
Acircumflexgrave              16785062     0x1001EA6
acircumflexgrave              16785063     0x1001EA7
Acircumflexhook               16785064     0x1001EA8
acircumflexhook               16785065     0x1001EA9
Acircumflextilde              16785066     0x1001EAA
acircumflextilde              16785067     0x1001EAB
Acircumflexbelowdot           16785068     0x1001EAC
acircumflexbelowdot           16785069     0x1001EAD
Abreveacute                   16785070     0x1001EAE
abreveacute                   16785071     0x1001EAF
Abrevegrave                   16785072     0x1001EB0
abrevegrave                   16785073     0x1001EB1
Abrevehook                    16785074     0x1001EB2
abrevehook                    16785075     0x1001EB3
Abrevetilde                   16785076     0x1001EB4
abrevetilde                   16785077     0x1001EB5
Abrevebelowdot                16785078     0x1001EB6
abrevebelowdot                16785079     0x1001EB7
Ebelowdot                     16785080     0x1001EB8
ebelowdot                     16785081     0x1001EB9
Ehook                         16785082     0x1001EBA
ehook                         16785083     0x1001EBB
Etilde                        16785084     0x1001EBC
etilde                        16785085     0x1001EBD
Ecircumflexacute              16785086     0x1001EBE
ecircumflexacute              16785087     0x1001EBF
Ecircumflexgrave              16785088     0x1001EC0
ecircumflexgrave              16785089     0x1001EC1
Ecircumflexhook               16785090     0x1001EC2
ecircumflexhook               16785091     0x1001EC3
Ecircumflextilde              16785092     0x1001EC4
ecircumflextilde              16785093     0x1001EC5
Ecircumflexbelowdot           16785094     0x1001EC6
ecircumflexbelowdot           16785095     0x1001EC7
Ihook                         16785096     0x1001EC8
ihook                         16785097     0x1001EC9
Ibelowdot                     16785098     0x1001ECA
ibelowdot                     16785099     0x1001ECB
Obelowdot                     16785100     0x1001ECC
obelowdot                     16785101     0x1001ECD
Ohook                         16785102     0x1001ECE
ohook                         16785103     0x1001ECF
Ocircumflexacute              16785104     0x1001ED0
ocircumflexacute              16785105     0x1001ED1
Ocircumflexgrave              16785106     0x1001ED2
ocircumflexgrave              16785107     0x1001ED3
Ocircumflexhook               16785108     0x1001ED4
ocircumflexhook               16785109     0x1001ED5
Ocircumflextilde              16785110     0x1001ED6
ocircumflextilde              16785111     0x1001ED7
Ocircumflexbelowdot           16785112     0x1001ED8
ocircumflexbelowdot           16785113     0x1001ED9
Ohornacute                    16785114     0x1001EDA
ohornacute                    16785115     0x1001EDB
Ohorngrave                    16785116     0x1001EDC
ohorngrave                    16785117     0x1001EDD
Ohornhook                     16785118     0x1001EDE
ohornhook                     16785119     0x1001EDF
Ohorntilde                    16785120     0x1001EE0
ohorntilde                    16785121     0x1001EE1
Ohornbelowdot                 16785122     0x1001EE2
ohornbelowdot                 16785123     0x1001EE3
Ubelowdot                     16785124     0x1001EE4
ubelowdot                     16785125     0x1001EE5
Uhook                         16785126     0x1001EE6
uhook                         16785127     0x1001EE7
Uhornacute                    16785128     0x1001EE8
uhornacute                    16785129     0x1001EE9
Uhorngrave                    16785130     0x1001EEA
uhorngrave                    16785131     0x1001EEB
Uhornhook                     16785132     0x1001EEC
uhornhook                     16785133     0x1001EED
Uhorntilde                    16785134     0x1001EEE
uhorntilde                    16785135     0x1001EEF
Uhornbelowdot                 16785136     0x1001EF0
uhornbelowdot                 16785137     0x1001EF1
Ygrave                        16785138     0x1001EF2
ygrave                        16785139     0x1001EF3
Ybelowdot                     16785140     0x1001EF4
ybelowdot                     16785141     0x1001EF5
Yhook                         16785142     0x1001EF6
yhook                         16785143     0x1001EF7
Ytilde                        16785144     0x1001EF8
ytilde                        16785145     0x1001EF9
zerosuperior                  16785520     0x1002070
foursuperior                  16785524     0x1002074
fivesuperior                  16785525     0x1002075
sixsuperior                   16785526     0x1002076
sevensuperior                 16785527     0x1002077
eightsuperior                 16785528     0x1002078
ninesuperior                  16785529     0x1002079
zerosubscript                 16785536     0x1002080
onesubscript                  16785537     0x1002081
twosubscript                  16785538     0x1002082
threesubscript                16785539     0x1002083
foursubscript                 16785540     0x1002084
fivesubscript                 16785541     0x1002085
sixsubscript                  16785542     0x1002086
sevensubscript                16785543     0x1002087
eightsubscript                16785544     0x1002088
ninesubscript                 16785545     0x1002089
EcuSign                       16785568     0x10020A0
ColonSign                     16785569     0x10020A1
CruzeiroSign                  16785570     0x10020A2
FFrancSign                    16785571     0x10020A3
LiraSign                      16785572     0x10020A4
MillSign                      16785573     0x10020A5
NairaSign                     16785574     0x10020A6
PesetaSign                    16785575     0x10020A7
RupeeSign                     16785576     0x10020A8
WonSign                       16785577     0x10020A9
NewSheqelSign                 16785578     0x10020AA
DongSign                      16785579     0x10020AB
partdifferential              16785922     0x1002202
emptyset                      16785925     0x1002205
elementof                     16785928     0x1002208
notelementof                  16785929     0x1002209
containsas                    16785931     0x100220B
squareroot                    16785946     0x100221A
cuberoot                      16785947     0x100221B
fourthroot                    16785948     0x100221C
dintegral                     16785964     0x100222C
tintegral                     16785965     0x100222D
because                       16785973     0x1002235
notapproxeq                   16785991     0x1002247
approxeq                      16785992     0x1002248
notidentical                  16786018     0x1002262
stricteq                      16786019     0x1002263
braille_blank                 16787456     0x1002800
braille_dots_1                16787457     0x1002801
braille_dots_2                16787458     0x1002802
braille_dots_12               16787459     0x1002803
braille_dots_3                16787460     0x1002804
braille_dots_13               16787461     0x1002805
braille_dots_23               16787462     0x1002806
braille_dots_123              16787463     0x1002807
braille_dots_4                16787464     0x1002808
braille_dots_14               16787465     0x1002809
braille_dots_24               16787466     0x100280A
braille_dots_124              16787467     0x100280B
braille_dots_34               16787468     0x100280C
braille_dots_134              16787469     0x100280D
braille_dots_234              16787470     0x100280E
braille_dots_1234             16787471     0x100280F
braille_dots_5                16787472     0x1002810
braille_dots_15               16787473     0x1002811
braille_dots_25               16787474     0x1002812
braille_dots_125              16787475     0x1002813
braille_dots_35               16787476     0x1002814
braille_dots_135              16787477     0x1002815
braille_dots_235              16787478     0x1002816
braille_dots_1235             16787479     0x1002817
braille_dots_45               16787480     0x1002818
braille_dots_145              16787481     0x1002819
braille_dots_245              16787482     0x100281A
braille_dots_1245             16787483     0x100281B
braille_dots_345              16787484     0x100281C
braille_dots_1345             16787485     0x100281D
braille_dots_2345             16787486     0x100281E
braille_dots_12345            16787487     0x100281F
braille_dots_6                16787488     0x1002820
braille_dots_16               16787489     0x1002821
braille_dots_26               16787490     0x1002822
braille_dots_126              16787491     0x1002823
braille_dots_36               16787492     0x1002824
braille_dots_136              16787493     0x1002825
braille_dots_236              16787494     0x1002826
braille_dots_1236             16787495     0x1002827
braille_dots_46               16787496     0x1002828
braille_dots_146              16787497     0x1002829
braille_dots_246              16787498     0x100282A
braille_dots_1246             16787499     0x100282B
braille_dots_346              16787500     0x100282C
braille_dots_1346             16787501     0x100282D
braille_dots_2346             16787502     0x100282E
braille_dots_12346            16787503     0x100282F
braille_dots_56               16787504     0x1002830
braille_dots_156              16787505     0x1002831
braille_dots_256              16787506     0x1002832
braille_dots_1256             16787507     0x1002833
braille_dots_356              16787508     0x1002834
braille_dots_1356             16787509     0x1002835
braille_dots_2356             16787510     0x1002836
braille_dots_12356            16787511     0x1002837
braille_dots_456              16787512     0x1002838
braille_dots_1456             16787513     0x1002839
braille_dots_2456             16787514     0x100283A
braille_dots_12456            16787515     0x100283B
braille_dots_3456             16787516     0x100283C
braille_dots_13456            16787517     0x100283D
braille_dots_23456            16787518     0x100283E
braille_dots_123456           16787519     0x100283F
braille_dots_7                16787520     0x1002840
braille_dots_17               16787521     0x1002841
braille_dots_27               16787522     0x1002842
braille_dots_127              16787523     0x1002843
braille_dots_37               16787524     0x1002844
braille_dots_137              16787525     0x1002845
braille_dots_237              16787526     0x1002846
braille_dots_1237             16787527     0x1002847
braille_dots_47               16787528     0x1002848
braille_dots_147              16787529     0x1002849
braille_dots_247              16787530     0x100284A
braille_dots_1247             16787531     0x100284B
braille_dots_347              16787532     0x100284C
braille_dots_1347             16787533     0x100284D
braille_dots_2347             16787534     0x100284E
braille_dots_12347            16787535     0x100284F
braille_dots_57               16787536     0x1002850
braille_dots_157              16787537     0x1002851
braille_dots_257              16787538     0x1002852
braille_dots_1257             16787539     0x1002853
braille_dots_357              16787540     0x1002854
braille_dots_1357             16787541     0x1002855
braille_dots_2357             16787542     0x1002856
braille_dots_12357            16787543     0x1002857
braille_dots_457              16787544     0x1002858
braille_dots_1457             16787545     0x1002859
braille_dots_2457             16787546     0x100285A
braille_dots_12457            16787547     0x100285B
braille_dots_3457             16787548     0x100285C
braille_dots_13457            16787549     0x100285D
braille_dots_23457            16787550     0x100285E
braille_dots_123457           16787551     0x100285F
braille_dots_67               16787552     0x1002860
braille_dots_167              16787553     0x1002861


braille_dots_267              16787554     0x1002862
braille_dots_1267             16787555     0x1002863
braille_dots_367              16787556     0x1002864
braille_dots_1367             16787557     0x1002865
braille_dots_2367             16787558     0x1002866
braille_dots_12367            16787559     0x1002867
braille_dots_467              16787560     0x1002868
braille_dots_1467             16787561     0x1002869
braille_dots_2467             16787562     0x100286A
braille_dots_12467            16787563     0x100286B
braille_dots_3467             16787564     0x100286C
braille_dots_13467            16787565     0x100286D
braille_dots_23467            16787566     0x100286E
braille_dots_123467           16787567     0x100286F
braille_dots_567              16787568     0x1002870
braille_dots_1567             16787569     0x1002871
braille_dots_2567             16787570     0x1002872
braille_dots_12567            16787571     0x1002873
braille_dots_3567             16787572     0x1002874
braille_dots_13567            16787573     0x1002875
braille_dots_23567            16787574     0x1002876
braille_dots_123567           16787575     0x1002877
braille_dots_4567             16787576     0x1002878
braille_dots_14567            16787577     0x1002879
braille_dots_24567            16787578     0x100287A
braille_dots_124567           16787579     0x100287B
braille_dots_34567            16787580     0x100287C
braille_dots_134567           16787581     0x100287D
braille_dots_234567           16787582     0x100287E
braille_dots_1234567          16787583     0x100287F
braille_dots_8                16787584     0x1002880
braille_dots_18               16787585     0x1002881
braille_dots_28               16787586     0x1002882
braille_dots_128              16787587     0x1002883
braille_dots_38               16787588     0x1002884
braille_dots_138              16787589     0x1002885
braille_dots_238              16787590     0x1002886
braille_dots_1238             16787591     0x1002887
braille_dots_48               16787592     0x1002888
braille_dots_148              16787593     0x1002889
braille_dots_248              16787594     0x100288A
braille_dots_1248             16787595     0x100288B
braille_dots_348              16787596     0x100288C
braille_dots_1348             16787597     0x100288D
braille_dots_2348             16787598     0x100288E
braille_dots_12348            16787599     0x100288F
braille_dots_58               16787600     0x1002890
braille_dots_158              16787601     0x1002891
braille_dots_258              16787602     0x1002892
braille_dots_1258             16787603     0x1002893
braille_dots_358              16787604     0x1002894
braille_dots_1358             16787605     0x1002895
braille_dots_2358             16787606     0x1002896
braille_dots_12358            16787607     0x1002897
braille_dots_458              16787608     0x1002898
braille_dots_1458             16787609     0x1002899
braille_dots_2458             16787610     0x100289A
braille_dots_12458            16787611     0x100289B
braille_dots_3458             16787612     0x100289C
braille_dots_13458            16787613     0x100289D
braille_dots_23458            16787614     0x100289E
braille_dots_123458           16787615     0x100289F
braille_dots_68               16787616     0x10028A0
braille_dots_168              16787617     0x10028A1
braille_dots_268              16787618     0x10028A2
braille_dots_1268             16787619     0x10028A3
braille_dots_368              16787620     0x10028A4
braille_dots_1368             16787621     0x10028A5
braille_dots_2368             16787622     0x10028A6
braille_dots_12368            16787623     0x10028A7
braille_dots_468              16787624     0x10028A8
braille_dots_1468             16787625     0x10028A9
braille_dots_2468             16787626     0x10028AA
braille_dots_12468            16787627     0x10028AB
braille_dots_3468             16787628     0x10028AC
braille_dots_13468            16787629     0x10028AD
braille_dots_23468            16787630     0x10028AE
braille_dots_123468           16787631     0x10028AF
braille_dots_568              16787632     0x10028B0
braille_dots_1568             16787633     0x10028B1
braille_dots_2568             16787634     0x10028B2
braille_dots_12568            16787635     0x10028B3
braille_dots_3568             16787636     0x10028B4
braille_dots_13568            16787637     0x10028B5
braille_dots_23568            16787638     0x10028B6
braille_dots_123568           16787639     0x10028B7
braille_dots_4568             16787640     0x10028B8
braille_dots_14568            16787641     0x10028B9
braille_dots_24568            16787642     0x10028BA
braille_dots_124568           16787643     0x10028BB
braille_dots_34568            16787644     0x10028BC
braille_dots_134568           16787645     0x10028BD
braille_dots_234568           16787646     0x10028BE
braille_dots_1234568          16787647     0x10028BF
braille_dots_78               16787648     0x10028C0
braille_dots_178              16787649     0x10028C1
braille_dots_278              16787650     0x10028C2
braille_dots_1278             16787651     0x10028C3
braille_dots_378              16787652     0x10028C4
braille_dots_1378             16787653     0x10028C5
braille_dots_2378             16787654     0x10028C6
braille_dots_12378            16787655     0x10028C7
braille_dots_478              16787656     0x10028C8
braille_dots_1478             16787657     0x10028C9
braille_dots_2478             16787658     0x10028CA
braille_dots_12478            16787659     0x10028CB
braille_dots_3478             16787660     0x10028CC
braille_dots_13478            16787661     0x10028CD
braille_dots_23478            16787662     0x10028CE
braille_dots_123478           16787663     0x10028CF
braille_dots_578              16787664     0x10028D0
braille_dots_1578             16787665     0x10028D1
braille_dots_2578             16787666     0x10028D2
braille_dots_12578            16787667     0x10028D3
braille_dots_3578             16787668     0x10028D4
braille_dots_13578            16787669     0x10028D5
braille_dots_23578            16787670     0x10028D6
braille_dots_123578           16787671     0x10028D7
braille_dots_4578             16787672     0x10028D8
braille_dots_14578            16787673     0x10028D9
braille_dots_24578            16787674     0x10028DA
braille_dots_124578           16787675     0x10028DB
braille_dots_34578            16787676     0x10028DC
braille_dots_134578           16787677     0x10028DD
braille_dots_234578           16787678     0x10028DE
braille_dots_1234578          16787679     0x10028DF
braille_dots_678              16787680     0x10028E0
braille_dots_1678             16787681     0x10028E1
braille_dots_2678             16787682     0x10028E2
braille_dots_12678            16787683     0x10028E3
braille_dots_3678             16787684     0x10028E4
braille_dots_13678            16787685     0x10028E5
braille_dots_23678            16787686     0x10028E6
braille_dots_123678           16787687     0x10028E7
braille_dots_4678             16787688     0x10028E8
braille_dots_14678            16787689     0x10028E9
braille_dots_24678            16787690     0x10028EA
braille_dots_124678           16787691     0x10028EB
braille_dots_34678            16787692     0x10028EC
braille_dots_134678           16787693     0x10028ED
braille_dots_234678           16787694     0x10028EE
braille_dots_1234678          16787695     0x10028EF
braille_dots_5678             16787696     0x10028F0
braille_dots_15678            16787697     0x10028F1
braille_dots_25678            16787698     0x10028F2
braille_dots_125678           16787699     0x10028F3
braille_dots_35678            16787700     0x10028F4
braille_dots_135678           16787701     0x10028F5
braille_dots_235678           16787702     0x10028F6
braille_dots_1235678          16787703     0x10028F7
braille_dots_45678            16787704     0x10028F8
braille_dots_145678           16787705     0x10028F9
braille_dots_245678           16787706     0x10028FA
braille_dots_1245678          16787707     0x10028FB
braille_dots_345678           16787708     0x10028FC
braille_dots_1345678          16787709     0x10028FD
braille_dots_2345678          16787710     0x10028FE
braille_dots_12345678         16787711     0x10028FF
SunFA_Grave                  268828416     0x1005FF00
SunFA_Circum                 268828417     0x1005FF01
SunFA_Tilde                  268828418     0x1005FF02
SunFA_Acute                  268828419     0x1005FF03
SunFA_Diaeresis              268828420     0x1005FF04
SunFA_Cedilla                268828421     0x1005FF05
SunF36                       268828432     0x1005FF10
SunF37                       268828433     0x1005FF11
SunSys_Req                   268828512     0x1005FF60
SunProps                     268828528     0x1005FF70
SunFront                     268828529     0x1005FF71
SunCopy                      268828530     0x1005FF72
SunOpen                      268828531     0x1005FF73
SunPaste                     268828532     0x1005FF74
SunCut                       268828533     0x1005FF75
SunPowerSwitch               268828534     0x1005FF76
SunAudioLowerVolume          268828535     0x1005FF77
SunAudioMute                 268828536     0x1005FF78
SunAudioRaiseVolume          268828537     0x1005FF79
SunVideoDegauss              268828538     0x1005FF7A
SunVideoLowerBrightness      268828539     0x1005FF7B
SunVideoRaiseBrightness      268828540     0x1005FF7C
SunPowerSwitchShift          268828541     0x1005FF7D
XF86Switch_VT_1              269024769     0x1008FE01
XF86Switch_VT_2              269024770     0x1008FE02
XF86Switch_VT_3              269024771     0x1008FE03
XF86Switch_VT_4              269024772     0x1008FE04
XF86Switch_VT_5              269024773     0x1008FE05
XF86Switch_VT_6              269024774     0x1008FE06
XF86Switch_VT_7              269024775     0x1008FE07
XF86Switch_VT_8              269024776     0x1008FE08
XF86Switch_VT_9              269024777     0x1008FE09
XF86Switch_VT_10             269024778     0x1008FE0A
XF86Switch_VT_11             269024779     0x1008FE0B
XF86Switch_VT_12             269024780     0x1008FE0C
XF86Ungrab                   269024800     0x1008FE20
XF86ClearGrab                269024801     0x1008FE21
XF86Next_VMode               269024802     0x1008FE22
XF86Prev_VMode               269024803     0x1008FE23
XF86LogWindowTree            269024804     0x1008FE24
XF86LogGrabInfo              269024805     0x1008FE25
XF86ModeLock                 269025025     0x1008FF01
XF86MonBrightnessUp          269025026     0x1008FF02
XF86MonBrightnessDown        269025027     0x1008FF03
XF86KbdLightOnOff            269025028     0x1008FF04
XF86KbdBrightnessUp          269025029     0x1008FF05
XF86KbdBrightnessDown        269025030     0x1008FF06
XF86MonBrightnessCycle       269025031     0x1008FF07
XF86Standby                  269025040     0x1008FF10
XF86AudioLowerVolume         269025041     0x1008FF11
XF86AudioMute                269025042     0x1008FF12
XF86AudioRaiseVolume         269025043     0x1008FF13
XF86AudioPlay                269025044     0x1008FF14
XF86AudioStop                269025045     0x1008FF15
XF86AudioPrev                269025046     0x1008FF16
XF86AudioNext                269025047     0x1008FF17
XF86HomePage                 269025048     0x1008FF18
XF86Mail                     269025049     0x1008FF19
XF86Start                    269025050     0x1008FF1A
XF86Search                   269025051     0x1008FF1B
XF86AudioRecord              269025052     0x1008FF1C
XF86Calculator               269025053     0x1008FF1D
XF86Memo                     269025054     0x1008FF1E
XF86ToDoList                 269025055     0x1008FF1F
XF86Calendar                 269025056     0x1008FF20
XF86PowerDown                269025057     0x1008FF21
XF86ContrastAdjust           269025058     0x1008FF22
XF86RockerUp                 269025059     0x1008FF23
XF86RockerDown               269025060     0x1008FF24
XF86RockerEnter              269025061     0x1008FF25
XF86Back                     269025062     0x1008FF26
XF86Forward                  269025063     0x1008FF27
XF86Stop                     269025064     0x1008FF28
XF86Refresh                  269025065     0x1008FF29
XF86PowerOff                 269025066     0x1008FF2A
XF86WakeUp                   269025067     0x1008FF2B
XF86Eject                    269025068     0x1008FF2C
XF86ScreenSaver              269025069     0x1008FF2D
XF86WWW                      269025070     0x1008FF2E
XF86Sleep                    269025071     0x1008FF2F
XF86Favorites                269025072     0x1008FF30
XF86AudioPause               269025073     0x1008FF31
XF86AudioMedia               269025074     0x1008FF32
XF86MyComputer               269025075     0x1008FF33
XF86VendorHome               269025076     0x1008FF34
XF86LightBulb                269025077     0x1008FF35
XF86Shop                     269025078     0x1008FF36
XF86History                  269025079     0x1008FF37
XF86OpenURL                  269025080     0x1008FF38
XF86AddFavorite              269025081     0x1008FF39
XF86HotLinks                 269025082     0x1008FF3A
XF86BrightnessAdjust         269025083     0x1008FF3B
XF86Finance                  269025084     0x1008FF3C
XF86Community                269025085     0x1008FF3D
XF86AudioRewind              269025086     0x1008FF3E
XF86BackForward              269025087     0x1008FF3F
XF86Launch0                  269025088     0x1008FF40
XF86Launch1                  269025089     0x1008FF41
XF86Launch2                  269025090     0x1008FF42
XF86Launch3                  269025091     0x1008FF43
XF86Launch4                  269025092     0x1008FF44
XF86Launch5                  269025093     0x1008FF45
XF86Launch6                  269025094     0x1008FF46
XF86Launch7                  269025095     0x1008FF47
XF86Launch8                  269025096     0x1008FF48
XF86Launch9                  269025097     0x1008FF49
XF86LaunchA                  269025098     0x1008FF4A
XF86LaunchB                  269025099     0x1008FF4B
XF86LaunchC                  269025100     0x1008FF4C
XF86LaunchD                  269025101     0x1008FF4D
XF86LaunchE                  269025102     0x1008FF4E
XF86LaunchF                  269025103     0x1008FF4F
XF86ApplicationLeft          269025104     0x1008FF50
XF86ApplicationRight         269025105     0x1008FF51
XF86Book                     269025106     0x1008FF52
XF86CD                       269025107     0x1008FF53
XF86Calculater               269025108     0x1008FF54
XF86Clear                    269025109     0x1008FF55
XF86Close                    269025110     0x1008FF56
XF86Copy                     269025111     0x1008FF57
XF86Cut                      269025112     0x1008FF58
XF86Display                  269025113     0x1008FF59
XF86DOS                      269025114     0x1008FF5A
XF86Documents                269025115     0x1008FF5B
XF86Excel                    269025116     0x1008FF5C
XF86Explorer                 269025117     0x1008FF5D
XF86Game                     269025118     0x1008FF5E
XF86Go                       269025119     0x1008FF5F
XF86iTouch                   269025120     0x1008FF60
XF86LogOff                   269025121     0x1008FF61
XF86Market                   269025122     0x1008FF62
XF86Meeting                  269025123     0x1008FF63
XF86MenuKB                   269025125     0x1008FF65
XF86MenuPB                   269025126     0x1008FF66
XF86MySites                  269025127     0x1008FF67
XF86New                      269025128     0x1008FF68
XF86News                     269025129     0x1008FF69
XF86OfficeHome               269025130     0x1008FF6A
XF86Open                     269025131     0x1008FF6B
XF86Option                   269025132     0x1008FF6C
XF86Paste                    269025133     0x1008FF6D
XF86Phone                    269025134     0x1008FF6E
XF86Q                        269025136     0x1008FF70
XF86Reply                    269025138     0x1008FF72
XF86Reload                   269025139     0x1008FF73
XF86RotateWindows            269025140     0x1008FF74
XF86RotationPB               269025141     0x1008FF75
XF86RotationKB               269025142     0x1008FF76
XF86Save                     269025143     0x1008FF77
XF86ScrollUp                 269025144     0x1008FF78
XF86ScrollDown               269025145     0x1008FF79
XF86ScrollClick              269025146     0x1008FF7A
XF86Send                     269025147     0x1008FF7B
XF86Spell                    269025148     0x1008FF7C
XF86SplitScreen              269025149     0x1008FF7D
XF86Support                  269025150     0x1008FF7E
XF86TaskPane                 269025151     0x1008FF7F
XF86Terminal                 269025152     0x1008FF80
XF86Tools                    269025153     0x1008FF81
XF86Travel                   269025154     0x1008FF82
XF86UserPB                   269025156     0x1008FF84
XF86User1KB                  269025157     0x1008FF85
XF86User2KB                  269025158     0x1008FF86
XF86Video                    269025159     0x1008FF87
XF86WheelButton              269025160     0x1008FF88
XF86Word                     269025161     0x1008FF89
XF86Xfer                     269025162     0x1008FF8A
XF86ZoomIn                   269025163     0x1008FF8B
XF86ZoomOut                  269025164     0x1008FF8C
XF86Away                     269025165     0x1008FF8D
XF86Messenger                269025166     0x1008FF8E
XF86WebCam                   269025167     0x1008FF8F
XF86MailForward              269025168     0x1008FF90
XF86Pictures                 269025169     0x1008FF91
XF86Music                    269025170     0x1008FF92
XF86Battery                  269025171     0x1008FF93
XF86Bluetooth                269025172     0x1008FF94
XF86WLAN                     269025173     0x1008FF95
XF86UWB                      269025174     0x1008FF96
XF86AudioForward             269025175     0x1008FF97
XF86AudioRepeat              269025176     0x1008FF98
XF86AudioRandomPlay          269025177     0x1008FF99
XF86Subtitle                 269025178     0x1008FF9A
XF86AudioCycleTrack          269025179     0x1008FF9B
XF86CycleAngle               269025180     0x1008FF9C
XF86FrameBack                269025181     0x1008FF9D
XF86FrameForward             269025182     0x1008FF9E
XF86Time                     269025183     0x1008FF9F
XF86Select                   269025184     0x1008FFA0
XF86View                     269025185     0x1008FFA1
XF86TopMenu                  269025186     0x1008FFA2
XF86Red                      269025187     0x1008FFA3
XF86Green                    269025188     0x1008FFA4
XF86Yellow                   269025189     0x1008FFA5
XF86Blue                     269025190     0x1008FFA6
XF86Suspend                  269025191     0x1008FFA7
XF86Hibernate                269025192     0x1008FFA8
XF86TouchpadToggle           269025193     0x1008FFA9
XF86TouchpadOn               269025200     0x1008FFB0
XF86TouchpadOff              269025201     0x1008FFB1
XF86AudioMicMute             269025202     0x1008FFB2
XF86Keyboard                 269025203     0x1008FFB3
XF86WWAN                     269025204     0x1008FFB4
XF86RFKill                   269025205     0x1008FFB5
XF86AudioPreset              269025206     0x1008FFB6
XF86RotationLockToggle       269025207     0x1008FFB7
.CE

.SH "SEE ALSO"
bind(n), event(n)

.SH KEYWORDS
bind, binding, event, keysym
'\" Local Variables:
'\" mode: nroff
'\" End:











>


|
<
|




|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
|
|
|
|
<
|
<
<
<
<
|
|
<
|
|
<
<
<
|
|
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
|
|
|
|
|
<
|
|
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
|
|
<
|
|
<
<
|
|
<
<
|
|
|
|
<
|
<
<
|
<
<
<
<
<
|
<
<
|
<
|
|
|
<
|
|
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
|
|
|
<
<
|
<
<
|
<
<
<
<
<
|
<
|
|
|
<
<
|
|
|
<
|
|
|
<
|
|
<
<
<
<
<
<
|
<
|
<
|
|
|
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
|
|
|
<
|
|
|
<
<
<
|
<
|
|
<
|
<
<
<
|
|
<
|
|
<
|
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
|
|
|
|
<
<
|
|
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
<
|
|
<
|
|
|
<
<
<
<
<
<
<
|
|
<
|
|
<
|
|
|
<
<
<
<
<
<
<
|
|
|
<
|
>
>
|
|
<
<
|
<
<
<
<
<
|
|
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
|
|
<
|
|
<
|
|
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
<
<
|
|
|
<
|
|
|
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
<
|
<
|
|
|
|
|
|
|
|
<
|
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
|
<
<
|
|
<
|
<
|
<
|
<
<
<
|
<
|
<
<
|
<
<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
|
|
<
<
<
<
|
|
|
<
|
|
<
|
|
<
<
<
|
|
<
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
|
|
|
<
|
<
|
|
<
|
|
|
|
<
<
|
<
<
|
<
<
<
|
|
|
|
<
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
|
<
|
<
|
<
|
<
|
|
|
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
<
<
|
<
|
<
|
<
|
<
|
|
|
|
<
|
<
<
<
|
|
<
|
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
|
<
<
|
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
|
<
|
<
|
|
|
|
|
<
|
<
<
<
|
<
<
<
|
|
<
<
<
|
<
|
|
|
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
|
|
|
|
<
<
<
|
|
|
|
|
<
<
<
|
|
|
|
<
|
<
|
<
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
|
|
<
<
<
<
|
|
|
|
<
<
<
|
|
|
<
<
<
|
<
<
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
<
|
|
|
<
<
<
|
|
|
|
|
|
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
|
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
|
|
|
|
|
<
<
<
<
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
|
|
|
|
|
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
|
|
|
|
<
|
|
|
|
|
|
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
>
>
|
|
<
<
|
|
|
<
<
<
<
<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
<
|
<
|
<
|
|
|
|
<
<
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
|
|
|
|
|
|
<
|
<
|
|
<
|
|
|
|
|
|
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
|
|
|
|
|
|
<
<
|
<
<
<
<
<
<
<
|
|
>
>
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
|
|
|
<
|
<
<
<
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
|
|
|
|
|
|
|
|
|
|
<
|
<
|
<
<
<
|
|
|
|
|
|
|
<
<
<
<
<
|
|
|
|
<
<
|
<
<
<
<
<
<
|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>

|
>

|
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

















42
43
44
45
46
47
48
49
50
51
52
53




















54










55
56
57
58
59
60
61
62
63
64
65
66
67








68
69
70
71

72




73
74

75
76



77
78


79




80


81
82



83
84
85
86
87

88
89
90


91
92
93











94


95

96

97
98

99
100


101
102


103
104
105
106

107


108





109


110

111
112
113

114
115


116
117





118






119
120
121


122


123





124

125
126
127


128
129
130

131
132
133

134
135






136

137

138
139
140




141







142
143
144
145
146



147
148
149

150
151
152



153

154
155

156



157
158

159
160

161








162
163
164
165



166
167

168
169
170
171
172
173
174
175
176
177
178


















179
180
181
182
183
184
185
186
187
188
189
190
191
192

193

















194
195
196

197



198
199
200
201
202


203
204
205
206




207










208
209

210
211

212
213
214







215
216

217
218

219
220
221







222
223
224

225
226
227
228
229


230





231
232
233


234
235










236
237
238

239
240
241

242
243

244
245
246

247





248






249





250
251






252


253
254







255
256
257
258
259
260
261
262
263


264
265
266

267
268
269
270

271
272
273












274
275
276

277

278

279
280
281
282
283
284
285
286

287
288
289




290
291














292

293


294
295


296
297

298

299

300



301

302


303


304
305
306
307
308
309










310
311
312
313
314
315
316
317





318
319




320
321
322

323
324

325
326



327
328



329
330
331
332











333





334





335




336

337
338
339

340

341
342

343
344
345
346


347


348



349
350
351
352

353
354
355
356
357
358
359

360
361









362
363
364

365


366

367

368

369

370
371
372

373
374









375







376
377
378



379

380

381

382

383
384
385
386

387



388
389

390


391
392
393
394















395

396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411


412




413







414
415


416

417







418
419
420
421
422
423
424
425
426
427
428
429
430
431
















432



433



434
435

436

437
438
439
440
441

442



443



444
445



446

447
448
449








450
451
452
453
454
455





456
457
458
459



460
461
462
463
464



465
466
467
468

469

470

471



472
473



















474
475
476

477
478
479




480
481
482
483



484
485
486



487


488



489
490











491
492
493
494
495
496
497
498
499
500

501
502
503



504
505
506
507
508
509





510
511
512
513
514

























515
516
517
518
519
520

521
522
523
524
525
526
527
528
529


530

531
532
533
534
535
536
537
538
539
540
541
542
543
544









545






546
547



548
549

550
551
552















553

554
555
556
557
558
559
560
561
562
563




564
565
566
567
568
569
570















571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

















587
588
589
590
591
592









593






594

595
596
597
598
599
600


601
602
603
604
605
606
607
608


















609
610
611
612
613





614
615
616
617

618
619
620
621
622
623

624
625
626
627












628
629

630
631
632
633


634
635
636






637

638

639
640
641












642
643

644

645
646
647








648







649
650
651
652
653
654
655
656
657


















658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679

680
681

682















683









684

685

686

687

688
689
690
691


692
693
694
695
696



697
698
699
700
701
702
703
704
705
706
707
708
709
710

711


















712













713

714

715
716
717
718
719
720
721
722
723
724
725







726
727
728
729
730
731
732
733
734
735
736
737










738




739
740
741
742
743
744
745
746
747
748
749










750
751




752
753














754





755
756
757
758
759
760
761
762
763
764
765



766
767
768
769
770
771
772
773

















774
775

776
777
778
779
780
781
782

783

784
785

786
787
788
789
790
791
792

793
794
795














796

797
798
799
800
801
802
803

804







805
806
807

808



809







810
811
812

813



814







815
816
817
818
819
820
821

822
823






824
825
826
827
828
829


830







831
832
833
834
835

836



837







838
839
840













841
842
843
844
845
846
847

848
849
850

851



852
853
854
855
856
857
858

859
860






861
862
863

864



865







866
867
868

869



870







871
872
873
874
875
876
877

878
879






880
881
882
883
884
885
886

887
888






889
890
891

892



893























894
895
896
897


898
899
900
901
902
903
904
905
906
907

908

909



910
911
912
913
914
915
916





917
918
919
920


921






922
923
924
925
926
927
928
929






















































































































































930
931
932
933
934
935
936



'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH keysyms n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
keysyms \- keysyms recognized by Tk
.BE

.SH DESCRIPTION
.PP
Tk recognizes many keysyms when specifying key bindings (e.g. 

\fBbind . <Key-\fR\fIkeysym\fR\fB>\fR).  The following list enumerates the
keysyms that will be recognized by Tk.  Note that not all keysyms will
be valid on all platforms, and some keysyms are also available on
platforms that have a different native name for that key.
For example, on Unix systems, the presence
of a particular keysym is dependant on the configuration of the
keyboard modifier map.  This list shows keysyms along with their
decimal and hexadecimal values.
.PP
.CS
space                               32     0x0020
exclam                              33     0x0021
quotedbl                            34     0x0022
numbersign                          35     0x0023
dollar                              36     0x0024
percent                             37     0x0025
ampersand                           38     0x0026
quoteright                          39     0x0027
parenleft                           40     0x0028
parenright                          41     0x0029
asterisk                            42     0x002a
plus                                43     0x002b
comma                               44     0x002c
minus                               45     0x002d
period                              46     0x002e
slash                               47     0x002f

















0                                   48     0x0030
1                                   49     0x0031
2                                   50     0x0032
3                                   51     0x0033
4                                   52     0x0034
5                                   53     0x0035
6                                   54     0x0036
7                                   55     0x0037
8                                   56     0x0038
9                                   57     0x0039
colon                               58     0x003a
semicolon                           59     0x003b




















less                                60     0x003c










equal                               61     0x003d
greater                             62     0x003e
question                            63     0x003f
at                                  64     0x0040
A                                   65     0x0041
B                                   66     0x0042
C                                   67     0x0043
D                                   68     0x0044
E                                   69     0x0045
F                                   70     0x0046
G                                   71     0x0047
H                                   72     0x0048
I                                   73     0x0049








J                                   74     0x004a
K                                   75     0x004b
L                                   76     0x004c
M                                   77     0x004d

N                                   78     0x004e




O                                   79     0x004f
P                                   80     0x0050

Q                                   81     0x0051
R                                   82     0x0052



S                                   83     0x0053
T                                   84     0x0054


U                                   85     0x0055




V                                   86     0x0056


W                                   87     0x0057
X                                   88     0x0058



Y                                   89     0x0059
Z                                   90     0x005a
bracketleft                         91     0x005b
backslash                           92     0x005c
bracketright                        93     0x005d

asciicircum                         94     0x005e
underscore                          95     0x005f
quoteleft                           96     0x0060


a                                   97     0x0061
b                                   98     0x0062
c                                   99     0x0063











d                                  100     0x0064


e                                  101     0x0065

f                                  102     0x0066

g                                  103     0x0067
h                                  104     0x0068

i                                  105     0x0069
j                                  106     0x006a


k                                  107     0x006b
l                                  108     0x006c


m                                  109     0x006d
n                                  110     0x006e
o                                  111     0x006f
p                                  112     0x0070

q                                  113     0x0071


r                                  114     0x0072





s                                  115     0x0073


t                                  116     0x0074

u                                  117     0x0075
v                                  118     0x0076
w                                  119     0x0077

x                                  120     0x0078
y                                  121     0x0079


z                                  122     0x007a
braceleft                          123     0x007b





bar                                124     0x007c






braceright                         125     0x007d
asciitilde                         126     0x007e
nobreakspace                       160     0x00a0


exclamdown                         161     0x00a1


cent                               162     0x00a2





sterling                           163     0x00a3

currency                           164     0x00a4
yen                                165     0x00a5
brokenbar                          166     0x00a6


section                            167     0x00a7
diaeresis                          168     0x00a8
copyright                          169     0x00a9

ordfeminine                        170     0x00aa
guillemotleft                      171     0x00ab
notsign                            172     0x00ac

hyphen                             173     0x00ad
registered                         174     0x00ae






macron                             175     0x00af

degree                             176     0x00b0

plusminus                          177     0x00b1
twosuperior                        178     0x00b2
threesuperior                      179     0x00b3




acute                              180     0x00b4







mu                                 181     0x00b5
paragraph                          182     0x00b6
periodcentered                     183     0x00b7
cedilla                            184     0x00b8
onesuperior                        185     0x00b9



masculine                          186     0x00ba
guillemotright                     187     0x00bb
onequarter                         188     0x00bc

onehalf                            189     0x00bd
threequarters                      190     0x00be
questiondown                       191     0x00bf



Agrave                             192     0x00c0

Aacute                             193     0x00c1
Acircumflex                        194     0x00c2

Atilde                             195     0x00c3



Adiaeresis                         196     0x00c4
Aring                              197     0x00c5

AE                                 198     0x00c6
Ccedilla                           199     0x00c7

Egrave                             200     0x00c8








Eacute                             201     0x00c9
Ecircumflex                        202     0x00ca
Ediaeresis                         203     0x00cb
Igrave                             204     0x00cc



Iacute                             205     0x00cd
Icircumflex                        206     0x00ce

Idiaeresis                         207     0x00cf
Eth                                208     0x00d0
Ntilde                             209     0x00d1
Ograve                             210     0x00d2
Oacute                             211     0x00d3
Ocircumflex                        212     0x00d4
Otilde                             213     0x00d5
Odiaeresis                         214     0x00d6
multiply                           215     0x00d7
Ooblique                           216     0x00d8
Ugrave                             217     0x00d9


















Uacute                             218     0x00da
Ucircumflex                        219     0x00db
Udiaeresis                         220     0x00dc
Yacute                             221     0x00dd
Thorn                              222     0x00de
ssharp                             223     0x00df
agrave                             224     0x00e0
aacute                             225     0x00e1
acircumflex                        226     0x00e2
atilde                             227     0x00e3
adiaeresis                         228     0x00e4
aring                              229     0x00e5
ae                                 230     0x00e6
ccedilla                           231     0x00e7

egrave                             232     0x00e8

















eacute                             233     0x00e9
ecircumflex                        234     0x00ea
ediaeresis                         235     0x00eb

igrave                             236     0x00ec



iacute                             237     0x00ed
icircumflex                        238     0x00ee
idiaeresis                         239     0x00ef
eth                                240     0x00f0
ntilde                             241     0x00f1


ograve                             242     0x00f2
oacute                             243     0x00f3
ocircumflex                        244     0x00f4
otilde                             245     0x00f5




odiaeresis                         246     0x00f6










division                           247     0x00f7
oslash                             248     0x00f8

ugrave                             249     0x00f9
uacute                             250     0x00fa

ucircumflex                        251     0x00fb
udiaeresis                         252     0x00fc
yacute                             253     0x00fd







thorn                              254     0x00fe
ydiaeresis                         255     0x00ff

Aogonek                            417     0x01a1
breve                              418     0x01a2

Lstroke                            419     0x01a3
Lcaron                             421     0x01a5
Sacute                             422     0x01a6







Scaron                             425     0x01a9
Scedilla                           426     0x01aa
Tcaron                             427     0x01ab

Zacute                             428     0x01ac
.CE
.CS
Zcaron                             430     0x01ae
Zabovedot                          431     0x01af


aogonek                            433     0x01b1





ogonek                             434     0x01b2
lstroke                            435     0x01b3
lcaron                             437     0x01b5


sacute                             438     0x01b6
caron                              439     0x01b7










scaron                             441     0x01b9
scedilla                           442     0x01ba
tcaron                             443     0x01bb

zacute                             444     0x01bc
doubleacute                        445     0x01bd
zcaron                             446     0x01be

zabovedot                          447     0x01bf
Racute                             448     0x01c0

Abreve                             451     0x01c3
Cacute                             454     0x01c6
Ccaron                             456     0x01c8

Eogonek                            458     0x01ca





Ecaron                             460     0x01cc






Dcaron                             463     0x01cf





Nacute                             465     0x01d1
Ncaron                             466     0x01d2






Odoubleacute                       469     0x01d5


Rcaron                             472     0x01d8
Uring                              473     0x01d9







Udoubleacute                       475     0x01db
Tcedilla                           478     0x01de
racute                             480     0x01e0
abreve                             483     0x01e3
cacute                             486     0x01e6
ccaron                             488     0x01e8
eogonek                            490     0x01ea
ecaron                             492     0x01ec
dcaron                             495     0x01ef


nacute                             497     0x01f1
ncaron                             498     0x01f2
odoubleacute                       501     0x01f5

rcaron                             504     0x01f8
uring                              505     0x01f9
udoubleacute                       507     0x01fb
tcedilla                           510     0x01fe

abovedot                           511     0x01ff
Hstroke                            673     0x02a1
Hcircumflex                        678     0x02a6












Iabovedot                          681     0x02a9
Gbreve                             683     0x02ab
Jcircumflex                        684     0x02ac

hstroke                            689     0x02b1

hcircumflex                        694     0x02b6

idotless                           697     0x02b9
gbreve                             699     0x02bb
jcircumflex                        700     0x02bc
Cabovedot                          709     0x02c5
Ccircumflex                        710     0x02c6
Gabovedot                          725     0x02d5
Gcircumflex                        728     0x02d8
Ubreve                             733     0x02dd

Scircumflex                        734     0x02de
cabovedot                          741     0x02e5
ccircumflex                        742     0x02e6




gabovedot                          757     0x02f5
gcircumflex                        760     0x02f8














ubreve                             765     0x02fd

scircumflex                        766     0x02fe


kappa                              930     0x03a2
Rcedilla                           931     0x03a3


Itilde                             933     0x03a5
Lcedilla                           934     0x03a6

Emacron                            938     0x03aa

Gcedilla                           939     0x03ab

Tslash                             940     0x03ac



rcedilla                           947     0x03b3

itilde                             949     0x03b5


lcedilla                           950     0x03b6


emacron                            954     0x03ba
gacute                             955     0x03bb
tslash                             956     0x03bc
ENG                                957     0x03bd
eng                                959     0x03bf
Amacron                            960     0x03c0










Iogonek                            967     0x03c7
Eabovedot                          972     0x03cc
Imacron                            975     0x03cf
Ncedilla                           977     0x03d1
Omacron                            978     0x03d2
Kcedilla                           979     0x03d3
Uogonek                            985     0x03d9
Utilde                             989     0x03dd





Umacron                            990     0x03de
amacron                            992     0x03e0




iogonek                            999     0x03e7
eabovedot                         1004     0x03ec
imacron                           1007     0x03ef

ncedilla                          1009     0x03f1
omacron                           1010     0x03f2

kcedilla                          1011     0x03f3
uogonek                           1017     0x03f9



utilde                            1021     0x03fd
umacron                           1022     0x03fe



overline                          1150     0x047e
kana_fullstop                     1185     0x04a1
kana_openingbracket               1186     0x04a2
kana_closingbracket               1187     0x04a3











kana_comma                        1188     0x04a4





kana_middledot                    1189     0x04a5





kana_WO                           1190     0x04a6




kana_a                            1191     0x04a7

kana_i                            1192     0x04a8
kana_u                            1193     0x04a9
kana_e                            1194     0x04aa

kana_o                            1195     0x04ab

kana_ya                           1196     0x04ac
kana_yu                           1197     0x04ad

kana_yo                           1198     0x04ae
kana_tu                           1199     0x04af
prolongedsound                    1200     0x04b0
kana_A                            1201     0x04b1


kana_I                            1202     0x04b2


kana_U                            1203     0x04b3



kana_E                            1204     0x04b4
kana_O                            1205     0x04b5
kana_KA                           1206     0x04b6
kana_KI                           1207     0x04b7

kana_KU                           1208     0x04b8
kana_KE                           1209     0x04b9
kana_KO                           1210     0x04ba
kana_SA                           1211     0x04bb
kana_SHI                          1212     0x04bc
kana_SU                           1213     0x04bd
kana_SE                           1214     0x04be

kana_SO                           1215     0x04bf
kana_TA                           1216     0x04c0









kana_TI                           1217     0x04c1
kana_TU                           1218     0x04c2
kana_TE                           1219     0x04c3

kana_TO                           1220     0x04c4


kana_NA                           1221     0x04c5

kana_NI                           1222     0x04c6

kana_NU                           1223     0x04c7

kana_NE                           1224     0x04c8

kana_NO                           1225     0x04c9
kana_HA                           1226     0x04ca
kana_HI                           1227     0x04cb

kana_HU                           1228     0x04cc
kana_HE                           1229     0x04cd









kana_HO                           1230     0x04ce







kana_MA                           1231     0x04cf
kana_MI                           1232     0x04d0
kana_MU                           1233     0x04d1



kana_ME                           1234     0x04d2

kana_MO                           1235     0x04d3

kana_YA                           1236     0x04d4

kana_YU                           1237     0x04d5

kana_YO                           1238     0x04d6
kana_RA                           1239     0x04d7
kana_RI                           1240     0x04d8
kana_RU                           1241     0x04d9

kana_RE                           1242     0x04da



kana_RO                           1243     0x04db
kana_WA                           1244     0x04dc

kana_N                            1245     0x04dd


voicedsound                       1246     0x04de
semivoicedsound                   1247     0x04df
Arabic_comma                      1452     0x05ac
Arabic_semicolon                  1467     0x05bb















Arabic_question_mark              1471     0x05bf

Arabic_hamza                      1473     0x05c1
Arabic_maddaonalef                1474     0x05c2
Arabic_hamzaonalef                1475     0x05c3
Arabic_hamzaonwaw                 1476     0x05c4
Arabic_hamzaunderalef             1477     0x05c5
Arabic_hamzaonyeh                 1478     0x05c6
Arabic_alef                       1479     0x05c7

Arabic_beh                        1480     0x05c8
Arabic_tehmarbuta                 1481     0x05c9
Arabic_teh                        1482     0x05ca
Arabic_theh                       1483     0x05cb
Arabic_jeem                       1484     0x05cc
Arabic_hah                        1485     0x05cd
Arabic_khah                       1486     0x05ce
Arabic_dal                        1487     0x05cf
Arabic_thal                       1488     0x05d0


Arabic_ra                         1489     0x05d1




Arabic_zain                       1490     0x05d2







Arabic_seen                       1491     0x05d3
Arabic_sheen                      1492     0x05d4


Arabic_sad                        1493     0x05d5

Arabic_dad                        1494     0x05d6







Arabic_tah                        1495     0x05d7
Arabic_zah                        1496     0x05d8
Arabic_ain                        1497     0x05d9
Arabic_ghain                      1498     0x05da
Arabic_tatweel                    1504     0x05e0
Arabic_feh                        1505     0x05e1
Arabic_qaf                        1506     0x05e2
Arabic_kaf                        1507     0x05e3
Arabic_lam                        1508     0x05e4
Arabic_meem                       1509     0x05e5
.CE
.CS
Arabic_noon                       1510     0x05e6
Arabic_heh                        1511     0x05e7
















Arabic_waw                        1512     0x05e8



Arabic_alefmaksura                1513     0x05e9



Arabic_yeh                        1514     0x05ea
Arabic_fathatan                   1515     0x05eb

Arabic_dammatan                   1516     0x05ec

Arabic_kasratan                   1517     0x05ed
Arabic_fatha                      1518     0x05ee
Arabic_damma                      1519     0x05ef
Arabic_kasra                      1520     0x05f0
Arabic_shadda                     1521     0x05f1

Arabic_sukun                      1522     0x05f2



Serbian_dje                       1697     0x06a1



Macedonia_gje                     1698     0x06a2
Cyrillic_io                       1699     0x06a3



Ukranian_je                       1700     0x06a4

Macedonia_dse                     1701     0x06a5
Ukranian_i                        1702     0x06a6
Ukranian_yi                       1703     0x06a7








Serbian_je                        1704     0x06a8
Serbian_lje                       1705     0x06a9
Serbian_nje                       1706     0x06aa
Serbian_tshe                      1707     0x06ab
Macedonia_kje                     1708     0x06ac
Byelorussian_shortu               1710     0x06ae





Serbian_dze                       1711     0x06af
numerosign                        1712     0x06b0
Serbian_DJE                       1713     0x06b1
Macedonia_GJE                     1714     0x06b2



Cyrillic_IO                       1715     0x06b3
Ukranian_JE                       1716     0x06b4
Macedonia_DSE                     1717     0x06b5
Ukranian_I                        1718     0x06b6
Ukranian_YI                       1719     0x06b7



Serbian_JE                        1720     0x06b8
Serbian_LJE                       1721     0x06b9
Serbian_NJE                       1722     0x06ba
Serbian_TSHE                      1723     0x06bb

Macedonia_KJE                     1724     0x06bc

Byelorussian_SHORTU               1726     0x06be

Serbian_DZE                       1727     0x06bf



Cyrillic_yu                       1728     0x06c0
Cyrillic_a                        1729     0x06c1



















Cyrillic_be                       1730     0x06c2
Cyrillic_tse                      1731     0x06c3
Cyrillic_de                       1732     0x06c4

Cyrillic_ie                       1733     0x06c5
Cyrillic_ef                       1734     0x06c6
Cyrillic_ghe                      1735     0x06c7




Cyrillic_ha                       1736     0x06c8
Cyrillic_i                        1737     0x06c9
Cyrillic_shorti                   1738     0x06ca
Cyrillic_ka                       1739     0x06cb



Cyrillic_el                       1740     0x06cc
Cyrillic_em                       1741     0x06cd
Cyrillic_en                       1742     0x06ce



Cyrillic_o                        1743     0x06cf


Cyrillic_pe                       1744     0x06d0



Cyrillic_ya                       1745     0x06d1
Cyrillic_er                       1746     0x06d2











Cyrillic_es                       1747     0x06d3
Cyrillic_te                       1748     0x06d4
Cyrillic_u                        1749     0x06d5
Cyrillic_zhe                      1750     0x06d6
Cyrillic_ve                       1751     0x06d7
Cyrillic_softsign                 1752     0x06d8
Cyrillic_yeru                     1753     0x06d9
Cyrillic_ze                       1754     0x06da
Cyrillic_sha                      1755     0x06db
Cyrillic_e                        1756     0x06dc

Cyrillic_shcha                    1757     0x06dd
Cyrillic_che                      1758     0x06de
Cyrillic_hardsign                 1759     0x06df



Cyrillic_YU                       1760     0x06e0
Cyrillic_A                        1761     0x06e1
Cyrillic_BE                       1762     0x06e2
Cyrillic_TSE                      1763     0x06e3
Cyrillic_DE                       1764     0x06e4
Cyrillic_IE                       1765     0x06e5





Cyrillic_EF                       1766     0x06e6
Cyrillic_GHE                      1767     0x06e7
Cyrillic_HA                       1768     0x06e8
Cyrillic_I                        1769     0x06e9
Cyrillic_SHORTI                   1770     0x06ea

























Cyrillic_KA                       1771     0x06eb
Cyrillic_EL                       1772     0x06ec
Cyrillic_EM                       1773     0x06ed
Cyrillic_EN                       1774     0x06ee
Cyrillic_O                        1775     0x06ef
Cyrillic_PE                       1776     0x06f0

Cyrillic_YA                       1777     0x06f1
Cyrillic_ER                       1778     0x06f2
Cyrillic_ES                       1779     0x06f3
Cyrillic_TE                       1780     0x06f4
Cyrillic_U                        1781     0x06f5
Cyrillic_ZHE                      1782     0x06f6
Cyrillic_VE                       1783     0x06f7
Cyrillic_SOFTSIGN                 1784     0x06f8
Cyrillic_YERU                     1785     0x06f9


Cyrillic_ZE                       1786     0x06fa

Cyrillic_SHA                      1787     0x06fb
Cyrillic_E                        1788     0x06fc
Cyrillic_SHCHA                    1789     0x06fd
Cyrillic_CHE                      1790     0x06fe
Cyrillic_HARDSIGN                 1791     0x06ff
Greek_ALPHAaccent                 1953     0x07a1
Greek_EPSILONaccent               1954     0x07a2
Greek_ETAaccent                   1955     0x07a3
Greek_IOTAaccent                  1956     0x07a4
Greek_IOTAdiaeresis               1957     0x07a5
Greek_IOTAaccentdiaeresis         1958     0x07a6
Greek_OMICRONaccent               1959     0x07a7
Greek_UPSILONaccent               1960     0x07a8
Greek_UPSILONdieresis             1961     0x07a9









Greek_UPSILONaccentdieresis       1962     0x07aa






Greek_OMEGAaccent                 1963     0x07ab
Greek_alphaaccent                 1969     0x07b1



Greek_epsilonaccent               1970     0x07b2
Greek_etaaccent                   1971     0x07b3

Greek_iotaaccent                  1972     0x07b4
Greek_iotadieresis                1973     0x07b5
Greek_iotaaccentdieresis          1974     0x07b6















Greek_omicronaccent               1975     0x07b7

Greek_upsilonaccent               1976     0x07b8
Greek_upsilondieresis             1977     0x07b9
Greek_upsilonaccentdieresis       1978     0x07ba
Greek_omegaaccent                 1979     0x07bb
Greek_ALPHA                       1985     0x07c1
Greek_BETA                        1986     0x07c2
Greek_GAMMA                       1987     0x07c3
Greek_DELTA                       1988     0x07c4
Greek_EPSILON                     1989     0x07c5
Greek_ZETA                        1990     0x07c6




Greek_ETA                         1991     0x07c7
Greek_THETA                       1992     0x07c8
Greek_IOTA                        1993     0x07c9
Greek_KAPPA                       1994     0x07ca
Greek_LAMBDA                      1995     0x07cb
Greek_MU                          1996     0x07cc
Greek_NU                          1997     0x07cd















Greek_XI                          1998     0x07ce
Greek_OMICRON                     1999     0x07cf
Greek_PI                          2000     0x07d0
Greek_RHO                         2001     0x07d1
Greek_SIGMA                       2002     0x07d2
Greek_TAU                         2004     0x07d4
Greek_UPSILON                     2005     0x07d5
Greek_PHI                         2006     0x07d6
Greek_CHI                         2007     0x07d7
Greek_PSI                         2008     0x07d8
Greek_OMEGA                       2009     0x07d9
Greek_alpha                       2017     0x07e1
Greek_beta                        2018     0x07e2
Greek_gamma                       2019     0x07e3
Greek_delta                       2020     0x07e4
Greek_epsilon                     2021     0x07e5

















Greek_zeta                        2022     0x07e6
Greek_eta                         2023     0x07e7
Greek_theta                       2024     0x07e8
Greek_iota                        2025     0x07e9
Greek_kappa                       2026     0x07ea
Greek_lambda                      2027     0x07eb









Greek_mu                          2028     0x07ec






Greek_nu                          2029     0x07ed

Greek_xi                          2030     0x07ee
Greek_omicron                     2031     0x07ef
Greek_pi                          2032     0x07f0
Greek_rho                         2033     0x07f1
Greek_sigma                       2034     0x07f2
Greek_finalsmallsigma             2035     0x07f3


Greek_tau                         2036     0x07f4
Greek_upsilon                     2037     0x07f5
Greek_phi                         2038     0x07f6
Greek_chi                         2039     0x07f7
Greek_psi                         2040     0x07f8
Greek_omega                       2041     0x07f9
leftradical                       2209     0x08a1
topleftradical                    2210     0x08a2


















horizconnector                    2211     0x08a3
topintegral                       2212     0x08a4
botintegral                       2213     0x08a5
vertconnector                     2214     0x08a6
topleftsqbracket                  2215     0x08a7





botleftsqbracket                  2216     0x08a8
toprightsqbracket                 2217     0x08a9
botrightsqbracket                 2218     0x08aa
topleftparens                     2219     0x08ab

botleftparens                     2220     0x08ac
toprightparens                    2221     0x08ad
botrightparens                    2222     0x08ae
leftmiddlecurlybrace              2223     0x08af
rightmiddlecurlybrace             2224     0x08b0
topleftsummation                  2225     0x08b1

botleftsummation                  2226     0x08b2
topvertsummationconnector         2227     0x08b3
botvertsummationconnector         2228     0x08b4
toprightsummation                 2229     0x08b5












botrightsummation                 2230     0x08b6
rightmiddlesummation              2231     0x08b7

.CE
.CS
lessthanequal                     2236     0x08bc
notequal                          2237     0x08bd


greaterthanequal                  2238     0x08be
integral                          2239     0x08bf
therefore                         2240     0x08c0






variation                         2241     0x08c1

infinity                          2242     0x08c2

nabla                             2245     0x08c5
approximate                       2248     0x08c8
similarequal                      2249     0x08c9












ifonlyif                          2253     0x08cd
implies                           2254     0x08ce

identical                         2255     0x08cf

radical                           2262     0x08d6
includedin                        2266     0x08da
includes                          2267     0x08db








intersection                      2268     0x08dc







union                             2269     0x08dd
logicaland                        2270     0x08de
logicalor                         2271     0x08df
partialderivative                 2287     0x08ef
function                          2294     0x08f6
leftarrow                         2299     0x08fb
uparrow                           2300     0x08fc
rightarrow                        2301     0x08fd
downarrow                         2302     0x08fe


















blank                             2527     0x09df
soliddiamond                      2528     0x09e0
checkerboard                      2529     0x09e1
ht                                2530     0x09e2
ff                                2531     0x09e3
cr                                2532     0x09e4
lf                                2533     0x09e5
nl                                2536     0x09e8
vt                                2537     0x09e9
lowrightcorner                    2538     0x09ea
uprightcorner                     2539     0x09eb
upleftcorner                      2540     0x09ec
lowleftcorner                     2541     0x09ed
crossinglines                     2542     0x09ee
horizlinescan1                    2543     0x09ef
horizlinescan3                    2544     0x09f0
horizlinescan5                    2545     0x09f1
horizlinescan7                    2546     0x09f2
horizlinescan9                    2547     0x09f3
leftt                             2548     0x09f4
rightt                            2549     0x09f5

bott                              2550     0x09f6

topt                              2551     0x09f7
vertbar                           2552     0x09f8

emspace                           2721     0x0aa1















enspace                           2722     0x0aa2









em3space                          2723     0x0aa3

em4space                          2724     0x0aa4

digitspace                        2725     0x0aa5

punctspace                        2726     0x0aa6

thinspace                         2727     0x0aa7
hairspace                         2728     0x0aa8
emdash                            2729     0x0aa9
endash                            2730     0x0aaa


signifblank                       2732     0x0aac
ellipsis                          2734     0x0aae
doubbaselinedot                   2735     0x0aaf
onethird                          2736     0x0ab0
twothirds                         2737     0x0ab1



onefifth                          2738     0x0ab2
twofifths                         2739     0x0ab3
threefifths                       2740     0x0ab4
fourfifths                        2741     0x0ab5
onesixth                          2742     0x0ab6
fivesixths                        2743     0x0ab7
careof                            2744     0x0ab8
figdash                           2747     0x0abb
leftanglebracket                  2748     0x0abc
decimalpoint                      2749     0x0abd
rightanglebracket                 2750     0x0abe
marker                            2751     0x0abf
oneeighth                         2755     0x0ac3
threeeighths                      2756     0x0ac4

fiveeighths                       2757     0x0ac5


















seveneighths                      2758     0x0ac6













trademark                         2761     0x0ac9

signaturemark                     2762     0x0aca

trademarkincircle                 2763     0x0acb
leftopentriangle                  2764     0x0acc
rightopentriangle                 2765     0x0acd
emopencircle                      2766     0x0ace
emopenrectangle                   2767     0x0acf
leftsinglequotemark               2768     0x0ad0
rightsinglequotemark              2769     0x0ad1
leftdoublequotemark               2770     0x0ad2
rightdoublequotemark              2771     0x0ad3
prescription                      2772     0x0ad4
minutes                           2774     0x0ad6







seconds                           2775     0x0ad7
latincross                        2777     0x0ad9
hexagram                          2778     0x0ada
filledrectbullet                  2779     0x0adb
filledlefttribullet               2780     0x0adc
filledrighttribullet              2781     0x0add
emfilledcircle                    2782     0x0ade
emfilledrect                      2783     0x0adf
enopencircbullet                  2784     0x0ae0
enopensquarebullet                2785     0x0ae1
openrectbullet                    2786     0x0ae2
opentribulletup                   2787     0x0ae3










opentribulletdown                 2788     0x0ae4




openstar                          2789     0x0ae5
enfilledcircbullet                2790     0x0ae6
enfilledsqbullet                  2791     0x0ae7
filledtribulletup                 2792     0x0ae8
filledtribulletdown               2793     0x0ae9
leftpointer                       2794     0x0aea
rightpointer                      2795     0x0aeb
club                              2796     0x0aec
diamond                           2797     0x0aed
heart                             2798     0x0aee
maltesecross                      2800     0x0af0










dagger                            2801     0x0af1
doubledagger                      2802     0x0af2




checkmark                         2803     0x0af3
ballotcross                       2804     0x0af4














musicalsharp                      2805     0x0af5





musicalflat                       2806     0x0af6
malesymbol                        2807     0x0af7
femalesymbol                      2808     0x0af8
telephone                         2809     0x0af9
telephonerecorder                 2810     0x0afa
phonographcopyright               2811     0x0afb
caret                             2812     0x0afc
singlelowquotemark                2813     0x0afd
doublelowquotemark                2814     0x0afe
cursor                            2815     0x0aff
leftcaret                         2979     0x0ba3



rightcaret                        2982     0x0ba6
downcaret                         2984     0x0ba8
upcaret                           2985     0x0ba9
overbar                           3008     0x0bc0
downtack                          3010     0x0bc2
upshoe                            3011     0x0bc3
downstile                         3012     0x0bc4
underbar                          3014     0x0bc6

















jot                               3018     0x0bca
quad                              3020     0x0bcc

uptack                            3022     0x0bce
circle                            3023     0x0bcf
upstile                           3027     0x0bd3
downshoe                          3030     0x0bd6
rightshoe                         3032     0x0bd8
leftshoe                          3034     0x0bda
lefttack                          3036     0x0bdc

righttack                         3068     0x0bfc

hebrew_aleph                      3296     0x0ce0
hebrew_beth                       3297     0x0ce1

hebrew_gimmel                     3298     0x0ce2
hebrew_daleth                     3299     0x0ce3
hebrew_he                         3300     0x0ce4
hebrew_waw                        3301     0x0ce5
hebrew_zayin                      3302     0x0ce6
hebrew_het                        3303     0x0ce7
hebrew_teth                       3304     0x0ce8

hebrew_yod                        3305     0x0ce9
hebrew_finalkaph                  3306     0x0cea
hebrew_kaph                       3307     0x0ceb














hebrew_lamed                      3308     0x0cec

hebrew_finalmem                   3309     0x0ced
hebrew_mem                        3310     0x0cee
hebrew_finalnun                   3311     0x0cef
hebrew_nun                        3312     0x0cf0
hebrew_samekh                     3313     0x0cf1
hebrew_ayin                       3314     0x0cf2
hebrew_finalpe                    3315     0x0cf3

hebrew_pe                         3316     0x0cf4







hebrew_finalzadi                  3317     0x0cf5
hebrew_zadi                       3318     0x0cf6
hebrew_kuf                        3319     0x0cf7

hebrew_resh                       3320     0x0cf8



hebrew_shin                       3321     0x0cf9







hebrew_taf                        3322     0x0cfa
BackSpace                        65288     0xff08
Tab                              65289     0xff09

Linefeed                         65290     0xff0a



Clear                            65291     0xff0b







Return                           65293     0xff0d
Pause                            65299     0xff13
Scroll_Lock                      65300     0xff14
Sys_Req                          65301     0xff15
Escape                           65307     0xff1b
Multi_key                        65312     0xff20
Kanji                            65313     0xff21

Home                             65360     0xff50
Left                             65361     0xff51






Up                               65362     0xff52
Right                            65363     0xff53
Down                             65364     0xff54
Prior                            65365     0xff55
Next                             65366     0xff56
End                              65367     0xff57


Begin                            65368     0xff58







Win_L                            65371     0xff5b
Win_R                            65372     0xff5c
.CE
.CS
App                              65373     0xff5d

Select                           65376     0xff60



Print                            65377     0xff61







Execute                          65378     0xff62
Insert                           65379     0xff63
Undo                             65381     0xff65













Redo                             65382     0xff66
Menu                             65383     0xff67
Find                             65384     0xff68
Cancel                           65385     0xff69
Help                             65386     0xff6a
Break                            65387     0xff6b
Hebrew_switch                    65406     0xff7e

Num_Lock                         65407     0xff7f
KP_Space                         65408     0xff80
KP_Tab                           65417     0xff89

KP_Enter                         65421     0xff8d



KP_F1                            65425     0xff91
KP_F2                            65426     0xff92
KP_F3                            65427     0xff93
KP_F4                            65428     0xff94
KP_Multiply                      65450     0xffaa
KP_Add                           65451     0xffab
KP_Separator                     65452     0xffac

KP_Subtract                      65453     0xffad
KP_Decimal                       65454     0xffae






KP_Divide                        65455     0xffaf
KP_0                             65456     0xffb0
KP_1                             65457     0xffb1

KP_2                             65458     0xffb2



KP_3                             65459     0xffb3







KP_4                             65460     0xffb4
KP_5                             65461     0xffb5
KP_6                             65462     0xffb6

KP_7                             65463     0xffb7



KP_8                             65464     0xffb8







KP_9                             65465     0xffb9
KP_Equal                         65469     0xffbd
F1                               65470     0xffbe
F2                               65471     0xffbf
F3                               65472     0xffc0
F4                               65473     0xffc1
F5                               65474     0xffc2

F6                               65475     0xffc3
F7                               65476     0xffc4






F8                               65477     0xffc5
F9                               65478     0xffc6
F10                              65479     0xffc7
L1                               65480     0xffc8
L2                               65481     0xffc9
L3                               65482     0xffca
L4                               65483     0xffcb

L5                               65484     0xffcc
L6                               65485     0xffcd






L7                               65486     0xffce
L8                               65487     0xffcf
L9                               65488     0xffd0

L10                              65489     0xffd1



R1                               65490     0xffd2























R2                               65491     0xffd3
R3                               65492     0xffd4
R4                               65493     0xffd5
R5                               65494     0xffd6


R6                               65495     0xffd7
R7                               65496     0xffd8
R8                               65497     0xffd9
R9                               65498     0xffda
R10                              65499     0xffdb
R11                              65500     0xffdc
R12                              65501     0xffdd
F33                              65502     0xffde
R14                              65503     0xffdf
R15                              65504     0xffe0

Shift_L                          65505     0xffe1

Shift_R                          65506     0xffe2



Control_L                        65507     0xffe3
Control_R                        65508     0xffe4
Caps_Lock                        65509     0xffe5
Shift_Lock                       65510     0xffe6
Meta_L                           65511     0xffe7
Meta_R                           65512     0xffe8
Alt_L                            65513     0xffe9





Alt_R                            65514     0xffea
Super_L                          65515     0xffeb
Super_R                          65516     0xffec
Hyper_L                          65517     0xffed


Hyper_R                          65518     0xffee






Delete                           65535     0xffff
XF86AudioLowerVolume         269025041     0x1008FF11
XF86AudioMute                269025042     0x1008FF12
XF86AudioRaiseVolume         269025043     0x1008FF13
XF86AudioPlay                269025044     0x1008FF14
XF86AudioStop                269025045     0x1008FF15
XF86AudioPrev                269025046     0x1008FF16
XF86AudioNext                269025047     0x1008FF17






















































































































































.CE

.SH "SEE ALSO"
bind

.SH KEYWORDS
keysym, bind, binding



Changes to doc/label.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH label n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
label \- Create and manipulate 'label' non-interactive text or image widgets
.SH SYNOPSIS
\fBlabel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH label n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
label \- Create and manipulate label widgets
.SH SYNOPSIS
\fBlabel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the label's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-state state State
Specifies one of three states for the label:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the button is displayed using the
\fB\-foreground\fR and \fB\-background\fR options.  In active state
the label is displayed using the \fB\-activeforeground\fR and
\fB\-activebackground\fR options.  In the disabled state the
\fB\-disabledforeground\fR and \fB\-background\fR options determine how
the button is displayed.
.OP \-width width Width
Specifies a desired width for the label.
If an image or bitmap is being displayed in the label then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in characters.
If this option is not specified, the label's desired width is computed







|
|
|
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the label's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-state state State
Specifies one of three states for the label:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the button is displayed using the
\fBforeground\fR and \fBbackground\fR options.  In active state
the label is displayed using the \fBactiveForeground\fR and
\fBactiveBackground\fR options.  In the disabled state the
\fBdisabledForeground\fR and \fBbackground\fR options determine how
the button is displayed.
.OP \-width width Width
Specifies a desired width for the label.
If an image or bitmap is being displayed in the label then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in characters.
If this option is not specified, the label's desired width is computed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A label is a widget that displays a textual string, bitmap or image.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fB\-wraplength\fR option) and
one of the characters may optionally be underlined using the
\fB\-underline\fR option.
The label can be manipulated in a few simple ways, such as
changing its relief or text, using the commands described below.
.SH "WIDGET COMMAND"
.PP
The \fBlabel\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given







|

|









|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A label is a widget that displays a textual string, bitmap or image.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fBwrapLength\fR option) and
one of the characters may optionally be underlined using the
\fBunderline\fR option.
The label can be manipulated in a few simple ways, such as
changing its relief or text, using the commands described below.
.SH "WIDGET COMMAND"
.PP
The \fBlabel\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.
.SH BINDINGS
.PP
When a new label is created, it has no default event bindings:
labels are not intended to be interactive.
.SH EXAMPLE
.PP
.CS
# Make the widgets
\fBlabel\fR .t \-text "This widget is at the top"    \-bg red
\fBlabel\fR .b \-text "This widget is at the bottom" \-bg green
\fBlabel\fR .l \-text "Left\enHand\enSide"
\fBlabel\fR .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
pack .t   \-side top    \-fill x
pack .b   \-side bottom \-fill x
pack .l   \-side left   \-fill y
pack .r   \-side right  \-fill y
pack .mid \-expand 1    \-fill both
.CE
.SH "SEE ALSO"
labelframe(n), button(n), ttk::label(n)
.SH KEYWORDS
label, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<



















<
<
<
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126



\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.
.SH BINDINGS
.PP
When a new label is created, it has no default event bindings:
labels are not intended to be interactive.
.SH EXAMPLE

.CS
# Make the widgets
\fBlabel\fR .t \-text "This widget is at the top"    \-bg red
\fBlabel\fR .b \-text "This widget is at the bottom" \-bg green
\fBlabel\fR .l \-text "Left\enHand\enSide"
\fBlabel\fR .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
pack .t   \-side top    \-fill x
pack .b   \-side bottom \-fill x
pack .l   \-side left   \-fill y
pack .r   \-side right  \-fill y
pack .mid \-expand 1    \-fill both
.CE
.SH "SEE ALSO"
labelframe(n), button(n), ttk::label(n)
.SH KEYWORDS
label, widget



Changes to doc/labelframe.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH labelframe n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
labelframe \- Create and manipulate 'labelframe' labelled container widgets
.SH SYNOPSIS
\fBlabelframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightbackground	\-pady
\-cursor	\-highlightcolor	\-relief
\-font	\-highlightthickness	\-takefocus
\-foreground	\-padx	\-text
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fB\-colormap\fR option is not specified, the new window
uses the same colormap as its parent.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-height height Height
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will












|










|









|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH labelframe n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
labelframe \- Create and manipulate labelframe widgets
.SH SYNOPSIS
\fBlabelframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightbackground	\-pady
\-cursor	\-highlightcolor	\-relief
\-font	\-highlightthickness	\-takefocus
\-foreground	\-padx	\-text
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fBbackground\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fBclass\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fBcolormap\fR option is not specified, the new window
uses the same colormap as its parent.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-height height Height
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
and if it is not a descendant of this window, it will be raised
above it in the stacking order.
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fB\-visual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will
not request any size at all.
.BE







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
and if it is not a descendant of this window, it will be raised
above it in the stacking order.
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fBvisual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will
not request any size at all.
.BE
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
.SH "WIDGET COMMAND"
.PP
The \fBlabelframe\fR command creates a new Tcl command whose
name is the same as the path name of the labelframe's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.SH BINDINGS
.PP
When a new labelframe is created, it has no default event bindings:
labelframes are not intended to be interactive.
.SH EXAMPLE
.PP
This shows how to build part of a GUI for a hamburger vendor. The
\fBlabelframe\fR widgets are used to organize the available choices by
the kinds of things that the choices are being made over.
.PP
.CS
grid [\fBlabelframe\fR .burger \-text "Burger"] \e
     [\fBlabelframe\fR .bun    \-text "Bun"] \-sticky news







|












|

















<







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
.SH "WIDGET COMMAND"
.PP
The \fBlabelframe\fR command creates a new Tcl command whose
name is the same as the path name of the labelframe's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.SH BINDINGS
.PP
When a new labelframe is created, it has no default event bindings:
labelframes are not intended to be interactive.
.SH EXAMPLE

This shows how to build part of a GUI for a hamburger vendor. The
\fBlabelframe\fR widgets are used to organize the available choices by
the kinds of things that the choices are being made over.
.PP
.CS
grid [\fBlabelframe\fR .burger \-text "Burger"] \e
     [\fBlabelframe\fR .bun    \-text "Bun"] \-sticky news
166
167
168
169
170
171
172
173
174
175
set cheese none
set pickle none
.CE
.SH "SEE ALSO"
frame(n), label(n), ttk::labelframe(n)
.SH KEYWORDS
labelframe, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
165
166
167
168
169
170
171



set cheese none
set pickle none
.CE
.SH "SEE ALSO"
frame(n), label(n), ttk::labelframe(n)
.SH KEYWORDS
labelframe, widget



Changes to doc/listbox.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1990 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.
'\"
.TH listbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
listbox \- Create and manipulate 'listbox' item list widgets
.SH SYNOPSIS
\fBlistbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-disabledforeground	\-exportselection	\-font
\-foreground	\-highlightbackground	\-highlightcolor
\-highlightthickness	\-justify	\-relief
\-selectbackground	\-selectborderwidth	\-selectforeground
\-setgrid	\-takefocus	\-xscrollcommand
\-yscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-activestyle activeStyle ActiveStyle
Specifies the style in which to draw the active element.  This must be
one of \fBdotbox\fR (show a focus ring around the active element),
\fBnone\fR (no special indication of active element) or
\fBunderline\fR (underline the active element).






|





|






|
|
|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
'\"
'\" Copyright (c) 1990 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.
'\" 
.TH listbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
listbox \- Create and manipulate listbox widgets
.SH SYNOPSIS
\fBlistbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-disabledforeground	\-exportselection	\-font
\-foreground	\-highlightbackground	\-highlightcolor
\-highlightthickness	\-relief	\-selectbackground
\-selectborderwidth	\-selectforeground	\-setgrid
\-takefocus	\-xscrollcommand	\-yscrollcommand

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-activestyle activeStyle ActiveStyle
Specifies the style in which to draw the active element.  This must be
one of \fBdotbox\fR (show a focus ring around the active element),
\fBnone\fR (no special indication of active element) or
\fBunderline\fR (underline the active element).
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
\fIpathName\fR's parent must exist.
.PP
A listbox is a widget that displays a list of strings, one per line.
When first created, a new listbox has no elements.
Elements may be added or deleted using widget commands described
below.  In addition, one or more elements may be selected as described
below.
If a listbox is exporting its selection (see \fB\-exportselection\fR
option), then it will observe the standard X11 protocols
for handling the selection.
Listbox selections are available as type \fBSTRING\fR;
the value of the selection will be the text of the selected elements, with
newlines separating the elements.
.PP
It is not necessary for all the elements to be
displayed in the listbox window at once;  commands described below
may be used to change the view in the window.  Listboxes allow
scrolling in both directions using the standard \fB\-xscrollcommand\fR
and \fB\-yscrollcommand\fR options.
They also support scanning, as described below.
.SH "INDICES"
.PP
Many of the widget commands for listboxes take one or more indices
as arguments.
An index specifies a particular element of the listbox, in any of
the following ways:
.TP 12
\fInumber\fR
.
Specifies the element as a numerical index, where 0 corresponds
to the first element in the listbox.
.TP 12
\fBactive\fR
.
Indicates the element that has the location cursor.  This element
will be displayed as specified by \fB\-activestyle\fR when the listbox
has the keyboard focus, and it is specified with the \fBactivate\fR
widget command.
.TP 12
\fBanchor\fR
.
Indicates the anchor point for the selection, which is set with the
\fBselection anchor\fR widget command.
.TP 12
\fBend\fR
.
Indicates the end of the listbox.
For most commands this refers to the last element in the listbox,
but for a few commands such as \fBindex\fR and \fBinsert\fR
it refers to the element just after the last one.
.TP 12
\fB@\fIx\fB,\fIy\fR
Indicates the element that covers the point in the listbox window







|









|
|









<




<






<




<







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102

103
104
105
106
107
108

109
110
111
112

113
114
115
116
117
118
119
\fIpathName\fR's parent must exist.
.PP
A listbox is a widget that displays a list of strings, one per line.
When first created, a new listbox has no elements.
Elements may be added or deleted using widget commands described
below.  In addition, one or more elements may be selected as described
below.
If a listbox is exporting its selection (see \fBexportSelection\fR
option), then it will observe the standard X11 protocols
for handling the selection.
Listbox selections are available as type \fBSTRING\fR;
the value of the selection will be the text of the selected elements, with
newlines separating the elements.
.PP
It is not necessary for all the elements to be
displayed in the listbox window at once;  commands described below
may be used to change the view in the window.  Listboxes allow
scrolling in both directions using the standard \fBxScrollCommand\fR
and \fByScrollCommand\fR options.
They also support scanning, as described below.
.SH "INDICES"
.PP
Many of the widget commands for listboxes take one or more indices
as arguments.
An index specifies a particular element of the listbox, in any of
the following ways:
.TP 12
\fInumber\fR

Specifies the element as a numerical index, where 0 corresponds
to the first element in the listbox.
.TP 12
\fBactive\fR

Indicates the element that has the location cursor.  This element
will be displayed as specified by \fB\-activestyle\fR when the listbox
has the keyboard focus, and it is specified with the \fBactivate\fR
widget command.
.TP 12
\fBanchor\fR

Indicates the anchor point for the selection, which is set with the
\fBselection anchor\fR widget command.
.TP 12
\fBend\fR

Indicates the end of the listbox.
For most commands this refers to the last element in the listbox,
but for a few commands such as \fBindex\fR and \fBinsert\fR
it refers to the element just after the last one.
.TP 12
\fB@\fIx\fB,\fIy\fR
Indicates the element that covers the point in the listbox window
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459

460
461
462
463
464
465
466
.SH "WIDGET COMMAND"
.PP
The \fBlistbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:
.TP
\fIpathName \fBactivate\fR \fIindex\fR
.
Sets the active element to the one indicated by \fIindex\fR.
If \fIindex\fR is outside the range of elements in the listbox
then the closest element is activated.
The active element is drawn as specified by \fB\-activestyle\fR when the
widget has the input focus, and its index may be retrieved with the
index \fBactive\fR.
.TP
\fIpathName \fBbbox\fR \fIindex\fR
.
Returns a list of four numbers describing the bounding box of
the text in the element given by \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the screen area covered by the text
(specified in pixels relative to the widget) and the last two
elements give the width and height of the area, in pixels.
If no part of the element given by \fIindex\fR is visible on the
screen,
or if \fIindex\fR refers to a non-existent element,
then the result is an empty string;  if the element is
partially visible, the result gives the full area of the element,
including any parts that are not visible.
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.TP
\fIpathName \fBcurselection\fR
.
Returns a list containing the numerical indices of
all of the elements in the listbox that are currently selected.
If there are no elements selected in the listbox then an empty
string is returned.
.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?
.
Deletes one or more elements of the listbox.  \fIFirst\fR and \fIlast\fR
are indices specifying the first and last elements in the range
to delete.  If \fIlast\fR is not specified it defaults to
\fIfirst\fR, i.e. a single element is deleted.
.TP
\fIpathName \fBget \fIfirst\fR ?\fIlast\fR?
.
If \fIlast\fR is omitted, returns the contents of the listbox
element indicated by \fIfirst\fR,
or an empty string if \fIfirst\fR refers to a non-existent element.
If \fIlast\fR is specified, the command returns a list whose elements
are all of the listbox elements between \fIfirst\fR and \fIlast\fR,
inclusive.
Both \fIfirst\fR and \fIlast\fR may have any of the standard
forms for indices.
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the integer index value that corresponds to \fIindex\fR.
If \fIindex\fR is \fBend\fR the return value is a count of the number
of elements in the listbox (not the index of the last element).
.TP
\fIpathName \fBinsert \fIindex \fR?\fIelement element ...\fR?
.
Inserts zero or more new elements in the list just before the
element given by \fIindex\fR.  If \fIindex\fR is specified as
\fBend\fR then the new elements are added to the end of the
list.  Returns an empty string.
.TP
\fIpathName \fBitemcget \fIindex option\fR
.
Returns the current value of the item configuration option given
by \fIoption\fR. \fIOption\fR may have any of the values accepted
by the \fBitemconfigure\fR command.
.TP
\fIpathName \fBitemconfigure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of an item in the listbox.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the item (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. The following options
are currently supported for items:
.RS
.TP
\fB\-background \fIcolor\fR
.
\fIColor\fR specifies the background color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the foreground color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-selectbackground \fIcolor\fR
.
\fIcolor\fR specifies the background color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.TP
\fB\-selectforeground \fIcolor\fR
.
\fIcolor\fR specifies the foreground color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.RE
.TP
\fIpathName \fBnearest \fIy\fR
.
Given a y-coordinate within the listbox window, this command returns
the index of the (visible) listbox element nearest to that y-coordinate.
.TP
\fIpathName \fBscan\fR \fIoption args\fR
.
This command is used to implement scanning on listboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.
Records \fIx\fR and \fIy\fR and the current view in the listbox
window;  used in conjunction with later \fBscan dragto\fR commands.
Typically this command is associated with a mouse button press in
the widget.  It returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx y\fR.
.
This command computes the difference between its \fIx\fR and \fIy\fR
arguments and the \fIx\fR and \fIy\fR arguments to the last
\fBscan mark\fR command for the widget.
It then adjusts the view by 10 times the
difference in coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the list at high speed through the window.  The return
value is an empty string.
.RE
.TP
\fIpathName \fBsee \fIindex\fR
.
Adjust the view in the listbox so that the element given by \fIindex\fR
is visible.
If the element is already visible then the command has no effect;
if the element is near one edge of the window then the listbox
scrolls to bring the element into view at the edge;  otherwise
the listbox scrolls to center the element.
.TP
\fIpathName \fBselection \fIoption arg\fR
.
This command is used to adjust the selection within a listbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBselection anchor \fIindex\fR
.
Sets the selection anchor to the element given by \fIindex\fR.
If \fIindex\fR refers to a non-existent element, then the closest
element is used.
The selection anchor is the end of the selection that is fixed
while dragging out a selection with the mouse.
The index \fBanchor\fR may be used to refer to the anchor
element.
.TP
\fIpathName \fBselection clear \fIfirst \fR?\fIlast\fR?
.
If any of the elements between \fIfirst\fR and \fIlast\fR
(inclusive) are selected, they are deselected.
The selection state is not changed for elements outside
this range.
.TP
\fIpathName \fBselection includes \fIindex\fR
.
Returns 1 if the element indicated by \fIindex\fR is currently
selected, 0 if it is not.
.TP
\fIpathName \fBselection set \fIfirst \fR?\fIlast\fR?
.
Selects all of the elements in the range between
\fIfirst\fR and \fIlast\fR, inclusive, without affecting
the selection state of elements outside that range.
.RE
.TP
\fIpathName \fBsize\fR
.
Returns a decimal string indicating the total number of elements
in the listbox.
.TP
\fIpathName \fBxview \fR?\fIargs\fR
.
This command is used to query and change the horizontal position of the
information in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the listbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview \fIindex\fR
.
Adjusts the view in the window so that the character position given by
\fIindex\fR is displayed at the left edge of the window.
Character positions are defined by the width of the character \fB0\fR.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that \fIfraction\fR of the
total width of the listbox text is off-screen to the left.
\fIfraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display.
.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR
Returns a list containing two elements, both of which are real fractions
between 0 and 1.
The first element gives the position of the listbox element at the
top of the window, relative to the listbox as a whole (0.5 means
it is halfway through the listbox, for example).
The second element gives the position of the listbox element just after
the last one in the window, relative to the listbox as a whole.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview \fIindex\fR
.
Adjusts the view in the window so that the element given by
\fIindex\fR is displayed at the top of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR
.
Adjusts the view in the window so that the element given by \fIfraction\fR
appears at the top of the window.
\fIFraction\fR is a fraction between 0 and 1;  0 indicates the first
element in the listbox, 0.33 indicates the element one-third the
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
If \fIwhat\fR is \fBpages\fR then

the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR lines.
.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for listboxes that give them
Motif-like behavior.  Much of the behavior of a listbox is determined
by its \fB\-selectmode\fR option, which selects one of four ways
of dealing with the selection.
.PP
If the selection mode is \fBsingle\fR or \fBbrowse\fR, at most one
element can be selected in the listbox at once.
In both modes, clicking button 1 on an element selects
it and deselects any other selected item.
In \fBbrowse\fR mode it is also possible to drag the selection
with button 1.

On button 1, the listbox will also take focus if it has a \fBnormal\fR
state.

.PP
If the selection mode is \fBmultiple\fR or \fBextended\fR,
any number of elements may be selected at once, including discontiguous
ranges.  In \fBmultiple\fR mode, clicking button 1 on an element
toggles its selection state without affecting any other elements.
In \fBextended\fR mode, pressing button 1 on an element selects
it, deselects everything else, and sets the anchor to the element







|






<








<














<






<














<






<






<










<





<






<

|
|


<














<
|



<




<





<






<




<





<






<











<








<





<









<






<




<






<



|
<






<









|
<





<





<


|
<
|

>
>
|




<
<
<


|
<
















|
<




<







<



|
|
>




<
<





|








>


>







127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188

189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204

205
206
207
208
209

210
211
212
213
214
215

216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238

239
240
241
242

243
244
245
246
247

248
249
250
251
252
253

254
255
256
257

258
259
260
261
262

263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287

288
289
290
291
292

293
294
295
296
297
298
299
300
301

302
303
304
305
306
307

308
309
310
311

312
313
314
315
316
317

318
319
320
321

322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337

338
339
340
341
342

343
344
345
346
347

348
349
350

351
352
353
354
355
356
357
358
359



360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383

384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
.SH "WIDGET COMMAND"
.PP
The \fBlistbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:
.TP
\fIpathName \fBactivate\fR \fIindex\fR

Sets the active element to the one indicated by \fIindex\fR.
If \fIindex\fR is outside the range of elements in the listbox
then the closest element is activated.
The active element is drawn as specified by \fB\-activestyle\fR when the
widget has the input focus, and its index may be retrieved with the
index \fBactive\fR.
.TP
\fIpathName \fBbbox\fR \fIindex\fR

Returns a list of four numbers describing the bounding box of
the text in the element given by \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the screen area covered by the text
(specified in pixels relative to the widget) and the last two
elements give the width and height of the area, in pixels.
If no part of the element given by \fIindex\fR is visible on the
screen,
or if \fIindex\fR refers to a non-existent element,
then the result is an empty string;  if the element is
partially visible, the result gives the full area of the element,
including any parts that are not visible.
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.TP
\fIpathName \fBcurselection\fR

Returns a list containing the numerical indices of
all of the elements in the listbox that are currently selected.
If there are no elements selected in the listbox then an empty
string is returned.
.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?

Deletes one or more elements of the listbox.  \fIFirst\fR and \fIlast\fR
are indices specifying the first and last elements in the range
to delete.  If \fIlast\fR is not specified it defaults to
\fIfirst\fR, i.e. a single element is deleted.
.TP
\fIpathName \fBget \fIfirst\fR ?\fIlast\fR?

If \fIlast\fR is omitted, returns the contents of the listbox
element indicated by \fIfirst\fR,
or an empty string if \fIfirst\fR refers to a non-existent element.
If \fIlast\fR is specified, the command returns a list whose elements
are all of the listbox elements between \fIfirst\fR and \fIlast\fR,
inclusive.
Both \fIfirst\fR and \fIlast\fR may have any of the standard
forms for indices.
.TP
\fIpathName \fBindex \fIindex\fR

Returns the integer index value that corresponds to \fIindex\fR.
If \fIindex\fR is \fBend\fR the return value is a count of the number
of elements in the listbox (not the index of the last element).
.TP
\fIpathName \fBinsert \fIindex \fR?\fIelement element ...\fR?

Inserts zero or more new elements in the list just before the
element given by \fIindex\fR.  If \fIindex\fR is specified as
\fBend\fR then the new elements are added to the end of the
list.  Returns an empty string.
.TP
\fIpathName \fBitemcget \fIindex option\fR

Returns the current value of the item configuration option given
by \fIoption\fR. \fIOption\fR may have any of the values accepted 
by the \fBlistbox itemconfigure\fR command.
.TP
\fIpathName \fBitemconfigure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?

Query or modify the configuration options of an item in the listbox.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the item (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. The following options
are currently supported for items:
.RS
.TP
\fB\-background \fIcolor\fR

\fIColor\fR specifies the background color to use when displaying the 
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-foreground \fIcolor\fR

\fIColor\fR specifies the foreground color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-selectbackground \fIcolor\fR

\fIcolor\fR specifies the background color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.TP
\fB\-selectforeground \fIcolor\fR

\fIcolor\fR specifies the foreground color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.RE
.TP
\fIpathName \fBnearest \fIy\fR

Given a y-coordinate within the listbox window, this command returns
the index of the (visible) listbox element nearest to that y-coordinate.
.TP
\fIpathName \fBscan\fR \fIoption args\fR

This command is used to implement scanning on listboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR

Records \fIx\fR and \fIy\fR and the current view in the listbox
window;  used in conjunction with later \fBscan dragto\fR commands.
Typically this command is associated with a mouse button press in
the widget.  It returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx y\fR.

This command computes the difference between its \fIx\fR and \fIy\fR
arguments and the \fIx\fR and \fIy\fR arguments to the last
\fBscan mark\fR command for the widget.
It then adjusts the view by 10 times the
difference in coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the list at high speed through the window.  The return
value is an empty string.
.RE
.TP
\fIpathName \fBsee \fIindex\fR

Adjust the view in the listbox so that the element given by \fIindex\fR
is visible.
If the element is already visible then the command has no effect;
if the element is near one edge of the window then the listbox
scrolls to bring the element into view at the edge;  otherwise
the listbox scrolls to center the element.
.TP
\fIpathName \fBselection \fIoption arg\fR

This command is used to adjust the selection within a listbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBselection anchor \fIindex\fR

Sets the selection anchor to the element given by \fIindex\fR.
If \fIindex\fR refers to a non-existent element, then the closest
element is used.
The selection anchor is the end of the selection that is fixed
while dragging out a selection with the mouse.
The index \fBanchor\fR may be used to refer to the anchor
element.
.TP
\fIpathName \fBselection clear \fIfirst \fR?\fIlast\fR?

If any of the elements between \fIfirst\fR and \fIlast\fR
(inclusive) are selected, they are deselected.
The selection state is not changed for elements outside
this range.
.TP
\fIpathName \fBselection includes \fIindex\fR

Returns 1 if the element indicated by \fIindex\fR is currently
selected, 0 if it is not.
.TP
\fIpathName \fBselection set \fIfirst \fR?\fIlast\fR?

Selects all of the elements in the range between
\fIfirst\fR and \fIlast\fR, inclusive, without affecting
the selection state of elements outside that range.
.RE
.TP
\fIpathName \fBsize\fR

Returns a decimal string indicating the total number of elements
in the listbox.
.TP
\fIpathName \fBxview \fIargs\fR

This command is used to query and change the horizontal position of the
information in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the listbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR

Adjusts the view in the window so that the character position given by
\fIindex\fR is displayed at the left edge of the window.
Character positions are defined by the width of the character \fB0\fR.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that \fIfraction\fR of the
total width of the listbox text is off-screen to the left.
\fIfraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display;  if it is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.



.RE
.TP
\fIpathName \fByview \fI?args\fR?

This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR
Returns a list containing two elements, both of which are real fractions
between 0 and 1.
The first element gives the position of the listbox element at the
top of the window, relative to the listbox as a whole (0.5 means
it is halfway through the listbox, for example).
The second element gives the position of the listbox element just after
the last one in the window, relative to the listbox as a whole.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview\fR \fIindex\fR

Adjusts the view in the window so that the element given by
\fIindex\fR is displayed at the top of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR

Adjusts the view in the window so that the element given by \fIfraction\fR
appears at the top of the window.
\fIFraction\fR is a fraction between 0 and 1;  0 indicates the first
element in the listbox, 0.33 indicates the element one-third the
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR

This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR lines;  if it is \fBpages\fR then
the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.


.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for listboxes that give them
Motif-like behavior.  Much of the behavior of a listbox is determined
by its \fBselectMode\fR option, which selects one of four ways
of dealing with the selection.
.PP
If the selection mode is \fBsingle\fR or \fBbrowse\fR, at most one
element can be selected in the listbox at once.
In both modes, clicking button 1 on an element selects
it and deselects any other selected item.
In \fBbrowse\fR mode it is also possible to drag the selection
with button 1.
.VS 8.5
On button 1, the listbox will also take focus if it has a \fBnormal\fR
state.
.VE 8.5
.PP
If the selection mode is \fBmultiple\fR or \fBextended\fR,
any number of elements may be selected at once, including discontiguous
ranges.  In \fBmultiple\fR mode, clicking button 1 on an element
toggles its selection state without affecting any other elements.
In \fBextended\fR mode, pressing button 1 on an element selects
it, deselects everything else, and sets the anchor to the element
573
574
575
576
577
578
579
580
581
582
583
584
585
The F16 key (labelled Copy on many Sun workstations) or Meta-w
copies the selection in the widget to the clipboard, if there is
a selection.
.PP
The behavior of listboxes can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::treeview(n)
.SH KEYWORDS
listbox, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|


<
<
<
532
533
534
535
536
537
538
539
540
541



The F16 key (labelled Copy on many Sun workstations) or Meta-w
copies the selection in the widget to the clipboard, if there is
a selection.
.PP
The behavior of listboxes can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk_treeview(n)
.SH KEYWORDS
listbox, widget



Changes to doc/loadTk.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21

22
23
24

25
26
27
28
29
30
31
32
33
34
35
36

37

38
39

40

41
42
43
44
45
46
47
48
49

50

51
52

53
54
55
56
57
58

59
60
61

62
63

64
65
66

67
68
69
'\"
'\" 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.
'\"
.TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
safe::loadTk \- Load Tk into a safe interpreter.
.SH SYNOPSIS
\fBsafe::loadTk \fIchild\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR?
.BE
.SH DESCRIPTION
.PP
Safe Tk is based on Safe Tcl, which provides a mechanism that allows

restricted and mediated access to auto-loading and packages for safe
interpreters.  Safe Tk adds the ability to configure the interpreter for safe
Tk operations and load Tk into safe interpreters.

.PP
The \fBsafe::loadTk\fR command initializes the required data structures in
the named safe interpreter and then loads Tk into it.  The interpreter must

have been created with \fBsafe::interpCreate\fR or have been initialized
with \fBsafe::interpInit\fR.  The command returns the name of the safe
interpreter.  If \fB\-use\fR is specified, the window identified by the
specified system dependent identifier \fIwindowId\fR is used to contain the
.QW .
window of the safe interpreter; it can be any valid id, eventually referencing
a window belonging to another application. As a convenience, if the window you
plan to use is a Tk Window of the application you can use the window name
(e.g.,
.QW \fB.x.y\fR )
instead of its window Id (e.g., from \fBwinfo id\fR \fB.x.y\fR).
When \fB\-use\fR is not specified, a new toplevel window is created for the

.QW .

window of the safe interpreter. On X11 if you want the embedded window to use
another display than the default one, specify it with \fB\-display\fR.  See

the \fBSECURITY ISSUES\fR section below for implementation details.

.SH "SECURITY ISSUES"
.PP
Please read the \fBsafe\fR manual page for Tcl to learn about the basic
security considerations for Safe Tcl.
.PP
\fBsafe::loadTk\fR adds the value of \fBtk_library\fR taken from the parent
interpreter to the virtual access path of the safe interpreter so that
auto-loading will work in the safe interpreter.
.PP

Tk initialization is now safe with respect to not trusting the child's state

for startup. \fBsafe::loadTk\fR registers the child's name so when the Tk
initialization (\fBTk_SafeInit\fR) is called and in turn calls the parent's

\fBsafe::InitTk\fR it will return the desired \fBargv\fR equivalent
(\fB\-use\fR \fIwindowId\fR, correct \fB\-display\fR, etc.)
.PP
When \fB\-use\fR is not used, the new toplevel created is specially decorated
so the user is always aware that the user interface presented comes from a
potentially unsafe code and can easily delete the corresponding interpreter.

.PP
On X11, conflicting \fB\-use\fR and \fB\-display\fR are likely to generate a
fatal X error.

.SH "SEE ALSO"
safe(n), interp(n), library(n), load(n), package(n), source(n), unknown(n)

.SH KEYWORDS
alias, auto-loading, auto_mkindex, load, parent interpreter, safe
interpreter, child interpreter, source

'\" Local Variables:
'\" mode: nroff
'\" End:





|





|

|


<
|
>
|
|
|
>

|
|
>
|
|
|
|

|
|
|
<
|
|
|
>

>
|
|
>
|
>





|



>
|
>
|
|
>
|
|

|
|
|
>

|
|
>


>

|
|
>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
'\"
'\" 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.
'\" 
.TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
loadTk \- Load Tk into a safe interpreter.
.SH SYNOPSIS
\fB::safe::loadTk \fIslave\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR? 
.BE
.SH DESCRIPTION

Safe Tk is based on Safe Tcl, which provides a mechanism 
that allows restricted and mediated
access to auto-loading and packages for safe interpreters.
Safe Tk adds the ability to configure the interpreter
for safe Tk operations and load Tk into safe 
interpreters.
.PP
The \fB::safe::loadTk\fR command initializes the required data structures
in the named safe interpreter and then loads Tk into it.
The interpreter must have been created with \fB::safe::interpCreate\fR
or have been initialized with \fB::safe::interpInit\fR.
The command returns the name of the safe interpreter.
If \fB\-use\fR is specified, the window identified by the specified system
dependent identifier \fIwindowId\fR is used to contain the
.QW .
window of the safe interpreter; it can be any valid id, eventually 
referencing a window belonging to another application. As a convenience,
if the window you plan to use is a Tk Window of the application you

can use the window name (e.g. \fB.x.y\fR) instead of its window Id 
(\fB[winfo id .x.y]\fR).
When \fB\-use\fR is not specified,
a new toplevel window is created for the
.QW .
window of
the safe interpreter. On X11 if you want the embedded window
to use another display than the default one, specify it with
\fB\-display\fR.
See the \fBSECURITY ISSUES\fR section below for implementation details.

.SH "SECURITY ISSUES"
.PP
Please read the \fBsafe\fR manual page for Tcl to learn about the basic
security considerations for Safe Tcl.
.PP
\fB::safe::loadTk\fR adds the value of \fBtk_library\fR taken from the master
interpreter to the virtual access path of the safe interpreter so that
auto-loading will work in the safe interpreter.
.PP
.PP
Tk initialization is now safe with respect to not trusting
the slave's state for startup. \fB::safe::loadTk\fR
registers the slave's name so
when the Tk initialization (\fBTk_SafeInit\fR) is called
and in turn calls the master's \fB::safe::InitTk\fR it will
return the desired \fBargv\fR equivalent (\fB\-use\fR 
\fIwindowId\fR, correct \fB\-display\fR, etc.)
.PP
When \fB\-use\fR is not used, the new toplevel created is specially
decorated so the user is always aware that the user interface presented comes
from a potentially unsafe code and can easily delete the corresponding
interpreter.
.PP
On X11, conflicting \fB\-use\fR and \fB\-display\fR are likely
to generate a fatal X error.

.SH "SEE ALSO"
safe(n), interp(n), library(n), load(n), package(n), source(n), unknown(n)
 
.SH KEYWORDS
alias, auto\-loading, auto_mkindex, load, master interpreter, safe
interpreter, slave interpreter, source

'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/lower.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH lower n 3.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lower \- Change a window's position in the stacking order
.SH SYNOPSIS
\fBlower \fIwindow \fR?\fIbelowThis\fR?
.BE

.SH DESCRIPTION
.PP
If the \fIbelowThis\fR argument is omitted then the command lowers
\fIwindow\fR so that it is below all of its siblings in the stacking
order (it will be obscured by any siblings that overlap it and
will not obscure any siblings).
If \fIbelowThis\fR is specified then it must be the path name of
a window that is either a sibling of \fIwindow\fR or the descendant
of a sibling of \fIwindow\fR.
In this case the \fBlower\fR command will insert
\fIwindow\fR into the stacking order just below \fIbelowThis\fR
(or the ancestor of \fIbelowThis\fR that is a sibling of \fIwindow\fR);
this could end up either raising or lowering \fIwindow\fR.
.PP
All \fBtoplevel\fR windows may be restacked with respect to each
other, whatever their relative path names, but the window manager is
not obligated to strictly honor requests to restack.
.SH "SEE ALSO"
raise

.SH KEYWORDS
lower, obscure, stacking order
'\" Local Variables:
'\" mode: nroff
'\" End:






|









>













|
<
<
<


>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31



32
33
34
35
36



'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH lower n 3.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lower \- Change a window's position in the stacking order
.SH SYNOPSIS
\fBlower \fIwindow \fR?\fIbelowThis\fR?
.BE

.SH DESCRIPTION
.PP
If the \fIbelowThis\fR argument is omitted then the command lowers
\fIwindow\fR so that it is below all of its siblings in the stacking
order (it will be obscured by any siblings that overlap it and
will not obscure any siblings).
If \fIbelowThis\fR is specified then it must be the path name of
a window that is either a sibling of \fIwindow\fR or the descendant
of a sibling of \fIwindow\fR.
In this case the \fBlower\fR command will insert
\fIwindow\fR into the stacking order just below \fIbelowThis\fR
(or the ancestor of \fIbelowThis\fR that is a sibling of \fIwindow\fR);
this could end up either raising or lowering \fIwindow\fR.




.SH "SEE ALSO"
raise

.SH KEYWORDS
lower, obscure, stacking order



Deleted doc/man.macros.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS ?type? ?name?
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .CS
.\"	Begin code excerpt.
.\"
.\" .CE
.\"	End code excerpt.
.\"
.\" .VS ?version? ?br?
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.  The first argument is ignored and used for recording
.\"	the version when the .VS was added, so that the sidebars can be
.\"	found and removed when they reach a certain age.  If another argument
.\"	is present, then a line break is forced before starting the sidebar.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
.\" .SO ?manpage?
.\"	Start of list of standard options for a Tk widget. The manpage
.\"	argument defines where to look up the standard options; if
.\"	omitted, defaults to "options". The options follow on successive
.\"	lines, in three columns separated by tabs.
.\"
.\" .SE
.\"	End of list of standard options for a Tk widget.
.\"
.\" .OP cmdName dbName dbClass
.\"	Start of description of a specific option.  cmdName gives the
.\"	option's name as specified in the class command, dbName gives
.\"	the option's name in the option database, and dbClass gives
.\"	the option's class in the option database.
.\"
.\" .UL arg1 arg2
.\"	Print arg1 underlined, then print arg2 normally.
.\"
.\" .QW arg1 ?arg2?
.\"	Print arg1 in quotes, then arg2 normally (for trailing punctuation).
.\"
.\" .PQ arg1 ?arg2?
.\"	Print an open parenthesis, arg1 in quotes, then arg2 normally
.\"	(for trailing punctuation) and then a closing parenthesis.
.\"
.\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
.\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
.\"	# BS - start boxed text
.\"	# ^y = starting y location
.\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\"	# VS - start vertical sidebar
.\"	# ^Y = starting y location
.\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
.\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
.\"	# Special macro to handle page bottom:  finish off current
.\"	# box/sidebar if in box/sidebar mode, then invoked standard
.\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
.\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
.\"	# DE - end display
.de DE
.fi
.RE
.sp
..
.\"	# SO - start of list of standard options
.de SO
'ie '\\$1'' .ds So \\fBoptions\\fR
'el .ds So \\fB\\$1\\fR
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
.\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\*(So manual entry for details on the standard options.
..
.\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
.\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.\"	# UL - underline word
.de UL
\\$1\l'|0\(ul'\\$2
..
.\"	# QW - apply quotation marks to word
.de QW
.ie '\\*(lq'"' ``\\$1''\\$2
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\$2
..
.\"	# PQ - apply parens and quotation marks to word
.de PQ
.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
.\"" fix emacs highlighting
.el (\\*(lq\\$1\\*(rq\\$2)\\$3
..
.\"	# QR - quoted range
.de QR
.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
..
.\"	# MT - "empty" string
.de MT
.QW ""
..
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































Changes to doc/menu.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'\"
'\" 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.
'\"
.TH menu n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate 'menu' widgets and menubars
.SH SYNOPSIS
.nf
\fBmenu\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fR \fIpathName\fR
.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font	\-activerelief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-postcommand postCommand Command
If this option is specified then it provides a Tcl command to execute
each time the menu is posted.  The command is invoked by the \fBpost\fR
widget command before posting the menu. Note that in Tk 8.0 on Macintosh
and Windows, all post-commands in a system of menus are executed before any
of those menus are posted.
This is due to the limitations in the individual platforms' menu managers.
.OP \-selectcolor selectColor Background
For menu entries that are check buttons or radio buttons, this option
specifies the color to display in the indicator when the check button
or radio button is selected.
.OP \-tearoff tearOff TearOff
This option must have a proper boolean value (default is false),
which specifies whether or not the menu should include a tear-off
entry at the top.  If so, it will exist as entry 0 of the menu and
the other entries will number starting at 1.  The default menu
bindings arrange for the menu to be torn off when the tear-off entry
is invoked.
This option is ignored under Aqua/Mac OS X, where menus cannot
be torn off.
.OP \-tearoffcommand tearOffCommand TearOffCommand
If this option has a non-empty value, then it specifies a Tcl command
to invoke whenever the menu is torn off.  The actual command will
consist of the value of this option, followed by a space, followed
by the name of the menu window, followed by a space, followed by
the name of the name of the torn off menu window.  For example, if
the option's value is
.QW "\fBa b\fR"
and menu \fB.x.y\fR is torn off to
create a new menu \fB.x.tearoff1\fR, then the command
.QW "\fBa b .x.y .x.tearoff1\fR"
will be invoked.
This option is ignored under Aqua/Mac OS X, where menus cannot
be torn off.
.OP \-title title Title
The string will be used to title the window created when this menu is
torn off. If the title is NULL, then the window will have the title
of the menubutton or the text of the cascade item from which this menu
was invoked.
.OP \-type type Type
This option can be one of \fBmenubar\fR, \fBtearoff\fR, or
\fBnormal\fR, and is set when the menu is created. While the string
returned by the configuration database will change if this option is
changed, this does not affect the menu widget's behavior. This is used
by the cloning mechanism and is not normally set outside of the Tk
library.
.BE
.SH INTRODUCTION
.PP
The \fBmenu\fR command creates a new top-level window (given
by the \fIpathName\fR argument) and makes it into a menu widget.
That menu widget can either be used as a pop-up window or applied to a
\fBtoplevel\fR (with its \fB\-menu\fR option) to make it into the menubar for
that toplevel.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the menu such as its colors and font.
The \fBmenu\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but






|





|








|














|
|
|
|
|
|
<
<












<
<

















<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42


43
44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71



72
73
74
75
76
77
78
'\"
'\" 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.
'\" 
.TH menu n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate menu widgets
.SH SYNOPSIS
.nf
\fBmenu\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fR \fIpathName\fR
.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-postcommand postCommand Command
If this option is specified then it provides a Tcl command to execute
each time the menu is posted.  The command is invoked by the \fBpost\fR
widget command before posting the menu. Note that in Tk 8.0 on Macintosh
and Windows, all post-commands in a system of menus are executed before any
of those menus are posted.
This is due to the limitations in the individual platforms' menu managers.
.OP \-selectcolor selectColor Background
For menu entries that are check buttons or radio buttons, this option
specifies the color to display in the indicator when the check button
or radio button is selected.
.OP \-tearoff tearOff TearOff
This option must have a proper boolean value, which specifies
whether or not the menu should include a tear-off entry at the
top.  If so, it will exist as entry 0 of the menu and the other
entries will number starting at 1.  The default
menu bindings arrange for the menu to be torn off when the tear-off
entry is invoked.


.OP \-tearoffcommand tearOffCommand TearOffCommand
If this option has a non-empty value, then it specifies a Tcl command
to invoke whenever the menu is torn off.  The actual command will
consist of the value of this option, followed by a space, followed
by the name of the menu window, followed by a space, followed by
the name of the name of the torn off menu window.  For example, if
the option's value is
.QW "\fBa b\fR"
and menu \fB.x.y\fR is torn off to
create a new menu \fB.x.tearoff1\fR, then the command
.QW "\fBa b .x.y .x.tearoff1\fR"
will be invoked.


.OP \-title title Title
The string will be used to title the window created when this menu is
torn off. If the title is NULL, then the window will have the title
of the menubutton or the text of the cascade item from which this menu
was invoked.
.OP \-type type Type
This option can be one of \fBmenubar\fR, \fBtearoff\fR, or
\fBnormal\fR, and is set when the menu is created. While the string
returned by the configuration database will change if this option is
changed, this does not affect the menu widget's behavior. This is used
by the cloning mechanism and is not normally set outside of the Tk
library.
.BE
.SH INTRODUCTION
.PP
The \fBmenu\fR command creates a new top-level window (given
by the \fIpathName\fR argument) and makes it into a menu widget.



Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the menu such as its colors and font.
The \fBmenu\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
.PP
Menu entries are displayed with up to three separate fields.
The main field is a label in the form of a text string,
a bitmap, or an image, controlled by the \fB\-label\fR,
\fB\-bitmap\fR, and \fB\-image\fR options for the entry.
If the  \fB\-accelerator\fR option is specified for an entry then a second
textual field is displayed to the right of the label.  The accelerator
typically describes a keystroke sequence that may be used in the
application to cause the same result as invoking the menu entry.
This is a display option, it does not actually set the corresponding
binding (which can be achieved using the \fBbind\fR command).
The third field is an \fIindicator\fR.  The indicator is present only for
checkbutton or radiobutton entries.  It indicates whether the entry
is selected or not, and is displayed to the left of the entry's
string.
.PP
In normal use, an entry becomes active (displays itself differently)
whenever the mouse pointer is over the entry.  If a mouse







|

<
<







87
88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
.PP
Menu entries are displayed with up to three separate fields.
The main field is a label in the form of a text string,
a bitmap, or an image, controlled by the \fB\-label\fR,
\fB\-bitmap\fR, and \fB\-image\fR options for the entry.
If the  \fB\-accelerator\fR option is specified for an entry then a second
textual field is displayed to the right of the label.  The accelerator
typically describes a keystroke sequence that may be typed in the
application to cause the same result as invoking the menu entry.


The third field is an \fIindicator\fR.  The indicator is present only for
checkbutton or radiobutton entries.  It indicates whether the entry
is selected or not, and is displayed to the left of the entry's
string.
.PP
In normal use, an entry becomes active (displays itself differently)
whenever the mouse pointer is over the entry.  If a mouse
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
.PP
If a \fB\-command\fR option is specified for a cascade entry then it is
evaluated as a Tcl command whenever the entry is invoked. This is not
supported on Windows.
.SS "TEAR-OFF ENTRIES"
.PP
A tear-off entry appears at the top of the menu if enabled with the
\fB\-tearoff\fR option.  It is not like other menu entries in that
it cannot be created with the \fBadd\fR widget command and
cannot be deleted with the \fBdelete\fR widget command.
When a tear-off entry is created it appears as a dashed line at
the top of the menu.  Under the default bindings, invoking the
tear-off entry causes a torn-off copy to be made of the menu and
all of its submenus.
.SH "MENUBARS"







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
.PP
If a \fB\-command\fR option is specified for a cascade entry then it is
evaluated as a Tcl command whenever the entry is invoked. This is not
supported on Windows.
.SS "TEAR-OFF ENTRIES"
.PP
A tear-off entry appears at the top of the menu if enabled with the
\fBtearOff\fR option.  It is not like other menu entries in that
it cannot be created with the \fBadd\fR widget command and
cannot be deleted with the \fBdelete\fR widget command.
When a tear-off entry is created it appears as a dashed line at
the top of the menu.  Under the default bindings, invoking the
tear-off entry causes a torn-off copy to be made of the menu and
all of its submenus.
.SH "MENUBARS"
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
As noted, menubars may behave differently on different platforms.  One
example of this concerns the handling of checkbuttons and radiobuttons
within the menu.  While it is permitted to put these menu elements on
menubars, they may not be drawn with indicators on some platforms, due
to system restrictions.
.SS "SPECIAL MENUS IN MENUBARS"
.PP
Certain menus in a menubar will be treated specially.  On the Macintosh,
access to the special Application, Window and Help menus is provided. On
Windows, access to the Windows System menu in each window is provided.
On X Windows, a special right-justified help menu may be provided if
Motif menu compatibility is enabled. In all cases, these menus must be
created with the command name of the menubar menu concatenated with the
special name. So for a menubar named .menubar, on the Macintosh, the
special menus would be .menubar.apple, .menubar.window and .menubar.help;
on Windows, the special menu would be .menubar.system; on X Windows,
the help menu would be .menubar.help.
.PP
When Tk sees a .menubar.apple menu as the first menu in a menubar on the
Macintosh, that menu's contents make up the first items of the
Application menu whenever the window containing the menubar is in front.
After all of the Tk-defined items, the menu will have a separator,
followed by all standard Application menu items.
Such a .apple menu must be present in a menu when that menu is first
configured as a toplevel's menubar, otherwise a default application menu
(hidden from Tk) will be inserted into the menubar at that time and
subsequent addition of a .apple menu will no longer result in it
becoming the Application menu.
.PP
When Tk sees a .menubar.window menu on the Macintosh, the menu's
contents are inserted into the standard Window menu of the user's
menubar whenever the window's menubar is in front. The first items in
the menu are provided by Mac OS X, and the names of the current
toplevels are automatically appended after all the Tk-defined items and
a separator. The Window menu on the Mac also allows toggling the
window into a fullscreen state, and managing a tabbed window interface
(multiple windows grouped into a single window) if supported by that
version of the operating system.
.PP
When Tk sees a .menubar.help menu on the Macintosh, the menu's contents
are appended to the standard Help menu of the user's menubar whenever
the window's menubar is in front. The first items in the menu
are provided by Mac OS X.
.PP
When Tk sees a System menu on Windows, its items are appended to the
system menu that the menubar is attached to. This menu is tied to the
application icon and can be invoked with the mouse or by typing
Alt+Spacebar.  Due to limitations in the Windows API, any font changes,
colors, images, bitmaps, or tearoff images will not appear in the
system menu.
.PP
When Tk sees a Help menu on X Windows and Motif menu compatibility is
enabled the menu is moved to be last in the menubar and is right
justified. Motif menu compatibility is enabled by setting the Tk option







|
|
|
|
|
|
|
|
|
|

|
|
|


<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
|
|
|


|
|
|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246





247










248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
As noted, menubars may behave differently on different platforms.  One
example of this concerns the handling of checkbuttons and radiobuttons
within the menu.  While it is permitted to put these menu elements on
menubars, they may not be drawn with indicators on some platforms, due
to system restrictions.
.SS "SPECIAL MENUS IN MENUBARS"
.PP
Certain menus in a menubar will be treated specially.  On the
Macintosh, access to the special Application and Help menus is
provided. On Windows, access to the Windows System menu in each window
is provided. On X Windows, a special right-justified help menu may be
provided if Motif menu compatibility is enabled. In all cases, these
menus must be created with the command name of the menubar menu
concatenated with the special name. So for a menubar named .menubar,
on the Macintosh, the special menus would be .menubar.apple
and .menubar.help; on Windows, the special menu would be .menubar.system;
on X Windows, the help menu would be .menubar.help.
.PP
When Tk sees a .menubar.apple menu on the Macintosh, that menu's contents
make up the first items of the Application menu whenever the window
containing the menubar is in front.
After all of the Tk-defined items, the menu will have a separator,
followed by all standard Application menu items.





.PP










When Tk sees a Help menu on the Macintosh, the menu's contents are
appended to the standard Help menu on the right of the user's menubar
whenever the window's menubar is in front. The first items in the menu
are provided by Mac OS X.
.PP
When Tk sees a System menu on Windows, its items are appended to the 
system menu that the menubar is attached to. This menu has an icon
representing a spacebar, and can be invoked with the mouse or by typing
Alt+Spacebar.  Due to limitations in the Windows API, any font changes,
colors, images, bitmaps, or tearoff images will not appear in the
system menu.
.PP
When Tk sees a Help menu on X Windows and Motif menu compatibility is
enabled the menu is moved to be last in the menubar and is right
justified. Motif menu compatibility is enabled by setting the Tk option
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384



























































385













































































































386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
.SH "WIDGET COMMAND"
.PP
The \fBmenu\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:
.TP 12
\fBactive\fR
.
Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fBnone\fR.  This form may
not be abbreviated.
.TP 12
\fBend\fR
.
Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fBnone\fR.
This form may not be abbreviated.
.TP 12
\fBlast\fR
.
Same as \fBend\fR.
.TP 12
\fBnone\fR
.
Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fBnone\fR causes
nothing to happen in the widget command.
This form may not be abbreviated.
.TP 12
\fB@\fInumber\fR
.
In this form, \fInumber\fR is treated as a y-coordinate in the
menu's window;  the entry closest to that y-coordinate is used.
For example,
.QW \fB@0\fR
indicates the top-most entry in the window.
.TP 12
\fInumber\fR
.
Specifies the entry numerically, where 0 corresponds
to the top-most entry of the menu, 1 to the entry below it, and
so on.
.TP 12
\fIpattern\fR
.
If the index does not satisfy one of the above forms then this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBstring match\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.
.PP
The following widget commands are possible for menu widgets:
.TP
\fIpathName \fBactivate \fIindex\fR
.
Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fBnone\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.
.TP
\fIpathName \fBadd \fItype \fR?\fIoption value option value ...\fR?
.
Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.  If additional arguments
are present, they specify the options listed in the \fBMENU ENTRY OPTIONS\fR



























































section below.













































































































The \fBadd\fR widget command returns an empty string.

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.TP
\fIpathName \fBclone \fInewPathname\fR ?\fIcloneType\fR?
.
Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?
.
Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fB\-tearoff\fR option to remove the tear-off entry).
.TP
\fIpathName \fBentrycget \fIindex option\fR
.
Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the names described in the
\fBMENU ENTRY OPTIONS\fR section below.

.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions...\fR?
.
This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values described in the
\fBMENU ENTRY OPTIONS\fR
section below.  If \fIoptions\fR are specified, options are

modified as indicated in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.
.TP
\fIpathName \fBinsert \fIindex type \fR?\fIoption value option value ...\fR?
.
Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIoption\fR, and \fIvalue\fR
arguments have the same interpretation as for the \fBadd\fR widget
command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.
.TP
\fIpathName \fBinvoke \fIindex\fR
.
Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.
.TP
\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  If an index is specified
the menu will be located so that the entry with that index is
displayed at the point.  These coordinates are adjusted if necessary to
guarantee that the entire menu is visible on the screen.  This command
normally returns an empty string.  If the \fB\-postcommand\fR option
has been specified, then its value is executed as a Tcl script before
posting the menu and the result of that script is returned as the
result of the \fBpost\fR widget command.  If an error returns while

executing the command, then the error is returned without posting the
menu.
.TP
\fIpathName \fBpostcascade \fIindex\fR
.
Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.
.TP
\fIpathName \fBtype \fIindex\fR
.
Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR or \fBinsert\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.
.TP
\fIpathName \fBunpost\fR
.
Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.
.TP
\fIpathName \fBxposition \fIindex\fR
.
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.

.TP
\fIpathName \fByposition \fIindex\fR
.
Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.
.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.
.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activebackground\fR option for the overall menu is used.
If the \fBtk_strictMotif\fR variable has been set to request strict
Motif compliance, then this option is ignored and the \fB\-background\fR
option is used in its place.
This option is not available for separator or tear-off entries.
.TP
\fB\-activeforeground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activeforeground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.
.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
If this option is specified as an empty string (the default), then the
\fB\-background\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-bitmap \fIvalue\fR
.
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.
.TP
\fB\-columnbreak \fIvalue\fR
.
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
This option is ignored on Aqua/Mac OS X, where menus are always a single
column.
.TP
\fB\-command \fIvalue\fR
.
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.
.TP
\fB\-compound \fIvalue\fR
.
Specifies whether the menu entry should display both an image and text,
and if so, where the image should be placed relative to the text.
Valid values for this option are \fBbottom\fR, \fBcenter\fR,
\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR.  The default value
is \fBnone\fR, meaning that the button will display either an image or
text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
options.
.TP
\fB\-font \fIvalue\fR
.
Specifies the font to use when drawing the label or accelerator
string in this entry.
If this option is specified as an empty string (the default) then
the \fB\-font\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-foreground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
If this option is specified as an empty string (the default), then the
\fB\-foreground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-hidemargin \fIvalue\fR
.
Specifies whether the standard margins should be drawn for this menu
entry. This is useful when creating palette with images in them, i.e.,
color palettes, pattern palettes, etc. 1 indicates that the margin for
the entry is hidden; 0 means that the margin is used.
.TP
\fB\-image \fIvalue\fR
.
Specifies an image to display in the menu instead of a text string
or bitmap.
The image must have been created by some previous invocation of
\fBimage create\fR.
This option overrides the \fB\-label\fR and \fB\-bitmap\fR options
(as controlled by the \fB\-compound\fR option)
but may be reset to an empty string to enable a textual or
bitmap label to be displayed.
This option is not available for separator or tear-off entries.
.TP
\fB\-indicatoron \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
\fIValue\fR is a boolean that determines whether or not the
indicator should be displayed.
.TP
\fB\-label \fIvalue\fR
.
Specifies a string to display as an identifying label in the menu
entry.  Not available for separator or tear-off entries.
.TP
\fB\-menu \fIvalue\fR
.
Available only for cascade entries.  Specifies the path name of
the submenu associated with this entry.
The submenu must be a child of the menu.
.TP
\fB\-offvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is
deselected.
.TP
\fB\-onvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
.TP
\fB\-selectcolor \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies the color to display in the indicator when the entry is
selected.
If the value is an empty string (the default) then the \fB\-selectcolor\fR
option for the menu determines the indicator color.
.TP
\fB\-selectimage \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies an image to display in the entry (in place of
the \fB\-image\fR option) when it is selected.
\fIValue\fR is the name of an image, which must have been created
by some previous invocation of \fBimage create\fR.
This option is ignored unless the \fB\-image\fR option has
been specified.
.TP
\fB\-state \fIvalue\fR
.
Specifies one of three states for the entry:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the entry is displayed using the
\fB\-foreground\fR option for the menu and the \fB\-background\fR
option from the entry or the menu.
The active state is typically used when the pointer is over the entry.
In active state the entry is displayed using the \fB\-activeforeground\fR
option for the menu along with the \fB\-activebackground\fR option from
the entry.  Disabled state means that the entry
should be insensitive:  the default bindings will refuse to activate
or invoke the entry.
In this state the entry is displayed according to the
\fB\-disabledforeground\fR option for the menu and the
\fB\-background\fR option from the entry.
This option is not available for separator entries.
.TP
\fB\-underline \fIvalue\fR
.
Specifies the integer index of a character to underline in the entry.
This option is also queried by the default bindings and used to
implement keyboard traversal.
0 corresponds to the first character of the text displayed in the entry,
1 to the next character, and so on.
If a bitmap or image is displayed in the entry then this option is ignored.
This option is not available for separator or tear-off entries.
.TP
\fB\-value \fIvalue\fR
.
Available only for radiobutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
If an empty string is specified, then the \fB\-label\fR option
for the entry as the value to store in the variable.
.TP
\fB\-variable \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.  Specifies
the name of a global variable to set when the entry is selected.
For checkbutton entries the variable is also set when the entry
is deselected.  For radiobutton entries, changing the variable
causes the currently-selected entry to deselect itself.
.RS
.PP
For checkbutton entries, the default value of this option is taken from the
\fB\-label\fR option, and for radiobutton entries a single fixed value is
used. It is recommended that you always set the \fB\-variable\fR option when
creating either a checkbutton or a radiobutton.
.RE
.SH "MENU CONFIGURATIONS"
.PP
The default bindings support four different ways of using menus:
.TP
\fBPulldown Menus in Menubar\fR
.
This is the most common case. You create a menu widget that will become the
menu bar. You then add cascade entries to this menu, specifying the
pull down menus you wish to use in your menu bar. You then create all
of the pulldowns. Once you have done this, specify the menu using the
\fB\-menu\fR option of the toplevel's widget command. See the
\fBtoplevel\fR manual entry for details.
.TP
\fBPulldown Menus in Menu Buttons\fR
.
This is the compatible way to do menu bars.  You create one menubutton
widget for each top-level menu, and typically you arrange a series of
menubuttons in a row in a menubar window.  You also create the top-level menus
and any cascaded submenus, and tie them together with \fB\-menu\fR
options in menubuttons and cascade menu entries.  The top-level menu must
be a child of the menubutton, and each submenu must be a child of the
menu that refers to it.  Once you have done this, the default bindings
will allow users to traverse and invoke the tree of menus via its
menubutton;  see the \fBmenubutton\fR manual entry for details.
.TP
\fBPopup Menus\fR
.
Popup menus typically post in response to a mouse button press or
keystroke.  You create the popup menus and any cascaded submenus,
then you call the \fBtk_popup\fR procedure at the appropriate time
to post the top-level menu.
.TP
\fBOption Menus\fR
.
An option menu consists of a menubutton with an associated menu
that allows you to select one of several values.  The current value
is displayed in the menubutton and is also stored in a global
variable.  Use the \fBtk_optionMenu\fR procedure to create option
menubuttons and their menus.
.TP
\fBTorn-off Menus\fR
.
You create a torn-off menu by invoking the tear-off entry at
the top of an existing menu.  The default bindings will create a new menu
that is a copy of the original menu and leave it permanently
posted as a top-level window.  The torn-off menu behaves just
the same as the original menu.
.SH "DEFAULT BINDINGS"
.PP







|










<





<





<



<









<







<





<



|








<








<




|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>

|
<





|
<








<














<




|

|
<


|
<
>

|
<



|
<
|
>
|





<



|
<








<










|
<

|
<
<
|
|
|
|
|
>
|
|


<








<

|




<






|


>


<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<








<











<






<







<







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297

298
299
300
301
302

303
304
305

306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321

322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530

531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559

560
561
562

563
564
565

566
567
568
569

570
571
572
573
574
575
576
577

578
579
580
581

582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
598
599
600

601
602


603
604
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
620

621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638

639
640












































































































































































































641
642
643
644
645

646
647
648
649
650
651
652
653

654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670

671
672
673
674
675
676
677

678
679
680
681
682
683
684
.SH "WIDGET COMMAND"
.PP
The \fBmenu\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:
.TP 12
\fBactive\fR

Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fBnone\fR.  This form may
not be abbreviated.
.TP 12
\fBend\fR

Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fBnone\fR.
This form may not be abbreviated.
.TP 12
\fBlast\fR

Same as \fBend\fR.
.TP 12
\fBnone\fR

Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fBnone\fR causes
nothing to happen in the widget command.
This form may not be abbreviated.
.TP 12
\fB@\fInumber\fR

In this form, \fInumber\fR is treated as a y-coordinate in the
menu's window;  the entry closest to that y-coordinate is used.
For example,
.QW \fB@0\fR
indicates the top-most entry in the window.
.TP 12
\fInumber\fR

Specifies the entry numerically, where 0 corresponds
to the top-most entry of the menu, 1 to the entry below it, and
so on.
.TP 12
\fIpattern\fR

If the index does not satisfy one of the above forms then this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBTcl_StringMatch\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.
.PP
The following widget commands are possible for menu widgets:
.TP
\fIpathName \fBactivate \fIindex\fR

Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fBnone\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.
.TP
\fIpathName \fBadd \fItype \fR?\fIoption value option value ...\fR?

Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.  If additional arguments
are present, they specify any of the following options:
.RS
.TP
\fB\-activebackground \fIvalue\fR
Specifies a background color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fBactiveBackground\fR option for the overall menu is used.
If the \fBtk_strictMotif\fR variable has been set to request strict
Motif compliance, then this option is ignored and the \fB\-background\fR
option is used in its place.
This option is not available for separator or tear-off entries.
.TP
\fB\-activeforeground \fIvalue\fR
Specifies a foreground color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fBactiveForeground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-accelerator \fIvalue\fR
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
typed to invoke the same function as the menu entry.  This option
is not available for separator or tear-off entries.
.TP
\fB\-background \fIvalue\fR
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
If this option is specified as an empty string (the default), then the
\fBbackground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-bitmap \fIvalue\fR
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.
.TP
\fB\-columnbreak \fIvalue\fR
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
.TP
\fB\-command \fIvalue\fR
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.
.TP
\fB\-compound \fIvalue\fR
Specifies whether the menu entry should display both an image and text,
and if so, where the image should be placed relative to the text.
Valid values for this option are \fBbottom\fR, \fBcenter\fR,
\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR.  The default value
is \fBnone\fR, meaning that the button will display either an image or
text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
options.
.TP
\fB\-font \fIvalue\fR
Specifies the font to use when drawing the label or accelerator
string in this entry.
If this option is specified as an empty string (the default) then
the \fBfont\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-foreground \fIvalue\fR
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
If this option is specified as an empty string (the default), then the
\fBforeground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-hidemargin \fIvalue\fR
Specifies whether the standard margins should be drawn for this menu
entry. This is useful when creating palette with images in them, i.e.,
color palettes, pattern palettes, etc. 1 indicates that the margin for
the entry is hidden; 0 means that the margin is used.
.TP
\fB\-image \fIvalue\fR
Specifies an image to display in the menu instead of a text string
or bitmap.
The image must have been created by some previous invocation of
\fBimage create\fR.
This option overrides the \fB\-label\fR and \fB\-bitmap\fR options
(as controlled by the \fB\-compound\fR option)
but may be reset to an empty string to enable a textual or
bitmap label to be displayed.
This option is not available for separator or tear-off entries.
.TP
\fB\-indicatoron \fIvalue\fR
Available only for checkbutton and radiobutton entries.
\fIValue\fR is a boolean that determines whether or not the
indicator should be displayed.
.TP
\fB\-label \fIvalue\fR
Specifies a string to display as an identifying label in the menu
entry.  Not available for separator or tear-off entries.
.TP
\fB\-menu \fIvalue\fR
Available only for cascade entries.  Specifies the path name of
the submenu associated with this entry.
The submenu must be a child of the menu.
.TP
\fB\-offvalue \fIvalue\fR
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is
deselected.
.TP
\fB\-onvalue \fIvalue\fR
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
.TP
\fB\-selectcolor \fIvalue\fR
Available only for checkbutton and radiobutton entries.
Specifies the color to display in the indicator when the entry is
selected.
If the value is an empty string (the default) then the \fBselectColor\fR
option for the menu determines the indicator color.
.TP
\fB\-selectimage \fIvalue\fR
Available only for checkbutton and radiobutton entries.
Specifies an image to display in the entry (in place of
the \fB\-image\fR option) when it is selected.
\fIValue\fR is the name of an image, which must have been created
by some previous invocation of \fBimage create\fR.
This option is ignored unless the \fB\-image\fR option has
been specified.
.TP
\fB\-state \fIvalue\fR
Specifies one of three states for the entry:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the entry is displayed using the
\fBforeground\fR option for the menu and the \fBbackground\fR
option from the entry or the menu.
The active state is typically used when the pointer is over the entry.
In active state the entry is displayed using the \fBactiveForeground\fR
option for the menu along with the \fBactivebackground\fR option from
the entry.  Disabled state means that the entry
should be insensitive:  the default bindings will refuse to activate
or invoke the entry.
In this state the entry is displayed according to the 
\fBdisabledForeground\fR option for the menu and the
\fBbackground\fR option from the entry.
This option is not available for separator entries.
.TP
\fB\-underline \fIvalue\fR
Specifies the integer index of a character to underline in the entry.
This option is also queried by the default bindings and used to
implement keyboard traversal.
0 corresponds to the first character of the text displayed in the entry,
1 to the next character, and so on.
If a bitmap or image is displayed in the entry then this option is ignored.
This option is not available for separator or tear-off entries.
.TP
\fB\-value \fIvalue\fR
Available only for radiobutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
If an empty string is specified, then the \fB\-label\fR option
for the entry as the value to store in the variable.
.TP
\fB\-variable \fIvalue\fR
Available only for checkbutton and radiobutton entries.  Specifies
the name of a global variable to set when the entry is selected.
For checkbutton entries the variable is also set when the entry
is deselected.  For radiobutton entries, changing the variable
causes the currently-selected entry to deselect itself.
.LP
The \fBadd\fR widget command returns an empty string.
.RE
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.TP
\fIpathName\fR \fBclone\fR \fInewPathname ?cloneType?\fR

Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?

Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fBtearOff\fR option to remove the tear-off entry).
.TP
\fIpathName \fBentrycget\fR \fIindex option\fR

Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the values accepted by the \fBadd\fR

widget command.
.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions\fR?

This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values accepted by the \fBadd\fR

widget command.  If \fIoptions\fR are specified, options are modified
as indicated
in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).
.TP
\fIpathName \fBindex \fIindex\fR

Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.
.TP
\fIpathName \fBinsert \fIindex\fR \fItype \fR?\fIoption value option value ...\fR?

Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIoption\fR, and \fIvalue\fR
arguments have the same interpretation as for the \fBadd\fR widget
command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.
.TP
\fIpathName \fBinvoke \fIindex\fR

Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.
.TP
\fIpathName \fBpost \fIx y\fR

Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  These coordinates are


adjusted if necessary to guarantee that the entire menu is visible on
the screen.  This command normally returns an empty string.
If the \fBpostCommand\fR option has been specified, then its value is
executed as a Tcl script before posting the menu and the result of
that script is returned as the result of the \fBpost\fR widget
command.
If an error returns while executing the command, then the error is
returned without posting the menu.
.TP
\fIpathName \fBpostcascade \fIindex\fR

Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.
.TP
\fIpathName \fBtype \fIindex\fR

Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.
.TP
\fIpathName \fBunpost\fR

Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.
.TP
\fIpathName \fBxposition \fIindex\fR
.VS 8.5
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.
.VE 8.5
.TP
\fIpathName \fByposition \fIindex\fR

Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.












































































































































































































.SH "MENU CONFIGURATIONS"
.PP
The default bindings support four different ways of using menus:
.TP
\fBPulldown Menus in Menubar\fR

This is the most common case. You create a menu widget that will become the
menu bar. You then add cascade entries to this menu, specifying the
pull down menus you wish to use in your menu bar. You then create all
of the pulldowns. Once you have done this, specify the menu using the
\fB\-menu\fR option of the toplevel's widget command. See the
\fBtoplevel\fR manual entry for details.
.TP
\fBPulldown Menus in Menu Buttons\fR

This is the compatible way to do menu bars.  You create one menubutton
widget for each top-level menu, and typically you arrange a series of
menubuttons in a row in a menubar window.  You also create the top-level menus
and any cascaded submenus, and tie them together with \fB\-menu\fR
options in menubuttons and cascade menu entries.  The top-level menu must
be a child of the menubutton, and each submenu must be a child of the
menu that refers to it.  Once you have done this, the default bindings
will allow users to traverse and invoke the tree of menus via its
menubutton;  see the \fBmenubutton\fR manual entry for details.
.TP
\fBPopup Menus\fR

Popup menus typically post in response to a mouse button press or
keystroke.  You create the popup menus and any cascaded submenus,
then you call the \fBtk_popup\fR procedure at the appropriate time
to post the top-level menu.
.TP
\fBOption Menus\fR

An option menu consists of a menubutton with an associated menu
that allows you to select one of several values.  The current value
is displayed in the menubutton and is also stored in a global
variable.  Use the \fBtk_optionMenu\fR procedure to create option
menubuttons and their menus.
.TP
\fBTorn-off Menus\fR

You create a torn-off menu by invoking the tear-off entry at
the top of an existing menu.  The default bindings will create a new menu
that is a copy of the original menu and leave it permanently
posted as a top-level window.  The torn-off menu behaves just
the same as the original menu.
.SH "DEFAULT BINDINGS"
.PP
832
833
834
835
836
837
838
839
840
841
At present it is not possible to use the
option database to specify values for the options to individual
entries.
.SH "SEE ALSO"
bind(n), menubutton(n), ttk::menubutton(n), toplevel(n)
.SH KEYWORDS
menu, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
745
746
747
748
749
750
751



At present it is not possible to use the
option database to specify values for the options to individual
entries.
.SH "SEE ALSO"
bind(n), menubutton(n), ttk::menubutton(n), toplevel(n)
.SH KEYWORDS
menu, widget



Changes to doc/menubar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31

32
33

34
35
36
37
38
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tk_menuBar n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_menuBar, tk_bindForTraversal \- Obsolete support for menu bars
.SH SYNOPSIS
\fBtk_menuBar \fIframe \fR?\fImenu menu ...\fR?
.sp
\fBtk_bindForTraversal \fIarg ... \fR
.BE

.SH DESCRIPTION
.PP
These procedures were used in Tk 3.6 and earlier releases to help
manage pulldown menus and to implement keyboard traversal of menus.
In Tk 4.0 and later releases they are no
longer needed.  Stubs for these procedures have been retained for
backward compatibility, but they have no effect.  You should remove
calls to these procedures from your code, since eventually the
procedures will go away.
.PP
From Tk 8.0 onwards, you should instead construct your menubar as a
normal \fBmenu\fR and then attach it to the \fBtoplevel\fR of your
choice using the \fB\-menu\fR option of that widget.

.SH "SEE ALSO"
menu(n), toplevel(n)

.SH KEYWORDS
keyboard traversal, menu, menu bar, post
'\" Local Variables:
'\" mode: nroff
'\" End:






|









|

>













>


>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38



'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tk_menuBar n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_menuBar, tk_bindForTraversal \- Obsolete support for menu bars
.SH SYNOPSIS
\fBtk_menuBar \fIframe \fR?\fImenu menu ...\fR?
.sp
\fBtk_bindForTraversal \fIarg arg ... \fR
.BE

.SH DESCRIPTION
.PP
These procedures were used in Tk 3.6 and earlier releases to help
manage pulldown menus and to implement keyboard traversal of menus.
In Tk 4.0 and later releases they are no
longer needed.  Stubs for these procedures have been retained for
backward compatibility, but they have no effect.  You should remove
calls to these procedures from your code, since eventually the
procedures will go away.
.PP
From Tk 8.0 onwards, you should instead construct your menubar as a
normal \fBmenu\fR and then attach it to the \fBtoplevel\fR of your
choice using the \fB\-menu\fR option of that widget.

.SH "SEE ALSO"
menu(n), toplevel(n)

.SH KEYWORDS
keyboard traversal, menu, menu bar, post



Changes to doc/menubutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" 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.
'\"
.TH menubutton n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menubutton \- Create and manipulate 'menubutton' pop-up menu indicator widgets
.SH SYNOPSIS
\fBmenubutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" 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.
'\" 
.TH menubutton n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menubutton \- Create and manipulate menubutton widgets
.SH SYNOPSIS
\fBmenubutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Specifies the path name of the menu associated with this menubutton.
The menu must be a child of the menubutton.
.OP \-state state State
Specifies one of three states for the menubutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the menubutton is displayed using the
\fBforeground\fR and \fBbackground\fR options.  The active state is
typically used when the pointer is over the menubutton.  In active state
the menubutton is displayed using the \fB\-activeforeground\fR and
\fB\-activebackground\fR options.  Disabled state means that the menubutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fB\-disabledforeground\fR and
\fB\-background\fR options determine how the button is displayed.
.OP \-width width Width
Specifies a desired width for the menubutton.
If an image or bitmap is being displayed in the menubutton then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in characters.
If this option is not specified, the menubutton's desired width is computed
from the size of the image or bitmap or text being displayed in it.







|
|


|
|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Specifies the path name of the menu associated with this menubutton.
The menu must be a child of the menubutton.
.OP \-state state State
Specifies one of three states for the menubutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the menubutton is displayed using the
\fBforeground\fR and \fBbackground\fR options.  The active state is
typically used when the pointer is over the menubutton.  In active state
the menubutton is displayed using the \fBactiveForeground\fR and
\fBactiveBackground\fR options.  Disabled state means that the menubutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fBdisabledForeground\fR and
\fBbackground\fR options determine how the button is displayed.
.OP \-width width Width
Specifies a desired width for the menubutton.
If an image or bitmap is being displayed in the menubutton then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in characters.
If this option is not specified, the menubutton's desired width is computed
from the size of the image or bitmap or text being displayed in it.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A menubutton is a widget that displays a textual string, bitmap, or image
and is associated with a menu widget.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fB\-wraplength\fR option) and
one of the characters may optionally be underlined using the
\fB\-underline\fR option.  In normal usage, pressing
mouse button 1 over the menubutton causes the associated menu to
be posted just underneath the menubutton.  If the mouse is moved over
the menu before releasing the mouse button, the button release
causes the underlying menu entry to be invoked.  When the button
is released, the menu is unposted.
.PP
Menubuttons are used to construct a \fBtk_optionMenu\fR, which is the
preferred mechanism for allowing a user to select one item from a list
on Mac OS X.
.PP
Menubuttons were also typically organized into groups called menu bars
that allow scanning:
if the mouse button is pressed over one menubutton (causing it
to post its menu) and the mouse is moved over another menubutton
in the same menu bar without releasing the mouse button, then the
menu of the first menubutton is unposted and the menu of the
new menubutton is posted instead.
\fIThis use is deprecated\fR in favor of setting a \fBmenu\fR directly as a
menubar; see the \fBtoplevel\fR's \fB\-menu\fR option for how to do that.
.PP
There are several interactions between menubuttons and menus;  see
the \fBmenu\fR manual entry for information on various menu configurations,
such as pulldown menus and option menus.
.SH "WIDGET COMMAND"
.PP
The \fBmenubutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for menubutton widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenubutton\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If







|

|






<
<
<
<
|






<
<











|





|
<






<







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95




96
97
98
99
100
101
102


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126

127
128
129
130
131
132
133
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A menubutton is a widget that displays a textual string, bitmap, or image
and is associated with a menu widget.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fBwrapLength\fR option) and
one of the characters may optionally be underlined using the
\fBunderline\fR option.  In normal usage, pressing
mouse button 1 over the menubutton causes the associated menu to
be posted just underneath the menubutton.  If the mouse is moved over
the menu before releasing the mouse button, the button release
causes the underlying menu entry to be invoked.  When the button
is released, the menu is unposted.
.PP




Menubuttons are typically organized into groups called menu bars
that allow scanning:
if the mouse button is pressed over one menubutton (causing it
to post its menu) and the mouse is moved over another menubutton
in the same menu bar without releasing the mouse button, then the
menu of the first menubutton is unposted and the menu of the
new menubutton is posted instead.


.PP
There are several interactions between menubuttons and menus;  see
the \fBmenu\fR manual entry for information on various menu configurations,
such as pulldown menus and option menus.
.SH "WIDGET COMMAND"
.PP
The \fBmenubutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for menubutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenubutton\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
any menubutton or menu, the menubutton unposts without invoking
any menu entry.
.IP [6]
When a menubutton is posted, its associated menu claims the input
focus to allow keyboard traversal of the menu and its submenus.
See the \fBmenu\fR manual entry for details on these bindings.
.IP [7]
If the \fB\-underline\fR option has been specified for a menubutton
then keyboard traversal may be used to post the menubutton:
Alt+\fIx\fR, where \fIx\fR is the underlined character (or its
lower-case or upper-case equivalent), may be typed in any window
under the menubutton's toplevel to post the menubutton.
.IP [8]
The F10 key may be typed in any window to post the first menubutton
under its toplevel window that is not disabled.
.IP [9]
If a menubutton has the input focus, the space and return keys
post the menubutton.
.PP
If the menubutton's state is \fBdisabled\fR then none of the above
actions occur:  the menubutton is completely non-responsive.
.PP
The behavior of menubuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::menubutton(n), menu(n)
.SH KEYWORDS
menubutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|




















<
<
<
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191



any menubutton or menu, the menubutton unposts without invoking
any menu entry.
.IP [6]
When a menubutton is posted, its associated menu claims the input
focus to allow keyboard traversal of the menu and its submenus.
See the \fBmenu\fR manual entry for details on these bindings.
.IP [7]
If the \fBunderline\fR option has been specified for a menubutton
then keyboard traversal may be used to post the menubutton:
Alt+\fIx\fR, where \fIx\fR is the underlined character (or its
lower-case or upper-case equivalent), may be typed in any window
under the menubutton's toplevel to post the menubutton.
.IP [8]
The F10 key may be typed in any window to post the first menubutton
under its toplevel window that is not disabled.
.IP [9]
If a menubutton has the input focus, the space and return keys
post the menubutton.
.PP
If the menubutton's state is \fBdisabled\fR then none of the above
actions occur:  the menubutton is completely non-responsive.
.PP
The behavior of menubuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::menubutton(n), menu(n)
.SH KEYWORDS
menubutton, widget



Changes to doc/message.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH message n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
message \- Create and manipulate 'message' non-interactive text widgets
.SH SYNOPSIS
\fBmessage\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-anchor	\-background	\-borderwidth
\-cursor	\-font	\-foreground
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-padx	\-pady	\-relief
\-takefocus	\-text	\-textvariable
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-aspect aspect Aspect
Specifies a non-negative integer value indicating desired
aspect ratio for the text.  The aspect ratio is specified as
100*width/height.  100 means the text should
be as wide as it is tall, 200 means the text should
be twice as wide as it is tall, 50 means the text should
be twice as tall as it is wide, and so on.
Used to choose line length for text if \fB\-width\fR option
is not specified.
Defaults to 150.
.OP \-justify justify Justify
Specifies how to justify lines of text.
Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR.  Defaults
to \fBleft\fR.
This option works together with the \fB\-anchor\fR, \fB\-aspect\fR,
\fB\-padx\fR, \fB\-pady\fR, and \fB\-width\fR options to provide a variety
of arrangements of the text within the window.
The \fB\-aspect\fR and \fB\-width\fR options determine the amount of
screen space needed to display the text.
The \fB\-anchor\fR, \fB\-padx\fR, and \fB\-pady\fR options determine where this
rectangular area is displayed within the widget's window, and the
\fB\-justify\fR option determines how each line is displayed within that
rectangular region.
For example, suppose \fB\-anchor\fR is \fBe\fR and \fB\-justify\fR is
\fBleft\fR, and that the message window is much larger than needed
for the text.
The text will be displayed so that the left edges of all the lines
line up and the right edge of the longest line is \fB\-padx\fR from
the right side of the window;  the entire text block will be centered
in the vertical span of the window.
.OP \-width width Width
Specifies the length of lines in the window.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If this option has a value greater than zero then the \fB\-aspect\fR
option is ignored and the \fB\-width\fR option determines the line
length.
If this option has a value less than or equal to zero, then
the \fB\-aspect\fR option determines the line length.
.BE
.SH DESCRIPTION
.PP
The \fBmessage\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a message widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the message such as its colors, font,
text, and initial relief.  The \fBmessage\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A message is a widget that displays a textual string.  A message
widget has three special features that differentiate it from a
\fBlabel\fR widget.  First, it breaks up
its string into lines in order to produce a given aspect ratio
for the window.  The line breaks are chosen at word boundaries
wherever possible (if not even a single word would fit on a
line, then the word will be split across lines).  Newline characters
in the string will force line breaks;  they can be used, for example,
to leave blank lines in the display.
.PP






|





|

















|






|
|

|

|

|

|



|





|
|


|















|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH message n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
message \- Create and manipulate message widgets
.SH SYNOPSIS
\fBmessage\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-anchor	\-background	\-borderwidth
\-cursor	\-font	\-foreground
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-padx	\-pady	\-relief
\-takefocus	\-text	\-textvariable
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-aspect aspect Aspect
Specifies a non-negative integer value indicating desired
aspect ratio for the text.  The aspect ratio is specified as
100*width/height.  100 means the text should
be as wide as it is tall, 200 means the text should
be twice as wide as it is tall, 50 means the text should
be twice as tall as it is wide, and so on.
Used to choose line length for text if \fBwidth\fR option
is not specified.
Defaults to 150.
.OP \-justify justify Justify
Specifies how to justify lines of text.
Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR.  Defaults
to \fBleft\fR.
This option works together with the \fBanchor\fR, \fBaspect\fR,
\fBpadX\fR, \fBpadY\fR, and \fBwidth\fR options to provide a variety
of arrangements of the text within the window.
The \fBaspect\fR and \fBwidth\fR options determine the amount of
screen space needed to display the text.
The \fBanchor\fR, \fBpadX\fR, and \fBpadY\fR options determine where this
rectangular area is displayed within the widget's window, and the
\fBjustify\fR option determines how each line is displayed within that
rectangular region.
For example, suppose \fBanchor\fR is \fBe\fR and \fBjustify\fR is
\fBleft\fR, and that the message window is much larger than needed
for the text.
The text will be displayed so that the left edges of all the lines
line up and the right edge of the longest line is \fBpadX\fR from
the right side of the window;  the entire text block will be centered
in the vertical span of the window.
.OP \-width width Width
Specifies the length of lines in the window.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If this option has a value greater than zero then the \fBaspect\fR
option is ignored and the \fBwidth\fR option determines the line
length.
If this option has a value less than or equal to zero, then
the \fBaspect\fR option determines the line length.
.BE
.SH DESCRIPTION
.PP
The \fBmessage\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a message widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the message such as its colors, font,
text, and initial relief.  The \fBmessage\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A message is a widget that displays a textual string.  A message
widget has three special features.  First, it breaks up

its string into lines in order to produce a given aspect ratio
for the window.  The line breaks are chosen at word boundaries
wherever possible (if not even a single word would fit on a
line, then the word will be split across lines).  Newline characters
in the string will force line breaks;  they can be used, for example,
to leave blank lines in the display.
.PP
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
.SH "WIDGET COMMAND"
.PP
The \fBmessage\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmessage\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If







|





|
<






<







101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120

121
122
123
124
125
126
127
.SH "WIDGET COMMAND"
.PP
The \fBmessage\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmessage\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
141
142
143
144
145
146
147
148
149
150
.PP
Tabs do not work very well with text that is centered or right-justified.
The most common result is that the line is justified wrong.
.SH "SEE ALSO"
label(n)
.SH KEYWORDS
message, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
138
139
140
141
142
143
144



.PP
Tabs do not work very well with text that is centered or right-justified.
The most common result is that the line is justified wrong.
.SH "SEE ALSO"
label(n)
.SH KEYWORDS
message, widget



Changes to doc/messageBox.n.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:
.TP
\fB\-command\fR \fIstring\fR
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog. The actual command consists of \fIstring\fR followed by a space
and the name of the button clicked by the user to close the dialog. This
is only available on Mac OS X.
.TP
\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR







<
<
<
<
<
<







20
21
22
23
24
25
26






27
28
29
30
31
32
33
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:
.TP






\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR

Changes to doc/option.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH option n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
option \- Add/retrieve window options to/from the option database
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH option n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
option \- Add/retrieve window options to/from the option database
.SH SYNOPSIS
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
.SH DESCRIPTION
.PP
The \fBoption\fR command allows you to add entries to the Tk option
database or to retrieve options from the database.  The \fBadd\fR
form of the command adds a new option to the database.
\fIPattern\fR contains
the option being specified, and consists of names and/or classes
separated by asterisks or dots, in the usual X format (see
\fBPATTERN FORMAT\fR).  \fIValue\fR
contains a text string to associate with \fIpattern\fR;  this is the
value that will be returned in calls to \fBTk_GetOption\fR or by
invocations of the \fBoption get\fR command.  If \fIpriority\fR
is specified, it indicates the priority level for this option (see
below for legal values);  it defaults to \fBinteractive\fR.
This command always returns an empty string.
.PP







|
|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
.SH DESCRIPTION
.PP
The \fBoption\fR command allows you to add entries to the Tk option
database or to retrieve options from the database.  The \fBadd\fR
form of the command adds a new option to the database.
\fIPattern\fR contains
the option being specified, and consists of names and/or classes
separated by asterisks or dots, in the usual X format (see \fBPATTERN
FORMAT\fR).  \fIValue\fR
contains a text string to associate with \fIpattern\fR;  this is the
value that will be returned in calls to \fBTk_GetOption\fR or by
invocations of the \fBoption get\fR command.  If \fIpriority\fR
is specified, it indicates the priority level for this option (see
below for legal values);  it defaults to \fBinteractive\fR.
This command always returns an empty string.
.PP
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74

75
76
77
78

79
80
81
82
83

84
85
86
87
88
89
90
The \fBreadfile\fR form of the command reads \fIfileName\fR,
which should have the standard format for an
X resource database such as \fB.Xdefaults\fR, and adds all the
options specified in that file to the option database.  If \fIpriority\fR
is specified, it indicates the priority level at which to enter the
options;  \fIpriority\fR defaults to \fBinteractive\fR.
.PP
The file is read through a channel which is in "utf-8" encoding,
invalid byte sequences are automatically converted to valid ones.
This means that encodings like ISO 8859-1 or cp1252 with high
probability will work as well, but this cannot be guaranteed.
This cannot be changed, setting the [encoding system] has no effect.
.PP
The \fIpriority\fR arguments to the \fBoption\fR command are
normally specified symbolically using one of the following values:
.TP
\fBwidgetDefault\fR

Level 20.  Used for default values hard-coded into widgets.
.TP
\fBstartupFile\fR

Level 40.  Used for options specified in application-specific
startup files.
.TP
\fBuserDefault\fR

Level 60.  Used for options specified in user-specific defaults
files, such as \fB.Xdefaults\fR, resource databases loaded into
the X server, or user-specific startup files.
.TP
\fBinteractive\fR

Level 80.  Used for options specified interactively after the application
starts running.  If \fIpriority\fR is not specified, it defaults to
this level.
.PP
Any of the above keywords may be abbreviated.  In addition, priorities
may be specified numerically using integers between 0 and 100,
inclusive.  The numeric form is probably a bad idea except for new priority







<
<
<
<
<
<




>



>




>





>







55
56
57
58
59
60
61






62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
The \fBreadfile\fR form of the command reads \fIfileName\fR,
which should have the standard format for an
X resource database such as \fB.Xdefaults\fR, and adds all the
options specified in that file to the option database.  If \fIpriority\fR
is specified, it indicates the priority level at which to enter the
options;  \fIpriority\fR defaults to \fBinteractive\fR.
.PP






The \fIpriority\fR arguments to the \fBoption\fR command are
normally specified symbolically using one of the following values:
.TP
\fBwidgetDefault\fR
.
Level 20.  Used for default values hard-coded into widgets.
.TP
\fBstartupFile\fR
.
Level 40.  Used for options specified in application-specific
startup files.
.TP
\fBuserDefault\fR
.
Level 60.  Used for options specified in user-specific defaults
files, such as \fB.Xdefaults\fR, resource databases loaded into
the X server, or user-specific startup files.
.TP
\fBinteractive\fR
.
Level 80.  Used for options specified interactively after the application
starts running.  If \fIpriority\fR is not specified, it defaults to
this level.
.PP
Any of the above keywords may be abbreviated.  In addition, priorities
may be specified numerically using integers between 0 and 100,
inclusive.  The numeric form is probably a bad idea except for new priority
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.PP
If the overall pattern is preceded by an asterisk, then the overall pattern
applies anywhere it can throughout the whole widget hierarchy. Otherwise the
first word of the pattern is matched against the name and class of the
.QW \fB.\fR
\fBtoplevel\fR, which are usually set by options to \fBwish\fR.
.SH EXAMPLES
.PP
Instruct every button in the application to have red text on it unless
explicitly overridden, by setting the \fBforeground\fR for the \fBButton\fR
class (note that on some platforms the option is ignored):
.CS
\fBoption add\fR *Button.foreground red startupFile
.CE
.PP
Allow users to control what happens in an entry widget when the Return
key is pressed by specifying a script in the option database and add a
default option for that which rings the bell:







<

<
|







109
110
111
112
113
114
115

116

117
118
119
120
121
122
123
124
.PP
If the overall pattern is preceded by an asterisk, then the overall pattern
applies anywhere it can throughout the whole widget hierarchy. Otherwise the
first word of the pattern is matched against the name and class of the
.QW \fB.\fR
\fBtoplevel\fR, which are usually set by options to \fBwish\fR.
.SH EXAMPLES

Instruct every button in the application to have red text on it unless

explicitly overridden (note that on some platforms the option is ignored):
.CS
\fBoption add\fR *Button.foreground red startupFile
.CE
.PP
Allow users to control what happens in an entry widget when the Return
key is pressed by specifying a script in the option database and add a
default option for that which rings the bell:

Changes to doc/optionMenu.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tk_optionMenu n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_optionMenu \- Create an option menubutton and its menu
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tk_optionMenu n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_optionMenu \- Create an option menubutton and its menu
.SH SYNOPSIS
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
and appear in the option menubutton.
The current value can also be changed by setting the variable.
.PP
The return value from \fBtk_optionMenu\fR is the name of the menu
associated with \fIpathName\fR, so that the caller can change its
configuration options or manipulate it in other ways.
.SH EXAMPLE
.PP
.CS
tk_optionMenu .foo myVar Foo Bar Boo Spong Wibble
pack .foo
.CE
.SH KEYWORDS
option menu
'\" Local Variables:
'\" mode: nroff
'\" End:







<






<
<
<
29
30
31
32
33
34
35

36
37
38
39
40
41



and appear in the option menubutton.
The current value can also be changed by setting the variable.
.PP
The return value from \fBtk_optionMenu\fR is the name of the menu
associated with \fIpathName\fR, so that the caller can change its
configuration options or manipulate it in other ways.
.SH EXAMPLE

.CS
tk_optionMenu .foo myVar Foo Bar Boo Spong Wibble
pack .foo
.CE
.SH KEYWORDS
option menu



Changes to doc/options.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH options n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
options \- Standard options supported by widgets
.BE

.SH DESCRIPTION
.PP
This manual entry describes the common configuration options supported
by widgets in the Tk toolkit.  Every widget does not necessarily support
every option (see the manual entries for individual widgets for a list
of the standard options supported by that widget), but if a widget does
support an option with one of the names listed below, then the option
has exactly the effect described below.
.PP






|







>

<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH options n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
options \- Standard options supported by widgets
.BE

.SH DESCRIPTION

This manual entry describes the common configuration options supported
by widgets in the Tk toolkit.  Every widget does not necessarily support
every option (see the manual entries for individual widgets for a list
of the standard options supported by that widget), but if a widget does
support an option with one of the names listed below, then the option
has exactly the effect described below.
.PP
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
definition of active elements.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.
.OP \-activerelief activeRelief Relief
Specifies the 3-D effect desired for the active item of the widget.
See the \fB-relief\fR option for details.
.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.
.OP "\-background or \-bg" background Background
Specifies the normal background color to use when displaying the
widget.
.OP \-bitmap bitmap Bitmap
Specifies a bitmap to display in the widget, in any of the forms
acceptable to \fBTk_GetBitmap\fR.
The exact way in which the bitmap is displayed may be affected by
other options such as \fB\-anchor\fR or \fB\-justify\fR.
Typically, if this option is specified then it overrides other
options that specify a textual value to display in the widget
but this is controlled by the \fB\-compound\fR option;
the \fB\-bitmap\fR option may be reset to an empty string to re-enable
a text display.
In widgets that support both \fB\-bitmap\fR and \fB\-image\fR options,
\fB\-image\fR will usually override \fB\-bitmap\fR.
.OP "\-borderwidth or \-bd" borderWidth BorderWidth
Specifies a non-negative value indicating the width
of the 3-D border to draw around the outside of the widget (if such a
border is being drawn;  the \fB\-relief\fR option typically determines
this).  The value may also be used when drawing 3-D effects in the
interior of the widget.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.OP \-cursor cursor Cursor
Specifies the mouse cursor to be used for the widget.
The value may have any of the forms acceptable to \fBTk_GetCursor\fR.
In addition, if an empty string is specified, it indicates that the







<
<
<














|


|
|

|
|



|







54
55
56
57
58
59
60



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
definition of active elements.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.



.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.
.OP "\-background or \-bg" background Background
Specifies the normal background color to use when displaying the
widget.
.OP \-bitmap bitmap Bitmap
Specifies a bitmap to display in the widget, in any of the forms
acceptable to \fBTk_GetBitmap\fR.
The exact way in which the bitmap is displayed may be affected by
other options such as \fBanchor\fR or \fBjustify\fR.
Typically, if this option is specified then it overrides other
options that specify a textual value to display in the widget
but this is controlled by the \fBcompound\fR option;
the \fBbitmap\fR option may be reset to an empty string to re-enable
a text display.
In widgets that support both \fBbitmap\fR and \fBimage\fR options,
\fBimage\fR will usually override \fBbitmap\fR.
.OP "\-borderwidth or \-bd" borderWidth BorderWidth
Specifies a non-negative value indicating the width
of the 3-D border to draw around the outside of the widget (if such a
border is being drawn;  the \fBrelief\fR option typically determines
this).  The value may also be used when drawing 3-D effects in the
interior of the widget.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.OP \-cursor cursor Cursor
Specifies the mouse cursor to be used for the widget.
The value may have any of the forms acceptable to \fBTk_GetCursor\fR.
In addition, if an empty string is specified, it indicates that the
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
rectangle to draw around the outside of the widget when it has the
input focus.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If the value is zero, no focus highlight is drawn around the widget.
.OP \-image image Image
Specifies an image to display in the widget, which must have been
created with the \fBimage create\fR command.
Typically, if the \fB\-image\fR option is specified then it overrides other
options that specify a bitmap or textual value to display in the
widget, though this is controlled by the \fB\-compound\fR option;
the \fB\-image\fR option may be reset to an empty string to re-enable
a bitmap or text display.
.OP \-insertbackground insertBackground Foreground
Specifies the color to use as background in the area covered by the
insertion cursor.  This color will normally override either the normal
background for the widget (or the selection background if the insertion
cursor happens to fall in the selection).
.OP \-insertborderwidth insertBorderWidth BorderWidth







|

|
|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
rectangle to draw around the outside of the widget when it has the
input focus.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If the value is zero, no focus highlight is drawn around the widget.
.OP \-image image Image
Specifies an image to display in the widget, which must have been
created with the \fBimage create\fR command.
Typically, if the \fBimage\fR option is specified then it overrides other
options that specify a bitmap or textual value to display in the
widget, though this is controlled by the \fBcompound\fR option;
the \fBimage\fR option may be reset to an empty string to re-enable
a bitmap or text display.
.OP \-insertbackground insertBackground Foreground
Specifies the color to use as background in the area covered by the
insertion cursor.  This color will normally override either the normal
background for the widget (or the selection background if the insertion
cursor happens to fall in the selection).
.OP \-insertborderwidth insertBorderWidth BorderWidth
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
milliseconds the insertion cursor should remain
.QW on
in each blink cycle.
.OP \-insertwidth insertWidth InsertWidth
Specifies a  value indicating the total width of the insertion cursor.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If a border has been specified for the insertion
cursor (using the \fB\-insertborderwidth\fR option), the border
will be drawn inside the width specified by the \fB\-insertwidth\fR
option.
.OP \-jump jump Jump
For widgets with a slider that can be dragged to adjust a value,
such as scrollbars, this option determines when
notifications are made about changes in the value.
The option's value must be a boolean of the form accepted by
\fBTcl_GetBoolean\fR.







|
|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
milliseconds the insertion cursor should remain
.QW on
in each blink cycle.
.OP \-insertwidth insertWidth InsertWidth
Specifies a  value indicating the total width of the insertion cursor.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If a border has been specified for the insertion
cursor (using the \fBinsertBorderWidth\fR option), the border
will be drawn inside the width specified by the \fBinsertWidth\fR
option.
.OP \-jump jump Jump
For widgets with a slider that can be dragged to adjust a value,
such as scrollbars, this option determines when
notifications are made about changes in the value.
The option's value must be a boolean of the form accepted by
\fBTcl_GetBoolean\fR.
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
this amount to the height it would normally need (as determined by
the height of the things displayed in the widget);  if the geometry
manager can satisfy this request, the widget will end up with extra
internal space above and/or below what it displays inside.
Most widgets only use this option for padding text:  if they are
displaying a bitmap or image, then they usually ignore padding
options.
.OP \-placeholder placeHolder PlaceHolder
Specifies a help text string to display if no text is otherwise displayed,
that is when the widget is empty. The placeholder text is displayed using
the values of the \fB\-font\fR and \fB\-justify\fR options.
.OP \-placeholderforeground placeholderForeground PlaceholderForeground
Specifies the foreground color to use when the placeholder text is
displayed. The default color is platform-specific.
.OP \-relief relief Relief
Specifies the 3-D effect desired for the widget.  Acceptable
values are \fBraised\fR, \fBsunken\fR, \fBflat\fR, \fBridge\fR,
\fBsolid\fR, and \fBgroove\fR.
The value
indicates how the interior of the widget should appear relative
to its exterior;  for example, \fBraised\fR means the interior of
the widget should appear to protrude from the screen, relative to
the exterior of the widget.
.OP \-repeatdelay repeatDelay RepeatDelay
Specifies the number of milliseconds a button or key must be held
down before it begins to auto-repeat.  Used, for example, on the
up- and down-arrows in scrollbars.
.OP \-repeatinterval repeatInterval RepeatInterval
Used in conjunction with \fB\-repeatdelay\fR:  once auto-repeat
begins, this option determines the number of milliseconds between
auto-repeats.
.OP \-selectbackground selectBackground Foreground
Specifies the background color to use when displaying selected
items.
.OP \-selectborderwidth selectBorderWidth BorderWidth
Specifies a non-negative value indicating the width
of the 3-D border to draw around selected items.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.OP \-selectforeground selectForeground Background
Specifies the foreground color to use when displaying selected
items.
.OP \-setgrid setGrid SetGrid
Specifies a boolean value that determines whether this widget controls the
resizing grid for its top-level window.
This option is typically used in text widgets, where the information
in the widget has a natural size (the size of a character) and it makes
sense for the window's dimensions to be integral numbers of these units.
These natural window sizes form a grid.
If the \fB\-setgrid\fR option is set to true then the widget will
communicate with the window manager so that when the user interactively
resizes the top-level window that contains the widget, the dimensions of
the window will be displayed to the user in grid units and the window
size will be constrained to integral numbers of grid units.
See the section \fBGRIDDED GEOMETRY MANAGEMENT\fR in the \fBwm\fR manual
entry for more details.
.OP \-takefocus takeFocus TakeFocus
Determines whether the window accepts the focus during keyboard
traversal (e.g., Tab and Shift-Tab).
Before setting the focus to a window, the traversal scripts
consult the value of the \fB\-takefocus\fR option.
A value of \fB0\fR means that the window should be skipped entirely
during keyboard traversal.
\fB1\fR means that the window should receive the input
focus as long as it is viewable (it and all of its ancestors are mapped).
An empty value for the option means that the traversal scripts make
the decision about whether or not to focus on the window:  the current
algorithm is to skip the window if it is
disabled, if it has no key bindings, or if it is not viewable.
If the value has any other form, then the traversal scripts take
the value, append the name of the window to it (with a separator space),
and evaluate the resulting string as a Tcl script.
The script must return \fB0\fR, \fB1\fR, or an empty string:  a
\fB0\fR or \fB1\fR value specifies whether the window will receive
the input focus, and an empty string results in the default decision
described above.
Note: this interpretation of the option is defined entirely by
the Tcl scripts that implement traversal:  the widget implementations
ignore the option entirely, so you can change its meaning if you
redefine the keyboard traversal scripts.
.OP \-text text Text
Specifies a string to be displayed inside the widget.  The way in which
the string is displayed depends on the particular widget and may be
determined by other options, such as \fB\-anchor\fR or \fB\-justify\fR.
.OP \-textvariable textVariable Variable
Specifies the name of a global variable.  The value of the variable is a text
string to be displayed inside the widget;  if the variable value changes
then the widget will automatically update itself to reflect the new value.
The way in which the string is displayed in the widget depends on the
particular widget and may be determined by other options, such as
\fB\-anchor\fR or \fB\-justify\fR.
.OP \-troughcolor troughColor Background
Specifies the color to use for the rectangular trough areas
in widgets such as scrollbars and scales.  This option is ignored for
scrollbars on Windows (native widget does not recognize this option).
.OP \-underline underline Underline
Specifies the integer index of a character to underline in the widget.
This option is used by the default bindings to implement keyboard







<
<
<
<
<
<
<














|



















|










|

|









|










|






|







217
218
219
220
221
222
223







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
this amount to the height it would normally need (as determined by
the height of the things displayed in the widget);  if the geometry
manager can satisfy this request, the widget will end up with extra
internal space above and/or below what it displays inside.
Most widgets only use this option for padding text:  if they are
displaying a bitmap or image, then they usually ignore padding
options.







.OP \-relief relief Relief
Specifies the 3-D effect desired for the widget.  Acceptable
values are \fBraised\fR, \fBsunken\fR, \fBflat\fR, \fBridge\fR,
\fBsolid\fR, and \fBgroove\fR.
The value
indicates how the interior of the widget should appear relative
to its exterior;  for example, \fBraised\fR means the interior of
the widget should appear to protrude from the screen, relative to
the exterior of the widget.
.OP \-repeatdelay repeatDelay RepeatDelay
Specifies the number of milliseconds a button or key must be held
down before it begins to auto-repeat.  Used, for example, on the
up- and down-arrows in scrollbars.
.OP \-repeatinterval repeatInterval RepeatInterval
Used in conjunction with \fBrepeatDelay\fR:  once auto-repeat
begins, this option determines the number of milliseconds between
auto-repeats.
.OP \-selectbackground selectBackground Foreground
Specifies the background color to use when displaying selected
items.
.OP \-selectborderwidth selectBorderWidth BorderWidth
Specifies a non-negative value indicating the width
of the 3-D border to draw around selected items.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.OP \-selectforeground selectForeground Background
Specifies the foreground color to use when displaying selected
items.
.OP \-setgrid setGrid SetGrid
Specifies a boolean value that determines whether this widget controls the
resizing grid for its top-level window.
This option is typically used in text widgets, where the information
in the widget has a natural size (the size of a character) and it makes
sense for the window's dimensions to be integral numbers of these units.
These natural window sizes form a grid.
If the \fBsetGrid\fR option is set to true then the widget will
communicate with the window manager so that when the user interactively
resizes the top-level window that contains the widget, the dimensions of
the window will be displayed to the user in grid units and the window
size will be constrained to integral numbers of grid units.
See the section \fBGRIDDED GEOMETRY MANAGEMENT\fR in the \fBwm\fR manual
entry for more details.
.OP \-takefocus takeFocus TakeFocus
Determines whether the window accepts the focus during keyboard
traversal (e.g., Tab and Shift-Tab).
Before setting the focus to a window, the traversal scripts
consult the value of the \fBtakeFocus\fR option.
A value of \fB0\fR means that the window should be skipped entirely
during keyboard traversal. 
\fB1\fR means that the window should receive the input
focus as long as it is viewable (it and all of its ancestors are mapped).
An empty value for the option means that the traversal scripts make
the decision about whether or not to focus on the window:  the current
algorithm is to skip the window if it is
disabled, if it has no key bindings, or if it is not viewable.
If the value has any other form, then the traversal scripts take
the value, append the name of the window to it (with a separator space),
and evaluate the resulting string as a Tcl script.
The script must return \fB0\fR, \fB1\fR, or an empty string:  a 
\fB0\fR or \fB1\fR value specifies whether the window will receive
the input focus, and an empty string results in the default decision
described above.
Note: this interpretation of the option is defined entirely by
the Tcl scripts that implement traversal:  the widget implementations
ignore the option entirely, so you can change its meaning if you
redefine the keyboard traversal scripts.
.OP \-text text Text
Specifies a string to be displayed inside the widget.  The way in which
the string is displayed depends on the particular widget and may be
determined by other options, such as \fBanchor\fR or \fBjustify\fR.
.OP \-textvariable textVariable Variable
Specifies the name of a global variable.  The value of the variable is a text
string to be displayed inside the widget;  if the variable value changes
then the widget will automatically update itself to reflect the new value.
The way in which the string is displayed in the widget depends on the
particular widget and may be determined by other options, such as
\fBanchor\fR or \fBjustify\fR.
.OP \-troughcolor troughColor Background
Specifies the color to use for the rectangular trough areas
in widgets such as scrollbars and scales.  This option is ignored for
scrollbars on Windows (native widget does not recognize this option).
.OP \-underline underline Underline
Specifies the integer index of a character to underline in the widget.
This option is used by the default bindings to implement keyboard
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363

364
365
366
367
368
1 indicates the end, .333 indicates a position one third the way through
the document, and so on.
The first fraction indicates the first information in the document
that is visible in the window, and the second fraction indicates
the information just after the last portion that is visible.
The command is
then passed to the Tcl interpreter for execution.  Typically the
\fB\-xscrollcommand\fR option consists of the path name of a scrollbar
widget followed by
.QW set ,
e.g.
.QW ".x.scrollbar set" :
this will cause
the scrollbar to be updated whenever the view in the window changes.
If this option is not specified, then no command will be executed.
.OP \-yscrollcommand yScrollCommand ScrollCommand
Specifies the prefix for a command used to communicate with vertical
scrollbars.  This option is treated in the same way as the
\fB\-xscrollcommand\fR option, except that it is used for vertical
scrollbars and is provided by widgets that support vertical scrolling.
See the description of \fB\-xscrollcommand\fR for details
on how this option is used.

.SH "SEE ALSO"
colors, cursors, font

.SH KEYWORDS
class, name, standard option, switch
'\" Local Variables:
'\" mode: nroff
'\" End:







|










|

|

>


>


<
<
<
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357



1 indicates the end, .333 indicates a position one third the way through
the document, and so on.
The first fraction indicates the first information in the document
that is visible in the window, and the second fraction indicates
the information just after the last portion that is visible.
The command is
then passed to the Tcl interpreter for execution.  Typically the
\fBxScrollCommand\fR option consists of the path name of a scrollbar
widget followed by
.QW set ,
e.g.
.QW ".x.scrollbar set" :
this will cause
the scrollbar to be updated whenever the view in the window changes.
If this option is not specified, then no command will be executed.
.OP \-yscrollcommand yScrollCommand ScrollCommand
Specifies the prefix for a command used to communicate with vertical
scrollbars.  This option is treated in the same way as the
\fBxScrollCommand\fR option, except that it is used for vertical
scrollbars and is provided by widgets that support vertical scrolling.
See the description of \fBxScrollCommand\fR for details
on how this option is used.

.SH "SEE ALSO"
colors, cursors, font

.SH KEYWORDS
class, name, standard option, switch



Changes to doc/pack-old.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH pack-old n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pack-old \- Obsolete syntax for packer geometry manager
.SH SYNOPSIS
\fBpack after \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack append \fIparent \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack before \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack unpack \fIwindow\fR
.BE

.SH DESCRIPTION
.PP
\fINote: this manual entry describes the syntax for the \fBpack\fI
command as it existed before Tk version 3.3.
Although this syntax continues to be supported for backward
compatibility, it is obsolete and should not be used anymore.
At some point in the future it may cease to be supported.\fR






|















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH pack-old n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pack-old \- Obsolete syntax for packer geometry manager
.SH SYNOPSIS
\fBpack after \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack append \fIparent \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack before \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack unpack \fIwindow\fR
.BE

.SH DESCRIPTION
.PP
\fINote: this manual entry describes the syntax for the \fBpack\fI
command as it existed before Tk version 3.3.
Although this syntax continues to be supported for backward
compatibility, it is obsolete and should not be used anymore.
At some point in the future it may cease to be supported.\fR
184
185
186
187
188
189
190

191
192
193
194
195
them, and it unmaps any windows for which there was no space left
in the cavity.
.PP
The packer makes geometry requests on behalf of the parent windows
it manages.  For each parent window it requests a size large enough
to accommodate all the options specified by all the packed children,
such that zero space would be leftover for \fBexpand\fR options.

.SH KEYWORDS
geometry manager, location, packer, parcel, size
'\" Local Variables:
'\" mode: nroff
'\" End:







>


<
<
<
185
186
187
188
189
190
191
192
193
194



them, and it unmaps any windows for which there was no space left
in the cavity.
.PP
The packer makes geometry requests on behalf of the parent windows
it manages.  For each parent window it requests a size large enough
to accommodate all the options specified by all the packed children,
such that zero space would be leftover for \fBexpand\fR options.

.SH KEYWORDS
geometry manager, location, packer, parcel, size



Changes to doc/pack.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290

291
292
293
294
295
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH pack n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pack \- Geometry manager that packs around edges of cavity
.SH SYNOPSIS
\fBpack \fIoption arg \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBpack\fR command is used to communicate with the packer,
a geometry manager that arranges the children of a parent by
packing them in order around the edges of the parent.
The \fBpack\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBpack \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
If the first argument to \fBpack\fR is a window name (any value
starting with
.QW . ),
then the command is processed in the same way as \fBpack configure\fR.
.TP
\fBpack configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
See \fBTHE PACKER ALGORITHM\fR below for details on how the options
are used by the packer.
The following options are supported:
.RS
.TP
\fB\-after \fIother\fR
\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just after \fIother\fR in the packing order.
.TP
\fB\-anchor \fIanchor\fR
\fIAnchor\fR must be a valid anchor position such as \fBn\fR
or \fBsw\fR; it specifies where to position each content in its
parcel.
Defaults to \fBcenter\fR.
.TP
\fB\-before \fIother\fR
\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just before \fIother\fR in the packing order.
.TP
\fB\-expand \fIboolean\fR
Specifies whether the content should be expanded to consume
extra space in their container.
\fIBoolean\fR may have any proper boolean value, such as \fB1\fR
or \fBno\fR.
Defaults to 0.
.TP
\fB\-fill \fIstyle\fR
If a content's parcel is larger than its requested dimensions, this
option may be used to stretch the content.
\fIStyle\fR must have one of the following values:
.RS
.TP
\fBnone\fR
Give the content its requested dimensions plus any internal padding
requested with \fB\-ipadx\fR or \fB\-ipady\fR.  This is the default.
.TP
\fBx\fR
Stretch the content horizontally to fill the entire width of its
parcel (except leave external padding as specified by \fB\-padx\fR).
.TP
\fBy\fR
Stretch the content vertically to fill the entire height of its
parcel (except leave external padding as specified by \fB\-pady\fR).
.TP
\fBboth\fR
Stretch the content both horizontally and vertically.
.RE
.TP
\fB\-in \fIcontainer\fR
Insert the window at the end of the packing order for the container
window given by \fIcontainer\fR.
.TP
\fB\-ipadx \fIamount\fR
\fIAmount\fR specifies how much horizontal internal padding to
leave on each side of the content.
\fIAmount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR
\fIAmount\fR specifies how much vertical internal padding to
leave on each side of the content.
\fIAmount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR
\fIAmount\fR specifies how much horizontal external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for left and right separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-pady \fIamount\fR
\fIAmount\fR specifies how much vertical external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-side \fIside\fR
Specifies which side of the container the content will be packed against.
Must be \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
Defaults to \fBtop\fR.
.LP
If no \fB\-in\fR, \fB\-after\fR or \fB\-before\fR option is specified
then each of the content will be inserted at the end of the packing list
for its parent unless it is already managed by the packer (in which
case it will be left where it is).
If one of these options is specified then all the content will be
inserted at the specified point.
If any of the content are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBpack forget \fIwindow \fR?\fIwindow ...\fR?
Removes each of the \fIwindow\fRs from the packing order for its
container and unmaps their windows.
The content will no longer be managed by the packer.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.TP
\fBpack info \fIwindow\fR
Returns a list whose elements are the current configuration state of
the window given by \fIwindow\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the window's container.
.TP
\fBpack propagate \fIcontainer\fR ?\fIboolean\fR?
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIcontainer\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIcontainer\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIcontainer\fR.
Propagation is enabled by default.
.TP
\fBpack content \fIwindow\fR
Returns a list of all of the content windows in the packing order for \fIwindow\fR.
The order of the content windows in the list is the same as their order in
the packing order.
If \fIwindow\fR has no content then an empty string is returned.
.TP
\fBpack slaves \fIwindow\fR
.
Synonym for . \fBpack content \fIwindow\fR
.SH "THE PACKER ALGORITHM"
.PP
For each container the packer maintains an ordered list of content
windows called the \fIpacking list\fR.
The \fB\-in\fR, \fB\-after\fR, and \fB\-before\fR configuration
options are used to specify the container for each content and the content's
position in the packing list.
If none of these options is given for a content then the content
is added to the end of the packing list for its parent.
.PP
The packer arranges the content windows for a container by scanning the
packing list in order.
At the time it processes each content, a rectangular area within
the container is still unallocated.
This area is called the \fIcavity\fR;  for the first content it
is the entire area of the container.
.PP
For each content the packer carries out the following steps:
.IP [1]
The packer allocates a rectangular \fIparcel\fR for the content
along the side of the cavity given by the content's \fB\-side\fR option.
If the side is top or bottom then the width of the parcel is
the width of the cavity and its height is the requested height
of the content plus the \fB\-ipady\fR and \fB\-pady\fR options.
For the left or right side the height of the parcel is
the height of the cavity and the width is the requested width
of the content plus the \fB\-ipadx\fR and \fB\-padx\fR options.
The parcel may be enlarged further because of the \fB\-expand\fR
option (see \fBEXPANSION\fR below)
.IP [2]
The packer chooses the dimensions of the content.
The width will normally be the content's requested width plus
twice its \fB\-ipadx\fR option and the height will normally be
the content's requested height plus twice its \fB\-ipady\fR
option.
However, if the \fB\-fill\fR option is \fBx\fR or \fBboth\fR
then the width of the content is expanded to fill the width of the parcel,
minus twice the \fB\-padx\fR option.
If the \fB\-fill\fR option is \fBy\fR or \fBboth\fR
then the height of the content is expanded to fill the width of the parcel,
minus twice the \fB\-pady\fR option.
.IP [3]
The packer positions the content over its parcel.
If the content is smaller than the parcel then the \fB\-anchor\fR
option determines where in the parcel the content will be placed.
If \fB\-padx\fR or \fB\-pady\fR is non-zero, then the given
amount of external padding will always be left between the
content and the edges of the parcel.
.PP
Once a given content has been packed, the area of its parcel
is subtracted from the cavity, leaving a smaller rectangular
cavity for the next content.
If a content does not use all of its parcel, the unused space
in the parcel will not be used by subsequent content.
If the cavity should become too small to meet the needs of
a content then the content will be given whatever space is
left in the cavity.
If the cavity shrinks to zero size, then all remaining content
on the packing list will be unmapped from the screen until
the container window becomes large enough to hold them again.
.SS "EXPANSION"
.PP
If a container window is so large that there will be extra space
left over after all of its content have been packed, then the
extra space is distributed uniformly among all of the content
for which the \fB\-expand\fR option is set.
Extra horizontal space is distributed among the expandable
content whose \fB\-side\fR is \fBleft\fR or \fBright\fR,
and extra vertical space is distributed among the expandable
content whose \fB\-side\fR is \fBtop\fR or \fBbottom\fR.
.SS "GEOMETRY PROPAGATION"
.PP
The packer normally computes how large a container must be to
just exactly meet the needs of its content, and it sets the
requested width and height of the container to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBpack propagate\fR command may be used to
turn off propagation for one or more containers.
If propagation is disabled then the packer will not set
the requested width and height of the packer.
This may be useful if, for example, you wish for a container
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON CONTAINER WINDOWS"
.PP
The container for each content must either be the content's parent
(the default) or a descendant of the content's parent.
This restriction is necessary to guarantee that the
content can be placed over any part of its container that is
visible without danger of the content being clipped by its parent.
.SH "PACKING ORDER"
.PP
If the container for a content is not its parent then you must make sure
that the content is higher in the stacking order than the container.
Otherwise the container will obscure the content and it will appear as
if the content has not been packed correctly.
The easiest way to make sure the content is higher than the container is
to create the container window first:  the most recently created window
will be highest in the stacking order.
Or, you can use the \fBraise\fR and \fBlower\fR commands to change
the stacking order of either the container or the content.
.SH EXAMPLE
.PP
.CS
# Make the widgets
label .t \-text "This widget is at the top"    \-bg red
label .b \-text "This widget is at the bottom" \-bg green
label .l \-text "Left\enHand\enSide"
label .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
\fBpack\fR .t   \-side top    \-fill x
\fBpack\fR .b   \-side bottom \-fill x
\fBpack\fR .l   \-side left   \-fill y
\fBpack\fR .r   \-side right  \-fill y
\fBpack\fR .mid \-expand 1    \-fill both
.CE

.SH "SEE ALSO"
grid(n), place(n)

.SH KEYWORDS
geometry manager, location, packer, parcel, propagation, size
'\" Local Variables:
'\" mode: nroff
'\" End:






|









>








|





|
|

|







|
|



|





|
|


|
|





|
|




|



|



|



|


|
|
|



|





|




|





|




|




|


|

|




|
|
|
|
<
<
<
<
<
<
<
<

|

|


|
|

|

|


|



|


|
|
|

|
<
<
<
<


|
|

|

|


|

|
|
|
|

|

|
|


|


|



|
|

|


|


|


|
|
|


|

|

|
|
|

|

|

|


|
|
|


|

|


|
|
|




|


|

|

|
|

|
|


|
|
|
|
|
|


|

<















>


>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132








133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158




159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282



'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH pack n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pack \- Geometry manager that packs around edges of cavity
.SH SYNOPSIS
\fBpack \fIoption arg \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBpack\fR command is used to communicate with the packer,
a geometry manager that arranges the children of a parent by
packing them in order around the edges of the parent.
The \fBpack\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBpack \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
If the first argument to \fBpack\fR is a window name (any value
starting with
.QW . ),
then the command is processed in the same way as \fBpack configure\fR.
.TP
\fBpack configure \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
The arguments consist of the names of one or more slave windows
followed by pairs of arguments that specify how
to manage the slaves.
See \fBTHE PACKER ALGORITHM\fR below for details on how the options
are used by the packer.
The following options are supported:
.RS
.TP
\fB\-after \fIother\fR
\fIOther\fR must the name of another window.
Use its master as the master for the slaves, and insert
the slaves just after \fIother\fR in the packing order.
.TP
\fB\-anchor \fIanchor\fR
\fIAnchor\fR must be a valid anchor position such as \fBn\fR
or \fBsw\fR; it specifies where to position each slave in its
parcel.
Defaults to \fBcenter\fR.
.TP
\fB\-before \fIother\fR
\fIOther\fR must the name of another window.
Use its master as the master for the slaves, and insert
the slaves just before \fIother\fR in the packing order.
.TP
\fB\-expand \fIboolean\fR
Specifies whether the slaves should be expanded to consume
extra space in their master.
\fIBoolean\fR may have any proper boolean value, such as \fB1\fR
or \fBno\fR.
Defaults to 0.
.TP
\fB\-fill \fIstyle\fR
If a slave's parcel is larger than its requested dimensions, this
option may be used to stretch the slave.
\fIStyle\fR must have one of the following values:
.RS
.TP
\fBnone\fR
Give the slave its requested dimensions plus any internal padding
requested with \fB\-ipadx\fR or \fB\-ipady\fR.  This is the default.
.TP
\fBx\fR
Stretch the slave horizontally to fill the entire width of its
parcel (except leave external padding as specified by \fB\-padx\fR).
.TP
\fBy\fR
Stretch the slave vertically to fill the entire height of its
parcel (except leave external padding as specified by \fB\-pady\fR).
.TP
\fBboth\fR
Stretch the slave both horizontally and vertically.
.RE
.TP
\fB\-in \fIother\fR
Insert the slave(s) at the end of the packing order for the master
window given by \fIother\fR.
.TP
\fB\-ipadx \fIamount\fR
\fIAmount\fR specifies how much horizontal internal padding to
leave on each side of the slave(s).
\fIAmount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR
\fIAmount\fR specifies how much vertical internal padding to
leave on each side of the slave(s).
\fIAmount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR
\fIAmount\fR specifies how much horizontal external padding to
leave on each side of the slave(s).  \fIAmount\fR may be a list
of two values to specify padding for left and right separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-pady \fIamount\fR
\fIAmount\fR specifies how much vertical external padding to
leave on each side of the slave(s).  \fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-side \fIside\fR
Specifies which side of the master the slave(s) will be packed against.
Must be \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
Defaults to \fBtop\fR.
.LP
If no \fB\-in\fR, \fB\-after\fR or \fB\-before\fR option is specified
then each of the slaves will be inserted at the end of the packing list
for its parent unless it is already managed by the packer (in which
case it will be left where it is).
If one of these options is specified then all the slaves will be
inserted at the specified point.
If any of the slaves are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBpack forget \fIslave \fR?\fIslave ...\fR?
Removes each of the \fIslave\fRs from the packing order for its
master and unmaps their windows.
The slaves will no longer be managed by the packer.








.TP
\fBpack info \fIslave\fR
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fImaster\fR"
where \fImaster\fR is the slave's master.
.TP
\fBpack propagate \fImaster\fR ?\fIboolean\fR?
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fImaster\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fImaster\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fImaster\fR.
Propagation is enabled by default.
.TP
\fBpack slaves \fImaster\fR
Returns a list of all of the slaves in the packing order for \fImaster\fR.
The order of the slaves in the list is the same as their order in
the packing order.
If \fImaster\fR has no slaves then an empty string is returned.




.SH "THE PACKER ALGORITHM"
.PP
For each master the packer maintains an ordered list of slaves
called the \fIpacking list\fR.
The \fB\-in\fR, \fB\-after\fR, and \fB\-before\fR configuration
options are used to specify the master for each slave and the slave's
position in the packing list.
If none of these options is given for a slave then the slave
is added to the end of the packing list for its parent.
.PP
The packer arranges the slaves for a master by scanning the
packing list in order.
At the time it processes each slave, a rectangular area within
the master is still unallocated.
This area is called the \fIcavity\fR;  for the first slave it
is the entire area of the master.
.PP
For each slave the packer carries out the following steps:
.IP [1]
The packer allocates a rectangular \fIparcel\fR for the slave
along the side of the cavity given by the slave's \fB\-side\fR option.
If the side is top or bottom then the width of the parcel is
the width of the cavity and its height is the requested height
of the slave plus the \fB\-ipady\fR and \fB\-pady\fR options.
For the left or right side the height of the parcel is
the height of the cavity and the width is the requested width
of the slave plus the \fB\-ipadx\fR and \fB\-padx\fR options.
The parcel may be enlarged further because of the \fB\-expand\fR
option (see \fBEXPANSION\fR below)
.IP [2]
The packer chooses the dimensions of the slave.
The width will normally be the slave's requested width plus
twice its \fB\-ipadx\fR option and the height will normally be
the slave's requested height plus twice its \fB\-ipady\fR
option.
However, if the \fB\-fill\fR option is \fBx\fR or \fBboth\fR
then the width of the slave is expanded to fill the width of the parcel,
minus twice the \fB\-padx\fR option.
If the \fB\-fill\fR option is \fBy\fR or \fBboth\fR
then the height of the slave is expanded to fill the width of the parcel,
minus twice the \fB\-pady\fR option.
.IP [3]
The packer positions the slave over its parcel.
If the slave is smaller than the parcel then the \fB\-anchor\fR
option determines where in the parcel the slave will be placed.
If \fB\-padx\fR or \fB\-pady\fR is non-zero, then the given
amount of external padding will always be left between the
slave and the edges of the parcel.
.PP
Once a given slave has been packed, the area of its parcel
is subtracted from the cavity, leaving a smaller rectangular
cavity for the next slave.
If a slave does not use all of its parcel, the unused space
in the parcel will not be used by subsequent slaves.
If the cavity should become too small to meet the needs of
a slave then the slave will be given whatever space is
left in the cavity.
If the cavity shrinks to zero size, then all remaining slaves
on the packing list will be unmapped from the screen until
the master window becomes large enough to hold them again.
.SS "EXPANSION"
.PP
If a master window is so large that there will be extra space
left over after all of its slaves have been packed, then the
extra space is distributed uniformly among all of the slaves
for which the \fB\-expand\fR option is set.
Extra horizontal space is distributed among the expandable
slaves whose \fB\-side\fR is \fBleft\fR or \fBright\fR,
and extra vertical space is distributed among the expandable
slaves whose \fB\-side\fR is \fBtop\fR or \fBbottom\fR.
.SS "GEOMETRY PROPAGATION"
.PP
The packer normally computes how large a master must be to
just exactly meet the needs of its slaves, and it sets the
requested width and height of the master to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBpack propagate\fR command may be used to
turn off propagation for one or more masters.
If propagation is disabled then the packer will not set
the requested width and height of the packer.
This may be useful if, for example, you wish for a master
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON MASTER WINDOWS"
.PP
The master for each slave must either be the slave's parent
(the default) or a descendant of the slave's parent.
This restriction is necessary to guarantee that the
slave can be placed over any part of its master that is
visible without danger of the slave being clipped by its parent.
.SH "PACKING ORDER"
.PP
If the master for a slave is not its parent then you must make sure
that the slave is higher in the stacking order than the master.
Otherwise the master will obscure the slave and it will appear as
if the slave has not been packed correctly.
The easiest way to make sure the slave is higher than the master is
to create the master window first:  the most recently created window
will be highest in the stacking order.
Or, you can use the \fBraise\fR and \fBlower\fR commands to change
the stacking order of either the master or the slave.
.SH EXAMPLE

.CS
# Make the widgets
label .t \-text "This widget is at the top"    \-bg red
label .b \-text "This widget is at the bottom" \-bg green
label .l \-text "Left\enHand\enSide"
label .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
\fBpack\fR .t   \-side top    \-fill x
\fBpack\fR .b   \-side bottom \-fill x
\fBpack\fR .l   \-side left   \-fill y
\fBpack\fR .r   \-side right  \-fill y
\fBpack\fR .mid \-expand 1    \-fill both
.CE

.SH "SEE ALSO"
grid(n), place(n)

.SH KEYWORDS
geometry manager, location, packer, parcel, propagation, size



Changes to doc/palette.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
'\"
'\" 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.
'\"
.TH tk_setPalette n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_setPalette, tk_bisque \- Modify the Tk color palette
.SH SYNOPSIS
\fBtk_setPalette \fIbackground\fR
.sp
\fBtk_setPalette \fIname value \fR?\fIname value ...\fR?
.sp
\fBtk_bisque\fR
.BE

.SH DESCRIPTION
.PP
The \fBtk_setPalette\fR procedure changes the color scheme for Tk.
It does this by modifying the colors of existing widgets and by changing
the option database so that future widgets will use the new color scheme.
If \fBtk_setPalette\fR is invoked with a single argument, the
argument is the name of a color to use as the normal background





|













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
'\"
'\" 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.
'\" 
.TH tk_setPalette n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_setPalette, tk_bisque \- Modify the Tk color palette
.SH SYNOPSIS
\fBtk_setPalette \fIbackground\fR
.sp
\fBtk_setPalette \fIname value \fR?\fIname value ...\fR?
.sp
\fBtk_bisque\fR
.BE

.SH DESCRIPTION
.PP
The \fBtk_setPalette\fR procedure changes the color scheme for Tk.
It does this by modifying the colors of existing widgets and by changing
the option database so that future widgets will use the new color scheme.
If \fBtk_setPalette\fR is invoked with a single argument, the
argument is the name of a color to use as the normal background
62
63
64
65
66
67
68

69
70
71
72
73
from the .Xdefaults file or options specified on the command-line
that creates a widget.
.PP
The procedure \fBtk_bisque\fR is provided for backward compatibility:
it restores the application's colors to the light brown
.PQ bisque
color scheme used in Tk 3.6 and earlier versions.

.SH KEYWORDS
bisque, color, palette
'\" Local Variables:
'\" mode: nroff
'\" End:







>


<
<
<
63
64
65
66
67
68
69
70
71
72



from the .Xdefaults file or options specified on the command-line
that creates a widget.
.PP
The procedure \fBtk_bisque\fR is provided for backward compatibility:
it restores the application's colors to the light brown
.PQ bisque
color scheme used in Tk 3.6 and earlier versions.

.SH KEYWORDS
bisque, color, palette



Changes to doc/panedwindow.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52



53
54
55
56
57
58
59
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH panedwindow n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
panedwindow \- Create and manipulate 'panedwindow' split container widgets
.SH SYNOPSIS
\fBpanedwindow\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-orient	\-relief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-handlepad handlePad HandlePad
When sash handles are drawn, specifies the distance from the top or
left end of the sash (depending on the orientation of the widget) at
which to draw the handle.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-handlesize handleSize HandleSize
Specifies the side length of a sash handle.  Handles are always
drawn as squares.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-height height Height
Specifies a desired height for the overall panedwindow widget. May be any
value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be
made high enough to allow all contained widgets to have their natural height.
.OP \-opaqueresize opaqueResize OpaqueResize
Specifies whether panes should be resized as a sash is moved (true),
or if resizing should be deferred until the sash is placed (false).
In the latter case, a
.QW ghost
version of the sash is displayed during the resizing to show where the
panes will be resized to when releasing the mouse button. This
.QW ghost
version of the sash is the proxy. It's rendering can be configured
using the \fB-proxybackground\fR, \fB-proxyborderwidth\fR and
\fB-proxyrelief\fR options.
.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB-sashrelief\fR
option will be used.



.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May
be any value accepted by \fBTk_GetPixels\fR.






|





|


















<
<
<
<
<
<
<
<
<
<
<










>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31











32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH panedwindow n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
panedwindow \- Create and manipulate panedwindow widgets
.SH SYNOPSIS
\fBpanedwindow\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-orient	\-relief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-handlepad handlePad HandlePad
When sash handles are drawn, specifies the distance from the top or
left end of the sash (depending on the orientation of the widget) at
which to draw the handle.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-handlesize handleSize HandleSize
Specifies the side length of a sash handle.  Handles are always
drawn as squares.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-height height Height
Specifies a desired height for the overall panedwindow widget. May be any
value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be
made high enough to allow all contained widgets to have their natural height.











.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB-sashrelief\fR
option will be used.
.OP \-opaqueresize opaqueResize OpaqueResize
Specifies whether panes should be resized as a sash is moved (true),
or if resizing should be deferred until the sash is placed (false).
.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May
be any value accepted by \fBTk_GetPixels\fR.
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143






144


145

































146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
.SH "WIDGET COMMAND"
.PP
The \fBpanedwindow\fR command creates a new Tcl command whose name is
the same as the path name of the panedwindow's window.  This command
may be used to invoke various operations on the widget.  It has the
following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
.
Add one or more windows to the panedwindow, each in a separate pane.
The arguments consist of the names of one or more windows
followed by pairs of arguments that specify how to manage the windows.
\fIOption\fR may have any of the values accepted by the
\fBconfigure\fR subcommand.
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given by
\fIoption\fR.  \fIOption\fR may have any of the values accepted by the
\fBpanedwindow\fR command.
.TP
\fIpathName \fBconfigure \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. \fIOption\fR may have
any of the values accepted by the \fBpanedwindow\fR command.
.TP
\fIpathName \fBforget \fIwindow \fR?\fIwindow ...\fR?
.
Remove the pane containing \fIwindow\fR from the panedwindow.  All
geometry management options for \fIwindow\fR will be forgotten.
.TP
\fIpathName \fBidentify \fIx y\fR
.
Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.
.TP






\fIpathName \fBpanecget \fIwindow option\fR


.

































Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.
.TP
\fIpathName \fBpaneconfigure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the management options for \fIwindow\fR.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.  The following options
are supported:
.RS
.TP
\fB\-after \fIwindow\fR
.
Insert the window after the window specified.  \fIwindow\fR should be the
name of a window already managed by \fIpathName\fR.
.TP
\fB\-before \fIwindow\fR
.
Insert the window before the window specified.  \fIwindow\fR should be
the name of a window already managed by \fIpathName\fR.
.TP
\fB\-height \fIsize\fR
.
Specify a height for the window.  The height will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-height\fR is not specified, then the
height requested internally by the window will be used initially; the
height may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.TP
\fB\-hide \fIboolean\fR
.
Controls the visibility of a pane.  When the \fIboolean\fR is true
(according to \fBTcl_GetBoolean\fR) the pane will not be visible, but
it will still be maintained in the list of panes.

.TP
\fB\-minsize \fIn\fR
.
Specifies that the size of the window cannot be made less than
\fIn\fR.  This constraint only affects the size of the widget in the
paned dimension \(em the x dimension for horizontal panedwindows, the y
dimension for vertical panedwindows.  May be any value accepted by
\fBTk_GetPixels\fR.
.TP
\fB\-padx \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the X-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.
.TP
\fB\-pady \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the Y-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.
.TP
\fB\-sticky \fIstyle\fR
.
If a window's pane is larger than the requested dimensions of the
window, this option may be used to position (or stretch) the window
within its pane.  \fIStyle\fR  is a string that contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.  The string
can optionally contains spaces or commas, but they are ignored.  Each
letter refers to a side (north, south, east, or west) that the window
will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR)
are specified, the window will be stretched to fill the entire height
(or width) of its cavity.
.TP
\fB\-stretch \fIwhen\fR
.
Controls how extra space is allocated to each of the panes.
\fIWhen\fR is one of \fBalways\fR, \fBfirst\fR, \fBlast\fR,
\fBmiddle\fR, and \fBnever\fR.
The panedwindow will calculate the required size of all its panes. Any
remaining (or deficit) space will be distributed to those panes marked
for stretching. The space will be distributed based on each panes
current ratio of the whole.  The \fIwhen\fR values have the following
definition:
.RS
.TP
\fBalways\fR
.
This pane will always stretch.
.TP
\fBfirst\fR
.
Only if this pane is the first pane (left-most or top-most) will it
stretch.
.TP
\fBlast\fR
.
Only if this pane is the last pane (right-most or bottom-most) will it
stretch.  This is the default value.
.TP
\fBmiddle\fR
.
Only if this pane is not the first or last pane will it stretch.
.TP
\fBnever\fR
.
This pane will never stretch.
.RE

.TP
\fB\-width \fIsize\fR
.
Specify a width for the window.  The width will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-width\fR is not specified, then the
width requested internally by the window will be used initially; the
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE
.TP
\fIpathName \fBpanes\fR
.
Returns an ordered list of the widgets managed by \fIpathName\fR.
.TP
\fIpathName \fBproxy \fR?\fIargs\fR?
.
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS
.TP
\fIpathName \fBproxy coord\fR
.
Return a list containing the x and y coordinates of the most recent
proxy location.
.TP
\fIpathName \fBproxy forget\fR
.
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
.
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.
.RE
.TP
\fIpathName \fBsash \fR?\fIargs\fR?
This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
.
Return the current x and y coordinate pair for the sash given by
\fIindex\fR.  \fIIndex\fR must be an integer between 0 and 1 less than
the number of panes in the panedwindow.  The coordinates given are
those of the top left corner of the region containing the sash.
.TP
\fIpathName \fBsash dragto \fIindex x y\fR
.
This command computes the difference between the given coordinates and the
coordinates given to the last \fBsash mark\fR command for the given
sash.  It then moves that sash the computed difference.  The return
value is the empty string.
.TP
\fIpathName \fBsash mark \fIindex x y\fR
.
Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in
conjunction with later \fBsash dragto\fR commands to move the sash.
.TP
\fIpathName \fBsash place \fIindex x y\fR
.
Place the sash given by \fIindex\fR at the given coordinates.
.RE
.SH "RESIZING PANES"
.PP
A pane is resized by grabbing the sash (or sash handle if present) and
dragging with the mouse.  This is accomplished via mouse motion
bindings on the widget.  When a sash is moved, the sizes of the panes
on each side of the sash, and thus the widgets in those panes, are
adjusted.
.PP
When a pane is resized from outside (e.g. it is packed to expand and
fill, and the containing toplevel is resized), space is added to the final
(rightmost or bottommost) pane in the window.
.PP
Unlike child windows managed by e.g. pack or grid, the panes managed by a
panedwindow do not change width or height to accommodate changes in the
requested widths or heights of the panes, once these have become mapped.
Therefore it may be advisable, particularly when creating layouts
interactively, to not add a pane to the panedwindow widget until after the
geometry requests of that pane has been finalized (i.e., all components of
the pane inserted, all options affecting geometry set to their proper
values, etc.).
.SH "SEE ALSO"
ttk::panedwindow(n)
.SH KEYWORDS
panedwindow, widget, geometry management
'\" Local Variables:
'\" mode: nroff
'\" End:







|






|
<







<




|
<












|
<




<







>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
<














<




<




<








|



>


<







<

|



<

|



<













|











<



<
|



<
|



<



<


>


<









<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<










|
|










<
<
<
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101

102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195

196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221

222
223
224
225
226

227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259

260
261
262
263

264
265
266
267

268
269
270

271
272
273
274
275

276
277
278
279
280
281
282
283
284

285


















































286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308



.SH "WIDGET COMMAND"
.PP
The \fBpanedwindow\fR command creates a new Tcl command whose name is
the same as the path name of the panedwindow's window.  This command
may be used to invoke various operations on the widget.  It has the
following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.TP
\fIpathName \fBadd \fIwindow ?window ...? ?option value ...?\fR

Add one or more windows to the panedwindow, each in a separate pane.
The arguments consist of the names of one or more windows
followed by pairs of arguments that specify how to manage the windows.
\fIOption\fR may have any of the values accepted by the
\fBconfigure\fR subcommand.
.TP
\fIpathName \fBcget \fIoption\fR

Returns the current value of the configuration option given by
\fIoption\fR.  \fIOption\fR may have any of the values accepted by the
\fBpanedwindow\fR command.
.TP
\fIpathName \fBconfigure \fI?option? ?value option value ...?\fR

Query or modify the configuration options of the widget.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. \fIOption\fR may have
any of the values accepted by the \fBpanedwindow\fR command.
.TP
\fIpathName \fBforget \fIwindow ?window ...?\fR

Remove the pane containing \fIwindow\fR from the panedwindow.  All
geometry management options for \fIwindow\fR will be forgotten.
.TP
\fIpathName \fBidentify \fIx y\fR

Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.
.TP
\fIpathName \fBproxy \fI?args?\fR
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS
.TP
\fIpathName \fBproxy coord\fR
Return a list containing the x and y coordinates of the most recent
proxy location.
.TP
\fIpathName \fBproxy forget\fR
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.  
.RE
.TP
\fIpathName \fBsash \fI?args?\fR
This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
Return the current x and y coordinate pair for the sash given by
\fIindex\fR.  \fIIndex\fR must be an integer between 0 and 1 less than
the number of panes in the panedwindow.  The coordinates given are
those of the top left corner of the region containing the sash.
.TP
\fIpathName \fBsash dragto \fIindex x y\fR
This command computes the difference between the given coordinates and the
coordinates given to the last \fBsash mark\fR command for the given
sash.  It then moves that sash the computed difference.  The return
value is the empty string.
.TP
\fIpathName \fBsash mark \fIindex x y\fR
Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in
conjunction with later \fBsash dragto\fR commands to move the sash.
.TP
\fIpathName \fBsash place \fIindex x y\fR
Place the sash given by \fIindex\fR at the given coordinates.
.RE
.TP
\fIpathName \fBpanecget \fIwindow option\fR
Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.
.TP
\fIpathName \fBpaneconfigure \fIwindow ?option? ?value option value ...?\fR

Query or modify the management options for \fIwindow\fR.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.  The following options
are supported:
.RS
.TP
\fB\-after \fIwindow\fR

Insert the window after the window specified.  \fIwindow\fR should be the
name of a window already managed by \fIpathName\fR.
.TP
\fB\-before \fIwindow\fR

Insert the window before the window specified.  \fIwindow\fR should be
the name of a window already managed by \fIpathName\fR.
.TP
\fB\-height \fIsize\fR

Specify a height for the window.  The height will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-height\fR is not specified, then the
height requested internally by the window will be used initially; the
height may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.TP
\fB\-hide \fIboolean\fR
.VS 8.5
Controls the visibility of a pane.  When the \fIboolean\fR is true
(according to \fBTcl_GetBoolean\fR) the pane will not be visible, but
it will still be maintained in the list of panes.
.VE 8.5
.TP
\fB\-minsize \fIn\fR

Specifies that the size of the window cannot be made less than
\fIn\fR.  This constraint only affects the size of the widget in the
paned dimension \(em the x dimension for horizontal panedwindows, the y
dimension for vertical panedwindows.  May be any value accepted by
\fBTk_GetPixels\fR.
.TP
\fB\-padx \fIn\fR

Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the X-direction.  The value may 
have any of the forms accepted by \fBTk_GetPixels\fR.
.TP
\fB\-pady \fIn\fR

Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the Y-direction.  The value may 
have any of the forms accepted by \fBTk_GetPixels\fR.
.TP
\fB\-sticky \fIstyle\fR

If a window's pane is larger than the requested dimensions of the
window, this option may be used to position (or stretch) the window
within its pane.  \fIStyle\fR  is a string that contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.  The string
can optionally contains spaces or commas, but they are ignored.  Each
letter refers to a side (north, south, east, or west) that the window
will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR)
are specified, the window will be stretched to fill the entire height
(or width) of its cavity.
.TP
\fB\-stretch \fIwhen\fR
.VS 8.5
Controls how extra space is allocated to each of the panes.
\fIWhen\fR is one of \fBalways\fR, \fBfirst\fR, \fBlast\fR,
\fBmiddle\fR, and \fBnever\fR.
The panedwindow will calculate the required size of all its panes. Any
remaining (or deficit) space will be distributed to those panes marked
for stretching. The space will be distributed based on each panes
current ratio of the whole.  The \fIwhen\fR values have the following
definition:
.RS
.TP
\fBalways\fR

This pane will always stretch.
.TP
\fBfirst\fR

Only if this pane is the first pane (left-most or top-most) will it 
stretch.
.TP
\fBlast\fR

Only if this pane is the last pane (right-most or bottom-most) will it 
stretch.  This is the default value.
.TP
\fBmiddle\fR

Only if this pane is not the first or last pane will it stretch.
.TP
\fBnever\fR

This pane will never stretch.
.RE
.VE 8.5
.TP
\fB\-width \fIsize\fR

Specify a width for the window.  The width will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-width\fR is not specified, then the
width requested internally by the window will be used initially; the
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE
.TP
\fIpathName \fBpanes\fR

Returns an ordered list of the widgets managed by \fIpathName\fR.


















































.SH "RESIZING PANES"

A pane is resized by grabbing the sash (or sash handle if present) and
dragging with the mouse.  This is accomplished via mouse motion
bindings on the widget.  When a sash is moved, the sizes of the panes
on each side of the sash, and thus the widgets in those panes, are
adjusted.
.PP
When a pane is resized from outside (e.g. it is packed to expand and
fill, and the containing toplevel is resized), space is added to the final
(rightmost or bottommost) pane in the window.
.PP
Unlike slave windows managed by e.g. pack or grid, the panes managed by a
panedwindow do not change width or height to accomodate changes in the
requested widths or heights of the panes, once these have become mapped.
Therefore it may be advisable, particularly when creating layouts
interactively, to not add a pane to the panedwindow widget until after the
geometry requests of that pane has been finalized (i.e., all components of
the pane inserted, all options affecting geometry set to their proper
values, etc.).
.SH "SEE ALSO"
ttk::panedwindow(n)
.SH KEYWORDS
panedwindow, widget, geometry management



Changes to doc/photo.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311






312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
'\"
'\" 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.
'\"
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH photo n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
photo \- Full-color images
.SH SYNOPSIS
.nf
\fBimage create photo \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBblank\fR
\fIimageName \fBcget \fIoption\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
\fIimageName \fBcopy \fIsourceImage\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBget \fIx y\fR ?\fIoption\fR?
\fIimageName \fBput \fIdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBread \fIfilename\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBredither\fR
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.fi
.BE

.SH DESCRIPTION
.PP
A photo is an image whose pixels can display any color with a varying
degree of transparency (the alpha channel). A photo image is stored
internally in full color (32 bits per pixel), and is displayed using
dithering if necessary.  Image data for a photo image can be obtained
from a file or a string, or it can be supplied from C code through a
procedural interface.  At present, only
.VS 8.6
PNG,
.VE 8.6
GIF and PPM/PGM formats are supported, but an interface exists to
allow additional image file formats to be added easily.  A photo image
is (semi)transparent if the image data it was obtained from had
transparency informaton. In regions where no image data has been
supplied, it is fully transparent. Transparency may also be modified
with the \fBtransparency set\fR subcommand.

.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the image as a string.
.VS 8.7
The string should
contain data in the default list-of-lists form,
.VE 8.7
binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for PNG and GIF images). The
format of the string must be one of those for which there is an image
file format handler that will accept string data.  If both the
\fB\-data\fR and \fB\-file\fR options are specified, the \fB\-file\fR
option takes precedence.
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option and optional arguments passed to
the format handler. Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.
.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.
.TP
\fB\-gamma \fIvalue\fR
.
Specifies that the colors allocated for displaying this image in a
window should be corrected for a non-linear display with the specified
gamma exponent value.  (The intensity produced by most
CRT displays is a power function of the input value, to a good
approximation; gamma is the exponent and is typically around 2).
The value specified must be greater than zero.  The default
value is one (no correction).  In general, values greater than one
will make the image lighter, and values less than one will make it
darker.
.TP
\fB\-height \fInumber\fR
.
Specifies the height of the image, in pixels.  This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink vertically to fit the data stored in it.
.TP
\fB\-palette \fIpalette-spec\fR
.
Specifies the resolution of the color cube to be allocated for
displaying this image, and thus the number of colors used from the
colormaps of the windows where it is displayed.  The
\fIpalette-spec\fR string may be either a single decimal number,
specifying the number of shades of gray to use, or three decimal
numbers separated by slashes (/), specifying the number of shades of
red, green and blue to use, respectively.  If the first form (a single
number) is used, the image will be displayed in monochrome (i.e.,
grayscale).
.TP
\fB\-width \fInumber\fR
.
Specifies the width of the image, in pixels.    This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink horizontally to fit the data stored in it.
.SH "IMAGE COMMAND"
.PP
When a photo image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Those options that write data to the image generally expand the size
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the
\fB\-width\fR and/or \fB\-height\fR configuration options, in which
case the width and/or height, respectively, of the image will not be
changed.
.PP
The following commands are possible for photo images:
.TP
\fIimageName \fBblank\fR
.
Blank the image; that is, set the entire image to have no data, so it
will be displayed as transparent, and the background of whatever
window it is displayed in will show through.
.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
.TP
\fIimageName \fBcopy\fR \fIsourceImage\fR ?\fIoption value(s) ...\fR?
.
Copies a region from the image called \fIsourceImage\fR (which must
be a photo image) to the image called \fIimageName\fR, possibly with
pixel zooming and/or subsampling.  If no options are specified, this
command copies the whole of \fIsourceImage\fR into \fIimageName\fR,
starting at coordinates (0,0) in \fIimageName\fR.  The following
options may be specified:
.RS
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the source image to be copied.
(\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite corners of
the rectangle.  If \fIx2\fR and \fIy2\fR are not specified, the
default value is the bottom-right corner of the source image.  The
pixels copied will include the left and top edges of the specified
rectangle but not the bottom or right edges.  If the \fB\-from\fR
option is not given, the default is the whole source image.
.TP
\fB\-to \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the destination image to be
affected.  (\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite
corners of the rectangle.  If \fIx2\fR and \fIy2\fR are not specified,
the default value is (\fIx1,y1\fR) plus the size of the source
region (after subsampling and zooming, if specified).  If \fIx2\fR and
\fIy2\fR are specified, the source region will be replicated if
necessary to fill the destination region in a tiled fashion.
.TP
\fB\-shrink\fR
.
Specifies that the size of the destination image should be reduced, if
necessary, so that the region being copied into is at the bottom-right
corner of the image.  This option will not affect the width or height
of the image if the user has specified a non-zero value for the
\fB\-width\fR or \fB\-height\fR configuration option, respectively.
.TP
\fB\-zoom \fIx y\fR
.
Specifies that the source region should be magnified by a factor of
\fIx\fR in the X direction and \fIy\fR in the Y direction.  If \fIy\fR
is not given, the default value is the same as \fIx\fR.  With this
option, each pixel in the source image will be expanded into a block
of \fIx\fR x \fIy\fR pixels in the destination image, all the same
color.  \fIx\fR and \fIy\fR must be greater than 0.
.TP
\fB\-subsample \fIx y\fR
.
Specifies that the source image should be reduced in size by using
only every \fIx\fRth pixel in the X direction and \fIy\fRth pixel in
the Y direction.  Negative values will cause the image to be flipped
about the Y or X axes, respectively.  If \fIy\fR is not given, the
default value is the same as \fIx\fR.
.TP
\fB\-compositingrule \fIrule\fR
.
Specifies how transparent pixels in the source image are combined with
the destination image.  When a compositing rule of \fIoverlay\fR is
set, the old contents of the destination image are visible, as if the
source image were printed on a piece of transparent film and placed
over the top of the destination.  When a compositing rule of \fIset\fR
is set, the old contents of the destination image are discarded and
the source image is used as-is.  The default compositing rule is
\fIoverlay\fR.
.RE
.TP
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
.
Returns image data in the form of a string.
.VS 8.7
The format of the string depends on the format handler. By default, a
human readable format as a list of lists of pixel data is used, other
formats can be chosen with the \fB-format\fR option.
See \fBIMAGE FORMATS\fR below for details.
.VE 8.7
The following options may be specified:
.RS
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to use and,
optionally, arguments to the format handler.  Specifically, this
subcommand searches for the first handler whose name matches an
initial substring of \fIformat-name\fR and which has the capability to
write a string containing this image data.
.VS 8.7
If this option is not given, this subcommand uses the default format
that consists of a list (one element per row) of lists (one element
per pixel/column) of colors in
.QW \fB#\fIrrggbb\fR
format (see \fBIMAGE FORMATS\fR below).
.VE 8.7
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.

.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be returned.
If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region, including x1,y1
and excluding x2,y2.  The default, if this option is not given, is the
whole image.
.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE
.VS 8.7
.TP
\fIimageName \fBget\fR \fIx y\fR ?\fB-withalpha\fR?
.
Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively. If the \fB-withalpha\fR
option is specified, the returned list will have a fourth element
representing the alpha value of the pixel as an integer between 0 and
255.
.VE 8.7
.TP
\fIimageName \fBput\fR \fIdata\fR ?\fIoption value(s) ...\fR?
.
Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR.
.VS 8.7
This command searches the list of image file format handlers for
a handler that can interpret the data in \fIdata\fR, and then reads
the image encoded within into \fIimageName\fR (the destination image).
See \fBIMAGE FORMATS\fR below for details on formats for image data.
.VE 8.7






The following options may be specified:
.RS
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIdata\fR and, optionally,
arguments to be passed to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.
.TP
\fB\-to \fIx1 y1\fR ?\fIx2 y2\fR?
.
Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR)
of the region of \fIimageName\fR into which the image data will be
copied.  The default position is (0,0).  If \fIx2\fR,\fIy2\fR is given
and \fIdata\fR is not large enough to cover the rectangle specified by
this option, the image data extracted will be tiled so it covers the
entire destination rectangle. If the region specified with this opion
is smaller than the supplied \fIdata\fR, the exceeding data is silently
discarded. Note that if \fIdata\fR specifies a
single color value, then a region extending to the bottom-right corner
represented by (\fIx2\fR,\fIy2\fR) will be filled with that color.
.RE
.TP
\fIimageName \fBread\fR \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Reads image data from the file named \fIfilename\fR into the image.
This command first searches the list of
image file format handlers for a handler that can interpret the data
in \fIfilename\fR, and then reads the image in \fIfilename\fR into
\fIimageName\fR (the destination image).  The following options may be
specified:
.RS
.TP
\fB\-format {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIfilename\fR and,
optionally, additional options to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
specified, they specify diagonally opposite corners or the region.
The default, if this option is not specified, is the whole of the
image in the image file.
.TP
\fB\-shrink\fR
.
If this option, the size of \fIimageName\fR will be reduced, if
necessary, so that the region into which the image file data are read
is at the bottom-right corner of the \fIimageName\fR.  This option
will not affect the width or height of the image if the user has
specified a non-zero value for the \fB\-width\fR or \fB\-height\fR
configuration option, respectively.
.TP
\fB\-to \fIx y\fR
.
Specifies the coordinates of the top-left corner of the region of
\fIimageName\fR into which data from \fIfilename\fR are to be read.
The default is (0,0).
.RE
.TP
\fIimageName \fBredither\fR
.
The dithering algorithm used in displaying photo images propagates
quantization errors from one pixel to its neighbors.
If the image data for \fIimageName\fR is supplied in pieces, the
dithered image may not be exactly correct.  Normally the difference is
not noticeable, but if it is a problem, this command can be used to
recalculate the dithered image in each window where the image is
displayed.
.TP
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
.
Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS
.VS 8.7
.TP
\fIimageName \fBtransparency get \fIx y\fR ?\fB-alpha\fR?
.
Returns true if the pixel at (\fIx\fR,\fIy\fR) is fully transparent,
false otherwise.  If the option \fB-alpha\fR is passed, returns the
alpha value of the pixel instead, as an integer in the range 0 to 255.
.VE 8.7

.VS 8.7
.TP
\fIimageName \fBtransparency set \fIx y\fR \fInewVal\fR ?\fB-alpha\fR?
.
Change the transparency of the pixel at (\fIx\fR,\fIy\fR) to
\fInewVal.\fR If no additional option is passed, \fInewVal\fR is
interpreted as a boolean and the pixel is made fully transparent if
that value is true, fully opaque otherwise.  If the \fB-alpha\fR
option is passed, \fInewVal\fR is interpreted as an integral alpha
value for the pixel, which must be in the range 0 to 255.
.VE 8.7
.RE
.TP
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Writes image data from \fIimageName\fR to a file named \fIfilename\fR.
The following options may be specified:
.RS
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to be used to
write the data to the file and, optionally, options to pass to the
format handler.  Specifically, this subcommand searches for the first
handler whose name matches an initial substring of \fIformat-name\fR
and which has the capability to write an image file.  If this option
is not given, the format is guessed from the file extension. If that
cannot be determined, this subcommand uses the first handler that has
the capability to write an image file.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be written to the
image file.  If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region.  The default,
if this option is not given, is the whole image.
.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
standard Tk distribution comes with handlers for PPM/PGM, PNG and GIF
formats,
.VS 8.7
as well as the \fBdefault\fR handler to encode/decode image
data in a human readable form.
.VE 8.7
These handlers are automatically registered on initialization.
.PP
When reading an image file or processing string data specified with
the \fB\-data\fR configuration option, the photo image code invokes

each handler in turn until one is found that claims to be able to read
the data in the file or string.  Usually this will find the correct
handler, but if it does not, the user may give a format name with the
\fB\-format\fR option to specify which handler to use.  In this case,
the photo image code will try those handlers whose names begin with
the string specified for the \fB\-format\fR option (the comparison is
case-insensitive).  For example, if the user specifies \fB\-format
gif\fR, then a handler named GIF87 or GIF89 may be invoked, but a
handler named JPEG may not (assuming that such handlers had been
registered).
.PP
When writing image data to a file, the processing of the
\fB\-format\fR option is slightly different: the string value given
for the \fB\-format\fR option must begin with the complete name of the
requested handler, and may contain additional information following
that, which the handler can use, for example, to specify which variant
to use of the formats supported by the handler.
Note that not all image handlers may support writing transparency data
to a file, even where the target image format does.
.VS 8.7
.SS "THE DEFAULT IMAGE HANDLER"
.PP
The \fBdefault\fR image handler cannot be used to read or write data
from/to a file. Its sole purpose is to encode and decode image data in
string form in a clear text, human readable, form. The \fIimageName\fR
\fBdata\fR subcommand uses this handler when no other format is
specified. When reading image data from a string with \fIimageName\fR
\fBput\fR or the \fB-data\fR option, the default handler is treated
as the other handlers.
.PP
Image data in the \fBdefault\fR string format is a (top-to-bottom)
list of scan-lines, with each scan-line being a (left-to-right) list
of pixel data. Every scan-line has the same length. The color
and, optionally, alpha value of each pixel is specified in any of
the forms described in the \fBCOLOR FORMATS\fR section below.
.VE 8.7

.SS "FORMAT SUBOPTIONS"
.PP
.VS 8.6
Image formats may support sub-options, wich ahre specified using
additional words in the value to the \fB\-format\fR option. These
suboptions can affect how image data is read or written to file or
string. The nature and values of these options is up to the format
handler.
The built-in handlers support these suboptions:
.VS 8.7
.TP
\fBdefault \-colorformat\fI formatType\fR
.
The option is allowed when writing image data to a string with
\fIimageName\fR \fBdata\fR. Specifies the format to use for the color
string of each pixel. \fIformatType\fR may be one of: \fBrgb\fR to
encode pixel data in the form \fB#\fIRRGGBB\fR, \fBrgba\fR to encode
pixel data in the form \fB#\fIRRGGBBAA\fR or \fBlist\fR to encode
pixel data as a list with four elements. See \fBCOLOR FORMATS\fR
below for details. The default is \fBrgb\fR.
.VE 8.7
.TP
\fBgif \-index\fI indexValue\fR
.
The option has effect when reading image data from a file. When
parsing a multi-part GIF image, Tk normally only accesses the first
image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th
value may be used instead. The \fIindexValue\fR must be an integer
from 0 up to the number of image parts in the GIF data.
.TP
\fBpng \-alpha\fI alphaValue\fR
.
The option has effect when reading image data from a file. Specifies
an additional alpha filtering for the overall image, which allows the
background on which the image is displayed to show through.  This
usually also has the effect of desaturating the image.  The
\fIalphaValue\fR must be between 0.0 and 1.0.
.TP
\fBsvg \-dpi\fI dpiValue\fB \-scale\fI scaleValue\fB \-scaletowidth \fI width\fB \-scaletoheight\fI height\fR
.
\fIdpiValue\fR is used in conversion between given coordinates and
screen resolution. The value must be greater than 0 and the default
value is 96.
\fIscaleValue\fR is used to scale the resulting image. The value must
be greater than 0 and the default value is 1.
\fIwidth\fR and \fIheight\fR are the width or height that the image
will be adjusted to. Only one parameter among \fB\-scale\fR,
\fB\-scaletowidth\fR and \fB\-scaletoheight\fR can be given at a time
and the aspect ratio of the original image is always preserved.
The svg format supports a wide range of SVG features, but the
full SVG standard is not available, for instance the 'text' feature
is missing and silently ignored when reading the SVG data.
The supported SVG features are:
.
.RS
\fB elements:\fR g, path, rect, circle, ellipse, line, polyline, polygon,
linearGradient, radialGradient, stop, defs, svg, style
.PP
\fB attributes:\fR width, height, viewBox,
preserveAspectRatio with none, xMin, xMid, xMax, yMin, yMid, yMax, slice
.PP
\fB gradient attributes:\fR gradientUnits with objectBoundingBox,
gradientTransform, cx, cy, r fx, fy x1, y1, x2, y2
spreadMethod with pad, reflect or repeat,
xlink:href
.PP
\fB poly attributes: \fR points
.PP
\fB line attributes: \fR x1, y1, x2, y2
.PP
\fB ellipse attributes: \fR cx, cy, rx, ry
.PP
\fB circle attributes: \fR cx, cy, r
.PP
\fB rectangle attributes: \fR x, y, width, height, rx, ry
.PP
\fB path attributes: \fR d with m, M, l, L, h, H, v, V, c, C, s, S, q, Q, t, T, a, A, z, Z
.PP
\fB style attributes: \fR display with none, visibility, hidden, visible,
fill with nonzero and evenodd, opacity, fill-opacity,
stroke, stroke-width, stroke-dasharray, stroke-dashoffset, stroke-opacity,
stroke-linecap with butt, round and square,
stroke-linejoin with miter, round and  bevel, stroke-miterlimit
fill-rule, font-size,
transform with matrix, translate, scale, rotate, skewX and  skewY,
stop-color, stop-opacity, offset, id, class
.RE
.
Currently only SVG images reading and conversion into (pixel-based
format) photos is supported: Tk does not (yet) support bundling photo
images in SVG vector graphics.
.VE 8.6
.VS 8.7
.SH "COLOR FORMATS"
.PP
The default image handler can represent/parse color and alpha values
of a pixel in one of the formats listed below. If a color format does
not contain transparency information, full opacity is assumed.  The
available color formats are:
.IP \(bu 3
The empty string - interpreted as full transparency, the color value
is undefined.
.IP \(bu 3
Any value accepted by \fBTk_GetColor\fR, optionally followed by an
alpha suffix. The alpha suffix may be one of:
.RS
.TP
\fB@\fR\fIA\fR
.
The alpha value \fIA\fR must be a fractional value in the range  0.0
(fully transparent) to 1.0 (fully opaque).
.TP
\fB#\fR\fIX\fR
.
The alpha value \fIX\fR is a hexadecimal digit that specifies an integer
alpha value in the range 0 (fully transparent) to 255 (fully opaque).
This is expanded in range from 4 bits wide to 8 bits wide by
multiplication by 0x11.
.TP
\fB#\fR\fIXX\fR
.
The alpha value \fIXX\fR is passed as two hexadecimal digits that
specify an integer alpha value in the range 0 (fully transparent) to 255
(fully opaque).
.RE
.IP \(bu 3
A Tcl list with three or four integers in the range 0 to 255,
specifying the values for the red, green, blue and (optionally)
alpha channels respectively.
.IP \(bu 3
\fB#\fR\fIRGBA\fR format: a \fB#\fR followed by four hexadecimal digits,
where each digit is the value for the red, green, blue and alpha
channels respectively. Each digit will be expanded internally to
8 bits by multiplication by 0x11.
.IP \(bu 3
\fB#\fR\fIRRGGBBAA\fR format: \fB#\fR followed by eight hexadecimal digits,
where each pair of  subsequent digits represents the value for the red,
green, blue and alpha channels respectively.
.VE 8.7
.SH "COLOR ALLOCATION"
.PP
When a photo image is displayed in a window, the photo image code
allocates colors to use to display the image and dithers the image, if
necessary, to display a reasonable approximation to the image using
the colors that are available.  The colors are allocated as a color
cube, that is, the number of colors allocated is the product of the






|











<

<
<
<
<
<
<
<
<
<
<
<
<
<

>


|
|
|
|
|
|
<
<
<
|
|
<
|
<
|
>







<
|
<
<
<
<
|
|
|
|
|
|

|
<

|
<
<
<


<





<











<






<











<












|














<





<



|


<











|


<









<









<









<







<








<







<










|
<
|
<
<
<
<
<
<
|



<




|
<
|
|
|
|
|
<
|
|
|

|
<
<
<
<
>


<









<



<

|
<


|
<
<
<
<


<

<
|


<
<
>
>
>
>
>
>
|


|
<
|
<



<
<
<


<





<
<
|





<








|
<
|
<



<
<
<


<









<








<






<








|
<



<

|
<
|
<
<
<
|
<

|
<
|
<
<
|
<
<
<



<





<




|
<

<
|
|
|
<
|
|
<
<
<


<








<









|
<
<
<
<
<
|

|
|
>
|
|
|
|
|
|
|
|
|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19













20
21
22
23
24
25
26
27
28
29



30
31

32

33
34
35
36
37
38
39
40
41

42




43
44
45
46
47
48
49
50

51
52



53
54

55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119

120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173

174
175
176
177
178
179
180
181

182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199

200






201
202
203
204

205
206
207
208
209

210
211
212
213
214

215
216
217
218
219




220
221
222

223
224
225
226
227
228
229
230
231

232
233
234

235
236

237
238
239




240
241

242

243
244
245


246
247
248
249
250
251
252
253
254
255

256

257
258
259



260
261

262
263
264
265
266


267
268
269
270
271
272

273
274
275
276
277
278
279
280
281

282

283
284
285



286
287

288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304

305
306
307
308
309
310

311
312
313
314
315
316
317
318
319

320
321
322

323
324

325



326

327
328

329


330



331
332
333

334
335
336
337
338

339
340
341
342
343

344

345
346
347

348
349



350
351

352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369





370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393





























































































































































394
395
396
397
398
399
400
'\"
'\" 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.
'\" 
'\" Author: Paul Mackerras (paulus@cs.anu.edu.au),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH photo n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
photo \- Full-color images
.SH SYNOPSIS

\fBimage create photo \fR?\fIname\fR? ?\fIoptions\fR?













.BE

.SH DESCRIPTION
.PP
A photo is an image whose pixels can display any color or be
transparent.  A photo image is stored internally in full color (32
bits per pixel), and is displayed using dithering if necessary.  Image
data for a photo image can be obtained from a file or a string, or it
can be supplied from
C code through a procedural interface.  At present, only GIF and PPM/PGM



formats are supported, but an interface exists to allow additional
image file formats to be added easily.  A photo image is transparent

in regions where no image data has been supplied

or where it has been set transparent by the \fBtransparency set\fR
subcommand.
.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:
.TP
\fB\-data \fIstring\fR

Specifies the contents of the image as a string.  The string should




contain binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for GIF images).  The format of the
string must be one of those for which there is an image file format
handler that will accept string data.  If both the \fB\-data\fR
and \fB\-file\fR options are specified, the \fB\-file\fR option takes
precedence.
.TP
\fB\-format \fIformat-name\fR

Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option.



.TP
\fB\-file \fIname\fR

\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.
.TP
\fB\-gamma \fIvalue\fR

Specifies that the colors allocated for displaying this image in a
window should be corrected for a non-linear display with the specified
gamma exponent value.  (The intensity produced by most
CRT displays is a power function of the input value, to a good
approximation; gamma is the exponent and is typically around 2).
The value specified must be greater than zero.  The default
value is one (no correction).  In general, values greater than one
will make the image lighter, and values less than one will make it
darker.
.TP
\fB\-height \fInumber\fR

Specifies the height of the image, in pixels.  This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink vertically to fit the data stored in it.
.TP
\fB\-palette \fIpalette-spec\fR

Specifies the resolution of the color cube to be allocated for
displaying this image, and thus the number of colors used from the
colormaps of the windows where it is displayed.  The
\fIpalette-spec\fR string may be either a single decimal number,
specifying the number of shades of gray to use, or three decimal
numbers separated by slashes (/), specifying the number of shades of
red, green and blue to use, respectively.  If the first form (a single
number) is used, the image will be displayed in monochrome (i.e.,
grayscale).
.TP
\fB\-width \fInumber\fR

Specifies the width of the image, in pixels.    This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink horizontally to fit the data stored in it.
.SH "IMAGE COMMAND"
.PP
When a photo image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Those options that write data to the image generally expand the size
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the
\fB\-width\fR and/or \fB\-height\fR configuration options, in which
case the width and/or height, respectively, of the image will not be
changed.
.PP
The following commands are possible for photo images:
.TP
\fIimageName \fBblank\fR

Blank the image; that is, set the entire image to have no data, so it
will be displayed as transparent, and the background of whatever
window it is displayed in will show through.
.TP
\fIimageName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create photo\fR command.
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create photo\fR command.
.TP
\fIimageName \fBcopy\fR \fIsourceImage\fR ?\fIoption value(s) ...\fR?

Copies a region from the image called \fIsourceImage\fR (which must
be a photo image) to the image called \fIimageName\fR, possibly with
pixel zooming and/or subsampling.  If no options are specified, this
command copies the whole of \fIsourceImage\fR into \fIimageName\fR,
starting at coordinates (0,0) in \fIimageName\fR.  The following
options may be specified:
.RS
.TP
\fB\-from \fIx1 y1 x2 y2\fR

Specifies a rectangular sub-region of the source image to be copied.
(\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite corners of
the rectangle.  If \fIx2\fR and \fIy2\fR are not specified, the
default value is the bottom-right corner of the source image.  The
pixels copied will include the left and top edges of the specified
rectangle but not the bottom or right edges.  If the \fB\-from\fR
option is not given, the default is the whole source image.
.TP
\fB\-to \fIx1 y1 x2 y2\fR

Specifies a rectangular sub-region of the destination image to be
affected.  (\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite
corners of the rectangle.  If \fIx2\fR and \fIy2\fR are not specified,
the default value is (\fIx1,y1\fR) plus the size of the source
region (after subsampling and zooming, if specified).  If \fIx2\fR and
\fIy2\fR are specified, the source region will be replicated if
necessary to fill the destination region in a tiled fashion.
.TP
\fB\-shrink\fR

Specifies that the size of the destination image should be reduced, if
necessary, so that the region being copied into is at the bottom-right
corner of the image.  This option will not affect the width or height
of the image if the user has specified a non-zero value for the
\fB\-width\fR or \fB\-height\fR configuration option, respectively.
.TP
\fB\-zoom \fIx y\fR

Specifies that the source region should be magnified by a factor of
\fIx\fR in the X direction and \fIy\fR in the Y direction.  If \fIy\fR
is not given, the default value is the same as \fIx\fR.  With this
option, each pixel in the source image will be expanded into a block
of \fIx\fR x \fIy\fR pixels in the destination image, all the same
color.  \fIx\fR and \fIy\fR must be greater than 0.
.TP
\fB\-subsample \fIx y\fR

Specifies that the source image should be reduced in size by using
only every \fIx\fRth pixel in the X direction and \fIy\fRth pixel in
the Y direction.  Negative values will cause the image to be flipped
about the Y or X axes, respectively.  If \fIy\fR is not given, the
default value is the same as \fIx\fR.
.TP
\fB\-compositingrule \fIrule\fR

Specifies how transparent pixels in the source image are combined with
the destination image.  When a compositing rule of \fIoverlay\fR is
set, the old contents of the destination image are visible, as if the
source image were printed on a piece of transparent film and placed
over the top of the destination.  When a compositing rule of \fIset\fR
is set, the old contents of the destination image are discarded and
the source image is used as-is.  The default compositing rule is
\fIoverlay\fR.
.RE
.TP
\fIimageName \fBdata ?\fIoption value(s) ...\fR?

Returns image data in the form of a string. The following options






may be specified:
.RS
.TP
\fB\-background\fI color\fR

If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fI format-name\fR

Specifies the name of the image file format handler to be used.
Specifically, this subcommand searches
for the first handler whose name matches an initial substring of
\fIformat-name\fR and which has the capability to write a string
containing this image data.

If this option is not given, this subcommand uses a format that
consists of a list (one element per row) of lists (one element per
pixel/column) of colors in
.QW \fB#\fIrrggbb\fR
format (where \fIrr\fR is a pair of hexadecimal digits for the red




channel, \fIgg\fR for green, and \fIbb\fR for blue).
.TP
\fB\-from \fIx1 y1 x2 y2\fR

Specifies a rectangular region of \fIimageName\fR to be returned.
If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region, including x1,y1
and excluding x2,y2.  The default, if this option is not given, is the
whole image.
.TP
\fB\-grayscale\fR

If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE

.TP
\fIimageName \fBget\fR \fIx y\fR

Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively.




.TP
\fIimageName \fBput\fR \fIdata\fR ?\fIoption value(s) ...\fR?

Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR.

This command first searches the list of image file format handlers for
a handler that can interpret the data in \fIdata\fR, and then reads
the image encoded within into \fIimageName\fR (the destination image).


If \fIdata\fR does not match any known format, an attempt to interpret
it as a (top-to-bottom) list of scan-lines is made, with each
scan-line being a (left-to-right) list of pixel colors (see
\fBTk_GetColor\fR for a description of valid colors.)  Every scan-line
must be of the same length.  Note that when \fIdata\fR is a single
color name, you are instructing Tk to fill a rectangular region with
that color.  The following options may be specified:
.RS
.TP
\fB\-format \fIformat-name\fR

Specifies the format of the image data in \fIdata\fR.

Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.



.TP
\fB\-to \fIx1 y1\fR ?\fIx2 y2\fR?

Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR)
of the region of \fIimageName\fR into which the image data will be
copied.  The default position is (0,0).  If \fIx2\fR,\fIy2\fR is given
and \fIdata\fR is not large enough to cover the rectangle specified by
this option, the image data extracted will be tiled so it covers the


entire destination rectangle.  Note that if \fIdata\fR specifies a
single color value, then a region extending to the bottom-right corner
represented by (\fIx2\fR,\fIy2\fR) will be filled with that color.
.RE
.TP
\fIimageName \fBread\fR \fIfilename\fR ?\fIoption value(s) ...\fR?

Reads image data from the file named \fIfilename\fR into the image.
This command first searches the list of
image file format handlers for a handler that can interpret the data
in \fIfilename\fR, and then reads the image in \fIfilename\fR into
\fIimageName\fR (the destination image).  The following options may be
specified:
.RS
.TP
\fB\-format \fIformat-name\fR

Specifies the format of the image data in \fIfilename\fR.

Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.



.TP
\fB\-from \fIx1 y1 x2 y2\fR

Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
specified, they specify diagonally opposite corners or the region.
The default, if this option is not specified, is the whole of the
image in the image file.
.TP
\fB\-shrink\fR

If this option, the size of \fIimageName\fR will be reduced, if
necessary, so that the region into which the image file data are read
is at the bottom-right corner of the \fIimageName\fR.  This option
will not affect the width or height of the image if the user has
specified a non-zero value for the \fB\-width\fR or \fB\-height\fR
configuration option, respectively.
.TP
\fB\-to \fIx y\fR

Specifies the coordinates of the top-left corner of the region of
\fIimageName\fR into which data from \fIfilename\fR are to be read.
The default is (0,0).
.RE
.TP
\fIimageName \fBredither\fR

The dithering algorithm used in displaying photo images propagates
quantization errors from one pixel to its neighbors.
If the image data for \fIimageName\fR is supplied in pieces, the
dithered image may not be exactly correct.  Normally the difference is
not noticeable, but if it is a problem, this command can be used to
recalculate the dithered image in each window where the image is
displayed.
.TP
\fIimageName \fBtransparency \fIsubcommand ?arg arg ...?\fR

Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS

.TP
\fIimageName \fBtransparency get \fIx y\fR

Returns a boolean indicating if the pixel at (\fIx\fR,\fIy\fR) is



transparent.

.TP
\fIimageName \fBtransparency set \fIx y boolean\fR

Makes the pixel at (\fIx\fR,\fIy\fR) transparent if \fIboolean\fR is


true, and makes that pixel opaque otherwise.



.RE
.TP
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?

Writes image data from \fIimageName\fR to a file named \fIfilename\fR.
The following options may be specified:
.RS
.TP
\fB\-background\fI color\fR

If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fI format-name\fR

Specifies the name of the image file format handler to be used to

write the data to the file.  Specifically, this subcommand searches
for the first handler whose name matches an initial substring of
\fIformat-name\fR and which has the capability to write an image

file.  If this option is not given, this subcommand uses the first
handler that has the capability to write an image file.



.TP
\fB\-from \fIx1 y1 x2 y2\fR

Specifies a rectangular region of \fIimageName\fR to be written to the
image file.  If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region.  The default,
if this option is not given, is the whole image.
.TP
\fB\-grayscale\fR

If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
standard Tk distribution comes with handlers for PPM/PGM and GIF formats,





which are automatically registered on initialization.
.PP
When reading an image file or processing
string data specified with the \fB\-data\fR configuration option, the
photo image code invokes each handler in turn until one is
found that claims to be able to read the data in the file or string.
Usually this will find the correct handler, but if it does not, the
user may give a format name with the \fB\-format\fR option to specify
which handler to use.  In fact the photo image code will try those
handlers whose names begin with the string specified for the
\fB\-format\fR option (the comparison is case-insensitive).  For
example, if the user specifies \fB\-format gif\fR, then a handler
named GIF87 or GIF89 may be invoked, but a handler
named JPEG may not (assuming that such handlers had been
registered).
.PP
When writing image data to a file, the processing of the
\fB\-format\fR option is slightly different: the string value given
for the \fB\-format\fR option must begin with the complete name of the
requested handler, and may contain additional information following
that, which the handler can use, for example, to specify which variant
to use of the formats supported by the handler.
Note that not all image handlers may support writing transparency data
to a file, even where the target image format does.





























































































































































.SH "COLOR ALLOCATION"
.PP
When a photo image is displayed in a window, the photo image code
allocates colors to use to display the image and dithers the image, if
necessary, to display a reasonable approximation to the image using
the colors that are available.  The colors are allocated as a color
cube, that is, the number of colors allocated is the product of the
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
slashes.
.SH CREDITS
.PP
The photo image type was designed and implemented by Paul Mackerras,
based on his earlier photo widget and some suggestions from
John Ousterhout.
.SH EXAMPLE
.PP
Load an image from a file and tile it to the size of a window, which
is useful for producing a tiled background:
.PP
.CS
# These lines should be called once
\fBimage create photo\fR untiled \-file "theFile.ppm"
\fBimage create photo\fR tiled

# These lines should be called whenever .someWidget changes
# size; a <Configure> binding is useful here
set width  [winfo width .someWidget]
set height [winfo height .someWidget]
tiled \fBcopy\fR untiled \-to 0 0 $width $height \-shrink
.CE
.PP
.VS 8.6
The PNG image loader allows the application of an additional alpha factor
during loading, which is useful for generating images suitable for disabled
buttons:
.PP
.CS
\fBimage create photo\fR icon \-file "icon.png"
\fBimage create photo\fR iconDisabled \-file "icon.png" \e
        \-format "png \-alpha 0.5"
button .b \-image icon \-disabledimage iconDisabled
.CE
.VE 8.6
.PP
.VS 8.7
Create a green box with a simple shadow effect
.PP
.CS
\fBimage create photo\fR foo

# Make a simple graduated fill varying in alpha for the shadow
for {set i 14} {$i > 0} {incr i -1} {
   set i2 [expr {$i + 30}]
   foo \fBput\fR [format black#%x [expr {15-$i}]] -to $i $i $i2 $i2
}

# Put a solid green rectangle on top
foo \fBput\fR #F080 -to 0 0 30 30
.VE 8.7
.CE
.SH "SEE ALSO"
image(n)

.SH KEYWORDS
photo, image, color
'\" Local Variables:
'\" mode: nroff
'\" End:







<


<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<


>


<
<
<
422
423
424
425
426
427
428

429
430

431
432
433
434
435
436
437
438
439
440
441



















442










443
444
445
446
447



slashes.
.SH CREDITS
.PP
The photo image type was designed and implemented by Paul Mackerras,
based on his earlier photo widget and some suggestions from
John Ousterhout.
.SH EXAMPLE

Load an image from a file and tile it to the size of a window, which
is useful for producing a tiled background:

.CS
# These lines should be called once
\fBimage create photo\fR untiled \-file "theFile.ppm"
\fBimage create photo\fR tiled

# These lines should be called whenever .someWidget changes
# size; a <Configure> binding is useful here
set width  [winfo width .someWidget]
set height [winfo height .someWidget]
tiled \fBcopy\fR untiled \-to 0 0 $width $height \-shrink
.CE






























.SH "SEE ALSO"
image(n)

.SH KEYWORDS
photo, image, color



Changes to doc/place.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254

255
256
257
258
259
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH place n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
place \- Geometry manager for fixed or rubber-sheet placement
.SH SYNOPSIS
\fBplace \fIoption arg \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The placer is a geometry manager for Tk.
It provides simple fixed placement of windows, where you specify
the exact size and location of one window, called the \fIcontent\fR,
within another window, called the \fIcontainer\fR.
The placer also provides rubber-sheet placement, where you specify the
size and location of the content in terms of the dimensions of
the container, so that the content changes size and location
in response to changes in the size of the container.
Lastly, the placer allows you to mix these styles of placement so
that, for example, the content has a fixed width and height but is
centered inside the container.
.PP
.TP
\fBplace \fIwindow option value \fR?\fIoption value ...\fR?
Arrange for the placer to manage the geometry of a content whose
pathName is \fIwindow\fR.  The remaining arguments consist of one or
more \fIoption\-value\fR pairs that specify the way in which
\fIwindow\fR's geometry is managed.  \fIOption\fR may have any of the
values accepted by the \fBplace configure\fR command.
.TP
\fBplace configure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
Query or modify the geometry options of the content given by
\fIwindow\fR.  If no \fIoption\fR is specified, this command returns a
list describing the available options (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s); in this case
the command returns an empty string.
.RS
.PP
The following \fIoption\-value\fR pairs are supported:

.TP
\fB\-anchor \fIwhere\fR
\fIWhere\fR specifies which point of \fIwindow\fR is to be positioned
at the (x,y) location selected by the \fB\-x\fR, \fB\-y\fR,
\fB\-relx\fR, and \fB\-rely\fR options.
The anchor point is in terms of the outer area of \fIwindow\fR
including its border, if any.
Thus if \fIwhere\fR is \fBse\fR then the lower-right corner of
\fIwindow\fR's border will appear at the given (x,y) location
in the container.
The anchor position defaults to \fBnw\fR.
.TP
\fB\-bordermode \fImode\fR
\fIMode\fR determines the degree to which borders within the
container are used in determining the placement of the content.
The default and most common value is \fBinside\fR.
In this case the placer considers the area of the container to
be the innermost area of the container, inside any border:
an option of \fB\-x 0\fR corresponds to an x-coordinate just
inside the border and an option of \fB\-relwidth 1.0\fR
means \fIwindow\fR will fill the area inside the container's
border.
.RS
.PP
If \fImode\fR is \fBoutside\fR then the placer considers
the area of the container to include its border;
this mode is typically used when placing \fIwindow\fR
outside its container, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
Lastly, \fImode\fR may be specified as \fBignore\fR, in which
case borders are ignored:  the area of the container is considered
to be its official X area, which includes any internal border but
no external border.  A bordermode of \fBignore\fR is probably
not very useful.
.RE
.TP
\fB\-height \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The height will be the outer dimension of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-height\fR or
\fB\-relheight\fR option is specified, then the height requested
internally by the window will be used.
.TP
\fB\-in \fIcontainer\fR
\fIContainer\fR specifies the path name of the window relative
to which \fIwindow\fR is to be placed.
\fIContainer\fR must either be \fIwindow\fR's parent or a descendant
of \fIwindow\fR's parent.
In addition, \fIcontainer\fR and \fIwindow\fR must both be descendants
of the same top-level window.
These restrictions are necessary to guarantee
that \fIwindow\fR is visible whenever \fIcontainer\fR is visible.
If this option is not specified then the other window defaults to
\fIwindow\fR's parent.
.TP
\fB\-relheight \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR.
In this case the height is specified as a floating-point number
relative to the height of the container: 0.5 means \fIwindow\fR will
be half as high as the container, 1.0 means \fIwindow\fR will have
the same height as the container, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a content,
their values are summed.  For example, \fB\-relheight 1.0 \-height \-2\fR
makes the content 2 pixels shorter than the container.
.TP
\fB\-relwidth \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR.
In this case the width is specified as a floating-point number
relative to the width of the container: 0.5 means \fIwindow\fR will
be half as wide as the container, 1.0 means \fIwindow\fR will have
the same width as the container, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a content,
their values are summed.  For example, \fB\-relwidth 1.0 \-width 5\fR
makes the content 5 pixels wider than the container.
.TP
\fB\-relx \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the location is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the left edge
of the container and 1.0 corresponds to the right edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-x\fR and \fB\-relx\fR are specified for a content
then their values are summed.  For example, \fB\-relx 0.5 \-x \-2\fR
positions the left edge of the content 2 pixels to the left of the
center of its container.
.TP
\fB\-rely \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the value is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the top edge
of the container and 1.0 corresponds to the bottom edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-y\fR and \fB\-rely\fR are specified for a content
then their values are summed.  For example, \fB\-rely 0.5 \-x 3\fR
positions the top edge of the content 3 pixels below the
center of its container.
.TP
\fB\-width \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The width will be the outer width of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-width\fR
or \fB\-relwidth\fR option is specified, then the width requested
internally by the window will be used.
.TP
\fB\-x \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.
.TP
\fB\-y \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.
.PP
If the same value is specified separately with
two different options, such as \fB\-x\fR and \fB\-relx\fR, then
the most recent option is used and the older one is ignored.
.RE
.TP
\fBplace forget \fIwindow\fR
Causes the placer to stop managing the geometry of \fIwindow\fR.  As a
side effect of this command \fIwindow\fR will be unmapped so that it
does not appear on the screen.  If \fIwindow\fR is not currently managed
by the placer then the command has no effect.  This command returns an
empty string.
.TP
\fBplace info \fIwindow\fR
Returns a list giving the current configuration of \fIwindow\fR.
The list consists of \fIoption\-value\fR pairs in exactly the
same form as might be specified to the \fBplace configure\fR
command.
.TP
\fBplace content \fIwindow\fR
Returns a list of all the content windows for which \fIwindow\fR is the container.
If there is no content for \fIwindow\fR then an empty string is returned.
.TP
\fBplace slaves \fIwindow\fR
.
Synonym for . \fBplace content \fIwindow\fR
.PP
If the configuration of a window has been retrieved with
\fBplace info\fR, that configuration can be restored later by
first using \fBplace forget\fR to erase any existing information
for the window and then invoking \fBplace configure\fR with
the saved information.
.SH "FINE POINTS"
.PP
It is not necessary for the container window to be the parent
of the content window.
This feature is useful in at least two situations.
First, for complex window layouts it means you can create a
hierarchy of subwindows whose only purpose
is to assist in the layout of the parent.
The
.QW "real children"
of the parent (i.e. the windows that
are significant for the application's user interface) can be
children of the parent yet be placed inside the windows
of the geometry-management hierarchy.
This means that the path names of the
.QW "real children"
do not reflect the geometry-management hierarchy and users
can specify options for the real children
without being aware of the structure of the geometry-management
hierarchy.
.PP
A second reason for having a container different than the content's
parent is to tie two siblings together.
For example, the placer can be used to force a window always to
be positioned centered just below one of its
siblings by specifying the configuration
.CS
\fB\-in \fIsibling\fB \-relx 0.5 \-rely 1.0 \-anchor n \-bordermode outside\fR
.CE
Whenever the sibling is repositioned in the future, the content
will be repositioned as well.
.PP
Unlike many other geometry managers (such as the packer)
the placer does not make any attempt to manipulate the geometry of
the container windows or the parents of content windows (i.e. it does not
set their requested sizes).
To control the sizes of these windows, make them windows like
frames and canvases that provide configuration options for this purpose.
.SH EXAMPLE
.PP
Make the label occupy the middle bit of the toplevel, no matter how it
is resized:
.CS
label .l \-text "In the\enMiddle!" \-bg black \-fg white
\fBplace\fR .l \-relwidth .3 \-relx .35 \-relheight .3 \-rely .35
.CE

.SH "SEE ALSO"
grid(n), pack(n)

.SH KEYWORDS
geometry manager, height, location, container, place, rubber sheet, content, width
'\" Local Variables:
'\" mode: nroff
'\" End:






|









>




|
|

|
|
|

|
|



|






|









|
<

>









|




|

|
|


|

|
<

|

|

|



<










|
|

|

|


|
|





|
|
|
|

|




|
|
|
|

|


|



|

|

|
|


|



|

|

|
|











|



|


|



|



















|
|
|
<
<
<
<








|
|

















|







|




|




<






>


>

|
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195




196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252



'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH place n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
place \- Geometry manager for fixed or rubber-sheet placement
.SH SYNOPSIS
\fBplace \fIoption arg \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The placer is a geometry manager for Tk.
It provides simple fixed placement of windows, where you specify
the exact size and location of one window, called the \fIslave\fR,
within another window, called the \fImaster\fR.
The placer also provides rubber-sheet placement, where you specify the
size and location of the slave in terms of the dimensions of
the master, so that the slave changes size and location
in response to changes in the size of the master.
Lastly, the placer allows you to mix these styles of placement so
that, for example, the slave has a fixed width and height but is
centered inside the master.
.PP
.TP
\fBplace \fIwindow option value \fR?\fIoption value ...\fR?
Arrange for the placer to manage the geometry of a slave whose
pathName is \fIwindow\fR.  The remaining arguments consist of one or
more \fIoption\-value\fR pairs that specify the way in which
\fIwindow\fR's geometry is managed.  \fIOption\fR may have any of the
values accepted by the \fBplace configure\fR command.
.TP
\fBplace configure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
Query or modify the geometry options of the slave given by
\fIwindow\fR.  If no \fIoption\fR is specified, this command returns a
list describing the available options (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s); in this case
the command returns an empty string.


The following \fIoption\-value\fR pairs are supported:
.RS
.TP
\fB\-anchor \fIwhere\fR
\fIWhere\fR specifies which point of \fIwindow\fR is to be positioned
at the (x,y) location selected by the \fB\-x\fR, \fB\-y\fR,
\fB\-relx\fR, and \fB\-rely\fR options.
The anchor point is in terms of the outer area of \fIwindow\fR
including its border, if any.
Thus if \fIwhere\fR is \fBse\fR then the lower-right corner of
\fIwindow\fR's border will appear at the given (x,y) location
in the master.
The anchor position defaults to \fBnw\fR.
.TP
\fB\-bordermode \fImode\fR
\fIMode\fR determines the degree to which borders within the
master are used in determining the placement of the slave.
The default and most common value is \fBinside\fR.
In this case the placer considers the area of the master to
be the innermost area of the master, inside any border:
an option of \fB\-x 0\fR corresponds to an x-coordinate just
inside the border and an option of \fB\-relwidth 1.0\fR
means \fIwindow\fR will fill the area inside the master's
border.


If \fImode\fR is \fBoutside\fR then the placer considers
the area of the master to include its border;
this mode is typically used when placing \fIwindow\fR
outside its master, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
Lastly, \fImode\fR may be specified as \fBignore\fR, in which
case borders are ignored:  the area of the master is considered
to be its official X area, which includes any internal border but
no external border.  A bordermode of \fBignore\fR is probably
not very useful.

.TP
\fB\-height \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The height will be the outer dimension of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-height\fR or
\fB\-relheight\fR option is specified, then the height requested
internally by the window will be used.
.TP
\fB\-in \fImaster\fR
\fIMaster\fR specifies the path name of the window relative
to which \fIwindow\fR is to be placed.
\fIMaster\fR must either be \fIwindow\fR's parent or a descendant
of \fIwindow\fR's parent.
In addition, \fImaster\fR and \fIwindow\fR must both be descendants
of the same top-level window.
These restrictions are necessary to guarantee
that \fIwindow\fR is visible whenever \fImaster\fR is visible.
If this option is not specified then the master defaults to
\fIwindow\fR's parent.
.TP
\fB\-relheight \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR.
In this case the height is specified as a floating-point number
relative to the height of the master: 0.5 means \fIwindow\fR will
be half as high as the master, 1.0 means \fIwindow\fR will have
the same height as the master, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a slave,
their values are summed.  For example, \fB\-relheight 1.0 \-height \-2\fR
makes the slave 2 pixels shorter than the master.
.TP
\fB\-relwidth \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR.
In this case the width is specified as a floating-point number
relative to the width of the master: 0.5 means \fIwindow\fR will
be half as wide as the master, 1.0 means \fIwindow\fR will have
the same width as the master, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a slave,
their values are summed.  For example, \fB\-relwidth 1.0 \-width 5\fR
makes the slave 5 pixels wider than the master.
.TP
\fB\-relx \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the master window
of the anchor point for \fIwindow\fR.
In this case the location is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the left edge
of the master and 1.0 corresponds to the right edge of the master.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-x\fR and \fB\-relx\fR are specified for a slave
then their values are summed.  For example, \fB\-relx 0.5 \-x \-2\fR
positions the left edge of the slave 2 pixels to the left of the
center of its master.
.TP
\fB\-rely \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the master window
of the anchor point for \fIwindow\fR.
In this case the value is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the top edge
of the master and 1.0 corresponds to the bottom edge of the master.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-y\fR and \fB\-rely\fR are specified for a slave
then their values are summed.  For example, \fB\-rely 0.5 \-x 3\fR
positions the top edge of the slave 3 pixels below the
center of its master.
.TP
\fB\-width \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The width will be the outer width of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-width\fR
or \fB\-relwidth\fR option is specified, then the width requested
internally by the window will be used.
.TP
\fB\-x \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the master window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the master window.
.TP
\fB\-y \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the master window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the master window.
.PP
If the same value is specified separately with
two different options, such as \fB\-x\fR and \fB\-relx\fR, then
the most recent option is used and the older one is ignored.
.RE
.TP
\fBplace forget \fIwindow\fR
Causes the placer to stop managing the geometry of \fIwindow\fR.  As a
side effect of this command \fIwindow\fR will be unmapped so that it
does not appear on the screen.  If \fIwindow\fR is not currently managed
by the placer then the command has no effect.  This command returns an
empty string.
.TP
\fBplace info \fIwindow\fR
Returns a list giving the current configuration of \fIwindow\fR.
The list consists of \fIoption\-value\fR pairs in exactly the
same form as might be specified to the \fBplace configure\fR
command.
.TP
\fBplace slaves \fIwindow\fR
Returns a list of all the slave windows for which \fIwindow\fR is the master.
If there are no slaves for \fIwindow\fR then an empty string is returned.




.PP
If the configuration of a window has been retrieved with
\fBplace info\fR, that configuration can be restored later by
first using \fBplace forget\fR to erase any existing information
for the window and then invoking \fBplace configure\fR with
the saved information.
.SH "FINE POINTS"
.PP
It is not necessary for the master window to be the parent
of the slave window.
This feature is useful in at least two situations.
First, for complex window layouts it means you can create a
hierarchy of subwindows whose only purpose
is to assist in the layout of the parent.
The
.QW "real children"
of the parent (i.e. the windows that
are significant for the application's user interface) can be
children of the parent yet be placed inside the windows
of the geometry-management hierarchy.
This means that the path names of the
.QW "real children"
do not reflect the geometry-management hierarchy and users
can specify options for the real children
without being aware of the structure of the geometry-management
hierarchy.
.PP
A second reason for having a master different than the slave's
parent is to tie two siblings together.
For example, the placer can be used to force a window always to
be positioned centered just below one of its
siblings by specifying the configuration
.CS
\fB\-in \fIsibling\fB \-relx 0.5 \-rely 1.0 \-anchor n \-bordermode outside\fR
.CE
Whenever the sibling is repositioned in the future, the slave
will be repositioned as well.
.PP
Unlike many other geometry managers (such as the packer)
the placer does not make any attempt to manipulate the geometry of
the master windows or the parents of slave windows (i.e. it does not
set their requested sizes).
To control the sizes of these windows, make them windows like
frames and canvases that provide configuration options for this purpose.
.SH EXAMPLE

Make the label occupy the middle bit of the toplevel, no matter how it
is resized:
.CS
label .l \-text "In the\enMiddle!" \-bg black \-fg white
\fBplace\fR .l \-relwidth .3 \-relx .35 \-relheight .3 \-rely .35
.CE

.SH "SEE ALSO"
grid(n), pack(n)

.SH KEYWORDS
geometry manager, height, location, master, place, rubber sheet, slave, width



Changes to doc/popup.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44

45
46
47
48
49
'\"
'\" Copyright (c) 1994-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.
'\"
.TH tk_popup n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_popup \- Post a popup menu
.SH SYNOPSIS
\fBtk_popup \fImenu x y \fR?\fIentry\fR?
.BE

.SH DESCRIPTION
.PP
This procedure posts a menu at a given position on the screen and
configures Tk so that the menu and its cascaded children can be
traversed with the mouse or the keyboard.
\fIMenu\fR is the name of a menu widget and \fIx\fR and \fIy\fR
are the root coordinates at which to display the menu.
If \fIentry\fR is omitted or an empty string, the
menu's upper left corner is positioned at the given point.
Otherwise \fIentry\fR gives the index of an entry in \fImenu\fR and
the menu will be positioned so that the entry is positioned over
the given point.
.SH EXAMPLE
.PP
How to attach a simple popup menu to a widget.
.CS
# Create a menu
set m [menu .popupMenu]
$m add command \-label "Example 1" \-command bell
$m add command \-label "Example 2" \-command bell

# Create something to attach it to
pack [label .l \-text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <Button-1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE

.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)

.SH KEYWORDS
menu, popup
'\" Local Variables:
'\" mode: nroff
'\" End:





|









>













<











|

>


>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48



'\"
'\" Copyright (c) 1994-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.
'\" 
.TH tk_popup n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_popup \- Post a popup menu
.SH SYNOPSIS
\fBtk_popup \fImenu x y \fR?\fIentry\fR?
.BE

.SH DESCRIPTION
.PP
This procedure posts a menu at a given position on the screen and
configures Tk so that the menu and its cascaded children can be
traversed with the mouse or the keyboard.
\fIMenu\fR is the name of a menu widget and \fIx\fR and \fIy\fR
are the root coordinates at which to display the menu.
If \fIentry\fR is omitted or an empty string, the
menu's upper left corner is positioned at the given point.
Otherwise \fIentry\fR gives the index of an entry in \fImenu\fR and
the menu will be positioned so that the entry is positioned over
the given point.
.SH EXAMPLE

How to attach a simple popup menu to a widget.
.CS
# Create a menu
set m [menu .popupMenu]
$m add command \-label "Example 1" \-command bell
$m add command \-label "Example 2" \-command bell

# Create something to attach it to
pack [label .l \-text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE

.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)

.SH KEYWORDS
menu, popup



Changes to doc/radiobutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH radiobutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
radiobutton \- Create and manipulate 'radiobutton' pick-one widgets
.SH SYNOPSIS
\fBradiobutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH radiobutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
radiobutton \- Create and manipulate radiobutton widgets
.SH SYNOPSIS
\fBradiobutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
34
35
36
37
38
39
40
41
42
43










44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93

94

95
96
97

98
99
100
101
102
103
104
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the button's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-indicatoron indicatorOn IndicatorOn
Specifies whether or not the indicator should be drawn.  Must be a
proper boolean value.  If false, the \fB\-relief\fR option is
ignored and the widget's relief is always sunken if the widget is
selected and raised otherwise.










.OP \-offrelief offRelief OffRelief
Specifies the relief for the checkbutton when the indicator is not drawn and
the checkbutton is off.  The default value is
.QW raised .
By setting this option to
.QW flat
and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to
.QW raised ,
the effect is achieved
of having a flat button that raises on mouse-over and which is
depressed when activated.  This is the behavior typically exhibited by
the Align-Left, Align-Right, and Center radiobuttons on the toolbar of a
word-processor, for example.
.OP \-overrelief overRelief OverRelief
Specifies an alternative relief for the radiobutton, to be used when the
mouse cursor is over the widget.  This option can be used to make
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.
If \fBindicatorOn\fR is true then the color is used as the background for
the indicator regardless of the select state.
If \fB\-indicatoron\fR is false, this color is used as the background
for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)
when the radiobutton is selected.
This option is ignored unless the \fB\-image\fR option has been
specified.
.OP \-state state State
Specifies one of three states for the radiobutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the radiobutton is displayed using the
\fB\-foreground\fR and \fB\-background\fR options.  The active state is
typically used when the pointer is over the radiobutton.  In active state
the radiobutton is displayed using the \fB\-activeforeground\fR and
\fB\-activebackground\fR options.  Disabled state means that the radiobutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fB\-disabledforeground\fR and
\fB\-background\fR options determine how the radiobutton is displayed.
.OP \-tristateimage tristateImage TristateImage

Specifies an image to display (in place of the \fB\-image\fR option)
when the radiobutton is selected.
This option is ignored unless the \fB\-image\fR option has been
specified.

.OP \-tristatevalue tristateValue Value

Specifies the value that causes the radiobutton to display the multi-value
selection, also known as the tri-state mode.  Defaults to
.QW "" .

.OP \-value value Value
Specifies value to store in the button's associated variable whenever
this button is selected.
.OP \-variable variable Variable
Specifies the name of a global variable to set whenever this button is
selected.  Changes in this variable also cause the button to select
or deselect itself.







|


>
>
>
>
>
>
>
>
>
>








|


|








<
<
<
<
<
<
<
<
<

|

|




|

|
|


|
|

>
|

|

>

>
|


>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73









74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
If an image or bitmap is being displayed in the button then the value is in
screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR);
for text it is in lines of text.
If this option is not specified, the button's desired height is computed
from the size of the image or bitmap or text being displayed in it.
.OP \-indicatoron indicatorOn IndicatorOn
Specifies whether or not the indicator should be drawn.  Must be a
proper boolean value.  If false, the \fBrelief\fR option is
ignored and the widget's relief is always sunken if the widget is
selected and raised otherwise.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.
If \fBindicatorOn\fR is true then the color applies to the indicator.
Under Windows, this color is used as the background for the indicator
regardless of the select state.
If \fBindicatorOn\fR is false, this color is used as the background
for the entire widget, in place of \fBbackground\fR or \fBactiveBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-offrelief offRelief OffRelief
Specifies the relief for the checkbutton when the indicator is not drawn and
the checkbutton is off.  The default value is
.QW raised .
By setting this option to
.QW flat
and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to
.QW raised ,
the effect is achieved 
of having a flat button that raises on mouse-over and which is
depressed when activated.  This is the behavior typically exhibited by
the Align-Left, Align-Right, and Center radiobuttons on the toolbar of a 
word-processor, for example.
.OP \-overrelief overRelief OverRelief
Specifies an alternative relief for the radiobutton, to be used when the
mouse cursor is over the widget.  This option can be used to make
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.









.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fBimage\fR option)
when the radiobutton is selected.
This option is ignored unless the \fBimage\fR option has been
specified.
.OP \-state state State
Specifies one of three states for the radiobutton:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the radiobutton is displayed using the
\fBforeground\fR and \fBbackground\fR options.  The active state is
typically used when the pointer is over the radiobutton.  In active state
the radiobutton is displayed using the \fBactiveForeground\fR and
\fBactiveBackground\fR options.  Disabled state means that the radiobutton
should be insensitive:  the default bindings will refuse to activate
the widget and will ignore mouse button presses.
In this state the \fBdisabledForeground\fR and
\fBbackground\fR options determine how the radiobutton is displayed.
.OP \-tristateimage tristateImage TristateImage
.VS 8.5
Specifies an image to display (in place of the \fBimage\fR option)
when the radiobutton is selected.
This option is ignored unless the \fBimage\fR option has been
specified.
.VE 8.5
.OP \-tristatevalue tristateValue Value
.VS 8.5
Specifies the value that causes the radiobutton to display the multi-value 
selection, also known as the tri-state mode.  Defaults to
.QW "" .
.VE 8.5
.OP \-value value Value
Specifies value to store in the button's associated variable whenever
this button is selected.
.OP \-variable variable Variable
Specifies the name of a global variable to set whenever this button is
selected.  Changes in this variable also cause the button to select
or deselect itself.
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A radiobutton is a widget that displays a textual string, bitmap or image
and a diamond or circle called an \fIindicator\fR.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fB\-wraplength\fR option) and
one of the characters may optionally be underlined using the
\fB\-underline\fR option.  A radiobutton has
all of the behavior of a simple button: it can display itself in either
of three different ways, according to the \fB\-state\fR option;
it can be made to appear
raised, sunken, or flat; it can be made to flash; and it invokes
a Tcl command whenever mouse button 1 is clicked over the
check button.
.PP
In addition, radiobuttons can be \fIselected\fR.
If a radiobutton is selected, the indicator is normally







|

|

|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A radiobutton is a widget that displays a textual string, bitmap or image
and a diamond or circle called an \fIindicator\fR.
If text is displayed, it must all be in a single font, but it
can occupy multiple lines on the screen (if it contains newlines
or if wrapping occurs because of the \fBwrapLength\fR option) and
one of the characters may optionally be underlined using the
\fBunderline\fR option.  A radiobutton has
all of the behavior of a simple button: it can display itself in either
of three different ways, according to the \fBstate\fR option;
it can be made to appear
raised, sunken, or flat; it can be made to flash; and it invokes
a Tcl command whenever mouse button 1 is clicked over the
check button.
.PP
In addition, radiobuttons can be \fIselected\fR.
If a radiobutton is selected, the indicator is normally
151
152
153
154
155
156
157

158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
The indicator is drawn without a round mark inside.
Typically, several radiobuttons share a single variable and the
value of the variable indicates which radiobutton is to be selected.
When a radiobutton is selected it sets the value of the variable to
indicate that fact;  each radiobutton also monitors the value of
the variable and automatically selects and deselects itself when the
variable's value changes.

If the variable's value matches the \fB\-tristatevalue\fR, then the radiobutton
is drawn using the tri-state mode.  This mode is used to indicate mixed or
multiple values.  (This is used when the radiobutton represents the state
of multiple items.)

By default the variable \fBselectedButton\fR
is used;  its contents give the name of the button that is
selected, or the empty string if no button associated with that
variable is selected.
The name of the variable for a radiobutton,
plus the variable to be stored into it, may be modified with options
on the command line or in the option database.
Configuration options may also be used to modify the way the
indicator is displayed (or whether it is displayed at all).
By default a radiobutton is configured to select itself on button clicks.
.SH "WIDGET COMMAND"
.PP
The \fBradiobutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.TP
\fIpathName \fBdeselect\fR
.
Deselects the radiobutton and sets the associated variable to an
empty string.
If this radiobutton was not currently selected, the command has
no effect.
.TP
\fIpathName \fBflash\fR
.
Flashes the radiobutton.  This is accomplished by redisplaying the radiobutton
several times, alternating between active and normal colors.  At
the end of the flash the radiobutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.TP
\fIpathName \fBinvoke\fR
.
Does just what would have happened if the user invoked the radiobutton
with the mouse: selects the button and invokes
its associated Tcl command, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the radiobutton.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.TP
\fIpathName \fBselect\fR
.
Selects the radiobutton and sets the associated variable to the
value corresponding to this widget.
.SH BINDINGS
.PP
Tk automatically creates class bindings for radiobuttons that give them
the following default behavior:
.IP [1]







>
|
|
|

>

















|






<






<














<






<







<








<







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218

219
220
221
222
223
224
225

226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
The indicator is drawn without a round mark inside.
Typically, several radiobuttons share a single variable and the
value of the variable indicates which radiobutton is to be selected.
When a radiobutton is selected it sets the value of the variable to
indicate that fact;  each radiobutton also monitors the value of
the variable and automatically selects and deselects itself when the
variable's value changes.
.VS 8.5
If the variable's value matches the \fBtristateValue\fR, then the radiobutton is 
drawn using the tri-state mode.  This mode is used to indicate mixed or 
multiple values.  (This is used when the radiobutton represents the state 
of multiple items.)
.VE 8.5
By default the variable \fBselectedButton\fR
is used;  its contents give the name of the button that is
selected, or the empty string if no button associated with that
variable is selected.
The name of the variable for a radiobutton,
plus the variable to be stored into it, may be modified with options
on the command line or in the option database.
Configuration options may also be used to modify the way the
indicator is displayed (or whether it is displayed at all).
By default a radiobutton is configured to select itself on button clicks.
.SH "WIDGET COMMAND"
.PP
The \fBradiobutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.TP
\fIpathName \fBdeselect\fR

Deselects the radiobutton and sets the associated variable to an
empty string.
If this radiobutton was not currently selected, the command has
no effect.
.TP
\fIpathName \fBflash\fR

Flashes the radiobutton.  This is accomplished by redisplaying the radiobutton
several times, alternating between active and normal colors.  At
the end of the flash the radiobutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.TP
\fIpathName \fBinvoke\fR

Does just what would have happened if the user invoked the radiobutton
with the mouse: selects the button and invokes
its associated Tcl command, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the radiobutton.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.TP
\fIpathName \fBselect\fR

Selects the radiobutton and sets the associated variable to the
value corresponding to this widget.
.SH BINDINGS
.PP
Tk automatically creates class bindings for radiobuttons that give them
the following default behavior:
.IP [1]
256
257
258
259
260
261
262
263
264
265
.PP
The behavior of radiobuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
checkbutton(n), labelframe(n), listbox(n), options(n), scale(n), ttk::radiobutton(n)
.SH KEYWORDS
radiobutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
257
258
259
260
261
262
263



.PP
The behavior of radiobuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
checkbutton(n), labelframe(n), listbox(n), options(n), scale(n), ttk::radiobutton(n)
.SH KEYWORDS
radiobutton, widget



Changes to doc/raise.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52

53
54
55
56
57
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH raise n 3.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
raise \- Change a window's position in the stacking order
.SH SYNOPSIS
\fBraise \fIwindow \fR?\fIaboveThis\fR?
.BE

.SH DESCRIPTION
.PP
If the \fIaboveThis\fR argument is omitted then the command raises
\fIwindow\fR so that it is above all of its siblings in the stacking
order (it will not be obscured by any siblings and will obscure
any siblings that overlap it).
If \fIaboveThis\fR is specified then it must be the path name of
a window that is either a sibling of \fIwindow\fR or the descendant
of a sibling of \fIwindow\fR.
In this case the \fBraise\fR command will insert
\fIwindow\fR into the stacking order just above \fIaboveThis\fR
(or the ancestor of \fIaboveThis\fR that is a sibling of \fIwindow\fR);
this could end up either raising or lowering \fIwindow\fR.
.PP
All \fBtoplevel\fR windows may be restacked with respect to each
other, whatever their relative path names, but the window manager is
not obligated to strictly honor requests to restack.
.PP
On macOS raising an iconified \fBtoplevel\fR window causes it to be
deiconified.
.SH EXAMPLE
.PP
Make a button appear to be in a sibling frame that was created after
it. This is is often necessary when building GUIs in the style where
you create your activity widgets first before laying them out on the
display:
.CS
button .b \-text "Hi there!"
pack [frame .f \-background blue]
pack [label .f.l1 \-text "This is above"]
pack .b \-in .f
pack [label .f.l2 \-text "This is below"]
\fBraise\fR .b
.CE

.SH "SEE ALSO"
lower(n)

.SH KEYWORDS
obscure, raise, stacking order
'\" Local Variables:
'\" mode: nroff
'\" End:






|









>













<
<
<
<
<
<
<

<












>


>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49



'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH raise n 3.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
raise \- Change a window's position in the stacking order
.SH SYNOPSIS
\fBraise \fIwindow \fR?\fIaboveThis\fR?
.BE

.SH DESCRIPTION
.PP
If the \fIaboveThis\fR argument is omitted then the command raises
\fIwindow\fR so that it is above all of its siblings in the stacking
order (it will not be obscured by any siblings and will obscure
any siblings that overlap it).
If \fIaboveThis\fR is specified then it must be the path name of
a window that is either a sibling of \fIwindow\fR or the descendant
of a sibling of \fIwindow\fR.
In this case the \fBraise\fR command will insert
\fIwindow\fR into the stacking order just above \fIaboveThis\fR
(or the ancestor of \fIaboveThis\fR that is a sibling of \fIwindow\fR);
this could end up either raising or lowering \fIwindow\fR.







.SH EXAMPLE

Make a button appear to be in a sibling frame that was created after
it. This is is often necessary when building GUIs in the style where
you create your activity widgets first before laying them out on the
display:
.CS
button .b \-text "Hi there!"
pack [frame .f \-background blue]
pack [label .f.l1 \-text "This is above"]
pack .b \-in .f
pack [label .f.l2 \-text "This is below"]
\fBraise\fR .b
.CE

.SH "SEE ALSO"
lower(n)

.SH KEYWORDS
obscure, raise, stacking order



Changes to doc/scale.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH scale n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scale \- Create and manipulate 'scale' value-controlled slider widgets
.SH SYNOPSIS
\fBscale\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-foreground	\-relief
\-background	\-highlightbackground	\-repeatdelay
\-borderwidth	\-highlightcolor	\-repeatinterval
\-cursor	\-highlightthickness	\-takefocus






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH scale n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scale \- Create and manipulate scale widgets
.SH SYNOPSIS
\fBscale\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-foreground	\-relief
\-background	\-highlightbackground	\-repeatdelay
\-borderwidth	\-highlightcolor	\-repeatinterval
\-cursor	\-highlightthickness	\-takefocus
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
Specifies the desired long dimension of the scale in screen units
(i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For vertical scales this is the scale's height;  for horizontal scales
it is the scale's width.
.OP \-resolution resolution Resolution
A real value specifying the resolution for the scale.
If this value is greater than zero then the scale's value will always be
rounded to an even multiple of this value, as will
the endpoints of the scale.  If the value is less than zero then no
rounding occurs.  Defaults to 1 (i.e., the value will be integral).
.OP \-showvalue showValue ShowValue
Specifies a boolean value indicating whether or not the current
value of the scale is to be displayed.
.OP \-sliderlength sliderLength SliderLength
Specifies the size of the slider, measured in screen units along the slider's
long dimension.  The value may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR.
.OP \-sliderrelief sliderRelief SliderRelief
Specifies the relief to use when drawing the slider, such as \fBraised\fR
or \fBsunken\fR.
.OP \-state state State
Specifies one of three states for the scale:  \fBnormal\fR,
\fBactive\fR, or \fBdisabled\fR.
If the scale is disabled then the value may not be changed and the scale
will not activate.
If the scale is active, the slider is displayed using the color
specified by the \fB\-activebackground\fR option.
.OP \-tickinterval tickInterval TickInterval
Must be a real value.
Determines the spacing between numerical
tick marks displayed below or to the left of the slider. The values will all be displayed with the same number of decimal places, which will be enough to ensure they are all accurate to within 20% of a tick interval.
If 0, no tick marks will be displayed.
.OP \-to to To
Specifies a real value corresponding
to the right or bottom end of the scale.
This value may be either less than or greater than the \fB\-from\fR option.
.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale.  Whenever the
value of the variable changes, the scale will update to reflect this
value.
Whenever the scale is manipulated interactively, the variable
will be modified to reflect the scale's new value.
.OP \-width width Width
Specifies the desired narrow dimension of the scale in screen units
(i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For vertical scales this is the scale's width;  for horizontal scales
this is the scale's height.
.BE

.SH DESCRIPTION
.PP
The \fBscale\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a scale widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the scale such as its colors, orientation,
and relief.  The \fBscale\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A scale is a widget that displays a rectangular \fItrough\fR and a
small \fIslider\fR.  The trough corresponds to a range
of real values (determined by the \fB\-from\fR, \fB\-to\fR, and
\fB\-resolution\fR options),
and the position of the slider selects a particular real value.
The slider's position (and hence the scale's value) may be adjusted
with the mouse or keyboard as described in the \fBBINDINGS\fR
section below.  Whenever the scale's value is changed, a Tcl
command is invoked (using the \fB\-command\fR option) to notify
other interested widgets of the change.
In addition, the value
of the scale can be linked to a Tcl variable (using the \fB\-variable\fR
option), so that changes in either are reflected in the other.
.PP
Three annotations may be displayed in a scale widget:  a label
appearing at the top right of the widget (top left for horizontal
scales), a number displayed just to the left of the slider
(just above the slider for horizontal scales), and a collection
of numerical tick marks just to the left of the current value
(just below the trough for horizontal scales).  Each of these three
annotations may be enabled or disabled using the
configuration options.
.SH "WIDGET COMMAND"
.PP
The \fBscale\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Returns a list whose elements are the x and y coordinates of
the point along the centerline of the trough that corresponds
to \fIvalue\fR.
If \fIvalue\fR is omitted then the scale's current value is used.
.TP
\fIpathName \fBget\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are omitted, returns the current value
of the scale.  If \fIx\fR and \fIy\fR are specified, they give
pixel coordinates within the widget;  the command returns
the scale value corresponding to the given pixel.
Only one of \fIx\fR or \fIy\fR is used:  for horizontal scales
\fIy\fR is ignored, and for vertical scales \fIx\fR is ignored.
.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns a string indicating what part of the scale lies under
the coordinates given by \fIx\fR and \fIy\fR.
A return value of \fBslider\fR means that the point is over
the slider;  \fBtrough1\fR means that the point is over the
portion of the slider above  or to the left of the slider;
and \fBtrough2\fR means that the point is over the portion
of the slider below or to the right of the slider.
If the point is not over one of these elements, an empty string
is returned.
.TP
\fIpathName \fBset \fIvalue\fR
.
This command is invoked to change the current value of the scale,
and hence the position at which the slider is displayed.  \fIValue\fR
gives the new value for the scale.
The command has no effect if the scale is disabled.
.SH BINDINGS
.PP
Tk automatically creates class bindings for scales that give them
the following default behavior.
Where the behavior is different for vertical and horizontal scales,
the horizontal behavior is described in parentheses.
.IP [1]
If button 1 is pressed in the trough, the scale's value will
be incremented or decremented by the value of the \fB\-resolution\fR
option so that the slider moves in the direction of the cursor.
If the button is held down, the action auto-repeats.
.IP [2]
If button 1 is pressed over the slider, the slider can be dragged
with the mouse.
.IP [3]
If button 1 is pressed in the trough with the Control key down,
the slider moves all the way to the end of its range, in the
direction towards the mouse cursor.
.IP [4]
If button 2 is pressed, the scale's value is set to the mouse
position.  If the mouse is dragged with button 2 down, the scale's
value changes with the drag.
.IP [5]
The Up and Left keys move the slider up (left) by the value
of the \fB\-resolution\fR option.
.IP [6]
The Down and Right keys move the slider down (right) by the value
of the \fB\-resolution\fR option.
.IP [7]
Control-Up and Control-Left move the slider up (left) by the
value of the \fB\-bigincrement\fR option.
.IP [8]
Control-Down and Control-Right move the slider down (right) by the
value of the \fB\-bigincrement\fR option.
.IP [9]
Home moves the slider to the top (left) end of its range.
.IP [10]
End moves the slider to the bottom (right) end of its range.
.PP
If the scale is disabled using the \fB\-state\fR option then
none of the above bindings have any effect.
.PP
The behavior of scales can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::scale(n)
.SH KEYWORDS
scale, slider, trough, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|


















|



|




|







|

|
|

>















|
|




|


|

















|






<






<














<






<







|
<










|
<












|
|














|


|


|


|





|




|
<


<
<
<
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244



Specifies the desired long dimension of the scale in screen units
(i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For vertical scales this is the scale's height;  for horizontal scales
it is the scale's width.
.OP \-resolution resolution Resolution
A real value specifying the resolution for the scale.
If this value is greater than zero then the scale's value will always be
rounded to an even multiple of this value, as will tick marks and
the endpoints of the scale.  If the value is less than zero then no
rounding occurs.  Defaults to 1 (i.e., the value will be integral).
.OP \-showvalue showValue ShowValue
Specifies a boolean value indicating whether or not the current
value of the scale is to be displayed.
.OP \-sliderlength sliderLength SliderLength
Specifies the size of the slider, measured in screen units along the slider's
long dimension.  The value may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR.
.OP \-sliderrelief sliderRelief SliderRelief
Specifies the relief to use when drawing the slider, such as \fBraised\fR
or \fBsunken\fR.
.OP \-state state State
Specifies one of three states for the scale:  \fBnormal\fR,
\fBactive\fR, or \fBdisabled\fR.
If the scale is disabled then the value may not be changed and the scale
will not activate.
If the scale is active, the slider is displayed using the color
specified by the \fBactiveBackground\fR option.
.OP \-tickinterval tickInterval TickInterval
Must be a real value.
Determines the spacing between numerical
tick marks displayed below or to the left of the slider.
If 0, no tick marks will be displayed.
.OP \-to to To
Specifies a real value corresponding
to the right or bottom end of the scale.
This value may be either less than or greater than the \fBfrom\fR option.
.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale.  Whenever the
value of the variable changes, the scale will update to reflect this
value.
Whenever the scale is manipulated interactively, the variable
will be modified to reflect the scale's new value.
.OP \-width width Width
Specifies the desired narrow dimension of the trough in screen units
(i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
For vertical scales this is the trough's width;  for horizontal scales
this is the trough's height.
.BE

.SH DESCRIPTION
.PP
The \fBscale\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a scale widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the scale such as its colors, orientation,
and relief.  The \fBscale\fR command returns its
\fIpathName\fR argument.  At the time this command is invoked,
there must not exist a window named \fIpathName\fR, but
\fIpathName\fR's parent must exist.
.PP
A scale is a widget that displays a rectangular \fItrough\fR and a
small \fIslider\fR.  The trough corresponds to a range
of real values (determined by the \fBfrom\fR, \fBto\fR, and
\fBresolution\fR options),
and the position of the slider selects a particular real value.
The slider's position (and hence the scale's value) may be adjusted
with the mouse or keyboard as described in the \fBBINDINGS\fR
section below.  Whenever the scale's value is changed, a Tcl
command is invoked (using the \fBcommand\fR option) to notify
other interested widgets of the change.
In addition, the value
of the scale can be linked to a Tcl variable (using the \fBvariable\fR
option), so that changes in either are reflected in the other.
.PP
Three annotations may be displayed in a scale widget:  a label
appearing at the top right of the widget (top left for horizontal
scales), a number displayed just to the left of the slider
(just above the slider for horizontal scales), and a collection
of numerical tick marks just to the left of the current value
(just below the trough for horizontal scales).  Each of these three
annotations may be enabled or disabled using the
configuration options.
.SH "WIDGET COMMAND"
.PP
The \fBscale\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?

Returns a list whose elements are the x and y coordinates of
the point along the centerline of the trough that corresponds
to \fIvalue\fR.
If \fIvalue\fR is omitted then the scale's current value is used.
.TP
\fIpathName \fBget\fR ?\fIx y\fR?

If \fIx\fR and \fIy\fR are omitted, returns the current value
of the scale.  If \fIx\fR and \fIy\fR are specified, they give
pixel coordinates within the widget;  the command returns
the scale value corresponding to the given pixel.
Only one of \fIx\fR or \fIy\fR is used:  for horizontal scales
\fIy\fR is ignored, and for vertical scales \fIx\fR is ignored.
.TP
\fIpathName \fBidentify\fR \fIx y\fR

Returns a string indicating what part of the scale lies under
the coordinates given by \fIx\fR and \fIy\fR.
A return value of \fBslider\fR means that the point is over
the slider;  \fBtrough1\fR means that the point is over the
portion of the slider above  or to the left of the slider;
and \fBtrough2\fR means that the point is over the portion
of the slider below or to the right of the slider.
If the point is not over one of these elements, an empty string
is returned.
.TP
\fIpathName \fBset\fR \fIvalue\fR

This command is invoked to change the current value of the scale,
and hence the position at which the slider is displayed.  \fIValue\fR
gives the new value for the scale.
The command has no effect if the scale is disabled.
.SH BINDINGS
.PP
Tk automatically creates class bindings for scales that give them
the following default behavior.
Where the behavior is different for vertical and horizontal scales,
the horizontal behavior is described in parentheses.
.IP [1]
If button 1 is pressed in the trough, the scale's value will
be incremented or decremented by the value of the \fBresolution\fR
option so that the slider moves in the direction of the cursor. 
If the button is held down, the action auto-repeats.
.IP [2]
If button 1 is pressed over the slider, the slider can be dragged
with the mouse.
.IP [3]
If button 1 is pressed in the trough with the Control key down,
the slider moves all the way to the end of its range, in the
direction towards the mouse cursor.
.IP [4]
If button 2 is pressed, the scale's value is set to the mouse
position.  If the mouse is dragged with button 2 down, the scale's
value changes with the drag.
.IP [5]
The Up and Left keys move the slider up (left) by the value
of the \fBresolution\fR option.
.IP [6]
The Down and Right keys move the slider down (right) by the value
of the \fBresolution\fR option.
.IP [7]
Control-Up and Control-Left move the slider up (left) by the
value of the \fBbigIncrement\fR option.
.IP [8]
Control-Down and Control-Right move the slider down (right) by the
value of the \fBbigIncrement\fR option.
.IP [9]
Home moves the slider to the top (left) end of its range.
.IP [10]
End moves the slider to the bottom (right) end of its range.
.PP
If the scale is disabled using the \fBstate\fR option then
none of the above bindings have any effect.
.PP
The behavior of scales can be changed by defining new bindings for
individual widgets or by redefining the class bindings.


.SH KEYWORDS
scale, slider, trough, widget



Changes to doc/scrollbar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH scrollbar n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scrollbar \- Create and manipulate 'scrollbar' scrolling control and indicator widgets
.SH SYNOPSIS
\fBscrollbar\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightcolor	\-repeatdelay
\-background	\-highlightthickness	\-repeatinterval
\-borderwidth	\-jump	\-takefocus
\-cursor	\-orient	\-troughcolor






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH scrollbar n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scrollbar \- Create and manipulate scrollbar widgets
.SH SYNOPSIS
\fBscrollbar\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightcolor	\-repeatdelay
\-background	\-highlightthickness	\-repeatinterval
\-borderwidth	\-jump	\-takefocus
\-cursor	\-orient	\-troughcolor
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
All scrollable widgets have \fBxview\fR and \fByview\fR commands
that take exactly the additional arguments appended by the scrollbar
as described in \fBSCROLLING COMMANDS\fR below.
.OP \-elementborderwidth elementBorderWidth BorderWidth
Specifies the width of borders drawn around the internal elements
of the scrollbar (the two arrows and the slider).  The value may
have any of the forms acceptable to \fBTk_GetPixels\fR.
If this value is less than zero, the value of the \fB\-borderwidth\fR
option is used in its place.
.OP \-width width Width
Specifies the desired narrow dimension of the scrollbar window,
not including 3-D border, if any.  For vertical
scrollbars this will be the width and for horizontal scrollbars
this will be the height.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
All scrollable widgets have \fBxview\fR and \fByview\fR commands
that take exactly the additional arguments appended by the scrollbar
as described in \fBSCROLLING COMMANDS\fR below.
.OP \-elementborderwidth elementBorderWidth BorderWidth
Specifies the width of borders drawn around the internal elements
of the scrollbar (the two arrows and the slider).  The value may
have any of the forms acceptable to \fBTk_GetPixels\fR.
If this value is less than zero, the value of the \fBborderWidth\fR
option is used in its place.
.OP \-width width Width
Specifies the desired narrow dimension of the scrollbar window,
not including 3-D border, if any.  For vertical
scrollbars this will be the width and for horizontal scrollbars
this will be the height.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218






219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
.SH "WIDGET COMMAND"
.PP
The \fBscrollbar\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scrollbar widgets:
.TP
\fIpathName \fBactivate \fR?\fIelement\fR?
.
Marks the element indicated by \fIelement\fR as active, which
causes it to be displayed as specified by the \fB\-activebackground\fR
and \fB\-activerelief\fR options.
The only element values understood by this command are \fBarrow1\fR,
\fBslider\fR, or \fBarrow2\fR.
If any other value is specified then no element of the scrollbar
will be active.
If \fIelement\fR is not specified, the command returns
the name of the element that is currently active, or an empty string
if no element is active.
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
.
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in slider position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the slider \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the slider \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.
.TP
\fIpathName \fBfraction \fIx y\fR
.
Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar.
The value 0 corresponds to the top or left of the trough, the
value 1 corresponds to the bottom or right, 0.5 corresponds to
the middle, and so on.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.
.TP
\fIpathName \fBget\fR
.
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns the name of the element under the point given by \fIx\fR and
\fIy\fR (such as \fBarrow1\fR), or an empty string if the point does
not lie in any element of the scrollbar.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
.TP
\fIpathName \fBset \fIfirst last\fR
.
This command is invoked by the scrollbar's associated widget to
tell the scrollbar about the current view in the widget.
The command takes two arguments, each of which is a real fraction
between 0 and 1.
The fractions describe the range of the document that is visible in
the associated widget.
For example, if \fIfirst\fR is 0.2 and \fIlast\fR is 0.4, it means
that the first part of the document visible in the window is 20%
of the way through the document, and the last visible part is 40%
of the way through.
.SH "SCROLLING COMMANDS"
.PP
When the user interacts with the scrollbar, for example by dragging
the slider, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like
.QW \fB.t yview\fR .
.TP
\fIprefix \fBmoveto \fIfraction\fR
.
\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR






.

The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible. Fractional number are rounded away from 0, so
scrolling 0.001 pages has the same effect as scrolling 1 page.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window. Fractional
numbers are rounded away from 0, so scrolling 0.001 units has
the same effect as scrolling 1 unit.
.SH "OLD COMMAND SYNTAX"
.PP
In versions of Tk before 4.0, the \fBset\fR and \fBget\fR widget
commands used a different form.
This form is still supported for backward compatibility, but it
is deprecated.
In the old command syntax, the \fBset\fR widget command has the
following form:
.TP
\fIpathName \fBset \fItotalUnits windowUnits firstUnit lastUnit\fR
In this form the arguments are all integers.
\fITotalUnits\fR gives the total size of the object being displayed in the
associated widget.  The meaning of one unit depends on the associated
widget;  for example, in a text editor widget units might
correspond to lines of
text.  \fIWindowUnits\fR indicates the total number of units that
can fit in the associated window at one time.  \fIFirstUnit\fR







|






<

|
|








|
<






<














<











<











<



|
<






|
<



















|
<


<








|
>
>
>
>
>
>
|
>






|
<
<
<
<
<
<
<
<
<
<
<
<









|







99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166

167
168
169
170

171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223












224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
.SH "WIDGET COMMAND"
.PP
The \fBscrollbar\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scrollbar widgets:
.TP
\fIpathName \fBactivate \fR?\fIelement\fR?

Marks the element indicated by \fIelement\fR as active, which
causes it to be displayed as specified by the \fBactiveBackground\fR
and \fBactiveRelief\fR options.
The only element values understood by this command are \fBarrow1\fR,
\fBslider\fR, or \fBarrow2\fR.
If any other value is specified then no element of the scrollbar
will be active.
If \fIelement\fR is not specified, the command returns
the name of the element that is currently active, or an empty string
if no element is active.
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR

Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in slider position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the slider \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the slider \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.
.TP
\fIpathName \fBfraction \fIx y\fR

Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar.
The value 0 corresponds to the top or left of the trough, the
value 1 corresponds to the bottom or right, 0.5 corresponds to
the middle, and so on.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.
.TP
\fIpathName \fBget\fR

Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify\fR \fIx y\fR

Returns the name of the element under the point given by \fIx\fR and
\fIy\fR (such as \fBarrow1\fR), or an empty string if the point does
not lie in any element of the scrollbar.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
.TP
\fIpathName \fBset\fR \fIfirst last\fR

This command is invoked by the scrollbar's associated widget to
tell the scrollbar about the current view in the widget.
The command takes two arguments, each of which is a real fraction
between 0 and 1.
The fractions describe the range of the document that is visible in
the associated widget.
For example, if \fIfirst\fR is 0.2 and \fIlast\fR is 0.4, it means
that the first part of the document visible in the window is 20%
of the way through the document, and the last visible part is 40%
of the way through.
.SH "SCROLLING COMMANDS"
.PP
When the user interacts with the scrollbar, for example by dragging
the slider, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like \fB.t yview\fR

.TP
\fIprefix \fBmoveto \fIfraction\fR

\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.












.SH "OLD COMMAND SYNTAX"
.PP
In versions of Tk before 4.0, the \fBset\fR and \fBget\fR widget
commands used a different form.
This form is still supported for backward compatibility, but it
is deprecated.
In the old command syntax, the \fBset\fR widget command has the
following form:
.TP
\fIpathName \fBset\fR \fItotalUnits windowUnits firstUnit lastUnit\fR
In this form the arguments are all integers.
\fITotalUnits\fR gives the total size of the object being displayed in the
associated widget.  The meaning of one unit depends on the associated
widget;  for example, in a text editor widget units might
correspond to lines of
text.  \fIWindowUnits\fR indicates the total number of units that
can fit in the associated window at one time.  \fIFirstUnit\fR
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
.LP
The most recent \fBset\fR widget command determines whether or not
to use the old syntax.
If it is given two real arguments then the new syntax will be
used in the future, and if it is given four integer arguments then
the old syntax will be used.
.SH BINDINGS
.PP
Tk automatically creates class bindings for scrollbars that give them
the following default behavior.
If the behavior is different for vertical and horizontal scrollbars,
the horizontal behavior is described in parentheses.
.IP [1]
Pressing button 1 over \fBarrow1\fR causes the view in the
associated widget to shift up (left) by one unit so that the







<







258
259
260
261
262
263
264

265
266
267
268
269
270
271
.LP
The most recent \fBset\fR widget command determines whether or not
to use the old syntax.
If it is given two real arguments then the new syntax will be
used in the future, and if it is given four integer arguments then
the old syntax will be used.
.SH BINDINGS

Tk automatically creates class bindings for scrollbars that give them
the following default behavior.
If the behavior is different for vertical and horizontal scrollbars,
the horizontal behavior is described in parentheses.
.IP [1]
Pressing button 1 over \fBarrow1\fR causes the view in the
associated widget to shift up (left) by one unit so that the
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
The Prior and Next keys have the same behavior
as mouse clicks over \fBtrough1\fR and \fBtrough2\fR, respectively.
.IP [13]
The Home key adjusts the view to the top (left edge) of the document.
.IP [14]
The End key adjusts the view to the bottom (right edge) of the document.
.SH EXAMPLE
.PP
Create a window with a scrollable \fBtext\fR widget:
.CS
toplevel .tl
text .tl.t \-yscrollcommand {.tl.s set}
\fBscrollbar\fR .tl.s \-command {.tl.t yview}
grid .tl.t .tl.s \-sticky nsew
grid columnconfigure .tl 0 \-weight 1
grid rowconfigure .tl 0 \-weight 1
.CE
.SH "SEE ALSO"
ttk:scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<













<
<
<
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343



The Prior and Next keys have the same behavior
as mouse clicks over \fBtrough1\fR and \fBtrough2\fR, respectively.
.IP [13]
The Home key adjusts the view to the top (left edge) of the document.
.IP [14]
The End key adjusts the view to the bottom (right edge) of the document.
.SH EXAMPLE

Create a window with a scrollable \fBtext\fR widget:
.CS
toplevel .tl
text .tl.t \-yscrollcommand {.tl.s set}
\fBscrollbar\fR .tl.s \-command {.tl.t yview}
grid .tl.t .tl.s \-sticky nsew
grid columnconfigure .tl 0 \-weight 1
grid rowconfigure .tl 0 \-weight 1
.CE
.SH "SEE ALSO"
ttk:scrollbar(n)
.SH KEYWORDS
scrollbar, widget



Changes to doc/selection.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH selection n 8.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
selection \- Manipulate the X selection
.SH SYNOPSIS
\fBselection \fIoption\fR ?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command provides a Tcl interface to the X selection mechanism and
implements the full selection functionality described in the
X Inter-Client Communication Conventions Manual (ICCCM).
.PP
Note that for management of the \fBCLIPBOARD\fR selection (see below), the
\fBclipboard\fR command may also be used.
.PP
The first argument to \fBselection\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:

.TP
\fBselection clear\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?
.
If \fIselection\fR exists anywhere on \fIwindow\fR's display, clear it
so that no window owns the selection anymore.  \fISelection\fR
specifies the X selection that should be cleared, and should be an
atom name such as \fBPRIMARY\fR or \fBCLIPBOARD\fR; see the Inter-Client
Communication Conventions Manual for complete details.
\fISelection\fR defaults to \fBPRIMARY\fR and \fIwindow\fR defaults to
.QW . .
Returns an empty string.
.TP
\fBselection get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR? ?\fB\-type\fR \fItype\fR?
.
Retrieves the value of \fIselection\fR from \fIwindow\fR's display and
returns it as a result.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which the selection is to be returned
(the desired
.QW target
for conversion, in ICCCM terminology), and
should be an atom name such as \fBSTRING\fR or \fBFILE_NAME\fR; see the
Inter-Client Communication Conventions Manual for complete details.
\fIType\fR defaults to \fBSTRING\fR.  The selection owner may choose to
return the selection in any of several different representation
formats, such as \fBSTRING\fR, \fBUTF8_STRING\fR, \fBATOM\fR,
\fBINTEGER\fR, etc. (this format is different
than the selection type; see the ICCCM for all the confusing details).
If the selection is returned in a non-string format, such as \fBINTEGER\fR
or \fBATOM\fR, the \fBselection\fR command converts it to string format as a
collection of fields separated by spaces: atoms are converted to their
textual names, and anything else is converted to hexadecimal integers.
Note that \fBselection get\fR does not retrieve the selection in the
\fBUTF8_STRING\fR format unless told to.
.TP
\fBselection handle\fR ?\fB\-selection\fR \fIs\fR? ?\fB\-type\fR \fIt\fR? ?\fB\-format\fR \fIf\fR? \fIwindow command\fR
.
Creates a handler for selection requests, such that \fIcommand\fR will
be executed whenever selection \fIs\fR is owned by \fIwindow\fR and
someone attempts to retrieve it in the form given by type \fIt\fR
(e.g. \fIt\fR is specified in the \fBselection get\fR command).
\fIS\fR defaults to \fBPRIMARY\fR, \fIt\fR defaults to \fBSTRING\fR, and
\fIf\fR defaults to \fBSTRING\fR.  If \fIcommand\fR is an empty string
then any existing handler for \fIwindow\fR, \fIt\fR, and
\fIs\fR is removed.
Note that when the selection is handled as type \fBSTRING\fR it is also
automatically handled as type \fBUTF8_STRING\fR as well.
.RS
.PP
When \fIselection\fR is requested, \fIwindow\fR is the selection owner,
and \fItype\fR is the requested type, \fIcommand\fR will be executed
as a Tcl command with two additional numbers appended to it
(with space separators).
The two additional numbers
are \fIoffset\fR and \fImaxChars\fR:  \fIoffset\fR specifies a starting
character position in the selection and \fImaxChars\fR gives the maximum
number of characters to retrieve.  The command should return a value consisting
of at most \fImaxChars\fR of the selection, starting at position
\fIoffset\fR.  For very large selections (larger than \fImaxChars\fR)
the selection will be retrieved using several invocations of \fIcommand\fR
with increasing \fIoffset\fR values.  If \fIcommand\fR returns a string
whose length is less than \fImaxChars\fR, the return value is assumed to
include all of the remainder of the selection;  if the length of
\fIcommand\fR's result is equal to \fImaxChars\fR then
\fIcommand\fR will be invoked again, until it eventually
returns a result shorter than \fImaxChars\fR.  The value of \fImaxChars\fR
will always be relatively large (thousands of characters).
.PP
If \fIcommand\fR returns an error then the selection retrieval is rejected
just as if the selection did not exist at all.
.PP
The \fIformat\fR argument specifies the representation that should be
used to transmit the selection to the requester (the second column of
Table 2 of the ICCCM), and defaults to \fBSTRING\fR.  If \fIformat\fR is
\fBSTRING\fR, the selection is transmitted as 8-bit ASCII characters (i.e.
just in the form returned by \fIcommand\fR, in the system \fBencoding\fR;
the \fBUTF8_STRING\fR format always uses UTF-8 as its encoding).
If \fIformat\fR is
\fBATOM\fR, then the return value from \fIcommand\fR is divided into fields
separated by white space;  each field is converted to its atom value,
and the 32-bit atom value is transmitted instead of the atom name.
For any other \fIformat\fR, the return value from \fIcommand\fR is
divided into fields separated by white space and each field is
converted to a 32-bit integer;  an array of integers is transmitted
to the selection requester.
.PP
The \fIformat\fR argument is needed only for compatibility with
selection requesters that do not use Tk.  If Tk is being
used to retrieve the selection then the value is converted back to
a string at the requesting end, so \fIformat\fR is
irrelevant.
.RE
.TP
\fBselection own\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?
.TP
\fBselection own\fR ?\fB\-command\fR \fIcommand\fR? ?\fB\-selection\fR \fIselection\fR? \fIwindow\fR
.
The first form of \fBselection own\fR returns the path name of the
window in this application that owns \fIselection\fR on the display
containing \fIwindow\fR, or an empty string if no window in this
application owns the selection.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
.RS
.PP
The second form of \fBselection own\fR causes \fIwindow\fR to become
the new owner of \fIselection\fR on \fIwindow\fR's display, returning
an empty string as result. The existing owner, if any, is notified
that it has lost the selection.
If \fIcommand\fR is specified, it is a Tcl script to execute when
some other window claims ownership of the selection away from
\fIwindow\fR.  \fISelection\fR defaults to PRIMARY.
.RE
.SH WIDGET FACILITIES
.PP
The \fBtext\fR, \fBentry\fR, \fBttk::entry\fR, \fBlistbox\fR, \fBspinbox\fR and \fBttk::spinbox\fR widgets have the option \fB\-exportselection\fR.  If a widget has this option set to boolean \fBtrue\fR, then (in an unsafe interpreter) a selection made in the widget is automatically written to the \fBPRIMARY\fR selection.
.PP
A GUI event, for example \fB<<PasteSelection>>\fR, can copy the \fBPRIMARY\fR selection to certain widgets.  This copy is implemented by a widget binding to the event.  The binding script makes appropriate calls to the \fBselection\fR command.
.PP
.SH PORTABILITY ISSUES
.PP
On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients.
.PP
On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a parent interpreter and its child interpreters.  It is not shared between interpreters in different processes or different threads.  Each parent interpreter has a separate \fBPRIMARY\fR selection that is shared only with its child interpreters which are not safe interpreters.
.PP
.SH SECURITY
.PP
A safe interpreter cannot read from the \fBPRIMARY\fR selection because its \fBselection\fR command is hidden.  For this reason the \fBPRIMARY\fR selection cannot be written to the Tk widgets of a safe interpreter.
.PP
A Tk widget can have its option \fB\-exportselection\fR set to boolean \fBtrue\fR, but in a safe interpreter this option has no effect: writing from the widget to the \fBPRIMARY\fR selection is disabled.
.PP
These are security features.  A safe interpreter may run untrusted code, and it is a security risk if this untrusted code can read or write the \fBPRIMARY\fR selection used by other interpreters.
.PP
.SH EXAMPLES
.PP
On X11 platforms, one of the standard selections available is the
\fBSECONDARY\fR selection. Hardly anything uses it, but here is how to read
it using Tk:
.PP
.CS
set selContents [\fBselection get\fR \-selection SECONDARY]
.CE
.PP
Many different types of data may be available for a selection; the
special type \fBTARGETS\fR allows you to get a list of available types:
.PP
.CS
foreach type [\fBselection get\fR \-type TARGETS] {
   puts "Selection PRIMARY supports type $type"
}
.CE
.PP
To claim the selection, you must first set up a handler to supply the
data for the selection. Then you have to claim the selection...
.CS
# Set up the data handler ready for incoming requests
set foo "This is a string with some data in it... blah blah"
\fBselection handle\fR \-selection SECONDARY . getData
proc getData {offset maxChars} {
   puts "Retrieving selection starting at $offset"
   return [string range $::foo $offset [expr {$offset+$maxChars-1}]]
}

# Now we grab the selection itself
puts "Claiming selection"
\fBselection own\fR \-command lost \-selection SECONDARY .
proc lost {} {
   puts "Lost selection"
}
.CE
.SH "SEE ALSO"
clipboard(n)
.SH KEYWORDS
clear, format, handler, ICCCM, own, selection, target, type
'\" Local Variables:
'\" mode: nroff
'\" End:






|







|

>






|





>


<



|

|

|


<

|






|

|

|
|

|
|



|


<




|
|


|
|





|




















|
|

|

|

















<



|


<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<

|

<





|
<







|






|













<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130

131
132
133
134
135
136
137
138





















139

140
141
142

143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176



'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH selection n 8.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
selection \- Manipulate the X selection
.SH SYNOPSIS
\fBselection \fIoption\fR ?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command provides a Tcl interface to the X selection mechanism and
implements the full selection functionality described in the
X Inter-Client Communication Conventions Manual (ICCCM).
.PP
Note that for management of the CLIPBOARD selection (see below), the
\fBclipboard\fR command may also be used.
.PP
The first argument to \fBselection\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:
.PP
.TP
\fBselection clear\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?

If \fIselection\fR exists anywhere on \fIwindow\fR's display, clear it
so that no window owns the selection anymore.  \fISelection\fR
specifies the X selection that should be cleared, and should be an
atom name such as PRIMARY or CLIPBOARD; see the Inter-Client
Communication Conventions Manual for complete details.
\fISelection\fR defaults to PRIMARY and \fIwindow\fR defaults to
.QW . .
Returns an empty string. 
.TP
\fBselection get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR? ?\fB\-type\fR \fItype\fR?

Retrieves the value of \fIselection\fR from \fIwindow\fR's display and
returns it as a result.  \fISelection\fR defaults to PRIMARY and
\fIwindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which the selection is to be returned
(the desired
.QW target
for conversion, in ICCCM terminology), and
should be an atom name such as STRING or FILE_NAME; see the
Inter-Client Communication Conventions Manual for complete details.
\fIType\fR defaults to STRING.  The selection owner may choose to
return the selection in any of several different representation
formats, such as STRING, UTF8_STRING, ATOM, INTEGER, etc. (this format
is different
than the selection type; see the ICCCM for all the confusing details).
If the selection is returned in a non-string format, such as INTEGER
or ATOM, the \fBselection\fR command converts it to string format as a
collection of fields separated by spaces: atoms are converted to their
textual names, and anything else is converted to hexadecimal integers.
Note that \fBselection get\fR does not retrieve the selection in the
UTF8_STRING format unless told to.
.TP
\fBselection handle\fR ?\fB\-selection\fR \fIs\fR? ?\fB\-type\fR \fIt\fR? ?\fB\-format\fR \fIf\fR? \fIwindow command\fR

Creates a handler for selection requests, such that \fIcommand\fR will
be executed whenever selection \fIs\fR is owned by \fIwindow\fR and
someone attempts to retrieve it in the form given by type \fIt\fR
(e.g. \fIt\fR is specified in the \fBselection get\fR command).
\fIS\fR defaults to PRIMARY, \fIt\fR defaults to STRING, and
\fIf\fR defaults to STRING.  If \fIcommand\fR is an empty string
then any existing handler for \fIwindow\fR, \fIt\fR, and
\fIs\fR is removed.
Note that when the selection is handled as type STRING it is also
automatically handled as type UTF8_STRING as well.
.RS
.PP
When \fIselection\fR is requested, \fIwindow\fR is the selection owner,
and \fItype\fR is the requested type, \fIcommand\fR will be executed
as a Tcl command with two additional numbers appended to it
(with space separators).  
The two additional numbers
are \fIoffset\fR and \fImaxChars\fR:  \fIoffset\fR specifies a starting
character position in the selection and \fImaxChars\fR gives the maximum
number of characters to retrieve.  The command should return a value consisting
of at most \fImaxChars\fR of the selection, starting at position
\fIoffset\fR.  For very large selections (larger than \fImaxChars\fR)
the selection will be retrieved using several invocations of \fIcommand\fR
with increasing \fIoffset\fR values.  If \fIcommand\fR returns a string
whose length is less than \fImaxChars\fR, the return value is assumed to
include all of the remainder of the selection;  if the length of
\fIcommand\fR's result is equal to \fImaxChars\fR then
\fIcommand\fR will be invoked again, until it eventually
returns a result shorter than \fImaxChars\fR.  The value of \fImaxChars\fR
will always be relatively large (thousands of characters).
.PP
If \fIcommand\fR returns an error then the selection retrieval is rejected
just as if the selection did not exist at all.
.PP
The \fIformat\fR argument specifies the representation that should be
used to transmit the selection to the requester (the second column of
Table 2 of the ICCCM), and defaults to STRING.  If \fIformat\fR is
STRING, the selection is transmitted as 8-bit ASCII characters (i.e.
just in the form returned by \fIcommand\fR, in the system \fBencoding\fR;
the UTF8_STRING format always uses UTF-8 as its encoding).
If \fIformat\fR is
ATOM, then the return value from \fIcommand\fR is divided into fields
separated by white space;  each field is converted to its atom value,
and the 32-bit atom value is transmitted instead of the atom name.
For any other \fIformat\fR, the return value from \fIcommand\fR is
divided into fields separated by white space and each field is
converted to a 32-bit integer;  an array of integers is transmitted
to the selection requester.
.PP
The \fIformat\fR argument is needed only for compatibility with
selection requesters that do not use Tk.  If Tk is being
used to retrieve the selection then the value is converted back to
a string at the requesting end, so \fIformat\fR is
irrelevant.
.RE
.TP
\fBselection own\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?
.TP
\fBselection own\fR ?\fB\-command\fR \fIcommand\fR? ?\fB\-selection\fR \fIselection\fR? \fIwindow\fR

The first form of \fBselection own\fR returns the path name of the
window in this application that owns \fIselection\fR on the display
containing \fIwindow\fR, or an empty string if no window in this
application owns the selection.  \fISelection\fR defaults to PRIMARY and
\fIwindow\fR defaults to
.QW . .

.PP
The second form of \fBselection own\fR causes \fIwindow\fR to become
the new owner of \fIselection\fR on \fIwindow\fR's display, returning
an empty string as result. The existing owner, if any, is notified
that it has lost the selection.
If \fIcommand\fR is specified, it is a Tcl script to execute when
some other window claims ownership of the selection away from
\fIwindow\fR.  \fISelection\fR defaults to PRIMARY.





















.SH EXAMPLES

On X11 platforms, one of the standard selections available is the
SECONDARY selection. Hardly anything uses it, but here is how to read
it using Tk:

.CS
set selContents [\fBselection get\fR \-selection SECONDARY]
.CE
.PP
Many different types of data may be available for a selection; the
special type TARGETS allows you to get a list of available types:

.CS
foreach type [\fBselection get\fR \-type TARGETS] {
   puts "Selection PRIMARY supports type $type"
}
.CE
.PP
To claim the selection, you must first set up a handler to supply the
data for the selection.  Then you have to claim the selection...
.CS
# Set up the data handler ready for incoming requests
set foo "This is a string with some data in it... blah blah"
\fBselection handle\fR \-selection SECONDARY . getData
proc getData {offset maxChars} {
   puts "Retrieving selection starting at $offset"
   return [string range $::foo $offset [expr {$offset+$maxChars}]]
}

# Now we grab the selection itself
puts "Claiming selection"
\fBselection own\fR \-command lost \-selection SECONDARY .
proc lost {} {
   puts "Lost selection"
}
.CE
.SH "SEE ALSO"
clipboard(n)
.SH KEYWORDS
clear, format, handler, ICCCM, own, selection, target, type



Changes to doc/send.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH send n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
send \- Execute a command in a different application
.SH SYNOPSIS
\fBsend ?\fIoptions\fR? \fIapp cmd \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command arranges for \fIcmd\fR (and \fIarg\fRs) to be executed in the
application named by \fIapp\fR.  It returns the result or
error from that command execution.
\fIApp\fR may be the name of any application whose main window is
on the display containing the sender's main window;  it need not






|







|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH send n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
send \- Execute a command in a different application
.SH SYNOPSIS
\fBsend ?\fIoptions\fR? \fIapp cmd \fR?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
This command arranges for \fIcmd\fR (and \fIarg\fRs) to be executed in the
application named by \fIapp\fR.  It returns the result or
error from that command execution.
\fIApp\fR may be the name of any application whose main window is
on the display containing the sender's main window;  it need not
45
46
47
48
49
50
51

52
53
54
55
56
57

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
the application's main window.
.TP
\fB\-\|\-\fR
Serves no purpose except to terminate the list of options.  This
option is needed only if \fIapp\fR could contain a leading
.QW \-
character.

.SH "APPLICATION NAMES"
.PP
The name of an application is set initially from the name of the
program or script that created the application.
You can query and change the name of an application with the
\fBtk appname\fR command.

.SH "DISABLING SENDS"
.PP
If the \fBsend\fR command is removed from an application (e.g.
with the command \fBrename\fR \fBsend {}\fR) then the application
will not respond to incoming send requests anymore,  nor will it
be able to issue outgoing requests.
Communication can be reenabled by invoking the \fBtk appname\fR
command.

.SH SECURITY
.PP
The \fBsend\fR command is potentially a serious security loophole. On Unix,
any application that can connect to your X server can send
scripts to your applications.
These incoming scripts can use Tcl to read and
write your files and invoke subprocesses under your name.







>






>



|




>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
the application's main window.
.TP
\fB\-\|\-\fR
Serves no purpose except to terminate the list of options.  This
option is needed only if \fIapp\fR could contain a leading
.QW \-
character.

.SH "APPLICATION NAMES"
.PP
The name of an application is set initially from the name of the
program or script that created the application.
You can query and change the name of an application with the
\fBtk appname\fR command.

.SH "DISABLING SENDS"
.PP
If the \fBsend\fR command is removed from an application (e.g.
with the command \fBrename send {}\fR) then the application
will not respond to incoming send requests anymore,  nor will it
be able to issue outgoing requests.
Communication can be reenabled by invoking the \fBtk appname\fR
command.

.SH SECURITY
.PP
The \fBsend\fR command is potentially a serious security loophole. On Unix,
any application that can connect to your X server can send
scripts to your applications.
These incoming scripts can use Tcl to read and
write your files and invoke subprocesses under your name.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
list of enabled hosts is empty.
This means that applications cannot connect to your server unless
they use some other form of authorization
such as that provide by \fBxauth\fR.
Under Windows, \fBsend\fR is currently disabled.  Most of the
functionality is provided by the \fBdde\fR command instead.
.SH EXAMPLE
.PP
This script fragment can be used to make an application that only runs
once on a particular display.
.CS
if {[tk appname FoobarApp] ne "FoobarApp"} {
    \fBsend\fR \-async FoobarApp RemoteStart $argv
    exit
}
# The command that will be called remotely, which raises
# the application main window and opens the requested files
proc RemoteStart args {
    raise .
    foreach filename $args {
        OpenFile $filename
    }
}
.CE
.SH KEYWORDS
application, dde, name, remote execution, security, send
'\" Local Variables:
'\" mode: nroff
'\" End:







<


















<
<
<
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109



list of enabled hosts is empty.
This means that applications cannot connect to your server unless
they use some other form of authorization
such as that provide by \fBxauth\fR.
Under Windows, \fBsend\fR is currently disabled.  Most of the
functionality is provided by the \fBdde\fR command instead.
.SH EXAMPLE

This script fragment can be used to make an application that only runs
once on a particular display.
.CS
if {[tk appname FoobarApp] ne "FoobarApp"} {
    \fBsend\fR \-async FoobarApp RemoteStart $argv
    exit
}
# The command that will be called remotely, which raises
# the application main window and opens the requested files
proc RemoteStart args {
    raise .
    foreach filename $args {
        OpenFile $filename
    }
}
.CE
.SH KEYWORDS
application, dde, name, remote execution, security, send



Changes to doc/spinbox.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'\"
'\" Copyright (c) 2000 Jeffrey Hobbs.
'\" 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.
'\"
.TH spinbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
spinbox \- Create and manipulate 'spinbox' value spinner widgets
.SH SYNOPSIS
\fBspinbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightthickness	\-repeatinterval
\-background	\-insertbackground	\-selectbackground
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable
\-foreground	\-justify	\-xscrollcommand
\-highlightbackground	\-relief
\-highlightcolor	\-repeatdelay
\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-buttonbackground buttonBackground Background
The background color to be used for the spin buttons.
.OP \-buttoncursor buttonCursor Cursor
The cursor to be used when over the spin buttons.  If this is empty
(the default), a default cursor will be used.






|





|












<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
'\"
'\" Copyright (c) 2000 Jeffrey Hobbs.
'\" 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.
'\" 
.TH spinbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
spinbox \- Create and manipulate spinbox widgets
.SH SYNOPSIS
\fBspinbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightthickness	\-repeatinterval
\-background	\-insertbackground	\-selectbackground
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable
\-foreground	\-justify	\-xscrollcommand
\-highlightbackground	\-relief
\-highlightcolor	\-repeatdelay

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-buttonbackground buttonBackground Background
The background color to be used for the spin buttons.
.OP \-buttoncursor buttonCursor Cursor
The cursor to be used when over the spin buttons.  If this is empty
(the default), a default cursor will be used.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating-point value corresponding to the lowest value for a spinbox, to
be used in conjunction with \fB\-to\fR and \fB\-increment\fR.  When all
are specified correctly, the spinbox will use these values to control its
contents. If this value is greater than the \fB\-to\fR option, then
\fB\-from\fR and \fB\-to\fR values are automatically swapped.
If \fB\-values\fR is specified, it supersedes this option.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fB\-validatecommand\fR returns 0.  Setting
it to an empty string disables this feature (the default).  The best use of
this option is to set it to \fIbell\fR.  See \fBVALIDATION\fR below for
more information.
.OP \-increment increment Increment
A floating-point value specifying the increment.  When used with
\fB\-from\fR and \fB\-to\fR, the value in the widget will be adjusted by
\fB\-increment\fR when a spin button is pressed (up adds the value,
down subtracts the value).
.OP \-readonlybackground readonlyBackground ReadonlyBackground







|
<
|

|

|







50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating-point value corresponding to the lowest value for a spinbox, to
be used in conjunction with \fB\-to\fR and \fB\-increment\fR.  When all
are specified correctly, the spinbox will use these values to control its
contents.  This value must be less than the \fB\-to\fR option.

If \fB\-values\fR is specified, it supercedes this option.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fBvalidateCommand\fR returns 0.  Setting
it to an empty string disables this feature (the default).  The best use of
this option is to set it to \fIbell\fR.  See \fBValidation\fR below for
more information.
.OP \-increment increment Increment
A floating-point value specifying the increment.  When used with
\fB\-from\fR and \fB\-to\fR, the value in the widget will be adjusted by
\fB\-increment\fR when a spin button is pressed (up adds the value,
down subtracts the value).
.OP \-readonlybackground readonlyBackground ReadonlyBackground
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
displayed, the contents will not be selectable, and the spinbox may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-to to To
A floating-point value corresponding to the highest value for the spinbox,
to be used in conjunction with \fB\-from\fR and \fB\-increment\fR.  When
all are specified correctly, the spinbox will use these values to control
its contents. If this value is less than the \fB\-from\fR option, then
\fB\-from\fR and \fB\-to\fR values are automatically swapped.
If \fB\-values\fR is specified, it supersedes this option.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBVALIDATION\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand
Specifies a script to evaluate when you want to validate the input in the
widget.  Setting it to an empty string disables this feature (the default).
Validation occurs according to the value of \fB\-validate\fR.
This command must return a valid Tcl boolean value.  If it returns 0 (or
the valid Tcl boolean equivalent) then the value of the widget will not
change and the \fB\-invalidcommand\fR will be evaluated if it is set.  If it
returns 1, then value will be changed.
See \fBVALIDATION\fR below for more information.
.OP \-values values Values
Must be a proper list value.  If specified, the spinbox will use these
values as to control its contents, starting with the first value.  This
option has precedence over the \fB\-from\fR and \fB\-to\fR range.
.OP \-width width Width
Specifies an integer value indicating the desired width of the spinbox window,
in average-size characters of the widget's font.







|
<
|




|






|

|







79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
displayed, the contents will not be selectable, and the spinbox may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-to to To
A floating-point value corresponding to the highest value for the spinbox,
to be used in conjunction with \fB\-from\fR and \fB\-increment\fR.  When
all are specified correctly, the spinbox will use these values to control
its contents.  This value must be greater than the \fB\-from\fR option.

If \fB\-values\fR is specified, it supercedes this option.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBValidation\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand
Specifies a script to evaluate when you want to validate the input in the
widget.  Setting it to an empty string disables this feature (the default).
Validation occurs according to the value of \fB\-validate\fR.
This command must return a valid Tcl boolean value.  If it returns 0 (or
the valid Tcl boolean equivalent) then the value of the widget will not
change and the \fBinvalidCommand\fR will be evaluated if it is set.  If it
returns 1, then value will be changed.
See \fBValidation\fR below for more information.
.OP \-values values Values
Must be a proper list value.  If specified, the spinbox will use these
values as to control its contents, starting with the first value.  This
option has precedence over the \fB\-from\fR and \fB\-to\fR range.
.OP \-width width Width
Specifies an integer value indicating the desired width of the spinbox window,
in average-size characters of the widget's font.
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
\fIpathName\fR's parent must exist.
.PP
A \fBspinbox\fR is an extended \fBentry\fR widget that allows he user
to move, or spin, through a fixed set of ascending or descending values
such as times or dates in addition to editing the value as in an
\fBentry\fR.  When first created, a spinbox's string is empty.
A portion of the spinbox may be selected as described below.
If a spinbox is exporting its selection (see the \fB\-exportselection\fR
option), then it will observe the standard protocols for handling the
selection;  spinbox selections are available as type \fBSTRING\fR.
Spinboxes also observe the standard Tk rules for dealing with the
input focus.  When a spinbox has the input focus it displays an
\fIinsertion cursor\fR to indicate where new characters will be
inserted.
.PP
Spinboxes are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed; commands described below
may be used to change the view in the window.  Spinboxes use
the standard \fB\-xscrollcommand\fR mechanism for interacting with
scrollbars (see the description of the \fB\-xscrollcommand\fR option
for details).  They also support scanning, as described below.
.SH VALIDATION
.PP
Validation works by setting the \fB\-validatecommand\fR
option to a script which will be evaluated according to the \fB\-validate\fR
option as follows:
.PP
.IP \fBnone\fR 10
Default.  This means no validation will occur.
.IP \fBfocus\fR 10
The \fB\-validatecommand\fR will be called when the spinbox receives or
loses focus.
.IP \fBfocusin\fR 10
The \fB\-validatecommand\fR will be called when the spinbox receives focus.
.IP \fBfocusout\fR 10
The \fB\-validatecommand\fR will be called when the spinbox loses focus.
.IP \fBkey\fR 10
The \fB\-validatecommand\fR will be called when the spinbox is edited.
.IP \fBall\fR 10
The \fB\-validatecommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the \fB\-validatecommand\fR
and \fB\-invalidcommand\fR scripts, just as you would in a \fBbind\fR script.  The
following substitutions are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5
Index of char string to be inserted/deleted, if any, otherwise \-1.







|











|
|



|
|





|


|

|

|

|

|
|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
\fIpathName\fR's parent must exist.
.PP
A \fBspinbox\fR is an extended \fBentry\fR widget that allows he user
to move, or spin, through a fixed set of ascending or descending values
such as times or dates in addition to editing the value as in an
\fBentry\fR.  When first created, a spinbox's string is empty.
A portion of the spinbox may be selected as described below.
If a spinbox is exporting its selection (see the \fBexportSelection\fR
option), then it will observe the standard protocols for handling the
selection;  spinbox selections are available as type \fBSTRING\fR.
Spinboxes also observe the standard Tk rules for dealing with the
input focus.  When a spinbox has the input focus it displays an
\fIinsertion cursor\fR to indicate where new characters will be
inserted.
.PP
Spinboxes are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed; commands described below
may be used to change the view in the window.  Spinboxes use
the standard \fBxScrollCommand\fR mechanism for interacting with
scrollbars (see the description of the \fBxScrollCommand\fR option
for details).  They also support scanning, as described below.
.SH VALIDATION
.PP
Validation works by setting the \fBvalidateCommand\fR
option to a script which will be evaluated according to the \fBvalidate\fR
option as follows:
.PP
.IP \fBnone\fR 10
Default.  This means no validation will occur.
.IP \fBfocus\fR 10
\fBvalidateCommand\fR will be called when the spinbox receives or
loses focus.
.IP \fBfocusin\fR 10
\fBvalidateCommand\fR will be called when the spinbox receives focus.
.IP \fBfocusout\fR 10
\fBvalidateCommand\fR will be called when the spinbox loses focus.
.IP \fBkey\fR 10
\fBvalidateCommand\fR will be called when the spinbox is edited.
.IP \fBall\fR 10
\fBvalidateCommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the \fBvalidateCommand\fR
and \fBinvalidCommand\fR, just as you would in a \fBbind\fR script.  The
following substitutions are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5
Index of char string to be inserted/deleted, if any, otherwise \-1.
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
The type of validation currently set.
.IP \fB%V\fR 5
The type of validation that triggered the callback
(key, focusin, focusout, forced).
.IP \fB%W\fR 5
The name of the spinbox widget.
.PP
In general, the \fB\-textvariable\fR and \fB\-validatecommand\fR can be
dangerous to mix.  Any problems have been overcome so that using the
\fB\-validatecommand\fR will not interfere with the traditional behavior of
the spinbox widget.  Using the \fB\-textvariable\fR for read-only purposes will
never cause problems.  The danger comes when you try set the
\fB\-textvariable\fR to something that the \fB\-validatecommand\fR would not
accept, which causes \fB\-validate\fR to become \fBnone\fR (the
\fB\-invalidcommand\fR will not be triggered).  The same happens
when an error occurs evaluating the \fB\-validatecommand\fR.
.PP
Primarily, an error will occur when the \fB\-validatecommand\fR or
\fB\-invalidcommand\fR encounters an error in its script while evaluating or
\fB\-validatecommand\fR does not return a valid Tcl boolean value.  The
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
spinbox widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the value of the widget
during validation and still have the \fB\-validate\fR option set, you should
include the command
.CS
     \fI%W config \-validate %v\fR
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the spinbox widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
spinbox widget to become out of sync with the \fB\-textvariable\fR.
.PP
Also, the \fB-validate\fR option will set itself to \fBnone\fR when the
spinbox value gets changed because of adjustment of \fB-from\fR or \fB-to\fR
and the \fB-validatecommand\fR returns false. For instance
.CS
     \fIspinbox pathName \-from 1 \-to 10 \-validate all \-vcmd {return 0}\fR
.CE
will in fact set the \fB-validate\fR option to \fBnone\fR because the default
value for the spinbox gets changed (due to the \fB-from\fR and \fB-to\fR
options) to a value not accepted by the validation script.
.PP
Moreover, forced validation is performed when invoking any spinbutton of
the spinbox. If the validation script returns false in this situation,
then the \fB-validate\fR option will be automatically set to \fBnone\fR.
.SH "WIDGET COMMAND"
.PP
The \fBspinbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for spinboxes take one or more indices as
arguments.  An index specifies a particular character in the spinbox's







|

|
|

|
|
|
|

|
|
|
|
|
|

|




|

|
|

|
|
|



|
|

<
<
<
<






|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228




229
230
231
232
233
234
235
236
237
238
239
240
241
242
The type of validation currently set.
.IP \fB%V\fR 5
The type of validation that triggered the callback
(key, focusin, focusout, forced).
.IP \fB%W\fR 5
The name of the spinbox widget.
.PP
In general, the \fBtextVariable\fR and \fBvalidateCommand\fR can be
dangerous to mix.  Any problems have been overcome so that using the
\fBvalidateCommand\fR will not interfere with the traditional behavior of
the spinbox widget.  Using the \fBtextVariable\fR for read-only purposes will
never cause problems.  The danger comes when you try set the
\fBtextVariable\fR to something that the \fBvalidateCommand\fR would not
accept, which causes \fBvalidate\fR to become \fBnone\fR (the
\fBinvalidCommand\fR will not be triggered).  The same happens
when an error occurs evaluating the \fBvalidateCommand\fR.
.PP
Primarily, an error will occur when the \fBvalidateCommand\fR or
\fBinvalidCommand\fR encounters an error in its script while evaluating or
\fBvalidateCommand\fR does not return a valid Tcl boolean value.  The
\fBvalidate\fR option will also set itself to \fBnone\fR when you edit the
spinbox widget from within either the \fBvalidateCommand\fR or the
\fBinvalidCommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the value of the widget
during validation and still have the \fBvalidate\fR option set, you should
include the command
.CS
     \fI%W config \-validate %v\fR
.CE
in the \fBvalidateCommand\fR or \fBinvalidCommand\fR (whichever one you
were editing the spinbox widget from).  It is also recommended to not set an
associated \fBtextVariable\fR during validation, as that can cause the
spinbox widget to become out of sync with the \fBtextVariable\fR.
.PP
Also, the \fBvalidate\fR option will set itself to \fBnone\fR when the
spinbox value gets changed because of adjustment of \fBfrom\fR or \fBto\fR
and the \fBvalidateCommand\fR returns false. For instance
.CS
     \fIspinbox pathName \-from 1 \-to 10 \-validate all \-vcmd {return 0}\fR
.CE
will in fact set the \fBvalidate\fR option to \fBnone\fR because the default
value for the spinbox gets changed (due to the \fBfrom\fR and \fBto\fR
options) to a value not accepted by the validation script.




.SH "WIDGET COMMAND"
.PP
The \fBspinbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for spinboxes take one or more indices as
arguments.  An index specifies a particular character in the spinbox's
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR
Returns 1 if there is are characters selected in the spinbox,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart end\fR
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the spinbox's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR







|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR
Returns 1 if there is are characters selected in the spinbox,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart\fR \fIend\fR
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the spinbox's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476


477
478
479
480
481
482
483

484
485
486
487
488
489
490
.TP
\fIpathName \fBset\fR ?\fIstring\fR?
If \fIstring\fR is specified, the spinbox will try and set it to this
value, otherwise it just returns the spinbox's string.
If validation is on, it will occur when setting the string.
.TP
\fIpathName \fBvalidate\fR
This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the spinbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview \fIindex\fR
Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR
screenfuls. If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE

.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for spinboxes that give them
the following default behavior.
In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or







|
|
|


















|











|
<
|

>
>
|
|


<
<

>







426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474


475
476
477
478
479
480
481
482
483
.TP
\fIpathName \fBset\fR ?\fIstring\fR?
If \fIstring\fR is specified, the spinbox will try and set it to this
value, otherwise it just returns the spinbox's string.
If validation is on, it will occur when setting the string.
.TP
\fIpathName \fBvalidate\fR
This command is used to force an evaluation of the \fBvalidateCommand\fR
independent of the conditions specified by the \fBvalidate\fR option.
This is done by temporarily setting the \fBvalidate\fR option to \fBall\fR.
It returns 0 or 1.
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the spinbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR
Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.


.RE

.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for spinboxes that give them
the following default behavior.
In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
.IP [5]
Clicking mouse button 1 with the Control key down will position the
insertion cursor in the spinbox without affecting the selection.
.IP [6]
If any normal printing characters are typed in a spinbox, they are
inserted at the point of the insertion cursor.
.IP [7]
The view in the spinbox can be adjusted by dragging with the middle
mouse button (button 2, or button 3 in TkAqua). If the middle mouse
button is clicked without moving the mouse, the selection is copied
into the spinbox at the position of the mouse cursor.
.IP [8]
If the mouse is dragged out of the spinbox on the left or right sides
while button 1 is pressed, the spinbox will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the







|
<
|
|







507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
.IP [5]
Clicking mouse button 1 with the Control key down will position the
insertion cursor in the spinbox without affecting the selection.
.IP [6]
If any normal printing characters are typed in a spinbox, they are
inserted at the point of the insertion cursor.
.IP [7]
The view in the spinbox can be adjusted by dragging with mouse button 2.

If mouse button 2 is clicked without moving the mouse, the selection
is copied into the spinbox at the position of the mouse cursor.
.IP [8]
If the mouse is dragged out of the spinbox on the left or right sides
while button 1 is pressed, the spinbox will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the
594
595
596
597
598
599
600
601
602
603
604
605
606
607
If the spinbox is disabled using the \fB\-state\fR option, then the spinbox's
view can still be adjusted and text in the spinbox can still be selected,
but no insertion cursor will be displayed and no text modifications will
take place.
.PP
The behavior of spinboxes can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
ttk::spinbox(n)
.SH KEYWORDS
spinbox, entry, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
<


<
<
<
586
587
588
589
590
591
592
593

594
595



If the spinbox is disabled using the \fB\-state\fR option, then the spinbox's
view can still be adjusted and text in the spinbox can still be selected,
but no insertion cursor will be displayed and no text modifications will
take place.
.PP
The behavior of spinboxes can be changed by defining new bindings for
individual widgets or by redefining the class bindings.


.SH KEYWORDS
spinbox, entry, widget



Changes to doc/text.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34

35
36
37

38

39
40

41
42
43
44

45
46
47

48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67

68
69
70
71
72
73

74
75

76
77
78

79

80
81
82
83

84
85
86
87
88
89

90
91
92
93

94
95
96
97
98

99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134

135
136
137

138
139
140
141
142
143
144
145

146
147
148

149
150
151
152
153

154
155
156
157

158

159

160
161
162

163
164

165
166
167

168
169
170

171
172

173
174
175

176
177
178

179
180
181
182
183

184
185
186

187
188
189

190
191

192
193
194
195
196
197

198

199

200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217

218
219

220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236

237
238
239
240
241
242

243
244
245
246
247
248

249

250
251
252
253

254

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274


275
276
277
278
279
280

281
282

283
284
285
286
287

288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306

307
308
309

310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339

340
341
342
343
344
345

346
347
348
349
350
351

352
353
354
355
356
357
358
359


360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383

384
385

386
387
388
389

390
391
392
393

394
395

396

397
398
399
400
401

402
403
404
405
406
407
408
409
410

411

412
413
414

415
416
417
418
419
420
421

422
423
424
425
426

427
428
429

430
431
432
433

434
435



436
437
438
439
440
441

442
443
444
445
446

447

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474

475

476

477
478
479
480
481
482
483

484
485

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525


526
527
528
529
530
531

532

533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

564

565
566
567
568
569
570

571
572
573
574
575

576

577
578
579
580
581

582
583
584

585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621

622
623

624
625

626
627
628

629

630
631


632
633

634
635


636
637

638
639

640
641
642
643

644

645
646

647
648
649


650
651

652
653
654
655
656
657

658
659
660

661
662
663
664
665
666

667
668
669
670
671
672
673
674

675
676


677
678

679
680
681
682

683
684
685
686

687
688
689
690





691
692

693
694
695




696

697
698

699
700
701

702

703
704
705

706
707
708
709
710
711
712
713
714
715

716
717
718
719
720
721
722

723
724

725
726


727
728

729
730
731
732
733
734

735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750

751
752
753
754

755
756
757

758
759

760
761
762
763

764
765
766
767
768

769




770
771
772
773
774
775

776
777

778
779
780

781

782
783
784
785
786
787

788
789
790
791
792
793
794
795
796

797

798
799
800
801
802
803
804

805
806
807

808
809
810
811
812
813
814
815
816
817

818
819
820
821
822
823

824
825
826
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841

842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858



859
860
861
862

863
864
865
866
867
868
869
870
871

872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
889
890

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916

917
918

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962

963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051

1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063

1064
1065
1066

1067

1068
1069
1070
1071
1072
1073

1074

1075
1076
1077
1078
1079

1080
1081
1082
1083

1084
1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095
1096


1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137

1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159

1160
1161
1162
1163
1164

1165
1166

1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH text n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
text, tk_textCopy, tk_textCut, tk_textPaste \- Create and manipulate 'text' hypertext editing widgets
.SH SYNOPSIS
.nf
\fBtext\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_textCopy\fR \fIpathName\fR
\fBtk_textCut\fR \fIpathName\fR
\fBtk_textPaste\fR \fIpathName\fR
.SO
\-background	\-highlightthickness	\-relief
\-borderwidth	\-insertbackground	\-selectbackground
\-cursor	\-insertborderwidth	\-selectborderwidth
\-exportselection	\-insertofftime	\-selectforeground
\-font	\-insertontime	\-setgrid
\-foreground	\-insertwidth	\-takefocus
\-highlightbackground	\-padx	\-xscrollcommand
\-highlightcolor	\-pady	\-yscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-autoseparators autoSeparators AutoSeparators
Specifies a boolean that says whether separators are automatically inserted in
the undo stack. Only meaningful when the \fB\-undo\fR option is true.

.OP \-blockcursor blockCursor BlockCursor

Specifies a boolean that says whether the blinking insertion cursor should be
drawn as a character-sized rectangular block. If false (the default) a thin
vertical line is used for the insertion cursor.

.OP \-endline endLine EndLine

Specifies an integer line index representing the line of the underlying
textual data store that should be just after the last line contained in

the widget. This allows a text widget to reflect only a portion of a
larger piece of text. Instead of an integer, the empty string can be
provided to this configuration option, which will configure the widget
to end at the very last line in the textual data store.

.OP \-height height Height
Specifies the desired height for the window, in units of characters in the
font given by the \fB\-font\fR option. Must be at least one.

.OP \-inactiveselectbackground inactiveSelectBackground Foreground

Specifies the colour to use for the selection (the \fBsel\fR tag) when the
window does not have the input focus. If empty, \fB{}\fR, then no selection is
shown when the window does not have the focus.
.OP \-insertunfocussed insertUnfocussed InsertUnfocussed
.VS 8.6
Specifies how to display the insertion cursor when the widget does not have
the focus. Must be \fBnone\fR (the default) which means to not display the
cursor, \fBhollow\fR which means to display a hollow box, or \fBsolid\fR which
means to display a solid box. Note that \fBhollow\fR and \fBsolid\fR will
appear very similar when the \fB\-blockcursor\fR option is false.
.VE 8.6
.OP \-maxundo maxUndo MaxUndo
Specifies the maximum number of compound undo actions on the undo stack. A
zero or a negative value imply an unlimited undo stack.
.OP \-spacing1 spacing1 Spacing1
Requests additional space above each text line in the widget, using any of the

standard forms for screen distances. If a line wraps, this option only applies
to the first line on the display. This option may be overridden with
\fB\-spacing1\fR options in tags.

.OP \-spacing2 spacing2 Spacing2
For lines that wrap (so that they cover more than one line on the display)
this option specifies additional space to provide between the display lines
that represent a single line of text. The value may have any of the standard
forms for screen distances. This option may be overridden with
\fB\-spacing2\fR options in tags.

.OP \-spacing3 spacing3 Spacing3
Requests additional space below each text line in the widget, using any of the

standard forms for screen distances. If a line wraps, this option only applies
to the last line on the display. This option may be overridden with
\fB\-spacing3\fR options in tags.

.OP \-startline startLine StartLine

Specifies an integer line index representing the first line of the underlying
textual data store that should be contained in the widget. This allows a text
widget to reflect only a portion of a larger piece of text. Instead of an
integer, the empty string can be provided to this configuration option, which

will configure the widget to start at the very first line in the textual data
store.
.OP \-state state State
Specifies one of two states for the text: \fBnormal\fR or \fBdisabled\fR. If
the text is disabled then characters may not be inserted or deleted and no
insertion cursor will be displayed, even if the input focus is in the widget.

.OP \-tabs tabs Tabs
Specifies a set of tab stops for the window. The option's value consists of a
list of screen distances giving the positions of the tab stops, each of which
is a distance relative to the left edge of the widget (excluding borders,

padding, etc). Each position may optionally be followed in the next list
element by one of the keywords \fBleft\fR, \fBright\fR, \fBcenter\fR, or
\fBnumeric\fR, which specifies how to justify text relative to the tab stop.
\fBLeft\fR is the default; it causes the text following the tab character to
be positioned with its left edge at the tab position. \fBRight\fR means that

the right edge of the text following the tab character is positioned at the
tab position, and \fBcenter\fR means that the text is centered at the tab
position. \fBNumeric\fR means that the decimal point in the text is positioned
at the tab position; if there is no decimal point then the least significant
digit of the number is positioned just to the left of the tab position; if
there is no number in the text then the text is right-justified at the tab

position. For example,
.QW "\fB\-tabs {2c left 4c 6c center}\fR"
creates three tab stops at two-centimeter intervals; the first two use left
justification and the third uses center justification.
.RS
.PP
If the list of tab stops does not have enough elements to cover all of the
tabs in a text line, then Tk extrapolates new tab stops using the spacing and
alignment from the last tab stop in the list. Tab distances must be strictly
positive, and must always increase from one tab stop to the next (if not, an

error is thrown). The value of the \fB\-tabs\fR option may be overridden by
\fB\-tabs\fR options in tags.
.PP
If no \fB\-tabs\fR option is specified, or if it is specified as an empty
list, then Tk uses default tabs spaced every eight (average size) characters.
To achieve a different standard spacing, for example every 4 characters,
simply configure the widget with
.QW "\fB\-tabs \N'34'[expr {4 * [font measure $font 0]}] left\N'34' \-tabstyle wordprocessor\fR" .
.RE
.OP \-tabstyle tabStyle TabStyle
Specifies how to interpret the relationship between tab stops on a line and
tabs in the text of that line. The value must be \fBtabular\fR (the default)
or \fBwordprocessor\fR. Note that tabs are interpreted as they are encountered
in the text. If the tab style is \fBtabular\fR then the \fIn\fR'th tab
character in the line's text will be associated with the \fIn\fR'th tab stop

defined for that line. If the tab character's x coordinate falls to the right
of the \fIn\fR'th tab stop, then a gap of a single space will be inserted as a
fallback. If the tab style is \fBwordprocessor\fR then any tab character being
laid out will use (and be defined by) the first tab stop to the right of the
preceding characters already laid out on that line. The value of the

\fB\-tabstyle\fR option may be overridden by \fB\-tabstyle\fR options in tags.
.OP \-undo undo Undo
Specifies a boolean that says whether the undo mechanism is active or not.

.OP \-width width Width
Specifies the desired width for the window in units of characters in the font
given by the \fB\-font\fR option. If the font does not have a uniform width
then the width of the character
.QW 0
is used in translating from character units to screen units.
.OP \-wrap wrap Wrap
Specifies how to handle lines in the text that are too long to be displayed in

a single line of the text's window. The value must be \fBnone\fR or \fBchar\fR
or \fBword\fR. A wrap mode of \fBnone\fR means that each line of text appears
as exactly one line on the screen; extra characters that do not fit on the

screen are not displayed. In the other modes each line of text will be broken
up into several screen lines if necessary to keep all the characters visible.
In \fBchar\fR mode a screen line break may occur after any character; in
\fBword\fR mode a line break will only be made at word boundaries.
.BE

.SH DESCRIPTION
.PP
The \fBtext\fR command creates a new window (given by the \fIpathName\fR
argument) and makes it into a text widget. Additional options, described

above, may be specified on the command line or in the option database to

configure aspects of the text such as its default background color and relief.

The \fBtext\fR command returns the path name of the new window.
.PP
A text widget displays one or more lines of text and allows that text to be

edited. Text widgets support four different kinds of annotations on the text,
called tags, marks, embedded windows or embedded images. Tags allow different

portions of the text to be displayed with different fonts and colors. In
addition, Tcl commands can be associated with tags so that scripts are invoked
when particular actions such as keystrokes and mouse button presses occur in

particular ranges of the text. See \fBTAGS\fR below for more details.
.PP
The second form of annotation consists of floating markers in the text called

.QW marks .
Marks are used to keep track of various interesting positions in the text as

it is edited. See \fBMARKS\fR below for more details.
.PP
The third form of annotation allows arbitrary windows to be embedded in a text

widget. See \fBEMBEDDED WINDOWS\fR below for more details.
.PP
The fourth form of annotation allows Tk images to be embedded in a text

widget. See \fBEMBEDDED IMAGES\fR below for more details.
.PP
The text widget also has a built-in undo/redo mechanism. See
\fBTHE UNDO MECHANISM\fR below for more details.
.PP

The text widget allows for the creation of peer widgets. These are other text
widgets which share the same underlying data (text, marks, tags, images, etc).
See \fBPEER WIDGETS\fR below for more details.

.SH INDICES
.PP
Many of the widget commands for texts take one or more indices as arguments.

An index is a string used to indicate a particular place within a text, such
as a place to insert characters or one endpoint of a range of characters to

delete. Indices have the syntax
.CS
\fIbase modifier modifier modifier ...\fR
.CE
Where \fIbase\fR gives a starting point and the \fImodifier\fRs adjust the
index from the starting point (e.g. move forward or backward one character).

Every index must contain a \fIbase\fR, but the \fImodifier\fRs are optional.

Most modifiers (as documented below) allow an optional submodifier. Valid

submodifiers are \fBany\fR and \fBdisplay\fR. If the submodifier is
abbreviated, then it must be followed by whitespace, but otherwise there need
be no space between the submodifier and the following \fImodifier\fR.
Typically the \fBdisplay\fR submodifier adjusts the meaning of the following
\fImodifier\fR to make it refer to visual or non-elided units rather than
logical units, but this is explained for each relevant case below. Lastly,
where \fIcount\fR is used as part of a modifier, it can be positive or
negative, so
.QW "\fIbase\fR \- \-3 lines"
is perfectly valid (and equivalent to
.QW "\fIbase\fR +3lines" ).

.PP
The \fIbase\fR for an index must have one of the following forms:
.TP 12
\fIline\fB.\fIchar\fR
.
Indicates \fIchar\fR'th character on line \fIline\fR. Lines are numbered from
1 for consistency with other UNIX programs that use this numbering scheme.

Within a line, characters are numbered from 0. If \fIchar\fR is \fBend\fR then
it refers to the newline character that ends the line.

.TP 12
\fB@\fIx\fB,\fIy\fR
.
Indicates the character that covers the pixel whose x and y coordinates within
the text's window are \fIx\fR and \fIy\fR.
.TP 12
\fBend\fR
.
Indicates the end of the text (the character just after the last newline).

.TP 12
\fImark\fR
.
Indicates the character just after the mark whose name is \fImark\fR.
.TP 12
\fItag\fB.first\fR
.
Indicates the first character in the text that has been tagged with \fItag\fR.

This form generates an error if no characters are currently tagged with
\fItag\fR.
.TP 12
\fItag\fB.last\fR
.
Indicates the character just after the last one in the text that has been

tagged with \fItag\fR. This form generates an error if no characters are
currently tagged with \fItag\fR.
.TP 12
\fIpathName\fR
.
Indicates the position of the embedded window whose name is \fIpathName\fR.

This form generates an error if there is no embedded window by the given name.

.TP 12
\fIimageName\fR
.
Indicates the position of the embedded image whose name is \fIimageName\fR.

This form generates an error if there is no embedded image by the given name.

.PP
If the \fIbase\fR could match more than one of the above forms, such as a
\fImark\fR and \fIimageName\fR both having the same value, then the form
earlier in the above list takes precedence. If modifiers follow the base
index, each one of them must have one of the forms listed below. Keywords such
as \fBchars\fR and \fBwordend\fR may be abbreviated as long as the
abbreviation is unambiguous.
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index forward by \fIcount\fR characters, moving to later lines in
the text if necessary. If there are fewer than \fIcount\fR characters in the
text after the current index, then set the index to the last index in the
text. Spaces on either side of \fIcount\fR are optional. If the \fBdisplay\fR
submodifier is given, elided characters are skipped over without being
counted. If \fBany\fR is given, then all characters are counted. For
historical reasons, if neither modifier is given then the count actually takes
place in units of index positions (see \fBINDICES\fR for details). This
behaviour may be changed in a future major release, so if you need an index
count, you are encouraged to use \fBindices\fR instead wherever possible.


.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index backward by \fIcount\fR characters, moving to earlier lines
in the text if necessary. If there are fewer than \fIcount\fR characters in
the text before the current index, then set the index to the first index in

the text (1.0). Spaces on either side of \fIcount\fR are optional. If the
\fBdisplay\fR submodifier is given, elided characters are skipped over without

being counted. If \fBany\fR is given, then all characters are counted. For
historical reasons, if neither modifier is given then the count actually takes
place in units of index positions (see \fBINDICES\fR for details). This
behavior may be changed in a future major release, so if you need an index
count, you are encouraged to use \fBindices\fR instead wherever possible.

.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index forward by \fIcount\fR index positions, moving to later lines
in the text if necessary. If there are fewer than \fIcount\fR index positions
in the text after the current index, then set the index to the last index
position in the text. Spaces on either side of \fIcount\fR are optional. Note
that an index position is either a single character or a single embedded image

or embedded window. If the \fBdisplay\fR submodifier is given, elided indices
are skipped over without being counted. If \fBany\fR is given, then all
indices are counted; this is also the default behaviour if no modifier is
given.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index backward by \fIcount\fR index positions, moving to earlier
lines in the text if necessary. If there are fewer than \fIcount\fR index
positions in the text before the current index, then set the index to the
first index position (1.0) in the text. Spaces on either side of \fIcount\fR

are optional. If the \fBdisplay\fR submodifier is given, elided indices are
skipped over without being counted. If \fBany\fR is given, then all indices
are counted; this is also the default behaviour if no modifier is given.

.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index forward by \fIcount\fR lines, retaining the same character
position within the line. If there are fewer than \fIcount\fR lines after the
line containing the current index, then set the index to refer to the same
character position on the last line of the text. Then, if the line is not long
enough to contain a character at the indicated character position, adjust the

character position to refer to the last character of the line (the newline).
Spaces on either side of \fIcount\fR are optional. If the \fBdisplay\fR
submodifier is given, then each visual display line is counted separately.
Otherwise, if \fBany\fR (or no modifier) is given, then each logical line (no
matter how many times it is visually wrapped) counts just once. If the
relevant lines are not wrapped, then these two methods of counting are
equivalent.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index backward by \fIcount\fR logical lines, retaining the same
character position within the line. If there are fewer than \fIcount\fR lines
before the line containing the current index, then set the index to refer to
the same character position on the first line of the text. Then, if the line
is not long enough to contain a character at the indicated character position,
adjust the character position to refer to the last character of the line (the

newline). Spaces on either side of \fIcount\fR are optional. If the
\fBdisplay\fR submodifier is given, then each visual display line is counted
separately. Otherwise, if \fBany\fR (or no modifier) is given, then each
logical line (no matter how many times it is visually wrapped) counts just
once. If the relevant lines are not wrapped, then these two methods of
counting are equivalent.

.TP
?\fIsubmodifier\fR? \fBlinestart\fR
.
Adjust the index to refer to the first index on the line. If the \fBdisplay\fR
submodifier is given, this is the first index on the display line, otherwise
on the logical line.

.TP
?\fIsubmodifier\fR? \fBlineend\fR
.
Adjust the index to refer to the last index on the line (the newline). If the
\fBdisplay\fR submodifier is given, this is the last index on the display
line, otherwise on the logical line.

.TP
?\fIsubmodifier\fR? \fBwordstart\fR
.
Adjust the index to refer to the first character of the word containing the
current index. A word consists of any number of adjacent characters that are
letters, digits, or underscores, or a single character that is not one of
these. If the \fBdisplay\fR submodifier is given, this only examines
non-elided characters, otherwise all characters (elided or not) are examined.


.TP
?\fIsubmodifier\fR? \fBwordend\fR
.
Adjust the index to refer to the character just after the last one of the word
containing the current index. If the current index refers to the last
character of the text then it is not modified. If the \fBdisplay\fR
submodifier is given, this only examines non-elided characters, otherwise all
characters (elided or not) are examined.
.PP
If more than one modifier is present then they are applied in left-to-right
order. For example, the index
.QW "\fBend \- 1 chars\fR"
refers to the next-to-last character in the text and
.QW "\fBinsert wordstart \- 1 c\fR"
refers to the character just before the first one in the word containing the

insertion cursor. Modifiers are applied one by one in this left to right
order, and after each step the resulting index is constrained to be a valid
index in the text widget. So, for example, the index
.QW "\fB1.0 \-1c +1c\fR"
refers to the index
.QW \fB2.0\fR .
.PP
Where modifiers result in index changes by display lines, display chars or
display indices, and the \fIbase\fR refers to an index inside an elided tag,

that base index is considered to be equivalent to the first following
non-elided index.

.SH TAGS
.PP
The first form of annotation in text widgets is a tag. A tag is a textual
string that is associated with some of the characters in a text. Tags may

contain arbitrary characters, but it is probably best to avoid using the
characters
.QW " "
(space), \fB+\fR, or \fB\-\fR: these characters have special meaning in

indices, so tags containing them cannot be used as indices. There may be any
number of tags associated with characters in a text. Each tag may refer to a

single character, a range of characters, or several ranges of characters. An

individual character may have any number of tags associated with it.
.PP
A priority order is defined among tags, and this order is used in implementing
some of the tag-related functions described below. When a tag is defined (by
associating it with characters or setting its display options or binding

commands to it), it is given a priority higher than any existing tag. The
priority order of tags may be redefined using the
.QW "\fIpathName \fBtag raise\fR"
and
.QW "\fIpathName \fBtag lower\fR"
widget commands.
.PP
Tags serve three purposes in text widgets. First, they control the way
information is displayed on the screen. By default, characters are displayed

as determined by the \fB\-background\fR, \fB\-font\fR, and \fB\-foreground\fR

options for the text widget. However, display options may be associated with
individual tags using the
.QW "\fIpathName \fBtag configure\fR"

widget command. If a character has been tagged, then the display options
associated with the tag override the default display style. The following
options are currently supported for tags:
.TP
\fB\-background \fIcolor\fR
.
\fIColor\fR specifies the background color to use for characters associated

with the tag. It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-bgstipple \fIbitmap\fR
.
\fIBitmap\fR specifies a bitmap that is used as a stipple pattern for the

background. It may have any of the forms accepted by \fBTk_GetBitmap\fR. If
\fIbitmap\fR has not been specified, or if it is specified as an empty string,
then a solid fill will be used for the background.

.TP
\fB\-borderwidth \fIpixels\fR
.
\fIPixels\fR specifies the width of a border to draw around the tag using any

of the forms accepted by \fBTk_GetPixels\fR. This option should be used in
conjunction with the \fB\-relief\fR option to provide the desired border.



.TP
\fB\-elide \fIboolean\fR
.
\fIElide\fR specifies whether the data should be elided. Elided data
(characters, images, embedded windows, etc.) is not displayed and takes no
space on screen, but further on behaves just as normal data.

.TP
\fB\-fgstipple \fIbitmap\fR
.
\fIBitmap\fR specifies a bitmap that is used as a stipple pattern when drawing
text and other foreground information such as underlines. It may have any of

the forms accepted by \fBTk_GetBitmap\fR. If \fIbitmap\fR has not been

specified, or if it is specified as an empty string, then a solid fill will be
used.
.TP
\fB\-font \fIfontName\fR
.
\fIFontName\fR is the name of a font to use for drawing characters. It may
have any of the forms accepted by \fBTk_GetFont\fR.
.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the color to use when drawing text and other foreground
information such as underlines. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.TP
\fB\-justify \fIjustify\fR
.
If the first non-elided character of a display line has a tag for which this
option has been specified, then \fIjustify\fR determines how to justify the

line. It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR. If a line
wraps, then the justification for each line on the display is determined by
the first non-elided character of that display line.
.TP
\fB\-lmargin1 \fIpixels\fR
.
If the first non-elided character of a text line has a tag for which this
option has been specified, then \fIpixels\fR specifies how much the line
should be indented from the left edge of the window. \fIPixels\fR may have any

of the standard forms for screen distances. If a line of text wraps, this

option only applies to the first line on the display; the \fB\-lmargin2\fR

option controls the indentation for subsequent lines.
.TP
\fB\-lmargin2 \fIpixels\fR
.
If the first non-elided character of a display line has a tag for which this
option has been specified, and if the display line is not the first for its
text line (i.e., the text line has wrapped), then \fIpixels\fR specifies how

much the line should be indented from the left edge of the window.
\fIPixels\fR may have any of the standard forms for screen distances. This

option is only used when wrapping is enabled, and it only applies to the
second and later display lines for a text line.
.TP
\fB\-lmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-lmargin1\fR or
\fB\-lmargin2\fR. It may have any of the forms accepted by
\fBTk_GetColor\fR. If \fIcolor\fR has not been specified, or if it is
specified as an empty string, then the color used is specified by the
\fB-background\fR tag option (or, if this is also unspecified, by the
\fB-background\fR widget option).
.TP
\fB\-offset \fIpixels\fR
.
\fIPixels\fR specifies an amount by which the text's baseline should be offset
vertically from the baseline of the overall line, in pixels. For example, a

positive offset can be used for superscripts and a negative offset can be used

for subscripts. \fIPixels\fR may have any of the standard forms for screen
distances.
.TP
\fB\-overstrike \fIboolean\fR
.
Specifies whether or not to draw a horizontal rule through the middle of
characters. \fIBoolean\fR may have any of the forms accepted by
\fBTcl_GetBoolean\fR.
.TP
\fB\-overstrikefg \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the overstrike. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
specified by the \fB\-foreground\fR tag option is used.
.TP
\fB\-relief \fIrelief\fR
.
\fIRelief\fR specifies the relief style to use for drawing the border, in any
of the forms accepted by \fBTk_GetRelief\fR. This option is used in
conjunction with the \fB\-borderwidth\fR option to enable to the desired
border appearance.


.TP
\fB\-rmargin \fIpixels\fR
.
If the first non-elided character of a display line has a tag for which this
option has been specified, then \fIpixels\fR specifies how wide a margin to
leave between the end of the line and the right edge of the window.

\fIPixels\fR may have any of the standard forms for screen distances. This

option is only used when wrapping is enabled. If a text line wraps, the right
margin for each line on the display is determined by the first non-elided
character of that display line.
.TP
\fB\-rmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-rmargin\fR. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
used is specified by the \fB-background\fR tag option (or, if this is also
unspecified, by the \fB-background\fR widget option).
.TP
\fB\-selectbackground \fIcolor\fR
\fIColor\fR specifies the background color to use when displaying selected
items. It may have any of the forms accepted by \fBTk_GetColor\fR. If
\fIcolor\fR has not been specified, or if it is specified as an empty
string, then the color specified by the \fB\-background\fR tag option is
used.
.TP
\fB\-selectforeground \fIcolor\fR
\fIColor\fR specifies the foreground color to use when displaying selected
items. It may have any of the forms accepted by \fBTk_GetColor\fR. If
\fIcolor\fR has not been specified, or if it is specified as an empty
string, then the color specified by the \fB\-foreground\fR tag option is
used.
.TP
\fB\-spacing1 \fIpixels\fR
.
\fIPixels\fR specifies how much additional space should be left above each
text line, using any of the standard forms for screen distances. If a line

wraps, this option only applies to the first line on the display.

.TP
\fB\-spacing2 \fIpixels\fR
.
For lines that wrap, this option specifies how much additional space to leave
between the display lines for a single text line. \fIPixels\fR may have any of
the standard forms for screen distances.

.TP
\fB\-spacing3 \fIpixels\fR
.
\fIPixels\fR specifies how much additional space should be left below each
text line, using any of the standard forms for screen distances. If a line

wraps, this option only applies to the last line on the display.

.TP
\fB\-tabs \fItabList\fR
.
\fITabList\fR specifies a set of tab stops in the same form as for the
\fB\-tabs\fR option for the text widget. This option only applies to a display

line if it applies to the first non-elided character on that display line. If
this option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default). If the option is specified as a

non-empty string that is an empty list, such as \fB\-tags\0{\0}\fR, then it
requests default 8-character tabs as described for the \fB\-tags\fR widget
option.
.TP
\fB\-tabstyle \fIstyle\fR
.
\fIStyle\fR specifies either the \fItabular\fR or \fIwordprocessor\fR style of

tabbing to use for the text widget. This option only applies to a display line
if it applies to the first non-elided character on that display line. If this
option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default).
.TP
\fB\-underline \fIboolean\fR
.
\fIBoolean\fR specifies whether or not to draw an underline underneath
characters. It may have any of the forms accepted by \fBTcl_GetBoolean\fR.
.TP
\fB\-underlinefg \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the underline. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
specified by the \fB\-foreground\fR tag option is used.
.TP
\fB\-wrap \fImode\fR
.
\fIMode\fR specifies how to handle lines that are wider than the text's
window. This option only applies to a display line if it applies to the
first non-elided character on that display line. It has the same legal
values as the \fB\-wrap\fR option for the text widget: \fBnone\fR,
\fBchar\fR, or \fBword\fR. If this tag option is specified, it
overrides the \fB\-wrap\fR option for the text widget.
.PP
If a character has several tags associated with it, and if their display
options conflict, then the options of the highest priority tag are used. If a

particular display option has not been specified for a particular tag, or if
it is specified as an empty string, then that option will never be used; the

next-highest-priority tag's option will used instead. If no tag specifies a
particular display option, then the default style for the widget will be used.

.PP
The second purpose for tags is event bindings. You can associate bindings with

a tag in much the same way you can associate bindings with a widget class:
whenever particular X events occur on characters with the given tag, a given
Tcl command will be executed. Tag bindings can be used to give behaviors to

ranges of characters; among other things, this allows hypertext-like features

to be implemented. For details, see the description of the
.QW "\fIpathName \fBtag bind\fR"


widget command below. Tag bindings are shared between all peer widgets
(including any bindings for the special \fBsel\fR tag).

.PP
The third use for tags is in managing the selection. See \fBTHE SELECTION\fR


below. With the exception of the special \fBsel\fR tag, all tags are shared
between peer text widgets, and may be manipulated on an equal basis from any

such widget. The \fBsel\fR tag exists separately and independently in each
peer text widget (but any tag bindings to \fBsel\fR are shared).

.SH MARKS
.PP
The second form of annotation in text widgets is a mark. Marks are used for
remembering particular places in a text. They are something like tags, in that

they have names and they refer to places in the file, but a mark is not

associated with particular characters. Instead, a mark is associated with the
gap between two characters. Only a single position may be associated with a

mark at any given time. If the characters around a mark are deleted the mark
will still remain; it will just have new neighbor characters. In contrast, if
the characters containing a tag are deleted then the tag will no longer have


an association with characters in the file. Marks may be manipulated with the
.QW "\fIpathName \fBmark\fR"

widget command, and their current locations may be determined by using the
mark name as an index in widget commands.
.PP
Each mark also has a
.QW gravity ,
which is either \fBleft\fR or \fBright\fR. The gravity for a mark specifies

what happens to the mark when text is inserted at the point of the mark. If a
mark has left gravity, then the mark is treated as if it were attached to the
character on its left, so the mark will remain to the left of any text

inserted at the mark position. If the mark has right gravity, new text
inserted at the mark position will appear to the left of the mark (so that the
mark remains rightmost). The gravity for a mark defaults to \fBright\fR.
.PP
The name space for marks is different from that for tags: the same name may be
used for both a mark and a tag, but they will refer to different things.

.PP
Two marks have special significance. First, the mark \fBinsert\fR is
associated with the insertion cursor, as described under
\fBTHE INSERTION CURSOR\fR
below. Second, the mark \fBcurrent\fR is associated with the
character closest to the mouse and is adjusted automatically to track the
mouse position and any changes to the text in the widget (one exception:
\fBcurrent\fR is not updated in response to mouse motions if a mouse button is

down; the update will be deferred until all mouse buttons have been released).
Neither of these special marks may be deleted. With the exception of these two


special marks, all marks are shared between peer text widgets, and may be
manipulated on an equal basis from any peer.

.SH "EMBEDDED WINDOWS"
.PP
The third form of annotation in text widgets is an embedded window. Each
embedded window annotation causes a window to be displayed at a particular

point in the text. There may be any number of embedded windows in a text
widget, and any widget may be used as an embedded window (subject to the usual
rules for geometry management, which require the text window to be the parent
of the embedded window or a descendant of its parent).

.PP
The embedded window's position on the screen will be updated as the text is
modified or scrolled, and it will be mapped and unmapped as it moves into and
out of the visible area of the text widget. Each embedded window occupies one





unit's worth of index space in the text widget, and it may be referred to
either by the name of its embedded window or by its position in the widget's

index space. If the range of text containing the embedded window is deleted
then the window is destroyed. Similarly if the text widget as a whole is
deleted, then the window is destroyed.




.PP

Eliding an embedded window immediately after scheduling it for creation via
\fIpathName \fBwindow create \fIindex \fB-create\fR will prevent it from being

effectively created. Uneliding an elided embedded window scheduled for creation
via \fIpathName \fBwindow create \fIindex \fB-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded

window, the latter won't get automatically recreated.

.PP
When an embedded window is added to a text widget with the \fIpathName
\fBwindow create\fR widget command, several configuration options may be

associated with it. These options may be modified later with the \fIpathName
\fBwindow configure\fR widget command. The following options are currently
supported:
.TP
\fB\-align \fIwhere\fR
.
If the window is not as tall as the line in which it is displayed, this option
determines where the window is displayed in the line. \fIWhere\fR must have
one of the values \fBtop\fR (align the top of the window with the top of the
line), \fBcenter\fR (center the window within the range of the line),

\fBbottom\fR (align the bottom of the window with the bottom of the line's
area), or \fBbaseline\fR (align the bottom of the window with the baseline of
the line).
.TP
\fB\-create \fIscript\fR
.
Specifies a Tcl script that may be evaluated to create the window for the

annotation. If no \fB\-window\fR option has been specified for the annotation
this script will be evaluated when the annotation is about to be displayed on

the screen. \fIScript\fR must create a window for the annotation and return
the name of that window as its result. Two substitutions will be performed in


\fIscript\fR before evaluation. \fI%W\fR will be substituted by the name of
the parent text widget, and \fI%%\fR will be substituted by a single \fI%\fR.

If the annotation's window should ever be deleted, \fIscript\fR will be
evaluated again the next time the annotation is displayed.
.TP
\fB\-padx \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on each side of the

embedded window. It may have any of the usual forms defined for a screen
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded window. It may have any of the usual forms defined
for a screen distance.
.TP
\fB\-stretch \fIboolean\fR
.
If the requested height of the embedded window is less than the height of the
line in which it is displayed, this option can be used to specify whether the
window should be stretched vertically to fill its line. If the \fB\-pady\fR

option has been specified as well, then the requested padding will be retained
even if the window is stretched.

.TP
\fB\-window \fIpathName\fR
.
Specifies the name of a window to display in the annotation. Note that if a

\fIpathName\fR has been set, then later configuring a window to the empty
string will not delete the widget corresponding to the old \fIpathName\fR.
Rather it will remove the association between the old \fIpathName\fR and the

text widget. If multiple peer widgets are in use, it is usually simpler to use
the \fB\-create\fR option if embedded windows are desired in each peer.

.SH "EMBEDDED IMAGES"
.PP
The final form of annotation in text widgets is an embedded image. Each
embedded image annotation causes an image to be displayed at a particular

point in the text. There may be any number of embedded images in a text
widget, and a particular image may be embedded in multiple places in the same
text widget.
.PP
The embedded image's position on the screen will be updated as the text is

modified or scrolled. Each embedded image occupies one unit's worth of index




space in the text widget, and it may be referred to either by its position in
the widget's index space, or the name it is assigned when the image is inserted
into the text widget with \fIpathName \fBimage create\fR. If the range of text
containing the embedded image is deleted then that copy of the image is removed
from the screen.
.PP

Eliding an embedded image immediately after scheduling it for creation via
\fIpathName \fBimage create \fIindex \fB-create\fR will prevent it from being

effectively created. Uneliding an elided embedded image scheduled for creation
via \fIpathName \fBimage create \fIindex \fB-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded

image, the latter won't get automatically recreated.

.PP
When an embedded image is added to a text widget with the \fIpathName \fBimage
create\fR widget command, a name unique to this instance of the image is
returned. This name may then be used to refer to this image instance. The name
is taken to be the value of the \fB\-name\fR option (described below). If the
\fB\-name\fR option is not provided, the \fB\-image\fR name is used instead.

If the \fIimageName\fR is already in use in the text widget, then \fB#\fInn\fR
is added to the end of the \fIimageName\fR, where \fInn\fR is an arbitrary
integer. This insures the \fIimageName\fR is unique. Once this name is
assigned to this instance of the image, it does not change, even though the
\fB\-image\fR or \fB\-name\fR values can be changed with \fIpathName \fBimage
configure\fR.
.PP
When an embedded image is added to a text widget with the \fIpathName \fBimage
create\fR widget command, several configuration options may be associated with

it. These options may be modified later with the \fIpathName \fBimage

configure\fR widget command. The following options are currently supported:
.TP
\fB\-align \fIwhere\fR
.
If the image is not as tall as the line in which it is displayed, this option
determines where the image is displayed in the line. \fIWhere\fR must have one
of the values \fBtop\fR (align the top of the image with the top of the line),

\fBcenter\fR (center the image within the range of the line), \fBbottom\fR
(align the bottom of the image with the bottom of the line's area), or
\fBbaseline\fR (align the bottom of the image with the baseline of the line).

.TP
\fB\-image \fIimage\fR
.
Specifies the name of the Tk image to display in the annotation. If
\fIimage\fR is not a valid Tk image, then an error is returned.
.TP
\fB\-name \fIImageName\fR
.
Specifies the name by which this image instance may be referenced in the text
widget. If \fIImageName\fR is not supplied, then the name of the Tk image is

used instead. If the \fIimageName\fR is already in use, \fI#nn\fR is appended
to the end of the name as described above.
.TP
\fB\-padx \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on each side of the

embedded image. It may have any of the usual forms defined for a screen
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded image. It may have any of the usual forms defined
for a screen distance.
.SH "THE SELECTION"
.PP
Selection support is implemented via tags. If the \fB\-exportselection\fR option

for the text widget is true then the \fBsel\fR tag will be associated with the
selection:
.IP [1]
Whenever characters are tagged with \fBsel\fR the text widget will claim
ownership of the selection.
.IP [2]
Attempts to retrieve the selection will be serviced by the text widget,

returning all the characters with the \fBsel\fR tag.
.IP [3]
If the selection is claimed away by another application or by another window
within this application, then the \fBsel\fR tag will be removed from all
characters in the text.
.IP [4]
Whenever the \fBsel\fR tag range changes a virtual event \fB<<Selection>>\fR
is generated.
.PP
The \fBsel\fR tag is automatically defined when a text widget is created, and
it may not be deleted with the
.QW "\fIpathName \fBtag delete\fR"
widget command. Furthermore, the \fB\-selectbackground\fR,
\fB\-selectborderwidth\fR, and \fB\-selectforeground\fR options for the text
widget are tied to the \fB\-background\fR, \fB\-borderwidth\fR, and
\fB\-foreground\fR options for the \fBsel\fR tag: changes in either will
automatically be reflected in the other. Also the



\fB\-inactiveselectbackground\fR option for the text widget is used instead of
\fB\-selectbackground\fR when the text widget does not have the focus. This
allows programmatic control over the visualization of the \fBsel\fR tag for
foreground and background windows, or to have \fBsel\fR not shown at all (when

\fB\-inactiveselectbackground\fR is empty) for background windows. Each peer
text widget has its own \fBsel\fR tag which can be separately configured and
set.
.SH "THE INSERTION CURSOR"
.PP
The mark named \fBinsert\fR has special significance in text widgets. It is
defined automatically when a text widget is created and it may not be unset
with the
.QW "\fIpathName \fBmark unset\fR"

widget command. The \fBinsert\fR mark represents the position of the insertion
cursor, and the insertion cursor will automatically be drawn at this point
whenever the text widget has the input focus.
.SH "THE MODIFIED FLAG"
.PP
The text widget can keep track of changes to the content of the widget by
means of the modified flag. Inserting or deleting text will set this flag. The
flag can be queried, set and cleared programmatically as well. Whenever the
flag changes state a \fB<<Modified>>\fR virtual event is generated. See the
\fIpathName \fBedit modified\fR widget command for more details.

.SH "THE UNDO MECHANISM"
.PP
The text widget has an unlimited undo and redo mechanism (when the
\fB\-undo\fR widget option is true) which records every insert and delete
action on a stack.
.PP
Boundaries (called
.QW separators )
are inserted between edit actions. The purpose of these separators is to group

inserts, deletes and replaces into one compound edit action. When undoing a
change everything between two separators will be undone. The undone changes
are then moved to the redo stack, so that an undone edit can be redone again.
The redo stack is cleared whenever new edit actions are recorded on the undo
stack. The undo and redo stacks can be cleared to keep their depth under
control.
.PP
Separators are inserted automatically when the \fB\-autoseparators\fR widget
option is true. You can insert separators programmatically as well. If a
separator is already present at the top of the undo stack no other will be
inserted. That means that two separators on the undo stack are always
separated by at least one insert or delete action.
.PP
The \fB<<UndoStack>>\fR virtual event is generated every time the undo stack
or the redo stack becomes empty or unempty.
.PP
The undo mechanism is also linked to the modified flag. This means that
undoing or redoing changes can take a modified text widget back to the
unmodified state or vice versa. The modified flag will be set automatically to

the appropriate state. This automatic coupling does not work when the modified
flag has been set by the user, until the flag has been reset again.
.PP
See below for the \fIpathName \fBedit\fR widget command that controls the undo
mechanism.
.SH "PEER WIDGETS"
.PP

The text widget has a separate store of all its data concerning each line's
textual contents, marks, tags, images and windows, and the undo stack.

.PP
While this data store cannot be accessed directly (i.e. without a text widget
as an intermediary), multiple text widgets can be created, each of which
present different views on the same underlying data. Such text widgets are
known as peer text widgets.
.PP
As text is added, deleted, edited and coloured in any one widget, and as
images, marks, tags are adjusted, all such changes will be reflected in all
peers.
.PP
All data and markup is shared, except for a few small details. First, the
\fBsel\fR tag may be set and configured (in its display style) differently for
each peer. Second, each peer has its own \fBinsert\fR and \fBcurrent\fR mark
positions (but all other marks are shared). Third, embedded windows, which are
arbitrary other widgets, cannot be shared between peers. This means the

\fB\-window\fR option of embedded windows is independently set for each peer
(it is advisable to use the \fB\-create\fR script capabilities to allow each
peer to create its own embedded windows as needed). Fourth, all of the
configuration options of each peer (e.g. \fB\-font\fR, etc) can be set
independently, with the exception of \fB\-undo\fR, \fB\-maxundo\fR,
\fB\-autoseparators\fR (i.e. all undo, redo and modified state issues are
shared).
.PP
Finally any single peer need not contain all lines from the underlying data
store. When creating a peer, a contiguous range of lines (e.g. only lines 52
through 125) may be specified. This allows a peer to contain just a small
portion of the overall text. The range of lines will expand and contract as

text is inserted or deleted. The peer will only ever display complete lines of
text (one cannot share just part of a line). If the peer's contents contracts
to nothing (i.e. all complete lines in the peer widget have been deleted from
another widget), then it is impossible for new lines to be inserted. The peer
will simply become an empty shell on which the background can be configured,
but which will never show any content (without manual reconfiguration of the
start and end lines). Note that a peer which does not contain all of the
underlying data store still has indices numbered from
.QW 1.0
to
.QW end .
It is simply that those indices reflect a subset of the total data, and data
outside the contained range is not accessible to the peer. This means that the
command \fIpeerName \fBindex end\fR may return quite different values in
different peers. Similarly, commands like \fIpeerName \fBtag ranges\fR will
not return index ranges outside that which is meaningful to the peer. The
configuration options \fB\-startline\fR and \fB\-endline\fR may be used to

control how much of the underlying data is contained in any given text widget.
.PP
Note that peers are really peers. Deleting the
.QW original
text widget will not cause any other peers to be deleted, or otherwise
affected.
.PP
See below for the \fIpathName \fBpeer\fR widget command that controls the
creation of peer widgets.
.SH "ASYNCHRONOUS UPDATE OF LINE HEIGHTS"
.PP
In order to maintain a responsive user-experience, the text widget calculates
lines metrics (line heights in pixels) asynchronously. Because of this, some
commands of the text widget may return wrong results if the asynchronous
calculations are not finished at the time of calling. This applies to
\fIpathName \fBcount -ypixels\fR and \fIpathName \fByview\fR.
.PP
Again for performance reasons, it would not be appropriate to let these
commands always wait for the end of the update calculation each time they are
called. In most use cases of these commands a more or less inaccurate result
does not really matter compared to execution speed.
.PP
In case accurate result is needed (and if the text widget is managed by a
geometry manager), one can resort to \fIpathName \fBsync\fR and \fIpathName
\fBpendingsync\fR to control the synchronization of the view of text widgets.
.PP
The \fB<<WidgetViewSync>>\fR virtual event fires when the line heights of the
text widget become obsolete (due to some editing command or configuration
change), and again when the internal data of the text widget are back in sync
with the widget view. The detail field (%d substitution) is either true (when
the widget is in sync) or false (when it is not).
.PP
\fIpathName \fBsync\fR, \fIpathName \fBpendingsync\fR and
\fB<<WidgetViewSync>>\fR apply to each text widget independently of its peers.
.PP
Examples of use:
.CS
## Example 1:
# immediately complete line metrics at any cost (GUI unresponsive)
$w sync
$w yview moveto $fraction

## Example 2:
# synchronously wait for up-to-date line metrics (GUI responsive)
# before executing the scheduled command, but don't block execution flow
$w sync -command [list $w yview moveto $fraction]

## Example 3:
# init
set yud($w) 0
proc updateaction w {
\&set ::yud($w) 1
\&# any other update action here...
}
# runtime, synchronously wait for up-to-date line metrics (GUI responsive)
$w sync -command [list updateaction $w]
vwait yud($w)
$w yview moveto $fraction

## Example 4:
# init
set todo($w) {}
proc updateaction w {
\&foreach cmd $::todo($w) {uplevel #0 $cmd}
\&set todo($w) {}
}
# runtime
lappend todo($w) [list $w yview moveto $fraction]
$w sync -command [list updateaction $w]

## Example 5:
# init
set todo($w) {}
bind $w <<WidgetViewSync>> {
\&if {%d} {
\&\&foreach cmd $todo(%W) {eval $cmd}
\&\&set todo(%W) {}
\&}
}
# runtime
if {![$w pendingsync]} {
\&$w yview moveto $fraction
} else {
\&lappend todo($w) [list $w yview moveto $fraction]
}
.CE
.SH "WIDGET COMMAND"
.PP
The \fBtext\fR command creates a new Tcl command whose name is the same as the

path name of the text's window. This command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as the text
widget's path name. \fIOption\fR and the \fIarg\fRs determine the exact

behavior of the command. The following commands are possible for text widgets:
.TP
\fIpathName \fBbbox \fIindex\fR
.
Returns a list of four elements describing the screen area of the character

given by \fIindex\fR. The first two elements of the list give the x and y
coordinates of the upper-left corner of the area occupied by the character,
and the last two elements give the width and height of the area. If the

character is only partially visible on the screen, then the return value

reflects just the visible part. If the character is not visible on the screen
then the return value is an empty list.
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given by \fIoption\fR.

\fIOption\fR may have any of the values accepted by the \fBtext\fR command.

.TP
\fIpathName \fBcompare\fR \fIindex1 op index2\fR
.
Compares the indices given by \fIindex1\fR and \fIindex2\fR according to the
relational operator given by \fIop\fR, and returns 1 if the relationship is

satisfied and 0 if it is not. \fIOp\fR must be one of the operators <, <=, ==,
>=, >, or !=. If \fIop\fR is == then 1 is returned if the two indices refer to
the same character, if \fIop\fR is < then 1 is returned if \fIindex1\fR refers
to an earlier character in the text than \fIindex2\fR, and so on.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget. If no \fIoption\fR is
specified, returns a list describing all of the available options for
\fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of

this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command
returns a list describing the one named option (this list will be identical to
the corresponding sublist of the value returned if no \fIoption\fR is
specified). If one or more \fIoption\-value\fR pairs are specified, then the
command modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string. \fIOption\fR may have any of
the values accepted by the \fBtext\fR command.


.TP
\fIpathName \fBcount\fR ?\fIoptions\fR? \fIindex1 index2\fR
.
Counts the number of relevant things between the two indices. If \fIindex1\fR
is after \fIindex2\fR, the result will be a negative number (and this holds

for each of the possible options). The actual items which are counted depend
on the options given. The result is a list of integers, one for the result of
each counting option given. Valid counting options are \fB\-chars\fR,
\fB\-displaychars\fR, \fB\-displayindices\fR, \fB\-displaylines\fR,
\fB\-indices\fR, \fB\-lines\fR, \fB\-xpixels\fR and \fB\-ypixels\fR. The
default value, if no option is specified, is \fB\-indices\fR. There is an
additional possible option \fB\-update\fR which is a modifier. If given (and
if the text widget is managed by a geometry manager), then all subsequent
options ensure that any possible out of date information is recalculated.
This currently only has any effect for the \fB\-ypixels\fR count (which, if
\fB\-update\fR is not given, will use the text widget's current cached value
for each line). This \fB\-update\fR option is obsoleted by \fIpathName
\fBsync\fR, \fIpathName \fBpendingsync\fR and \fB<<WidgetViewSync>>\fR.  The
count options are interpreted as follows:
.RS
.IP \fB\-chars\fR
count all characters, whether elided or not. Do not count embedded windows or
images.
.IP \fB\-displaychars\fR
count all non-elided characters.
.IP \fB\-displayindices\fR
count all non-elided characters, windows and images.
.IP \fB\-displaylines\fR
count all display lines (i.e. counting one for each time a line wraps) from
the line of the first index up to, but not including the display line of the

second index. Therefore if they are both on the same display line, zero will
be returned. By definition displaylines are visible and therefore this only
counts portions of actual visible lines.
.IP \fB\-indices\fR
count all characters and embedded windows or images (i.e. everything which
counts in text-widget index space), whether they are elided or not.

.IP \fB\-lines\fR
count all logical lines (irrespective of wrapping) from the line of the first
index up to, but not including the line of the second index. Therefore if they
are both on the same line, zero will be returned. Logical lines are counted
whether they are currently visible (non-elided) or not.

.IP \fB\-xpixels\fR
count the number of horizontal pixels from the first pixel of the first index
to (but not including) the first pixel of the second index. To count the total
desired width of the text widget (assuming wrapping is not enabled), first
find the longest line and then use

.QW ".text count \-xpixels \N'34'${line}.0\N'34' \N'34'${line}.0 lineend\N'34'" .
.IP \fB\-ypixels\fR
count the number of vertical pixels from the first pixel of the first index to
(but not including) the first pixel of the second index. If both indices are
on the same display line, zero will be returned. To count the total number of
vertical pixels in the text widget, use

.QW ".text count \-ypixels 1.0 end" ,
and to ensure this is up to date, use
.QW ".text count \-update \-ypixels 1.0 end" .
.PP
The command returns a positive or negative integer corresponding to the number
of items counted between the two indices. One such integer is returned for
each counting option given, so a list is returned if more than one option was
supplied. For example
.QW ".text count \-xpixels \-ypixels 1.3 4.5"
is perfectly valid and will return a list of two elements.
.RE

.TP
\fIpathName \fBdebug \fR?\fIboolean\fR?
.
If \fIboolean\fR is specified, then it must have one of the true or false
values accepted by Tcl_GetBoolean. If the value is a true one then internal

consistency checks will be turned on in the B-tree code associated with text
widgets. If \fIboolean\fR has a false value then the debugging checks will be

turned off. In either case the command returns an empty string. If
\fIboolean\fR is not specified then the command returns \fBon\fR or \fBoff\fR
to indicate whether or not debugging is turned on. There is a single debugging
switch shared by all text widgets: turning debugging on or off in any widget

turns it on or off for all widgets. For widgets with large amounts of text,
the consistency checks may cause a noticeable slow-down.
.RS
.PP
When debugging is turned on, the drawing routines of the text widget set the
global variables \fBtk_textRedraw\fR and \fBtk_textRelayout\fR to the lists of
indices that are redrawn. The values of these variables are tested by Tk's
test suite.
.RE
.TP
\fIpathName \fBdelete \fIindex1 \fR?\fIindex2 ...\fR?
.
Delete a range of characters from the text.
If both \fIindex1\fR and \fIindex2\fR are specified, then delete
all the characters starting with the one given by \fIindex1\fR
and stopping just before \fIindex2\fR (i.e. the character at
\fIindex2\fR is not deleted).
If \fIindex2\fR does not specify a position later in the text
than \fIindex1\fR then no characters are deleted.






|



|

|


















|
|
>

>
|
|
|
>

>


>
|
|
|
|
>

|
|
>

>
|
|
|
<
<
<
<
<
<
<
|

|
|

|
>
|
|
|
>

|
|
|
|
|
>

|
>
|
|
|
>

>
|
|
|
|
>
|
|

|
|
|
>

|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
|
>
|

|



|
|
|
|
>
|
|

|
|
|
|



|
|
|
|
|
>
|
|
|
|
|
>
|

|
>

|
|
|



|
>
|
|
|
>
|
|
|
|

>


|
|
>
|
>
|
>
|

|
>
|
|
>
|
|
|
>
|

|
>

|
>
|

|
>
|


>
|

|
|

>
|
|
|
>


|
>
|
|
>
|



|
|
>
|
>
|
>
|
|
|
|
|
|
|
<



>




<
|
|
>
|
|
>


<
|
|


<
|
>


<



<
|
>
|
|


<
|
>
|
|


<
|
>
|
>


<
|
>
|
>

|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
>
>


<
|
|
|
>
|
|
>
|
|
|
|
|
>


|
|
|
|
|
|
>
|
|
|
|


|
|
|
|
|
>
|
|
|
>


|
|
|
|
|
|
>
|
|
|
|
|
|
|


|
|
|
|
|
|
|
>
|
|
|
|
|
<
>


|
|
|
|
>


|
|
|
|
>


|
|
|
|
|
|
>
>


|
|
|
|
|
|

|
|



|
>
|
|
|




|
|
>


>


|
|
>
|
|

|
>
|
|
>
|
>
|

|
|
|
>
|
|





|
|
>
|
>
|
|

>
|
|
|


<
|
>
|


<
|
>
|
|
|
>


<
|
>
|
|
>
>
>


<
|
|
|
>


<
|
|
>
|
>
|
<


<
|
|


<
|
|
|


<

|
>
|
|
|


<

|
|
>
|
>
|
>
|


<

|
|
>
|
|
>
|
|

<
<
<
<
<
<
<
<
<
<

<
|
|
>
|
>
|



<
|
|
<
<
<
<
<
|
<
<


<
|
|
|
|
>
>


<

|
|
>
|
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<


<
|
|
>
|
>


<
|
|
|
>


<
|
|
>
|
>


<
|
|
>
|
|
|
>
|
|
|


<
|
>
|
|
|
|


<

|
<
<
<
<
|
<
<


<
|
|
|
|
|
|

|
|
>
|
|
>
|
|
>

|
>
|
|
|
>
|
>
|

>
>
|

>

|
>
>
|
|
>
|
|
>


|
|
>
|
>
|
|
>
|
|
|
>
>
|

>
|




|
>
|
|
|
>
|
|
|

|
|
>

|
|
|
|
|
|
|
>
|
|
>
>
|
|
>


|
|
>
|
|
|
|
>

|
|
|
>
>
>
>
>
|
|
>
|
<
|
>
>
>
>

>
|
|
>
|
|
|
>
|
>

|
|
>
|
|
|


<
|
|
|
|
>
|
|
|


<
|
>
|
|
>
|
|
>
>
|
|
>
|
|


<
|
>
|
<


<
|
|
|


<
|
|
|
>
|
|
>


<
|
>
|
|
|
>
|
|
>


|
|
>
|
|


|
>
|
>
>
>
>
|
|
|
|
|

>
|
|
>
|
|
|
>
|
>


|
|
|
|
>
|
|
|
|
|
|

|
|
>
|
>
|


<
|
|
|
>
|
|
|
>


<
|
|


<
|
|
>
|
|


<
|
>
|
<


<
|
|
|


|
>
|
<

|
|

|
>
|

|
|
|

|
|

|
|

|
|
|
|
|
>
>
>
|
|
|
|
>
|
|
|


|
|
|

>
|
|
|

<
|
|
|
|
|
>



|
|



|
>
|
|
|
|
|
<

|
|
|
|
|

<
<
<
|
|
|
>
|
|





>
|
|
>

|
|
|
|


|
|

|
|
|
|
|
>
|
|
|
|
|
|
<

|
|
|
|
>
|
|
|
|
|
|
|




|
|
|
|
|
|
>
|

|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
>
|
|

|

|
|
>
|


<
|
>
|
|
|
>
|
>
|
|


<
|
>
|
>


<
|
|
>
|
|
|
|
>

|
<
|
|
|
>
|
|
|
|
|
|
|
>
>

|
<
|
|
>
|
|
|





|
|

<
<
|


|
|





|
|
>
|
|
|

|
|
>

|
|
|
|
>

|
|
|
|
>


|
|
|
|
>




|
|
|
|



>


<
|
|
>
|
|
>
|
|
|
|
>
|
|


|
|
|
|



<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258

259
260
261
262

263
264
265
266

267
268
269

270
271
272
273
274
275

276
277
278
279
280
281

282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480

481
482
483
484
485

486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501
502

503
504
505
506
507
508

509
510
511
512
513
514

515
516

517
518
519
520

521
522
523
524
525

526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554










555

556
557
558
559
560
561
562
563
564

565
566





567


568
569

570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
586















587







588
589

590
591
592
593
594
595
596

597
598
599
600
601
602

603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629

630
631




632


633
634

635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802

803
804
805

806
807

808
809
810
811
812

813
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892
893
894

895
896
897
898

899
900
901
902
903
904
905

906
907
908

909
910

911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991



992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
































1062












































1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134


1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187

1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213
1214
1215
1216
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH text n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
text, tk_textCopy, tk_textCut, tk_textPaste \- Create and manipulate text widgets
.SH SYNOPSIS
.nf
\fBtext\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_textCopy\fR \fIpathName\fR
\fBtk_textCut\fR \fIpathName\fR
\fBtk_textPaste\fR \fIpathName\fR
.SO
\-background	\-highlightthickness	\-relief
\-borderwidth	\-insertbackground	\-selectbackground
\-cursor	\-insertborderwidth	\-selectborderwidth
\-exportselection	\-insertofftime	\-selectforeground
\-font	\-insertontime	\-setgrid
\-foreground	\-insertwidth	\-takefocus
\-highlightbackground	\-padx	\-xscrollcommand
\-highlightcolor	\-pady	\-yscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-autoseparators autoSeparators AutoSeparators
Specifies a boolean that says whether separators are automatically
inserted in the undo stack. Only meaningful when the \fB\-undo\fR
option is true.
.OP \-blockcursor blockCursor BlockCursor
.VS 8.5
Specifies a boolean that says whether the blinking insertion cursor
should be drawn as a character-sized rectangular block.  If false
(the default) a thin vertical line is used for the insertion cursor.
.VE 8.5
.OP \-endline endLine EndLine
.VS 8.5
Specifies an integer line index representing the line of the underlying
textual data store that should be just after the last line contained in
the widget.
This allows a text widget to reflect only a portion of a larger piece
of text.   Instead of an integer, the empty string can be provided to
this configuration option, which will configure the widget to end
at the very last line in the textual data store.
.VE 8.5
.OP \-height height Height
Specifies the desired height for the window, in units of characters
in the font given by the \fB\-font\fR option.
Must be at least one.
.OP \-inactiveselectbackground inactiveSelectBackground Foreground
.VS 8.5
Specifies the colour to use for the selection (the \fBsel\fR tag) when
the window does not have the input focus.  If empty, \fB{}\fR, then no
selection is shown when the window does not have the focus.







.VE 8.5
.OP \-maxundo maxUndo MaxUndo
Specifies the maximum number of compound undo actions on the undo
stack. A zero or a negative value imply an unlimited undo stack.
.OP \-spacing1 spacing1 Spacing1
Requests additional space above each text line in the widget,
using any of the standard forms for screen distances.
If a line wraps, this option only applies to the first line
on the display.
This option may be overridden with \fB\-spacing1\fR options in
tags.
.OP \-spacing2 spacing2 Spacing2
For lines that wrap (so that they cover more than one line on the
display) this option specifies additional space to provide between
the display lines that represent a single line of text.
The value may have any of the standard forms for screen distances.
This option may be overridden with \fB\-spacing2\fR options in
tags.
.OP \-spacing3 spacing3 Spacing3
Requests additional space below each text line in the widget,
using any of the standard forms for screen distances.
If a line wraps, this option only applies to the last line
on the display.
This option may be overridden with \fB\-spacing3\fR options in
tags.
.OP \-startline startLine StartLine
.VS 8.5
Specifies an integer line index representing the first line of the
underlying textual data store that should be contained in the widget.
This allows a text widget to reflect only a portion of a larger piece
of text.  Instead of an integer, the empty string can be provided to
this configuration option, which will configure the widget to start
at the very first line in the textual data store.
.VE 8.5
.OP \-state state State
Specifies one of two states for the text:  \fBnormal\fR or \fBdisabled\fR.
If the text is disabled then characters may not be inserted or deleted
and no insertion cursor will be displayed, even if the input focus is
in the widget.
.OP \-tabs tabs Tabs
Specifies a set of tab stops for the window.  The option's value consists
of a list of screen distances giving the positions of the tab stops,
each of which is a distance relative to the left edge of the widget
(excluding borders, padding, etc).  Each
position may optionally be followed in the next list element
by one of the keywords \fBleft\fR, \fBright\fR, \fBcenter\fR,
or \fBnumeric\fR, which specifies how to justify
text relative to the tab stop.  \fBLeft\fR is the default; it causes
the text following the tab character to be positioned with its left edge
at the tab position.  \fBRight\fR means that the right edge of the text
following the tab character is positioned at the tab position, and
\fBcenter\fR means that the text is centered at the tab position.
\fBNumeric\fR means that the decimal point in the text is positioned
at the tab position;  if there is no decimal point then the least
significant digit of the number is positioned just to the left of the
tab position;  if there is no number in the text then the text is
right-justified at the tab position.
For example,
.QW "\fB\-tabs {2c left 4c 6c center}\fR"
creates three tab stops at two-centimeter intervals;  the first two use left
justification and the third uses center justification.
.RS
.PP
If the list of tab stops does not have enough elements to cover all
of the tabs in a text line, then Tk extrapolates new tab stops using
the spacing and alignment from the last tab stop in the list.  Tab
distances must be strictly positive, and must always increase from one
tab stop to the next (if not, an error is thrown).
The value of the \fBtabs\fR option may be overridden by \fB\-tabs\fR
options in tags.
.PP
If no \fB\-tabs\fR option is specified, or if it is specified as
an empty list, then Tk uses default tabs spaced every eight
(average size) characters.  To achieve a different standard spacing,
for example every 4 characters, simply configure the widget with
.QW "\fB\-tabs \N'34'[expr {4 * [font measure $font 0]}] left\N'34' \-tabstyle wordprocessor\fR" .
.RE
.OP \-tabstyle tabStyle TabStyle
Specifies how to interpret the relationship between tab stops on a line
and tabs in the text of that line.  The value must be \fBtabular\fR (the
default) or \fBwordprocessor\fR. Note that tabs are interpreted as they
are encountered in the text.  If the tab style is \fBtabular\fR then the
\fIn\fR'th tab character in the line's text will be associated with
the \fIn\fR'th
tab stop defined for that line.  If the tab character's x coordinate
falls to the right of the \fIn\fR'th tab stop, then a gap of a single space
will be inserted as a fallback.  If the tab style is \fBwordprocessor\fR
then any tab character being laid out will use (and be defined by) the
first tab stop to the right of the preceding characters already laid out
on that line.  The value of the \fBtabstyle\fR option may be overridden
by \fB\-tabstyle\fR options in tags.
.OP \-undo undo Undo
Specifies a boolean that says whether the undo mechanism is active or
not.
.OP \-width width Width
Specifies the desired width for the window in units of characters
in the font given by the \fB\-font\fR option.
If the font does not have a uniform width then the width of the character
.QW 0
is used in translating from character units to screen units.
.OP \-wrap wrap Wrap
Specifies how to handle lines in the text that are too long to be
displayed in a single line of the text's window.
The value must be \fBnone\fR or \fBchar\fR or \fBword\fR.
A wrap mode of \fBnone\fR means that each line of text appears as
exactly one line on the screen;  extra characters that do not fit
on the screen are not displayed.
In the other modes each line of text will be broken up into several
screen lines if necessary to keep all the characters visible.
In \fBchar\fR mode a screen line break may occur after any character;
in \fBword\fR mode a line break will only be made at word boundaries.
.BE

.SH DESCRIPTION
.PP
The \fBtext\fR command creates a new window (given by the
\fIpathName\fR argument) and makes it into a text widget.
Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the text such as its default background color
and relief.  The \fBtext\fR command returns the
path name of the new window.
.PP
A text widget displays one or more lines of text and allows that
text to be edited.
Text widgets support four different kinds of annotations on the
text, called tags, marks, embedded windows or embedded images.
Tags allow different portions of the text
to be displayed with different fonts and colors.
In addition, Tcl commands can be associated with tags so
that scripts are invoked when particular actions such as keystrokes
and mouse button presses occur in particular ranges of the text.
See \fBTAGS\fR below for more details.
.PP
The second form of annotation consists of floating markers in the text
called
.QW marks .
Marks are used to keep track of various interesting positions in the
text as it is edited.
See \fBMARKS\fR below for more details.
.PP
The third form of annotation allows arbitrary windows to be
embedded in a text widget.
See \fBEMBEDDED WINDOWS\fR below for more details.
.PP
The fourth form of annotation allows Tk images to be embedded in a text
widget.
See \fBEMBEDDED IMAGES\fR below for more details.
.PP
The text widget also has a built-in undo/redo mechanism.
See \fBTHE UNDO MECHANISM\fR below for more details.
.PP
.VS 8.5
The text widget allows for the creation of peer widgets.  These are
other text widgets which share the same underlying data (text, marks,
tags, images, etc).  See \fBPEER WIDGETS\fR below for more details.
.VE 8.5
.SH INDICES
.PP
Many of the widget commands for texts take one or more indices
as arguments.
An index is a string used to indicate a particular place within
a text, such as a place to insert characters or one endpoint of a
range of characters to delete.
Indices have the syntax
.CS
\fIbase modifier modifier modifier ...\fR
.CE
Where \fIbase\fR gives a starting point and the \fImodifier\fRs
adjust the index from the starting point (e.g. move forward or
backward one character).  Every index must contain a \fIbase\fR,
but the \fImodifier\fRs are optional.
.VS 8.5
Most modifiers (as documented below) allow
an optional submodifier.  Valid submodifiers are \fBany\fR
and \fBdisplay\fR. If the submodifier is abbreviated, then it must be
followed by whitespace, but otherwise there need be no space between the
submodifier and the following \fImodifier\fR.  Typically the \fBdisplay\fR
submodifier adjusts the meaning of the following \fImodifier\fR to make
it refer to visual or non-elided units rather than logical units, but
this is explained for each relevant case below.  Lastly, where \fIcount\fR
is used as part of a modifier, it can be positive or negative, so

.QW "\fIbase\fR \- \-3 lines"
is perfectly valid (and equivalent to
.QW "\fIbase\fR +3lines" ).
.VE 8.5
.PP
The \fIbase\fR for an index must have one of the following forms:
.TP 12
\fIline\fB.\fIchar\fR

Indicates \fIchar\fR'th character on line \fIline\fR.
Lines are numbered from 1 for consistency with other UNIX programs
that use this numbering scheme.
Within a line, characters are numbered from 0.
If \fIchar\fR is \fBend\fR then it refers to the newline character
that ends the line.
.TP 12
\fB@\fIx\fB,\fIy\fR

Indicates the character that covers the pixel whose x and y coordinates
within the text's window are \fIx\fR and \fIy\fR.
.TP 12
\fBend\fR

Indicates the end of the text (the character just after the last
newline).
.TP 12
\fImark\fR

Indicates the character just after the mark whose name is \fImark\fR.
.TP 12
\fItag\fB.first\fR

Indicates the first character in the text that has been tagged with
\fItag\fR.
This form generates an error if no characters are currently tagged
with \fItag\fR.
.TP 12
\fItag\fB.last\fR

Indicates the character just after the last one in the text that has
been tagged with \fItag\fR.
This form generates an error if no characters are currently tagged
with \fItag\fR.
.TP 12
\fIpathName\fR

Indicates the position of the embedded window whose name is
\fIpathName\fR.
This form generates an error if there is no embedded window
by the given name.
.TP 12
\fIimageName\fR

Indicates the position of the embedded image whose name is
\fIimageName\fR.
This form generates an error if there is no embedded image
by the given name.
.PP
If the \fIbase\fR could match more than one of the above forms, such
as a \fImark\fR and \fIimageName\fR both having the same value, then
the form earlier in the above list takes precedence.
If modifiers follow the base index, each one of them must have one
of the forms listed below.  Keywords such as \fBchars\fR and \fBwordend\fR
may be abbreviated as long as the abbreviation is unambiguous.
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.VS 8.5
Adjust the index forward by \fIcount\fR characters, moving to later lines
in the text if necessary.  If there are fewer than \fIcount\fR characters
in the text after the current index, then set the index to the last index
in the text.  Spaces on either side of \fIcount\fR are optional.  If the
\fBdisplay\fR submodifier is given, elided characters are skipped over
without being counted.  If \fBany\fR is given, then all characters are
counted.  For historical reasons, if neither modifier is given then the
count actually takes place in units of index positions (see \fBindices\fR
for details).  This behaviour may be changed in a future major release,
so if you need an index count, you are encouraged to use \fBindices\fR
instead wherever possible.
.VE 8.5
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR

Adjust the index backward by \fIcount\fR characters, moving to earlier
lines in the text if necessary.  If there are fewer than \fIcount\fR
characters in the text before the current index, then set the index to
.VS 8.5
the first index in the text (1.0).  Spaces on either side of \fIcount\fR
are optional.  If the \fBdisplay\fR submodifier is given, elided
characters are skipped over without being counted.  If \fBany\fR is
given, then all characters are counted.  For historical reasons, if
neither modifier is given then the count actually takes place in units of
index positions (see \fBindices\fR for details).  This behaviour may be
changed in a future major release, so if you need an index count, you are
encouraged to use \fBindices\fR instead wherever possible.
.VE 8.5
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.VS 8.5
Adjust the index forward by \fIcount\fR index positions, moving to later
lines in the text if necessary.  If there are fewer than \fIcount\fR
index positions in the text after the current index, then set the index
to the last index position in the text.  Spaces on either side of
\fIcount\fR are optional.  Note that an index position is either a single
character or a single embedded image or embedded window.  If the
\fBdisplay\fR submodifier is given, elided indices are skipped over
without being counted.  If \fBany\fR is given, then all indices are
counted; this is also the default behaviour if no modifier is given.
.VE 8.5
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.VS 8.5
Adjust the index backward by \fIcount\fR index positions, moving to
earlier lines in the text if necessary.  If there are fewer than
\fIcount\fR index positions in the text before the current index, then
set the index to the first index position (1.0) in the text.  Spaces on
either side of \fIcount\fR are optional.  If the \fBdisplay\fR
submodifier is given, elided indices are skipped over without being
counted.  If \fBany\fR is given, then all indices are counted; this is
also the default behaviour if no modifier is given.
.VE 8.5
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.VS 8.5
Adjust the index forward by \fIcount\fR lines, retaining the same
character position within the line.  If there are fewer than \fIcount\fR
lines after the line containing the current index, then set the index to
refer to the same character position on the last line of the text.  Then,
if the line is not long enough to contain a character at the indicated
character position, adjust the character position to refer to the last
character of the line (the newline).  Spaces on either side of
\fIcount\fR are optional.  If the \fBdisplay\fR submodifier is given,
then each visual display line is counted separately.  Otherwise, if
\fBany\fR (or no modifier) is given, then each logical line (no matter
how many times it is visually wrapped) counts just once.  If the relevant
lines are not wrapped, then these two methods of counting are equivalent.
.VE 8.5
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.VS 8.5
Adjust the index backward by \fIcount\fR logical lines, retaining the
same character position within the line.  If there are fewer than
\fIcount\fR lines before the line containing the current index, then set
the index to refer to the same character position on the first line of
the text.  Then, if the line is not long enough to contain a character at
the indicated character position, adjust the character position to refer
to the last character of the line (the newline).  Spaces on either side
of \fIcount\fR are optional.  If the \fBdisplay\fR submodifier is given,
then each visual display line is counted separately.  Otherwise, if
\fBany\fR (or no modifier) is given, then each logical line (no matter
how many times it is visually wrapped) counts just once.  If the relevant
lines are not wrapped, then these two methods of counting are equivalent.

.VE 8.5
.TP
?\fIsubmodifier\fR? \fBlinestart\fR
.VS 8.5
Adjust the index to refer to the first index on the line.  If the
\fBdisplay\fR submodifier is given, this is the first index on the
display line, otherwise on the logical line.
.VE 8.5
.TP
?\fIsubmodifier\fR? \fBlineend\fR
.VS 8.5
Adjust the index to refer to the last index on the line (the
newline).  If the \fBdisplay\fR submodifier is given, this is the last
index on the display line, otherwise on the logical line.
.VE 8.5
.TP
?\fIsubmodifier\fR? \fBwordstart\fR
.VS 8.5
Adjust the index to refer to the first character of the word containing
the current index.  A word consists of any number of adjacent characters
that are letters, digits, or underscores, or a single character that is
not one of these.  If the \fBdisplay\fR submodifier is given, this only
examines non-elided characters, otherwise all characters (elided or not)
are examined.
.VE 8.5
.TP
?\fIsubmodifier\fR? \fBwordend\fR
.VS 8.5
Adjust the index to refer to the character just after the last one of the
word containing the current index.  If the current index refers to the
last character of the text then it is not modified.  If the \fBdisplay\fR
submodifier is given, this only examines non-elided characters, otherwise
all characters (elided or not) are examined.
.PP
If more than one modifier is present then they are applied in
left-to-right order.  For example, the index
.QW "\fBend \- 1 chars\fR"
refers to the next-to-last character in the text and
.QW "\fBinsert wordstart \- 1 c\fR"
refers to the character just before
the first one in the word containing the insertion cursor.  Modifiers
are applied one by one in this left to right order, and after each step
the resulting index is constrained to be a valid index in the text
widget.  So, for example, the index
.QW "\fB1.0 \-1c +1c\fR"
refers to the index
.QW \fB2.0\fR .
.PP
Where modifiers result in index changes by display lines, display chars
or display indices, and the \fIbase\fR refers to an index inside an
elided tag,
that base index is considered to be equivalent to the first following
non-elided index.
.VE 8.5
.SH TAGS
.PP
The first form of annotation in text widgets is a tag.
A tag is a textual string that is associated with some of the characters
in a text.
Tags may contain arbitrary characters, but it is probably best to
avoid using the characters
.QW " "
(space), \fB+\fR, or \fB\-\fR:
these characters have special meaning in indices, so tags containing
them cannot be used as indices.
There may be any number of tags associated with characters in a
text.
Each tag may refer to a single character, a range of characters, or
several ranges of characters.
An individual character may have any number of tags associated with it.
.PP
A priority order is defined among tags, and this order is used in
implementing some of the tag-related functions described below.
When a tag is defined (by associating it with characters or setting
its display options or binding commands to it), it is given
a priority higher than any existing tag.
The priority order of tags may be redefined using the
.QW "\fIpathName \fBtag raise\fR"
and
.QW "\fIpathName \fBtag lower\fR"
widget commands.
.PP
Tags serve three purposes in text widgets.
First, they control the way information is displayed on the screen.
By default, characters are displayed as determined by the
\fB\-background\fR, \fB\-font\fR, and \fB\-foreground\fR options for the
text widget.
However, display options may be associated with individual tags
using the
.QW "\fIpathName \fBtag configure\fR"
widget command.
If a character has been tagged, then the display options associated
with the tag override the default display style.
The following options are currently supported for tags:
.TP
\fB\-background \fIcolor\fR

\fIColor\fR specifies the background color to use for characters
associated with the tag.
It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-bgstipple \fIbitmap\fR

\fIBitmap\fR specifies a bitmap that is used as a stipple pattern
for the background.
It may have any of the forms accepted by \fBTk_GetBitmap\fR.
If \fIbitmap\fR has not been specified, or if it is specified
as an empty string, then a solid fill will be used for the
background.
.TP
\fB\-borderwidth \fIpixels\fR

\fIPixels\fR specifies the width of a 3-D border to draw around
the background.
It may have any of the forms accepted by \fBTk_GetPixels\fR.
This option is used in conjunction with the \fB\-relief\fR
option to give a 3-D appearance to the background for characters;
it is ignored unless the \fB\-background\fR option
has been set for the tag.
.TP
\fB\-elide \fIboolean\fR

\fIElide\fR specifies whether the data should
be elided.  Elided data (characters, images, embedded windows, etc) is
not displayed and takes no space on screen, but further on behaves just
as normal data.
.TP
\fB\-fgstipple \fIbitmap\fR

\fIBitmap\fR specifies a bitmap that is used as a stipple pattern
when drawing text and other foreground information such as
underlines.
It may have any of the forms accepted by \fBTk_GetBitmap\fR.
If \fIbitmap\fR has not been specified, or if it is specified
as an empty string, then a solid fill will be used.

.TP
\fB\-font \fIfontName\fR

\fIFontName\fR is the name of a font to use for drawing characters.
It may have any of the forms accepted by \fBTk_GetFont\fR.
.TP
\fB\-foreground \fIcolor\fR

\fIColor\fR specifies the color to use when drawing text and other
foreground information such as underlines.
It may have any of the forms accepted by \fBTk_GetColor\fR.
.TP
\fB\-justify \fIjustify\fR

If the first non-elided character of a display line has a tag for which this
option has been specified, then \fIjustify\fR determines how to
justify the line.
It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR.
If a line wraps, then the justification for each line on the
display is determined by the first non-elided character of that display line.
.TP
\fB\-lmargin1 \fIpixels\fR

If the first non-elided character of a text line has a tag for which this
option has been specified, then \fIpixels\fR specifies how
much the line should be indented from the left edge of the
window.
\fIPixels\fR may have any of the standard forms for screen
distances.
If a line of text wraps, this option only applies to the
first line on the display;  the \fB\-lmargin2\fR option controls
the indentation for subsequent lines.
.TP
\fB\-lmargin2 \fIpixels\fR

If the first non-elided character of a display line has a tag for which this
option has been specified, and if the display line is not the
first for its text line (i.e., the text line has wrapped), then
\fIpixels\fR specifies how much the line should be indented from
the left edge of the window.
\fIPixels\fR may have any of the standard forms for screen
distances.
This option is only used when wrapping is enabled, and it only
applies to the second and later display lines for a text line.
.TP










\fB\-offset \fIpixels\fR

\fIPixels\fR specifies an amount by which the text's baseline
should be offset vertically from the baseline of the overall
line, in pixels.
For example, a positive offset can be used for superscripts
and a negative offset can be used for subscripts.
\fIPixels\fR may have any of the standard forms for screen
distances.
.TP
\fB\-overstrike \fIboolean\fR

Specifies whether or not to draw a horizontal rule through
the middle of characters.





\fIBoolean\fR may have any of the forms accepted by \fBTcl_GetBoolean\fR.


.TP
\fB\-relief \fIrelief\fR

\fIRelief\fR specifies the 3-D relief to use for drawing backgrounds,
in any of the forms accepted by \fBTk_GetRelief\fR.
This option is used in conjunction with the \fB\-borderwidth\fR
option to give a 3-D appearance to the background for characters;
it is ignored unless the \fB\-background\fR option
has been set for the tag.
.TP
\fB\-rmargin \fIpixels\fR

If the first non-elided character of a display line has a tag for which this
option has been specified, then \fIpixels\fR specifies how wide
a margin to leave between the end of the line and the right
edge of the window.
\fIPixels\fR may have any of the standard forms for screen
distances.
This option is only used when wrapping is enabled.
If a text line wraps, the right margin for each line on the
display is determined by the first non-elided character of that display















line.







.TP
\fB\-spacing1 \fIpixels\fR

\fIPixels\fR specifies how much additional space should be
left above each text line, using any of the standard forms for
screen distances.
If a line wraps, this option only applies to the first
line on the display.
.TP
\fB\-spacing2 \fIpixels\fR

For lines that wrap, this option specifies how much additional
space to leave between the display lines for a single text line.
\fIPixels\fR may have any of the standard forms for screen
distances.
.TP
\fB\-spacing3 \fIpixels\fR

\fIPixels\fR specifies how much additional space should be
left below each text line, using any of the standard forms for
screen distances.
If a line wraps, this option only applies to the last
line on the display.
.TP
\fB\-tabs \fItabList\fR

\fITabList\fR specifies a set of tab stops in the same form
as for the \fB\-tabs\fR option for the text widget.  This
option only applies to a display line if it applies to the
first non-elided character on that display line.
If this option is specified as an empty string, it cancels
the option, leaving it unspecified for the tag (the default).
If the option is specified as a non-empty string that is
an empty list, such as \fB\-tags\0{\0}\fR, then it requests
default 8-character tabs as described for the \fB\-tags\fR
widget option.
.TP
\fB\-tabstyle \fIstyle\fR

\fIStyle\fR specifies either the \fItabular\fR or
\fIwordprocessor\fR style of tabbing to use for the text widget.
This option only applies to a display line if it applies to the
first non-elided character on that display line.
If this option is specified as an empty string, it cancels
the option, leaving it unspecified for the tag (the default).
.TP
\fB\-underline \fIboolean\fR

\fIBoolean\fR specifies whether or not to draw an underline underneath
characters.




It may have any of the forms accepted by \fBTcl_GetBoolean\fR.


.TP
\fB\-wrap \fImode\fR

\fIMode\fR specifies how to handle lines that are wider than the
text's window.
It has the same legal values as the \fB\-wrap\fR option
for the text widget:  \fBnone\fR, \fBchar\fR, or \fBword\fR.
If this tag option is specified, it overrides the \fB\-wrap\fR option
for the text widget.
.PP
If a character has several tags associated with it, and if their
display options conflict, then the options of the highest priority
tag are used.
If a particular display option has not been specified for a
particular tag, or if it is specified as an empty string, then
that option will never be used;  the next-highest-priority
tag's option will used instead.
If no tag specifies a particular display option, then the default
style for the widget will be used.
.PP
The second purpose for tags is event bindings.
You can associate bindings with a tag in much the same way you can
associate bindings with a widget class:  whenever particular X
events occur on characters with the given tag, a given
Tcl command will be executed.
Tag bindings can be used to give behaviors to ranges of characters;
among other things, this allows hypertext-like
features to be implemented.
For details, see the description of the
.QW "\fIpathName \fBtag bind\fR"
widget command below.
.VS 8.5
Tag bindings are shared between all peer widgets
(including any bindings for the special \fBsel\fR tag).
.VE 8.5
.PP
The third use for tags is in managing the selection.
See \fBTHE SELECTION\fR below.
.VS 8.5
With the exception of the special \fBsel\fR
tag, all tags are shared between peer text widgets, and may be
manipulated on an equal basis from any such widget.  The \fBsel\fR
tag exists separately and independently in each peer text widget (but
any tag bindings to \fBsel\fR are shared).
.VE 8.5
.SH MARKS
.PP
The second form of annotation in text widgets is a mark.
Marks are used for remembering particular places in a text.
They are something like tags, in that they have names and
they refer to places in the file, but a mark is not associated
with particular characters.
Instead, a mark is associated with the gap between two characters.
Only a single position may be associated with a mark at any given
time.
If the characters around a mark are deleted the mark will still
remain;  it will just have new neighbor characters.
In contrast, if the characters containing a tag are deleted then
the tag will no longer have an association with characters in
the file.
Marks may be manipulated with the
.QW "\fIpathName \fBmark\fR"
widget
command, and their current locations may be determined by using the
mark name as an index in widget commands.
.PP
Each mark also has a
.QW gravity ,
which is either \fBleft\fR or \fBright\fR.
The gravity for a mark specifies what happens to the mark when
text is inserted at the point of the mark.
If a mark has left gravity, then the mark is treated as if it
were attached to the character on its left, so the mark will
remain to the left of any text inserted at the mark position.
If the mark has right gravity, new text inserted at the mark
position will appear to the left of the mark (so that the mark
remains rightmost).  The gravity for a mark defaults to \fBright\fR.
.PP
The name space for marks is different from that for tags:  the
same name may be used for both a mark and a tag, but they will refer
to different things.
.PP
Two marks have special significance.
First, the mark \fBinsert\fR is associated with the insertion cursor,
as described under \fBTHE INSERTION CURSOR\fR below.
Second, the mark \fBcurrent\fR is associated with the character
closest to the mouse and is adjusted automatically to track the
mouse position and any changes to the text in the widget (one
exception:  \fBcurrent\fR is not updated in response to mouse
motions if a mouse button is down;  the update will be deferred
until all mouse buttons have been released).
Neither of these special marks may be deleted.
.VS 8.5
With the exception of
these two special marks, all marks are shared between peer text
widgets, and may be manipulated on an equal basis from any peer.
.VE 8.5
.SH "EMBEDDED WINDOWS"
.PP
The third form of annotation in text widgets is an embedded window.
Each embedded window annotation causes a window to be displayed
at a particular point in  the text.
There may be any number of embedded windows in a text widget,
and any widget may be used as an embedded window (subject to the
usual rules for geometry management, which require the text window
to be the parent of the embedded window or a descendant of its
parent).
.PP
The embedded window's position on the screen will be updated as the
text is modified or scrolled, and it will be mapped and unmapped as
it moves into and out of the visible area of the text widget.
Each embedded window occupies one
.VS 8.5
unit's
.VE 8.5
worth of index space
in the text widget, and it may be referred to either by the name
of its embedded window or by its position in the widget's
index space.
If the range of text containing the embedded window is deleted then

the window is destroyed.
.VS 8.5
Similarly if the text widget as a whole is deleted, then the window is
destroyed.
.VE 8.5
.PP
.VS 8.5
Eliding an embedded window immediately after scheduling it for creation
via \fIpathName \fBwindow create \fIindex \fB-create\fR will prevent it
from being effectively created.
Uneliding an elided embedded window scheduled for creation via
\fIpathName \fBwindow create \fIindex \fB-create\fR will automatically
trigger the associated creation script.
After destroying an elided embedded window, the latter won't get
automatically recreated.
.VE 8.5
.PP
When an embedded window is added to a text widget with the
\fIpathName \fBwindow create\fR widget command, several configuration
options may be associated with it.
These options may be  modified later with the \fIpathName \fBwindow configure\fR
widget command.
The following options are currently supported:
.TP
\fB\-align \fIwhere\fR

If the window is not as tall as the line in which it is displayed,
this option determines where the window is displayed in the line.
\fIWhere\fR must have one of the values \fBtop\fR (align the top of the window
with the top of the line), \fBcenter\fR (center the window
within the range of the line), \fBbottom\fR (align the bottom of the
window with the bottom of the line's area),
or \fBbaseline\fR (align the bottom of the window with the baseline
of the line).
.TP
\fB\-create \fIscript\fR

Specifies a Tcl script that may be evaluated to create the window
for the annotation.
If no \fB\-window\fR option has been specified for the annotation
this script will be evaluated when the annotation is about to
be displayed on the screen.
\fIScript\fR must create a window for the annotation and return
the name of that window as its result.
.VS 8.5
Two substitutions will be performed in \fIscript\fR before evaluation.
\fI%W\fR will be substituted by the name of the parent text widget,
and \fI%%\fR will be substituted by a single \fI%\fR.
.VE 8.5
If the annotation's window should ever be deleted, \fIscript\fR
will be evaluated again the next time the annotation is displayed.
.TP
\fB\-padx \fIpixels\fR

\fIPixels\fR specifies the amount of extra space to leave on
each side of the embedded window.
It may have any of the usual forms defined for a screen distance.

.TP
\fB\-pady \fIpixels\fR

\fIPixels\fR specifies the amount of extra space to leave on
the top and on the bottom of the embedded window.
It may have any of the usual forms defined for a screen distance.
.TP
\fB\-stretch \fIboolean\fR

If the requested height of the embedded window is less than the
height of the line in which it is displayed, this option can be
used to specify whether the window should be stretched vertically
to fill its line.
If the \fB\-pady\fR option has been specified as well, then the
requested padding will be retained even if the window is
stretched.
.TP
\fB\-window \fIpathName\fR

Specifies the name of a window to display in the annotation.
.VS 8.5
Note that if a \fIpathName\fR has been set, then later configuring a
window to the empty string will not delete the widget corresponding to
the old \fIpathName\fR. Rather it will remove the association between
the old \fIpathName\fR and the text widget.  If multiple peer widgets
are in use, it is usually simpler to use the \fB\-create\fR option if
embedded windows are desired in each peer.
.VE 8.5
.SH "EMBEDDED IMAGES"
.PP
The final form of annotation in text widgets is an embedded image.
Each embedded image annotation causes an image to be displayed
at a particular point in  the text.
There may be any number of embedded images in a text widget,
and a particular image may be embedded in multiple places in the same
text widget.
.PP
The embedded image's position on the screen will be updated as the
text is modified or scrolled.
Each embedded image occupies one
.VS 8.5
unit's
.VE 8.5
worth of index space
in the text widget, and it may be referred to either by
its position in the widget's index space, or the name it is assigned
when the image is inserted into the text widget with \fIpathName \fBimage create\fR.
If the range of text containing the embedded image is deleted then
that copy of the image is removed from the screen.
.PP
.VS 8.5
Eliding an embedded image immediately after scheduling it for creation
via \fIpathName \fBimage create \fIindex \fB-create\fR will prevent it
from being effectively created.
Uneliding an elided embedded image scheduled for creation via
\fIpathName \fBimage create \fIindex \fB-create\fR will automatically
trigger the associated creation script.
After destroying an elided embedded image, the latter won't get
automatically recreated.
.VE 8.5
.PP
When an embedded image is added to a text widget with the \fIpathName \fBimage
create\fR widget command, a name unique to this instance of the image
is returned.  This name may then be used to refer to this image
instance.  The name is taken to be the value of the \fB\-name\fR option
(described below).  If the \fB\-name\fR option is not provided, the
\fB\-image\fR name is used instead.  If the \fIimageName\fR is already
in use in the text widget, then \fB#\fInn\fR is added to the end of the
\fIimageName\fR, where \fInn\fR is an arbitrary integer.  This insures
the \fIimageName\fR is unique.
Once this name is assigned to this instance of the image, it does not
change, even though the \fB\-image\fR or \fB\-name\fR values can be changed
with \fIpathName \fBimage configure\fR.
.PP
When an embedded image is added to a text widget with the
\fIpathName \fBimage create\fR widget command, several configuration
options may be associated with it.
These options may be modified later with the \fIpathName \fBimage configure\fR
widget command.
The following options are currently supported:
.TP
\fB\-align \fIwhere\fR

If the image is not as tall as the line in which it is displayed,
this option determines where the image is displayed in the line.
\fIWhere\fR must have one of the values \fBtop\fR (align the top of the image
with the top of the line), \fBcenter\fR (center the image
within the range of the line), \fBbottom\fR (align the bottom of the
image with the bottom of the line's area),
or \fBbaseline\fR (align the bottom of the image with the baseline
of the line).
.TP
\fB\-image \fIimage\fR

Specifies the name of the Tk image to display in the annotation.
If \fIimage\fR is not a valid Tk image, then an error is returned.
.TP
\fB\-name \fIImageName\fR

Specifies the name by which this image instance may be referenced in
the text widget. If \fIImageName\fR is not supplied, then the
name of the Tk image is used instead.
If the \fIimageName\fR is already in use, \fI#nn\fR is appended to
the end of the name as described above.
.TP
\fB\-padx \fIpixels\fR

\fIPixels\fR specifies the amount of extra space to leave on
each side of the embedded image.
It may have any of the usual forms defined for a screen distance.

.TP
\fB\-pady \fIpixels\fR

\fIPixels\fR specifies the amount of extra space to leave on
the top and on the bottom of the embedded image.
It may have any of the usual forms defined for a screen distance.
.SH "THE SELECTION"
.PP
Selection support is implemented via tags.
If the \fBexportSelection\fR option for the text widget is true
then the \fBsel\fR tag will be associated with the selection:

.IP [1]
Whenever characters are tagged with \fBsel\fR the text widget
will claim ownership of the selection.
.IP [2]
Attempts to retrieve the
selection will be serviced by the text widget, returning all the
characters with the \fBsel\fR tag.
.IP [3]
If the selection is claimed away by another application or by another
window within this application, then the \fBsel\fR tag will be removed
from all characters in the text.
.IP [4]
Whenever the \fBsel\fR tag range changes a virtual event
\fB<<Selection>>\fR is generated.
.PP
The \fBsel\fR tag is automatically defined when a text widget is
created, and it may not be deleted with the
.QW "\fIpathName \fBtag delete\fR"
widget command.  Furthermore, the \fBselectBackground\fR,
\fBselectBorderWidth\fR, and \fBselectForeground\fR options for
the text widget are tied to the \fB\-background\fR,
\fB\-borderwidth\fR, and \fB\-foreground\fR options for the \fBsel\fR
tag:  changes in either will automatically be reflected in the
other.
.VS 8.5
Also the
\fB\-inactiveselectbackground\fR option for the text widget is used
instead of \fB\-selectbackground\fR when the text widget does not have
the focus.  This allows programmatic control over the visualization of
the \fBsel\fR tag for foreground and background windows, or to have
\fBsel\fR not shown at all (when \fB\-inactiveselectbackground\fR is
empty) for background windows.  Each peer text widget has its own
\fBsel\fR tag which can be separately configured and set.
.VE 8.5
.SH "THE INSERTION CURSOR"
.PP
The mark named \fBinsert\fR has special significance in text widgets.
It is defined automatically when a text widget is created and it
may not be unset with the
.QW "\fIpathName \fBmark unset\fR"
widget command.
The \fBinsert\fR mark represents the position of the insertion
cursor, and the insertion cursor will automatically be drawn at
this point whenever the text widget has the input focus.
.SH "THE MODIFIED FLAG"

The text widget can keep track of changes to the content of the widget
by means of the modified flag. Inserting or deleting text will set
this flag. The flag can be queried, set and cleared programmatically
as well. Whenever the flag changes state a \fB<<Modified>>\fR virtual
event is generated. See the \fIpathName \fBedit modified\fR widget command for
more details.
.SH "THE UNDO MECHANISM"
.PP
The text widget has an unlimited undo and redo mechanism (when the
\fB\-undo\fR widget option is true) which records every insert and
delete action on a stack.
.PP
Boundaries (called
.QW separators )
are inserted between edit actions.  The
purpose of these separators is to group inserts, deletes and replaces
into one compound edit action.  When undoing a change everything between
two separators will be undone.  The undone changes are then moved to the
redo stack, so that an undone edit can be redone again.  The redo stack
is cleared whenever new edit actions are recorded on the undo stack.  The
undo and redo stacks can be cleared to keep their depth under control.

.PP
Separators are inserted automatically when the \fB\-autoseparators\fR
widget option is true.  You can insert separators programmatically as
well.  If a separator is already present at the top of the undo stack
no other will be inserted.  That means that two separators on the undo
stack are always separated by at least one insert or delete action.
.PP



The undo mechanism is also linked to the modified flag.  This means
that undoing or redoing changes can take a modified text widget back
to the unmodified state or vice versa.  The modified flag will be set
automatically to the appropriate state.  This automatic coupling
does not work when the modified flag has been set by the user, until
the flag has been reset again.
.PP
See below for the \fIpathName \fBedit\fR widget command that controls the undo
mechanism.
.SH "PEER WIDGETS"
.PP
.VS 8.5
The text widget has a separate store of all its data concerning each
line's textual contents, marks, tags, images and windows, and the undo
stack.
.PP
While this data store cannot be accessed directly (i.e. without a text
widget as an intermediary), multiple text widgets can be created, each
of which present different views on the same underlying data.  Such
text widgets are known as peer text widgets.
.PP
As text is added, deleted, edited and coloured in any one widget, and as
images, marks, tags are adjusted, all such changes will be reflected in
all peers.
.PP
All data and markup is shared, except for a few small details.  First,
the \fBsel\fR tag may be set and configured (in its display style)
differently for each peer.  Second, each peer has its own \fBinsert\fR
and \fBcurrent\fR mark positions (but all other marks are shared).
Third, embedded windows, which are arbitrary other widgets, cannot be
shared between peers.  This means the \fB\-window\fR option of embedded
windows is independently set for each peer (it is advisable to use
the \fB\-create\fR script capabilities to allow each peer to create its
own embedded windows as needed).  Fourth, all of the configuration
options of each peer (e.g. \fB\-font\fR, etc) can be set independently,
with the exception of \fB\-undo\fR, \fB\-maxUndo\fR, \fB\-autoSeparators\fR
(i.e. all undo, redo and modified state issues are shared).

.PP
Finally any single peer need not contain all lines from the underlying
data store.  When creating a peer, a contiguous range of lines (e.g.
only lines 52 through 125) may be specified.  This allows a peer to
contain just a small portion of the overall text.  The range of lines
will expand and contract as text is inserted or deleted.  The peer will
only ever display complete lines of text (one cannot share just part of
a line).  If the peer's contents contracts to nothing (i.e. all complete
lines in the peer widget have been deleted from another widget), then it
is impossible for new lines to be inserted.  The peer will simply become
an empty shell on which the background can be configured, but which will
never show any content (without manual reconfiguration of the start and
end lines).  Note that a peer which does not contain all of the
underlying data store still has indices numbered from
.QW 1.0
to
.QW end .
It is simply that those indices reflect a subset of the total data, and
data outside the contained range is not accessible to the peer.  This
means that the command \fIpeerName \fBindex end\fR may return quite different
values in different peers.  Similarly, commands like \fIpeerName \fBtag
ranges\fR will not return index ranges outside that which is meaningful
to the peer.  The configuration options \fB\-startline\fR and
\fB\-endline\fR may be used to control how much of the underlying data is
contained in any given text widget.
.PP
Note that peers are really peers.  Deleting the
.QW original
text widget will not cause any other peers to be deleted, or otherwise
affected.
.PP
See below for the \fIpathName \fBpeer\fR widget command that controls the
creation of peer widgets.
































.VE 8.5












































.SH "WIDGET COMMAND"
.PP
The \fBtext\fR command creates a new Tcl command whose
name is the same as the path name of the text's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the text widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for text widgets:
.TP
\fIpathName \fBbbox \fIindex\fR

Returns a list of four elements describing the screen area
of the character given by \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the area occupied by the
character, and the last two elements give the width and height
of the area.
If the character is only partially visible on the screen, then
the return value reflects just the visible part.
If the character is not visible on the screen then the return
value is an empty list.
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtext\fR
command.
.TP
\fIpathName \fBcompare\fR \fIindex1 op index2\fR

Compares the indices given by \fIindex1\fR and \fIindex2\fR according
to the relational operator given by \fIop\fR, and returns 1 if
the relationship is satisfied and 0 if it is not.
\fIOp\fR must be one of the operators <, <=, ==, >=, >, or !=.
If \fIop\fR is == then 1 is returned if the two indices refer to
the same character, if \fIop\fR is < then 1 is returned if \fIindex1\fR
refers to an earlier character in the text than \fIindex2\fR, and
so on.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBtext\fR
command.
.VS 8.5
.TP
\fIpathName \fBcount\fR \fI?options\fR? \fIindex1 index2\fR

Counts the number of relevant things between the two indices.
If \fIindex1\fR is after \fIindex2\fR, the result will be a negative number
(and this holds for each of the possible options).
The actual items which are counted depend on the
options given.  The result is a list of integers, one for the result of
each counting option given.  Valid counting options are \fB\-chars\fR,
\fB\-displaychars\fR, \fB\-displayindices\fR, \fB\-displaylines\fR,
\fB\-indices\fR, \fB\-lines\fR, \fB\-xpixels\fR and \fB\-ypixels\fR. The
default value, if no option is specified, is \fB\-indices\fR. There is an
additional possible option \fB\-update\fR which is a modifier. If given (and
if the text widget is managed by a geometry manager), then all subsequent
options ensure that any possible out of date information is recalculated. 
This currently only has any effect for the \fI\-ypixels\fR count (which, if
\fB\-update\fR is not given, will use the text widget's current cached value


for each line).  The count options are interpreted as follows:
.RS
.IP \fB\-chars\fR
count all characters, whether elided or not.  Do not count
embedded windows or images.
.IP \fB\-displaychars\fR
count all non-elided characters.
.IP \fB\-displayindices\fR
count all non-elided characters, windows and images.
.IP \fB\-displaylines\fR
count all display lines (i.e. counting one for each
time a line wraps) from the line of the first index up to, but not
including the display line of the second index.  Therefore if they are
both on the same display line, zero will be returned.  By definition
displaylines are visible and therefore this only counts portions of
actual visible lines.
.IP \fB\-indices\fR
count all characters and embedded windows or images (i.e.
everything which counts in text-widget index space), whether they are
elided or not.
.IP \fB\-lines\fR
count all logical lines (irrespective of wrapping) from
the line of the first index up to, but not including the line of the
second index.  Therefore if they are both on the same line, zero will be
returned.  Logical lines are counted whether they are currently visible
(non-elided) or not.
.IP \fB\-xpixels\fR
count the number of horizontal pixels from the first
pixel of the first index to (but not including) the first pixel of the
second index.  To count the total desired width of the text widget
(assuming wrapping is not enabled), first find the longest line and then
use
.QW ".text count \-xpixels \N'34'${line}.0\N'34' \N'34'${line}.0 lineend\N'34'" .
.IP \fB\-ypixels\fR
count the number of vertical pixels from the first pixel
of the first index to (but not including) the first pixel of the second
index.  If both indices are on the same display line, zero will be
returned.  To count the total number of vertical pixels in the text
widget, use
.QW ".text count \-ypixels 1.0 end" ,
and to ensure this is up to date, use
.QW ".text count \-update \-ypixels 1.0 end" .
.PP
The command returns a positive or negative integer corresponding to the
number of items counted between the two indices.  One such integer is
returned for each counting option given, so a list is returned if more
than one option was supplied.  For example
.QW ".text count \-xpixels \-ypixels 1.3 4.5"
is perfectly valid and will return a list of two elements.
.RE
.VE 8.5
.TP
\fIpathName \fBdebug \fR?\fIboolean\fR?

If \fIboolean\fR is specified, then it must have one of the true or
false values accepted by Tcl_GetBoolean.
If the value is a true one then internal consistency checks will be
turned on in the B-tree code associated with text widgets.
If \fIboolean\fR has a false value then the debugging checks will
be turned off.
In either case the command returns an empty string.
If \fIboolean\fR is not specified then the command returns \fBon\fR
or \fBoff\fR to indicate whether or not debugging is turned on.
There is a single debugging switch shared by all text widgets:  turning
debugging on or off in any widget turns it on or off for all widgets.
For widgets with large amounts of text, the consistency checks may
cause a noticeable slow-down.
.RS
.PP
When debugging is turned on, the drawing routines of the text widget
set the global variables \fBtk_textRedraw\fR and \fBtk_textRelayout\fR
to the lists of indices that are redrawn.  The values of these variables
are tested by Tk's test suite.
.RE
.TP
\fIpathName \fBdelete \fIindex1 \fR?\fIindex2 ...\fR?

Delete a range of characters from the text.
If both \fIindex1\fR and \fIindex2\fR are specified, then delete
all the characters starting with the one given by \fIindex1\fR
and stopping just before \fIindex2\fR (i.e. the character at
\fIindex2\fR is not deleted).
If \fIindex2\fR does not specify a position later in the text
than \fIindex1\fR then no characters are deleted.
1202
1203
1204
1205
1206
1207
1208
1209
1210

1211
1212
1213
1214

1215
1216

1217
1218

1219
1220
1221
1222
1223
1224
1225
1226


1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237

1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278
1279

1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336

1337
1338

1339

1340
1341
1342
1343
1344
1345
1346


1347
1348
1349
1350

1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371

1372
1373
1374

1375
1376
1377

1378
1379
1380
1381

1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402

1403
1404

1405
1406
1407
1408

1409
1410

1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427

1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439

1440

1441
1442
1443

1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456

1457
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533

1534
1535

1536
1537
1538
1539
1540
1541
1542
1543
1544

1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558


1559
1560
1561
1562

1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573

1574
1575

1576
1577
1578
1579
1580
1581
1582
1583
1584

1585
1586

1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631

1632
1633
1634
1635
1636

1637
1638
1639
1640
1641

1642
1643

1644
1645
1646
1647

1648
1649
1650
1651
1652

1653

1654
1655
1656
1657

1658

1659

1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676

1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701

1702
1703
1704
1705
1706
1707

1708

1709
1710

1711
1712
1713
1714
1715
1716

1717
1718

1719
1720

1721
1722
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751

1752
1753

1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767
1768

1769
1770
1771
1772
1773
1774
1775
1776

1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1787

1788
1789

1790
1791
1792
1793
1794
1795

1796
1797
1798
1799
1800
1801
1802

1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815

1816
1817

1818
1819

1820

1821
1822
1823
1824
1825
1826

1827
1828
1829

1830
1831

1832

1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844

1845
1846

1847
1848
1849


1850
1851
1852
1853
1854
1855

1856

1857
1858
1859
1860

1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883

1884
1885
1886

1887
1888
1889

1890
1891
1892
1893

1894
1895


1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907

1908
1909
1910
1911
1912
1913
1914

1915

1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933


1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944



1945
1946

1947
1948
1949
1950
1951

1952
1953
1954
1955
1956
1957

1958
1959
1960

1961
1962

1963
1964
1965
1966
1967
1968
1969

1970
1971


1972
1973
1974
1975
1976

1977
1978
1979
1980
1981


1982
1983
1984
1985
1986
1987
1988

1989
1990
1991
1992


1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024

2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038

2039
2040
2041
2042
2043
2044

2045
2046
2047
2048

2049
2050
2051
2052

2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065

2066
2067
2068
2069

2070
2071
2072
2073
2074
2075

2076
2077
2078
2079
2080

2081
2082

2083
2084
2085
2086
2087

2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132

2133
2134
2135
2136
2137

2138
2139
2140
2141
2142
2143
2144

2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161



2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176

2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195

2196
2197
2198
2199
2200
2201
2202
2203

2204
2205
2206

2207
2208
2209
2210
2211

2212
2213

2214
2215
2216
2217
2218
2219

2220
2221

2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232

2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254

2255
2256
2257
2258
2259
2260
2261
2262

2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282

2283
2284
2285
2286
2287
2288
2289
first range so deleted text does not cause an undesired index shifting
side-effects.  If multiple ranges with the same start index are given,
then the longest range is used.  If overlapping ranges are given, then
they will be merged into spans that do not cause deletion of text
outside the given ranges due to text shifted during deletion.
.TP
\fIpathName \fBdlineinfo \fIindex\fR
.
Returns a list with five elements describing the area occupied by the display

line containing \fIindex\fR. The first two elements of the list give the x and
y coordinates of the upper-left corner of the area occupied by the line, the
third and fourth elements give the width and height of the area, and the fifth
element gives the position of the baseline for the line, measured down from

the top of the area. All of this information is measured in pixels. If the
current wrap mode is \fBnone\fR and the line extends beyond the boundaries of

the window, the area returned reflects the entire area of the line, including
the portions that are out of the window. If the line is shorter than the full

width of the window then the area returned reflects just the portion of the
line that is occupied by characters and embedded windows. If the display line
containing \fIindex\fR is not visible on the screen then the return value is
an empty list.
.TP
\fIpathName \fBdump \fR?\fIswitches\fR? \fIindex1 \fR?\fIindex2\fR?
.
Return the contents of the text widget from \fIindex1\fR up to, but not


including \fIindex2\fR, including the text and information about marks, tags,
and embedded windows. If \fIindex2\fR is not specified, then it defaults to
one character past \fIindex1\fR. The information is returned in the following
format:
.RS
.LP
\fIkey1 value1 index1 key2 value2 index2\fR ...
.LP
The possible \fIkey\fR values are \fBtext\fR, \fBmark\fR, \fBtagon\fR,
\fBtagoff\fR, \fBimage\fR, and \fBwindow\fR. The corresponding \fIvalue\fR is
the text, mark name, tag name, image name, or window name. The \fIindex\fR

information is the index of the start of the text, mark, tag transition, image
or window. One or more of the following switches (or abbreviations thereof)
may be specified to control the dump:
.TP
\fB\-all\fR
.
Return information about all elements: text, marks, tags, images and windows.
This is the default.
.TP
\fB\-command \fIcommand\fR
.
Instead of returning the information as the result of the dump operation,
invoke the \fIcommand\fR on each element of the text widget within the range.
The command has three arguments appended to it before it is evaluated: the
\fIkey\fR, \fIvalue\fR, and \fIindex\fR.
.TP
\fB\-image\fR
.
Include information about images in the dump results.
.TP
\fB\-mark\fR
.
Include information about marks in the dump results.
.TP
\fB\-tag\fR
.
Include information about tag transitions in the dump results. Tag information
is returned as \fBtagon\fR and \fBtagoff\fR elements that indicate the begin
and end of each range of each tag, respectively.
.TP
\fB\-text\fR
.
Include information about text in the dump results. The value is the text up
to the next element or the end of range indicated by \fIindex2\fR. A text
element does not span newlines. A multi-line block of text that contains no
marks or tag transitions will still be dumped as a set of text segments that
each end with a newline. The newline is part of the value.

.TP
\fB\-window\fR
.
Include information about embedded windows in the dump results. The value of a
window is its Tk pathname, unless the window has not been created yet. (It

must have a create script.) In this case an empty string is returned, and you
must query the window by its index position to get more information.
.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg ...\fR?
.
This command controls the undo mechanism and the modified flag. The exact
behavior of the command depends on the \fIoption\fR argument that follows the
\fBedit\fR argument. The following forms of the command are currently
supported:
.RS
.TP
\fIpathName \fBedit canredo\fR
.
Returns a boolean true if redo is possible, i.e. when the redo stack is not
empty. Otherwise returns false.
.TP
\fIpathName \fBedit canundo\fR
.
Returns a boolean true if undo is possible, i.e. when the undo stack is not
empty. Otherwise returns false.
.TP
\fIpathName \fBedit modified \fR?\fIboolean\fR?
.
If \fIboolean\fR is not specified, returns the modified flag of the widget.
The insert, delete, edit undo and edit redo commands or the user can set or
clear the modified flag. If \fIboolean\fR is specified, sets the modified flag
of the widget to \fIboolean\fR.
.TP
\fIpathName \fBedit redo\fR
.
When the \fB\-undo\fR option is true, reapplies the last undone edits provided
no other edits were done since then, and returns a list of indices indicating
what ranges were changed by the redo operation. Generates an error when the
redo stack is empty. Does nothing when the \fB\-undo\fR option is false.

.TP
\fIpathName \fBedit reset\fR
.
Clears the undo and redo stacks.
.TP
\fIpathName \fBedit separator\fR
.
Inserts a separator (boundary) on the undo stack. Does nothing when the
\fB\-undo\fR option is false.
.TP
\fIpathName \fBedit undo\fR
.
Undoes the last edit action when the \fB\-undo\fR option is true, and returns a
list of indices indicating what ranges were changed by the undo operation. An
edit action is defined as all the insert and delete commands that are recorded
on the undo stack in between two separators. Generates an error when the undo
stack is empty. Does nothing when the \fB\-undo\fR option is false.

.RE
.TP
\fIpathName \fBget\fR ?\fB\-displaychars\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR?
.
Return a range of characters from the text. The return value will be all the

characters in the text starting with the one whose index is \fIindex1\fR and
ending just before the one whose index is \fIindex2\fR (the character at

\fIindex2\fR will not be returned). If \fIindex2\fR is omitted then the single

character at \fIindex1\fR is returned. If there are no characters in the
specified range (e.g. \fIindex1\fR is past the end of the file or \fIindex2\fR
is less than or equal to \fIindex1\fR) then an empty string is returned. If
the specified range contains embedded windows, no information about them is
included in the returned string. If multiple index pairs are given, multiple
ranges of text will be returned in a list. Invalid ranges will not be
represented with empty strings in the list. The ranges are returned in the


order passed to \fIpathName \fBget\fR. If the \fB\-displaychars\fR option is
given, then, within each range, only those characters which are not elided
will be returned. This may have the effect that some of the returned ranges
are empty strings.

.TP
\fIpathName \fBimage \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded images. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBtag\fR

argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBimage cget \fIindex option\fR
.
Returns the value of a configuration option for an embedded image. \fIIndex\fR
identifies the embedded image, and \fIoption\fR specifies a particular
configuration option, which must be one of the ones listed in the section
\fBEMBEDDED IMAGES\fR.
.TP
\fIpathName \fBimage configure \fIindex\fR ?\fIoption value ...\fR?
.
Query or modify the configuration options for an embedded image. If no
\fIoption\fR is specified, returns a list describing all of the available
options for the embedded image at \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified with no

\fIvalue\fR, then the command returns a list describing the one named option
(this list will be identical to the corresponding sublist of the value
returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR

pairs are specified, then the command modifies the given option(s) to have the
given value(s); in this case the command returns an empty string. See
\fBEMBEDDED IMAGES\fR for information on the options that are supported.

.TP
\fIpathName \fBimage create \fIindex\fR ?\fIoption value ...\fR?
.
This command creates a new image annotation, which will appear in the text at

the position given by \fIindex\fR. Any number of \fIoption\-value\fR pairs may
be specified to configure the annotation. Returns a unique identifier that may
be used as an index to refer to this image. See \fBEMBEDDED IMAGES\fR for

information on the options that are supported, and a description of the
identifier returned.
.TP
\fIpathName \fBimage names\fR
.
Returns a list whose elements are the names of all image instances currently
embedded in \fIwindow\fR.
.RE
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the position corresponding to \fIindex\fR in the form \fIline.char\fR
where \fIline\fR is the line number and \fIchar\fR is the character number.

\fIIndex\fR may have any of the forms described under \fBINDICES\fR above.
.TP
\fIpathName \fBinsert \fIindex chars \fR?\fItagList chars tagList ...\fR?
.
Inserts all of the \fIchars\fR arguments just before the character at

\fIindex\fR. If \fIindex\fR refers to the end of the text (the character after
the last newline) then the new text is inserted just before the last newline

instead. If there is a single \fIchars\fR argument and no \fItagList\fR, then
the new text will receive any tags that are present on both the character
before and the character after the insertion point; if a tag is present on
only one of these characters then it will not be applied to the new text. If

\fItagList\fR is specified then it consists of a list of tag names; the new
characters will receive all of the tags in this list and no others, regardless

of the tags present around the insertion point. If multiple
\fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same
effect as if a separate \fIpathName \fBinsert\fR widget command had been
issued for each pair, in order. The last \fItagList\fR argument may be
omitted.
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate marks. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBmark\fR argument. The

following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?
.
If \fIdirection\fR is not specified, returns \fBleft\fR or \fBright\fR to
indicate which of its adjacent characters \fImarkName\fR is attached to. If

\fIdirection\fR is specified, it must be \fBleft\fR or \fBright\fR; the
gravity of \fImarkName\fR is set to the given value.
.TP
\fIpathName \fBmark names\fR
.
Returns a list whose elements are the names of all the marks that are
currently set.
.TP
\fIpathName \fBmark next \fIindex\fR
.
Returns the name of the next mark at or after \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the next mark begins at that

index. If \fIindex\fR is the name of a mark, then the search for the next mark

begins immediately after that mark. This can still return a mark at the same
position if there are multiple marks at the same index. These semantics mean
that the \fBmark next\fR operation can be used to step through all the marks

in a text widget in the same order as the mark information returned by the
\fIpathName \fBdump\fR operation. If a mark has been set to the special
\fBend\fR index, then it appears to be \fIafter\fR \fBend\fR with respect to
the \fIpathName \fBmark next\fR operation. An empty string is returned if
there are no marks after \fIindex\fR.
.TP
\fIpathName \fBmark previous \fIindex\fR
.
Returns the name of the mark at or before \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the previous mark begins with

the character just before that index. If \fIindex\fR is the name of a mark,
then the search for the next mark begins immediately before that mark. This
can still return a mark at the same position if there are multiple marks at

the same index. These semantics mean that the \fIpathName \fBmark previous\fR
operation can be used to step through all the marks in a text widget in the
reverse order as the mark information returned by the \fIpathName \fBdump\fR
operation. An empty string is returned if there are no marks before
\fIindex\fR.
.TP
\fIpathName \fBmark set \fImarkName index\fR
.
Sets the mark named \fImarkName\fR to a position just before the character at

\fIindex\fR. If \fImarkName\fR already exists, it is moved from its old
position; if it does not exist, a new mark is created. This command returns an
empty string.
.TP
\fIpathName \fBmark unset \fImarkName \fR?\fImarkName markName ...\fR?
.
Remove the mark corresponding to each of the \fImarkName\fR arguments. The
removed marks will not be usable in indices and will not be returned by future
calls to
.QW "\fIpathName \fBmark names\fR" .
This command returns an empty string.
.RE
.TP
\fIpathName \fBpeer \fIoption args\fR
.
This command is used to create and query widget peers. It has two forms,
depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBpeer create \fInewPathName\fR ?\fIoptions\fR?
.
Creates a peer text widget with the given \fInewPathName\fR, and any optional
standard configuration options (as for the \fItext\fR command). By default the
peer will have the same start and end line as the parent widget, but these can

be overridden with the standard configuration options.
.TP
\fIpathName \fBpeer names\fR
.
Returns a list of peers of this widget (this does not include the widget
itself). The order within this list is undefined.
.RE
.TP
\fIpathName \fBpendingsync\fR
Returns 1 if the line heights calculations are not up-to-date, 0 otherwise.
.TP
\fIpathName \fBreplace\fR \fIindex1 index2 chars\fR ?\fItagList chars tagList ...\fR?
Replaces the range of characters between \fIindex1\fR and \fIindex2\fR
with the given characters and tags.  See the section on \fIpathName
\fBinsert\fR for an explanation of the handling of the \fItagList...\fR
arguments, and the section on \fIpathName
\fBdelete\fR for an explanation of the handling of the indices.  If
\fIindex2\fR corresponds to an index earlier in the text than
\fIindex1\fR, an error will be generated.
.RS
.PP
The deletion and insertion are arranged so that no unnecessary scrolling of
the window or movement of insertion cursor occurs. In addition the undo/redo
stack are correctly modified, if undo operations are active in the text
widget. The command returns an empty string.
.RE

.TP
\fIpathName \fBscan \fIoption args\fR
.
This command is used to implement scanning on texts. It has two forms,
depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.
Records \fIx\fR and \fIy\fR and the current view in the text window, for use
in conjunction with later \fIpathName \fBscan dragto\fR commands. Typically
this command is associated with a mouse button press in the widget. It returns
an empty string.
.TP
\fIpathName \fBscan dragto \fIx y\fR
.
This command computes the difference between its \fIx\fR and \fIy\fR arguments
and the \fIx\fR and \fIy\fR arguments to the last \fIpathName \fBscan mark\fR

command for the widget. It then adjusts the view by 10 times the difference in
coordinates. This command is typically associated with mouse motion events in

the widget, to produce the effect of dragging the text at high speed through
the window. The return value is an empty string.
.RE
.TP
\fIpathName \fBsearch \fR?\fIswitches\fR? \fIpattern index \fR?\fIstopIndex\fR?
.
Searches the text in \fIpathName\fR starting at \fIindex\fR for a range of
characters that matches \fIpattern\fR. If a match is found, the index of the
first character in the match is returned as result; otherwise an empty string

is returned. One or more of the following switches (or abbreviations thereof)
may be specified to control the search:
.RS
.TP
\fB\-forwards\fR
.
The search will proceed forward through the text, finding the first matching
range starting at or after the position given by \fIindex\fR. This is the
default.
.TP
\fB\-backwards\fR
.
The search will proceed backward through the text, finding the matching range
closest to \fIindex\fR whose first character is before \fIindex\fR (it is not


allowed to be at \fIindex\fR). Note that, for a variety of reasons, backwards
searches can be substantially slower than forwards searches (particularly when
using \fB\-regexp\fR), so it is recommended that performance-critical code use
forward searches.

.TP
\fB\-exact\fR
.
Use exact matching: the characters in the matching range must be identical to

those in \fIpattern\fR. This is the default.
.TP
\fB\-regexp\fR
.
Treat \fIpattern\fR as a regular expression and match it against the text
using the rules for regular expressions (see the \fBregexp\fR command
and the \fBre_syntax\fR page for

details). The default matching automatically passes both the
\fB\-lineanchor\fR and \fB\-linestop\fR options to the regexp engine (unless

\fB\-nolinestop\fR is used), so that \fI^$\fR match beginning and end of line,
and \fI.\fR, \fI[^\fR sequences will never match the newline character
\fI\en\fR.
.TP
\fB\-nolinestop\fR
.
This allows \fI.\fR and \fI[^\fR sequences to match the newline character
\fI\en\fR, which they will otherwise not do (see the \fBregexp\fR command for
details). This option is only meaningful if \fB\-regexp\fR is also given, and

an error will be thrown otherwise. For example, to match the entire text, use
.QW "\fIpathName \fBsearch \-nolinestop \-regexp\fR \N'34'.*\N'34' 1.0" .

.TP
\fB\-nocase\fR
.
Ignore case differences between the pattern and the text.
.TP
\fB\-count\fI varName\fR
.
The argument following \fB\-count\fR gives the name of a variable; if a match
is found, the number of index positions between beginning and end of the
matching range will be stored in the variable. If there are no embedded images
or windows in the matching range (and there are no elided characters if
\fB\-elide\fR is not given), this is equivalent to the number of characters
matched. In either case, the range \fImatchIdx\fR to \fImatchIdx + $count
chars\fR will return the entire matched text.
.TP
\fB\-all\fR
.
Find all matches in the given range and return a list of the indices of the
first character of each match. If a \fB\-count\fI varName\fR switch is given,
then \fIvarName\fR is also set to a list containing one element for each
successful match. Note that, even for exact searches, the elements of this
list may be different, if there are embedded images, windows or hidden text.
Searches with \fB\-all\fR behave very similarly to the Tcl command \fBregexp

\-all\fR, in that overlapping matches are not normally returned. For example,
applying an \fB\-all\fR search of the pattern
.QW \ew+
against
.QW "hello there"
will just match twice, once for each word, and matching
.QW "Z[a\-z]+Z"
against
.QW ZooZooZoo
will just match once.

.TP
\fB\-overlap\fR
.
When performing \fB\-all\fR searches, the normal behaviour is that matches
which overlap an already-found match will not be returned. This switch changes
that behaviour so that all matches which are not totally enclosed within
another match are returned. For example, applying an \fB\-overlap\fR search of
the pattern
.QW \ew+
against
.QW "hello there"
will just match twice (i.e. no different to just \fB\-all\fR), but matching

.QW Z[a\-z]+Z
against
.QW ZooZooZoo
will now match twice. An error will be thrown if this switch is used without
\fB\-all\fR.

.TP
\fB\-strictlimits\fR
.
When performing any search, the normal behaviour is that the start and stop
limits are checked with respect to the start of the matching text. With the

\fB\-strictlimits\fR flag, the entire matching range must lie inside the start
and stop limits specified for the match to be valid.

.TP
\fB\-elide\fR
.
Find elided (hidden) text as well. By default only displayed text is searched.

.TP
\fB\-\|\-\fR
.
This switch has no effect except to terminate the list of switches: the next
argument will be treated as \fIpattern\fR even if it starts with \fB\-\fR.

.PP

The matching range may be within a single line of text, or run across multiple
lines (if parts of the pattern can match a new-line). For regular expression
matching one can use the various newline-matching features such as \fB$\fR to
match the end of a line, \fB^\fR to match the beginning of a line, and to

control whether \fB.\fR is allowed to match a new-line. If \fIstopIndex\fR is

specified, the search stops at that index: for forward searches, no match at

or after \fIstopIndex\fR will be considered; for backward searches, no match
earlier in the text than \fIstopIndex\fR will be considered. If
\fIstopIndex\fR is omitted, the entire text will be searched: when the
beginning or end of the text is reached, the search continues at the other end
until the starting location is reached again; if \fIstopIndex\fR is specified,

no wrap-around will occur. This means that, for example, if the search is
\fB\-forwards\fR but \fIstopIndex\fR is earlier in the text than
\fIstartIndex\fR, nothing will ever be found. See \fBKNOWN BUGS\fR below for a
number of minor limitations of the \fIpathName \fBsearch\fR command.
.RE
.TP
\fIpathName \fBsee \fIindex\fR
.
Adjusts the view in the window so that the character given by \fIindex\fR is

completely visible. If \fIindex\fR is already visible then the command does
nothing. If \fIindex\fR is a short distance out of view, the command adjusts
the view just enough to make \fIindex\fR visible at the edge of the window.

If \fIindex\fR is far out of view, then the command centers \fIindex\fR in the
window.
.TP
\fIpathName \fBsync\fR ?\fB-command \fIcommand\fR?
Controls the synchronization of the view of the text widget.
.RS
.TP
\fIpathName \fBsync\fR
Immediately brings the line metrics up-to-date by forcing computation of any
outdated line heights. The command returns immediately if there is no such
outdated line heights, otherwise it returns only at the end of the computation.
The command returns an empty string.
.TP
\fIpathName \fBsync -command \fIcommand\fR
Schedules \fIcommand\fR to be executed (by the event loop) exactly once as soon
as all line heights are up-to-date. If there are no pending line metrics
calculations, the scheduling is immediate. The command returns the empty
string. \fBbgerror\fR is called on \fIcommand\fR failure.
.RE
.TP
\fIpathName \fBtag \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:

.RS
.TP
\fIpathName \fBtag add \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?
.
Associate the tag \fItagName\fR with all of the characters starting with
\fIindex1\fR and ending just before \fIindex2\fR (the character at

\fIindex2\fR is not tagged). A single command may contain any number of

\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
single character at \fIindex1\fR is tagged. If there are no characters in the

specified range (e.g. \fIindex1\fR is past the end of the file or \fIindex2\fR
is less than or equal to \fIindex1\fR) then the command has no effect.
.TP
\fIpathName \fBtag bind \fItagName\fR ?\fIsequence\fR? ?\fIscript\fR?
.
This command associates \fIscript\fR with the tag given by \fItagName\fR.

Whenever the event sequence given by \fIsequence\fR occurs for a character
that has been tagged with \fItagName\fR, the script will be invoked. This

widget command is similar to the \fBbind\fR command except that it operates on
characters in a text rather than entire widgets. See the \fBbind\fR manual

entry for complete details on the syntax of \fIsequence\fR and the
substitutions performed on \fIscript\fR before invoking it. If all arguments
are specified then a new binding is created, replacing any existing binding
for the same \fIsequence\fR and \fItagName\fR (if the first character of
\fIscript\fR is
.QW +
then \fIscript\fR augments an existing binding rather than replacing it). In
this case the return value is an empty string. If \fIscript\fR is omitted then
the command returns the \fIscript\fR associated with \fItagName\fR and

\fIsequence\fR (an error occurs if there is no such binding). If both
\fIscript\fR and \fIsequence\fR are omitted then the command returns a list of
all the sequences for which bindings have been defined for \fItagName\fR.

.RS
.PP
The only events for which bindings may be specified are those related to the
mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButton\fR,
\fBMotion\fR, and \fBKey\fR) or virtual events. Event bindings for a text
widget use the \fBcurrent\fR mark described under \fBMARKS\fR above. An
\fBEnter\fR event triggers for a tag when the tag first becomes present on the
current character, and a \fBLeave\fR event triggers for a tag when it ceases

to be present on the current character. \fBEnter\fR and \fBLeave\fR events can
happen either because the \fBcurrent\fR mark moved or because the character at
that position changed. Note that these events are different than \fBEnter\fR
and \fBLeave\fR events for windows. Mouse and keyboard events are directed to
the current character. If a virtual event is used in a binding, that binding
can trigger only if the virtual event is defined by an underlying
mouse-related or keyboard-related event.
.PP
It is possible for the current character to have multiple tags, and for each
of them to have a binding for a particular event sequence. When this occurs,

one binding is invoked for each tag, in order from lowest-priority to highest

priority. If there are multiple matching bindings for a single tag, then the
most specific binding is chosen (see the manual entry for the \fBbind\fR

command for details). \fBcontinue\fR and \fBbreak\fR commands within binding
scripts are processed in the same way as for bindings created with the
\fBbind\fR command.
.PP
If bindings are created for the widget as a whole using the \fBbind\fR
command, then those bindings will supplement the tag bindings. The tag

bindings will be invoked first, followed by bindings for the window as a
whole.
.RE
.TP
\fIpathName \fBtag cget \fItagName option\fR
.
This command returns the current value of the option named \fIoption\fR
associated with the tag given by \fItagName\fR. \fIOption\fR may have any of
the values accepted by the \fIpathName \fBtag configure\fR widget command.

.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fIpathName \fBconfigure\fR widget command
except that it modifies options associated with the tag given by \fItagName\fR
instead of modifying options for the overall text widget. If no \fIoption\fR
is specified, the command returns a list describing all of the available
options for \fItagName\fR (see \fBTk_ConfigureInfo\fR for information on the

format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then
the command returns a list describing the one named option (this list will be
identical to the corresponding sublist of the value returned if no

\fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are
specified, then the command modifies the given option(s) to have the given
value(s) in \fItagName\fR; in this case the command returns an empty string.
See \fBTAGS\fR above for details on the options available for tags.
.TP
\fIpathName \fBtag delete \fItagName \fR?\fItagName ...\fR?
.
Deletes all tag information for each of the \fItagName\fR arguments. The

command removes the tags from all characters in the file and also deletes any
other information associated with the tags, such as bindings and display

information. The command returns an empty string.
.TP
\fIpathName\fB tag lower \fItagName \fR?\fIbelowThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just lower in priority
than the tag whose name is \fIbelowThis\fR. If \fIbelowThis\fR is omitted,

then \fItagName\fR's priority is changed to make it lowest priority of all
tags.
.TP
\fIpathName \fBtag names \fR?\fIindex\fR?
.
Returns a list whose elements are the names of all the tags that are active at
the character position given by \fIindex\fR. If \fIindex\fR is omitted, then

the return value will describe all of the tags that exist for the text (this
includes all tags that have been named in a
.QW "\fIpathName \fBtag\fR"
widget command but have not been deleted by a
.QW "\fIpathName \fBtag delete\fR"
widget command, even if no characters are currently marked with the tag). The
list will be sorted in order from lowest priority to highest priority.

.TP
\fIpathName \fBtag nextrange \fItagName index1 \fR?\fIindex2\fR?
.
This command searches the text for a range of characters tagged with
\fItagName\fR where the first character of the range is no earlier than the
character at \fIindex1\fR and no later than the character just before

\fIindex2\fR (a range starting at \fIindex2\fR will not be considered). If
several matching ranges exist, the first one is chosen. The command's return

value is a list containing two elements, which are the index of the first
character of the range and the index of the character just after the last one

in the range. If no matching range is found then the return value is an empty

string. If \fIindex2\fR is not given then it defaults to the end of the text.
.TP
\fIpathName \fBtag prevrange \fItagName index1 \fR?\fIindex2\fR?
.
This command searches the text for a range of characters tagged with
\fItagName\fR where the first character of the range is before the character

at \fIindex1\fR and no earlier than the character at \fIindex2\fR (a range
starting at \fIindex2\fR will be considered). If several matching ranges
exist, the one closest to \fIindex1\fR is chosen. The command's return value

is a list containing two elements, which are the index of the first character
of the range and the index of the character just after the last one in the

range. If no matching range is found then the return value is an empty string.

If \fIindex2\fR is not given then it defaults to the beginning of the text.
.TP
\fIpathName\fB tag raise \fItagName \fR?\fIaboveThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just higher in
priority than the tag whose name is \fIaboveThis\fR. If \fIaboveThis\fR is
omitted, then \fItagName\fR's priority is changed to make it highest priority
of all tags.
.TP
\fIpathName \fBtag ranges \fItagName\fR
.
Returns a list describing all of the ranges of text that have been tagged with

\fItagName\fR. The first two elements of the list describe the first tagged
range in the text, the next two elements describe the second range, and so on.

The first element of each pair contains the index of the first character of
the range, and the second element of the pair contains the index of the
character just after the last one in the range. If there are no characters


tagged with \fItag\fR then an empty string is returned.
.TP
\fIpathName \fBtag remove \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?
.
Remove the tag \fItagName\fR from all of the characters starting at
\fIindex1\fR and ending just before \fIindex2\fR (the character at

\fIindex2\fR is not affected). A single command may contain any number of

\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command

has no effect. This command returns an empty string.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR

argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBwindow cget \fIindex option\fR
.
Returns the value of a configuration option for an embedded window.
\fIIndex\fR identifies the embedded window, and \fIoption\fR specifies a
particular configuration option, which must be one of the ones listed in the
section \fBEMBEDDED WINDOWS\fR.
.TP
\fIpathName \fBwindow configure \fIindex\fR ?\fIoption value ...\fR?
.
Query or modify the configuration options for an embedded window. If no
\fIoption\fR is specified, returns a list describing all of the available
options for the embedded window at \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified with no

\fIvalue\fR, then the command returns a list describing the one named option
(this list will be identical to the corresponding sublist of the value
returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR

pairs are specified, then the command modifies the given option(s) to have the
given value(s); in this case the command returns an empty string. See
\fBEMBEDDED WINDOWS\fR for information on the options that are supported.

.TP
\fIpathName \fBwindow create \fIindex\fR ?\fIoption value ...\fR?
.
This command creates a new window annotation, which will appear in the text at

the position given by \fIindex\fR. Any number of \fIoption\-value\fR pairs may
be specified to configure the annotation. See \fBEMBEDDED WINDOWS\fR for


information on the options that are supported. Returns an empty string.
.TP
\fIpathName \fBwindow names\fR
.
Returns a list whose elements are the names of all windows currently embedded
in \fIwindow\fR.
.RE
.TP
\fIpathName \fBxview \fIoption args\fR
.
This command is used to query and change the horizontal position of the text
in the widget's window. It can take any of the following forms:

.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements. Each element is a real fraction
between 0 and 1; together they describe the portion of the document's
horizontal span that is visible in the window. For example, if the first

element is .2 and the second element is .6, 20% of the text is off-screen to

the left, the middle 40% is visible in the window, and 40% of the text is
off-screen to the right. The fractions refer only to the lines that are
actually visible in the window: if the lines in the window are all very short,
so that they are entirely visible, the returned fractions will be 0 and 1,
even if there are other lines in the text that are much wider than the window.

These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that \fIfraction\fR of the horizontal span
of the text is off-screen to the left. \fIFraction\fR is a fraction between 0
and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBpages\fR,


\fBpixels\fR, or \fBunits\fR. If \fIwhat\fR is \fBpages\fR or
\fBunits\fR then \fInumber\fR must be an integer, otherwise number may be
specified in any of the forms acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,
pixels are assumed). If \fIwhat\fR is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls; if it is \fBpixels\fR then the view adjusts by
\fInumber\fR pixels; if it is \fBunits\fR, the view adjusts left or
right by \fInumber\fR average-width characters on the display. If \fInumber\fR is



negative then characters farther to the left become visible; if it is positive
then characters farther to the right become visible.

.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the text in

the widget's window. It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR
.
Returns a list containing two elements, both of which are real fractions

between 0 and 1. The first element gives the position of the first visible
pixel of the first character (or image, etc) in the top line in the window,
relative to the text as a whole (0.5 means it is halfway through the text, for

example). The second element gives the position of the first pixel just after
the last visible one in the bottom line of the window, relative to the text as

a whole. These are the same values passed to scrollbars via the
\fB\-yscrollcommand\fR option.
.TP
\fIpathName \fByview moveto\fI fraction\fR
.
Adjusts the view in the window so that the pixel given by \fIfraction\fR
appears at the top of the top line of the window. \fIFraction\fR is a fraction

between 0 and 1; 0 indicates the first pixel of the first character in the
text, 0.33 indicates the pixel that is one-third the way through the text; and


so on. Values close to 1 will indicate values close to the last pixel in the
text (1 actually refers to one pixel beyond the last pixel), but in such cases
the widget will never scroll beyond the last pixel, and so a value of 1 will
effectively be rounded back to whatever fraction ensures the last pixel is at
the bottom of the window, and some other pixel is at the top.

.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjust the view in the window up or down according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBpages\fR,


\fBpixels\fR, or \fBunits\fR. If \fIwhat\fR is \fBunits\fR or \fBpages\fR then
\fInumber\fR must be an integer, otherwise number may be specified in any of
the forms acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,

pixels are assumed). If \fIwhat\fR is \fBunits\fR, the view adjusts up or down
by \fInumber\fR lines on the display; if it is \fBpages\fR then the view
adjusts by \fInumber\fR screenfuls; if it is \fBpixels\fR then the view
adjusts by \fInumber\fR pixels. If \fInumber\fR is negative then earlier


positions in the text become visible; if it is positive then later positions
in the text become visible.
.TP
\fIpathName \fByview \fR?\fB\-pickplace\fR? \fIindex\fR
.
Changes the view in the widget's window to make \fIindex\fR visible. If the
\fB\-pickplace\fR option is not specified then \fIindex\fR will appear at the

top of the window. If \fB\-pickplace\fR is specified then the widget chooses
where \fIindex\fR appears in the window:
.RS
.IP [1]
If \fIindex\fR is already visible somewhere in the window then the command
does nothing.
.IP [2]
If \fIindex\fR is only a few lines off-screen above the window then it will be
positioned at the top of the window.
.IP [3]
If \fIindex\fR is only a few lines off-screen below the window then it will be
positioned at the bottom of the window.
.IP [4]
Otherwise, \fIindex\fR will be centered in the window.
.PP
The \fB\-pickplace\fR option has been obsoleted by the \fIpathName \fBsee\fR
widget command (\fIpathName \fBsee\fR handles both x- and y-motion to make a
location visible, whereas the \fB\-pickplace\fR mode only handles motion in
y).
.RE
.TP
\fIpathName \fByview \fInumber\fR
.
This command makes the first character on the line after the one given by
\fInumber\fR visible at the top of the window. \fINumber\fR must be an

integer. This command used to be used for scrolling, but now it is obsolete.
.RE
.SH BINDINGS
.PP
Tk automatically creates class bindings for texts that give them the following
default behavior.
In the descriptions below,
.QW word
is dependent on the value of
the \fBtcl_wordchars\fR variable.  See \fBtclvars\fR(n).
.IP [1]
Clicking mouse button 1 positions the insertion cursor just before the
character underneath the mouse cursor, sets the input focus to this widget,
and clears any selection in the widget. Dragging with mouse button 1 strokes

out a selection between the insertion cursor and the character under the
mouse.
.IP [2]
Double-clicking with mouse button 1 selects the word under the mouse and
positions the insertion cursor at the start of the word. Dragging after a
double click will stroke out a selection consisting of whole words.

.IP [3]
Triple-clicking with mouse button 1 selects the line under the mouse and
positions the insertion cursor at the start of the line. Dragging after a
triple click will stroke out a selection consisting of whole lines.

.IP [4]
The ends of the selection can be adjusted by dragging with mouse button 1
while the Shift key is down; this will adjust the end of the selection that
was nearest to the mouse cursor when button 1 was pressed. If the button is

double-clicked before dragging then the selection will be adjusted in units of
whole words; if it is triple-clicked then the selection will be adjusted in
units of whole lines.
.IP [5]
Clicking mouse button 1 with the Control key down will reposition the
insertion cursor without affecting the selection.
.IP [6]
If any normal printing characters are typed, they are inserted at the point of
the insertion cursor.
.IP [7]
The view in the widget can be adjusted by dragging with the middle mouse
button (button 2, or button 3 in TkAqua). If the middle mouse button is
clicked without moving the mouse, the selection is copied into the text at the

position of the mouse cursor. The Insert key also inserts the selection,
but at the position of the insertion cursor.
.IP [8]
If the mouse is dragged out of the widget while button 1 is pressed, the entry

will automatically scroll to make more text visible (if there is more text
off-screen on the side where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the left or
right; they also clear any selection in the text. If Left or Right is typed
with the Shift key down, then the insertion cursor moves and the selection is

extended to include the new character. Control-Left and Control-Right move the
insertion cursor by words, and Control-Shift-Left and Control-Shift-Right move
the insertion cursor by words and also extend the selection. Control-b and
Control-f behave the same as Left and Right, respectively. Meta-b and Meta-f
behave the same as Control-Left and Control-Right, respectively.

.IP [10]
The Up and Down keys move the insertion cursor one line up or down and clear

any selection in the text. If Up or Right is typed with the Shift key down,
then the insertion cursor moves and the selection is extended to include the
new character. Control-Up and Control-Down move the insertion cursor by
paragraphs (groups of lines separated by blank lines), and Control-Shift-Up
and Control-Shift-Down move the insertion cursor by paragraphs and also extend

the selection. Control-p and Control-n behave the same as Up and Down,
respectively.
.IP [11]
The Next and Prior keys move the insertion cursor forward or backwards by one
screenful and clear any selection in the text. If the Shift key is held down
while Next or Prior is typed, then the selection is extended to include the
new character.
.IP [12]
Control-Next and Control-Prior scroll the view right or left by one page
without moving the insertion cursor or affecting the selection.
.IP [13]
Home and Control-a move the insertion cursor to the beginning of its display
line and clear any selection in the widget. Shift-Home moves the insertion
cursor to the beginning of the display line and also extends the selection to
that point.
.IP [14]
End and Control-e move the insertion cursor to the end of the display line and

clear any selection in the widget. Shift-End moves the cursor to the end of
the display line and extends the selection to that point.
.IP [15]
Control-Home and Meta-< move the insertion cursor to the beginning of the text
and clear any selection in the widget. Control-Shift-Home moves the insertion
cursor to the beginning of the text and also extends the selection to that
point.
.IP [16]
Control-End and Meta-> move the insertion cursor to the end of the text and
clear any selection in the widget. Control-Shift-End moves the cursor to the

end of the text and extends the selection to that point.
.IP [17]
The Select key and Control-Space set the selection anchor to the position of
the insertion cursor. They do not affect the current selection. Shift-Select
and Control-Shift-Space adjust the selection to the current position of the
insertion cursor, selecting from the anchor to the insertion cursor if there
was not any selection previously.
.IP [18]
Control-/ selects the entire contents of the widget.
.IP [19]
Control-\e clears any selection in the widget.
.IP [20]
The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the
selection in the widget to the clipboard, if there is a selection. This
action is carried out by the command \fBtk_textCopy\fR.
.IP [21]
The F20 key (labelled Cut on many Sun workstations) or Control-w copies the
selection in the widget to the clipboard and deletes the selection. This

action is carried out by the command \fBtk_textCut\fR. If there is no
selection in the widget then these keys have no effect.
.IP [22]
The F18 key (labelled Paste on many Sun workstations) or Control-y inserts the
contents of the clipboard at the position of the insertion cursor. This action

is carried out by the command \fBtk_textPaste\fR.
.IP [23]
The Delete key deletes the selection, if there is one in the widget. If there
is no selection, it deletes the character to the right of the insertion
cursor.
.IP [24]
Backspace and Control-h delete the selection, if there is one in the widget.

If there is no selection, they delete the character to the left of the
insertion cursor.
.IP [25]
Control-d deletes the character to the right of the insertion cursor.
.IP [26]
Meta-d deletes the word to the right of the insertion cursor.
.IP [27]
Control-k deletes from the insertion cursor to the end of its line; if the
insertion cursor is already at the end of a line, then Control-k deletes the
newline character.
.IP [28]
Control-o opens a new line by inserting a newline character in front of the
insertion cursor without moving the insertion cursor.
.IP [29]
Meta-backspace and Meta-Delete delete the word to the left of the insertion
cursor.
.IP [30]



Control-t reverses the order of the two characters to the right of the
insertion cursor.
.IP [31]
Control-x deletes whatever is selected in the text widget after copying it to
the clipboard.
.IP [32]
Control-z undoes the last edit action if the \fB\-undo\fR option is true.
Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit action if
the \fB\-undo\fR option is true. Does nothing otherwise.
.PP
If the widget is disabled using the \fB\-state\fR option, then its view can
still be adjusted and text can still be selected, but no insertion cursor will
be displayed and no text modifications will take place.

.PP
The behavior of texts can be changed by defining new bindings for individual
widgets or by redefining the class bindings.
.SH "KNOWN ISSUES"
.SS "ISSUES CONCERNING CHARS AND INDICES"

.PP
Before Tk 8.5, the widget used the string
.QW chars
to refer to index positions (which included characters, embedded windows and
embedded images). As of Tk 8.5 the text widget deals separately and correctly
with
.QW chars
and
.QW indices .
For backwards compatibility, however, the index modifiers
.QW "+N chars"
and
.QW "\-N chars"
continue to refer to indices. One must use any of the full forms

.QW "+N any chars"
or
.QW "\-N any chars"
etc. to refer to actual character indices. This confusion may be fixed in a
future release by making the widget correctly interpret
.QW "+N chars"
as a synonym for
.QW "+N any chars" .

.SS "PERFORMANCE ISSUES"
.PP
Text widgets should run efficiently under a variety of conditions. The text

widget uses about 2-3 bytes of main memory for each byte of text, so texts
containing a megabyte or more should be practical on most workstations. Text
is represented internally with a modified B-tree structure that makes
operations relatively efficient even with large texts. Tags are included in
the B-tree structure in a way that allows tags to span large ranges or have

many disjoint smaller ranges without loss of efficiency. Marks are also
implemented in a way that allows large numbers of marks. In most cases it is

fine to have large numbers of unique tags, or a tag that has many distinct
ranges.
.PP
One performance problem can arise if you have hundreds or thousands of
different tags that all have the following characteristics: the first and last
ranges of each tag are near the beginning and end of the text, respectively,

or a single tag range covers most of the text widget. The cost of adding and
deleting tags like this is proportional to the number of other tags with the

same properties. In contrast, there is no problem with having thousands of
distinct tags if their overall ranges are localized and spread uniformly
throughout the text.
.PP
Very long text lines can be expensive, especially if they have many marks and
tags within them.
.PP
The display line with the insert cursor is redrawn each time the cursor
blinks, which causes a steady stream of graphics traffic. Set the
\fB\-insertofftime\fR attribute to 0 avoid this.
.SS "KNOWN BUGS"

.PP
The \fIpathName \fBsearch \-regexp\fR sub-command attempts to perform
sophisticated regexp matching across multiple lines in an efficient fashion
(since Tk 8.5), examining each line individually, and then in small groups of
lines, whether searching forwards or backwards. Under certain conditions the
search result might differ from that obtained by applying the same regexp to
the entire text from the widget in one go. For example, when searching with a
greedy regexp, the widget will continue to attempt to add extra lines to the
match as long as one of two conditions are true: either Tcl's regexp library
returns a code to indicate a longer match is possible (but there are known
bugs in Tcl which mean this code is not always correctly returned); or if each

extra line added results in at least a partial match with the pattern. This
means in the case where the first extra line added results in no match and
Tcl's regexp system returns the incorrect code and adding a second extra line
would actually match, the text widget will return the wrong result. In
practice this is a rare problem, but it can occur, for example:
.CS
pack [\fBtext\fR .t]
\&.t insert 1.0 "aaaa\enbbbb\encccc\enbbbb\enaaaa\en"
\&.t search \-regexp \-\- {(a+|b+\enc+\enb+)+\ena+} 1.0
.CE
will not find a match when one exists of 19 characters starting from the first

.QW b .
.PP
Whenever one possible match is fully enclosed in another, the search command
will attempt to ensure only the larger match is returned. When performing
backwards regexp searches it is possible that Tcl will not always achieve
this, in the case where a match is preceded by one or more short,
non-overlapping matches, all of which are preceded by a large match which
actually encompasses all of them. The search algorithm used by the widget does

not look back arbitrarily far for a possible match which might cover large
portions of the widget. For example:
.CS
pack [\fBtext\fR .t]
\&.t insert 1.0 "aaaa\enbbbb\enbbbb\enbbbb\enbbbb\\n"
\&.t search \-regexp \-backward \-\- {b+\en|a+\en(b+\en)+} end
.CE
matches at
.QW 5.0
when a true greedy match would match at
.QW 1.0 .
Similarly if we add \fB\-all\fR to this case, it matches at all of
.QW 5.0 ,
.QW 4.0 ,
.QW 3.0
and
.QW 1.0 ,
when really it should only match at
.QW 1.0
since that match encloses all the others.

.SH "SEE ALSO"
entry(n), scrollbar(n)
.SH KEYWORDS
text, widget, tkvars
'\" Local Variables:
'\" mode: nroff
'\" End:







<
|
>
|
|
|
|
>
|
|
>
|
|
>
|
|
|
|


<
|
>
>
|
|
|
|




|
|
|
>
|
|



<




<


|
|


<



<



<
|
|
|


<
|
|
|
|
|
>


<
|
|
>
|
|


|
<
|
|
|
|


<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|


<
|
|
<
|
>


<



<
|
|


<
|
<
|
|
|
>


|
<
|
>
|
|
>
|
>
|
|
|
|
|
|
|
>
>
|
|
|
<
>

|
<
|
|
>
|


|
<
|
|
|
|


<
|
|
|
|
>
|
|
|
>
|
|
|
>


<
|
>
|
|
|
>
|
|


<





<
|
|
>



<

>
|
|
>
|
|
|
|
>
|
|
>
|
|
|
|
|

|
<
|
|
>
|



<
|
|
>
|
|


<
|
|


<
|
|
>
|
>
|
|
|
>
|
|
|
<
|


<
|
|
>
|
|
|
>
|
|
|
|
<


<
|
>
|
|
|


<
|
|
|




|
|
|
|



<
|
|
|
>
|


<

|


<
<
<










|
|
|
|

>

|
<
|
|



<
|
|
|
|


<
|
|
>
|
|
>
|
|



<
|
|
|
>
|




<
|
|
|


<
|
|
>
>
|
|
|
|
>


<
|
>
|


<
|
|
|
>
|
|
>
|
|
|


|
|
|
|
>
|

>


<



<
|
|
|
|
|
|
|


|
|
|
|
|
|
|
>
|
|








>


|
|
|
|
|
|



|
>



|
|
>


|
|
|
>
|
|
>


<
|
>


<
|
|
>

>
|
|
|
|
>
|
>
|
>
|
|
|
|
|
>
|
|
|
|



<
|
>
|
|
|
>
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
>



<
|
|
>
|
>
|
|
>
|
|


<
|
>
|
|
>
|
|
>
|
|
|
|
|

|
|
|
>
|
|
|
>


|
|
|
|
|
|
>
|
|
|
|
|
|


|
|
>
|
>
|
|
>
|
|
|

|
|
>
|
|


|
<

|
|
>


<
|
|
|
|
|
>
|
|
|
>
|
|
|



<
|
>
|
|
>
|


<
|
|
>
|
<


<
|
|
>
|
|



|
|
>


<
|
|
|
>
|
|
>
|
|
>
|
>
|


<
|
|
>
|
|
|
>
|
|
>
|
>



<
|
|
|
|


<
|
>
|
|
>
|
|
|
>
>
|


<
|
|
>
|
>
|
|
|
|
>
|


|
<
|
|
>
|


|
<

|
|
|


<
|
|
|
|
>
|
|
|
>
|
|
|
>


<
|
>
|
|
>
>
|


<
|
|



<
|
|
>



<
|
|
|
>
|
>
|
|
|
|
|
>




<
|
|
|


<

|
>
>
|
|
|



|
|
<
|
|
>
>
>
|
|
>


|
<
|
>
|



<

>
|
|
|
>
|
|
>
|
|


<

|
>
|
|
>
>
|
|
|
|
|
>


<

|
>
>
|
|
|



|
>
|
|

|
>
>
|
|


<
|
|
>
|
|


|
|

|
|

|
|


|
|
|
|
<



<
|
|
>
|



|
|





|
|
|
>
|
<

|
|
|
>

|
|
|
>

|
|
|
>
|
|
|




|
|

|
<
|
>
|
|

|
>
|
|

|
|
|
>
|
|
|
|
|
>

|
>
|
|
|
|
|
>
|
<

|
|
|
|




|
|
|
|

|
>
|
|

|
|
|
|

|
|
>
|

|
|
|
|
|





|
|
|

|
|
>
|
|

|
|
>
|

|
|
|

|
>
|
|





|
|
|

|
|

|
|

>
>
>
|
|
<
<
<

|
|

|
|

|
|
|
>

|
|


>



|
|
|







|
>



|




>


|
>
|
|
|
|
|
>
|
|
>
|
|

|
|
|
>
|
|
>
|
|
|

|
|

|
|
|

>

|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|

|



|
>


|
|
|
|
|
|
>
|
|

|
















>




<
<
<
1229
1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278

1279
1280
1281
1282
1283
1284

1285
1286
1287

1288
1289
1290

1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317










1318

1319
1320
1321
1322
1323
1324

1325
1326

1327
1328
1329
1330

1331
1332
1333

1334
1335
1336
1337

1338

1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367

1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441
1442
1443

1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454

1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469

1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480

1481
1482

1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503

1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514



1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532

1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543

1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584

1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706
1707

















1708

1709
1710
1711
1712
1713
1714
1715

1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727

1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786

1787
1788
1789
1790
1791
1792

1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808

1809
1810
1811
1812
1813
1814
1815
1816

1817
1818
1819
1820

1821
1822

1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835

1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865

1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898

1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911

1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926

1927
1928
1929
1930
1931
1932
1933
1934
1935

1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946

1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979

1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990

1991
1992
1993
1994
1995
1996

1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024

2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067

2068
2069
2070

2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115

2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227



2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361



first range so deleted text does not cause an undesired index shifting
side-effects.  If multiple ranges with the same start index are given,
then the longest range is used.  If overlapping ranges are given, then
they will be merged into spans that do not cause deletion of text
outside the given ranges due to text shifted during deletion.
.TP
\fIpathName \fBdlineinfo \fIindex\fR

Returns a list with five elements describing the area occupied
by the display line containing \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the area occupied by the
line, the third and fourth elements give the width and height
of the area, and the fifth element gives the position of the baseline
for the line, measured down from the top of the area.
All of this information is measured in pixels.
If the current wrap mode is \fBnone\fR and the line extends beyond
the boundaries of the window,
the area returned reflects the entire area of the line, including the
portions that are out of the window.
If the line is shorter than the full width of the window then the
area returned reflects just the portion of the line that is occupied
by characters and embedded windows.
If the display line containing \fIindex\fR is not visible on
the screen then the return value is an empty list.
.TP
\fIpathName \fBdump \fR?\fIswitches\fR? \fIindex1 \fR?\fIindex2\fR?

Return the contents of the text widget from \fIindex1\fR up to,
but not including \fIindex2\fR,
including the text and
information about marks, tags, and embedded windows.
If \fIindex2\fR is not specified, then it defaults to
one character past \fIindex1\fR.  The information is returned
in the following format:
.RS
.LP
\fIkey1 value1 index1 key2 value2 index2\fR ...
.LP
The possible \fIkey\fR values are \fBtext\fR, \fBmark\fR,
\fBtagon\fR, \fBtagoff\fR, \fBimage\fR, and \fBwindow\fR.  The corresponding
\fIvalue\fR is the text, mark name, tag name, image name, or window name.
The \fIindex\fR information is the index of the
start of the text, mark, tag transition, image or window.
One or more of the following switches (or abbreviations thereof)
may be specified to control the dump:
.TP
\fB\-all\fR

Return information about all elements: text, marks, tags, images and windows.
This is the default.
.TP
\fB\-command \fIcommand\fR

Instead of returning the information as the result of the dump operation,
invoke the \fIcommand\fR on each element of the text widget within the range.
The command has three arguments appended to it before it is evaluated:
the \fIkey\fR, \fIvalue\fR, and \fIindex\fR.
.TP
\fB\-image\fR

Include information about images in the dump results.
.TP
\fB\-mark\fR

Include information about marks in the dump results.
.TP
\fB\-tag\fR

Include information about tag transitions in the dump results. Tag
information is returned as \fBtagon\fR and \fBtagoff\fR elements that
indicate the begin and end of each range of each tag, respectively.
.TP
\fB\-text\fR

Include information about text in the dump results.  The value is the
text up to the next element or the end of range indicated by \fIindex2\fR.
A text element does not span newlines.  A multi-line block of text that
contains no marks or tag transitions will still be dumped as a set
of text segments that each end with a newline.  The newline is part
of the value.
.TP
\fB\-window\fR

Include information about embedded windows in the dump results.
The value of a window is its Tk pathname, unless the window
has not been created yet.  (It must have a create script.)
In this case an empty string is returned, and you must query the
window by its index position to get more information.
.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg arg ...\fR?

This command controls the undo mechanism and the modified flag.  The
exact behavior of the command depends on the \fIoption\fR argument
that follows the \fBedit\fR argument.  The following forms of the
command are currently supported:
.RS
.TP










\fIpathName \fBedit modified ?\fIboolean\fR?

If \fIboolean\fR is not specified, returns the modified flag of the
widget. The insert, delete, edit undo and edit redo commands or the
user can set or clear the modified flag.  If \fIboolean\fR is
specified, sets the modified flag of the widget to \fIboolean\fR.
.TP
\fIpathName \fBedit redo\fR

When the \fB\-undo\fR option is true, reapplies the last undone edits
provided no other edits were done since then. Generates an error when

the redo stack is empty.  Does nothing when the \fB\-undo\fR option is
false.
.TP
\fIpathName \fBedit reset\fR

Clears the undo and redo stacks.
.TP
\fIpathName \fBedit separator\fR

Inserts a separator (boundary) on the undo stack. Does nothing when
the \fB\-undo\fR option is false.
.TP
\fIpathName \fBedit undo\fR

Undoes the last edit action when the \fB\-undo\fR option is true.  An

edit action is defined as all the insert and delete commands that are
recorded on the undo stack in between two separators. Generates an
error when the undo stack is empty.  Does nothing when the \fB\-undo\fR
option is false.
.RE
.TP
\fIpathName \fBget\fR \fI?\-displaychars?\fR \fI\-\- index1\fR ?\fIindex2 ...\fR?

Return a range of characters from the text.
The return value will be all the characters in the text starting
with the one whose index is \fIindex1\fR and ending just before
the one whose index is \fIindex2\fR (the character at \fIindex2\fR
will not be returned).
If \fIindex2\fR is omitted then the single character at \fIindex1\fR
is returned.
If there are no characters in the specified range (e.g. \fIindex1\fR
is past the end of the file or \fIindex2\fR is less than or equal
to \fIindex1\fR) then an empty string is returned.
If the specified range contains embedded windows, no information
about them is included in the returned string.
If multiple index pairs are given, multiple ranges of text will be returned
in a list.  Invalid ranges will not be represented with empty strings in
the list.  The ranges are returned in the order passed to \fIpathName \fBget\fR.
.VS 8.5
If the \fB\-displaychars\fR option is given, then, within each range,
only those characters which are not elided will be returned.  This may
have the effect that some of the returned ranges are empty strings.

.VE 8.5
.TP
\fIpathName \fBimage \fIoption \fR?\fIarg arg ...\fR?

This command is used to manipulate embedded images.
The behavior of the command depends on the \fIoption\fR argument
that follows the \fBtag\fR argument.
The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBimage cget\fR \fIindex option\fR

Returns the value of a configuration option for an embedded image.
\fIIndex\fR identifies the embedded image, and \fIoption\fR
specifies a particular configuration option, which must be one of
the ones listed in the section \fBEMBEDDED IMAGES\fR.
.TP
\fIpathName \fBimage configure \fIindex\fR ?\fIoption value ...\fR?

Query or modify the configuration options for an embedded image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the embedded image at \fIindex\fR
(see \fBTk_ConfigureInfo\fR for information on the format of this list).
If \fIoption\fR is specified with no \fIvalue\fR, then the command
returns a list describing the one named option (this list will be
identical to the corresponding sublist of the value returned if no
\fIoption\fR is specified).
If one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
See \fBEMBEDDED IMAGES\fR for information on the options that
are supported.
.TP
\fIpathName \fBimage create \fIindex\fR ?\fIoption value ...\fR?

This command creates a new image annotation, which will appear
in the text at the position given by \fIindex\fR.
Any number of \fIoption\-value\fR pairs may be specified to
configure the annotation.
Returns a unique identifier that may be used as an index to refer to
this image.
See \fBEMBEDDED IMAGES\fR for information on the options that
are supported, and a description of the identifier returned.
.TP
\fIpathName \fBimage names\fR

Returns a list whose elements are the names of all image instances currently
embedded in \fIwindow\fR.
.RE
.TP
\fIpathName \fBindex \fIindex\fR

Returns the position corresponding to \fIindex\fR in the form
\fIline.char\fR where \fIline\fR is the line number and \fIchar\fR
is the character number.
\fIIndex\fR may have any of the forms described under \fBINDICES\fR above.
.TP
\fIpathName \fBinsert \fIindex chars \fR?\fItagList chars tagList ...\fR?

Inserts all of the \fIchars\fR arguments just before the character at
\fIindex\fR.
If \fIindex\fR refers to the end of the text (the character after
the last newline) then the new text is inserted just before the
last newline instead.
If there is a single \fIchars\fR argument and no \fItagList\fR, then
the new text will receive any tags that are present on both the
character before and the character after the insertion point; if a tag
is present on only one of these characters then it will not be
applied to the new text.
If \fItagList\fR is specified then it consists of a list of
tag names;  the new characters will receive all of the tags in
this list and no others, regardless of the tags present around
the insertion point.
If multiple \fIchars\fR\-\fItagList\fR argument pairs are present,
they produce the same effect as if a separate \fIpathName \fBinsert\fR widget
command had been issued for each pair, in order.
The last \fItagList\fR argument may be omitted.
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg arg ...\fR?

This command is used to manipulate marks.  The exact behavior of
the command depends on the \fIoption\fR argument that follows
the \fBmark\fR argument.  The following forms of the command
are currently supported:
.RS
.TP
\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?

If \fIdirection\fR is not specified, returns \fBleft\fR or \fBright\fR
to indicate which of its adjacent characters \fImarkName\fR is attached
to.
If \fIdirection\fR is specified, it must be \fBleft\fR or \fBright\fR;
the gravity of \fImarkName\fR is set to the given value.
.TP
\fIpathName \fBmark names\fR

Returns a list whose elements are the names of all the marks that
are currently set.
.TP
\fIpathName \fBmark next \fIindex\fR

Returns the name of the next mark at or after \fIindex\fR.
If \fIindex\fR is specified in numerical form, then the search for
the next mark begins at that index.
If \fIindex\fR is the name of a mark, then the search for
the next mark begins immediately after that mark.
This can still return a mark at the same position if
there are multiple marks at the same index.
These semantics mean that the \fBmark next\fR operation can be used to
step through all the marks in a text widget in the same order
as the mark information returned by the \fIpathName \fBdump\fR operation.
If a mark has been set to the special \fBend\fR index,
then it appears to be \fIafter\fR \fBend\fR with respect to the \fIpathName \fBmark next\fR operation.

An empty string is returned if there are no marks after \fIindex\fR.
.TP
\fIpathName \fBmark previous \fIindex\fR

Returns the name of the mark at or before \fIindex\fR.
If \fIindex\fR is specified in numerical form, then the search for
the previous mark begins with the character just before that index.
If \fIindex\fR is the name of a mark, then the search for
the next mark begins immediately before that mark.
This can still return a mark at the same position if
there are multiple marks at the same index.
These semantics mean that the \fIpathName \fBmark previous\fR operation can be used to
step through all the marks in a text widget in the reverse order
as the mark information returned by the \fIpathName \fBdump\fR operation.
An empty string is returned if there are no marks before \fIindex\fR.

.TP
\fIpathName \fBmark set \fImarkName index\fR

Sets the mark named \fImarkName\fR to a position just before the
character at \fIindex\fR.
If \fImarkName\fR already exists, it is moved from its old position;
if it does not exist, a new mark is created.
This command returns an empty string.
.TP
\fIpathName \fBmark unset \fImarkName \fR?\fImarkName markName ...\fR?

Remove the mark corresponding to each of the \fImarkName\fR arguments.
The removed marks will not be usable in indices and will not be
returned by future calls to
.QW "\fIpathName \fBmark names\fR" .
This command returns an empty string.
.RE
.TP
\fIpathName \fBpeer\fR \fIoption args\fR
.VS 8.5
This command is used to create and query widget peers.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBpeer create \fInewPathName\fR ?\fIoptions\fR?

Creates a peer text widget with the given \fInewPathName\fR, and any
optional standard configuration options (as for the \fItext\fR command).
By default the peer will have the same start and end line as the
parent widget, but these can be overridden with the standard
configuration options.
.TP
\fIpathName \fBpeer names\fR

Returns a list of peers of this widget (this does not include the widget
itself).  The order within this list is undefined.
.RE
.TP



\fIpathName \fBreplace\fR \fIindex1 index2 chars\fR ?\fItagList chars tagList ...\fR?
Replaces the range of characters between \fIindex1\fR and \fIindex2\fR
with the given characters and tags.  See the section on \fIpathName
\fBinsert\fR for an explanation of the handling of the \fItagList...\fR
arguments, and the section on \fIpathName
\fBdelete\fR for an explanation of the handling of the indices.  If
\fIindex2\fR corresponds to an index earlier in the text than
\fIindex1\fR, an error will be generated.
.RS
.PP
The deletion and insertion are arranged so that no unnecessary
scrolling of the window or movement of insertion cursor occurs.  In
addition the undo/redo stack are correctly modified, if undo operations
are active in the text widget.  The command returns an empty string.
.RE
.VE 8.5
.TP
\fIpathName \fBscan\fR \fIoption args\fR

This command is used to implement scanning on texts.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR

Records \fIx\fR and \fIy\fR and the current view in the text window,
for use in conjunction with later \fIpathName \fBscan dragto\fR commands.
Typically this command is associated with a mouse button press in
the widget.  It returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx y\fR

This command computes the difference between its \fIx\fR and \fIy\fR
arguments and the \fIx\fR and \fIy\fR arguments to the last
\fIpathName \fBscan mark\fR command for the widget.
It then adjusts the view by 10 times the difference in coordinates.
This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the text at high speed through the window.  The return
value is an empty string.
.RE
.TP
\fIpathName \fBsearch \fR?\fIswitches\fR? \fIpattern index \fR?\fIstopIndex\fR?

Searches the text in \fIpathName\fR starting at \fIindex\fR for a range
of characters that matches \fIpattern\fR.
If a match is found, the index of the first character in the match is
returned as result;  otherwise an empty string is returned.
One or more of the following switches (or abbreviations thereof)
may be specified to control the search:
.RS
.TP
\fB\-forwards\fR

The search will proceed forward through the text, finding the first
matching range starting at or after the position given by \fIindex\fR.
This is the default.
.TP
\fB\-backwards\fR

The search will proceed backward through the text, finding the
matching range closest to \fIindex\fR whose first character
is before \fIindex\fR
.VS 8.5
(it is not allowed to be at \fIindex\fR).  Note that, for a variety of
reasons, backwards searches can be substantially slower than forwards
searches (particularly when using \fB\-regexp\fR), so it is recommended
that performance-critical code use forward searches.
.VE 8.5
.TP
\fB\-exact\fR

Use exact matching:  the characters in the matching range must be
identical to those in \fIpattern\fR.
This is the default.
.TP
\fB\-regexp\fR

Treat \fIpattern\fR as a regular expression and match it against
the text using the rules for regular expressions (see the \fBregexp\fR
command for details).
.VS 8.5
The default matching automatically passes
both the \fB\-lineanchor\fR and \fB\-linestop\fR options
to the regexp engine (unless \fB\-nolinestop\fR is used), so that
\fI^$\fR match beginning and end of line, and \fI.\fR, \fI[^\fR
sequences will never match the newline character \fI\en\fR.
.VE 8.5
.TP
\fB\-nolinestop\fR
.VS 8.5
This allows \fI.\fR and \fI[^\fR sequences to match the newline
character \fI\en\fR, which they will otherwise not do (see the \fBregexp\fR
command for details). This option is only meaningful if \fB\-regexp\fR
is also given, and an error will be thrown otherwise.  For example,
to match the entire text, use
.QW "\fIpathName \fBsearch \-nolinestop \-regexp\fR \N'34'.*\N'34' 1.0" .
.VE 8.5
.TP
\fB\-nocase\fR

Ignore case differences between the pattern and the text.
.TP
\fB\-count\fI varName\fR

The argument following \fB\-count\fR gives the name of a variable;
if a match is found, the number of index positions between beginning and
end of the matching range will be stored in the variable.  If there are no
embedded images or windows in the matching range (and there are no
elided characters if \fB\-elide\fR is not given), this is equivalent to the
number of characters matched.  In either case, the range \fImatchIdx\fR to
\fImatchIdx + $count chars\fR will return the entire matched text.
.TP
\fB\-all\fR
.VS 8.5
Find all matches in the given range and return a list of the indices of
the first character of each match.  If a \fB\-count\fI varName\fR switch is
given, then \fIvarName\fR is also set to a list containing one element
for each successful match.  Note that, even for exact searches, the
elements of this list may be different, if there are embedded images,
windows or hidden text.  Searches with \fB\-all\fR behave very
similarly to the Tcl command \fBregexp \-all\fR, in that overlapping
matches are not normally returned.  For example, applying an
\fB\-all\fR search of the pattern
.QW \ew+
against
.QW "hello there"
will just match twice, once for each word, and matching
.QW "Z[a\-z]+Z"
against
.QW ZooZooZoo
will just match once.
.VE 8.5
.TP
\fB\-overlap\fR
.VS 8.5
When performing \fB\-all\fR searches, the normal behaviour is that
matches which overlap an already-found match will not be returned.  This
switch changes that behaviour so that all matches which are not totally
enclosed within another match are returned.  For example, applying an
\fB\-overlap\fR search of the pattern
.QW \ew+
against
.QW "hello there"
will just match twice (i.e. no different to just \fB\-all\fR),
but matching
.QW Z[a\-z]+Z
against
.QW ZooZooZoo
will now match twice.
An error will be thrown if this switch is used without \fB\-all\fR.
.VE 8.5
.TP
\fB\-strictlimits\fR
.VS 8.5
When performing any search, the normal behaviour is that
the start and stop limits are checked with respect to the
start of the matching text.  With the \fB\-strictlimits\fR flag,
the entire matching range must lie inside the start and stop
limits specified for the match to be valid.
.VE 8.5
.TP
\fB\-elide\fR

Find elided (hidden) text as well. By default only displayed text is
searched.
.TP
\fB\-\|\-\fR

This switch has no effect except to terminate the list of switches:
the next argument will be treated as \fIpattern\fR even if it starts
with \fB\-\fR.
.PP
.VS 8.5
The matching range may be within a single line of text, or run across
multiple lines (if parts of the pattern can match a new-line).  For
regular expression matching one can use the various newline-matching
features such as \fB$\fR to match the end of a line, \fB^\fR to match
the beginning of a line, and to control
whether \fB.\fR is allowed to match a new-line.
.VE 8.5
If \fIstopIndex\fR is specified, the search stops at that index:
for forward searches, no match at or after \fIstopIndex\fR will
be considered;  for backward searches, no match earlier in the
text than \fIstopIndex\fR will be considered.
If \fIstopIndex\fR is omitted, the entire text will be searched:
when the beginning or end of the text is reached, the search
continues at the other end until the starting location is reached
again;  if \fIstopIndex\fR is specified, no wrap-around will occur.
This means that, for example, if the search is \fB\-forwards\fR
but \fIstopIndex\fR is earlier in the text than \fIstartIndex\fR,
nothing will ever be found.  See \fBKNOWN BUGS\fR below for a number of
minor limitations of the \fIpathName \fBsearch\fR command.
.RE
.TP
\fIpathName \fBsee \fIindex\fR

Adjusts the view in the window so that the character given by \fIindex\fR
is completely visible.
If \fIindex\fR is already visible then the command does nothing.
If \fIindex\fR is a short distance out of view, the command
adjusts the view just enough to make \fIindex\fR visible at the
edge of the window.
If \fIindex\fR is far out of view, then the command centers
\fIindex\fR in the window.
.TP

















\fIpathName \fBtag \fIoption \fR?\fIarg arg ...\fR?

This command is used to manipulate tags.  The exact behavior of the
command depends on the \fIoption\fR argument that follows the
\fBtag\fR argument.  The following forms of the command are currently
supported:
.RS
.TP
\fIpathName \fBtag add \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?

Associate the tag \fItagName\fR with all of the characters starting
with \fIindex1\fR and ending just before
\fIindex2\fR (the character at \fIindex2\fR is not tagged).
A single command may contain any number of \fIindex1\fR\-\fIindex2\fR
pairs.
If the last \fIindex2\fR is omitted then the single character at
\fIindex1\fR is tagged.
If there are no characters in the specified range (e.g. \fIindex1\fR
is past the end of the file or \fIindex2\fR is less than or equal
to \fIindex1\fR) then the command has no effect.
.TP
\fIpathName \fBtag bind \fItagName\fR ?\fIsequence\fR? ?\fIscript\fR?

This command associates \fIscript\fR with the tag given by
\fItagName\fR.
Whenever the event sequence given by \fIsequence\fR occurs for a
character that has been tagged with \fItagName\fR,
the script will be invoked.
This widget command is similar to the \fBbind\fR command except that
it operates on characters in a text rather than entire widgets.
See the \fBbind\fR manual entry for complete details
on the syntax of \fIsequence\fR and the substitutions performed
on \fIscript\fR before invoking it.
If all arguments are specified then a new binding is created, replacing
any existing binding for the same \fIsequence\fR and \fItagName\fR
(if the first character of \fIscript\fR is
.QW +
then \fIscript\fR augments an existing binding rather than replacing it).
In this case the return value is an empty string.
If \fIscript\fR is omitted then the command returns the \fIscript\fR
associated with \fItagName\fR and \fIsequence\fR (an error occurs
if there is no such binding).
If both \fIscript\fR and \fIsequence\fR are omitted then the command
returns a list of all the sequences for which bindings have been
defined for \fItagName\fR.
.RS
.PP
The only events for which bindings may be specified are those related
to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
\fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR) or virtual events.
Event bindings for a text widget use the \fBcurrent\fR mark described
under \fBMARKS\fR above.  An \fBEnter\fR event triggers for a tag when the tag
first becomes present on the current character, and a \fBLeave\fR event
triggers for a tag when it ceases to be present on the current character.
\fBEnter\fR and \fBLeave\fR events can happen either because the
\fBcurrent\fR mark moved or because the character at that position
changed.  Note that these events are different than \fBEnter\fR and
\fBLeave\fR events for windows.  Mouse and keyboard events are directed
to the current character.  If a virtual event is used in a binding, that
binding can trigger only if the virtual event is defined by an underlying
mouse-related or keyboard-related event.
.PP
It is possible for the current character to have multiple tags,
and for each of them to have a binding for a particular event
sequence.
When this occurs, one binding is invoked for each tag, in order
from lowest-priority to highest priority.
If there are multiple matching bindings for a single tag, then
the most specific binding is chosen (see the manual entry for
the \fBbind\fR command for details).
\fBcontinue\fR and \fBbreak\fR commands within binding scripts
are processed in the same way as for bindings created with
the \fBbind\fR command.
.PP
If bindings are created for the widget as a whole using the
\fBbind\fR command, then those bindings will supplement the
tag bindings.
The tag bindings will be invoked first, followed by bindings
for the window as a whole.
.RE
.TP
\fIpathName \fBtag cget\fR \fItagName option\fR

This command returns the current value of the option named \fIoption\fR
associated with the tag given by \fItagName\fR.
\fIOption\fR may have any of the values accepted by the \fIpathName \fBtag
configure\fR widget command.
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?

This command is similar to the \fIpathName \fBconfigure\fR widget command except
that it modifies options associated with the tag given by \fItagName\fR
instead of modifying options for the overall text widget.
If no \fIoption\fR is specified, the command returns a list describing
all of the available options for \fItagName\fR (see \fBTk_ConfigureInfo\fR
for information on the format of this list).
If \fIoption\fR is specified with no \fIvalue\fR, then the command returns
a list describing the one named option (this list will be identical to
the corresponding sublist of the value returned if no \fIoption\fR
is specified).
If one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s) in \fItagName\fR;
in this case the command returns an empty string.
See \fBTAGS\fR above for details on the options available for tags.
.TP
\fIpathName \fBtag delete \fItagName \fR?\fItagName ...\fR?

Deletes all tag information for each of the \fItagName\fR
arguments.
The command removes the tags from all characters in the file
and also deletes any other information associated with the tags,
such as bindings and display information.
The command returns an empty string.
.TP
\fIpathName\fB tag lower \fItagName \fR?\fIbelowThis\fR?

Changes the priority of tag \fItagName\fR so that it is just lower
in priority than the tag whose name is \fIbelowThis\fR.
If \fIbelowThis\fR is omitted, then \fItagName\fR's priority
is changed to make it lowest priority of all tags.

.TP
\fIpathName \fBtag names \fR?\fIindex\fR?

Returns a list whose elements are the names of all the tags that
are active at the character position given by \fIindex\fR.
If \fIindex\fR is omitted, then the return value will describe
all of the tags that exist for the text (this includes all tags
that have been named in a
.QW "\fIpathName \fBtag\fR"
widget command but have not been deleted by a
.QW "\fIpathName \fBtag delete\fR"
widget command, even if no characters are currently marked with the tag).
The list will be sorted in order from lowest priority to highest
priority.
.TP
\fIpathName \fBtag nextrange \fItagName index1 \fR?\fIindex2\fR?

This command searches the text for a range of characters tagged
with \fItagName\fR where the first character of the range is
no earlier than the character at \fIindex1\fR and no later than
the character just before \fIindex2\fR (a range starting at
\fIindex2\fR will not be considered).
If several matching ranges exist, the first one is chosen.
The command's return value is a list containing
two elements, which are the index of the first character of the
range and the index of the character just after the last one in
the range.
If no matching range is found then the return value is an
empty string.
If \fIindex2\fR is not given then it defaults to the end of the text.
.TP
\fIpathName \fBtag prevrange \fItagName index1 \fR?\fIindex2\fR?

This command searches the text for a range of characters tagged
with \fItagName\fR where the first character of the range is
before the character at \fIindex1\fR and no earlier than
the character at \fIindex2\fR (a range starting at
\fIindex2\fR will be considered).
If several matching ranges exist, the one closest to \fIindex1\fR is chosen.
The command's return value is a list containing
two elements, which are the index of the first character of the
range and the index of the character just after the last one in
the range.
If no matching range is found then the return value is an
empty string.
If \fIindex2\fR is not given then it defaults to the beginning of the text.
.TP
\fIpathName\fB tag raise \fItagName \fR?\fIaboveThis\fR?

Changes the priority of tag \fItagName\fR so that it is just higher
in priority than the tag whose name is \fIaboveThis\fR.
If \fIaboveThis\fR is omitted, then \fItagName\fR's priority
is changed to make it highest priority of all tags.
.TP
\fIpathName \fBtag ranges \fItagName\fR

Returns a list describing all of the ranges of text that have been
tagged with \fItagName\fR.
The first two elements of the list describe the first tagged range
in the text, the next two elements describe the second range, and
so on.
The first element of each pair contains the index of the first
character of the range, and the second element of the pair contains
the index of the character just after the last one in the
range.
If there are no characters tagged with \fItag\fR then an
empty string is returned.
.TP
\fIpathName \fBtag remove \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?

Remove the tag \fItagName\fR from all of the characters starting
at \fIindex1\fR and ending just before
\fIindex2\fR (the character at \fIindex2\fR is not affected).
A single command may contain any number of \fIindex1\fR\-\fIindex2\fR
pairs.
If the last \fIindex2\fR is omitted then the tag is removed from the
single character at \fIindex1\fR.
If there are no characters in the specified range (e.g. \fIindex1\fR
is past the end of the file or \fIindex2\fR is less than or equal
to \fIindex1\fR) then the command has no effect.
This command returns an empty string.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg arg ...\fR?

This command is used to manipulate embedded windows.
The behavior of the command depends on the \fIoption\fR argument
that follows the \fBwindow\fR argument.
The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBwindow cget\fR \fIindex option\fR

Returns the value of a configuration option for an embedded window.
\fIIndex\fR identifies the embedded window, and \fIoption\fR
specifies a particular configuration option, which must be one of
the ones listed in the section \fBEMBEDDED WINDOWS\fR.
.TP
\fIpathName \fBwindow configure \fIindex\fR ?\fIoption value ...\fR?

Query or modify the configuration options for an embedded window.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the embedded window at \fIindex\fR
(see \fBTk_ConfigureInfo\fR for information on the format of this list).
If \fIoption\fR is specified with no \fIvalue\fR, then the command
returns a list describing the one named option (this list will be
identical to the corresponding sublist of the value returned if no
\fIoption\fR is specified).
If one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
See \fBEMBEDDED WINDOWS\fR for information on the options that
are supported.
.TP
\fIpathName \fBwindow create \fIindex\fR ?\fIoption value ...\fR?

This command creates a new window annotation, which will appear
in the text at the position given by \fIindex\fR.
Any number of \fIoption\-value\fR pairs may be specified to
configure the annotation.
See \fBEMBEDDED WINDOWS\fR for information on the options that
are supported.
Returns an empty string.
.TP
\fIpathName \fBwindow names\fR

Returns a list whose elements are the names of all windows currently
embedded in \fIwindow\fR.
.RE
.TP
\fIpathName \fBxview \fIoption args\fR

This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the portion of the document's horizontal span that is visible in
the window.
For example, if the first element is .2 and the second element is .6,
20% of the text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
The fractions refer only to the lines that are actually visible in the
window:  if the lines in the window are all very short, so that they
are entirely visible, the returned fractions will be 0 and 1,
even if there are other lines in the text that are
much wider than the window.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that \fIfraction\fR of the horizontal
span of the text is off-screen to the left.
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fIWhat\fR must be \fBunits\fR, \fBpages\fR or \fBpixels\fR.
.VS 8.5
If \fIwhat\fR is \fBunits\fR or \fBpages\fR then \fInumber\fR must be an
integer, otherwise number may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded
to the nearest integer value.  If no units are given, pixels are

assumed).  If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display; if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls; if it is
\fBpixels\fR then the view adjusts by \fInumber\fR pixels.  If
.VE 8.5
\fInumber\fR is negative then characters farther to the left become
visible; if it is positive then characters farther to the right become
visible.
.RE
.TP
\fIpathName \fByview \fI?args\fR?

This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR

Returns a list containing two elements, both of which are real fractions
between 0 and 1.
The first element gives the position of the first visible pixel of the
first character (or image, etc) in the
top line in the window, relative to the text as a whole (0.5 means
it is halfway through the text, for example).
The second element gives the position of the first pixel just after the
last visible one in the bottom line of the window,
relative to the text as a whole.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview moveto\fI fraction\fR

Adjusts the view in the window so that the pixel given by \fIfraction\fR
appears at the top of the top line of the window.
\fIFraction\fR is a fraction between 0 and 1;  0 indicates the first
pixel of the first character in the text, 0.33 indicates the pixel that is
one-third the way through the text; and so on.
.VS 8.5
Values close to 1 will
indicate values close to the last pixel in the text (1 actually refers
to one pixel beyond the last pixel), but in such cases the widget will
never scroll beyond the last pixel, and so a value of 1 will effectively
be rounded back to whatever fraction ensures the last pixel is at the
bottom of the window, and some other pixel is at the top.
.VE 8.5
.TP
\fIpathName \fByview scroll \fInumber what\fR

This command adjust the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fIWhat\fR must be \fBunits\fR, \fBpages\fR or \fBpixels\fR.
.VS 8.5
If \fIwhat\fR is \fBunits\fR or \fBpages\fR then \fInumber\fR must be an
integer, otherwise number may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded
to the nearest integer value.  If no units are given, pixels are
assumed).  If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR lines on the display; if it is \fBpages\fR then the view
adjusts by \fInumber\fR screenfuls; if it is \fBpixels\fR then the view
adjusts by \fInumber\fR pixels.
.VE 8.5
If \fInumber\fR is negative then earlier positions in the text
become visible;  if it is positive then later positions in the text
become visible.
.TP
\fIpathName \fByview \fR?\fB\-pickplace\fR? \fIindex\fR

Changes the view in the widget's window to make \fIindex\fR visible.
If the \fB\-pickplace\fR option is not specified then \fIindex\fR will
appear at the top of the window.
If \fB\-pickplace\fR is specified then the widget chooses where
\fIindex\fR appears in the window:
.RS
.IP [1]
If \fIindex\fR is already visible somewhere in the window then the
command does nothing.
.IP [2]
If \fIindex\fR is only a few lines off-screen above the window then
it will be positioned at the top of the window.
.IP [3]
If \fIindex\fR is only a few lines off-screen below the window then
it will be positioned at the bottom of the window.
.IP [4]
Otherwise, \fIindex\fR will be centered in the window.
.LP
The \fB\-pickplace\fR option has been obsoleted by the \fIpathName \fBsee\fR widget
command (\fIpathName \fBsee\fR handles both x- and y-motion to make a location
visible, whereas the \fB\-pickplace\fR mode only handles motion in y).

.RE
.TP
\fIpathName \fByview \fInumber\fR

This command makes the first character on the line after
the one given by \fInumber\fR visible at the top of the window.
\fINumber\fR must be an integer.
This command used to be used for scrolling, but now it is obsolete.
.RE
.SH BINDINGS
.PP
Tk automatically creates class bindings for texts that give them
the following default behavior.
In the descriptions below,
.QW word
is dependent on the value of
the \fBtcl_wordchars\fR variable.  See \fBtclvars\fR(n).
.IP [1]
Clicking mouse button 1 positions the insertion cursor
just before the character underneath the mouse cursor, sets the
input focus to this widget, and clears any selection in the widget.
Dragging with mouse button 1 strokes out a selection between
the insertion cursor and the character under the mouse.

.IP [2]
Double-clicking with mouse button 1 selects the word under the mouse
and positions the insertion cursor at the start of the word.
Dragging after a double click will stroke out a selection consisting
of whole words.
.IP [3]
Triple-clicking with mouse button 1 selects the line under the mouse
and positions the insertion cursor at the start of the line.
Dragging after a triple click will stroke out a selection consisting
of whole lines.
.IP [4]
The ends of the selection can be adjusted by dragging with mouse
button 1 while the Shift key is down;  this will adjust the end
of the selection that was nearest to the mouse cursor when button
1 was pressed.
If the button is double-clicked before dragging then the selection
will be adjusted in units of whole words;  if it is triple-clicked
then the selection will be adjusted in units of whole lines.
.IP [5]
Clicking mouse button 1 with the Control key down will reposition the
insertion cursor without affecting the selection.
.IP [6]
If any normal printing characters are typed, they are
inserted at the point of the insertion cursor.
.IP [7]
The view in the widget can be adjusted by dragging with mouse button 2.

If mouse button 2 is clicked without moving the mouse, the selection
is copied into the text at the position of the mouse cursor.
The Insert key also inserts the selection, but at the position of
the insertion cursor.
.IP [8]
If the mouse is dragged out of the widget
while button 1 is pressed, the entry will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP [9]
The Left and Right keys move the insertion cursor one character to the
left or right;  they also clear any selection in the text.
If Left or Right is typed with the Shift key down, then the insertion
cursor moves and the selection is extended to include the new character.
Control-Left and Control-Right move the insertion cursor by words, and
Control-Shift-Left and Control-Shift-Right move the insertion cursor
by words and also extend the selection.
Control-b and Control-f behave the same as Left and Right, respectively.
Meta-b and Meta-f behave the same as Control-Left and Control-Right,
respectively.
.IP [10]
The Up and Down keys move the insertion cursor one line up or
down and clear any selection in the text.
If Up or Right is typed with the Shift key down, then the insertion
cursor moves and the selection is extended to include the new character.
Control-Up and Control-Down move the insertion cursor by paragraphs (groups
of lines separated by blank lines), and
Control-Shift-Up and Control-Shift-Down move the insertion cursor
by paragraphs and also extend the selection.
Control-p and Control-n behave the same as Up and Down, respectively.

.IP [11]
The Next and Prior keys move the insertion cursor forward or backwards
by one screenful and clear any selection in the text.
If the Shift key is held down while Next or Prior is typed, then
the selection is extended to include the new character.
.IP [12]
Control-Next and Control-Prior scroll the view right or left by one page
without moving the insertion cursor or affecting the selection.
.IP [13]
Home and Control-a move the insertion cursor to the
beginning of its display line and clear any selection in the widget.
Shift-Home moves the insertion cursor to the beginning of the display line
and also extends the selection to that point.
.IP [14]
End and Control-e move the insertion cursor to the
end of the display line and clear any selection in the widget.
Shift-End moves the cursor to the end of the display line and extends
the selection to that point.
.IP [15]
Control-Home and Meta-< move the insertion cursor to the beginning of
the text and clear any selection in the widget.
Control-Shift-Home moves the insertion cursor to the beginning of the text
and also extends the selection to that point.
.IP [16]
Control-End and Meta-> move the insertion cursor to the end of the
text and clear any selection in the widget.
Control-Shift-End moves the cursor to the end of the text and extends
the selection to that point.
.IP [17]
The Select key and Control-Space set the selection anchor to the position
of the insertion cursor.  They do not affect the current selection.
Shift-Select and Control-Shift-Space adjust the selection to the
current position of the insertion cursor, selecting from the anchor
to the insertion cursor if there was not any selection previously.
.IP [18]
Control-/ selects the entire contents of the widget.
.IP [19]
Control-\e clears any selection in the widget.
.IP [20]
The F16 key (labelled Copy on many Sun workstations) or Meta-w
copies the selection in the widget to the clipboard, if there is a selection.
This action is carried out by the command \fBtk_textCopy\fR.
.IP [21]
The F20 key (labelled Cut on many Sun workstations) or Control-w
copies the selection in the widget to the clipboard and deletes
the selection.
This action is carried out by the command \fBtk_textCut\fR.
If there is no selection in the widget then these keys have no effect.
.IP [22]
The F18 key (labelled Paste on many Sun workstations) or Control-y
inserts the contents of the clipboard at the position of the
insertion cursor.
This action is carried out by the command \fBtk_textPaste\fR.
.IP [23]
The Delete key deletes the selection, if there is one in the widget.
If there is no selection, it deletes the character to the right of
the insertion cursor.
.IP [24]
Backspace and Control-h delete the selection, if there is one
in the widget.
If there is no selection, they delete the character to the left of
the insertion cursor.
.IP [25]
Control-d deletes the character to the right of the insertion cursor.
.IP [26]
Meta-d deletes the word to the right of the insertion cursor.
.IP [27]
Control-k deletes from the insertion cursor to the end of its line;
if the insertion cursor is already at the end of a line, then
Control-k deletes the newline character.
.IP [28]
Control-o opens a new line by inserting a newline character in
front of the insertion cursor without moving the insertion cursor.
.IP [29]
Meta-backspace and Meta-Delete delete the word to the left of the
insertion cursor.
.IP [30]
Control-x deletes whatever is selected in the text widget
after copying it to the clipboard.
.IP [31]
Control-t reverses the order of the two characters to the right of
the insertion cursor.



.IP [32]
Control-z (undoes the last edit action if the \fB\-undo\fR option is
true. Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit
action if the \fB\-undo\fR option is true. Does nothing otherwise.
.PP
If the widget is disabled using the \fB\-state\fR option, then its
view can still be adjusted and text can still be selected,
but no insertion cursor will be displayed and no text modifications will
take place.
.PP
The behavior of texts can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "KNOWN ISSUES"
.SS "ISSUES CONCERNING CHARS AND INDICES"
.VS 8.5
.PP
Before Tk 8.5, the widget used the string
.QW chars
to refer to index positions (which included characters, embedded
windows and embedded images).  As of Tk 8.5 the text widget deals
separately and correctly with
.QW chars
and
.QW indices .
For backwards compatibility, however, the index modifiers
.QW "+N chars"
and
.QW "\-N chars"
continue to refer to indices.
One must use any of the full forms
.QW "+N any chars"
or
.QW "\-N any chars"
etc. to refer to actual character indices.  This confusion may be fixed in a
future release by making the widget correctly interpret
.QW "+N chars"
as a synonym for
.QW "+N any chars" .
.VE 8.5
.SS "PERFORMANCE ISSUES"
.PP
Text widgets should run efficiently under a variety
of conditions.  The text widget uses about 2-3 bytes of
main memory for each byte of text, so texts containing a megabyte
or more should be practical on most workstations.
Text is represented internally with a modified B-tree structure
that makes operations relatively efficient even with large texts.
Tags are included in the B-tree structure in a way that allows
tags to span large ranges or have many disjoint smaller ranges
without loss of efficiency.
Marks are also implemented in a way that allows large numbers of
marks.
In most cases it is fine to have large numbers of unique tags,
or a tag that has many distinct ranges.
.PP
One performance problem can arise if you have hundreds or thousands
of different tags that all have the following characteristics:
the first and last ranges of each tag are near the beginning and
end of the text, respectively,
or a single tag range covers most of the text widget.
The cost of adding and deleting tags like this is proportional
to the number of other tags with the same properties.
In contrast, there is no problem with having thousands of distinct
tags if their overall ranges are localized and spread uniformly throughout
the text.
.PP
Very long text lines can be expensive,
especially if they have many marks and tags within them.
.PP
The display line with the insert cursor is redrawn each time the
cursor blinks, which causes a steady stream of graphics traffic.
Set the \fBinsertOffTime\fR attribute to 0 avoid this.
.SS "KNOWN BUGS"
.VS 8.5
.PP
The \fIpathName \fBsearch \-regexp\fR sub-command attempts to perform sophisticated
regexp matching across multiple lines in an efficient fashion (since Tk
8.5), examining each line individually, and then in small groups of lines,
whether searching forwards or backwards.  Under certain conditions the
search result might differ from that obtained by applying the same regexp
to the entire text from the widget in one go.  For example, when
searching with a greedy regexp, the widget will continue to attempt to
add extra lines to the match as long as one of two conditions are true:
either Tcl's regexp library returns a code to indicate a longer match is
possible (but there are known bugs in Tcl which mean this code is not
always correctly returned); or if each extra line added results in at
least a partial match with the pattern.  This means in the case where the
first extra line added results in no match and Tcl's regexp system
returns the incorrect code and adding a second extra line would actually
match, the text widget will return the wrong result.  In practice this is
a rare problem, but it can occur, for example:
.CS
pack [text .t]
\&.t insert 1.0 "aaaa\enbbbb\encccc\enbbbb\enaaaa\en"
\&.t search \-regexp \-\- {(a+|b+\enc+\enb+)+\ena+} 1.0
.CE
will not find a match when one exists of 19
characters starting from the first
.QW b .
.PP
Whenever one possible match is fully enclosed in another, the search
command will attempt to ensure only the larger match is returned.
When performing backwards regexp searches it is possible that Tcl
will not always achieve this, in the case where a match is preceded by
one or more short, non-overlapping matches, all of which are preceded
by a large match which actually encompasses all of them.  The search
algorithm used by the widget does not look back arbitrarily far for a
possible match which might cover large portions of the widget.
For example:
.CS
pack [text .t]
\&.t insert 1.0 "aaaa\enbbbb\enbbbb\enbbbb\enbbbb\\n"
\&.t search \-regexp \-backward \-\- {b+\en|a+\en(b+\en)+} end
.CE
matches at
.QW 5.0
when a true greedy match would match at
.QW 1.0 .
Similarly if we add \fB\-all\fR to this case, it matches at all of
.QW 5.0 ,
.QW 4.0 ,
.QW 3.0
and
.QW 1.0 ,
when really it should only match at
.QW 1.0
since that match encloses all the others.
.VE 8.5
.SH "SEE ALSO"
entry(n), scrollbar(n)
.SH KEYWORDS
text, widget, tkvars



Changes to doc/tk.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tk n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk \- Manipulate Tk internal state
.SH SYNOPSIS
\fBtk\fR \fIoption \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBtk\fR command provides access to miscellaneous
elements of Tk's internal state.
Most of the information manipulated by this command pertains to the
application as a whole, or to a screen or display, rather than to a
particular window.






|







|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tk n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk \- Manipulate Tk internal state
.SH SYNOPSIS
\fBtk\fR \fIoption \fR?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBtk\fR command provides access to miscellaneous
elements of Tk's internal state.
Most of the information manipulated by this command pertains to the
application as a whole, or to a screen or display, rather than to a
particular window.
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112


















113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
This will interfere with option processing, since names starting with
capitals are assumed to be classes;  as a result, Tk may not
be able to find some options for the application.
If sends have been disabled by deleting the \fBsend\fR command,
this command will reenable them and recreate the \fBsend\fR
command.
.TP
\fBtk busy \fIsubcommand\fR ...
.
This command controls the marking of window hierarchies as
.QW busy ,
rendering them non-interactive while some other operation is proceeding. For
more details see the \fBbusy\fR manual page.
.TP
\fBtk caret \fIwindow \fR?\fB\-x \fIx\fR? ?\fB\-y \fIy\fR? ?\fB\-height \fIheight\fR?
.
Sets and queries the caret location for the display of the specified
Tk window \fIwindow\fR.  The caret is the per-display cursor location
used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot
XIM (X Input Methods) or Windows IME windows.  If no options are specified,
the last values used for setting the caret are return in option-value pair
format.  \fB\-x\fR and \fB\-y\fR represent window-relative coordinates, and
\fB\-height\fR is the height of the current cursor location, or the height
of the specified \fIwindow\fR if none is given.
.TP
\fBtk inactive \fR?\fB\-displayof \fIwindow\fR? ?\fBreset\fR?
.
Returns a positive integer, the number of milliseconds since the last
time the user interacted with the system. If the \fB\-displayof\fR
option is given then the return value refers to the display of
\fIwindow\fR; otherwise it refers to the display of the application's
main window.
.RS
.PP
\fBtk inactive\fR will return \-1, if querying the user inactive time
is not supported by the system, and in safe interpreters.
.PP
If the literal string \fBreset\fR is given as an additional argument,
the timer is reset and an empty string is returned. Resetting the
inactivity time is forbidden in safe interpreters and will throw an
error if tried.
.RE
.TP
\fBtk fontchooser \fIsubcommand\fR ...
Controls the Tk font selection dialog. For more details see the
\fBfontchooser\fR manual page.
.TP
\fBtk scaling \fR?\fB\-displayof \fIwindow\fR? ?\fInumber\fR?
.
Sets and queries the current scaling factor used by Tk to convert between
physical units (for example, points, inches, or millimeters) and pixels.  The
\fInumber\fR argument is a floating point number that specifies the number of
pixels per point on \fIwindow\fR's display.  If the \fIwindow\fR argument is
omitted, it defaults to the main window.  If the \fInumber\fR argument is
omitted, the current value of the scaling factor is returned.
.RS
.PP
A
.QW point
is a unit of measurement equal to 1/72 inch.  A scaling factor
of 1.0 corresponds to 1 pixel per point, which is equivalent to a standard
72 dpi monitor.  A scaling factor of 1.25 would mean 1.25 pixels per point,
which is the setting for a 90 dpi monitor; setting the scaling factor to
1.25 on a 72 dpi monitor would cause everything in the application to be
displayed 1.25 times as large as normal.  The initial value for the scaling
factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE


















.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.
.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (Mac OS X Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), send(n), winfo(n)
.SH KEYWORDS
application name, send
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
<
<
<
<
|







|
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















|


<
<
<
42
43
44
45
46
47
48







49
50
51
52
53
54
55
56
57
58
59
60






















61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122



This will interfere with option processing, since names starting with
capitals are assumed to be classes;  as a result, Tk may not
be able to find some options for the application.
If sends have been disabled by deleting the \fBsend\fR command,
this command will reenable them and recreate the \fBsend\fR
command.
.TP







\fBtk caret window \fR?\fB\-x \fIx\fR? ?\fB\-y \fIy\fR? ?\fB\-height \fIheight\fR?
.
Sets and queries the caret location for the display of the specified
Tk window \fIwindow\fR.  The caret is the per-display cursor location
used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot
XIM (X Input Methods) or Windows IME windows.  If no options are specified,
the last values used for setting the caret are return in option-value pair
format.  \fI\-x\fR and \fI\-y\fR represent window-relative coordinates, and
\fI\-height\fR is the height of the current cursor location, or the height
of the specified \fIwindow\fR if none is given.
.TP






















\fBtk scaling \fR?\fB\-displayof \fIwindow\fR? ?\fInumber\fR?
.
Sets and queries the current scaling factor used by Tk to convert between
physical units (for example, points, inches, or millimeters) and pixels.  The
\fInumber\fR argument is a floating point number that specifies the number of
pixels per point on \fIwindow\fR's display.  If the \fIwindow\fR argument is
omitted, it defaults to the main window.  If the \fInumber\fR argument is 
omitted, the current value of the scaling factor is returned.
.RS
.PP
A
.QW point
is a unit of measurement equal to 1/72 inch.  A scaling factor
of 1.0 corresponds to 1 pixel per point, which is equivalent to a standard
72 dpi monitor.  A scaling factor of 1.25 would mean 1.25 pixels per point,
which is the setting for a 90 dpi monitor; setting the scaling factor to
1.25 on a 72 dpi monitor would cause everything in the application to be
displayed 1.25 times as large as normal.  The initial value for the scaling
factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE
.TP
\fBtk inactive \fR?\fB\-displayof \fIwindow\fR? ?\fBreset\fR?
.
Returns a positive integer, the number of milliseconds since the last
time the user interacted with the system. If the \fB\-displayof\fR
option is given then the return value refers to the display of
\fIwindow\fR; otherwise it refers to the display of the application's
main window.
.RS
.PP
\fBtk inactive\fR will return \-1, if querying the user inactive time
is not supported by the system, and in safe interpreters.
.PP
If the literal string \fBreset\fR is given as an additional argument,
the timer is reset and an empty string is returned. Resetting the
inactivity time is forbidden in safe interpreters and will throw and
error if tried.
.RE
.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.
.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (Mac OS X Aqua).
.SH "SEE ALSO"
send(n), winfo(n)
.SH KEYWORDS
application name, send



Changes to doc/tk4.0.ps.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% FrameMaker.
% NOTE
% This file fixes the problem with NeWS printers dithering color output.
% Any questions should be sent to mickey@magickingdom.eng.sun.com
%
% Known Problems:
%	Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
/FMversion (3.0) def
% Set up Color vs. Black-and-White

/FMPrintInColor { % once-thru loop gimmick
    % See if we're a NeWSprint printer
     /currentcanvas where {
        pop systemdict /separationdict known
	exit







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% FrameMaker.
% NOTE
% This file fixes the problem with NeWS printers dithering color output.
% Any questions should be sent to mickey@magickingdom.eng.sun.com
%
% Known Problems:
%	Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
/FMversion (3.0) def 
% Set up Color vs. Black-and-White

/FMPrintInColor { % once-thru loop gimmick
    % See if we're a NeWSprint printer
     /currentcanvas where {
        pop systemdict /separationdict known
	exit
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
%    } if
    systemdict /colorimage known
    systemdict /currentcolortransfer known and
exit } loop def

% Uncomment the following line to force b&w on color printer
%   /FMPrintInColor false def
/FrameDict 195 dict def
systemdict /errordict known not {/errordict 10 dict def
		errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put
errordict /rangecheck {FrameDict /bug true put} put
FrameDict /bug false put
mark
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark
errordict /rangecheck FrameDict /tmprangecheck get put
FrameDict /bug get {
	/readline {
		/gstring exch def
		/gfile exch def
		/gindex 0 def
		{
			gfile read pop
			dup 10 eq {exit} if
			dup 13 eq {exit} if
			gstring exch gindex exch put
			/gindex gindex 1 add def
		} loop
		pop
		gstring 0 gindex getinterval true
		} def
	} if
/FMVERSION {
	FMversion ne {
		/Times-Roman findfont 18 scalefont setfont
		100 100 moveto
		(FrameMaker version does not match postscript_prolog!)
		dup =
		show showpage
		} if
	} def
/FMLOCAL {
	FrameDict begin
	0 def
	end
	} def
	/gstring FMLOCAL
	/gfile FMLOCAL
	/gindex FMLOCAL
	/orgxfer FMLOCAL
	/orgproc FMLOCAL
	/organgle FMLOCAL
	/orgfreq FMLOCAL
	/yscale FMLOCAL
	/xscale FMLOCAL
	/manualfeed FMLOCAL
	/paperheight FMLOCAL
	/paperwidth FMLOCAL
/FMDOCUMENT {
	array /FMfonts exch def
	/#copies exch def
	FrameDict begin
	0 ne dup {setmanualfeed} if
	/manualfeed exch def
	/paperheight exch def
	/paperwidth exch def
	/yscale exch def
	/xscale exch def
	currenttransfer cvlit /orgxfer exch def
	currentscreen cvlit /orgproc exch def
	/organgle exch def /orgfreq exch def
	setpapername
	manualfeed {true} {papersize} ifelse
	{manualpapersize} {false} ifelse
	{desperatepapersize} if
	end
	} def
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE {
	FrameDict begin
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape {
		90 rotate 0 exch neg translate pop
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave
	} def
/FMENDPAGE {
	grestore
	pagesave restore
	end
	showpage
	} def
/FMFONTDEFINE {
	FrameDict begin
	findfont
	ReEncode
	1 index exch
	definefont
	FMfonts 3 1 roll
	put
	end
	} def
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end
	} def
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end
	} def
/FMNORMALIZEGRAPHICS {
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray
	} bind def
	/fx FMLOCAL
	/fy FMLOCAL
	/fh FMLOCAL
	/fw FMLOCAL
	/llx FMLOCAL
	/lly FMLOCAL
	/urx FMLOCAL
	/ury FMLOCAL
/FMBEGINEPSF {
	end
	/FMEPSF save def
	/showpage {} def
	FMNORMALIZEGRAPHICS
	[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall
	fx fy translate
	rotate
	fw urx llx sub div fh ury lly sub div scale
	llx neg lly neg translate
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin
	} bind def
FrameDict begin
/setmanualfeed {
%%BeginFeature *ManualFeed True
	 statusdict /manualfeed true put
%%EndFeature
	} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen {
	paperheight sub abs 16 lt exch
	paperwidth sub abs 16 lt and
	{/papername exch def} {pop} ifelse
	} def
	/papersizedict FMLOCAL
/setpapername {
	/papersizedict 14 dict def
	papersizedict begin
	/papername /unknown def
		/Letter 8.5 inch 11.0 inch pagedimen
		/LetterSmall 7.68 inch 10.16 inch pagedimen
		/Tabloid 11.0 inch 17.0 inch pagedimen
		/Ledger 17.0 inch 11.0 inch pagedimen
		/Legal 8.5 inch 14.0 inch pagedimen
		/Statement 5.5 inch 8.5 inch pagedimen
		/Executive 7.5 inch 10.0 inch pagedimen







|



|
|
|
|




|
|
|





|
|
|
|
|

|
|










|


|
|
|












|
|











|
|
|

|
|



|
|



|
|





|
|

|

|

|
|

|
|
|
|
|

|
|



|
|



|
|
|





|









|
|
|
|
|
|
|

|
|



|

|








|
|




|
|

|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
%    } if
    systemdict /colorimage known
    systemdict /currentcolortransfer known and
exit } loop def

% Uncomment the following line to force b&w on color printer
%   /FMPrintInColor false def
/FrameDict 195 dict def 
systemdict /errordict known not {/errordict 10 dict def
		errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put 
errordict /rangecheck {FrameDict /bug true put} put 
FrameDict /bug false put 
mark 
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark 
errordict /rangecheck FrameDict /tmprangecheck get put 
FrameDict /bug get { 
	/readline {
		/gstring exch def
		/gfile exch def
		/gindex 0 def
		{
			gfile read pop 
			dup 10 eq {exit} if 
			dup 13 eq {exit} if 
			gstring exch gindex exch put 
			/gindex gindex 1 add def 
		} loop
		pop 
		gstring 0 gindex getinterval true 
		} def
	} if
/FMVERSION {
	FMversion ne {
		/Times-Roman findfont 18 scalefont setfont
		100 100 moveto
		(FrameMaker version does not match postscript_prolog!)
		dup =
		show showpage
		} if
	} def 
/FMLOCAL {
	FrameDict begin
	0 def 
	end 
	} def 
	/gstring FMLOCAL
	/gfile FMLOCAL
	/gindex FMLOCAL
	/orgxfer FMLOCAL
	/orgproc FMLOCAL
	/organgle FMLOCAL
	/orgfreq FMLOCAL
	/yscale FMLOCAL
	/xscale FMLOCAL
	/manualfeed FMLOCAL
	/paperheight FMLOCAL
	/paperwidth FMLOCAL
/FMDOCUMENT { 
	array /FMfonts exch def 
	/#copies exch def
	FrameDict begin
	0 ne dup {setmanualfeed} if
	/manualfeed exch def
	/paperheight exch def
	/paperwidth exch def
	/yscale exch def
	/xscale exch def
	currenttransfer cvlit /orgxfer exch def
	currentscreen cvlit /orgproc exch def
	/organgle exch def /orgfreq exch def
	setpapername 
	manualfeed {true} {papersize} ifelse 
	{manualpapersize} {false} ifelse 
	{desperatepapersize} if
	end 
	} def 
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE { 
	FrameDict begin 
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape { 
		90 rotate 0 exch neg translate pop 
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave 
	} def 
/FMENDPAGE {
	grestore 
	pagesave restore
	end 
	showpage
	} def 
/FMFONTDEFINE { 
	FrameDict begin
	findfont 
	ReEncode 
	1 index exch 
	definefont 
	FMfonts 3 1 roll 
	put
	end 
	} def 
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end 
	} def 
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end 
	} def 
/FMNORMALIZEGRAPHICS { 
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray 
	} bind def
	/fx FMLOCAL
	/fy FMLOCAL
	/fh FMLOCAL
	/fw FMLOCAL
	/llx FMLOCAL
	/lly FMLOCAL
	/urx FMLOCAL
	/ury FMLOCAL
/FMBEGINEPSF { 
	end 
	/FMEPSF save def 
	/showpage {} def 
	FMNORMALIZEGRAPHICS 
	[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall 
	fx fy translate 
	rotate
	fw urx llx sub div fh ury lly sub div scale 
	llx neg lly neg translate 
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin 
	} bind def
FrameDict begin 
/setmanualfeed {
%%BeginFeature *ManualFeed True
	 statusdict /manualfeed true put
%%EndFeature
	} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen { 
	paperheight sub abs 16 lt exch 
	paperwidth sub abs 16 lt and
	{/papername exch def} {pop} ifelse
	} def
	/papersizedict FMLOCAL
/setpapername { 
	/papersizedict 14 dict def 
	papersizedict begin
	/papername /unknown def 
		/Letter 8.5 inch 11.0 inch pagedimen
		/LetterSmall 7.68 inch 10.16 inch pagedimen
		/Tabloid 11.0 inch 17.0 inch pagedimen
		/Ledger 17.0 inch 11.0 inch pagedimen
		/Legal 8.5 inch 14.0 inch pagedimen
		/Statement 5.5 inch 8.5 inch pagedimen
		/Executive 7.5 inch 10.0 inch pagedimen
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		/A4 {a4tray a4} def
		/A4Small {a4tray a4small} def
		/B4 {b4tray b4} def
		/B5 {b5tray b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	/FMdicttop countdictstack 1 add def
	statusdict begin stopped end
	countdictstack -1 FMdicttop {pop end} for
	} def
/manualpapersize {
	papersizedict begin
		/Letter {letter} def
		/LetterSmall {lettersmall} def
		/Tabloid {11x17} def
		/Ledger {ledger} def
		/Legal {legal} def
		/Statement {statement} def
		/Executive {executive} def
		/A3 {a3} def
		/A4 {a4} def
		/A4Small {a4small} def
		/B4 {b4} def
		/B5 {b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	stopped
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1
		statusdict begin
		{setpageparams} stopped pop
		end
		} if
	} def
/savematrix {
	orgmatrix currentmatrix pop
	} bind def
/restorematrix {







|
|
|


















|




|

|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		/A4 {a4tray a4} def
		/A4Small {a4tray a4small} def
		/B4 {b4tray b4} def
		/B5 {b5tray b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	/FMdicttop countdictstack 1 add def 
	statusdict begin stopped end 
	countdictstack -1 FMdicttop {pop end} for 
	} def
/manualpapersize {
	papersizedict begin
		/Letter {letter} def
		/LetterSmall {lettersmall} def
		/Tabloid {11x17} def
		/Ledger {ledger} def
		/Legal {legal} def
		/Statement {statement} def
		/Executive {executive} def
		/A3 {a3} def
		/A4 {a4} def
		/A4Small {a4small} def
		/B4 {b4} def
		/B5 {b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	stopped 
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1 
		statusdict begin
		{setpageparams} stopped pop 
		end
		} if
	} def
/savematrix {
	orgmatrix currentmatrix pop
	} bind def
/restorematrix {
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode {
	dup
	length
	dict begin
	{
	1 index /FID ne
		{def}
		{pop pop} ifelse
	} forall
	0 eq {/Encoding DiacriticEncoding def} if
	currentdict
	end
	} bind def
/graymode true def
	/bwidth FMLOCAL
	/bpside FMLOCAL
	/bstring FMLOCAL
	/onbits FMLOCAL
	/offbits FMLOCAL
	/xindex FMLOCAL
	/yindex FMLOCAL
	/x FMLOCAL
	/y FMLOCAL
/setpattern {
	 /bwidth  exch def
	 /bpside  exch def
	 /bstring exch def
	 /onbits 0 def  /offbits 0 def
	 freq sangle landscape {90 add} if
		{/y exch def
		 /x exch def
		 /xindex x 1 add 2 div bpside mul cvi def
		 /yindex y 1 add 2 div bpside mul cvi def
		 bstring yindex bwidth mul xindex 8 idiv add get
		 1 7 xindex 8 mod sub bitshift and 0 ne
		 {/onbits  onbits  1 add def 1}







|
|
|
|

|
|
|
|
|
|
|
















|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode { 
	dup 
	length 
	dict begin 
	{
	1 index /FID ne 
		{def} 
		{pop pop} ifelse 
	} forall 
	0 eq {/Encoding DiacriticEncoding def} if 
	currentdict 
	end 
	} bind def
/graymode true def
	/bwidth FMLOCAL
	/bpside FMLOCAL
	/bstring FMLOCAL
	/onbits FMLOCAL
	/offbits FMLOCAL
	/xindex FMLOCAL
	/yindex FMLOCAL
	/x FMLOCAL
	/y FMLOCAL
/setpattern {
	 /bwidth  exch def
	 /bpside  exch def
	 /bstring exch def
	 /onbits 0 def  /offbits 0 def
	 freq sangle landscape {90 add} if 
		{/y exch def
		 /x exch def
		 /xindex x 1 add 2 div bpside mul cvi def
		 /yindex y 1 add 2 div bpside mul cvi def
		 bstring yindex bwidth mul xindex 8 idiv add get
		 1 7 xindex 8 mod sub bitshift and 0 ne
		 {/onbits  onbits  1 add def 1}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		orgfreq organgle orgproc cvx setscreen
		} if
	} bind def
	/HUE FMLOCAL
	/SAT FMLOCAL
	/BRIGHT FMLOCAL
	/Colors FMLOCAL
FMPrintInColor

	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors
	[[0    0  ]    % black
	 [0    0  ]    % white
	 [0.00 1.0]    % red
	 [0.37 1.0]    % green
	 [0.60 1.0]    % blue
	 [0.50 1.0]    % cyan
	 [0.83 1.0]    % magenta
	 [0.16 1.0]    % comment / yellow
	 ] def

	/BEGINBITMAPCOLOR {
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc {
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUECOLORc } def
	/K {
		Colors exch get dup
		0 get /HUE exch store
		1 get /BRIGHT exch store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} def
	/FMsetgray {
		/SAT exch 1.0 exch sub store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} bind def
	}

	{
	/BEGINBITMAPCOLOR {
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc {
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K {
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize {
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H {
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X {
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern}
	{grayness}
	ifelse
	} bind def
/V {
	gsave eofill grestore
	} bind def
/N {
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L {
 	/n exch def
	newpath
	normalize
	moveto
	2 1 n {pop normalize lineto} for
	} bind def
/Y {
	L
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R {
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y
	} bind def
/RR {
	/rad exch def
	normalize
	/y2 exch def
	/x2 exch def
	normalize
	/y1 exch def
	/x1 exch def
	newpath
	x1 y1 rad add moveto
	x1 y2 x2 y2 rad arcto
	x2 y2 x2 y1 rad arcto
	x2 y1 x1 y1 rad arcto
	x1 y1 x1 y2 rad arcto
	closepath
	16 {pop} repeat
	} bind def
/C {
	grestore
	gsave
	R
	clip
	} bind def
	/FMpointsize FMLOCAL
/F {
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q {
	/FMpointsize exch def
	F
	} bind def
/T {
	moveto show
	} bind def
/RF {
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF {
	gsave
	moveto
	RF
	show
	grestore
	} bind def
/P {
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF {
	gsave
	moveto
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S {
	moveto
	0 exch ashow
	} bind def
/SF {
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B {
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF {
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G {
	gsave
	newpath
	normalize translate 0.0 0.0 moveto
	dnormalize scale
	0.0 0.0 1.0 5 3 roll arc
	closepath fill
	grestore
	} bind def
/A {
	gsave
	savematrix
	newpath
	2 index 2 div add exch 3 index 2 div sub exch
	normalize 2 index 2 div sub exch 3 index 2 div add exch
	translate
	scale
	0.0 0.0 1.0 5 3 roll arc
	restorematrix
	stroke
	grestore
	} bind def
	/x FMLOCAL
	/y FMLOCAL
	/w FMLOCAL
	/h FMLOCAL
	/xx FMLOCAL
	/yy FMLOCAL
	/ww FMLOCAL
	/hh FMLOCAL
	/FMsaveobject FMLOCAL
	/FMoptop FMLOCAL
	/FMdicttop FMLOCAL
/BEGINPRINTCODE {
	/FMdicttop countdictstack 1 add def
	/FMoptop count 4 sub def
	/FMsaveobject save def
	userdict begin
	/showpage {} def
	FMNORMALIZEGRAPHICS
	3 index neg 3 index neg translate
	} bind def
/ENDPRINTCODE {
	count -1 FMoptop {pop pop} for
	countdictstack -1 FMdicttop {pop end} for
	FMsaveobject restore
	} bind def
/gn {
	0
	{	46 mul
		cf read pop
		32 sub
		dup 46 lt {exit} if
		46 sub add
		} loop
	add
	} bind def
	/str FMLOCAL
/cfs {
	/str sl string def
	0 1 sl 1 sub {str exch val put} for
	str def
	} bind def
/ic [
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0
	{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
	{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
	{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
	{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}







|
|





|









|
|

|

|

|

|

|



|


|
|


|



|

|

|

|

|


|










|


|






|


|



|


|







|



|


|
|







|








|

|
















|


|



|




|

|

|


|



|

|




|



|

|




|



|






|



|






|


|
|
|



|



|
|
|
|
|















|
|
|

|
|
|



|
|
|

|
|
|
|
|
|
|

|


|
|
|
|

|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		orgfreq organgle orgproc cvx setscreen
		} if
	} bind def
	/HUE FMLOCAL
	/SAT FMLOCAL
	/BRIGHT FMLOCAL
	/Colors FMLOCAL
FMPrintInColor 
	
	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors   
	[[0    0  ]    % black
	 [0    0  ]    % white
	 [0.00 1.0]    % red
	 [0.37 1.0]    % green
	 [0.60 1.0]    % blue
	 [0.50 1.0]    % cyan
	 [0.83 1.0]    % magenta
	 [0.16 1.0]    % comment / yellow
	 ] def
      
	/BEGINBITMAPCOLOR { 
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc { 
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUECOLORc } def
	/K { 
		Colors exch get dup
		0 get /HUE exch store 
		1 get /BRIGHT exch store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} def
	/FMsetgray { 
		/SAT exch 1.0 exch sub store 
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} bind def
	}
	
	{
	/BEGINBITMAPCOLOR { 
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc { 
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K { 
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize { 
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H { 
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X { 
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern} 
	{grayness}
	ifelse
	} bind def
/V { 
	gsave eofill grestore
	} bind def
/N { 
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L { 
 	/n exch def
	newpath
	normalize
	moveto 
	2 1 n {pop normalize lineto} for
	} bind def
/Y { 
	L 
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R { 
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y 
	} bind def
/RR { 
	/rad exch def
	normalize
	/y2 exch def
	/x2 exch def
	normalize
	/y1 exch def
	/x1 exch def
	newpath
	x1 y1 rad add moveto
	x1 y2 x2 y2 rad arcto
	x2 y2 x2 y1 rad arcto
	x2 y1 x1 y1 rad arcto
	x1 y1 x1 y2 rad arcto
	closepath
	16 {pop} repeat
	} bind def
/C { 
	grestore
	gsave
	R 
	clip
	} bind def
	/FMpointsize FMLOCAL
/F { 
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q { 
	/FMpointsize exch def
	F 
	} bind def
/T { 
	moveto show
	} bind def
/RF { 
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF { 
	gsave
	moveto 
	RF
	show
	grestore
	} bind def
/P { 
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF { 
	gsave
	moveto 
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S { 
	moveto
	0 exch ashow
	} bind def
/SF { 
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B { 
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF { 
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G { 
	gsave
	newpath
	normalize translate 0.0 0.0 moveto 
	dnormalize scale 
	0.0 0.0 1.0 5 3 roll arc 
	closepath fill
	grestore
	} bind def
/A { 
	gsave
	savematrix
	newpath
	2 index 2 div add exch 3 index 2 div sub exch 
	normalize 2 index 2 div sub exch 3 index 2 div add exch 
	translate 
	scale 
	0.0 0.0 1.0 5 3 roll arc 
	restorematrix
	stroke
	grestore
	} bind def
	/x FMLOCAL
	/y FMLOCAL
	/w FMLOCAL
	/h FMLOCAL
	/xx FMLOCAL
	/yy FMLOCAL
	/ww FMLOCAL
	/hh FMLOCAL
	/FMsaveobject FMLOCAL
	/FMoptop FMLOCAL
	/FMdicttop FMLOCAL
/BEGINPRINTCODE { 
	/FMdicttop countdictstack 1 add def 
	/FMoptop count 4 sub def 
	/FMsaveobject save def
	userdict begin 
	/showpage {} def 
	FMNORMALIZEGRAPHICS 
	3 index neg 3 index neg translate
	} bind def
/ENDPRINTCODE {
	count -1 FMoptop {pop pop} for 
	countdictstack -1 FMdicttop {pop end} for 
	FMsaveobject restore 
	} bind def
/gn { 
	0 
	{	46 mul 
		cf read pop 
		32 sub 
		dup 46 lt {exit} if 
		46 sub add 
		} loop
	add 
	} bind def
	/str FMLOCAL
/cfs { 
	/str sl string def 
	0 1 sl 1 sub {str exch val put} for 
	str def 
	} bind def
/ic [ 
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0
	{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
	{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
	{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
	{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	/val FMLOCAL
	/ws FMLOCAL
	/im FMLOCAL
	/bs FMLOCAL
	/cs FMLOCAL
	/len FMLOCAL
	/pos FMLOCAL
/ms {
	/sl exch def
	/val 255 def
	/ws cfs
	/im cfs
	/val 0 def
	/bs cfs
	/cs cfs
	} bind def
400 ms
/ip {
	is
	0
	cf cs readline pop
	{	ic exch get exec
		add
		} forall
	pop

	} bind def
/wh {
	/len exch def
	/pos exch def
	ws 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/bl {
	/len exch def
	/pos exch def
	bs 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/s1 1 string def
/fl {
	/len exch def
	/pos exch def
	/val cf s1 readhexstring pop 0 get def
	pos 1 pos len add 1 sub {im exch val put} for
	pos len
	} bind def
/hx {
	3 copy getinterval
	cf exch readhexstring pop pop
	} bind def
	/h FMLOCAL
	/w FMLOCAL
	/d FMLOCAL
	/lb FMLOCAL
	/bitmapsave FMLOCAL
	/is FMLOCAL
	/cf FMLOCAL
/wbytes {
	dup
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc {
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc {
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc {
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	r
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} image
	bitmapsave restore
	grestore
	} bind def
/BEGINBITMAPBW {
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY {
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT {
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	r
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} image
	bitmapsave restore
	grestore
	} bind def
	/proc1 FMLOCAL
	/proc2 FMLOCAL
	/newproc FMLOCAL
/Fmcc {
    /proc2 exch cvlit def







|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|

|

|
|
|

|


|
|
|


|

|
|
|








|
|


|


|


|


|




|
|
|
|
|
|
|
|
|
|


|


|


|


|




|
|

|
|

|







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	/val FMLOCAL
	/ws FMLOCAL
	/im FMLOCAL
	/bs FMLOCAL
	/cs FMLOCAL
	/len FMLOCAL
	/pos FMLOCAL
/ms { 
	/sl exch def 
	/val 255 def 
	/ws cfs 
	/im cfs 
	/val 0 def 
	/bs cfs 
	/cs cfs 
	} bind def
400 ms 
/ip { 
	is 
	0 
	cf cs readline pop 
	{	ic exch get exec 
		add 
		} forall 
	pop 
	
	} bind def
/wh { 
	/len exch def 
	/pos exch def 
	ws 0 len getinterval im pos len getinterval copy pop
	pos len 
	} bind def
/bl { 
	/len exch def 
	/pos exch def 
	bs 0 len getinterval im pos len getinterval copy pop
	pos len 
	} bind def
/s1 1 string def
/fl { 
	/len exch def 
	/pos exch def 
	/val cf s1 readhexstring pop 0 get def
	pos 1 pos len add 1 sub {im exch val put} for
	pos len 
	} bind def
/hx { 
	3 copy getinterval 
	cf exch readhexstring pop pop 
	} bind def
	/h FMLOCAL
	/w FMLOCAL
	/d FMLOCAL
	/lb FMLOCAL
	/bitmapsave FMLOCAL
	/is FMLOCAL
	/cf FMLOCAL
/wbytes { 
	dup 
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc { 
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc { 
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc { 
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc { 
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def 
	sl lb lt {lb ms} if 
	/bitmapsave save def 
	r                    
	/is im 0 lb getinterval def 
	ws 0 lb getinterval is copy pop 
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{ip} image 
	bitmapsave restore 
	grestore
	} bind def
/BEGINBITMAPBW { 
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY { 
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT { 
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP { 
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def 
	r                    
	/is w d wbytes string def
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{cf is readhexstring pop} image
	bitmapsave restore 
	grestore
	} bind def
	/proc1 FMLOCAL
	/proc2 FMLOCAL
	/newproc FMLOCAL
/Fmcc {
    /proc2 exch cvlit def
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
	setcolortransfer
	{pop 0} setundercolorremoval
	{} setblackgeneration
	} bind def
	/tran FMLOCAL
/fakecolorsetup {
	/tran 256 string def
	0 1 255 {/indx exch def
		tran indx
		red indx get 77 mul
		green indx get 151 mul
		blue indx get 28 mul
		add add 256 idiv put} for
	currenttransfer
	{255 mul cvi tran exch get 255.0 div}
	exch Fmcc settransfer
} bind def
/BITMAPCOLOR {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	colorsetup
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPCOLORc {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	colorsetup
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPTRUECOLORc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip} {gip} {bip} true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUECOLOR {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop }
        { cf gis readhexstring pop }
        { cf bis readhexstring pop }
        true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUEGRAYc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip gip bip w gray} image
        bitmapsave restore
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray {
        /ww exch def
        /b exch def
        /g exch def
        /r exch def
        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
			b i get .114 mul add add r i 3 -1 roll floor cvi put } for
        r
        } bind def
/BITMAPTRUEGRAY {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop
          cf gis readhexstring pop
          cf bis readhexstring pop w gray}  image
        bitmapsave restore
        grestore
        } bind def
/BITMAPGRAY {
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc {
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end
	/ALDsave FMLOCAL
	/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
	/ALDsave save def
	 savematrix
	 ALDmatrix setmatrix
	} bind def







|









|



|


|
|
|
|


|



|
|
|

|
|
|
|

|


|


|
|

|
|
|
|

|


|


|



|
|
|
|
|
|
|


|


|
|

|
|
|
|

|







|








|


|



|
|
|
|

|


|


|




|







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
	setcolortransfer
	{pop 0} setundercolorremoval
	{} setblackgeneration
	} bind def
	/tran FMLOCAL
/fakecolorsetup {
	/tran 256 string def
	0 1 255 {/indx exch def 
		tran indx
		red indx get 77 mul
		green indx get 151 mul
		blue indx get 28 mul
		add add 256 idiv put} for
	currenttransfer
	{255 mul cvi tran exch get 255.0 div}
	exch Fmcc settransfer
} bind def
/BITMAPCOLOR { 
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def 
	colorsetup
	/is w d wbytes string def
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{cf is readhexstring pop} {is} {is} true 3 colorimage 
	bitmapsave restore 
	grestore
	} bind def
/BITMAPCOLORc { 
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def 
	sl lb lt {lb ms} if 
	/bitmapsave save def 
	colorsetup
	/is im 0 lb getinterval def 
	ws 0 lb getinterval is copy pop 
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{ip} {is} {is} true 3 colorimage
	bitmapsave restore 
	grestore
	} bind def
/BITMAPTRUECOLORc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        
        /is w string def
        
        ws 0 w getinterval is copy pop 
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        {ip} {gip} {bip} true 3 colorimage
        bitmapsave restore 
        grestore
        } bind def
/BITMAPTRUECOLOR { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        { cf is readhexstring pop } 
        { cf gis readhexstring pop } 
        { cf bis readhexstring pop } 
        true 3 colorimage 
        bitmapsave restore 
        grestore
        } bind def
/BITMAPTRUEGRAYc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        
        /is w string def
        
        ws 0 w getinterval is copy pop 
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        {ip gip bip w gray} image
        bitmapsave restore 
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray { 
        /ww exch def
        /b exch def
        /g exch def
        /r exch def
        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
			b i get .114 mul add add r i 3 -1 roll floor cvi put } for
        r
        } bind def
/BITMAPTRUEGRAY { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        { cf is readhexstring pop 
          cf gis readhexstring pop 
          cf bis readhexstring pop w gray}  image
        bitmapsave restore 
        grestore
        } bind def
/BITMAPGRAY { 
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc { 
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end 
	/ALDsave FMLOCAL
	/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
	/ALDsave save def
	 savematrix
	 ALDmatrix setmatrix
	} bind def
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
-0.27 ( binding, and) 457.95 580 P
(a binding on) 152.1 567.89 T
5 F
(<Control-a>) 204.57 567.89 T
3 F
( takes precedence over a binding on) 270.54 567.89 T
5 F
(<Key>.) 416.24 567.89 T
3 F
-0.26 (The mechanism for con\337ict resolution is similar in Tk 4.0 except that one binding can) 170.1 555.89 P
-0.35 (trigger for) 152.1 543.78 P
2 F
-0.35 (each) 194.7 543.78 P
3 F
-0.35 ( binding tag on the window where the event occurs. The bindings trigger in) 213.57 543.78 P







|







1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
-0.27 ( binding, and) 457.95 580 P
(a binding on) 152.1 567.89 T
5 F
(<Control-a>) 204.57 567.89 T
3 F
( takes precedence over a binding on) 270.54 567.89 T
5 F
(<KeyPress>.) 416.24 567.89 T
3 F
-0.26 (The mechanism for con\337ict resolution is similar in Tk 4.0 except that one binding can) 170.1 555.89 P
-0.35 (trigger for) 152.1 543.78 P
2 F
-0.35 (each) 194.7 543.78 P
3 F
-0.35 ( binding tag on the window where the event occurs. The bindings trigger in) 213.57 543.78 P
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
5 F
(Control) 391.17 608.33 T
3 F
(, or any combina-) 433.15 608.33 T
(tion of them. If you wish for a binding not to trigger when a modi\336er is present, you can) 152.1 596.33 T
(just de\336ne an empty binding for that modi\336er combination. For example,) 152.1 584.33 T
5 9 Q
(bind .b <Control-Button-1> {# this script is a no-op}) 179.1 570 T
3 10 Q
(creates a binding that will trigger on mouse button presses when the) 152.1 556.33 T
5 F
(Control) 426.36 556.33 T
3 F
( key is) 468.34 556.33 T
-0.22 (down. If there is also a) 152.1 544.33 P
5 F
-0.52 (<Button-1>) 244.35 544.33 P
3 F
-0.22 ( binding for) 334.3 544.33 P
5 F
-0.52 (.b) 383.35 544.33 P
3 F
-0.22 (, it will no longer be invoked) 395.34 544.33 P
-0.02 (if the) 152.1 532.33 P







|








|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
5 F
(Control) 391.17 608.33 T
3 F
(, or any combina-) 433.15 608.33 T
(tion of them. If you wish for a binding not to trigger when a modi\336er is present, you can) 152.1 596.33 T
(just de\336ne an empty binding for that modi\336er combination. For example,) 152.1 584.33 T
5 9 Q
(bind .b <Control-ButtonPress-1> {# this script is a no-op}) 179.1 570 T
3 10 Q
(creates a binding that will trigger on mouse button presses when the) 152.1 556.33 T
5 F
(Control) 426.36 556.33 T
3 F
( key is) 468.34 556.33 T
-0.22 (down. If there is also a) 152.1 544.33 P
5 F
-0.52 (<ButtonPress-1>) 244.35 544.33 P
3 F
-0.22 ( binding for) 334.3 544.33 P
5 F
-0.52 (.b) 383.35 544.33 P
3 F
-0.22 (, it will no longer be invoked) 395.34 544.33 P
-0.02 (if the) 152.1 532.33 P

Changes to doc/tk_mac.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
'\"
'\" Copyright (c) 2011 Kevin Walzer.
'\" Copyright (c) 2011 Donal K. Fellows.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk::mac n 8.6 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on OS X from Tk
.SH SYNOPSIS
.nf
\fB::tk::mac::DoScriptFile\fR
\fB::tk::mac::DoScriptText\fR
\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR
\fB::tk::mac::OpenDocument \fIfile...\fR
\fB::tk::mac::PrintDocument \fIfile...\fR
\fB::tk::mac::Quit\fR
\fB::tk::mac::OnHide\fR
\fB::tk::mac::OnShow\fR
\fB::tk::mac::ShowHelp\fR
\fB::tk::mac::PerformService\fR
\fB::tk::mac::LaunchURL \fIURL...\fR
\fB::tk::mac::GetAppPath\fR

\fB::tk::mac::standardAboutPanel\fR

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.TP
\fB::tk::mac::DoScriptFile\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes a Tcl file when an AppleScript sends a
.QW "do script"
command to Wish with a file path as a parameter.
.TP
\fB::tk::mac::DoScriptText\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes Tcl code when an AppleScript sends a
.QW "do script"
command to Wish with Tcl code or a Tcl procedure as a parameter.
.TP
\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is






|








<
<









<
<
<







<











<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24



25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42














43
44
45
46
47
48
49
'\"
'\" Copyright (c) 2011 Kevin Walzer.
'\" Copyright (c) 2011 Donal K. Fellows.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH tk::mac n 8.6 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on OS X from Tk
.SH SYNOPSIS
.nf


\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR
\fB::tk::mac::OpenDocument \fIfile...\fR
\fB::tk::mac::PrintDocument \fIfile...\fR
\fB::tk::mac::Quit\fR
\fB::tk::mac::OnHide\fR
\fB::tk::mac::OnShow\fR
\fB::tk::mac::ShowHelp\fR




\fB::tk::mac::standardAboutPanel\fR

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.TP














\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
}
.CE
.RE
.TP
\fB::tk::mac::OpenApplication\fR
.
If a proc of this name is defined, this proc fill fire when your application
is initially opened. It is the default Apple Event handler for
kAEOpenApplication,
.QW oapp .
.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,







|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
}
.CE
.RE
.TP
\fB::tk::mac::OpenApplication\fR
.
If a proc of this name is defined, this proc fill fire when your application
is intially opened. It is the default Apple Event handler for
kAEOpenApplication,
.QW oapp .
.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
.RE
.TP
\fB::tk::mac::PrintDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEPrintDocuments,
.QW pdoc ,
the Apple Event sent when your application is asked to print a
document.  It takes a single absolute file path as an argument.

.TP
\fB::tk::mac::Quit\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEQuitApplication,
.QW quit ,
the Apple Event sent when your application is asked to be quit, e.g. via the







|
|
>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
.RE
.TP
\fB::tk::mac::PrintDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEPrintDocuments,
.QW pdoc ,
the Apple Event sent when your application is asked to print one or more
documents (e.g., via the Print menu item in the Finder).  It works the same
way as \fBtk::mac::OpenDocument\fR in terms of arguments.
.TP
\fB::tk::mac::Quit\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEQuitApplication,
.QW quit ,
the Apple Event sent when your application is asked to be quit, e.g. via the
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
.TP
\fB::tk::mac::ShowHelp\fR
.
Customizes behavior of Apple Help menu; if this procedure is not defined, the
platform-specific standard Help menu item
.QW "YourApp Help"
performs the default Cocoa action of showing the Help Book configured in the
application's Info.plist (or displaying an alert if no Help Book is
set).
.TP
\fB::tk::mac::PerformService\fR
.
Executes a Tcl procedure called from the macOS
.QW Services
menu in the Application menu item. The
.QW Services
menu item allows for inter-application communication; data from one
application, such as selected text, can be sent to another application
for processing, for example to Safari as a search item for Google, or
to TextEdit to be appended to a file. An example of the proc is below,
and should be rewritten in an application script for customization:
.RS
.PP
.CS
proc ::tk::mac::PerformService {} {
    set data [clipboard get]
    $w insert end $data
}
.CE
.RE
Note that the mechanism for retrieving the data is from the clipboard;
there is no other supported way to obtain the data.  If the Services
process is not desired, the NSServices keys can be deleted from
the application's Info.plist file. The underlying code supporting this
command also allows the text, entry and ttk::entry widgets to access
services from other applications via the Services menu. The NSPortName
key in Wish's Info.plist file is currently set as
.QW "Wish"
; if a developer changes the name of the Wish executable to something
  else, this key should be modified with the same name.
.TP
\fB::tk::mac::LaunchURL \fIURL...\fR
.
If defined, launches a URL within Tk. This would be used if a Tk
application wants to handle a URL itself, such as displaying data from
an RSS feed, rather than launching a default application to handle the
URL, although it can defined as such. Wish includes a stub URL scheme
of
.QW foo://
in the CFBundleURLSchemes key of its Info.plist file; this should be customized for the specific URL
scheme the developer wants to support.
.TP
\fB::tk::mac::GetAppPath\fR
.
Returns the current applications's file path.
.TP


.SH "ADDITIONAL DIALOGS"
.PP
The Aqua/Mac OS X defines additional dialogs that applications should
support.
.TP
\fB::tk::mac::standardAboutPanel\fR
.







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







137
138
139
140
141
142
143
144


















































145
146
147
148
149
150
151
.TP
\fB::tk::mac::ShowHelp\fR
.
Customizes behavior of Apple Help menu; if this procedure is not defined, the
platform-specific standard Help menu item
.QW "YourApp Help"
performs the default Cocoa action of showing the Help Book configured in the
application's Info.plist (or displaying an alert if no Help Book is set).


















































.SH "ADDITIONAL DIALOGS"
.PP
The Aqua/Mac OS X defines additional dialogs that applications should
support.
.TP
\fB::tk::mac::standardAboutPanel\fR
.

Changes to doc/tkerror.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tkerror n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkerror \- Command invoked to process background errors
.SH SYNOPSIS
\fBtkerror \fImessage\fR
.BE

.SH DESCRIPTION
.PP
Note: as of Tk 4.1 the \fBtkerror\fR command has been renamed to
\fBbgerror\fR because the event loop (which is what usually invokes
it) is now part of Tcl.  For backward compatibility
the \fBbgerror\fR provided by the current Tk version still
tries to call \fBtkerror\fR if there is one (or an auto loadable one),
so old script defining that error handler should still work, but you
should anyhow modify your scripts to use \fBbgerror\fR instead
of \fBtkerror\fR because that support for the old name might vanish
in the near future. If that call fails, \fBbgerror\fR
posts a dialog showing the error and offering to see the stack trace
to the user. If you want your own error management you should
directly override \fBbgerror\fR instead of \fBtkerror\fR.
Documentation for \fBbgerror\fR is available as part of Tcl's
documentation.

.SH KEYWORDS
background error, reporting
'\" Local Variables:
'\" mode: nroff
'\" End:






|









>






|

|

|





>


<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36



'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tkerror n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkerror \- Command invoked to process background errors
.SH SYNOPSIS
\fBtkerror \fImessage\fR
.BE

.SH DESCRIPTION
.PP
Note: as of Tk 4.1 the \fBtkerror\fR command has been renamed to
\fBbgerror\fR because the event loop (which is what usually invokes
it) is now part of Tcl.  For backward compatibility
the \fBbgerror\fR provided by the current Tk version still
tries to call \fBtkerror\fR if there is one (or an auto loadable one), 
so old script defining that error handler should still work, but you
should anyhow modify your scripts to use \fBbgerror\fR instead 
of \fBtkerror\fR because that support for the old name might vanish
in the near future. If that call fails, \fBbgerror\fR 
posts a dialog showing the error and offering to see the stack trace
to the user. If you want your own error management you should
directly override \fBbgerror\fR instead of \fBtkerror\fR.
Documentation for \fBbgerror\fR is available as part of Tcl's
documentation.

.SH KEYWORDS
background error, reporting



Changes to doc/tkvars.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54



55
56
57
58
59
60
61
62




63



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tkvars n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
geometry, tk_library, tk_patchLevel, tk_strictMotif, tk_version \- Variables used or set by Tk
.BE

.SH DESCRIPTION
.PP
The following Tcl variables are either set or used by Tk at various times
in its execution:
.TP 15
\fBtk_library\fR
.
This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.
.RS
.PP
The initial value of \fBtcl_library\fR is set when Tk is added to
an interpreter;  this is done by searching several different directories
until one is found that contains an appropriate Tk startup script.
If the \fBTK_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
If \fBTK_LIBRARY\fR is not set or does not refer to an appropriate
directory, then Tk checks several other directories based on a
compiled-in default location, the location of the Tcl library directory,
the location of the binary containing the application, and the current
working directory.
.PP
The variable can be modified by an application to switch to a different
library.
.RE
.TP
\fBtk_patchLevel\fR
.
Contains a dot-separated sequence of decimal integers giving the
current patch level for Tk.
The patch level is incremented for each new release or patch, and
it uniquely identifies an official version of Tk.
.RS
.PP
This value is normally the same as the result of
.QW "\fBpackage require\fR \fBTk\fR" .
.RE



.TP
\fBtk_strictMotif\fR
.
This variable is set to zero by default.
If an application sets it to one, then Tk attempts to adhere as
closely as possible to Motif look-and-feel standards.
For example, active elements such as buttons and scrollbar
sliders will not change color when the pointer passes over them.




Modern applications should not normally set this variable.



.TP 15
\fBtk_version\fR
.
Tk sets this variable in the interpreter for each application.
The variable holds the current version number of the Tk
library in the form \fImajor\fR.\fIminor\fR.  \fIMajor\fR and
\fIminor\fR are integers.  The major version number increases in
any Tk release that includes changes that are not backward compatible
(i.e. whenever existing Tk applications and scripts may have to change to
work with the new release).  The minor version number increases with
each new release of Tk, except that it resets to zero whenever the
major version number changes.
.SS "INTERNAL AND DEBUGGING VARIABLES"
.PP
These variables should not normally be set by user code.
.TP
\fBtk::Priv\fR
.
This variable is an array containing several pieces of information
that are private to Tk.  The elements of \fBtk::Priv\fR are used by
Tk library procedures and default bindings.
They should not be accessed by any code outside Tk.
.TP
\fBtk_textRedraw\fR
.TP
\fBtk_textRelayout\fR
.
These variables are set by text widgets when they have debugging
turned on.  The values written to these variables can be used to
test or debug text widget operations.  These variables are mostly
used by Tk's test suite.
.SH "OTHER GLOBAL VARIABLES"
The following variables are only guaranteed to exist in \fBwish\fR
executables; the Tk library does not define them itself but many Tk
environments do.
.TP 6
\fBgeometry\fR
.
If set, contains the user-supplied geometry specification to use for
the main Tk window.
.SH "SEE ALSO"
package(n), tclvars(n), wish(1)
.SH KEYWORDS
environment, text, variables, version
'\" Local Variables:
'\" mode: nroff
'\" End:






|





|

>






<





<
<
|









<


<


<
<
|


|
|
|
<
<
>
>
>


<





>
>
>
>
|
>
>
>


<









<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26


27
28
29
30
31
32
33
34
35
36

37
38

39
40


41
42
43
44
45
46


47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75





76
























77
78



'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tkvars n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkvars \- Variables used or set by Tk
.BE

.SH DESCRIPTION
.PP
The following Tcl variables are either set or used by Tk at various times
in its execution:
.TP 15
\fBtk_library\fR

This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.


The initial value of \fBtk_library\fR is set when Tk is added to
an interpreter;  this is done by searching several different directories
until one is found that contains an appropriate Tk startup script.
If the \fBTK_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
If \fBTK_LIBRARY\fR is not set or does not refer to an appropriate
directory, then Tk checks several other directories based on a
compiled-in default location, the location of the Tcl library directory,
the location of the binary containing the application, and the current
working directory.

The variable can be modified by an application to switch to a different
library.

.TP
\fBtk_patchLevel\fR


Contains a decimal integer giving the current patch level for Tk.
The patch level is incremented for each new release or patch, and
it uniquely identifies an official version of Tk.
.TP
\fBtk::Priv\fR
This variable is an array containing several pieces of information


that are private to Tk.  The elements of \fBtk::Priv\fR are used by
Tk library procedures and default bindings.
They should not be accessed by any code outside Tk.
.TP
\fBtk_strictMotif\fR

This variable is set to zero by default.
If an application sets it to one, then Tk attempts to adhere as
closely as possible to Motif look-and-feel standards.
For example, active elements such as buttons and scrollbar
sliders will not change color when the pointer passes over them.
.TP
\fBtk_textRedraw\fR
.TP
\fBtk_textRelayout\fR
These variables are set by text widgets when they have debugging
turned on.  The values written to these variables can be used to
test or debug text widget operations.  These variables are mostly
used by Tk's test suite.
.TP 15
\fBtk_version\fR

Tk sets this variable in the interpreter for each application.
The variable holds the current version number of the Tk
library in the form \fImajor\fR.\fIminor\fR.  \fIMajor\fR and
\fIminor\fR are integers.  The major version number increases in
any Tk release that includes changes that are not backward compatible
(i.e. whenever existing Tk applications and scripts may have to change to
work with the new release).  The minor version number increases with
each new release of Tk, except that it resets to zero whenever the
major version number changes.






























.SH KEYWORDS
variables, version, text



Changes to doc/tkwait.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH tkwait n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkwait \- Wait for variable to change or window to be destroyed
.SH SYNOPSIS
\fBtkwait variable \fIname\fR
.sp
\fBtkwait visibility \fIname\fR
.sp
\fBtkwait window \fIname\fR
.BE

.SH DESCRIPTION
.PP
The \fBtkwait\fR command waits for one of several things to happen,
then it returns without taking any other actions.
The return value is always an empty string.
If the first argument is \fBvariable\fR (or any abbreviation of
it) then the second argument is the name of a global variable and the






|













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH tkwait n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkwait \- Wait for variable to change or window to be destroyed
.SH SYNOPSIS
\fBtkwait variable \fIname\fR
.sp
\fBtkwait visibility \fIname\fR
.sp
\fBtkwait window \fIname\fR
.BE

.SH DESCRIPTION
.PP
The \fBtkwait\fR command waits for one of several things to happen,
then it returns without taking any other actions.
The return value is always an empty string.
If the first argument is \fBvariable\fR (or any abbreviation of
it) then the second argument is the name of a global variable and the
39
40
41
42
43
44
45
46
47
48
49
50
51
52
with a dialog box before using the result of that interaction.
.PP
While the \fBtkwait\fR command is waiting it processes events in
the normal fashion, so the application will continue to respond
to user interactions.
If an event handler invokes \fBtkwait\fR again, the nested call
to \fBtkwait\fR must complete before the outer call can complete.
.SH "SEE ALSO"
bind(n), vwait(n)
.SH KEYWORDS
variable, visibility, wait, window
'\" Local Variables:
'\" mode: nroff
'\" End:







|
<


<
<
<
40
41
42
43
44
45
46
47

48
49



with a dialog box before using the result of that interaction.
.PP
While the \fBtkwait\fR command is waiting it processes events in
the normal fashion, so the application will continue to respond
to user interactions.
If an event handler invokes \fBtkwait\fR again, the nested call
to \fBtkwait\fR must complete before the outer call can complete.


.SH KEYWORDS
variable, visibility, wait, window



Changes to doc/toplevel.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH toplevel n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
toplevel \- Create and manipulate 'toplevel' main and popup window widgets
.SH SYNOPSIS
\fBtoplevel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.VS "8.7, TIP262"
An empty background will disable drawing the background image.
.OP \-backgroundimage backgroundImage BackgroundImage
This specifies an image to display on the toplevel's background within
the border of the toplevel (i.e., the image will be clipped by the
toplevel's highlight ring and border, if either are present) on top of
the background;
subwidgets of the toplevel will be drawn on top. The image must have
been created with the \fBimage create\fR command. If specified as the
empty string, no image will be displayed.
.VE "8.7, TIP262"
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.


The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fB\-colormap\fR option is not specified, the new window
uses the default colormap of its screen.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-container container Container
The value must be a boolean.  If true, it means that this window will
be used as a container in which some other application will be embedded
(for example, a Tk toplevel can be embedded using the \fB\-use\fR option).












|









|




<
<
<
<
<
<
<
<
<
<
<




|
>
>
|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27











28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH toplevel n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
toplevel \- Create and manipulate toplevel widgets
.SH SYNOPSIS
\fBtoplevel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fBbackground\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.











.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings. Some window managers display the
class name for windows in their dock while some others display the
window title.
The \fBclass\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual
as \fIpathName\fR), in which case the new window will use the colormap
from the specified window.
If the \fBcolormap\fR option is not specified, the new window
uses the default colormap of its screen.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-container container Container
The value must be a boolean.  If true, it means that this window will
be used as a container in which some other application will be embedded
(for example, a Tk toplevel can be embedded using the \fB\-use\fR option).
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178

179
180

181
182
183
Specifies the screen on which to place the new window.
Any valid screen name may be used, even one associated with a
different display.
Defaults to the same screen as its parent.
This option is special in that it may not be specified via the option
database, and it may not be modified with the \fBconfigure\fR
widget command.
.OP \-tile tile Tile
.VS "8.7, TIP262"
This specifies how to draw the background image (see
\fB\-backgroundimage\fR) on the toplevel.
If true (according to \fBTcl_GetBoolean\fR), the image will be tiled
to fill the whole toplevel, with the origin of the first copy of the
image being the top left of the interior of the toplevel.
If false (the default), the image will be centered within the toplevel.
.VE "8.7, TIP262"
.OP \-use use Use
This option is used for embedding. If the value is not an empty string,
it must be the window identifier of a container window, specified as
a hexadecimal string like the ones returned by the \fBwinfo id\fR
command. The toplevel widget will be created as a child of the given
container instead of the root window for the screen.  If the container
window is in a Tk application, it must be a frame or toplevel widget for
which the \fB\-container\fR option was specified.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the default
visual for its screen.
The \fB\-visual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will
not request any size at all.
.BE

.SH DESCRIPTION
.PP
The \fBtoplevel\fR command creates a new toplevel widget (given
by the \fIpathName\fR argument).  Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the toplevel such as its background color
and relief.  The \fBtoplevel\fR command returns the
path name of the new window.
.PP
A toplevel is similar to a \fBframe\fR except that it is created as a
top-level window:  its X parent is the root window of a screen
rather than the logical parent from its Tk path name.  The primary
purpose of a toplevel is to serve as a container for dialog boxes
and other collections of widgets.  The only visible features
of a toplevel are its background and an optional 3-D border
to make the toplevel appear raised or sunken.

.SH "WIDGET COMMAND"
.PP
The \fBtoplevel\fR command creates a new Tcl command whose
name is the same as the path name of the toplevel's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.

.SH BINDINGS
.PP
When a new toplevel is created, it has no default event bindings:
toplevels are not intended to be interactive.
.PP
Be aware that bindings on toplevels may receive events from subwidgets.
.SH "SEE ALSO"
bind(n), bindtags(n), frame(n), wm(n)

.SH KEYWORDS
toplevel, widget

'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
<
<
<
<
<
<















|







>










|

|


|

>






<

|

<





|
<






<












>




|
<

|
>


>



69
70
71
72
73
74
75









76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126

127
128
129
130
131
132

133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
Specifies the screen on which to place the new window.
Any valid screen name may be used, even one associated with a
different display.
Defaults to the same screen as its parent.
This option is special in that it may not be specified via the option
database, and it may not be modified with the \fBconfigure\fR
widget command.









.OP \-use use Use
This option is used for embedding. If the value is not an empty string,
it must be the window identifier of a container window, specified as
a hexadecimal string like the ones returned by the \fBwinfo id\fR
command. The toplevel widget will be created as a child of the given
container instead of the root window for the screen.  If the container
window is in a Tk application, it must be a frame or toplevel widget for
which the \fB\-container\fR option was specified.
This option may not be changed with the \fBconfigure\fR
widget command.
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the default
visual for its screen.
The \fBvisual\fR option may not be modified with the \fBconfigure\fR
widget command.
.OP \-width width Width
Specifies the desired width for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.
If this option is less than or equal to zero then the window will
not request any size at all.
.BE

.SH DESCRIPTION
.PP
The \fBtoplevel\fR command creates a new toplevel widget (given
by the \fIpathName\fR argument).  Additional
options, described above, may be specified on the command line
or in the option database
to configure aspects of the toplevel such as its background color
and relief.  The \fBtoplevel\fR command returns the
path name of the new window.
.PP
A toplevel is similar to a frame except that it is created as a
top-level window:  its X parent is the root window of a screen
rather than the logical parent from its path name.  The primary
purpose of a toplevel is to serve as a container for dialog boxes
and other collections of widgets.  The only visible features
of a toplevel are its background color and an optional 3-D border
to make the toplevel appear raised or sunken.

.SH "WIDGET COMMAND"
.PP
The \fBtoplevel\fR command creates a new Tcl command whose
name is the same as the path name of the toplevel's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:

.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE

\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.

.SH BINDINGS
.PP
When a new toplevel is created, it has no default event bindings:
toplevels are not intended to be interactive.


.SH "SEE ALSO"
frame(n)

.SH KEYWORDS
toplevel, widget

'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_Geometry.3.

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
.AP "Ttk_Box *" cavity in/out
A rectangular region from which a parcel is allocated.
.AP short border in
Extra padding (in pixels) to add uniformly to each side of a region.
.AP short bottom in
Extra padding (in pixels) to add to the bottom of a region.
.AP Ttk_Box box in
Specifies a rectangular region.
.AP "Ttk_Box *" box_rtn out
A rectangular region.
.AP int height in
The height in pixels of a region.
.AP "Tcl_Interp *" interp in
Used to store error messages.
.AP int left in
Extra padding (in pixels) to add to the left side of a region.
.AP "Tcl_Obj *" objPtr in
String value contains a symbolic name
to be converted to an enumerated value or bitmask.
Internal rep may be be modified to cache corresponding value.
.AP Ttk_Padding padding in
Extra padding to add on the inside of a region.
.AP "Ttk_Padding *" padding_rtn out
Padding present in the inside of a region.
.AP Ttk_Box parcel in
A rectangular region, allocated from a cavity.
.AP int relief in
One of the standard Tk relief options
(\fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, etc.).
See \fBTk_GetReliefFromObj\fR.
.AP short right in
Extra padding (in pixels) to add to the right side of a region.
.AP Ttk_Side side in
One of \fBTTK_SIDE_LEFT\fR, \fBTTK_SIDE_TOP\fR,
\fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR.
.AP unsigned sticky in
A bitmask containing one or more of the bits
\fBTTK_STICK_W\fR (west, or left),
\fBTTK_STICK_E\fR (east, or right),
\fBTTK_STICK_N\fR (north, or top), and
\fBTTK_STICK_S\fR (south, or bottom).
\fBTTK_FILL_X\fR is defined as a synonym for (\fBTTK_STICK_W\fR|\fBTTK_STICK_E\fR),
\fBTTK_FILL_Y\fR is a synonym for (\fBTTK_STICK_N\fR|\fBTTK_STICK_S\fR),
and  \fBTTK_FILL_BOTH\fR
is a synonym for (\fBTTK_FILL_X\fR|\fBTTK_FILL_Y\fR).
See also: \fIgrid(n)\fR.
.AP Tk_Window tkwin in
Window whose screen geometry determines
the conversion between absolute units and pixels.
.AP short top in
Extra padding at the top of a region.
.AP int width in
The width in pixels of a region.
.AP int x in
X coordinate of upper-left corner of region.







<

|







|



<

|



|
|


|

|



|
|


|
|
|
|


|







62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
.AP "Ttk_Box *" cavity in/out
A rectangular region from which a parcel is allocated.
.AP short border in
Extra padding (in pixels) to add uniformly to each side of a region.
.AP short bottom in
Extra padding (in pixels) to add to the bottom of a region.
.AP Ttk_Box box in

.AP "Ttk_Box *" box_rtn out
Specifies a rectangular region.
.AP int height in
The height in pixels of a region.
.AP "Tcl_Interp *" interp in
Used to store error messages.
.AP int left in
Extra padding (in pixels) to add to the left side of a region.
.AP "Tcl_Obj *" objPtr in
String value contains a symbolic name 
to be converted to an enumerated value or bitmask.
Internal rep may be be modified to cache corresponding value.
.AP Ttk_Padding padding in

.AP "Ttk_Padding *" padding_rtn out
Extra padding to add on the inside of a region.
.AP Ttk_Box parcel in
A rectangular region, allocated from a cavity.
.AP int relief in
One of the standard Tk relief options 
(TK_RELIEF_RAISED, TK_RELIEF_SUNKEN, etc.).  
See \fBTk_GetReliefFromObj\fR.
.AP short right in
Extra padding (in pixles) to add to the right side of a region.
.AP Ttk_Side side in
One of \fBTTK_SIDE_LEFT\fR, \fBTTK_SIDE_TOP\fR, 
\fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR.
.AP unsigned sticky in
A bitmask containing one or more of the bits
\fBTTK_STICK_W\fR (west, or left), 
\fBTTK_STICK_E\fR (east, or right, 
\fBTTK_STICK_N\fR (north, or top), and
\fBTTK_STICK_S\fR (south, or bottom).
\fBTTK_FILL_X\fR is defined as a synonym for (TTK_STICK_W|TTK_STICK_E),
\fBTTK_FILL_Y\fR is a synonym for (TTK_STICK_N|TTK_STICK_S),
and  \fBTTK_FILL_BOTH\fR and \fBTTK_STICK_ALL\fR
are synonyms for (TTK_FILL_X|TTK_FILL_Y).
See also: \fIgrid(n)\fR.
.AP Tk_Window tkwin in
Window whose screen geometry determines 
the conversion between absolute units and pixels.
.AP short top in
Extra padding at the top of a region.
.AP int width in
The width in pixels of a region.
.AP int x in
X coordinate of upper-left corner of region.
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    int \fIy\fR;
    int \fIwidth\fR;
    int \fIheight\fR;
} \fBTtk_Box\fR;
.CE
All coordinates are relative to the window.
.PP
\fBTtk_MakeBox\fR is a convenience routine that constructs
a \fBTtk_Box\fR structure representing a region \fIwidth\fR pixels
wide, \fIheight\fR pixels tall, at the specified \fIx, y\fR coordinates.
.PP
\fBTtk_PadBox\fR returns a new box located inside the specified \fIparcel\fR,
shrunken according to the left, top, right, and bottom margins
specified by \fIpadding\fR.
.PP







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    int \fIy\fR;
    int \fIwidth\fR;
    int \fIheight\fR;
} \fBTtk_Box\fR;
.CE
All coordinates are relative to the window.
.PP
\fBTtk_MakeBox\fR is a convenience routine that contsructs
a \fBTtk_Box\fR structure representing a region \fIwidth\fR pixels
wide, \fIheight\fR pixels tall, at the specified \fIx, y\fR coordinates.
.PP
\fBTtk_PadBox\fR returns a new box located inside the specified \fIparcel\fR,
shrunken according to the left, top, right, and bottom margins
specified by \fIpadding\fR.
.PP
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    short \fIleft\fR;
    short \fItop\fR;
    short \fIright\fR;
    short \fIbottom\fR;
} \fBTtk_Padding\fR;
.CE
.PP
\fBTtk_MakePadding\fR is a convenience routine that constructs
a \fBTtk_Padding\fR structure with the specified left, top, right, and bottom
components.
.PP
\fBTtk_UniformPadding\fR constructs a \fBTtk_Padding\fR structure
with all components equal to the specified \fIborder\fR.
.PP
\fBTtk_AddPadding\fR adds two \fBTtk_Padding\fRs together
and returns a combined padding containing the sum of the
individual padding components.
.PP
\fBTtk_RelievePadding\fR
adds an extra 2 pixels of padding to \fIpadding\fR
according to the specified \fIrelief\fR.
If \fIrelief\fR is \fBTK_RELIEF_SUNKEN\fR,
adds two pixels at the top and left
so the inner region is shifted down and to the left.
If it is \fBTK_RELIEF_RAISED\fR, adds two pixels
at the bottom and right so
the inner region is shifted up and to the right.
Otherwise, adds 1 pixel on all sides.
This is typically used in element geometry procedures to simulate a
.QW pressed-in
look for pushbuttons.
.SH "CONVERSION ROUTINES"
.PP
\fBTtk_GetPaddingFromObj\fR converts the string in \fIobjPtr\fR
to a \fBTtk_Padding\fR structure.
The string representation is a list of
up to four length specifications
.QW "\fIleft top right bottom\fR" .
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
See \fBTk_GetPixelsFromObj(3)\fR for the syntax of length specifications.
.PP
\fBTtk_GetBorderFromObj\fR is the same as \fBTtk_GetPaddingFromObj\fR
except that the lengths are specified as integers
(i.e., resolution-dependent values like \fI3m\fR are not allowed).
.PP
\fBTtk_GetStickyFromObj\fR converts the string in \fIobjPtr\fR
to a \fIsticky\fR bitmask.  The string contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR, or \fBw\fR.
.SH "SEE ALSO"
Tk_GetReliefFromObj(3), Tk_GetPixelsFromObj(3), Tk_GetAnchorFromObj(3)
.SH "KEYWORDS"
geometry, padding, margins, box, region, sticky, relief







|










|


|



|









|
|

|

|




|
|








169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    short \fIleft\fR;
    short \fItop\fR;
    short \fIright\fR;
    short \fIbottom\fR;
} \fBTtk_Padding\fR;
.CE
.PP
\fBTtk_MakePadding\fR is a convenience routine that contsructs
a \fBTtk_Padding\fR structure with the specified left, top, right, and bottom
components.
.PP
\fBTtk_UniformPadding\fR constructs a \fBTtk_Padding\fR structure
with all components equal to the specified \fIborder\fR.
.PP
\fBTtk_AddPadding\fR adds two \fBTtk_Padding\fRs together
and returns a combined padding containing the sum of the
individual padding components.
.PP
\fBTtk_RelievePadding\fR 
adds an extra 2 pixels of padding to \fIpadding\fR
according to the specified \fIrelief\fR.
If \fIrelief\fR is \fBTK_RELIEF_SUNKEN\fR, 
adds two pixels at the top and left
so the inner region is shifted down and to the left.
If it is \fBTK_RELIEF_RAISED\fR, adds two pixels
at the bottom and right so 
the inner region is shifted up and to the right.
Otherwise, adds 1 pixel on all sides.
This is typically used in element geometry procedures to simulate a
.QW pressed-in
look for pushbuttons.
.SH "CONVERSION ROUTINES"
.PP
\fBTtk_GetPaddingFromObj\fR converts the string in \fIobjPtr\fR
to a \fBTtk_Padding\fR structure.
The string representation is a list of 
up to four length specifications 
.QW "\fIleft top right bottom\fR" .
If fewer than four elements are specified, 
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and 
\fItop\fR defaults to \fIleft\fR.
See \fBTk_GetPixelsFromObj(3)\fR for the syntax of length specifications.
.PP
\fBTtk_GetBorderFromObj\fR is the same as \fBTtk_GetPaddingFromObj\fR
except that the lengths are specified as integers 
(i.e., resolution-dependant values like \fI3m\fR are not allowed).
.PP
\fBTtk_GetStickyFromObj\fR converts the string in \fIobjPtr\fR
to a \fIsticky\fR bitmask.  The string contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR, or \fBw\fR.
.SH "SEE ALSO"
Tk_GetReliefFromObj(3), Tk_GetPixelsFromObj(3), Tk_GetAnchorFromObj(3)
.SH "KEYWORDS"
geometry, padding, margins, box, region, sticky, relief

Changes to doc/ttk_Theme.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\"
.TH Ttk_CreateTheme 3 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
Ttk_CreateTheme, Ttk_GetTheme, Ttk_GetDefaultTheme, Ttk_GetCurrentTheme \- create and use Tk themes.
.SH SYNOPSIS
.nf





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" 
.TH Ttk_CreateTheme 3 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
Ttk_CreateTheme, Ttk_GetTheme, Ttk_GetDefaultTheme, Ttk_GetCurrentTheme \- create and use Tk themes.
.SH SYNOPSIS
.nf

Changes to doc/ttk_button.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41







42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::button n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::button \- Widget that issues a command when pressed
.SH SYNOPSIS
\fBttk::button\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-justify	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A script to evaluate when the widget is invoked.
.OP \-default default Default
May be set to one of  \fBnormal\fR, \fBactive\fR, or \fBdisabled\fR.
In a dialog box, one button may be designated the
.QW default
button (meaning, roughly,
.QW "the one that gets invoked when the user presses <Enter>" ).
\fBactive\fR indicates that this is currently the default button;
\fBnormal\fR means that it may become the default button, and
\fBdisabled\fR means that it is not defaultable.
The default is \fBnormal\fR.
.RS
.PP
Depending on the theme, the default button may be displayed
with an extra highlight ring, or with a different border color.
.RE







.\" Not documented -- may go away
.\" .OP \-padding padding Padding
.\" .OP \-foreground foreground Foreground
.\" .OP \-font font Font
.\" .OP \-anchor anchor Anchor

.\" .OP \-relief relief Relief
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, buttons support the following additional widget commands:
.TP
\fIpathName \fBinvoke\fR
Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::button\fP is \fBTButton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTButton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-anchor\fP \fIanchor\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-highlightcolor\fP \fIcolor\fP
.br
\fB\-highlightthickness\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-shiftrelief\fP \fIamount\fP
.RS
\fB\-shiftrelief\fP specifies how far the button contents are
shifted down and right in the \fIpressed\fP state.
This action provides additional skeumorphic feedback.
.RE
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), button(n)
.SH "KEYWORDS"
widget, button, default, command
'\" Local Variables:
'\" mode: nroff
'\" End:





|













|


















|


>
>
>
>
>
>
>





>



|
|








|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


70































71

72


73


74
75
76
77
78
79
80
81
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::button n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::button \- Widget that issues a command when pressed
.SH SYNOPSIS
\fBttk::button\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A script to evaluate when the widget is invoked.
.OP \-default default Default
May be set to one of  \fBnormal\fR, \fBactive\fR, or \fBdisabled\fR.
In a dialog box, one button may be designated the
.QW default
button (meaning, roughly,
.QW "the one that gets invoked when the user presses <Enter>" ).
\fBactive\fR indicates that this is currently the default button;
\fBnormal\fR means that it may become the default button, and
\fBdisabled\fR means that it is not defaultable.
The default is \fBnormal\fR.
.RS
.PP
Depending on the theme, the default button may be displayed 
with an extra highlight ring, or with a different border color.
.RE
.OP \-width width Width
If greater than zero, specifies how much space, in character widths, 
to allocate for the text label.  
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.
Note that some themes may specify a non-zero \fB\-width\fR
in the style.
.\" Not documented -- may go away
.\" .OP \-padding padding Padding
.\" .OP \-foreground foreground Foreground
.\" .OP \-font font Font
.\" .OP \-anchor anchor Anchor
.\" .OP \-padding padding Padding
.\" .OP \-relief relief Relief
.SH "WIDGET COMMAND"
.PP
In addition to the standard 
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR 
commands, buttons support the following additional widget commands:
.TP
\fIpathName \fBinvoke\fR
Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.
.SH "COMPATIBILITY OPTIONS"
.OP \-state state State


May be set to \fBnormal\fR or \fBdisabled\fR to control the































\fBdisabled\fR state bit. This is a

.QW write-only


option: setting it changes the widget state, but the \fBstate\fR


widget command does not affect the state option.
.SH "SEE ALSO"
ttk::widget(n), button(n)
.SH "KEYWORDS"
widget, button, default, command
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_checkbutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::checkbutton \- On/off widget
.SH SYNOPSIS
\fBttk::checkbutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::checkbutton\fR widget is used to show or change a setting.
It has two states, selected and deselected.
The state of the checkbutton may be linked to a Tcl variable.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script to execute whenever the widget is invoked.
.OP \-offvalue offValue OffValue
The value to store in the associated \fB\-variable\fR
when the widget is deselected.  Defaults to \fB0\fR.
.OP \-onvalue onValue OnValue
The value to store in the associated \fB\-variable\fR
when the widget is selected.  Defaults to \fB1\fR.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Defaults to the widget pathname if not specified.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, checkbuttons support the following additional
widget commands:
.TP
\fIpathname\fB invoke\fR
Toggles between the selected and deselected states
and evaluates the associated \fB\-command\fR.
If the widget is currently selected, sets the \fB\-variable\fR
to the \fB\-offvalue\fR and deselects the widget;
otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR
Returns the result of the \fB\-command\fR.
.\" Missing: select, deselect, toggle
.\" Are these useful?  They don't invoke the -command
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"
.PP
The widget does not respond to user input if the \fBdisabled\fR state is set.
The widget sets the \fBselected\fR state whenever
the linked \fB\-variable\fR is set to the widget's \fB\-onvalue\fR,
and clears it otherwise.
The widget sets the \fBalternate\fR state whenever the
linked \fB\-variable\fR is unset.
(The \fBalternate\fR state may be used to indicate a
.QW tri-state
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::checkbutton\fP is \fBTCheckbutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP,
\fBpressed\fP, \fBselected\fP, \fBreadonly\fP.
.PP
\fBTCheckbutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatorbackground\fP \fIcolor\fP
.br
\fB\-indicatorcolor\fP \fIcolor\fP
.br
\fB\-indicatormargin\fP \fIpadding\fP
.br
\fB\-indicatorrelief\fP \fIrelief\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::radiobutton(n), checkbutton(n)
.SH "KEYWORDS"
widget, button, toggle, check, option
'\" Local Variables:
'\" mode: nroff
'\" End:





|










|











|


|






|
|










|





|


|
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70






























71
72
73
74
75
76
77
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::checkbutton \- On/off widget
.SH SYNOPSIS
\fBttk::checkbutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::checkbutton\fR widget is used to show or change a setting.
It has two states, selected and deselected.  
The state of the checkbutton may be linked to a Tcl variable.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script to execute whenever the widget is invoked.
.OP \-offvalue offValue OffValue
The value to store in the associated \fB\-variable\fR 
when the widget is deselected.  Defaults to \fB0\fR.
.OP \-onvalue onValue OnValue
The value to store in the associated \fB\-variable\fR 
when the widget is selected.  Defaults to \fB1\fR.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Defaults to the widget pathname if not specified.
.SH "WIDGET COMMAND"
.PP
In addition to the standard 
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR 
commands, checkbuttons support the following additional
widget commands:
.TP
\fIpathname\fB invoke\fR
Toggles between the selected and deselected states
and evaluates the associated \fB\-command\fR.
If the widget is currently selected, sets the \fB\-variable\fR
to the \fB\-offvalue\fR and deselects the widget;
otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR
Returns the result of the \fB\-command\fR.
.\" Missing: select, deselect, toggle 
.\" Are these useful?  They don't invoke the -command
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"
.PP
The widget does not respond to user input if the \fBdisabled\fR state is set.
The widget sets the \fBselected\fR state whenever 
the linked \fB\-variable\fR is set to the widget's \fB\-onvalue\fR,
and clears it otherwise.
The widget sets the \fBalternate\fR state whenever the 
linked \fB\-variable\fR is unset.  
(The \fBalternate\fR state may be used to indicate a
.QW tri-state
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.






























.SH "SEE ALSO"
ttk::widget(n), ttk::radiobutton(n), checkbutton(n)
.SH "KEYWORDS"
widget, button, toggle, check, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_combobox.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::combobox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::combobox \- text field with popdown selection list
.SH SYNOPSIS
\fBttk::combobox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the
values in the list.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style	\-placeholder	\-placeholderforeground
.SE
.\" ALSO: Other entry widget options
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
Boolean value.
If set, the widget selection is linked to the X selection.
.OP \-justify justify Justify
Specifies how the text is aligned within the widget.
Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
.OP \-height height Height
Specifies the height of the pop-down listbox, in rows.
.OP \-postcommand postCommand PostCommand
A Tcl script to evaluate immediately before displaying the listbox.
The \fB\-postcommand\fR script may specify the \fB\-values\fR to display.
.OP \-state state State
One of \fBnormal\fR, \fBreadonly\fR, or \fBdisabled\fR.
In the \fBreadonly\fR state,
the value may not be edited directly, and
the user can only select one of the \fB\-values\fR from the
dropdown list.
In the \fBnormal\fR state,
the text field is directly editable.
In the \fBdisabled\fR state, no interaction is possible.
.OP \-textvariable textVariable TextVariable
Specifies the name of a global variable whose value is linked
to the widget value.
Whenever the variable changes value the widget value is updated,
and vice versa.
.OP \-values values Values
Specifies the list of values to display in the drop-down listbox.
.OP \-width width Width
Specifies an integer value indicating the desired width of the entry window,





|











|



|

















|


|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::combobox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::combobox \- text field with popdown selection list
.SH SYNOPSIS
\fBttk::combobox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the 
values in the list.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.\" ALSO: Other entry widget options
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
Boolean value.
If set, the widget selection is linked to the X selection.
.OP \-justify justify Justify
Specifies how the text is aligned within the widget.
Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
.OP \-height height Height
Specifies the height of the pop-down listbox, in rows.
.OP \-postcommand postCommand PostCommand
A Tcl script to evaluate immediately before displaying the listbox.
The \fB\-postcommand\fR script may specify the \fB\-values\fR to display.
.OP \-state state State
One of \fBnormal\fR, \fBreadonly\fR, or \fBdisabled\fR.
In the \fBreadonly\fR state,
the value may not be edited directly, and 
the user can only select one of the \fB\-values\fR from the
dropdown list.
In the \fBnormal\fR state, 
the text field is directly editable.
In the \fBdisabled\fR state, no interaction is possible.
.OP \-textvariable textVariable TextVariable
Specifies the name of a global variable whose value is linked 
to the widget value.
Whenever the variable changes value the widget value is updated,
and vice versa.
.OP \-values values Values
Specifies the list of values to display in the drop-down listbox.
.OP \-width width Width
Specifies an integer value indicating the desired width of the entry window,
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'\"See \fIttk::widget(n)\fR.
'\".TP
'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
'\"Modify or query widget options.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBcurrent\fR ?\fInewIndex\fR?
If \fInewIndex\fR is supplied, sets the combobox value
to the element at position \fInewIndex\fR in the list of \fB\-values\fR
(in addition to integers, the \fBend\fR index is supported and indicates
the last element of the list).
Otherwise, returns the index of the current value in the list of
\fB\-values\fR or \fB\-1\fR if the current value does not appear in the list.
.TP
\fIpathName \fBget\fR
Returns the current value of the combobox.
'\".TP
'\"\fIpathName \fBidentify \fIx y\fR







|
|
<
<







62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
'\"See \fIttk::widget(n)\fR.
'\".TP
'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
'\"Modify or query widget options.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBcurrent\fR ?\fInewIndex\fR?
If \fInewIndex\fR is supplied, sets the combobox value 
to the element at position \fInewIndex\fR in the list of \fB\-values\fR.


Otherwise, returns the index of the current value in the list of
\fB\-values\fR or \fB\-1\fR if the current value does not appear in the list.
.TP
\fIpathName \fBget\fR
Returns the current value of the combobox.
'\".TP
'\"\fIpathName \fBidentify \fIx y\fR
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
.DE
.SH "VIRTUAL EVENTS"
.PP
The combobox widget generates a \fB<<ComboboxSelected>>\fR virtual event
when the user selects an element from the list of values.
If the selection action unposts the listbox,
this event is delivered after the listbox is unposted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::combobox\fP is \fBTCombobox\fP.
The \fBttk::combobox\fP uses the \fBentry\fP and
\fBlistbox\fP widgets internally.
The listbox frame has a class name of \fBComboboxPopdownFrame\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTCombobox\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-focusfill\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Can only be changed when using non-native and non-graphical themes.
.RE
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-postoffset\fP \fIpadding\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.RS
Text entry select background.
.RE
\fB\-selectforeground\fP \fIcolor\fP
.RS
Text entry select foreground.
.RE
.PP
The \fBttk::combobox\fP popdown listbox cannot be configured using
\fBttk::style\fP nor via the widget \fBconfigure\fP command.  The listbox
can be configured using the option database.
.PP
option add *TCombobox*Listbox.background \fIcolor\fP
.br
option add *TCombobox*Listbox.font \fIfont\fP
.br
option add *TCombobox*Listbox.foreground \fIcolor\fP
.br
option add *TCombobox*Listbox.selectBackground \fIcolor\fP
.br
option add *TCombobox*Listbox.selectForeground \fIcolor\fP
.PP
To configure a specific listbox (subject to future change):
.CS
set popdown [ttk::combobox::PopdownWindow .mycombobox]
$popdown.f.l configure \-font \fIfont\fP
.CE
.PP
\fBComboboxPopdownFrame\fP
styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n)
.SH KEYWORDS
choice, entry, list box, text box, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







106
107
108
109
110
111
112



















































































113
114
115
116
117
118
119
.DE
.SH "VIRTUAL EVENTS"
.PP
The combobox widget generates a \fB<<ComboboxSelected>>\fR virtual event
when the user selects an element from the list of values.
If the selection action unposts the listbox,
this event is delivered after the listbox is unposted.



















































































.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n)
.SH KEYWORDS
choice, entry, list box, text box, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_entry.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


39
40
41
42
43
44
45
46
47
48
49
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::entry n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::entry \- Editable text field widget
.SH SYNOPSIS
\fBttk::entry\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
An \fBttk::entry\fR widget displays a one-line text string and
allows that string to be edited by the user.
The value of the string may be linked to a Tcl variable
with the \fB\-textvariable\fR option.
Entry widgets support horizontal scrolling with the
standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command.
.SO ttk_widget
\-class	\-cursor
\-font	\-foreground
\-style
\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
A boolean value specifying whether or not
a selection in the widget should be linked to the X selection.
If the selection is exported, then selecting in the widget deselects
the current X selection, selecting outside the widget deselects any
widget selection, and the widget will respond to selection retrieval
requests when it has a selection.


.\" MAYBE: .OP \-insertbackground insertBackground Foreground
.\" MAYBE: .OP \-insertwidth insertWidth InsertWidth
.OP \-invalidcommand invalidCommand InvalidCommand
A script template to evaluate whenever the \fB\-validatecommand\fR returns 0.
See \fBVALIDATION\fR below for more information.
.OP \-justify justify Justify
Specifies how the text is aligned within the entry widget.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
.\" MAYBE: .OP \-selectbackground selectBackground Foreground
.\" MAYBE: .OP \-selectborderwidth selectBorderWidth BorderWidth
.\" MAYBE: .OP \-selectforeground selectForeground Background







|












|

|


|
<
<
|



|





>
>



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::entry n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::entry \- Editable text field widget
.SH SYNOPSIS
\fBttk::entry\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
An \fBttk::entry\fR widget displays a one-line text string and
allows that string to be edited by the user.
The value of the string may be linked to a Tcl variable 
with the \fB\-textvariable\fR option.
Entry widgets support horizontal scrolling with the 
standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command.
.SO ttk_widget
\-class	\-cursor	\-style


\-takefocus	\-xscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
A boolean value specifying whether or not 
a selection in the widget should be linked to the X selection.
If the selection is exported, then selecting in the widget deselects
the current X selection, selecting outside the widget deselects any
widget selection, and the widget will respond to selection retrieval
requests when it has a selection.
.\" MAYBE: .OP \-font font Font
.\" MAYBE: .OP \-foreground foreground Foreground
.\" MAYBE: .OP \-insertbackground insertBackground Foreground
.\" MAYBE: .OP \-insertwidth insertWidth InsertWidth
.OP \-invalidcommand invalidCommand InvalidCommand
A script template to evaluate whenever the \fBvalidateCommand\fR returns 0.
See \fBVALIDATION\fR below for more information.
.OP \-justify justify Justify
Specifies how the text is aligned within the entry widget.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
.\" MAYBE: .OP \-selectbackground selectBackground Foreground
.\" MAYBE: .OP \-selectborderwidth selectBorderWidth BorderWidth
.\" MAYBE: .OP \-selectforeground selectForeground Background
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
of the entry.
.OP \-state state State
Compatibility option; see \fIttk::widget(n)\fR for details.
Specifies one of three states for the entry,
\fBnormal\fR, \fBdisabled\fR, or \fBreadonly\fR.
See \fBWIDGET STATES\fR, below.
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value is linked
to the entry widget's contents.
Whenever the variable changes value, the widget's contents are updated,
and vice versa.
.OP \-validate validate Validate
Specifies the mode in which validation should operate:
\fBnone\fR, \fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
Default is \fBnone\fR, meaning that validation is disabled.







|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
of the entry.
.OP \-state state State
Compatibility option; see \fIttk::widget(n)\fR for details.
Specifies one of three states for the entry,
\fBnormal\fR, \fBdisabled\fR, or \fBreadonly\fR.
See \fBWIDGET STATES\fR, below.
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value is linked 
to the entry widget's contents.
Whenever the variable changes value, the widget's contents are updated,
and vice versa.
.OP \-validate validate Validate
Specifies the mode in which validation should operate:
\fBnone\fR, \fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
Default is \fBnone\fR, meaning that validation is disabled.
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font.
.\" Not in ttk: If the value is less than or equal to zero, the widget picks a
.\" Not in ttk: size just large enough to hold its current text.
.SH NOTES
.PP
A portion of the entry may be selected as described below.
If an entry is exporting its selection (see the \fB\-exportselection\fR
option), then it will observe the standard X11 protocols for handling the
selection;  entry selections are available as type \fBSTRING\fR.
Entries also observe the standard Tk rules for dealing with the
input focus.  When an entry has the input focus it displays an
\fIinsert cursor\fR to indicate where new characters will be
inserted.
.PP
Entries are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed;  commands described below
may be used to change the view in the window.  Entries use
the standard \fB\-xscrollcommand\fR mechanism for interacting with
scrollbars (see the description of the \fB\-xscrollcommand\fR option
for details).
.SH "INDICES"
.PP
Many of the \fBentry\fR widget commands take one or more indices as
arguments.  An index specifies a particular character in the entry's
string, in any of the following ways:
.IP \fInumber\fR







|











|
|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font.
.\" Not in ttk: If the value is less than or equal to zero, the widget picks a
.\" Not in ttk: size just large enough to hold its current text.
.SH NOTES
.PP
A portion of the entry may be selected as described below.
If an entry is exporting its selection (see the \fBexportSelection\fR
option), then it will observe the standard X11 protocols for handling the
selection;  entry selections are available as type \fBSTRING\fR.
Entries also observe the standard Tk rules for dealing with the
input focus.  When an entry has the input focus it displays an
\fIinsert cursor\fR to indicate where new characters will be
inserted.
.PP
Entries are capable of displaying strings that are too long to
fit entirely within the widget's window.  In this case, only a
portion of the string will be displayed;  commands described below
may be used to change the view in the window.  Entries use
the standard \fBxScrollCommand\fR mechanism for interacting with
scrollbars (see the description of the \fBxScrollCommand\fR option
for details).
.SH "INDICES"
.PP
Many of the \fBentry\fR widget commands take one or more indices as
arguments.  An index specifies a particular character in the entry's
string, in any of the following ways:
.IP \fInumber\fR
213
214
215
216
217
218
219
220
221
222
223
224







































225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
.RE
'\".TP
'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR?
'\"Modify or query the widget state.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBvalidate\fR
Force revalidation, independent of the conditions specified
by the \fB\-validate\fR option.
Returns 0 if validation fails, 1 if it succeeds.
Sets or clears the \fBinvalid\fR state accordingly.
See \fBVALIDATION\fR below for more details.







































.PP
The entry widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR	\fBidentify\fR
\fBinstate\fR	\fBstate\fR	\fBxview\fR
.DE
.SH VALIDATION
.PP
The \fB\-validate\fR, \fB\-validatecommand\fR, and \fB\-invalidcommand\fR
options are used to enable entry widget validation.
.SS "VALIDATION MODES"
.PP
There are two main validation modes: \fIprevalidation\fR,
in which the \fB\-validatecommand\fR is evaluated prior to each edit
and the return value is used to determine whether to accept
or reject the change;
and \fIrevalidation\fR, in which the \fB\-validatecommand\fR is
evaluated to determine whether the current value is valid.
.PP
The \fB\-validate\fR option determines when validation occurs;
it may be set to any of the following values:
.RS
.IP \fBnone\fR
Default.  This means validation will only occur when
specifically requested by the \fBvalidate\fR widget command.
.IP \fBkey\fR
The entry will be prevalidated prior to each edit
(specifically, whenever the \fBinsert\fR or \fBdelete\fR
widget commands are called).
If prevalidation fails, the edit is rejected.
.IP \fBfocus\fR
The entry is revalidated when the entry receives or loses focus.
.IP \fBfocusin\fR
The entry is revalidated when the entry receives focus.
.IP \fBfocusout\fR
The entry is revalidated when the entry loses focus.
.IP \fBall\fR
Validation is performed for all above conditions.
.RE
.PP
The \fB\-invalidcommand\fR is evaluated whenever
the \fB\-validatecommand\fR returns a false value.
.PP
The \fB\-validatecommand\fR and \fB\-invalidcommand\fR
may modify the entry widget's value
via the widget \fBinsert\fR or \fBdelete\fR commands,
or by setting the linked \fB\-textvariable\fR.
If either does so during prevalidation,
then the edit is rejected
regardless of the value returned by the \fB\-validatecommand\fR.
.PP
If \fB\-validatecommand\fR is empty (the default),
validation always succeeds.
.SS "VALIDATION SCRIPT SUBSTITUTIONS"
.PP
It is possible to perform percent substitutions on the
\fB\-validatecommand\fR and \fB\-invalidcommand\fR,
just as in a \fBbind\fR script.
The following substitutions are recognized:
.RS
.IP \fB%d\fR
Type of action: 1 for \fBinsert\fR prevalidation,
0 for \fBdelete\fR prevalidation,
or \-1 for revalidation.
.IP \fB%i\fR
Index of character string to be inserted/deleted, if any, otherwise \-1.
.IP \fB%P\fR
In prevalidation, the new value of the entry if the edit is accepted.
In revalidation, the current value of the entry.







|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|









|

|






|



|




















|


|



|





|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
.RE
'\".TP
'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR?
'\"Modify or query the widget state.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBvalidate\fR
Force revalidation, independent of the conditions specified 
by the \fB\-validate\fR option.
Returns 0 if validation fails, 1 if it succeeds.
Sets or clears the \fBinvalid\fR state accordingly.
See \fBVALIDATION\fR below for more details.
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the entry's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR
Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
.RE
.PP
The entry widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR	\fBidentify\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH VALIDATION
.PP
The \fB\-validate\fR, \fB\-validatecommand\fR, and \fB\-invalidcommand\fR
options are used to enable entry widget validation.
.SS "VALIDATION MODES"
.PP
There are two main validation modes: \fIprevalidation\fR,
in which the \fB\-validatecommand\fR is evaluated prior to each edit
and the return value is used to determine whether to accept 
or reject the change;
and \fIrevalidation\fR, in which the \fB\-validatecommand\fR is 
evaluated to determine whether the current value is valid.
.PP
The \fB\-validate\fR option determines when validation occurs;
it may be set to any of the following values:
.RS
.IP \fBnone\fR
Default.  This means validation will only occur when 
specifically requested by the \fBvalidate\fR widget command.
.IP \fBkey\fR
The entry will be prevalidated prior to each edit
(specifically, whenever the \fBinsert\fR or \fBdelete\fR 
widget commands are called).
If prevalidation fails, the edit is rejected.
.IP \fBfocus\fR
The entry is revalidated when the entry receives or loses focus.
.IP \fBfocusin\fR
The entry is revalidated when the entry receives focus.
.IP \fBfocusout\fR
The entry is revalidated when the entry loses focus.
.IP \fBall\fR
Validation is performed for all above conditions.
.RE
.PP
The \fB\-invalidcommand\fR is evaluated whenever
the \fB\-validatecommand\fR returns a false value.
.PP
The \fB\-validatecommand\fR and \fB\-invalidcommand\fR
may modify the entry widget's value
via the widget \fBinsert\fR or \fBdelete\fR commands,
or by setting the linked \fB\-textvariable\fR.
If either does so during prevalidation,
then the edit is rejected 
regardless of the value returned by the \fB\-validatecommand\fR.
.PP
If \fB\-validatecommand\fR is empty (the default), 
validation always succeeds.
.SS "VALIDATION SCRIPT SUBSTITUTIONS"
.PP
It is possible to perform percent substitutions on the 
\fB\-validatecommand\fR and \fB\-invalidcommand\fR,
just as in a \fBbind\fR script.
The following substitutions are recognized:
.RS
.IP \fB%d\fR
Type of action: 1 for \fBinsert\fR prevalidation, 
0 for \fBdelete\fR prevalidation,
or \-1 for revalidation.
.IP \fB%i\fR
Index of character string to be inserted/deleted, if any, otherwise \-1.
.IP \fB%P\fR
In prevalidation, the new value of the entry if the edit is accepted.
In revalidation, the current value of the entry.
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
.IP \fB%W\fR
The name of the entry widget.
.RE
.SS "DIFFERENCES FROM TK ENTRY WIDGET VALIDATION"
.PP
The standard Tk entry widget automatically disables validation
(by setting \fB\-validate\fR to \fBnone\fR)
if the \fB\-validatecommand\fR or \fB\-invalidcommand\fR modifies
the entry's value.
The Tk themed entry widget only disables validation if one
of the validation scripts raises an error, or if \fB\-validatecommand\fR
does not return a valid boolean value.
(Thus, it is not necessary to re-enable validation after
modifying the entry value in a validation script).
.PP
In addition, the standard entry widget invokes validation whenever the linked
\fB\-textvariable\fR is modified; the Tk themed entry widget does not.
.SH "DEFAULT BINDINGS"
.PP
The entry widget's default bindings enable the following behavior.
In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or
.QW _
characters, or any single character other than these.
.IP \0\(bu 4
Clicking mouse button 1 positions the insert cursor







|




|






|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
.IP \fB%W\fR
The name of the entry widget.
.RE
.SS "DIFFERENCES FROM TK ENTRY WIDGET VALIDATION"
.PP
The standard Tk entry widget automatically disables validation
(by setting \fB\-validate\fR to \fBnone\fR)
if the \fB\-validatecommand\fR or \fB\-invalidcommand\fR modifies 
the entry's value.
The Tk themed entry widget only disables validation if one
of the validation scripts raises an error, or if \fB\-validatecommand\fR
does not return a valid boolean value.
(Thus, it is not necessary to re-enable validation after 
modifying the entry value in a validation script).
.PP
In addition, the standard entry widget invokes validation whenever the linked
\fB\-textvariable\fR is modified; the Tk themed entry widget does not.
.SH "DEFAULT BINDINGS"
.PP
The entry widget's default bindings enable the following behavior.  
In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or
.QW _
characters, or any single character other than these.
.IP \0\(bu 4
Clicking mouse button 1 positions the insert cursor
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
.IP \0\(bu 4
Clicking mouse button 1 with the Control key down will position the
insert cursor in the entry without affecting the selection.
.IP \0\(bu 4
If any normal printing characters are typed in an entry, they are
inserted at the point of the insert cursor.
.IP \0\(bu 4
The view in the entry can be adjusted by dragging with the middle
mouse button (button 2, or button 3 in TkAqua). If the middle mouse
button is clicked without moving the mouse, the selection is copied
into the entry at the position of the mouse cursor.
.IP \0\(bu 4
If the mouse is dragged out of the entry on the left or right sides
while button 1 is pressed, the entry will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP \0\(bu 4
The Left and Right keys move the insert cursor one character to the







|
<
|
|







388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
.IP \0\(bu 4
Clicking mouse button 1 with the Control key down will position the
insert cursor in the entry without affecting the selection.
.IP \0\(bu 4
If any normal printing characters are typed in an entry, they are
inserted at the point of the insert cursor.
.IP \0\(bu 4
The view in the entry can be adjusted by dragging with mouse button 2.

If mouse button 2 is clicked without moving the mouse, the selection
is copied into the entry at the position of the mouse cursor.
.IP \0\(bu 4
If the mouse is dragged out of the entry on the left or right sides
while button 1 is pressed, the entry will automatically scroll to
make more text visible (if there is more text off-screen on the side
where the mouse left the window).
.IP \0\(bu 4
The Left and Right keys move the insert cursor one character to the
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
.IP \0\(bu 4
Control-d deletes the character to the right of the insert cursor.
.IP \0\(bu 4
Control-k deletes all the characters to the right of the insertion
cursor.
.SH "WIDGET STATES"
.PP
In the \fBdisabled\fR state,
the entry cannot be edited and the text cannot be selected.
In the \fBreadonly\fR state,
no insert cursor is displayed and
the entry cannot be edited
(specifically: the \fBinsert\fR and \fBdelete\fR commands have no effect).
The \fBdisabled\fR state is the same as \fBreadonly\fR,
and in addition text cannot be selected.
.PP
Note that changes to the linked \fB\-textvariable\fR will
still be reflected in the entry, even if it is disabled or readonly.
.PP
Typically, the text is
.QW grayed-out
in the \fBdisabled\fR state,
and a different background is used in the \fBreadonly\fR state.
.PP
The entry widget sets the \fBinvalid\fR state if revalidation fails,
and clears it whenever validation succeeds.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::entry\fP is \fBTEntry\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP.
.PP
\fBTEntry\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.RS
For backwards compatibility, when using the aqua theme (for macOS), this
option behaves as an alias for the \fB\-fieldbackground\fP provided that no
value is specified for \fB\-fieldbackground\fP. Otherwise it is ignored.
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Some themes use a graphical background and their field background colors cannot be changed.
.RE
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectborderwidth\fP \fIamount\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), entry(n)
.SH KEYWORDS
entry, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:







|


|
|

|


|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463













































464
465
466
467
468
469
470
.IP \0\(bu 4
Control-d deletes the character to the right of the insert cursor.
.IP \0\(bu 4
Control-k deletes all the characters to the right of the insertion
cursor.
.SH "WIDGET STATES"
.PP
In the \fBdisabled\fR state, 
the entry cannot be edited and the text cannot be selected.
In the \fBreadonly\fR state,
no insert cursor is displayed and 
the entry cannot be edited 
(specifically: the \fBinsert\fR and \fBdelete\fR commands have no effect).
The \fBdisabled\fR state is the same as \fBreadonly\fR, 
and in addition text cannot be selected.
.PP
Note that changes to the linked \fB\-textvariable\fR will 
still be reflected in the entry, even if it is disabled or readonly.
.PP
Typically, the text is
.QW grayed-out
in the \fBdisabled\fR state,
and a different background is used in the \fBreadonly\fR state. 
.PP
The entry widget sets the \fBinvalid\fR state if revalidation fails,
and clears it whenever validation succeeds.













































.SH "SEE ALSO"
ttk::widget(n), entry(n)
.SH KEYWORDS
entry, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_frame.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::frame n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::frame \- Simple container widget
.SH SYNOPSIS
\fBttk::frame\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::frame\fR widget is a container, used to group other widgets
together.
.SO ttk_widget
\-class	\-cursor	\-padding	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-borderwidth borderWidth BorderWidth
The desired width of the widget border.  Defaults to 0.
May be ignored depending on the theme used.
.OP \-relief relief Relief
One of the standard Tk border styles:
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
\fBsolid\fR, or \fBsunken\fR.
Defaults to \fBflat\fR.


.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "NOTES"
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used
to change this.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::frame\fP is \fBTFrame\fP.
.PP
\fBTFrame\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH BINDINGS
.PP
When a new \fBttk::frame\fR is created, it has no default event bindings;
\fBttk::frame\fRs are not intended to be interactive.
.SH "SEE ALSO"
ttk::widget(n), ttk::labelframe(n), frame(n)
.SH "KEYWORDS"
widget, frame, container
'\" Local Variables:
'\" mode: nroff
'\" End:





|













|
|



|
<

|



>
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49



















50
51
52
53
54
55
56
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::frame n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::frame \- Simple container widget
.SH SYNOPSIS
\fBttk::frame\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::frame\fR widget is a container, used to group other widgets
together.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-borderwidth borderWidth BorderWidth
The desired width of the widget border.  Defaults to 0. 

.OP \-relief relief Relief
One of the standard Tk border styles: 
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
\fBsolid\fR, or \fBsunken\fR.
Defaults to \fBflat\fR.
.OP \-padding padding Padding
Additional padding to include inside the border.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "NOTES"
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used
to change this.



















.SH "SEE ALSO"
ttk::widget(n), ttk::labelframe(n), frame(n)
.SH "KEYWORDS"
widget, frame, container
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_image.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_image n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_image \- Define an element based on an image
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBimage\fR \fIimageSpec\fR ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fIimage\fR element factory creates a new element
in the current theme whose visual appearance is determined
by Tk images.
\fIimageSpec\fP is a list of one or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR
pairs specifying other images to use when the element is
in a particular state or combination of states.
.SH OPTIONS
.PP
Valid \fIoptions\fR are:
.TP
\fB\-border\fR \fIpadding\fR
\fIpadding\fR is a list of up to four integers, specifying
the left, top, right, and bottom borders, respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right border;
a list of two numbers specify the horizontal and the vertical border;
a single number specifies the same border all the way around the element.
See \fBIMAGE STRETCHING\fR, below.
.TP
\fB\-height \fIheight\fR
Specifies a minimum height for the element.
If less than zero, the base image's height is used as a default.
.TP
\fB\-padding\fR \fIpadding\fR
Specifies the element's interior padding.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
Defaults to \fB\-border\fR if not specified.
.TP
\fB\-sticky\fR \fIspec\fR
Specifies how the image is placed within the final parcel.
\fIspec\fR contains zero or more characters
.QW n ,
.QW s ,
.QW w ,
or
.QW e .
.TP
\fB\-width \fIwidth\fR
Specifies a minimum width for the element.
If less than zero, the base image's width is used as a default.
.SH "IMAGE STRETCHING"
.PP
If the element's allocated parcel is larger than the image,
the image will be placed in the parcel based on the \fB\-sticky\fR option.
If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR)
or vertically (\fB\-sticky ns\fR),
subregions of the image are replicated to fill the parcel
based on the \fB\-border\fR option.
The \fB\-border\fR divides the image into 9 regions:
four fixed corners, top and left edges (which may be tiled horizontally),
left and right edges (which may be tiled vertically),
and the central area (which may be tiled in both directions).
.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo \-file button.png]





|












|












<
<
<
<
<
<
<







|
<
<
<
<
<
<
<
<
<
|















|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31







32
33
34
35
36
37
38
39









40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk_image n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_image \- Define an element based on an image
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBimage\fR \fIimageSpec\fR ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fIimage\fR element factory creates a new element
in the current theme whose visual appearance is determined
by Tk images. 
\fIimageSpec\fP is a list of one or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR
pairs specifying other images to use when the element is
in a particular state or combination of states.
.SH OPTIONS
.PP
Valid \fIoptions\fR are:
.TP
\fB\-border\fR \fIpadding\fR
\fIpadding\fR is a list of up to four integers, specifying
the left, top, right, and bottom borders, respectively.







See \fBIMAGE STRETCHING\fR, below.
.TP
\fB\-height \fIheight\fR
Specifies a minimum height for the element.
If less than zero, the base image's height is used as a default.
.TP
\fB\-padding\fR \fIpadding\fR
Specifies the element's interior padding.  Defaults to 









\fB\-border\fR if not specified.
.TP
\fB\-sticky\fR \fIspec\fR
Specifies how the image is placed within the final parcel.
\fIspec\fR contains zero or more characters
.QW n ,
.QW s ,
.QW w ,
or
.QW e .
.TP
\fB\-width \fIwidth\fR
Specifies a minimum width for the element.
If less than zero, the base image's width is used as a default.
.SH "IMAGE STRETCHING"
.PP
If the element's allocated parcel is larger than the image, 
the image will be placed in the parcel based on the \fB\-sticky\fR option.
If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR)
or vertically (\fB\-sticky ns\fR),
subregions of the image are replicated to fill the parcel
based on the \fB\-border\fR option.
The \fB\-border\fR divides the image into 9 regions: 
four fixed corners, top and left edges (which may be tiled horizontally),
left and right edges (which may be tiled vertically),
and the central area (which may be tiled in both directions).
.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo \-file button.png]

Changes to doc/ttk_intro.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::intro n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::intro \- Introduction to the Tk theme engine
.BE
.SH "OVERVIEW"
.PP
The Tk themed widget set is based on a revised and enhanced version
of TIP #48 (https://tip.tcl-lang.org/48) specified style engine.
The main concepts are described below.
The basic idea is to separate, to the extent possible,
the code implementing a widget's behavior from
the code implementing its appearance.
Widget class bindings are primarily responsible for
maintaining the widget state and invoking callbacks;
all aspects of the widget's appearance are controlled by the style of
the widget (i.e. the style of the elements of the widget).
.SH "THEMES"
.PP
A \fItheme\fR is a collection of elements and styles
that determine the look and feel of the widget set.
Themes can be used to:
.IP \(bu
isolate platform differences (X11 vs. classic Windows vs. XP vs. Aqua ...)
.IP \(bu
adapt to display limitations (low-color, grayscale, monochrome, tiny screens)
.IP \(bu





|









|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::intro n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::intro \- Introduction to the Tk theme engine
.BE
.SH "OVERVIEW"
.PP
The Tk themed widget set is based on a revised and enhanced version
of TIP #48 (http://tip.tcl.tk/48) specified style engine.
The main concepts are described below.
The basic idea is to separate, to the extent possible,
the code implementing a widget's behavior from
the code implementing its appearance.
Widget class bindings are primarily responsible for
maintaining the widget state and invoking callbacks;
all aspects of the widget's appearance are controlled by the style of
the widget (i.e. the style of the elements of the widget).
.SH "THEMES"
.PP
A \fItheme\fR is a collection of elements and styles 
that determine the look and feel of the widget set.
Themes can be used to:
.IP \(bu
isolate platform differences (X11 vs. classic Windows vs. XP vs. Aqua ...)
.IP \(bu
adapt to display limitations (low-color, grayscale, monochrome, tiny screens)
.IP \(bu
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
.PP
An \fIelement\fR displays an individual part of a widget.
For example, a vertical scrollbar widget contains \fBuparrow\fR,
\fBdownarrow\fR, \fBtrough\fR and \fBslider\fR elements.
.PP
Element names use a recursive dotted notation.
For example, \fBuparrow\fR identifies a generic arrow element,
and \fBScrollbar.uparrow\fR and \fBCombobox.uparrow\fR identify
widget-specific elements.
When looking for an element, the style engine looks for
the specific name first, and if an element of that name is
not found it looks for generic elements by stripping off
successive leading components of the element name.
.PP
Like widgets, elements have \fIoptions\fR which
specify what to display and how to display it.
For example, the \fBtext\fR element
(which displays a text string) has
\fB\-text\fR, \fB\-font\fR, \fB\-foreground\fR, \fB\-background\fR,
\fB\-underline\fR, and \fB\-width\fR options.
The value of an element option is taken from (in precedence order):
.IP \(bu
an option of the same name and type in the widget containing the element;
.IP \(bu
a dynamic setting specified by \fBstyle map\fR and the current state;
.IP \(bu
the default setting specified by \fBstyle configure\fR; or
.IP \(bu







|








|

|

|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
.PP
An \fIelement\fR displays an individual part of a widget.
For example, a vertical scrollbar widget contains \fBuparrow\fR,
\fBdownarrow\fR, \fBtrough\fR and \fBslider\fR elements.
.PP
Element names use a recursive dotted notation.
For example, \fBuparrow\fR identifies a generic arrow element,
and \fBScrollbar.uparrow\fR and \fBCombobox.uparrow\fR identify 
widget-specific elements.
When looking for an element, the style engine looks for
the specific name first, and if an element of that name is
not found it looks for generic elements by stripping off
successive leading components of the element name.
.PP
Like widgets, elements have \fIoptions\fR which
specify what to display and how to display it.
For example, the \fBtext\fR element 
(which displays a text string) has
\fB\-text\fR, \fB\-font\fR, \fB\-foreground\fR, \fB\-background\fR, 
\fB\-underline\fR, and \fB\-width\fR options.
The value of an element option is taken from:
.IP \(bu
an option of the same name and type in the widget containing the element;
.IP \(bu
a dynamic setting specified by \fBstyle map\fR and the current state;
.IP \(bu
the default setting specified by \fBstyle configure\fR; or
.IP \(bu
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
For example, the layout for a horizontal scrollbar is:
.PP
.CS
ttk::\fBstyle layout\fR Horizontal.TScrollbar {
    Scrollbar.trough \-children {
	Scrollbar.leftarrow \-side left \-sticky w
	Scrollbar.rightarrow \-side right \-sticky e
	Scrollbar.thumb \-sticky ew
    }
}
.CE
.PP
By default, the layout for a widget is the same as its class name.
Some widgets may override this (for example, the \fBttk::scrollbar\fR
widget chooses different layouts based on the \fB\-orient\fR option).
.SH "STATES"
.PP
In standard Tk, many widgets have a \fB\-state\fR option
which (in most cases) is either \fBnormal\fR or \fBdisabled\fR.
Some widgets support additional states, such
as the \fBentry\fR widget which has a \fBreadonly\fR state
and the various flavors of buttons which have \fBactive\fR state.
.PP
The themed Tk widgets generalizes this idea:
every widget has a bitmap of independent state flags.
Widget state flags include \fBactive\fR, \fBdisabled\fR,
\fBpressed\fR, \fBfocus\fR, etc.,
(see \fIttk::widget(n)\fR for the full list of state flags).
.PP
Instead of a \fB\-state\fR option, every widget now has
a \fBstate\fR widget command which is used to set or query
the state.
A \fIstate specification\fR is a list of symbolic state names
indicating which bits are set, each optionally prefixed with an
exclamation point indicating that the bit is cleared instead.
.PP
For example, the class bindings for the \fBttk::button\fR
widget are:
.PP
.CS
bind TButton <Enter>		{ %W state active }
bind TButton <Leave>		{ %W state !active }
bind TButton <Button-1>		{ %W state pressed }
bind TButton <Button1-Leave>	{ %W state !pressed }
bind TButton <Button1-Enter>	{ %W state pressed }
bind TButton <ButtonRelease-1>	\e
    { %W instate {pressed} { %W state !pressed ; %W invoke } }
.CE
.PP
This specifies that the widget becomes \fBactive\fR when
the pointer enters the widget, and inactive when it leaves.
Similarly it becomes \fBpressed\fR when the mouse button is pressed,
and \fB!pressed\fR on the ButtonRelease event.
In addition, the button unpresses if
pointer is dragged outside the widget while Button-1 is held down,
and represses if it's dragged back in.
Finally, when the mouse button is released, the widget's
\fB\-command\fR is invoked, but only if the button is currently
in the \fBpressed\fR state.
(The actual bindings are a little more complicated than the above,
but not by much).
'\" Note to self: rewrite that paragraph.  It's horrible.
.SH "STYLES"
.PP
Each widget is associated with a \fIstyle\fR,
which specifies values for element options.
Style names use a recursive dotted notation like layouts and elements;
by default, widgets use the class name to look up a style in the current theme.
For example:
.PP
.CS
ttk::\fBstyle configure\fR TButton \e
	\-background #d9d9d9 \e
	\-foreground black \e
	\-relief raised \e
	;
.CE
.PP
Many elements are displayed differently depending on the widget state.
For example, buttons have a different background when they are active,
a different foreground when disabled, and a different relief when pressed.
The \fBstyle map\fR command specifies dynamic option settings
for a particular style:
.PP
.CS
ttk::\fBstyle map\fR TButton \e







|


















|


|



|








|










|










|













|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
For example, the layout for a horizontal scrollbar is:
.PP
.CS
ttk::\fBstyle layout\fR Horizontal.TScrollbar {
    Scrollbar.trough \-children {
	Scrollbar.leftarrow \-side left \-sticky w
	Scrollbar.rightarrow \-side right \-sticky e
	Scrollbar.thumb \-side left \-expand true \-sticky ew
    }
}
.CE
.PP
By default, the layout for a widget is the same as its class name.
Some widgets may override this (for example, the \fBttk::scrollbar\fR
widget chooses different layouts based on the \fB\-orient\fR option).
.SH "STATES"
.PP
In standard Tk, many widgets have a \fB\-state\fR option
which (in most cases) is either \fBnormal\fR or \fBdisabled\fR.
Some widgets support additional states, such
as the \fBentry\fR widget which has a \fBreadonly\fR state
and the various flavors of buttons which have \fBactive\fR state.
.PP
The themed Tk widgets generalizes this idea:
every widget has a bitmap of independent state flags.
Widget state flags include \fBactive\fR, \fBdisabled\fR,
\fBpressed\fR, \fBfocus\fR, etc., 
(see \fIttk::widget(n)\fR for the full list of state flags).
.PP
Instead of a \fB\-state\fR option, every widget now has 
a \fBstate\fR widget command which is used to set or query
the state.
A \fIstate specification\fR is a list of symbolic state names
indicating which bits are set, each optionally prefixed with an 
exclamation point indicating that the bit is cleared instead.
.PP
For example, the class bindings for the \fBttk::button\fR
widget are:
.PP
.CS
bind TButton <Enter>		{ %W state active }
bind TButton <Leave>		{ %W state !active }
bind TButton <ButtonPress-1>	{ %W state pressed }
bind TButton <Button1-Leave>	{ %W state !pressed }
bind TButton <Button1-Enter>	{ %W state pressed }
bind TButton <ButtonRelease-1>	\e
    { %W instate {pressed} { %W state !pressed ; %W invoke } }
.CE
.PP
This specifies that the widget becomes \fBactive\fR when
the pointer enters the widget, and inactive when it leaves.
Similarly it becomes \fBpressed\fR when the mouse button is pressed,
and \fB!pressed\fR on the ButtonRelease event.
In addition, the button unpresses if 
pointer is dragged outside the widget while Button-1 is held down,
and represses if it's dragged back in.
Finally, when the mouse button is released, the widget's
\fB\-command\fR is invoked, but only if the button is currently
in the \fBpressed\fR state.
(The actual bindings are a little more complicated than the above,
but not by much).
'\" Note to self: rewrite that paragraph.  It's horrible.
.SH "STYLES"
.PP
Each widget is associated with a \fIstyle\fR, 
which specifies values for element options.
Style names use a recursive dotted notation like layouts and elements;
by default, widgets use the class name to look up a style in the current theme.
For example:
.PP
.CS
ttk::\fBstyle configure\fR TButton \e
	\-background #d9d9d9 \e
	\-foreground black \e
	\-relief raised \e
	;
.CE
.PP
Many elements are displayed differently depending on the widget state.  
For example, buttons have a different background when they are active,
a different foreground when disabled, and a different relief when pressed.
The \fBstyle map\fR command specifies dynamic option settings
for a particular style:
.PP
.CS
ttk::\fBstyle map\fR TButton \e

Changes to doc/ttk_label.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27






28
29
30


















31
32
33
34
35
36



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::label n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::label \- Display a text string and/or image
.SH SYNOPSIS
\fBttk::label\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable
to automatically change the displayed text.
.SO ttk_widget
\-anchor	\-class	\-compound	\-cursor
\-font	\-foreground
\-image	\-justify	\-padding	\-state	\-style	\-takefocus
\-text	\-textvariable	\-underline
\-width	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"






.OP \-background frameColor FrameColor
The widget's background color.
If unspecified, the theme default is used.


















.OP \-relief relief Relief
.\" Rewrite this:
Specifies the 3-D effect desired for the widget border.
Valid values are
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR,
and \fBsunken\fR.



.OP \-wraplength wrapLength WrapLength
Specifies the maximum line length (in pixels).
If this option is less than or equal to zero,
then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::label\fP is \fBTLabel\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabel\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), label(n)
'\" Local Variables:
'\" mode: nroff
'\" End:





|











|


|
<
|

|


>
>
>
>
>
>

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|

>
>
>











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73





















74
75
76
77
78
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::label n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::label \- Display a text string and/or image
.SH SYNOPSIS
\fBttk::label\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable 
to automatically change the displayed text.
.SO ttk_widget
\-class	\-compound	\-cursor

\-image	\-style	\-takefocus
\-text	\-textvariable	\-underline
\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-anchor anchor Anchor
Specifies how the information in the widget is positioned
relative to the inner margins.  Legal values are
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR.
See also \fB\-justify\fR.
.OP \-background frameColor FrameColor
The widget's background color.  
If unspecified, the theme default is used.
.OP \-font font Font
Font to use for label text.
.OP \-foreground textColor TextColor
The widget's foreground color.
If unspecified, the theme default is used.
.OP \-justify justify Justify
If there are multiple lines of text, specifies how
the lines are laid out relative to one another.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
See also \fB\-anchor\fR.
.OP \-padding padding Padding
Specifies the amount of extra space to allocate for the widget.
The padding is a list of up to four length specifications 
\fIleft top right bottom\fR.
If fewer than four elements are specified, 
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and 
\fItop\fR defaults to \fIleft\fR.
.OP \-relief relief Relief
.\" Rewrite this:
Specifies the 3-D effect desired for the widget border.
Valid values are
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, 
and \fBsunken\fR.
.OP \-text text Text
Specifies a text string to be displayed inside the widget
(unless overridden by \fB\-textvariable\fR).
.OP \-wraplength wrapLength WrapLength
Specifies the maximum line length (in pixels).
If this option is less than or equal to zero,
then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.





















.SH "SEE ALSO"
ttk::widget(n), label(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_labelframe.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46










47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62




63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::labelframe n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::labelframe \- Container widget with optional label
.SH SYNOPSIS
\fBttk::labelframe\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::labelframe\fR widget is a container used to group other widgets
together.  It has an optional label, which may be a plain text string or
another widget.
.SO ttk_widget
\-class	\-cursor	\-padding	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.\" XXX: Currently included, but may go away:
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
.\" XXX: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
.\" XXX: \fBsolid\fR, or \fBsunken\fR.
.\" XXX: Default is theme-dependent.
.OP \-height height Height
If specified, the widget's requested height in pixels.
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.OP \-labelanchor labelAnchor LabelAnchor
Specifies where to place the label.
Allowed values are (clockwise from the top upper left corner):
\fBnw\fR, \fBn\fR, \fBne\fR, \fBen\fR, \fBe\fR, \fBes\fR,
\fBse\fR, \fBs\fR,\fBsw\fR, \fBws\fR, \fBw\fR and \fBwn\fR.
The default value is theme-dependent.
.\" Alternate explanation: The first character must be one of n, s, e, or w
.\" and specifies which side the label should be placed on;
.\" the remaining characters specify how the label is aligned on that side.
.\" NOTE: Now allows other values as well; leave this undocumented for now










.OP \-labelwidget labelWidget LabelWidget
The name of a widget to use for the label.
If set, overrides the \fB\-text\fR option.
The \fB\-labelwidget\fR must be a child of the \fBlabelframe\fR widget
or one of the \fBlabelframe\fR's ancestors, and must belong to the
same top-level widget as the \fBlabelframe\fR.
.OP \-text text Text
Specifies the text of the label.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to
underline in the text string.
The underlined character is used for mnemonic activation.
Mnemonic activation for a \fBttk::labelframe\fR
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.
.OP \-width width Width
If specified, the widget's requested width in pixels.




.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP.
The text label
has a class of \fBTLabelframe.Label\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabelframe\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-labelmargins\fP \fIamount\fP
.br
\fB\-labeloutside\fP \fIboolean\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
\fBTLabelframe.Label\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::frame(n), labelframe(n)
.SH "KEYWORDS"
widget, frame, container, label, groupbox
'\" Local Variables:
'\" mode: nroff
'\" End:





|














|
|


|







<
<
<
<

|








>
>
>
>
>
>
>
>
>
>






<
<
<
<
<
<
<
<


>
>
>
>





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58








59
60
61
62
63
64
65
66
67
68
69








































70
71
72
73
74
75
76
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::labelframe n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::labelframe \- Container widget with optional label
.SH SYNOPSIS
\fBttk::labelframe\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::labelframe\fR widget is a container used to group other widgets
together.  It has an optional label, which may be a plain text string or
another widget.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.\" XXX: Currently included, but may go away: 
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
.\" XXX: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
.\" XXX: \fBsolid\fR, or \fBsunken\fR.
.\" XXX: Default is theme-dependent.




.OP \-labelanchor labelAnchor LabelAnchor
Specifies where to place the label.  
Allowed values are (clockwise from the top upper left corner):
\fBnw\fR, \fBn\fR, \fBne\fR, \fBen\fR, \fBe\fR, \fBes\fR,
\fBse\fR, \fBs\fR,\fBsw\fR, \fBws\fR, \fBw\fR and \fBwn\fR.
The default value is theme-dependent.
.\" Alternate explanation: The first character must be one of n, s, e, or w
.\" and specifies which side the label should be placed on;
.\" the remaining characters specify how the label is aligned on that side.
.\" NOTE: Now allows other values as well; leave this undocumented for now
.OP \-text text Text
Specifies the text of the label.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to 
underline in the text string.
The underlined character is used for mnemonic activation.  
Mnemonic activation for a \fBttk::labelframe\fR 
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.
.OP \-padding padding Padding
Additional padding to include inside the border.
.OP \-labelwidget labelWidget LabelWidget
The name of a widget to use for the label.
If set, overrides the \fB\-text\fR option.
The \fB\-labelwidget\fR must be a child of the \fBlabelframe\fR widget
or one of the \fBlabelframe\fR's ancestors, and must belong to the
same top-level widget as the \fBlabelframe\fR.








.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.








































.SH "SEE ALSO"
ttk::widget(n), ttk::frame(n), labelframe(n)
.SH "KEYWORDS"
widget, frame, container, label, groupbox
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_menubutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::menubutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::menubutton \- Widget that pops down a menu when pressed
.SH SYNOPSIS
\fBttk::menubutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::menubutton\fR widget displays a textual label and/or image,
and displays a menu when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-direction direction Direction
Specifies where the menu is to be popped up relative
to the menubutton.
One of: \fBabove\fR, \fBbelow\fR, \fBleft\fR, \fBright\fR,
or \fBflush\fR.  The default is \fBbelow\fR.
\fBflush\fR pops the menu up directly over the menubutton.
.OP \-menu menu Menu
Specifies the path name of the menu associated with the menubutton.
To be on the safe side, the menu ought to be a direct child of the
menubutton.
.\" not documented: may go away:
.\" .OP \-anchor anchor Anchor
.\" .OP \-padding padding Pad
.SH "WIDGET COMMAND"
.PP
Menubutton widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTMenubutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), menu(n), menubutton(n)
.SH "KEYWORDS"
widget, button, menu
'\" Local Variables:
'\" mode: nroff
'\" End:





|




















|
|

|










|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47





























48
49
50
51
52
53
54
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::menubutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::menubutton \- Widget that pops down a menu when pressed
.SH SYNOPSIS
\fBttk::menubutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::menubutton\fR widget displays a textual label and/or image,
and displays a menu when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-direction direction Direction
Specifies where the menu is to be popped up relative 
to the menubutton.  
One of: \fBabove\fR, \fBbelow\fR, \fBleft\fR, \fBright\fR,
or \fBflush\fR.  The default is \fBbelow\fR.  
\fBflush\fR pops the menu up directly over the menubutton.
.OP \-menu menu Menu
Specifies the path name of the menu associated with the menubutton.
To be on the safe side, the menu ought to be a direct child of the
menubutton.
.\" not documented: may go away:
.\" .OP \-anchor anchor Anchor
.\" .OP \-padding padding Pad
.SH "WIDGET COMMAND"
.PP
Menubutton widgets support the standard 
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR 
methods.  No other widget methods are used.
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.





























.SH "SEE ALSO"
ttk::widget(n), menu(n), menubutton(n)
.SH "KEYWORDS"
widget, button, menu
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_notebook.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::notebook n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::notebook \- Multi-paned container widget
.SH SYNOPSIS
.nf
\fBttk::notebook\fR \fIpathname \fR?\fIoptions...\fR?
.br
\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::notebook\fR widget manages a collection of windows
and displays a single one at a time.
Each content window is associated with a \fItab\fR,
which the user may select to change the currently-displayed window.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-height height Height
If present and greater than zero,
specifies the desired height of the pane area
(not including internal padding or tabs).
Otherwise, the maximum height of all panes is used.
.OP \-padding padding Padding
Specifies the amount of extra space to add around the outside
of the notebook.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-width width Width
If present and greater than zero,
specifies the desired width of the pane area
(not including internal padding).
Otherwise, the maximum width of all panes is used.
.SH "TAB OPTIONS"
The following options may be specified for individual notebook panes:
.OP \-state state State
Either \fBnormal\fR, \fBdisabled\fR or \fBhidden\fR.
If \fBdisabled\fR, then the tab is not selectable.
If \fBhidden\fR, then the tab is not shown.
.OP \-sticky sticky Sticky
Specifies how the content window is positioned within the pane area.
Value is a string containing zero or more of the characters
\fBn, s, e,\fR or \fBw\fR.
Each letter refers to a side (north, south, east, or west)
that the content window will
.QW stick
to, as per the \fBgrid\fR geometry manager.
.OP \-padding padding Padding
Specifies the amount of extra space to add between the notebook and this pane.
Syntax is the same as for the widget \fB\-padding\fR option.
.OP \-text text Text
Specifies a string to be displayed in the tab.
.OP \-image image Image
Specifies an image to display in the tab.
See \fIttk_widget(n)\fR for details.
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
See \fIlabel(n)\fR for legal values.
.OP \-underline underline Underline
Specifies the integer index (0-based) of a character to underline
in the text string.
The underlined character is used for mnemonic activation
if \fBttk::notebook::enableTraversal\fR is called.
.SH "TAB IDENTIFIERS"
The \fItabid\fR argument to the following commands may take
any of the following forms:
.IP \(bu
An integer between zero and the number of tabs;
.IP \(bu
The name of a content window;
.IP \(bu
A positional specification of the form
.QW @\fIx\fR,\fIy\fR ,
which identifies the tab
.IP \(bu
The literal string
.QW \fBcurrent\fR ,
which identifies the currently-selected tab; or:
.IP \(bu
The literal string
.QW \fBend\fR ,
which returns the number of tabs
(only valid for
.QW "\fIpathname \fBindex\fR" ).
.SH "WIDGET COMMAND"
.TP
\fIpathname \fBadd \fIwindow\fR ?\fIoptions...\fR?
Adds a new tab to the notebook.
See \fBTAB OPTIONS\fR for the list of available \fIoptions\fR.
If \fIwindow\fR is currently managed by the notebook but hidden,
it is restored to its previous position.
.TP
\fIpathname \fBconfigure\fR ?\fIoptions\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBcget \fIoption\fR
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBforget \fItabid\fR
Removes the tab specified by \fItabid\fR,
unmaps and unmanages the associated window.
.TP
\fIpathname \fBhide \fItabid\fR
Hides the tab specified by \fItabid\fR.
The tab will not be displayed, but the associated window
remains managed by the notebook and its configuration remembered.
Hidden tabs may be restored with the \fBadd\fR command.
.TP
\fIpathname \fBidentify\fI component x y\fR
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element\fR \fIx y\fR
Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify tab\fR \fIx y\fR
Returns the index of the tab at the specified location.
.RE
.TP
\fIpathname \fBindex \fItabid\fR
Returns the numeric index of the tab specified by \fItabid\fR,
or the total number of tabs if \fItabid\fR is the string
.QW \fBend\fR .
.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the notebook,
moves it to the specified position.
See \fBTAB OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBinstate \fIstatespec \fR?\fIscript...\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBselect\fR ?\fItabid\fR?
Selects the specified tab.
The associated content window will be displayed,
and the previously-selected window (if different) is unmapped.
If \fItabid\fR is omitted, returns the widget name of the
currently selected pane.
.TP
\fIpathname \fBstate\fR ?\fIstatespec\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBtab \fItabid\fR ?\fI\-option \fR?\fIvalue ...\fR
Query or modify the options of the specific tab.
If no \fI\-option\fR is specified,
returns a dictionary of the tab option values.
If one \fI\-option\fR is specified,
returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
See \fBTAB OPTIONS\fR for the available options.
.TP
\fIpathname \fBtabs\fR
Returns the list of windows managed by the notebook, in the index order of
their associated tabs.
.SH "KEYBOARD TRAVERSAL"
To enable keyboard traversal for a toplevel window
containing a notebook widget \fI$nb\fR, call:
.CS
ttk::notebook::enableTraversal $nb
.CE
.PP
This will extend the bindings for the toplevel window
containing the notebook as follows:
.IP \(bu
\fBControl-Tab\fR selects the tab following the currently selected one.
.IP \(bu
\fBControl-Shift-Tab\fR selects the tab preceding the currently selected one.
.IP \(bu
\fBAlt-\fIK\fR, where \fIK\fR is the mnemonic (underlined) character
of any tab, will select that tab.
.PP
Multiple notebooks in a single toplevel may be enabled for traversal,
including nested notebooks.
However, notebook traversal only works properly if all panes
are direct children of the notebook.
.SH "VIRTUAL EVENTS"
The notebook widget generates a \fB<<NotebookTabChanged>>\fR
virtual event after a new tab is selected.
.SH "EXAMPLE"
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] \-text "First tab"
\&.nb add [frame .nb.f2] \-text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::notebook\fP is \fBTNotebook\fP.  The tab has
a class name of \fBTNotebook.Tab\fP
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBselected\fP.
.PP
\fBTNotebook\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIside\fP
.br
.PP
\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-expand\fP \fIpadding\fP
.RS
Defines how much the tab grows in size.  Usually used with the
\fBselected\fP dynamic state.  \fB\-tabmargins\fP should be
set appropriately so that there is room for the tab growth.
.RE
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:





|














|

|







|






|

|

|

<
<
<

|






|



|


|
|















|









|



|







|




|








|


|



|





|





|


|



|




|

|

|



|




|







|









|
<












|

|



|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206




















































207
208
209
210
211
212
213
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::notebook n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::notebook \- Multi-paned container widget
.SH SYNOPSIS
.nf
\fBttk::notebook\fR \fIpathname \fR?\fIoptions...\fR?
.br
\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::notebook\fR widget manages a collection of windows 
and displays a single one at a time.
Each slave window is associated with a \fItab\fR,
which the user may select to change the currently-displayed window.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-height height Height
If present and greater than zero, 
specifies the desired height of the pane area
(not including internal padding or tabs).
Otherwise, the maximum height of all panes is used.
.OP \-padding padding Padding
Specifies the amount of extra space to add around the outside
of the notebook.
The padding is a list of up to four length specifications 
\fIleft top right bottom\fR.
If fewer than four elements are specified, 
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and 
\fItop\fR defaults to \fIleft\fR.



.OP \-width width Width
If present and greater than zero, 
specifies the desired width of the pane area
(not including internal padding).
Otherwise, the maximum width of all panes is used.
.SH "TAB OPTIONS"
The following options may be specified for individual notebook panes:
.OP \-state state State
Either \fBnormal\fR, \fBdisabled\fR or \fBhidden\fR.  
If \fBdisabled\fR, then the tab is not selectable.
If \fBhidden\fR, then the tab is not shown.
.OP \-sticky sticky Sticky
Specifies how the slave window is positioned within the pane area.
Value is a string containing zero or more of the characters
\fBn, s, e,\fR or \fBw\fR.
Each letter refers to a side (north, south, east, or west) 
that the slave window will
.QW stick
to, as per the \fBgrid\fR geometry manager.
.OP \-padding padding Padding
Specifies the amount of extra space to add between the notebook and this pane.
Syntax is the same as for the widget \fB\-padding\fR option.
.OP \-text text Text
Specifies a string to be displayed in the tab.
.OP \-image image Image
Specifies an image to display in the tab.
See \fIttk_widget(n)\fR for details.
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
See \fIlabel(n)\fR for legal values.
.OP \-underline underline Underline
Specifies the integer index (0-based) of a character to underline 
in the text string.
The underlined character is used for mnemonic activation
if \fBttk::notebook::enableTraversal\fR is called.
.SH "TAB IDENTIFIERS"
The \fItabid\fR argument to the following commands may take
any of the following forms:
.IP \(bu
An integer between zero and the number of tabs;
.IP \(bu
The name of a slave window;
.IP \(bu
A positional specification of the form
.QW @\fIx\fR,\fIy\fR ,
which identifies the tab 
.IP \(bu
The literal string
.QW \fBcurrent\fR ,
which identifies the currently-selected tab; or:
.IP \(bu
The literal string
.QW \fBend\fR ,
which returns the number of tabs 
(only valid for
.QW "\fIpathname \fBindex\fR" ).
.SH "WIDGET COMMAND"
.TP
\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
Adds a new tab to the notebook.
See \fBTAB OPTIONS\fR for the list of available \fIoptions\fR.
If \fIwindow\fR is currently managed by the notebook but hidden,
it is restored to its previous position.
.TP
\fIpathname \fBconfigure\fR ?\fIoptions\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBcget\fR \fIoption\fR
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBforget\fR \fItabid\fR
Removes the tab specified by \fItabid\fR,
unmaps and unmanages the associated window.
.TP
\fIpathname \fBhide\fR \fItabid\fR
Hides the tab specified by \fItabid\fR.
The tab will not be displayed, but the associated window
remains managed by the notebook and its configuration remembered.
Hidden tabs may be restored with the \fBadd\fR command.
.TP
\fIpathname \fBidentify\fR \fIcomponent\fR \fIx\fR \fIy\fR
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify\fR \fBelement\fR \fIx\fR \fIy\fR
Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify\fR \fBtab\fR \fIx\fR \fIy\fR
Returns the index of the tab at the specified location.
.RE
.TP
\fIpathname \fBindex\fR \fItabid\fR
Returns the numeric index of the tab specified by \fItabid\fR,
or the total number of tabs if \fItabid\fR is the string
.QW \fBend\fR .
.TP
\fIpathname \fBinsert\fR \fIpos\fR \fIsubwindow\fR \fIoptions...\fR
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index, 
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the notebook, 
moves it to the specified position.
See \fBTAB OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBinstate\fR \fIstatespec \fR?\fIscript...\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBselect\fR ?\fItabid\fR?
Selects the specified tab.
The associated slave window will be displayed,
and the previously-selected window (if different) is unmapped.
If \fItabid\fR is omitted, returns the widget name of the
currently selected pane.
.TP
\fIpathname \fBstate\fR ?\fIstatespec\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBtab\fR \fItabid\fR ?\fI\-option \fR?\fIvalue ...\fR
Query or modify the options of the specific tab.
If no \fI\-option\fR is specified,
returns a dictionary of the tab option values.
If one \fI\-option\fR is specified,
returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
See \fBTAB OPTIONS\fR for the available options.
.TP
\fIpathname \fBtabs\fR
Returns the list of windows managed by the notebook.

.SH "KEYBOARD TRAVERSAL"
To enable keyboard traversal for a toplevel window
containing a notebook widget \fI$nb\fR, call:
.CS
ttk::notebook::enableTraversal $nb
.CE
.PP
This will extend the bindings for the toplevel window
containing the notebook as follows:
.IP \(bu
\fBControl-Tab\fR selects the tab following the currently selected one.
.IP \(bu
\fBShift-Control-Tab\fR selects the tab preceding the currently selected one.
.IP \(bu
\fBAlt-K\fR, where \fBK\fR is the mnemonic (underlined) character
of any tab, will select that tab.
.PP
Multiple notebooks in a single toplevel may be enabled for traversal,
including nested notebooks.  
However, notebook traversal only works properly if all panes
are direct children of the notebook.
.SH "VIRTUAL EVENTS"
The notebook widget generates a \fB<<NotebookTabChanged>>\fR
virtual event after a new tab is selected.
.SH "EXAMPLE"
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] \-text "First tab"
\&.nb add [frame .nb.f2] \-text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE




















































.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_panedwindow.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::panedwindow n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::panedwindow \- Multi-pane container window
.SH SYNOPSIS
.nf
\fBttk::panedwindow\fR \fIpathname \fR?\fIoptions\fR?






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::panedwindow n 8.5.9 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::panedwindow \- Multi-pane container window
.SH SYNOPSIS
.nf
\fBttk::panedwindow\fR \fIpathname \fR?\fIoptions\fR?
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
When the paned window is resized, the extra space is added
or subtracted to each pane proportionally to its \fB\-weight\fR.
.SH "WIDGET COMMAND"
Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR,
and \fBinstate\fR commands; see \fIttk::widget(n)\fR for details.
Additional commands:
.TP
\fIpathname \fBadd \fIsubwindow options...\fR
Adds a new pane to the window.
See \fBPANE OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBforget \fIpane\fR
Removes the specified subpane from the widget.
\fIpane\fR is either an integer index or the name of a managed subwindow.
.TP
\fIpathname \fBidentify \fIcomponent x y\fR
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
If \fIcomponent\fR is omitted, it defaults to \fBsash\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element \fIx y\fR
Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify sash \fIx y\fR
Returns the index of the sash at the specified location.
.RE
.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the paned window,
moves it to the specified position.
See \fBPANE OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBpane \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR
Query or modify the options of the specified \fIpane\fR,
where \fIpane\fR is either an integer index or the name of a managed subwindow.
If no \fI\-option\fR is specified, returns a dictionary of the pane
option values.
If one \fI\-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
.TP
\fIpathname \fBpanes\fR
Returns the list of all windows managed by the widget, in the index order of
their associated panes.
.TP
\fIpathname \fBsashpos \fIindex\fR ?\fInewpos\fR?
If \fInewpos\fR is specified, sets the position
of sash number \fIindex\fR.
May adjust the positions of adjacent sashes
to ensure that positions are monotonically increasing.
Sash positions are further constrained to be between 0
and the total size of the widget.
.\" Full story: "total size" is either the -height (resp -width),
.\" or the actual window height (resp actual window width),
.\" depending on which changed most recently.
Returns the new position of sash number \fIindex\fR.
.\" Full story: new position may be different than the requested position.
.PP
The panedwindow widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
for <Leave> events when the pointer crosses from a parent to a child. The
panedwindow widget needs to know when that happens.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP.  The
sash has a class name of \fBSash\fP.
.PP
\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
\fBSash\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-gripcount\fP \fIcount\fP
.br
\fB\-handlepad\fP \fIamount\fP
.br
\fB\-handlesize\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-sashpad\fP \fIamount\fP
.br
\fB\-sashrelief\fP \fIrelief\fP
.br
\fB\-sashthickness\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::notebook(n), panedwindow(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







|



|



|






|


|



|







|







|
|
<

|











<
<
<
<
<
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107








108
109
110
111
112
113



































114
115
116
117
118
When the paned window is resized, the extra space is added
or subtracted to each pane proportionally to its \fB\-weight\fR.
.SH "WIDGET COMMAND"
Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR,
and \fBinstate\fR commands; see \fIttk::widget(n)\fR for details.
Additional commands:
.TP
\fIpathname\fR \fBadd\fR \fIsubwindow\fR \fIoptions...\fR
Adds a new pane to the window.
See \fBPANE OPTIONS\fR for the list of available options.
.TP
\fIpathname\fR \fBforget\fR \fIpane\fR
Removes the specified subpane from the widget.
\fIpane\fR is either an integer index or the name of a managed subwindow.
.TP
\fIpathname\fR \fBidentify\fR \fIcomponent\fR \fIx\fR \fIy\fR
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
If \fIcomponent\fR is omitted, it defaults to \fBsash\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname\fR \fBidentify\fR \fBelement\fR \fIx\fR \fIy\fR
Returns the name of the element at the specified location.
.TP
\fIpathname\fR \fBidentify\fR \fBsash\fR \fIx\fR \fIy\fR
Returns the index of the sash at the specified location.
.RE
.TP
\fIpathname\fR \fBinsert\fR \fIpos\fR \fIsubwindow\fR \fIoptions...\fR
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the paned window,
moves it to the specified position.
See \fBPANE OPTIONS\fR for the list of available options.
.TP
\fIpathname\fR \fBpane\fR \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR
Query or modify the options of the specified \fIpane\fR,
where \fIpane\fR is either an integer index or the name of a managed subwindow.
If no \fI\-option\fR is specified, returns a dictionary of the pane
option values.
If one \fI\-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
.TP
\fIpathname\fR \fBpanes\fR
Returns the list of all windows managed by the widget.

.TP
\fIpathname\fR \fBsashpos\fR \fIindex\fR ?\fInewpos\fR?
If \fInewpos\fR is specified, sets the position
of sash number \fIindex\fR.
May adjust the positions of adjacent sashes
to ensure that positions are monotonically increasing.
Sash positions are further constrained to be between 0
and the total size of the widget.
.\" Full story: "total size" is either the -height (resp -width),
.\" or the actual window height (resp actual window width),
.\" depending on which changed most recently.
Returns the new position of sash number \fIindex\fR.
.\" Full story: new position may be different than the requested position.








.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
for <Leave> events when the pointer crosses from a parent to a child. The
panedwindow widget needs to know when that happens.



































.SH "SEE ALSO"
ttk::widget(n), ttk::notebook(n), panedwindow(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_progressbar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::progressbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::progressbar \- Provide progress feedback
.SH SYNOPSIS
\fBttk::progressbar\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.
.PP
If the value of \fB-orient\fR is \fBhorizontal\fR a text string can be
displayed inside the progressbar. This string can be configured using
the \fB-anchor\fR, \fB-font\fR, \fB-foreground\fR, \fB-justify\fR,
\fB-text\fR and \fB-wraplength\fR options. If the value of \fB-orient\fR
is \fBvertical\fR then these options are ignored.
.SO ttk_widget
\-anchor	\-class	\-cursor
\-font	\-foreground	\-justify	\-style
\-takefocus	\-text	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"



.OP \-length length Length
Specifies the length of the long axis of the progress bar
(width if horizontal, height if vertical). The value may have any of the forms
acceptable to \fBTk_GetPixels\fR.


.OP \-maximum maximum Maximum
A floating point number specifying the maximum \fB\-value\fR.
Defaults to 100.
.OP \-mode mode Mode
One of \fBdeterminate\fR or \fBindeterminate\fR.
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the progress bar.
.OP \-phase phase Phase
Read-only option.
The widget periodically increments the value of this option
whenever the \fB\-value\fR is greater than 0 and,
in \fIdeterminate\fR mode, less than \fB\-maximum\fR.
This option may be used by the current theme
to provide additional animation effects.
.OP \-value value Value
The current value of the progress bar.
In \fIdeterminate\fR mode, this represents the amount of work completed.
In \fIindeterminate\fR mode, it is interpreted modulo \fB\-maximum\fR;
that is, the progress bar completes one
.QW cycle
when the \fB\-value\fR increases by \fB\-maximum\fR.
If \fB\-variable\fR is set to an existing variable, specifying \fB\-value\fR
has no effect (the variable value takes precedence).
.OP \-variable variable Variable
The name of a global Tcl variable which is linked to the \fB\-value\fR.
If specified to an existing variable, the \fB\-value\fR of the progress bar is
automatically set to the value of the variable whenever
the latter is modified.







.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstart\fR ?\fIinterval\fR?
Begin autoincrement mode:
schedules a recurring timer event that calls \fBstep\fR
every \fIinterval\fR milliseconds.
If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second).
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstep\fR ?\fIamount\fR?
Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.
.TP
\fIpathName \fBstop\fR
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-maxphase\fP
.RS
For the aqua theme.
.RE
\fB\-period\fP
.RS
For the aqua theme.
.RE
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
'\" Local Variables:
'\" mode: nroff
'\" End:





|















<
<
<
<
<
<

|
|
<


>
>
>


|
<
>
>



<
<
<
<
<
<
<
<
<
<
<
<







<
<


|
|

>
>
>
>
>
>
>



|





|








|







|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21






22
23
24

25
26
27
28
29
30
31
32

33
34
35
36
37












38
39
40
41
42
43
44


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88





























89
90
91
92
93
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::progressbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::progressbar \- Provide progress feedback
.SH SYNOPSIS
\fBttk::progressbar\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.






.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the progress bar.
.OP \-length length Length
Specifies the length of the long axis of the progress bar
(width if horizontal, height if vertical).

.OP \-mode mode Mode
One of \fBdeterminate\fR or \fBindeterminate\fR.
.OP \-maximum maximum Maximum
A floating point number specifying the maximum \fB\-value\fR.
Defaults to 100.












.OP \-value value Value
The current value of the progress bar.
In \fIdeterminate\fR mode, this represents the amount of work completed.
In \fIindeterminate\fR mode, it is interpreted modulo \fB\-maximum\fR;
that is, the progress bar completes one
.QW cycle
when the \fB\-value\fR increases by \fB\-maximum\fR.


.OP \-variable variable Variable
The name of a global Tcl variable which is linked to the \fB\-value\fR.
If specified, the \fB\-value\fR of the progress bar is 
automatically set to the value of the variable whenever 
the latter is modified.
.OP \-phase phase Phase
Read-only option.
The widget periodically increments the value of this option 
whenever the \fB\-value\fR is greater than 0 and,
in \fIdeterminate\fR mode, less than \fB\-maximum\fR.
This option may be used by the current theme 
to provide additional animation effects.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBidentify\fR \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstart\fR ?\fIinterval\fR?
Begin autoincrement mode:
schedules a recurring timer event that calls \fBstep\fR 
every \fIinterval\fR milliseconds.
If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second).
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstep\fR ?\fIamount\fR?
Increments the \fB\-value\fR by \fIamount\fR.  
\fIamount\fR defaults to 1.0 if omitted.
.TP
\fIpathName \fBstop\fR
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.





























.SH "SEE ALSO"
ttk::widget(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_radiobutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::radiobutton \- Mutually exclusive option widget
.SH SYNOPSIS
\fBttk::radiobutton\fR \fIpathName \fR?\fIoptions\fR?





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::radiobutton \- Mutually exclusive option widget
.SH SYNOPSIS
\fBttk::radiobutton\fR \fIpathName \fR?\fIoptions\fR?
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script to evaluate whenever the widget is invoked.
.OP \-value Value Value
The value to store in the associated \fB\-variable\fR
when the widget is selected.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Default value is \fB::selectedButton\fR.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, radiobuttons support the following additional
widget commands:
.TP
\fIpathname\fB invoke\fR
Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget,
and evaluates the associated \fB\-command\fR.
Returns the result of the \fB\-command\fR, or the empty
string if no \fB\-command\fR is specified.
.\" Missing: select, deselect.  Useful?
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"
.PP
The widget does not respond to user input if the \fBdisabled\fR state is set.
The widget sets the \fBselected\fR state whenever
the linked \fB\-variable\fR is set to the widget's \fB\-value\fR,
and clears it otherwise.
The widget sets the \fBalternate\fR state whenever the
linked \fB\-variable\fR is unset.
(The \fBalternate\fR state may be used to indicate a
.QW tri-state
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::radiobutton\fP is \fBTRadiobutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP,
\fBpressed\fP, \fBreadonly\fP, \fBselected\fP.
.PP
\fBTRadiobutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatorbackground\fP \fIcolor\fP
.br
\fB\-indicatorcolor\fP \fIcolor\fP
.br
\fB\-indicatormargin\fP \fIpadding\fP
.br
\fB\-indicatorrelief\fP \fIrelief\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::checkbutton(n), radiobutton(n)
.SH "KEYWORDS"
widget, button, option
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|





|
|





|







|


|
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67






























68
69
70
71
72
73
74
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script to evaluate whenever the widget is invoked.
.OP \-value Value Value
The value to store in the associated \fI\-variable\fR 
when the widget is selected. 
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Default value is \fB::selectedButton\fR.
.SH "WIDGET COMMAND"
.PP
In addition to the standard 
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR 
commands, radiobuttons support the following additional
widget commands:
.TP
\fIpathname\fB invoke\fR
Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget,
and evaluates the associated \fB\-command\fR.  
Returns the result of the \fB\-command\fR, or the empty
string if no \fB\-command\fR is specified.
.\" Missing: select, deselect.  Useful?
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"
.PP
The widget does not respond to user input if the \fBdisabled\fR state is set.
The widget sets the \fBselected\fR state whenever 
the linked \fB\-variable\fR is set to the widget's \fB\-value\fR,
and clears it otherwise.
The widget sets the \fBalternate\fR state whenever the 
linked \fB\-variable\fR is unset.  
(The \fBalternate\fR state may be used to indicate a
.QW tri-state
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.






























.SH "SEE ALSO"
ttk::widget(n), ttk::checkbutton(n), radiobutton(n)
.SH "KEYWORDS"
widget, button, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_scale.n.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
scale's height; for horizontal scales it is the scale's width.
.OP \-orient orient Orient
Specifies which orientation whether the widget should be laid out horizontally
or vertically. Must be either \fBhorizontal\fR or \fBvertical\fR or an
abbreviation of one of these.
.OP \-to to To
Specifies a real value corresponding to the right or bottom end of the scale.
This value may be either less than or greater than the \fB\-from\fR option.
.OP \-value value Value
Specifies the current floating-point value of the variable.
If \fB\-variable\fR is set to an existing variable, specifying \fB\-value\fR
has no effect (the variable value takes precedence).
.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale. Whenever the
value of the variable changes, the scale will update to reflect this value.
Whenever the scale is manipulated interactively, the variable will be modified
to reflect the scale's new value.
.SH "WIDGET COMMAND"
.PP







|


<
<







35
36
37
38
39
40
41
42
43
44


45
46
47
48
49
50
51
scale's height; for horizontal scales it is the scale's width.
.OP \-orient orient Orient
Specifies which orientation whether the widget should be laid out horizontally
or vertically. Must be either \fBhorizontal\fR or \fBvertical\fR or an
abbreviation of one of these.
.OP \-to to To
Specifies a real value corresponding to the right or bottom end of the scale.
This value may be either less than or greater than the \fBfrom\fR option.
.OP \-value value Value
Specifies the current floating-point value of the variable.


.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale. Whenever the
value of the variable changes, the scale will update to reflect this value.
Whenever the scale is manipulated interactively, the variable will be modified
to reflect the scale's new value.
.SH "WIDGET COMMAND"
.PP
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
.TP
\fIpathName \fBget \fR?\fIx y\fR?
.
Get the current value of the \fB\-value\fR option, or the value corresponding
to the coordinates \fIx,y\fR if they are specified. \fIX\fR and \fIy\fR are
pixel coordinates relative to the scale widget origin.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget state; see \fIttk::widget(n)\fR.
.TP







|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
.TP
\fIpathName \fBget \fR?\fIx y\fR?
.
Get the current value of the \fB\-value\fR option, or the value corresponding
to the coordinates \fIx,y\fR if they are specified. \fIX\fR and \fIy\fR are
pixel coordinates relative to the scale widget origin.
.TP
\fIpathName \fBidentify\fR \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget state; see \fIttk::widget(n)\fR.
.TP
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
.PP
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scale\fP is \fBTScale\fP.
.PP
Dynamic states: \fBactive\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-groovewidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-sliderwidth\fP \fIamount\fP
.br
\fB\-troughcolor\fP \fIcolor\fP
.br
\fB\-troughrelief\fP \fIrelief\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), scale(n)
.SH KEYWORDS
scale, slider, trough, widget
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 78
.\" End:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








87
88
89
90
91
92
93





























94
95
96
97
98
99
100
101
.PP
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.





























.SH "SEE ALSO"
ttk::widget(n), scale(n)
.SH KEYWORDS
scale, slider, trough, widget
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 78
.\" End:

Changes to doc/ttk_scrollbar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::scrollbar \- Control the viewport of a scrollable widget
.SH SYNOPSIS
\fBttk::scrollbar\fR \fIpathName \fR?\fIoptions...\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::scrollbar\fR widgets are typically linked to an associated window
that displays a document of some sort, such as a file being edited or a
drawing.
A scrollbar displays a \fIthumb\fR in the middle portion of the scrollbar,
whose position and size provides information about the portion of the
document visible in the associated window.
The thumb may be dragged by the user to control the visible region.
Depending on the theme, two or more arrow buttons may also be present;
these are used to scroll the visible region in discrete units.
.SO ttk_widget
\-class	\-cursor	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script prefix to evaluate
to change the view in the widget associated with the scrollbar.
Additional arguments are appended to the value of this option,
as described in \fBSCROLLING COMMANDS\fR below,
whenever the user requests a view change by manipulating the scrollbar.
.RS
.PP
This option typically consists of a two-element list,
containing the name of a scrollable widget followed by
either \fBxview\fR (for horizontal scrollbars)
or \fByview\fR (for vertical scrollbars).
.RE
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the scrollbar.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBget\fR
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset \fIfirst last\fR
This command is normally invoked by the scrollbar's associated widget
from an \fB\-xscrollcommand\fR or \fB\-yscrollcommand\fR callback.
Specifies the visible range to be displayed.
\fIfirst\fR and \fIlast\fR are real fractions between 0 and 1.
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.SH "INTERNAL COMMANDS"
.PP
The following widget commands are used internally
by the \fBTScrollbar\fP widget class bindings.
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in thumb position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the thumb \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is






|




|




















|

















|









|






|
|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::scrollbar \- Control the viewport of a scrollable widget 
.SH SYNOPSIS
\fBttk::scrollbar\fR \fIpathName \fR?\fIoptions...\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::scrollbar\fR widgets are typically linked to an associated window
that displays a document of some sort, such as a file being edited or a
drawing.
A scrollbar displays a \fIthumb\fR in the middle portion of the scrollbar,
whose position and size provides information about the portion of the
document visible in the associated window.
The thumb may be dragged by the user to control the visible region.
Depending on the theme, two or more arrow buttons may also be present;
these are used to scroll the visible region in discrete units.
.SO ttk_widget
\-class	\-cursor	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A Tcl script prefix to evaluate 
to change the view in the widget associated with the scrollbar.
Additional arguments are appended to the value of this option,
as described in \fBSCROLLING COMMANDS\fR below,
whenever the user requests a view change by manipulating the scrollbar.
.RS
.PP
This option typically consists of a two-element list,
containing the name of a scrollable widget followed by
either \fBxview\fR (for horizontal scrollbars)
or \fByview\fR (for vertical scrollbars).
.RE
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the scrollbar.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBget\fR
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify\fR \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset\fR \fIfirst last\fR
This command is normally invoked by the scrollbar's associated widget 
from an \fB\-xscrollcommand\fR or \fB\-yscrollcommand\fR callback.
Specifies the visible range to be displayed.
\fIfirst\fR and \fIlast\fR are real fractions between 0 and 1.
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.SH "INTERNAL COMMANDS"
.PP
The following widget commands are used internally
by the TScrollbar widget class bindings.
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in thumb position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the thumb \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
114
115
116
117
118
119
120








121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP








\fIprefix \fBscroll \fInumber \fBpages\fR
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.SH "WIDGET STATES"
.PP
The scrollbar automatically sets the \fBdisabled\fR state bit.
when the entire range is visible (range is 0.0 to 1.0),
and clears it otherwise.
It also sets the \fBactive\fR and \fBpressed\fR state flags
of individual elements, based on the position and state of the mouse pointer.
.SH EXAMPLE
.PP
.CS
set f [frame .f]
ttk::scrollbar $f.hsb \-orient horizontal \-command [list $f.t xview]
ttk::scrollbar $f.vsb \-orient vertical \-command [list $f.t yview]
text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set]
grid $f.t \-row 0 \-column 0 \-sticky nsew
grid $f.vsb \-row 0 \-column 1 \-sticky nsew
grid $f.hsb \-row 1 \-column 0 \-sticky nsew
grid columnconfigure $f 0 \-weight 1
grid rowconfigure $f 0 \-weight 1
pack $f
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP.
.PP
\fBTScrollbar\fP (or more specifically \fBVertical.TScrollbar\fP and
\fBHorizontal.TScrollbar\fP) styling options that are configurable with
\fBttk::style\fP are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP (color of the dark part of the 3D relief)
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-gripcount\fP \fIcount\fP (number of lines on the thumb)
.br
\fB\-lightcolor\fP \fIcolor\fP (color of the light part of the 3D relief)
.br
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







>
>
>
>
>
>
>
>








<
<
<
<
<
<
<
<













|





<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136








137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
































157
158
159
160
161
162
163
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.








.SH "WIDGET STATES"
.PP
The scrollbar automatically sets the \fBdisabled\fR state bit.
when the entire range is visible (range is 0.0 to 1.0),
and clears it otherwise.
It also sets the \fBactive\fR and \fBpressed\fR state flags
of individual elements, based on the position and state of the mouse pointer.
.SH EXAMPLE
.PP
.CS
set f [frame .f]
ttk::scrollbar $f.hsb \-orient horizontal \-command [list $f.t xview]
ttk::scrollbar $f.vsb \-orient vertical \-command [list $f.t yview]
text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set] 
grid $f.t \-row 0 \-column 0 \-sticky nsew
grid $f.vsb \-row 0 \-column 1 \-sticky nsew
grid $f.hsb \-row 1 \-column 0 \-sticky nsew
grid columnconfigure $f 0 \-weight 1
grid rowconfigure $f 0 \-weight 1

.CE
































.SH "SEE ALSO"
ttk::widget(n), scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_separator.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::separator n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::separator \- Separator bar
.SH SYNOPSIS
\fBttk::separator\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::separator\fR widget displays a horizontal or vertical separator
bar.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.PP
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::separator\fP is \fBTSeparator\fP.
.PP
\fBTSeparator\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, separator
'\" Local Variables:
'\" mode: nroff
'\" End:





|













|








|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31














32
33
34
35
36
37
38
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::separator n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::separator \- Separator bar
.SH SYNOPSIS
\fBttk::separator\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::separator\fR widget displays a horizontal or vertical separator
bar.
.SO ttk_widget
\-class	\-cursor	\-state
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard 
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR 
methods.  No other widget methods are used.














.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, separator
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_sizegrip.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR)
allows the user to resize the containing toplevel window
by pressing and dragging the grip.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.





|














|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR)
allows the user to resize the containing toplevel window
by pressing and dragging the grip.
.SO ttk_widget
\-class	\-cursor	\-state
\-style	\-takefocus
.SE
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
instead of
.QW "\fBwm geometry ... \fIw\fBx\fIh\fB+\fIx\fB+\fIy\fR" ),
the sizegrip widget will not resize the window.
.PP
\fBttk::sizegrip\fR widgets only support
.QW southeast
resizing.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::sizegrip\fP is \fBTSizegrip\fP.
.PP
\fBTSizegrip\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, sizegrip, grow box
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
<
<
<
<
<
<
<
<
<
<







56
57
58
59
60
61
62













63
64
65
66
67
68
69
instead of
.QW "\fBwm geometry ... \fIw\fBx\fIh\fB+\fIx\fB+\fIy\fR" ),
the sizegrip widget will not resize the window.
.PP
\fBttk::sizegrip\fR widgets only support
.QW southeast
resizing.













.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, sizegrip, grow box
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_spinbox.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57







58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::spinbox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::spinbox \- Selecting text field widget
.SH SYNOPSIS
\fBttk::spinbox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
up and down buttons that are used to either modify a numeric value or
to select among a set of values. The widget implements all the features
of the \fBttk::entry\fR widget including support of the
\fB\-textvariable\fR option to link the value displayed by the widget
to a Tcl variable.
.SO ttk_widget
\-class	\-cursor	\-state	\-style
\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
.OP \-format format Format
Specifies an alternate format to use when setting the string value
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating\-point value specifying the lowest value for the spinbox. This is
used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical




range.
.OP \-increment increment Increment
A floating\-point value specifying the change in value to be applied each
time one of the widget spin buttons is pressed. The up button applies a
positive increment, the down button applies a negative increment.
.OP \-to to To
A floating\-point value specifying the highest permissible value for the
widget. See also \fB\-from\fR and \fB\-increment\fR.
range.
.OP \-values values Values
This must be a Tcl list of values. If this option is set then this will
override any range set using the \fB\-from\fR, \fB\-to\fR and
\fB\-increment\fR options. The widget will instead use the values
specified beginning with the first value.
.OP \-wrap wrap Wrap
Must be a proper boolean value.  If on, the spinbox will wrap around the
values of data in the widget.







.SH "INDICES"
.PP
See the \fBttk::entry\fR manual for information about indexing characters.
.SH "VALIDATION"
.PP
See the \fBttk::entry\fR manual for information about using the
\fB\-validate\fR and \fB\-validatecommand\fR options.
.SH "WIDGET COMMAND"
.PP
The following subcommands are possible for spinbox widgets in addition to
the commands described for the \fBttk::entry\fR widget:
.TP


\fIpathName \fBget\fR
Returns the spinbox's current value.
.TP
\fIpathName \fBset \fIvalue\fR
Set the spinbox string to \fIvalue\fR. If a \fB\-format\fR option has
been configured then this format will be applied. If formatting fails
or is not set or the \fB\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when
the user presses <Up>, and a \fB<<Decrement>>\fR virtual event when the
user presses <Down>.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::spinbox\fP is \fBTSpinbox\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP.
.PP
\fBTSpinbox\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.RS
For backwards compatibility, when using the aqua theme (for macOS), this
option behaves as an alias for the \fB\-fieldbackground\fP provided that no
value is specified for \fB\-fieldbackground\fP. Otherwise it is ignored.
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n), spinbox(n)
.SH KEYWORDS
entry, spinbox, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:





|
|
















|
|





<
<
<
<
<
<
<


|
>
>
>
>





<
<
<
<


|
|




>
>
>
>
>
>
>





|
|





>
>




|

|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







31
32
33
34
35
36
37
38
39
40
41
42




43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84













































85
86
87
88
89
90
91
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::spinbox n 8.5.9 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::spinbox \- Selecting text field widget
.SH SYNOPSIS
\fBttk::spinbox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
up and down buttons that are used to either modify a numeric value or
to select among a set of values. The widget implements all the features
of the \fBttk::entry\fR widget including support of the
\fB\-textvariable\fR option to link the value displayed by the widget
to a Tcl variable.
.SO ttk_widget
\-class	\-cursor	\-style
\-takefocus	\-xscrollcommand
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"







.OP \-from from From
A floating\-point value specifying the lowest value for the spinbox. This is
used in conjunction with \fI\-to\fR and \fI\-increment\fR to set a numerical
range.
.OP \-to to To
A floating\-point value specifying the highest permissible value for the
widget. See also \fI\-from\fR and \fI\-increment\fR.
range.
.OP \-increment increment Increment
A floating\-point value specifying the change in value to be applied each
time one of the widget spin buttons is pressed. The up button applies a
positive increment, the down button applies a negative increment.




.OP \-values values Values
This must be a Tcl list of values. If this option is set then this will
override any range set using the \fI\-from\fR, \fI\-to\fR and 
\fI\-increment\fR options. The widget will instead use the values
specified beginning with the first value.
.OP \-wrap wrap Wrap
Must be a proper boolean value.  If on, the spinbox will wrap around the
values of data in the widget.
.OP \-format format Format
Specifies an alternate format to use when setting the string value
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
.SH "INDICES"
.PP
See the \fBttk::entry\fR manual for information about indexing characters.
.SH "VALIDATION"
.PP
See the \fBttk::entry\fR manual for information about using the 
\fI\-validate\fR and \fI\-validatecommand\fR options.
.SH "WIDGET COMMAND"
.PP
The following subcommands are possible for spinbox widgets in addition to
the commands described for the \fBttk::entry\fR widget:
.TP
\fIpathName \fBcurrent \fIindex\fR
.TP
\fIpathName \fBget\fR
Returns the spinbox's current value.
.TP
\fIpathName \fBset \fIvalue\fR
Set the spinbox string to \fIvalue\fR. If a \fI\-format\fR option has
been configured then this format will be applied. If formatting fails
or is not set or the \fI\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when
the user presses <Up>, and a \fB<<Decrement>>\fR virtual event when the
user presses <Down>.













































.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n), spinbox(n)
.SH KEYWORDS
entry, spinbox, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_style.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

























78

79


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::style n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::style \- Manipulate style database
.SH SYNOPSIS
\fBttk::style\fR \fIoption\fR ?\fIargs\fR?
.BE
.SH NOTES
.PP
See also the Tcl'2004 conference presentation,
available at https://tktable.sourceforge.net/tile/tile-tcl2004.pdf
.SH DEFINITIONS
.PP
Each widget is assigned a \fIstyle\fR,
which specifies the set of elements making up the widget
and how they are arranged, along with dynamic and default
settings for element options.
By default, the style name is the same as the widget's class;
this may be overridden by the \fB\-style\fR option.
.PP
A \fItheme\fR is a collection of elements and styles
which controls the overall look and feel of an application.
.SH DESCRIPTION
.PP
The \fBttk::style\fR command takes the following arguments:
.TP
\fBttk::style configure \fIstyle\fR ?\fI\-option\fR ?\fIvalue option value...\fR? ?
Sets the default value of the specified option(s) in \fIstyle\fR.
.TP
\fBttk::style element\fR \fIargs\fR
.RS
.TP
\fBttk::style element create\fR \fIelementName\fR \fItype\fR ?\fIargs...\fR?
Creates a new element in the current theme of type \fItype\fR.
The only cross-platform built-in element type is \fIimage\fR
(see \fBttk_image\fR(n)) but themes may define other element types
(see \fBTtk_RegisterElementFactory\fR). On suitable versions of Windows
an element factory is registered to create Windows theme elements
(see \fBttk_vsapi\fR(n)).
.TP
\fBttk::style element names\fR
Returns the list of elements defined in the current theme.
.TP
\fBttk::style element options \fIelement\fR
Returns the list of \fIelement\fR's options.
.RE
.TP
\fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR?
Define the widget layout for style \fIstyle\fR.
See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR.
If \fIlayoutSpec\fR is omitted, return the layout specification
for style \fIstyle\fR.
.TP
\fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR??
Returns the value specified for \fI\-option\fR in style \fIstyle\fR
in state \fIstate\fR, using the standard lookup rules for element options.
\fIstate\fR is a list of state names; if omitted,
it defaults to all bits off (the
.QW normal
state).
If the \fIdefault\fR argument is present, it is used as a fallback
value in case no specification for \fI\-option\fR is found.
.\" Otherwise -- signal error? return empty string? Leave unspecified for now.
.TP
\fBttk::style map \fIstyle\fR ?\fI\-option\fB { \fIstatespec value...\fB }\fR?
Sets dynamic values of the specified option(s) in \fIstyle\fR.
Each \fIstatespec / value\fR pair is examined in order;
the value corresponding to the first matching \fIstatespec\fR
is used.
.TP

























\fBttk::style theme\fR \fIargs\fR

.RS


.TP
\fBttk::style theme create\fR \fIthemeName\fR ?\fB\-parent \fIbasedon\fR? ?\fB\-settings \fIscript...\fR ?
Creates a new theme.  It is an error if \fIthemeName\fR already exists.
If \fB\-parent\fR is specified, the new theme will inherit
styles, elements, and layouts from the parent theme \fIbasedon\fR.
If \fB\-settings\fR is present, \fIscript\fR is evaluated in the
context of the new theme as per \fBttk::style theme settings\fR.
.TP
\fBttk::style theme names\fR
Returns a list of all known themes.
.TP
\fBttk::style theme settings \fIthemeName\fR \fIscript\fR
Temporarily sets the current theme to \fIthemeName\fR,
evaluate \fIscript\fR, then restore the previous theme.
Typically \fIscript\fR simply defines styles and elements,
though arbitrary Tcl code may appear.
.TP



\fBttk::style theme use\fR ?\fIthemeName\fR?
Without an argument the result is the name of the current theme.
Otherwise this command sets the current theme to \fIthemeName\fR,
and refreshes all widgets.
.RE
.SH LAYOUTS
.PP
A \fIlayout\fR specifies a list of elements, each followed
by one or more options specifying how to arrange the element.
The layout mechanism uses a simplified version of the \fBpack\fR
geometry manager: given an initial cavity,
each element is allocated a parcel.
Then the parcel actually used by the element is adjusted within
the allocated parcel.
Valid options are:
.\" -border should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-border\fR \fIboolean\fR
.\" Specifies whether the element is drawn after its children. Defaults to 0.
.TP
\fB\-children { \fIsublayout...\fB }\fR
Specifies a list of elements to place inside the element.
.TP
\fB\-expand\fR \fIboolean\fR
Specifies whether the allocated parcel is the entire cavity. If so,
simultaneous specification of \fB\-side\fR is ignored.
Defaults to 0.
.TP
\fB\-side \fIside\fR
Specifies which side of the cavity to place the element;
one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
For instance, \fB\-side top\fR allocates the parcel along the top of
the cavity having width and height respectively the width of the cavity
and the height of the element.
If omitted, the allocated parcel is the entire cavity (same effect
as \fB\-expand\fR 1).
.TP
\fB\-sticky\fR \fB[\fInswe\fB]\fR
Specifies the actual parcel position and size inside the allocated parcel.
If specified as an empty string then the actual parcel is centered in
the allocated parcel. Default is \fBnswe\fR.
.\" -unit should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-unit\fR \fIboolean\fR
.\" Specifies whether the element propagates its state to its children.
.\" Defaults to 0.
.PP
For example:
.CS
ttk::style layout Horizontal.TScrollbar {
    Scrollbar.trough \-children {
        Scrollbar.leftarrow \-side left
        Scrollbar.rightarrow \-side right


|


|











|







|

|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>








<
<
<

|




>
>
>




<







<
<

<
<
<
<
|
<
<
<
<
<
<
<
<



<
<
<
|
<


<
<
|
<
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36



































37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100


101




102








103
104
105



106

107
108


109

110
111
112
113
114
115
116
117
118
119
120
'\"
'\" Copyright (c) 2004 Joe English
'\" 
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::style n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::style \- Manipulate style database
.SH SYNOPSIS
\fBttk::style\fR \fIoption\fR ?\fIargs\fR?
.BE
.SH NOTES
.PP
See also the Tcl'2004 conference presentation,
available at http://tktable.sourceforge.net/tile/tile-tcl2004.pdf
.SH DEFINITIONS
.PP
Each widget is assigned a \fIstyle\fR,
which specifies the set of elements making up the widget
and how they are arranged, along with dynamic and default
settings for element options.
By default, the style name is the same as the widget's class;
this may be overridden by the \fB\-style\fR option. 
.PP
A \fItheme\fR is a collection of elements and styles 
which controls the overall look and feel of an application.
.SH DESCRIPTION
.PP
The \fBttk::style\fR command takes the following arguments:
.TP
\fBttk::style configure \fIstyle\fR ?\fI\-option\fR ?\fIvalue option value...\fR? ?
Sets the default value of the specified option(s) in \fIstyle\fR.
.TP



































\fBttk::style map \fIstyle\fR ?\fI\-option\fB { \fIstatespec value...\fB }\fR?
Sets dynamic values of the specified option(s) in \fIstyle\fR.
Each \fIstatespec / value\fR pair is examined in order;
the value corresponding to the first matching \fIstatespec\fR
is used.
.TP
\fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR??
Returns the value specified for \fI\-option\fR in style \fIstyle\fR
in state \fIstate\fR, using the standard lookup rules for element options.
\fIstate\fR is a list of state names; if omitted, 
it defaults to all bits off (the
.QW normal
state).
If the \fIdefault\fR argument is present, it is used as a fallback
value in case no specification for \fI\-option\fR is found.
.\" Otherwise -- signal error? return empty string? Leave unspecified for now. 
.TP
\fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR?
Define the widget layout for style \fIstyle\fR.  
See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR.
If \fIlayoutSpec\fR is omitted, return the layout specification
for style \fIstyle\fR.
.TP 
\fBttk::style element create\fR \fIelementName\fR \fItype\fR ?\fIargs...\fR?
Creates a new element in the current theme of type \fItype\fR.
The only cross-platform built-in element type is \fIimage\fR 
(see \fBttk_image\fR(n)) but themes may define other element types 
(see \fBTtk_RegisterElementFactory\fR). On suitable versions of Windows
an element factory is registered to create Windows theme elements
(see \fBttk_vsapi\fR(n)).
.TP 
\fBttk::style element names\fR
Returns the list of elements defined in the current theme.
.TP 
\fBttk::style element options \fIelement\fR
Returns the list of \fIelement\fR's options.
.TP
\fBttk::style theme create\fR \fIthemeName\fR ?\fB\-parent \fIbasedon\fR? ?\fB\-settings \fIscript...\fR ?
Creates a new theme.  It is an error if \fIthemeName\fR already exists.
If \fB\-parent\fR is specified, the new theme will inherit
styles, elements, and layouts from the parent theme \fIbasedon\fR.
If \fB\-settings\fR is present, \fIscript\fR is evaluated in the
context of the new theme as per \fBttk::style theme settings\fR.
.TP



\fBttk::style theme settings \fIthemeName\fR \fIscript\fR
Temporarily sets the current theme to \fIthemeName\fR, 
evaluate \fIscript\fR, then restore the previous theme.
Typically \fIscript\fR simply defines styles and elements,
though arbitrary Tcl code may appear.
.TP
\fBttk::style theme names\fR
Returns a list of all known themes.
.TP
\fBttk::style theme use\fR ?\fIthemeName\fR?
Without an argument the result is the name of the current theme.
Otherwise this command sets the current theme to \fIthemeName\fR,
and refreshes all widgets.

.SH LAYOUTS
.PP
A \fIlayout\fR specifies a list of elements, each followed
by one or more options specifying how to arrange the element.
The layout mechanism uses a simplified version of the \fBpack\fR
geometry manager: given an initial cavity,
each element is allocated a parcel.


Valid options are:




.TP 








\fB\-side \fIside\fR
Specifies which side of the cavity to place the element;
one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.



If omitted, the element occupies the entire cavity.

.TP
\fB\-sticky\fR \fB[\fInswe\fB]\fR


Specifies where the element is placed inside its allocated parcel.

.TP
\fB\-children { \fIsublayout... \fB}\fR
Specifies a list of elements to place inside the element.
.\" Also: -border, -unit, -expand: may go away.
.PP
For example:
.CS
ttk::style layout Horizontal.TScrollbar {
    Scrollbar.trough \-children {
        Scrollbar.leftarrow \-side left
        Scrollbar.rightarrow \-side right

Changes to doc/ttk_treeview.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66




67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::treeview n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::treeview \- hierarchical multicolumn data display widget
.SH SYNOPSIS
\fBttk::treeview \fIpathname \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fBttk::treeview\fR widget displays a hierarchical collection of items.
Each item has a textual label, an optional image,
and an optional list of data values.
The data values are displayed in successive columns after
the tree label.
.PP
The order in which data values are displayed may be controlled
by setting the \fB\-displaycolumns\fR widget option.
The tree widget can also display column headings.
Columns may be accessed by number or by symbolic names
listed in the \fB\-columns\fR widget option;
see \fBCOLUMN IDENTIFIERS\fR.
.PP
Each item is identified by a unique name.
The widget will generate item IDs if they are not supplied by the caller.
There is a distinguished root item, named \fB{}\fR.
The root item itself is not displayed;
its children appear at the top level of the hierarchy.
.PP
Each item also has a list of \fItags\fR,
which can be used to associate event bindings with individual items
and control the appearance of the item.
.\" .PP
.\" @@@HERE: describe selection, focus item
.PP
Treeview widgets support horizontal and vertical scrolling with the
standard \fB\-\fR[\fBxy\fR]\fBscrollcommand\fR options
and [\fBxy\fR]\fBview\fR widget commands.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style	\-xscrollcommand	\-yscrollcommand
\-padding
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-columns columns Columns
A list of column identifiers,
specifying the number of columns and their names.
.\"X: This is a read-only option; it may only be set when the widget is created.
.OP \-displaycolumns displayColumns DisplayColumns
A list of column identifiers
(either symbolic names or integer indices)
specifying which data columns are displayed
and the order in which they appear,
or the string \fB#all\fP.
If set to \fB#all\fP (the default),
all columns are shown in the order given.
.OP \-height height Height
Specifies the number of rows which should be visible.
Note:
the requested width is determined from the sum of the column widths.




.OP \-selectmode selectMode SelectMode
Controls how the built-in class bindings manage the selection.
One of \fBextended\fR, \fBbrowse\fR, or \fBnone\fR.
.RS
.PP
If set to \fBextended\fR (the default), multiple items may be selected.
If \fBbrowse\fR, only a single item will be selected at a time.
If \fBnone\fR, the selection will not be changed.
.PP
Note that application code and tag bindings can set the selection
however they wish, regardless of the value of \fB\-selectmode\fR.
.RE
.OP \-show show Show
A list containing zero or more of the following values, specifying
which elements of the tree to display.
.RS
.IP \fBtree\fR
Display tree labels in column #0.
.IP \fBheadings\fR
Display the heading row.
.PP
The default is \fBtree headings\fR, i.e., show all elements.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.





|
|










|





|

|
















|




<



|



|

|
|







>
>
>
>









|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::treeview n 8.5.9 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::treeview \- hierarchical multicolumn data display widget
.SH SYNOPSIS
\fBttk::treeview \fIpathname \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fBttk::treeview\fR widget displays a hierarchical collection of items.
Each item has a textual label, an optional image, 
and an optional list of data values.
The data values are displayed in successive columns after
the tree label.
.PP
The order in which data values are displayed may be controlled
by setting the \fB\-displaycolumns\fR widget option.  
The tree widget can also display column headings.
Columns may be accessed by number or by symbolic names 
listed in the \fB\-columns\fR widget option;
see \fBCOLUMN IDENTIFIERS\fR.
.PP
Each item is identified by a unique name.
The widget will generate item IDs if they are not supplied by the caller.
There is a distinguished root item, named \fB{}\fR.
The root item itself is not displayed;
its children appear at the top level of the hierarchy.
.PP
Each item also has a list of \fItags\fR,
which can be used to associate event bindings with individual items
and control the appearance of the item.
.\" .PP
.\" @@@HERE: describe selection, focus item
.PP
Treeview widgets support horizontal and vertical scrolling with the
standard \fB\-\fR[\fBxy\fR]\fBscrollcommand\fR options 
and [\fBxy\fR]\fBview\fR widget commands.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style	\-xscrollcommand	\-yscrollcommand

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-columns columns Columns
A list of column identifiers, 
specifying the number of columns and their names.
.\"X: This is a read-only option; it may only be set when the widget is created.
.OP \-displaycolumns displayColumns DisplayColumns
A list of column identifiers 
(either symbolic names or integer indices)
specifying which data columns are displayed 
and the order in which they appear, 
or the string \fB#all\fP.
If set to \fB#all\fP (the default),
all columns are shown in the order given.
.OP \-height height Height
Specifies the number of rows which should be visible.
Note:
the requested width is determined from the sum of the column widths.
.OP \-padding padding Padding
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications;
see \fBTtk_GetPaddingFromObj()\fR for details.
.OP \-selectmode selectMode SelectMode
Controls how the built-in class bindings manage the selection.
One of \fBextended\fR, \fBbrowse\fR, or \fBnone\fR.
.RS
.PP
If set to \fBextended\fR (the default), multiple items may be selected.
If \fBbrowse\fR, only a single item will be selected at a time.
If \fBnone\fR, the selection will not be changed.
.PP
Note that application code and tag bindings can set the selection 
however they wish, regardless of the value of \fB\-selectmode\fR.
.RE
.OP \-show show Show
A list containing zero or more of the following values, specifying
which elements of the tree to display.
.RS
.IP \fBtree\fR
Display tree labels in column #0.  
.IP \fBheadings\fR
Display the heading row.
.PP
The default is \fBtree headings\fR, i.e., show all elements.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
.TP
\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR?
If \fInewchildren\fR is not specified,
returns the list of children belonging to \fIitem\fR.
.RS
.PP
If \fInewchildren\fR is specified, replaces \fIitem\fR's child list
with \fInewchildren\fR.
Items in the old child list not present in the new child list
are detached from the tree.
None of the items in \fInewchildren\fR may be an ancestor
of \fIitem\fR.
.RE
.TP
\fIpathname \fBcolumn \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the options for the specified \fIcolumn\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the options are updated with the specified values.
The following options may be set on each column:
.RS
.TP
\fB\-id \fIname\fR
The column name.  This is a read-only option.
For example, [\fI$pathname \fBcolumn #\fIn \fB\-id\fR]
returns the data column associated with display column #\fIn\fR.
.TP
\fB\-anchor \fIanchor\fR
Specifies how the text in this column should be aligned
with respect to the cell. \fIAnchor\fR is one of
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
.TP
\fB\-minwidth \fIminwidth\fR
The minimum width of the column in pixels.
The treeview widget will not make the column any smaller than
\fB\-minwidth\fR when the widget is resized or the user drags a
column separator.  Default is 20 pixels.
.TP
\fB\-stretch \fIboolean\fR
Specifies whether or not the column width should be adjusted
when the widget is resized or the user drags a column separator.
\fIBoolean\fR may have any of the forms accepted by \fBTcl_GetBoolean\fR.
By default columns are stretchable.
.TP
\fB\-width \fIwidth\fR
The width of the column in pixels.  Default is 200 pixels. The specified
column width may be changed by Tk in order to honor \fB\-stretch\fR
and/or \fB\-minwidth\fR, or when the widget is resized or the user drags a
column separator.
.PP
Use \fIpathname column #0\fR to configure the tree column.
.RE
.TP
\fIpathname \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP







|










|








|

|

|



|


|
|

|
|
|
<
<

|
|
<
<
|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153


154
155
156


157
158
159
160
161
162
163
164
.TP
\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR?
If \fInewchildren\fR is not specified,
returns the list of children belonging to \fIitem\fR.
.RS
.PP
If \fInewchildren\fR is specified, replaces \fIitem\fR's child list
with \fInewchildren\fR.  
Items in the old child list not present in the new child list
are detached from the tree.
None of the items in \fInewchildren\fR may be an ancestor
of \fIitem\fR.
.RE
.TP
\fIpathname \fBcolumn \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the options for the specified \fIcolumn\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified, 
returns the value of that option.
Otherwise, the options are updated with the specified values.
The following options may be set on each column:
.RS
.TP
\fB\-id \fIname\fR
The column name.  This is a read-only option.
For example, [\fI$pathname \fBcolumn #\fIn \fB\-id\fR]
returns the data column associated with display column #\fIn\fR. 
.TP
\fB\-anchor\fR
Specifies how the text in this column should be aligned
with respect to the cell. One of
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
.TP
\fB\-minwidth\fR
The minimum width of the column in pixels.
The treeview widget will not make the column any smaller than
\fB\-minwidth\fR when the widget is resized or the user drags a 
column separator.
.TP
\fB\-stretch\fR
Specifies whether or not the column's width should be adjusted
when the widget is resized.


.TP
\fB\-width \fIw\fR
The width of the column in pixels.  Default is something reasonable,


probably 200 or so.
.PP
Use \fIpathname column #0\fR to configure the tree column.
.RE
.TP
\fIpathname \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
Returns 1 if the specified \fIitem\fR is present in the tree,
0 otherwise.
.TP
\fIpathname \fBfocus \fR?\fIitem\fR?
If \fIitem\fR is specified, sets the focus item to \fIitem\fR.
Otherwise, returns the current focus item, or \fB{}\fR if there is none.
.\" Need: way to clear the focus item.  {} works for this...
.TP
\fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the heading options for the specified \fIcolumn\fR.
Valid options are:
.RS
.TP
\fB\-text \fItext\fR
The text to display in the column heading.







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
Returns 1 if the specified \fIitem\fR is present in the tree,
0 otherwise.
.TP
\fIpathname \fBfocus \fR?\fIitem\fR?
If \fIitem\fR is specified, sets the focus item to \fIitem\fR.
Otherwise, returns the current focus item, or \fB{}\fR if there is none.
.\" Need: way to clear the focus item.  {} works for this...
.TP 
\fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the heading options for the specified \fIcolumn\fR.
Valid options are:
.RS
.TP
\fB\-text \fItext\fR
The text to display in the column heading.
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
.IP cell
A data cell.
.RE
\fIpathname \fBidentify item \fIx y\fR
Returns the item ID of the item at position \fIy\fR.
.TP
\fIpathname \fBidentify column \fIx y\fR
Returns the display column identifier of the cell at position \fIx\fR.
The tree column has ID \fB#0\fR.
.TP
\fIpathname \fBidentify element \fIx y\fR
The element at position \fIx,y\fR.
.TP
\fIpathname \fBidentify row \fIx y\fR
Obsolescent synonym for \fIpathname \fBidentify item\fR.
.PP
See \fBCOLUMN IDENTIFIERS\fR for a discussion of display columns
and data columns.
.RE
.TP
\fIpathname \fBindex \fIitem\fR
Returns the integer index of \fIitem\fR within its parent's list of children.
.TP
\fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR
Creates a new item.
\fIparent\fR is the item ID of the parent item,
or the empty string \fB{}\fR
to create a new top-level item.
\fIindex\fR is an integer, or the value \fBend\fR, specifying where in the
list of \fIparent\fR's children to insert the new item.
If \fIindex\fR is less than or equal to zero,
the new node is inserted at the beginning;
if \fIindex\fR is greater than or equal to the current number of children,
it is inserted at the end.
If \fB\-id\fR is specified, it is used as the item identifier;
\fIid\fR must not already exist in the tree.
Otherwise, a new unique identifier is generated.
.RS
.PP
\fIpathname \fBinsert\fR returns the item identifier of the
newly created item.
See \fBITEM OPTIONS\fR for the list of available options.
.RE
.TP
\fIpathname \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the options for the specified \fIitem\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the item's options are updated with the specified values.
See \fBITEM OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBmove \fIitem parent index\fR
Moves \fIitem\fR to position \fIindex\fR in \fIparent\fR's list of children.
It is illegal to move an item under one of its descendants.
.RS
.PP
If \fIindex\fR is less than or equal to zero, \fIitem\fR is moved
to the beginning; if greater than or equal to the number of children,
it is moved to the end.
.RE
.TP
\fIpathname \fBnext \fIitem\fR
Returns the identifier of \fIitem\fR's next sibling,
or \fB{}\fR if \fIitem\fR is the last child of its parent.
.TP
\fIpathname \fBparent \fIitem\fR
Returns the ID of the parent of \fIitem\fR,
or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy.
.TP
\fIpathname \fBprev \fIitem\fR
Returns the identifier of \fIitem\fR's previous sibling,
or \fB{}\fR if \fIitem\fR is the first child of its parent.
.TP
\fIpathname \fBsee \fIitem\fR
Ensure that \fIitem\fR is visible:
sets all of \fIitem\fR's ancestors to \fB\-open true\fR,
and scrolls the widget if necessary so that \fIitem\fR is
within the visible portion of the tree.
.TP
\fIpathname \fBselection\fR ?\fIselop itemList\fR?
If \fIselop\fR is not specified, returns the list of selected items.
Otherwise, \fIselop\fR is one of the following:
.RS
.TP







|
















|





|


















|

|













|







|







|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
.IP cell
A data cell.
.RE
\fIpathname \fBidentify item \fIx y\fR
Returns the item ID of the item at position \fIy\fR.
.TP
\fIpathname \fBidentify column \fIx y\fR
Returns the data column identifier of the cell at position \fIx\fR.
The tree column has ID \fB#0\fR.
.TP
\fIpathname \fBidentify element \fIx y\fR
The element at position \fIx,y\fR.
.TP
\fIpathname \fBidentify row \fIx y\fR
Obsolescent synonym for \fIpathname \fBidentify item\fR.
.PP
See \fBCOLUMN IDENTIFIERS\fR for a discussion of display columns
and data columns.
.RE
.TP
\fIpathname \fBindex \fIitem\fR
Returns the integer index of \fIitem\fR within its parent's list of children.
.TP
\fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR
Creates a new item.  
\fIparent\fR is the item ID of the parent item,
or the empty string \fB{}\fR
to create a new top-level item.
\fIindex\fR is an integer, or the value \fBend\fR, specifying where in the
list of \fIparent\fR's children to insert the new item.
If \fIindex\fR is less than or equal to zero, 
the new node is inserted at the beginning;
if \fIindex\fR is greater than or equal to the current number of children,
it is inserted at the end.
If \fB\-id\fR is specified, it is used as the item identifier;
\fIid\fR must not already exist in the tree.
Otherwise, a new unique identifier is generated.
.RS
.PP
\fIpathname \fBinsert\fR returns the item identifier of the
newly created item.
See \fBITEM OPTIONS\fR for the list of available options.
.RE
.TP
\fIpathname \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the options for the specified \fIitem\fR.
If no \fI\-option\fR is specified, 
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified, 
returns the value of that option.
Otherwise, the item's options are updated with the specified values.
See \fBITEM OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBmove \fIitem parent index\fR
Moves \fIitem\fR to position \fIindex\fR in \fIparent\fR's list of children.
It is illegal to move an item under one of its descendants.
.RS
.PP
If \fIindex\fR is less than or equal to zero, \fIitem\fR is moved
to the beginning; if greater than or equal to the number of children,
it is moved to the end.
.RE
.TP 
\fIpathname \fBnext \fIitem\fR
Returns the identifier of \fIitem\fR's next sibling,
or \fB{}\fR if \fIitem\fR is the last child of its parent.
.TP
\fIpathname \fBparent \fIitem\fR
Returns the ID of the parent of \fIitem\fR,
or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy.
.TP 
\fIpathname \fBprev \fIitem\fR
Returns the identifier of \fIitem\fR's previous sibling,
or \fB{}\fR if \fIitem\fR is the first child of its parent.
.TP
\fIpathname \fBsee \fIitem\fR
Ensure that \fIitem\fR is visible:
sets all of \fIitem\fR's ancestors to \fB\-open true\fR,
and scrolls the widget if necessary so that \fIitem\fR is 
within the visible portion of the tree.
.TP
\fIpathname \fBselection\fR ?\fIselop itemList\fR?
If \fIselop\fR is not specified, returns the list of selected items.
Otherwise, \fIselop\fR is one of the following:
.RS
.TP
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
.TP
\fIpathname \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBtag \fIargs...\fR
.RS
.TP
\fIpathName \fBtag add \fItag items\fR
Adds the specified \fItag\fR to each of the listed \fIitems\fR.
If \fItag\fR is already present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.TP
\fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR?
Add a Tk binding script for the event sequence \fIsequence\fR
to the tag \fItagName\fR.  When an X event is delivered to an item,
binding scripts for each of the item's \fB\-tags\fR are evaluated
in order as per \fIbindtags(n)\fR.
.RS
.PP
\fB<Key>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<Button>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
are sent to the item under the mouse pointer.
No other event types are supported.
.PP
The binding \fIscript\fR undergoes \fB%\fR-substitutions before
evaluation; see \fBbind(n)\fR for details.
.RE
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR?
Query or modify the options for the specified \fItagName\fR.
If one or more \fIoption/value\fR pairs are specified,
sets the value of those options for the specified tag.
If a single \fIoption\fR is specified,
returns the value of that option
(or the empty string if the option has not been specified for \fItagName\fR).
With no additional arguments,
returns a dictionary of the option settings for \fItagName\fR.
See \fBTAG OPTIONS\fR for the list of available options.
.TP
\fIpathName \fBtag delete \fItagName\fR
Deletes all tag information for the \fItagName\fR argument. The
command removes the tag from all items in the widget and also deletes any
other information associated with the tag, such as bindings and display
information. The command returns an empty string.
.TP
\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR?
If \fIitem\fR is specified, returns 1 or 0
depending on whether the specified item has the named tag.
Otherwise, returns a list of all items which have
the specified tag.
.TP
\fIpathName \fBtag names\fR
Returns a list of all tags used by the widget.
.TP





\fIpathName \fBtag remove \fItag\fR ?\fIitems\fR?
Removes the specified \fItag\fR from each of the listed \fIitems\fR.
If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree.
If \fItag\fR is not present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.RE
.PP
The treeview widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBxview\fR	\fByview\fR
.DE

.SH "ITEM OPTIONS"
.PP
The following item options may be specified for items
in the \fBinsert\fR and \fBitem\fR widget commands.
.OP \-text text Text
The textual label to display for the item.
.OP \-image image Image







<
<
<
<
<

|





|

|
|


|







|
|

|



<
<
<
<
<
<









>
>
>
>
>
|



|

|
|
|
|
<
|
<
>







339
340
341
342
343
344
345





346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373






374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398

399
400
401
402
403
404
405
406
.TP
\fIpathname \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBtag \fIargs...\fR
.RS
.TP





\fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR?
Add a Tk binding script for the event sequence \fIsequence\fR 
to the tag \fItagName\fR.  When an X event is delivered to an item,
binding scripts for each of the item's \fB\-tags\fR are evaluated
in order as per \fIbindtags(n)\fR.
.RS
.PP
\fB<KeyPress>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<ButtonPress>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
are sent to the item under the mouse pointer.  
No other event types are supported.
.PP
The binding \fIscript\fR undergoes \fB%\fR-substitutions before 
evaluation; see \fBbind(n)\fR for details.
.RE
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR?
Query or modify the options for the specified \fItagName\fR.
If one or more \fIoption/value\fR pairs are specified,
sets the value of those options for the specified tag.
If a single \fIoption\fR is specified, 
returns the value of that option 
(or the empty string if the option has not been specified for \fItagName\fR).
With no additional arguments, 
returns a dictionary of the option settings for \fItagName\fR.
See \fBTAG OPTIONS\fR for the list of available options.
.TP






\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR?
If \fIitem\fR is specified, returns 1 or 0
depending on whether the specified item has the named tag.
Otherwise, returns a list of all items which have
the specified tag.
.TP
\fIpathName \fBtag names\fR
Returns a list of all tags used by the widget.
.TP
\fIpathName \fBtag add\fR \fItag\fR \fIitems\fR
Adds the specified \fItag\fR to each of the listed \fIitems\fR.
If \fItag\fR is already present for a particular item,
then the \fB-tags\fR for that item are unchanged.
.TP
\fIpathName \fBtag remove\fR \fItag\fR ?\fIitems\fR?
Removes the specified \fItag\fR from each of the listed \fIitems\fR.
If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree.
If \fItag\fR is not present for a particular item,
then the \fB-tags\fR for that item are unchanged.
.RE
.TP
\fIpathName \fBxview \fIargs\fR
Standard command for horizontal scrolling; see \fIwidget(n)\fR.
.TP

\fIpathName \fByview \fIargs\fR

Standard command for vertical scrolling; see \fIttk::widget(n)\fR.
.SH "ITEM OPTIONS"
.PP
The following item options may be specified for items
in the \fBinsert\fR and \fBitem\fR widget commands.
.OP \-text text Text
The textual label to display for the item.
.OP \-image image Image
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
If there are more values than columns,
the extra values are ignored.
.RE
.OP \-open open Open
A boolean value indicating whether the item's children
should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR).
.OP \-tags tags Tags
A list of tags associated with this item.
.SH "TAG OPTIONS"
.PP
The following options may be specified on tags:
.IP \fB\-foreground\fR
Specifies the text foreground color.
.IP \fB\-background\fR
Specifies the cell or item background color.
.IP \fB\-font\fR
Specifies the font to use when drawing text.
.\" ??? Maybe: .IP \-anchor
.\" ??? Maybe: .IP \-padding
.\" ??? Maybe: .IP \-text
.IP \fB\-image\fR
Specifies the item image, in case the item's \fB\-image\fR option is empty.
.\" .PP
.\" \fI(@@@ TODO: sort out order of precedence for options)\fR
.PP
Tag priority is decided by the creation order: tags created first receive
higher priority.
.SH "COLUMN IDENTIFIERS"
.PP
Column identifiers take any of the following forms:
.IP \(bu
A symbolic name from the list of \fB\-columns\fR.
.IP \(bu
An integer \fIn\fR, specifying the \fIn\fRth data column.
.IP \(bu
A string of the form \fB#\fIn\fR, where \fIn\fR is an integer,
specifying the \fIn\fRth display column.
.PP
\fBNOTE:\fR
Item \fB\-values\fR may be displayed in a different order than
the order in which they are stored.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.PP
A \fIdata column number\fR is an index into an item's \fB\-values\fR list;
a \fIdisplay column number\fR is the column number in the tree
where the values are displayed.
Tree labels are displayed in column #0.
If \fB\-displaycolumns\fR is not set,
then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR.
Again, \fBcolumn #0 always refers to the tree column\fR.
.SH "VIRTUAL EVENTS"
.PP
The treeview widget generates the following virtual events.
.IP <<TreeviewSelect>>
Generated whenever the selection changes.
.IP <<TreeviewOpen>>
Generated just before setting the focus item to \fB\-open true\fR.
.IP <<TreeviewClose>>
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
'\" Not yet:
'\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field
'\" of the virtual event.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::treeview\fP is \fBTreeview\fP.
The treeview header class name is \fBHeading\fP.
The treeview item class name is \fBItem\fP.
The treeview cell class name is \fBCell\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBselected\fP.
.PP
\fBTreeview\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-rowheight\fP \fIamount\fP
.RS
The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP
value or by the configured font size and must always be set.  Also make
sure that the \fB\-rowheight\fP is large enough to contain any images.
.PP
To adjust the \fB\-rowheight\fP for the Treeview style, use the following code
after \fBtk scaling\fP has been applied.
Note that even if you do not support or change \fBtk scaling\fP
in your program, your users may have it set in their .wishrc.
.RE
.PP
.CS
ttk::style configure Treeview \\
     \-rowheight [expr {[font metrics \fIfont\fP \-linespace] + 2}]
.CE
.PP
\fBHeading\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
\fBItem\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatormargins\fP \fIpadding\fP
.br
\fB\-indicatorsize\fP \fIamount\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
\fBCell\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), listbox(n), image(n), bind(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







|
















<
<
<











|
|







|



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479


































































480
481
482
483
484
If there are more values than columns,
the extra values are ignored.
.RE
.OP \-open open Open
A boolean value indicating whether the item's children
should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR).
.OP \-tags tags Tags
A list of tags associated with this item.  
.SH "TAG OPTIONS"
.PP
The following options may be specified on tags:
.IP \fB\-foreground\fR
Specifies the text foreground color.
.IP \fB\-background\fR
Specifies the cell or item background color.
.IP \fB\-font\fR
Specifies the font to use when drawing text.
.\" ??? Maybe: .IP \-anchor
.\" ??? Maybe: .IP \-padding
.\" ??? Maybe: .IP \-text
.IP \fB\-image\fR
Specifies the item image, in case the item's \fB\-image\fR option is empty.
.\" .PP
.\" \fI(@@@ TODO: sort out order of precedence for options)\fR



.SH "COLUMN IDENTIFIERS"
.PP
Column identifiers take any of the following forms:
.IP \(bu
A symbolic name from the list of \fB\-columns\fR.
.IP \(bu
An integer \fIn\fR, specifying the \fIn\fRth data column.
.IP \(bu
A string of the form \fB#\fIn\fR, where \fIn\fR is an integer,
specifying the \fIn\fRth display column.
.PP
\fBNOTE:\fR 
Item \fB\-values\fR may be displayed in a different order than 
the order in which they are stored.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.PP
A \fIdata column number\fR is an index into an item's \fB\-values\fR list;
a \fIdisplay column number\fR is the column number in the tree
where the values are displayed.  
Tree labels are displayed in column #0.
If \fB\-displaycolumns\fR is not set,
then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR.
Again, \fBcolumn #0 always refers to the tree column\fR.
.SH "VIRTUAL EVENTS"
.PP
The treeview widget generates the following virtual events.
.IP <<TreeviewSelect>>
Generated whenever the selection changes.
.IP <<TreeviewOpen>>
Generated just before setting the focus item to \fB\-open true\fR.
.IP <<TreeviewClose>>
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
'\" Not yet:
'\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field
'\" of the virtual event.


































































.SH "SEE ALSO"
ttk::widget(n), listbox(n), image(n), bind(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_vsapi.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_vsapi n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_vsapi \- Define a Microsoft Visual Styles element
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBvsapi\fR \fIclassName\fR \fIpartId\fR ?\fIstateMap\fR? ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fBvsapi\fR element factory creates a new element
in the current theme whose visual appearance is drawn using the
Microsoft Visual Styles API which is responsible for the themed styles
on Windows XP and Vista. This factory permits any of the Visual
Styles parts to be declared as Ttk elements that can then be
included in a style layout to modify the appearance of Ttk widgets.
.PP
\fIclassName\fR and \fIpartId\fR are required parameters and specify
the Visual Styles class and part as given in the Microsoft
documentation. The \fIstateMap\fR may be provided to map Ttk states to
Visual Styles API states (see \fBSTATE MAP\fR).
.SH "OPTIONS"
.PP
Valid \fIoptions\fR are:
.TP
\fB\-padding \fIpadding\fR
.
Specify the element's interior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
This option may not be mixed with any other options.
.TP
\fB\-margins \fIpadding\fR
.
Specifies the elements exterior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
This option may not be mixed with any other options.
.TP
\fB\-width \fIwidth\fR
.
Specifies the height for the element. If this option is set then
the Visual Styles API will not be queried for the recommended
size or the part. If this option is set then \fB\-height\fR should
also be set. The \fB\-width\fR and \fB\-height\fR options cannot
be mixed with the \fB\-padding\fR or \fB\-margins\fR options.
.TP
\fB\-height \fIheight\fR
.
Specifies the height of the element. See the comments for \fB\-width\fR.
.SH "STATE MAP"
.PP
The \fIstateMap\fR parameter is a list of ttk states and the
corresponding Visual Styles API state value.
This permits the element appearance to respond to changes in the
widget state such as becoming active or being pressed. The list should
be as described for the \fBttk::style map\fR command but note that the
last pair in the list should be the default state and is typically an
empty list and 1. Unfortunately all the Visual Styles parts have
different state values and these must be looked up either in the
Microsoft documentation or more likely in the header files. The
original header to use was \fItmschema.h\fR, but in more recent
versions of the Windows Development Kit this is \fIvssym32.h\fR.
.PP
If no \fIstateMap\fR parameter is given there is an implicit default
map of {{} 1}
.SH "EXAMPLE"
.PP
Create a correctly themed close button by changing the layout of
a \fBttk::button\fR(n). This uses the WINDOW part WP_SMALLCLOSEBUTTON
and as documented the states CBS_DISABLED, CBS_HOT, CBS_NORMAL and
CBS_PUSHED are mapped from ttk states.
.CS
ttk::style element create smallclose \fBvsapi\fR WINDOW 19 \\
    {disabled 4 pressed 3 active 2 {} 1}
ttk::style layout CloseButton {CloseButton.smallclose -sticky news}
pack [ttk::button .close -style CloseButton]
.CE
.PP
Change the appearance of a \fBttk::checkbutton\fR(n) to use the
Explorer pin part EBP_HEADERPIN.
.CS
ttk::style element create pin \fBvsapi\fR EXPLORERBAR 3 {
    {pressed !selected} 3
    {active !selected} 2
    {pressed selected} 6
    {active selected} 5
    {selected} 4
    {} 1
}





|










|

|

|
|



|





|
<



<
<
<
<
<
<
<


|
<





|
<


|
|
|

|
<
|




|


|



|






|




|





|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35







36
37
38

39
40
41
42
43
44

45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk_vsapi n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_vsapi \- Define a Microsoft Visual Styles element
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBvsapi\fR \fIclassName\fR \fIpartId\fR ?\fIstateMap\fR? ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fIvsapi\fR element factory creates a new element
in the current theme whose visual appearance is drawn using the
Microsoft Visual Styles API which is reponsible for the themed styles
on Windows XP and Vista. This factory permits any of the Visual
Styles parts to be declared as ttk elements that can then be
included in a style layout to modify the appearance of ttk widgets.
.PP
\fIclassName\fR and \fIpartId\fR are required parameters and specify
the Visual Styles class and part as given in the Microsoft
documentation. The \fIstateMap\fR may be provided to map ttk states to
Visual Styles API states (see \fBSTATE MAP\fR).
.SH "OPTIONS"
.PP
Valid \fIoptions\fR are:
.TP
\fB\-padding\fR \fIpadding\fR

Specify the element's interior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.







This option may not be mixed with any other options.
.TP
\fB\-margins\fR \fIpadding\fR

Specifies the elements exterior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
This option may not be mixed with any other options.
.TP
\fB\-width\fR \fIwidth\fR

Specifies the height for the element. If this option is set then
the Visual Styles API will not be queried for the recommended
size or the part. If this option is set then \fI-height\fR should
also be set. The \fI-width\fR and \fI-height\fR options cannot
be mixed with the \fI-padding\fR or \fI-margins\fR options.
.TP
\fB\-height\fR \fIheight\fR

Specifies the height of the element. See the comments for \fI-width\fR.
.SH "STATE MAP"
.PP
The \fIstateMap\fR parameter is a list of ttk states and the
corresponding Visual Styles API state value.
This permits the element appearence to respond to changes in the
widget state such as becoming active or being pressed. The list should
be as described for the \fBttk::style map\fR command but note that the
last pair in the list should be the default state and is typically and
empty list and 1. Unfortunately all the Visual Styles parts have
different state values and these must be looked up either in the
Microsoft documentation or more likely in the header files. The
original header to use was \fItmschema.h\fR but in more recent
versions of the Windows Development Kit this is \fIvssym32.h\fR.
.PP
If no \fIstateMap\fR parameter is given there is an implicit default
map of {{} 1}
.SH "EXAMPLE"
.PP
Create a correctly themed close button by changing the layout of 
a \fBttk::button\fR(n). This uses the WINDOW part WP_SMALLCLOSEBUTTON
and as documented the states CBS_DISABLED, CBS_HOT, CBS_NORMAL and
CBS_PUSHED are mapped from ttk states.
.CS
ttk::style element create smallclose vsapi WINDOW 19 \\
    {disabled 4 pressed 3 active 2 {} 1}
ttk::style layout CloseButton {CloseButton.smallclose -sticky news}
pack [ttk::button .close -style CloseButton]
.CE
.PP
Change the appearence of a \fBttk::checkbutton\fR(n) to use the
Explorer pin part EBP_HEADERPIN.
.CS
ttk::style element create pin vsapi EXPLORERBAR 3 {
    {pressed !selected} 3
    {active !selected} 2
    {pressed selected} 6
    {active selected} 5
    {selected} 4
    {} 1
}

Changes to doc/ttk_widget.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::widget n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::widget \- Standard options and commands supported by Tk themed widgets
.BE
.SH DESCRIPTION
This manual describes common widget options and commands.






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::widget n 8.5.9 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::widget \- Standard options and commands supported by Tk themed widgets
.BE
.SH DESCRIPTION
This manual describes common widget options and commands.
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75






76
77
78







79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Each of the numbers is a fraction between 0 and 1 indicating
a position in the document; 0 indicates the beginning,
and 1 indicates the end.
The first fraction indicates the first information in the widget
that is visible in the window, and the second fraction indicates
the information just after the last portion that is visible.
.PP
Typically the \fB\-xscrollcommand\fR option consists of the path name
of a \fBscrollbar\fR widget followed by
.QW set ,
e.g.
.QW ".x.scrollbar set" .
This will cause the scrollbar to be updated whenever the view in the
window changes.
.PP
If this option is set to the empty string (the default),
then no command will be executed.
.RE
.OP \-yscrollcommand yScrollCommand ScrollCommand
A command prefix, used to communicate with vertical scrollbars.
See the description of \fB\-xscrollcommand\fR above for details.
.SH "LABEL OPTIONS"
The following options are supported by labels, buttons,
and other button-like widgets:
.OP \-anchor anchor Anchor
Specifies how the information in the widget is positioned






relative to the inner margins.  Legal values are
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR.







See also \fB\-justify\fR (for widgets supporting this option).

.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
If set to the empty string (the default), the rules described in the
"Elements" section of \fIttk::intro(n)\fR explain which value is actually
used.
Valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.
.IP top
.IP bottom
.IP left
.IP right
Display image above, below, left of, or right of the text, respectively.
.IP none
Display the image if present, otherwise the text.
.RE
.OP \-font font Font
Font to use for the text displayed by the widget.
.OP \-foreground textColor TextColor
The widget's foreground color.
If unspecified, the theme default is used.
.OP \-image image Image
Specifies an image to display.
This is a list of 1 or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR pairs
as per \fBstyle map\fR, specifying different images to use when
the widget is in a particular state or combination of states.
All images in the list should have the same size.
.OP \-justify justify Justify
If there are multiple lines of text, specifies how
the lines are laid out relative to one another.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
See also \fB\-anchor\fR (for widgets supporting this option).
.OP \-padding padding Padding
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-text text Text
Specifies a text string to be displayed inside the widget
(unless overridden by \fB\-textvariable\fR for the widgets supporting this option).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string.
The underlined character is used for mnemonic activation.
.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.
Note that some themes may specify a non-zero \fB\-width\fR
in the style.
.OP \-wraplength wrapLength WrapLength
Specifies the maximum line length. The value may have any of the forms
acceptable to \fBTk_GetPixels\fR. If this option is less than or equal
to zero, then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "ENTRY OPTIONS"
The following options are supported by entry, spinbox and combobox:
.OP \-placeholder placeHolder PlaceHolder
Specifies a help text string to display if no text is otherwise displayed,
that is when the widget is empty. The placeholder text is displayed using
the values of the \fB\-font\fR, \fB\-justify\fR and
\fB\-placeholderforeground\fR options.
.OP \-placeholderforeground placeHolderForeground PlaceHolderForeground
Specifies the foreground color of the placeholder text.
.SH "COMPATIBILITY OPTIONS"
This option is only available for themed widgets that have
.QW corresponding
traditional Tk widgets.
.OP \-state state State
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.
.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE
.TP
\fIpathName \fBxview \fIargs\fR
This command is used to query and change the horizontal position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the left, the middle 40% is visible
in the window, and 40% of the content is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR
Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the content appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.TP
\fIpathName \fByview \fIargs\fR
This command is used to query and change the vertical position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fByview\fR
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the vertical span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the top, the middle 40% is visible
in the window, and 40% of the content is off-screen to the bottom.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview\fR \fIindex\fR
Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the top edge of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR
Adjusts the view in the window so that the item \fIfraction\fR of the
way through the content appears at the top edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
This command shifts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then items farther to the top
become visible;  if it is positive then items farther to the bottom
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR average-width characters on the display.
.RE
.SH "WIDGET STATES"
The widget state is a bitmap of independent state flags.
Widget state flags include:
.TP
\fBactive\fR
.
The mouse cursor is over the widget
and pressing a mouse button will cause some action to occur. (aka
.QW prelight
(Gnome),
.QW hot
(Windows),
.QW hover ).
.TP
\fBdisabled\fR
.
Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive ).
.TP
\fBfocus\fR
.
Widget has keyboard focus.
.TP
\fBpressed\fR
.
Widget is being pressed (aka
.QW armed
in Motif).
.TP
\fBselected\fR
.
.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.
.TP
\fBbackground\fR
.
Windows and the Mac have a notion of an
.QW active
or foreground window.
The \fBbackground\fR state is set for widgets in a background window,
and cleared for those in the foreground window.
.TP
\fBreadonly\fR
.
Widget should not allow user modification.
.TP
\fBalternate\fR
.
A widget-specific alternate display format.
For example, used for checkbuttons and radiobuttons in the
.QW tristate
or
.QW mixed
state, and for buttons with \fB\-default active\fR.
.TP
\fBinvalid\fR
.
The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)
.TP
\fBhover\fR
.
The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.
.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]

# Disable the widget:
$b \fBstate\fR disabled

# Invoke the widget only if it is currently pressed and enabled:
$b \fBinstate\fR {pressed !disabled} { .b invoke }

# Reenable widget:
$b \fBstate\fR !disabled
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n)
.SH KEYWORDS
state, configure, option
'\" Local Variables:
'\" mode: nroff
'\" End:







|
















|
|
>
>
>
>
>
>
|
<
<
>
>
>
>
>
>
>
|
>



<
<
<














|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<









|
<




<














|
<






|
<









<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<









<


|


<
|


<





<







<







<



<








<





<















|


|


|








50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110







































111
112
113
114
115

















116



117
118
119
120
121
122
123
124
125
126

127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175

















































































176
177
178
179
180

181
182
183
184
185
186
187
188
189

190
191
192
193
194

195
196
197

198
199
200
201
202

203
204
205
206
207
208
209

210
211
212
213
214
215
216

217
218
219

220
221
222
223
224
225
226
227

228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
Each of the numbers is a fraction between 0 and 1 indicating
a position in the document; 0 indicates the beginning,
and 1 indicates the end.
The first fraction indicates the first information in the widget
that is visible in the window, and the second fraction indicates
the information just after the last portion that is visible.
.PP
Typically the \fBxScrollCommand\fR option consists of the path name
of a \fBscrollbar\fR widget followed by
.QW set ,
e.g.
.QW ".x.scrollbar set" .
This will cause the scrollbar to be updated whenever the view in the
window changes.
.PP
If this option is set to the empty string (the default),
then no command will be executed.
.RE
.OP \-yscrollcommand yScrollCommand ScrollCommand
A command prefix, used to communicate with vertical scrollbars.
See the description of \fB\-xscrollcommand\fR above for details.
.SH "LABEL OPTIONS"
The following options are supported by labels, buttons,
and other button-like widgets:
.OP \-text text Text
Specifies a text string to be displayed inside the widget
(unless overridden by \fB\-textvariable\fR).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string.


The underlined character is used for mnemonic activation.
.OP \-image image Image
Specifies an image to display.
This is a list of 1 or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR pairs
as per \fBstyle map\fR, specifying different images to use when
the widget is in a particular state or combination of states.
All images in the list should have the same size.
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.



Valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.
.IP top
.IP bottom
.IP left
.IP right
Display image above, below, left of, or right of the text, respectively.
.IP none
The default; display the image if present, otherwise the text.
.RE







































.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.

















.SH "COMPATIBILITY OPTIONS"



.OP \-state state State
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS
.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.
.TP
\fIpathName \fBidentify\fR \fBelement\fR \fIx y\fR

Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands.
.TP
\fIpathName \fBinstate\fR \fIstatespec\fR ?\fIscript\fR?

Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?

Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE

















































































.SH "WIDGET STATES"
The widget state is a bitmap of independent state flags.
Widget state flags include:
.TP
\fBactive\fR

The mouse cursor is over the widget
and pressing a mouse button will cause some action to occur. (aka
.QW prelight
(Gnome),
.QW hot
(Windows),
.QW hover ).
.TP
\fBdisabled\fR

Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive )
.TP
\fBfocus\fR

Widget has keyboard focus
.TP
\fBpressed\fR

Widget is being pressed (aka
.QW armed
in Motif).
.TP
\fBselected\fR

.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.
.TP
\fBbackground\fR

Windows and the Mac have a notion of an
.QW active
or foreground window.
The \fBbackground\fR state is set for widgets in a background window,
and cleared for those in the foreground window.
.TP
\fBreadonly\fR

Widget should not allow user modification.
.TP
\fBalternate\fR

A widget-specific alternate display format.
For example, used for checkbuttons and radiobuttons in the
.QW tristate
or
.QW mixed
state, and for buttons with \fB\-default active\fR.
.TP
\fBinvalid\fR

The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)
.TP
\fBhover\fR

The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.
.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]

# Disable the widget:
$b state disabled

# Invoke the widget only if it is currently pressed and enabled:
$b instate {pressed !disabled} { .b invoke }

# Reenable widget:
$b state !disabled
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n)
.SH KEYWORDS
state, configure, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/winfo.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
'\"
'\" 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.
'\"
.TH winfo n 4.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
winfo \- Return window-related information
.SH SYNOPSIS
\fBwinfo\fR \fIoption \fR?\fIarg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBwinfo\fR command is used to retrieve information about windows
managed by Tk.  It can take any of a number of different forms,
depending on the \fIoption\fR argument.  The legal forms are:
.TP
\fBwinfo atom \fR?\fB\-displayof \fIwindow\fR? \fIname\fR






|







|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" 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.
'\" 
.TH winfo n 4.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
winfo \- Return window-related information
.SH SYNOPSIS
\fBwinfo\fR \fIoption \fR?\fIarg arg ...\fR?
.BE

.SH DESCRIPTION
.PP
The \fBwinfo\fR command is used to retrieve information about windows
managed by Tk.  It can take any of a number of different forms,
depending on the \fIoption\fR argument.  The legal forms are:
.TP
\fBwinfo atom \fR?\fB\-displayof \fIwindow\fR? \fIname\fR
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
system of the root window (if a virtual-root window manager is in
use then the coordinate system of the virtual root window is used).
If the \fB\-displayof\fR option is given then the coordinates refer
to the screen containing \fIwindow\fR;  otherwise they refer to the
screen of the application's main window.
If no window in this application contains the point then an empty
string is returned.
An empty string is also returned if the point lies in the title bar
or border of its highest containing toplevel in this application.
(Note that with some window managers the borders may be invisible.)
In selecting the containing window, children are given higher priority
than parents and among siblings the highest one in the stacking order is
chosen.
.TP
\fBwinfo depth \fIwindow\fR
Returns a decimal string giving the depth of \fIwindow\fR (number
of bits per pixel).







<
<
<







70
71
72
73
74
75
76



77
78
79
80
81
82
83
system of the root window (if a virtual-root window manager is in
use then the coordinate system of the virtual root window is used).
If the \fB\-displayof\fR option is given then the coordinates refer
to the screen containing \fIwindow\fR;  otherwise they refer to the
screen of the application's main window.
If no window in this application contains the point then an empty
string is returned.



In selecting the containing window, children are given higher priority
than parents and among siblings the highest one in the stacking order is
chosen.
.TP
\fBwinfo depth \fIwindow\fR
Returns a decimal string giving the depth of \fIwindow\fR (number
of bits per pixel).
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
Returns the geometry for \fIwindow\fR, in the form
\fIwidth\fBx\fIheight\fB+\fIx\fB+\fIy\fR.  All dimensions are
in pixels.
.TP
\fBwinfo height \fIwindow\fR
Returns a decimal string giving \fIwindow\fR's height in pixels.
When a window is first created its height will be 1 pixel;  the
height will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true height immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqheight\fR to get the window's requested height
instead of its actual height.
.TP
\fBwinfo id \fIwindow\fR







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
Returns the geometry for \fIwindow\fR, in the form
\fIwidth\fBx\fIheight\fB+\fIx\fB+\fIy\fR.  All dimensions are
in pixels.
.TP
\fBwinfo height \fIwindow\fR
Returns a decimal string giving \fIwindow\fR's height in pixels.
When a window is first created its height will be 1 pixel;  the
height will eventually be changed by a geometry manager to fulfill
the window's needs.
If you need the true height immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqheight\fR to get the window's requested height
instead of its actual height.
.TP
\fBwinfo id \fIwindow\fR
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.
.TP
\fBwinfo width \fIwindow\fR
Returns a decimal string giving \fIwindow\fR's width in pixels.
When a window is first created its width will be 1 pixel;  the
width will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true width immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqwidth\fR to get the window's requested width
instead of its actual width.
.TP
\fBwinfo x \fIwindow\fR
Returns a decimal string giving the x-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.TP
\fBwinfo y \fIwindow\fR
Returns a decimal string giving the y-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.SH EXAMPLE
.PP
Print where the mouse pointer is and what window it is currently over:
.CS
lassign [\fBwinfo pointerxy\fR .] x y
puts \-nonewline "Mouse pointer at ($x,$y) which is "
set win [\fBwinfo containing\fR $x $y]
if {$win eq ""} {
    puts "over no window"
} else {
    puts "over $win"
}
.CE

.SH KEYWORDS
atom, children, class, geometry, height, identifier, information, interpreters,
mapped, parent, path name, screen, virtual root, width, window
'\" Local Variables:
'\" mode: nroff
'\" End:







|


















<











>



<
<
<
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352



relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.
.TP
\fBwinfo width \fIwindow\fR
Returns a decimal string giving \fIwindow\fR's width in pixels.
When a window is first created its width will be 1 pixel;  the
width will eventually be changed by a geometry manager to fulfill
the window's needs.
If you need the true width immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqwidth\fR to get the window's requested width
instead of its actual width.
.TP
\fBwinfo x \fIwindow\fR
Returns a decimal string giving the x-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.TP
\fBwinfo y \fIwindow\fR
Returns a decimal string giving the y-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.SH EXAMPLE

Print where the mouse pointer is and what window it is currently over:
.CS
lassign [\fBwinfo pointerxy\fR .] x y
puts \-nonewline "Mouse pointer at ($x,$y) which is "
set win [\fBwinfo containing\fR $x $y]
if {$win eq ""} {
    puts "over no window"
} else {
    puts "over $win"
}
.CE

.SH KEYWORDS
atom, children, class, geometry, height, identifier, information, interpreters,
mapped, parent, path name, screen, virtual root, width, window



Changes to doc/wish.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19

20
21
22
23
24
25
26
'\"
'\" Copyright (c) 1991-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH wish 1 8.0 Tk "Tk Applications"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg ...\fR?
.SH OPTIONS
.IP "\fB\-encoding \fIname\fR" 20

Specifies the encoding of the text stored in \fIfileName\fR.
This option is only recognized prior to the \fIfileName\fR argument.

.IP "\fB\-colormap \fInew\fR" 20
Specifies that the window should have a new private colormap instead of
using the default colormap for the screen.
.IP "\fB\-display \fIdisplay\fR" 20
Display (and screen) on which to display window.
.IP "\fB\-geometry \fIgeometry\fR" 20
Initial geometry to use for window.  If this option is specified, its






|







|


>


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1991-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH wish 1 8.0 Tk "Tk Applications"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
.SH OPTIONS
.IP "\fB\-encoding \fIname\fR" 20
.VS 8.5
Specifies the encoding of the text stored in \fIfileName\fR.
This option is only recognized prior to the \fIfileName\fR argument.
.VE 8.5
.IP "\fB\-colormap \fInew\fR" 20
Specifies that the window should have a new private colormap instead of
using the default colormap for the screen.
.IP "\fB\-display \fIdisplay\fR" 20
Display (and screen) on which to display window.
.IP "\fB\-geometry \fIgeometry\fR" 20
Initial geometry to use for window.  If this option is specified, its
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
.SH DESCRIPTION
.PP
\fBWish\fR is a simple program consisting of the Tcl command
language, the Tk toolkit, and a main program that reads commands
from standard input or from a file.
It creates a main window and then processes Tcl commands.
If \fBwish\fR is invoked with arguments, then the first few
arguments, ?\fB\-encoding \fIname\fR? ?\fIfileName\fR?, specify the
name of a script file, and, optionally, the
encoding of the text data stored in that script file.  A value
for \fIfileName\fR is recognized if the appropriate argument
does not start with
.QW \- .
.PP
If there are no arguments, or the arguments do not specify a \fIfileName\fR,
then wish reads Tcl commands interactively from standard input.
It will continue processing commands until all windows have been
deleted or until end-of-file is reached on standard input.
If there exists a file
.QW \fB.wishrc\fR
in the home directory of the user, \fBwish\fR evaluates the file as a
Tcl script just before reading the first command from standard input.
.PP
If arguments to \fBwish\fR do specify a \fIfileName\fR, then
\fIfileName\fR is treated as the name of a script file.
\fBWish\fR will evaluate the script in \fIfileName\fR (which
presumably creates a user interface), then it will respond to events
until all windows have been deleted.
Commands will not be read from standard input.
There is no automatic evaluation of
.QW \fB.wishrc\fR







|















|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
.SH DESCRIPTION
.PP
\fBWish\fR is a simple program consisting of the Tcl command
language, the Tk toolkit, and a main program that reads commands
from standard input or from a file.
It creates a main window and then processes Tcl commands.
If \fBwish\fR is invoked with arguments, then the first few
arguments, ?\fB\-encoding \fIname\fR? ?\fIfileName\fR? specify the
name of a script file, and, optionally, the
encoding of the text data stored in that script file.  A value
for \fIfileName\fR is recognized if the appropriate argument
does not start with
.QW \- .
.PP
If there are no arguments, or the arguments do not specify a \fIfileName\fR,
then wish reads Tcl commands interactively from standard input.
It will continue processing commands until all windows have been
deleted or until end-of-file is reached on standard input.
If there exists a file
.QW \fB.wishrc\fR
in the home directory of the user, \fBwish\fR evaluates the file as a
Tcl script just before reading the first command from standard input.
.PP
If arguments to \fBwish\fR do specify a \fIfileName\fR, then 
\fIfileName\fR is treated as the name of a script file.
\fBWish\fR will evaluate the script in \fIfileName\fR (which
presumably creates a user interface), then it will respond to events
until all windows have been deleted.
Commands will not be read from standard input.
There is no automatic evaluation of
.QW \fB.wishrc\fR
207
208
209
210
211
212
213
214
215
216
217
218
\fBtcl_prompt1\fR exists then it must consist of a Tcl script
to output a prompt;  instead of outputting a prompt \fBwish\fR
will evaluate the script in \fBtcl_prompt1\fR.
The variable \fBtcl_prompt2\fR is used in a similar way when
a newline is typed but the current command is not yet complete;
if \fBtcl_prompt2\fR is not set then no prompt is output for
incomplete commands.
.SH "SEE ALSO"
tclsh(1), toplevel(n), Tk_Main(3), Tk_MainLoop(3), Tk_MainWindow(3)
.SH KEYWORDS
application, argument, interpreter, prompt, script file, shell,
toolkit, toplevel







<
<

<
|
209
210
211
212
213
214
215


216

217
\fBtcl_prompt1\fR exists then it must consist of a Tcl script
to output a prompt;  instead of outputting a prompt \fBwish\fR
will evaluate the script in \fBtcl_prompt1\fR.
The variable \fBtcl_prompt2\fR is used in a similar way when
a newline is typed but the current command is not yet complete;
if \fBtcl_prompt2\fR is not set then no prompt is output for
incomplete commands.


.SH KEYWORDS

shell, toolkit

Changes to doc/wm.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1991-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\"
.TH wm n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wm \- Communicate with window manager
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1991-1994 The Regents of the University of California.
'\" Copyright (c) 1994-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.
'\" 
.TH wm n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wm \- Communicate with window manager
.SH SYNOPSIS
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80









81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98





99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
the \fIoption\fR argument.  All of the forms expect at least one
additional argument, \fIwindow\fR, which must be the path name of a
top-level window.
.PP
The legal forms for the \fBwm\fR command are:
.TP
\fBwm aspect \fIwindow\fR ?\fIminNumer minDenom maxNumer maxDenom\fR?
.
If \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
are all specified, then they will be passed to the window manager
and the window manager should use them to enforce a range of
acceptable aspect ratios for \fIwindow\fR.  The aspect ratio of
\fIwindow\fR (width/length) will be constrained to lie
between \fIminNumer\fR/\fIminDenom\fR and \fImaxNumer\fR/\fImaxDenom\fR.
If \fIminNumer\fR etc. are all specified as empty strings, then
any existing aspect ratio restrictions are removed.
If \fIminNumer\fR etc. are specified, then the command returns an
empty string.  Otherwise, it returns
a Tcl list containing four elements, which are the current values
of \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
(if no aspect restrictions are in effect, then an empty string is
returned).
.TP
\fBwm attributes \fIwindow\fR
.TP
\fBwm attributes \fIwindow\fR ?\fBoption\fR?
.TP
\fBwm attributes \fIwindow\fR ?\fBoption value option value...\fR?
.
This subcommand returns or sets platform specific attributes associated
with a window. The first form returns a list of the platform specific
flags and their values. The second form returns the value for the
specific option. The third form sets one or more of the values. The
values are as follows:
.RS
.PP
All platforms support the following attributes (though X11 users
should see the notes below):
.TP
\fB\-alpha\fR
.
Specifies the alpha transparency level of the toplevel. It accepts a value
from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque).  Values outside that
range will be constrained.  Where not supported, the \fB\-alpha\fR value
remains at \fB1.0\fR.
.TP
\fB\-fullscreen\fR
.
Places the window in a mode that takes up the entire screen, has no
borders, and covers the general use area (i.e. Start menu and taskbar on
Windows, dock and menubar on OSX, general window decorations on X11).
.TP
\fB\-topmost\fR
.
Specifies whether this is a topmost window (displays above all other windows).
.PP
On Windows, the following attributes may be set.
.TP









\fB\-disabled\fR
.
Specifies whether the window is in a disabled state.
.TP
\fB\-toolwindow\fR
.
Specifies a toolwindow style window (as defined in the MSDN).
.TP
\fB\-transparentcolor\fR
.
Specifies the transparent color index of the toplevel.  It takes any color
value accepted by \fBTk_GetColor\fR.  If the empty string is specified
(default), no transparent color is used.  This is supported on Windows
2000/XP+.  Where not supported, the \fB\-transparentcolor\fR value remains
at \fB{}\fR.

.PP
On Mac OS X, the following attributes may be set.
.TP





\fB\-modified\fR
.
Specifies the modification state of the window (determines whether the
window close widget contains the modification indicator and whether the
proxy icon is draggable).
.TP
\fB\-notify\fR
.
Specifies process notification state (bouncing of the application dock icon).
.TP
\fB\-titlepath\fR
.
Specifies the path of the file referenced as the window proxy icon (which
can be dragged and dropped in lieu of the file's finder icon).
.TP
\fB\-transparent\fR
.
Makes the window content area transparent and turns off the window shadow. For
the transparency to be effective, the toplevel background needs to be set to a
color with some alpha, e.g.
.QW systemTransparent .
.PP
On X11, the following attributes may be set. These are not supported by all

window managers, and will have no effect under older WMs.
.\" See http://www.freedesktop.org/Standards/wm-spec
.TP
\fB\-type\fR
.VS 8.6
Requests that the window should be interpreted by the window manager as being
of the specified type(s). This may cause the window to be decorated in a
different way or otherwise managed differently, though exactly what happens is
entirely up to the window manager. A list of types may be used, in order of
preference. The following values are mapped to constants defined in the EWMH
specification (using others is possible, but not advised):
.RS
.TP
\fBdesktop\fR
.
indicates a desktop feature,
.TP
\fBdock\fR
.
indicates a dock/panel feature,
.TP
\fBtoolbar\fR
.
indicates a toolbar window that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,
.TP
\fBmenu\fR
.
indicates a torn-off menu that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,
.TP
\fButility\fR
.
indicates a utility window (e.g., palette or toolbox) that should be acting on
behalf of another window, as indicated with \fBwm transient\fR,
.TP
\fBsplash\fR
.
indicates a splash screen, displayed during application start up,
.TP
\fBdialog\fR
.
indicates a general dialog window, that should be acting on behalf of another
window, as indicated with \fBwm transient\fR,
.TP
\fBdropdown_menu\fR
.
indicates a menu summoned from a menu bar, which should usually also be set to
be override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBpopup_menu\fR
.
indicates a popup menu, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBtooltip\fR
.
indicates a tooltip window, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBnotification\fR
.
indicates a window that provides a background notification of some event,
which should usually also be set to be override-redirected (with \fBwm
overrideredirect\fR),
.TP
\fBcombo\fR
.
indicates the drop-down list of a combobox widget, which should usually also
be set to be override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBdnd\fR
.
indicates a window that represents something being dragged, which should
usually also be set to be override-redirected (with
\fBwm overrideredirect\fR),
.TP
\fBnormal\fR
.
indicates a window that has no special interpretation.
.RE
.VE 8.6
.TP
\fB\-zoomed\fR
.
Requests that the window should be maximized. This is the same as \fBwm state
zoomed\fR on Windows and Mac OS X.
.PP
On X11, changes to window attributes are performed asynchronously. Querying
the value of an attribute returns the current state, which will not be the
same as the value most recently set if the window manager has not yet

processed the request or if it does not support the attribute.
.RE
.TP
\fBwm client \fIwindow\fR ?\fIname\fR?
.
If \fIname\fR is specified, this command stores \fIname\fR (which
should be the name of
the host on which the application is executing) in \fIwindow\fR's
\fBWM_CLIENT_MACHINE\fR property for use by the window manager or
session manager.
The command returns an empty string in this case.
If \fIname\fR is not specified, the command returns the last name
set in a \fBwm client\fR command for \fIwindow\fR.
If \fIname\fR is specified as an empty string, the command deletes the
\fBWM_CLIENT_MACHINE\fR property from \fIwindow\fR.
.TP
\fBwm colormapwindows \fIwindow\fR ?\fIwindowList\fR?
.
This command is used to manipulate the \fBWM_COLORMAP_WINDOWS\fR
property, which provides information to the window managers about
windows that have private colormaps.
.RS
.PP
If \fIwindowList\fR is not specified, the command returns a list
whose elements are the names of the windows in the \fBWM_COLORMAP_WINDOWS\fR







<




















<










<
<
<
<
<
<
<

<





<




>
>
>
>
>
>
>
>
>

<



<



|





>



>
>
>
>
>

<





<



<




<

|



|
>
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|

|
|
|
>
|



<












<







23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59







60

61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106

107
108
109

110
111
112
113

114
115
116
117
118
119
120
121
122
123
















































































124

125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
the \fIoption\fR argument.  All of the forms expect at least one
additional argument, \fIwindow\fR, which must be the path name of a
top-level window.
.PP
The legal forms for the \fBwm\fR command are:
.TP
\fBwm aspect \fIwindow\fR ?\fIminNumer minDenom maxNumer maxDenom\fR?

If \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
are all specified, then they will be passed to the window manager
and the window manager should use them to enforce a range of
acceptable aspect ratios for \fIwindow\fR.  The aspect ratio of
\fIwindow\fR (width/length) will be constrained to lie
between \fIminNumer\fR/\fIminDenom\fR and \fImaxNumer\fR/\fImaxDenom\fR.
If \fIminNumer\fR etc. are all specified as empty strings, then
any existing aspect ratio restrictions are removed.
If \fIminNumer\fR etc. are specified, then the command returns an
empty string.  Otherwise, it returns
a Tcl list containing four elements, which are the current values
of \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
(if no aspect restrictions are in effect, then an empty string is
returned).
.TP
\fBwm attributes \fIwindow\fR
.TP
\fBwm attributes \fIwindow\fR ?\fBoption\fR?
.TP
\fBwm attributes \fIwindow\fR ?\fBoption value option value...\fR?

This subcommand returns or sets platform specific attributes associated
with a window. The first form returns a list of the platform specific
flags and their values. The second form returns the value for the
specific option. The third form sets one or more of the values. The
values are as follows:
.RS
.PP
All platforms support the following attributes (though X11 users
should see the notes below):
.TP







\fB\-fullscreen\fR

Places the window in a mode that takes up the entire screen, has no
borders, and covers the general use area (i.e. Start menu and taskbar on
Windows, dock and menubar on OSX, general window decorations on X11).
.TP
\fB\-topmost\fR

Specifies whether this is a topmost window (displays above all other windows).
.PP
On Windows, the following attributes may be set.
.TP
\fB\-alpha\fR
.VS 8.5
Specifies the alpha transparency level of the toplevel.
It accepts a value from \fB0.0\fR (fully transparent) to \fB1.0\fR
(opaque).  Values outside that range will be constrained.  This is
supported on Windows 2000/XP+.  Where not supported, the \fB\-alpha\fR
value remains at \fB1.0\fR.
.VE 8.5
.TP
\fB\-disabled\fR

Specifies whether the window is in a disabled state.
.TP
\fB\-toolwindow\fR

Specifies a toolwindow style window (as defined in the MSDN).
.TP
\fB\-transparentcolor\fR
.VS 8.5
Specifies the transparent color index of the toplevel.  It takes any color
value accepted by \fBTk_GetColor\fR.  If the empty string is specified
(default), no transparent color is used.  This is supported on Windows
2000/XP+.  Where not supported, the \fB\-transparentcolor\fR value remains
at \fB{}\fR.
.VE 8.5
.PP
On Mac OS X, the following attributes may be set.
.TP
\fB\-alpha\fR
Specifies the alpha transparency level of the window.
It accepts a value from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque),
values outside that range will be constrained.
.TP
\fB\-modified\fR

Specifies the modification state of the window (determines whether the
window close widget contains the modification indicator and whether the
proxy icon is draggable).
.TP
\fB\-notify\fR

Specifies process notification state (bouncing of the application dock icon).
.TP
\fB\-titlepath\fR

Specifies the path of the file referenced as the window proxy icon (which
can be dragged and dropped in lieu of the file's finder icon).
.TP
\fB\-transparent\fR

Makes the window content area transparent and turns off the window shadow. For
the transparency to be effecive, the toplevel background needs to be set to a
color with some alpha, e.g.
.QW systemTransparent .
.PP
On X11, the following attributes may be set.
These are not supported by all window managers,
and will have no effect under older WMs.
.\" See http://www.freedesktop.org/Standards/wm-spec
.TP
















































































\fB\-zoomed\fR

Requests that the window should be maximized.
This is the same as \fBwm state zoomed\fR on Windows and Mac OS X.
.PP
On X11, changes to window attributes are performed asynchronously.
Querying the value of an attribute returns the current state,
which will not be the same as the value most recently set
if the window manager has not yet processed the request
or if it does not support the attribute.
.RE
.TP
\fBwm client \fIwindow\fR ?\fIname\fR?

If \fIname\fR is specified, this command stores \fIname\fR (which
should be the name of
the host on which the application is executing) in \fIwindow\fR's
\fBWM_CLIENT_MACHINE\fR property for use by the window manager or
session manager.
The command returns an empty string in this case.
If \fIname\fR is not specified, the command returns the last name
set in a \fBwm client\fR command for \fIwindow\fR.
If \fIname\fR is specified as an empty string, the command deletes the
\fBWM_CLIENT_MACHINE\fR property from \fIwindow\fR.
.TP
\fBwm colormapwindows \fIwindow\fR ?\fIwindowList\fR?

This command is used to manipulate the \fBWM_COLORMAP_WINDOWS\fR
property, which provides information to the window managers about
windows that have private colormaps.
.RS
.PP
If \fIwindowList\fR is not specified, the command returns a list
whose elements are the names of the windows in the \fBWM_COLORMAP_WINDOWS\fR
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
whose colormaps differ from their parents, followed by the top-level
itself;  the order of the internal windows is undefined.
See the ICCCM documentation for more information on the
\fBWM_COLORMAP_WINDOWS\fR property.
.RE
.TP
\fBwm command \fIwindow\fR ?\fIvalue\fR?
.
If \fIvalue\fR is specified, this command stores \fIvalue\fR in \fIwindow\fR's
\fBWM_COMMAND\fR property for use by the window manager or
session manager and returns an empty string.
\fIValue\fR must have proper list structure;  the elements should
contain the words of the command used to invoke the application.
If \fIvalue\fR is not specified then the command returns the last value
set in a \fBwm command\fR command for \fIwindow\fR.
If \fIvalue\fR is specified as an empty string, the command
deletes the \fBWM_COMMAND\fR property from \fIwindow\fR.
.TP
\fBwm deiconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be displayed in normal (non-iconified) form.
This is done by mapping the window.  If the window has never been
mapped then this command will not map the window, but it will ensure
that when the window is first mapped it will be displayed
in de-iconified form.  On Windows, a deiconified window will also be
raised and be given the focus (made the active window).
Returns an empty string.
.TP
\fBwm focusmodel \fIwindow\fR ?\fBactive\fR|\fBpassive\fR?
.
If \fBactive\fR or \fBpassive\fR is supplied as an optional argument
to the command, then it specifies the focus model for \fIwindow\fR.
In this case the command returns an empty string.  If no additional
argument is supplied, then the command returns the current focus
model for \fIwindow\fR.
.RS
.PP
An \fBactive\fR focus model means that \fIwindow\fR will claim the
input focus for itself or its descendants, even at times when
the focus is currently in some other application.  \fBPassive\fR means that
\fIwindow\fR will never claim the focus for itself:  the window manager
should give the focus to \fIwindow\fR at appropriate times.  However,
once the focus has been given to \fIwindow\fR or one of its descendants,
the application may re-assign the focus among \fIwindow\fR's descendants.
The focus model defaults to \fBpassive\fR, and Tk's \fBfocus\fR command
assumes a passive model of focusing.
.RE
.TP
\fBwm forget \fIwindow\fR
.
The \fIwindow\fR will be unmapped from the screen and will no longer
be managed by \fBwm\fR.  Windows created with the \fBtoplevel\fR
command will be treated like \fBframe\fR windows once they are no
longer managed by \fBwm\fR, however, the \fB\-menu\fR configuration will be
remembered and the menus will return once the widget is managed again.
.TP
\fBwm frame \fIwindow\fR
.
If \fIwindow\fR has been reparented by the window manager into a
decorative frame, the command returns the platform specific window
identifier for the outermost frame that contains \fIwindow\fR (the
window whose parent is the root or virtual root).  If \fIwindow\fR
has not been reparented by the window manager then the command returns
the platform specific window identifier for \fIwindow\fR.
.TP
\fBwm geometry \fIwindow\fR ?\fInewGeometry\fR?
.
If \fInewGeometry\fR is specified, then the geometry of \fIwindow\fR
is changed and an empty string is returned.  Otherwise the current
geometry for \fIwindow\fR is returned (this is the most recent
geometry specified either by manual resizing or
in a \fBwm geometry\fR command).  \fINewGeometry\fR has
the form \fB=\fIwidth\fBx\fIheight\fB\(+-\fIx\fB\(+-\fIy\fR, where
any of \fB=\fR, \fIwidth\fBx\fIheight\fR, or \fB\(+-\fIx\fB\(+-\fIy\fR







<











<









<



















<







<








<







171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223

224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
whose colormaps differ from their parents, followed by the top-level
itself;  the order of the internal windows is undefined.
See the ICCCM documentation for more information on the
\fBWM_COLORMAP_WINDOWS\fR property.
.RE
.TP
\fBwm command \fIwindow\fR ?\fIvalue\fR?

If \fIvalue\fR is specified, this command stores \fIvalue\fR in \fIwindow\fR's
\fBWM_COMMAND\fR property for use by the window manager or
session manager and returns an empty string.
\fIValue\fR must have proper list structure;  the elements should
contain the words of the command used to invoke the application.
If \fIvalue\fR is not specified then the command returns the last value
set in a \fBwm command\fR command for \fIwindow\fR.
If \fIvalue\fR is specified as an empty string, the command
deletes the \fBWM_COMMAND\fR property from \fIwindow\fR.
.TP
\fBwm deiconify \fIwindow\fR

Arrange for \fIwindow\fR to be displayed in normal (non-iconified) form.
This is done by mapping the window.  If the window has never been
mapped then this command will not map the window, but it will ensure
that when the window is first mapped it will be displayed
in de-iconified form.  On Windows, a deiconified window will also be
raised and be given the focus (made the active window).
Returns an empty string.
.TP
\fBwm focusmodel \fIwindow\fR ?\fBactive\fR|\fBpassive\fR?

If \fBactive\fR or \fBpassive\fR is supplied as an optional argument
to the command, then it specifies the focus model for \fIwindow\fR.
In this case the command returns an empty string.  If no additional
argument is supplied, then the command returns the current focus
model for \fIwindow\fR.
.RS
.PP
An \fBactive\fR focus model means that \fIwindow\fR will claim the
input focus for itself or its descendants, even at times when
the focus is currently in some other application.  \fBPassive\fR means that
\fIwindow\fR will never claim the focus for itself:  the window manager
should give the focus to \fIwindow\fR at appropriate times.  However,
once the focus has been given to \fIwindow\fR or one of its descendants,
the application may re-assign the focus among \fIwindow\fR's descendants.
The focus model defaults to \fBpassive\fR, and Tk's \fBfocus\fR command
assumes a passive model of focusing.
.RE
.TP
\fBwm forget \fIwindow\fR

The \fIwindow\fR will be unmapped from the screen and will no longer
be managed by \fBwm\fR.  Windows created with the \fBtoplevel\fR
command will be treated like \fBframe\fR windows once they are no
longer managed by \fBwm\fR, however, the \fB\-menu\fR configuration will be
remembered and the menus will return once the widget is managed again.
.TP
\fBwm frame \fIwindow\fR

If \fIwindow\fR has been reparented by the window manager into a
decorative frame, the command returns the platform specific window
identifier for the outermost frame that contains \fIwindow\fR (the
window whose parent is the root or virtual root).  If \fIwindow\fR
has not been reparented by the window manager then the command returns
the platform specific window identifier for \fIwindow\fR.
.TP
\fBwm geometry \fIwindow\fR ?\fInewGeometry\fR?

If \fInewGeometry\fR is specified, then the geometry of \fIwindow\fR
is changed and an empty string is returned.  Otherwise the current
geometry for \fIwindow\fR is returned (this is the most recent
geometry specified either by manual resizing or
in a \fBwm geometry\fR command).  \fINewGeometry\fR has
the form \fB=\fIwidth\fBx\fIheight\fB\(+-\fIx\fB\(+-\fIy\fR, where
any of \fB=\fR, \fIwidth\fBx\fIheight\fR, or \fB\(+-\fIx\fB\(+-\fIy\fR
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
size and location of the window. This can vary significantly, for example to
reflect the addition of decorative elements to \fIwindow\fR such as title
bars, and window managers are not required to precisely follow the requests
made through this command.
.RE
.TP
\fBwm grid \fIwindow\fR ?\fIbaseWidth baseHeight widthInc heightInc\fR?
.
This command indicates that \fIwindow\fR is to be managed as a
gridded window.
It also specifies the relationship between grid units and pixel units.
\fIBaseWidth\fR and \fIbaseHeight\fR specify the number of grid
units corresponding to the pixel dimensions requested internally
by \fIwindow\fR using \fBTk_GeometryRequest\fR.  \fIWidthInc\fR
and \fIheightInc\fR specify the number of pixels in each horizontal







<







268
269
270
271
272
273
274

275
276
277
278
279
280
281
size and location of the window. This can vary significantly, for example to
reflect the addition of decorative elements to \fIwindow\fR such as title
bars, and window managers are not required to precisely follow the requests
made through this command.
.RE
.TP
\fBwm grid \fIwindow\fR ?\fIbaseWidth baseHeight widthInc heightInc\fR?

This command indicates that \fIwindow\fR is to be managed as a
gridded window.
It also specifies the relationship between grid units and pixel units.
\fIBaseWidth\fR and \fIbaseHeight\fR specify the number of grid
units corresponding to the pixel dimensions requested internally
by \fIwindow\fR using \fBTk_GeometryRequest\fR.  \fIWidthInc\fR
and \fIheightInc\fR specify the number of pixels in each horizontal
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
.PP
Note: this command should not be needed very often, since the
\fBTk_SetGrid\fR library procedure and the \fBsetGrid\fR option
provide easier access to the same functionality.
.RE
.TP
\fBwm group \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it gives the path name for the leader of
a group of related windows.  The window manager may use this information,
for example, to unmap all of the windows in a group when the group's
leader is iconified.  \fIPathName\fR may be specified as an empty string to
remove \fIwindow\fR from any group association.  If \fIpathName\fR is
specified then the command returns an empty string;  otherwise it
returns the path name of \fIwindow\fR's current group leader, or an empty
string if \fIwindow\fR is not part of any group.
.TP
\fBwm iconbitmap \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be displayed in
\fIwindow\fR's icon, and the command returns an empty string.  If
an empty string is specified for \fIbitmap\fR, then any current icon
bitmap is cancelled for \fIwindow\fR.
If \fIbitmap\fR is specified then the command returns an empty string.
Otherwise it returns the name of
the current icon bitmap associated with \fIwindow\fR, or an empty
string if \fIwindow\fR has no icon bitmap.  On the Windows operating
system, an additional flag is supported:
.RS
.TP
\fBwm iconbitmap \fIwindow\fR ?\fB\-default\fR? ?\fIimage\fR?
.
If the \fB\-default\fR
flag is given, the icon is applied to all toplevel windows (existing
and future) to which no other specific icon has yet been applied.
In addition to bitmap image types, a full path specification to
any file which contains a valid
Windows icon is also accepted (usually .ico or .icr files), or any
file for which the shell has assigned an icon.  Tcl will
first test if the file contains an icon, then if it has an assigned
icon, and finally, if that fails, test for
a bitmap.
.RE
.TP
\fBwm iconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be iconified.  It \fIwindow\fR has not
yet been mapped for the first time, this command will arrange for
it to appear in the iconified state when it is eventually mapped.
.TP
\fBwm iconmask \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be used as a mask
in conjunction with the \fBiconbitmap\fR option:  where the mask
has zeroes no icon will be displayed;  where it has ones, the bits
from the icon bitmap will be displayed.  If
an empty string is specified for \fIbitmap\fR then any current icon
mask is cancelled for \fIwindow\fR (this is equivalent to specifying
a bitmap of all ones).  If \fIbitmap\fR is specified
then the command returns an empty string.  Otherwise it
returns the name of the current icon mask associated with
\fIwindow\fR, or an empty string if no mask is in effect.
.TP
\fBwm iconname \fIwindow\fR ?\fInewName\fR?
.
If \fInewName\fR is specified, then it is passed to the window
manager;  the window manager should display \fInewName\fR inside
the icon associated with \fIwindow\fR.  In this case an empty
string is returned as result.  If \fInewName\fR is not specified
then the command returns the current icon name for \fIwindow\fR,
or an empty string if no icon name has been specified (in this
case the window manager will normally display the window's title,
as specified with the \fBwm title\fR command).

.TP
\fBwm iconphoto \fIwindow\fR ?\fB\-default\fR? \fIimage1\fR ?\fIimage2 ...\fR?
.
Sets the titlebar icon for \fIwindow\fR based on the named photo images.
If \fB\-default\fR is specified, this is applied to all future created
toplevels as well.  The data in the images is taken as a snapshot at the
time of invocation.  If the images are later changed, this is not
reflected to the titlebar icons.  Multiple images are accepted to allow
different images sizes (e.g., 16x16 and 32x32) to be provided. The window
manager may scale provided icons to an appropriate size.
.RS
.PP
On Windows, the images are packed into a Windows icon structure.
This will override an ico specified to \fBwm iconbitmap\fR, and
vice versa.
.PP
On X, the images are arranged into the _NET_WM_ICON X property, which
most modern window managers support.  A \fBwm iconbitmap\fR may exist
simultaneously.  It is recommended to use not more than 2 icons, placing
the larger icon first.
.PP
On Macintosh, the first image called is loaded into an OSX-native icon
format, and becomes the application icon in dialogs, the Dock, and
other contexts. At the
script level the command will accept only the first image passed in the
parameters as support for multiple sizes/resolutions on macOS is outside Tk's
scope. Developers should use the largest icon they can support
(preferably 512 pixels) to ensure smooth rendering on the Mac.
.RE
.TP
\fBwm iconposition \fIwindow\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are specified, they are passed to the window
manager as a hint about where to position the icon for \fIwindow\fR.
In this case an empty string is returned.  If \fIx\fR and \fIy\fR are
specified as empty strings then any existing icon position hint is cancelled.
If neither \fIx\fR nor \fIy\fR is specified, then the command returns
a Tcl list containing two values, which are the current icon position
hints (if no hints are in effect then an empty string is returned).
.TP
\fBwm iconwindow \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it is the path name for a window to
use as icon for \fIwindow\fR: when \fIwindow\fR is iconified then
\fIpathName\fR will be mapped to serve as icon, and when \fIwindow\fR
is de-iconified then \fIpathName\fR will be unmapped again.  If
\fIpathName\fR is specified as an empty string then any existing
icon window association for \fIwindow\fR will be cancelled.  If
the \fIpathName\fR argument is specified then an empty string is
returned.  Otherwise the command returns the path name of the
current icon window for \fIwindow\fR, or an empty string if there
is no icon window currently specified for \fIwindow\fR.
Button press events are disabled for \fIwindow\fR as long as it is
an icon window;  this is needed in order to allow window managers to
.QW own
those events.
Note: not all window managers support the notion of an icon window.
.TP
\fBwm manage \fIwidget\fR
.
The \fIwidget\fR specified will become a stand alone top-level window.  The
window will be decorated with the window managers title bar, etc. Only
\fIframe\fR, \fIlabelframe\fR and \fItoplevel\fR widgets can be used
with this command. Attempting to pass any other widget type will raise
an error. Attempting to manage a \fItoplevel\fR widget is benign and
achieves nothing. See also \fBGEOMETRY MANAGEMENT\fR.
.TP
\fBwm maxsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give
the maximum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
less than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
maximum width and height currently in effect.
The maximum size defaults to the size of the screen.
See the sections on geometry management below for more information.
.TP
\fBwm minsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give the
minimum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
greater than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
minimum width and height currently in effect.
The minimum size defaults to one pixel in each dimension.
See the sections on geometry management below for more information.
.TP
\fBwm overrideredirect \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR is specified, it must have a proper boolean form and
the override-redirect flag for \fIwindow\fR is set to that value.
If \fIboolean\fR is not specified then \fB1\fR or \fB0\fR is
returned to indicate whether or not the override-redirect flag
is currently set for \fIwindow\fR.
Setting the override-redirect flag for a window causes
it to be ignored by the window manager;  among other things, this means
that the window will not be reparented from the root window into a
decorative frame and the user will not be able to manipulate the
window using the normal window manager mechanisms.
.RS
.PP
Note that the override-redirect flag is only guaranteed to be taken notice of
when the window is first mapped or when mapped after the state is changed from
withdrawn to normal. Some, but not all, platforms will take notice at
additional times.
.RE
.TP
\fBwm positionfrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current position was requested by the
program or by the user.  Many window managers ignore program-requested
initial positions and ask the user to manually position the window;  if
\fBuser\fR is specified then the window manager should position the
window at the given place without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current position
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBprogram\fR to indicate the
source of the window's current position, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
Tk will automatically set the position source to \fBuser\fR
when a \fBwm geometry\fR command is invoked, unless the source has
been set explicitly to \fBprogram\fR.
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
This command is used to manage window manager protocols such as
\fBWM_DELETE_WINDOW\fR.
\fIName\fR is the name of an atom corresponding to a window manager
protocol, such as \fBWM_DELETE_WINDOW\fR or \fBWM_SAVE_YOURSELF\fR
or \fBWM_TAKE_FOCUS\fR.
If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR
is associated with the protocol specified by \fIname\fR.







<










<










|



<













<





<














<








>


<


















|
|
<
<
<
<
<



<









<

















<








<














<














<










<
<
<
<
<
<
<


<




















<







303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396





397
398
399

400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471







472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
.PP
Note: this command should not be needed very often, since the
\fBTk_SetGrid\fR library procedure and the \fBsetGrid\fR option
provide easier access to the same functionality.
.RE
.TP
\fBwm group \fIwindow\fR ?\fIpathName\fR?

If \fIpathName\fR is specified, it gives the path name for the leader of
a group of related windows.  The window manager may use this information,
for example, to unmap all of the windows in a group when the group's
leader is iconified.  \fIPathName\fR may be specified as an empty string to
remove \fIwindow\fR from any group association.  If \fIpathName\fR is
specified then the command returns an empty string;  otherwise it
returns the path name of \fIwindow\fR's current group leader, or an empty
string if \fIwindow\fR is not part of any group.
.TP
\fBwm iconbitmap \fIwindow\fR ?\fIbitmap\fR?

If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be displayed in
\fIwindow\fR's icon, and the command returns an empty string.  If
an empty string is specified for \fIbitmap\fR, then any current icon
bitmap is cancelled for \fIwindow\fR.
If \fIbitmap\fR is specified then the command returns an empty string.
Otherwise it returns the name of
the current icon bitmap associated with \fIwindow\fR, or an empty
string if \fIwindow\fR has no icon bitmap.  On the Windows operating
system, an additional flag is supported: 
.RS
.TP
\fBwm iconbitmap \fIwindow\fR ?\fB\-default\fR? ?\fIimage\fR?

If the \fB\-default\fR
flag is given, the icon is applied to all toplevel windows (existing
and future) to which no other specific icon has yet been applied.
In addition to bitmap image types, a full path specification to
any file which contains a valid
Windows icon is also accepted (usually .ico or .icr files), or any
file for which the shell has assigned an icon.  Tcl will
first test if the file contains an icon, then if it has an assigned
icon, and finally, if that fails, test for
a bitmap.
.RE
.TP
\fBwm iconify \fIwindow\fR

Arrange for \fIwindow\fR to be iconified.  It \fIwindow\fR has not
yet been mapped for the first time, this command will arrange for
it to appear in the iconified state when it is eventually mapped.
.TP
\fBwm iconmask \fIwindow\fR ?\fIbitmap\fR?

If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be used as a mask
in conjunction with the \fBiconbitmap\fR option:  where the mask
has zeroes no icon will be displayed;  where it has ones, the bits
from the icon bitmap will be displayed.  If
an empty string is specified for \fIbitmap\fR then any current icon
mask is cancelled for \fIwindow\fR (this is equivalent to specifying
a bitmap of all ones).  If \fIbitmap\fR is specified
then the command returns an empty string.  Otherwise it
returns the name of the current icon mask associated with
\fIwindow\fR, or an empty string if no mask is in effect.
.TP
\fBwm iconname \fIwindow\fR ?\fInewName\fR?

If \fInewName\fR is specified, then it is passed to the window
manager;  the window manager should display \fInewName\fR inside
the icon associated with \fIwindow\fR.  In this case an empty
string is returned as result.  If \fInewName\fR is not specified
then the command returns the current icon name for \fIwindow\fR,
or an empty string if no icon name has been specified (in this
case the window manager will normally display the window's title,
as specified with the \fBwm title\fR command).
.VS 8.5
.TP
\fBwm iconphoto \fIwindow\fR ?\fB\-default\fR? \fIimage1\fR ?\fIimage2 ...\fR?

Sets the titlebar icon for \fIwindow\fR based on the named photo images.
If \fB\-default\fR is specified, this is applied to all future created
toplevels as well.  The data in the images is taken as a snapshot at the
time of invocation.  If the images are later changed, this is not
reflected to the titlebar icons.  Multiple images are accepted to allow
different images sizes (e.g., 16x16 and 32x32) to be provided. The window
manager may scale provided icons to an appropriate size.
.RS
.PP
On Windows, the images are packed into a Windows icon structure.
This will override an ico specified to \fBwm iconbitmap\fR, and
vice versa.
.PP
On X, the images are arranged into the _NET_WM_ICON X property, which
most modern window managers support.  A \fBwm iconbitmap\fR may exist
simultaneously.  It is recommended to use not more than 2 icons, placing
the larger icon first.
.PP
On Macintosh, this currently does nothing.
.VE 8.5





.RE
.TP
\fBwm iconposition \fIwindow\fR ?\fIx y\fR?

If \fIx\fR and \fIy\fR are specified, they are passed to the window
manager as a hint about where to position the icon for \fIwindow\fR.
In this case an empty string is returned.  If \fIx\fR and \fIy\fR are
specified as empty strings then any existing icon position hint is cancelled.
If neither \fIx\fR nor \fIy\fR is specified, then the command returns
a Tcl list containing two values, which are the current icon position
hints (if no hints are in effect then an empty string is returned).
.TP
\fBwm iconwindow \fIwindow\fR ?\fIpathName\fR?

If \fIpathName\fR is specified, it is the path name for a window to
use as icon for \fIwindow\fR: when \fIwindow\fR is iconified then
\fIpathName\fR will be mapped to serve as icon, and when \fIwindow\fR
is de-iconified then \fIpathName\fR will be unmapped again.  If
\fIpathName\fR is specified as an empty string then any existing
icon window association for \fIwindow\fR will be cancelled.  If
the \fIpathName\fR argument is specified then an empty string is
returned.  Otherwise the command returns the path name of the
current icon window for \fIwindow\fR, or an empty string if there
is no icon window currently specified for \fIwindow\fR.
Button press events are disabled for \fIwindow\fR as long as it is
an icon window;  this is needed in order to allow window managers to
.QW own
those events.
Note: not all window managers support the notion of an icon window.
.TP
\fBwm manage \fIwidget\fR

The \fIwidget\fR specified will become a stand alone top-level window.  The
window will be decorated with the window managers title bar, etc. Only
\fIframe\fR, \fIlabelframe\fR and \fItoplevel\fR widgets can be used
with this command. Attempting to pass any other widget type will raise
an error. Attempting to manage a \fItoplevel\fR widget is benign and
achieves nothing. See also \fBGEOMETRY MANAGEMENT\fR.
.TP
\fBwm maxsize \fIwindow\fR ?\fIwidth height\fR?

If \fIwidth\fR and \fIheight\fR are specified, they give
the maximum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
less than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
maximum width and height currently in effect.
The maximum size defaults to the size of the screen.
See the sections on geometry management below for more information.
.TP
\fBwm minsize \fIwindow\fR ?\fIwidth height\fR?

If \fIwidth\fR and \fIheight\fR are specified, they give the
minimum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
greater than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
minimum width and height currently in effect.
The minimum size defaults to one pixel in each dimension.
See the sections on geometry management below for more information.
.TP
\fBwm overrideredirect \fIwindow\fR ?\fIboolean\fR?

If \fIboolean\fR is specified, it must have a proper boolean form and
the override-redirect flag for \fIwindow\fR is set to that value.
If \fIboolean\fR is not specified then \fB1\fR or \fB0\fR is
returned to indicate whether or not the override-redirect flag
is currently set for \fIwindow\fR.
Setting the override-redirect flag for a window causes
it to be ignored by the window manager;  among other things, this means
that the window will not be reparented from the root window into a
decorative frame and the user will not be able to manipulate the
window using the normal window manager mechanisms.







.TP
\fBwm positionfrom \fIwindow\fR ?\fIwho\fR?

If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current position was requested by the
program or by the user.  Many window managers ignore program-requested
initial positions and ask the user to manually position the window;  if
\fBuser\fR is specified then the window manager should position the
window at the given place without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current position
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBprogram\fR to indicate the
source of the window's current position, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
Tk will automatically set the position source to \fBuser\fR
when a \fBwm geometry\fR command is invoked, unless the source has
been set explicitly to \fBprogram\fR.
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?

This command is used to manage window manager protocols such as
\fBWM_DELETE_WINDOW\fR.
\fIName\fR is the name of an atom corresponding to a window manager
protocol, such as \fBWM_DELETE_WINDOW\fR or \fBWM_SAVE_YOURSELF\fR
or \fBWM_TAKE_FOCUS\fR.
If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR
is associated with the protocol specified by \fIname\fR.
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
you have not asked for one with \fBwm protocol\fR.
If a \fBWM_DELETE_WINDOW\fR message arrives when you have not defined
a handler, then Tk handles the message by destroying the window for
which it was received.
.RE
.TP
\fBwm resizable \fIwindow\fR ?\fIwidth height\fR?
.
This command controls whether or not the user may interactively
resize a top-level window.  If \fIwidth\fR and \fIheight\fR are
specified, they are boolean values that determine whether the
width and height of \fIwindow\fR may be modified by the user.
In this case the command returns an empty string.
If \fIwidth\fR and \fIheight\fR are omitted then the command
returns a list with two 0/1 elements that indicate whether the
width and height of \fIwindow\fR are currently resizable.
By default, windows are resizable in both dimensions.
If resizing is disabled, then the window's size will be the size
from the most recent interactive resize or \fBwm geometry\fR
command.  If there has been no such operation then
the window's natural size will be used.
.TP
\fBwm sizefrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current size was requested by the
program or by the user.  Some window managers ignore program-requested
sizes and ask the user to manually size the window;  if
\fBuser\fR is specified then the window manager should give the
window its specified size without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current size
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBwindow\fR to indicate the
source of the window's current size, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
.TP
\fBwm stackorder \fIwindow\fR ?\fBisabove\fR|\fBisbelow \fIwindow\fR?
.
The \fBstackorder\fR command returns a list of toplevel windows
in stacking order, from lowest to highest. When a single toplevel
window is passed, the returned list recursively includes all of the
window's children that are toplevels. Only those toplevels
that are currently mapped to the screen are returned.
The \fBstackorder\fR command can also be used to determine if one
toplevel is positioned above or below a second toplevel.
When two window arguments separated by either \fBisabove\fR or
\fBisbelow\fR are passed, a boolean result indicates whether
or not the first window is currently above or below the second
window in the stacking order.
.TP
\fBwm state \fIwindow\fR ?newstate?
.
If \fInewstate\fR is specified, the window will be set to the new state,
otherwise it returns the current state of \fIwindow\fR: either
\fBnormal\fR, \fBiconic\fR, \fBwithdrawn\fR, \fBicon\fR, or (Windows and Mac
OS X only) \fBzoomed\fR.
The difference between \fBiconic\fR and \fBicon\fR is that
\fBiconic\fR refers to a window that has been iconified (e.g., with the
\fBwm iconify\fR command) while \fBicon\fR refers to a window whose only
purpose is to serve as the icon for some other window (via the \fBwm
iconwindow\fR command).  The \fBicon\fR state cannot be set.
.TP
\fBwm title \fIwindow\fR ?\fIstring\fR?
.
If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.
.TP
\fBwm transient \fIwindow\fR ?\fIcontainer\fR?
.
If \fIcontainer\fR is specified, then the window manager is informed that
\fIwindow\fR is a transient window (e.g. pull-down menu) working on
behalf of \fIcontainer\fR (where \fIcontainer\fR is the path name for a

top-level window).  If \fIcontainer\fR is specified as an empty string
then \fIwindow\fR is marked as not being a transient window any more.
Otherwise the command returns the path name of \fIwindow\fR's current
container, or an empty string if \fIwindow\fR is not currently a
transient window.  A transient window will mirror state changes in the
container and inherit the state of the container when initially mapped. The
directed graph with an edge from each transient to its container must be
acyclic.  In particular, it is an error to attempt to make a window a
transient of itself.  The window manager may also decorate a transient
window differently, removing some features normally present (e.g.,
minimize and maximize buttons) though this is entirely at the
discretion of the window manager.
.TP
\fBwm withdraw \fIwindow\fR
.
Arranges for \fIwindow\fR to be withdrawn from the screen.  This
causes the window to be unmapped and forgotten about by the window
manager.  If the window
has never been mapped, then this command
causes the window to be mapped in the withdrawn state.  Not all
window managers appear to know how to handle windows that are
mapped in the withdrawn state.







<















<

















<













<











<







|
<
|
|
|
>
|
|
|
|
|
|
<
|
<
<
<
<


<







520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590

591
592
593
594
595
596
597
598
599
600

601




602
603

604
605
606
607
608
609
610
you have not asked for one with \fBwm protocol\fR.
If a \fBWM_DELETE_WINDOW\fR message arrives when you have not defined
a handler, then Tk handles the message by destroying the window for
which it was received.
.RE
.TP
\fBwm resizable \fIwindow\fR ?\fIwidth height\fR?

This command controls whether or not the user may interactively
resize a top-level window.  If \fIwidth\fR and \fIheight\fR are
specified, they are boolean values that determine whether the
width and height of \fIwindow\fR may be modified by the user.
In this case the command returns an empty string.
If \fIwidth\fR and \fIheight\fR are omitted then the command
returns a list with two 0/1 elements that indicate whether the
width and height of \fIwindow\fR are currently resizable.
By default, windows are resizable in both dimensions.
If resizing is disabled, then the window's size will be the size
from the most recent interactive resize or \fBwm geometry\fR
command.  If there has been no such operation then
the window's natural size will be used.
.TP
\fBwm sizefrom \fIwindow\fR ?\fIwho\fR?

If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current size was requested by the
program or by the user.  Some window managers ignore program-requested
sizes and ask the user to manually size the window;  if
\fBuser\fR is specified then the window manager should give the
window its specified size without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current size
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBwindow\fR to indicate the
source of the window's current size, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
.TP
\fBwm stackorder \fIwindow\fR ?\fBisabove\fR|\fBisbelow \fIwindow\fR?

The \fBstackorder\fR command returns a list of toplevel windows
in stacking order, from lowest to highest. When a single toplevel
window is passed, the returned list recursively includes all of the
window's children that are toplevels. Only those toplevels
that are currently mapped to the screen are returned.
The \fBstackorder\fR command can also be used to determine if one
toplevel is positioned above or below a second toplevel.
When two window arguments separated by either \fBisabove\fR or
\fBisbelow\fR are passed, a boolean result indicates whether
or not the first window is currently above or below the second
window in the stacking order.
.TP
\fBwm state \fIwindow\fR ?newstate?

If \fInewstate\fR is specified, the window will be set to the new state,
otherwise it returns the current state of \fIwindow\fR: either
\fBnormal\fR, \fBiconic\fR, \fBwithdrawn\fR, \fBicon\fR, or (Windows and Mac
OS X only) \fBzoomed\fR.
The difference between \fBiconic\fR and \fBicon\fR is that
\fBiconic\fR refers to a window that has been iconified (e.g., with the
\fBwm iconify\fR command) while \fBicon\fR refers to a window whose only
purpose is to serve as the icon for some other window (via the \fBwm
iconwindow\fR command).  The \fBicon\fR state cannot be set.
.TP
\fBwm title \fIwindow\fR ?\fIstring\fR?

If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.
.TP
\fBwm transient \fIwindow\fR ?\fImaster\fR?

If \fImaster\fR is specified, then the window manager is informed
that \fIwindow\fR is a transient window (e.g. pull-down menu) working
on behalf of \fImaster\fR (where \fImaster\fR is the
path name for a top-level window).  If \fImaster\fR
is specified as an empty string then \fIwindow\fR is marked as not
being a transient window any more.  Otherwise the command
returns the path name of \fIwindow\fR's current master, or an
empty string if \fIwindow\fR is not currently a transient window.
A transient window will mirror state changes in the master and
inherit the state of the master when initially mapped. It is an

error to attempt to make a window a transient of itself.




.TP
\fBwm withdraw \fIwindow\fR

Arranges for \fIwindow\fR to be withdrawn from the screen.  This
causes the window to be unmapped and forgotten about by the window
manager.  If the window
has never been mapped, then this command
causes the window to be mapped in the withdrawn state.  Not all
window managers appear to know how to handle windows that are
mapped in the withdrawn state.
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
Tk (and the window manager) assume that there is a grid of some
sort within the application and that the application should be
resized in terms of \fIgrid units\fR rather than pixels.
Gridded geometry management is typically invoked by turning on
the \fBsetGrid\fR option for a widget;  it can also be invoked
with the \fBwm grid\fR command or by calling \fBTk_SetGrid\fR.
In each of these approaches the particular widget (or sometimes
code in the application as a whole) specifies the relationship between
integral grid sizes for the window and pixel sizes.
To return to non-gridded geometry management, invoke
\fBwm grid\fR with empty argument strings.
.PP
When gridded geometry management is enabled then all the dimensions specified
in \fBwm minsize\fR, \fBwm maxsize\fR, and \fBwm geometry\fR commands
are treated as grid units rather than pixel units.
Interactive resizing is also carried out in even numbers of grid units
rather than pixels.
.SH BUGS
.PP
Most existing window managers appear to have bugs that affect the
operation of the \fBwm\fR command.  For example, some changes will not
take effect if the window is already active:  the window will have
to be withdrawn and de-iconified in order to make the change happen.
.SH EXAMPLES
.PP
A fixed-size window that says that it is fixed-size too:
.CS
toplevel .fixed
\fBwm title\fR     .fixed "Fixed-size Window"
\fBwm resizable\fR .fixed 0 0
.CE
.PP







|
















<







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
Tk (and the window manager) assume that there is a grid of some
sort within the application and that the application should be
resized in terms of \fIgrid units\fR rather than pixels.
Gridded geometry management is typically invoked by turning on
the \fBsetGrid\fR option for a widget;  it can also be invoked
with the \fBwm grid\fR command or by calling \fBTk_SetGrid\fR.
In each of these approaches the particular widget (or sometimes
code in the application as a whole) specifies the relationship between 
integral grid sizes for the window and pixel sizes.
To return to non-gridded geometry management, invoke
\fBwm grid\fR with empty argument strings.
.PP
When gridded geometry management is enabled then all the dimensions specified
in \fBwm minsize\fR, \fBwm maxsize\fR, and \fBwm geometry\fR commands
are treated as grid units rather than pixel units.
Interactive resizing is also carried out in even numbers of grid units
rather than pixels.
.SH BUGS
.PP
Most existing window managers appear to have bugs that affect the
operation of the \fBwm\fR command.  For example, some changes will not
take effect if the window is already active:  the window will have
to be withdrawn and de-iconified in order to make the change happen.
.SH EXAMPLES

A fixed-size window that says that it is fixed-size too:
.CS
toplevel .fixed
\fBwm title\fR     .fixed "Fixed-size Window"
\fBwm resizable\fR .fixed 0 0
.CE
.PP
851
852
853
854
855
856
857
858
859
860
\fBwm title\fR     .msg "Dialog demo"
\fBwm deiconify\fR .msg
.CE
.SH "SEE ALSO"
toplevel(n), winfo(n)
.SH KEYWORDS
aspect ratio, deiconify, focus model, geometry, grid, group, icon, iconify, increments, position, size, title, top-level window, units, window manager
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
723
724
725
726
727
728
729



\fBwm title\fR     .msg "Dialog demo"
\fBwm deiconify\fR .msg
.CE
.SH "SEE ALSO"
toplevel(n), winfo(n)
.SH KEYWORDS
aspect ratio, deiconify, focus model, geometry, grid, group, icon, iconify, increments, position, size, title, top-level window, units, window manager



Changes to generic/default.h.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _DEFAULT
#define _DEFAULT


#ifdef _WIN32
#   include "tkWinDefault.h"
#else
#   if defined(MAC_OSX_TK)
#	include "tkMacOSXDefault.h"
#   else
#	include "tkUnixDefault.h"
#   endif







>
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _DEFAULT
#define _DEFAULT

#if defined(__WIN32__) || defined(_WIN32) || \
    defined(__MINGW32__)
#   include "tkWinDefault.h"
#else
#   if defined(MAC_OSX_TK)
#	include "tkMacOSXDefault.h"
#   else
#	include "tkUnixDefault.h"
#   endif

Changes to generic/ks_names.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * This file should be maintained in sync with xlib/X11/keysymdefs.h
 *
 * Note that this should be done manually only, because in some cases
 * keysymdefs.h defines the same integer for multiple keysyms, e.g.:
 *
 *    #define XK_Greek_LAMDA                         0x7CB
 *    #define XK_Greek_LAMBDA                        0x7CB
 *
 *    #define XK_Cyrillic_DZHE                       0x6BF
 *    #define XK_Serbian_DZE                         0x6BF  (deprecated)
 *
 */
{ "BackSpace", 0xFF08 },
{ "Tab", 0xFF09 },
{ "Linefeed", 0xFF0A },
{ "Clear", 0xFF0B },
{ "Return", 0xFF0D },
{ "Pause", 0xFF13 },
{ "Scroll_Lock", 0xFF14 },
{ "Sys_Req", 0xFF15 },
{ "Escape", 0xFF1B },
{ "Delete", 0xFFFF },
{ "Multi_key", 0xFF20 },
{ "Codeinput", 0xFF37 },
{ "SingleCandidate", 0xFF3C },
{ "MultipleCandidate", 0xFF3D },
{ "PreviousCandidate", 0xFF3E },
{ "Kanji", 0xFF21 },
{ "Muhenkan", 0xFF22 },
{ "Henkan_Mode", 0xFF23 },
{ "Henkan", 0xFF23 },
{ "Romaji", 0xFF24 },
{ "Hiragana", 0xFF25 },
{ "Katakana", 0xFF26 },
{ "Hiragana_Katakana", 0xFF27 },
{ "Zenkaku", 0xFF28 },
{ "Hankaku", 0xFF29 },
{ "Zenkaku_Hankaku", 0xFF2A },
{ "Touroku", 0xFF2B },
{ "Massyo", 0xFF2C },
{ "Kana_Lock", 0xFF2D },
{ "Kana_Shift", 0xFF2E },
{ "Eisu_Shift", 0xFF2F },
{ "Eisu_toggle", 0xFF30 },
{ "Kanji_Bangou", 0xFF37 },
{ "Zen_Koho", 0xFF3D },
{ "Mae_Koho", 0xFF3E },
{ "Home", 0xFF50 },
{ "Left", 0xFF51 },
{ "Up", 0xFF52 },
{ "Right", 0xFF53 },
{ "Down", 0xFF54 },
{ "Prior", 0xFF55 },
{ "Page_Up", 0xFF55 },
{ "Next", 0xFF56 },
{ "Page_Down", 0xFF56 },
{ "End", 0xFF57 },
{ "Begin", 0xFF58 },
{ "Win_L", 0xFF5B },
{ "Win_R", 0xFF5C },
{ "App", 0xFF5D },
{ "Select", 0xFF60 },
{ "Print", 0xFF61 },






|
|

|
|













<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<

<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24




25



















26
27
28
29
30
31

32

33
34
35
36
37
38
39
/*
 * This file should be maintained in sync with xlib/X11/keysymdefs.h
 *
 * Note that this should be done manually only, because in some cases
 * keysymdefs.h defines the same integer for multiple keysyms, e.g.:
 *
 *    #define XK_Greek_LAMDA                         0x7cb
 *    #define XK_Greek_LAMBDA                        0x7cb
 *
 *    #define XK_Cyrillic_DZHE                       0x6bf
 *    #define XK_Serbian_DZE                         0x6bf  (deprecated)
 *
 */
{ "BackSpace", 0xFF08 },
{ "Tab", 0xFF09 },
{ "Linefeed", 0xFF0A },
{ "Clear", 0xFF0B },
{ "Return", 0xFF0D },
{ "Pause", 0xFF13 },
{ "Scroll_Lock", 0xFF14 },
{ "Sys_Req", 0xFF15 },
{ "Escape", 0xFF1B },
{ "Delete", 0xFFFF },
{ "Multi_key", 0xFF20 },




{ "Kanji", 0xFF21 },



















{ "Home", 0xFF50 },
{ "Left", 0xFF51 },
{ "Up", 0xFF52 },
{ "Right", 0xFF53 },
{ "Down", 0xFF54 },
{ "Prior", 0xFF55 },

{ "Next", 0xFF56 },

{ "End", 0xFF57 },
{ "Begin", 0xFF58 },
{ "Win_L", 0xFF5B },
{ "Win_R", 0xFF5C },
{ "App", 0xFF5D },
{ "Select", 0xFF60 },
{ "Print", 0xFF61 },
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
{ "KP_Space", 0xFF80 },
{ "KP_Tab", 0xFF89 },
{ "KP_Enter", 0xFF8D },
{ "KP_F1", 0xFF91 },
{ "KP_F2", 0xFF92 },
{ "KP_F3", 0xFF93 },
{ "KP_F4", 0xFF94 },
{ "KP_Home", 0xFF95 },
{ "KP_Left", 0xFF96 },
{ "KP_Up", 0xFF97 },
{ "KP_Right", 0xFF98 },
{ "KP_Down", 0xFF99 },
{ "KP_Prior", 0xFF9A },
{ "KP_Page_Up", 0xFF9A },
{ "KP_Next", 0xFF9B },
{ "KP_Page_Down", 0xFF9B },
{ "KP_End", 0xFF9C },
{ "KP_Begin", 0xFF9D },
{ "KP_Insert", 0xFF9E },
{ "KP_Delete", 0xFF9F },
{ "KP_Equal", 0xFFBD },
{ "KP_Multiply", 0xFFAA },
{ "KP_Add", 0xFFAB },
{ "KP_Separator", 0xFFAC },
{ "KP_Subtract", 0xFFAD },
{ "KP_Decimal", 0xFFAE },
{ "KP_Divide", 0xFFAF },







<
<
<
<
<
<
<
<
<
<
<
<
<







52
53
54
55
56
57
58













59
60
61
62
63
64
65
{ "KP_Space", 0xFF80 },
{ "KP_Tab", 0xFF89 },
{ "KP_Enter", 0xFF8D },
{ "KP_F1", 0xFF91 },
{ "KP_F2", 0xFF92 },
{ "KP_F3", 0xFF93 },
{ "KP_F4", 0xFF94 },













{ "KP_Equal", 0xFFBD },
{ "KP_Multiply", 0xFFAA },
{ "KP_Add", 0xFFAB },
{ "KP_Separator", 0xFFAC },
{ "KP_Subtract", 0xFFAD },
{ "KP_Decimal", 0xFFAE },
{ "KP_Divide", 0xFFAF },
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927






928







929
930
931
932
933
934


935
936

937
938
939
940
941
942

943
944





945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },
{ "Super_R", 0xFFEC },
{ "Hyper_L", 0xFFED },
{ "Hyper_R", 0xFFEE },
{ "ISO_Lock", 0xFE01 },
{ "ISO_Level2_Latch", 0xFE02 },
{ "ISO_Level3_Shift", 0xFE03 },
{ "ISO_Level3_Latch", 0xFE04 },
{ "ISO_Level3_Lock", 0xFE05 },
{ "ISO_Level5_Shift", 0xFE11 },
{ "ISO_Level5_Latch", 0xFE12 },
{ "ISO_Level5_Lock", 0xFE13 },
{ "ISO_Group_Shift", 0xFF7E },
{ "ISO_Group_Latch", 0xFE06 },
{ "ISO_Group_Lock", 0xFE07 },
{ "ISO_Next_Group", 0xFE08 },
{ "ISO_Next_Group_Lock", 0xFE09 },
{ "ISO_Prev_Group", 0xFE0A },
{ "ISO_Prev_Group_Lock", 0xFE0B },
{ "ISO_First_Group", 0xFE0C },
{ "ISO_First_Group_Lock", 0xFE0D },
{ "ISO_Last_Group", 0xFE0E },
{ "ISO_Last_Group_Lock", 0xFE0F },
{ "ISO_Left_Tab", 0xFE20 },
{ "ISO_Move_Line_Up", 0xFE21 },
{ "ISO_Move_Line_Down", 0xFE22 },
{ "ISO_Partial_Line_Up", 0xFE23 },
{ "ISO_Partial_Line_Down", 0xFE24 },
{ "ISO_Partial_Space_Left", 0xFE25 },
{ "ISO_Partial_Space_Right", 0xFE26 },
{ "ISO_Set_Margin_Left", 0xFE27 },
{ "ISO_Set_Margin_Right", 0xFE28 },
{ "ISO_Release_Margin_Left", 0xFE29 },
{ "ISO_Release_Margin_Right", 0xFE2A },
{ "ISO_Release_Both_Margins", 0xFE2B },
{ "ISO_Fast_Cursor_Left", 0xFE2C },
{ "ISO_Fast_Cursor_Right", 0xFE2D },
{ "ISO_Fast_Cursor_Up", 0xFE2E },
{ "ISO_Fast_Cursor_Down", 0xFE2F },
{ "ISO_Continuous_Underline", 0xFE30 },
{ "ISO_Discontinuous_Underline", 0xFE31 },
{ "ISO_Emphasize", 0xFE32 },
{ "ISO_Center_Object", 0xFE33 },
{ "ISO_Enter", 0xFE34 },
{ "dead_grave", 0xFE50 },
{ "dead_acute", 0xFE51 },
{ "dead_circumflex", 0xFE52 },
{ "dead_tilde", 0xFE53 },
{ "dead_perispomeni", 0xFE53 },
{ "dead_macron", 0xFE54 },
{ "dead_breve", 0xFE55 },
{ "dead_abovedot", 0xFE56 },
{ "dead_diaeresis", 0xFE57 },
{ "dead_abovering", 0xFE58 },
{ "dead_doubleacute", 0xFE59 },
{ "dead_caron", 0xFE5A },
{ "dead_cedilla", 0xFE5B },
{ "dead_ogonek", 0xFE5C },
{ "dead_iota", 0xFE5D },
{ "dead_voiced_sound", 0xFE5E },
{ "dead_semivoiced_sound", 0xFE5F },
{ "dead_belowdot", 0xFE60 },
{ "dead_hook", 0xFE61 },
{ "dead_horn", 0xFE62 },
{ "dead_stroke", 0xFE63 },
{ "dead_abovecomma", 0xFE64 },
{ "dead_psili", 0xFE64 },
{ "dead_abovereversedcomma", 0xFE65 },
{ "dead_dasia", 0xFE65 },
{ "dead_doublegrave", 0xFE66 },
{ "dead_belowring", 0xFE67 },
{ "dead_belowmacron", 0xFE68 },
{ "dead_belowcircumflex", 0xFE69 },
{ "dead_belowtilde", 0xFE6A },
{ "dead_belowbreve", 0xFE6B },
{ "dead_belowdiaeresis", 0xFE6C },
{ "dead_invertedbreve", 0xFE6D },
{ "dead_belowcomma", 0xFE6E },
{ "dead_currency", 0xFE6F },
{ "dead_lowline", 0xFE90 },
{ "dead_aboveverticalline", 0xFE91 },
{ "dead_belowverticalline", 0xFE92 },
{ "dead_longsolidusoverlay", 0xFE93 },
{ "dead_a", 0xFE80 },
{ "dead_A", 0xFE81 },
{ "dead_e", 0xFE82 },
{ "dead_E", 0xFE83 },
{ "dead_i", 0xFE84 },
{ "dead_I", 0xFE85 },
{ "dead_o", 0xFE86 },
{ "dead_O", 0xFE87 },
{ "dead_u", 0xFE88 },
{ "dead_U", 0xFE89 },
{ "dead_small_schwa", 0xFE8A },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "First_Virtual_Screen", 0xFED0 },
{ "Prev_Virtual_Screen", 0xFED1 },
{ "Next_Virtual_Screen", 0xFED2 },
{ "Last_Virtual_Screen", 0xFED4 },
{ "Terminate_Server", 0xFED5 },
{ "AccessX_Enable", 0xFE70 },
{ "AccessX_Feedback_Enable", 0xFE71 },
{ "RepeatKeys_Enable", 0xFE72 },
{ "SlowKeys_Enable", 0xFE73 },
{ "BounceKeys_Enable", 0xFE74 },
{ "StickyKeys_Enable", 0xFE75 },
{ "MouseKeys_Enable", 0xFE76 },
{ "MouseKeys_Accel_Enable", 0xFE77 },
{ "Overlay1_Enable", 0xFE78 },
{ "Overlay2_Enable", 0xFE79 },
{ "AudibleBell_Enable", 0xFE7A },
{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },
{ "Pointer_DownRight", 0xFEE7 },
{ "Pointer_Button_Dflt", 0xFEE8 },
{ "Pointer_Button1", 0xFEE9 },
{ "Pointer_Button2", 0xFEEA },
{ "Pointer_Button3", 0xFEEB },
{ "Pointer_Button4", 0xFEEC },
{ "Pointer_Button5", 0xFEED },
{ "Pointer_DblClick_Dflt", 0xFEEE },
{ "Pointer_DblClick1", 0xFEEF },
{ "Pointer_DblClick2", 0xFEF0 },
{ "Pointer_DblClick3", 0xFEF1 },
{ "Pointer_DblClick4", 0xFEF2 },
{ "Pointer_DblClick5", 0xFEF3 },
{ "Pointer_Drag_Dflt", 0xFEF4 },
{ "Pointer_Drag1", 0xFEF5 },
{ "Pointer_Drag2", 0xFEF6 },
{ "Pointer_Drag3", 0xFEF7 },
{ "Pointer_Drag4", 0xFEF8 },
{ "Pointer_Drag5", 0xFEFD },
{ "Pointer_EnableKeys", 0xFEF9 },
{ "Pointer_Accelerate", 0xFEFA },
{ "Pointer_DfltBtnNext", 0xFEFB },
{ "Pointer_DfltBtnPrev", 0xFEFC },
{ "ch", 0xFEA0 },
{ "Ch", 0xFEA1 },
{ "CH", 0xFEA2 },
{ "c_h", 0xFEA3 },
{ "C_h", 0xFEA4 },
{ "C_H", 0xFEA5 },
{ "3270_Duplicate", 0xFD01 },
{ "3270_FieldMark", 0xFD02 },
{ "3270_Right2", 0xFD03 },
{ "3270_Left2", 0xFD04 },
{ "3270_BackTab", 0xFD05 },
{ "3270_EraseEOF", 0xFD06 },
{ "3270_EraseInput", 0xFD07 },
{ "3270_Reset", 0xFD08 },
{ "3270_Quit", 0xFD09 },
{ "3270_PA1", 0xFD0A },
{ "3270_PA2", 0xFD0B },
{ "3270_PA3", 0xFD0C },
{ "3270_Test", 0xFD0D },
{ "3270_Attn", 0xFD0E },
{ "3270_CursorBlink", 0xFD0F },
{ "3270_AltCursor", 0xFD10 },
{ "3270_KeyClick", 0xFD11 },
{ "3270_Jump", 0xFD12 },
{ "3270_Ident", 0xFD13 },
{ "3270_Rule", 0xFD14 },
{ "3270_Copy", 0xFD15 },
{ "3270_Play", 0xFD16 },
{ "3270_Setup", 0xFD17 },
{ "3270_Record", 0xFD18 },
{ "3270_ChangeScreen", 0xFD19 },
{ "3270_DeleteWord", 0xFD1A },
{ "3270_ExSelect", 0xFD1B },
{ "3270_CursorSelect", 0xFD1C },
{ "3270_PrintScreen", 0xFD1D },
{ "3270_Enter", 0xFD1E },
{ "space", 0x20 },
{ "exclam", 0x21 },
{ "quotedbl", 0x22 },
{ "numbersign", 0x23 },
{ "dollar", 0x24 },
{ "percent", 0x25 },
{ "ampersand", 0x26 },
{ "apostrophe", 0x27 },
{ "quoteright", 0x27 },
{ "parenleft", 0x28 },
{ "parenright", 0x29 },
{ "asterisk", 0x2A },
{ "plus", 0x2B },
{ "comma", 0x2C },
{ "minus", 0x2D },
{ "period", 0x2E },
{ "slash", 0x2F },
{ "0", 0x30 },
{ "1", 0x31 },
{ "2", 0x32 },
{ "3", 0x33 },
{ "4", 0x34 },
{ "5", 0x35 },
{ "6", 0x36 },
{ "7", 0x37 },
{ "8", 0x38 },
{ "9", 0x39 },
{ "colon", 0x3A },
{ "semicolon", 0x3B },
{ "less", 0x3C },
{ "equal", 0x3D },
{ "greater", 0x3E },
{ "question", 0x3F },
{ "at", 0x40 },
{ "A", 0x41 },
{ "B", 0x42 },
{ "C", 0x43 },
{ "D", 0x44 },
{ "E", 0x45 },
{ "F", 0x46 },
{ "G", 0x47 },
{ "H", 0x48 },
{ "I", 0x49 },
{ "J", 0x4A },
{ "K", 0x4B },
{ "L", 0x4C },
{ "M", 0x4D },
{ "N", 0x4E },
{ "O", 0x4F },
{ "P", 0x50 },
{ "Q", 0x51 },
{ "R", 0x52 },
{ "S", 0x53 },
{ "T", 0x54 },
{ "U", 0x55 },
{ "V", 0x56 },
{ "W", 0x57 },
{ "X", 0x58 },
{ "Y", 0x59 },
{ "Z", 0x5A },
{ "bracketleft", 0x5B },
{ "backslash", 0x5C },
{ "bracketright", 0x5D },
{ "asciicircum", 0x5E },
{ "underscore", 0x5F },
{ "grave", 0x60 },
{ "quoteleft", 0x60 },
{ "a", 0x61 },
{ "b", 0x62 },
{ "c", 0x63 },
{ "d", 0x64 },
{ "e", 0x65 },
{ "f", 0x66 },
{ "g", 0x67 },
{ "h", 0x68 },
{ "i", 0x69 },
{ "j", 0x6A },
{ "k", 0x6B },
{ "l", 0x6C },
{ "m", 0x6D },
{ "n", 0x6E },
{ "o", 0x6F },
{ "p", 0x70 },
{ "q", 0x71 },
{ "r", 0x72 },
{ "s", 0x73 },
{ "t", 0x74 },
{ "u", 0x75 },
{ "v", 0x76 },
{ "w", 0x77 },
{ "x", 0x78 },
{ "y", 0x79 },
{ "z", 0x7A },
{ "braceleft", 0x7B },
{ "bar", 0x7C },
{ "braceright", 0x7D },
{ "asciitilde", 0x7E },
{ "nobreakspace", 0xA0 },
{ "exclamdown", 0xA1 },
{ "cent", 0xA2 },
{ "sterling", 0xA3 },
{ "currency", 0xA4 },
{ "yen", 0xA5 },
{ "brokenbar", 0xA6 },
{ "section", 0xA7 },
{ "diaeresis", 0xA8 },
{ "copyright", 0xA9 },
{ "ordfeminine", 0xAA },
{ "guillemotleft", 0xAB },
{ "notsign", 0xAC },
{ "hyphen", 0xAD },
{ "registered", 0xAE },
{ "macron", 0xAF },
{ "degree", 0xB0 },
{ "plusminus", 0xB1 },
{ "twosuperior", 0xB2 },
{ "threesuperior", 0xB3 },
{ "acute", 0xB4 },
{ "mu", 0xB5 },
{ "paragraph", 0xB6 },
{ "periodcentered", 0xB7 },
{ "cedilla", 0xB8 },
{ "onesuperior", 0xB9 },
{ "masculine", 0xBA },
{ "guillemotright", 0xBB },
{ "onequarter", 0xBC },
{ "onehalf", 0xBD },
{ "threequarters", 0xBE },
{ "questiondown", 0xBF },
{ "Agrave", 0xC0 },
{ "Aacute", 0xC1 },
{ "Acircumflex", 0xC2 },
{ "Atilde", 0xC3 },
{ "Adiaeresis", 0xC4 },
{ "Aring", 0xC5 },
{ "AE", 0xC6 },
{ "Ccedilla", 0xC7 },
{ "Egrave", 0xC8 },
{ "Eacute", 0xC9 },
{ "Ecircumflex", 0xCA },
{ "Ediaeresis", 0xCB },
{ "Igrave", 0xCC },
{ "Iacute", 0xCD },
{ "Icircumflex", 0xCE },
{ "Idiaeresis", 0xCF },
{ "ETH", 0xD0 },
{ "Eth", 0xD0 },
{ "Ntilde", 0xD1 },
{ "Ograve", 0xD2 },
{ "Oacute", 0xD3 },
{ "Ocircumflex", 0xD4 },
{ "Otilde", 0xD5 },
{ "Odiaeresis", 0xD6 },
{ "multiply", 0xD7 },
{ "Oslash", 0xD8 },
#ifndef TK_NO_DEPRECATED
{ "Ooblique", 0xD8 },
#endif
{ "Ugrave", 0xD9 },
{ "Uacute", 0xDA },
{ "Ucircumflex", 0xDB },
{ "Udiaeresis", 0xDC },
{ "Yacute", 0xDD },
{ "THORN", 0xDE },
{ "Thorn", 0xDE },
{ "ssharp", 0xDF },

{ "agrave", 0xE0 },
{ "aacute", 0xE1 },
{ "acircumflex", 0xE2 },
{ "atilde", 0xE3 },
{ "adiaeresis", 0xE4 },
{ "aring", 0xE5 },
{ "ae", 0xE6 },
{ "ccedilla", 0xE7 },
{ "egrave", 0xE8 },
{ "eacute", 0xE9 },
{ "ecircumflex", 0xEA },
{ "ediaeresis", 0xEB },
{ "igrave", 0xEC },
{ "iacute", 0xED },
{ "icircumflex", 0xEE },
{ "idiaeresis", 0xEF },
{ "eth", 0xF0 },
{ "ntilde", 0xF1 },
{ "ograve", 0xF2 },
{ "oacute", 0xF3 },
{ "ocircumflex", 0xF4 },
{ "otilde", 0xF5 },
{ "odiaeresis", 0xF6 },
{ "division", 0xF7 },
{ "oslash", 0xF8 },
#ifndef TK_NO_DEPRECATED
{ "ooblique", 0xF8 },
#endif
{ "ugrave", 0xF9 },
{ "uacute", 0xFA },
{ "ucircumflex", 0xFB },
{ "udiaeresis", 0xFC },
{ "yacute", 0xFD },
{ "thorn", 0xFE },
{ "ydiaeresis", 0xFF },
{ "Aogonek", 0x1A1 },
{ "breve", 0x1A2 },
{ "Lstroke", 0x1A3 },
{ "Lcaron", 0x1A5 },
{ "Sacute", 0x1A6 },
{ "Scaron", 0x1A9 },
{ "Scedilla", 0x1AA },
{ "Tcaron", 0x1AB },
{ "Zacute", 0x1AC },
{ "Zcaron", 0x1AE },
{ "Zabovedot", 0x1AF },
{ "aogonek", 0x1B1 },
{ "ogonek", 0x1B2 },
{ "lstroke", 0x1B3 },
{ "lcaron", 0x1B5 },
{ "sacute", 0x1B6 },
{ "caron", 0x1B7 },
{ "scaron", 0x1B9 },
{ "scedilla", 0x1BA },
{ "tcaron", 0x1BB },
{ "zacute", 0x1BC },
{ "doubleacute", 0x1BD },
{ "zcaron", 0x1BE },
{ "zabovedot", 0x1BF },
{ "Racute", 0x1C0 },
{ "Abreve", 0x1C3 },
{ "Lacute", 0x1C5 },
{ "Cacute", 0x1C6 },
{ "Ccaron", 0x1C8 },
{ "Eogonek", 0x1CA },
{ "Ecaron", 0x1CC },
{ "Dcaron", 0x1CF },
{ "Dstroke", 0x1D0 },
{ "Nacute", 0x1D1 },
{ "Ncaron", 0x1D2 },
{ "Odoubleacute", 0x1D5 },
{ "Rcaron", 0x1D8 },
{ "Uring", 0x1D9 },
{ "Udoubleacute", 0x1DB },
{ "Tcedilla", 0x1DE },
{ "racute", 0x1E0 },
{ "abreve", 0x1E3 },
{ "lacute", 0x1E5 },
{ "cacute", 0x1E6 },
{ "ccaron", 0x1E8 },
{ "eogonek", 0x1EA },
{ "ecaron", 0x1EC },
{ "dcaron", 0x1EF },
{ "dstroke", 0x1F0 },
{ "nacute", 0x1F1 },
{ "ncaron", 0x1F2 },
{ "odoubleacute", 0x1F5 },

{ "rcaron", 0x1F8 },
{ "uring", 0x1F9 },
{ "udoubleacute", 0x1FB },
{ "tcedilla", 0x1FE },
{ "abovedot", 0x1FF },
{ "Hstroke", 0x2A1 },
{ "Hcircumflex", 0x2A6 },
{ "Iabovedot", 0x2A9 },
{ "Gbreve", 0x2AB },
{ "Jcircumflex", 0x2AC },
{ "hstroke", 0x2B1 },
{ "hcircumflex", 0x2B6 },
{ "idotless", 0x2B9 },
{ "gbreve", 0x2BB },
{ "jcircumflex", 0x2BC },
{ "Cabovedot", 0x2C5 },
{ "Ccircumflex", 0x2C6 },
{ "Gabovedot", 0x2D5 },
{ "Gcircumflex", 0x2D8 },
{ "Ubreve", 0x2DD },
{ "Scircumflex", 0x2DE },
{ "cabovedot", 0x2E5 },
{ "ccircumflex", 0x2E6 },
{ "gabovedot", 0x2F5 },
{ "gcircumflex", 0x2F8 },
{ "ubreve", 0x2FD },
{ "scircumflex", 0x2FE },
{ "kra", 0x3A2 },
#ifndef TK_NO_DEPRECATED
{ "kappa", 0x3A2 },
#endif
{ "Rcedilla", 0x3A3 },
{ "Itilde", 0x3A5 },
{ "Lcedilla", 0x3A6 },
{ "Emacron", 0x3AA },
{ "Gcedilla", 0x3AB },
{ "Tslash", 0x3AC },
{ "rcedilla", 0x3B3 },
{ "itilde", 0x3B5 },
{ "lcedilla", 0x3B6 },
{ "emacron", 0x3BA },
{ "gcedilla", 0x3BB },
#ifndef TK_NO_DEPRECATED
{ "gacute", 0x3BB },
#endif
{ "tslash", 0x3BC },
{ "ENG", 0x3BD },
{ "eng", 0x3BF },
{ "Amacron", 0x3C0 },
{ "Iogonek", 0x3C7 },
{ "Eabovedot", 0x3CC },
{ "Imacron", 0x3CF },
{ "Ncedilla", 0x3D1 },
{ "Omacron", 0x3D2 },
{ "Kcedilla", 0x3D3 },
{ "Uogonek", 0x3D9 },
{ "Utilde", 0x3DD },
{ "Umacron", 0x3DE },
{ "amacron", 0x3E0 },
{ "iogonek", 0x3E7 },
{ "eabovedot", 0x3EC },
{ "imacron", 0x3EF },
{ "ncedilla", 0x3F1 },
{ "omacron", 0x3F2 },
{ "kcedilla", 0x3F3 },
{ "uogonek", 0x3F9 },
{ "utilde", 0x3FD },
{ "umacron", 0x3FE },
{ "Wcircumflex", 0x1000174 },
{ "wcircumflex", 0x1000175 },
{ "Ycircumflex", 0x1000176 },
{ "ycircumflex", 0x1000177 },
{ "Babovedot", 0x1001E02 },
{ "babovedot", 0x1001E03 },
{ "Dabovedot", 0x1001E0A },
{ "dabovedot", 0x1001E0B },
{ "Fabovedot", 0x1001E1E },
{ "fabovedot", 0x1001E1F },
{ "Mabovedot", 0x1001E40 },
{ "mabovedot", 0x1001E41 },
{ "Pabovedot", 0x1001E56 },
{ "pabovedot", 0x1001E57 },
{ "Sabovedot", 0x1001E60 },
{ "sabovedot", 0x1001E61 },
{ "Tabovedot", 0x1001E6A },
{ "tabovedot", 0x1001E6B },
{ "Wgrave", 0x1001E80 },
{ "wgrave", 0x1001E81 },
{ "Wacute", 0x1001E82 },
{ "wacute", 0x1001E83 },
{ "Wdiaeresis", 0x1001E84 },
{ "wdiaeresis", 0x1001E85 },
{ "Ygrave", 0x1001EF2 },
{ "ygrave", 0x1001EF3 },
{ "OE", 0x13BC },
{ "oe", 0x13BD },
{ "Ydiaeresis", 0x13BE },
{ "overline", 0x47E },
{ "kana_fullstop", 0x4A1 },
{ "kana_openingbracket", 0x4A2 },
{ "kana_closingbracket", 0x4A3 },
{ "kana_comma", 0x4A4 },
{ "kana_conjunctive", 0x4A5 },
#ifndef TK_NO_DEPRECATED
{ "kana_middledot", 0x4A5 },
#endif
{ "kana_WO", 0x4A6 },
{ "kana_a", 0x4A7 },
{ "kana_i", 0x4A8 },
{ "kana_u", 0x4A9 },
{ "kana_e", 0x4AA },
{ "kana_o", 0x4AB },
{ "kana_ya", 0x4AC },
{ "kana_yu", 0x4AD },
{ "kana_yo", 0x4AE },
{ "kana_tsu", 0x4AF },
#ifndef TK_NO_DEPRECATED
{ "kana_tu", 0x4AF },
#endif
{ "prolongedsound", 0x4B0 },
{ "kana_A", 0x4B1 },
{ "kana_I", 0x4B2 },
{ "kana_U", 0x4B3 },
{ "kana_E", 0x4B4 },
{ "kana_O", 0x4B5 },
{ "kana_KA", 0x4B6 },
{ "kana_KI", 0x4B7 },
{ "kana_KU", 0x4B8 },
{ "kana_KE", 0x4B9 },
{ "kana_KO", 0x4BA },
{ "kana_SA", 0x4BB },
{ "kana_SHI", 0x4BC },
{ "kana_SU", 0x4BD },
{ "kana_SE", 0x4BE },
{ "kana_SO", 0x4BF },
{ "kana_TA", 0x4C0 },
{ "kana_CHI", 0x4C1 },
#ifndef TK_NO_DEPRECATED
{ "kana_TI", 0x4C1 },
#endif
{ "kana_TSU", 0x4C2 },
#ifndef TK_NO_DEPRECATED
{ "kana_TU", 0x4C2 },
#endif
{ "kana_TE", 0x4C3 },
{ "kana_TO", 0x4C4 },
{ "kana_NA", 0x4C5 },
{ "kana_NI", 0x4C6 },
{ "kana_NU", 0x4C7 },
{ "kana_NE", 0x4C8 },
{ "kana_NO", 0x4C9 },
{ "kana_HA", 0x4CA },
{ "kana_HI", 0x4CB },
{ "kana_FU", 0x4CC },
#ifndef TK_NO_DEPRECATED
{ "kana_HU", 0x4CC },
#endif
{ "kana_HE", 0x4CD },
{ "kana_HO", 0x4CE },
{ "kana_MA", 0x4CF },
{ "kana_MI", 0x4D0 },
{ "kana_MU", 0x4D1 },
{ "kana_ME", 0x4D2 },
{ "kana_MO", 0x4D3 },
{ "kana_YA", 0x4D4 },
{ "kana_YU", 0x4D5 },
{ "kana_YO", 0x4D6 },
{ "kana_RA", 0x4D7 },
{ "kana_RI", 0x4D8 },
{ "kana_RU", 0x4D9 },
{ "kana_RE", 0x4DA },
{ "kana_RO", 0x4DB },
{ "kana_WA", 0x4DC },
{ "kana_N", 0x4DD },
{ "voicedsound", 0x4DE },
{ "semivoicedsound", 0x4DF },
{ "kana_switch", 0xFF7E },
{ "Farsi_0", 0x10006F0 },
{ "Farsi_1", 0x10006F1 },
{ "Farsi_2", 0x10006F2 },
{ "Farsi_3", 0x10006F3 },
{ "Farsi_4", 0x10006F4 },
{ "Farsi_5", 0x10006F5 },
{ "Farsi_6", 0x10006F6 },
{ "Farsi_7", 0x10006F7 },
{ "Farsi_8", 0x10006F8 },
{ "Farsi_9", 0x10006F9 },
{ "Arabic_percent", 0x100066A },
{ "Arabic_superscript_alef", 0x1000670 },
{ "Arabic_tteh", 0x1000679 },
{ "Arabic_peh", 0x100067E },
{ "Arabic_tcheh", 0x1000686 },
{ "Arabic_ddal", 0x1000688 },
{ "Arabic_rreh", 0x1000691 },
{ "Arabic_comma", 0x5AC },
{ "Arabic_fullstop", 0x10006D4 },
{ "Arabic_0", 0x1000660 },
{ "Arabic_1", 0x1000661 },
{ "Arabic_2", 0x1000662 },
{ "Arabic_3", 0x1000663 },
{ "Arabic_4", 0x1000664 },
{ "Arabic_5", 0x1000665 },
{ "Arabic_6", 0x1000666 },
{ "Arabic_7", 0x1000667 },
{ "Arabic_8", 0x1000668 },
{ "Arabic_9", 0x1000669 },
{ "Arabic_semicolon", 0x5BB },
{ "Arabic_question_mark", 0x5BF },
{ "Arabic_hamza", 0x5C1 },
{ "Arabic_maddaonalef", 0x5C2 },
{ "Arabic_hamzaonalef", 0x5C3 },
{ "Arabic_hamzaonwaw", 0x5C4 },
{ "Arabic_hamzaunderalef", 0x5C5 },
{ "Arabic_hamzaonyeh", 0x5C6 },
{ "Arabic_alef", 0x5C7 },
{ "Arabic_beh", 0x5C8 },
{ "Arabic_tehmarbuta", 0x5C9 },
{ "Arabic_teh", 0x5CA },
{ "Arabic_theh", 0x5CB },
{ "Arabic_jeem", 0x5CC },
{ "Arabic_hah", 0x5CD },
{ "Arabic_khah", 0x5CE },
{ "Arabic_dal", 0x5CF },
{ "Arabic_thal", 0x5D0 },
{ "Arabic_ra", 0x5D1 },
{ "Arabic_zain", 0x5D2 },
{ "Arabic_seen", 0x5D3 },
{ "Arabic_sheen", 0x5D4 },
{ "Arabic_sad", 0x5D5 },
{ "Arabic_dad", 0x5D6 },
{ "Arabic_tah", 0x5D7 },
{ "Arabic_zah", 0x5D8 },
{ "Arabic_ain", 0x5D9 },
{ "Arabic_ghain", 0x5DA },
{ "Arabic_tatweel", 0x5E0 },
{ "Arabic_feh", 0x5E1 },
{ "Arabic_qaf", 0x5E2 },
{ "Arabic_kaf", 0x5E3 },
{ "Arabic_lam", 0x5E4 },
{ "Arabic_meem", 0x5E5 },
{ "Arabic_noon", 0x5E6 },
{ "Arabic_ha", 0x5E7 },
#ifndef TK_NO_DEPRECATED
{ "Arabic_heh", 0x5E7 },
#endif
{ "Arabic_waw", 0x5E8 },
{ "Arabic_alefmaksura", 0x5E9 },
{ "Arabic_yeh", 0x5EA },
{ "Arabic_fathatan", 0x5EB },
{ "Arabic_dammatan", 0x5EC },
{ "Arabic_kasratan", 0x5ED },
{ "Arabic_fatha", 0x5EE },
{ "Arabic_damma", 0x5EF },
{ "Arabic_kasra", 0x5F0 },
{ "Arabic_shadda", 0x5F1 },
{ "Arabic_sukun", 0x5F2 },
{ "Arabic_madda_above", 0x1000653 },
{ "Arabic_hamza_above", 0x1000654 },
{ "Arabic_hamza_below", 0x1000655 },
{ "Arabic_jeh", 0x1000698 },
{ "Arabic_veh", 0x10006A4 },
{ "Arabic_keheh", 0x10006A9 },
{ "Arabic_gaf", 0x10006AF },
{ "Arabic_noon_ghunna", 0x10006BA },
{ "Arabic_heh_doachashmee", 0x10006BE },
{ "Farsi_yeh", 0x10006CC },
{ "Arabic_farsi_yeh", 0x10006CC },
{ "Arabic_yeh_baree", 0x10006D2 },
{ "Arabic_heh_goal", 0x10006C1 },
{ "Arabic_switch", 0xFF7E },
{ "Cyrillic_GHE_bar", 0x1000492 },
{ "Cyrillic_ghe_bar", 0x1000493 },
{ "Cyrillic_ZHE_descender", 0x1000496 },
{ "Cyrillic_zhe_descender", 0x1000497 },
{ "Cyrillic_KA_descender", 0x100049A },
{ "Cyrillic_ka_descender", 0x100049B },
{ "Cyrillic_KA_vertstroke", 0x100049C },
{ "Cyrillic_ka_vertstroke", 0x100049D },
{ "Cyrillic_EN_descender", 0x10004A2 },
{ "Cyrillic_en_descender", 0x10004A3 },
{ "Cyrillic_U_straight", 0x10004AE },
{ "Cyrillic_u_straight", 0x10004AF },
{ "Cyrillic_U_straight_bar", 0x10004B0 },
{ "Cyrillic_u_straight_bar", 0x10004B1 },
{ "Cyrillic_HA_descender", 0x10004B2 },
{ "Cyrillic_ha_descender", 0x10004B3 },
{ "Cyrillic_CHE_descender", 0x10004B6 },
{ "Cyrillic_che_descender", 0x10004B7 },
{ "Cyrillic_CHE_vertstroke", 0x10004B8 },
{ "Cyrillic_che_vertstroke", 0x10004B9 },
{ "Cyrillic_SHHA", 0x10004BA },
{ "Cyrillic_shha", 0x10004BB },
{ "Cyrillic_SCHWA", 0x10004D8 },
{ "Cyrillic_schwa", 0x10004D9 },
{ "Cyrillic_I_macron", 0x10004E2 },
{ "Cyrillic_i_macron", 0x10004E3 },
{ "Cyrillic_O_bar", 0x10004E8 },
{ "Cyrillic_o_bar", 0x10004E9 },
{ "Cyrillic_U_macron", 0x10004EE },
{ "Cyrillic_u_macron", 0x10004EF },
{ "Serbian_dje", 0x6A1 },
{ "Macedonia_gje", 0x6A2 },
{ "Cyrillic_io", 0x6A3 },
{ "Ukrainian_ie", 0x6A4 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_je", 0x6A4 },
#endif
{ "Macedonia_dse", 0x6A5 },
{ "Ukrainian_i", 0x6A6 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_i", 0x6A6 },
#endif
{ "Ukrainian_yi", 0x6A7 },






#ifndef TK_NO_DEPRECATED







{ "Ukranian_yi", 0x6A7 },
#endif
{ "Cyrillic_je", 0x6A8 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_je", 0x6A8 },
#endif


{ "Cyrillic_lje", 0x6A9 },
#ifndef TK_NO_DEPRECATED

{ "Serbian_lje", 0x6A9 },
#endif
{ "Cyrillic_nje", 0x6AA },
#ifndef TK_NO_DEPRECATED
{ "Serbian_nje", 0x6AA },
#endif

{ "Serbian_tshe", 0x6AB },
{ "Macedonia_kje", 0x6AC },





{ "Ukrainian_ghe_with_upturn", 0x6AD },
{ "Byelorussian_shortu", 0x6AE },
{ "Cyrillic_dzhe", 0x6AF },
#ifndef TK_NO_DEPRECATED
{ "Serbian_dze", 0x6AF },
#endif
{ "numerosign", 0x6B0 },
{ "Serbian_DJE", 0x6B1 },
{ "Macedonia_GJE", 0x6B2 },
{ "Cyrillic_IO", 0x6B3 },
{ "Ukrainian_IE", 0x6B4 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_JE", 0x6B4 },
#endif
{ "Macedonia_DSE", 0x6B5 },
{ "Ukrainian_I", 0x6B6 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_I", 0x6B6 },
#endif
{ "Ukrainian_YI", 0x6B7 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_YI", 0x6B7 },
#endif
{ "Cyrillic_JE", 0x6B8 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_JE", 0x6B8 },
#endif
{ "Cyrillic_LJE", 0x6B9 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_LJE", 0x6B9 },
#endif
{ "Cyrillic_NJE", 0x6BA },
#ifndef TK_NO_DEPRECATED
{ "Serbian_NJE", 0x6BA },
#endif
{ "Serbian_TSHE", 0x6BB },
{ "Macedonia_KJE", 0x6BC },
{ "Ukrainian_GHE_WITH_UPTURN", 0x6BD },
{ "Byelorussian_SHORTU", 0x6BE },
{ "Cyrillic_DZHE", 0x6BF },
#ifndef TK_NO_DEPRECATED
{ "Serbian_DZE", 0x6BF },
#endif
{ "Cyrillic_yu", 0x6C0 },
{ "Cyrillic_a", 0x6C1 },
{ "Cyrillic_be", 0x6C2 },
{ "Cyrillic_tse", 0x6C3 },
{ "Cyrillic_de", 0x6C4 },
{ "Cyrillic_ie", 0x6C5 },
{ "Cyrillic_ef", 0x6C6 },
{ "Cyrillic_ghe", 0x6C7 },
{ "Cyrillic_ha", 0x6C8 },
{ "Cyrillic_i", 0x6C9 },
{ "Cyrillic_shorti", 0x6CA },
{ "Cyrillic_ka", 0x6CB },
{ "Cyrillic_el", 0x6CC },
{ "Cyrillic_em", 0x6CD },
{ "Cyrillic_en", 0x6CE },
{ "Cyrillic_o", 0x6CF },
{ "Cyrillic_pe", 0x6D0 },
{ "Cyrillic_ya", 0x6D1 },
{ "Cyrillic_er", 0x6D2 },
{ "Cyrillic_es", 0x6D3 },
{ "Cyrillic_te", 0x6D4 },
{ "Cyrillic_u", 0x6D5 },
{ "Cyrillic_zhe", 0x6D6 },
{ "Cyrillic_ve", 0x6D7 },
{ "Cyrillic_softsign", 0x6D8 },
{ "Cyrillic_yeru", 0x6D9 },
{ "Cyrillic_ze", 0x6DA },
{ "Cyrillic_sha", 0x6DB },
{ "Cyrillic_e", 0x6DC },
{ "Cyrillic_shcha", 0x6DD },
{ "Cyrillic_che", 0x6DE },
{ "Cyrillic_hardsign", 0x6DF },
{ "Cyrillic_YU", 0x6E0 },
{ "Cyrillic_A", 0x6E1 },
{ "Cyrillic_BE", 0x6E2 },
{ "Cyrillic_TSE", 0x6E3 },
{ "Cyrillic_DE", 0x6E4 },
{ "Cyrillic_IE", 0x6E5 },
{ "Cyrillic_EF", 0x6E6 },
{ "Cyrillic_GHE", 0x6E7 },
{ "Cyrillic_HA", 0x6E8 },
{ "Cyrillic_I", 0x6E9 },
{ "Cyrillic_SHORTI", 0x6EA },
{ "Cyrillic_KA", 0x6EB },
{ "Cyrillic_EL", 0x6EC },
{ "Cyrillic_EM", 0x6ED },
{ "Cyrillic_EN", 0x6EE },
{ "Cyrillic_O", 0x6EF },
{ "Cyrillic_PE", 0x6F0 },
{ "Cyrillic_YA", 0x6F1 },
{ "Cyrillic_ER", 0x6F2 },
{ "Cyrillic_ES", 0x6F3 },
{ "Cyrillic_TE", 0x6F4 },
{ "Cyrillic_U", 0x6F5 },
{ "Cyrillic_ZHE", 0x6F6 },
{ "Cyrillic_VE", 0x6F7 },
{ "Cyrillic_SOFTSIGN", 0x6F8 },
{ "Cyrillic_YERU", 0x6F9 },
{ "Cyrillic_ZE", 0x6FA },
{ "Cyrillic_SHA", 0x6FB },
{ "Cyrillic_E", 0x6FC },
{ "Cyrillic_SHCHA", 0x6FD },
{ "Cyrillic_CHE", 0x6FE },
{ "Cyrillic_HARDSIGN", 0x6FF },
{ "Greek_ALPHAaccent", 0x7A1 },
{ "Greek_EPSILONaccent", 0x7A2 },
{ "Greek_ETAaccent", 0x7A3 },
{ "Greek_IOTAaccent", 0x7A4 },
{ "Greek_IOTAdieresis", 0x7A5 },
{ "Greek_IOTAdiaeresis", 0x7A5 },
{ "Greek_IOTAaccentdiaeresis", 0x7A6 },
{ "Greek_OMICRONaccent", 0x7A7 },
{ "Greek_UPSILONaccent", 0x7A8 },
{ "Greek_UPSILONdieresis", 0x7A9 },
{ "Greek_UPSILONaccentdieresis", 0x7AA },
{ "Greek_OMEGAaccent", 0x7AB },
{ "Greek_accentdieresis", 0x7AE },
{ "Greek_horizbar", 0x7AF },
{ "Greek_alphaaccent", 0x7B1 },
{ "Greek_epsilonaccent", 0x7B2 },
{ "Greek_etaaccent", 0x7B3 },
{ "Greek_iotaaccent", 0x7B4 },
{ "Greek_iotadieresis", 0x7B5 },
{ "Greek_iotaaccentdieresis", 0x7B6 },
{ "Greek_omicronaccent", 0x7B7 },
{ "Greek_upsilonaccent", 0x7B8 },
{ "Greek_upsilondieresis", 0x7B9 },
{ "Greek_upsilonaccentdieresis", 0x7BA },
{ "Greek_omegaaccent", 0x7BB },
{ "Greek_ALPHA", 0x7C1 },
{ "Greek_BETA", 0x7C2 },
{ "Greek_GAMMA", 0x7C3 },
{ "Greek_DELTA", 0x7C4 },
{ "Greek_EPSILON", 0x7C5 },
{ "Greek_ZETA", 0x7C6 },
{ "Greek_ETA", 0x7C7 },
{ "Greek_THETA", 0x7C8 },
{ "Greek_IOTA", 0x7C9 },
{ "Greek_KAPPA", 0x7CA },
{ "Greek_LAMDA", 0x7CB },
{ "Greek_LAMBDA", 0x7CB },
{ "Greek_MU", 0x7CC },
{ "Greek_NU", 0x7CD },
{ "Greek_XI", 0x7CE },
{ "Greek_OMICRON", 0x7CF },
{ "Greek_PI", 0x7D0 },
{ "Greek_RHO", 0x7D1 },
{ "Greek_SIGMA", 0x7D2 },
{ "Greek_TAU", 0x7D4 },
{ "Greek_UPSILON", 0x7D5 },
{ "Greek_PHI", 0x7D6 },
{ "Greek_CHI", 0x7D7 },
{ "Greek_PSI", 0x7D8 },
{ "Greek_OMEGA", 0x7D9 },
{ "Greek_alpha", 0x7E1 },
{ "Greek_beta", 0x7E2 },
{ "Greek_gamma", 0x7E3 },
{ "Greek_delta", 0x7E4 },
{ "Greek_epsilon", 0x7E5 },
{ "Greek_zeta", 0x7E6 },
{ "Greek_eta", 0x7E7 },
{ "Greek_theta", 0x7E8 },
{ "Greek_iota", 0x7E9 },
{ "Greek_kappa", 0x7EA },
{ "Greek_lamda", 0x7EB },
{ "Greek_lambda", 0x7EB },
{ "Greek_mu", 0x7EC },
{ "Greek_nu", 0x7ED },
{ "Greek_xi", 0x7EE },
{ "Greek_omicron", 0x7EF },
{ "Greek_pi", 0x7F0 },
{ "Greek_rho", 0x7F1 },
{ "Greek_sigma", 0x7F2 },
{ "Greek_finalsmallsigma", 0x7F3 },
{ "Greek_tau", 0x7F4 },
{ "Greek_upsilon", 0x7F5 },
{ "Greek_phi", 0x7F6 },
{ "Greek_chi", 0x7F7 },
{ "Greek_psi", 0x7F8 },
{ "Greek_omega", 0x7F9 },
{ "Greek_switch", 0xFF7E },
{ "leftradical", 0x8A1 },
{ "topleftradical", 0x8A2 },
{ "horizconnector", 0x8A3 },
{ "topintegral", 0x8A4 },
{ "botintegral", 0x8A5 },
{ "vertconnector", 0x8A6 },
{ "topleftsqbracket", 0x8A7 },
{ "botleftsqbracket", 0x8A8 },
{ "toprightsqbracket", 0x8A9 },
{ "botrightsqbracket", 0x8AA },
{ "topleftparens", 0x8AB },
{ "botleftparens", 0x8AC },
{ "toprightparens", 0x8AD },
{ "botrightparens", 0x8AE },
{ "leftmiddlecurlybrace", 0x8AF },
{ "rightmiddlecurlybrace", 0x8B0 },
{ "topleftsummation", 0x8B1 },
{ "botleftsummation", 0x8B2 },
{ "topvertsummationconnector", 0x8B3 },
{ "botvertsummationconnector", 0x8B4 },
{ "toprightsummation", 0x8B5 },
{ "botrightsummation", 0x8B6 },
{ "rightmiddlesummation", 0x8B7 },
{ "lessthanequal", 0x8BC },
{ "notequal", 0x8BD },
{ "greaterthanequal", 0x8BE },
{ "integral", 0x8BF },
{ "therefore", 0x8C0 },
{ "variation", 0x8C1 },
{ "infinity", 0x8C2 },
{ "nabla", 0x8C5 },
{ "approximate", 0x8C8 },
{ "similarequal", 0x8C9 },
{ "ifonlyif", 0x8CD },
{ "implies", 0x8CE },
{ "identical", 0x8CF },
{ "radical", 0x8D6 },
{ "includedin", 0x8DA },
{ "includes", 0x8DB },
{ "intersection", 0x8DC },
{ "union", 0x8DD },
{ "logicaland", 0x8DE },
{ "logicalor", 0x8DF },
{ "partialderivative", 0x8EF },
{ "function", 0x8F6 },
{ "leftarrow", 0x8FB },
{ "uparrow", 0x8FC },
{ "rightarrow", 0x8FD },
{ "downarrow", 0x8FE },
{ "blank", 0x9DF },
{ "soliddiamond", 0x9E0 },
{ "checkerboard", 0x9E1 },
{ "ht", 0x9E2 },
{ "ff", 0x9E3 },
{ "cr", 0x9E4 },
{ "lf", 0x9E5 },
{ "nl", 0x9E8 },
{ "vt", 0x9E9 },
{ "lowrightcorner", 0x9EA },
{ "uprightcorner", 0x9EB },
{ "upleftcorner", 0x9EC },
{ "lowleftcorner", 0x9ED },
{ "crossinglines", 0x9EE },
{ "horizlinescan1", 0x9EF },
{ "horizlinescan3", 0x9F0 },
{ "horizlinescan5", 0x9F1 },
{ "horizlinescan7", 0x9F2 },
{ "horizlinescan9", 0x9F3 },
{ "leftt", 0x9F4 },
{ "rightt", 0x9F5 },
{ "bott", 0x9F6 },
{ "topt", 0x9F7 },
{ "vertbar", 0x9F8 },
{ "emspace", 0xAA1 },
{ "enspace", 0xAA2 },
{ "em3space", 0xAA3 },
{ "em4space", 0xAA4 },
{ "digitspace", 0xAA5 },
{ "punctspace", 0xAA6 },
{ "thinspace", 0xAA7 },
{ "hairspace", 0xAA8 },
{ "emdash", 0xAA9 },
{ "endash", 0xAAA },
{ "signifblank", 0xAAC },
{ "ellipsis", 0xAAE },
{ "doubbaselinedot", 0xAAF },
{ "onethird", 0xAB0 },
{ "twothirds", 0xAB1 },
{ "onefifth", 0xAB2 },
{ "twofifths", 0xAB3 },
{ "threefifths", 0xAB4 },
{ "fourfifths", 0xAB5 },
{ "onesixth", 0xAB6 },
{ "fivesixths", 0xAB7 },
{ "careof", 0xAB8 },
{ "figdash", 0xABB },
{ "leftanglebracket", 0xABC },
{ "decimalpoint", 0xABD },
{ "rightanglebracket", 0xABE },
{ "marker", 0xABF },
{ "oneeighth", 0xAC3 },
{ "threeeighths", 0xAC4 },
{ "fiveeighths", 0xAC5 },
{ "seveneighths", 0xAC6 },
{ "trademark", 0xAC9 },
{ "signaturemark", 0xACA },
{ "trademarkincircle", 0xACB },
{ "leftopentriangle", 0xACC },
{ "rightopentriangle", 0xACD },
{ "emopencircle", 0xACE },
{ "emopenrectangle", 0xACF },
{ "leftsinglequotemark", 0xAD0 },
{ "rightsinglequotemark", 0xAD1 },
{ "leftdoublequotemark", 0xAD2 },
{ "rightdoublequotemark", 0xAD3 },
{ "prescription", 0xAD4 },
{ "permille", 0xAD5 },
{ "minutes", 0xAD6 },
{ "seconds", 0xAD7 },
{ "latincross", 0xAD9 },
{ "hexagram", 0xADA },
{ "filledrectbullet", 0xADB },
{ "filledlefttribullet", 0xADC },
{ "filledrighttribullet", 0xADD },
{ "emfilledcircle", 0xADE },
{ "emfilledrect", 0xADF },
{ "enopencircbullet", 0xAE0 },
{ "enopensquarebullet", 0xAE1 },
{ "openrectbullet", 0xAE2 },
{ "opentribulletup", 0xAE3 },
{ "opentribulletdown", 0xAE4 },
{ "openstar", 0xAE5 },
{ "enfilledcircbullet", 0xAE6 },
{ "enfilledsqbullet", 0xAE7 },
{ "filledtribulletup", 0xAE8 },
{ "filledtribulletdown", 0xAE9 },
{ "leftpointer", 0xAEA },
{ "rightpointer", 0xAEB },
{ "club", 0xAEC },
{ "diamond", 0xAED },
{ "heart", 0xAEE },
{ "maltesecross", 0xAF0 },
{ "dagger", 0xAF1 },
{ "doubledagger", 0xAF2 },
{ "checkmark", 0xAF3 },
{ "ballotcross", 0xAF4 },
{ "musicalsharp", 0xAF5 },
{ "musicalflat", 0xAF6 },
{ "malesymbol", 0xAF7 },
{ "femalesymbol", 0xAF8 },
{ "telephone", 0xAF9 },
{ "telephonerecorder", 0xAFA },
{ "phonographcopyright", 0xAFB },
{ "caret", 0xAFC },
{ "singlelowquotemark", 0xAFD },
{ "doublelowquotemark", 0xAFE },
{ "cursor", 0xAFF },
{ "leftcaret", 0xBA3 },
{ "rightcaret", 0xBA6 },
{ "downcaret", 0xBA8 },
{ "upcaret", 0xBA9 },
{ "overbar", 0xBC0 },
{ "downtack", 0xBC2 },
{ "upshoe", 0xBC3 },
{ "downstile", 0xBC4 },
{ "underbar", 0xBC6 },
{ "jot", 0xBCA },
{ "quad", 0xBCC },
{ "uptack", 0xBCE },
{ "circle", 0xBCF },
{ "upstile", 0xBD3 },
{ "downshoe", 0xBD6 },
{ "rightshoe", 0xBD8 },
{ "leftshoe", 0xBDA },
{ "lefttack", 0xBDC },
{ "righttack", 0xBFC },
{ "hebrew_doublelowline", 0xCDF },
{ "hebrew_aleph", 0xCE0 },
{ "hebrew_bet", 0xCE1 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_beth", 0xCE1 },
#endif
{ "hebrew_gimel", 0xCE2 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_gimmel", 0xCE2 },
#endif
{ "hebrew_dalet", 0xCE3 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_daleth", 0xCE3 },
#endif
{ "hebrew_he", 0xCE4 },
{ "hebrew_waw", 0xCE5 },
{ "hebrew_zain", 0xCE6 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_zayin", 0xCE6 },
#endif
{ "hebrew_chet", 0xCE7 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_het", 0xCE7 },
#endif
{ "hebrew_tet", 0xCE8 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_teth", 0xCE8 },
#endif
{ "hebrew_yod", 0xCE9 },
{ "hebrew_finalkaph", 0xCEA },
{ "hebrew_kaph", 0xCEB },
{ "hebrew_lamed", 0xCEC },
{ "hebrew_finalmem", 0xCED },
{ "hebrew_mem", 0xCEE },
{ "hebrew_finalnun", 0xCEF },
{ "hebrew_nun", 0xCF0 },
{ "hebrew_samech", 0xCF1 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_samekh", 0xCF1 },
#endif
{ "hebrew_ayin", 0xCF2 },
{ "hebrew_finalpe", 0xCF3 },
{ "hebrew_pe", 0xCF4 },
{ "hebrew_finalzade", 0xCF5 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_finalzadi", 0xCF5 },
#endif
{ "hebrew_zade", 0xCF6 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_zadi", 0xCF6 },
#endif
{ "hebrew_qoph", 0xCF7 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_kuf", 0xCF7 },
#endif
{ "hebrew_resh", 0xCF8 },
{ "hebrew_shin", 0xCF9 },
{ "hebrew_taw", 0xCFA },
#ifndef TK_NO_DEPRECATED
{ "hebrew_taf", 0xCFA },
#endif
{ "Hebrew_switch", 0xFF7E },
{ "Thai_kokai", 0xDA1 },
{ "Thai_khokhai", 0xDA2 },
{ "Thai_khokhuat", 0xDA3 },
{ "Thai_khokhwai", 0xDA4 },
{ "Thai_khokhon", 0xDA5 },
{ "Thai_khorakhang", 0xDA6 },
{ "Thai_ngongu", 0xDA7 },
{ "Thai_chochan", 0xDA8 },
{ "Thai_choching", 0xDA9 },
{ "Thai_chochang", 0xDAA },
{ "Thai_soso", 0xDAB },
{ "Thai_chochoe", 0xDAC },
{ "Thai_yoying", 0xDAD },
{ "Thai_dochada", 0xDAE },
{ "Thai_topatak", 0xDAF },
{ "Thai_thothan", 0xDB0 },
{ "Thai_thonangmontho", 0xDB1 },
{ "Thai_thophuthao", 0xDB2 },
{ "Thai_nonen", 0xDB3 },
{ "Thai_dodek", 0xDB4 },
{ "Thai_totao", 0xDB5 },
{ "Thai_thothung", 0xDB6 },
{ "Thai_thothahan", 0xDB7 },
{ "Thai_thothong", 0xDB8 },
{ "Thai_nonu", 0xDB9 },
{ "Thai_bobaimai", 0xDBA },
{ "Thai_popla", 0xDBB },
{ "Thai_phophung", 0xDBC },
{ "Thai_fofa", 0xDBD },
{ "Thai_phophan", 0xDBE },
{ "Thai_fofan", 0xDBF },
{ "Thai_phosamphao", 0xDC0 },
{ "Thai_moma", 0xDC1 },
{ "Thai_yoyak", 0xDC2 },
{ "Thai_rorua", 0xDC3 },
{ "Thai_ru", 0xDC4 },
{ "Thai_loling", 0xDC5 },
{ "Thai_lu", 0xDC6 },
{ "Thai_wowaen", 0xDC7 },
{ "Thai_sosala", 0xDC8 },
{ "Thai_sorusi", 0xDC9 },
{ "Thai_sosua", 0xDCA },
{ "Thai_hohip", 0xDCB },
{ "Thai_lochula", 0xDCC },
{ "Thai_oang", 0xDCD },
{ "Thai_honokhuk", 0xDCE },
{ "Thai_paiyannoi", 0xDCF },
{ "Thai_saraa", 0xDD0 },
{ "Thai_maihanakat", 0xDD1 },
{ "Thai_saraaa", 0xDD2 },
{ "Thai_saraam", 0xDD3 },
{ "Thai_sarai", 0xDD4 },
{ "Thai_saraii", 0xDD5 },
{ "Thai_saraue", 0xDD6 },
{ "Thai_sarauee", 0xDD7 },
{ "Thai_sarau", 0xDD8 },
{ "Thai_sarauu", 0xDD9 },
{ "Thai_phinthu", 0xDDA },
{ "Thai_maihanakat_maitho", 0xDDE },
{ "Thai_baht", 0xDDF },
{ "Thai_sarae", 0xDE0 },
{ "Thai_saraae", 0xDE1 },
{ "Thai_sarao", 0xDE2 },
{ "Thai_saraaimaimuan", 0xDE3 },
{ "Thai_saraaimaimalai", 0xDE4 },
{ "Thai_lakkhangyao", 0xDE5 },
{ "Thai_maiyamok", 0xDE6 },
{ "Thai_maitaikhu", 0xDE7 },
{ "Thai_maiek", 0xDE8 },
{ "Thai_maitho", 0xDE9 },
{ "Thai_maitri", 0xDEA },
{ "Thai_maichattawa", 0xDEB },
{ "Thai_thanthakhat", 0xDEC },
{ "Thai_nikhahit", 0xDED },
{ "Thai_leksun", 0xDF0 },
{ "Thai_leknung", 0xDF1 },
{ "Thai_leksong", 0xDF2 },
{ "Thai_leksam", 0xDF3 },
{ "Thai_leksi", 0xDF4 },
{ "Thai_lekha", 0xDF5 },
{ "Thai_lekhok", 0xDF6 },
{ "Thai_lekchet", 0xDF7 },
{ "Thai_lekpaet", 0xDF8 },
{ "Thai_lekkao", 0xDF9 },
{ "Hangul", 0xFF31 },
{ "Hangul_Start", 0xFF32 },
{ "Hangul_End", 0xFF33 },
{ "Hangul_Hanja", 0xFF34 },
{ "Hangul_Jamo", 0xFF35 },
{ "Hangul_Romaja", 0xFF36 },
{ "Hangul_Codeinput", 0xFF37 },
{ "Hangul_Jeonja", 0xFF38 },
{ "Hangul_Banja", 0xFF39 },
{ "Hangul_PreHanja", 0xFF3A },
{ "Hangul_PostHanja", 0xFF3B },
{ "Hangul_SingleCandidate", 0xFF3C },
{ "Hangul_MultipleCandidate", 0xFF3D },
{ "Hangul_PreviousCandidate", 0xFF3E },
{ "Hangul_Special", 0xFF3F },
{ "Hangul_switch", 0xFF7E },
{ "Hangul_Kiyeog", 0xEA1 },
{ "Hangul_SsangKiyeog", 0xEA2 },
{ "Hangul_KiyeogSios", 0xEA3 },
{ "Hangul_Nieun", 0xEA4 },
{ "Hangul_NieunJieuj", 0xEA5 },
{ "Hangul_NieunHieuh", 0xEA6 },
{ "Hangul_Dikeud", 0xEA7 },
{ "Hangul_SsangDikeud", 0xEA8 },
{ "Hangul_Rieul", 0xEA9 },
{ "Hangul_RieulKiyeog", 0xEAA },
{ "Hangul_RieulMieum", 0xEAB },
{ "Hangul_RieulPieub", 0xEAC },
{ "Hangul_RieulSios", 0xEAD },
{ "Hangul_RieulTieut", 0xEAE },
{ "Hangul_RieulPhieuf", 0xEAF },
{ "Hangul_RieulHieuh", 0xEB0 },
{ "Hangul_Mieum", 0xEB1 },
{ "Hangul_Pieub", 0xEB2 },
{ "Hangul_SsangPieub", 0xEB3 },
{ "Hangul_PieubSios", 0xEB4 },
{ "Hangul_Sios", 0xEB5 },
{ "Hangul_SsangSios", 0xEB6 },
{ "Hangul_Ieung", 0xEB7 },
{ "Hangul_Jieuj", 0xEB8 },
{ "Hangul_SsangJieuj", 0xEB9 },
{ "Hangul_Cieuc", 0xEBA },
{ "Hangul_Khieuq", 0xEBB },
{ "Hangul_Tieut", 0xEBC },
{ "Hangul_Phieuf", 0xEBD },
{ "Hangul_Hieuh", 0xEBE },
{ "Hangul_A", 0xEBF },
{ "Hangul_AE", 0xEC0 },
{ "Hangul_YA", 0xEC1 },
{ "Hangul_YAE", 0xEC2 },
{ "Hangul_EO", 0xEC3 },
{ "Hangul_E", 0xEC4 },
{ "Hangul_YEO", 0xEC5 },
{ "Hangul_YE", 0xEC6 },
{ "Hangul_O", 0xEC7 },
{ "Hangul_WA", 0xEC8 },
{ "Hangul_WAE", 0xEC9 },
{ "Hangul_OE", 0xECA },
{ "Hangul_YO", 0xECB },
{ "Hangul_U", 0xECC },
{ "Hangul_WEO", 0xECD },
{ "Hangul_WE", 0xECE },
{ "Hangul_WI", 0xECF },
{ "Hangul_YU", 0xED0 },
{ "Hangul_EU", 0xED1 },
{ "Hangul_YI", 0xED2 },
{ "Hangul_I", 0xED3 },
{ "Hangul_J_Kiyeog", 0xED4 },
{ "Hangul_J_SsangKiyeog", 0xED5 },
{ "Hangul_J_KiyeogSios", 0xED6 },
{ "Hangul_J_Nieun", 0xED7 },
{ "Hangul_J_NieunJieuj", 0xED8 },
{ "Hangul_J_NieunHieuh", 0xED9 },
{ "Hangul_J_Dikeud", 0xEDA },
{ "Hangul_J_Rieul", 0xEDB },
{ "Hangul_J_RieulKiyeog", 0xEDC },
{ "Hangul_J_RieulMieum", 0xEDD },
{ "Hangul_J_RieulPieub", 0xEDE },
{ "Hangul_J_RieulSios", 0xEDF },
{ "Hangul_J_RieulTieut", 0xEE0 },
{ "Hangul_J_RieulPhieuf", 0xEE1 },
{ "Hangul_J_RieulHieuh", 0xEE2 },
{ "Hangul_J_Mieum", 0xEE3 },
{ "Hangul_J_Pieub", 0xEE4 },
{ "Hangul_J_PieubSios", 0xEE5 },
{ "Hangul_J_Sios", 0xEE6 },
{ "Hangul_J_SsangSios", 0xEE7 },
{ "Hangul_J_Ieung", 0xEE8 },
{ "Hangul_J_Jieuj", 0xEE9 },
{ "Hangul_J_Cieuc", 0xEEA },
{ "Hangul_J_Khieuq", 0xEEB },
{ "Hangul_J_Tieut", 0xEEC },
{ "Hangul_J_Phieuf", 0xEED },
{ "Hangul_J_Hieuh", 0xEEE },
{ "Hangul_RieulYeorinHieuh", 0xEEF },
{ "Hangul_SunkyeongeumMieum", 0xEF0 },
{ "Hangul_SunkyeongeumPieub", 0xEF1 },
{ "Hangul_PanSios", 0xEF2 },
{ "Hangul_KkogjiDalrinIeung", 0xEF3 },
{ "Hangul_SunkyeongeumPhieuf", 0xEF4 },
{ "Hangul_YeorinHieuh", 0xEF5 },
{ "Hangul_AraeA", 0xEF6 },
{ "Hangul_AraeAE", 0xEF7 },
{ "Hangul_J_PanSios", 0xEF8 },
{ "Hangul_J_KkogjiDalrinIeung", 0xEF9 },
{ "Hangul_J_YeorinHieuh", 0xEFA },
{ "Korean_Won", 0xEFF },
{ "Armenian_ligature_ew", 0x1000587 },
{ "Armenian_full_stop", 0x1000589 },
{ "Armenian_verjaket", 0x1000589 },
{ "Armenian_separation_mark", 0x100055D },
{ "Armenian_but", 0x100055D },
{ "Armenian_hyphen", 0x100058A },
{ "Armenian_yentamna", 0x100058A },
{ "Armenian_exclam", 0x100055C },
{ "Armenian_amanak", 0x100055C },
{ "Armenian_accent", 0x100055B },
{ "Armenian_shesht", 0x100055B },
{ "Armenian_question", 0x100055E },
{ "Armenian_paruyk", 0x100055E },
{ "Armenian_AYB", 0x1000531 },
{ "Armenian_ayb", 0x1000561 },
{ "Armenian_BEN", 0x1000532 },
{ "Armenian_ben", 0x1000562 },
{ "Armenian_GIM", 0x1000533 },
{ "Armenian_gim", 0x1000563 },
{ "Armenian_DA", 0x1000534 },
{ "Armenian_da", 0x1000564 },
{ "Armenian_YECH", 0x1000535 },
{ "Armenian_yech", 0x1000565 },
{ "Armenian_ZA", 0x1000536 },
{ "Armenian_za", 0x1000566 },
{ "Armenian_E", 0x1000537 },
{ "Armenian_e", 0x1000567 },
{ "Armenian_AT", 0x1000538 },
{ "Armenian_at", 0x1000568 },
{ "Armenian_TO", 0x1000539 },
{ "Armenian_to", 0x1000569 },
{ "Armenian_ZHE", 0x100053A },
{ "Armenian_zhe", 0x100056A },
{ "Armenian_INI", 0x100053B },
{ "Armenian_ini", 0x100056B },
{ "Armenian_LYUN", 0x100053C },
{ "Armenian_lyun", 0x100056C },
{ "Armenian_KHE", 0x100053D },
{ "Armenian_khe", 0x100056D },
{ "Armenian_TSA", 0x100053E },
{ "Armenian_tsa", 0x100056E },
{ "Armenian_KEN", 0x100053F },
{ "Armenian_ken", 0x100056F },
{ "Armenian_HO", 0x1000540 },
{ "Armenian_ho", 0x1000570 },
{ "Armenian_DZA", 0x1000541 },
{ "Armenian_dza", 0x1000571 },
{ "Armenian_GHAT", 0x1000542 },
{ "Armenian_ghat", 0x1000572 },
{ "Armenian_TCHE", 0x1000543 },
{ "Armenian_tche", 0x1000573 },
{ "Armenian_MEN", 0x1000544 },
{ "Armenian_men", 0x1000574 },
{ "Armenian_HI", 0x1000545 },
{ "Armenian_hi", 0x1000575 },
{ "Armenian_NU", 0x1000546 },
{ "Armenian_nu", 0x1000576 },
{ "Armenian_SHA", 0x1000547 },
{ "Armenian_sha", 0x1000577 },
{ "Armenian_VO", 0x1000548 },
{ "Armenian_vo", 0x1000578 },
{ "Armenian_CHA", 0x1000549 },
{ "Armenian_cha", 0x1000579 },
{ "Armenian_PE", 0x100054A },
{ "Armenian_pe", 0x100057A },
{ "Armenian_JE", 0x100054B },
{ "Armenian_je", 0x100057B },
{ "Armenian_RA", 0x100054C },
{ "Armenian_ra", 0x100057C },
{ "Armenian_SE", 0x100054D },
{ "Armenian_se", 0x100057D },
{ "Armenian_VEV", 0x100054E },
{ "Armenian_vev", 0x100057E },
{ "Armenian_TYUN", 0x100054F },
{ "Armenian_tyun", 0x100057F },
{ "Armenian_RE", 0x1000550 },
{ "Armenian_re", 0x1000580 },
{ "Armenian_TSO", 0x1000551 },
{ "Armenian_tso", 0x1000581 },
{ "Armenian_VYUN", 0x1000552 },
{ "Armenian_vyun", 0x1000582 },
{ "Armenian_PYUR", 0x1000553 },
{ "Armenian_pyur", 0x1000583 },
{ "Armenian_KE", 0x1000554 },
{ "Armenian_ke", 0x1000584 },
{ "Armenian_O", 0x1000555 },
{ "Armenian_o", 0x1000585 },
{ "Armenian_FE", 0x1000556 },
{ "Armenian_fe", 0x1000586 },
{ "Armenian_apostrophe", 0x100055A },
{ "Georgian_an", 0x10010D0 },
{ "Georgian_ban", 0x10010D1 },
{ "Georgian_gan", 0x10010D2 },
{ "Georgian_don", 0x10010D3 },
{ "Georgian_en", 0x10010D4 },
{ "Georgian_vin", 0x10010D5 },
{ "Georgian_zen", 0x10010D6 },
{ "Georgian_tan", 0x10010D7 },
{ "Georgian_in", 0x10010D8 },
{ "Georgian_kan", 0x10010D9 },
{ "Georgian_las", 0x10010DA },
{ "Georgian_man", 0x10010DB },
{ "Georgian_nar", 0x10010DC },
{ "Georgian_on", 0x10010DD },
{ "Georgian_par", 0x10010DE },
{ "Georgian_zhar", 0x10010DF },
{ "Georgian_rae", 0x10010E0 },
{ "Georgian_san", 0x10010E1 },
{ "Georgian_tar", 0x10010E2 },
{ "Georgian_un", 0x10010E3 },
{ "Georgian_phar", 0x10010E4 },
{ "Georgian_khar", 0x10010E5 },
{ "Georgian_ghan", 0x10010E6 },
{ "Georgian_qar", 0x10010E7 },
{ "Georgian_shin", 0x10010E8 },
{ "Georgian_chin", 0x10010E9 },
{ "Georgian_can", 0x10010EA },
{ "Georgian_jil", 0x10010EB },
{ "Georgian_cil", 0x10010EC },
{ "Georgian_char", 0x10010ED },
{ "Georgian_xan", 0x10010EE },
{ "Georgian_jhan", 0x10010EF },
{ "Georgian_hae", 0x10010F0 },
{ "Georgian_he", 0x10010F1 },
{ "Georgian_hie", 0x10010F2 },
{ "Georgian_we", 0x10010F3 },
{ "Georgian_har", 0x10010F4 },
{ "Georgian_hoe", 0x10010F5 },
{ "Georgian_fi", 0x10010F6 },
{ "Xabovedot", 0x1001E8A },
{ "Ibreve", 0x100012C },
{ "Zstroke", 0x10001B5 },
{ "Gcaron", 0x10001E6 },
{ "Ocaron", 0x10001D1 },
{ "Obarred", 0x100019F },
{ "xabovedot", 0x1001E8B },
{ "ibreve", 0x100012D },
{ "zstroke", 0x10001B6 },
{ "gcaron", 0x10001E7 },
{ "ocaron", 0x10001D2 },
{ "obarred", 0x1000275 },
{ "SCHWA", 0x100018F },
{ "schwa", 0x1000259 },
{ "EZH", 0x10001B7 },
{ "ezh", 0x1000292 },
{ "Lbelowdot", 0x1001E36 },
{ "lbelowdot", 0x1001E37 },
{ "Abelowdot", 0x1001EA0 },
{ "abelowdot", 0x1001EA1 },
{ "Ahook", 0x1001EA2 },
{ "ahook", 0x1001EA3 },
{ "Acircumflexacute", 0x1001EA4 },
{ "acircumflexacute", 0x1001EA5 },
{ "Acircumflexgrave", 0x1001EA6 },
{ "acircumflexgrave", 0x1001EA7 },
{ "Acircumflexhook", 0x1001EA8 },
{ "acircumflexhook", 0x1001EA9 },
{ "Acircumflextilde", 0x1001EAA },
{ "acircumflextilde", 0x1001EAB },
{ "Acircumflexbelowdot", 0x1001EAC },
{ "acircumflexbelowdot", 0x1001EAD },
{ "Abreveacute", 0x1001EAE },
{ "abreveacute", 0x1001EAF },
{ "Abrevegrave", 0x1001EB0 },
{ "abrevegrave", 0x1001EB1 },
{ "Abrevehook", 0x1001EB2 },
{ "abrevehook", 0x1001EB3 },
{ "Abrevetilde", 0x1001EB4 },
{ "abrevetilde", 0x1001EB5 },
{ "Abrevebelowdot", 0x1001EB6 },
{ "abrevebelowdot", 0x1001EB7 },
{ "Ebelowdot", 0x1001EB8 },
{ "ebelowdot", 0x1001EB9 },
{ "Ehook", 0x1001EBA },
{ "ehook", 0x1001EBB },
{ "Etilde", 0x1001EBC },
{ "etilde", 0x1001EBD },
{ "Ecircumflexacute", 0x1001EBE },
{ "ecircumflexacute", 0x1001EBF },
{ "Ecircumflexgrave", 0x1001EC0 },
{ "ecircumflexgrave", 0x1001EC1 },
{ "Ecircumflexhook", 0x1001EC2 },
{ "ecircumflexhook", 0x1001EC3 },
{ "Ecircumflextilde", 0x1001EC4 },
{ "ecircumflextilde", 0x1001EC5 },
{ "Ecircumflexbelowdot", 0x1001EC6 },
{ "ecircumflexbelowdot", 0x1001EC7 },
{ "Ihook", 0x1001EC8 },
{ "ihook", 0x1001EC9 },
{ "Ibelowdot", 0x1001ECA },
{ "ibelowdot", 0x1001ECB },
{ "Obelowdot", 0x1001ECC },
{ "obelowdot", 0x1001ECD },
{ "Ohook", 0x1001ECE },
{ "ohook", 0x1001ECF },
{ "Ocircumflexacute", 0x1001ED0 },
{ "ocircumflexacute", 0x1001ED1 },
{ "Ocircumflexgrave", 0x1001ED2 },
{ "ocircumflexgrave", 0x1001ED3 },
{ "Ocircumflexhook", 0x1001ED4 },
{ "ocircumflexhook", 0x1001ED5 },
{ "Ocircumflextilde", 0x1001ED6 },
{ "ocircumflextilde", 0x1001ED7 },
{ "Ocircumflexbelowdot", 0x1001ED8 },
{ "ocircumflexbelowdot", 0x1001ED9 },
{ "Ohornacute", 0x1001EDA },
{ "ohornacute", 0x1001EDB },
{ "Ohorngrave", 0x1001EDC },
{ "ohorngrave", 0x1001EDD },
{ "Ohornhook", 0x1001EDE },
{ "ohornhook", 0x1001EDF },
{ "Ohorntilde", 0x1001EE0 },
{ "ohorntilde", 0x1001EE1 },
{ "Ohornbelowdot", 0x1001EE2 },
{ "ohornbelowdot", 0x1001EE3 },
{ "Ubelowdot", 0x1001EE4 },
{ "ubelowdot", 0x1001EE5 },
{ "Uhook", 0x1001EE6 },
{ "uhook", 0x1001EE7 },
{ "Uhornacute", 0x1001EE8 },
{ "uhornacute", 0x1001EE9 },
{ "Uhorngrave", 0x1001EEA },
{ "uhorngrave", 0x1001EEB },
{ "Uhornhook", 0x1001EEC },
{ "uhornhook", 0x1001EED },
{ "Uhorntilde", 0x1001EEE },
{ "uhorntilde", 0x1001EEF },
{ "Uhornbelowdot", 0x1001EF0 },
{ "uhornbelowdot", 0x1001EF1 },
{ "Ybelowdot", 0x1001EF4 },
{ "ybelowdot", 0x1001EF5 },
{ "Yhook", 0x1001EF6 },
{ "yhook", 0x1001EF7 },
{ "Ytilde", 0x1001EF8 },
{ "ytilde", 0x1001EF9 },
{ "Ohorn", 0x10001A0 },
{ "ohorn", 0x10001A1 },
{ "Uhorn", 0x10001AF },
{ "uhorn", 0x10001B0 },
{ "EcuSign", 0x10020A0 },
{ "ColonSign", 0x10020A1 },
{ "CruzeiroSign", 0x10020A2 },
{ "FFrancSign", 0x10020A3 },
{ "LiraSign", 0x10020A4 },
{ "MillSign", 0x10020A5 },
{ "NairaSign", 0x10020A6 },
{ "PesetaSign", 0x10020A7 },
{ "RupeeSign", 0x10020A8 },
{ "WonSign", 0x10020A9 },
{ "NewSheqelSign", 0x10020AA },
{ "DongSign", 0x10020AB },
{ "EuroSign", 0x20AC },
{ "zerosuperior", 0x1002070 },
{ "foursuperior", 0x1002074 },
{ "fivesuperior", 0x1002075 },
{ "sixsuperior", 0x1002076 },
{ "sevensuperior", 0x1002077 },
{ "eightsuperior", 0x1002078 },
{ "ninesuperior", 0x1002079 },
{ "zerosubscript", 0x1002080 },
{ "onesubscript", 0x1002081 },
{ "twosubscript", 0x1002082 },
{ "threesubscript", 0x1002083 },
{ "foursubscript", 0x1002084 },
{ "fivesubscript", 0x1002085 },
{ "sixsubscript", 0x1002086 },
{ "sevensubscript", 0x1002087 },
{ "eightsubscript", 0x1002088 },
{ "ninesubscript", 0x1002089 },
{ "partdifferential", 0x1002202 },
{ "emptyset", 0x1002205 },
{ "elementof", 0x1002208 },
{ "notelementof", 0x1002209 },
{ "containsas", 0x100220B },
{ "squareroot", 0x100221A },
{ "cuberoot", 0x100221B },
{ "fourthroot", 0x100221C },
{ "dintegral", 0x100222C },
{ "tintegral", 0x100222D },
{ "because", 0x1002235 },
{ "approxeq", 0x1002248 },
{ "notapproxeq", 0x1002247 },
{ "notidentical", 0x1002262 },
{ "stricteq", 0x1002263 },
{ "braille_dot_1", 0xFFF1 },
{ "braille_dot_2", 0xFFF2 },
{ "braille_dot_3", 0xFFF3 },
{ "braille_dot_4", 0xFFF4 },
{ "braille_dot_5", 0xFFF5 },
{ "braille_dot_6", 0xFFF6 },
{ "braille_dot_7", 0xFFF7 },
{ "braille_dot_8", 0xFFF8 },
{ "braille_dot_9", 0xFFF9 },
{ "braille_dot_10", 0xFFFA },
{ "braille_blank", 0x1002800 },
{ "braille_dots_1", 0x1002801 },
{ "braille_dots_2", 0x1002802 },
{ "braille_dots_12", 0x1002803 },
{ "braille_dots_3", 0x1002804 },
{ "braille_dots_13", 0x1002805 },
{ "braille_dots_23", 0x1002806 },
{ "braille_dots_123", 0x1002807 },
{ "braille_dots_4", 0x1002808 },
{ "braille_dots_14", 0x1002809 },
{ "braille_dots_24", 0x100280A },
{ "braille_dots_124", 0x100280B },
{ "braille_dots_34", 0x100280C },
{ "braille_dots_134", 0x100280D },
{ "braille_dots_234", 0x100280E },
{ "braille_dots_1234", 0x100280F },
{ "braille_dots_5", 0x1002810 },
{ "braille_dots_15", 0x1002811 },
{ "braille_dots_25", 0x1002812 },
{ "braille_dots_125", 0x1002813 },
{ "braille_dots_35", 0x1002814 },
{ "braille_dots_135", 0x1002815 },
{ "braille_dots_235", 0x1002816 },
{ "braille_dots_1235", 0x1002817 },
{ "braille_dots_45", 0x1002818 },
{ "braille_dots_145", 0x1002819 },
{ "braille_dots_245", 0x100281A },
{ "braille_dots_1245", 0x100281B },
{ "braille_dots_345", 0x100281C },
{ "braille_dots_1345", 0x100281D },
{ "braille_dots_2345", 0x100281E },
{ "braille_dots_12345", 0x100281F },
{ "braille_dots_6", 0x1002820 },
{ "braille_dots_16", 0x1002821 },
{ "braille_dots_26", 0x1002822 },
{ "braille_dots_126", 0x1002823 },
{ "braille_dots_36", 0x1002824 },
{ "braille_dots_136", 0x1002825 },
{ "braille_dots_236", 0x1002826 },
{ "braille_dots_1236", 0x1002827 },
{ "braille_dots_46", 0x1002828 },
{ "braille_dots_146", 0x1002829 },
{ "braille_dots_246", 0x100282A },
{ "braille_dots_1246", 0x100282B },
{ "braille_dots_346", 0x100282C },
{ "braille_dots_1346", 0x100282D },
{ "braille_dots_2346", 0x100282E },
{ "braille_dots_12346", 0x100282F },
{ "braille_dots_56", 0x1002830 },
{ "braille_dots_156", 0x1002831 },
{ "braille_dots_256", 0x1002832 },
{ "braille_dots_1256", 0x1002833 },
{ "braille_dots_356", 0x1002834 },
{ "braille_dots_1356", 0x1002835 },
{ "braille_dots_2356", 0x1002836 },
{ "braille_dots_12356", 0x1002837 },
{ "braille_dots_456", 0x1002838 },
{ "braille_dots_1456", 0x1002839 },
{ "braille_dots_2456", 0x100283A },
{ "braille_dots_12456", 0x100283B },
{ "braille_dots_3456", 0x100283C },
{ "braille_dots_13456", 0x100283D },
{ "braille_dots_23456", 0x100283E },
{ "braille_dots_123456", 0x100283F },
{ "braille_dots_7", 0x1002840 },
{ "braille_dots_17", 0x1002841 },
{ "braille_dots_27", 0x1002842 },
{ "braille_dots_127", 0x1002843 },
{ "braille_dots_37", 0x1002844 },
{ "braille_dots_137", 0x1002845 },
{ "braille_dots_237", 0x1002846 },
{ "braille_dots_1237", 0x1002847 },
{ "braille_dots_47", 0x1002848 },
{ "braille_dots_147", 0x1002849 },
{ "braille_dots_247", 0x100284A },
{ "braille_dots_1247", 0x100284B },
{ "braille_dots_347", 0x100284C },
{ "braille_dots_1347", 0x100284D },
{ "braille_dots_2347", 0x100284E },
{ "braille_dots_12347", 0x100284F },
{ "braille_dots_57", 0x1002850 },
{ "braille_dots_157", 0x1002851 },
{ "braille_dots_257", 0x1002852 },
{ "braille_dots_1257", 0x1002853 },
{ "braille_dots_357", 0x1002854 },
{ "braille_dots_1357", 0x1002855 },
{ "braille_dots_2357", 0x1002856 },
{ "braille_dots_12357", 0x1002857 },
{ "braille_dots_457", 0x1002858 },
{ "braille_dots_1457", 0x1002859 },
{ "braille_dots_2457", 0x100285A },
{ "braille_dots_12457", 0x100285B },
{ "braille_dots_3457", 0x100285C },
{ "braille_dots_13457", 0x100285D },
{ "braille_dots_23457", 0x100285E },
{ "braille_dots_123457", 0x100285F },
{ "braille_dots_67", 0x1002860 },
{ "braille_dots_167", 0x1002861 },
{ "braille_dots_267", 0x1002862 },
{ "braille_dots_1267", 0x1002863 },
{ "braille_dots_367", 0x1002864 },
{ "braille_dots_1367", 0x1002865 },
{ "braille_dots_2367", 0x1002866 },
{ "braille_dots_12367", 0x1002867 },
{ "braille_dots_467", 0x1002868 },
{ "braille_dots_1467", 0x1002869 },
{ "braille_dots_2467", 0x100286A },
{ "braille_dots_12467", 0x100286B },
{ "braille_dots_3467", 0x100286C },
{ "braille_dots_13467", 0x100286D },
{ "braille_dots_23467", 0x100286E },
{ "braille_dots_123467", 0x100286F },
{ "braille_dots_567", 0x1002870 },
{ "braille_dots_1567", 0x1002871 },
{ "braille_dots_2567", 0x1002872 },
{ "braille_dots_12567", 0x1002873 },
{ "braille_dots_3567", 0x1002874 },
{ "braille_dots_13567", 0x1002875 },
{ "braille_dots_23567", 0x1002876 },
{ "braille_dots_123567", 0x1002877 },
{ "braille_dots_4567", 0x1002878 },
{ "braille_dots_14567", 0x1002879 },
{ "braille_dots_24567", 0x100287A },
{ "braille_dots_124567", 0x100287B },
{ "braille_dots_34567", 0x100287C },
{ "braille_dots_134567", 0x100287D },
{ "braille_dots_234567", 0x100287E },
{ "braille_dots_1234567", 0x100287F },
{ "braille_dots_8", 0x1002880 },
{ "braille_dots_18", 0x1002881 },
{ "braille_dots_28", 0x1002882 },
{ "braille_dots_128", 0x1002883 },
{ "braille_dots_38", 0x1002884 },
{ "braille_dots_138", 0x1002885 },
{ "braille_dots_238", 0x1002886 },
{ "braille_dots_1238", 0x1002887 },
{ "braille_dots_48", 0x1002888 },
{ "braille_dots_148", 0x1002889 },
{ "braille_dots_248", 0x100288A },
{ "braille_dots_1248", 0x100288B },
{ "braille_dots_348", 0x100288C },
{ "braille_dots_1348", 0x100288D },
{ "braille_dots_2348", 0x100288E },
{ "braille_dots_12348", 0x100288F },
{ "braille_dots_58", 0x1002890 },
{ "braille_dots_158", 0x1002891 },
{ "braille_dots_258", 0x1002892 },
{ "braille_dots_1258", 0x1002893 },
{ "braille_dots_358", 0x1002894 },
{ "braille_dots_1358", 0x1002895 },
{ "braille_dots_2358", 0x1002896 },
{ "braille_dots_12358", 0x1002897 },
{ "braille_dots_458", 0x1002898 },
{ "braille_dots_1458", 0x1002899 },
{ "braille_dots_2458", 0x100289A },
{ "braille_dots_12458", 0x100289B },
{ "braille_dots_3458", 0x100289C },
{ "braille_dots_13458", 0x100289D },
{ "braille_dots_23458", 0x100289E },
{ "braille_dots_123458", 0x100289F },
{ "braille_dots_68", 0x10028A0 },
{ "braille_dots_168", 0x10028A1 },
{ "braille_dots_268", 0x10028A2 },
{ "braille_dots_1268", 0x10028A3 },
{ "braille_dots_368", 0x10028A4 },
{ "braille_dots_1368", 0x10028A5 },
{ "braille_dots_2368", 0x10028A6 },
{ "braille_dots_12368", 0x10028A7 },
{ "braille_dots_468", 0x10028A8 },
{ "braille_dots_1468", 0x10028A9 },
{ "braille_dots_2468", 0x10028AA },
{ "braille_dots_12468", 0x10028AB },
{ "braille_dots_3468", 0x10028AC },
{ "braille_dots_13468", 0x10028AD },
{ "braille_dots_23468", 0x10028AE },
{ "braille_dots_123468", 0x10028AF },
{ "braille_dots_568", 0x10028B0 },
{ "braille_dots_1568", 0x10028B1 },
{ "braille_dots_2568", 0x10028B2 },
{ "braille_dots_12568", 0x10028B3 },
{ "braille_dots_3568", 0x10028B4 },
{ "braille_dots_13568", 0x10028B5 },
{ "braille_dots_23568", 0x10028B6 },
{ "braille_dots_123568", 0x10028B7 },
{ "braille_dots_4568", 0x10028B8 },
{ "braille_dots_14568", 0x10028B9 },
{ "braille_dots_24568", 0x10028BA },
{ "braille_dots_124568", 0x10028BB },
{ "braille_dots_34568", 0x10028BC },
{ "braille_dots_134568", 0x10028BD },
{ "braille_dots_234568", 0x10028BE },
{ "braille_dots_1234568", 0x10028BF },
{ "braille_dots_78", 0x10028C0 },
{ "braille_dots_178", 0x10028C1 },
{ "braille_dots_278", 0x10028C2 },
{ "braille_dots_1278", 0x10028C3 },
{ "braille_dots_378", 0x10028C4 },
{ "braille_dots_1378", 0x10028C5 },
{ "braille_dots_2378", 0x10028C6 },
{ "braille_dots_12378", 0x10028C7 },
{ "braille_dots_478", 0x10028C8 },
{ "braille_dots_1478", 0x10028C9 },
{ "braille_dots_2478", 0x10028CA },
{ "braille_dots_12478", 0x10028CB },
{ "braille_dots_3478", 0x10028CC },
{ "braille_dots_13478", 0x10028CD },
{ "braille_dots_23478", 0x10028CE },
{ "braille_dots_123478", 0x10028CF },
{ "braille_dots_578", 0x10028D0 },
{ "braille_dots_1578", 0x10028D1 },
{ "braille_dots_2578", 0x10028D2 },
{ "braille_dots_12578", 0x10028D3 },
{ "braille_dots_3578", 0x10028D4 },
{ "braille_dots_13578", 0x10028D5 },
{ "braille_dots_23578", 0x10028D6 },
{ "braille_dots_123578", 0x10028D7 },
{ "braille_dots_4578", 0x10028D8 },
{ "braille_dots_14578", 0x10028D9 },
{ "braille_dots_24578", 0x10028DA },
{ "braille_dots_124578", 0x10028DB },
{ "braille_dots_34578", 0x10028DC },
{ "braille_dots_134578", 0x10028DD },
{ "braille_dots_234578", 0x10028DE },
{ "braille_dots_1234578", 0x10028DF },
{ "braille_dots_678", 0x10028E0 },
{ "braille_dots_1678", 0x10028E1 },
{ "braille_dots_2678", 0x10028E2 },
{ "braille_dots_12678", 0x10028E3 },
{ "braille_dots_3678", 0x10028E4 },
{ "braille_dots_13678", 0x10028E5 },
{ "braille_dots_23678", 0x10028E6 },
{ "braille_dots_123678", 0x10028E7 },
{ "braille_dots_4678", 0x10028E8 },
{ "braille_dots_14678", 0x10028E9 },
{ "braille_dots_24678", 0x10028EA },
{ "braille_dots_124678", 0x10028EB },
{ "braille_dots_34678", 0x10028EC },
{ "braille_dots_134678", 0x10028ED },
{ "braille_dots_234678", 0x10028EE },
{ "braille_dots_1234678", 0x10028EF },
{ "braille_dots_5678", 0x10028F0 },
{ "braille_dots_15678", 0x10028F1 },
{ "braille_dots_25678", 0x10028F2 },
{ "braille_dots_125678", 0x10028F3 },
{ "braille_dots_35678", 0x10028F4 },
{ "braille_dots_135678", 0x10028F5 },
{ "braille_dots_235678", 0x10028F6 },
{ "braille_dots_1235678", 0x10028F7 },
{ "braille_dots_45678", 0x10028F8 },
{ "braille_dots_145678", 0x10028F9 },
{ "braille_dots_245678", 0x10028FA },
{ "braille_dots_1245678", 0x10028FB },
{ "braille_dots_345678", 0x10028FC },
{ "braille_dots_1345678", 0x10028FD },
{ "braille_dots_2345678", 0x10028FE },
{ "braille_dots_12345678", 0x10028FF },
{ "Sinh_ng", 0x1000D82 },
{ "Sinh_h2", 0x1000D83 },
{ "Sinh_a", 0x1000D85 },
{ "Sinh_aa", 0x1000D86 },
{ "Sinh_ae", 0x1000D87 },
{ "Sinh_aee", 0x1000D88 },
{ "Sinh_i", 0x1000D89 },
{ "Sinh_ii", 0x1000D8A },
{ "Sinh_u", 0x1000D8B },
{ "Sinh_uu", 0x1000D8C },
{ "Sinh_ri", 0x1000D8D },
{ "Sinh_rii", 0x1000D8E },
{ "Sinh_lu", 0x1000D8F },
{ "Sinh_luu", 0x1000D90 },
{ "Sinh_e", 0x1000D91 },
{ "Sinh_ee", 0x1000D92 },
{ "Sinh_ai", 0x1000D93 },
{ "Sinh_o", 0x1000D94 },
{ "Sinh_oo", 0x1000D95 },
{ "Sinh_au", 0x1000D96 },
{ "Sinh_ka", 0x1000D9A },
{ "Sinh_kha", 0x1000D9B },
{ "Sinh_ga", 0x1000D9C },
{ "Sinh_gha", 0x1000D9D },
{ "Sinh_ng2", 0x1000D9E },
{ "Sinh_nga", 0x1000D9F },
{ "Sinh_ca", 0x1000DA0 },
{ "Sinh_cha", 0x1000DA1 },
{ "Sinh_ja", 0x1000DA2 },
{ "Sinh_jha", 0x1000DA3 },
{ "Sinh_nya", 0x1000DA4 },
{ "Sinh_jnya", 0x1000DA5 },
{ "Sinh_nja", 0x1000DA6 },
{ "Sinh_tta", 0x1000DA7 },
{ "Sinh_ttha", 0x1000DA8 },
{ "Sinh_dda", 0x1000DA9 },
{ "Sinh_ddha", 0x1000DAA },
{ "Sinh_nna", 0x1000DAB },
{ "Sinh_ndda", 0x1000DAC },
{ "Sinh_tha", 0x1000DAD },
{ "Sinh_thha", 0x1000DAE },
{ "Sinh_dha", 0x1000DAF },
{ "Sinh_dhha", 0x1000DB0 },
{ "Sinh_na", 0x1000DB1 },
{ "Sinh_ndha", 0x1000DB3 },
{ "Sinh_pa", 0x1000DB4 },
{ "Sinh_pha", 0x1000DB5 },
{ "Sinh_ba", 0x1000DB6 },
{ "Sinh_bha", 0x1000DB7 },
{ "Sinh_ma", 0x1000DB8 },
{ "Sinh_mba", 0x1000DB9 },
{ "Sinh_ya", 0x1000DBA },
{ "Sinh_ra", 0x1000DBB },
{ "Sinh_la", 0x1000DBD },
{ "Sinh_va", 0x1000DC0 },
{ "Sinh_sha", 0x1000DC1 },
{ "Sinh_ssha", 0x1000DC2 },
{ "Sinh_sa", 0x1000DC3 },
{ "Sinh_ha", 0x1000DC4 },
{ "Sinh_lla", 0x1000DC5 },
{ "Sinh_fa", 0x1000DC6 },
{ "Sinh_al", 0x1000DCA },
{ "Sinh_aa2", 0x1000DCF },
{ "Sinh_ae2", 0x1000DD0 },
{ "Sinh_aee2", 0x1000DD1 },
{ "Sinh_i2", 0x1000DD2 },
{ "Sinh_ii2", 0x1000DD3 },
{ "Sinh_u2", 0x1000DD4 },
{ "Sinh_uu2", 0x1000DD6 },
{ "Sinh_ru2", 0x1000DD8 },
{ "Sinh_e2", 0x1000DD9 },
{ "Sinh_ee2", 0x1000DDA },
{ "Sinh_ai2", 0x1000DDB },
{ "Sinh_o2", 0x1000DDC },
{ "Sinh_oo2", 0x1000DDD },
{ "Sinh_au2", 0x1000DDE },
{ "Sinh_lu2", 0x1000DDF },
{ "Sinh_ruu2", 0x1000DF2 },
{ "Sinh_luu2", 0x1000DF3 },
{ "Sinh_kunddaliya", 0x1000DF4 },
{ "XF86ModeLock", 0x1008FF01 },
{ "XF86MonBrightnessUp", 0x1008FF02 },
{ "XF86MonBrightnessDown", 0x1008FF03 },
{ "XF86KbdLightOnOff", 0x1008FF04 },
{ "XF86KbdBrightnessUp", 0x1008FF05 },
{ "XF86KbdBrightnessDown", 0x1008FF06 },
{ "XF86MonBrightnessCycle", 0x1008FF07 },
{ "XF86Standby", 0x1008FF10 },
{ "XF86AudioLowerVolume", 0x1008FF11 },
{ "XF86AudioMute", 0x1008FF12 },
{ "XF86AudioRaiseVolume", 0x1008FF13 },
{ "XF86AudioPlay", 0x1008FF14 },
{ "XF86AudioStop", 0x1008FF15 },
{ "XF86AudioPrev", 0x1008FF16 },
{ "XF86AudioNext", 0x1008FF17 },
{ "XF86HomePage", 0x1008FF18 },
{ "XF86Mail", 0x1008FF19 },
{ "XF86Start", 0x1008FF1A },
{ "XF86Search", 0x1008FF1B },
{ "XF86AudioRecord", 0x1008FF1C },
{ "XF86Calculator", 0x1008FF1D },
{ "XF86Memo", 0x1008FF1E },
{ "XF86ToDoList", 0x1008FF1F },
{ "XF86Calendar", 0x1008FF20 },
{ "XF86PowerDown", 0x1008FF21 },
{ "XF86ContrastAdjust", 0x1008FF22 },
{ "XF86RockerUp", 0x1008FF23 },
{ "XF86RockerDown", 0x1008FF24 },
{ "XF86RockerEnter", 0x1008FF25 },
{ "XF86Back", 0x1008FF26 },
{ "XF86Forward", 0x1008FF27 },
{ "XF86Stop", 0x1008FF28 },
{ "XF86Refresh", 0x1008FF29 },
{ "XF86PowerOff", 0x1008FF2A },
{ "XF86WakeUp", 0x1008FF2B },
{ "XF86Eject", 0x1008FF2C },
{ "XF86ScreenSaver", 0x1008FF2D },
{ "XF86WWW", 0x1008FF2E },
{ "XF86Sleep", 0x1008FF2F },
{ "XF86Favorites", 0x1008FF30 },
{ "XF86AudioPause", 0x1008FF31 },
{ "XF86AudioMedia", 0x1008FF32 },
{ "XF86MyComputer", 0x1008FF33 },
{ "XF86VendorHome", 0x1008FF34 },
{ "XF86LightBulb", 0x1008FF35 },
{ "XF86Shop", 0x1008FF36 },
{ "XF86History", 0x1008FF37 },
{ "XF86OpenURL", 0x1008FF38 },
{ "XF86AddFavorite", 0x1008FF39 },
{ "XF86HotLinks", 0x1008FF3A },
{ "XF86BrightnessAdjust", 0x1008FF3B },
{ "XF86Finance", 0x1008FF3C },
{ "XF86Community", 0x1008FF3D },
{ "XF86AudioRewind", 0x1008FF3E },
{ "XF86BackForward", 0x1008FF3F },
{ "XF86Launch0", 0x1008FF40 },
{ "XF86Launch1", 0x1008FF41 },
{ "XF86Launch2", 0x1008FF42 },
{ "XF86Launch3", 0x1008FF43 },
{ "XF86Launch4", 0x1008FF44 },
{ "XF86Launch5", 0x1008FF45 },
{ "XF86Launch6", 0x1008FF46 },
{ "XF86Launch7", 0x1008FF47 },
{ "XF86Launch8", 0x1008FF48 },
{ "XF86Launch9", 0x1008FF49 },
{ "XF86LaunchA", 0x1008FF4A },
{ "XF86LaunchB", 0x1008FF4B },
{ "XF86LaunchC", 0x1008FF4C },
{ "XF86LaunchD", 0x1008FF4D },
{ "XF86LaunchE", 0x1008FF4E },
{ "XF86LaunchF", 0x1008FF4F },
{ "XF86ApplicationLeft", 0x1008FF50 },
{ "XF86ApplicationRight", 0x1008FF51 },
{ "XF86Book", 0x1008FF52 },
{ "XF86CD", 0x1008FF53 },
{ "XF86Calculater", 0x1008FF54 },
{ "XF86Clear", 0x1008FF55 },
{ "XF86Close", 0x1008FF56 },
{ "XF86Copy", 0x1008FF57 },
{ "XF86Cut", 0x1008FF58 },
{ "XF86Display", 0x1008FF59 },
{ "XF86DOS", 0x1008FF5A },
{ "XF86Documents", 0x1008FF5B },
{ "XF86Excel", 0x1008FF5C },
{ "XF86Explorer", 0x1008FF5D },
{ "XF86Game", 0x1008FF5E },
{ "XF86Go", 0x1008FF5F },
{ "XF86iTouch", 0x1008FF60 },
{ "XF86LogOff", 0x1008FF61 },
{ "XF86Market", 0x1008FF62 },
{ "XF86Meeting", 0x1008FF63 },
{ "XF86MenuKB", 0x1008FF65 },
{ "XF86MenuPB", 0x1008FF66 },
{ "XF86MySites", 0x1008FF67 },
{ "XF86New", 0x1008FF68 },
{ "XF86News", 0x1008FF69 },
{ "XF86OfficeHome", 0x1008FF6A },
{ "XF86Open", 0x1008FF6B },
{ "XF86Option", 0x1008FF6C },
{ "XF86Paste", 0x1008FF6D },
{ "XF86Phone", 0x1008FF6E },
{ "XF86Q", 0x1008FF70 },
{ "XF86Reply", 0x1008FF72 },
{ "XF86Reload", 0x1008FF73 },
{ "XF86RotateWindows", 0x1008FF74 },
{ "XF86RotationPB", 0x1008FF75 },
{ "XF86RotationKB", 0x1008FF76 },
{ "XF86Save", 0x1008FF77 },
{ "XF86ScrollUp", 0x1008FF78 },
{ "XF86ScrollDown", 0x1008FF79 },
{ "XF86ScrollClick", 0x1008FF7A },
{ "XF86Send", 0x1008FF7B },
{ "XF86Spell", 0x1008FF7C },
{ "XF86SplitScreen", 0x1008FF7D },
{ "XF86Support", 0x1008FF7E },
{ "XF86TaskPane", 0x1008FF7F },
{ "XF86Terminal", 0x1008FF80 },
{ "XF86Tools", 0x1008FF81 },
{ "XF86Travel", 0x1008FF82 },
{ "XF86UserPB", 0x1008FF84 },
{ "XF86User1KB", 0x1008FF85 },
{ "XF86User2KB", 0x1008FF86 },
{ "XF86Video", 0x1008FF87 },
{ "XF86WheelButton", 0x1008FF88 },
{ "XF86Word", 0x1008FF89 },
{ "XF86Xfer", 0x1008FF8A },
{ "XF86ZoomIn", 0x1008FF8B },
{ "XF86ZoomOut", 0x1008FF8C },
{ "XF86Away", 0x1008FF8D },
{ "XF86Messenger", 0x1008FF8E },
{ "XF86WebCam", 0x1008FF8F },
{ "XF86MailForward", 0x1008FF90 },
{ "XF86Pictures", 0x1008FF91 },
{ "XF86Music", 0x1008FF92 },
{ "XF86Battery", 0x1008FF93 },
{ "XF86Bluetooth", 0x1008FF94 },
{ "XF86WLAN", 0x1008FF95 },
{ "XF86UWB", 0x1008FF96 },
{ "XF86AudioForward", 0x1008FF97 },
{ "XF86AudioRepeat", 0x1008FF98 },
{ "XF86AudioRandomPlay", 0x1008FF99 },
{ "XF86Subtitle", 0x1008FF9A },
{ "XF86AudioCycleTrack", 0x1008FF9B },
{ "XF86CycleAngle", 0x1008FF9C },
{ "XF86FrameBack", 0x1008FF9D },
{ "XF86FrameForward", 0x1008FF9E },
{ "XF86Time", 0x1008FF9F },
{ "XF86Select", 0x1008FFA0 },
{ "XF86View", 0x1008FFA1 },
{ "XF86TopMenu", 0x1008FFA2 },
{ "XF86Red", 0x1008FFA3 },
{ "XF86Green", 0x1008FFA4 },
{ "XF86Yellow", 0x1008FFA5 },
{ "XF86Blue", 0x1008FFA6 },
{ "XF86Suspend", 0x1008FFA7 },
{ "XF86Hibernate", 0x1008FFA8 },
{ "XF86TouchpadToggle", 0x1008FFA9 },
{ "XF86TouchpadOn", 0x1008FFB0 },
{ "XF86TouchpadOff", 0x1008FFB1 },
{ "XF86AudioMicMute", 0x1008FFB2 },
{ "XF86Keyboard", 0x1008FFB3 },
{ "XF86WWAN", 0x1008FFB4 },
{ "XF86RFKill", 0x1008FFB5 },
{ "XF86AudioPreset", 0x1008FFB6 },
{ "XF86RotationLockToggle", 0x1008FFB7 },
{ "XF86Switch_VT_1", 0x1008FE01 },
{ "XF86Switch_VT_2", 0x1008FE02 },
{ "XF86Switch_VT_3", 0x1008FE03 },
{ "XF86Switch_VT_4", 0x1008FE04 },
{ "XF86Switch_VT_5", 0x1008FE05 },
{ "XF86Switch_VT_6", 0x1008FE06 },
{ "XF86Switch_VT_7", 0x1008FE07 },
{ "XF86Switch_VT_8", 0x1008FE08 },
{ "XF86Switch_VT_9", 0x1008FE09 },
{ "XF86Switch_VT_10", 0x1008FE0A },
{ "XF86Switch_VT_11", 0x1008FE0B },
{ "XF86Switch_VT_12", 0x1008FE0C },
{ "XF86Ungrab", 0x1008FE20 },
{ "XF86ClearGrab", 0x1008FE21 },
{ "XF86Next_VMode", 0x1008FE22 },
{ "XF86Prev_VMode", 0x1008FE23 },
{ "XF86LogWindowTree", 0x1008FE24 },
{ "XF86LogGrabInfo", 0x1008FE25 },
{ "SunFA_Grave", 0x1005FF00 },
{ "SunFA_Circum", 0x1005FF01 },
{ "SunFA_Tilde", 0x1005FF02 },
{ "SunFA_Acute", 0x1005FF03 },
{ "SunFA_Diaeresis", 0x1005FF04 },
{ "SunFA_Cedilla", 0x1005FF05 },
{ "SunF36", 0x1005FF10 },
{ "SunF37", 0x1005FF11 },
{ "SunSys_Req", 0x1005FF60 },
{ "SunProps", 0x1005FF70 },
{ "SunFront", 0x1005FF71 },
{ "SunCopy", 0x1005FF72 },
{ "SunOpen", 0x1005FF73 },
{ "SunPaste", 0x1005FF74 },
{ "SunCut", 0x1005FF75 },
{ "SunPowerSwitch", 0x1005FF76 },
{ "SunAudioLowerVolume", 0x1005FF77 },
{ "SunAudioMute", 0x1005FF78 },
{ "SunAudioRaiseVolume", 0x1005FF79 },
{ "SunVideoDegauss", 0x1005FF7A },
{ "SunVideoLowerBrightness", 0x1005FF7B },
{ "SunVideoRaiseBrightness", 0x1005FF7C },
{ "SunPowerSwitchShift", 0x1005FF7D },







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
<
|
<
|
|
|
|
<
<
|
<
<
<
<
<
|
|
|
|
|
|
<
|
|
|
<
<
|
|
<
<
|
|
<
<
<
<
|
|
|
|
|
|
|
|
<
|
|
<
|
<
<
<
<
<
|
<
<
|
<
<
<
<
|
|
<
|
|
|
|
|
|
|
|
<
|
|
|
|
|
<
|
|
|
|
|
<
|
|
|
|
|
|
<
|
<
|
|
|
|
|
|
<
<
<
<
<
<
|
|
|
|
|
<
<
|
<
<
<
<
|
|
|
<
<
<
|
<
|
<
|
|
|
|
|
|
|
<
|
|
|
<
<
<
|
|
<
|
<
|
|
|
|
|
|
|
|
|
|
<
<
|
<
<
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
<
<
|
<
<
|
|
<
|
|
<
<
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
|
|
|
<
<
<
<
|
<
|
|
|
|
|
|
|
|
|
|
<
|
|
<
|
|
|
<
<
|
|
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
|
|
|
<
|
|
>
|
|
|
|
<
<
|
|
|
|
<
|
|
|
<
<
|
|
|
|
<
|
<
|
|
<
<
<
|
|
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
<
|
|
|
>
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
<
<
|
<
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
|
<
|
<
<
|
<
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
|
|
|
|
>
>
|
<
>
|
<
|
<
|
|
>
|
|
>
>
>
>
>
|
|
|
<
|
<
|
|
|
|
|
<
|
<
|
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
<
<
<
<
<
<
|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
|
<
|
|
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
|
|
|
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
|
<
|
|
|
|
|
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
|
|
|
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
|
|
|
|
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
|
<
<
<
|
|
<
<
<
<
|
|
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
<
<
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
|
|
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
<
<
|
|
|
|
|
|
<
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171















172

173
174
175

176

177
178
179
180


181





182
183
184
185
186
187

188
189
190


191
192


193
194




195
196
197
198
199
200
201
202

203
204

205





206


207




208
209

210
211
212
213
214
215
216
217

218
219
220
221
222

223
224
225
226
227

228
229
230
231
232
233

234

235
236
237
238
239
240






241
242
243
244
245


246




247
248
249



250

251

252
253
254
255
256
257
258

259
260
261



262
263

264

265
266
267
268
269
270
271
272
273
274


275


276
277
278
279
280
281
282
283
284
285









286
287
288
289
290
291
292



293


294
295

296
297


298
299
300
301
302
303
304
305
306
307

308






309
310
311




312

313
314
315
316
317
318
319
320
321
322

323
324

325
326
327


328
329




330


331

332

























333



334
335
336
337
338

339
340
341
342
343
344
345


346
347
348
349

350
351
352


353
354
355
356

357

358
359



360
361


362
363
364
365
























366

367
368
369
370
371

372
373
374
375
376
377
378
379
380

381
382
383
384
385

386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415


416

417
418
419
420
421
422
423
424
425
426


427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450





























451
452
453
454
455


456

457
458
459
460
461
462
463
464
465


466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483


484



485

486
487
488
489
490
491
492
493
494


495

496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515

















516











517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551


552

553
554
555
556
557
558
559
560
561
562
563













564






























565
566
567


568

569


570

571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

595
596

597

598
599
600
601
602
603
604
605
606
607
608
609
610

611

612
613
614
615
616

617

618
619

620

621

622

623

624

625

626

627







628



629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649






650



651
652








653

654
655
















656
657
658
659
660
661

662
663
664
665
666
667
668


669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

























































742
743


744
745






746

































747
748
749
750
751










752
753






754









755
756



757


758









759
760

761
762
763

764








765

















766

767

768
769
770
771

772

773






























774





775







776





777

778






779

780

781





















782
783
784
785





















786
787
788
789
790
791








































792
793
794

795
796

797
798
799
800
801
802
803






804















805
806

807

808
809
810



811






812














813










814








815
816
817






818
819
820
821


822
823
824
825
826
827
828
829


































830












































831












832
833




834
835
836









837
838
839
840
841
842






843
844
845
846










847
848




849
850










851











852
853










854
855






856
857
858











859



860



861
862



863
864




865
866



867

868
































869
870
871

872











873
874
875
876
877



878
879






















880
881











882
883
884
885
886
887
888
889



890







891
892






























893















894
895
896
897
898



899
900
901
902




903
904






























905
906
































































907



908

909
910
911
912
913
914
915
916
917
918
919


920
921
922
923
924
925

926
927
928

929

















































930
931



932
933
934
935
936
937
938
939































































































































































































{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },
{ "Super_R", 0xFFEC },
{ "Hyper_L", 0xFFED },
{ "Hyper_R", 0xFFEE },
{ "space", 0x020 },
{ "exclam", 0x021 },
{ "quotedbl", 0x022 },
{ "numbersign", 0x023 },
{ "dollar", 0x024 },
{ "percent", 0x025 },
{ "ampersand", 0x026 },
{ "quoteright", 0x027 },
{ "parenleft", 0x028 },
{ "parenright", 0x029 },
{ "asterisk", 0x02a },
{ "plus", 0x02b },
{ "comma", 0x02c },
{ "minus", 0x02d },
{ "period", 0x02e },
{ "slash", 0x02f },
{ "0", 0x030 },
{ "1", 0x031 },
{ "2", 0x032 },
{ "3", 0x033 },
{ "4", 0x034 },
{ "5", 0x035 },















{ "6", 0x036 },

{ "7", 0x037 },
{ "8", 0x038 },
{ "9", 0x039 },

{ "colon", 0x03a },

{ "semicolon", 0x03b },
{ "less", 0x03c },
{ "equal", 0x03d },
{ "greater", 0x03e },


{ "question", 0x03f },





{ "at", 0x040 },
{ "A", 0x041 },
{ "B", 0x042 },
{ "C", 0x043 },
{ "D", 0x044 },
{ "E", 0x045 },

{ "F", 0x046 },
{ "G", 0x047 },
{ "H", 0x048 },


{ "I", 0x049 },
{ "J", 0x04a },


{ "K", 0x04b },
{ "L", 0x04c },




{ "M", 0x04d },
{ "N", 0x04e },
{ "O", 0x04f },
{ "P", 0x050 },
{ "Q", 0x051 },
{ "R", 0x052 },
{ "S", 0x053 },
{ "T", 0x054 },

{ "U", 0x055 },
{ "V", 0x056 },

{ "W", 0x057 },





{ "X", 0x058 },


{ "Y", 0x059 },




{ "Z", 0x05a },
{ "bracketleft", 0x05b },

{ "backslash", 0x05c },
{ "bracketright", 0x05d },
{ "asciicircum", 0x05e },
{ "underscore", 0x05f },
{ "quoteleft", 0x060 },
{ "a", 0x061 },
{ "b", 0x062 },
{ "c", 0x063 },

{ "d", 0x064 },
{ "e", 0x065 },
{ "f", 0x066 },
{ "g", 0x067 },
{ "h", 0x068 },

{ "i", 0x069 },
{ "j", 0x06a },
{ "k", 0x06b },
{ "l", 0x06c },
{ "m", 0x06d },

{ "n", 0x06e },
{ "o", 0x06f },
{ "p", 0x070 },
{ "q", 0x071 },
{ "r", 0x072 },
{ "s", 0x073 },

{ "t", 0x074 },

{ "u", 0x075 },
{ "v", 0x076 },
{ "w", 0x077 },
{ "x", 0x078 },
{ "y", 0x079 },
{ "z", 0x07a },






{ "braceleft", 0x07b },
{ "bar", 0x07c },
{ "braceright", 0x07d },
{ "asciitilde", 0x07e },
{ "nobreakspace", 0x0a0 },


{ "exclamdown", 0x0a1 },




{ "cent", 0x0a2 },
{ "sterling", 0x0a3 },
{ "currency", 0x0a4 },



{ "yen", 0x0a5 },

{ "brokenbar", 0x0a6 },

{ "section", 0x0a7 },
{ "diaeresis", 0x0a8 },
{ "copyright", 0x0a9 },
{ "ordfeminine", 0x0aa },
{ "guillemotleft", 0x0ab },
{ "notsign", 0x0ac },
{ "hyphen", 0x0ad },

{ "registered", 0x0ae },
{ "macron", 0x0af },
{ "degree", 0x0b0 },



{ "plusminus", 0x0b1 },
{ "twosuperior", 0x0b2 },

{ "threesuperior", 0x0b3 },

{ "acute", 0x0b4 },
{ "mu", 0x0b5 },
{ "paragraph", 0x0b6 },
{ "periodcentered", 0x0b7 },
{ "cedilla", 0x0b8 },
{ "onesuperior", 0x0b9 },
{ "masculine", 0x0ba },
{ "guillemotright", 0x0bb },
{ "onequarter", 0x0bc },
{ "onehalf", 0x0bd },


{ "threequarters", 0x0be },


{ "questiondown", 0x0bf },
{ "Agrave", 0x0c0 },
{ "Aacute", 0x0c1 },
{ "Acircumflex", 0x0c2 },
{ "Atilde", 0x0c3 },
{ "Adiaeresis", 0x0c4 },
{ "Aring", 0x0c5 },
{ "AE", 0x0c6 },
{ "Ccedilla", 0x0c7 },
{ "Egrave", 0x0c8 },









{ "Eacute", 0x0c9 },
{ "Ecircumflex", 0x0ca },
{ "Ediaeresis", 0x0cb },
{ "Igrave", 0x0cc },
{ "Iacute", 0x0cd },
{ "Icircumflex", 0x0ce },
{ "Idiaeresis", 0x0cf },



{ "Eth", 0x0d0 },


{ "Ntilde", 0x0d1 },
{ "Ograve", 0x0d2 },

{ "Oacute", 0x0d3 },
{ "Ocircumflex", 0x0d4 },


{ "Otilde", 0x0d5 },
{ "Odiaeresis", 0x0d6 },
{ "multiply", 0x0d7 },
{ "Ooblique", 0x0d8 },
{ "Ugrave", 0x0d9 },
{ "Uacute", 0x0da },
{ "Ucircumflex", 0x0db },
{ "Udiaeresis", 0x0dc },
{ "Yacute", 0x0dd },
{ "Thorn", 0x0de },

{ "ssharp", 0x0df },






{ "agrave", 0x0e0 },
{ "aacute", 0x0e1 },
{ "acircumflex", 0x0e2 },




{ "atilde", 0x0e3 },

{ "adiaeresis", 0x0e4 },
{ "aring", 0x0e5 },
{ "ae", 0x0e6 },
{ "ccedilla", 0x0e7 },
{ "egrave", 0x0e8 },
{ "eacute", 0x0e9 },
{ "ecircumflex", 0x0ea },
{ "ediaeresis", 0x0eb },
{ "igrave", 0x0ec },
{ "iacute", 0x0ed },

{ "icircumflex", 0x0ee },
{ "idiaeresis", 0x0ef },

{ "eth", 0x0f0 },
{ "ntilde", 0x0f1 },
{ "ograve", 0x0f2 },


{ "oacute", 0x0f3 },
{ "ocircumflex", 0x0f4 },




{ "otilde", 0x0f5 },


{ "odiaeresis", 0x0f6 },

{ "division", 0x0f7 },

























{ "oslash", 0x0f8 },



{ "ugrave", 0x0f9 },
{ "uacute", 0x0fa },
{ "ucircumflex", 0x0fb },
{ "udiaeresis", 0x0fc },
{ "yacute", 0x0fd },

{ "thorn", 0x0fe },
{ "ydiaeresis", 0x0ff },
{ "Aogonek", 0x1a1 },
{ "breve", 0x1a2 },
{ "Lstroke", 0x1a3 },
{ "Lcaron", 0x1a5 },
{ "Sacute", 0x1a6 },


{ "Scaron", 0x1a9 },
{ "Scedilla", 0x1aa },
{ "Tcaron", 0x1ab },
{ "Zacute", 0x1ac },

{ "Zcaron", 0x1ae },
{ "Zabovedot", 0x1af },
{ "aogonek", 0x1b1 },


{ "ogonek", 0x1b2 },
{ "lstroke", 0x1b3 },
{ "lcaron", 0x1b5 },
{ "sacute", 0x1b6 },

{ "caron", 0x1b7 },

{ "scaron", 0x1b9 },
{ "scedilla", 0x1ba },



{ "tcaron", 0x1bb },
{ "zacute", 0x1bc },


{ "doubleacute", 0x1bd },
{ "zcaron", 0x1be },
{ "zabovedot", 0x1bf },
{ "Racute", 0x1c0 },
























{ "Abreve", 0x1c3 },

{ "Cacute", 0x1c6 },
{ "Ccaron", 0x1c8 },
{ "Eogonek", 0x1ca },
{ "Ecaron", 0x1cc },
{ "Dcaron", 0x1cf },

{ "Nacute", 0x1d1 },
{ "Ncaron", 0x1d2 },
{ "Odoubleacute", 0x1d5 },
{ "Rcaron", 0x1d8 },
{ "Uring", 0x1d9 },
{ "Udoubleacute", 0x1db },
{ "Tcedilla", 0x1de },
{ "racute", 0x1e0 },
{ "abreve", 0x1e3 },

{ "cacute", 0x1e6 },
{ "ccaron", 0x1e8 },
{ "eogonek", 0x1ea },
{ "ecaron", 0x1ec },
{ "dcaron", 0x1ef },

{ "nacute", 0x1f1 },
{ "ncaron", 0x1f2 },
{ "odoubleacute", 0x1f5 },
{ "udoubleacute", 0x1fb },
{ "rcaron", 0x1f8 },
{ "uring", 0x1f9 },

{ "tcedilla", 0x1fe },
{ "abovedot", 0x1ff },
{ "Hstroke", 0x2a1 },
{ "Hcircumflex", 0x2a6 },
{ "Iabovedot", 0x2a9 },
{ "Gbreve", 0x2ab },
{ "Jcircumflex", 0x2ac },
{ "hstroke", 0x2b1 },
{ "hcircumflex", 0x2b6 },
{ "idotless", 0x2b9 },
{ "gbreve", 0x2bb },
{ "jcircumflex", 0x2bc },
{ "Cabovedot", 0x2c5 },
{ "Ccircumflex", 0x2c6 },
{ "Gabovedot", 0x2d5 },
{ "Gcircumflex", 0x2d8 },
{ "Ubreve", 0x2dd },
{ "Scircumflex", 0x2de },
{ "cabovedot", 0x2e5 },
{ "ccircumflex", 0x2e6 },
{ "gabovedot", 0x2f5 },
{ "gcircumflex", 0x2f8 },
{ "ubreve", 0x2fd },
{ "scircumflex", 0x2fe },


{ "kappa", 0x3a2 },

{ "Rcedilla", 0x3a3 },
{ "Itilde", 0x3a5 },
{ "Lcedilla", 0x3a6 },
{ "Emacron", 0x3aa },
{ "Gcedilla", 0x3ab },
{ "Tslash", 0x3ac },
{ "rcedilla", 0x3b3 },
{ "itilde", 0x3b5 },
{ "lcedilla", 0x3b6 },
{ "emacron", 0x3ba },


{ "gacute", 0x3bb },

{ "tslash", 0x3bc },
{ "ENG", 0x3bd },
{ "eng", 0x3bf },
{ "Amacron", 0x3c0 },
{ "Iogonek", 0x3c7 },
{ "Eabovedot", 0x3cc },
{ "Imacron", 0x3cf },
{ "Ncedilla", 0x3d1 },
{ "Omacron", 0x3d2 },
{ "Kcedilla", 0x3d3 },
{ "Uogonek", 0x3d9 },
{ "Utilde", 0x3dd },
{ "Umacron", 0x3de },
{ "amacron", 0x3e0 },
{ "iogonek", 0x3e7 },
{ "eabovedot", 0x3ec },
{ "imacron", 0x3ef },
{ "ncedilla", 0x3f1 },
{ "omacron", 0x3f2 },
{ "kcedilla", 0x3f3 },
{ "uogonek", 0x3f9 },
{ "utilde", 0x3fd },
{ "umacron", 0x3fe },





























{ "overline", 0x47e },
{ "kana_fullstop", 0x4a1 },
{ "kana_openingbracket", 0x4a2 },
{ "kana_closingbracket", 0x4a3 },
{ "kana_comma", 0x4a4 },


{ "kana_middledot", 0x4a5 },

{ "kana_WO", 0x4a6 },
{ "kana_a", 0x4a7 },
{ "kana_i", 0x4a8 },
{ "kana_u", 0x4a9 },
{ "kana_e", 0x4aa },
{ "kana_o", 0x4ab },
{ "kana_ya", 0x4ac },
{ "kana_yu", 0x4ad },
{ "kana_yo", 0x4ae },


{ "kana_tu", 0x4af },

{ "prolongedsound", 0x4b0 },
{ "kana_A", 0x4b1 },
{ "kana_I", 0x4b2 },
{ "kana_U", 0x4b3 },
{ "kana_E", 0x4b4 },
{ "kana_O", 0x4b5 },
{ "kana_KA", 0x4b6 },
{ "kana_KI", 0x4b7 },
{ "kana_KU", 0x4b8 },
{ "kana_KE", 0x4b9 },
{ "kana_KO", 0x4ba },
{ "kana_SA", 0x4bb },
{ "kana_SHI", 0x4bc },
{ "kana_SU", 0x4bd },
{ "kana_SE", 0x4be },
{ "kana_SO", 0x4bf },
{ "kana_TA", 0x4c0 },


{ "kana_TI", 0x4c1 },



{ "kana_TU", 0x4c2 },

{ "kana_TE", 0x4c3 },
{ "kana_TO", 0x4c4 },
{ "kana_NA", 0x4c5 },
{ "kana_NI", 0x4c6 },
{ "kana_NU", 0x4c7 },
{ "kana_NE", 0x4c8 },
{ "kana_NO", 0x4c9 },
{ "kana_HA", 0x4ca },
{ "kana_HI", 0x4cb },


{ "kana_HU", 0x4cc },

{ "kana_HE", 0x4cd },
{ "kana_HO", 0x4ce },
{ "kana_MA", 0x4cf },
{ "kana_MI", 0x4d0 },
{ "kana_MU", 0x4d1 },
{ "kana_ME", 0x4d2 },
{ "kana_MO", 0x4d3 },
{ "kana_YA", 0x4d4 },
{ "kana_YU", 0x4d5 },
{ "kana_YO", 0x4d6 },
{ "kana_RA", 0x4d7 },
{ "kana_RI", 0x4d8 },
{ "kana_RU", 0x4d9 },
{ "kana_RE", 0x4da },
{ "kana_RO", 0x4db },
{ "kana_WA", 0x4dc },
{ "kana_N", 0x4dd },
{ "voicedsound", 0x4de },
{ "semivoicedsound", 0x4df },
{ "kana_switch", 0xFF7E },

















{ "Arabic_comma", 0x5ac },











{ "Arabic_semicolon", 0x5bb },
{ "Arabic_question_mark", 0x5bf },
{ "Arabic_hamza", 0x5c1 },
{ "Arabic_maddaonalef", 0x5c2 },
{ "Arabic_hamzaonalef", 0x5c3 },
{ "Arabic_hamzaonwaw", 0x5c4 },
{ "Arabic_hamzaunderalef", 0x5c5 },
{ "Arabic_hamzaonyeh", 0x5c6 },
{ "Arabic_alef", 0x5c7 },
{ "Arabic_beh", 0x5c8 },
{ "Arabic_tehmarbuta", 0x5c9 },
{ "Arabic_teh", 0x5ca },
{ "Arabic_theh", 0x5cb },
{ "Arabic_jeem", 0x5cc },
{ "Arabic_hah", 0x5cd },
{ "Arabic_khah", 0x5ce },
{ "Arabic_dal", 0x5cf },
{ "Arabic_thal", 0x5d0 },
{ "Arabic_ra", 0x5d1 },
{ "Arabic_zain", 0x5d2 },
{ "Arabic_seen", 0x5d3 },
{ "Arabic_sheen", 0x5d4 },
{ "Arabic_sad", 0x5d5 },
{ "Arabic_dad", 0x5d6 },
{ "Arabic_tah", 0x5d7 },
{ "Arabic_zah", 0x5d8 },
{ "Arabic_ain", 0x5d9 },
{ "Arabic_ghain", 0x5da },
{ "Arabic_tatweel", 0x5e0 },
{ "Arabic_feh", 0x5e1 },
{ "Arabic_qaf", 0x5e2 },
{ "Arabic_kaf", 0x5e3 },
{ "Arabic_lam", 0x5e4 },
{ "Arabic_meem", 0x5e5 },
{ "Arabic_noon", 0x5e6 },


{ "Arabic_heh", 0x5e7 },

{ "Arabic_waw", 0x5e8 },
{ "Arabic_alefmaksura", 0x5e9 },
{ "Arabic_yeh", 0x5ea },
{ "Arabic_fathatan", 0x5eb },
{ "Arabic_dammatan", 0x5ec },
{ "Arabic_kasratan", 0x5ed },
{ "Arabic_fatha", 0x5ee },
{ "Arabic_damma", 0x5ef },
{ "Arabic_kasra", 0x5f0 },
{ "Arabic_shadda", 0x5f1 },
{ "Arabic_sukun", 0x5f2 },













{ "Arabic_switch", 0xFF7E },






























{ "Serbian_dje", 0x6a1 },
{ "Macedonia_gje", 0x6a2 },
{ "Cyrillic_io", 0x6a3 },


{ "Ukranian_je", 0x6a4 },

{ "Macedonia_dse", 0x6a5 },


{ "Ukranian_i", 0x6a6 },

{ "Ukranian_yi", 0x6a7 },
{ "Serbian_je", 0x6a8 },
{ "Serbian_lje", 0x6a9 },
{ "Serbian_nje", 0x6aa },
{ "Serbian_tshe", 0x6ab },
{ "Macedonia_kje", 0x6ac },
{ "Byelorussian_shortu", 0x6ae },
{ "Serbian_dze", 0x6af },
{ "numerosign", 0x6b0 },
{ "Serbian_DJE", 0x6b1 },
{ "Macedonia_GJE", 0x6b2 },
{ "Cyrillic_IO", 0x6b3 },
{ "Ukranian_JE", 0x6b4 },
{ "Macedonia_DSE", 0x6b5 },
{ "Ukranian_I", 0x6b6 },
{ "Ukranian_YI", 0x6b7 },
{ "Serbian_JE", 0x6b8 },
{ "Serbian_LJE", 0x6b9 },
{ "Serbian_NJE", 0x6ba },
{ "Serbian_TSHE", 0x6bb },
{ "Macedonia_KJE", 0x6bc },
{ "Byelorussian_SHORTU", 0x6be },
{ "Serbian_DZE", 0x6bf },
{ "Cyrillic_yu", 0x6c0 },

{ "Cyrillic_a", 0x6c1 },
{ "Cyrillic_be", 0x6c2 },

{ "Cyrillic_tse", 0x6c3 },

{ "Cyrillic_de", 0x6c4 },
{ "Cyrillic_ie", 0x6c5 },
{ "Cyrillic_ef", 0x6c6 },
{ "Cyrillic_ghe", 0x6c7 },
{ "Cyrillic_ha", 0x6c8 },
{ "Cyrillic_i", 0x6c9 },
{ "Cyrillic_shorti", 0x6ca },
{ "Cyrillic_ka", 0x6cb },
{ "Cyrillic_el", 0x6cc },
{ "Cyrillic_em", 0x6cd },
{ "Cyrillic_en", 0x6ce },
{ "Cyrillic_o", 0x6cf },
{ "Cyrillic_pe", 0x6d0 },

{ "Cyrillic_ya", 0x6d1 },

{ "Cyrillic_er", 0x6d2 },
{ "Cyrillic_es", 0x6d3 },
{ "Cyrillic_te", 0x6d4 },
{ "Cyrillic_u", 0x6d5 },
{ "Cyrillic_zhe", 0x6d6 },

{ "Cyrillic_ve", 0x6d7 },

{ "Cyrillic_softsign", 0x6d8 },
{ "Cyrillic_yeru", 0x6d9 },

{ "Cyrillic_ze", 0x6da },

{ "Cyrillic_sha", 0x6db },

{ "Cyrillic_e", 0x6dc },

{ "Cyrillic_shcha", 0x6dd },

{ "Cyrillic_che", 0x6de },

{ "Cyrillic_hardsign", 0x6df },

{ "Cyrillic_YU", 0x6e0 },

{ "Cyrillic_A", 0x6e1 },







{ "Cyrillic_BE", 0x6e2 },



{ "Cyrillic_TSE", 0x6e3 },
{ "Cyrillic_DE", 0x6e4 },
{ "Cyrillic_IE", 0x6e5 },
{ "Cyrillic_EF", 0x6e6 },
{ "Cyrillic_GHE", 0x6e7 },
{ "Cyrillic_HA", 0x6e8 },
{ "Cyrillic_I", 0x6e9 },
{ "Cyrillic_SHORTI", 0x6ea },
{ "Cyrillic_KA", 0x6eb },
{ "Cyrillic_EL", 0x6ec },
{ "Cyrillic_EM", 0x6ed },
{ "Cyrillic_EN", 0x6ee },
{ "Cyrillic_O", 0x6ef },
{ "Cyrillic_PE", 0x6f0 },
{ "Cyrillic_YA", 0x6f1 },
{ "Cyrillic_ER", 0x6f2 },
{ "Cyrillic_ES", 0x6f3 },
{ "Cyrillic_TE", 0x6f4 },
{ "Cyrillic_U", 0x6f5 },
{ "Cyrillic_ZHE", 0x6f6 },

{ "Cyrillic_VE", 0x6f7 },






{ "Cyrillic_SOFTSIGN", 0x6f8 },



{ "Cyrillic_YERU", 0x6f9 },
{ "Cyrillic_ZE", 0x6fa },








{ "Cyrillic_SHA", 0x6fb },

{ "Cyrillic_E", 0x6fc },
{ "Cyrillic_SHCHA", 0x6fd },
















{ "Cyrillic_CHE", 0x6fe },
{ "Cyrillic_HARDSIGN", 0x6ff },
{ "Greek_ALPHAaccent", 0x7a1 },
{ "Greek_EPSILONaccent", 0x7a2 },
{ "Greek_ETAaccent", 0x7a3 },
{ "Greek_IOTAaccent", 0x7a4 },

{ "Greek_IOTAdiaeresis", 0x7a5 },
{ "Greek_IOTAaccentdiaeresis", 0x7a6 },
{ "Greek_OMICRONaccent", 0x7a7 },
{ "Greek_UPSILONaccent", 0x7a8 },
{ "Greek_UPSILONdieresis", 0x7a9 },
{ "Greek_UPSILONaccentdieresis", 0x7aa },
{ "Greek_OMEGAaccent", 0x7ab },


{ "Greek_alphaaccent", 0x7b1 },
{ "Greek_epsilonaccent", 0x7b2 },
{ "Greek_etaaccent", 0x7b3 },
{ "Greek_iotaaccent", 0x7b4 },
{ "Greek_iotadieresis", 0x7b5 },
{ "Greek_iotaaccentdieresis", 0x7b6 },
{ "Greek_omicronaccent", 0x7b7 },
{ "Greek_upsilonaccent", 0x7b8 },
{ "Greek_upsilondieresis", 0x7b9 },
{ "Greek_upsilonaccentdieresis", 0x7ba },
{ "Greek_omegaaccent", 0x7bb },
{ "Greek_ALPHA", 0x7c1 },
{ "Greek_BETA", 0x7c2 },
{ "Greek_GAMMA", 0x7c3 },
{ "Greek_DELTA", 0x7c4 },
{ "Greek_EPSILON", 0x7c5 },
{ "Greek_ZETA", 0x7c6 },
{ "Greek_ETA", 0x7c7 },
{ "Greek_THETA", 0x7c8 },
{ "Greek_IOTA", 0x7c9 },
{ "Greek_KAPPA", 0x7ca },

{ "Greek_LAMBDA", 0x7cb },
{ "Greek_MU", 0x7cc },
{ "Greek_NU", 0x7cd },
{ "Greek_XI", 0x7ce },
{ "Greek_OMICRON", 0x7cf },
{ "Greek_PI", 0x7d0 },
{ "Greek_RHO", 0x7d1 },
{ "Greek_SIGMA", 0x7d2 },
{ "Greek_TAU", 0x7d4 },
{ "Greek_UPSILON", 0x7d5 },
{ "Greek_PHI", 0x7d6 },
{ "Greek_CHI", 0x7d7 },
{ "Greek_PSI", 0x7d8 },
{ "Greek_OMEGA", 0x7d9 },
{ "Greek_alpha", 0x7e1 },
{ "Greek_beta", 0x7e2 },
{ "Greek_gamma", 0x7e3 },
{ "Greek_delta", 0x7e4 },
{ "Greek_epsilon", 0x7e5 },
{ "Greek_zeta", 0x7e6 },
{ "Greek_eta", 0x7e7 },
{ "Greek_theta", 0x7e8 },
{ "Greek_iota", 0x7e9 },
{ "Greek_kappa", 0x7ea },

{ "Greek_lambda", 0x7eb },
{ "Greek_mu", 0x7ec },
{ "Greek_nu", 0x7ed },
{ "Greek_xi", 0x7ee },
{ "Greek_omicron", 0x7ef },
{ "Greek_pi", 0x7f0 },
{ "Greek_rho", 0x7f1 },
{ "Greek_sigma", 0x7f2 },
{ "Greek_finalsmallsigma", 0x7f3 },
{ "Greek_tau", 0x7f4 },
{ "Greek_upsilon", 0x7f5 },
{ "Greek_phi", 0x7f6 },
{ "Greek_chi", 0x7f7 },
{ "Greek_psi", 0x7f8 },
{ "Greek_omega", 0x7f9 },
{ "Greek_switch", 0xFF7E },
{ "leftradical", 0x8a1 },
{ "topleftradical", 0x8a2 },
{ "horizconnector", 0x8a3 },
{ "topintegral", 0x8a4 },
{ "botintegral", 0x8a5 },
{ "vertconnector", 0x8a6 },
{ "topleftsqbracket", 0x8a7 },
{ "botleftsqbracket", 0x8a8 },
{ "toprightsqbracket", 0x8a9 },
{ "botrightsqbracket", 0x8aa },
{ "topleftparens", 0x8ab },
{ "botleftparens", 0x8ac },

























































{ "toprightparens", 0x8ad },
{ "botrightparens", 0x8ae },


{ "leftmiddlecurlybrace", 0x8af },
{ "rightmiddlecurlybrace", 0x8b0 },






{ "topleftsummation", 0x8b1 },

































{ "botleftsummation", 0x8b2 },
{ "topvertsummationconnector", 0x8b3 },
{ "botvertsummationconnector", 0x8b4 },
{ "toprightsummation", 0x8b5 },
{ "botrightsummation", 0x8b6 },










{ "rightmiddlesummation", 0x8b7 },
{ "lessthanequal", 0x8bc },






{ "notequal", 0x8bd },









{ "greaterthanequal", 0x8be },
{ "integral", 0x8bf },



{ "therefore", 0x8c0 },


{ "variation", 0x8c1 },









{ "infinity", 0x8c2 },
{ "nabla", 0x8c5 },

{ "approximate", 0x8c8 },
{ "similarequal", 0x8c9 },
{ "ifonlyif", 0x8cd },

{ "implies", 0x8ce },








{ "identical", 0x8cf },

















{ "radical", 0x8d6 },

{ "includedin", 0x8da },

{ "includes", 0x8db },
{ "intersection", 0x8dc },
{ "union", 0x8dd },
{ "logicaland", 0x8de },

{ "logicalor", 0x8df },

{ "partialderivative", 0x8ef },






























{ "function", 0x8f6 },





{ "leftarrow", 0x8fb },







{ "uparrow", 0x8fc },





{ "rightarrow", 0x8fd },

{ "downarrow", 0x8fe },






{ "blank", 0x9df },

{ "soliddiamond", 0x9e0 },

{ "checkerboard", 0x9e1 },





















{ "ht", 0x9e2 },
{ "ff", 0x9e3 },
{ "cr", 0x9e4 },
{ "lf", 0x9e5 },





















{ "nl", 0x9e8 },
{ "vt", 0x9e9 },
{ "lowrightcorner", 0x9ea },
{ "uprightcorner", 0x9eb },
{ "upleftcorner", 0x9ec },
{ "lowleftcorner", 0x9ed },








































{ "crossinglines", 0x9ee },
{ "horizlinescan1", 0x9ef },
{ "horizlinescan3", 0x9f0 },

{ "horizlinescan5", 0x9f1 },
{ "horizlinescan7", 0x9f2 },

{ "horizlinescan9", 0x9f3 },
{ "leftt", 0x9f4 },
{ "rightt", 0x9f5 },
{ "bott", 0x9f6 },
{ "topt", 0x9f7 },
{ "vertbar", 0x9f8 },
{ "emspace", 0xaa1 },






{ "enspace", 0xaa2 },















{ "em3space", 0xaa3 },
{ "em4space", 0xaa4 },

{ "digitspace", 0xaa5 },

{ "punctspace", 0xaa6 },
{ "thinspace", 0xaa7 },
{ "hairspace", 0xaa8 },



{ "emdash", 0xaa9 },






{ "endash", 0xaaa },














{ "signifblank", 0xaac },










{ "ellipsis", 0xaae },








{ "doubbaselinedot", 0xaaf },
{ "onethird", 0xab0 },
{ "twothirds", 0xab1 },






{ "onefifth", 0xab2 },
{ "twofifths", 0xab3 },
{ "threefifths", 0xab4 },
{ "fourfifths", 0xab5 },


{ "onesixth", 0xab6 },
{ "fivesixths", 0xab7 },
{ "careof", 0xab8 },
{ "figdash", 0xabb },
{ "leftanglebracket", 0xabc },
{ "decimalpoint", 0xabd },
{ "rightanglebracket", 0xabe },
{ "marker", 0xabf },


































{ "oneeighth", 0xac3 },












































{ "threeeighths", 0xac4 },












{ "fiveeighths", 0xac5 },
{ "seveneighths", 0xac6 },




{ "trademark", 0xac9 },
{ "signaturemark", 0xaca },
{ "trademarkincircle", 0xacb },









{ "leftopentriangle", 0xacc },
{ "rightopentriangle", 0xacd },
{ "emopencircle", 0xace },
{ "emopenrectangle", 0xacf },
{ "leftsinglequotemark", 0xad0 },
{ "rightsinglequotemark", 0xad1 },






{ "leftdoublequotemark", 0xad2 },
{ "rightdoublequotemark", 0xad3 },
{ "prescription", 0xad4 },
{ "minutes", 0xad6 },










{ "seconds", 0xad7 },
{ "latincross", 0xad9 },




{ "hexagram", 0xada },
{ "filledrectbullet", 0xadb },










{ "filledlefttribullet", 0xadc },











{ "filledrighttribullet", 0xadd },
{ "emfilledcircle", 0xade },










{ "emfilledrect", 0xadf },
{ "enopencircbullet", 0xae0 },






{ "enopensquarebullet", 0xae1 },
{ "openrectbullet", 0xae2 },
{ "opentribulletup", 0xae3 },











{ "opentribulletdown", 0xae4 },



{ "openstar", 0xae5 },



{ "enfilledcircbullet", 0xae6 },
{ "enfilledsqbullet", 0xae7 },



{ "filledtribulletup", 0xae8 },
{ "filledtribulletdown", 0xae9 },




{ "leftpointer", 0xaea },
{ "rightpointer", 0xaeb },



{ "club", 0xaec },

{ "diamond", 0xaed },
































{ "heart", 0xaee },
{ "maltesecross", 0xaf0 },
{ "dagger", 0xaf1 },

{ "doubledagger", 0xaf2 },











{ "checkmark", 0xaf3 },
{ "ballotcross", 0xaf4 },
{ "musicalsharp", 0xaf5 },
{ "musicalflat", 0xaf6 },
{ "malesymbol", 0xaf7 },



{ "femalesymbol", 0xaf8 },
{ "telephone", 0xaf9 },






















{ "telephonerecorder", 0xafa },
{ "phonographcopyright", 0xafb },











{ "caret", 0xafc },
{ "singlelowquotemark", 0xafd },
{ "doublelowquotemark", 0xafe },
{ "cursor", 0xaff },
{ "leftcaret", 0xba3 },
{ "rightcaret", 0xba6 },
{ "downcaret", 0xba8 },
{ "upcaret", 0xba9 },



{ "overbar", 0xbc0 },







{ "downtack", 0xbc2 },
{ "upshoe", 0xbc3 },






























{ "downstile", 0xbc4 },















{ "underbar", 0xbc6 },
{ "jot", 0xbca },
{ "quad", 0xbcc },
{ "uptack", 0xbce },
{ "circle", 0xbcf },



{ "upstile", 0xbd3 },
{ "downshoe", 0xbd6 },
{ "rightshoe", 0xbd8 },
{ "leftshoe", 0xbda },




{ "lefttack", 0xbdc },
{ "righttack", 0xbfc },






























{ "hebrew_aleph", 0xce0 },
{ "hebrew_beth", 0xce1 },
































































{ "hebrew_gimmel", 0xce2 },



{ "hebrew_daleth", 0xce3 },

{ "hebrew_he", 0xce4 },
{ "hebrew_waw", 0xce5 },
{ "hebrew_zayin", 0xce6 },
{ "hebrew_het", 0xce7 },
{ "hebrew_teth", 0xce8 },
{ "hebrew_yod", 0xce9 },
{ "hebrew_finalkaph", 0xcea },
{ "hebrew_kaph", 0xceb },
{ "hebrew_lamed", 0xcec },
{ "hebrew_finalmem", 0xced },
{ "hebrew_mem", 0xcee },


{ "hebrew_finalnun", 0xcef },
{ "hebrew_nun", 0xcf0 },
{ "hebrew_samekh", 0xcf1 },
{ "hebrew_ayin", 0xcf2 },
{ "hebrew_finalpe", 0xcf3 },
{ "hebrew_pe", 0xcf4 },

{ "hebrew_finalzadi", 0xcf5 },
{ "hebrew_zadi", 0xcf6 },
{ "hebrew_kuf", 0xcf7 },

{ "hebrew_resh", 0xcf8 },

















































{ "hebrew_shin", 0xcf9 },
{ "hebrew_taf", 0xcfa },



{ "Hebrew_switch", 0xFF7E },
{ "XF86AudioLowerVolume", 0x1008FF11 },
{ "XF86AudioMute", 0x1008FF12 },
{ "XF86AudioRaiseVolume", 0x1008FF13 },
{ "XF86AudioPlay", 0x1008FF14 },
{ "XF86AudioStop", 0x1008FF15 },
{ "XF86AudioPrev", 0x1008FF16 },
{ "XF86AudioNext", 0x1008FF17 },































































































































































































Deleted generic/nanosvg.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
/*
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example
 * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/)
 *
 * Arc calculation code based on canvg (https://code.google.com/p/canvg/)
 *
 * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
 *
 */

#ifndef NANOSVG_H
#define NANOSVG_H

#ifdef __cplusplus
extern "C" {
#endif

// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes.
//
// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.
//
// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!
//
// The shapes in the SVG images are transformed by the viewBox and converted to specified units.
// That is, you should get the same looking data as your designed in your favorite app.
//
// NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose
// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.
//
// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
// DPI (dots-per-inch) controls how the unit conversion is done.
//
// If you don't know or care about the units stuff, "px" and 96 should get you going.


/* Example Usage:
	// Load SVG
	NSVGimage* image;
	image = nsvgParseFromFile("test.svg", "px", 96);
	printf("size: %f x %f\n", image->width, image->height);
	// Use...
	for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
		for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
			for (int i = 0; i < path->npts-1; i += 3) {
				float* p = &path->pts[i*2];
				drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
			}
		}
	}
	// Delete
	nsvgDelete(image);
*/

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif

#ifndef NANOSVG_malloc
#define NANOSVG_malloc malloc
#endif

#ifndef NANOSVG_realloc
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

// float emulation for MS VC6++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1200)
#define tanf(a) (float)tan(a)
#define cosf(a) (float)cos(a)
#define sinf(a) (float)sin(a)
#define sqrtf(a) (float)sqrt(a)
#define fabsf(a) (float)fabs(a)
#define acosf(a) (float)acos(a)
#define atan2f(a,b) (float)atan2(a,b)
#define ceilf(a) (float)ceil(a)
#define fmodf(a,b) (float)fmod(a,b)
#define floorf(a) (float)floor(a)
#endif
// float emulation for MS VC8++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1400)
#define fabsf(a) (float)fabs(a)
#endif

enum NSVGpaintType {
	NSVG_PAINT_NONE = 0,
	NSVG_PAINT_COLOR = 1,
	NSVG_PAINT_LINEAR_GRADIENT = 2,
	NSVG_PAINT_RADIAL_GRADIENT = 3
};

enum NSVGspreadType {
	NSVG_SPREAD_PAD = 0,
	NSVG_SPREAD_REFLECT = 1,
	NSVG_SPREAD_REPEAT = 2
};

enum NSVGlineJoin {
	NSVG_JOIN_MITER = 0,
	NSVG_JOIN_ROUND = 1,
	NSVG_JOIN_BEVEL = 2
};

enum NSVGlineCap {
	NSVG_CAP_BUTT = 0,
	NSVG_CAP_ROUND = 1,
	NSVG_CAP_SQUARE = 2
};

enum NSVGfillRule {
	NSVG_FILLRULE_NONZERO = 0,
	NSVG_FILLRULE_EVENODD = 1
};

enum NSVGflags {
	NSVG_FLAGS_VISIBLE = 0x01
};

typedef struct NSVGgradientStop {
	unsigned int color;
	float offset;
} NSVGgradientStop;

typedef struct NSVGgradient {
	float xform[6];
	char spread;
	float fx, fy;
	int nstops;
	NSVGgradientStop stops[1];
} NSVGgradient;

typedef struct NSVGpaint {
	char type;
	union {
		unsigned int color;
		NSVGgradient* gradient;
	};
} NSVGpaint;

typedef struct NSVGpath
{
	float* pts;					// Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
	int npts;					// Total number of bezier points.
	char closed;				// Flag indicating if shapes should be treated as closed.
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].
	struct NSVGpath* next;		// Pointer to next path, or NULL if last element.
} NSVGpath;

typedef struct NSVGshape
{
	char id[64];				// Optional 'id' attr of the shape or its group
	NSVGpaint fill;				// Fill paint
	NSVGpaint stroke;			// Stroke paint
	float opacity;				// Opacity of the shape.
	float strokeWidth;			// Stroke width (scaled).
	float strokeDashOffset;		// Stroke dash offset (scaled).
	float strokeDashArray[8];			// Stroke dash array (scaled).
	char strokeDashCount;				// Number of dash values in dash array.
	char strokeLineJoin;		// Stroke join type.
	char strokeLineCap;			// Stroke cap type.
	float miterLimit;			// Miter limit
	char fillRule;				// Fill rule, see NSVGfillRule.
	unsigned char flags;		// Logical or of NSVG_FLAGS_* flags
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].
	NSVGpath* paths;			// Linked list of paths in the image.
	struct NSVGshape* next;		// Pointer to next shape, or NULL if last element.
} NSVGshape;

typedef struct NSVGimage
{
	float width;				// Width of the image.
	float height;				// Height of the image.
	NSVGshape* shapes;			// Linked list of shapes in the image.
} NSVGimage;

// Parses SVG file from a file, returns SVG image as paths.
NANOSVG_SCOPE NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);

// Parses SVG file from a null terminated string, returns SVG image as paths.
// Important note: changes the string.
NANOSVG_SCOPE NSVGimage* nsvgParse(char* input, const char* units, float dpi);

// Deletes list of paths.
NANOSVG_SCOPE void nsvgDelete(NSVGimage* image);

#ifdef __cplusplus
}
#endif

#endif // NANOSVG_H

#ifdef NANOSVG_IMPLEMENTATION

#include <string.h>
#include <stdlib.h>
#include <math.h>

#define NSVG_PI (3.14159265358979323846264338327f)
#define NSVG_KAPPA90 (0.5522847493f)	// Length proportional to radius of a cubic bezier handle for 90deg arcs.

#define NSVG_ALIGN_MIN 0
#define NSVG_ALIGN_MID 1
#define NSVG_ALIGN_MAX 2
#define NSVG_ALIGN_NONE 0
#define NSVG_ALIGN_MEET 1
#define NSVG_ALIGN_SLICE 2

#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))

#ifdef _MSC_VER
	#pragma warning (disable: 4996) // Switch off security warnings
	#pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
	#ifdef __cplusplus
	#define NSVG_INLINE inline
	#else
	#define NSVG_INLINE
	#endif
	#if !defined(strtoll)           // old MSVC versions do not have strtoll()
		#define strtoll _strtoi64
	#endif
#else
	#define NSVG_INLINE inline
#endif


static int nsvg__isspace(char c)
{
	return strchr(" \t\n\v\f\r", c) != 0;
}

static int nsvg__isdigit(char c)
{
	return c >= '0' && c <= '9';
}

static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }


// Simple XML parser

#define NSVG_XML_TAG 1
#define NSVG_XML_CONTENT 2
#define NSVG_XML_MAX_ATTRIBS 256

static void nsvg__parseContent(char* s,
							   void (*contentCb)(void* ud, const char* s),
							   void* ud)
{
	// Trim start white spaces
	while (*s && nsvg__isspace(*s)) s++;
	if (!*s) return;

	if (contentCb)
		(*contentCb)(ud, s);
}

static void nsvg__parseElement(char* s,
							   void (*startelCb)(void* ud, const char* el, const char** attr),
							   void (*endelCb)(void* ud, const char* el),
							   void* ud)
{
	const char* attr[NSVG_XML_MAX_ATTRIBS];
	int nattr = 0;
	char* cbname;
	int start = 0;
	int end = 0;
	char quote;

	// Skip white space after the '<'
	while (*s && nsvg__isspace(*s)) s++;

	// Check if the tag is end tag
	if (*s == '/') {
		s++;
		end = 1;
	} else {
		start = 1;
	}

	// Skip comments, data and preprocessor stuff.
	if (!*s || *s == '?' || *s == '!')
		return;

	// Get tag name
	cbname = s;
	while (*s && !nsvg__isspace(*s)) s++;
	if (*s) { *s++ = '\0'; }

	// Get attribs
	while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) {
		char* name = NULL;
		char* value = NULL;

		// Skip white space before the attrib name
		while (*s && nsvg__isspace(*s)) s++;
		if (!*s) break;
		if (*s == '/') {
			end = 1;
			break;
		}
		name = s;
		// Find end of the attrib name.
		while (*s && !nsvg__isspace(*s) && *s != '=') s++;
		if (*s) { *s++ = '\0'; }
		// Skip until the beginning of the value.
		while (*s && *s != '\"' && *s != '\'') s++;
		if (!*s) break;
		quote = *s;
		s++;
		// Store value and find the end of it.
		value = s;
		while (*s && *s != quote) s++;
		if (*s) { *s++ = '\0'; }

		// Store only well formed attributes
		if (name && value) {
			attr[nattr++] = name;
			attr[nattr++] = value;
		}
	}

	// List terminator
	attr[nattr++] = 0;
	attr[nattr++] = 0;

	// Call callbacks.
	if (start && startelCb)
		(*startelCb)(ud, cbname, attr);
	if (end && endelCb)
		(*endelCb)(ud, cbname);
}

NANOSVG_SCOPE
int nsvg__parseXML(char* input,
				   void (*startelCb)(void* ud, const char* el, const char** attr),
				   void (*endelCb)(void* ud, const char* el),
				   void (*contentCb)(void* ud, const char* s),
				   void* ud)
{
	char* s = input;
	char* mark = s;
	int state = NSVG_XML_CONTENT;
	while (*s) {
		if (*s == '<' && state == NSVG_XML_CONTENT) {
			// Start of a tag
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			mark = s;
			state = NSVG_XML_TAG;
		} else if (*s == '>' && state == NSVG_XML_TAG) {
			// Start of a content or new tag.
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			nsvg__parseElement(mark, startelCb, endelCb, ud);
			mark = s;
			state = NSVG_XML_CONTENT;
		} else {
			s++;
		}
	}

	return 1;
}


/* Simple SVG parser. */

#define NSVG_MAX_ATTR 128

enum NSVGgradientUnits {
	NSVG_USER_SPACE = 0,
	NSVG_OBJECT_SPACE = 1
};

#define NSVG_MAX_DASHES 8

enum NSVGunits {
	NSVG_UNITS_USER,
	NSVG_UNITS_PX,
	NSVG_UNITS_PT,
	NSVG_UNITS_PC,
	NSVG_UNITS_MM,
	NSVG_UNITS_CM,
	NSVG_UNITS_IN,
	NSVG_UNITS_PERCENT,
	NSVG_UNITS_EM,
	NSVG_UNITS_EX
};

enum NSVGvisible {
	NSVG_VIS_DISPLAY = 1,
	NSVG_VIS_VISIBLE = 2
};

typedef struct NSVGcoordinate {
	float value;
	int units;
} NSVGcoordinate;

typedef struct NSVGlinearData {
	NSVGcoordinate x1, y1, x2, y2;
} NSVGlinearData;

typedef struct NSVGradialData {
	NSVGcoordinate cx, cy, r, fx, fy;
} NSVGradialData;

typedef struct NSVGgradientData
{
	char id[64];
	char ref[64];
	char type;
	union {
		NSVGlinearData linear;
		NSVGradialData radial;
	};
	char spread;
	char units;
	float xform[6];
	int nstops;
	NSVGgradientStop* stops;
	struct NSVGgradientData* next;
} NSVGgradientData;

typedef struct NSVGattrib
{
	char id[64];
	float xform[6];
	unsigned int fillColor;
	unsigned int strokeColor;
	float opacity;
	float fillOpacity;
	float strokeOpacity;
	char fillGradient[64];
	char strokeGradient[64];
	float strokeWidth;
	float strokeDashOffset;
	float strokeDashArray[NSVG_MAX_DASHES];
	int strokeDashCount;
	char strokeLineJoin;
	char strokeLineCap;
	float miterLimit;
	char fillRule;
	float fontSize;
	unsigned int stopColor;
	float stopOpacity;
	float stopOffset;
	char hasFill;
	char hasStroke;
	char visible;
} NSVGattrib;

typedef struct NSVGstyles
{
	char*	name;
	char* description;
	struct NSVGstyles* next;
} NSVGstyles;

typedef struct NSVGparser
{
	NSVGattrib attr[NSVG_MAX_ATTR];
	int attrHead;
	float* pts;
	int npts;
	int cpts;
	NSVGpath* plist;
	NSVGimage* image;
	NSVGstyles* styles;
	NSVGgradientData* gradients;
	NSVGshape* shapesTail;
	float viewMinx, viewMiny, viewWidth, viewHeight;
	int alignX, alignY, alignType;
	float dpi;
	char pathFlag;
	char defsFlag;
	char styleFlag;
} NSVGparser;

static void nsvg__xformIdentity(float* t)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetTranslation(float* t, float tx, float ty)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = tx; t[5] = ty;
}

static void nsvg__xformSetScale(float* t, float sx, float sy)
{
	t[0] = sx; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = sy;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetSkewX(float* t, float a)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = tanf(a); t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetSkewY(float* t, float a)
{
	t[0] = 1.0f; t[1] = tanf(a);
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetRotation(float* t, float a)
{
	float cs = cosf(a), sn = sinf(a);
	t[0] = cs; t[1] = sn;
	t[2] = -sn; t[3] = cs;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformMultiply(float* t, float* s)
{
	float t0 = t[0] * s[0] + t[1] * s[2];
	float t2 = t[2] * s[0] + t[3] * s[2];
	float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
	t[1] = t[0] * s[1] + t[1] * s[3];
	t[3] = t[2] * s[1] + t[3] * s[3];
	t[5] = t[4] * s[1] + t[5] * s[3] + s[5];
	t[0] = t0;
	t[2] = t2;
	t[4] = t4;
}

static void nsvg__xformInverse(float* inv, float* t)
{
	double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
	if (det > -1e-6 && det < 1e-6) {
		nsvg__xformIdentity(t);
		return;
	}
	invdet = 1.0 / det;
	inv[0] = (float)(t[3] * invdet);
	inv[2] = (float)(-t[2] * invdet);
	inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
	inv[1] = (float)(-t[1] * invdet);
	inv[3] = (float)(t[0] * invdet);
	inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
}

static void nsvg__xformPremultiply(float* t, float* s)
{
	float s2[6];
	memcpy(s2, s, sizeof(float)*6);
	nsvg__xformMultiply(s2, t);
	memcpy(t, s2, sizeof(float)*6);
}

static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t)
{
	*dx = x*t[0] + y*t[2] + t[4];
	*dy = x*t[1] + y*t[3] + t[5];
}

static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t)
{
	*dx = x*t[0] + y*t[2];
	*dy = x*t[1] + y*t[3];
}

#define NSVG_EPSILON (1e-12)

static int nsvg__ptInBounds(float* pt, float* bounds)
{
	return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
}


static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3)
{
	double it = 1.0-t;
	return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3;
}

static void nsvg__curveBounds(float* bounds, float* curve)
{
	int i, j, count;
	double roots[2], a, b, c, b2ac, t, v;
	float* v0 = &curve[0];
	float* v1 = &curve[2];
	float* v2 = &curve[4];
	float* v3 = &curve[6];

	// Start the bounding box by end points
	bounds[0] = nsvg__minf(v0[0], v3[0]);
	bounds[1] = nsvg__minf(v0[1], v3[1]);
	bounds[2] = nsvg__maxf(v0[0], v3[0]);
	bounds[3] = nsvg__maxf(v0[1], v3[1]);

	// Bezier curve fits inside the convex hull of it's control points.
	// If control points are inside the bounds, we're done.
	if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
		return;

	// Add bezier curve inflection points in X and Y.
	for (i = 0; i < 2; i++) {
		a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
		b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
		c = 3.0 * v1[i] - 3.0 * v0[i];
		count = 0;
		if (fabs(a) < NSVG_EPSILON) {
			if (fabs(b) > NSVG_EPSILON) {
				t = -c / b;
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
			}
		} else {
			b2ac = b*b - 4.0*c*a;
			if (b2ac > NSVG_EPSILON) {
				t = (-b + sqrt(b2ac)) / (2.0 * a);
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
				t = (-b - sqrt(b2ac)) / (2.0 * a);
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
			}
		}
		for (j = 0; j < count; j++) {
			v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
			bounds[0+i] = nsvg__minf(bounds[0+i], (float)v);
			bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v);
		}
	}
}

static NSVGparser* nsvg__createParser(void)
{
	NSVGparser* p;
	p = (NSVGparser*)NANOSVG_malloc(sizeof(NSVGparser));
	if (p == NULL) goto error;
	memset(p, 0, sizeof(NSVGparser));

	p->image = (NSVGimage*)NANOSVG_malloc(sizeof(NSVGimage));
	if (p->image == NULL) goto error;
	memset(p->image, 0, sizeof(NSVGimage));

	// Init style
	nsvg__xformIdentity(p->attr[0].xform);
	memset(p->attr[0].id, 0, sizeof p->attr[0].id);
	p->attr[0].fillColor = NSVG_RGB(0,0,0);
	p->attr[0].strokeColor = NSVG_RGB(0,0,0);
	p->attr[0].opacity = 1;
	p->attr[0].fillOpacity = 1;
	p->attr[0].strokeOpacity = 1;
	p->attr[0].stopOpacity = 1;
	p->attr[0].strokeWidth = 1;
	p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
	p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
	p->attr[0].miterLimit = 4;
	p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
	p->attr[0].hasFill = 1;
	p->attr[0].visible = NSVG_VIS_DISPLAY | NSVG_VIS_VISIBLE;

	return p;

error:
	if (p) {
		if (p->image) NANOSVG_free(p->image);
		NANOSVG_free(p);
	}
	return NULL;
}

static void nsvg__deleteStyles(NSVGstyles* style) {
	while (style) {
		NSVGstyles *next = style->next;
		if (style->name!= NULL)
			NANOSVG_free(style->name);
		if (style->description != NULL)
			NANOSVG_free(style->description);
		NANOSVG_free(style);
		style = next;
	}
}

static void nsvg__deletePaths(NSVGpath* path)
{
	while (path) {
		NSVGpath *next = path->next;
		if (path->pts != NULL)
			NANOSVG_free(path->pts);
		NANOSVG_free(path);
		path = next;
	}
}

static void nsvg__deletePaint(NSVGpaint* paint)
{
	if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
		NANOSVG_free(paint->gradient);
}

static void nsvg__deleteGradientData(NSVGgradientData* grad)
{
	NSVGgradientData* next;
	while (grad != NULL) {
		next = grad->next;
		NANOSVG_free(grad->stops);
		NANOSVG_free(grad);
		grad = next;
	}
}

static void nsvg__deleteParser(NSVGparser* p)
{
	if (p != NULL) {
		nsvg__deleteStyles(p->styles);
		nsvg__deletePaths(p->plist);
		nsvg__deleteGradientData(p->gradients);
		nsvgDelete(p->image);
		NANOSVG_free(p->pts);
		NANOSVG_free(p);
	}
}

static void nsvg__resetPath(NSVGparser* p)
{
	p->npts = 0;
}

static void nsvg__addPoint(NSVGparser* p, float x, float y)
{
	if (p->npts+1 > p->cpts) {
		p->cpts = p->cpts ? p->cpts*2 : 8;
		p->pts = (float*)NANOSVG_realloc(p->pts, p->cpts*2*sizeof(float));
		if (!p->pts) return;
	}
	p->pts[p->npts*2+0] = x;
	p->pts[p->npts*2+1] = y;
	p->npts++;
}

static void nsvg__moveTo(NSVGparser* p, float x, float y)
{
	if (p->npts > 0) {
		p->pts[(p->npts-1)*2+0] = x;
		p->pts[(p->npts-1)*2+1] = y;
	} else {
		nsvg__addPoint(p, x, y);
	}
}

static void nsvg__lineTo(NSVGparser* p, float x, float y)
{
	float px,py, dx,dy;
	if (p->npts > 0) {
		px = p->pts[(p->npts-1)*2+0];
		py = p->pts[(p->npts-1)*2+1];
		dx = x - px;
		dy = y - py;
		nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
		nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f);
		nsvg__addPoint(p, x, y);
	}
}

static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
{
	if (p->npts > 0) {
		nsvg__addPoint(p, cpx1, cpy1);
		nsvg__addPoint(p, cpx2, cpy2);
		nsvg__addPoint(p, x, y);
	}
}

static NSVGattrib* nsvg__getAttr(NSVGparser* p)
{
	return &p->attr[p->attrHead];
}

static void nsvg__pushAttr(NSVGparser* p)
{
	if (p->attrHead < NSVG_MAX_ATTR-1) {
		p->attrHead++;
		memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib));
	}
}

static void nsvg__popAttr(NSVGparser* p)
{
	if (p->attrHead > 0)
		p->attrHead--;
}

static float nsvg__actualOrigX(NSVGparser* p)
{
	return p->viewMinx;
}

static float nsvg__actualOrigY(NSVGparser* p)
{
	return p->viewMiny;
}

static float nsvg__actualWidth(NSVGparser* p)
{
	return p->viewWidth;
}

static float nsvg__actualHeight(NSVGparser* p)
{
	return p->viewHeight;
}

static float nsvg__actualLength(NSVGparser* p)
{
	float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
	return sqrtf(w*w + h*h) / sqrtf(2.0f);
}

static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	switch (c.units) {
		case NSVG_UNITS_USER:		return c.value;
		case NSVG_UNITS_PX:			return c.value;
		case NSVG_UNITS_PT:			return c.value / 72.0f * p->dpi;
		case NSVG_UNITS_PC:			return c.value / 6.0f * p->dpi;
		case NSVG_UNITS_MM:			return c.value / 25.4f * p->dpi;
		case NSVG_UNITS_CM:			return c.value / 2.54f * p->dpi;
		case NSVG_UNITS_IN:			return c.value * p->dpi;
		case NSVG_UNITS_EM:			return c.value * attr->fontSize;
		case NSVG_UNITS_EX:			return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
		case NSVG_UNITS_PERCENT:	return orig + c.value / 100.0f * length;
		default:					return c.value;
	}
	return c.value;
}

static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
	NSVGgradientData* grad = p->gradients;
	if (id == NULL || *id == '\0')
		return NULL;
	while (grad != NULL) {
		if (strcmp(grad->id, id) == 0)
			return grad;
		grad = grad->next;
	}
	return NULL;
}

static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	NSVGgradientData* data = NULL;
	NSVGgradientData* ref = NULL;
	NSVGgradientStop* stops = NULL;
	NSVGgradient* grad;
	float ox, oy, sw, sh, sl;
	int nstops = 0;
	int refIter;

	data = nsvg__findGradientData(p, id);
	if (data == NULL) return NULL;

	// TODO: use ref to fill in all unset values too.
	ref = data;
	refIter = 0;
	while (ref != NULL) {
		NSVGgradientData* nextRef = NULL;
		if (stops == NULL && ref->stops != NULL) {
			stops = ref->stops;
			nstops = ref->nstops;
			break;
		}
		nextRef = nsvg__findGradientData(p, ref->ref);
		if (nextRef == ref) break; // prevent infite loops on malformed data
		ref = nextRef;
		refIter++;
		if (refIter > 32) break; // prevent infite loops on malformed data
	}
	if (stops == NULL) return NULL;

	grad = (NSVGgradient*)NANOSVG_malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
	if (grad == NULL) return NULL;

	// The shape width and height.
	if (data->units == NSVG_OBJECT_SPACE) {
		ox = localBounds[0];
		oy = localBounds[1];
		sw = localBounds[2] - localBounds[0];
		sh = localBounds[3] - localBounds[1];
	} else {
		ox = nsvg__actualOrigX(p);
		oy = nsvg__actualOrigY(p);
		sw = nsvg__actualWidth(p);
		sh = nsvg__actualHeight(p);
	}
	sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);

	if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
		float x1, y1, x2, y2, dx, dy;
		x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
		y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
		x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
		y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
		// Calculate transform aligned to the line
		dx = x2 - x1;
		dy = y2 - y1;
		grad->xform[0] = dy; grad->xform[1] = -dx;
		grad->xform[2] = dx; grad->xform[3] = dy;
		grad->xform[4] = x1; grad->xform[5] = y1;
	} else {
		float cx, cy, fx, fy, r;
		cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
		cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
		fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
		fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
		r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
		// Calculate transform aligned to the circle
		grad->xform[0] = r; grad->xform[1] = 0;
		grad->xform[2] = 0; grad->xform[3] = r;
		grad->xform[4] = cx; grad->xform[5] = cy;
		grad->fx = fx / r;
		grad->fy = fy / r;
	}

	nsvg__xformMultiply(grad->xform, data->xform);
	nsvg__xformMultiply(grad->xform, attr->xform);

	grad->spread = data->spread;
	memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
	grad->nstops = nstops;

	*paintType = data->type;

	return grad;
}

static float nsvg__getAverageScale(float* t)
{
	float sx = sqrtf(t[0]*t[0] + t[2]*t[2]);
	float sy = sqrtf(t[1]*t[1] + t[3]*t[3]);
	return (sx + sy) * 0.5f;
}

static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform)
{
	NSVGpath* path;
	float curve[4*2], curveBounds[4];
	int i, first = 1;
	for (path = shape->paths; path != NULL; path = path->next) {
		nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
		for (i = 0; i < path->npts-1; i += 3) {
			nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform);
			nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform);
			nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform);
			nsvg__curveBounds(curveBounds, curve);
			if (first) {
				bounds[0] = curveBounds[0];
				bounds[1] = curveBounds[1];
				bounds[2] = curveBounds[2];
				bounds[3] = curveBounds[3];
				first = 0;
			} else {
				bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
				bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
				bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
				bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
			}
			curve[0] = curve[6];
			curve[1] = curve[7];
		}
	}
}

static void nsvg__addShape(NSVGparser* p)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	float scale = 1.0f;
	NSVGshape* shape;
	NSVGpath* path;
	int i;

	if (p->plist == NULL)
		return;

	shape = (NSVGshape*)NANOSVG_malloc(sizeof(NSVGshape));
	if (shape == NULL) goto error;
	memset(shape, 0, sizeof(NSVGshape));

	memcpy(shape->id, attr->id, sizeof shape->id);
	scale = nsvg__getAverageScale(attr->xform);
	shape->strokeWidth = attr->strokeWidth * scale;
	shape->strokeDashOffset = attr->strokeDashOffset * scale;
	shape->strokeDashCount = (char)attr->strokeDashCount;
	for (i = 0; i < attr->strokeDashCount; i++)
		shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
	shape->strokeLineJoin = attr->strokeLineJoin;
	shape->strokeLineCap = attr->strokeLineCap;
	shape->miterLimit = attr->miterLimit;
	shape->fillRule = attr->fillRule;
	shape->opacity = attr->opacity;

	shape->paths = p->plist;
	p->plist = NULL;

	// Calculate shape bounds
	shape->bounds[0] = shape->paths->bounds[0];
	shape->bounds[1] = shape->paths->bounds[1];
	shape->bounds[2] = shape->paths->bounds[2];
	shape->bounds[3] = shape->paths->bounds[3];
	for (path = shape->paths->next; path != NULL; path = path->next) {
		shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
		shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
		shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
		shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
	}

	// Set fill
	if (attr->hasFill == 0) {
		shape->fill.type = NSVG_PAINT_NONE;
	} else if (attr->hasFill == 1) {
		shape->fill.type = NSVG_PAINT_COLOR;
		shape->fill.color = attr->fillColor;
		shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
	} else if (attr->hasFill == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
		if (shape->fill.gradient == NULL) {
			shape->fill.type = NSVG_PAINT_NONE;
		}
	}

	// Set stroke
	if (attr->hasStroke == 0) {
		shape->stroke.type = NSVG_PAINT_NONE;
	} else if (attr->hasStroke == 1) {
		shape->stroke.type = NSVG_PAINT_COLOR;
		shape->stroke.color = attr->strokeColor;
		shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24;
	} else if (attr->hasStroke == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
		if (shape->stroke.gradient == NULL)
			shape->stroke.type = NSVG_PAINT_NONE;
	}

	// Set flags
	shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);

	// Add to tail
	if (p->image->shapes == NULL)
		p->image->shapes = shape;
	else
		p->shapesTail->next = shape;
	p->shapesTail = shape;

	return;

error:
	if (shape) NANOSVG_free(shape);
}

static void nsvg__addPath(NSVGparser* p, char closed)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	NSVGpath* path = NULL;
	float bounds[4];
	float* curve;
	int i;

	if (p->npts < 4)
		return;

	if (closed)
		nsvg__lineTo(p, p->pts[0], p->pts[1]);

	// Expect 1 + N*3 points (N = number of cubic bezier segments).
	if ((p->npts % 3) != 1)
		return;

	path = (NSVGpath*)NANOSVG_malloc(sizeof(NSVGpath));
	if (path == NULL) goto error;
	memset(path, 0, sizeof(NSVGpath));

	path->pts = (float*)NANOSVG_malloc(p->npts*2*sizeof(float));
	if (path->pts == NULL) goto error;
	path->closed = closed;
	path->npts = p->npts;

	// Transform path.
	for (i = 0; i < p->npts; ++i)
		nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);

	// Find bounds
	for (i = 0; i < path->npts-1; i += 3) {
		curve = &path->pts[i*2];
		nsvg__curveBounds(bounds, curve);
		if (i == 0) {
			path->bounds[0] = bounds[0];
			path->bounds[1] = bounds[1];
			path->bounds[2] = bounds[2];
			path->bounds[3] = bounds[3];
		} else {
			path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
			path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
			path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
			path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
		}
	}

	path->next = p->plist;
	p->plist = path;

	return;

error:
	if (path != NULL) {
		if (path->pts != NULL) NANOSVG_free(path->pts);
		NANOSVG_free(path);
	}
}

// We roll our own string to float because the std library one uses locale and messes things up.
static double nsvg__atof(const char* s)
{
	char* cur = (char*)s;
	char* end = NULL;
	double res = 0.0, sign = 1.0;
#if defined(_MSC_VER) && (_MSC_VER == 1200)
	__int64 intPart = 0, fracPart = 0;
#else
	long long intPart = 0, fracPart = 0;
#endif
	char hasIntPart = 0, hasFracPart = 0;

	// Parse optional sign
	if (*cur == '+') {
		cur++;
	} else if (*cur == '-') {
		sign = -1;
		cur++;
	}

	// Parse integer part
	if (nsvg__isdigit(*cur)) {
		// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
		intPart = strtol(cur, &end, 10);
#else
		intPart = strtoll(cur, &end, 10);
#endif
		if (cur != end) {
			res = (double)intPart;
			hasIntPart = 1;
			cur = end;
		}
	}

	// Parse fractional part.
	if (*cur == '.') {
		cur++; // Skip '.'
		if (nsvg__isdigit(*cur)) {
			// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
			fracPart = strtol(cur, &end, 10);
#else
			fracPart = strtoll(cur, &end, 10);
#endif
			if (cur != end) {
				res += (double)fracPart / pow(10.0, (double)(end - cur));
				hasFracPart = 1;
				cur = end;
			}
		}
	}

	// A valid number should have integer or fractional part.
	if (!hasIntPart && !hasFracPart)
		return 0.0;

	// Parse optional exponent
	if (*cur == 'e' || *cur == 'E') {
		int expPart = 0;
		cur++; // skip 'E'
		expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
		if (cur != end) {
			res *= pow(10.0, (double)expPart);
		}
	}

	return res * sign;
}


static const char* nsvg__parseNumber(const char* s, char* it, const int size)
{
	const int last = size-1;
	int i = 0;

	// sign
	if (*s == '-' || *s == '+') {
		if (i < last) it[i++] = *s;
		s++;
	}
	// integer part
	while (*s && nsvg__isdigit(*s)) {
		if (i < last) it[i++] = *s;
		s++;
	}
	if (*s == '.') {
		// decimal point
		if (i < last) it[i++] = *s;
		s++;
		// fraction part
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	// exponent
	if (*s == 'e' || *s == 'E') {
		if (i < last) it[i++] = *s;
		s++;
		if (*s == '-' || *s == '+') {
			if (i < last) it[i++] = *s;
			s++;
		}
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	it[i] = '\0';

	return s;
}

static const char* nsvg__getNextPathItem(const char* s, char* it)
{
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	if (!*s) return s;
	if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
		s = nsvg__parseNumber(s, it, 64);
	} else {
		// Parse command
		it[0] = *s++;
		it[1] = '\0';
		return s;
	}

	return s;
}

static unsigned int nsvg__parseColorHex(const char* str)
{
	unsigned int c = 0, r = 0, g = 0, b = 0;
	int n = 0;
	str++; // skip #
	// Calculate number of characters.
	while(str[n] && !nsvg__isspace(str[n]))
		n++;
	if (n == 6) {
		sscanf(str, "%x", &c);
	} else if (n == 3) {
		sscanf(str, "%x", &c);
		c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
		c |= c<<4;
	}
	r = (c >> 16) & 0xff;
	g = (c >> 8) & 0xff;
	b = c & 0xff;
	return NSVG_RGB(r,g,b);
}

static unsigned int nsvg__parseColorRGB(const char* str)
{
	int r = -1, g = -1, b = -1;
	char s1[32]="", s2[32]="";
	sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
	if (strchr(s1, '%')) {
		return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);
	} else {
		return NSVG_RGB(r,g,b);
	}
}

typedef struct NSVGNamedColor {
	const char* name;
	unsigned int color;
} NSVGNamedColor;

NSVGNamedColor nsvg__colors[] = {

	{ "red", NSVG_RGB(255, 0, 0) },
	{ "green", NSVG_RGB( 0, 128, 0) },
	{ "blue", NSVG_RGB( 0, 0, 255) },
	{ "yellow", NSVG_RGB(255, 255, 0) },
	{ "cyan", NSVG_RGB( 0, 255, 255) },
	{ "magenta", NSVG_RGB(255, 0, 255) },
	{ "black", NSVG_RGB( 0, 0, 0) },
	{ "grey", NSVG_RGB(128, 128, 128) },
	{ "gray", NSVG_RGB(128, 128, 128) },
	{ "white", NSVG_RGB(255, 255, 255) },

#ifdef NANOSVG_ALL_COLOR_KEYWORDS
	{ "aliceblue", NSVG_RGB(240, 248, 255) },
	{ "antiquewhite", NSVG_RGB(250, 235, 215) },
	{ "aqua", NSVG_RGB( 0, 255, 255) },
	{ "aquamarine", NSVG_RGB(127, 255, 212) },
	{ "azure", NSVG_RGB(240, 255, 255) },
	{ "beige", NSVG_RGB(245, 245, 220) },
	{ "bisque", NSVG_RGB(255, 228, 196) },
	{ "blanchedalmond", NSVG_RGB(255, 235, 205) },
	{ "blueviolet", NSVG_RGB(138, 43, 226) },
	{ "brown", NSVG_RGB(165, 42, 42) },
	{ "burlywood", NSVG_RGB(222, 184, 135) },
	{ "cadetblue", NSVG_RGB( 95, 158, 160) },
	{ "chartreuse", NSVG_RGB(127, 255, 0) },
	{ "chocolate", NSVG_RGB(210, 105, 30) },
	{ "coral", NSVG_RGB(255, 127, 80) },
	{ "cornflowerblue", NSVG_RGB(100, 149, 237) },
	{ "cornsilk", NSVG_RGB(255, 248, 220) },
	{ "crimson", NSVG_RGB(220, 20, 60) },
	{ "darkblue", NSVG_RGB( 0, 0, 139) },
	{ "darkcyan", NSVG_RGB( 0, 139, 139) },
	{ "darkgoldenrod", NSVG_RGB(184, 134, 11) },
	{ "darkgray", NSVG_RGB(169, 169, 169) },
	{ "darkgreen", NSVG_RGB( 0, 100, 0) },
	{ "darkgrey", NSVG_RGB(169, 169, 169) },
	{ "darkkhaki", NSVG_RGB(189, 183, 107) },
	{ "darkmagenta", NSVG_RGB(139, 0, 139) },
	{ "darkolivegreen", NSVG_RGB( 85, 107, 47) },
	{ "darkorange", NSVG_RGB(255, 140, 0) },
	{ "darkorchid", NSVG_RGB(153, 50, 204) },
	{ "darkred", NSVG_RGB(139, 0, 0) },
	{ "darksalmon", NSVG_RGB(233, 150, 122) },
	{ "darkseagreen", NSVG_RGB(143, 188, 143) },
	{ "darkslateblue", NSVG_RGB( 72, 61, 139) },
	{ "darkslategray", NSVG_RGB( 47, 79, 79) },
	{ "darkslategrey", NSVG_RGB( 47, 79, 79) },
	{ "darkturquoise", NSVG_RGB( 0, 206, 209) },
	{ "darkviolet", NSVG_RGB(148, 0, 211) },
	{ "deeppink", NSVG_RGB(255, 20, 147) },
	{ "deepskyblue", NSVG_RGB( 0, 191, 255) },
	{ "dimgray", NSVG_RGB(105, 105, 105) },
	{ "dimgrey", NSVG_RGB(105, 105, 105) },
	{ "dodgerblue", NSVG_RGB( 30, 144, 255) },
	{ "firebrick", NSVG_RGB(178, 34, 34) },
	{ "floralwhite", NSVG_RGB(255, 250, 240) },
	{ "forestgreen", NSVG_RGB( 34, 139, 34) },
	{ "fuchsia", NSVG_RGB(255, 0, 255) },
	{ "gainsboro", NSVG_RGB(220, 220, 220) },
	{ "ghostwhite", NSVG_RGB(248, 248, 255) },
	{ "gold", NSVG_RGB(255, 215, 0) },
	{ "goldenrod", NSVG_RGB(218, 165, 32) },
	{ "greenyellow", NSVG_RGB(173, 255, 47) },
	{ "honeydew", NSVG_RGB(240, 255, 240) },
	{ "hotpink", NSVG_RGB(255, 105, 180) },
	{ "indianred", NSVG_RGB(205, 92, 92) },
	{ "indigo", NSVG_RGB( 75, 0, 130) },
	{ "ivory", NSVG_RGB(255, 255, 240) },
	{ "khaki", NSVG_RGB(240, 230, 140) },
	{ "lavender", NSVG_RGB(230, 230, 250) },
	{ "lavenderblush", NSVG_RGB(255, 240, 245) },
	{ "lawngreen", NSVG_RGB(124, 252, 0) },
	{ "lemonchiffon", NSVG_RGB(255, 250, 205) },
	{ "lightblue", NSVG_RGB(173, 216, 230) },
	{ "lightcoral", NSVG_RGB(240, 128, 128) },
	{ "lightcyan", NSVG_RGB(224, 255, 255) },
	{ "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) },
	{ "lightgray", NSVG_RGB(211, 211, 211) },
	{ "lightgreen", NSVG_RGB(144, 238, 144) },
	{ "lightgrey", NSVG_RGB(211, 211, 211) },
	{ "lightpink", NSVG_RGB(255, 182, 193) },
	{ "lightsalmon", NSVG_RGB(255, 160, 122) },
	{ "lightseagreen", NSVG_RGB( 32, 178, 170) },
	{ "lightskyblue", NSVG_RGB(135, 206, 250) },
	{ "lightslategray", NSVG_RGB(119, 136, 153) },
	{ "lightslategrey", NSVG_RGB(119, 136, 153) },
	{ "lightsteelblue", NSVG_RGB(176, 196, 222) },
	{ "lightyellow", NSVG_RGB(255, 255, 224) },
	{ "lime", NSVG_RGB( 0, 255, 0) },
	{ "limegreen", NSVG_RGB( 50, 205, 50) },
	{ "linen", NSVG_RGB(250, 240, 230) },
	{ "maroon", NSVG_RGB(128, 0, 0) },
	{ "mediumaquamarine", NSVG_RGB(102, 205, 170) },
	{ "mediumblue", NSVG_RGB( 0, 0, 205) },
	{ "mediumorchid", NSVG_RGB(186, 85, 211) },
	{ "mediumpurple", NSVG_RGB(147, 112, 219) },
	{ "mediumseagreen", NSVG_RGB( 60, 179, 113) },
	{ "mediumslateblue", NSVG_RGB(123, 104, 238) },
	{ "mediumspringgreen", NSVG_RGB( 0, 250, 154) },
	{ "mediumturquoise", NSVG_RGB( 72, 209, 204) },
	{ "mediumvioletred", NSVG_RGB(199, 21, 133) },
	{ "midnightblue", NSVG_RGB( 25, 25, 112) },
	{ "mintcream", NSVG_RGB(245, 255, 250) },
	{ "mistyrose", NSVG_RGB(255, 228, 225) },
	{ "moccasin", NSVG_RGB(255, 228, 181) },
	{ "navajowhite", NSVG_RGB(255, 222, 173) },
	{ "navy", NSVG_RGB( 0, 0, 128) },
	{ "oldlace", NSVG_RGB(253, 245, 230) },
	{ "olive", NSVG_RGB(128, 128, 0) },
	{ "olivedrab", NSVG_RGB(107, 142, 35) },
	{ "orange", NSVG_RGB(255, 165, 0) },
	{ "orangered", NSVG_RGB(255, 69, 0) },
	{ "orchid", NSVG_RGB(218, 112, 214) },
	{ "palegoldenrod", NSVG_RGB(238, 232, 170) },
	{ "palegreen", NSVG_RGB(152, 251, 152) },
	{ "paleturquoise", NSVG_RGB(175, 238, 238) },
	{ "palevioletred", NSVG_RGB(219, 112, 147) },
	{ "papayawhip", NSVG_RGB(255, 239, 213) },
	{ "peachpuff", NSVG_RGB(255, 218, 185) },
	{ "peru", NSVG_RGB(205, 133, 63) },
	{ "pink", NSVG_RGB(255, 192, 203) },
	{ "plum", NSVG_RGB(221, 160, 221) },
	{ "powderblue", NSVG_RGB(176, 224, 230) },
	{ "purple", NSVG_RGB(128, 0, 128) },
	{ "rosybrown", NSVG_RGB(188, 143, 143) },
	{ "royalblue", NSVG_RGB( 65, 105, 225) },
	{ "saddlebrown", NSVG_RGB(139, 69, 19) },
	{ "salmon", NSVG_RGB(250, 128, 114) },
	{ "sandybrown", NSVG_RGB(244, 164, 96) },
	{ "seagreen", NSVG_RGB( 46, 139, 87) },
	{ "seashell", NSVG_RGB(255, 245, 238) },
	{ "sienna", NSVG_RGB(160, 82, 45) },
	{ "silver", NSVG_RGB(192, 192, 192) },
	{ "skyblue", NSVG_RGB(135, 206, 235) },
	{ "slateblue", NSVG_RGB(106, 90, 205) },
	{ "slategray", NSVG_RGB(112, 128, 144) },
	{ "slategrey", NSVG_RGB(112, 128, 144) },
	{ "snow", NSVG_RGB(255, 250, 250) },
	{ "springgreen", NSVG_RGB( 0, 255, 127) },
	{ "steelblue", NSVG_RGB( 70, 130, 180) },
	{ "tan", NSVG_RGB(210, 180, 140) },
	{ "teal", NSVG_RGB( 0, 128, 128) },
	{ "thistle", NSVG_RGB(216, 191, 216) },
	{ "tomato", NSVG_RGB(255, 99, 71) },
	{ "turquoise", NSVG_RGB( 64, 224, 208) },
	{ "violet", NSVG_RGB(238, 130, 238) },
	{ "wheat", NSVG_RGB(245, 222, 179) },
	{ "whitesmoke", NSVG_RGB(245, 245, 245) },
	{ "yellowgreen", NSVG_RGB(154, 205, 50) },
#endif
};

static unsigned int nsvg__parseColorName(const char* str)
{
	int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);

	for (i = 0; i < ncolors; i++) {
		if (strcmp(nsvg__colors[i].name, str) == 0) {
			return nsvg__colors[i].color;
		}
	}

	return NSVG_RGB(128, 128, 128);
}

static unsigned int nsvg__parseColor(const char* str)
{
	size_t len = 0;
	while(*str == ' ') ++str;
	len = strlen(str);
	if (len >= 1 && *str == '#')
		return nsvg__parseColorHex(str);
	else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
		return nsvg__parseColorRGB(str);
	return nsvg__parseColorName(str);
}

static float nsvg__parseOpacity(const char* str)
{
	float val = 0;
	sscanf(str, "%f", &val);
	if (val < 0.0f) val = 0.0f;
	if (val > 1.0f) val = 1.0f;
	return val;
}

static float nsvg__parseMiterLimit(const char* str)
{
	float val = 0;
	sscanf(str, "%f", &val);
	if (val < 0.0f) val = 0.0f;
	return val;
}

static int nsvg__parseUnits(const char* units)
{
	if (units[0] == 'p' && units[1] == 'x')
		return NSVG_UNITS_PX;
	else if (units[0] == 'p' && units[1] == 't')
		return NSVG_UNITS_PT;
	else if (units[0] == 'p' && units[1] == 'c')
		return NSVG_UNITS_PC;
	else if (units[0] == 'm' && units[1] == 'm')
		return NSVG_UNITS_MM;
	else if (units[0] == 'c' && units[1] == 'm')
		return NSVG_UNITS_CM;
	else if (units[0] == 'i' && units[1] == 'n')
		return NSVG_UNITS_IN;
	else if (units[0] == '%')
		return NSVG_UNITS_PERCENT;
	else if (units[0] == 'e' && units[1] == 'm')
		return NSVG_UNITS_EM;
	else if (units[0] == 'e' && units[1] == 'x')
		return NSVG_UNITS_EX;
	return NSVG_UNITS_USER;
}

static int nsvg__isCoordinate(const char* s)
{
	// optional sign
	if (*s == '-' || *s == '+')
		s++;
	// must have at least one digit
	return nsvg__isdigit(*s);
}

static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
{
	NSVGcoordinate coord = {0, NSVG_UNITS_USER};
	char units[32]="";
	sscanf(str, "%f%s", &coord.value, units);
	coord.units = nsvg__parseUnits(units);
	return coord;
}

static NSVGcoordinate nsvg__coord(float v, int units)
{
	NSVGcoordinate coord = {v, units};
	return coord;
}

static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length)
{
	NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
	return nsvg__convertToPixels(p, coord, orig, length);
}

static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na)
{
	const char* end;
	const char* ptr;
	char it[64];

	*na = 0;
	ptr = str;
	while (*ptr && *ptr != '(') ++ptr;
	if (*ptr == 0)
		return 1;
	end = ptr;
	while (*end && *end != ')') ++end;
	if (*end == 0)
		return 1;

	while (ptr < end) {
		if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
			if (*na >= maxNa) return 0;
			ptr = nsvg__parseNumber(ptr, it, 64);
			args[(*na)++] = (float)nsvg__atof(it);
		} else {
			++ptr;
		}
	}
	return (int)(end - str);
}


static int nsvg__parseMatrix(float* xform, const char* str)
{
	float t[6];
	int na = 0;
	int len = nsvg__parseTransformArgs(str, t, 6, &na);
	if (na != 6) return len;
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseTranslate(float* xform, const char* str)
{
	float args[2];
	float t[6];
	int na = 0;
	int len = nsvg__parseTransformArgs(str, args, 2, &na);
	if (na == 1) args[1] = 0.0;

	nsvg__xformSetTranslation(t, args[0], args[1]);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseScale(float* xform, const char* str)
{
	float args[2];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 2, &na);
	if (na == 1) args[1] = args[0];
	nsvg__xformSetScale(t, args[0], args[1]);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseSkewX(float* xform, const char* str)
{
	float args[1];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 1, &na);
	nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseSkewY(float* xform, const char* str)
{
	float args[1];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 1, &na);
	nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseRotate(float* xform, const char* str)
{
	float args[3];
	int na = 0;
	float m[6];
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 3, &na);
	if (na == 1)
		args[1] = args[2] = 0.0f;
	nsvg__xformIdentity(m);

	if (na > 1) {
		nsvg__xformSetTranslation(t, -args[1], -args[2]);
		nsvg__xformMultiply(m, t);
	}

	nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI);
	nsvg__xformMultiply(m, t);

	if (na > 1) {
		nsvg__xformSetTranslation(t, args[1], args[2]);
		nsvg__xformMultiply(m, t);
	}

	memcpy(xform, m, sizeof(float)*6);

	return len;
}

static void nsvg__parseTransform(float* xform, const char* str)
{
	float t[6];
        int len;
	nsvg__xformIdentity(xform);
	while (*str)
	{
		if (strncmp(str, "matrix", 6) == 0)
			len = nsvg__parseMatrix(t, str);
		else if (strncmp(str, "translate", 9) == 0)
			len = nsvg__parseTranslate(t, str);
		else if (strncmp(str, "scale", 5) == 0)
			len = nsvg__parseScale(t, str);
		else if (strncmp(str, "rotate", 6) == 0)
			len = nsvg__parseRotate(t, str);
		else if (strncmp(str, "skewX", 5) == 0)
			len = nsvg__parseSkewX(t, str);
		else if (strncmp(str, "skewY", 5) == 0)
			len = nsvg__parseSkewY(t, str);
		else{
			++str;
			continue;
		}
                if (len != 0) {
			str += len;
                } else {
			++str;
			continue;
                }

		nsvg__xformPremultiply(xform, t);
	}
}

static void nsvg__parseUrl(char* id, const char* str)
{
	int i = 0;
	str += 4; // "url(";
	if (*str == '#')
		str++;
	while (i < 63 && *str != ')') {
		id[i] = *str++;
		i++;
	}
	id[i] = '\0';
}

static char nsvg__parseLineCap(const char* str)
{
	if (strcmp(str, "butt") == 0)
		return NSVG_CAP_BUTT;
	else if (strcmp(str, "round") == 0)
		return NSVG_CAP_ROUND;
	else if (strcmp(str, "square") == 0)
		return NSVG_CAP_SQUARE;
	// TODO: handle inherit.
	return NSVG_CAP_BUTT;
}

static char nsvg__parseLineJoin(const char* str)
{
	if (strcmp(str, "miter") == 0)
		return NSVG_JOIN_MITER;
	else if (strcmp(str, "round") == 0)
		return NSVG_JOIN_ROUND;
	else if (strcmp(str, "bevel") == 0)
		return NSVG_JOIN_BEVEL;
	// TODO: handle inherit.
	return NSVG_JOIN_MITER;
}

static char nsvg__parseFillRule(const char* str)
{
	if (strcmp(str, "nonzero") == 0)
		return NSVG_FILLRULE_NONZERO;
	else if (strcmp(str, "evenodd") == 0)
		return NSVG_FILLRULE_EVENODD;
	// TODO: handle inherit.
	return NSVG_FILLRULE_NONZERO;
}

static const char* nsvg__getNextDashItem(const char* s, char* it)
{
	int n = 0;
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	// Advance until whitespace, comma or end.
	while (*s && (!nsvg__isspace(*s) && *s != ',')) {
		if (n < 63)
			it[n++] = *s;
		s++;
	}
	it[n++] = '\0';
	return s;
}

static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
{
	char item[64];
	int count = 0, i;
	float sum = 0.0f;

	// Handle "none"
	if (str[0] == 'n')
		return 0;

	// Parse dashes
	while (*str) {
		str = nsvg__getNextDashItem(str, item);
		if (!*item) break;
		if (count < NSVG_MAX_DASHES)
			strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
	}

	for (i = 0; i < count; i++)
		sum += strokeDashArray[i];
	if (sum <= 1e-6f)
		count = 0;

	return count;
}

static void nsvg__parseStyle(NSVGparser* p, const char* str);

static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
{
	float xform[6];
	NSVGattrib* attr = nsvg__getAttr(p);
	if (!attr) return 0;

	if (strcmp(name, "style") == 0) {
		nsvg__parseStyle(p, value);
	} else if (strcmp(name, "display") == 0) {
		if (strcmp(value, "none") == 0)
			attr->visible &= ~NSVG_VIS_DISPLAY;
		// Don't reset ->visible on display:inline, one display:none hides the whole subtree

	} else if (strcmp(name, "visibility") == 0) {
		if (strcmp(value, "hidden") == 0) {
			attr->visible &= ~NSVG_VIS_VISIBLE;
		} else if (strcmp(value, "visible") == 0) {
			attr->visible |= NSVG_VIS_VISIBLE;
		}
	} else if (strcmp(name, "fill") == 0) {
		if (strcmp(value, "none") == 0) {
			attr->hasFill = 0;
		} else if (strncmp(value, "url(", 4) == 0) {
			attr->hasFill = 2;
			nsvg__parseUrl(attr->fillGradient, value);
		} else {
			attr->hasFill = 1;
			attr->fillColor = nsvg__parseColor(value);
		}
	} else if (strcmp(name, "opacity") == 0) {
		attr->opacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "fill-opacity") == 0) {
		attr->fillOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "stroke") == 0) {
		if (strcmp(value, "none") == 0) {
			attr->hasStroke = 0;
		} else if (strncmp(value, "url(", 4) == 0) {
			attr->hasStroke = 2;
			nsvg__parseUrl(attr->strokeGradient, value);
		} else {
			attr->hasStroke = 1;
			attr->strokeColor = nsvg__parseColor(value);
		}
	} else if (strcmp(name, "stroke-width") == 0) {
		attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "stroke-dasharray") == 0) {
		attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
	} else if (strcmp(name, "stroke-dashoffset") == 0) {
		attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "stroke-opacity") == 0) {
		attr->strokeOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "stroke-linecap") == 0) {
		attr->strokeLineCap = nsvg__parseLineCap(value);
	} else if (strcmp(name, "stroke-linejoin") == 0) {
		attr->strokeLineJoin = nsvg__parseLineJoin(value);
	} else if (strcmp(name, "stroke-miterlimit") == 0) {
		attr->miterLimit = nsvg__parseMiterLimit(value);
	} else if (strcmp(name, "fill-rule") == 0) {
		attr->fillRule = nsvg__parseFillRule(value);
	} else if (strcmp(name, "font-size") == 0) {
		attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "transform") == 0) {
		nsvg__parseTransform(xform, value);
		nsvg__xformPremultiply(attr->xform, xform);
	} else if (strcmp(name, "stop-color") == 0) {
		attr->stopColor = nsvg__parseColor(value);
	} else if (strcmp(name, "stop-opacity") == 0) {
		attr->stopOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "offset") == 0) {
		attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
	} else if (strcmp(name, "id") == 0) {
		strncpy(attr->id, value, 63);
		attr->id[63] = '\0';
	} else if (strcmp(name, "class") == 0) {
		NSVGstyles* style = p->styles;
		while (style) {
			if (strcmp(style->name + 1, value) == 0) {
				break;
			}
			style = style->next;
		}
		if (style) {
			nsvg__parseStyle(p, style->description);
		}
	} else {
		return 0;
	}
	return 1;
}

static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end)
{
	const char* str;
	const char* val;
	char name[512];
	char value[512];
	int n;

	str = start;
	while (str < end && *str != ':') ++str;

	val = str;

	// Right Trim
	while (str > start &&  (*str == ':' || nsvg__isspace(*str))) --str;
	++str;

	n = (int)(str - start);
	if (n > 511) n = 511;
	if (n) memcpy(name, start, n);
	name[n] = 0;

	while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val;

	n = (int)(end - val);
	if (n > 511) n = 511;
	if (n) memcpy(value, val, n);
	value[n] = 0;

	return nsvg__parseAttr(p, name, value);
}

static void nsvg__parseStyle(NSVGparser* p, const char* str)
{
	const char* start;
	const char* end;

	while (*str) {
		// Left Trim
		while(*str && nsvg__isspace(*str)) ++str;
		start = str;
		while(*str && *str != ';') ++str;
		end = str;

		// Right Trim
		while (end > start &&  (*end == ';' || nsvg__isspace(*end))) --end;
		++end;

		nsvg__parseNameValue(p, start, end);
		if (*str) ++str;
	}
}

static void nsvg__parseAttribs(NSVGparser* p, const char** attr)
{
	int i;
	for (i = 0; attr[i]; i += 2)
	{
		if (strcmp(attr[i], "style") == 0)
			nsvg__parseStyle(p, attr[i + 1]);
		else
			nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}
}

static int nsvg__getArgsPerElement(char cmd)
{
	switch (cmd) {
		case 'v':
		case 'V':
		case 'h':
		case 'H':
			return 1;
		case 'm':
		case 'M':
		case 'l':
		case 'L':
		case 't':
		case 'T':
			return 2;
		case 'q':
		case 'Q':
		case 's':
		case 'S':
			return 4;
		case 'c':
		case 'C':
			return 6;
		case 'a':
		case 'A':
			return 7;
		case 'z':
		case 'Z':
			return 0;
	}
	return -1;
}

static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel) {
		*cpx += args[0];
		*cpy += args[1];
	} else {
		*cpx = args[0];
		*cpy = args[1];
	}
	nsvg__moveTo(p, *cpx, *cpy);
}

static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel) {
		*cpx += args[0];
		*cpy += args[1];
	} else {
		*cpx = args[0];
		*cpy = args[1];
	}
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel)
		*cpx += args[0];
	else
		*cpx = args[0];
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel)
		*cpy += args[0];
	else
		*cpy = args[0];
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy,
								 float* cpx2, float* cpy2, float* args, int rel)
{
	float x2, y2, cx1, cy1, cx2, cy2;

	if (rel) {
		cx1 = *cpx + args[0];
		cy1 = *cpy + args[1];
		cx2 = *cpx + args[2];
		cy2 = *cpy + args[3];
		x2 = *cpx + args[4];
		y2 = *cpy + args[5];
	} else {
		cx1 = args[0];
		cy1 = args[1];
		cx2 = args[2];
		cy2 = args[3];
		x2 = args[4];
		y2 = args[5];
	}

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx2;
	*cpy2 = cy2;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy,
									  float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		cx2 = *cpx + args[0];
		cy2 = *cpy + args[1];
		x2 = *cpx + args[2];
		y2 = *cpy + args[3];
	} else {
		cx2 = args[0];
		cy2 = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	cx1 = 2*x1 - *cpx2;
	cy1 = 2*y1 - *cpy2;

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx2;
	*cpy2 = cy2;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy,
								float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx, cy;
	float cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		cx = *cpx + args[0];
		cy = *cpy + args[1];
		x2 = *cpx + args[2];
		y2 = *cpy + args[3];
	} else {
		cx = args[0];
		cy = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	// Convert to cubic bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx;
	*cpy2 = cy;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy,
									 float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx, cy;
	float cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		x2 = *cpx + args[0];
		y2 = *cpy + args[1];
	} else {
		x2 = args[0];
		y2 = args[1];
	}

	cx = 2*x1 - *cpx2;
	cy = 2*y1 - *cpy2;

	// Convert to cubix bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx;
	*cpy2 = cy;
	*cpx = x2;
	*cpy = y2;
}

static float nsvg__sqr(float x) { return x*x; }
static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); }

static float nsvg__vecrat(float ux, float uy, float vx, float vy)
{
	return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy));
}

static float nsvg__vecang(float ux, float uy, float vx, float vy)
{
	float r = nsvg__vecrat(ux,uy, vx,vy);
	if (r < -1.0f) r = -1.0f;
	if (r > 1.0f) r = 1.0f;
	return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
}

static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	// Ported from canvg (https://code.google.com/p/canvg/)
	float rx, ry, rotx;
	float x1, y1, x2, y2, cx, cy, dx, dy, d;
	float x1p, y1p, cxp, cyp, s, sa, sb;
	float ux, uy, vx, vy, a1, da;
	float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
	float sinrx, cosrx;
	int fa, fs;
	int i, ndivs;
	float hda, kappa;

	rx = fabsf(args[0]);				// y radius
	ry = fabsf(args[1]);				// x radius
	rotx = args[2] / 180.0f * NSVG_PI;		// x rotation angle
	fa = fabsf(args[3]) > 1e-6 ? 1 : 0;	// Large arc
	fs = fabsf(args[4]) > 1e-6 ? 1 : 0;	// Sweep direction
	x1 = *cpx;							// start point
	y1 = *cpy;
	if (rel) {							// end point
		x2 = *cpx + args[5];
		y2 = *cpy + args[6];
	} else {
		x2 = args[5];
		y2 = args[6];
	}

	dx = x1 - x2;
	dy = y1 - y2;
	d = sqrtf(dx*dx + dy*dy);
	if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
		// The arc degenerates to a line
		nsvg__lineTo(p, x2, y2);
		*cpx = x2;
		*cpy = y2;
		return;
	}

	sinrx = sinf(rotx);
	cosrx = cosf(rotx);

	// Convert to center point parameterization.
	// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
	// 1) Compute x1', y1'
	x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
	y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
	d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
	if (d > 1) {
		d = sqrtf(d);
		rx *= d;
		ry *= d;
	}
	// 2) Compute cx', cy'
	s = 0.0f;
	sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
	sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
	if (sa < 0.0f) sa = 0.0f;
	if (sb > 0.0f)
		s = sqrtf(sa / sb);
	if (fa == fs)
		s = -s;
	cxp = s * rx * y1p / ry;
	cyp = s * -ry * x1p / rx;

	// 3) Compute cx,cy from cx',cy'
	cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
	cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;

	// 4) Calculate theta1, and delta theta.
	ux = (x1p - cxp) / rx;
	uy = (y1p - cyp) / ry;
	vx = (-x1p - cxp) / rx;
	vy = (-y1p - cyp) / ry;
	a1 = nsvg__vecang(1.0f,0.0f, ux,uy);	// Initial angle
	da = nsvg__vecang(ux,uy, vx,vy);		// Delta angle

//	if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
//	if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;

	if (fs == 0 && da > 0)
		da -= 2 * NSVG_PI;
	else if (fs == 1 && da < 0)
		da += 2 * NSVG_PI;

	// Approximate the arc using cubic spline segments.
	t[0] = cosrx; t[1] = sinrx;
	t[2] = -sinrx; t[3] = cosrx;
	t[4] = cx; t[5] = cy;

	// Split arc into max 90 degree segments.
	// The loop assumes an iteration per end point (including start and end), this +1.
	ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
	hda = (da / (float)ndivs) / 2.0f;
	kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
	if (da < 0.0f)
		kappa = -kappa;

	for (i = 0; i <= ndivs; i++) {
		a = a1 + da * ((float)i/(float)ndivs);
		dx = cosf(a);
		dy = sinf(a);
		nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position
		nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent
		if (i > 0)
			nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
		px = x;
		py = y;
		ptanx = tanx;
		ptany = tany;
	}

	*cpx = x2;
	*cpy = y2;
}

static void nsvg__parsePath(NSVGparser* p, const char** attr)
{
	const char* s = NULL;
	char cmd = '\0';
	float args[10];
	int nargs;
	int rargs = 0;
	char initPoint;
	float cpx, cpy, cpx2, cpy2;
	const char* tmp[4];
	char closedFlag;
	int i;
	char item[64];

	for (i = 0; attr[i]; i += 2) {
		if (strcmp(attr[i], "d") == 0) {
			s = attr[i + 1];
		} else {
			tmp[0] = attr[i];
			tmp[1] = attr[i + 1];
			tmp[2] = 0;
			tmp[3] = 0;
			nsvg__parseAttribs(p, tmp);
		}
	}

	if (s) {
		nsvg__resetPath(p);
		cpx = 0; cpy = 0;
		cpx2 = 0; cpy2 = 0;
		initPoint = 0;
		closedFlag = 0;
		nargs = 0;

		while (*s) {
			s = nsvg__getNextPathItem(s, item);
			if (!*item) break;
			if (cmd != '\0' && nsvg__isCoordinate(item)) {
				if (nargs < 10)
					args[nargs++] = (float)nsvg__atof(item);
				if (nargs >= rargs) {
					switch (cmd) {
						case 'm':
						case 'M':
							nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
							// Moveto can be followed by multiple coordinate pairs,
							// which should be treated as linetos.
							cmd = (cmd == 'm') ? 'l' : 'L';
							rargs = nsvg__getArgsPerElement(cmd);
							cpx2 = cpx; cpy2 = cpy;
							initPoint = 1;
							break;
						case 'l':
						case 'L':
							nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'H':
						case 'h':
							nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'V':
						case 'v':
							nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'C':
						case 'c':
							nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
							break;
						case 'S':
						case 's':
							nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
							break;
						case 'Q':
						case 'q':
							nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
							break;
						case 'T':
						case 't':
							nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
							break;
						case 'A':
						case 'a':
							nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						default:
							if (nargs >= 2) {
								cpx = args[nargs-2];
								cpy = args[nargs-1];
								cpx2 = cpx; cpy2 = cpy;
							}
							break;
					}
					nargs = 0;
				}
			} else {
				cmd = item[0];
				if (cmd == 'M' || cmd == 'm') {
					// Commit path.
					if (p->npts > 0)
						nsvg__addPath(p, closedFlag);
					// Start new subpath.
					nsvg__resetPath(p);
					closedFlag = 0;
					nargs = 0;
				} else if (initPoint == 0) {
					// Do not allow other commands until initial point has been set (moveTo called once).
					cmd = '\0';
				}
				if (cmd == 'Z' || cmd == 'z') {
					closedFlag = 1;
					// Commit path.
					if (p->npts > 0) {
						// Move current point to first point
						cpx = p->pts[0];
						cpy = p->pts[1];
						cpx2 = cpx; cpy2 = cpy;
						nsvg__addPath(p, closedFlag);
					}
					// Start new subpath.
					nsvg__resetPath(p);
					nsvg__moveTo(p, cpx, cpy);
					closedFlag = 0;
					nargs = 0;
				}
				rargs = nsvg__getArgsPerElement(cmd);
				if (rargs == -1) {
					// Command not recognized
					cmd = '\0';
					rargs = 0;
				}
			}
		}
		// Commit path.
		if (p->npts)
			nsvg__addPath(p, closedFlag);
	}

	nsvg__addShape(p);
}

static void nsvg__parseRect(NSVGparser* p, const char** attr)
{
	float x = 0.0f;
	float y = 0.0f;
	float w = 0.0f;
	float h = 0.0f;
	float rx = -1.0f; // marks not set
	float ry = -1.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p));
			if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p));
			if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
			if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
		}
	}

	if (rx < 0.0f && ry > 0.0f) rx = ry;
	if (ry < 0.0f && rx > 0.0f) ry = rx;
	if (rx < 0.0f) rx = 0.0f;
	if (ry < 0.0f) ry = 0.0f;
	if (rx > w/2.0f) rx = w/2.0f;
	if (ry > h/2.0f) ry = h/2.0f;

	if (w != 0.0f && h != 0.0f) {
		nsvg__resetPath(p);

		if (rx < 0.00001f || ry < 0.0001f) {
			nsvg__moveTo(p, x, y);
			nsvg__lineTo(p, x+w, y);
			nsvg__lineTo(p, x+w, y+h);
			nsvg__lineTo(p, x, y+h);
		} else {
			// Rounded rectangle
			nsvg__moveTo(p, x+rx, y);
			nsvg__lineTo(p, x+w-rx, y);
			nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
			nsvg__lineTo(p, x+w, y+h-ry);
			nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
			nsvg__lineTo(p, x+rx, y+h);
			nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);
			nsvg__lineTo(p, x, y+ry);
			nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y);
		}

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseCircle(NSVGparser* p, const char** attr)
{
	float cx = 0.0f;
	float cy = 0.0f;
	float r = 0.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p)));
		}
	}

	if (r > 0.0f) {
		nsvg__resetPath(p);

		nsvg__moveTo(p, cx+r, cy);
		nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r);
		nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy);
		nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r);
		nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy);

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseEllipse(NSVGparser* p, const char** attr)
{
	float cx = 0.0f;
	float cy = 0.0f;
	float rx = 0.0f;
	float ry = 0.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
			if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
		}
	}

	if (rx > 0.0f && ry > 0.0f) {

		nsvg__resetPath(p);

		nsvg__moveTo(p, cx+rx, cy);
		nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry);
		nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy);
		nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry);
		nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy);

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseLine(NSVGparser* p, const char** attr)
{
	float x1 = 0.0;
	float y1 = 0.0;
	float x2 = 0.0;
	float y2 = 0.0;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
		}
	}

	nsvg__resetPath(p);

	nsvg__moveTo(p, x1, y1);
	nsvg__lineTo(p, x2, y2);

	nsvg__addPath(p, 0);

	nsvg__addShape(p);
}

static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag)
{
	int i;
	const char* s;
	float args[2];
	int nargs, npts = 0;
	char item[64];

	nsvg__resetPath(p);

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "points") == 0) {
				s = attr[i + 1];
				nargs = 0;
				while (*s) {
					s = nsvg__getNextPathItem(s, item);
					args[nargs++] = (float)nsvg__atof(item);
					if (nargs >= 2) {
						if (npts == 0)
							nsvg__moveTo(p, args[0], args[1]);
						else
							nsvg__lineTo(p, args[0], args[1]);
						nargs = 0;
						npts++;
					}
				}
			}
		}
	}

	nsvg__addPath(p, (char)closeFlag);

	nsvg__addShape(p);
}

static void nsvg__parseSVG(NSVGparser* p, const char** attr)
{
	int i;
	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "width") == 0) {
				p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "height") == 0) {
				p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "viewBox") == 0) {
				sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
			} else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
				if (strstr(attr[i + 1], "none") != 0) {
					// No uniform scaling
					p->alignType = NSVG_ALIGN_NONE;
				} else {
					// Parse X align
					if (strstr(attr[i + 1], "xMin") != 0)
						p->alignX = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "xMid") != 0)
						p->alignX = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "xMax") != 0)
						p->alignX = NSVG_ALIGN_MAX;
					// Parse X align
					if (strstr(attr[i + 1], "yMin") != 0)
						p->alignY = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "yMid") != 0)
						p->alignY = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "yMax") != 0)
						p->alignY = NSVG_ALIGN_MAX;
					// Parse meet/slice
					p->alignType = NSVG_ALIGN_MEET;
					if (strstr(attr[i + 1], "slice") != 0)
						p->alignType = NSVG_ALIGN_SLICE;
				}
			}
		}
	}
}

static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
{
	int i;
	NSVGgradientData* grad = (NSVGgradientData*)NANOSVG_malloc(sizeof(NSVGgradientData));
	if (grad == NULL) return;
	memset(grad, 0, sizeof(NSVGgradientData));
	grad->units = NSVG_OBJECT_SPACE;
	grad->type = type;
	if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
		grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
		grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
		grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
		grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
	} else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
		grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
		grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
		grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
	}

	nsvg__xformIdentity(grad->xform);

	for (i = 0; attr[i]; i += 2) {
		if (strcmp(attr[i], "id") == 0) {
			strncpy(grad->id, attr[i+1], 63);
			grad->id[63] = '\0';
		} else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "gradientUnits") == 0) {
				if (strcmp(attr[i+1], "objectBoundingBox") == 0)
					grad->units = NSVG_OBJECT_SPACE;
				else
					grad->units = NSVG_USER_SPACE;
			} else if (strcmp(attr[i], "gradientTransform") == 0) {
				nsvg__parseTransform(grad->xform, attr[i + 1]);
			} else if (strcmp(attr[i], "cx") == 0) {
				grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "cy") == 0) {
				grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "r") == 0) {
				grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "fx") == 0) {
				grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "fy") == 0) {
				grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "x1") == 0) {
				grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "y1") == 0) {
				grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "x2") == 0) {
				grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "y2") == 0) {
				grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "spreadMethod") == 0) {
				if (strcmp(attr[i+1], "pad") == 0)
					grad->spread = NSVG_SPREAD_PAD;
				else if (strcmp(attr[i+1], "reflect") == 0)
					grad->spread = NSVG_SPREAD_REFLECT;
				else if (strcmp(attr[i+1], "repeat") == 0)
					grad->spread = NSVG_SPREAD_REPEAT;
			} else if (strcmp(attr[i], "xlink:href") == 0) {
				const char *href = attr[i+1];
				strncpy(grad->ref, href+1, 62);
				grad->ref[62] = '\0';
			}
		}
	}

	grad->next = p->gradients;
	p->gradients = grad;
}

static void nsvg__parseGradientStop(NSVGparser* p, const char** attr)
{
	NSVGattrib* curAttr = nsvg__getAttr(p);
	NSVGgradientData* grad;
	NSVGgradientStop* stop;
	int i, idx;

	curAttr->stopOffset = 0;
	curAttr->stopColor = 0;
	curAttr->stopOpacity = 1.0f;

	for (i = 0; attr[i]; i += 2) {
		nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}

	// Add stop to the last gradient.
	grad = p->gradients;
	if (grad == NULL) return;

	grad->nstops++;
	grad->stops = (NSVGgradientStop*)NANOSVG_realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
	if (grad->stops == NULL) return;

	// Insert
	idx = grad->nstops-1;
	for (i = 0; i < grad->nstops-1; i++) {
		if (curAttr->stopOffset < grad->stops[i].offset) {
			idx = i;
			break;
		}
	}
	if (idx != grad->nstops-1) {
		for (i = grad->nstops-1; i > idx; i--)
			grad->stops[i] = grad->stops[i-1];
	}

	stop = &grad->stops[idx];
	stop->color = curAttr->stopColor;
	stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24;
	stop->offset = curAttr->stopOffset;
}

static void nsvg__startElement(void* ud, const char* el, const char** attr)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (p->defsFlag) {
		// Skip everything but gradients in defs
		if (strcmp(el, "linearGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
		} else if (strcmp(el, "radialGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
		} else if (strcmp(el, "stop") == 0) {
			nsvg__parseGradientStop(p, attr);
		}
		return;
	}

	if (strcmp(el, "g") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseAttribs(p, attr);
	} else if (strcmp(el, "path") == 0) {
		if (p->pathFlag)	// Do not allow nested paths.
			return;
		nsvg__pushAttr(p);
		nsvg__parsePath(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "rect") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseRect(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "circle") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseCircle(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "ellipse") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseEllipse(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "line") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parseLine(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "polyline") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parsePoly(p, attr, 0);
		nsvg__popAttr(p);
	} else if (strcmp(el, "polygon") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parsePoly(p, attr, 1);
		nsvg__popAttr(p);
	} else  if (strcmp(el, "linearGradient") == 0) {
		nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
	} else if (strcmp(el, "radialGradient") == 0) {
		nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
	} else if (strcmp(el, "stop") == 0) {
		nsvg__parseGradientStop(p, attr);
	} else if (strcmp(el, "defs") == 0) {
		p->defsFlag = 1;
	} else if (strcmp(el, "svg") == 0) {
		nsvg__parseSVG(p, attr);
	} else if (strcmp(el, "style") == 0) {
		p->styleFlag = 1;
	}
}

static void nsvg__endElement(void* ud, const char* el)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (strcmp(el, "g") == 0) {
		nsvg__popAttr(p);
	} else if (strcmp(el, "path") == 0) {
		p->pathFlag = 0;
	} else if (strcmp(el, "defs") == 0) {
		p->defsFlag = 0;
	} else if (strcmp(el, "style") == 0) {
		p->styleFlag = 0;
	}
}

static char *nsvg__strndup(const char *s, size_t n)
{
	char *result;
	size_t len = strlen(s);

	if (n < len)
		len = n;

	result = (char*)NANOSVG_malloc(len+1);
	if (!result)
		return 0;

	result[len] = '\0';
	return (char *)memcpy(result, s, len);
}

static void nsvg__content(void* ud, const char* s)
{
	NSVGparser* p = (NSVGparser*)ud;
	if (p->styleFlag) {

		int state = 0;
		const char* start = NULL;
		while (*s) {
			char c = *s;
			if (nsvg__isspace(c) || c == '{') {
				if (state == 1) {
					NSVGstyles* next = p->styles;

					p->styles = (NSVGstyles*)NANOSVG_malloc(sizeof(NSVGstyles));
					p->styles->next = next;
					p->styles->name = nsvg__strndup(start, (size_t)(s - start));
					start = s + 1;
					state = 2;
				}
			} else if (state == 2 && c == '}') {
				p->styles->description = nsvg__strndup(start, (size_t)(s - start));
				state = 0;
			}
			else if (state == 0) {
				start = s;
				state = 1;
			}
			s++;
		/*
			if (*s == '{' && state == NSVG_XML_CONTENT) {
				// Start of a tag
				*s++ = '\0';
				nsvg__parseContent(mark, contentCb, ud);
				mark = s;
				state = NSVG_XML_TAG;
			}
			else if (*s == '>' && state == NSVG_XML_TAG) {
				// Start of a content or new tag.
				*s++ = '\0';
				nsvg__parseElement(mark, startelCb, endelCb, ud);
				mark = s;
				state = NSVG_XML_CONTENT;
			}
			else {
				s++;
			}
		*/
		}

	}
}

static void nsvg__imageBounds(NSVGparser* p, float* bounds)
{
	NSVGshape* shape;
	shape = p->image->shapes;
	if (shape == NULL) {
		bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
		return;
	}
	bounds[0] = shape->bounds[0];
	bounds[1] = shape->bounds[1];
	bounds[2] = shape->bounds[2];
	bounds[3] = shape->bounds[3];
	for (shape = shape->next; shape != NULL; shape = shape->next) {
		bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
		bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
		bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
		bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
	}
}

static float nsvg__viewAlign(float content, float container, int type)
{
	if (type == NSVG_ALIGN_MIN)
		return 0;
	else if (type == NSVG_ALIGN_MAX)
		return container - content;
	// mid
	return (container - content) * 0.5f;
}

static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
{
	float t[6];
	nsvg__xformSetTranslation(t, tx, ty);
	nsvg__xformMultiply (grad->xform, t);

	nsvg__xformSetScale(t, sx, sy);
	nsvg__xformMultiply (grad->xform, t);
}

static void nsvg__scaleToViewbox(NSVGparser* p, const char* units)
{
	NSVGshape* shape;
	NSVGpath* path;
	float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
	int i;
	float* pt;

	// Guess image size if not set completely.
	nsvg__imageBounds(p, bounds);

	if (p->viewWidth == 0) {
		if (p->image->width > 0) {
			p->viewWidth = p->image->width;
		} else {
			p->viewMinx = bounds[0];
			p->viewWidth = bounds[2] - bounds[0];
		}
	}
	if (p->viewHeight == 0) {
		if (p->image->height > 0) {
			p->viewHeight = p->image->height;
		} else {
			p->viewMiny = bounds[1];
			p->viewHeight = bounds[3] - bounds[1];
		}
	}
	if (p->image->width == 0)
		p->image->width = p->viewWidth;
	if (p->image->height == 0)
		p->image->height = p->viewHeight;

	tx = -p->viewMinx;
	ty = -p->viewMiny;
	sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
	sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
	// Unit scaling
	us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);

	// Fix aspect ratio
	if (p->alignType == NSVG_ALIGN_MEET) {
		// fit whole image into viewbox
		sx = sy = nsvg__minf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	} else if (p->alignType == NSVG_ALIGN_SLICE) {
		// fill whole viewbox with image
		sx = sy = nsvg__maxf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	}

	// Transform
	sx *= us;
	sy *= us;
	avgs = (sx+sy) / 2.0f;
	for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
		shape->bounds[0] = (shape->bounds[0] + tx) * sx;
		shape->bounds[1] = (shape->bounds[1] + ty) * sy;
		shape->bounds[2] = (shape->bounds[2] + tx) * sx;
		shape->bounds[3] = (shape->bounds[3] + ty) * sy;
		for (path = shape->paths; path != NULL; path = path->next) {
			path->bounds[0] = (path->bounds[0] + tx) * sx;
			path->bounds[1] = (path->bounds[1] + ty) * sy;
			path->bounds[2] = (path->bounds[2] + tx) * sx;
			path->bounds[3] = (path->bounds[3] + ty) * sy;
			for (i =0; i < path->npts; i++) {
				pt = &path->pts[i*2];
				pt[0] = (pt[0] + tx) * sx;
				pt[1] = (pt[1] + ty) * sy;
			}
		}

		if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
			nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy);
			memcpy(t, shape->fill.gradient->xform, sizeof(float)*6);
			nsvg__xformInverse(shape->fill.gradient->xform, t);
		}
		if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
			nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy);
			memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6);
			nsvg__xformInverse(shape->stroke.gradient->xform, t);
		}

		shape->strokeWidth *= avgs;
		shape->strokeDashOffset *= avgs;
		for (i = 0; i < shape->strokeDashCount; i++)
			shape->strokeDashArray[i] *= avgs;
	}
}

NANOSVG_SCOPE
NSVGimage* nsvgParse(char* input, const char* units, float dpi)
{
	NSVGparser* p;
	NSVGimage* ret = 0;

	p = nsvg__createParser();
	if (p == NULL) {
		return NULL;
	}
	p->dpi = dpi;

	nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);

	// Scale to viewBox
	nsvg__scaleToViewbox(p, units);

	ret = p->image;
	p->image = NULL;

	nsvg__deleteParser(p);

	return ret;
}

NANOSVG_SCOPE
NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
{
	FILE* fp = NULL;
	size_t size;
	char* data = NULL;
	NSVGimage* image = NULL;

	fp = fopen(filename, "rb");
	if (!fp) goto error;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	data = (char*)NANOSVG_malloc(size+1);
	if (data == NULL) goto error;
	if (fread(data, 1, size, fp) != size) goto error;
	data[size] = '\0';	// Must be null terminated.
	fclose(fp);
	image = nsvgParse(data, units, dpi);
	NANOSVG_free(data);

	return image;

error:
	if (fp) fclose(fp);
	if (data) NANOSVG_free(data);
	if (image) nsvgDelete(image);
	return NULL;
}

NANOSVG_SCOPE
void nsvgDelete(NSVGimage* image)
{
	NSVGshape *snext, *shape;
	if (image == NULL) return;
	shape = image->shapes;
	while (shape != NULL) {
		snext = shape->next;
		nsvg__deletePaths(shape->paths);
		nsvg__deletePaint(&shape->fill);
		nsvg__deletePaint(&shape->stroke);
		NANOSVG_free(shape);
		shape = snext;
	}
	NANOSVG_free(image);
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted generic/nanosvgrast.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
/*
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * The polygon rasterization is heavily based on stb_truetype rasterizer
 * by Sean Barrett - http://nothings.org/
 *
 */

#ifndef NANOSVGRAST_H
#define NANOSVGRAST_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif

#ifndef NANOSVG_malloc
#define NANOSVG_malloc malloc
#endif

#ifndef NANOSVG_realloc
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

typedef struct NSVGrasterizer NSVGrasterizer;

/* Example Usage:
	// Load SVG
	struct SNVGImage* image = nsvgParseFromFile("test.svg.");

	// Create rasterizer (can be used to render multiple images).
	struct NSVGrasterizer* rast = nsvgCreateRasterizer();
	// Allocate memory for image
	unsigned char* img = malloc(w*h*4);
	// Rasterize
	nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4);
*/

// Allocated rasterizer context.
NANOSVG_SCOPE NSVGrasterizer* nsvgCreateRasterizer(void);

// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
//   r - pointer to rasterizer context
//   image - pointer to image to rasterize
//   tx,ty - image offset (applied after scaling)
//   scale - image scale
//   dst - pointer to destination image data, 4 bytes per pixel (RGBA)
//   w - width of the image to render
//   h - height of the image to render
//   stride - number of bytes per scaleline in the destination buffer
NANOSVG_SCOPE void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride);

// Deletes rasterizer context.
NANOSVG_SCOPE void nsvgDeleteRasterizer(NSVGrasterizer*);


#ifdef __cplusplus
}
#endif

#endif // NANOSVGRAST_H

#ifdef NANOSVGRAST_IMPLEMENTATION

#include <math.h>

#define NSVG__SUBSAMPLES	5
#define NSVG__FIXSHIFT		10
#define NSVG__FIX			(1 << NSVG__FIXSHIFT)
#define NSVG__FIXMASK		(NSVG__FIX-1)
#define NSVG__MEMPAGE_SIZE	1024

typedef struct NSVGedge {
	float x0,y0, x1,y1;
	int dir;
	struct NSVGedge* next;
} NSVGedge;

typedef struct NSVGpoint {
	float x, y;
	float dx, dy;
	float len;
	float dmx, dmy;
	unsigned char flags;
} NSVGpoint;

typedef struct NSVGactiveEdge {
	int x,dx;
	float ey;
	int dir;
	struct NSVGactiveEdge *next;
} NSVGactiveEdge;

typedef struct NSVGmemPage {
	unsigned char mem[NSVG__MEMPAGE_SIZE];
	int size;
	struct NSVGmemPage* next;
} NSVGmemPage;

typedef struct NSVGcachedPaint {
	char type;
	char spread;
	float xform[6];
	unsigned int colors[256];
} NSVGcachedPaint;

struct NSVGrasterizer
{
	float px, py;

	float tessTol;
	float distTol;

	NSVGedge* edges;
	int nedges;
	int cedges;

	NSVGpoint* points;
	int npoints;
	int cpoints;

	NSVGpoint* points2;
	int npoints2;
	int cpoints2;

	NSVGactiveEdge* freelist;
	NSVGmemPage* pages;
	NSVGmemPage* curpage;

	unsigned char* scanline;
	int cscanline;

	unsigned char* bitmap;
	int width, height, stride;
};

NANOSVG_SCOPE
NSVGrasterizer* nsvgCreateRasterizer(void)
{
	NSVGrasterizer* r = (NSVGrasterizer*)NANOSVG_malloc(sizeof(NSVGrasterizer));
	if (r == NULL) goto error;
	memset(r, 0, sizeof(NSVGrasterizer));

	r->tessTol = 0.25f;
	r->distTol = 0.01f;

	return r;

error:
	nsvgDeleteRasterizer(r);
	return NULL;
}

NANOSVG_SCOPE
void nsvgDeleteRasterizer(NSVGrasterizer* r)
{
	NSVGmemPage* p;

	if (r == NULL) return;

	p = r->pages;
	while (p != NULL) {
		NSVGmemPage* next = p->next;
		NANOSVG_free(p);
		p = next;
	}

	if (r->edges) NANOSVG_free(r->edges);
	if (r->points) NANOSVG_free(r->points);
	if (r->points2) NANOSVG_free(r->points2);
	if (r->scanline) NANOSVG_free(r->scanline);

	NANOSVG_free(r);
}

static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur)
{
	NSVGmemPage *newp;

	// If using existing chain, return the next page in chain
	if (cur != NULL && cur->next != NULL) {
		return cur->next;
	}

	// Alloc new page
	newp = (NSVGmemPage*)NANOSVG_malloc(sizeof(NSVGmemPage));
	if (newp == NULL) return NULL;
	memset(newp, 0, sizeof(NSVGmemPage));

	// Add to linked list
	if (cur != NULL)
		cur->next = newp;
	else
		r->pages = newp;

	return newp;
}

static void nsvg__resetPool(NSVGrasterizer* r)
{
	NSVGmemPage* p = r->pages;
	while (p != NULL) {
		p->size = 0;
		p = p->next;
	}
	r->curpage = r->pages;
}

static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size)
{
	unsigned char* buf;
	if (size > NSVG__MEMPAGE_SIZE) return NULL;
	if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) {
		r->curpage = nsvg__nextPage(r, r->curpage);
	}
	buf = &r->curpage->mem[r->curpage->size];
	r->curpage->size += size;
	return buf;
}

static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol)
{
	float dx = x2 - x1;
	float dy = y2 - y1;
	return dx*dx + dy*dy < tol*tol;
}

static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags)
{
	NSVGpoint* pt;

	if (r->npoints > 0) {
		pt = &r->points[r->npoints-1];
		if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) {
			pt->flags = (unsigned char)(pt->flags | flags);
			return;
		}
	}

	if (r->npoints+1 > r->cpoints) {
		r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64;
		r->points = (NSVGpoint*)NANOSVG_realloc(r->points, sizeof(NSVGpoint) * r->cpoints);
		if (r->points == NULL) return;
	}

	pt = &r->points[r->npoints];
	pt->x = x;
	pt->y = y;
	pt->flags = (unsigned char)flags;
	r->npoints++;
}

static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt)
{
	if (r->npoints+1 > r->cpoints) {
		r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64;
		r->points = (NSVGpoint*)NANOSVG_realloc(r->points, sizeof(NSVGpoint) * r->cpoints);
		if (r->points == NULL) return;
	}
	r->points[r->npoints] = pt;
	r->npoints++;
}

static void nsvg__duplicatePoints(NSVGrasterizer* r)
{
	if (r->npoints > r->cpoints2) {
		r->cpoints2 = r->npoints;
		r->points2 = (NSVGpoint*)NANOSVG_realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2);
		if (r->points2 == NULL) return;
	}

	memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints);
	r->npoints2 = r->npoints;
}

static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1)
{
	NSVGedge* e;

	// Skip horizontal edges
	if (y0 == y1)
		return;

	if (r->nedges+1 > r->cedges) {
		r->cedges = r->cedges > 0 ? r->cedges * 2 : 64;
		r->edges = (NSVGedge*)NANOSVG_realloc(r->edges, sizeof(NSVGedge) * r->cedges);
		if (r->edges == NULL) return;
	}

	e = &r->edges[r->nedges];
	r->nedges++;

	if (y0 < y1) {
		e->x0 = x0;
		e->y0 = y0;
		e->x1 = x1;
		e->y1 = y1;
		e->dir = 1;
	} else {
		e->x0 = x1;
		e->y0 = y1;
		e->x1 = x0;
		e->y1 = y0;
		e->dir = -1;
	}
}

static float nsvg__normalize(float *x, float* y)
{
	float d = sqrtf((*x)*(*x) + (*y)*(*y));
	if (d > 1e-6f) {
		float id = 1.0f / d;
		*x *= id;
		*y *= id;
	}
	return d;
}

static float nsvg__absf(float x) { return x < 0 ? -x : x; }

static void nsvg__flattenCubicBez(NSVGrasterizer* r,
								  float x1, float y1, float x2, float y2,
								  float x3, float y3, float x4, float y4,
								  int level, int type)
{
	float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;
	float dx,dy,d2,d3;

	if (level > 10) return;

	x12 = (x1+x2)*0.5f;
	y12 = (y1+y2)*0.5f;
	x23 = (x2+x3)*0.5f;
	y23 = (y2+y3)*0.5f;
	x34 = (x3+x4)*0.5f;
	y34 = (y3+y4)*0.5f;
	x123 = (x12+x23)*0.5f;
	y123 = (y12+y23)*0.5f;

	dx = x4 - x1;
	dy = y4 - y1;
	d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx));
	d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx));

	if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) {
		nsvg__addPathPoint(r, x4, y4, type);
		return;
	}

	x234 = (x23+x34)*0.5f;
	y234 = (y23+y34)*0.5f;
	x1234 = (x123+x234)*0.5f;
	y1234 = (y123+y234)*0.5f;

	nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0);
	nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type);
}

static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j;
	NSVGpath* path;

	for (path = shape->paths; path != NULL; path = path->next) {
		r->npoints = 0;
		// Flatten path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
		}
		// Close path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		// Build edges
		for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
			nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
	}
}

enum NSVGpointFlags
{
	NSVG_PT_CORNER = 0x01,
	NSVG_PT_BEVEL = 0x02,
	NSVG_PT_LEFT = 0x04
};

static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dx = p1->x - p0->x;
	float dy = p1->y - p0->y;
	float len = nsvg__normalize(&dx, &dy);
	float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect)
{
	float w = lineWidth * 0.5f;
	float px = p->x, py = p->y;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;

	nsvg__addEdge(r, lx, ly, rx, ry);

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect)
{
	float w = lineWidth * 0.5f;
	float px = p->x - dx*w, py = p->y - dy*w;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;

	nsvg__addEdge(r, lx, ly, rx, ry);

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

#ifndef NSVG_PI
#define NSVG_PI (3.14159265358979323846264338327f)
#endif

static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect)
{
	int i;
	float w = lineWidth * 0.5f;
	float px = p->x, py = p->y;
	float dlx = dy, dly = -dx;
	float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0;

	for (i = 0; i < ncap; i++) {
		float a = (float)i/(float)(ncap-1)*NSVG_PI;
		float ax = cosf(a) * w, ay = sinf(a) * w;
		float x = px - dlx*ax - dx*ay;
		float y = py - dly*ax - dy*ay;

		if (i > 0)
			nsvg__addEdge(r, prevx, prevy, x, y);

		prevx = x;
		prevy = y;

		if (i == 0) {
			lx = x; ly = y;
		} else if (i == ncap-1) {
			rx = x; ry = y;
		}
	}

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w);
	float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w);
	float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w);
	float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w);

	nsvg__addEdge(r, lx0, ly0, left->x, left->y);
	nsvg__addEdge(r, lx1, ly1, lx0, ly0);

	nsvg__addEdge(r, right->x, right->y, rx0, ry0);
	nsvg__addEdge(r, rx0, ry0, rx1, ry1);

	left->x = lx1; left->y = ly1;
	right->x = rx1; right->y = ry1;
}

static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float lx0, rx0, lx1, rx1;
	float ly0, ry0, ly1, ry1;

	if (p1->flags & NSVG_PT_LEFT) {
		lx0 = lx1 = p1->x - p1->dmx * w;
		ly0 = ly1 = p1->y - p1->dmy * w;
		nsvg__addEdge(r, lx1, ly1, left->x, left->y);

		rx0 = p1->x + (dlx0 * w);
		ry0 = p1->y + (dly0 * w);
		rx1 = p1->x + (dlx1 * w);
		ry1 = p1->y + (dly1 * w);
		nsvg__addEdge(r, right->x, right->y, rx0, ry0);
		nsvg__addEdge(r, rx0, ry0, rx1, ry1);
	} else {
		lx0 = p1->x - (dlx0 * w);
		ly0 = p1->y - (dly0 * w);
		lx1 = p1->x - (dlx1 * w);
		ly1 = p1->y - (dly1 * w);
		nsvg__addEdge(r, lx0, ly0, left->x, left->y);
		nsvg__addEdge(r, lx1, ly1, lx0, ly0);

		rx0 = rx1 = p1->x + p1->dmx * w;
		ry0 = ry1 = p1->y + p1->dmy * w;
		nsvg__addEdge(r, right->x, right->y, rx1, ry1);
	}

	left->x = lx1; left->y = ly1;
	right->x = rx1; right->y = ry1;
}

static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap)
{
	int i, n;
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float a0 = atan2f(dly0, dlx0);
	float a1 = atan2f(dly1, dlx1);
	float da = a1 - a0;
	float lx, ly, rx, ry;

	if (da < NSVG_PI) da += NSVG_PI*2;
	if (da > NSVG_PI) da -= NSVG_PI*2;

	n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap);
	if (n < 2) n = 2;
	if (n > ncap) n = ncap;

	lx = left->x;
	ly = left->y;
	rx = right->x;
	ry = right->y;

	for (i = 0; i < n; i++) {
		float u = (float)i/(float)(n-1);
		float a = a0 + u*da;
		float ax = cosf(a) * w, ay = sinf(a) * w;
		float lx1 = p1->x - ax, ly1 = p1->y - ay;
		float rx1 = p1->x + ax, ry1 = p1->y + ay;

		nsvg__addEdge(r, lx1, ly1, lx, ly);
		nsvg__addEdge(r, rx, ry, rx1, ry1);

		lx = lx1; ly = ly1;
		rx = rx1; ry = ry1;
	}

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w);
	float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w);

	nsvg__addEdge(r, lx, ly, left->x, left->y);
	nsvg__addEdge(r, right->x, right->y, rx, ry);

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static int nsvg__curveDivs(float r, float arc, float tol)
{
	float da = acosf(r / (r + tol)) * 2.0f;
	int divs = (int)ceilf(arc / da);
	if (divs < 2) divs = 2;
	return divs;
}

static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth)
{
	int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol);	// Calculate divisions per half circle.
	NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0};
	NSVGpoint* p0, *p1;
	int j, s, e;

	// Build stroke edges
	if (closed) {
		// Looping
		p0 = &points[npoints-1];
		p1 = &points[0];
		s = 0;
		e = npoints;
	} else {
		// Add cap
		p0 = &points[0];
		p1 = &points[1];
		s = 1;
		e = npoints-1;
	}

	if (closed) {
		nsvg__initClosed(&left, &right, p0, p1, lineWidth);
		firstLeft = left;
		firstRight = right;
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0);
	}

	for (j = s; j < e; ++j) {
		if (p1->flags & NSVG_PT_CORNER) {
			if (lineJoin == NSVG_JOIN_ROUND)
				nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap);
			else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL))
				nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth);
			else
				nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth);
		} else {
			nsvg__straightJoin(r, &left, &right, p1, lineWidth);
		}
		p0 = p1++;
	}

	if (closed) {
		// Loop it
		nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y);
		nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y);
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1);
	}
}

static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin)
{
	int i, j;
	NSVGpoint* p0, *p1;

	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (i = 0; i < r->npoints; i++) {
		// Calculate segment direction and length
		p0->dx = p1->x - p0->x;
		p0->dy = p1->y - p0->y;
		p0->len = nsvg__normalize(&p0->dx, &p0->dy);
		// Advance
		p0 = p1++;
	}

	// calculate joins
	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (j = 0; j < r->npoints; j++) {
		float dlx0, dly0, dlx1, dly1, dmr2, cross;
		dlx0 = p0->dy;
		dly0 = -p0->dx;
		dlx1 = p1->dy;
		dly1 = -p1->dx;
		// Calculate extrusions
		p1->dmx = (dlx0 + dlx1) * 0.5f;
		p1->dmy = (dly0 + dly1) * 0.5f;
		dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy;
		if (dmr2 > 0.000001f) {
			float s2 = 1.0f / dmr2;
			if (s2 > 600.0f) {
				s2 = 600.0f;
			}
			p1->dmx *= s2;
			p1->dmy *= s2;
		}

		// Clear flags, but keep the corner.
		p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0;

		// Keep track of left turns.
		cross = p1->dx * p0->dy - p0->dx * p1->dy;
		if (cross > 0.0f)
			p1->flags |= NSVG_PT_LEFT;

		// Check to see if the corner needs to be beveled.
		if (p1->flags & NSVG_PT_CORNER) {
			if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) {
				p1->flags |= NSVG_PT_BEVEL;
			}
		}

		p0 = p1++;
	}
}

static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j, closed;
	NSVGpath* path;
	NSVGpoint* p0, *p1;
	float miterLimit = shape->miterLimit;
	int lineJoin = shape->strokeLineJoin;
	int lineCap = shape->strokeLineCap;
	float lineWidth = shape->strokeWidth * scale;

	for (path = shape->paths; path != NULL; path = path->next) {
		// Flatten path
		r->npoints = 0;
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
		}
		if (r->npoints < 2)
			continue;

		closed = path->closed;

		// If the first and last points are the same, remove the last, mark as closed path.
		p0 = &r->points[r->npoints-1];
		p1 = &r->points[0];
		if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) {
			r->npoints--;
			p0 = &r->points[r->npoints-1];
			closed = 1;
		}

		if (shape->strokeDashCount > 0) {
			int idash = 0, dashState = 1;
			float totalDist = 0, dashLen, allDashLen, dashOffset;
			NSVGpoint cur;

			if (closed)
				nsvg__appendPathPoint(r, r->points[0]);

			// Duplicate points -> points2.
			nsvg__duplicatePoints(r);

			r->npoints = 0;
 			cur = r->points2[0];
			nsvg__appendPathPoint(r, cur);

			// Figure out dash offset.
			allDashLen = 0;
			for (j = 0; j < shape->strokeDashCount; j++)
				allDashLen += shape->strokeDashArray[j];
			if (shape->strokeDashCount & 1)
				allDashLen *= 2.0f;
			// Find location inside pattern
			dashOffset = fmodf(shape->strokeDashOffset, allDashLen);
			if (dashOffset < 0.0f)
				dashOffset += allDashLen;

			while (dashOffset > shape->strokeDashArray[idash]) {
				dashOffset -= shape->strokeDashArray[idash];
				idash = (idash + 1) % shape->strokeDashCount;
			}
			dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;

			for (j = 1; j < r->npoints2; ) {
				float dx = r->points2[j].x - cur.x;
				float dy = r->points2[j].y - cur.y;
				float dist = sqrtf(dx*dx + dy*dy);

				if ((totalDist + dist) > dashLen) {
					// Calculate intermediate point
					float d = (dashLen - totalDist) / dist;
					float x = cur.x + dx * d;
					float y = cur.y + dy * d;
					nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER);

					// Stroke
					if (r->npoints > 1 && dashState) {
						nsvg__prepareStroke(r, miterLimit, lineJoin);
						nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
					}
					// Advance dash pattern
					dashState = !dashState;
					idash = (idash+1) % shape->strokeDashCount;
					dashLen = shape->strokeDashArray[idash] * scale;
					// Restart
					cur.x = x;
					cur.y = y;
					cur.flags = NSVG_PT_CORNER;
					totalDist = 0.0f;
					r->npoints = 0;
					nsvg__appendPathPoint(r, cur);
				} else {
					totalDist += dist;
					cur = r->points2[j];
					nsvg__appendPathPoint(r, cur);
					j++;
				}
			}
			// Stroke any leftover path
			if (r->npoints > 1 && dashState)
				nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
		} else {
			nsvg__prepareStroke(r, miterLimit, lineJoin);
			nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth);
		}
	}
}

static int nsvg__cmpEdge(const void *p, const void *q)
{
	const NSVGedge* a = (const NSVGedge*)p;
	const NSVGedge* b = (const NSVGedge*)q;

	if (a->y0 < b->y0) return -1;
	if (a->y0 > b->y0) return  1;
	return 0;
}


static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint)
{
	 NSVGactiveEdge* z;
	float dxdy;

	if (r->freelist != NULL) {
		// Restore from freelist.
		z = r->freelist;
		r->freelist = z->next;
	} else {
		// Alloc new edge.
		z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge));
		if (z == NULL) return NULL;
	}

	dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
//	STBTT_assert(e->y0 <= start_point);
	// round dx down to avoid going too far
	if (dxdy < 0)
		z->dx = (int)(-floorf(NSVG__FIX * -dxdy));
	else
		z->dx = (int)floorf(NSVG__FIX * dxdy);
	z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0)));
//	z->x -= off_x * FIX;
	z->ey = e->y1;
	z->next = 0;
	z->dir = e->dir;

	return z;
}

static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z)
{
	z->next = r->freelist;
	r->freelist = z;
}

static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax)
{
	int i = x0 >> NSVG__FIXSHIFT;
	int j = x1 >> NSVG__FIXSHIFT;
	if (i < *xmin) *xmin = i;
	if (j > *xmax) *xmax = j;
	if (i < len && j >= 0) {
		if (i == j) {
			// x0,x1 are the same pixel, so compute combined coverage
			scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT));
		} else {
			if (i >= 0) // add antialiasing for x0
				scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT));
			else
				i = -1; // clip

			if (j < len) // add antialiasing for x1
				scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT));
			else
				j = len; // clip

			for (++i; i < j; ++i) // fill pixels between x0 and x1
				scanline[i] = (unsigned char)(scanline[i] + maxWeight);
		}
	}
}

// note: this routine clips fills that extend off the edges... ideally this
// wouldn't happen, but it could happen if the truetype glyph bounding boxes
// are wrong, or if the user supplies a too-small bitmap
static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule)
{
	// non-zero winding fill
	int x0 = 0, w = 0;

	if (fillRule == NSVG_FILLRULE_NONZERO) {
		// Non-zero
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w += e->dir;
			} else {
				int x1 = e->x; w += e->dir;
				// if we went to zero, we need to draw
				if (w == 0)
					nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	} else if (fillRule == NSVG_FILLRULE_EVENODD) {
		// Even-odd
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w = 1;
			} else {
				int x1 = e->x; w = 0;
				nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	}
}

static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }

static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
	return (r) | (g << 8) | (b << 16) | (a << 24);
}

static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8;
	int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8;
	int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8;
	int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8;
	return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a);
}

static unsigned int nsvg__applyOpacity(unsigned int c, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (c) & 0xff;
	int g = (c>>8) & 0xff;
	int b = (c>>16) & 0xff;
	int a = (((c>>24) & 0xff)*iu) >> 8;
	return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a);
}

static inline int nsvg__div255(int x)
{
    return ((x+1) * 257) >> 16;
}

static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y,
								float tx, float ty, float scale, NSVGcachedPaint* cache)
{

	if (cache->type == NSVG_PAINT_COLOR) {
		int i, cr, cg, cb, ca;
		cr = cache->colors[0] & 0xff;
		cg = (cache->colors[0] >> 8) & 0xff;
		cb = (cache->colors[0] >> 16) & 0xff;
		ca = (cache->colors[0] >> 24) & 0xff;

		for (i = 0; i < count; i++) {
			int r,g,b;
			int a = nsvg__div255((int)cover[0] * ca);
			int ia = 255 - a;
			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
		}
	} else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		float fx, fy, dx, gy;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
		dx = 1.0f / scale;

		for (i = 0; i < count; i++) {
			int r,g,b,a,ia;
			gy = fx*t[1] + fy*t[3] + t[5];
			c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)];
			cr = (c) & 0xff;
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	} else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		// TODO: focus (fx,fy)
		float fx, fy, dx, gx, gy, gd;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
		dx = 1.0f / scale;

		for (i = 0; i < count; i++) {
			int r,g,b,a,ia;
			gx = fx*t[0] + fy*t[2] + t[4];
			gy = fx*t[1] + fy*t[3] + t[5];
			gd = sqrtf(gx*gx + gy*gy);
			c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)];
			cr = (c) & 0xff;
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	}
}

static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
{
	NSVGactiveEdge *active = NULL;
	int y, s;
	int e = 0;
	int maxWeight = (255 / NSVG__SUBSAMPLES);  // weight per vertical scanline
	int xmin, xmax;

	for (y = 0; y < r->height; y++) {
		memset(r->scanline, 0, r->width);
		xmin = r->width;
		xmax = 0;
		for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
			// find center of pixel for this scanline
			float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f;
			NSVGactiveEdge **step = &active;

			// update all active edges;
			// remove all active edges that terminate before the center of this scanline
			while (*step) {
				NSVGactiveEdge *z = *step;
				if (z->ey <= scany) {
					*step = z->next; // delete from list
//					NSVG__assert(z->valid);
					nsvg__freeActive(r, z);
				} else {
					z->x += z->dx; // advance to position for current scanline
					step = &((*step)->next); // advance through list
				}
			}

			// resort the list if needed
			for (;;) {
				int changed = 0;
				step = &active;
				while (*step && (*step)->next) {
					if ((*step)->x > (*step)->next->x) {
						NSVGactiveEdge* t = *step;
						NSVGactiveEdge* q = t->next;
						t->next = q->next;
						q->next = t;
						*step = q;
						changed = 1;
					}
					step = &(*step)->next;
				}
				if (!changed) break;
			}

			// insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
			while (e < r->nedges && r->edges[e].y0 <= scany) {
				if (r->edges[e].y1 > scany) {
					NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany);
					if (z == NULL) break;
					// find insertion point
					if (active == NULL) {
						active = z;
					} else if (z->x < active->x) {
						// insert at front
						z->next = active;
						active = z;
					} else {
						// find thing to insert AFTER
						NSVGactiveEdge* p = active;
						while (p->next && p->next->x < z->x)
							p = p->next;
						// at this point, p->next->x is NOT < z->x
						z->next = p->next;
						p->next = z;
					}
				}
				e++;
			}

			// now process all active edges in non-zero fashion
			if (active != NULL)
				nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
		}
		// Blit
		if (xmin < 0) xmin = 0;
		if (xmax > r->width-1) xmax = r->width-1;
		if (xmin <= xmax) {
			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
		}
	}

}

static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride)
{
	int x,y;

	// Unpremultiply
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = row[0], g = row[1], b = row[2], a = row[3];
			if (a != 0) {
				row[0] = (unsigned char)(r*255/a);
				row[1] = (unsigned char)(g*255/a);
				row[2] = (unsigned char)(b*255/a);
			}
			row += 4;
		}
	}

	// Defringe
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = 0, g = 0, b = 0, a = row[3], n = 0;
			if (a == 0) {
				if (x-1 > 0 && row[-1] != 0) {
					r += row[-4];
					g += row[-3];
					b += row[-2];
					n++;
				}
				if (x+1 < w && row[7] != 0) {
					r += row[4];
					g += row[5];
					b += row[6];
					n++;
				}
				if (y-1 > 0 && row[-stride+3] != 0) {
					r += row[-stride];
					g += row[-stride+1];
					b += row[-stride+2];
					n++;
				}
				if (y+1 < h && row[stride+3] != 0) {
					r += row[stride];
					g += row[stride+1];
					b += row[stride+2];
					n++;
				}
				if (n > 0) {
					row[0] = (unsigned char)(r/n);
					row[1] = (unsigned char)(g/n);
					row[2] = (unsigned char)(b/n);
				}
			}
			row += 4;
		}
	}
}


static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity)
{
	int i, j;
	NSVGgradient* grad;

	cache->type = paint->type;

	if (paint->type == NSVG_PAINT_COLOR) {
		cache->colors[0] = nsvg__applyOpacity(paint->color, opacity);
		return;
	}

	grad = paint->gradient;

	cache->spread = grad->spread;
	memcpy(cache->xform, grad->xform, sizeof(float)*6);

	if (grad->nstops == 0) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = 0;
	} if (grad->nstops == 1) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity);
	} else {
		unsigned int ca, cb = 0;
		float ua, ub, du, u;
		int ia, ib, count;

		ca = nsvg__applyOpacity(grad->stops[0].color, opacity);
		ua = nsvg__clampf(grad->stops[0].offset, 0, 1);
		ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1);
		ia = (int)(ua * 255.0f);
		ib = (int)(ub * 255.0f);
		for (i = 0; i < ia; i++) {
			cache->colors[i] = ca;
		}

		for (i = 0; i < grad->nstops-1; i++) {
			ca = nsvg__applyOpacity(grad->stops[i].color, opacity);
			cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity);
			ua = nsvg__clampf(grad->stops[i].offset, 0, 1);
			ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1);
			ia = (int)(ua * 255.0f);
			ib = (int)(ub * 255.0f);
			count = ib - ia;
			if (count <= 0) continue;
			u = 0;
			du = 1.0f / (float)count;
			for (j = 0; j < count; j++) {
				cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u);
				u += du;
			}
		}

		for (i = ib; i < 256; i++)
			cache->colors[i] = cb;
	}

}

/*
static void dumpEdges(NSVGrasterizer* r, const char* name)
{
	float xmin = 0, xmax = 0, ymin = 0, ymax = 0;
	NSVGedge *e = NULL;
	int i;
	if (r->nedges == 0) return;
	FILE* fp = fopen(name, "w");
	if (fp == NULL) return;

	xmin = xmax = r->edges[0].x0;
	ymin = ymax = r->edges[0].y0;
	for (i = 0; i < r->nedges; i++) {
		e = &r->edges[i];
		xmin = nsvg__minf(xmin, e->x0);
		xmin = nsvg__minf(xmin, e->x1);
		xmax = nsvg__maxf(xmax, e->x0);
		xmax = nsvg__maxf(xmax, e->x1);
		ymin = nsvg__minf(ymin, e->y0);
		ymin = nsvg__minf(ymin, e->y1);
		ymax = nsvg__maxf(ymax, e->y0);
		ymax = nsvg__maxf(ymax, e->y1);
	}

	fprintf(fp, "<svg viewBox=\"%f %f %f %f\" xmlns=\"http://www.w3.org/2000/svg\">", xmin, ymin, (xmax - xmin), (ymax - ymin));

	for (i = 0; i < r->nedges; i++) {
		e = &r->edges[i];
		fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#000;\" />", e->x0,e->y0, e->x1,e->y1);
	}

	for (i = 0; i < r->npoints; i++) {
		if (i+1 < r->npoints)
			fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#f00;\" />", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y);
		fprintf(fp ,"<circle cx=\"%f\" cy=\"%f\" r=\"1\" style=\"fill:%s;\" />", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0");
	}

	fprintf(fp, "</svg>");
	fclose(fp);
}
*/

NANOSVG_SCOPE
void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride)
{
	NSVGshape *shape = NULL;
	NSVGedge *e = NULL;
	NSVGcachedPaint cache;
	int i;

	r->bitmap = dst;
	r->width = w;
	r->height = h;
	r->stride = stride;

	if (w > r->cscanline) {
		r->cscanline = w;
		r->scanline = (unsigned char*)NANOSVG_realloc(r->scanline, w);
		if (r->scanline == NULL) return;
	}

	for (i = 0; i < h; i++)
		memset(&dst[i*stride], 0, w*4);

	for (shape = image->shapes; shape != NULL; shape = shape->next) {
		if (!(shape->flags & NSVG_FLAGS_VISIBLE))
			continue;

		if (shape->fill.type != NSVG_PAINT_NONE) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShape(r, shape, scale);

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges
			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->fill, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
		}
		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShapeStroke(r, shape, scale);

//			dumpEdges(r, "edge.svg");

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges
			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->stroke, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
		}
	}

	nsvg__unpremultiplyAlpha(dst, w, h, stride);

	r->bitmap = NULL;
	r->width = 0;
	r->height = 0;
	r->stride = 0;
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tk.decls.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Define the tk interface with 3 sub interfaces:
#     tkPlat	 - platform specific public
#     tkInt	 - generic private
#     tkPlatInt - platform specific private

interface tk
hooks {tkPlat tkInt tkIntPlat tkIntXlib}
scspec EXTERN

# Declare each of the functions in the public Tk interface.  Note that
# the an index should never be reused for a different function in order
# to preserve backwards compatibility.

declare 0 {
    void Tk_MainLoop(void)







<







16
17
18
19
20
21
22

23
24
25
26
27
28
29
# Define the tk interface with 3 sub interfaces:
#     tkPlat	 - platform specific public
#     tkInt	 - generic private
#     tkPlatInt - platform specific private

interface tk
hooks {tkPlat tkInt tkIntPlat tkIntXlib}


# Declare each of the functions in the public Tk interface.  Note that
# the an index should never be reused for a different function in order
# to preserve backwards compatibility.

declare 0 {
    void Tk_MainLoop(void)
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc)
}
declare 18 {
    int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 19 {
    const char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
    Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas)
}
declare 21 {
    void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y,







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc)
}
declare 18 {
    int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 19 {
    char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
    Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas)
}
declare 21 {
    void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y,
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
	    int *yPtr, int *widthPtr, int *heightPtr)
}
declare 24 {
    void Tk_ClearSelection(Tk_Window tkwin, Atom selection)
}
declare 25 {
    int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom target, Atom format, const char *buffer)
}
declare 26 {
    int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin)
}
declare 27 {
    int Tk_ConfigureInfo(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 28 {
    int Tk_ConfigureValue(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 29 {
    int Tk_ConfigureWidget(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    int argc, const char **argv, char *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
    Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font,
	    const char *str, int numChars, int wrapLength,
	    Tk_Justify justify, int flags, int *widthPtr,
	    int *heightPtr)
}
declare 32 {
    Tk_Window Tk_CoordsToWindow(int rootX, int rootY, Tk_Window tkwin)
}
declare 33 {
    unsigned long Tk_CreateBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr, const char *script, int append)
}
declare 34 {
    Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp)
}
declare 35 {
    Tk_ErrorHandler Tk_CreateErrorHandler(Display *display,
	    int errNum, int request, int minorCode,
	    Tk_ErrorProc *errorProc, ClientData clientData)
}
declare 36 {
    void Tk_CreateEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    ClientData clientData)
}
declare 37 {
    void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData)
}
declare 38 {
    void Tk_CreateImageType(const Tk_ImageType *typePtr)
}
declare 39 {
    void Tk_CreateItemType(Tk_ItemType *typePtr)
}
declare 40 {
    void Tk_CreatePhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}
declare 41 {
    void Tk_CreateSelHandler(Tk_Window tkwin,
	    Atom selection, Atom target,
	    Tk_SelectionProc *proc, ClientData clientData,
	    Atom format)
}
declare 42 {
    Tk_Window Tk_CreateWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *name, const char *screenName)
}
declare 43 {
    Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *pathName, const char *screenName)
}
declare 44 {
    int Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
	    const void *source, int width, int height)
}
declare 45 {
    void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor)
}
declare 46 {
    void Tk_DeleteAllBindings(Tk_BindingTable bindingTable, ClientData object)
}







|






|




|




|
|


















|


















|





|

















|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	    int *yPtr, int *widthPtr, int *heightPtr)
}
declare 24 {
    void Tk_ClearSelection(Tk_Window tkwin, Atom selection)
}
declare 25 {
    int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom target, Atom format, char *buffer)
}
declare 26 {
    int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin)
}
declare 27 {
    int Tk_ConfigureInfo(Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 28 {
    int Tk_ConfigureValue(Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 29 {
    int Tk_ConfigureWidget(Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_ConfigSpec *specs,
	    int argc, CONST84 char **argv, char *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
    Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font,
	    const char *str, int numChars, int wrapLength,
	    Tk_Justify justify, int flags, int *widthPtr,
	    int *heightPtr)
}
declare 32 {
    Tk_Window Tk_CoordsToWindow(int rootX, int rootY, Tk_Window tkwin)
}
declare 33 {
    unsigned long Tk_CreateBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr, const char *command, int append)
}
declare 34 {
    Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp)
}
declare 35 {
    Tk_ErrorHandler Tk_CreateErrorHandler(Display *display,
	    int errNum, int request, int minorCode,
	    Tk_ErrorProc *errorProc, ClientData clientData)
}
declare 36 {
    void Tk_CreateEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    ClientData clientData)
}
declare 37 {
    void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData)
}
declare 38 {
    void Tk_CreateImageType(Tk_ImageType *typePtr)
}
declare 39 {
    void Tk_CreateItemType(Tk_ItemType *typePtr)
}
declare 40 {
    void Tk_CreatePhotoImageFormat(Tk_PhotoImageFormat *formatPtr)
}
declare 41 {
    void Tk_CreateSelHandler(Tk_Window tkwin,
	    Atom selection, Atom target,
	    Tk_SelectionProc *proc, ClientData clientData,
	    Atom format)
}
declare 42 {
    Tk_Window Tk_CreateWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *name, const char *screenName)
}
declare 43 {
    Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *pathName, const char *screenName)
}
declare 44 {
    int Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
	    const char *source, int width, int height)
}
declare 45 {
    void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor)
}
declare 46 {
    void Tk_DeleteAllBindings(Tk_BindingTable bindingTable, ClientData object)
}
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
declare 53 {
    void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target)
}
declare 54 {
    void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
    const char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
    int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
}
declare 57 {
    void Tk_Draw3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,







|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
declare 53 {
    void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target)
}
declare 54 {
    void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
    CONST84_RETURN char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
    int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
}
declare 57 {
    void Tk_Draw3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
declare 72 {
    void Tk_FreeGC(Display *display, GC gc)
}
declare 73 {
    void Tk_FreeImage(Tk_Image image)
}
declare 74 {
    void Tk_FreeOptions(const Tk_ConfigSpec *specs,
	    char *widgRec, Display *display, int needFlags)
}
declare 75 {
    void Tk_FreePixmap(Display *display, Pixmap pixmap)
}
declare 76 {
    void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}
declare 77 {deprecated {function does nothing, call can be removed}} {
    void Tk_FreeXId(Display *display, XID xid)
}
declare 78 {
    GC Tk_GCForColor(XColor *colorPtr, Drawable drawable)
}
declare 79 {
    void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,  int reqHeight)







|








|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
declare 72 {
    void Tk_FreeGC(Display *display, GC gc)
}
declare 73 {
    void Tk_FreeImage(Tk_Image image)
}
declare 74 {
    void Tk_FreeOptions(Tk_ConfigSpec *specs,
	    char *widgRec, Display *display, int needFlags)
}
declare 75 {
    void Tk_FreePixmap(Display *display, Pixmap pixmap)
}
declare 76 {
    void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}
declare 77 {
    void Tk_FreeXId(Display *display, XID xid)
}
declare 78 {
    GC Tk_GCForColor(XColor *colorPtr, Drawable drawable)
}
declare 79 {
    void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,  int reqHeight)
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
	    Tk_BindingTable bindingTable, ClientData object)
}
declare 82 {
    int Tk_GetAnchor(Tcl_Interp *interp,
	    const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
    const char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    const char *Tk_GetBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr)
}
declare 85 {
    Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str)
}
declare 86 {
    Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp,
	    Tk_Window tkwin, const void *source, int width, int height)
}
declare 87 {
    int Tk_GetCapStyle(Tcl_Interp *interp, const char *str, int *capPtr)
}
declare 88 {
    XColor *Tk_GetColor(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name)
}







|


|








|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
	    Tk_BindingTable bindingTable, ClientData object)
}
declare 82 {
    int Tk_GetAnchor(Tcl_Interp *interp,
	    const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
    CONST84_RETURN char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    CONST84_RETURN char *Tk_GetBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr)
}
declare 85 {
    Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str)
}
declare 86 {
    Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *source, int width, int height)
}
declare 87 {
    int Tk_GetCapStyle(Tcl_Interp *interp, const char *str, int *capPtr)
}
declare 88 {
    XColor *Tk_GetColor(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name)
}
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageModelData(Tcl_Interp *interp,
	    const char *name, const Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)
}







|
|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
	    const char *name, Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)
}
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr)
}
declare 107 {
    void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr)
}
declare 108 {
    int Tk_GetScrollInfo(Tcl_Interp *interp,
	    int argc, const char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
    int Tk_GetScreenMM(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, double *doublePtr)
}
declare 110 {
    int Tk_GetSelection(Tcl_Interp *interp,







|







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr)
}
declare 107 {
    void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr)
}
declare 108 {
    int Tk_GetScrollInfo(Tcl_Interp *interp,
	    int argc, CONST84 char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
    int Tk_GetScreenMM(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, double *doublePtr)
}
declare 110 {
    int Tk_GetSelection(Tcl_Interp *interp,
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
declare 115 {
    void Tk_HandleEvent(XEvent *eventPtr)
}
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageModel model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
}
declare 120 {
    int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height)
}
declare 121 {
    void Tk_MaintainGeometry(Tk_Window window,
	    Tk_Window container, int x, int y, int width, int height)
}
declare 122 {
    Tk_Window Tk_MainWindow(Tcl_Interp *interp)
}
declare 123 {
    void Tk_MakeWindowExist(Tk_Window tkwin)
}







|













|
|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
declare 115 {
    void Tk_HandleEvent(XEvent *eventPtr)
}
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageMaster master, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
}
declare 120 {
    int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height)
}
declare 121 {
    void Tk_MaintainGeometry(Tk_Window slave,
	    Tk_Window master, int x, int y, int width, int height)
}
declare 122 {
    Tk_Window Tk_MainWindow(Tcl_Interp *interp)
}
declare 123 {
    void Tk_MakeWindowExist(Tk_Window tkwin)
}
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
declare 128 {
    void Tk_MoveWindow(Tk_Window tkwin, int x, int y)
}
declare 129 {
    void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y)
}
declare 130 {
    const char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
    const char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
    const char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
    const char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
    const char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
    const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    const char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    const char *Tk_NameOfImage(Tk_ImageModel model)
}
declare 138 {
    const char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    const char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
    const char *Tk_NameOfRelief(int relief)
}
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    ClientData clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, const char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}
declare 144 {deprecated {function signature changed}} {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {deprecated {function signature changed}} {
    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)
}
declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {deprecated {function signature changed}} {
    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 {deprecated {function signature changed}} {
    void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)







|


|


|


|


|


|


|


|


|


|


|












|
|

|




|











|





|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
declare 128 {
    void Tk_MoveWindow(Tk_Window tkwin, int x, int y)
}
declare 129 {
    void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y)
}
declare 130 {
    CONST84_RETURN char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
    CONST84_RETURN char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
    CONST84_RETURN char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
    CONST84_RETURN char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
    CONST84_RETURN char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
    CONST84_RETURN char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    CONST84_RETURN char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    CONST84_RETURN char *Tk_NameOfImage(Tk_ImageMaster imageMaster)
}
declare 138 {
    CONST84_RETURN char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    CONST84_RETURN char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
    CONST84_RETURN char *Tk_NameOfRelief(int relief)
}
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    ClientData clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, CONST84 char **argv,
	    Tk_ArgvInfo *argTable, int flags)
}
declare 144 {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {
    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)
}
declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {
    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_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
	    Tk_TextLayout layout, int x, int y,
	    int underline)
}
declare 180 {
    void Tk_Ungrab(Tk_Window tkwin)
}
declare 181 {
    void Tk_UnmaintainGeometry(Tk_Window window, Tk_Window container)
}
declare 182 {
    void Tk_UnmapWindow(Tk_Window tkwin)
}
declare 183 {
    void Tk_UnsetGrid(Tk_Window tkwin)
}







|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
	    Tk_TextLayout layout, int x, int y,
	    int underline)
}
declare 180 {
    void Tk_Ungrab(Tk_Window tkwin)
}
declare 181 {
    void Tk_UnmaintainGeometry(Tk_Window slave, Tk_Window master)
}
declare 182 {
    void Tk_UnmapWindow(Tk_Window tkwin)
}
declare 183 {
    void Tk_UnsetGrid(Tk_Window tkwin)
}
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
declare 193 {
    void  Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 194 {
    void  Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 195 {
    void  Tk_FreeConfigOptions(void *recordPtr, Tk_OptionTable optionToken,
	    Tk_Window tkwin)
}
declare 196 {
    void  Tk_FreeSavedOptions(Tk_SavedOptions *savePtr)
}
declare 197 {
    void  Tk_FreeCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)







|







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
declare 193 {
    void  Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 194 {
    void  Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 195 {
    void  Tk_FreeConfigOptions(char *recordPtr, Tk_OptionTable optionToken,
	    Tk_Window tkwin)
}
declare 196 {
    void  Tk_FreeSavedOptions(Tk_SavedOptions *savePtr)
}
declare 197 {
    void  Tk_FreeCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
    XColor *Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 203 {
    Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 204 {
    Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp,
	    void *recordPtr, Tk_OptionTable optionTable,
	    Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
    Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 206 {
    int	 Tk_GetJustifyFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, Tk_Justify *justifyPtr)
}
declare 207 {







|



|







769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
    XColor *Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 203 {
    Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 204 {
    Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp,
	    char *recordPtr, Tk_OptionTable optionTable,
	    Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
    Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 206 {
    int	 Tk_GetJustifyFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, Tk_Justify *justifyPtr)
}
declare 207 {
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
	    Tcl_Obj *objPtr, int *resultPtr)
}
declare 210 {
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {nostub {Don't use this function in a stub-enabled extension}} {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
    int	 Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionTable, int objc,
	    Tcl_Obj *const objv[], Tk_Window tkwin,
	    Tk_SavedOptions *savePtr, int *maskPtr)
}
declare 215 {
    void Tk_InitConsoleChannels(Tcl_Interp *interp)
}
declare 216 {
    int Tk_CreateConsoleWindow(Tcl_Interp *interp)
}
declare 217 {
    void Tk_CreateSmoothMethod(Tcl_Interp *interp, const Tk_SmoothMethod *method)
}
#declare 218 {
#    void Tk_CreateCanvasVisitor(Tcl_Interp *interp, void *typePtr)
#}
#declare 219 {
#    void *Tk_GetCanvasVisitor(Tcl_Interp *interp, const char *name)
#}







|


|







|











|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
	    Tcl_Obj *objPtr, int *resultPtr)
}
declare 210 {
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
    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)
}
declare 215 {
    void Tk_InitConsoleChannels(Tcl_Interp *interp)
}
declare 216 {
    int Tk_CreateConsoleWindow(Tcl_Interp *interp)
}
declare 217 {
    void Tk_CreateSmoothMethod(Tcl_Interp *interp, Tk_SmoothMethod *method)
}
#declare 218 {
#    void Tk_CreateCanvasVisitor(Tcl_Interp *interp, void *typePtr)
#}
#declare 219 {
#    void *Tk_GetCanvasVisitor(Tcl_Interp *interp, const char *name)
#}
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
#
declare 241 {
    Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *screenName)
}
declare 242 {
    void Tk_SetClassProcs(Tk_Window tkwin,
	    const Tk_ClassProcs *procs, ClientData instanceData)
}

# New in 8.4a4
#
declare 243 {
    void Tk_SetInternalBorderEx(Tk_Window tkwin, int left, int right,
	    int top, int bottom)
}
declare 244 {
    void Tk_SetMinimumRequestSize(Tk_Window tkwin,
	    int minWidth, int minHeight)
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {deprecated {function signature changed}} {
    void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int compRule)
}
declare 247 {deprecated {function signature changed}} {
    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)
}
declare 248 {
    int Tk_CollapseMotionEvents(Display *display, int collapse)







|


















|




|







919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
#
declare 241 {
    Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *screenName)
}
declare 242 {
    void Tk_SetClassProcs(Tk_Window tkwin,
	    Tk_ClassProcs *procs, ClientData instanceData)
}

# New in 8.4a4
#
declare 243 {
    void Tk_SetInternalBorderEx(Tk_Window tkwin, int left, int right,
	    int top, int bottom)
}
declare 244 {
    void Tk_SetMinimumRequestSize(Tk_Window tkwin,
	    int minWidth, int minHeight)
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {
    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_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)
}
declare 248 {
    int Tk_CollapseMotionEvents(Display *display, int collapse)
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
}
declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}
declare 262 {
    void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int x, int y, int width,
	    int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
	    int *heightPtr)
}
declare 263 {
    int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin)
}
declare 264 {
    void Tk_DrawElement(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y,
	    int width, int height, int state)
}

# TIP#116
declare 265 {
    int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
	    int width, int height)







|




|





|



|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
}
declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}
declare 262 {
    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)
}
declare 263 {
    int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin)
}
declare 264 {
    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)
}

# TIP#116
declare 265 {
    int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
	    int width, int height)
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
# 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(const Tk_ImageType *typePtr)
}
declare 273 {
    void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}

# TIP#580
declare 274 {
    int Tk_AlwaysShowSelection(Tk_Window tkwin)
}
declare 275 {
    unsigned Tk_GetButtonMask(unsigned button)
}
declare 276 {
    int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, double *doublePtr)
}
declare 277 {
    Tcl_Obj *Tk_NewWindowObj(Tk_Window tkwin)
}
declare 278 {
    void Tk_SendVirtualEvent(Tk_Window tkwin, const char *eventName,
	    Tcl_Obj *detail)
}
declare 279 {
    Tcl_Obj *Tk_FontGetDescription(Tk_Font tkfont)
}

# Define the platform specific public Tk interface.  These functions are
# only available on the designated platform.

interface tkPlat








|


|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069


1070













1071




1072
1073
1074
1075
1076
1077
1078
# 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)
}


declare 280 {













    void TkUnusedStubEntry(void)




}

# Define the platform specific public Tk interface.  These functions are
# only available on the designated platform.

interface tkPlat

1117
1118
1119
1120
1121
1122
1123
1124














1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169




1170
1171
1172
1173



1174
1175
1176

1177
1178
1179
1180










1181
1182
1183
1184
1185
declare 5 win {
    int Tk_TranslateWinEvent(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}

################################
# Aqua specific functions
# Stub removed because the function no longer exists.














#declare 3 aqua {
#    void TkMacOSXInitMenus(Tcl_Interp *interp)
#}

declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}
declare 5 aqua {
    void TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}
declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}
# Stub removed because it just returned NULL.
#declare 7 aqua {
#    void *TkMacOSXGetDrawablePort(Drawable drawable)
#}

declare 8 aqua {
    void *TkMacOSXGetRootControl(Drawable drawable)
}
declare 9 aqua {
    void Tk_MacOSXSetupTkNotifier(void)
}
declare 10 aqua {
    int Tk_MacOSXIsAppInFront(void)
}
declare 11 aqua {
    Tk_Window Tk_MacOSXGetTkWindow(void *w)
}
declare 12 aqua {
    void *Tk_MacOSXGetCGContextForDrawable(Drawable drawable)
}
# Replaces TkMacOSXDrawable
declare 13 aqua {
    void *Tk_MacOSXGetNSWindowForDrawable(Drawable drawable)
}
declare 16 aqua {
    void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}

##############################################################################

# Public functions that are not accessible via the stubs table.





export {
    const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
	    int exact)
}



export {
    void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)

}
export {
    void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);










}

# Local Variables:
# mode: tcl
# End:







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>




|





<
|
|
<
>









<
<
<
<
<
<
<
<
<
<

|
<






>
>
>
>




>
>
>

<
<
>


<
<
>
>
>
>
>
>
>
>
>
>





1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

1132
1133

1134
1135
1136
1137
1138
1139
1140
1141
1142
1143










1144
1145

1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163


1164
1165
1166


1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
declare 5 win {
    int Tk_TranslateWinEvent(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}

################################
# Aqua specific functions

declare 0 aqua {
    void Tk_MacOSXSetEmbedHandler(
	    Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
	    Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
	    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
	    Tk_MacOSXEmbedGetClipProc *getClipProc,
	    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
}
declare 1 aqua {
    void Tk_MacOSXTurnOffMenus(void)
}
declare 2 aqua {
    void Tk_MacOSXTkOwnsCursor(int tkOwnsIt)
}
declare 3 aqua {
    void TkMacOSXInitMenus(Tcl_Interp *interp)

}
declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}
declare 5 aqua {
    void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}
declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}

declare 7 aqua {
    void *TkMacOSXGetDrawablePort(Drawable drawable)

}
declare 8 aqua {
    void *TkMacOSXGetRootControl(Drawable drawable)
}
declare 9 aqua {
    void Tk_MacOSXSetupTkNotifier(void)
}
declare 10 aqua {
    int Tk_MacOSXIsAppInFront(void)
}










declare 16 aqua {
    void TkUnusedStubEntry(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
# End:

Changes to generic/tk.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
#	error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better
#endif

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*
 * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
 * quotation marks), JOIN joins two arguments.
 */

#ifndef STRINGIFY
#  define STRINGIFY(x) STRINGIFY1(x)
#  define STRINGIFY1(x) #x
#endif
#ifndef JOIN
#  define JOIN(a,b) JOIN1(a,b)
#  define JOIN1(a,b) a##b
#endif

/*
 * For C++ compilers, use extern "C"
 */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * When version numbers change here, you must also go into the following files
 * and update the version numbers:
 *
 * library/tk.tcl	(1 LOC patch)
 * unix/configure.ac	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.ac	(as above)
 * README		(sections 0 and 1)

 * macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC
 * win/README		(not patchlevel)
 * unix/README		(not patchlevel)
 * 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.
 */

#define TK_MAJOR_VERSION	8
#define TK_MINOR_VERSION	7
#define TK_RELEASE_LEVEL	TCL_ALPHA_RELEASE
#define TK_RELEASE_SERIAL	4

#define TK_VERSION		"8.7"
#define TK_PATCH_LEVEL		"8.7a4"

/*
 * 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.
 */

#ifndef RC_INVOKED

#if !defined(_XLIB_H) && !defined(_X11_XLIB_H_)
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#   include <X11/Xlib.h>
#   ifdef MAC_OSX_TK
#	include <X11/X.h>
#   endif
#endif
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT
#else
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif

/*
 *----------------------------------------------------------------------
 *
 * Decide whether or not to use input methods.
 */

#if defined(XNQueryInputStyle) && !defined(_WIN32) && !defined(MAC_OSX_TK)
#define TK_USE_INPUT_METHODS
#endif

/*
 * Dummy types that are used by clients:
 */

#define Tk_ImageMaster Tk_ImageModel
typedef struct Tk_BindingTable_ *Tk_BindingTable;
typedef struct Tk_Canvas_ *Tk_Canvas;
typedef struct Tk_Cursor_ *Tk_Cursor;
typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler;
typedef struct Tk_Font_ *Tk_Font;
typedef struct Tk_Image__ *Tk_Image;
typedef struct Tk_ImageModel_ *Tk_ImageModel;
typedef struct Tk_OptionTable_ *Tk_OptionTable;
typedef struct Tk_PostscriptInfo_ *Tk_PostscriptInfo;
typedef struct Tk_TextLayout_ *Tk_TextLayout;
typedef struct Tk_Window_ *Tk_Window;
typedef struct Tk_3DBorder_ *Tk_3DBorder;
typedef struct Tk_Style_ *Tk_Style;
typedef struct Tk_StyleEngine_ *Tk_StyleEngine;







|
|


|
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<

|













|
|

>
|










|
|
|

|
|
|













<
<
<













<
<
<
<








|







<






|







13
14
15
16
17
18
19
20
21
22
23
24

25
26




27


28
29



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79



80
81
82
83
84
85
86
87
88
89
90
91
92




93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 5)
#	error Tk 8.5 must be compiled with tcl.h from Tcl 8.5 or better
#endif

#ifndef _ANSI_ARGS_

#   ifndef NO_PROTOTYPES
#	define _ANSI_ARGS_(x)	x




#   else


#	define _ANSI_ARGS_(x)	()
#   endif



#endif

/*
 * For C++ compilers, use extern "C"
 */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * When version numbers change here, you must also go into the following files
 * and update the version numbers:
 *
 * library/tk.tcl	(1 LOC patch)
 * unix/configure.in	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.in	(as above)
 * README		(sections 0 and 1)
 * 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		(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.
 */

#define TK_MAJOR_VERSION	8
#define TK_MINOR_VERSION	5
#define TK_RELEASE_LEVEL	TCL_FINAL_RELEASE
#define TK_RELEASE_SERIAL	19

#define TK_VERSION		"8.5"
#define TK_PATCH_LEVEL		"8.5.19"

/*
 * 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.
 */

#ifndef RC_INVOKED

#if !defined(_XLIB_H) && !defined(_X11_XLIB_H_)



#   include <X11/Xlib.h>
#   ifdef MAC_OSX_TK
#	include <X11/X.h>
#   endif
#endif
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT




#endif

/*
 *----------------------------------------------------------------------
 *
 * Decide whether or not to use input methods.
 */

#ifdef XNQueryInputStyle
#define TK_USE_INPUT_METHODS
#endif

/*
 * Dummy types that are used by clients:
 */


typedef struct Tk_BindingTable_ *Tk_BindingTable;
typedef struct Tk_Canvas_ *Tk_Canvas;
typedef struct Tk_Cursor_ *Tk_Cursor;
typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler;
typedef struct Tk_Font_ *Tk_Font;
typedef struct Tk_Image__ *Tk_Image;
typedef struct Tk_ImageMaster_ *Tk_ImageMaster;
typedef struct Tk_OptionTable_ *Tk_OptionTable;
typedef struct Tk_PostscriptInfo_ *Tk_PostscriptInfo;
typedef struct Tk_TextLayout_ *Tk_TextLayout;
typedef struct Tk_Window_ *Tk_Window;
typedef struct Tk_3DBorder_ *Tk_3DBorder;
typedef struct Tk_Style_ *Tk_Style;
typedef struct Tk_StyleEngine_ *Tk_StyleEngine;
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    const char *optionName;	/* Name used to specify option in Tcl
				 * commands. */
    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. */
#if TCL_MAJOR_VERSION > 8
    size_t 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 offsetof macro to generate
				 * values for this. TCL_INDEX_NONE means don't
				 * store the Tcl_Obj in the record. */
    size_t 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 offsetof
				 * macro to generate values for it.
				 * TCL_INDEX_NONE means don't store the
				 * internal representation in the record. */
#else
    int objOffset;
    int internalOffset;
#endif
    int flags;			/* Any combination of the values defined
				 * below. */
    const void *clientData;	/* An alternate place to put option-specific
				 * data. Used for the monochrome default value
				 * for colors, etc. */
    int typeMask;		/* An arbitrary bit mask defined by the class
				 * manager; typically bits correspond to
				 * certain kinds of options such as all those
				 * that require a redisplay when they change.
				 * Tk_SetOptions returns the bit-wise OR of







<
|


|
|
|
|



|
|
|
|
<
<
<
<


|







171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191




192
193
194
195
196
197
198
199
200
201
    const char *optionName;	/* Name used to specify option in Tcl
				 * commands. */
    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. */
    int internalOffset;		/* Where in record to store the internal
				 * representation of the value of this option,
				 * such as an int or XColor *. This field is
				 * specified as an offset in bytes from the
				 * start of the record. Use the Tk_Offset
				 * macro to generate values for it. -1 means
				 * don't store the internal representation in
				 * the record. */




    int flags;			/* Any combination of the values defined
				 * below. */
    ClientData clientData;	/* An alternate place to put option-specific
				 * data. Used for the monochrome default value
				 * for colors, etc. */
    int typeMask;		/* An arbitrary bit mask defined by the class
				 * manager; typically bits correspond to
				 * certain kinds of options such as all those
				 * that require a redisplay when they change.
				 * Tk_SetOptions returns the bit-wise OR of
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

/*
 * The following structure and function types are used by TK_OPTION_CUSTOM
 * options; the structure holds pointers to the functions needed by the Tk
 * option config code to handle a custom option.
 */

#if TCL_MAJOR_VERSION > 8
typedef int (Tk_CustomOptionSetProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,
	size_t offset, char *saveInternalPtr, int flags);
typedef Tcl_Obj *(Tk_CustomOptionGetProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, size_t offset);
#else
typedef int (Tk_CustomOptionSetProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,
	int offset, char *saveInternalPtr, int flags);
typedef Tcl_Obj *(Tk_CustomOptionGetProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset);
#endif
typedef void (Tk_CustomOptionRestoreProc) (ClientData clientData,
	Tk_Window tkwin, char *internalPtr, char *saveInternalPtr);
typedef void (Tk_CustomOptionFreeProc) (ClientData clientData, Tk_Window tkwin,
	char *internalPtr);

typedef struct Tk_ObjCustomOption {
    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;







<
|

<
<
<
<
<
<
|
|
|
<
|
|
|
|







213
214
215
216
217
218
219

220
221






222
223
224

225
226
227
228
229
230
231
232
233
234
235

/*
 * The following structure and function types are used by TK_OPTION_CUSTOM
 * options; the structure holds pointers to the functions needed by the Tk
 * option config code to handle a custom option.
 */


typedef int (Tk_CustomOptionSetProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,






	int offset, char *saveInternalPtr, int flags));
typedef Tcl_Obj *(Tk_CustomOptionGetProc) _ANSI_ARGS_((ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset));

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 {
    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;
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
} Tk_ObjCustomOption;

/*
 * 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.
 */

#ifndef TK_NO_DEPRECATED
#   define Tk_Offset(type, field) ((int) offsetof(type, field))
#endif
/* Workaround for platforms missing offsetof(), e.g. VC++ 6.0 */
#ifndef offsetof
#   define offsetof(type, field) ((size_t) ((char *) &((type *) 0)->field))
#endif

/*
 * The following two structures are used for error handling. When config







<
|
<







247
248
249
250
251
252
253

254

255
256
257
258
259
260
261
} Tk_ObjCustomOption;

/*
 * 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.
 */


#define Tk_Offset(type, field) ((int) offsetof(type, field))

/* Workaround for platforms missing offsetof(), e.g. VC++ 6.0 */
#ifndef offsetof
#   define offsetof(type, field) ((size_t) ((char *) &((type *) 0)->field))
#endif

/*
 * The following two structures are used for error handling. When config
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
				 * 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 -1. 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
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    void *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */
#if TCL_MAJOR_VERSION > 8
    size_t numItems;		/* The number of valid items in items field. */
#else
    int numItems;
#endif
    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. */







|















|



<
|
<
<
<







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298



299
300
301
302
303
304
305
				 * 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
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    char *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */

    int numItems;		/* The number of valid items in items field. */



    Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
				/* Items used to hold old values. */
    struct Tk_SavedOptions *nextPtr;
				/* Points to next structure in list; needed if
				 * too many options changed to hold all the
				 * old values in a single structure. NULL
				 * means no more structures. */
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG

#if TCL_MAJOR_VERSION > 8
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, size_t offset);

typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, int offset);
typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
#endif

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







<
|
|
>
|
|
<
<
<
<
|
<







315
316
317
318
319
320
321

322
323
324
325
326




327

328
329
330
331
332
333
334
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG


typedef int (Tk_OptionParseProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, CONST84 char *value, char *widgRec,
	int offset));
typedef char *(Tk_OptionPrintProc) _ANSI_ARGS_((ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset,




	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
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
 * 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. */
    const 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. */
#if TCL_MAJOR_VERSION > 8
    size_t offset;			/* Where in widget record to store value; use
				 * offsetof macro to generate values for
				 * this. */
#else
    int offset;
#endif
    int specFlags;		/* Any combination of the values defined
				 * below; other bits are used internally by
				 * tkConfig.c. */
    const 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







|





<
|
|

<
<
<



<
|







345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360



361
362
363

364
365
366
367
368
369
370
371
 * 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. */
    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. */



    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
				 * irrelevant. */
} Tk_ConfigSpec;

/*
 * Type values for Tk_ConfigSpec structures. See the user documentation for
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)
#ifndef TK_NO_DEPRECATED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif /* !TK_NO_DEPRECATED */
#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */

typedef struct {
    const char *key;		/* The key string that flags the option in the
				 * argv array. */
    int type;			/* Indicates option type; see below. */
    void *src;			/* Value to be used in setting dst; usage
				 * depends on type. */
    void *dst;			/* Address of value to be modified; usage
				 * depends on type. */
    const char *help;		/* Documentation message describing this
				 * option. */
} Tk_ArgvInfo;

/*
 * Legal values for the type field of a Tk_ArgvInfo: see the user
 * documentation for details.
 */







<
|
<








|


|

|

|







396
397
398
399
400
401
402

403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)

#define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)

#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */

typedef struct {
    char *key;			/* The key string that flags the option in the
				 * argv array. */
    int type;			/* Indicates option type; see below. */
    char *src;			/* Value to be used in setting dst; usage
				 * depends on type. */
    char *dst;			/* Address of value to be modified; usage
				 * depends on type. */
    char *help;			/* Documentation message describing this
				 * option. */
} Tk_ArgvInfo;

/*
 * Legal values for the type field of a Tk_ArgvInfo: see the user
 * documentation for details.
 */
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621
622
623
#define TK_IGNORE_NEWLINES	16

/*
 * Widget class procedures used to implement platform specific widget
 * behavior.
 */

typedef Window (Tk_ClassCreateProc) (Tk_Window tkwin, Window parent,
	ClientData instanceData);
typedef void (Tk_ClassWorldChangedProc) (ClientData instanceData);
typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr);


typedef struct Tk_ClassProcs {
#if TCL_MAJOR_VERSION > 8
    size_t size;
#else
    unsigned int size;
#endif
    Tk_ClassWorldChangedProc *worldChangedProc;
				/* 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. */







|
|
|
|
>


<
<
<

<







551
552
553
554
555
556
557
558
559
560
561
562
563
564



565

566
567
568
569
570
571
572
#define TK_IGNORE_NEWLINES	16

/*
 * Widget class procedures used to implement platform specific widget
 * behavior.
 */

typedef Window (Tk_ClassCreateProc) _ANSI_ARGS_((Tk_Window tkwin,
	Window parent, ClientData instanceData));
typedef void (Tk_ClassWorldChangedProc) _ANSI_ARGS_((ClientData instanceData));
typedef void (Tk_ClassModalProc) _ANSI_ARGS_((Tk_Window tkwin,
	XEvent *eventPtr));

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
				 * world (font changes, etc.) */
    Tk_ClassCreateProc *createProc;
				/* Procedure to invoke when the platform-
				 * dependent window needs to be created. */
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((who)->size <= offsetof(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((procs)->size <= offsetof(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.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostContentProc) (ClientData clientData, Tk_Window tkwin);


typedef struct Tk_GeomMgr {
    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 content's
				 * requested geometry changes. */
    Tk_GeomLostContentProc *lostContentProc;
				/* Procedure to invoke when content is taken
				 * away from one geometry manager by another.
				 * NULL means geometry manager doesn't care
				 * when content lost. */
} Tk_GeomMgr;

/*
 * Result values returned by Tk_GetScrollInfo:
 */

#define TK_SCROLL_MOVETO	1







|




|







|
|
|
>






|

|
|


|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((who)->size <= Tk_Offset(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((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.
 */

typedef void (Tk_GeomRequestProc) _ANSI_ARGS_((ClientData clientData,
	Tk_Window tkwin));
typedef void (Tk_GeomLostSlaveProc) _ANSI_ARGS_((ClientData clientData,
	Tk_Window tkwin));

typedef struct Tk_GeomMgr {
    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. */
} Tk_GeomMgr;

/*
 * Result values returned by Tk_GetScrollInfo:
 */

#define TK_SCROLL_MOVETO	1
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
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 occurred 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. */







|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
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. */
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
    (((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
#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)
#ifndef TK_NO_DEPRECATED
#define Tk_InternalBorderWidth(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#endif /* !TK_NO_DEPRECATED */
#define Tk_InternalBorderLeft(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderRight)
#define Tk_InternalBorderTop(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \







|


<







731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
    (((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
#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)

#define Tk_InternalBorderLeft(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderRight)
#define Tk_InternalBorderTop(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
    Tk_Uid classUid;
    XWindowChanges changes;
    unsigned int dummy6;	/* dirtyChanges */
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    ClientData *dummy10;	/* tagPtr */
    int dummy11;		/* numTags */
    int dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    ClientData dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    ClientData dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    int dummy20;
#endif /* TK_USE_INPUT_METHODS */
    char *dummy21;		/* geomMgrName */
    Tk_Window dummy22;		/* maintainerPtr */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC dummy9;			/* inputContext */
    int dummy20;
#endif /* TK_USE_INPUT_METHODS */
} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.







|



















<
<
<
<
<
<
<
<
<







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804









805
806
807
808
809
810
811
    Tk_Uid classUid;
    XWindowChanges changes;
    unsigned int dummy6;	/* dirtyChanges */
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#ifdef TK_USE_INPUT_METHODS
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    ClientData *dummy10;	/* tagPtr */
    int dummy11;		/* numTags */
    int dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    ClientData dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    ClientData dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;









} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.
900
901
902
903
904
905
906



907
908
909
910
911
912
913
 *				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.



 * 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.







>
>
>







840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
 *				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.
 * 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_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.
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

973
974
975

976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
 *				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].
 * TK_CAN_INPUT_TEXT            1 means that this window accepts text input.
 *                              Used on macOS to indicate that key events can be
 *                              processed with the NSTextInputClient protocol.
 *                              Not currently accessible through the public API.
 */

#define TK_MAPPED		1
#define TK_TOP_LEVEL		2
#define TK_ALREADY_DEAD		4
#define TK_NEED_CONFIG_NOTIFY	8
#define TK_GRAB_FLAG		0x10
#define TK_CHECKED_IC		0x20
#define TK_DONT_DESTROY_WINDOW	0x40
#define TK_WM_COLORMAP_WINDOW	0x80
#define TK_EMBEDDED		0x100
#define TK_CONTAINER		0x200
#define TK_BOTH_HALVES		0x400

#define TK_WRAPPER		0x1000
#define TK_REPARENTED		0x2000
#define TK_ANONYMOUS_WINDOW	0x4000
#define TK_HAS_WRAPPER		0x8000
#define TK_WIN_MANAGED		0x10000
#define TK_TOP_HIERARCHY	0x20000
#define TK_PROP_PROPCHANGE	0x40000
#define TK_WM_MANAGEABLE	0x80000
#define TK_CAN_INPUT_TEXT       0x100000

/*
 *----------------------------------------------------------------------
 *
 * Procedure prototypes and structures used for defining new canvas items:
 *
 *----------------------------------------------------------------------
 */

typedef enum {
    TK_STATE_NULL = -1, TK_STATE_ACTIVE, TK_STATE_DISABLED,
    TK_STATE_NORMAL, TK_STATE_HIDDEN
} Tk_State;

typedef struct Tk_SmoothMethod {
    const char *name;

    int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints,
	    int numSteps, XPoint xPoints[], double dblPoints[]);
    void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas,

	    double *coordPtr, int numPoints, int numSteps);
} 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.
 */

#define TK_TAG_SPACE 3

typedef struct Tk_Item {
#if TCL_MAJOR_VERSION > 8
    size_t id;		/* Unique identifier for this item (also
				 * serves as first tag for item). */
#else
    int id;
#endif
    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. */
#if TCL_MAJOR_VERSION > 8
    size_t tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    size_t numTags;		/* Number of tag slots actually used at
				 * *tagPtr. */
#else
    int tagSpace, numTags;
#endif
    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. */







<
<
<
<













|








<















|
>
|
|
|
>
|











<
|

<
<
<








<
|

|

<
<
<







866
867
868
869
870
871
872




873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927

928
929



930
931
932
933
934
935
936
937

938
939
940
941



942
943
944
945
946
947
948
 *				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
#define TK_NEED_CONFIG_NOTIFY	8
#define TK_GRAB_FLAG		0x10
#define TK_CHECKED_IC		0x20
#define TK_DONT_DESTROY_WINDOW	0x40
#define TK_WM_COLORMAP_WINDOW	0x80
#define TK_EMBEDDED		0x100
#define TK_CONTAINER		0x200
#define TK_BOTH_HALVES		0x400
#define TK_DEFER_MODAL		0x800
#define TK_WRAPPER		0x1000
#define TK_REPARENTED		0x2000
#define TK_ANONYMOUS_WINDOW	0x4000
#define TK_HAS_WRAPPER		0x8000
#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:
 *
 *----------------------------------------------------------------------
 */

typedef enum {
    TK_STATE_NULL = -1, TK_STATE_ACTIVE, TK_STATE_DISABLED,
    TK_STATE_NORMAL, TK_STATE_HIDDEN
} Tk_State;

typedef struct Tk_SmoothMethod {
    char *name;
    int (*coordProc) _ANSI_ARGS_((Tk_Canvas canvas,
		double *pointPtr, int numPoints, int numSteps,
		XPoint xPoints[], double dblPoints[]));
    void (*postscriptProc) _ANSI_ARGS_((Tcl_Interp *interp,
		Tk_Canvas canvas, double *coordPtr,
		int numPoints, int numSteps));
} 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.
 */

#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. */
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058


1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112


1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
#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.
 */

#if defined(USE_OLD_CANVAS) && TCL_MAJOR_VERSION < 9
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv, int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);


typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, char *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, char *indexString, int *indexPtr);
#else
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[],
		    int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const argv[]);
#if TCL_MAJOR_VERSION > 8
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, size_t *indexPtr);
#else
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr);
#endif
#endif /* USE_OLD_CANVAS */
typedef void	(Tk_ItemDeleteProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display);
typedef void	(Tk_ItemDisplayProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display, Drawable dst, int x, int y, int width,
		    int height);
typedef double	(Tk_ItemPointProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *pointPtr);
typedef int	(Tk_ItemAreaProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *rectPtr);
typedef int	(Tk_ItemPostscriptProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int prepass);
typedef void	(Tk_ItemRotateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double angleRadians);
typedef void	(Tk_ItemScaleProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double scaleX,
		    double scaleY);
typedef void	(Tk_ItemTranslateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double deltaX, double deltaY);
#if TCL_MAJOR_VERSION > 8

typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t index);
typedef size_t	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t offset, char *buffer, size_t maxBytes);
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t first, size_t last);
#else
typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int index);
typedef int	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int offset, char *buffer, int maxBytes);


typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,

		    int first, int last);
#endif

#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    const char *name;		/* The name of this type of item, such as
				 * "line". */
#if TCL_MAJOR_VERSION > 8
    size_t itemSize;		/* Total amount of space needed for item's
				 * record. */
#else
    int itemSize;
#endif
    Tk_ItemCreateProc *createProc;
				/* Procedure to create a new item of this
				 * type. */
    const 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. */







|
|
|
<
|
|
|
>
>
|
|
<
<

|
|
<
|
<
|
<
<
|
|
|
<
<
|
|
<
<

<
|
|
|
|
|
|
|
|
|
|
|
<
<
|
|
|
|
|
<
>
|
|
<
<
<
<
<
|
|
|
|
>
>
|
>
|
<




|

<
|

<
<
<



|







977
978
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993


994
995
996

997

998


999
1000
1001


1002
1003


1004

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015


1016
1017
1018
1019
1020

1021
1022
1023





1024
1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038

1039
1040



1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
#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.
 */

#ifdef USE_OLD_CANVAS
typedef int	Tk_ItemCreateProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,

		    char **argv));
typedef int	Tk_ItemConfigureProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
		    char **argv, int flags));
typedef int	Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
		    char **argv));


#else
typedef int	Tk_ItemCreateProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,

		    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));
typedef int	Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp,


		    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
		    Tcl_Obj *const argv[]));


#endif

typedef void	Tk_ItemDeleteProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, Display *display));
typedef void	Tk_ItemDisplayProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, Display *display, Drawable dst,
		    int x, int y, int width, int height));
typedef double	Tk_ItemPointProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, double *pointPtr));
typedef int	Tk_ItemAreaProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, double *rectPtr));
typedef int	Tk_ItemPostscriptProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));


typedef void	Tk_ItemScaleProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, double originX, double originY,
		    double scaleX, double scaleY));
typedef void	Tk_ItemTranslateProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, double deltaX, double deltaY));

typedef int	Tk_ItemIndexProc _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_Canvas canvas, Tk_Item *itemPtr, char *indexString,
		    int *indexPtr));





typedef void	Tk_ItemCursorProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, int index));
typedef int	Tk_ItemSelectionProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, int offset, char *buffer,
		    int maxBytes));
typedef void	Tk_ItemInsertProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, int beforeThis, char *string));
typedef void	Tk_ItemDCharsProc _ANSI_ARGS_((Tk_Canvas canvas,
		    Tk_Item *itemPtr, int first, int last));


#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    char *name;			/* The name of this type of item, such as
				 * "line". */

    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. */
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
    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. */
    Tk_ItemRotateProc *rotateProc;
				/* Procedure to rotate an item's coordinates
				 * about a point. */
    int reserved2;		/* Carefully compatible with */
    char *reserved3;		/* Jan Nijtmans dash patch */
    char *reserved4;
} Tk_ItemType;

/*
 * Flag (used in the alwaysRedraw field) to say whether an item supports
 * point-level manipulation like the line and polygon items.
 */

#define TK_MOVABLE_POINTS	2

#endif /* __NO_OLD_CONFIG */

/*
 * 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. */
    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. */
#if TCL_MAJOR_VERSION > 8
    size_t selectFirst;		/* Character index of first selected
				 * character. Writable by items. */
    size_t selectLast;		/* Character index of last selected character.
				 * Writable by items. */
#else
    int selectFirst, selectLast;
#endif
    Tk_Item *anchorItemPtr;	/* Item corresponding to "selectAnchor": not
				 * necessarily selItemPtr. Read-only to
				 * items. */
#if TCL_MAJOR_VERSION > 8
    size_t 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. */
#else
    int selectAnchor;
#endif
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * 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







<
<
|





<
<
<
<
<
<
<
|



















<
|

|

<
<
<



<
|



<
<
<







1080
1081
1082
1083
1084
1085
1086


1087
1088
1089
1090
1091
1092







1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116



1117
1118
1119

1120
1121
1122
1123



1124
1125
1126
1127
1128
1129
1130
    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.
 */

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. */
    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. */

    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). 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
				 * 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
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319

1320
1321
1322

1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
typedef struct Tk_TSOffset {
    int flags;			/* Flags; see below for possible values */
    int xoffset;		/* x offset */
    int yoffset;		/* y offset */
} Tk_TSOffset;

/*
 * Bit fields in Tk_TSOffset->flags:
 */

#define TK_OFFSET_INDEX		1
#define TK_OFFSET_RELATIVE	2
#define TK_OFFSET_LEFT		4
#define TK_OFFSET_CENTER	8
#define TK_OFFSET_RIGHT		16
#define TK_OFFSET_TOP		32
#define TK_OFFSET_MIDDLE	64
#define TK_OFFSET_BOTTOM	128

typedef struct Tk_Outline {
    GC gc;			/* Graphics context. */
    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. */
    void *reserved2;
    void *reserved3;
    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. */
} Tk_Outline;

/*
 *----------------------------------------------------------------------
 *
 * Procedure prototypes and structures used for managing images:
 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && defined(USE_OLD_IMAGE)
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
	char **argv, Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#else
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, int objc,
	Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#endif /* USE_OLD_IMAGE */
typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData clientData);

typedef void (Tk_ImageDisplayProc) (ClientData clientData, Display *display,
	Drawable drawable, int imageX, int imageY, int width, int height,
	int drawableX, int drawableY);
typedef void (Tk_ImageFreeProc) (ClientData clientData, Display *display);

typedef void (Tk_ImageDeleteProc) (ClientData clientData);
typedef void (Tk_ImageChangedProc) (ClientData clientData, int x, int y,
	int width, int height, int imageWidth, int imageHeight);

typedef int (Tk_ImagePostscriptProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo,
	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.
 */

struct Tk_ImageType {
    const char *name;		/* Name of image type. */
    Tk_ImageCreateProc *createProc;
				/* 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_ImageDisplayProc *displayProc;







|




















|
|
|




















|
|
|
|

|
|
|
|
|
>
|
|
|
|
>
|
|
|
>
|

|










|







1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
typedef struct Tk_TSOffset {
    int flags;			/* Flags; see below for possible values */
    int xoffset;		/* x offset */
    int yoffset;		/* y offset */
} Tk_TSOffset;

/*
 * Bit fields in Tk_Offset->flags:
 */

#define TK_OFFSET_INDEX		1
#define TK_OFFSET_RELATIVE	2
#define TK_OFFSET_LEFT		4
#define TK_OFFSET_CENTER	8
#define TK_OFFSET_RIGHT		16
#define TK_OFFSET_TOP		32
#define TK_OFFSET_MIDDLE	64
#define TK_OFFSET_BOTTOM	128

typedef struct Tk_Outline {
    GC gc;			/* Graphics context. */
    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. */
    VOID *reserved2;
    VOID *reserved3;
    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. */
} Tk_Outline;

/*
 *----------------------------------------------------------------------
 *
 * Procedure prototypes and structures used for managing images:
 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageCreateProc) _ANSI_ARGS_((Tcl_Interp *interp,
	char *name, int argc, char **argv, Tk_ImageType *typePtr,
	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,
	Tk_ImageMaster master, ClientData *masterDataPtr));
#endif
typedef ClientData (Tk_ImageGetProc) _ANSI_ARGS_((Tk_Window tkwin,
	ClientData masterData));
typedef void (Tk_ImageDisplayProc) _ANSI_ARGS_((ClientData instanceData,
	Display *display, Drawable drawable, int imageX, int imageY,
	int width, int height, int drawableX, int drawableY));
typedef void (Tk_ImageFreeProc) _ANSI_ARGS_((ClientData instanceData,
	Display *display));
typedef void (Tk_ImageDeleteProc) _ANSI_ARGS_((ClientData masterData));
typedef void (Tk_ImageChangedProc) _ANSI_ARGS_((ClientData clientData,
	int x, int y, int width, int height, int imageWidth,
	int imageHeight));
typedef int (Tk_ImagePostscriptProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo,
	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.
 */

struct Tk_ImageType {
    char *name;			/* Name of image type. */
    Tk_ImageCreateProc *createProc;
				/* 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_ImageDisplayProc *displayProc;
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
1423

1424
1425

1426
1427
1428

1429
1430

1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
/*
 * Procedure prototypes and structures used in reading and writing photo
 * images:
 */

typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat;
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, char *fileName,
	char *formatString, int *widthPtr, int *heightPtr);
typedef int (Tk_ImageStringMatchProc) (char *string, char *formatString,
	int *widthPtr, int *heightPtr);
typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan,
	char *fileName, char *formatString, Tk_PhotoHandle imageHandle,

	int destX, int destY, int width, int height, int srcX, int srcY);
typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, char *string,
	char *formatString, Tk_PhotoHandle imageHandle, int destX, int destY,
	int width, int height, int srcX, int srcY);
typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, char *fileName,
	char *formatString, Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp,
	Tcl_DString *dataPtr, char *formatString, Tk_PhotoImageBlock *blockPtr);

#else
typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, const char *fileName,

	Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp);
typedef int (Tk_ImageStringMatchProc) (Tcl_Obj *dataObj, Tcl_Obj *format,
	int *widthPtr, int *heightPtr, Tcl_Interp *interp);

typedef int (Tk_ImageFileReadProc) (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);
typedef int (Tk_ImageStringReadProc) (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) (Tcl_Interp *interp, const char *fileName,
	Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format,
	Tk_PhotoImageBlock *blockPtr);
#endif /* USE_OLD_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 {
    const char *name;		/* Name of image file format */
    Tk_ImageFileMatchProc *fileMatchProc;
				/* 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. */
    Tk_ImageFileReadProc *fileReadProc;







|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
>

|
>
|
|
|
>
|
|
>
|
|
|
|
|
|
|
|
|








|







1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
/*
 * Procedure prototypes and structures used in reading and writing photo
 * images:
 */

typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat;
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageFileMatchProc) _ANSI_ARGS_((Tcl_Channel chan,
	char *fileName, char *formatString, int *widthPtr, int *heightPtr));
typedef int (Tk_ImageStringMatchProc) _ANSI_ARGS_((char *string,
	char *formatString, int *widthPtr, int *heightPtr));
typedef int (Tk_ImageFileReadProc) _ANSI_ARGS_((Tcl_Interp *interp,
	Tcl_Channel chan, char *fileName, char *formatString,
	Tk_PhotoHandle imageHandle, int destX, int destY,
	int width, int height, int srcX, int srcY));
typedef int (Tk_ImageStringReadProc) _ANSI_ARGS_((Tcl_Interp *interp,
	char *string, char *formatString, Tk_PhotoHandle imageHandle,
	int destX, int destY, int width, int height, int srcX, int srcY));
typedef int (Tk_ImageFileWriteProc) _ANSI_ARGS_((Tcl_Interp *interp,
	char *fileName, char *formatString, Tk_PhotoImageBlock *blockPtr));
typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp,
	Tcl_DString *dataPtr, char *formatString,
	Tk_PhotoImageBlock *blockPtr));
#else
typedef int (Tk_ImageFileMatchProc) _ANSI_ARGS_((Tcl_Channel chan,
	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,
	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));
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.
 */

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. */
    Tk_ImageStringMatchProc *stringMatchProc;
				/* Procedure to call to determine whether the
				 * data in a string matches this format. */
    Tk_ImageFileReadProc *fileReadProc;
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
#define TK_STYLE_VERSION        TK_STYLE_VERSION_1

/*
 * The following structures and prototypes are used as static templates to
 * declare widget elements.
 */

typedef void (Tk_GetElementSizeProc) (ClientData clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int width,
	int height, int inner, int *widthPtr, int *heightPtr);
typedef void (Tk_GetElementBoxProc) (ClientData clientData, 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) (ClientData clientData,
	char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin);
typedef void (Tk_DrawElementProc) (ClientData clientData, 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 {
    char *name;			/* Name of the required option. */
    Tk_OptionType type;		/* Accepted option type. TK_OPTION_END means
				 * any. */
} Tk_ElementOptionSpec;

typedef struct Tk_ElementSpec {
    int version;		/* Version of the style support. */
    char *name;			/* Name of element. */
    Tk_ElementOptionSpec *options;
				/* List of required options. Last one's name
				 * must be NULL. */
    Tk_GetElementSizeProc *getSize;
				/* 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_ElementSpec;

/*
 * Element state flags. Can be OR'ed.
 */







|
|
|
|
|
|
|
|
|
|
|
|


|
|
|



|
|

|
|

|
|
|

|
|

|
|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
#define TK_STYLE_VERSION        TK_STYLE_VERSION_1

/*
 * The following structures and prototypes are used as static templates to
 * declare widget elements.
 */

typedef void (Tk_GetElementSizeProc) _ANSI_ARGS_((ClientData clientData,
        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,
        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));
typedef void (Tk_DrawElementProc) _ANSI_ARGS_((ClientData clientData,
        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 {
    char *name;                 /* Name of the required option. */
    Tk_OptionType type;         /* Accepted option type. TK_OPTION_END means
                                 * any. */
} Tk_ElementOptionSpec;

typedef struct Tk_ElementSpec {
    int version;                /* Version of the style support. */
    char *name;                 /* Name of element. */
    Tk_ElementOptionSpec *options;
                                /* List of required options. Last one's name
                                 * must be NULL. */
    Tk_GetElementSizeProc *getSize;
                                /* 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_ElementSpec;

/*
 * Element state flags. Can be OR'ed.
 */
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
 * 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.
 *
 *----------------------------------------------------------------------
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#define TK_READABLE		TCL_READABLE
#define TK_WRITABLE		TCL_WRITABLE
#define TK_EXCEPTION		TCL_EXCEPTION

#define TK_DONT_WAIT		TCL_DONT_WAIT
#define TK_X_EVENTS		TCL_WINDOW_EVENTS
#define TK_WINDOW_EVENTS	TCL_WINDOW_EVENTS







<







1449
1450
1451
1452
1453
1454
1455

1456
1457
1458
1459
1460
1461
1462
 * 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.
 *
 *----------------------------------------------------------------------
 */


#define TK_READABLE		TCL_READABLE
#define TK_WRITABLE		TCL_WRITABLE
#define TK_EXCEPTION		TCL_EXCEPTION

#define TK_DONT_WAIT		TCL_DONT_WAIT
#define TK_X_EVENTS		TCL_WINDOW_EVENTS
#define TK_WINDOW_EVENTS	TCL_WINDOW_EVENTS
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595





1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617

1618

1619

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638

/* Additional stuff that has moved to Tcl: */

#define Tk_EventuallyFree	Tcl_EventuallyFree
#define Tk_FreeProc		Tcl_FreeProc
#define Tk_Preserve		Tcl_Preserve
#define Tk_Release		Tcl_Release
#endif

/* Removed Tk_Main, use macro instead */

#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)()))
#endif





const char *		Tk_InitStubs(Tcl_Interp *interp, const char *version,
				int exact);
EXTERN const char *	Tk_PkgInitStubsCheck(Tcl_Interp *interp,
				const char *version, int exact);

#ifndef USE_TK_STUBS
#define Tk_InitStubs(interp, version, exact) \
    Tk_PkgInitStubsCheck(interp, version, exact)
#endif /* USE_TK_STUBS */

#define Tk_InitImageArgs(interp, argc, argv) /**/

/*
 *----------------------------------------------------------------------
 *
 * Additional procedure types defined by Tk.
 *
 *----------------------------------------------------------------------
 */


typedef int (Tk_ErrorProc) (ClientData clientData, XErrorEvent *errEventPtr);
typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr);

typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr);

typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr);

typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp,
	const char *portion);
typedef void (Tk_LostSelProc) (ClientData clientData);
typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData,
	XEvent *eventPtr);
#if TCL_MAJOR_VERSION > 8
typedef size_t (Tk_SelectionProc) (ClientData clientData, size_t offset,
	char *buffer, size_t maxBytes);
#else
typedef int (Tk_SelectionProc) (ClientData clientData, int offset,
	char *buffer, int maxBytes);
#endif

/*
 *----------------------------------------------------------------------
 *
 * Platform independent exported procedures and variables.
 *
 *----------------------------------------------------------------------







<


>







>
>
>
>
>
|
|
|
|
















>
|
|
>
|
>
|
>
|
|
|
|
|
<
<
<
<
|
|
<







1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536




1537
1538

1539
1540
1541
1542
1543
1544
1545

/* Additional stuff that has moved to Tcl: */

#define Tk_EventuallyFree	Tcl_EventuallyFree
#define Tk_FreeProc		Tcl_FreeProc
#define Tk_Preserve		Tcl_Preserve
#define Tk_Release		Tcl_Release


/* Removed Tk_Main, use macro instead */
#if TCL_MINOR_VERSION > 5
#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)()))
#endif
#else
#define Tk_Main(argc, argv, proc) \
    Tk_MainEx(argc, argv, proc, (Tcl_CreateInterp)())
#endif

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) \
    Tk_PkgInitStubsCheck(interp, version, exact)
#endif /* USE_TK_STUBS */

#define Tk_InitImageArgs(interp, argc, argv) /**/

/*
 *----------------------------------------------------------------------
 *
 * Additional procedure types defined by Tk.
 *
 *----------------------------------------------------------------------
 */

typedef int (Tk_ErrorProc) _ANSI_ARGS_((ClientData clientData,
	XErrorEvent *errEventPtr));
typedef void (Tk_EventProc) _ANSI_ARGS_((ClientData clientData,
	XEvent *eventPtr));
typedef int (Tk_GenericProc) _ANSI_ARGS_((ClientData clientData,
	XEvent *eventPtr));
typedef int (Tk_ClientMessageProc) _ANSI_ARGS_((Tk_Window tkwin,
	XEvent *eventPtr));
typedef int (Tk_GetSelProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, char *portion));
typedef void (Tk_LostSelProc) _ANSI_ARGS_((ClientData clientData));
typedef Tk_RestrictAction (Tk_RestrictProc) _ANSI_ARGS_((
	ClientData clientData, XEvent *eventPtr));




typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
	int offset, char *buffer, int maxBytes));


/*
 *----------------------------------------------------------------------
 *
 * Platform independent exported procedures and variables.
 *
 *----------------------------------------------------------------------
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
#define Tk_CreatePhotoImageFormat	Tk_CreateOldPhotoImageFormat
#endif /* USE_OLD_IMAGE */

/*
 *----------------------------------------------------------------------
 *
 * Allow users to say that they don't want to alter their source to add extra
 * arguments to Tk_PhotoPutBlock() et al.
 *
 * This goes after the inclusion of the stubbed-decls so that the declarations
 * of what is actually there can be correct.
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
#   ifdef Tk_PhotoPutBlock
#	undef Tk_PhotoPutBlock
#   endif
#   define Tk_PhotoPutBlock		Tk_PhotoPutBlock_NoComposite
#   ifdef Tk_PhotoPutZoomedBlock
#	undef Tk_PhotoPutZoomedBlock







|





<







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
#define Tk_CreatePhotoImageFormat	Tk_CreateOldPhotoImageFormat
#endif /* USE_OLD_IMAGE */

/*
 *----------------------------------------------------------------------
 *
 * 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.
 */


#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
#   ifdef Tk_PhotoPutBlock
#	undef Tk_PhotoPutBlock
#   endif
#   define Tk_PhotoPutBlock		Tk_PhotoPutBlock_NoComposite
#   ifdef Tk_PhotoPutZoomedBlock
#	undef Tk_PhotoPutZoomedBlock
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
#   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 */
#endif /* !TK_NO_DEPRECATED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*







<







1592
1593
1594
1595
1596
1597
1598

1599
1600
1601
1602
1603
1604
1605
#   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 */


#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*

Changes to generic/tk3d.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "tk3d.h"

/*
 * The following table defines the string values for reliefs, which are used
 * by Tk_GetReliefFromObj.
 */

static const char *const reliefStrings[] = {
    "flat", "groove", "raised", "ridge", "solid", "sunken", NULL
};

/*
 * Forward declarations for functions defined in this file:
 */

static void		BorderInit(TkDisplay *dispPtr);
static void		DupBorderObjProc(Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr);
static void		FreeBorderObj(Tcl_Obj *objPtr);
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
 * object, used for drawing. The border object remembers the hash table entry
 * associated with a border. The actual allocation and deallocation of the
 * border should be done by the configuration package when the border option
 * is set.
 */

const Tcl_ObjType tkBorderObjType = {
    "border",			/* name */
    FreeBorderObjProc,		/* freeIntRepProc */
    DupBorderObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};








|










<















|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "tk3d.h"

/*
 * 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", NULL
};

/*
 * Forward declarations for functions defined in this file:
 */

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
 * object, used for drawing. The border object remembers the hash table entry
 * associated with a border. The actual allocation and deallocation of the
 * border should be done by the configuration package when the border option
 * is set.
 */

Tcl_ObjType tkBorderObjType = {
    "border",			/* name */
    FreeBorderObjProc,		/* freeIntRepProc */
    DupBorderObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
 *	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 function, there should eventually be a call to
 *	FreeBorderObj so that the database is cleaned up when borders aren't
 *	in use anymore.
 *
 *----------------------------------------------------------------------
 */

Tk_3DBorder
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;

    if (objPtr->typePtr != &tkBorderObjType) {
	InitBorderObj(objPtr);
    }
    borderPtr = (TkBorder *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBorder, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (borderPtr != NULL) {
	if (borderPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a border that's no
	     * longer in use. Clear the reference.
	     */

	    FreeBorderObj(objPtr);
	    borderPtr = NULL;
	} else if ((Tk_Screen(tkwin) == borderPtr->screen)
		&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	    borderPtr->resourceRefCount++;
	    return (Tk_3DBorder) borderPtr;
	}
    }

    /*
     * The object didn't point to the border that we wanted. Search the list
     * of borders with the same name to see if one of the others is the right
     * one.

     *

     * If the cached value is NULL, either the object type was not a color
     * going in, or the object is a color type but had previously been freed.
     *
     * If the value is not NULL, the internal rep is the value of the color
     * the last time this object was accessed. Check the screen and colormap
     * of the last access, and if they match, we are done.
     */

    if (borderPtr != NULL) {
	TkBorder *firstBorderPtr = (TkBorder *)Tcl_GetHashValue(borderPtr->hashPtr);

	FreeBorderObj(objPtr);
	for (borderPtr = firstBorderPtr ; borderPtr != NULL;
		borderPtr = borderPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == borderPtr->screen)
		    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
		borderPtr->resourceRefCount++;
		borderPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = borderPtr;
		return (Tk_3DBorder) borderPtr;
	    }
	}
    }

    /*
     * Still no luck. Call Tk_Get3DBorder to allocate a new border.
     */

    borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin,
	    Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = borderPtr;
    if (borderPtr != NULL) {
	borderPtr->objRefCount++;
    }
    return (Tk_3DBorder) borderPtr;
}

/*







|
|
















|













|












>
|
>









|
|
|



|


|











|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
 *	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 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(
    Tcl_Interp *interp,		/* Interp for error results. */
    Tk_Window tkwin,		/* Need the screen the border is used on.*/
    Tcl_Obj *objPtr)		/* Object giving name of color for window
				 * background. */
{
    TkBorder *borderPtr;

    if (objPtr->typePtr != &tkBorderObjType) {
	InitBorderObj(objPtr);
    }
    borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBorder, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (borderPtr != NULL) {
	if (borderPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a border that's no
	     * longer in use. Clear the reference.
	     */

	    FreeBorderObjProc(objPtr);
	    borderPtr = NULL;
	} else if ((Tk_Screen(tkwin) == borderPtr->screen)
		&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	    borderPtr->resourceRefCount++;
	    return (Tk_3DBorder) borderPtr;
	}
    }

    /*
     * The object didn't point to the border that we wanted. Search the list
     * of borders with the same name to see if one of the others is the right
     * one.
     */

    /*
     * If the cached value is NULL, either the object type was not a color
     * going in, or the object is a color type but had previously been freed.
     *
     * If the value is not NULL, the internal rep is the value of the color
     * the last time this object was accessed. Check the screen and colormap
     * of the last access, and if they match, we are done.
     */

    if (borderPtr != NULL) {
	TkBorder *firstBorderPtr =
		(TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr);
	FreeBorderObjProc(objPtr);
	for (borderPtr = firstBorderPtr ; borderPtr != NULL;
		borderPtr = borderPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == borderPtr->screen)
		&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
		borderPtr->resourceRefCount++;
		borderPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
		return (Tk_3DBorder) borderPtr;
	    }
	}
    }

    /*
     * Still no luck. Call Tk_Get3DBorder to allocate a new border.
     */

    borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin,
	    Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
    if (borderPtr != NULL) {
	borderPtr->objRefCount++;
    }
    return (Tk_3DBorder) borderPtr;
}

/*
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

    if (!dispPtr->borderInit) {
	BorderInit(dispPtr);
    }

    hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew);
    if (!isNew) {
	existingBorderPtr = (TkBorder *)Tcl_GetHashValue(hashPtr);
	for (borderPtr = existingBorderPtr; borderPtr != NULL;
		borderPtr = borderPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == borderPtr->screen)
		    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
		borderPtr->resourceRefCount++;
		return (Tk_3DBorder) borderPtr;
	    }







|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

    if (!dispPtr->borderInit) {
	BorderInit(dispPtr);
    }

    hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew);
    if (!isNew) {
	existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);
	for (borderPtr = existingBorderPtr; borderPtr != NULL;
		borderPtr = borderPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == borderPtr->screen)
		    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
		borderPtr->resourceRefCount++;
		return (Tk_3DBorder) borderPtr;
	    }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOf3DBorder(
    Tk_3DBorder border)		/* Token for border. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    return borderPtr->hashPtr->key.string;
}







|







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOf3DBorder(
    Tk_3DBorder border)		/* Token for border. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    return borderPtr->hashPtr->key.string;
}
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
Tk_Free3DBorder(
    Tk_3DBorder border)		/* Token for border to be released. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    Display *display = DisplayOfScreen(borderPtr->screen);
    TkBorder *prevPtr;


    if (borderPtr->resourceRefCount-- > 1) {
	return;
    }

    prevPtr = (TkBorder *)Tcl_GetHashValue(borderPtr->hashPtr);
    TkpFreeBorder(borderPtr);
    if (borderPtr->bgColorPtr != NULL) {
	Tk_FreeColor(borderPtr->bgColorPtr);
    }
    if (borderPtr->darkColorPtr != NULL) {
	Tk_FreeColor(borderPtr->darkColorPtr);
    }







>
|



|







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
Tk_Free3DBorder(
    Tk_3DBorder border)		/* Token for border to be released. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    Display *display = DisplayOfScreen(borderPtr->screen);
    TkBorder *prevPtr;

    borderPtr->resourceRefCount--;
    if (borderPtr->resourceRefCount > 0) {
	return;
    }

    prevPtr = (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr);
    TkpFreeBorder(borderPtr);
    if (borderPtr->bgColorPtr != NULL) {
	Tk_FreeColor(borderPtr->bgColorPtr);
    }
    if (borderPtr->darkColorPtr != NULL) {
	Tk_FreeColor(borderPtr->darkColorPtr);
    }
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
    } else {
	while (prevPtr->nextPtr != borderPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = borderPtr->nextPtr;
    }
    if (borderPtr->objRefCount == 0) {
	ckfree(borderPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_Free3DBorderFromObj --







|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
    } else {
	while (prevPtr->nextPtr != borderPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = borderPtr->nextPtr;
    }
    if (borderPtr->objRefCount == 0) {
	ckfree((char *) borderPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_Free3DBorderFromObj --
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
void
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));
    FreeBorderObj(objPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeBorderObjProc, FreeBorderObj --
 *
 *	This proc is called to release an object reference to a border. Called
 *	when the object's internal rep is released or when the cached
 *	borderPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the border's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeBorderObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    FreeBorderObj(objPtr);
    objPtr->typePtr = NULL;
}

static void
FreeBorderObj(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    TkBorder *borderPtr = (TkBorder *)objPtr->internalRep.twoPtrValue.ptr1;

    if (borderPtr != NULL) {
	borderPtr->objRefCount--;
	if ((borderPtr->objRefCount == 0)
		&& (borderPtr->resourceRefCount == 0)) {
	    ckfree(borderPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------







|





|



















<
<
<
<
<
<
<
<
|





|







490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522








523
524
525
526
527
528
529
530
531
532
533
534
535
536
void
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);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeBorderObjProc --
 *
 *	This proc is called to release an object reference to a border. Called
 *	when the object's internal rep is released or when the cached
 *	borderPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the border's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeBorderObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{








    TkBorder *borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1;

    if (borderPtr != NULL) {
	borderPtr->objRefCount--;
	if ((borderPtr->objRefCount == 0)
		&& (borderPtr->resourceRefCount == 0)) {
	    ckfree((char *) borderPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
 */

static void
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 = borderPtr;

    if (borderPtr != NULL) {
	borderPtr->objRefCount++;
    }
}

/*







|


|







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
 */

static void
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;

    if (borderPtr != NULL) {
	borderPtr->objRefCount++;
    }
}

/*
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
 */

void
Tk_SetBackgroundFromBorder(
    Tk_Window tkwin,		/* Window whose background is to be set. */
    Tk_3DBorder border)		/* Token for border. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    Tk_SetWindowBackground(tkwin, borderPtr->bgColorPtr->pixel);
}

/*
 *----------------------------------------------------------------------
 *







|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
 */

void
Tk_SetBackgroundFromBorder(
    Tk_Window tkwin,		/* Window whose background is to be set. */
    Tk_3DBorder border)		/* Token for border. */
{
    register TkBorder *borderPtr = (TkBorder *) border;

    Tk_SetWindowBackground(tkwin, borderPtr->bgColorPtr->pixel);
}

/*
 *----------------------------------------------------------------------
 *
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
int
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_GetIndexFromObjStruct(interp, objPtr, reliefStrings,
	    sizeof(char *), "relief", 0, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRelief --
 *







|
|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
int
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,
	    resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRelief --
 *
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
 *
 *----------------------------------------------------------------------
 */

int
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;

    c = name[0];
    length = strlen(name);
    if ((c == 'f') && (strncmp(name, "flat", length) == 0)) {
	*reliefPtr = TK_RELIEF_FLAT;
    } else if ((c == 'g') && (strncmp(name, "groove", length) == 0)
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_GROOVE;
    } else if ((c == 'r') && (strncmp(name, "raised", length) == 0)
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_RAISED;
    } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)) {
	*reliefPtr = TK_RELIEF_RIDGE;
    } else if ((c == 's') && (strncmp(name, "solid", length) == 0)) {
	*reliefPtr = TK_RELIEF_SOLID;
    } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) {
	*reliefPtr = TK_RELIEF_SUNKEN;
    } else {

	Tcl_SetObjResult(interp,
		Tcl_ObjPrintf("bad relief \"%.50s\": must be %s",
		name, "flat, groove, raised, ridge, solid, or sunken"));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "RELIEF", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|











|




|





>
|
|
|
|







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
 *
 *----------------------------------------------------------------------
 */

int
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;

    c = name[0];
    length = strlen(name);
    if ((c == 'f') && (strncmp(name, "flat", length) == 0)) {
	*reliefPtr = TK_RELIEF_FLAT;
    } else if ((c == 'g') && (strncmp(name, "groove", length) == 0)
	    && (length >= 2)) {
        *reliefPtr = TK_RELIEF_GROOVE;
    } else if ((c == 'r') && (strncmp(name, "raised", length) == 0)
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_RAISED;
    } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)) {
        *reliefPtr = TK_RELIEF_RIDGE;
    } else if ((c == 's') && (strncmp(name, "solid", length) == 0)) {
	*reliefPtr = TK_RELIEF_SOLID;
    } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) {
	*reliefPtr = TK_RELIEF_SUNKEN;
    } else {
	char buf[200];

	sprintf(buf, "bad relief type \"%.50s\": must be %s",
		name, "flat, groove, raised, ridge, solid, or sunken");
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOfRelief(
    int relief)		/* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
			 * TK_RELIEF_SUNKEN. */
{
    if (relief == TK_RELIEF_FLAT) {
	return "flat";
    } else if (relief == TK_RELIEF_SUNKEN) {







|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfRelief(
    int relief)		/* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
			 * TK_RELIEF_SUNKEN. */
{
    if (relief == TK_RELIEF_FLAT) {
	return "flat";
    } else if (relief == TK_RELIEF_SUNKEN) {
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
				 * 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. */
    XPoint *p1Ptr, *p2Ptr;
    TkBorder *borderPtr = (TkBorder *) border;
    GC gc;
    int i, lightOnLeft, dx, dy, parallel, pointsSeen;
    Display *display = Tk_Display(tkwin);

    if (borderPtr->lightGC == NULL) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*
     * Handle grooves and ridges with recursive calls.
     */

    if ((leftRelief == TK_RELIEF_GROOVE) || (leftRelief == TK_RELIEF_RIDGE)) {
	int halfWidth = borderWidth/2;


	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		halfWidth, (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED
		: TK_RELIEF_SUNKEN);
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		-halfWidth, (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_SUNKEN
		: TK_RELIEF_RAISED);
	return;







|














|

>







749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
				 * 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. */
    register XPoint *p1Ptr, *p2Ptr;
    TkBorder *borderPtr = (TkBorder *) border;
    GC gc;
    int i, lightOnLeft, dx, dy, parallel, pointsSeen;
    Display *display = Tk_Display(tkwin);

    if (borderPtr->lightGC == NULL) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*
     * Handle grooves and ridges with recursive calls.
     */

    if ((leftRelief == TK_RELIEF_GROOVE) || (leftRelief == TK_RELIEF_RIDGE)) {
	int halfWidth;

	halfWidth = borderWidth/2;
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		halfWidth, (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED
		: TK_RELIEF_SUNKEN);
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		-halfWidth, (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_SUNKEN
		: TK_RELIEF_RAISED);
	return;
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
    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. */
{
    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.
     */







|







947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
    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.
     */
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
	}
    }
    doubleBorder = 2*borderWidth;

    if ((width > doubleBorder) && (height > doubleBorder)) {
	XFillRectangle(Tk_Display(tkwin), drawable, borderPtr->bgGC,
		x + borderWidth, y + borderWidth,
		(unsigned) (width - doubleBorder),
		(unsigned) (height - doubleBorder));
    }
    if (borderWidth) {
	Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width,
		height, borderWidth, relief);
    }
}








|
|







976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
	}
    }
    doubleBorder = 2*borderWidth;

    if ((width > doubleBorder) && (height > doubleBorder)) {
	XFillRectangle(Tk_Display(tkwin), drawable, borderPtr->bgGC,
		x + borderWidth, y + borderWidth,
		(unsigned int) (width - doubleBorder),
		(unsigned int) (height - doubleBorder));
    }
    if (borderWidth) {
	Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width,
		height, borderWidth, relief);
    }
}

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
				 * 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. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    XFillPolygon(Tk_Display(tkwin), drawable, borderPtr->bgGC,
	    pointPtr, numPoints, Complex, CoordModeOrigin);
    if (leftRelief != TK_RELIEF_FLAT) {
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		borderWidth, leftRelief);
    }







|







1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
				 * 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. */
{
    register TkBorder *borderPtr = (TkBorder *) border;

    XFillPolygon(Tk_Display(tkwin), drawable, borderPtr->bgGC,
	    pointPtr, numPoints, Complex, CoordModeOrigin);
    if (leftRelief != TK_RELIEF_FLAT) {
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		borderWidth, leftRelief);
    }
1083
1084
1085
1086
1087
1088
1089


1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101



1102
1103
1104
1105
1106
1107
1108
    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;


    static int shiftTable[129];	/* 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. */




    /*
     * Initialize the table if this is the first time it is used.
     */

    if (shiftTable[0] == 0) {
	int i;







>
>
|
<
|
|
<
|
<
|
|
<
|
|
>
>
>







1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090

1091

1092
1093

1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
    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.
     */

    static int shiftTable[129];

    /*
     * Initialize the table if this is the first time it is used.
     */

    if (shiftTable[0] == 0) {
	int i;
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262

    /*
     * 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;
    if ((borderPtr != NULL)
	    && (borderPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == borderPtr->screen)
	    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	/*
	 * The object already points to the right border structure. Just
	 * return it.







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259

    /*
     * 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;
    if ((borderPtr != NULL)
	    && (borderPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == borderPtr->screen)
	    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	/*
	 * The object already points to the right border structure. Just
	 * return it.
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
     * find the right TkBorder structure.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (borderPtr = (TkBorder *)Tcl_GetHashValue(hashPtr); borderPtr != NULL;
	    borderPtr = borderPtr->nextPtr) {
	if ((Tk_Screen(tkwin) == borderPtr->screen)
		&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	    FreeBorderObj(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = borderPtr;
	    borderPtr->objRefCount++;
	    return (Tk_3DBorder) borderPtr;
	}
    }

  error:
    Tcl_Panic("Tk_Get3DBorderFromObj called with non-existent border!");







|
|


|
|







1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
     * find the right TkBorder structure.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);
	    (borderPtr != NULL); borderPtr = borderPtr->nextPtr) {
	if ((Tk_Screen(tkwin) == borderPtr->screen)
		&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
	    FreeBorderObjProc(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
	    borderPtr->objRefCount++;
	    return (Tk_3DBorder) borderPtr;
	}
    }

  error:
    Tcl_Panic("Tk_Get3DBorderFromObj called with non-existent border!");
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
 * Results:
 *	The return value is a standard Tcl result. If an error occurs during
 *	conversion, an error message is left in the interpreter's result
 *	unless "interp" is NULL.
 *
 * Side effects:
 *	If no error occurs, a blank internal format for a border value is
 *	initialized. The final form cannot be done without a Tk_Window.
 *
 *----------------------------------------------------------------------
 */

static void
InitBorderObj(
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBorderObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------







|

















|







1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
 * Results:
 *	The return value is a standard Tcl result. If an error occurs during
 *	conversion, an error message is left in the interpreter's result
 *	unless "interp" is NULL.
 *
 * Side effects:
 *	If no error occurs, a blank internal format for a border value is
 *	intialized. The final form cannot be done without a Tk_Window.
 *
 *----------------------------------------------------------------------
 */

static void
InitBorderObj(
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->typePtr = &tkBorderObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
1357
1358
1359
1360
1361
1362
1363
1364
1365

1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugBorder(
    Tk_Window tkwin,		/* The window in which the border will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{

    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, name);
    if (hashPtr != NULL) {
	TkBorder *borderPtr = (TkBorder *)Tcl_GetHashValue(hashPtr);

	if (borderPtr == NULL) {
	    Tcl_Panic("TkDebugBorder found empty hash table entry");
	}
	for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(borderPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(borderPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

>

|





|
<




|
<

|

|













1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371

1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
 *----------------------------------------------------------------------
 */

Tcl_Obj *
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;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, name);
    if (hashPtr != NULL) {
	borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);

	if (borderPtr == NULL) {
	    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_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tk3d.h.

8
9
10
11
12
13
14
15





16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D

#include "tkInt.h"






/*
 * One of the following data structures is allocated for each 3-D border
 * currently in use. Structures of this type are indexed by borderTable, so
 * that a single structure can be shared for several uses.
 */

typedef struct TkBorder {
    Screen *screen;		/* Screen on which the border will be used. */
    Visual *visual;		/* Visual for all windows and pixmaps using
				 * the border. */
    int depth;			/* Number of bits per pixel of drawables where
				 * the border will be used. */
    Colormap colormap;		/* Colormap out of which pixels are
				 * allocated. */
    TkSizeT 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 objRefCount and
				 * resourceRefCount are both 0. */

    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    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.*/
    XColor *lightColorPtr;	/* Color used for lighter areas of border







|
>
>
>
>
>















|






|
|
>
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D

#include <tkInt.h>

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * One of the following data structures is allocated for each 3-D border
 * currently in use. Structures of this type are indexed by borderTable, so
 * that a single structure can be shared for several uses.
 */

typedef struct TkBorder {
    Screen *screen;		/* Screen on which the border will be used. */
    Visual *visual;		/* Visual for all windows and pixmaps using
				 * the border. */
    int depth;			/* Number of bits per pixel of drawables where
				 * the border will be used. */
    Colormap colormap;		/* Colormap out of which pixels are
				 * allocated. */
    int resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder).
				 * If this count is 0, then this structure is
				 * no longer valid and it isn't present in
				 * borderTable: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when
				 * resourceRefCount and objRefCount are both
				 * 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    XColor *bgColorPtr;		/* Background color (intensity between
				 * lightColorPtr and darkColorPtr). */
    XColor *darkColorPtr;	/* Color for darker areas (must free when
				 * deleting structure). NULL means shadows
				 * haven't been allocated yet.*/
    XColor *lightColorPtr;	/* Color used for lighter areas of border
78
79
80
81
82
83
84



85
 * Declarations for platform specific interfaces used by this module.
 */

MODULE_SCOPE TkBorder	*TkpGetBorder(void);
MODULE_SCOPE void	TkpGetShadows(TkBorder *borderPtr, Tk_Window tkwin);
MODULE_SCOPE void	TkpFreeBorder(TkBorder *borderPtr);




#endif /* _TK3D */







>
>
>

84
85
86
87
88
89
90
91
92
93
94
 * Declarations for platform specific interfaces used by this module.
 */

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

#endif /* _TK3D */

Changes to generic/tkArgv.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "tkInt.h"

/*
 * Default table of argument descriptors. These are normally available in
 * every application.
 */

static const Tk_ArgvInfo defaultTable[] = {
    {"-help",	TK_ARGV_HELP, NULL, NULL,
	"Print summary of command-line options and abort"},
    {NULL,	TK_ARGV_END, NULL, NULL, NULL}
};

/*
 * Forward declarations for functions defined in this file:
 */

static void	PrintUsage(Tcl_Interp *interp, const Tk_ArgvInfo *argTable,
		    int flags);

/*
 *----------------------------------------------------------------------
 *
 * Tk_ParseArgv --
 *







|









|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "tkInt.h"

/*
 * Default table of argument descriptors. These are normally available in
 * every application.
 */

static Tk_ArgvInfo defaultTable[] = {
    {"-help",	TK_ARGV_HELP, NULL, NULL,
	"Print summary of command-line options and abort"},
    {NULL,	TK_ARGV_END, NULL, NULL, NULL}
};

/*
 * Forward declarations for functions defined in this file:
 */

static void	PrintUsage(Tcl_Interp *interp, Tk_ArgvInfo *argTable,
		    int flags);

/*
 *----------------------------------------------------------------------
 *
 * Tk_ParseArgv --
 *
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
int
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. */
    const Tk_ArgvInfo *argTable,	/* Array of option descriptions */
    int flags)			/* Or'ed combination of various flag bits,
				 * such as TK_ARGV_NO_DEFAULTS. */
{
    const Tk_ArgvInfo *infoPtr;
				/* Pointer to the current entry in the table
				 * of argument descriptions. */
    const Tk_ArgvInfo *matchPtr;/* Descriptor that matches current argument. */
    const char *curArg;		/* Current argument */
    char c;		/* Second character of current arg (used for
				 * 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
				 * argument should be copied (never greater
				 * than srcIndex). */
    int argc;			/* # arguments in argv still to process. */
    size_t length;		/* Number of characters in current argument. */
    char *endPtr;		/* Used for identifying junk in arguments. */
    int i;

    if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
	srcIndex = dstIndex = 0;
	argc = *argcPtr;
    } else {
	srcIndex = dstIndex = 1;







|

|



|


|
|
|










<







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
int
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. */
    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
				 * '-'). */
    int srcIndex;		/* Location from which to read next argument
				 * from argv. */
    int dstIndex;		/* Index into argv to which next unused
				 * argument should be copied (never greater
				 * than srcIndex). */
    int argc;			/* # arguments in argv still to process. */
    size_t length;		/* Number of characters in current argument. */

    int i;

    if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
	srcIndex = dstIndex = 0;
	argc = *argcPtr;
    } else {
	srcIndex = dstIndex = 1;
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182


183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
		    matchPtr = infoPtr;
		    goto gotMatch;
		}
		if (flags & TK_ARGV_NO_ABBREV) {
		    continue;
		}
		if (matchPtr != NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "ambiguous option \"%s\"", curArg));
		    Tcl_SetErrorCode(interp, "TK", "ARG", "AMBIGUOUS", curArg,
			    NULL);
		    return TCL_ERROR;
		}
		matchPtr = infoPtr;
	    }
	}
	if (matchPtr == NULL) {
	    /*
	     * Unrecognized argument. Just copy it down, unless the caller
	     * prefers an error to be registered.
	     */

	    if (flags & TK_ARGV_NO_LEFTOVERS) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unrecognized argument \"%s\"", curArg));
		Tcl_SetErrorCode(interp, "TK", "ARG", "UNRECOGNIZED", curArg,
			NULL);
		return TCL_ERROR;
	    }
	    argv[dstIndex] = curArg;
	    dstIndex++;
	    continue;
	}

	/*
	 * Take the appropriate action based on the option type
	 */

    gotMatch:
	infoPtr = matchPtr;
	switch (infoPtr->type) {
	case TK_ARGV_CONSTANT:
	    *((int *) infoPtr->dst) = PTR2INT(infoPtr->src);
	    break;
	case TK_ARGV_INT:
	    if (argc == 0) {
		goto missingArg;


	    }
	    *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0);
	    if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected %s argument for \"%s\" but got \"%s\"",
			"integer", infoPtr->key, argv[srcIndex]));
		Tcl_SetErrorCode(interp, "TK", "ARG", "INTEGER", curArg,NULL);
		return TCL_ERROR;
	    }
	    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;
	    }
	    *((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;


	    }
	    *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr);
	    if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected %s argument for \"%s\" but got \"%s\"",
			"floating-point", infoPtr->key, argv[srcIndex]));
		Tcl_SetErrorCode(interp, "TK", "ARG", "FLOAT", curArg, NULL);
		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;

	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);
	    ArgvFunc *handlerProc = (ArgvFunc *)infoPtr->src;

	    if (handlerProc((char *)infoPtr->dst, infoPtr->key, argv[srcIndex])) {
		srcIndex++;
		argc--;
	    }
	    break;
	}
	case TK_ARGV_GENFUNC: {
	    typedef int (ArgvGenFunc)(char *, Tcl_Interp *, const char *, int,
		    const char **);
	    ArgvGenFunc *handlerProc = (ArgvGenFunc *)infoPtr->src;

	    argc = handlerProc((char *)infoPtr->dst, interp, infoPtr->key, argc,
		    argv+srcIndex);
	    if (argc < 0) {
		return TCL_ERROR;
	    }
	    break;
	}
	case TK_ARGV_HELP:
	    PrintUsage(interp, argTable, flags);
	    Tcl_SetErrorCode(interp, "TK", "ARG", "HELP", NULL);
	    return TCL_ERROR;
	case TK_ARGV_CONST_OPTION:
	    Tk_AddOption(tkwin, (char *)infoPtr->dst, (char *)infoPtr->src,
		    TK_INTERACTIVE_PRIO);
	    break;
	case TK_ARGV_OPTION_VALUE:
	    if (argc < 1) {
		goto missingArg;
	    }
	    Tk_AddOption(tkwin, (char *)infoPtr->dst, argv[srcIndex],
		    TK_INTERACTIVE_PRIO);
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_OPTION_NAME_VALUE:
	    if (argc < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"\"%s\" option requires two following arguments",
			curArg));
		Tcl_SetErrorCode(interp, "TK", "ARG", "NAME_VALUE", curArg,
			NULL);
		return TCL_ERROR;
	    }
	    Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1],
		    TK_INTERACTIVE_PRIO);
	    srcIndex += 2;
	    argc -= 2;
	    break;
	default:

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument type %d in Tk_ArgvInfo", infoPtr->type));
	    Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
	    return TCL_ERROR;

	}
    }

    /*
     * If we broke out of the loop because of an OPT_REST argument, copy the
     * remaining arguments down.
     */

  argsDone:
    while (argc) {
	argv[dstIndex] = argv[srcIndex];
	srcIndex++;
	dstIndex++;
	argc--;
    }
    argv[dstIndex] = NULL;
    *argcPtr = dstIndex;
    return TCL_OK;

  missingArg:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "\"%s\" option requires an additional argument", curArg));
    Tcl_SetErrorCode(interp, "TK", "ARG", "MISSING", curArg, NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * PrintUsage --







<
|
<
|












<
|
<
|




















>
>
|
|
|
|
<
|
|
|
|
|
|
>





|







|









>
>
|
|
|
|
|
|
<
|
|
|
|
>


|
|

|






|
|
|

|
|







<


|






|






|
|
<
<
<







|
>
|
|
|

>




















|
|
<







135
136
137
138
139
140
141

142

143
144
145
146
147
148
149
150
151
152
153
154
155

156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
		    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
	     * prefers an error to be registered.
	     */

	    if (flags & TK_ARGV_NO_LEFTOVERS) {

		Tcl_AppendResult(interp, "unrecognized argument \"",

			curArg, "\"", NULL);
		return TCL_ERROR;
	    }
	    argv[dstIndex] = curArg;
	    dstIndex++;
	    continue;
	}

	/*
	 * Take the appropriate action based on the option type
	 */

    gotMatch:
	infoPtr = matchPtr;
	switch (infoPtr->type) {
	case TK_ARGV_CONSTANT:
	    *((int *) infoPtr->dst) = PTR2INT(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],
			    "\"", NULL);
		    return TCL_ERROR;
		}
		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;
	    }
	    *((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], "\"", NULL);

		    return TCL_ERROR;
		}
		srcIndex++;
		argc--;
	    }
	    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_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.
     */

  argsDone:
    while (argc) {
	argv[dstIndex] = argv[srcIndex];
	srcIndex++;
	dstIndex++;
	argc--;
    }
    argv[dstIndex] = NULL;
    *argcPtr = dstIndex;
    return TCL_OK;

  missingArg:
    Tcl_AppendResult(interp, "\"", curArg,
	    "\" option requires an additional argument", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * PrintUsage --
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387

388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
 *----------------------------------------------------------------------
 */

static void
PrintUsage(
    Tcl_Interp *interp,		/* Place information in this interp's result
				 * area. */
    const 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. */
{
    const Tk_ArgvInfo *infoPtr;
    size_t width, i, numSpaces;
    Tcl_Obj *message;

    /*
     * 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++) {
	    size_t length;

	    if (infoPtr->key == NULL) {
		continue;
	    }
	    length = strlen(infoPtr->key);
	    if (length > width) {
		width = length;
	    }
	}
    }

    message = Tcl_NewStringObj("Command-specific options:", -1);
    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_AppendPrintfToObj(message, "\n%s", infoPtr->help);
		continue;
	    }
	    Tcl_AppendPrintfToObj(message, "\n %s:", infoPtr->key);
	    numSpaces = width + 1 - strlen(infoPtr->key);
	    while (numSpaces-- > 0) {
		Tcl_AppendToObj(message, " ", 1);
	    }
	    Tcl_AppendToObj(message, infoPtr->help, -1);
	    switch (infoPtr->type) {
	    case TK_ARGV_INT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %d",
			*((int *) infoPtr->dst));

		break;
	    case TK_ARGV_FLOAT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %f",
			*((double *) infoPtr->dst));

		break;
	    case TK_ARGV_STRING: {
		char *string = *((char **) infoPtr->dst);

		if (string != NULL) {
		    Tcl_AppendPrintfToObj(message,
			    "\n\t\tDefault value: \"%s\"", string);

		}
		break;
	    }
	    default:
		break;
	    }
	}

	if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {
	    break;
	}
	Tcl_AppendToObj(message, "\nGeneric options for all commands:", -1);
    }
    Tcl_SetObjResult(interp, message);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|





|

|











<










|




|


|


|

|


<
|
>


<
|
>





<
|
>











|

<









324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380

381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
 *----------------------------------------------------------------------
 */

static void
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. */
{
    register Tk_ArgvInfo *infoPtr;
    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.
     */

    width = 4;
    for (i = 0; i < 2; i++) {
	for (infoPtr = i ? defaultTable : argTable;
		infoPtr->type != TK_ARGV_END; infoPtr++) {
	    size_t length;

	    if (infoPtr->key == NULL) {
		continue;
	    }
	    length = strlen(infoPtr->key);
	    if (length > width) {
		width = length;
	    }
	}
    }

    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, NULL);
		continue;
	    }
	    Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL);
	    numSpaces = width + 1 - strlen(infoPtr->key);
	    while (numSpaces-- > 0) {
		Tcl_AppendResult(interp, " ", 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, 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);

		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:", NULL);
    }

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Deleted generic/tkArray.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
/*
 * tkArray.h --
 *
 * An array is a sequence of items, stored in a contiguous memory region.
 * Random access to any item is very fast. New items can be either appended
 * or prepended. An array may be traversed in the forward or backward direction.
 *
 * Copyright (c) 2018-2019 by Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Note that this file will not be included in header files, it is the purpose
 * of this file to be included in source files only. Thus we are not using the
 * prefix "Tk_" here for functions, because all the functions have private scope.
 */

/*
 * -------------------------------------------------------------------------------
 * Use the array in the following way:
 * -------------------------------------------------------------------------------
 * typedef struct { int key, value; } Pair;
 * TK_PTR_ARRAY_DEFINE(MyArray, Pair);
 * MyArray *arr = NULL;
 * if (MyArray_IsEmpty(arr)) {
 *     MyArray_Append(&arr, MakePair(1, 2));
 *     MyArray_Append(&arr, MakePair(2, 3));
 *     for (i = 0; i < MyArray_Size(arr); ++i) {
 *         Pair *p = MyArray_Get(arr, i);
 *         printf("%d -> %d\n", p->key, p->value);
 *         ckfree(p);
 *     }
 *     MyArray_Free(&arr);
 *     assert(arr == NULL);
 * }
 * -------------------------------------------------------------------------------
 * Or with aggregated elements:
 * -------------------------------------------------------------------------------
 * typedef struct { int key, value; } Pair;
 * TK_ARRAY_DEFINE(MyArray, Pair);
 * Pair p1 = { 1, 2 };
 * Pair p2 = { 2, 3 };
 * MyArray *arr = NULL;
 * if (MyArray_IsEmpty(arr)) {
 *     MyArray_Append(&arr, p1);
 *     MyArray_Append(&arr, p2);
 *     for (i = 0; i < MyArray_Size(arr); ++i) {
 *         const Pair *p = MyArray_Get(arr, i);
 *         printf("%d -> %d\n", p->key, p->value);
 *     }
 *     MyArray_Free(&arr);
 *     assert(arr == NULL);
 * }
 * -------------------------------------------------------------------------------
 */

/*************************************************************************/
/*
 * Two array types will be provided:
 * Use TK_ARRAY_DEFINE if your array is aggregating the elements. Use
 * TK_PTR_ARRAY_DEFINE if your array contains pointers to elements. But
 * in latter case the array is not responsible for the lifetime of the
 * elements.
 */
/*************************************************************************/
/*
 * Array_ElemSize: Returns the memory size for one array element.
 */
/*************************************************************************/
/*
 * Array_BufferSize: Returns the memory size for given number of elements.
 */
/*************************************************************************/
/*
 * Array_IsEmpty: Array is empty?
 */
/*************************************************************************/
/*
 * Array_Size: Number of elements in array.
 */
/*************************************************************************/
/*
 * Array_Capacity: Capacity of given array. This is the maximal number of
 * elements fitting into current array memory without resizing the buffer.
 */
/*************************************************************************/
/*
 * Array_SetSize: Set array size, new size must not exceed the capacity of
 * the array. This function has to be used with care when increasing the
 * array size.
 */
/*************************************************************************/
/*
 * Array_First: Returns position of first element in array. Given array
 * may be NULL.
 */
/*************************************************************************/
/*
 * Array_Last: Returns position after last element in array. Given array
 * may be empty.
 */
/*************************************************************************/
/*
 * Array_Front: Returns first element in array. Given array must not be
 * empty.
 */
/*************************************************************************/
/*
 * Array_Back: Returns last element in array. Given array must not be
 * empty.
 */
/*************************************************************************/
/*
 * Array_Resize: Resize buffer of array for given number of elements. The
 * array may grow or shrink. Note that this function is not initializing
 * the increased buffer.
 */
/*************************************************************************/
/*
 * Array_ResizeAndClear: Resize buffer of array for given number of
 * elements. The array may grow or shrink. The increased memory will be
 * filled with zeroes.
 */
/*************************************************************************/
/*
 * Array_Clear: Fill specified range with zeroes.
 */
/*************************************************************************/
/*
 * Array_Free: Resize array to size zero. This function will release the
 * array buffer.
 */
/*************************************************************************/
/*
 * Array_Append: Insert given element after end of array.
 */
/*************************************************************************/
/*
 * Array_PopBack: Shrink array by one element. Given array must not be
 * empty.
 */
/*************************************************************************/
/*
 * Array_Get: Random access to array element at given position. The given
 * index must not exceed current array size.
 */
/*************************************************************************/
/*
 * Array_Set: Replace array element at given position with new value. The
 * given index must not exceed current array size.
 */
/*************************************************************************/
/*
 * Array_Find: Return index position of element which matches given
 * argument. If not found then -1 will be returned.
 */
/*************************************************************************/

#ifndef TK_ARRAY_DEFINED
#define TK_ARRAY_DEFINED

#include "tkInt.h"

#if defined(__GNUC__) || defined(__clang__)
# define __TK_ARRAY_UNUSED __attribute__((unused))
#else
# define __TK_ARRAY_UNUSED
#endif

#define TK_ARRAY_DEFINE(AT, ElemType) /* AT = type of array */			\
/* ------------------------------------------------------------------------- */	\
typedef struct AT {								\
    size_t size;								\
    size_t capacity;								\
    ElemType buf[1];								\
} AT;										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Init(AT *arr)								\
{										\
    assert(arr);								\
    arr->size = 0;								\
    arr->capacity = 0;								\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_ElemSize(void)									\
{										\
    return sizeof(ElemType);							\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_BufferSize(size_t numElems)						\
{										\
    return numElems*sizeof(ElemType);						\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_IsEmpty(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return !arr || arr->size == 0u;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_Size(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->size : 0u;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_Capacity(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->capacity : 0u;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_First(AT *arr)								\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->buf : NULL;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Last(AT *arr)								\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->buf + arr->size : NULL;					\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Front(AT *arr)								\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(!AT##_IsEmpty(arr));							\
    return &arr->buf[0];							\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Back(AT *arr)								\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(!AT##_IsEmpty(arr));							\
    return &arr->buf[arr->size - 1];						\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Resize(AT **arrp, size_t newSize)						\
{										\
    assert(arrp);								\
    assert(!*arrp || (*arrp)->size != 0xdeadbeef);				\
    if (newSize == 0) {								\
	assert(!*arrp || ((*arrp)->size = 0xdeadbeef));				\
	ckfree(*arrp);								\
	*arrp = NULL;								\
    } else {									\
	int init = *arrp == NULL;						\
	size_t memSize = AT##_BufferSize(newSize - 1) + sizeof(AT);		\
	*arrp = (AT *)ckrealloc(*arrp, memSize);					\
	if (init) {								\
	    (*arrp)->size = 0;							\
	} else if (newSize < (*arrp)->size) {					\
	    (*arrp)->size = newSize;						\
	}									\
	(*arrp)->capacity = newSize;						\
    }										\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Clear(AT *arr, size_t from, size_t to)					\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(to <= AT##_Capacity(arr));						\
    assert(from <= to);								\
    memset(arr->buf + from, 0, AT##_BufferSize(to - from));			\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_ResizeAndClear(AT **arrp, size_t newSize)					\
{										\
    size_t oldCapacity;								\
    assert(arrp);								\
    oldCapacity = *arrp ? (*arrp)->capacity : 0;				\
    AT##_Resize(arrp, newSize);							\
    if (newSize > oldCapacity) {						\
	AT##_Clear(*arrp, oldCapacity, newSize);				\
    }										\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_SetSize(AT *arr, size_t newSize)						\
{										\
    assert(newSize <= AT##_Capacity(arr));					\
    assert(!arr || arr->size != 0xdeadbeef);					\
    if (arr) {									\
	arr->size = newSize;							\
    }										\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Append(AT **arrp, ElemType *elem)						\
{										\
    assert(arrp);								\
    if (!*arrp) {								\
	AT##_Resize(arrp, 1);							\
    } else if ((*arrp)->size == (*arrp)->capacity) {				\
	AT##_Resize(arrp, (*arrp)->capacity + ((*arrp)->capacity + 1)/2);	\
    }										\
    (*arrp)->buf[(*arrp)->size++] = *elem;					\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_PopBack(AT *arr)								\
{										\
    assert(!AT##_IsEmpty(arr));							\
    return arr->size -= 1;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Get(const AT *arr, size_t at)						\
{										\
    assert(arr);								\
    assert(at < AT##_Size(arr));						\
    return (ElemType *) &arr->buf[at];						\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Set(AT *arr, size_t at, ElemType *elem)					\
{										\
    assert(arr);								\
    assert(at < AT##_Size(arr));						\
    arr->buf[at] = *elem;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Free(AT **arrp)								\
{										\
    AT##_Resize(arrp, 0);							\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_Find(const AT *arr, const ElemType *elem)					\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    if (arr) {									\
	const ElemType *buf = arr->buf;						\
	size_t i;								\
	for (i = 0; i < arr->size; ++i) {					\
	    if (memcmp(&buf[i], elem, sizeof(ElemType)) == 0) {			\
		return (int) i;							\
	    }									\
	}									\
    }										\
    return -1;									\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_Contains(const AT *arr, const ElemType *elem)				\
{										\
    return AT##_Find(arr, elem) != -1;						\
}										\
/* ------------------------------------------------------------------------- */

#define TK_PTR_ARRAY_DEFINE(AT, ElemType) /* AT = type of array */		\
/* ------------------------------------------------------------------------- */	\
typedef struct AT {								\
    size_t size;								\
    size_t capacity;								\
    ElemType *buf[1];								\
} AT;										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_ElemSize(void)									\
{										\
    return sizeof(ElemType);							\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_BufferSize(size_t numElems)						\
{										\
    return numElems*sizeof(ElemType *);						\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_IsEmpty(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return !arr || arr->size == 0;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType **								\
AT##_First(AT *arr)								\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->buf : NULL;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType **								\
AT##_Last(AT *arr)								\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->buf + arr->size : NULL;					\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Front(AT *arr)								\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(!AT##_IsEmpty(arr));							\
    return arr->buf[0];								\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Back(AT *arr)								\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(!AT##_IsEmpty(arr));							\
    return arr->buf[arr->size - 1];						\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_Size(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->size : 0;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_Capacity(const AT *arr)							\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    return arr ? arr->capacity : 0;						\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Resize(AT **arrp, size_t newCapacity)					\
{										\
    assert(arrp);								\
    assert(!*arrp || (*arrp)->size != 0xdeadbeef);				\
    if (newCapacity == 0) {							\
	assert(!*arrp || ((*arrp)->size = 0xdeadbeef));				\
	ckfree(*arrp);								\
	*arrp = NULL;								\
    } else {									\
	int init = *arrp == NULL;						\
	size_t memSize = AT##_BufferSize(newCapacity - 1) + sizeof(AT);		\
	*arrp = (AT *)ckrealloc(*arrp, memSize);					\
	if (init) {								\
	    (*arrp)->size = 0;							\
	} else if (newCapacity < (*arrp)->size) {				\
	    (*arrp)->size = newCapacity;					\
	}									\
	(*arrp)->capacity = newCapacity;					\
    }										\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Clear(AT *arr, size_t from, size_t to)					\
{										\
    assert(arr);								\
    assert(arr->size != 0xdeadbeef);						\
    assert(to <= AT##_Capacity(arr));						\
    assert(from <= to);								\
    memset(arr->buf + from, 0, AT##_BufferSize(to - from));			\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_ResizeAndClear(AT **arrp, size_t newCapacity)				\
{										\
    size_t oldCapacity;								\
    assert(arrp);								\
    oldCapacity = *arrp ? (*arrp)->capacity : 0;				\
    AT##_Resize(arrp, newCapacity);						\
    if (newCapacity > oldCapacity) {						\
	AT##_Clear(*arrp, oldCapacity, newCapacity);				\
    }										\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_SetSize(AT *arr, size_t newSize)						\
{										\
    assert(arr);								\
    assert(newSize <= AT##_Capacity(arr));					\
    arr->size = newSize;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Append(AT **arrp, ElemType *elem)						\
{										\
    assert(arrp);								\
    if (!*arrp) {								\
	AT##_Resize(arrp, 1);							\
    } else if ((*arrp)->size == (*arrp)->capacity) {				\
	AT##_Resize(arrp, (*arrp)->capacity + ((*arrp)->capacity + 1)/2);	\
    }										\
    (*arrp)->buf[(*arrp)->size++] = elem;					\
}										\
										\
__TK_ARRAY_UNUSED								\
static size_t									\
AT##_PopBack(AT *arr)								\
{										\
    assert(!AT##_IsEmpty(arr));							\
    return arr->size -= 1;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static ElemType *								\
AT##_Get(const AT *arr, size_t at)						\
{										\
    assert(arr);								\
    assert(at < AT##_Size(arr));						\
    return arr->buf[at];							\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Set(AT *arr, size_t at, ElemType *elem)					\
{										\
    assert(arr);								\
    assert(at < AT##_Size(arr));						\
    arr->buf[at] = elem;							\
}										\
										\
__TK_ARRAY_UNUSED								\
static void									\
AT##_Free(AT **arrp)								\
{										\
    AT##_Resize(arrp, 0);							\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_Find(const AT *arr, const ElemType *elem)					\
{										\
    assert(!arr || arr->size != 0xdeadbeef);					\
    if (arr) {									\
	ElemType *const *buf = arr->buf;					\
	size_t i;								\
	for (i = 0; i < arr->size; ++i) {					\
	    if (buf[i] == elem) {						\
		return (int) i;							\
	    }									\
	}									\
    }										\
    return -1;									\
}										\
										\
__TK_ARRAY_UNUSED								\
static int									\
AT##_Contains(const AT *arr, const ElemType *elem)				\
{										\
    return AT##_Find(arr, elem) != -1;						\
}										\
/* ------------------------------------------------------------------------- */

#endif /* TK_ARRAY_DEFINED */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkAtom.c.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "tkInt.h"

/*
 * The following are a list of the predefined atom strings. They should match
 * those found in xatom.h
 */

static const char *const atomNameArray[] = {
    "PRIMARY",		"SECONDARY",		"ARC",
    "ATOM",		"BITMAP",		"CARDINAL",
    "COLORMAP",		"CURSOR",		"CUT_BUFFER0",
    "CUT_BUFFER1",	"CUT_BUFFER2",		"CUT_BUFFER3",
    "CUT_BUFFER4",	"CUT_BUFFER5",		"CUT_BUFFER6",
    "CUT_BUFFER7",	"DRAWABLE",		"FONT",
    "INTEGER",		"PIXMAP",		"POINT",







|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "tkInt.h"

/*
 * The following are a list of the predefined atom strings. They should match
 * those found in xatom.h
 */

static const char *atomNameArray[] = {
    "PRIMARY",		"SECONDARY",		"ARC",
    "ATOM",		"BITMAP",		"CARDINAL",
    "COLORMAP",		"CURSOR",		"CUT_BUFFER0",
    "CUT_BUFFER1",	"CUT_BUFFER2",		"CUT_BUFFER3",
    "CUT_BUFFER4",	"CUT_BUFFER5",		"CUT_BUFFER6",
    "CUT_BUFFER7",	"DRAWABLE",		"FONT",
    "INTEGER",		"PIXMAP",		"POINT",
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 *--------------------------------------------------------------
 */

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. */
{
    TkDisplay *dispPtr;
    Tcl_HashEntry *hPtr;
    int isNew;

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->atomInit) {
	AtomInit(dispPtr);
    }

    hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
    if (isNew) {
	Tcl_HashEntry *hPtr2;
	Atom atom;

	atom = XInternAtom(dispPtr->display, name, False);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr));
    }
    return (Atom)PTR2INT(Tcl_GetHashValue(hPtr));
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetAtomName --
 *







|

|
|

















|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 *--------------------------------------------------------------
 */

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 isNew;

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->atomInit) {
	AtomInit(dispPtr);
    }

    hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
    if (isNew) {
	Tcl_HashEntry *hPtr2;
	Atom atom;

	atom = XInternAtom(dispPtr->display, name, False);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr));
    }
    return (Atom) PTR2INT(Tcl_GetHashValue(hPtr));
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetAtomName --
 *
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_GetAtomName(
    Tk_Window tkwin,		/* Window token; map atom to name relative to
				 * this window's display. */
    Atom atom)			/* Atom whose name is wanted. */
{
    TkDisplay *dispPtr;
    Tcl_HashEntry *hPtr;

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->atomInit) {
	AtomInit(dispPtr);
    }

    hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, INT2PTR(atom));
    if (hPtr == NULL) {
	const char *name;
	Tk_ErrorHandler handler;
	int isNew;
	char *mustFree = NULL;

	handler = Tk_CreateErrorHandler(dispPtr->display, BadAtom, -1, -1,
		NULL, NULL);
	name = mustFree = XGetAtomName(dispPtr->display, atom);

	if (name == NULL) {
	    name = "?bad atom?";

	}
	Tk_DeleteErrorHandler(handler);
	hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	if (mustFree) {
	    XFree(mustFree);
	}
	name = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, (char *)name);
    }
    return (const char *)Tcl_GetHashValue(hPtr);
}

/*
 *--------------------------------------------------------------
 *
 * AtomInit --
 *
 *	Initialize atom-related information for a display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Tables get initialized, etc. etc..
 *
 *--------------------------------------------------------------
 */

static void
AtomInit(
    TkDisplay *dispPtr)/* Display to initialize. */
{
    Tcl_HashEntry *hPtr;
    Atom atom;

    dispPtr->atomInit = 1;
    Tcl_InitHashTable(&dispPtr->nameTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS);

    for (atom = 1; atom <= XA_LAST_PREDEFINED; atom++) {
	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 = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, (char *)name);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|





|
|








|

|
<


|
|
>


>





|

|

|

|




















|




















|

|










117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
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;

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->atomInit) {
	AtomInit(dispPtr);
    }

    hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, INT2PTR(atom));
    if (hPtr == NULL) {
	char *name;
	Tk_ErrorHandler handler;
	int isNew, mustFree;


	handler = Tk_CreateErrorHandler(dispPtr->display, BadAtom, -1, -1,
		NULL, (ClientData) NULL);
	name = XGetAtomName(dispPtr->display, atom);
	mustFree = 1;
	if (name == NULL) {
	    name = "?bad atom?";
	    mustFree = 0;
	}
	Tk_DeleteErrorHandler(handler);
	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, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, name);
    }
    return Tcl_GetHashValue(hPtr);
}

/*
 *--------------------------------------------------------------
 *
 * AtomInit --
 *
 *	Initialize atom-related information for a display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Tables get initialized, etc. etc..
 *
 *--------------------------------------------------------------
 */

static void
AtomInit(
    register TkDisplay *dispPtr)/* Display to initialize. */
{
    Tcl_HashEntry *hPtr;
    Atom atom;

    dispPtr->atomInit = 1;
    Tcl_InitHashTable(&dispPtr->nameTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS);

    for (atom = 1; atom <= XA_LAST_PREDEFINED; atom++) {
	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:
 */

Changes to generic/tkBind.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51


52
53


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188








189
190
191
192
193
194
195

196



197
198




199
200
201

202
203

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220


221

222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264

265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304


305
306

307


308


309

310

311
312

313
314

315
316
317
318

319
320
321

322

323
324


325
326
327
328
329











330
331


332
333
334
335
336
337
338
339













340
341
342
343
344
345
346


347


348
349
350
351
352
353
354
355
356
357

358
359

360
361
























362
363
364
365
366
367
368
369

370

371



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402








403
404
405
406
407
408
409
410
411
412

413

414
415
416
417
418
419

420

421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/*
 * tkBind.c --
 *
 *	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.
 * Copyright (c) 2018-2019 by Gregor Cramer.
 *
 * 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 "tkDList.h"
#include "tkArray.h"

#if defined(_WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else /* if defined(__unix__) */
#include "tkUnixInt.h"
#endif

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

#ifdef _MSC_VER
/*
 * Earlier versions of MSVC don't know snprintf, but _snprintf is compatible.
 * Note that sprintf is deprecated.
 */
# define snprintf _snprintf
#endif

#define SIZE_OF_ARRAY(arr) (sizeof(arr)/sizeof(arr[0]))

/*
 * File structure:
 *
 * Structure definitions and static variables.
 *
 * Init/Free this package.
 *
 * Tcl "bind" command (actually located in tkCmds.c) core implementation, plus helpers.


 *
 * Tcl "event" command implementation, plus helpers.


 *
 * Package-specific common helpers.
 *
 * Non-package-specific helpers.
 */

/*
 * In old implementation (the one that used an event ring), <Double-1> and <1><1> were
 * equivalent sequences. However it is logical to give <Double-1> higher precedence
 * since it is more specific. Indeed <Double-1> includes time and space requirements,
 * which is not the case for <1><1>.
 * This is achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1.
 */

#ifndef PREFER_MOST_SPECIALIZED_EVENT
# define PREFER_MOST_SPECIALIZED_EVENT 1
#endif

/*
 * Traditionally motion events can be combined with buttons in this way: <B1-B2-Motion>.
 * However it should be allowed to express this as <Motion-1-2> in addition. This is achieved
 * by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1.
 */

#ifndef SUPPORT_ADDITIONAL_MOTION_SYNTAX
# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 1
#endif

/*
 * The output for motion events is of the type <B1-Motion>. This can be changed to become
 * <Motion-1> instead by setting PRINT_SHORT_MOTION_SYNTAX to 1, however this would be a
 * backwards incompatibility.
 */

#ifndef PRINT_SHORT_MOTION_SYNTAX
# define PRINT_SHORT_MOTION_SYNTAX 0 /* set to 1 if wanted */
#endif

#if !SUPPORT_ADDITIONAL_MOTION_SYNTAX
# undef PRINT_SHORT_MOTION_SYNTAX
# define PRINT_SHORT_MOTION_SYNTAX 0
#endif

/*
 * For debugging only, normally set to zero.
 */

#ifdef SUPPORT_DEBUGGING
# undef SUPPORT_DEBUGGING
#endif
#define SUPPORT_DEBUGGING 0

/*
 * Test validity of PSEntry items.
 */

# define TEST_PSENTRY(psPtr) psPtr->number != 0xdeadbeef
# define MARK_PSENTRY(psPtr) psPtr->number = 0xdeadbeef

/*
 * The following union is used to hold the detail information from an XEvent
 * (including Tk's XVirtualEvent extension).
 */

typedef KeySym Info;

typedef union {
    Info info;		/* This either corresponds to xkey.keycode, or to xbutton.button,
    			 * or is meaningless, depending on event type. */

    Tk_Uid name;	/* Tk_Uid of virtual event. */
} Detail;

/*
 * We need an extended event definition.
 */

typedef struct {
    XEvent xev;		/* The original event from server. */
    Detail detail;	/* Additional information (for hashing). */
    unsigned countAny;	/* Count of multi-events, like multi-clicks, or repeated key pressing,
    			 * this count does not depend on detail (keySym or button). */
    unsigned countDetailed;
    			/* Count of multi-events, like multi-clicks, or repeated key pressing,
    			 * this count considers the detail (keySym or button). */
} Event;

struct PatSeq; /* forward declaration */

/* We need this array for bookkeeping the last matching modifier mask per pattern. */
TK_ARRAY_DEFINE(PSModMaskArr, unsigned);

typedef struct PSEntry {
    TK_DLIST_LINKS(PSEntry);	/* Makes this struct a double linked list; must be first entry. */
    Window window;		/* Window of last match. */
    struct PatSeq* psPtr;	/* Pointer to pattern sequence. */
    PSModMaskArr *lastModMaskArr;
    				/* Last matching modifier mask per pattern (except last pattern).
    				 * Only needed if pattern sequence is not single (more than one
				 * pattern), and if one of these patterns contains a non-zero
				 * modifier mask. */
    unsigned count;		/* Only promote to next level if this count has reached count of
    				 * pattern. */
    unsigned expired:1;		/* Whether this entry is expired, this means it has to be removed
    				 * from promotion list. */
    unsigned keepIt:1;		/* Whether to keep this entry, even if expired. */
} PSEntry;

/* Defining the whole PSList_* stuff (list of PSEntry items). */
TK_DLIST_DEFINE(PSList, PSEntry);

/* Don't keep larger arrays of modifier masks inside PSEntry. */
#define MAX_MOD_MASK_ARR_SIZE 8

/*
 * Maps and lookup tables from an event to a list of patterns that match that event.
 */

typedef struct {
    Tcl_HashTable patternTable;	/* Keys are PatternTableKey structs, values are (PatSeq *). */
    Tcl_HashTable listTable;	/* Keys are PatternTableKey structs, values are (PSList *). */
    PSList entryPool;		/* Contains free (unused) list items. */
    unsigned number;		/* Needed for enumeration of pattern sequences. */
} LookupTables;

/*
 * 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).








 */

/* defining the whole Promotion_* stuff (array of PSList entries) */
TK_ARRAY_DEFINE(PromArr, PSList);

typedef struct Tk_BindingTable_ {
    Event eventInfo[TK_LASTEVENT];

    				/* Containing the most recent event for every event type. */



    PromArr *promArr;		/* Contains the promoted pattern sequences. */
    Event *curEvent;		/* Pointing to most recent event. */




    unsigned curModMask;		/* Containing the current modifier mask. */
    LookupTables lookupTables;	/* Containing hash tables for fast lookup. */
    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>>,
 * <<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 commands. 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 {

    LookupTables lookupTables;	/* Providing fast lookup tables to lists of pattern sequences. */


    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 PhysOwned structs. */

} VirtualEventTable;

/*
 * 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 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.
 */

typedef struct {
    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. */
    unsigned type;		/* Type of event (from X). */
    Detail detail;		/* Additional information, such as keysym, button, Tk_Uid, or zero

    				 * if nothing additional. */
} PatternTableKey;

/*
 * The following structure defines a pattern, which is matched against X
 * events as part of the process of converting X events into Tcl commands.
 *
 * For technical reasons we do not use 'union Detail', although this would
 * be possible, instead 'info' and 'name' are both included.
 */

typedef struct {
    unsigned eventType;		/* Type of X event, e.g. ButtonPress. */
    unsigned count;		/* Multi-event count, e.g. double-clicks, triple-clicks, etc. */
    unsigned modMask;		/* Mask of modifiers that must be present (zero means no modifiers
    				 * are required). */
    Info info;			/* Additional information that must match event. Normally this is zero,

    				 * meaning no additional information must match. For KeyPress and

				 * KeyRelease events, it may be specified to select a particular
				 * keystroke (zero means any keystrokes). For button events, specifies

				 * a particular button (zero means any buttons are OK). */
    Tk_Uid name;		/* Specifies the Tk_Uid of the virtual event name. NULL if not a
    				 * virtual event. */
} TkPattern;

/*
 * The following structure keeps track of all the virtual events that are
 * associated with a particular physical event. It is pointed to by the 'owners'
 * field in a PatSeq in the patternTable of a virtual event table.
 */

TK_PTR_ARRAY_DEFINE(VirtOwners, Tcl_HashEntry); /* define array of hash entries */

/*
 * 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
 * helper functions that traverse and match patterns will work for both
 * binding tables and virtual event tables.
 */

typedef struct PatSeq {
    unsigned numPats;		/* Number of patterns in sequence (usually 1). */
    unsigned count;		/* Total number of repetition counts, summed over count in TkPattern. */
    unsigned number;		/* Needed for the decision whether a binding is less recently defined
    				 * than another, it is guaranteed that the most recently bound event
				 * has the highest number. */

    unsigned added:1;		/* Is this pattern sequence already added to lookup table? */


    unsigned modMaskUsed:1;	/* Does at least one pattern contain a non-zero modifier mask? */
    DEBUG(unsigned owned:1;)	/* For debugging purposes. */

    char *script;		/* Binding script to evaluate when sequence matches (ckalloc()ed) */


    Tcl_Obj* object;		/* Token for object with which binding is associated. For virtual


    				 * event table this is NULL. */

    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. */
    union {

	VirtOwners *owners;	/* In a binding table it has no meaning. In a virtual event table,
				 * identifies the array of virtual events that can be triggered
				 * by this event. */
	struct PatSeq *nextObj;	/* 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 table it has no meaning. */
    } ptr;

    TkPattern pats[1];		/* Array of "numPats" patterns. Only one element is declared here

    				 * but in actuality enough space will be allocated for "numPats"
				 * patterns (but usually 1). */


} PatSeq;

/*
 * Compute memory size of struct PatSeq with given pattern size.
 * The caller must be sure that pattern size is greater than zero.











 */
#define PATSEQ_MEMSIZE(numPats) (sizeof(PatSeq) + (numPats - 1)*sizeof(TkPattern))



/*
 * 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 is used in the nameTable of a virtual event table
 * to associate a virtual event with all the physical events that can trigger
 * it.
 */



TK_PTR_ARRAY_DEFINE(PhysOwned, PatSeq); /* define array of pattern seqs */



/*
 * 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
 * command can be invoked whenever the display/screen changes (the command 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 */
    unsigned bindingDepth;	/* Number of active instances of Tk_BindEvent in this application. */

} ScreenInfo;

























/*
 * The following structure keeps track of all the information local to the
 * binding package on a per interpreter basis.
 */

typedef struct TkBindInfo_ {
    VirtualEventTable virtualEventTable;
				/* 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. */



    int deleted;		/* 1 if the application has been deleted but the structure has been
    				 * preserved. */
    Time lastEventTime;		/* Needed for time measurement. */
    Time lastCurrentTime;	/* Needed for time measurement. */
} 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.
 */

#ifdef REDO_KEYSYM_LOOKUP
typedef struct {
    const char *name;		/* Name of keysym. */
    KeySym value;		/* Numeric identifier for keysym. */
} KeySymInfo;
static const KeySymInfo keyArray[] = {
#ifndef lint
#include "ks_names.h"
#endif
    {NULL, 0}
};
static Tcl_HashTable keySymTable;	/* keyArray hashed by keysym value. */
static Tcl_HashTable nameTable;		/* keyArray hashed by keysym name. */
#endif /* REDO_KEYSYM_LOOKUP */









/*
 * 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 {
    const char *name;	/* Name of modifier. */
    unsigned mask;	/* Button/modifier mask value, such as Button1Mask. */

    unsigned flags;	/* Various flags; see below for definitions. */

} ModInfo;

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event, e.g. for double-clicks.

 * TRIPLE -		Non-zero means triplicate this event, e.g. for triple-clicks.

 * QUADRUPLE -		Non-zero means quadruple this event, e.g. for 4-fold-clicks.

 * MULT_CLICKS -	Combination of all of above.
 */

#define DOUBLE		(1<<0)
#define TRIPLE		(1<<1)
#define QUADRUPLE	(1<<2)
#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

static const ModInfo modArray[] = {
    {"Control",		ControlMask,	0},
    {"Shift",		ShiftMask,	0},
    {"Lock",		LockMask,	0},
    {"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},
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},
    {"Button3",		Button3Mask,	0},
    {"B4",		Button4Mask,	0},
    {"Button4",		Button4Mask,	0},
    {"B5",		Button5Mask,	0},
    {"Button5",		Button5Mask,	0},
    {"B6",		Button6Mask,	0},
    {"Button6",		Button6Mask,	0},
    {"B7",		Button7Mask,	0},
    {"Button7",		Button7Mask,	0},
    {"B8",		Button8Mask,	0},
    {"Button8",		Button8Mask,	0},
    {"B9",		Button9Mask,	0},
    {"Button9",		Button9Mask,	0},
    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},
    {"Command",		Mod1Mask,	0},
    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},
    {"Option",		Mod2Mask,	0},
    {"Mod3",		Mod3Mask,	0},









<






<
<

|



|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
>
>

|
>
>






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<

|
<
>
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











>
>
>
>
>
>
>
>


<
<
|
|
|
>
|
>
>
>
|
|
>
>
>
>
|
<
|
>
|
|
>










|




|
>
|
>
>
|
>
|
|
>

















|
|
>
|
|
|
|
>
|





<
<
<


|
|
<
|
|
|
>
|
>
|
|
>
|
|
|

<
<
<
<
<
<
<
<




















|
<
<
<
|
>
|
>
>
|
|
>
|
>
>
|
>
>
|
>
|
>
|
|
>
|
<
>
|
|
|
|
>
|
|
<
>
|
>
|
|
>
>



|
<
>
>
>
>
>
>
>
>
>
>
>

|
>
>






|
|
>
>
>
>
>
>
>
>
>
>
>
>
>






|
>
>
|
>
>




|




|
>

|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|

|
>
|
>
|
>
>
>
|
|
<
<














|


|





|
|


>
>
>
>
>
>
>
>








|
|
>
|
>





|
>
|
>
|
>



|
|
|
|

|

















<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
















25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44





















































45
46
47
48
49


50
51

52
53

54



55









56

57


58















59

















60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156



157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173








174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425








426
427
428
429
430
431
432
/*
 * tkBind.c --
 *
 *	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.
 */

#include "tkInt.h"



#ifdef __WIN32__
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

















/*
 * File structure:
 *
 * Structure definitions and static variables.
 *
 * Init/Free this package.
 *
 * Tcl "bind" command (actually located in tkCmds.c).
 * "bind" command implementation.
 * "bind" implementation helpers.
 *
 * Tcl "event" command.
 * "event" command implementation.
 * "event" implementation helpers.
 *
 * Package-specific common helpers.
 *
 * Non-package-specific helpers.
 */






















































/*
 * 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. */


} 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.
 */



#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. */
} 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>>,
 * <<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.
 */

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. */
} VirtualEventTable;

/*
 * 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 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.
 */

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. */
    int type;			/* Type of event (from X). */
    Detail detail;		/* Additional information, such as keysym,
				 * button, Tk_Uid, or 0 if nothing
				 * additional. */
} PatternTableKey;

/*
 * The following structure defines a pattern, which is matched against X
 * events as part of the process of converting X events into Tcl commands.



 */

typedef struct TkPattern {
    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
				 * virtual event name (never 0). */
} TkPattern;









/*
 * 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
 * helper functions that traverse and match patterns will work for both
 * binding tables and virtual event tables.
 */

typedef struct PatSeq {
    int numPats;		/* Number of patterns in sequence (usually



				 * 1). */
    TkBindEvalProc *eventProc;	/* The function that will be invoked on the
				 * clientData when this pattern sequence
				 * matches. */
    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
				 * 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
				 * pattern sequences for the same object (NULL
				 * for end of list). Needed to implement
				 * Tk_DeleteAllBindings. In a virtual event

				 * table, always NULL. */
    TkPattern 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. */
} 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.
 * 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
 *			skipped if set.
 */

#define PAT_NEARBY		0x1
#define MARKED_DELETED		0x2

/*
 * 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.
 */

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. */
} 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.
 */
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. */
} 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).
 */

typedef struct {
    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;

/*
 * 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.
 */

typedef struct PendingBinding {
    struct PendingBinding *nextPtr;
				/* 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
				 * size of this depends on how many C bindings
				 * matched the event passed to Tk_BindEvent.
				 * THIS FIELD MUST BE THE LAST IN THE
				 * STRUCTURE. */
} PendingBinding;

/*
 * The following structure keeps track of all the information local to the
 * binding package on a per interpreter basis.
 */

typedef struct BindInfo {
    VirtualEventTable virtualEventTable;
				/* 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. */
    PendingBinding *pendingList;/* The list of pending C bindings, kept in
				 * case a C or Tcl binding causes the target
				 * window to be deleted. */
    int deleted;		/* 1 the application has been deleted but the
				 * structure has been preserved. */


} BindInfo;

/*
 * 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. */
} KeySymInfo;
static KeySymInfo keyArray[] = {
#ifndef lint
#include "ks_names.h"
#endif
    {NULL, 0}
};
static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */
static Tcl_HashTable nameTable;	/* keyArray hashed by keysym name. */
#endif /* REDO_KEYSYM_LOOKUP */

/*
 * Set to non-zero when the package-wide static variables have been
 * initialized.
 */

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.
 */

typedef struct {
    char *name;			/* Name of modifier. */
    int mask;			/* Button/modifier mask value, such as
				 * Button1Mask. */
    int flags;			/* Various flags; see below for
				 * definitions. */
} ModInfo;

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event,
 *			e.g. for double-clicks.
 * TRIPLE -		Non-zero means triplicate this event,
 *			e.g. for triple-clicks.
 * QUADRUPLE -		Non-zero means quadruple this event,
 *			e.g. for 4-fold-clicks.
 * MULT_CLICKS -	Combination of all of above.
 */

#define DOUBLE		1
#define TRIPLE		2
#define QUADRUPLE	4
#define MULT_CLICKS	7

static ModInfo modArray[] = {
    {"Control",		ControlMask,	0},
    {"Shift",		ShiftMask,	0},
    {"Lock",		LockMask,	0},
    {"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},
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},
    {"Button3",		Button3Mask,	0},
    {"B4",		Button4Mask,	0},
    {"Button4",		Button4Mask,	0},
    {"B5",		Button5Mask,	0},
    {"Button5",		Button5Mask,	0},








    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},
    {"Command",		Mod1Mask,	0},
    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},
    {"Option",		Mod2Mask,	0},
    {"Mod3",		Mod3Mask,	0},
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502

503
504
505
506
507
508
509
/*
 * 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 {
    const char *name;	/* Name of event. */
    unsigned type;	/* Event type for X, such as ButtonPress. */
    unsigned 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.
 */

static const EventInfo eventArray[] = {
    {"Key",		KeyPress,		KeyPressMask},
    {"KeyPress",	KeyPress,		KeyPressMask},
    {"KeyRelease",	KeyRelease,		KeyPressMask|KeyReleaseMask},
    {"Button",		ButtonPress,		ButtonPressMask},
    {"ButtonPress",	ButtonPress,		ButtonPressMask},
    {"ButtonRelease",	ButtonRelease,		ButtonPressMask|ButtonReleaseMask},

    {"Motion",		MotionNotify,		ButtonPressMask|PointerMotionMask},

    {"Enter",		EnterNotify,		EnterWindowMask},
    {"Leave",		LeaveNotify,		LeaveWindowMask},
    {"FocusIn",		FocusIn,		FocusChangeMask},
    {"FocusOut",	FocusOut,		FocusChangeMask},
    {"Expose",		Expose,			ExposureMask},
    {"Visibility",	VisibilityNotify,	VisibilityChangeMask},
    {"Destroy",		DestroyNotify,		StructureNotifyMask},







|
|
|
>









|





|
>
|
>







446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
/*
 * 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. */
} 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.
 */

static EventInfo eventArray[] = {
    {"Key",		KeyPress,		KeyPressMask},
    {"KeyPress",	KeyPress,		KeyPressMask},
    {"KeyRelease",	KeyRelease,		KeyPressMask|KeyReleaseMask},
    {"Button",		ButtonPress,		ButtonPressMask},
    {"ButtonPress",	ButtonPress,		ButtonPressMask},
    {"ButtonRelease",	ButtonRelease,
	    ButtonPressMask|ButtonReleaseMask},
    {"Motion",		MotionNotify,
	    ButtonPressMask|PointerMotionMask},
    {"Enter",		EnterNotify,		EnterWindowMask},
    {"Leave",		LeaveNotify,		LeaveWindowMask},
    {"FocusIn",		FocusIn,		FocusChangeMask},
    {"FocusOut",	FocusOut,		FocusChangeMask},
    {"Expose",		Expose,			ExposureMask},
    {"Visibility",	VisibilityNotify,	VisibilityChangeMask},
    {"Destroy",		DestroyNotify,		StructureNotifyMask},
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
    {"Create",		CreateNotify,		SubstructureNotifyMask},
    {"MapRequest",	MapRequest,		SubstructureRedirectMask},
    {"ResizeRequest",	ResizeRequest,		ResizeRedirectMask},
    {NULL,		0,			0}
};
static Tcl_HashTable eventTable;

static int eventArrayIndex[TK_LASTEVENT];

/*
 * 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			(1<<0)
#define BUTTON			(1<<1)
#define MOTION			(1<<2)
#define CROSSING		(1<<3)
#define FOCUS			(1<<4)
#define EXPOSE			(1<<5)
#define VISIBILITY		(1<<6)
#define CREATE			(1<<7)
#define DESTROY			(1<<8)
#define UNMAP			(1<<9)
#define MAP			(1<<10)
#define REPARENT		(1<<11)
#define CONFIG			(1<<12)
#define GRAVITY			(1<<13)
#define CIRC			(1<<14)
#define PROP			(1<<15)
#define COLORMAP		(1<<16)
#define VIRTUAL			(1<<17)
#define ACTIVATE		(1<<18)
#define WHEEL			(1<<19)
#define	MAPREQ			(1<<20)
#define	CONFIGREQ		(1<<21)
#define	RESIZEREQ		(1<<22)
#define CIRCREQ			(1<<23)

/*

 * These structs agree with xkey for the fields type, serial, send_event, display,
 * window, root, subwindow, time, x, y, x_root, and y_root.  So when accessing
 * these fields we may pretend that we are using a struct xkey.
 */

#define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL)

/*
 * The xcrossing struct puts the state field in a different location, but the other
 * events above agree on where state is located.
 */

#define HAS_XKEY_HEAD_AND_STATE (KEY|BUTTON|MOTION|VIRTUAL|WHEEL)

/*
 * Event types which support -warp.
 */

#define CAN_WARP (KEY|BUTTON|MOTION|WHEEL)

static const int flagArray[TK_LASTEVENT] = {
   /* Not used */		0,
   /* Not used */		0,
   /* KeyPress */		KEY,
   /* KeyRelease */		KEY,
   /* ButtonPress */		BUTTON,
   /* ButtonRelease */		BUTTON,
   /* MotionNotify */		MOTION,







<
<








|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
<
>
|
<
<
<
|
|
|
<
<
<
<
|
|

<
<
<
|
|

|







496
497
498
499
500
501
502


503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524









525
526

527
528



529
530
531




532
533
534



535
536
537
538
539
540
541
542
543
544
545
    {"Create",		CreateNotify,		SubstructureNotifyMask},
    {"MapRequest",	MapRequest,		SubstructureRedirectMask},
    {"ResizeRequest",	ResizeRequest,		ResizeRedirectMask},
    {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.
 */

#define KEY			0x1
#define BUTTON			0x2
#define MOTION			0x4
#define CROSSING		0x8
#define FOCUS			0x10
#define EXPOSE			0x20
#define VISIBILITY		0x40
#define CREATE			0x80
#define DESTROY			0x100
#define UNMAP			0x200
#define MAP			0x400
#define REPARENT		0x800
#define CONFIG			0x1000
#define GRAVITY			0x2000









#define CIRC			0x4000
#define PROP			0x8000

#define COLORMAP		0x10000
#define VIRTUAL			0x20000



#define ACTIVATE		0x40000
#define	MAPREQ			0x80000
#define	CONFIGREQ		0x100000




#define	RESIZEREQ		0x200000
#define CIRCREQ			0x400000




#define KEY_BUTTON_MOTION_VIRTUAL	(KEY|BUTTON|MOTION|VIRTUAL)
#define KEY_BUTTON_MOTION_CROSSING	(KEY|BUTTON|MOTION|VIRTUAL|CROSSING)

static int flagArray[TK_LASTEVENT] = {
   /* Not used */		0,
   /* Not used */		0,
   /* KeyPress */		KEY,
   /* KeyRelease */		KEY,
   /* ButtonPress */		BUTTON,
   /* ButtonRelease */		BUTTON,
   /* MotionNotify */		MOTION,
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
   /* SelectionNotify */	0,
   /* ColormapNotify */		COLORMAP,
   /* ClientMessage */		0,
   /* MappingNotify */		0,
   /* VirtualEvent */		VIRTUAL,
   /* Activate */		ACTIVATE,
   /* Deactivate */		ACTIVATE,
   /* MouseWheel */		WHEEL
};

/*
 * 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 const TkStateMap queuePosition[] = {
    {-1,		"now"},
    {TCL_QUEUE_HEAD,	"head"},
    {TCL_QUEUE_MARK,	"mark"},
    {TCL_QUEUE_TAIL,	"tail"},
    {-2,		NULL}
};

/*
 * The following tables are used as a two-way map between X's internal numeric
 * values for fields in an XEvent and the strings used in Tcl. The tables are
 * used both when constructing an XEvent from user input and when providing
 * data from an XEvent to the user.







|








|
|
|
|
|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
   /* SelectionNotify */	0,
   /* ColormapNotify */		COLORMAP,
   /* ClientMessage */		0,
   /* MappingNotify */		0,
   /* VirtualEvent */		VIRTUAL,
   /* 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.
 */

static const TkStateMap queuePosition[] = {
    {-1,			"now"},
    {TCL_QUEUE_HEAD,		"head"},
    {TCL_QUEUE_MARK,		"mark"},
    {TCL_QUEUE_TAIL,		"tail"},
    {-2,			NULL}
};

/*
 * The following tables are used as a two-way map between X's internal numeric
 * values for fields in an XEvent and the strings used in Tcl. The tables are
 * used both when constructing an XEvent from user input and when providing
 * data from an XEvent to the user.
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708

709
710

711
712
713

714

715

716
717
718

719
720
721
722

723

724
725
726
727
728


729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
    {NotifyPointer,		"NotifyPointer"},
    {NotifyPointerRoot,		"NotifyPointerRoot"},
    {NotifyDetailNone,		"NotifyDetailNone"},
    {-1, NULL}
};

static const TkStateMap circPlace[] = {
    {PlaceOnTop,	"PlaceOnTop"},
    {PlaceOnBottom,	"PlaceOnBottom"},
    {-1, NULL}
};

static const TkStateMap visNotify[] = {
    {VisibilityUnobscured,	  "VisibilityUnobscured"},
    {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"},
    {VisibilityFullyObscured,	  "VisibilityFullyObscured"},
    {-1, NULL}
};

static const TkStateMap configureRequestDetail[] = {
    {None,	"None"},
    {Above,	"Above"},
    {Below,	"Below"},
    {BottomIf,	"BottomIf"},
    {TopIf,	"TopIf"},
    {Opposite,	"Opposite"},
    {-1, NULL}
};

static const TkStateMap propNotify[] = {
    {PropertyNewValue,	"NewValue"},
    {PropertyDelete,	"Delete"},
    {-1, NULL}
};

DEBUG(static int countTableItems = 0;)
DEBUG(static int countEntryItems = 0;)
DEBUG(static int countListItems = 0;)
DEBUG(static int countBindItems = 0;)
DEBUG(static int countSeqItems = 0;)

/*
 * Prototypes for local functions defined in this file:
 */

static void		ChangeScreen(Tcl_Interp *interp, char *dispName, int screenIndex);

static int		CreateVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,

			    char *virtString, const char *eventString);
static int		DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,

			    char *virtString, const char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPtr,

			    unsigned scriptCount, Tcl_DString *dsPtr);

static PatSeq *		FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,

			    ClientData object, const char *eventString, int create,
			    int allowVirtual, unsigned *maskPtr);
static void		GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);

static const char *	GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj *	GetPatternObj(const PatSeq *psPtr);
static int		GetVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    Tcl_Obj *virtName);

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, Tk_BindingTable bindPtr, PSList *psList,
			    PSList *psSuccList, unsigned patIndex, const Event *eventPtr,


			    ClientData object, PatSeq **physPtrPtr);
static int		NameToWindow(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static unsigned		ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr,
			    TkPattern *patPtr, unsigned *eventMaskPtr);
static PSList *		GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr,
			    Tcl_Obj *object, int onlyConsiderDetailedEvents);
static void		ClearLookupTable(LookupTables *lookupTables, ClientData object);
static void		ClearPromotionLists(Tk_BindingTable bindPtr, ClientData object);
static PSEntry *	MakeListEntry(PSList *pool, PatSeq *psPtr, int needModMasks);
static void		RemovePatSeqFromLookup(LookupTables *lookupTables, PatSeq *psPtr);
static void		RemovePatSeqFromPromotionLists(Tk_BindingTable bindPtr, PatSeq *psPtr);
static PatSeq *		DeletePatSeq(PatSeq *psPtr);
static void		InsertPatSeq(LookupTables *lookupTables, PatSeq *psPtr);
#if SUPPORT_DEBUGGING
void			TkpDumpPS(const PatSeq *psPtr);
void			TkpDumpPSList(const PSList *psList);
#endif

/*
 * Some useful helper functions.
 */
#ifdef SUPPORT_DEBUGGING
static int BindCount = 0;
#endif

static unsigned Max(unsigned a, unsigned b) { return a < b ? b : a; }
static int Abs(int n) { return n < 0 ? -n : n; }
static int IsOdd(int n) { return n & 1; }

static int TestNearbyTime(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_MS; }
static int TestNearbyCoords(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_PIXELS; }

static int
IsSubsetOf(
    unsigned lhsMask,	/* this is a subset */
    unsigned rhsMask)	/* of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)
{
    assert(s);
    while (isspace(UCHAR(*s)))
	++s;
    return s;
}

static const char*
SkipFieldDelims(
    const char* s)
{
    assert(s);
    while (*s == '-' || isspace(UCHAR(*s))) {
	++s;
    }
    return s;
}

static unsigned
GetButtonNumber(
    const char *field)
{
    unsigned button;
    assert(field);
    button = (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? field[0] - '0' : 0;
    return (button > 3) ? (button + 4) : button;
}

static Time
CurrentTimeInMilliSecs(void)
{
    Tcl_Time now;
    Tcl_GetTime(&now);
    return ((Time) now.sec)*1000 + ((Time) now.usec)/1000;
}

static Info
GetInfo(
    const PatSeq *psPtr,
    unsigned index)
{
    assert(psPtr);
    assert(index < psPtr->numPats);

    return psPtr->pats[index].info;
}

static unsigned
GetCount(
    const PatSeq *psPtr,
    unsigned index)
{
    assert(psPtr);
    assert(index < psPtr->numPats);

    return psPtr->pats[index].count;
}

static int
CountSpecialized(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr)
{
    int fstCount = 0;
    int sndCount = 0;
    unsigned i;

    assert(fstMatchPtr);
    assert(sndMatchPtr);

    for (i = 0; i < fstMatchPtr->numPats; ++i) {
	if (GetInfo(fstMatchPtr, i)) { fstCount += GetCount(fstMatchPtr, i); }
    }
    for (i = 0; i < sndMatchPtr->numPats; ++i) {
	if (GetInfo(sndMatchPtr, i)) { sndCount += GetCount(sndMatchPtr, i); }
    }

    return sndCount - fstCount;
}

int
IsKeyEventType(
    unsigned eventType)
{
    return eventType == KeyPress || eventType == KeyRelease;
}

int
IsButtonEventType(
    unsigned eventType)
{
    return eventType == ButtonPress || eventType == ButtonRelease;
}

static int
MatchEventNearby(
    const XEvent *lhs,	/* previous button event */
    const XEvent *rhs)	/* current button event */
{
    assert(lhs);
    assert(rhs);
    assert(IsButtonEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->xbutton.time <= rhs->xbutton.time */

    return TestNearbyTime(rhs->xbutton.time, lhs->xbutton.time)
	    && TestNearbyCoords(rhs->xbutton.x_root, lhs->xbutton.x_root)
	    && TestNearbyCoords(rhs->xbutton.y_root, lhs->xbutton.y_root);
}

static int
MatchEventRepeat(
    const XKeyEvent *lhs,	/* previous key event */
    const XKeyEvent *rhs)	/* current key event */
{
    assert(lhs);
    assert(rhs);
    assert(IsKeyEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->time <= rhs->time */
    return lhs->keycode == rhs->keycode && TestNearbyTime(lhs->time, rhs->time);
}

static void
FreePatSeq(
    PatSeq *psPtr)
{
    assert(psPtr);
    assert(!psPtr->owned);
    DEBUG(MARK_PSENTRY(psPtr);)
    ckfree(psPtr->script);
    if (!psPtr->object) {
	VirtOwners_Free(&psPtr->ptr.owners);
    }
    ckfree(psPtr);
    DEBUG(countSeqItems -= 1;)
}

static void
RemoveListEntry(
    PSList *pool,
    PSEntry *psEntry)
{
    assert(pool);
    assert(psEntry);

    if (PSModMaskArr_Capacity(psEntry->lastModMaskArr) > MAX_MOD_MASK_ARR_SIZE) {
	PSModMaskArr_Free(&psEntry->lastModMaskArr);
    }
    PSList_Remove(psEntry);
    PSList_Append(pool, psEntry);
}

static void
ClearList(
    PSList *psList,
    PSList *pool,
    ClientData object)
{
    assert(psList);
    assert(pool);

    if (object) {
	PSEntry *psEntry;
	PSEntry *psNext;

	for (psEntry = PSList_First(psList); psEntry; psEntry = psNext) {
	    psNext = PSList_Next(psEntry);
	    if (psEntry->psPtr->object == object) {
		RemoveListEntry(pool, psEntry);
	    }
	}
    } else {
	PSList_Move(pool, psList);
    }
}

static PSEntry *
FreePatSeqEntry(
    TCL_UNUSED(PSList *),
    PSEntry *entry)
{
    PSEntry *next = PSList_Next(entry);

    PSModMaskArr_Free(&entry->lastModMaskArr);
    ckfree(entry);
    return next;
}

static unsigned
ResolveModifiers(
    TkDisplay *dispPtr,
    unsigned modMask)
{
    assert(dispPtr);

    if (dispPtr->metaModMask) {
	if (modMask & META_MASK) {
	    modMask &= ~META_MASK;
	    modMask |= dispPtr->metaModMask;
	}
    }
    if (dispPtr->altModMask) {
	if (modMask & ALT_MASK) {
	    modMask &= ~ALT_MASK;
	    modMask |= dispPtr->altModMask;
	}
    }

    return modMask;
}

static int
ButtonNumberFromState(
    unsigned state)
{
    if (!(state & ALL_BUTTONS)) { return 0; }
    if (state & Button1Mask) { return 1; }
    if (state & Button2Mask) { return 2; }
    if (state & Button3Mask) { return 3; }
    if (state & Button4Mask) { return 4; }
    if (state & Button5Mask) { return 5; }
    if (state & Button6Mask) { return 6; }
    if (state & Button7Mask) { return 7; }
    if (state & Button8Mask) { return 8; }
    return 9;
}

static void
SetupPatternKey(
    PatternTableKey *key,
    const PatSeq *psPtr)
{
    const TkPattern *patPtr;

    assert(key);
    assert(psPtr);

    /* otherwise on some systems the key contains uninitialized bytes */
    memset(key, 0, sizeof(PatternTableKey));

    patPtr = psPtr->pats;
    assert(!patPtr->info || !patPtr->name);

    key->object = psPtr->object;
    key->type = patPtr->eventType;
    if (patPtr->info) {
	key->detail.info = patPtr->info;
    } else {
	key->detail.name = patPtr->name;
    }
}

/*
 *--------------------------------------------------------------
 *
 * MakeListEntry --
 *
 *	Makes new entry item for lookup table. We are using a
 *	pool of items, this avoids superfluous memory allocation/
 *	deallocation.
 *
 * Results:
 *	New entry item.
 *
 * Side effects:
 *	Memory allocated.
 *
 *--------------------------------------------------------------
 */

static PSEntry *
MakeListEntry(
    PSList *pool,
    PatSeq *psPtr,
    int needModMasks)
{
    PSEntry *newEntry = NULL;

    assert(pool);
    assert(psPtr);
    assert(psPtr->numPats > 0);
    assert(TEST_PSENTRY(psPtr));

    if (PSList_IsEmpty(pool)) {
	newEntry = (PSEntry *)ckalloc(sizeof(PSEntry));
	newEntry->lastModMaskArr = NULL;
	DEBUG(countEntryItems += 1;)
    } else {
	newEntry = PSList_First(pool);
	PSList_RemoveHead(pool);
    }

    if (!needModMasks) {
	PSModMaskArr_SetSize(newEntry->lastModMaskArr, 0);
    } else {
	if (PSModMaskArr_Capacity(newEntry->lastModMaskArr) < psPtr->numPats - 1) {
	    PSModMaskArr_Resize(&newEntry->lastModMaskArr, psPtr->numPats - 1);
	}
	PSModMaskArr_SetSize(newEntry->lastModMaskArr, psPtr->numPats - 1);
    }

    newEntry->psPtr = psPtr;
    newEntry->window = None;
    newEntry->expired = 0;
    newEntry->keepIt = 1;
    newEntry->count = 1;
    DEBUG(psPtr->owned = 0;)

    return newEntry;
}

/*
 *--------------------------------------------------------------
 *
 * GetLookupForEvent --
 *
 *	Get specific pattern sequence table for given event.
 *
 * Results:
 *	Specific pattern sequence table for given event.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static PSList *
GetLookupForEvent(
    LookupTables* lookupTables,
    const Event *eventPtr,
    Tcl_Obj *object,
    int onlyConsiderDetailedEvents)
{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(eventPtr);

    /* otherwise on some systems the key contains uninitialized bytes */
    memset(&key, 0, sizeof(PatternTableKey));

    if (onlyConsiderDetailedEvents) {
	switch (eventPtr->xev.type) {
	case ButtonPress:   /* fallthru */
	case ButtonRelease: key.detail.info = eventPtr->xev.xbutton.button; break;
	case MotionNotify:  key.detail.info = ButtonNumberFromState(eventPtr->xev.xmotion.state); break;
	case KeyPress:      /* fallthru */
	case KeyRelease:    key.detail.info = eventPtr->detail.info; break;
	case VirtualEvent:  key.detail.name = eventPtr->detail.name; break;
	}
	if (!key.detail.name) {
	    assert(!key.detail.info);
	    return NULL;
	}
    }

    key.object = object;
    key.type = eventPtr->xev.type;
    hPtr = Tcl_FindHashEntry(&lookupTables->listTable, (char *) &key);
    return hPtr ? (PSList *)Tcl_GetHashValue(hPtr) : NULL;
}

/*
 *--------------------------------------------------------------
 *
 * ClearLookupTable --
 *
 *	Clear lookup table in given binding table, but only those
 *	bindings associated to given object. If object is NULL
 *	then remove all entries.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */
static void
ClearLookupTable(
    LookupTables *lookupTables,
    ClientData object)
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_HashEntry *nextPtr;
    PSList *pool = &lookupTables->entryPool;

    assert(lookupTables);

    for (hPtr = Tcl_FirstHashEntry(&lookupTables->listTable, &search); hPtr; hPtr = nextPtr) {
	PSList *psList;

	nextPtr = Tcl_NextHashEntry(&search);

	if (object) {
	    const PatternTableKey *key = (const PatternTableKey *)Tcl_GetHashKey(&lookupTables->listTable, hPtr);
	    if (key->object != object) {
		continue;
	    }
	}

	psList = (PSList *)Tcl_GetHashValue(hPtr);
	PSList_Move(pool, psList);
	ckfree(psList);
	DEBUG(countListItems -= 1;)
	Tcl_DeleteHashEntry(hPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ClearPromotionLists --
 *
 *	Clear all the lists holding the promoted pattern
 *	sequences, which belongs to given object. If object
 *	is NULL then remove all patterns.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
ClearPromotionLists(
    Tk_BindingTable bindPtr,
    ClientData object)
{
    unsigned newArraySize = 0;
    unsigned i;

    assert(bindPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	ClearList(psList, &bindPtr->lookupTables.entryPool, object);
	if (!PSList_IsEmpty(psList)) {
	    newArraySize = i + 1;
	}
    }

    PromArr_SetSize(bindPtr->promArr, newArraySize);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkBindInit --
 *
 *	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.
 *
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * Windoze compiler does not allow the definition of these static variables inside a function,
 * otherwise this should belong to function TkBindInit().
 */
TCL_DECLARE_MUTEX(bindMutex);
static int initialized = 0;

void
TkBindInit(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;

    assert(mainPtr);

    /* otherwise virtual events can't be supported */
    assert(sizeof(XEvent) >= sizeof(XVirtualEvent));

    /* type of TkPattern.info is well defined? */
    assert(sizeof(Info) >= sizeof(KeySym));
    assert(sizeof(Info) >= sizeof(unsigned));

    /* ensure that our matching algorithm is working (when testing detail) */
    assert(sizeof(Detail) == sizeof(Tk_Uid));

    /* test expected indices of Button1..Button5, otherwise our button handling is not working */
    assert(Button1 == 1 && Button2 == 2 && Button3 == 3 && Button4 == 4 && Button5 == 5);
    assert(Button2Mask == (Button1Mask << 1));
    assert(Button3Mask == (Button1Mask << 2));
    assert(Button4Mask == (Button1Mask << 3));
    assert(Button5Mask == (Button1Mask << 4));

    /* test expected values of button motion masks, otherwise our button handling is not working */
    assert(Button1MotionMask == Button1Mask);
    assert(Button2MotionMask == Button2Mask);
    assert(Button3MotionMask == Button3Mask);
    assert(Button4MotionMask == Button4Mask);
    assert(Button5MotionMask == Button5Mask);

    /* because we expect zero if keySym is empty */
    assert(NoSymbol == 0L);

    /* this must be a union, not a struct, otherwise comparison with NULL will not work */
    assert(offsetof(Detail, name) == offsetof(Detail, info));

    /* we use some constraints about X*Event */
    assert(offsetof(XButtonEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XButtonEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XButtonEvent, y_root) == offsetof(XMotionEvent, y_root));
    assert(offsetof(XCreateWindowEvent, border_width) == offsetof(XConfigureEvent, border_width));
    assert(offsetof(XCreateWindowEvent, width) == offsetof(XConfigureEvent, width));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XCirculateRequestEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XConfigureEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XGravityEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XMapEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XReparentEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XUnmapEvent, window));
    assert(offsetof(XCreateWindowEvent, x) == offsetof(XConfigureEvent, x));
    assert(offsetof(XCreateWindowEvent, x) == offsetof(XGravityEvent, x));
    assert(offsetof(XCreateWindowEvent, y) == offsetof(XConfigureEvent, y));
    assert(offsetof(XCreateWindowEvent, y) == offsetof(XGravityEvent, y));
    assert(offsetof(XCrossingEvent, time) == offsetof(XEnterWindowEvent, time));
    assert(offsetof(XCrossingEvent, time) == offsetof(XLeaveWindowEvent, time));
    assert(offsetof(XCrossingEvent, time) == offsetof(XKeyEvent, time));
    assert(offsetof(XKeyEvent, root) == offsetof(XButtonEvent, root));
    assert(offsetof(XKeyEvent, root) == offsetof(XCrossingEvent, root));
    assert(offsetof(XKeyEvent, root) == offsetof(XMotionEvent, root));
    assert(offsetof(XKeyEvent, state) == offsetof(XButtonEvent, state));
    assert(offsetof(XKeyEvent, state) == offsetof(XMotionEvent, state));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XButtonEvent, subwindow));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XCrossingEvent, subwindow));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XMotionEvent, subwindow));
    assert(offsetof(XKeyEvent, time) == offsetof(XButtonEvent, time));
    assert(offsetof(XKeyEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XKeyEvent, x) == offsetof(XButtonEvent, x));
    assert(offsetof(XKeyEvent, x) == offsetof(XCrossingEvent, x));
    assert(offsetof(XKeyEvent, x) == offsetof(XMotionEvent, x));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XButtonEvent, x_root));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XCrossingEvent, x_root));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XKeyEvent, y) == offsetof(XButtonEvent, y));
    assert(offsetof(XKeyEvent, y) == offsetof(XCrossingEvent, y));
    assert(offsetof(XKeyEvent, y) == offsetof(XMotionEvent, y));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XButtonEvent, y_root));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XCrossingEvent, y_root));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XMotionEvent, y_root));

    /*
     * 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);
	if (!initialized) {
	    Tcl_HashEntry *hPtr;
	    const ModInfo *modPtr;
	    const EventInfo *eiPtr;
	    int newEntry;
	    unsigned i;
#ifdef REDO_KEYSYM_LOOKUP
	    const KeySymInfo *kPtr;

	    Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS);
	    Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS);
	    for (kPtr = keyArray; kPtr->name; ++kPtr) {
		hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &newEntry);
		Tcl_SetHashValue(hPtr, kPtr->value);
		hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, &newEntry);

		if (newEntry) {
		    Tcl_SetHashValue(hPtr, kPtr->name);
		}
	    }
#endif /* REDO_KEYSYM_LOOKUP */

	    for (i = 0; i < SIZE_OF_ARRAY(eventArrayIndex); ++i) {
		eventArrayIndex[i] = -1;
	    }
	    for (i = 0; i < SIZE_OF_ARRAY(eventArray); ++i) {
		unsigned type = eventArray[i].type;
		assert(type < TK_LASTEVENT);
		assert(type > 0 || i == SIZE_OF_ARRAY(eventArray) - 1);
		if (type > 0 && eventArrayIndex[type] == -1) {
		    eventArrayIndex[type] = i;
		}
	    }

	    Tcl_InitHashTable(&modTable, TCL_STRING_KEYS);
	    for (modPtr = modArray; modPtr->name; ++modPtr) {
		hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &newEntry);
		Tcl_SetHashValue(hPtr, modPtr);
	    }

	    Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS);
	    for (eiPtr = eventArray; eiPtr->name; ++eiPtr) {
		hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &newEntry);
		Tcl_SetHashValue(hPtr, eiPtr);
	    }

	    initialized = 1;
	}
	Tcl_MutexUnlock(&bindMutex);
    }

    mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp);

    bindInfoPtr = (BindInfo *)ckalloc(sizeof(BindInfo));
    InitVirtualEventTable(&bindInfoPtr->virtualEventTable);
    bindInfoPtr->screenInfo.curDispPtr = NULL;
    bindInfoPtr->screenInfo.curScreenIndex = -1;
    bindInfoPtr->screenInfo.bindingDepth = 0;
    bindInfoPtr->deleted = 0;
    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
    bindInfoPtr->lastEventTime = 0;
    mainPtr->bindInfo = bindInfoPtr;
    DEBUG(countBindItems += 1;)

    TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable);
}

/*
 *---------------------------------------------------------------------------
 *







|
|











|
|
|
|
|
|









<
<
<
<
<
<




|
>
|
>
|
|
>
|

|
>
|
>
|
>
|
|
|
>
|
|
|
<
>
|
>



|
<
>
>
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















<
<
<
<
<
<
<






<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|
|

<

|



|


|
>






<
<
<
<
<
<
<
<
<
<
<
<

|





|



<







|




|
<
|
|
<







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648






649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681

682
683
684
685
686
687




























































688












































689



























































690


















































































691














































692
















693







694




695








696

































697







698


699


















































































































700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718







719
720
721
722
723
724

725
726

727




































































728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756












757
758
759
760
761
762
763
764
765
766
767

768
769
770
771
772
773
774
775
776
777
778
779
780

781
782

783
784
785
786
787
788
789
    {NotifyPointer,		"NotifyPointer"},
    {NotifyPointerRoot,		"NotifyPointerRoot"},
    {NotifyDetailNone,		"NotifyDetailNone"},
    {-1, NULL}
};

static const TkStateMap circPlace[] = {
    {PlaceOnTop,		"PlaceOnTop"},
    {PlaceOnBottom,		"PlaceOnBottom"},
    {-1, NULL}
};

static const TkStateMap visNotify[] = {
    {VisibilityUnobscured,	  "VisibilityUnobscured"},
    {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"},
    {VisibilityFullyObscured,	  "VisibilityFullyObscured"},
    {-1, NULL}
};

static const TkStateMap configureRequestDetail[] = {
    {None,		"None"},
    {Above,		"Above"},
    {Below,		"Below"},
    {BottomIf,		"BottomIf"},
    {TopIf,		"TopIf"},
    {Opposite,		"Opposite"},
    {-1, NULL}
};

static const TkStateMap propNotify[] = {
    {PropertyNewValue,	"NewValue"},
    {PropertyDelete,	"Delete"},
    {-1, NULL}
};







/*
 * Prototypes for local functions defined in this file:
 */

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(Tcl_Interp *interp,
			    VirtualEventTable *vetPtr, char *virtString,
			    char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before,
			    XEvent *eventPtr,KeySym keySym,
			    unsigned int scriptCount, 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(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(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static int		ParseEventDescription(Tcl_Interp *interp,




























































			    const char **eventStringPtr, TkPattern *patPtr,












































			    unsigned long *eventMaskPtr);



























































static void		DoWarp(ClientData clientData);

































































































































/*
















 * 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 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.
 *
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */








void
TkBindInit(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;


    if (sizeof(XEvent) < sizeof(XVirtualEvent)) {
	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.
     */

    if (!initialized) {
	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);
		Tcl_SetHashValue(hPtr, kPtr->value);
		hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value,
			&newEntry);
		if (newEntry) {
		    Tcl_SetHashValue(hPtr, kPtr->name);
		}
	    }
#endif /* REDO_KEYSYM_LOOKUP */













	    Tcl_InitHashTable(&modTable, TCL_STRING_KEYS);
	    for (modPtr = modArray; modPtr->name != NULL; modPtr++) {
		hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &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);
		Tcl_SetHashValue(hPtr, eiPtr);
	    }

	    initialized = 1;
	}
	Tcl_MutexUnlock(&bindMutex);
    }

    mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp);

    bindInfoPtr = (BindInfo *) ckalloc(sizeof(BindInfo));
    InitVirtualEventTable(&bindInfoPtr->virtualEventTable);
    bindInfoPtr->screenInfo.curDispPtr = NULL;
    bindInfoPtr->screenInfo.curScreenIndex = -1;
    bindInfoPtr->screenInfo.bindingDepth = 0;
    bindInfoPtr->pendingList = NULL;

    bindInfoPtr->deleted = 0;
    mainPtr->bindInfo = (TkBindInfo) bindInfoPtr;


    TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable);
}

/*
 *---------------------------------------------------------------------------
 *
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432

1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450

void
TkBindFree(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;

    assert(mainPtr);

    Tk_DeleteBindingTable(mainPtr->bindingTable);
    mainPtr->bindingTable = NULL;

    bindInfoPtr = mainPtr->bindInfo;
    DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable);
    bindInfoPtr->deleted = 1;
    Tcl_EventuallyFree(bindInfoPtr, TCL_DYNAMIC);
    mainPtr->bindInfo = NULL;

    DEBUG(countBindItems -= 1;)
    assert(countBindItems > 0 || countTableItems == 0);
    assert(countBindItems > 0 || countEntryItems == 0);
    assert(countBindItems > 0 || countListItems == 0);
    assert(countBindItems > 0 || countSeqItems == 0);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateBindingTable --
 *







<
<


>
|


|

<
<
<
<
<
<







803
804
805
806
807
808
809


810
811
812
813
814
815
816
817






818
819
820
821
822
823
824

void
TkBindFree(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;



    Tk_DeleteBindingTable(mainPtr->bindingTable);
    mainPtr->bindingTable = NULL;

    bindInfoPtr = (BindInfo *) mainPtr->bindInfo;
    DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable);
    bindInfoPtr->deleted = 1;
    Tcl_EventuallyFree((ClientData) bindInfoPtr, TCL_DYNAMIC);
    mainPtr->bindInfo = NULL;






}

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateBindingTable --
 *
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
 *	Memory is allocated for the new table.
 *
 *--------------------------------------------------------------
 */

Tk_BindingTable
Tk_CreateBindingTable(
    Tcl_Interp *interp)		/* Interpreter to associate with the binding table: commands are

    				 * executed in this interpreter. */
{
    BindingTable *bindPtr = (BindingTable *)ckalloc(sizeof(BindingTable));
    unsigned i;

    assert(interp);
    DEBUG(countTableItems += 1;)

    /*
     * Create and initialize a new binding table.
     */

    memset(bindPtr, 0, sizeof(BindingTable));
    for (i = 0; i < SIZE_OF_ARRAY(bindPtr->eventInfo); ++i) {
	bindPtr->eventInfo[i].xev.type = -1;
    }
    bindPtr->curEvent = bindPtr->eventInfo; /* do not assign NULL */
    bindPtr->lookupTables.number = 0;
    PromArr_ResizeAndClear(&bindPtr->promArr, 2);
    Tcl_InitHashTable(&bindPtr->lookupTables.listTable, sizeof(PatternTableKey)/sizeof(int));
    Tcl_InitHashTable(&bindPtr->lookupTables.patternTable, sizeof(PatternTableKey)/sizeof(int));
    Tcl_InitHashTable(&bindPtr->objectTable, TCL_ONE_WORD_KEYS);
    bindPtr->interp = interp;
    return bindPtr;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteBindingTable --
 *







|
>
|

|
|
<
<
<





|
|
|

|
<
<
|
|


|







832
833
834
835
836
837
838
839
840
841
842
843
844



845
846
847
848
849
850
851
852
853
854


855
856
857
858
859
860
861
862
863
864
865
866
 *	Memory is allocated for the new table.
 *
 *--------------------------------------------------------------
 */

Tk_BindingTable
Tk_CreateBindingTable(
    Tcl_Interp *interp)		/* Interpreter to associate with the binding
				 * table: commands are executed in this
				 * interpreter. */
{
    BindingTable *bindPtr;
    int i;




    /*
     * Create and initialize a new binding table.
     */

    bindPtr = (BindingTable *) ckalloc(sizeof(BindingTable));
    for (i = 0; i < EVENT_BUFFER_SIZE; i++) {
	bindPtr->eventRing[i].type = -1;
    }
    bindPtr->curEvent = 0;


    Tcl_InitHashTable(&bindPtr->patternTable,
	    sizeof(PatternTableKey)/sizeof(int));
    Tcl_InitHashTable(&bindPtr->objectTable, TCL_ONE_WORD_KEYS);
    bindPtr->interp = interp;
    return (Tk_BindingTable) bindPtr;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteBindingTable --
 *
1504
1505
1506
1507
1508
1509
1510

1511
1512


1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529





1530

1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
 *	Memory is freed.
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteBindingTable(

    Tk_BindingTable bindPtr)	/* Token for the binding table to destroy. */
{


    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    assert(bindPtr);

    /*
     * Find and delete all of the patterns associated with the binding table.
     */

    hPtr = Tcl_FirstHashEntry(&bindPtr->lookupTables.patternTable, &search);
    for ( ; hPtr; hPtr = Tcl_NextHashEntry(&search)) {
	PatSeq *nextPtr;
	PatSeq *psPtr;

	for (psPtr = (PatSeq *)Tcl_GetHashValue(hPtr); psPtr; psPtr = nextPtr) {
	    assert(TEST_PSENTRY(psPtr));
	    nextPtr = psPtr->nextSeqPtr;





	    FreePatSeq(psPtr);

	}
    }

    /*
     * Don't forget to release lookup elements.
     */

    ClearLookupTable(&bindPtr->lookupTables, NULL);
    ClearPromotionLists(bindPtr, NULL);
    PromArr_Free(&bindPtr->promArr);
    DEBUG(countEntryItems -= PSList_Size(&bindPtr->lookupTables.entryPool);)
    PSList_Traverse(&bindPtr->lookupTables.entryPool, FreePatSeqEntry);

    /*
     * Clean up the rest of the information associated with the binding table.
     */

    Tcl_DeleteHashTable(&bindPtr->lookupTables.patternTable);
    Tcl_DeleteHashTable(&bindPtr->lookupTables.listTable);
    Tcl_DeleteHashTable(&bindPtr->objectTable);

    ckfree(bindPtr);
    DEBUG(countTableItems -= 1;)
}

/*
 *--------------------------------------------------------------
 *
 * InsertPatSeq --
 *
 *	Insert given pattern sequence into lookup table for fast
 *	access.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory allocated.
 *
 *--------------------------------------------------------------
 */

static void
InsertPatSeq(
    LookupTables *lookupTables,
    PatSeq *psPtr)
{
    assert(lookupTables);
    assert(psPtr);
    assert(TEST_PSENTRY(psPtr));
    assert(psPtr->numPats >= 1u);

    if (!(psPtr->added)) {
	PatternTableKey key;
	Tcl_HashEntry *hPtr;
	int isNew;
	PSList *psList;
	PSEntry *psEntry;

	SetupPatternKey(&key, psPtr);
	hPtr = Tcl_CreateHashEntry(&lookupTables->listTable, (char *) &key, &isNew);

	if (isNew) {
	    psList = (PSList *)ckalloc(sizeof(PSList));
	    PSList_Init(psList);
	    Tcl_SetHashValue(hPtr, psList);
	    DEBUG(countListItems += 1;)
	} else {
	    psList = (PSList *)Tcl_GetHashValue(hPtr);
	}

	psEntry = MakeListEntry(&lookupTables->entryPool, psPtr, 0);
	PSList_Append(psList, psEntry);
	psPtr->added = 1;
    }
}
/*
 *--------------------------------------------------------------
 *
 * Tk_CreateBinding --
 *
 *	Add a binding to a binding table, so that future calls to Tk_BindEvent
 *	may execute the command in the binding.







>
|

>
>



<
<




|
|
<
<
|
|
<

>
>
>
>
>
|
>



<
<
<
<
<
<
<
<
<
<




<
|

<
|
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







874
875
876
877
878
879
880
881
882
883
884
885
886
887
888


889
890
891
892
893
894


895
896

897
898
899
900
901
902
903
904
905
906
907










908
909
910
911

912
913

914

915
916



















































917
918
919
920
921
922
923
 *	Memory is freed.
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteBindingTable(
    Tk_BindingTable bindingTable)
				/* Token for the binding table to destroy. */
{
    BindingTable *bindPtr = (BindingTable *) bindingTable;
    PatSeq *psPtr, *nextPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;



    /*
     * Find and delete all of the patterns associated with the binding table.
     */

    for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search);
	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {


	for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
		psPtr != NULL; psPtr = nextPtr) {

	    nextPtr = psPtr->nextSeqPtr;
	    psPtr->flags |= MARKED_DELETED;
	    if (psPtr->refCount == 0) {
		if (psPtr->freeProc != NULL) {
		    (*psPtr->freeProc)(psPtr->clientData);
		}
		ckfree((char *) psPtr);
	    }
	}
    }











    /*
     * Clean up the rest of the information associated with the binding table.
     */


    Tcl_DeleteHashTable(&bindPtr->patternTable);
    Tcl_DeleteHashTable(&bindPtr->objectTable);

    ckfree((char *) bindPtr);

}




















































/*
 *--------------------------------------------------------------
 *
 * Tk_CreateBinding --
 *
 *	Add a binding to a binding table, so that future calls to Tk_BindEvent
 *	may execute the command in the binding.
1627
1628
1629
1630
1631
1632
1633

1634
1635

1636


1637
1638

1639
1640
1641

1642

1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660































































































1661





1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686




1687

1688
1689




1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706

1707
1708
1709
1710
1711
1712
1713
1714
1715
 *
 *--------------------------------------------------------------
 */

unsigned long
Tk_CreateBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */

    Tk_BindingTable bindPtr,	/* Table in which to create binding. */
    ClientData object,		/* Token for object with which binding is associated. */

    const char *eventString,	/* String describing event sequence that triggers binding. */


    const char *script,		/* Contains Tcl script to execute when binding triggers. */
    int append)			/* 0 means replace any existing binding for eventString;

    				 * 1 means append to that binding. If the existing binding is
				 * for a callback function and not a Tcl command string, the
				 * existing binding will always be replaced. */

{

    PatSeq *psPtr;
    unsigned eventMask;
    char *oldStr;
    char *newStr;

    assert(bindPtr);
    assert(object);
    assert(eventString);
    assert(script);

    psPtr = FindSequence(interp, &bindPtr->lookupTables, object, eventString,
	    !!*script, 1, &eventMask);

    if (!*script) {
	assert(!psPtr || psPtr->added);
	/* Silently ignore empty scripts -- see SF#3006842 */
	return eventMask;
    }































































































    if (!psPtr) {





	return 0;
    }
    assert(TEST_PSENTRY(psPtr));

    if (psPtr->numPats > PromArr_Capacity(bindPtr->promArr)) {
	/*
	 * We have to increase the size of array containing the lists of promoted sequences.
	 * Normally the maximal size is 1, only in very seldom cases a bigger size is needed.
	 * Note that for technical reasons the capacity should be one higher than the expected
	 * maximal size.
	 */
	PromArr_ResizeAndClear(&bindPtr->promArr, psPtr->numPats);
    }

    if (!psPtr->script) {
	Tcl_HashEntry *hPtr;
	int isNew;

	/*
	 * 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, &isNew);




	psPtr->ptr.nextObj = isNew ? NULL : (PatSeq *)Tcl_GetHashValue(hPtr);

	Tcl_SetHashValue(hPtr, psPtr);
	InsertPatSeq(&bindPtr->lookupTables, psPtr);




    }

    oldStr = psPtr->script;
    if (append && oldStr) {
	size_t length1 = strlen(oldStr);
	size_t length2 = strlen(script);

	newStr = (char *)ckalloc(length1 + length2 + 2);
	memcpy(newStr, oldStr, length1);
	newStr[length1] = '\n';
	memcpy(newStr + length1 + 1, script, length2 + 1);
    } else {
	size_t length = strlen(script);

	newStr = (char *)ckalloc(length + 1);
	memcpy(newStr, script, length + 1);
    }

    ckfree(oldStr);
    psPtr->script = newStr;
    return eventMask;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteBinding --







>
|
|
>
|
>
>
|
|
>
|
|
|
>

>

|
<
|

<
<
<
<
<
<
<
<
|
<

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>


<
|
<
<
<
<
<
<
<
<
<
|
<

<







|
>
>
>
>
|
>

<
>
>
>
>
|
|
|
<
<
<
|
<
<
<
<
<
<
|
<
<
|
>
|
|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961

962
963








964

965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070

1071









1072

1073

1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095



1096






1097


1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
 *
 *--------------------------------------------------------------
 */

unsigned long
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
				 * associated. */
    const char *eventString,	/* String describing event sequence that
				 * triggers binding. */
    const char *command,	/* Contains Tcl command to execute when
				 * binding triggers. */
    int append)			/* 0 means replace any existing binding for
				 * eventString; 1 means append to that
				 * binding. If the existing binding is for a
				 * callback function and not a Tcl command
				 * string, the existing binding will always be
				 * replaced. */
{
    BindingTable *bindPtr = (BindingTable *) bindingTable;
    PatSeq *psPtr;
    unsigned long eventMask;

    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 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.
	 */

	hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object,
		&isNew);
	if (isNew) {
	    psPtr->nextObjPtr = NULL;
	} else {
	    psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
	}
	Tcl_SetHashValue(hPtr, psPtr);
    } else if (psPtr->eventProc != EvalTclBinding) {
	/*
	 * Free existing procedural binding.
	 */

	if (psPtr->freeProc != NULL) {
	    (*psPtr->freeProc)(psPtr->clientData);
	}
	psPtr->clientData = NULL;
	append = 0;
    }

    oldStr = (char *) psPtr->clientData;
    if ((append != 0) && (oldStr != NULL)) {
	size_t length;

	length = strlen(oldStr) + strlen(command) + 2;
	newStr = (char *) ckalloc((unsigned) length);
	sprintf(newStr, "%s\n%s", oldStr, command);
    } else {
	newStr = (char *) ckalloc((unsigned) strlen(command) + 1);
	strcpy(newStr, command);
    }
    if (oldStr != NULL) {
	ckfree(oldStr);
    }
    psPtr->eventProc = EvalTclBinding;
    psPtr->freeProc = FreeTclBinding;
    psPtr->clientData = (ClientData) newStr;
    return eventMask;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkCreateBindingProcedure --
 *
 *	Add a C binding to a binding table, so that future calls to
 *	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
 *	what events to select for in a window, for example.
 *
 * Side effects:
 *	Any existing binding on the same event sequence will be replaced.
 *
 *---------------------------------------------------------------------------
 */

unsigned long
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
				 * associated. */
    const char *eventString,	/* String describing event sequence that
				 * triggers binding. */
    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;
    PatSeq *psPtr;
    unsigned long eventMask;

    psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString,
	    1, 1, &eventMask);
    if (psPtr == NULL) {
	return 0;
    }

    if (psPtr->eventProc == NULL) {









	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.
	 */

	hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object,
		&isNew);
	if (isNew) {
	    psPtr->nextObjPtr = NULL;
	} else {
	    psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
	}
	Tcl_SetHashValue(hPtr, psPtr);

    } else {
	/*
	 * Free existing callback.
	 */

	if (psPtr->freeProc != NULL) {
	    (*psPtr->freeProc)(psPtr->clientData);



	}






    }



    psPtr->eventProc = eventProc;
    psPtr->freeProc = freeProc;
    psPtr->clientData = clientData;
    return eventMask;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteBinding --
1726
1727
1728
1729
1730
1731
1732

1733
1734

1735

1736

1737
1738
1739
1740
1741
1742
1743

1744
1745
1746
1747
1748
1749
1750
1751
1752
1753

1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764
1765
1766







1767











1768
1769
1770
1771
1772
1773
1774
1775
1776

1777

1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805

1806
1807

1808

1809

1810

1811
1812
1813
1814


1815
1816
1817


1818
1819
1820
1821
1822
1823
1824
1825
 *
 *--------------------------------------------------------------
 */

int
Tk_DeleteBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */

    Tk_BindingTable bindPtr,	/* 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. */

{

    PatSeq *psPtr;

    assert(bindPtr);
    assert(object);
    assert(eventString);

    psPtr = FindSequence(interp, &bindPtr->lookupTables, object, eventString, 0, 1, NULL);

    if (!psPtr) {
	Tcl_ResetResult(interp);
    } else {
	Tcl_HashEntry *hPtr;
	PatSeq *prevPtr;

	assert(TEST_PSENTRY(psPtr));

	/*
	 * Unlink the binding from the list for its object.

	 */

	if (!(hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {

	    Tcl_Panic("Tk_DeleteBinding couldn't find object table entry");
	}
	prevPtr = (PatSeq *)Tcl_GetHashValue(hPtr);
	if (prevPtr == psPtr) {
	    Tcl_SetHashValue(hPtr, psPtr->ptr.nextObj);
	} else {
	    for ( ; ; prevPtr = prevPtr->ptr.nextObj) {
		if (!prevPtr) {
		    Tcl_Panic("Tk_DeleteBinding couldn't find on object list");
		}







		if (prevPtr->ptr.nextObj == psPtr) {











		    prevPtr->ptr.nextObj = psPtr->ptr.nextObj;
		    break;
		}
	    }
	}

	RemovePatSeqFromLookup(&bindPtr->lookupTables, psPtr);
	RemovePatSeqFromPromotionLists(bindPtr, psPtr);
	DeletePatSeq(psPtr);

    }


    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetBinding --
 *
 *	Return the script associated with a given event string.
 *
 * Results:
 *	The return value is a pointer to the script 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.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_GetBinding(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */

    Tk_BindingTable bindPtr,	/* 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 PatSeq *psPtr;


    assert(bindPtr);
    assert(object);
    assert(eventString);



    psPtr = FindSequence(interp, &bindPtr->lookupTables, object, eventString, 0, 1, NULL);
    assert(!psPtr || TEST_PSENTRY(psPtr));


    return psPtr ? psPtr->script : NULL;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetAllBindings --
 *







>
|
|
>
|
>

>
|
|
|
<
<

|
>
|

<
<
|
|
<

|
|
>
|

|
>
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|

|
|
|
>
|
>
|








|


|















>
|
|
>
|
>

>
|
>

|
<
|
>
>
|
<
|
>
>
|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136


1137
1138
1139
1140
1141


1142
1143

1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
 *
 *--------------------------------------------------------------
 */

int
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;
    unsigned long eventMask;
    Tcl_HashEntry *hPtr;



    psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString,
	    0, 1, &eventMask);
    if (psPtr == NULL) {
	Tcl_ResetResult(interp);


	return TCL_OK;
    }


    /*
     * 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) {
	Tcl_Panic("Tk_DeleteBinding couldn't find object table entry");
    }
    prevPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
    if (prevPtr == psPtr) {
	Tcl_SetHashValue(hPtr, psPtr->nextObjPtr);
    } else {
	for ( ; ; prevPtr = prevPtr->nextObjPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("Tk_DeleteBinding couldn't find on object list");
	    }
	    if (prevPtr->nextObjPtr == psPtr) {
		prevPtr->nextObjPtr = psPtr->nextObjPtr;
		break;
	    }
	}
    }
    prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
    if (prevPtr == psPtr) {
	if (psPtr->nextSeqPtr == NULL) {
	    Tcl_DeleteHashEntry(psPtr->hPtr);
	} else {
	    Tcl_SetHashValue(psPtr->hPtr, psPtr->nextSeqPtr);
	}
    } else {
	for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("Tk_DeleteBinding couldn't find on hash chain");
	    }
	    if (prevPtr->nextSeqPtr == psPtr) {
		prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
		break;
	    }
	}
    }

    psPtr->flags |= MARKED_DELETED;
    if (psPtr->refCount == 0) {
	if (psPtr->freeProc != NULL) {
	    (*psPtr->freeProc)(psPtr->clientData);
	}
	ckfree((char *) psPtr);
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetBinding --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

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;
    unsigned long eventMask;

    psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString,

	    0, 1, &eventMask);
    if (psPtr == NULL) {
	return NULL;
    }

    if (psPtr->eventProc == EvalTclBinding) {
	return (const char *) psPtr->clientData;
    }
    return "";
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetAllBindings --
 *
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913

1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
 *
 *--------------------------------------------------------------
 */

void
Tk_GetAllBindings(
    Tcl_Interp *interp,		/* Interpreter returning result or error. */

    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    ClientData object)		/* Token for object. */
{
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);

    if ((hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {
	const PatSeq *psPtr;
	Tcl_Obj *resultObj = Tcl_NewObj();

	/*
	 * For each binding, output information about each of the patterns in its sequence.
	 */

	for (psPtr = (const PatSeq *)Tcl_GetHashValue(hPtr); psPtr; psPtr = psPtr->ptr.nextObj) {
	    assert(TEST_PSENTRY(psPtr));
	    Tcl_ListObjAppendElement(NULL, resultObj, GetPatternObj(psPtr));
	}
	Tcl_SetObjResult(interp, resultObj);
    }
}

/*
 *--------------------------------------------------------------
 *
 * RemovePatSeqFromLookup --
 *
 *	Remove given pattern sequence from lookup tables. This
 *	can be required before deleting the pattern sequence.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
RemovePatSeqFromLookup(
    LookupTables *lookupTables,	/* Remove from this lookup tables. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(psPtr);

    SetupPatternKey(&key, psPtr);

    if ((hPtr = Tcl_FindHashEntry(&lookupTables->listTable, (char *) &key))) {
	PSList *psList = (PSList *)Tcl_GetHashValue(hPtr);
	PSEntry *psEntry;

	TK_DLIST_FOREACH(psEntry, psList) {
	    if (psEntry->psPtr == psPtr) {
		psPtr->added = 0;
		RemoveListEntry(&lookupTables->entryPool, psEntry);
		return;
	    }
	}
    }

    assert(!"couldn't find pattern sequence in lookup");
}


/*
 *--------------------------------------------------------------
 *
 * RemovePatSeqFromPromotionLists --
 *
 *	Remove given pattern sequence from promotion lists. This

 *	can be required before deleting the pattern sequence.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
RemovePatSeqFromPromotionLists(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    unsigned i;

    assert(bindPtr);
    assert(psPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;

	TK_DLIST_FOREACH(psEntry, psList) {
	    if (psEntry->psPtr == psPtr) {
		RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
		break;
	    }
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * DeletePatSeq --
 *
 *	Delete given pattern sequence. Possibly it is required
 *	to invoke RemovePatSeqFromLookup(), and RemovePatSeqFromPromotionLists()
 *	before.
 *
 * Results:
 *	Pointer to succeeding pattern sequence.
 *
 * Side effects:
 *	Deallocation of memory.
 *
 *--------------------------------------------------------------
 */

static PatSeq *
DeletePatSeq(
    PatSeq *psPtr)		/* Delete this pattern sequence. */
{
    PatSeq *prevPtr;
    PatSeq *nextPtr;

    assert(psPtr);
    assert(!psPtr->added);
    assert(!psPtr->owned);

    prevPtr = (PatSeq *)Tcl_GetHashValue(psPtr->hPtr);
    nextPtr = psPtr->ptr.nextObj;

    /*
     * 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.
     */

    if (prevPtr == psPtr) {
	if (!psPtr->nextSeqPtr) {
	    Tcl_DeleteHashEntry(psPtr->hPtr);
	} else {
	    Tcl_SetHashValue(psPtr->hPtr, psPtr->nextSeqPtr);
	}
    } else {
	for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
	    if (!prevPtr) {
		Tcl_Panic("DeletePatSeq couldn't find on hash chain");
	    }
	    if (prevPtr->nextSeqPtr == psPtr) {
		prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
		break;
	    }
	}
    }

    FreePatSeq(psPtr);
    return nextPtr;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteAllBindings --
 *







>
|


<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

|
<
<

<
<
|
<
<
|
<
<
<
<
|
|
<
<
|
<
<
|
>
|
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
|
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270







































1271


1272
1273


1274


1275


1276




1277
1278


1279


1280
1281
1282





1283
1284








1285
1286






1287


1288



1289




1290



1291


























































1292
1293
1294
1295
1296
1297
1298
 *
 *--------------------------------------------------------------
 */

void
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;


    Tcl_HashEntry *hPtr;
    Tcl_DString ds;





    hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object);


    if (hPtr == NULL) {




	return;
    }


    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.








	 */







	Tcl_DStringSetLength(&ds, 0);


	GetPatternString(psPtr, &ds);



	Tcl_AppendElement(interp, Tcl_DStringValue(&ds));




    }



    Tcl_DStringFree(&ds);


























































}

/*
 *--------------------------------------------------------------
 *
 * Tk_DeleteAllBindings --
 *
2026
2027
2028
2029
2030
2031
2032

2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043

2044
2045



2046
2047

2048

2049
2050


2051


2052
2053












2054
2055
2056


2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156

2157
2158
2159

2160
2161
2162

2163
2164

2165
2166
2167
2168
2169
2170




2171
2172
2173
2174
2175
2176
2177

2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247

2248
2249


2250


2251
2252









2253

2254
2255






2256
2257

2258


2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289

2290
2291
2292
2293
2294
2295
2296
2297

2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362



2363
2364
2365



2366




2367



2368



2369



2370




2371








2372










2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388

2389
2390
2391
2392
2393



2394
2395



2396

2397
2398
2399
2400
2401
2402
2403
2404
2405
2406



2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424

2425
2426


2427
2428
2429
2430



2431
2432
2433
2434

2435
2436
2437
2438
2439
2440
2441
2442
2443
2444


2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470


2471
2472



2473
2474
2475
2476



2477
2478
2479
2480
2481
2482



2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579

2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596

2597

























2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613





















2614
2615
2616


2617
2618
2619
2620




2621


2622
2623

2624


2625














2626
2627
2628
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641














































2642

2643




2644














2645
2646
2647
2648
2649
2650
2651
2652
2653













2654
2655
2656

2657
2658


2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780

2781

2782
2783


2784
2785
2786


2787

2788


2789


2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801



2802
2803
2804





2805




2806
2807
2808

2809
2810

2811

2812

2813
2814
2815
2816

2817
2818

2819
2820





2821


2822
2823
2824
2825
2826
2827
2828





2829
2830







2831






2832
2833



2834
2835
2836



2837
2838

2839

2840
2841





2842
2843
2844




2845
2846
2847
2848
2849
2850



2851




2852

2853

2854



2855
2856






2857






2858
2859
2860
2861
2862
2863

2864
2865
2866
2867



2868

2869









2870
2871
2872
2873









2874


2875
2876

2877




2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891

2892


2893
2894

2895








2896

2897
2898
2899

2900


2901
2902
2903
2904
2905
2906
2907



2908



2909




2910
2911


2912

















2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
















2932

2933



2934


2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
 *	None.
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(

    Tk_BindingTable bindPtr,	/* Table in which to delete bindings. */
    ClientData object)		/* Token for object. */
{

    PatSeq *psPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);

    if (!(hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {

	return;
    }




    /*

     * Don't forget to clear lookup tables.

     */



    ClearLookupTable(&bindPtr->lookupTables, object);


    ClearPromotionLists(bindPtr, object);













    for (psPtr = (PatSeq *)Tcl_GetHashValue(hPtr); psPtr; psPtr = nextPtr) {
	assert(TEST_PSENTRY(psPtr));
	DEBUG(psPtr->added = 0;)


	nextPtr = DeletePatSeq(psPtr);
    }

    Tcl_DeleteHashEntry(hPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_BindEvent --
 *
 *	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:
 *	None.
 *
 * Side effects:
 *	Depends on the script associated with the matching binding.
 *
 *	All Tcl binding 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.
 *
 *---------------------------------------------------------------------------
 */

/* helper function */
static void
ResetCounters(
    Event *eventInfo,
    unsigned eventType,
    Window window)
{
    Event *curEvent;

    assert(eventInfo);
    curEvent = eventInfo + eventType;

    if (curEvent->xev.xany.window == window) {
	curEvent->xev.xany.window = None;
	eventInfo[eventType].countAny = 0;
	eventInfo[eventType].countDetailed = 0;
    }
}

/* helper function */
static int
IsBetterMatch(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr)	/* this is a better match? */
{
    int diff;

    if (!sndMatchPtr) { return 0; }
    if (!fstMatchPtr) { return 1; }

    diff = CountSpecialized(fstMatchPtr, sndMatchPtr);
    if (diff > 0) { return 1; }
    if (diff < 0) { return 0; }

#if PREFER_MOST_SPECIALIZED_EVENT
    {	/* local scope */
#define M (Tcl_WideUInt)1000000
	static const Tcl_WideUInt weight[5] = { 0, 1, M, M*M, M*M*M };
#undef M
	Tcl_WideUInt fstCount = 0;
	Tcl_WideUInt sndCount = 0;
	unsigned i;

	/*
	 * Count the most high-ordered patterns.
	 *
	 * (This computation assumes that a sequence does not contain more than
	 * 1,000,000 single patterns. It can be precluded that in practice this
	 * assumption will not be violated.)
	 */

	for (i = 0; i < fstMatchPtr->numPats; ++i) {
	    assert(GetCount(fstMatchPtr, i) < SIZE_OF_ARRAY(weight));
	    fstCount += weight[GetCount(fstMatchPtr, i)];
	}
	for (i = 0; i < sndMatchPtr->numPats; ++i) {
	    assert(GetCount(sndMatchPtr, i) < SIZE_OF_ARRAY(weight));
	    sndCount += weight[GetCount(sndMatchPtr, i)];
	}
	if (sndCount > fstCount) { return 1; }
	if (sndCount < fstCount) { return 0; }
    }
#endif

    return sndMatchPtr->number > fstMatchPtr->number;
}

void
Tk_BindEvent(

    Tk_BindingTable bindPtr,	/* 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 *objArr. */
    ClientData *objArr)		/* Array of one or more objects to check for a matching binding. */

{
    Tcl_Interp *interp;

    ScreenInfo *screenPtr;
    TkDisplay *dispPtr;
    TkDisplay *oldDispPtr;
    Event *curEvent;
    TkWindow *winPtr = (TkWindow *)tkwin;
    BindInfo *bindInfoPtr;




    Tcl_InterpState interpState;
    LookupTables *physTables;
    PatSeq *psPtr[2];
    PatSeq *matchPtrBuf[32];
    PatSeq **matchPtrArr = matchPtrBuf;
    PSList *psl[2];
    Tcl_DString scripts;

    const char *p;
    const char *end;
    unsigned scriptCount;
    int oldScreen;
    unsigned flags;
    unsigned arraySize;
    unsigned newArraySize;
    unsigned i, k;

    assert(bindPtr);
    assert(eventPtr);
    assert(tkwin);
    assert(numObjects >= 0);

    /*
     * 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) {
	return;
    }

    flags = flagArray[eventPtr->type];

    /*
     * Ignore event types which are not in flagArray and all zeroes there.
     */

    if (eventPtr->type >= TK_LASTEVENT || !flags) {
	return;
    }

    if (flags & HAS_XKEY_HEAD_AND_STATE) {
	bindPtr->curModMask = eventPtr->xkey.state;
    } else if (flags & CROSSING) {
	bindPtr->curModMask = eventPtr->xcrossing.state;
    }

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    bindInfoPtr = winPtr->mainPtr->bindInfo;
    curEvent = bindPtr->eventInfo + eventPtr->type;

    /*
     * 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 be 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.
     *
     * Furthermore we have to compute current time, needed for "event generate".
     */

    switch (eventPtr->type) {
    case EnterNotify:
    case LeaveNotify:
	if (eventPtr->xcrossing.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xcrossing.time;
	}
	if (eventPtr->xcrossing.detail == NotifyInferior) {
	    return;
	}
	break;
    case FocusIn:

    case FocusOut:
	if (eventPtr->xfocus.detail == NotifyInferior) {
	    return;
	}

	break;
    case KeyPress:


    case KeyRelease: {


	int reset = 1;










	if (eventPtr->xkey.time) {

	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xkey.time;






	}
	/* modifier keys should not influence button events */

	for (i = 0; i < (unsigned) dispPtr->numModKeyCodes; ++i) {


	    if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {
		reset = 0;
	    }
	}
	if (reset) {
	    /* reset repetition count for button events */
	    bindPtr->eventInfo[ButtonPress].countAny = 0;
	    bindPtr->eventInfo[ButtonPress].countDetailed = 0;
	    bindPtr->eventInfo[ButtonRelease].countAny = 0;
	    bindPtr->eventInfo[ButtonRelease].countDetailed = 0;
	}
	break;
    }
    case ButtonPress:
    case ButtonRelease:
	/* reset repetition count for key events */
	bindPtr->eventInfo[KeyPress].countAny = 0;
	bindPtr->eventInfo[KeyPress].countDetailed = 0;
	bindPtr->eventInfo[KeyRelease].countAny = 0;
	bindPtr->eventInfo[KeyRelease].countDetailed = 0;
	/* fallthru */
    case MotionNotify:
	if (eventPtr->xmotion.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xmotion.time;
	}
	break;
    case PropertyNotify:
	if (eventPtr->xproperty.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xproperty.time;

	}
	break;
    case DestroyNotify:
	ResetCounters(bindPtr->eventInfo, KeyPress, eventPtr->xany.window);
	ResetCounters(bindPtr->eventInfo, KeyRelease, eventPtr->xany.window);
	ResetCounters(bindPtr->eventInfo, ButtonPress, eventPtr->xany.window);
	ResetCounters(bindPtr->eventInfo, ButtonRelease, eventPtr->xany.window);
	break;

    }

    /*
     * Now check whether this is a repeating event (multi-click, repeated key press, and so on).
     */

    /* NOTE: if curEvent is not yet set, then the following cannot match: */
    if (curEvent->xev.xany.window == eventPtr->xany.window) {
	switch (eventPtr->type) {
	case KeyPress:
	case KeyRelease:
	    if (MatchEventRepeat(&curEvent->xev.xkey, &eventPtr->xkey)) {
		if (curEvent->xev.xkey.keycode == eventPtr->xkey.keycode) {
		    ++curEvent->countDetailed;
		} else {
		    curEvent->countDetailed = 1;
		}
		++curEvent->countAny;
	    } else {
		curEvent->countAny = curEvent->countDetailed = 1;
	    }
	    break;
	case ButtonPress:
	case ButtonRelease:
	    if (MatchEventNearby(&curEvent->xev, eventPtr)) {
		if (curEvent->xev.xbutton.button == eventPtr->xbutton.button) {
		    ++curEvent->countDetailed;
		} else {
		    curEvent->countDetailed = 1;
		}
		++curEvent->countAny;
	    } else {
		curEvent->countAny = curEvent->countDetailed = 1;
	    }
	    break;
	case EnterNotify:
	case LeaveNotify:
	    if (TestNearbyTime(eventPtr->xcrossing.time, curEvent->xev.xcrossing.time)) {
		++curEvent->countAny;
	    } else {
		curEvent->countAny = 1;
	    }
	    break;
	case PropertyNotify:
	    if (TestNearbyTime(eventPtr->xproperty.time, curEvent->xev.xproperty.time)) {
		++curEvent->countAny;
	    } else {
		curEvent->countAny = 1;
	    }
	    break;
	default:
	    ++curEvent->countAny;
	    break;
	}
    } else {
	curEvent->countAny = curEvent->countDetailed = 1;
    }

    /*
     * Now update the details.
     */

    curEvent->xev = *eventPtr;
    if (flags & KEY) {
	curEvent->detail.info = TkpGetKeySym(dispPtr, eventPtr);



    } else if (flags & BUTTON) {
	curEvent->detail.info = eventPtr->xbutton.button;
    } else if (flags & MOTION) {



	curEvent->detail.info = ButtonNumberFromState(eventPtr->xmotion.state);




    } else if (flags & VIRTUAL) {



	curEvent->detail.name = ((XVirtualEvent *) eventPtr)->name;



    }








    bindPtr->curEvent = curEvent;








    physTables = &bindPtr->lookupTables;










    scriptCount = 0;
    arraySize = 0;
    Tcl_DStringInit(&scripts);

    if ((size_t) numObjects > SIZE_OF_ARRAY(matchPtrBuf)) {
	/* it's unrealistic that the buffer size is too small, but who knows? */
	matchPtrArr = (PatSeq **)ckalloc(numObjects*sizeof(matchPtrArr[0]));
    }
    memset(matchPtrArr, 0, numObjects*sizeof(matchPtrArr[0]));

    if (!PromArr_IsEmpty(bindPtr->promArr)) {
	for (k = 0; k < (unsigned) numObjects; ++k) {
	    psl[1] = PromArr_Last(bindPtr->promArr);
	    psl[0] = psl[1] - 1;

	    /*

	     * Loop over all promoted bindings, finding the longest matching one.
	     *
	     * Note that we must process all lists, because all matching patterns
	     * have to be promoted. Normally at most one list will be processed, and
	     * usually this list only contains one or two patterns.



	     */




	    for (i = PromArr_Size(bindPtr->promArr); i > 0; --i, --psl[0], --psl[1]) {

		psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psl[1], i, curEvent, objArr[k], NULL);

		if (IsBetterMatch(matchPtrArr[k], psPtr[0])) {
		    /* we will process it later, because we still may find a pattern with better match */
		    matchPtrArr[k] = psPtr[0];
		}
		if (!PSList_IsEmpty(psl[1])) {
		    /* we have promoted sequences, adjust array size */
		    arraySize = Max(i + 1, arraySize);
		}



	    }
	}
    }

    /*
     * 1. Look for bindings for the specific detail (button and key events).
     * 2. Look for bindings without detail.
     */

    for (k = 0; k < (unsigned) numObjects; ++k) {
	PSList *psSuccList = PromArr_First(bindPtr->promArr);
	PatSeq *bestPtr;

	psl[0] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 1);
	psl[1] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 0);

	assert(psl[0] == NULL || psl[0] != psl[1]);


	psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psSuccList, 0, curEvent, objArr[k], NULL);
	psPtr[1] = MatchPatterns(dispPtr, bindPtr, psl[1], psSuccList, 0, curEvent, objArr[k], NULL);



	if (!PSList_IsEmpty(psSuccList)) {
	    /* we have promoted sequences, adjust array size */
	    arraySize = Max(1u, arraySize);



	}

	bestPtr = psPtr[0] ? psPtr[0] : psPtr[1];


	if (matchPtrArr[k]) {
	    if (IsBetterMatch(matchPtrArr[k], bestPtr)) {
		matchPtrArr[k] = bestPtr;
	    } else {
		/*
		 * We've already found a higher level match, nevertheless it was required to
		 * process the level zero patterns because of possible promotions.
		 */
	    }
	    /*


	     * Now we have to catch up the processing of the script.
	     */
	} else {
	    /*
	     * We have to look whether we can find a better match in virtual table, provided that we
	     * don't have a higher level match.
	     */

	    matchPtrArr[k] = bestPtr;

	    if (eventPtr->type != VirtualEvent) {
		LookupTables *virtTables = &bindInfoPtr->virtualEventTable.lookupTables;
		PatSeq *matchPtr = matchPtrArr[k];
		PatSeq *mPtr;

		/*
		 * Note that virtual events cannot promote.
		 */

		psl[0] = GetLookupForEvent(virtTables, curEvent, NULL, 1);
		psl[1] = GetLookupForEvent(virtTables, curEvent, NULL, 0);

		assert(psl[0] == NULL || psl[0] != psl[1]);

		mPtr = MatchPatterns(dispPtr, bindPtr, psl[0], NULL, 0, curEvent, objArr[k], &matchPtr);
		if (mPtr) {


		    matchPtrArr[k] = matchPtr;
		    matchPtr = mPtr;



		}
		if (MatchPatterns(dispPtr, bindPtr, psl[1], NULL, 0, curEvent, objArr[k], &matchPtr)) {
		    matchPtrArr[k] = matchPtr;
		}



	    }
	}

	if (matchPtrArr[k]) {
	    ExpandPercents(winPtr, matchPtrArr[k]->script, curEvent, scriptCount++, &scripts);
	    /* nul is added to the scripts string to separate the various scripts */



	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }

    PromArr_SetSize(bindPtr->promArr, arraySize);

    /*
     * Remove expired pattern sequences.
     */

    for (i = 0, newArraySize = 0; i < arraySize; ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;
	PSEntry *psNext;

	for (psEntry = PSList_First(psList); psEntry; psEntry = psNext) {
	    const TkPattern *patPtr;

	    assert(i + 1 < psEntry->psPtr->numPats);

	    psNext = PSList_Next(psEntry);
	    patPtr = &psEntry->psPtr->pats[i + 1];

	    /*
	     * We have to remove the following entries from promotion list (but
	     * only if we don't want to keep it):
	     * ------------------------------------------------------------------
	     * 1) It is marked as expired (see MatchPatterns()).
	     * 2) If we have a Key event, and current entry is matching a Button.
	     * 3) If we have a Button event, and current entry is matching a Key.
	     * 4) If we have a detailed event, current entry it is also detailed,
	     *    we have matching event types, but the details are different.
	     * 5) Current entry has been matched with a different window.
	     */

	    if (psEntry->keepIt) {
		assert(!psEntry->expired);
		psEntry->keepIt = 0;
	    } else if (psEntry->expired
		    || psEntry->window != curEvent->xev.xany.window
		    || (patPtr->info
			&& curEvent->detail.info
			&& patPtr->eventType == (unsigned) curEvent->xev.type
			&& patPtr->info != curEvent->detail.info)) {
		RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
	    } else {
		switch (patPtr->eventType) {
		case ButtonPress:
		case ButtonRelease:
		    if (IsKeyEventType(curEvent->xev.type)) {
			RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
		    }
		    break;
		case KeyPress:
		case KeyRelease:
		    if (IsButtonEventType(curEvent->xev.type)) {
			RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
		    }
		    break;
		}
	    }
	}

	if (!PSList_IsEmpty(psList)) {
	    /* we still have promoted sequences, adjust array size */
	    newArraySize = Max(i + 1, newArraySize);
	}
    }

    PromArr_SetSize(bindPtr->promArr, newArraySize);

    if (matchPtrArr != matchPtrBuf) {
	ckfree(matchPtrArr);
    }

    if (Tcl_DStringLength(&scripts) == 0) {
	return; /* nothing to do */
    }

    /*
     * 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.
     */

    interp = bindPtr->interp;


    /*
     * Save information about the current screen, then invoke a script if the
     * screen has changed.
     */

    interpState = Tcl_SaveInterpState(interp, TCL_OK);
    screenPtr = &bindInfoPtr->screenInfo;
    oldDispPtr = screenPtr->curDispPtr;
    oldScreen = screenPtr->curScreenIndex;

    if (dispPtr != screenPtr->curDispPtr || Tk_ScreenNumber(tkwin) != screenPtr->curScreenIndex) {
	screenPtr->curDispPtr = dispPtr;
	screenPtr->curScreenIndex = Tk_ScreenNumber(tkwin);
	ChangeScreen(interp, dispPtr->name, screenPtr->curScreenIndex);
    }


    /*

























     * Be careful 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(bindInfoPtr);

    for (p = Tcl_DStringValue(&scripts), end = p + Tcl_DStringLength(&scripts); p < end; ) {
	unsigned len = strlen(p);
	int code;

	if (!bindInfoPtr->deleted) {
	    ++screenPtr->bindingDepth;
	}
	Tcl_AllowExceptions(interp);






















	code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL);
	p += len + 1;



	if (!bindInfoPtr->deleted) {
	    --screenPtr->bindingDepth;
	}
	if (code != TCL_OK && code != TCL_CONTINUE) {




	    if (code != TCL_BREAK) {


		Tcl_AddErrorInfo(interp, "\n    (command bound to event)");
		Tcl_BackgroundException(interp, code);

	    }


	    break;














	}
    }

    if (!bindInfoPtr->deleted
	    && screenPtr->bindingDepth > 0
	    && (oldDispPtr != screenPtr->curDispPtr || oldScreen != screenPtr->curScreenIndex)) {
	/*
	 * Some other binding script is currently executing, but its screen is
	 * no longer current. Change the current display back again.
	 */

	screenPtr->curDispPtr = oldDispPtr;
	screenPtr->curScreenIndex = oldScreen;
	ChangeScreen(interp, oldDispPtr->name, oldScreen);
    }
    Tcl_RestoreInterpState(interp, interpState);
    Tcl_DStringFree(&scripts);














































    Tcl_Release(bindInfoPtr);

}



















/*
 *----------------------------------------------------------------------
 *
 * MatchPatterns --
 *
 *	Given a list of pattern sequences and the recent event, return
 *	the pattern sequence that best matches this event, if there is
 *	one.
 *













 * Results:
 *
 *	The return value is NULL if no match is found. Otherwise the

 *	return value is the most specific pattern sequence among all
 *	those that match the event table.


 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

/* helper function */
static int
VirtPatIsBound(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr,		/* Test this pattern. */
    ClientData object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event.
    				 * Output: the physical event associated with matching virtual event. */
{
    PatternTableKey key;
    const struct VirtOwners *owners;
    unsigned i;

    assert(bindPtr);
    assert(psPtr);
    assert(!psPtr->object);
    assert(physPtrPtr);

    if (*physPtrPtr) {
	const TkPattern *physPatPtr = (*physPtrPtr)->pats;
	const TkPattern *virtPatPtr = psPtr->pats;

	if (physPatPtr->info || !virtPatPtr->info) {
	    if (IsSubsetOf(virtPatPtr->modMask, physPatPtr->modMask)) {
		return 0; /* we cannot surpass this match */
	    }
	}
    }

    /* otherwise on some systems the key contains uninitialized bytes */
    memset(&key, 0, sizeof(key));

    key.object = object;
    key.type = VirtualEvent;
    owners = psPtr->ptr.owners;

    for (i = 0; i < VirtOwners_Size(owners); ++i) {
	Tcl_HashEntry *hPtr = VirtOwners_Get(owners, i);

	key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr, hPtr);

	if ((hPtr = Tcl_FindHashEntry(&bindPtr->lookupTables.patternTable, (char *) &key))) {
	    /* The physical event matches this virtual event's definition. */
	    *physPtrPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
	    return 1;
	}
    }

    return 0;
}

/* helper function */
static int
Compare(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr) /* most recent match */
{
    int diff;

    if (!fstMatchPtr) { return +1; }
    assert(sndMatchPtr);
    diff = CountSpecialized(fstMatchPtr, sndMatchPtr);
    return diff ? diff : (int) sndMatchPtr->count - (int) fstMatchPtr->count;
}

/* helper function */
static int
CompareModMasks(
    const PSModMaskArr *fstModMaskArr,
    const PSModMaskArr *sndModMaskArr,
    unsigned fstModMask,
    unsigned sndModMask)
{
    int fstCount = 0;
    int sndCount = 0;
    int i;

    if (PSModMaskArr_IsEmpty(fstModMaskArr)) {
	if (!PSModMaskArr_IsEmpty(sndModMaskArr)) {
	    for (i = PSModMaskArr_Size(sndModMaskArr) - 1; i >= 0; --i) {
		if (*PSModMaskArr_Get(sndModMaskArr, i)) {
		    ++sndCount;
		}
	    }
	}
    } else if (PSModMaskArr_IsEmpty(sndModMaskArr)) {
	for (i = PSModMaskArr_Size(fstModMaskArr) - 1; i >= 0; --i) {
	    if (*PSModMaskArr_Get(fstModMaskArr, i)) {
		++fstCount;
	    }
	}
    } else {
	assert(PSModMaskArr_Size(fstModMaskArr) == PSModMaskArr_Size(sndModMaskArr));

	for (i = PSModMaskArr_Size(fstModMaskArr) - 1; i >= 0; --i) {
	    unsigned fstiModMask = *PSModMaskArr_Get(fstModMaskArr, i);
	    unsigned sndiModMask = *PSModMaskArr_Get(sndModMaskArr, i);

	    if (IsSubsetOf(fstiModMask, sndiModMask)) { ++sndCount; }
	    if (IsSubsetOf(sndiModMask, fstiModMask)) { ++fstCount; }
	}
    }

    /* Finally compare modifier masks of last pattern. */

    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }

    return fstCount - sndCount;
}

static PatSeq *
MatchPatterns(
    TkDisplay *dispPtr,		/* Display from which the event came. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */

    PSList *psList,		/* List of potentially matching patterns, can be NULL. */

    PSList *psSuccList,		/* Add all matching higher-level pattern sequences to this list.
    				 * Can be NULL. */


    unsigned patIndex,		/* Match only this tag in sequence. */
    const Event *curEvent,	/* Match this event. */
    ClientData object,		/* Check for this binding tag. */


    PatSeq **physPtrPtr)	/* Input: the best physical event; NULL if we test physical events.

    				 * Output: the associated physical event for the best matching virtual


				 * event; NULL when we match physical events. */


{
    Window window;
    PSEntry *psEntry;
    PatSeq *bestPtr;
    PatSeq *bestPhysPtr;
    unsigned bestModMask;
    const PSModMaskArr *bestModMaskArr = NULL;
    int i, isModKeyOnly = 0;

    assert(dispPtr);
    assert(bindPtr);
    assert(curEvent);




    if (!psList) {
	return NULL;





    }





    bestModMask = 0;
    bestPtr = NULL;

    bestPhysPtr = NULL;
    window = curEvent->xev.xany.window;



    /*

     * Modifier key events interlaced between patterns parts of a
     * sequence shall not prevent a sequence from ultimately
     * matching. Example: when trying to trigger <a><Control-c>
     * from the keyboard, the sequence of events actually seen is

     * <a> then <Control_L> (possibly repeating if the key is hold
     * down), and finally <Control-c>. At the time <Control_L> is

     * seen, we shall keep the <a><Control-c> pattern sequence in
     * the promotion list, otherwise it is impossible to trigger





     * it from the keyboard. See bug [16ef161925].


     */
    if (IsKeyEventType(curEvent->xev.type)) {
        for (i = 0; i < dispPtr->numModKeyCodes; ++i) {
            if (dispPtr->modKeyCodes[i] == curEvent->xev.xkey.keycode) {
                isModKeyOnly = 1;
                break;
            }





        }
    }














    for (psEntry = PSList_First(psList); psEntry; psEntry = PSList_Next(psEntry)) {
	if (patIndex == 0 || psEntry->window == window) {



	    PatSeq* psPtr = psEntry->psPtr;

	    assert(TEST_PSENTRY(psPtr));



	    assert((psPtr->object == NULL) == (physPtrPtr != NULL));
	    assert(psPtr->object || patIndex == 0);

	    assert(psPtr->numPats > patIndex);


	    if (psPtr->object





		    ? psPtr->object == object
		    : VirtPatIsBound(bindPtr, psPtr, object, physPtrPtr)) {
		TkPattern *patPtr = psPtr->pats + patIndex;





                /* ignore modifier key events, and KeyRelease events if the current event
                 * is of a different type (e.g. a Button event)
                 */
                psEntry->keepIt = isModKeyOnly || \
                        ((patPtr->eventType != (unsigned) curEvent->xev.type) && curEvent->xev.type == KeyRelease);








		if (patPtr->eventType == (unsigned) curEvent->xev.type

			&& (curEvent->xev.type != CreateNotify

				|| curEvent->xev.xcreatewindow.parent == window)



			&& (!patPtr->name || patPtr->name == curEvent->detail.name)
			&& (!patPtr->info || patPtr->info == curEvent->detail.info)) {






		    /*






		     * Resolve the modifier mask for Alt and Mod keys. Unfortunately this
		     * cannot be done in ParseEventDescription, otherwise this function would
		     * be the better place.
		     */
		    unsigned modMask = ResolveModifiers(dispPtr, patPtr->modMask);
		    unsigned curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);


		    psEntry->expired = 1; /* remove it from promotion list */
                    psEntry->keepIt = 0; /* don't keep matching patterns */




		    if (IsSubsetOf(modMask, curModMask)) {

			unsigned count = patPtr->info ? curEvent->countDetailed : curEvent->countAny;










			if (patIndex < PSModMaskArr_Size(psEntry->lastModMaskArr)) {
			    PSModMaskArr_Set(psEntry->lastModMaskArr, patIndex, &modMask);
			}












			/*
			 * This pattern is finally matching.

			 */





			if (psPtr->numPats == patIndex + 1) {
			    if (patPtr->count <= count) {
				/*
				 * This is also a final pattern.
				 * We always prefer the pattern with better match.
				 * If completely equal than prefer most recently defined pattern.
				 */

				int cmp = Compare(bestPtr, psPtr);

				if (cmp == 0) {
				    cmp = CompareModMasks(psEntry->lastModMaskArr, bestModMaskArr,
					    modMask, bestModMask);

				}



				if (cmp > 0 || (cmp == 0 && bestPtr->number < psPtr->number)) {

				    bestPtr = psPtr;








				    bestModMask = modMask;

				    bestModMaskArr = psEntry->lastModMaskArr;
				    if (physPtrPtr) {
					bestPhysPtr = *physPtrPtr;

				    }


				}
			    } else {
				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* don't remove it from promotion list */
			    }
			} else if (psSuccList) {
			    /*



			     * Not a final pattern, but matching, so promote it to next level.



			     * But do not promote if count of current pattern is not yet reached.




			     */
			    if (patPtr->count == psEntry->count) {


				PSEntry *psNewEntry;


















				assert(!patPtr->name);
				psNewEntry = MakeListEntry(
				    &bindPtr->lookupTables.entryPool, psPtr, psPtr->modMaskUsed);
				if (!PSModMaskArr_IsEmpty(psNewEntry->lastModMaskArr)) {
				    PSModMaskArr_Set(psNewEntry->lastModMaskArr, patIndex, &modMask);
				}
				assert(psNewEntry->keepIt);
				assert(psNewEntry->count == 1u);
				PSList_Append(psSuccList, psNewEntry);
				psNewEntry->window = window; /* bind to current window */
			    } else {
				assert(psEntry->count < patPtr->count);
				DEBUG(psEntry->expired = 0;)
				psEntry->count += 1;
				psEntry->keepIt = 1; /* don't remove it from promotion list */
			    }
			}
		    }
















		}

	    }



	}


    }

    if (bestPhysPtr) {
	assert(physPtrPtr);
	*physPtrPtr = bestPhysPtr;
    }
    return bestPtr;
}

/*
 *--------------------------------------------------------------
 *
 * ExpandPercents --







>
|


>
|



<
<
<
|
>


>
>
>

|
>
|
>
|

>
>
|
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
|
|
|


















|

|



<
<
<
|
<
<
<
<
<
|
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


>
|

|
>
|
|
|
>

|
>

|

|
<
<
>
>
>
>
|
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
|
|
|
|
<






|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|


<
<


|
<
<
<
<
<
<



<
<
>
|



>
|
|
>
>
|
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
|
|
>
>
>
>
>
>
|
<
>
|
>
>

<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
|
|
>

<
<
|
<
<
<
<
>
|
|
<
<
<
|
<
<
|
|
<
<
|
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
|
<
<
|
<
|
<
<
<
<
|
<
<
|
<
<
<
<
|
<
|
<
|
<
|
<
|
<

|
>
>
>

|
|
>
>
>
|
>
>
>
>
|
>
>
>
|
>
>
>
|
>
>
>

>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>

|


|
<
<
<
|
|
<
<
<
<

|
>
|
<
<
<
<
>
>
>
|

>
>
>
|
>
|
|
<
<
|
|
<
<
<
|
>
>
>
|
|
<
<
|
|
|
|

<
<
<
|
<
<
|
<
|
>
|
<
>
>
|
<
<
|
>
>
>
|

<
|
>
|
|
<
<
<
|
<
<

<
>
>
|
<
|
<
<
|
<
|
<
|
<
<
<
<

<
<
<
|
<
<
|
<
|
|
<
>
>
|
|
>
>
>
|
<
|

>
>
>

|
|
<
<
|
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|




















>






|



|
|





>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




|
|
<
<



|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>

|

|
>
>
>
>
|
>
>

|
>

>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|
|




>




|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|


>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
>
|
|
>
>






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
>
|
>
|
|
>
>
|
|
|
>
>
|
>
|
>
>
|
>
>

<
<
|
|
|
<
<

<
<
<
>
>
>

<
|
>
>
>
>
>
|
>
>
>
>

|
|
>
|
<
>
|
>
|
>
|
|
<
<
>
|
<
>
|
<
>
>
>
>
>
|
>
>
|
<
<
<
<
<
|
>
>
>
>
>
|
<
>
>
>
>
>
>
>

>
>
>
>
>
>
|
<
>
>
>
|
|
<
>
>
>
|
|
>
|
>
|
|
>
>
>
>
>
|
<
|
>
>
>
>
|
|
<
|
|
|
>
>
>
|
>
>
>
>
|
>
|
>
|
>
>
>
|
|
>
>
>
>
>
>
|
>
>
>
>
>
>
|
<
<
<
|
<
>
|
<
<
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
|
<
<
|
>
>
>
>
>
>
>
>
>
|
>
>
|
|
>
|
>
>
>
>

<
<
|
|
|
|
|

|

|
|
|
>
|
>
>

<
>
|
>
>
>
>
>
>
>
>
|
>
|
|
|
>
|
>
>
|
<
<
<
|
|
|
>
>
>
|
>
>
>
|
>
>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
|
>
>


<
<
|
<







1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321



1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386



1387





1388


1389


1390






1391







1392


1393



1394








1395






1396
1397
















1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415


1416
1417
1418
1419
1420





1421
1422
1423







1424
1425
1426
1427

1428
1429
1430
1431
1432
1433
1434
1435
1436




















1437
1438
1439
1440
1441
1442
1443
1444


1445
1446
1447






1448
1449
1450


1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485

1486
1487
1488
1489
1490










1491
1492












1493


1494
1495
1496
1497
1498


1499




1500
1501
1502



1503


1504
1505


1506
1507


1508
1509












1510
1511

1512

1513


1514

1515




1516


1517




1518

1519

1520

1521

1522

1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580



1581
1582




1583
1584
1585
1586




1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598


1599
1600



1601
1602
1603
1604
1605
1606


1607
1608
1609
1610
1611



1612


1613

1614
1615
1616

1617
1618
1619


1620
1621
1622
1623
1624
1625

1626
1627
1628
1629



1630


1631

1632
1633
1634

1635


1636

1637

1638




1639



1640


1641

1642
1643

1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1659


1660
1661
1662
1663
1664
1665
1666








































































1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740


1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
















































































































1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951


1952
1953
1954


1955



1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975

1976
1977
1978
1979
1980
1981
1982


1983
1984

1985
1986

1987
1988
1989
1990
1991
1992
1993
1994
1995





1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017

2018
2019
2020
2021
2022

2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038

2039
2040
2041
2042
2043
2044
2045

2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080



2081

2082
2083


2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100


2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122


2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138

2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158



2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202









2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232


2233

2234
2235
2236
2237
2238
2239
2240
 *	None.
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(
    Tk_BindingTable bindingTable,
				/* Table in which to delete bindings. */
    ClientData object)		/* Token for object. */
{
    BindingTable *bindPtr = (BindingTable *) bindingTable;
    PatSeq *psPtr, *prevPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;




    hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object);
    if (hPtr == NULL) {
	return;
    }
    for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
	    psPtr = nextPtr) {
	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.
	 */

	prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
	if (prevPtr == psPtr) {
	    if (psPtr->nextSeqPtr == NULL) {
		Tcl_DeleteHashEntry(psPtr->hPtr);
	    } else {
		Tcl_SetHashValue(psPtr->hPtr, psPtr->nextSeqPtr);
	    }
	} else {
	    for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
		if (prevPtr == NULL) {
		    Tcl_Panic("Tk_DeleteAllBindings couldn't find on hash chain");
		}
		if (prevPtr->nextSeqPtr == psPtr) {
		    prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
		    break;
		}
	    }
	}
	psPtr->flags |= MARKED_DELETED;

	if (psPtr->refCount == 0) {
	    if (psPtr->freeProc != NULL) {
		(*psPtr->freeProc)(psPtr->clientData);
	    }
	    ckfree((char *) psPtr);
	}
    }
    Tcl_DeleteHashEntry(hPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_BindEvent --
 *
 *	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:
 *	None.
 *
 * 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 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(
    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;
    ScreenInfo *screenPtr;
    BindInfo *bindInfoPtr;
    TkDisplay *oldDispPtr;
    XEvent *ringPtr;


    PatSeq *vMatchDetailList, *vMatchNoDetailList;
    int flags, oldScreen, i, deferModal;
    unsigned int matchCount, matchSpace;
    unsigned int scriptCount;
    Tcl_Interp *interp;





    Tcl_DString scripts, savedResult;
    Detail detail;
    char *p, *end;







    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.
     */

    if (winPtr->pathName == NULL) {
	return;
    }





















    /*
     * 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->xcrossing.detail == NotifyInferior) {
	    return;
	}


    }
    if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
	if (eventPtr->xfocus.detail == NotifyInferior) {
	    return;
	}
    }

    bindPtr = (BindingTable *) bindingTable;
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;

    /*
     * 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.
     * 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).
     */

    if ((eventPtr->type == MotionNotify)
	    && (bindPtr->eventRing[bindPtr->curEvent].type == MotionNotify)) {
	/*
	 * Don't advance the ring pointer.
	 */
    } else if (eventPtr->type == KeyPress) {
	int i;


	for (i = 0; ; i++) {
	    if (i >= dispPtr->numModKeyCodes) {
		goto advanceRingPointer;
	    }
	    if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {










		break;
	    }












	}


	ringPtr = &bindPtr->eventRing[bindPtr->curEvent];
	if ((ringPtr->type != KeyRelease)
		|| (ringPtr->xkey.keycode != eventPtr->xkey.keycode)) {
	    goto advanceRingPointer;
	}


	if (bindPtr->curEvent <= 0) {




	    i = EVENT_BUFFER_SIZE - 1;
	} else {
	    i = bindPtr->curEvent - 1;



	}


	ringPtr = &bindPtr->eventRing[i];
	if ((ringPtr->type != KeyPress)


		|| (ringPtr->xkey.keycode != eventPtr->xkey.keycode)) {
	    goto advanceRingPointer;


	}
	bindPtr->eventRing[bindPtr->curEvent].type = -1;












	bindPtr->curEvent = i;
    } else {



    advanceRingPointer:


	bindPtr->curEvent++;

	if (bindPtr->curEvent >= EVENT_BUFFER_SIZE) {




	    bindPtr->curEvent = 0;


	}




    }

    ringPtr = &bindPtr->eventRing[bindPtr->curEvent];

    memcpy((void *) ringPtr, (void *) eventPtr, sizeof(XEvent));

    detail.clientData = 0;

    flags = flagArray[ringPtr->type];

    if (flags & KEY) {
	detail.keySym = TkpGetKeySym(dispPtr, ringPtr);
	if (detail.keySym == NoSymbol) {
	    detail.keySym = 0;
	}
    } else if (flags & BUTTON) {
	detail.button = ringPtr->xbutton.button;
    } else if (flags & VIRTUAL) {
	detail.name = ((XVirtualEvent *) ringPtr)->name;
    }
    bindPtr->detailRing[bindPtr->curEvent] = detail;

    /*
     * Find out if there are any virtual events that correspond to this
     * physical event (or sequence of physical events).
     */

    vMatchDetailList = NULL;
    vMatchNoDetailList = NULL;
    memset(&key, 0, sizeof(key));

    if (ringPtr->type != VirtualEvent) {
	Tcl_HashTable *veptPtr = &bindInfoPtr->virtualEventTable.patternTable;
	Tcl_HashEntry *hPtr;

	key.object = NULL;
	key.type = ringPtr->type;
	key.detail = detail;

	hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
	if (hPtr != NULL) {
	    vMatchDetailList = (PatSeq *) Tcl_GetHashValue(hPtr);
	}

	if (key.detail.clientData != 0) {
	    key.detail.clientData = 0;
	    hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
	    if (hPtr != NULL) {
		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.
     */

    pendingPtr = &staticPending;
    matchCount = 0;
    scriptCount = 0;
    matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *);
    Tcl_DStringInit(&scripts);

    for ( ; numObjects > 0; numObjects--, objectPtr++) {



	PatSeq *matchPtr = NULL, *sourcePtr = NULL;
	Tcl_HashEntry *hPtr;





	/*
	 * 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.
	 */

	key.object = *objectPtr;
	key.type = ringPtr->type;
	key.detail = detail;
	hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key);
	if (hPtr != NULL) {
	    matchPtr = MatchPatterns(dispPtr, bindPtr,
		    (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL,


		    &sourcePtr);
	}




	if (vMatchDetailList != NULL) {
	    matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchDetailList,
		    matchPtr, objectPtr, &sourcePtr);
	}



	/*
	 * If no match was found, look for a binding for all keys or buttons
	 * (detail of 0). Again, first match on a virtual event.
	 */




	if ((detail.clientData != 0) && (matchPtr == NULL)) {


	    key.detail.clientData = 0;

	    hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key);
	    if (hPtr != NULL) {
		matchPtr = MatchPatterns(dispPtr, bindPtr,

			(PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL,
			&sourcePtr);
	    }



	    if (vMatchNoDetailList != NULL) {
		matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList,
			matchPtr, objectPtr, &sourcePtr);
	    }


	}

	if (matchPtr != NULL) {
	    if (sourcePtr->eventProc == NULL) {



		Tcl_Panic("Tk_BindEvent: missing command");


	    }

	    if (sourcePtr->eventProc == EvalTclBinding) {
		ExpandPercents(winPtr, (char *) sourcePtr->clientData,
			eventPtr, detail.keySym, scriptCount++, &scripts);

	    } else {


		if (matchCount >= matchSpace) {

		    PendingBinding *newPtr;

		    unsigned int oldSize, newSize;








		    oldSize = sizeof(staticPending)


			    - sizeof(staticPending.matchArray)

			    + matchSpace * sizeof(PatSeq*);
		    matchSpace *= 2;

		    newSize = sizeof(staticPending)
			    - sizeof(staticPending.matchArray)
			    + matchSpace * sizeof(PatSeq*);
		    newPtr = (PendingBinding *) ckalloc(newSize);
		    memcpy((void *) newPtr, (void *) pendingPtr, oldSize);
		    if (pendingPtr != &staticPending) {
			ckfree((char *) pendingPtr);
		    }

		    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.
	     */

	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }








































































    if (Tcl_DStringLength(&scripts) == 0) {
	return;
    }

    /*
     * 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.
     */

    interp = bindPtr->interp;
    Tcl_DStringInit(&savedResult);

    /*
     * Save information about the current screen, then invoke a script if the
     * screen has changed.
     */

    Tcl_DStringGetResult(interp, &savedResult);
    screenPtr = &bindInfoPtr->screenInfo;
    oldDispPtr = screenPtr->curDispPtr;
    oldScreen = screenPtr->curScreenIndex;
    if ((dispPtr != screenPtr->curDispPtr)
	    || (Tk_ScreenNumber(tkwin) != screenPtr->curScreenIndex)) {
	screenPtr->curDispPtr = dispPtr;
	screenPtr->curScreenIndex = Tk_ScreenNumber(tkwin);
	ChangeScreen(interp, dispPtr->name, screenPtr->curScreenIndex);
    }

    if (matchCount > 0) {
	/*
	 * Remember the list of pending C binding callbacks, so we can mark
	 * them as deleted and not call them if the act of evaluating a C or
	 * Tcl binding deletes a C binding callback or even the whole window.
	 */

	pendingPtr->nextPtr = bindInfoPtr->pendingList;
	pendingPtr->tkwin = tkwin;
	pendingPtr->deleted = 0;
	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.
     */

    flags = winPtr->flags;
    winPtr->flags &= ~TK_DEFER_MODAL;

    p = Tcl_DStringValue(&scripts);
    end = p + Tcl_DStringLength(&scripts);
    i = 0;

    /*
     * Be carefule when dereferencing screenPtr or bindInfoPtr. If we evaluate
     * something that destroys ".", bindInfoPtr would have been freed, but we
     * can tell that by first checking to see if winPtr->mainPtr == NULL.
     */

    Tcl_Preserve((ClientData) bindInfoPtr);
    while (p < end) {


	int code;

	if (!bindInfoPtr->deleted) {
	    screenPtr->bindingDepth++;
	}
	Tcl_AllowExceptions(interp);

	if (*p == '\0') {
	    PatSeq *psPtr;

	    psPtr = pendingPtr->matchArray[i];
	    i++;
	    code = TCL_OK;
	    if ((pendingPtr->deleted == 0)
		    && ((psPtr->flags & MARKED_DELETED) == 0)) {
		code = (*psPtr->eventProc)(psPtr->clientData, interp, eventPtr,
			tkwin, detail.keySym);
	    }
	    psPtr->refCount--;
	    if ((psPtr->refCount == 0) && (psPtr->flags & MARKED_DELETED)) {
		if (psPtr->freeProc != NULL) {
		    (*psPtr->freeProc)(psPtr->clientData);
		}
		ckfree((char *) psPtr);
	    }
	} else {
	    int len = (int) strlen(p);

	    code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL);
	    p += len;
	}
	p++;

	if (!bindInfoPtr->deleted) {
	    screenPtr->bindingDepth--;
	}
	if (code != TCL_OK) {
	    if (code == TCL_CONTINUE) {
		/*
		 * Do nothing: just go on to the next command.
		 */
	    } else if (code == TCL_BREAK) {
		break;
	    } else {
		Tcl_AddErrorInfo(interp, "\n    (command bound to event)");
		Tcl_BackgroundError(interp);
		break;
	    }
	}
    }

    if (matchCount > 0 && !pendingPtr->deleted) {
	/*
	 * 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);
	if (deferModal) {
	    modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc);
	    if (modalProc != NULL) {
		(*modalProc)(tkwin, eventPtr);
	    }
	}
    }

    if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0)
	    && ((oldDispPtr != screenPtr->curDispPtr)
		    || (oldScreen != screenPtr->curScreenIndex))) {
	/*
	 * Some other binding script is currently executing, but its screen is
	 * no longer current. Change the current display back again.
	 */

	screenPtr->curDispPtr = oldDispPtr;
	screenPtr->curScreenIndex = oldScreen;
	ChangeScreen(interp, oldDispPtr->name, oldScreen);
    }
    Tcl_DStringResult(interp, &savedResult);
    Tcl_DStringFree(&scripts);

    if (matchCount > 0) {
	if (!bindInfoPtr->deleted) {
	    /*
	     * Delete the pending list from the list of pending scripts for
	     * this window.
	     */

	    PendingBinding **curPtrPtr;

	    for (curPtrPtr = &bindInfoPtr->pendingList; ; ) {
		if (*curPtrPtr == pendingPtr) {
		    *curPtrPtr = pendingPtr->nextPtr;
		    break;
		}
		curPtrPtr = &(*curPtrPtr)->nextPtr;
	    }
	}
	if (pendingPtr != &staticPending) {
	    ckfree((char *) pendingPtr);
	}
    }
    Tcl_Release((ClientData) bindInfoPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkBindDeadWindow --
 *
 *	This function is invoked when it is determined that a window is dead.
 *	It cleans up bind-related information about the window
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Any pending C bindings for this window are cancelled.
 *
 *---------------------------------------------------------------------------
 */

void
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.
     */

    if (winPtr->mainPtr == NULL) {
	return;
    }

    bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
    curPtr = bindInfoPtr->pendingList;
    while (curPtr != NULL) {
	if (curPtr->tkwin == (Tk_Window) winPtr) {
	    curPtr->deleted = 1;
	}
	curPtr = curPtr->nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *	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.
 *
 * 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
















































































































static PatSeq *
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 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
				 * differs from the return value, it is the
				 * virtual event that most closely matched the
				 * return value (a physical event). Not
				 * modified unless a result other than bestPtr
				 * is returned. */
{


    PatSeq *matchPtr, *bestSourcePtr, *sourcePtr;

    bestSourcePtr = *sourcePtrPtr;






    /*
     * Iterate over all the pattern sequences.
     */


    for ( ; psPtr != NULL; psPtr = psPtr->nextSeqPtr) {
	XEvent *eventPtr = &bindPtr->eventRing[bindPtr->curEvent];
	Detail *detailPtr = &bindPtr->detailRing[bindPtr->curEvent];
	TkPattern *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.
	 */

	patCount = psPtr->numPats;
	ringCount = EVENT_BUFFER_SIZE;
	while (patCount > 0) {
	    if (ringCount <= 0) {

		goto nextSequence;
	    }
	    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:
		 * 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.
		 */






		if ((patPtr->eventType == KeyPress)
			|| (patPtr->eventType == KeyRelease)) {
		    if ((eventPtr->xany.type == ButtonPress)
			    || (eventPtr->xany.type == ButtonRelease)) {
			goto nextSequence;
		    }

		} else if ((patPtr->eventType == ButtonPress)
			|| (patPtr->eventType == ButtonRelease)) {
		    if ((eventPtr->xany.type == KeyPress)
			    || (eventPtr->xany.type == KeyRelease)) {
			/*
			 * Ignore key events if they are modifier keys.
			 */

			for (i = 0; i < dispPtr->numModKeyCodes; i++) {
			    if (dispPtr->modKeyCodes[i]
				    == eventPtr->xkey.keycode) {
				/*
				 * This key is a modifier key, so ignore it.
				 */


				goto nextEvent;
			    }
			}
			goto nextSequence;
		    }

		}
		goto nextEvent;
	    }
	    if (eventPtr->xany.type == CreateNotify
		    && eventPtr->xcreatewindow.parent != window) {
		goto nextSequence;
	    } 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.
	     */


	    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".

		 */

		if (eventPtr->xany.type == KeyPress) {
		    for (i = 0; i < dispPtr->numModKeyCodes; i++) {
			if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {
			    goto nextEvent;
			}
		    }
		}
		goto nextSequence;
	    }
	    flags = flagArray[eventPtr->type];
	    if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
		state = eventPtr->xkey.state;
	    } else if (flags & CROSSING) {
		state = eventPtr->xcrossing.state;
	    } else {
		state = 0;
	    }
	    if (patPtr->needMods != 0) {
		modMask = patPtr->needMods;
		if ((modMask & META_MASK) && (dispPtr->metaModMask != 0)) {
		    modMask = (modMask & ~META_MASK) | dispPtr->metaModMask;
		}
		if ((modMask & ALT_MASK) && (dispPtr->altModMask != 0)) {
		    modMask = (modMask & ~ALT_MASK) | dispPtr->altModMask;
		}

		if ((state & META_MASK) && (dispPtr->metaModMask != 0)) {
		    state = (state & ~META_MASK) | dispPtr->metaModMask;
		}
		if ((state & ALT_MASK) && (dispPtr->altModMask != 0)) {
		    state = (state & ~ALT_MASK) | dispPtr->altModMask;
		}




		if ((state & modMask) != modMask) {

		    goto nextSequence;
		}


	    }
	    if (psPtr->flags & PAT_NEARBY) {
		XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent];
		int timeDiff;

		timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time;
		if ((firstPtr->xkey.x_root
			    < (eventPtr->xkey.x_root - NEARBY_PIXELS))
			|| (firstPtr->xkey.x_root
			    > (eventPtr->xkey.x_root + NEARBY_PIXELS))
			|| (firstPtr->xkey.y_root
			    < (eventPtr->xkey.y_root - NEARBY_PIXELS))
			|| (firstPtr->xkey.y_root
			    > (eventPtr->xkey.y_root + NEARBY_PIXELS))
			|| (timeDiff > NEARBY_MS)) {
		    goto nextSequence;
		}


	    }
	    patPtr++;
	    patCount--;
	nextEvent:
	    if (eventPtr == bindPtr->eventRing) {
		eventPtr = &bindPtr->eventRing[EVENT_BUFFER_SIZE-1];
		detailPtr = &bindPtr->detailRing[EVENT_BUFFER_SIZE-1];
	    } else {
		eventPtr--;
		detailPtr--;
	    }
	    ringCount--;
	}

	matchPtr = psPtr;
	sourcePtr = psPtr;

	if (objectPtr != NULL) {
	    int iVirt;
	    VirtualOwners *voPtr;
	    PatternTableKey key;



	    /*
	     * The sequence matches the physical constraints. Is this object
	     * interested in any of the virtual events that correspond to this
	     * sequence?
	     */

	    voPtr = psPtr->voPtr;

	    memset(&key, 0, sizeof(key));
	    key.object = *objectPtr;
	    key.type = VirtualEvent;
	    key.detail.clientData = 0;

	    for (iVirt = 0; iVirt < voPtr->numOwners; iVirt++) {
		Tcl_HashEntry *hPtr = voPtr->owners[iVirt];


		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 *) Tcl_GetHashValue(hPtr);

		    if ((virtMatchPtr->numPats != 1)
			    || (virtMatchPtr->nextSeqPtr != NULL)) {
			Tcl_Panic("MatchPattern: badly constructed virtual event");
		    }
		    sourcePtr = virtMatchPtr;
		    goto match;
		}



	    }

	    /*
	     * The physical event matches a virtual event's definition, but
	     * the tag isn't interested in it.
	     */

	    goto nextSequence;
	}
    match:

	/*
	 * This sequence matches. If we've already got another match, pick
	 * whichever is most specific. Detail is most important, then
	 * needMods.
	 */

	if (bestPtr != NULL) {
	    TkPattern *patPtr2;

	    if (matchPtr->numPats != bestPtr->numPats) {
		if (bestPtr->numPats > matchPtr->numPats) {
		    goto nextSequence;
		} else {
		    goto newBest;
		}
	    }
	    for (i = 0, patPtr = matchPtr->pats, patPtr2 = bestPtr->pats;
		    i < matchPtr->numPats; i++, patPtr++, patPtr2++) {
		if (patPtr->detail.clientData != patPtr2->detail.clientData) {
		    if (patPtr->detail.clientData == 0) {
			goto nextSequence;
		    } else {
			goto newBest;
		    }
		}
		if (patPtr->needMods != patPtr2->needMods) {
		    if ((patPtr->needMods & patPtr2->needMods)
			    == patPtr->needMods) {
			goto nextSequence;
		    } else if ((patPtr->needMods & patPtr2->needMods)
			    == patPtr2->needMods) {
			goto newBest;
		    }









		}
	    }

	    /*
	     * 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.
	     *
	     * (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.
	     */

	    goto nextSequence;
	}
    newBest:
	bestPtr = matchPtr;
	bestSourcePtr = sourcePtr;

    nextSequence:
	continue;
    }



    *sourcePtrPtr = bestSourcePtr;

    return bestPtr;
}

/*
 *--------------------------------------------------------------
 *
 * ExpandPercents --
2957
2958
2959
2960
2961
2962
2963
2964

2965

2966



2967
2968
2969

2970


2971


2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006


3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018

3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032

3033
3034
3035
3036
3037

3038
3039
3040
3041



3042

3043
3044
3045
3046

3047
3048
3049
3050
3051


3052


3053

3054
3055
3056
3057

3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070


3071
3072
3073
3074
3075
3076
3077

3078
3079
3080
3081
3082
3083
3084
3085
3086
3087

3088
3089
3090
3091

3092
3093

3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105


3106
3107
3108
3109
3110

3111
3112

3113
3114
3115
3116
3117

3118
3119

3120
3121

3122
3123

3124
3125
3126
3127
3128


3129
3130


3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146


3147
3148
3149
3150
3151


3152
3153
3154
3155
3156
3157


3158
3159


3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170




3171
3172


3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187


3188
3189
3190



3191

3192

3193
3194
3195
3196
3197
3198
3199
3200

3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211

3212
3213
3214
3215
3216

3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227


3228
3229
3230
3231
3232
3233
3234
3235



3236
3237


3238
3239
3240
3241
3242
3243

3244
3245
3246
3247
3248

3249
3250
3251
3252
3253
3254
3255
3256
3257



3258

3259
3260
3261
3262
3263
3264

3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
ExpandPercents(
    TkWindow *winPtr,		/* Window where event occurred: needed to get input context. */

    const char *before,		/* Command containing percent expressions to be replaced. */

    Event *eventPtr,		/* Event containing information to be used in % replacements. */



    unsigned scriptCount,	/* The number of script-based binding patterns matched so far for
    				 * this event. */
    Tcl_DString *dsPtr)		/* Dynamic string in which to append new command. */

{


    unsigned flags;


    Tcl_DString buf;
    XEvent *evPtr;

    assert(winPtr);
    assert(before);
    assert(eventPtr);
    assert(dsPtr);

    Tcl_DStringInit(&buf);
    evPtr = &eventPtr->xev;
    flags = (evPtr->type < TK_LASTEVENT) ? flagArray[evPtr->type] : 0;

#define SET_NUMBER(value)   { number = (value);			     \
    snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "d", number);	     \
    string = numStorage;					     \
    }

#define SET_UNUMBER(value)  { unumber = (value);				\
	snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "u", unumber);	\
	string = numStorage;						\
    }

    while (1) {
	char numStorage[TCL_INTEGER_SPACE];
	const char *string;
	Tcl_WideInt number;     /* signed */
	Tcl_WideUInt unumber;   /* unsigned */

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	for (string = before; *string && *string != '%'; ++string)
	    ;


	if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, string - before);
	    before = string;
	}
	if (!*before) {
	    break;
	}

	/*
	 * There's a percent sequence here. Process it.
	 */


	string = "??";
	switch (before[1]) {
	case '#':
	    SET_UNUMBER(evPtr->xany.serial);
	    break;
	case 'a':
	    if (flags & CONFIG) {
		TkpPrintWindowId(numStorage, evPtr->xconfigure.above);
		string = numStorage;
	    }
	    break;
	case 'b':
	    if (flags & BUTTON) {
		SET_UNUMBER(evPtr->xbutton.button);

	    }
	    break;
	case 'c':
	    if (flags & EXPOSE) {
		SET_NUMBER(evPtr->xexpose.count);

	    }
	    break;
	case 'd':
	    if (flags & (CROSSING|FOCUS)) {



		int detail = (flags & FOCUS) ? evPtr->xfocus.detail : evPtr->xcrossing.detail;

		string = TkFindStateString(notifyDetail, detail);
	    } else if (flags & CONFIGREQ) {
		if (evPtr->xconfigurerequest.value_mask & CWStackMode) {
		    string = TkFindStateString(configureRequestDetail, evPtr->xconfigurerequest.detail);

		} else {
		    string = "";
		}
	    } else if (flags & VIRTUAL) {
		XVirtualEvent *vePtr = (XVirtualEvent *) evPtr;


		string = vePtr->user_data ? Tcl_GetString(vePtr->user_data) : "";


	    }

	    break;
	case 'f':
	    if (flags & CROSSING) {
		SET_NUMBER(evPtr->xcrossing.focus != 0);

	    }
	    break;
	case 'h':
	    if (flags & EXPOSE) {
		SET_NUMBER(evPtr->xexpose.height);
	    } else if (flags & CONFIG) {
		SET_NUMBER(evPtr->xconfigure.height);
	    } else if (flags & CREATE) {
		SET_NUMBER(evPtr->xcreatewindow.height);
	    } else if (flags & CONFIGREQ) {
		SET_NUMBER(evPtr->xconfigurerequest.height);
	    } else if (flags & RESIZEREQ) {
		SET_NUMBER(evPtr->xresizerequest.height);


	    }
	    break;
	case 'i':
	    if (flags & CREATE) {
		TkpPrintWindowId(numStorage, evPtr->xcreatewindow.window);
	    } else if (flags & CONFIGREQ) {
		TkpPrintWindowId(numStorage, evPtr->xconfigurerequest.window);

	    } else if (flags & MAPREQ) {
		TkpPrintWindowId(numStorage, evPtr->xmaprequest.window);
	    } else {
		TkpPrintWindowId(numStorage, evPtr->xany.window);
	    }
	    string = numStorage;
	    break;
	case 'k':
	    if (flags & KEY) {
		SET_UNUMBER(evPtr->xkey.keycode);

	    }
	    break;
	case 'm':
	    if (flags & CROSSING) {

		string = TkFindStateString(notifyMode, evPtr->xcrossing.mode);
	    } else if (flags & FOCUS) {

		string = TkFindStateString(notifyMode, evPtr->xfocus.mode);
	    }
	    break;
	case 'o':
	    if (flags & CREATE) {
		SET_NUMBER(evPtr->xcreatewindow.override_redirect != 0);
	    } else if (flags & MAP) {
		SET_NUMBER(evPtr->xmap.override_redirect != 0);
	    } else if (flags & REPARENT) {
		SET_NUMBER(evPtr->xreparent.override_redirect != 0);
	    } else if (flags & CONFIG) {
		SET_NUMBER(evPtr->xconfigure.override_redirect != 0);


	    }
	    break;
	case 'p':
	    if (flags & CIRC) {
		string = TkFindStateString(circPlace, evPtr->xcirculate.place);

	    } else if (flags & CIRCREQ) {
		string = TkFindStateString(circPlace, evPtr->xcirculaterequest.place);

	    }
	    break;
	case 's':
	    if (flags & HAS_XKEY_HEAD_AND_STATE) {
		SET_UNUMBER(evPtr->xkey.state);

	    } else if (flags & CROSSING) {
		SET_UNUMBER(evPtr->xcrossing.state);

	    } else if (flags & PROP) {
		string = TkFindStateString(propNotify, evPtr->xproperty.state);

	    } else if (flags & VISIBILITY) {
		string = TkFindStateString(visNotify, evPtr->xvisibility.state);

	    }
	    break;
	case 't':
	    if (flags & HAS_XKEY_HEAD) {
		SET_UNUMBER(evPtr->xkey.time);


	    } else if (flags & PROP) {
		SET_UNUMBER(evPtr->xproperty.time);


	    }
	    break;
	case 'v':
	    SET_UNUMBER(evPtr->xconfigurerequest.value_mask);
	    break;
	case 'w':
	    if (flags & EXPOSE) {
		SET_NUMBER(evPtr->xexpose.width);
	    } else if (flags & CONFIG) {
		SET_NUMBER(evPtr->xconfigure.width);
	    } else if (flags & CREATE) {
		SET_NUMBER(evPtr->xcreatewindow.width);
	    } else if (flags & CONFIGREQ) {
		SET_NUMBER(evPtr->xconfigurerequest.width);
	    } else if (flags & RESIZEREQ) {
		SET_NUMBER(evPtr->xresizerequest.width);


	    }
	    break;
	case 'x':
	    if (flags & HAS_XKEY_HEAD) {
		SET_NUMBER(evPtr->xkey.x);


	    } else if (flags & EXPOSE) {
		SET_NUMBER(evPtr->xexpose.x);
	    } else if (flags & (CREATE|CONFIG|GRAVITY)) {
		SET_NUMBER(evPtr->xcreatewindow.x);
	    } else if (flags & REPARENT) {
		SET_NUMBER(evPtr->xreparent.x);


	    } else if (flags & CONFIGREQ) {
		SET_NUMBER(evPtr->xconfigurerequest.x);


	    }
	    break;
	case 'y':
	    if (flags & HAS_XKEY_HEAD) {
		SET_NUMBER(evPtr->xkey.y);
	    } else if (flags & EXPOSE) {
		SET_NUMBER(evPtr->xexpose.y);
	    } else if (flags & (CREATE|CONFIG|GRAVITY)) {
		SET_NUMBER(evPtr->xcreatewindow.y);
	    } else if (flags & REPARENT) {
		SET_NUMBER(evPtr->xreparent.y);




	    } else if (flags & CONFIGREQ) {
		SET_NUMBER(evPtr->xconfigurerequest.y);


	    }
	    break;
	case 'A':
	    if (flags & KEY) {
		Tcl_DStringFree(&buf);
		string = TkpGetString(winPtr, evPtr, &buf);
	    }
	    break;
	case 'B':
	    if (flags & CREATE) {
		SET_NUMBER(evPtr->xcreatewindow.border_width);
	    } else if (flags & CONFIGREQ) {
		SET_NUMBER(evPtr->xconfigurerequest.border_width);
	    } else if (flags & CONFIG) {
		SET_NUMBER(evPtr->xconfigure.border_width);


	    }
	    break;
	case 'D':



	    if (flags & WHEEL) {

		SET_NUMBER((int)evPtr->xbutton.button); /* mis-use button field for this */

	    }
	    break;
	case 'E':
	    SET_NUMBER(evPtr->xany.send_event != 0);
	    break;
	case 'K':
	    if (flags & KEY) {
		const char *name = TkKeysymToString(eventPtr->detail.info);

		if (name) {
		    string = name;
		}
	    }
	    break;
	case 'M':
	    SET_UNUMBER(scriptCount);
	    break;
	case 'N':
	    if (flags & KEY) {
		SET_UNUMBER(eventPtr->detail.info);

	    }
	    break;
	case 'P':
	    if (flags & PROP) {
		string = Tk_GetAtomName((Tk_Window) winPtr, evPtr->xproperty.atom);

	    }
	    break;
	case 'R':
	    if (flags & HAS_XKEY_HEAD) {
		TkpPrintWindowId(numStorage, evPtr->xkey.root);
		string = numStorage;
	    }
	    break;
	case 'S':
	    if (flags & HAS_XKEY_HEAD) {
		TkpPrintWindowId(numStorage, evPtr->xkey.subwindow);


		string = numStorage;
	    }
	    break;
	case 'T':
	    SET_NUMBER(evPtr->type);
	    break;
	case 'W': {
	    Tk_Window tkwin = Tk_IdToWindow(evPtr->xany.display, evPtr->xany.window);



	    if (tkwin) {
		string = Tk_PathName(tkwin);


	    }
	    break;
	}
	case 'X':
	    if (flags & HAS_XKEY_HEAD) {
		SET_NUMBER(evPtr->xkey.x_root);

	    }
	    break;
	case 'Y':
	    if (flags & HAS_XKEY_HEAD) {
		SET_NUMBER(evPtr->xkey.y_root);

	    }
	    break;
	default:
	    numStorage[0] = before[1];
	    numStorage[1] = '\0';
	    string = numStorage;
	    break;
	}
	{   /* local scope */



	    int cvtFlags;

	    unsigned spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
	    unsigned length = Tcl_DStringLength(dsPtr);

	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    spaceNeeded = Tcl_ConvertElement(
		    string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES);

	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    before += 2;
	}
    }

#undef SET_NUMBER
#undef SET_UNUMBER

    Tcl_DStringFree(&buf);
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeScreen --







|
>
|
>
|
>
>
>
|
|
|
>

>
>
|
>
>

<
|
<
<
<
<


|
|
|
<
<
<
|
|
<
<
<



<
<
<
<
<





|
<
>
>

|


|







>



|
|


|


|


|
>

|


|
>

|


>
>
>
|
>
|

|
|
>




|
>
>
|
>
>
|
>
|


|
>

|


|

|

|

|

|
>
>

|


|

|
>

|

|


|

|
|
>

|


>
|

>
|

|


|

|

|

|
>
>

|


|
>

|
>

|

|
|
>

|
>

|
>

|
>

|

|
|
>
>

|
>
>

|

|
|


|

|

|

|

|
>
>

|

|
|
>
>

|

|

|
>
>

|
>
>

|

|
|

|

|

|
>
>
>
>

|
>
>

|

|

|

|


|

|

|
>
>

|

>
>
>
|
>
|
>

|

|
|

|
|
>
|



|

|
|

|
|
>

|


|
>

|

|
|


|

|
|
>
>
|
<
<

|
|

|
>
>
>
|

>
>

|


|
|
>

|

|
|
>

|




|

|
>
>
>
|
>
|
|
<
|
|
|
>
|
|
|
<
<
<
<
<







2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275

2276




2277
2278
2279
2280
2281



2282
2283



2284
2285
2286





2287
2288
2289
2290
2291
2292

2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574


2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615

2616
2617
2618
2619
2620
2621
2622





2623
2624
2625
2626
2627
2628
2629
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
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). */
    unsigned int scriptCount,	/* The number of script-based binding patterns
				 * matched so far for this event. */
    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;
    Tcl_DString buf;

    char numStorage[NUM_SIZE+1];





    Tcl_DStringInit(&buf);

    if (eventPtr->type < TK_LASTEVENT) {
	flags = flagArray[eventPtr->type];



    } else {
	flags = 0;



    }

    while (1) {





	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	for (string = before; (*string != 0) && (*string != '%'); string++) {

	    /* Empty loop body. */
	}
	if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, (int) (string-before));
	    before = string;
	}
	if (*before == 0) {
	    break;
	}

	/*
	 * 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 = "";
		}
	    } else if (flags & VIRTUAL) {
		XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;

		if (vePtr->user_data != NULL) {
		    string = Tcl_GetString(vePtr->user_data);
		} 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);
	    }
	    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;
		goto doNumber;
	    } 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;
	    }
	    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;
	    }
	    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;
	    }
	    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;
	    }
	    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;
	    }
	    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 '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;
	case 'M':
	    number = scriptCount;
	    goto doNumber;
	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;
	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:
	sprintf(numStorage, "%d", number);
	string = numStorage;

    doString:
	spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);

	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	spaceNeeded = Tcl_ConvertElement(string,
		Tcl_DStringValue(dsPtr) + length,
		cvtFlags | TCL_DONT_USE_BRACES);
	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	before += 2;
    }





    Tcl_DStringFree(&buf);
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeScreen --
3296
3297
3298
3299
3300
3301
3302
3303
3304

3305
3306





3307

3308
3309

3310
3311
3312
3313
3314
3315
3316
3317
3318
3319

static void
ChangeScreen(
    Tcl_Interp *interp,		/* Interpreter in which to invoke command. */
    char *dispName,		/* Name of new display. */
    int screenIndex)		/* Index of new screen. */
{
    Tcl_Obj *cmdObj = Tcl_ObjPrintf("::tk::ScreenChanged %s.%d", dispName, screenIndex);
    int code;


    Tcl_IncrRefCount(cmdObj);





    code = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_GLOBAL);

    if (code != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (changing screen in event binding)");

	Tcl_BackgroundException(interp, code);
    }
    Tcl_DecrRefCount(cmdObj);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_EventCmd --
 *







|

>

|
>
>
>
>
>
|
>

|
>
|

<







2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669

2670
2671
2672
2673
2674
2675
2676

static void
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;
    char screen[TCL_INTEGER_SPACE];

    Tcl_DStringInit(&cmd);
    Tcl_DStringAppend(&cmd, "tk::ScreenChanged ", 18);
    Tcl_DStringAppend(&cmd, dispName, -1);
    sprintf(screen, ".%d", 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 --
 *
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346



3347


3348
3349


3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375



3376
3377

3378
3379
3380
3381
3382
3383
3384
3385
3386
3387

3388



3389
3390

3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403

3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419

3420
3421
3422
3423
3424
3425
3426
int
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, i;
    char *name;
    const char *event;
    Tk_Window tkwin;
    TkBindInfo bindInfo;
    VirtualEventTable *vetPtr;

    static const char *const optionStrings[] = { "add", "delete", "generate", "info", NULL };



    enum options { EVENT_ADD, EVENT_DELETE, EVENT_GENERATE, EVENT_INFO };



    assert(clientData);



    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(
	    interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) {
#ifdef SUPPORT_DEBUGGING
    	if (strcmp(Tcl_GetString(objv[1]), "debug") == 0) {
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "debug number");
		return TCL_ERROR;
	    }
	    Tcl_GetIntFromObj(interp, objv[2], &BindCount);
	    return TCL_OK;
	}
#endif
	return TCL_ERROR;
    }

    tkwin = (Tk_Window) clientData;
    bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
    vetPtr = &bindInfo->virtualEventTable;

    switch ((enum options) index) {
    case EVENT_ADD:



	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual sequence ?sequence ...?");

	    return TCL_ERROR;
	}
	name = Tcl_GetString(objv[2]);
	for (i = 3; i < objc; ++i) {
	    event = Tcl_GetString(objv[i]);
	    if (!CreateVirtualEvent(interp, vetPtr, name, event)) {
		return TCL_ERROR;
	    }
	}
	break;

    case EVENT_DELETE:



	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");

	    return TCL_ERROR;
	}
	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 ?-option value ...?");
	    return TCL_ERROR;
	}
	return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2);
    case EVENT_INFO:
	if (objc == 2) {
	    GetAllVirtualEvents(interp, vetPtr);
	    return TCL_OK;
	}
	if (objc == 3) {
	    return GetVirtualEvent(interp, vetPtr, objv[2]);
	}
	Tcl_WrongNumArgs(interp, 2, objv, "?virtual?");
	return TCL_ERROR;

    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *







|
<
<

<

|
|
>
>
>
|
>
>

|
>
>





|
<
<
<
<
<
<
<
<
|
<
<



<
<
<
<

|
>
>
>

|
>



|

|




>
|
>
>
>

|
>






|






>


|







<
|
|
|
|
|
>







2689
2690
2691
2692
2693
2694
2695
2696


2697

2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716








2717


2718
2719
2720




2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770

2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
int
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[] = {
	"add",		"delete",	"generate",	"info",
	NULL
    };
    enum options {
	EVENT_ADD,	EVENT_DELETE,	EVENT_GENERATE,	EVENT_INFO
    };

    tkwin = (Tk_Window) clientData;
    bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
    vetPtr = &((BindInfo *) bindInfo)->virtualEventTable;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,








	    &index) != TCL_OK) {


	return TCL_ERROR;
    }





    switch ((enum options) index) {
    case EVENT_ADD: {
	int i;
	char *name, *event;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "virtual sequence ?sequence ...?");
	    return TCL_ERROR;
	}
	name = Tcl_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;
	    }
	}
	break;
    }
    case EVENT_DELETE: {
	int i;
	char *name, *event;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "virtual ?sequence sequence ...?");
	    return TCL_ERROR;
	}
	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;
}

/*
 *---------------------------------------------------------------------------
 *
3436
3437
3438
3439
3440
3441
3442
3443

3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
 *	*vetPtr is now initialized.
 *
 *---------------------------------------------------------------------------
 */

static void
InitVirtualEventTable(
    VirtualEventTable *vetPtr)	/* Pointer to virtual event table. Memory is supplied by the caller. */

{
    assert(vetPtr);
    memset(vetPtr, 0, sizeof(*vetPtr));
    Tcl_InitHashTable(&vetPtr->lookupTables.patternTable, sizeof(PatternTableKey)/sizeof(int));
    Tcl_InitHashTable(&vetPtr->lookupTables.listTable, sizeof(PatternTableKey)/sizeof(int));
    Tcl_InitHashTable(&vetPtr->nameTable, TCL_ONE_WORD_KEYS);
    PSList_Init(&vetPtr->lookupTables.entryPool);
}

/*
 *---------------------------------------------------------------------------
 *
 * DeleteVirtualEventTable --
 *







|
>

<
<
|
|

<







2793
2794
2795
2796
2797
2798
2799
2800
2801
2802


2803
2804
2805

2806
2807
2808
2809
2810
2811
2812
 *	*vetPtr is now initialized.
 *
 *---------------------------------------------------------------------------
 */

static void
InitVirtualEventTable(
    VirtualEventTable *vetPtr)	/* Pointer to virtual event table. Memory is
				 * supplied by the caller. */
{


    Tcl_InitHashTable(&vetPtr->patternTable,
	    sizeof(PatternTableKey) / sizeof(int));
    Tcl_InitHashTable(&vetPtr->nameTable, TCL_ONE_WORD_KEYS);

}

/*
 *---------------------------------------------------------------------------
 *
 * DeleteVirtualEventTable --
 *
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535

3536

3537
3538
3539
3540
3541
3542
3543

3544
3545
3546
3547
3548
3549
3550
3551


3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566








3567

3568

3569






3570

3571
3572

3573

3574








3575



3576
3577
3578
3579
3580
3581
3582
3583
3584

static void
DeleteVirtualEventTable(
    VirtualEventTable *vetPtr)	/* The virtual event table to delete. */
{
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    assert(vetPtr);

    hPtr = Tcl_FirstHashEntry(&vetPtr->lookupTables.patternTable, &search);
    for ( ; hPtr; hPtr = Tcl_NextHashEntry(&search)) {
	PatSeq *nextPtr;
	PatSeq *psPtr;

	for (psPtr = (PatSeq *)Tcl_GetHashValue(hPtr); psPtr; psPtr = nextPtr) {
	    assert(TEST_PSENTRY(psPtr));
	    nextPtr = psPtr->nextSeqPtr;
	    DEBUG(psPtr->owned = 0;)
	    FreePatSeq(psPtr);
	}
    }
    Tcl_DeleteHashTable(&vetPtr->lookupTables.patternTable);

    hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
    for ( ; hPtr; hPtr = Tcl_NextHashEntry(&search)) {
	ckfree(Tcl_GetHashValue(hPtr));
    }
    Tcl_DeleteHashTable(&vetPtr->nameTable);

    ClearLookupTable(&vetPtr->lookupTables, NULL);
    Tcl_DeleteHashTable(&vetPtr->lookupTables.listTable);

    DEBUG(countEntryItems -= PSList_Size(&vetPtr->lookupTables.entryPool);)
    PSList_Traverse(&vetPtr->lookupTables.entryPool, FreePatSeqEntry);
}

/*
 *----------------------------------------------------------------------
 *
 * CreateVirtualEvent --
 *
 *	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 occurred 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.
 *
 *----------------------------------------------------------------------
 */

static int
CreateVirtualEvent(
    Tcl_Interp *interp,		/* Used for error reporting. */
    VirtualEventTable *vetPtr,	/* Table in which to augment virtual event. */
    char *virtString,		/* Name of new virtual event. */
    const char *eventString)	/* String describing physical event that triggers virtual event. */

{
    PatSeq *psPtr;
    int dummy;
    Tcl_HashEntry *vhPtr;

    PhysOwned *owned;

    Tk_Uid virtUid;

    assert(vetPtr);
    assert(virtString);
    assert(eventString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {

	return 0;
    }

    /*
     * Find/create physical event
     */

    if (!(psPtr = FindSequence(interp, &vetPtr->lookupTables, NULL, eventString, 1, 0, NULL))) {


	return 0;
    }
    assert(TEST_PSENTRY(psPtr));

    /*
     * Find/create virtual event.
     */

    vhPtr = Tcl_CreateHashEntry(&vetPtr->nameTable, virtUid, &dummy);

    /*
     * Make virtual event own the physical event.
     */

    owned = (PhysOwned *)Tcl_GetHashValue(vhPtr);










    if (!PhysOwned_Contains(owned, psPtr)) {

	PhysOwned_Append(&owned, psPtr);






	Tcl_SetHashValue(vhPtr, owned);

	DEBUG(psPtr->owned = 1;)
	InsertPatSeq(&vetPtr->lookupTables, psPtr);

	/* Make physical event so it can trigger the virtual event. */

	VirtOwners_Append(&psPtr->ptr.owners, vhPtr);








    }




    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteVirtualEvent --
 *







|
<

|
|
<
<
|
|
<

|
|


|


|
|


<
<
<
<
<
<











|















|
>




>
|
>


<
<
<
<
|
>
|






|
>
>
|

<











|
>
>
>
>
>
>
>
>

>
|
>
|
>
>
>
>
>
>
|
>
|
|
>
|
>
|
>
>
>
>
>
>
>
>

>
>
>

|







2824
2825
2826
2827
2828
2829
2830
2831

2832
2833
2834


2835
2836

2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848






2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886




2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900

2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960

static void
DeleteVirtualEventTable(
    VirtualEventTable *vetPtr)	/* The virtual event table to delete. */
{
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    PatSeq *psPtr, *nextPtr;


    hPtr = Tcl_FirstHashEntry(&vetPtr->patternTable, &search);
    for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {


	psPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
	for ( ; psPtr != NULL; psPtr = nextPtr) {

	    nextPtr = psPtr->nextSeqPtr;
	    ckfree((char *) psPtr->voPtr);
	    ckfree((char *) psPtr);
	}
    }
    Tcl_DeleteHashTable(&vetPtr->patternTable);

    hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
    for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	ckfree((char *) Tcl_GetHashValue(hPtr));
    }
    Tcl_DeleteHashTable(&vetPtr->nameTable);






}

/*
 *----------------------------------------------------------------------
 *
 * CreateVirtualEvent --
 *
 *	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.
 *
 * Side effects:
 *	The virtual event may cause future calls to Tk_BindEvent to behave
 *	differently than they did previously.
 *
 *----------------------------------------------------------------------
 */

static int
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;
    int dummy;
    Tcl_HashEntry *vhPtr;
    unsigned long eventMask;
    PhysicalsOwned *poPtr;
    VirtualOwners *voPtr;
    Tk_Uid virtUid;





    virtUid = GetVirtualEventUid(interp, virtString);
    if (virtUid == NULL) {
	return TCL_ERROR;
    }

    /*
     * Find/create physical event
     */

    psPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString,
	    1, 0, &eventMask);
    if (psPtr == NULL) {
	return TCL_ERROR;
    }


    /*
     * Find/create virtual event.
     */

    vhPtr = Tcl_CreateHashEntry(&vetPtr->nameTable, virtUid, &dummy);

    /*
     * Make virtual event own the physical event.
     */

    poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
    if (poPtr == NULL) {
	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;
	    }
	}
	poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr,
		sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *));
    }
    Tcl_SetHashValue(vhPtr, (ClientData) poPtr);
    poPtr->patSeqs[poPtr->numOwned] = psPtr;
    poPtr->numOwned++;

    /*
     * Make physical event so it can trigger the virtual event.
     */

    voPtr = psPtr->voPtr;
    if (voPtr == NULL) {
	voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners));
	voPtr->numOwners = 0;
    } else {
	voPtr = (VirtualOwners *) ckrealloc((char *) voPtr,
		sizeof(VirtualOwners)
		+ voPtr->numOwners * sizeof(Tcl_HashEntry *));
    }
    psPtr->voPtr = voPtr;
    voPtr->owners[voPtr->numOwners] = vhPtr;
    voPtr->numOwners++;

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteVirtualEvent --
 *
3600
3601
3602
3603
3604
3605
3606
3607

3608

3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621

3622
3623
3624
3625

3626
3627
3628
3629
3630
3631
3632

3633
3634
3635
3636
3637
3638
3639
3640

3641
3642

3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662









3663

3664
3665
3666
3667
3668
3669
3670

3671



3672

















3673
3674


3675
3676
3677
3678
3679

3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695

3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708

3709
3710
3711
3712
3713
3714
3715
 *--------------------------------------------------------------
 */

static int
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. */

    const char *eventString)	/* The event sequence that should be deleted, or NULL to delete

    				 * all event sequences for the entire virtual event. */
{
    int iPhys;
    Tk_Uid virtUid;
    Tcl_HashEntry *vhPtr;
    PhysOwned *owned;
    const PatSeq *eventPSPtr;
    PatSeq *lastElemPtr;

    assert(vetPtr);
    assert(virtString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {

	return TCL_ERROR;
    }

    if (!(vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid))) {

	return TCL_OK;
    }
    owned = (PhysOwned *)Tcl_GetHashValue(vhPtr);

    eventPSPtr = NULL;
    if (eventString) {
	LookupTables *lookupTables = &vetPtr->lookupTables;


	/*
	 * 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, lookupTables, NULL, eventString, 0, 0, NULL);

	if (!eventPSPtr) {
	    const char *string = Tcl_GetString(Tcl_GetObjResult(interp));

	    return string[0] ? TCL_ERROR : TCL_OK;
	}
    }

    for (iPhys = PhysOwned_Size(owned); --iPhys >= 0; ) {
	PatSeq *psPtr = PhysOwned_Get(owned, iPhys);

	assert(TEST_PSENTRY(psPtr));

	if (!eventPSPtr || psPtr == eventPSPtr) {
	    VirtOwners *owners = psPtr->ptr.owners;
	    int iVirt = VirtOwners_Find(owners, vhPtr);

	    assert(iVirt != -1); /* otherwise we couldn't find owner, and this should not happen */

	    /*
	     * Remove association between this physical event and the given
	     * virtual event that it triggers.
	     */










	    if (VirtOwners_Size(owners) > 1) {

		/*
		 * 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.
		 */
		VirtOwners_Set(owners, iVirt, VirtOwners_Back(owners));

		VirtOwners_PopBack(owners);



	    } else {

















		/*
		 * Removed last reference to this physical event, so remove it


		 * from lookup table.
		 */
		DEBUG(psPtr->owned = 0;)
		RemovePatSeqFromLookup(&vetPtr->lookupTables, psPtr);
		DeletePatSeq(psPtr);

	    }

	    /*
	     * Now delete the virtual event's reference to the physical event.
	     */

	    lastElemPtr = PhysOwned_Back(owned);

	    if (PhysOwned_PopBack(owned) > 0 && eventPSPtr) {
		/*
		 * Just deleting this one physical event. Consolidate list of
		 * owned physical events and return.
		 */
		if ((size_t) iPhys < PhysOwned_Size(owned)) {
		    PhysOwned_Set(owned, iPhys, lastElemPtr);
		}

		return TCL_OK;
	    }
	}
    }

    if (PhysOwned_IsEmpty(owned)) {
	/*
	 * 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.
	 */
	PhysOwned_Free(&owned);

	Tcl_DeleteHashEntry(vhPtr);
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------







|
>
|
>
|




|
|
<

<
<
<
|
>



|
>


|


|
<
>







|
>
|
|
>
|



|
|

<
<
|
<
|
|
<






>
>
>
>
>
>
>
>
>
|
>

|
|
<
<

|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
>
|

|
<
<
>






<
|
|




<
<
|
>





|






|
>







2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993

2994



2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007

3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027


3028

3029
3030

3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050


3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082


3083
3084
3085
3086
3087
3088
3089

3090
3091
3092
3093
3094
3095


3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
 *--------------------------------------------------------------
 */

static int
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,
				 * or NULL to delete all event sequences for
				 * the entire virtual event. */
{
    int iPhys;
    Tk_Uid virtUid;
    Tcl_HashEntry *vhPtr;
    PhysicalsOwned *poPtr;
    PatSeq *eventPSPtr;





    virtUid = GetVirtualEventUid(interp, virtString);
    if (virtUid == NULL) {
	return TCL_ERROR;
    }

    vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid);
    if (vhPtr == NULL) {
	return TCL_OK;
    }
    poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);

    eventPSPtr = NULL;
    if (eventString != NULL) {

	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.
	 */

	eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL,
		eventString, 0, 0, &eventMask);
	if (eventPSPtr == NULL) {
	    const char *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.
	     */

	    voPtr = psPtr->voPtr;
	    for (iVirt = 0; iVirt < voPtr->numOwners; iVirt++) {
		if (voPtr->owners[iVirt] == vhPtr) {
		    break;
		}
	    }
	    if (iVirt == voPtr->numOwners) {
		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.


		 */

		PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);

		if (prevPtr == psPtr) {
		    if (psPtr->nextSeqPtr == NULL) {
			Tcl_DeleteHashEntry(psPtr->hPtr);
		    } else {
			Tcl_SetHashValue(psPtr->hPtr,
				psPtr->nextSeqPtr);
		    }
		} else {
		    for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
			if (prevPtr == NULL) {
			    Tcl_Panic("DeleteVirtualEvent couldn't find on hash chain");
			}
			if (prevPtr->nextSeqPtr == psPtr) {
			    prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
			    break;
			}
		    }
		}
		ckfree((char *) psPtr->voPtr);
		ckfree((char *) psPtr);
	    } 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.
		 */



		voPtr->owners[iVirt] = voPtr->owners[voPtr->numOwners];
	    }

	    /*
	     * 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.
		 */



		poPtr->patSeqs[iPhys] = poPtr->patSeqs[poPtr->numOwned];
		return TCL_OK;
	    }
	}
    }

    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.
	 */

	ckfree((char *) poPtr);
	Tcl_DeleteHashEntry(vhPtr);
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742

3743
3744
3745
3746
3747
3748
3749
3750
3751

3752
3753
3754
3755

3756
3757
3758

3759
3760
3761


3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
 *---------------------------------------------------------------------------
 */

static int
GetVirtualEvent(
    Tcl_Interp *interp,		/* Interpreter for reporting. */
    VirtualEventTable *vetPtr,	/* Table in which to look for event. */
    Tcl_Obj *virtName)		/* String describing virtual event. */
{
    Tcl_HashEntry *vhPtr;

    unsigned iPhys;
    const PhysOwned *owned;
    Tk_Uid virtUid;
    Tcl_Obj *resultObj;

    assert(vetPtr);
    assert(virtName);

    if (!(virtUid = GetVirtualEventUid(interp, Tcl_GetString(virtName)))) {

	return TCL_ERROR;
    }

    if (!(vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid))) {

	return TCL_OK;
    }


    resultObj = Tcl_NewObj();
    owned = (const PhysOwned *)Tcl_GetHashValue(vhPtr);
    for (iPhys = 0; iPhys < PhysOwned_Size(owned); ++iPhys) {


	Tcl_ListObjAppendElement(NULL, resultObj, GetPatternObj(PhysOwned_Get(owned, iPhys)));
    }
    Tcl_SetObjResult(interp, resultObj);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *







|


>
|
|

<

<
<
<
|
>



|
>



>
|
|
|
>
>
|

|







3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149

3150



3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
 *---------------------------------------------------------------------------
 */

static int
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;
    int iPhys;
    PhysicalsOwned *poPtr;
    Tk_Uid virtUid;





    virtUid = GetVirtualEventUid(interp, virtString);
    if (virtUid == NULL) {
	return TCL_ERROR;
    }

    vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid);
    if (vhPtr == NULL) {
	return TCL_OK;
    }

    Tcl_DStringInit(&ds);

    poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
    for (iPhys = 0; iPhys < poPtr->numOwned; iPhys++) {
	Tcl_DStringSetLength(&ds, 0);
	GetPatternString(poPtr->patSeqs[iPhys], &ds);
	Tcl_AppendElement(interp, Tcl_DStringValue(&ds));
    }
    Tcl_DStringFree(&ds);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800


3801

3802
3803
3804

3805
3806
3807
3808
3809
3810
3811
static void
GetAllVirtualEvents(
    Tcl_Interp *interp,		/* Interpreter returning result. */
    VirtualEventTable *vetPtr)	/* Table containing events. */
{
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_Obj *resultObj;

    assert(vetPtr);

    resultObj = Tcl_NewObj();
    hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
    for ( ; hPtr; hPtr = Tcl_NextHashEntry(&search)) {


	Tcl_Obj* msg = Tcl_ObjPrintf("<<%s>>", (char *) Tcl_GetHashKey(hPtr->tablePtr, hPtr));

	Tcl_ListObjAppendElement(NULL, resultObj, msg);
    }
    Tcl_SetObjResult(interp, resultObj);

}

/*
 *---------------------------------------------------------------------------
 *
 * HandleEventGenerate --
 *







|

|

<

|
>
>
|
>
|

|
>







3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202

3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
static void
GetAllVirtualEvents(
    Tcl_Interp *interp,		/* Interpreter returning result. */
    VirtualEventTable *vetPtr)	/* Table containing events. */
{
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_DString ds;

    Tcl_DStringInit(&ds);


    hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
    for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	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_DStringFree(&ds);
}

/*
 *---------------------------------------------------------------------------
 *
 * HandleEventGenerate --
 *
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853

3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898

3899
3900
3901
3902
3903
3904
3905
3906
3907

3908
3909
3910
3911

3912
3913
3914
3915
3916
3917

3918
3919
3920
3921
3922

3923
3924
3925
3926
3927
3928
3929
3930
3931
3932

3933
3934
3935
3936
3937
3938
3939
3940
3941

3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969

3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012

4013
4014
4015

4016


4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067

4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084

4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107

4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146

4147
4148
4149
4150
4151
4152

4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180

4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227

4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241

4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262


4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373

4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385

4386
4387
4388
4389
4390
4391
4392
4393
4394

4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446



4447











4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485

4486
4487

4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552

4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
 *	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 synchronously or asynchronously, depending on
 *	the value specified by the optional "-when" option. The default
 *	setting is synchronous.
 *
 *---------------------------------------------------------------------------
 */

static int
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. */
{
    union { XEvent general; XVirtualEvent virt; } event;

    const char *p;
    const char *name;
    const char *windowName;

    Tcl_QueuePosition pos;
    TkPattern pat;
    Tk_Window tkwin;
    Tk_Window tkwin2;
    TkWindow *mainPtr;
    unsigned eventMask;
    Tcl_Obj *userDataObj;
    int synch;
    int warp;
    unsigned count;
    unsigned flags;
    int number;
    unsigned i;

    static const char *const fieldStrings[] = {
	"-when",	"-above",	"-borderwidth",	"-button",
	"-count",	"-data",	"-delta",	"-detail",
	"-focus",	"-height",
	"-keycode",	"-keysym",	"-mode",	"-override",
	"-place",	"-root",	"-rootx",	"-rooty",
	"-sendevent",	"-serial",	"-state",	"-subwindow",
	"-time",	"-warp",	"-width",	"-window",
	"-x",		"-y",		NULL
    };
    enum field {
	EVENT_WHEN,	EVENT_ABOVE,	EVENT_BORDER,	EVENT_BUTTON,
	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,
	EVENT_TIME,	EVENT_WARP,	EVENT_WIDTH,	EVENT_WINDOW,
	EVENT_X,	EVENT_Y
    };

    assert(mainWin);

    windowName = Tcl_GetString(objv[0]);
    if (!windowName[0]) {
	tkwin = mainWin;
    } else if (!NameToWindow(interp, mainWin, objv[0], &tkwin)) {
	return TCL_ERROR;
    }

    mainPtr = (TkWindow *) mainWin;

    if (!tkwin || mainPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window id \"%s\" doesn't exist in this application",
		Tcl_GetString(objv[0])));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", Tcl_GetString(objv[0]), NULL);
	return TCL_ERROR;
    }

    name = Tcl_GetString(objv[1]);

    p = name;
    eventMask = 0;
    userDataObj = NULL;
    if ((count = ParseEventDescription(interp, &p, &pat, &eventMask)) == 0) {

	return TCL_ERROR;
    }
    if (count != 1u) {
	Tcl_SetObjResult(interp,
		Tcl_NewStringObj("Double, Triple, or Quadruple modifier not allowed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_MODIFIER", NULL);

	return TCL_ERROR;
    }
    if (*p) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("only one event specification allowed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "MULTIPLE", NULL);

	return TCL_ERROR;
    }

    memset(&event, 0, sizeof(event));
    event.general.xany.type = pat.eventType;
    event.general.xany.serial = NextRequest(Tk_Display(tkwin));
    event.general.xany.send_event = 0;
    if (windowName[0]) {
	event.general.xany.window = Tk_WindowId(tkwin);
    } else {

	event.general.xany.window = RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
    }
    event.general.xany.display = Tk_Display(tkwin);

    flags = flagArray[event.general.xany.type];
    if (flags & DESTROY) {
	/*
	 * Event DestroyNotify should be generated by destroying the window.
	 */

	Tk_DestroyWindow(tkwin);
	return TCL_OK;
    }
    if (flags & HAS_XKEY_HEAD_AND_STATE) {
	event.general.xkey.state = pat.modMask;
	if (flags & KEY) {
	    TkpSetKeycodeAndState(tkwin, pat.info, &event.general);
	} else if (flags & BUTTON) {
	    event.general.xbutton.button = pat.info;
	} else if (flags & VIRTUAL) {
	    event.virt.name = pat.name;
	}
    }
    if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) {
	event.general.xcreatewindow.window = event.general.xany.window;
    }

    if (flags & HAS_XKEY_HEAD) {
	event.general.xkey.x_root = -1;
	event.general.xkey.y_root = -1;
    }

    if (event.general.xany.type == FocusIn || event.general.xany.type == FocusOut) {
	event.general.xany.send_event = GENERATED_FOCUS_EVENT_MAGIC;
    }

    /*
     * Process the remaining arguments to fill in additional fields of the event.

     */

    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < (unsigned) objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;
	int badOpt = 0;
	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (IsOdd(objc)) {
	    /*
	     * 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_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "EVENT", "MISSING_VALUE", NULL);
	    return TCL_ERROR;
	}

	switch ((enum field) index) {
	case EVENT_WARP:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (!(flags & CAN_WARP)) {
		badOpt = 1;
	    }
	    break;
	case EVENT_WHEN:
	    pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, queuePosition, valuePtr);

	    if ((int) pos < -1) {
		return TCL_ERROR;
	    }

	    synch = ((int) pos == -1);


	    break;
	case EVENT_ABOVE:
	    if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) {
		return TCL_ERROR;
	    }
	    if (flags & CONFIG) {
		event.general.xconfigure.above = Tk_WindowId(tkwin2);
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_BORDER:
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & (CREATE|CONFIG)) {
		event.general.xcreatewindow.border_width = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_BUTTON:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & BUTTON) {
		if (number >= Button4) {
		    number += (Button8 - Button4);
		}
		event.general.xbutton.button = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_COUNT:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & EXPOSE) {
		event.general.xexpose.count = number;
	    } else {
		badOpt = 1;
	    }
	    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.
		 */

		userDataObj = valuePtr;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_DELTA:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & WHEEL) {
		event.general.xbutton.button = (unsigned)number; /* mis-use button field for this */
	    } else {
		badOpt = 1;
	    }
	    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 {
		badOpt = 1;
	    }
	    break;
	case EVENT_FOCUS:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & CROSSING) {
		event.general.xcrossing.focus = number;
	    } else {
		badOpt = 1;
	    }
	    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 {
		badOpt = 1;
	    }
	    break;
	case EVENT_KEYCODE:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & KEY) {
		event.general.xkey.keycode = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_KEYSYM: {
	    KeySym keysym;
	    const char *value;

	    value = Tcl_GetString(valuePtr);
	    keysym = TkStringToKeysym(value);
	    if (keysym == NoSymbol) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf("unknown keysym \"%s\"", value));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYSYM", value, NULL);
		return TCL_ERROR;
	    }

	    TkpSetKeycodeAndState(tkwin, keysym, &event.general);
	    if (event.general.xkey.keycode == 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf("no keycode for keysym \"%s\"", value));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYCODE", value, NULL);
		return TCL_ERROR;
	    }
	    if (!(flags & KEY)) {

		badOpt = 1;
	    }
	    break;
	}
	case EVENT_MODE:
	    if ((number = TkFindStateNumObj(interp, optionPtr, notifyMode, valuePtr)) < 0) {

		return TCL_ERROR;
	    }
	    if (flags & CROSSING) {
		event.general.xcrossing.mode = number;
	    } else if (flags & FOCUS) {
		event.general.xfocus.mode = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_OVERRIDE:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    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 {
		badOpt = 1;
	    }
	    break;
	case EVENT_PLACE:
	    if ((number = TkFindStateNumObj(interp, optionPtr, circPlace, valuePtr)) < 0) {

		return TCL_ERROR;
	    }
	    if (flags & CIRC) {
		event.general.xcirculate.place = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_ROOT:
	    if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.root = Tk_WindowId(tkwin2);
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_ROOTX:
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.x_root = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_ROOTY:
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.y_root = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_SEND: {
	    const char *value;

	    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;
		}
		if (number) {
		    /*
		     * send_event only expects 1 or 0. We cannot allow arbitrary non-zero
		     * values, otherwise the thing with GENERATED_FOCUS_EVENT_MAGIC will not
		     * work.
		     */
		    number = 1;
		}
	    } else if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }

	    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 & HAS_XKEY_HEAD) {
		if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (flags & HAS_XKEY_HEAD_AND_STATE) {
		    event.general.xkey.state = number;
		} else {
		    event.general.xcrossing.state = number;
		}
	    } else if (flags & VISIBILITY) {
		if ((number = TkFindStateNumObj(interp, optionPtr, visNotify, valuePtr)) < 0) {


		    return TCL_ERROR;
		}
		event.general.xvisibility.state = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_SUBWINDOW:
	    if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.subwindow = Tk_WindowId(tkwin2);
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_TIME: {
	    if (strcmp(Tcl_GetString(valuePtr), "current") == 0) {
		TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
		BindInfo *biPtr = mainPtr->mainPtr->bindInfo;
		number = dispPtr->lastEventTime + (CurrentTimeInMilliSecs() - biPtr->lastCurrentTime);
	    } else if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.time = number;
	    } else if (flags & PROP) {
		event.general.xproperty.time = number;
	    } else {
		badOpt = 1;
	    }
	    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 {
		badOpt = 1;
	    }
	    break;
	case EVENT_WINDOW:
	    if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) {
		return TCL_ERROR;
	    }
	    if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) {
		event.general.xcreatewindow.window = Tk_WindowId(tkwin2);
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_X:
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.x = number;

		/*
		 * 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;
		}
	    } 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 {
		badOpt = 1;
	    }
	    break;
	case EVENT_Y:
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & HAS_XKEY_HEAD) {
		event.general.xkey.y = number;

		/*
		 * 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;
		}
	    } 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 {
		badOpt = 1;
	    }
	    break;
	}


    	if (badOpt) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s event doesn't accept \"%s\" option", name, Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_OPTION", NULL);
	    return TCL_ERROR;
	}
    }

    /*
     * Don't generate events for windows that don't exist yet.
     */


    if (event.general.xany.window) {
	if (userDataObj) {
	    /*
	     * 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.
	     */

	    event.virt.user_data = userDataObj;
	    Tcl_IncrRefCount(userDataObj);
	}

	/*
	 * We only allow warping if the window is mapped.
	 */

	if (warp && Tk_IsMapped(tkwin)) {
	    TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);

	    Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window);

	    if (warpWindow != dispPtr->warpWindow) {
		if (warpWindow) {
		    Tcl_Preserve(warpWindow);
		}
		if (dispPtr->warpWindow) {
		    Tcl_Release(dispPtr->warpWindow);
		}
		dispPtr->warpWindow = warpWindow;
	    }
	    dispPtr->warpMainwin = mainWin;
	    dispPtr->warpX = event.general.xmotion.x;
	    dispPtr->warpY = event.general.xmotion.y;

            /*
             * Warping with respect to a window will be done when Tk_handleEvent
             * below will run the event handlers and in particular TkPointerEvent.
             * This allows to make grabs and warping work together robustly, that
             * is without depending on a precise sequence of events.
             * Warping with respect to the whole screen (i.e. dispPtr->warpWindow
             * is NULL) is run directly here.
             */

            if (!dispPtr->warpWindow) {
                TkpWarpPointer(dispPtr);
                XForceScreenSaver(dispPtr->display, ScreenSaverReset);
            }
	}

	/*
	 * Now we have constructed the event, inject it into the event handling
	 * code.
	 */

	if (synch) {
	    Tk_HandleEvent(&event.general);
	} else {
	    Tk_QueueWindowEvent(&event.general, pos);
	}
    }















    Tcl_ResetResult(interp);
    return TCL_OK;
}
/*
 *---------------------------------------------------------------------------
 *
 * NameToWindow --
 *
 *	Helper function for lookup of a window given its path name. Our
 *	version is able to handle window id's.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
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. */
{
    const char *name;
    Tk_Window tkwin;

    assert(mainWin);
    assert(objPtr);
    assert(tkwinPtr);

    name = Tcl_GetString(objPtr);

    if (name[0] == '.') {
	if (!(tkwin = Tk_NameToWindow(interp, name, mainWin))) {

	    return 0;
	}

    } else {
	Window id;

	tkwin = NULL;

	/*
	 * Check for the winPtr being valid, even if it looks okay to
	 * TkpScanWindowId. [Bug #411307]
	 */

	if (TkpScanWindowId(NULL, name, &id) == TCL_OK) {
	    tkwin = Tk_IdToWindow(Tk_Display(mainWin), id);
	}

	if (!tkwin) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad window name/identifier \"%s\"", name));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW_ID", name, NULL);
	    return 0;
	}
    }

    assert(tkwin);
    *tkwinPtr = tkwin;
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
 * TkDoWarpWrtWin --
 *
 *	Perform warping of mouse pointer with respect to a window.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Mouse pointer moves to a new location.
 *
 *-------------------------------------------------------------------------
 */

void
TkDoWarpWrtWin(
    TkDisplay *dispPtr)
{
    assert(dispPtr);

    /*
     * A NULL warpWindow means warping with respect to the whole screen.
     * We want to warp here only if we're warping with respect to a window.
     */

    if (dispPtr->warpWindow) {

        /*
         * Warping with respect to a window can only be done if the window is
         * mapped. This was checked in HandleEvent. The window needs to be
         * still mapped at the time the present code is executed. Also
         * one needs to guard against window destruction in the meantime,
         * which could have happened as a side effect of an event handler.
         */

        if (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None) {
            TkpWarpPointer(dispPtr);

            XForceScreenSaver(dispPtr->display, ScreenSaverReset);
        }
        Tcl_Release(dispPtr->warpWindow);
        dispPtr->warpWindow = NULL;
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *







|













|
<

|
<
>


|
<

|

<
<
<
<
<
<
<
|







|












<
<



|




>
|
|
|
<
<




>



|
>


|
|
<
<
>


|
|
<
>



|


|



>
|








>



|
|
|
|

|

|






|




<
<
<
<

|
>





<
|

<





|
|


|







|
|
<








|
|



|
>



>
|
>
>


|





|



|





|







<
<
<


|









|









>


|






|
|

|



|
>








|









|



|
>







|






|


|




|




|
|





|
|


|
>
|




|
>







|















|



|
>





|



|


|


|



|


|


|



|


|


|











>



<
<
<
<
<
<
<
|
|
|
|
>
|









|



|





|
>
>




|



|


|


|


|
<
<
<
<
|


|
|

|

|


<

|







|



|





|



|


|



















|



|


|



















|



>

|
|
|
<
|
|
<
|
<
<
<
>

<
<
|
|
|
|
|
|
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
|
|
|

|
|
|
|
|
|
>
>
>

>
>
>
>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|

|
<
<
<


<

|
>
|

>

<
<
<
<

|



|
|
<
|
<
|
|
|


<
<
<
|





|

|





|



<
|
|
<
<
<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
<

<
|
>
|
<
<
|
<







3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257

3258
3259

3260
3261
3262
3263

3264
3265
3266







3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287


3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299


3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313


3314
3315
3316
3317
3318

3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362




3363
3364
3365
3366
3367
3368
3369
3370

3371
3372

3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391

3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439



3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631







3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677




3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688

3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770

3771
3772

3773



3774
3775


3776
3777
3778
3779
3780
3781
3782
3783
3784





































3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
















3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826



3827
3828

3829
3830
3831
3832
3833
3834
3835




3836
3837
3838
3839
3840
3841
3842

3843

3844
3845
3846
3847
3848



3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866

3867
3868



3869




3870

3871







3872

3873
3874
3875


3876

3877
3878
3879
3880
3881
3882
3883
 *	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.
 *
 *---------------------------------------------------------------------------
 */

static int
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. */
{
    union {XEvent general; XVirtualEvent virtual;} event;

    const char *p;
    char *name, *windowName;

    int count, flags, synch, i, number, warp;
    Tcl_QueuePosition pos;
    TkPattern pat;
    Tk_Window tkwin, tkwin2;

    TkWindow *mainPtr;
    unsigned long eventMask;
    Tcl_Obj *userDataObj;







    static const char *fieldStrings[] = {
	"-when",	"-above",	"-borderwidth",	"-button",
	"-count",	"-data",	"-delta",	"-detail",
	"-focus",	"-height",
	"-keycode",	"-keysym",	"-mode",	"-override",
	"-place",	"-root",	"-rootx",	"-rooty",
	"-sendevent",	"-serial",	"-state",	"-subwindow",
	"-time",	"-warp",	"-width",	"-window",
	"-x",		"-y",	NULL
    };
    enum field {
	EVENT_WHEN,	EVENT_ABOVE,	EVENT_BORDER,	EVENT_BUTTON,
	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,
	EVENT_TIME,	EVENT_WARP,	EVENT_WIDTH,	EVENT_WINDOW,
	EVENT_X,	EVENT_Y
    };



    windowName = Tcl_GetString(objv[0]);
    if (!windowName[0]) {
	tkwin = mainWin;
    } else if (NameToWindow(interp, mainWin, objv[0], &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }

    mainPtr = (TkWindow *) mainWin;
    if ((tkwin == NULL)
	    || (mainPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) {
	Tcl_AppendResult(interp, "window id \"", Tcl_GetString(objv[0]),
		"\" doesn't exist in this application", NULL);


	return TCL_ERROR;
    }

    name = Tcl_GetString(objv[1]);

    p = name;
    eventMask = 0;
    userDataObj = NULL;
    count = ParseEventDescription(interp, &p, &pat, &eventMask);
    if (count == 0) {
	return TCL_ERROR;
    }
    if (count != 1) {
	Tcl_SetResult(interp, "Double or Triple modifier not allowed",


		TCL_STATIC);
	return TCL_ERROR;
    }
    if (*p != '\0') {
	Tcl_SetResult(interp, "only one event specification allowed",

		TCL_STATIC);
	return TCL_ERROR;
    }

    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.general.xany.window = Tk_WindowId(tkwin);
    } else {
	event.general.xany.window =
		RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
    }
    event.general.xany.display = Tk_Display(tkwin);

    flags = flagArray[event.general.xany.type];
    if (flags & DESTROY) {
	/*
	 * Event DestroyNotify should be generated by destroying the window.
	 */

	Tk_DestroyWindow(tkwin);
	return TCL_OK;
    }
    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.general.xbutton.button = pat.detail.button;
	} else if (flags & VIRTUAL) {
	    event.virtual.name = pat.detail.name;
	}
    }
    if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) {
	event.general.xcreatewindow.window = event.general.xany.window;
    }

    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.
     */

    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;

	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fieldStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc & 1) {
	    /*
	     * This test occurs after Tcl_GetIndexFromObj() so that "event
	     * generate <Button> -xyz" will return the error message that
	     * "-xyz" is a bad option, rather than that the value for "-xyz"
	     * is missing.
	     */

	    Tcl_AppendResult(interp, "value for \"", Tcl_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_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;
	case EVENT_ABOVE:
	    if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & CONFIG) {
		event.general.xconfigure.above = Tk_WindowId(tkwin2);
	    } else {
		goto badopt;
	    }
	    break;
	case EVENT_BORDER:
	    if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & (CREATE|CONFIG)) {
		event.general.xcreatewindow.border_width = number;
	    } else {
		goto badopt;
	    }
	    break;
	case EVENT_BUTTON:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & BUTTON) {



		event.general.xbutton.button = number;
	    } else {
		goto badopt;
	    }
	    break;
	case EVENT_COUNT:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    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.
		 */

		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.general);
	    if (event.general.xkey.keycode == 0) {
		Tcl_AppendResult(interp, "no keycode for keysym \"", value,
			"\"", NULL);
		return TCL_ERROR;
	    }
	    if (!(flags & KEY)
		    || (event.general.xkey.type == MouseWheelEvent)) {
		goto badopt;
	    }
	    break;
	}
	case EVENT_MODE:
	    number = TkFindStateNumObj(interp,optionPtr,notifyMode,valuePtr);
	    if (number < 0) {
		return TCL_ERROR;
	    }
	    if (flags & CROSSING) {
		event.general.xcrossing.mode = number;
	    } else if (flags & FOCUS) {
		event.general.xfocus.mode = number;
	    } else {
		goto badopt;
	    }
	    break;
	case EVENT_OVERRIDE:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    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;
	    }
	    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;
	    }
	    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_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.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) {
		    event.general.xkey.state = number;
		} else {
		    event.general.xcrossing.state = number;
		}
	    } else if (flags & VISIBILITY) {
		number = TkFindStateNumObj(interp, optionPtr, visNotify,
			valuePtr);
		if (number < 0) {
		    return TCL_ERROR;
		}
		event.general.xvisibility.state = number;
	    } else {
		goto badopt;
	    }
	    break;
	case EVENT_SUBWINDOW:
	    if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
		return TCL_ERROR;
	    }
	    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;

		/*
		 * 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;
		}
	    } 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;
	    }
	    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;

		/*
		 * 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;
		}
	    } 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:
	Tcl_AppendResult(interp, name, " event doesn't accept \"",
		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.general);
    } else {
	Tk_QueueWindowEvent(&event.general, pos);
    }

    /*
     * We only allow warping if the window is mapped.
     */

    if ((warp != 0) && Tk_IsMapped(tkwin)) {
	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.general.xany.window;
	dispPtr->warpX = event.general.xkey.x;
	dispPtr->warpY = event.general.xkey.y;
    }
    Tcl_ResetResult(interp);
    return TCL_OK;
}

















static int
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_GetString(objPtr);

    if (name[0] == '.') {
	tkwin = Tk_NameToWindow(interp, name, mainWin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	*tkwinPtr = tkwin;
    } else {




	/*
	 * Check for the winPtr being valid, even if it looks ok to
	 * 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, "\"", NULL);
	    return TCL_ERROR;
	}
    }



    return TCL_OK;
}

/*
 *-------------------------------------------------------------------------
 *
 * DoWarp --
 *
 *	Perform Warping of X pointer. Executed as an idle handler only.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	X Pointer will move to a new location.
 *
 *-------------------------------------------------------------------------
 */

static void
DoWarp(



    ClientData clientData)




{

    TkDisplay *dispPtr = (TkDisplay *) clientData;









    XWarpPointer(dispPtr->display, None, (Window) dispPtr->warpWindow,
	    0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY);
    XForceScreenSaver(dispPtr->display, ScreenSaverReset);


    dispPtr->flags &= ~TK_DISPLAY_IN_WARP;

}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
GetVirtualEventUid(
    Tcl_Interp *interp,
    char *virtString)
{
    Tk_Uid uid;
    size_t length;

    assert(virtString);

    length = strlen(virtString);

    if (length < 5
	    || virtString[0] != '<'
	    || virtString[1] != '<'
	    || virtString[length - 2] != '>'
	    || virtString[length - 1] != '>') {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("virtual event \"%s\" is badly formed", virtString));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "MALFORMED", NULL);
	return NULL;
    }
    virtString[length - 2] = '\0';
    uid = Tk_GetUid(virtString + 2);
    virtString[length - 2] = '>';

    return uid;







<
<


|
<
<
|
|
|
<







3900
3901
3902
3903
3904
3905
3906


3907
3908
3909


3910
3911
3912

3913
3914
3915
3916
3917
3918
3919
GetVirtualEventUid(
    Tcl_Interp *interp,
    char *virtString)
{
    Tk_Uid uid;
    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", NULL);

	return NULL;
    }
    virtString[length - 2] = '\0';
    uid = Tk_GetUid(virtString + 2);
    virtString[length - 2] = '>';

    return uid;
4628
4629
4630
4631
4632
4633
4634

4635
4636

4637
4638
4639
4640

4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655

4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669


4670
4671
4672
4673
4674
4675
4676
4677
4678



4679


4680

4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698

4699

4700





4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729

4730

4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744

4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779

4780

4781
4782
4783
4784
4785
4786
4787
4788
4789
 *
 *----------------------------------------------------------------------
 */

static PatSeq *
FindSequence(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */

    LookupTables *lookupTables,	/* Tables used 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.

    				 * 1 means create. */
    int allowVirtual,		/* 0 means that virtual events are not allowed in the sequence.
    				 * 1 otherwise. */
    unsigned *maskPtr)		/* *maskPtr is filled in with the event types on which this
    				 * pattern sequence depends. */
{
    unsigned patsBufSize = 1;
    unsigned numPats;
    unsigned totalCount = 0;
    int virtualFound = 0;
    const char *p = eventString;
    TkPattern *patPtr;
    PatSeq *psPtr;
    Tcl_HashEntry *hPtr;
    int isNew;

    unsigned count;
    unsigned maxCount = 0;
    unsigned eventMask = 0;
    unsigned modMask = 0;
    PatternTableKey key;

    assert(lookupTables);
    assert(eventString);

    psPtr = (PatSeq *)ckalloc(PATSEQ_MEMSIZE(patsBufSize));

    /*
     *------------------------------------------------------------------
     * Step 1: parse the pattern string to produce an array of Patterns.


     *------------------------------------------------------------------
     */

    for (patPtr = psPtr->pats, numPats = 0; *(p = SkipSpaces(p)); ++patPtr, ++numPats) {
	if (numPats >= patsBufSize) {
	    unsigned pos = patPtr - psPtr->pats;
	    patsBufSize += patsBufSize;
	    psPtr = (PatSeq *)ckrealloc(psPtr, PATSEQ_MEMSIZE(patsBufSize));
	    patPtr = psPtr->pats + pos;



	}




	if ((count = ParseEventDescription(interp, &p, patPtr, &eventMask)) == 0) {
	    /* error encountered */
	    ckfree(psPtr);
	    return NULL;
	}

	if (eventMask & VirtualEventMask) {
	    if (!allowVirtual) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"virtual event not allowed in definition of another virtual event", -1));
		Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "INNER", NULL);
		ckfree(psPtr);
		return NULL;
	    }
	    virtualFound = 1;
	}

	if (count > 1u) {

	    maxCount = Max(count, maxCount);

	}






	totalCount += count;
	modMask |= patPtr->modMask;
    }

    /*
     *------------------------------------------------------------------
     * Step 2: find the sequence in the binding table if it exists, and
     * add a new sequence to the table if it doesn't.
     *------------------------------------------------------------------
     */

    if (numPats == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("no events specified in binding", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "NO_EVENTS", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (numPats > 1u && virtualFound) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("virtual events may not be composed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "COMPOSITION", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (patsBufSize > numPats) {
	psPtr = (PatSeq *)ckrealloc(psPtr, PATSEQ_MEMSIZE(numPats));
    }

    patPtr = psPtr->pats;

    psPtr->object = (Tcl_Obj *)object;

    SetupPatternKey(&key, psPtr);
    hPtr = Tcl_CreateHashEntry(&lookupTables->patternTable, (char *) &key, &isNew);
    if (!isNew) {
	unsigned sequenceSize = numPats*sizeof(TkPattern);
	PatSeq *psPtr2;

	for (psPtr2 = (PatSeq *)Tcl_GetHashValue(hPtr); psPtr2; psPtr2 = psPtr2->nextSeqPtr) {
	    assert(TEST_PSENTRY(psPtr2));
	    if (numPats == psPtr2->numPats && memcmp(patPtr, psPtr2->pats, sequenceSize) == 0) {
		ckfree(psPtr);
		if (maskPtr) {
		    *maskPtr = eventMask;
		}
		return psPtr2;

	    }
	}
    }
    if (!create) {
	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.
	 */

	ckfree(psPtr);
	return NULL;
    }

    DEBUG(countSeqItems += 1;)

    psPtr->numPats = numPats;
    psPtr->count = totalCount;
    psPtr->number = lookupTables->number++;
    psPtr->added = 0;
    psPtr->modMaskUsed = (modMask != 0);
    psPtr->script = NULL;
    psPtr->nextSeqPtr = (PatSeq *)Tcl_GetHashValue(hPtr);
    psPtr->hPtr = hPtr;
    psPtr->ptr.nextObj = NULL;
    assert(psPtr->ptr.owners == NULL);
    DEBUG(psPtr->owned = 0;)
    Tcl_SetHashValue(hPtr, psPtr);


    if (maskPtr) {

	*maskPtr = eventMask;
    }
    return psPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * ParseEventDescription --







>
|
|
>
|
|
|
|
>
|
|
|
|
|

|
<
<
|
|



|
>
|
<
<
<


<
<
<
<
<

|
|
>
>
|


|
|
|
|
|
|
>
>
>

>
>
|
>
|
|
<




|
|
|
<
|





<
>
|
>
|
>
>
>
>
>
|
<
<



|
|
|
|



|
<
<


|
|
<
|


<
<
|
|
<
>
|
>
|
|
<
|
<
|
|
|
|
|
|
|
<
<
>
















<


|
<
|

|
|
|
|
|
|

|
<
|


>
|
>
|
<







3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964


3965
3966
3967
3968
3969
3970
3971
3972



3973
3974





3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998

3999
4000
4001
4002
4003
4004
4005

4006
4007
4008
4009
4010
4011

4012
4013
4014
4015
4016
4017
4018
4019
4020
4021


4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032


4033
4034
4035
4036

4037
4038
4039


4040
4041

4042
4043
4044
4045
4046

4047

4048
4049
4050
4051
4052
4053
4054


4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071

4072
4073
4074

4075
4076
4077
4078
4079
4080
4081
4082
4083
4084

4085
4086
4087
4088
4089
4090
4091

4092
4093
4094
4095
4096
4097
4098
 *
 *----------------------------------------------------------------------
 */

static PatSeq *
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. */
{
    TkPattern pats[EVENT_BUFFER_SIZE];


    int numPats, virtualFound;
    const char *p;
    TkPattern *patPtr;
    PatSeq *psPtr;
    Tcl_HashEntry *hPtr;
    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.
     *-------------------------------------------------------------
     */

    p = eventString;
    flags = 0;
    eventMask = 0;
    virtualFound = 0;

    patPtr = &pats[EVENT_BUFFER_SIZE-1];
    for (numPats = 0; numPats < EVENT_BUFFER_SIZE; numPats++, patPtr--) {
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	if (*p == '\0') {
	    break;
	}

	count = ParseEventDescription(interp, &p, patPtr, &eventMask);
	if (count == 0) {

	    return NULL;
	}

	if (eventMask & VirtualEventMask) {
	    if (allowVirtual == 0) {
		Tcl_SetResult(interp,
			"virtual event not allowed in definition of another virtual event",

			TCL_STATIC);
		return NULL;
	    }
	    virtualFound = 1;
	}


	/*
	 * Replicate events for DOUBLE, TRIPLE, QUADRUPLE.
	 */

	while ((count-- > 1) && (numPats < EVENT_BUFFER_SIZE-1)) {
	    flags |= PAT_NEARBY;
	    patPtr[-1] = patPtr[0];
	    patPtr--;
	    numPats++;
	}


    }

    /*
     *-------------------------------------------------------------
     * Step 2: find the sequence in the binding table if it exists, and add a
     * new sequence to the table if it doesn't.
     *-------------------------------------------------------------
     */

    if (numPats == 0) {
	Tcl_SetResult(interp, "no events specified in binding", TCL_STATIC);


	return NULL;
    }
    if ((numPats > 1) && (virtualFound != 0)) {
	Tcl_SetResult(interp, "virtual events may not be composed",

		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, &isNew);

    sequenceSize = numPats*sizeof(TkPattern);

    if (!isNew) {
	for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
		psPtr = psPtr->nextSeqPtr) {
	    if ((numPats == psPtr->numPats)
		    && ((flags & PAT_NEARBY) == (psPtr->flags & PAT_NEARBY))
		    && (memcmp((char *) patPtr, (char *) psPtr->pats,
		    sequenceSize) == 0)) {


		goto done;
	    }
	}
    }
    if (!create) {
	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.
	 */


	return NULL;
    }
    psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq)

	    + (numPats-1)*sizeof(TkPattern)));
    psPtr->numPats = numPats;
    psPtr->eventProc = NULL;
    psPtr->freeProc = NULL;
    psPtr->clientData = NULL;
    psPtr->flags = flags;
    psPtr->refCount = 0;
    psPtr->nextSeqPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
    psPtr->hPtr = hPtr;
    psPtr->voPtr = NULL;

    psPtr->nextObjPtr = NULL;
    Tcl_SetHashValue(hPtr, psPtr);

    memcpy((void *) psPtr->pats, (void *) patPtr, sequenceSize);

  done:
    *maskPtr = eventMask;

    return psPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * ParseEventDescription --
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830

4831
4832

4833
4834
4835
4836
4837




4838

4839
4840
4841


4842
4843
4844

4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861

4862
4863



4864
4865
4866
4867


4868
4869
4870

4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884

4885
4886
4887
4888
4889
4890
4891

4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904



4905
4906
4907


4908



4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930

4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944

4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957


4958
4959

4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984

4985


4986
4987
4988
4989
4990
4991
4992
4993
4994
4995


4996
4997
4998







4999

5000
5001
5002
5003
5004


5005
5006


5007
5008
5009
5010
5011
5012
5013

5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036

5037
5038
5039


5040
5041
5042
5043
5044
5045
5046
5047
5048
5049


5050
5051
5052
5053
5054
5055


5056
5057
5058
5059
5060
5061
5062


5063
5064
5065
5066
5067
5068
5069
5070
 *	On exit, eventStringPtr points to rest of event string (after the
 *	closing '>', so that this function can be called repeatedly to parse
 *	all the events in the entire sequence.
 *
 *---------------------------------------------------------------------------
 */

/* helper function */
static unsigned
FinalizeParseEventDescription(
    Tcl_Interp *interp,
    TkPattern *patPtr,
    unsigned count,
    Tcl_Obj* errorObj,
    const char* errCode)
{
    assert(patPtr);
    assert(!errorObj == (count > 0));

    if (errorObj) {
	Tcl_SetObjResult(interp, errorObj);
	Tcl_SetErrorCode(interp, "TK", "EVENT", errCode, NULL);
    }
    patPtr->count = count;
    return count;
}

static unsigned
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. */
    TkPattern *patPtr,		/* Filled with the pattern parsed from the event string. */

    unsigned *eventMaskPtr)	/* Filled with event mask of matched event. */
{
    const char *p;
    unsigned eventMask = 0;
    unsigned count = 1;






    assert(eventStringPtr);
    assert(patPtr);
    assert(eventMaskPtr);



    p = *eventStringPtr;
    memset(patPtr, 0, sizeof(TkPattern)); /* otherwise memcmp doesn't work */


    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];

	patPtr->eventType = KeyPress;
	eventMask = KeyPressMask;
	string[0] = *p;
	string[1] = '\0';
	patPtr->info = TkStringToKeysym(string);
	if (patPtr->info == NoSymbol) {
	    if (!isprint(UCHAR(*p))) {
		return FinalizeParseEventDescription(
			interp,

			patPtr, 0,
			Tcl_ObjPrintf("bad ASCII character 0x%x", UCHAR(*p)), "BAD_CHAR");



	    }
	    patPtr->info = *p;
	}
	++p;


    } else {
	/*
	 * A fancier event description. This can be either a virtual event or a physical event.

	 *
	 * A virtual event description consists of:
	 *
	 * 1. double open angle brackets.
	 * 2. virtual event name.
	 * 3. double close angle brackets.
	 *
	 * A physical event description consists of:
	 *
	 * 1. open angle bracket.
	 * 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.

	 * 5. a close angle bracket.
	 */

	++p;
	if (*p == '<') {
	    /*
	     * This is a virtual event: soak up all the characters up to the next '>'.

	     */

	    const char *field = p + 1;
	    char buf[256];
	    char* bufPtr = buf;
	    unsigned size;

	    p = strchr(field, '>');
	    if (p == field) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("virtual event \"<<>>\" is badly formed", -1), "MALFORMED");



	    }
	    if (!p || p[1] != '>') {
		return FinalizeParseEventDescription(


			interp,



			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in virtual binding", -1), "MALFORMED");
	    }

	    size = p - field;
	    if (size >= sizeof(buf)) {
		bufPtr = (char *)ckalloc(size + 1);
	    }
	    strncpy(bufPtr, field, size);
	    bufPtr[size] = '\0';
	    eventMask = VirtualEventMask;
	    patPtr->eventType = VirtualEvent;
	    patPtr->name = Tk_GetUid(bufPtr);
	    if (bufPtr != buf) {
		ckfree(bufPtr);
	    }
	    p += 2;
	} else {
	    unsigned eventFlags;
	    char field[512];
	    Tcl_HashEntry *hPtr;


	    while (1) {
		ModInfo *modPtr;

		p = GetField(p, field, sizeof(field));
		if (*p == '>') {
		    /*
		     * This solves the problem of, e.g., <Control-M> being
		     * misinterpreted as Control + Meta + missing keysym instead of
		     * Control + KeyPress + M.
		     */

		     break;
		}
		if (!(hPtr = Tcl_FindHashEntry(&modTable, field))) {

		    break;
		}
		modPtr = (ModInfo *)Tcl_GetHashValue(hPtr);
		patPtr->modMask |= modPtr->mask;
		if (modPtr->flags & MULT_CLICKS) {
		    unsigned i = modPtr->flags & MULT_CLICKS;

		    count = 2;
		    while (i >>= 1) {
			++count;
		    }
		}
		p = SkipFieldDelims(p);


	    }


	    eventFlags = 0;
	    if ((hPtr = Tcl_FindHashEntry(&eventTable, field))) {
		const EventInfo *eiPtr = (const EventInfo *)Tcl_GetHashValue(hPtr);

		patPtr->eventType = eiPtr->type;
		eventFlags = flagArray[eiPtr->type];
		eventMask = eiPtr->eventMask;
		p = GetField(SkipFieldDelims(p), field, sizeof(field));
	    }
	    if (*field) {
		unsigned button = GetButtonNumber(field);

		if ((eventFlags & BUTTON)
			|| (button && eventFlags == 0)
			|| (SUPPORT_ADDITIONAL_MOTION_SYNTAX && (eventFlags & MOTION) && button == 0)) {
		    /* This must be a button (or bad motion) event */
		    if (button == 0) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
		    }
		    patPtr->info = button;
		    if (!(eventFlags & BUTTON)) {
			patPtr->eventType = ButtonPress;

			eventMask = ButtonPressMask;


		    }
		} else if ((eventFlags & KEY) || eventFlags == 0) {
		    /* This must be a key event */
		    patPtr->info = TkStringToKeysym(field);
		    if (patPtr->info == NoSymbol) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("bad event type or keysym \"%s\"", field), "KEYSYM");
		    }


		    if (!(eventFlags & KEY)) {
			patPtr->eventType = KeyPress;
			eventMask = KeyPressMask;







		    }

		} else if (button) {
		    if (!SUPPORT_ADDITIONAL_MOTION_SYNTAX || patPtr->eventType != MotionNotify) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,


				Tcl_ObjPrintf("specified button \"%s\" for non-button event", field),
				"NON_BUTTON");


		    }
#if SUPPORT_ADDITIONAL_MOTION_SYNTAX
		    patPtr->modMask |= Tk_GetButtonMask(button);
		    p = SkipFieldDelims(p);
		    while (*p && *p != '>') {
			p = SkipFieldDelims(GetField(p, field, sizeof(field)));
			if ((button = GetButtonNumber(field)) == 0) {

			    return FinalizeParseEventDescription(
				    interp,
				    patPtr, 0,
				    Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
			}
			patPtr->modMask |= Tk_GetButtonMask(button);
		    }
		    patPtr->info = ButtonNumberFromState(patPtr->modMask);
#endif
		} else {
		    return FinalizeParseEventDescription(
			    interp,
			    patPtr, 0,
			    Tcl_ObjPrintf("specified keysym \"%s\" for non-key event", field),
			    "NON_KEY");
		}
	    } else if (eventFlags == 0) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("no event type or button # or keysym", -1), "UNMODIFIABLE");
	    } else if (patPtr->eventType == MotionNotify) {
		patPtr->info = ButtonNumberFromState(patPtr->modMask);

	    }

	    p = SkipFieldDelims(p);



	    if (*p != '>') {
		while (*p) {
		    ++p;
		    if (*p == '>') {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_NewStringObj("extra characters after detail in binding", -1),
				"PAST_DETAIL");


		    }
		}
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in binding", -1), "MALFORMED");


	    }
	    ++p;
	}
    }

    *eventStringPtr = p;
    *eventMaskPtr |= eventMask;


    return FinalizeParseEventDescription(interp, patPtr, count, NULL, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * GetField --
 *







<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
>
|
|
>
|

|
|
|
>
>
>
>

>
|
|
|
>
>

|
<
>











|
|
|
|
|
|
>
|
|
>
>
>

<

|
>
>
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|

|
|
|
|
>
|

|
<
<
<

|
|
<
<
<
|
>
>
>
|
|
<
>
>
|
>
>
>
|
<
<
<
<
<
<
<
<
<
|
<
|
|
<
|
|
|
<
<
<
|
>
|
|

|
|
|
|
|
|
|

|
|
|
>
|
|
|
|
|
|

|
|
|
|
|
<
>
>
|
|
>
|
|
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
>
|
>
>
|
<
<
<
<
<
<
<
|
|
>
>
|
|
|
>
>
>
>
>
>
>
|
>
|
|
<
|
|
>
>
|
<
>
>
|
|
|
|
<
<
|
>
|
|
|
<
|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
|
>
|

<
>
>
|
|
|
|
|
<
|
<
|
|
>
>
|
|
<
<
<
|
>
>
|
|
|
<
|
|

>
>
|







4109
4110
4111
4112
4113
4114
4115

4116



















4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141

4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166

4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200



4201
4202
4203



4204
4205
4206
4207
4208
4209

4210
4211
4212
4213
4214
4215
4216









4217

4218
4219

4220
4221
4222



4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251

4252
4253
4254
4255
4256
4257
4258

4259







4260









4261


4262
4263
4264
4265
4266
4267







4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285

4286
4287
4288
4289
4290

4291
4292
4293
4294
4295
4296


4297
4298
4299
4300
4301

4302

4303









4304



4305
4306
4307
4308
4309
4310

4311
4312
4313
4314
4315
4316
4317

4318

4319
4320
4321
4322
4323
4324



4325
4326
4327
4328
4329
4330

4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
 *	On exit, eventStringPtr points to rest of event string (after the
 *	closing '>', so that this function can be called repeatedly to parse
 *	all the events in the entire sequence.
 *
 *---------------------------------------------------------------------------
 */


static int



















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. */
    TkPattern *patPtr,		/* Filled with the pattern parsed from the
				 * event string. */
    unsigned long *eventMaskPtr)/* Filled with event mask of matched event. */
{
    char *p;
    unsigned long eventMask;
    int count, eventFlags;
#define FIELD_SIZE 48
    char field[FIELD_SIZE];
    Tcl_HashEntry *hPtr;
    Tcl_DString copy;

    Tcl_DStringInit(&copy);
    p = Tcl_DStringAppend(&copy, *eventStringPtr, -1);

    patPtr->eventType = -1;
    patPtr->needMods = 0;
    patPtr->detail.clientData = 0;

    eventMask = 0;

    count = 1;

    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];

	patPtr->eventType = KeyPress;
	eventMask = KeyPressMask;
	string[0] = *p;
	string[1] = 0;
	patPtr->detail.keySym = TkStringToKeysym(string);
	if (patPtr->detail.keySym == NoSymbol) {
	    if (isprint(UCHAR(*p))) {
		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;
		goto done;
	    }

	}
	p++;
	goto end;
    }

    /*
     * A fancier event description. This can be either a virtual event or a
     * physical event.
     *
     * A virtual event description consists of:
     *
     * 1. double open angle brackets.
     * 2. virtual event name.
     * 3. double close angle brackets.
     *
     * A physical event description consists of:
     *
     * 1. open angle bracket.
     * 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.
     * 5. a close angle bracket.
     */

    p++;
    if (*p == '<') {
	/*
	 * This is a virtual event: soak up all the characters up to the next
	 * '>'.
	 */

	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);
	    count = 0;
	    goto done;
	}
	*p = '\0';
	patPtr->eventType = VirtualEvent;









	eventMask = VirtualEventMask;

	patPtr->detail.name = Tk_GetUid(field);
	*p = '>';


	p += 2;
	goto end;



    }

    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.
	     */

	     break;
	}
	hPtr = Tcl_FindHashEntry(&modTable, field);
	if (hPtr == NULL) {
	    break;
	}
	modPtr = (ModInfo *) Tcl_GetHashValue(hPtr);
	patPtr->needMods |= modPtr->mask;
	if (modPtr->flags & MULT_CLICKS) {
	    int i = modPtr->flags & MULT_CLICKS;

	    count = 2;
	    while (i >>= 1) {
		count++;
	    }
	}

	while ((*p == '-') || isspace(UCHAR(*p))) {
	    p++;
	}
    }

    eventFlags = 0;
    hPtr = Tcl_FindHashEntry(&eventTable, field);

    if (hPtr != NULL) {







	EventInfo *eiPtr = (EventInfo *) Tcl_GetHashValue(hPtr);












	patPtr->eventType = eiPtr->type;
	eventFlags = flagArray[eiPtr->type];
	eventMask = eiPtr->eventMask;
	while ((*p == '-') || isspace(UCHAR(*p))) {
	    p++;
	}







	p = GetField(p, field, FIELD_SIZE);
    }
    if (*field != '\0') {
	if ((*field >= '1') && (*field <= '5') && (field[1] == '\0')) {
	    if (eventFlags == 0) {
		patPtr->eventType = ButtonPress;
		eventMask = ButtonPressMask;
	    } else if (eventFlags & KEY) {
		goto getKeysym;
	    } else if ((eventFlags & BUTTON) == 0) {
		Tcl_AppendResult(interp, "specified button \"", field,
			"\" for non-button event", NULL);
		count = 0;
		goto done;
	    }
	    patPtr->detail.button = (*field - '0');
	} else {


	getKeysym:
	    patPtr->detail.keySym = TkStringToKeysym(field);
	    if (patPtr->detail.keySym == NoSymbol) {
		Tcl_AppendResult(interp, "bad event type or keysym \"",
			field, "\"", NULL);

		count = 0;
		goto done;
	    }
	    if (eventFlags == 0) {
		patPtr->eventType = KeyPress;
		eventMask = KeyPressMask;


	    } else if ((eventFlags & KEY) == 0) {
		Tcl_AppendResult(interp, "specified keysym \"", field,
			"\" for non-key event", NULL);
		count = 0;
		goto done;

	    }

	}









    } else if (eventFlags == 0) {



	Tcl_SetResult(interp, "no event type or button # or keysym",
		TCL_STATIC);
	count = 0;
	goto done;
    }


    while ((*p == '-') || isspace(UCHAR(*p))) {
	p++;
    }
    if (*p != '>') {
	while (*p != '\0') {
	    p++;
	    if (*p == '>') {

		Tcl_SetResult(interp,

			"extra characters after detail in binding",
			TCL_STATIC);
		count = 0;
		goto done;
	    }
	}



	Tcl_SetResult(interp, "missing \">\" in binding", TCL_STATIC);
	count = 0;
	goto done;
    }
    p++;


  end:
    *eventStringPtr += (p - Tcl_DStringValue(&copy));
    *eventMaskPtr |= eventMask;
  done:
    Tcl_DStringFree(&copy);
    return count;
}

/*
 *----------------------------------------------------------------------
 *
 * GetField --
 *
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093

5094
5095
5096
5097

5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112


































































































































5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const char *
GetField(
    const char *p,	/* Pointer to part of pattern. */
    char *copy,		/* Place to copy field. */
    unsigned size)	/* Maximum number of characters to copy. */
{
    assert(p);

    assert(copy);

    for ( ; *p && !isspace(UCHAR(*p)) && *p != '>' && *p != '-' && size > 1u; --size) {
	*copy++ = *p++;

    }
    *copy = '\0';
    return p;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetPatternObj --
 *
 *	Produce a string version of the given event, for displaying to the
 *	user.
 *
 * Results:
 *	The string is returned as a Tcl_Obj.


































































































































 *
 * Side effects:
 *	It is the caller's responsibility to arrange for the object to be
 *	released; it starts with a refCount of zero.
 *
 *---------------------------------------------------------------------------
 */

static Tcl_Obj *
GetPatternObj(
    const PatSeq *psPtr)
{
    Tcl_Obj *patternObj = Tcl_NewObj();
    unsigned i;

    assert(psPtr);

    for (i = 0; i < psPtr->numPats; ++i) {
	const TkPattern *patPtr = psPtr->pats + i;

	/*
	 * Check for simple case of an ASCII character.
	 */
	if (patPtr->eventType == KeyPress
		&& patPtr->count == 1
		&& patPtr->modMask == 0
		&& patPtr->info < 128
		&& isprint(UCHAR(patPtr->info))
		&& patPtr->info != '<'
		&& patPtr->info != ' ') {
	    char c = (char) patPtr->info;
	    Tcl_AppendToObj(patternObj, &c, 1);
	} else if (patPtr->eventType == VirtualEvent) {
	    assert(patPtr->name);
	    Tcl_AppendPrintfToObj(patternObj, "<<%s>>", patPtr->name);
	} else {
	    unsigned modMask;
	    const ModInfo *modPtr;

	    /*
	     * It's a more general event specification. First check for "Double",
	     * "Triple", "Quadruple", then modifiers, then event type, then keysym
	     * or button detail.
	     */

	    Tcl_AppendToObj(patternObj, "<", 1);

	    switch (patPtr->count) {
	    case 2: Tcl_AppendToObj(patternObj, "Double-", 7); break;
	    case 3: Tcl_AppendToObj(patternObj, "Triple-", 7); break;
	    case 4: Tcl_AppendToObj(patternObj, "Quadruple-", 10); break;
	    }

	    modMask = patPtr->modMask;
#if PRINT_SHORT_MOTION_SYNTAX
	    if (patPtr->eventType == MotionNotify) {
		modMask &= ~(ModMask)ALL_BUTTONS;
	    }
#endif

	    for (modPtr = modArray; modMask; ++modPtr) {
		if (modPtr->mask & modMask) {
		    modMask &= ~modPtr->mask;
		    Tcl_AppendPrintfToObj(patternObj, "%s-", modPtr->name);
		}
	    }

	    assert(patPtr->eventType < TK_LASTEVENT);
	    assert(((size_t) eventArrayIndex[patPtr->eventType]) < SIZE_OF_ARRAY(eventArray));
	    Tcl_AppendToObj(patternObj, eventArray[eventArrayIndex[patPtr->eventType]].name, -1);

	    if (patPtr->info) {
		switch (patPtr->eventType) {
		case KeyPress:
		case KeyRelease: {
		    const char *string = TkKeysymToString(patPtr->info);
		    if (string) {
			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, -1);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= 13);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info));
		    break;
#if PRINT_SHORT_MOTION_SYNTAX
		case MotionNotify: {
		    unsigned mask = patPtr->modMask;
		    while (mask & ALL_BUTTONS) {
			unsigned button = ButtonNumberFromState(mask);
			Tcl_AppendPrintfToObj(patternObj, "-%u", (button > 7) ? (button - 4) : button);
			mask &= ~Tk_GetButtonMask(button);
		    }
		    break;
		}
#endif
		}
	    }

	    Tcl_AppendToObj(patternObj, ">", 1);
	}
    }

    return patternObj;
}

/*
 *----------------------------------------------------------------------
 *
 * TkStringToKeysym --
 *







|

|
|
|

|
>
|
|
<
|
>








|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<




|
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369

4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519

4520
4521
4522
4523
4524





4525

4526


4527


















4528



































































4529
4530
4531
4532
4533
4534
4535
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
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)) {
	*copy = *p;
	p++;

	copy++;
	size--;
    }
    *copy = '\0';
    return p;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetPatternString --
 *
 *	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 function.
 *
 *---------------------------------------------------------------------------
 */

static void
GetPatternString(
    PatSeq *psPtr,
    Tcl_DString *dsPtr)
{
    TkPattern *patPtr;
    char c, buffer[TCL_INTEGER_SPACE];
    int patsLeft, needMods;
    ModInfo *modPtr;
    EventInfo *eiPtr;

    /*
     * The order of the patterns in the sequence is backwards from the order
     * in which they must be output.
     */

    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)
		&& (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;
	}

	/*
	 * Check for virtual event.
	 */

	if (patPtr->eventType == VirtualEvent) {
	    Tcl_DStringAppend(dsPtr, "<<", 2);
	    Tcl_DStringAppend(dsPtr, patPtr->detail.name, -1);
	    Tcl_DStringAppend(dsPtr, ">>", 2);
	    continue;
	}

	/*
	 * 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(TkPattern)) == 0)) {
	    patsLeft--;
	    patPtr--;
	    if ((patsLeft > 1) && (memcmp((char *) patPtr,
		    (char *) (patPtr-1), sizeof(TkPattern)) == 0)) {
		patsLeft--;
		patPtr--;
		    if ((patsLeft > 1) && (memcmp((char *) patPtr,
			    (char *) (patPtr-1), sizeof(TkPattern)) == 0)) {
			patsLeft--;
			patPtr--;
			Tcl_DStringAppend(dsPtr, "Quadruple-", 10);
		    } else {
			Tcl_DStringAppend(dsPtr, "Triple-", 7);
		    }
	    } else {
		Tcl_DStringAppend(dsPtr, "Double-", 7);
	    }
	}

	for (needMods = patPtr->needMods, modPtr = modArray;
		needMods != 0; modPtr++) {
	    if (modPtr->mask & needMods) {
		needMods &= ~modPtr->mask;
		Tcl_DStringAppend(dsPtr, modPtr->name, -1);
		Tcl_DStringAppend(dsPtr, "-", 1);
	    }
	}

	for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) {
	    if (eiPtr->type == patPtr->eventType) {
		Tcl_DStringAppend(dsPtr, eiPtr->name, -1);
		if (patPtr->detail.clientData != 0) {
		    Tcl_DStringAppend(dsPtr, "-", 1);
		}
		break;
	    }
	}

	if (patPtr->detail.clientData != 0) {
	    if ((patPtr->eventType == KeyPress)
		    || (patPtr->eventType == KeyRelease)) {
		char *string = TkKeysymToString(patPtr->detail.keySym);
		if (string != NULL) {
		    Tcl_DStringAppend(dsPtr, string, -1);
		}
	    } else {
		sprintf(buffer, "%d", patPtr->detail.button);
		Tcl_DStringAppend(dsPtr, buffer, -1);
	    }
	}

	Tcl_DStringAppend(dsPtr, ">", 1);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * EvalTclBinding --
 *
 *	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
 *	percent-substitued binding string.
 *
 * Side effects:
 *	Normal side effects due to eval.

 *
 *---------------------------------------------------------------------------
 */

static void





FreeTclBinding(

    ClientData clientData)


{


















    ckfree((char *) clientData);



































































}

/*
 *----------------------------------------------------------------------
 *
 * TkStringToKeysym --
 *
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289


5290


















5291







5292





5293
5294
5295
5296
5297
5298
5299
5300
5301
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
TkStringToKeysym(
    const char *name)		/* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);

    if (hPtr) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }
    assert(name);
    if (strlen(name) == 1u) {
	KeySym keysym = (KeySym) (unsigned char) name[0];

	if (TkKeysymToString(keysym)) {
	    return keysym;
	}
    }
#endif /* REDO_KEYSYM_LOOKUP */
    assert(name);
    return XStringToKeysym(name);
}

/*
 *----------------------------------------------------------------------
 *
 * TkKeysymToString --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkKeysymToString(
    KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);

    if (hPtr) {
	return (const char *)Tcl_GetHashValue(hPtr);
    }
#endif /* REDO_KEYSYM_LOOKUP */



    if (keysym > (KeySym)0x1008FFFF) {


















	return NULL;







    }





    return XKeysymToString(keysym);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetBindingXEvent --
 *
 *	This function returns the XEvent associated with the currently







|




|


<
|


|




<




















|






|
|



>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
|








4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557

4558
4559
4560
4561
4562
4563
4564
4565

4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
TkStringToKeysym(
    char *name)			/* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);

    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }

    if (strlen(name) == 1) {
	KeySym keysym = (KeySym) (unsigned char) name[0];

	if (TkKeysymToString(keysym) != NULL) {
	    return keysym;
	}
    }
#endif /* REDO_KEYSYM_LOOKUP */

    return XStringToKeysym(name);
}

/*
 *----------------------------------------------------------------------
 *
 * TkKeysymToString --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TkKeysymToString(
    KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);

    if (hPtr != NULL) {
	return (char *) Tcl_GetHashValue(hPtr);
    }
#endif /* REDO_KEYSYM_LOOKUP */

    return XKeysymToString(keysym);
}

/*
 *----------------------------------------------------------------------
 *
 * TkCopyAndGlobalEval --
 *
 *	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.
 *
 * Side effects:
 *	Any; depends on script.
 *
 *----------------------------------------------------------------------
 */

int
TkCopyAndGlobalEval(
    Tcl_Interp *interp,		/* Interpreter in which to evaluate script. */
    char *script)		/* Script to evaluate. */
{
    Tcl_DString buffer;
    int code;

    Tcl_DStringInit(&buffer);
    Tcl_DStringAppend(&buffer, script, -1);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buffer),
	    Tcl_DStringLength(&buffer), TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buffer);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetBindingXEvent --
 *
 *	This function returns the XEvent associated with the currently
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
 *----------------------------------------------------------------------
 */

XEvent *
TkpGetBindingXEvent(
    Tcl_Interp *interp)		/* Interpreter. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    BindingTable *bindPtr = winPtr->mainPtr->bindingTable;

    return &bindPtr->curEvent->xev;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDumpPS --
 *
 *	Dump given pattern sequence to stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if SUPPORT_DEBUGGING
void
TkpDumpPS(
    const PatSeq *psPtr)
{
    if (!psPtr) {
	fprintf(stdout, "<null>\n");
    } else {
	Tcl_Obj* result = GetPatternObj(psPtr);
	Tcl_IncrRefCount(result);
	fprintf(stdout, "%s", Tcl_GetString(result));
	if (psPtr->object) {
	    fprintf(stdout, " (%s)", (char *) psPtr->object);
	}
	fprintf(stdout, "\n");
	Tcl_DecrRefCount(result);
    }
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkpDumpPSList --
 *
 *	Dump given pattern sequence list to stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if SUPPORT_DEBUGGING
void
TkpDumpPSList(
    const PSList *psList)
{
    if (!psList) {
	fprintf(stdout, "<null>\n");
    } else {
	const PSEntry *psEntry;

	fprintf(stdout, "Dump PSList ========================================\n");
	TK_DLIST_FOREACH(psEntry, psList) {
	    TkpDumpPS(psEntry->psPtr);
	}
	fprintf(stdout, "====================================================\n");
    }
}
#endif

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */







|
|

|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|

<

4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665







































































4666
4667
4668
4669
4670

4671
 *----------------------------------------------------------------------
 */

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:

 */

Changes to generic/tkBitmap.c.

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 */

typedef struct {
    const char *source;		/* Bitmap bits. */
    int width, height;		/* Dimensions of bitmap. */
} DataKey;

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */
    Tcl_HashTable predefBitmapTable;
				/* Hash table created by Tk_DefineBitmap to
				 * map from a name to a collection of in-core
				 * data about a bitmap. The table is indexed
				 * by the address of the data for the bitmap,
				 * and the entries contain pointers to
				 * TkPredefBitmap structures. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static void		BitmapInit(TkDisplay *dispPtr);
static void		DupBitmapObjProc(Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr);
static void		FreeBitmap(TkBitmap *bitmapPtr);
static void		FreeBitmapObj(Tcl_Obj *objPtr);
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.
 */

const Tcl_ObjType tkBitmapObjType = {
    "bitmap",			/* name */
    FreeBitmapObjProc,		/* freeIntRepProc */
    DupBitmapObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};








|



















<












|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 */

typedef struct {
    const char *source;		/* Bitmap bits. */
    int width, height;		/* Dimensions of bitmap. */
} DataKey;

typedef struct ThreadSpecificData {
    int initialized;		/* 0 means table below needs initializing. */
    Tcl_HashTable predefBitmapTable;
				/* Hash table created by Tk_DefineBitmap to
				 * map from a name to a collection of in-core
				 * data about a bitmap. The table is indexed
				 * by the address of the data for the bitmap,
				 * and the entries contain pointers to
				 * TkPredefBitmap structures. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

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.
 */

Tcl_ObjType tkBitmapObjType = {
    "bitmap",			/* name */
    FreeBitmapObjProc,		/* freeIntRepProc */
    DupBitmapObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
				 * for legal syntax of string value. */
{
    TkBitmap *bitmapPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(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 (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.
	     */

	    FreeBitmapObj(objPtr);
	    bitmapPtr = NULL;
	} 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.
     */

    if (bitmapPtr != NULL) {
	TkBitmap *firstBitmapPtr = (TkBitmap *)Tcl_GetHashValue(bitmapPtr->nameHashPtr);

	FreeBitmapObj(objPtr);
	for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		bitmapPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr;
		return bitmapPtr->bitmap;
	    }
	}
    }

    /*
     * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
     */

    bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr;
    if (bitmapPtr == NULL) {
	return None;
    }
    bitmapPtr->objRefCount++;
    return bitmapPtr->bitmap;
}








|













|















|
|
|






|










|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
				 * for legal syntax of string value. */
{
    TkBitmap *bitmapPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(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 (bitmapPtr != NULL) {
	if (bitmapPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkBitmap that's no
	     * longer in use. Clear the reference.
	     */

	    FreeBitmapObjProc(objPtr);
	    bitmapPtr = NULL;
	} else if ((Tk_Display(tkwin) == bitmapPtr->display)
		&& (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.
     */

    if (bitmapPtr != NULL) {
	TkBitmap *firstBitmapPtr = (TkBitmap *)
		Tcl_GetHashValue(bitmapPtr->nameHashPtr);
	FreeBitmapObjProc(objPtr);
	for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		bitmapPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
		return bitmapPtr->bitmap;
	    }
	}
    }

    /*
     * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
     */

    bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
    if (bitmapPtr == NULL) {
	return None;
    }
    bitmapPtr->objRefCount++;
    return bitmapPtr->bitmap;
}

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
    if (!dispPtr->bitmapInit) {
	BitmapInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string,
	    &isNew);
    if (!isNew) {
	existingBitmapPtr = (TkBitmap *)Tcl_GetHashValue(nameHashPtr);
	for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		return bitmapPtr;
	    }
	}
    } else {
	existingBitmapPtr = NULL;
    }

    /*
     * 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_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify bitmap with '@' in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", 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
	 * the string.
	 */

	string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
	if (string == NULL) {
	    goto error;
	}
	result = TkReadBitmapFile(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), string,
		(unsigned int *) &width, (unsigned int *) &height,
		&bitmap, &dummy2, &dummy2);
	if (result != BitmapSuccess) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"error reading bitmap file \"%s\"", string));
		Tcl_SetErrorCode(interp, "TK", "BITMAP", "FILE_ERROR", NULL);
	    }
	    Tcl_DStringFree(&buffer);
	    goto error;
	}
	Tcl_DStringFree(&buffer);
    } else {
	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.
	     */

	    bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
		    &width, &height);

	    if (bitmap == None) {
		if (interp != NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bitmap \"%s\" not defined", string));
		    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BITMAP", string,
			    NULL);
		}
		goto error;
	    }
	} else {
	    predefPtr = (TkPredefBitmap *)Tcl_GetHashValue(predefHashPtr);
	    width = predefPtr->width;
	    height = predefPtr->height;
	    if (predefPtr->native) {
		bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
		    predefPtr->source);
		if (bitmap == None) {
		    Tcl_Panic("native bitmap creation failed");
		}
	    } else {
		bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
			RootWindowOfScreen(Tk_Screen(tkwin)),
			(const char *)predefPtr->source, (unsigned)width, (unsigned)height);
	    }
	}
    }

    /*
     * Add information about this bitmap to our database.
     */

    bitmapPtr = (TkBitmap *)ckalloc(sizeof(TkBitmap));
    bitmapPtr->bitmap = bitmap;
    bitmapPtr->width = width;
    bitmapPtr->height = height;
    bitmapPtr->display = Tk_Display(tkwin);
    bitmapPtr->screenNum = Tk_ScreenNumber(tkwin);
    bitmapPtr->resourceRefCount = 1;
    bitmapPtr->objRefCount = 0;







|


|
|




















<
|
<
|



















<
|
|



















|
|
<
<




|











|








|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    if (!dispPtr->bitmapInit) {
	BitmapInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string,
	    &isNew);
    if (!isNew) {
	existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
	for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ( (Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum) ) {
		bitmapPtr->resourceRefCount++;
		return bitmapPtr;
	    }
	}
    } else {
	existingBitmapPtr = NULL;
    }

    /*
     * 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", 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
	 * the string.
	 */

	string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
	if (string == NULL) {
	    goto error;
	}
	result = TkReadBitmapFile(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), string,
		(unsigned int *) &width, (unsigned int *) &height,
		&bitmap, &dummy2, &dummy2);
	if (result != BitmapSuccess) {
	    if (interp != 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);
	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.
	     */

	    bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
		    &width, &height);

	    if (bitmap == None) {
		if (interp != NULL) {
		    Tcl_AppendResult(interp, "bitmap \"", string,
			    "\" not defined", NULL);


		}
		goto error;
	    }
	} else {
	    predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr);
	    width = predefPtr->width;
	    height = predefPtr->height;
	    if (predefPtr->native) {
		bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
		    predefPtr->source);
		if (bitmap == None) {
		    Tcl_Panic("native bitmap creation failed");
		}
	    } else {
		bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
			RootWindowOfScreen(Tk_Screen(tkwin)),
			predefPtr->source, (unsigned)width, (unsigned)height);
	    }
	}
    }

    /*
     * Add information about this bitmap to our database.
     */

    bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
    bitmapPtr->bitmap = bitmap;
    bitmapPtr->width = width;
    bitmapPtr->height = height;
    bitmapPtr->display = Tk_Display(tkwin);
    bitmapPtr->screenNum = Tk_ScreenNumber(tkwin);
    bitmapPtr->resourceRefCount = 1;
    bitmapPtr->objRefCount = 0;
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 */

int
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 void *source,		/* Address of bits for bitmap. */
    int width,			/* Width of bitmap. */
    int height)			/* Height of bitmap. */
{
    int isNew;
    Tcl_HashEntry *predefHashPtr;
    TkPredefBitmap *predefPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)







|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
 */

int
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 isNew;
    Tcl_HashEntry *predefHashPtr;
    TkPredefBitmap *predefPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    if (!tsdPtr->initialized) {
	BitmapInit(NULL);
    }

    predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,
	    name, &isNew);
    if (!isNew) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bitmap \"%s\" is already defined", name));
	Tcl_SetErrorCode(interp, "TK", "BITMAP", "EXISTS", NULL);
	return TCL_ERROR;
    }
    predefPtr = (TkPredefBitmap *)ckalloc(sizeof(TkPredefBitmap));
    predefPtr->source = source;
    predefPtr->width = width;
    predefPtr->height = height;
    predefPtr->native = 0;
    Tcl_SetHashValue(predefHashPtr, predefPtr);
    return TCL_OK;
}







|
<
|


|







482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
    if (!tsdPtr->initialized) {
	BitmapInit(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));
    predefPtr->source = source;
    predefPtr->width = width;
    predefPtr->height = height;
    predefPtr->native = 0;
    Tcl_SetHashValue(predefHashPtr, predefPtr);
    return TCL_OK;
}
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (dispPtr == NULL || !dispPtr->bitmapInit) {
    unknown:
	Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	goto unknown;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    return bitmapPtr->nameHashPtr->key.string;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SizeOfBitmap --







|



|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (dispPtr == NULL || !dispPtr->bitmapInit) {
    unknown:
	Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknown;
    }
    bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
    return bitmapPtr->nameHashPtr->key.string;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SizeOfBitmap --
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
    unknownBitmap:
	Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	goto unknownBitmap;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    *widthPtr = bitmapPtr->width;
    *heightPtr = bitmapPtr->height;
}

/*
 *----------------------------------------------------------------------
 *







|



|







567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
    unknownBitmap:
	Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknownBitmap;
    }
    bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
    *widthPtr = bitmapPtr->width;
    *heightPtr = bitmapPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

static void
FreeBitmap(
    TkBitmap *bitmapPtr)	/* Bitmap to be released. */
{
    TkBitmap *prevPtr;


    if (bitmapPtr->resourceRefCount-- > 1) {
	return;
    }

    Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
    Tcl_DeleteHashEntry(bitmapPtr->idHashPtr);
    prevPtr = (TkBitmap *)Tcl_GetHashValue(bitmapPtr->nameHashPtr);
    if (prevPtr == bitmapPtr) {
	if (bitmapPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr);
	} else {
	    Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != bitmapPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = bitmapPtr->nextPtr;
    }
    if (bitmapPtr->objRefCount == 0) {
	ckfree(bitmapPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeBitmap --







>
|





|













|







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636

static void
FreeBitmap(
    TkBitmap *bitmapPtr)	/* Bitmap to be released. */
{
    TkBitmap *prevPtr;

    bitmapPtr->resourceRefCount--;
    if (bitmapPtr->resourceRefCount > 0) {
	return;
    }

    Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
    Tcl_DeleteHashEntry(bitmapPtr->idHashPtr);
    prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);
    if (prevPtr == bitmapPtr) {
	if (bitmapPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr);
	} else {
	    Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != bitmapPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = bitmapPtr->nextPtr;
    }
    if (bitmapPtr->objRefCount == 0) {
	ckfree((char *) bitmapPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeBitmap --
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
	Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
    }
    FreeBitmap((TkBitmap *)Tcl_GetHashValue(idHashPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeBitmapFromObj --
 *







|



|







656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
	Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
    }
    FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeBitmapFromObj --
 *
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
{
    FreeBitmap(GetBitmapFromObj(tkwin, objPtr));
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeBitmapObjProc, FreeBitmapObj --
 *
 *	This proc is called to release an object reference to a bitmap.
 *	Called when the object's internal rep is released or when the cached
 *	bitmapPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeBitmapObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    FreeBitmapObj(objPtr);
    objPtr->typePtr = NULL;
}

static void
FreeBitmapObj(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    TkBitmap *bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;

    if (bitmapPtr != NULL) {
	bitmapPtr->objRefCount--;
	if ((bitmapPtr->objRefCount == 0)
		&& (bitmapPtr->resourceRefCount == 0)) {
	    ckfree(bitmapPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------







|



















<
<
<
<
<
<
<
<
|





|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722








723
724
725
726
727
728
729
730
731
732
733
734
735
736
{
    FreeBitmap(GetBitmapFromObj(tkwin, objPtr));
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeBitmapObjProc --
 *
 *	This proc is called to release an object reference to a bitmap.
 *	Called when the object's internal rep is released or when the cached
 *	bitmapPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeBitmapObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{








    TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;

    if (bitmapPtr != NULL) {
	bitmapPtr->objRefCount--;
	if ((bitmapPtr->objRefCount == 0)
		&& (bitmapPtr->resourceRefCount == 0)) {
	    ckfree((char *) bitmapPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
 */

static void
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 = bitmapPtr;

    if (bitmapPtr != NULL) {
	bitmapPtr->objRefCount++;
    }
}

/*







|


|







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
 */

static void
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;

    if (bitmapPtr != NULL) {
	bitmapPtr->objRefCount++;
    }
}

/*
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
 *	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_GetBitmapFromData(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which bitmap will be used. */
    const void *source,		/* Bitmap data for bitmap shape. */
    int width, int height)	/* Dimensions of bitmap. */
{
    DataKey nameKey;
    Tcl_HashEntry *dataHashPtr;
    int isNew;
    char string[16 + TCL_INTEGER_SPACE];
    char *name;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	BitmapInit(dispPtr);
    }

    nameKey.source = (const char *)source;
    nameKey.width = width;
    nameKey.height = height;
    dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
	    (char *) &nameKey, &isNew);
    if (!isNew) {
	name = (char *)Tcl_GetHashValue(dataHashPtr);
    } else {
	dispPtr->bitmapAutoNumber++;
	sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);







>




|















|





|







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
 *	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.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
Pixmap
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 isNew;
    char string[16 + TCL_INTEGER_SPACE];
    char *name;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	BitmapInit(dispPtr);
    }

    nameKey.source = source;
    nameKey.width = width;
    nameKey.height = height;
    dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
	    (char *) &nameKey, &isNew);
    if (!isNew) {
	name = (char *) Tcl_GetHashValue(dataHashPtr);
    } else {
	dispPtr->bitmapAutoNumber++;
	sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(objPtr);
    }

    bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;
    if (bitmapPtr != NULL) {
	if ((bitmapPtr->resourceRefCount > 0)
		&& (Tk_Display(tkwin) == bitmapPtr->display)) {
	    return bitmapPtr;
	}
	hashPtr = bitmapPtr->nameHashPtr;
	FreeBitmapObj(objPtr);
    } else {
	hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,
		Tcl_GetString(objPtr));
	if (hashPtr == NULL) {
	    goto error;
	}
    }

    /*
     * At this point we've got a hash table entry, off of which hang one or
     * more TkBitmap structures. See if any of them will work.
     */

    for (bitmapPtr = (TkBitmap *)Tcl_GetHashValue(hashPtr); bitmapPtr != NULL;
	    bitmapPtr = bitmapPtr->nextPtr) {
	if (Tk_Display(tkwin) == bitmapPtr->display) {
	    objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr;
	    bitmapPtr->objRefCount++;
	    return bitmapPtr;
	}
    }

  error:
    Tcl_Panic("GetBitmapFromObj called with non-existent bitmap!");







|






|













|
|

|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(objPtr);
    }

    bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
    if (bitmapPtr != NULL) {
	if ((bitmapPtr->resourceRefCount > 0)
		&& (Tk_Display(tkwin) == bitmapPtr->display)) {
	    return bitmapPtr;
	}
	hashPtr = bitmapPtr->nameHashPtr;
	FreeBitmapObjProc(objPtr);
    } else {
	hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,
		Tcl_GetString(objPtr));
	if (hashPtr == NULL) {
	    goto error;
	}
    }

    /*
     * At this point we've got a hash table entry, off of which hang one or
     * more TkBitmap structures. See if any of them will work.
     */

    for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
	    bitmapPtr != NULL;  bitmapPtr = bitmapPtr->nextPtr) {
	if (Tk_Display(tkwin) == bitmapPtr->display) {
	    objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
	    bitmapPtr->objRefCount++;
	    return bitmapPtr;
	}
    }

  error:
    Tcl_Panic("GetBitmapFromObj called with non-existent bitmap!");
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBitmapObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------







|







961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->typePtr = &tkBitmapObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
     */

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	dummy = Tcl_CreateInterp();
	Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);

	Tk_DefineBitmap(dummy, "error", error_bits,
		error_width, error_height);
	Tk_DefineBitmap(dummy, "gray75", gray75_bits,
		gray75_width, gray75_height);
	Tk_DefineBitmap(dummy, "gray50", gray50_bits,
		gray50_width, gray50_height);
	Tk_DefineBitmap(dummy, "gray25", gray25_bits,
		gray25_width, gray25_height);
	Tk_DefineBitmap(dummy, "gray12", gray12_bits,
		gray12_width, gray12_height);
	Tk_DefineBitmap(dummy, "hourglass", hourglass_bits,
		hourglass_width, hourglass_height);
	Tk_DefineBitmap(dummy, "info", info_bits,
		info_width, info_height);
	Tk_DefineBitmap(dummy, "questhead", questhead_bits,
		questhead_width, questhead_height);
	Tk_DefineBitmap(dummy, "question", question_bits,
		question_width, question_height);
	Tk_DefineBitmap(dummy, "warning", warning_bits,
		warning_width, warning_height);

	TkpDefineNativeBitmaps();
	Tcl_DeleteInterp(dummy);
    }

    /*







|

|

|

|

|

|

|

|

|

|







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
     */

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	dummy = Tcl_CreateInterp();
	Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);

	Tk_DefineBitmap(dummy, "error", (char *) error_bits,
		error_width, error_height);
	Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits,
		gray75_width, gray75_height);
	Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits,
		gray50_width, gray50_height);
	Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits,
		gray25_width, gray25_height);
	Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits,
		gray12_width, gray12_height);
	Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits,
		hourglass_width, hourglass_height);
	Tk_DefineBitmap(dummy, "info", (char *) info_bits,
		info_width, info_height);
	Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits,
		questhead_width, questhead_height);
	Tk_DefineBitmap(dummy, "question", (char *) question_bits,
		question_width, question_height);
	Tk_DefineBitmap(dummy, "warning", (char *) warning_bits,
		warning_width, warning_height);

	TkpDefineNativeBitmaps();
	Tcl_DeleteInterp(dummy);
    }

    /*
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
    unsigned int *height_return,
    Pixmap *bitmap_return,
    int *x_hot_return,
    int *y_hot_return)
{
    char *data;

    data = TkGetBitmapData(NULL, NULL, filename,
	    (int *) width_return, (int *) height_return, x_hot_return,
	    y_hot_return);
    if (data == NULL) {
	return BitmapFileInvalid;
    }

    *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
    unsigned int *height_return,
    Pixmap *bitmap_return,
    int *x_hot_return,
    int *y_hot_return)
{
    char *data;

    data = TkGetBitmapData(NULL, NULL, (char *) filename,
	    (int *) width_return, (int *) height_return, x_hot_return,
	    y_hot_return);
    if (data == NULL) {
	return BitmapFileInvalid;
    }

    *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugBitmap(
    Tk_Window tkwin,		/* The window in which the bitmap will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{
    TkBitmap *bitmapPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name);
    if (hashPtr != NULL) {
	bitmapPtr = (TkBitmap *)Tcl_GetHashValue(hashPtr);
	if (bitmapPtr == NULL) {
	    Tcl_Panic("TkDebugBitmap found empty hash table entry");
	}
	for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(bitmapPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(bitmapPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*







|









|






|

|







1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
 *----------------------------------------------------------------------
 */

Tcl_Obj *
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;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name);
    if (hashPtr != NULL) {
	bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
	if (bitmapPtr == NULL) {
	    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_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*

Deleted generic/tkBusy.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
/*
 * tkBusy.c --
 *
 *	This file provides functions that implement busy for Tk.
 *
 * Copyright 1993-1998 Lucent Technologies, Inc.
 *
 *	The "busy" command was created by George Howlett. Adapted for
 *	integration into Tk by Jos Decoster and Donal K. Fellows.
 *
 * 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 "tkBusy.h"
#include "default.h"

/*
 * Things about the busy system that may be configured. Note that on some
 * platforms this may or may not have an effect.
 */

static const Tk_OptionSpec busyOptionSpecs[] = {
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUSY_CURSOR, TCL_INDEX_NONE, offsetof(Busy, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations of functions defined in this file.
 */

static void		BusyEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		BusyGeometryProc(ClientData clientData,
			    Tk_Window tkwin);
static void		BusyCustodyProc(ClientData clientData,
			    Tk_Window tkwin);
static int		ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
			    int objc, Tcl_Obj *const objv[]);
static Busy *		CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
static void		DestroyBusy(void *dataPtr);
static void		DoConfigureNotify(Tk_FakeWin *winPtr);
static inline Tk_Window	FirstChild(Tk_Window parent);
static Busy *		GetBusy(Tcl_Interp *interp,
			    Tcl_HashTable *busyTablePtr,
			    Tcl_Obj *const windowObj);
static int		HoldBusy(Tcl_HashTable *busyTablePtr,
			    Tcl_Interp *interp, Tcl_Obj *const windowObj,
			    int configObjc, Tcl_Obj *const configObjv[]);
static void		MakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
static inline Tk_Window	NextChild(Tk_Window tkwin);
static void		RefWinEventProc(ClientData clientData,
			    XEvent *eventPtr);
static inline void	SetWindowInstanceData(Tk_Window tkwin,
			    ClientData instanceData);

/*
 * The "busy" geometry manager definition.
 */

static Tk_GeomMgr busyMgrInfo = {
    "busy",			/* Name of geometry manager used by winfo */
    BusyGeometryProc,		/* Procedure to for new geometry requests */
    BusyCustodyProc,		/* Procedure when window is taken away */
};

/*
 * Helper functions, need to check if a Tcl/Tk alternative already exists.
 */

static inline Tk_Window
FirstChild(
    Tk_Window parent)
{
    struct TkWindow *parentPtr = (struct TkWindow *) parent;

    return (Tk_Window) parentPtr->childList;
}

static inline Tk_Window
NextChild(
    Tk_Window tkwin)
{
    struct TkWindow *winPtr = (struct TkWindow *) tkwin;

    if (winPtr == NULL) {
	return NULL;
    }
    return (Tk_Window) winPtr->nextPtr;
}

static inline void
SetWindowInstanceData(
    Tk_Window tkwin,
    ClientData instanceData)
{
    struct TkWindow *winPtr = (struct TkWindow *) tkwin;

    winPtr->instanceData = instanceData;
}

/*
 *----------------------------------------------------------------------
 *
 * BusyCustodyProc --
 *
 *	This procedure is invoked when the busy window has been stolen by
 *	another geometry manager. The information and memory associated with
 *	the busy window is released. I don't know why anyone would try to pack
 *	a busy window, but this should keep everything sane, if it is.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Busy structure is freed at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyCustodyProc(
    ClientData clientData,	/* Information about the busy window. */
    TCL_UNUSED(Tk_Window))		/* Not used. */
{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *
 *	This procedure is invoked by Tk_GeometryRequest for busy windows.
 *	Busy windows never request geometry, so it's unlikely that this
 *	function will ever be called;it exists simply as a place holder for
 *	the GeomProc in the Geometry Manager structure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
BusyGeometryProc(
    TCL_UNUSED(void *),	/* Information about window that got new
				 * preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    /* Should never get here */
}

/*
 *----------------------------------------------------------------------
 *
 * DoConfigureNotify --
 *
 *	Generate a ConfigureNotify event describing the current configuration
 *	of a window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An event is generated and processed by Tk_HandleEvent.
 *
 *----------------------------------------------------------------------
 */

static void
DoConfigureNotify(
    Tk_FakeWin *winPtr)		/* Window whose configuration was just
				 * changed. */
{
    XEvent event;

    event.type = ConfigureNotify;
    event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display);
    event.xconfigure.send_event = False;
    event.xconfigure.display = winPtr->display;
    event.xconfigure.event = winPtr->window;
    event.xconfigure.window = winPtr->window;
    event.xconfigure.x = winPtr->changes.x;
    event.xconfigure.y = winPtr->changes.y;
    event.xconfigure.width = winPtr->changes.width;
    event.xconfigure.height = winPtr->changes.height;
    event.xconfigure.border_width = winPtr->changes.border_width;
    if (winPtr->changes.stack_mode == Above) {
	event.xconfigure.above = winPtr->changes.sibling;
    } else {
	event.xconfigure.above = None;
    }
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    Tk_HandleEvent(&event);
}

/*
 *----------------------------------------------------------------------
 *
 * RefWinEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for the following
 *	events on the reference window. If the reference and parent windows
 *	are the same, only the first event is important.
 *
 *	1) ConfigureNotify	The reference window has been resized or
 *				moved. Move and resize the busy window to be
 *				the same size and position of the reference
 *				window.
 *
 *	2) DestroyNotify	The reference window was destroyed. Destroy
 *				the busy window and the free resources used.
 *
 *	3) MapNotify		The reference window was (re)shown. Map the
 *				busy window again.
 *
 *	4) UnmapNotify		The reference window was hidden. Unmap the
 *				busy window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When the reference window gets deleted, internal structures get
 *	cleaned up. When it gets resized, the busy window is resized
 *	accordingly. If it's displayed, the busy window is displayed. And when
 *	it's hidden, the busy window is unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
RefWinEventProc(
    ClientData clientData,	/* Busy window record */
    XEvent *eventPtr)	/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    switch (eventPtr->type) {
    case ReparentNotify:
    case DestroyNotify:
	/*
	 * Arrange for the busy structure to be removed at a proper time.
	 */

	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	break;

    case ConfigureNotify:
	if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) ||
		(busyPtr->height != Tk_Height(busyPtr->tkRef)) ||
		(busyPtr->x != Tk_X(busyPtr->tkRef)) ||
		(busyPtr->y != Tk_Y(busyPtr->tkRef))) {
	    int x, y;

	    busyPtr->width = Tk_Width(busyPtr->tkRef);
	    busyPtr->height = Tk_Height(busyPtr->tkRef);
	    busyPtr->x = Tk_X(busyPtr->tkRef);
	    busyPtr->y = Tk_Y(busyPtr->tkRef);

	    x = y = 0;

	    if (busyPtr->tkParent != busyPtr->tkRef) {
		Tk_Window tkwin;

		for (tkwin = busyPtr->tkRef; (tkwin != NULL) &&
			 (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) {
		    if (tkwin == busyPtr->tkParent) {
			break;
		    }
		    x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
		    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
		}
	    }
	    if (busyPtr->tkBusy != NULL) {
		Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width,
			busyPtr->height);
		TkpShowBusyWindow(busyPtr);
	    }
	}
	break;

    case MapNotify:
	if (busyPtr->tkParent != busyPtr->tkRef) {
	    TkpShowBusyWindow(busyPtr);
	}
	break;

    case UnmapNotify:
	if (busyPtr->tkParent != busyPtr->tkRef) {
	    TkpHideBusyWindow(busyPtr);
	}
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyBusy --
 *
 *	This procedure is called from the Tk event dispatcher. It releases X
 *	resources and memory used by the busy window and updates the internal
 *	hash table.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(
    void *data)			/* Busy window structure record */
{
    Busy *busyPtr = (Busy *)data;

    if (busyPtr->hashPtr != NULL) {
	Tcl_DeleteHashEntry(busyPtr->hashPtr);
    }
    Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask,
	    RefWinEventProc, busyPtr);

    if (busyPtr->tkBusy != NULL) {
	Tk_FreeConfigOptions(data, busyPtr->optionTable, busyPtr->tkBusy);
	Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask,
		BusyEventProc, busyPtr);
	Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr);
	Tk_DestroyWindow(busyPtr->tkBusy);
    }
    ckfree(data);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for events on the busy
 *	window itself. We're only concerned with destroy events.
 *
 *	It might be necessary (someday) to watch resize events. Right now, I
 *	don't think there's any point in it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When a busy window is destroyed, all internal structures associated
 *	with it released at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyEventProc(
    ClientData clientData,	/* Busy window record */
    XEvent *eventPtr)		/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    if (eventPtr->type == DestroyNotify) {
	busyPtr->tkBusy = NULL;
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTransparentWindowExist --
 *
 *	Similar to Tk_MakeWindowExist but instead creates a transparent window
 *	to block for user events from sibling windows.
 *
 *	Differences from Tk_MakeWindowExist.
 *
 *	1. This is always a "busy" window. There's never a platform-specific
 *	   class procedure to execute instead.
 *	2. The window is transparent and never will contain children, so
 *	   colormap information is irrelevant.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When the procedure returns, the internal window associated with tkwin
 *	is guaranteed to exist. This may require the window's ancestors to be
 *	created too.
 *
 *----------------------------------------------------------------------
 */

static void
MakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent)		/* Parent window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Tcl_HashEntry *hPtr;
    int notUsed;
    TkDisplay *dispPtr;

    if (winPtr->window != None) {
	return;			/* Window already exists. */
    }

    /*
     * Create a transparent window and put it on top.
     */

    TkpMakeTransparentWindowExist(tkwin, parent);

    if (winPtr->window == None) {
	return;			/* Platform didn't make Window. */
    }

    dispPtr = winPtr->dispPtr;
    hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *) winPtr->window,
	    &notUsed);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->dirtyAtts = 0;
    winPtr->dirtyChanges = 0;

    if (!(winPtr->flags & TK_TOP_HIERARCHY)) {
	TkWindow *winPtr2;

	/*
	 * 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.
	 */

	for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL;
		winPtr2 = winPtr2->nextPtr) {
	    if ((winPtr2->window != None) &&
		    !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) {
		XWindowChanges changes;

		changes.sibling = winPtr2->window;
		changes.stack_mode = Below;
		XConfigureWindow(winPtr->display, winPtr->window,
			CWSibling | CWStackMode, &changes);
		break;
	    }
	}
    }

    /*
     * 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).
     */

    if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY)
	    && !(winPtr->flags & TK_ALREADY_DEAD)) {
	winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY;
	DoConfigureNotify((Tk_FakeWin *) tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CreateBusy --
 *
 *	Creates a child transparent window that obscures its parent window
 *	thereby effectively blocking device events. The size and position of
 *	the busy window is exactly that of the reference window.
 *
 *	We want to create sibling to the window to be blocked. If the busy
 *	window is a child of the window to be blocked, Enter/Leave events can
 *	sneak through. Futhermore under WIN32, messages of transparent windows
 *	are sent directly to the parent. The only exception to this are
 *	toplevels, since we can't make a sibling. Fortunately, toplevel
 *	windows rarely receive events that need blocking.
 *
 * Results:
 *	Returns a pointer to the new busy window structure.
 *
 * Side effects:
 *	When the busy window is eventually displayed, it will screen device
 *	events (in the area of the reference window) from reaching its parent
 *	window and its children. User feed back can be achieved by changing
 *	the cursor.
 *
 *----------------------------------------------------------------------
 */

static Busy *
CreateBusy(
    Tcl_Interp *interp,		/* Interpreter to report error to */
    Tk_Window tkRef)		/* Window hosting the busy window */
{
    Busy *busyPtr;
    size_t length;
    int x, y;
    const char *fmt;
    char *name;
    Tk_Window tkBusy, tkChild, tkParent;
    Window parent;
    Tk_FakeWin *winPtr;

    busyPtr = (Busy *)ckalloc(sizeof(Busy));
    x = y = 0;
    length = strlen(Tk_Name(tkRef));
    name = (char *)ckalloc(length + 6);
    if (Tk_IsTopLevel(tkRef)) {
	fmt = "_Busy";		/* Child */
	tkParent = tkRef;
    } else {
	Tk_Window tkwin;

	fmt = "%s_Busy";	/* Sibling */
	tkParent = Tk_Parent(tkRef);
	for (tkwin = tkRef; (tkwin != NULL) && !Tk_IsTopLevel(tkwin);
		tkwin = Tk_Parent(tkwin)) {
	    if (tkwin == tkParent) {
		break;
	    }
	    x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
	    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	}
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
	    tkChild = NextChild(tkChild)) {
	Tk_MakeWindowExist(tkChild);
    }
    sprintf(name, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
	return NULL;
    }
    Tk_MakeWindowExist(tkRef);
    busyPtr->display = Tk_Display(tkRef);
    busyPtr->interp = interp;
    busyPtr->tkRef = tkRef;
    busyPtr->tkParent = tkParent;
    busyPtr->tkBusy = tkBusy;
    busyPtr->width = Tk_Width(tkRef);
    busyPtr->height = Tk_Height(tkRef);
    busyPtr->x = Tk_X(tkRef);
    busyPtr->y = Tk_Y(tkRef);
    busyPtr->cursor = NULL;
    Tk_SetClass(tkBusy, "Busy");
    busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
    if (Tk_InitOptions(interp, busyPtr, busyPtr->optionTable,
	    tkBusy) != TCL_OK) {
	Tk_DestroyWindow(tkBusy);
	return NULL;
    }
    SetWindowInstanceData(tkBusy, busyPtr);
    winPtr = (Tk_FakeWin *) tkRef;

    TkpCreateBusy(winPtr, tkRef, &parent, tkParent, busyPtr);

    MakeTransparentWindowExist(tkBusy, parent);

    Tk_MoveResizeWindow(tkBusy, x, y, busyPtr->width, busyPtr->height);

    /*
     * Only worry if the busy window is destroyed.
     */

    Tk_CreateEventHandler(tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);

    /*
     * Indicate that the busy window's geometry is being managed. This will
     * also notify us if the busy window is ever packed.
     */

    Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr);
    if (busyPtr->cursor != NULL) {
	Tk_DefineCursor(tkBusy, busyPtr->cursor);
    }

    /*
     * Track the reference window to see if it is resized or destroyed.
     */

    Tk_CreateEventHandler(tkRef, StructureNotifyMask, RefWinEventProc,
	    busyPtr);
    return busyPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureBusy --
 *
 *	This procedure is called from the Tk event dispatcher. It releases X
 *	resources and memory used by the busy window and updates the internal
 *	hash table.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureBusy(
    Tcl_Interp *interp,
    Busy *busyPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
	    objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }
    if (busyPtr->cursor != oldCursor) {
	if (busyPtr->cursor == NULL) {
	    Tk_UndefineCursor(busyPtr->tkBusy);
	} else {
	    Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor);
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetBusy --
 *
 *	Returns the busy window structure associated with the reference
 *	window, keyed by its path name. The clientData argument is the main
 *	window of the interpreter, used to search for the reference window in
 *	its own window hierarchy.
 *
 * Results:
 *	If path name represents a reference window with a busy window, a
 *	pointer to the busy window structure is returned. Otherwise, NULL is
 *	returned and an error message is left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Busy *
GetBusy(
    Tcl_Interp *interp,		/* Interpreter to look up main window of. */
    Tcl_HashTable *busyTablePtr,/* Busy hash table */
    Tcl_Obj *const windowObj)	/* Path name of parent window */
{
    Tcl_HashEntry *hPtr;
    Tk_Window tkwin;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, tkwin);
    if (hPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't find busy window \"%s\"", Tcl_GetString(windowObj)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY",
		Tcl_GetString(windowObj), NULL);
	return NULL;
    }
    return (Busy *)Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * HoldBusy --
 *
 *	Creates (if necessary) and maps a busy window, thereby preventing
 *	device events from being be received by the parent window and its
 *	children.
 *
 * Results:
 *	Returns a standard TCL result. If path name represents a busy window,
 *	it is unmapped and TCL_OK is returned. Otherwise, TCL_ERROR is
 *	returned and an error message is left in interp->result.
 *
 * Side effects:
 *	The busy window is created and displayed, blocking events from the
 *	parent window and its children.
 *
 *----------------------------------------------------------------------
 */

static int
HoldBusy(
    Tcl_HashTable *busyTablePtr,/* Busy hash table. */
    Tcl_Interp *interp,		/* Interpreter to report errors to. */
    Tcl_Obj *const windowObj,	/* Window name. */
    int configObjc,		/* Option pairs. */
    Tcl_Obj *const configObjv[])
{
    Tk_Window tkwin;
    Tcl_HashEntry *hPtr;
    Busy *busyPtr;
    int isNew, result;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }
    hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
    if (isNew) {
	busyPtr = CreateBusy(interp, tkwin);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetHashValue(hPtr, busyPtr);
	busyPtr->hashPtr = hPtr;
    } else {
	busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
    }

    busyPtr->tablePtr = busyTablePtr;
    result = ConfigureBusy(interp, busyPtr, configObjc, configObjv);

    /*
     * Don't map the busy window unless the reference window is also currently
     * displayed.
     */

    if (Tk_IsMapped(busyPtr->tkRef)) {
	TkpShowBusyWindow(busyPtr);
    } else {
	TkpHideBusyWindow(busyPtr);
    }
    if (result == TCL_OK) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BusyObjCmd --
 *
 *	This function is invoked to process the "tk busy" Tcl command. See the
 *	user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BusyObjCmd(
    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;
    Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable;
    Busy *busyPtr;
    Tcl_Obj *objPtr;
    int index, result = TCL_OK;
    static const char *const optionStrings[] = {
	"busywindow", "cget", "configure", "current", "forget", "hold",
        "status", NULL
    };
    enum options {
	BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET,
	BUSY_HOLD, BUSY_STATUS
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * [tk busy <window>] command shortcut.
     */

    if (Tcl_GetString(objv[1])[0] == '.') {
	if (objc%2 == 1) {
	    Tcl_WrongNumArgs(interp, 1, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {
    case BUSY_BUSYWINDOW:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    Tcl_ResetResult(interp);
            return TCL_OK;
	}
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
        return TCL_OK;

    case BUSY_CGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window option");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	objPtr = Tk_GetOptionValue(interp, busyPtr,
		busyPtr->optionTable, objv[3], busyPtr->tkBusy);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, objPtr);
	}
	Tcl_Release(busyPtr);
	return result;

    case BUSY_CONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, busyPtr,
		    busyPtr->optionTable, (objc == 4) ? objv[3] : NULL,
		    busyPtr->tkBusy);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureBusy(interp, busyPtr, objc-3, objv+3);
	}
	Tcl_Release(busyPtr);
	return result;

    case BUSY_CURRENT: {
	Tcl_HashEntry *hPtr;
	Tcl_HashSearch cursor;
	const char *pattern = (objc == 3 ? Tcl_GetString(objv[2]) : NULL);

	objPtr = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL;
		hPtr = Tcl_NextHashEntry(&cursor)) {
	    busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
	    if (pattern == NULL ||
		    Tcl_StringCaseMatch(Tk_PathName(busyPtr->tkRef), pattern, 0)) {
		Tcl_ListObjAppendElement(interp, objPtr,
			Tk_NewWindowObj(busyPtr->tkRef));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }

    case BUSY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3);

    case BUSY_STATUS:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		GetBusy(interp, busyTablePtr, objv[2]) != NULL));
	return TCL_OK;
    }

    Tcl_Panic("unhandled option: %d", index);
    return TCL_ERROR;		/* Unreachable */
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted generic/tkBusy.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
 * tkBusy.h --
 *
 *	This file defines the type of the structure describing a busy window.
 *
 * Copyright 1993-1998 Lucent Technologies, Inc.
 *
 *	The "busy" command was created by George Howlett. Adapted for
 *	integration into Tk by Jos Decoster and Donal K. Fellows.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

typedef struct Busy {
    Display *display;		/* Display of busy window */
    Tcl_Interp *interp;		/* Interpreter where "busy" command was
				 * created. It's used to key the searches in
				 * the window hierarchy. See the "windows"
				 * command. */
    Tk_Window tkBusy;		/* Busy window: Transparent window used to
				 * block delivery of events to windows
				 * underneath it. */
    Tk_Window tkParent;		/* Parent window of the busy window. It may be
				 * the reference window (if the reference is a
				 * toplevel) or a mutual ancestor of the
				 * reference window */
    Tk_Window tkRef;		/* Reference window of the busy window. It is
				 * used to manage the size and position of the
				 * busy window. */
    int x, y;			/* Position of the reference window */
    int width, height;		/* Size of the reference window. Retained to
				 * know if the reference window has been
				 * reconfigured to a new size. */
    int menuBar;		/* Menu bar flag. */
    Tk_Cursor cursor;		/* Cursor for the busy window. */
    Tcl_HashEntry *hashPtr;	/* Used the delete the busy window entry out
				 * of the global hash table. */
    Tcl_HashTable *tablePtr;
    Tk_OptionTable optionTable;
} Busy;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































Changes to generic/tkButton.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkButton.h"
#include "default.h"

typedef struct {
    int defaultsInitialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Class names for buttons, indexed by one of the type values defined in
 * tkButton.h.







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkButton.h"
#include "default.h"

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.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
/*
 * Information used for parsing configuration options.  There is a
 * separate table for each of the four widget classes.
 */

static const Tk_OptionSpec labelOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec buttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
        DEF_BUTTON_DEFAULT, TCL_INDEX_NONE, offsetof(TkButton, defaultState),
	0, defaultStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, offsetof(TkButton, offValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 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.
 */

static const Tk_OptionSpec *const optionSpecs[] = {
    labelOptionSpecs,
    buttonOptionSpecs,
    checkbuttonOptionSpecs,
    radiobuttonOptionSpecs
};

/*
 * The following tables define the widget commands supported by each of the
 * classes, and map the indexes into the string tables into a single
 * enumerated type used to dispatch the widget command.
 */

static const char *const commandNames[][8] = {
    {"cget", "configure", NULL},
    {"cget", "configure", "flash", "invoke", NULL},
    {"cget", "configure", "deselect", "flash", "invoke", "select",
	    "toggle", NULL},
    {"cget", "configure", "deselect", "flash", "invoke", "select", NULL}
};
enum command {
    COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
    COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE
};
static const enum command map[][8] = {
    {COMMAND_CGET, COMMAND_CONFIGURE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_FLASH, COMMAND_INVOKE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
	    COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
	    COMMAND_INVOKE, COMMAND_SELECT}
};







|
|

|
|

|

|
|

|

|

|


|
|

|
|

|



|


|

|

|

|


|


|



|
|

|


|

|
|

|
|

|

|
|

|


|

|


|

|

|
|





|
|

|
|

|

|
|

|

|

|


|
|

|


|
|

|


|
|


|


|

|

|

|


|


|



|
|

|


|

|


|
|

|
|

|


|


|


|
|

|


|

|


|

|

|
|
|




|
|

|
|

|

|
|

|

|

|


|
|

|


|
|

|



|


|

|

|

|


|


|



|
|

|


|

|

|

|

|

|


|
|

|
|

|

|
|

|


|
|

|


|

|


|


|

|

|


|

|
|
|




|
|

|
|

|

|
|

|

|

|


|
|

|


|
|

|



|


|

|

|

|


|


|



|
|

|


|


|

|

|


|
|

|
|

|

|
|

|


|
|

|


|

|


|


|

|

|

|


|

|
|
|




















|










|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
/*
 * Information used for parsing configuration options.  There is a
 * separate table for each of the four widget classes.
 */

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},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, (ClientData) DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
	 (ClientData) compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", 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",
	DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	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},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

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},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, (ClientData) DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
	 (ClientData) compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
        DEF_BUTTON_DEFAULT, -1, Tk_Offset(TkButton, defaultState),
	0, (ClientData) defaultStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", 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",
	DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	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),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, -1, Tk_Offset(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, -1, Tk_Offset(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

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},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, (ClientData) DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
	 (ClientData) compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", 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",
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, Tk_Offset(TkButton, offValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	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},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_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",
	DEF_CHECKBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

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},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, (ClientData) DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
	 (ClientData) compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", 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",
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	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},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder),
	TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_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",
	DEF_BUTTON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, 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.
 */

static const Tk_OptionSpec *const optionSpecs[] = {
    labelOptionSpecs,
    buttonOptionSpecs,
    checkbuttonOptionSpecs,
    radiobuttonOptionSpecs
};

/*
 * The following tables define the widget commands supported by each of the
 * classes, and map the indexes into the string tables into a single
 * enumerated type used to dispatch the widget command.
 */

static const char *commandNames[][8] = {
    {"cget", "configure", NULL},
    {"cget", "configure", "flash", "invoke", NULL},
    {"cget", "configure", "deselect", "flash", "invoke", "select",
	    "toggle", NULL},
    {"cget", "configure", "deselect", "flash", "invoke", "select", NULL}
};
enum command {
    COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
    COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE
};
static enum command map[][8] = {
    {COMMAND_CGET, COMMAND_CONFIGURE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_FLASH, COMMAND_INVOKE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
	    COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE},
    {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
	    COMMAND_INVOKE, COMMAND_SELECT}
};
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonCreate(
    ClientData dummy,	/* 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));
    (void)dummy;

    if (!tsdPtr->defaultsInitialized) {
	TkpButtonSetDefaults();
	tsdPtr->defaultsInitialized = 1;
    }

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
     * Create the new window.
     */








|












<







|







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
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));


    if (!tsdPtr->defaultsInitialized) {
	TkpButtonSetDefaults();
	tsdPtr->defaultsInitialized = 1;
    }

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    /*
     * Create the new window.
     */

669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]);

    Tk_SetClass(tkwin, classNames[type]);
    butPtr = TkpCreateButton(tkwin);

    Tk_SetClassProcs(tkwin, &tkpButtonProcs, butPtr);

    /*
     * Initialize the data structure for the button.
     */

    butPtr->tkwin = tkwin;
    butPtr->display = Tk_Display(tkwin);
    butPtr->interp = interp;
    butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
	    ButtonWidgetObjCmd, butPtr, ButtonCmdDeletedProc);
    butPtr->type = type;
    butPtr->optionTable = optionTable;
    butPtr->textPtr = NULL;
    butPtr->underline = -1;
    butPtr->textVarNamePtr = NULL;
    butPtr->bitmap = None;
    butPtr->imagePtr = NULL;







|









|







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]);

    Tk_SetClass(tkwin, classNames[type]);
    butPtr = TkpCreateButton(tkwin);

    Tk_SetClassProcs(tkwin, &tkpButtonProcs, (ClientData) butPtr);

    /*
     * Initialize the data structure for the button.
     */

    butPtr->tkwin = tkwin;
    butPtr->display = Tk_Display(tkwin);
    butPtr->interp = interp;
    butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
	    ButtonWidgetObjCmd, (ClientData) butPtr, ButtonCmdDeletedProc);
    butPtr->type = type;
    butPtr->optionTable = optionTable;
    butPtr->textPtr = NULL;
    butPtr->underline = -1;
    butPtr->textVarNamePtr = NULL;
    butPtr->bitmap = None;
    butPtr->imagePtr = NULL;
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
    butPtr->cursor = NULL;
    butPtr->takeFocusPtr = NULL;
    butPtr->commandPtr = NULL;
    butPtr->flags = 0;

    Tk_CreateEventHandler(butPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ButtonEventProc, butPtr);

    if (Tk_InitOptions(interp, butPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(butPtr->tkwin));

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --







|

|









|
>







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
    butPtr->cursor = NULL;
    butPtr->takeFocusPtr = NULL;
    butPtr->commandPtr = NULL;
    butPtr->flags = 0;

    Tk_CreateEventHandler(butPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ButtonEventProc, (ClientData) butPtr);

    if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(butPtr->tkwin),
	    -1);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827
828
829
830

831
832
833
834
835
836
837
static int
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;
    int result;
    Tcl_Obj *objPtr;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames[butPtr->type],
	    sizeof(char *), "option", 0, &index);
    if (result != TCL_OK) {
	return result;
    }
    Tcl_Preserve(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, butPtr,
		butPtr->optionTable, objv[2], butPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, butPtr,
		    butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    butPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    result = ConfigureButton(interp, butPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DESELECT:
	if (objc > 2) {







|





|


|
|



|







|



|
|
>




|




|
|
>







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
static int
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;
    int result;
    Tcl_Obj *objPtr;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObj(interp, objv[1], commandNames[butPtr->type],
	    "option", 0, &index);
    if (result != TCL_OK) {
	return result;
    }
    Tcl_Preserve((ClientData) butPtr);

    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);
	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;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureButton(interp, butPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DESELECT:
	if (objc > 2) {
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
		    Tk_SetBackgroundFromBorder(butPtr->tkwin,
			    butPtr->activeBorder);
		} else {
		    butPtr->state = STATE_NORMAL;
		    Tk_SetBackgroundFromBorder(butPtr->tkwin,
			    butPtr->normalBorder);
		}
		TkpDisplayButton(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, butPtr);
		(void)XFlush(butPtr->display);
		#ifndef MAC_OSX_TK
		/*
		 * On the mac you can not sleep in a display proc, and the
		 * flash command doesn't do anything anyway.
		 */
		Tcl_Sleep(50);
		#endif
	    }
	}
	break;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");







|







|
|
<
<
<
<
<

<







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884





885

886
887
888
889
890
891
892
		    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;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
		(butPtr->flags & SELECTED) ? butPtr->offValuePtr
		: butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
		== NULL) {
	    goto error;
	}
	break;
    }
    Tcl_Release(butPtr);
    return result;

  error:
    Tcl_Release(butPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyButton --







|



|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
		(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:
    Tcl_Release((ClientData) butPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyButton --
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
DestroyButton(
    TkButton *butPtr)		/* Info about button widget. */
{
    butPtr->flags |= BUTTON_DELETED;
    TkpDestroyButton(butPtr);

    if (butPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
    }

    /*
     * 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);
    if (butPtr->textVarNamePtr != NULL) {
	Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, butPtr);
    }
    if (butPtr->image != NULL) {
	Tk_FreeImage(butPtr->image);
    }
    if (butPtr->selectImage != NULL) {
	Tk_FreeImage(butPtr->selectImage);
    }







|









|
|
|







951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
DestroyButton(
    TkButton *butPtr)		/* Info about button widget. */
{
    butPtr->flags |= BUTTON_DELETED;
    TkpDestroyButton(butPtr);

    if (butPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd);
    if (butPtr->textVarNamePtr != NULL) {
	Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, (ClientData) butPtr);
    }
    if (butPtr->image != NULL) {
	Tk_FreeImage(butPtr->image);
    }
    if (butPtr->selectImage != NULL) {
	Tk_FreeImage(butPtr->selectImage);
    }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    if (butPtr->copyGC != NULL) {
	Tk_FreeGC(butPtr->display, butPtr->copyGC);
    }
    if (butPtr->textLayout != NULL) {
	Tk_FreeTextLayout(butPtr->textLayout);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, butPtr);
    }
    Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable,
	    butPtr->tkwin);
    butPtr->tkwin = NULL;
    Tcl_EventuallyFree(butPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureButton --
 *







|
|
|




|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
    if (butPtr->copyGC != NULL) {
	Tk_FreeGC(butPtr->display, butPtr->copyGC);
    }
    if (butPtr->textLayout != NULL) {
	Tk_FreeTextLayout(butPtr->textLayout);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, (ClientData) butPtr);
    }
    Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable,
	    butPtr->tkwin);
    butPtr->tkwin = NULL;
    Tcl_EventuallyFree((ClientData) butPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureButton --
 *
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureButton(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error, haveImage;
    Tk_Image image;

    /*
     * Eliminate any existing trace on variables monitored by the button.
     */

    if (butPtr->textVarNamePtr != NULL) {
	Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, butPtr);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, 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.
     */

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, butPtr,
		    butPtr->optionTable, objc, objv,
		    butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|














|
|
|


|
|
|















|







1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error, haveImage;
    Tk_Image image;

    /*
     * Eliminate any existing trace on variables monitored by the button.
     */

    if (butPtr->textVarNamePtr != NULL) {
	Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, (ClientData) butPtr);
    }
    if (butPtr->selVarNamePtr != NULL) {
	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.
     */

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) butPtr,
		    butPtr->optionTable, objc, objv,
		    butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
	}

	if (butPtr->type >= TYPE_CHECK_BUTTON) {
	    Tcl_Obj *valuePtr, *namePtr;

	    if (butPtr->selVarNamePtr == NULL) {
		butPtr->selVarNamePtr = Tcl_NewStringObj(
			Tk_Name(butPtr->tkwin), TCL_INDEX_NONE);
		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,







|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
	}

	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,
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

		/*
		 * If a radiobutton has the empty string as value it should be
		 * selected.
		 */

 		if ((butPtr->type == TYPE_RADIO_BUTTON) &&
			(*Tcl_GetString(butPtr->onValuePtr) == '\0')) {
		    butPtr->flags |= SELECTED;
		}
	    }
	}

	/*
	 * 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,
		    butPtr);
	    if (image == NULL) {
		continue;
	    }
	} else {
	    image = NULL;
	}
	if (butPtr->image != NULL) {
	    Tk_FreeImage(butPtr->image);
	}
	butPtr->image = image;
	if (butPtr->selectImagePtr != NULL) {
	    image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
		    Tcl_GetString(butPtr->selectImagePtr),
		    ButtonSelectImageProc, butPtr);
	    if (image == NULL) {
		continue;
	    }
	} else {
	    image = NULL;
	}
	if (butPtr->selectImage != NULL) {
	    Tk_FreeImage(butPtr->selectImage);
	}
	butPtr->selectImage = image;
	if (butPtr->tristateImagePtr != NULL) {
	    image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
		    Tcl_GetString(butPtr->tristateImagePtr),
		    ButtonTristateImageProc, butPtr);
	    if (image == NULL) {
		continue;
	    }
	} else {
	    image = NULL;
	}
	if (butPtr->tristateImage != NULL) {







|














|













|













|







1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

		/*
		 * If a radiobutton has the empty string as value it should be
		 * selected.
		 */

 		if ((butPtr->type == TYPE_RADIO_BUTTON) &&
			(*Tcl_GetString(butPtr->onValuePtr) == 0)) {
		    butPtr->flags |= SELECTED;
		}
	    }
	}

	/*
	 * 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,
		    (ClientData) butPtr);
	    if (image == NULL) {
		continue;
	    }
	} else {
	    image = NULL;
	}
	if (butPtr->image != NULL) {
	    Tk_FreeImage(butPtr->image);
	}
	butPtr->image = image;
	if (butPtr->selectImagePtr != NULL) {
	    image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
		    Tcl_GetString(butPtr->selectImagePtr),
		    ButtonSelectImageProc, (ClientData) butPtr);
	    if (image == NULL) {
		continue;
	    }
	} else {
	    image = NULL;
	}
	if (butPtr->selectImage != NULL) {
	    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) {
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
    }

    /*
     * Reestablish the variable traces, if they're needed.
     */

    if (butPtr->textVarNamePtr != NULL) {
	Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, butPtr);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, butPtr);
    }

    TkButtonWorldChanged(butPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }







|
|
|


|
|
|


|







1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
    }

    /*
     * Reestablish the variable traces, if they're needed.
     */

    if (butPtr->textVarNamePtr != NULL) {
	Tcl_TraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonTextVarProc, (ClientData) butPtr);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_TraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, (ClientData) butPtr);
    }

    TkButtonWorldChanged((ClientData) butPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }
1345
1346
1347
1348
1349
1350
1351
1352


1353
1354
1355
1356
1357
1358
1359
void
TkButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    TkButton *butPtr = (TkButton *)instanceData;



    /*
     * Recompute GCs.
     */

    gcValues.font = Tk_FontId(butPtr->tkfont);
    gcValues.foreground = butPtr->normalFg->pixel;







|
>
>







1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
void
TkButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    TkButton *butPtr;

    butPtr = (TkButton *) instanceData;

    /*
     * Recompute GCs.
     */

    gcValues.font = Tk_FontId(butPtr->tkfont);
    gcValues.foreground = butPtr->normalFg->pixel;
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
    TkpComputeButtonGeometry(butPtr);

    /*
     * Lastly, arrange for the button to be redisplayed.
     */

    if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *







|







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
    TkpComputeButtonGeometry(butPtr);

    /*
     * Lastly, arrange for the button to be redisplayed.
     */

    if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
 */

static void
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.
	 */







|







1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
 */

static void
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.
	 */
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
	    }
	}
    }
    return;

  redraw:
    if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
	    }
	}
    }
    return;

  redraw:
    if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
 *----------------------------------------------------------------------
 */

static void
ButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkButton *butPtr = (TkButton *)clientData;

    /*
     * 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.
     */







|







1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
 *----------------------------------------------------------------------
 */

static void
ButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkButton *butPtr = (TkButton *) clientData;

    /*
     * 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.
     */
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
 *
 * Side effects:
 *	The button may become selected or deselected.
 *
 *--------------------------------------------------------------
 */


static char *
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. */
{
    TkButton *butPtr = (TkButton *)clientData;
    const char *value;
    Tcl_Obj *valuePtr;
    (void)name1;
    (void)name2;

    /*
     * 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 | TRISTATED);
	if (!Tcl_InterpDeleted(interp)) {
	    ClientData probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->selVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonVarProc, probe);
		if (probe == (ClientData)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * selVarNamePtr, which means it is not unset and not
		 * the cause of this unset trace. Instead some outdated
		 * former variable must be, and we should ignore it.
		 */
		goto redisplay;
	    }
	    Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ButtonVarProc, clientData);
	}
	goto redisplay;
    }

    /*
     * Use the value of the variable to update the selected status of the
     * button.
     */

    valuePtr = Tcl_ObjGetVar2(interp, butPtr->selVarNamePtr, NULL,
	    TCL_GLOBAL_ONLY);
    if (valuePtr == NULL) {
	value = Tcl_GetString(butPtr->tristateValuePtr);
    } else {
	value = Tcl_GetString(valuePtr);
    }
    if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
	if (butPtr->flags & SELECTED) {
	    return NULL;
	}
	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 NULL;
    }

  redisplay:
    if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *--------------------------------------------------------------







>








|
|

|
|







|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|










<
|











|




















|







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626


1627



1628














1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
 *
 * Side effects:
 *	The button may become selected or deselected.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
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;
    Tcl_Obj *valuePtr;

    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 (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,
		    ButtonVarProc, clientData);
	}
	goto redisplay;
    }

    /*
     * 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 = Tcl_GetString(butPtr->tristateValuePtr);
    } else {
	value = Tcl_GetString(valuePtr);
    }
    if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
	if (butPtr->flags & SELECTED) {
	    return NULL;
	}
	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 NULL;
    }

  redisplay:
    if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *--------------------------------------------------------------
1711
1712
1713
1714
1715
1716
1717

1718
1719
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733


1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
 *
 * Side effects:
 *	The text displayed in the button will change to match the variable.
 *
 *--------------------------------------------------------------
 */


static char *
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;

    Tcl_Obj *valuePtr;
    (void)name1;
    (void)name2;

    if (butPtr->flags & BUTTON_DELETED) {
	return NULL;
    }



    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) {

	    /*
	     * An unset trace on some variable brought us here, but is it
	     * the variable we have stored in butPtr->textVarNamePtr ?
	     */

	    ClientData probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->textVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonTextVarProc, probe);
		if (probe == (ClientData)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * textVarNamePtr, which means it is not unset and not
		 * the cause of this unset trace. Instead some outdated
		 * former textvariable must be, and we should ignore it.
		 */
		return NULL;
	    }

	    Tcl_ObjSetVar2(interp, butPtr->textVarNamePtr, NULL,
		    butPtr->textPtr, TCL_GLOBAL_ONLY);
	    Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ButtonTextVarProc, clientData);
	}
	return NULL;
    }

    valuePtr = Tcl_ObjGetVar2(interp, butPtr->textVarNamePtr, NULL,
	    TCL_GLOBAL_ONLY);
    if (valuePtr == NULL) {
	valuePtr = Tcl_NewObj();
    }
    Tcl_DecrRefCount(butPtr->textPtr);
    butPtr->textPtr = valuePtr;
    Tcl_IncrRefCount(butPtr->textPtr);
    TkpComputeButtonGeometry(butPtr);

    if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







>








|
>

<
<




>
>







<
|
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|





<
|










|







1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708


1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

1722




1723





1724














1725



1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
 *
 * Side effects:
 *	The text displayed in the button will change to match the variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
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 NULL;
    }

    name = Tcl_GetString(butPtr->textVarNamePtr);

    /*
     * 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_GLOBAL_ONLY);














	    Tcl_TraceVar(interp, name,



		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ButtonTextVarProc, clientData);
	}
	return NULL;
    }


    valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
    if (valuePtr == NULL) {
	valuePtr = Tcl_NewObj();
    }
    Tcl_DecrRefCount(butPtr->textPtr);
    butPtr->textPtr = valuePtr;
    Tcl_IncrRefCount(butPtr->textPtr);
    TkpComputeButtonGeometry(butPtr);

    if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
    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. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
	if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	    butPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------







|
<
<
<
<
<
<




|







1769
1770
1771
1772
1773
1774
1775
1776






1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
    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;







    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
	if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	    butPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
    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. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*
     * Don't recompute geometry: it's controlled by the primary image.
     */
#endif

    if ((butPtr->flags & SELECTED) && (butPtr->tkwin != NULL)
	    && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|
<
<
<
<
<
<

<
<
<
<
<



<




|







1807
1808
1809
1810
1811
1812
1813
1814






1815





1816
1817
1818

1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
    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 & SELECTED) && (butPtr->tkwin != NULL)
	    && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
    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. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*
     * Don't recompute geometry: it's controlled by the primary image.
     */
#endif

    if ((butPtr->flags & TRISTATED) && (butPtr->tkwin != NULL)
	    && Tk_IsMapped(butPtr->tkwin)
	    && !(butPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	butPtr->flags |= REDRAW_PENDING;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
<
<
<
<
<
<

<
<
<
<
<



<




|











1848
1849
1850
1851
1852
1853
1854
1855






1856





1857
1858
1859

1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
    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:
 */

Changes to generic/tkButton.h.

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#define TRISTATED		(1 << 4)

/*
 * Declaration of button class functions structure
 * and button/label defaults, for use in optionSpecs.
 */

MODULE_SCOPE const 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];







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#define TRISTATED		(1 << 4)

/*
 * Declaration of button class functions structure
 * and button/label defaults, for use in optionSpecs.
 */

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];

Changes to generic/tkCanvArc.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * tkCanvArc.c --
 *
 *	This file implements arc items for canvas 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.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

#include "float.h"

/*
 * The structure below defines the record for each arc item.
 */

typedef enum {
    PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE












|
|
<
<
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
22
/*
 * tkCanvArc.c --
 *
 *	This file implements arc items for canvas 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.
 */

#include <stdio.h>
#include "tkInt.h"


#include "tkCanvas.h"

/*
 * The structure below defines the record for each arc item.
 */

typedef enum {
    PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98

99
100
101

102
103
104

105
106
107

108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    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). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */
    double height;              /* Distance from the arc's chord to its
				 * mid-point. */
    double startPoint[2];       /* Start point of arc used when specifying
				 * height. */
    double endPoint[2];         /* End point of arc used when specifying
				 * height. */
} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

#define CHORD_OUTLINE_PTS	7
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(ClientData clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, const char *value,
		    char *widgRec, TkSizeT offset);
static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
		    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr);

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption styleOption = {

    StyleParseProc, StylePrintProc, NULL
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {

    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {

    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
static const Tk_CustomOption pixelOption = {

    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", offsetof(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-height", NULL, NULL,
	0, offsetof(ArcItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(ArcItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
	"0", offsetof(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
	NULL, offsetof(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
	&styleOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
	&pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

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 void		ComputeArcParametersFromHeight(ArcItem *arcPtr);
static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(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(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(double x, double y1,
			    double y2, double rx, double ry,
			    double start, double extent);
static void		RotateArc(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);

/*
 * The structures below defines the arc item types by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkArcType = {







<
<
<
<
<
<
















|
|
|
|

|
>
|

|
>
|

|
>
|

|
>
|

|
>
|

|
>
|


|

|


|

|

|

|

|


|


|

|


|

|

|

|

|


|

|
<
<

|


|

|


|

|

|

|

|




|

|









|
<


|






|




















<
<







59
60
61
62
63
64
65






66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214


215
216
217
218
219
220
221
    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). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */






} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

#define CHORD_OUTLINE_PTS	7
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(ClientData clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, CONST char *value,
		    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,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption styleOption = {
    (Tk_OptionParseProc *) StyleParseProc,
    StylePrintProc, (ClientData) NULL
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_CustomOption dashOption = {
    (Tk_OptionParseProc *) TkCanvasDashParseProc,
    TkCanvasDashPrintProc, (ClientData) NULL
};
static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE)
};
static Tk_CustomOption pixelOption = {
    (Tk_OptionParseProc *) TkPixelParseProc,
    TkPixelPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, 0},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, 0},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK, 0},


    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	"black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, 0},
    {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
	"0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, 0},
    {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, 0},
    {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
	NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
	&styleOption},
    {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, NULL, NULL, NULL, NULL, 0, 0, 0}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(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(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(double x, double y1,
			    double y2, double rx, double ry,
			    double start, double extent);



/*
 * The structures below defines the arc item types by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkArcType = {
242
243
244
245
246
247
248
249
250
251




252
253
254
255
256
257
258
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateArc,			/* rotateProc */
    0, NULL, NULL
};





/*
 *--------------------------------------------------------------
 *
 * CreateArc --
 *
 *	This function is invoked to create a new arc item in a canvas.







<
<

>
>
>
>







235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250
251
252
253
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */


};

#ifndef PI
#define PI	3.14159265358979323846
#endif

/*
 *--------------------------------------------------------------
 *
 * CreateArc --
 *
 *	This function is invoked to create a new arc item in a canvas.
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
     * errors during the the remainder of this function.
     */








|





|







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
static int
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) {
	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 function.
     */

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = NULL;
    arcPtr->height = 0;

    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (ArcCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;







<






|







297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = NULL;


    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (ArcCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365

366

367

368

369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
static int
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 *objs[4];


	objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]);

	objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]);

	objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]);

	objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]);

	Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
    } 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) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
 		    &arcPtr->bbox[0]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}

	/*
	 * Store bbox as start and end points so they can be used if either
	 * radius or height is specified.
	 */

	arcPtr->startPoint[0] = arcPtr->bbox[0];
	arcPtr->startPoint[1] = arcPtr->bbox[1];
	arcPtr->endPoint[0] = arcPtr->bbox[2];
	arcPtr->endPoint[1] = arcPtr->bbox[3];

	ComputeArcBbox(canvas, arcPtr);
    } else {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|




|
>

<
>
|
>
|
>
|
>
|
|
|




>
|
|
|
<













<
<
<
<
<
<
<
<
<
<
<


>
|
|
|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390











391
392
393
394
395
396
397
398
399
400
401
402
403
static int
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);
	subobj = Tcl_NewDoubleObj(arcPtr->bbox[2]);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	subobj = Tcl_NewDoubleObj(arcPtr->bbox[3]);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	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];

		sprintf(buf, "wrong # coordinates: expected 4, got %d", objc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);

		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
 		    &arcPtr->bbox[0]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}











	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;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

static int
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;
    GC newGC;
    unsigned long mask;
    int i;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) arcPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as style and







|















|







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

static int
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;
    GC newGC;
    unsigned long mask;
    int i;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) arcPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as style and
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508








509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    /*
     * Override the start and extent if the height is given.
     */

    ComputeArcParametersFromHeight(arcPtr);

    ComputeArcBbox(canvas, arcPtr);

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
    }
    if (flags & TK_OFFSET_TOP) {
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }









    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }
    if (arcPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), arcPtr->outline.gc);
    }
    arcPtr->outline.gc = newGC;

    if(state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (state==TK_STATE_HIDDEN) {
	ComputeArcBbox(canvas, arcPtr);
	return TCL_OK;
    }

    color = arcPtr->fillColor;
    stipple = arcPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->activeFillColor!=NULL) {
	    color = arcPtr->activeFillColor;
	}
	if (arcPtr->activeFillStipple!=None) {
	    stipple = arcPtr->activeFillStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->disabledFillColor!=NULL) {
	    color = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    stipple = arcPtr->disabledFillStipple;
	}
    }

    if (arcPtr->style == ARC_STYLE) {
	newGC = NULL;
    } else if (color == NULL) {
	newGC = NULL;
    } else {
	gcValues.foreground = color->pixel;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















>
>
>
>
>
>
>
>















|








|













|







458
459
460
461
462
463
464
















465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

















    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
    }
    if (flags & TK_OFFSET_TOP) {
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }
    if (arcPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), arcPtr->outline.gc);
    }
    arcPtr->outline.gc = newGC;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (state==TK_STATE_HIDDEN) {
	ComputeArcBbox(canvas, arcPtr);
	return TCL_OK;
    }

    color = arcPtr->fillColor;
    stipple = arcPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->activeFillColor!=NULL) {
	    color = arcPtr->activeFillColor;
	}
	if (arcPtr->activeFillStipple!=None) {
	    stipple = arcPtr->activeFillStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->disabledFillColor!=NULL) {
	    color = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    stipple = arcPtr->disabledFillStipple;
	}
      }

    if (arcPtr->style == ARC_STYLE) {
	newGC = NULL;
    } else if (color == NULL) {
	newGC = NULL;
    } else {
	gcValues.foreground = color->pixel;
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ComputeArcParametersFromHeight --
 *
 *	This function calculates the arc parameters given start-point,
 *	end-point and height (!= 0).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The height parameter is set to 0 on exit.
 *
 *--------------------------------------------------------------
 */

static void
ComputeArcParametersFromHeight(
    ArcItem* arcPtr)
{
    double chordLen, chordDir[2], chordCen[2], arcCen[2], d, radToDeg, radius;

    /*
     * Do nothing if no height has been specified.
     */

    if (arcPtr->height == 0)
        return;

    /*
     * Calculate the chord length, return early if it is too small.
     */

    chordLen = hypot(arcPtr->endPoint[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcPtr->endPoint[0]);

    if (chordLen < DBL_EPSILON) {
        arcPtr->start = arcPtr->extent = arcPtr->height = 0;
        return;
    }

    chordDir[0] = (arcPtr->endPoint[0] - arcPtr->startPoint[0]) / chordLen;
    chordDir[1] = (arcPtr->endPoint[1] - arcPtr->startPoint[1]) / chordLen;
    chordCen[0] = (arcPtr->startPoint[0] + arcPtr->endPoint[0]) / 2;
    chordCen[1] = (arcPtr->startPoint[1] + arcPtr->endPoint[1]) / 2;

    /*
     * Calculate the radius (assumes height != 0).
     */

    radius = (4*pow(arcPtr->height, 2) + pow(chordLen, 2))
	    / (8 * arcPtr->height);

    /*
     * The arc centre.
     */

    d = radius - arcPtr->height;
    arcCen[0] = chordCen[0] - d * chordDir[1];
    arcCen[1] = chordCen[1] + d * chordDir[0];

    /*
     * The arc start and span. Angles are negated because the coordinate
     * system is left-handed.
     */

    radToDeg = 45 / atan(1);
    arcPtr->start = atan2(arcCen[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcCen[0]) * radToDeg;
    arcPtr->extent = -2 * asin(chordLen / (2 * radius)) * radToDeg;

    /*
     * Handle spans > 180.
     */

    if (fabs(2 * arcPtr->height) > chordLen) {
	arcPtr->extent = arcPtr->extent > 0 ? (360 - arcPtr->extent)
		: -(360 + arcPtr->extent);
    }

    /*
     * Create the bounding box.
     */

    arcPtr->bbox[0] = arcCen[0] - radius;
    arcPtr->bbox[1] = arcCen[1] - radius;
    arcPtr->bbox[2] = arcCen[0] + radius;
    arcPtr->bbox[3] = arcCen[1] + radius;

    /*
     * Set the height to 0 so that itemcget -height returns 0.
     */

    arcPtr->height = 0;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with
 *	an arc item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteArc(
    TCL_UNUSED(Tk_Canvas),		/* Info about overall canvas. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    ArcItem *arcPtr = (ArcItem *)itemPtr;

    Tk_DeleteOutline(display, &(arcPtr->outline));
    if (arcPtr->numOutlinePoints != 0) {
	ckfree(arcPtr->outlinePtr);
    }
    if (arcPtr->fillColor != NULL) {
	Tk_FreeColor(arcPtr->fillColor);
    }
    if (arcPtr->activeFillColor != NULL) {
	Tk_FreeColor(arcPtr->activeFillColor);
    }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|



|



|







570
571
572
573
574
575
576

































































































577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *

































































































 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with
 *	an arc item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
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;

    Tk_DeleteOutline(display, &(arcPtr->outline));
    if (arcPtr->numOutlinePoints != 0) {
	ckfree((char *) arcPtr->outlinePtr);
    }
    if (arcPtr->fillColor != NULL) {
	Tk_FreeColor(arcPtr->fillColor);
    }
    if (arcPtr->activeFillColor != NULL) {
	Tk_FreeColor(arcPtr->activeFillColor);
    }
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = arcPtr->outline.width;
    if (width < 1.0) {
	width = 1.0;
    }
    if (state==TK_STATE_HIDDEN) {
	arcPtr->header.x1 = arcPtr->header.x2 =
	arcPtr->header.y1 = arcPtr->header.y2 = -1;
	return;
    } else if (Canvas(canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = arcPtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = arcPtr->outline.disabledWidth;
	}
    }

    /*
     * Make sure that the first coordinates are the lowest ones.
     */

    if (arcPtr->bbox[1] > arcPtr->bbox[3]) {
	tmp = arcPtr->bbox[3];

	arcPtr->bbox[3] = arcPtr->bbox[1];
	arcPtr->bbox[1] = tmp;
    }
    if (arcPtr->bbox[0] > arcPtr->bbox[2]) {
	tmp = arcPtr->bbox[2];

	arcPtr->bbox[2] = arcPtr->bbox[0];
	arcPtr->bbox[0] = tmp;
    }

    ComputeArcOutline(canvas,arcPtr);

    /*
     * To compute the bounding box, start with 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];
    arcPtr->header.y1 = arcPtr->header.y2 = (int) arcPtr->center1[1];







>










|










|














|





|








|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = arcPtr->outline.width;
    if (width < 1.0) {
	width = 1.0;
    }
    if (state==TK_STATE_HIDDEN) {
	arcPtr->header.x1 = arcPtr->header.x2 =
	arcPtr->header.y1 = arcPtr->header.y2 = -1;
	return;
    } else if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = arcPtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = arcPtr->outline.disabledWidth;
	}
    }

    /*
     * Make sure that the first coordinates are the lowest ones.
     */

    if (arcPtr->bbox[1] > 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 = arcPtr->bbox[2];

	arcPtr->bbox[2] = arcPtr->bbox[0];
	arcPtr->bbox[0] = tmp;
    }

    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.
     */

    arcPtr->header.x1 = arcPtr->header.x2 = (int) arcPtr->center1[0];
    arcPtr->header.y1 = arcPtr->header.y2 = (int) arcPtr->center1[1];
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

static void
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. */
    TCL_UNUSED(int),		/* Describes region of canvas that must be */
    TCL_UNUSED(int),	/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    short x1, y1, x2, y2;
    int start, extent, dashnumber;
    double lineWidth;
    Tk_State state = itemPtr->state;
    Pixmap stipple;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    lineWidth = arcPtr->outline.width;
    if (lineWidth < 1.0) {
	lineWidth = 1.0;
    }
    dashnumber = arcPtr->outline.dash.number;
    stipple = arcPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>lineWidth) {
	    lineWidth = arcPtr->outline.activeWidth;
	}
	if (arcPtr->outline.activeDash.number != 0) {
	    dashnumber = arcPtr->outline.activeDash.number;
	}
	if (arcPtr->activeFillStipple != None) {







|
|
<
<









|







|







779
780
781
782
783
784
785
786
787


788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812

static void
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;
    int start, extent, dashnumber;
    double lineWidth;
    Tk_State state = itemPtr->state;
    Pixmap stipple;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    lineWidth = arcPtr->outline.width;
    if (lineWidth < 1.0) {
	lineWidth = 1.0;
    }
    dashnumber = arcPtr->outline.dash.number;
    stipple = arcPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>lineWidth) {
	    lineWidth = arcPtr->outline.activeWidth;
	}
	if (arcPtr->outline.activeDash.number != 0) {
	    dashnumber = arcPtr->outline.activeDash.number;
	}
	if (arcPtr->activeFillStipple != None) {
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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;
    double poly[8], polyDist, width, t1, t2;
    int filled, angleInRange;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = (double) arcPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = (double) arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = (double) arcPtr->outline.disabledWidth;
	}







>













|



|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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;
    double poly[8], polyDist, width, t1, t2;
    int filled, angleInRange;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = (double) arcPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = (double) arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = (double) arcPtr->outline.disabledWidth;
	}
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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. */
{







>







1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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. */
{
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
				 * 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;

    if(state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = (double) arcPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = (double) arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = (double) arcPtr->outline.disabledWidth;
	}







|


|







1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
				 * 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;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    width = (double) arcPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeWidth>width) {
	    width = (double) arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>0) {
	    width = (double) arcPtr->outline.disabledWidth;
	}
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
    arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);
    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateArc --
 *
 *	This function is called to rotate an arc by a given amount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the arc is rotated by angleRad radians about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateArc(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double newX, newY, oldX, oldY;

    /*
     * Compute the centre of the box, then rotate that about the origin.
     */

    newX = oldX = (arcPtr->bbox[0] + arcPtr->bbox[2]) / 2.0;
    newY = oldY = (arcPtr->bbox[1] + arcPtr->bbox[3]) / 2.0;
    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &newX, &newY);

    /*
     * Apply the translation to the box.
     */

    arcPtr->bbox[0] += newX - oldX;
    arcPtr->bbox[1] += newY - oldY;
    arcPtr->bbox[2] += newX - oldX;
    arcPtr->bbox[3] += newY - oldY;

    /*
     * TODO: update the arc endpoints?
     */

    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateArc --
 *
 *	This function is called to move an arc by a given amount.
 *
 * Results:
 *	None.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1390
1391
1392
1393
1394
1395
1396






















































1397
1398
1399
1400
1401
1402
1403
    arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);
    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *






















































 * TranslateArc --
 *
 *	This function is called to move an arc by a given amount.
 *
 * Results:
 *	None.
 *
1627
1628
1629
1630
1631
1632
1633
1634

1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655

    /*
     * Make sure that the outlinePtr array is large enough to hold either a
     * chord or pie-slice outline.
     */

    if (arcPtr->numOutlinePoints == 0) {
	arcPtr->outlinePtr = (double *)ckalloc(26 * sizeof(double));

	arcPtr->numOutlinePoints = 22;
    }
    outlinePtr = arcPtr->outlinePtr;

    if (state == TK_STATE_NULL) {
	state = Canvas(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:
     *
     *
     *			          * * *
     *			      *          *
     *			   *      * *      *
     *			 *    *         *    *
     *			*   *             *   *
     *			 X *               * X
     *
     * The code is tricky because the arc can be ovular in shape. It computes







|
>





|







|







1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486

    /*
     * Make sure that the outlinePtr array is large enough to hold either a
     * chord or pie-slice outline.
     */

    if (arcPtr->numOutlinePoints == 0) {
	arcPtr->outlinePtr = (double *) ckalloc((unsigned)
		(26 * sizeof(double)));
	arcPtr->numOutlinePoints = 22;
    }
    outlinePtr = arcPtr->outlinePtr;

    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:
     *
     *
     *				  * * *
     *			      *          *
     *			   *      * *      *
     *			 *    *         *    *
     *			*   *             *   *
     *			 X *               * X
     *
     * The code is tricky because the arc can be ovular in shape. It computes
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
     * 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;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
	if (arcPtr->outline.activeWidth>arcPtr->outline.width) {
	    width = arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>arcPtr->outline.width) {
	    width = arcPtr->outline.disabledWidth;
	}







|







1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
     * 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;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
	if (arcPtr->outline.activeWidth>arcPtr->outline.width) {
	    width = arcPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (arcPtr->outline.disabledWidth>arcPtr->outline.width) {
	    width = arcPtr->outline.disabledWidth;
	}
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005

2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
 */

static int
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. */
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;

    double y1, y2, ang1, ang2;
    XColor *color;
    Pixmap stipple;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;

    y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]);
    y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]);
    ang1 = arcPtr->start;
    ang2 = ang1 + arcPtr->extent;
    if (ang2 < ang1) {
	ang1 = ang2;
	ang2 = arcPtr->start;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    color = arcPtr->outline.color;
    stipple = arcPtr->outline.stipple;
    fillColor = arcPtr->fillColor;
    fillStipple = arcPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeColor!=NULL) {
	    color = arcPtr->outline.activeColor;
	}
	if (arcPtr->outline.activeStipple!=None) {
	    stipple = arcPtr->outline.activeStipple;
	}
	if (arcPtr->activeFillColor!=NULL) {







|




>






<
<











|





|







1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843


1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
 */

static int
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];
    double y1, y2, ang1, ang2;
    XColor *color;
    Pixmap stipple;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;



    y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]);
    y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]);
    ang1 = arcPtr->start;
    ang2 = ang1 + arcPtr->extent;
    if (ang2 < ang1) {
	ang1 = ang2;
	ang2 = arcPtr->start;
    }

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    color = arcPtr->outline.color;
    stipple = arcPtr->outline.stipple;
    fillColor = arcPtr->fillColor;
    fillStipple = arcPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (arcPtr->outline.activeColor!=NULL) {
	    color = arcPtr->outline.activeColor;
	}
	if (arcPtr->outline.activeStipple!=None) {
	    stipple = arcPtr->outline.activeStipple;
	}
	if (arcPtr->activeFillColor!=NULL) {
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079

2080
2081
2082
2083
2084
2085
2086
2087

2088
2089
2090
2091
2092
2093
2094

2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118

2119
2120

2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133

2134
2135
2136


2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155


2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
	    fillColor = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    fillStipple = arcPtr->disabledFillStipple;
	}
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * If the arc is filled, output Postscript for the interior region of the
     * arc.
     */

    if (arcPtr->fillGC != NULL) {
	Tcl_AppendPrintfToObj(psObj,
		"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);

	if (arcPtr->style != CHORD_STYLE) {
	    Tcl_AppendToObj(psObj, "0 0 moveto ", -1);

	}
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	    if (arcPtr->outline.gc != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
    }

    /*
     * If there's an outline for the arc, draw it.
     */

    if (arcPtr->outline.gc != NULL) {
	Tcl_AppendPrintfToObj(psObj,
		"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_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc\nsetmatrix\n0 setlinecap\n",
		ang1, ang2);

	Tcl_ResetResult(interp);

	Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (arcPtr->style != ARC_STYLE) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

	    Tcl_ResetResult(interp);
	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		Tk_CanvasPsColor(interp, canvas, color);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", -1);



		    Tcl_ResetResult(interp);
		    Tk_CanvasPsStipple(interp, canvas, stipple);
		    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
		} else {
		    Tcl_AppendToObj(psObj, "fill\n", -1);
		}
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    Tk_CanvasPsColor(interp, canvas, color);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", -1);



		Tcl_ResetResult(interp);
		Tk_CanvasPsStipple(interp, canvas, stipple);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    } else {
		Tcl_AppendToObj(psObj, "fill\n", -1);
	    }
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * StyleParseProc --







<
<
<
<
<
<
<






<
<
|


|
|
|
>
|
|
|
|
|
|
|
<
>
|

<
<
|
|
<
>
|

|


|








<
<
|


|
<
|
<
|
>
|
<
>
|

|
<
<






|
|
>
|

|
>
>
|
<
<
<

|

|
<
<




|
|
>
|

|
>
>
|
<
<
<

|




<
<
<
<
<
<
<







1882
1883
1884
1885
1886
1887
1888







1889
1890
1891
1892
1893
1894


1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911


1912
1913

1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928


1929
1930
1931
1932

1933

1934
1935
1936

1937
1938
1939
1940


1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955



1956
1957
1958
1959


1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972



1973
1974
1975
1976
1977
1978







1979
1980
1981
1982
1983
1984
1985
	    fillColor = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    fillStipple = arcPtr->disabledFillStipple;
	}
    }








    /*
     * If the arc is filled, output Postscript for the interior region of the
     * arc.
     */

    if (arcPtr->fillGC != NULL) {


	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, NULL);
	if (arcPtr->style == CHORD_STYLE) {
	    sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		    ang1, ang2);
	} else {
	    sprintf(buffer,
		    "0 0 moveto 0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		    ang1, ang2);
	}
	Tcl_AppendResult(interp, buffer, NULL);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (fillStipple != None) {


	    Tcl_AppendResult(interp, "clip ", NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {

		return TCL_ERROR;
	    }
	    if (arcPtr->outline.gc != NULL) {
		Tcl_AppendResult(interp, "grestore gsave\n", NULL);
	    }
	} else {
	    Tcl_AppendResult(interp, "fill\n", NULL);
	}
    }

    /*
     * If there's an outline for the arc, draw it.
     */

    if (arcPtr->outline.gc != NULL) {


	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, NULL);

	sprintf(buffer, "0 0 1 %.15g %.15g", ang1, ang2);

	Tcl_AppendResult(interp, buffer,
		" 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", NULL);


	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		if (Tk_CanvasPsColor(interp, canvas, color)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		if (stipple != None) {
		    Tcl_AppendResult(interp, "clip ", NULL);
		    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK){
			return TCL_ERROR;
		    }



		} else {
		    Tcl_AppendResult(interp, "fill\n", NULL);
		}
		Tcl_AppendResult(interp, "grestore gsave\n", NULL);


		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    if (Tk_CanvasPsColor(interp, canvas, color)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (stipple != None) {
		Tcl_AppendResult(interp, "clip ", NULL);
		if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		    return TCL_ERROR;
		}



	    } else {
		Tcl_AppendResult(interp, "fill\n", NULL);
	    }
	}
    }








    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * StyleParseProc --
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204

2205
2206
2207
2208
2209
2210
2211
2212
 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
StyleParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;

    Style *stylePtr = (Style *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;
	return TCL_OK;
    }

    c = value[0];







|

|
|

|



>
|







1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
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) {
	*stylePtr = PIESLICE_STYLE;
	return TCL_OK;
    }

    c = value[0];
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
	return TCL_OK;
    }
    if ((c == 'p') && (strncmp(value, "pieslice", length) == 0)) {
	*stylePtr = PIESLICE_STYLE;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad -style option \"%s\": must be arc, chord, or pieslice",
	    value));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARC_STYLE", NULL);
    *stylePtr = PIESLICE_STYLE;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







|
|
<
<







2028
2029
2030
2031
2032
2033
2034
2035
2036


2037
2038
2039
2040
2041
2042
2043
	return TCL_OK;
    }
    if ((c == 'p') && (strncmp(value, "pieslice", length) == 0)) {
	*stylePtr = PIESLICE_STYLE;
	return TCL_OK;
    }

    Tcl_AppendResult(interp, "bad -style option \"", value,
	    "\": must be arc, chord, or pieslice", NULL);


    *stylePtr = PIESLICE_STYLE;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static const char *
StylePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Ignored. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Style *stylePtr = (Style *) (widgRec + offset);

    if (*stylePtr == ARC_STYLE) {
	return "arc";
    } else if (*stylePtr == CHORD_STYLE) {
	return "chord";
    } else {
	return "pieslice";







|

|
|

|
|



|







2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static char *
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) {
	return "arc";
    } else if (*stylePtr == CHORD_STYLE) {
	return "chord";
    } else {
	return "pieslice";

Changes to generic/tkCanvBmap.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
/*
 * tkCanvBmap.c --
 *
 *	This file implements bitmap items for canvas 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each bitmap item.
 */

typedef struct BitmapItem  {
    Tk_Item header;		/* Generic stuff that's the same for all












>


<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
/*
 * tkCanvBmap.c --
 *
 *	This file implements bitmap items for canvas 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"


/*
 * The structure below defines the record for each bitmap item.
 */

typedef struct BitmapItem  {
    Tk_Item header;		/* Generic stuff that's the same for all
37
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
				 * on screen. */
} BitmapItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-background", NULL, NULL,
	NULL, offsetof(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBitmap),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledFgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
	DEF_CANVBMAP_FG, offsetof(BitmapItem, fgColor), 0, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(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, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static int		BitmapCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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		RotateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double deltaX, double deltaY);

/*







|
>
|

|
>
|


|

|

|

|

|

|

|

|
|

|
|

|
|

|

|



|








|










|


|





<
<







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110


111
112
113
114
115
116
117
				 * on screen. */
} BitmapItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {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", 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", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, disabledBitmap),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, disabledFgColor),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
	"black", Tk_Offset(BitmapItem, fgColor), 0},
    {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 functions defined in this file:
 */

static int		BitmapCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double deltaX, double deltaY);

/*
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateBitmap,		/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * TkcCreateBitmap --
 *







<
<







136
137
138
139
140
141
142


143
144
145
146
147
148
149
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */


};

/*
 *--------------------------------------------------------------
 *
 * TkcCreateBitmap --
 *
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
static int
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;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
     */

    bmapPtr->anchor = TK_ANCHOR_CENTER;







|





|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
static int
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;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords\n");
    }

    /*
     * Initialize item's record.
     */

    bmapPtr->anchor = TK_ANCHOR_CENTER;
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
     * 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 {
	const char *arg = Tcl_GetString(objv[1]);
	i = 2;
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if (BitmapCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;







|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
     * 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;
	}
    }
    if (BitmapCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
242
243
244
245
246
247
248
249
250
251
252
253
254
255

256

257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
static int
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_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->x));

	Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->y));
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&bmapPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
			&bmapPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeBitmapBbox(canvas, bmapPtr);
    } else {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|






>
|
>
|







>
|
|
|
<











>
|
|
|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
static int
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);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf, "wrong # coordinates: expected 2, got %d", objc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);

		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&bmapPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
			&bmapPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeBitmapBbox(canvas, bmapPtr);
    } 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;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

static int
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;
    GC newGC;
    Tk_Window tkwin;
    unsigned long mask;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) bmapPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as those that
     * determine the graphics context.
     */

    state = itemPtr->state;

    if (bmapPtr->activeFgColor!=NULL ||
	    bmapPtr->activeBgColor!=NULL ||
	    bmapPtr->activeBitmap!=None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputeBitmapBbox(canvas, bmapPtr);
	return TCL_OK;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeFgColor!=NULL) {
	    fgColor = bmapPtr->activeFgColor;
	}
	if (bmapPtr->activeBgColor!=NULL) {
	    bgColor = bmapPtr->activeBgColor;
	}
	if (bmapPtr->activeBitmap!=None) {







|














|



















|








|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

static int
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;
    GC newGC;
    Tk_Window tkwin;
    unsigned long mask;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) bmapPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as those that
     * determine the graphics context.
     */

    state = itemPtr->state;

    if (bmapPtr->activeFgColor!=NULL ||
	    bmapPtr->activeBgColor!=NULL ||
	    bmapPtr->activeBitmap!=None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputeBitmapBbox(canvas, bmapPtr);
	return TCL_OK;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeFgColor!=NULL) {
	    fgColor = bmapPtr->activeFgColor;
	}
	if (bmapPtr->activeBgColor!=NULL) {
	    bgColor = bmapPtr->activeBgColor;
	}
	if (bmapPtr->activeBitmap!=None) {
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
static void
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;
    (void)canvas;

    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }







<







419
420
421
422
423
424
425

426
427
428
429
430
431
432
static void
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;


    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
ComputeBitmapBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    BitmapItem *bmapPtr)	/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
    Pixmap bitmap;
    Tk_State state = bmapPtr->header.state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    bitmap = bmapPtr->bitmap;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *)bmapPtr) {
	if (bmapPtr->activeBitmap!=None) {
	    bitmap = bmapPtr->activeBitmap;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (bmapPtr->disabledBitmap!=None) {
	    bitmap = bmapPtr->disabledBitmap;
	}







>











|


|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
ComputeBitmapBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    BitmapItem *bmapPtr)	/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
    Pixmap bitmap;
    Tk_State state = bmapPtr->header.state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    bitmap = bmapPtr->bitmap;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)bmapPtr) {
	if (bmapPtr->activeBitmap!=None) {
	    bitmap = bmapPtr->activeBitmap;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (bmapPtr->disabledBitmap!=None) {
	    bitmap = bmapPtr->disabledBitmap;
	}
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608

    /*
     * 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) {
	state = Canvas(canvas)->canvas_state;
    }
    bitmap = bmapPtr->bitmap;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeBitmap!=None) {
	    bitmap = bmapPtr->activeBitmap;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (bmapPtr->disabledBitmap!=None) {
	    bitmap = bmapPtr->disabledBitmap;
	}







|


|







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

    /*
     * 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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    bitmap = bmapPtr->bitmap;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeBitmap!=None) {
	    bitmap = bmapPtr->activeBitmap;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (bmapPtr->disabledBitmap!=None) {
	    bitmap = bmapPtr->disabledBitmap;
	}
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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;
    (void)canvas;

    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*







>








<







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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;


    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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;
    (void)canvas;

    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }







>









<







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;


    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    bmapPtr->x = originX + scaleX*(bmapPtr->x - originX);
    bmapPtr->y = originY + scaleY*(bmapPtr->y - originY);
    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateBitmap --
 *
 *	This function is called to rotate a bitmap's origin by a given amount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the bitmap is rotated by angleRad radians about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateBitmap(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &bmapPtr->x, &bmapPtr->y);
    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







785
786
787
788
789
790
791

































792
793
794
795
796
797
798
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    bmapPtr->x = originX + scaleX*(bmapPtr->x - originX);
    bmapPtr->y = originY + scaleY*(bmapPtr->y - originY);

































    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --
883
884
885
886
887
888
889

890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
				 * information; 0 means final Postscript is
				 * being created. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x, y;
    int width, height, rowsAtOnce, rowsThisTime;
    int curRow;

    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;
    (void)prepass;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeFgColor!=NULL) {
	    fgColor = bmapPtr->activeFgColor;
	}
	if (bmapPtr->activeBgColor!=NULL) {
	    bgColor = bmapPtr->activeBgColor;
	}
	if (bmapPtr->activeBitmap!=None) {







>




<
<
<


|




|







851
852
853
854
855
856
857
858
859
860
861
862



863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
				 * information; 0 means final Postscript is
				 * being created. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x, y;
    int width, height, rowsAtOnce, rowsThisTime;
    int curRow;
    char buffer[100 + TCL_DOUBLE_SPACE * 2 + TCL_INTEGER_SPACE * 4];
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state = itemPtr->state;




    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (bmapPtr->activeFgColor!=NULL) {
	    fgColor = bmapPtr->activeFgColor;
	}
	if (bmapPtr->activeBgColor!=NULL) {
	    bgColor = bmapPtr->activeBgColor;
	}
	if (bmapPtr->activeBitmap!=None) {
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970

971
972
973
974
975
976
977
978
979
980
981
982
983
984
985

986
987
988
989
990
991
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
    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;
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Color the background, if there is one.
     */

    if (bgColor != NULL) {
	Tcl_AppendPrintfToObj(psObj,
		"%.15g %.15g moveto %d 0 rlineto 0 %d rlineto "
		"%d 0 rlineto closepath\n",
		x, y, width, height, -width);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, bgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	Tcl_AppendToObj(psObj, "fill\n", -1);
    }

    /*
     * 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) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (width > 60000) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't generate Postscript for bitmaps more than 60000"
		    " pixels wide", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	    goto error;

	}

	rowsAtOnce = 60000/width;
	if (rowsAtOnce < 1) {
	    rowsAtOnce = 1;
	}

	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y+height);

	for (curRow = 0; curRow < height; curRow += rowsAtOnce) {
	    rowsThisTime = rowsAtOnce;
	    if (rowsThisTime > (height - curRow)) {
		rowsThisTime = height - curRow;
	    }

	    Tcl_AppendPrintfToObj(psObj,
		    "0 -%.15g translate\n%d %d true matrix {\n",
		    (double) rowsThisTime, width, rowsThisTime);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsBitmap(interp, canvas, bitmap, 0, curRow, width,
		    rowsThisTime);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", -1);
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<





|
|
<
|
<
|
|
<
>
|
|










<
|
<
>
|

|
|
|
<
<
>

<




<
|
|





<
<
|

<
|
|
|
<
|
<
|
<
|
<
<
<
|
<
<
<
<
|
<
<
<
|









910
911
912
913
914
915
916







917
918
919
920
921
922
923

924

925
926

927
928
929
930
931
932
933
934
935
936
937
938
939

940

941
942
943
944
945
946


947
948

949
950
951
952

953
954
955
956
957
958
959


960
961

962
963
964

965

966

967



968




969



970
971
972
973
974
975
976
977
978
979
    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;
    }








    /*
     * Color the background, if there is one.
     */

    if (bgColor != NULL) {
	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, NULL);
	if (Tk_CanvasPsColor(interp, canvas, bgColor) != TCL_OK) {

	    return TCL_ERROR;
	}
	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.
     */

    if (fgColor != NULL) {

	if (Tk_CanvasPsColor(interp, canvas, fgColor) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (width > 60000) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "can't generate Postscript",
		    " for bitmaps more than 60000 pixels wide", NULL);


	    return TCL_ERROR;
	}

	rowsAtOnce = 60000/width;
	if (rowsAtOnce < 1) {
	    rowsAtOnce = 1;
	}

	sprintf(buffer, "%.15g %.15g translate\n", x, y+height);
	Tcl_AppendResult(interp, buffer, NULL);
	for (curRow = 0; curRow < height; curRow += rowsAtOnce) {
	    rowsThisTime = rowsAtOnce;
	    if (rowsThisTime > (height - curRow)) {
		rowsThisTime = height - curRow;
	    }


	    sprintf(buffer, "0 -%.15g translate\n%d %d true matrix {\n",
		    (double) rowsThisTime, width, rowsThisTime);

	    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", NULL);



	}




    }



    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvImg.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
/*
 * tkCanvImg.c --
 *
 *	This file implements image items for canvas 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"

/*
 * The structure below defines the record for each image item.
 */













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tkCanvImg.c --
 *
 *	This file implements image items for canvas 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"

/*
 * The structure below defines the record for each image item.
 */

39
40
41
42
43
44
45
46

47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
				 * image at present. */
} ImageItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, offsetof(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_STRING, "-disabledimage", NULL, NULL,
	NULL, offsetof(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-image", NULL, NULL,
	NULL, offsetof(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(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, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ImageChangedProc(ClientData clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static int		ImageCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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		RotateImage(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*







|
>
|

|
>
|


|

|

|

|

|

|


|











|









|


|





<
<







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
				 * image at present. */
} ImageItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {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", 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 functions defined in this file:
 */

static void		ImageChangedProc(ClientData clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static int		ImageCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateImage,		/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateImage --
 *







<
<







125
126
127
128
129
130
131


132
133
134
135
136
137
138
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */


};

/*
 *--------------------------------------------------------------
 *
 * CreateImage --
 *
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
     */

    imgPtr->canvas = canvas;







|





|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
static int
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) {
	Tcl_Panic("canvas did not pass any coords\n");
    }

    /*
     * Initialize item's record.
     */

    imgPtr->canvas = canvas;
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
     * 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 {
	const char *arg = Tcl_GetString(objv[1]);
	i = 2;
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if ((ImageCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {
	goto error;







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
     * 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;
	}
    }
    if ((ImageCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {
	goto error;
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241

242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
static int
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 *objs[2];

	objs[0] = Tcl_NewDoubleObj(imgPtr->x);

	objs[1] = Tcl_NewDoubleObj(imgPtr->y);

	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &imgPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
  		    &imgPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeImageBbox(canvas, imgPtr);
    } else {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|




|

|
>
|
>
|






>
|
|
|
<



|
<






>
|
|
|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
static int
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);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		char buf[64];

		sprintf(buf, "wrong # coordinates: expected 2, got %d", objc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);

		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &imgPtr->x) != TCL_OK)

		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
  		    &imgPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	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;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

static int
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;
    Tk_Image image;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) imgPtr, flags|TK_CONFIG_OBJS)) {
	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.
     */

    if (imgPtr->activeImageString != NULL) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }
    if (imgPtr->imageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->imageString,
		ImageChangedProc, imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->image != NULL) {
	Tk_FreeImage(imgPtr->image);
    }
    imgPtr->image = image;
    if (imgPtr->activeImageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->activeImageString,
		ImageChangedProc, imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->activeImage != NULL) {
	Tk_FreeImage(imgPtr->activeImage);
    }
    imgPtr->activeImage = image;
    if (imgPtr->disabledImageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->disabledImageString,
		ImageChangedProc, imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->disabledImage != NULL) {







|








|

















|












|












|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

static int
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;
    Tk_Image image;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) imgPtr, flags|TK_CONFIG_OBJS)) {
	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.
     */

    if (imgPtr->activeImageString != NULL) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }
    if (imgPtr->imageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->imageString,
		ImageChangedProc, (ClientData) imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->image != NULL) {
	Tk_FreeImage(imgPtr->image);
    }
    imgPtr->image = image;
    if (imgPtr->activeImageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->activeImageString,
		ImageChangedProc, (ClientData) imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->activeImage != NULL) {
	Tk_FreeImage(imgPtr->activeImage);
    }
    imgPtr->activeImage = image;
    if (imgPtr->disabledImageString != NULL) {
	image = Tk_GetImage(interp, tkwin, imgPtr->disabledImageString,
		ImageChangedProc, (ClientData) imgPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (imgPtr->disabledImage != NULL) {
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
static void
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;
    (void)canvas;
    (void)display;

    if (imgPtr->imageString != NULL) {
	ckfree(imgPtr->imageString);
    }
    if (imgPtr->activeImageString != NULL) {
	ckfree(imgPtr->activeImageString);
    }







<
<







382
383
384
385
386
387
388


389
390
391
392
393
394
395
static void
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;



    if (imgPtr->imageString != NULL) {
	ckfree(imgPtr->imageString);
    }
    if (imgPtr->activeImageString != NULL) {
	ckfree(imgPtr->activeImageString);
    }
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
ComputeImageBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    ImageItem *imgPtr)		/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
    Tk_Image image;
    Tk_State state = imgPtr->header.state;

    if(state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    image = imgPtr->image;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *)imgPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}







>











|


|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
ComputeImageBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    ImageItem *imgPtr)		/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
    Tk_Image image;
    Tk_State state = imgPtr->header.state;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    image = imgPtr->image;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)imgPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
				/* 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;
    (void)display;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}







<


|



|







534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
				/* 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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
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;
    (void)canvas;

    x1 = imgPtr->header.x1;
    y1 = imgPtr->header.y1;
    x2 = imgPtr->header.x2;
    y2 = imgPtr->header.y2;

    /*







<







592
593
594
595
596
597
598

599
600
601
602
603
604
605
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;


    x1 = imgPtr->header.x1;
    y1 = imgPtr->header.y1;
    x2 = imgPtr->header.x2;
    y2 = imgPtr->header.y2;

    /*
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    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;
    (void)canvas;

    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }







<







649
650
651
652
653
654
655

656
657
658
659
660
661
662
    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;


    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }
696
697
698
699
700
701
702
703
704


705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    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);


    double x, y;
    int width, height;
    Tk_Image image;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}







|

>
>





|
|



|







693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
    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);

    char buffer[256];
    double x, y;
    int width, height;
    Tk_Image image;
    Tk_State state = itemPtr->state;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (imgPtr->activeImage != NULL) {
	    image = imgPtr->activeImage;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (imgPtr->disabledImage != NULL) {
	    image = imgPtr->disabledImage;
	}
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
    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) {
	Tcl_Obj *psObj = Tcl_GetObjResult(interp);

	if (Tcl_IsShared(psObj)) {
	    psObj = Tcl_DuplicateObj(psObj);
	    Tcl_SetObjResult(interp, psObj);
	}

	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y);
    }

    return Tk_PostscriptImage(image, interp, canvasWin,
	    ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
}

/*
 *--------------------------------------------------------------
 *
 * RotateImage --
 *
 *	This function is called to rotate an image's origin by a given amount.
 *	This does *not* rotate the contents of the image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the image anchor is rotated by angleRad radians about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateImage(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &imgPtr->x, &imgPtr->y);
    ComputeImageBbox(canvas, imgPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleImage --
 *
 *	This function is invoked to rescale an item.







<
|
<
<
|
|

<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







746
747
748
749
750
751
752

753


754
755
756



757
758
759


































760
761
762
763
764
765
766
    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", NULL);
    }




    return Tk_PostscriptImage(image, interp, canvasWin,
	    ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
}



































/*
 *--------------------------------------------------------------
 *
 * ScaleImage --
 *
 *	This function is invoked to rescale an item.
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
    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.
     */







|







847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
    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.
     */

Changes to generic/tkCanvLine.c.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * tkCanvLine.c --
 *
 *	This file implements line items for canvas widgets.
 *
 * 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
} Arrows;

typedef struct LineItem {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_Outline outline;		/* Outline structure */
    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-













>


<









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * tkCanvLine.c --
 *
 *	This file implements line items for canvas widgets.
 *
 * 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"


/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
} Arrows;

typedef struct LineItem  {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_Outline outline;		/* Outline structure */
    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-
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138

139
140
141

142
143
144

145
146
147

148
149
150

151
152
153

154
155
156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
				 * 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. */
    const Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e.
				 * with Bezier splines). */
    int splineSteps;		/* Number of steps in each spline segment. */
} LineItem;

/*
 * Number of points in an arrowHead:
 */

#define PTS_IN_ARROW 6

/*
 * Prototypes for functions defined in this file:
 */

static int		ArrowheadPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, LineItem *linePtr,
			    double *arrowPtr, Tcl_Obj *psObj);
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(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(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(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		LineCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		LineDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT 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, TkSizeT offset);
static const char * ArrowPrintProc(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, TkSizeT offset);
static const char * PrintArrowShape(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static void		RotateLine(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    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.
 */

static const Tk_CustomOption arrowShapeOption = {

    ParseArrowShape, PrintArrowShape, NULL
};
static const Tk_CustomOption arrowOption = {

    ArrowParseProc, ArrowPrintProc, NULL
};
static const Tk_CustomOption smoothOption = {

    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {

    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {

    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {

    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL,
	"none", offsetof(LineItem, arrow),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
    {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
	"8 10 3", offsetof(LineItem, arrowShapeA),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
    {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL,
	"butt", offsetof(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(LineItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(LineItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", offsetof(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(LineItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(LineItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(LineItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The structures below defines the line item type by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkLineType = {
    "line",				/* name */
    sizeof(LineItem),			/* itemSize */
    CreateLine,				/* createProc */
    configSpecs,			/* configSpecs */
    ConfigureLine,			/* configureProc */
    LineCoords,				/* coordProc */
    DeleteLine,				/* deleteProc */
    DisplayLine,			/* displayProc */
    TK_CONFIG_OBJS | TK_MOVABLE_POINTS,	/* flags */
    LineToPoint,			/* pointProc */
    LineToArea,				/* areaProc */
    LineToPostscript,			/* postscriptProc */
    ScaleLine,				/* scaleProc */
    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    LineInsert,				/* insertProc */
    LineDeleteCoords,			/* dTextProc */
    NULL,				/* nextPtr */
    RotateLine,				/* rotateProc */
    0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */







|
















|



|



|







|


|

|

|








|
|
|



|
|
|

<
<





|






|
>
|

|
>
|

|
>
|

|
>
|

|
>
|

|
>
|

|
>
|
|

|
>
|


|

|


|

|

|


<
|

|


|

|

|


|

|


|

|

|


|

|


|


|

|

|



|

|
















|





|


|


<
<







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
				 * 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. */
    Tk_SmoothMethod *smooth;	/* Non-zero means draw line smoothed (i.e.
				 * with Bezier splines). */
    int splineSteps;		/* Number of steps in each spline segment. */
} LineItem;

/*
 * Number of points in an arrowHead:
 */

#define PTS_IN_ARROW 6

/*
 * Prototypes for functions defined in this file:
 */

static int		ArrowheadPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, LineItem *linePtr,
			    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(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(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(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    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(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(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, int offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    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.
 */

static Tk_CustomOption arrowShapeOption = {
    (Tk_OptionParseProc *) ParseArrowShape,
    PrintArrowShape, (ClientData) NULL
};
static Tk_CustomOption arrowOption = {
    (Tk_OptionParseProc *) ArrowParseProc,
    ArrowPrintProc, (ClientData) NULL
};
static Tk_CustomOption smoothOption = {
    (Tk_OptionParseProc *) TkSmoothParseProc,
    TkSmoothPrintProc, (ClientData) NULL
};
static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_CustomOption dashOption = {
    (Tk_OptionParseProc *) TkCanvasDashParseProc,
    TkCanvasDashPrintProc, (ClientData) NULL
};
static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc,
    (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static Tk_CustomOption pixelOption = {
    (Tk_OptionParseProc *) TkPixelParseProc,
    TkPixelPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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", NULL, NULL,

	"none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
    {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
	"8 10 3", Tk_Offset(LineItem, arrowShapeA),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
    {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL,
	"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	"black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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", 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", NULL, NULL,
	"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(LineItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", Tk_Offset(LineItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", Tk_Offset(LineItem, splineSteps), 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(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, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * The structures below defines the line item type by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkLineType = {
    "line",				/* name */
    sizeof(LineItem),			/* itemSize */
    CreateLine,				/* createProc */
    configSpecs,			/* configSpecs */
    ConfigureLine,			/* configureProc */
    LineCoords,				/* coordProc */
    DeleteLine,				/* deleteProc */
    DisplayLine,			/* displayProc */
    TK_CONFIG_OBJS,			/* flags */
    LineToPoint,			/* pointProc */
    LineToArea,				/* areaProc */
    LineToPostscript,			/* postscriptProc */
    ScaleLine,				/* scaleProc */
    TranslateLine,			/* translateProc */
    (Tk_ItemIndexProc *) GetLineIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    (Tk_ItemInsertProc *) LineInsert,	/* insertProc */
    LineDeleteCoords,			/* dTextProc */
    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).
 */
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * 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);
    linePtr->canvas = canvas;
    linePtr->numPoints = 0;
    linePtr->coordPtr = NULL;
    linePtr->capStyle = CapButt;
    linePtr->joinStyle = JoinRound;
    linePtr->arrowGC = NULL;
    linePtr->arrow = ARROWS_NONE;







|





|







|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
static int
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) {
	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 function.
     */

    Tk_CreateOutline(&(linePtr->outline));
    linePtr->canvas = canvas;
    linePtr->numPoints = 0;
    linePtr->coordPtr = NULL;
    linePtr->capStyle = CapButt;
    linePtr->joinStyle = JoinRound;
    linePtr->arrowGC = NULL;
    linePtr->arrow = ARROWS_NONE;
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
    /*
     * 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++) {
	const char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (LineCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;







|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    /*
     * 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;
	}
    }
    if (LineCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
static int
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;
    double *coordPtr;

    if (objc == 0) {
	int numCoords;







|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
static int
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;
    double *coordPtr;

    if (objc == 0) {
	int numCoords;
391
392
393
394
395
396
397

398
399
400
401
402
403

404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    } else if (objc < 4) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected at least 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (linePtr->numPoints != numPoints) {
	coordPtr = (double *)ckalloc(sizeof(double) * objc);

	if (linePtr->coordPtr != NULL) {
	    ckfree(linePtr->coordPtr);
	}
	linePtr->coordPtr = coordPtr;
	linePtr->numPoints = numPoints;
    }
    coordPtr = linePtr->coordPtr;
    for (i = 0; i < objc ; i++) {
	if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		coordPtr++) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * Update arrowheads by throwing away any existing arrow-head information
     * and calling ConfigureArrows to recompute it.
     */

    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    ComputeLineBbox(canvas, linePtr);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigureLine --







>
|
|
|
|


>
|
|
|

<
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
>







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    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));
	    if (linePtr->coordPtr != NULL) {
		ckfree((char *) linePtr->coordPtr);
	    }
	    linePtr->coordPtr = coordPtr;
	    linePtr->numPoints = numPoints;
	}
	coordPtr = linePtr->coordPtr;
	for (i = 0; i <objc; i++) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		    coordPtr++) != TCL_OK) {
  		return TCL_ERROR;
  	    }
  	}

	/*
	 * Update arrowheads by throwing away any existing arrow-head
	 * information and calling ConfigureArrows to recompute it.
	 */

	if (linePtr->firstArrowPtr != NULL) {
	    ckfree((char *) linePtr->firstArrowPtr);
	    linePtr->firstArrowPtr = NULL;
	}
	if (linePtr->lastArrowPtr != NULL) {
	    ckfree((char *) linePtr->lastArrowPtr);
	    linePtr->lastArrowPtr = NULL;
	}
	if (linePtr->arrow != ARROWS_NONE) {
	    ConfigureArrows(canvas, linePtr);
	}
	ComputeLineBbox(canvas, linePtr);
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigureLine --
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
 */

static int
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;
    GC newGC, arrowGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) linePtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (linePtr->outline.activeWidth > linePtr->outline.width ||
	    linePtr->outline.activeDash.number != 0 ||
	    linePtr->outline.activeColor != NULL ||
	    linePtr->outline.activeStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }
    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &linePtr->outline);

    if (mask) {
	if (linePtr->arrow == ARROWS_NONE) {
	    gcValues.cap_style = linePtr->capStyle;
	    mask |= GCCapStyle;
	}
	gcValues.join_style = linePtr->joinStyle;
	mask |= GCJoinStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to linewidth even for arrow fills
	 * (as linewidth controls antialiasing).
	 */

	mask |= GCLineWidth;
#else
	gcValues.line_width = 0;
#endif
	arrowGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = arrowGC = NULL;







|
|











|










|
|










|
>










|
|

<







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
 */

static int
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;
    GC newGC, arrowGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) linePtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    if (linePtr->outline.activeWidth > linePtr->outline.width ||
	    linePtr->outline.activeDash.number != 0 ||
	    linePtr->outline.activeColor != NULL ||
	    linePtr->outline.activeStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }
    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,
	    &(linePtr->outline));
    if (mask) {
	if (linePtr->arrow == ARROWS_NONE) {
	    gcValues.cap_style = linePtr->capStyle;
	    mask |= GCCapStyle;
	}
	gcValues.join_style = linePtr->joinStyle;
	mask |= GCJoinStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to linewidth even for 
	 * arrow fills (as linewidth controls antialiasing).
	 */

	mask |= GCLineWidth;
#else
	gcValues.line_width = 0;
#endif
	arrowGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = arrowGC = NULL;
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

    if (linePtr->splineSteps < 1) {
	linePtr->splineSteps = 1;
    } else if (linePtr->splineSteps > 100) {
	linePtr->splineSteps = 100;
    }

    if ((!linePtr->numPoints) || (state == TK_STATE_HIDDEN)) {
	ComputeLineBbox(canvas, linePtr);
	return TCL_OK;
    }

    /*
     * 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)
	    && (linePtr->arrow != ARROWS_BOTH)) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST)
	    && (linePtr->arrow != ARROWS_BOTH)) {
	int i;

	i = 2*(linePtr->numPoints-1);
	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    /*







|













|









|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

    if (linePtr->splineSteps < 1) {
	linePtr->splineSteps = 1;
    } else if (linePtr->splineSteps > 100) {
	linePtr->splineSteps = 100;
    }

    if ((!linePtr->numPoints) || (state==TK_STATE_HIDDEN)) {
	ComputeLineBbox(canvas, linePtr);
	return TCL_OK;
    }

    /*
     * 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)
	    && (linePtr->arrow != ARROWS_BOTH)) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
	ckfree((char *) linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST)
	    && (linePtr->arrow != ARROWS_BOTH)) {
	int i;

	i = 2*(linePtr->numPoints-1);
	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];
	ckfree((char *) linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    /*
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteLine(
    TCL_UNUSED(Tk_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;

    Tk_DeleteOutline(display, &linePtr->outline);
    if (linePtr->coordPtr != NULL) {
	ckfree(linePtr->coordPtr);
    }
    if (linePtr->arrowGC != NULL) {
	Tk_FreeGC(display, linePtr->arrowGC);
    }
    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ComputeLineBbox --







|





|

|





|


|







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
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;

    Tk_DeleteOutline(display, &(linePtr->outline));
    if (linePtr->coordPtr != NULL) {
	ckfree((char *) linePtr->coordPtr);
    }
    if (linePtr->arrowGC != NULL) {
	Tk_FreeGC(display, linePtr->arrowGC);
    }
    if (linePtr->firstArrowPtr != NULL) {
	ckfree((char *) linePtr->firstArrowPtr);
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree((char *) linePtr->lastArrowPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ComputeLineBbox --
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
{
    double *coordPtr;
    int i, intWidth;
    double width;
    Tk_State state = linePtr->header.state;
    Tk_TSOffset *tsoffset;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!(linePtr->numPoints) || (state == TK_STATE_HIDDEN)) {
	linePtr->header.x1 = -1;
	linePtr->header.x2 = -1;
	linePtr->header.y1 = -1;
	linePtr->header.y2 = -1;
	return;
    }

    width = linePtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *)linePtr) {
	if (linePtr->outline.activeWidth > width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth > 0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    coordPtr = linePtr->coordPtr;
    linePtr->header.x1 = linePtr->header.x2 = (int) coordPtr[0];
    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.
     */

    for (i = 1, coordPtr = linePtr->coordPtr+2; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkIncludePoint((Tk_Item *) linePtr, coordPtr);
    }
    width = linePtr->outline.width;







|
|


|








|
|


|
|





|







|
|







656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
{
    double *coordPtr;
    int i, intWidth;
    double width;
    Tk_State state = linePtr->header.state;
    Tk_TSOffset *tsoffset;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    if (!(linePtr->numPoints) || (state==TK_STATE_HIDDEN)) {
	linePtr->header.x1 = -1;
	linePtr->header.x2 = -1;
	linePtr->header.y1 = -1;
	linePtr->header.y2 = -1;
	return;
    }

    width = linePtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
	if (linePtr->outline.activeWidth>width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth>0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    coordPtr = linePtr->coordPtr;
    linePtr->header.x1 = linePtr->header.x2 = (int) *coordPtr;
    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. 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;
	    i++, coordPtr += 2) {
	TkIncludePoint((Tk_Item *) linePtr, coordPtr);
    }
    width = linePtr->outline.width;
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
	if (linePtr->arrow != ARROWS_FIRST) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	coordPtr = linePtr->coordPtr
		+ (tsoffset->flags & ~TK_OFFSET_INDEX);

	if (tsoffset->flags <= 0) {
	    coordPtr = linePtr->coordPtr;
	    if ((linePtr->arrow == ARROWS_FIRST)
		    || (linePtr->arrow == ARROWS_BOTH)) {
		coordPtr = linePtr->firstArrowPtr;
	    }
	}
	if (tsoffset->flags > (linePtr->numPoints * 2)) {
	    coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2);
	    if ((linePtr->arrow == ARROWS_LAST)
		    || (linePtr->arrow == ARROWS_BOTH)) {
		coordPtr = linePtr->lastArrowPtr;
	    }
	}
	tsoffset->xoffset = (int) (coordPtr[0] + 0.5);
	tsoffset->yoffset = (int) (coordPtr[1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {







<
|
<


|
<





|
<







711
712
713
714
715
716
717

718

719
720
721

722
723
724
725
726
727

728
729
730
731
732
733
734
	if (linePtr->arrow != ARROWS_FIRST) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {

	double *coordPtr = linePtr->coordPtr + (tsoffset->flags & ~TK_OFFSET_INDEX);

	if (tsoffset->flags <= 0) {
	    coordPtr = linePtr->coordPtr;
	    if ((linePtr->arrow == ARROWS_FIRST) || (linePtr->arrow == ARROWS_BOTH)) {

		coordPtr = linePtr->firstArrowPtr;
	    }
	}
	if (tsoffset->flags > (linePtr->numPoints * 2)) {
	    coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2);
	    if ((linePtr->arrow == ARROWS_LAST) || (linePtr->arrow == ARROWS_BOTH)) {

		coordPtr = linePtr->lastArrowPtr;
	    }
	}
	tsoffset->xoffset = (int) (coordPtr[0] + 0.5);
	tsoffset->yoffset = (int) (coordPtr[1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

    intWidth = (int) (width + 0.5);
    linePtr->header.x1 -= intWidth;
    linePtr->header.x2 += intWidth;
    linePtr->header.y1 -= intWidth;
    linePtr->header.y2 += intWidth;

    if (linePtr->numPoints == 1) {
	linePtr->header.x1 -= 1;
	linePtr->header.x2 += 1;
	linePtr->header.y1 -= 1;
	linePtr->header.y2 += 1;
	return;
    }








|







749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

    intWidth = (int) (width + 0.5);
    linePtr->header.x1 -= intWidth;
    linePtr->header.x2 += intWidth;
    linePtr->header.y1 -= intWidth;
    linePtr->header.y2 += intWidth;

    if (linePtr->numPoints==1) {
	linePtr->header.x1 -= 1;
	linePtr->header.x2 += 1;
	linePtr->header.y1 -= 1;
	linePtr->header.y2 += 1;
	return;
    }

829
830
831
832
833
834
835

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

static void
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. */

    TCL_UNUSED(int),		/* Describes region of canvas that must be */
    TCL_UNUSED(int),		/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    LineItem *linePtr = (LineItem *)itemPtr;
    XPoint staticPoints[MAX_STATIC_POINTS*3];
    XPoint *pointPtr;
    double linewidth;
    int numPoints;
    Tk_State state = itemPtr->state;

    if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	    state = Canvas(canvas)->canvas_state;
    }
    linewidth = linePtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth != linewidth) {
	    linewidth = linePtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth != linewidth) {
	    linewidth = linePtr->outline.disabledWidth;
	}
    }
    /*
     * 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,







>
|
|
<
<

|











|


|



|







831
832
833
834
835
836
837
838
839
840


841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

static void
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];
    XPoint *pointPtr;
    double linewidth;
    int numPoints;
    Tk_State state = itemPtr->state;

    if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	    state = ((TkCanvas *)canvas)->canvas_state;
    }
    linewidth = linePtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth != linewidth) {
	    linewidth = linePtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth != linewidth) {
	    linewidth = linePtr->outline.disabledWidth;
	}
    }
    /*
     * 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,
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    } else {
	numPoints = linePtr->numPoints;
    }

    if (numPoints <= MAX_STATIC_POINTS) {
	pointPtr = staticPoints;
    } else {
	pointPtr = (XPoint *)ckalloc(numPoints * 3 * sizeof(XPoint));
    }

    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		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.
     */

    if (Tk_ChangeOutlineGC(canvas, itemPtr, &linePtr->outline)) {
	Tk_CanvasSetOffset(canvas, linePtr->arrowGC,
		&linePtr->outline.tsoffset);
    }
    if (numPoints > 1) {
	XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints,
		CoordModeOrigin);
    } else {
	int intwidth = (int) (linewidth + 0.5);

	if (intwidth < 1) {
	    intwidth = 1;
	}
	XFillArc(display, drawable, linePtr->outline.gc,
		pointPtr->x - intwidth/2, pointPtr->y - intwidth/2,
		(unsigned) intwidth+1, (unsigned) intwidth+1, 0, 64*360);
    }
    if (pointPtr != staticPoints) {
	ckfree(pointPtr);
    }

    /*
     * Display arrowheads, if they are wanted.
     */

    if (linePtr->firstArrowPtr != NULL) {
	TkFillPolygon(canvas, linePtr->firstArrowPtr, PTS_IN_ARROW,
		display, drawable, linePtr->arrowGC, NULL);
    }
    if (linePtr->lastArrowPtr != NULL) {
	TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW,
		display, drawable, linePtr->arrowGC, NULL);
    }
    if (Tk_ResetOutlineGC(canvas, itemPtr, &linePtr->outline)) {
	XSetTSOrigin(display, linePtr->arrowGC, 0, 0);
    }
}

/*
 *--------------------------------------------------------------
 *







|






|










|
|
<

|

|


<
|
|



|


|














|







876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
    } else {
	numPoints = linePtr->numPoints;
    }

    if (numPoints <= MAX_STATIC_POINTS) {
	pointPtr = staticPoints;
    } else {
	pointPtr = (XPoint *)ckalloc((unsigned)(numPoints * 3*sizeof(XPoint)));
    }

    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		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.
     */

    if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) {
	Tk_CanvasSetOffset(canvas, linePtr->arrowGC, &linePtr->outline.tsoffset);

    }
    if (numPoints>1) {
	XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints,
	    CoordModeOrigin);
    } else {
	int intwidth = (int) (linewidth + 0.5);

        if (intwidth<1) {
	    intwidth=1;
	}
	XFillArc(display, drawable, linePtr->outline.gc,
		pointPtr->x - intwidth/2, pointPtr->y - intwidth/2,
		(unsigned int)intwidth+1, (unsigned int)intwidth+1, 0, 64*360);
    }
    if (pointPtr != staticPoints) {
	ckfree((char *) pointPtr);
    }

    /*
     * Display arrowheads, if they are wanted.
     */

    if (linePtr->firstArrowPtr != NULL) {
	TkFillPolygon(canvas, linePtr->firstArrowPtr, PTS_IN_ARROW,
		display, drawable, linePtr->arrowGC, NULL);
    }
    if (linePtr->lastArrowPtr != NULL) {
	TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW,
		display, drawable, linePtr->arrowGC, NULL);
    }
    if (Tk_ResetOutlineGC(canvas, itemPtr, &(linePtr->outline))) {
	XSetTSOrigin(display, linePtr->arrowGC, 0, 0);
    }
}

/*
 *--------------------------------------------------------------
 *
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
 *--------------------------------------------------------------
 */

static void
LineInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    TkSizeT 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 *newCoordPtr, *coordPtr;
    Tk_State state = itemPtr->state;
    Tcl_Obj **objv;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    length = 2*linePtr->numPoints;
    if (beforeThis == TCL_INDEX_NONE) {
	beforeThis = 0;
    }
    if (beforeThis + 1 > (TkSizeT)length + 1) {
	beforeThis = length;
    }
    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + objc));

    for (i=0; i<(int)beforeThis; i++) {
	newCoordPtr[i] = linePtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i + beforeThis]) != TCL_OK) {
	    Tcl_ResetResult(Canvas(canvas)->interp);
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = linePtr->coordPtr[i];
    }
    if (linePtr->coordPtr) {
        ckfree(linePtr->coordPtr);
    }
    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.
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	if ((int)beforeThis > 0) {
	    beforeThis -= 2;
	    objc += 2;
	}
	if ((int)beforeThis+objc < length) {
	    objc += 2;
	}
	if (linePtr->smooth) {
	    if ((int)beforeThis > 0) {
		beforeThis -= 2;
		objc += 2;
	    }
	    if ((int)beforeThis+objc+2 < length) {
		objc += 2;
	    }
	}
	itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
	itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
	if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis < 1)) {
	    /*
	     * Include old first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc >= length)) {
	    /*
	     * 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) {
	    TkIncludePoint(itemPtr, coordPtr);
	    coordPtr += 2;
	}
    }
    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis > 2)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc < length-2)) {
	    /*
	     * Include new right arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	width = linePtr->outline.width;
	if (Canvas(canvas)->currentItemPtr == itemPtr) {
	    if (linePtr->outline.activeWidth > width) {
		width = linePtr->outline.activeWidth;
	    }
	} else if (state == TK_STATE_DISABLED) {
	    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;
	Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1,
		itemPtr->x2, itemPtr->y2);
    }

    ComputeLineBbox(canvas, linePtr);
}








|










|







|


|










|
>
|





|
|








|


|


|











<
|
<
<
|
<
<

|
|
<

|
|




|









|









|


|



|



|










|









|










|
|


|
|







|
<
|
<







950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

1026


1027


1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115

1116
1117
1118
1119
1120
1121
1122
 *--------------------------------------------------------------
 */

static void
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 *newCoordPtr, *coordPtr;
    Tk_State state = itemPtr->state;
    Tcl_Obj **objv;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    length = 2*linePtr->numPoints;
    if (beforeThis < 0) {
	beforeThis = 0;
    }
    if (beforeThis > length) {
	beforeThis = length;
    }
    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    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(NULL, objv[i],
		&newCoordPtr[i + beforeThis]) != TCL_OK) {
	    Tcl_ResetResult(((TkCanvas *)canvas)->interp);
	    ckfree((char *) newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = linePtr->coordPtr[i];
    }
    if (linePtr->coordPtr) {
	ckfree((char *) linePtr->coordPtr);
    }
    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.
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;


	if (beforeThis>0) {beforeThis -= 2; objc+=2; }


	if ((beforeThis+objc)<length) objc+=2;


	if (linePtr->smooth) {
	    if(beforeThis>0) {
		beforeThis-=2; objc+=2;

	    }
	    if((beforeThis+objc+2)<length) {
		objc+=2;
	    }
	}
	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.
	     */

	    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.
	     */

	    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) {
	    TkIncludePoint(itemPtr, coordPtr);
	    coordPtr+=2;
	}
    }
    if (linePtr->firstArrowPtr != NULL) {
	ckfree((char *) linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree((char *) linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) {
	    /*
	     * 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.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	width = linePtr->outline.width;
	if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	    if (linePtr->outline.activeWidth>width) {
		width = linePtr->outline.activeWidth;
	    }
	} else if (state==TK_STATE_DISABLED) {
	    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;

	Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1,
		itemPtr->x2, itemPtr->y2);
    }

    ComputeLineBbox(canvas, linePtr);
}

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
 *--------------------------------------------------------------
 */

static void
LineDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Index of first character to delete. */
    TkSizeT last)			/* Index of last character to delete. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int count, i, first1, last1;
    int length = 2*linePtr->numPoints;
    double *coordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    first &= -2;
    last &= -2;

    if ((int)first < 0) {
	first = 0;
    }
    if ((int)last >= length) {
	last = length-2;
    }
    if ((int)first > (int)last) {
	return;
    }
    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {







|
|








|





|


|


|







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
 *--------------------------------------------------------------
 */

static void
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;
    int length = 2*linePtr->numPoints;
    double *coordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    first &= -2;
    last &= -2;

    if (first < 0) {
	first = 0;
    }
    if (last >= length) {
	last = length-2;
    }
    if (first > last) {
	return;
    }
    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
	    first1 -= 2;
	}
	if (last1 < length-2) {
	    last1 += 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.







|







1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
	    first1 -= 2;
	}
	if (last1 < length-2) {
	    last1 += 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.
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259

    count = last + 2 - first;
    for (i=last+2; i<length; i++) {
	linePtr->coordPtr[i-count] = linePtr->coordPtr[i];
    }
    linePtr->numPoints -= count/2;
    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;







|



|







1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251

    count = last + 2 - first;
    for (i=last+2; i<length; i++) {
	linePtr->coordPtr[i-count] = linePtr->coordPtr[i];
    }
    linePtr->numPoints -= count/2;
    if (linePtr->firstArrowPtr != NULL) {
	ckfree((char *) linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree((char *) linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	width = linePtr->outline.width;
	if (Canvas(canvas)->currentItemPtr == itemPtr) {
	    if (linePtr->outline.activeWidth > width) {
		width = linePtr->outline.activeWidth;
	    }
	} else if (state == TK_STATE_DISABLED) {
	    if (linePtr->outline.disabledWidth > 0) {
		width = linePtr->outline.disabledWidth;
	    }
	}
	intWidth = (int) (width + 0.5);
	if (intWidth < 1) {
	    intWidth = 1;







|



|







1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	width = linePtr->outline.width;
	if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	    if (linePtr->outline.activeWidth > width) {
		width = linePtr->outline.activeWidth;
	    }
	} else if (state==TK_STATE_DISABLED) {
	    if (linePtr->outline.disabledWidth > 0) {
		width = linePtr->outline.disabledWidth;
	    }
	}
	intWidth = (int) (width + 0.5);
	if (intWidth < 1) {
	    intWidth = 1;
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328
1329
1330
1331
1332
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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;







>







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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;
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371

1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
    bestDist = 1.0e36;

    /*
     * Handle smoothed lines by generating an expanded set of points against
     * which to do the check.
     */

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	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->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, NULL,
		linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    linePoints = staticSpace;
	} else {
	    linePoints = (double *)ckalloc(2 * numPoints * sizeof(double));

	}
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
    } else {
	numPoints = linePtr->numPoints;
	linePoints = linePtr->coordPtr;
    }

    if (width < 1.0) {
	width = 1.0;
    }

    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;
	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







|
|



|
|


|
|










|
>












|




|
<
<







1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383


1384
1385
1386
1387
1388
1389
1390
    bestDist = 1.0e36;

    /*
     * Handle smoothed lines by generating an expanded set of points against
     * which to do the check.
     */

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	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->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, NULL,
		linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    linePoints = staticSpace;
	} else {
	    linePoints = (double *) ckalloc((unsigned)
		    (2*numPoints*sizeof(double)));
	}
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
    } else {
	numPoints = linePtr->numPoints;
	linePoints = linePtr->coordPtr;
    }

    if (width < 1.0) {
	width = 1.0;
    }

    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;
	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
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
		bestDist = dist;
	    }
	}
    }

  done:
    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
	ckfree(linePoints);
    }
    return bestDist;
}

/*
 *--------------------------------------------------------------
 *







|







1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
		bestDist = dist;
	    }
	}
    }

  done:
    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
	ckfree((char *) linePoints);
    }
    return bestDist;
}

/*
 *--------------------------------------------------------------
 *
1546
1547
1548
1549
1550
1551
1552

1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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];
    double *linePoints;
    int numPoints, result;
    double radius, width;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = linePtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth > width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth > 0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    radius = (width+1.0)/2.0;

    if ((state == TK_STATE_HIDDEN) || !linePtr->numPoints) {
	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;







>













|
|


|
|


|
|






|







1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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];
    double *linePoints;
    int numPoints, result;
    double radius, width;
    Tk_State state = itemPtr->state;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    width = linePtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth>width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth>0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    radius = (width+1.0)/2.0;

    if ((state==TK_STATE_HIDDEN) || !linePtr->numPoints) {
	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;
1598
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630

    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, NULL,
		linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    linePoints = staticSpace;
	} else {
	    linePoints = (double *)ckalloc(2 * numPoints * sizeof(double));

	}
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
    } else {
	numPoints = linePtr->numPoints;
	linePoints = linePtr->coordPtr;
    }

    /*
     * Check the segments of the line.
     */

    if (width < 1.0) {
	width = 1.0;
    }

    result = TkThickPolyLineToArea(linePoints, numPoints, width,
	    linePtr->capStyle, linePtr->joinStyle, rectPtr);

    if (result == 0) {
	goto done;
    }

    /*
     * Check arrowheads, if any.
     */







|
>












|



|
|
>







1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625

    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
	numPoints = linePtr->smooth->coordProc(canvas, NULL,
		linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    linePoints = staticSpace;
	} else {
	    linePoints = (double *) ckalloc((unsigned)
		    (2*numPoints*sizeof(double)));
	}
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
    } else {
	numPoints = linePtr->numPoints;
	linePoints = linePtr->coordPtr;
    }

    /*
     * Check the segments of the line.
     */

     if (width < 1.0) {
	width = 1.0;
    }

    result = TkThickPolyLineToArea(linePoints, numPoints,
	    width, linePtr->capStyle, linePtr->joinStyle,
	    rectPtr);
    if (result == 0) {
	goto done;
    }

    /*
     * Check arrowheads, if any.
     */
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
		goto done;
	    }
	}
    }

  done:
    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
	ckfree(linePoints);
    }
    return result;
}

/*
 *--------------------------------------------------------------
 *







|







1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
		goto done;
	    }
	}
    }

  done:
    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
	ckfree((char *) linePoints);
    }
    return result;
}

/*
 *--------------------------------------------------------------
 *
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699


1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
     * Delete any arrowheads before scaling all the points (so that the
     * end-points of the line get restored).
     */

    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {


	i = 2*(linePtr->numPoints-1);
	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	coordPtr[0] = originX + scaleX*(*coordPtr - originX);
	coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);
    }







|



>
>



|







1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
     * Delete any arrowheads before scaling all the points (so that the
     * end-points of the line get restored).
     */

    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
	ckfree((char *) linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	int i;

	i = 2*(linePtr->numPoints-1);
	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];
	ckfree((char *) linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	coordPtr[0] = originX + scaleX*(*coordPtr - originX);
	coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);
    }
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754

1755
1756



1757
1758
1759


1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792


1793

1794
1795
1796
1797


1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
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. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    TkSizeT idx, length;
    LineItem *linePtr = (LineItem *) itemPtr;

    const char *string;
    (void)canvas;

    if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, 0, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > (2*(TkSizeT)linePtr->numPoints)) {

	    idx = 2*linePtr->numPoints;
	} else {



	    idx &= (TkSizeT)-2;	/* If index is odd, make it even. */
	}
	*indexPtr = idx;


	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = linePtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<linePtr->numPoints; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {




	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */



    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *







|

<

>
|
<

<
|
<
<
>
|

>
>
>
|
|
|
>
>
|
|
<
<
<
|

|
|
<














|

|






>
>
|
>
|
<
<
|
>
>
|
<
<
<
<







1734
1735
1736
1737
1738
1739
1740
1741
1742

1743
1744
1745

1746

1747


1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760



1761
1762
1763
1764

1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792


1793
1794
1795
1796




1797
1798
1799
1800
1801
1802
1803
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. */
{

    LineItem *linePtr = (LineItem *) itemPtr;
    int length;
    char *string = Tcl_GetStringFromObj(obj, &length);



    if (string[0] == 'e') {


	if (strncmp(string, "end", (unsigned) length) == 0) {
	    *indexPtr = 2*linePtr->numPoints;
	} else {
	    /*
	     * Some of the paths here leave messages in interp->result, so we
	     * have to clear it out before storing our own message.
	     */

	badIndex:
	    Tcl_SetResult(interp, NULL, TCL_STATIC);
	    Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
	    return TCL_ERROR;
	}



    } else if (string[0] == '@') {
	int i;
	double x ,y, bestDist, dist, *coordPtr;
	char *end, *p;


	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = linePtr->coordPtr;
	*indexPtr = 0;
	for(i=0; i<linePtr->numPoints; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist<bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	*indexPtr &= -2;		/* if index is odd, make it even */
	if (*indexPtr < 0){


	    *indexPtr = 0;
	} else if (*indexPtr > (2*linePtr->numPoints)) {
	    *indexPtr = (2*linePtr->numPoints);
	}




    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925

1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947








1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993

1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006

2007
2008
2009
2010
2011

2012
2013
2014
2015
2016
2017
2018
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateLine --
 *
 *	This function is called to rotate a line by a given amount about a
 *	point.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the line is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateLine(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *
 * ParseArrowShape --
 *
 *	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.
 *
 * Side effects:
 *	Arrow information in recordPtr is updated.
 *
 *--------------------------------------------------------------
 */


static int
ParseArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    TkSizeT offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    int argc;
    const char **argv = NULL;

    if ((size_t)offset != offsetof(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	goto syntaxError;








    } else if (argc != 3) {
	goto syntaxError;
    }
    if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK)
	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[1], &b)
		!= TCL_OK)
	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[2], &c)
		!= TCL_OK)) {
	goto syntaxError;
    }

    linePtr->arrowShapeA = (float) a;
    linePtr->arrowShapeB = (float) b;
    linePtr->arrowShapeC = (float) c;
    ckfree(argv);
    return TCL_OK;

  syntaxError:
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad arrow shape \"%s\": must be list with three numbers",
	    value));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARROW_SHAPE", NULL);
    if (argv != NULL) {
	ckfree(argv);
    }
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * PrintArrowShape --
 *
 *	This function is a callback invoked by the configuration code to
 *	return a printable value describing an arrow shape.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static const char *
PrintArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(Tk_Window),		/* Window associated with linePtr's widget. */
    char *recordPtr,		/* Pointer to item record containing current
				 * shape information. */
    TCL_UNUSED(TkSizeT),			/* 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 = (char *)ckalloc(120);


    sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}


/*
 *--------------------------------------------------------------
 *
 * ArrowParseProc --
 *
 *	This function is invoked during option processing to handle the







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















>


|

|
|


|





|

|




|
>
>
>
>
>
>
>
>
|









<
|
|
|
|

<
<
<
<
<
<
<
<
<
<
<



















>
|

|
|


|




|

>





>







1847
1848
1849
1850
1851
1852
1853


















































1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910

1911
1912
1913
1914
1915











1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *


















































 * ParseArrowShape --
 *
 *	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.
 *
 * Side effects:
 *	Arrow information in recordPtr is updated.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
    double a, b, c;
    int argc;
    CONST char **argv = NULL;

    if (offset != Tk_Offset(LineItem, arrowShapeA)) {
	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", NULL);
	if (argv != NULL) {
	    ckfree((char *) argv);
	}
	return TCL_ERROR;
    }
    if (argc != 3) {
	goto syntaxError;
    }
    if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK)
	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[1], &b)
		!= TCL_OK)
	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[2], &c)
		!= TCL_OK)) {
	goto syntaxError;
    }

    linePtr->arrowShapeA = (float)a;
    linePtr->arrowShapeB = (float)b;
    linePtr->arrowShapeC = (float)c;
    ckfree((char *) argv);
    return TCL_OK;











}

/*
 *--------------------------------------------------------------
 *
 * PrintArrowShape --
 *
 *	This function is a callback invoked by the configuration code to
 *	return a printable value describing an arrow shape.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

    /* ARGSUSED */
static char *
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 function to call to free
				 * string here. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    char *buffer;

    buffer = (char *) ckalloc(120);
    sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}


/*
 *--------------------------------------------------------------
 *
 * ArrowParseProc --
 *
 *	This function is invoked during option processing to handle the
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
ArrowParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;

    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);








|

|
|

|



>
|

|







1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
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;

    register Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if(value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);

2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
	return TCL_OK;
    }
    if ((c == 'b') && (strncmp(value, "both", length) == 0)) {
	*arrowPtr = ARROWS_BOTH;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad arrow spec \"%s\": must be none, first, last, or both",
	    value));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARROW", NULL);
    *arrowPtr = ARROWS_NONE;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







|
|
<
<







2007
2008
2009
2010
2011
2012
2013
2014
2015


2016
2017
2018
2019
2020
2021
2022
	return TCL_OK;
    }
    if ((c == 'b') && (strncmp(value, "both", length) == 0)) {
	*arrowPtr = ARROWS_BOTH;
	return TCL_OK;
    }

    Tcl_AppendResult(interp, "bad arrow spec \"", value,
	    "\": must be none, first, last, or both", NULL);


    *arrowPtr = ARROWS_NONE;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static const char *
ArrowPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    switch (*arrowPtr) {
    case ARROWS_FIRST:
	return "first";
    case ARROWS_LAST:
	return "last";
    case ARROWS_BOTH:







|

|
|

|
|



|







2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static char *
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:
	return "first";
    case ARROWS_LAST:
	return "last";
    case ARROWS_BOTH:
2135
2136
2137
2138
2139
2140
2141

2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
 *	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.
 *
 *--------------------------------------------------------------
 */


static int
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 width;
    Tk_State state = linePtr->header.state;

    if (linePtr->numPoints < 2) {
	return TCL_OK;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *)linePtr) {
	if (linePtr->outline.activeWidth > width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth > 0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    /*
     * 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







>



















|



|
|



|
|


|
|







2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
 *	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(
    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 width;
    Tk_State state = linePtr->header.state;

    if (linePtr->numPoints <2) {
	return TCL_OK;
    }

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
	if (linePtr->outline.activeWidth>width) {
	    width = linePtr->outline.activeWidth;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth>0) {
	    width = linePtr->outline.disabledWidth;
	}
    }

    /*
     * 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
2195
2196
2197
2198
2199
2200
2201
2202

2203
2204
2205
2206
2207
2208
2209
     */

    fracHeight = (width/2.0)/shapeC;
    backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0;
    if (linePtr->arrow != ARROWS_LAST) {
	poly = linePtr->firstArrowPtr;
	if (poly == NULL) {
	    poly = (double *)ckalloc(2 * PTS_IN_ARROW * sizeof(double));

	    poly[0] = poly[10] = linePtr->coordPtr[0];
	    poly[1] = poly[11] = linePtr->coordPtr[1];
	    linePtr->firstArrowPtr = poly;
	}
	dx = poly[0] - linePtr->coordPtr[2];
	dy = poly[1] - linePtr->coordPtr[3];
	length = hypot(dx, dy);







|
>







2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
     */

    fracHeight = (width/2.0)/shapeC;
    backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0;
    if (linePtr->arrow != ARROWS_LAST) {
	poly = linePtr->firstArrowPtr;
	if (poly == NULL) {
	    poly = (double *) ckalloc((unsigned)
		    (2*PTS_IN_ARROW*sizeof(double)));
	    poly[0] = poly[10] = linePtr->coordPtr[0];
	    poly[1] = poly[11] = linePtr->coordPtr[1];
	    linePtr->firstArrowPtr = poly;
	}
	dx = poly[0] - linePtr->coordPtr[2];
	dy = poly[1] - linePtr->coordPtr[3];
	length = hypot(dx, dy);
2239
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
     * Similar arrowhead calculation for the last point of the line.
     */

    if (linePtr->arrow != ARROWS_FIRST) {
	coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2);
	poly = linePtr->lastArrowPtr;
	if (poly == NULL) {
	    poly = (double *)ckalloc(2 * PTS_IN_ARROW * sizeof(double));

	    poly[0] = poly[10] = coordPtr[2];
	    poly[1] = poly[11] = coordPtr[3];
	    linePtr->lastArrowPtr = poly;
	}
	dx = poly[0] - coordPtr[0];
	dy = poly[1] - coordPtr[1];
	length = hypot(dx, dy);







|
>







2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
     * Similar arrowhead calculation for the last point of the line.
     */

    if (linePtr->arrow != ARROWS_FIRST) {
	coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2);
	poly = linePtr->lastArrowPtr;
	if (poly == NULL) {
	    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;
	}
	dx = poly[0] - coordPtr[0];
	dy = poly[1] - coordPtr[1];
	length = hypot(dx, dy);
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307

2308

2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370

2371
2372
2373
2374
2375
2376


2377
2378
2379
2380

2381
2382
2383
2384
2385
2386
2387
2388
2389
2390

2391
2392
2393
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404
2405
2406
2407
2408
2409
2410

2411
2412
2413
2414
2415
2416
2417
2418
2419
2420

2421
2422
2423
2424
2425

2426
2427
2428
2429
2430
2431
2432
2433

2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445


2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456

2457

2458
2459
2460
2461
2462
2463

2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531


2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
 */

static int
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. */
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    LineItem *linePtr = (LineItem *) itemPtr;

    int style;

    double width;
    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    color = linePtr->outline.color;
    stipple = linePtr->outline.stipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth > width) {
	    width = linePtr->outline.activeWidth;
	}
	if (linePtr->outline.activeColor != NULL) {
	    color = linePtr->outline.activeColor;
	}
	if (linePtr->outline.activeStipple != None) {
	    stipple = linePtr->outline.activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth > 0) {
	    width = linePtr->outline.disabledWidth;
	}
	if (linePtr->outline.disabledColor != NULL) {
	    color = linePtr->outline.disabledColor;
	}
	if (linePtr->outline.disabledStipple != None) {
	    stipple = linePtr->outline.disabledStipple;
	}
    }

    if (color == NULL || linePtr->numPoints < 1 || linePtr->coordPtr == NULL){
	return TCL_OK;
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Check if we're just doing a "pixel".
     */

    if (linePtr->numPoints == 1) {
	Tcl_AppendToObj(psObj, "matrix currentmatrix\n", -1);
	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate %.15g %.15g",
		linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
		width/2.0, width/2.0);
	Tcl_AppendToObj(psObj,
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", -1);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);
	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;

    }

    /*
     * Generate a path for the line's center-line (do this differently for
     * straight lines and smoothed lines).
     */

    Tcl_ResetResult(interp);
    if ((!linePtr->smooth) || (linePtr->numPoints < 3)) {
	Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints);

    } else if ((stipple == None) && linePtr->smooth->postscriptProc) {
	linePtr->smooth->postscriptProc(interp, canvas, 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.

	 */

	double staticPoints[2*MAX_STATIC_POINTS];
	double *pointPtr;
	int numPoints;

	numPoints = linePtr->smooth->coordProc(canvas, NULL,
		linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
	pointPtr = staticPoints;
	if (numPoints > MAX_STATIC_POINTS) {

	    pointPtr = (double *)ckalloc(numPoints * 2 * sizeof(double));
	}
	numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
		linePtr->numPoints, linePtr->splineSteps, NULL, pointPtr);
	Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints);
	if (pointPtr != staticPoints) {
	    ckfree(pointPtr);
	}
    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


    /*
     * Set other line-drawing parameters and stroke out the line.
     */


    if (linePtr->capStyle == CapRound) {
	style = 1;
    } else if (linePtr->capStyle == CapProjecting) {
	style = 2;
    } else {
	style = 0;
    }
    Tcl_AppendPrintfToObj(psObj, "%d setlinecap\n", style);

    if (linePtr->joinStyle == JoinRound) {
	style = 1;
    } else if (linePtr->joinStyle == JoinBevel) {
	style = 2;
    } else {
	style = 0;
    }
    Tcl_AppendPrintfToObj(psObj, "%d setlinejoin\n", style);

    Tcl_ResetResult(interp);
    Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));



    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj);

    }

    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj);

    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ArrowheadPostscript --
 *
 *	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 given object.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ArrowheadPostscript(
    Tcl_Interp *interp,		/* Leave error message here; non-error results
				 * will be discarded by caller. */
    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. */
    Tcl_Obj *psObj)		/* Append postscript to this object. */
{
    Pixmap stipple;
    Tk_State state = linePtr->header.state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    stipple = linePtr->outline.stipple;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) linePtr) {
	if (linePtr->outline.activeStipple!=None) {
	    stipple = linePtr->outline.activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (linePtr->outline.activeStipple!=None) {
	    stipple = linePtr->outline.disabledStipple;
	}
    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_AppendToObj(psObj, "clip ", -1);



	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    } else {
	Tcl_AppendToObj(psObj, "fill\n", -1);
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




>
|
>




<
<

|
|





|
|


|


|


|
|


|


|




|



<
<
<
<
<
<
<
<
<
<
<
|
<
|


|
|
<
<
|
<
>
|

<
|
|
<
>
>

|

<
>

<





<


>
|
|
|
|
|
|
|
|
|
|
>
|

|
|
|

|
|
|
|
>
|
|
|
|
|
|
|
|
|
<
>





>

|

|
<
<

|
>

|

|
<
<

|

<
|
<
>
>







|

|
|
>
|
>


|

|
|
>
|
|
<
<
<
<
<
<
<
<















|









|
<



|

<




|
|



|



|





<

<
<

|
>
>
|
<
<
<

|











2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260


2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294











2295

2296
2297
2298
2299
2300


2301

2302
2303
2304

2305
2306

2307
2308
2309
2310
2311

2312
2313

2314
2315
2316
2317
2318

2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352

2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363


2364
2365
2366
2367
2368
2369
2370


2371
2372
2373

2374

2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399








2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425

2426
2427
2428
2429
2430

2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449

2450


2451
2452
2453
2454
2455



2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
 */

static int
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 + 4*TCL_INTEGER_SPACE];
    char *style;

    double width;
    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;



    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    color = linePtr->outline.color;
    stipple = linePtr->outline.stipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (linePtr->outline.activeWidth>width) {
	    width = linePtr->outline.activeWidth;
	}
	if (linePtr->outline.activeColor!=NULL) {
	    color = linePtr->outline.activeColor;
	}
	if (linePtr->outline.activeStipple!=None) {
	    stipple = linePtr->outline.activeStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.disabledWidth>0) {
	    width = linePtr->outline.disabledWidth;
	}
	if (linePtr->outline.disabledColor!=NULL) {
	    color = linePtr->outline.disabledColor;
	}
	if (linePtr->outline.disabledStipple!=None) {
	    stipple = linePtr->outline.disabledStipple;
	}
    }

    if (color == NULL || linePtr->numPoints<1 || linePtr->coordPtr==NULL) {
	return TCL_OK;
    }












    if (linePtr->numPoints==1) {

	sprintf(buffer, "%.15g %.15g translate %.15g %.15g",
		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", NULL);


	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (stipple != None) {

	    Tcl_AppendResult(interp, "clip ", NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {

		return TCL_ERROR;
	    }
	} else {
	    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).
     */


    if ((!linePtr->smooth) || (linePtr->numPoints < 3)) {
	Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints);
    } else {
	if ((stipple == None) && linePtr->smooth->postscriptProc) {
	    linePtr->smooth->postscriptProc(interp, canvas,
		    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.
	     */

	    double staticPoints[2*MAX_STATIC_POINTS];
	    double *pointPtr;
	    int numPoints;

	    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, NULL, pointPtr);
	    Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints);
	    if (pointPtr != staticPoints) {
		ckfree((char *) pointPtr);
	    }
	}

    }

    /*
     * Set other line-drawing parameters and stroke out the line.
     */

    style = "0 setlinecap\n";
    if (linePtr->capStyle == CapRound) {
	style = "1 setlinecap\n";
    } else if (linePtr->capStyle == CapProjecting) {
	style = "2 setlinecap\n";


    }
    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, NULL);


    if (Tk_CanvasPsOutline(canvas, itemPtr, &(linePtr->outline)) != TCL_OK) {

	return TCL_ERROR;
    }

    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendResult(interp, "grestore gsave\n", NULL);
	}
	if (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendResult(interp, "grestore gsave\n", NULL);
	}
	if (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
    }








    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ArrowheadPostscript --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
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;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    stipple = linePtr->outline.stipple;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
	if (linePtr->outline.activeStipple!=None) {
	    stipple = linePtr->outline.activeStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (linePtr->outline.activeStipple!=None) {
	    stipple = linePtr->outline.disabledStipple;
	}
    }


    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);


    if (stipple != None) {
	Tcl_AppendResult(interp, "clip ", NULL);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}



    } else {
	Tcl_AppendResult(interp, "fill\n", NULL);
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvPoly.c.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
/*
 * tkCanvPoly.c --
 *
 *	This file implements polygon items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each polygon item.
 */

typedef struct PolygonItem  {
    Tk_Item header;		/* Generic stuff that's the same for all













>


<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
/*
 * tkCanvPoly.c --
 *
 *	This file implements polygon items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"


/*
 * The structure below defines the record for each polygon item.
 */

typedef struct PolygonItem  {
    Tk_Item header;		/* Generic stuff that's the same for all
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61

62
63
64

65
66
67

68
69
70

71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
				 * 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. */
    GC fillGC;			/* Graphics context for filling polygon. */
    const Tk_SmoothMethod *smooth; /* Non-zero means draw shape smoothed (i.e.
				 * with Bezier splines). */
    int splineSteps;		/* Number of steps in each spline segment. */
    int autoClosed;		/* Zero means the given polygon was closed,
				   one means that we auto closed it. */
} PolygonItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption smoothOption = {

    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {

    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {

    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {

    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", offsetof(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(PolygonItem, tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(PolygonItem, outline.tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(PolygonItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(PolygonItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT 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		RotatePolygon(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScalePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    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 functions
 * that can be invoked by generic item code.
 */

Tk_ItemType tkPolygonType = {
    "polygon",				/* name */
    sizeof(PolygonItem),		/* itemSize */
    CreatePolygon,			/* createProc */
    configSpecs,			/* configSpecs */
    ConfigurePolygon,			/* configureProc */
    PolygonCoords,			/* coordProc */
    DeletePolygon,			/* deleteProc */
    DisplayPolygon,			/* displayProc */
    TK_CONFIG_OBJS | TK_MOVABLE_POINTS,	/* flags */
    PolygonToPoint,			/* pointProc */
    PolygonToArea,			/* areaProc */
    PolygonToPostscript,		/* postscriptProc */
    ScalePolygon,			/* scaleProc */
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    PolygonInsert,		/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    NULL,				/* nextPtr */
    RotatePolygon,			/* rotateProc */
    0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */







|










|
>
|

|
>
|

|
>
|

|
>
|

|
>
|
|

|
>
|


|

|


|

|

|
|

|

|


|


|
|

|


|

|
|

|
|

|

|


|

|

|


|

|


|

|


|

|

|



|

|










|


|







|


|

|

|






<
<




















|





|


|


<
<







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224
				 * 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. */
    GC fillGC;			/* Graphics context for filling polygon. */
    Tk_SmoothMethod *smooth;	/* Non-zero means draw shape smoothed (i.e.
				 * with Bezier splines). */
    int splineSteps;		/* Number of steps in each spline segment. */
    int autoClosed;		/* Zero means the given polygon was closed,
				   one means that we auto closed it. */
} PolygonItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption smoothOption = {
    (Tk_OptionParseProc *) TkSmoothParseProc,
    TkSmoothPrintProc, (ClientData) NULL
};
static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_CustomOption dashOption = {
    (Tk_OptionParseProc *) TkCanvasDashParseProc,
    TkCanvasDashPrintProc, (ClientData) NULL
};
static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc,
    (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static Tk_CustomOption pixelOption = {
    (Tk_OptionParseProc *) TkPixelParseProc,
    TkPixelPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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", 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", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK},
    {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", NULL, NULL,
	"black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(PolygonItem, tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {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", 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", NULL, NULL,
	"12", Tk_Offset(PolygonItem, splineSteps), 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(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, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    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(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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
 * The structures below defines the polygon item type by means of functions
 * that can be invoked by generic item code.
 */

Tk_ItemType tkPolygonType = {
    "polygon",				/* name */
    sizeof(PolygonItem),		/* itemSize */
    CreatePolygon,			/* createProc */
    configSpecs,			/* configSpecs */
    ConfigurePolygon,			/* configureProc */
    PolygonCoords,			/* coordProc */
    DeletePolygon,			/* deleteProc */
    DisplayPolygon,			/* displayProc */
    TK_CONFIG_OBJS,			/* flags */
    PolygonToPoint,			/* pointProc */
    PolygonToArea,			/* areaProc */
    PolygonToPostscript,		/* postscriptProc */
    ScalePolygon,			/* scaleProc */
    TranslatePolygon,			/* translateProc */
    (Tk_ItemIndexProc *) GetPolygonIndex,/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    (Tk_ItemInsertProc *) PolygonInsert,/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    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).
 */
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
     * errors during the the remainder of this function.
     */

    Tk_CreateOutline(&polyPtr->outline);
    polyPtr->numPoints = 0;
    polyPtr->pointsAllocated = 0;
    polyPtr->coordPtr = NULL;
    polyPtr->joinStyle = JoinRound;
    polyPtr->tsoffset.flags = 0;
    polyPtr->tsoffset.xoffset = 0;
    polyPtr->tsoffset.yoffset = 0;







|





|







|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
static int
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) {
	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 function.
     */

    Tk_CreateOutline(&(polyPtr->outline));
    polyPtr->numPoints = 0;
    polyPtr->pointsAllocated = 0;
    polyPtr->coordPtr = NULL;
    polyPtr->joinStyle = JoinRound;
    polyPtr->tsoffset.flags = 0;
    polyPtr->tsoffset.xoffset = 0;
    polyPtr->tsoffset.yoffset = 0;
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
    /*
     * 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++) {
	const char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
    }







|
<







287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
    /*
     * 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++) {
	char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
    }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
static int
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







|







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
static int
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
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "POLYGON", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (polyPtr->pointsAllocated <= numPoints) {
	if (polyPtr->coordPtr != NULL) {
	    ckfree(polyPtr->coordPtr);
	}

	/*
	 * One extra point gets allocated here, because we always add
	 * another point to close the polygon.
	 */

	polyPtr->coordPtr = (double *)ckalloc(sizeof(double) * (objc+2));

	polyPtr->pointsAllocated = numPoints+1;
    }
    for (i = objc-1; i >= 0; i--) {
	if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		&polyPtr->coordPtr[i]) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    polyPtr->numPoints = numPoints;
    polyPtr->autoClosed = 0;

    /*
     * 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;
	polyPtr->numPoints++;
	polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
    }

    ComputePolygonBbox(canvas, polyPtr);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigurePolygon --







>
|
|
|
|

<
|
|
|
|
|
|

|
|
|
|

|
>
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
<
|
>







357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    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 {
	numPoints = objc/2;
	if (polyPtr->pointsAllocated <= numPoints) {
	    if (polyPtr->coordPtr != NULL) {
		ckfree((char *) polyPtr->coordPtr);
	    }

	    /*
	     * One extra point gets allocated here, because we always add
	     * another point to close the polygon.
	     */

	    polyPtr->coordPtr = (double *) ckalloc((unsigned)
		    (sizeof(double) * (objc+2)));
	    polyPtr->pointsAllocated = numPoints+1;
	}
	for (i = objc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		    &polyPtr->coordPtr[i]) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	polyPtr->numPoints = numPoints;
	polyPtr->autoClosed = 0;

	/*
	 * 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;
	    polyPtr->numPoints++;
	    polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
	}

	ComputePolygonBbox(canvas, polyPtr);
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigurePolygon --
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

static int
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;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */







|













|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

static int
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;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
	    polyPtr->activeFillColor != NULL ||
	    polyPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputePolygonBbox(canvas, polyPtr);
	return TCL_OK;
    }

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &polyPtr->outline);
    if (mask) {
	gcValues.cap_style = CapRound;
	gcValues.join_style = polyPtr->joinStyle;
	mask |= GCCapStyle|GCJoinStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }
    if (polyPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), polyPtr->outline.gc);
    }
    polyPtr->outline.gc = newGC;

    color = polyPtr->fillColor;
    stipple = polyPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->activeFillColor != NULL) {
	    color = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple != None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->disabledFillColor != NULL) {
	    color = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple != None) {
	    stipple = polyPtr->disabledFillStipple;
	}
    }

    if (color == NULL) {
	newGC = NULL;
    } else {







|
|

|




|















|
|


|


|
|


|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
	    polyPtr->activeFillColor != NULL ||
	    polyPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (state==TK_STATE_HIDDEN) {
	ComputePolygonBbox(canvas, polyPtr);
	return TCL_OK;
    }

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(polyPtr->outline));
    if (mask) {
	gcValues.cap_style = CapRound;
	gcValues.join_style = polyPtr->joinStyle;
	mask |= GCCapStyle|GCJoinStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }
    if (polyPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), polyPtr->outline.gc);
    }
    polyPtr->outline.gc = newGC;

    color = polyPtr->fillColor;
    stipple = polyPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->activeFillColor!=NULL) {
	    color = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple!=None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->disabledFillColor!=NULL) {
	    color = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple!=None) {
	    stipple = polyPtr->disabledFillStipple;
	}
    }

    if (color == NULL) {
	newGC = NULL;
    } else {
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeletePolygon(
    TCL_UNUSED(Tk_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;

    Tk_DeleteOutline(display, &polyPtr->outline);
    if (polyPtr->coordPtr != NULL) {
	ckfree(polyPtr->coordPtr);
    }
    if (polyPtr->fillColor != NULL) {
	Tk_FreeColor(polyPtr->fillColor);
    }
    if (polyPtr->activeFillColor != NULL) {
	Tk_FreeColor(polyPtr->activeFillColor);
    }







|





|

|







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
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;

    Tk_DeleteOutline(display,&(polyPtr->outline));
    if (polyPtr->coordPtr != NULL) {
	ckfree((char *) polyPtr->coordPtr);
    }
    if (polyPtr->fillColor != NULL) {
	Tk_FreeColor(polyPtr->fillColor);
    }
    if (polyPtr->activeFillColor != NULL) {
	Tk_FreeColor(polyPtr->activeFillColor);
    }
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
{
    double *coordPtr;
    int i;
    double width;
    Tk_State state = polyPtr->header.state;
    Tk_TSOffset *tsoffset;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1)
	    || (state == TK_STATE_HIDDEN)) {
	polyPtr->header.x1 = polyPtr->header.x2 =
		polyPtr->header.y1 = polyPtr->header.y2 = -1;
	return;
    }
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) polyPtr) {
	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;
	}
    }

    coordPtr = polyPtr->coordPtr;
    polyPtr->header.x1 = polyPtr->header.x2 = (int) *coordPtr;
    polyPtr->header.y1 = polyPtr->header.y2 = (int) coordPtr[1];







|
|


|
<

|


|
|


|
|







625
626
627
628
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
{
    double *coordPtr;
    int i;
    double width;
    Tk_State state = polyPtr->header.state;
    Tk_TSOffset *tsoffset;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1) || (state==TK_STATE_HIDDEN)) {

	polyPtr->header.x1 = polyPtr->header.x2 =
	polyPtr->header.y1 = polyPtr->header.y2 = -1;
	return;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)polyPtr) {
	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;
	}
    }

    coordPtr = polyPtr->coordPtr;
    polyPtr->header.x1 = polyPtr->header.x2 = (int) *coordPtr;
    polyPtr->header.y1 = polyPtr->header.y2 = (int) coordPtr[1];
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	    i++, coordPtr += 2) {
	TkIncludePoint((Tk_Item *) polyPtr, coordPtr);
    }

    tsoffset = &polyPtr->tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	int index = tsoffset->flags & ~TK_OFFSET_INDEX;

	if (tsoffset->flags == INT_MAX) {
	    index = (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	    if (index < 0) {
		index = 0;
	    }
	}
	index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	if (index < 0) {
	    index += (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	}
 	tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
	tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
	    tsoffset->xoffset = polyPtr->header.x1;







<







|







665
666
667
668
669
670
671

672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	    i++, coordPtr += 2) {
	TkIncludePoint((Tk_Item *) polyPtr, coordPtr);
    }

    tsoffset = &polyPtr->tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	int index = tsoffset->flags & ~TK_OFFSET_INDEX;

	if (tsoffset->flags == INT_MAX) {
	    index = (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	    if (index < 0) {
		index = 0;
	    }
	}
	index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	if (index <0) {
	    index += (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	}
 	tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
	tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
	    tsoffset->xoffset = polyPtr->header.x1;
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761

762
763
764
765
766
767
768
769
770
	    if (tsoffset->flags & TK_OFFSET_INDEX) {
		int index = tsoffset->flags & ~TK_OFFSET_INDEX;

		if (tsoffset->flags == INT_MAX) {
		    index = (polyPtr->numPoints - 1) * 2;
		}
		index %= (polyPtr->numPoints - 1) * 2;
		if (index < 0) {
		    index += (polyPtr->numPoints - 1) * 2;
		}
		tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
		tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
	    } else {
		if (tsoffset->flags & TK_OFFSET_LEFT) {
		    tsoffset->xoffset = polyPtr->header.x1;
		} else if (tsoffset->flags & TK_OFFSET_CENTER) {
		    tsoffset->xoffset =
			    (polyPtr->header.x1 + polyPtr->header.x2) / 2;
		} else if (tsoffset->flags & TK_OFFSET_RIGHT) {
		    tsoffset->xoffset = polyPtr->header.x2;
		}
		if (tsoffset->flags & TK_OFFSET_TOP) {
		    tsoffset->yoffset = polyPtr->header.y1;
		} else if (tsoffset->flags & TK_OFFSET_MIDDLE) {
		    tsoffset->yoffset =
			    (polyPtr->header.y1 + polyPtr->header.y2) / 2;
		} else if (tsoffset->flags & TK_OFFSET_BOTTOM) {
		    tsoffset->yoffset = polyPtr->header.y2;
		}
	    }
	}

	i = (int) ((width+1.5) / 2.0);
	polyPtr->header.x1 -= i;
	polyPtr->header.x2 += i;
	polyPtr->header.y1 -= i;
	polyPtr->header.y2 += i;

	/*
	 * 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 (polyPtr->joinStyle == JoinMiter) {
	    double miter[4];
	    int j;

	    coordPtr = polyPtr->coordPtr;
	    if (polyPtr->numPoints > 3) {
		if (TkGetMiterPoints(coordPtr+2*(polyPtr->numPoints-2),
			coordPtr, coordPtr+2, width, miter, miter+2)) {

		    for (j = 0; j < 4; j += 2) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	    }
	    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) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	    }
	}
    }







|








<
|






<
|






|
















|

|
>




|

>
|
|







704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719

720
721
722
723
724
725
726

727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
	    if (tsoffset->flags & TK_OFFSET_INDEX) {
		int index = tsoffset->flags & ~TK_OFFSET_INDEX;

		if (tsoffset->flags == INT_MAX) {
		    index = (polyPtr->numPoints - 1) * 2;
		}
		index %= (polyPtr->numPoints - 1) * 2;
		if (index <0) {
		    index += (polyPtr->numPoints - 1) * 2;
		}
		tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
		tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
	    } else {
		if (tsoffset->flags & TK_OFFSET_LEFT) {
		    tsoffset->xoffset = polyPtr->header.x1;
		} else if (tsoffset->flags & TK_OFFSET_CENTER) {

		    tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2;
		} else if (tsoffset->flags & TK_OFFSET_RIGHT) {
		    tsoffset->xoffset = polyPtr->header.x2;
		}
		if (tsoffset->flags & TK_OFFSET_TOP) {
		    tsoffset->yoffset = polyPtr->header.y1;
		} else if (tsoffset->flags & TK_OFFSET_MIDDLE) {

		    tsoffset->yoffset = (polyPtr->header.y1 + polyPtr->header.y2)/2;
		} else if (tsoffset->flags & TK_OFFSET_BOTTOM) {
		    tsoffset->yoffset = polyPtr->header.y2;
		}
	    }
	}

	i = (int) ((width+1.5)/2.0);
	polyPtr->header.x1 -= i;
	polyPtr->header.x2 += i;
	polyPtr->header.y1 -= i;
	polyPtr->header.y2 += i;

	/*
	 * 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 (polyPtr->joinStyle == JoinMiter) {
	    double miter[4];
	    int j;

	    coordPtr = polyPtr->coordPtr;
	    if (polyPtr->numPoints>3) {
		if (TkGetMiterPoints(coordPtr+2*(polyPtr->numPoints-2),
			coordPtr, coordPtr+2, width,
			miter, miter+2)) {
		    for (j = 0; j < 4; j += 2) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	     }
	    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) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	    }
	}
    }
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
     * unless the polygon has an enormous number of points; in this case,
     * dynamically allocate an array.
     */

    if (numPoints <= MAX_STATIC_POINTS) {
	pointPtr = staticPoints;
    } else {
	pointPtr = (XPoint *)ckalloc(numPoints * sizeof(XPoint));
    }

    for (i=0, pPtr=pointPtr ; i<numPoints; i+=1, coordPtr+=2, pPtr++) {
	Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], &pPtr->x,
		&pPtr->y);
    }

    /*
     * Display polygon, then free up polygon storage if it was dynamically
     * allocated.
     */

    if (gc != NULL && numPoints > 3) {
	XFillPolygon(display, drawable, gc, pointPtr, numPoints, Complex,
		CoordModeOrigin);
    }
    if (outlineGC != NULL) {
	XDrawLines(display, drawable, outlineGC, pointPtr, numPoints,
		CoordModeOrigin);
    }
    if (pointPtr != staticPoints) {
	ckfree(pointPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * DisplayPolygon --







|












|




|
|


|







823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
     * unless the polygon has an enormous number of points; in this case,
     * dynamically allocate an array.
     */

    if (numPoints <= MAX_STATIC_POINTS) {
	pointPtr = staticPoints;
    } else {
	pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));
    }

    for (i=0, pPtr=pointPtr ; i<numPoints; i+=1, coordPtr+=2, pPtr++) {
	Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], &pPtr->x,
		&pPtr->y);
    }

    /*
     * Display polygon, then free up polygon storage if it was dynamically
     * allocated.
     */

    if (gc != NULL && numPoints>3) {
	XFillPolygon(display, drawable, gc, pointPtr, numPoints, Complex,
		CoordModeOrigin);
    }
    if (outlineGC != NULL) {
	XDrawLines(display, drawable, outlineGC, pointPtr,
	    numPoints, CoordModeOrigin);
    }
    if (pointPtr != staticPoints) {
	ckfree((char *) pointPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * DisplayPolygon --
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977

978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067

static void
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. */

    TCL_UNUSED(int),	/* Describes region of canvas that must be */
    TCL_UNUSED(int),	/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    Tk_State state = itemPtr->state;
    Pixmap stipple = polyPtr->fillStipple;
    double linewidth = polyPtr->outline.width;

    if (((polyPtr->fillGC == NULL) && (polyPtr->outline.gc == NULL)) ||
	    (polyPtr->numPoints < 1) ||
	    (polyPtr->numPoints < 3 && polyPtr->outline.gc == NULL)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > linewidth) {
	    linewidth = polyPtr->outline.activeWidth;
	}
	if (polyPtr->activeFillStipple != None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    linewidth = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->disabledFillStipple != None) {
	    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 ((stipple != None) && (polyPtr->fillGC != NULL)) {
	Tk_TSOffset *tsoffset = &polyPtr->tsoffset;
	int w = 0, 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) {
		w /= 2;
	    } else {
		w = 0;
	    }
	    if (flags & TK_OFFSET_MIDDLE) {
		h /= 2;
	    } else {
		h = 0;
	    }
	}
	tsoffset->xoffset -= w;
	tsoffset->yoffset -= h;
	Tk_CanvasSetOffset(canvas, polyPtr->fillGC, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
    }
    Tk_ChangeOutlineGC(canvas, itemPtr, &polyPtr->outline);

    if (polyPtr->numPoints < 3) {
	short x, y;
	int intLineWidth = (int) (linewidth + 0.5);

	if (intLineWidth < 1) {
	    intLineWidth = 1;
	}
	Tk_CanvasDrawableCoords(canvas, polyPtr->coordPtr[0],
		polyPtr->coordPtr[1], &x, &y);
	XFillArc(display, drawable, polyPtr->outline.gc,
		x - intLineWidth/2, y - intLineWidth/2,
		(unsigned) intLineWidth+1, (unsigned) intLineWidth+1,
		0, 64*360);
    } else if (!polyPtr->smooth || polyPtr->numPoints < 4) {
	TkFillPolygon(canvas, polyPtr->coordPtr, polyPtr->numPoints,
		    display, drawable, polyPtr->fillGC, polyPtr->outline.gc);
    } else {
	int numPoints;
	XPoint staticPoints[MAX_STATIC_POINTS];
	XPoint *pointPtr;

	/*
	 * This is a smoothed polygon. Display using a set of generated spline
	 * points rather than the original points.
	 */

	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    pointPtr = staticPoints;
	} else {
	    pointPtr = (XPoint *)ckalloc(numPoints * sizeof(XPoint));

	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL);
	if (polyPtr->fillGC != NULL) {
	    XFillPolygon(display, drawable, polyPtr->fillGC, pointPtr,
		    numPoints, Complex, CoordModeOrigin);
	}
	if (polyPtr->outline.gc != NULL) {
	    XDrawLines(display, drawable, polyPtr->outline.gc, pointPtr,
		    numPoints, CoordModeOrigin);
	}
	if (pointPtr != staticPoints) {
	    ckfree(pointPtr);
	}
    }
    Tk_ResetOutlineGC(canvas, itemPtr, &polyPtr->outline);
    if ((stipple != None) && (polyPtr->fillGC != NULL)) {
	XSetTSOrigin(display, polyPtr->fillGC, 0, 0);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PolygonInsert --
 *
 *	Insert coords into a polygon item at a given index.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The coords in the given item is modified.
 *
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    TkSizeT 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 *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    while ((int)beforeThis > length) {
	beforeThis -= length;
    }
    while ((int)beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));

    for (i=0; i<(int)beforeThis; i++) {
	newCoordPtr[i] = polyPtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i+beforeThis]) != TCL_OK){
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=(int)beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    if (polyPtr->coordPtr) {
	ckfree(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







>
|
|
<
<













|

|
|





|
|














|


|
<


















|

|
|






|


|



















|
>












|


|










|














|










|







|


|


|
>
|





|




|



|







872
873
874
875
876
877
878
879
880
881


882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067

static void
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;
    Pixmap stipple = polyPtr->fillStipple;
    double linewidth = polyPtr->outline.width;

    if (((polyPtr->fillGC == NULL) && (polyPtr->outline.gc == NULL)) ||
	    (polyPtr->numPoints < 1) ||
	    (polyPtr->numPoints < 3 && polyPtr->outline.gc == NULL)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth>linewidth) {
	    linewidth = polyPtr->outline.activeWidth;
	}
	if (polyPtr->activeFillStipple != None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
	    linewidth = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->disabledFillStipple != None) {
	    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 ((stipple != None) && (polyPtr->fillGC != NULL)) {
	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) {
		w /= 2;
	    } else {
		w = 0;
	    }
	    if (flags & TK_OFFSET_MIDDLE) {
		h /= 2;
	    } else {
		h = 0;
	    }
	}
	tsoffset->xoffset -= w;
	tsoffset->yoffset -= h;
	Tk_CanvasSetOffset(canvas, polyPtr->fillGC, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
    }
    Tk_ChangeOutlineGC(canvas, itemPtr, &(polyPtr->outline));

    if(polyPtr->numPoints < 3) {
	short x,y;
	int intLineWidth = (int) (linewidth + 0.5);

	if (intLineWidth < 1) {
	    intLineWidth = 1;
	}
	Tk_CanvasDrawableCoords(canvas, polyPtr->coordPtr[0],
		    polyPtr->coordPtr[1], &x,&y);
	XFillArc(display, drawable, polyPtr->outline.gc,
		x - intLineWidth/2, y - intLineWidth/2,
		(unsigned int)intLineWidth+1, (unsigned int)intLineWidth+1,
		0, 64*360);
    } else if (!polyPtr->smooth || polyPtr->numPoints < 4) {
	TkFillPolygon(canvas, polyPtr->coordPtr, polyPtr->numPoints,
		    display, drawable, polyPtr->fillGC, polyPtr->outline.gc);
    } else {
	int numPoints;
	XPoint staticPoints[MAX_STATIC_POINTS];
	XPoint *pointPtr;

	/*
	 * This is a smoothed polygon. Display using a set of generated spline
	 * points rather than the original points.
	 */

	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    pointPtr = staticPoints;
	} else {
	    pointPtr = (XPoint *) ckalloc((unsigned)
		    (numPoints * sizeof(XPoint)));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL);
	if (polyPtr->fillGC != NULL) {
	    XFillPolygon(display, drawable, polyPtr->fillGC, pointPtr,
		    numPoints, Complex, CoordModeOrigin);
	}
	if (polyPtr->outline.gc != NULL) {
	    XDrawLines(display, drawable, polyPtr->outline.gc, pointPtr,
		    numPoints, CoordModeOrigin);
	}
	if (pointPtr != staticPoints) {
	    ckfree((char *) pointPtr);
	}
    }
    Tk_ResetOutlineGC(canvas, itemPtr, &(polyPtr->outline));
    if ((stipple != None) && (polyPtr->fillGC != NULL)) {
	XSetTSOrigin(display, polyPtr->fillGC, 0, 0);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PolygonInsert --
 *
 *	Insert coords into a polugon item at a given index.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The coords in the given item is modified.
 *
 *--------------------------------------------------------------
 */

static void
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 *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    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;
    }
    newCoordPtr = (double *)
	    ckalloc(sizeof(double) * (unsigned)(length + 2 + objc));
    for (i=0; i<beforeThis; i++) {
	newCoordPtr[i] = polyPtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i+beforeThis]) != TCL_OK){
	    ckfree((char *) newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    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
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
	    polyPtr->autoClosed = 1;
	    polyPtr->numPoints++;
	}
    }

    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.
	 */

    	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.
	 */

	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 careful; beforeThis could now be negative
	 */

	for (i=beforeThis; i<(int)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 (Canvas(canvas)->currentItemPtr == itemPtr) {
	    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;
	    }
	}
	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);
    }

    ComputePolygonBbox(canvas, polyPtr);
}








|











<











|
<

|
|






|

|

|





|



|




|
<
|
<







1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140

1141
1142
1143
1144
1145
1146
1147
	    polyPtr->autoClosed = 1;
	    polyPtr->numPoints++;
	}
    }

    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.
	 */

    	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.
	 */

	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 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;
	    }
	} else if (state==TK_STATE_DISABLED) {
	    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);
    }

    ComputePolygonBbox(canvas, polyPtr);
}

1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Index of first character to delete. */
    TkSizeT last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)first >= length) {
	first -= length;
    }
    while ((int)first < 0) {
	first += length;
    }
    while ((int)last >= length) {
	last -= length;
    }
    while ((int)last < 0) {
	last += length;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;
    if (count <= 0) {
	count += length;
    }

    if (count >= length) {
	polyPtr->numPoints = 0;
	if (polyPtr->coordPtr != NULL) {
	    ckfree(polyPtr->coordPtr);
	    polyPtr->coordPtr = NULL;
	}
	ComputePolygonBbox(canvas, polyPtr);
	return;
    }

    if (last >= first) {
	for (i=last+2; i<length; i++) {
	    polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
	}
    } else {
	for (i=last; i<=(int)first; i++) {
	    polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i];
	}
    }
    polyPtr->coordPtr[length-count] = polyPtr->coordPtr[0];
    polyPtr->coordPtr[length-count+1] = polyPtr->coordPtr[1];
    polyPtr->numPoints -= count/2;
    ComputePolygonBbox(canvas, polyPtr);







|
|





|


|


|


|







|






|






|
|



|







1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
 *--------------------------------------------------------------
 */

static void
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;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;
    if (count<=0) {
	count += length;
    }

    if (count >= length) {
	polyPtr->numPoints = 0;
	if (polyPtr->coordPtr != NULL) {
	    ckfree((char *) polyPtr->coordPtr);
	    polyPtr->coordPtr = NULL;
	}
	ComputePolygonBbox(canvas, polyPtr);
	return;
    }

    if (last>=first) {
	for(i=last+2; i<length; i++) {
	    polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
	}
    } else {
	for(i=last; i<=first; i++) {
	    polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i];
	}
    }
    polyPtr->coordPtr[length-count] = polyPtr->coordPtr[0];
    polyPtr->coordPtr[length-count+1] = polyPtr->coordPtr[1];
    polyPtr->numPoints -= count/2;
    ComputePolygonBbox(canvas, polyPtr);
1239
1240
1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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;







>







1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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;
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293

1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
				 * angle was < 11 degrees. */
    double width;
    Tk_State state = itemPtr->state;

    bestDist = 1.0e36;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	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;
	}
    }
    radius = width/2.0;

    /*
     * Handle smoothed polygons by generating an expanded set of points
     * against which to do the check.
     */

    if ((polyPtr->smooth) && (polyPtr->numPoints > 2)) {
	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);

	if (numPoints <= MAX_STATIC_POINTS) {
	    polyPoints = staticSpace;
	} else {
	    polyPoints = (double *)ckalloc(2 * numPoints * sizeof(double));

	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints);

    } else {
	numPoints = polyPtr->numPoints;
	polyPoints = polyPtr->coordPtr;
    }

    bestDist = TkPolygonToPoint(polyPoints, numPoints, pointPtr);
    if (bestDist <= 0.0) {
	goto donepoint;
    }
    if ((polyPtr->outline.gc != NULL) && (polyPtr->joinStyle == JoinRound)) {
	dist = bestDist - radius;
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;







|


|
|


|
|










|

|
>



|
>


|
>






|







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
				 * angle was < 11 degrees. */
    double width;
    Tk_State state = itemPtr->state;

    bestDist = 1.0e36;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	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;
	}
    }
    radius = width/2.0;

    /*
     * Handle smoothed polygons by generating an expanded set of points
     * against which to do the check.
     */

    if ((polyPtr->smooth) && (polyPtr->numPoints>2)) {
	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)));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, NULL,
		polyPoints);
    } else {
	numPoints = polyPtr->numPoints;
	polyPoints = polyPtr->coordPtr;
    }

    bestDist = TkPolygonToPoint(polyPoints, numPoints, pointPtr);
    if (bestDist<=0.0) {
	goto donepoint;
    }
    if ((polyPtr->outline.gc != NULL) && (polyPtr->joinStyle == JoinRound)) {
	dist = bestDist - radius;
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
	/*
	 * 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, (double) 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, (double) 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.
	     */







|
|






|
|







1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
	/*
	 * 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, (double) 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, (double) 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.
	     */
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
		} else if (dist < bestDist) {
		    bestDist = dist;
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4,
		    poly+6);
	} else if (polyPtr->joinStyle == JoinMiter) {
	    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);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4,
		    poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	dist = TkPolygonToPoint(poly, 5, pointPtr);
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;
	} else if (dist < bestDist) {
	    bestDist = dist;
	}
    }

  donepoint:
    if (polyPoints != staticSpace && polyPoints != polyPtr->coordPtr) {
	ckfree(polyPoints);
    }
    return bestDist;
}

/*
 *--------------------------------------------------------------
 *







|
|








|
|













|
|







1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
		} else if (dist < bestDist) {
		    bestDist = dist;
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width,
		    0, poly+4, poly+6);
	} else if (polyPtr->joinStyle == JoinMiter) {
	    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);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0,
		    poly+4, poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	dist = TkPolygonToPoint(poly, 5, pointPtr);
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;
	} else if (dist < bestDist) {
	    bestDist = dist;
	}
    }

  donepoint:
    if ((polyPoints != staticSpace) && polyPoints != polyPtr->coordPtr) {
	ckfree((char *) polyPoints);
    }
    return bestDist;
}

/*
 *--------------------------------------------------------------
 *
1428
1429
1430
1431
1432
1433
1434

1435
1436
1437
1438
1439
1440
1441
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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. */







>







1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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. */
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
				 * 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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = polyPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	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;
	}
    }

    radius = width/2.0;
    inside = -1;

    if ((state == TK_STATE_HIDDEN) || polyPtr->numPoints < 2) {
	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, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    polyPoints = staticSpace;
	} else {
	    polyPoints = (double *)ckalloc(2 * numPoints * sizeof(double));

	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		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.
     */

    inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
    if (inside == 0) {
	goto donearea;
    }

    if (polyPtr->outline.gc == NULL) {
	goto donearea;
    }








|



|
|


|
|







|

|




















|
>















|







1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
				 * 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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = polyPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	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;
	}
    }

    radius = width/2.0;
    inside = -1;

    if ((state==TK_STATE_HIDDEN) || polyPtr->numPoints<2) {
	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, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    polyPoints = staticSpace;
	} else {
	    polyPoints = (double *)
		    ckalloc((unsigned) (2*numPoints*sizeof(double)));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		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.
     */

    inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
    if (inside==0) {
	goto donearea;
    }

    if (polyPtr->outline.gc == NULL) {
	goto donearea;
    }

1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    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);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	if (TkPolygonToArea(poly, 5, rectPtr) != inside) {
	    inside = 0;
	    goto donearea;
	}
    }

  donearea:
    if ((polyPoints != staticSpace) && (polyPoints != polyPtr->coordPtr)) {
	ckfree(polyPoints);
    }
    return inside;
}

/*
 *--------------------------------------------------------------
 *







|
|
















|







1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    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);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	if (TkPolygonToArea(poly, 5, rectPtr) != inside) {
	    inside = 0;
	    goto donearea;
	}
    }

  donearea:
    if ((polyPoints != staticSpace) && (polyPoints != polyPtr->coordPtr)) {
	ckfree((char *) polyPoints);
    }
    return inside;
}

/*
 *--------------------------------------------------------------
 *
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679

1680
1681
1682
1683
1684
1685


1686

1687


1688
1689


1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727

1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1779
 *
 *--------------------------------------------------------------
 */

static int
GetPolygonIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_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. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    TkSizeT length, idx;
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;

    const char *string;
    TkSizeT count = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    if (TCL_OK == TkGetIntForIndex(obj,  (INT_MAX - 1) - ((INT_MAX) % count), 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;


	} else {

	    idx = (idx & (TkSizeT)-2) % count;


	}
	*indexPtr = idx;


	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = polyPtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<polyPtr->numPoints-1; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */


    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * RotatePolygon --
 *
 *	This function is called to rotate a polygon by a given amount about a
 *	point.
 *
 * Results:
 *	None.
 *

 * Side effects:
 *	The position of the polygon is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */


static void
RotatePolygon(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    ComputePolygonBbox(canvas, polyPtr);

}

/*
 *--------------------------------------------------------------
 *
 * TranslatePolygon --
 *
 *	This function is called to move a polygon by a given amount.







|




|

<

>
|
<

<
|
<
>
>

>
|
>
>
|
|
>
>
|
|
<
<
<
|

|
|
<














|

|






|
<
<
<

>
|
<
<
<
|
<
<
|
<
<
<
<
<
<
|
|
<
<
<
>
|
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<

<
>








1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679

1680
1681
1682

1683

1684

1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697



1698
1699
1700
1701

1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725



1726
1727
1728



1729


1730






1731
1732



1733
1734






1735
1736








1737
1738

1739



1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
 *
 *--------------------------------------------------------------
 */

static int
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. */
{

    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length;
    char *string = Tcl_GetStringFromObj(obj, &length);



    if (string[0] == 'e') {

	if (strncmp(string, "end", (unsigned)length) == 0) {
	    *indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
	} else {
	    /*
	     * Some of the paths here leave messages in interp->result, so we
	     * have to clear it out before storing our own message.
	     */

	badIndex:
	    Tcl_SetResult(interp, NULL, TCL_STATIC);
	    Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
	    return TCL_ERROR;
	}



    } else if (string[0] == '@') {
	int i;
	double x ,y, bestDist, dist, *coordPtr;
	char *end, *p;


	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = polyPtr->coordPtr;
	*indexPtr = 0;
	for(i=0; i<(polyPtr->numPoints-1); i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist<bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	int count = 2*(polyPtr->numPoints - polyPtr->autoClosed);




	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;



	}


	*indexPtr &= -2; /* if odd, make it even */






	if (count) {
	    if (*indexPtr > 0) {



		*indexPtr = ((*indexPtr - 2) % count) + 2;
	    } else {






		*indexPtr = -((-(*indexPtr)) % count);
	    }








	} else {
	    *indexPtr = 0;

	}



    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TranslatePolygon --
 *
 *	This function is called to move a polygon by a given amount.
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902

1903
1904

1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929

1930
1931
1932


1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964

1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000


2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
 */

static int
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. */
    TCL_UNUSED(int))	/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int style;
    XColor *color;
    XColor *fillColor;
    Pixmap stipple;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    double width;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;

    if (polyPtr->numPoints < 2 || polyPtr->coordPtr == NULL) {
	return TCL_OK;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    color = polyPtr->outline.color;
    stipple = polyPtr->fillStipple;
    fillColor = polyPtr->fillColor;
    fillStipple = polyPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > width) {
	    width = polyPtr->outline.activeWidth;
	}
	if (polyPtr->outline.activeColor != NULL) {
	    color = polyPtr->outline.activeColor;
	}
	if (polyPtr->outline.activeStipple != None) {
	    stipple = polyPtr->outline.activeStipple;
	}
	if (polyPtr->activeFillColor != NULL) {
	    fillColor = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple != None) {
	    fillStipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->outline.disabledColor != NULL) {
	    color = polyPtr->outline.disabledColor;
	}
	if (polyPtr->outline.disabledStipple != None) {
	    stipple = polyPtr->outline.disabledStipple;
	}
	if (polyPtr->disabledFillColor != NULL) {
	    fillColor = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple != None) {
	    fillStipple = polyPtr->disabledFillStipple;
	}
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    if (polyPtr->numPoints == 2) {

	if (color == NULL) {
	    goto done;

	}

	/*
	 * Create a point by using a small circle. (Printer pixels are too
	 * tiny to be used directly...)
	 */

	Tcl_AppendPrintfToObj(psObj,
		"matrix currentmatrix\n"	/* save state */
		"%.15g %.15g translate "	/* go to drawing location */
		"%.15g %.15g scale "		/* scale the drawing */
		"1 0 moveto "			/* correct for origin */
		"0 0 1 0 360 arc\n"		/* make the circle */
		"setmatrix\n",			/* restore state */
		polyPtr->coordPtr[0],
		Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]),
		width/2.0, width/2.0);

	/*
	 * Color it in.
	 */

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);



	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;

    }

    /*
     * Fill the area of the polygon.
     */

    if (fillColor != NULL && polyPtr->numPoints > 3) {
	Tcl_ResetResult(interp);
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", -1);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {
	Tcl_ResetResult(interp);
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (polyPtr->joinStyle == JoinRound) {
	    style = 1;
	} else if (polyPtr->joinStyle == JoinBevel) {
	    style = 2;
	} else {
	    style = 0;
	}
	Tcl_AppendPrintfToObj(psObj, "%d setlinejoin 1 setlinecap\n", style);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




|






<
<

|



|
|






|
|


|


|


|


|


|
|


|


|


|


|



<
<
<
<
<
<
<
<
|
>

<
>


<
<
<
<
<
<
<
|
<
<
<
<
<
|

|
<
<
<
|
<
|
<
>
|

|
>
>
|
<
<
<

|

<
>






|
<







|
|
|

<
<
|
|
<
>
|

|


|








<







<


|

|

|

<
|
<
|
<
>
>
|
|
<
<
<
<
<
<
<
<










1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815


1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861








1862
1863
1864

1865
1866
1867







1868





1869
1870
1871



1872

1873

1874
1875
1876
1877
1878
1879
1880



1881
1882
1883

1884
1885
1886
1887
1888
1889
1890
1891

1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902


1903
1904

1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926

1927
1928
1929
1930
1931
1932
1933
1934

1935

1936

1937
1938
1939
1940








1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
 */

static int
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;
    XColor *color;
    XColor *fillColor;
    Pixmap stipple;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    double width;



    if (polyPtr->numPoints<2 || polyPtr->coordPtr==NULL) {
	return TCL_OK;
    }

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    color = polyPtr->outline.color;
    stipple = polyPtr->fillStipple;
    fillColor = polyPtr->fillColor;
    fillStipple = polyPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth>width) {
	    width = polyPtr->outline.activeWidth;
	}
	if (polyPtr->outline.activeColor!=NULL) {
	    color = polyPtr->outline.activeColor;
	}
	if (polyPtr->outline.activeStipple!=None) {
	    stipple = polyPtr->outline.activeStipple;
	}
	if (polyPtr->activeFillColor!=NULL) {
	    fillColor = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple!=None) {
	    fillStipple = polyPtr->activeFillStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->outline.disabledColor!=NULL) {
	    color = polyPtr->outline.disabledColor;
	}
	if (polyPtr->outline.disabledStipple!=None) {
	    stipple = polyPtr->outline.disabledStipple;
	}
	if (polyPtr->disabledFillColor!=NULL) {
	    fillColor = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple!=None) {
	    fillStipple = polyPtr->disabledFillStipple;
	}
    }








    if (polyPtr->numPoints==2) {
	char string[128];
	if (color == NULL) {

	    return TCL_OK;
	}








	sprintf(string, "%.15g %.15g translate %.15g %.15g",





		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", NULL);

	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (stipple != None) {
	    Tcl_AppendResult(interp, "clip ", NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		return TCL_ERROR;
	    }



	} else {
	    Tcl_AppendResult(interp, "fill\n", NULL);
	}

	return TCL_OK;
    }

    /*
     * Fill the area of the polygon.
     */

    if (fillColor != NULL && polyPtr->numPoints>3) {

	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (fillStipple != None) {


	    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", NULL);
	    }
	} else {
	    Tcl_AppendResult(interp, "eofill\n", NULL);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {

	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}


	if (polyPtr->joinStyle == JoinRound) {
	    style = "1";
	} else if (polyPtr->joinStyle == JoinBevel) {
	    style = "2";
	} else {
	    style = "0";
	}

	Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n", NULL);

	if (Tk_CanvasPsOutline(canvas, itemPtr,

		&(polyPtr->outline)) != TCL_OK) {
	    return TCL_ERROR;
	}
    }








    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvPs.c.

37
38
39
40
41
42
43

44
45
46
47
48
49
50
/*
 * 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.
 */

typedef struct TkPostscriptInfo {

    int x, y, width, height;	/* Area to print, in canvas pixel
				 * coordinates. */
    int x2, y2;			/* x+width and y+height. */
    char *pageXString;		/* String value of "-pagex" option or NULL. */
    char *pageYString;		/* String value of "-pagey" option or NULL. */
    double pageX, pageY;	/* Postscript coordinates (in points)
				 * corresponding to pageXString and







>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * 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.
 */

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. */
    char *pageXString;		/* String value of "-pagex" option or NULL. */
    char *pageYString;		/* String value of "-pagey" option or NULL. */
    double pageX, pageY;	/* Postscript coordinates (in points)
				 * corresponding to pageXString and
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212




213
214

215
216
217
218
219
220
221
				 * "gray", or "color".  Malloc'ed. */
    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. */
    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
				 * 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
				 * standard prolog in the header. Generated in
				 * library/mkpsenc.tcl, stored in the variable
				 * ::tk::ps_preamable [sic]. */
    Tk_Window tkwin;		/* Window to get font pixel/point transform
				 * from. */
} TkPostscriptInfo;

/*
 * The table below provides a template that's used to process arguments to the
 * canvas "postscript" command and fill in TkPostscriptInfo structures.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-colormap", NULL, NULL,
	"", offsetof(TkPostscriptInfo, colorVar), 0, NULL},
    {TK_CONFIG_STRING, "-colormode", NULL, NULL,
	"", offsetof(TkPostscriptInfo, colorMode), 0, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fileName), 0, NULL},
    {TK_CONFIG_STRING, "-channel", NULL, NULL,
	"", offsetof(TkPostscriptInfo, channelName), 0, NULL},
    {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fontVar), 0, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"", offsetof(TkPostscriptInfo, height), 0, NULL},
    {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageAnchor), 0, NULL},
    {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageHeightString), 0, NULL},
    {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageWidthString), 0, NULL},
    {TK_CONFIG_STRING, "-pagex", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageXString), 0, NULL},
    {TK_CONFIG_STRING, "-pagey", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageYString), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
	"", offsetof(TkPostscriptInfo, prolog), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
	"", offsetof(TkPostscriptInfo, rotate), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"", offsetof(TkPostscriptInfo, width), 0, NULL},
    {TK_CONFIG_PIXELS, "-x", NULL, NULL,
	"", offsetof(TkPostscriptInfo, x), 0, NULL},
    {TK_CONFIG_PIXELS, "-y", NULL, NULL,
	"", offsetof(TkPostscriptInfo, y), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int		GetPostscriptPoints(Tcl_Interp *interp,
			    char *string, double *doublePtr);
static void		PostscriptBitmap(Tk_Window tkwin, Pixmap bitmap,
			    int startX, int startY, int width, int height,
			    Tcl_Obj *psObj);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);

/*
 *--------------------------------------------------------------
 *
 * TkCanvPostscriptCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */


int
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, *psInfoPtr = &psInfo;
    Tk_PostscriptInfo oldInfoPtr;
    int result;
    Tk_Item *itemPtr;
#define STRING_LENGTH 400

    const char *p;
    time_t now;
    size_t length;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_DString buffer;
    Tcl_Obj *preambleObj;
    Tcl_Obj *psObj;
    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. */

    /*
     * Get the generic preamble. We only ever bother with the ASCII encoding;
     * the others just make life too complicated and never actually worked as
     * such.
     */

    result = Tcl_EvalEx(interp, "::tk::ensure_psenc_is_loaded", -1, TCL_EVAL_GLOBAL);
    if (result != TCL_OK) {
	return result;
    }
    preambleObj = Tcl_GetVar2Ex(interp, "::tk::ps_preamble", NULL,
	    TCL_LEAVE_ERR_MSG);
    if (preambleObj == NULL) {
	return TCL_ERROR;
    }
    Tcl_IncrRefCount(preambleObj);
    Tcl_ResetResult(interp);
    psObj = Tcl_NewObj();

    /*
     * Initialize the data structure describing Postscript generation, then
     * process all the arguments to fill the data structure in.
     */





    oldInfoPtr = canvasPtr->psInfo;
    canvasPtr->psInfo = (Tk_PostscriptInfo) psInfoPtr;

    psInfo.x = canvasPtr->xOrigin;
    psInfo.y = canvasPtr->yOrigin;
    psInfo.width = -1;
    psInfo.height = -1;
    psInfo.pageXString = NULL;
    psInfo.pageYString = NULL;
    psInfo.pageX = 72*4.25;







|








|
<
<
<
<







|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|
|








<
<
<
<



















>





|








>
|






|
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





>
>
>
>


>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84




85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133




134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182



















183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
				 * "gray", or "color".  Malloc'ed. */
    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. */
    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
				 * 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
				 * 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.
 */

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-colormap", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, colorVar), 0},
    {TK_CONFIG_STRING, "-colormode", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, colorMode), 0},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, fileName), 0},
    {TK_CONFIG_STRING, "-channel", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, channelName), 0},
    {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, fontVar), 0},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, height), 0},
    {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageAnchor), 0},
    {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageHeightString), 0},
    {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageWidthString), 0},
    {TK_CONFIG_STRING, "-pagex", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageXString), 0},
    {TK_CONFIG_STRING, "-pagey", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageYString), 0},
    {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, prolog), 0},
    {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, rotate), 0},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, width), 0},
    {TK_CONFIG_PIXELS, "-x", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, x), 0},
    {TK_CONFIG_PIXELS, "-y", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, y), 0},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int		GetPostscriptPoints(Tcl_Interp *interp,
			    char *string, double *doublePtr);





/*
 *--------------------------------------------------------------
 *
 * TkCanvPostscriptCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

    /* ARGSUSED */
int
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, *psInfoPtr = &psInfo;
    Tk_PostscriptInfo oldInfoPtr;
    int result;
    Tk_Item *itemPtr;
#define STRING_LENGTH 400
    char string[STRING_LENGTH+1];
    CONST char *p;
    time_t now;
    size_t length;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_DString buffer;
    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.
     */

    result = Tcl_EvalEx(interp,psenccmd,-1,TCL_EVAL_GLOBAL);
    if (result != TCL_OK) {
        return result;
    }
    oldInfoPtr = canvasPtr->psInfo;
    canvasPtr->psInfo = (Tk_PostscriptInfo) psInfoPtr;
    psInfo.tkwin = canvasPtr->tkwin;
    psInfo.x = canvasPtr->xOrigin;
    psInfo.y = canvasPtr->yOrigin;
    psInfo.width = -1;
    psInfo.height = -1;
    psInfo.pageXString = NULL;
    psInfo.pageYString = NULL;
    psInfo.pageX = 72*4.25;
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    psInfo.colorMode = NULL;
    psInfo.colorLevel = 0;
    psInfo.fileName = NULL;
    psInfo.channelName = NULL;
    psInfo.chan = NULL;
    psInfo.prepass = 0;
    psInfo.prolog = 1;
    psInfo.tkwin = tkwin;
    Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
    result = Tk_ConfigureWidget(interp, tkwin, configSpecs, argc-2, argv+2,
	    (char *) &psInfo, TK_CONFIG_ARGV_ONLY);
    if (result != TCL_OK) {
	goto cleanup;
    }








<







210
211
212
213
214
215
216

217
218
219
220
221
222
223
    psInfo.colorMode = NULL;
    psInfo.colorLevel = 0;
    psInfo.fileName = NULL;
    psInfo.channelName = NULL;
    psInfo.chan = NULL;
    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);
    if (result != TCL_OK) {
	goto cleanup;
    }

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543
544
545

546
547
548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	if (strncmp(psInfo.colorMode, "monochrome", length) == 0) {
	    psInfo.colorLevel = 0;
	} else if (strncmp(psInfo.colorMode, "gray", length) == 0) {
	    psInfo.colorLevel = 1;
	} else if (strncmp(psInfo.colorMode, "color", length) == 0) {
	    psInfo.colorLevel = 2;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad color mode \"%s\": must be monochrome, gray, or color",
		    psInfo.colorMode));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "COLORMODE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}
    }

    if (psInfo.fileName != NULL) {
	/*
	 * Check that -file and -channel are not both specified.
	 */

	if (psInfo.channelName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify both -file and -channel", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "USAGE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	/*
	 * Check that we are not in a safe interpreter. If we are, disallow
	 * the -file specification.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify -file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PS_FILE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
	if (p == NULL) {
	    goto cleanup;
	}
	psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666);
	Tcl_DStringFree(&buffer);
	if (psInfo.chan == NULL) {
	    goto cleanup;
	}
    }

    if (psInfo.channelName != NULL) {
	int mode;

	/*
	 * Check that the channel is found in this interpreter and that it is
	 * open for writing.
	 */

	psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode);
	if (psInfo.chan == NULL) {
	    result = TCL_ERROR;
	    goto cleanup;
	}
	if (!(mode & TCL_WRITABLE)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel \"%s\" wasn't opened for writing",
		    psInfo.channelName));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "UNWRITABLE",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.
     */

    psInfo.prepass = 1;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if ((itemPtr->x1 >= psInfo.x2) || (itemPtr->x2 < psInfo.x)
		|| (itemPtr->y1 >= psInfo.y2) || (itemPtr->y2 < psInfo.y)) {
	    continue;
	}
	if (itemPtr->typePtr->postscriptProc == NULL) {
	    continue;
	}
	result = itemPtr->typePtr->postscriptProc(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 1);
	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).
	     */

	    break;
	}
    }
    psInfo.prepass = 0;

    /*
     * Generate the header and prolog for the Postscript.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"%!PS-Adobe-3.0 EPSF-3.0\n"
		"%%Creator: Tk Canvas Widget\n", -1);

#ifdef HAVE_PW_GECOS
	if (!Tcl_IsSafe(interp)) {
	    struct passwd *pwPtr = getpwuid(getuid());	/* INTL: Native. */

	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%For: %s\n", (pwPtr ? pwPtr->pw_gecos : "Unknown"));
	    endpwent();
	}
#endif /* HAVE_PW_GECOS */
	Tcl_AppendPrintfToObj(psObj,
		"%%%%Title: Window %s\n", Tk_PathName(tkwin));

	time(&now);
	Tcl_AppendPrintfToObj(psObj,
		"%%%%CreationDate: %s", ctime(&now));	/* INTL: Native. */
	if (!psInfo.rotate) {
	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%BoundingBox: %d %d %d %d\n",
		    (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 {
	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%BoundingBox: %d %d %d %d\n",
		    (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_AppendPrintfToObj(psObj,
		"%%%%Pages: 1\n"
		"%%%%DocumentData: Clean7Bit\n"
		"%%%%Orientation: %s\n",
		psInfo.rotate ? "Landscape" : "Portrait");
	p = "%%%%DocumentNeededResources: font %s\n";
	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj, p,
		    Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	    p = "%%%%+ font %s\n";
	}
	Tcl_AppendToObj(psObj, "%%EndComments\n\n", -1);

	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);


	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
	    channelWriteFailed:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"problem writing postscript data to channel: %s",
			Tcl_PosixError(interp)));
		result = TCL_ERROR;
		goto cleanup;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}

	/*
	 * Document setup:  set the color level and include fonts.
	 */

	Tcl_AppendPrintfToObj(psObj,
		"%%%%BeginSetup\n/CL %d def\n", psInfo.colorLevel);

	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%IncludeResource: font %s\n",
		    (char *) Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	}
	Tcl_AppendToObj(psObj, "%%EndSetup\n\n", -1);

	/*
	 * Page setup: move to page positioning point, rotate if needed, set
	 * scale factor, offset for proper anchor position, and set clip
	 * region.
	 */

	Tcl_AppendToObj(psObj, "%%Page: 1 1\nsave\n", -1);
	Tcl_AppendPrintfToObj(psObj,
		"%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);

	if (psInfo.rotate) {
	    Tcl_AppendToObj(psObj, "90 rotate\n", -1);
	}
	Tcl_AppendPrintfToObj(psObj,
		"%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
	Tcl_AppendPrintfToObj(psObj,
		"%d %d translate\n", deltaX - psInfo.x, deltaY);
	Tcl_AppendPrintfToObj(psObj,

		"%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g "
		"lineto closepath clip newpath\n",
		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));

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);

	    psObj = Tcl_NewObj();
	}
    }

    /*
     * Iterate through all the items, having each relevant one draw itself.
     * Quit if any of the items returns an error.
     */

    result = TCL_OK;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if ((itemPtr->x1 >= psInfo.x2) || (itemPtr->x2 < psInfo.x)
		|| (itemPtr->y1 >= psInfo.y2) || (itemPtr->y2 < psInfo.y)) {
	    continue;
	}
	if (itemPtr->typePtr->postscriptProc == NULL) {
	    continue;
	}
	if (itemPtr->state == TK_STATE_HIDDEN) {
	    continue;
	}

	result = itemPtr->typePtr->postscriptProc(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 0);
	if (result != TCL_OK) {

	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (generating Postscript for item %d)",
		    (int)itemPtr->id));

	    goto cleanup;
	}

	Tcl_AppendToObj(psObj, "gsave\n", -1);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "grestore\n", -1);
	Tcl_ResetResult(interp);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }

    /*
     * Output page-end information, such as commands to print the page and
     * document trailer stuff.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"restore showpage\n\n"
		"%%Trailer\n"
		"end\n"
		"%%EOF\n", -1);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	}
    }

    if (psInfo.chan == NULL) {
	Tcl_SetObjResult(interp, psObj);
	psObj = Tcl_NewObj();
    }

    /*
     * Clean up psInfo to release malloc'ed stuff.
     */

  cleanup:







|
|
<
<
<





|
|
|

|
|
|
<
|
|
|

|
|
|
|

|
|
|
<
|
|
|













|

|
|
|
|

|
|
|
|
|
|
|
|
<
<
|
|
|




















|









<










<
|
|
<




|
|



<
|
>

|
|

<
|







<
|






|
|
|
|
|
|


|
|
|

|





|
>


<
<
|
<
|
<
<
<
<
<






<
|
>


<
|
|

|







|
<
|
>

|

<
|
|
|
|
>
|
<








>
|
<
<
|
|
>
|
<




















|
|


>
|
|
|
>


<
<
<
<
|
<

|
<
<
<
|









<
|
|
<
<
|
|
|
<
<
<
<
|
<
<
<







300
301
302
303
304
305
306
307
308



309
310
311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363


364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406

407
408

409
410
411
412
413
414
415
416
417

418
419
420
421
422
423

424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460


461

462





463
464
465
466
467
468

469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489

490
491
492
493
494
495

496
497
498
499
500
501
502
503
504
505


506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540




541

542
543



544
545
546
547
548
549
550
551
552
553

554
555


556
557
558




559



560
561
562
563
564
565
566
	if (strncmp(psInfo.colorMode, "monochrome", length) == 0) {
	    psInfo.colorLevel = 0;
	} else if (strncmp(psInfo.colorMode, "gray", length) == 0) {
	    psInfo.colorLevel = 1;
	} 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", 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", NULL);

            result = TCL_ERROR;
            goto cleanup;
        }

        /*
         * Check that we are not in a safe interpreter. If we are, disallow
         * the -file specification.
         */

        if (Tcl_IsSafe(interp)) {
            Tcl_AppendResult(interp, "can't specify -file in a",
                    " safe interpreter", NULL);

            result = TCL_ERROR;
            goto cleanup;
        }

	p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
	if (p == NULL) {
	    goto cleanup;
	}
	psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666);
	Tcl_DStringFree(&buffer);
	if (psInfo.chan == NULL) {
	    goto cleanup;
	}
    }

    if (psInfo.channelName != NULL) {
        int mode;

        /*
         * Check that the channel is found in this interpreter and that it is
         * open for writing.
         */

        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", 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.
     */

    psInfo.prepass = 1;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if ((itemPtr->x1 >= psInfo.x2) || (itemPtr->x2 < psInfo.x)
		|| (itemPtr->y1 >= psInfo.y2) || (itemPtr->y2 < psInfo.y)) {
	    continue;
	}
	if (itemPtr->typePtr->postscriptProc == NULL) {
	    continue;
	}
	result = (*itemPtr->typePtr->postscriptProc)(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 1);
	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).
	     */

	    break;
	}
    }
    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", 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", NULL);
	    endpwent();
	}
#endif /* HAVE_PW_GECOS */

	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), NULL);

	if (psInfo.chan != NULL) {


	    Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);

	    Tcl_ResetResult(canvasPtr->interp);





	}

	/*
	 * Document setup:  set the color level and include fonts.
	 */


	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);

	/*
	 * 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);
	Tcl_ResetResult(canvasPtr->interp);

    }

    /*
     * Iterate through all the items, having each relevant one draw itself.
     * Quit if any of the items returns an error.
     */

    result = TCL_OK;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if ((itemPtr->x1 >= psInfo.x2) || (itemPtr->x2 < psInfo.x)
		|| (itemPtr->y1 >= psInfo.y2) || (itemPtr->y2 < psInfo.y)) {
	    continue;
	}
	if (itemPtr->typePtr->postscriptProc == NULL) {
	    continue;
	}
	if (itemPtr->state == TK_STATE_HIDDEN) {
	    continue;
	}
	Tcl_AppendResult(interp, "gsave\n", NULL);
	result = (*itemPtr->typePtr->postscriptProc)(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 0);
	if (result != TCL_OK) {
	    char msg[64 + TCL_INTEGER_SPACE];

	    sprintf(msg, "\n    (generating Postscript for item %d)",
		    itemPtr->id);
	    Tcl_AddErrorInfo(interp, msg);
	    goto cleanup;
	}




	Tcl_AppendResult(interp, "grestore\n", NULL);

	if (psInfo.chan != NULL) {
	    Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);



	    Tcl_ResetResult(interp);
	}
    }

    /*
     * 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", NULL);


    }
    if (psInfo.chan != NULL) {
	Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);




	Tcl_ResetResult(canvasPtr->interp);



    }

    /*
     * Clean up psInfo to release malloc'ed stuff.
     */

  cleanup:
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    if (psInfo.fileName != NULL) {
	ckfree(psInfo.fileName);
    }
    if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) {
	Tcl_Close(interp, psInfo.chan);
    }
    if (psInfo.channelName != NULL) {
	ckfree(psInfo.channelName);
    }
    Tcl_DeleteHashTable(&psInfo.fontTable);
    canvasPtr->psInfo = (Tk_PostscriptInfo) oldInfoPtr;
    Tcl_DecrRefCount(preambleObj);
    Tcl_DecrRefCount(psObj);
    return result;
}

static inline Tcl_Obj *
GetPostscriptBuffer(
    Tcl_Interp *interp)
{
    Tcl_Obj *psObj = Tcl_GetObjResult(interp);

    if (Tcl_IsShared(psObj)) {
	psObj = Tcl_DuplicateObj(psObj);
	Tcl_SetObjResult(interp, psObj);
    }
    return psObj;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptColor --
 *
 *	This function is called by individual canvas items when they want to







|



<
<


<
<
<
<
<
<
<
<
<
<
<
<
<







588
589
590
591
592
593
594
595
596
597
598


599
600













601
602
603
604
605
606
607
    if (psInfo.fileName != NULL) {
	ckfree(psInfo.fileName);
    }
    if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) {
	Tcl_Close(interp, psInfo.chan);
    }
    if (psInfo.channelName != NULL) {
        ckfree(psInfo.channelName);
    }
    Tcl_DeleteHashTable(&psInfo.fontTable);
    canvasPtr->psInfo = (Tk_PostscriptInfo) oldInfoPtr;


    return result;
}














/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptColor --
 *
 *	This function is called by individual canvas items when they want to
697
698
699
700
701
702
703

704

705
706
707
708
709
710
711
712
713
714
715


716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738

739

740
741
742
743

744
745
746
747
748
749
750
int
Tk_PostscriptColor(
    Tcl_Interp *interp,
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    XColor *colorPtr)		/* Information about color. */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;

    double red, green, blue;


    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    /*
     * 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) {


	const char *cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar,
		Tk_NameOfColor(colorPtr), 0);

	if (cmdString != NULL) {
	    Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp),
		    "%s\n", cmdString);
	    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.
     */


    red = ((double) (((int) colorPtr->red) >> 8))/255.0;

    green = ((double) (((int) colorPtr->green) >> 8))/255.0;

    blue = ((double) (((int) colorPtr->blue) >> 8))/255.0;
    Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp),
	    "%.3f %.3f %.3f setrgbcolor AdjustColor\n",
	    red, green, blue);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptFont --







>

>











>
>
|

<

<
|
















>
|
>
|
>
|
<
|

>







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671

672
673
674
675
676
677
678
679
680
681
int
Tk_PostscriptColor(
    Tcl_Interp *interp,
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    XColor *colorPtr)		/* Information about color. */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    int tmp;
    double red, green, blue;
    char string[200];

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    /*
     * 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) {
	CONST char *cmdString;

	cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar,
		Tk_NameOfColor(colorPtr), 0);

	if (cmdString != 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.
     */

    tmp = colorPtr->red;
    red = ((double) (tmp >> 8))/255.0;
    tmp = colorPtr->green;
    green = ((double) (tmp >> 8))/255.0;
    tmp = colorPtr->blue;
    blue = ((double) (tmp >> 8))/255.0;

    sprintf(string, "%.3f %.3f %.3f setrgbcolor AdjustColor\n",
	    red, green, blue);
    Tcl_AppendResult(interp, string, NULL);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptFont --
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794


795
796
797
798
799
800
801
802
803
804
805
806
807
808

809
810
811

812



813
814
815
816
817
818
819
820
821
822
823

824
825
826
827
828



829
830
831
832
833
834
835
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;

    Tcl_DString ds;
    int i, points;
    const char *fontname;

    /*
     * 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.
     */

    if (psInfoPtr->fontVar != NULL) {
	const char *name = Tk_NameOfFont(tkfont);
	Tcl_Obj **objv;
	int objc;
	double size;
	Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0);

	if (list != NULL) {


	    if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK
		    || objc != 2
		    || (fontname = Tcl_GetString(objv[0]))[0] == '\0'
		    || strchr(fontname, ' ') != NULL
		    || Tcl_GetDoubleFromObj(interp, objv[1], &size) != TCL_OK
		    || size <= 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad font map entry for \"%s\": \"%s\"",
			name, Tcl_GetString(list)));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "FONTMAP",
			NULL);
		return TCL_ERROR;
	    }


	    Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp),
		    "/%s findfont %d scalefont%s setfont\n",
		    fontname, (int) size,

		    strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : "");



	    Tcl_CreateHashEntry(&psInfoPtr->fontTable, fontname, &i);
	    return TCL_OK;
	}
    }

    /*
     * Nothing in the font map, so fall back to the old guessing technique.
     */

    Tcl_DStringInit(&ds);
    points = Tk_PostscriptFontName(tkfont, &ds);

    fontname = Tcl_DStringValue(&ds);
    Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp),
	    "/%s findfont %d scalefont%s setfont\n",
	    fontname, (int)(TkFontGetPoints(psInfoPtr->tkwin, points) + 0.5),
	    strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : "");



    Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i);
    Tcl_DStringFree(&ds);

    return TCL_OK;
}

/*







>


<








|






>
>


|
<


|
|
|
<
<



>
|
|
|
>
|
>
>
>











>
|
<
|
<
|
>
>
>







701
702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735


736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760

761

762
763
764
765
766
767
768
769
770
771
772
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 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.
     */

    if (psInfoPtr->fontVar != NULL) {
	CONST char *name = Tk_NameOfFont(tkfont);
	Tcl_Obj **objv;
	int objc;
	double size;
	Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0);

	if (list != NULL) {
	    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,
			"\": \"", Tcl_GetString(list), "\"", NULL);


		return TCL_ERROR;
	    }

	    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;
	}
    }

    /*
     * Nothing in the font map, so fall back to the old guessing technique.
     */

    Tcl_DStringInit(&ds);
    points = Tk_PostscriptFontName(tkfont, &ds);
    sprintf(pointString, "%d", TkFontGetPoints(psInfoPtr->tkwin, points));
    Tcl_AppendResult(interp, "/", Tcl_DStringValue(&ds), " findfont ",

	    pointString, " scalefont ", NULL);

    if (strncasecmp(Tcl_DStringValue(&ds), "Symbol", 7) != 0) {
	Tcl_AppendResult(interp, "ISOEncode ", NULL);
    }
    Tcl_AppendResult(interp, "setfont\n", NULL);
    Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i);
    Tcl_DStringFree(&ds);

    return TCL_OK;
}

/*
859
860
861
862
863
864
865







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
930

931
932
933
934
935
936
937
938

939
940
941
942
943
944
945
    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;








    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    PostscriptBitmap(tkwin, bitmap, startX, startY, width, height,
	    GetPostscriptBuffer(interp));
    return TCL_OK;
}

static void
PostscriptBitmap(
    Tk_Window tkwin,
    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. */
    Tcl_Obj *psObj)		/* Where to append the postscript. */
{
    XImage *imagePtr;
    int charsInLine, x, y, lastX, lastY, value, mask;
    unsigned int totalWidth, totalHeight;
    Window dummyRoot;
    int dummyX, dummyY;
    unsigned dummyBorderwidth, dummyDepth;

    /*
     * 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.
     */

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
    imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
	    totalWidth, totalHeight, 1, XYPixmap);

    Tcl_AppendToObj(psObj, "<", -1);
    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
	for (x = startX; x <= lastX; x++) {
	    if (XGetPixel(imagePtr, x, y)) {
		value |= mask;
	    }
	    mask >>= 1;
	    if (mask == 0) {
		Tcl_AppendPrintfToObj(psObj, "%02x", value);

		mask = 0x80;
		value = 0;
		charsInLine += 2;
		if (charsInLine >= 60) {
		    Tcl_AppendToObj(psObj, "\n", -1);
		    charsInLine = 0;
		}
	    }
	}
	if (mask != 0x80) {
	    Tcl_AppendPrintfToObj(psObj, "%02x", value);

	    mask = 0x80;
	    value = 0;
	    charsInLine += 2;
	}
    }
    Tcl_AppendToObj(psObj, ">", -1);

    XDestroyImage(imagePtr);

}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptStipple --
 *







>
>
>
>
>
>
>





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
<












|
>




|





|
>





<
|

>







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814





















815
816
817
818
819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
867
868
869
    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;
    int charsInLine, x, y, lastX, lastY, value, mask;
    unsigned int totalWidth, totalHeight;
    char string[100];
    Window dummyRoot;
    int dummyX, dummyY;
    unsigned dummyBorderwidth, dummyDepth;

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }






















    /*
     * 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.
     */

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
    imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
	    totalWidth, totalHeight, 1, XYPixmap);
    Tcl_AppendResult(interp, "<", NULL);

    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
	for (x = startX; x <= lastX; x++) {
	    if (XGetPixel(imagePtr, x, y)) {
		value |= mask;
	    }
	    mask >>= 1;
	    if (mask == 0) {
		sprintf(string, "%02x", value);
		Tcl_AppendResult(interp, string, NULL);
		mask = 0x80;
		value = 0;
		charsInLine += 2;
		if (charsInLine >= 60) {
		    Tcl_AppendResult(interp, "\n", NULL);
		    charsInLine = 0;
		}
	    }
	}
	if (mask != 0x80) {
	    sprintf(string, "%02x", value);
	    Tcl_AppendResult(interp, string, NULL);
	    mask = 0x80;
	    value = 0;
	    charsInLine += 2;
	}
    }

    Tcl_AppendResult(interp, ">", NULL);
    XDestroyImage(imagePtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptStipple --
 *
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992





993
994
995
996
997
998
999
1000
1001
1002
1003
1004
    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;

    Window dummyRoot;
    int dummyX, dummyY;
    unsigned dummyBorderwidth, dummyDepth;
    Tcl_Obj *psObj;

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    /*
     * 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.
     */

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
	    (unsigned *) &height, &dummyBorderwidth, &dummyDepth);






    psObj = GetPostscriptBuffer(interp);
    Tcl_AppendPrintfToObj(psObj, "%d %d ", width, height);
    PostscriptBitmap(tkwin, bitmap, 0, 0, width, height, psObj);
    Tcl_AppendToObj(psObj, " StippleFill\n", -1);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptY --







>



<
















>
>
>
>
>
|
<
<
<
|







890
891
892
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922



923
924
925
926
927
928
929
930
    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;
    char string[TCL_INTEGER_SPACE * 2];
    Window dummyRoot;
    int dummyX, dummyY;
    unsigned dummyBorderwidth, dummyDepth;


    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    /*
     * 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.
     */

    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, NULL);
    if (Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, 0, 0,
	    width, height) != TCL_OK) {
	return TCL_ERROR;
    }



    Tcl_AppendResult(interp, " StippleFill\n", NULL);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptY --
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
    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;
    Tcl_Obj *psObj;

    if (psInfoPtr->prepass) {
	return;
    }

    psObj = GetPostscriptBuffer(interp);
    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g moveto\n",
	    coordPtr[0], Tk_PostscriptY(coordPtr[1], psInfo));

    for (numPoints--, coordPtr += 2; numPoints > 0;
	    numPoints--, coordPtr += 2) {
	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n",
		coordPtr[0], Tk_PostscriptY(coordPtr[1], psInfo));

    }
}

/*
 *--------------------------------------------------------------
 *
 * GetPostscriptPoints --







|




<
<
|
|
>


|
|
>







976
977
978
979
980
981
982
983
984
985
986
987


988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
    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];

    if (psInfoPtr->prepass) {
	return;
    }


    sprintf(buffer, "%.15g %.15g moveto\n", coordPtr[0],
	    Tk_PostscriptY(coordPtr[1], psInfo));
    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, NULL);
    }
}

/*
 *--------------------------------------------------------------
 *
 * GetPostscriptPoints --
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "POINTS", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TkImageGetColor --







|
<







1059
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_AppendResult(interp, "bad distance \"", string, "\"", NULL);

    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TkImageGetColor --
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

#ifdef _WIN32
#include <windows.h>

/*
 * We could just define these instead of pulling in windows.h.
 #define GetRValue(rgb)	((BYTE)(rgb))
 #define GetGValue(rgb)	((BYTE)(((WORD)(rgb)) >> 8))
 #define GetBValue(rgb)	((BYTE)((rgb)>>16))
 */

#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 /* _WIN32 */

#if defined(_WIN32) || defined(MAC_OSX_TK)
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{
    (void)cdata;

    *red   = (double) GetRValue(pixel) / 255.0;
    *green = (double) GetGValue(pixel) / 255.0;
    *blue  = (double) GetBValue(pixel) / 255.0;
}
#else /* ! (_WIN32 || MAC_OSX_TK) */
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{







|









|





|

|







<
<




|







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120


1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

#ifdef WIN32
#include <windows.h>

/*
 * We could just define these instead of pulling in windows.h.
 #define GetRValue(rgb)	((BYTE)(rgb))
 #define GetGValue(rgb)	((BYTE)(((WORD)(rgb)) >> 8))
 #define GetBValue(rgb)	((BYTE)((rgb)>>16))
 */

#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 /* WIN32 */

#if defined(WIN32) || defined(MAC_OSX_TK)
static void
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 /* ! (WIN32 || MAC_OSX_TK) */
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
	*blue  = cdata->colors[b].blue / 65535.0;
    } else {
	*red   = cdata->colors[pixel].red / 65535.0;
	*green = cdata->colors[pixel].green / 65535.0;
	*blue  = cdata->colors[pixel].blue / 65535.0;
    }
}
#endif /* _WIN32 || MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *
 * TkPostscriptImage --
 *
 *	This function is called to output the contents of an image in







|







1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
	*blue  = cdata->colors[b].blue / 65535.0;
    } else {
	*red   = cdata->colors[pixel].red / 65535.0;
	*green = cdata->colors[pixel].green / 65535.0;
	*blue  = cdata->colors[pixel].blue / 65535.0;
    }
}
#endif /* WIN32 || MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *
 * TkPostscriptImage --
 *
 *	This function is called to output the contents of an image in
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
    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;

    int xx, yy, band, maxRows;
    double red, green, blue;
    int bytesPerLine = 0, maxWidth = 0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;
    Tcl_Obj *psObj;
    (void)y;

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    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.
     */

    ncolors = visual->map_entries;
    cdata.colors = (XColor *)ckalloc(sizeof(XColor) * ncolors);
    cdata.ncolors = ncolors;

    if (visual->c_class == DirectColor || visual->c_class == TrueColor) {
	cdata.separated = 1;
	cdata.red_mask = visual->red_mask;
	cdata.green_mask = visual->green_mask;
	cdata.blue_mask = visual->blue_mask;
	cdata.red_shift = 0;
	cdata.green_shift = 0;
	cdata.blue_shift = 0;







>


|





<
<














|


|







1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188


1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
    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];
    int xx, yy, band, maxRows;
    double red, green, blue;
    int bytesPerLine=0, maxWidth=0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;



    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    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.
     */

    ncolors = visual->map_entries;
    cdata.colors = (XColor *) ckalloc(sizeof(XColor) * ncolors);
    cdata.ncolors = ncolors;

    if (visual->class == DirectColor || visual->class == TrueColor) {
	cdata.separated = 1;
	cdata.red_mask = visual->red_mask;
	cdata.green_mask = visual->green_mask;
	cdata.blue_mask = visual->blue_mask;
	cdata.red_shift = 0;
	cdata.green_shift = 0;
	cdata.blue_shift = 0;
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369

1370
1371
1372

1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
    } else {
	cdata.separated=0;
	for (i = 0; i < ncolors; i ++) {
	    cdata.colors[i].pixel = i;
	}
    }

    if (visual->c_class == StaticGray || visual->c_class == GrayScale) {
	cdata.color = 0;
    } 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.
     */

    if (!cdata.color && level >= 2) {
	level = 1;
    }

    if (!cdata.color && cdata.ncolors == 2) {
	level = 0;
    }

    /*
     * 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;
    default: bytesPerLine = 3 * width;	     maxWidth = 20000;  break;
    }

    if (bytesPerLine > 60000) {
	Tcl_ResetResult(interp);
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't generate Postscript for images more than %d pixels wide",
		maxWidth));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	ckfree(cdata.colors);
	return TCL_ERROR;
    }

    maxRows = 60000 / bytesPerLine;
    psObj = GetPostscriptBuffer(interp);

    for (band = height-1; band >= 0; band -= maxRows) {
	int rows = (band >= maxRows) ? maxRows : band + 1;
	int lineLen = 0;

	switch (level) {
	case 0:
	    Tcl_AppendPrintfToObj(psObj, "%d %d 1 matrix {\n<", width, rows);

	    break;
	case 1:
	    Tcl_AppendPrintfToObj(psObj, "%d %d 8 matrix {\n<", width, rows);

	    break;
	default:
	    Tcl_AppendPrintfToObj(psObj, "%d %d 8 matrix {\n<", width, rows);

	    break;
	}
	for (yy = band; yy > band - rows; yy--) {
	    switch (level) {
	    case 0: {
		/*
		 * Generate data for image in monochrome mode. No attempt at







|













|
















|




|
|
|
|
|




<







|
>


|
>

|
|
>







1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
    } else {
	cdata.separated=0;
	for (i = 0; i < ncolors; i ++) {
	    cdata.colors[i].pixel = i;
	}
    }

    if (visual->class == StaticGray || visual->class == GrayScale) {
	cdata.color = 0;
    } 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.
     */

    if (!cdata.color && level == 2) {
	level = 1;
    }

    if (!cdata.color && cdata.ncolors == 2) {
	level = 0;
    }

    /*
     * 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;
    }

    if (bytesPerLine > 60000) {
	Tcl_ResetResult(interp);
	sprintf(buffer,
		"Can't generate Postscript for images more than %d pixels wide",
		maxWidth);
	Tcl_AppendResult(interp, buffer, NULL);
	ckfree((char *) cdata.colors);
	return TCL_ERROR;
    }

    maxRows = 60000 / bytesPerLine;


    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, 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
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425

1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445

1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460

1461

1462
1463
1464
1465
1466
1467
1468
1469
1470
		    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) {
			Tcl_AppendPrintfToObj(psObj, "%02X", data);

			lineLen += 2;
			if (lineLen > 60) {
			    lineLen = 0;
			    Tcl_AppendToObj(psObj, "\n", -1);
			}
			mask = 0x80;
			data = 0x00;
		    }
		}
		if ((width % 8) != 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);

		    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);
		    Tcl_AppendPrintfToObj(psObj, "%02X",
			    (int) floor(0.5 + 255.0 *
			    (0.30 * red + 0.59 * green + 0.11 * blue)));

		    lineLen += 2;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		}
		break;
	    default:
		/*
		 * 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);
		    Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			    (int) floor(0.5 + 255.0 * red),
			    (int) floor(0.5 + 255.0 * green),
			    (int) floor(0.5 + 255.0 * blue));

		    lineLen += 6;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		}
		break;
	    }
	}
	switch (level) {
	case 0: case 1:
	    Tcl_AppendToObj(psObj, ">\n} image\n", -1); break;
	default:
	    Tcl_AppendToObj(psObj, ">\n} false 3 colorimage\n", -1); break;
	}

	Tcl_AppendPrintfToObj(psObj, "0 %d translate\n", rows);

    }
    ckfree(cdata.colors);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptPhoto --







|
>



|

|
|



|
>
|
|












<
|

>



|



|








|



>



|







|
|
|

>
|
>

|







1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348

1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
		    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, 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;
		}
		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;
	    }
	}
	switch (level) {
	case 0: case 1:
	    sprintf(buffer, ">\n} image\n"); break;
	case 2:
	    sprintf(buffer, ">\n} false 3 colorimage\n"); break;
	}
	Tcl_AppendResult(interp, buffer, NULL);
	sprintf(buffer, "0 %d translate\n", rows);
	Tcl_AppendResult(interp, buffer, NULL);
    }
    ckfree((char *) cdata.colors);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptPhoto --
1490
1491
1492
1493
1494
1495
1496

1497
1498


1499
1500

1501

1502
1503
1504
1505
1506
1507

1508
1509
1510








1511
1512
1513
1514
1515


1516











1517

























































1518
1519
1520
1521


1522




































1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568

1569
1570


1571

1572

1573
1574
1575
1576
1577
1578
1579
1580
1581
    Tcl_Interp *interp,
    Tk_PhotoImageBlock *blockPtr,
    Tk_PostscriptInfo psInfo,
    int width, int height)
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    int colorLevel = psInfoPtr->colorLevel;

    const char *displayOperation, *decode;
    unsigned char *pixelPtr;


    int bpc, xx, yy, lineLen, alpha;
    float red, green, blue;

    int bytesPerLine = 0, maxWidth = 0;

    unsigned char opaque = 255;
    unsigned char *alphaPtr;
    int alphaOffset, alphaPitch, alphaIncr;
    Tcl_Obj *psObj;

    if (psInfoPtr->prepass) {

	return TCL_OK;
    }









    if (colorLevel != 0) {
	/*
	 * Color and gray-scale code.
	 */



	displayOperation = "TkPhotoColor";











    } else {

























































	/*
	 * Monochrome-only code
	 */



	displayOperation = "TkPhotoMono";




































    }

    /*
     * 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;
    default: bytesPerLine = 3 * width;	    maxWidth = 20000;  break;
    }
    if (bytesPerLine > 60000) {
	Tcl_ResetResult(interp);
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't generate Postscript for images more than %d pixels wide",
		maxWidth));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	return TCL_ERROR;
    }

    /*
     * Set up the postscript code except for the image-data stream.
     */

    psObj = GetPostscriptBuffer(interp);
    switch (colorLevel) {
    case 0:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1);
	decode = "1 0";
	bpc = 1;
	break;
    case 1:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1);
	decode = "0 1";
	bpc = 8;
	break;
    default:
	Tcl_AppendToObj(psObj, "/DeviceRGB setcolorspace\n\n", -1);
	decode = "0 1 0 1 0 1";
	bpc = 8;
	break;
    }

    Tcl_AppendPrintfToObj(psObj,

	    "<<\n  /ImageType 1\n"
	    "  /Width %d\n  /Height %d\n  /BitsPerComponent %d\n"


	    "  /DataSource currentfile\n  /ASCIIHexDecode filter\n"

	    "  /ImageMatrix [1 0 0 -1 0 %d]\n  /Decode [%s]\n>>\n"

	    "1 %s\n",
	    width, height, bpc, height, decode, displayOperation);

    /*
     * 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.
     */








>
|

>
>
|

>
|
>



<


>



>
>
>
>
>
>
>
>
|




>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|



|
|
|
|







<


|
|



|
|



|
|




|
>
|
|
>
>
|
>
|
>
|
<







1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598

1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627

1628
1629
1630
1631
1632
1633
1634
    Tcl_Interp *interp,
    Tk_PhotoImageBlock *blockPtr,
    Tk_PostscriptInfo psInfo,
    int width, int height)
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    int colorLevel = psInfoPtr->colorLevel;
    static int codeIncluded = 0;

    unsigned char *pixelPtr;
    char buffer[256], cspace[40], decode[40];
    int bpc;
    int xx, yy, lineLen;
    float red, green, blue;
    int alpha;
    int bytesPerLine=0, maxWidth=0;

    unsigned char opaque = 255;
    unsigned char *alphaPtr;
    int alphaOffset, alphaPitch, alphaIncr;


    if (psInfoPtr->prepass) {
	codeIncluded = 0;
	return TCL_OK;
    }

    /*
     * 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)) {
	/*
	 * Color and gray-scale code.
	 */

	codeIncluded = !0;
	Tcl_AppendResult(interp,
		"/TkPhoto { \n",
		"  gsave \n",
		"  32 dict begin \n",
		"  /tinteger exch def \n",
		"  /transparent 1 string def \n",
		"  transparent 0 tinteger put \n",
		"  /olddict exch def \n",
		"  olddict /DataSource get dup type /filetype ne { \n",
		"    olddict /DataSource 3 -1 roll \n",
		"    0 () /SubFileDecode filter put \n",
		"  } { \n",
		"    pop \n",
		"  } ifelse \n",
		"  /newdict olddict maxlength dict def \n",
		"  olddict newdict copy pop \n",
		"  /w newdict /Width get def \n",
		"  /crpp newdict /Decode get length 2 idiv def \n",
		"  /str w string def \n",
		"  /pix w crpp mul string def \n",
		"  /substrlen 2 w log 2 log div floor exp cvi def \n",
		"  /substrs [ \n",
		"  { \n",
		"     substrlen string \n",
		"     0 1 substrlen 1 sub { \n",
		"       1 index exch tinteger put \n",
		"     } for \n",
		"     /substrlen substrlen 2 idiv def \n",
		"     substrlen 0 eq {exit} if \n",
		"  } loop \n",
		"  ] def \n",
		"  /h newdict /Height get def \n",
		"  1 w div 1 h div matrix scale \n",
		"  olddict /ImageMatrix get exch matrix concatmatrix \n",
		"  matrix invertmatrix concat \n",
		"  newdict /Height 1 put \n",
		"  newdict /DataSource pix put \n",
		"  /mat [w 0 0 h 0 0] def \n",
		"  newdict /ImageMatrix mat put \n",
		"  0 1 h 1 sub { \n",
		"    mat 5 3 -1 roll neg put \n",
		"    olddict /DataSource get str readstring pop pop \n",
		"    /tail str def \n",
		"    /x 0 def \n",
		"    olddict /DataSource get pix readstring pop pop \n",
		"    { \n",
		"      tail transparent search dup /done exch not def \n",
		"      {exch pop exch pop} if \n",
		"      /w1 exch length def \n",
		"      w1 0 ne { \n",
		"        newdict /DataSource ",
		          " pix x crpp mul w1 crpp mul getinterval put \n",
		"        newdict /Width w1 put \n",
		"        mat 4 x neg put \n",
		"        /x x w1 add def \n",
		"        newdict image \n",
		"        /tail tail w1 tail length w1 sub getinterval def \n",
		"      } if \n",
		"      done {exit} if \n",
		"      tail substrs { \n",
		"        anchorsearch {pop} if \n",
		"      } forall \n",
		"      /tail exch def \n",
		"      tail length 0 eq {exit} if \n",
		"      /x w tail length sub def \n",
		"    } loop \n",
		"  } for \n",
		"  end \n",
		"  grestore \n",
		"} bind def \n\n\n", NULL);
    } else if (!codeIncluded && (colorLevel == 0)) {
	/*
	 * Monochrome-only code
	 */

	codeIncluded = !0;
	Tcl_AppendResult(interp,
		"/TkPhoto { \n",
		"  gsave \n",
		"  32 dict begin \n",
		"  /dummyInteger exch def \n",
		"  /olddict exch def \n",
		"  olddict /DataSource get dup type /filetype ne { \n",
		"    olddict /DataSource 3 -1 roll \n",
		"    0 () /SubFileDecode filter put \n",
		"  } { \n",
		"    pop \n",
		"  } ifelse \n",
		"  /newdict olddict maxlength dict def \n",
		"  olddict newdict copy pop \n",
		"  /w newdict /Width get def \n",
		"  /pix w 7 add 8 idiv string def \n",
		"  /h newdict /Height get def \n",
		"  1 w div 1 h div matrix scale \n",
		"  olddict /ImageMatrix get exch matrix concatmatrix \n",
		"  matrix invertmatrix concat \n",
		"  newdict /Height 1 put \n",
		"  newdict /DataSource pix put \n",
		"  /mat [w 0 0 h 0 0] def \n",
		"  newdict /ImageMatrix mat put \n",
		"  0 1 h 1 sub { \n",
		"    mat 5 3 -1 roll neg put \n",
		"    0.000 0.000 0.000 setrgbcolor \n",
		"    olddict /DataSource get pix readstring pop pop \n",
		"    newdict /DataSource pix put \n",
		"    newdict imagemask \n",
		"    1.000 1.000 1.000 setrgbcolor \n",
		"    olddict /DataSource get pix readstring pop pop \n",
		"    newdict /DataSource pix put \n",
		"    newdict imagemask \n",
		"  } for \n",
		"  end \n",
		"  grestore \n",
		"} 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).
     */

    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, NULL);
	return TCL_ERROR;
    }

    /*
     * Set up the postscript code except for the image-data stream.
     */


    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;
    }


    Tcl_AppendResult(interp, cspace, " setcolorspace\n\n", NULL);

    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", 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:
     *     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.
     */

1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

    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
	     * transparencies 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 ++) {







|







1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666

    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.
	     */

	    unsigned char mask = 0x80;
	    unsigned char data = 0x00;

	    for (xx = 0; xx< width; xx ++) {
1627
1628
1629
1630
1631
1632
1633
1634

1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652

		if ((alpha != 0) &&
			(0.3086*red + 0.6094*green + 0.082*blue < 128)) {
		    data |= mask;
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);

		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);

		mask = 0x80;
		data = 0x00;
	    }

	    mask = 0x80;
	    data = 0x00;
	    for (xx=0 ; xx<width ; xx++) {







|
>



|






|
>







1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707

		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", 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++) {
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684

1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699

1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784

		if ((alpha != 0) &&
			(0.3086*red + 0.6094*green + 0.082*blue >= 128)) {
		    data |= mask;
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);

		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);

		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);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);

		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }

	    /*
	     * 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)
			+ (xx *blockPtr->pixelSize);

		red = pixelPtr[blockPtr->offset[0]];
		green = pixelPtr[blockPtr->offset[1]];
		blue = pixelPtr[blockPtr->offset[2]];

		Tcl_AppendPrintfToObj(psObj, "%02X", (int) floor(0.5 +
			( 0.3086 * red + 0.6094 * green + 0.0820 * blue)));

		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }
	    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);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);

		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }

	    /*
	     * 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);

		Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			pixelPtr[blockPtr->offset[0]],
			pixelPtr[blockPtr->offset[1]],
			pixelPtr[blockPtr->offset[2]]);

		lineLen += 6;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }
	    break;
	}
    }

    /*
     * The end-of-data marker.
     */

    Tcl_AppendToObj(psObj, ">\n", -1);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>



|






|
>














|
>



|
















|

>



|













|
>



|












|



>



|






<
<
<
|
<










1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830



1831

1832
1833
1834
1835
1836
1837
1838
1839
1840
1841

		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", 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.
	     */

	    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, 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.
	     */

	    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.
	     */

	    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;
	}
    }




    Tcl_AppendResult(interp, ">\n", NULL);

    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvText.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
/*
 * tkCanvText.c --
 *
 *	This file implements text 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each text item.
 */












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tkCanvText.c --
 *
 *	This file implements text 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each text item.
 */
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				 * (and shared with) the generic canvas
				 * code. */
    /*
     * Fields that are set by widget commands other than "configure".
     */

    double x, y;		/* Positioning point for text. */
    TkSizeT insertPos;		/* Character index of character just before
				 * which the insertion cursor is displayed. */

    /*
     * Configuration settings that are updated by Tk_ConfigureWidget.
     */

    Tk_Anchor anchor;		/* Where to anchor text relative to (x,y). */







|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
				 * (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. */

    /*
     * Configuration settings that are updated by Tk_ConfigureWidget.
     */

    Tk_Anchor anchor;		/* Where to anchor text relative to (x,y). */
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89

90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    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 underline;		/* Index of character to put underline beneath
				 * or -1 for no underlining. */
    double angle;		/* What angle, in degrees, to draw the text
				 * at. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    TkSizeT numChars;		/* Length of text in characters. */
    TkSizeT numBytes;		/* Length of text in bytes. */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int actualWidth;		/* Width of text as computed. Used to make



				 * selections of wrapped text display
				 * right. */
    double drawOrigin[2];	/* Where we start drawing from. */
    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. */
    double sine;		/* Sine of angle field. */
    double cosine;		/* Cosine of angle field. */
} TextItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)

};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_DOUBLE, "-angle", NULL, NULL,
	"0.0", offsetof(TextItem, angle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(TextItem, color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_FONT, "-font", NULL, NULL,
	DEF_CANVTEXT_FONT, offsetof(TextItem, tkfont), 0, NULL},
    {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL,
	"left", offsetof(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(TextItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_STRING, "-text", NULL, NULL,
	"", offsetof(TextItem, text), 0, NULL},
    {TK_CONFIG_INT, "-underline", NULL, NULL,
	"-1", offsetof(TextItem, underline), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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 TkSizeT	GetSelText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT offset, char *buffer,
			    TkSizeT maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static void		ScaleText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		SetTextCursor(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
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		RotateText(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
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
 * functions that can be invoked by generic item code.
 */







<
<






|
|

|
>
>
>
|
|
<






<
<






|
>
|

|
>
|

|
|
>


|

|

|

|
<
<

|

|

|

|

|

|


|

|



|

|

|
|









|


|





|
|
|


|




|


|

|

|






<
<







51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172


173
174
175
176
177
178
179
    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 underline;		/* Index of character to put underline beneath
				 * or -1 for no underlining. */



    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    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. */

    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. */


} TextItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE)
};

static Tk_ConfigSpec configSpecs[] = {
    {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", NULL, NULL,
	DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0},
    {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", 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_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, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int offset, char *buffer,
			    int maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    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(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(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
 * functions that can be invoked by generic item code.
 */
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    DisplayCanvText,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    TextToPoint,		/* pointProc */
    TextToArea,			/* areaProc */
    TextToPostscript,		/* postscriptProc */
    ScaleText,			/* scaleProc */
    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */
    GetSelText,			/* selectionProc */
    TextInsert,			/* insertProc */
    TextDeleteChars,		/* dTextProc */
    NULL,			/* nextPtr */
    RotateText,			/* rotateProc */
    0, NULL, NULL
};

#define ROUND(d) ((int) floor((d) + 0.5))

/*
 *--------------------------------------------------------------
 *
 * CreateText --
 *
 *	This function is invoked to create a new text item in a canvas.







|





<
<

<
<







189
190
191
192
193
194
195
196
197
198
199
200
201


202


203
204
205
206
207
208
209
    DisplayCanvText,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    TextToPoint,		/* pointProc */
    TextToArea,			/* areaProc */
    TextToPostscript,		/* postscriptProc */
    ScaleText,			/* scaleProc */
    TranslateText,		/* translateProc */
    (Tk_ItemIndexProc *) GetTextIndex,/* indexProc */
    SetTextCursor,		/* icursorProc */
    GetSelText,			/* selectionProc */
    TextInsert,			/* insertProc */
    TextDeleteChars,		/* dTextProc */
    NULL,			/* nextPtr */


};



/*
 *--------------------------------------------------------------
 *
 * CreateText --
 *
 *	This function is invoked to create a new text item in a canvas.
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
static int
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. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
     * errors during the the remainder of this function.
     */








|





|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
static int
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. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int i;

    if (objc == 0) {
	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 function.
     */

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    textPtr->justify	= TK_JUSTIFY_LEFT;
    textPtr->stipple	= None;
    textPtr->activeStipple = None;
    textPtr->disabledStipple = None;
    textPtr->text	= NULL;
    textPtr->width	= 0;
    textPtr->underline	= -1;
    textPtr->angle	= 0.0;

    textPtr->numChars	= 0;
    textPtr->numBytes	= 0;
    textPtr->textLayout = NULL;
    textPtr->actualWidth = 0;
    textPtr->drawOrigin[0] = textPtr->drawOrigin[1] = 0.0;
    textPtr->gc		= NULL;
    textPtr->selTextGC	= NULL;
    textPtr->cursorOffGC = NULL;
    textPtr->sine	= 0.0;
    textPtr->cosine	= 1.0;

    /*
     * 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 {
	const char *arg = Tcl_GetString(objv[1]);

	i = 2;
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if ((TextCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {







<




|
|



<
<









|







255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    textPtr->justify	= TK_JUSTIFY_LEFT;
    textPtr->stipple	= None;
    textPtr->activeStipple = None;
    textPtr->disabledStipple = None;
    textPtr->text	= NULL;
    textPtr->width	= 0;
    textPtr->underline	= -1;


    textPtr->numChars	= 0;
    textPtr->numBytes	= 0;
    textPtr->textLayout = NULL;
    textPtr->leftEdge	= 0;
    textPtr->rightEdge	= 0;
    textPtr->gc		= NULL;
    textPtr->selTextGC	= NULL;
    textPtr->cursorOffGC = NULL;



    /*
     * 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;
	}
    }
    if ((TextCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369







370
371
372
373
374
375
376
static int
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, ... */
{
    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);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
	return TCL_OK;
    } else if (objc > 2) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	return TCL_ERROR;
    }

    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	} else if (objc != 2) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # coordinates: expected 2, got %d", objc));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	    return TCL_ERROR;
	}
    }
    if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&textPtr->x) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		&textPtr->y) != TCL_OK)) {
	return TCL_ERROR;
    }
    ComputeTextBbox(canvas, textPtr);







    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigureText --







|





<

>




<
|
<
<
<
<
<
<
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>







316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334

335






336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
static int
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, ... */
{
    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);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);

    } else if (objc < 3) {






	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf, "wrong # coordinates: expected 2, got %d", objc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &textPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &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;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigureText --
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

static int
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;
    GC newGC, newSelGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    XColor *selBgColorPtr;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if (textPtr->activeColor != NULL || textPtr->activeStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    color = textPtr->color;
    stipple = textPtr->stipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor != NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple != None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (textPtr->disabledColor != NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple != None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    newGC = newSelGC = NULL;
    if (textPtr->tkfont != NULL) {
	gcValues.font = Tk_FontId(textPtr->tkfont);







|















|
















|
|




|
|


|


|
|


|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

static int
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;
    GC newGC, newSelGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    XColor *selBgColorPtr;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if (textPtr->activeColor != NULL || textPtr->activeStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    color = textPtr->color;
    stipple = textPtr->stipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor!=NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple!=None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (textPtr->disabledColor!=NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple!=None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    newGC = newSelGC = NULL;
    if (textPtr->tkfont != NULL) {
	gcValues.font = Tk_FontId(textPtr->tkfont);
496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    } else {
	newGC = NULL;
    }
    if (textPtr->cursorOffGC != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), textPtr->cursorOffGC);
    }
    textPtr->cursorOffGC = newGC;


    /*
     * 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 + 1 >= textPtr->numChars + 1) {
	    textInfoPtr->selItemPtr = NULL;
	} else {
	    if (textInfoPtr->selectLast + 1 >= textPtr->numChars + 1) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor + 1 >= textPtr->numChars + 1)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos + 1 >= textPtr->numChars + 1) {
	textPtr->insertPos = textPtr->numChars;
    }

    /*
     * Restrict so that 0.0 <= angle < 360.0, and then recompute the cached
     * sine and cosine of the angle. Note that fmod() can produce negative
     * results, and we try to avoid negative zero as well.
     */

    textPtr->angle = fmod(textPtr->angle, 360.0);
    if (textPtr->angle < 0.0) {
	textPtr->angle += 360.0;
    }
    if (textPtr->angle == 0.0) {
	textPtr->angle = 0.0;
    }
    textPtr->sine = sin(textPtr->angle * PI/180.0);
    textPtr->cosine = cos(textPtr->angle * PI/180.0);

    ComputeTextBbox(canvas, textPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *







>










|


|



|




|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
















522
523
524
525
526
527
528
    } else {
	newGC = NULL;
    }
    if (textPtr->cursorOffGC != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), textPtr->cursorOffGC);
    }
    textPtr->cursorOffGC = newGC;


    /*
     * 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 {
	    if (textInfoPtr->selectLast >= textPtr->numChars) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor >= textPtr->numChars)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos >= textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    }

















    ComputeTextBbox(canvas, textPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
static void
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;
    (void)canvas;

    if (textPtr->color != NULL) {
	Tk_FreeColor(textPtr->color);
    }
    if (textPtr->activeColor != NULL) {
	Tk_FreeColor(textPtr->activeColor);
    }







<







543
544
545
546
547
548
549

550
551
552
553
554
555
556
static void
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;


    if (textPtr->color != NULL) {
	Tk_FreeColor(textPtr->color);
    }
    if (textPtr->activeColor != NULL) {
	Tk_FreeColor(textPtr->activeColor);
    }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

static void
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, i;
    Tk_State state = textPtr->header.state;
    double x[4], y[4], dx[4], dy[4], sinA, cosA, tmp;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    Tk_FreeTextLayout(textPtr->textLayout);
    textPtr->textLayout = Tk_ComputeTextLayout(textPtr->tkfont,
	    textPtr->text, textPtr->numChars, textPtr->width,
	    textPtr->justify, 0, &width, &height);

    if (state == TK_STATE_HIDDEN || textPtr->color == NULL) {
	width = height = 0;
    }

    /*
     * Use overall geometry information to compute the top-left corner of the
     * bounding box for the text item.
     */

    leftX = ROUND(textPtr->x);
    topY = ROUND(textPtr->y);
    for (i=0 ; i<4 ; i++) {
	dx[i] = dy[i] = 0.0;
    }
    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;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height / 2;
	}
	break;

    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	topY -= height;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height;
	}
	break;
    }
    switch (textPtr->anchor) {
    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;
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width / 2;
	}
	break;

    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	leftX -= width;
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width;
	}
	break;
    }

    textPtr->actualWidth = width;

    sinA = textPtr->sine;
    cosA = textPtr->cosine;
    textPtr->drawOrigin[0] = textPtr->x + dx[0]*cosA + dy[0]*sinA;
    textPtr->drawOrigin[1] = textPtr->y + dy[0]*cosA - dx[0]*sinA;

    /*
     * 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;
    fudge = (textInfoPtr->insertWidth + 1) / 2;
    if (textInfoPtr->selBorderWidth > fudge) {
	fudge = textInfoPtr->selBorderWidth;
    }

    /*
     * Apply the rotation before computing the bounding box.
     */

    dx[0] -= fudge;
    dx[1] += width + fudge;
    dx[2] += width + fudge;
    dy[2] += height;
    dx[3] -= fudge;
    dy[3] += height;
    for (i=0 ; i<4 ; i++) {
	x[i] = textPtr->x + dx[i] * cosA + dy[i] * sinA;
	y[i] = textPtr->y + dy[i] * cosA - dx[i] * sinA;
    }

    /*
     * Convert to a rectilinear bounding box.
     */

    for (i=1,tmp=x[0] ; i<4 ; i++) {
	if (x[i] < tmp) {
	    tmp = x[i];
	}
    }
    textPtr->header.x1 = ROUND(tmp);
    for (i=1,tmp=y[0] ; i<4 ; i++) {
	if (y[i] < tmp) {
	    tmp = y[i];
	}
    }
    textPtr->header.y1 = ROUND(tmp);
    for (i=1,tmp=x[0] ; i<4 ; i++) {
	if (x[i] > tmp) {
	    tmp = x[i];
	}
    }
    textPtr->header.x2 = ROUND(tmp);
    for (i=1,tmp=y[0] ; i<4 ; i++) {
	if (y[i] > tmp) {
	    tmp = y[i];
	}
    }
    textPtr->header.y2 = ROUND(tmp);
}

/*
 *--------------------------------------------------------------
 *
 * DisplayCanvText --
 *







|

<

|
|
















|
|
<
<
<










<
<
<






<
<
<












<
<
<






<
<
<



<
<
|
|
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|







605
606
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634



635
636
637
638
639
640
641
642
643
644



645
646
647
648
649
650



651
652
653
654
655
656
657
658
659
660
661
662



663
664
665
666
667
668



669
670
671


672
673


674
675
676
677
678
679
680
681
682
683
684
685

























686





687





688





689
690
691
692
693
694
695
696

static void
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;
    Tk_State state = textPtr->header.state;


    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    Tk_FreeTextLayout(textPtr->textLayout);
    textPtr->textLayout = Tk_ComputeTextLayout(textPtr->tkfont,
	    textPtr->text, textPtr->numChars, textPtr->width,
	    textPtr->justify, 0, &width, &height);

    if (state == TK_STATE_HIDDEN || textPtr->color == NULL) {
	width = height = 0;
    }

    /*
     * 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;
    }
    switch (textPtr->anchor) {
    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_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	leftX -= width;



	break;
    }



    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).
     */

    textInfoPtr = textPtr->textInfoPtr;
    fudge = (textInfoPtr->insertWidth + 1) / 2;
    if (textInfoPtr->selBorderWidth > fudge) {
	fudge = textInfoPtr->selBorderWidth;
    }

























    textPtr->header.x1 = leftX - fudge;





    textPtr->header.y1 = topY;





    textPtr->header.x2 = leftX + width + fudge;





    textPtr->header.y2 = topY + height;
}

/*
 *--------------------------------------------------------------
 *
 * DisplayCanvText --
 *
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
    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;
    Tk_CanvasTextInfo *textInfoPtr;
    TkSizeT selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    stipple = textPtr->stipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeStipple != None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (textPtr->disabledStipple != None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    if (textPtr->gc == NULL) {
	return;
    }

    /*
     * 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) {
	Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset);
    }

    selFirstChar = TCL_INDEX_NONE;
    selLastChar = 0;
    Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0],
	    textPtr->drawOrigin[1], &drawableX, &drawableY);

    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar + 1 > textPtr->numChars + 1 ) {
	    selLastChar = textPtr->numChars - 1;
	}
	if (((int)selFirstChar >= 0) && (selFirstChar + 1 <= selLastChar + 1 )) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */








|







|
|


|
|


|
|


















|
|
<
<




|


|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758


759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
    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;
    Tk_CanvasTextInfo *textInfoPtr;
    int selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;

    if(state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    stipple = textPtr->stipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeStipple!=None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (textPtr->disabledStipple!=None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    if (textPtr->gc == NULL) {
	return;
    }

    /*
     * 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) {
	Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset);
    }

    selFirstChar = -1;
    selLastChar = 0;		/* lint. */



    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar > textPtr->numChars) {
	    selLastChar = textPtr->numChars - 1;
	}
	if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883


884
885
886
887
888
889
890
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937


938
939
940
941
942
943
944
945
946
947
948


949
950
951
952
953
954
955
956
957
958
959
960
961
962



963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
	     * However, for the last line we only want to display up to the
	     * last character, not the end of the line.
	     */

	    x = xFirst;
	    height = hFirst;
	    for (y = yFirst ; y <= yLast; y += height) {
		int dx1, dy1, dx2, dy2;
		double s = textPtr->sine, c = textPtr->cosine;
		XPoint points[4];

		if (y == yLast) {
		    width = xLast + wLast - x;
		} else {
		    width = textPtr->actualWidth - x;
		}


		dx1 = x - textInfoPtr->selBorderWidth;
		dy1 = y;
		dx2 = width + 2 * textInfoPtr->selBorderWidth;
		dy2 = height;
		points[0].x = (short)(drawableX + dx1*c + dy1*s);
		points[0].y = (short)(drawableY + dy1*c - dx1*s);
		points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s);
		points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s);
		points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s);
		points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s);
		points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s);
		points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s);
		Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable,
			textInfoPtr->selBorder, points, 4,

			textInfoPtr->selBorderWidth, TK_RELIEF_RAISED);
		x = 0;
	    }
	}
    }

    /*
     * 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.
     */

    if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) {
	if (Tk_CharBbox(textPtr->textLayout, textPtr->insertPos,
		&x, &y, NULL, &height)) {
	    int dx1, dy1, dx2, dy2;
	    double s = textPtr->sine, c = textPtr->cosine;
	    XPoint points[4];

	    dx1 = x - (textInfoPtr->insertWidth / 2);
	    dy1 = y;
	    dx2 = textInfoPtr->insertWidth;
	    dy2 = height;
	    points[0].x = (short)(drawableX + dx1*c + dy1*s);
	    points[0].y = (short)(drawableY + dy1*c - dx1*s);
	    points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s);
	    points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s);
	    points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s);
	    points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s);
	    points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s);
	    points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s);

	    Tk_SetCaretPos(Tk_CanvasTkwin(canvas), points[0].x, points[0].y,
		    height);
	    if (textInfoPtr->cursorOn) {
		Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable,
			textInfoPtr->insertBorder, points, 4,


			textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED);
	    } else if (textPtr->cursorOffGC != NULL) {
		/*
		 * 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.
		 */

		XFillPolygon(display, drawable, textPtr->cursorOffGC,
			points, 4, Convex, CoordModeOrigin);


	    }
	}
    }

    /*
     * 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 ((selFirstChar != TCL_INDEX_NONE) && (textPtr->selTextGC != textPtr->gc)) {
	if (0 < selFirstChar) {
	    TkDrawAngledTextLayout(display, drawable, textPtr->gc,
		    textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		    0, selFirstChar);
	}
	TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC,
		textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		selFirstChar, selLastChar + 1);
	if (selLastChar + 1 < textPtr->numChars) {
	    TkDrawAngledTextLayout(display, drawable, textPtr->gc,
		    textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		    selLastChar + 1, textPtr->numChars);
	}
    } else {
	TkDrawAngledTextLayout(display, drawable, textPtr->gc,
		textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		0, textPtr->numChars);
    }
    TkUnderlineAngledTextLayout(display, drawable, textPtr->gc,
	    textPtr->textLayout, drawableX, drawableY, textPtr->angle,
	    textPtr->underline);

    if (stipple != None) {
	XSetTSOrigin(display, textPtr->gc, 0, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TextInsert --
 *
 *	Insert characters into a text item at a given position.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The text in the given item is modified. The cursor and selection
 *	positions are also modified to reflect the insertion.
 *
 *----------------------------------------------------------------------
 */

static void
TextInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Text item to be modified. */
    TkSizeT index,			/* Character index before which string is to
				 * be inserted. */
    Tcl_Obj *obj)		/* New characters to be inserted. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    TkSizeT byteCount;
    char *newStr, *text;
    const char *string;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = TkGetStringFromObj(obj, &byteCount);

    text = textPtr->text;

    if (index == TCL_INDEX_NONE) {
	index = 0;
    }
    if (index + 1 > textPtr->numChars + 1) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }

    newStr = (char *)ckalloc(textPtr->numBytes + byteCount + 1);
    memcpy(newStr, text, byteIndex);
    strcpy(newStr + byteIndex, string);
    strcpy(newStr + byteIndex + byteCount, text + byteIndex);

    ckfree(text);
    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.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst + 1 >= index + 1) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast + 1 >= index + 1) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 >= index + 1)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos + 1 >= index + 1) {
	textPtr->insertPos += charsAdded;
    }
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------







<
<
<
<



|

>
>
|
|
<
<
|
<
<
<
<
<
<
<
|
|
>
|

















|
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
|
|


|
|
>
>









|
|
>
>














>
>
>
|
<
|
<
|
<
|
|
|
<
|
|
<
<

|
|
<

|
<
|







|












|






|

|


|
<

<


|



|


|








|
|















|


|



|



|







782
783
784
785
786
787
788




789
790
791
792
793
794
795
796
797


798







799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820


821
822

823









824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862

863

864

865
866
867

868
869


870
871
872

873
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

909

910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
	     * However, for the last line we only want to display up to the
	     * last character, not the end of the line.
	     */

	    x = xFirst;
	    height = hFirst;
	    for (y = yFirst ; y <= yLast; y += height) {




		if (y == yLast) {
		    width = xLast + wLast - x;
		} else {
		    width = textPtr->rightEdge - textPtr->leftEdge - x;
		}
		Tk_CanvasDrawableCoords(canvas,
			(double) (textPtr->leftEdge + x
				- textInfoPtr->selBorderWidth),
			(double) (textPtr->header.y1 + y),


			&drawableX, &drawableY);







		Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable,
			textInfoPtr->selBorder, drawableX, drawableY,
			width + 2 * textInfoPtr->selBorderWidth,
			height, textInfoPtr->selBorderWidth, TK_RELIEF_RAISED);
		x = 0;
	    }
	}
    }

    /*
     * 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.
     */

    if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) {
	if (Tk_CharBbox(textPtr->textLayout, textPtr->insertPos,
		&x, &y, NULL, &height)) {
	    Tk_CanvasDrawableCoords(canvas,


		    (double) (textPtr->leftEdge + x
			    - (textInfoPtr->insertWidth / 2)),

		    (double) (textPtr->header.y1 + y),









		    &drawableX, &drawableY);
	    Tk_SetCaretPos(Tk_CanvasTkwin(canvas), drawableX, drawableY,
		    height);
	    if (textInfoPtr->cursorOn) {
		Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable,
			textInfoPtr->insertBorder,
			drawableX, drawableY,
			textInfoPtr->insertWidth, height,
			textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED);
	    } else if (textPtr->cursorOffGC != NULL) {
		/*
		 * 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,
			drawableX, drawableY,
			(unsigned) textInfoPtr->insertWidth,
			(unsigned) 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.
     */

    Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge,
	    (double) textPtr->header.y1, &drawableX, &drawableY);

    if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) {

	Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout,

	    drawableX, drawableY, 0, selFirstChar);

	Tk_DrawTextLayout(display, drawable, textPtr->selTextGC,
	    textPtr->textLayout, drawableX, drawableY, selFirstChar,
	    selLastChar + 1);

	Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout,
	    drawableX, drawableY, selLastChar + 1, -1);


    } else {
	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);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TextInsert --
 *
 *	Insert characters into a text item at a given position.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The text in the given item is modified. The cursor and selection
 *	positions are also modified to reflect the insertion.
 *
 *--------------------------------------------------------------
 */

static void
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 *newStr, *text;

    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = Tcl_GetStringFromObj((Tcl_Obj *) string, &byteCount);

    text = textPtr->text;

    if (index < 0) {
	index = 0;
    }
    if (index > textPtr->numChars) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }

    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 = 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.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst >= index) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast >= index) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor >= index)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos >= index) {
	textPtr->insertPos += charsAdded;
    }
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
 *--------------------------------------------------------------
 */

static void
TextDeleteChars(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Character index of first character to
				 * delete. */
    TkSizeT last)			/* Character index of last character to delete
				 * (inclusive). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if ((int)first < 0) {
	first = 0;
    }
    if (last + 1 >= textPtr->numChars + 1) {
	last = textPtr->numChars - 1;
    }
    if (first + 1 > last + 1) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);

    newStr = (char *)ckalloc(textPtr->numBytes + 1 - byteCount);
    memcpy(newStr, text, byteIndex);
    strcpy(newStr + byteIndex, text + byteIndex + byteCount);

    ckfree(text);
    textPtr->text = newStr;
    textPtr->numChars -= charsRemoved;
    textPtr->numBytes -= byteCount;

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst + 1 > first + 1) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if ((int)textInfoPtr->selectFirst + 1 < (int)first + 1) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast + 1 >= first + 1) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast + 1 < first) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if ((int)textInfoPtr->selectFirst + 1 > (int)textInfoPtr->selectLast + 1) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 > first + 1)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor + 1 < first + 1) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos + 1 > first + 1) {
	textPtr->insertPos -= charsRemoved;
	if ((int)textPtr->insertPos + 1 < (int)first + 1) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}








|

|








|


|


|








|
|













|

|



|

|



|



|

|




|

|







976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
 *--------------------------------------------------------------
 */

static void
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). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if (first < 0) {
	first = 0;
    }
    if (last >= textPtr->numChars) {
	last = textPtr->numChars - 1;
    }
    if (first > last) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);

    newStr = (char *) ckalloc((unsigned) (textPtr->numBytes + 1 - byteCount));
    memcpy(newStr, text, (size_t) byteIndex);
    strcpy(newStr + byteIndex, text + byteIndex + byteCount);

    ckfree(text);
    textPtr->text = newStr;
    textPtr->numChars -= charsRemoved;
    textPtr->numBytes -= byteCount;

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst > first) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if (textInfoPtr->selectFirst < first) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast >= first) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast < first - 1) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if (textInfoPtr->selectFirst > textInfoPtr->selectLast) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor > first)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor < first) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos > first) {
	textPtr->insertPos -= charsRemoved;
	if (textPtr->insertPos < first) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}

1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
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;
    double value, px, py;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    textPtr = (TextItem *) itemPtr;
    px = pointPtr[0] - textPtr->drawOrigin[0];
    py = pointPtr[1] - textPtr->drawOrigin[1];
    value = (double) Tk_DistanceToTextLayout(textPtr->textLayout,
	    (int) (px*textPtr->cosine - py*textPtr->sine),
	    (int) (py*textPtr->cosine + px*textPtr->sine));

    if ((state == TK_STATE_HIDDEN) || (textPtr->color == NULL) ||
	    (textPtr->text == NULL) || (*textPtr->text == 0)) {
	value = 1.0e36;
    }
    return value;
}







|


|


<
<

|
|







1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090


1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
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;
    double value;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    textPtr = (TextItem *) itemPtr;


    value = (double) Tk_DistanceToTextLayout(textPtr->textLayout,
	    (int) pointPtr[0] - textPtr->leftEdge,
	    (int) pointPtr[1] - textPtr->header.y1);

    if ((state == TK_STATE_HIDDEN) || (textPtr->color == NULL) ||
	    (textPtr->text == NULL) || (*textPtr->text == 0)) {
	value = 1.0e36;
    }
    return value;
}
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    TextItem *textPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    textPtr = (TextItem *) itemPtr;
    return TkIntersectAngledTextLayout(textPtr->textLayout,
	    (int) ((rectPtr[0] + 0.5) - textPtr->drawOrigin[0]),
	    (int) ((rectPtr[1] + 0.5) - textPtr->drawOrigin[1]),
	    (int) (rectPtr[2] - rectPtr[0] + 0.5),
	    (int) (rectPtr[3] - rectPtr[1] + 0.5),
	    textPtr->angle);
}

/*
 *--------------------------------------------------------------
 *
 * RotateText --
 *
 *	This function is called to rotate a text item by a given amount about a
 *	point. Note that this does *not* rotate the text of the item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the text anchor is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateText(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &textPtr->x, &textPtr->y);
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleText --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */


static void
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. */







|



|
|
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















>







1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141


































1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    TextItem *textPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    textPtr = (TextItem *) itemPtr;
    return Tk_IntersectTextLayout(textPtr->textLayout,
	    (int) (rectPtr[0] + 0.5) - textPtr->leftEdge,
	    (int) (rectPtr[1] + 0.5) - textPtr->header.y1,
	    (int) (rectPtr[2] - rectPtr[0] + 0.5),
	    (int) (rectPtr[3] - rectPtr[1] + 0.5));


































}

/*
 *--------------------------------------------------------------
 *
 * ScaleText --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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. */
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388

1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446


1447





1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
 *
 *--------------------------------------------------------------
 */

static int
GetTextIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_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. */
    TkSizeT *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT length, idx;
    int c;

    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > textPtr->numChars) {
	    idx = textPtr->numChars;
	}

	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    c = string[0];

    if ((c == 'i')
	    && (strncmp(string, "insert", length) == 0)) {
	*indexPtr = textPtr->insertPos;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.first", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectFirst;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.last", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectLast;
    } else if (c == '@') {
	int x, y;
	double tmp, cs = textPtr->cosine, s = textPtr->sine;
	char *end;
	const char *p;

	p = string+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	x = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	p = end+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	x -= (int) textPtr->drawOrigin[0];
	y -= (int) textPtr->drawOrigin[1];
	*indexPtr = Tk_PointToChar(textPtr->textLayout,


		(int) (x*cs - y*s), (int) (y*cs + x*s));





    } 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.
	 */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "TEXT", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|




|



|

>

|

<
<
|
<
<
|
>
|
<
<
<
<
<
<
|
|


|

<
|
<




|

<
|
<





|
|
<













<
<

>
>
|
>
>
>
>
>







|
|







1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246


1247


1248
1249
1250






1251
1252
1253
1254
1255
1256

1257

1258
1259
1260
1261
1262
1263

1264

1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284


1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
 *
 *--------------------------------------------------------------
 */

static int
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
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int length;
    int c;
    TkCanvas *canvasPtr = (TkCanvas *) canvas;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    char *string = Tcl_GetStringFromObj(obj, &length);



    c = string[0];



    if ((c == 'e') && (strncmp(string, "end", (unsigned) length) == 0)) {
	*indexPtr = textPtr->numChars;






    } else if ((c == 'i')
	    && (strncmp(string, "insert", (unsigned) length) == 0)) {
	*indexPtr = textPtr->insertPos;
    } 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') && (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;
	}
	*indexPtr = textInfoPtr->selectLast;
    } else if (c == '@') {
	int x, y;
	double tmp;
	char *end, *p;


	p = string+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	x = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	p = end+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);


	*indexPtr = Tk_PointToChar(textPtr->textLayout,
		x + canvasPtr->scrollX1 - textPtr->leftEdge,
		y + canvasPtr->scrollY1 - textPtr->header.y1);
    } else if (Tcl_GetIntFromObj(NULL, obj, indexPtr) == TCL_OK) {
	if (*indexPtr < 0){
	    *indexPtr = 0;
	} else if (*indexPtr > textPtr->numChars) {
	    *indexPtr = textPtr->numChars;
	}
    } 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.
	 */

    badIndex:
	Tcl_SetResult(interp, NULL, TCL_STATIC);
	Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
1471
1472
1473
1474
1475
1476
1477

1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
 *
 * Side effects:
 *	The cursor position will change.
 *
 *--------------------------------------------------------------
 */


static void
SetTextCursor(
    TCL_UNUSED(Tk_Canvas),		/* Record describing canvas widget. */
    Tk_Item *itemPtr,		/* Text item in which cursor position is to be
				 * set. */
    TkSizeT index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (index == TCL_INDEX_NONE) {
	textPtr->insertPos = 0;
    } else if (index > textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
    }
}







>


|


|




|







1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
 *
 * Side effects:
 *	The cursor position will change.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
    }
}
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548



1549
1550
1551
1552
1553
1554
1555
1556
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if (((int)textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst + 1 > textInfoPtr->selectLast + 1)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);
    if (selEnd  <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }



    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *--------------------------------------------------------------
 *







|

|

|


|




|

|


|
|






<
<
<




>
>
>
|







1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388



1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
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
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteCount;
    char *text;
    CONST char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if ((textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst > textInfoPtr->selectLast)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);



    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, (size_t) byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *--------------------------------------------------------------
 *
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585

1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629

1630
1631
1632
1633
1634

1635
1636
1637
1638
1639

1640
1641
1642
1643


1644


1645
1646

1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
    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;
    double x, y;
    Tk_FontMetrics fm;
    const char *justify;

    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    color = textPtr->color;
    stipple = textPtr->stipple;
    if (state == TK_STATE_HIDDEN || textPtr->color == NULL ||
	    textPtr->text == NULL || *textPtr->text == 0) {
	return TCL_OK;
    } else if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor != NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple != None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (textPtr->disabledColor != NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple != None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Generate postscript.
     */

    Tcl_ResetResult(interp);
    if (Tk_CanvasPsFont(interp, canvas, textPtr->tkfont) != TCL_OK) {
	goto error;

    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (prepass != 0) {
	goto done;

    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsColor(interp, canvas, color);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);


	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",


		Tcl_GetString(Tcl_GetObjResult(interp)));
    }


    x = 0;  y = 0;  justify = NULL;
    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;
    }
    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;
    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n",
	    textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y));
    Tcl_ResetResult(interp);
    Tk_TextLayoutToPostscript(interp, textPtr->textLayout);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    Tcl_AppendPrintfToObj(psObj,
	    "] %d %g %g %s %s DrawText\n",
	    fm.linespace, x / -2.0, y / 2.0, justify,
	    ((stipple == None) ? "false" : "true"));

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|
>



<
<


|






|
|


|


|
|


|




<
<
<
<
<
<
<
<
<
<
<
<

<
>

<
<

<
>

<
<
|
<
>
|

|

>
>
|
>
>
|
|
>

|


















|
|
|
|
|
<
|
|
<
|
|
<
<
<

<
<
<
<

<
<
<
<
<









1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436


1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461












1462

1463
1464


1465

1466
1467


1468

1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

1507
1508

1509
1510



1511




1512





1513
1514
1515
1516
1517
1518
1519
1520
1521
    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;
    Tk_FontMetrics fm;
    char *justify;
    char buffer[500];
    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;



    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    color = textPtr->color;
    stipple = textPtr->stipple;
    if (state == TK_STATE_HIDDEN || textPtr->color == NULL ||
	    textPtr->text == NULL || *textPtr->text == 0) {
	return TCL_OK;
    } else if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor!=NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple!=None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state==TK_STATE_DISABLED) {
	if (textPtr->disabledColor!=NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple!=None) {
	    stipple = textPtr->disabledStipple;
	}
    }













    if (Tk_CanvasPsFont(interp, canvas, textPtr->tkfont) != TCL_OK) {

	return TCL_ERROR;
    }


    if (prepass != 0) {

	return TCL_OK;
    }


    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {

	return TCL_ERROR;
    }
    if (stipple != None) {
	Tcl_AppendResult(interp, "/StippleText {\n    ", NULL);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendResult(interp, "} bind def\n", NULL);
    }

    sprintf(buffer, "%.15g %.15g [\n", textPtr->x,
	    Tk_CanvasPsY(canvas, textPtr->y));
    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;
    }
    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;
    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);
    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:
 */

Changes to generic/tkCanvUtil.c.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 *
 * 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"


/*
 * 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;

const Tk_SmoothMethod tkBezierSmoothMethod = {
    "true",
    TkMakeBezierCurve,
    (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr,
	    int numPoints, int numSteps))(void *)TkMakeBezierPostscript,
};
static const Tk_SmoothMethod tkRawSmoothMethod = {
    "raw",
    TkMakeRawCurve,
    (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr,
	    int numPoints, int numSteps))(void *)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);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);

#define ABS(a) ((a>=0)?(a):(-(a)))

static inline Tcl_Obj *
GetPostscriptBuffer(
    Tcl_Interp *interp)
{
    Tcl_Obj *psObj = Tcl_GetObjResult(interp);

    if (Tcl_IsShared(psObj)) {
	psObj = Tcl_DuplicateObj(psObj);
	Tcl_SetObjResult(interp, psObj);
    }
    return psObj;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasTkwin --
 *
 *	Given a token for a canvas, this function returns the widget that







>












|





|














|



<


<
<
<
<
<
<
<
<
<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54













55
56
57
58
59
60
61
 *
 * 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 <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))(void *)TkMakeBezierPostscript,
};
static Tk_SmoothMethod tkRawSmoothMethod = {
    "raw",
    TkMakeRawCurve,
    (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr,
	    int numPoints, int numSteps))(void *)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 function returns the widget that
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_CanvasTkwin(
    Tk_Canvas canvas)		/* Token for the canvas. */
{

    return Canvas(canvas)->tkwin;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasDrawableCoords --
 *







>
|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_CanvasTkwin(
    Tk_Canvas canvas)		/* Token for the canvas. */
{
    TkCanvas *canvasPtr = (TkCanvas *) canvas;
    return canvasPtr->tkwin;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasDrawableCoords --
 *
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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)
{

    double tmp;

    tmp = x - Canvas(canvas)->drawableXOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*drawableXPtr = 32767;
    } else if (tmp < -32768) {
	*drawableXPtr = -32768;
    } else {
	*drawableXPtr = (short) tmp;
    }

    tmp = y - Canvas(canvas)->drawableYOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*drawableYPtr = 32767;







>


|













|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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;

    tmp = x - canvasPtr->drawableXOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*drawableXPtr = 32767;
    } else if (tmp < -32768) {
	*drawableXPtr = -32768;
    } else {
	*drawableXPtr = (short) tmp;
    }

    tmp = y - canvasPtr->drawableYOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*drawableYPtr = 32767;
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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)
{

    double tmp;

    tmp = x - Canvas(canvas)->xOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*screenXPtr = 32767;
    } else if (tmp < -32768) {
	*screenXPtr = -32768;
    } else {
	*screenXPtr = (short) tmp;
    }

    tmp = y - Canvas(canvas)->yOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*screenYPtr = 32767;







>


|













|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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;

    tmp = x - canvasPtr->xOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*screenXPtr = 32767;
    } else if (tmp < -32768) {
	*screenXPtr = -32768;
    } else {
	*screenXPtr = (short) tmp;
    }

    tmp = y - canvasPtr->yOrigin;
    if (tmp > 0) {
	tmp += 0.5;
    } else {
	tmp -= 0.5;
    }
    if (tmp > 32767) {
	*screenYPtr = 32767;
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoord(
    Tcl_Interp *dummy,		/* 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. */
{
    (void)dummy;

    if (Tk_GetScreenMM(Canvas(canvas)->interp, Canvas(canvas)->tkwin, string,
	    doublePtr) != TCL_OK) {
	return TCL_ERROR;
    }
    *doublePtr *= Canvas(canvas)->pixelsPerMM;
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasGetCoordFromObj --







|

|



|

|



|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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;
    }
    *doublePtr *= canvasPtr->pixelsPerMM;
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasGetCoordFromObj --
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoordFromObj(
    Tcl_Interp *dummy,		/* 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. */
{
    (void)dummy;

    return Tk_GetDoublePixelsFromObj(Canvas(canvas)->interp, Canvas(canvas)->tkwin, obj, doublePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetStippleOrigin --
 *







|





|

|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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;

    return Tk_GetDoublePixelsFromObj(canvasPtr->interp, canvasPtr->tkwin, obj, doublePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetStippleOrigin --
 *
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
void
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. */
{

    XSetTSOrigin(Canvas(canvas)->display, gc,
	    -Canvas(canvas)->drawableXOrigin,
	    -Canvas(canvas)->drawableYOrigin);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetOffset--
 *







>
|
|
|







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
void
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;

    XSetTSOrigin(canvasPtr->display, gc, -canvasPtr->drawableXOrigin,
	    -canvasPtr->drawableYOrigin);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetOffset--
 *
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
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 = Canvas(canvas);
    int flags = 0;
    int x = - canvasPtr->drawableXOrigin;
    int y = - canvasPtr->drawableYOrigin;

    if (offset != NULL) {
	flags = offset->flags;
	x += offset->xoffset;







|







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
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;
    int x = - canvasPtr->drawableXOrigin;
    int y = - canvasPtr->drawableYOrigin;

    if (offset != NULL) {
	flags = offset->flags;
	x += offset->xoffset;
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
 *----------------------------------------------------------------------
 */

Tk_CanvasTextInfo *
Tk_CanvasGetTextInfo(
    Tk_Canvas canvas)		/* Token for the canvas widget. */
{
    return &Canvas(canvas)->textInfo;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasTagsParseProc --
 *







|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
 *----------------------------------------------------------------------
 */

Tk_CanvasTextInfo *
Tk_CanvasGetTextInfo(
    Tk_Canvas canvas)		/* Token for the canvas widget. */
{
    return &((TkCanvas *) canvas)->textInfo;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasTagsParseProc --
 *
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 *	The tags for a given item get replaced by those indicated in the value
 *	argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasTagsParseProc(
    ClientData dummy,	/* 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. */
    TkSizeT offset)			/* Offset into item (ignored). */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    int argc, i;
    const char **argv;
    Tk_Uid *newPtr;
    (void)dummy;
    (void)tkwin;
    (void)offset;

    /*
     * Break the value up into the individual tag names.
     */

    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Make sure that there's enough space in the item to hold the tag names.
     */

    if ((int)itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *)ckalloc(argc * sizeof(Tk_Uid));
	for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	    newPtr[i] = itemPtr->tagPtr[i];
	}
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newPtr;
	itemPtr->tagSpace = argc;
    }
    itemPtr->numTags = argc;
    for (i = 0; i < argc; i++) {
	itemPtr->tagPtr[i] = Tk_GetUid(argv[i]);
    }
    ckfree(argv);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasTagsPrintProc --







|
|


|

|

|

|

<
<
<













|
|
|



|








|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
 *	The tags for a given item get replaced by those indicated in the value
 *	argument.
 *
 *--------------------------------------------------------------
 */

int
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;
    CONST char **argv;
    Tk_Uid *newPtr;




    /*
     * Break the value up into the individual tag names.
     */

    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Make sure that there's enough space in the item to hold the tag names.
     */

    if (itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *) ckalloc((unsigned) (argc * sizeof(Tk_Uid)));
	for (i = itemPtr->numTags-1; i >= 0; i--) {
	    newPtr[i] = itemPtr->tagPtr[i];
	}
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree((char *) itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newPtr;
	itemPtr->tagSpace = argc;
    }
    itemPtr->numTags = argc;
    for (i = 0; i < argc; i++) {
	itemPtr->tagPtr[i] = Tk_GetUid(argv[i]);
    }
    ckfree((char *) argv);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasTagsPrintProc --
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasTagsPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Ignored. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    (void)dummy;
    (void)tkwin;
    (void)offset;

    if (itemPtr->numTags == 0) {
	*freeProcPtr = NULL;
	return "";
    }
    if (itemPtr->numTags == 1) {
	*freeProcPtr = NULL;
	return (const char *) itemPtr->tagPtr[0];
    }
    *freeProcPtr = TCL_DYNAMIC;
    return Tcl_Merge(itemPtr->numTags, (const char **) itemPtr->tagPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashParseProc --
 *







|
|
|


|




|
<
<
<







|


|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

char *
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 = NULL;
	return "";
    }
    if (itemPtr->numTags == 1) {
	*freeProcPtr = NULL;
	return (char *) itemPtr->tagPtr[0];
    }
    *freeProcPtr = TCL_DYNAMIC;
    return Tcl_Merge(itemPtr->numTags, (CONST char **) itemPtr->tagPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashParseProc --
 *
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasDashParseProc(
    ClientData dummy,	/* 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. */
    TkSizeT offset)			/* Offset into item. */
{
    (void)dummy;
    (void)tkwin;

    return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --
 *







|


|

|

<
<
<
|







499
500
501
502
503
504
505
506
507
508
509
510
511
512



513
514
515
516
517
518
519
520
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
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));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --
 *
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasDashPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT 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, *p;

    int i = dash->number;
    (void)dummy;
    (void)tkwin;

    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = (char *)ckalloc(i + 1);
	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 = NULL;
	return "";
    }
    buffer = (char *)ckalloc(4 * i);
    *freeProcPtr = TCL_DYNAMIC;

    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);
    }
    return buffer;
}

/*
 *--------------------------------------------------------------







|

|


|





|
>

<
<




|








|




|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551


552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

char *
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;
    char *p;
    int i = dash->number;



    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = (char *) ckalloc((unsigned int) (i+1));
	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 = NULL;
	return "";
    }
    buffer = (char *)ckalloc((unsigned int) (4*i));
    *freeProcPtr = TCL_DYNAMIC;

    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);
    }
    return buffer;
}

/*
 *--------------------------------------------------------------
613
614
615
616
617
618
619
620
621
622
623
624


625
626
627
628
629
630
631

632
633
634
635
636
637
638

static SmoothAssocData *
InitSmoothMethods(
    Tcl_Interp *interp)
{
    SmoothAssocData *methods, *ptr;

    methods = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    methods->smooth.name = tkRawSmoothMethod.name;
    methods->smooth.coordProc = tkRawSmoothMethod.coordProc;
    methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc;



    ptr = methods->nextPtr = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = tkBezierSmoothMethod.name;
    ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc;
    ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc;
    ptr->nextPtr = NULL;

    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,methods);

    return methods;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateSmoothMethod --







|




>
>
|





|
>







594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

static SmoothAssocData *
InitSmoothMethods(
    Tcl_Interp *interp)
{
    SmoothAssocData *methods, *ptr;

    methods = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));
    methods->smooth.name = tkRawSmoothMethod.name;
    methods->smooth.coordProc = tkRawSmoothMethod.coordProc;
    methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc;

    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 --
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
 *
 *--------------------------------------------------------------
 */

void
Tk_CreateSmoothMethod(
    Tcl_Interp *interp,
    const Tk_SmoothMethod *smooth)
{
    SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", NULL);


    /*
     * Initialize if we were not previously initialized.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);







|


|
>







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
 *
 *--------------------------------------------------------------
 */

void
Tk_CreateSmoothMethod(
    Tcl_Interp *interp,
    Tk_SmoothMethod *smooth)
{
    SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
    methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
	    NULL);

    /*
     * Initialize if we were not previously initialized.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
	    prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) {
	if (!strcmp(typePtr2->smooth.name, smooth->name)) {
	    if (prevPtr == NULL) {
		methods = typePtr2->nextPtr;
	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree(typePtr2);
	    break;
	}
    }
    ptr = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = smooth->name;
    ptr->smooth.coordProc = smooth->coordProc;
    ptr->smooth.postscriptProc = smooth->postscriptProc;
    ptr->nextPtr = methods;
    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, ptr);

}

/*
 *----------------------------------------------------------------------
 *
 * SmoothMethodCleanupProc --
 *







|



|




|
>







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
	    prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) {
	if (!strcmp(typePtr2->smooth.name, smooth->name)) {
	    if (prevPtr == NULL) {
		methods = typePtr2->nextPtr;
	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree((char *) typePtr2);
	    break;
	}
    }
    ptr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = smooth->name;
    ptr->smooth.coordProc = smooth->coordProc;
    ptr->smooth.postscriptProc = smooth->postscriptProc;
    ptr->nextPtr = methods;
    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,
	    (ClientData) ptr);
}

/*
 *----------------------------------------------------------------------
 *
 * SmoothMethodCleanupProc --
 *
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    ClientData clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    Tcl_Interp *dummy)		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = (SmoothAssocData *)clientData;
    (void)dummy;

    while (methods != NULL) {
	ptr = methods;
	methods = methods->nextPtr;
	ckfree(ptr);
    }
}
/*
 *--------------------------------------------------------------
 *
 * TkSmoothParseProc --
 *







|

|
<


|
<
|







693
694
695
696
697
698
699
700
701
702

703
704
705

706
707
708
709
710
711
712
713
 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    ClientData clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData;


    while (methods != NULL) {
	methods = (ptr = methods)->nextPtr;

	ckfree((char *) ptr);
    }
}
/*
 *--------------------------------------------------------------
 *
 * TkSmoothParseProc --
 *
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkSmoothParseProc(
    ClientData dummy,	/* Ignored. */
    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. */
    TkSizeT offset)			/* Offset into item. */
{
    const Tk_SmoothMethod **smoothPtr =
	    (const Tk_SmoothMethod **) (widgRec + offset);
    const Tk_SmoothMethod *smooth = NULL;
    int b;
    size_t length;
    SmoothAssocData *methods;
    (void)dummy;
    (void)tkwin;

    if (value == NULL || *value == 0) {
	*smoothPtr = NULL;
	return TCL_OK;
    }
    length = strlen(value);
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", 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 != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"ambiguous smooth method \"%s\"", value));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "SMOOTH", value,
			NULL);
		return TCL_ERROR;
	    }
	    smooth = &methods->smooth;
	}
	methods = methods->nextPtr;
    }
    if (smooth) {







|


|

|

|
|
|



<
<






|
>










|













<
|
<
|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741


742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774

775
776
777
778
779
780
781
782
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
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 *smooth = NULL;
    int b;
    size_t length;
    SmoothAssocData *methods;



    if (value == NULL || *value == 0) {
	*smoothPtr = NULL;
	return TCL_OK;
    }
    length = strlen(value);
    methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
	    NULL);

    /*
     * Not initialized yet; fix that now.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
    }

    /*
     * Backward compatibility 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 != NULL) {

		Tcl_AppendResult(interp, "ambiguous smooth method \"", value,

			"\"", NULL);
		return TCL_ERROR;
	    }
	    smooth = &methods->smooth;
	}
	methods = methods->nextPtr;
    }
    if (smooth) {
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkSmoothPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    const Tk_SmoothMethod *smoothPtr =
	    * (Tk_SmoothMethod **) (widgRec + offset);
    (void)dummy;
	(void)tkwin;
    (void)freeProcPtr;

    return smoothPtr ? smoothPtr->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash
 *
 *	This function is used to parse a string, assuming it is dash







|

|


|




|
|
<
<
<

|







811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829



830
831
832
833
834
835
836
837
838
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

char *
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);




    return (*smoothPtr) ? (*smoothPtr)->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash
 *
 *	This function is used to parse a string, assuming it is dash
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896


897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927

928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
 *
 *--------------------------------------------------------------
 */

int
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 == NULL) || (*value == '\0')) {
	dash->number = 0;
	return TCL_OK;
    }

    /*
     * 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) {


	    goto badDashList;
	}
	i = strlen(value);
	if (i > (int) sizeof(char *)) {
	    dash->pattern.pt = pt = (char *)ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt, value, (unsigned) i);
	dash->number = -i;
	return TCL_OK;
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	Tcl_ResetResult(interp);
	goto badDashList;
    }

    if ((unsigned) ABS(dash->number) > sizeof(char *)) {
	ckfree(dash->pattern.pt);
    }
    if (argc > (int) sizeof(char *)) {
	dash->pattern.pt = pt = (char *)ckalloc(argc);
    } else {
	pt = dash->pattern.array;
    }
    dash->number = argc;

    largv = argv;
    while (argc > 0) {
	if (Tcl_GetInt(interp, *largv, &i) != TCL_OK || i < 1 || i>255) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "expected integer in the range 1..255 but got \"%s\"",
		    *largv));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "DASH", NULL);
	    goto syntaxError;
	}
	*pt++ = i;
	argc--;
	largv++;
    }

    if (argv != NULL) {
	ckfree(argv);
    }
    return TCL_OK;

    /*
     * Something went wrong. Generate error message, clean up and return.
     */

  badDashList:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad dash list \"%s\": must be a list of integers or a format like \"-..\"",
	    value));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "DASH", NULL);
  syntaxError:
    if (argv != NULL) {
	ckfree(argv);
    }
    if ((unsigned) ABS(dash->number) > sizeof(char *)) {
	ckfree(dash->pattern.pt);
    }
    dash->number = 0;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------







|




|


|











|
>
>


<
|
|



|









|
|

|
|






|

>
|
|
|
<








|








|
|
<
|


|

|
|







847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929

930
931
932
933
934
935
936
937
938
939
940
941
942
943
 *
 *--------------------------------------------------------------
 */

int
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==NULL) || (*value==0) ) {
	dash->number = 0;
	return TCL_OK;
    }

    /*
     * 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 > (int)sizeof(char *)) {
	    dash->pattern.pt = pt = (char *) ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt,value, (unsigned int) i);
	dash->number = -i;
	return TCL_OK;
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	Tcl_ResetResult(interp);
	goto badDashList;
    }

    if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
	ckfree((char *) dash->pattern.pt);
    }
    if (argc > (int)sizeof(char *)) {
	dash->pattern.pt = pt = (char *) ckalloc((unsigned int) argc);
    } else {
	pt = dash->pattern.array;
    }
    dash->number = argc;

    largv = argv;
    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, "\"", NULL);

	    goto syntaxError;
	}
	*pt++ = i;
	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;
}

/*
 *--------------------------------------------------------------
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
Tk_DeleteOutline(
    Display *display,		/* Display containing window. */
    Tk_Outline *outline)
{
    if (outline->gc != NULL) {
	Tk_FreeGC(display, outline->gc);
    }
    if ((unsigned) ABS(outline->dash.number) > sizeof(char *)) {
	ckfree(outline->dash.pattern.pt);
    }
    if ((unsigned) ABS(outline->activeDash.number) > sizeof(char *)) {
	ckfree(outline->activeDash.pattern.pt);
    }
    if ((unsigned) ABS(outline->disabledDash.number) > sizeof(char *)) {
	ckfree(outline->disabledDash.pattern.pt);
    }
    if (outline->color != NULL) {
	Tk_FreeColor(outline->color);
    }
    if (outline->activeColor != NULL) {
	Tk_FreeColor(outline->activeColor);
    }







|
|

|
|

|
|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
Tk_DeleteOutline(
    Display *display,		/* Display containing window. */
    Tk_Outline *outline)
{
    if (outline->gc != NULL) {
	Tk_FreeGC(display, outline->gc);
    }
    if ((unsigned int)ABS(outline->dash.number) > sizeof(char *)) {
	ckfree((char *) outline->dash.pattern.pt);
    }
    if ((unsigned int)ABS(outline->activeDash.number) > sizeof(char *)) {
	ckfree((char *) outline->activeDash.pattern.pt);
    }
    if ((unsigned int)ABS(outline->disabledDash.number) > sizeof(char *)) {
	ckfree((char *) outline->disabledDash.pattern.pt);
    }
    if (outline->color != NULL) {
	Tk_FreeColor(outline->color);
    }
    if (outline->activeColor != NULL) {
	Tk_FreeColor(outline->activeColor);
    }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (Canvas(canvas)->currentItemPtr == item) {
	if (outline->activeWidth>width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor!=NULL) {







|

|







1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == item) {
	if (outline->activeWidth>width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor!=NULL) {
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220

int
Tk_ChangeOutlineGC(
    Tk_Canvas canvas,
    Tk_Item *item,
    Tk_Outline *outline)
{
    const char *p;
    double width;
    Tk_Dash *dash;
    XColor *color;
    Pixmap stipple;
    Tk_State state = item->state;

    width = outline->width;
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (Canvas(canvas)->currentItemPtr == item) {
	if (outline->activeWidth > width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor != NULL) {







|














|

|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

int
Tk_ChangeOutlineGC(
    Tk_Canvas canvas,
    Tk_Item *item,
    Tk_Outline *outline)
{
    CONST char *p;
    double width;
    Tk_Dash *dash;
    XColor *color;
    Pixmap stipple;
    Tk_State state = item->state;

    width = outline->width;
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == item) {
	if (outline->activeWidth > width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor != NULL) {
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304

    if ((dash->number<-1) ||
	    ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
	char *q;
	int i = -dash->number;

	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	q = (char *)ckalloc(2 * i);
	i = DashConvert(q, p, i, width);
	XSetDashes(Canvas(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 = (dash->number > (int) sizeof(char *))
		? dash->pattern.pt : dash->pattern.array;
	XSetDashes(Canvas(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))) {
	    Tk_SizeOfBitmap(Canvas(canvas)->display, stipple, &w, &h);
	    if (flags & TK_OFFSET_CENTER) {
		w /= 2;
	    } else {
		w = 0;
	    }
	    if (flags & TK_OFFSET_MIDDLE) {
		h /= 2;
	    } else {
		h = 0;
	    }
	}
	tsoffset->xoffset -= w;
	tsoffset->yoffset -= h;
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * Tk_ResetOutlineGC
 *
 *	Restores the GC to the situation before Tk_ChangeOutlineGC() 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, and 0 otherwise.
 *
 * Side effects:
 *	GC is updated.
 *







|

|
>



|

|
|


|


<


|




















>






|
|
|







1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283

    if ((dash->number<-1) ||
	    ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
	char *q;
	int i = -dash->number;

	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);
	ckfree(q);
    } 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))) {
	    Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h);
	    if (flags & TK_OFFSET_CENTER) {
		w /= 2;
	    } else {
		w = 0;
	    }
	    if (flags & TK_OFFSET_MIDDLE) {
		h /= 2;
	    } else {
		h = 0;
	    }
	}
	tsoffset->xoffset -= w;
	tsoffset->yoffset -= h;
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	1 if there is a stipple pattern, and 0 otherwise.
 *
 * Side effects:
 *	GC is updated.
 *
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (Canvas(canvas)->currentItemPtr == item) {
	if (outline->activeWidth>width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor!=NULL) {







|

|







1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
    if (width < 1.0) {
	width = 1.0;
    }
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == item) {
	if (outline->activeWidth>width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number != 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor!=NULL) {
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
	if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
	    dashList = dash->pattern.pt[0];
	} else if (dash->number != 0) {
	    dashList = dash->pattern.array[0];
	} else {
	    dashList = (char) (4 * width + 0.5);
	}
	XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset,
		&dashList , 1);
    }
    if (stipple != None) {
	XSetTSOrigin(Canvas(canvas)->display, outline->gc, 0, 0);
	return 1;
    }
    return 0;
}

/*
 *--------------------------------------------------------------







|
|


|







1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
	if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
	    dashList = dash->pattern.pt[0];
	} else if (dash->number != 0) {
	    dashList = dash->pattern.array[0];
	} else {
	    dashList = (char) (4 * width + 0.5);
	}
	XSetDashes(((TkCanvas *)canvas)->display, outline->gc,
		outline->offset, &dashList , 1);
    }
    if (stipple != None) {
	XSetTSOrigin(((TkCanvas *)canvas)->display, outline->gc, 0, 0);
	return 1;
    }
    return 0;
}

/*
 *--------------------------------------------------------------
1399
1400
1401
1402
1403
1404
1405

1406
1407
1408


1409
1410
1411
1412
1413
1414
1415
1416




1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447


1448
1449





1450
1451
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464
1465
1466
1467
1468


1469
1470
1471
1472
1473
1474
1475



1476
1477


1478

1479
1480
1481
1482
1483
1484
1485
1486
1487

1488
1489
1490
1491
1492

1493
1494
1495
1496


1497
1498
1499
1500
1501
1502
1503
1504
1505

int
Tk_CanvasPsOutline(
    Tk_Canvas canvas,
    Tk_Item *item,
    Tk_Outline *outline)
{

    char pattern[11];
    int i;
    char *ptr, *lptr = pattern;


    Tcl_Interp *interp = Canvas(canvas)->interp;
    double width = outline->width;
    Tk_Dash *dash = &outline->dash;
    XColor *color = outline->color;
    Pixmap stipple = outline->stipple;
    Tk_State state = item->state;
    Tcl_Obj *psObj = GetPostscriptBuffer(interp);





    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (Canvas(canvas)->currentItemPtr == item) {
	if (outline->activeWidth > width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number > 0) {
	    dash = &outline->activeDash;
	}
	if (outline->activeColor != NULL) {
	    color = outline->activeColor;
	}
	if (outline->activeStipple != None) {
	    stipple = outline->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (outline->disabledWidth > 0) {
	    width = outline->disabledWidth;
	}
	if (outline->disabledDash.number > 0) {
	    dash = &outline->disabledDash;
	}
	if (outline->disabledColor != NULL) {
	    color = outline->disabledColor;
	}
	if (outline->disabledStipple != None) {
	    stipple = outline->disabledStipple;
	}
    }



    Tcl_AppendPrintfToObj(psObj, "%.15g setlinewidth\n", width);






    ptr = ((unsigned) ABS(dash->number) > sizeof(char *)) ?
	    dash->pattern.pt : dash->pattern.array;
    Tcl_AppendToObj(psObj, "[", -1);
    if (dash->number > 0) {
	Tcl_Obj *converted;
	char *p = ptr;

	converted = Tcl_ObjPrintf("%d", *p++ & 0xff);
	for (i = dash->number-1 ; i>0 ; i--) {

	    Tcl_AppendPrintfToObj(converted, " %d", *p++ & 0xff);
	}
	Tcl_AppendObjToObj(psObj, converted);
	if (dash->number & 1) {
	    Tcl_AppendToObj(psObj, " ", -1);
	    Tcl_AppendObjToObj(psObj, converted);
	}
	Tcl_DecrRefCount(converted);
	Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);


    } else if (dash->number < 0) {
	if (dash->number < -5) {
	    lptr = (char *)ckalloc(1 - 2*dash->number);
	}
	i = DashConvert(lptr, ptr, -dash->number, width);
	if (i > 0) {
	    char *p = lptr;




	    Tcl_AppendPrintfToObj(psObj, "%d", *p++ & 0xff);


	    for (; --i>0 ;) {

		Tcl_AppendPrintfToObj(psObj, " %d", *p++ & 0xff);
	    }
	    Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
	} else {
	    Tcl_AppendToObj(psObj, "] 0 setdash\n", -1);
	}
	if (lptr != pattern) {
	    ckfree(lptr);
	}

    } else {
	Tcl_AppendToObj(psObj, "] 0 setdash\n", -1);
    }

    Tk_CanvasPsColor(interp, canvas, color);


    if (stipple != None) {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", -1);
	Tk_CanvasPsStipple(interp, canvas, stipple);


    } else {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", -1);
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------







>


|
>
>
|
|
|
|
|

<

>
>
>
>

|


|




|












|








>
>

<
>
>
>
>
>
|
|

<

<
|

|
|
>
|

|
|
|
<

<
|
>
>

|
|
|
<
<
<
>
>
>
|
|
>
>
|
>
|
|
<
|
|
|
|
|
|
>
|
<

<
|
>
|

|
|
>
>

|







1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442
1443

1444

1445
1446
1447
1448
1449
1450
1451
1452
1453
1454

1455

1456
1457
1458
1459
1460
1461
1462



1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473

1474
1475
1476
1477
1478
1479
1480
1481

1482

1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499

int
Tk_CanvasPsOutline(
    Tk_Canvas canvas,
    Tk_Item *item,
    Tk_Outline *outline)
{
    char string[41];
    char pattern[11];
    int i;
    char *ptr;
    char *str = string;
    char *lptr = pattern;
    Tcl_Interp *interp = ((TkCanvas *)canvas)->interp;
    double width;
    Tk_Dash *dash;
    XColor *color;
    Pixmap stipple;
    Tk_State state = item->state;


    width = outline->width;
    dash = &(outline->dash);
    color = outline->color;
    stipple = outline->stipple;
    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    if (((TkCanvas *)canvas)->currentItemPtr == item) {
	if (outline->activeWidth > width) {
	    width = outline->activeWidth;
	}
	if (outline->activeDash.number > 0) {
	    dash = &(outline->activeDash);
	}
	if (outline->activeColor != NULL) {
	    color = outline->activeColor;
	}
	if (outline->activeStipple != None) {
	    stipple = outline->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (outline->disabledWidth > 0) {
	    width = outline->disabledWidth;
	}
	if (outline->disabledDash.number > 0) {
	    dash = &(outline->disabledDash);
	}
	if (outline->disabledColor != NULL) {
	    color = outline->disabledColor;
	}
	if (outline->disabledStipple != None) {
	    stipple = outline->disabledStipple;
	}
    }
    sprintf(string, "%.15g setlinewidth\n", width);
    Tcl_AppendResult(interp, string, NULL);


    if (dash->number > 10) {
	str = (char *)ckalloc((unsigned int) (1 + 4*dash->number));
    } else if (dash->number < -5) {
	str = (char *)ckalloc((unsigned int) (1 - 8*dash->number));
	lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number));
    }
    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, NULL);
	if (dash->number&1) {
	    Tcl_AppendResult(interp, " ", str+1, NULL);

	}

	sprintf(str, "] %d setdash\n", outline->offset);
	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, NULL);
	    sprintf(str, "] %d setdash\n", outline->offset);
	    Tcl_AppendResult(interp, str, NULL);
	    lptr = lptr0;
	} else {
	    Tcl_AppendResult(interp, "[] 0 setdash\n", NULL);
	}

    } else {
	Tcl_AppendResult(interp, "[] 0 setdash\n", NULL);
    }
    if (str != string) {
	ckfree(str);
    }
    if (lptr != pattern) {
	ckfree(lptr);

    }

    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	return TCL_ERROR;
    }
    if (stipple != None) {
	Tcl_AppendResult(interp, "StrokeClip ", NULL);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	Tcl_AppendResult(interp, "stroke\n", NULL);
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
 *--------------------------------------------------------------
 */

static int
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;

    if (n < 0) {
	n = strlen(p);
    }
    intWidth = (int) (width + 0.5);
    if (intWidth < 1) {
	intWidth = 1;
    }
    while (n-- && *p) {







|







|







1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
 *--------------------------------------------------------------
 */

static int
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;

    if (n<0) {
	n = strlen(p);
    }
    intWidth = (int) (width + 0.5);
    if (intWidth < 1) {
	intWidth = 1;
    }
    while (n-- && *p) {
1667
1668
1669
1670
1671
1672
1673




1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
    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 */




    double limit[4];		/* Boundries at which clipping occurs */
    double staticSpace[480];	/* Temp space from the stack */
    (void)closedPath;

    /*
     * 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.
     *







>
>
>
>


<







1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
    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 */
#ifndef NDEBUG
    int maxOutput;		/* Maximum number of outputs that we will
				 * allow */
#endif
    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.
     *
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
     * 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(double))) {
	tempArr = staticSpace;
    } else {
	tempArr = (double *)ckalloc(numVertex * 12 * sizeof(double));
    }
    for (i=0; i<numVertex*2; i++){
	tempArr[i] = coordArr[i];
    }
    a = tempArr;
    b = &tempArr[numVertex*6];








|

















|


|







1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
     * 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]));
    }
    for (i=0; i<numVertex*2; i++){
	tempArr[i] = coordArr[i];
    }
    a = tempArr;
    b = &tempArr[numVertex*6];

1762
1763
1764
1765
1766
1767
1768



1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
    limit[2] = -lft;
    limit[3] = btm;

    /*
     * This is the loop that makes the four passes through the data.
     */




    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 <= numVertex*3);
		    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 <= numVertex*3);
		    }
		    inside = 1;
		}
		b[numOutput*2] = -y;
		b[numOutput*2 + 1] = x;
		numOutput++;
		assert(numOutput <= numVertex*3);
	    }
	}

	/*
	 * 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(tempArr);
    }
    return numOutput;
}

/*
 *--------------------------------------------------------------
 *
 * TkRotatePoint --
 *
 *	Rotate a point about another point. The angle should be converted into
 *	its sine and cosine before calling this function.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The point in (*xPtr,*yPtr) is updated to be rotated about
 *	(originX,originY) by the amount given by the sine and cosine of the
 *	angle to rotate.
 *
 *--------------------------------------------------------------
 */

void
TkRotatePoint(
    double originX, double originY,	/* The point about which to rotate. */
    double sine, double cosine,		/* How much to rotate? */
    double *xPtr, double *yPtr)		/* The point to be rotated. (INOUT) */
{
    double x = *xPtr - originX;
    double y = *yPtr - originY;

    /*
     * Beware! The canvas coordinate space is flipped vertically, so rotations
     * go the "wrong" way with respect to mathematics.
     */

    *xPtr = originX + x * cosine + y * sine;
    *yPtr = originY - x * sine + y * cosine;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
|

|








|

|

















|
|


|

|


















<

<
|









|
|



|

|




|

|


















|



|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824

1825

1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876





































1877
1878
1879
1880
1881
1882
1883
1884
    limit[2] = -lft;
    limit[3] = btm;

    /*
     * This is the loop that makes the four passes through the data.
     */

#ifndef NDEBUG
    maxOutput = numVertex*3;
#endif
    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:
 */

Changes to generic/tkCanvWind.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
/*
 * tkCanvWind.c --
 *
 *	This file implements window items for canvas 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"

/*
 * The structure below defines the record for each window item.
 */













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tkCanvWind.c --
 *
 *	This file implements window items for canvas 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"

/*
 * The structure below defines the record for each window item.
 */

33
34
35
36
37
38
39
40

41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    Tk_Canvas canvas;		/* Canvas containing this item. */
} WindowItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", offsetof(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(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", offsetof(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_WINDOW, "-window", NULL, NULL,
	NULL, offsetof(WindowItem, tkwin), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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		RotateWinItem(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    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		WinItemLostContentProc(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);







|
>
|

|
>
|


|

|

|

|



|

|
|










|


|





<
<







|
|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    Tk_Canvas canvas;		/* Canvas containing this item. */
} WindowItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
    {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", NULL, NULL,
	NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Prototypes for functions defined in this file:
 */

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(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    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(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    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(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);
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateWinItem,		/* rotateProc */
    0, NULL, NULL
};

/*
 * The structure below defines the official type record for the canvas (as
 * geometry manager):
 */

static const Tk_GeomMgr canvasGeomType = {
    "canvas",				/* name */
    WinItemRequestProc,			/* requestProc */
    WinItemLostContentProc,		/* lostContentProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *







<
<










|







129
130
131
132
133
134
135


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */


};

/*
 * The structure below defines the official type record for the canvas (as
 * geometry manager):
 */

static const Tk_GeomMgr canvasGeomType = {
    "canvas",				/* name */
    WinItemRequestProc,			/* requestProc */
    WinItemLostSlaveProc,		/* lostSlaveProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
     */

    winItemPtr->tkwin = NULL;
    winItemPtr->width = 0;
    winItemPtr->height = 0;
    winItemPtr->anchor = TK_ANCHOR_CENTER;
    winItemPtr->canvas = canvas;

    /*
     * 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 {
	const char *arg = Tcl_GetString(objv[1]);

	i = 2;
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if (WinItemCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;







|





|




















|
<







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
static int
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) {
	Tcl_Panic("canvas did not pass any coords\n");
    }

    /*
     * Initialize item's record.
     */

    winItemPtr->tkwin = NULL;
    winItemPtr->width = 0;
    winItemPtr->height = 0;
    winItemPtr->anchor = TK_ANCHOR_CENTER;
    winItemPtr->canvas = canvas;

    /*
     * 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;
	}
    }
    if (WinItemCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255

256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
static int
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;

    if (objc == 0) {
	Tcl_Obj *objs[2];

	objs[0] = Tcl_NewDoubleObj(winItemPtr->x);

	objs[1] = Tcl_NewDoubleObj(winItemPtr->y);

	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &winItemPtr->x)
		!= TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		&winItemPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeWindowBbox(canvas, winItemPtr);
    } else {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|




|
<
|
>
|
>
|






>
|
|
|
<










>
|
|
|







238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
static int
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;

    if (objc == 0) {
	Tcl_Obj *obj = Tcl_NewObj();

	Tcl_Obj *subobj = Tcl_NewDoubleObj(winItemPtr->x);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	subobj = Tcl_NewDoubleObj(winItemPtr->y);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf, "wrong # coordinates: expected 2, got %d", objc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);

		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &winItemPtr->x)
		!= TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		&winItemPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeWindowBbox(canvas, winItemPtr);
    } 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;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351





352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

static int
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;
    Tk_Window canvasTkwin;

    oldWindow = winItemPtr->tkwin;
    canvasTkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, objc,
	    (const char **) objv, (char *) winItemPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing.
     */

    if (oldWindow != winItemPtr->tkwin) {
	if (oldWindow != NULL) {
	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
		    WinItemStructureProc, winItemPtr);
	    Tk_ManageGeometry(oldWindow, NULL, NULL);
	    Tk_UnmaintainGeometry(oldWindow, canvasTkwin);
	    Tk_UnmapWindow(oldWindow);
	}
	if (winItemPtr->tkwin != NULL) {
	    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.
	     */

	    parent = Tk_Parent(winItemPtr->tkwin);
	    for (ancestor = canvasTkwin ;; ancestor = Tk_Parent(ancestor)) {

		if (ancestor == parent) {
		    break;
		}
		if (((Tk_FakeWin *) ancestor)->flags & TK_TOP_HIERARCHY) {
		    goto badWindow;





		}
	    }
	    if (((Tk_FakeWin *) winItemPtr->tkwin)->flags & TK_TOP_HIERARCHY){
		goto badWindow;
	    }
	    if (winItemPtr->tkwin == canvasTkwin) {
		goto badWindow;
	    }
	    Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		    WinItemStructureProc, winItemPtr);
	    Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType, winItemPtr);

	}
    }
    if ((winItemPtr->tkwin != NULL)
	    && (itemPtr->state == TK_STATE_HIDDEN)) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
    }

    ComputeWindowBbox(canvas, winItemPtr);
    return TCL_OK;

  badWindow:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't use %s in a window item of this canvas",
	    Tk_PathName(winItemPtr->tkwin)));
    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
    winItemPtr->tkwin = NULL;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteWinItem --
 *







|









|










|
|














|
>



|
|
>
>
>
>
>


|






|
|
>












<

<
<
<
<
<
<
|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382






383
384
385
386
387
388
389
390

static int
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;
    Tk_Window canvasTkwin;

    oldWindow = winItemPtr->tkwin;
    canvasTkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) winItemPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing.
     */

    if (oldWindow != winItemPtr->tkwin) {
	if (oldWindow != NULL) {
	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
		    WinItemStructureProc, (ClientData) winItemPtr);
	    Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL);
	    Tk_UnmaintainGeometry(oldWindow, canvasTkwin);
	    Tk_UnmapWindow(oldWindow);
	}
	if (winItemPtr->tkwin != NULL) {
	    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.
	     */

	    parent = Tk_Parent(winItemPtr->tkwin);
	    for (ancestor = canvasTkwin; ;
		    ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
		badWindow:
		    Tcl_AppendResult(interp, "can't use ",
			    Tk_PathName(winItemPtr->tkwin),
			    " in a window item of this canvas", NULL);
		    winItemPtr->tkwin = NULL;
		    return TCL_ERROR;
		}
	    }
	    if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_HIERARCHY) {
		goto badWindow;
	    }
	    if (winItemPtr->tkwin == canvasTkwin) {
		goto badWindow;
	    }
	    Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		    WinItemStructureProc, (ClientData) winItemPtr);
	    Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType,
		    (ClientData) winItemPtr);
	}
    }
    if ((winItemPtr->tkwin != NULL)
	    && (itemPtr->state == TK_STATE_HIDDEN)) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
    }

    ComputeWindowBbox(canvas, winItemPtr);








    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteWinItem --
 *
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
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);
    (void)display;

    if (winItemPtr->tkwin != NULL) {
	Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		WinItemStructureProc, winItemPtr);
	Tk_ManageGeometry(winItemPtr->tkwin, NULL, NULL);

	if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tk_UnmapWindow(winItemPtr->tkwin);
    }
}








<



|
|
>







404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
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);


    if (winItemPtr->tkwin != NULL) {
	Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		WinItemStructureProc, (ClientData) winItemPtr);
	Tk_ManageGeometry(winItemPtr->tkwin, NULL,
		(ClientData) NULL);
	if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tk_UnmapWindow(winItemPtr->tkwin);
    }
}

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    int width, height, x, y;
    Tk_State state = winItemPtr->header.state;

    x = (int) (winItemPtr->x + ((winItemPtr->x >= 0) ? 0.5 : - 0.5));
    y = (int) (winItemPtr->y + ((winItemPtr->y >= 0) ? 0.5 : - 0.5));

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    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.







|







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    int width, height, x, y;
    Tk_State state = winItemPtr->header.state;

    x = (int) (winItemPtr->x + ((winItemPtr->x >= 0) ? 0.5 : - 0.5));
    y = (int) (winItemPtr->y + ((winItemPtr->y >= 0) ? 0.5 : - 0.5));

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    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.
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
				 * redisplayed (not used). */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;
    (void)display;
    (void)regionX;
    (void)regionY;
    (void)regionWidth;
    (void)regionHeight;

    if (winItemPtr->tkwin == NULL) {
	return;
    }
    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    /*
     * A drawable of None is used by the canvas UnmapNotify handler
     * to indicate that we should no longer display ourselves.
     */
    if (state == TK_STATE_HIDDEN || drawable == None) {







<
<
<
<
<





|







567
568
569
570
571
572
573





574
575
576
577
578
579
580
581
582
583
584
585
586
				 * redisplayed (not used). */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;






    if (winItemPtr->tkwin == NULL) {
	return;
    }
    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    /*
     * A drawable of None is used by the canvas UnmapNotify handler
     * to indicate that we should no longer display ourselves.
     */
    if (state == TK_STATE_HIDDEN || drawable == None) {
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
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;
    (void)canvas;

    x1 = winItemPtr->header.x1;
    y1 = winItemPtr->header.y1;
    x2 = winItemPtr->header.x2;
    y2 = winItemPtr->header.y2;

    /*







<







655
656
657
658
659
660
661

662
663
664
665
666
667
668
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;


    x1 = winItemPtr->header.x1;
    y1 = winItemPtr->header.y1;
    x2 = winItemPtr->header.x2;
    y2 = winItemPtr->header.y2;

    /*
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    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;
    (void)canvas;

    if ((rectPtr[2] <= winItemPtr->header.x1)
	    || (rectPtr[0] >= winItemPtr->header.x2)
	    || (rectPtr[3] <= winItemPtr->header.y1)
	    || (rectPtr[1] >= winItemPtr->header.y2)) {
	return -1;
    }







<







712
713
714
715
716
717
718

719
720
721
722
723
724
725
    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;


    if ((rectPtr[2] <= winItemPtr->header.x1)
	    || (rectPtr[0] >= winItemPtr->header.x2)
	    || (rectPtr[3] <= winItemPtr->header.y1)
	    || (rectPtr[1] >= winItemPtr->header.y2)) {
	return -1;
    }
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    ClientData dummy,
    XErrorEvent *e)
{
    (void)dummy;
    (void)e;

    return 0;
}
#endif /* X_GetImage */


/*
 *--------------------------------------------------------------
 *
 * WinItemToPostscript --
 *
 *	This function is called to generate Postscript for window items.







|


<
<
<


|
>







748
749
750
751
752
753
754
755
756
757



758
759
760
761
762
763
764
765
766
767
768
 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    ClientData clientData,
    XErrorEvent *e)
{



    return 0;
}
#endif


/*
 *--------------------------------------------------------------
 *
 * WinItemToPostscript --
 *
 *	This function is called to generate Postscript for window items.
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
    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;

    double x, y;
    int width, height;
    Tk_Window tkwin = winItemPtr->tkwin;

    if (prepass || winItemPtr->tkwin == NULL) {
        return TCL_OK;
    }







|
>







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
    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;

    double x, y;
    int width, height;
    Tk_Window tkwin = winItemPtr->tkwin;

    if (prepass || winItemPtr->tkwin == NULL) {
        return TCL_OK;
    }
836
837
838
839
840
841
842

843
844

845
846
847
848
849
850
851
852
853
854
855
856
857
858

859
860
861
862
863
864


865
866
867
868


869
870
871
872
873
874
875
876
877


878

879

880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
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. */
{

    XImage *ximage;
    int result;

#ifdef X_GetImage
    Tk_ErrorHandler handle;
#endif
    Tcl_Obj *cmdObj, *psObj;
    Tcl_InterpState interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Locate the subwindow within the wider window.
     */

    psObj = Tcl_ObjPrintf(
	    "\n%%%% %s item (%s, %d x %d)\n"	/* Comment */
	    "%.15g %.15g translate\n",		/* Position */
	    Tk_Class(tkwin), Tk_PathName(tkwin), width, height, x, y);


    /*
     * 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_ResetResult(interp);
    cmdObj = Tcl_ObjPrintf("%s postscript -prolog 0", Tk_PathName(tkwin));
    Tcl_IncrRefCount(cmdObj);
    result = Tcl_EvalObjEx(interp, cmdObj, 0);


    Tcl_DecrRefCount(cmdObj);

    if (result == TCL_OK) {
	Tcl_AppendPrintfToObj(psObj,
		"50 dict begin\nsave\ngsave\n"
		"0 %d moveto %d 0 rlineto 0 -%d rlineto -%d 0 rlineto closepath\n"
		"1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n",
		height, width, height, width);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	Tcl_AppendToObj(psObj, "\nrestore\nend\n\n\n", -1);

	goto done;

    }


    /*
     * 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, tkwin);
#endif

    /*
     * 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,
	    (unsigned) width, (unsigned) height, AllPlanes, ZPixmap);

#ifdef X_GetImage
    Tk_DeleteErrorHandler(handle);
#endif

    if (ximage == NULL) {
	result = TCL_OK;
    } else {
	Tcl_ResetResult(interp);
	result = TkPostscriptImage(interp, tkwin, Canvas(canvas)->psInfo,
		ximage, 0, 0, width, height);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	XDestroyImage(ximage);
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    if (result == TCL_OK) {
	(void) Tcl_RestoreInterpState(interp, interpState);
	Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    } else {
	Tcl_DiscardInterpState(interpState);
    }
    Tcl_DecrRefCount(psObj);

    return result;
}

/*
 *--------------------------------------------------------------
 *
 * RotateWinItem --
 *
 *	This function is called to rotate a window item by a given amount
 *	about a point. Note that this does *not* rotate the window of the
 *	item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the window anchor is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateWinItem(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &winItemPtr->x, &winItemPtr->y);
    ComputeWindowBbox(canvas, winItemPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWinItem --
 *







>


>



<
<

<
<
<
<
<
|
<

>






>
>
|
|
<
|
>
>
|


<
|
|
<

|
>
>
|
>
|
>

>








|








|






|
<
<
<
<
<
<


<
|
<
|
<
<
<
<
<
<
|
<
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







828
829
830
831
832
833
834
835
836
837
838
839
840
841


842





843

844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861

862
863

864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898






899
900

901

902






903

904
905


































906
907
908
909
910
911
912
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;
#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, 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.
     */

    Tcl_DStringInit(&buffer1);
    Tcl_DStringInit(&buffer2);
    Tcl_DStringGetResult(interp, &buffer2);
    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", NULL);
	sprintf(buffer, "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d",

		height, width, height, width);
	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", NULL);
	Tcl_DStringFree(&buffer1);

	return result;
    }
    Tcl_DStringFree(&buffer1);

    /*
     * 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.
     */

    ximage = XGetImage(Tk_Display(tkwin), Tk_WindowId(tkwin), 0, 0,
	    (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);

#ifdef X_GetImage
    Tk_DeleteErrorHandler(handle);
#endif

    if (ximage == NULL) {
	return TCL_OK;






    }


    result = TkPostscriptImage(interp, tkwin,

	    ((TkCanvas *)canvas)->psInfo, ximage, 0, 0, width, height);








    XDestroyImage(ximage);
    return result;


































}

/*
 *--------------------------------------------------------------
 *
 * ScaleWinItem --
 *
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
 */

static void
WinItemStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }
}

/*







|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
 */

static void
WinItemStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = (WindowItem *) clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }
}

/*
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
 */

static void
WinItemRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    (void)tkwin;

    ComputeWindowBbox(winItemPtr->canvas, winItemPtr);

    /*
     * A drawable argument of None to DisplayWinItem is used by the canvas
     * UnmapNotify handler to indicate that we should no longer display
     * ourselves, so need to pass a (bogus) non-zero drawable value here.
     */
    DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr, NULL,
	    (Drawable) -1, 0, 0, 0, 0);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */


static void
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
    (void)tkwin;

    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, winItemPtr);
    if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
    }
    Tk_UnmapWindow(winItemPtr->tkwin);
    winItemPtr->tkwin = NULL;
}








|
<















|


|





|




>

|
|

|

|

<


|







1026
1027
1028
1029
1030
1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
 */

static void
WinItemRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = (WindowItem *) clientData;


    ComputeWindowBbox(winItemPtr->canvas, winItemPtr);

    /*
     * A drawable argument of None to DisplayWinItem is used by the canvas
     * UnmapNotify handler to indicate that we should no longer display
     * ourselves, so need to pass a (bogus) non-zero drawable value here.
     */
    DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr, NULL,
	    (Drawable) -1, 0, 0, 0, 0);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemLostSlaveProc --
 *
 *	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 canvas-related information about the slave.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
WinItemLostSlaveProc(
    ClientData clientData,	/* WindowItem structure for slave window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
{
    WindowItem *winItemPtr = (WindowItem *) clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);


    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, (ClientData) winItemPtr);
    if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
    }
    Tk_UnmapWindow(winItemPtr->tkwin);
    winItemPtr->tkwin = NULL;
}


Changes to generic/tkCanvas.c.

9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28




















29
30
31
32
33
34
35
 * 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.
 */



#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
#endif /* TK_NO_DOUBLE_BUFFERING */

/*
 * See tkCanvas.h for key data structures used to implement canvases.
 */





















/*
 * 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:







>
>
|
|
|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * 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.
 */

/* #define USE_OLD_TAG_SEARCH 1 */

#include "default.h"
#include "tkInt.h"
#include "tkCanvas.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
#endif /* TK_NO_DOUBLE_BUFFERING */

/*
 * See tkCanvas.h for key data structures used to implement canvases.
 */

#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.
 */

typedef struct TagSearch {
    TkCanvas *canvasPtr;	/* Canvas widget being searched. */
    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. */
    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.
 * (
 *   Not quite accurate: the TagSearch structure is also accessed from:
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74


75
76
77
78
79

80
81
82
83
84

85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253

254
255




256
257

258
259
260
261
262



263
264
265






266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
    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. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    int type;			/* Search type (see #defs below) */
    TkSizeT id;			/* Item id for searches by id */
    const 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;

/*
 * Values for the TagSearch type field.
 */

#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 */



/*
 * Custom option for handling "-state" and "-offset"
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc,
    NULL		/* Only "normal" and "disabled". */
};

static const Tk_CustomOption offsetOption = {

    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)

};

/*
 * Information used for argv parsing.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_COLOR, offsetof(TkCanvas, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_MONO, offsetof(TkCanvas, bgBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_CANVAS_BORDER_WIDTH, offsetof(TkCanvas, borderWidth), 0, NULL},
    {TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough",
	DEF_CANVAS_CLOSE_ENOUGH, offsetof(TkCanvas, closeEnough), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine",
	DEF_CANVAS_CONFINE, offsetof(TkCanvas, confine), 0, NULL},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_CANVAS_CURSOR, offsetof(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
	DEF_CANVAS_HEIGHT, offsetof(TkCanvas, height), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG,
	offsetof(TkCanvas, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_CANVAS_HIGHLIGHT, offsetof(TkCanvas, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_CANVAS_HIGHLIGHT_WIDTH, offsetof(TkCanvas, highlightWidth), 0, NULL},
    {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_CANVAS_INSERT_BG, offsetof(TkCanvas, textInfo.insertBorder), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_COLOR,
	offsetof(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_MONO,
	offsetof(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_CANVAS_INSERT_OFF_TIME, offsetof(TkCanvas, insertOffTime), 0, NULL},
    {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_CANVAS_INSERT_ON_TIME, offsetof(TkCanvas, insertOnTime), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_CANVAS_INSERT_WIDTH, offsetof(TkCanvas, textInfo.insertWidth), 0, NULL},
    {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0",
	offsetof(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	&offsetOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_CANVAS_RELIEF, offsetof(TkCanvas, relief), 0, NULL},
    {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion",
	DEF_CANVAS_SCROLL_REGION, offsetof(TkCanvas, regionString),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_COLOR, offsetof(TkCanvas, textInfo.selBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_MONO, offsetof(TkCanvas, textInfo.selBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_COLOR,
	offsetof(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_MONO, offsetof(TkCanvas, textInfo.selBorderWidth),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_COLOR, offsetof(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_MONO, offsetof(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", "state", "State",
	"normal", offsetof(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT,
	&stateOption},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_CANVAS_TAKE_FOCUS, offsetof(TkCanvas, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	DEF_CANVAS_WIDTH, offsetof(TkCanvas, width), 0, NULL},
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_CANVAS_X_SCROLL_CMD, offsetof(TkCanvas, xScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_X_SCROLL_INCREMENT, offsetof(TkCanvas, xScrollIncrement),
	0, NULL},
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_CANVAS_Y_SCROLL_CMD, offsetof(TkCanvas, yScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_Y_SCROLL_INCREMENT, offsetof(TkCanvas, yScrollIncrement),
	0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * 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 been done
				 * yet. */
TCL_DECLARE_MUTEX(typeListMutex)


/*
 * Uids for operands in compiled advanced tag search expressions.
 * Initialization is done by GetStaticUids()
 */

typedef struct {
    Tk_Uid allUid;
    Tk_Uid currentUid;
    Tk_Uid andUid;
    Tk_Uid orUid;
    Tk_Uid xorUid;
    Tk_Uid parenUid;
    Tk_Uid negparenUid;
    Tk_Uid endparenUid;
    Tk_Uid tagvalUid;
    Tk_Uid negtagvalUid;
} SearchUids;

static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);


/*
 * Prototypes for functions defined later in this file:
 */

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 TkSizeT	CanvasFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT 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, TkSizeT 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		DefaultRotateImplementation(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, double x, double y,
			    double angleRadians);
static void		DestroyCanvas(void *memPtr);
static int		DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
static void		DisplayCanvas(ClientData clientData);
static void		DoItem(Tcl_Obj *accumObj,
			    Tk_Item *itemPtr, Tk_Uid tag);
static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr);

static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *const *argv,




			    Tcl_Obj *newTagObj, int first,
			    TagSearch **searchPtrPtr);

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);



static void		PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
static Tcl_Obj *	ScrollFractions(int screen1,
			    int screen2, int object1, int object2);






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);


/*
 * The structure below defines canvas class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs canvasClass = {
    sizeof(Tk_ClassProcs),	/* size */
    CanvasWorldChanged,		/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * Macros that significantly simplify all code that finds items.
 */








#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)))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr)
#define RELINK_ITEMS(objPtr, itemPtr) \
    result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr)

/*
 * ----------------------------------------------------------------------
 *
 * AlwaysRedraw, ItemConfigure, ItemCoords, etc. --
 *
 *	Helper functions that make access to canvas item functions simpler.
 *	Note that these are all inline functions.
 *
 * ----------------------------------------------------------------------
 */

static inline int
AlwaysRedraw(
    Tk_Item *itemPtr)
{
    return itemPtr->typePtr->alwaysRedraw & 1;
}

static inline int
ItemConfigure(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, objv, TK_CONFIG_ARGV_ONLY);
    } else {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline int
ItemConfigInfo(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, (char *) itemPtr,
	    (fieldName ? Tcl_GetString(fieldName) : NULL), 0);
}

static inline int
ItemConfigValue(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, (char *) itemPtr,
	    Tcl_GetString(fieldName), 0);
}

static inline int
ItemCoords(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->coordProc == NULL) {
	result = TCL_OK;
    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, objv);
    } else {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, (Tcl_Obj **) args);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline int
ItemCreate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,		/* Warning: incomplete! typePtr field must be
				 * set by this point. */
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc-3, objv+3);
    } else {
	const char **args = TkGetStringsFromObjs(objc-3, objv+3);

	result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc-3, (Tcl_Obj **) args);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline void
ItemCursor(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int index)
{
    itemPtr->typePtr->icursorProc((Tk_Canvas) canvasPtr, itemPtr, index);
}

static inline void
ItemDelChars(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int first,
    int last)
{
    itemPtr->typePtr->dCharsProc((Tk_Canvas) canvasPtr, itemPtr, first, last);
}

static inline void
ItemDelete(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr)
{
    itemPtr->typePtr->deleteProc((Tk_Canvas) canvasPtr, itemPtr,
	    canvasPtr->display);
}

static inline void
ItemDisplay(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Pixmap pixmap,
    int screenX1, int screenY1,
    int width, int height)
{
    itemPtr->typePtr->displayProc((Tk_Canvas) canvasPtr, itemPtr,
	    canvasPtr->display, pixmap, screenX1, screenY1, width, height);
}

static int
ItemIndex(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *objPtr,
    TkSizeT *indexPtr)
{
    Tcl_Interp *interp = canvasPtr->interp;

    if (itemPtr->typePtr->indexProc == NULL) {
	return TCL_OK;
    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objPtr, indexPtr);
    } else {
	return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, (Tcl_Obj *) Tcl_GetString(objPtr), indexPtr);
    }
}

static inline void
ItemInsert(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int beforeThis,
    Tcl_Obj *toInsert)
{
    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
		beforeThis, toInsert);
    } else {
	itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
		beforeThis, (Tcl_Obj *) Tcl_GetString(toInsert));
    }
}

static inline int
ItemOverlap(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double rect[])
{
    return itemPtr->typePtr->areaProc((Tk_Canvas) canvasPtr, itemPtr, rect);
}

static inline double
ItemPoint(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double coords[],
    double halo)
{
    double dist;

    dist = itemPtr->typePtr->pointProc((Tk_Canvas) canvasPtr, itemPtr,
	    coords) - halo;
    return (dist < 0.0) ? 0.0 : dist;
}

static inline void
ItemScale(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double xOrigin, double yOrigin,
    double xScale, double yScale)
{
    itemPtr->typePtr->scaleProc((Tk_Canvas) canvasPtr, itemPtr,
	    xOrigin, yOrigin, xScale, yScale);
}

static inline int
ItemSelection(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int offset,
    char *buffer,
    int maxBytes)
{
    if (itemPtr == NULL || itemPtr->typePtr->selectionProc == NULL) {
	return -1;
    }

    return itemPtr->typePtr->selectionProc((Tk_Canvas) canvasPtr, itemPtr,
	    offset, buffer, maxBytes);
}

static inline void
ItemTranslate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double xDelta,
    double yDelta)
{
    itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, itemPtr,
	    xDelta, yDelta);
}

static inline void
ItemRotate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{
    if (itemPtr->typePtr->rotateProc != NULL) {
	itemPtr->typePtr->rotateProc((Tk_Canvas) canvasPtr,
		itemPtr, x, y, angleRadians);
    } else {
	DefaultRotateImplementation(canvasPtr, itemPtr, x, y, angleRadians);
    }
}

/*
 *--------------------------------------------------------------
 *
 * DefaultRotateImplementation --
 *
 *	The default implementation of the rotation operation, used when items
 *	do not provide their own version.
 *
 *--------------------------------------------------------------
 */

static void
DefaultRotateImplementation(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{
    int objc, i, ok = 1;
    Tcl_Obj **objv, **newObjv;
    double *coordv;
    double s = sin(angleRadians);
    double c = cos(angleRadians);
    Tcl_Interp *interp = canvasPtr->interp;

    /*
     * Get the coordinates out of the item.
     */

    if (ItemCoords(canvasPtr, itemPtr, 0, NULL) == TCL_OK &&
	    Tcl_ListObjGetElements(NULL, Tcl_GetObjResult(interp),
		    &objc, &objv) == TCL_OK) {
	coordv = (double *) ckalloc(sizeof(double) * objc);
	for (i=0 ; i<objc ; i++) {
	    if (Tcl_GetDoubleFromObj(NULL, objv[i], &coordv[i]) != TCL_OK) {
		ok = 0;
		break;
	    }
	}
	if (ok) {
	    /*
	     * Apply the rotation.
	     */

	    for (i=0 ; i<objc ; i+=2) {
		double px = coordv[i+0] - x;
		double py = coordv[i+1] - y;
		double nx = px * c - py * s;
		double ny = px * s + py * c;

		coordv[i+0] = nx + x;
		coordv[i+1] = ny + y;
	    }

	    /*
	     * Write the coordinates back into the item.
	     */

	    newObjv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * objc);
	    for (i=0 ; i<objc ; i++) {
		newObjv[i] = Tcl_NewDoubleObj(coordv[i]);
		Tcl_IncrRefCount(newObjv[i]);
	    }
	    ItemCoords(canvasPtr, itemPtr, objc, newObjv);
	    for (i=0 ; i<objc ; i++) {
		Tcl_DecrRefCount(newObjv[i]);
	    }
	    ckfree((char *) newObjv);
	}
	ckfree((char *) coordv);
    }

    /*
     * The interpreter result was (probably) modified above; reset it.
     */

    Tcl_ResetResult(interp);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasObjCmd --
 *
 *	This function is invoked to process the "canvas" Tcl command. See the







|
|


















>
>




|
>
|
|


|
>
|
>






|

|
|

|
|
|
|

|

|

|

|

|


|

|


|

|


|


|

|

|

|

|


|

|
|

|
|

|
|


|

|
|

|
|

|
|

|


|
|

|

|
|


|
|

|
|


|
|
|







|
<
|


>




















>












|
|





|





|
|
>


|
<
<
<
|
<

|

|

>

|
>
>
>
>


>

|

|

>
>
>



>
>
>
>
>
>













>






|


<
<






>
>
>
>
>
>
>











<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272



273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328


329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352




353


354



























































































































































































































































































































































355
356
357
358
359
360
361
    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. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    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;

/*
 * Values for the TagSearch type field.
 */

#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 */

#endif /* USE_OLD_TAG_SEARCH */

/*
 * Custom option for handling "-state" and "-offset"
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc,
    (ClientData) NULL	/* only "normal" and "disabled" */
};

static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc,
    (ClientData) TK_OFFSET_RELATIVE
};

/*
 * Information used for argv parsing.
 */

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_COLOR, Tk_Offset(TkCanvas, bgBorder),
	TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_MONO, Tk_Offset(TkCanvas, bgBorder),
	TK_CONFIG_MONO_ONLY},
    {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",
	DEF_CANVAS_CLOSE_ENOUGH, Tk_Offset(TkCanvas, closeEnough), 0},
    {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine",
	DEF_CANVAS_CONFINE, Tk_Offset(TkCanvas, confine), 0},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_CANVAS_CURSOR, Tk_Offset(TkCanvas, cursor), TK_CONFIG_NULL_OK},
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
	DEF_CANVAS_HEIGHT, Tk_Offset(TkCanvas, height), 0},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG,
	Tk_Offset(TkCanvas, highlightBgColorPtr), 0},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_CANVAS_HIGHLIGHT, Tk_Offset(TkCanvas, highlightColorPtr), 0},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_CANVAS_HIGHLIGHT_WIDTH, Tk_Offset(TkCanvas, highlightWidth), 0},
    {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_CANVAS_INSERT_BG, Tk_Offset(TkCanvas, textInfo.insertBorder), 0},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_COLOR,
	Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_MONO,
	Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY},
    {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_CANVAS_INSERT_OFF_TIME, Tk_Offset(TkCanvas, insertOffTime), 0},
    {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_CANVAS_INSERT_ON_TIME, Tk_Offset(TkCanvas, insertOnTime), 0},
    {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_CANVAS_INSERT_WIDTH, Tk_Offset(TkCanvas, textInfo.insertWidth), 0},
    {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0",
	Tk_Offset(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	&offsetOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_CANVAS_RELIEF, Tk_Offset(TkCanvas, relief), 0},
    {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion",
	DEF_CANVAS_SCROLL_REGION, Tk_Offset(TkCanvas, regionString),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_COLOR, Tk_Offset(TkCanvas, textInfo.selBorder),
	TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_MONO, Tk_Offset(TkCanvas, textInfo.selBorder),
	TK_CONFIG_MONO_ONLY},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_COLOR,
	Tk_Offset(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_MONO, Tk_Offset(TkCanvas, textInfo.selBorderWidth),
	TK_CONFIG_MONO_ONLY},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_COLOR, Tk_Offset(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_MONO, Tk_Offset(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-state", "state", "State",
	"normal", Tk_Offset(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT,
	&stateOption},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_CANVAS_TAKE_FOCUS, Tk_Offset(TkCanvas, takeFocus),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	DEF_CANVAS_WIDTH, Tk_Offset(TkCanvas, width), 0},
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_CANVAS_X_SCROLL_CMD, Tk_Offset(TkCanvas, xScrollCmd),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_X_SCROLL_INCREMENT, Tk_Offset(TkCanvas, xScrollIncrement),
	0},
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_CANVAS_Y_SCROLL_CMD, Tk_Offset(TkCanvas, yScrollCmd),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_Y_SCROLL_INCREMENT, Tk_Offset(TkCanvas, yScrollIncrement),
	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.
 */

static Tk_ItemType *typeList = NULL;	/* NULL means initialization hasn't

					 * been done yet. */
TCL_DECLARE_MUTEX(typeListMutex)

#ifndef USE_OLD_TAG_SEARCH
/*
 * Uids for operands in compiled advanced tag search expressions.
 * Initialization is done by GetStaticUids()
 */

typedef struct {
    Tk_Uid allUid;
    Tk_Uid currentUid;
    Tk_Uid andUid;
    Tk_Uid orUid;
    Tk_Uid xorUid;
    Tk_Uid parenUid;
    Tk_Uid negparenUid;
    Tk_Uid endparenUid;
    Tk_Uid tagvalUid;
    Tk_Uid negtagvalUid;
} SearchUids;

static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);
#endif /* USE_OLD_TAG_SEARCH */

/*
 * Prototypes for functions defined later in this file:
 */

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(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *CONST *argv,
			    Tcl_Obj *newTagObj, int first);
#else /* USE_OLD_TAG_SEARCH */
static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *CONST *argv,
			    Tcl_Obj *newTagObj, int first,
			    TagSearch **searchPtrPtr);
#endif /* USE_OLD_TAG_SEARCH */
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(TagSearch *searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
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(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(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 functions
 * that can be invoked from generic window code.
 */

static Tk_ClassProcs canvasClass = {
    sizeof(Tk_ClassProcs),	/* size */
    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 function is invoked to process the "canvas" Tcl command. See the
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
 */

int
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 newWin;

    if (typeList == NULL) {
	InitCanvas();
    }

    if (argc < 2) {
	Tcl_WrongNumArgs(interp, 1, argv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    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).
     */

    canvasPtr = (TkCanvas *)ckalloc(sizeof(TkCanvas));
    canvasPtr->tkwin = newWin;
    canvasPtr->display = Tk_Display(newWin);
    canvasPtr->interp = interp;
    canvasPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd, canvasPtr,
	    CanvasCmdDeletedProc);
    canvasPtr->firstItemPtr = NULL;
    canvasPtr->lastItemPtr = NULL;
    canvasPtr->borderWidth = 0;
    canvasPtr->bgBorder = NULL;
    canvasPtr->relief = TK_RELIEF_FLAT;
    canvasPtr->highlightWidth = 0;
    canvasPtr->highlightBgColorPtr = NULL;
    canvasPtr->highlightColorPtr = NULL;
    canvasPtr->inset = 0;
    canvasPtr->pixmapGC = NULL;
    canvasPtr->width = None;
    canvasPtr->height = None;
    canvasPtr->confine = 0;
    canvasPtr->textInfo.selBorder = NULL;
    canvasPtr->textInfo.selBorderWidth = 0;
    canvasPtr->textInfo.selFgColorPtr = NULL;
    canvasPtr->textInfo.selItemPtr = NULL;
    canvasPtr->textInfo.selectFirst = TCL_INDEX_NONE;
    canvasPtr->textInfo.selectLast = TCL_INDEX_NONE;
    canvasPtr->textInfo.anchorItemPtr = NULL;
    canvasPtr->textInfo.selectAnchor = 0;
    canvasPtr->textInfo.insertBorder = NULL;
    canvasPtr->textInfo.insertWidth = 0;
    canvasPtr->textInfo.insertBorderWidth = 0;
    canvasPtr->textInfo.focusItemPtr = NULL;
    canvasPtr->textInfo.gotFocus = 0;
    canvasPtr->textInfo.cursorOn = 0;
    canvasPtr->insertOnTime = 0;
    canvasPtr->insertOffTime = 0;
    canvasPtr->insertBlinkHandler = NULL;
    canvasPtr->xOrigin = canvasPtr->yOrigin = 0;
    canvasPtr->drawableXOrigin = canvasPtr->drawableYOrigin = 0;
    canvasPtr->bindingTable = NULL;
    canvasPtr->currentItemPtr = NULL;
    canvasPtr->newCurrentPtr = NULL;
    canvasPtr->closeEnough = 0.0;
    canvasPtr->pickEvent.type = LeaveNotify;







|

|








|














|




|
|

















|
|










|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
 */

int
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 newWin;

    if (typeList == NULL) {
	InitCanvas();
    }

    if (argc < 2) {
	Tcl_WrongNumArgs(interp, 1, argv, "pathName ?options?");
	return TCL_ERROR;
    }

    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).
     */

    canvasPtr = (TkCanvas *) ckalloc(sizeof(TkCanvas));
    canvasPtr->tkwin = newWin;
    canvasPtr->display = Tk_Display(newWin);
    canvasPtr->interp = interp;
    canvasPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd,
	    (ClientData) canvasPtr, CanvasCmdDeletedProc);
    canvasPtr->firstItemPtr = NULL;
    canvasPtr->lastItemPtr = NULL;
    canvasPtr->borderWidth = 0;
    canvasPtr->bgBorder = NULL;
    canvasPtr->relief = TK_RELIEF_FLAT;
    canvasPtr->highlightWidth = 0;
    canvasPtr->highlightBgColorPtr = NULL;
    canvasPtr->highlightColorPtr = NULL;
    canvasPtr->inset = 0;
    canvasPtr->pixmapGC = NULL;
    canvasPtr->width = None;
    canvasPtr->height = None;
    canvasPtr->confine = 0;
    canvasPtr->textInfo.selBorder = NULL;
    canvasPtr->textInfo.selBorderWidth = 0;
    canvasPtr->textInfo.selFgColorPtr = NULL;
    canvasPtr->textInfo.selItemPtr = NULL;
    canvasPtr->textInfo.selectFirst = -1;
    canvasPtr->textInfo.selectLast = -1;
    canvasPtr->textInfo.anchorItemPtr = NULL;
    canvasPtr->textInfo.selectAnchor = 0;
    canvasPtr->textInfo.insertBorder = NULL;
    canvasPtr->textInfo.insertWidth = 0;
    canvasPtr->textInfo.insertBorderWidth = 0;
    canvasPtr->textInfo.focusItemPtr = NULL;
    canvasPtr->textInfo.gotFocus = 0;
    canvasPtr->textInfo.cursorOn = 0;
    canvasPtr->insertOnTime = 0;
    canvasPtr->insertOffTime = 0;
    canvasPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
    canvasPtr->xOrigin = canvasPtr->yOrigin = 0;
    canvasPtr->drawableXOrigin = canvasPtr->drawableYOrigin = 0;
    canvasPtr->bindingTable = NULL;
    canvasPtr->currentItemPtr = NULL;
    canvasPtr->newCurrentPtr = NULL;
    canvasPtr->closeEnough = 0.0;
    canvasPtr->pickEvent.type = LeaveNotify;
777
778
779
780
781
782
783

784

785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
    canvasPtr->flags = 0;
    canvasPtr->nextId = 1;
    canvasPtr->psInfo = NULL;
    canvasPtr->canvas_state = TK_STATE_NORMAL;
    canvasPtr->tsoffset.flags = 0;
    canvasPtr->tsoffset.xoffset = 0;
    canvasPtr->tsoffset.yoffset = 0;

    canvasPtr->bindTagExprs = NULL;

    Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);

    Tk_SetClass(canvasPtr->tkwin, "Canvas");
    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    CanvasEventProc, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}








>

>



|


|



|

|




|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
    canvasPtr->flags = 0;
    canvasPtr->nextId = 1;
    canvasPtr->psInfo = NULL;
    canvasPtr->canvas_state = TK_STATE_NORMAL;
    canvasPtr->tsoffset.flags = 0;
    canvasPtr->tsoffset.xoffset = 0;
    canvasPtr->tsoffset.yoffset = 0;
#ifndef USE_OLD_TAG_SEARCH
    canvasPtr->bindTagExprs = NULL;
#endif
    Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);

    Tk_SetClass(canvasPtr->tkwin, "Canvas");
    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, (ClientData) canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    CanvasEventProc, (ClientData) canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, (ClientData) canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, (ClientData) canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC);
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}

826
827
828
829
830
831
832
833
834
835
836
837
838



839
840

841
842
843
844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

886



887
888
889
890
891
892
893
 */

static int
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, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */



    TagSearch *searchPtr = NULL;/* Allocated by first TagSearchScan, freed by
				 * TagSearchDestroy */


    int idx;
    static const char *const canvasOptionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",
        "image",	"imove",	"index",	"insert",
	"itemcget",	"itemconfigure",
	"lower",	"move",		"moveto",	"postscript",
	"raise",	"rchars",	"rotate",	"scale",
	"scan",		"select",	"type",		"xview",
	"yview",	NULL

    };
    enum canvasOptionStringsEnum {
	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
        CANV_IMAGE,	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,
	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
	CANV_RAISE,	CANV_RCHARS,	CANV_ROTATE,	CANV_SCALE,
	CANV_SCAN,	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,
	CANV_YVIEW
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], canvasOptionStrings, "option", 0,
	    &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(canvasPtr);

    result = TCL_OK;
    switch ((enum canvasOptionStringsEnum)idx) {
    case CANV_ADDTAG:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}

	result = FIND_ITEMS(objv[2], 3);



	break;

    case CANV_BBOX: {
	int i, gotAny;
	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;	/* Initializations needed only
						 * to prevent overcautious
						 * compiler warnings. */







|

|



>
>
>


>

|
|




<
|
|
<
|
|
>

|




<
|
|
<
|
|



|


|
|


|


|


|



>
|
>
>
>







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548

549
550
551
552
553
554
555
556
557

558
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
 */

static int
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, 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 */
#endif /* USE_OLD_TAG_SEARCH */

    int index;
    static CONST char *optionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",

	"index",	"insert",	"itemcget",	"itemconfigure",
	"lower",	"move",		"postscript",	"raise",

	"scale",	"scan",		"select",	"type",
	"xview",	"yview",
	NULL
    };
    enum options {
	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,

	CANV_INDEX,	CANV_INSERT,	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
	CANV_LOWER,	CANV_MOVE,	CANV_POSTSCRIPT,CANV_RAISE,

	CANV_SCALE,	CANV_SCAN,	CANV_SELECT,	CANV_TYPE,
	CANV_XVIEW,	CANV_YVIEW
    };

    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;
    }
    Tcl_Preserve((ClientData) canvasPtr);

    result = TCL_OK;
    switch ((enum options) index) {
    case CANV_ADDTAG:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
#ifdef USE_OLD_TAG_SEARCH
	result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3);
#else /* USE_OLD_TAG_SEARCH */
	result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3, &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
	break;

    case CANV_BBOX: {
	int i, gotAny;
	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;	/* Initializations needed only
						 * to prevent overcautious
						 * compiler warnings. */
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954



























955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
		    if (itemPtr->y2 > y2) {
			y2 = itemPtr->y2;
		    }
		}
	    }
	}
	if (gotAny) {
	    Tcl_Obj *resultObjs[4];

	    resultObjs[0] = Tcl_NewWideIntObj(x1);
	    resultObjs[1] = Tcl_NewWideIntObj(y1);
	    resultObjs[2] = Tcl_NewWideIntObj(x2);
	    resultObjs[3] = Tcl_NewWideIntObj(y2);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resultObjs));
	}
	break;
    }
    case CANV_BIND: {
	void *object;

	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?sequence? ?command?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out what object to use for the binding (individual item vs.
	 * tag).
	 */

	object = NULL;



























	result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	if (searchPtr->type == SEARCH_TYPE_ID) {
	    Tcl_HashEntry *entryPtr;

	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
		    INT2PTR(searchPtr->id));
	    if (entryPtr != NULL) {
		itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
		object = itemPtr;
	    }

	    if (object == 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"item \"%s\" doesn't exist", Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM",
			Tcl_GetString(objv[2]), NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    object = (char *)searchPtr->expr->uid;
	}


	/*
	 * Make a binding table if the canvas doesn't already have one.
	 */

	if (canvasPtr->bindingTable == NULL) {
	    canvasPtr->bindingTable = Tk_CreateBindingTable(interp);
	}

	if (objc == 5) {
	    int append = 0;
	    unsigned int mask;
	    const char *argv4 = Tcl_GetString(objv[4]);

	    if (argv4[0] == 0) {
		result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		goto done;
	    }

	    if (searchPtr->type == SEARCH_TYPE_EXPR) {
		/*
		 * If new tag expression, then insert in linked list.
		 */

	    	TagSearchExpr *expr, **lastPtr;








|

|
<
<
<
|




|












|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|

|
|



|
|
<
<




|

>











|
|






>







623
624
625
626
627
628
629
630
631
632



633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695


696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
		    if (itemPtr->y2 > y2) {
			y2 = itemPtr->y2;
		    }
		}
	    }
	}
	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: {
	ClientData object;

	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?sequence? ?command?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out what object to use for the binding (individual item vs.
	 * tag).
	 */

	object = 0;
#ifdef USE_OLD_TAG_SEARCH
	if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))) {
	    int id;
	    char *end;
	    Tcl_HashEntry *entryPtr;

	    id = strtoul(Tcl_GetString(objv[2]), &end, 0);
	    if (*end != 0) {
		goto bindByTag;
	    }
	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id);
	    if (entryPtr != NULL) {
		itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr);
		object = (ClientData) itemPtr;
	    }

	    if (object == 0) {
		Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]),
			"\" doesn't exist", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    bindByTag:
	    object = (ClientData) Tk_GetUid(Tcl_GetString(objv[2]));
	}
#else /* USE_OLD_TAG_SEARCH */
	result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	if (searchPtr->type == SEARCH_TYPE_ID) {
	    Tcl_HashEntry *entryPtr;

	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
		    (char *) INT2PTR(searchPtr->id));
	    if (entryPtr != NULL) {
		itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr);
		object = (ClientData) itemPtr;
	    }

	    if (object == 0) {
		Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]),
			"\" doesn't exist", NULL);


		result = TCL_ERROR;
		goto done;
	    }
	} else {
    	    object = (ClientData) searchPtr->expr->uid;
	}
#endif /* USE_OLD_TAG_SEARCH */

	/*
	 * Make a binding table if the canvas doesn't already have one.
	 */

	if (canvasPtr->bindingTable == NULL) {
	    canvasPtr->bindingTable = Tk_CreateBindingTable(interp);
	}

	if (objc == 5) {
	    int append = 0;
	    unsigned long mask;
	    char* argv4 = Tcl_GetString(objv[4]);

	    if (argv4[0] == 0) {
		result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		goto done;
	    }
#ifndef USE_OLD_TAG_SEARCH
	    if (searchPtr->type == SEARCH_TYPE_EXPR) {
		/*
		 * If new tag expression, then insert in linked list.
		 */

	    	TagSearchExpr *expr, **lastPtr;

1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058


1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
		     * Flag in TagSearch that expr has changed ownership so
		     * that TagSearchDestroy doesn't try to free it.
		     */

		    searchPtr->expr = NULL;
		}
	    }

	    if (argv4[0] == '+') {
		argv4++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]), argv4, append);
	    if (mask == 0) {
		result = TCL_ERROR;
		goto done;
	    }
	    if (mask & ~(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"requested illegal events; only key, button, motion,"
			" enter, leave, and virtual events may be used", -1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_EVENTS", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else if (objc == 4) {
	    const char *command;

	    command = Tk_GetBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]));
	    if (command == NULL) {


		const char *string = Tcl_GetString(Tcl_GetObjResult(interp));

		/*
		 * Ignore missing binding errors. This is a special hack that
		 * relies on the error message returned by FindSequence in
		 * tkBind.c.
		 */

		if (string[0] != '\0') {
		    result = TCL_ERROR;
		    goto done;
		}
		Tcl_ResetResult(interp);

	    } else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
	    }
	} else {
	    Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
	}
	break;
    }
    case CANV_CANVASX: {
	int x;
	double grid;


	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "screenx ?gridspacing?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2],
		&x) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[3], &grid) != TCL_OK) {
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    grid = 0.0;
	}
	x += canvasPtr->xOrigin;
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)x,grid)));

	break;
    }
    case CANV_CANVASY: {
	int y;
	double grid;


	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "screeny ?gridspacing?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2],
		&y) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[3], &grid) != TCL_OK) {
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    grid = 0.0;
	}
	y += canvasPtr->yOrigin;
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)y,grid)));

	break;
    }
    case CANV_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;







>










|






|
|
|
|




|




>
>
|










|
|
>

|









>






|
<




|
|







|
>





>






|
<













|
>







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
		     * 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_GetString(objv[3]), argv4, append);
	    if (mask == 0) {
		result = TCL_ERROR;
		goto done;
	    }
	    if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			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", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else if (objc == 4) {
	    CONST char *command;

	    command = Tk_GetBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]));
	    if (command == NULL) {
		CONST char *string;

		string = Tcl_GetStringResult(interp);

		/*
		 * Ignore missing binding errors. This is a special hack that
		 * relies on the error message returned by FindSequence in
		 * tkBind.c.
		 */

		if (string[0] != '\0') {
		    result = TCL_ERROR;
		    goto done;
		} else {
		    Tcl_ResetResult(interp);
		}
	    } else {
		Tcl_SetResult(interp, (char *) command, TCL_STATIC);
	    }
	} else {
	    Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
	}
	break;
    }
    case CANV_CANVASX: {
	int x;
	double grid;
	char buf[TCL_DOUBLE_SPACE];

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "screenx ?gridspacing?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &x) != TCL_OK) {

	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3],
		    &grid) != TCL_OK) {
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    grid = 0.0;
	}
	x += canvasPtr->xOrigin;
	Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    case CANV_CANVASY: {
	int y;
	double grid;
	char buf[TCL_DOUBLE_SPACE];

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "screeny ?gridspacing?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &y) != TCL_OK) {

	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[3], &grid) != TCL_OK) {
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    grid = 0.0;
	}
	y += canvasPtr->yOrigin;
	Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    case CANV_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
1157
1158
1159
1160
1161
1162
1163
1164
1165



1166










1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249


1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275




1276
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

1309
1310
1311
1312
1313
1314









1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337

1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354


1355






1356
1357
1358
1359






1360


1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396

1397

1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?x y x y ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    if (objc != 3) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }



	    result = ItemCoords(canvasPtr, itemPtr, objc-3, objv+3);










	    if (objc != 3) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	}
	break;
    case CANV_IMOVE: {
	double ignored;
	Tcl_Obj *tmpObj;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index x y");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[4], &ignored) != TCL_OK
		|| Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[5], &ignored) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Make a temporary object here that we can reuse for all the
	 * modifications in the loop.
	 */

	tmpObj = Tcl_NewListObj(2, objv+4);

	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
	    TkSizeT index;
	    int x1, x2, y1, y2;
	    int dontRedraw1, dontRedraw2;

	    /*
	     * The TK_MOVABLE_POINTS flag should only be set for types that
	     * support the same semantics of index, dChars and insert methods
	     * as lines and canvases.
	     */

	    if (itemPtr == NULL ||
		    !(itemPtr->typePtr->alwaysRedraw & TK_MOVABLE_POINTS)) {
		continue;
	    }

	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	    if (result != TCL_OK) {
		break;
	    }

	    /*
	     * Redraw both item's old and new areas: it's possible that a
	     * replace could result in a new area larger than the old area.
	     * Except if the dCharsProc or insertProc sets the
	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;

	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemDelChars(canvasPtr, itemPtr, index, index);
	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemInsert(canvasPtr, itemPtr, index, tmpObj);
	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

	    if (!(dontRedraw1 && dontRedraw2)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}

    doneImove:
	Tcl_DecrRefCount(tmpObj);
	break;
    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;


	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	TkSizeT length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	c = arg[0];

	/*
	 * Lock because the list of types is a global resource that could be
	 * updated by another thread. That's fairly unlikely, but not
	 * impossible.
	 */

	Tcl_MutexLock(&typeListMutex);
	for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr){
	    if ((c == typePtr->name[0])
		    && (!strncmp(arg, typePtr->name, length))) {
		if (matchPtr != NULL) {
		    Tcl_MutexUnlock(&typeListMutex);
		    goto badType;




		}
		matchPtr = typePtr;
	    }
	}

	/*
	 * Can unlock now because we no longer look at the fields of the
	 * matched item type that are potentially modified by other threads.

	 */

	Tcl_MutexUnlock(&typeListMutex);
	if (matchPtr == NULL) {
	badType:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "unknown or ambiguous item type \"%s\"", arg));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM_TYPE", arg,
		    NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc < 4) {
	    /*
	     * Allow more specific error return.
	     */

	    Tcl_WrongNumArgs(interp, 3, objv, "coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}

	typePtr = matchPtr;
	itemPtr = (Tk_Item *)ckalloc(typePtr->itemSize);
	itemPtr->id = canvasPtr->nextId++;

	itemPtr->tagPtr = itemPtr->staticTagSpace;
	itemPtr->tagSpace = TK_TAG_SPACE;
	itemPtr->numTags = 0;
	itemPtr->typePtr = typePtr;
	itemPtr->state = TK_STATE_NULL;
	itemPtr->redraw_flags = 0;











	if (ItemCreate(canvasPtr, itemPtr, objc, objv) != TCL_OK) {
	    ckfree(itemPtr);
	    result = TCL_ERROR;
	    goto done;
	}

	itemPtr->nextPtr = NULL;
	entryPtr = Tcl_CreateHashEntry(&canvasPtr->idTable,
		INT2PTR(itemPtr->id), &isNew);
	Tcl_SetHashValue(entryPtr, itemPtr);
	itemPtr->prevPtr = canvasPtr->lastItemPtr;
	canvasPtr->hotPtr = itemPtr;
	canvasPtr->hotPrevPtr = canvasPtr->lastItemPtr;
	if (canvasPtr->lastItemPtr == NULL) {
	    canvasPtr->firstItemPtr = itemPtr;
	} else {
	    canvasPtr->lastItemPtr->nextPtr = itemPtr;
	}
	canvasPtr->lastItemPtr = itemPtr;
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;

	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if ((itemPtr->typePtr->indexProc == NULL)
		    || (itemPtr->typePtr->dCharsProc == NULL)) {
		continue;
	    }


	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &first);






	    if (result != TCL_OK) {
		goto done;
	    }
	    if (objc == 5) {






		result = ItemIndex(canvasPtr, itemPtr, objv[4], &last);


		if (result != TCL_OK) {
		    goto done;
		}
	    } else {
		last = first;
	    }

	    /*
	     * 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 dCharsProc sets the TK_ITEM_DONT_REDRAW flag,
	     * nothing more needs to be done.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;

	    ItemDelChars(canvasPtr, itemPtr, first, last);
	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_DELETE: {
	int i;
	Tcl_HashEntry *entryPtr;

	for (i = 2; i < objc; i++) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
		if (canvasPtr->bindingTable != NULL) {
		    Tk_DeleteAllBindings(canvasPtr->bindingTable, itemPtr);

		}

		ItemDelete(canvasPtr, itemPtr);
		if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
		    ckfree(itemPtr->tagPtr);
		}
		entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
			INT2PTR(itemPtr->id));
		Tcl_DeleteHashEntry(entryPtr);
		if (itemPtr->nextPtr != NULL) {
		    itemPtr->nextPtr->prevPtr = itemPtr->prevPtr;
		}
		if (itemPtr->prevPtr != NULL) {
		    itemPtr->prevPtr->nextPtr = itemPtr->nextPtr;
		}
		if (canvasPtr->firstItemPtr == itemPtr) {
		    canvasPtr->firstItemPtr = itemPtr->nextPtr;
		    if (canvasPtr->firstItemPtr == NULL) {
			canvasPtr->lastItemPtr = NULL;
		    }
		}
		if (canvasPtr->lastItemPtr == itemPtr) {
		    canvasPtr->lastItemPtr = itemPtr->prevPtr;
		}
		ckfree(itemPtr);
		if (itemPtr == canvasPtr->currentItemPtr) {
		    canvasPtr->currentItemPtr = NULL;
		    canvasPtr->flags |= REPICK_NEEDED;
		}
		if (itemPtr == canvasPtr->newCurrentPtr) {
		    canvasPtr->newCurrentPtr = NULL;
		    canvasPtr->flags |= REPICK_NEEDED;







|

>
>
>
|
>
>
>
>
>
>
>
>
>
>

|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



>
>


|
|


|



|

<
<
<
<
<
<
<

|

|


|
>
>
>
>




<

|
|
>

<


|
<
<
<
<
<
<





<
|



<

|
|
>






>
>
>
>
>
>
>
>
>
|
>
|
|



<


|











|

>
|



|
|











>
>
|
>
>
>
>
>
>




>
>
>
>
>
>
|
>
>










|






>
|



|











|

|
>

>
|

|


|
















|







887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914











































































915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

947
948
949
950
951

952
953
954






955
956
957
958
959

960
961
962
963

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?x y x y ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	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 = 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: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	Tk_Item *itemPtr;
	char buf[TCL_INTEGER_SPACE];
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	char *arg;
	int length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = Tcl_GetStringFromObj(objv[2], &length);
	c = arg[0];







	Tcl_MutexLock(&typeListMutex);
	for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr) {
	    if ((c == typePtr->name[0])
		    && (strncmp(arg, typePtr->name, (unsigned)length) == 0)) {
		if (matchPtr != NULL) {
		    Tcl_MutexUnlock(&typeListMutex);
		badType:
		    Tcl_AppendResult(interp,
			    "unknown or ambiguous item type \"",arg,"\"",NULL);
		    result = TCL_ERROR;
		    goto done;
		}
		matchPtr = typePtr;
	    }
	}

	/*
	 * Can unlock now because we no longer look at the fields of
	 * the matched item type that are potentially modified by
	 * other threads.
	 */

	Tcl_MutexUnlock(&typeListMutex);
	if (matchPtr == NULL) {
	    goto badType;






	}
	if (objc < 4) {
	    /*
	     * Allow more specific error return.
	     */

	    Tcl_WrongNumArgs(interp, 3, objv, "coords ?arg arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}

	typePtr = matchPtr;
	itemPtr = (Tk_Item *) ckalloc((unsigned) typePtr->itemSize);
	itemPtr->id = canvasPtr->nextId;
	canvasPtr->nextId++;
	itemPtr->tagPtr = itemPtr->staticTagSpace;
	itemPtr->tagSpace = TK_TAG_SPACE;
	itemPtr->numTags = 0;
	itemPtr->typePtr = typePtr;
	itemPtr->state = TK_STATE_NULL;
	itemPtr->redraw_flags = 0;
	if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	    result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr,
		    itemPtr, objc-3, objv+3);
	} else {
	    CONST char **args = TkGetStringsFromObjs(objc-3, objv+3);
	    result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr,
		    itemPtr, objc-3, (Tcl_Obj **) args);
	    if (args != NULL) {
		ckfree((char *) args);
	    }
	}
	if (result != TCL_OK) {
	    ckfree((char *) itemPtr);
	    result = TCL_ERROR;
	    goto done;
	}

	itemPtr->nextPtr = NULL;
	entryPtr = Tcl_CreateHashEntry(&canvasPtr->idTable,
		(char *) INT2PTR(itemPtr->id), &isNew);
	Tcl_SetHashValue(entryPtr, itemPtr);
	itemPtr->prevPtr = canvasPtr->lastItemPtr;
	canvasPtr->hotPtr = itemPtr;
	canvasPtr->hotPrevPtr = canvasPtr->lastItemPtr;
	if (canvasPtr->lastItemPtr == NULL) {
	    canvasPtr->firstItemPtr = itemPtr;
	} else {
	    canvasPtr->lastItemPtr->nextPtr = itemPtr;
	}
	canvasPtr->lastItemPtr = itemPtr;
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
	sprintf(buf, "%d", itemPtr->id);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    case CANV_DCHARS: {
	int first, last;
	int x1,x2,y1,y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}
	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);
	    } else {
		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);
		} else {
		    result = itemPtr->typePtr->indexProc(interp,
			    (Tk_Canvas) canvasPtr, itemPtr,
			    Tcl_GetString(objv[4]), &last);
		}
		if (result != TCL_OK) {
		    goto done;
		}
	    } else {
		last = first;
	    }

	    /*
	     * 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;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    (*itemPtr->typePtr->dCharsProc)((Tk_Canvas) canvasPtr,
		    itemPtr, first, last);
	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_DELETE: {
	int i;
	Tcl_HashEntry *entryPtr;

	for (i = 2; i < objc; i++) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
		if (canvasPtr->bindingTable != NULL) {
		    Tk_DeleteAllBindings(canvasPtr->bindingTable,
			    (ClientData) itemPtr);
		}
		(*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr,
			canvasPtr->display);
		if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
		    ckfree((char *) itemPtr->tagPtr);
		}
		entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
			(char *) INT2PTR(itemPtr->id));
		Tcl_DeleteHashEntry(entryPtr);
		if (itemPtr->nextPtr != NULL) {
		    itemPtr->nextPtr->prevPtr = itemPtr->prevPtr;
		}
		if (itemPtr->prevPtr != NULL) {
		    itemPtr->prevPtr->nextPtr = itemPtr->nextPtr;
		}
		if (canvasPtr->firstItemPtr == itemPtr) {
		    canvasPtr->firstItemPtr = itemPtr->nextPtr;
		    if (canvasPtr->firstItemPtr == NULL) {
			canvasPtr->lastItemPtr = NULL;
		    }
		}
		if (canvasPtr->lastItemPtr == itemPtr) {
		    canvasPtr->lastItemPtr = itemPtr->prevPtr;
		}
		ckfree((char *) itemPtr);
		if (itemPtr == canvasPtr->currentItemPtr) {
		    canvasPtr->currentItemPtr = NULL;
		    canvasPtr->flags |= REPICK_NEEDED;
		}
		if (itemPtr == canvasPtr->newCurrentPtr) {
		    canvasPtr->newCurrentPtr = NULL;
		    canvasPtr->flags |= REPICK_NEEDED;
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485



1486


1487
1488
1489
1490
1491
1492
1493
1494
1495
1496

1497


1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551


1552






1553
1554
1555

1556
1557
1558
1559
1560
1561
1562
1563
1564
1565

1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584


1585




1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605


1606






1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620


1621




1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639


1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650


1651
1652


1653
1654


1655










1656
1657
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680



1681
1682
1683
1684

1685



1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    for (i = (int)itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == tag) {

                    /*
                     * Don't shuffle the tags sequence: memmove the tags.
                     */

                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;

                    /*
                     * There must be no break here: all tags with the same name must
                     * be deleted.
                     */

 		}
	    }
	}
	break;
    }
    case CANV_FIND:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}



	result = FIND_ITEMS(NULL, 2);


	break;
    case CANV_FOCUS:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?tagOrId?");
	    result = TCL_ERROR;
	    goto done;
	}
	itemPtr = canvasPtr->textInfo.focusItemPtr;
	if (objc == 2) {
	    if (itemPtr != NULL) {

		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));


	    }
	    goto done;
	}
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	}
	if (Tcl_GetString(objv[2])[0] == 0) {
	    canvasPtr->textInfo.focusItemPtr = NULL;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if (itemPtr->typePtr->icursorProc != NULL) {
		break;
	    }
	}
	if (itemPtr == NULL) {
	    goto done;
	}
	canvasPtr->textInfo.focusItemPtr = itemPtr;
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	}
	break;
    case CANV_GETTAGS:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (i = 0; i < (int)itemPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(itemPtr->tagPtr[i], -1));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    case CANV_ICURSOR: {
	TkSizeT index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if ((itemPtr->typePtr->indexProc == NULL)
		    || (itemPtr->typePtr->icursorProc == NULL)) {
		goto done;
	    }


	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);






	    if (result != TCL_OK) {
		goto done;
	    }

	    ItemCursor(canvasPtr, itemPtr, index);
	    if ((itemPtr == canvasPtr->textInfo.focusItemPtr)
		    && (canvasPtr->textInfo.cursorOn)) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	}
	break;
    }
    case CANV_INDEX: {
	TkSizeT index;


	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if (itemPtr->typePtr->indexProc != NULL) {
		break;
	    }
	}
	if (itemPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't find an indexable item \"%s\"",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "INDEXABLE_ITEM", NULL);
	    result = TCL_ERROR;
	    goto done;
	}


	result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);




	if (result != TCL_OK) {
	    goto done;
	}

	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	break;
    }
    case CANV_INSERT: {
	TkSizeT beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if ((itemPtr->typePtr->indexProc == NULL)
		    || (itemPtr->typePtr->insertProc == NULL)) {
		continue;
	    }


	    result = ItemIndex(canvasPtr, itemPtr, 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.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;


	    ItemInsert(canvasPtr, itemPtr, beforeThis, objv[4]);




	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_ITEMCGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId option");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    result = ItemConfigValue(canvasPtr, itemPtr, objv[3]);


	}
	break;
    case CANV_ITEMCONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?-option value ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if (objc == 3) {
		result = ItemConfigInfo(canvasPtr, itemPtr, NULL);


	    } else if (objc == 4) {
		result = ItemConfigInfo(canvasPtr, itemPtr, objv[3]);


	    } else {
		EventuallyRedrawItem(canvasPtr, itemPtr);


		result = ItemConfigure(canvasPtr, itemPtr, objc-3, objv+3);










		EventuallyRedrawItem(canvasPtr, itemPtr);
		canvasPtr->flags |= REPICK_NEEDED;
	    }
	    if ((result != TCL_OK) || (objc < 5)) {
		break;
	    }
	}
	break;
    case CANV_LOWER: {


	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?belowThis?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * First find the item just after which we'll insert the named items.
	 */

	if (objc == 3) {
	    itemPtr = NULL;
	} else {
	    FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done);
	    if (itemPtr == NULL) {



		goto done;
	    }
	    itemPtr = itemPtr->prevPtr;
	}

	RELINK_ITEMS(objv[2], itemPtr);



	break;
    }
    case CANV_MOVE: {
	double xAmount, yAmount;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId xAmount yAmount");
	    result = TCL_ERROR;
	    goto done;
	}
	if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3],
		&xAmount) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp,
		(Tk_Canvas) canvasPtr, objv[4], &yAmount) != TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    ItemTranslate(canvasPtr, itemPtr, xAmount, yAmount);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_MOVETO: {
	int xBlank, yBlank;
	double xAmount, yAmount;
	double oldX = 0, oldY = 0, newX, newY;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId x y");
	    result = TCL_ERROR;
	    goto done;
	}

	xBlank = 0;
	if (Tcl_GetString(objv[3])[0] == '\0') {
	    xBlank = 1;
	} else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		objv[3], &newX) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}

	yBlank = 0;
	if (Tcl_GetString(objv[4])[0] == '\0') {
	    yBlank = 1;
	} else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		objv[4], &newY) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}

	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    oldX = itemPtr->x1;
	    oldY = itemPtr->y1;

	    /*
	     * Calculate the displacement.
	     */

	    if (xBlank) {
		xAmount = 0;
	    } else {
		xAmount = newX - oldX;
	    }

	    if (yBlank) {
		yAmount = 0;
	    } else {
		yAmount = newY - oldY;
	    }

	    /*
	     * Move the object(s).
	     */

	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
		ItemTranslate(canvasPtr, itemPtr, xAmount, yAmount);
		EventuallyRedrawItem(canvasPtr, itemPtr);
		canvasPtr->flags |= REPICK_NEEDED;
	    }
	}
	break;
    }
    case CANV_POSTSCRIPT: {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = TkCanvPostscriptCmd(canvasPtr, interp, objc, args);
	if (args != NULL) {
	    ckfree(args);
	}
	break;
    }
    case CANV_RAISE: {
	Tk_Item *prevPtr;

	if ((objc != 3) && (objc != 4)) {







|

<
<
<
<
<
<
|
<

|
<
<
<
<
<
<






|



>
>
>
|
>
>










>
|
>
>



|
|















|











<
<
|
|
<

<



|











>
>
|
>
>
>
>
>
>



>
|


|





|
>












<
|
|
<



>
>
|
>
>
>
>



>
|



|
|











>
>
|
>
>
>
>
>
>














>
>
|
>
>
>
>



|













|
>
>




|





|
>
>

|
>
>

|
>
>
|
>
>
>
>
>
>
>
>
>
>
|








>
















>
>
>




>
|
>
>
>

















|
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<



|



|







1139
1140
1141
1142
1143
1144
1145
1146
1147






1148

1149
1150






1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212


1213
1214

1215

1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437


1438





1439




















































1440


1441
1442

1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	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];

		    itemPtr->numTags--;
		}






	    }
	}
	break;
    }
    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, NULL, 2);
#else /* USE_OLD_TAG_SEARCH */
	result = FindItems(interp, canvasPtr, objc, objv, NULL, 2,
		&searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
	break;
    case CANV_FOCUS:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?tagOrId?");
	    result = TCL_ERROR;
	    goto done;
	}
	itemPtr = canvasPtr->textInfo.focusItemPtr;
	if (objc == 2) {
	    if (itemPtr != NULL) {
		char buf[TCL_INTEGER_SPACE];

		sprintf(buf, "%d", itemPtr->id);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    }
	    goto done;
	}
	if ((itemPtr != NULL) && (canvasPtr->textInfo.gotFocus)) {
	    EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	}
	if (Tcl_GetString(objv[2])[0] == 0) {
	    canvasPtr->textInfo.focusItemPtr = NULL;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if (itemPtr->typePtr->icursorProc != NULL) {
		break;
	    }
	}
	if (itemPtr == NULL) {
	    goto done;
	}
	canvasPtr->textInfo.focusItemPtr = itemPtr;
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	}
	break;
    case CANV_GETTAGS:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;


	    for (i = 0; i < itemPtr->numTags; i++) {
		Tcl_AppendElement(interp, (char *) itemPtr->tagPtr[i]);

	    }

	}
	break;
    case CANV_ICURSOR: {
	int index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
	    result = TCL_ERROR;
	    goto done;
	}
	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);
	    } else {
		result = itemPtr->typePtr->indexProc(interp,
			(Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]),
			&index);
	    }
	    if (result != TCL_OK) {
		goto done;
	    }
	    (*itemPtr->typePtr->icursorProc)((Tk_Canvas) canvasPtr, itemPtr,
		    index);
	    if ((itemPtr == canvasPtr->textInfo.focusItemPtr)
		    && (canvasPtr->textInfo.cursorOn)) {
		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	    }
	}
	break;
    }
    case CANV_INDEX: {
	int index;
	char buf[TCL_INTEGER_SPACE];

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
	    result = TCL_ERROR;
	    goto done;
	}
	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_GetString(objv[2]), "\"", NULL);

	    result = TCL_ERROR;
	    goto done;
	}
	if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	    result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		    itemPtr, (char *) objv[3], &index);
	} else {
	    result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		    itemPtr, Tcl_GetString(objv[3]), &index);
	}
	if (result != TCL_OK) {
	    goto done;
	}
	sprintf(buf, "%d", index);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    case CANV_INSERT: {
	int beforeThis;
	int x1,x2,y1,y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}
	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);
	    } else {
		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.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
		(*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr,
			itemPtr, beforeThis, (char *) objv[4]);
	    } else {
		(*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr,
			itemPtr, beforeThis, Tcl_GetString(objv[4]));
	    }
	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_ITEMCGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId option");
	    result = TCL_ERROR;
	    goto done;
	}
	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_GetString(objv[3]), 0);
	}
	break;
    case CANV_ITEMCONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?option value ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	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,
			NULL, 0);
	    } else if (objc == 4) {
		result = Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
			itemPtr->typePtr->configSpecs, (char *) itemPtr,
			Tcl_GetString(objv[3]), 0);
	    } 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);
		} else {
		    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;
	    }
	    if ((result != TCL_OK) || (objc < 5)) {
		break;
	    }
	}
	break;
    case CANV_LOWER: {
	Tk_Item *itemPtr;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?belowThis?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * First find the item just after which we'll insert the named items.
	 */

	if (objc == 3) {
	    itemPtr = NULL;
	} else {
	    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", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    itemPtr = itemPtr->prevPtr;
	}
#ifdef USE_OLD_TAG_SEARCH
	RelinkItems(canvasPtr, objv[2], itemPtr);
#else /* USE_OLD_TAG_SEARCH */
	result = RelinkItems(canvasPtr, objv[2], itemPtr, &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
	break;
    }
    case CANV_MOVE: {
	double xAmount, yAmount;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId xAmount yAmount");
	    result = TCL_ERROR;
	    goto done;
	}
	if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3],
		&xAmount) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp,
		(Tk_Canvas) canvasPtr, objv[4], &yAmount) != TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	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);




















































	    EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);


	    canvasPtr->flags |= REPICK_NEEDED;
	}

	break;
    }
    case CANV_POSTSCRIPT: {
	CONST char **args = TkGetStringsFromObjs(objc, objv);

	result = TkCanvPostscriptCmd(canvasPtr, interp, objc, args);
	if (args != NULL) {
	    ckfree((char *) args);
	}
	break;
    }
    case CANV_RAISE: {
	Tk_Item *prevPtr;

	if ((objc != 3) && (objc != 4)) {
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
	    prevPtr = canvasPtr->lastItemPtr;
	} else {
	    prevPtr = NULL;
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		prevPtr = itemPtr;
	    }
	    if (prevPtr == NULL) {
		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;
	int dontRedraw1, dontRedraw2;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    if ((itemPtr->typePtr->indexProc == NULL)
		    || (itemPtr->typePtr->dCharsProc == NULL)
		    || (itemPtr->typePtr->insertProc == NULL)) {
		continue;
	    }
	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &first);
	    if (result != TCL_OK) {
		goto done;
	    }
	    result = ItemIndex(canvasPtr, itemPtr, objv[4], &last);
	    if (result != TCL_OK) {
		goto done;
	    }

	    /*
	     * Redraw both item's old and new areas: it's possible that a
	     * replace could result in a new area larger than the old area.
	     * Except if the dCharsProc or insertProc sets the
	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;

            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemDelChars(canvasPtr, itemPtr, first, last);
	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemInsert(canvasPtr, itemPtr, first, objv[5]);
	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

            if (!(dontRedraw1 && dontRedraw2)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_ROTATE: {
	double x, y, angle;
	Tk_Canvas canvas = (Tk_Canvas) canvasPtr;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId x y angle");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3], &x) != TCL_OK ||
		Tk_CanvasGetCoordFromObj(interp, canvas, objv[4], &y) != TCL_OK ||
		Tcl_GetDoubleFromObj(interp, objv[5], &angle) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}
	angle = angle * 3.1415927 / 180.0;
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    ItemRotate(canvasPtr, itemPtr, x, y, angle);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCALE: {
	double xOrigin, yOrigin, xScale, yScale;

	if (objc != 7) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "tagOrId xOrigin yOrigin xScale yScale");
	    result = TCL_ERROR;
	    goto done;
	}
	if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[3], &xOrigin) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[4], &yOrigin) != TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[5], &xScale)!=TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[6], &yScale)!=TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	if ((xScale == 0.0) || (yScale == 0.0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "scale factor cannot be zero", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_SCALE", NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);

	    ItemScale(canvasPtr, itemPtr, xOrigin, yOrigin, xScale, yScale);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCAN: {
	int x, y, gain = 10;
	static const char *const optionStrings[] = {
	    "mark", "dragto", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &idx) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+idx)) {
	    Tcl_WrongNumArgs(interp, 3, objv, idx?"x y ?gain?":"x y");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (!idx) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;








<
<
<
|
<
<
<
<
<
<
|
<
<
|
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
<







|
|




<
|
<




|
>
|
|






|







|

|
|







|







1468
1469
1470
1471
1472
1473
1474



1475






1476


1477
1478
1479





1480








1481






1482


1483



1484



1485































1486
1487
1488
1489
1490
1491
1492

1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505

1506

1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
	    prevPtr = canvasPtr->lastItemPtr;
	} else {
	    prevPtr = NULL;
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		prevPtr = itemPtr;
	    }
	    if (prevPtr == NULL) {



		Tcl_AppendResult(interp, "tagOrId \"", Tcl_GetString(objv[3]),






			"\" doesn't match any items", NULL);


		result = TCL_ERROR;
		goto done;
	    }





	}








#ifdef USE_OLD_TAG_SEARCH






	RelinkItems(canvasPtr, objv[2], prevPtr);


#else /* USE_OLD_TAG_SEARCH */



	result = RelinkItems(canvasPtr, objv[2], prevPtr, &searchPtr);



#endif /* USE_OLD_TAG_SEARCH */































	break;
    }
    case CANV_SCALE: {
	double xOrigin, yOrigin, xScale, yScale;

	if (objc != 7) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId xOrigin yOrigin xScale yScale");

	    result = TCL_ERROR;
	    goto done;
	}
	if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[3], &xOrigin) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		    objv[4], &yOrigin) != TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[5], &xScale) != TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[6], &yScale) != TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	if ((xScale == 0.0) || (yScale == 0.0)) {

	    Tcl_SetResult(interp, "scale factor cannot be zero", TCL_STATIC);

	    result = TCL_ERROR;
	    goto done;
	}
	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);
	    EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCAN: {
	int x, y, gain = 10;
	static CONST char *optionStrings[] = {
	    "mark", "dragto", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &index) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+index)) {
	    Tcl_WrongNumArgs(interp, 3, objv, index?"x y ?gain?":"x y");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (!index) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;

1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994


1995






1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029


2030
2031


2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
		    - canvasPtr->scrollY1;
	    newYOrigin = canvasPtr->scrollY1 + tmp;
	    CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
	}
	break;
    }
    case CANV_SELECT: {
	TkSizeT index;
	int optionindex;
	static const char *const optionStrings[] = {
	    "adjust", "clear", "from", "item", "to", NULL
	};
	enum options {
	    CANV_ADJUST, CANV_CLEAR, CANV_FROM, CANV_ITEM, CANV_TO
	};

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?tagOrId? ?arg?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc >= 4) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		if ((itemPtr->typePtr->indexProc != NULL)
			&& (itemPtr->typePtr->selectionProc != NULL)){
		    break;
		}
	    }
	    if (itemPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't find an indexable and selectable item \"%s\"",
			Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SELECTABLE_ITEM",
			NULL);
		result = TCL_ERROR;
		goto done;
	    }
	}
	if (objc == 5) {


	    result = ItemIndex(canvasPtr, itemPtr, objv[4], &index);






	    if (result != TCL_OK) {
		goto done;
	    }
	}
	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:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr == itemPtr) {
		if (index + 1 <= ((canvasPtr->textInfo.selectFirst
			+ canvasPtr->textInfo.selectLast)/2)) {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectLast + 1;
		} else {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectFirst;
		}
	    }
	    CanvasSelectTo(canvasPtr, itemPtr, index);
	    break;
	case CANV_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }


	    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr);
	    canvasPtr->textInfo.selItemPtr = NULL;


	    break;
	case CANV_FROM:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    canvasPtr->textInfo.anchorItemPtr = itemPtr;
	    canvasPtr->textInfo.selectAnchor = index;
	    break;
	case CANV_ITEM:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj(canvasPtr->textInfo.selItemPtr->id));
	    }
	    break;
	case CANV_TO:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;







<
|
|



















|
|
|
<
<





>
>
|
>
>
>
>
>
>

















|
|















>
>
|
|
>
>


















|







1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587


1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
		    - canvasPtr->scrollY1;
	    newYOrigin = canvasPtr->scrollY1 + tmp;
	    CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
	}
	break;
    }
    case CANV_SELECT: {

	int index, optionindex;
	static CONST char *optionStrings[] = {
	    "adjust", "clear", "from", "item", "to", NULL
	};
	enum options {
	    CANV_ADJUST, CANV_CLEAR, CANV_FROM, CANV_ITEM, CANV_TO
	};

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?tagOrId? ?arg?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc >= 4) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		if ((itemPtr->typePtr->indexProc != NULL)
			&& (itemPtr->typePtr->selectionProc != NULL)){
		    break;
		}
	    }
	    if (itemPtr == NULL) {
		Tcl_AppendResult(interp,
			"can't find an indexable and selectable item \"",
			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);
	    } else {
		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) {
	    result = TCL_ERROR;
	    goto done;
	}
	switch ((enum options) optionindex) {
	case CANV_ADJUST:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr == itemPtr) {
		if (index < (canvasPtr->textInfo.selectFirst
			+ canvasPtr->textInfo.selectLast)/2) {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectLast + 1;
		} else {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectFirst;
		}
	    }
	    CanvasSelectTo(canvasPtr, itemPtr, index);
	    break;
	case CANV_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr != NULL) {
		EventuallyRedrawItem((Tk_Canvas) canvasPtr,
			canvasPtr->textInfo.selItemPtr);
		canvasPtr->textInfo.selItemPtr = NULL;
	    }
	    goto done;
	    break;
	case CANV_FROM:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    canvasPtr->textInfo.anchorItemPtr = itemPtr;
	    canvasPtr->textInfo.selectAnchor = index;
	    break;
	case CANV_ITEM:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewIntObj(canvasPtr->textInfo.selItemPtr->id));
	    }
	    break;
	case CANV_TO:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115

2116
2117
2118
2119

2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148

2149
2150
2151
2152
2153

2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188

2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209

2210

2211
2212
2213
2214
2215
2216
2217
2218
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(itemPtr->typePtr->name, -1));
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->xOrigin + canvasPtr->inset,
		    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
		    - canvasPtr->inset, canvasPtr->scrollX1,
		    canvasPtr->scrollX2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(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;
	}
	CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);

	break;
    }
    case CANV_YVIEW: {
	int count, type;
	int newY = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->yOrigin + canvasPtr->inset,
		    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
		    - canvasPtr->inset,
		    canvasPtr->scrollY1, canvasPtr->scrollY2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(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
		    * (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;
	}
	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
	break;
    }
    case CANV_IMAGE: {
        Tk_PhotoHandle photohandle;
        int subsample = 1, zoom = 1;

        if (objc < 3 || objc > 5) {
            Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?");
            result = TCL_ERROR;
            goto done;
        }

        if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) {
            result = TCL_ERROR;
            goto done;
        }

        /*
         * If we are given a subsample or a zoom then grab them.
         */

        if (objc >= 4 && Tcl_GetIntFromObj(interp, objv[3], &subsample) != TCL_OK) {
            result = TCL_ERROR;
            goto done;

        }
        if (objc >= 5 && Tcl_GetIntFromObj(interp, objv[4], &zoom) != TCL_OK) {
            result = TCL_ERROR;
            goto done;
        }

        /*
         * Set the image size to zero, which allows the DrawCanvas() function
         * to expand the image automatically when it copies the pixmap into it.
         */

        if (Tk_PhotoSetSize(interp, photohandle, 0, 0) != TCL_OK) {
            result = TCL_ERROR;
            goto done;
        }

        result = DrawCanvas(interp, clientData, photohandle, subsample, zoom);
    }
    }

  done:

    TagSearchDestroy(searchPtr);

    Tcl_Release(canvasPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyCanvas --







<
|




|
|

<







<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
>
|
|
|
|
>




|
|

<







<
<
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
<
|
<
<
<
>
|
<
|
<
|
|
<
<
<
<
|
<
<
<
<
|
<




>

>
|







1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685
1686
1687
1688
1689

1690
1691
1692
1693
1694
1695
1696


1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735

1736
1737
1738
1739
1740
1741
1742


1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764




















1765
1766

1767
1768



1769



1770
1771

1772

1773
1774




1775




1776

1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {

	    Tcl_SetResult(interp, itemPtr->typePtr->name, TCL_STATIC);
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent
				 * gcc warnings. */
	double fraction;


	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->xOrigin + canvasPtr->inset,
		    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
		    - canvasPtr->inset, canvasPtr->scrollX1,
		    canvasPtr->scrollX2));


	} else {
	    CONST char **args = TkGetStringsFromObjs(objc, objv);
	    type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	    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;
	    }
	    CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);
	}
	break;
    }
    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(
		    canvasPtr->yOrigin + canvasPtr->inset,
		    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
		    - canvasPtr->inset,
		    canvasPtr->scrollY1, canvasPtr->scrollY2));


	} else {
	    CONST char **args = TkGetStringsFromObjs(objc, objv);
	    type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	    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
			* (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;

	    }
	    CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);




	}




	break;

    }
    }

  done:
#ifndef USE_OLD_TAG_SEARCH
    TagSearchDestroy(searchPtr);
#endif /* not USE_OLD_TAG_SEARCH */
    Tcl_Release((ClientData) canvasPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyCanvas --
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238

2239

2240
2241
2242
2243
2244
2245
2246
2247

2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263

2264
2265
2266
2267
2268
2269

2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
    void *memPtr)		/* Info about canvas widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)memPtr;
    Tk_Item *itemPtr;

    TagSearchExpr *expr, *next;


    /*
     * Free up all of the items in the canvas.
     */

    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = canvasPtr->firstItemPtr) {
	canvasPtr->firstItemPtr = itemPtr->nextPtr;

	ItemDelete(canvasPtr, itemPtr);
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	ckfree(itemPtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteHashTable(&canvasPtr->idTable);
    if (canvasPtr->pixmapGC != NULL) {
	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
    }

    expr = canvasPtr->bindTagExprs;
    while (expr) {
	next = expr->next;
	TagSearchExprDestroy(expr);
	expr = next;
    }

    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureCanvas --
 *







|

|

>

>








>
|

|

|











>






>






|







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
    char *memPtr)		/* Info about canvas widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *) memPtr;
    Tk_Item *itemPtr;
#ifndef USE_OLD_TAG_SEARCH
    TagSearchExpr *expr, *next;
#endif

    /*
     * Free up all of the items in the canvas.
     */

    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = canvasPtr->firstItemPtr) {
	canvasPtr->firstItemPtr = itemPtr->nextPtr;
	(*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr,
		canvasPtr->display);
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree((char *) itemPtr->tagPtr);
	}
	ckfree((char *) itemPtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteHashTable(&canvasPtr->idTable);
    if (canvasPtr->pixmapGC != NULL) {
	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
    }
#ifndef USE_OLD_TAG_SEARCH
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	next = expr->next;
	TagSearchExprDestroy(expr);
	expr = next;
    }
#endif /* USE_OLD_TAG_SEARCH */
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree((char *) canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureCanvas --
 *
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320

static int
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 newGC;
    Tk_State old_canvas_state=canvasPtr->canvas_state;

    if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,
	    objc, (const char **) objv, (char *) canvasPtr,
	    flags|TK_CONFIG_OBJS) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * 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.







|







|







1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898

static int
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 newGC;
    Tk_State old_canvas_state=canvasPtr->canvas_state;

    if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,
	    objc, (CONST char **) objv, (char *) canvasPtr,
	    flags|TK_CONFIG_OBJS) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * 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.
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
		if (result != TCL_OK) {
		    Tcl_ResetResult(canvasPtr->interp);
		}
	    }
	}
    }

     /*
     * Reset the desired dimensions for the window.
     */

    Tk_GeometryRequest(canvasPtr->tkwin, canvasPtr->width + 2*canvasPtr->inset,
	    canvasPtr->height + 2*canvasPtr->inset);

    /*







|







1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
		if (result != TCL_OK) {
		    Tcl_ResetResult(canvasPtr->interp);
		}
	    }
	}
    }

    /*
     * Reset the desired dimensions for the window.
     */

    Tk_GeometryRequest(canvasPtr->tkwin, canvasPtr->width + 2*canvasPtr->inset,
	    canvasPtr->height + 2*canvasPtr->inset);

    /*
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420

    canvasPtr->scrollX1 = 0;
    canvasPtr->scrollY1 = 0;
    canvasPtr->scrollX2 = 0;
    canvasPtr->scrollY2 = 0;
    if (canvasPtr->regionString != NULL) {
	int argc2;
	const char **argv2;

	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scrollRegion \"%s\"", canvasPtr->regionString));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SCROLL_REGION", NULL);
	badRegion:
	    ckfree(canvasPtr->regionString);
	    ckfree(argv2);
	    canvasPtr->regionString = NULL;
	    return TCL_ERROR;
	}
	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[0], &canvasPtr->scrollX1) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[1], &canvasPtr->scrollY1) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[2], &canvasPtr->scrollX2) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[3], &canvasPtr->scrollY2) != TCL_OK)) {
	    goto badRegion;
	}
	ckfree(argv2);
    }

    flags = canvasPtr->tsoffset.flags;
    if (flags & TK_OFFSET_LEFT) {
	canvasPtr->tsoffset.xoffset = 0;
    } else if (flags & TK_OFFSET_CENTER) {
	canvasPtr->tsoffset.xoffset = canvasPtr->width/2;







|






|
|
<
|

|













|







1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973

1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997

    canvasPtr->scrollX1 = 0;
    canvasPtr->scrollY1 = 0;
    canvasPtr->scrollX2 = 0;
    canvasPtr->scrollY2 = 0;
    if (canvasPtr->regionString != NULL) {
	int argc2;
	CONST char **argv2;

	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {
	    Tcl_AppendResult(interp, "bad scrollRegion \"",
		    canvasPtr->regionString, "\"", NULL);

	    badRegion:
	    ckfree(canvasPtr->regionString);
	    ckfree((char *) argv2);
	    canvasPtr->regionString = NULL;
	    return TCL_ERROR;
	}
	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[0], &canvasPtr->scrollX1) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[1], &canvasPtr->scrollY1) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[2], &canvasPtr->scrollX2) != TCL_OK)
		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
		    argv2[3], &canvasPtr->scrollY2) != TCL_OK)) {
	    goto badRegion;
	}
	ckfree((char *) argv2);
    }

    flags = canvasPtr->tsoffset.flags;
    if (flags & TK_OFFSET_LEFT) {
	canvasPtr->tsoffset.xoffset = 0;
    } else if (flags & TK_OFFSET_CENTER) {
	canvasPtr->tsoffset.xoffset = canvasPtr->width/2;
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471

2472

2473
2474

2475


2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasWorldChanged --
 *
 *	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 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(
    ClientData instanceData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)instanceData;
    Tk_Item *itemPtr;



    itemPtr = canvasPtr->firstItemPtr;
    for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) {

	if (ItemConfigure(canvasPtr, itemPtr, 0, NULL) != TCL_OK) {


	    Tcl_ResetResult(canvasPtr->interp);
	}
    }
    canvasPtr->flags |= REPICK_NEEDED;
    Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}

/*
 *----------------------------------------------------------------------
 *
 * DecomposeMaskToShiftAndBits --
 *
 *      Given a 32 bit pixel mask, we find the position of the lowest bit and the
 *      width of the mask bits.
 *
 * Results:
 *	None.
 *
 * Side effects:
*       None.
 *
 *----------------------------------------------------------------------
 */
static void
DecomposeMaskToShiftAndBits(
    unsigned int mask,     /* The pixel mask to examine */
    int *shift,             /* Where to put the shift count (position of lowest bit) */
    int *bits)              /* Where to put the bit count (width of the pixel mask) */
{
    int i;

    *shift = 0;
    *bits = 0;

    /*
     * Find the lowest '1' bit in the mask.
     */

    for (i = 0; i < 32; ++i) {
        if (mask & 1 << i)
            break;
    }
    if (i < 32) {
        *shift = i;

        /*
        * Now find the next '0' bit and the width of the mask.
        */

        for ( ; i < 32; ++i) {
            if ((mask & 1 << i) == 0)
                break;
            else
                ++*bits;
        }

        /*
        * Limit to the top 8 bits if the mask was wider than 8.
        */

        if (*bits > 8) {
            *shift += *bits - 8;
            *bits = 8;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawCanvas --
 *
 *      This function draws the contents of a canvas into the given Photo image.
 *      This function is called from the widget "image" subcommand.
 *      The canvas does not need to be mapped (one of it's ancestors must be)
 *      in order for this function to work.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *      Canvas contents from within the -scrollregion or widget size are rendered
 *      into the Photo. Any errors are left in the result.
 *
 *----------------------------------------------------------------------
 */

#define OVERDRAW_PIXELS 32        /* How much larger we make the pixmap
                                   * that the canvas objects are drawn into */

/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */
#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)

#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))

static int
DrawCanvas(
    Tcl_Interp *interp,           /* As passed to the widget command, and we will leave errors here */
    ClientData clientData,
    Tk_PhotoHandle photohandle,   /* The photo we are rendering into */
    int subsample,                /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
    int zoom)
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin;
    Display *displayPtr;
    Tk_PhotoImageBlock blockPtr = {0,0,0,0,0,{0,0,0,0}};
    Window wid;
    Tk_Item *itemPtr;
    Pixmap pixmap = 0;
    XImage *ximagePtr = NULL;
    Visual *visualPtr;
    GC xgc = 0;
    XGCValues xgcValues;
    int canvasX1, canvasY1, canvasX2, canvasY2, cWidth, cHeight,
        pixmapX1, pixmapY1, pixmapX2, pixmapY2, pmWidth, pmHeight,
        bitsPerPixel, bytesPerPixel, x, y, result = TCL_OK,
        rshift, gshift, bshift, rbits, gbits, bbits;

#ifdef DEBUG_DRAWCANVAS
    char buffer[128];
#endif

    if ((tkwin = canvasPtr->tkwin) == NULL) {
        Tcl_AppendResult(interp, "canvas tkwin is NULL!", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
     * If this canvas is unmapped, then we won't have a window id, so we will
     * try the ancestors of the canvas until we find a window that has a
     * valid window id. The Tk_GetPixmap() call requires a valid window id.
     */

    do {

        if ((displayPtr = Tk_Display(tkwin)) == NULL) {
            Tcl_AppendResult(interp, "canvas (or parent) display is NULL!", NULL);
            result = TCL_ERROR;
            goto done;
        }

        if ((wid = Tk_WindowId(tkwin)) != 0) {
            continue;
        }

        if ((tkwin = Tk_Parent(tkwin)) == NULL) {
            Tcl_AppendResult(interp, "canvas has no parent with a valid window id! Is the toplevel window mapped?", NULL);
            result = TCL_ERROR;
            goto done;
        }

    } while (wid == 0);

    bitsPerPixel = Tk_Depth(tkwin);
    visualPtr = Tk_Visual(tkwin);

    if (subsample == 0) {
        Tcl_AppendResult(interp, "subsample cannot be zero", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
    * 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;
            itemPtr = itemPtr -> nextPtr) {
        if (itemPtr -> redraw_flags & FORCE_REDRAW) {
            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
            EventuallyRedrawItem(canvasPtr, itemPtr);
            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
        }
    }

    /*
     * The DisplayCanvas() function works out the region that needs redrawing,
     * but we don't do this. We grab the whole scrollregion or canvas window
     * area. If we have a defined -scrollregion we use that as the drawing
     * region, otherwise use the canvas window height and width with an origin
     * of 0,0.
     */
    if (canvasPtr->scrollX1 != 0 || canvasPtr->scrollY1 != 0 ||
            canvasPtr->scrollX2 != 0 || canvasPtr->scrollY2 != 0) {

        canvasX1 = canvasPtr->scrollX1;
        canvasY1 = canvasPtr->scrollY1;
        canvasX2 = canvasPtr->scrollX2;
        canvasY2 = canvasPtr->scrollY2;
        cWidth = canvasX2 - canvasX1 + 1;
        cHeight = canvasY2 - canvasY1 + 1;

    } else {

        cWidth = Tk_Width(tkwin);
        cHeight = Tk_Height(tkwin);
        canvasX1 = 0;
        canvasY1 = 0;
        canvasX2 = canvasX1 + cWidth - 1;
        canvasY2 = canvasY1 + cHeight - 1;
    }

    /*
     * Allocate a pixmap to draw into. We add OVERDRAW_PIXELS in the same way
     * that DisplayCanvas() does to avoid problems on some systems when objects
     * are being drawn too close to the edge.
     */

    pixmapX1 = canvasX1 - OVERDRAW_PIXELS;
    pixmapY1 = canvasY1 - OVERDRAW_PIXELS;
    pixmapX2 = canvasX2 + OVERDRAW_PIXELS;
    pixmapY2 = canvasY2 + OVERDRAW_PIXELS;
    pmWidth = pixmapX2 - pixmapX1 + 1;
    pmHeight = pixmapY2 - pixmapY1 + 1;
    if ((pixmap = Tk_GetPixmap(displayPtr, Tk_WindowId(tkwin), pmWidth, pmHeight,
            bitsPerPixel)) == 0) {
        Tcl_AppendResult(interp, "failed to create drawing Pixmap", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
     * Before we can draw the canvas objects into the pixmap it's background
     * should be filled with canvas background colour.
     */

    xgcValues.function = GXcopy;
    xgcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
    xgc = XCreateGC(displayPtr, pixmap, GCFunction|GCForeground, &xgcValues);
    XFillRectangle(displayPtr,pixmap,xgc,0,0,pmWidth,pmHeight);

    /*
     * Draw all the cavas items into the pixmap
     */

    canvasPtr->drawableXOrigin = pixmapX1;
    canvasPtr->drawableYOrigin = pixmapY1;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
            itemPtr = itemPtr->nextPtr) {
        if ((itemPtr->x1 >= pixmapX2) || (itemPtr->y1 >= pixmapY2) ||
                (itemPtr->x2 < pixmapX1) || (itemPtr->y2 < pixmapY1)) {
            if (!AlwaysRedraw(itemPtr)) {
                continue;
            }
        }
        if (itemPtr->state == TK_STATE_HIDDEN ||
                (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state
                == TK_STATE_HIDDEN)) {
            continue;
        }
        ItemDisplay(canvasPtr, itemPtr, pixmap, pixmapX1, pixmapY1, pmWidth,
                pmHeight);
    }

    /*
     * Copy the Pixmap into an ZPixmap format XImage so we can copy it across
     * to the photo image. This seems to be the only way to get Pixmap image
     * data out of an image. Note we have to account for the OVERDRAW_PIXELS
     * border width.
     */

    if ((ximagePtr = XGetImage(displayPtr, pixmap, -pixmapX1, -pixmapY1, cWidth,
            cHeight, AllPlanes, ZPixmap)) == NULL) {
        Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
        result = TCL_ERROR;
        goto done;
    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, "ximagePtr {", NULL);
    sprintf(buffer,"%d",ximagePtr->width);   Tcl_AppendResult(interp, " width ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->height);  Tcl_AppendResult(interp, " height ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->format);  Tcl_AppendResult(interp, " format ", buffer, NULL);
                                             Tcl_AppendResult(interp, " ximagePtr->data", NULL);
    if (ximagePtr->data != NULL) {
	int ix, iy;

        Tcl_AppendResult(interp, " {", NULL);
	for (iy = 0; iy < ximagePtr->height; ++ iy) {
	    Tcl_AppendResult(interp, " {", NULL);
	    for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
	        if (ix > 0) {
                    if (ix % 4 == 0)
                        Tcl_AppendResult(interp, "-", NULL);
                    else
                        Tcl_AppendResult(interp, " ", NULL);
                }
	        sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
	        Tcl_AppendResult(interp, buffer, NULL);
	    }
	    Tcl_AppendResult(interp, " }", NULL);
	}
	Tcl_AppendResult(interp, " }", NULL);
    } else
	sprintf(buffer," NULL");
    sprintf(buffer,"%d",ximagePtr->byte_order);       Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_unit);      Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_pad);       Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->depth);            Tcl_AppendResult(interp, " depth ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bytes_per_line);   Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bits_per_pixel);   Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

    Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

#endif

    /*
     * Fill in the PhotoImageBlock structure abd allocate a block of memory
     * for the converted image data. Note we allocate an alpha channel even
     * though we don't use one, because this layout helps Tk_PhotoPutBlock()
     * use memcpy() instead of the slow pixel or line copy.
     */

    blockPtr.width = cWidth;
    blockPtr.height = cHeight;
    blockPtr.pixelSize = 4;
    blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;
    blockPtr.offset[0] = 0;
    blockPtr.offset[1] = 1;
    blockPtr.offset[2] = 2;
    blockPtr.offset[3] = 3;
    blockPtr.pixelPtr = (unsigned char *)ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);

    /*
     * Now convert the image data pixel by pixel from XImage to 32bit RGBA
     * format suitable for Tk_PhotoPutBlock().
     */

    DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
    DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
    DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);

#ifdef DEBUG_DRAWCANVAS
    sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
    sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
    sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
    sprintf(buffer,"%d",rbits);  Tcl_AppendResult(interp, " rbits ", buffer, NULL);
    sprintf(buffer,"%d",gbits);  Tcl_AppendResult(interp, " gbits ", buffer, NULL);
    sprintf(buffer,"%d",bbits);  Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
    Tcl_AppendResult(interp, "\nConverted_image {", NULL);
#endif

    /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
     * below to get this to work on Windows. X11 correctly sets the bitmap
     *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
     * respectively!
     */

    bytesPerPixel = ximagePtr->bits_per_pixel/8;
    for (y = 0; y < blockPtr.height; ++y) {

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " {", NULL);
#endif

        for(x = 0; x < blockPtr.width; ++x) {
            unsigned int pixel = 0;

            switch (ximagePtr->bits_per_pixel) {

                /*
                 * Get an 8 bit pixel from the XImage.
                 */

                case 8 :
                    pixel = *((unsigned char *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    break;

                /*
                 * Get a 16 bit pixel from the XImage, and correct the
                 * byte order as necessary.
                 */

                case 16 :
                    pixel = *((unsigned short *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
                        pixel = BYTE_SWAP16(pixel);
                    break;

                /*
                 * Grab a 32 bit pixel from the XImage, and correct the
                 * byte order as necessary.
                 */

                case 32 :
                    pixel = *((unsigned int *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
                        pixel = BYTE_SWAP32(pixel);
                    break;
            }

            /*
             * We have a pixel with the correct byte order, so pull out the
             * colours and place them in the photo block. Perhaps we could
             * just not bother with the alpha byte because we are using
             * TK_PHOTO_COMPOSITE_SET later?
             * ***Windows: We have to swap the red and blue values. The
             * XImage storage is B - G - R - A which becomes a 32bit ARGB
             * quad. However the visual mask is a 32bit ABGR quad. And
             * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
             * If the visual mask was correct there would be no need to
             * swap anything here.
             */

#ifdef _WIN32
#define   R_OFFSET 2
#define   B_OFFSET 0
#else
#define   R_OFFSET 0
#define   B_OFFSET 2
#endif
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =
                    (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
                    (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] =
                    (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF;

#ifdef DEBUG_DRAWCANVAS
            {
		int ix;
                if (x > 0)
                    Tcl_AppendResult(interp, "-", NULL);
	        for (ix = 0; ix < 4; ++ix) {
                    if (ix > 0)
                        Tcl_AppendResult(interp, " ", NULL);
		    sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y
                            + blockPtr.pixelSize * x + ix]&0xFF);
                    Tcl_AppendResult(interp, buffer, NULL);
                }
            }
#endif

        }

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " }", NULL);
#endif

    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, " }", NULL);
#endif

    /*
     * Now put the copied pixmap into the photo.
     * If either zoom or subsample are not 1, we use the zoom function.
     */

    if (subsample != 1 || zoom != 1) {
        if ((result = Tk_PhotoPutZoomedBlock(interp, photohandle, &blockPtr,
                0, 0, cWidth * zoom / subsample, cHeight * zoom / subsample,
                zoom, zoom, subsample, subsample, TK_PHOTO_COMPOSITE_SET))
                != TCL_OK) {
            goto done;
        }
    } else {
        if ((result = Tk_PhotoPutBlock(interp, photohandle, &blockPtr, 0, 0,
            cWidth, cHeight, TK_PHOTO_COMPOSITE_SET)) != TCL_OK) {
            goto done;
        }
    }

    /*
     * Clean up anything we have allocated and exit.
     */

done:
    if (blockPtr.pixelPtr)
        ckfree(blockPtr.pixelPtr);
    if (pixmap)
        Tk_FreePixmap(Tk_Display(tkwin), pixmap);
    if (ximagePtr)
        XDestroyImage(ximagePtr);
    if (xgc)
        XFreeGC(displayPtr,xgc);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayCanvas --
 *
 *	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.
 *
 * Side effects:
 *	Information appears on the screen.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCanvas(
    ClientData clientData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tk_Item *itemPtr;
    Pixmap pixmap;
    int screenX1, screenX2, screenY1, screenY2, width, height;

    if (canvasPtr->tkwin == NULL) {
	return;







|















|






|

>

>


>
|
>
>











|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|






|







2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069














































































































































































































































































































































































































































































































2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * CanvasWorldChanged --
 *
 *	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 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(
    ClientData instanceData)	/* Information about widget. */
{
    TkCanvas *canvasPtr;
    Tk_Item *itemPtr;
    int result;

    canvasPtr = (TkCanvas *) instanceData;
    itemPtr = canvasPtr->firstItemPtr;
    for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) {
	result = (*itemPtr->typePtr->configProc)(canvasPtr->interp,
		(Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
		TK_CONFIG_ARGV_ONLY);
	if (result != TCL_OK) {
	    Tcl_ResetResult(canvasPtr->interp);
	}
    }
    canvasPtr->flags |= REPICK_NEEDED;
    Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}

/*
 *--------------------------------------------------------------














































































































































































































































































































































































































































































































 *
 * DisplayCanvas --
 *
 *	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.
 *
 * Side effects:
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayCanvas(
    ClientData clientData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tk_Item *itemPtr;
    Pixmap pixmap;
    int screenX1, screenX2, screenY1, screenY2, width, height;

    if (canvasPtr->tkwin == NULL) {
	return;
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066

    /*
     * Choose a new current item if that is needed (this could cause event
     * handlers to be invoked).
     */

    while (canvasPtr->flags & REPICK_NEEDED) {
	Tcl_Preserve(canvasPtr);
	canvasPtr->flags &= ~REPICK_NEEDED;
	PickCurrentItem(canvasPtr, &canvasPtr->pickEvent);
	tkwin = canvasPtr->tkwin;
	Tcl_Release(canvasPtr);
	if (tkwin == NULL) {
	    return;
	}
    }

    /*
     * 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;
	    itemPtr = itemPtr->nextPtr) {
	if (itemPtr->redraw_flags & FORCE_REDRAW) {
	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
	}
    }

    /*
     * Compute the intersection between the area that needs redrawing and the
     * area that's visible on the screen.
     */

    if ((canvasPtr->redrawX1 < canvasPtr->redrawX2)
	    && (canvasPtr->redrawY1 < canvasPtr->redrawY2)) {







|



|












|


|



<







2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150
2151
2152
2153

    /*
     * Choose a new current item if that is needed (this could cause event
     * handlers to be invoked).
     */

    while (canvasPtr->flags & REPICK_NEEDED) {
	Tcl_Preserve((ClientData) canvasPtr);
	canvasPtr->flags &= ~REPICK_NEEDED;
	PickCurrentItem(canvasPtr, &canvasPtr->pickEvent);
	tkwin = canvasPtr->tkwin;
	Tcl_Release((ClientData) canvasPtr);
	if (tkwin == NULL) {
	    return;
	}
    }

    /*
     * 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;
		itemPtr = itemPtr->nextPtr) {
	if (itemPtr->redraw_flags & FORCE_REDRAW) {
	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
	    EventuallyRedrawItem((Tk_Canvas)canvasPtr, itemPtr);
	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
	}
    }

    /*
     * Compute the intersection between the area that needs redrawing and the
     * area that's visible on the screen.
     */

    if ((canvasPtr->redrawX1 < canvasPtr->redrawX2)
	    && (canvasPtr->redrawY1 < canvasPtr->redrawY2)) {
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169

3170
3171
3172
3173
3174
3175
3176
3177

	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    if ((itemPtr->x1 >= screenX2)
		    || (itemPtr->y1 >= screenY2)
		    || (itemPtr->x2 < screenX1)
		    || (itemPtr->y2 < screenY1)) {
		if (!AlwaysRedraw(itemPtr)
			|| (itemPtr->x1 >= canvasPtr->redrawX2)
			|| (itemPtr->y1 >= canvasPtr->redrawY2)
			|| (itemPtr->x2 < canvasPtr->redrawX1)
			|| (itemPtr->y2 < canvasPtr->redrawY1)) {
		    continue;
		}
	    }
	    if (itemPtr->state == TK_STATE_HIDDEN ||
		    (itemPtr->state == TK_STATE_NULL &&
		    canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
		continue;
	    }

	    ItemDisplay(canvasPtr, itemPtr, pixmap, screenX1, screenY1, width,
		    height);
	}

#ifndef TK_NO_DOUBLE_BUFFERING
	/*
	 * Copy from the temporary pixmap to the screen, then free up the
	 * temporary pixmap.







|








|
|


>
|







2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265

	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    if ((itemPtr->x1 >= screenX2)
		    || (itemPtr->y1 >= screenY2)
		    || (itemPtr->x2 < screenX1)
		    || (itemPtr->y2 < screenY1)) {
		if (!(itemPtr->typePtr->alwaysRedraw & 1)
			|| (itemPtr->x1 >= canvasPtr->redrawX2)
			|| (itemPtr->y1 >= canvasPtr->redrawY2)
			|| (itemPtr->x2 < canvasPtr->redrawX1)
			|| (itemPtr->y2 < canvasPtr->redrawY1)) {
		    continue;
		}
	    }
	    if (itemPtr->state == TK_STATE_HIDDEN ||
		(itemPtr->state == TK_STATE_NULL &&
		 canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
		continue;
	    }
	    (*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr, itemPtr,
		    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.
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
    canvasPtr->redrawY1 = canvasPtr->redrawY2 = 0;
    if (canvasPtr->flags & UPDATE_SCROLLBARS) {
	CanvasUpdateScrollbars(canvasPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasEventProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (eventPtr->type == Expose) {
	int x, y;

	x = eventPtr->xexpose.x + canvasPtr->xOrigin;
	y = eventPtr->xexpose.y + canvasPtr->yOrigin;
	Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x, y,







|










|
|

|







|







2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
    canvasPtr->redrawY1 = canvasPtr->redrawY2 = 0;
    if (canvasPtr->flags & UPDATE_SCROLLBARS) {
	CanvasUpdateScrollbars(canvasPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * CanvasEventProc --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
CanvasEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;

    if (eventPtr->type == Expose) {
	int x, y;

	x = eventPtr->xexpose.x + canvasPtr->xOrigin;
	y = eventPtr->xexpose.y + canvasPtr->yOrigin;
	Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x, y,
3274
3275
3276
3277
3278
3279
3280
3281
3282

3283
3284
3285
3286
3287
3288
3289
3290
    } else if (eventPtr->type == DestroyNotify) {
	if (canvasPtr->tkwin != NULL) {
	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
	}

	Tcl_EventuallyFree(canvasPtr, (Tcl_FreeProc *) DestroyCanvas);
    } else if (eventPtr->type == ConfigureNotify) {
	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.
	 */







|

>
|







2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
    } else if (eventPtr->type == DestroyNotify) {
	if (canvasPtr->tkwin != NULL) {
	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, (ClientData) canvasPtr);
	}
	Tcl_EventuallyFree((ClientData) canvasPtr,
		(Tcl_FreeProc *) DestroyCanvas);
    } else if (eventPtr->type == ConfigureNotify) {
	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.
	 */
3310
3311
3312
3313
3314
3315
3316
3317

3318
3319
3320
3321
3322
3323
3324
3325
	 * 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;
		itemPtr = itemPtr->nextPtr) {
	    if (AlwaysRedraw(itemPtr)) {

		ItemDisplay(canvasPtr, itemPtr, None, 0, 0, 0, 0);
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------







|
>
|







2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
	 * 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;
		itemPtr = itemPtr->nextPtr) {
	    if (itemPtr->typePtr->alwaysRedraw & 1) {
		(*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr,
			itemPtr, canvasPtr->display, None, 0, 0, 0, 0);
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
 *----------------------------------------------------------------------
 */

static void
CanvasCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;

    /*
     * 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) {
	canvasPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasEventuallyRedraw --
 *
 *	Arrange for part or all of a canvas widget to redrawn at some
 *	convenient time in the future.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The screen will eventually be refreshed.
 *
 *----------------------------------------------------------------------
 */

void
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 = Canvas(canvas);

    /*
     * If tkwin is NULL, the canvas has been destroyed, so we can't really
     * redraw it.
     */

    if (canvasPtr->tkwin == NULL) {







|
















|












|










|







2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
 *----------------------------------------------------------------------
 */

static void
CanvasCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;
    Tk_Window tkwin = canvasPtr->tkwin;

    /*
     * 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) {
	canvasPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasEventuallyRedraw --
 *
 *	Arrange for part or all of a canvas widget to redrawn at some
 *	convenient time in the future.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The screen will eventually be refreshed.
 *
 *--------------------------------------------------------------
 */

void
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) {
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
	canvasPtr->redrawX1 = x1;
	canvasPtr->redrawY1 = y1;
	canvasPtr->redrawX2 = x2;
	canvasPtr->redrawY2 = y2;
	canvasPtr->flags |= BBOX_NOT_EMPTY;
    }
    if (!(canvasPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayCanvas, canvasPtr);
	canvasPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawItem --
 *
 *	Arrange for part or all of a canvas widget to redrawn at some
 *	convenient time in the future.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The screen will eventually be refreshed.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyRedrawItem(
    TkCanvas *canvasPtr,	/* Information about widget. */
    Tk_Item *itemPtr)		/* Item to be redrawn. May be NULL, in which
				 * case nothing happens. */
{
    if (itemPtr == NULL || canvasPtr->tkwin == NULL) {
	return;
    }
    if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) ||
 	    (itemPtr->x2 < canvasPtr->xOrigin) ||
	    (itemPtr->y2 < canvasPtr->yOrigin) ||
	    (itemPtr->x1 >= canvasPtr->xOrigin+Tk_Width(canvasPtr->tkwin)) ||
	    (itemPtr->y1 >= canvasPtr->yOrigin+Tk_Height(canvasPtr->tkwin))) {
	if (!AlwaysRedraw(itemPtr)) {
	    return;
	}
    }
    if (!(itemPtr->redraw_flags & FORCE_REDRAW)) {
	if (canvasPtr->flags & BBOX_NOT_EMPTY) {
	    if (itemPtr->x1 <= canvasPtr->redrawX1) {
		canvasPtr->redrawX1 = itemPtr->x1;







|





|












|




|
|
<

|
<
<



|
|
|







2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540

2541
2542


2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
	canvasPtr->redrawX1 = x1;
	canvasPtr->redrawY1 = y1;
	canvasPtr->redrawX2 = x2;
	canvasPtr->redrawY2 = y2;
	canvasPtr->flags |= BBOX_NOT_EMPTY;
    }
    if (!(canvasPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
	canvasPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
 * EventuallyRedrawItem --
 *
 *	Arrange for part or all of a canvas widget to redrawn at some
 *	convenient time in the future.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The screen will eventually be refreshed.
 *
 *--------------------------------------------------------------
 */

static void
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) ||
 	    (itemPtr->x2 < canvasPtr->xOrigin) ||
	    (itemPtr->y2 < canvasPtr->yOrigin) ||
	    (itemPtr->x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) ||
	    (itemPtr->y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) {
	if (!(itemPtr->typePtr->alwaysRedraw & 1)) {
	    return;
	}
    }
    if (!(itemPtr->redraw_flags & FORCE_REDRAW)) {
	if (canvasPtr->flags & BBOX_NOT_EMPTY) {
	    if (itemPtr->x1 <= canvasPtr->redrawX1) {
		canvasPtr->redrawX1 = itemPtr->x1;
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
	    canvasPtr->redrawX2 = itemPtr->x2;
	    canvasPtr->redrawY2 = itemPtr->y2;
	    canvasPtr->flags |= BBOX_NOT_EMPTY;
	}
	itemPtr->redraw_flags |= FORCE_REDRAW;
    }
    if (!(canvasPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayCanvas, canvasPtr);
	canvasPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateItemType --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

void
Tk_CreateItemType(
    Tk_ItemType *typePtr)	/* Information about item type; storage must
				 * be statically allocated (must live
				 * forever). */







|





|















|







2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
	    canvasPtr->redrawX2 = itemPtr->x2;
	    canvasPtr->redrawY2 = itemPtr->y2;
	    canvasPtr->flags |= BBOX_NOT_EMPTY;
	}
	itemPtr->redraw_flags |= FORCE_REDRAW;
    }
    if (!(canvasPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
	canvasPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateItemType --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

void
Tk_CreateItemType(
    Tk_ItemType *typePtr)	/* Information about item type; storage must
				 * be statically allocated (must live
				 * forever). */
3607
3608
3609
3610
3611
3612
3613













































































































































































































3614
3615
3616
3617
3618
3619
3620
    tkOvalType.nextPtr = &tkBitmapType;
    tkBitmapType.nextPtr = &tkArcType;
    tkArcType.nextPtr = &tkWindowType;
    tkWindowType.nextPtr = NULL;
    Tcl_MutexUnlock(&typeListMutex);
}














































































































































































































/*
 *----------------------------------------------------------------------
 *
 * GetStaticUids --
 *
 *	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







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
    tkOvalType.nextPtr = &tkBitmapType;
    tkBitmapType.nextPtr = &tkArcType;
    tkArcType.nextPtr = &tkWindowType;
    tkWindowType.nextPtr = NULL;
    Tcl_MutexUnlock(&typeListMutex);
}

#ifdef USE_OLD_TAG_SEARCH
/*
 *--------------------------------------------------------------
 *
 * StartTagSearch --
 *
 *	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.
 *
 * 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.
 *
 *--------------------------------------------------------------
 */

static Tk_Item *
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;
    Tk_Uid *tagPtr;
    Tk_Uid uid;
    char *tag = Tcl_GetString(tagObj);
    int count;
    TkWindow *tkwin;
    TkDisplay *dispPtr;

    tkwin = (TkWindow *) canvasPtr->tkwin;
    dispPtr = tkwin->dispPtr;

    /*
     * Initialize the search.
     */

    searchPtr->canvasPtr = canvasPtr;
    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.
     */

    if (isdigit(UCHAR(*tag))) {
	char *end;
	Tcl_HashEntry *entryPtr;

	dispPtr->numIdSearches++;
	id = strtoul(tag, &end, 0);
	if (*end == 0) {
	    itemPtr = canvasPtr->hotPtr;
	    lastPtr = canvasPtr->hotPrevPtr;
	    if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL)
		    || (lastPtr->nextPtr != itemPtr)) {
		dispPtr->numSlowSearches++;
		entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id);
		if (entryPtr != NULL) {
		    itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
		    lastPtr = itemPtr->prevPtr;
		} else {
		    lastPtr = itemPtr = NULL;
		}
	    }
	    searchPtr->lastPtr = lastPtr;
	    searchPtr->searchOver = 1;
	    canvasPtr->hotPtr = itemPtr;
	    canvasPtr->hotPrevPtr = lastPtr;
	    return itemPtr;
	}
    }

    searchPtr->tag = uid = Tk_GetUid(tag);
    if (uid == Tk_GetUid("all")) {
	/*
	 * All items match.
	 */

	searchPtr->tag = NULL;
	searchPtr->lastPtr = NULL;
	searchPtr->currentPtr = canvasPtr->firstItemPtr;
	return canvasPtr->firstItemPtr;
    }

    /*
     * None of the above. Search for an item with a matching tag.
     */

    for (lastPtr = NULL, itemPtr = 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;
	    }
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}

/*
 *--------------------------------------------------------------
 *
 * NextItem --
 *
 *	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 function will
 *	return the next item.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static Tk_Item *
NextItem(
    TagSearch *searchPtr)	/* Record describing search in progress. */
{
    Tk_Item *itemPtr, *lastPtr;
    int count;
    Tk_Uid uid;
    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.
     */

    lastPtr = searchPtr->lastPtr;
    if (lastPtr == NULL) {
	itemPtr = searchPtr->canvasPtr->firstItemPtr;
    } else {
	itemPtr = lastPtr->nextPtr;
    }
    if ((itemPtr == NULL) || (searchPtr->searchOver)) {
	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).
	 */
    } else {
	lastPtr = itemPtr;
	itemPtr = lastPtr->nextPtr;
    }

    /*
     * Handle special case of "all" search by returning next item.
     */

    uid = searchPtr->tag;
    if (uid == NULL) {
	searchPtr->lastPtr = lastPtr;
	searchPtr->currentPtr = itemPtr;
	return itemPtr;
    }

    /*
     * Look for an item with a particular tag.
     */

    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;
}

#else /* !USE_OLD_TAG_SEARCH */
/*
 *----------------------------------------------------------------------
 *
 * GetStaticUids --
 *
 *	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
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
 *--------------------------------------------------------------
 */

static void
TagSearchExprInit(
    TagSearchExpr **exprPtrPtr)
{
    TagSearchExpr *expr = *exprPtrPtr;

    if (expr == NULL) {
	expr = (TagSearchExpr *)ckalloc(sizeof(TagSearchExpr));
	expr->allocated = 0;
	expr->uids = NULL;
	expr->next = NULL;
    }
    expr->uid = NULL;
    expr->index = 0;
    expr->length = 0;







|

|
|







2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
 *--------------------------------------------------------------
 */

static void
TagSearchExprInit(
    TagSearchExpr **exprPtrPtr)
{
    TagSearchExpr* expr = *exprPtrPtr;

    if (! expr) {
	expr = (TagSearchExpr *) ckalloc(sizeof(TagSearchExpr));
	expr->allocated = 0;
	expr->uids = NULL;
	expr->next = NULL;
    }
    expr->uid = NULL;
    expr->index = 0;
    expr->length = 0;
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
 *--------------------------------------------------------------
 */

static void
TagSearchExprDestroy(
    TagSearchExpr *expr)
{
    if (expr != NULL) {
    	if (expr->uids) {
	    ckfree(expr->uids);
	}
	ckfree(expr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchScan --







|

|

|







2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
 *--------------------------------------------------------------
 */

static void
TagSearchExprDestroy(
    TagSearchExpr *expr)
{
    if (expr) {
    	if (expr->uids) {
	    ckfree((char *)expr->uids);
	}
	ckfree((char *)expr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchScan --
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
static int
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. */
{
    const char *tag = Tcl_GetString(tagObj);
    int i;
    TagSearch *searchPtr;

    /*
     * Initialize the search.
     */

    if (*searchPtrPtr != NULL) {
	searchPtr = *searchPtrPtr;
    } else {
	/*
	 * 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 = (char *)ckalloc(searchPtr->rewritebufferAllocated);
    }
    TagSearchExprInit(&searchPtr->expr);

    /*
     * How long is the tagOrId?
     */

    searchPtr->stringLength = strlen(tag);

    /*
     * Make sure there is enough buffer to hold rewritten tags.
     */

    if ((unsigned) searchPtr->stringLength >=
	    searchPtr->rewritebufferAllocated) {
	searchPtr->rewritebufferAllocated = searchPtr->stringLength + 100;
	searchPtr->rewritebuffer = (char *)
		ckrealloc(searchPtr->rewritebuffer,
		searchPtr->rewritebufferAllocated);
    }

    /*
     * Initialize search.
     */







|







|






|







|

|











|


|







3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
static int
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_GetString(tagObj);
    int i;
    TagSearch *searchPtr;

    /*
     * Initialize the search.
     */

    if (*searchPtrPtr) {
	searchPtr = *searchPtrPtr;
    } else {
	/*
	 * 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);
    }
    TagSearchExprInit(&(searchPtr->expr));

    /*
     * How long is the tagOrId?
     */

    searchPtr->stringLength = strlen(tag);

    /*
     * 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);
    }

    /*
     * Initialize search.
     */
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
    }

    /*
     * 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.
     */

    if (searchPtr->stringLength == 0) {
	return TCL_OK;
    }

    /*
     * 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] == '\\') {







<











|
|







3101
3102
3103
3104
3105
3106
3107

3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
    }

    /*
     * 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.
     */

    if (searchPtr->stringLength == 0) {
	return TCL_OK;
    }

    /*
     * 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] == '\\') {
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
 *	Deallocates memory.
 *
 *--------------------------------------------------------------
 */

static void
TagSearchDestroy(
    TagSearch *searchPtr)	/* Record describing tag search. */
{
    if (searchPtr) {
	TagSearchExprDestroy(searchPtr->expr);
	ckfree(searchPtr->rewritebuffer);
	ckfree(searchPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchScanExpr --







|



|
|







3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
 *	Deallocates memory.
 *
 *--------------------------------------------------------------
 */

static void
TagSearchDestroy(
    TagSearch *searchPtr)	/* Record describing tag search */
{
    if (searchPtr) {
	TagSearchExprDestroy(searchPtr->expr);
	ckfree((char *)searchPtr->rewritebuffer);
	ckfree((char *)searchPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchScanExpr --
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964

3965
3966
3967

3968
3969
3970
3971

3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
 *
 *--------------------------------------------------------------
 */

static int
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. */
    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++];

	/*
	 * 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(expr->uids,

			expr->allocated * sizeof(Tk_Uid));
	    } else {
		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_SetObjResult(interp, Tcl_NewStringObj(
			    "too many '!' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "COMPLEXITY", 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 (c == '"') {
			found_endquote = 1;
			break;
		    }
		    *tag++ = c;
		}
		if (!found_endquote) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "missing endquote in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "ENDQUOTE", NULL);
		    return TCL_ERROR;
		}
		if (!(tag - searchPtr->rewritebuffer)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "null quoted tag string in tag search expression",
			    -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "EMPTY", 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_SetObjResult(interp, Tcl_NewStringObj(
			"unexpected operator in tag search expression", -1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			"UNEXPECTED", 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;







|
|


|
|
|
|
|


















|
>
|

|
>




>

|





|

|
|
<
|






|


















|



















|
|
|
<
|


|
|
|
<
<
|









|



|
|
<
|


|







3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276

3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325

3326
3327
3328
3329
3330
3331


3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347

3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
 *
 *--------------------------------------------------------------
 */

static int
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 */
    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++];

	/*
	 * 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));
	    } else {
		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",

			    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 (c == '"') {
			found_endquote = 1;
			break;
		    }
		    *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;
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
		*++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_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '&' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", 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_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '|' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", 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_SetObjResult(interp, Tcl_NewStringObj(
			"invalid boolean operator in tag search expression",
			-1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "BAD_OP",
			NULL);
		return TCL_ERROR;
	    }
	}
    }

  breakwhile:
    if (found_tag && !looking_for_tag) {
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing tag in tag search expression", -1));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "NO_TAG", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchEvalExpr --







|

|





|


|
|
<
|






|


|
|
<
|






|




|



|
|
|
<
<







|


<
|
<







3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410

3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422

3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441


3442
3443
3444
3445
3446
3447
3448
3449
3450
3451

3452

3453
3454
3455
3456
3457
3458
3459
		*++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;
    }

    Tcl_AppendResult(interp, "Missing tag in tag search expression", NULL);

    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TagSearchEvalExpr --
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266




4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
    int count;
    int result;			/* Value of expr so far */
    int parendepth;
    SearchUids *searchUids;	/* Collection of uids for basic search
				 * expression terms. */

    searchUids = GetStaticUids();
    result = 0;			/* Just to keep the compiler quiet. */

    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) {
/*
 *		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 = (int)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);
 */
		uid = expr->uids[expr->index++];
		result = 0;

		/*
		 * set result 1 if tag is found in item's tags.
		 */

		for (tagPtr = itemPtr->tagPtr, count = (int)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);




	    }
	    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







|

















|
















|


|









|





|


|



>
>
>
>






|







3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
    int count;
    int result;			/* Value of expr so far */
    int parendepth;
    SearchUids *searchUids;	/* Collection of uids for basic search
				 * expression terms. */

    searchUids = GetStaticUids();
    result = 0;  /* just to keep the compiler quiet */

    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) {
/*
 *		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;
/*
 *		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);
/*
 *	    } else {
 *		assert(0);
 */
	    }
	    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
4308
4309
4310
4311
4312
4313
4314




4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
		 * If the previous result was 1 then negate the next result.
		 */

		negate_result = result;

	    } else if (uid == searchUids->endparenUid) {
		return result;




	    }
	    looking_for_tag = 1;
	}
    }
/*
 *  assert(!looking_for_tag);
 */
    return result;
}

/*
 *--------------------------------------------------------------
 *







>
>
>
>





|







3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
		 * If the previous result was 1 then negate the next result.
		 */

		negate_result = result;

	    } else if (uid == searchUids->endparenUid) {
		return result;
/*
 *	    } else {
 *		assert(0);
 */
	    }
	    looking_for_tag = 1;
	}
    }
/*
 *  assert(! looking_for_tag);
 */
    return result;
}

/*
 *--------------------------------------------------------------
 *
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
	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,
		    INT2PTR(searchPtr->id));
	    if (entryPtr != NULL) {
		itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
		lastPtr = itemPtr->prevPtr;
	    } else {
		lastPtr = itemPtr = NULL;
	    }
	}







|







3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
	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;
	    }
	}
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419

4420
4421
4422
4423
4424
4425
4426
    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 = (int)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.
	 */

	for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
		itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	    searchPtr->expr->index = 0;







|
|









>







3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
    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.
	 */

	for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
		itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	    searchPtr->expr->index = 0;
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
    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 = (int)itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }







|







3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
    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;
		}
	    }
4535
4536
4537
4538
4539
4540
4541

4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577

4578


4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597

4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
	    return itemPtr;
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}


/*
 *--------------------------------------------------------------
 *
 * DoItem --
 *
 *	This is a utility function called by FindItems. It either adds
 *	itemPtr's id to the list being constructed, 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 an element to the
 *	supplied object; otherwise tag is added to itemPtr's list of tags.
 *
 *--------------------------------------------------------------
 */

static void
DoItem(
    Tcl_Obj *accumObj,		/* Object 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;

    /*
     * Handle the "add-to-result" case and return, if appropriate.
     */

    if (tag == NULL) {

	Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewWideIntObj(itemPtr->id));


	return;
    }

    for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
	    count > 0; tagPtr++, count--) {
	if (tag == *tagPtr) {
	    return;
	}
    }

    /*
     * 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(itemPtr->tagSpace * sizeof(Tk_Uid));

	memcpy((void *) newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }

    /*
     * Add in the new tag.







>







|






|
|






|
|












>
|
>
>



|














|
>



|







3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
	    return itemPtr;
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}
#endif /* USE_OLD_TAG_SEARCH */

/*
 *--------------------------------------------------------------
 *
 * DoItem --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
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;

    /*
     * Handle the "add-to-result" case and return, if appropriate.
     */

    if (tag == NULL) {
	char msg[TCL_INTEGER_SPACE];

	sprintf(msg, "%d", itemPtr->id);
	Tcl_AppendElement(interp, msg);
	return;
    }

    for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
	    count > 0; tagPtr++, count--) {
	if (tag == *tagPtr) {
	    return;
	}
    }

    /*
     * 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, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree((char *) itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }

    /*
     * Add in the new tag.
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653

4654

4655
4656



4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668

static int
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. */

    ,TagSearch **searchPtrPtr	/* From CanvasWidgetCmd local vars*/

    )
{



    Tk_Item *itemPtr;
    Tk_Uid uid;
    int index, result;
    Tcl_Obj *resultObj;
    static const char *const optionStrings[] = {
	"above", "all", "below", "closest",
	"enclosed", "overlapping", "withtag", NULL
    };
    enum options {
	CANV_ABOVE, CANV_ALL, CANV_BELOW, CANV_CLOSEST,
	CANV_ENCLOSED, CANV_OVERLAPPING, CANV_WITHTAG
    };







|









>

>


>
>
>



<
|







3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961

3962
3963
3964
3965
3966
3967
3968
3969

static int
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*/
#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, result;

    static CONST char *optionStrings[] = {
	"above", "all", "below", "closest",
	"enclosed", "overlapping", "withtag", NULL
    };
    enum options {
	CANV_ABOVE, CANV_ALL, CANV_BELOW, CANV_CLOSEST,
	CANV_ENCLOSED, CANV_OVERLAPPING, CANV_WITHTAG
    };
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718

4719
4720
4721
4722

4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748

4749
4750
4751
4752
4753
4754
4755
	    return TCL_ERROR;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
		return TCL_ERROR) {
	    lastPtr = itemPtr;
	}
	if ((lastPtr != NULL) && (lastPtr->nextPtr != NULL)) {
	    resultObj = Tcl_NewObj();
	    DoItem(resultObj, lastPtr->nextPtr, uid);
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    }
    case CANV_ALL:
	if (objc != first+1) {
	    Tcl_WrongNumArgs(interp, first+1, objv, NULL);
	    return TCL_ERROR;
	}

	resultObj = Tcl_NewObj();
	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    DoItem(resultObj, itemPtr, uid);
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case CANV_BELOW:
	if (objc != first+2) {
	    Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId");
	    return TCL_ERROR;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
		return TCL_ERROR);

	if ((itemPtr != NULL) && (itemPtr->prevPtr != NULL)) {
	    resultObj = Tcl_NewObj();
	    DoItem(resultObj, itemPtr->prevPtr, uid);
	    Tcl_SetObjResult(interp, resultObj);

	}
	break;
    case CANV_CLOSEST: {
	double closestDist;
	Tk_Item *startPtr, *closestPtr;
	double coords[2], halo;
	int x1, y1, x2, y2;

	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,
		objv[first+1], &coords[0]) != TCL_OK
		|| Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
		objv[first+2], &coords[1]) != TCL_OK) {
	    return TCL_ERROR;
	}
	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_SetObjResult(interp, Tcl_ObjPrintf(
			"can't have negative halo value \"%f\"", halo));

		return TCL_ERROR;
	    }
	} else {
	    halo = 0.0;
	}

	/*







<
|
<









<


|

<









>
|
<
|
<
>












|
<
|
|



|
|



<
|
>







3986
3987
3988
3989
3990
3991
3992

3993

3994
3995
3996
3997
3998
3999
4000
4001
4002

4003
4004
4005
4006

4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017

4018

4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032

4033
4034
4035
4036
4037
4038
4039
4040
4041
4042

4043
4044
4045
4046
4047
4048
4049
4050
4051
	    return TCL_ERROR;
	}
	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 (objc != first+1) {
	    Tcl_WrongNumArgs(interp, first+1, objv, NULL);
	    return TCL_ERROR;
	}


	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    DoItem(interp, itemPtr, uid);
	}

	break;

    case CANV_BELOW:
	if (objc != first+2) {
	    Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId");
	    return TCL_ERROR;
	}
	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: {
	double closestDist;
	Tk_Item *startPtr, *closestPtr;
	double coords[2], halo;
	int x1, y1, x2, y2;

	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, objv[first+1],

		&coords[0]) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp,
		(Tk_Canvas) canvasPtr, objv[first+2], &coords[1]) != TCL_OK)) {
	    return TCL_ERROR;
	}
	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(objv[3]), "\"", NULL);
		return TCL_ERROR;
	    }
	} else {
	    halo = 0.0;
	}

	/*
4778
4779
4780
4781
4782
4783
4784



4785

4786
4787
4788
4789
4790
4791
4792
		(itemPtr->state == TK_STATE_NULL &&
		canvasPtr->canvas_state == TK_STATE_HIDDEN))) {
	    itemPtr = itemPtr->nextPtr;
	}
	if (itemPtr == NULL) {
	    return TCL_OK;
	}



	closestDist = ItemPoint(canvasPtr, itemPtr, coords, halo);

	while (1) {
	    double newDist;

	    /*
	     * Update the bounding box using itemPtr, which is the new closest
	     * item.
	     */







>
>
>
|
>







4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
		(itemPtr->state == TK_STATE_NULL &&
		canvasPtr->canvas_state == TK_STATE_HIDDEN))) {
	    itemPtr = itemPtr->nextPtr;
	}
	if (itemPtr == NULL) {
	    return TCL_OK;
	}
	closestDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr,
		itemPtr, coords) - halo;
	if (closestDist < 0.0) {
	    closestDist = 0.0;
	}
	while (1) {
	    double newDist;

	    /*
	     * Update the bounding box using itemPtr, which is the new closest
	     * item.
	     */
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825



4826

4827
4828
4829
4830
4831
4832
4833

	    while (1) {
		itemPtr = itemPtr->nextPtr;
		if (itemPtr == NULL) {
		    itemPtr = canvasPtr->firstItemPtr;
		}
		if (itemPtr == startPtr) {
		    resultObj = Tcl_NewObj();
		    DoItem(resultObj, closestPtr, uid);
		    Tcl_SetObjResult(interp, resultObj);
		    return TCL_OK;
		}
		if (itemPtr->state == TK_STATE_HIDDEN ||
			(itemPtr->state == TK_STATE_NULL &&
			canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
		    continue;
		}
		if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1)
			|| (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) {
		    continue;
		}



		newDist = ItemPoint(canvasPtr, itemPtr, coords, halo);

		if (newDist <= closestDist) {
		    closestDist = newDist;
		    break;
		}
	    }
	}
	break;







<
|
<











>
>
>
|
>







4105
4106
4107
4108
4109
4110
4111

4112

4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135

	    while (1) {
		itemPtr = itemPtr->nextPtr;
		if (itemPtr == NULL) {
		    itemPtr = canvasPtr->firstItemPtr;
		}
		if (itemPtr == startPtr) {

		    DoItem(interp, closestPtr, uid);

		    return TCL_OK;
		}
		if (itemPtr->state == TK_STATE_HIDDEN ||
			(itemPtr->state == TK_STATE_NULL &&
			canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
		    continue;
		}
		if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1)
			|| (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) {
		    continue;
		}
		newDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr,
			itemPtr, coords) - halo;
		if (newDist < 0.0) {
		    newDist = 0.0;
		}
		if (newDist <= closestDist) {
		    closestDist = newDist;
		    break;
		}
	    }
	}
	break;
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
	}
	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;
	}
	resultObj = Tcl_NewObj();
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
		goto badWithTagSearch) {
	    DoItem(resultObj, itemPtr, uid);
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    badWithTagSearch:
	Tcl_DecrRefCount(resultObj);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *







<

|
|

<
<
<
<
<







4147
4148
4149
4150
4151
4152
4153

4154
4155
4156
4157





4158
4159
4160
4161
4162
4163
4164
	}
	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;
	}

	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
		return TCL_ERROR) {
	    DoItem(interp, itemPtr, uid);
	}





    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945

4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
 */

static int
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;
    Tcl_Obj *resultObj;

    if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[0],
		&rect[0]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[1],
		&rect[1]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[2],
		&rect[2]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[3],
		&rect[3]) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (rect[0] > rect[2]) {
	tmp = rect[0]; rect[0] = rect[2]; rect[2] = tmp;
    }
    if (rect[1] > rect[3]) {
	tmp = rect[1]; rect[1] = rect[3]; rect[3] = tmp;
    }

    /*
     * 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);
    y1 = (int) (rect[1] - 1.0);
    x2 = (int) (rect[2] + 1.0);
    y2 = (int) (rect[3] + 1.0);
    resultObj = Tcl_NewObj();
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if (itemPtr->state == TK_STATE_HIDDEN ||
		(itemPtr->state == TK_STATE_NULL
		&& canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
	    continue;
	}
	if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1)
		|| (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) {
	    continue;
	}

	if (ItemOverlap(canvasPtr, itemPtr, rect) >= enclosed) {
	    DoItem(resultObj, itemPtr, uid);
	}
    }
    Tcl_SetObjResult(interp, resultObj);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * RelinkItems --







|












<



|

|

|















|
|
|
|
<


|
<
|






>
|
|


<







4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201

4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228

4229
4230
4231

4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243

4244
4245
4246
4247
4248
4249
4250
 */

static int
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, objv[0],
		&rect[0]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[1],
		&rect[1]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[2],
		&rect[2]) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3],
		&rect[3]) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (rect[0] > rect[2]) {
	tmp = rect[0]; rect[0] = rect[2]; rect[2] = tmp;
    }
    if (rect[1] > rect[3]) {
	tmp = rect[1]; rect[1] = rect[3]; rect[3] = tmp;
    }

    /*
     * 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);
    y1 = (int) (rect[1]-1.0);
    x2 = (int) (rect[2]+1.0);
    y2 = (int) (rect[3]+1.0);

    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if (itemPtr->state == TK_STATE_HIDDEN || (itemPtr->state == TK_STATE_NULL &&

		canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
	    continue;
	}
	if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1)
		|| (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) {
	    continue;
	}
	if ((*itemPtr->typePtr->areaProc)((Tk_Canvas) canvasPtr, itemPtr, rect)
		>= enclosed) {
	    DoItem(interp, itemPtr, uid);
	}
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * RelinkItems --
4966
4967
4968
4969
4970
4971
4972










4973
4974
4975
4976
4977
4978
4979
4980
4981

4982
4983



4984
4985
4986
4987
4988
4989
4990
 *	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.
 *
 *--------------------------------------------------------------
 */











static int
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 */

{
    Tk_Item *itemPtr;



    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.







>
>
>
>
>
>
>
>
>
>









>


>
>
>







4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
 *	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(
    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(
    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 */
{
    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.
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034



5035

5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055

5056

5057
5058
5059
5060
5061
5062
5063
	    itemPtr->prevPtr = NULL;
	    firstMovePtr = itemPtr;
	} else {
	    itemPtr->prevPtr = lastMovePtr;
	    lastMovePtr->nextPtr = itemPtr;
	}
	lastMovePtr = itemPtr;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
    }

    /*
     * Insert the list of to-be-moved items back into the canvas's at the
     * desired position.
     */

    if (firstMovePtr == NULL) {



	return TCL_OK;

    }
    if (prevPtr == NULL) {
	if (canvasPtr->firstItemPtr != NULL) {
	    canvasPtr->firstItemPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = canvasPtr->firstItemPtr;
	canvasPtr->firstItemPtr = firstMovePtr;
    } else {
	if (prevPtr->nextPtr != NULL) {
	    prevPtr->nextPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = prevPtr->nextPtr;
	if (firstMovePtr != NULL) {
	    firstMovePtr->prevPtr = prevPtr;
	}
	prevPtr->nextPtr = firstMovePtr;
    }
    if (canvasPtr->lastItemPtr == prevPtr) {
	canvasPtr->lastItemPtr = lastMovePtr;
    }

    return TCL_OK;

}

/*
 *--------------------------------------------------------------
 *
 * CanvasBindProc --
 *







|









>
>
>

>




















>

>







4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
	    itemPtr->prevPtr = NULL;
	    firstMovePtr = itemPtr;
	} else {
	    itemPtr->prevPtr = lastMovePtr;
	    lastMovePtr->nextPtr = itemPtr;
	}
	lastMovePtr = itemPtr;
	EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
    }

    /*
     * 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;
#endif /* USE_OLD_TAG_SEARCH */
    }
    if (prevPtr == NULL) {
	if (canvasPtr->firstItemPtr != NULL) {
	    canvasPtr->firstItemPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = canvasPtr->firstItemPtr;
	canvasPtr->firstItemPtr = firstMovePtr;
    } else {
	if (prevPtr->nextPtr != NULL) {
	    prevPtr->nextPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = prevPtr->nextPtr;
	if (firstMovePtr != NULL) {
	    firstMovePtr->prevPtr = prevPtr;
	}
	prevPtr->nextPtr = firstMovePtr;
    }
    if (canvasPtr->lastItemPtr == prevPtr) {
	canvasPtr->lastItemPtr = lastMovePtr;
    }
#ifndef USE_OLD_TAG_SEARCH
    return TCL_OK;
#endif /* not USE_OLD_TAG_SEARCH */
}

/*
 *--------------------------------------------------------------
 *
 * CanvasBindProc --
 *
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092



5093
5094


5095












5096


5097
5098
5099
5100
5101
5102
5103
 */

static void
CanvasBindProc(
    ClientData clientData,	/* Pointer to canvas structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    unsigned mask;

    Tcl_Preserve(canvasPtr);

    /*
     * 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.
     */




    switch (eventPtr->type) {
    case ButtonPress:


    case ButtonRelease:












	mask = Tk_GetButtonMask(eventPtr->xbutton.button);



	/*
	 * 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).







|
<

|







>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>







4388
4389
4390
4391
4392
4393
4394
4395

4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
 */

static void
CanvasBindProc(
    ClientData clientData,	/* Pointer to canvas structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;


    Tcl_Preserve((ClientData) canvasPtr);

    /*
     * 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.
     */

    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;
	}

	/*
	 * 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).
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140

5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
	    canvasPtr->state = eventPtr->xbutton.state;
	    CanvasDoEvent(canvasPtr, eventPtr);
	    eventPtr->xbutton.state ^= mask;
	    canvasPtr->state = eventPtr->xbutton.state;
	    PickCurrentItem(canvasPtr, eventPtr);
	    eventPtr->xbutton.state ^= mask;
	}
	break;
    case EnterNotify:
    case LeaveNotify:
	canvasPtr->state = eventPtr->xcrossing.state;
	PickCurrentItem(canvasPtr, eventPtr);
	break;
    case MotionNotify:
	canvasPtr->state = eventPtr->xmotion.state;
	PickCurrentItem(canvasPtr, eventPtr);
	/* fallthrough */
    default:

	CanvasDoEvent(canvasPtr, eventPtr);
    }

    Tcl_Release(canvasPtr);
}

/*
 *--------------------------------------------------------------
 *
 * PickCurrentItem --
 *







|
|
|


|
|


<
<
>
|
|
|
|







4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469


4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
	    canvasPtr->state = eventPtr->xbutton.state;
	    CanvasDoEvent(canvasPtr, eventPtr);
	    eventPtr->xbutton.state ^= mask;
	    canvasPtr->state = eventPtr->xbutton.state;
	    PickCurrentItem(canvasPtr, eventPtr);
	    eventPtr->xbutton.state ^= mask;
	}
	goto done;
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	canvasPtr->state = eventPtr->xcrossing.state;
	PickCurrentItem(canvasPtr, eventPtr);
	goto done;
    } else if (eventPtr->type == MotionNotify) {
	canvasPtr->state = eventPtr->xmotion.state;
	PickCurrentItem(canvasPtr, eventPtr);


    }
    CanvasDoEvent(canvasPtr, eventPtr);

  done:
    Tcl_Release((ClientData) canvasPtr);
}

/*
 *--------------------------------------------------------------
 *
 * PickCurrentItem --
 *
5172
5173
5174
5175
5176
5177
5178
5179
5180

5181

5182
5183
5184
5185
5186
5187
5188
5189
5190

5191
5192
5193
5194
5195
5196
5197
    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];
    unsigned int buttonDown;
    Tk_Item *prevItemPtr;

    SearchUids *searchUids = GetStaticUids();


    /*
     * 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 & ALL_BUTTONS;


    /*
     * 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.







|

>

>








|
>







4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
    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;
    Tk_Item *prevItemPtr;
#ifndef USE_OLD_TAG_SEARCH
    SearchUids *searchUids = GetStaticUids();
#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.
     */

    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:
     *
     * 1. Event bindings: if the current item changes, fake events are
     *    generated to allow item-enter and item-leave bindings to trigger.
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
	    canvasPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
	    canvasPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
	    canvasPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
	    canvasPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
	    canvasPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    canvasPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    canvasPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    canvasPtr->pickEvent.xcrossing.same_screen =
		    eventPtr->xmotion.same_screen;
	    canvasPtr->pickEvent.xcrossing.focus = False;
	    canvasPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else {
	    canvasPtr->pickEvent = *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







|
|


|







4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
	    canvasPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
	    canvasPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
	    canvasPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
	    canvasPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
	    canvasPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    canvasPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    canvasPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    canvasPtr->pickEvent.xcrossing.same_screen
		    = eventPtr->xmotion.same_screen;
	    canvasPtr->pickEvent.xcrossing.focus = False;
	    canvasPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else  {
	    canvasPtr->pickEvent = *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
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
    } else {
	canvasPtr->newCurrentPtr = NULL;
    }

    if ((canvasPtr->newCurrentPtr == canvasPtr->currentItemPtr)
	    && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) {
	/*
	 * Nothing to do: the current item hasn't changed.
	 */

	return;
    }

    if (!buttonDown) {
	canvasPtr->flags &= ~LEFT_GRABBED_ITEM;







|







4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
    } else {
	canvasPtr->newCurrentPtr = NULL;
    }

    if ((canvasPtr->newCurrentPtr == canvasPtr->currentItemPtr)
	    && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) {
	/*
	 * Nothing to do:  the current item hasn't changed.
	 */

	return;
    }

    if (!buttonDown) {
	canvasPtr->flags &= ~LEFT_GRABBED_ITEM;
5295
5296
5297
5298
5299
5300
5301
5302



5303

5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336

5337

5338
5339
5340
5341



5342

5343
5344

5345


5346
5347
5348
5349
5350
5351
5352
5353

	/*
	 * 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 = (int)itemPtr->numTags-1; i >= 0; i--) {



		if (itemPtr->tagPtr[i] == searchUids->currentUid)

		    /* then */ {
                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;
		    break;
		}
	    }
	}

	/*
	 * 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) {
	canvasPtr->flags |= LEFT_GRABBED_ITEM;
	return;
    }

    /*
     * 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;
    canvasPtr->flags &= ~LEFT_GRABBED_ITEM;
    canvasPtr->currentItemPtr = canvasPtr->newCurrentPtr;
    if (prevItemPtr != NULL && prevItemPtr != canvasPtr->currentItemPtr &&
	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
	EventuallyRedrawItem(canvasPtr, prevItemPtr);

	ItemConfigure(canvasPtr, prevItemPtr, 0, NULL);

    }
    if (canvasPtr->currentItemPtr != NULL) {
	XEvent event;




	DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid);

	if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT
		&& prevItemPtr != canvasPtr->currentItemPtr)) {

	    ItemConfigure(canvasPtr, canvasPtr->currentItemPtr, 0, NULL);


	    EventuallyRedrawItem(canvasPtr, canvasPtr->currentItemPtr);
	}
	event = canvasPtr->pickEvent;
	event.type = EnterNotify;
	event.xcrossing.detail = NotifyAncestor;
	CanvasDoEvent(canvasPtr, &event);
    }
}







|
>
>
>

>

<
|
<












|















|
>
|
>




>
>
>

>
|
|
>
|
>
>
|







4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641

4642

4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697

	/*
	 * 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"))
#else /* USE_OLD_TAG_SEARCH */
		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.
	 */
    }
    if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr) && buttonDown) {
	canvasPtr->flags |= LEFT_GRABBED_ITEM;
	return;
    }

    /*
     * 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;
    canvasPtr->flags &= ~LEFT_GRABBED_ITEM;
    canvasPtr->currentItemPtr = canvasPtr->newCurrentPtr;
    if (prevItemPtr != NULL && prevItemPtr != canvasPtr->currentItemPtr &&
	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr, prevItemPtr);
	(*prevItemPtr->typePtr->configProc)(canvasPtr->interp,
		(Tk_Canvas) canvasPtr, prevItemPtr, 0, NULL,
		TK_CONFIG_ARGV_ONLY);
    }
    if (canvasPtr->currentItemPtr != NULL) {
	XEvent event;

#ifdef USE_OLD_TAG_SEARCH
	DoItem(NULL, canvasPtr->currentItemPtr, Tk_GetUid("current"));
#else /* USE_OLD_TAG_SEARCH */
	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, NULL,
		    TK_CONFIG_ARGV_ONLY);
	    EventuallyRedrawItem((Tk_Canvas) canvasPtr,
		    canvasPtr->currentItemPtr);
	}
	event = canvasPtr->pickEvent;
	event.type = EnterNotify;
	event.xcrossing.detail = NotifyAncestor;
	CanvasDoEvent(canvasPtr, &event);
    }
}
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402

5403
5404
5405
5406
5407
5408
5409
5410
    y1 = (int) (coords[1] - canvasPtr->closeEnough);
    x2 = (int) (coords[0] + canvasPtr->closeEnough);
    y2 = (int) (coords[1] + canvasPtr->closeEnough);

    bestPtr = NULL;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if (itemPtr->state == TK_STATE_HIDDEN ||
		itemPtr->state==TK_STATE_DISABLED ||
		(itemPtr->state == TK_STATE_NULL &&
		(canvasPtr->canvas_state == TK_STATE_HIDDEN ||
		canvasPtr->canvas_state == TK_STATE_DISABLED))) {
	    continue;
	}
	if ((itemPtr->x1 > x2) || (itemPtr->x2 < x1)
		|| (itemPtr->y1 > y2) || (itemPtr->y2 < y1)) {
	    continue;
	}

	if (ItemPoint(canvasPtr,itemPtr,coords,0) <= canvasPtr->closeEnough) {
	    bestPtr = itemPtr;
	}
    }
    return bestPtr;
}

/*







|
<
|
<







>
|







4729
4730
4731
4732
4733
4734
4735
4736

4737

4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
    y1 = (int) (coords[1] - canvasPtr->closeEnough);
    x2 = (int) (coords[0] + canvasPtr->closeEnough);
    y2 = (int) (coords[1] + canvasPtr->closeEnough);

    bestPtr = NULL;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = itemPtr->nextPtr) {
	if (itemPtr->state == TK_STATE_HIDDEN || itemPtr->state==TK_STATE_DISABLED ||

		(itemPtr->state == TK_STATE_NULL && (canvasPtr->canvas_state == TK_STATE_HIDDEN ||

		canvasPtr->canvas_state == TK_STATE_DISABLED))) {
	    continue;
	}
	if ((itemPtr->x1 > x2) || (itemPtr->x2 < x1)
		|| (itemPtr->y1 > y2) || (itemPtr->y2 < y1)) {
	    continue;
	}
	if ((*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr,
		itemPtr, coords) <= canvasPtr->closeEnough) {
	    bestPtr = itemPtr;
	}
    }
    return bestPtr;
}

/*
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439

5440
5441
5442

5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455










5456
5457
5458
5459
5460
5461
5462
static void
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
    void *staticObjects[NUM_STATIC];
    void **objectPtr;
    int numObjects, i;
    Tk_Item *itemPtr;

    TagSearchExpr *expr;
    int numExprs;
    SearchUids *searchUids = GetStaticUids();


    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;
    if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
	itemPtr = canvasPtr->textInfo.focusItemPtr;
    }
    if (itemPtr == NULL) {
	return;
    }











    /*
     * 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,
     * (c) the expressions that are true for the event's item's tags, and
     * (d) the tag "all".







|
|


>



>













>
>
>
>
>
>
>
>
>
>







4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
static void
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];
    ClientData *objectPtr;
    int numObjects, i;
    Tk_Item *itemPtr;
#ifndef USE_OLD_TAG_SEARCH
    TagSearchExpr *expr;
    int numExprs;
    SearchUids *searchUids = GetStaticUids();
#endif /* not USE_OLD_TAG_SEARCH */

    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;
    if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
	itemPtr = canvasPtr->textInfo.focusItemPtr;
    }
    if (itemPtr == NULL) {
	return;
    }

#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.
     */

    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:
     * (a) 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".
5477
5478
5479
5480
5481
5482
5483

5484
5485
5486

5487
5488



5489

5490
5491
5492
5493
5494

5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506

5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
	if (expr->match) {
	    numExprs++;
	}
	expr = expr->next;
    }

    numObjects = itemPtr->numTags + numExprs + 2;

    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {

	objectPtr = (void **)ckalloc(numObjects * sizeof(void *));
    }



    objectPtr[0] = (char *)searchUids->allUid;

    for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (char *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = itemPtr;


    /*
     * Copy uids of matching expressions into object array
     */

    i = itemPtr->numTags+2;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
    	if (expr->match) {
	    objectPtr[i++] = (int *) expr->uid;
	}
	expr = expr->next;
    }


    /*
     * Invoke the binding system, then free up the object array if it was
     * malloc-ed.
     */

    if (canvasPtr->tkwin != NULL) {
	Tk_BindEvent(canvasPtr->bindingTable, eventPtr, canvasPtr->tkwin,
		numObjects, objectPtr);
    }
    if (objectPtr != staticObjects) {
	ckfree(objectPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasBlinkProc --







>



>
|

>
>
>
|
>
|
|

|

>












>











|







4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
	if (expr->match) {
	    numExprs++;
	}
	expr = expr->next;
    }

    numObjects = itemPtr->numTags + numExprs + 2;
#endif /* not USE_OLD_TAG_SEARCH */
    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {
	objectPtr = (ClientData *) ckalloc((unsigned)
		(numObjects * sizeof(ClientData)));
    }
#ifdef USE_OLD_TAG_SEARCH
    objectPtr[0] = (ClientData) Tk_GetUid("all");
#else /* USE_OLD_TAG_SEARCH */
    objectPtr[0] = (ClientData) searchUids->allUid;
#endif /* USE_OLD_TAG_SEARCH */
    for (i = itemPtr->numTags-1; i >= 0; i--) {
	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
     */

    i = itemPtr->numTags+2;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
    	if (expr->match) {
	    objectPtr[i++] = (int *) expr->uid;
	}
	expr = expr->next;
    }
#endif /* not USE_OLD_TAG_SEARCH */

    /*
     * Invoke the binding system, then free up the object array if it was
     * malloc-ed.
     */

    if (canvasPtr->tkwin != NULL) {
	Tk_BindEvent(canvasPtr->bindingTable, eventPtr, canvasPtr->tkwin,
		numObjects, objectPtr);
    }
    if (objectPtr != staticObjects) {
	ckfree((char *) objectPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasBlinkProc --
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552

5553
5554
5555
5556

5557


5558

5559
5560
5561
5562
5563
5564
5565
 *----------------------------------------------------------------------
 */

static void
CanvasBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (!canvasPtr->textInfo.gotFocus || (canvasPtr->insertOffTime == 0)) {
	return;
    }
    if (canvasPtr->textInfo.cursorOn) {
	canvasPtr->textInfo.cursorOn = 0;
	canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		canvasPtr->insertOffTime, CanvasBlinkProc, canvasPtr);

    } else {
	canvasPtr->textInfo.cursorOn = 1;
	canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		canvasPtr->insertOnTime, CanvasBlinkProc, canvasPtr);

    }


    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.focusItemPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * CanvasFocusProc --
 *







|







|
>



|
>

>
>
|
>







4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
 *----------------------------------------------------------------------
 */

static void
CanvasBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;

    if (!canvasPtr->textInfo.gotFocus || (canvasPtr->insertOffTime == 0)) {
	return;
    }
    if (canvasPtr->textInfo.cursorOn) {
	canvasPtr->textInfo.cursorOn = 0;
	canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		canvasPtr->insertOffTime, CanvasBlinkProc,
		(ClientData) canvasPtr);
    } else {
	canvasPtr->textInfo.cursorOn = 1;
	canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		canvasPtr->insertOnTime, CanvasBlinkProc,
		(ClientData) canvasPtr);
    }
    if (canvasPtr->textInfo.focusItemPtr != NULL) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr,
		canvasPtr->textInfo.focusItemPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasFocusProc --
 *
5584
5585
5586
5587
5588
5589
5590
5591

5592
5593
5594
5595
5596
5597


5598

5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
{
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (gotFocus) {
	canvasPtr->textInfo.gotFocus = 1;
	canvasPtr->textInfo.cursorOn = 1;
	if (canvasPtr->insertOffTime != 0) {
	    canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    canvasPtr->insertOffTime, CanvasBlinkProc, canvasPtr);

	}
    } else {
	canvasPtr->textInfo.gotFocus = 0;
	canvasPtr->textInfo.cursorOn = 0;
	canvasPtr->insertBlinkHandler = NULL;
    }


    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.focusItemPtr);

    if (canvasPtr->highlightWidth > 0) {
	canvasPtr->flags |= REDRAW_BORDERS;
	if (!(canvasPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayCanvas, canvasPtr);
	    canvasPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------







|
>




|

>
>
|
>



|







4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
{
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (gotFocus) {
	canvasPtr->textInfo.gotFocus = 1;
	canvasPtr->textInfo.cursorOn = 1;
	if (canvasPtr->insertOffTime != 0) {
	    canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    canvasPtr->insertOffTime, CanvasBlinkProc,
		    (ClientData) canvasPtr);
	}
    } else {
	canvasPtr->textInfo.gotFocus = 0;
	canvasPtr->textInfo.cursorOn = 0;
	canvasPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
    }
    if (canvasPtr->textInfo.focusItemPtr != NULL) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr,
		canvasPtr->textInfo.focusItemPtr);
    }
    if (canvasPtr->highlightWidth > 0) {
	canvasPtr->flags |= REDRAW_BORDERS;
	if (!(canvasPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
	    canvasPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646

5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
 *----------------------------------------------------------------------
 */

static void
CanvasSelectTo(
    TkCanvas *canvasPtr,	/* Information about widget. */
    Tk_Item *itemPtr,		/* Item that is to hold selection. */
    TkSizeT index)			/* Index of element that is to become the
				 * "other" end of the selection. */
{
    TkSizeT oldFirst, oldLast;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*
     * Grab the selection if we don't own it already.
     */

    if (canvasPtr->textInfo.selItemPtr == NULL) {
	Tk_OwnSelection(canvasPtr->tkwin, XA_PRIMARY, CanvasLostSelection,
		canvasPtr);
    } else if (canvasPtr->textInfo.selItemPtr != itemPtr) {

	EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr);
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor + 1 <= index + 1) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = ((int)index < 0) ? TCL_INDEX_NONE : index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
	    || (canvasPtr->textInfo.selectLast != oldLast)
	    || (itemPtr != oldSelPtr)) {
	EventuallyRedrawItem(canvasPtr, itemPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * CanvasFetchSelection --







|


|












|

>
|







|



|





|







4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
 *----------------------------------------------------------------------
 */

static void
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;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*
     * Grab the selection if we don't own it already.
     */

    if (canvasPtr->textInfo.selItemPtr == NULL) {
	Tk_OwnSelection(canvasPtr->tkwin, XA_PRIMARY, CanvasLostSelection,
		(ClientData) canvasPtr);
    } else if (canvasPtr->textInfo.selItemPtr != itemPtr) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr,
		canvasPtr->textInfo.selItemPtr);
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor <= index) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
	    || (canvasPtr->textInfo.selectLast != oldLast)
	    || (itemPtr != oldSelPtr)) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * CanvasFetchSelection --
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701







5702
5703
5704
5705
5706
5707
5708
5709
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
CanvasFetchSelection(
    ClientData clientData,	/* Information about canvas widget. */
    TkSizeT offset,			/* Offset within selection of first character
				 * to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;








    return ItemSelection(canvasPtr, canvasPtr->textInfo.selItemPtr, offset,
	    buffer, maxBytes);
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasLostSelection --







|


|


|



|

>
>
>
>
>
>
>
|







5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
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;

    if (canvasPtr->textInfo.selItemPtr == NULL) {
	return -1;
    }
    if (canvasPtr->textInfo.selItemPtr->typePtr->selectionProc == NULL) {
	return -1;
    }
    return (*canvasPtr->textInfo.selItemPtr->typePtr->selectionProc)(
	    (Tk_Canvas) canvasPtr, canvasPtr->textInfo.selItemPtr, offset,
	    buffer, maxBytes);
}

/*
 *----------------------------------------------------------------------
 *
 * CanvasLostSelection --
5721
5722
5723
5724
5725
5726
5727
5728
5729


5730

5731
5732
5733
5734
5735
5736
5737
 *----------------------------------------------------------------------
 */

static void
CanvasLostSelection(
    ClientData clientData)	/* Information about entry widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;



    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr);

    canvasPtr->textInfo.selItemPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * GridAlign --







|

>
>
|
>







5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
 *----------------------------------------------------------------------
 */

static void
CanvasLostSelection(
    ClientData clientData)	/* Information about entry widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *) clientData;

    if (canvasPtr->textInfo.selItemPtr != NULL) {
	EventuallyRedrawItem((Tk_Canvas) canvasPtr,
		canvasPtr->textInfo.selItemPtr);
    }
    canvasPtr->textInfo.selItemPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * GridAlign --
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
    TkCanvas *canvasPtr)		/* Information about canvas. */
{
    int result;
    Tcl_Interp *interp;
    int xOrigin, yOrigin, inset, width, height;
    int scrollX1, scrollX2, scrollY1, scrollY2;
    char *xScrollCmd, *yScrollCmd;
    Tcl_DString buf;

    /*
     * Preserve the relevant values from the canvasPtr, because it might be
     * deleted as part of either of the two calls to Tcl_EvalEx below.
     */

    interp = canvasPtr->interp;
    Tcl_Preserve(interp);
    xScrollCmd = canvasPtr->xScrollCmd;
    if (xScrollCmd != NULL) {
	Tcl_Preserve(xScrollCmd);
    }
    yScrollCmd = canvasPtr->yScrollCmd;
    if (yScrollCmd != NULL) {
	Tcl_Preserve(yScrollCmd);
    }
    xOrigin = canvasPtr->xOrigin;
    yOrigin = canvasPtr->yOrigin;
    inset = canvasPtr->inset;
    width = Tk_Width(canvasPtr->tkwin);
    height = Tk_Height(canvasPtr->tkwin);
    scrollX1 = canvasPtr->scrollX1;
    scrollX2 = canvasPtr->scrollX2;
    scrollY1 = canvasPtr->scrollY1;
    scrollY2 = canvasPtr->scrollY2;
    canvasPtr->flags &= ~UPDATE_SCROLLBARS;
    if (canvasPtr->xScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
		xOrigin + width - inset, scrollX1, scrollX2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, xScrollCmd, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(xScrollCmd);
    }

    if (yScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
		yOrigin + height - inset, scrollY1, scrollY2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, yScrollCmd, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(yScrollCmd);
    }
    Tcl_Release(interp);
}

/*
 *--------------------------------------------------------------
 *
 * CanvasSetOrigin --
 *







<


|
|



|


|



|














<
<
<
<
|
<
|


|


|





<
<
<
<
|
<
|


|


|

|







5223
5224
5225
5226
5227
5228
5229

5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258




5259

5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271




5272

5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
    TkCanvas *canvasPtr)		/* Information about canvas. */
{
    int result;
    Tcl_Interp *interp;
    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 != NULL) {
	Tcl_Preserve((ClientData) xScrollCmd);
    }
    yScrollCmd = canvasPtr->yScrollCmd;
    if (yScrollCmd != NULL) {
	Tcl_Preserve((ClientData) yScrollCmd);
    }
    xOrigin = canvasPtr->xOrigin;
    yOrigin = canvasPtr->yOrigin;
    inset = canvasPtr->inset;
    width = Tk_Width(canvasPtr->tkwin);
    height = Tk_Height(canvasPtr->tkwin);
    scrollX1 = canvasPtr->scrollX1;
    scrollX2 = canvasPtr->scrollX2;
    scrollY1 = canvasPtr->scrollY1;
    scrollY2 = canvasPtr->scrollY2;
    canvasPtr->flags &= ~UPDATE_SCROLLBARS;
    if (canvasPtr->xScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
		xOrigin + width - inset, scrollX1, scrollX2);




	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);
    }

    if (yScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
		yOrigin + height - inset, scrollY1, scrollY2);




	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) interp);
}

/*
 *--------------------------------------------------------------
 *
 * CanvasSetOrigin --
 *
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
	}
    }

    /*
     * 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.
     */

    if ((canvasPtr->confine) && (canvasPtr->regionString != NULL)) {
	left = xOrigin + canvasPtr->inset - canvasPtr->scrollX1;
	right = canvasPtr->scrollX2
		- (xOrigin + Tk_Width(canvasPtr->tkwin) - canvasPtr->inset);
	top = yOrigin + canvasPtr->inset - canvasPtr->scrollY1;







|
|
|
|
|







5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
	}
    }

    /*
     * 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.
     */

    if ((canvasPtr->confine) && (canvasPtr->regionString != NULL)) {
	left = xOrigin + canvasPtr->inset - canvasPtr->scrollX1;
	right = canvasPtr->scrollX2
		- (xOrigin + Tk_Width(canvasPtr->tkwin) - canvasPtr->inset);
	top = yOrigin + canvasPtr->inset - canvasPtr->scrollY1;
6050
6051
6052
6053
6054
6055
6056

6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
 * Side effects:
 *	Memory is allocated for the objv array, which must be freed using
 *	ckfree() when no longer needed.
 *
 *----------------------------------------------------------------------
 */


static const char **
TkGetStringsFromObjs(
    int objc,
    Tcl_Obj *const objv[])
{
    int i;
    const char **argv;

    if (objc <= 0) {
	return NULL;
    }
    argv = (const char **)ckalloc((objc+1) * sizeof(char *));
    for (i = 0; i < objc; i++) {
	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[objc] = 0;
    return argv;
}








>
|


|

|
|
<



|







5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436

5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
 * Side effects:
 *	Memory is allocated for the objv array, which must be freed using
 *	ckfree() when no longer needed.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
static CONST char **
TkGetStringsFromObjs(
    int objc,
    Tcl_Obj *CONST objv[])
{
    register int i;
    CONST char **argv;

    if (objc <= 0) {
	return NULL;
    }
    argv = (CONST char **) ckalloc((objc+1) * sizeof(char *));
    for (i = 0; i < objc; i++) {
	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[objc] = 0;
    return argv;
}

6097
6098
6099
6100
6101
6102
6103
6104

6105
6106
6107
6108
6109
6110
6111
int
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, Canvas(canvas)->psInfo, colorPtr);

}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsFont --
 *







|
>







5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
int
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);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsFont --
 *
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
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, Canvas(canvas)->psInfo, tkfont);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsBitmap --
 *







|







5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
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);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsBitmap --
 *
6163
6164
6165
6166
6167
6168
6169
6170
6171

6172
6173
6174
6175
6176
6177
6178
				 * 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, Canvas(canvas)->tkwin,
	    Canvas(canvas)->psInfo, bitmap, startX, startY, width, height);

}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsStipple --
 *







|
|
>







5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
				 * 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,
	    width, height);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsStipple --
 *
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
int
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, Canvas(canvas)->tkwin,
	    Canvas(canvas)->psInfo, bitmap);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsY --
 *







|
|







5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
int
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);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsY --
 *
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237

double
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, Canvas(canvas)->psInfo);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsPath --
 *







|







5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611

double
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);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsPath --
 *
6253
6254
6255
6256
6257
6258
6259

6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
				 * 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, Canvas(canvas)->psInfo, coordPtr, numPoints);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
|









5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
				 * 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:
 */

Changes to generic/tkCanvas.h.

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
				 * 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. */
    unsigned int state;		/* Last known modifier state. Used to defer
				 * picking a new current object while buttons
				 * are down. */

    /*
     * Information used for managing scrollbars:
     */








|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
				 * 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:
     */

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    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. */
    TkSizeT 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. */

    /*







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    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. */
    Tcl_HashTable idTable;	/* Table of integer indices. */

    /*
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

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);
/*
 * Standard item types provided by Tk:
 */

MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;
MODULE_SCOPE Tk_ItemType tkOvalType, tkPolygonType;
MODULE_SCOPE Tk_ItemType tkRectangleType, tkTextType, tkWindowType;

/*
 * Convenience macro.
 */

#define Canvas(canvas) ((TkCanvas *) (canvas))

#endif /* _TKCANVAS */







|











<
<
<
<
<
<

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305






306

/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

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);
/*
 * Standard item types provided by Tk:
 */

MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;
MODULE_SCOPE Tk_ItemType tkOvalType, tkPolygonType;
MODULE_SCOPE Tk_ItemType tkRectangleType, tkTextType, tkWindowType;







#endif /* _TKCANVAS */

Changes to generic/tkClipboard.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "tkInt.h"
#include "tkSelect.h"

/*
 * Prototypes for functions used only in this file:
 */

static TkSizeT	ClipboardAppHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static TkSizeT	ClipboardHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static TkSizeT	ClipboardWindowHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		ClipboardLostSel(ClientData clientData);
static int		ClipboardGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *----------------------------------------------------------------------
 *
 * ClipboardHandler --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardHandler(
    ClientData clientData,	/* Information about data to fetch. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkClipboardTarget *targetPtr = (TkClipboardTarget *)clientData;
    TkClipboardBuffer *cbPtr;
    char *srcPtr, *destPtr;
    TkSizeT count = 0;
    TkSizeT scanned = 0;
    TkSizeT length, freeCount;

    /*
     * Skip to buffer containing offset byte
     */

    for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
	if (cbPtr == NULL) {







|
|
|
|
|
|


|




















|


|


|

|


|
|
|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "tkInt.h"
#include "tkSelect.h"

/*
 * Prototypes for functions used only in this file:
 */

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 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    TkClipboardTarget *targetPtr = (TkClipboardTarget*) clientData;
    TkClipboardBuffer *cbPtr;
    char *srcPtr, *destPtr;
    size_t count = 0;
    int scanned = 0;
    size_t length, freeCount;

    /*
     * Skip to buffer containing offset byte
     */

    for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
	if (cbPtr == NULL) {
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	cbPtr = cbPtr->nextPtr;
	if (cbPtr == NULL) {
	    break;
	}
	srcPtr = cbPtr->buffer;
	length = cbPtr->length;
    }
    return count;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardAppHandler --
 *







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	cbPtr = cbPtr->nextPtr;
	if (cbPtr == NULL) {
	    break;
	}
	srcPtr = cbPtr->buffer;
	length = cbPtr->length;
    }
    return (int)count;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardAppHandler --
 *
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardAppHandler(
    ClientData clientData,	/* Pointer to TkDisplay structure. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    TkSizeT length;
    const char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);

    if (length <= offset) {
	return 0;
    }
    length -= offset;
    if (length > maxBytes) {
	length = maxBytes;
    }
    memcpy(buffer, p, length);
    buffer[length] = 0;
    return length;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardWindowHandler --
 *







|


|


|

|
|
|



>
|


<
|




|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    TkDisplay *dispPtr = (TkDisplay *) clientData;
    size_t length;
    CONST char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);
    length -= offset;
    if (length <= 0) {
	return 0;
    }

    if (length > (size_t) maxBytes) {
	length = maxBytes;
    }
    memcpy(buffer, p, length);
    buffer[length] = 0;
    return (int)length;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardWindowHandler --
 *
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(TkSizeT),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(TkSizeT))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*







|

|
|


|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 *----------------------------------------------------------------------
 */

static void
ClipboardLostSel(
    ClientData clientData)	/* Pointer to TkDisplay structure. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;

    dispPtr->clipboardActive = 0;
}

/*
 *----------------------------------------------------------------------
 *







|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 *----------------------------------------------------------------------
 */

static void
ClipboardLostSel(
    ClientData clientData)	/* Pointer to TkDisplay structure. */
{
    TkDisplay *dispPtr = (TkDisplay*) clientData;

    dispPtr->clipboardActive = 0;
}

/*
 *----------------------------------------------------------------------
 *
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = nextTargetPtr) {
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = nextCbPtr) {
	    ckfree(cbPtr->buffer);
	    nextCbPtr = cbPtr->nextPtr;
	    ckfree(cbPtr);
	}
	nextTargetPtr = targetPtr->nextPtr;
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		targetPtr->type);
	ckfree(targetPtr);
    }
    dispPtr->clipTargetPtr = NULL;

    /*
     * Reclaim the clipboard selection if we lost it.
     */








|




|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = nextTargetPtr) {
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = nextCbPtr) {
	    ckfree(cbPtr->buffer);
	    nextCbPtr = cbPtr->nextPtr;
	    ckfree((char *) cbPtr);
	}
	nextTargetPtr = targetPtr->nextPtr;
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		targetPtr->type);
	ckfree((char *) targetPtr);
    }
    dispPtr->clipTargetPtr = NULL;

    /*
     * Reclaim the clipboard selection if we lost it.
     */

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
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. */
    const char *buffer)		/* NULL terminated string containing the data
				 * to be added to the clipboard. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;








|







321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
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
				 * to be added to the clipboard. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == type) {
	    break;
	}
    }
    if (targetPtr == NULL) {
	targetPtr = (TkClipboardTarget *)ckalloc(sizeof(TkClipboardTarget));
	targetPtr->type = type;
	targetPtr->format = format;
	targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL;
	targetPtr->nextPtr = dispPtr->clipTargetPtr;
	dispPtr->clipTargetPtr = targetPtr;
	Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		type, ClipboardHandler, targetPtr, format);
    } else if (targetPtr->format != format) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"format \"%s\" does not match current format \"%s\" for %s",
		Tk_GetAtomName(tkwin, format),
		Tk_GetAtomName(tkwin, targetPtr->format),
		Tk_GetAtomName(tkwin, type)));
	Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "FORMAT_MISMATCH", NULL);
	return TCL_ERROR;
    }

    /*
     * Append a new buffer to the buffer chain.
     */

    cbPtr = (TkClipboardBuffer *)ckalloc(sizeof(TkClipboardBuffer));
    cbPtr->nextPtr = NULL;
    if (targetPtr->lastBufferPtr != NULL) {
	targetPtr->lastBufferPtr->nextPtr = cbPtr;
    } else {
	targetPtr->firstBufferPtr = cbPtr;
    }
    targetPtr->lastBufferPtr = cbPtr;

    cbPtr->length = strlen(buffer);
    cbPtr->buffer = (char *)ckalloc(cbPtr->length + 1);
    strcpy(cbPtr->buffer, buffer);

    TkSelUpdateClipboard((TkWindow *) dispPtr->clipWindow, targetPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|






|

|
|
<
|
|
<







|









|


|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == type) {
	    break;
	}
    }
    if (targetPtr == NULL) {
	targetPtr = (TkClipboardTarget*) ckalloc(sizeof(TkClipboardTarget));
	targetPtr->type = type;
	targetPtr->format = format;
	targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL;
	targetPtr->nextPtr = dispPtr->clipTargetPtr;
	dispPtr->clipTargetPtr = targetPtr;
	Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		type, ClipboardHandler, (ClientData) targetPtr, format);
    } else if (targetPtr->format != format) {
	Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format),
		"\" does not match current format \"",

		Tk_GetAtomName(tkwin, targetPtr->format),"\" for ",
		Tk_GetAtomName(tkwin, type), NULL);

	return TCL_ERROR;
    }

    /*
     * Append a new buffer to the buffer chain.
     */

    cbPtr = (TkClipboardBuffer*) ckalloc(sizeof(TkClipboardBuffer));
    cbPtr->nextPtr = NULL;
    if (targetPtr->lastBufferPtr != NULL) {
	targetPtr->lastBufferPtr->nextPtr = cbPtr;
    } else {
	targetPtr->firstBufferPtr = cbPtr;
    }
    targetPtr->lastBufferPtr = cbPtr;

    cbPtr->length = strlen(buffer);
    cbPtr->buffer = (char *) ckalloc((unsigned) (cbPtr->length + 1));
    strcpy(cbPtr->buffer, buffer);

    TkSelUpdateClipboard((TkWindow*)(dispPtr->clipWindow), targetPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
 */

int
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;
    const char *path = NULL;
    Atom selection;
    static const char *const optionStrings[] = { "append", "clear", "get", NULL };
    enum options { CLIPBOARD_APPEND, CLIPBOARD_CLEAR, CLIPBOARD_GET };
    int index, i;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case CLIPBOARD_APPEND: {
	Atom target, format;
	const char *targetName = NULL;
	const char *formatName = NULL;
	const char *string;
	static const char *const appendOptionStrings[] = {
	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex;
	TkSizeT length;

	for (i = 2; i < objc - 1; i++) {
	    string = TkGetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */







|

|
|

|




|











|
|
|
|



|
<


|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461
 */

int
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;
    Atom selection;
    static CONST char *optionStrings[] = { "append", "clear", "get", NULL };
    enum options { CLIPBOARD_APPEND, CLIPBOARD_CLEAR, CLIPBOARD_GET };
    int index, i;

    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 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.
	     */
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
	    /*
	     * Increment i so that it points to the value for the flag instead
	     * of the flag itself.
	     */

	    i++;
	    if (i >= objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "VALUE", 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;
	    }
	}
	if (objc - i != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...? data");
	    return TCL_ERROR;
	}
	if (path != NULL) {
	    tkwin = Tk_NameToWindow(interp, path, tkwin);
	}
	if (tkwin == NULL) {
	    return TCL_ERROR;







|
|
<















|







471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
	    /*
	     * 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;
	    }
	    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;
	    }
	}
	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;
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
	} else {
	    format = XA_STRING;
	}
	return Tk_ClipboardAppend(interp, tkwin, target, format,
		Tcl_GetString(objv[i]));
    }
    case CLIPBOARD_CLEAR: {
	static const char *const clearOptionStrings[] = { "-displayof", NULL };
	enum clearOptions { CLEAR_DISPLAYOF };
	int subIndex;

	if (objc != 2 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}







|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
	} 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;
	}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_ClipboardClear(interp, tkwin);
    }
    case CLIPBOARD_GET: {
	Atom target;
	const char *targetName = NULL;
	Tcl_DString selBytes;
	int result;
	const char *string;
	static const char *const 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_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "VALUE", 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 (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, "?-option value ...?");
	    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;







|


|
|
















|
|
<




















|







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
	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 (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", 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 (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;
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
 *	Sets up the clipWindow and related data structures.
 *
 *----------------------------------------------------------------------
 */

int
TkClipInit(
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter to use for error reporting. */
    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.
     */

    dispPtr->clipWindow = (Tk_Window) TkAllocWindow(dispPtr,
	DefaultScreen(dispPtr->display), NULL);
    Tcl_Preserve(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) {
	/*







|
|














|
|
<







628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
 *	Sets up the clipWindow and related data structures.
 *
 *----------------------------------------------------------------------
 */

int
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.
     */

    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) {
	/*
673
674
675
676
677
678
679
680

681
682

683
684
685
686
687
688
689
    /*
     * 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,
	    dispPtr->applicationAtom, ClipboardAppHandler, dispPtr,XA_STRING);

    Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
	    dispPtr->windowAtom, ClipboardWindowHandler, dispPtr, XA_STRING);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ClipboardGetProc --







|
>

|
>







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
    /*
     * 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,
	    dispPtr->applicationAtom, ClipboardAppHandler,
	    (ClientData) dispPtr, XA_STRING);
    Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
	    dispPtr->windowAtom, ClipboardWindowHandler,
	    (ClientData) dispPtr, XA_STRING);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ClipboardGetProc --
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
 * Side effects:
 *	Bytes get appended to the dynamic string pointed to by the clientData
 *	argument.
 *
 *--------------------------------------------------------------
 */


static int
ClipboardGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter used for error reporting (not
				 * used). */
    const 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:
 */







>




|

|

|










693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
 * Side effects:
 *	Bytes get appended to the dynamic string pointed to by the clientData
 *	argument.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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:
 */

Changes to generic/tkCmds.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if defined(_WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

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);
static int		AppnameCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		CaretCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		InactiveCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		ScalingCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		UseinputmethodsCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);
static int		WindowingsystemCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);

#if defined(_WIN32) || defined(MAC_OSX_TK)
MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
#else
#define tkFontchooserEnsemble NULL
#endif

/*
 * Table of tk subcommand names and implementations.
 */

static const TkEnsemble tkCmdMap[] = {
    {"appname",		AppnameCmd, NULL },
    {"busy",		Tk_BusyObjCmd, NULL },
    {"caret",		CaretCmd, NULL },
    {"inactive",	InactiveCmd, NULL },
    {"scaling",		ScalingCmd, NULL },
    {"useinputmethods",	UseinputmethodsCmd, NULL },
    {"windowingsystem",	WindowingsystemCmd, NULL },
    {"fontchooser",	NULL, tkFontchooserEnsemble},
    {NULL, NULL, NULL}
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_BellObjCmd --
 *
 *	This function is invoked to process the "bell" Tcl command. See the







|



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36




































37
38
39
40
41
42
43
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if defined(WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

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 function is invoked to process the "bell" Tcl command. See the
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
int
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 *const bellOptions[] = {
	"-displayof", "-nice", NULL
    };
    enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
    Tk_Window tkwin = (Tk_Window)clientData;
    int i, index, nice = 0;
    Tk_ErrorHandler handler;

    if (objc > 4) {
    wrongArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], bellOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum options) index) {
	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;
	}
    }
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL);
    XBell(Tk_Display(tkwin), 0);
    if (!nice) {
	XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
    }
    (void)XFlush(Tk_Display(tkwin));
    Tk_DeleteErrorHandler(handler);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BindObjCmd --







|



|

<








|
|

















<




|
<







55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99

100
101
102
103
104
105
106
int
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", 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;
    }

    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObj(interp, objv[i], bellOptions, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum options) index) {
	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);
    if (!nice) {
	XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
    }
    XFlush(Tk_Display(tkwin));

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BindObjCmd --
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
int
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;
    const 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
     * is a tag.
     */

    if (string[0] == '.') {
	winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	object = (ClientData) winPtr->pathName;
    } else {
	winPtr = (TkWindow *)clientData;
	object = (ClientData) Tk_GetUid(string);
    }

    /*
     * 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.
     */

    if (objc == 4) {
	int append = 0;
	unsigned long mask;

	const char *sequence = Tcl_GetString(objv[2]);
	const char *script = Tcl_GetString(objv[3]);

	/*
	 * If the script is null, just delete the binding.
	 */

	if (script[0] == 0) {
	    return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable,







|


|




















|













>
|
|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
int
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
     * is a tag.
     */

    if (string[0] == '.') {
	winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	object = (ClientData) winPtr->pathName;
    } else {
	winPtr = (TkWindow *) clientData;
	object = (ClientData) Tk_GetUid(string);
    }

    /*
     * 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.
     */

    if (objc == 4) {
	int append = 0;
	unsigned long mask;
	char *sequence, *script;
	sequence	= Tcl_GetString(objv[2]);
	script		= Tcl_GetString(objv[3]);

	/*
	 * If the script is null, just delete the binding.
	 */

	if (script[0] == 0) {
	    return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable,
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

	command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
		object, Tcl_GetString(objv[2]));
	if (command == NULL) {
	    Tcl_ResetResult(interp);
	    return TCL_OK;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
    } else {
	Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
    }
    return TCL_OK;
}

/*







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

	command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
		object, Tcl_GetString(objv[2]));
	if (command == NULL) {
	    Tcl_ResetResult(interp);
	    return TCL_OK;
	}
	Tcl_SetResult(interp, (char *) command, TCL_STATIC);
    } else {
	Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
    }
    return TCL_OK;
}

/*
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
    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.
	 */

	if (winPtr->numTags > MAX_OBJS) {

	    objPtr = (void **)ckalloc(winPtr->numTags * sizeof(void *));
	}
	for (i = 0; i < winPtr->numTags; i++) {
	    p = (const char *)winPtr->tagPtr[i];
	    if (*p == '.') {
		hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
		if (hPtr != NULL) {
		    p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
		} else {
		    p = NULL;
		}







>
|


|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    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.
	 */

	if (winPtr->numTags > MAX_OBJS) {
	    objPtr = (ClientData *) ckalloc((unsigned)
		    (winPtr->numTags * sizeof(ClientData)));
	}
	for (i = 0; i < winPtr->numTags; i++) {
	    p = winPtr->tagPtr[i];
	    if (*p == '.') {
		hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
		if (hPtr != NULL) {
		    p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
		} else {
		    p = NULL;
		}
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
	    count = 3;
	}
	objPtr[count-1] = (ClientData) Tk_GetUid("all");
    }
    Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
	    count, objPtr);
    if (objPtr != objects) {
	ckfree(objPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BindtagsObjCmd --







|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
	    count = 3;
	}
	objPtr[count-1] = (ClientData) Tk_GetUid("all");
    }
    Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
	    count, objPtr);
    if (objPtr != objects) {
	ckfree((char *) objPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BindtagsObjCmd --
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
int
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;
    const char *p;
    Tcl_Obj *listPtr, **tags;

    if ((objc < 2) || (objc > 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?taglist?");
	return TCL_ERROR;
    }
    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
	    tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	listPtr = Tcl_NewObj();
	if (winPtr->numTags == 0) {
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->pathName, -1));
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->classUid, -1));
	    winPtr2 = winPtr;
	    while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) {
		winPtr2 = winPtr2->parentPtr;
	    }
	    if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj(winPtr2->pathName, -1));
	    }
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj("all", -1));
	} else {
	    for (i = 0; i < winPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj((char *) winPtr->tagPtr[i], -1));
	    }
	}
	Tcl_SetObjResult(interp, listPtr);
	return TCL_OK;
    }
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    if (Tcl_ListObjGetElements(interp, objv[2], &length, &tags) != TCL_OK) {
	return TCL_ERROR;
    }
    if (length == 0) {
	return TCL_OK;
    }

    winPtr->numTags = length;

    winPtr->tagPtr = (void **)ckalloc(length * sizeof(void *));
    for (i = 0; i < length; i++) {
	p = Tcl_GetString(tags[i]);
	if (p[0] == '.') {
	    char *copy;

	    /*
	     * 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.
	     */

	    copy = (char *)ckalloc(strlen(p) + 1);
	    strcpy(copy, p);
	    winPtr->tagPtr[i] = (ClientData) copy;
	} else {
	    winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p);
	}
    }
    return TCL_OK;







|


|














|

|






|


|



|
|
















>
|












|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
int
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;
    }
    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
	    tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	listPtr = Tcl_NewObj();
	if (winPtr->numTags == 0) {
	    Tcl_ListObjAppendElement(interp, listPtr,
		    Tcl_NewStringObj(winPtr->pathName, -1));
	    Tcl_ListObjAppendElement(interp, listPtr,
		    Tcl_NewStringObj(winPtr->classUid, -1));
	    winPtr2 = winPtr;
	    while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) {
		winPtr2 = winPtr2->parentPtr;
	    }
	    if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
		Tcl_ListObjAppendElement(interp, listPtr,
			Tcl_NewStringObj(winPtr2->pathName, -1));
	    }
	    Tcl_ListObjAppendElement(interp, listPtr,
		    Tcl_NewStringObj("all", -1));
	} else {
	    for (i = 0; i < winPtr->numTags; i++) {
		Tcl_ListObjAppendElement(interp, listPtr,
			Tcl_NewStringObj((char *)winPtr->tagPtr[i], -1));
	    }
	}
	Tcl_SetObjResult(interp, listPtr);
	return TCL_OK;
    }
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    if (Tcl_ListObjGetElements(interp, objv[2], &length, &tags) != TCL_OK) {
	return TCL_ERROR;
    }
    if (length == 0) {
	return TCL_OK;
    }

    winPtr->numTags = length;
    winPtr->tagPtr = (ClientData *) ckalloc((unsigned)
	    (length * sizeof(ClientData)));
    for (i = 0; i < length; i++) {
	p = Tcl_GetString(tags[i]);
	if (p[0] == '.') {
	    char *copy;

	    /*
	     * 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.
	     */

	    copy = (char *) ckalloc((unsigned) (strlen(p) + 1));
	    strcpy(copy, p);
	    winPtr->tagPtr[i] = (ClientData) copy;
	} else {
	    winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p);
	}
    }
    return TCL_OK;
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
TkFreeBindingTags(
    TkWindow *winPtr)		/* Window whose tags are to be released. */
{
    int i;
    const char *p;

    for (i = 0; i < winPtr->numTags; i++) {
	p = (const char *)winPtr->tagPtr[i];
	if (*p == '.') {
	    /*
	     * Names starting with "." are malloced rather than Uids, so they
	     * have to be freed.
	     */

	    ckfree((char *)p);
	}
    }
    ckfree(winPtr->tagPtr);
    winPtr->numTags = 0;
    winPtr->tagPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *







|









|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
TkFreeBindingTags(
    TkWindow *winPtr)		/* Window whose tags are to be released. */
{
    int i;
    const char *p;

    for (i = 0; i < winPtr->numTags; i++) {
	p = winPtr->tagPtr[i];
	if (*p == '.') {
	    /*
	     * Names starting with "." are malloced rather than Uids, so they
	     * have to be freed.
	     */

	    ckfree((char *)p);
	}
    }
    ckfree((char *) winPtr->tagPtr);
    winPtr->numTags = 0;
    winPtr->tagPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
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;
    int i;

    for (i = 1; i < objc; i++) {
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
	if (window == NULL) {
	    Tcl_ResetResult(interp);
	    continue;







|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
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;
    int i;

    for (i = 1; i < objc; i++) {
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
	if (window == NULL) {
	    Tcl_ResetResult(interp);
	    continue;
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?belowThis?");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	other = NULL;
    } else {
	other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
	if (other == NULL) {
	    return TCL_ERROR;
	}
    }
    if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) {
	if (other) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't lower \"%s\" below \"%s\"",
		    Tcl_GetString(objv[1]), Tcl_GetString(objv[2])));
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't lower \"%s\" to bottom", Tcl_GetString(objv[1])));
	}
	Tcl_SetErrorCode(interp, "TK", "RESTACK", "LOWER", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







>







|




















<
<
<
|
<
<
|
<
|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522



523


524

525
526
527
528
529
530
531
532
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?belowThis?");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	other = NULL;
    } else {
	other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
	if (other == NULL) {
	    return TCL_ERROR;
	}
    }
    if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) {



	Tcl_AppendResult(interp, "can't lower \"", Tcl_GetString(objv[1]),


		"\" below \"", (other ? Tcl_GetString(objv[2]) : ""),

		"\"", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683

684






















685
686
687
688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866

867
868
869
870
871
872
873
874
875





876
877
878
879
880
881
882

883
884
885
886
887

888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940

941
942
943
944
945



946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963



964
965
966
967
968
969
970
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?aboveThis?");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	other = NULL;
    } else {
	other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
	if (other == NULL) {
	    return TCL_ERROR;
	}
    }
    if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) {
	if (other) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't raise \"%s\" above \"%s\"",
		    Tcl_GetString(objv[1]), Tcl_GetString(objv[2])));
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't raise \"%s\" to top", Tcl_GetString(objv[1])));
	}
	Tcl_SetErrorCode(interp, "TK", "RESTACK", "RAISE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * TkInitTkCmd --
 *
 *	Set up the tk ensemble.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 * ----------------------------------------------------------------------
 */

int
TkInitTkCmd(
    Tcl_Interp *interp,
    ClientData clientData)
{
    TkMakeEnsemble(interp, "::", "tk", clientData, tkCmdMap);
#if defined(_WIN32) || defined(MAC_OSX_TK)
    TkInitFontchooser(interp, clientData);
#endif
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AppnameCmd, CaretCmd, ScalingCmd, UseinputmethodsCmd,
 * WindowingsystemCmd, InactiveCmd --
 *
 *	These functions are invoked to process the "tk" ensemble subcommands.
 *	See the user documentation for details on what they do.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
AppnameCmd(
    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;
    const char *string;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"appname not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "APPLICATION", NULL);

	return TCL_ERROR;
    }

    winPtr = (TkWindow *) tkwin;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?newName?");
	return TCL_ERROR;
    }
    if (objc == 2) {
	string = Tcl_GetString(objv[1]);
	winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, -1));
    return TCL_OK;
}

int
CaretCmd(
    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 index;
    Tcl_Obj *objPtr;
    TkCaret *caretPtr;
    Tk_Window window;
    static const char *const caretStrings[] = {
	"-x",	"-y", "-height", NULL
    };
    enum caretOptions {
	TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT
    };

    if ((objc < 2) || ((objc > 3) && !!(objc & 1))) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"window ?-x x? ?-y y? ?-height height?");
	return TCL_ERROR;
    }
    window = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tkwin);
    if (window == NULL) {
	return TCL_ERROR;
    }
    caretPtr = &(((TkWindow *) window)->dispPtr->caret);
    if (objc == 2) {
	/*
	 * Return all the current values
	 */

	objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-height", 7));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->height));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-x", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->x));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-y", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->y));
	Tcl_SetObjResult(interp, objPtr);
    } else if (objc == 3) {
	int value;

	/*
	 * Return the current value of the selected option
	 */

	if (Tcl_GetIndexFromObj(interp, objv[2], caretStrings,
		"caret option", 0, &index) != TCL_OK) {
	    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;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
    } else {
	int i, value, x = 0, y = 0, height = -1;

	for (i = 2; 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);
	}
	Tk_SetCaretPos(window, x, y, height);
    }
    return TCL_OK;
}

int
ScalingCmd(
    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;
    Screen *screenPtr;
    int skip, width, height;
    double d;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"scaling not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL);

	return TCL_ERROR;
    }

    skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    screenPtr = Tk_Screen(tkwin);
    if (objc - skip == 1) {
	d = 25.4 / 72;
	d *= WidthOfScreen(screenPtr);
	d /= WidthMMOfScreen(screenPtr);
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));
    } else if (objc - skip == 2) {
	if (Tcl_GetDoubleFromObj(interp, objv[1+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, 1, objv, "?-displayof window? ?factor?");

	return TCL_ERROR;
    }
    return TCL_OK;
}

int
UseinputmethodsCmd(
    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;
    TkDisplay *dispPtr;
    int skip;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"useinputmethods not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "INPUT_METHODS", NULL);

	return TCL_ERROR;
    }

    skip = TkGetDisplayOf(interp, objc-1, objv+1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if ((objc - skip) == 2) {






	int boolVal;

	if (Tcl_GetBooleanFromObj(interp, objv[1+skip],
		&boolVal) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (boolVal && (dispPtr->inputMethod != NULL)) {
	    dispPtr->flags |= TK_DISPLAY_USE_IM;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_USE_IM;
	}

    } else if ((objc - skip) != 1) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-displayof window? ?boolean?");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM));
    return TCL_OK;
}

int
WindowingsystemCmd(
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    const char *windowingsystem;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
#if defined(_WIN32)
    windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
    windowingsystem = "aqua";
#else
    windowingsystem = "x11";
#endif
    Tcl_SetObjResult(interp, Tcl_NewStringObj(windowingsystem, -1));
    return TCL_OK;
}

int
InactiveCmd(
    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 skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);

    if (skip < 0) {
	return TCL_ERROR;
    }
    if (objc - skip == 1) {
	Tcl_WideInt inactive;

	inactive = (Tcl_IsSafe(interp) ? -1 :
		Tk_GetUserInactiveTime(Tk_Display(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(inactive));

    } else if (objc - skip == 2) {
	const char *string;

	string = Tcl_GetString(objv[objc-1]);
	if (strcmp(string, "reset") != 0) {



	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad option \"%s\": must be reset", string));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
		    string, NULL);
	    return TCL_ERROR;
	}
	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "resetting the user inactivity timer "
		    "is not allowed in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "INACTIVITY_TIMER", NULL);
	    return TCL_ERROR;
	}
	Tk_ResetUserInactiveTime(Tk_Display(tkwin));
	Tcl_ResetResult(interp);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?reset?");
	return TCL_ERROR;



    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







>







|




















<
<
<
|
<
<
|
<
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
|

|
|











|





>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
|
|
<
>
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
|
|
|

|
|
|
<
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
<
<
<
<
<
<
<
<
|
|

|
|
|
<
>
|
|

|
|
|
|
|
|
>
>
>
>
>

|

|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|

|
|
|
|
|
|

|

|

|
|
|
|
<
<
<
<
<
<
<
<
|

|
|
|
|
|

|
|
|
>
|
|

|
|
>
>
>
|
<
<
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
>
>
>







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576



577


578

579
580
581
582
583




























584
585
586
587

588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656









657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739








740
741
742
743
744
745
746

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783








784
785
786
787
788
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845








846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866



867
868
869
870
871
872

873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?aboveThis?");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	other = NULL;
    } else {
	other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
	if (other == NULL) {
	    return TCL_ERROR;
	}
    }
    if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) {



	Tcl_AppendResult(interp, "can't raise \"", Tcl_GetString(objv[1]),


		"\" above \"", (other ? Tcl_GetString(objv[2]) : ""),

		"\"", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}





























/*
 *----------------------------------------------------------------------
 *

 * Tk_TkObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
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[] = {
	"appname",	"caret",	"scaling",	"useinputmethods",
	"windowingsystem",		"inactive",	NULL
    };
    enum options {
	TK_APPNAME,	TK_CARET,	TK_SCALING,	TK_USE_IM,
	TK_WINDOWINGSYSTEM,		TK_INACTIVE
    };

    tkwin = (Tk_Window) clientData;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case 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;

	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;
	}
	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;
	    }
	    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;
	    }
	    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);
	    }
	    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;
	}

	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;
	    }
	    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;
	}
	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;
	}

	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.
	     */

	    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;
	}
	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;
	}
#if defined(WIN32)
	windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
	windowingsystem = "aqua";
#else
	windowingsystem = "x11";
#endif
	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;
}

/*
 *----------------------------------------------------------------------
 *
978
979
980
981
982
983
984

985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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;
    int code = TCL_OK;
    static const char *const 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;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case TKWAIT_VARIABLE:
	if (Tcl_TraceVar2(interp, Tcl_GetString(objv[2]),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		WaitVariableProc, &done) != TCL_OK) {
	    return TCL_ERROR;
	}
	done = 0;
	while (!done) {
	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
		code = TCL_ERROR;
		break;
	    }
	    Tcl_DoOneEvent(0);
	}
	Tcl_UntraceVar2(interp, Tcl_GetString(objv[2]),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		WaitVariableProc, &done);
	break;

    case TKWAIT_VISIBILITY: {
	Tk_Window window;

	window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
	if (window == NULL) {
	    return TCL_ERROR;
	}
	Tk_CreateEventHandler(window,
		VisibilityChangeMask|StructureNotifyMask,
		WaitVisibilityProc, &done);
	done = 0;
	while (!done) {
	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
		code = TCL_ERROR;
		break;
	    }
	    Tcl_DoOneEvent(0);
	}
	if ((done != 0) && (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_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" was deleted before its visibility changed",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "WAIT", "PREMATURE", NULL);
	    return TCL_ERROR;
	}
	Tk_DeleteEventHandler(window,
		VisibilityChangeMask|StructureNotifyMask,
		WaitVisibilityProc, &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, &done);
	done = 0;
	while (!done) {
	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
		code = TCL_ERROR;
		break;
	    }
	    Tcl_DoOneEvent(0);
	}

	/*
	 * Note: normally there's no need to delete the event handler. It was
	 * deleted automatically when the window was destroyed; however, if
	 * the wait operation was canceled, we need to delete it.
	 */

	if (done == 0) {
	    Tk_DeleteEventHandler(window, StructureNotifyMask,
		    WaitWindowProc, &done);
	}
	break;
    }
    }

    /*
     * Clear out the interpreter's result, since it may have been set by event
     * handlers. This is skipped if an error occurred above, such as the wait
     * operation being canceled.
     */

    if (code == TCL_OK)
    Tcl_ResetResult(interp);

    return code;
}


static char *
WaitVariableProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),		/* Name of variable. */
    TCL_UNUSED(const char *),		/* Second part of variable name. */
    TCL_UNUSED(int))			/* Information about what happened. */
{
    int *donePtr = (int *)clientData;

    *donePtr = 1;
    return NULL;
}


static void
WaitVisibilityProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == VisibilityNotify) {
	*donePtr = 1;

    } else if (eventPtr->type == DestroyNotify) {
	*donePtr = 2;
    }
}

static void
WaitWindowProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event. */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == DestroyNotify) {
	*donePtr = 1;
    }
}

/*







>







|

<
|


















|
|
|




<
<
<
<


|
|
|











|


<
<
<
<


|






|
|
<
<




|











|


<
<
<
<




|
|
<


<
<
<
<






|
<


<

<
|


>



|
|
|
|

|





>





|



>
|









|







897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939




940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958




959
960
961
962
963
964
965
966
967
968
969


970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988




989
990
991
992
993
994

995
996




997
998
999
1000
1001
1002
1003

1004
1005

1006

1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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", NULL
    };
    enum options {
	TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW
    };

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    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_VISIBILITY: {
	Tk_Window window;

	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", 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.

     */


    Tcl_ResetResult(interp);

    return TCL_OK;
}

	/* ARGSUSED */
static char *
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 NULL;
}

	/*ARGSUSED*/
static void
WaitVisibilityProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
{
    int *donePtr = (int *) clientData;

    if (eventPtr->type == VisibilityNotify) {
	*donePtr = 1;
    }
    if (eventPtr->type == DestroyNotify) {
	*donePtr = 2;
    }
}

static void
WaitWindowProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event. */
{
    int *donePtr = (int *) clientData;

    if (eventPtr->type == DestroyNotify) {
	*donePtr = 1;
    }
}

/*
1163
1164
1165
1166
1167
1168
1169

1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
Tk_UpdateObjCmd(
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const updateOptions[] = {"idletasks", NULL};
    int flags, index;
    TkDisplay *dispPtr;
    int code = TCL_OK;

    if (objc == 1) {
	flags = TCL_DONT_WAIT;
    } else if (objc == 2) {
	if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;







>


|




|


<







1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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", NULL};
    int flags, index;
    TkDisplay *dispPtr;


    if (objc == 1) {
	flags = TCL_DONT_WAIT;
    } else if (objc == 2) {
	if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
     * 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) {
	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
		code = TCL_ERROR;
		break;
	    }
	}

	/*
	 * If event processing was canceled proceed no further.
	 */

	if (code == TCL_ERROR)
	    break;

	for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		dispPtr = dispPtr->nextPtr) {
	    XSync(dispPtr->display, False);
	}

	/*
	 * Check again if event processing has been canceled because the inner
	 * loop (above) may not have checked (i.e. no events were processed and
	 * the loop body was skipped).
	 */

	if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
	    code = TCL_ERROR;
	    break;
	}

	if (Tcl_DoOneEvent(flags) == 0) {
	    break;
	}
    }

    /*
     * Must clear the interpreter's result because event handlers could have
     * executed commands. This is skipped if an error occurred above, such as
     * the wait operation being canceled.
     */

    if (code == TCL_OK)
    Tcl_ResetResult(interp);

    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WinfoObjCmd --
 *







<
<
<
<
<
|
<
<
<
|
<
<
<




<
<
<
<
<
<
<
<
<
<
<
<







|
<


<

<
|







1098
1099
1100
1101
1102
1103
1104





1105



1106



1107
1108
1109
1110












1111
1112
1113
1114
1115
1116
1117
1118

1119
1120

1121

1122
1123
1124
1125
1126
1127
1128
1129
     * 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 */



	}



	for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		dispPtr = dispPtr->nextPtr) {
	    XSync(dispPtr->display, False);
	}












	if (Tcl_DoOneEvent(flags) == 0) {
	    break;
	}
    }

    /*
     * Must clear the interpreter's result because event handlers could have
     * executed commands.

     */


    Tcl_ResetResult(interp);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WinfoObjCmd --
 *
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
int
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, c_class, skip;
    const char *string;
    TkWindow *winPtr;
    Tk_Window tkwin = (Tk_Window)clientData;


    static const TkStateMap visualMap[] = {
	{PseudoColor,	"pseudocolor"},
	{GrayScale,	"grayscale"},
	{DirectColor,	"directcolor"},
	{TrueColor,	"truecolor"},
	{StaticColor,	"staticcolor"},
	{StaticGray,	"staticgray"},
	{-1,		NULL}
    };
    static const char *const optionStrings[] = {
	"cells",	"children",	"class",	"colormapfull",
	"depth",	"geometry",	"height",	"id",
	"ismapped",	"manager",	"name",		"parent",
	"pointerx",	"pointery",	"pointerxy",	"reqheight",
	"reqwidth",	"rootx",	"rooty",	"screen",
	"screencells",	"screendepth",	"screenheight",	"screenwidth",
	"screenmmheight","screenmmwidth","screenvisual","server",







|
|

|
>










|







1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
int
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;
    TkWindow *winPtr;
    Tk_Window tkwin;
    Tcl_Obj *resultPtr;

    static const TkStateMap visualMap[] = {
	{PseudoColor,	"pseudocolor"},
	{GrayScale,	"grayscale"},
	{DirectColor,	"directcolor"},
	{TrueColor,	"truecolor"},
	{StaticColor,	"staticcolor"},
	{StaticGray,	"staticgray"},
	{-1,		NULL}
    };
    static const char *optionStrings[] = {
	"cells",	"children",	"class",	"colormapfull",
	"depth",	"geometry",	"height",	"id",
	"ismapped",	"manager",	"name",		"parent",
	"pointerx",	"pointery",	"pointerxy",	"reqheight",
	"reqwidth",	"rootx",	"rooty",	"screen",
	"screencells",	"screendepth",	"screenheight",	"screenwidth",
	"screenmmheight","screenmmwidth","screenvisual","server",
1321
1322
1323
1324
1325
1326
1327


1328
1329
1330
1331
1332
1333
1334
	WIN_ATOM,	WIN_ATOMNAME,	WIN_CONTAINING,	WIN_INTERPS,
	WIN_PATHNAME,

	WIN_EXISTS,	WIN_FPIXELS,	WIN_PIXELS,	WIN_RGB,
	WIN_VISUALSAVAILABLE
    };



    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;







>
>







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
	WIN_ATOM,	WIN_ATOMNAME,	WIN_CONTAINING,	WIN_INTERPS,
	WIN_PATHNAME,

	WIN_EXISTS,	WIN_FPIXELS,	WIN_PIXELS,	WIN_RGB,
	WIN_VISUALSAVAILABLE
    };

    tkwin = (Tk_Window) clientData;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
1342
1343
1344
1345
1346
1347
1348

1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

1379

1380

1381

1382
1383
1384
1385
1386
1387
1388
1389





1390

1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
	string = Tcl_GetString(objv[2]);
	tkwin = Tk_NameToWindow(interp, string, tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
    }
    winPtr = (TkWindow *) tkwin;


    switch ((enum options) index) {
    case WIN_CELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_Visual(tkwin)->map_entries));
	break;
    case WIN_CHILDREN: {
	Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj();

	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);
	    }
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case WIN_CLASS:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Class(tkwin), -1));
	break;
    case WIN_COLORMAPFULL:
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(TkpCmapStressed(tkwin,Tk_Colormap(tkwin))));
	break;
    case WIN_DEPTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Depth(tkwin)));
	break;
    case WIN_GEOMETRY:

	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d+%d+%d",

		Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin)));

	break;

    case WIN_HEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Height(tkwin)));
	break;
    case WIN_ID: {
	char buf[TCL_INTEGER_SPACE];

	Tk_MakeWindowExist(tkwin);
	TkpPrintWindowId(buf, Tk_WindowId(tkwin));





	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));

	break;
    }
    case WIN_ISMAPPED:
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tk_IsMapped(tkwin)));
	break;
    case WIN_MANAGER:
	if (winPtr->geomMgrPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->geomMgrPtr->name, -1));
	}
	break;
    case WIN_NAME:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Name(tkwin), -1));
	break;
    case WIN_PARENT:
	if (winPtr->parentPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->parentPtr->pathName, -1));
	}
	break;
    case WIN_POINTERX:
	useX = 1;
	useY = 0;
	goto pointerxy;
    case WIN_POINTERY:







>



<
|


|








<



|


|
|


|

|
>
|
>
|
>

>

|






>
>
>
>
>
|
>



|



<
|



|



<
|







1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241

1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291

1292
1293
1294
1295
1296
1297
1298
1299
	string = Tcl_GetString(objv[2]);
	tkwin = Tk_NameToWindow(interp, string, tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
    }
    winPtr = (TkWindow *) tkwin;
    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);
	    }
	}

	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];

	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:
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457

1458
1459

1460

1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523

1524

1525

1526

1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
	if (winPtr == NULL) {
	    x = -1;
	    y = -1;
	} else {
	    TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
	}
	if (useX & useY) {
	    Tcl_Obj *xyObj[2];

	    xyObj[0] = Tcl_NewWideIntObj(x);
	    xyObj[1] = Tcl_NewWideIntObj(y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, xyObj));
	} else if (useX) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	}
	break;
    case WIN_REQHEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqHeight(tkwin)));
	break;
    case WIN_REQWIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqWidth(tkwin)));
	break;
    case WIN_ROOTX:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	break;
    case WIN_ROOTY:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	break;
    case WIN_SCREEN:

	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s.%d",
		Tk_DisplayName(tkwin), Tk_ScreenNumber(tkwin)));

	break;

    case WIN_SCREENCELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(CellsOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENDEPTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENVISUAL:
	c_class = DefaultVisualOfScreen(Tk_Screen(tkwin))->c_class;
	goto visual;
    case WIN_SERVER:
	TkGetServerInfo(interp, tkwin);
	break;
    case WIN_TOPLEVEL:
	winPtr = GetTopHierarchy(tkwin);
	if (winPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->pathName, -1));
	}
	break;
    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;
	    }
	}

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(viewable));
	break;
    }
    case WIN_VISUAL:
	c_class = Tk_Visual(tkwin)->c_class;

    visual:
	string = TkFindStateString(visualMap, c_class);
	if (string == NULL) {
	    string = "unknown";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(string, -1));
	break;
    case WIN_VISUALID:

	Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned)

		XVisualIDFromVisual(Tk_Visual(tkwin))));

	break;

    case WIN_VROOTHEIGHT:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(height));
	break;
    case WIN_VROOTWIDTH:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(width));
	break;
    case WIN_VROOTX:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	break;
    case WIN_VROOTY:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	break;
    case WIN_WIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Width(tkwin)));
	break;
    case WIN_X:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_X(tkwin)));
	break;
    case WIN_Y:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Y(tkwin)));
	break;

	/*
	 * Uses -displayof.
	 */

    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_GetString(objv[2]);
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_InternAtom(tkwin, string)));
	break;
    case WIN_ATOMNAME: {
	const char *name;
	Tcl_WideInt 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_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	name = Tk_GetAtomName(tkwin, (Atom) id);
	if (strcmp(name, "?bad atom?") == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(

		    "no atom exists with id \"%s\"", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "ATOM",
		    Tcl_GetString(objv[2]), NULL);
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
	break;
    }
    case WIN_CONTAINING:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}







|

|
<
|

|

|



|


|



|



|

|
>
|
|
>

>

<
|


<
|


<
|


<
|


<
|


<
|


|







|















|



|


|



|

|
>
|
>
|
>

>


|



|



|



|


|


|


|

















<
|



|










|




|
>
|
<
<


|







1309
1310
1311
1312
1313
1314
1315
1316
1317
1318

1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347

1348
1349
1350

1351
1352
1353

1354
1355
1356

1357
1358
1359

1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451

1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474


1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
	if (winPtr == NULL) {
	    x = -1;
	    y = -1;
	} else {
	    TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
	}
	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);
	}
	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 (winPtr->flags & TK_TOP_HIERARCHY) {
		viewable = 1;
		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;
	}
	if (objc - skip != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
	    return TCL_ERROR;
	}
	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;
	}
	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_GetString(objv[2]);
	    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;
	}
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
	    return TCL_ERROR;
	}
	tkwin = Tk_CoordsToWindow(x, y, tkwin);
	if (tkwin != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1));
	}
	break;
    case WIN_INTERPS:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}







|







1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
	}
	string = Tcl_GetString(objv[3]);
	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:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683

1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699

1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717

1718

1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734

1735

1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760

1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780

1781

1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817



1818




















































































































































































































1819
1820
1821
1822
1823
1824
1825
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[2 + skip]);
	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_SetObjResult(interp, Tcl_ObjPrintf(
		    "window id \"%s\" doesn't exist in this application",
		    string));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", string, 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_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1));
	}
	break;
    }

	/*
	 * objv[3] is window.
	 */

    case WIN_EXISTS: {
	int alive;

	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);


	alive = 1;
	if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) {
	    alive = 0;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(alive));
	break;
    }
    case WIN_FPIXELS: {
	double mm, pixels;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window number");
	    return TCL_ERROR;
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {

	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetScreenMM(interp, tkwin, string, &mm) != TCL_OK) {
	    return TCL_ERROR;
	}
	pixels = mm * WidthOfScreen(Tk_Screen(tkwin))
		/ WidthMMOfScreen(Tk_Screen(tkwin));
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(pixels));
	break;
    }
    case WIN_PIXELS: {
	int pixels;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window number");
	    return TCL_ERROR;
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {

	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixels));
	break;
    }
    case WIN_RGB: {
	XColor *colorPtr;


	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
	    return TCL_ERROR;
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {

	    return TCL_ERROR;
	}
#ifdef TK_HAS_DYNAMIC_COLORS

	/*
	 * Make sure that the TkColor used for the winfo rgb command is
	 * destroyed when we are through with it, so we do not get stale RGB
	 * values next time.
	 */

	{
	    Colormap temp = Tk_Colormap(tkwin);
	    Tk_Colormap(tkwin) = TK_DYNAMIC_COLORMAP;
	    colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
	    Tk_Colormap(tkwin) = temp;
	}
#else
	colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
#endif
	if (colorPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d",
		colorPtr->red, colorPtr->green, colorPtr->blue));
	Tk_FreeColor(colorPtr);

	break;
    }
    case WIN_VISUALSAVAILABLE: {
	XVisualInfo templ, *visInfoPtr;
	int count, i;
	int includeVisualId;
	Tcl_Obj *strPtr, *resultPtr;
	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;
	}


	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {

	    return TCL_ERROR;
	}

	templ.screen = Tk_ScreenNumber(tkwin);
	visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
		&templ, &count);
	if (visInfoPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find any visuals for screen", -1));
	    Tcl_SetErrorCode(interp, "TK", "VISUAL", "NONE", NULL);
	    return TCL_ERROR;
	}
	resultPtr = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    string = TkFindStateString(visualMap, visInfoPtr[i].c_class);
	    if (string == NULL) {
		strcpy(buf, "unknown");
	    } else {
		sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
	    }
	    if (includeVisualId) {
		sprintf(visualIdString, " 0x%lx",
			(unsigned long) visInfoPtr[i].visualid);
		strcat(buf, visualIdString);
	    }
	    strPtr = Tcl_NewStringObj(buf, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
	Tcl_SetObjResult(interp, resultPtr);
	XFree((char *) visInfoPtr);
	break;
    }
    }
    return TCL_OK;
}

























































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TkGetDisplayOf --
 *
 *	Parses a "-displayof window" option for various commands. If present,
 *	the literal "-displayof" should be in objv[0] and the window name in







|


|
|
<
<











|


















>





|









>
|
>








|









>
|
>






|




>





>
|
>


<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<



|
|

>



|


|













>
|
>



|

|

|
|
<


<

|






|
|





<







>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533


1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625











1626



1627

1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666

1667
1668

1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683

1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[2 + skip]);
	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", 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;
    }

	/*
	 * objv[3] is window.
	 */

    case WIN_EXISTS: {
	int alive;

	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;
    }
    case WIN_FPIXELS: {
	double mm, pixels;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window number");
	    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_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;
    }
    case WIN_PIXELS: {
	int pixels;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window number");
	    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];

	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;
	}

	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);
	    }
	    if (includeVisualId) {
		sprintf(visualIdString, " 0x%x",
			(unsigned int) visInfoPtr[i].visualid);
		strcat(buf, visualIdString);
	    }
	    strPtr = Tcl_NewStringObj(buf, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}

	XFree((char *) visInfoPtr);
	break;
    }
    }
    return TCL_OK;
}

#if 0
/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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[] = {
	"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",	NULL
    };
    enum options {
	TKWM_ASPECT,	TKWM_CLIENT,	TKWM_COMMAND,	TKWM_DEICONIFY,
	TKWM_FOCUSMOD,	TKWM_FRAME,	TKWM_GEOMETRY,	TKWM_GRID,
	TKWM_GROUP,	TKWM_ICONBMP,	TKWM_ICONIFY,	TKWM_ICONMASK,
	TKWM_ICONNAME,	TKWM_ICONPOS,	TKWM_ICONWIN,	TKWM_MAXSIZE,
	TKWM_MINSIZE,	TKWM_OVERRIDE,	TKWM_POSFROM,	TKWM_PROTOCOL,
	TKWM_RESIZABLE,	TKWM_SIZEFROM,	TKWM_STATE,	TKWM_TITLE,
	TKWM_TRACING,	TKWM_TRANSIENT,	TKWM_WITHDRAW
    };

    tkwin = (Tk_Window) clientData;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (index == TKWM_TRACING) {
	int wmTracing;
	TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 1, objv, "tracing ?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_WM_TRACING));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (wmTracing) {
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?arg?");
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) Tk_NameToWindow(interp,
	    Tcl_GetString(objv[2]), tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" 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;
    }

  updateGeom:
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkGetDisplayOf --
 *
 *	Parses a "-displayof window" option for various commands. If present,
 *	the literal "-displayof" should be in objv[0] and the window name in
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903

1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
    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
				 * present. */
{
    const char *string;
    TkSizeT length;

    if (objc < 1) {
	return 0;
    }
    string = TkGetStringFromObj(objv[0], &length);
    if ((length >= 2) &&
	    (strncmp(string, "-displayof", length) == 0)) {
        if (objc < 2) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "value for \"-displayof\" missing", -1));
	    Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL);
	    return -1;
	}
	*tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr);
	if (*tkwinPtr == NULL) {
	    return -1;
	}
	return 2;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeadAppObjCmd --
 *
 *	If an application has been deleted then all Tk commands will be
 *	re-bound to this function.
 *
 * Results:
 *	A standard Tcl error is reported to let the user know that the
 *	application is dead.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
TkDeadAppObjCmd(
    TCL_UNUSED(void *),

    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't invoke \"%s\" command: application has been destroyed",
	    Tcl_GetString(objv[0])));
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetTopHierarchy --







|
|




|

|

|
|
<














|














>

|
<
>

|
|

|
|
<







1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990

1991
1992
1993
1994
1995
1996
1997

1998
1999
2000
2001
2002
2003
2004
    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
				 * present. */
{
    char *string;
    int length;

    if (objc < 1) {
	return 0;
    }
    string = Tcl_GetStringFromObj(objv[0], &length);
    if ((length >= 2) &&
	    (strncmp(string, "-displayof", (unsigned) length) == 0)) {
        if (objc < 2) {
	    Tcl_SetStringObj(Tcl_GetObjResult(interp),
		    "value for \"-displayof\" missing", -1);

	    return -1;
	}
	*tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr);
	if (*tkwinPtr == NULL) {
	    return -1;
	}
	return 2;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeadAppCmd --
 *
 *	If an application has been deleted then all Tk commands will be
 *	re-bound to this function.
 *
 * Results:
 *	A standard Tcl error is reported to let the user know that the
 *	application is dead.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetTopHierarchy --

Changes to generic/tkColor.c.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    Display *display;		/* Display for colormap. */
} ValueKey;

/*
 * The structure below is used to allocate thread-local data.
 */

typedef struct {
    char rgbString[20];		/* */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static void		ColorInit(TkDisplay *dispPtr);
static void		DupColorObjProc(Tcl_Obj *srcObjPtr,Tcl_Obj *dupObjPtr);
static void		FreeColorObj(Tcl_Obj *objPtr);
static void		FreeColorObjProc(Tcl_Obj *objPtr);
static void		InitColorObj(Tcl_Obj *objPtr);

/*
 * The following structure defines the implementation of the "color" Tcl
 * object, which maps a string color name to a TkColor object. The ptr1 field
 * of the Tcl_Obj points to a TkColor object.
 */

const Tcl_ObjType tkColorObjType = {
    "color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};








|










<









|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    Display *display;		/* Display for colormap. */
} ValueKey;

/*
 * The structure below is used to allocate thread-local data.
 */

typedef struct ThreadSpecificData {
    char rgbString[20];		/* */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

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
 * object, which maps a string color name to a TkColor object. The ptr1 field
 * of the Tcl_Obj points to a TkColor object.
 */

Tcl_ObjType tkColorObjType = {
    "color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    if (tkColPtr != NULL) {
	if (tkColPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkColor that's no
	     * longer in use. Clear the reference.
	     */

	    FreeColorObj(objPtr);
	    tkColPtr = NULL;
	} else if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    tkColPtr->resourceRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

    /*
     * The object didn't point to the TkColor that we wanted. Search the list
     * of TkColors with the same name to see if one of the other TkColors is
     * the right one.
     */

    if (tkColPtr != NULL) {
	TkColor *firstColorPtr = (TkColor *)Tcl_GetHashValue(tkColPtr->hashPtr);

	FreeColorObj(objPtr);
	for (tkColPtr = firstColorPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == tkColPtr->screen)
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		tkColPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
		return (XColor *) tkColPtr;
	    }
	}
    }

    /*
     * Still no luck. Call Tk_GetColor to allocate a new TkColor object.
     */

    tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
    return (XColor *) tkColPtr;
}

/*







|















|

|






|










|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    if (tkColPtr != NULL) {
	if (tkColPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkColor that's no
	     * longer in use. Clear the reference.
	     */

	    FreeColorObjProc(objPtr);
	    tkColPtr = NULL;
	} else if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    tkColPtr->resourceRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

    /*
     * The object didn't point to the TkColor that we wanted. Search the list
     * of TkColors with the same name to see if one of the other TkColors is
     * the right one.
     */

    if (tkColPtr != NULL) {
	TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr);

	FreeColorObjProc(objPtr);
	for (tkColPtr = firstColorPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == tkColPtr->screen)
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		tkColPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
		return (XColor *) tkColPtr;
	    }
	}
    }

    /*
     * Still no luck. Call Tk_GetColor to allocate a new TkColor object.
     */

    tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
    return (XColor *) tkColPtr;
}

/*
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

    /*
     * First, check to see if there's already a mapping for this color name.
     */

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew);
    if (!isNew) {
	existingColPtr = (TkColor *)Tcl_GetHashValue(nameHashPtr);
	for (tkColPtr = existingColPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((tkColPtr->screen == Tk_Screen(tkwin))
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		return &tkColPtr->color;
	    }
	}
    } else {
	existingColPtr = NULL;
    }

    /*
     * The name isn't currently known. Map from the name to a pixel value.
     */

    tkColPtr = TkpGetColor(tkwin, name);
    if (tkColPtr == NULL) {
	if (interp != NULL) {
	    if (*name == '#') {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"invalid color name \"%s\"", name));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL);
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown color name \"%s\"", name));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "COLOR", name, NULL);
	    }
	}
	if (isNew) {
	    Tcl_DeleteHashEntry(nameHashPtr);
	}
	return NULL;
    }







|




















<
|
|

<
|
|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228

229
230
231
232
233
234
235
236
237

    /*
     * First, check to see if there's already a mapping for this color name.
     */

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew);
    if (!isNew) {
	existingColPtr = Tcl_GetHashValue(nameHashPtr);
	for (tkColPtr = existingColPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((tkColPtr->screen == Tk_Screen(tkwin))
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		return &tkColPtr->color;
	    }
	}
    } else {
	existingColPtr = NULL;
    }

    /*
     * The name isn't currently known. Map from the name to a pixel value.
     */

    tkColPtr = TkpGetColor(tkwin, name);
    if (tkColPtr == NULL) {
	if (interp != NULL) {
	    if (*name == '#') {

		Tcl_AppendResult(interp, "invalid color name \"", name,
			"\"", NULL);
	    } else {

		Tcl_AppendResult(interp, "unknown color name \"", name,
			"\"", NULL);
	    }
	}
	if (isNew) {
	    Tcl_DeleteHashEntry(nameHashPtr);
	}
	return NULL;
    }
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
    valueKey.green = colorPtr->green;
    valueKey.blue = colorPtr->blue;
    valueKey.colormap = Tk_Colormap(tkwin);
    valueKey.display = display;
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable,
	    (char *) &valueKey, &isNew);
    if (!isNew) {
	tkColPtr = (TkColor *)Tcl_GetHashValue(valueHashPtr);
	tkColPtr->resourceRefCount++;
	return &tkColPtr->color;
    }

    /*
     * The name isn't currently known. Find a pixel value for this color and
     * add a new structure to colorValueTable (in TkDisplay).







|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    valueKey.green = colorPtr->green;
    valueKey.blue = colorPtr->blue;
    valueKey.colormap = Tk_Colormap(tkwin);
    valueKey.display = display;
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable,
	    (char *) &valueKey, &isNew);
    if (!isNew) {
	tkColPtr = Tcl_GetHashValue(valueHashPtr);
	tkColPtr->resourceRefCount++;
	return &tkColPtr->color;
    }

    /*
     * The name isn't currently known. Find a pixel value for this color and
     * add a new structure to colorValueTable (in TkDisplay).
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOfColor(
    XColor *colorPtr)		/* Color whose name is desired. */
{
    TkColor *tkColPtr = (TkColor *) colorPtr;

    if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);

	/*
	 * If the string has the form #RSRSTUTUVWVW (where equal letters
	 * denote equal hexdigits) then this is equivalent to #RSTUVW. Then
	 * output the shorter form.
	 */

	if ((tsdPtr->rgbString[1] == tsdPtr->rgbString[3])
		&& (tsdPtr->rgbString[2] == tsdPtr->rgbString[4])
		&& (tsdPtr->rgbString[5] == tsdPtr->rgbString[7])
		&& (tsdPtr->rgbString[6] == tsdPtr->rgbString[8])
		&& (tsdPtr->rgbString[9] == tsdPtr->rgbString[11])
		&& (tsdPtr->rgbString[10] == tsdPtr->rgbString[12])) {
	    tsdPtr->rgbString[3] = tsdPtr->rgbString[5];
	    tsdPtr->rgbString[4] = tsdPtr->rgbString[6];
	    tsdPtr->rgbString[5] = tsdPtr->rgbString[9];
	    tsdPtr->rgbString[6] = tsdPtr->rgbString[10];
	    tsdPtr->rgbString[7] = '\0';
	}
	return tsdPtr->rgbString;
    }
}

/*
 *----------------------------------------------------------------------
 *







|



|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372



















373
374
375
376
377
378
379
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
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) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);



















	return tsdPtr->rgbString;
    }
}

/*
 *----------------------------------------------------------------------
 *
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
     * Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	Tcl_Panic("Tk_FreeColor called with bogus color");
    }


    if (tkColPtr->resourceRefCount-- > 1) {
	return;
    }

    /*
     * This color is no longer being actively used, so free the color
     * resources associated with it and remove it from the hash table. No
     * longer any objects referencing it.
     */

    if (tkColPtr->gc != NULL) {
	XFreeGC(DisplayOfScreen(screen), tkColPtr->gc);
	tkColPtr->gc = NULL;
    }
    TkpFreeColor(tkColPtr);

    prevPtr = (TkColor *)Tcl_GetHashValue(tkColPtr->hashPtr);
    if (prevPtr == tkColPtr) {
	if (tkColPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(tkColPtr->hashPtr);
	} else {
	    Tcl_SetHashValue(tkColPtr->hashPtr, tkColPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != tkColPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = tkColPtr->nextPtr;
    }

    /*
     * Free the TkColor structure if there are no objects referencing it.
     * However, if there are objects referencing it then keep the structure
     * around; it will get freed when the last reference is cleared
     */

    if (tkColPtr->objRefCount == 0) {
	ckfree(tkColPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColorFromObj --







>
|















|




















|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
     * Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	Tcl_Panic("Tk_FreeColor called with bogus color");
    }

    tkColPtr->resourceRefCount--;
    if (tkColPtr->resourceRefCount > 0) {
	return;
    }

    /*
     * This color is no longer being actively used, so free the color
     * resources associated with it and remove it from the hash table. No
     * longer any objects referencing it.
     */

    if (tkColPtr->gc != NULL) {
	XFreeGC(DisplayOfScreen(screen), tkColPtr->gc);
	tkColPtr->gc = NULL;
    }
    TkpFreeColor(tkColPtr);

    prevPtr = Tcl_GetHashValue(tkColPtr->hashPtr);
    if (prevPtr == tkColPtr) {
	if (tkColPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(tkColPtr->hashPtr);
	} else {
	    Tcl_SetHashValue(tkColPtr->hashPtr, tkColPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != tkColPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = tkColPtr->nextPtr;
    }

    /*
     * Free the TkColor structure if there are no objects referencing it.
     * However, if there are objects referencing it then keep the structure
     * around; it will get freed when the last reference is cleared
     */

    if (tkColPtr->objRefCount == 0) {
	ckfree((char *) tkColPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColorFromObj --
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
void
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));
    FreeColorObj(objPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeColorObjProc, FreeColorObj --
 *
 *	This proc is called to release an object reference to a color. Called
 *	when the object's internal rep is released or when the cached tkColPtr
 *	needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeColorObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    FreeColorObj(objPtr);
    objPtr->typePtr = NULL;
}

static void
FreeColorObj(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    TkColor *tkColPtr = (TkColor *)objPtr->internalRep.twoPtrValue.ptr1;

    if (tkColPtr != NULL) {

	if ((tkColPtr->objRefCount-- <= 1)
		&& (tkColPtr->resourceRefCount == 0)) {
	    ckfree(tkColPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------







|





|



















<
<
<
<
<
<
<
<
|


>
|

|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556








557
558
559
560
561
562
563
564
565
566
567
568
569
570
void
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);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeColorObjProc --
 *
 *	This proc is called to release an object reference to a color. Called
 *	when the object's internal rep is released or when the cached tkColPtr
 *	needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeColorObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{








    TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount--;
	if ((tkColPtr->objRefCount == 0)
		&& (tkColPtr->resourceRefCount == 0)) {
	    ckfree((char *) tkColPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
 */

static void
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 = tkColPtr;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
}

/*







|


|







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
 */

static void
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;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
}

/*
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.
     */

    tkColPtr = (TkColor *)objPtr->internalRep.twoPtrValue.ptr1;
    if ((tkColPtr != NULL)
	    && (tkColPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == tkColPtr->screen)
	    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	/*
	 * The object already points to the right TkColor structure. Just
	 * return it.







|







635
636
637
638
639
640
641
642
643
644
645
646
647
648
649

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.
     */

    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
    if ((tkColPtr != NULL)
	    && (tkColPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == tkColPtr->screen)
	    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	/*
	 * The object already points to the right TkColor structure. Just
	 * return it.
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable,
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (tkColPtr = (TkColor *)Tcl_GetHashValue(hashPtr);
	    (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    FreeColorObj(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
	    tkColPtr->objRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

  error:
    Tcl_Panic("Tk_GetColorFromObj called with non-existent color!");







|



|
|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable,
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    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;
	    tkColPtr->objRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

  error:
    Tcl_Panic("Tk_GetColorFromObj called with non-existent color!");
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkColorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------







|







711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->typePtr = &tkColorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugColor(
    Tk_Window tkwin,		/* The window in which the color will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name);
    if (hashPtr != NULL) {
	TkColor *tkColPtr = (TkColor *)Tcl_GetHashValue(hashPtr);

	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef _WIN32

/* This function is not necessary for Win32,
 * since XParseColor already does the right thing */

#undef XParseColor

const char *const tkWebColors[20] = {
    /* 'a' */ "qua\0#0000ffffffff",
    /* 'b' */ NULL,
    /* 'c' */ "rimson\0#dcdc14143c3c",
    /* 'd' */ NULL,
    /* 'e' */ NULL,
    /* 'f' */ "uchsia\0#ffff0000ffff",
    /* 'g' */ "reen\0#000080800000",
    /* 'h' */ NULL,
    /* 'i' */ "ndigo\0#4b4b00008282",
    /* 'j' */ NULL,
    /* 'k' */ NULL,
    /* 'l' */ "ime\0#0000ffff0000",
    /* 'm' */ "aroon\0#808000000000",
    /* 'n' */ NULL,
    /* 'o' */ "live\0#808080800000",
    /* 'p' */ "urple\0#808000008080",
    /* 'q' */ NULL,
    /* 'r' */ NULL,
    /* 's' */ "ilver\0#c0c0c0c0c0c0",
    /* 't' */ "eal\0#000080808080"
};

Status







|








|








|

|






|






|






|





|


|







768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugColor(
    Tk_Window tkwin,		/* The window in which the color will be used
				 * (not currently used). */
    char *name)			/* Name of the desired color. */
{
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name);
    if (hashPtr != NULL) {
	TkColor *tkColPtr = Tcl_GetHashValue(hashPtr);

	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef __WIN32__

/* This function is not necessary for Win32,
 * since XParseColor already does the right thing */

#undef XParseColor

CONST char *CONST tkWebColors[20] = {
    /* 'a' */ "qua\0#0000ffffffff",
    /* 'b' */ NULL,
    /* 'c' */ "rimson\0#dcdc14143c3c",
    /* 'd' */ NULL,
    /* 'e' */ NULL,
    /* 'f' */ "uchsia\0#ffff0000ffff",
    /* 'g' */ NULL,
    /* 'h' */ NULL,
    /* 'i' */ "ndigo\0#4b4b00008282",
    /* 'j' */ NULL,
    /* 'k' */ NULL,
    /* 'l' */ "ime\0#0000ffff0000",
    /* 'm' */ NULL,
    /* 'n' */ NULL,
    /* 'o' */ "live\0#808080800000",
    /* 'p' */ NULL,
    /* 'q' */ NULL,
    /* 'r' */ NULL,
    /* 's' */ "ilver\0#c0c0c0c0c0c0",
    /* 't' */ "eal\0#000080808080"
};

Status
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
942
943
944
945
	    /* Not exactly 12 hex digits, so invalid */
	    return 0;
	} else {
	    name -= 13;
	}
	goto done;
    } else if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {
	if (!((name[0] - 'G') & 0xdf) && !((name[1] - 'R') & 0xdf)
		&& !((name[2] - 'A') & 0xdb) && !((name[3] - 'Y') & 0xdf)
		&& !name[4]) {
	    name = "#808080808080";
	    goto done;
	} else {
	    const char *p = tkWebColors[((*name - 'A') & 0x1f)];
	    if (p) {
		const char *q = name;
		while (!((*p - *(++q)) & 0xdf)) {
		    if (!*p++) {
			name = p;
			goto done;
		    }
		}
	    }
	}
    }
    if (strlen(name) > 99) {

	return 0;
    }
done:
    return XParseColor(display, map, name, color);
}
#endif /* _WIN32 */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
|
|
|
|
|
|
|
<





>





|







879
880
881
882
883
884
885






886
887
888
889
890
891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
	    /* Not exactly 12 hex digits, so invalid */
	    return 0;
	} else {
	    name -= 13;
	}
	goto done;
    } else if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {






	const char *p = tkWebColors[((*name - 'A') & 0x1f)];
	if (p) {
	    const char *q = name;
	    while (!((*p - *(++q)) & 0xdf)) {
		if (!*p++) {
		    name = p;
		    goto done;

		}
	    }
	}
    }
    if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return 0;
    }
done:
    return XParseColor(display, map, name, color);
}
#endif /* __WIN32__ */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkColor.h.

8
9
10
11
12
13
14
15





16
17
18
19
20
21
22
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR

#include "tkInt.h"






/*
 * 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.
 */








|
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR

#include <tkInt.h>

#ifdef BUILD_tk
#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.
 */

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
				 * color and all other fields defaulted. May
				 * be NULL. */
    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. */
    TkSizeT resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_AllocColorFromObj or Tk_GetColor). If
				 * this count is 0, then this TkColor
				 * structure is no longer valid and it isn't
				 * present in a hash table: it is being kept
				 * around only because there are objects
				 * referring to it. The structure is freed
				 * when resourceRefCount and objRefCount are
				 * both 0. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    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







|









|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
				 * color and all other fields defaulted. May
				 * be NULL. */
    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. */
    int resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_AllocColorFromObj or Tk_GetColor). If
				 * this count is 0, then this TkColor
				 * structure is no longer valid and it isn't
				 * present in a hash table: it is being kept
				 * around only because there are objects
				 * referring to it. The structure is freed
				 * when resourceRefCount and objRefCount are
				 * both 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    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
68
69
70
71
72
73
74



75

#ifndef TkpFreeColor
MODULE_SCOPE void	TkpFreeColor(TkColor *tkColPtr);
#endif
MODULE_SCOPE TkColor *	TkpGetColor(Tk_Window tkwin, Tk_Uid name);
MODULE_SCOPE TkColor *	TkpGetColorByValue(Tk_Window tkwin, XColor *colorPtr);




#endif /* _TKCOLOR */







>
>
>

73
74
75
76
77
78
79
80
81
82
83

#ifndef TkpFreeColor
MODULE_SCOPE void	TkpFreeColor(TkColor *tkColPtr);
#endif
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

#endif /* _TKCOLOR */

Changes to generic/tkConfig.c.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define __NO_OLD_CONFIG
#endif

#include "tkInt.h"
#include "tkFont.h"

/*
 * The following definition keeps track of all of
 * the option tables that have been created for a thread.
 */

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */
    Tcl_HashTable hashTable;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;


/*
 * 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







|
|


<
<
<
<
<
|







23
24
25
26
27
28
29
30
31
32
33





34
35
36
37
38
39
40
41
#define __NO_OLD_CONFIG
#endif

#include "tkInt.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.
 */






#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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    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
				 * original entry. */
	const struct Tk_ObjCustomOption *custom;
				/* For TK_OPTION_CUSTOM. */
    } extra;
    int flags;			/* Miscellaneous flag values; see below for
				 * definitions. */
} Option;

/*







|
|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    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. */
    } extra;
    int flags;			/* Miscellaneous flag values; see below for
				 * definitions. */
} Option;

/*
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

/*
 * One of the following exists for each Tk_OptionSpec array that has been
 * passed to Tk_CreateOptionTable.
 */

typedef struct OptionTable {
    size_t 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. */
    size_t 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 functions defined later in this file:
 */

static int		DoObjConfig(Tcl_Interp *interp, void *recordPtr,
			    Option *optionPtr, Tcl_Obj *valuePtr,
			    Tk_Window tkwin, Tk_SavedOption *savePtr);


static void		FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
			    void *internalPtr, Tk_Window tkwin);
static Tcl_Obj *	GetConfigList(void *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Tcl_Obj *	GetObjectForOption(void *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 void		FreeOptionInternalRep(Tcl_Obj *objPtr);
static void		DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *);

/*
 * 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.
 */

static const Tcl_ObjType optionObjType = {
    "option",			/* name */
    FreeOptionInternalRep,	/* freeIntRepProc */
    DupOptionInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateOptionTable --
 *







|











|











|


>
>

|
|

|





|
<








|

|
|

|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

/*
 * One of the following exists for each Tk_OptionSpec array that has been
 * passed to Tk_CreateOptionTable.
 */

typedef struct OptionTable {
    int refCount;		/* Counts the number of uses of this table
				 * (the number of times Tk_CreateOptionTable
				 * has returned it). This can be greater than
				 * 1 if it is shared along several option
				 * table chains, or if the same table is used
				 * for multiple purposes. */
    Tcl_HashEntry *hashEntryPtr;/* Hash table entry that refers to this table;
				 * used to delete the entry. */
    struct OptionTable *nextPtr;/* If templatePtr was part of a chain of
				 * templates, this points to the table
				 * corresponding to the next template in the
				 * chain. */
    int numOptions;		/* The number of items in the options array
				 * below. */
    Option options[1];		/* Information about the individual options in
				 * the table. This must be the last field in
				 * the structure: the actual size of the array
				 * will be numOptions, not 1. */
} OptionTable;

/*
 * Forward declarations for functions defined later in this file:
 */

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.
 */

Tcl_ObjType tkOptionObjType = {
    "option",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetOptionFromAny		/* setFromAnyProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateOptionTable --
 *
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191


192

193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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_HashEntry *hashEntryPtr;
    int newEntry;
    OptionTable *tablePtr;
    const Tk_OptionSpec *specPtr, *specPtr2;
    Option *optionPtr;
    size_t numOptions, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * We use an TSD in the thread to keep a hash table of
     * all the option tables we've created for this application. This is
     * used for allowing us to share the tables (e.g. in several chains).


     * The code below finds the hash table or creates a new one if it
     * doesn't already exist.
     */



    if (!tsdPtr->initialized) {

	Tcl_InitHashTable(&tsdPtr->hashTable, TCL_ONE_WORD_KEYS);

	tsdPtr->initialized = 1;
    }

    /*
     * See if a table has already been created for this template. If so, just
     * reuse the existing table.
     */

    hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->hashTable, (char *) templatePtr,
	    &newEntry);
    if (!newEntry) {
	tablePtr = (OptionTable *)Tcl_GetHashValue(hashEntryPtr);
	tablePtr->refCount++;
	return (Tk_OptionTable) tablePtr;
    }

    /*
     * Count the number of options in the template, then create the table
     * structure.
     */

    numOptions = 0;
    for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) {
	numOptions++;
    }

    tablePtr = (OptionTable *)ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option)));
    tablePtr->refCount = 1;
    tablePtr->hashEntryPtr = hashEntryPtr;
    tablePtr->nextPtr = NULL;
    tablePtr->numOptions = numOptions;

    /*
     * Initialize all of the Option structures in the table.
     */

    for (specPtr = templatePtr, optionPtr = tablePtr->options;
	    specPtr->type != TK_OPTION_END; specPtr++, optionPtr++) {
	optionPtr->specPtr = specPtr;
	optionPtr->dbNameUID = NULL;
	optionPtr->dbClassUID = NULL;
	optionPtr->defaultPtr = NULL;
	optionPtr->extra.monoColorPtr = NULL;
	optionPtr->flags = 0;

	if (specPtr->type == TK_OPTION_SYNONYM) {
	    /*
	     * This is a synonym option; find the original option that it refers
	     * to and create a pointer from the synonym to the origin.
	     */

	    for (specPtr2 = templatePtr, i = 0; ; specPtr2++, i++) {
		if (specPtr2->type == TK_OPTION_END) {
		    Tcl_Panic("Tk_CreateOptionTable couldn't find synonym");
		}
		if (strcmp(specPtr2->optionName,







>





|
<
<


|
|
|
>
>
|



>
>
|
>
|
>
|







|


|













>
|




















|
|







164
165
166
167
168
169
170
171
172
173
174
175
176
177


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
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;
    Option *optionPtr;
    int numOptions, i;



    /*
     * We use an AssocData value in the interpreter to keep a hash table of
     * all the option tables we've created for this application. This is used
     * for two purposes. First, it allows us to share the tables (e.g. in
     * several chains) and second, we use the deletion callback for the
     * AssocData to delete all the option tables when the interpreter is
     * deleted. The code below finds the hash table or creates a new one if it
     * doesn't already exist.
     */

    hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY,
	    NULL);
    if (hashTablePtr == NULL) {
	hashTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS);
	Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable,
		(ClientData) hashTablePtr);
    }

    /*
     * See if a table has already been created for this template. If so, just
     * reuse the existing table.
     */

    hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr,
	    &newEntry);
    if (!newEntry) {
	tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr);
	tablePtr->refCount++;
	return (Tk_OptionTable) tablePtr;
    }

    /*
     * Count the number of options in the template, then create the table
     * structure.
     */

    numOptions = 0;
    for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) {
	numOptions++;
    }
    tablePtr = (OptionTable *) (ckalloc(sizeof(OptionTable)
	    + (numOptions * sizeof(Option))));
    tablePtr->refCount = 1;
    tablePtr->hashEntryPtr = hashEntryPtr;
    tablePtr->nextPtr = NULL;
    tablePtr->numOptions = numOptions;

    /*
     * Initialize all of the Option structures in the table.
     */

    for (specPtr = templatePtr, optionPtr = tablePtr->options;
	    specPtr->type != TK_OPTION_END; specPtr++, optionPtr++) {
	optionPtr->specPtr = specPtr;
	optionPtr->dbNameUID = NULL;
	optionPtr->dbClassUID = NULL;
	optionPtr->defaultPtr = NULL;
	optionPtr->extra.monoColorPtr = NULL;
	optionPtr->flags = 0;

	if (specPtr->type == TK_OPTION_SYNONYM) {
	    /*
	     * This is a synonym option; find the master option that it refers
	     * to and create a pointer from the synonym to the master.
	     */

	    for (specPtr2 = templatePtr, i = 0; ; specPtr2++, i++) {
		if (specPtr2->type == TK_OPTION_END) {
		    Tcl_Panic("Tk_CreateOptionTable couldn't find synonym");
		}
		if (strcmp(specPtr2->optionName,
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
		optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue,-1);
		Tcl_IncrRefCount(optionPtr->defaultPtr);
	    }
	    if (((specPtr->type == TK_OPTION_COLOR)
		    || (specPtr->type == TK_OPTION_BORDER))
		    && (specPtr->clientData != NULL)) {
		optionPtr->extra.monoColorPtr =
			Tcl_NewStringObj((const char *)specPtr->clientData, -1);
		Tcl_IncrRefCount(optionPtr->extra.monoColorPtr);
	    }

	    if (specPtr->type == TK_OPTION_CUSTOM) {
		/*
		 * Get the custom parsing, etc., functions.
		 */

		optionPtr->extra.custom = (const Tk_ObjCustomOption *)specPtr->clientData;

	    }
	}
	if (((specPtr->type == TK_OPTION_STRING)
		&& (specPtr->internalOffset != TCL_INDEX_NONE))
		|| (specPtr->type == TK_OPTION_COLOR)
		|| (specPtr->type == TK_OPTION_FONT)
		|| (specPtr->type == TK_OPTION_BITMAP)
		|| (specPtr->type == TK_OPTION_BORDER)
		|| (specPtr->type == TK_OPTION_CURSOR)
		|| (specPtr->type == TK_OPTION_CUSTOM)) {
	    optionPtr->flags |= OPTION_NEEDS_FREEING;
	}
    }
    tablePtr->hashEntryPtr = hashEntryPtr;
    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).
     */

    if (specPtr->clientData != NULL) {
	tablePtr->nextPtr = (OptionTable *)
		Tk_CreateOptionTable(interp, (Tk_OptionSpec *)specPtr->clientData);
    }

    return (Tk_OptionTable) tablePtr;
}

/*
 *----------------------------------------------------------------------







|







<
|
>



|



















|
|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
		optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue,-1);
		Tcl_IncrRefCount(optionPtr->defaultPtr);
	    }
	    if (((specPtr->type == TK_OPTION_COLOR)
		    || (specPtr->type == TK_OPTION_BORDER))
		    && (specPtr->clientData != NULL)) {
		optionPtr->extra.monoColorPtr =
			Tcl_NewStringObj((char *) specPtr->clientData, -1);
		Tcl_IncrRefCount(optionPtr->extra.monoColorPtr);
	    }

	    if (specPtr->type == TK_OPTION_CUSTOM) {
		/*
		 * Get the custom parsing, etc., functions.
		 */

		optionPtr->extra.custom =
			(Tk_ObjCustomOption *) specPtr->clientData;
	    }
	}
	if (((specPtr->type == TK_OPTION_STRING)
		&& (specPtr->internalOffset >= 0))
		|| (specPtr->type == TK_OPTION_COLOR)
		|| (specPtr->type == TK_OPTION_FONT)
		|| (specPtr->type == TK_OPTION_BITMAP)
		|| (specPtr->type == TK_OPTION_BORDER)
		|| (specPtr->type == TK_OPTION_CURSOR)
		|| (specPtr->type == TK_OPTION_CUSTOM)) {
	    optionPtr->flags |= OPTION_NEEDS_FREEING;
	}
    }
    tablePtr->hashEntryPtr = hashEntryPtr;
    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).
     */

    if (specPtr->clientData != NULL) {
	tablePtr->nextPtr = (OptionTable *) Tk_CreateOptionTable(interp,
		(Tk_OptionSpec *) specPtr->clientData);
    }

    return (Tk_OptionTable) tablePtr;
}

/*
 *----------------------------------------------------------------------
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355





















































356
357
358
359
360
361
362

void
Tk_DeleteOptionTable(
    Tk_OptionTable optionTable)	/* The option table to delete. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;


    if (tablePtr->refCount-- > 1) {
	return;
    }

    if (tablePtr->nextPtr != NULL) {
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
    }

    for (count = tablePtr->numOptions, optionPtr = tablePtr->options;
	    count > 0;  count--, optionPtr++) {
	if (optionPtr->defaultPtr != NULL) {
	    Tcl_DecrRefCount(optionPtr->defaultPtr);
	}
	if (((optionPtr->specPtr->type == TK_OPTION_COLOR)
		|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
		&& (optionPtr->extra.monoColorPtr != NULL)) {
	    Tcl_DecrRefCount(optionPtr->extra.monoColorPtr);
	}
    }
    Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
    ckfree(tablePtr);





















































}

/*
 *--------------------------------------------------------------
 *
 * Tk_InitOptions --
 *







|

>
|



















|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

void
Tk_DeleteOptionTable(
    Tk_OptionTable optionTable)	/* The option table to delete. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    int count;

    tablePtr->refCount--;
    if (tablePtr->refCount > 0) {
	return;
    }

    if (tablePtr->nextPtr != NULL) {
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
    }

    for (count = tablePtr->numOptions, optionPtr = tablePtr->options;
	    count > 0;  count--, optionPtr++) {
	if (optionPtr->defaultPtr != NULL) {
	    Tcl_DecrRefCount(optionPtr->defaultPtr);
	}
	if (((optionPtr->specPtr->type == TK_OPTION_COLOR)
		|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
		&& (optionPtr->extra.monoColorPtr != NULL)) {
	    Tcl_DecrRefCount(optionPtr->extra.monoColorPtr);
	}
    }
    Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
    ckfree((char *) tablePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyOptionHashTable --
 *
 *	This 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.
 *
 *----------------------------------------------------------------------
 */

static void
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;
    Tcl_HashEntry *hashEntryPtr;
    OptionTable *tablePtr;

    for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr);

	/*
	 * 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).
	 */

	tablePtr->refCount = 1;
	tablePtr->nextPtr = NULL;
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
    }
    Tcl_DeleteHashTable(hashTablePtr);
    ckfree((char *) hashTablePtr);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_InitOptions --
 *
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
 *--------------------------------------------------------------
 */

int
Tk_InitOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. NULL means
				 * don't leave an error message. */
    void *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







|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
 *--------------------------------------------------------------
 */

int
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
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
 */

static int
DoObjConfig(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no message is left if an error
				 * occurs. */
    void *recordPtr,		/* The record to modify to hold the new option
				 * value. */
    Option *optionPtr,		/* Pointer to information about the option. */
    Tcl_Obj *valuePtr,		/* New value for option. */
    Tk_Window tkwin,		/* Window in which option will be used (needed
				 * to allocate resources for some options).
				 * May be NULL if the option doesn't require
				 * window-related resources. */
    Tk_SavedOption *savedOptionPtr)
				/* If NULL, the old value for the option will
				 * be freed. If non-NULL, the old value will
				 * be stored here, and it becomes the property
				 * of the caller (the caller must eventually
				 * free the old value). */
{
    Tcl_Obj **slotPtrPtr, *oldPtr;
    void *internalPtr;		/* Points to location in record where internal
				 * representation of value should be stored,
				 * or NULL. */
    void *oldInternalPtr;	/* Points to location in which to save old
				 * internal representation of value. */
    Tk_SavedOption internal;	/* Used to save the old internal
				 * representation of the value if
				 * savedOptionPtr is NULL. */
    const Tk_OptionSpec *specPtr;
    int nullOK;

    /*
     * Save the old object form for the value, if there is one.
     */

    specPtr = optionPtr->specPtr;
    if (specPtr->objOffset != TCL_INDEX_NONE) {
	slotPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
	oldPtr = *slotPtrPtr;
    } else {
	slotPtrPtr = NULL;
	oldPtr = NULL;
    }

    /*
     * Apply the new value in a type-specific way. Also remember the old
     * object and internal forms, if they exist.
     */

    if (specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + specPtr->internalOffset;
    } else {
	internalPtr = NULL;
    }
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;







|















|


|












|
|











|
|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
 */

static int
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
				 * to allocate resources for some options).
				 * May be NULL if the option doesn't require
				 * window-related resources. */
    Tk_SavedOption *savedOptionPtr)
				/* If NULL, the old value for the option will
				 * be freed. If non-NULL, the old value will
				 * be stored here, and it becomes the property
				 * of the caller (the caller must eventually
				 * free the old value). */
{
    Tcl_Obj **slotPtrPtr, *oldPtr;
    char *internalPtr;		/* Points to location in record where internal
				 * representation of value should be stored,
				 * or NULL. */
    char *oldInternalPtr;	/* Points to location in which to save old
				 * internal representation of value. */
    Tk_SavedOption internal;	/* Used to save the old internal
				 * representation of the value if
				 * savedOptionPtr is NULL. */
    const Tk_OptionSpec *specPtr;
    int nullOK;

    /*
     * Save the old object form for the value, if there is one.
     */

    specPtr = optionPtr->specPtr;
    if (specPtr->objOffset >= 0) {
	slotPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
	oldPtr = *slotPtrPtr;
    } else {
	slotPtrPtr = NULL;
	oldPtr = NULL;
    }

    /*
     * Apply the new value in a type-specific way. Also remember the old
     * object and internal forms, if they exist.
     */

    if (specPtr->internalOffset >= 0) {
	internalPtr = recordPtr + specPtr->internalOffset;
    } else {
	internalPtr = NULL;
    }
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
	if (internalPtr != NULL) {
	    *((double *) oldInternalPtr) = *((double *) internalPtr);
	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr;
	const char *value;
	TkSizeT length;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	}
	if (internalPtr != NULL) {
	    if (valuePtr != NULL) {
		value = TkGetStringFromObj(valuePtr, &length);
		newStr = (char *)ckalloc(length + 1);
		strcpy(newStr, value);
	    } else {
		newStr = NULL;
	    }
	    *((char **) oldInternalPtr) = *((char **) internalPtr);
	    *((char **) internalPtr) = newStr;
	}
	break;
    }
    case TK_OPTION_STRING_TABLE: {
	int newValue;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
            newValue = -1;
        } else {
	    if (Tcl_GetIndexFromObjStruct(interp, valuePtr,
		    optionPtr->specPtr->clientData, sizeof(char *),
		    optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
	        return TCL_ERROR;
	    }
        }
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newValue;
	}
	break;
    }
    case TK_OPTION_COLOR: {







|
<
|






|
|












<
<
<
<
|
|
|
|
|
<







706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734




735
736
737
738
739

740
741
742
743
744
745
746
	if (internalPtr != NULL) {
	    *((double *) oldInternalPtr) = *((double *) internalPtr);
	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr, *value;

	int length;

	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 {
		newStr = NULL;
	    }
	    *((char **) oldInternalPtr) = *((char **) internalPtr);
	    *((char **) internalPtr) = newStr;
	}
	break;
    }
    case TK_OPTION_STRING_TABLE: {
	int newValue;





	if (Tcl_GetIndexFromObj(interp, valuePtr,
		(const char **) optionPtr->specPtr->clientData,
		optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newValue;
	}
	break;
    }
    case TK_OPTION_COLOR: {
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892



893
894
895
896
897
898

899
900
901
902
903
904
905
	if (internalPtr != NULL) {
	    *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr);
	    *((Tk_Window *) internalPtr) = newWin;
	}
	break;
    }
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	if (custom->setProc(custom->clientData, interp, tkwin,
		&valuePtr, (char *)recordPtr, optionPtr->specPtr->internalOffset,
		(char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) {
	    return TCL_ERROR;
	}
	break;
    }




    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad config table: unknown type %d",
		optionPtr->specPtr->type));
	Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL);
	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.
     */








|


|






>
>
>

<
|
|
|

>







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

947
948
949
950
951
952
953
954
955
956
957
958
	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.
     */

937
938
939
940
941
942
943


944
945
946
947
948
949

950
951
952
953
954
955
956
957
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{


    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}

/*
 *----------------------------------------------------------------------
 *
 * GetOption --
 *







>
>



|
|

>
|







990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
 *----------------------------------------------------------------------
 */

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);
}

/*
 *----------------------------------------------------------------------
 *
 * GetOption --
 *
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
    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;
    size_t count;

    /*
     * 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







|







1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    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;
    int count;

    /*
     * 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
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
    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;
    const char *name;

    /*
     * First, check to see if the object already has the answer cached.
     */

    if (objPtr->typePtr == &optionObjType) {
	if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
	    return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
	}
    }

    /*
     * The answer isn't cached.







|





|







1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
    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;

    /*
     * First, check to see if the object already has the answer cached.
     */

    if (objPtr->typePtr == &tkOptionObjType) {
	if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
	    return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
	}
    }

    /*
     * The answer isn't cached.
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111

    if ((objPtr->typePtr != NULL)
	    && (objPtr->typePtr->freeIntRepProc != NULL)) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
    objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
    objPtr->typePtr = &optionObjType;
    tablePtr->refCount++;
    return bestPtr;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", name));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", name, NULL);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|
<




<
|
<







1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156

1157

1158
1159
1160
1161
1162
1163
1164

    if ((objPtr->typePtr != NULL)
	    && (objPtr->typePtr->freeIntRepProc != NULL)) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
    objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
    objPtr->typePtr = &tkOptionObjType;

    return bestPtr;

  error:
    if (interp != NULL) {

	Tcl_AppendResult(interp, "unknown option \"", name, "\"", NULL);

    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156


1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
    }
    return optionPtr->specPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeOptionInternalRep --
 *
 *	Part of the option Tcl object type implementation. Frees the storage
 *	associated with a option object's internal representation unless it
 *	is still in use.

 *
 * Results:
 *	None.


 *
 * Side effects:
 *	The option object's internal rep is marked invalid and its memory
 *	gets freed unless it is still in use somewhere. In that case the
 *	cleanup is delayed until the last reference goes away.
 *
 *----------------------------------------------------------------------
 */

static void
FreeOptionInternalRep(

    Tcl_Obj *objPtr)	/* Object whose internal rep to free. */
{
    Tk_OptionTable tablePtr = (Tk_OptionTable) objPtr->internalRep.twoPtrValue.ptr1;

    Tk_DeleteOptionTable(tablePtr);
    objPtr->typePtr = NULL;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
}

/*
 *---------------------------------------------------------------------------
 *
 * DupOptionInternalRep --
 *
 *	When a cached option object is duplicated, this is called to update the
 *	internal reps.
 *
 *---------------------------------------------------------------------------
 */

static void
DupOptionInternalRep(
    Tcl_Obj *srcObjPtr,		/* The object we are copying from. */
    Tcl_Obj *dupObjPtr)		/* The object we are copying to. */
{
    OptionTable *tablePtr = (OptionTable *) srcObjPtr->internalRep.twoPtrValue.ptr1;
    tablePtr->refCount++;
    dupObjPtr->typePtr = srcObjPtr->typePtr;
    dupObjPtr->internalRep = srcObjPtr->internalRep;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SetOptions --
 *







|

|
|
|
>


<
>
>


<
<
|




|
|
>
|

<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<







1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213


1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225




1226










1227









1228
1229
1230
1231
1232
1233
1234
    }
    return optionPtr->specPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * SetOptionFromAny --
 *
 *	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.
 *
 * Side effects:


 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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",




	    -1);










    return TCL_ERROR;









}

/*
 *--------------------------------------------------------------
 *
 * Tk_SetOptions --
 *
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
 *--------------------------------------------------------------
 */

int
Tk_SetOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is returned.*/
    void *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







|







1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
 *--------------------------------------------------------------
 */

int
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
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301

1302
1303
1304

1305
1306
1307
1308
1309
1310
1311
	}
	if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	    optionPtr = optionPtr->extra.synonymPtr;
	}

	if (objc < 2) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing",
			Tcl_GetString(*objv)));
		Tcl_SetErrorCode(interp, "TK", "VALUE_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
	     * more space.
	     */

	    newSavePtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));
	    newSavePtr->recordPtr = recordPtr;
	    newSavePtr->tkwin = tkwin;
	    newSavePtr->numItems = 0;
	    newSavePtr->nextPtr = NULL;
	    lastSavePtr->nextPtr = newSavePtr;
	    lastSavePtr = newSavePtr;
	}
	if (DoObjConfig(interp, recordPtr, optionPtr, objv[1], tkwin,
		(savePtr != NULL) ? &lastSavePtr->items[lastSavePtr->numItems]
		: NULL) != TCL_OK) {

	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (processing \"%.40s\" option)",
		    Tcl_GetString(*objv)));

	    goto error;
	}
	if (savePtr != NULL) {
	    lastSavePtr->numItems++;
	}
	mask |= optionPtr->specPtr->typeMask;
    }







|
<
|
|










|










>
|
|
|
>







1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
	}
	if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	    optionPtr = optionPtr->extra.synonymPtr;
	}

	if (objc < 2) {
	    if (interp != NULL) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),

			"value for \"", Tcl_GetStringFromObj(*objv, NULL),
			"\" missing", NULL);
		goto error;
	    }
	}
	if ((savePtr != NULL)
		&& (lastSavePtr->numItems >= TK_NUM_SAVED_OPTIONS)) {
	    /*
	     * We've run out of space for saving old option values. Allocate
	     * more space.
	     */

	    newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(Tk_SavedOptions));
	    newSavePtr->recordPtr = recordPtr;
	    newSavePtr->tkwin = tkwin;
	    newSavePtr->numItems = 0;
	    newSavePtr->nextPtr = NULL;
	    lastSavePtr->nextPtr = newSavePtr;
	    lastSavePtr = newSavePtr;
	}
	if (DoObjConfig(interp, recordPtr, optionPtr, objv[1], tkwin,
		(savePtr != NULL) ? &lastSavePtr->items[lastSavePtr->numItems]
		: NULL) != TCL_OK) {
	    char msg[100];

	    sprintf(msg, "\n    (processing \"%.40s\" option)",
		    Tcl_GetStringFromObj(*objv, NULL));
	    Tcl_AddErrorInfo(interp, msg);
	    goto error;
	}
	if (savePtr != NULL) {
	    lastSavePtr->numItems++;
	}
	mask |= optionPtr->specPtr->typeMask;
    }
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412
1413
1414
 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    size_t i;
    Option *optionPtr;
    Tcl_Obj *newPtr;		/* New object value of option, which we
				 * replace with old value and free. Taken from
				 * record. */
    void *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i != (size_t)-1; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset != TCL_INDEX_NONE) {
	    newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}
	if (newPtr != NULL) {
	    Tcl_DecrRefCount(newPtr);
	}

	/*
	 * Now restore the old value of the option.
	 */

	if (specPtr->objOffset != TCL_INDEX_NONE) {
	    *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset))
		    = savePtr->items[i].valuePtr;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:


	    case TK_OPTION_INT:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:







|




|











|


|








|
|



|
|














|
|


|
|

<


>
>







1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
 */

void
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. */
    char *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree((char *) savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i >= 0; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset >= 0) {
	    newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset >= 0) {
	    internalPtr = savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}
	if (newPtr != NULL) {
	    Tcl_DecrRefCount(newPtr);
	}

	/*
	 * Now restore the old value of the option.
	 */

	if (specPtr->objOffset >= 0) {
	    *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset))
		    = savePtr->items[i].valuePtr;
	}
	if (specPtr->internalOffset >= 0) {
	    register char *ptr = (char *) &savePtr->items[i].internalForm;


	    switch (specPtr->type) {
	    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:
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
	    case TK_OPTION_PIXELS:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_WINDOW:
		*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
		break;
	    case TK_OPTION_CUSTOM: {
		const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

		if (custom->restoreProc != NULL) {
		    custom->restoreProc(custom->clientData, savePtr->tkwin,
			    (char *)internalPtr, ptr);
		}
		break;
	    }
	    default:
		Tcl_Panic("bad option type in Tk_RestoreSavedOptions");
	    }
	}







|



|







1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
	    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");
	    }
	}
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
 */

void
Tk_FreeSavedOptions(
    Tk_SavedOptions *savePtr)	/* Contains options saved in a previous call
				 * to Tk_SetOptions. */
{
    size_t count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
    }
    for (count = savePtr->numItems; count > 0; count--) {
	savedOptionPtr = &savePtr->items[count-1];

	if (savedOptionPtr->optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(savedOptionPtr->optionPtr, savedOptionPtr->valuePtr,
		    (char *) &savedOptionPtr->internalForm, savePtr->tkwin);
	}
	if (savedOptionPtr->valuePtr != NULL) {
	    Tcl_DecrRefCount(savedOptionPtr->valuePtr);
	}







|




|

|
|
>







1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
 */

void
Tk_FreeSavedOptions(
    Tk_SavedOptions *savePtr)	/* Contains options saved in a previous call
				 * to Tk_SetOptions. */
{
    int count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree((char *) savePtr->nextPtr);
    }
    for (count = savePtr->numItems,
	    savedOptionPtr = &savePtr->items[savePtr->numItems-1];
	    count > 0;  count--, savedOptionPtr--) {
	if (savedOptionPtr->optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(savedOptionPtr->optionPtr, savedOptionPtr->valuePtr,
		    (char *) &savedOptionPtr->internalForm, savePtr->tkwin);
	}
	if (savedOptionPtr->valuePtr != NULL) {
	    Tcl_DecrRefCount(savedOptionPtr->valuePtr);
	}
1522
1523
1524
1525
1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
 * Side effects:
 *	All of the Tcl_Obj's in recordPtr that are controlled by configuration
 *	options in optionTable are freed.
 *
 *----------------------------------------------------------------------
 */


void
Tk_FreeConfigOptions(
    void *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;
    size_t count;
    Tcl_Obj **oldPtrPtr, *oldPtr;
    void *oldInternalPtr;
    const Tk_OptionSpec *specPtr;

    for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
	    tablePtr = tablePtr->nextPtr) {
	for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
		count > 0; optionPtr++, count--) {
	    specPtr = optionPtr->specPtr;
	    if (specPtr->type == TK_OPTION_SYNONYM) {
		continue;
	    }
	    if (specPtr->objOffset != TCL_INDEX_NONE) {
		oldPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
		oldPtr = *oldPtrPtr;
		*oldPtrPtr = NULL;
	    } else {
		oldPtr = NULL;
	    }
	    if (specPtr->internalOffset != TCL_INDEX_NONE) {
		oldInternalPtr = (char *)recordPtr + specPtr->internalOffset;
	    } else {
		oldInternalPtr = NULL;
	    }
	    if (optionPtr->flags & OPTION_NEEDS_FREEING) {
		FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin);
	    }
	    if (oldPtr != NULL) {







>


|







|

|










|
|





|
|







1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
 * Side effects:
 *	All of the Tcl_Obj's in recordPtr that are controlled by configuration
 *	options in optionTable are freed.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
void
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;
    char *oldInternalPtr;
    const Tk_OptionSpec *specPtr;

    for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
	    tablePtr = tablePtr->nextPtr) {
	for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
		count > 0; optionPtr++, count--) {
	    specPtr = optionPtr->specPtr;
	    if (specPtr->type == TK_OPTION_SYNONYM) {
		continue;
	    }
	    if (specPtr->objOffset >= 0) {
		oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
		oldPtr = *oldPtrPtr;
		*oldPtrPtr = NULL;
	    } else {
		oldPtr = NULL;
	    }
	    if (specPtr->internalOffset >= 0) {
		oldInternalPtr = recordPtr + specPtr->internalOffset;
	    } else {
		oldInternalPtr = NULL;
	    }
	    if (optionPtr->flags & OPTION_NEEDS_FREEING) {
		FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin);
	    }
	    if (oldPtr != NULL) {
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
 */

static void
FreeResources(
    Option *optionPtr,		/* Description of the configuration option. */
    Tcl_Obj *objPtr,		/* The current value of the option, specified
				 * as an object. */
    void *internalPtr,		/* A pointer to an internal representation for
				 * the option's value, such as an int or
				 * (XColor *). Only valid if
				 * optionPtr->specPtr->internalOffset != -1. */
    Tk_Window tkwin)		/* The window in which this option is used. */
{
    int internalFormExists;

    /*
     * If there exists an internal form for the value, use it to free
     * resources (also zero out the internal form). If there is no internal
     * form, then use the object form.
     */

    internalFormExists = optionPtr->specPtr->internalOffset != TCL_INDEX_NONE;
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_STRING:
	if (internalFormExists) {
	    if (*((char **) internalPtr) != NULL) {
		ckfree(*((char **) internalPtr));
		*((char **) internalPtr) = NULL;
	    }







|


|










|







1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
 */

static void
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
				 * the option's value, such as an int or
				 * (XColor *). Only valid if
				 * optionPtr->specPtr->internalOffset >= 0. */
    Tk_Window tkwin)		/* The window in which this option is used. */
{
    int internalFormExists;

    /*
     * If there exists an internal form for the value, use it to free
     * resources (also zero out the internal form). If there is no internal
     * form, then use the object form.
     */

    internalFormExists = optionPtr->specPtr->internalOffset >= 0;
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_STRING:
	if (internalFormExists) {
	    if (*((char **) internalPtr) != NULL) {
		ckfree(*((char **) internalPtr));
		*((char **) internalPtr) = NULL;
	    }
1636
1637
1638
1639
1640
1641
1642


1643
1644
1645
1646
1647
1648
1649
	    Tk_FreeFontFromObj(tkwin, objPtr);
	}
	break;
    case TK_OPTION_STYLE:
	if (internalFormExists) {
	    Tk_FreeStyle(*((Tk_Style *) internalPtr));
	    *((Tk_Style *) internalPtr) = NULL;


	}
	break;
    case TK_OPTION_BITMAP:
	if (internalFormExists) {
	    if (*((Pixmap *) internalPtr) != None) {
		Tk_FreeBitmap(Tk_Display(tkwin), *((Pixmap *) internalPtr));
		*((Pixmap *) internalPtr) = None;







>
>







1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
	    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;
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695

1696
1697
1698
1699
1700
1701
1702
		*((Tk_Cursor *) internalPtr) = NULL;
	    }
	} else if (objPtr != NULL) {
	    Tk_FreeCursorFromObj(tkwin, objPtr);
	}
	break;
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
	if (internalFormExists && custom->freeProc != NULL) {
	    custom->freeProc(custom->clientData, tkwin, (char *)internalPtr);
	}
	break;
    }
    default:
	break;
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetOptionInfo --
 *
 *	Returns a list object containing complete information about either a
 *	single option or all the configuration options in a table.
 *
 * Results:

 *	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







|

|

















>







1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
		*((Tk_Cursor *) internalPtr) = NULL;
	    }
	} 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;
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetOptionInfo --
 *
 *	Returns a list object containing complete information about either a
 *	single option or all the configuration options in a table.
 *
 * Results:

 *	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
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
 *--------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetOptionInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is created. */
    void *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;
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    if (namePtr != NULL) {







|













|







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
 *--------------------------------------------------------------
 */

Tcl_Obj *
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;
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    int count;

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    if (namePtr != NULL) {
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
 *	Memory is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
GetConfigList(
    void *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. */
{
    Tcl_Obj *listPtr, *elementPtr;








|







1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
 *	Memory is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
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. */
{
    Tcl_Obj *listPtr, *elementPtr;

1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
	} else if (optionPtr->defaultPtr != NULL) {
	    elementPtr = optionPtr->defaultPtr;
	} else {
	    elementPtr = Tcl_NewObj();
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->specPtr->objOffset != TCL_INDEX_NONE) {
	    elementPtr = *((Tcl_Obj **) ((char *)recordPtr
		    + optionPtr->specPtr->objOffset));
	    if (elementPtr == NULL) {
		elementPtr = Tcl_NewObj();
	    }
	} else {
	    elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin);
	}







|
|







1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
	} else if (optionPtr->defaultPtr != NULL) {
	    elementPtr = optionPtr->defaultPtr;
	} else {
	    elementPtr = Tcl_NewObj();
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->specPtr->objOffset >= 0) {
	    elementPtr = *((Tcl_Obj **) (recordPtr
		    + optionPtr->specPtr->objOffset));
	    if (elementPtr == NULL) {
		elementPtr = Tcl_NewObj();
	    }
	} else {
	    elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin);
	}
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878


1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetObjectForOption(
    void *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;
    void *internalPtr;		/* Points to internal value of option in
				 * record. */


    objPtr = NULL;
    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:


	case TK_OPTION_INT:
	    objPtr = Tcl_NewWideIntObj(*((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);
	    }
	    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 != NULL) {
		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_NewWideIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_WINDOW: {
	    tkwin = *((Tk_Window *) internalPtr);

	    if (tkwin != NULL) {
		objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
	    }
	    break;
	}
	case TK_OPTION_CUSTOM: {
	    const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	    objPtr = custom->getProc(custom->clientData, tkwin, (char *)recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
        }
        default:
	    Tcl_Panic("bad option type in GetObjectForOption");
	}
    }
    if (objPtr == NULL) {
	objPtr = Tcl_NewObj();
    }
    return objPtr;
}








|







|


>

<
<
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
<







1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912


1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010

2011
2012
2013
2014
2015
2016
2017
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
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
				 * record. */

    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_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);
	}
	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 != NULL) {
	    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();
    }
    return objPtr;
}

1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
 */

Tcl_Obj *
Tk_GetOptionValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL
				 * then no messages are provided for
				 * errors. */
    void *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;
    Tcl_Obj *resultPtr;

    optionPtr = GetOptionFromObj(interp, namePtr, tablePtr);
    if (optionPtr == NULL) {
	return NULL;
    }
    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	optionPtr = optionPtr->extra.synonymPtr;
    }
    if (optionPtr->specPtr->objOffset != TCL_INDEX_NONE) {
	resultPtr = *((Tcl_Obj **) ((char *)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.
	     */








|

















|
|







2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
 */

Tcl_Obj *
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. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    Tcl_Obj *resultPtr;

    optionPtr = GetOptionFromObj(interp, namePtr, tablePtr);
    if (optionPtr == NULL) {
	return NULL;
    }
    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	optionPtr = optionPtr->extra.synonymPtr;
    }
    if (optionPtr->specPtr->objOffset >= 0) {
	resultPtr = *((Tcl_Obj **) (recordPtr+optionPtr->specPtr->objOffset));
	if (resultPtr == NULL) {
	    /*
	     * This option has a null value and is represented by a null
	     * object pointer. We can't return the null pointer, since that
	     * would indicate an error. Instead, return a new empty object.
	     */

2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071

2072
2073
2074
2075
2076
2077
2078


2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugConfig(
    TCL_UNUSED(Tcl_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_HashEntry *hashEntryPtr;
    Tcl_HashSearch search;
    Tcl_Obj *objPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    objPtr = Tcl_NewObj();


    if (!tablePtr || !tsdPtr->initialized) {
	return objPtr;
    }

    /*
     * Scan all the tables for this interpreter to make sure that the one we
     * want still is valid.
     */

    for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
	    for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj(tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj(tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, -1));
	    }
	    break;
	}
    }
    return objPtr;







|






>



<
<


>
>
|








|





|

|







2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112


2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
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;
    Tcl_HashEntry *hashEntryPtr;
    Tcl_HashSearch search;
    Tcl_Obj *objPtr;



    objPtr = Tcl_NewObj();
    hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY,
	    NULL);
    if (hashTablePtr == NULL) {
	return objPtr;
    }

    /*
     * Scan all the tables for this interpreter to make sure that the one we
     * want still is valid.
     */

    for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
	    for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewIntObj(tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewIntObj(tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, -1));
	    }
	    break;
	}
    }
    return objPtr;

Changes to generic/tkConsole.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * 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.
 *
 * 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.
 */

#include "tkInt.h"

/*
 * Each console is associated with an instance of the ConsoleInfo struct.
 * It keeps track of what interp holds the Tk application that displays
 * the console, and what interp is controlled by the interactions in that
 * console.  A refCount permits the struct to be shared as instance data
 * by commands and by channels.
 */

typedef struct ConsoleInfo {
    Tcl_Interp *consoleInterp;	/* Interpreter displaying the console. */
    Tcl_Interp *interp;		/* Interpreter controlled by console. */
    size_t refCount;
} ConsoleInfo;

/*
 * Each console channel holds an instance of the ChannelData struct as
 * its instance data.  It contains ConsoleInfo, so the channel can work
 * with the appropriate console window, and a type value to distinguish
 * the stdout channel from the stderr channel.
 */

typedef struct ChannelData {
    ConsoleInfo *info;
    int type;			/* TCL_STDOUT or TCL_STDERR */
} ChannelData;

/*
 * Prototypes for local procedures defined in this file:
 */

static int	ConsoleClose(ClientData instanceData, Tcl_Interp *interp);
static int	Console2Close(ClientData instanceData, Tcl_Interp *interp, int flags);
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:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    TCL_CHANNEL_VERSION_5,	/* v5 channel */
    (Tcl_DriverCloseProc *)ConsoleClose,		/* Close proc. */
    ConsoleInput,		/* Input proc. */
    ConsoleOutput,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatch,		/* Watch for events on console. */
    ConsoleHandle,		/* Get a handle from the device. */
    Console2Close,			/* close2proc. */
    NULL,			/* Always non-blocking.*/
    NULL,			/* flush proc. */
    NULL,			/* handler proc. */
    NULL,			/* wide seek proc */
    NULL,			/* thread action proc */
    NULL
};

#ifdef _WIN32
#include <windows.h>

/*
 *----------------------------------------------------------------------
 *
 * ShouldUseConsoleChannel
 *













|












|



















<


|
|
|
|

|
|
|




|





|

|
|







|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * 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.
 *
 * 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.
 */

#include "tk.h"

/*
 * Each console is associated with an instance of the ConsoleInfo struct.
 * It keeps track of what interp holds the Tk application that displays
 * the console, and what interp is controlled by the interactions in that
 * console.  A refCount permits the struct to be shared as instance data
 * by commands and by channels.
 */

typedef struct ConsoleInfo {
    Tcl_Interp *consoleInterp;	/* Interpreter displaying the console. */
    Tcl_Interp *interp;		/* Interpreter controlled by console. */
    int refCount;
} ConsoleInfo;

/*
 * Each console channel holds an instance of the ChannelData struct as
 * its instance data.  It contains ConsoleInfo, so the channel can work
 * with the appropriate console window, and a type value to distinguish
 * the stdout channel from the stderr channel.
 */

typedef struct ChannelData {
    ConsoleInfo *info;
    int type;			/* TCL_STDOUT or TCL_STDERR */
} ChannelData;

/*
 * Prototypes for local procedures defined in this file:
 */

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:
 */

static Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    TCL_CHANNEL_VERSION_4,	/* v4 channel */
    ConsoleClose,		/* Close proc. */
    ConsoleInput,		/* Input proc. */
    ConsoleOutput,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatch,		/* Watch for events on console. */
    ConsoleHandle,		/* Get a handle from the device. */
    NULL,			/* close2proc. */
    NULL,			/* Always non-blocking.*/
    NULL,			/* flush proc. */
    NULL,			/* handler proc. */
    NULL,			/* wide seek proc */
    NULL,			/* thread action proc */
    NULL
};

#ifdef __WIN32__
#include <windows.h>

/*
 *----------------------------------------------------------------------
 *
 * ShouldUseConsoleChannel
 *
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    /*
     * 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) {
	dcb.DCBlength = sizeof(DCB);
	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.
	     */








|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    /*
     * 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) {
	dcb.DCBlength = sizeof( DCB ) ;
	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.
	     */

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274

275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291

292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308

309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    ConsoleInfo *info;
    Tcl_Channel consoleChannel;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
        return;
    }

    consoleInitPtr = (int *)Tcl_GetThreadData(&consoleInitKey, (int) sizeof(int));
    if (*consoleInitPtr) {
	/*
	 * We've already initialized console channels in this thread.
	 */

	return;
    }
    *consoleInitPtr = 1;

    doIn = ShouldUseConsoleChannel(TCL_STDIN);
    doOut = ShouldUseConsoleChannel(TCL_STDOUT);
    doErr = ShouldUseConsoleChannel(TCL_STDERR);

    if (!(doIn || doOut || doErr)) {
	/*
	 * No std channels should be tied to the console; thus, no need to
	 * create the console.
	 */

	return;
    }

    /*
     * At least one std channel wants to be tied to the console, so create the
     * interp for it to live in.
     */

    info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo));
    info->consoleInterp = NULL;
    info->interp = NULL;
    info->refCount = 0;

    if (doIn) {
	ChannelData *data = (ChannelData *)ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDIN;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0",
		data, TCL_READABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8");

	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDIN);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }

    if (doOut) {
	ChannelData *data = (ChannelData *)ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDOUT;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1",
		data, TCL_WRITABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8");

	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDOUT);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }

    if (doErr) {
	ChannelData *data = (ChannelData *)ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDERR;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2",
		data, TCL_WRITABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none");

	    Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8");

	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDERR);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateConsoleWindow --
 *
 *	Initialize the console. This code actually creates a new application
 *	and associated interpreter. This effectively hides the implementation
 *	from the main application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A new console it created.







|



|

<
|
<
<










|
|

<




|
|








|
<




|

|
>
|
>
|
>






|
<




|

|
>
|
>
|
>






|
<




|

|
>
|
>
|
>












|







219
220
221
222
223
224
225
226
227
228
229
230
231

232


233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    ConsoleInfo *info;
    Tcl_Channel consoleChannel;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) {
        return;
    }

    consoleInitPtr = Tcl_GetThreadData(&consoleInitKey, (int)sizeof(int));
    if (*consoleInitPtr) {

	/* We've already initialized console channels in this thread. */


	return;
    }
    *consoleInitPtr = 1;

    doIn = ShouldUseConsoleChannel(TCL_STDIN);
    doOut = ShouldUseConsoleChannel(TCL_STDOUT);
    doErr = ShouldUseConsoleChannel(TCL_STDERR);

    if (!(doIn || doOut || doErr)) {
	/*
	 * No std channels should be tied to the console;
	 * Thus, no need to create the console
	 */

	return;
    }

    /*
     * At least one std channel wants to be tied to the console,
     * so create the interp for it to live in.
     */

    info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo));
    info->consoleInterp = NULL;
    info->interp = NULL;
    info->refCount = 0;

    if (doIn) {
	ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDIN;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0",
		(ClientData) data, TCL_READABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-translation", "lf");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-buffering", "none");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-encoding", "utf-8");
	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDIN);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }

    if (doOut) {
	ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDOUT;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1",
		(ClientData) data, TCL_WRITABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-translation", "lf");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-buffering", "none");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-encoding", "utf-8");
	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDOUT);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }

    if (doErr) {
	ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData));

	data->info = info;
	data->info->refCount++;
	data->type = TCL_STDERR;
	consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2",
		(ClientData) data, TCL_WRITABLE);
	if (consoleChannel != NULL) {
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-translation", "lf");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-buffering", "none");
	    Tcl_SetChannelOption(NULL, consoleChannel,
		    "-encoding", "utf-8");
	}
	Tcl_SetStdChannel(consoleChannel, TCL_STDERR);
	Tcl_RegisterChannel(NULL, consoleChannel);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateConsoleWindow --
 *
 *	Initialize the console. This code actually creates a new application
 *	and associated interpreter. This effectivly hides the implementation
 *	from the main application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A new console it created.
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    Tcl_Command token;
    int result = TCL_OK;
    int haveConsoleChannel = 1;

    /* Init an interp with Tcl and Tk */
    Tcl_Interp *consoleInterp = Tcl_CreateInterp();
    if (Tcl_Init(consoleInterp) != TCL_OK) {
	Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp);
	Tcl_SetObjResult(interp, result_obj);
	goto error;
    }
    if (Tk_Init(consoleInterp) != TCL_OK) {
	Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp);
	Tcl_SetObjResult(interp, result_obj);
	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) {
    } else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT))
	    == &consoleChannelType) {
    } else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR))
	    == &consoleChannelType) {
    } else {
	haveConsoleChannel = 0;
    }

    if (haveConsoleChannel) {
	ChannelData *data = (ChannelData *) Tcl_GetChannelInstanceData(chan);
	info = data->info;
	if (info->consoleInterp) {
	    /*
	     * New ConsoleInfo for a new console window.
	     */

	    info = (ConsoleInfo *)ckalloc(sizeof(ConsoleInfo));
	    info->refCount = 0;

	    /*
	     * Update any console channels to make use of the new console.
	     */

	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDIN))
		    == &consoleChannelType) {
		data = (ChannelData *) Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT))
		    == &consoleChannelType) {
		data = (ChannelData *) Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR))
		    == &consoleChannelType) {
		data = (ChannelData *) Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	}
    } else {
	info = (ConsoleInfo *)ckalloc(sizeof(ConsoleInfo));
	info->refCount = 0;
    }

    info->consoleInterp = consoleInterp;
    info->interp = interp;

    Tcl_CallWhenDeleted(consoleInterp, InterpDeleteProc, info);
    info->refCount++;
    Tcl_CreateThreadExitHandler(DeleteConsoleInterp, consoleInterp);


    /*
     * Add console commands to the interp
     */

    token = Tcl_CreateObjCommand(interp, "console", ConsoleObjCmd, info,
	    ConsoleDeleteProc);
    info->refCount++;

    /*
     * We don't have to count the ref held by the [consoleinterp] command
     * in the consoleInterp.  The ref held by the consoleInterp delete
     * handler takes care of us.
     */
    Tcl_CreateObjCommand(consoleInterp, "consoleinterp", InterpreterObjCmd,
	    info, NULL);

    mainWindow = Tk_MainWindow(interp);
    if (mainWindow) {
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
	    -1, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release(consoleInterp);
    if (result == TCL_ERROR) {
	Tcl_DeleteCommandFromToken(interp, token);
	mainWindow = Tk_MainWindow(interp);
	if (mainWindow) {
	    Tk_DeleteEventHandler(mainWindow, StructureNotifyMask,
		    ConsoleEventProc, info);
	    if (info->refCount-- <= 1) {
		ckfree(info);
	    }
	}
	goto error;
    }
    return TCL_OK;

  error:
    Tcl_AddErrorInfo(interp, "\n    (creating console window)");
    if (!Tcl_InterpDeleted(consoleInterp)) {
	Tcl_DeleteInterp(consoleInterp);
    }
    return TCL_ERROR;
}








<
<



<
<



















|


<
|
<
<
|


<
|
<
<


|






|






|






|






|

|
>





|
|








|




|



|







|





|
|
|






|







342
343
344
345
346
347
348


349
350
351


352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374


375
376
377

378


379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    Tcl_Command token;
    int result = TCL_OK;
    int haveConsoleChannel = 1;

    /* Init an interp with Tcl and Tk */
    Tcl_Interp *consoleInterp = Tcl_CreateInterp();
    if (Tcl_Init(consoleInterp) != TCL_OK) {


	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) {
    } else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT))
	    == &consoleChannelType) {
    } else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR))
	    == &consoleChannelType) {
    } else {
	haveConsoleChannel = 0;
    }

    if (haveConsoleChannel) {
	ChannelData *data = (ChannelData *)Tcl_GetChannelInstanceData(chan);
	info = data->info;
	if (info->consoleInterp) {

	    /* New ConsoleInfo for a new console window */


	    info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo));
	    info->refCount = 0;


	    /* Update any console channels to make use of the new console */


	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDIN))
		    == &consoleChannelType) {
		data = (ChannelData *)Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT))
		    == &consoleChannelType) {
		data = (ChannelData *)Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	    if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR))
		    == &consoleChannelType) {
		data = (ChannelData *)Tcl_GetChannelInstanceData(chan);
		data->info->refCount--;
		data->info = info;
		data->info->refCount++;
	    }
	}
    } else {
	info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo));
	info->refCount = 0;
    }

    info->consoleInterp = consoleInterp;
    info->interp = interp;

    Tcl_CallWhenDeleted(consoleInterp, InterpDeleteProc, (ClientData) info);
    info->refCount++;
    Tcl_CreateThreadExitHandler(DeleteConsoleInterp,
	    (ClientData) consoleInterp);

    /*
     * Add console commands to the interp
     */

    token = Tcl_CreateObjCommand(interp, "console", ConsoleObjCmd,
	    (ClientData) info, ConsoleDeleteProc);
    info->refCount++;

    /*
     * We don't have to count the ref held by the [consoleinterp] command
     * in the consoleInterp.  The ref held by the consoleInterp delete
     * handler takes care of us.
     */
    Tcl_CreateObjCommand(consoleInterp, "consoleinterp", InterpreterObjCmd,
	    (ClientData) info, NULL);

    mainWindow = Tk_MainWindow(interp);
    if (mainWindow) {
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, (ClientData) info);
	info->refCount++;
    }

    Tcl_Preserve((ClientData) consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
	    -1, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release((ClientData) consoleInterp);
    if (result == TCL_ERROR) {
	Tcl_DeleteCommandFromToken(interp, token);
	mainWindow = Tk_MainWindow(interp);
	if (mainWindow) {
	    Tk_DeleteEventHandler(mainWindow, StructureNotifyMask,
		    ConsoleEventProc, (ClientData) info);
	    if (--info->refCount <= 0) {
		ckfree((char *) info);
	    }
	}
	goto error;
    }
    return TCL_OK;

    error:
    Tcl_AddErrorInfo(interp, "\n    (creating console window)");
    if (!Tcl_InterpDeleted(consoleInterp)) {
	Tcl_DeleteInterp(consoleInterp);
    }
    return TCL_ERROR;
}

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
 *
 *----------------------------------------------------------------------
 */

static int
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;

    *errorCode = 0;







|







482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 *
 *----------------------------------------------------------------------
 */

static int
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;

    *errorCode = 0;
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

	    /*
	     * Not checking for utf8 == NULL.  Did not check for TCL_ERROR
	     * from Tcl_SetChannelOption() in Tk_InitConsoleChannels() either.
	     * Assumption is utf-8 Tcl_Encoding is reliably present.
	     */

	    const char *bytes
		    = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds);
	    int numBytes = Tcl_DStringLength(&ds);
	    Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", -1);

	    Tcl_FreeEncoding(utf8);

	    if (data->type == TCL_STDERR) {







|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

	    /*
	     * Not checking for utf8 == NULL.  Did not check for TCL_ERROR
	     * from Tcl_SetChannelOption() in Tk_InitConsoleChannels() either.
	     * Assumption is utf-8 Tcl_Encoding is reliably present.
	     */

	    CONST char *bytes
		    = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds);
	    int numBytes = Tcl_DStringLength(&ds);
	    Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", -1);

	    Tcl_FreeEncoding(utf8);

	    if (data->type == TCL_STDERR) {
555
556
557
558
559
560
561

562
563
564

565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648
649
650
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
ConsoleInput(
    TCL_UNUSED(void *),

    TCL_UNUSED(char *),			/* Where to store data read. */
    TCL_UNUSED(int),		/* How much space is available in the
				 * buffer? */
    TCL_UNUSED(int *))		/* Where to store error code. */
{
    return 0;			/* Always return EOF. */
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleClose/Console2Close --
 *
 *	Closes the IO channel.
 *
 * Results:
 *	Always returns 0 (success).
 *
 * Side effects:
 *	Frees the dummy file associated with the channel.
 *
 *----------------------------------------------------------------------
 */


static int
ConsoleClose(
    ClientData instanceData,
    TCL_UNUSED(Tcl_Interp *))
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;

    if (info) {
	if (info->refCount-- <= 1) {
	    /*
	     * Assuming the Tcl_Interp * fields must already be NULL.
	     */

	    ckfree(info);
	}
    }
    ckfree(data);
    return 0;
}

static int
Console2Close(
    ClientData instanceData,	/* Unused. */
    Tcl_Interp *interp,		/* Unused. */
    int flags)
{
    if ((flags&(TCL_CLOSE_READ|TCL_CLOSE_WRITE))==0) {
	return ConsoleClose(instanceData, interp);
    }
    return EINVAL;
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static void
ConsoleWatch(
    TCL_UNUSED(void *),	/* Device ID for the channel. */
    TCL_UNUSED(int))			/* OR-ed combination of TCL_READABLE,
				 * TCL_WRITABLE and TCL_EXCEPTION, for the
				 * events we are interested in. */
{
}

/*
 *----------------------------------------------------------------------







>


<
>
|
|

|







|












>


|
|





|
<
|
<
<
|


|

<
<
<
<
<
<
<
<
<
<
<
<




















>


|
|







547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592

593


594
595
596
597
598












599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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. */
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleClose --
 *
 *	Closes the IO channel.
 *
 * Results:
 *	Always returns 0 (success).
 *
 * Side effects:
 *	Frees the dummy file associated with the channel.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
ConsoleClose(
    ClientData instanceData,	/* Unused. */
    Tcl_Interp *interp)		/* Unused. */
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;

    if (info) {
	if (--info->refCount <= 0) {

	    /* Assuming the Tcl_Interp * fields must already be NULL */


	    ckfree((char *) info);
	}
    }
    ckfree((char *) data);
    return 0;












}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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. */
{
}

/*
 *----------------------------------------------------------------------
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
ConsoleHandle(
    TCL_UNUSED(void *),	/* Device ID for the channel. */
    TCL_UNUSED(int),		/* TCL_READABLE or TCL_WRITABLE to indicate
				 * which direction of the channel is being
				 * requested. */
    TCL_UNUSED(void **))	/* Where to store handle */
{
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







>


|
|


|







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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 */
{
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
 */

static int
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 *const options[] = {
	"eval", "hide", "show", "title", NULL};
    enum option {CON_EVAL, CON_HIDE, CON_SHOW, CON_TITLE};
    Tcl_Obj *cmd = NULL;
    ConsoleInfo *info = (ConsoleInfo *)clientData;
    Tcl_Interp *consoleInterp = info->consoleInterp;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum option) index) {
    case CON_EVAL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "script");







|


<
|


|






|
|







673
674
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 */

static int
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};
    enum option {CON_EVAL, CON_HIDE, CON_SHOW, CON_TITLE};
    Tcl_Obj *cmd = NULL;
    ConsoleInfo *info = (ConsoleInfo *) clientData;
    Tcl_Interp *consoleInterp = info->consoleInterp;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum option) index) {
    case CON_EVAL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "script");
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm title .", -1);
	if (objc == 3) {
	    Tcl_ListObjAppendElement(NULL, cmd, objv[2]);
	}
	break;
    default:
	CLANG_ASSERT(0);
    }

    Tcl_IncrRefCount(cmd);
    if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	Tcl_Preserve(consoleInterp);
	result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
	Tcl_Release(consoleInterp);
    } else {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active console interp", -1));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NONE", NULL);
	result = TCL_ERROR;
    }
    Tcl_DecrRefCount(cmd);
    return result;
}

/*







<
<




|




|

<
|
<







723
724
725
726
727
728
729


730
731
732
733
734
735
736
737
738
739
740

741

742
743
744
745
746
747
748
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm title .", -1);
	if (objc == 3) {
	    Tcl_ListObjAppendElement(NULL, cmd, objv[2]);
	}
	break;


    }

    Tcl_IncrRefCount(cmd);
    if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	Tcl_Preserve((ClientData) consoleInterp);
	result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
	Tcl_Release((ClientData) consoleInterp);
    } else {

	Tcl_AppendResult(interp, "no active console interp", NULL);

	result = TCL_ERROR;
    }
    Tcl_DecrRefCount(cmd);
    return result;
}

/*
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902
903
904
905
 */

static int
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 *const options[] = {"eval", "record", NULL};
    enum option {OTHER_EVAL, OTHER_RECORD};
    ConsoleInfo *info = (ConsoleInfo *)clientData;
    Tcl_Interp *otherInterp = info->interp;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "script");
	return TCL_ERROR;
    }

    if ((otherInterp == NULL) || Tcl_InterpDeleted(otherInterp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active parent interp", -1));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NO_INTERP", NULL);
	return TCL_ERROR;
    }

    Tcl_Preserve(otherInterp);
    switch ((enum option) index) {
    case OTHER_EVAL:
   	result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL);

	/*
	 * TODO: Should exceptions be filtered here?
	 */

	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);

	/*
	 * By not setting result, we discard any exceptions or errors here and
	 * always return TCL_OK. All the caller wants is the interp result to
	 * display, whether that's result or error message.
	 */

	Tcl_SetObjResult(interp, Tcl_GetObjResult(otherInterp));
	break;
    }
    Tcl_Release(otherInterp);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteConsoleInterp --
 *
 *	Thread exit handler to destroy a console interp when the thread it
 *	lives in gets torn down.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteConsoleInterp(
    ClientData clientData)
{
    Tcl_Interp *interp = (Tcl_Interp *)clientData;

    Tcl_DeleteInterp(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * InterpDeleteProc --
 *
 *	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 clientData,
    Tcl_Interp *interp)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp == interp) {
	Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp);

	info->consoleInterp = NULL;
    }
    if (info->refCount-- <= 1) {
	ckfree(info);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleDeleteProc --







|


|

|






|
|









|
<
<



|



<



<






<

|
|
|

<



|








|
|









<








|
|















|


|
>


|
|







760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790


791
792
793
794
795
796
797

798
799
800

801
802
803
804
805
806

807
808
809
810
811

812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
 */

static int
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};
    enum option {OTHER_EVAL, OTHER_RECORD};
    ConsoleInfo *info = (ConsoleInfo *) clientData;
    Tcl_Interp *otherInterp = info->interp;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "script");
	return TCL_ERROR;
    }

    if ((otherInterp == NULL) || Tcl_InterpDeleted(otherInterp)) {
	Tcl_AppendResult(interp, "no active master interp", NULL);


	return TCL_ERROR;
    }

    Tcl_Preserve((ClientData) otherInterp);
    switch ((enum option) index) {
    case OTHER_EVAL:
   	result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL);

	/*
	 * TODO: Should exceptions be filtered here?
	 */

	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);

	/*
	 * By not setting result, we discard any exceptions or errors here
	 * and always return TCL_OK.  All the caller wants is the
	 * interp result to display, whether that's result or error message.
	 */

	Tcl_SetObjResult(interp, Tcl_GetObjResult(otherInterp));
	break;
    }
    Tcl_Release((ClientData) otherInterp);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteConsoleInterp --
 *
 *	Thread exit handler to destroy a console interp when the
 *	thread it lives in gets torn down.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteConsoleInterp(
    ClientData clientData)
{
    Tcl_Interp *interp = (Tcl_Interp *)clientData;

    Tcl_DeleteInterp(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * InterpDeleteProc --
 *
 *	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 clientData,
    Tcl_Interp *interp)
{
    ConsoleInfo *info = (ConsoleInfo *) clientData;

    if (info->consoleInterp == interp) {
	Tcl_DeleteThreadExitHandler(DeleteConsoleInterp,
		(ClientData) info->consoleInterp);
	info->consoleInterp = NULL;
    }
    if (--info->refCount <= 0) {
	ckfree((char *) info);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleDeleteProc --
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
 *----------------------------------------------------------------------
 */

static void
ConsoleDeleteProc(
    ClientData clientData)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp) {
	Tcl_DeleteInterp(info->consoleInterp);
    }
    if (info->refCount-- <= 1) {
	ckfree(info);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleEventProc --
 *
 *	This event function is registered on the main window of the child
 *	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.
 *
 * Side effects:
 *	Invokes the "::tk::ConsoleExit" command in the console interp.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleEventProc(
    ClientData clientData,
    XEvent *eventPtr)
{
    if (eventPtr->type == DestroyNotify) {
	ConsoleInfo *info = (ConsoleInfo *)clientData;
	Tcl_Interp *consoleInterp = info->consoleInterp;

	if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	    Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL);
	}

	if (info->refCount-- <= 1) {
	    ckfree(info);
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




|
|








|



















|






|
|











886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
 *----------------------------------------------------------------------
 */

static void
ConsoleDeleteProc(
    ClientData clientData)
{
    ConsoleInfo *info = (ConsoleInfo *) clientData;

    if (info->consoleInterp) {
	Tcl_DeleteInterp(info->consoleInterp);
    }
    if (--info->refCount <= 0) {
	ckfree((char *) info);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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
 *	invoking "::tk::ConsoleExit".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Invokes the "::tk::ConsoleExit" command in the console interp.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleEventProc(
    ClientData clientData,
    XEvent *eventPtr)
{
    if (eventPtr->type == DestroyNotify) {
	ConsoleInfo *info = (ConsoleInfo *) clientData;
	Tcl_Interp *consoleInterp = info->consoleInterp;

	if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	    Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL);
	}

	if (--info->refCount <= 0) {
	    ckfree((char *) info);
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCursor.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 * 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 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 functions defined in this file:
 */

static void		CursorInit(TkDisplay *dispPtr);
static void		DupCursorObjProc(Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr);
static void		FreeCursor(TkCursor *cursorPtr);
static void		FreeCursorObj(Tcl_Obj *objPtr);
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
 * object, used for drawing. The color object remembers the hash table
 * entry associated with a color. The actual allocation and deallocation
 * of the color should be done by the configuration package when the cursor
 * option is set.
 */

Tcl_ObjType const tkCursorObjType = {
    "cursor",			/* name */
    FreeCursorObjProc,		/* freeIntRepProc */
    DupCursorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};








|
|















<

|
|











|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 * 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 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 functions defined in this file:
 */

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
 * object, used for drawing. The color object remembers the hash table
 * entry associated with a color. The actual allocation and deallocation
 * of the color should be done by the configuration package when the cursor
 * option is set.
 */

Tcl_ObjType tkCursorObjType = {
    "cursor",			/* name */
    FreeCursorObjProc,		/* freeIntRepProc */
    DupCursorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
				 * obj's string rep. */
{
    TkCursor *cursorPtr;

    if (objPtr->typePtr != &tkCursorObjType) {
	InitCursorObj(objPtr);
    }
    cursorPtr = (TkCursor *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkCursor, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (cursorPtr != NULL) {
	if (cursorPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkCursor that's no
	     * longer in use. Clear the reference.
	     */

	    FreeCursorObj(objPtr);
	    cursorPtr = NULL;
	} else if (Tk_Display(tkwin) == cursorPtr->display) {
	    cursorPtr->resourceRefCount++;
	    return cursorPtr->cursor;
	}
    }

    /*
     * The object didn't point to the TkCursor that we wanted. Search the list
     * of TkCursors with the same name to see if one of the other TkCursors is
     * the right one.
     */

    if (cursorPtr != NULL) {
	TkCursor *firstCursorPtr = (TkCursor *)Tcl_GetHashValue(cursorPtr->hashPtr);

	FreeCursorObj(objPtr);
	for (cursorPtr = firstCursorPtr;  cursorPtr != NULL;
		cursorPtr = cursorPtr->nextPtr) {
	    if (Tk_Display(tkwin) == cursorPtr->display) {
		cursorPtr->resourceRefCount++;
		cursorPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr;
		return cursorPtr->cursor;
	    }
	}
    }

    /*
     * Still no luck. Call TkcGetCursor to allocate a new TkCursor object.
     */

    cursorPtr = TkcGetCursor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr;
    if (cursorPtr == NULL) {
	return NULL;
    }
    cursorPtr->objRefCount++;
    return cursorPtr->cursor;
}








|













|














|
|
|





|










|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
				 * obj's string rep. */
{
    TkCursor *cursorPtr;

    if (objPtr->typePtr != &tkCursorObjType) {
	InitCursorObj(objPtr);
    }
    cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkCursor, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (cursorPtr != NULL) {
	if (cursorPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkCursor that's no
	     * longer in use. Clear the reference.
	     */

	    FreeCursorObjProc(objPtr);
	    cursorPtr = NULL;
	} else if (Tk_Display(tkwin) == cursorPtr->display) {
	    cursorPtr->resourceRefCount++;
	    return cursorPtr->cursor;
	}
    }

    /*
     * The object didn't point to the TkCursor that we wanted. Search the list
     * of TkCursors with the same name to see if one of the other TkCursors is
     * the right one.
     */

    if (cursorPtr != NULL) {
	TkCursor *firstCursorPtr = (TkCursor *)
		Tcl_GetHashValue(cursorPtr->hashPtr);
	FreeCursorObjProc(objPtr);
	for (cursorPtr = firstCursorPtr;  cursorPtr != NULL;
		cursorPtr = cursorPtr->nextPtr) {
	    if (Tk_Display(tkwin) == cursorPtr->display) {
		cursorPtr->resourceRefCount++;
		cursorPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
		return cursorPtr->cursor;
	    }
	}
    }

    /*
     * Still no luck. Call TkcGetCursor to allocate a new TkCursor object.
     */

    cursorPtr = TkcGetCursor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
    if (cursorPtr == NULL) {
	return NULL;
    }
    cursorPtr->objRefCount++;
    return cursorPtr->cursor;
}

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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) {
	return NULL;
    }
    return cursorPtr->cursor;
}

/*







<







183
184
185
186
187
188
189

190
191
192
193
194
195
196
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) {
	return NULL;
    }
    return cursorPtr->cursor;
}

/*
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 *----------------------------------------------------------------------
 */

static TkCursor *
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;
    TkCursor *cursorPtr;
    TkCursor *existingCursorPtr = NULL;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable,
	    string, &isNew);
    if (!isNew) {
	existingCursorPtr = (TkCursor *)Tcl_GetHashValue(nameHashPtr);
	for (cursorPtr = existingCursorPtr; cursorPtr != NULL;
		cursorPtr = cursorPtr->nextPtr) {
	    if (Tk_Display(tkwin) == cursorPtr->display) {
		cursorPtr->resourceRefCount++;
		return cursorPtr;
	    }
	}







|



|









|

|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 *----------------------------------------------------------------------
 */

static TkCursor *
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 isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable,
            string, &isNew);
    if (!isNew) {
	existingCursorPtr = (TkCursor *) Tcl_GetHashValue(nameHashPtr);
	for (cursorPtr = existingCursorPtr; cursorPtr != NULL;
		cursorPtr = cursorPtr->nextPtr) {
	    if (Tk_Display(tkwin) == cursorPtr->display) {
		cursorPtr->resourceRefCount++;
		return cursorPtr;
	    }
	}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
    cursorPtr->display = Tk_Display(tkwin);
    cursorPtr->resourceRefCount = 1;
    cursorPtr->objRefCount = 0;
    cursorPtr->otherTable = &dispPtr->cursorNameTable;
    cursorPtr->hashPtr = nameHashPtr;
    cursorPtr->nextPtr = existingCursorPtr;
    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);

    return cursorPtr;







|







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
    cursorPtr->display = Tk_Display(tkwin);
    cursorPtr->resourceRefCount = 1;
    cursorPtr->objRefCount = 0;
    cursorPtr->otherTable = &dispPtr->cursorNameTable;
    cursorPtr->hashPtr = nameHashPtr;
    cursorPtr->nextPtr = existingCursorPtr;
    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);

    return cursorPtr;
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
 *----------------------------------------------------------------------
 */

Tk_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;
    TkCursor *cursorPtr;
    int isNew;
    XColor fgColor, bgColor;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }

    dataKey.source = source;
    dataKey.mask = mask;
    dataKey.width = width;
    dataKey.height = height;
    dataKey.xHot = xHot;
    dataKey.yHot = yHot;
    dataKey.fg = fg;
    dataKey.bg = bg;
    dataKey.display = Tk_Display(tkwin);
    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.
     */

    if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid color name \"%s\"", fg));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", "COLOR", NULL);
	goto error;
    }
    if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid color name \"%s\"", bg));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", "COLOR", NULL);
	goto error;
    }

    cursorPtr = TkCreateCursorFromData(tkwin, source, mask, width, height,
	    xHot, yHot, fgColor, bgColor);

    if (cursorPtr == NULL) {
	goto error;
    }

    cursorPtr->resourceRefCount = 1;
    cursorPtr->otherTable = &dispPtr->cursorDataTable;
    cursorPtr->hashPtr = dataHashPtr;
    cursorPtr->objRefCount = 0;
    cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
	    (char *) cursorPtr->cursor, &isNew);
    cursorPtr->nextPtr = NULL;

    if (!isNew) {
	Tcl_Panic("cursor already registered in Tk_GetCursorFromData");
    }
    Tcl_SetHashValue(dataHashPtr, cursorPtr);
    Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr);







|
|







|


















|

|










<
|
<



<
|
<















|







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353

354
355
356

357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
 *----------------------------------------------------------------------
 */

Tk_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 isNew;
    XColor fgColor, bgColor;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }

    dataKey.source = source;
    dataKey.mask = mask;
    dataKey.width = width;
    dataKey.height = height;
    dataKey.xHot = xHot;
    dataKey.yHot = yHot;
    dataKey.fg = fg;
    dataKey.bg = bg;
    dataKey.display = Tk_Display(tkwin);
    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.
     */

    if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {

	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, "\"", NULL);

	goto error;
    }

    cursorPtr = TkCreateCursorFromData(tkwin, source, mask, width, height,
	    xHot, yHot, fgColor, bgColor);

    if (cursorPtr == NULL) {
	goto error;
    }

    cursorPtr->resourceRefCount = 1;
    cursorPtr->otherTable = &dispPtr->cursorDataTable;
    cursorPtr->hashPtr = dataHashPtr;
    cursorPtr->objRefCount = 0;
    cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
            (char *) cursorPtr->cursor, &isNew);
    cursorPtr->nextPtr = NULL;

    if (!isNew) {
	Tcl_Panic("cursor already registered in Tk_GetCursorFromData");
    }
    Tcl_SetHashValue(dataHashPtr, cursorPtr);
    Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr);
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOfCursor(
    Display *display,		/* Display for which cursor was allocated. */
    Tk_Cursor cursor)		/* Identifier for cursor whose name is
				 * wanted. */
{
    Tcl_HashEntry *idHashPtr;
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	sprintf(dispPtr->cursorString, "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);
    if (cursorPtr->otherTable != &dispPtr->cursorNameTable) {
	goto printid;
    }
    return cursorPtr->hashPtr->key.string;
}

/*







|













|


|



|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfCursor(
    Display *display,		/* Display for which cursor was allocated. */
    Tk_Cursor cursor)		/* Identifier for cursor whose name is
				 * wanted. */
{
    Tcl_HashEntry *idHashPtr;
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	sprintf(dispPtr->cursorString, "cursor id %p", cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *) Tcl_GetHashValue(idHashPtr);
    if (cursorPtr->otherTable != &dispPtr->cursorNameTable) {
	goto printid;
    }
    return cursorPtr->hashPtr->key.string;
}

/*
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

static void
FreeCursor(
    TkCursor *cursorPtr)	/* Cursor to be released. */
{
    TkCursor *prevPtr;


    if (cursorPtr->resourceRefCount-- > 1) {
	return;
    }

    Tcl_DeleteHashEntry(cursorPtr->idHashPtr);
    prevPtr = (TkCursor *)Tcl_GetHashValue(cursorPtr->hashPtr);
    if (prevPtr == cursorPtr) {
	if (cursorPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(cursorPtr->hashPtr);
	} else {
	    Tcl_SetHashValue(cursorPtr->hashPtr, cursorPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != cursorPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = cursorPtr->nextPtr;
    }
    TkpFreeCursor(cursorPtr);
    if (cursorPtr->objRefCount == 0) {
	ckfree(cursorPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeCursor --







>
|




|














|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

static void
FreeCursor(
    TkCursor *cursorPtr)	/* Cursor to be released. */
{
    TkCursor *prevPtr;

    cursorPtr->resourceRefCount--;
    if (cursorPtr->resourceRefCount > 0) {
	return;
    }

    Tcl_DeleteHashEntry(cursorPtr->idHashPtr);
    prevPtr = (TkCursor *) Tcl_GetHashValue(cursorPtr->hashPtr);
    if (prevPtr == cursorPtr) {
	if (cursorPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(cursorPtr->hashPtr);
	} else {
	    Tcl_SetHashValue(cursorPtr->hashPtr, cursorPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != cursorPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = cursorPtr->nextPtr;
    }
    TkpFreeCursor(cursorPtr);
    if (cursorPtr->objRefCount == 0) {
	ckfree((char *) cursorPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeCursor --
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
	Tcl_Panic("Tk_FreeCursor called before Tk_GetCursor");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
    }
    FreeCursor((TkCursor *)Tcl_GetHashValue(idHashPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeCursorFromObj --
 *







|



|







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
	Tcl_Panic("Tk_FreeCursor called before Tk_GetCursor");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
    }
    FreeCursor((TkCursor *) Tcl_GetHashValue(idHashPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeCursorFromObj --
 *
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
void
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));
    FreeCursorObj(objPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeCursorObjProc, FreeCursorObj --
 *
 *	This proc is called to release an object reference to a cursor.
 *	Called when the object's internal rep is released or when the cached
 *	tkColPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeCursorObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    FreeCursorObj(objPtr);
    objPtr->typePtr = NULL;
}

static void
FreeCursorObj(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    TkCursor *cursorPtr = (TkCursor *)objPtr->internalRep.twoPtrValue.ptr1;

    if (cursorPtr != NULL) {

	if ((cursorPtr->objRefCount-- <= 1)
		&& (cursorPtr->resourceRefCount == 0)) {
	    ckfree(cursorPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------







|





|



















<
<
<
<
<
<
<
<
|


>
|

|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575








576
577
578
579
580
581
582
583
584
585
586
587
588
589
void
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);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeCursorFromObjProc --
 *
 *	This proc is called to release an object reference to a cursor.
 *	Called when the object's internal rep is released or when the cached
 *	tkColPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeCursorObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{








    TkCursor *cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1;

    if (cursorPtr != NULL) {
	cursorPtr->objRefCount--;
	if ((cursorPtr->objRefCount == 0)
		&& (cursorPtr->resourceRefCount == 0)) {
	    ckfree((char *) cursorPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
 */

static void
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 = cursorPtr;

    if (cursorPtr != NULL) {
	cursorPtr->objRefCount++;
    }
}

/*







|


|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
 */

static void
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;

    if (cursorPtr != NULL) {
	cursorPtr->objRefCount++;
    }
}

/*
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    /*
     * 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;
    }

    /*
     * If we get to here, it means the cursor we need is not in the cache.
     * Try to look up the cursor in the TkDisplay structure of the window.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable,
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (cursorPtr = (TkCursor *)Tcl_GetHashValue(hashPtr);
	    cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) {
	if (Tk_Display(tkwin) == cursorPtr->display) {
	    FreeCursorObj(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr;
	    cursorPtr->objRefCount++;
	    return cursorPtr;
	}
    }

  error:
    Tcl_Panic("GetCursorFromObj called with non-existent cursor!");







|














|


|
|







689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    /*
     * 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;
    }

    /*
     * If we get to here, it means the cursor we need is not in the cache.
     * Try to look up the cursor in the TkDisplay structure of the window.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable,
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr);
	    cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) {
	if (Tk_Display(tkwin) == cursorPtr->display) {
	    FreeCursorObjProc(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
	    cursorPtr->objRefCount++;
	    return cursorPtr;
	}
    }

  error:
    Tcl_Panic("GetCursorFromObj called with non-existent cursor!");
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkCursorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------







|







753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->typePtr = &tkCursorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugCursor(
    Tk_Window tkwin,		/* The window in which the cursor will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{
    TkCursor *cursorPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }
    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable, name);
    if (hashPtr != NULL) {
	cursorPtr = (TkCursor *)Tcl_GetHashValue(hashPtr);
	if (cursorPtr == NULL) {
	    Tcl_Panic("TkDebugCursor found empty hash table entry");
	}
	for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(cursorPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(cursorPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|












|






|

|













826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
 *----------------------------------------------------------------------
 */

Tcl_Obj *
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;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->cursorInit) {
	CursorInit(dispPtr);
    }
    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable, name);
    if (hashPtr != NULL) {
	cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr);
	if (cursorPtr == NULL) {
	    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_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Deleted generic/tkDList.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
/*
 * tkDList.h --
 *
 * A list is headed by pointers to first and last element. The elements
 * are doubly linked so that an arbitrary element can be removed without
 * a need to traverse the list. New elements can be added to the list
 * before or after an existing element or at the head/tail of the list.
 * A list may be traversed in the forward or backward direction.
 *
 * Copyright (c) 2018 by Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Note that this file will not be included in header files, it is the purpose
 * of this file to be included in source files only. Thus we are not using the
 * prefix "Tk_" here for functions, because all the functions have private scope.
 */

/*
 * -------------------------------------------------------------------------------
 * Use the double linked list in the following way:
 * -------------------------------------------------------------------------------
 * typedef struct MyListEntry { TK_DLIST_LINKS(MyListEntry); int value; } MyListEntry;
 * TK_DLIST_DEFINE(MyList, MyListEntry);
 * MyList listHdr = TK_DLIST_LIST_INITIALIZER; // or MyList_Init(&listHdr)
 * MyListEntry *p;
 * int i = 0;
 * MyList_Append(&listHdr, (MyListEntry *)ckalloc(sizeof(MyListEntry)));
 * MyList_Append(&listHdr, (MyListEntry *)ckalloc(sizeof(MyListEntry)));
 * TK_DLIST_FOREACH(p, &listHdr) { p->value = i++; }
 * // ...
 * MyList_RemoveHead(&listHdr);
 * MyList_RemoveHead(&listHdr);
 * MyList_Clear(MyListEntry, &listHdr); // invokes ckfree() for each element
 * -------------------------------------------------------------------------------
 * IMPORTANT NOTE: TK_DLIST_LINKS must be used at start of struct!
 */

#ifndef TK_DLIST_DEFINED
#define TK_DLIST_DEFINED

#include "tkInt.h"

/*
 * List definitions.
 */

#define TK_DLIST_LINKS(ElemType)						\
struct {									\
    struct ElemType *prev;	/* previous element */				\
    struct ElemType *next;	/* next element */				\
} _dl_

#define TK_DLIST_LIST_INITIALIZER { NULL, NULL }
#define TK_DLIST_ELEM_INITIALIZER { NULL, NULL }

/*************************************************************************/
/*
 * DList_Init: Initialize list header. This can also be used to clear the
 * list.
 *
 * See also: DList_Clear()
 */
/*************************************************************************/
/*
 * DList_ElemInit: Initialize a list element.
 */
/*************************************************************************/
/*
 * DList_InsertAfter: Insert 'elem' after 'listElem'. 'elem' must not
 * be linked, but 'listElem' must be linked.
 */
/*************************************************************************/
/*
 * DList_InsertBefore: Insert 'elem' before 'listElem'. 'elem' must not
 * be linked, but 'listElem' must be linked.
 */
/*************************************************************************/
/*
 * DList_Prepend: Insert 'elem' at start of list. This element must not
 * be linked.
 *
 * See also: DList_Append()
 */
/*************************************************************************/
/*
 * DList_Append: Append 'elem' to end of list. This element must not
 * be linked.
 *
 * See also: DList_Prepend()
 */
/*************************************************************************/
/*
 * DList_Move: Append all list items of 'src' to end of 'dst'.
 */
/*************************************************************************/
/*
 * DList_Remove: Remove 'elem' from list. This element must be linked.
 *
 * See also: DList_Free()
 */
/*************************************************************************/
/*
 * DList_Free: Remove 'elem' from list and free it. This element must
 * be linked.
 *
 * See also: DList_Remove()
 */
/*************************************************************************/
/*
 * DList_RemoveHead: Remove first element from list. The list must
 * not be empty.
 *
 * See also: DList_FreeHead()
 */
/*************************************************************************/
/*
 * DList_RemoveTail: Remove last element from list. The list must
 * not be empty.
 *
 * See also: DList_FreeTail()
 */
/*************************************************************************/
/*
 * DList_FreeHead: Remove first element from list and free it.
 * The list must not be empty.
 *
 * See also: DList_RemoveHead()
 */
/*************************************************************************/
/*
 * DList_FreeTail: Remove last element from list and free it.
 * The list must not be empty.
 *
 * See also: DList_RemoveTail()
 */
/*************************************************************************/
/*
 * DList_SwapElems: Swap positions of given elements 'lhs' and 'rhs'.
 * Both elements must be linked, and must belong to same list.
 */
/*************************************************************************/
/*
 * DList_Clear: Clear whole list and free all elements.
 *
 * See also: DList_Init
 */
/*************************************************************************/
/*
 * DList_Traverse: Iterate over all elements in list from first to last.
 * Call given function func(head, elem) for each element. The function has
 * to return the next element in list to traverse, normally this is
 * DList_Next(elem).
 *
 * See also: TK_DLIST_FOREACH, TK_DLIST_FOREACH_REVERSE
 */
/*************************************************************************/
/*
 * DList_First: Return pointer of first element in list, maybe it's NULL.
 */
/*************************************************************************/
/*
 * DList_Last: Return pointer of last element in list, maybe it's NULL.
 */
/*************************************************************************/
/*
 * DList_Next: Return pointer of next element after 'elem', maybe it's NULL.
 *
 * See also: DList_Prev()
 */
/*************************************************************************/
/*
 * DList_Prev: Return pointer of previous element before 'elem', maybe it's
 * NULL.
 *
 * See also: DList_Next()
 */
/*************************************************************************/
/*
 * DList_IsEmpty: Test whether given list is empty.
 */
/*************************************************************************/
/*
 * DList_IsLinked: Test whether given element is linked.
 */
/*************************************************************************/
/*
 * DList_IsFirst: Test whether given element is first element in list.
 * Note that 'elem' must be linked.
 *
 * See also: DList_IsLast(), DList_IsLinked()
 */
/*************************************************************************/
/*
 * DList_IsLast: Test whether given element is last element in list.
 * Note that 'elem' must be linked.
 *
 * See also: DList_IsFirst(), DList_IsLinked()
 */
/*************************************************************************/
/*
 * DList_Size: Count number of elements in given list.
 */
/*************************************************************************/
/*
 * TK_DLIST_FOREACH: Iterate over all elements in list from first to last.
 * 'var' is the name of the variable which points to current element.
 *
 * See also: TK_DLIST_FOREACH_REVERSE, DList_Traverse()
 */
/*************************************************************************/
/*
 * TK_DLIST_FOREACH_REVERSE: Iterate over all elements in list from last
 * to first (backwards). 'var' is the name of the variable which points to
 * current element.
 */
/*************************************************************************/

#if defined(__GNUC__) || defined(__clang__)
# define __TK_DLIST_UNUSED __attribute__((unused))
#else
# define __TK_DLIST_UNUSED
#endif

#define TK_DLIST_DEFINE(LT, ElemType) /* LT = type of head/list */		\
/* ------------------------------------------------------------------------- */	\
typedef struct LT {								\
    struct ElemType *first;	/* first element */				\
    struct ElemType *last;	/* last element */				\
} LT;										\
										\
typedef struct ElemType *(LT##_Func)(LT *head, struct ElemType *elem);		\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Init(LT *head)								\
{										\
    assert(head);								\
    head->first = NULL;								\
    head->last = NULL;								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_ElemInit(struct ElemType *elem)						\
{										\
    assert(elem);								\
    elem->_dl_.next = NULL;							\
    elem->_dl_.prev = NULL;							\
}										\
										\
__TK_DLIST_UNUSED								\
static int									\
LT##_IsEmpty(LT *head)								\
{										\
    assert(head);								\
    return head->first == NULL;							\
}										\
										\
__TK_DLIST_UNUSED								\
static int									\
LT##_IsLinked(struct ElemType *elem)						\
{										\
    assert(elem);								\
    return elem->_dl_.next && elem->_dl_.prev;					\
}										\
										\
__TK_DLIST_UNUSED								\
static int									\
LT##_IsFirst(struct ElemType *elem)						\
{										\
    assert(LT##_IsLinked(elem));						\
    return elem->_dl_.prev->_dl_.prev == elem;					\
}										\
										\
__TK_DLIST_UNUSED								\
static int									\
LT##_IsLast(struct ElemType *elem)						\
{										\
    assert(LT##_IsLinked(elem));						\
    return elem->_dl_.next->_dl_.next == elem;					\
}										\
										\
__TK_DLIST_UNUSED								\
static struct ElemType *							\
LT##_First(LT *head)								\
{										\
    assert(head);								\
    return head->first;								\
}										\
										\
__TK_DLIST_UNUSED								\
static struct ElemType *							\
LT##_Last(LT *head)								\
{										\
    assert(head);								\
    return head->last;								\
}										\
										\
__TK_DLIST_UNUSED								\
static struct ElemType *							\
LT##_Next(struct ElemType *elem)						\
{										\
    assert(elem);								\
    return LT##_IsLast(elem) ? NULL : elem->_dl_.next;				\
}										\
										\
__TK_DLIST_UNUSED								\
static struct ElemType *							\
LT##_Prev(struct ElemType *elem)						\
{										\
    assert(elem);								\
    return LT##_IsFirst(elem) ? NULL : elem->_dl_.prev;				\
}										\
										\
__TK_DLIST_UNUSED								\
static unsigned									\
LT##_Size(const LT *head)							\
{										\
    const struct ElemType *elem;						\
    unsigned size = 0;								\
    assert(head);								\
    if ((elem = head->first)) {							\
	for ( ; elem != (void *) head; elem = elem->_dl_.next) {		\
	    ++size;								\
	}									\
    }										\
    return size;								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_InsertAfter(struct ElemType *listElem, struct ElemType *elem)		\
{										\
    assert(listElem);								\
    assert(elem);								\
    elem->_dl_.next = listElem->_dl_.next;					\
    elem->_dl_.prev = listElem;							\
    listElem->_dl_.next->_dl_.prev = elem;					\
    listElem->_dl_.next = elem;							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_InsertBefore(struct ElemType *listElem, struct ElemType *elem)		\
{										\
    assert(listElem);								\
    assert(elem);								\
    elem->_dl_.next = listElem;							\
    elem->_dl_.prev = listElem->_dl_.prev;;					\
    listElem->_dl_.prev->_dl_.next = elem;					\
    listElem->_dl_.prev = elem;							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Prepend(LT *head, struct ElemType *elem)					\
{										\
    assert(head);								\
    assert(elem);								\
    elem->_dl_.prev = (PSEntry *) head;						\
    if (!head->first) {								\
	elem->_dl_.next = (PSEntry *) head;					\
	head->last = elem;							\
    } else {									\
	elem->_dl_.next = head->first;						\
	head->first->_dl_.prev = elem;						\
    }										\
    head->first = elem;								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Append(LT *head, struct ElemType *elem)					\
{										\
    assert(head);								\
    assert(elem);								\
    elem->_dl_.next = (PSEntry *) head;						\
    if (!head->first) {								\
	elem->_dl_.prev = (PSEntry *) head;					\
	head->first = elem;							\
    } else {									\
	elem->_dl_.prev = head->last;						\
	head->last->_dl_.next = elem;						\
    }										\
    head->last = elem;								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Move(LT *dst, LT *src)							\
{										\
    assert(dst);								\
    assert(src);								\
    if (src->first) {								\
	if (dst->first) {							\
	    dst->last->_dl_.next = src->first;					\
	    src->first->_dl_.prev = dst->last;					\
	    dst->last = src->last;						\
	} else {								\
	    *dst = *src;							\
	    dst->first->_dl_.prev = (PSEntry *) dst;				\
	}									\
	dst->last->_dl_.next = (PSEntry *) dst;					\
	LT##_Init(src);								\
    }										\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Remove(struct ElemType *elem)						\
{										\
    int isFirst, isLast;							\
    assert(LT##_IsLinked(elem));						\
    isFirst = LT##_IsFirst(elem);						\
    isLast = LT##_IsLast(elem);							\
    if (isFirst && isLast) {							\
	((LT *) elem->_dl_.prev)->first = NULL;					\
	((LT *) elem->_dl_.next)->last = NULL;					\
    } else {									\
	if (isFirst) {								\
	    ((LT *) elem->_dl_.prev)->first = elem->_dl_.next;			\
	} else {								\
	    elem->_dl_.prev->_dl_.next = elem->_dl_.next;			\
	}									\
	if (isLast) {								\
	    ((LT *) elem->_dl_.next)->last = elem->_dl_.prev;			\
	} else {								\
	    elem->_dl_.next->_dl_.prev = elem->_dl_.prev;			\
	}									\
    }										\
    LT##_ElemInit(elem);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Free(struct ElemType *elem)						\
{										\
    LT##_Remove(elem);								\
    ckfree((void *) elem);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_RemoveHead(LT *head)							\
{										\
    assert(!LT##_IsEmpty(head));						\
    LT##_Remove(head->first);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_RemoveTail(LT *head)							\
{										\
    assert(!LT##_IsEmpty(head));						\
    LT##_Remove(head->last);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_FreeHead(LT *head)								\
{										\
    assert(!LT##_IsEmpty(head));						\
    LT##_Free(head->first);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_FreeTail(LT *head)								\
{										\
    assert(!LT##_IsEmpty(head));						\
    LT##_Free(head->last);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_SwapElems(struct ElemType *lhs, struct ElemType *rhs)			\
{										\
    assert(lhs);								\
    assert(rhs);								\
    if (lhs != rhs) {								\
	struct ElemType tmp;							\
	if (LT##_IsFirst(lhs))  {						\
	    ((LT *) lhs->_dl_.prev)->first = rhs;				\
	} else if (LT##_IsFirst(rhs)) {						\
	    ((LT *) rhs->_dl_.prev)->first = lhs;				\
	}									\
	if (LT##_IsLast(lhs))  {						\
	    ((LT *) lhs->_dl_.next)->last = rhs;				\
	} else if (LT##_IsLast(rhs)) {						\
	    ((LT *) rhs->_dl_.next)->last = lhs;				\
	}									\
	tmp._dl_ = lhs->_dl_;							\
	lhs->_dl_ = rhs->_dl_;							\
	rhs->_dl_ = tmp._dl_;							\
    }										\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Clear(LT *head)								\
{										\
    struct ElemType *p;								\
    struct ElemType *next;							\
    assert(head);								\
    for (p = head->first; p; p = next) {					\
	next = LT##_Next(p);							\
	ckfree((void *) p);							\
    }										\
    LT##_Init(head);								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Traverse(LT *head, LT##_Func func)						\
{										\
    struct ElemType *next;							\
    struct ElemType *p;								\
    assert(head);								\
    for (p = head->first; p; p = next) {					\
	next = func(head, p);							\
    }										\
}										\
/* ------------------------------------------------------------------------- */

#define TK_DLIST_FOREACH(var, head)						\
    assert(head);								\
    for (var = head->first ? head->first : (PSEntry *) head; var != (PSEntry *) head; var = var->_dl_.next)

#define TK_DLIST_FOREACH_REVERSE(var, head)					\
    assert(head);								\
    for (var = head->last ? head->last : (PSEntry *) head; var != (PSEntry *) head; var = var->_dl_.prev)

#endif /* TK_DLIST_DEFINED */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkDecls.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43


44
45



46
47



48
49
50



51
52
53
54
55



56
57
58
59
60



61
62
63



64
65
66
67



68
69
70
71



72
73
74



75
76
77
78



79
80



81
82
83
84



85
86
87



88
89
90



91
92
93



94
95
96



97
98



99
100



101
102
103
104



105
106
107
108



109
110



111
112
113
114



115
116
117
118



119
120
121
122



123
124



125
126
127
128



129
130
131



132
133
134
135



136
137
138
139
140



141
142
143
144
145



146
147
148
149



150
151
152
153
154



155
156
157



158
159
160
161
162



163
164



165
166
167
168
169



170
171
172
173



174
175
176



177
178



179
180



181
182
183



184
185
186
187



188
189
190



191
192
193
194



195
196
197



198
199



200
201
202



203
204
205
206



207
208



209
210



211
212
213
214



215
216
217



218
219



220
221
222



223
224



225
226



227
228
229



230
231
232
233
234



235
236
237
238
239



240
241
242
243



244
245
246



247
248
249
250
251



252
253
254
255
256



257
258
259
260
261



262
263
264



265
266



267
268



269
270



271
272



273
274



275
276



277
278



279
280



281
282



283
284
285
286


287
288



289
290



291
292
293



294
295



296
297
298



299
300
301



302
303
304
305



306
307
308



309
310



311
312
313
314



315
316
317



318
319
320
321



322
323
324



325
326
327



328
329



330
331
332



333
334
335



336
337
338
339
340



341
342
343



344
345



346
347
348



349
350
351



352
353
354
355
356



357
358
359
360



361
362



363
364
365



366
367
368



369
370



371
372
373



374
375
376



377
378
379



380
381
382



383
384
385



386
387
388
389



390
391
392



393
394
395
396



397
398



399
400
401
402



403
404
405



406
407
408



409
410



411
412



413
414
415
416



417
418



419
420



421
422
423



424
425
426
427



428
429



430
431



432
433
434
435



436
437



438
439
440
441



442
443
444



445
446



447
448



449
450



451
452



453
454



455
456



457
458



459
460




461
462



463
464



465
466



467
468



469
470



471
472
473



474
475
476



477
478
479
480



481
482
483
484
485



486
487
488
489
490
491
492



493
494
495



496
497



498
499
500
501



502
503
504



505
506
507
508



509
510



511
512
513



514
515
516



517
518
519



520
521
522
523
524



525
526
527



528
529
530



531
532
533



534
535



536
537



538
539
540



541
542



543
544
545



546
547



548
549
550



551
552
553



554
555
556



557
558



559
560
561



562
563
564



565
566
567



568
569
570



571
572
573



574
575



576
577
578



579
580
581



582
583



584
585
586
587
588



589
590
591
592
593



594
595



596
597
598



599
600



601
602



603
604
605



606
607
608



609
610
611



612
613
614



615
616
617



618
619
620



621
622
623



624
625



626
627
628



629
630
631



632
633



634
635
636



637
638



639
640
641



642
643



644
645
646



647
648
649



650
651



652
653



654
655



656
657
658
659



660
661
662
663



664
665
666



667
668
669



670
671
672
673



674
675
676



677
678
679
680



681
682
683



684
685
686
687



688
689



690
691
692
693
694



695
696



697
698



699
700
701

702
703


704
705
706



707
708



709
710
711



712
713
714
715



716
717
718



719
720
721



722
723
724



725
726



727
728
729
730



731
732
733



734
735
736



737
738
739
740
741



742
743
744



745
746
747



748
749
750
751
752



753
754
755
756



757
758
759
760



761
762



763
764
765
766
767



768
769
770



771
772
773



774
775
776



777
778
779
780



781
782
783



784
785
786



787
788
789



790
791
792
793
794



795
796
797
798
799
800



801
802
803



804
805
806



807
808



809
810
811



812
813



814
815
816



817
818



819
820



821
822



823
824
825



826
827



828
829



830
831
832



833
834
835
836
837



838
839
840
841
842
843



844
845
846
847



848
849
850
851
852



853
854
855



856
857
858
859
860



861
862
863
864
865
866



867
868
869



870
871



872
873



874
875



876
877



878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893



894
895

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201

1202
1203


1204
1205


1206
1207


1208
1209


1210
1211


1212
1213


1214
1215


1216
1217


1218
1219


1220
1221


1222
1223


1224
1225


1226
1227


1228
1229


1230
1231


1232
1233


1234
1235


1236
1237


1238
1239


1240
1241


1242
1243


1244
1245


1246
1247


1248
1249


1250
1251


1252
1253


1254
1255


1256
1257


1258
1259


1260
1261


1262
1263


1264
1265


1266
1267


1268
1269


1270
1271


1272
1273


1274
1275


1276
1277


1278
1279


1280
1281


1282
1283


1284
1285


1286
1287


1288
1289


1290
1291


1292
1293


1294
1295


1296
1297


1298
1299


1300
1301


1302
1303


1304
1305


1306
1307


1308
1309


1310
1311


1312
1313


1314
1315


1316
1317


1318
1319


1320
1321


1322
1323


1324
1325


1326
1327


1328
1329


1330
1331


1332
1333


1334
1335


1336
1337


1338
1339


1340
1341


1342
1343


1344
1345


1346
1347


1348
1349


1350
1351


1352
1353


1354
1355


1356
1357


1358
1359


1360
1361


1362
1363


1364
1365


1366
1367


1368
1369


1370
1371


1372
1373


1374
1375


1376
1377


1378
1379


1380
1381


1382
1383


1384
1385


1386
1387


1388
1389


1390
1391


1392
1393


1394
1395


1396
1397


1398
1399


1400
1401


1402
1403


1404
1405


1406
1407


1408
1409


1410
1411


1412
1413


1414
1415


1416
1417


1418
1419


1420
1421


1422
1423


1424
1425


1426
1427


1428
1429


1430
1431


1432
1433


1434
1435


1436
1437


1438
1439


1440
1441


1442
1443


1444
1445


1446
1447


1448
1449


1450
1451


1452
1453


1454
1455


1456
1457


1458
1459


1460
1461


1462
1463


1464
1465


1466
1467


1468
1469


1470
1471


1472
1473


1474
1475


1476
1477


1478
1479


1480
1481


1482
1483


1484
1485


1486
1487


1488
1489


1490
1491


1492
1493


1494
1495


1496
1497


1498
1499


1500
1501


1502
1503


1504
1505


1506
1507


1508
1509


1510
1511


1512
1513


1514
1515


1516
1517


1518
1519


1520
1521


1522
1523


1524
1525


1526
1527


1528
1529


1530
1531


1532
1533


1534
1535


1536
1537


1538
1539


1540
1541


1542
1543


1544
1545


1546
1547


1548
1549


1550
1551


1552
1553


1554
1555


1556
1557


1558
1559


1560
1561


1562
1563


1564
1565


1566
1567


1568
1569


1570
1571


1572
1573


1574
1575


1576
1577


1578
1579


1580
1581


1582
1583


1584
1585


1586
1587


1588
1589


1590
1591


1592
1593


1594
1595


1596
1597


1598
1599


1600
1601


1602
1603


1604
1605


1606
1607


1608
1609


1610
1611


1612
1613


1614
1615


1616
1617


1618
1619


1620
1621


1622
1623


1624
1625


1626
1627


1628
1629


1630
1631


1632
1633


1634
1635


1636
1637

1638
1639

1640
1641


1642
1643


1644
1645


1646
1647


1648
1649


1650
1651


1652
1653


1654
1655


1656
1657


1658
1659


1660
1661


1662
1663


1664
1665


1666
1667


1668
1669


1670
1671


1672
1673


1674
1675


1676
1677


1678
1679


1680
1681


1682
1683


1684
1685


1686
1687


1688
1689


1690
1691


1692
1693


1694
1695


1696
1697


1698
1699


1700
1701


1702
1703


1704
1705


1706
1707


1708
1709


1710
1711


1712
1713


1714
1715


1716
1717


1718
1719


1720
1721


1722
1723


1724
1725


1726
1727


1728
1729


1730
1731


1732
1733


1734
1735


1736
1737


1738
1739


1740
1741


1742
1743


1744
1745


1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
1792
1793
1794

1795
1796
1797
1798


1799

#define _TKDECLS

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

#if !defined(BUILD_tk)
# define TK_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg)
#elif defined(TK_NO_DEPRECATED)
# define TK_DEPRECATED(msg) MODULE_SCOPE
#else
# define TK_DEPRECATED(msg) EXTERN
#endif

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */



/* 0 */
EXTERN void		Tk_MainLoop(void);



/* 1 */
EXTERN XColor *		Tk_3DBorderColor(Tk_3DBorder border);



/* 2 */
EXTERN GC		Tk_3DBorderGC(Tk_Window tkwin, Tk_3DBorder border,
				int which);



/* 3 */
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);



/* 4 */
EXTERN void		Tk_3DVerticalBevel(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height, int leftBevel,
				int relief);



/* 5 */
EXTERN void		Tk_AddOption(Tk_Window tkwin, const char *name,
				const char *value, int priority);



/* 6 */
EXTERN void		Tk_BindEvent(Tk_BindingTable bindingTable,
				XEvent *eventPtr, Tk_Window tkwin,
				int numObjects, ClientData *objectPtr);



/* 7 */
EXTERN void		Tk_CanvasDrawableCoords(Tk_Canvas canvas, double x,
				double y, short *drawableXPtr,
				short *drawableYPtr);



/* 8 */
EXTERN void		Tk_CanvasEventuallyRedraw(Tk_Canvas canvas, int x1,
				int y1, int x2, int y2);



/* 9 */
EXTERN int		Tk_CanvasGetCoord(Tcl_Interp *interp,
				Tk_Canvas canvas, const char *str,
				double *doublePtr);



/* 10 */
EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo(Tk_Canvas canvas);



/* 11 */
EXTERN int		Tk_CanvasPsBitmap(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap, int x,
				int y, int width, int height);



/* 12 */
EXTERN int		Tk_CanvasPsColor(Tcl_Interp *interp,
				Tk_Canvas canvas, XColor *colorPtr);



/* 13 */
EXTERN int		Tk_CanvasPsFont(Tcl_Interp *interp, Tk_Canvas canvas,
				Tk_Font font);



/* 14 */
EXTERN void		Tk_CanvasPsPath(Tcl_Interp *interp, Tk_Canvas canvas,
				double *coordPtr, int numPoints);



/* 15 */
EXTERN int		Tk_CanvasPsStipple(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap);



/* 16 */
EXTERN double		Tk_CanvasPsY(Tk_Canvas canvas, double y);



/* 17 */
EXTERN void		Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc);



/* 18 */
EXTERN int		Tk_CanvasTagsParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);



/* 19 */
EXTERN const char *	Tk_CanvasTagsPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);



/* 20 */
EXTERN Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas);



/* 21 */
EXTERN void		Tk_CanvasWindowCoords(Tk_Canvas canvas, double x,
				double y, short *screenXPtr,
				short *screenYPtr);



/* 22 */
EXTERN void		Tk_ChangeWindowAttributes(Tk_Window tkwin,
				unsigned long valueMask,
				XSetWindowAttributes *attsPtr);



/* 23 */
EXTERN int		Tk_CharBbox(Tk_TextLayout layout, int index,
				int *xPtr, int *yPtr, int *widthPtr,
				int *heightPtr);



/* 24 */
EXTERN void		Tk_ClearSelection(Tk_Window tkwin, Atom selection);



/* 25 */
EXTERN int		Tk_ClipboardAppend(Tcl_Interp *interp,
				Tk_Window tkwin, Atom target, Atom format,
				const char *buffer);



/* 26 */
EXTERN int		Tk_ClipboardClear(Tcl_Interp *interp,
				Tk_Window tkwin);



/* 27 */
EXTERN int		Tk_ConfigureInfo(Tcl_Interp *interp, Tk_Window tkwin,
				const Tk_ConfigSpec *specs, char *widgRec,
				const char *argvName, int flags);



/* 28 */
EXTERN int		Tk_ConfigureValue(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				char *widgRec, const char *argvName,
				int flags);



/* 29 */
EXTERN int		Tk_ConfigureWidget(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				int argc, const char **argv, char *widgRec,
				int flags);



/* 30 */
EXTERN void		Tk_ConfigureWindow(Tk_Window tkwin,
				unsigned int valueMask,
				XWindowChanges *valuePtr);



/* 31 */
EXTERN Tk_TextLayout	Tk_ComputeTextLayout(Tk_Font font, const char *str,
				int numChars, int wrapLength,
				Tk_Justify justify, int flags, int *widthPtr,
				int *heightPtr);



/* 32 */
EXTERN Tk_Window	Tk_CoordsToWindow(int rootX, int rootY,
				Tk_Window tkwin);



/* 33 */
EXTERN unsigned long	Tk_CreateBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr,
				const char *script, int append);



/* 34 */
EXTERN Tk_BindingTable	Tk_CreateBindingTable(Tcl_Interp *interp);



/* 35 */
EXTERN Tk_ErrorHandler	Tk_CreateErrorHandler(Display *display, int errNum,
				int request, int minorCode,
				Tk_ErrorProc *errorProc,
				ClientData clientData);



/* 36 */
EXTERN void		Tk_CreateEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);



/* 37 */
EXTERN void		Tk_CreateGenericHandler(Tk_GenericProc *proc,
				ClientData clientData);



/* 38 */
EXTERN void		Tk_CreateImageType(const Tk_ImageType *typePtr);



/* 39 */
EXTERN void		Tk_CreateItemType(Tk_ItemType *typePtr);



/* 40 */
EXTERN void		Tk_CreatePhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);



/* 41 */
EXTERN void		Tk_CreateSelHandler(Tk_Window tkwin, Atom selection,
				Atom target, Tk_SelectionProc *proc,
				ClientData clientData, Atom format);



/* 42 */
EXTERN Tk_Window	Tk_CreateWindow(Tcl_Interp *interp, Tk_Window parent,
				const char *name, const char *screenName);



/* 43 */
EXTERN Tk_Window	Tk_CreateWindowFromPath(Tcl_Interp *interp,
				Tk_Window tkwin, const char *pathName,
				const char *screenName);



/* 44 */
EXTERN int		Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
				const void *source, int width, int height);



/* 45 */
EXTERN void		Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor);



/* 46 */
EXTERN void		Tk_DeleteAllBindings(Tk_BindingTable bindingTable,
				ClientData object);



/* 47 */
EXTERN int		Tk_DeleteBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr);



/* 48 */
EXTERN void		Tk_DeleteBindingTable(Tk_BindingTable bindingTable);



/* 49 */
EXTERN void		Tk_DeleteErrorHandler(Tk_ErrorHandler handler);



/* 50 */
EXTERN void		Tk_DeleteEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);



/* 51 */
EXTERN void		Tk_DeleteGenericHandler(Tk_GenericProc *proc,
				ClientData clientData);



/* 52 */
EXTERN void		Tk_DeleteImage(Tcl_Interp *interp, const char *name);



/* 53 */
EXTERN void		Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
				Atom target);



/* 54 */
EXTERN void		Tk_DestroyWindow(Tk_Window tkwin);



/* 55 */
EXTERN const char *	Tk_DisplayName(Tk_Window tkwin);



/* 56 */
EXTERN int		Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
				int y);



/* 57 */
EXTERN void		Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				int numPoints, int borderWidth,
				int leftRelief);



/* 58 */
EXTERN void		Tk_Draw3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);



/* 59 */
EXTERN void		Tk_DrawChars(Display *display, Drawable drawable,
				GC gc, Tk_Font tkfont, const char *source,
				int numBytes, int x, int y);



/* 60 */
EXTERN void		Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc,
				int width, Drawable drawable);



/* 61 */
EXTERN void		Tk_DrawTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int firstChar, int lastChar);



/* 62 */
EXTERN void		Tk_Fill3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				int numPoints, int borderWidth,
				int leftRelief);



/* 63 */
EXTERN void		Tk_Fill3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);



/* 64 */
EXTERN Tk_PhotoHandle	Tk_FindPhoto(Tcl_Interp *interp,
				const char *imageName);



/* 65 */
EXTERN Font		Tk_FontId(Tk_Font font);



/* 66 */
EXTERN void		Tk_Free3DBorder(Tk_3DBorder border);



/* 67 */
EXTERN void		Tk_FreeBitmap(Display *display, Pixmap bitmap);



/* 68 */
EXTERN void		Tk_FreeColor(XColor *colorPtr);



/* 69 */
EXTERN void		Tk_FreeColormap(Display *display, Colormap colormap);



/* 70 */
EXTERN void		Tk_FreeCursor(Display *display, Tk_Cursor cursor);



/* 71 */
EXTERN void		Tk_FreeFont(Tk_Font f);



/* 72 */
EXTERN void		Tk_FreeGC(Display *display, GC gc);



/* 73 */
EXTERN void		Tk_FreeImage(Tk_Image image);



/* 74 */
EXTERN void		Tk_FreeOptions(const Tk_ConfigSpec *specs,
				char *widgRec, Display *display,
				int needFlags);


/* 75 */
EXTERN void		Tk_FreePixmap(Display *display, Pixmap pixmap);



/* 76 */
EXTERN void		Tk_FreeTextLayout(Tk_TextLayout textLayout);



/* 77 */
TK_DEPRECATED("function does nothing, call can be removed")
void			Tk_FreeXId(Display *display, XID xid);



/* 78 */
EXTERN GC		Tk_GCForColor(XColor *colorPtr, Drawable drawable);



/* 79 */
EXTERN void		Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,
				int reqHeight);



/* 80 */
EXTERN Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid colorName);



/* 81 */
EXTERN void		Tk_GetAllBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object);



/* 82 */
EXTERN int		Tk_GetAnchor(Tcl_Interp *interp, const char *str,
				Tk_Anchor *anchorPtr);



/* 83 */
EXTERN const char *	Tk_GetAtomName(Tk_Window tkwin, Atom atom);



/* 84 */
EXTERN const char *	Tk_GetBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr);



/* 85 */
EXTERN Pixmap		Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);



/* 86 */
EXTERN Pixmap		Tk_GetBitmapFromData(Tcl_Interp *interp,
				Tk_Window tkwin, const void *source,
				int width, int height);



/* 87 */
EXTERN int		Tk_GetCapStyle(Tcl_Interp *interp, const char *str,
				int *capPtr);



/* 88 */
EXTERN XColor *		Tk_GetColor(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid name);



/* 89 */
EXTERN XColor *		Tk_GetColorByValue(Tk_Window tkwin, XColor *colorPtr);



/* 90 */
EXTERN Colormap		Tk_GetColormap(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);



/* 91 */
EXTERN Tk_Cursor	Tk_GetCursor(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid str);



/* 92 */
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);



/* 93 */
EXTERN Tk_Font		Tk_GetFont(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);



/* 94 */
EXTERN Tk_Font		Tk_GetFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 95 */
EXTERN void		Tk_GetFontMetrics(Tk_Font font,
				Tk_FontMetrics *fmPtr);



/* 96 */
EXTERN GC		Tk_GetGC(Tk_Window tkwin, unsigned long valueMask,
				XGCValues *valuePtr);



/* 97 */
EXTERN Tk_Image		Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
				const char *name,
				Tk_ImageChangedProc *changeProc,
				ClientData clientData);



/* 98 */
EXTERN ClientData	Tk_GetImageModelData(Tcl_Interp *interp,
				const char *name,
				const Tk_ImageType **typePtrPtr);



/* 99 */
EXTERN Tk_ItemType *	Tk_GetItemTypes(void);



/* 100 */
EXTERN int		Tk_GetJoinStyle(Tcl_Interp *interp, const char *str,
				int *joinPtr);



/* 101 */
EXTERN int		Tk_GetJustify(Tcl_Interp *interp, const char *str,
				Tk_Justify *justifyPtr);



/* 102 */
EXTERN int		Tk_GetNumMainWindows(void);



/* 103 */
EXTERN Tk_Uid		Tk_GetOption(Tk_Window tkwin, const char *name,
				const char *className);



/* 104 */
EXTERN int		Tk_GetPixels(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, int *intPtr);



/* 105 */
EXTERN Pixmap		Tk_GetPixmap(Display *display, Drawable d, int width,
				int height, int depth);



/* 106 */
EXTERN int		Tk_GetRelief(Tcl_Interp *interp, const char *name,
				int *reliefPtr);



/* 107 */
EXTERN void		Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
				int *yPtr);



/* 108 */
EXTERN int		Tk_GetScrollInfo(Tcl_Interp *interp, int argc,
				const char **argv, double *dblPtr,
				int *intPtr);



/* 109 */
EXTERN int		Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, double *doublePtr);



/* 110 */
EXTERN int		Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
				Atom selection, Atom target,
				Tk_GetSelProc *proc, ClientData clientData);



/* 111 */
EXTERN Tk_Uid		Tk_GetUid(const char *str);



/* 112 */
EXTERN Visual *		Tk_GetVisual(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, int *depthPtr,
				Colormap *colormapPtr);



/* 113 */
EXTERN void		Tk_GetVRootGeometry(Tk_Window tkwin, int *xPtr,
				int *yPtr, int *widthPtr, int *heightPtr);



/* 114 */
EXTERN int		Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin,
				int grabGlobal);



/* 115 */
EXTERN void		Tk_HandleEvent(XEvent *eventPtr);



/* 116 */
EXTERN Tk_Window	Tk_IdToWindow(Display *display, Window window);



/* 117 */
EXTERN void		Tk_ImageChanged(Tk_ImageModel model, int x, int y,
				int width, int height, int imageWidth,
				int imageHeight);



/* 118 */
EXTERN int		Tk_Init(Tcl_Interp *interp);



/* 119 */
EXTERN Atom		Tk_InternAtom(Tk_Window tkwin, const char *name);



/* 120 */
EXTERN int		Tk_IntersectTextLayout(Tk_TextLayout layout, int x,
				int y, int width, int height);



/* 121 */
EXTERN void		Tk_MaintainGeometry(Tk_Window window,
				Tk_Window container, int x, int y, int width,
				int height);



/* 122 */
EXTERN Tk_Window	Tk_MainWindow(Tcl_Interp *interp);



/* 123 */
EXTERN void		Tk_MakeWindowExist(Tk_Window tkwin);



/* 124 */
EXTERN void		Tk_ManageGeometry(Tk_Window tkwin,
				const Tk_GeomMgr *mgrPtr,
				ClientData clientData);



/* 125 */
EXTERN void		Tk_MapWindow(Tk_Window tkwin);



/* 126 */
EXTERN int		Tk_MeasureChars(Tk_Font tkfont, const char *source,
				int numBytes, int maxPixels, int flags,
				int *lengthPtr);



/* 127 */
EXTERN void		Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
				int width, int height);



/* 128 */
EXTERN void		Tk_MoveWindow(Tk_Window tkwin, int x, int y);



/* 129 */
EXTERN void		Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y);



/* 130 */
EXTERN const char *	Tk_NameOf3DBorder(Tk_3DBorder border);



/* 131 */
EXTERN const char *	Tk_NameOfAnchor(Tk_Anchor anchor);



/* 132 */
EXTERN const char *	Tk_NameOfBitmap(Display *display, Pixmap bitmap);



/* 133 */
EXTERN const char *	Tk_NameOfCapStyle(int cap);



/* 134 */
EXTERN const char *	Tk_NameOfColor(XColor *colorPtr);



/* 135 */
EXTERN const char *	Tk_NameOfCursor(Display *display, Tk_Cursor cursor);




/* 136 */
EXTERN const char *	Tk_NameOfFont(Tk_Font font);



/* 137 */
EXTERN const char *	Tk_NameOfImage(Tk_ImageModel model);



/* 138 */
EXTERN const char *	Tk_NameOfJoinStyle(int join);



/* 139 */
EXTERN const char *	Tk_NameOfJustify(Tk_Justify justify);



/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);



/* 141 */
EXTERN Tk_Window	Tk_NameToWindow(Tcl_Interp *interp,
				const char *pathName, Tk_Window tkwin);



/* 142 */
EXTERN void		Tk_OwnSelection(Tk_Window tkwin, Atom selection,
				Tk_LostSelProc *proc, ClientData clientData);



/* 143 */
EXTERN int		Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
				int *argcPtr, const char **argv,
				const Tk_ArgvInfo *argTable, int flags);



/* 144 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height);



/* 145 */
TK_DEPRECATED("function signature changed")
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);



/* 146 */
EXTERN int		Tk_PhotoGetImage(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr);



/* 147 */
EXTERN void		Tk_PhotoBlank(Tk_PhotoHandle handle);



/* 148 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
				int width, int height);



/* 149 */
EXTERN void		Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
				int *heightPtr);



/* 150 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
				int width, int height);



/* 151 */
EXTERN int		Tk_PointToChar(Tk_TextLayout layout, int x, int y);



/* 152 */
EXTERN int		Tk_PostscriptFontName(Tk_Font tkfont,
				Tcl_DString *dsPtr);



/* 153 */
EXTERN void		Tk_PreserveColormap(Display *display,
				Colormap colormap);



/* 154 */
EXTERN void		Tk_QueueWindowEvent(XEvent *eventPtr,
				Tcl_QueuePosition position);



/* 155 */
EXTERN void		Tk_RedrawImage(Tk_Image image, int imageX,
				int imageY, int width, int height,
				Drawable drawable, int drawableX,
				int drawableY);



/* 156 */
EXTERN void		Tk_ResizeWindow(Tk_Window tkwin, int width,
				int height);



/* 157 */
EXTERN int		Tk_RestackWindow(Tk_Window tkwin, int aboveBelow,
				Tk_Window other);



/* 158 */
EXTERN Tk_RestrictProc * Tk_RestrictEvents(Tk_RestrictProc *proc,
				ClientData arg, ClientData *prevArgPtr);



/* 159 */
EXTERN int		Tk_SafeInit(Tcl_Interp *interp);



/* 160 */
EXTERN const char *	Tk_SetAppName(Tk_Window tkwin, const char *name);



/* 161 */
EXTERN void		Tk_SetBackgroundFromBorder(Tk_Window tkwin,
				Tk_3DBorder border);



/* 162 */
EXTERN void		Tk_SetClass(Tk_Window tkwin, const char *className);



/* 163 */
EXTERN void		Tk_SetGrid(Tk_Window tkwin, int reqWidth,
				int reqHeight, int gridWidth, int gridHeight);



/* 164 */
EXTERN void		Tk_SetInternalBorder(Tk_Window tkwin, int width);



/* 165 */
EXTERN void		Tk_SetWindowBackground(Tk_Window tkwin,
				unsigned long pixel);



/* 166 */
EXTERN void		Tk_SetWindowBackgroundPixmap(Tk_Window tkwin,
				Pixmap pixmap);



/* 167 */
EXTERN void		Tk_SetWindowBorder(Tk_Window tkwin,
				unsigned long pixel);



/* 168 */
EXTERN void		Tk_SetWindowBorderWidth(Tk_Window tkwin, int width);



/* 169 */
EXTERN void		Tk_SetWindowBorderPixmap(Tk_Window tkwin,
				Pixmap pixmap);



/* 170 */
EXTERN void		Tk_SetWindowColormap(Tk_Window tkwin,
				Colormap colormap);



/* 171 */
EXTERN int		Tk_SetWindowVisual(Tk_Window tkwin, Visual *visual,
				int depth, Colormap colormap);



/* 172 */
EXTERN void		Tk_SizeOfBitmap(Display *display, Pixmap bitmap,
				int *widthPtr, int *heightPtr);



/* 173 */
EXTERN void		Tk_SizeOfImage(Tk_Image image, int *widthPtr,
				int *heightPtr);



/* 174 */
EXTERN int		Tk_StrictMotif(Tk_Window tkwin);



/* 175 */
EXTERN void		Tk_TextLayoutToPostscript(Tcl_Interp *interp,
				Tk_TextLayout layout);



/* 176 */
EXTERN int		Tk_TextWidth(Tk_Font font, const char *str,
				int numBytes);



/* 177 */
EXTERN void		Tk_UndefineCursor(Tk_Window window);



/* 178 */
EXTERN void		Tk_UnderlineChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int x, int y,
				int firstByte, int lastByte);



/* 179 */
EXTERN void		Tk_UnderlineTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int underline);



/* 180 */
EXTERN void		Tk_Ungrab(Tk_Window tkwin);



/* 181 */
EXTERN void		Tk_UnmaintainGeometry(Tk_Window window,
				Tk_Window container);



/* 182 */
EXTERN void		Tk_UnmapWindow(Tk_Window tkwin);



/* 183 */
EXTERN void		Tk_UnsetGrid(Tk_Window tkwin);



/* 184 */
EXTERN void		Tk_UpdatePointer(Tk_Window tkwin, int x, int y,
				int state);



/* 185 */
EXTERN Pixmap		Tk_AllocBitmapFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr);



/* 186 */
EXTERN Tk_3DBorder	Tk_Alloc3DBorderFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr);



/* 187 */
EXTERN XColor *		Tk_AllocColorFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr);



/* 188 */
EXTERN Tk_Cursor	Tk_AllocCursorFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr);



/* 189 */
EXTERN Tk_Font		Tk_AllocFontFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr);



/* 190 */
EXTERN Tk_OptionTable	Tk_CreateOptionTable(Tcl_Interp *interp,
				const Tk_OptionSpec *templatePtr);



/* 191 */
EXTERN void		Tk_DeleteOptionTable(Tk_OptionTable optionTable);



/* 192 */
EXTERN void		Tk_Free3DBorderFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);



/* 193 */
EXTERN void		Tk_FreeBitmapFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);



/* 194 */
EXTERN void		Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 195 */
EXTERN void		Tk_FreeConfigOptions(void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);



/* 196 */
EXTERN void		Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);



/* 197 */
EXTERN void		Tk_FreeCursorFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);



/* 198 */
EXTERN void		Tk_FreeFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 199 */
EXTERN Tk_3DBorder	Tk_Get3DBorderFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);



/* 200 */
EXTERN int		Tk_GetAnchorFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Tk_Anchor *anchorPtr);



/* 201 */
EXTERN Pixmap		Tk_GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 202 */
EXTERN XColor *		Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 203 */
EXTERN Tk_Cursor	Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);



/* 204 */
EXTERN Tcl_Obj *	Tk_GetOptionInfo(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, Tcl_Obj *namePtr,
				Tk_Window tkwin);



/* 205 */
EXTERN Tcl_Obj *	Tk_GetOptionValue(Tcl_Interp *interp,
				void *recordPtr, Tk_OptionTable optionTable,
				Tcl_Obj *namePtr, Tk_Window tkwin);



/* 206 */
EXTERN int		Tk_GetJustifyFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Tk_Justify *justifyPtr);



/* 207 */
EXTERN int		Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin,
				Tcl_Obj *objPtr, double *doublePtr);



/* 208 */
EXTERN int		Tk_GetPixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);



/* 209 */
EXTERN int		Tk_GetReliefFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *resultPtr);



/* 210 */
EXTERN int		Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], double *dblPtr,
				int *intPtr);



/* 211 */
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);



/* 212 */
EXTERN void		Tk_MainEx(int argc, char **argv,
				Tcl_AppInitProc *appInitProc,
				Tcl_Interp *interp);



/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);



/* 214 */
EXTERN int		Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, int objc,
				Tcl_Obj *const objv[], Tk_Window tkwin,
				Tk_SavedOptions *savePtr, int *maskPtr);



/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);



/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);



/* 217 */
EXTERN void		Tk_CreateSmoothMethod(Tcl_Interp *interp,
				const Tk_SmoothMethod *method);

/* Slot 218 is reserved */
/* Slot 219 is reserved */


/* 220 */
EXTERN int		Tk_GetDash(Tcl_Interp *interp, const char *value,
				Tk_Dash *dash);



/* 221 */
EXTERN void		Tk_CreateOutline(Tk_Outline *outline);



/* 222 */
EXTERN void		Tk_DeleteOutline(Display *display,
				Tk_Outline *outline);



/* 223 */
EXTERN int		Tk_ConfigOutlineGC(XGCValues *gcValues,
				Tk_Canvas canvas, Tk_Item *item,
				Tk_Outline *outline);



/* 224 */
EXTERN int		Tk_ChangeOutlineGC(Tk_Canvas canvas, Tk_Item *item,
				Tk_Outline *outline);



/* 225 */
EXTERN int		Tk_ResetOutlineGC(Tk_Canvas canvas, Tk_Item *item,
				Tk_Outline *outline);



/* 226 */
EXTERN int		Tk_CanvasPsOutline(Tk_Canvas canvas, Tk_Item *item,
				Tk_Outline *outline);



/* 227 */
EXTERN void		Tk_SetTSOrigin(Tk_Window tkwin, GC gc, int x, int y);



/* 228 */
EXTERN int		Tk_CanvasGetCoordFromObj(Tcl_Interp *interp,
				Tk_Canvas canvas, Tcl_Obj *obj,
				double *doublePtr);



/* 229 */
EXTERN void		Tk_CanvasSetOffset(Tk_Canvas canvas, GC gc,
				Tk_TSOffset *offset);



/* 230 */
EXTERN void		Tk_DitherPhoto(Tk_PhotoHandle handle, int x, int y,
				int width, int height);



/* 231 */
EXTERN int		Tk_PostscriptBitmap(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap, int startX, int startY,
				int width, int height);



/* 232 */
EXTERN int		Tk_PostscriptColor(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, XColor *colorPtr);



/* 233 */
EXTERN int		Tk_PostscriptFont(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, Tk_Font font);



/* 234 */
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);



/* 235 */
EXTERN void		Tk_PostscriptPath(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, double *coordPtr,
				int numPoints);



/* 236 */
EXTERN int		Tk_PostscriptStipple(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap);



/* 237 */
EXTERN double		Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo);



/* 238 */
EXTERN int		Tk_PostscriptPhoto(Tcl_Interp *interp,
				Tk_PhotoImageBlock *blockPtr,
				Tk_PostscriptInfo psInfo, int width,
				int height);



/* 239 */
EXTERN void		Tk_CreateClientMessageHandler(
				Tk_ClientMessageProc *proc);



/* 240 */
EXTERN void		Tk_DeleteClientMessageHandler(
				Tk_ClientMessageProc *proc);



/* 241 */
EXTERN Tk_Window	Tk_CreateAnonymousWindow(Tcl_Interp *interp,
				Tk_Window parent, const char *screenName);



/* 242 */
EXTERN void		Tk_SetClassProcs(Tk_Window tkwin,
				const Tk_ClassProcs *procs,
				ClientData instanceData);



/* 243 */
EXTERN void		Tk_SetInternalBorderEx(Tk_Window tkwin, int left,
				int right, int top, int bottom);



/* 244 */
EXTERN void		Tk_SetMinimumRequestSize(Tk_Window tkwin,
				int minWidth, int minHeight);



/* 245 */
EXTERN void		Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
				int height);



/* 246 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int compRule);



/* 247 */
TK_DEPRECATED("function signature changed")
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);



/* 248 */
EXTERN int		Tk_CollapseMotionEvents(Display *display,
				int collapse);



/* 249 */
EXTERN Tk_StyleEngine	Tk_RegisterStyleEngine(const char *name,
				Tk_StyleEngine parent);



/* 250 */
EXTERN Tk_StyleEngine	Tk_GetStyleEngine(const char *name);



/* 251 */
EXTERN int		Tk_RegisterStyledElement(Tk_StyleEngine engine,
				Tk_ElementSpec *templatePtr);



/* 252 */
EXTERN int		Tk_GetElementId(const char *name);



/* 253 */
EXTERN Tk_Style		Tk_CreateStyle(const char *name,
				Tk_StyleEngine engine, ClientData clientData);



/* 254 */
EXTERN Tk_Style		Tk_GetStyle(Tcl_Interp *interp, const char *name);



/* 255 */
EXTERN void		Tk_FreeStyle(Tk_Style style);



/* 256 */
EXTERN const char *	Tk_NameOfStyle(Tk_Style style);



/* 257 */
EXTERN Tk_Style		Tk_AllocStyleFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr);



/* 258 */
EXTERN Tk_Style		Tk_GetStyleFromObj(Tcl_Obj *objPtr);



/* 259 */
EXTERN void		Tk_FreeStyleFromObj(Tcl_Obj *objPtr);



/* 260 */
EXTERN Tk_StyledElement	 Tk_GetStyledElement(Tk_Style style, int elementId,
				Tk_OptionTable optionTable);



/* 261 */
EXTERN void		Tk_GetElementSize(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);



/* 262 */
EXTERN void		Tk_GetElementBox(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int x, int y, int width,
				int height, int inner, int *xPtr, int *yPtr,
				int *widthPtr, int *heightPtr);



/* 263 */
EXTERN int		Tk_GetElementBorderWidth(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin);



/* 264 */
EXTERN void		Tk_DrawElement(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, Drawable d, int x, int y,
				int width, int height, int state);



/* 265 */
EXTERN int		Tk_PhotoExpand(Tcl_Interp *interp,
				Tk_PhotoHandle handle, int width, int height);



/* 266 */
EXTERN int		Tk_PhotoPutBlock(Tcl_Interp *interp,
				Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int compRule);



/* 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);



/* 268 */
EXTERN int		Tk_PhotoSetSize(Tcl_Interp *interp,
				Tk_PhotoHandle handle, int width, int height);



/* 269 */
EXTERN long		Tk_GetUserInactiveTime(Display *dpy);



/* 270 */
EXTERN void		Tk_ResetUserInactiveTime(Display *dpy);



/* 271 */
EXTERN Tcl_Interp *	Tk_Interp(Tk_Window tkwin);



/* 272 */
EXTERN void		Tk_CreateOldImageType(const Tk_ImageType *typePtr);



/* 273 */
EXTERN void		Tk_CreateOldPhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);

/* 274 */
EXTERN int		Tk_AlwaysShowSelection(Tk_Window tkwin);
/* 275 */
EXTERN unsigned		Tk_GetButtonMask(unsigned button);
/* 276 */
EXTERN int		Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				double *doublePtr);
/* 277 */
EXTERN Tcl_Obj *	Tk_NewWindowObj(Tk_Window tkwin);
/* 278 */
EXTERN void		Tk_SendVirtualEvent(Tk_Window tkwin,
				const char *eventName, Tcl_Obj *detail);



/* 279 */
EXTERN Tcl_Obj *	Tk_FontGetDescription(Tk_Font tkfont);


typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
    const struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;

typedef struct TkStubs {
    int magic;
    const TkStubHooks *hooks;

    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 */
    const 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, const char *buffer); /* 25 */
    int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
    int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */
    int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */
    int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, const 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 *script, 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) (const Tk_ImageType *typePtr); /* 38 */
    void (*tk_CreateItemType) (Tk_ItemType *typePtr); /* 39 */
    void (*tk_CreatePhotoImageFormat) (const 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 void *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 */
    const 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) (const 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 */
    TCL_DEPRECATED_API("function does nothing, call can be removed") 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 */
    const char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
    const 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 void *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_GetImageModelData) (Tcl_Interp *interp, const char *name, const 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, const 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_ImageModel model, 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 window, Tk_Window container, 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 */
    const char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
    const char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
    const char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
    const char * (*tk_NameOfCapStyle) (int cap); /* 133 */
    const char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
    const char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
    const char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
    const char * (*tk_NameOfImage) (Tk_ImageModel model); /* 137 */
    const char * (*tk_NameOfJoinStyle) (int join); /* 138 */
    const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
    const 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, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
    TCL_DEPRECATED_API("function signature changed") 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 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
    void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
    TCL_DEPRECATED_API("function signature changed") 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 window, Tk_Window container); /* 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) (void *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, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *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, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") 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, void *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, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);
    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, const 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 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
    TCL_DEPRECATED_API("function signature changed") 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, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
    void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, void *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, void *recordPtr, Tk_Window tkwin); /* 263 */
    void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, void *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) (const Tk_ImageType *typePtr); /* 272 */
    void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */
    int (*tk_AlwaysShowSelection) (Tk_Window tkwin); /* 274 */
    unsigned (*tk_GetButtonMask) (unsigned button); /* 275 */
    int (*tk_GetDoublePixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 276 */
    Tcl_Obj * (*tk_NewWindowObj) (Tk_Window tkwin); /* 277 */
    void (*tk_SendVirtualEvent) (Tk_Window tkwin, const char *eventName, Tcl_Obj *detail); /* 278 */

    Tcl_Obj * (*tk_FontGetDescription) (Tk_Font tkfont); /* 279 */
} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */


#define Tk_MainLoop \
	(tkStubsPtr->tk_MainLoop) /* 0 */


#define Tk_3DBorderColor \
	(tkStubsPtr->tk_3DBorderColor) /* 1 */


#define Tk_3DBorderGC \
	(tkStubsPtr->tk_3DBorderGC) /* 2 */


#define Tk_3DHorizontalBevel \
	(tkStubsPtr->tk_3DHorizontalBevel) /* 3 */


#define Tk_3DVerticalBevel \
	(tkStubsPtr->tk_3DVerticalBevel) /* 4 */


#define Tk_AddOption \
	(tkStubsPtr->tk_AddOption) /* 5 */


#define Tk_BindEvent \
	(tkStubsPtr->tk_BindEvent) /* 6 */


#define Tk_CanvasDrawableCoords \
	(tkStubsPtr->tk_CanvasDrawableCoords) /* 7 */


#define Tk_CanvasEventuallyRedraw \
	(tkStubsPtr->tk_CanvasEventuallyRedraw) /* 8 */


#define Tk_CanvasGetCoord \
	(tkStubsPtr->tk_CanvasGetCoord) /* 9 */


#define Tk_CanvasGetTextInfo \
	(tkStubsPtr->tk_CanvasGetTextInfo) /* 10 */


#define Tk_CanvasPsBitmap \
	(tkStubsPtr->tk_CanvasPsBitmap) /* 11 */


#define Tk_CanvasPsColor \
	(tkStubsPtr->tk_CanvasPsColor) /* 12 */


#define Tk_CanvasPsFont \
	(tkStubsPtr->tk_CanvasPsFont) /* 13 */


#define Tk_CanvasPsPath \
	(tkStubsPtr->tk_CanvasPsPath) /* 14 */


#define Tk_CanvasPsStipple \
	(tkStubsPtr->tk_CanvasPsStipple) /* 15 */


#define Tk_CanvasPsY \
	(tkStubsPtr->tk_CanvasPsY) /* 16 */


#define Tk_CanvasSetStippleOrigin \
	(tkStubsPtr->tk_CanvasSetStippleOrigin) /* 17 */


#define Tk_CanvasTagsParseProc \
	(tkStubsPtr->tk_CanvasTagsParseProc) /* 18 */


#define Tk_CanvasTagsPrintProc \
	(tkStubsPtr->tk_CanvasTagsPrintProc) /* 19 */


#define Tk_CanvasTkwin \
	(tkStubsPtr->tk_CanvasTkwin) /* 20 */


#define Tk_CanvasWindowCoords \
	(tkStubsPtr->tk_CanvasWindowCoords) /* 21 */


#define Tk_ChangeWindowAttributes \
	(tkStubsPtr->tk_ChangeWindowAttributes) /* 22 */


#define Tk_CharBbox \
	(tkStubsPtr->tk_CharBbox) /* 23 */


#define Tk_ClearSelection \
	(tkStubsPtr->tk_ClearSelection) /* 24 */


#define Tk_ClipboardAppend \
	(tkStubsPtr->tk_ClipboardAppend) /* 25 */


#define Tk_ClipboardClear \
	(tkStubsPtr->tk_ClipboardClear) /* 26 */


#define Tk_ConfigureInfo \
	(tkStubsPtr->tk_ConfigureInfo) /* 27 */


#define Tk_ConfigureValue \
	(tkStubsPtr->tk_ConfigureValue) /* 28 */


#define Tk_ConfigureWidget \
	(tkStubsPtr->tk_ConfigureWidget) /* 29 */


#define Tk_ConfigureWindow \
	(tkStubsPtr->tk_ConfigureWindow) /* 30 */


#define Tk_ComputeTextLayout \
	(tkStubsPtr->tk_ComputeTextLayout) /* 31 */


#define Tk_CoordsToWindow \
	(tkStubsPtr->tk_CoordsToWindow) /* 32 */


#define Tk_CreateBinding \
	(tkStubsPtr->tk_CreateBinding) /* 33 */


#define Tk_CreateBindingTable \
	(tkStubsPtr->tk_CreateBindingTable) /* 34 */


#define Tk_CreateErrorHandler \
	(tkStubsPtr->tk_CreateErrorHandler) /* 35 */


#define Tk_CreateEventHandler \
	(tkStubsPtr->tk_CreateEventHandler) /* 36 */


#define Tk_CreateGenericHandler \
	(tkStubsPtr->tk_CreateGenericHandler) /* 37 */


#define Tk_CreateImageType \
	(tkStubsPtr->tk_CreateImageType) /* 38 */


#define Tk_CreateItemType \
	(tkStubsPtr->tk_CreateItemType) /* 39 */


#define Tk_CreatePhotoImageFormat \
	(tkStubsPtr->tk_CreatePhotoImageFormat) /* 40 */


#define Tk_CreateSelHandler \
	(tkStubsPtr->tk_CreateSelHandler) /* 41 */


#define Tk_CreateWindow \
	(tkStubsPtr->tk_CreateWindow) /* 42 */


#define Tk_CreateWindowFromPath \
	(tkStubsPtr->tk_CreateWindowFromPath) /* 43 */


#define Tk_DefineBitmap \
	(tkStubsPtr->tk_DefineBitmap) /* 44 */


#define Tk_DefineCursor \
	(tkStubsPtr->tk_DefineCursor) /* 45 */


#define Tk_DeleteAllBindings \
	(tkStubsPtr->tk_DeleteAllBindings) /* 46 */


#define Tk_DeleteBinding \
	(tkStubsPtr->tk_DeleteBinding) /* 47 */


#define Tk_DeleteBindingTable \
	(tkStubsPtr->tk_DeleteBindingTable) /* 48 */


#define Tk_DeleteErrorHandler \
	(tkStubsPtr->tk_DeleteErrorHandler) /* 49 */


#define Tk_DeleteEventHandler \
	(tkStubsPtr->tk_DeleteEventHandler) /* 50 */


#define Tk_DeleteGenericHandler \
	(tkStubsPtr->tk_DeleteGenericHandler) /* 51 */


#define Tk_DeleteImage \
	(tkStubsPtr->tk_DeleteImage) /* 52 */


#define Tk_DeleteSelHandler \
	(tkStubsPtr->tk_DeleteSelHandler) /* 53 */


#define Tk_DestroyWindow \
	(tkStubsPtr->tk_DestroyWindow) /* 54 */


#define Tk_DisplayName \
	(tkStubsPtr->tk_DisplayName) /* 55 */


#define Tk_DistanceToTextLayout \
	(tkStubsPtr->tk_DistanceToTextLayout) /* 56 */


#define Tk_Draw3DPolygon \
	(tkStubsPtr->tk_Draw3DPolygon) /* 57 */


#define Tk_Draw3DRectangle \
	(tkStubsPtr->tk_Draw3DRectangle) /* 58 */


#define Tk_DrawChars \
	(tkStubsPtr->tk_DrawChars) /* 59 */


#define Tk_DrawFocusHighlight \
	(tkStubsPtr->tk_DrawFocusHighlight) /* 60 */


#define Tk_DrawTextLayout \
	(tkStubsPtr->tk_DrawTextLayout) /* 61 */


#define Tk_Fill3DPolygon \
	(tkStubsPtr->tk_Fill3DPolygon) /* 62 */


#define Tk_Fill3DRectangle \
	(tkStubsPtr->tk_Fill3DRectangle) /* 63 */


#define Tk_FindPhoto \
	(tkStubsPtr->tk_FindPhoto) /* 64 */


#define Tk_FontId \
	(tkStubsPtr->tk_FontId) /* 65 */


#define Tk_Free3DBorder \
	(tkStubsPtr->tk_Free3DBorder) /* 66 */


#define Tk_FreeBitmap \
	(tkStubsPtr->tk_FreeBitmap) /* 67 */


#define Tk_FreeColor \
	(tkStubsPtr->tk_FreeColor) /* 68 */


#define Tk_FreeColormap \
	(tkStubsPtr->tk_FreeColormap) /* 69 */


#define Tk_FreeCursor \
	(tkStubsPtr->tk_FreeCursor) /* 70 */


#define Tk_FreeFont \
	(tkStubsPtr->tk_FreeFont) /* 71 */


#define Tk_FreeGC \
	(tkStubsPtr->tk_FreeGC) /* 72 */


#define Tk_FreeImage \
	(tkStubsPtr->tk_FreeImage) /* 73 */


#define Tk_FreeOptions \
	(tkStubsPtr->tk_FreeOptions) /* 74 */


#define Tk_FreePixmap \
	(tkStubsPtr->tk_FreePixmap) /* 75 */


#define Tk_FreeTextLayout \
	(tkStubsPtr->tk_FreeTextLayout) /* 76 */


#define Tk_FreeXId \
	(tkStubsPtr->tk_FreeXId) /* 77 */


#define Tk_GCForColor \
	(tkStubsPtr->tk_GCForColor) /* 78 */


#define Tk_GeometryRequest \
	(tkStubsPtr->tk_GeometryRequest) /* 79 */


#define Tk_Get3DBorder \
	(tkStubsPtr->tk_Get3DBorder) /* 80 */


#define Tk_GetAllBindings \
	(tkStubsPtr->tk_GetAllBindings) /* 81 */


#define Tk_GetAnchor \
	(tkStubsPtr->tk_GetAnchor) /* 82 */


#define Tk_GetAtomName \
	(tkStubsPtr->tk_GetAtomName) /* 83 */


#define Tk_GetBinding \
	(tkStubsPtr->tk_GetBinding) /* 84 */


#define Tk_GetBitmap \
	(tkStubsPtr->tk_GetBitmap) /* 85 */


#define Tk_GetBitmapFromData \
	(tkStubsPtr->tk_GetBitmapFromData) /* 86 */


#define Tk_GetCapStyle \
	(tkStubsPtr->tk_GetCapStyle) /* 87 */


#define Tk_GetColor \
	(tkStubsPtr->tk_GetColor) /* 88 */


#define Tk_GetColorByValue \
	(tkStubsPtr->tk_GetColorByValue) /* 89 */


#define Tk_GetColormap \
	(tkStubsPtr->tk_GetColormap) /* 90 */


#define Tk_GetCursor \
	(tkStubsPtr->tk_GetCursor) /* 91 */


#define Tk_GetCursorFromData \
	(tkStubsPtr->tk_GetCursorFromData) /* 92 */


#define Tk_GetFont \
	(tkStubsPtr->tk_GetFont) /* 93 */


#define Tk_GetFontFromObj \
	(tkStubsPtr->tk_GetFontFromObj) /* 94 */


#define Tk_GetFontMetrics \
	(tkStubsPtr->tk_GetFontMetrics) /* 95 */


#define Tk_GetGC \
	(tkStubsPtr->tk_GetGC) /* 96 */


#define Tk_GetImage \
	(tkStubsPtr->tk_GetImage) /* 97 */


#define Tk_GetImageModelData \
	(tkStubsPtr->tk_GetImageModelData) /* 98 */


#define Tk_GetItemTypes \
	(tkStubsPtr->tk_GetItemTypes) /* 99 */


#define Tk_GetJoinStyle \
	(tkStubsPtr->tk_GetJoinStyle) /* 100 */


#define Tk_GetJustify \
	(tkStubsPtr->tk_GetJustify) /* 101 */


#define Tk_GetNumMainWindows \
	(tkStubsPtr->tk_GetNumMainWindows) /* 102 */


#define Tk_GetOption \
	(tkStubsPtr->tk_GetOption) /* 103 */


#define Tk_GetPixels \
	(tkStubsPtr->tk_GetPixels) /* 104 */


#define Tk_GetPixmap \
	(tkStubsPtr->tk_GetPixmap) /* 105 */


#define Tk_GetRelief \
	(tkStubsPtr->tk_GetRelief) /* 106 */


#define Tk_GetRootCoords \
	(tkStubsPtr->tk_GetRootCoords) /* 107 */


#define Tk_GetScrollInfo \
	(tkStubsPtr->tk_GetScrollInfo) /* 108 */


#define Tk_GetScreenMM \
	(tkStubsPtr->tk_GetScreenMM) /* 109 */


#define Tk_GetSelection \
	(tkStubsPtr->tk_GetSelection) /* 110 */


#define Tk_GetUid \
	(tkStubsPtr->tk_GetUid) /* 111 */


#define Tk_GetVisual \
	(tkStubsPtr->tk_GetVisual) /* 112 */


#define Tk_GetVRootGeometry \
	(tkStubsPtr->tk_GetVRootGeometry) /* 113 */


#define Tk_Grab \
	(tkStubsPtr->tk_Grab) /* 114 */


#define Tk_HandleEvent \
	(tkStubsPtr->tk_HandleEvent) /* 115 */


#define Tk_IdToWindow \
	(tkStubsPtr->tk_IdToWindow) /* 116 */


#define Tk_ImageChanged \
	(tkStubsPtr->tk_ImageChanged) /* 117 */


#define Tk_Init \
	(tkStubsPtr->tk_Init) /* 118 */


#define Tk_InternAtom \
	(tkStubsPtr->tk_InternAtom) /* 119 */


#define Tk_IntersectTextLayout \
	(tkStubsPtr->tk_IntersectTextLayout) /* 120 */


#define Tk_MaintainGeometry \
	(tkStubsPtr->tk_MaintainGeometry) /* 121 */


#define Tk_MainWindow \
	(tkStubsPtr->tk_MainWindow) /* 122 */


#define Tk_MakeWindowExist \
	(tkStubsPtr->tk_MakeWindowExist) /* 123 */


#define Tk_ManageGeometry \
	(tkStubsPtr->tk_ManageGeometry) /* 124 */


#define Tk_MapWindow \
	(tkStubsPtr->tk_MapWindow) /* 125 */


#define Tk_MeasureChars \
	(tkStubsPtr->tk_MeasureChars) /* 126 */


#define Tk_MoveResizeWindow \
	(tkStubsPtr->tk_MoveResizeWindow) /* 127 */


#define Tk_MoveWindow \
	(tkStubsPtr->tk_MoveWindow) /* 128 */


#define Tk_MoveToplevelWindow \
	(tkStubsPtr->tk_MoveToplevelWindow) /* 129 */


#define Tk_NameOf3DBorder \
	(tkStubsPtr->tk_NameOf3DBorder) /* 130 */


#define Tk_NameOfAnchor \
	(tkStubsPtr->tk_NameOfAnchor) /* 131 */


#define Tk_NameOfBitmap \
	(tkStubsPtr->tk_NameOfBitmap) /* 132 */


#define Tk_NameOfCapStyle \
	(tkStubsPtr->tk_NameOfCapStyle) /* 133 */


#define Tk_NameOfColor \
	(tkStubsPtr->tk_NameOfColor) /* 134 */


#define Tk_NameOfCursor \
	(tkStubsPtr->tk_NameOfCursor) /* 135 */


#define Tk_NameOfFont \
	(tkStubsPtr->tk_NameOfFont) /* 136 */


#define Tk_NameOfImage \
	(tkStubsPtr->tk_NameOfImage) /* 137 */


#define Tk_NameOfJoinStyle \
	(tkStubsPtr->tk_NameOfJoinStyle) /* 138 */


#define Tk_NameOfJustify \
	(tkStubsPtr->tk_NameOfJustify) /* 139 */


#define Tk_NameOfRelief \
	(tkStubsPtr->tk_NameOfRelief) /* 140 */


#define Tk_NameToWindow \
	(tkStubsPtr->tk_NameToWindow) /* 141 */


#define Tk_OwnSelection \
	(tkStubsPtr->tk_OwnSelection) /* 142 */


#define Tk_ParseArgv \
	(tkStubsPtr->tk_ParseArgv) /* 143 */


#define Tk_PhotoPutBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutBlock_NoComposite) /* 144 */


#define Tk_PhotoPutZoomedBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_NoComposite) /* 145 */


#define Tk_PhotoGetImage \
	(tkStubsPtr->tk_PhotoGetImage) /* 146 */


#define Tk_PhotoBlank \
	(tkStubsPtr->tk_PhotoBlank) /* 147 */


#define Tk_PhotoExpand_Panic \
	(tkStubsPtr->tk_PhotoExpand_Panic) /* 148 */


#define Tk_PhotoGetSize \
	(tkStubsPtr->tk_PhotoGetSize) /* 149 */


#define Tk_PhotoSetSize_Panic \
	(tkStubsPtr->tk_PhotoSetSize_Panic) /* 150 */


#define Tk_PointToChar \
	(tkStubsPtr->tk_PointToChar) /* 151 */


#define Tk_PostscriptFontName \
	(tkStubsPtr->tk_PostscriptFontName) /* 152 */


#define Tk_PreserveColormap \
	(tkStubsPtr->tk_PreserveColormap) /* 153 */


#define Tk_QueueWindowEvent \
	(tkStubsPtr->tk_QueueWindowEvent) /* 154 */


#define Tk_RedrawImage \
	(tkStubsPtr->tk_RedrawImage) /* 155 */


#define Tk_ResizeWindow \
	(tkStubsPtr->tk_ResizeWindow) /* 156 */


#define Tk_RestackWindow \
	(tkStubsPtr->tk_RestackWindow) /* 157 */


#define Tk_RestrictEvents \
	(tkStubsPtr->tk_RestrictEvents) /* 158 */


#define Tk_SafeInit \
	(tkStubsPtr->tk_SafeInit) /* 159 */


#define Tk_SetAppName \
	(tkStubsPtr->tk_SetAppName) /* 160 */


#define Tk_SetBackgroundFromBorder \
	(tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */


#define Tk_SetClass \
	(tkStubsPtr->tk_SetClass) /* 162 */


#define Tk_SetGrid \
	(tkStubsPtr->tk_SetGrid) /* 163 */


#define Tk_SetInternalBorder \
	(tkStubsPtr->tk_SetInternalBorder) /* 164 */


#define Tk_SetWindowBackground \
	(tkStubsPtr->tk_SetWindowBackground) /* 165 */


#define Tk_SetWindowBackgroundPixmap \
	(tkStubsPtr->tk_SetWindowBackgroundPixmap) /* 166 */


#define Tk_SetWindowBorder \
	(tkStubsPtr->tk_SetWindowBorder) /* 167 */


#define Tk_SetWindowBorderWidth \
	(tkStubsPtr->tk_SetWindowBorderWidth) /* 168 */


#define Tk_SetWindowBorderPixmap \
	(tkStubsPtr->tk_SetWindowBorderPixmap) /* 169 */


#define Tk_SetWindowColormap \
	(tkStubsPtr->tk_SetWindowColormap) /* 170 */


#define Tk_SetWindowVisual \
	(tkStubsPtr->tk_SetWindowVisual) /* 171 */


#define Tk_SizeOfBitmap \
	(tkStubsPtr->tk_SizeOfBitmap) /* 172 */


#define Tk_SizeOfImage \
	(tkStubsPtr->tk_SizeOfImage) /* 173 */


#define Tk_StrictMotif \
	(tkStubsPtr->tk_StrictMotif) /* 174 */


#define Tk_TextLayoutToPostscript \
	(tkStubsPtr->tk_TextLayoutToPostscript) /* 175 */


#define Tk_TextWidth \
	(tkStubsPtr->tk_TextWidth) /* 176 */


#define Tk_UndefineCursor \
	(tkStubsPtr->tk_UndefineCursor) /* 177 */


#define Tk_UnderlineChars \
	(tkStubsPtr->tk_UnderlineChars) /* 178 */


#define Tk_UnderlineTextLayout \
	(tkStubsPtr->tk_UnderlineTextLayout) /* 179 */


#define Tk_Ungrab \
	(tkStubsPtr->tk_Ungrab) /* 180 */


#define Tk_UnmaintainGeometry \
	(tkStubsPtr->tk_UnmaintainGeometry) /* 181 */


#define Tk_UnmapWindow \
	(tkStubsPtr->tk_UnmapWindow) /* 182 */


#define Tk_UnsetGrid \
	(tkStubsPtr->tk_UnsetGrid) /* 183 */


#define Tk_UpdatePointer \
	(tkStubsPtr->tk_UpdatePointer) /* 184 */


#define Tk_AllocBitmapFromObj \
	(tkStubsPtr->tk_AllocBitmapFromObj) /* 185 */


#define Tk_Alloc3DBorderFromObj \
	(tkStubsPtr->tk_Alloc3DBorderFromObj) /* 186 */


#define Tk_AllocColorFromObj \
	(tkStubsPtr->tk_AllocColorFromObj) /* 187 */


#define Tk_AllocCursorFromObj \
	(tkStubsPtr->tk_AllocCursorFromObj) /* 188 */


#define Tk_AllocFontFromObj \
	(tkStubsPtr->tk_AllocFontFromObj) /* 189 */


#define Tk_CreateOptionTable \
	(tkStubsPtr->tk_CreateOptionTable) /* 190 */


#define Tk_DeleteOptionTable \
	(tkStubsPtr->tk_DeleteOptionTable) /* 191 */


#define Tk_Free3DBorderFromObj \
	(tkStubsPtr->tk_Free3DBorderFromObj) /* 192 */


#define Tk_FreeBitmapFromObj \
	(tkStubsPtr->tk_FreeBitmapFromObj) /* 193 */


#define Tk_FreeColorFromObj \
	(tkStubsPtr->tk_FreeColorFromObj) /* 194 */


#define Tk_FreeConfigOptions \
	(tkStubsPtr->tk_FreeConfigOptions) /* 195 */


#define Tk_FreeSavedOptions \
	(tkStubsPtr->tk_FreeSavedOptions) /* 196 */


#define Tk_FreeCursorFromObj \
	(tkStubsPtr->tk_FreeCursorFromObj) /* 197 */


#define Tk_FreeFontFromObj \
	(tkStubsPtr->tk_FreeFontFromObj) /* 198 */


#define Tk_Get3DBorderFromObj \
	(tkStubsPtr->tk_Get3DBorderFromObj) /* 199 */


#define Tk_GetAnchorFromObj \
	(tkStubsPtr->tk_GetAnchorFromObj) /* 200 */


#define Tk_GetBitmapFromObj \
	(tkStubsPtr->tk_GetBitmapFromObj) /* 201 */


#define Tk_GetColorFromObj \
	(tkStubsPtr->tk_GetColorFromObj) /* 202 */


#define Tk_GetCursorFromObj \
	(tkStubsPtr->tk_GetCursorFromObj) /* 203 */


#define Tk_GetOptionInfo \
	(tkStubsPtr->tk_GetOptionInfo) /* 204 */


#define Tk_GetOptionValue \
	(tkStubsPtr->tk_GetOptionValue) /* 205 */


#define Tk_GetJustifyFromObj \
	(tkStubsPtr->tk_GetJustifyFromObj) /* 206 */


#define Tk_GetMMFromObj \
	(tkStubsPtr->tk_GetMMFromObj) /* 207 */


#define Tk_GetPixelsFromObj \
	(tkStubsPtr->tk_GetPixelsFromObj) /* 208 */


#define Tk_GetReliefFromObj \
	(tkStubsPtr->tk_GetReliefFromObj) /* 209 */


#define Tk_GetScrollInfoObj \
	(tkStubsPtr->tk_GetScrollInfoObj) /* 210 */


#define Tk_InitOptions \
	(tkStubsPtr->tk_InitOptions) /* 211 */


#define Tk_MainEx \
	(tkStubsPtr->tk_MainEx) /* 212 */


#define Tk_RestoreSavedOptions \
	(tkStubsPtr->tk_RestoreSavedOptions) /* 213 */


#define Tk_SetOptions \
	(tkStubsPtr->tk_SetOptions) /* 214 */


#define Tk_InitConsoleChannels \
	(tkStubsPtr->tk_InitConsoleChannels) /* 215 */


#define Tk_CreateConsoleWindow \
	(tkStubsPtr->tk_CreateConsoleWindow) /* 216 */


#define Tk_CreateSmoothMethod \
	(tkStubsPtr->tk_CreateSmoothMethod) /* 217 */

/* Slot 218 is reserved */
/* Slot 219 is reserved */

#define Tk_GetDash \
	(tkStubsPtr->tk_GetDash) /* 220 */


#define Tk_CreateOutline \
	(tkStubsPtr->tk_CreateOutline) /* 221 */


#define Tk_DeleteOutline \
	(tkStubsPtr->tk_DeleteOutline) /* 222 */


#define Tk_ConfigOutlineGC \
	(tkStubsPtr->tk_ConfigOutlineGC) /* 223 */


#define Tk_ChangeOutlineGC \
	(tkStubsPtr->tk_ChangeOutlineGC) /* 224 */


#define Tk_ResetOutlineGC \
	(tkStubsPtr->tk_ResetOutlineGC) /* 225 */


#define Tk_CanvasPsOutline \
	(tkStubsPtr->tk_CanvasPsOutline) /* 226 */


#define Tk_SetTSOrigin \
	(tkStubsPtr->tk_SetTSOrigin) /* 227 */


#define Tk_CanvasGetCoordFromObj \
	(tkStubsPtr->tk_CanvasGetCoordFromObj) /* 228 */


#define Tk_CanvasSetOffset \
	(tkStubsPtr->tk_CanvasSetOffset) /* 229 */


#define Tk_DitherPhoto \
	(tkStubsPtr->tk_DitherPhoto) /* 230 */


#define Tk_PostscriptBitmap \
	(tkStubsPtr->tk_PostscriptBitmap) /* 231 */


#define Tk_PostscriptColor \
	(tkStubsPtr->tk_PostscriptColor) /* 232 */


#define Tk_PostscriptFont \
	(tkStubsPtr->tk_PostscriptFont) /* 233 */


#define Tk_PostscriptImage \
	(tkStubsPtr->tk_PostscriptImage) /* 234 */


#define Tk_PostscriptPath \
	(tkStubsPtr->tk_PostscriptPath) /* 235 */


#define Tk_PostscriptStipple \
	(tkStubsPtr->tk_PostscriptStipple) /* 236 */


#define Tk_PostscriptY \
	(tkStubsPtr->tk_PostscriptY) /* 237 */


#define Tk_PostscriptPhoto \
	(tkStubsPtr->tk_PostscriptPhoto) /* 238 */


#define Tk_CreateClientMessageHandler \
	(tkStubsPtr->tk_CreateClientMessageHandler) /* 239 */


#define Tk_DeleteClientMessageHandler \
	(tkStubsPtr->tk_DeleteClientMessageHandler) /* 240 */


#define Tk_CreateAnonymousWindow \
	(tkStubsPtr->tk_CreateAnonymousWindow) /* 241 */


#define Tk_SetClassProcs \
	(tkStubsPtr->tk_SetClassProcs) /* 242 */


#define Tk_SetInternalBorderEx \
	(tkStubsPtr->tk_SetInternalBorderEx) /* 243 */


#define Tk_SetMinimumRequestSize \
	(tkStubsPtr->tk_SetMinimumRequestSize) /* 244 */


#define Tk_SetCaretPos \
	(tkStubsPtr->tk_SetCaretPos) /* 245 */


#define Tk_PhotoPutBlock_Panic \
	(tkStubsPtr->tk_PhotoPutBlock_Panic) /* 246 */


#define Tk_PhotoPutZoomedBlock_Panic \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_Panic) /* 247 */


#define Tk_CollapseMotionEvents \
	(tkStubsPtr->tk_CollapseMotionEvents) /* 248 */


#define Tk_RegisterStyleEngine \
	(tkStubsPtr->tk_RegisterStyleEngine) /* 249 */


#define Tk_GetStyleEngine \
	(tkStubsPtr->tk_GetStyleEngine) /* 250 */


#define Tk_RegisterStyledElement \
	(tkStubsPtr->tk_RegisterStyledElement) /* 251 */


#define Tk_GetElementId \
	(tkStubsPtr->tk_GetElementId) /* 252 */


#define Tk_CreateStyle \
	(tkStubsPtr->tk_CreateStyle) /* 253 */


#define Tk_GetStyle \
	(tkStubsPtr->tk_GetStyle) /* 254 */


#define Tk_FreeStyle \
	(tkStubsPtr->tk_FreeStyle) /* 255 */


#define Tk_NameOfStyle \
	(tkStubsPtr->tk_NameOfStyle) /* 256 */


#define Tk_AllocStyleFromObj \
	(tkStubsPtr->tk_AllocStyleFromObj) /* 257 */


#define Tk_GetStyleFromObj \
	(tkStubsPtr->tk_GetStyleFromObj) /* 258 */


#define Tk_FreeStyleFromObj \
	(tkStubsPtr->tk_FreeStyleFromObj) /* 259 */


#define Tk_GetStyledElement \
	(tkStubsPtr->tk_GetStyledElement) /* 260 */


#define Tk_GetElementSize \
	(tkStubsPtr->tk_GetElementSize) /* 261 */


#define Tk_GetElementBox \
	(tkStubsPtr->tk_GetElementBox) /* 262 */


#define Tk_GetElementBorderWidth \
	(tkStubsPtr->tk_GetElementBorderWidth) /* 263 */


#define Tk_DrawElement \
	(tkStubsPtr->tk_DrawElement) /* 264 */


#define Tk_PhotoExpand \
	(tkStubsPtr->tk_PhotoExpand) /* 265 */


#define Tk_PhotoPutBlock \
	(tkStubsPtr->tk_PhotoPutBlock) /* 266 */


#define Tk_PhotoPutZoomedBlock \
	(tkStubsPtr->tk_PhotoPutZoomedBlock) /* 267 */


#define Tk_PhotoSetSize \
	(tkStubsPtr->tk_PhotoSetSize) /* 268 */


#define Tk_GetUserInactiveTime \
	(tkStubsPtr->tk_GetUserInactiveTime) /* 269 */


#define Tk_ResetUserInactiveTime \
	(tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */


#define Tk_Interp \
	(tkStubsPtr->tk_Interp) /* 271 */


#define Tk_CreateOldImageType \
	(tkStubsPtr->tk_CreateOldImageType) /* 272 */


#define Tk_CreateOldPhotoImageFormat \
	(tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
#define Tk_AlwaysShowSelection \
	(tkStubsPtr->tk_AlwaysShowSelection) /* 274 */
#define Tk_GetButtonMask \
	(tkStubsPtr->tk_GetButtonMask) /* 275 */
#define Tk_GetDoublePixelsFromObj \
	(tkStubsPtr->tk_GetDoublePixelsFromObj) /* 276 */
#define Tk_NewWindowObj \
	(tkStubsPtr->tk_NewWindowObj) /* 277 */
#define Tk_SendVirtualEvent \
	(tkStubsPtr->tk_SendVirtualEvent) /* 278 */
#define Tk_FontGetDescription \
	(tkStubsPtr->tk_FontGetDescription) /* 279 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

/* Functions that don't belong in the stub table */
#undef Tk_MainEx
#undef Tk_Init
#undef Tk_SafeInit
#undef Tk_CreateConsoleWindow

#undef Tk_FreeXId
#define Tk_FreeXId(display,xid)
#undef Tk_GetStyleFromObj
#undef Tk_FreeStyleFromObj
#define Tk_GetStyleFromObj(obj) Tk_AllocStyleFromObj(NULL, obj)
#define Tk_FreeStyleFromObj(obj) /* no-op */
#define Tk_GetImageMasterData Tk_GetImageModelData

#if defined(_WIN32) && defined(UNICODE)
#   define Tk_MainEx Tk_MainExW
    EXTERN void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif



#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#undef Tk_PhotoPutBlock_NoComposite
#undef Tk_PhotoPutZoomedBlock_NoComposite
#undef Tk_PhotoExpand_Panic
#undef Tk_PhotoPutBlock_Panic
#undef Tk_PhotoPutZoomedBlock_Panic
#undef Tk_PhotoSetSize_Panic
#undef Tk_CreateOldPhotoImageFormat
#endif /* TK_NO_DEPRECATED */


#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT



#endif /* _TKDECLS */








<
<
<
<
<
<
<
<
















>
>


>
>
>


>
>
>



>
>
>





>
>
>





>
>
>

|
|
>
>
>




>
>
>




>
>
>



>
>
>


|

>
>
>


>
>
>




>
>
>



>
>
>



>
>
>



>
>
>



>
>
>


>
>
>


>
>
>



|
>
>
>

|


>
>
>


>
>
>




>
>
>




>
>
>




>
>
>


>
>
>



|
>
>
>



>
>
>


|
|
>
>
>


|
|

>
>
>


|
|

>
>
>




>
>
>

|



>
>
>



>
>
>



|
|
>
>
>


>
>
>





>
>
>




>
>
>



>
>
>

|
>
>
>


>
>
>


|
>
>
>




>
>
>


|
>
>
>


|
|
>
>
>

|
|
>
>
>


>
>
>



>
>
>



|
>
>
>


>
>
>


>
>
>




>
>
>



>
>
>

|
>
>
>



>
>
>


>
>
>

|
>
>
>



>
>
>





>
>
>





>
>
>


|

>
>
>



>
>
>





>
>
>





>
>
>





>
>
>


|
>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>

|
|
|
>
>


>
>
>


>
>
>

<
|
>
>
>


>
>
>



>
>
>



>
>
>




>
>
>

|

>
>
>

|
>
>
>

|

|
>
>
>


|
>
>
>


|

>
>
>

|

>
>
>



>
>
>


>
>
>


|
>
>
>



>
>
>


|
|

>
>
>


|
>
>
>


>
>
>



>
>
>



>
>
>


|


>
>
>

|
<
|
>
>
>


>
>
>

|

>
>
>

|

>
>
>


>
>
>

|
|
>
>
>


|
>
>
>



>
>
>

|

>
>
>



>
>
>


|

>
>
>


|
>
>
>




>
>
>

|
>
>
>


|

>
>
>



>
>
>



>
>
>


>
>
>


>
>
>

|


>
>
>


>
>
>

|
>
>
>



>
>
>

|
|

>
>
>


>
>
>


>
>
>


|

>
>
>


>
>
>

|


>
>
>



>
>
>


>
>
>


>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>


|
>
>
>



>
>
>


|
|
>
>
>

<
|


>
>
>

<
|




>
>
>



>
>
>


>
>
>

<
|

>
>
>



>
>
>

<
|

>
>
>


>
>
>



>
>
>



>
>
>



>
>
>





>
>
>



>
>
>



>
>
>



>
>
>


>
>
>

|
>
>
>



>
>
>

|
>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>



>
>
>



>
>
>


>
>
>



>
>
>

|

>
>
>


>
>
>



|

>
>
>





>
>
>


>
>
>

|
|
>
>
>


>
>
>


>
>
>



>
>
>



>
>
>



>
>
>



>
>
>



>
>
>



>
>
>


|
>
>
>


>
>
>



>
>
>



>
>
>


>
>
>

|

>
>
>


>
>
>



>
>
>


>
>
>



>
>
>



>
>
>


>
>
>


>
>
>


>
>
>

|


>
>
>


|

>
>
>



>
>
>



>
>
>




>
>
>



>
>
>


|

>
>
>

|

>
>
>




>
>
>


>
>
>

|

|

>
>
>


>
>
>


>
>
>


|
>


>
>

|

>
>
>


>
>
>



>
>
>




>
>
>



>
>
>



>
>
>



>
>
>


>
>
>




>
>
>



>
>
>



>
>
>





>
>
>



>
>
>



>
>
>





>
>
>




>
>
>




>
>
>


>
>
>





>
>
>



>
>
>



>
>
>


|
>
>
>


|

>
>
>



>
>
>



>
>
>



>
>
>

<
|


>
>
>

<
|



>
>
>



>
>
>

|

>
>
>

|
>
>
>



>
>
>

|
>
>
>

|

>
>
>

|
>
>
>


>
>
>

|
>
>
>



>
>
>


>
>
>


>
>
>



>
>
>


|


>
>
>


|



>
>
>


|

>
>
>


|


>
>
>



>
>
>





>
>
>






>
>
>



>
>
>


>
>
>


>
>
>


>
>
>

|
>
>
>


|
>
|
<
|
<
|
<
<
<
|
<
|
<
<
>
>
>
|
|
>

|
|
|
|
|




|






|



|








|
|





|

|
|
|

|

|




|

|

|
|
|


|




|


|



|




|









|


|




|
|
|
|
|
|


|

|
|



|
|

|
|

|
|

|

|
|

|
|




|

|

|


|

|



|
|
|
|
|
|
|
|
|
|
|
|

|
|
|


|

|









|

|













|

|


|








|




|








|
|




|
|
|

|


|
|
|
|




















|
|



|
|

|
|

|
|
|

|




|
|
|
|







|
|
|
|
|
|
|
>
|


|





|





>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>
|
|
>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>


>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


|
|
<
|
<
<
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
|
|
|
<
<
<
<
<
|
<
<
<
<


>

<
<
<
<
<
<
<
<
<
>




>
>

>
13
14
15
16
17
18
19








20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905

906
907
908
909
910
911
912

913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
942
943
944

945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514
1515
1516
1517

1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681

1682

1683



1684

1685


1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089

3090








3091

3092

3093





3094
3095
3096





3097




3098
3099
3100
3101









3102
3103
3104
3105
3106
3107
3108
3109
3110
#define _TKDECLS

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif









/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#ifndef Tk_MainLoop_TCL_DECLARED
#define Tk_MainLoop_TCL_DECLARED
/* 0 */
EXTERN void		Tk_MainLoop(void);
#endif
#ifndef Tk_3DBorderColor_TCL_DECLARED
#define Tk_3DBorderColor_TCL_DECLARED
/* 1 */
EXTERN XColor *		Tk_3DBorderColor(Tk_3DBorder border);
#endif
#ifndef Tk_3DBorderGC_TCL_DECLARED
#define Tk_3DBorderGC_TCL_DECLARED
/* 2 */
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(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height, int leftIn,
				int rightIn, int topBevel, int relief);
#endif
#ifndef Tk_3DVerticalBevel_TCL_DECLARED
#define Tk_3DVerticalBevel_TCL_DECLARED
/* 4 */
EXTERN void		Tk_3DVerticalBevel(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height, int leftBevel,
				int relief);
#endif
#ifndef Tk_AddOption_TCL_DECLARED
#define Tk_AddOption_TCL_DECLARED
/* 5 */
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(Tk_BindingTable bindingTable,
				XEvent *eventPtr, Tk_Window tkwin,
				int numObjects, ClientData *objectPtr);
#endif
#ifndef Tk_CanvasDrawableCoords_TCL_DECLARED
#define Tk_CanvasDrawableCoords_TCL_DECLARED
/* 7 */
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(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(Tcl_Interp *interp,
				Tk_Canvas canvas, CONST char *str,
				double *doublePtr);
#endif
#ifndef Tk_CanvasGetTextInfo_TCL_DECLARED
#define Tk_CanvasGetTextInfo_TCL_DECLARED
/* 10 */
EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo(Tk_Canvas canvas);
#endif
#ifndef Tk_CanvasPsBitmap_TCL_DECLARED
#define Tk_CanvasPsBitmap_TCL_DECLARED
/* 11 */
EXTERN int		Tk_CanvasPsBitmap(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap, int x,
				int y, int width, int height);
#endif
#ifndef Tk_CanvasPsColor_TCL_DECLARED
#define Tk_CanvasPsColor_TCL_DECLARED
/* 12 */
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(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(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(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap);
#endif
#ifndef Tk_CanvasPsY_TCL_DECLARED
#define Tk_CanvasPsY_TCL_DECLARED
/* 16 */
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(Tk_Canvas canvas, GC gc);
#endif
#ifndef Tk_CanvasTagsParseProc_TCL_DECLARED
#define Tk_CanvasTagsParseProc_TCL_DECLARED
/* 18 */
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(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(Tk_Canvas canvas);
#endif
#ifndef Tk_CanvasWindowCoords_TCL_DECLARED
#define Tk_CanvasWindowCoords_TCL_DECLARED
/* 21 */
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(Tk_Window tkwin,
				unsigned long valueMask,
				XSetWindowAttributes *attsPtr);
#endif
#ifndef Tk_CharBbox_TCL_DECLARED
#define Tk_CharBbox_TCL_DECLARED
/* 23 */
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(Tk_Window tkwin, Atom selection);
#endif
#ifndef Tk_ClipboardAppend_TCL_DECLARED
#define Tk_ClipboardAppend_TCL_DECLARED
/* 25 */
EXTERN int		Tk_ClipboardAppend(Tcl_Interp *interp,
				Tk_Window tkwin, Atom target, Atom format,
				char *buffer);
#endif
#ifndef Tk_ClipboardClear_TCL_DECLARED
#define Tk_ClipboardClear_TCL_DECLARED
/* 26 */
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(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(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_ConfigSpec *specs,
				char *widgRec, CONST char *argvName,
				int flags);
#endif
#ifndef Tk_ConfigureWidget_TCL_DECLARED
#define Tk_ConfigureWidget_TCL_DECLARED
/* 29 */
EXTERN int		Tk_ConfigureWidget(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_ConfigSpec *specs,
				int argc, CONST84 char **argv, char *widgRec,
				int flags);
#endif
#ifndef Tk_ConfigureWindow_TCL_DECLARED
#define Tk_ConfigureWindow_TCL_DECLARED
/* 30 */
EXTERN void		Tk_ConfigureWindow(Tk_Window tkwin,
				unsigned int valueMask,
				XWindowChanges *valuePtr);
#endif
#ifndef Tk_ComputeTextLayout_TCL_DECLARED
#define Tk_ComputeTextLayout_TCL_DECLARED
/* 31 */
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(int rootX, int rootY,
				Tk_Window tkwin);
#endif
#ifndef Tk_CreateBinding_TCL_DECLARED
#define Tk_CreateBinding_TCL_DECLARED
/* 33 */
EXTERN unsigned long	Tk_CreateBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, CONST char *eventStr,
				CONST char *command, int append);
#endif
#ifndef Tk_CreateBindingTable_TCL_DECLARED
#define Tk_CreateBindingTable_TCL_DECLARED
/* 34 */
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(Display *display, int errNum,
				int request, int minorCode,
				Tk_ErrorProc *errorProc,
				ClientData clientData);
#endif
#ifndef Tk_CreateEventHandler_TCL_DECLARED
#define Tk_CreateEventHandler_TCL_DECLARED
/* 36 */
EXTERN void		Tk_CreateEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);
#endif
#ifndef Tk_CreateGenericHandler_TCL_DECLARED
#define Tk_CreateGenericHandler_TCL_DECLARED
/* 37 */
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(Tk_ImageType *typePtr);
#endif
#ifndef Tk_CreateItemType_TCL_DECLARED
#define Tk_CreateItemType_TCL_DECLARED
/* 39 */
EXTERN void		Tk_CreateItemType(Tk_ItemType *typePtr);
#endif
#ifndef Tk_CreatePhotoImageFormat_TCL_DECLARED
#define Tk_CreatePhotoImageFormat_TCL_DECLARED
/* 40 */
EXTERN void		Tk_CreatePhotoImageFormat(
				Tk_PhotoImageFormat *formatPtr);
#endif
#ifndef Tk_CreateSelHandler_TCL_DECLARED
#define Tk_CreateSelHandler_TCL_DECLARED
/* 41 */
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(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(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(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(Tk_Window window, Tk_Cursor cursor);
#endif
#ifndef Tk_DeleteAllBindings_TCL_DECLARED
#define Tk_DeleteAllBindings_TCL_DECLARED
/* 46 */
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(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, CONST char *eventStr);
#endif
#ifndef Tk_DeleteBindingTable_TCL_DECLARED
#define Tk_DeleteBindingTable_TCL_DECLARED
/* 48 */
EXTERN void		Tk_DeleteBindingTable(Tk_BindingTable bindingTable);
#endif
#ifndef Tk_DeleteErrorHandler_TCL_DECLARED
#define Tk_DeleteErrorHandler_TCL_DECLARED
/* 49 */
EXTERN void		Tk_DeleteErrorHandler(Tk_ErrorHandler handler);
#endif
#ifndef Tk_DeleteEventHandler_TCL_DECLARED
#define Tk_DeleteEventHandler_TCL_DECLARED
/* 50 */
EXTERN void		Tk_DeleteEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);
#endif
#ifndef Tk_DeleteGenericHandler_TCL_DECLARED
#define Tk_DeleteGenericHandler_TCL_DECLARED
/* 51 */
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(Tcl_Interp *interp, CONST char *name);
#endif
#ifndef Tk_DeleteSelHandler_TCL_DECLARED
#define Tk_DeleteSelHandler_TCL_DECLARED
/* 53 */
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(Tk_Window tkwin);
#endif
#ifndef Tk_DisplayName_TCL_DECLARED
#define Tk_DisplayName_TCL_DECLARED
/* 55 */
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(Tk_TextLayout layout, int x,
				int y);
#endif
#ifndef Tk_Draw3DPolygon_TCL_DECLARED
#define Tk_Draw3DPolygon_TCL_DECLARED
/* 57 */
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(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
#endif
#ifndef Tk_DrawChars_TCL_DECLARED
#define Tk_DrawChars_TCL_DECLARED
/* 59 */
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(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(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int firstChar, int lastChar);
#endif
#ifndef Tk_Fill3DPolygon_TCL_DECLARED
#define Tk_Fill3DPolygon_TCL_DECLARED
/* 62 */
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(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
#endif
#ifndef Tk_FindPhoto_TCL_DECLARED
#define Tk_FindPhoto_TCL_DECLARED
/* 64 */
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(Tk_Font font);
#endif
#ifndef Tk_Free3DBorder_TCL_DECLARED
#define Tk_Free3DBorder_TCL_DECLARED
/* 66 */
EXTERN void		Tk_Free3DBorder(Tk_3DBorder border);
#endif
#ifndef Tk_FreeBitmap_TCL_DECLARED
#define Tk_FreeBitmap_TCL_DECLARED
/* 67 */
EXTERN void		Tk_FreeBitmap(Display *display, Pixmap bitmap);
#endif
#ifndef Tk_FreeColor_TCL_DECLARED
#define Tk_FreeColor_TCL_DECLARED
/* 68 */
EXTERN void		Tk_FreeColor(XColor *colorPtr);
#endif
#ifndef Tk_FreeColormap_TCL_DECLARED
#define Tk_FreeColormap_TCL_DECLARED
/* 69 */
EXTERN void		Tk_FreeColormap(Display *display, Colormap colormap);
#endif
#ifndef Tk_FreeCursor_TCL_DECLARED
#define Tk_FreeCursor_TCL_DECLARED
/* 70 */
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(Tk_Font f);
#endif
#ifndef Tk_FreeGC_TCL_DECLARED
#define Tk_FreeGC_TCL_DECLARED
/* 72 */
EXTERN void		Tk_FreeGC(Display *display, GC gc);
#endif
#ifndef Tk_FreeImage_TCL_DECLARED
#define Tk_FreeImage_TCL_DECLARED
/* 73 */
EXTERN void		Tk_FreeImage(Tk_Image image);
#endif
#ifndef Tk_FreeOptions_TCL_DECLARED
#define Tk_FreeOptions_TCL_DECLARED
/* 74 */
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(Display *display, Pixmap pixmap);
#endif
#ifndef Tk_FreeTextLayout_TCL_DECLARED
#define Tk_FreeTextLayout_TCL_DECLARED
/* 76 */
EXTERN void		Tk_FreeTextLayout(Tk_TextLayout textLayout);
#endif
#ifndef Tk_FreeXId_TCL_DECLARED
#define Tk_FreeXId_TCL_DECLARED
/* 77 */

EXTERN void		Tk_FreeXId(Display *display, XID xid);
#endif
#ifndef Tk_GCForColor_TCL_DECLARED
#define Tk_GCForColor_TCL_DECLARED
/* 78 */
EXTERN GC		Tk_GCForColor(XColor *colorPtr, Drawable drawable);
#endif
#ifndef Tk_GeometryRequest_TCL_DECLARED
#define Tk_GeometryRequest_TCL_DECLARED
/* 79 */
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(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(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object);
#endif
#ifndef Tk_GetAnchor_TCL_DECLARED
#define Tk_GetAnchor_TCL_DECLARED
/* 82 */
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(Tk_Window tkwin, Atom atom);
#endif
#ifndef Tk_GetBinding_TCL_DECLARED
#define Tk_GetBinding_TCL_DECLARED
/* 84 */
EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, CONST char *eventStr);
#endif
#ifndef Tk_GetBitmap_TCL_DECLARED
#define Tk_GetBitmap_TCL_DECLARED
/* 85 */
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(Tcl_Interp *interp,
				Tk_Window tkwin, CONST char *source,
				int width, int height);
#endif
#ifndef Tk_GetCapStyle_TCL_DECLARED
#define Tk_GetCapStyle_TCL_DECLARED
/* 87 */
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(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(Tk_Window tkwin, XColor *colorPtr);
#endif
#ifndef Tk_GetColormap_TCL_DECLARED
#define Tk_GetColormap_TCL_DECLARED
/* 90 */
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(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(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);
#endif
#ifndef Tk_GetFont_TCL_DECLARED
#define Tk_GetFont_TCL_DECLARED
/* 93 */
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(Tk_Window tkwin, Tcl_Obj *objPtr);
#endif
#ifndef Tk_GetFontMetrics_TCL_DECLARED
#define Tk_GetFontMetrics_TCL_DECLARED
/* 95 */
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(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(Tcl_Interp *interp, Tk_Window tkwin,
				CONST char *name,
				Tk_ImageChangedProc *changeProc,
				ClientData clientData);
#endif
#ifndef Tk_GetImageMasterData_TCL_DECLARED
#define Tk_GetImageMasterData_TCL_DECLARED
/* 98 */
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(void);
#endif
#ifndef Tk_GetJoinStyle_TCL_DECLARED
#define Tk_GetJoinStyle_TCL_DECLARED
/* 100 */
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(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(void);
#endif
#ifndef Tk_GetOption_TCL_DECLARED
#define Tk_GetOption_TCL_DECLARED
/* 103 */
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(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(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(Tcl_Interp *interp, CONST char *name,
				int *reliefPtr);
#endif
#ifndef Tk_GetRootCoords_TCL_DECLARED
#define Tk_GetRootCoords_TCL_DECLARED
/* 107 */
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(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(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(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(CONST char *str);
#endif
#ifndef Tk_GetVisual_TCL_DECLARED
#define Tk_GetVisual_TCL_DECLARED
/* 112 */
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(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(Tcl_Interp *interp, Tk_Window tkwin,
				int grabGlobal);
#endif
#ifndef Tk_HandleEvent_TCL_DECLARED
#define Tk_HandleEvent_TCL_DECLARED
/* 115 */
EXTERN void		Tk_HandleEvent(XEvent *eventPtr);
#endif
#ifndef Tk_IdToWindow_TCL_DECLARED
#define Tk_IdToWindow_TCL_DECLARED
/* 116 */
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(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(Tcl_Interp *interp);
#endif
#ifndef Tk_InternAtom_TCL_DECLARED
#define Tk_InternAtom_TCL_DECLARED
/* 119 */
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(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(Tk_Window slave,
				Tk_Window master, int x, int y, int width,
				int height);
#endif
#ifndef Tk_MainWindow_TCL_DECLARED
#define Tk_MainWindow_TCL_DECLARED
/* 122 */
EXTERN Tk_Window	Tk_MainWindow(Tcl_Interp *interp);
#endif
#ifndef Tk_MakeWindowExist_TCL_DECLARED
#define Tk_MakeWindowExist_TCL_DECLARED
/* 123 */
EXTERN void		Tk_MakeWindowExist(Tk_Window tkwin);
#endif
#ifndef Tk_ManageGeometry_TCL_DECLARED
#define Tk_ManageGeometry_TCL_DECLARED
/* 124 */
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(Tk_Window tkwin);
#endif
#ifndef Tk_MeasureChars_TCL_DECLARED
#define Tk_MeasureChars_TCL_DECLARED
/* 126 */
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(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(Tk_Window tkwin, int x, int y);
#endif
#ifndef Tk_MoveToplevelWindow_TCL_DECLARED
#define Tk_MoveToplevelWindow_TCL_DECLARED
/* 129 */
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(Tk_3DBorder border);
#endif
#ifndef Tk_NameOfAnchor_TCL_DECLARED
#define Tk_NameOfAnchor_TCL_DECLARED
/* 131 */
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(Display *display, Pixmap bitmap);
#endif
#ifndef Tk_NameOfCapStyle_TCL_DECLARED
#define Tk_NameOfCapStyle_TCL_DECLARED
/* 133 */
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(XColor *colorPtr);
#endif
#ifndef Tk_NameOfCursor_TCL_DECLARED
#define Tk_NameOfCursor_TCL_DECLARED
/* 135 */
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(Tk_Font font);
#endif
#ifndef Tk_NameOfImage_TCL_DECLARED
#define Tk_NameOfImage_TCL_DECLARED
/* 137 */
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(int join);
#endif
#ifndef Tk_NameOfJustify_TCL_DECLARED
#define Tk_NameOfJustify_TCL_DECLARED
/* 139 */
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(int relief);
#endif
#ifndef Tk_NameToWindow_TCL_DECLARED
#define Tk_NameToWindow_TCL_DECLARED
/* 141 */
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(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(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(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height);
#endif
#ifndef Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED
#define Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED
/* 145 */

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);
#endif
#ifndef Tk_PhotoGetImage_TCL_DECLARED
#define Tk_PhotoGetImage_TCL_DECLARED
/* 146 */
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(Tk_PhotoHandle handle);
#endif
#ifndef Tk_PhotoExpand_Panic_TCL_DECLARED
#define Tk_PhotoExpand_Panic_TCL_DECLARED
/* 148 */

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(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_Panic(Tk_PhotoHandle handle,
				int width, int height);
#endif
#ifndef Tk_PointToChar_TCL_DECLARED
#define Tk_PointToChar_TCL_DECLARED
/* 151 */
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(Tk_Font tkfont,
				Tcl_DString *dsPtr);
#endif
#ifndef Tk_PreserveColormap_TCL_DECLARED
#define Tk_PreserveColormap_TCL_DECLARED
/* 153 */
EXTERN void		Tk_PreserveColormap(Display *display,
				Colormap colormap);
#endif
#ifndef Tk_QueueWindowEvent_TCL_DECLARED
#define Tk_QueueWindowEvent_TCL_DECLARED
/* 154 */
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(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(Tk_Window tkwin, int width,
				int height);
#endif
#ifndef Tk_RestackWindow_TCL_DECLARED
#define Tk_RestackWindow_TCL_DECLARED
/* 157 */
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(Tk_RestrictProc *proc,
				ClientData arg, ClientData *prevArgPtr);
#endif
#ifndef Tk_SafeInit_TCL_DECLARED
#define Tk_SafeInit_TCL_DECLARED
/* 159 */
EXTERN int		Tk_SafeInit(Tcl_Interp *interp);
#endif
#ifndef Tk_SetAppName_TCL_DECLARED
#define Tk_SetAppName_TCL_DECLARED
/* 160 */
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(Tk_Window tkwin,
				Tk_3DBorder border);
#endif
#ifndef Tk_SetClass_TCL_DECLARED
#define Tk_SetClass_TCL_DECLARED
/* 162 */
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(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(Tk_Window tkwin, int width);
#endif
#ifndef Tk_SetWindowBackground_TCL_DECLARED
#define Tk_SetWindowBackground_TCL_DECLARED
/* 165 */
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(Tk_Window tkwin,
				Pixmap pixmap);
#endif
#ifndef Tk_SetWindowBorder_TCL_DECLARED
#define Tk_SetWindowBorder_TCL_DECLARED
/* 167 */
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(Tk_Window tkwin, int width);
#endif
#ifndef Tk_SetWindowBorderPixmap_TCL_DECLARED
#define Tk_SetWindowBorderPixmap_TCL_DECLARED
/* 169 */
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(Tk_Window tkwin,
				Colormap colormap);
#endif
#ifndef Tk_SetWindowVisual_TCL_DECLARED
#define Tk_SetWindowVisual_TCL_DECLARED
/* 171 */
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(Display *display, Pixmap bitmap,
				int *widthPtr, int *heightPtr);
#endif
#ifndef Tk_SizeOfImage_TCL_DECLARED
#define Tk_SizeOfImage_TCL_DECLARED
/* 173 */
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(Tk_Window tkwin);
#endif
#ifndef Tk_TextLayoutToPostscript_TCL_DECLARED
#define Tk_TextLayoutToPostscript_TCL_DECLARED
/* 175 */
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(Tk_Font font, CONST char *str,
				int numBytes);
#endif
#ifndef Tk_UndefineCursor_TCL_DECLARED
#define Tk_UndefineCursor_TCL_DECLARED
/* 177 */
EXTERN void		Tk_UndefineCursor(Tk_Window window);
#endif
#ifndef Tk_UnderlineChars_TCL_DECLARED
#define Tk_UnderlineChars_TCL_DECLARED
/* 178 */
EXTERN void		Tk_UnderlineChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				CONST char *source, int x, int y,
				int firstByte, int lastByte);
#endif
#ifndef Tk_UnderlineTextLayout_TCL_DECLARED
#define Tk_UnderlineTextLayout_TCL_DECLARED
/* 179 */
EXTERN void		Tk_UnderlineTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int underline);
#endif
#ifndef Tk_Ungrab_TCL_DECLARED
#define Tk_Ungrab_TCL_DECLARED
/* 180 */
EXTERN void		Tk_Ungrab(Tk_Window tkwin);
#endif
#ifndef Tk_UnmaintainGeometry_TCL_DECLARED
#define Tk_UnmaintainGeometry_TCL_DECLARED
/* 181 */
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(Tk_Window tkwin);
#endif
#ifndef Tk_UnsetGrid_TCL_DECLARED
#define Tk_UnsetGrid_TCL_DECLARED
/* 183 */
EXTERN void		Tk_UnsetGrid(Tk_Window tkwin);
#endif
#ifndef Tk_UpdatePointer_TCL_DECLARED
#define Tk_UpdatePointer_TCL_DECLARED
/* 184 */
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(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(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(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(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(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(Tcl_Interp *interp,
				CONST Tk_OptionSpec *templatePtr);
#endif
#ifndef Tk_DeleteOptionTable_TCL_DECLARED
#define Tk_DeleteOptionTable_TCL_DECLARED
/* 191 */
EXTERN void		Tk_DeleteOptionTable(Tk_OptionTable optionTable);
#endif
#ifndef Tk_Free3DBorderFromObj_TCL_DECLARED
#define Tk_Free3DBorderFromObj_TCL_DECLARED
/* 192 */
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(Tk_Window tkwin,
				Tcl_Obj *objPtr);
#endif
#ifndef Tk_FreeColorFromObj_TCL_DECLARED
#define Tk_FreeColorFromObj_TCL_DECLARED
/* 194 */
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(char *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
#endif
#ifndef Tk_FreeSavedOptions_TCL_DECLARED
#define Tk_FreeSavedOptions_TCL_DECLARED
/* 196 */
EXTERN void		Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);
#endif
#ifndef Tk_FreeCursorFromObj_TCL_DECLARED
#define Tk_FreeCursorFromObj_TCL_DECLARED
/* 197 */
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(Tk_Window tkwin, Tcl_Obj *objPtr);
#endif
#ifndef Tk_Get3DBorderFromObj_TCL_DECLARED
#define Tk_Get3DBorderFromObj_TCL_DECLARED
/* 199 */
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(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(Tk_Window tkwin, Tcl_Obj *objPtr);
#endif
#ifndef Tk_GetColorFromObj_TCL_DECLARED
#define Tk_GetColorFromObj_TCL_DECLARED
/* 202 */
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(Tk_Window tkwin, Tcl_Obj *objPtr);
#endif
#ifndef Tk_GetOptionInfo_TCL_DECLARED
#define Tk_GetOptionInfo_TCL_DECLARED
/* 204 */
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(Tcl_Interp *interp,
				char *recordPtr, Tk_OptionTable optionTable,
				Tcl_Obj *namePtr, Tk_Window tkwin);
#endif
#ifndef Tk_GetJustifyFromObj_TCL_DECLARED
#define Tk_GetJustifyFromObj_TCL_DECLARED
/* 206 */
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(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(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);
#endif
#ifndef Tk_GetReliefFromObj_TCL_DECLARED
#define Tk_GetReliefFromObj_TCL_DECLARED
/* 209 */
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(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(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(int argc, char **argv,
				Tcl_AppInitProc *appInitProc,
				Tcl_Interp *interp);
#endif
#ifndef Tk_RestoreSavedOptions_TCL_DECLARED
#define Tk_RestoreSavedOptions_TCL_DECLARED
/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
#endif
#ifndef Tk_SetOptions_TCL_DECLARED
#define Tk_SetOptions_TCL_DECLARED
/* 214 */
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(Tcl_Interp *interp);
#endif
#ifndef Tk_CreateConsoleWindow_TCL_DECLARED
#define Tk_CreateConsoleWindow_TCL_DECLARED
/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);
#endif
#ifndef Tk_CreateSmoothMethod_TCL_DECLARED
#define Tk_CreateSmoothMethod_TCL_DECLARED
/* 217 */
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(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(Tk_Outline *outline);
#endif
#ifndef Tk_DeleteOutline_TCL_DECLARED
#define Tk_DeleteOutline_TCL_DECLARED
/* 222 */
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(XGCValues *gcValues,
				Tk_Canvas canvas, Tk_Item *item,
				Tk_Outline *outline);
#endif
#ifndef Tk_ChangeOutlineGC_TCL_DECLARED
#define Tk_ChangeOutlineGC_TCL_DECLARED
/* 224 */
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(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(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(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(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(Tk_Canvas canvas, GC gc,
				Tk_TSOffset *offset);
#endif
#ifndef Tk_DitherPhoto_TCL_DECLARED
#define Tk_DitherPhoto_TCL_DECLARED
/* 230 */
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(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap, int startX, int startY,
				int width, int height);
#endif
#ifndef Tk_PostscriptColor_TCL_DECLARED
#define Tk_PostscriptColor_TCL_DECLARED
/* 232 */
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(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(Tk_Image image,
				Tcl_Interp *interp, Tk_Window tkwin,
				Tk_PostscriptInfo psinfo, int x, int y,
				int width, int height, int prepass);
#endif
#ifndef Tk_PostscriptPath_TCL_DECLARED
#define Tk_PostscriptPath_TCL_DECLARED
/* 235 */
EXTERN void		Tk_PostscriptPath(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, double *coordPtr,
				int numPoints);
#endif
#ifndef Tk_PostscriptStipple_TCL_DECLARED
#define Tk_PostscriptStipple_TCL_DECLARED
/* 236 */
EXTERN int		Tk_PostscriptStipple(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap);
#endif
#ifndef Tk_PostscriptY_TCL_DECLARED
#define Tk_PostscriptY_TCL_DECLARED
/* 237 */
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(Tcl_Interp *interp,
				Tk_PhotoImageBlock *blockPtr,
				Tk_PostscriptInfo psInfo, int width,
				int height);
#endif
#ifndef Tk_CreateClientMessageHandler_TCL_DECLARED
#define Tk_CreateClientMessageHandler_TCL_DECLARED
/* 239 */
EXTERN void		Tk_CreateClientMessageHandler(
				Tk_ClientMessageProc *proc);
#endif
#ifndef Tk_DeleteClientMessageHandler_TCL_DECLARED
#define Tk_DeleteClientMessageHandler_TCL_DECLARED
/* 240 */
EXTERN void		Tk_DeleteClientMessageHandler(
				Tk_ClientMessageProc *proc);
#endif
#ifndef Tk_CreateAnonymousWindow_TCL_DECLARED
#define Tk_CreateAnonymousWindow_TCL_DECLARED
/* 241 */
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(Tk_Window tkwin,
				Tk_ClassProcs *procs,
				ClientData instanceData);
#endif
#ifndef Tk_SetInternalBorderEx_TCL_DECLARED
#define Tk_SetInternalBorderEx_TCL_DECLARED
/* 243 */
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(Tk_Window tkwin,
				int minWidth, int minHeight);
#endif
#ifndef Tk_SetCaretPos_TCL_DECLARED
#define Tk_SetCaretPos_TCL_DECLARED
/* 245 */
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_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int compRule);
#endif
#ifndef Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED
#define Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED
/* 247 */

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);
#endif
#ifndef Tk_CollapseMotionEvents_TCL_DECLARED
#define Tk_CollapseMotionEvents_TCL_DECLARED
/* 248 */
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(CONST char *name,
				Tk_StyleEngine parent);
#endif
#ifndef Tk_GetStyleEngine_TCL_DECLARED
#define Tk_GetStyleEngine_TCL_DECLARED
/* 250 */
EXTERN Tk_StyleEngine	Tk_GetStyleEngine(CONST char *name);
#endif
#ifndef Tk_RegisterStyledElement_TCL_DECLARED
#define Tk_RegisterStyledElement_TCL_DECLARED
/* 251 */
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(CONST char *name);
#endif
#ifndef Tk_CreateStyle_TCL_DECLARED
#define Tk_CreateStyle_TCL_DECLARED
/* 253 */
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(Tcl_Interp *interp, CONST char *name);
#endif
#ifndef Tk_FreeStyle_TCL_DECLARED
#define Tk_FreeStyle_TCL_DECLARED
/* 255 */
EXTERN void		Tk_FreeStyle(Tk_Style style);
#endif
#ifndef Tk_NameOfStyle_TCL_DECLARED
#define Tk_NameOfStyle_TCL_DECLARED
/* 256 */
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(Tcl_Interp *interp,
				Tcl_Obj *objPtr);
#endif
#ifndef Tk_GetStyleFromObj_TCL_DECLARED
#define Tk_GetStyleFromObj_TCL_DECLARED
/* 258 */
EXTERN Tk_Style		Tk_GetStyleFromObj(Tcl_Obj *objPtr);
#endif
#ifndef Tk_FreeStyleFromObj_TCL_DECLARED
#define Tk_FreeStyleFromObj_TCL_DECLARED
/* 259 */
EXTERN void		Tk_FreeStyleFromObj(Tcl_Obj *objPtr);
#endif
#ifndef Tk_GetStyledElement_TCL_DECLARED
#define Tk_GetStyledElement_TCL_DECLARED
/* 260 */
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(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);
#endif
#ifndef Tk_GetElementBox_TCL_DECLARED
#define Tk_GetElementBox_TCL_DECLARED
/* 262 */
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);
#endif
#ifndef Tk_GetElementBorderWidth_TCL_DECLARED
#define Tk_GetElementBorderWidth_TCL_DECLARED
/* 263 */
EXTERN int		Tk_GetElementBorderWidth(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin);
#endif
#ifndef Tk_DrawElement_TCL_DECLARED
#define Tk_DrawElement_TCL_DECLARED
/* 264 */
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);
#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
/* Slot 274 is reserved */

/* Slot 275 is reserved */

/* Slot 276 is reserved */



/* Slot 277 is reserved */

/* Slot 278 is reserved */


/* Slot 279 is reserved */
#ifndef TkUnusedStubEntry_TCL_DECLARED
#define TkUnusedStubEntry_TCL_DECLARED
/* 280 */
EXTERN void		TkUnusedStubEntry(void);
#endif

typedef struct TkStubHooks {
    struct TkPlatStubs *tkPlatStubs;
    struct TkIntStubs *tkIntStubs;
    struct TkIntPlatStubs *tkIntPlatStubs;
    struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;

typedef struct TkStubs {
    int magic;
    struct TkStubHooks *hooks;

    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) (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 */
    VOID *reserved274;
    VOID *reserved275;
    VOID *reserved276;
    VOID *reserved277;
    VOID *reserved278;
    VOID *reserved279;
    void (*tkUnusedStubEntry) (void); /* 280 */
} TkStubs;

extern TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)

/*
 * Inline function declarations:
 */

#ifndef Tk_MainLoop
#define Tk_MainLoop \
	(tkStubsPtr->tk_MainLoop) /* 0 */
#endif
#ifndef Tk_3DBorderColor
#define Tk_3DBorderColor \
	(tkStubsPtr->tk_3DBorderColor) /* 1 */
#endif
#ifndef Tk_3DBorderGC
#define Tk_3DBorderGC \
	(tkStubsPtr->tk_3DBorderGC) /* 2 */
#endif
#ifndef Tk_3DHorizontalBevel
#define Tk_3DHorizontalBevel \
	(tkStubsPtr->tk_3DHorizontalBevel) /* 3 */
#endif
#ifndef Tk_3DVerticalBevel
#define Tk_3DVerticalBevel \
	(tkStubsPtr->tk_3DVerticalBevel) /* 4 */
#endif
#ifndef Tk_AddOption
#define Tk_AddOption \
	(tkStubsPtr->tk_AddOption) /* 5 */
#endif
#ifndef Tk_BindEvent
#define Tk_BindEvent \
	(tkStubsPtr->tk_BindEvent) /* 6 */
#endif
#ifndef Tk_CanvasDrawableCoords
#define Tk_CanvasDrawableCoords \
	(tkStubsPtr->tk_CanvasDrawableCoords) /* 7 */
#endif
#ifndef Tk_CanvasEventuallyRedraw
#define Tk_CanvasEventuallyRedraw \
	(tkStubsPtr->tk_CanvasEventuallyRedraw) /* 8 */
#endif
#ifndef Tk_CanvasGetCoord
#define Tk_CanvasGetCoord \
	(tkStubsPtr->tk_CanvasGetCoord) /* 9 */
#endif
#ifndef Tk_CanvasGetTextInfo
#define Tk_CanvasGetTextInfo \
	(tkStubsPtr->tk_CanvasGetTextInfo) /* 10 */
#endif
#ifndef Tk_CanvasPsBitmap
#define Tk_CanvasPsBitmap \
	(tkStubsPtr->tk_CanvasPsBitmap) /* 11 */
#endif
#ifndef Tk_CanvasPsColor
#define Tk_CanvasPsColor \
	(tkStubsPtr->tk_CanvasPsColor) /* 12 */
#endif
#ifndef Tk_CanvasPsFont
#define Tk_CanvasPsFont \
	(tkStubsPtr->tk_CanvasPsFont) /* 13 */
#endif
#ifndef Tk_CanvasPsPath
#define Tk_CanvasPsPath \
	(tkStubsPtr->tk_CanvasPsPath) /* 14 */
#endif
#ifndef Tk_CanvasPsStipple
#define Tk_CanvasPsStipple \
	(tkStubsPtr->tk_CanvasPsStipple) /* 15 */
#endif
#ifndef Tk_CanvasPsY
#define Tk_CanvasPsY \
	(tkStubsPtr->tk_CanvasPsY) /* 16 */
#endif
#ifndef Tk_CanvasSetStippleOrigin
#define Tk_CanvasSetStippleOrigin \
	(tkStubsPtr->tk_CanvasSetStippleOrigin) /* 17 */
#endif
#ifndef Tk_CanvasTagsParseProc
#define Tk_CanvasTagsParseProc \
	(tkStubsPtr->tk_CanvasTagsParseProc) /* 18 */
#endif
#ifndef Tk_CanvasTagsPrintProc
#define Tk_CanvasTagsPrintProc \
	(tkStubsPtr->tk_CanvasTagsPrintProc) /* 19 */
#endif
#ifndef Tk_CanvasTkwin
#define Tk_CanvasTkwin \
	(tkStubsPtr->tk_CanvasTkwin) /* 20 */
#endif
#ifndef Tk_CanvasWindowCoords
#define Tk_CanvasWindowCoords \
	(tkStubsPtr->tk_CanvasWindowCoords) /* 21 */
#endif
#ifndef Tk_ChangeWindowAttributes
#define Tk_ChangeWindowAttributes \
	(tkStubsPtr->tk_ChangeWindowAttributes) /* 22 */
#endif
#ifndef Tk_CharBbox
#define Tk_CharBbox \
	(tkStubsPtr->tk_CharBbox) /* 23 */
#endif
#ifndef Tk_ClearSelection
#define Tk_ClearSelection \
	(tkStubsPtr->tk_ClearSelection) /* 24 */
#endif
#ifndef Tk_ClipboardAppend
#define Tk_ClipboardAppend \
	(tkStubsPtr->tk_ClipboardAppend) /* 25 */
#endif
#ifndef Tk_ClipboardClear
#define Tk_ClipboardClear \
	(tkStubsPtr->tk_ClipboardClear) /* 26 */
#endif
#ifndef Tk_ConfigureInfo
#define Tk_ConfigureInfo \
	(tkStubsPtr->tk_ConfigureInfo) /* 27 */
#endif
#ifndef Tk_ConfigureValue
#define Tk_ConfigureValue \
	(tkStubsPtr->tk_ConfigureValue) /* 28 */
#endif
#ifndef Tk_ConfigureWidget
#define Tk_ConfigureWidget \
	(tkStubsPtr->tk_ConfigureWidget) /* 29 */
#endif
#ifndef Tk_ConfigureWindow
#define Tk_ConfigureWindow \
	(tkStubsPtr->tk_ConfigureWindow) /* 30 */
#endif
#ifndef Tk_ComputeTextLayout
#define Tk_ComputeTextLayout \
	(tkStubsPtr->tk_ComputeTextLayout) /* 31 */
#endif
#ifndef Tk_CoordsToWindow
#define Tk_CoordsToWindow \
	(tkStubsPtr->tk_CoordsToWindow) /* 32 */
#endif
#ifndef Tk_CreateBinding
#define Tk_CreateBinding \
	(tkStubsPtr->tk_CreateBinding) /* 33 */
#endif
#ifndef Tk_CreateBindingTable
#define Tk_CreateBindingTable \
	(tkStubsPtr->tk_CreateBindingTable) /* 34 */
#endif
#ifndef Tk_CreateErrorHandler
#define Tk_CreateErrorHandler \
	(tkStubsPtr->tk_CreateErrorHandler) /* 35 */
#endif
#ifndef Tk_CreateEventHandler
#define Tk_CreateEventHandler \
	(tkStubsPtr->tk_CreateEventHandler) /* 36 */
#endif
#ifndef Tk_CreateGenericHandler
#define Tk_CreateGenericHandler \
	(tkStubsPtr->tk_CreateGenericHandler) /* 37 */
#endif
#ifndef Tk_CreateImageType
#define Tk_CreateImageType \
	(tkStubsPtr->tk_CreateImageType) /* 38 */
#endif
#ifndef Tk_CreateItemType
#define Tk_CreateItemType \
	(tkStubsPtr->tk_CreateItemType) /* 39 */
#endif
#ifndef Tk_CreatePhotoImageFormat
#define Tk_CreatePhotoImageFormat \
	(tkStubsPtr->tk_CreatePhotoImageFormat) /* 40 */
#endif
#ifndef Tk_CreateSelHandler
#define Tk_CreateSelHandler \
	(tkStubsPtr->tk_CreateSelHandler) /* 41 */
#endif
#ifndef Tk_CreateWindow
#define Tk_CreateWindow \
	(tkStubsPtr->tk_CreateWindow) /* 42 */
#endif
#ifndef Tk_CreateWindowFromPath
#define Tk_CreateWindowFromPath \
	(tkStubsPtr->tk_CreateWindowFromPath) /* 43 */
#endif
#ifndef Tk_DefineBitmap
#define Tk_DefineBitmap \
	(tkStubsPtr->tk_DefineBitmap) /* 44 */
#endif
#ifndef Tk_DefineCursor
#define Tk_DefineCursor \
	(tkStubsPtr->tk_DefineCursor) /* 45 */
#endif
#ifndef Tk_DeleteAllBindings
#define Tk_DeleteAllBindings \
	(tkStubsPtr->tk_DeleteAllBindings) /* 46 */
#endif
#ifndef Tk_DeleteBinding
#define Tk_DeleteBinding \
	(tkStubsPtr->tk_DeleteBinding) /* 47 */
#endif
#ifndef Tk_DeleteBindingTable
#define Tk_DeleteBindingTable \
	(tkStubsPtr->tk_DeleteBindingTable) /* 48 */
#endif
#ifndef Tk_DeleteErrorHandler
#define Tk_DeleteErrorHandler \
	(tkStubsPtr->tk_DeleteErrorHandler) /* 49 */
#endif
#ifndef Tk_DeleteEventHandler
#define Tk_DeleteEventHandler \
	(tkStubsPtr->tk_DeleteEventHandler) /* 50 */
#endif
#ifndef Tk_DeleteGenericHandler
#define Tk_DeleteGenericHandler \
	(tkStubsPtr->tk_DeleteGenericHandler) /* 51 */
#endif
#ifndef Tk_DeleteImage
#define Tk_DeleteImage \
	(tkStubsPtr->tk_DeleteImage) /* 52 */
#endif
#ifndef Tk_DeleteSelHandler
#define Tk_DeleteSelHandler \
	(tkStubsPtr->tk_DeleteSelHandler) /* 53 */
#endif
#ifndef Tk_DestroyWindow
#define Tk_DestroyWindow \
	(tkStubsPtr->tk_DestroyWindow) /* 54 */
#endif
#ifndef Tk_DisplayName
#define Tk_DisplayName \
	(tkStubsPtr->tk_DisplayName) /* 55 */
#endif
#ifndef Tk_DistanceToTextLayout
#define Tk_DistanceToTextLayout \
	(tkStubsPtr->tk_DistanceToTextLayout) /* 56 */
#endif
#ifndef Tk_Draw3DPolygon
#define Tk_Draw3DPolygon \
	(tkStubsPtr->tk_Draw3DPolygon) /* 57 */
#endif
#ifndef Tk_Draw3DRectangle
#define Tk_Draw3DRectangle \
	(tkStubsPtr->tk_Draw3DRectangle) /* 58 */
#endif
#ifndef Tk_DrawChars
#define Tk_DrawChars \
	(tkStubsPtr->tk_DrawChars) /* 59 */
#endif
#ifndef Tk_DrawFocusHighlight
#define Tk_DrawFocusHighlight \
	(tkStubsPtr->tk_DrawFocusHighlight) /* 60 */
#endif
#ifndef Tk_DrawTextLayout
#define Tk_DrawTextLayout \
	(tkStubsPtr->tk_DrawTextLayout) /* 61 */
#endif
#ifndef Tk_Fill3DPolygon
#define Tk_Fill3DPolygon \
	(tkStubsPtr->tk_Fill3DPolygon) /* 62 */
#endif
#ifndef Tk_Fill3DRectangle
#define Tk_Fill3DRectangle \
	(tkStubsPtr->tk_Fill3DRectangle) /* 63 */
#endif
#ifndef Tk_FindPhoto
#define Tk_FindPhoto \
	(tkStubsPtr->tk_FindPhoto) /* 64 */
#endif
#ifndef Tk_FontId
#define Tk_FontId \
	(tkStubsPtr->tk_FontId) /* 65 */
#endif
#ifndef Tk_Free3DBorder
#define Tk_Free3DBorder \
	(tkStubsPtr->tk_Free3DBorder) /* 66 */
#endif
#ifndef Tk_FreeBitmap
#define Tk_FreeBitmap \
	(tkStubsPtr->tk_FreeBitmap) /* 67 */
#endif
#ifndef Tk_FreeColor
#define Tk_FreeColor \
	(tkStubsPtr->tk_FreeColor) /* 68 */
#endif
#ifndef Tk_FreeColormap
#define Tk_FreeColormap \
	(tkStubsPtr->tk_FreeColormap) /* 69 */
#endif
#ifndef Tk_FreeCursor
#define Tk_FreeCursor \
	(tkStubsPtr->tk_FreeCursor) /* 70 */
#endif
#ifndef Tk_FreeFont
#define Tk_FreeFont \
	(tkStubsPtr->tk_FreeFont) /* 71 */
#endif
#ifndef Tk_FreeGC
#define Tk_FreeGC \
	(tkStubsPtr->tk_FreeGC) /* 72 */
#endif
#ifndef Tk_FreeImage
#define Tk_FreeImage \
	(tkStubsPtr->tk_FreeImage) /* 73 */
#endif
#ifndef Tk_FreeOptions
#define Tk_FreeOptions \
	(tkStubsPtr->tk_FreeOptions) /* 74 */
#endif
#ifndef Tk_FreePixmap
#define Tk_FreePixmap \
	(tkStubsPtr->tk_FreePixmap) /* 75 */
#endif
#ifndef Tk_FreeTextLayout
#define Tk_FreeTextLayout \
	(tkStubsPtr->tk_FreeTextLayout) /* 76 */
#endif
#ifndef Tk_FreeXId
#define Tk_FreeXId \
	(tkStubsPtr->tk_FreeXId) /* 77 */
#endif
#ifndef Tk_GCForColor
#define Tk_GCForColor \
	(tkStubsPtr->tk_GCForColor) /* 78 */
#endif
#ifndef Tk_GeometryRequest
#define Tk_GeometryRequest \
	(tkStubsPtr->tk_GeometryRequest) /* 79 */
#endif
#ifndef Tk_Get3DBorder
#define Tk_Get3DBorder \
	(tkStubsPtr->tk_Get3DBorder) /* 80 */
#endif
#ifndef Tk_GetAllBindings
#define Tk_GetAllBindings \
	(tkStubsPtr->tk_GetAllBindings) /* 81 */
#endif
#ifndef Tk_GetAnchor
#define Tk_GetAnchor \
	(tkStubsPtr->tk_GetAnchor) /* 82 */
#endif
#ifndef Tk_GetAtomName
#define Tk_GetAtomName \
	(tkStubsPtr->tk_GetAtomName) /* 83 */
#endif
#ifndef Tk_GetBinding
#define Tk_GetBinding \
	(tkStubsPtr->tk_GetBinding) /* 84 */
#endif
#ifndef Tk_GetBitmap
#define Tk_GetBitmap \
	(tkStubsPtr->tk_GetBitmap) /* 85 */
#endif
#ifndef Tk_GetBitmapFromData
#define Tk_GetBitmapFromData \
	(tkStubsPtr->tk_GetBitmapFromData) /* 86 */
#endif
#ifndef Tk_GetCapStyle
#define Tk_GetCapStyle \
	(tkStubsPtr->tk_GetCapStyle) /* 87 */
#endif
#ifndef Tk_GetColor
#define Tk_GetColor \
	(tkStubsPtr->tk_GetColor) /* 88 */
#endif
#ifndef Tk_GetColorByValue
#define Tk_GetColorByValue \
	(tkStubsPtr->tk_GetColorByValue) /* 89 */
#endif
#ifndef Tk_GetColormap
#define Tk_GetColormap \
	(tkStubsPtr->tk_GetColormap) /* 90 */
#endif
#ifndef Tk_GetCursor
#define Tk_GetCursor \
	(tkStubsPtr->tk_GetCursor) /* 91 */
#endif
#ifndef Tk_GetCursorFromData
#define Tk_GetCursorFromData \
	(tkStubsPtr->tk_GetCursorFromData) /* 92 */
#endif
#ifndef Tk_GetFont
#define Tk_GetFont \
	(tkStubsPtr->tk_GetFont) /* 93 */
#endif
#ifndef Tk_GetFontFromObj
#define Tk_GetFontFromObj \
	(tkStubsPtr->tk_GetFontFromObj) /* 94 */
#endif
#ifndef Tk_GetFontMetrics
#define Tk_GetFontMetrics \
	(tkStubsPtr->tk_GetFontMetrics) /* 95 */
#endif
#ifndef Tk_GetGC
#define Tk_GetGC \
	(tkStubsPtr->tk_GetGC) /* 96 */
#endif
#ifndef Tk_GetImage
#define Tk_GetImage \
	(tkStubsPtr->tk_GetImage) /* 97 */
#endif
#ifndef Tk_GetImageMasterData
#define Tk_GetImageMasterData \
	(tkStubsPtr->tk_GetImageMasterData) /* 98 */
#endif
#ifndef Tk_GetItemTypes
#define Tk_GetItemTypes \
	(tkStubsPtr->tk_GetItemTypes) /* 99 */
#endif
#ifndef Tk_GetJoinStyle
#define Tk_GetJoinStyle \
	(tkStubsPtr->tk_GetJoinStyle) /* 100 */
#endif
#ifndef Tk_GetJustify
#define Tk_GetJustify \
	(tkStubsPtr->tk_GetJustify) /* 101 */
#endif
#ifndef Tk_GetNumMainWindows
#define Tk_GetNumMainWindows \
	(tkStubsPtr->tk_GetNumMainWindows) /* 102 */
#endif
#ifndef Tk_GetOption
#define Tk_GetOption \
	(tkStubsPtr->tk_GetOption) /* 103 */
#endif
#ifndef Tk_GetPixels
#define Tk_GetPixels \
	(tkStubsPtr->tk_GetPixels) /* 104 */
#endif
#ifndef Tk_GetPixmap
#define Tk_GetPixmap \
	(tkStubsPtr->tk_GetPixmap) /* 105 */
#endif
#ifndef Tk_GetRelief
#define Tk_GetRelief \
	(tkStubsPtr->tk_GetRelief) /* 106 */
#endif
#ifndef Tk_GetRootCoords
#define Tk_GetRootCoords \
	(tkStubsPtr->tk_GetRootCoords) /* 107 */
#endif
#ifndef Tk_GetScrollInfo
#define Tk_GetScrollInfo \
	(tkStubsPtr->tk_GetScrollInfo) /* 108 */
#endif
#ifndef Tk_GetScreenMM
#define Tk_GetScreenMM \
	(tkStubsPtr->tk_GetScreenMM) /* 109 */
#endif
#ifndef Tk_GetSelection
#define Tk_GetSelection \
	(tkStubsPtr->tk_GetSelection) /* 110 */
#endif
#ifndef Tk_GetUid
#define Tk_GetUid \
	(tkStubsPtr->tk_GetUid) /* 111 */
#endif
#ifndef Tk_GetVisual
#define Tk_GetVisual \
	(tkStubsPtr->tk_GetVisual) /* 112 */
#endif
#ifndef Tk_GetVRootGeometry
#define Tk_GetVRootGeometry \
	(tkStubsPtr->tk_GetVRootGeometry) /* 113 */
#endif
#ifndef Tk_Grab
#define Tk_Grab \
	(tkStubsPtr->tk_Grab) /* 114 */
#endif
#ifndef Tk_HandleEvent
#define Tk_HandleEvent \
	(tkStubsPtr->tk_HandleEvent) /* 115 */
#endif
#ifndef Tk_IdToWindow
#define Tk_IdToWindow \
	(tkStubsPtr->tk_IdToWindow) /* 116 */
#endif
#ifndef Tk_ImageChanged
#define Tk_ImageChanged \
	(tkStubsPtr->tk_ImageChanged) /* 117 */
#endif
#ifndef Tk_Init
#define Tk_Init \
	(tkStubsPtr->tk_Init) /* 118 */
#endif
#ifndef Tk_InternAtom
#define Tk_InternAtom \
	(tkStubsPtr->tk_InternAtom) /* 119 */
#endif
#ifndef Tk_IntersectTextLayout
#define Tk_IntersectTextLayout \
	(tkStubsPtr->tk_IntersectTextLayout) /* 120 */
#endif
#ifndef Tk_MaintainGeometry
#define Tk_MaintainGeometry \
	(tkStubsPtr->tk_MaintainGeometry) /* 121 */
#endif
#ifndef Tk_MainWindow
#define Tk_MainWindow \
	(tkStubsPtr->tk_MainWindow) /* 122 */
#endif
#ifndef Tk_MakeWindowExist
#define Tk_MakeWindowExist \
	(tkStubsPtr->tk_MakeWindowExist) /* 123 */
#endif
#ifndef Tk_ManageGeometry
#define Tk_ManageGeometry \
	(tkStubsPtr->tk_ManageGeometry) /* 124 */
#endif
#ifndef Tk_MapWindow
#define Tk_MapWindow \
	(tkStubsPtr->tk_MapWindow) /* 125 */
#endif
#ifndef Tk_MeasureChars
#define Tk_MeasureChars \
	(tkStubsPtr->tk_MeasureChars) /* 126 */
#endif
#ifndef Tk_MoveResizeWindow
#define Tk_MoveResizeWindow \
	(tkStubsPtr->tk_MoveResizeWindow) /* 127 */
#endif
#ifndef Tk_MoveWindow
#define Tk_MoveWindow \
	(tkStubsPtr->tk_MoveWindow) /* 128 */
#endif
#ifndef Tk_MoveToplevelWindow
#define Tk_MoveToplevelWindow \
	(tkStubsPtr->tk_MoveToplevelWindow) /* 129 */
#endif
#ifndef Tk_NameOf3DBorder
#define Tk_NameOf3DBorder \
	(tkStubsPtr->tk_NameOf3DBorder) /* 130 */
#endif
#ifndef Tk_NameOfAnchor
#define Tk_NameOfAnchor \
	(tkStubsPtr->tk_NameOfAnchor) /* 131 */
#endif
#ifndef Tk_NameOfBitmap
#define Tk_NameOfBitmap \
	(tkStubsPtr->tk_NameOfBitmap) /* 132 */
#endif
#ifndef Tk_NameOfCapStyle
#define Tk_NameOfCapStyle \
	(tkStubsPtr->tk_NameOfCapStyle) /* 133 */
#endif
#ifndef Tk_NameOfColor
#define Tk_NameOfColor \
	(tkStubsPtr->tk_NameOfColor) /* 134 */
#endif
#ifndef Tk_NameOfCursor
#define Tk_NameOfCursor \
	(tkStubsPtr->tk_NameOfCursor) /* 135 */
#endif
#ifndef Tk_NameOfFont
#define Tk_NameOfFont \
	(tkStubsPtr->tk_NameOfFont) /* 136 */
#endif
#ifndef Tk_NameOfImage
#define Tk_NameOfImage \
	(tkStubsPtr->tk_NameOfImage) /* 137 */
#endif
#ifndef Tk_NameOfJoinStyle
#define Tk_NameOfJoinStyle \
	(tkStubsPtr->tk_NameOfJoinStyle) /* 138 */
#endif
#ifndef Tk_NameOfJustify
#define Tk_NameOfJustify \
	(tkStubsPtr->tk_NameOfJustify) /* 139 */
#endif
#ifndef Tk_NameOfRelief
#define Tk_NameOfRelief \
	(tkStubsPtr->tk_NameOfRelief) /* 140 */
#endif
#ifndef Tk_NameToWindow
#define Tk_NameToWindow \
	(tkStubsPtr->tk_NameToWindow) /* 141 */
#endif
#ifndef Tk_OwnSelection
#define Tk_OwnSelection \
	(tkStubsPtr->tk_OwnSelection) /* 142 */
#endif
#ifndef Tk_ParseArgv
#define Tk_ParseArgv \
	(tkStubsPtr->tk_ParseArgv) /* 143 */
#endif
#ifndef Tk_PhotoPutBlock_NoComposite
#define Tk_PhotoPutBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutBlock_NoComposite) /* 144 */
#endif
#ifndef Tk_PhotoPutZoomedBlock_NoComposite
#define Tk_PhotoPutZoomedBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_NoComposite) /* 145 */
#endif
#ifndef Tk_PhotoGetImage
#define Tk_PhotoGetImage \
	(tkStubsPtr->tk_PhotoGetImage) /* 146 */
#endif
#ifndef Tk_PhotoBlank
#define Tk_PhotoBlank \
	(tkStubsPtr->tk_PhotoBlank) /* 147 */
#endif
#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_Panic
#define Tk_PhotoSetSize_Panic \
	(tkStubsPtr->tk_PhotoSetSize_Panic) /* 150 */
#endif
#ifndef Tk_PointToChar
#define Tk_PointToChar \
	(tkStubsPtr->tk_PointToChar) /* 151 */
#endif
#ifndef Tk_PostscriptFontName
#define Tk_PostscriptFontName \
	(tkStubsPtr->tk_PostscriptFontName) /* 152 */
#endif
#ifndef Tk_PreserveColormap
#define Tk_PreserveColormap \
	(tkStubsPtr->tk_PreserveColormap) /* 153 */
#endif
#ifndef Tk_QueueWindowEvent
#define Tk_QueueWindowEvent \
	(tkStubsPtr->tk_QueueWindowEvent) /* 154 */
#endif
#ifndef Tk_RedrawImage
#define Tk_RedrawImage \
	(tkStubsPtr->tk_RedrawImage) /* 155 */
#endif
#ifndef Tk_ResizeWindow
#define Tk_ResizeWindow \
	(tkStubsPtr->tk_ResizeWindow) /* 156 */
#endif
#ifndef Tk_RestackWindow
#define Tk_RestackWindow \
	(tkStubsPtr->tk_RestackWindow) /* 157 */
#endif
#ifndef Tk_RestrictEvents
#define Tk_RestrictEvents \
	(tkStubsPtr->tk_RestrictEvents) /* 158 */
#endif
#ifndef Tk_SafeInit
#define Tk_SafeInit \
	(tkStubsPtr->tk_SafeInit) /* 159 */
#endif
#ifndef Tk_SetAppName
#define Tk_SetAppName \
	(tkStubsPtr->tk_SetAppName) /* 160 */
#endif
#ifndef Tk_SetBackgroundFromBorder
#define Tk_SetBackgroundFromBorder \
	(tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */
#endif
#ifndef Tk_SetClass
#define Tk_SetClass \
	(tkStubsPtr->tk_SetClass) /* 162 */
#endif
#ifndef Tk_SetGrid
#define Tk_SetGrid \
	(tkStubsPtr->tk_SetGrid) /* 163 */
#endif
#ifndef Tk_SetInternalBorder
#define Tk_SetInternalBorder \
	(tkStubsPtr->tk_SetInternalBorder) /* 164 */
#endif
#ifndef Tk_SetWindowBackground
#define Tk_SetWindowBackground \
	(tkStubsPtr->tk_SetWindowBackground) /* 165 */
#endif
#ifndef Tk_SetWindowBackgroundPixmap
#define Tk_SetWindowBackgroundPixmap \
	(tkStubsPtr->tk_SetWindowBackgroundPixmap) /* 166 */
#endif
#ifndef Tk_SetWindowBorder
#define Tk_SetWindowBorder \
	(tkStubsPtr->tk_SetWindowBorder) /* 167 */
#endif
#ifndef Tk_SetWindowBorderWidth
#define Tk_SetWindowBorderWidth \
	(tkStubsPtr->tk_SetWindowBorderWidth) /* 168 */
#endif
#ifndef Tk_SetWindowBorderPixmap
#define Tk_SetWindowBorderPixmap \
	(tkStubsPtr->tk_SetWindowBorderPixmap) /* 169 */
#endif
#ifndef Tk_SetWindowColormap
#define Tk_SetWindowColormap \
	(tkStubsPtr->tk_SetWindowColormap) /* 170 */
#endif
#ifndef Tk_SetWindowVisual
#define Tk_SetWindowVisual \
	(tkStubsPtr->tk_SetWindowVisual) /* 171 */
#endif
#ifndef Tk_SizeOfBitmap
#define Tk_SizeOfBitmap \
	(tkStubsPtr->tk_SizeOfBitmap) /* 172 */
#endif
#ifndef Tk_SizeOfImage
#define Tk_SizeOfImage \
	(tkStubsPtr->tk_SizeOfImage) /* 173 */
#endif
#ifndef Tk_StrictMotif
#define Tk_StrictMotif \
	(tkStubsPtr->tk_StrictMotif) /* 174 */
#endif
#ifndef Tk_TextLayoutToPostscript
#define Tk_TextLayoutToPostscript \
	(tkStubsPtr->tk_TextLayoutToPostscript) /* 175 */
#endif
#ifndef Tk_TextWidth
#define Tk_TextWidth \
	(tkStubsPtr->tk_TextWidth) /* 176 */
#endif
#ifndef Tk_UndefineCursor
#define Tk_UndefineCursor \
	(tkStubsPtr->tk_UndefineCursor) /* 177 */
#endif
#ifndef Tk_UnderlineChars
#define Tk_UnderlineChars \
	(tkStubsPtr->tk_UnderlineChars) /* 178 */
#endif
#ifndef Tk_UnderlineTextLayout
#define Tk_UnderlineTextLayout \
	(tkStubsPtr->tk_UnderlineTextLayout) /* 179 */
#endif
#ifndef Tk_Ungrab
#define Tk_Ungrab \
	(tkStubsPtr->tk_Ungrab) /* 180 */
#endif
#ifndef Tk_UnmaintainGeometry
#define Tk_UnmaintainGeometry \
	(tkStubsPtr->tk_UnmaintainGeometry) /* 181 */
#endif
#ifndef Tk_UnmapWindow
#define Tk_UnmapWindow \
	(tkStubsPtr->tk_UnmapWindow) /* 182 */
#endif
#ifndef Tk_UnsetGrid
#define Tk_UnsetGrid \
	(tkStubsPtr->tk_UnsetGrid) /* 183 */
#endif
#ifndef Tk_UpdatePointer
#define Tk_UpdatePointer \
	(tkStubsPtr->tk_UpdatePointer) /* 184 */
#endif
#ifndef Tk_AllocBitmapFromObj
#define Tk_AllocBitmapFromObj \
	(tkStubsPtr->tk_AllocBitmapFromObj) /* 185 */
#endif
#ifndef Tk_Alloc3DBorderFromObj
#define Tk_Alloc3DBorderFromObj \
	(tkStubsPtr->tk_Alloc3DBorderFromObj) /* 186 */
#endif
#ifndef Tk_AllocColorFromObj
#define Tk_AllocColorFromObj \
	(tkStubsPtr->tk_AllocColorFromObj) /* 187 */
#endif
#ifndef Tk_AllocCursorFromObj
#define Tk_AllocCursorFromObj \
	(tkStubsPtr->tk_AllocCursorFromObj) /* 188 */
#endif
#ifndef Tk_AllocFontFromObj
#define Tk_AllocFontFromObj \
	(tkStubsPtr->tk_AllocFontFromObj) /* 189 */
#endif
#ifndef Tk_CreateOptionTable
#define Tk_CreateOptionTable \
	(tkStubsPtr->tk_CreateOptionTable) /* 190 */
#endif
#ifndef Tk_DeleteOptionTable
#define Tk_DeleteOptionTable \
	(tkStubsPtr->tk_DeleteOptionTable) /* 191 */
#endif
#ifndef Tk_Free3DBorderFromObj
#define Tk_Free3DBorderFromObj \
	(tkStubsPtr->tk_Free3DBorderFromObj) /* 192 */
#endif
#ifndef Tk_FreeBitmapFromObj
#define Tk_FreeBitmapFromObj \
	(tkStubsPtr->tk_FreeBitmapFromObj) /* 193 */
#endif
#ifndef Tk_FreeColorFromObj
#define Tk_FreeColorFromObj \
	(tkStubsPtr->tk_FreeColorFromObj) /* 194 */
#endif
#ifndef Tk_FreeConfigOptions
#define Tk_FreeConfigOptions \
	(tkStubsPtr->tk_FreeConfigOptions) /* 195 */
#endif
#ifndef Tk_FreeSavedOptions
#define Tk_FreeSavedOptions \
	(tkStubsPtr->tk_FreeSavedOptions) /* 196 */
#endif
#ifndef Tk_FreeCursorFromObj
#define Tk_FreeCursorFromObj \
	(tkStubsPtr->tk_FreeCursorFromObj) /* 197 */
#endif
#ifndef Tk_FreeFontFromObj
#define Tk_FreeFontFromObj \
	(tkStubsPtr->tk_FreeFontFromObj) /* 198 */
#endif
#ifndef Tk_Get3DBorderFromObj
#define Tk_Get3DBorderFromObj \
	(tkStubsPtr->tk_Get3DBorderFromObj) /* 199 */
#endif
#ifndef Tk_GetAnchorFromObj
#define Tk_GetAnchorFromObj \
	(tkStubsPtr->tk_GetAnchorFromObj) /* 200 */
#endif
#ifndef Tk_GetBitmapFromObj
#define Tk_GetBitmapFromObj \
	(tkStubsPtr->tk_GetBitmapFromObj) /* 201 */
#endif
#ifndef Tk_GetColorFromObj
#define Tk_GetColorFromObj \
	(tkStubsPtr->tk_GetColorFromObj) /* 202 */
#endif
#ifndef Tk_GetCursorFromObj
#define Tk_GetCursorFromObj \
	(tkStubsPtr->tk_GetCursorFromObj) /* 203 */
#endif
#ifndef Tk_GetOptionInfo
#define Tk_GetOptionInfo \
	(tkStubsPtr->tk_GetOptionInfo) /* 204 */
#endif
#ifndef Tk_GetOptionValue
#define Tk_GetOptionValue \
	(tkStubsPtr->tk_GetOptionValue) /* 205 */
#endif
#ifndef Tk_GetJustifyFromObj
#define Tk_GetJustifyFromObj \
	(tkStubsPtr->tk_GetJustifyFromObj) /* 206 */
#endif
#ifndef Tk_GetMMFromObj
#define Tk_GetMMFromObj \
	(tkStubsPtr->tk_GetMMFromObj) /* 207 */
#endif
#ifndef Tk_GetPixelsFromObj
#define Tk_GetPixelsFromObj \
	(tkStubsPtr->tk_GetPixelsFromObj) /* 208 */
#endif
#ifndef Tk_GetReliefFromObj
#define Tk_GetReliefFromObj \
	(tkStubsPtr->tk_GetReliefFromObj) /* 209 */
#endif
#ifndef Tk_GetScrollInfoObj
#define Tk_GetScrollInfoObj \
	(tkStubsPtr->tk_GetScrollInfoObj) /* 210 */
#endif
#ifndef Tk_InitOptions
#define Tk_InitOptions \
	(tkStubsPtr->tk_InitOptions) /* 211 */
#endif
#ifndef Tk_MainEx
#define Tk_MainEx \
	(tkStubsPtr->tk_MainEx) /* 212 */
#endif
#ifndef Tk_RestoreSavedOptions
#define Tk_RestoreSavedOptions \
	(tkStubsPtr->tk_RestoreSavedOptions) /* 213 */
#endif
#ifndef Tk_SetOptions
#define Tk_SetOptions \
	(tkStubsPtr->tk_SetOptions) /* 214 */
#endif
#ifndef Tk_InitConsoleChannels
#define Tk_InitConsoleChannels \
	(tkStubsPtr->tk_InitConsoleChannels) /* 215 */
#endif
#ifndef Tk_CreateConsoleWindow
#define Tk_CreateConsoleWindow \
	(tkStubsPtr->tk_CreateConsoleWindow) /* 216 */
#endif
#ifndef Tk_CreateSmoothMethod
#define Tk_CreateSmoothMethod \
	(tkStubsPtr->tk_CreateSmoothMethod) /* 217 */
#endif
/* Slot 218 is reserved */
/* Slot 219 is reserved */
#ifndef Tk_GetDash
#define Tk_GetDash \
	(tkStubsPtr->tk_GetDash) /* 220 */
#endif
#ifndef Tk_CreateOutline
#define Tk_CreateOutline \
	(tkStubsPtr->tk_CreateOutline) /* 221 */
#endif
#ifndef Tk_DeleteOutline
#define Tk_DeleteOutline \
	(tkStubsPtr->tk_DeleteOutline) /* 222 */
#endif
#ifndef Tk_ConfigOutlineGC
#define Tk_ConfigOutlineGC \
	(tkStubsPtr->tk_ConfigOutlineGC) /* 223 */
#endif
#ifndef Tk_ChangeOutlineGC
#define Tk_ChangeOutlineGC \
	(tkStubsPtr->tk_ChangeOutlineGC) /* 224 */
#endif
#ifndef Tk_ResetOutlineGC
#define Tk_ResetOutlineGC \
	(tkStubsPtr->tk_ResetOutlineGC) /* 225 */
#endif
#ifndef Tk_CanvasPsOutline
#define Tk_CanvasPsOutline \
	(tkStubsPtr->tk_CanvasPsOutline) /* 226 */
#endif
#ifndef Tk_SetTSOrigin
#define Tk_SetTSOrigin \
	(tkStubsPtr->tk_SetTSOrigin) /* 227 */
#endif
#ifndef Tk_CanvasGetCoordFromObj
#define Tk_CanvasGetCoordFromObj \
	(tkStubsPtr->tk_CanvasGetCoordFromObj) /* 228 */
#endif
#ifndef Tk_CanvasSetOffset
#define Tk_CanvasSetOffset \
	(tkStubsPtr->tk_CanvasSetOffset) /* 229 */
#endif
#ifndef Tk_DitherPhoto
#define Tk_DitherPhoto \
	(tkStubsPtr->tk_DitherPhoto) /* 230 */
#endif
#ifndef Tk_PostscriptBitmap
#define Tk_PostscriptBitmap \
	(tkStubsPtr->tk_PostscriptBitmap) /* 231 */
#endif
#ifndef Tk_PostscriptColor
#define Tk_PostscriptColor \
	(tkStubsPtr->tk_PostscriptColor) /* 232 */
#endif
#ifndef Tk_PostscriptFont
#define Tk_PostscriptFont \
	(tkStubsPtr->tk_PostscriptFont) /* 233 */
#endif
#ifndef Tk_PostscriptImage
#define Tk_PostscriptImage \
	(tkStubsPtr->tk_PostscriptImage) /* 234 */
#endif
#ifndef Tk_PostscriptPath
#define Tk_PostscriptPath \
	(tkStubsPtr->tk_PostscriptPath) /* 235 */
#endif
#ifndef Tk_PostscriptStipple
#define Tk_PostscriptStipple \
	(tkStubsPtr->tk_PostscriptStipple) /* 236 */
#endif
#ifndef Tk_PostscriptY
#define Tk_PostscriptY \
	(tkStubsPtr->tk_PostscriptY) /* 237 */
#endif
#ifndef Tk_PostscriptPhoto
#define Tk_PostscriptPhoto \
	(tkStubsPtr->tk_PostscriptPhoto) /* 238 */
#endif
#ifndef Tk_CreateClientMessageHandler
#define Tk_CreateClientMessageHandler \
	(tkStubsPtr->tk_CreateClientMessageHandler) /* 239 */
#endif
#ifndef Tk_DeleteClientMessageHandler
#define Tk_DeleteClientMessageHandler \
	(tkStubsPtr->tk_DeleteClientMessageHandler) /* 240 */
#endif
#ifndef Tk_CreateAnonymousWindow
#define Tk_CreateAnonymousWindow \
	(tkStubsPtr->tk_CreateAnonymousWindow) /* 241 */
#endif
#ifndef Tk_SetClassProcs
#define Tk_SetClassProcs \
	(tkStubsPtr->tk_SetClassProcs) /* 242 */
#endif
#ifndef Tk_SetInternalBorderEx
#define Tk_SetInternalBorderEx \
	(tkStubsPtr->tk_SetInternalBorderEx) /* 243 */
#endif
#ifndef Tk_SetMinimumRequestSize
#define Tk_SetMinimumRequestSize \
	(tkStubsPtr->tk_SetMinimumRequestSize) /* 244 */
#endif
#ifndef Tk_SetCaretPos
#define Tk_SetCaretPos \
	(tkStubsPtr->tk_SetCaretPos) /* 245 */
#endif
#ifndef Tk_PhotoPutBlock_Panic
#define Tk_PhotoPutBlock_Panic \
	(tkStubsPtr->tk_PhotoPutBlock_Panic) /* 246 */
#endif
#ifndef Tk_PhotoPutZoomedBlock_Panic
#define Tk_PhotoPutZoomedBlock_Panic \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_Panic) /* 247 */
#endif
#ifndef Tk_CollapseMotionEvents
#define Tk_CollapseMotionEvents \
	(tkStubsPtr->tk_CollapseMotionEvents) /* 248 */
#endif
#ifndef Tk_RegisterStyleEngine
#define Tk_RegisterStyleEngine \
	(tkStubsPtr->tk_RegisterStyleEngine) /* 249 */
#endif
#ifndef Tk_GetStyleEngine
#define Tk_GetStyleEngine \
	(tkStubsPtr->tk_GetStyleEngine) /* 250 */
#endif
#ifndef Tk_RegisterStyledElement
#define Tk_RegisterStyledElement \
	(tkStubsPtr->tk_RegisterStyledElement) /* 251 */
#endif
#ifndef Tk_GetElementId
#define Tk_GetElementId \
	(tkStubsPtr->tk_GetElementId) /* 252 */
#endif
#ifndef Tk_CreateStyle
#define Tk_CreateStyle \
	(tkStubsPtr->tk_CreateStyle) /* 253 */
#endif
#ifndef Tk_GetStyle
#define Tk_GetStyle \
	(tkStubsPtr->tk_GetStyle) /* 254 */
#endif
#ifndef Tk_FreeStyle
#define Tk_FreeStyle \
	(tkStubsPtr->tk_FreeStyle) /* 255 */
#endif
#ifndef Tk_NameOfStyle
#define Tk_NameOfStyle \
	(tkStubsPtr->tk_NameOfStyle) /* 256 */
#endif
#ifndef Tk_AllocStyleFromObj
#define Tk_AllocStyleFromObj \
	(tkStubsPtr->tk_AllocStyleFromObj) /* 257 */
#endif
#ifndef Tk_GetStyleFromObj
#define Tk_GetStyleFromObj \
	(tkStubsPtr->tk_GetStyleFromObj) /* 258 */
#endif
#ifndef Tk_FreeStyleFromObj
#define Tk_FreeStyleFromObj \
	(tkStubsPtr->tk_FreeStyleFromObj) /* 259 */
#endif
#ifndef Tk_GetStyledElement
#define Tk_GetStyledElement \
	(tkStubsPtr->tk_GetStyledElement) /* 260 */
#endif
#ifndef Tk_GetElementSize
#define Tk_GetElementSize \
	(tkStubsPtr->tk_GetElementSize) /* 261 */
#endif
#ifndef Tk_GetElementBox
#define Tk_GetElementBox \
	(tkStubsPtr->tk_GetElementBox) /* 262 */
#endif
#ifndef Tk_GetElementBorderWidth
#define Tk_GetElementBorderWidth \
	(tkStubsPtr->tk_GetElementBorderWidth) /* 263 */
#endif
#ifndef Tk_DrawElement
#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
/* Slot 274 is reserved */

/* Slot 275 is reserved */








/* Slot 276 is reserved */

/* Slot 277 is reserved */

/* Slot 278 is reserved */





/* Slot 279 is reserved */
#ifndef TkUnusedStubEntry
#define TkUnusedStubEntry \





	(tkStubsPtr->tkUnusedStubEntry) /* 280 */




#endif

#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */










/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkUnusedStubEntry

#endif /* _TKDECLS */

Changes to generic/tkEntry.c.

12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
 * 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.
 */

#include "tkInt.h"
#include "tkEntry.h"
#include "default.h"


/*
 * The following macro defines how many extra pixels to leave on each side of
 * the text in the entry.
 */

#define XPAD 1







<

>







12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
 * 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.
 */

#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.
 */

#define XPAD 1
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

/*
 * Information used for Entry objv parsing.
 */

static const Tk_OptionSpec entryOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, TCL_INDEX_NONE, offsetof(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEF_ENTRY_SHOW, TCL_INDEX_NONE, offsetof(Entry, showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, TCL_INDEX_NONE, offsetof(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, TCL_INDEX_NONE, offsetof(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * Information used for Spinbox objv parsing.
 */

#define DEF_SPINBOX_REPEAT_DELAY	"400"







|
|

|

|

|

|


|
|


|
|

|
|

|

|

|


|

|

|
|

|

|
|


|


|

|

|


|

|
<
<
<
<
<
<

|
|


|

|
|

|
|
|

|
|

|


|
|

|


|


|
|

|

|

|

|

|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120






121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

/*
 * Information used for Entry objv parsing.
 */

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", 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},
    {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},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"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", 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},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	-1, Tk_Offset(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
	Tk_Offset(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 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},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
	0, (ClientData) DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(Entry, selBorderWidth),
	0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
	TK_OPTION_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},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
	TK_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",
	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, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * Information used for Spinbox objv parsing.
 */

#define DEF_SPINBOX_REPEAT_DELAY	"400"
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
#define DEF_SPINBOX_FORMAT		""

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

static const Tk_OptionSpec sbOptSpec[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(Spinbox, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, TCL_INDEX_NONE, offsetof(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-buttonbackground", "buttonBackground", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(Spinbox, buttonBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_CURSOR, "-buttoncursor", "buttonCursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(Spinbox, bCursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-buttondownrelief", "buttonDownRelief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(Spinbox, bdRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-buttonuprelief", "buttonUpRelief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(Spinbox, buRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SPINBOX_CMD, TCL_INDEX_NONE, offsetof(Spinbox, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_STRING, "-format", "format", "Format",
	DEF_SPINBOX_FORMAT, TCL_INDEX_NONE, offsetof(Spinbox, reqFormat),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From",
	DEF_SPINBOX_FROM, TCL_INDEX_NONE, offsetof(Spinbox, fromValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, TCL_INDEX_NONE, offsetof(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, TCL_INDEX_NONE, offsetof(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SPINBOX_TO, TCL_INDEX_NONE, offsetof(Spinbox, toValue), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, TCL_INDEX_NONE, offsetof(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-values", "values", "Values",
	DEF_SPINBOX_VALUES, TCL_INDEX_NONE, offsetof(Spinbox, valueStr),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	DEF_SPINBOX_WRAP, TCL_INDEX_NONE, offsetof(Spinbox, wrap), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 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.
 */

static const char *const 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_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW
};

static const char *const selCmdNames[] = {
    "adjust", "clear", "from", "present", "range", "to", NULL
};

enum selCmd {
    SELECTION_ADJUST, SELECTION_CLEAR, SELECTION_FROM,
    SELECTION_PRESENT, SELECTION_RANGE, SELECTION_TO
};

/*
 * 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 *const sbCmdNames[] = {
    "bbox", "cget", "configure", "delete", "get", "icursor", "identify",
    "index", "insert", "invoke", "scan", "selection", "set",
    "validate", "xview", NULL
};

enum sbCmd {
    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 *const 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_PRESENT, SB_SEL_RANGE, SB_SEL_TO
};

/*
 * 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.
 */

static const char *const selElementNames[] = {
    "none", "buttondown", "buttonup", NULL, "entry"
};

/*
 * Flags for GetEntryIndex function:
 */

#define ZERO_OK			1
#define LAST_PLUS_ONE_OK	2

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		DeleteChars(Entry *entryPtr, TkSizeT index, TkSizeT count);
static void		DestroyEntry(void *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 TkSizeT	EntryFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT 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, TkSizeT 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, const char *change,
			    const char *newStr, TkSizeT index, int type);
static void		ExpandPercents(Entry *entryPtr, const char *before,
			    const char *change, const char *newStr, TkSizeT index,
			    int type, Tcl_DString *dsPtr);
static int		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,
			    Tcl_Obj *indexObj, TkSizeT *indexPtr);
static int		InsertChars(Entry *entryPtr, TkSizeT index, const char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

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 functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs entryClass = {
    sizeof(Tk_ClassProcs),	/* size */
    EntryWorldChanged,		/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};


/*
 *--------------------------------------------------------------
 *
 * Tk_EntryObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_EntryObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;







|
|

|
|

|

|

|
|
|
|
|
|

|
|
|
|

|


|


|
|


|
|

|
|

|

|

|

|


|


|

|

|
|

|

|

|
|


|


|

|

|


|

|
<
<
<
<
<
<

|

|
|


|


|


|
|

|
|
|

|
|

|
|

|


|


|

|
|

|

|


|

|

|

|

|








|










|














|












|

















|
















|
|







|
|




|





|
|

|










|
|


















|


<
<

>




















|




|



<


|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260






261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451


452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
492
#define DEF_SPINBOX_FORMAT		""

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

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", 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},
    {TK_OPTION_BORDER, "-buttonbackground", "Button.background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder),
	0, (ClientData) DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_CURSOR, "-buttoncursor", "Button.cursor", "Cursor",
	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},
    {TK_OPTION_RELIEF, "-buttonuprelief", "Button.relief", "Relief",
	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},
    {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},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"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", 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},
    {TK_OPTION_STRING, "-format", "format", "Format",
	DEF_SPINBOX_FORMAT, -1, Tk_Offset(Spinbox, reqFormat),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From",
	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},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_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},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 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},
    {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},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	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},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
	0, (ClientData) DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(Entry, selBorderWidth),
	0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
	TK_OPTION_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},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	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_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",
	NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_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", 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",
	DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 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, 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.
 */

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_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW
};

static const char *selCmdNames[] = {
    "adjust", "clear", "from", "present", "range", "to", NULL
};

enum selCmd {
    SELECTION_ADJUST, SELECTION_CLEAR, SELECTION_FROM,
    SELECTION_PRESENT, SELECTION_RANGE, SELECTION_TO
};

/*
 * 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[] = {
    "bbox", "cget", "configure", "delete", "get", "icursor", "identify",
    "index", "insert", "invoke", "scan", "selection", "set",
    "validate", "xview", NULL
};

enum sbCmd {
    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", NULL
};

enum sbselCmd {
    SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM,
    SB_SEL_PRESENT, SB_SEL_RANGE, SB_SEL_TO
};

/*
 * 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.
 */

static const char *selElementNames[] = {
    "none", "buttondown", "buttonup", NULL, "entry"
};

/*
 * Flags for GetEntryIndex function:
 */

#define ZERO_OK			1
#define LAST_PLUS_ONE_OK	2

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		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 int		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 int		InsertChars(Entry *entryPtr, int index, char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

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 functions
 * that can be invoked from generic window code.
 */

static Tk_ClassProcs entryClass = {
    sizeof(Tk_ClassProcs),	/* size */
    EntryWorldChanged,		/* worldChangedProc */


};


/*
 *--------------------------------------------------------------
 *
 * Tk_EntryObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_Window tkwin;
    char *tmp;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
    /*
     * 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(entryPtr, 0, sizeof(Entry));

    entryPtr->tkwin		= tkwin;
    entryPtr->display		= Tk_Display(tkwin);
    entryPtr->interp		= interp;
    entryPtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, entryPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_ENTRY;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= TCL_INDEX_NONE;
    entryPtr->selectLast	= TCL_INDEX_NONE;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
    entryPtr->inset		= XPAD;
    entryPtr->textGC		= NULL;
    entryPtr->selTextGC		= NULL;
    entryPtr->highlightGC	= NULL;
    entryPtr->avgWidth		= 1;
    entryPtr->validate		= VALIDATE_NONE;

    entryPtr->placeholderGC	= NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the entry,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Entry");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if ((Tk_InitOptions(interp, entryPtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --







|






|
|


|


|
|














<
<





|


|


|

|

|






|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538


539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
    /*
     * 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(entryPtr, 0, sizeof(Entry));

    entryPtr->tkwin		= tkwin;
    entryPtr->display		= Tk_Display(tkwin);
    entryPtr->interp		= interp;
    entryPtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd,
	    (ClientData) entryPtr, EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_ENTRY;
    tmp				= (char *) ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= -1;
    entryPtr->selectLast	= -1;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
    entryPtr->inset		= XPAD;
    entryPtr->textGC		= NULL;
    entryPtr->selTextGC		= NULL;
    entryPtr->highlightGC	= NULL;
    entryPtr->avgWidth		= 1;
    entryPtr->validate		= VALIDATE_NONE;



    /*
     * Keep a hold of the associated tkwin until we destroy the entry,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve((ClientData) entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Entry");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, (ClientData) entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, (ClientData) entryPtr, XA_STRING);

    if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
static int
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;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * Parse the widget command by looking up the second token in the list of
     * valid command names.
     */

    result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames, "option", 0,
	    &cmdIndex);
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index + 1 > 1)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, entryPtr,
		    entryPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL,
		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else if (GetEntryIndex(interp, entryPtr, objv[3],
		&last) != TCL_OK) {
	    goto error;
	}
	if ((last + 1 >= first + 1 ) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case COMMAND_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, TCL_INDEX_NONE));
	break;

    case COMMAND_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&entryPtr->insertPos) != TCL_OK) {
	    goto error;
	}
	EventuallyRedraw(entryPtr);
	break;

    case COMMAND_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case COMMAND_INSERT: {
	TkSizeT index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if (entryPtr->state == STATE_NORMAL) {
	    code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case COMMAND_SCAN: {
	int x;
	const 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_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be mark or dragto",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case COMMAND_SELECTION: {
	TkSizeT index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*







|




|








|
|




|


<
|
<
>





|



|



|
|
<
<
|









|



|
|
>




|





|
|
>






|
<





|





|



|













|







|







|





|



|




|
<





|














|


















|
|
<
<
|






|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

613

614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629


630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768


769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
static int
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;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    /*
     * Parse the widget command by looking up the second token in the list of
     * valid command names.
     */

    result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames,
	    "option", 0, &cmdIndex);
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve((ClientData) entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    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 (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;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	int first, last, code;


	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)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case COMMAND_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
	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_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_INSERT: {
	int index, code;


	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) {
	    code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	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;
	}

	/*
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
	switch (selIndex) {
	case SELECTION_ADJUST:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1 ) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1 ) {
		    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, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SELECTION_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    entryPtr->selectAnchor = index;
	    break;

	case SELECTION_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp,
		    Tcl_NewWideIntObj(entryPtr->selectFirst != TCL_INDEX_NONE));
	    goto done;

	case SELECTION_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[4],
		    &index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1 ) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && (entryPtr->exportSelection)
		    && (!Tcl_IsSafe(entryPtr->interp))) {
		Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
			EntryLostSelection, 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,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    EntrySelectTo(entryPtr, index);
	    break;
	}
	break;
    }







|


|
|



|

|
















|
|
|










|











|







|



|



|
|
|





|
<

|











|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887

888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
	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, 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, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
	    goto done;

	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;
    }
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958

959
960
961
962
963
964
965
966
967
968
969
970
	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_XVIEW: {
	TkSizeT index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);

	    span[1] = Tcl_NewDoubleObj(last);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, span));
	    goto done;
	} else if (objc == 3) {
	    if (GetEntryIndex(interp, entryPtr, objv[2],
		    &index) != TCL_OK) {
		goto error;
	    }
	} else {
	    double fraction;
	    int count;








|




|



|


|
>
|
|


|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
	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_XVIEW: {
	int index;

	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;
	    }
	} else {
	    double fraction;
	    int count;

988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	    index = entryPtr->numChars - 1;
	}
	if ((int)index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
    }
    }

  done:
    Tcl_Release(entryPtr);
    return result;

  error:
    Tcl_Release(entryPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyEntry --







|


|











|



|







967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    }
	}
	if (index >= entryPtr->numChars) {
	    index = entryPtr->numChars - 1;
	}
	if (index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
    }
    }

  done:
    Tcl_Release((ClientData) entryPtr);
    return result;

  error:
    Tcl_Release((ClientData) entryPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyEntry --
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyEntry(
    void *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.
     */

    ckfree((char *)entryPtr->string);
    if (entryPtr->textVarName != NULL) {
	Tcl_UntraceVar2(entryPtr->interp, entryPtr->textVarName,
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, entryPtr);
	entryPtr->flags &= ~ENTRY_VAR_TRACED;
    }
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);







|

|








|
|
|







1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
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.
     */

    ckfree((char *)entryPtr->string);
    if (entryPtr->textVarName != NULL) {
	Tcl_UntraceVar(entryPtr->interp, entryPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, (ClientData) entryPtr);
	entryPtr->flags &= ~ENTRY_VAR_TRACED;
    }
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
	if (sbPtr->formatBuf) {
	    ckfree(sbPtr->formatBuf);
	}
    }
    Tk_FreeTextLayout(entryPtr->textLayout);
    Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable,
	    entryPtr->tkwin);
    Tcl_Release(entryPtr->tkwin);
    entryPtr->tkwin = NULL;

    ckfree(entryPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureEntry --
 *







|


|







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
	if (sbPtr->formatBuf) {
	    ckfree(sbPtr->formatBuf);
	}
    }
    Tk_FreeTextLayout(entryPtr->textLayout);
    Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable,
	    entryPtr->tkwin);
    Tcl_Release((ClientData) entryPtr->tkwin);
    entryPtr->tkwin = NULL;

    ckfree((char *) entryPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureEntry --
 *
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
{
    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;
    char *oldFormat = NULL;
    int error;
    int oldExport = 0;
    int valuesChanged = 0;
    double oldFrom = 0.0;
    double oldTo = 0.0;
    int code;

    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {
	Tcl_UntraceVar2(interp, entryPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, entryPtr);
	entryPtr->flags &= ~ENTRY_VAR_TRACED;
    }

    /*
     * Store old values that we need to effect certain behavior if they change
     * value.
     */

    oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp));
    if (entryPtr->type == TK_SPINBOX) {
	oldValues = sbPtr->valueStr;
	oldFormat = sbPtr->reqFormat;
	oldFrom = sbPtr->fromValue;
	oldTo = sbPtr->toValue;
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, entryPtr,
		    entryPtr->optionTable, objc, objv,
		    entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|
|

|
|
|
|








|

|








|

|
|
|
|








|







1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
{
    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 */
    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 code;

    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {
	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.
     */

    oldExport		= entryPtr->exportSelection;
    if (entryPtr->type == TK_SPINBOX) {
	oldValues	= sbPtr->valueStr;
	oldFormat	= sbPtr->reqFormat;
	oldFrom		= sbPtr->fromValue;
	oldTo		= sbPtr->toValue;
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) entryPtr,
		    entryPtr->optionTable, objc, objv,
		    entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
	}
	if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) {
	    entryPtr->insertBorderWidth = entryPtr->insertWidth/2;
	}

	if (entryPtr->type == TK_SPINBOX) {
	    if (sbPtr->fromValue > sbPtr->toValue) {
                /*

                 * Swap -from and -to values.
                 */

                double tmpFromTo = sbPtr->fromValue;

                sbPtr->fromValue = sbPtr->toValue;
                sbPtr->toValue = tmpFromTo;
            }

	    if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) {
		/*
		 * Make sure that the given format is somewhat correct, and
		 * 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;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		badFormatOpt:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad spinbox format specifier \"%s\"",
			    sbPtr->reqFormat));
		    Tcl_SetErrorCode(interp, "TK", "SPINBOX", "FORMAT_SANITY",
			    NULL);
		    continue;
		}
		if ((sscanf(fmt, "%%%d.%d%[f]", &min, &max, fbuf) == 3)
			&& (max >= 0)) {
		    formatSpace = min + max + 1;
		} else if (((sscanf(fmt, "%%.%d%[f]", &min, fbuf) == 2)
			|| (sscanf(fmt, "%%%d%[f]", &min, fbuf) == 2)
			|| (sscanf(fmt, "%%%d.%[f]", &min, fbuf) == 2))
			&& (min >= 0)) {
		    formatSpace = min + 1;
		} else {
		    goto badFormatOpt;
		}
		if (formatSpace < TCL_DOUBLE_SPACE) {
		    formatSpace = TCL_DOUBLE_SPACE;
		}
		sbPtr->formatBuf = (char *)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.
		 */

		oldFrom = sbPtr->fromValue - 1;







<
>
|
<
|
<
|
<
<
|














|
<
|
|
<
<
















|







1170
1171
1172
1173
1174
1175
1176

1177
1178

1179

1180


1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198


1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
	}
	if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) {
	    entryPtr->insertBorderWidth = entryPtr->insertWidth/2;
	}

	if (entryPtr->type == TK_SPINBOX) {
	    if (sbPtr->fromValue > sbPtr->toValue) {

		Tcl_SetResult(interp,
			"-to value must be greater than -from value",

			TCL_VOLATILE);

		continue;


	    }

	    if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) {
		/*
		 * Make sure that the given format is somewhat correct, and
		 * 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;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		    badFormatOpt:

		    Tcl_AppendResult(interp, "bad spinbox format specifier \"",
			    sbPtr->reqFormat, "\"", NULL);


		    continue;
		}
		if ((sscanf(fmt, "%%%d.%d%[f]", &min, &max, fbuf) == 3)
			&& (max >= 0)) {
		    formatSpace = min + max + 1;
		} else if (((sscanf(fmt, "%%.%d%[f]", &min, fbuf) == 2)
			|| (sscanf(fmt, "%%%d%[f]", &min, fbuf) == 2)
			|| (sscanf(fmt, "%%%d.%[f]", &min, fbuf) == 2))
			&& (min >= 0)) {
		    formatSpace = min + 1;
		} else {
		    goto badFormatOpt;
		}
		if (formatSpace < TCL_DOUBLE_SPACE) {
		    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.
		 */

		oldFrom = sbPtr->fromValue - 1;
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, TCL_INDEX_NONE);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
		    sbPtr->listObj = newObjPtr;
		    Tcl_IncrRefCount(sbPtr->listObj);







|







1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, -1);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
		    sbPtr->listObj = newObjPtr;
		    Tcl_IncrRefCount(sbPtr->listObj);
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
	}

	/*
	 * Claim the selection if we've suddenly started exporting it.
	 */

	if (entryPtr->exportSelection && (!oldExport)
		&& (!Tcl_IsSafe(entryPtr->interp))
		&& (entryPtr->selectFirst != TCL_INDEX_NONE)
		&& !(entryPtr->flags & GOT_SELECTION)) {
	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		    entryPtr);
	    entryPtr->flags |= GOT_SELECTION;
	}

	/*
	 * Recompute the window's geometry and arrange for it to be
	 * redisplayed.
	 */







<
|


|







1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
	}

	/*
	 * Claim the selection if we've suddenly started exporting it.
	 */

	if (entryPtr->exportSelection && (!oldExport)

		&& (entryPtr->selectFirst != -1)
		&& !(entryPtr->flags & GOT_SELECTION)) {
	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		    (ClientData) entryPtr);
	    entryPtr->flags |= GOT_SELECTION;
	}

	/*
	 * Recompute the window's geometry and arrange for it to be
	 * redisplayed.
	 */
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
     * If the entry is tied to the value of a variable, create the variable if
     * it doesn't exist, and set the entry's value from the variable's value.
     */

    if (entryPtr->textVarName != NULL) {
	const char *value;

	value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
	if (value == NULL) {

            /*
             * Since any trace on the textvariable was eliminated above,
             * the only possible reason for EntryValueChanged to return
             * an error is that the textvariable lives in a namespace
             * that does not (yet) exist. Indeed, namespaces are not







|







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
     * If the entry is tied to the value of a variable, create the variable if
     * it doesn't exist, and set the entry's value from the variable's value.
     */

    if (entryPtr->textVarName != NULL) {
	const char *value;

	value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
	if (value == NULL) {

            /*
             * Since any trace on the textvariable was eliminated above,
             * the only possible reason for EntryValueChanged to return
             * an error is that the textvariable lives in a namespace
             * that does not (yet) exist. Indeed, namespaces are not
1381
1382
1383
1384
1385
1386
1387

1388
1389
1390
1391

1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
	     */

	    double dvalue;

	    if (sscanf(entryPtr->string, "%lf", &dvalue) <= 0) {
		/* Scan failure */
		dvalue = sbPtr->fromValue;

	    } else if (dvalue > sbPtr->toValue) {
		dvalue = sbPtr->toValue;
	    } else if (dvalue < sbPtr->fromValue) {
		dvalue = sbPtr->fromValue;

	    }
	    sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);

            /*
	     * No check for error return here as well, because any possible
	     * error will be trapped below when attempting tracing.
	     */

	    EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }

    /*
     * 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)
	    && !(entryPtr->flags & ENTRY_VAR_TRACED)) {
	code = Tcl_TraceVar2(interp, entryPtr->textVarName,
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, entryPtr);
        if (code != TCL_OK) {
            return TCL_ERROR;
        }
        entryPtr->flags |= ENTRY_VAR_TRACED;
    }

    EntryWorldChanged(entryPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }







>
|
|
|
|
>



















|
|
|






|







1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
	     */

	    double dvalue;

	    if (sscanf(entryPtr->string, "%lf", &dvalue) <= 0) {
		/* Scan failure */
		dvalue = sbPtr->fromValue;
	    } else {
		if (dvalue > sbPtr->toValue) {
		    dvalue = sbPtr->toValue;
		} else if (dvalue < sbPtr->fromValue) {
		    dvalue = sbPtr->fromValue;
		}
	    }
	    sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);

            /*
	     * No check for error return here as well, because any possible
	     * error will be trapped below when attempting tracing.
	     */

	    EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }

    /*
     * 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)
	    && !(entryPtr->flags & ENTRY_VAR_TRACED)) {
	code = Tcl_TraceVar(interp, entryPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, (ClientData) entryPtr);
        if (code != TCL_OK) {
            return TCL_ERROR;
        }
        entryPtr->flags |= ENTRY_VAR_TRACED;
    }

    EntryWorldChanged((ClientData) entryPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *)instanceData;

    entryPtr->avgWidth = Tk_TextWidth(entryPtr->tkfont, "0", 1);
    if (entryPtr->avgWidth == 0) {
	entryPtr->avgWidth = 1;
    }

    if (entryPtr->type == TK_SPINBOX) {







|







1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *) instanceData;

    entryPtr->avgWidth = Tk_TextWidth(entryPtr->tkfont, "0", 1);
    if (entryPtr->avgWidth == 0) {
	entryPtr->avgWidth = 1;
    }

    if (entryPtr->type == TK_SPINBOX) {
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489

    /*
     * 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;







|
|







1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462

    /*
     * 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;
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    entryPtr->textGC = gc;

    if (entryPtr->placeholderColorPtr != NULL) {
	gcValues.foreground = entryPtr->placeholderColorPtr->pixel;
    }
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->placeholderGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->placeholderGC);
    }
    entryPtr->placeholderGC = gc;

    if (entryPtr->selFgColorPtr != NULL) {
	gcValues.foreground = entryPtr->selFgColorPtr->pixel;
    } else {
        gcValues.foreground = colorPtr->pixel;
    }
    gcValues.font = Tk_FontId(entryPtr->tkfont);
    mask = GCForeground | GCFont;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }







<
<
<
<
<
<
<
<
<
<


<
<







1476
1477
1478
1479
1480
1481
1482










1483
1484


1485
1486
1487
1488
1489
1490
1491
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    entryPtr->textGC = gc;











    if (entryPtr->selFgColorPtr != NULL) {
	gcValues.foreground = entryPtr->selFgColorPtr->pixel;


    }
    gcValues.font = Tk_FontId(entryPtr->tkfont);
    mask = GCForeground | GCFont;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550


1551
1552
1553

1554
1555
1556

1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581


1582
1583
1584

1585
1586
1587

1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606

#ifndef MAC_OSX_TK
/*
 *--------------------------------------------------------------
 *
 * TkpDrawEntryBorderAndFocus --
 *
 *	Stub function for Tk on platforms other than Aqua
 *	(Windows and X11), which do not draw native entry borders.
 *	See macosx/tkMacOSXEntry.c for function definition in Tk Aqua.


 *
 * Results:
 *	Returns 0.

 *
 * Side effects:
 *	None.

 *
 *--------------------------------------------------------------
 */

int
TkpDrawEntryBorderAndFocus(
    Entry *entryPtr,
    Drawable pixmap,
    int isSpinbox)
{
    (void)entryPtr;
    (void)pixmap;
    (void)isSpinbox;

    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --
 *
 *	Stub function for Tk on platforms other than Aqua
 *	(Windows and X11), which do not draw native spinbox buttons.
 *	See macosx/tkMacOSXEntry.c for function definition in Tk Aqua.


 *
 * Results:
 *	Returns 0.

 *
 * Side effects:
 *	None.

 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Pixmap pixmap)
{
    (void)sbPtr;
    (void)pixmap;

    return 0;
}
#endif /* Not MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *







|
|
|
>
>


<
>


<
>










<
<
<
<








|
|
|
>
>


<
>


<
>









<
<
<







1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518

1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529




1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544

1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
1555
1556
1557



1558
1559
1560
1561
1562
1563
1564

#ifndef MAC_OSX_TK
/*
 *--------------------------------------------------------------
 *
 * TkpDrawEntryBorderAndFocus --
 *
 *	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.
 *
 * Side effects:

 *	May draw the entry border into pixmap.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawEntryBorderAndFocus(
    Entry *entryPtr,
    Drawable pixmap,
    int isSpinbox)
{




    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --
 *
 *	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.
 *
 * Side effects:

 *	May draw the entry border into pixmap.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Pixmap pixmap)
{



    return 0;
}
#endif /* Not MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
 *--------------------------------------------------------------
 */

static void
DisplayEntry(
    ClientData clientData)	/* Information about window. */
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->tkwin;
    int baseY, selStartX, selEndX, cursorX;
    int showSelection, xBound;
    Tk_FontMetrics fm;
    Pixmap pixmap;
    Tk_3DBorder border;








|







1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
 *--------------------------------------------------------------
 */

static void
DisplayEntry(
    ClientData clientData)	/* Information about window. */
{
    Entry *entryPtr = (Entry *) clientData;
    Tk_Window tkwin = entryPtr->tkwin;
    int baseY, selStartX, selEndX, cursorX;
    int showSelection, xBound;
    Tk_FontMetrics fm;
    Pixmap pixmap;
    Tk_3DBorder border;

1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
	entryPtr->flags &= ~UPDATE_SCROLLBAR;

	/*
	 * Preserve/Release because updating the scrollbar can have the
	 * side-effect of destroying or unmapping the entry widget.
	 */

	Tcl_Preserve(entryPtr);
	EntryUpdateScrollbar(entryPtr);

	if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release(entryPtr);
	    return;
	}
	Tcl_Release(entryPtr);
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * 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







|



|


|







1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
	entryPtr->flags &= ~UPDATE_SCROLLBAR;

	/*
	 * Preserve/Release because updating the scrollbar can have the
	 * side-effect of destroying or unmapping the entry widget.
	 */

	Tcl_Preserve((ClientData) entryPtr);
	EntryUpdateScrollbar(entryPtr);

	if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release((ClientData) entryPtr);
	    return;
	}
	Tcl_Release((ClientData) entryPtr);
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * 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
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
    xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
    baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;

    /*
     * Hide the selection whenever we don't have the focus, unless we
     * always want to show selection.
     */
    if (Tk_AlwaysShowSelection(entryPtr->tkwin)) {
	showSelection = 1;
    } else {
	showSelection = (entryPtr->flags & GOT_FOCUS);
    }

    /*
     * Draw the background in three layers. From bottom to top the layers are:







|







1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
    xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
    baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;

    /*
     * Hide the selection whenever we don't have the focus, unless we
     * always want to show selection.
     */
    if (TkpAlwaysShowSelection(entryPtr->tkwin)) {
	showSelection = 1;
    } else {
	showSelection = (entryPtr->flags & GOT_FOCUS);
    }

    /*
     * Draw the background in three layers. From bottom to top the layers are:
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
    } else {
	border = entryPtr->normalBorder;
    }
    Tk_Fill3DRectangle(tkwin, pixmap, border,
	    0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selectLast + 1  > entryPtr->leftIndex + 1)) {
	if (entryPtr->selectFirst <= entryPtr->leftIndex) {
	    selStartX = entryPtr->leftX;
	} else {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst,
		    &selStartX, NULL, NULL, NULL);
	    selStartX += entryPtr->layoutX;
	}
	if ((selStartX - entryPtr->selBorderWidth) < xBound) {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectLast,
		    &selEndX, NULL, NULL, NULL);
	    selEndX += entryPtr->layoutX;
	    Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->selBorder,
		    selStartX - entryPtr->selBorderWidth,
		    baseY - fm.ascent - entryPtr->selBorderWidth,
		    (selEndX - selStartX) + 2*entryPtr->selBorderWidth,
		    (fm.ascent + fm.descent) + 2*entryPtr->selBorderWidth,
		    entryPtr->selBorderWidth,
#ifndef MAC_OSX_TK
		    TK_RELIEF_RAISED
#else
		    MAC_OSX_ENTRY_SELECT_RELIEF
#endif
		    );
	}







|
















|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
    } else {
	border = entryPtr->normalBorder;
    }
    Tk_Fill3DRectangle(tkwin, pixmap, border,
	    0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selectLast > entryPtr->leftIndex)) {
	if (entryPtr->selectFirst <= entryPtr->leftIndex) {
	    selStartX = entryPtr->leftX;
	} else {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst,
		    &selStartX, NULL, NULL, NULL);
	    selStartX += entryPtr->layoutX;
	}
	if ((selStartX - entryPtr->selBorderWidth) < xBound) {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectLast,
		    &selEndX, NULL, NULL, NULL);
	    selEndX += entryPtr->layoutX;
	    Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->selBorder,
		    selStartX - entryPtr->selBorderWidth,
		    baseY - fm.ascent - entryPtr->selBorderWidth,
		    (selEndX - selStartX) + 2*entryPtr->selBorderWidth,
		    (fm.ascent + fm.descent) + 2*entryPtr->selBorderWidth,
		    entryPtr->selBorderWidth, 
#ifndef MAC_OSX_TK
		    TK_RELIEF_RAISED
#else
		    MAC_OSX_ENTRY_SELECT_RELIEF
#endif
		    );
	}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	if ((entryPtr->insertPos + 1 >= entryPtr->leftIndex + 1) && 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->numChars == 0) && (entryPtr->placeholderChars != 0)) {

        /*
         * Draw the placeholder text.

         */

        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->placeholderGC,
	    entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY,
	    entryPtr->placeholderLeftIndex, entryPtr->placeholderChars);

    } else {

        if (showSelection && (entryPtr->state != STATE_DISABLED)
	        && (entryPtr->selTextGC != entryPtr->textGC)
	        && (entryPtr->selectFirst + 1 < entryPtr->selectLast + 1)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */

	    TkSizeT selFirst;

	    if (entryPtr->selectFirst + 1 < entryPtr->leftIndex + 1) {
	        selFirst = entryPtr->leftIndex;
	    } else {
	        selFirst = entryPtr->selectFirst;
	    }
	    if (entryPtr->leftIndex < selFirst) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->leftIndex, selFirst);
	    }
	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    selFirst, entryPtr->selectLast);
	    if (entryPtr->selectLast < entryPtr->numChars) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->selectLast, entryPtr->numChars);
	    }
        } else {

            /*
             * Draw the entire visible text
             */

	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    entryPtr->leftIndex, entryPtr->numChars);
        }
    }

    if (entryPtr->type == TK_SPINBOX) {
	int startx, height, inset, pad, tHeight, xWidth;
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	/*







|













<
<
|
|
>
|

|
|
|

<
<
|
|
|
<
<
<
<
<
|

|
|
|
|
|
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726


1727
1728
1729
1730
1731
1732
1733
1734
1735


1736
1737
1738





1739
1740
1741
1742
1743
1744
1745





1746
1747
1748















1749
1750
1751
1752
1753
1754
1755
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	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
     * selected portion on top of it.
     */

    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
	    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
	    entryPtr->leftIndex, entryPtr->numChars);



    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selTextGC != entryPtr->textGC)
	    && (entryPtr->selectFirst < entryPtr->selectLast)) {





	int selFirst;

	if (entryPtr->selectFirst < entryPtr->leftIndex) {
	    selFirst = entryPtr->leftIndex;
	} else {
	    selFirst = entryPtr->selectFirst;
	}





	Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		selFirst, entryPtr->selectLast);















    }

    if (entryPtr->type == TK_SPINBOX) {
	int startx, height, inset, pad, tHeight, xWidth;
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	/*
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
 *----------------------------------------------------------------------
 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, rightX;
    TkSizeT maxOffScreen;
    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * If we're displaying a special character instead of the value of the
     * entry, recompute the displayString.
     */

    if (entryPtr->showChar != NULL) {
	int ch;
	char buf[6];
	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.
	 */

	TkUtfToUniChar(entryPtr->showChar, &ch);
	size = TkUniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *)ckalloc(entryPtr->numDisplayBytes + 1);
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; i-- > 0; ) {
	    memcpy(p, buf, size);
	    p += size;
	}
	*p = '\0';
    }

    /* Recompute layout of placeholder text.
     * Only the placeholderX and placeholderLeftIndex value is needed.
     * We use the same font so we can use the layoutY value from below.
     */

    Tk_FreeTextLayout(entryPtr->placeholderLayout);
    if (entryPtr->placeholderString) {
        entryPtr->placeholderChars = strlen(entryPtr->placeholderString);
        entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	        entryPtr->placeholderString, entryPtr->placeholderChars, 0,
	        entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, NULL);
	overflow = totalLength -
	        (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth);
	if (overflow <= 0) {
	    entryPtr->placeholderLeftIndex = 0;
	    if (entryPtr->justify == TK_JUSTIFY_LEFT) {
		entryPtr->placeholderX = entryPtr->inset;
	    } else if (entryPtr->justify == TK_JUSTIFY_RIGHT) {
		entryPtr->placeholderX = Tk_Width(entryPtr->tkwin) - entryPtr->inset
		        - entryPtr->xWidth - totalLength;
	    } else {
		entryPtr->placeholderX = (Tk_Width(entryPtr->tkwin)
		        - entryPtr->xWidth - totalLength)/2;
	    }
    	} 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
	     * placeholderLeftIndex be any greater than that.
	     */

	    maxOffScreen = Tk_PointToChar(entryPtr->placeholderLayout, overflow, 0);
	    Tk_CharBbox(entryPtr->placeholderLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	    if (rightX < overflow) {
		maxOffScreen++;
	    }
	    entryPtr->placeholderLeftIndex = maxOffScreen;
	    Tk_CharBbox(entryPtr->placeholderLayout, entryPtr->placeholderLeftIndex, &rightX,
		NULL, NULL, NULL);
	    entryPtr->placeholderX = entryPtr->inset -rightX;
        }
    } else {
        entryPtr->placeholderChars = 0;
        entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	        entryPtr->placeholderString, 0, 0,
	        entryPtr->justify, TK_IGNORE_NEWLINES, NULL, NULL);
	entryPtr->placeholderX = entryPtr->inset;
    }

    Tk_FreeTextLayout(entryPtr->textLayout);
    entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	    entryPtr->displayString, entryPtr->numChars, 0,
	    entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height);

    entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2;








|
<
















|
|









|
|


|


|
<
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1898
1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945




















































1946
1947
1948
1949
1950
1951
1952
 *----------------------------------------------------------------------
 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, maxOffScreen, rightX;

    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * If we're displaying a special character instead of the value of the
     * entry, recompute the displayString.
     */

    if (entryPtr->showChar != NULL) {
	Tcl_UniChar ch;
	char buf[TCL_UTF_MAX];
	int size;

	/*
	 * Normalize the special character so we can safely duplicate it in
	 * the display string. If we didn't do this, then two malformed
	 * characters might end up looking like one valid UTF character in the
	 * resulting string.
	 */

	Tcl_UtfToUniChar(entryPtr->showChar, &ch);
	size = Tcl_UniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *) ckalloc((unsigned) (entryPtr->numDisplayBytes + 1));
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; --i >= 0; ) {

	    p += Tcl_UniCharToUtf(ch, p);
	}
	*p = '\0';
    }





















































    Tk_FreeTextLayout(entryPtr->textLayout);
    entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	    entryPtr->displayString, entryPtr->numChars, 0,
	    entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height);

    entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2;

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128

2129
2130
2131
2132
2133
2134
2135

	maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
	Tk_CharBbox(entryPtr->textLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	if (rightX < overflow) {
	    maxOffScreen++;
	}
	if (entryPtr->leftIndex + 1 > maxOffScreen + 1) {
	    entryPtr->leftIndex = maxOffScreen;
	}
	Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX,
		NULL, NULL, NULL);
	entryPtr->leftX = entryPtr->inset;
	entryPtr->layoutX = entryPtr->leftX - rightX;
    }

    Tk_GetFontMetrics(entryPtr->tkfont, &fm);
    height = fm.linespace + 2*entryPtr->inset + 2*(YPAD-XPAD);
    if (entryPtr->prefWidth > 0) {
	width = entryPtr->prefWidth*entryPtr->avgWidth + 2*entryPtr->inset;

    } else if (totalLength == 0) {
	width = entryPtr->avgWidth + 2*entryPtr->inset;
    } else {
	width = totalLength + 2*entryPtr->inset;

    }

    /*
     * Add one extra length for the spin buttons
     */
    width += entryPtr->xWidth;








|












>
|
|
|
|
>







1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013

	maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
	Tk_CharBbox(entryPtr->textLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	if (rightX < overflow) {
	    maxOffScreen++;
	}
	if (entryPtr->leftIndex > maxOffScreen) {
	    entryPtr->leftIndex = maxOffScreen;
	}
	Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX,
		NULL, NULL, NULL);
	entryPtr->leftX = entryPtr->inset;
	entryPtr->layoutX = entryPtr->leftX - rightX;
    }

    Tk_GetFontMetrics(entryPtr->tkfont, &fm);
    height = fm.linespace + 2*entryPtr->inset + 2*(YPAD-XPAD);
    if (entryPtr->prefWidth > 0) {
	width = entryPtr->prefWidth*entryPtr->avgWidth + 2*entryPtr->inset;
    } else {
	if (totalLength == 0) {
	    width = entryPtr->avgWidth + 2*entryPtr->inset;
	} else {
	    width = totalLength + 2*entryPtr->inset;
	}
    }

    /*
     * Add one extra length for the spin buttons
     */
    width += entryPtr->xWidth;

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164

2165

2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
 *
 *----------------------------------------------------------------------
 */

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    TkSizeT index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{

    size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;

    const char *string;
    char *newStr;

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = strlen(value);
    if (byteCount == 0) {
	return TCL_OK;
    }

    newByteCount = entryPtr->numBytes + byteCount + 1;
    newStr = (char *)ckalloc(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, newStr, index,







|

|


>
|
>











|







2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
 *
 *----------------------------------------------------------------------
 */

static int
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). */
{
    ptrdiff_t byteIndex;
    size_t byteCount, newByteCount;
    int oldChars, charsAdded;
    const char *string;
    char *newStr;

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = strlen(value);
    if (byteCount == 0) {
	return TCL_OK;
    }

    newByteCount = entryPtr->numBytes + byteCount + 1;
    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, newStr, index,
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
     * 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(newStr, TCL_INDEX_NONE);
    charsAdded = entryPtr->numChars - oldChars;
    entryPtr->numBytes += byteCount;

    if (entryPtr->displayString == string) {
	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.
     */

    if (entryPtr->selectFirst + 1 >= index + 1) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast + 1 > index + 1) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor + 1 > index + 1) || (entryPtr->selectFirst + 1 >= index + 1)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------







|
















|


|


|


|


|







2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
     * 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(newStr, -1);
    charsAdded = entryPtr->numChars - oldChars;
    entryPtr->numBytes += byteCount;

    if (entryPtr->displayString == string) {
	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.
     */

    if (entryPtr->selectFirst >= index) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast > index) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex > index) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos >= index) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
 *
 *----------------------------------------------------------------------
 */

static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    TkSizeT index,			/* Index of first character to delete. */
    TkSizeT count)			/* How many characters to delete. */
{
    int byteIndex, byteCount, newByteCount;
    const char *string;
    char *newStr, *toDelete;

    if (index + count + 1 > entryPtr->numChars + 1) {
	count = entryPtr->numChars - index;
    }
    if ((int)count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->numBytes + 1 - byteCount;
    newStr = (char *)ckalloc(newByteCount);
    memcpy(newStr, string, (size_t) byteIndex);
    strcpy(newStr + byteIndex, string + byteIndex + byteCount);

    toDelete = (char *)ckalloc(byteCount + 1);
    memcpy(toDelete, string + byteIndex, (size_t) byteCount);
    toDelete[byteCount] = '\0';

    if ((entryPtr->validate == VALIDATE_KEY ||
	    entryPtr->validate == VALIDATE_ALL) &&
	    EntryValidateChange(entryPtr, toDelete, newStr, index,
		    VALIDATE_DELETE) != TCL_OK) {







|
|





|


|








|



|







2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
 *
 *----------------------------------------------------------------------
 */

static int
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 *newStr, *toDelete;

    if ((index + count) > entryPtr->numChars) {
	count = entryPtr->numChars - index;
    }
    if (count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->numBytes + 1 - 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';

    if ((entryPtr->validate == VALIDATE_KEY ||
	    entryPtr->validate == VALIDATE_ALL) &&
	    EntryValidateChange(entryPtr, toDelete, newStr, index,
		    VALIDATE_DELETE) != TCL_OK) {
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352

    /*
     * Deleting characters results in the remaining characters being
     * renumbered. Update the various indexes into the string to reflect this
     * change.
     */

    if (entryPtr->selectFirst + 1 >= index + 1) {
	if (entryPtr->selectFirst + 1 >= index + count + 1) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast + 1 >= index + 1) {
	if (entryPtr->selectLast + 1 >= index + count + 1) {
	    entryPtr->selectLast -= count;
	} else {
	    entryPtr->selectLast = index;
	}
    }
    if (entryPtr->selectLast + 1 <= entryPtr->selectFirst + 1) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
    }
    if (entryPtr->selectAnchor + 1 >= index + 1) {
	if (entryPtr->selectAnchor + 1 >= index + count + 1) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	if (entryPtr->leftIndex + 1 >= index + count + 1) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	if (entryPtr->insertPos + 1 >= index + count + 1) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}







|
|





|
|





|
|
|

|
|





|
|





|
|







2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232

    /*
     * Deleting characters results in the remaining characters being
     * renumbered. Update the various indexes into the string to reflect this
     * change.
     */

    if (entryPtr->selectFirst >= index) {
	if (entryPtr->selectFirst >= (index + count)) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast >= index) {
	if (entryPtr->selectLast >= (index + count)) {
	    entryPtr->selectLast -= count;
	} else {
	    entryPtr->selectLast = index;
	}
    }
    if (entryPtr->selectLast <= entryPtr->selectFirst) {
	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
    }
    if (entryPtr->selectAnchor >= index) {
	if (entryPtr->selectAnchor >= (index+count)) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex > index) {
	if (entryPtr->leftIndex >= (index + count)) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos >= index) {
	if (entryPtr->insertPos >= (index + count)) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
    if (newValue != NULL) {
	EntrySetValue(entryPtr, newValue);
    }

    if (entryPtr->textVarName == NULL) {
	newValue = NULL;
    } else {
	newValue = Tcl_SetVar2(entryPtr->interp, entryPtr->textVarName,
		NULL, entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
    }

    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 function wasn't invoked since the modification came while







|
|







2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
    if (newValue != NULL) {
	EntrySetValue(entryPtr, newValue);
    }

    if (entryPtr->textVarName == NULL) {
	newValue = NULL;
    } else {
	newValue = Tcl_SetVar(entryPtr->interp, entryPtr->textVarName,
		entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
    }

    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 function wasn't invoked since the modification came while
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
    } 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
	 */

	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	value = tmp;
	malloced = 1;

	entryPtr->flags |= VALIDATE_VAR;
	(void) EntryValidateChange(entryPtr, NULL, value, -1,







|







2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
    } 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
	 */

	char *tmp = (char *) ckalloc((unsigned) (valueLen + 1));

	strcpy(tmp, value);
	value = tmp;
	malloced = 1;

	entryPtr->flags |= VALIDATE_VAR;
	(void) EntryValidateChange(entryPtr, NULL, value, -1,
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532

    oldSource = entryPtr->string;
    ckfree((char *)entryPtr->string);

    if (malloced) {
	entryPtr->string = value;
    } else {
	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	entryPtr->string = tmp;
    }
    entryPtr->numBytes = valueLen;
    entryPtr->numChars = Tcl_NumUtfChars(value, valueLen);

    if (entryPtr->displayString == oldSource) {
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
	if (entryPtr->selectFirst + 1 >= entryPtr->numChars + 1) {
	    entryPtr->selectFirst = TCL_INDEX_NONE;
	    entryPtr->selectLast = TCL_INDEX_NONE;
	} else if (entryPtr->selectLast + 1 > entryPtr->numChars + 1) {
	    entryPtr->selectLast = entryPtr->numChars;
	}
    }
    if (entryPtr->leftIndex + 1 >= entryPtr->numChars + 1) {
	if (entryPtr->numChars + 1 > 1) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos + 1 > entryPtr->numChars + 1) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}







|












|
|
|
|
|



|
|





|







2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412

    oldSource = entryPtr->string;
    ckfree((char *)entryPtr->string);

    if (malloced) {
	entryPtr->string = value;
    } else {
	char *tmp = (char *) ckalloc((unsigned) (valueLen + 1));

	strcpy(tmp, value);
	entryPtr->string = tmp;
    }
    entryPtr->numBytes = valueLen;
    entryPtr->numChars = Tcl_NumUtfChars(value, valueLen);

    if (entryPtr->displayString == oldSource) {
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    if (entryPtr->selectFirst >= 0) {
	if (entryPtr->selectFirst >= entryPtr->numChars) {
	    entryPtr->selectFirst = -1;
	    entryPtr->selectLast = -1;
	} else if (entryPtr->selectLast > entryPtr->numChars) {
	    entryPtr->selectLast = entryPtr->numChars;
	}
    }
    if (entryPtr->leftIndex >= entryPtr->numChars) {
	if (entryPtr->numChars > 0) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos > entryPtr->numChars) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
 */

static void
EntryEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->type == TK_SPINBOX) && (eventPtr->type == MotionNotify)) {
	Spinbox *sbPtr = (Spinbox *)clientData;
	int elem;

	elem = GetSpinboxElement(sbPtr, eventPtr->xmotion.x,
		eventPtr->xmotion.y);
	if (elem != sbPtr->curElement) {
	    Tk_Cursor cursor;








|


|







2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
 */

static void
EntryEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Entry *entryPtr = (Entry *) clientData;

    if ((entryPtr->type == TK_SPINBOX) && (eventPtr->type == MotionNotify)) {
	Spinbox *sbPtr = (Spinbox *) clientData;
	int elem;

	elem = GetSpinboxElement(sbPtr, eventPtr->xmotion.x,
		eventPtr->xmotion.y);
	if (elem != sbPtr->curElement) {
	    Tk_Cursor cursor;

2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
    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, (Tcl_FreeProc *) DestroyEntry);
	}
	break;
    case ConfigureNotify:
	Tcl_Preserve(entryPtr);
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	Tcl_Release(entryPtr);
	break;
    case FocusIn:
    case FocusOut:
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    EntryFocusProc(entryPtr, (eventPtr->type == FocusIn));
	}
	break;







|



|



|







2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
    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));
	}
	break;
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
 *----------------------------------------------------------------------
 */

static void
EntryCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    /*
     * 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.
     */







|







2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
 *----------------------------------------------------------------------
 */

static void
EntryCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Entry *entryPtr = (Entry *) clientData;

    /*
     * 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.
     */
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697


2698
2699







2700
2701
2702
2703
2704
2705


2706
2707
2708



2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759


2760
2761
2762
2763
2764
2765
2766
2767
2768

2769
2770
2771
2772
2773
2774
2775
 */

static int
GetEntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,	/* Specifies character in entryPtr. */
    TkSizeT *indexPtr)		/* Where to store converted character index */
{
    TkSizeT length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > entryPtr->numChars) {
	    idx = entryPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);

    switch (string[0]) {
    case 'a':
	if (strncmp(string, "anchor", length) != 0) {


	    goto badIndex;
	}







	*indexPtr = entryPtr->selectAnchor;
	break;
    case 'i':
	if (strncmp(string, "insert", length) != 0) {
	    goto badIndex;
	}


	*indexPtr = entryPtr->insertPos;
	break;
    case 's':



	if (entryPtr->selectFirst == TCL_INDEX_NONE) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "NO_SELECTION", NULL);
	    return TCL_ERROR;
	}
	if (length < 5) {
	    goto badIndex;
	}
	if (strncmp(string, "sel.first", length) == 0) {
	    *indexPtr = entryPtr->selectFirst;
	} else if (strncmp(string, "sel.last", length) == 0) {
	    *indexPtr = entryPtr->selectLast;
	} else {
	    goto badIndex;
	}
	break;
    case '@': {
	int x, roundUp, maxWidth;

	if (Tcl_GetInt(NULL, string + 1, &x) != TCL_OK) {
	    goto badIndex;
	}
	if (x < entryPtr->inset) {
	    x = entryPtr->inset;
	}
	roundUp = 0;
	maxWidth = Tk_Width(entryPtr->tkwin) - entryPtr->inset
		- entryPtr->xWidth - 1;
	if (x > maxWidth) {
	    x = maxWidth;
	    roundUp = 1;
	}
	*indexPtr = Tk_PointToChar(entryPtr->textLayout,
		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.
	 */

	if (roundUp && (*indexPtr + 1 < entryPtr->numChars + 1)) {
	    *indexPtr += 1;
	}
	break;


    }
    default:
	  badIndex:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"",
		    (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox", string));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "BAD_INDEX", NULL);
	    return TCL_ERROR;

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|
|

|
<

<
<
<
<
<
<
<
<
<
|
<

|
<
|
>
>
|
|
>
>
>
>
>
>
>
|
<
|
<


>
>
|
<
|
>
>
>
|
<
<
|
|
<
<
<












<
|










|














|


|
>
>
|
|
|
<
|
<
|
<
<
>







2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560

2561









2562

2563
2564

2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577

2578

2579
2580
2581
2582
2583

2584
2585
2586
2587
2588


2589
2590



2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602

2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637

2638

2639


2640
2641
2642
2643
2644
2645
2646
2647
 */

static int
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 */
{
    size_t length;











    length = strlen(string);


    if (string[0] == 'a') {

	if (strncmp(string, "anchor", length) == 0) {
	    *indexPtr = entryPtr->selectAnchor;
	} else {
	badIndex:

	    Tcl_AppendResult(interp, "bad ",
		    (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox",
		    " index \"", string, "\"", NULL);
	    return TCL_ERROR;
	}
    } else if (string[0] == 'e') {
	if (strncmp(string, "end", length) == 0) {
	    *indexPtr = entryPtr->numChars;

	} else {

	    goto badIndex;
	}
    } else if (string[0] == 'i') {
	if (strncmp(string, "insert", length) == 0) {
	    *indexPtr = entryPtr->insertPos;

	} else {
	    goto badIndex;
	}
    } else if (string[0] == 's') {
	if (entryPtr->selectFirst < 0) {


	    Tcl_AppendResult(interp, "selection isn't in widget ",
		    Tk_PathName(entryPtr->tkwin), NULL);



	    return TCL_ERROR;
	}
	if (length < 5) {
	    goto badIndex;
	}
	if (strncmp(string, "sel.first", length) == 0) {
	    *indexPtr = entryPtr->selectFirst;
	} else if (strncmp(string, "sel.last", length) == 0) {
	    *indexPtr = entryPtr->selectLast;
	} else {
	    goto badIndex;
	}

    } else if (string[0] == '@') {
	int x, roundUp, maxWidth;

	if (Tcl_GetInt(NULL, string + 1, &x) != TCL_OK) {
	    goto badIndex;
	}
	if (x < entryPtr->inset) {
	    x = entryPtr->inset;
	}
	roundUp = 0;
	maxWidth = Tk_Width(entryPtr->tkwin) - entryPtr->inset
	    - entryPtr->xWidth - 1;
	if (x > maxWidth) {
	    x = maxWidth;
	    roundUp = 1;
	}
	*indexPtr = Tk_PointToChar(entryPtr->textLayout,
		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.
	 */

	if (roundUp && (*indexPtr < entryPtr->numChars)) {
	    *indexPtr += 1;
	}
    } else {
	if (Tcl_GetInt(NULL, string, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	if (*indexPtr < 0){
	    *indexPtr = 0;

	} else if (*indexPtr > entryPtr->numChars) {

	    *indexPtr = entryPtr->numChars;


	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
 */

static void
EntryScanTo(
    Entry *entryPtr,		/* Information about widget. */
    int x)			/* X-coordinate to use for scan operation. */
{
    TkSizeT 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).
     */

    newLeftIndex = entryPtr->scanMarkIndex
	    - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth;
    if (newLeftIndex + 1 >= entryPtr->numChars + 1) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex == TCL_INDEX_NONE) {
	newLeftIndex = entryPtr->scanMarkIndex = 0;
	entryPtr->scanMarkX = x;
    }

    if (newLeftIndex != entryPtr->leftIndex) {
	entryPtr->leftIndex = newLeftIndex;
	entryPtr->flags |= UPDATE_SCROLLBAR;







|














|



|







2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
 */

static void
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).
     */

    newLeftIndex = entryPtr->scanMarkIndex
	    - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth;
    if (newLeftIndex >= entryPtr->numChars) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex < 0) {
	newLeftIndex = entryPtr->scanMarkIndex = 0;
	entryPtr->scanMarkX = x;
    }

    if (newLeftIndex != entryPtr->leftIndex) {
	entryPtr->leftIndex = newLeftIndex;
	entryPtr->flags |= UPDATE_SCROLLBAR;
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    TkSizeT index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    TkSizeT newFirst, newLast;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		entryPtr);
	entryPtr->flags |= GOT_SELECTION;
    }

    /*
     * Pick new starting and ending points for the selection.
     */

    if (entryPtr->selectAnchor + 1 > entryPtr->numChars + 1) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor + 1 <= index + 1) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast == TCL_INDEX_NONE) {
	    newFirst = newLast = TCL_INDEX_NONE;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }
    entryPtr->selectFirst = newFirst;







|


|





|
<

|







|


|





|
|







2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732

2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
 *
 *----------------------------------------------------------------------
 */

static void
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;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) {

	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		(ClientData) entryPtr);
	entryPtr->flags |= GOT_SELECTION;
    }

    /*
     * Pick new starting and ending points for the selection.
     */

    if (entryPtr->selectAnchor > entryPtr->numChars) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor <= index) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast < 0) {
	    newFirst = newLast = -1;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }
    entryPtr->selectFirst = newFirst;
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942



2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
EntryFetchSelection(
    ClientData clientData,	/* Information about entry widget. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst == TCL_INDEX_NONE) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);
    if (selEnd <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }



    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *----------------------------------------------------------------------
 *
 * EntryLostSelection --
 *
 *	This function is called back by Tk when the selection is grabbed away
 *	from an entry widget.







|


|


|


|
|



|
<






<
<
<




>
>
>
|



|







2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802
2803
2804
2805



2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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 NUL character. */
{
    Entry *entryPtr = (Entry *) clientData;
    int byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) {

	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);



    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, (size_t) byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *----------------------------------------------------------------------
 *
 * EntryLostSelection --
 *
 *	This function is called back by Tk when the selection is grabbed away
 *	from an entry widget.
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
 *----------------------------------------------------------------------
 */

static void
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.
     */

    if (Tk_AlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst != TCL_INDEX_NONE) && entryPtr->exportSelection
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
	EventuallyRedraw(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *







|










|
|
<
|
|







2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852

2853
2854
2855
2856
2857
2858
2859
2860
2861
 *----------------------------------------------------------------------
 */

static void
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.
     */

    if (TkpAlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) {

	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
	EventuallyRedraw(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
     * 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)) {
	entryPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayEntry, entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EntryVisibleRange --







|







2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
     * 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)) {
	entryPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayEntry, (ClientData) entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EntryVisibleRange --
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
    if (entryPtr->numChars == 0) {
	*firstPtr = 0.0;
	*lastPtr = 1.0;
    } else {
	charsInWindow = Tk_PointToChar(entryPtr->textLayout,
		Tk_Width(entryPtr->tkwin) - entryPtr->inset
		- entryPtr->xWidth - entryPtr->layoutX - 1, 0);
	if (charsInWindow < (int)entryPtr->numChars) {
	    charsInWindow++;
	}
	charsInWindow -= entryPtr->leftIndex;
	if (charsInWindow == 0) {
	    charsInWindow = 1;
	}








|







2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
    if (entryPtr->numChars == 0) {
	*firstPtr = 0.0;
	*lastPtr = 1.0;
    } else {
	charsInWindow = Tk_PointToChar(entryPtr->textLayout,
		Tk_Width(entryPtr->tkwin) - entryPtr->inset
		- entryPtr->xWidth - entryPtr->layoutX - 1, 0);
	if (charsInWindow < entryPtr->numChars) {
	    charsInWindow++;
	}
	charsInWindow -= entryPtr->leftIndex;
	if (charsInWindow == 0) {
	    charsInWindow = 1;
	}

3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128

3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
EntryUpdateScrollbar(
    Entry *entryPtr)			/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE];
    int code;
    double first, last;
    Tcl_Interp *interp;
    Tcl_DString buf;

    if (entryPtr->scrollCmd == NULL) {
	return;
    }

    interp = entryPtr->interp;
    Tcl_Preserve(interp);
    EntryVisibleRange(entryPtr, &first, &last);
    Tcl_PrintDouble(NULL, first, firstStr);
    Tcl_PrintDouble(NULL, last, lastStr);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, entryPtr->scrollCmd, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, lastStr, TCL_INDEX_NONE);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (code != TCL_OK) {
	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		"\n    (horizontal scrolling command executed by %s)",
		Tk_PathName(entryPtr->tkwin)));

	Tcl_BackgroundException(interp, code);
    }
    Tcl_ResetResult(interp);
    Tcl_Release(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * EntryBlinkProc --
 *







<






|



<
|
<
<
<
|
<
<

|
|
|
>
|

|
|







2968
2969
2970
2971
2972
2973
2974

2975
2976
2977
2978
2979
2980
2981
2982
2983
2984

2985



2986


2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
EntryUpdateScrollbar(
    Entry *entryPtr)			/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE];
    int code;
    double first, last;
    Tcl_Interp *interp;


    if (entryPtr->scrollCmd == NULL) {
	return;
    }

    interp = entryPtr->interp;
    Tcl_Preserve((ClientData) interp);
    EntryVisibleRange(entryPtr, &first, &last);
    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 ");
	Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin));
	Tcl_AddErrorInfo(interp, ")");
	Tcl_BackgroundError(interp);
    }
    Tcl_SetResult(interp, NULL, TCL_STATIC);
    Tcl_Release((ClientData) interp);
}

/*
 *----------------------------------------------------------------------
 *
 * EntryBlinkProc --
 *
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
 *----------------------------------------------------------------------
 */

static void
EntryBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->state == STATE_DISABLED) ||
	    (entryPtr->state == STATE_READONLY) ||
	    !(entryPtr->flags & GOT_FOCUS) || (entryPtr->insertOffTime == 0)) {
	return;
    }
    if (entryPtr->flags & CURSOR_ON) {
	entryPtr->flags &= ~CURSOR_ON;
	entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		entryPtr->insertOffTime, EntryBlinkProc, entryPtr);
    } else {
	entryPtr->flags |= CURSOR_ON;
	entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		entryPtr->insertOnTime, EntryBlinkProc, entryPtr);
    }
    EventuallyRedraw(entryPtr);
}

/*
 *----------------------------------------------------------------------
 *







|









|



|







3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
 *----------------------------------------------------------------------
 */

static void
EntryBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    Entry *entryPtr = (Entry *) clientData;

    if ((entryPtr->state == STATE_DISABLED) ||
	    (entryPtr->state == STATE_READONLY) ||
	    !(entryPtr->flags & GOT_FOCUS) || (entryPtr->insertOffTime == 0)) {
	return;
    }
    if (entryPtr->flags & CURSOR_ON) {
	entryPtr->flags &= ~CURSOR_ON;
	entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
	    entryPtr->insertOffTime, EntryBlinkProc, (ClientData) entryPtr);
    } else {
	entryPtr->flags |= CURSOR_ON;
	entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
	    entryPtr->insertOnTime, EntryBlinkProc, (ClientData) entryPtr);
    }
    EventuallyRedraw(entryPtr);
}

/*
 *----------------------------------------------------------------------
 *
3198
3199
3200
3201
3202
3203
3204
3205

3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
				 * it's losing it. */
{
    Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
    if (gotFocus) {
	entryPtr->flags |= GOT_FOCUS | CURSOR_ON;
	if (entryPtr->insertOffTime != 0) {
	    entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    entryPtr->insertOnTime, EntryBlinkProc, entryPtr);

	}
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSIN) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, -1,
		    VALIDATE_FOCUSIN);
	}
    } else {
	entryPtr->flags &= ~(GOT_FOCUS | CURSOR_ON);
	entryPtr->insertBlinkHandler = NULL;
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSOUT) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, -1,
		    VALIDATE_FOCUSOUT);
	}
    }
    EventuallyRedraw(entryPtr);
}

/*
 *--------------------------------------------------------------







|
>


|
|
|
|



|

|
|
|
|







3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
				 * it's losing it. */
{
    Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
    if (gotFocus) {
	entryPtr->flags |= GOT_FOCUS | CURSOR_ON;
	if (entryPtr->insertOffTime != 0) {
	    entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    entryPtr->insertOnTime, EntryBlinkProc,
		    (ClientData) entryPtr);
	}
	if (entryPtr->validate == VALIDATE_ALL ||
	    entryPtr->validate == VALIDATE_FOCUS ||
	    entryPtr->validate == VALIDATE_FOCUSIN) {
	    EntryValidateChange(entryPtr, NULL,
				entryPtr->string, -1, VALIDATE_FOCUSIN);
	}
    } else {
	entryPtr->flags &= ~(GOT_FOCUS | CURSOR_ON);
	entryPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
	if (entryPtr->validate == VALIDATE_ALL ||
	    entryPtr->validate == VALIDATE_FOCUS ||
	    entryPtr->validate == VALIDATE_FOCUSOUT) {
	    EntryValidateChange(entryPtr, NULL,
				entryPtr->string, -1, VALIDATE_FOCUSOUT);
	}
    }
    EventuallyRedraw(entryPtr);
}

/*
 *--------------------------------------------------------------
3236
3237
3238
3239
3240
3241
3242

3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
 *
 * Side effects:
 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */


static char *
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;
    (void)name1;
    (void)name2;

    if (entryPtr->flags & ENTRY_DELETED) {
	/*
	 * Just abort early if we entered here while being deleted.
	 */
	return NULL;
    }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && entryPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        entryPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        EntryTextVarProc, probe);
                if (probe == (ClientData)entryPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
                return NULL;
            }
	    Tcl_SetVar2(interp, entryPtr->textVarName, NULL,
		    entryPtr->string, TCL_GLOBAL_ONLY);
	    Tcl_TraceVar2(interp, entryPtr->textVarName, NULL,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    EntryTextVarProc, clientData);
	    entryPtr->flags |= ENTRY_VAR_TRACED;
        }
	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).
     */

    value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    EntrySetValue(entryPtr, value);
    return NULL;
}








>








|

<
<














<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|



|









|







3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117


3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131


3132


















3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
 *
 * Side effects:
 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
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;



    if (entryPtr->flags & ENTRY_DELETED) {
	/*
	 * Just abort early if we entered here while being deleted.
	 */
	return NULL;
    }

    /*
     * 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_SetVar(interp, entryPtr->textVarName, entryPtr->string,
		    TCL_GLOBAL_ONLY);
	    Tcl_TraceVar(interp, entryPtr->textVarName,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    EntryTextVarProc, clientData);
	    entryPtr->flags |= ENTRY_VAR_TRACED;
	}
	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).
     */

    value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    EntrySetValue(entryPtr, value);
    return NULL;
}

3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
 *	An error condition may arise
 *
 *--------------------------------------------------------------
 */

static int
EntryValidate(
     Entry *entryPtr,	/* Entry that needs validation. */
     char *cmd)	/* Validation command (NULL-terminated
				 * string). */
{
    Tcl_Interp *interp = entryPtr->interp;
    int code, isOK;

    code = Tcl_EvalEx(interp, cmd, TCL_INDEX_NONE, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);

    /*
     * We accept TCL_OK and TCL_RETURN as valid return codes from the command
     * callback.
     */

    if (code != TCL_OK && code != TCL_RETURN) {
	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		"\n    (in validation command executed by %s)",
		Tk_PathName(entryPtr->tkwin)));

	Tcl_BackgroundException(interp, code);
	return TCL_ERROR;
    }

    /*
     * The command callback should return an acceptable Tcl boolean.
     */

    if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp),
	    &isOK) != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		 "\n    (invalid boolean result from validation command)");
	Tcl_BackgroundException(interp, TCL_ERROR);
	Tcl_ResetResult(interp);
	return TCL_ERROR;
    }

    Tcl_ResetResult(interp);
    return (isOK ? TCL_OK : TCL_BREAK);
}

/*
 *--------------------------------------------------------------
 *
 * EntryValidateChange --
 *
 *	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 occurred with validatecommand.
 *
 * Side effects:
 *	The insertion/deletion may be aborted, and the validatecommand might
 *	turn itself off (if an error or loop condition arises).
 *
 *--------------------------------------------------------------
 */

static int
EntryValidateChange(
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *change,	/* Characters to be added/deleted
				 * (NUL-terminated string). */
     const char *newValue,	/* Potential new value of entry string */
     TkSizeT 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) {
        if (entryPtr->flags & VALIDATING) {
            entryPtr->flags |= VALIDATE_ABORT;
        }
	return (varValidate ? TCL_ERROR : TCL_OK);
    }

    /*
     * If we're already validating, then we're hitting a loop condition. Set
     * validate to none to disallow further validations, arrange for flags
     * to prevent current validation from finishing, and return.
     */

    if (entryPtr->flags & VALIDATING) {
	entryPtr->validate = VALIDATE_NONE;
        entryPtr->flags |= VALIDATE_ABORT;
	return (varValidate ? TCL_ERROR : TCL_OK);
    }

    entryPtr->flags |= VALIDATING;

    /*
     * Now form command string and run through the -validatecommand







|
|


|
|

|







<
|
|
>
|








|

|
|
|



|
|












|










|
|


|









<
<
<




|
|
|




<







3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193

3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252



3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263

3264
3265
3266
3267
3268
3269
3270
 *	An error condition may arise
 *
 *--------------------------------------------------------------
 */

static int
EntryValidate(
     register Entry *entryPtr,	/* Entry that needs validation. */
     register char *cmd)	/* Validation command (NULL-terminated
				 * string). */
{
    register Tcl_Interp *interp = entryPtr->interp;
    int code, bool;

    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.
     */

    if (code != TCL_OK && code != TCL_RETURN) {

	Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by ");
	Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin));
	Tcl_AddErrorInfo(interp, ")");
	Tcl_BackgroundError(interp);
	return TCL_ERROR;
    }

    /*
     * The command callback should return an acceptable Tcl boolean.
     */

    if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp),
	    &bool) != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		 "\nvalid boolean not returned by validation command");
	Tcl_BackgroundError(interp);
	Tcl_SetResult(interp, NULL, 0);
	return TCL_ERROR;
    }

    Tcl_SetResult(interp, NULL, 0);
    return (bool ? TCL_OK : TCL_BREAK);
}

/*
 *--------------------------------------------------------------
 *
 * EntryValidateChange --
 *
 *	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.
 *
 * Side effects:
 *	The insertion/deletion may be aborted, and the validatecommand might
 *	turn itself off (if an error or loop condition arises).
 *
 *--------------------------------------------------------------
 */

static int
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 (entryPtr->flags & VALIDATING) {
	entryPtr->validate = VALIDATE_NONE;

	return (varValidate ? TCL_ERROR : TCL_OK);
    }

    entryPtr->flags |= VALIDATING;

    /*
     * Now form command string and run through the -validatecommand
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
    p = Tcl_DStringValue(&script);
    code = EntryValidate(entryPtr, p);
    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 occurred. Do not allow this
     * validation result to finish.
     */

    if (entryPtr->validate == VALIDATE_NONE
	    || (!varValidate && (entryPtr->flags & VALIDATE_VAR))) {
	code = TCL_ERROR;
    }







|







3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
    p = Tcl_DStringValue(&script);
    code = EntryValidate(entryPtr, p);
    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 (entryPtr->validate == VALIDATE_NONE
	    || (!varValidate && (entryPtr->flags & VALIDATE_VAR))) {
	code = TCL_ERROR;
    }
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
	 * 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) {
	    entryPtr->validate = VALIDATE_NONE;
	} else if (entryPtr->invalidCmd != NULL) {
	    int result;

	    Tcl_DStringInit(&script);
	    ExpandPercents(entryPtr, entryPtr->invalidCmd,
		    change, newValue, index, type, &script);
	    Tcl_DStringAppend(&script, "", 1);
	    p = Tcl_DStringValue(&script);
	    result = Tcl_EvalEx(entryPtr->interp, p, -1,
		    TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(entryPtr->interp,
			"\n    (in invalidcommand executed by entry)");
		Tcl_BackgroundException(entryPtr->interp, result);
		code = TCL_ERROR;
		entryPtr->validate = VALIDATE_NONE;
	    }
	    Tcl_DStringFree(&script);

	    /*
	     * It's possible that the user deleted the entry during







<
<





|
|
<

|
|







3316
3317
3318
3319
3320
3321
3322


3323
3324
3325
3326
3327
3328
3329

3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
	 * 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) {
	    entryPtr->validate = VALIDATE_NONE;
	} else if (entryPtr->invalidCmd != NULL) {


	    Tcl_DStringInit(&script);
	    ExpandPercents(entryPtr, entryPtr->invalidCmd,
		    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)");
		Tcl_BackgroundError(entryPtr->interp);
		code = TCL_ERROR;
		entryPtr->validate = VALIDATE_NONE;
	    }
	    Tcl_DStringFree(&script);

	    /*
	     * It's possible that the user deleted the entry during
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
ExpandPercents(
     Entry *entryPtr,	/* Entry that needs validation. */
     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 */
     TkSizeT 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;
    const char *string;
    int ch;
    char numStorage[2*TCL_INTEGER_SPACE];

    while (1) {
	if (*before == '\0') {
	    break;
	}
	/*







|
|





|







|
|







3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
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;
    Tcl_UniChar ch;
    char numStorage[2*TCL_INTEGER_SPACE];

    while (1) {
	if (*before == '\0') {
	    break;
	}
	/*
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615

	/*
	 * There's a percent sequence here. Process it.
	 */

	before++; /* skip over % */
	if (*before != '\0') {
	    before += TkUtfToUniChar(before, &ch);
	} else {
	    ch = '%';
	}
	if (type == VALIDATE_BUTTON) {
	    /*
	     * -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 = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	} else {
	    /*
	     * -validatecommand / -invalidcommand %-substitution







|



















|







3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451

	/*
	 * There's a percent sequence here. Process it.
	 */

	before++; /* skip over % */
	if (*before != '\0') {
	    before += Tcl_UtfToUniChar(before, &ch);
	} else {
	    ch = '%';
	}
	if (type == VALIDATE_BUTTON) {
	    /*
	     * -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;
	    }
	} else {
	    /*
	     * -validatecommand / -invalidcommand %-substitution
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
		    number = -1;
		    break;
		}
		sprintf(numStorage, "%d", number);
		string = numStorage;
		break;
	    case 'i':		/* index of insert/delete */
		sprintf(numStorage, "%d", (int)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;







|







3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
		    number = -1;
		    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;
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
		    break;
		}
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	}

	spaceNeeded = Tcl_ScanCountedElement(string, -1, &cvtFlags);







|







3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
		    break;
		}
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = Tcl_UniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	}

	spaceNeeded = Tcl_ScanCountedElement(string, -1, &cvtFlags);
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SpinboxObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Spinbox *sbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;







|




|
|



<


|







3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549

3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
    /*
     * 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(sbPtr, 0, sizeof(Spinbox));

    entryPtr->tkwin		= tkwin;
    entryPtr->display		= Tk_Display(tkwin);
    entryPtr->interp		= interp;
    entryPtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd, sbPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_SPINBOX;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= TCL_INDEX_NONE;
    entryPtr->selectLast	= TCL_INDEX_NONE;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;







|







|
|


|


|
|







3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
    /*
     * 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(sbPtr, 0, sizeof(Spinbox));

    entryPtr->tkwin		= tkwin;
    entryPtr->display		= Tk_Display(tkwin);
    entryPtr->interp		= interp;
    entryPtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd,
	    (ClientData) sbPtr, EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_SPINBOX;
    tmp				= (char *) ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= -1;
    entryPtr->selectLast	= -1;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
    sbPtr->curElement		= SEL_NONE;
    sbPtr->bCursor		= NULL;
    sbPtr->repeatDelay		= 400;
    sbPtr->repeatInterval	= 100;
    sbPtr->fromValue		= 0.0;
    sbPtr->toValue		= 100.0;
    sbPtr->increment		= 1.0;
    sbPtr->formatBuf		= (char *)ckalloc(TCL_DOUBLE_SPACE);
    sbPtr->bdRelief		= TK_RELIEF_FLAT;
    sbPtr->buRelief		= TK_RELIEF_FLAT;

    entryPtr->placeholderGC	= NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the spinbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Spinbox");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if (Tk_InitOptions(interp, sbPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







|



<
<





|


|


|

|

|








|


|







3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618


3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
    sbPtr->curElement		= SEL_NONE;
    sbPtr->bCursor		= NULL;
    sbPtr->repeatDelay		= 400;
    sbPtr->repeatInterval	= 100;
    sbPtr->fromValue		= 0.0;
    sbPtr->toValue		= 100.0;
    sbPtr->increment		= 1.0;
    sbPtr->formatBuf		= (char *) ckalloc(TCL_DOUBLE_SPACE);
    sbPtr->bdRelief		= TK_RELIEF_FLAT;
    sbPtr->buRelief		= TK_RELIEF_FLAT;



    /*
     * Keep a hold of the associated tkwin until we destroy the spinbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve((ClientData) entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Spinbox");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, (ClientData) entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, (ClientData) entryPtr, XA_STRING);

    if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
	goto error;
    }

    Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC);
    return TCL_OK;

    error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869

3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882

3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902

3903
3904
3905
3906
3907
3908

3909
3910
3911
3912
3913

3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
static int
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;
    int cmdIndex, selIndex, result;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * Parse the widget command by looking up the second token in the list of
     * valid command names.
     */

    result = Tcl_GetIndexFromObj(interp, objv[1], sbCmdNames,
	    "option", 0, &cmdIndex);
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index + 1 > 1)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);

	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case SB_CMD_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;

    case SB_CMD_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, entryPtr,
		    entryPtr->optionTable, (objc == 3) ? objv[2] : NULL,

		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else {
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &last) != TCL_OK) {
		goto error;
	    }
	}
	if ((last + 1 >= first + 1) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case SB_CMD_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
	break;

    case SB_CMD_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, 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_SetObjResult(interp,
		    Tcl_NewStringObj(selElementNames[elem], -1));
	}
	break;
    }

    case SB_CMD_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	TkSizeT index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if (entryPtr->state == STATE_NORMAL) {
	    code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
            if (code != TCL_OK) {
                goto error;







|
|




|














|


<
|
<
>





|



|


|
>
|
|
<
<
|









|



|
|
>




|
|
>



|
|
>






|
<





|






|




|













|







|



















|
|





|





|



|




|
<





|







3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699

3700

3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717


3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754

3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836

3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
static int
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;
    int cmdIndex, selIndex, result;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    /*
     * Parse the widget command by looking up the second token in the list of
     * valid command names.
     */

    result = Tcl_GetIndexFromObj(interp, objv[1], sbCmdNames,
	    "option", 0, &cmdIndex);
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve((ClientData) entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    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;

    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;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	int first, last, code;


	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)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    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, code;


	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) {
	    code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
            if (code != TCL_OK) {
                goto error;
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
		goto error;
	    }
	}
	break;

    case SB_CMD_SCAN: {
	int x;
	const 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_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be mark or dragto",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	TkSizeT index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*







|


















|
|
<
<
|






|







3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894


3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
		goto error;
	    }
	}
	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;
	}

	/*
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
	switch (selIndex) {
	case SB_SEL_ADJUST:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1) {
		    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, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SB_SEL_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    entryPtr->selectAnchor = index;
	    break;

	case SB_SEL_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    entryPtr->selectFirst != TCL_INDEX_NONE));
	    goto done;

	case SB_SEL_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[4],& index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && entryPtr->exportSelection
		    && (!Tcl_IsSafe(entryPtr->interp))) {
		Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
			EntryLostSelection, entryPtr);
		entryPtr->flags |= GOT_SELECTION;
	    }
	    EventuallyRedraw(entryPtr);
	    break;

	case SB_SEL_TO:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    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_SetObjResult(interp, Tcl_NewStringObj(
			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;







|


|
|



|

|
















|
|
|










|










|
|








|



|


|
|
|





|
<

|











|











|
|







3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013

4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
	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, 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, NULL);
		goto error;
	    }
	    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 (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 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;
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273

4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
	}
	if (objc == 3) {
	    code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(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_XVIEW: {
	TkSizeT index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);

	    span[1] = Tcl_NewDoubleObj(last);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, span));
	    goto done;
	} else if (objc == 3) {
	    if (GetEntryIndex(interp, entryPtr, 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 = ((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;
	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	    index = entryPtr->numChars - 1;
	}
	if (index == TCL_INDEX_NONE) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
    }
    }

  done:
    Tcl_Release(entryPtr);
    return result;

  error:
    Tcl_Release(entryPtr);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetSpinboxElement --







|

















<
|




|



|


|
>
|
|


|













|


















|


|











|



|







4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088

4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
	}
	if (objc == 3) {
	    code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	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_XVIEW: {
	int index;

	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;
	    }
	} 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;
	    }
	}
	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:
    Tcl_Release((ClientData) entryPtr);
    return result;

  error:
    Tcl_Release((ClientData) entryPtr);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetSpinboxElement --
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
 *	The widget value may change.
 *
 *--------------------------------------------------------------
 */

static int
SpinboxInvoke(
    Tcl_Interp *interp,/* Current interpreter. */
    Spinbox *sbPtr,	/* Spinbox to invoke. */
    int element)		/* Element to invoke, either the "up" or
				 * "down" button. */
{
    Entry *entryPtr = (Entry *) sbPtr;
    const char *type;
    int code, up;
    Tcl_DString script;

    switch (element) {
    case SEL_BUTTONUP:
	type = "up";
	up = 1;







|
|




|







4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
 *	The widget value may change.
 *
 *--------------------------------------------------------------
 */

static int
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;
    int code, up;
    Tcl_DString script;

    switch (element) {
    case SEL_BUTTONUP:
	type = "up";
	up = 1;
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
	    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.
		 */

		int i, listc;
		TkSizeT elemLen, length = entryPtr->numChars;
		const char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = TkGetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}
	    }
	    if (up) {
		if (++sbPtr->eIndex >= sbPtr->nElements) {







<
|
|




|


|







4251
4252
4253
4254
4255
4256
4257

4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
	    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.
		 */


		int i, listc, elemLen, length = entryPtr->numChars;
		char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    (size_t) length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}
	    }
	    if (up) {
		if (++sbPtr->eIndex >= sbPtr->nElements) {
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
	Tcl_DStringAppend(&script, "", 1);

	code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), -1,
		TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	Tcl_DStringFree(&script);

	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (in command executed by spinbox)");
	    Tcl_BackgroundException(interp, code);

	    /*
	     * Yes, it's an error, but a bg one, so we return OK
	     */

	    return TCL_OK;
	}

	Tcl_ResetResult(interp);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
<
|








|







4349
4350
4351
4352
4353
4354
4355
4356

4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
	Tcl_DStringAppend(&script, "", 1);

	code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), -1,
		TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	Tcl_DStringFree(&script);

	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;
	}

	Tcl_SetResult(interp, NULL, 0);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------

Changes to generic/tkEntry.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17





18
19
20
21
22
23
24
/*
 *  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.
 *
 * Copyright (c) 2002 Apple Inc.
 */

#ifndef _TKENTRY
#define _TKENTRY

#ifndef _TKINT
#include "tkInt.h"
#endif






enum EntryType {
    TK_ENTRY, TK_SPINBOX
};

/*
 * A data structure of the following type is kept for each Entry widget








|








>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 *  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.
 *
 * Copyright (c) 2002 Apple Computer, Inc.
 */

#ifndef _TKENTRY
#define _TKENTRY

#ifndef _TKINT
#include "tkInt.h"
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

enum EntryType {
    TK_ENTRY, TK_SPINBOX
};

/*
 * A data structure of the following type is kept for each Entry widget
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
				 * available for this widget. */
    enum EntryType type;	/* Specialized type of Entry widget */

    /*
     * Fields that are set by widget commands other than "configure".
     */

    const char *string;		/* Pointer to storage for string;
				 * NULL-terminated; malloc-ed. */
    TkSizeT insertPos;		/* Character index before which next typed
				 * character will be inserted. */

    /*
     * Information about what's selected, if any.
     */

    TkSizeT selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    TkSizeT selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    TkSizeT selectAnchor;		/* Fixed end of selection (i.e. "select to"
				 * operation will use this as one end of the
				 * selection). */

    /*
     * Information for scanning:
     */








|

|






|

|

|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
				 * available for this widget. */
    enum EntryType type;	/* Specialized type of Entry widget */

    /*
     * Fields that are set by widget commands other than "configure".
     */

    CONST char *string;		/* Pointer to storage for string;
				 * NULL-terminated; malloc-ed. */
    int insertPos;		/* Character index before which next typed
				 * character will be inserted. */

    /*
     * Information about what's selected, if any.
     */

    int selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    int selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    int selectAnchor;		/* Fixed end of selection (i.e. "select to"
				 * operation will use this as one end of the
				 * selection). */

    /*
     * Information for scanning:
     */

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
				 * 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. */

    /*
     * Fields used in displaying help text if entry value is empty
     */

    Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */
    char *placeholderString;	/* String value of placeholder. */
    TkSizeT placeholderChars;	/* Number of chars in placeholder. */
    XColor *placeholderColorPtr;/* Color value of placeholder foreground. */
    GC placeholderGC;		/* For drawing placeholder text. */
    int placeholderX;		/* Origin for layout. */
    int placeholderLeftIndex;	/* Character index of left-most character
				 * visible in window. */

    /*
     * 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
				 * malloced memory with the same character
				 * length as string but whose characters are
				 * all equal to showChar. */
    TkSizeT numBytes;		/* Length of string in bytes. */
    TkSizeT 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. */
    TkSizeT numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    TkSizeT leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */







<
<
<
<
<
<
<
<
<
<
<
<
<





|




|
|




|








|







129
130
131
132
133
134
135













136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
				 * 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. */














    /*
     * 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
				 * malloced memory with the same character
				 * 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 numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    int leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */
304
305
306
307
308
309
310



311
 * the Entry widget.
 */

MODULE_SCOPE int	TkpDrawEntryBorderAndFocus(Entry *entryPtr,
			    Drawable d, int isSpinbox);
MODULE_SCOPE int	TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d);




#endif /* _TKENTRY */







>
>
>

296
297
298
299
300
301
302
303
304
305
306
 * the Entry widget.
 */

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

#endif /* _TKENTRY */

Changes to generic/tkError.c.

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
				 * 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. */
{
    TkErrorHandler *errorPtr;
    TkDisplay *dispPtr;

    /*
     * Find the display. If Tk doesn't know about this display then it's an
     * error: panic.
     */

    dispPtr = TkGetDisplay(display);







|
|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
				 * 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. */
{
    register TkErrorHandler *errorPtr;
    register TkDisplay *dispPtr;

    /*
     * Find the display. If Tk doesn't know about this display then it's an
     * error: panic.
     */

    dispPtr = TkGetDisplay(display);
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
	defaultHandler = XSetErrorHandler(ErrorProc);
    }

    /*
     * Create the handler record.
     */

    errorPtr = (TkErrorHandler *)ckalloc(sizeof(TkErrorHandler));
    errorPtr->dispPtr = dispPtr;
    errorPtr->firstRequest = NextRequest(display);
    errorPtr->lastRequest = (unsigned) -1;
    errorPtr->error = error;
    errorPtr->request = request;
    errorPtr->minorCode = minorCode;
    errorPtr->errorProc = errorProc;







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
	defaultHandler = XSetErrorHandler(ErrorProc);
    }

    /*
     * Create the handler record.
     */

    errorPtr = (TkErrorHandler *) ckalloc(sizeof(TkErrorHandler));
    errorPtr->dispPtr = dispPtr;
    errorPtr->firstRequest = NextRequest(display);
    errorPtr->lastRequest = (unsigned) -1;
    errorPtr->error = error;
    errorPtr->request = request;
    errorPtr->minorCode = minorCode;
    errorPtr->errorProc = errorProc;
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
 */

void
Tk_DeleteErrorHandler(
    Tk_ErrorHandler handler)	/* Token for handler to delete; was previous
				 * return value from Tk_CreateErrorHandler. */
{
    TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
    TkDisplay *dispPtr = errorPtr->dispPtr;

    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).
     */


    if (dispPtr->deleteCount++ >= 9) {
	TkErrorHandler *prevPtr;
	TkErrorHandler *nextPtr;
	unsigned long lastSerial = LastKnownRequestProcessed(dispPtr->display);

	/*
	 * Last chance to catch errors for this handler: if no event/error
	 * processing took place to follow up the end of this error handler
	 * we need a round trip with the X server now.
	 */

	if (errorPtr->lastRequest > lastSerial) {
	    XSync(dispPtr->display, False);
	}
	dispPtr->deleteCount = 0;

	errorPtr = dispPtr->errorPtr;
	for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) {
	    nextPtr = errorPtr->nextPtr;
	    if ((errorPtr->lastRequest != (unsigned long) -1)
		    && (errorPtr->lastRequest <= lastSerial)) {
		if (prevPtr == NULL) {
		    dispPtr->errorPtr = nextPtr;
		} else {
		    prevPtr->nextPtr = nextPtr;
		}
		ckfree(errorPtr);
		continue;
	    }
	    prevPtr = errorPtr;
	}
    }
}








|
|















>
|
|

<
<
<
<
<
<
<
<
|
<
|

>




|





|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170








171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 */

void
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;

    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).
     */

    dispPtr->deleteCount += 1;
    if (dispPtr->deleteCount >= 10) {
	register TkErrorHandler *prevPtr;
	TkErrorHandler *nextPtr;








	int lastSerial;


	dispPtr->deleteCount = 0;
	lastSerial = LastKnownRequestProcessed(dispPtr->display);
	errorPtr = dispPtr->errorPtr;
	for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) {
	    nextPtr = errorPtr->nextPtr;
	    if ((errorPtr->lastRequest != (unsigned long) -1)
		    && (errorPtr->lastRequest <= (unsigned long) lastSerial)) {
		if (prevPtr == NULL) {
		    dispPtr->errorPtr = nextPtr;
		} else {
		    prevPtr->nextPtr = nextPtr;
		}
		ckfree((char *) errorPtr);
		continue;
	    }
	    prevPtr = errorPtr;
	}
    }
}

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 *
 *--------------------------------------------------------------
 */

static int
ErrorProc(
    Display *display,		/* Display for which error occurred. */
    XErrorEvent *errEventPtr)
				/* Information about error. */
{
    TkDisplay *dispPtr;
    TkErrorHandler *errorPtr;

    /*
     * See if we know anything about the display. If not, then invoke the
     * default error handler.
     */

    dispPtr = TkGetDisplay(display);







|


|
|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
 *
 *--------------------------------------------------------------
 */

static int
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.
     */

    dispPtr = TkGetDisplay(display);
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
		    && (errorPtr->request != errEventPtr->request_code))
		|| ((errorPtr->minorCode != -1)
		    && (errorPtr->minorCode != errEventPtr->minor_code))
		|| ((errorPtr->lastRequest != (unsigned long) -1)
		    && (errorPtr->lastRequest < errEventPtr->serial))) {
	    continue;
	}
	if (errorPtr->errorProc == NULL ||
		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







|
|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
		    && (errorPtr->request != errEventPtr->request_code))
		|| ((errorPtr->minorCode != -1)
		    && (errorPtr->minorCode != errEventPtr->minor_code))
		|| ((errorPtr->lastRequest != (unsigned long) -1)
		    && (errorPtr->lastRequest < errEventPtr->serial))) {
	    continue;
	}
	if (errorPtr->errorProc == NULL || (*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
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
     * were deleted by the container. Now we are getting the errors
     * (BadWindow) after Tk already deleted the window itself.
     */

    if (errEventPtr->error_code == BadWindow) {
	Window w = (Window) errEventPtr->resourceid;

	if (Tk_IdToWindow(display, w) != NULL) {

	    return 0;
	}
    }

    /*
     * We couldn't handle the error. Use the default handler.
     */

  couldntHandle:
    return defaultHandler(display, errEventPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>









|









265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
     * were deleted by the container. Now we are getting the errors
     * (BadWindow) after Tk already deleted the window itself.
     */

    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.
     */

  couldntHandle:
    return (*defaultHandler)(display, errEventPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkEvent.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * 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.







<
<
<
<
<
<
<
<







11
12
13
14
15
16
17








18
19
20
21
22
23
24
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









/*
 * 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.
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    XEvent event;		/* The X event. */
} TkWindowEvent;

/*
 * Array of event masks corresponding to each X event:
 */

static const unsigned long eventMasks[TK_LASTEVENT] = {
    0,
    0,
    KeyPressMask,			/* KeyPress */
    KeyReleaseMask,			/* KeyRelease */
    ButtonPressMask,			/* ButtonPress */
    ButtonReleaseMask,			/* ButtonRelease */
    PointerMotionMask|PointerMotionHintMask|ButtonMotionMask







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    XEvent event;		/* The X event. */
} TkWindowEvent;

/*
 * Array of event masks corresponding to each X event:
 */

static unsigned long eventMasks[TK_LASTEVENT] = {
    0,
    0,
    KeyPressMask,			/* KeyPress */
    KeyReleaseMask,			/* KeyRelease */
    ButtonPressMask,			/* ButtonPress */
    ButtonReleaseMask,			/* ButtonRelease */
    PointerMotionMask|PointerMotionHintMask|ButtonMotionMask
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

/*
 * 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 {
    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.







|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

/*
 * 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. */

    /*
     * List of generic handler records.
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214

215

216

217
218
219
220
221
222
223

/*
 * Prototypes for functions that are only referenced locally within this file.
 */

static void		CleanUpTkEvent(XEvent *eventPtr);
static void		DelayedMotionProc(ClientData clientData);

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 int		WindowEventProc(Tcl_Event *evPtr, int flags);

static void		CreateXIC(TkWindow *winPtr);


/*
 *----------------------------------------------------------------------
 *
 * InvokeFocusHandlers --
 *
 *	Call focus-related code to look at FocusIn, FocusOut, Enter, and Leave







>














>

>

>







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

/*
 * 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
242
243
244
245
246
247
248
249
250
251

252





253
254
255
256
257
258
259
{
    if ((mask & (FocusChangeMask|EnterWindowMask|LeaveWindowMask))
	    && (TkFocusFilterEvent(*winPtrPtr, eventPtr) == 0)) {
	return 1;
    }

    /*
     * Only key-related events are directed according to the focus.
     */


    if (mask & (KeyPressMask|KeyReleaseMask)) {





	(*winPtrPtr)->dispPtr->lastEventTime = eventPtr->xkey.time;
	*winPtrPtr = TkFocusKeyEvent(*winPtrPtr, eventPtr);
	if (*winPtrPtr == NULL) {
	    return 1;
	}
    }








|


>
|
>
>
>
>
>







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
{
    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;
	}
    }

317
318
319
320
321
322
323

324
325
326
327
328
329
330
 *
 *	Create the X input context for our winPtr.
 *	XIM is only ever enabled on Unix.
 *
 *----------------------------------------------------------------------
 */


static void
CreateXIC(
    TkWindow *winPtr)
{
    TkDisplay *dispPtr = winPtr->dispPtr;
    long im_event_mask = 0L;
    const char *preedit_attname = NULL;







>







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
 *
 *	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;
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
	    preedit_attname, preedit_attlist,
	    NULL);

    if (preedit_attlist) {
	XFree(preedit_attlist);
    }


    if (winPtr->inputContext == NULL) {
	/* XCreateIC failed. */
	return;
    }
    winPtr->ximGeneration = dispPtr->ximGeneration;

    /*
     * 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);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetTkWindowFromXEvent --
 *
 *	Attempt to find which TkWindow is associated with an event. If it







|


|

<
|









>







350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
	    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
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532





533











534




















535



536



537

538



539


540






541


















542
543
544
545
546
547
548
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetButtonMask --
 *
 *	Return the proper Button${n}Mask for the button. Don't care about
 *	Button4 - Button7, because those are not actually buttons: Those
 *	are used for the horizontal or vertical mouse wheels. Button4Mask
 *	and higher is actually used for Button 8 and higher.
 *
 * Results:
 *	A button mask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const unsigned buttonMasks[] = {





    0, Button1Mask, Button2Mask, Button3Mask, 0, 0, 0, 0, Button4Mask, \











	    Button5Mask, Button6Mask, Button7Mask, Button8Mask, Button9Mask




















};







unsigned

Tk_GetButtonMask(



    unsigned button)


{






    return (button > Button9) ? 0 : buttonMasks[button];


















}

/*
 *----------------------------------------------------------------------
 *
 * InvokeClientMessageHandlers --
 *







|

|
<
<
<










|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
|
>
|
>
>
>
|
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







512
513
514
515
516
517
518
519
520
521



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
    }
    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
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 --
 *
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
		    tsdPtr->cmList = tmpPtr;
		} else {
		    prevPtr->nextPtr = tmpPtr;
		}
		if (tmpPtr == NULL) {
		    tsdPtr->lastCmPtr = prevPtr;
		}
		ckfree(curPtr);
		curPtr = tmpPtr;
		continue;
	    }
	} else {
	    int done;

	    tsdPtr->handlersActive++;







|







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
		    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++;
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
		    tsdPtr->genericList = tmpPtr;
		} else {
		    prevPtr->nextPtr = tmpPtr;
		}
		if (tmpPtr == NULL) {
		    tsdPtr->lastGenericPtr = prevPtr;
		}
		ckfree(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;







|







|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
		    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;
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
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. */
{
    TkEventHandler *handlerPtr;
    TkWindow *winPtr = (TkWindow *)token;

    /*
     * 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.
     */

    if (winPtr->handlerList == NULL) {
	/*
	 * No event handlers defined at all, so must create.
	 */

	handlerPtr = (TkEventHandler *)ckalloc(sizeof(TkEventHandler));
	winPtr->handlerList = handlerPtr;
    } else {
	int found = 0;

	for (handlerPtr = winPtr->handlerList; ;
		handlerPtr = handlerPtr->nextPtr) {
	    if ((handlerPtr->proc == proc)







|
|














|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
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;

    /*
     * 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.
     */

    if (winPtr->handlerList == NULL) {
	/*
	 * No event handlers defined at all, so must create.
	 */

	handlerPtr = (TkEventHandler *) ckalloc(sizeof(TkEventHandler));
	winPtr->handlerList = handlerPtr;
    } else {
	int found = 0;

	for (handlerPtr = winPtr->handlerList; ;
		handlerPtr = handlerPtr->nextPtr) {
	    if ((handlerPtr->proc == proc)
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
	    return;
	}

	/*
	 * No event handler matched, so create a new one.
	 */

	handlerPtr->nextPtr = (TkEventHandler *)ckalloc(sizeof(TkEventHandler));

	handlerPtr = handlerPtr->nextPtr;
    }

    /*
     * Initialize the new event handler.
     */








|
>







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
	    return;
	}

	/*
	 * No event handler matched, so create a new one.
	 */

	handlerPtr->nextPtr = (TkEventHandler *)
		ckalloc(sizeof(TkEventHandler));
	handlerPtr = handlerPtr->nextPtr;
    }

    /*
     * Initialize the new event handler.
     */

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
void
Tk_DeleteEventHandler(
    Tk_Window token,		/* Same as corresponding arguments passed */
    unsigned long mask,		/* previously to Tk_CreateEventHandler. */
    Tk_EventProc *proc,
    ClientData clientData)
{
    TkEventHandler *handlerPtr;
    InProgress *ipPtr;
    TkEventHandler *prevPtr;
    TkWindow *winPtr = (TkWindow *) token;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Find the event handler to be deleted, or return immediately if it
     * doesn't exist.
     */







|
|

|







852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
void
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));

    /*
     * Find the event handler to be deleted, or return immediately if it
     * doesn't exist.
     */
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
     */

    if (prevPtr == NULL) {
	winPtr->handlerList = handlerPtr->nextPtr;
    } else {
	prevPtr->nextPtr = handlerPtr->nextPtr;
    }
    ckfree(handlerPtr);

    /*
     * No need to call XSelectInput: Tk always selects on all events for all
     * windows (needed to support bindings on classes and "all").
     */
}








|







895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
     */

    if (prevPtr == NULL) {
	winPtr->handlerList = handlerPtr->nextPtr;
    } else {
	prevPtr->nextPtr = handlerPtr->nextPtr;
    }
    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").
     */
}

858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
    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));

    handlerPtr->proc		= proc;
    handlerPtr->clientData	= clientData;
    handlerPtr->deleteFlag	= 0;
    handlerPtr->nextPtr		= NULL;
    if (tsdPtr->genericList == NULL) {
	tsdPtr->genericList	= handlerPtr;







|







931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
    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));

    handlerPtr->proc		= proc;
    handlerPtr->clientData	= clientData;
    handlerPtr->deleteFlag	= 0;
    handlerPtr->nextPtr		= NULL;
    if (tsdPtr->genericList == NULL) {
	tsdPtr->genericList	= handlerPtr;
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
	    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.
     */

    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;







|







1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
	    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.
     */

    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;
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
 *
 *----------------------------------------------------------------------
 */

static int
TkXErrorHandler(
    ClientData clientData,	/* Pointer to flag we set. */
    TCL_UNUSED(XErrorEvent *))	/* X error info. */
{
    int *error = (int *)clientData;


    *error = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------
 *







|

|

>







1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
 *
 *----------------------------------------------------------------------
 */

static int
TkXErrorHandler(
    ClientData clientData,	/* Pointer to flag we set. */
    XErrorEvent *errEventPtr)	/* X error info. */
{
    int *error;

    error = (int *) clientData;
    *error = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

    /*
     * Handle errors ourselves.
     */

    gotXError = 0;
    handler = Tk_CreateErrorHandler(display, -1, -1, -1,
	    TkXErrorHandler, &gotXError);

    /*
     * Get the parent window.
     */

    status = XQueryTree(display, w, &root, &parent, &childList, &nChildren);








|







1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

    /*
     * Handle errors ourselves.
     */

    gotXError = 0;
    handler = Tk_CreateErrorHandler(display, -1, -1, -1,
	    TkXErrorHandler, (ClientData) (&gotXError));

    /*
     * Get the parent window.
     */

    status = XQueryTree(display, w, &root, &parent, &childList, &nChildren);

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
 *----------------------------------------------------------------------
 */

void
Tk_HandleEvent(
    XEvent *eventPtr)	/* Event to dispatch. */
{
    TkEventHandler *handlerPtr;
    TkWindow *winPtr;
    unsigned long mask;
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


#if !defined(_WIN32) && !defined(MAC_OSX_TK)
    if ((eventPtr->xbutton.button >= Button4) && (eventPtr->xbutton.button < Button8)) {
	if (eventPtr->type == ButtonRelease) {
	    return;
	} else if (eventPtr->type == ButtonPress) {
	    int but = eventPtr->xbutton.button;
	    eventPtr->type = MouseWheelEvent;
	    eventPtr->xany.send_event = -1;
	    eventPtr->xkey.keycode = (but & 1) ? -120 : 120;
	    if (but > Button5) {
		eventPtr->xkey.state ^= ShiftMask;
	    }
	}
    }
#endif

    /*
     * If the generic handler processed this event we are done and can return.
     */

    if (InvokeGenericHandlers(tsdPtr, eventPtr)) {
	goto releaseEventResources;







|







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217















1218
1219
1220
1221
1222
1223
1224
 *----------------------------------------------------------------------
 */

void
Tk_HandleEvent(
    XEvent *eventPtr)	/* Event to dispatch. */
{
    register TkEventHandler *handlerPtr;
    TkWindow *winPtr;
    unsigned long mask;
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    UpdateButtonEventState(eventPtr);
















    /*
     * If the generic handler processed this event we are done and can return.
     */

    if (InvokeGenericHandlers(tsdPtr, eventPtr)) {
	goto releaseEventResources;
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
	/*
	 * 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.
	 */

	Tcl_Preserve(interp);

	result = ((InvokeFocusHandlers(&winPtr, mask, eventPtr))
		|| (InvokeMouseHandlers(winPtr, mask, eventPtr)));

	if (result) {
	    goto releaseInterpreter;
	}
    }

    /*
     * 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.
     */

    /*
     * If the XIC has been invalidated, it must be recreated.
     */
    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
	winPtr->flags &= ~TK_CHECKED_IC;
	winPtr->inputContext = NULL;
    }

    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
	if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
	    winPtr->flags |= TK_CHECKED_IC;
	    if (winPtr->dispPtr->inputMethod != NULL) {
		CreateXIC(winPtr);
	    }
	}
	if ((eventPtr->type == FocusIn) &&
		(winPtr->dispPtr->inputMethod != NULL) &&
		(winPtr->inputContext != NULL)) {
	    XSetICFocus(winPtr->inputContext);
	}
    }


    /*
     * For events where it hasn't already been done, update the current time
     * in the display.
     */

    if (eventPtr->type == PropertyNotify) {







|
















<
<
<
<
<
<
<
|







<
<
|



>







1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284







1285
1286
1287
1288
1289
1290
1291
1292


1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
	/*
	 * 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.
	 */

	Tcl_Preserve((ClientData) interp);

	result = ((InvokeFocusHandlers(&winPtr, mask, eventPtr))
		|| (InvokeMouseHandlers(winPtr, mask, eventPtr)));

	if (result) {
	    goto releaseInterpreter;
	}
    }

    /*
     * 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.
     */








#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 (winPtr->dispPtr->inputMethod != NULL) {
		CreateXIC(winPtr);
	    }
	}


	if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) {
	    XSetICFocus(winPtr->inputContext);
	}
    }
#endif

    /*
     * For events where it hasn't already been done, update the current time
     * in the display.
     */

    if (eventPtr->type == PropertyNotify) {
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
		|| (eventPtr->type == SelectionNotify)) {
	    TkSelEventProc((Tk_Window) winPtr, eventPtr);
	} else if (eventPtr->type == ClientMessage) {
	    if (eventPtr->xclient.message_type ==
		    Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS")) {
		TkWmProtocolEventProc(winPtr, eventPtr);
	    } else {
		InvokeClientMessageHandlers(tsdPtr, (Tk_Window) winPtr,
			eventPtr);
	    }
	}
    } else {
	for (handlerPtr = winPtr->handlerList; handlerPtr != NULL; ) {
	    if (handlerPtr->mask & mask) {
		ip.nextHandler = handlerPtr->nextPtr;
		handlerPtr->proc(handlerPtr->clientData, eventPtr);
		handlerPtr = ip.nextHandler;
	    } else {
		handlerPtr = handlerPtr->nextPtr;
	    }
	}

	/*







|





|

|







1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
		|| (eventPtr->type == SelectionNotify)) {
	    TkSelEventProc((Tk_Window) winPtr, eventPtr);
	} else if (eventPtr->type == ClientMessage) {
	    if (eventPtr->xclient.message_type ==
		    Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS")) {
		TkWmProtocolEventProc(winPtr, eventPtr);
	    } else {
		InvokeClientMessageHandlers(tsdPtr, (Tk_Window)winPtr,
			eventPtr);
	    }
	}
    } else {
	for (handlerPtr = winPtr->handlerList; handlerPtr != NULL; ) {
	    if ((handlerPtr->mask & mask) != 0) {
		ip.nextHandler = handlerPtr->nextPtr;
		(*(handlerPtr->proc))(handlerPtr->clientData, eventPtr);
		handlerPtr = ip.nextHandler;
	    } else {
		handlerPtr = handlerPtr->nextPtr;
	    }
	}

	/*
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
    /*
     * Release the interpreter for this window so that it can be potentially
     * deleted if requested.
     */

  releaseInterpreter:
    if (interp != NULL) {
	Tcl_Release(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.







|







1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
    /*
     * Release the interpreter for this window so that it can be potentially
     * deleted if requested.
     */

  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.
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
 */

void
TkEventDeadWindow(
    TkWindow *winPtr)		/* Information about the window that is being
				 * deleted. */
{
    TkEventHandler *handlerPtr;
    InProgress *ipPtr;
    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).







|
|







1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
 */

void
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));

    /*
     * 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).
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
	    if (ipPtr->nextHandler == handlerPtr) {
		ipPtr->nextHandler = NULL;
	    }
	    if (ipPtr->winPtr == winPtr) {
		ipPtr->winPtr = NULL;
	    }
	}
	ckfree(handlerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkCurrentTime --







|







1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
	    if (ipPtr->nextHandler == handlerPtr) {
		ipPtr->nextHandler = NULL;
	    }
	    if (ipPtr->winPtr == winPtr) {
		ipPtr->winPtr = NULL;
	    }
	}
	ckfree((char *) handlerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkCurrentTime --
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
 *----------------------------------------------------------------------
 */

Time
TkCurrentTime(
    TkDisplay *dispPtr)		/* Display for which the time is desired. */
{
    XEvent *eventPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->pendingPtr == NULL) {
	return dispPtr->lastEventTime;
    }
    eventPtr = tsdPtr->pendingPtr->eventPtr;







|







1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
 *----------------------------------------------------------------------
 */

Time
TkCurrentTime(
    TkDisplay *dispPtr)		/* Display for which the time is desired. */
{
    register XEvent *eventPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->pendingPtr == NULL) {
	return dispPtr->lastEventTime;
    }
    eventPtr = tsdPtr->pendingPtr->eventPtr;
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
    /*
     * 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;
	wevPtr->event = *eventPtr;
	Tcl_QueueEvent(&wevPtr->header, position);
	return;
    }

    if ((dispPtr->delayedMotionPtr != NULL) && (position == TCL_QUEUE_TAIL)) {







|







1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
    /*
     * 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;
	wevPtr->event = *eventPtr;
	Tcl_QueueEvent(&wevPtr->header, position);
	return;
    }

    if ((dispPtr->delayedMotionPtr != NULL) && (position == TCL_QUEUE_TAIL)) {
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
	     * 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.
	     */

	    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, position);
	    dispPtr->delayedMotionPtr = NULL;
	    Tcl_CancelIdleCall(DelayedMotionProc, dispPtr);
	}
    }

    wevPtr = (TkWindowEvent *)ckalloc(sizeof(TkWindowEvent));
    wevPtr->header.proc = WindowEventProc;
    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.
	 */

	if (dispPtr->delayedMotionPtr != NULL) {
	    Tcl_Panic("Tk_QueueWindowEvent found unexpected delayed motion event");
	}
	dispPtr->delayedMotionPtr = wevPtr;
	Tcl_DoWhenIdle(DelayedMotionProc, dispPtr);
    } else {
	Tcl_QueueEvent(&wevPtr->header, position);
    }
}

/*
 *----------------------------------------------------------------------







|



|













|







1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
	     * 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.
	     */

	    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, position);
	    dispPtr->delayedMotionPtr = NULL;
	    Tcl_CancelIdleCall(DelayedMotionProc, (ClientData) dispPtr);
	}
    }

    wevPtr = (TkWindowEvent *) ckalloc(sizeof(TkWindowEvent));
    wevPtr->header.proc = WindowEventProc;
    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.
	 */

	if (dispPtr->delayedMotionPtr != NULL) {
	    Tcl_Panic("Tk_QueueWindowEvent found unexpected delayed motion event");
	}
	dispPtr->delayedMotionPtr = wevPtr;
	Tcl_DoWhenIdle(DelayedMotionProc, (ClientData) dispPtr);
    } else {
	Tcl_QueueEvent(&wevPtr->header, position);
    }
}

/*
 *----------------------------------------------------------------------
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
	childPtr = childPtr->nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates X events.
 *
 *----------------------------------------------------------------------
 */

void
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.
     */

    event.xany.serial = NextRequest(winPtr->display);
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xany.window = winPtr->window;

    event.xany.type = active ? ActivateNotify : DeactivateNotify;
    TkQueueEventForAllChildren(winPtr, &event);
}

/*
 *----------------------------------------------------------------------
 *
 * WindowEventProc --
 *
 *	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:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1692
1693
1694
1695
1696
1697
1698









































1699
1700
1701
1702
1703
1704
1705
	childPtr = childPtr->nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *









































 * WindowEventProc --
 *
 *	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:
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return 0;
    }
    if (tsdPtr->restrictProc != NULL) {
	result = tsdPtr->restrictProc(tsdPtr->restrictArg, &wevPtr->event);
	if (result != TK_PROCESS_EVENT) {
	    if (result == TK_DEFER_EVENT) {
		return 0;
	    } else {
		/*
		 * TK_DELETE_EVENT: return and say we processed the event,
		 * even though we didn't do anything at all.







|







1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return 0;
    }
    if (tsdPtr->restrictProc != NULL) {
	result = (*tsdPtr->restrictProc)(tsdPtr->restrictArg, &wevPtr->event);
	if (result != TK_PROCESS_EVENT) {
	    if (result == TK_DEFER_EVENT) {
		return 0;
	    } else {
		/*
		 * TK_DELETE_EVENT: return and say we processed the event,
		 * even though we didn't do anything at all.
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
static void
CleanUpTkEvent(
    XEvent *eventPtr)
{
    switch (eventPtr->type) {
    case KeyPress:
    case KeyRelease: {

#if !defined(_WIN32) && !defined(MAC_OSX_TK)
	TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

	if (kePtr->charValuePtr != NULL) {
	    ckfree(kePtr->charValuePtr);
	    kePtr->charValuePtr = NULL;
	    kePtr->charValueLen = 0;
	}
#endif
	break;
    }

    case VirtualEvent: {
	XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;

	if (vePtr->user_data != NULL) {







<
<

>





<







1772
1773
1774
1775
1776
1777
1778


1779
1780
1781
1782
1783
1784
1785

1786
1787
1788
1789
1790
1791
1792
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) {
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
 */

static void
DelayedMotionProc(
    ClientData clientData)	/* Pointer to display containing a delayed
				 * motion event to be serviced. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;

    if (dispPtr->delayedMotionPtr == NULL) {
	Tcl_Panic("DelayedMotionProc found no delayed mouse motion event");
    }
    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, TCL_QUEUE_TAIL);
    dispPtr->delayedMotionPtr = NULL;
}







|







1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
 */

static void
DelayedMotionProc(
    ClientData clientData)	/* Pointer to display containing a delayed
				 * motion event to be serviced. */
{
    TkDisplay *dispPtr = (TkDisplay *) clientData;

    if (dispPtr->delayedMotionPtr == NULL) {
	Tcl_Panic("DelayedMotionProc found no delayed mouse motion event");
    }
    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, TCL_QUEUE_TAIL);
    dispPtr->delayedMotionPtr = NULL;
}
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
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.







|







1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
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.
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }
	    ckfree(exitPtr);
	    break;
	}
    }
    Tcl_MutexUnlock(&exitMutex);
    return;
}








|







1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
	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;
}

1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
    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().
     */








|







1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
    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().
     */

1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		tsdPtr->firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }
	    ckfree(exitPtr);
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------







|







1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		tsdPtr->firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }
	    ckfree((char *) exitPtr);
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkFinalize(
    TCL_UNUSED(void *))	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

#if defined(_WIN32) && !defined(STATIC_BUILD)
    if (!tclStubsPtr) {
	return;
    }







|







2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkFinalize(
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

#if defined(_WIN32) && !defined(STATIC_BUILD)
    if (!tclStubsPtr) {
	return;
    }
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
	 * 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(exitPtr);
	Tcl_MutexLock(&exitMutex);
    }
    firstExitPtr = NULL;
    Tcl_MutexUnlock(&exitMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * TkFinalizeThread --
 *
 *	Runs our private thread exit handlers and removes itself from Tcl.
 *	This is beneficial 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(
    TCL_UNUSED(void *))	/* 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(exitPtr);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *







|
|












|















|



















|
|







2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
	 * 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);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkFileFilter.c.

9
10
11
12
13
14
15
16
17
18



19
20
21
22
23
24
25
26
 * 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(Tcl_Interp *interp, FileFilter *filterPtr,
			    Tcl_Obj *patternsObj, Tcl_Obj *ostypesObj,
			    int isWindows);



static FileFilter *	GetFilter(FileFilterList *flistPtr, const char *name);

/*
 *----------------------------------------------------------------------
 *
 * TkInitFileFilters --
 *
 *	Initializes a FileFilterList data structure. A FileFilterList must be







|
|
|
>
>
>
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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(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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    int isWindows)		/* True if we are running on Windows. */
{
    int listObjc;
    Tcl_Obj ** listObjv = NULL;
    int i;

    if (types == NULL) {
	return TCL_OK;
    }

    if (Tcl_ListObjGetElements(interp, types, &listObjc,
	    &listObjv) != TCL_OK) {
	return TCL_ERROR;
    }
    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.
     */

    TkFreeFileFilters(flistPtr);

    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.
	 */

	int count;
	FileFilter *filterPtr;
	Tcl_Obj **typeInfo;

	if (Tcl_ListObjGetElements(interp, listObjv[i], &count,
		&typeInfo) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (count != 2 && count != 3) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad file type \"%s\", should be "
		    "\"typeName {extension ?extensions ...?} "
		    "?{macType ?macTypes ...?}?\"",
		    Tcl_GetString(listObjv[i])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "FILE_TYPE", NULL);
	    return TCL_ERROR;
	}

	filterPtr = GetFilter(flistPtr, Tcl_GetString(typeInfo[0]));

	if (AddClause(interp, filterPtr, typeInfo[1],
		(count==2 ? NULL : typeInfo[2]), isWindows) != TCL_OK) {







|















<



















|
|
|
|
<
<







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128


129
130
131
132
133
134
135
    int isWindows)		/* True if we are running on Windows. */
{
    int listObjc;
    Tcl_Obj ** listObjv = NULL;
    int i;

    if (types == NULL) {
        return TCL_OK;
    }

    if (Tcl_ListObjGetElements(interp, types, &listObjc,
	    &listObjv) != TCL_OK) {
	return TCL_ERROR;
    }
    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.
     */

    TkFreeFileFilters(flistPtr);

    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.
	 */

	int count;
	FileFilter *filterPtr;
	Tcl_Obj **typeInfo;

	if (Tcl_ListObjGetElements(interp, listObjv[i], &count,
		&typeInfo) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (count != 2 && count != 3) {
	    Tcl_AppendResult(interp, "bad file type \"",
		    Tcl_GetString(listObjv[i]), "\", ",
		    "should be \"typeName {extension ?extensions ...?} ",
		    "?{macType ?macTypes ...?}?\"", NULL);


	    return TCL_ERROR;
	}

	filterPtr = GetFilter(flistPtr, Tcl_GetString(typeInfo[0]));

	if (AddClause(interp, filterPtr, typeInfo[1],
		(count==2 ? NULL : typeInfo[2]), isWindows) != TCL_OK) {
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203


204
205
206
207
208
209
210
 *----------------------------------------------------------------------
 */

void
TkFreeFileFilters(
    FileFilterList *flistPtr)	/* List of file filters to free */
{
    FileFilter *filterPtr;
    FileFilterClause *clausePtr;
    GlobPattern *globPtr;
    MacFileType *mfPtr;
    void *toFree;	/* A pointer that we are about to free. */

    for (filterPtr = flistPtr->filters; filterPtr != NULL; ) {
	for (clausePtr = filterPtr->clauses; clausePtr != NULL; ) {
	    /*
	     * Squelch each of the glob patterns.
	     */

	    for (globPtr = clausePtr->patterns; globPtr != NULL; ) {
		ckfree(globPtr->pattern);
		toFree = globPtr;
		globPtr = globPtr->next;
		ckfree(toFree);
	    }

	    /*
	     * Squelch each of the Mac file type codes.
	     */

	    for (mfPtr = clausePtr->macTypes; mfPtr != NULL; ) {
		toFree = mfPtr;
		mfPtr = mfPtr->next;
		ckfree(toFree);
	    }
	    toFree = clausePtr;
	    clausePtr = clausePtr->next;
	    ckfree(toFree);
	}

	/*
	 * Squelch the name of the filter and the overall structure.
	 */

	ckfree(filterPtr->name);
	toFree = filterPtr;
	filterPtr = filterPtr->next;
	ckfree(toFree);


    }
    flistPtr->filters = NULL;
}

/*
 *----------------------------------------------------------------------
 *







|
<
<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


|
>
>







156
157
158
159
160
161
162
163




164
165






























166
167
168
169
170
171
172
173
174
175
176
177
178
 *----------------------------------------------------------------------
 */

void
TkFreeFileFilters(
    FileFilterList *flistPtr)	/* List of file filters to free */
{
    FileFilter *filterPtr, *toFree;





    filterPtr=flistPtr->filters;






























    while (filterPtr != NULL) {
	toFree = filterPtr;
	filterPtr = filterPtr->next;
	FreeClauses(toFree);
	ckfree((char*)toFree->name);
	ckfree((char*)toFree);
    }
    flistPtr->filters = NULL;
}

/*
 *----------------------------------------------------------------------
 *
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	/*
	 * 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++) {
	    TkSizeT len;
	    const char *strType = TkGetStringFromObj(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).







|
|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	/*
	 * 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++) {
	    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).
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
		 */

		Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
		len = Tcl_DStringLength(&osTypeDS);
		Tcl_DStringFree(&osTypeDS);
	    }
	    if (len != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad Macintosh file type \"%s\"",
			Tcl_GetString(ostypeList[i])));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "MAC_TYPE", NULL);
		code = TCL_ERROR;
		goto done;
	    }
	}
    }

    /*
     * Add the clause into the list of clauses
     */

    clausePtr = (FileFilterClause *)ckalloc(sizeof(FileFilterClause));
    clausePtr->patterns = NULL;
    clausePtr->patternsTail = NULL;
    clausePtr->macTypes = NULL;
    clausePtr->macTypesTail = NULL;

    if (filterPtr->clauses == NULL) {
	filterPtr->clauses = filterPtr->clausesTail = clausePtr;
    } else {
	filterPtr->clausesTail->next = clausePtr;
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = (GlobPattern *)ckalloc(sizeof(GlobPattern));
	    TkSizeT len;
	    const char *str = TkGetStringFromObj(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(len + 1);
		globPtr->pattern[0] = '*';
		strcpy(globPtr->pattern+1, str);
	    } else if (isWindows) {
		if (strcmp(str, "*") == 0) {
		    globPtr->pattern = (char *)ckalloc(4);
		    strcpy(globPtr->pattern, "*.*");
		} else if (strcmp(str, "") == 0) {
		    /*
		     * An empty string means "match all files with no
		     * extensions"
		     * TODO: "*." actually matches with all files on Win95
		     */

		    globPtr->pattern = (char *)ckalloc(3);
		    strcpy(globPtr->pattern, "*.");
		} else {
		    globPtr->pattern = (char *)ckalloc(len);
		    strcpy(globPtr->pattern, str);
		}
	    } else {
		globPtr->pattern = (char *)ckalloc(len);
		strcpy(globPtr->pattern, str);
	    }

	    /*
	     * Add the glob pattern into the list of patterns.
	     */








<
|
|
<










|
|

|












|
|
<

>

>





|




|





|


|


|



|







255
256
257
258
259
260
261

262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
		 */

		Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
		len = Tcl_DStringLength(&osTypeDS);
		Tcl_DStringFree(&osTypeDS);
	    }
	    if (len != 4) {

		Tcl_AppendResult(interp, "bad Macintosh file type \"",
			Tcl_GetString(ostypeList[i]), "\"", NULL);

		code = TCL_ERROR;
		goto done;
	    }
	}
    }

    /*
     * Add the clause into the list of clauses
     */

    clausePtr = (FileFilterClause*)ckalloc(sizeof(FileFilterClause));
    clausePtr->patterns     = NULL;
    clausePtr->patternsTail = NULL;
    clausePtr->macTypes     = NULL;
    clausePtr->macTypesTail = NULL;

    if (filterPtr->clauses == NULL) {
	filterPtr->clauses = filterPtr->clausesTail = clausePtr;
    } else {
	filterPtr->clausesTail->next = clausePtr;
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = (GlobPattern*)ckalloc(sizeof(GlobPattern));
	    int len;


	    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, str);
	    } else if (isWindows) {
		if (strcmp(str, "*") == 0) {
		    globPtr->pattern = (char*)ckalloc(4 * sizeof(char));
		    strcpy(globPtr->pattern, "*.*");
		} 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));
		    strcpy(globPtr->pattern, "*.");
		} else {
		    globPtr->pattern = (char *) ckalloc((unsigned int) len);
		    strcpy(globPtr->pattern, str);
		}
	    } else {
		globPtr->pattern = (char *) ckalloc((unsigned int) len);
		strcpy(globPtr->pattern, str);
	    }

	    /*
	     * Add the glob pattern into the list of patterns.
	     */

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    }
    if (ostypeList != NULL && ostypeCount > 0) {
	if (macRoman == NULL) {
	    macRoman = Tcl_GetEncoding(NULL, "macRoman");
	}
	for (i=0; i<ostypeCount; i++) {
	    Tcl_DString osTypeDS;
	    TkSizeT len;
	    MacFileType *mfPtr = (MacFileType *)ckalloc(sizeof(MacFileType));
	    const char *strType = TkGetStringFromObj(ostypeList[i], &len);
	    char *string;

	    /*
	     * Convert utf to macRoman, since MacOS types are defined to be 4
	     * macRoman characters long
	     */








|
|
|







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    }
    if (ostypeList != NULL && ostypeCount > 0) {
	if (macRoman == NULL) {
	    macRoman = Tcl_GetEncoding(NULL, "macRoman");
	}
	for (i=0; i<ostypeCount; 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
	     */

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

































































































468
469
470
471
472
473
 *----------------------------------------------------------------------
 */

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 = flistPtr->filters;
    size_t len;

    for (; filterPtr; filterPtr=filterPtr->next) {
	if (strcmp(filterPtr->name, name) == 0) {
	    return filterPtr;
	}
    }

    filterPtr = (FileFilter *)ckalloc(sizeof(FileFilter));
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;
    len = strlen(name) + 1;
    filterPtr->name = (char *)ckalloc(len);
    memcpy(filterPtr->name, name, len);

    if (flistPtr->filters == NULL) {
	flistPtr->filters = flistPtr->filtersTail = filterPtr;
    } else {
	flistPtr->filtersTail->next = filterPtr;
	flistPtr->filtersTail = filterPtr;
    }
    filterPtr->next = NULL;

    ++flistPtr->numFilters;
    return filterPtr;
}

/*

































































































 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




<







|


<
|
|














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
 *----------------------------------------------------------------------
 */

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 = flistPtr->filters;


    for (; filterPtr; filterPtr=filterPtr->next) {
	if (strcmp(filterPtr->name, name) == 0) {
	    return filterPtr;
	}
    }

    filterPtr = (FileFilter *) ckalloc(sizeof(FileFilter));
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;

    filterPtr->name = (char *) ckalloc((strlen(name)+1) * sizeof(char));
    strcpy(filterPtr->name, name);

    if (flistPtr->filters == NULL) {
	flistPtr->filters = flistPtr->filtersTail = filterPtr;
    } else {
	flistPtr->filtersTail->next = filterPtr;
	flistPtr->filtersTail = filterPtr;
    }
    filterPtr->next = NULL;

    ++flistPtr->numFilters;
    return filterPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeClauses --
 *
 *	Frees the malloc'ed file type clause
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The list of clauses in filterPtr->clauses are freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeClauses(
    FileFilter *filterPtr)	/* FileFilter whose clauses are to be freed */
{
    FileFilterClause *clausePtr = filterPtr->clauses;

    while (clausePtr != NULL) {
	FileFilterClause *toFree = clausePtr;
	clausePtr = clausePtr->next;

	FreeGlobPatterns(toFree);
	FreeMacFileTypes(toFree);
	ckfree((char *) toFree);
    }
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeGlobPatterns --
 *
 *	Frees the malloc'ed glob patterns in a clause
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The list of glob patterns in clausePtr->patterns are freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeGlobPatterns(
    FileFilterClause *clausePtr)/* The clause whose patterns are to be freed*/
{
    GlobPattern *globPtr = clausePtr->patterns;

    while (globPtr != NULL) {
	GlobPattern *toFree = globPtr;
	globPtr = globPtr->next;

	ckfree((char *) toFree->pattern);
	ckfree((char *) toFree);
    }
    clausePtr->patterns = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeMacFileTypes --
 *
 *	Frees the malloc'ed Mac file types in a clause
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The list of Mac file types in clausePtr->macTypes are freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeMacFileTypes(
    FileFilterClause *clausePtr)/* The clause whose mac types are to be
				 * freed */
{
    MacFileType *mfPtr = clausePtr->macTypes;

    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:
 */

Changes to generic/tkFileFilter.h.

9
10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
 * 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
#define _TK_FILE_FILTER

#ifdef __cplusplus
extern "C" {



#endif

#define OSType long

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 "*.*" */
} GlobPattern;







|
|
>
>
>

<
<







9
10
11
12
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
 * 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
#define _TK_FILE_FILTER

#define OSType long

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#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 "*.*" */
} GlobPattern;
75
76
77
78
79
80
81
82
83

84
85
86

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);

#ifdef __cplusplus
}

#endif

#endif	/* _TK_FILE_FILTER */







|
<
>

<
<
76
77
78
79
80
81
82
83

84
85



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


Changes to generic/tkFocus.c.

63
64
65
66
67
68
69








70
71
72
73
74
75
76
				 * 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. */
} DisplayFocusInfo;









/*
 * Debugging support...
 */

#define DEBUG(dispPtr, arguments) \
    if ((dispPtr)->focusDebug) { \
	printf arguments; \







>
>
>
>
>
>
>
>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
				 * 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. */
} 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.
 */

#define GENERATED_EVENT_MAGIC	((Bool) 0x547321ac)

/*
 * Debugging support...
 */

#define DEBUG(dispPtr, arguments) \
    if ((dispPtr)->focusDebug) { \
	printf arguments; \
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 */

int
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 *const focusOptions[] = {
	"-displayof", "-force", "-lastfor", NULL
    };
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *newPtr, *topLevelPtr;
    ToplevelFocusInfo *tlFocusPtr;
    const char *windowName;
    int index;

    /*
     * If invoked with no arguments, just return the current focus window.
     */

    if (objc == 1) {
	Tk_Window focusWin = (Tk_Window) TkGetFocusWin(winPtr);

	if (focusWin != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(focusWin));
	}
	return TCL_OK;
    }

    /*
     * If invoked with a single argument beginning with "." then focus on that
     * window.







|

|


|
|
|

|







|
<
|
|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
 */

int
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", NULL
    };
    Tk_Window tkwin = (Tk_Window) clientData;
    TkWindow *winPtr = (TkWindow *) clientData;
    TkWindow *newPtr, *focusWinPtr, *topLevelPtr;
    ToplevelFocusInfo *tlFocusPtr;
    char *windowName;
    int index;

    /*
     * If invoked with no arguments, just return the current focus window.
     */

    if (objc == 1) {
	focusWinPtr = TkGetFocusWin(winPtr);

	if (focusWinPtr != NULL) {
	    Tcl_SetResult(interp, focusWinPtr->pathName, TCL_STATIC);
	}
	return TCL_OK;
    }

    /*
     * If invoked with a single argument beginning with "." then focus on that
     * window.
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	}
    }

    /*
     * We have a subcommand to parse and act upon.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], focusOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
    	return TCL_ERROR;
    }
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    switch (index) {
    case 0:			/* -displayof */
	windowName = Tcl_GetString(objv[2]);
	newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin);
	if (newPtr == NULL) {
	    return TCL_ERROR;
	}
	newPtr = TkGetFocusWin(newPtr);
	if (newPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) newPtr));
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.







|
|















|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	}
    }

    /*
     * We have a subcommand to parse and act upon.
     */

    if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0,
	    &index) != TCL_OK) {
    	return TCL_ERROR;
    }
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    switch (index) {
    case 0:			/* -displayof */
	windowName = Tcl_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);
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    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 (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
		    tlFocusPtr = tlFocusPtr->nextPtr) {
		if (tlFocusPtr->topLevelPtr == topLevelPtr) {
		    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			    tlFocusPtr->focusWinPtr));
		    return TCL_OK;
		}
	    }
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) topLevelPtr));
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;







|






|
|



|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    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 (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
		    tlFocusPtr = tlFocusPtr->nextPtr) {
		if (tlFocusPtr->topLevelPtr == topLevelPtr) {
		    Tcl_SetResult(interp,
			    tlFocusPtr->focusWinPtr->pathName, TCL_STATIC);
		    return TCL_OK;
		}
	    }
	    Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC);
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
    int retValue, delta;

    /*
     * 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_FOCUS_EVENT_MAGIC) == GENERATED_FOCUS_EVENT_MAGIC) {
	eventPtr->xfocus.send_event &= ~GENERATED_FOCUS_EVENT_MAGIC;
	return 1;
    }

    /*
     * 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:







|
|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    int retValue, delta;

    /*
     * 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) {
	eventPtr->xfocus.send_event = 0;
	return 1;
    }

    /*
     * 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:
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    }

    /*
     * 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) {
	return retValue;
    }

    /*
     * 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







|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    }

    /*
     * 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)  {
	return retValue;
    }

    /*
     * 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
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
    for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
	    tlFocusPtr = tlFocusPtr->nextPtr) {
	if (tlFocusPtr->topLevelPtr == winPtr) {
	    break;
	}
    }
    if (tlFocusPtr == NULL) {
	tlFocusPtr = (ToplevelFocusInfo *)ckalloc(sizeof(ToplevelFocusInfo));
	tlFocusPtr->topLevelPtr = tlFocusPtr->focusWinPtr = winPtr;
	tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr;
	winPtr->mainPtr->tlFocusPtr = tlFocusPtr;
    }
    newFocusPtr = tlFocusPtr->focusWinPtr;

    /*







|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
	    tlFocusPtr = tlFocusPtr->nextPtr) {
	if (tlFocusPtr->topLevelPtr == winPtr) {
	    break;
	}
    }
    if (tlFocusPtr == NULL) {
	tlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo));
	tlFocusPtr->topLevelPtr = tlFocusPtr->focusWinPtr = winPtr;
	tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr;
	winPtr->mainPtr->tlFocusPtr = tlFocusPtr;
    }
    newFocusPtr = tlFocusPtr->focusWinPtr;

    /*
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
	    displayFocusPtr->focusWinPtr = newFocusPtr;
	    dispPtr->implicitWinPtr = winPtr;
	    dispPtr->focusPtr = newFocusPtr;
	}
    } else if (eventPtr->type == LeaveNotify) {
	/*
	 * 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:
	 * 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 because
	 * the window manager won't give us a FocusOut event when we focus on
	 * the root.
	 */

	if ((dispPtr->implicitWinPtr != NULL)
		&& !(winPtr->flags & TK_EMBEDDED)) {
	    DEBUG(dispPtr, ("Defocussed implicit Async\n"));
	    GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
	    XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,







|
|

|
|
|
|
|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
	    displayFocusPtr->focusWinPtr = newFocusPtr;
	    dispPtr->implicitWinPtr = winPtr;
	    dispPtr->focusPtr = newFocusPtr;
	}
    } else if (eventPtr->type == LeaveNotify) {
	/*
	 * 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:
	 * 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
	 * because the window manager won't give us a FocusOut event when
	 * we focus on the root.
	 */

	if ((dispPtr->implicitWinPtr != NULL)
		&& !(winPtr->flags & TK_EMBEDDED)) {
	    DEBUG(dispPtr, ("Defocussed implicit Async\n"));
	    GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
	    XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644
645

646
647

648
649
650
651
652
653
654
655
656
657
658
659
660

661

662

663
664
665
666
667
668
669
     * Don't set focus if window is already dead. [Bug 3574708]
     */

    if (winPtr->flags & TK_ALREADY_DEAD) {
	return;
    }

    /*
     * Get the current focus window with the same display and application
     * as winPtr.
     */

    displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);

    /*
     * Do nothing if the window already has focus and force is not set.  If
     * force is set, we need to grab the focus, since under Windows or macOS

     * this may involve taking control away from another application.
     */

    if (winPtr == displayFocusPtr->focusWinPtr && !force) {
	return;
    }

    /*
     * Find the toplevel window for winPtr, then find (or create) a record
     * for the toplevel. 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.
	     */

	    return;
	}
	if (!(topLevelPtr->flags & TK_MAPPED)) {
	    allMapped = 0;
	}
	if (topLevelPtr->flags & TK_TOP_HIERARCHY) {
	    break;
	}
    }

    /*
     * If any ancestor of the new focus window isn't mapped, then we can't set
     * focus for 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) {

	Tk_DeleteEventHandler((Tk_Window) displayFocusPtr->focusOnMapPtr,
		VisibilityChangeMask, FocusMapProc,
		displayFocusPtr->focusOnMapPtr);
	displayFocusPtr->focusOnMapPtr = NULL;
    }
    if (!allMapped) {
	Tk_CreateEventHandler((Tk_Window) winPtr, VisibilityChangeMask,
		FocusMapProc, winPtr);

	displayFocusPtr->focusOnMapPtr = winPtr;
	displayFocusPtr->forceFocus = force;
	return;
    }

    for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
	    tlFocusPtr = tlFocusPtr->nextPtr) {
	if (tlFocusPtr->topLevelPtr == topLevelPtr) {
	    break;
	}
    }
    if (tlFocusPtr == NULL) {
	tlFocusPtr = (ToplevelFocusInfo *)ckalloc(sizeof(ToplevelFocusInfo));
	tlFocusPtr->topLevelPtr = topLevelPtr;
	tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr;
	winPtr->mainPtr->tlFocusPtr = tlFocusPtr;
    }
    tlFocusPtr->focusWinPtr = winPtr;

    if (topLevelPtr->flags & TK_EMBEDDED &&
        (displayFocusPtr->focusWinPtr == NULL)) {

	/*
	 * We are assigning focus to an embedded toplevel.  The platform

	 * specific function TkpClaimFocus needs to handle the job of
	 * assigning focus to the container, since we have no way to find the
	 * contaiuner.
	 */

	TkpClaimFocus(topLevelPtr, force);
    } else if ((displayFocusPtr->focusWinPtr != NULL) || force) {

	/*

	 * If we are forcing removal of focus from a container hosting a
	 * toplevel from a different application, clear the focus in that

	 * application.
	 */

    	if (force) {
	    TkWindow *focusPtr = winPtr->dispPtr->focusPtr;
	    if (focusPtr && focusPtr->mainPtr != winPtr->mainPtr) {
		DisplayFocusInfo *displayFocusPtr2 = FindDisplayFocusInfo(
		    focusPtr->mainPtr, focusPtr->dispPtr);
		displayFocusPtr2->focusWinPtr = NULL;
	    }
    	}

	/*

	 * Call the platform specific function TkpChangeFocus to move the

	 * window manager's focus to a new toplevel.

	 */

	serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force);
	if (serial != 0) {
	    displayFocusPtr->focusSerial = serial;
	}
	GenerateFocusEvents(displayFocusPtr->focusWinPtr, winPtr);







<
<
<
<
<



<
|
>
|







|
|




|

<
















|
|
|
|
|



>
|
|
|



|
|
>












|






<
<
<
|
<
>
|
<
<
<
|
<
<
|
<
>
|
|
>
|
|

|
<
<
|
|
<
<
<
|

>
|
>
|
>







554
555
556
557
558
559
560





561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634



635

636
637



638


639

640
641
642
643
644
645
646
647


648
649



650
651
652
653
654
655
656
657
658
659
660
661
662
663
     * 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 (winPtr == displayFocusPtr->focusWinPtr && !force) {
	return;
    }

    /*
     * 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.
	     */

	    return;
	}
	if (!(topLevelPtr->flags & TK_MAPPED)) {
	    allMapped = 0;
	}
	if (topLevelPtr->flags & TK_TOP_HIERARCHY) {
	    break;
	}
    }

    /*
     * 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) {
	Tk_DeleteEventHandler(
		(Tk_Window) displayFocusPtr->focusOnMapPtr,
		StructureNotifyMask, FocusMapProc,
		(ClientData) displayFocusPtr->focusOnMapPtr);
	displayFocusPtr->focusOnMapPtr = NULL;
    }
    if (!allMapped) {
	Tk_CreateEventHandler((Tk_Window) winPtr,
		VisibilityChangeMask, FocusMapProc,
		(ClientData) winPtr);
	displayFocusPtr->focusOnMapPtr = winPtr;
	displayFocusPtr->forceFocus = force;
	return;
    }

    for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
	    tlFocusPtr = tlFocusPtr->nextPtr) {
	if (tlFocusPtr->topLevelPtr == topLevelPtr) {
	    break;
	}
    }
    if (tlFocusPtr == NULL) {
	tlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo));
	tlFocusPtr->topLevelPtr = topLevelPtr;
	tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr;
	winPtr->mainPtr->tlFocusPtr = tlFocusPtr;
    }
    tlFocusPtr->focusWinPtr = winPtr;




    /*

     * 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.
     */

    if ((topLevelPtr->flags & TK_EMBEDDED)


	    && (displayFocusPtr->focusWinPtr == NULL)) {
	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.
	 */

	serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force);
	if (serial != 0) {
	    displayFocusPtr->focusSerial = serial;
	}
	GenerateFocusEvents(displayFocusPtr->focusWinPtr, winPtr);
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
 *	Various things get cleaned up and recycled.
 *
 *----------------------------------------------------------------------
 */

void
TkFocusDeadWindow(
    TkWindow *winPtr)	/* Information about the window that is being
				 * deleted. */
{
    ToplevelFocusInfo *tlFocusPtr, *prevPtr;
    DisplayFocusInfo *displayFocusPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;

    /*







|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
 *	Various things get cleaned up and recycled.
 *
 *----------------------------------------------------------------------
 */

void
TkFocusDeadWindow(
    register TkWindow *winPtr)	/* Information about the window that is being
				 * deleted. */
{
    ToplevelFocusInfo *tlFocusPtr, *prevPtr;
    DisplayFocusInfo *displayFocusPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;

    /*
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
		dispPtr->focusPtr = NULL;
	    }
	    if (prevPtr == NULL) {
		winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = tlFocusPtr->nextPtr;
	    }
	    ckfree(tlFocusPtr);
	    break;
	} else if (winPtr == tlFocusPtr->focusWinPtr) {
	    /*
	     * The deleted window had the focus for its top-level: move the
	     * focus to the top-level itself.
	     */








|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
		dispPtr->focusPtr = NULL;
	    }
	    if (prevPtr == NULL) {
		winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = tlFocusPtr->nextPtr;
	    }
	    ckfree((char *) tlFocusPtr);
	    break;
	} else if (winPtr == tlFocusPtr->focusWinPtr) {
	    /*
	     * The deleted window had the focus for its top-level: move the
	     * focus to the top-level itself.
	     */

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
	winPtr = destPtr;
	if (winPtr == NULL) {
	    return;
	}
    }

    event.xfocus.serial = LastKnownRequestProcessed(winPtr->display);
    event.xfocus.send_event = GENERATED_FOCUS_EVENT_MAGIC;
    event.xfocus.display = winPtr->display;
    event.xfocus.mode = NotifyNormal;
    TkInOutEvents(&event, sourcePtr, destPtr, FocusOut, FocusIn,
	    TCL_QUEUE_MARK);
}

/*







|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
	winPtr = destPtr;
	if (winPtr == NULL) {
	    return;
	}
    }

    event.xfocus.serial = LastKnownRequestProcessed(winPtr->display);
    event.xfocus.send_event = GENERATED_EVENT_MAGIC;
    event.xfocus.display = winPtr->display;
    event.xfocus.mode = NotifyNormal;
    TkInOutEvents(&event, sourcePtr, destPtr, FocusOut, FocusIn,
	    TCL_QUEUE_MARK);
}

/*
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
 */

static void
FocusMapProc(
    ClientData clientData,	/* Toplevel window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    DisplayFocusInfo *displayFocusPtr;

    if (eventPtr->type == VisibilityNotify) {
	displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr,
		winPtr->dispPtr);
	DEBUG(winPtr->dispPtr, ("auto-focussing on %s, force %d\n",
		winPtr->pathName, displayFocusPtr->forceFocus));







|







951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
 */

static void
FocusMapProc(
    ClientData clientData,	/* Toplevel window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;
    DisplayFocusInfo *displayFocusPtr;

    if (eventPtr->type == VisibilityNotify) {
	displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr,
		winPtr->dispPtr);
	DEBUG(winPtr->dispPtr, ("auto-focussing on %s, force %d\n",
		winPtr->pathName, displayFocusPtr->forceFocus));
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
	}
    }

    /*
     * The record doesn't exist yet. Make a new one.
     */

    displayFocusPtr = (DisplayFocusInfo *)ckalloc(sizeof(DisplayFocusInfo));
    displayFocusPtr->dispPtr = dispPtr;
    displayFocusPtr->focusWinPtr = NULL;
    displayFocusPtr->focusOnMapPtr = NULL;
    displayFocusPtr->forceFocus = 0;
    displayFocusPtr->focusSerial = 0;
    displayFocusPtr->nextPtr = mainPtr->displayFocusPtr;
    mainPtr->displayFocusPtr = displayFocusPtr;







|







1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
	}
    }

    /*
     * The record doesn't exist yet. Make a new one.
     */

    displayFocusPtr = (DisplayFocusInfo *) ckalloc(sizeof(DisplayFocusInfo));
    displayFocusPtr->dispPtr = dispPtr;
    displayFocusPtr->focusWinPtr = NULL;
    displayFocusPtr->focusOnMapPtr = NULL;
    displayFocusPtr->forceFocus = 0;
    displayFocusPtr->focusSerial = 0;
    displayFocusPtr->nextPtr = mainPtr->displayFocusPtr;
    mainPtr->displayFocusPtr = displayFocusPtr;
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
    TkMainInfo *mainPtr)	/* Record that identifies a particular
				 * application. */
{
    while (mainPtr->displayFocusPtr != NULL) {
	DisplayFocusInfo *displayFocusPtr = mainPtr->displayFocusPtr;

	mainPtr->displayFocusPtr = mainPtr->displayFocusPtr->nextPtr;
	ckfree(displayFocusPtr);
    }
    while (mainPtr->tlFocusPtr != NULL) {
	ToplevelFocusInfo *tlFocusPtr = mainPtr->tlFocusPtr;

	mainPtr->tlFocusPtr = mainPtr->tlFocusPtr->nextPtr;
	ckfree(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(
    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, *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) {
	/* EMPTY */
    }

    if (subWinPtr == winPtr) {
	/*
	 * Move focus to new toplevel.
	 */

	ToplevelFocusInfo *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(
    TkWindow *winPtr)		/* Window is no longer a toplevel. */
{
    ToplevelFocusInfo *tlFocusPtr, *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(tmpPtr);
    } else if (winPtr && winPtr->mainPtr) {
	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(tmpPtr);
		break;
	    }
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|





|








|
|











|
|
|
|


|
>




|
|
|


|


|
|

<







<
|
<
<

|






<
|
<
<



<
|
<
<
|
|
|
<
|
<

<
|
<
<
|

>




<
<
|
<
<


<
<
|
<



















|
|

|
>




<

|


|
|

|

|


|













1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105

1106


1107
1108
1109
1110
1111
1112
1113
1114

1115


1116
1117
1118

1119


1120
1121
1122

1123

1124

1125


1126
1127
1128
1129
1130
1131
1132


1133


1134
1135


1136

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
    TkMainInfo *mainPtr)	/* Record that identifies a particular
				 * application. */
{
    while (mainPtr->displayFocusPtr != NULL) {
	DisplayFocusInfo *displayFocusPtr = mainPtr->displayFocusPtr;

	mainPtr->displayFocusPtr = mainPtr->displayFocusPtr->nextPtr;
	ckfree((char *) displayFocusPtr);
    }
    while (mainPtr->tlFocusPtr != NULL) {
	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:
 */

Changes to generic/tkFont.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * 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 "tkFont.h"
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"    /* Defines TK_DRAW_IN_CONTEXT */
#endif

/*
 * 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.
 */








<
<
<







9
10
11
12
13
14
15



16
17
18
19
20
21
22
 *
 * 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 "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.
 */

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * The following data structure is used to keep track of the font attributes
 * for each named font that has been defined. The named font is only deleted
 * when the last reference to it goes away.
 */

typedef struct NamedFont {
    size_t refCount;		/* Number of users of named font. */
    int deletePending;		/* Non-zero if font should be deleted when
				 * last reference goes away. */
    TkFontAttributes fa;	/* Desired attributes for named font. */
} NamedFont;

/*
 * The following two structures are used to keep track of string measurement







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * The following data structure is used to keep track of the font attributes
 * for each named font that has been defined. The named font is only deleted
 * when the last reference to it goes away.
 */

typedef struct NamedFont {
    int refCount;		/* Number of users of named font. */
    int deletePending;		/* Non-zero if font should be deleted when
				 * last reference goes away. */
    TkFontAttributes fa;	/* Desired attributes for named font. */
} NamedFont;

/*
 * The following two structures are used to keep track of string measurement
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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[TKFLEXARRAY];/* 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,







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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. */
} 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,
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
};

/*
 * The following structure and defines specify the valid builtin options when
 * configuring a set of font attributes.
 */

static const char *const fontOpt[] = {
    "-family",
    "-size",
    "-weight",
    "-slant",
    "-underline",
    "-overstrike",
    NULL







|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
};

/*
 * The following structure and defines specify the valid builtin options when
 * configuring a set of font attributes.
 */

static const char *fontOpt[] = {
    "-family",
    "-size",
    "-weight",
    "-slant",
    "-underline",
    "-overstrike",
    NULL
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/*
 * 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 const char *const timesAliases[] = {
    "Times",			/* Unix. */
    "Times New Roman",		/* Windows. */
    "New York",			/* Mac. */
    NULL
};

static const char *const helveticaAliases[] = {
    "Helvetica",		/* Unix. */
    "Arial",			/* Windows. */
    "Geneva",			/* Mac. */
    NULL
};

static const char *const courierAliases[] = {
    "Courier",			/* Unix and Mac. */
    "Courier New",		/* Windows. */
    NULL
};

static const char *const minchoAliases[] = {
    "mincho",			/* Unix. */
    "\357\274\255\357\274\263 \346\230\216\346\234\235",
				/* Windows (MS mincho). */
    "\346\234\254\346\230\216\346\234\235\342\210\222\357\274\255",
				/* Mac (honmincho-M). */
    NULL
};

static const char *const gothicAliases[] = {
    "gothic",			/* Unix. */
    "\357\274\255\357\274\263 \343\202\264\343\202\267\343\203\203\343\202\257",
				/* Windows (MS goshikku). */
    "\344\270\270\343\202\264\343\202\267\343\203\203\343\202\257\342\210\222\357\274\255",
				/* Mac (goshikku-M). */
    NULL
};

static const char *const dingbatsAliases[] = {
    "dingbats", "zapfdingbats", "itc zapfdingbats",
				/* Unix. */
				/* Windows. */
    "zapf dingbats",		/* Mac. */
    NULL
};

static const char *const *const fontAliases[] = {
    timesAliases,
    helveticaAliases,
    courierAliases,
    minchoAliases,
    gothicAliases,
    dingbatsAliases,
    NULL
};

/*
 * Hardcoded font classes. If the character cannot be found in the base font,
 * the classes are examined in order to see if some other similar font should
 * be examined also.
 */

static const char *const systemClass[] = {
    "fixed",			/* Unix. */
				/* Windows. */
    "chicago", "osaka", "sistemny",
				/* Mac. */
    NULL
};

static const char *const serifClass[] = {
    "times", "palatino", "mincho",
				/* All platforms. */
    "song ti",			/* Unix. */
    "ms serif", "simplified arabic",
				/* Windows. */
    "latinski",			/* Mac. */
    NULL
};

static const char *const sansClass[] = {
    "helvetica", "gothic",	/* All platforms. */
				/* Unix. */
    "ms sans serif", "traditional arabic",
				/* Windows. */
    "bastion",			/* Mac. */
    NULL
};

static const char *const monoClass[] = {
    "courier", "gothic",	/* All platforms. */
    "fangsong ti",		/* Unix. */
    "simplified arabic fixed",	/* Windows. */
    "monaco", "pryamoy",	/* Mac. */
    NULL
};

static const char *const symbolClass[] = {
    "symbol", "dingbats", "wingdings", NULL
};

static const char *const *const fontFallbacks[] = {
    systemClass,
    serifClass,
    sansClass,
    monoClass,
    symbolClass,
    NULL
};

/*
 * Global fallbacks. If the character could not be found in the preferred
 * fallback list, this list is examined. If the character still cannot be
 * found, all font families in the system are examined.
 */

static const char *const globalFontClass[] = {
    "symbol",			/* All platforms. */
				/* Unix. */
    "lucida sans unicode",	/* Windows. */
    "bitstream cyberbit",	/* Windows popular CJK font */
    "chicago",			/* Mac. */
    NULL
};

#define GetFontAttributes(tkfont) \
	((const TkFontAttributes *) &((TkFont *) (tkfont))->fa)

#define GetFontMetrics(tkfont)    \
	((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		FreeFontObj(Tcl_Obj *objPtr);
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.
 */

const Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *







|






|






|





|








|








|







|















|







|









|








|







|



|














|




















<




















|




|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
 * Hardcoded font aliases. These are used to describe (mostly) identical fonts
 * whose names differ from platform to platform. If the user-supplied font
 * name matches any of the names in one of the alias lists, the other names in
 * the alias list are also automatically tried.
 */

static char *timesAliases[] = {
    "Times",			/* Unix. */
    "Times New Roman",		/* Windows. */
    "New York",			/* Mac. */
    NULL
};

static char *helveticaAliases[] = {
    "Helvetica",		/* Unix. */
    "Arial",			/* Windows. */
    "Geneva",			/* Mac. */
    NULL
};

static char *courierAliases[] = {
    "Courier",			/* Unix and Mac. */
    "Courier New",		/* Windows. */
    NULL
};

static char *minchoAliases[] = {
    "mincho",			/* Unix. */
    "\357\274\255\357\274\263 \346\230\216\346\234\235",
				/* Windows (MS mincho). */
    "\346\234\254\346\230\216\346\234\235\342\210\222\357\274\255",
				/* Mac (honmincho-M). */
    NULL
};

static char *gothicAliases[] = {
    "gothic",			/* Unix. */
    "\357\274\255\357\274\263 \343\202\264\343\202\267\343\203\203\343\202\257",
				/* Windows (MS goshikku). */
    "\344\270\270\343\202\264\343\202\267\343\203\203\343\202\257\342\210\222\357\274\255",
				/* Mac (goshikku-M). */
    NULL
};

static char *dingbatsAliases[] = {
    "dingbats", "zapfdingbats", "itc zapfdingbats",
				/* Unix. */
				/* Windows. */
    "zapf dingbats",		/* Mac. */
    NULL
};

static char **fontAliases[] = {
    timesAliases,
    helveticaAliases,
    courierAliases,
    minchoAliases,
    gothicAliases,
    dingbatsAliases,
    NULL
};

/*
 * Hardcoded font classes. If the character cannot be found in the base font,
 * the classes are examined in order to see if some other similar font should
 * be examined also.
 */

static char *systemClass[] = {
    "fixed",			/* Unix. */
				/* Windows. */
    "chicago", "osaka", "sistemny",
				/* Mac. */
    NULL
};

static char *serifClass[] = {
    "times", "palatino", "mincho",
				/* All platforms. */
    "song ti",			/* Unix. */
    "ms serif", "simplified arabic",
				/* Windows. */
    "latinski",			/* Mac. */
    NULL
};

static char *sansClass[] = {
    "helvetica", "gothic",	/* All platforms. */
				/* Unix. */
    "ms sans serif", "traditional arabic",
				/* Windows. */
    "bastion",			/* Mac. */
    NULL
};

static char *monoClass[] = {
    "courier", "gothic",	/* All platforms. */
    "fangsong ti",		/* Unix. */
    "simplified arabic fixed",	/* Windows. */
    "monaco", "pryamoy",	/* Mac. */
    NULL
};

static char *symbolClass[] = {
    "symbol", "dingbats", "wingdings", NULL
};

static char **fontFallbacks[] = {
    systemClass,
    serifClass,
    sansClass,
    monoClass,
    symbolClass,
    NULL
};

/*
 * Global fallbacks. If the character could not be found in the preferred
 * fallback list, this list is examined. If the character still cannot be
 * found, all font families in the system are examined.
 */

static char *globalFontClass[] = {
    "symbol",			/* All platforms. */
				/* Unix. */
    "lucida sans unicode",	/* Windows. */
    "bitstream cyberbit",	/* Windows popular CJK font */
    "chicago",			/* Mac. */
    NULL
};

#define GetFontAttributes(tkfont) \
	((const TkFontAttributes *) &((TkFont *) (tkfont))->fa)

#define GetFontMetrics(tkfont)    \
	((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.
 */

Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetFontFromAny		/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
 *---------------------------------------------------------------------------
 */

void
TkFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    TkFontInfo *fiPtr = (TkFontInfo *)ckalloc(sizeof(TkFontInfo));


    Tcl_InitHashTable(&fiPtr->fontCache, TCL_STRING_KEYS);
    Tcl_InitHashTable(&fiPtr->namedTable, TCL_STRING_KEYS);
    fiPtr->mainPtr = mainPtr;
    fiPtr->updatePending = 0;
    mainPtr->fontInfoPtr = fiPtr;

    TkpFontPkgInit(mainPtr);







|

>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
 *---------------------------------------------------------------------------
 */

void
TkFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    TkFontInfo *fiPtr;

    fiPtr = (TkFontInfo *) ckalloc(sizeof(TkFontInfo));
    Tcl_InitHashTable(&fiPtr->fontCache, TCL_STRING_KEYS);
    Tcl_InitHashTable(&fiPtr->namedTable, TCL_STRING_KEYS);
    fiPtr->mainPtr = mainPtr;
    fiPtr->updatePending = 0;
    mainPtr->fontInfoPtr = fiPtr;

    TkpFontPkgInit(mainPtr);
409
410
411
412
413
414
415
416
417
418
419
420



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 *---------------------------------------------------------------------------
 */

void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr = mainPtr->fontInfoPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;
    int fontsLeft = 0;




    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {
	fontsLeft++;
#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		(char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY
    if (fontsLeft) {
	Tcl_Panic("TkFontPkgFree: all fonts should have been freed already");
    }
#endif

    Tcl_DeleteHashTable(&fiPtr->fontCache);

    hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search);
    while (hPtr != NULL) {
	ckfree(Tcl_GetHashValue(hPtr));
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&fiPtr->namedTable);
    if (fiPtr->updatePending) {
	Tcl_CancelIdleCall(TheWorldHasChanged, fiPtr);
    }
    ckfree(fiPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FontObjCmd --
 *







|


|

>
>
>






|













|



|
|

|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 *---------------------------------------------------------------------------
 */

void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;
    int fontsLeft;

    fiPtr = mainPtr->fontInfoPtr;

    fontsLeft = 0;
    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {
	fontsLeft++;
#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY
    if (fontsLeft) {
	Tcl_Panic("TkFontPkgFree: all fonts should have been freed already");
    }
#endif

    Tcl_DeleteHashTable(&fiPtr->fontCache);

    hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search);
    while (hPtr != NULL) {
	ckfree((char *) Tcl_GetHashValue(hPtr));
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&fiPtr->namedTable);
    if (fiPtr->updatePending != 0) {
	Tcl_CancelIdleCall(TheWorldHasChanged, (ClientData) fiPtr);
    }
    ckfree((char *) fiPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FontObjCmd --
 *
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487



488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
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 = (Tk_Window)clientData;
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    static const char *const optionStrings[] = {
	"actual",	"configure",	"create",	"delete",
	"families",	"measure",	"metrics",	"names",
	NULL
    };
    enum options {
	FONT_ACTUAL,	FONT_CONFIGURE,	FONT_CREATE,	FONT_DELETE,
	FONT_FAMILIES,	FONT_MEASURE,	FONT_METRICS,	FONT_NAMES
    };




    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case FONT_ACTUAL: {
	int skip, result, n;
	const char *s;
	Tk_Font tkfont;
	Tcl_Obj *optPtr, *charPtr, *resultPtr;
	int uniChar = 0;
	const TkFontAttributes *faPtr;
	TkFontAttributes fa;

	/*
	 * Params 0 and 1 are 'font actual'. Param 2 is the font name. 3-4 may
	 * be '-displayof $window'
	 */







|
|
|









>
>
>















|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
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[] = {
	"actual",	"configure",	"create",	"delete",
	"families",	"measure",	"metrics",	"names",
	NULL
    };
    enum options {
	FONT_ACTUAL,	FONT_CONFIGURE,	FONT_CREATE,	FONT_DELETE,
	FONT_FAMILIES,	FONT_MEASURE,	FONT_METRICS,	FONT_NAMES
    };

    tkwin = (Tk_Window) clientData;
    fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case 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;

	/*
	 * Params 0 and 1 are 'font actual'. Param 2 is the font name. 3-4 may
	 * be '-displayof $window'
	 */
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
	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 {
		optPtr = NULL;
	    }
	}

	/*
	 * Next parameter may be '--' to mark end of options.
	 */

	if (n < objc) {
	    if (!strcmp(Tcl_GetString(objv[n]), "--")) {
		n++;
	    }
	}

	/*
	 * 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) {
	    const char *string = Tcl_GetString(charPtr);
	    size_t len = TkUtfToUniChar(string, &uniChar);

	    if (len != (size_t)charPtr->length) {
		resultPtr = Tcl_NewStringObj(
			"expected a single character but got \"", -1);
		Tcl_AppendLimitedToObj(resultPtr, string,
			-1, 40, "...");
		Tcl_AppendToObj(resultPtr, "\"", -1);
		Tcl_SetObjResult(interp, resultPtr);
		Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);
		return TCL_ERROR;
	    }

	}

	/*
	 * Find the font.
	 */

	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);







|











|









|








|








<
<
|
<


|



<


>







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570


571

572
573
574
575
576
577

578
579
580
581
582
583
584
585
586
587
	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 {
		optPtr = NULL;
	    }
	}

	/*
	 * Next parameter may be '--' to mark end of options.
	 */

	if (n < objc) {
	    if (!strcmp(Tcl_GetString(objv[n]), "--")) {
		++n;
	    }
	}

	/*
	 * 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;
	    }
	    uniChar = Tcl_GetUniChar(charPtr, 0);
	}

	/*
	 * Find the font.
	 */

	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
	}
	result = GetAttributeInfoObj(interp, faPtr, optPtr);

	Tk_FreeFont(tkfont);
	return result;
    }
    case FONT_CONFIGURE: {
    	int result;
    	const char *string;
    	Tcl_Obj *objPtr;
    	NamedFont *nfPtr;
    	Tcl_HashEntry *namedHashPtr;

    	if (objc < 3) {
    	    Tcl_WrongNumArgs(interp, 2, objv, "fontname ?-option value ...?");
    	    return TCL_ERROR;
    	}
    	string = Tcl_GetString(objv[2]);
    	namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string);
	nfPtr = NULL;
    	if (namedHashPtr != NULL) {
    	    nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);
    	}
    	if ((namedHashPtr == NULL) || nfPtr->deletePending) {
    	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
    		    "named font \"%s\" doesn't exist", string));
    	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, 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 = 3, i;
	const char *name;
	char buf[16 + TCL_INTEGER_SPACE];
	TkFontAttributes fa;
	Tcl_HashEntry *namedHashPtr;


	if (objc < 3) {
	    name = NULL;
	} else {
	    name = Tcl_GetString(objv[2]);
	    if (name[0] == '-') {
		name = NULL;
	    }







|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|




>







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
	}
	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;
	    }
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789


790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
	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;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
	break;
    }
    case FONT_DELETE: {
	int i, result = TCL_OK;
	const char *string;

	/*
	 * 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;
	}
	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 = 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;
    }
    case FONT_MEASURE: {
	const char *string;
	Tk_Font tkfont;
	TkSizeT length = 0;
	int skip = 0;

	if (objc > 4) {
	    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 = TkGetStringFromObj(objv[3 + skip], &length);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		Tk_TextWidth(tkfont, string, length)));
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_METRICS: {
	Tk_Font tkfont;
	int skip, i;
	const TkFontMetrics *fmPtr;
	static const char *const 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) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "-ascent %d -descent %d -linespace %d -fixed %d",
		    fmPtr->ascent, fmPtr->descent,
		    fmPtr->ascent + fmPtr->descent, fmPtr->fixed));

	} 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_SetObjResult(interp, Tcl_NewWideIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {


	Tcl_HashSearch search;
	Tcl_HashEntry *namedHashPtr;
	Tcl_Obj *resultPtr;

	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "names");
	    return TCL_ERROR;
	}
	resultPtr = Tcl_NewObj();
	namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search);
	while (namedHashPtr != NULL) {
	    NamedFont *nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);

	    if (!nfPtr->deletePending) {
		char *string = (char *)Tcl_GetHashKey(&fiPtr->namedTable,
			namedHashPtr);

		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj(string, -1));
	    }
	    namedHashPtr = Tcl_NextHashEntry(&search);
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    }
    return TCL_OK;
}

/*







|




|










|






|

>











|

|
|








|
<






|
|
|





|

|









|










>
|
|

|
>













|





>
>


|





|


|
<
|
|
<
|
|
<



<







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

806
807

808
809

810
811
812

813
814
815
816
817
818
819
	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;
	}
	Tcl_AppendResult(interp, name, NULL);
	break;
    }
    case FONT_DELETE: {
	int i, result = TCL_OK;
	char *string;

	/*
	 * 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;
	}
	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;
	}
	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 - 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;
	    }
	    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);
	}
	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);

	    }
	    namedHashPtr = Tcl_NextHashEntry(&search);
	}

	break;
    }
    }
    return TCL_OK;
}

/*
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
    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;
    TkFont *fontPtr;
    NamedFont *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.
	 */

	return;
    }

    cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
    while (cacheHashPtr != NULL) {
	for (fontPtr = (TkFont *)Tcl_GetHashValue(cacheHashPtr);
		fontPtr != NULL; fontPtr = fontPtr->nextPtr) {
	    if (fontPtr->namedHashPtr == namedHashPtr) {
		TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa);
		if (!fiPtr->updatePending) {
		    fiPtr->updatePending = 1;
		    Tcl_DoWhenIdle(TheWorldHasChanged, fiPtr);
		}
	    }
	}
	cacheHashPtr = Tcl_NextHashEntry(&search);
    }
}

static void
TheWorldHasChanged(
    ClientData clientData)	/* Info about application's fonts. */
{
    TkFontInfo *fiPtr = (TkFontInfo *)clientData;

    /*
     * On macOS it is catastrophic to recompute all widgets while the
     * [NSView drawRect] method is drawing. The best that we can do in
     * that situation is to abort the recomputation and hope for the best.
     * This is ignored on other platforms.
     */

    if (TkpWillDrawWidget(NULL)) {
	return;
    }

    fiPtr->updatePending = 0;
    RecomputeWidgets(fiPtr->mainPtr->winPtr);
}

static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc =
	    Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);

    if (proc != NULL) {
	proc(winPtr->instanceData);
    }

    /*
     * 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







|

>











|



|

|











|

|
<
<
<
<
<
|
<
<
|
<
<







|
|
<

|







840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881





882


883


884
885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
900
901
    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;
    TkFont *fontPtr;
    NamedFont *nfPtr;

    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.
	 */

	return;
    }

    cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
    while (cacheHashPtr != NULL) {
	for (fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr);
		fontPtr != NULL; fontPtr = fontPtr->nextPtr) {
	    if (fontPtr->namedHashPtr == namedHashPtr) {
		TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa);
		if (fiPtr->updatePending == 0) {
		    fiPtr->updatePending = 1;
		    Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData) fiPtr);
		}
	    }
	}
	cacheHashPtr = Tcl_NextHashEntry(&search);
    }
}

static void
TheWorldHasChanged(
    ClientData clientData)	/* Info about application's fonts. */
{
    TkFontInfo *fiPtr;

    fiPtr = (TkFontInfo *) clientData;





    fiPtr->updatePending = 0;





    RecomputeWidgets(fiPtr->mainPtr->winPtr);
}

static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc;
    proc = Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);

    if (proc != NULL) {
	(*proc)(winPtr->instanceData);
    }

    /*
     * 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
954
955
956
957
958
959
960
961
962
963
964
965


966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
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 = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    Tcl_HashEntry *namedHashPtr;
    int isNew;
    NamedFont *nfPtr;



    namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew);

    if (!isNew) {
	nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);
	if (!nfPtr->deletePending) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"named font \"%s\" already exists", name));
		Tcl_SetErrorCode(interp, "TK", "FONT", "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.
	 */

	nfPtr->fa = *faPtr;
	nfPtr->deletePending = 0;
	UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
	return TCL_OK;
    }

    nfPtr = (NamedFont *)ckalloc(sizeof(NamedFont));
    nfPtr->deletePending = 0;
    Tcl_SetHashValue(namedHashPtr, nfPtr);
    nfPtr->fa = *faPtr;
    nfPtr->refCount = 0;
    nfPtr->deletePending = 0;
    return TCL_OK;
}







|




>
>

>

|
|

|
|
<
















|







945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
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 isNew;
    NamedFont *nfPtr;

    fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;

    namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew);

    if (!isNew) {
	nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
	if (nfPtr->deletePending == 0) {
	    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.
	 */

	nfPtr->fa = *faPtr;
	nfPtr->deletePending = 0;
	UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
	return TCL_OK;
    }

    nfPtr = (NamedFont *) ckalloc(sizeof(NamedFont));
    nfPtr->deletePending = 0;
    Tcl_SetHashValue(namedHashPtr, nfPtr);
    nfPtr->fa = *faPtr;
    nfPtr->refCount = 0;
    nfPtr->deletePending = 0;
    return TCL_OK;
}
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018


1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
 *---------------------------------------------------------------------------
 */

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 = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    NamedFont *nfPtr;
    Tcl_HashEntry *namedHashPtr;



    namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, name);
    if (namedHashPtr == NULL) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "named font \"%s\" doesn't exist", name));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", name, NULL);
	}
	return TCL_ERROR;
    }
    nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);
    if (nfPtr->refCount != 0) {
	nfPtr->deletePending = 1;
    } else {
	Tcl_DeleteHashEntry(namedHashPtr);
	ckfree(nfPtr);
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *







|

|


>
>




|
|
<



|




|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
 *---------------------------------------------------------------------------
 */

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;
}

/*
 *---------------------------------------------------------------------------
 *
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
    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;
    Tcl_Obj *strPtr;

    strPtr = Tcl_NewStringObj(string, -1);
    Tcl_IncrRefCount(strPtr);
    tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr);
    Tcl_DecrRefCount(strPtr);
    return tkfont;
}

/*







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
    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;
    Tcl_Obj *strPtr;

    strPtr = Tcl_NewStringObj((char *) string, -1);
    Tcl_IncrRefCount(strPtr);
    tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr);
    Tcl_DecrRefCount(strPtr);
    return tkfont;
}

/*
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
Tk_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 = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    Tcl_HashEntry *cacheHashPtr, *namedHashPtr;
    TkFont *fontPtr, *firstFontPtr, *oldFontPtr;
    int isNew, descent;
    NamedFont *nfPtr;


    if (objPtr->typePtr != &tkFontObjType
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(interp, objPtr);
    }

    oldFontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;

    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.
	     */

	    FreeFontObj(objPtr);
	    oldFontPtr = NULL;
	} else if (Tk_Screen(tkwin) == oldFontPtr->screen) {
	    oldFontPtr->resourceRefCount++;
	    return (Tk_Font) oldFontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.
     */

    isNew = 0;
    if (oldFontPtr != NULL) {
	cacheHashPtr = oldFontPtr->cacheHashPtr;
	FreeFontObj(objPtr);
    } else {
	cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache,
		Tcl_GetString(objPtr), &isNew);
    }
    firstFontPtr = (TkFont *)Tcl_GetHashValue(cacheHashPtr);
    for (fontPtr = firstFontPtr; (fontPtr != NULL);
	    fontPtr = fontPtr->nextPtr) {
	if (Tk_Screen(tkwin) == fontPtr->screen) {
	    fontPtr->resourceRefCount++;
	    fontPtr->objRefCount++;
	    objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
	    objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * The desired font isn't in the table. Make a new one.
     */

    namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable,
	    Tcl_GetString(objPtr));
    if (namedHashPtr != NULL) {
	/*
	 * Construct a font based on a named font.
	 */

	nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);
	nfPtr->refCount++;

	fontPtr = TkpGetFontFromAttributes(NULL, tkwin, &nfPtr->fa);
    } else {
	/*
	 * Native font?
	 */







|





>
|
<



|
>







|















|




|





|
<















|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
Tk_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 isNew, descent;
    NamedFont *nfPtr;

    fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    if (objPtr->typePtr != &tkFontObjType) {

	SetFontFromAny(interp, objPtr);
    }

    oldFontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1;

    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.
	     */

	    FreeFontObjProc(objPtr);
	    oldFontPtr = NULL;
	} else if (Tk_Screen(tkwin) == oldFontPtr->screen) {
	    oldFontPtr->resourceRefCount++;
	    return (Tk_Font) oldFontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.
     */

    isNew = 0;
    if (oldFontPtr != NULL) {
	cacheHashPtr = oldFontPtr->cacheHashPtr;
	FreeFontObjProc(objPtr);
    } else {
	cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache,
		Tcl_GetString(objPtr), &isNew);
    }
    firstFontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr);
    for (fontPtr = firstFontPtr; (fontPtr != NULL);
	    fontPtr = fontPtr->nextPtr) {
	if (Tk_Screen(tkwin) == fontPtr->screen) {
	    fontPtr->resourceRefCount++;
	    fontPtr->objRefCount++;
	    objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;

	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * The desired font isn't in the table. Make a new one.
     */

    namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable,
	    Tcl_GetString(objPtr));
    if (namedHashPtr != NULL) {
	/*
	 * Construct a font based on a named font.
	 */

	nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
	nfPtr->refCount++;

	fontPtr = TkpGetFontFromAttributes(NULL, tkwin, &nfPtr->fa);
    } else {
	/*
	 * Native font?
	 */
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
     * Detect the system font engine going wrong and fail more gracefully.
     */

    if (fontPtr == NULL) {
	if (isNew) {
	    Tcl_DeleteHashEntry(cacheHashPtr);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"failed to allocate font due to internal system font engine"
		" problem", -1));
	Tcl_SetErrorCode(interp, "TK", "FONT", "INTERNAL_PROBLEM", NULL);
	return NULL;
    }

    fontPtr->resourceRefCount = 1;
    fontPtr->objRefCount = 1;
    fontPtr->cacheHashPtr = cacheHashPtr;
    fontPtr->namedHashPtr = namedHashPtr;







<
|
|
<







1196
1197
1198
1199
1200
1201
1202

1203
1204

1205
1206
1207
1208
1209
1210
1211
     * 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;
    fontPtr->namedHashPtr = namedHashPtr;
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
    /*
     * Get information used for drawing underlines in generic code on a
     * non-underlined font.
     */

    descent = fontPtr->fm.descent;
    fontPtr->underlinePos = descent / 2;
    fontPtr->underlineHeight = (int) (TkFontGetPixels(tkwin, fontPtr->fa.size) / 10 + 0.5);
    if (fontPtr->underlineHeight == 0) {
	fontPtr->underlineHeight = 1;
    }
    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.
	 */

	fontPtr->underlineHeight = descent - fontPtr->underlinePos;
	if (fontPtr->underlineHeight == 0) {
	    fontPtr->underlinePos--;
	    fontPtr->underlineHeight = 1;
	}
    }

    objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
    objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
    return (Tk_Font) fontPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetFontFromObj --







|

















|
<







1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
    /*
     * 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;
    if (fontPtr->underlineHeight == 0) {
	fontPtr->underlineHeight = 1;
    }
    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.
	 */

	fontPtr->underlineHeight = descent - fontPtr->underlinePos;
	if (fontPtr->underlineHeight == 0) {
	    fontPtr->underlinePos--;
	    fontPtr->underlineHeight = 1;
	}
    }

    objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;

    return (Tk_Font) fontPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetFontFromObj --
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
 *	old internal representation.
 *
 *----------------------------------------------------------------------
 */

Tk_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
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(NULL, objPtr);
    }

    fontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;

    if (fontPtr != NULL) {
	if (fontPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkFont that's no
	     * longer in use. Clear the reference.
	     */

	    FreeFontObj(objPtr);
	    fontPtr = NULL;
	} else if (Tk_Screen(tkwin) == fontPtr->screen) {
	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.
     */

    if (fontPtr != NULL) {
	hashPtr = fontPtr->cacheHashPtr;
	FreeFontObj(objPtr);
    } else {
	hashPtr = Tcl_FindHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr));
    }
    if (hashPtr != NULL) {
	for (fontPtr = (TkFont *)Tcl_GetHashValue(hashPtr); fontPtr != NULL;
		fontPtr = fontPtr->nextPtr) {
	    if (Tk_Screen(tkwin) == fontPtr->screen) {
		fontPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
		objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
		return (Tk_Font) fontPtr;
	    }
	}
    }

    Tcl_Panic("Tk_GetFontFromObj called with non-existent font!");
    return NULL;







|
<






|
<



|
>







|













|




|



|
<







1274
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
 *	old internal representation.
 *
 *----------------------------------------------------------------------
 */

Tk_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(NULL, objPtr);
    }

    fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1;

    if (fontPtr != NULL) {
	if (fontPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkFont that's no
	     * longer in use. Clear the reference.
	     */

	    FreeFontObjProc(objPtr);
	    fontPtr = NULL;
	} else if (Tk_Screen(tkwin) == fontPtr->screen) {
	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.
     */

    if (fontPtr != NULL) {
	hashPtr = fontPtr->cacheHashPtr;
	FreeFontObjProc(objPtr);
    } else {
	hashPtr = Tcl_FindHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr));
    }
    if (hashPtr != NULL) {
	for (fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); fontPtr != NULL;
		fontPtr = fontPtr->nextPtr) {
	    if (Tk_Screen(tkwin) == fontPtr->screen) {
		fontPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;

		return (Tk_Font) fontPtr;
	    }
	}
    }

    Tcl_Panic("Tk_GetFontFromObj called with non-existent font!");
    return NULL;
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
 *	TkFont pointer is NULL.
 *
 *----------------------------------------------------------------------
 */

static int
SetFontFromAny(
    TCL_UNUSED(Tcl_Interp *),	/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkFontObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *







|











|



<







1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369

1370
1371
1372
1373
1374
1375
1376
 *	TkFont pointer is NULL.
 *
 *----------------------------------------------------------------------
 */

static int
SetFontFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->typePtr = &tkFontObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;


    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
1402
1403
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
 *---------------------------------------------------------------------------
 */

const char *
Tk_NameOfFont(
    Tk_Font tkfont)		/* Font whose name is desired. */
{
    TkFont *fontPtr = (TkFont *) tkfont;


    return fontPtr->cacheHashPtr->key.string;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeFont --







|

>







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
 *---------------------------------------------------------------------------
 */

const char *
Tk_NameOfFont(
    Tk_Font tkfont)		/* Font whose name is desired. */
{
    TkFont *fontPtr;

    fontPtr = (TkFont *) tkfont;
    return fontPtr->cacheHashPtr->key.string;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeFont --
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440


1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451

1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
 *---------------------------------------------------------------------------
 */

void
Tk_FreeFont(
    Tk_Font tkfont)		/* Font to be released. */
{
    TkFont *fontPtr = (TkFont *) tkfont, *prevPtr;
    NamedFont *nfPtr;

    if (fontPtr == NULL) {
	return;
    }


    if (fontPtr->resourceRefCount-- > 1) {
	return;
    }
    if (fontPtr->namedHashPtr != NULL) {
	/*
	 * This font derived from a named font. Reduce the reference count on
	 * the named font and free it if no-one else is using it.
	 */

	nfPtr = (NamedFont *)Tcl_GetHashValue(fontPtr->namedHashPtr);
	if ((nfPtr->refCount-- <= 1) && nfPtr->deletePending) {

	    Tcl_DeleteHashEntry(fontPtr->namedHashPtr);
	    ckfree(nfPtr);
	}
    }

    prevPtr = (TkFont *)Tcl_GetHashValue(fontPtr->cacheHashPtr);
    if (prevPtr == fontPtr) {
	if (fontPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(fontPtr->cacheHashPtr);
	} else {
	    Tcl_SetHashValue(fontPtr->cacheHashPtr, fontPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != fontPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = fontPtr->nextPtr;
    }

    TkpDeleteFont(fontPtr);
    if (fontPtr->objRefCount == 0) {
	ckfree(fontPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeFontFromObj --







|


|


>
>
|








|
|
>

|



|















|







1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
 *---------------------------------------------------------------------------
 */

void
Tk_FreeFont(
    Tk_Font tkfont)		/* Font to be released. */
{
    TkFont *fontPtr, *prevPtr;
    NamedFont *nfPtr;

    if (tkfont == NULL) {
	return;
    }
    fontPtr = (TkFont *) tkfont;
    fontPtr->resourceRefCount--;
    if (fontPtr->resourceRefCount > 0) {
	return;
    }
    if (fontPtr->namedHashPtr != NULL) {
	/*
	 * This font derived from a named font. Reduce the reference count on
	 * the named font and free it if no-one else is using it.
	 */

	nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr);
	nfPtr->refCount--;
	if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) {
	    Tcl_DeleteHashEntry(fontPtr->namedHashPtr);
	    ckfree((char *) nfPtr);
	}
    }

    prevPtr = (TkFont *) Tcl_GetHashValue(fontPtr->cacheHashPtr);
    if (prevPtr == fontPtr) {
	if (fontPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(fontPtr->cacheHashPtr);
	} else {
	    Tcl_SetHashValue(fontPtr->cacheHashPtr, fontPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != fontPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = fontPtr->nextPtr;
    }

    TkpDeleteFont(fontPtr);
    if (fontPtr->objRefCount == 0) {
	ckfree((char *) fontPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeFontFromObj --
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
{
    Tk_FreeFont(Tk_GetFontFromObj(tkwin, objPtr));
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeFontObjProc, FreeFontObj --
 *
 *	This proc is called to release an object reference to a font. Called
 *	when the object's internal rep is released or when the cached fontPtr
 *	needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the font's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeFontObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    FreeFontObj(objPtr);
    objPtr->typePtr = NULL;
}

static void
FreeFontObj(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{
    TkFont *fontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;

    if (fontPtr != NULL) {
	if ((fontPtr->objRefCount-- <= 1) && (fontPtr->resourceRefCount == 0)) {

	    ckfree(fontPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
	objPtr->internalRep.twoPtrValue.ptr2 = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * DupFontObjProc --







|



















<
<
<
<
<
<
<
<
|


|
>
|


<







1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518








1519
1520
1521
1522
1523
1524
1525
1526

1527
1528
1529
1530
1531
1532
1533
{
    Tk_FreeFont(Tk_GetFontFromObj(tkwin, objPtr));
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeFontObjProc --
 *
 *	This proc is called to release an object reference to a font. Called
 *	when the object's internal rep is released or when the cached fontPtr
 *	needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the font's resources are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeFontObjProc(
    Tcl_Obj *objPtr)		/* The object we are releasing. */
{








    TkFont *fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1;

    if (fontPtr != NULL) {
	fontPtr->objRefCount--;
	if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) {
	    ckfree((char *) fontPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = NULL;

    }
}

/*
 *---------------------------------------------------------------------------
 *
 * DupFontObjProc --
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
 */

static void
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 = fontPtr;
    dupObjPtr->internalRep.twoPtrValue.ptr2
	    = srcObjPtr->internalRep.twoPtrValue.ptr2;

    if (fontPtr != NULL) {
	fontPtr->objRefCount++;
    }
}

/*







|


|
<
<







1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556


1557
1558
1559
1560
1561
1562
1563
 */

static void
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;



    if (fontPtr != NULL) {
	fontPtr->objRefCount++;
    }
}

/*
1598
1599
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609
1610
1611
1612
1613
 */

Font
Tk_FontId(
    Tk_Font tkfont)		/* Font that is going to be selected into
				 * GC. */
{
    TkFont *fontPtr = (TkFont *) tkfont;


    return fontPtr->fid;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetFontMetrics --







|

>







1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
 */

Font
Tk_FontId(
    Tk_Font tkfont)		/* Font that is going to be selected into
				 * GC. */
{
    TkFont *fontPtr;

    fontPtr = (TkFont *) tkfont;
    return fontPtr->fid;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetFontMetrics --
1630
1631
1632
1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644
1645

void
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 = (TkFont *) tkfont;


    fmPtr->ascent = fontPtr->fm.ascent;
    fmPtr->descent = fontPtr->fm.descent;
    fmPtr->linespace = fontPtr->fm.ascent + fontPtr->fm.descent;
}

/*
 *---------------------------------------------------------------------------







|

>







1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629

void
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;

    fontPtr = (TkFont *) tkfont;
    fmPtr->ascent = fontPtr->fm.ascent;
    fmPtr->descent = fontPtr->fm.descent;
    fmPtr->linespace = fontPtr->fm.ascent + fontPtr->fm.descent;
}

/*
 *---------------------------------------------------------------------------
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683

1684
1685
1686
1687
1688
1689
1690
int
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. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    Tk_Uid family, weightString, slantString;
    char *src, *dest;
    int upper, len;

    len = Tcl_DStringLength(dsPtr);


    /*
     * 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.
     */








|





>







1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
int
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. */
{
    TkFont *fontPtr;
    Tk_Uid family, weightString, slantString;
    char *src, *dest;
    int upper, len;

    len = Tcl_DStringLength(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.
     */

1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
    } else if (strcasecmp(family, "AvantGarde") == 0) {
	family = "AvantGarde";
    } else if (strcasecmp(family, "ZapfChancery") == 0) {
	family = "ZapfChancery";
    } else if (strcasecmp(family, "ZapfDingbats") == 0) {
	family = "ZapfDingbats";
    } else {
	int ch;

	/*
	 * 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.
	 */

	Tcl_DStringAppend(dsPtr, family, -1);

	src = dest = Tcl_DStringValue(dsPtr) + len;
	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += TkUtfToUniChar(src, &ch);
	    if (upper) {
		ch = Tcl_UniCharToUpper(ch);
		upper = 0;
	    } else {
		ch = Tcl_UniCharToLower(ch);
	    }
	    dest += TkUniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
    if (family != Tcl_DStringValue(dsPtr) + len) {
	Tcl_DStringAppend(dsPtr, family, -1);







|

















|






|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
    } else if (strcasecmp(family, "AvantGarde") == 0) {
	family = "AvantGarde";
    } else if (strcasecmp(family, "ZapfChancery") == 0) {
	family = "ZapfChancery";
    } else if (strcasecmp(family, "ZapfDingbats") == 0) {
	family = "ZapfDingbats";
    } else {
	Tcl_UniChar ch;

	/*
	 * Inline, capitalize the first letter of each word, lowercase the
	 * rest of the letters in each word, and then take out the spaces
	 * between the words. This may make the DString shorter, which is safe
	 * to do.
	 */

	Tcl_DStringAppend(dsPtr, family, -1);

	src = dest = Tcl_DStringValue(dsPtr) + len;
	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += Tcl_UtfToUniChar(src, &ch);
	    if (upper) {
		ch = Tcl_UniCharToUpper(ch);
		upper = 0;
	    } else {
		ch = Tcl_UniCharToLower(ch);
	    }
	    dest += Tcl_UniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
    if (family != Tcl_DStringValue(dsPtr) + len) {
	Tcl_DStringAppend(dsPtr, family, -1);
1774
1775
1776
1777
1778
1779
1780
1781

1782
1783
1784
1785
1786
1787
1788

    /*
     * Get the string to use for the slant.
     */

    slantString = NULL;
    if (fontPtr->fa.slant == TK_FS_ROMAN) {
	/* Do nothing */

    } else if ((strcmp(family, "Helvetica") == 0)
	    || (strcmp(family, "Courier") == 0)
	    || (strcmp(family, "AvantGarde") == 0)) {
	slantString = "Oblique";
    } else {
	slantString = "Italic";
    }







<
>







1759
1760
1761
1762
1763
1764
1765

1766
1767
1768
1769
1770
1771
1772
1773

    /*
     * Get the string to use for the slant.
     */

    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 {
	slantString = "Italic";
    }
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
	    Tcl_DStringAppend(dsPtr, weightString, -1);
	}
	if (slantString != NULL) {
	    Tcl_DStringAppend(dsPtr, slantString, -1);
	}
    }

    return (int)(fontPtr->fa.size + 0.5);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_TextWidth --
 *







|







1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
	    Tcl_DStringAppend(dsPtr, weightString, -1);
	}
	if (slantString != NULL) {
	    Tcl_DStringAppend(dsPtr, slantString, -1);
	}
    }

    return fontPtr->fa.size;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_TextWidth --
 *
1902
1903
1904
1905
1906
1907
1908
1909
1910


1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
    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 = (TkFont *) tkfont;
    int startX, 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) (endX - startX),
	    (unsigned) fontPtr->underlineHeight);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_ComputeTextLayout --
 *







|

>
>







|
|







1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
    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;

    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),
	    (unsigned int) fontPtr->underlineHeight);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_ComputeTextLayout --
 *
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980

1981
1982
1983
1984
1985
1986
1987
				 * 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 = (TkFont *) tkfont;
    const char *start, *endp, *special;
    int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

    Tcl_DStringInit(&lineBuffer);


    if ((fontPtr == NULL) || (string == NULL)) {
	if (widthPtr != NULL) {
	    *widthPtr = 0;
	}
	if (heightPtr != NULL) {
	    *heightPtr = 0;
	}







|
|









>







1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
				 * 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, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

    Tcl_DStringInit(&lineBuffer);

    fontPtr = (TkFont *) tkfont;
    if ((fontPtr == NULL) || (string == NULL)) {
	if (widthPtr != NULL) {
	    *widthPtr = 0;
	}
	if (heightPtr != NULL) {
	    *heightPtr = 0;
	}
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)ckalloc(offsetof(TextLayout, chunks)
	    + maxChunks * sizeof(LayoutChunk));
    layoutPtr->tkfont = tkfont;
    layoutPtr->string = string;
    layoutPtr->numChunks = 0;

    baseline = fmPtr->ascent;
    maxWidth = 0;

    /*
     * Divide the string up into simple strings and measure each string.
     */

    curX = 0;

    endp = Tcl_UtfAtIndex(string, numChars);
    special = string;

    flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
    flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
    for (start = string; start < endp; ) {
	if (start >= special) {
	    /*
	     * Find the next special character in the string.
	     *
	     * INTL: Note that it is safe to increment by byte, because we are
	     * looking for 7-bit characters that will appear unchanged in
	     * UTF-8. At some point we may need to support the full Unicode
	     * whitespace set.
	     */

	    for (special = start; special < endp; special++) {
		if (!(flags & TK_IGNORE_NEWLINES)) {
		    if ((*special == '\n') || (*special == '\r')) {
			break;
		    }
		}
		if (!(flags & TK_IGNORE_TABS)) {
		    if (*special == '\t') {







|
|













|




|










|







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)
	    ckalloc(sizeof(TextLayout) + (maxChunks-1) * sizeof(LayoutChunk));
    layoutPtr->tkfont = tkfont;
    layoutPtr->string = string;
    layoutPtr->numChunks = 0;

    baseline = fmPtr->ascent;
    maxWidth = 0;

    /*
     * Divide the string up into simple strings and measure each string.
     */

    curX = 0;

    end = Tcl_UtfAtIndex(string, numChars);
    special = string;

    flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
    flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
    for (start = string; start < end; ) {
	if (start >= special) {
	    /*
	     * Find the next special character in the string.
	     *
	     * INTL: Note that it is safe to increment by byte, because we are
	     * looking for 7-bit characters that will appear unchanged in
	     * UTF-8. At some point we may need to support the full Unicode
	     * whitespace set.
	     */

	    for (special = start; special < end; special++) {
		if (!(flags & TK_IGNORE_NEWLINES)) {
		    if ((*special == '\n') || (*special == '\r')) {
			break;
		    }
		}
		if (!(flags & TK_IGNORE_TABS)) {
		    if (*special == '\t') {
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
			bytesThisChunk, curX, newX, baseline);

		start += bytesThisChunk;
		curX = newX;
	    }
	}

	if ((start == special) && (special < endp)) {
	    /*
	     * Handle the special character.
	     *
	     * INTL: Special will be pointing at a 7-bit character so we can
	     * safely treat it as a single byte.
	     */

	    chunkPtr = NULL;
	    if (*special == '\t') {
		newX = curX + fontPtr->tabWidth;
		newX -= newX % fontPtr->tabWidth;
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
			baseline)->numDisplayChars = -1;
		start++;
		curX = newX;
		flags &= ~TK_AT_LEAST_ONE;
		if ((start < endp) &&
			((wrapLength <= 0) || (newX <= wrapLength))) {
		    /*
		     * More chars can still fit on this line.
		     */

		    continue;
		}







|
















|







2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
			bytesThisChunk, curX, newX, baseline);

		start += bytesThisChunk;
		curX = newX;
	    }
	}

	if ((start == special) && (special < end)) {
	    /*
	     * Handle the special character.
	     *
	     * INTL: Special will be pointing at a 7-bit character so we can
	     * safely treat it as a single byte.
	     */

	    chunkPtr = NULL;
	    if (*special == '\t') {
		newX = curX + fontPtr->tabWidth;
		newX -= newX % fontPtr->tabWidth;
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
			baseline)->numDisplayChars = -1;
		start++;
		curX = newX;
		flags &= ~TK_AT_LEAST_ONE;
		if ((start < end) &&
			((wrapLength <= 0) || (newX <= wrapLength))) {
		    /*
		     * More chars can still fit on this line.
		     */

		    continue;
		}
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115

	/*
	 * 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 < endp) && isspace(UCHAR(*start))) { /* INTL: ISO space */
	    if (!(flags & TK_IGNORE_NEWLINES)) {
		if ((*start == '\n') || (*start == '\r')) {
		    break;
		}
	    }
	    if (!(flags & TK_IGNORE_TABS)) {
		if (*start == '\t') {







|







2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103

	/*
	 * 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 */
	    if (!(flags & TK_IGNORE_NEWLINES)) {
		if ((*start == '\n') || (*start == '\r')) {
		    break;
		}
	    }
	    if (!(flags & TK_IGNORE_TABS)) {
		if (*start == '\t') {
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
    }

    /*
     * 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)) {
	if (layoutPtr->chunks[layoutPtr->numChunks - 1].start[0] == '\n') {
	    chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, 0, curX,
		    curX, baseline);
	    chunkPtr->numDisplayChars = -1;
	    Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX));
	    baseline += height;
	}







|







2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
    }

    /*
     * 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)) {
	if (layoutPtr->chunks[layoutPtr->numChunks - 1].start[0] == '\n') {
	    chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, 0, curX,
		    curX, baseline);
	    chunkPtr->numDisplayChars = -1;
	    Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX));
	    baseline += height;
	}
2251
2252
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2267
2268
 *---------------------------------------------------------------------------
 */

void
Tk_FreeTextLayout(
    Tk_TextLayout textLayout)	/* The text layout to be released. */
{
    TextLayout *layoutPtr = (TextLayout *) textLayout;


    if (layoutPtr != NULL) {
	ckfree(layoutPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawTextLayout --







|

>

|







2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
 *---------------------------------------------------------------------------
 */

void
Tk_FreeTextLayout(
    Tk_TextLayout textLayout)	/* The text layout to be released. */
{
    TextLayout *layoutPtr;

    layoutPtr = (TextLayout *) textLayout;
    if (layoutPtr != NULL) {
	ckfree((char *) layoutPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawTextLayout --
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308

2309
2310

2311
2312
2313
2314
2315
2316
2317
 *---------------------------------------------------------------------------
 */

void
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 specifies 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. */
{
#if 0
    /* Use TkDrawAngledTextLayout() implementation - testing purposes at this point */
    TkDrawAngledTextLayout(display, drawable, gc, layout, x, y, 0.0, firstChar, lastChar);
#else
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;

    LayoutChunk *chunkPtr;


    if (layoutPtr == NULL) {
	return;
    }

    if (lastChar < 0) {
	lastChar = 100000000;
    }







|
<





|





<
<
<
<
|

|
>


>







2271
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289




2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
 *---------------------------------------------------------------------------
 */

void
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
				 * 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. */
{




    TextLayout *layoutPtr;
    int i, numDisplayChars, drawX;
    const char *firstByte;
    const char *lastByte;
    LayoutChunk *chunkPtr;

    layoutPtr = (TextLayout *) layout;
    if (layoutPtr == NULL) {
	return;
    }

    if (lastChar < 0) {
	lastChar = 100000000;
    }
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    TkpDrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
		    chunkPtr->start, chunkPtr->numBytes,
		    firstByte - chunkPtr->start, lastByte - firstByte,
		    x+chunkPtr->x, y+chunkPtr->y);
#else /* !TK_DRAW_IN_CONTEXT */
	    Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte,
		    lastByte - firstByte, x+chunkPtr->x+drawX, y+chunkPtr->y);
#endif /* TK_DRAW_IN_CONTEXT */
	}
	firstChar -= chunkPtr->numChars;
	lastChar -= chunkPtr->numChars;
	if (lastChar <= 0) {
	    break;
	}
	chunkPtr++;
    }
#endif /* Use TkDrawAngledTextLayout() implementation */
}

void
TkDrawAngledTextLayout(
    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). */
    double angle,
    int firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specifies 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. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (layoutPtr == NULL) {
	return;
    }

    if (lastChar < 0) {
	lastChar = 100000000;
    }
    chunkPtr = layoutPtr->chunks;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	numDisplayChars = chunkPtr->numDisplayChars;
	if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) {
	    double dx, dy;

	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar);
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    dx = cosA * (chunkPtr->x) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		TkpDrawCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,
			(int)(x + dx), (int)(y + dy));
	    } else {
		TkpDrawAngledCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,
			x+dx, y+dy, angle);
	    }
#else /* !TK_DRAW_IN_CONTEXT */
	    dx = cosA * (chunkPtr->x + drawX) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x + drawX) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont,
			firstByte, lastByte - firstByte,
			(int)(x + dx), (int)(y + dy));
	    } else {
		TkDrawAngledChars(display, drawable, gc, layoutPtr->tkfont,
			firstByte, lastByte - firstByte, x+dx, y+dy, angle);
	    }
#endif /* TK_DRAW_IN_CONTEXT */
	}
	firstChar -= chunkPtr->numChars;
	lastChar -= chunkPtr->numChars;
	if (lastChar <= 0) {
	    break;
	}
	chunkPtr++;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<







2314
2315
2316
2317
2318
2319
2320
























































































2321
2322
2323





2324
2325
2326
2327
2328
2329
2330
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
























































































	    Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont,
		    firstByte, lastByte - firstByte,
		    x + chunkPtr->x + drawX, y + chunkPtr->y);





	}
	firstChar -= chunkPtr->numChars;
	lastChar -= chunkPtr->numChars;
	if (lastChar <= 0) {
	    break;
	}
	chunkPtr++;
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
    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 xx, yy, width, height;

    if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0)
	    && (width != 0)) {
	TextLayout *layoutPtr = (TextLayout *) layout;
	TkFont *fontPtr = (TkFont *) layoutPtr->tkfont;

	XFillRectangle(display, drawable, gc, x + xx,
		y + yy + fontPtr->fm.ascent + fontPtr->underlinePos,
		(unsigned) width, (unsigned) fontPtr->underlineHeight);
    }
}

void
TkUnderlineAngledTextLayout(
    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). */
    double angle,
    int underline)		/* Index of the single character to underline,
				 * or -1 for no underline. */
{
    int xx, yy, width, height;

    if (angle == 0.0) {
	Tk_UnderlineTextLayout(display, drawable, gc, layout, x,y, underline);
	return;
    }

    if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0)
	    && (width != 0)) {
	TextLayout *layoutPtr = (TextLayout *) layout;
	TkFont *fontPtr = (TkFont *) layoutPtr->tkfont;
	double sinA = sin(angle*PI/180), cosA = cos(angle*PI/180);
	double dy = yy + fontPtr->fm.ascent + fontPtr->underlinePos;
	XPoint points[5];

	/*
	 * Note that we're careful to only round a double value once, which
	 * minimizes roundoff errors.
	 */

	points[0].x = x + ROUND16(xx*cosA + dy*sinA);
	points[0].y = y + ROUND16(dy*cosA - xx*sinA);
	points[1].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA);
	points[1].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA);
	if (fontPtr->underlineHeight == 1) {
	    /*
	     * Thin underlines look better when rotated when drawn as a line
	     * rather than a rectangle; the rasterizer copes better.
	     */

	    XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
	} else {
	    points[2].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA
		    + fontPtr->underlineHeight*sinA);
	    points[2].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA
		    + fontPtr->underlineHeight*cosA);
	    points[3].x = x + ROUND16(xx*cosA + dy*sinA
		    + fontPtr->underlineHeight*sinA);
	    points[3].y = y + ROUND16(dy*cosA - xx*sinA
		    + fontPtr->underlineHeight*cosA);
	    points[4].x = points[0].x;
	    points[4].y = points[0].y;
	    XFillPolygon(display, drawable, gc, points, 5, Complex,
		    CoordModeOrigin);
	    XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	}
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_PointToChar --







<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<


|
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<







2362
2363
2364
2365
2366
2367
2368




2369
2370





















2371
2372





2373
2374
2375
2376



2377















2378


2379

2380










2381
2382
2383
2384
2385
2386
2387
    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. */
{




    TextLayout *layoutPtr;
    TkFont *fontPtr;





















    int xx, yy, width, height;






    if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0)
	    && (width != 0)) {
	layoutPtr = (TextLayout *) layout;
	fontPtr = (TkFont *) layoutPtr->tkfont;



















	XFillRectangle(display, drawable, gc, x + xx,


		y + yy + fontPtr->fm.ascent + fontPtr->underlinePos,

		(unsigned int) width, (unsigned int) fontPtr->underlineHeight);










    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_PointToChar --
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609

2610
2611
2612
2613
2614
2615
2616
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 = (TextLayout *) layout;
    LayoutChunk *chunkPtr, *lastPtr;
    TkFont *fontPtr;
    int i, n, dummy, baseline, pos, numChars;

    if (y < 0) {
	/*
	 * Point lies above any line in this layout. Return the index of the
	 * first char.
	 */

	return 0;
    }

    /*
     * Find which line contains the point.
     */


    fontPtr = (TkFont *) layoutPtr->tkfont;
    lastPtr = chunkPtr = layoutPtr->chunks;
    numChars = 0;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	baseline = chunkPtr->y;
	if (y < baseline + fontPtr->fm.descent) {
	    if (x < chunkPtr->x) {







|

















>







2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
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;
    TkFont *fontPtr;
    int i, n, dummy, baseline, pos, numChars;

    if (y < 0) {
	/*
	 * Point lies above any line in this layout. Return the index of the
	 * first char.
	 */

	return 0;
    }

    /*
     * Find which line contains the point.
     */

    layoutPtr = (TextLayout *) layout;
    fontPtr = (TkFont *) layoutPtr->tkfont;
    lastPtr = chunkPtr = layoutPtr->chunks;
    numChars = 0;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	baseline = chunkPtr->y;
	if (y < baseline + fontPtr->fm.descent) {
	    if (x < chunkPtr->x) {
2649
2650
2651
2652
2653
2654
2655
2656

2657
2658
2659
2660
2661
2662
2663
			 * This is a special chunk that encapsulates a single
			 * tab or newline char.
			 */

			return numChars;
		    }
		    n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start,
			    chunkPtr->numBytes, x - chunkPtr->x, 0, &dummy);

		    return numChars + Tcl_NumUtfChars(chunkPtr->start, n);
		}
		numChars += chunkPtr->numChars;
		lastPtr = chunkPtr;
		chunkPtr++;
		i++;
	    }







|
>







2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
			 * This is a special chunk that encapsulates a single
			 * tab or newline char.
			 */

			return numChars;
		    }
		    n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start,
			    chunkPtr->numBytes, x - chunkPtr->x,
			    0, &dummy);
		    return numChars + Tcl_NumUtfChars(chunkPtr->start, n);
		}
		numChars += chunkPtr->numChars;
		lastPtr = chunkPtr;
		chunkPtr++;
		i++;
	    }
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749


2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
				 * 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 = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	return 0;
    }



    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {
	    if (index == 0) {
		x = chunkPtr->x;
		w = chunkPtr->totalWidth;
		goto check;
	    }
	} else if (index < chunkPtr->numChars) {
	    end = Tcl_UtfAtIndex(chunkPtr->start, index);
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {
		int ch;
		Tk_MeasureChars(tkfont, end, TkUtfToUniChar(end, &ch), -1, 0, &w);

	    }
	    goto check;
	}
	index -= chunkPtr->numChars;
	chunkPtr++;
    }
    if (index != 0) {







|
|









>
>


















<
|
>







2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603

2604
2605
2606
2607
2608
2609
2610
2611
2612
				 * 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 = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	return 0;
    }

    layoutPtr = (TextLayout *) layout;
    chunkPtr = layoutPtr->chunks;
    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {
	    if (index == 0) {
		x = chunkPtr->x;
		w = chunkPtr->totalWidth;
		goto check;
	    }
	} else if (index < chunkPtr->numChars) {
	    end = Tcl_UtfAtIndex(chunkPtr->start, index);
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {

		Tk_MeasureChars(tkfont, end, Tcl_UtfNext(end) - end,
			-1, 0, &w);
	    }
	    goto check;
	}
	index -= chunkPtr->numChars;
	chunkPtr++;
    }
    if (index != 0) {
2842
2843
2844
2845
2846
2847
2848
2849
2850

2851
2852

2853
2854
2855
2856
2857
2858
2859
    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
				 * (in pixels). */
{
    int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent;
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;

    TkFont *fontPtr;


    fontPtr = (TkFont *) layoutPtr->tkfont;
    ascent = fontPtr->fm.ascent;
    descent = fontPtr->fm.descent;

    minDist = 0;
    chunkPtr = layoutPtr->chunks;
    for (i = 0; i < layoutPtr->numChunks; i++) {







<

>


>







2678
2679
2680
2681
2682
2683
2684

2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
    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
				 * (in pixels). */
{
    int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent;

    LayoutChunk *chunkPtr;
    TextLayout *layoutPtr;
    TkFont *fontPtr;

    layoutPtr = (TextLayout *) layout;
    fontPtr = (TkFont *) layoutPtr->tkfont;
    ascent = fontPtr->fm.ascent;
    descent = fontPtr->fm.descent;

    minDist = 0;
    chunkPtr = layoutPtr->chunks;
    for (i = 0; i < layoutPtr->numChunks; i++) {
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947

2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
				 * 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;
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;
    TkFont *fontPtr;
    int left, top, right, bottom;

    /*
     * 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.
     */


    chunkPtr = layoutPtr->chunks;
    fontPtr = (TkFont *) layoutPtr->tkfont;

    left = x;
    top = y;
    right = x + width;
    bottom = y + height;

    result = 0;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	if ((chunkPtr->start[0] == '\n') || (chunkPtr->numBytes == 0)) {
	    /*
	     * Newline characters and empty chunks are not counted when
	     * computing area intersection (but tab characters would still be
	     * considered).
	     */

	    chunkPtr++;
	    continue;
	}

	x1 = chunkPtr->x;







|











>










|

|
|
<







2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802
2803
2804
2805
2806
				 * 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;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    TkFont *fontPtr;
    int left, top, right, bottom;

    /*
     * 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.
     */

    layoutPtr = (TextLayout *) layout;
    chunkPtr = layoutPtr->chunks;
    fontPtr = (TkFont *) layoutPtr->tkfont;

    left = x;
    top = y;
    right = x + width;
    bottom = y + height;

    result = 0;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->start[0] == '\n') {
	    /*
	     * Newline characters are not counted when computing area
	     * intersection (but tab characters would still be considered).

	     */

	    chunkPtr++;
	    continue;
	}

	x1 = chunkPtr->x;
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
	} else {
	    result = 1;
	}
	chunkPtr++;
    }
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkIntersectAngledTextLayout --
 *
 *	Determines whether a text layout that has been turned by an angle
 *	about its top-left coordinae 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.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static inline int
PointInQuadrilateral(
    double qx[],
    double qy[],
    double x,
    double y)
{
    int i;

    for (i=0 ; i<4 ; i++) {
	double sideDX = qx[(i+1)%4] - qx[i];
	double sideDY = qy[(i+1)%4] - qy[i];
	double dx = x - qx[i];
	double dy = y - qy[i];

	if (sideDX*dy < sideDY*dx) {
	    return 0;
	}
    }
    return 1;
}

static inline int
SidesIntersect(
    double ax1, double ay1, double ax2, double ay2,
    double bx1, double by1, double bx2, double by2)
{
#if 0
/* http://www.freelunchdesign.com/cgi-bin/codwiki.pl?DiscussionTopics/CollideMeUpBaby */

    double a1, b1, c1, a2, b2, c2, r1, r2, r3, r4, denom;

    a1 = ay2 - ay1;
    b1 = ax1 - ax2;
    c1 = (ax2 * ay1) - (ax1 * ay2);
    r3 = (a1 * bx1) + (b1 * by1) + c1;
    r4 = (a1 * bx2) + (b1 * by2) + c1;
    if ((r3 != 0.0) && (r4 != 0.0) && (r3*r4 > 0.0)) {
	return 0;
    }

    a2 = by2 - by1;
    b2 = bx1 - bx2;
    c2 = (bx2 * by1) - (bx1 * by2);
    r1 = (a2 * ax1) + (b2 * ay1) + c2;
    r2 = (a2 * ax2) + (b2 * ay2) + c2;
    if ((r1 != 0.0) && (r2 != 0.0) && (r1*r2 > 0.0)) {
	return 0;
    }

    denom = (a1 * b2) - (a2 * b1);
    return (denom != 0.0);
#else
    /*
     * A more efficient version. Two line segments intersect if, when seen
     * from the perspective of one line, the two endpoints of the other
     * segment lie on opposite sides of the line, and vice versa. "Lie on
     * opposite sides" is computed by taking the cross products and seeing if
     * they are of opposite signs.
     */

    double dx, dy, dx1, dy1;

    dx = ax2 - ax1;
    dy = ay2 - ay1;
    dx1 = bx1 - ax1;
    dy1 = by1 - ay1;
    if ((dx*dy1-dy*dx1 > 0.0) == (dx*(by2-ay1)-dy*(bx2-ax1) > 0.0)) {
	return 0;
    }
    dx = bx2 - bx1;
    dy = by2 - by1;
    if ((dy*dx1-dx*dy1 > 0.0) == (dx*(ay2-by1)-dy*(ax2-bx1) > 0.0)) {
	return 0;
    }
    return 1;
#endif
}

int
TkIntersectAngledTextLayout(
    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, int height,	/* The width and height of the above
				 * rectangular area, in pixels. */
    double angle)
{
    int i, x1, y1, x2, y2;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    TkFont *fontPtr;
    double c = cos(angle * PI/180.0), s = sin(angle * PI/180.0);
    double rx[4], ry[4];

    if (angle == 0.0) {
	return Tk_IntersectTextLayout(layout, x, y, width, height);
    }

    /*
     * Compute the coordinates of the rectangle, rotated into text layout
     * space.
     */

    rx[0] = x*c - y*s;
    ry[0] = y*c + x*s;
    rx[1] = (x+width)*c - y*s;
    ry[1] = y*c + (x+width)*s;
    rx[2] = (x+width)*c - (y+height)*s;
    ry[2] = (y+height)*c + (x+width)*s;
    rx[3] = x*c - (y+height)*s;
    ry[3] = (y+height)*c + x*s;

    /*
     * Want to know if all chunks are inside the rectangle, or if there is any
     * overlap. First, we check to see if all chunks are inside; if and only
     * if they are, we're in the "inside" case.
     */

    layoutPtr = (TextLayout *) layout;
    chunkPtr = layoutPtr->chunks;
    fontPtr = (TkFont *) layoutPtr->tkfont;

    for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
	if (chunkPtr->start[0] == '\n') {
	    /*
	     * Newline characters are not counted when computing area
	     * intersection (but tab characters would still be considered).
	     */

	    continue;
	}

	x1 = chunkPtr->x;
	y1 = chunkPtr->y - fontPtr->fm.ascent;
	x2 = chunkPtr->x + chunkPtr->displayWidth;
	y2 = chunkPtr->y + fontPtr->fm.descent;
	if (	!PointInQuadrilateral(rx, ry, x1, y1) ||
		!PointInQuadrilateral(rx, ry, x2, y1) ||
		!PointInQuadrilateral(rx, ry, x2, y2) ||
		!PointInQuadrilateral(rx, ry, x1, y2)) {
	    goto notInside;
	}
    }
    return 1;

    /*
     * Next, check to see if all the points of the rectangle are inside a
     * single chunk; if they are, we're in an "overlap" case.
     */

  notInside:
    chunkPtr = layoutPtr->chunks;

    for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
	double cx[4], cy[4];

	if (chunkPtr->start[0] == '\n') {
	    /*
	     * Newline characters are not counted when computing area
	     * intersection (but tab characters would still be considered).
	     */

	    continue;
	}

	cx[0] = cx[3] = chunkPtr->x;
	cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent;
	cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth;
	cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent;
	if (	PointInQuadrilateral(cx, cy, rx[0], ry[0]) &&
		PointInQuadrilateral(cx, cy, rx[1], ry[1]) &&
		PointInQuadrilateral(cx, cy, rx[2], ry[2]) &&
		PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
            return 0;
        }
    }

    /*
     * If we're overlapping now, we must be partially in and out of at least
     * one chunk. If that is the case, there must be one line segment of the
     * rectangle that is touching or crossing a line segment of a chunk.
     */

    chunkPtr = layoutPtr->chunks;

    for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
	int j;

	if (chunkPtr->start[0] == '\n') {
	    /*
	     * Newline characters are not counted when computing area
	     * intersection (but tab characters would still be considered).
	     */

	    continue;
	}

	x1 = chunkPtr->x;
	y1 = chunkPtr->y - fontPtr->fm.ascent;
	x2 = chunkPtr->x + chunkPtr->displayWidth;
	y2 = chunkPtr->y + fontPtr->fm.descent;

	for (j=0 ; j<4 ; j++) {
	    int k = (j+1) % 4;

	    if (    SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y1, x2,y1) ||
		    SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y1, x2,y2) ||
		    SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y2, x1,y2) ||
		    SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y2, x1,y1)) {
		return 0;
	    }
	}
    }

    /*
     * They must be wholly non-overlapping.
     */

    return -1;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_TextLayoutToPostscript --
 *
 *	Outputs the contents of a text layout in Postscript format. The set of







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2822
2823
2824
2825
2826
2827
2828
























































































































































































































































2829
2830
2831
2832
2833
2834
2835
	} else {
	    result = 1;
	}
	chunkPtr++;
    }
    return result;
}

























































































































































































































































/*
 *---------------------------------------------------------------------------
 *
 * Tk_TextLayoutToPostscript --
 *
 *	Outputs the contents of a text layout in Postscript format. The set of
3277
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289

3290
3291

3292
3293

3294




3295
3296
3297





3298
3299
3300
3301
3302

3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314

3315





3316

3317
3318
3319

3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351


3352
3353





3354



3355

3356
3357
3358


3359
3360
3361
3362
3363
3364
3365

3366
3367
3368
3369
3370

3371
3372


3373

3374
3375
3376
3377
3378
3379
3380
3381
3382
 */

void
Tk_TextLayoutToPostscript(
    Tcl_Interp *interp,		/* Filled with Postscript code. */
    Tk_TextLayout layout)	/* The layout to be rendered. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;

    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int baseline = chunkPtr->y;
    Tcl_Obj *psObj = Tcl_NewObj();
    int i, j;
    TkSizeT len;

    const char *p, *glyphname;
    char uindex[5], c, *ps;

    int ch;


    Tcl_AppendToObj(psObj, "[(", -1);




    for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) {
	if (baseline != chunkPtr->y) {
	    Tcl_AppendToObj(psObj, ")]\n[(", -1);





	    baseline = chunkPtr->y;
	}
	if (chunkPtr->numDisplayChars <= 0) {
	    if (chunkPtr->start[0] == '\t') {
		Tcl_AppendToObj(psObj, "\\t", -1);

	    }
	    continue;
	}

	for (p=chunkPtr->start, j=0; j<chunkPtr->numDisplayChars; j++) {
	    /*
	     * INTL: We only handle symbols that have an encoding as a glyph
	     * from the standard set defined by Adobe. The rest get punted.
	     * Eventually this should be revised to handle more sophsticiated
	     * international postscript fonts.
	     */


	    p += TkUtfToUniChar(p, &ch);





	    if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) {

		/*
		 * 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 following this sequence could be
		 * interpreted by Postscript as part of this sequence.
		 */

		Tcl_AppendPrintfToObj(psObj, "\\%03o", ch);
		continue;
	    } else if (ch <= 0x7f) {
		/*
		 * Normal ASCII character.
		 */

		c = (char) ch;
		Tcl_AppendToObj(psObj, &c, 1);
		continue;
	    }

	    /*
	     * This character doesn't belong to the ASCII character set, so we
	     * use the full glyph name.
	     */

	    if (ch > 0xffff) {
		goto noMapping;
	    }
	    sprintf(uindex, "%04X", ch);		/* endianness? */
	    glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0);
	    if (glyphname) {
		ps = TkGetStringFromObj(psObj, &len);
		if (ps[len-1] == '(') {
		    /*
		     * In-place edit. Ewww!
		     */



		    ps[len-1] = '/';





		} else {



		    Tcl_AppendToObj(psObj, ")/", -1);

		}
		Tcl_AppendToObj(psObj, glyphname, -1);
		Tcl_AppendToObj(psObj, "(", -1);


	    } else {
		/*
		 * No known mapping for the character into the space of
		 * PostScript glyphs. Ignore it. :-(
		 */
noMapping:	;


#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT
		fprintf(stderr, "Warning: no mapping to PostScript "
			"glyphs for \\u%04x\n", ch);
#endif
	    }

	}
    }


    Tcl_AppendToObj(psObj, ")]\n", -1);

    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
}

/*
 *---------------------------------------------------------------------------
 *
 * ConfigAttributesObj --
 *







|
>
|
<
<
|
<
>
|
<
>
|

>
|
>
>
>
>
|

<
>
>
>
>
>




|
>

<
|
|
|
|
|
<
|
|
|

>
|
>
>
>
>
>
|
>
|
|
|
>
|
|
|

|
|
|
<
<
<
|
<
<
<
|
|
|
|
|
|

<
<
<
|
|
|
<
|
<
|
<
>
>
|
|
>
>
>
>
>
|
>
>
>
|
>

<
<
>
>
|
|
|
|
|
<

>
|
<
<
|
|
>
|
<
>
>
|
>
|
<







2866
2867
2868
2869
2870
2871
2872
2873
2874
2875


2876

2877
2878

2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889

2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901

2902
2903
2904
2905
2906

2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930



2931



2932
2933
2934
2935
2936
2937
2938



2939
2940
2941

2942

2943

2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959


2960
2961
2962
2963
2964
2965
2966

2967
2968
2969


2970
2971
2972
2973

2974
2975
2976
2977
2978

2979
2980
2981
2982
2983
2984
2985
 */

void
Tk_TextLayoutToPostscript(
    Tcl_Interp *interp,		/* Filled with Postscript code. */
    Tk_TextLayout layout)	/* The layout to be rendered. */
{
#define MAXUSE 128
    char buf[MAXUSE+30], uindex[5] = "\0\0\0\0", one_char[5];
    LayoutChunk *chunkPtr;


    int i, j, used, c, baseline, charsize;

    Tcl_UniChar ch;
    const char *p, *last_p, *glyphname;

    TextLayout *layoutPtr;
    int bytecount=0;

    layoutPtr = (TextLayout *) layout;
    chunkPtr = layoutPtr->chunks;
    baseline = chunkPtr->y;
    used = 0;
    buf[used++] = '[';
    buf[used++] = '(';
    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (baseline != chunkPtr->y) {

	    buf[used++] = ')';
	    buf[used++] = ']';
	    buf[used++] = '\n';
	    buf[used++] = '[';
	    buf[used++] = '(';
	    baseline = chunkPtr->y;
	}
	if (chunkPtr->numDisplayChars <= 0) {
	    if (chunkPtr->start[0] == '\t') {
		buf[used++] = '\\';
		buf[used++] = 't';
	    }

	} else {
	    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.
		 */

		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
			 * below, so that a full three digits of octal are
			 * always generated. Without the "03", a number
			 * following this sequence could be interpreted by
			 * Postscript as part of this sequence.
			 */

			sprintf(buf + used, "\\%03o", c);
			used += 4;
		    } else {



			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? */
		    glyphname = Tcl_GetVar2(interp,"::tk::psglyphs",uindex,0);
		    if (glyphname) {

			if (used > 0 && buf [used-1] == '(') {

			    --used;

			} else {
			    buf[used++] = ')';
			}
			buf[used++] = '/';
			while ((*glyphname) && (used < (MAXUSE+27))) {
			    buf[used++] = *glyphname++ ;
			}
			buf[used++] = '(';
		    }

		}
		if (used >= MAXUSE) {
		    buf[used] = '\0';
		    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.
	     */


	    buf[used] = '\0';
	    Tcl_AppendResult(interp, buf, NULL);


	    used = 0;
	}
	chunkPtr++;
    }

    buf[used++] = ')';
    buf[used++] = ']';
    buf[used++] = '\n';
    buf[used] = '\0';
    Tcl_AppendResult(interp, buf, NULL);

}

/*
 *---------------------------------------------------------------------------
 *
 * ConfigAttributesObj --
 *
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
 *
 *---------------------------------------------------------------------------
 */

static int
ConfigAttributesObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    TCL_UNUSED(Tk_Window),	/* 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;
    const char *value;

    for (i = 0; i < objc; i += 2) {
	optionPtr = objv[i];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	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.
	     */

	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" option missing",
			Tcl_GetString(optionPtr)));
		Tcl_SetErrorCode(interp, "TK", "FONT", "NO_ATTRIBUTE", NULL);
	    }
	    return TCL_ERROR;
	}
	valuePtr = objv[i + 1];

	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 = (double)n;
	    break;
	case FONT_WEIGHT:
	    n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr);
	    if (n == TK_FW_UNKNOWN) {
		return TCL_ERROR;
	    }
	    faPtr->weight = n;







|








|
















|
<
|
<














|







2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031

3032

3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
 *
 *---------------------------------------------------------------------------
 */

static int
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];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	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.
	     */

	    if (interp != NULL) {
		Tcl_AppendResult(interp, "value for \"",

			Tcl_GetString(optionPtr), "\" option missing", NULL);

	    }
	    return TCL_ERROR;
	}
	valuePtr = objv[i + 1];

	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_WEIGHT:
	    n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr);
	    if (n == TK_FW_UNKNOWN) {
		return TCL_ERROR;
	    }
	    faPtr->weight = n;
3505
3506
3507
3508
3509
3510
3511
3512


3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
				/* 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;
    Tcl_Obj *valuePtr, *resultPtr = NULL;



    start = 0;
    end = FONT_NUMFIELDS;
    if (objPtr != NULL) {
	if (Tcl_GetIndexFromObj(interp, objPtr, fontOpt, "option", TCL_EXACT,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	start = index;
	end = index + 1;
    }

    valuePtr = NULL;
    if (objPtr == NULL) {
	resultPtr = Tcl_NewObj();
    }
    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_SIZE:
	    if (faPtr->size >= 0.0) {
		valuePtr = Tcl_NewWideIntObj((Tcl_WideInt)(faPtr->size + 0.5));
	    } else {
		valuePtr = Tcl_NewWideIntObj(-(Tcl_WideInt)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;








|
>
>













<
<
<








|
<
<
<
<







3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128



3129
3130
3131
3132
3133
3134
3135
3136
3137




3138
3139
3140
3141
3142
3143
3144
				/* 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;
    Tcl_Obj *optionPtr, *valuePtr, *resultPtr;

    resultPtr = Tcl_GetObjResult(interp);

    start = 0;
    end = FONT_NUMFIELDS;
    if (objPtr != NULL) {
	if (Tcl_GetIndexFromObj(interp, objPtr, fontOpt, "option", TCL_EXACT,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	start = index;
	end = index + 1;
    }

    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_SIZE:
	    valuePtr = Tcl_NewIntObj(faPtr->size);




	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;

3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
	    valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
	    break;
	}
	if (objPtr != NULL) {
	    Tcl_SetObjResult(interp, valuePtr);
	    return TCL_OK;
	}
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj(fontOpt[i], -1));
	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FontGetDescription --
 *
 *	Return information about the font description as a Tcl list. One
 *	possible result is "{{DejaVu Sans} -16 bold underline}".
 *
 * Results:
 *	The list of descriptions.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Obj *
Tk_FontGetDescription(
    Tk_Font tkfont)		/* Font whose description is desired. */
{
    const TkFontAttributes *faPtr = GetFontAttributes(tkfont);
    Tcl_Obj *resultPtr = Tcl_NewObj();
    const char *str;

    str = faPtr->family;
    Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, str ? -1 : 0));
    if (faPtr->size >= 0.0) {
    	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewWideIntObj((int)(faPtr->size + 0.5)));
    } else {
    	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewWideIntObj(-(int)(-faPtr->size + 0.5)));
    }
    if (faPtr->weight != TK_FW_NORMAL) {
	str = TkFindStateString(weightMap, faPtr->weight);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->slant != TK_FS_ROMAN) {
	str = TkFindStateString(slantMap, faPtr->slant);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->underline) {
	str = TkFindStateString(underlineMap, faPtr->underline);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->overstrike) {
	str = TkFindStateString(overstrikeMap, faPtr->overstrike);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * ParseFontNameObj --
 *
 *	Converts a object into a set of font attributes that can be used to







<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|








3155
3156
3157
3158
3159
3160
3161

3162
3163































3164




3165
















3166
3167
3168
3169
3170
3171
3172
3173
3174
	    valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
	    break;
	}
	if (objPtr != NULL) {
	    Tcl_SetObjResult(interp, valuePtr);
	    return TCL_OK;
	}

	optionPtr = Tcl_NewStringObj(fontOpt[i], -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, optionPtr);































	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);




    }
















    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * ParseFontNameObj --
 *
 *	Converts a object into a set of font attributes that can be used to
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int objc, result, i, n;
    Tcl_Obj **objv;
    const char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {
	/*
	 * 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.
	 */

	if (string[1] == '*') {
	    goto xlfd;
	}
	dash = strchr(string + 1, '-');
	if ((dash != NULL)
		&& !isspace(UCHAR(dash[-1]))) {	/* INTL: ISO space */
	    goto xlfd;
	}

	if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
	    return TCL_ERROR;
	}








|

















|







3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int objc, result, i, n;
    Tcl_Obj **objv;
    char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {
	/*
	 * 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.
	 */

	if (string[1] == '*') {
	    goto xlfd;
	}
	dash = strchr(string + 1, '-');
	if ((dash != NULL)
		&& (!isspace(UCHAR(dash[-1])))) { /* INTL: ISO space */
	    goto xlfd;
	}

	if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
	    return TCL_ERROR;
	}

3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
     * 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_SetObjResult(interp, Tcl_ObjPrintf(
		    "font \"%s\" doesn't exist", string));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, NULL);
	}
	return TCL_ERROR;
    }

    faPtr->family = Tk_GetUid(Tcl_GetString(objv[0]));
    if (objc > 1) {
	if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) {
	    return TCL_ERROR;
	}
	faPtr->size = (double)n;
    }

    i = 2;
    if (objc == 3) {
	if (Tcl_ListObjGetElements(interp, objv[2], &objc, &objv) != TCL_OK) {
	    return TCL_ERROR;
	}







|
<
|









|







3266
3267
3268
3269
3270
3271
3272
3273

3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
     * 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",

		    NULL);
	}
	return TCL_ERROR;
    }

    faPtr->family = Tk_GetUid(Tcl_GetString(objv[0]));
    if (objc > 1) {
	if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) {
	    return TCL_ERROR;
	}
	faPtr->size = n;
    }

    i = 2;
    if (objc == 3) {
	if (Tcl_ListObjGetElements(interp, objv[2], &objc, &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
	}

	/*
	 * Unknown style.
	 */

	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "unknown font style \"%s\"", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT_STYLE",
		    Tcl_GetString(objv[i]), NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







<
|
<
|







3314
3315
3316
3317
3318
3319
3320

3321

3322
3323
3324
3325
3326
3327
3328
3329
	}

	/*
	 * Unknown style.
	 */

	if (interp != NULL) {

	    Tcl_AppendResult(interp, "unknown font style \"",

		    Tcl_GetString(objv[i]), "\"", NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = offsetof(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *)ckrealloc(layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];
    chunkPtr->start		= start;







|
|







3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *) ckrealloc((char *) layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];
    chunkPtr->start		= start;
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908

    str = string;
    if (*str == '-') {
	str++;
    }

    Tcl_DStringInit(&ds);
    Tcl_DStringAppend(&ds, str, -1);
    src = Tcl_DStringValue(&ds);

    field[0] = src;
    for (i = 0; *src != '\0'; src++) {
	if (!(*src & 0x80)
		&& Tcl_UniCharIsUpper(UCHAR(*src))) {
	    *src = (char) Tcl_UniCharToLower(UCHAR(*src));







|







3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449

    str = string;
    if (*str == '-') {
	str++;
    }

    Tcl_DStringInit(&ds);
    Tcl_DStringAppend(&ds, (char *) str, -1);
    src = Tcl_DStringValue(&ds);

    field[0] = src;
    for (i = 0; *src != '\0'; src++) {
	if (!(*src & 0x80)
		&& Tcl_UniCharIsUpper(UCHAR(*src))) {
	    *src = (char) Tcl_UniCharToLower(UCHAR(*src));
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
     * 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])) {
	if (atoi(field[XLFD_ADD_STYLE]) != 0) {
	    for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) {
		field[j + 1] = field[j];
	    }
	    field[XLFD_ADD_STYLE] = NULL;
	    i++;
	}







|







3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
     * 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]))) {
	if (atoi(field[XLFD_ADD_STYLE]) != 0) {
	    for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) {
		field[j + 1] = field[j];
	    }
	    field[XLFD_ADD_STYLE] = NULL;
	    i++;
	}
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
    /* XLFD_ADD_STYLE ignored. */

    /*
     * Pointsize in tenths of a point, but treat it as tenths of a pixel for
     * historical compatibility.
     */

    faPtr->size = 12.0;

    if (FieldSpecified(field[XLFD_POINT_SIZE])) {
	if (field[XLFD_POINT_SIZE][0] == '[') {
	    /*
	     * Some X fonts have the point size specified as follows:
	     *
	     *	    [ N1 N2 N3 N4 ]
	     *
	     * where N1 is the point size (in points, not decipoints!), and
	     * N2, N3, and N4 are some additional numbers that I don't know
	     * the purpose of, so I ignore them.
	     */

	    faPtr->size = atof(field[XLFD_POINT_SIZE] + 1);
	} else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE],
		&i) == TCL_OK) {
	    faPtr->size = i/10.0;
	} else {
	    return TCL_ERROR;
	}
    }

    /*
     * Pixel height of font. If specified, overrides pointsize.







|













|

|
|







3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
    /* XLFD_ADD_STYLE ignored. */

    /*
     * Pointsize in tenths of a point, but treat it as tenths of a pixel for
     * historical compatibility.
     */

    faPtr->size = 12;

    if (FieldSpecified(field[XLFD_POINT_SIZE])) {
	if (field[XLFD_POINT_SIZE][0] == '[') {
	    /*
	     * Some X fonts have the point size specified as follows:
	     *
	     *	    [ N1 N2 N3 N4 ]
	     *
	     * where N1 is the point size (in points, not decipoints!), and
	     * 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_POINT_SIZE] + 1);
	} else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE],
		&faPtr->size) == TCL_OK) {
	    faPtr->size /= 10;
	} else {
	    return TCL_ERROR;
	}
    }

    /*
     * Pixel height of font. If specified, overrides pointsize.
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
	     *	    [ 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.
	     */

	    faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1);
	} else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE],
		&i) == TCL_OK) {
	    faPtr->size = (double)i;
	} else {
	    return TCL_ERROR;
	}
    }

    faPtr->size = -faPtr->size;

    /* XLFD_RESOLUTION_X ignored. */







|

|
<
<







3558
3559
3560
3561
3562
3563
3564
3565
3566
3567


3568
3569
3570
3571
3572
3573
3574
	     *	    [ 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.
	     */

	    faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1);
	} else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE],
		&faPtr->size) != TCL_OK) {


	    return TCL_ERROR;
	}
    }

    faPtr->size = -faPtr->size;

    /* XLFD_RESOLUTION_X ignored. */
4097
4098
4099
4100
4101
4102
4103
4104

4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138

4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164

4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

double

TkFontGetPixels(
    Tk_Window tkwin,		/* For point->pixel conversion factor. */
    double size)		/* Font size. */
{
    double d;

    if (size <= 0.0) {
	return -size;
    }

    d = size * 25.4 / 72.0;
    d *= WidthOfScreen(Tk_Screen(tkwin));
    d /= WidthMMOfScreen(Tk_Screen(tkwin));
    return d;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkFontGetPoints --
 *
 *	Given a font size specification (as described in the TkFontAttributes
 *	structure) return the number of points it represents.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

double

TkFontGetPoints(
    Tk_Window tkwin,		/* For pixel->point conversion factor. */
    double size)		/* Font size. */
{
    double d;

    if (size >= 0.0) {
	return size;
    }

    d = -size * 72.0 / 25.4;
    d *= WidthMMOfScreen(Tk_Screen(tkwin));
    d /= WidthOfScreen(Tk_Screen(tkwin));
    return d;
}

/*
 *-------------------------------------------------------------------------
 *
 * TkFontGetAliasList --
 *
 *	Given a font name, find the list of all aliases for that font name.
 *	One of the names in this list will probably be the name that this
 *	platform expects when asking for the font.
 *
 * Results:

 *	As above. The return value is NULL if the font name has no aliases.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

const char *const *
TkFontGetAliasList(
    const char *faceName)	/* Font name to test for aliases. */
{
    int i, j;

    for (i = 0; fontAliases[i] != NULL; i++) {
	for (j = 0; fontAliases[i][j] != NULL; j++) {







<
>


|



|






|



















<
>


|



|






|












>








|







3636
3637
3638
3639
3640
3641
3642

3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676

3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */


int
TkFontGetPixels(
    Tk_Window tkwin,		/* For point->pixel conversion factor. */
    int size)			/* Font size. */
{
    double d;

    if (size < 0) {
	return -size;
    }

    d = size * 25.4 / 72.0;
    d *= WidthOfScreen(Tk_Screen(tkwin));
    d /= WidthMMOfScreen(Tk_Screen(tkwin));
    return (int) (d + 0.5);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkFontGetPoints --
 *
 *	Given a font size specification (as described in the TkFontAttributes
 *	structure) return the number of points it represents.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */


int
TkFontGetPoints(
    Tk_Window tkwin,		/* For pixel->point conversion factor. */
    int size)			/* Font size. */
{
    double d;

    if (size >= 0) {
	return size;
    }

    d = -size * 72.0 / 25.4;
    d *= WidthMMOfScreen(Tk_Screen(tkwin));
    d /= WidthOfScreen(Tk_Screen(tkwin));
    return (int) (d + 0.5);
}

/*
 *-------------------------------------------------------------------------
 *
 * TkFontGetAliasList --
 *
 *	Given a font name, find the list of all aliases for that font name.
 *	One of the names in this list will probably be the name that this
 *	platform expects when asking for the font.
 *
 * Results:

 *	As above. The return value is NULL if the font name has no aliases.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char **
TkFontGetAliasList(
    const char *faceName)	/* Font name to test for aliases. */
{
    int i, j;

    for (i = 0; fontAliases[i] != NULL; i++) {
	for (j = 0; fontAliases[i][j] != NULL; j++) {
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

const char *const *const *
TkFontGetFallbacks(void)
{
    return fontFallbacks;
}

/*
 *-------------------------------------------------------------------------







|







3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char ***
TkFontGetFallbacks(void)
{
    return fontFallbacks;
}

/*
 *-------------------------------------------------------------------------
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

const char *const *
TkFontGetGlobalClass(void)
{
    return globalFontClass;
}

/*
 *-------------------------------------------------------------------------







|







3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char **
TkFontGetGlobalClass(void)
{
    return globalFontClass;
}

/*
 *-------------------------------------------------------------------------
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

const char *const *
TkFontGetSymbolClass(void)
{
    return symbolClass;
}

/*
 *----------------------------------------------------------------------







|







3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char **
TkFontGetSymbolClass(void)
{
    return symbolClass;
}

/*
 *----------------------------------------------------------------------
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugFont(
    Tk_Window tkwin,		/* The window in which the font will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{
    TkFont *fontPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(
	    &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name);
    if (hashPtr != NULL) {
	fontPtr = (TkFont *)Tcl_GetHashValue(hashPtr);
	if (fontPtr == NULL) {
	    Tcl_Panic("TkDebugFont found empty hash table entry");
	}
	for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(fontPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(fontPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*







|









|






|

|







3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
 *----------------------------------------------------------------------
 */

Tcl_Obj *
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;
    Tcl_Obj *resultPtr, *objPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(
	    &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name);
    if (hashPtr != NULL) {
	fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr);
	if (fontPtr == NULL) {
	    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_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337

4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
int
TkFontGetFirstTextLayout(
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    Tk_Font *font,
    char *dst)
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;
    int numBytesInChunk;


    if ((layoutPtr == NULL) || (layoutPtr->numChunks == 0)
	    || (layoutPtr->chunks->numDisplayChars <= 0)) {
	dst[0] = '\0';
	return 0;
    }
    chunkPtr = layoutPtr->chunks;
    numBytesInChunk = chunkPtr->numBytes;
    strncpy(dst, chunkPtr->start, numBytesInChunk);
    *font = layoutPtr->tkfont;
    return numBytesInChunk;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



>
|






|











3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
int
TkFontGetFirstTextLayout(
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    Tk_Font *font,
    char *dst)
{
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    int numBytesInChunk;

    layoutPtr = (TextLayout *)layout;
    if ((layoutPtr==NULL) || (layoutPtr->numChunks==0)
	    || (layoutPtr->chunks->numDisplayChars <= 0)) {
	dst[0] = '\0';
	return 0;
    }
    chunkPtr = layoutPtr->chunks;
    numBytesInChunk = chunkPtr->numBytes;
    strncpy(dst, chunkPtr->start, (size_t) numBytesInChunk);
    *font = layoutPtr->tkfont;
    return numBytesInChunk;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkFont.h.

10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 * 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 __cplusplus
extern "C" {

#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
 * attributes gotten when the font was instantiated.
 */

struct TkFontAttributes {
    Tk_Uid family;		/* Font family, or NULL to represent plaform-
				 * specific default system font. */
    double size;		/* Pointsize of font, 0.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. */
};








|
|
>











|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * 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
#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
 * attributes gotten when the font was instantiated.
 */

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. */
};

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    TkSizeT 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. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
				 * used when deleting it. */
    Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that
				 * corresponds to the named font that the
				 * tkfont was based on, or NULL if the tkfont
				 * was not based on a named font. */







|









|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    int resourceRefCount;	/* Number of active uses of this font (each
				 * active use corresponds to a call to
				 * Tk_AllocFontFromTable or Tk_GetFont). If
				 * this count is 0, then this TkFont structure
				 * is no longer valid and it isn't present in
				 * a hash table: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when
				 * resourceRefCount and objRefCount are both
				 * 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
				 * used when deleting it. */
    Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that
				 * corresponds to the named font that the
				 * tkfont was based on, or NULL if the tkfont
				 * was not based on a named font. */
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
#define XLFD_RESOLUTION_X   8
#define XLFD_RESOLUTION_Y   9
#define XLFD_SPACING	    10
#define XLFD_AVERAGE_WIDTH  11
#define XLFD_CHARSET	    12
#define XLFD_NUMFIELDS	    13	/* Number of fields in XLFD. */

/*
 * Helper macro. How to correctly round a double to a short.
 */

#define ROUND16(x)	((short) floor((x) + 0.5))

/*
 * Low-level API exported by generic code to platform-specific code.
 */

#define TkInitFontAttributes(fa)   memset((fa), 0, sizeof(TkFontAttributes));
#define TkInitXLFDAttributes(xa)   memset((xa), 0, sizeof(TkXLFDAttributes));

MODULE_SCOPE int	TkFontParseXLFD(const char *string,
			    TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr);
MODULE_SCOPE const char *const * TkFontGetAliasList(const char *faceName);
MODULE_SCOPE const char *const *const * TkFontGetFallbacks(void);
MODULE_SCOPE double	TkFontGetPixels(Tk_Window tkwin, double size);
MODULE_SCOPE double	TkFontGetPoints(Tk_Window tkwin, double size);
MODULE_SCOPE const char *const * TkFontGetGlobalClass(void);
MODULE_SCOPE const char *const * 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.
 */

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);

#ifdef __cplusplus

}
#endif

#endif	/* _TKFONT */







<
<
<
<
<
<







|

|
|
|
|
|
|

|

|










|


|

|
>
|
<
<

182
183
184
185
186
187
188






189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225


226
#define XLFD_RESOLUTION_X   8
#define XLFD_RESOLUTION_Y   9
#define XLFD_SPACING	    10
#define XLFD_AVERAGE_WIDTH  11
#define XLFD_CHARSET	    12
#define XLFD_NUMFIELDS	    13	/* Number of fields in XLFD. */







/*
 * Low-level API exported by generic code to platform-specific code.
 */

#define TkInitFontAttributes(fa)   memset((fa), 0, sizeof(TkFontAttributes));
#define TkInitXLFDAttributes(xa)   memset((xa), 0, sizeof(TkXLFDAttributes));

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.
 */

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 */

Changes to generic/tkFrame.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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.
 */

#include "tkInt.h"
#include "default.h"

/*
 * The following enum is used to define the type of the frame.
 */

enum FrameType {
    TYPE_FRAME, TYPE_TOPLEVEL, TYPE_LABELFRAME







|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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.
 */

#include "default.h"
#include "tkInt.h"

/*
 * The following enum is used to define the type of the frame.
 */

enum FrameType {
    TYPE_FRAME, TYPE_TOPLEVEL, TYPE_LABELFRAME
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
				 * pixels of extra space to leave on left and
				 * right of child area. */
    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 child area. */
    int padY;			/* Integer value corresponding to padYPtr. */
    Tcl_Obj *bgimgPtr;		/* Value of -backgroundimage option: specifies
				 * image to display on window's background, or
				 * NULL if none. */
    Tk_Image bgimg;		/* Derived from bgimgPtr by calling
				 * Tk_GetImage, or NULL if bgimgPtr is
				 * NULL. */
    int tile;			/* Whether to tile the bgimg. */
#ifndef TK_NO_DOUBLE_BUFFERING
    GC copyGC;			/* GC for copying when double-buffering. */
#endif /* TK_NO_DOUBLE_BUFFERING */
} Frame;

/*
 * A data structure of the following type is kept for each labelframe widget
 * managed by this file:
 */








<
<
<
<
<
<
<
<
<
<







90
91
92
93
94
95
96










97
98
99
100
101
102
103
				 * pixels of extra space to leave on left and
				 * right of child area. */
    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 child area. */
    int padY;			/* Integer value corresponding to padYPtr. */










} Frame;

/*
 * A data structure of the following type is kept for each labelframe widget
 * managed by this file:
 */

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
enum labelanchor {
    LABELANCHOR_E, LABELANCHOR_EN, LABELANCHOR_ES,
    LABELANCHOR_N, LABELANCHOR_NE, LABELANCHOR_NW,
    LABELANCHOR_S, LABELANCHOR_SE, LABELANCHOR_SW,
    LABELANCHOR_W, LABELANCHOR_WN, LABELANCHOR_WS
};

static const char *const labelAnchorStrings[] = {
    "e", "en", "es", "n", "ne", "nw", "s", "se", "sw", "w", "wn", "ws",
    NULL
};

/*
 * 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[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_FRAME_BG_COLOR, TCL_INDEX_NONE, offsetof(Frame, border),
	TK_OPTION_NULL_OK, DEF_FRAME_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_STRING, "-colormap", "colormap", "Colormap",
	DEF_FRAME_COLORMAP, TCL_INDEX_NONE, offsetof(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, TCL_INDEX_NONE, offsetof(Frame, isContainer), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_FRAME_CURSOR, TCL_INDEX_NONE, offsetof(Frame, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_FRAME_HEIGHT, TCL_INDEX_NONE, offsetof(Frame, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, TCL_INDEX_NONE,
	offsetof(Frame, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_FRAME_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Frame, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Frame, highlightWidth), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_FRAME_PADX, offsetof(Frame, padXPtr),
	offsetof(Frame, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_FRAME_PADY, offsetof(Frame, padYPtr),
	offsetof(Frame, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_FRAME_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Frame, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-visual", "visual", "Visual",
	DEF_FRAME_VISUAL, TCL_INDEX_NONE, offsetof(Frame, visualName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_FRAME_WIDTH, TCL_INDEX_NONE, offsetof(Frame, width), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec frameOptSpec[] = {
    {TK_OPTION_STRING, "-backgroundimage", "backgroundImage", "BackgroundImage",
	DEF_FRAME_BG_IMAGE, offsetof(Frame, bgimgPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bgimg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-backgroundimage", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_FRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-tile", "tile", "Tile",
	DEF_FRAME_BG_TILE, TCL_INDEX_NONE, offsetof(Frame, tile), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec toplevelOptSpec[] = {
    {TK_OPTION_STRING, "-backgroundimage", "backgroundImage", "BackgroundImage",
	DEF_FRAME_BG_IMAGE, offsetof(Frame, bgimgPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bgimg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-backgroundimage", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_TOPLEVEL_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_TOPLEVEL_MENU, TCL_INDEX_NONE, offsetof(Frame, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-screen", "screen", "Screen",
	DEF_TOPLEVEL_SCREEN, TCL_INDEX_NONE, offsetof(Frame, screenName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-tile", "tile", "Tile",
	DEF_FRAME_BG_TILE, TCL_INDEX_NONE, offsetof(Frame, tile), 0, 0, 0},
    {TK_OPTION_STRING, "-use", "use", "Use",
	DEF_TOPLEVEL_USE, TCL_INDEX_NONE, offsetof(Frame, useThis),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec labelframeOptSpec[] = {
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_LABELFRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_LABELFRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_LABELFRAME_FONT, TCL_INDEX_NONE, offsetof(Labelframe, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABELFRAME_FG, TCL_INDEX_NONE, offsetof(Labelframe, textColorPtr), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor",
	DEF_LABELFRAME_LABELANCHOR, TCL_INDEX_NONE, offsetof(Labelframe, labelAnchor),
	0, labelAnchorStrings, 0},
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
	NULL, TCL_INDEX_NONE, offsetof(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABELFRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_LABELFRAME_TEXT, offsetof(Labelframe, textPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

/*
 * Class names for widgets, indexed by FrameType.
 */

static const char *const classNames[] = {"Frame", "Toplevel", "Labelframe"};

/*
 * The following table maps from FrameType to the option template for that
 * class of widgets.
 */

static const Tk_OptionSpec *const optionSpecs[] = {
    frameOptSpec,
    toplevelOptSpec,
    labelframeOptSpec,
};

/*
 * Forward declarations for functions defined later in this file:
 */

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, const char *appName);
static void		DestroyFrame(void *memPtr);
static void		DestroyFramePartly(Frame *framePtr);
static void		DisplayFrame(ClientData clientData);
static void		DrawFrameBackground(Tk_Window tkwin, Pixmap pixmap,
			    int highlightWidth, int borderWidth,
			    Tk_Image bgimg, int bgtile);
static void		FrameBgImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		FrameCmdDeletedProc(ClientData clientData);
static void		FrameEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		FrameLostContentProc(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 functions that
 * can be invoked from generic window code.
 */

static const Tk_ClassProcs frameClass = {
    sizeof(Tk_ClassProcs),	/* size */
    FrameWorldChanged,		/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 * The structure below defines the official type record for the labelframe's
 * geometry manager:
 */

static const Tk_GeomMgr frameGeomType = {
    "labelframe",		/* name */
    FrameRequestProc,		/* requestProc */
    FrameLostContentProc		/* lostContentProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd --
 *







|











|
|

|

|






|

|


|

|
|

|


|
|

|
|

|
|

|


|


|




<
<
<

|
<
<

|

|

|
<
<

|



<
<
<

|
<
<

|

|

|


|

|

<
<

|


|




|

|


|

|

|

|

|
|

|

|

|


|






|






|


|








|

|
|
|


<
<
<
<
<
<



|







|








|

|
<
<










|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221



222
223


224
225
226
227
228
229


230
231
232
233
234



235
236


237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313






314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
enum labelanchor {
    LABELANCHOR_E, LABELANCHOR_EN, LABELANCHOR_ES,
    LABELANCHOR_N, LABELANCHOR_NE, LABELANCHOR_NW,
    LABELANCHOR_S, LABELANCHOR_SE, LABELANCHOR_SW,
    LABELANCHOR_W, LABELANCHOR_WN, LABELANCHOR_WS
};

static CONST char *labelAnchorStrings[] = {
    "e", "en", "es", "n", "ne", "nw", "s", "se", "sw", "w", "wn", "ws",
    NULL
};

/*
 * 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[] = {
    {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", 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},
    {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},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1,
	Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_FRAME_HIGHLIGHT, -1, Tk_Offset(Frame, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Frame, highlightWidth), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_FRAME_PADX, Tk_Offset(Frame, padXPtr),
	Tk_Offset(Frame, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_FRAME_PADY, Tk_Offset(Frame, padYPtr),
	Tk_Offset(Frame, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_FRAME_TAKE_FOCUS, -1, Tk_Offset(Frame, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-visual", "visual", "Visual",
	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, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 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},
    {TK_OPTION_STRING, "-class", "class", "Class",
	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, NULL, NULL, NULL,
	NULL, 0, 0, 0, (ClientData) commonOptSpec, 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},
    {TK_OPTION_STRING, "-class", "class", "Class",
	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},
    {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, NULL, NULL, NULL,
	NULL, 0, 0, 0, (ClientData) commonOptSpec, 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", 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},
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
	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},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
};

/*
 * Class names for widgets, indexed by FrameType.
 */

static CONST char *classNames[] = {"Frame", "Toplevel", "Labelframe"};

/*
 * The following table maps from FrameType to the option template for that
 * class of widgets.
 */

static const Tk_OptionSpec * const optionSpecs[] = {
    frameOptSpec,
    toplevelOptSpec,
    labelframeOptSpec
};

/*
 * Forward declarations for functions defined later in this file:
 */

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 functions that
 * can be invoked from generic window code.
 */

static Tk_ClassProcs frameClass = {
    sizeof(Tk_ClassProcs),	/* size */
    FrameWorldChanged		/* worldChangedProc */


};

/*
 * The structure below defines the official type record for the labelframe's
 * geometry manager:
 */

static const Tk_GeomMgr frameGeomType = {
    "labelframe",		/* name */
    FrameRequestProc,		/* requestProc */
    FrameLostSlaveProc		/* lostSlaveProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd --
 *
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
 */

int
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, NULL);
}

int
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, NULL);
}

int
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, NULL);
}

/*
 *--------------------------------------------------------------
 *







|









|









|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
 */

int
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, NULL);
}

int
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, NULL);
}

int
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, NULL);
}

/*
 *--------------------------------------------------------------
 *
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
 */

int
TkCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char *const *argv,	/* Argument strings. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    const 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. */
{
    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]);
    }
    objv[argc] = NULL;
    result = CreateFrame(clientData, interp, argc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, appName);
    for (i=0; i<argc; i++) {
	Tcl_DecrRefCount(objv[i]);
    }
    ckfree(objv);
    return result;
}

int
TkListCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *listObj,		/* List of arguments. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    Tcl_Obj *nameObj)		/* 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. */
{
    int objc;
    Tcl_Obj **objv;

    if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) {
	return TCL_ERROR;
    }
    return CreateFrame(clientData, interp, objc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME,
	    nameObj ? Tcl_GetString(nameObj) : NULL);
}

static int
CreateFrame(
    ClientData dummy,	/* 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. */
    const 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 newWin;
    const char *className, *screenName, *visualName, *colormapName;
    const char *arg, *useOption;
    int i, depth;
    TkSizeT length;
    unsigned int mask;
    Colormap colormap;
    Visual *visual;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    className = colormapName = screenName = visualName = useOption = NULL;
    colormap = None;
    for (i = 2; i < objc; i += 2) {
	arg = TkGetStringFromObj(objv[i], &length);
	if (length < 2) {
	    continue;
	}

	if ((arg[1] == 'c') && (length >= 3)
		&& (strncmp(arg, "-class", length) == 0)) {
	    className = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'c') && (length >= 3)
		&& (strncmp(arg, "-colormap", length) == 0)) {
	    colormapName = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 's') && (type == TYPE_TOPLEVEL)
		&& (strncmp(arg, "-screen", length) == 0)) {
	    screenName = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'u') && (type == TYPE_TOPLEVEL)
		&& (strncmp(arg, "-use", length) == 0)) {
	    useOption = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'v')
		&& (strncmp(arg, "-visual", length) == 0)) {
	    visualName = Tcl_GetString(objv[i+1]);
	}
    }

    /*
     * Create the window, and deal with the special options -use, -classname,
     * -colormap, -screenname, and -visual. These options must be handle







|


|





|











|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|


|

|








|
<
|
<



<


|




















|



>
|
|

|
|

|
|

|
|

|
|







416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447























448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465

466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
 */

int
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
				 * window associated with the interpreter.
				 * 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]);
    }
    objv[argc] = NULL;
    result = CreateFrame(clientData, interp, argc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, appName);
    for (i=0; i<argc; i++) {
	Tcl_DecrRefCount(objv[i]);
    }
    ckfree((char *) objv);
    return result;
}
























static int
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 newWin;
    CONST char *className, *screenName, *visualName, *colormapName, *arg, *useOption;

    int i, c, length, depth;

    unsigned int mask;
    Colormap colormap;
    Visual *visual;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    className = colormapName = screenName = visualName = useOption = NULL;
    colormap = None;
    for (i = 2; i < objc; i += 2) {
	arg = Tcl_GetStringFromObj(objv[i], &length);
	if (length < 2) {
	    continue;
	}
	c = arg[1];
	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)) {
	    colormapName = Tcl_GetString(objv[i+1]);
	} else if ((c == 's') && (type == TYPE_TOPLEVEL)
		&& (strncmp(arg, "-screen", (unsigned) length) == 0)) {
	    screenName = Tcl_GetString(objv[i+1]);
	} else if ((c == 'u') && (type == TYPE_TOPLEVEL)
		&& (strncmp(arg, "-use", (unsigned) length) == 0)) {
	    useOption = Tcl_GetString(objv[i+1]);
	} else if ((c == 'v')
		&& (strncmp(arg, "-visual", (unsigned) length) == 0)) {
	    visualName = Tcl_GetString(objv[i+1]);
	}
    }

    /*
     * Create the window, and deal with the special options -use, -classname,
     * -colormap, -screenname, and -visual. These options must be handle
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
		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.
	 */

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unable to create widget \"%s\"", Tcl_GetString(objv[1])));
	Tcl_SetErrorCode(interp, "TK", "APPLICATION_GONE", NULL);
	return TCL_ERROR;
    } else {
	/*
	 * We were called from Tk_Init; create a new application.
	 */

	newWin = TkCreateMainWindow(interp, screenName, appName);
    }
    if (newWin == NULL) {
	goto error;
    }

    /*
     * Mark Tk frames as suitable candidates for [wm manage].
     */

    ((TkWindow *) newWin)->flags |= TK_WM_MANAGEABLE;

    if (className == NULL) {
	className = Tk_GetOption(newWin, "class", "Class");
	if (className == NULL) {
	    className = classNames[type];
	}
    }
    Tk_SetClass(newWin, className);
    if (useOption == NULL) {
	useOption = Tk_GetOption(newWin, "use", "Use");
    }
    if ((useOption != NULL) && (*useOption != 0)
	    && (TkpUseWindow(interp, newWin, useOption) != TCL_OK)) {
	goto error;

    }
    if (visualName == NULL) {
	visualName = Tk_GetOption(newWin, "visual", "Visual");
    }
    if (colormapName == NULL) {
	colormapName = Tk_GetOption(newWin, "colormap", "Colormap");
    }







|
|
<
|









<
|
|
|
|
|
|
|










|
|
|
>







541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
		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.
	 */

	Tcl_AppendResult(interp, "unable to create widget \"",
		Tcl_GetString(objv[1]), "\"", NULL);

	newWin = NULL;
    } else {
	/*
	 * We were called from Tk_Init; create a new application.
	 */

	newWin = TkCreateMainWindow(interp, screenName, appName);
    }
    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(newWin, "class", "Class");
	if (className == NULL) {
	    className = classNames[type];
	}
    }
    Tk_SetClass(newWin, className);
    if (useOption == NULL) {
	useOption = Tk_GetOption(newWin, "use", "Use");
    }
    if ((useOption != NULL) && (*useOption != 0)) {
	if (TkpUseWindow(interp, newWin, useOption) != TCL_OK) {
	    goto error;
	}
    }
    if (visualName == NULL) {
	visualName = Tk_GetOption(newWin, "visual", "Visual");
    }
    if (colormapName == NULL) {
	colormapName = Tk_GetOption(newWin, "colormap", "Colormap");
    }
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
    /*
     * 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) {
	framePtr = (Frame *)ckalloc(sizeof(Labelframe));
	memset(framePtr, 0, sizeof(Labelframe));
    } else {
	framePtr = (Frame *)ckalloc(sizeof(Frame));
	memset(framePtr, 0, sizeof(Frame));
    }
    framePtr->tkwin = newWin;
    framePtr->display = Tk_Display(newWin);
    framePtr->interp = interp;
    framePtr->widgetCmd	= Tcl_CreateObjCommand(interp, Tk_PathName(newWin),

	    FrameWidgetObjCmd, framePtr, FrameCmdDeletedProc);
    framePtr->optionTable = optionTable;
    framePtr->type = type;
    framePtr->colormap = colormap;
    framePtr->relief = TK_RELIEF_FLAT;
    framePtr->cursor = NULL;

    if (framePtr->type == TYPE_LABELFRAME) {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	labelframePtr->labelAnchor = LABELANCHOR_NW;
	labelframePtr->textGC = NULL;
    }

    /*
     * Store backreference to frame widget in window structure.
     */

    Tk_SetClassProcs(newWin, &frameClass, framePtr);

    mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
    if (type == TYPE_TOPLEVEL) {
	mask |= ActivateMask;
    }
    Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr);
    if ((Tk_InitOptions(interp, framePtr, optionTable, newWin)
	    != TCL_OK) ||
	    (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
	goto error;
    }
    if (framePtr->isContainer) {
	if (framePtr->useThis != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(

		    "windows cannot have both the -use and the -container"
		    " option set", -1));
	    Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL);
	    goto error;
	}
	TkpMakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, Tk_NewWindowObj(newWin));
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;







|
|

|
|

|
|
|
|
>
|








<








|





|
|




|
|
|
>
|
|
<


<


|

|







617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671

672
673
674
675
676
677
678
679
680
681
682
683
    /*
     * 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) {
	framePtr = (Frame *) ckalloc(sizeof(Labelframe));
	memset((void *) framePtr, 0, (sizeof(Labelframe)));
    } else {
	framePtr = (Frame *) ckalloc(sizeof(Frame));
	memset((void *) framePtr, 0, (sizeof(Frame)));
    }
    framePtr->tkwin		= newWin;
    framePtr->display		= Tk_Display(newWin);
    framePtr->interp		= interp;
    framePtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(newWin), FrameWidgetObjCmd,
	    (ClientData) framePtr, FrameCmdDeletedProc);
    framePtr->optionTable = optionTable;
    framePtr->type = type;
    framePtr->colormap = colormap;
    framePtr->relief = TK_RELIEF_FLAT;
    framePtr->cursor = NULL;

    if (framePtr->type == TYPE_LABELFRAME) {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	labelframePtr->labelAnchor = LABELANCHOR_NW;
	labelframePtr->textGC = NULL;
    }

    /*
     * Store backreference to frame widget in window structure.
     */

    Tk_SetClassProcs(newWin, &frameClass, (ClientData) framePtr);

    mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
    if (type == TYPE_TOPLEVEL) {
	mask |= ActivateMask;
    }
    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;
    }
    if ((framePtr->isContainer)) {
	if (framePtr->useThis == NULL) {
	    TkpMakeContainer(framePtr->tkwin);
	} else {
	    Tcl_AppendResult(interp, "A window cannot have both the -use ",
		    "and the -container option set.", NULL);

	    goto error;
	}

    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr);
    }
    Tcl_SetResult(interp, Tk_PathName(newWin), TCL_STATIC);
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

805
806
807
808
809

810
811
812
813
814
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850




851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
 */

static int
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 *const frameOptions[] = {
	"cget", "configure", NULL
    };
    enum options {
	FRAME_CGET, FRAME_CONFIGURE
    };
    Frame *framePtr = (Frame *)clientData;
    int result = TCL_OK, index;
    int c, i;
    TkSizeT length;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(framePtr);
    switch ((enum options) index) {
    case FRAME_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	objPtr = Tk_GetOptionValue(interp, framePtr,
		framePtr->optionTable, objv[2], framePtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;
    case FRAME_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, framePtr,
		    framePtr->optionTable, (objc == 3) ? objv[2] : NULL,

		    framePtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    /*
	     * Don't allow the options -class, -colormap, -container, -screen,
	     * -use, or -visual to be changed.
	     */

	    for (i = 2; i < objc; i++) {
		const char *arg = TkGetStringFromObj(objv[i], &length);

		if (length < 2) {
		    continue;
		}
		c = arg[1];
		if (((c == 'c') && (length >= 2)
			&& (strncmp(arg, "-class", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-colormap", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-container", length) == 0))
		    || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-screen", length) == 0))
		    || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-use", length) == 0))
		    || ((c == 'v')
			&& (strncmp(arg, "-visual", 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;
			}




			continue;
		    }
#endif
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "can't modify %s option after widget is created",
			    arg));
		    Tcl_SetErrorCode(interp, "TK", "FRAME", "CREATE_ONLY",
			    NULL);
		    result = TCL_ERROR;
		    goto done;

		}
	    }
	    result = ConfigureFrame(interp, framePtr, objc-2, objv+2);
	}
	break;
    }

  done:
    Tcl_Release(framePtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFrame --







|

|





|

|
<



|


|
|


|







|




|
|
>



|
|
>




|
|
>







|
<





|

|

|

|

|

|



|
<





>
>
>
>
|

|
|
|
<
<
<
|
|
>








|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800



801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
 */

static int
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", NULL
    };
    enum options {
	FRAME_CGET, FRAME_CONFIGURE
    };
    register Frame *framePtr = (Frame *) clientData;
    int result = TCL_OK, index;
    int c, i, length;

    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], frameOptions, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve((ClientData) framePtr);
    switch ((enum options) index) {
    case FRAME_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	objPtr = Tk_GetOptionValue(interp, (char *) framePtr,
		framePtr->optionTable, objv[2], framePtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	} else {
	    Tcl_SetObjResult(interp, objPtr);
	}
	break;
    case FRAME_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) framePtr,
		    framePtr->optionTable,
		    (objc == 3) ? objv[2] : NULL,
		    framePtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    /*
	     * Don't allow the options -class, -colormap, -container, -screen,
	     * -use, or -visual to be changed.
	     */

	    for (i = 2; i < objc; i++) {
		char *arg = Tcl_GetStringFromObj(objv[i], &length);

		if (length < 2) {
		    continue;
		}
		c = arg[1];
		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:
    Tcl_Release((ClientData) framePtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFrame --
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
    void *memPtr)		/* Info about frame widget. */
{
    Frame *framePtr = (Frame *)memPtr;
    Labelframe *labelframePtr = (Labelframe *)memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {
	    Tk_FreeGC(framePtr->display, labelframePtr->textGC);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    if (framePtr->copyGC != NULL) {
	Tk_FreeGC(framePtr->display, framePtr->copyGC);
    }
#endif /* TK_NO_DOUBLE_BUFFERING */
    if (framePtr->colormap != None) {
	Tk_FreeColormap(framePtr->display, framePtr->colormap);
    }
    if (framePtr->bgimg) {
	Tk_FreeImage(framePtr->bgimg);
    }
    ckfree(framePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFramePartly --
 *







|

|
|







<
<
<
<
<



|
<
<
<







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846





847
848
849
850



851
852
853
854
855
856
857
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
    char *memPtr)		/* Info about frame widget. */
{
    register Frame *framePtr = (Frame *) memPtr;
    register Labelframe *labelframePtr = (Labelframe *) memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {
	    Tk_FreeGC(framePtr->display, labelframePtr->textGC);
	}
    }





    if (framePtr->colormap != None) {
	Tk_FreeColormap(framePtr->display, framePtr->colormap);
    }
    ckfree((char *) framePtr);



}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFramePartly --
 *
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
 *----------------------------------------------------------------------
 */

static void
DestroyFramePartly(
    Frame *framePtr)		/* Info about frame widget. */
{
    Labelframe *labelframePtr = (Labelframe *) framePtr;

    if (framePtr->type == TYPE_LABELFRAME && labelframePtr->labelWin != NULL) {
	Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask,
		FrameStructureProc, framePtr);
	Tk_ManageGeometry(labelframePtr->labelWin, NULL, NULL);
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }








|



|
|







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
 *----------------------------------------------------------------------
 */

static void
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, NULL, (ClientData) NULL);
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureFrame(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;
    Tk_Image image = NULL;

    /*
     * Need the old menubar name for the menu code to delete it.
     */

    if (framePtr->menuName == NULL) {
    	oldMenuName = NULL;
    } else {
    	oldMenuName = (char *)ckalloc(strlen(framePtr->menuName) + 1);
    	strcpy(oldMenuName, framePtr->menuName);
    }

    if (framePtr->type == TYPE_LABELFRAME) {
	oldWindow = labelframePtr->labelWin;
    }
    if (Tk_SetOptions(interp, framePtr,
	    framePtr->optionTable, objc, objv,
	    framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	if (oldMenuName != NULL) {
	    ckfree(oldMenuName);
	}
	return TCL_ERROR;
    }

    if (framePtr->bgimgPtr) {
	image = Tk_GetImage(interp, framePtr->tkwin,
		Tcl_GetString(framePtr->bgimgPtr), FrameBgImageProc, framePtr);
	if (image == NULL) {
	    Tk_RestoreSavedOptions(&savedOptions);
	    return TCL_ERROR;
	}
    }
    if (framePtr->bgimg) {
	Tk_FreeImage(framePtr->bgimg);
    }
    framePtr->bgimg = image;

    Tk_FreeSavedOptions(&savedOptions);

    /*
     * A few of the options require additional processing.
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName == NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName != NULL)
	    && strcmp(oldMenuName, framePtr->menuName) != 0))
	    && framePtr->type == TYPE_TOPLEVEL) {
	TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,
		framePtr->menuName);
    }

    if (oldMenuName != NULL) {
    	ckfree(oldMenuName);
    }







|


|





<








|






|






<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
<









|







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

946




947

948







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
 *
 *----------------------------------------------------------------------
 */

static int
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;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;


    /*
     * Need the old menubar name for the menu code to delete it.
     */

    if (framePtr->menuName == NULL) {
    	oldMenuName = NULL;
    } else {
    	oldMenuName = ckalloc(strlen(framePtr->menuName) + 1);
    	strcpy(oldMenuName, framePtr->menuName);
    }

    if (framePtr->type == TYPE_LABELFRAME) {
	oldWindow = labelframePtr->labelWin;
    }
    if (Tk_SetOptions(interp, (char *) framePtr,
	    framePtr->optionTable, objc, objv,
	    framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	if (oldMenuName != NULL) {
	    ckfree(oldMenuName);
	}
	return TCL_ERROR;

    } else {




	Tk_FreeSavedOptions(&savedOptions);

    }








    /*
     * A few of the options require additional processing.
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName == NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName != NULL)
	    && strcmp(oldMenuName, framePtr->menuName) != 0))
	&& framePtr->type == TYPE_TOPLEVEL) {
	TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,
		framePtr->menuName);
    }

    if (oldMenuName != NULL) {
    	ckfree(oldMenuName);
    }
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093





1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
     * geometry management for it.
     */

    if (framePtr->type == TYPE_LABELFRAME) {
	if (oldWindow != labelframePtr->labelWin) {
	    if (oldWindow != NULL) {
		Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
			FrameStructureProc, framePtr);
		Tk_ManageGeometry(oldWindow, NULL, NULL);
		Tk_UnmaintainGeometry(oldWindow, framePtr->tkwin);
		Tk_UnmapWindow(oldWindow);
	    }
	    if (labelframePtr->labelWin != NULL) {
		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.
		 */

		parent = Tk_Parent(labelframePtr->labelWin);
		for (ancestor = framePtr->tkwin; ;
		     ancestor = Tk_Parent(ancestor)) {
		    if (ancestor == parent) {
			break;
		    }
		    sibling = ancestor;
		    if (Tk_IsTopLevel(ancestor)) {
			goto badLabelWindow;





		    }
		}
		if (Tk_IsTopLevel(labelframePtr->labelWin)) {
		    goto badLabelWindow;
		}
		if (labelframePtr->labelWin == framePtr->tkwin) {
		    goto badLabelWindow;
		}
		Tk_CreateEventHandler(labelframePtr->labelWin,
			StructureNotifyMask, FrameStructureProc, framePtr);

		Tk_ManageGeometry(labelframePtr->labelWin, &frameGeomType,
			framePtr);

		/*
		 * If the frame is not parent to the label, make sure the
		 * label is above its sibling in the stacking order.
		 */

		if (sibling != NULL) {
		    Tk_RestackWindow(labelframePtr->labelWin, Above, sibling);
		}
	    }
	}
    }

    FrameWorldChanged(framePtr);
    return TCL_OK;

  badLabelWindow:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't use %s as label in this frame",
	    Tk_PathName(labelframePtr->labelWin)));
    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
    labelframePtr->labelWin = NULL;
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * FrameWorldChanged --
 *







|
|




















|
>
>
>
>
>



|


|


|
>

|













|
<

<
<
<
<
<
<
|







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

1047






1048
1049
1050
1051
1052
1053
1054
1055
     * geometry management for it.
     */

    if (framePtr->type == TYPE_LABELFRAME) {
	if (oldWindow != labelframePtr->labelWin) {
	    if (oldWindow != NULL) {
		Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
			FrameStructureProc, (ClientData) framePtr);
		Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL);
		Tk_UnmaintainGeometry(oldWindow, framePtr->tkwin);
		Tk_UnmapWindow(oldWindow);
	    }
	    if (labelframePtr->labelWin != NULL) {
		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.
		 */

		parent = Tk_Parent(labelframePtr->labelWin);
		for (ancestor = framePtr->tkwin; ;
		     ancestor = Tk_Parent(ancestor)) {
		    if (ancestor == parent) {
			break;
		    }
		    sibling = ancestor;
		    if (Tk_IsTopLevel(ancestor)) {
			badWindow:
			Tcl_AppendResult(interp, "can't use ",
				Tk_PathName(labelframePtr->labelWin),
				" as label in this frame", NULL);
			labelframePtr->labelWin = NULL;
			return TCL_ERROR;
		    }
		}
		if (Tk_IsTopLevel(labelframePtr->labelWin)) {
		    goto badWindow;
		}
		if (labelframePtr->labelWin == framePtr->tkwin) {
		    goto badWindow;
		}
		Tk_CreateEventHandler(labelframePtr->labelWin,
			StructureNotifyMask, FrameStructureProc,
			(ClientData) framePtr);
		Tk_ManageGeometry(labelframePtr->labelWin, &frameGeomType,
			(ClientData) framePtr);

		/*
		 * If the frame is not parent to the label, make sure the
		 * label is above its sibling in the stacking order.
		 */

		if (sibling != NULL) {
		    Tk_RestackWindow(labelframePtr->labelWin, Above, sibling);
		}
	    }
	}
    }

    FrameWorldChanged((ClientData) framePtr);








    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * FrameWorldChanged --
 *
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)instanceData;
    Labelframe *labelframePtr = (Labelframe *)instanceData;
    Tk_Window tkwin = framePtr->tkwin;
    XGCValues gcValues;
    GC gc;
    int anyTextLabel, anyWindowLabel;
    int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom;
    const char *labelText;

    anyTextLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->textPtr != NULL) &&
	    (labelframePtr->labelWin == NULL);
    anyWindowLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->labelWin != NULL);

#ifndef TK_NO_DOUBLE_BUFFERING
    gcValues.graphics_exposures = False;
    gc = Tk_GetGC(tkwin, GCGraphicsExposures, &gcValues);
    if (framePtr->copyGC != NULL) {
	Tk_FreeGC(framePtr->display, framePtr->copyGC);
    }
    framePtr->copyGC = gc;
#endif /* TK_NO_DOUBLE_BUFFERING */

    if (framePtr->type == TYPE_LABELFRAME) {
	/*
	 * The textGC is needed even in the labelWin case, so it's always
	 * created for a labelframe.
	 */

	gcValues.font = Tk_FontId(labelframePtr->tkfont);







|
|





|







<
<
<
<
<
<
<
<
<







1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087









1088
1089
1090
1091
1092
1093
1094
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *) instanceData;
    Labelframe *labelframePtr = (Labelframe *) framePtr;
    Tk_Window tkwin = framePtr->tkwin;
    XGCValues gcValues;
    GC gc;
    int anyTextLabel, anyWindowLabel;
    int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom;
    char *labelText;

    anyTextLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->textPtr != NULL) &&
	    (labelframePtr->labelWin == NULL);
    anyWindowLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->labelWin != NULL);










    if (framePtr->type == TYPE_LABELFRAME) {
	/*
	 * The textGC is needed even in the labelWin case, so it's always
	 * created for a labelframe.
	 */

	gcValues.font = Tk_FontId(labelframePtr->tkfont);
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
	 */

	labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0;

	if (anyTextLabel) {
	    labelText = Tcl_GetString(labelframePtr->textPtr);
	    Tk_FreeTextLayout(labelframePtr->textLayout);
	    labelframePtr->textLayout =
		    Tk_ComputeTextLayout(labelframePtr->tkfont,
		    labelText, -1, 0, TK_JUSTIFY_CENTER, 0,
		    &labelframePtr->labelReqWidth,
		    &labelframePtr->labelReqHeight);
	    labelframePtr->labelReqWidth += 2 * LABELSPACING;
	    labelframePtr->labelReqHeight += 2 * LABELSPACING;
	} else if (anyWindowLabel) {
	    labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin);
	    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.
	 */







|
<

|
<




|
<







1106
1107
1108
1109
1110
1111
1112
1113

1114
1115

1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
	 */

	labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0;

	if (anyTextLabel) {
	    labelText = Tcl_GetString(labelframePtr->textPtr);
	    Tk_FreeTextLayout(labelframePtr->textLayout);
	    labelframePtr->textLayout = Tk_ComputeTextLayout(labelframePtr->tkfont,

		    labelText, -1, 0, TK_JUSTIFY_CENTER, 0,
		    &labelframePtr->labelReqWidth, &labelframePtr->labelReqHeight);

	    labelframePtr->labelReqWidth += 2 * LABELSPACING;
	    labelframePtr->labelReqHeight += 2 * LABELSPACING;
	} else if (anyWindowLabel) {
	    labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin);
	    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.
	 */
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312

    if ((framePtr->width > 0) || (framePtr->height > 0)) {
	Tk_GeometryRequest(tkwin, framePtr->width, framePtr->height);
    }

    if (Tk_IsMapped(tkwin)) {
	if (!(framePtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayFrame, framePtr);
	}
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------







|







1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220

    if ((framePtr->width > 0) || (framePtr->height > 0)) {
	Tk_GeometryRequest(tkwin, framePtr->width, framePtr->height);
    }

    if (Tk_IsMapped(tkwin)) {
	if (!(framePtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);
	}
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
 *	Display-related numbers get changed in *framePtr.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeFrameGeometry(
    Frame *framePtr)	/* Information about widget. */
{
    int otherWidth, otherHeight, otherWidthT, otherHeightT, padding;
    int maxWidth, maxHeight;
    Tk_Window tkwin;
    Labelframe *labelframePtr = (Labelframe *) framePtr;

    /*
     * We have nothing to do here unless there is a label.
     */

    if (framePtr->type != TYPE_LABELFRAME) {
	return;
    }
    if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) {
	return;
    }

    tkwin = framePtr->tkwin;

    /*







|










|
<
<







1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250


1251
1252
1253
1254
1255
1256
1257
 *	Display-related numbers get changed in *framePtr.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeFrameGeometry(
    register Frame *framePtr)	/* Information about widget. */
{
    int otherWidth, otherHeight, otherWidthT, otherHeightT, padding;
    int maxWidth, maxHeight;
    Tk_Window tkwin;
    Labelframe *labelframePtr = (Labelframe *) framePtr;

    /*
     * We have nothing to do here unless there is a label.
     */

    if (framePtr->type != TYPE_LABELFRAME) return;


    if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) {
	return;
    }

    tkwin = framePtr->tkwin;

    /*
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

    maxHeight = Tk_Height(tkwin);
    maxWidth  = Tk_Width(tkwin);

    if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
	    (labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
	maxWidth -= padding;
	if (maxWidth < 1) {
	    maxWidth = 1;
	}
    } else {
	maxHeight -= padding;
	if (maxHeight < 1) {
	    maxHeight = 1;
	}
    }
    if (labelframePtr->labelBox.width > maxWidth) {
	labelframePtr->labelBox.width = maxWidth;
    }
    if (labelframePtr->labelBox.height > maxHeight) {
	labelframePtr->labelBox.height = maxHeight;
    }







|
<
<


|
<
<







1269
1270
1271
1272
1273
1274
1275
1276


1277
1278
1279


1280
1281
1282
1283
1284
1285
1286

    maxHeight = Tk_Height(tkwin);
    maxWidth  = Tk_Width(tkwin);

    if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
	    (labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
	maxWidth -= padding;
	if (maxWidth < 1) maxWidth = 1;


    } else {
	maxHeight -= padding;
	if (maxHeight < 1) maxHeight = 1;


    }
    if (labelframePtr->labelBox.width > maxWidth) {
	labelframePtr->labelBox.width = maxWidth;
    }
    if (labelframePtr->labelBox.height > maxHeight) {
	labelframePtr->labelBox.height = maxHeight;
    }
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    ClientData clientData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;
    int bdX1, bdY1, bdX2, bdY2, hlWidth;
    Pixmap pixmap;
    TkRegion clipRegion = NULL;

    framePtr->flags &= ~REDRAW_PENDING;
    if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;







|
|







1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    ClientData clientData)	/* Information about widget. */
{
    register Frame *framePtr = (Frame *) clientData;
    register Tk_Window tkwin = framePtr->tkwin;
    int bdX1, bdY1, bdX2, bdY2, hlWidth;
    Pixmap pixmap;
    TkRegion clipRegion = NULL;

    framePtr->flags &= ~REDRAW_PENDING;
    if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555














1556
1557
1558
1559
1560
1561
1562
	}
    }

    /*
     * If -background is set to "", no interior is drawn.
     */

    if (framePtr->border == NULL) {
	return;
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * 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),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */

    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.
	 */

    noLabel:
	TkpDrawFrameEx(tkwin, pixmap, framePtr->border, hlWidth,
		framePtr->borderWidth, framePtr->relief);
	if (framePtr->bgimg) {
	    DrawFrameBackground(tkwin, pixmap, hlWidth, framePtr->borderWidth,
		    framePtr->bgimg, framePtr->tile);
	}
    } else {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	if ((labelframePtr->textPtr == NULL) &&
		(labelframePtr->labelWin == NULL)) {
	    goto noLabel;
	}















	/*
	 * Clear the pixmap.
	 */

	Tk_Fill3DRectangle(tkwin, pixmap, framePtr->border, 0, 0,
		Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|

<
<
<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>







1412
1413
1414
1415
1416
1417
1418
1419
















1420
1421
1422
1423
1424
1425
1426
1427
1428
1429




1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
	}
    }

    /*
     * If -background is set to "", no interior is drawn.
     */

    if (framePtr->border == NULL) return;

















    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.
	 */

    noLabel:
	TkpDrawFrame(tkwin, framePtr->border, hlWidth,
		framePtr->borderWidth, framePtr->relief);




    } else {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	if ((labelframePtr->textPtr == NULL) &&
		(labelframePtr->labelWin == NULL)) {
	    goto noLabel;
	}

#ifndef TK_NO_DOUBLE_BUFFERING
	/*
	 * 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),
		Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
	pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */

	/*
	 * Clear the pixmap.
	 */

	Tk_Fill3DRectangle(tkwin, pixmap, framePtr->border, 0, 0,
		Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
			|| (labelframePtr->labelBox.y !=
				Tk_Y(labelframePtr->labelWin))
			|| (labelframePtr->labelBox.width !=
				Tk_Width(labelframePtr->labelWin))
			|| (labelframePtr->labelBox.height !=
				Tk_Height(labelframePtr->labelWin))) {
		    Tk_MoveResizeWindow(labelframePtr->labelWin,
			    labelframePtr->labelBox.x,
			    labelframePtr->labelBox.y,
			    labelframePtr->labelBox.width,
			    labelframePtr->labelBox.height);
		}
		Tk_MapWindow(labelframePtr->labelWin);
	    } else {
		Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
			labelframePtr->labelBox.x, labelframePtr->labelBox.y,
			labelframePtr->labelBox.width,
			labelframePtr->labelBox.height);
	    }
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * Everything's been redisplayed; now copy the pixmap onto the screen and
     * free up the pixmap.
     */

    XCopyArea(framePtr->display, pixmap, Tk_WindowId(tkwin),
	    framePtr->copyGC, hlWidth, hlWidth,
	    (unsigned) (Tk_Width(tkwin) - 2 * hlWidth),
	    (unsigned) (Tk_Height(tkwin) - 2 * hlWidth),
	    hlWidth, hlWidth);
    Tk_FreePixmap(framePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrame --
 *
 *	This procedure draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrame(
    Tk_Window tkwin,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    /*
     * Legacy shim to allow for external callers. Internal ones use
     * non-exposed TkpDrawFrameEx directly so they can use double-buffering.
     */

    TkpDrawFrameEx(tkwin, Tk_WindowId(tkwin), border,
	    highlightWidth, borderWidth, relief);
}

/*
 *--------------------------------------------------------------
 *
 * FrameEventProc --
 *







|
<











|


|
|
|
|

|
|
|
|
|
|

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1543
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578































1579
1580
1581
1582
1583
1584
1585
			|| (labelframePtr->labelBox.y !=
				Tk_Y(labelframePtr->labelWin))
			|| (labelframePtr->labelBox.width !=
				Tk_Width(labelframePtr->labelWin))
			|| (labelframePtr->labelBox.height !=
				Tk_Height(labelframePtr->labelWin))) {
		    Tk_MoveResizeWindow(labelframePtr->labelWin,
			    labelframePtr->labelBox.x, labelframePtr->labelBox.y,

			    labelframePtr->labelBox.width,
			    labelframePtr->labelBox.height);
		}
		Tk_MapWindow(labelframePtr->labelWin);
	    } else {
		Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
			labelframePtr->labelBox.x, labelframePtr->labelBox.y,
			labelframePtr->labelBox.width,
			labelframePtr->labelBox.height);
	    }
	}


#ifndef TK_NO_DOUBLE_BUFFERING
	/*
	 * Everything's been redisplayed; now copy the pixmap onto the screen
	 * and free up the pixmap.
	 */

	XCopyArea(framePtr->display, pixmap, Tk_WindowId(tkwin),
		labelframePtr->textGC, hlWidth, hlWidth,
		(unsigned) (Tk_Width(tkwin) - 2 * hlWidth),
		(unsigned) (Tk_Height(tkwin) - 2 * hlWidth),
		hlWidth, hlWidth);
	Tk_FreePixmap(framePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }
































}

/*
 *--------------------------------------------------------------
 *
 * FrameEventProc --
 *
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)	/* Information about event. */
{
    Frame *framePtr = (Frame *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeFrameGeometry(framePtr);
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {







|

|







1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    ClientData clientData,	/* Information about window. */
    register XEvent *eventPtr)	/* Information about event. */
{
    register Frame *framePtr = (Frame *) clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeFrameGeometry(framePtr);
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
	     * DestroyFrame, we must free all options now.
	     */

	    DestroyFramePartly(framePtr);

	    Tk_DeleteEventHandler(framePtr->tkwin,
		    ExposureMask|StructureNotifyMask|FocusChangeMask,
		    FrameEventProc, framePtr);
	    framePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
	}
	if (framePtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayFrame, framePtr);
	}
	Tcl_CancelIdleCall(MapFrame, framePtr);
	Tcl_EventuallyFree(framePtr, (Tcl_FreeProc *) DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}







|




|

|
|







1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
	     * DestroyFrame, we must free all options now.
	     */

	    DestroyFramePartly(framePtr);

	    Tk_DeleteEventHandler(framePtr->tkwin,
		    ExposureMask|StructureNotifyMask|FocusChangeMask,
		    FrameEventProc, (ClientData) framePtr);
	    framePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
	}
	if (framePtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr);
	}
	Tcl_CancelIdleCall(MapFrame, (ClientData) framePtr);
	Tcl_EventuallyFree((ClientData) framePtr, DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
    	TkpSetMainMenubar(framePtr->interp, framePtr->tkwin,
    		framePtr->menuName);
    }
    return;

  redraw:
    if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, framePtr);
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
    	TkpSetMainMenubar(framePtr->interp, framePtr->tkwin,
    		framePtr->menuName);
    }
    return;

  redraw:
    if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
 *----------------------------------------------------------------------
 */

static void
FrameCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;

    if (framePtr->menuName != NULL) {
	TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
		framePtr->menuName, NULL);
	ckfree(framePtr->menuName);
	framePtr->menuName = NULL;







|







1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
 *----------------------------------------------------------------------
 */

static void
FrameCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Frame *framePtr = (Frame *) clientData;
    Tk_Window tkwin = framePtr->tkwin;

    if (framePtr->menuName != NULL) {
	TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
		framePtr->menuName, NULL);
	ckfree(framePtr->menuName);
	framePtr->menuName = NULL;
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
 *----------------------------------------------------------------------
 */

static void
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.
     */

    Tcl_Preserve(framePtr);
    while (1) {
	if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) {
	    break;
	}

	/*
	 * After each event, make sure that the window still exists and quit
	 * if the window has been destroyed.
	 */

	if (framePtr->tkwin == NULL) {
	    Tcl_Release(framePtr);
	    return;
	}
    }
    Tk_MapWindow(framePtr->tkwin);
    Tcl_Release(framePtr);
}

/*
 *--------------------------------------------------------------
 *
 * TkInstallFrameMenu --
 *







|








|











|




|







1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
 *----------------------------------------------------------------------
 */

static void
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.
     */

    Tcl_Preserve((ClientData) framePtr);
    while (1) {
	if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) {
	    break;
	}

	/*
	 * After each event, make sure that the window still exists and quit
	 * if the window has been destroyed.
	 */

	if (framePtr->tkwin == NULL) {
	    Tcl_Release((ClientData) framePtr);
	    return;
	}
    }
    Tk_MapWindow(framePtr->tkwin);
    Tcl_Release((ClientData) framePtr);
}

/*
 *--------------------------------------------------------------
 *
 * TkInstallFrameMenu --
 *
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
void
TkInstallFrameMenu(
    Tk_Window tkwin)		/* The window that was just created. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->mainPtr != NULL) {
	Frame *framePtr = (Frame *)winPtr->instanceData;

	if (framePtr == NULL) {
	    Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer");
	}
	TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,
		framePtr->menuName);
    }
}







|
|







1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
void
TkInstallFrameMenu(
    Tk_Window tkwin)		/* The window that was just created. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->mainPtr != NULL) {
	Frame *framePtr;
	framePtr = (Frame*) winPtr->instanceData;
	if (framePtr == NULL) {
	    Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer");
	}
	TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,
		framePtr->menuName);
    }
}
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
 */

static void
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.
	 */

	if (labelframePtr->frame.type == TYPE_LABELFRAME) {
	    labelframePtr->labelWin = NULL;
	    FrameWorldChanged(labelframePtr);
	}
    }
}

/*
 *--------------------------------------------------------------
 *







|









|







1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
 */

static void
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.
	 */

	if (labelframePtr->frame.type == TYPE_LABELFRAME) {
	    labelframePtr->labelWin = NULL;
	    FrameWorldChanged((ClientData) labelframePtr);
	}
    }
}

/*
 *--------------------------------------------------------------
 *
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
 */

static void
FrameRequestProc(
    ClientData clientData,	/* Pointer to record for frame. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    Frame *framePtr = (Frame *)clientData;
    (void)tkwin;

    FrameWorldChanged(framePtr);
}

/*
 *--------------------------------------------------------------
 *
 * FrameLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostContentProc(
    ClientData clientData,	/* Frame structure for content window window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window window. */
{
    Frame *framePtr = (Frame *)clientData;
    Labelframe *labelframePtr = (Labelframe *)clientData;
    (void)tkwin;

    /*
     * 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, labelframePtr);
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }
    FrameWorldChanged(framePtr);
}

void
TkMapTopFrame(
     Tk_Window tkwin)
{
    Frame *framePtr = (Frame *)((TkWindow *) tkwin)->instanceData;
    Tk_OptionTable optionTable;

    if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) {
	framePtr->type = TYPE_TOPLEVEL;
	Tcl_DoWhenIdle(MapFrame, 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 --







|
<

|





|


|





|





|
|

|

|
|
<








|






|



|
|

|

<


|


|




<
|
<
<


<

|
|

<
|
<







1867
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903

1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935
1936
1937

1938


1939
1940

1941
1942
1943
1944

1945

1946
1947
1948
1949
1950
1951
1952
 */

static void
FrameRequestProc(
    ClientData clientData,	/* Pointer to record for frame. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    Frame *framePtr = (Frame *) clientData;


    FrameWorldChanged((ClientData) framePtr);
}

/*
 *--------------------------------------------------------------
 *
 * FrameLostSlaveProc --
 *
 *	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 frame-related information about the slave.
 *
 *--------------------------------------------------------------
 */

static void
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.
     */

    if (labelframePtr->frame.type == TYPE_LABELFRAME) {
	Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask,
		FrameStructureProc, (ClientData) labelframePtr);
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }
    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 --
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
 *
 *--------------------------------------------------------------
 */

Tk_Window
TkToplevelWindowForCommand(
    Tcl_Interp *interp,
    const char *cmdName)
{
    Tcl_CmdInfo cmdInfo;
    Frame *framePtr;

    if (Tcl_GetCommandInfo(interp, cmdName, &cmdInfo) == 0) {
	return NULL;
    }
    if (cmdInfo.objProc != FrameWidgetObjCmd) {
	return NULL;
    }
    framePtr = (Frame *)cmdInfo.objClientData;
    if (framePtr->type != TYPE_TOPLEVEL) {
	return NULL;
    }
    return framePtr->tkwin;
}

/*
 *----------------------------------------------------------------------
 *
 * FrameBgImageProc --
 *
 *	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 on a frame's background.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameBgImageProc(
    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. */
{
    Frame *framePtr = (Frame *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;


    /*
     * Changing the background image never alters the dimensions of the frame.
     */

    if (framePtr->tkwin && Tk_IsMapped(framePtr->tkwin) &&
	    !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, framePtr);
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawFrameBackground --
 *
 *	This function draws the background image of a rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

static void
DrawFrameBackground(
    Tk_Window tkwin,
    Pixmap pixmap,
    int highlightWidth,
    int borderWidth,
    Tk_Image bgimg,
    int bgtile)
{
    int width, height;			/* Area to paint on. */
    int imageWidth, imageHeight;	/* Dimensions of image. */
    const int bw = highlightWidth + borderWidth;

    Tk_SizeOfImage(bgimg, &imageWidth, &imageHeight);
    width = Tk_Width(tkwin) - 2*bw;
    height = Tk_Height(tkwin) - 2*bw;

    if (bgtile) {
	/*
	 * Draw the image tiled in the widget (inside the border).
	 */

	int x, y;

	for (x = bw; x - bw < width; x += imageWidth) {
	    int w = imageWidth;
	    if (x - bw + imageWidth > width) {
		w = (width + bw) - x;
	    }
	    for (y = bw; y < height + bw; y += imageHeight) {
		int h = imageHeight;
		if (y - bw + imageHeight > height) {
		    h = (height + bw) - y;
		}
		Tk_RedrawImage(bgimg, 0, 0, w, h, pixmap, x, y);
	    }
	}
    } else {
	/*
	 * Draw the image centred in the widget (inside the border).
	 */

	int x, y, xOff, yOff, w, h;

	if (width > imageWidth) {
	    x = 0;
	    xOff = (Tk_Width(tkwin) - imageWidth) / 2;
	    w = imageWidth;
	} else {
	    x = (imageWidth - width) / 2;
	    xOff = bw;
	    w = width;
	}
	if (height > imageHeight) {
	    y = 0;
	    yOff = (Tk_Height(tkwin) - imageHeight) / 2;
	    h = imageHeight;
	} else {
	    y = (imageHeight - height) / 2;
	    yOff = bw;
	    h = height;
	}
	Tk_RedrawImage(bgimg, x, y, w, h, pixmap, xOff, yOff);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|










|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988

































































































































1989
1990
1991
1992
1993
1994
1995
1996
 *
 *--------------------------------------------------------------
 */

Tk_Window
TkToplevelWindowForCommand(
    Tcl_Interp *interp,
    CONST char *cmdName)
{
    Tcl_CmdInfo cmdInfo;
    Frame *framePtr;

    if (Tcl_GetCommandInfo(interp, cmdName, &cmdInfo) == 0) {
	return NULL;
    }
    if (cmdInfo.objProc != FrameWidgetObjCmd) {
	return NULL;
    }
    framePtr = (Frame *) cmdInfo.objClientData;
    if (framePtr->type != TYPE_TOPLEVEL) {
	return NULL;
    }
    return framePtr->tkwin;
}


































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkGC.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * values in the graphics context and the other based on the display and GC
 * identifier.
 */

typedef struct {
    GC gc;			/* Graphics context. */
    Display *display;		/* Display to which gc belongs. */
    size_t refCount;		/* Number of active uses of gc. */
    Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
				 * this structure). */
} TkGC;

typedef struct {
    XGCValues values;		/* Desired values for GC. */
    Display *display;		/* Display for which GC is valid. */







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * values in the graphics context and the other based on the display and GC
 * identifier.
 */

typedef struct {
    GC gc;			/* Graphics context. */
    Display *display;		/* Display to which gc belongs. */
    int refCount;		/* Number of active uses of gc. */
    Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
				 * this structure). */
} TkGC;

typedef struct {
    XGCValues values;		/* Desired values for GC. */
    Display *display;		/* Display for which GC is valid. */
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 *
 *----------------------------------------------------------------------
 */

GC
Tk_GetGC(
    Tk_Window tkwin,		/* Window in which GC will be used. */
    unsigned long valueMask,
				/* 1 bits correspond to values specified in
				 * *valuesPtr; other values are set from
				 * defaults. */
    XGCValues *valuePtr)
				/* Values are specified here for bits set in
				 * valueMask. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr, *idHashPtr;
    TkGC *gcPtr;
    int isNew;
    Drawable d, freeDrawable;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (dispPtr->gcInit <= 0) {
	GCInit(dispPtr);
    }







|



|





|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 *
 *----------------------------------------------------------------------
 */

GC
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 isNew;
    Drawable d, freeDrawable;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (dispPtr->gcInit <= 0) {
	GCInit(dispPtr);
    }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    }
    valueKey.display = Tk_Display(tkwin);
    valueKey.screenNum = Tk_ScreenNumber(tkwin);
    valueKey.depth = Tk_Depth(tkwin);
    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.
     */

    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
     * Tk_MakeWindowExist on the window.
     */








|









|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    }
    valueKey.display = Tk_Display(tkwin);
    valueKey.screenNum = Tk_ScreenNumber(tkwin);
    valueKey.depth = Tk_Depth(tkwin);
    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.
     */

    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
     * Tk_MakeWindowExist on the window.
     */

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315

316
317
318
319
320
321
322
323
324
325
326

void
Tk_FreeGC(
    Display *display,		/* Display for which gc was allocated. */
    GC gc)			/* Graphics context to be released. */
{
    Tcl_HashEntry *idHashPtr;
    TkGC *gcPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->gcInit) {
	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.
	 */

	return;
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, gc);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeGC received unknown gc argument");
    }
    gcPtr = (TkGC *)Tcl_GetHashValue(idHashPtr);

    if (gcPtr->refCount-- <= 1) {

	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
	Tcl_DeleteHashEntry(idHashPtr);
	ckfree(gcPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkGCCleanup --







|















|



|
>
|
>



|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

void
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) {
	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.
	 */

	return;
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeGC received unknown gc argument");
    }
    gcPtr = (TkGC *) Tcl_GetHashValue(idHashPtr);
    gcPtr->refCount--;
    if (gcPtr->refCount == 0) {
	Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
	Tcl_DeleteHashEntry(idHashPtr);
	ckfree((char *) gcPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkGCCleanup --
343
344
345
346
347
348
349
350






351
352
353
354
355
356
357
358
359
360
361
362
{
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    TkGC *gcPtr;

    for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &search);
	    entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) {
	gcPtr = (TkGC *)Tcl_GetHashValue(entryPtr);







	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
	Tcl_DeleteHashEntry(entryPtr);
	ckfree(gcPtr);
    }
    Tcl_DeleteHashTable(&dispPtr->gcValueTable);
    Tcl_DeleteHashTable(&dispPtr->gcIdTable);
    dispPtr->gcInit = -1;
}

/*







|
>
>
>
>
>
>




|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
{
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    TkGC *gcPtr;

    for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &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.
	 *   Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
	 */

	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
	Tcl_DeleteHashEntry(entryPtr);
	ckfree((char *) gcPtr);
    }
    Tcl_DeleteHashTable(&dispPtr->gcValueTable);
    Tcl_DeleteHashTable(&dispPtr->gcIdTable);
    dispPtr->gcInit = -1;
}

/*

Changes to generic/tkGeometry.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Data structures of the following type are used by Tk_MaintainGeometry. For
 * each content managed by Tk_MaintainGeometry, there is one of these structures
 * associated with its container.
 */

typedef struct MaintainContent {
    Tk_Window content;		/* The content window being positioned. */
    Tk_Window container;		/* The container that determines content's
				 * position; it must be a descendant of
				 * content's parent. */
    int x, y;			/* Desired position of content relative to
				 * container. */
    int width, height;		/* Desired dimensions of content. */
    struct MaintainContent *nextPtr;
				/* Next in list of Maintains associated with
				 * container. */
} MaintainContent;

/*
 * For each window that has been specified as a content to Tk_MaintainGeometry,
 * there is a structure of the following type:
 */

typedef struct MaintainContainer {
    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. */
    MaintainContent *contentPtr;	/* First in list of all content associated with
				 * this container. */
} MaintainContainer;

/*
 * Prototypes for static procedures in this file:
 */

static void		MaintainCheckProc(ClientData clientData);
static void		MaintainContainerProc(ClientData clientData,
			    XEvent *eventPtr);
static void		MaintainContentProc(ClientData clientData,
			    XEvent *eventPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_ManageGeometry --
 *
 *	Arrange for a particular procedure to manage the geometry of a given
 *	content 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 lostContentProc.
 *
 *--------------------------------------------------------------
 */

void
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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if ((winPtr->geomMgrPtr != NULL) && (mgrPtr != NULL)
	    && ((winPtr->geomMgrPtr != mgrPtr)
		|| (winPtr->geomData != clientData))
	    && (winPtr->geomMgrPtr->lostContentProc != NULL)) {
	winPtr->geomMgrPtr->lostContentProc(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*







|
|


|
|
|

|
|
|
|
|

|
|


|



|







|
|
|






|

|








|









|








|





|




|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#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.
 */

typedef struct MaintainSlave {
    Tk_Window slave;		/* The slave window being positioned. */
    Tk_Window master;		/* The master that determines slave's
				 * position; it must be a descendant of
				 * slave's parent. */
    int x, y;			/* Desired position of slave relative to
				 * master. */
    int width, height;		/* Desired dimensions of slave. */
    struct MaintainSlave *nextPtr;
				/* 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:
 */

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. */
} MaintainMaster;

/*
 * Prototypes for static procedures in this file:
 */

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.
 *
 * 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.
 *
 *--------------------------------------------------------------
 */

void
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;

    if ((winPtr->geomMgrPtr != NULL) && (mgrPtr != NULL)
	    && ((winPtr->geomMgrPtr != mgrPtr)
		|| (winPtr->geomData != clientData))
	    && (winPtr->geomMgrPtr->lostSlaveProc != NULL)) {
	(*winPtr->geomMgrPtr->lostSlaveProc)(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
void
Tk_GeometryRequest(
    Tk_Window tkwin,		/* Window that geometry information pertains
				 * to. */
    int reqWidth, int reqHeight)/* Minimum desired dimensions for window, in
				 * pixels. */
{
    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.
     */

    if (reqWidth <= 0) {
	reqWidth = 1;
    }
    if (reqHeight <= 0) {
	reqHeight = 1;
    }
    if ((reqWidth == winPtr->reqWidth) && (reqHeight == winPtr->reqHeight)) {
	return;
    }
    winPtr->reqWidth = reqWidth;
    winPtr->reqHeight = reqHeight;
    if ((winPtr->geomMgrPtr != NULL)
	    && (winPtr->geomMgrPtr->requestProc != NULL)) {
	winPtr->geomMgrPtr->requestProc(winPtr->geomData, tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetInternalBorderEx --







|



















|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
void
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.
     */

    if (reqWidth <= 0) {
	reqWidth = 1;
    }
    if (reqHeight <= 0) {
	reqHeight = 1;
    }
    if ((reqWidth == winPtr->reqWidth) && (reqHeight == winPtr->reqHeight)) {
	return;
    }
    winPtr->reqWidth = reqWidth;
    winPtr->reqHeight = reqHeight;
    if ((winPtr->geomMgrPtr != NULL)
	    && (winPtr->geomMgrPtr->requestProc != NULL)) {
	(*winPtr->geomMgrPtr->requestProc)(winPtr->geomData, tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetInternalBorderEx --
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

void
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)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int changed = 0;

    if (left < 0) {
	left = 0;
    }
    if (left != winPtr->internalBorderLeft) {
	winPtr->internalBorderLeft = left;
	changed = 1;







|
|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

void
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;

    if (left < 0) {
	left = 0;
    }
    if (left != winPtr->internalBorderLeft) {
	winPtr->internalBorderLeft = left;
	changed = 1;
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
    }
    if (bottom != winPtr->internalBorderBottom) {
	winPtr->internalBorderBottom = bottom;
	changed = 1;
    }

    /*
     * All the content for which this is the container window must now be
     * repositioned to take account of the new internal border width. To
     * signal all the geometry managers to do this, trigger a ConfigureNotify

     * event. This will cause geometry managers to recompute everything.
     */

    if (changed) {
	TkDoConfigureNotify(winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetInternalBorder --







|

|
>
|



|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    }
    if (bottom != winPtr->internalBorderBottom) {
	winPtr->internalBorderBottom = bottom;
	changed = 1;
    }

    /*
     * 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.
     */

    if (changed) {
	Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetInternalBorder --
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 */

void
Tk_SetMinimumRequestSize(
    Tk_Window tkwin,		/* Window that will have internal border. */
    int minWidth, int minHeight)/* Minimum requested size, in pixels. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if ((winPtr->minReqWidth == minWidth) &&
	    (winPtr->minReqHeight == minHeight)) {
	return;
    }

    winPtr->minReqWidth = minWidth;







|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
 */

void
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;

    if ((winPtr->minReqWidth == minWidth) &&
	    (winPtr->minReqHeight == minHeight)) {
	return;
    }

    winPtr->minReqWidth = minWidth;
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

    Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetGeometryContainer --
 *
 *	Set a geometry container for this window. Only one container may own
 *	a window at any time.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The geometry container is recorded for the window.
 *
 *----------------------------------------------------------------------
 */

int
TkSetGeometryContainer(
    Tcl_Interp *interp,		/* Current interpreter, for error. */
    Tk_Window tkwin,		/* Window that will have geometry container
				 * set. */
    const char *name)		/* The name of the geometry manager. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, name) == 0) {
	return TCL_OK;
    }
    if (winPtr->geomMgrName != NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cannot use geometry manager %s inside %s because"
		    " %s is already managing it's content windows",
		    name, Tk_PathName(tkwin), winPtr->geomMgrName));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL);
	}
	return TCL_ERROR;
    }

    winPtr->geomMgrName = (char *)ckalloc(strlen(name) + 1);
    strcpy(winPtr->geomMgrName, name);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeGeometryContainer --
 *
 *	Remove a geometry container for this window. Only one container may own
 *	a window at any time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The geometry container is cleared for the window.
 *
 *----------------------------------------------------------------------
 */

void
TkFreeGeometryContainer(
    Tk_Window tkwin,		/* Window that will have geometry container
				 * cleared. */
    const char *name)		/* The name of the geometry manager. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, name) != 0) {
	Tcl_Panic("Trying to free %s from geometry manager %s",
		winPtr->geomMgrName, name);
    }
    if (winPtr->geomMgrName != NULL) {
	ckfree(winPtr->geomMgrName);
	winPtr->geomMgrName = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MaintainGeometry --
 *
 *	This procedure is invoked by geometry managers to handle content whose
 *	container's are not their parents. It translates the desired geometry for
 *	the content into the coordinate system of the parent and respositions
 *	the content if it isn't already at the right place. Furthermore, it sets
 *	up event handlers so that if the container (or any of its ancestors up to
 *	the content's parent) is mapped, unmapped, or moved, then the content will
 *	be adjusted to match.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Event handlers are created and state is allocated to keep track of
 *	content. Note: if content was already managed for container 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(
    Tk_Window window,		/* Window for geometry management. */
    Tk_Window container,		/* Container for window; must be a descendant of
				 * window's parent. */
    int x, int y,		/* Desired position of window within container. */
    int width, int height)	/* Desired dimensions for window. */
{
    Tcl_HashEntry *hPtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr;
    int isNew, map;
    Tk_Window ancestor, parent;
    TkDisplay *dispPtr = ((TkWindow *) container)->dispPtr;

    ((TkWindow *)window)->maintainerPtr = (TkWindow *)container;

    if (container == Tk_Parent(window)) {
	/*
	 * If the window is a direct descendant of the container, don't bother
	 * setting up the extra infrastructure for management, just make a
	 * call to Tk_MoveResizeWindow; the parent/child relationship will
	 * take care of the rest.
	 */

	Tk_MoveResizeWindow(window, x, y, width, height);

	/*
	 * Map the window if the container is already mapped; otherwise, wait
	 * until the container is mapped later (in which case mapping the window
	 * is taken care of elsewhere).
	 */

	if (Tk_IsMapped(container)) {
	    Tk_MapWindow(window);
	}
	return;
    }

    if (!dispPtr->geomInit) {
	dispPtr->geomInit = 1;
	Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
     * See if there is already a MaintainContainer structure for the container; if
     * not, then create one.
     */

    parent = Tk_Parent(window);
    hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable,
	    (char *) container, &isNew);
    if (!isNew) {
	containerPtr = (MaintainContainer *)Tcl_GetHashValue(hPtr);
    } else {
	containerPtr = (MaintainContainer *)ckalloc(sizeof(MaintainContainer));
	containerPtr->ancestor = container;
	containerPtr->checkScheduled = 0;
	containerPtr->contentPtr = NULL;
	Tcl_SetHashValue(hPtr, containerPtr);
    }

    /*
     * Create a MaintainContent structure for the window if there isn't already
     * one.
     */

    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if (contentPtr->content == window) {
	    goto gotContent;
	}
    }
    contentPtr = (MaintainContent *)ckalloc(sizeof(MaintainContent));
    contentPtr->content = window;
    contentPtr->container = container;
    contentPtr->nextPtr = containerPtr->contentPtr;
    containerPtr->contentPtr = contentPtr;
    Tk_CreateEventHandler(window, StructureNotifyMask, MaintainContentProc,
	    contentPtr);

    /*
     * Make sure that there are event handlers registered for all the windows
     * between container and windows's parent (including container but not window's
     * parent). There may already be handlers for container and some of its
     * ancestors (containerPtr->ancestor tells how many).
     */

    for (ancestor = container; ancestor != parent;
	    ancestor = Tk_Parent(ancestor)) {
	if (ancestor == containerPtr->ancestor) {
	    Tk_CreateEventHandler(ancestor, StructureNotifyMask,
		    MaintainContainerProc, containerPtr);
	    containerPtr->ancestor = Tk_Parent(ancestor);
	}
    }

    /*
     * Fill in up-to-date information in the structure, then update the window
     * if it's not currently in the right place or state.
     */

  gotContent:
    contentPtr->x = x;
    contentPtr->y = y;
    contentPtr->width = width;
    contentPtr->height = height;
    map = 1;
    for (ancestor = contentPtr->container; ; ancestor = Tk_Parent(ancestor)) {
	if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
	    map = 0;
	}
	if (ancestor == parent) {
	    if ((x != Tk_X(contentPtr->content))
		    || (y != Tk_Y(contentPtr->content))
		    || (width != Tk_Width(contentPtr->content))
		    || (height != Tk_Height(contentPtr->content))) {
		Tk_MoveResizeWindow(contentPtr->content, x, y, width, height);
	    }
	    if (map) {
		Tk_MapWindow(contentPtr->content);
	    } else {
		Tk_UnmapWindow(contentPtr->content);
	    }
	    break;
	}
	x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_UnmaintainGeometry --
 *
 *	This procedure cancels a previous Tk_MaintainGeometry call, so that
 *	the relationship between window and container is no longer maintained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The window is unmapped and state is released, so that window won't track
 *	container any more. If we weren't previously managing window relative to
 *	container, then this procedure has no effect.
 *
 *----------------------------------------------------------------------
 */

void
Tk_UnmaintainGeometry(
    Tk_Window window,		/* WIndow for geometry management. */
    Tk_Window container)		/* Container for window; must be a descendant of
				 * window's parent. */
{
    Tcl_HashEntry *hPtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr, *prevPtr;
    Tk_Window ancestor;
    TkDisplay *dispPtr = ((TkWindow *) window)->dispPtr;

    ((TkWindow *)window)->maintainerPtr = NULL;

    if (container == Tk_Parent(window)) {
	/*
	 * If the window is a direct descendant of the container,
	 * Tk_MaintainGeometry will not have set up any of the extra
	 * 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);
    }

    if (!(((TkWindow *) window)->flags & TK_ALREADY_DEAD)) {
	Tk_UnmapWindow(window);
    }
    hPtr = Tcl_FindHashEntry(&dispPtr->maintainHashTable, container);
    if (hPtr == NULL) {
	return;
    }
    containerPtr = (MaintainContainer *)Tcl_GetHashValue(hPtr);
    contentPtr = containerPtr->contentPtr;
    if (contentPtr->content == window) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = contentPtr, contentPtr = contentPtr->nextPtr; ;
		prevPtr = contentPtr, contentPtr = contentPtr->nextPtr) {
	    if (contentPtr == NULL) {
		return;
	    }
	    if (contentPtr->content == window) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
    Tk_DeleteEventHandler(contentPtr->content, StructureNotifyMask,
	    MaintainContentProc, contentPtr);
    ckfree(contentPtr);
    if (containerPtr->contentPtr == NULL) {
	if (containerPtr->ancestor != NULL) {
	    for (ancestor = container; ; ancestor = Tk_Parent(ancestor)) {
		Tk_DeleteEventHandler(ancestor, StructureNotifyMask,
			MaintainContainerProc, containerPtr);
		if (ancestor == containerPtr->ancestor) {
		    break;
		}
	    }
	}
	if (containerPtr->checkScheduled) {
	    Tcl_CancelIdleCall(MaintainCheckProc, containerPtr);
	}
	Tcl_DeleteHashEntry(hPtr);
	ckfree(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainContainerProc --
 *
 *	This procedure is invoked by the Tk event dispatcher in response to
 *	StructureNotify events on the container 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 windows of the container. Or, if the container window is being
 *	deleted then state is cleaned up.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainContainerProc(
    ClientData clientData,	/* Pointer to MaintainContainer structure for the
				 * container window. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainContainer *containerPtr = (MaintainContainer *)clientData;
    MaintainContent *contentPtr;
    int done;

    if ((eventPtr->type == ConfigureNotify)
	    || (eventPtr->type == MapNotify)
	    || (eventPtr->type == UnmapNotify)) {
	if (!containerPtr->checkScheduled) {
	    containerPtr->checkScheduled = 1;
	    Tcl_DoWhenIdle(MaintainCheckProc, containerPtr);
	}
    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * Delete all of the state associated with this container, but be careful
	 * not to use containerPtr after the last window is deleted, since its
	 * memory will have been freed.
	 */

	done = 0;
	do {
	    contentPtr = containerPtr->contentPtr;
	    if (contentPtr->nextPtr == NULL) {
		done = 1;
	    }
	    Tk_UnmaintainGeometry(contentPtr->content, contentPtr->container);
	} while (!done);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainContentProc --
 *
 *	This procedure is invoked by the Tk event dispatcher in response to
 *	StructureNotify events on a window 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 window are deleted.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainContentProc(
    ClientData clientData,	/* Pointer to MaintainContent structure for
				 * container-window pair. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainContent *contentPtr = (MaintainContent *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_UnmaintainGeometry(contentPtr->content, contentPtr->container);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainCheckProc --
 *
 *	This procedure is invoked by the Tk event dispatcher as an idle
 *	handler, when a container or one of its ancestors has been reconfigured,
 *	mapped, or unmapped. Its job is to scan all of the windows for the
 *	container and reposition them, map them, or unmap them as needed to
 *	maintain their geometry relative to the container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Windows can get repositioned, mapped, or unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainCheckProc(
    ClientData clientData)	/* Pointer to MaintainContainer structure for the
				 * container window. */
{
    MaintainContainer *containerPtr = (MaintainContainer *)clientData;
    MaintainContent *contentPtr;
    Tk_Window ancestor, parent;
    int x, y, map;

    containerPtr->checkScheduled = 0;
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	parent = Tk_Parent(contentPtr->content);
	x = contentPtr->x;
	y = contentPtr->y;
	map = 1;
	for (ancestor = contentPtr->container; ; ancestor = Tk_Parent(ancestor)) {
	    if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
		map = 0;
	    }
	    if (ancestor == parent) {
		if ((x != Tk_X(contentPtr->content))
			|| (y != Tk_Y(contentPtr->content))) {
		    Tk_MoveWindow(contentPtr->content, x, y);
		}
		if (map) {
		    Tk_MapWindow(contentPtr->content);
		} else {
		    Tk_UnmapWindow(contentPtr->content);
		}
		break;
	    }
	    x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	    y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
	}
    }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|
|
|
|







|










|
|
|
|
|


|
|


|

<
<
|

|





|


|
|



|
|










|



|

|

|

|
|
|
|
|



|



|
|
|
|


|
|
|
|
|
|
|



|
|
|


|

|

|
|








|
|
|
|
|

|




|
|
|
|
|


|

|














|





|
|
|






|
|
|


|
|

|

<
<
|

|











|
|

|



|
|
|
|

|
|
|


|
|




|
|
|
|
|
|

|
|




|
|


|






|


|








|






|
|
|


|
|





|
|
|



|
|





|
|


|







|


|







|





|
|
|


|


|









|
|
|
|





|






|
|

|
|



|
|
|
|
|
|

|




|
|
|


|

|







300
301
302
303
304
305
306


















































































307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490


491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

    Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
}

/*
 *----------------------------------------------------------------------
 *


















































































 * 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.
 *
 * 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).
 *
 *----------------------------------------------------------------------
 */

void
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 isNew, map;
    Tk_Window ancestor, parent;
    TkDisplay *dispPtr = ((TkWindow *) master)->dispPtr;



    if (master == Tk_Parent(slave)) {
	/*
	 * If the slave is a direct descendant of the master, don't bother
	 * setting up the extra infrastructure for management, just make a
	 * call to Tk_MoveResizeWindow; the parent/child relationship will
	 * take care of the rest.
	 */

	Tk_MoveResizeWindow(slave, x, y, width, height);

	/*
	 * Map the slave if the master is already mapped; otherwise, wait
	 * until the master is mapped later (in which case mapping the slave
	 * is taken care of elsewhere).
	 */

	if (Tk_IsMapped(master)) {
	    Tk_MapWindow(slave);
	}
	return;
    }

    if (!dispPtr->geomInit) {
	dispPtr->geomInit = 1;
	Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
     * 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, &isNew);
    if (!isNew) {
	masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr);
    } else {
	masterPtr = (MaintainMaster *) ckalloc(sizeof(MaintainMaster));
	masterPtr->ancestor = master;
	masterPtr->checkScheduled = 0;
	masterPtr->slavePtr = NULL;
	Tcl_SetHashValue(hPtr, masterPtr);
    }

    /*
     * Create a MaintainSlave structure for the slave if there isn't already
     * one.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if (slavePtr->slave == slave) {
	    goto gotSlave;
	}
    }
    slavePtr = (MaintainSlave *) ckalloc(sizeof(MaintainSlave));
    slavePtr->slave = slave;
    slavePtr->master = master;
    slavePtr->nextPtr = masterPtr->slavePtr;
    masterPtr->slavePtr = slavePtr;
    Tk_CreateEventHandler(slave, StructureNotifyMask, MaintainSlaveProc,
	    (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).
     */

    for (ancestor = master; ancestor != parent;
	    ancestor = Tk_Parent(ancestor)) {
	if (ancestor == masterPtr->ancestor) {
	    Tk_CreateEventHandler(ancestor, StructureNotifyMask,
		    MaintainMasterProc, (ClientData) masterPtr);
	    masterPtr->ancestor = Tk_Parent(ancestor);
	}
    }

    /*
     * 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:
    slavePtr->x = x;
    slavePtr->y = y;
    slavePtr->width = width;
    slavePtr->height = height;
    map = 1;
    for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) {
	if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
	    map = 0;
	}
	if (ancestor == parent) {
	    if ((x != Tk_X(slavePtr->slave))
		    || (y != Tk_Y(slavePtr->slave))
		    || (width != Tk_Width(slavePtr->slave))
		    || (height != Tk_Height(slavePtr->slave))) {
		Tk_MoveResizeWindow(slavePtr->slave, x, y, width, height);
	    }
	    if (map) {
		Tk_MapWindow(slavePtr->slave);
	    } else {
		Tk_UnmapWindow(slavePtr->slave);
	    }
	    break;
	}
	x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_UnmaintainGeometry --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

void
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;
    register MaintainSlave *slavePtr, *prevPtr;
    Tk_Window ancestor;
    TkDisplay *dispPtr = ((TkWindow *) slave)->dispPtr;



    if (master == Tk_Parent(slave)) {
	/*
	 * 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.
	 */
	return;
    }

    if (!dispPtr->geomInit) {
	dispPtr->geomInit = 1;
	Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
    }

    if (!(((TkWindow *) slave)->flags & TK_ALREADY_DEAD)) {
	Tk_UnmapWindow(slave);
    }
    hPtr = Tcl_FindHashEntry(&dispPtr->maintainHashTable, (char *) master);
    if (hPtr == NULL) {
	return;
    }
    masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr);
    slavePtr = masterPtr->slavePtr;
    if (slavePtr->slave == slave) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    } else {
	for (prevPtr = slavePtr, slavePtr = slavePtr->nextPtr; ;
		prevPtr = slavePtr, slavePtr = slavePtr->nextPtr) {
	    if (slavePtr == NULL) {
		return;
	    }
	    if (slavePtr->slave == slave) {
		prevPtr->nextPtr = slavePtr->nextPtr;
		break;
	    }
	}
    }
    Tk_DeleteEventHandler(slavePtr->slave, StructureNotifyMask,
	    MaintainSlaveProc, (ClientData) slavePtr);
    ckfree((char *) slavePtr);
    if (masterPtr->slavePtr == NULL) {
	if (masterPtr->ancestor != NULL) {
	    for (ancestor = master; ; ancestor = Tk_Parent(ancestor)) {
		Tk_DeleteEventHandler(ancestor, StructureNotifyMask,
			MaintainMasterProc, (ClientData) masterPtr);
		if (ancestor == masterPtr->ancestor) {
		    break;
		}
	    }
	}
	if (masterPtr->checkScheduled) {
	    Tcl_CancelIdleCall(MaintainCheckProc, (ClientData) masterPtr);
	}
	Tcl_DeleteHashEntry(hPtr);
	ckfree((char *) masterPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainMasterProc(
    ClientData clientData,	/* Pointer to MaintainMaster structure for the
				 * master window. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainMaster *masterPtr = (MaintainMaster *) clientData;
    MaintainSlave *slavePtr;
    int done;

    if ((eventPtr->type == ConfigureNotify)
	    || (eventPtr->type == MapNotify)
	    || (eventPtr->type == UnmapNotify)) {
	if (!masterPtr->checkScheduled) {
	    masterPtr->checkScheduled = 1;
	    Tcl_DoWhenIdle(MaintainCheckProc, (ClientData) masterPtr);
	}
    } 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.
	 */

	done = 0;
	do {
	    slavePtr = masterPtr->slavePtr;
	    if (slavePtr->nextPtr == NULL) {
		done = 1;
	    }
	    Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master);
	} while (!done);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainSlaveProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainSlaveProc(
    ClientData clientData,	/* Pointer to MaintainSlave structure for
				 * master-slave pair. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainSlave *slavePtr = (MaintainSlave *) clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Slaves can get repositioned, mapped, or unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainCheckProc(
    ClientData clientData)	/* Pointer to MaintainMaster structure for the
				 * master window. */
{
    MaintainMaster *masterPtr = (MaintainMaster *) clientData;
    MaintainSlave *slavePtr;
    Tk_Window ancestor, parent;
    int x, y, map;

    masterPtr->checkScheduled = 0;
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	parent = Tk_Parent(slavePtr->slave);
	x = slavePtr->x;
	y = slavePtr->y;
	map = 1;
	for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) {
	    if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
		map = 0;
	    }
	    if (ancestor == parent) {
		if ((x != Tk_X(slavePtr->slave))
			|| (y != Tk_Y(slavePtr->slave))) {
		    Tk_MoveWindow(slavePtr->slave, x, y);
		}
		if (map) {
		    Tk_MapWindow(slavePtr->slave);
		} else {
		    Tk_UnmapWindow(slavePtr->slave);
		}
		break;
	    }
	    x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	    y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
	}
    }

Changes to generic/tkGet.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * 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 {
    int initialized;
    Tcl_HashTable uidTable;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		FreeUidThreadExitProc(ClientData clientData);

/*
 * The following tables defines the string values for reliefs, which are
 * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj.
 */

static const char *const anchorStrings[] = {
    "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL
};
static const char *const justifyStrings[] = {
    "left", "right", "center", NULL
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetAnchorFromObj --







|












|


|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * 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 {
    int initialized;
    Tcl_HashTable uidTable;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		FreeUidThreadExitProc(ClientData clientData);

/*
 * The following tables defines the string values for reliefs, which are
 * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj.
 */

static CONST char *anchorStrings[] = {
    "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL
};
static CONST char *justifyStrings[] = {
    "left", "right", "center", NULL
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetAnchorFromObj --
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 *
 *--------------------------------------------------------------
 */

int
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;







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 *
 *--------------------------------------------------------------
 */

int
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;
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
	    *anchorPtr = TK_ANCHOR_CENTER;
	    return TCL_OK;
	}
	goto error;
    }

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad anchor position \"%s\": must be"
	    " n, ne, e, se, s, sw, w, nw, or center", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "ANCHOR", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfAnchor --
 *
 *	Given a Tk_Anchor, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
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";







<
|
|
<



















|







148
149
150
151
152
153
154

155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
	    *anchorPtr = TK_ANCHOR_CENTER;
	    return TCL_OK;
	}
	goto error;
    }

  error:

    Tcl_AppendResult(interp, "bad anchor position \"", string,
	    "\": must be n, ne, e, se, s, sw, w, nw, or center", NULL);

    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfAnchor --
 *
 *	Given a Tk_Anchor, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
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";
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
	return TCL_OK;
    }
    if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
	*joinPtr = JoinRound;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad join style \"%s\": must be bevel, miter, or round",
	    string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "JOIN", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfJoinStyle --
 *
 *	Given a Tk JoinStyle, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOfJoinStyle(
    int join)			/* Join style for which identifying string is
				 * desired. */
{
    switch (join) {
    case JoinBevel: return "bevel";
    case JoinMiter: return "miter";







|
|
<
<



















|







233
234
235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
	return TCL_OK;
    }
    if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
	*joinPtr = JoinRound;
	return TCL_OK;
    }

    Tcl_AppendResult(interp, "bad join style \"", string,
	    "\": must be bevel, miter, or round", NULL);


    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfJoinStyle --
 *
 *	Given a Tk JoinStyle, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfJoinStyle(
    int join)			/* Join style for which identifying string is
				 * desired. */
{
    switch (join) {
    case JoinBevel: return "bevel";
    case JoinMiter: return "miter";
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];







|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
	return TCL_OK;
    }
    if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
	*capPtr = CapRound;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad cap style \"%s\": must be butt, projecting, or round",
	    string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "CAP", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfCapStyle --
 *
 *	Given a Tk CapStyle, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_NameOfCapStyle(
    int cap)			/* Cap style for which identifying string is
				 * desired. */
{
    switch (cap) {
    case CapButt: return "butt";
    case CapProjecting: return "projecting";







|
|
<
<



















|







312
313
314
315
316
317
318
319
320


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
	return TCL_OK;
    }
    if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
	*capPtr = CapRound;
	return TCL_OK;
    }

    Tcl_AppendResult(interp, "bad cap style \"", string,
	    "\": must be butt, projecting, or round", NULL);


    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfCapStyle --
 *
 *	Given a Tk CapStyle, return the string that corresponds to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfCapStyle(
    int cap)			/* Cap style for which identifying string is
				 * desired. */
{
    switch (cap) {
    case CapButt: return "butt";
    case CapProjecting: return "projecting";
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];







|







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
 *
 *--------------------------------------------------------------
 */

int
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;

    c = string[0];
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
	return TCL_OK;
    }
    if ((c == 'c') && (strncmp(string, "center", length) == 0)) {
	*justifyPtr = TK_JUSTIFY_CENTER;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad justification \"%s\": must be left, right, or center",
	    string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "JUSTIFY", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfJustify --
 *
 *	Given a Tk_Justify, return the string that corresponds
 *	to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
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";







|
|
<
<




















|







428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	return TCL_OK;
    }
    if ((c == 'c') && (strncmp(string, "center", length) == 0)) {
	*justifyPtr = TK_JUSTIFY_CENTER;
	return TCL_OK;
    }

    Tcl_AppendResult(interp, "bad justification \"", string,
	    "\": must be left, right, or center", NULL);


    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfJustify --
 *
 *	Given a Tk_Justify, return the string that corresponds
 *	to it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
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";
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
 *	All information in the identifier table is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeUidThreadExitProc(
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    Tcl_DeleteHashTable(&tsdPtr->uidTable);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *







|


|
<







481
482
483
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
 *	All information in the identifier table is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeUidThreadExitProc(
    ClientData clientData)		/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    Tcl_DeleteHashTable(&tsdPtr->uidTable);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
 *	New information may be entered into the identifier table.
 *
 *----------------------------------------------------------------------
 */

Tk_Uid
Tk_GetUid(
    const char *string)		/* String to convert. */
{
    int dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_HashTable *tablePtr = &tsdPtr->uidTable;

    if (!tsdPtr->initialized) {







|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
 *	New information may be entered into the identifier table.
 *
 *----------------------------------------------------------------------
 */

Tk_Uid
Tk_GetUid(
    CONST char *string)		/* String to convert. */
{
    int dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_HashTable *tablePtr = &tsdPtr->uidTable;

    if (!tsdPtr->initialized) {
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579


580
581
582
583
584
585
586

int
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. */
{
    char *end;
    double d;

    d = strtod(string, &end);
    if (end == string) {
	goto error;


    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    switch (*end) {
    case 0:
	d /= WidthOfScreen(Tk_Screen(tkwin));







|







|
>
>







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

int
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. */
{
    char *end;
    double d;

    d = strtod(string, &end);
    if (end == string) {
	error:
	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));
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad screen distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "SCREEN_DISTANCE", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetPixels --
 *







<
<
<
<
<
<







601
602
603
604
605
606
607






608
609
610
611
612
613
614
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;






}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetPixels --
 *
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

int
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. */
{
    double d;

    if (TkGetDoublePixels(interp, tkwin, string, &d) != TCL_OK) {
	return TCL_ERROR;
    }







|







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

int
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. */
{
    double d;

    if (TkGetDoublePixels(interp, tkwin, string, &d) != TCL_OK) {
	return TCL_ERROR;
    }
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699


700
701
702
703
704
705
706
 *
 * TkGetDoublePixels --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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. */
{
    char *end;
    double d;

    d = strtod((char *) string, &end);
    if (end == string) {
	goto error;


    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    switch (*end) {
    case 0:
	break;







>

















|







|
>
>







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
 *
 * TkGetDoublePixels --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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. */
{
    char *end;
    double d;

    d = strtod((char *) string, &end);
    if (end == string) {
    error:
	Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL);
	return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    switch (*end) {
    case 0:
	break;
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad screen distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<









721
722
723
724
725
726
727






728
729
730
731
732
733
734
735
736
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;






}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkGrab.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif !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







|

|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#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
128
129
130
131
132
133
134
135











136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * 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.
 */

#define GENERATED_GRAB_EVENT_MAGIC ((Bool) 0x147321ac)












/*
 * Forward declarations for functions declared later in this file:
 */

static void		EatGrabEvents(TkDisplay *dispPtr, unsigned int serial);
static TkWindow *	FindCommonAncestor(TkWindow *winPtr1,
			    TkWindow *winPtr2, int *countPtr1, int *countPtr2);
static Tk_RestrictProc GrabRestrictProc;
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);








|
>
>
>
>
>
>
>
>
>
>
>








|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * 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.
 */

#define GENERATED_EVENT_MAGIC ((Bool) 0x147321ac)

/*
 * Mask that selects any of the state bits corresponding to buttons, plus
 * masks that select individual buttons' bits:
 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)
static unsigned int buttonStates[] = {
    Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask
};

/*
 * Forward declarations for functions declared later in this file:
 */

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);

162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    TkSizeT len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const 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
	 * read:
	 * wrong # args: should be "cmd ?-global? window" or "cmd option
	 *    ?arg ...?"
	 * We can fake it with Tcl_WrongNumArgs if we assume the command name
	 * is "grab", but if it has been aliased, the message will be
	 * incorrect.
	 */

	Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]),
		" option ?arg ...?\"", NULL);
	/* This API not exposed:
	 *
	((Interp *) interp)->flags |= INTERP_ALTERNATE_WRONG_ARGS;
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	 */
	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = TkGetStringFromObj(objv[1], &len);
    if (arg[0] == '.') {
	/* [grab window] */
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, arg, (Tk_Window)clientData);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 0);
    } else if (arg[0] == '-' && len > 1) {
	if (Tcl_GetIndexFromObj(interp, objv[1], flagStrings, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/* [grab -global window] */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), (Tk_Window)clientData);

	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 1);
    }

    /*







>





|




|

|
|


|










|
|




|
|
|
|
<
<
<
<
<







|






|















|
>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217





218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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;
    TkDisplay *dispPtr;
    char *arg;
    int index;
    int len;
    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
	 * read:
	 * wrong # args: should be "cmd ?-global window" or "cmd option
	 *    ?arg arg ...?"
	 * We can fake it with Tcl_WrongNumArgs if we assume the command name
	 * is "grab", but if it has been aliased, the message will be
	 * incorrect.
	 */
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		Tcl_GetString(objv[0]), " ?-global? window\" or \"",
		Tcl_GetString(objv[0]), " option ?arg arg ...?\"", NULL);





	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = Tcl_GetStringFromObj(objv[1], &len);
    if (arg[0] == '.') {
	/* [grab window] */
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, arg, (Tk_Window) clientData);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 0);
    } else if (arg[0] == '-' && len > 1) {
	if (Tcl_GetIndexFromObj(interp, objv[1], flagStrings, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/* [grab -global window] */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		(Tk_Window) clientData);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	return Tk_Grab(interp, tkwin, 1);
    }

    /*
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
	/* [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;
	    }
	    dispPtr = ((TkWindow *) tkwin)->dispPtr;
	    if (dispPtr->eventualGrabWinPtr != NULL) {
		Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			dispPtr->eventualGrabWinPtr));

	    }
	} else {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		    dispPtr = dispPtr->nextPtr) {
		if (dispPtr->eventualGrabWinPtr != NULL) {
		    Tcl_ListObjAppendElement(NULL, resultObj, Tk_NewWindowObj(
			    (Tk_Window) dispPtr->eventualGrabWinPtr));
		}
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	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_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);

    case GRABCMD_STATUS: {
	/* [grab status window] */
	TkWindow *winPtr;
	const char *statusString;

	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) {
	    statusString = "none";
	} else if (dispPtr->grabFlags & GRAB_GLOBAL) {
	    statusString = "global";
	} else {
	    statusString = "local";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(statusString, -1));
	break;
    }
    }

    return TCL_OK;
}








|





<
|
>


<
<



|
|


<









|
>
















|















|









<






|





|

|

|

<







268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284


285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
	/* [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;
	    }
	    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_AppendElement(interp,
			    dispPtr->eventualGrabWinPtr->pathName);
		}
	    }

	}
	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_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);

    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;
}

404
405
406
407
408
409
410
411



412
413
414
415
416
417
418
    ReleaseButtonGrab(dispPtr);
    if (dispPtr->eventualGrabWinPtr != NULL) {
	if ((dispPtr->eventualGrabWinPtr == winPtr)
		&& (grabGlobal == ((dispPtr->grabFlags & GRAB_GLOBAL) != 0))) {
	    return TCL_OK;
	}
	if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) {
	    goto alreadyGrabbed;



	}
	Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr);
    }

    Tk_MakeWindowExist(tkwin);
    if (!grabGlobal) {
	Window dummy1, dummy2;







|
>
>
>







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
    ReleaseButtonGrab(dispPtr);
    if (dispPtr->eventualGrabWinPtr != NULL) {
	if ((dispPtr->eventualGrabWinPtr == winPtr)
		&& (grabGlobal == ((dispPtr->grabFlags & GRAB_GLOBAL) != 0))) {
	    return TCL_OK;
	}
	if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) {
	alreadyGrabbed:
	    Tcl_SetResult(interp, "grab failed: another application has grab",
		    TCL_STATIC);
	    return TCL_ERROR;
	}
	Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr);
    }

    Tk_MakeWindowExist(tkwin);
    if (!grabGlobal) {
	Window dummy1, dummy2;
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
	 * (b) it allows us to track mouse motion among all of the windows of
	 * this application.
	 */

	dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL);
	XQueryPointer(dispPtr->display, winPtr->window, &dummy1,
		&dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &state);
	if (state & ALL_BUTTONS) {
	    dispPtr->grabFlags |= GRAB_TEMP_GLOBAL;
	    goto setGlobalGrab;
	}
    } else {
	dispPtr->grabFlags |= GRAB_GLOBAL;
    setGlobalGrab:








|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
	 * (b) it allows us to track mouse motion among all of the windows of
	 * this application.
	 */

	dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL);
	XQueryPointer(dispPtr->display, winPtr->window, &dummy1,
		&dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &state);
	if ((state & ALL_BUTTONS) != 0) {
	    dispPtr->grabFlags |= GRAB_TEMP_GLOBAL;
	    goto setGlobalGrab;
	}
    } else {
	dispPtr->grabFlags |= GRAB_GLOBAL;
    setGlobalGrab:

465
466
467
468
469
470
471
472



















473
474
475
476
477
478
479
		    None, CurrentTime);
	    if (grabResult != AlreadyGrabbed) {
		break;
	    }
	    Tcl_Sleep(100);
	}
	if (grabResult != 0) {
	    goto grabError;



















	}
	grabResult = XGrabKeyboard(dispPtr->display, Tk_WindowId(tkwin),
		False, GrabModeAsync, GrabModeAsync, CurrentTime);
	if (grabResult != 0) {
	    XUngrabPointer(dispPtr->display, CurrentTime);
	    goto grabError;
	}







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
		    None, CurrentTime);
	    if (grabResult != AlreadyGrabbed) {
		break;
	    }
	    Tcl_Sleep(100);
	}
	if (grabResult != 0) {
	grabError:
	    if (grabResult == GrabNotViewable) {
		Tcl_SetResult(interp, "grab failed: window not viewable",
			TCL_STATIC);
	    } else if (grabResult == AlreadyGrabbed) {
		goto alreadyGrabbed;
	    } else if (grabResult == GrabFrozen) {
		Tcl_SetResult(interp,
			"grab failed: keyboard or pointer frozen", TCL_STATIC);
	    } else if (grabResult == GrabInvalidTime) {
		Tcl_SetResult(interp, "grab failed: invalid time",
			TCL_STATIC);
	    } else {
		char msg[64 + TCL_INTEGER_SPACE];

		sprintf(msg, "grab failed for unknown reason (code %d)",
			grabResult);
		Tcl_AppendResult(interp, msg, NULL);
	    }
	    return TCL_ERROR;
	}
	grabResult = XGrabKeyboard(dispPtr->display, Tk_WindowId(tkwin),
		False, GrabModeAsync, GrabModeAsync, CurrentTime);
	if (grabResult != 0) {
	    XUngrabPointer(dispPtr->display, CurrentTime);
	    goto grabError;
	}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
		MovePointer2(dispPtr->serverWinPtr, winPtr, NotifyGrab, 1, 0);
		break;
	    }
	}
    }
    QueueGrabWindowChange(dispPtr, winPtr);
    return TCL_OK;

  grabError:
    if (grabResult == GrabNotViewable) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: window not viewable", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNVIEWABLE", NULL);
    } else if (grabResult == AlreadyGrabbed) {
    alreadyGrabbed:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: another application has grab", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "GRABBED", NULL);
    } else if (grabResult == GrabFrozen) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: keyboard or pointer frozen", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "FROZEN", NULL);
    } else if (grabResult == GrabInvalidTime) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: invalid time", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "BAD_TIME", NULL);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"grab failed for unknown reason (code %d)", grabResult));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNKNOWN", NULL);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_Ungrab --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







539
540
541
542
543
544
545

























546
547
548
549
550
551
552
		MovePointer2(dispPtr->serverWinPtr, winPtr, NotifyGrab, 1, 0);
		break;
	    }
	}
    }
    QueueGrabWindowChange(dispPtr, winPtr);
    return TCL_OK;

























}

/*
 *----------------------------------------------------------------------
 *
 * Tk_Ungrab --
 *
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
 *	to its current window.
 *
 *----------------------------------------------------------------------
 */

static void
ReleaseButtonGrab(
    TkDisplay *dispPtr)/* Display whose button grab is to be
				 * released. */
{
    unsigned int serial;

    if (dispPtr->buttonWinPtr != NULL) {
	if (dispPtr->buttonWinPtr != dispPtr->serverWinPtr) {
	    MovePointer2(dispPtr->buttonWinPtr, dispPtr->serverWinPtr,







|







634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
 *	to its current window.
 *
 *----------------------------------------------------------------------
 */

static void
ReleaseButtonGrab(
    register TkDisplay *dispPtr)/* Display whose button grab is to be
				 * released. */
{
    unsigned int serial;

    if (dispPtr->buttonWinPtr != NULL) {
	if (dispPtr->buttonWinPtr != dispPtr->serverWinPtr) {
	    MovePointer2(dispPtr->buttonWinPtr, dispPtr->serverWinPtr,
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 *----------------------------------------------------------------------
 *
 * TkPointerEvent --
 *
 *	This function is called for each pointer-related event, before the
 *	event has been processed. It does various things to make grabs work
 *	correctly.
 *	Also, this function takes care of warping the mouse pointer with
 *	respect to a given window, both when there is a grab in effect and
 *	when there is none.
 *
 * 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 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.
 *	The mouse pointer may be moved.
 *
 *----------------------------------------------------------------------
 */

int
TkPointerEvent(
    XEvent *eventPtr,	/* Pointer to the event. */
    TkWindow *winPtr)		/* Tk's information for window where event was
				 * reported. */
{
    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. */







<
<
<











<






|



|







663
664
665
666
667
668
669



670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
 *----------------------------------------------------------------------
 *
 * TkPointerEvent --
 *
 *	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 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.

 *
 *----------------------------------------------------------------------
 */

int
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. */
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	/*
	 * 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_GRAB_EVENT_MAGIC) {
	    if ((eventPtr->type == LeaveNotify) &&
		    (winPtr->flags & TK_TOP_HIERARCHY)) {
		dispPtr->serverWinPtr = NULL;
	    } else {
		dispPtr->serverWinPtr = winPtr;
	    }
	}







|







720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
	/*
	 * 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) {
	    if ((eventPtr->type == LeaveNotify) &&
		    (winPtr->flags & TK_TOP_HIERARCHY)) {
		dispPtr->serverWinPtr = NULL;
	    } else {
		dispPtr->serverWinPtr = winPtr;
	    }
	}
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
		    && (winPtr != dispPtr->buttonWinPtr)) {
		return 0;
	    }
	}
	return 1;
    }

    if ((eventPtr->type == MotionNotify) && !appGrabbed) {

        /*
         * Warp the mouse pointer with respect to window dispPtr->warpWindow
         * if such a window was set in HandleEventGenerate.
         */

        TkDoWarpWrtWin(dispPtr);
    }

    if (!appGrabbed) {
	return 1;
    }

    /*
     * From this point on, there is a grab in effect.
     */

    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
	 * 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







<
<
<
<
<
<
<
<
<
<




<
<
<
<







770
771
772
773
774
775
776










777
778
779
780




781
782
783
784
785
786
787
		    && (winPtr != dispPtr->buttonWinPtr)) {
		return 0;
	    }
	}
	return 1;
    }











    if (!appGrabbed) {
	return 1;
    }





    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
	 * 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
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
	    winPtr2 = dispPtr->grabWinPtr;
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;
	}

        /*
         * Warp the mouse pointer with respect to window dispPtr->warpWindow
         * if such a window was set in HandleEventGenerate.
         */

        TkDoWarpWrtWin(dispPtr);
	return 1;
    }

    /*
     * Process ButtonPress and ButtonRelease events:
     * 1. Keep track of whether a button is down and what window it went down
     *    in.







<
<
<
<
<
<
<







796
797
798
799
800
801
802







803
804
805
806
807
808
809
	    winPtr2 = dispPtr->grabWinPtr;
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;
	}







	return 1;
    }

    /*
     * Process ButtonPress and ButtonRelease events:
     * 1. Keep track of whether a button is down and what window it went down
     *    in.
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
	    if (outsideGrabTree) {
		winPtr2 = dispPtr->grabWinPtr;			/* Note 5. */
	    } else {
		winPtr2 = winPtr;				/* Note 5. */
	    }
	}
	if (eventPtr->type == ButtonPress) {
	    if (!(eventPtr->xbutton.state & ALL_BUTTONS)) {
		if (outsideGrabTree) {
		    TkChangeEventWindow(eventPtr, dispPtr->grabWinPtr);
		    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
		    return 0;					/* Note 2. */
		}
		if (!(dispPtr->grabFlags & GRAB_GLOBAL)) {	/* Note 6. */
		    serial = NextRequest(dispPtr->display);







|







839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
	    if (outsideGrabTree) {
		winPtr2 = dispPtr->grabWinPtr;			/* Note 5. */
	    } else {
		winPtr2 = winPtr;				/* Note 5. */
	    }
	}
	if (eventPtr->type == ButtonPress) {
	    if ((eventPtr->xbutton.state & ALL_BUTTONS) == 0) {
		if (outsideGrabTree) {
		    TkChangeEventWindow(eventPtr, dispPtr->grabWinPtr);
		    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
		    return 0;					/* Note 2. */
		}
		if (!(dispPtr->grabFlags & GRAB_GLOBAL)) {	/* Note 6. */
		    serial = NextRequest(dispPtr->display);
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
			}
		    }
		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {
	    if (eventPtr->xbutton.button != AnyButton &&
		    ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == Tk_GetButtonMask(eventPtr->xbutton.button))) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */







<
|
|







866
867
868
869
870
871
872

873
874
875
876
877
878
879
880
881
			}
		    }
		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {

	    if ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == buttonStates[eventPtr->xbutton.button - Button1]) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkChangeEventWindow(
    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;
    TkWindow *childPtr;

    eventPtr->xmotion.window = Tk_WindowId(winPtr);
    if (eventPtr->xmotion.root ==
	    RootWindow(winPtr->display, winPtr->screenNum)) {
	Tk_GetRootCoords((Tk_Window) winPtr, &x, &y);
	eventPtr->xmotion.x = eventPtr->xmotion.x_root - x;
	eventPtr->xmotion.y = eventPtr->xmotion.y_root - y;







|






|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
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;

    eventPtr->xmotion.window = Tk_WindowId(winPtr);
    if (eventPtr->xmotion.root ==
	    RootWindow(winPtr->display, winPtr->screenNum)) {
	Tk_GetRootCoords((Tk_Window) winPtr, &x, &y);
	eventPtr->xmotion.x = eventPtr->xmotion.x_root - x;
	eventPtr->xmotion.y = eventPtr->xmotion.y_root - y;
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
				 * means don't generate leave events. */
    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. */
{
    TkWindow *winPtr;
    int upLevels, downLevels, i, j, focus;

    /*
     * There are four possible cases to deal with:
     *
     * 1. SourcePtr and destPtr are the same. There's nothing to do in this
     *    case.







|







990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
				 * means don't generate leave events. */
    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. */
{
    register TkWindow *winPtr;
    int upLevels, downLevels, i, j, focus;

    /*
     * There are four possible cases to deal with:
     *
     * 1. SourcePtr and destPtr are the same. There's nothing to do in this
     *    case.
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
	winPtr = destPtr;
	if ((winPtr == NULL) || (winPtr->window == None)) {
	    return;
	}
    }

    event.xcrossing.serial = LastKnownRequestProcessed(winPtr->display);
    event.xcrossing.send_event = GENERATED_GRAB_EVENT_MAGIC;
    event.xcrossing.display = winPtr->display;
    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,
	    &dummy3, &dummy4, &event.xcrossing.state);
    event.xcrossing.mode = mode;







|







1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
	winPtr = destPtr;
	if ((winPtr == NULL) || (winPtr->window == None)) {
	    return;
	}
    }

    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.time = TkCurrentTime(winPtr->dispPtr);
    XQueryPointer(winPtr->display, winPtr->window, &dummy1, &dummy2,
	    &event.xcrossing.x_root, &event.xcrossing.y_root,
	    &dummy3, &dummy4, &event.xcrossing.state);
    event.xcrossing.mode = mode;
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
 *	code.
 *
 *----------------------------------------------------------------------
 */

void
TkGrabDeadWindow(
    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.







|







1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
 *	code.
 *
 *----------------------------------------------------------------------
 */

void
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.
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285

static void
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 *prevProc;
    GrabInfo info;
    ClientData prevArg;

    info.display = dispPtr->display;
    info.serial = serial;
    TkpSync(info.display);
    prevProc = Tk_RestrictEvents(GrabRestrictProc, &info, &prevArg);
    while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	/* EMPTY */
    }
    Tk_RestrictEvents(prevProc, prevArg, &prevArg);
}

/*
 *----------------------------------------------------------------------
 *
 * GrabRestrictProc --
 *







|

|




|

<

|







1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258
1259

static void
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;
    GrabInfo info;
    ClientData oldArg, dummy;

    info.display = dispPtr->display;
    info.serial = serial;
    TkpSync(info.display);
    oldProc = Tk_RestrictEvents(GrabRestrictProc, (ClientData)&info, &oldArg);
    while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {

    }
    Tk_RestrictEvents(oldProc, oldArg, &dummy);
}

/*
 *----------------------------------------------------------------------
 *
 * GrabRestrictProc --
 *
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
 */

static Tk_RestrictAction
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.
     */







|







1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
 */

static Tk_RestrictAction
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.
     */
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
    TkDisplay *dispPtr,		/* Display on which to change the grab
				 * window. */
    TkWindow *grabWinPtr)	/* Window that is to become the new grab
				 * window (may be NULL). */
{
    NewGrabWinEvent *grabEvPtr;

    grabEvPtr = (NewGrabWinEvent *)ckalloc(sizeof(NewGrabWinEvent));
    grabEvPtr->header.proc = GrabWinEventProc;
    grabEvPtr->dispPtr = dispPtr;
    if (grabWinPtr == NULL) {
	grabEvPtr->grabWindow = None;
    } else {
	grabEvPtr->grabWindow = grabWinPtr->window;
    }







|







1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
    TkDisplay *dispPtr,		/* Display on which to change the grab
				 * window. */
    TkWindow *grabWinPtr)	/* Window that is to become the new grab
				 * window (may be NULL). */
{
    NewGrabWinEvent *grabEvPtr;

    grabEvPtr = (NewGrabWinEvent *) ckalloc(sizeof(NewGrabWinEvent));
    grabEvPtr->header.proc = GrabWinEventProc;
    grabEvPtr->dispPtr = dispPtr;
    if (grabWinPtr == NULL) {
	grabEvPtr->grabWindow = None;
    } else {
	grabEvPtr->grabWindow = grabWinPtr->window;
    }
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
 *
 *----------------------------------------------------------------------
 */

static int
GrabWinEventProc(
    Tcl_Event *evPtr,		/* Event of type NewGrabWinEvent. */
    TCL_UNUSED(int))			/* Flags argument to Tcl_DoOneEvent: indicates
				 * what kinds of events are being processed
				 * right now. */
{
    NewGrabWinEvent *grabEvPtr = (NewGrabWinEvent *) evPtr;

    grabEvPtr->dispPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(
	    grabEvPtr->dispPtr->display, grabEvPtr->grabWindow);







|







1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
 *
 *----------------------------------------------------------------------
 */

static int
GrabWinEventProc(
    Tcl_Event *evPtr,		/* Event of type NewGrabWinEvent. */
    int flags)			/* Flags argument to Tcl_DoOneEvent: indicates
				 * what kinds of events are being processed
				 * right now. */
{
    NewGrabWinEvent *grabEvPtr = (NewGrabWinEvent *) evPtr;

    grabEvPtr->dispPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(
	    grabEvPtr->dispPtr->display, grabEvPtr->grabWindow);
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
    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
				 * common ancestor here. */
{
    TkWindow *winPtr;
    TkWindow *ancestorPtr;
    int count1, count2, i;

    /*
     * Mark winPtr1 and all of its ancestors with a special flag bit.
     */








|







1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
    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
				 * common ancestor here. */
{
    register TkWindow *winPtr;
    TkWindow *ancestorPtr;
    int count1, count2, i;

    /*
     * Mark winPtr1 and all of its ancestors with a special flag bit.
     */

Changes to generic/tkGrid.c.

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Default value for 'grid anchor'.
 */

#define GRID_DEFAULT_ANCHOR TK_ANCHOR_NW

/*
 * Structure to hold information for grid containers. A slot is either a row or
 * column.
 */

typedef struct SlotInfo {
    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
				 * 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
				 * content 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. */
} 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.
 */

typedef struct GridLayout {
    struct Gridder *binNextPtr;	/* The next content window in this bin. Each bin
    				 * contains a list of all content 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 content 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
				 * group slots that should have the same
				 * size. */
    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;

/*
 * Keep one of these for each geometry container.
 */

typedef struct {
    SlotInfo *columnPtr;	/* Pointer to array of column constraints. */
    SlotInfo *rowPtr;		/* Pointer to array of row constraints. */
    int columnEnd;		/* The last column occupied by any content. */
    int columnMax;		/* The number of columns with constraints. */
    int columnSpace;		/* The number of slots currently allocated for
    				 * column constraints. */
    int rowEnd;			/* The last row occupied by any content. */
    int rowMax;			/* The number of rows with constraints. */
    int rowSpace;		/* The number of slots currently allocated for
    				 * row constraints. */
    int startX;			/* Pixel offset of this layout within its
    				 * container. */
    int startY;			/* Pixel offset of this layout within its
    				 * container. */
    Tk_Anchor anchor;		/* Value of anchor option: specifies where a
				 * grid without weight should be placed. */
} GridContainer;

/*
 * For each window that the grid cares about (either because the window is
 * managed by the grid or because the window has content 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 *containerPtr;	/* Container 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 container.
				 * List order doesn't matter. */
    struct Gridder *contentPtr;	/* First in list of content managed inside this
				 * window (NULL means no grid content). */
    GridContainer *containerDataPtr;	/* Additional data for geometry container. */
    Tcl_Obj *in;                /* Store container name when removed. */
    int column, row;		/* Location in the grid (starting from
				 * zero). */
    int numCols, numRows;	/* Number of columns or rows this content 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:
				 * 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 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 container. */
    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 content
				 * is deleted. */
    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 content in this bin. */
    int size;			/* Nominal size (width or height) in pixels of
    				 * the content. This includes the padding. */
} Gridder;

/*
 * 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.







|













|


















|
|




|


















|





|



|




|

|


|



|








|


|

|
|
|
|


|
















|




|








|

|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * 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).
				 * It is set via the rowconfigure or
				 * columnconfigure commands. */
    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
				 * 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. */
} 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.
 */

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. */
    int pad;			/* Padding needed for this slot */
    int weight;			/* Slot weight, controls resizing. */
    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 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;

/*
 * Keep one of these for each geometry master.
 */

typedef struct {
    SlotInfo *columnPtr;	/* Pointer to array of column constraints. */
    SlotInfo *rowPtr;		/* Pointer to array of row constraints. */
    int columnEnd;		/* The last column occupied by any slave. */
    int columnMax;		/* The number of columns with constraints. */
    int columnSpace;		/* The number of slots currently allocated for
    				 * 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 startX;			/* Pixel offset of this layout within its
    				 * master. */
    int startY;			/* Pixel offset of this layout within its
    				 * 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:
 */

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 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. */
    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:
				 * 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 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 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. */

    /*
     * 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. */
} Gridder;

/*
 * 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.
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
    int minSize;
} UniformGroup;

/*
 * Flag values for Grid structures:
 *
 * REQUESTED_RELAYOUT		1 means a Tcl_DoWhenIdle request has already
 *				been made to re-arrange all the content of this
 *				window.
 * DONT_PROPAGATE		1 means don't set this window's requested
 *				size. 0 means if this window is a container then
 *				Tk will set its requested size to fit the
 *				needs of its content.
 * ALLOCED_CONTAINER		1 means that Grid has allocated itself as
 *				geometry container for this window.
 */

#define REQUESTED_RELAYOUT	1
#define DONT_PROPAGATE		2
#define ALLOCED_CONTAINER	4

/*
 * Prototypes for procedures used only in this file:
 */

static void		AdjustForSticky(Gridder *contentPtr, 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 *containerPtr, int slot,
			    int slotType, int checkOnly);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyGrid(void *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		GridContentCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		GridLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		GridReqProc(ClientData clientData, Tk_Window tkwin);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(Tcl_WideInt, Tcl_WideInt);
static Tcl_Obj *	NewQuadObj(Tcl_WideInt, Tcl_WideInt, Tcl_WideInt, Tcl_WideInt);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,
			    int column, int numCols);
static int		SetContentRow(Tcl_Interp *interp, Gridder *contentPtr,
			    int row, int numRows);
static Tcl_Obj *	StickyToObj(int flags);
static int		StringToSticky(const char *string);
static void		Unlink(Gridder *gridPtr);

static const Tk_GeomMgr gridMgrType = {
    "grid",			/* name */
    GridReqProc,		/* requestProc */
    GridLostContentProc,		/* lostContentProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GridCmd --
 *







|


|

|
<
<




<





|




|

|
|
|


|

|


|

|


|


|


|

|
|
|


|


|
|
|



|

|

|
|





|







231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    int minSize;
} 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.


 */

#define REQUESTED_RELAYOUT	1
#define DONT_PROPAGATE		2


/*
 * Prototypes for procedures used only in this file:
 */

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 --
 *
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
 */

int
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 *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"content", "forget", "info", "location", "propagate",
	"remove", "rowconfigure", "size", "slaves", NULL
    };
    static const char *const optionStringsNoDep[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"content", "forget", "info", "location", "propagate",
	"remove", "rowconfigure", "size", NULL
    };
    enum options {
	GRID_ANCHOR, GRID_BBOX, GRID_COLUMNCONFIGURE, GRID_CONFIGURE,
	GRID_CONTENT, GRID_FORGET, GRID_INFO, GRID_LOCATION, GRID_PROPAGATE,
	GRID_REMOVE, GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES
    };
    int index;

    if (objc >= 2) {
	const char *argv1 = Tcl_GetString(objv[1]);

	if ((argv1[0] == '.') || (argv1[0] == REL_SKIP) ||
    		(argv1[0] == REL_VERT)) {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(NULL, objv[1], optionStrings,
	    sizeof(char *), "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
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:
	return GridBboxCommand(tkwin, interp, objc, objv);
    case GRID_CONFIGURE:
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case GRID_FORGET:
    case GRID_REMOVE:
	return GridForgetRemoveCommand(tkwin, interp, objc, objv);
    case GRID_INFO:
	return GridInfoCommand(tkwin, interp, objc, objv);
    case GRID_LOCATION:
	return GridLocationCommand(tkwin, interp, objc, objv);
    case GRID_PROPAGATE:
	return GridPropagateCommand(tkwin, interp, objc, objv);
    case GRID_SIZE:
	return GridSizeCommand(tkwin, interp, objc, objv);
    case GRID_SLAVES:
    case GRID_CONTENT:
	return GridContentCommand(tkwin, interp, objc, objv);

    /*
     * Sample argument combinations:
     *  grid columnconfigure <container> <index> -option
     *  grid columnconfigure <container> <index> -option value -option value
     *  grid rowconfigure <container> <index>
     *  grid rowconfigure <container> <index> -option
     *  grid rowconfigure <container> <index> -option value -option value.
     */

    case GRID_COLUMNCONFIGURE:
    case GRID_ROWCONFIGURE:
	return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
    }

    /* This should not happen */
    Tcl_SetObjResult(interp, Tcl_NewStringObj("internal error in grid", -1));
    Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GridAnchorCommand --







|

|
|

|
<
<
<
<
<
|



|
|




|



|







|
|
<
<
<
<
<
<
<
<









|












<
|



|
|
|
|
|








|
<







326
327
328
329
330
331
332
333
334
335
336
337
338





339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362








363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
 */

int
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[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"forget", "info", "location", "propagate", "remove",





	"rowconfigure", "size",	"slaves", NULL
    };
    enum options {
	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);
	}
    }
    if (objc < 3) {
	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 GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:
	return GridBboxCommand(tkwin, interp, objc, objv);
    case GRID_CONFIGURE:
	return ConfigureSlaves(interp, tkwin, objc-2, objv+2);
    case GRID_FORGET:
    case GRID_REMOVE:
	return GridForgetRemoveCommand(tkwin, interp, objc, objv);
    case GRID_INFO:
	return GridInfoCommand(tkwin, interp, objc, objv);
    case GRID_LOCATION:
	return GridLocationCommand(tkwin, interp, objc, objv);
    case GRID_PROPAGATE:
	return GridPropagateCommand(tkwin, interp, objc, objv);
    case GRID_SIZE:
	return GridSizeCommand(tkwin, interp, objc, objv);
    case GRID_SLAVES:

	return GridSlavesCommand(tkwin, interp, objc, objv);

    /*
     * Sample argument combinations:
     *  grid columnconfigure <master> <index> -option
     *  grid columnconfigure <master> <index> -option value -option value
     *  grid rowconfigure <master> <index>
     *  grid rowconfigure <master> <index> -option
     *  grid rowconfigure <master> <index> -option value -option value.
     */

    case GRID_COLUMNCONFIGURE:
    case GRID_ROWCONFIGURE:
	return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
    }

    /* This should not happen */
    Tcl_SetResult(interp, "Internal error in grid.", TCL_STATIC);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GridAnchorCommand --
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
 */

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 container;
    Gridder *containerPtr;
    GridContainer *gridPtr;
    Tk_Anchor old;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?anchor?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);

    if (objc == 3) {
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR),
		-1));
	return TCL_OK;
    }

    InitContainerData(containerPtr);
    gridPtr = containerPtr->containerDataPtr;
    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 (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|
|
|







|


|


|
|
|
<



|
|










|
|

|
|
|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
 */

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;
}

/*
 *----------------------------------------------------------------------
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
 */

static int
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 container;
    Gridder *containerPtr;		/* container grid record */
    GridContainer *gridPtr;	/* pointer to grid data */
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
    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, "window ?column row ?column row??");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);

    if (objc >= 5) {
	if (Tcl_GetIntFromObj(interp, objv[3], &column) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[4], &row) != TCL_OK) {
	    return TCL_ERROR;







|

|
|
|







|



|


|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
 */

static int
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 */
    GridMaster *gridPtr;	/* pointer to grid data */
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
    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;
	}
	if (Tcl_GetIntFromObj(interp, objv[4], &row) != TCL_OK) {
	    return TCL_ERROR;
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[6], &row2) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    gridPtr = containerPtr->containerDataPtr;
    if (gridPtr == NULL) {
	Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
	return TCL_OK;
    }

    SetGridSize(containerPtr);
    endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
    endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);

    if ((endX == 0) || (endY == 0)) {
	Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
	return TCL_OK;
    }







|





|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[6], &row2) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    gridPtr = masterPtr->masterDataPtr;
    if (gridPtr == NULL) {
	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(0, 0, 0, 0));
	return TCL_OK;
    }
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
 */

static int
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 content;
    Gridder *contentPtr;
    int i;
    const char *string = Tcl_GetString(objv[1]);
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	contentPtr = GetGrid(content);
	if (contentPtr->containerPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		contentPtr->column = -1;
		contentPtr->row = -1;
		contentPtr->numCols = 1;
		contentPtr->numRows = 1;
		contentPtr->padX = 0;
		contentPtr->padY = 0;
		contentPtr->padLeft = 0;
		contentPtr->padTop = 0;
		contentPtr->iPadX = 0;
		contentPtr->iPadY = 0;
		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		contentPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
		if (contentPtr->flags & REQUESTED_RELAYOUT) {
		    Tcl_CancelIdleCall(ArrangeGrid, contentPtr);
		}
		contentPtr->flags = 0;
		contentPtr->sticky = 0;
	    } else {
		/*
		 * When removing, store name of container to be able to
		 * restore it later, even if the container is recreated.
		 */

		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		if (contentPtr->containerPtr != NULL) {
		    contentPtr->in = Tcl_NewStringObj(
			    Tk_PathName(contentPtr->containerPtr->tkwin), -1);
		    Tcl_IncrRefCount(contentPtr->in);
		}
	    }
	    Tk_ManageGeometry(content, NULL, NULL);
	    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);
	    }
	    Unlink(contentPtr);
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|
|

|



|



|
|





|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|


|
|


|
|
|

|
|
|
|


|
|
|
|

|
|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
 */

static int
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;
	}

	slavePtr = GetGrid(slave);
	if (slavePtr->masterPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		slavePtr->column = -1;
		slavePtr->row = -1;
		slavePtr->numCols = 1;
		slavePtr->numRows = 1;
		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, NULL, (ClientData) NULL);
	    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
		Tk_UnmaintainGeometry(slavePtr->tkwin,
			slavePtr->masterPtr->tkwin);
	    }
	    Unlink(slavePtr);
	    Tk_UnmapWindow(slavePtr->tkwin);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
 */

static int
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. */
{
    Gridder *contentPtr;
    Tk_Window content;
    Tcl_Obj *infoObj;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	return TCL_ERROR;
    }
    contentPtr = GetGrid(content);
    if (contentPtr->containerPtr == NULL) {
	Tcl_ResetResult(interp);
	return TCL_OK;
    }

    infoObj = Tcl_NewObj();
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
	    Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1),
	    Tcl_NewWideIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1),
	    Tcl_NewWideIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numRows));
    TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
    TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
    TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft, contentPtr->padX);
    TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-sticky", -1),
	    StickyToObj(contentPtr->sticky));
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GridLocationCommand --







|

|
|
|





|


|
|




|
<
|
|
|
<
<
<
|
<
|
|
|
|
|
<
|
|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738



739

740
741
742
743
744

745
746
747
748
749
750
751
752
753
 */

static int
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;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &slave) != TCL_OK) {
	return TCL_ERROR;
    }
    slavePtr = GetGrid(slave);
    if (slavePtr->masterPtr == NULL) {
	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, 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, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GridLocationCommand --
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808




809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
 */

static int
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 container;
    Gridder *containerPtr;		/* Container grid record. */
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of container. */
    int i, j;			/* Corresponding column and row indeces. */
    int endX, endY;		/* End of grid. */

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "window x y");




	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tk_GetPixelsFromObj(interp, container, objv[3], &x) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*
     * 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 (containerPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, containerPtr);
	ArrangeGrid(containerPtr);
    }
    SetGridSize(containerPtr);
    endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
    endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);

    slotPtr = containerPtr->containerDataPtr->columnPtr;
    if (x < containerPtr->containerDataPtr->startX) {
	i = -1;
    } else {
	x -= containerPtr->containerDataPtr->startX;
	for (i = 0; slotPtr[i].offset < x && i < endX; i++) {
	    /* null body */
	}
    }

    slotPtr = containerPtr->containerDataPtr->rowPtr;
    if (y < containerPtr->containerDataPtr->startY) {
	j = -1;
    } else {
	y -= containerPtr->containerDataPtr->startY;
	for (j = 0; slotPtr[j].offset < y && j < endY; j++) {
	    /* null body */
	}
    }

    Tcl_SetObjResult(interp, NewPairObj(i, j));
    return TCL_OK;







|

|
|
|
|
|




|
>
>
>
>



<
<
<
<
|


|



|
|



|







|
|
|

|



|
|


|





|
|


|







765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790




791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
 */

static int
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. */
    register SlotInfo *slotPtr;
    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(-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.
     */

    while (masterPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, (ClientData) masterPtr);
	ArrangeGrid((ClientData) masterPtr);
    }
    SetGridSize(masterPtr);
    endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
    endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);

    slotPtr = masterPtr->masterDataPtr->columnPtr;
    if (x < masterPtr->masterDataPtr->startX) {
	i = -1;
    } else {
	x -= masterPtr->masterDataPtr->startX;
	for (i = 0; slotPtr[i].offset < x && i < endX; i++) {
	    /* null body */
	}
    }

    slotPtr = masterPtr->masterDataPtr->rowPtr;
    if (y < masterPtr->masterDataPtr->startY) {
	j = -1;
    } else {
	y -= masterPtr->masterDataPtr->startY;
	for (j = 0; slotPtr[j].offset < y && j < endY; j++) {
	    /* null body */
	}
    }

    Tcl_SetObjResult(interp, NewPairObj(i, j));
    return TCL_OK;
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
 */

static int
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 container;
    Gridder *containerPtr;
    int propagate, old;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);
    if (objc == 3) {
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Only request a relayout if the propagation bit changes.
     */

    old = !(containerPtr->flags & DONT_PROPAGATE);
    if (propagate != old) {
	if (propagate) {
	    /*
	     * If we have content, we need to register as geometry container.
	     */

	    if (containerPtr->contentPtr != NULL) {
		if (TkSetGeometryContainer(interp, container, "grid")	!= TCL_OK) {
		    return TCL_ERROR;
		}
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	    containerPtr->flags &= ~DONT_PROPAGATE;
	} else {
	    if (containerPtr->flags & ALLOCED_CONTAINER) {
		TkFreeGeometryContainer(container, "grid");
		containerPtr->flags &= ~ALLOCED_CONTAINER;
	    }
	    containerPtr->flags |= DONT_PROPAGATE;
	}

	/*
	 * Re-arrange the container to allow new geometry information to
	 * propagate upwards to the container's container.
	 */

	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|
|







|


|


|










|


<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
|



|
|


|
|

|
|
|







858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895










896
897




898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
 */

static int
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;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    if (objc == 3) {
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(!(masterPtr->flags & DONT_PROPAGATE)));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Only request a relayout if the propagation bit changes.
     */

    old = !(masterPtr->flags & DONT_PROPAGATE);
    if (propagate != old) {
	if (propagate) {










	    masterPtr->flags &= ~DONT_PROPAGATE;
	} 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;
	}
	if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
 */

static int
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 container, content;
    Gridder *containerPtr, *contentPtr;
    SlotInfo *slotPtr = NULL;
    int slot;			/* the column or row number */
    int slotType;		/* COLUMN or ROW */
    int size;			/* the configuration value */
    int lObjc;			/* Number of items in index list */
    Tcl_Obj **lObjv;		/* array of indices */
    int ok;			/* temporary TCL result code */
    int i, j, first, last;
    const char *string;
    static const char *const optionStrings[] = {
	"-minsize", "-pad", "-uniform", "-weight", NULL
    };
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };
    int index;
    Tcl_Obj *listCopy;

    if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window index ?-option value ...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    listCopy = Tcl_DuplicateObj(objv[3]);
    Tcl_IncrRefCount(listCopy);
    if (Tcl_ListObjGetElements(interp, listCopy, &lObjc, &lObjv) != TCL_OK) {
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    string = Tcl_GetString(objv[1]);
    slotType = (*string == 'c') ? COLUMN : ROW;
    if (lObjc == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("no %s indices specified",
		(slotType == COLUMN) ? "column" : "row"));
	Tcl_SetErrorCode(interp, "TK", "GRID", "NO_INDEX", NULL);
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);
    first = 0;
    last = 0;

    if ((objc == 4) || (objc == 5)) {
	if (lObjc != 1) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(

		    "must specify a single element on retrieval", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "USAGE", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, lObjv[0], &slot) != TCL_OK) {
	    Tcl_AppendResult(interp,
		    " (when retrieving options only integer indices are "
		    "allowed)", NULL);
	    Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_FORMAT", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	ok = CheckSlotData(containerPtr, slot, slotType, /* checkOnly */ 1);
	if (ok == TCL_OK) {
	    slotPtr = (slotType == COLUMN) ?
		    containerPtr->containerDataPtr->columnPtr :
		    containerPtr->containerDataPtr->rowPtr;
	}

	/*
	 * Return all of the options for this row or column. If the request is
	 * out of range, return all 0's.
	 */








|

|
|








|
|









|



|













|
|
|




|
|
|



|
>
|
<





|

<



|


|
|







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
 */

static int
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, 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 lObjc;			/* Number of items in index list */
    Tcl_Obj **lObjv;		/* array of indices */
    int ok;			/* temporary TCL result code */
    int i, j, first, last;
    char *string;
    static CONST char *optionStrings[] = {
	"-minsize", "-pad", "-uniform", "-weight", NULL
    };
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };
    int index;
    Tcl_Obj *listCopy;

    if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	return TCL_ERROR;
    }

    listCopy = Tcl_DuplicateObj(objv[3]);
    Tcl_IncrRefCount(listCopy);
    if (Tcl_ListObjGetElements(interp, listCopy, &lObjc, &lObjv) != TCL_OK) {
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    string = Tcl_GetString(objv[1]);
    slotType = (*string == 'c') ? COLUMN : ROW;
    if (lObjc == 0) {
	Tcl_AppendResult(interp, "no ",
		(slotType == COLUMN) ? "column" : "row",
		" indices specified", NULL);
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    masterPtr = GetGrid(master);
    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;
	}
	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;
	}
	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.
	 */

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211



1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229



1230
1231

1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*
	 * If only one option is given, with no value, the current value is
	 * returned.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[4], optionStrings,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	if (index == ROWCOL_MINSIZE) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (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_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }

    for (j = 0; j < lObjc; j++) {
	int allContent = 0;

	if (Tcl_GetIntFromObj(NULL, lObjv[j], &slot) == TCL_OK) {
	    first = slot;
	    last = slot;
	    contentPtr = NULL;
	} else if (strcmp(Tcl_GetString(lObjv[j]), "all") == 0) {
	    /*
	     * Make sure container is initialised.
	     */

	    InitContainerData(containerPtr);

	    contentPtr = containerPtr->contentPtr;
	    if (contentPtr == NULL) {
		continue;
	    }
	    allContent = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &content)
		== TCL_OK) {
	    /*
	     * Is it gridded in this container?
	     */

	    contentPtr = GetGrid(content);
	    if (contentPtr->containerPtr != containerPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(

			"the window \"%s\" is not managed by \"%s\"",
			Tcl_GetString(lObjv[j]), Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MANAGED", NULL);
		Tcl_DecrRefCount(listCopy);
		return TCL_ERROR;
	    }
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(

		    "illegal index \"%s\"", Tcl_GetString(lObjv[j])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID_INDEX", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}

	/*
	 * The outer loop is only to handle "all".
	 */

	do {
	    if (contentPtr != NULL) {
		first = (slotType == COLUMN) ?
			contentPtr->column : contentPtr->row;
		last = first - 1 + ((slotType == COLUMN) ?
			contentPtr->numCols : contentPtr->numRows);
	    }

	    for (slot = first; slot <= last; slot++) {
		ok = CheckSlotData(containerPtr, slot, slotType, /*checkOnly*/ 0);
		if (ok != TCL_OK) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "\"%s\" is out of range",
			    Tcl_GetString(lObjv[j])));
		    Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_RANGE",
			    NULL);
		    Tcl_DecrRefCount(listCopy);
		    return TCL_ERROR;
		}
		slotPtr = (slotType == COLUMN) ?
			containerPtr->containerDataPtr->columnPtr :
			containerPtr->containerDataPtr->rowPtr;

		/*
		 * Loop through each option value pair, setting the values as
		 * required.
		 */

		for (i = 4; i < objc; i += 2) {
		    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
			    sizeof(char *), "option", 0, &index) != TCL_OK) {
			Tcl_DecrRefCount(listCopy);
			return TCL_ERROR;
		    }
		    if (index == ROWCOL_MINSIZE) {
			if (Tk_GetPixelsFromObj(interp, container, 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_DecrRefCount(listCopy);
			    goto negativeIndex;

			} 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, container, objv[i+1],
				&size) != TCL_OK) {
			    Tcl_DecrRefCount(listCopy);
			    return TCL_ERROR;
			} else if (size < 0) {



			    Tcl_DecrRefCount(listCopy);
			    goto negativeIndex;

			} else {
			    slotPtr[slot].pad = size;
			}
		    }
		}
	    }
	    if (contentPtr != NULL) {
		contentPtr = contentPtr->nextPtr;
	    }
	} while ((allContent == 1) && (contentPtr != NULL));
    }
    Tcl_DecrRefCount(listCopy);

    /*
     * We changed a property, re-arrange the table, and check for constraint
     * shrinkage. A null slotPtr will occur for 'all' checks.
     */

    if (slotPtr != NULL) {
	if (slotType == ROW) {
	    last = containerPtr->containerDataPtr->rowMax - 1;

	    while ((last >= 0) && (slotPtr[last].weight == 0)
		    && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
		    && (slotPtr[last].uniform == NULL)) {
		last--;
	    }
	    containerPtr->containerDataPtr->rowMax = last+1;
	} else {
	    last = containerPtr->containerDataPtr->columnMax - 1;

	    while ((last >= 0) && (slotPtr[last].weight == 0)
		    && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
		    && (slotPtr[last].uniform == NULL)) {
		last--;
	    }
	    containerPtr->containerDataPtr->columnMax = last + 1;
	}
    }

    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	containerPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
    }
    return TCL_OK;

  negativeIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "invalid arg \"%s\": should be non-negative",
	    Tcl_GetString(objv[i])));
    Tcl_SetErrorCode(interp, "TK", "GRID", "NEG_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GridSizeCommand --
 *







|


|






|










|
|




|
|

|
|



|
|

|
|






|




|


|


|

|
|


|
|


|


|
|
|
>
|
|
<




|
>
|
<









|

|

|



|

|
|
|
<
|
|



|
|







|
|
|



|

|








|


>
>
>
|
<
>











|

|


>
>
>
|
<
>






|
|

|










|






|

|






|



|
|

|
|
|


<
<
<
<
<
<
<







1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244







1245
1246
1247
1248
1249
1250
1251
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*
	 * If only one option is given, with no value, the current value is
	 * returned.
	 */

	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;
	    }
	} 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;
		}
		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;
		    }
		    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;
			}
		    }
		}
	    }
	    if (slavePtr != NULL) {
		slavePtr = slavePtr->nextPtr;
	    }
	} while ((allSlaves == 1) && (slavePtr != NULL));
    }
    Tcl_DecrRefCount(listCopy);

    /*
     * We changed a property, re-arrange the table, and check for constraint
     * shrinkage. A null slotPtr will occur for 'all' checks.
     */

    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].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].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);
    }
    return TCL_OK;







}

/*
 *----------------------------------------------------------------------
 *
 * GridSizeCommand --
 *
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
 */

static int
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 container;
    Gridder *containerPtr;
    GridContainer *gridPtr;	/* pointer to grid data */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);

    if (containerPtr->containerDataPtr != NULL) {
	SetGridSize(containerPtr);
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));
    } else {
	Tcl_SetObjResult(interp, NewPairObj(0, 0));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GridContentCommand --
 *
 *	Implementation of the [grid content] subcommand. See the user
 *	documentation for details on what it does.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Places a list of content windows of the specified window in the
 *	interpreter's result field.
 *
 *----------------------------------------------------------------------
 */

static int
GridContentCommand(
    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 container;
    Gridder *containerPtr;		/* container grid record */
    Gridder *contentPtr;
    int i, value, index;
    int row = -1, column = -1;
    static const char *const optionStrings[] = {
	"-column", "-row", NULL
    };
    enum options { CONTENT_COLUMN, CONTENT_ROW };
    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_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[i+1], &value) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (value < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%d is an invalid value: should NOT be < 0", value));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "NEG_INDEX", NULL);
	    return TCL_ERROR;
	}
	if (index == CONTENT_COLUMN) {
	    column = value;
	} else {
	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);

    res = Tcl_NewListObj(0, NULL);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((column >= 0) && (contentPtr->column > column
		|| contentPtr->column+contentPtr->numCols-1 < column)) {
	    continue;
	}
	if ((row >= 0) && (contentPtr->row > row ||
		contentPtr->row+contentPtr->numRows-1 < row)) {
	    continue;
	}
	Tcl_ListObjAppendElement(interp,res, Tk_NewWindowObj(contentPtr->tkwin));

    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|
|
|






|


|

|
|
|












|

|






|
|





|



|

|
|
|


|


|



|




|
|






|
|
<


|






|


|


|
|
|
|


|
|


|
>







1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348

1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
 */

static int
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;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);

    if (masterPtr->masterDataPtr != NULL) {
	SetGridSize(masterPtr);
	gridPtr = masterPtr->masterDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));
    } else {
	Tcl_SetObjResult(interp, NewPairObj(0, 0));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GridSlavesCommand --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static int
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, index;
    int row = -1, column = -1;
    static CONST char *optionStrings[] = {
	"-column", "-row", NULL
    };
    enum options { SLAVES_COLUMN, SLAVES_ROW };
    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) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[i+1], &value) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (value < 0) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[i]),
		    " is an invalid value: should NOT be < 0", NULL);

	    return TCL_ERROR;
	}
	if (index == SLAVES_COLUMN) {
	    column = value;
	} else {
	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);

    res = Tcl_NewListObj(0, NULL);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if (column>=0 && (slavePtr->column > column
		|| slavePtr->column+slavePtr->numCols-1 < column)) {
	    continue;
	}
	if (row>=0 && (slavePtr->row > row ||
		slavePtr->row+slavePtr->numRows-1 < row)) {
	    continue;
	}
	Tcl_ListObjAppendElement(interp, res,
		Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin), -1));
    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
 *----------------------------------------------------------------------
 */

static void
GridReqProc(
    ClientData clientData,	/* Grid's information about window that got
				 * new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Gridder *gridPtr = (Gridder *)clientData;

    gridPtr = gridPtr->containerPtr;
    if (gridPtr && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	gridPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GridLostContentProc --
 *
 *	This procedure is invoked by Tk whenever some other geometry claims
 *	control over a content that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all grid-related information about the content.
 *
 *----------------------------------------------------------------------
 */

static void
GridLostContentProc(
    ClientData clientData,	/* Grid structure for content window that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Gridder *contentPtr = (Gridder *)clientData;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Unlink(contentPtr);
    Tk_UnmapWindow(contentPtr->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustOffsets --
 *







|


|

|


|






|


|





|





|
|

|

|

|
|

|
|







1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
 *----------------------------------------------------------------------
 */

static void
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;

    gridPtr = gridPtr->masterPtr;
    if (gridPtr && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	gridPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GridLostSlaveProc --
 *
 *	This procedure 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 grid-related information about the slave.
 *
 *----------------------------------------------------------------------
 */

static void
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;

    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
    }
    Unlink(slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustOffsets --
 *
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
 *----------------------------------------------------------------------
 */

static int
AdjustOffsets(
    int size,			/* The total layout size (in pixels). */
    int slots,			/* Number of slots. */
    SlotInfo *slotPtr)	/* Pointer to slot array. */
{
    int slot;		/* Current slot. */
    int diff;			/* Extra pixels needed to add to the layout. */
    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. */








|

|







1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
 *----------------------------------------------------------------------
 */

static int
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;		/* 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. */

1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustForSticky --
 *
 *	This procedure adjusts the size of a content 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 content.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
AdjustForSticky(
    Gridder *contentPtr,	/* Content 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 - content width. */
    int diffy = 0;	/* Cavity hight - content height. */
    int sticky = contentPtr->sticky;

    *xPtr += contentPtr->padLeft;
    *widthPtr -= contentPtr->padX;
    *yPtr += contentPtr->padTop;
    *heightPtr -= contentPtr->padY;

    if (*widthPtr > (Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX)) {
	diffx = *widthPtr - (Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX);
	*widthPtr = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX;
    }

    if (*heightPtr > (Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY)) {
	diffy = *heightPtr - (Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY);
	*heightPtr = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY;
    }

    if (sticky&STICK_EAST && sticky&STICK_WEST) {
	*widthPtr += diffx;
    }
    if (sticky&STICK_NORTH && sticky&STICK_SOUTH) {
	*heightPtr += diffy;







|




|









|





|
|
|

|
|
|
|

|
|
|


|
|
|







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustForSticky --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
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 sticky = slavePtr->sticky;

    *xPtr += slavePtr->padLeft;
    *widthPtr -= slavePtr->padX;
    *yPtr += slavePtr->padTop;
    *heightPtr -= slavePtr->padY;

    if (*widthPtr > (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX)) {
	diffx = *widthPtr - (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX);
	*widthPtr = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX;
    }

    if (*heightPtr > (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY)) {
	diffy = *heightPtr - (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY);
	*heightPtr = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY;
    }

    if (sticky&STICK_EAST && sticky&STICK_WEST) {
	*widthPtr += diffx;
    }
    if (sticky&STICK_NORTH && sticky&STICK_SOUTH) {
	*heightPtr += diffy;
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834

1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971

1972
1973
1974
1975
1976
1977
1978
 *	time so that a series of grid requests can be merged into a single
 *	layout operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The content of containerPtr may get resized or moved.
 *
 *----------------------------------------------------------------------
 */

static void
ArrangeGrid(
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Gridder *containerPtr = (Gridder *)clientData;
    Gridder *contentPtr;
    GridContainer *slotPtr = containerPtr->containerDataPtr;
    int abort;
    int width, height;		/* Requested size of layout, in pixels. */
    int realWidth, realHeight;	/* Actual size layout should take-up. */
    int usedX, usedY;

    containerPtr->flags &= ~REQUESTED_RELAYOUT;

    /*
     * If the container has no content anymore, then don't change the container size.

     * Otherwise there is no way to "relinquish" control over the container
     * so another geometry manager can take over.
     */

    if (containerPtr->contentPtr == NULL) {
	return;
    }

    if (containerPtr->containerDataPtr == NULL) {
	return;
    }

    /*
     * 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 (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(containerPtr);

    /*
     * Call the constraint engine to fill in the row and column offsets.
     */

    SetGridSize(containerPtr);
    width = ResolveConstraints(containerPtr, COLUMN, 0);
    height = ResolveConstraints(containerPtr, ROW, 0);
    width += Tk_InternalBorderLeft(containerPtr->tkwin) +
	    Tk_InternalBorderRight(containerPtr->tkwin);
    height += Tk_InternalBorderTop(containerPtr->tkwin) +
	    Tk_InternalBorderBottom(containerPtr->tkwin);

    if (width < Tk_MinReqWidth(containerPtr->tkwin)) {
	width = Tk_MinReqWidth(containerPtr->tkwin);
    }
    if (height < Tk_MinReqHeight(containerPtr->tkwin)) {
	height = Tk_MinReqHeight(containerPtr->tkwin);
    }

    if (((width != Tk_ReqWidth(containerPtr->tkwin))
	    || (height != Tk_ReqHeight(containerPtr->tkwin)))
	    && !(containerPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(containerPtr->tkwin, width, height);
	if (width>1 && height>1) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
	containerPtr->abortPtr = NULL;
	Tcl_Release(containerPtr);
	return;
    }

    /*
     * If the currently requested layout size doesn't match the container'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(containerPtr->tkwin) -
	    Tk_InternalBorderLeft(containerPtr->tkwin) -
	    Tk_InternalBorderRight(containerPtr->tkwin);
    realHeight = Tk_Height(containerPtr->tkwin) -
	    Tk_InternalBorderTop(containerPtr->tkwin) -
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    usedX = AdjustOffsets(realWidth,
	    MAX(slotPtr->columnEnd, slotPtr->columnMax), slotPtr->columnPtr);
    usedY = AdjustOffsets(realHeight, MAX(slotPtr->rowEnd, slotPtr->rowMax),
	    slotPtr->rowPtr);
    TkComputeAnchor(containerPtr->containerDataPtr->anchor, containerPtr->tkwin,
	    0, 0, usedX, usedY, &slotPtr->startX, &slotPtr->startY);

    /*
     * Now adjust the actual size of the content to its cavity by computing the
     * cavity size, and adjusting the widget according to its stickyness.
     */

    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL && !abort;
	    contentPtr = contentPtr->nextPtr) {
	int x, y;			/* Top left coordinate */

	int col = contentPtr->column;
	int row = contentPtr->row;

	x = (col>0) ? slotPtr->columnPtr[col-1].offset : 0;
	y = (row>0) ? slotPtr->rowPtr[row-1].offset : 0;

	width = slotPtr->columnPtr[contentPtr->numCols+col-1].offset - x;
	height = slotPtr->rowPtr[contentPtr->numRows+row-1].offset - y;

	x += slotPtr->startX;
	y += slotPtr->startY;

	AdjustForSticky(contentPtr, &x, &y, &width, &height);

	/*
	 * Now put the window in the proper spot. (This was taken directly
	 * from tkPack.c.) If the content is a child of the container, then do this
	 * here. Otherwise let Tk_MaintainGeometry do the work.
	 */

	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		if ((x != Tk_X(contentPtr->tkwin))
			|| (y != Tk_Y(contentPtr->tkwin))
			|| (width != Tk_Width(contentPtr->tkwin))
			|| (height != Tk_Height(contentPtr->tkwin))) {
		    Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
		}
		if (abort) {
		    break;
		}

		/*
		 * Don't map the content if the container isn't mapped: wait until
		 * the container gets mapped later.
		 */

		if (Tk_IsMapped(containerPtr->tkwin)) {
		    Tk_MapWindow(contentPtr->tkwin);
		}
	    }
	} else if ((width <= 0) || (height <= 0)) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
	    Tk_UnmapWindow(contentPtr->tkwin);
	} else {
	    Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin, x, y,
		    width, height);
	}
    }

    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	The offset (in pixels) from the left/top edge of this layout is
 *	returned.
 *
 * Side effects:
 *	The slot offsets are copied into the SlotInfo structure for the
 *	geometry container.
 *
 *----------------------------------------------------------------------
 */

static int
ResolveConstraints(
    Gridder *containerPtr,		/* The geometry container 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). */
{
    SlotInfo *slotPtr;	/* Pointer to row/col constraints. */
    Gridder *contentPtr;	/* List of content windows in this grid. */
    int constraintCount;	/* Count of rows or columns that have
				 * constraints. */
    int slotCount;		/* Last occupied row or column. */
    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
				 * accommodate all of the content at their
				 * requested sizes. */
    int offset;			/* The pixel offset of the right edge of the
				 * 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. */
    int end;			/* The Last slot of a contiguous set whose
				 * constraints are not yet fully resolved. */
    UniformGroup uniformPre[UNIFORM_PREALLOC];
				/* Pre-allocated space for uniform groups. */
    UniformGroup *uniformGroupPtr;
				/* Uniform groups data. */
    int uniformGroups;		/* Number of currently used uniform groups. */
    int uniformGroupsAlloced;	/* Size of allocated space for uniform
				 * groups. */
    int 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.
     */

    GridLayout layoutData[TYPICAL_SIZE + 1];

    if (slotType == COLUMN) {
	constraintCount = containerPtr->containerDataPtr->columnMax;
	slotCount = containerPtr->containerDataPtr->columnEnd;
	slotPtr = containerPtr->containerDataPtr->columnPtr;
    } else {
	constraintCount = containerPtr->containerDataPtr->rowMax;
	slotCount = containerPtr->containerDataPtr->rowEnd;
	slotPtr = containerPtr->containerDataPtr->rowPtr;
    }

    /*
     * Make sure there is enough memory for the layout.
     */

    gridCount = MAX(constraintCount, slotCount);
    if (gridCount >= TYPICAL_SIZE) {
	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







|






|


|
|
|





|


|
>
|
|


|



|









|
|

|

|





|
|
|
|
|
|
|

|
|

|
|


|
|
|
|

|
|

|
|




|





|
|
|
|
|
|




|



|



|
|

>
|
|




|
|




|



|



|

|

|
|
|
|
|






|
|


|
|



|
|

|




|
|

















|






|




|
|








|
















|










|
|
|

|
|
|








|
>







1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
 *	time so that a series of grid requests can be merged into a single
 *	layout operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slaves of masterPtr may get resized or moved.
 *
 *----------------------------------------------------------------------
 */

static void
ArrangeGrid(
    ClientData clientData)	/* Structure describing master whose slaves
				 * are to be re-layed out. */
{
    register Gridder *masterPtr = (Gridder *) clientData;
    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 usedX, usedY;

    masterPtr->flags &= ~REQUESTED_RELAYOUT;

    /*
     * 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) {
	return;
    }

    if (masterPtr->masterDataPtr == NULL) {
	return;
    }

    /*
     * 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) {
	*masterPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve((ClientData) masterPtr);

    /*
     * Call the constraint engine to fill in the row and column offsets.
     */

    SetGridSize(masterPtr);
    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);
    }
    if (height < Tk_MinReqHeight(masterPtr->tkwin)) {
	height = Tk_MinReqHeight(masterPtr->tkwin);
    }

    if (((width != Tk_ReqWidth(masterPtr->tkwin))
	    || (height != Tk_ReqHeight(masterPtr->tkwin)))
	    && !(masterPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(masterPtr->tkwin, width, height);
	if (width>1 && height>1) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
	}
	masterPtr->abortPtr = NULL;
	Tcl_Release((ClientData) masterPtr);
	return;
    }

    /*
     * 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) -
	    Tk_InternalBorderLeft(masterPtr->tkwin) -
	    Tk_InternalBorderRight(masterPtr->tkwin);
    realHeight = Tk_Height(masterPtr->tkwin) -
	    Tk_InternalBorderTop(masterPtr->tkwin) -
	    Tk_InternalBorderBottom(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.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
	    slavePtr = slavePtr->nextPtr) {
	int x, y;			/* Top left coordinate */
	int width, height;		/* Slot or slave size */
	int col = slavePtr->column;
	int row = slavePtr->row;

	x = (col>0) ? slotPtr->columnPtr[col-1].offset : 0;
	y = (row>0) ? slotPtr->rowPtr[row-1].offset : 0;

	width = slotPtr->columnPtr[slavePtr->numCols+col-1].offset - x;
	height = slotPtr->rowPtr[slavePtr->numRows+row-1].offset - y;

	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);
	}
    }

    masterPtr->abortPtr = NULL;
    Tcl_Release((ClientData) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	The offset (in pixels) from the left/top edge of this layout is
 *	returned.
 *
 * Side effects:
 *	The slot offsets are copied into the SlotInfo structure for the
 *	geometry master.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
    int slotCount;		/* Last occupied row or column. */
    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. */
    int slot;			/* The current slot. */
    int start;			/* The first slot of a contiguous set whose
				 * 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];
				/* Pre-allocated space for uniform groups. */
    UniformGroup *uniformGroupPtr;
				/* Uniform groups data. */
    int uniformGroups;		/* Number of currently used 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.
     */

    GridLayout layoutData[TYPICAL_SIZE + 1];

    if (slotType == COLUMN) {
	constraintCount = masterPtr->masterDataPtr->columnMax;
	slotCount = masterPtr->masterDataPtr->columnEnd;
	slotPtr = masterPtr->masterDataPtr->columnPtr;
    } else {
	constraintCount = masterPtr->masterDataPtr->rowMax;
	slotCount = masterPtr->masterDataPtr->rowEnd;
	slotPtr = masterPtr->masterDataPtr->rowPtr;
    }

    /*
     * Make sure there is enough memory for the layout.
     */

    gridCount = MAX(constraintCount, slotCount);
    if (gridCount >= TYPICAL_SIZE) {
	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
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
	layoutPtr[slot].uniform = NULL;
	layoutPtr[slot].pad = 0;
	layoutPtr[slot].binNextPtr = NULL;
    }

    /*
     * Step 2.
     * Content with a span of 1 are used to determine the minimum size of each
     * slot. Content 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 content 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 content.
     */

    switch (slotType) {
    case COLUMN:
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    int rightEdge = contentPtr->column + contentPtr->numCols - 1;

	    contentPtr->size = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->padX
		    + contentPtr->iPadX + contentPtr->doubleBw;
	    if (contentPtr->numCols > 1) {
		contentPtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = contentPtr;
	    } else if (rightEdge >= 0) {
		int size = contentPtr->size + layoutPtr[rightEdge].pad;

		if (size > layoutPtr[rightEdge].minSize) {
		    layoutPtr[rightEdge].minSize = size;
		}
	    }
	}
	break;
    case ROW:
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    int rightEdge = contentPtr->row + contentPtr->numRows - 1;

	    contentPtr->size = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->padY
		    + contentPtr->iPadY + contentPtr->doubleBw;
	    if (contentPtr->numRows > 1) {
		contentPtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = contentPtr;
	    } else if (rightEdge >= 0) {
		int size = contentPtr->size + layoutPtr[rightEdge].pad;

		if (size > layoutPtr[rightEdge].minSize) {
		    layoutPtr[rightEdge].minSize = size;
		}
	    }
	}
	break;
    }

    /*
     * Step 2b.
     * Consider demands on uniform sizes.
     */

    uniformGroupPtr = uniformPre;
    uniformGroupsAlloced = UNIFORM_PREALLOC;
    uniformGroups = 0;

    for (slot = 0; slot < gridCount; slot++) {
	if (layoutPtr[slot].uniform != NULL) {
		int weight;
	    for (start = 0; start < uniformGroups; start++) {
		if (uniformGroupPtr[start].group == layoutPtr[slot].uniform) {
		    break;
		}
	    }
	    if (start >= uniformGroups) {
		/*
		 * Have not seen that group before, set up data for it.
		 */

		if (uniformGroups >= uniformGroupsAlloced) {
		    /*
		     * We need to allocate more space.
		     */

		    size_t oldSize = uniformGroupsAlloced
			    * sizeof(UniformGroup);
		    size_t newSize = (uniformGroupsAlloced + UNIFORM_PREALLOC)
			    * sizeof(UniformGroup);
		    UniformGroup *newUG = (UniformGroup *)ckalloc(newSize);
		    UniformGroup *oldUG = uniformGroupPtr;

		    memcpy(newUG, oldUG, oldSize);
		    if (oldUG != uniformPre) {
			ckfree(oldUG);
		    }
		    uniformGroupPtr = newUG;
		    uniformGroupsAlloced += UNIFORM_PREALLOC;
		}
		uniformGroups++;
		uniformGroupPtr[start].group = layoutPtr[slot].uniform;
		uniformGroupPtr[start].minSize = 0;







|
|



|

|




|
|
|

|
|
|
|
|

|








|
|
|

|
|
|
|
|

|




















<



















|




|







1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
	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.
     */

    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 if (rightEdge >= 0) {
		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 if (rightEdge >= 0) {
		int size = slavePtr->size + layoutPtr[rightEdge].pad;

		if (size > layoutPtr[rightEdge].minSize) {
		    layoutPtr[rightEdge].minSize = size;
		}
	    }
	}
	break;
    }

    /*
     * Step 2b.
     * Consider demands on uniform sizes.
     */

    uniformGroupPtr = uniformPre;
    uniformGroupsAlloced = UNIFORM_PREALLOC;
    uniformGroups = 0;

    for (slot = 0; slot < gridCount; slot++) {
	if (layoutPtr[slot].uniform != NULL) {

	    for (start = 0; start < uniformGroups; start++) {
		if (uniformGroupPtr[start].group == layoutPtr[slot].uniform) {
		    break;
		}
	    }
	    if (start >= uniformGroups) {
		/*
		 * Have not seen that group before, set up data for it.
		 */

		if (uniformGroups >= uniformGroupsAlloced) {
		    /*
		     * We need to allocate more space.
		     */

		    size_t oldSize = uniformGroupsAlloced
			    * sizeof(UniformGroup);
		    size_t newSize = (uniformGroupsAlloced + UNIFORM_PREALLOC)
			    * sizeof(UniformGroup);
		    UniformGroup *newUG = (UniformGroup *) ckalloc(newSize);
		    UniformGroup *oldUG = uniformGroupPtr;

		    memcpy(newUG, oldUG, oldSize);
		    if (oldUG != uniformPre) {
			ckfree((char *) oldUG);
		    }
		    uniformGroupPtr = newUG;
		    uniformGroupsAlloced += UNIFORM_PREALLOC;
		}
		uniformGroups++;
		uniformGroupPtr[start].group = layoutPtr[slot].uniform;
		uniformGroupPtr[start].minSize = 0;
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197

    if (uniformGroups > 0) {
	for (slot = 0; slot < gridCount; slot++) {
	    if (layoutPtr[slot].uniform != NULL) {
		for (start = 0; start < uniformGroups; start++) {
		    if (uniformGroupPtr[start].group ==
			    layoutPtr[slot].uniform) {
			int weight = layoutPtr[slot].weight;
			weight = weight > 0 ? weight : 1;
			layoutPtr[slot].minSize =
				uniformGroupPtr[start].minSize * weight;
			break;
		    }
		}
	    }
	}
    }

    if (uniformGroupPtr != uniformPre) {
	ckfree(uniformGroupPtr);
    }

    /*
     * Step 3.
     * Determine the minimum slot offsets going from left to right that would
     * fit all of the content. This determines the minimum
     */

    for (offset=0,slot=0; slot < gridCount; slot++) {
	layoutPtr[slot].minOffset = layoutPtr[slot].minSize + offset;
	for (contentPtr = layoutPtr[slot].binNextPtr; contentPtr != NULL;
		contentPtr = contentPtr->binNextPtr) {
	    int span = (slotType == COLUMN) ?
		    contentPtr->numCols : contentPtr->numRows;
	    int required = contentPtr->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 "container" will resize itself to
     * this size.
     */

    requiredSize = offset;
    if (maxOffset > offset) {
	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.
     */

    for (slot=0; slot < gridCount; slot++) {
	layoutPtr[slot].maxOffset = offset;
    }
    for (slot=gridCount-1; slot > 0;) {
	for (contentPtr = layoutPtr[slot].binNextPtr; contentPtr != NULL;
		contentPtr = contentPtr->binNextPtr) {
	    int span = (slotType == COLUMN) ?
		    contentPtr->numCols : contentPtr->numRows;
	    int require = offset - contentPtr->size;
	    int startSlot = slot - span;

	    if (startSlot >=0 && require < layoutPtr[startSlot].maxOffset) {
		layoutPtr[startSlot].maxOffset = require;
	    }
	}
	offset -= layoutPtr[slot].minSize;







|











|





|




|
|

|
|










|




















|
|

|
|







2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157

    if (uniformGroups > 0) {
	for (slot = 0; slot < gridCount; slot++) {
	    if (layoutPtr[slot].uniform != NULL) {
		for (start = 0; start < uniformGroups; start++) {
		    if (uniformGroupPtr[start].group ==
			    layoutPtr[slot].uniform) {
			weight = layoutPtr[slot].weight;
			weight = weight > 0 ? weight : 1;
			layoutPtr[slot].minSize =
				uniformGroupPtr[start].minSize * weight;
			break;
		    }
		}
	    }
	}
    }

    if (uniformGroupPtr != uniformPre) {
	ckfree((char *) uniformGroupPtr);
    }

    /*
     * Step 3.
     * Determine the minimum slot offsets going from left to right that would
     * fit all of the slaves. This determines the minimum
     */

    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.
     */

    requiredSize = offset;
    if (maxOffset > offset) {
	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.
     */

    for (slot=0; slot < gridCount; slot++) {
	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;
	    }
	}
	offset -= layoutPtr[slot].minSize;
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
	    }
	}
    }

    /*
     * Step 6.
     * All of the space has been apportioned; copy the layout information back
     * into the container.
     */

    for (slot=0; slot < gridCount; slot++) {
	slotPtr[slot].offset = layoutPtr[slot].minOffset;
    }

    --layoutPtr;
    if (layoutPtr != layoutData) {
	ckfree(layoutPtr);
    }
    return requiredSize;
}

/*
 *----------------------------------------------------------------------
 *







|








|







2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
	    }
	}
    }

    /*
     * Step 6.
     * 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;
    }

    --layoutPtr;
    if (layoutPtr != layoutData) {
	ckfree((char *) layoutPtr);
    }
    return requiredSize;
}

/*
 *----------------------------------------------------------------------
 *
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221

3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344



3345



3346
3347


3348


3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379

3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
 */

static Gridder *
GetGrid(
    Tk_Window tkwin)		/* Token for window for which grid structure
				 * is desired. */
{
    Gridder *gridPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->gridInit) {
	Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS);
	dispPtr->gridInit = 1;
    }

    /*
     * See if there's already grid for this window. If not, then create a new
     * one.
     */

    hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char*) tkwin, &isNew);
    if (!isNew) {
	return (Gridder *)Tcl_GetHashValue(hPtr);
    }
    gridPtr = (Gridder *)ckalloc(sizeof(Gridder));
    gridPtr->tkwin = tkwin;
    gridPtr->containerPtr = NULL;
    gridPtr->containerDataPtr = NULL;
    gridPtr->nextPtr = NULL;
    gridPtr->contentPtr = NULL;
    gridPtr->binNextPtr = NULL;

    gridPtr->column = -1;
    gridPtr->row = -1;
    gridPtr->numCols = 1;
    gridPtr->numRows = 1;

    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->containerDataPtr = NULL;
    Tcl_SetHashValue(hPtr, gridPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    GridStructureProc, gridPtr);
    return gridPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * SetGridSize --
 *
 *	This internal procedure sets the size of the grid occupied by content.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The width and height arguments are filled in the container data
 *	structure. Additional space is allocated for the constraints to
 *	accommodate the offsets.
 *
 *----------------------------------------------------------------------
 */

static void
SetGridSize(
    Gridder *containerPtr)		/* The geometry container for this grid. */
{
    Gridder *contentPtr;	/* Current content window. */
    int maxX = 0, maxY = 0;

    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	maxX = MAX(maxX, contentPtr->numCols + contentPtr->column);
	maxY = MAX(maxY, contentPtr->numRows + contentPtr->row);
    }
    containerPtr->containerDataPtr->columnEnd = maxX;
    containerPtr->containerDataPtr->rowEnd = maxY;
    CheckSlotData(containerPtr, maxX, COLUMN, CHECK_SPACE);
    CheckSlotData(containerPtr, maxY, ROW, CHECK_SPACE);
}

/*
 *----------------------------------------------------------------------
 *
 * SetContentColumn --
 *
 *	Update column data for a content, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	Content fields are updated.
 *
 *----------------------------------------------------------------------
 */

static int
SetContentColumn(
    Tcl_Interp *interp,		/* Interp for error message. */
    Gridder *contentPtr,		/* Content 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 : contentPtr->column;
    newNumCols = (numCols >= 1) ? numCols : contentPtr->numCols;

    lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
    if (lastCol >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("column out of bounds",-1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_COLUMN", NULL);
	return TCL_ERROR;
    }

    contentPtr->column = newColumn;
    contentPtr->numCols = newNumCols;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetContentRow --
 *
 *	Update row data for a content, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	Content fields are updated.
 *
 *----------------------------------------------------------------------
 */

static int
SetContentRow(
    Tcl_Interp *interp,		/* Interp for error message. */
    Gridder *contentPtr,		/* Content 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 : contentPtr->row;
    newNumRows = (numRows >= 1) ? numRows : contentPtr->numRows;

    lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
    if (lastRow >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("row out of bounds", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_ROW", NULL);
	return TCL_ERROR;
    }

    contentPtr->row = newRow;
    contentPtr->numRows = newNumRows;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckSlotData --
 *
 *	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 container 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(
    Gridder *containerPtr,		/* The geometry container 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. */

    /*
     * If slot is out of bounds, return immediately.
     */

    if (slot < 0 || slot >= MAX_ELEMENT) {
	return TCL_ERROR;
    }

    if ((checkOnly == CHECK_ONLY) && (containerPtr->containerDataPtr == NULL)) {
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    InitContainerData(containerPtr);
    end = (slotType == ROW) ? containerPtr->containerDataPtr->rowMax :
	    containerPtr->containerDataPtr->columnMax;
    if (checkOnly == CHECK_ONLY) {
    	return ((end < slot) ? TCL_ERROR : TCL_OK);
    } else {
    	numSlot = (slotType == ROW) ? containerPtr->containerDataPtr->rowSpace
		: containerPtr->containerDataPtr->columnSpace;
    	if (slot >= numSlot) {
	    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)
		    ? containerPtr->containerDataPtr->rowPtr
		    : containerPtr->containerDataPtr->columnPtr;

	    memcpy(newSI, oldSI, oldSize);
	    memset(newSI+numSlot, 0, newSize - oldSize);
	    ckfree(oldSI);
	    if (slotType == ROW) {
	 	containerPtr->containerDataPtr->rowPtr = newSI;
	    	containerPtr->containerDataPtr->rowSpace = newNumSlot;
	    } else {
	    	containerPtr->containerDataPtr->columnPtr = newSI;
	    	containerPtr->containerDataPtr->columnSpace = newNumSlot;
	    }
	}
	if (slot >= end && checkOnly != CHECK_SPACE) {
	    if (slotType == ROW) {
		containerPtr->containerDataPtr->rowMax = slot+1;
	    } else {
		containerPtr->containerDataPtr->columnMax = slot+1;
	    }
	}
    	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * InitContainerData --
 *
 *	This internal procedure is used to allocate and initialize the data
 *	for a geometry container, if the data doesn't exist already.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	A new container grid structure may be created. If so, then it is
 *	initialized.
 *
 *----------------------------------------------------------------------
 */

static void
InitContainerData(
    Gridder *containerPtr)
{
    if (containerPtr->containerDataPtr == NULL) {
	GridContainer *gridPtr = containerPtr->containerDataPtr = (GridContainer *)
		ckalloc(sizeof(GridContainer));
	size_t size = sizeof(SlotInfo) * TYPICAL_SIZE;

	gridPtr->columnEnd = 0;
	gridPtr->columnMax = 0;
	gridPtr->columnPtr = (SlotInfo *)ckalloc(size);
	gridPtr->columnSpace = TYPICAL_SIZE;
	gridPtr->rowEnd = 0;
	gridPtr->rowMax = 0;
	gridPtr->rowPtr = (SlotInfo *)ckalloc(size);
	gridPtr->rowSpace = TYPICAL_SIZE;
	gridPtr->startX = 0;
	gridPtr->startY = 0;
	gridPtr->anchor = GRID_DEFAULT_ANCHOR;

	memset(gridPtr->columnPtr, 0, size);
	memset(gridPtr->rowPtr, 0, size);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a grid from its container's list of content.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The container will be scheduled for re-arranging, and the size of the
 *	grid will be adjusted accordingly
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Gridder *contentPtr)	/* Window to unlink. */
{
    Gridder *containerPtr, *contentPtr2;

    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }

    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (contentPtr2=containerPtr->contentPtr ; ; contentPtr2=contentPtr2->nextPtr) {
	    if (contentPtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (contentPtr2->nextPtr == contentPtr) {
		contentPtr2->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
    if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	containerPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
    }
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }

    SetGridSize(contentPtr->containerPtr);
    contentPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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 container structure for geometry
 *	managers.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
    void *memPtr)		/* Info about window that is now dead. */
{
    Gridder *gridPtr = (Gridder *)memPtr;

    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}
	ckfree(gridPtr->containerDataPtr);
    }
    if (gridPtr->in != NULL) {
	Tcl_DecrRefCount(gridPtr->in);
    }
    ckfree(gridPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GridStructureProc --
 *
 *	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 content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
GridStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Gridder *gridPtr = (Gridder *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr;

    if (eventPtr->type == ConfigureNotify) {
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
	if ((gridPtr->containerPtr != NULL) &&
		(gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) {
	    if (!(gridPtr->containerPtr->flags & REQUESTED_RELAYOUT)) {
		gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width;
		gridPtr->containerPtr->flags |= REQUESTED_RELAYOUT;
		Tcl_DoWhenIdle(ArrangeGrid, gridPtr->containerPtr);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	Gridder *contentPtr, *nextPtr;

	if (gridPtr->containerPtr != NULL) {
	    Unlink(gridPtr);
	}
	for (contentPtr = gridPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Gridder *contentPtr;

	for (contentPtr = gridPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureContent --
 *
 *	This implements the guts of the "grid configure" command. Given a list
 *	of content and configuration options, it arranges for the grid to
 *	manage the content 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.
 *
 * Side effects:
 *	Content windows get taken over by the grid.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * content. Used to look up content 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 *containerPtr = NULL;
    Gridder *contentPtr;
    Tk_Window other, content, parent, ancestor;
    TkWindow *container;
    int i, j, tmp;
    int numWindows;
    int width;
    int defaultRow = -1;
    int defaultColumn = 0;	/* Default column number */
    int defaultColumnSpan = 1;	/* Default number of columns */
    const char *lastWindow;	/* Use this window to base current row/col
				 * on */
    int numSkip;		/* Number of 'x' found */
    static const char *const optionStrings[] = {
	"-column", "-columnspan", "-in", "-ipadx", "-ipady",
	"-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;
    const char *string;
    char firstChar;
    int positionGiven;

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	TkSizeT length;
	char prevChar = firstChar;

	string = TkGetStringFromObj(objv[i], &length);
    	firstChar = string[0];

	if (firstChar == '.') {
	    /*
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */

	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (containerPtr == NULL) {
		/*
		 * Is there any saved -in from a removed content?
		 * If there is, it becomes default for -in.
		 * If the stored container does not exist, just ignore it.
		 */

		contentPtr = GetGrid(content);
		if (contentPtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, content, contentPtr->in, &parent)
			    == TCL_OK) {
			containerPtr = GetGrid(parent);
			InitContainerData(containerPtr);
		    }
		}
	    }
	    if (containerPtr == NULL) {
		parent = Tk_Parent(content);
		if (parent != NULL) {
		    containerPtr = GetGrid(parent);
		    InitContainerData(containerPtr);
		}
	    }
	    numWindows++;
	    continue;
    	}
	if (length > 1 && i == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument \"%s\": must be name of window", string));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	    return TCL_ERROR;
	}
    	if (length > 1 && firstChar == '-') {
	    break;
	}
	if (length > 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "unexpected parameter \"%s\" in configure list:"
		    " should be window name or option", string));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_HORIZ) && ((numWindows == 0) ||
		(prevChar == REL_SKIP) || (prevChar == REL_VERT))) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify window before shortcut '-'", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)
		|| (firstChar == REL_HORIZ)) {
	    continue;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid window shortcut, \"%s\" should be '-', 'x', or '^'",
		string));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    numWindows = i;

    if ((objc - numWindows) & 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra option or option with no value", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	return TCL_ERROR;
    }

    /*
     * 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_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *), "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;
	    }
	    containerPtr = GetGrid(other);
	    InitContainerData(containerPtr);
	} else if (index == CONF_ROW) {
	    if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
		    || tmp < 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad row value \"%s\": must be a non-negative integer",
			Tcl_GetString(objv[i+1])));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "POSITIVE_INT", NULL);
		return TCL_ERROR;
	    }
	    defaultRow = tmp;
	}
    }

    /*
     * If no -row is given, use the next row after the highest occupied row
     * of the container.
     */

    if (defaultRow < 0) {
	if (containerPtr != NULL && containerPtr->containerDataPtr != NULL) {
	    SetGridSize(containerPtr);
	    defaultRow = containerPtr->containerDataPtr->rowEnd;
	} else {
	    defaultRow = 0;
	}
    }

    /*
     * Iterate over all of the content windows and short-cuts, parsing options
     * for each content. It's a bit wasteful to re-parse the options for each
     * content, but things get too messy if we try to parse the arguments just
     * once at the beginning. For example, if a content 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.
     */

    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 content.
	 */

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)) {
	    defaultColumn++;
	    continue;
	}
	if (firstChar == REL_HORIZ) {
	    continue;
	}

	for (defaultColumnSpan = 1; j + defaultColumnSpan < numWindows;
		defaultColumnSpan++) {
	    string = Tcl_GetString(objv[j + defaultColumnSpan]);

	    if (*string != REL_HORIZ) {
		break;
	    }
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[j], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't manage \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	contentPtr = GetGrid(content);

	/*
	 * The following statement is taken from tkPack.c:
	 *
	 * "If the content isn't currently managed, reset all of its
	 * configuration information to default values (there could be old
	 * values left from a previous packer)."
	 *
	 * I [D.S.] disagree with this statement. If a content 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.
	 */

	for (i = numWindows; i < objc; i += 2) {
	    Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &index);
	    switch ((enum options) index) {
	    case CONF_COLUMN:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp < 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad column value \"%s\": must be a non-negative integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL);
		    return TCL_ERROR;
		}
		if (SetContentColumn(interp, contentPtr, tmp, -1) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_COLUMNSPAN:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp <= 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad columnspan value \"%s\": must be a positive integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL);
		    return TCL_ERROR;
		}
		if (SetContentColumn(interp, contentPtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
			&other) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (other == content) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "window can't be managed in itself", -1));
		    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);

		    return TCL_ERROR;
		}
		positionGiven = 1;
		containerPtr = GetGrid(other);
		InitContainerData(containerPtr);
		break;
	    case CONF_STICKY: {
		int sticky = StringToSticky(Tcl_GetString(objv[i+1]));

		if (sticky == -1) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad stickyness value \"%s\": must be"
			    " a string containing n, e, s, and/or w",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "STICKY", NULL);
		    return TCL_ERROR;
		}
		contentPtr->sticky = sticky;
		break;
	    }
	    case CONF_IPADX:
		if ((Tk_GetPixelsFromObj(NULL, content, objv[i+1],
			&tmp) != TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipadx value \"%s\": must be positive screen distance",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		contentPtr->iPadX = tmp * 2;
		break;
	    case CONF_IPADY:
		if ((Tk_GetPixelsFromObj(NULL, content, objv[i+1],
			&tmp) != TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipady value \"%s\": must be positive screen distance",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		contentPtr->iPadY = tmp * 2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&contentPtr->padLeft, &contentPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROW:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp < 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad row value \"%s\": must be a non-negative integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL);
		    return TCL_ERROR;
		}
		if (SetContentRow(interp, contentPtr, tmp, -1) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROWSPAN:
		if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK)
			|| tmp <= 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad rowspan value \"%s\": must be a positive integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL);
		    return TCL_ERROR;
		}
		if (SetContentRow(interp, contentPtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}

	/*
	 * If no position was specified via -in and the content is already
	 * packed, then leave it in its current location.
	 */

    	if (!positionGiven && (contentPtr->containerPtr != NULL)) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
    	}

	/*
	 * If the same -in window is passed in again, then just leave it in
	 * its current location.
	 */

	if (positionGiven && (containerPtr == contentPtr->containerPtr)) {
	    goto scheduleLayout;
	}

	/*
	 * Make sure we have a geometry container. We look at:
	 *  1)   the -in flag
	 *  2)   the parent of the first content.
	 */

	parent = Tk_Parent(content);
    	if (containerPtr == NULL) {
	    containerPtr = GetGrid(parent);
	    InitContainerData(containerPtr);
    	}

	if (contentPtr->containerPtr != NULL && contentPtr->containerPtr != containerPtr) {
            if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
                Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
            }
	    Unlink(contentPtr);
	    contentPtr->containerPtr = NULL;
	}

	if (contentPtr->containerPtr == NULL) {



	    Gridder *tempPtr = containerPtr->contentPtr;




	    contentPtr->containerPtr = containerPtr;


	    containerPtr->contentPtr = contentPtr;


	    contentPtr->nextPtr = tempPtr;
	}

	/*
	 * Make sure that the content's parent is either the container or an
	 * ancestor of the container, and that the container and content aren't the
	 * same.
	 */

	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't put \"%s\" inside \"%s\"", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(

		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;
	}

	Tk_ManageGeometry(content, &gridMgrType, contentPtr);

	if (!(containerPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryContainer(interp, containerPtr->tkwin, "grid")
		    != TCL_OK) {
		Tk_ManageGeometry(content, NULL, NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	    containerPtr->flags |= ALLOCED_CONTAINER;
	}

	/*
	 * Assign default position information.
	 */

	if (contentPtr->column == -1) {
	    if (SetContentColumn(interp, contentPtr, defaultColumn,-1) != TCL_OK){
		return TCL_ERROR;
	    }
	}
	if (SetContentColumn(interp, contentPtr, -1,
		contentPtr->numCols + defaultColumnSpan - 1) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (contentPtr->row == -1) {
	    if (SetContentRow(interp, contentPtr, defaultRow, -1) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	defaultColumn += contentPtr->numCols;
	defaultColumnSpan = 1;

	/*
	 * Arrange for the container to be re-arranged at the first idle moment.
	 */

    scheduleLayout:
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }

    /*
     * 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. */

	string = Tcl_GetString(objv[j]);
	firstChar = string[0];

	if (firstChar == '.') {
	    lastWindow = string;
	    numSkip = 0;
	}
	if (firstChar == REL_SKIP) {
	    numSkip++;
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', can't find container window", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */

	for (width = 1; width + j < numWindows; width++) {
	    string = Tcl_GetString(objv[j+width]);

	    if (*string != REL_VERT) {
		break;
	    }
	}

	/*







|
















|

|

|
|

|













|





|


|








|





|

|






|

|


|
|
|
|

|
|
|
|





|

|






|





|

|





|
|



|
<



|
|






|

|






|





|

|





|
|



|
<



|
|















|









|















|









|
|
|



|
|




|

|
|



|

|
|

|
|




|

|









|


|





|






|
|

|
|
|




|



|















|





|







|

|

|
|



|
|

|
|


|
|




|
|
|

|
|


|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<










|













|

|

|
|
|

|
|

|




|















|










|



|


|

|

|

|
|



|

|


|
|
<
|
|
|
|


|

|


|

|


|


|

|
|
|







|


|
|







|





|


|

|




|
|
|
<






|


|







|









|


|




|



|


|

|

|


|
|
|

|
|



|
|

|
|






|
|
<






|
|
|
<





|
|
<








|
|
<
<





<
|
<











|
|







|
|



|
|
|
|







|
<



|
|
|






|
|
|
|












|












|






|



|
|
|
<
<


|




|



|








|
|




<
|
|
|


|






<
|
|
|


|








|
<
|
<
>



|
|





<
|
<
|
|


|



|

<
|
|
|


|


|

<
|
|
|


|



|





|






|
<
|
|


|






<
|
|
|


|







|



|
|








|




|

|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
|
>
>
>
|
|
>
>
|
>
>
|



|
|



|




<
|
|
<
|





|


|
<
<
|
>
|
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<





|
|



|
|


|
|



|



|



|
|

|
|
|











|
|


|

|










|
<
|
<








|







2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516

2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556

2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745

2746













2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900

2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971

2972
2973
2974
2975
2976
2977
2978
2979
2980

2981
2982
2983
2984
2985
2986
2987

2988
2989
2990
2991
2992
2993
2994
2995
2996
2997


2998
2999
3000
3001
3002

3003

3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040

3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095


3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121

3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133

3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148

3149

3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160

3161

3162
3163
3164
3165
3166
3167
3168
3169
3170
3171

3172
3173
3174
3175
3176
3177
3178
3179
3180
3181

3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204

3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215

3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253













3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282

3283
3284

3285
3286
3287
3288
3289
3290
3291
3292
3293
3294


3295
3296
3297


3298
3299
3300
3301









3302





3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364

3365

3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
 */

static Gridder *
GetGrid(
    Tk_Window tkwin)		/* Token for window for which grid structure
				 * is desired. */
{
    register Gridder *gridPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->gridInit) {
	Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS);
	dispPtr->gridInit = 1;
    }

    /*
     * See if there's already grid for this window. If not, then create a new
     * one.
     */

    hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char*) tkwin, &isNew);
    if (!isNew) {
	return (Gridder *) Tcl_GetHashValue(hPtr);
    }
    gridPtr = (Gridder *) ckalloc(sizeof(Gridder));
    gridPtr->tkwin = tkwin;
    gridPtr->masterPtr = NULL;
    gridPtr->masterDataPtr = NULL;
    gridPtr->nextPtr = NULL;
    gridPtr->slavePtr = NULL;
    gridPtr->binNextPtr = NULL;

    gridPtr->column = -1;
    gridPtr->row = -1;
    gridPtr->numCols = 1;
    gridPtr->numRows = 1;

    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,
	    GridStructureProc, (ClientData) gridPtr);
    return gridPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * SetGridSize --
 *
 *	This internal procedure sets the size of the grid occupied by slaves.
 *
 * Results:
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
SetGridSize(
    Gridder *masterPtr)		/* The geometry master for this grid. */
{
    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);
    }
    masterPtr->masterDataPtr->columnEnd = maxX;
    masterPtr->masterDataPtr->rowEnd = maxY;
    CheckSlotData(masterPtr, maxX, COLUMN, CHECK_SPACE);
    CheckSlotData(masterPtr, maxY, ROW, CHECK_SPACE);
}

/*
 *----------------------------------------------------------------------
 *
 * SetSlaveColumn --
 *
 *	Update column data for a slave, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	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. */
{
    int newColumn, newNumCols, lastCol;

    newColumn = (column >= 0) ? column : slavePtr->column;
    newNumCols = (numCols >= 1) ? numCols : slavePtr->numCols;

    lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
    if (lastCol >= MAX_ELEMENT) {
	Tcl_SetResult(interp, "Column out of bounds", TCL_STATIC);

	return TCL_ERROR;
    }

    slavePtr->column = newColumn;
    slavePtr->numCols = newNumCols;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetSlaveRow --
 *
 *	Update row data for a slave, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	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. */
{
    int newRow, newNumRows, lastRow;

    newRow = (row >= 0) ? row : slavePtr->row;
    newNumRows = (numRows >= 1) ? numRows : slavePtr->numRows;

    lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
    if (lastRow >= MAX_ELEMENT) {
	Tcl_SetResult(interp, "Row out of bounds", TCL_STATIC);

	return TCL_ERROR;
    }

    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.
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

static int
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. */

    /*
     * If slot is out of bounds, return immediately.
     */

    if (slot < 0 || slot >= MAX_ELEMENT) {
	return TCL_ERROR;
    }

    if ((checkOnly == CHECK_ONLY) && (masterPtr->masterDataPtr == NULL)) {
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    InitMasterData(masterPtr);
    end = (slotType == ROW) ? masterPtr->masterDataPtr->rowMax :
	    masterPtr->masterDataPtr->columnMax;
    if (checkOnly == CHECK_ONLY) {
    	return ((end < slot) ? TCL_ERROR : TCL_OK);
    } else {
    	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 *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 = newSI;
	    	masterPtr->masterDataPtr->rowSpace = newNumSlot;
	    } else {
	    	masterPtr->masterDataPtr->columnPtr = newSI;
	    	masterPtr->masterDataPtr->columnSpace = newNumSlot;
	    }
	}
	if (slot >= end && checkOnly != CHECK_SPACE) {
	    if (slotType == ROW) {
		masterPtr->masterDataPtr->rowMax = slot+1;
	    } else {
		masterPtr->masterDataPtr->columnMax = slot+1;
	    }
	}
    	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * InitMasterData --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
InitMasterData(
    Gridder *masterPtr)
{
    if (masterPtr->masterDataPtr == NULL) {
	GridMaster *gridPtr = masterPtr->masterDataPtr = (GridMaster *)
		ckalloc(sizeof(GridMaster));
	size_t size = sizeof(SlotInfo) * TYPICAL_SIZE;

	gridPtr->columnEnd = 0;
	gridPtr->columnMax = 0;
	gridPtr->columnPtr = (SlotInfo *) ckalloc(size);
	gridPtr->columnSpace = TYPICAL_SIZE;
	gridPtr->rowEnd = 0;
	gridPtr->rowMax = 0;
	gridPtr->rowPtr = (SlotInfo *) ckalloc(size);
	gridPtr->rowSpace = TYPICAL_SIZE;
	gridPtr->startX = 0;
	gridPtr->startY = 0;
	gridPtr->anchor = GRID_DEFAULT_ANCHOR;

	memset(gridPtr->columnPtr, 0, size);
	memset(gridPtr->rowPtr, 0, size);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a grid from its master's list of slaves.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The master will be scheduled for re-arranging, and the size of the
 *	grid will be adjusted accordingly
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    register Gridder *slavePtr)	/* Window to unlink. */
{
    register Gridder *masterPtr, *slavePtr2;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
	return;
    }

    if (masterPtr->slavePtr == slavePtr) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    } else {
	for (slavePtr2=masterPtr->slavePtr ; ; slavePtr2=slavePtr2->nextPtr) {
	    if (slavePtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (slavePtr2->nextPtr == slavePtr) {
		slavePtr2->nextPtr = slavePtr->nextPtr;
		break;
	    }
	}
    }
    if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	masterPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
    }
    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    }

    SetGridSize(slavePtr->masterPtr);

    slavePtr->masterPtr = NULL;













}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
    char *memPtr)		/* Info about window that is now dead. */
{
    register Gridder *gridPtr = (Gridder *) memPtr;

    if (gridPtr->masterDataPtr != NULL) {
	if (gridPtr->masterDataPtr->rowPtr != NULL) {
	    ckfree((char *) gridPtr->masterDataPtr -> rowPtr);
	}
	if (gridPtr->masterDataPtr->columnPtr != NULL) {
	    ckfree((char *) gridPtr->masterDataPtr -> columnPtr);
	}
	ckfree((char *) gridPtr->masterDataPtr);
    }
    if (gridPtr->in != NULL) {
	Tcl_DecrRefCount(gridPtr->in);
    }
    ckfree((char *) gridPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GridStructureProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
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->slavePtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
	}
	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);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	register Gridder *gridPtr2, *nextPtr;

	if (gridPtr->masterPtr != NULL) {
	    Unlink(gridPtr);
	}
	for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
		gridPtr2 = nextPtr) {

	    Tk_UnmapWindow(gridPtr2->tkwin);
	    gridPtr2->masterPtr = NULL;
	    nextPtr = gridPtr2->nextPtr;
	    gridPtr2->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		(char *) gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, (ClientData) gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree((ClientData) gridPtr, DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->slavePtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	register Gridder *gridPtr2;

	for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
		gridPtr2 = gridPtr2->nextPtr) {
	    Tk_UnmapWindow(gridPtr2->tkwin);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * 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.
 *
 * Side effects:
 *	Slave windows get taken over by the grid.
 *
 *----------------------------------------------------------------------
 */

static int
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 = NULL;
    Gridder *slavePtr;
    Tk_Window other, slave, parent, ancestor;

    int i, j, tmp;
    int numWindows;
    int width;
    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", 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;
    int positionGiven;

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    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", NULL);

	    return TCL_ERROR;
	}
    	if (length > 1 && firstChar == '-') {
	    break;
	}
	if (length > 1) {
	    Tcl_AppendResult(interp, "unexpected parameter, \"",
		    string, "\", in configure list. ",
		    "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 '-'.", NULL);

	    return TCL_ERROR;
	}

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)
		|| (firstChar == REL_HORIZ)) {
	    continue;
	}

	Tcl_AppendResult(interp, "invalid window shortcut, \"",
		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", NULL);

	return TCL_ERROR;
    }

    /*
     * 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.
     */

    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.
	 */

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)) {
	    defaultColumn++;
	    continue;
	}
	if (firstChar == REL_HORIZ) {
	    continue;
	}

	for (defaultColumnSpan = 1; j + defaultColumnSpan < numWindows;
		defaultColumnSpan++) {
	    char *string = Tcl_GetString(objv[j + defaultColumnSpan]);

	    if (*string != REL_HORIZ) {
		break;
	    }
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[j], &slave) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (Tk_TopWinHierarchy(slave)) {
	    Tcl_AppendResult(interp, "can't manage \"", Tcl_GetString(objv[j]),
		    "\": it's a top-level window", NULL);


	    return TCL_ERROR;
	}
	slavePtr = GetGrid(slave);

	/*
	 * 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)."
	 *
	 * 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.
	 */

	for (i = numWindows; i < objc; i += 2) {
	    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;
		}
		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", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
			&other) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (other == slave) {

		    Tcl_SetResult(interp, "Window can't be managed in itself",

			    TCL_STATIC);
		    return TCL_ERROR;
		}
		positionGiven = 1;
		masterPtr = GetGrid(other);
		InitMasterData(masterPtr);
		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", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadX = tmp*2;
		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", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadY = tmp*2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROW:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp < 0) {
		    Tcl_AppendResult(interp, "bad row value \"",

			    Tcl_GetString(objv[i+1]),
			    "\": must be a non-negative integer", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROWSPAN:
		if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK)
			|| tmp <= 0) {

		    Tcl_AppendResult(interp, "bad rowspan value \"",
			    Tcl_GetString(objv[i+1]),
			    "\": must be a positive integer", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}

	/*
	 * If no position was specified via -in and the slave is already
	 * packed, then leave it in its current location.
	 */

    	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);
	    InitMasterData(masterPtr);
    	}

	if (slavePtr->masterPtr != NULL && slavePtr->masterPtr != masterPtr) {
	    Unlink(slavePtr);
	    slavePtr->masterPtr = NULL;
	}

	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.
	 */

	for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {

		Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]),
			" inside ", Tk_PathName(masterPtr->tkwin), NULL);

		Unlink(slavePtr);
		return TCL_ERROR;
	    }
	}

	/*
	 * Try to make sure our master isn't managed by us.
	 */

     	if (masterPtr->masterPtr == slavePtr) {


	    Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]),
		    " inside ", Tk_PathName(masterPtr->tkwin),
		    ", would cause management loop.", NULL);


	    Unlink(slavePtr);
	    return TCL_ERROR;
     	}










	Tk_ManageGeometry(slave, &gridMgrType, (ClientData) slavePtr);






	/*
	 * Assign default position information.
	 */

	if (slavePtr->column == -1) {
	    if (SetSlaveColumn(interp, slavePtr, defaultColumn,-1) != TCL_OK){
		return TCL_ERROR;
	    }
	}
	if (SetSlaveColumn(interp, slavePtr, -1,
		slavePtr->numCols + defaultColumnSpan - 1) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (slavePtr->row == -1) {
	    if (SetSlaveRow(interp, slavePtr, defaultRow, -1) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	defaultColumn += slavePtr->numCols;
	defaultColumnSpan = 1;

	/*
	 * Arrange for the master to be re-arranged at the first idle moment.
	 */

    scheduleLayout:
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
	}
    }

    /*
     * 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. */

	string = Tcl_GetString(objv[j]);
    	firstChar = string[0];

    	if (firstChar == '.') {
	    lastWindow = string;
	    numSkip = 0;
	}
	if (firstChar == REL_SKIP) {
	    numSkip++;
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (masterPtr == NULL) {

	    Tcl_AppendResult(interp, "can't use '^', cant find master", NULL);

	    return TCL_ERROR;
	}

	/*
	 * 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;
	    }
	}

	/*
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569

3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586




3587
3588
3589
3590
3591
3592
3593
	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	match = 0;
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {

	    if (contentPtr->column == lastColumn
		    && contentPtr->row + contentPtr->numRows - 1 == lastRow) {
		if (contentPtr->numCols <= width) {
		    if (SetContentRow(interp, contentPtr, -1,
			    contentPtr->numRows + 1) != TCL_OK) {
			return TCL_ERROR;
		    }
		    match++;
		    j += contentPtr->numCols - 1;
		    lastWindow = Tk_PathName(contentPtr->tkwin);
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find content to extend with \"^\"", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine container window", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(containerPtr);

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if (containerPtr->contentPtr == NULL && containerPtr->flags & ALLOCED_CONTAINER) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * StickyToObj
 *
 *	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 new object is returned that holds the sticky representation.
 *
 * Side effects:
 *	none.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
StickyToObj(
    int flags)			/* The sticky flags. */

{
    int count = 0;
    char buffer[4];

    if (flags & STICK_NORTH) {
    	buffer[count++] = 'n';
    }
    if (flags & STICK_EAST) {
    	buffer[count++] = 'e';
    }
    if (flags & STICK_SOUTH) {
    	buffer[count++] = 's';
    }
    if (flags & STICK_WEST) {
    	buffer[count++] = 'w';
    }
    return Tcl_NewStringObj(buffer, count);




}

/*
 *----------------------------------------------------------------------
 *
 * StringToSticky --
 *







|
|

|
|
|
|
|



|
|






<
|
|




|
<
|
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|





|







|
|
|
>


<
<
|
|

|
|

|
|

|
|

|
>
>
>
>







3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416

3417
3418
3419
3420
3421
3422
3423

3424

3425
3426
3427















3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453


3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	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;
		    }
		    match++;
		    j += slavePtr->numCols - 1;
		    lastWindow = Tk_PathName(slavePtr->tkwin);
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {

	    Tcl_AppendResult(interp, "can't find slave to extend with \"^\".",
		    NULL);
	    return TCL_ERROR;
	}
    }

    if (masterPtr == NULL) {

	Tcl_AppendResult(interp, "can't determine master window", NULL);

	return TCL_ERROR;
    }
    SetGridSize(masterPtr);















    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * StickyToString
 *
 *	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.
 *
 * Side effects:
 *	none.
 *
 *----------------------------------------------------------------------
 */

static void
StickyToString(
    int flags,			/* The sticky flags. */
    char *result)		/* Where to put the result. */
{
    int count = 0;


    if (flags&STICK_NORTH) {
    	result[count++] = 'n';
    }
    if (flags&STICK_EAST) {
    	result[count++] = 'e';
    }
    if (flags&STICK_SOUTH) {
    	result[count++] = 's';
    }
    if (flags&STICK_WEST) {
    	result[count++] = 'w';
    }
    if (count) {
	result[count] = '\0';
    } else {
	sprintf(result, "{}");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * StringToSticky --
 *
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
 *	none
 *
 *----------------------------------------------------------------------
 */

static int
StringToSticky(
    const char *string)
{
    int sticky = 0;
    char c;

    while ((c = *string++) != '\0') {
	switch (c) {
	case 'n': case 'N':







|







3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
 *	none
 *
 *----------------------------------------------------------------------
 */

static int
StringToSticky(
    char *string)
{
    int sticky = 0;
    char c;

    while ((c = *string++) != '\0') {
	switch (c) {
	case 'n': case 'N':
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewPairObj(
    Tcl_WideInt val1, Tcl_WideInt val2)
{
    Tcl_Obj *ary[2];

    ary[0] = Tcl_NewWideIntObj(val1);
    ary[1] = Tcl_NewWideIntObj(val2);
    return Tcl_NewListObj(2, ary);
}

/*
 *----------------------------------------------------------------------
 *
 * NewQuadObj --







|



|
|







3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewPairObj(
    int val1, int val2)
{
    Tcl_Obj *ary[2];

    ary[0] = Tcl_NewIntObj(val1);
    ary[1] = Tcl_NewIntObj(val2);
    return Tcl_NewListObj(2, ary);
}

/*
 *----------------------------------------------------------------------
 *
 * NewQuadObj --
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewQuadObj(
    Tcl_WideInt val1, Tcl_WideInt val2, Tcl_WideInt val3, Tcl_WideInt val4)
{
    Tcl_Obj *ary[4];

    ary[0] = Tcl_NewWideIntObj(val1);
    ary[1] = Tcl_NewWideIntObj(val2);
    ary[2] = Tcl_NewWideIntObj(val3);
    ary[3] = Tcl_NewWideIntObj(val4);
    return Tcl_NewListObj(4, ary);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



|
|
|
|










3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewQuadObj(
    int val1, int val2, int val3, int val4)
{
    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:
 */

Changes to generic/tkImage.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Each call to Tk_GetImage returns a pointer to one of the following
 * structures, which is used as a token by clients (widgets) that display
 * images.
 */

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. */
    struct ImageModel *modelPtr;
				/* Model for this image (identifiers image
				 * manager, for example). */
    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. */
    struct Image *nextPtr;	/* Next in list of all image instances
				 * associated with the same name. */
} Image;

/*
 * For each image model 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 ImageModel {
    Tk_ImageType *typePtr;	/* Information about image type. NULL means
				 * that no image manager owns this image: the
				 * image was deleted. */
    ClientData modelData;	/* One-word argument to pass to image mgr when
				 * dealing with the model, 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
				 * structure). */
    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.) */
} ImageModel;

typedef struct {
    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 functions:
 */

static void		ImageTypeThreadExitProc(ClientData clientData);
static void		DeleteImage(ImageModel *modelPtr);
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    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(
    TCL_UNUSED(void *))
{
    Tk_ImageType *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    while (tsdPtr->oldImageTypeList != NULL) {
	freePtr = tsdPtr->oldImageTypeList;
	tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr;
	ckfree(freePtr);
    }
    while (tsdPtr->imageTypeList != NULL) {
	freePtr = tsdPtr->imageTypeList;
	tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr;
	ckfree(freePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateOldImageType, Tk_CreateImageType --
 *
 *	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







|
|









|
|












|




|



|
|













|

|















|
|




















|

|
|





|




|


|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Each call to Tk_GetImage returns a pointer to one of the following
 * structures, which is used as a token by clients (widgets) that
 * display images.
 */

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. */
    struct ImageMaster *masterPtr;
				/* Master for this image (identifiers image
				 * manager, for example). */
    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. */
    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.
 */

typedef struct ImageMaster {
    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. */
    int width, height;		/* Last known dimensions for image. */
    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
				 * 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.) */
} 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. */
    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

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 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *	command.
 *
 *----------------------------------------------------------------------
 */

void
Tk_CreateOldImageType(
    const Tk_ImageType *typePtr)
				/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_ImageType *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    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(
    const Tk_ImageType *typePtr)
				/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_ImageType *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    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;
}

/*
 *----------------------------------------------------------------------







<
|



|
|






|







<
|



|
|






|







139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
 *	command.
 *
 *----------------------------------------------------------------------
 */

void
Tk_CreateOldImageType(

    Tk_ImageType *typePtr)	/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
	Tk_ImageType *copyPtr;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    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(

    Tk_ImageType *typePtr)	/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
	Tk_ImageType *copyPtr;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    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;
}

/*
 *----------------------------------------------------------------------
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
 */

int
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 *const imageOptions[] = {
	"create", "delete", "height", "inuse", "names", "type", "types",
	"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, isNew, firstOption, index;
    Tk_ImageType *typePtr;
    ImageModel *modelPtr;
    Image *imagePtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char idString[16 + TCL_INTEGER_SPACE];
    TkDisplay *dispPtr = winPtr->dispPtr;
    const char *arg, *name;
    Tcl_Obj *resultObj;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {
    case IMAGE_CREATE: {
	Tcl_Obj **args;
	int oldimage = 0;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "type ?name? ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * Look up the image type.
	 */








|

|







|


|





|
<








|
|






<

|
<







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243

244
245
246
247
248
249
250
 */

int
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", 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, isNew, firstOption, index;
    Tk_ImageType *typePtr;
    ImageMaster *masterPtr;
    Image *imagePtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char idString[16 + TCL_INTEGER_SPACE];
    TkDisplay *dispPtr = winPtr->dispPtr;
    char *arg, *name;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], imageOptions, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {
    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.
	 */

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363


364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
		if ((*arg == typePtr->name[0])
			&& (strcmp(arg, typePtr->name) == 0)) {
		    break;
		}
	    }
	}
	if (typePtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image type \"%s\" doesn't exist", arg));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE_TYPE", arg, NULL);
	    return TCL_ERROR;
	}

	/*
	 * Figure out a name to use for the new image.
	 */

	if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {

	    do {
		dispPtr->imageId++;
		sprintf(idString, "image%d", dispPtr->imageId);
		name = idString;
	    } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
	    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 model 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_SetObjResult(interp, Tcl_NewStringObj(
			"images may not be named the same as the main window",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SMASH_MAIN", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Create the data structure for the new image.
	 */

	hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &isNew);
	if (isNew) {
	    modelPtr = (ImageModel *)ckalloc(sizeof(ImageModel));
	    modelPtr->typePtr = NULL;
	    modelPtr->modelData = NULL;
	    modelPtr->width = modelPtr->height = 1;
	    modelPtr->tablePtr = &winPtr->mainPtr->imageTable;
	    modelPtr->hPtr = hPtr;
	    modelPtr->instancePtr = NULL;
	    modelPtr->deleted = 0;
	    modelPtr->winPtr = winPtr->mainPtr->winPtr;
	    Tcl_Preserve(modelPtr->winPtr);
	    Tcl_SetHashValue(hPtr, modelPtr);
	} else {
	    /*
	     * An image already exists by this name. Disconnect the instances
	     * from the model.
	     */

	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->typePtr != NULL) {
		for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
			imagePtr = imagePtr->nextPtr) {
		    modelPtr->typePtr->freeProc(imagePtr->instanceData,
			    imagePtr->display);
		    imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
			    modelPtr->width, modelPtr->height,
			    modelPtr->width, modelPtr->height);
		}
		modelPtr->typePtr->deleteProc(modelPtr->modelData);
		modelPtr->typePtr = NULL;
	    }
	    modelPtr->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) {


	    args = (Tcl_Obj **)ckalloc((objc+1) * sizeof(Tcl_Obj *));
	    for (i = 0; i < objc; i++) {
		args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
	    }
	    args[objc] = NULL;
	}
	Tcl_Preserve(modelPtr);
	if (typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData) != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
	Tcl_Release(modelPtr);
	if (oldimage) {
	    ckfree(args);
	}
	modelPtr->typePtr = typePtr;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
		    modelPtr->modelData);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));

	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) {
		goto alreadyDeleted;
	    }
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage(modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
	resultObj = Tcl_NewObj();
	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		continue;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    case IMAGE_TYPES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, -1));
	}
	for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	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 model 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;
	}
	modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	if (modelPtr->deleted) {
	    goto alreadyDeleted;
	}

	/*
	 * Now we read off the specific piece of data we were asked for.
	 */

	switch ((enum options) index) {
	case IMAGE_HEIGHT:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->height));
	    break;
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(modelPtr->typePtr->name, -1));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
	}
	break;
    }
    return TCL_OK;

  alreadyDeleted:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("image \"%s\" doesn't exist",arg));
    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", arg, NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ImageChanged --







|
<
|








>




|









|






|
|
<
<










|
|
|
|
|
|
|
|
|
|
|



|


|
|
|

|

|
|
|

|
|

|












>
>
|





|
|
|
|
|

|



|

|

|
|

|
|

|
|
>









|
|


|








<

|
|


|
|

<






<


<
|



<
|

<








|













|
|









|


|
|


|
<
|



|









|
<







263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303


304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417

418
419
420
421
422
423

424
425

426
427
428
429

430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
		if ((*arg == typePtr->name[0])
			&& (strcmp(arg, typePtr->name) == 0)) {
		    break;
		}
	    }
	}
	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.
	 */

	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", 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 {
	    /*
	     * 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;
	    }
	    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);
	    }
	    return TCL_ERROR;
	}
	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;
    }
    case IMAGE_DELETE:
	for (i = 2; i < objc; i++) {
	    arg = Tcl_GetString(objv[i]);
	    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
	    if (masterPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage(masterPtr);
	}
	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;
	    }
	    Tcl_AppendElement(interp, Tcl_GetHashKey(
		    &winPtr->mainPtr->imageTable, 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_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;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ImageChanged --
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 *	redisplay themselves as appropriate.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ImageChanged(
    Tk_ImageModel imageModel,	/* 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. */
{
    ImageModel *modelPtr = (ImageModel *) imageModel;
    Image *imagePtr;

    modelPtr->width = imageWidth;
    modelPtr->height = imageHeight;
    for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
	    imagePtr = imagePtr->nextPtr) {
	imagePtr->changeProc(imagePtr->widgetClientData, x, y, width, height,
		imageWidth, imageHeight);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NameOfImage --
 *
 *	Given a token for an image model, this function returns the name of
 *	the image.
 *
 * Results:
 *	The return value is the string name for imageModel.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
Tk_NameOfImage(
    Tk_ImageModel imageModel)	/* Token for image. */
{
    ImageModel *modelPtr = (ImageModel *) imageModel;

    if (modelPtr->hPtr == NULL) {
	return NULL;
    }
    return (const char *)Tcl_GetHashKey(modelPtr->tablePtr, modelPtr->hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImage --
 *







|










|


|
|
|

|
|








|



|







|

|

|

|


|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
 *	redisplay themselves as appropriate.
 *
 *----------------------------------------------------------------------
 */

void
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;

    masterPtr->width = imageWidth;
    masterPtr->height = imageHeight;
    for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
	    imagePtr = imagePtr->nextPtr) {
	(*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
		width, height, imageWidth, imageHeight);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NameOfImage --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CONST char *
Tk_NameOfImage(
    Tk_ImageMaster imageMaster)	/* Token for image. */
{
    ImageMaster *masterPtr = (ImageMaster *) imageMaster;

    if (masterPtr->hPtr == NULL) {
	return NULL;
    }
    return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImage --
 *
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

Tk_Image
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;
    ImageModel *modelPtr;
    Image *imagePtr;

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	goto noSuchImage;
    }
    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
    if (modelPtr->typePtr == NULL) {
	goto noSuchImage;
    }
    if (modelPtr->deleted) {
	goto noSuchImage;
    }
    imagePtr = (Image *)ckalloc(sizeof(Image));
    imagePtr->tkwin = tkwin;
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->modelPtr = modelPtr;
    imagePtr->instanceData =
	    modelPtr->typePtr->getProc(tkwin, modelPtr->modelData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", name, NULL);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|






|






|
|


|


|


|

|


|
|




|
<
<







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627


628
629
630
631
632
633
634

Tk_Image
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;
    Image *imagePtr;

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	goto noSuchImage;
    }
    masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
    if (masterPtr->typePtr == NULL) {
	goto noSuchImage;
    }
    if (masterPtr->deleted) {
	goto noSuchImage;
    }
    imagePtr = (Image *) ckalloc(sizeof(Image));
    imagePtr->tkwin = tkwin;
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->masterPtr = masterPtr;
    imagePtr->instanceData =
	    (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist", NULL);


    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709

void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageModel *modelPtr = imagePtr->modelPtr;
    Image *prevPtr;

    /*
     * Clean up the particular instance.
     */

    if (modelPtr->typePtr != NULL) {
	modelPtr->typePtr->freeProc(imagePtr->instanceData,
		imagePtr->display);
    }
    prevPtr = modelPtr->instancePtr;
    if (prevPtr == imagePtr) {
	modelPtr->instancePtr = imagePtr->nextPtr;
    } else {
	while (prevPtr->nextPtr != imagePtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = imagePtr->nextPtr;
    }
    ckfree(imagePtr);

    /*
     * If there are no more instances left for the model, and if the model
     * image has been deleted, then delete the model too.
     */

    if ((modelPtr->typePtr == NULL) && (modelPtr->instancePtr == NULL)) {
	if (modelPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(modelPtr->hPtr);
	}
	Tcl_Release(modelPtr->winPtr);
	ckfree(modelPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PostscriptImage --







|






|
|


|

|






|


|
|


|
|
|

|
|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageMaster *masterPtr = imagePtr->masterPtr;
    Image *prevPtr;

    /*
     * Clean up the particular instance.
     */

    if (masterPtr->typePtr != NULL) {
	(*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
		imagePtr->display);
    }
    prevPtr = masterPtr->instancePtr;
    if (prevPtr == imagePtr) {
	masterPtr->instancePtr = imagePtr->nextPtr;
    } else {
	while (prevPtr->nextPtr != imagePtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = imagePtr->nextPtr;
    }
    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 ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
	if (masterPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(masterPtr->hPtr);
	}
	Tcl_Release((ClientData) masterPtr->winPtr);
	ckfree((char *) masterPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PostscriptImage --
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    Image *imagePtr = (Image *) image;
    int result;
    XImage *ximage;
    Pixmap pmap;
    GC newGC;
    XGCValues gcValues;

    if (imagePtr->modelPtr->typePtr == NULL) {
	/*
	 * No model 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.
     */

    if (imagePtr->modelPtr->typePtr->postscriptProc != NULL) {
	return imagePtr->modelPtr->typePtr->postscriptProc(
		imagePtr->modelPtr->modelData, interp, tkwin, psinfo,
		x, y, width, height, prepass);
    }

    if (prepass) {
	return TCL_OK;
    }

    /*
     * 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.
     */

    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);
    if (newGC != NULL) {
	XFillRectangle(Tk_Display(tkwin), pmap, newGC, 0, 0,
		(unsigned) width, (unsigned) height);
	Tk_FreeGC(Tk_Display(tkwin), newGC);
    }

    Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);

    ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
	    (unsigned) width, (unsigned) 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.







|

|










|
|
|
|


















|
|






|







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    Image *imagePtr = (Image *) image;
    int result;
    XImage *ximage;
    Pixmap pmap;
    GC newGC;
    XGCValues gcValues;

    if (imagePtr->masterPtr->typePtr == NULL) {
	/*
	 * 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.
     */

    if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
	return (*imagePtr->masterPtr->typePtr->postscriptProc)(
	    imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
	    x, y, width, height, prepass);
    }

    if (prepass) {
	return TCL_OK;
    }

    /*
     * 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.
     */

    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);
    if (newGC != NULL) {
	XFillRectangle(Tk_Display(tkwin), pmap, newGC,
		0, 0, (unsigned int)width, (unsigned int)height);
	Tk_FreeGC(Tk_Display(tkwin), newGC);
    }

    Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);

    ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
	    (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.
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
				 * the Tk_GetImage call for the image. */
    int drawableX, int drawableY)
				/* Coordinates in drawable that correspond to
				 * imageX and imageY. */
{
    Image *imagePtr = (Image *) image;

    if (imagePtr->modelPtr->typePtr == NULL) {
	/*
	 * No model for image, so nothing to display.
	 */

	return;
    }

    /*
     * Clip the redraw area to the area of the image.
     */

    if (imageX < 0) {
	width += imageX;
	drawableX -= imageX;
	imageX = 0;
    }
    if (imageY < 0) {
	height += imageY;
	drawableY -= imageY;
	imageY = 0;
    }
    if ((imageX + width) > imagePtr->modelPtr->width) {
	width = imagePtr->modelPtr->width - imageX;
    }
    if ((imageY + height) > imagePtr->modelPtr->height) {
	height = imagePtr->modelPtr->height - imageY;
    }
    imagePtr->modelPtr->typePtr->displayProc(imagePtr->instanceData,
	    imagePtr->display, drawable, imageX, imageY, width, height,
	    drawableX, drawableY);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SizeOfImage --
 *







|

|



















|
|

|
|

|
|
|







817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
				 * the Tk_GetImage call for the image. */
    int drawableX, int drawableY)
				/* Coordinates in drawable that correspond to
				 * imageX and imageY. */
{
    Image *imagePtr = (Image *) image;

    if (imagePtr->masterPtr->typePtr == NULL) {
	/*
	 * No master for image, so nothing to display.
	 */

	return;
    }

    /*
     * Clip the redraw area to the area of the image.
     */

    if (imageX < 0) {
	width += imageX;
	drawableX -= imageX;
	imageX = 0;
    }
    if (imageY < 0) {
	height += imageY;
	drawableY -= imageY;
	imageY = 0;
    }
    if ((imageX + width) > imagePtr->masterPtr->width) {
	width = imagePtr->masterPtr->width - imageX;
    }
    if ((imageY + height) > imagePtr->masterPtr->height) {
	height = imagePtr->masterPtr->height - imageY;
    }
    (*imagePtr->masterPtr->typePtr->displayProc)(
	    imagePtr->instanceData, imagePtr->display, drawable,
	    imageX, imageY, width, height, drawableX, drawableY);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SizeOfImage --
 *
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
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;

    *widthPtr = imagePtr->modelPtr->width;
    *heightPtr = imagePtr->modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DeleteImage --
 *







|
|







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
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;

    *widthPtr = imagePtr->masterPtr->width;
    *heightPtr = imagePtr->masterPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DeleteImage --
 *
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
 *----------------------------------------------------------------------
 */

void
Tk_DeleteImage(
    Tcl_Interp *interp,		/* Interpreter in which the image was
				 * created. */
    const char *name)		/* Name of image. */
{
    Tcl_HashEntry *hPtr;
    TkWindow *winPtr;

    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((ImageModel *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *
 *	This function is responsible for deleting an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The connection is dropped between instances of this image and an image
 *	model. Image instances will redisplay themselves as empty areas, but
 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
    ImageModel *modelPtr)	/* Pointer to main data structure for image. */
{
    Image *imagePtr;
    Tk_ImageType *typePtr;

    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {

	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
	    imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
		    modelPtr->width, modelPtr->height, modelPtr->width,
		    modelPtr->height);
	}
	typePtr->deleteProc(modelPtr->modelData);
    }
    if (modelPtr->instancePtr == NULL) {
	if (modelPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(modelPtr->hPtr);
	}
	Tcl_Release(modelPtr->winPtr);
	ckfree(modelPtr);
    } else {
	modelPtr->deleted = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyDeleteImage --







|












|














|







|




|
|

|

>
|
|
|
|

|

|
|
|

|
|

|







900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
 *----------------------------------------------------------------------
 */

void
Tk_DeleteImage(
    Tcl_Interp *interp,		/* Interpreter in which the image was
				 * created. */
    CONST char *name)		/* Name of image. */
{
    Tcl_HashEntry *hPtr;
    TkWindow *winPtr;

    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((ImageMaster *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
    ImageMaster *masterPtr)	/* Pointer to main data structure for image. */
{
    Image *imagePtr;
    Tk_ImageType *typePtr;

    typePtr = masterPtr->typePtr;
    masterPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    (*typePtr->freeProc)(imagePtr->instanceData,
		    imagePtr->display);
	    (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
		    masterPtr->width, masterPtr->height, masterPtr->width,
		    masterPtr->height);
	}
	(*typePtr->deleteProc)(masterPtr->masterData);
    }
    if (masterPtr->instancePtr == NULL) {
	if (masterPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(masterPtr->hPtr);
	}
	Tcl_Release((ClientData) masterPtr->winPtr);
	ckfree((char *) masterPtr);
    } else {
	masterPtr->deleted = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyDeleteImage --
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
 *	ill effects.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyDeleteImage(
    ImageModel *modelPtr,	/* Pointer to main data structure for image. */
    int forgetImageHashNow)	/* Flag to say whether the hash table is about
				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, (Tcl_FreeProc *) DeleteImage);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --







|




|

|
|
|
>







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
 *	ill effects.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyDeleteImage(
    ImageMaster *masterPtr,	/* Pointer to main data structure for image. */
    int forgetImageHashNow)	/* Flag to say whether the hash table is about
				 * to vanish. */
{
    if (forgetImageHashNow) {
	masterPtr->hPtr = NULL;
    }
    if (!masterPtr->deleted) {
	masterPtr->deleted = 1;
	Tcl_EventuallyFree((ClientData) masterPtr,
		(Tcl_FreeProc *)DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083

1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
				 * going away. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;

    for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	EventuallyDeleteImage((ImageModel *)Tcl_GetHashValue(hPtr), 1);
    }
    Tcl_DeleteHashTable(&mainPtr->imageTable);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImageModelData --
 *
 *	Given the name of an image, this function returns the type of the
 *	image and the clientData associated with its model.
 *
 * 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tk_GetImageModelData(
    Tcl_Interp *interp,		/* Interpreter in which the image was
				 * created. */
    const char *name,		/* Name of image. */
    const Tk_ImageType **typePtrPtr)
				/* Points to location to fill in with pointer
				 * to type information for image. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    Tcl_HashEntry *hPtr;

    ImageModel *modelPtr;


    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	*typePtrPtr = NULL;
	return NULL;
    }
    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
    if (modelPtr->deleted) {
	*typePtrPtr = NULL;
	return NULL;
    }
    *typePtrPtr = modelPtr->typePtr;
    return modelPtr->modelData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetTSOrigin --
 *







|







|


|














|


|
<
|


<

>
|

>





|
|



|
|







1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063

1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
				 * going away. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;

    for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	EventuallyDeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr), 1);
    }
    Tcl_DeleteHashTable(&mainPtr->imageTable);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImageMasterData --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
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. */
{

    Tcl_HashEntry *hPtr;
    TkWindow *winPtr;
    ImageMaster *masterPtr;

    winPtr = (TkWindow *) Tk_MainWindow(interp);
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	*typePtrPtr = NULL;
	return NULL;
    }
    masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
    if (masterPtr->deleted) {
	*typePtrPtr = NULL;
	return NULL;
    }
    *typePtrPtr = masterPtr->typePtr;
    return masterPtr->masterData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetTSOrigin --
 *
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
 * Side Effects:
 *	The GCTileStipOrigin is reset in the GC. This will cause the tile
 *	origin to change when the GC is used for drawing.
 *
 *----------------------------------------------------------------------
 */


void
Tk_SetTSOrigin(
    Tk_Window tkwin,
    GC gc,
    int x, int y)
{
    while (!Tk_TopWinHierarchy(tkwin)) {







>







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
 * Side Effects:
 *	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(
    Tk_Window tkwin,
    GC gc,
    int x, int y)
{
    while (!Tk_TopWinHierarchy(tkwin)) {

Changes to generic/tkImgBmap.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 * 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 data structure represents the model for a bitmap
 * image:
 */

typedef struct {
    Tk_ImageModel tkModel;	/* Tk's token for image model. 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. */
    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). */
    char *dataString;		/* Value of -data option (malloc'ed). */
    char *maskFileString;	/* Value of -maskfile option (malloc'ed). */
    char *maskDataString;	/* Value of -maskdata option (malloc'ed). */
    struct BitmapInstance *instancePtr;
				/* First in list of all instances associated
				 * with this model. */
} BitmapModel;

/*
 * The following data structure represents all of the instances of an image
 * that lie within a particular window:
 */

typedef struct BitmapInstance {
    size_t refCount;		/* Number of instances that share this data
				 * structure. */
    BitmapModel *modelPtr;	/* Pointer to model for image. */
    Tk_Window tkwin;		/* Window in which the instances will be
				 * displayed. */
    XColor *fg;			/* Foreground color for displaying image. */
    XColor *bg;			/* Background color for displaying image. */
    Pixmap bitmap;		/* The bitmap to display. */
    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. */
    struct BitmapInstance *nextPtr;
				/* Next in list of all instance structures
				 * associated with modelPtr (NULL means end
				 * of list). */
} BitmapInstance;

/*
 * The type record for bitmap images:
 */

static int		GetByte(Tcl_Channel chan);
static int		ImgBmapCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    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(ClientData clientData, Display *display);







|



|
|




















|
|







|

|













|









|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 * 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 data structure represents the master for a bitmap
 * image:
 */

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. */
    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. */
    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). */
    char *dataString;		/* Value of -data option (malloc'ed). */
    char *maskFileString;	/* Value of -maskfile option (malloc'ed). */
    char *maskDataString;	/* Value of -maskdata option (malloc'ed). */
    struct BitmapInstance *instancePtr;
				/* First in list of all instances associated
				 * with this master. */
} BitmapMaster;

/*
 * 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. */
    BitmapMaster *masterPtr;	/* Pointer to master for image. */
    Tk_Window tkwin;		/* Window in which the instances will be
				 * displayed. */
    XColor *fg;			/* Foreground color for displaying image. */
    XColor *bg;			/* Background color for displaying image. */
    Pixmap bitmap;		/* The bitmap to display. */
    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. */
    struct BitmapInstance *nextPtr;
				/* Next in list of all instance structures
				 * associated with masterPtr (NULL means end
				 * of list). */
} BitmapInstance;

/*
 * The type record for bitmap images:
 */

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(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(ClientData clientData, Display *display);
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    "bitmap",			/* name */
    ImgBmapCreate,		/* createProc */
    ImgBmapGet,			/* getProc */
    ImgBmapDisplay,		/* displayProc */
    ImgBmapFree,		/* freeProc */
    ImgBmapDelete,		/* deleteProc */
    ImgBmapPostscript,		/* postscriptProc */
    NULL,			/* nextPtr */
    NULL
};

/*
 * Information used for parsing configuration specs:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_UID, "-background", NULL, NULL,
	"", offsetof(BitmapModel, bgUid), 0, NULL},
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	NULL, offsetof(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	NULL, offsetof(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-foreground", NULL, NULL,
	"#000000", offsetof(BitmapModel, fgUid), 0, NULL},
    {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
	NULL, offsetof(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
	NULL, offsetof(BitmapModel, maskFileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * 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
typedef struct ParseInfo {
    const 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. */
    char word[MAX_WORD_LENGTH+1];
				/* Current word of bitmap data, NULL
				 * terminated. */
    int wordLength;		/* Number of non-NULL bytes in word. */
} ParseInfo;

/*
 * Prototypes for procedures used only locally in this file:
 */

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		ImgBmapConfigureModel(BitmapModel *modelPtr,
			    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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */


static int
ImgBmapCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const 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). */
    const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* 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. */
{
    BitmapModel *modelPtr = (BitmapModel *)ckalloc(sizeof(BitmapModel));
    (void)typePtr;


    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd,
	    modelPtr, ImgBmapCmdDeletedProc);
    modelPtr->width = modelPtr->height = 0;
    modelPtr->data = NULL;
    modelPtr->maskData = NULL;
    modelPtr->fgUid = NULL;
    modelPtr->bgUid = NULL;
    modelPtr->fileString = NULL;
    modelPtr->dataString = NULL;
    modelPtr->maskFileString = NULL;
    modelPtr->maskDataString = NULL;
    modelPtr->instancePtr = NULL;
    if (ImgBmapConfigureModel(modelPtr, argc, argv, 0) != TCL_OK) {
	ImgBmapDelete(modelPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapConfigureModel --
 *
 *	This procedure is called when a bitmap image is created or
 *	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 modelPtr->interp's result.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapConfigureModel(
    BitmapModel *modelPtr,	/* 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. */
{
    BitmapInstance *instancePtr;
    int maskWidth, maskHeight, dummy1, dummy2;
    const char **argv = (const char **)ckalloc((objc+1) * sizeof(char *));


    for (dummy1 = 0; dummy1 < objc; dummy1++) {
	argv[dummy1] = Tcl_GetString(objv[dummy1]);
    }
    argv[objc] = NULL;

    if (Tk_ConfigureWidget(modelPtr->interp, Tk_MainWindow(modelPtr->interp),
	    configSpecs, objc, argv, (char *) modelPtr, flags) != TCL_OK) {

	ckfree(argv);
	return TCL_ERROR;
    }
    ckfree(argv);

    /*
     * Parse the bitmap and/or mask to create binary data. Make sure that the
     * bitmap and mask have the same dimensions.
     */

    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
	modelPtr->data = NULL;
    }
    if ((modelPtr->fileString != NULL) || (modelPtr->dataString != NULL)) {
	modelPtr->data = TkGetBitmapData(modelPtr->interp,
		modelPtr->dataString, modelPtr->fileString,
		&modelPtr->width, &modelPtr->height, &dummy1, &dummy2);
	if (modelPtr->data == NULL) {
	    return TCL_ERROR;
	}
    }
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
	modelPtr->maskData = NULL;
    }
    if ((modelPtr->maskFileString != NULL)
	    || (modelPtr->maskDataString != NULL)) {
	if (modelPtr->data == NULL) {
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "can't have mask without bitmap", -1));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "NO_BITMAP", NULL);

	    return TCL_ERROR;
	}
	modelPtr->maskData = TkGetBitmapData(modelPtr->interp,
		modelPtr->maskDataString, modelPtr->maskFileString,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (modelPtr->maskData == NULL) {
	    return TCL_ERROR;
	}
	if ((maskWidth != modelPtr->width)
		|| (maskHeight != modelPtr->height)) {
	    ckfree(modelPtr->maskData);
	    modelPtr->maskData = NULL;
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "bitmap and mask have different sizes", -1));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "MASK_SIZE", NULL);
	    return TCL_ERROR;
	}
    }

    /*
     * 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 = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	ImgBmapConfigureInstance(instancePtr);
    }
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapConfigureInstance --
 *
 *	This procedure is called to create displaying information for a bitmap
 *	image instance based on the configuration information in the model.
 *	It is invoked both when new instances are created and when the model
 *	is reconfigured.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates errors via Tcl_BackgroundException if there are problems in
 *	setting up the instance.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapConfigureInstance(
    BitmapInstance *instancePtr)/* Instance to reconfigure. */
{
    BitmapModel *modelPtr = instancePtr->modelPtr;
    XColor *colorPtr;
    XGCValues gcValues;
    GC gc;
    unsigned int mask;
    Pixmap oldBitmap, oldMask;

    /*
     * For each of the options in modelPtr, translate the string form into an
     * internal form appropriate for instancePtr.
     */

    if (*modelPtr->bgUid != 0) {
	colorPtr = Tk_GetColor(modelPtr->interp, instancePtr->tkwin,
		modelPtr->bgUid);
	if (colorPtr == NULL) {
	    goto error;
	}
    } else {
	colorPtr = NULL;
    }
    if (instancePtr->bg != NULL) {
	Tk_FreeColor(instancePtr->bg);
    }
    instancePtr->bg = colorPtr;

    colorPtr = Tk_GetColor(modelPtr->interp, instancePtr->tkwin,
	    modelPtr->fgUid);
    if (colorPtr == NULL) {
	goto error;
    }
    if (instancePtr->fg != NULL) {
	Tk_FreeColor(instancePtr->fg);
    }
    instancePtr->fg = colorPtr;

    /*
     * Careful: We have to allocate new Pixmaps before deleting the old ones.
     * Otherwise, The XID allocator will always return the same XID for the
     * new Pixmaps as was used for the old Pixmaps. And that will prevent the
     * data and/or mask from changing in the GC below.
     */

    oldBitmap = instancePtr->bitmap;
    instancePtr->bitmap = None;
    oldMask = instancePtr->mask;
    instancePtr->mask = None;

    if (modelPtr->data != NULL) {
	instancePtr->bitmap = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		modelPtr->data, (unsigned) modelPtr->width,
		(unsigned) modelPtr->height);
    }
    if (modelPtr->maskData != NULL) {
	instancePtr->mask = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		modelPtr->maskData, (unsigned) modelPtr->width,
		(unsigned) modelPtr->height);
    }

    if (oldMask != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldMask);
    }
    if (oldBitmap != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldBitmap);
    }

    if (modelPtr->data != NULL) {
	gcValues.foreground = instancePtr->fg->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground|GCGraphicsExposures;
	if (instancePtr->bg != NULL) {
	    gcValues.background = instancePtr->bg->pixel;
	    mask |= GCBackground;
	    if (instancePtr->mask != None) {







|
<






|

|

|

|

|

|

|
|










|















|


|
|


















>




|

|

|
|




<
|

>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|






|







|









|
|


|





<

>

|



|
|
>
|


|






|
|
|

|
|
|
|
|



|
|
|

|
|
|
<
|
<
<
>


|
|

|


|
|
|
|
|
|
<
<










|



|
|









|
|






|









|







|



|
|
|











|
|




















|



|
|

|



|
|









|







94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281


282
283
284
285
286
287
288
289
290
291
292
293
294
295
296


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
    "bitmap",			/* name */
    ImgBmapCreate,		/* createProc */
    ImgBmapGet,			/* getProc */
    ImgBmapDisplay,		/* displayProc */
    ImgBmapFree,		/* freeProc */
    ImgBmapDelete,		/* deleteProc */
    ImgBmapPostscript,		/* postscriptProc */
    NULL			/* nextPtr */

};

/*
 * Information used for parsing configuration specs:
 */

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_UID, "-background", NULL, NULL,
	"", Tk_Offset(BitmapMaster, bgUid), 0},
    {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", 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.
 */

#define MAX_WORD_LENGTH 100
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. */
    char word[MAX_WORD_LENGTH+1];
				/* Current word of bitmap data, NULL
				 * terminated. */
    int wordLength;		/* Number of non-NULL bytes in word. */
} ParseInfo;

/*
 * Prototypes for procedures used only locally in this file:
 */

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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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
				 * 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. */
{

    BitmapMaster *masterPtr;

    masterPtr = (BitmapMaster *) ckalloc(sizeof(BitmapMaster));
    masterPtr->tkMaster = master;
    masterPtr->interp = interp;
    masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd,
	    (ClientData) masterPtr, ImgBmapCmdDeletedProc);
    masterPtr->width = masterPtr->height = 0;
    masterPtr->data = NULL;
    masterPtr->maskData = NULL;
    masterPtr->fgUid = NULL;
    masterPtr->bgUid = NULL;
    masterPtr->fileString = NULL;
    masterPtr->dataString = NULL;
    masterPtr->maskFileString = NULL;
    masterPtr->maskDataString = NULL;
    masterPtr->instancePtr = NULL;
    if (ImgBmapConfigureMaster(masterPtr, argc, argv, 0) != TCL_OK) {
	ImgBmapDelete((ClientData) masterPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = (ClientData) masterPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapConfigureMaster --
 *
 *	This procedure is called when a bitmap image is created or
 *	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.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    BitmapInstance *instancePtr;
    int maskWidth, maskHeight, dummy1, dummy2;


    CONST char **argv = (CONST char **) ckalloc((objc+1) * sizeof(char *));
    for (dummy1 = 0; dummy1 < objc; dummy1++) {
	argv[dummy1]=Tcl_GetString(objv[dummy1]);
    }
    argv[objc] = NULL;

    if (Tk_ConfigureWidget(masterPtr->interp, Tk_MainWindow(masterPtr->interp),
	    configSpecs, objc, argv, (char *) masterPtr, flags)
	    != TCL_OK) {
	ckfree((char *) argv);
	return TCL_ERROR;
    }
    ckfree((char *) argv);

    /*
     * 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) {
	ckfree(masterPtr->data);
	masterPtr->data = NULL;
    }
    if ((masterPtr->fileString != NULL) || (masterPtr->dataString != NULL)) {
	masterPtr->data = TkGetBitmapData(masterPtr->interp,
		masterPtr->dataString, masterPtr->fileString,
		&masterPtr->width, &masterPtr->height, &dummy1, &dummy2);
	if (masterPtr->data == NULL) {
	    return TCL_ERROR;
	}
    }
    if (masterPtr->maskData != NULL) {
	ckfree(masterPtr->maskData);
	masterPtr->maskData = NULL;
    }
    if ((masterPtr->maskFileString != NULL)
	    || (masterPtr->maskDataString != NULL)) {
	if (masterPtr->data == NULL) {

	    Tcl_SetResult(masterPtr->interp, "can't have mask without bitmap",


		    TCL_STATIC);
	    return TCL_ERROR;
	}
	masterPtr->maskData = TkGetBitmapData(masterPtr->interp,
		masterPtr->maskDataString, masterPtr->maskFileString,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (masterPtr->maskData == NULL) {
	    return TCL_ERROR;
	}
	if ((maskWidth != masterPtr->width)
		|| (maskHeight != masterPtr->height)) {
	    ckfree(masterPtr->maskData);
	    masterPtr->maskData = NULL;
	    Tcl_SetResult(masterPtr->interp,
		    "bitmap and mask have different sizes", TCL_STATIC);


	    return TCL_ERROR;
	}
    }

    /*
     * 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;
	    instancePtr = instancePtr->nextPtr) {
	ImgBmapConfigureInstance(instancePtr);
    }
    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates errors via Tcl_BackgroundError if there are problems in
 *	setting up the instance.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapConfigureInstance(
    BitmapInstance *instancePtr)/* Instance to reconfigure. */
{
    BitmapMaster *masterPtr = instancePtr->masterPtr;
    XColor *colorPtr;
    XGCValues gcValues;
    GC gc;
    unsigned int mask;
    Pixmap oldBitmap, oldMask;

    /*
     * For each of the options in masterPtr, translate the string form into an
     * internal form appropriate for instancePtr.
     */

    if (*masterPtr->bgUid != 0) {
	colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
		masterPtr->bgUid);
	if (colorPtr == NULL) {
	    goto error;
	}
    } else {
	colorPtr = NULL;
    }
    if (instancePtr->bg != NULL) {
	Tk_FreeColor(instancePtr->bg);
    }
    instancePtr->bg = colorPtr;

    colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
	    masterPtr->fgUid);
    if (colorPtr == NULL) {
	goto error;
    }
    if (instancePtr->fg != NULL) {
	Tk_FreeColor(instancePtr->fg);
    }
    instancePtr->fg = colorPtr;

    /*
     * Careful: We have to allocate new Pixmaps before deleting the old ones.
     * Otherwise, The XID allocator will always return the same XID for the
     * new Pixmaps as was used for the old Pixmaps. And that will prevent the
     * data and/or mask from changing in the GC below.
     */

    oldBitmap = instancePtr->bitmap;
    instancePtr->bitmap = None;
    oldMask = instancePtr->mask;
    instancePtr->mask = None;

    if (masterPtr->data != NULL) {
	instancePtr->bitmap = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->data, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
    }
    if (masterPtr->maskData != NULL) {
	instancePtr->mask = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->maskData, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
    }

    if (oldMask != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldMask);
    }
    if (oldBitmap != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldBitmap);
    }

    if (masterPtr->data != NULL) {
	gcValues.foreground = instancePtr->fg->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground|GCGraphicsExposures;
	if (instancePtr->bg != NULL) {
	    gcValues.background = instancePtr->bg->pixel;
	    mask |= GCBackground;
	    if (instancePtr->mask != None) {
441
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
     * it clear that this instance cannot be displayed. Then report the error.
     */

    if (instancePtr->gc != NULL) {
	Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
    }
    instancePtr->gc = NULL;
    Tcl_AppendObjToErrorInfo(modelPtr->interp, Tcl_ObjPrintf(
	    "\n    (while configuring image \"%s\")", Tk_NameOfImage(
	    modelPtr->tkModel)));

    Tcl_BackgroundException(modelPtr->interp, TCL_ERROR);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapData --
 *







<
|
|
>
|







438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
     * it clear that this instance cannot be displayed. Then report the error.
     */

    if (instancePtr->gc != NULL) {
	Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
    }
    instancePtr->gc = NULL;

    Tcl_AddErrorInfo(masterPtr->interp, "\n    (while configuring image \"");
    Tcl_AddErrorInfo(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
    Tcl_AddErrorInfo(masterPtr->interp, "\")");
    Tcl_BackgroundError(masterPtr->interp);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapData --
 *
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
 *
 *----------------------------------------------------------------------
 */

char *
TkGetBitmapData(
    Tcl_Interp *interp,		/* For reporting errors, or NULL. */
    const char *string,		/* String describing bitmap. May be NULL. */
    const 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;
    char *p, *end;
    ParseInfo pi;
    char *data = NULL;
    Tcl_DString buffer;

    pi.string = string;
    if (string == NULL) {
	if ((interp != NULL) && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get bitmap data from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (expandedFileName == NULL) {
	    return NULL;
	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {
	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't read bitmap file \"%s\": %s",
			fileName, Tcl_PosixError(interp)));
	    }
	    return NULL;
	}

	if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
		!= TCL_OK) {
	    return NULL;







|
|







|








<
|
<
|











<
|
|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

494

495
496
497
498
499
500
501
502
503
504
505
506

507
508
509
510
511
512
513
514
515
 *
 *----------------------------------------------------------------------
 */

char *
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;
    char *p, *end;
    ParseInfo pi;
    char *data = NULL;
    Tcl_DString buffer;

    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", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (expandedFileName == NULL) {
	    return NULL;
	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {
	    if (interp != NULL) {
		Tcl_ResetResult(interp);

		Tcl_AppendResult(interp, "couldn't read bitmap file \"",
			fileName, "\": ", Tcl_PosixError(interp), NULL);
	    }
	    return NULL;
	}

	if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
		!= TCL_OK) {
	    return NULL;
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
		}
		if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
		    goto getData;
		}
	    }
	} else if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"format error in bitmap data; looks like it's an"
			" obsolete X10 bitmap file", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "OBSOLETE",
			NULL);
	    }
	    goto errorCleanup;
	}
    }

    /*
     * Now we've read everything but the data. Allocate an array and read in
     * the data.
     */

  getData:
    if ((width <= 0) || (height <= 0)) {
	goto error;
    }
    numBytes = ((width+7)/8) * height;
    data = (char *)ckalloc(numBytes);
    for (p = data; numBytes > 0; p++, numBytes--) {
	if (NextBitmapWord(&pi) != TCL_OK) {
	    goto error;
	}
	*p = (char) strtol(pi.word, &end, 0);
	if (end == pi.word) {
	    goto error;







<
|
|
<
<















|







590
591
592
593
594
595
596

597
598


599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
		}
		if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
		    goto getData;
		}
	    }
	} 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", NULL);


	    }
	    goto errorCleanup;
	}
    }

    /*
     * Now we've read everything but the data. Allocate an array and read in
     * the data.
     */

  getData:
    if ((width <= 0) || (height <= 0)) {
	goto error;
    }
    numBytes = ((width+7)/8) * height;
    data = (char *) ckalloc((unsigned) numBytes);
    for (p = data; numBytes > 0; p++, numBytes--) {
	if (NextBitmapWord(&pi) != TCL_OK) {
	    goto error;
	}
	*p = (char) strtol(pi.word, &end, 0);
	if (end == pi.word) {
	    goto error;
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
    *heightPtr = height;
    *hotXPtr = hotX;
    *hotYPtr = hotY;
    return data;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"format error in bitmap data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "FORMAT", NULL);
    }

  errorCleanup:
    if (data != NULL) {
	ckfree(data);
    }
    if (pi.chan != NULL) {







<
|
<







633
634
635
636
637
638
639

640

641
642
643
644
645
646
647
    *heightPtr = height;
    *hotXPtr = hotX;
    *hotYPtr = hotY;
    return data;

  error:
    if (interp != NULL) {

	Tcl_SetResult(interp, "format error in bitmap data", TCL_STATIC);

    }

  errorCleanup:
    if (data != NULL) {
	ckfree(data);
    }
    if (pi.chan != NULL) {
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
 */

static int
NextBitmapWord(
    ParseInfo *parseInfoPtr)	/* Describes what we're reading and where we
				 * are in it. */
{
    const char *src;
    char *dst;
    int c;

    parseInfoPtr->wordLength = 0;
    dst = parseInfoPtr->word;
    if (parseInfoPtr->string != NULL) {
	for (src = parseInfoPtr->string; isspace(UCHAR(*src)) || (*src == ',');
		src++) {







<
|







670
671
672
673
674
675
676

677
678
679
680
681
682
683
684
 */

static int
NextBitmapWord(
    ParseInfo *parseInfoPtr)	/* Describes what we're reading and where we
				 * are in it. */
{

    char *src, *dst;
    int c;

    parseInfoPtr->wordLength = 0;
    dst = parseInfoPtr->word;
    if (parseInfoPtr->string != NULL) {
	for (src = parseInfoPtr->string; isspace(UCHAR(*src)) || (*src == ',');
		src++) {
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ImgBmapCmd(
    ClientData clientData,	/* Information about the image model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bmapOptions[] = {"cget", "configure", NULL};
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], bmapOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch (index) {
    case 0: /* cget */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		(char *) modelPtr, Tcl_GetString(objv[2]), 0);
    case 1: /* configure */
	if (objc == 2) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr,
		    Tcl_GetString(objv[2]), 0);
	} else {
	    return ImgBmapConfigureModel(modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
    default:
	Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");
	return TCL_OK;
    }
}







|


|

|
|



|


|
|









|



|


|


|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
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", NULL};
    BitmapMaster *masterPtr = (BitmapMaster *) clientData;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], bmapOptions, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch (index) {
    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: /* configure */
	if (objc == 2) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) masterPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) masterPtr,
		    Tcl_GetString(objv[2]), 0);
	} else {
	    return ImgBmapConfigureMaster(masterPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
    default:
	Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");
	return TCL_OK;
    }
}
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
 *----------------------------------------------------------------------
 */

static ClientData
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;
    BitmapInstance *instancePtr;

    /*
     * See if there is already an instance for this window. If so then just
     * re-use it.
     */

    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if (instancePtr->tkwin == tkwin) {
	    instancePtr->refCount++;
	    return instancePtr;
	}
    }

    /*
     * The image isn't already in use in this window. Make a new instance of
     * the image.
     */

    instancePtr = (BitmapInstance *)ckalloc(sizeof(BitmapInstance));
    instancePtr->refCount = 1;
    instancePtr->modelPtr = modelPtr;
    instancePtr->tkwin = tkwin;
    instancePtr->fg = NULL;
    instancePtr->bg = NULL;
    instancePtr->bitmap = None;
    instancePtr->mask = None;
    instancePtr->gc = NULL;
    instancePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = instancePtr;
    ImgBmapConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }

    return instancePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapDisplay --
 *







|


|







|



|








|

|






|
|







|
|


|







800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
 *----------------------------------------------------------------------
 */

static ClientData
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    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.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if (instancePtr->tkwin == tkwin) {
	    instancePtr->refCount++;
	    return (ClientData) instancePtr;
	}
    }

    /*
     * The image isn't already in use in this window. Make a new instance of
     * the image.
     */

    instancePtr = (BitmapInstance *) ckalloc(sizeof(BitmapInstance));
    instancePtr->refCount = 1;
    instancePtr->masterPtr = masterPtr;
    instancePtr->tkwin = tkwin;
    instancePtr->fg = NULL;
    instancePtr->bg = NULL;
    instancePtr->bitmap = None;
    instancePtr->mask = None;
    instancePtr->gc = NULL;
    instancePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = instancePtr;
    ImgBmapConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width,
		masterPtr->height);
    }

    return (ClientData) instancePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapDisplay --
 *
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
    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.
     */








|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
    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.
     */

944
945
946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961

static void
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;


    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Free the
     * instance structure.
     */







|


>
|







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950

static void
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;

    instancePtr->refCount--;
    if (instancePtr->refCount > 0) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Free the
     * instance structure.
     */
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
    }
    if (instancePtr->mask != None) {
	Tk_FreePixmap(display, instancePtr->mask);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(display, instancePtr->gc);
    }
    if (instancePtr->modelPtr->instancePtr == instancePtr) {
	instancePtr->modelPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->modelPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    ckfree(instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapDelete --
 *
 *	This procedure is called by the image code to delete the model
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    ClientData modelData)	/* Pointer to BitmapModel structure for
				 * image. Must not have any more instances. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;

    if (modelPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
    }
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, (char *) modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCmdDeletedProc --
 *







|
|

|





|







|













|


|

|


|
|
|

|
|

|
|

|
|







960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
    }
    if (instancePtr->mask != None) {
	Tk_FreePixmap(display, instancePtr->mask);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(display, instancePtr->gc);
    }
    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->masterPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    ckfree((char *) instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapDelete --
 *
 *	This procedure is called by the image code to delete the master
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    ClientData masterData)	/* Pointer to BitmapMaster structure for
				 * image. Must not have any more instances. */
{
    BitmapMaster *masterPtr = (BitmapMaster *) masterData;

    if (masterPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    masterPtr->tkMaster = NULL;
    if (masterPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(masterPtr->interp, masterPtr->imageCmd);
    }
    if (masterPtr->data != NULL) {
	ckfree(masterPtr->data);
    }
    if (masterPtr->maskData != NULL) {
	ckfree(masterPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree((char *) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCmdDeletedProc --
 *
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    ClientData clientData)	/* Pointer to BitmapModel structure for
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetByte --







|


|

|
|
|







1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    ClientData clientData)	/* Pointer to BitmapMaster structure for
				 * image. */
{
    BitmapMaster *masterPtr = (BitmapMaster *) clientData;

    masterPtr->imageCmd = NULL;
    if (masterPtr->tkMaster != NULL) {
	Tk_DeleteImage(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetByte --
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;
    size_t size;

    size = Tcl_Read(chan, &buffer, 1);
    if (size != 1) {
	return EOF;
    } else {
	return buffer;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPsImagemask --
 *
 *	This procedure generates postscript suitable for rendering a single







|


|





>







1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;
    int size;

    size = Tcl_Read(chan, &buffer, 1);
    if (size <= 0) {
	return EOF;
    } else {
	return buffer;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPsImagemask --
 *
 *	This procedure generates postscript suitable for rendering a single
1106
1107
1108
1109
1110
1111
1112




1113
1114


1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133
1134
1135
 *
 *	   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.
 *




 * Results:
 *	None.


 *
 * Side effects:
 *	Postscript code is appended to psObj.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapPsImagemask(
    Tcl_Obj *psObj,		/* Append postscript to this buffer. */
    int width, int height,	/* Width and height of the bitmap in pixels */
    char *data)			/* Data for the bitmap. */
{
    int i, j, nBytePerRow;


    /*
     * 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
     * within a byte so that the bits will be in the order postscript expects.







>
>
>
>

<
>
>


|




|

|

|


>







1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
 *
 *	   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.
 *
 *	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
 *	message in interp->result if there is a problem.
 *
 * Side effects:
 *	Postscript code is appended to interp->result.
 *
 *----------------------------------------------------------------------
 */

static int
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
     * within a byte so that the bits will be in the order postscript expects.
1150
1151
1152
1153
1154
1155
1156






1157
1158
1159

1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
      13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
       3, 131, 67, 195, 35, 163,  99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
      11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
       7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
      15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255,
    };







    Tcl_AppendPrintfToObj(psObj,
	    "0 0 moveto %d %d true [%d 0 0 %d 0 %d] {<\n",
	    width, height, width, -height, height);


    nBytePerRow = (width + 7) / 8;
    for (i=0; i<height; i++) {
	for (j=0; j<nBytePerRow; j++) {
	    Tcl_AppendPrintfToObj(psObj, " %02x",
		    bit_reverse[0xff & data[i*nBytePerRow + j]]);

	}
	Tcl_AppendToObj(psObj, "\n", -1);
    }

    Tcl_AppendToObj(psObj, ">} imagemask \n", -1);

}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPostscript --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapPostscript(
    ClientData clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,
    int x, int y, int width, int height,
    int prepass)
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    Tcl_InterpState interpState;
    Tcl_Obj *psObj;

    if (prepass) {
	return TCL_OK;
    }

    /*
     * There is nothing to do for bitmaps with zero width or height.
     */

    if (width<=0 || height<=0 || modelPtr->width<=0 || modelPtr->height<=0){
	return TCL_OK;
    }

    /*
     * Some postscript implementations cannot handle bitmap strings longer
     * than about 60k characters. If the bitmap data is that big or bigger,
     * we bail out.
     */

    if (modelPtr->width*modelPtr->height > 60000) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unable to generate postscript for bitmaps larger than 60000"
		" pixels", -1));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	return TCL_ERROR;
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, 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.
     */

    if (x != 0 || y != 0) {
	Tcl_AppendPrintfToObj(psObj, "%d %d moveto\n", x, y);

    }
    if (width != 1 || height != 1) {
	Tcl_AppendPrintfToObj(psObj, "%d %d scale\n", width, height);

    }

    /*
     * 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
     * color to the bits specified by the mask.
     */

    if ((modelPtr->bgUid != NULL) && (modelPtr->bgUid[0] != '\000')) {
	XColor color;

	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), modelPtr->bgUid,
		&color);
	Tcl_ResetResult(interp);
	if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
	    goto error;

	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (modelPtr->maskData == NULL) {
	    Tcl_AppendToObj(psObj,
		    "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto "
		    "closepath fill\n", -1);
	} else {
	    ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		    modelPtr->maskData);

	}
    }

    /*
     * Draw the bitmap foreground, assuming there is one.
     */

    if ((modelPtr->fgUid != NULL) && (modelPtr->data != NULL)) {
	XColor color;

	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), modelPtr->fgUid,
		&color);
	Tcl_ResetResult(interp);
	if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
	    goto error;

	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		modelPtr->data);
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
>
>
>
|
|

>

|
|
|
|

>

|


|
>










>



















|
|
<









|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|
|
>

|
|
>










|


|

<

<
>

<
<
|
|
|
|
<
|
|
>







|


|

<

<
>

<
|
<
|
<
|
<
<
<
|
<
<
<
<
|
<
<
<
|









1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220





















1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251

1252

1253
1254


1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273

1274

1275
1276

1277

1278

1279



1280




1281



1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
      13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
       3, 131, 67, 195, 35, 163,  99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
      11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
       7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
      15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255,
    };

    if (width*height > 60000) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "unable to generate postscript for bitmaps "
		"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);
    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);
    }

    Tcl_AppendResult(interp, ">} imagemask \n", NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPostscript --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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];


    if (prepass) {
	return TCL_OK;
    }

    /*
     * There is nothing to do for bitmaps with zero width or height.
     */

    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.
     */

    if (x!=0 || y!=0) {
	sprintf(buffer, "%d %d moveto\n", x, y);
	Tcl_AppendResult(interp, buffer, NULL);
    }
    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
     * there is no background mask, then color the complete rectangle that
     * 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) {

	    return TCL_ERROR;
	}


	if (masterPtr->maskData == NULL) {
	    Tcl_AppendResult(interp,
		    "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) {
	    return TCL_ERROR;
	}
    }

    /*
     * Draw the bitmap foreground, assuming there is one.
     */

    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) {

	    return TCL_ERROR;
	}

	if (ImgBmapPsImagemask(interp, masterPtr->width, masterPtr->height,

		masterPtr->data) != TCL_OK) {

	    return TCL_ERROR;



	}




    }



    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkImgGIF.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30



31
32
33
34
35
36
37
/*
 * 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.
 *
 * 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-2010 Donal K. Fellows
 *
 * 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:
 *
 * +--------------------------------------------------------------------+
 * | Copyright 1990, David Koblas.					|
 * |   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" without express or implied warranty.		|
 * +--------------------------------------------------------------------+



 */

#include "tkInt.h"

/*
 * 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, +













|
















>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
 * 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.
 *
 * 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.
 *
 * This file also contains code from the giftoppm program, which is
 * copyrighted as follows:
 *
 * +--------------------------------------------------------------------+
 * | Copyright 1990, David Koblas.					|
 * |   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" 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 either binary or base64 format. base64
 * strings consist of 4 6-bit characters -> 3 8 bit bytes. A-Z, a-z, 0-9, +
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    int c;			/* bits left over from previous character */
    int state;			/* decoder state (0-4 or GIF_DONE) */
    size_t length;			/* Total amount of bytes in data */
} MFile;

/*
 * 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
 * accommodate these systems, we test against the numeric value of the ASCII
 * characters instead of the characters themselves. This is encoding
 * independent.
 */

static const char GIF87a[] = {			/* ASCII GIF87a */
    0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x00
};
static const char GIF89a[] = {			/* ASCII GIF89a */
    0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x00







|







|

|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    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;

/*
 * 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.
 */

static const char GIF87a[] = {			/* ASCII GIF87a */
    0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x00
};
static const char GIF89a[] = {			/* ASCII GIF89a */
    0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x00
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
	int done;
	unsigned int window;
	int bitsInWindow;
	unsigned char *c;
    } reader;
} GIFImageConfig;

/*
 * Type of a function used to do the writing to a file or buffer when
 * serializing in the GIF format.
 */

typedef size_t (WriteBytesFunc) (ClientData clientData, const char *bytes,
			    size_t byteCount);

/*
 * The format record for the GIF file format:
 */

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		StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format,
			    Tk_PhotoImageBlock *blockPtr);
static int		CommonWriteGIF(Tcl_Interp *interp, ClientData clientData,
			    WriteBytesFunc *writeProc, Tcl_Obj *format,
			    Tk_PhotoImageBlock *blockPtr);

Tk_PhotoImageFormat tkImgFmtGIF = {
    "gif",		/* name */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
    FileReadGIF,	/* fileReadProc */
    StringReadGIF,	/* stringReadProc */
    FileWriteGIF,	/* fileWriteProc */
    StringWriteGIF,	/* stringWriteProc */
    NULL
};

#define INTERLACE		0x40
#define LOCALCOLORMAP		0x80
#define BitSet(byte, bit)	(((byte) & (bit)) == (bit))
#define MAXCOLORMAPSIZE		256
#define CM_RED			0







<
<
<
<
<
<
<
<



















<
<
|
<
|








|
<







105
106
107
108
109
110
111








112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130


131

132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
	int done;
	unsigned int window;
	int bitsInWindow;
	unsigned char *c;
    } reader;
} GIFImageConfig;









/*
 * The format record for the GIF file format:
 */

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 */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
    FileReadGIF,	/* fileReadProc */
    StringReadGIF,	/* stringReadProc */
    FileWriteGIF,	/* fileWriteProc */
    NULL,		/* stringWriteProc */

};

#define INTERLACE		0x40
#define LOCALCOLORMAP		0x80
#define BitSet(byte, bit)	(((byte) & (bit)) == (bit))
#define MAXCOLORMAPSIZE		256
#define CM_RED			0
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
			    unsigned char cmap[MAXCOLORMAPSIZE][4], int srcX,
			    int srcY, int interlace, int transparent);

/*
 * these are for the BASE64 image reader code only
 */

static size_t		Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
			    size_t size, size_t count, Tcl_Channel chan);
static size_t		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,
			    size_t length);

/*
 * Types, defines and variables needed to write and compress a GIF.
 */

#define LSB(a)		((unsigned char) (((short)(a)) & 0x00FF))
#define MSB(a)		((unsigned char) (((short)(a)) >> 8))

#define GIFBITS		12
#define HSIZE		5003	/* 80% occupancy */

#define DEFAULT_BACKGROUND_VALUE	0xD9

typedef struct {
    int ssize;
    int csize;
    int rsize;
    unsigned char *pixelOffset;
    int pixelSize;
    int pixelPitch;
    int greenOffset;
    int blueOffset;
    int alphaOffset;
    int num;
    unsigned char mapa[MAXCOLORMAPSIZE][3];
} GifWriterState;

typedef int (* ifunptr) (GifWriterState *statePtr);

/*
 * Support for compression of GIFs.
 */

#define MAXCODE(numBits)	(((long) 1 << (numBits)) - 1)

#ifdef SIGNED_COMPARE_SLOW
#define U(x)	((unsigned) (x))
#else
#define U(x)	(x)
#endif

typedef struct {
    int numBits;		/* Number of bits/code. */
    long maxCode;		/* Maximum code, given numBits. */
    int hashTable[HSIZE];
    unsigned int codeTable[HSIZE];
    long hSize;			/* For dynamic table sizing. */

    /*
     * To save much memory, we overlay the table used by compress() with those
     * used by decompress(). The tab_prefix table is the same size and type as
     * the codeTable. The tab_suffix table needs 2**GIFBITS characters. We get
     * this from the beginning of hashTable. The output stack uses the rest of
     * hashTable, and contains characters. There is plenty of room for any
     * possible stack (stack used to be 8000 characters).
     */

    int freeEntry;		/* First unused entry. */

    /*
     * Block compression parameters.  After all codes are used up, and
     * compression rate changes, start over.
     */

    int clearFlag;

    int offset;
    unsigned int inCount;	/* Length of input */
    unsigned int outCount;	/* # of codes output (for debugging) */

    /*
     * Algorithm: use open addressing double hashing (no chaining) on the
     * prefix code / next character combination. We do a variant of Knuth's
     * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
     * secondary probe. Here, the modular division first probe is gives way to
     * a faster exclusive-or manipulation. Also do block compression with an
     * adaptive reset, whereby the code table is cleared when the compression
     * ratio decreases, but after the table fills. The variable-length output
     * codes are re-sized at this point, and a special CLEAR code is generated
     * for the decompressor. Late addition: construct the table according to
     * file size for noticeable speed improvement on small files. Please
     * direct questions about this implementation to ames!jaw.
     */

    int initialBits;
    ClientData destination;
    WriteBytesFunc *writeProc;

    int clearCode;
    int eofCode;

    unsigned long currentAccumulated;
    int currentBits;

    /*
     * Number of characters so far in this 'packet'
     */

    int accumulatedByteCount;

    /*
     * Define the storage for the packet accumulator
     */

    unsigned char packetAccumulator[256];
} GIFState_t;

/*
 * Definition of new functions to write GIFs
 */

static int		ColorNumber(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		Compress(int initBits, ClientData handle,
			    WriteBytesFunc *writeProc, ifunptr readValue,
			    GifWriterState *statePtr);
static int		IsNewColor(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		SaveMap(GifWriterState *statePtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		ReadValue(GifWriterState *statePtr);
static WriteBytesFunc	WriteToChannel;
static WriteBytesFunc	WriteToByteArray;
static void		Output(GIFState_t *statePtr, long code);
static void		ClearForBlock(GIFState_t *statePtr);
static void		ClearHashTable(GIFState_t *statePtr, int hSize);
static void		CharInit(GIFState_t *statePtr);
static void		CharOut(GIFState_t *statePtr, int c);
static void		FlushChar(GIFState_t *statePtr);

/*
 *----------------------------------------------------------------------
 *
 * FileMatchGIF --
 *
 *	This function is invoked by the photo image type to see if a file







|

|




|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

































































































































189
190
191
192
193
194
195
			    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(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 function is invoked by the photo image type to see if a file
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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 *dummy)		/* not used */
{
    GIFImageConfig gifConf;
    (void)fileName;
    (void)format;
    (void)dummy;

    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------







|


<
<
<







209
210
211
212
213
214
215
216
217
218



219
220
221
222
223
224
225
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 */
{
    GIFImageConfig gifConf;




    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
				 * 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;
    unsigned int nBytes;
    int index = 0, argc = 0, i, result = TCL_ERROR;
    Tcl_Obj **objv;
    unsigned char buf[100];
    unsigned char *trashBuffer = NULL;
    int bitPixel;
    unsigned char colorMap[MAXCOLORMAPSIZE][4];
    int transparent = -1;
    static const char *const 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(colorMap, 0, MAXCOLORMAPSIZE*4);
    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++) {
	int optionIdx;
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *), "option name", 0, &optionIdx) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i == (argc-1)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no value given for \"%s\" option",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "OPT_VALUE", NULL);
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * Read the GIF file header and check for some sanity.
     */

    if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read GIF header from file \"%s\"", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "HEADER", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"GIF image file \"%s\" has dimension(s) <= 0", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BOGUS_SIZE", NULL);
	return TCL_ERROR;
    }

    /*
     * Get the general colormap information.
     */

    if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {
	return TCL_OK;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
    }







<
|






|









<















<
|
|



<
|
|
<












<
|
|



|
|
<














<
|
<







251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294

295
296

297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329

330

331
332
333
334
335
336
337
				 * 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, result = TCL_ERROR;
    Tcl_Obj **objv;
    unsigned char buf[100];
    unsigned char *trashBuffer = NULL;
    int bitPixel;
    unsigned char colorMap[MAXCOLORMAPSIZE][4];
    int transparent = -1;
    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) {
	    return TCL_ERROR;
	}
	if (i == (argc-1)) {

	    Tcl_AppendResult(interp, "no value given for \"",
		    Tcl_GetString(objv[i]), "\" option", NULL);

	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * 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", NULL);

	return TCL_ERROR;
    }

    /*
     * Get the general colormap information.
     */

    if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {
	return TCL_OK;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {

	    Tcl_AppendResult(interp, "error reading color map", NULL);

	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
    }
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

    while (1) {
	if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
	    /*
	     * Premature end of image.
	     */

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "premature end of image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END",
		    NULL);
	    goto error;
	}

	switch (buf[0]) {
	case GIF_TERMINATOR:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA", NULL);
	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension function code in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, buf[0],
		    gifConfPtr->workingBuffer, &transparent) < 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't read left/top/width/height in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "DIMENSIONS",
			NULL);
		goto error;
	    }
	    break;
	default:
	    /*
	     * Not a valid start character; ignore it.
	     */







|
|
<
<





<
|
<








|

|
<
<




<
|
<
|





|

|
<
<







359
360
361
362
363
364
365
366
367


368
369
370
371
372

373

374
375
376
377
378
379
380
381
382
383
384


385
386
387
388

389

390
391
392
393
394
395
396
397
398


399
400
401
402
403
404
405

    while (1) {
	if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
	    /*
	     * Premature end of image.
	     */

	    Tcl_AppendResult(interp,
		    "premature end of image data for this index", NULL);


	    goto error;
	}

	switch (buf[0]) {
	case GIF_TERMINATOR:

	    Tcl_AppendResult(interp, "no image data for this index", NULL);

	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    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(gifConfPtr, chan, buf[0],
		    gifConfPtr->workingBuffer, &transparent) < 0) {

		Tcl_SetResult(interp, "error reading extension in GIF image",

			TCL_STATIC);
		goto error;
	    }
	    continue;
	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.
	     */
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
	if (index--) {
	    /*
	     * This is not the GIF frame we want to read: skip it.
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "error reading color map", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF",
			    "COLOR_MAP", NULL);
		    goto error;
		}
	    }

	    /*
	     * If we've not yet allocated a trash buffer, do so now.
	     */

	    if (trashBuffer == NULL) {
		if (fileWidth > (int)((UINT_MAX/3)/fileHeight)) {
		    goto error;
		}
		nBytes = fileWidth * fileHeight * 3;
		trashBuffer = (unsigned char *)ckalloc(nBytes);
		if (trashBuffer) {
		    memset(trashBuffer, 0, nBytes);
		}
	    }

	    /*
	     * 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







<
|
<
<









<
<
<

|
<
<
<







419
420
421
422
423
424
425

426


427
428
429
430
431
432
433
434
435



436
437



438
439
440
441
442
443
444
	if (index--) {
	    /*
	     * This is not the GIF frame we want to read: skip it.
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {

		    Tcl_AppendResult(interp, "error reading color map", NULL);


		    goto error;
		}
	    }

	    /*
	     * If we've not yet allocated a trash buffer, do so now.
	     */

	    if (trashBuffer == NULL) {



		nBytes = fileWidth * fileHeight * 3;
		trashBuffer = (unsigned char *) ckalloc((unsigned) nBytes);



	    }

	    /*
	     * 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
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
    /*
     * Found the frame we want to read. Next, check for a local color map for
     * this frame.
     */

    if (BitSet(buf[8], LOCALCOLORMAP)) {
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    goto error;
	}
    }

    /*
     * Extract the location within the overall visible image to put the data
     * in this frame, together with the size of this frame.







<
|
<







466
467
468
469
470
471
472

473

474
475
476
477
478
479
480
    /*
     * Found the frame we want to read. Next, check for a local color map for
     * this frame.
     */

    if (BitSet(buf[8], LOCALCOLORMAP)) {
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {

	    Tcl_AppendResult(interp, "error reading color map", NULL);

	    goto error;
	}
    }

    /*
     * Extract the location within the overall visible image to put the data
     * in this frame, together with the size of this frame.
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
	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;
	if (imageWidth > INT_MAX/block.pixelSize) {
	    goto error;
	}
	block.pitch = block.pixelSize * imageWidth;
	if (imageHeight > (int)(UINT_MAX/block.pitch)) {
	    goto error;
	}
	nBytes = block.pitch * imageHeight;
	block.pixelPtr = (unsigned char *)ckalloc(nBytes);
	if (block.pixelPtr) {
	    memset(block.pixelPtr, 0, nBytes);
	}

	if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
		imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE),
		transparent) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}
	ckfree(block.pixelPtr);
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

    Tcl_SetObjResult(interp, Tcl_NewStringObj(tkImgFmtGIF.name, -1));
    result = TCL_OK;

  error:
    /*
     * If a trash buffer has been allocated, free it now.
     */

    if (trashBuffer != NULL) {
	ckfree(trashBuffer);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<

<
<
<

|
<
<
|
<

|

|




|


|







|








|







512
513
514
515
516
517
518



519



520
521


522

523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
	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(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
		imageHeight, colorMap, srcX, srcY, BitSet(buf[8],INTERLACE),
		transparent) != TCL_OK) {
	    ckfree((char *) block.pixelPtr);
	    goto error;
	}
	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);
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

    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);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

static int
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 *dummy)		/* not used */
{
    unsigned char *data, header[10];
    TkSizeT got, length;
    MFile handle;
    (void)format;
    (void)dummy;

    data = TkGetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;







|


|

<
<

|







573
574
575
576
577
578
579
580
581
582
583
584


585
586
587
588
589
590
591
592
593

static int
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;
    MFile handle;



    data = Tcl_GetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
    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)
{
    MFile handle, *hdlPtr = &handle;
    TkSizeT length;
    const char *xferFormat;
    unsigned char *data = TkGetByteArrayFromObj(dataObj, &length);

    mInit(data, hdlPtr, length);

    /*
     * 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







|

|







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    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)
{
    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 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
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	if (((size_t)Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) + 1) < 2) {
	    return 0;
	}

	if (buffer) {
	    buffer[i][CM_RED] = rgb[0];
	    buffer[i][CM_GREEN] = rgb[1];
	    buffer[i][CM_BLUE] = rgb[2];







|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	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];
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
    int label,
    unsigned char *buf,
    int *transparent)
{
    int count;

    switch (label) {
    case 0x01:			/* Plain Text Extension */
	break;

    case 0xff:			/* Application Extension */
	break;

    case 0xfe:			/* Comment Extension */
	do {
	    count = GetDataBlock(gifConfPtr, chan, buf);
	} while (count > 0);
	return count;

    case 0xf9:			/* Graphic Control Extension */
	count = GetDataBlock(gifConfPtr, chan, buf);
	if (count < 0) {
	    return 1;
	}
	if ((buf[0] & 0x1) != 0) {
	    *transparent = buf[3];
	}







|


|


|





|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
    int label,
    unsigned char *buf,
    int *transparent)
{
    int count;

    switch (label) {
    case 0x01:		/* Plain Text Extension */
	break;

    case 0xff:		/* Application Extension */
	break;

    case 0xfe:		/* Comment Extension */
	do {
	    count = GetDataBlock(gifConfPtr, chan, buf);
	} while (count > 0);
	return count;

    case 0xf9:		/* Graphic Control Extension */
	count = GetDataBlock(gifConfPtr, chan, buf);
	if (count < 0) {
	    return 1;
	}
	if ((buf[0] & 0x1) != 0) {
	    *transparent = buf[3];
	}
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (((size_t)Fread(gifConfPtr, &count, 1, 1, chan) + 1) < 2) {
	return -1;
    }

    if ((count != 0) && (((size_t)Fread(gifConfPtr, buf, count, 1, chan) + 1) < 2)) {
	return -1;
    }

    return count;
}

/*







|



|







802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) {
	return -1;
    }

    if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) {
	return -1;
    }

    return count;
}

/*
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,
    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i, count;
    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 *top;
    int codeSize, clearCode, inCode, endCode, oldCode, maxCode;
    int code, firstCode, v;
    (void)srcX;
    (void)srcY;

    /*
     * Initialize the decoder
     */

    if (((size_t)Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) + 1) < 2) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading GIF image: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    if (initialCodeSize > MAX_LWZ_BITS) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("malformed image", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED", NULL);
	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;
	cmap[transparent][CM_BLUE] = 0;







|
|





|


<
<





|
|
|




|
<







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869


870
871
872
873
874
875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,
    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i;
    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];
    register unsigned char *top;
    int codeSize, clearCode, inCode, endCode, oldCode, maxCode;
    int code, firstCode, v;



    /*
     * Initialize the decoder
     */

    if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) {
	Tcl_AppendResult(interp, "error reading GIF image: ",
		Tcl_PosixError(interp), NULL);
	return TCL_ERROR;
    }

    if (initialCodeSize > MAX_LWZ_BITS) {
	Tcl_SetResult(interp, "malformed image", TCL_STATIC);

	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;
	cmap[transparent][CM_BLUE] = 0;
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
		ypos = interlaceStart[pass];
	    }
	} else {
	    ypos++;
	}
	pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3);
    }

    /*
     * Now read until the final zero byte.
     * It was observed that there might be 1 length blocks
     * (test imgPhoto-14.1) which are not read.
     *
     * The field "stack" is abused for temporary buffer. it has 4096 bytes
     * and we need 256.
     *
     * Loop until we hit a 0 length block which is the end sign.
     */
    while ( 0 < (count = GetDataBlock(gifConfPtr, chan, stack)))
    {
	if (-1 == count ) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading GIF image: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCode --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1070
1071
1072
1073
1074
1075
1076



















1077
1078
1079
1080
1081
1082
1083
		ypos = interlaceStart[pass];
	    }
	} else {
	    ypos++;
	}
	pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3);
    }



















    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCode --
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
 *----------------------------------------------------------------------
 */

static void
mInit(
    unsigned char *string,	/* string containing initial mmencoded data */
    MFile *handle,		/* mmdecode "file" handle */
    size_t length)			/* Number of bytes in string */
{
    handle->data = string;
    handle->state = 0;
    handle->c = 0;
    handle->length = length;
}








|







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
 *----------------------------------------------------------------------
 */

static void
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->state = 0;
    handle->c = 0;
    handle->length = length;
}

1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static size_t
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 */
{
    int c;
    size_t i, count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}








|






|
|







1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static int
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++) {
	*dst++ = c;
    }
    return i;
}

1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
	if (handle->length-- <= 0) {
	    return GIF_DONE;
	}
	c = char64(*handle->data);
	handle->data++;
    } while (c == GIF_SPACE);

    if (c > GIF_SPECIAL) {
	handle->state = GIF_DONE;
	return handle->c;
    }

    switch (handle->state++) {
    case 0:
	handle->c = c<<2;







|







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
	if (handle->length-- <= 0) {
	    return GIF_DONE;
	}
	c = char64(*handle->data);
	handle->data++;
    } while (c == GIF_SPACE);

    if (c>GIF_SPECIAL) {
	handle->state = GIF_DONE;
	return handle->c;
    }

    switch (handle->state++) {
    case 0:
	handle->c = c<<2;
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633










































1634
1635
1636
1637
1638
1639
1640
 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static size_t
Fread(
    GIFImageConfig *gifConfPtr,
    unsigned char *dst,		/* where to put the result */
    size_t hunk, size_t count,	/* how many */
    Tcl_Channel chan)
{
    if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
	return Mread(dst, hunk, count, (MFile *) chan);
    }

    if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
	MFile *handle = (MFile *) chan;

	if ((handle->length + 1 < 2) || (handle->length < hunk*count)) {
	    return (size_t)-1;
	}
	memcpy(dst, handle->data, hunk * count);
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return hunk * count;
    }

    /*
     * Otherwise we've got a real file to read.
     */

    return Tcl_Read(chan, (char *) dst, 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
 *
 * Modified for transparency handling (gif89a)
 * by Jan Nijtmans <nijtmans@users.sourceforge.net>
 *
 *----------------------------------------------------------------------
 * FileWriteGIF-
 *
 *	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 the interp's result.
 *
 *----------------------------------------------------------------------
 */












































static int
FileWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    const char *filename,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)







|













|
|

|


|






|













|
|








|
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static int
Fread(
    GIFImageConfig *gifConfPtr,
    unsigned char *dst,		/* where to put the result */
    size_t hunk, size_t count,	/* how many */
    Tcl_Channel chan)
{
    if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
	return Mread(dst, hunk, count, (MFile *) chan);
    }

    if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
	MFile *handle = (MFile *) chan;

	if (handle->length <= 0 || (size_t) handle->length < hunk*count) {
	    return -1;
	}
	memcpy(dst, handle->data, (size_t) (hunk * count));
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return (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
 *
 * Modified for transparency handling (gif89a) and miGIF compression
 * by Jan Nijtmans <j.nijtmans@chello.nl>
 *
 *----------------------------------------------------------------------
 * FileWriteGIF-
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

/*
 * Types, defines and variables needed to write and compress a GIF.
 */

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
 */

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(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    const char *filename,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888

1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953


1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965


1966
1967
1968
1969
1970
1971
1972
1973

1974
1975
1976








1977
1978



1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990

1991
























1992




1993

1994




1995
1996
1997


1998
1999
2000
2001
2002

2003

2004

2005
2006
2007
2008
2009
2010



2011

2012



2013



2014
2015





2016
2017
2018
2019
2020
2021

2022
2023
2024
2025
2026
2027

2028



2029
2030
2031
2032
2033
2034
2035
2036
2037



2038

2039
2040
2041
2042



2043
2044
2045
2046




2047
2048
2049
2050
2051
2052
2053
2054
2055
2056

2057
2058
2059
2060

2061
2062
2063

2064
2065
2066
2067
2068
2069
2070
2071
2072

2073



2074
2075
2076

2077
2078
2079
2080
2081
2082
2083
2084
2085




2086
2087
2088





2089

2090
2091











2092
2093
2094
2095
2096
2097




2098

2099



2100



2101



2102






2103












2104
2105



2106
2107
2108
2109








2110


2111


2112
2113
2114
2115
2116
2117


2118
2119

2120

2121

2122

2123
2124


2125
2126
2127
2128
2129
2130
2131




2132

2133
2134
2135
2136








2137

2138
2139


2140
2141


2142


2143
2144



2145
2146



2147
2148
2149
2150
2151
2152
2153
2154



2155


2156

2157
2158




2159
2160
2161
2162

2163
2164
2165
2166
2167
2168


2169



2170





2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
2189
2190

2191
2192
2193
2194



2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211

2212






























2213



2214
2215
2216




2217
2218
2219
2220
2221


2222
2223
2224
2225
2226
2227

2228

2229



2230






2231






2232


2233
2234
2235
2236
2237




2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253


2254



2255
2256
2257
2258
2259
2260
2261
2262
2263
    }
    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr);

    if (Tcl_Close(interp, chan) == TCL_ERROR) {
	return TCL_ERROR;
    }
    return result;
}

static int
StringWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors and
				 * returning the GIF data. */
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    int result;
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_IncrRefCount(objPtr);
    result = CommonWriteGIF(interp, objPtr, WriteToByteArray, format,
	    blockPtr);
    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objPtr);
    }
    Tcl_DecrRefCount(objPtr);
    return result;
}

static size_t
WriteToChannel(
    ClientData clientData,
    const char *bytes,
    size_t byteCount)
{
    Tcl_Channel handle = (Tcl_Channel)clientData;

    return Tcl_Write(handle, bytes, byteCount);
}

static size_t
WriteToByteArray(
    ClientData clientData,
    const char *bytes,
    size_t byteCount)
{
    Tcl_Obj *objPtr = (Tcl_Obj *)clientData;
    Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount);

    Tcl_IncrRefCount(tmpObj);
    Tcl_AppendObjToObj(objPtr, tmpObj);
    Tcl_DecrRefCount(tmpObj);
    return byteCount;
}

static int
CommonWriteGIF(
    Tcl_Interp *interp,
    ClientData handle,
    WriteBytesFunc *writeProc,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    GifWriterState state;
    int resolution;
    long width, height, x;
    unsigned char c;
    unsigned int top, left;
    (void)format;

    top = 0;
    left = 0;

    memset(&state, 0, sizeof(state));

    state.pixelSize = blockPtr->pixelSize;
    state.greenOffset = blockPtr->offset[1]-blockPtr->offset[0];
    state.blueOffset = blockPtr->offset[2]-blockPtr->offset[0];
    state.alphaOffset = blockPtr->offset[0];
    if (state.alphaOffset < blockPtr->offset[2]) {
	state.alphaOffset = blockPtr->offset[2];
    }
    if (++state.alphaOffset < state.pixelSize) {
	state.alphaOffset -= blockPtr->offset[0];
    } else {
	state.alphaOffset = 0;
    }

    writeProc(handle, (char *) (state.alphaOffset ? GIF89a : GIF87a), 6);

    for (x = 0; x < MAXCOLORMAPSIZE ;x++) {
	state.mapa[x][CM_RED] = 255;
	state.mapa[x][CM_GREEN] = 255;
	state.mapa[x][CM_BLUE] = 255;
    }

    width = blockPtr->width;
    height = blockPtr->height;
    state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0];
    state.pixelPitch = blockPtr->pitch;
    SaveMap(&state, blockPtr);
    if (state.num >= MAXCOLORMAPSIZE) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL", NULL);
	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);
    writeProc(handle, (char *) &c, 1);
    c = MSB(width);
    writeProc(handle, (char *) &c, 1);
    c = LSB(height);
    writeProc(handle, (char *) &c, 1);
    c = MSB(height);
    writeProc(handle, (char *) &c, 1);

    resolution = 0;
    while (state.num >> resolution) {
	resolution++;
    }
    c = 111 + resolution * 17;
    writeProc(handle, (char *) &c, 1);

    state.num = 1 << resolution;

    /*
     * Background color
     */

    c = 0;
    writeProc(handle, (char *) &c, 1);

    /*
     * Zero for future expansion.
     */

    writeProc(handle, (char *) &c, 1);

    for (x = 0; x < state.num; x++) {
	c = state.mapa[x][CM_RED];
	writeProc(handle, (char *) &c, 1);
	c = state.mapa[x][CM_GREEN];
	writeProc(handle, (char *) &c, 1);
	c = state.mapa[x][CM_BLUE];
	writeProc(handle, (char *) &c, 1);
    }

    /*
     * Write out extension for transparent colour index, if necessary.
     */

    if (state.alphaOffset) {
	c = GIF_EXTENSION;
	writeProc(handle, (char *) &c, 1);
	writeProc(handle, "\371\4\1\0\0\0", 7);
    }

    c = GIF_START;
    writeProc(handle, (char *) &c, 1);
    c = LSB(top);
    writeProc(handle, (char *) &c, 1);
    c = MSB(top);
    writeProc(handle, (char *) &c, 1);
    c = LSB(left);
    writeProc(handle, (char *) &c, 1);
    c = MSB(left);
    writeProc(handle, (char *) &c, 1);

    c = LSB(width);
    writeProc(handle, (char *) &c, 1);
    c = MSB(width);
    writeProc(handle, (char *) &c, 1);

    c = LSB(height);
    writeProc(handle, (char *) &c, 1);
    c = MSB(height);
    writeProc(handle, (char *) &c, 1);

    c = 0;
    writeProc(handle, (char *) &c, 1);
    c = resolution;
    writeProc(handle, (char *) &c, 1);

    state.ssize = state.rsize = blockPtr->width;
    state.csize = blockPtr->height;
    Compress(resolution+1, handle, writeProc, ReadValue, &state);

    c = 0;
    writeProc(handle, (char *) &c, 1);
    c = GIF_TERMINATOR;
    writeProc(handle, (char *) &c, 1);

    return TCL_OK;
}

static int
ColorNumber(
    GifWriterState *statePtr,
    int red, int green, int blue)

{
    int x = (statePtr->alphaOffset != 0);

    for (; x <= MAXCOLORMAPSIZE; x++) {
	if ((statePtr->mapa[x][CM_RED] == red) &&
		(statePtr->mapa[x][CM_GREEN] == green) &&
		(statePtr->mapa[x][CM_BLUE] == blue)) {
	    return x;
	}
    }
    return -1;
}

static int
IsNewColor(
    GifWriterState *statePtr,
    int red, int green, int blue)

{
    int x = (statePtr->alphaOffset != 0);

    for (; x<=statePtr->num ; x++) {
	if ((statePtr->mapa[x][CM_RED] == red) &&
		(statePtr->mapa[x][CM_GREEN] == green) &&
		(statePtr->mapa[x][CM_BLUE] == blue)) {
	    return 0;
	}
    }
    return 1;
}

static void
SaveMap(
    GifWriterState *statePtr,
    Tk_PhotoImageBlock *blockPtr)

{
    unsigned char *colores;
    int x, y;
    unsigned char red, green, blue;

    if (statePtr->alphaOffset) {
	statePtr->num = 0;
	statePtr->mapa[0][CM_RED] = DEFAULT_BACKGROUND_VALUE;
	statePtr->mapa[0][CM_GREEN] = DEFAULT_BACKGROUND_VALUE;
	statePtr->mapa[0][CM_BLUE] = DEFAULT_BACKGROUND_VALUE;
    } else {
	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 (!statePtr->alphaOffset || colores[statePtr->alphaOffset]!=0) {
		red = colores[0];
		green = colores[statePtr->greenOffset];
		blue = colores[statePtr->blueOffset];
		if (IsNewColor(statePtr, red, green, blue)) {
		    statePtr->num++;
		    if (statePtr->num >= MAXCOLORMAPSIZE) {
			return;
		    }
		    statePtr->mapa[statePtr->num][CM_RED] = red;
		    statePtr->mapa[statePtr->num][CM_GREEN] = green;
		    statePtr->mapa[statePtr->num][CM_BLUE] = blue;
		}
	    }
	    colores += statePtr->pixelSize;
	}
    }
}

static int
ReadValue(
    GifWriterState *statePtr)
{

    unsigned int col;

    if (statePtr->csize == 0) {
	return EOF;
    }
    if (statePtr->alphaOffset
	    && (statePtr->pixelOffset[statePtr->alphaOffset]==0)) {
	col = 0;
    } else {
	col = ColorNumber(statePtr, statePtr->pixelOffset[0],
		statePtr->pixelOffset[statePtr->greenOffset],
		statePtr->pixelOffset[statePtr->blueOffset]);
    }
    statePtr->pixelOffset += statePtr->pixelSize;
    if (--statePtr->ssize <= 0) {
	statePtr->ssize = statePtr->rsize;
	statePtr->csize--;
	statePtr->pixelOffset += statePtr->pixelPitch
		- (statePtr->rsize * statePtr->pixelSize);
    }

    return col;
}

/*


 * GIF Image compression - modified 'Compress'
 *
 * Based on: compress.c - File compression ala IEEE Computer, June 1984.
 *
 * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
 *              Jim McKie               (decvax!mcvax!jim)
 *              Steve Davies            (decvax!vax135!petsd!peora!srd)
 *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 */



static void
Compress(
    int initialBits,
    ClientData handle,
    WriteBytesFunc *writeProc,
    ifunptr readValue,
    GifWriterState *statePtr)
{

    long fcode, ent, disp, hSize, i = 0;
    int c, hshift;
    GIFState_t state;









    memset(&state, 0, sizeof(state));




    /*
     * Set up the globals:  initialBits - initial number of bits
     *			    outChannel	- pointer to output file
     */

    state.initialBits = initialBits;
    state.destination = handle;
    state.writeProc = writeProc;

    /*
     * Set up the necessary values.

     */





























    state.offset = 0;

    state.hSize = HSIZE;




    state.outCount = 0;
    state.clearFlag = 0;
    state.inCount = 1;


    state.maxCode = MAXCODE(state.numBits = state.initialBits);
    state.clearCode = 1 << (initialBits - 1);
    state.eofCode = state.clearCode + 1;
    state.freeEntry = state.clearCode + 2;
    CharInit(&state);



    ent = readValue(statePtr);


    hshift = 0;
    for (fcode = (long) state.hSize;  fcode < 65536L;  fcode *= 2L) {
	hshift++;
    }
    hshift = 8 - hshift;		/* Set hash code range bound */





    hSize = state.hSize;



    ClearHashTable(&state, (int) hSize); /* Clear hash table */




    Output(&state, (long) state.clearCode);






    while (U(c = readValue(statePtr)) != U(EOF)) {
	state.inCount++;

	fcode = (long) (((long) c << GIFBITS) + ent);
	i = ((long)c << hshift) ^ ent;	/* XOR hashing */


	if (state.hashTable[i] == fcode) {
	    ent = state.codeTable[i];
	    continue;
	} else if ((long) state.hashTable[i] < 0) {	/* Empty slot */
	    goto nomatch;

	}




	disp = hSize - i;		/* Secondary hash (after G. Knott) */
	if (i == 0) {
	    disp = 1;
	}

    probe:
	if ((i -= disp) < 0) {
	    i += hSize;



	}


	if (state.hashTable[i] == fcode) {
	    ent = state.codeTable[i];
	    continue;



	}
	if ((long) state.hashTable[i] > 0) {
	    goto probe;
	}





    nomatch:
	Output(&state, (long) ent);
	state.outCount++;
	ent = c;
	if (U(state.freeEntry) < U((long)1 << GIFBITS)) {
	    state.codeTable[i] = state.freeEntry++; /* code -> hashtable */
	    state.hashTable[i] = fcode;
	} else {
	    ClearForBlock(&state);

	}
    }

    /*

     * Put out the final code.
     */


    Output(&state, (long) ent);
    state.outCount++;
    Output(&state, (long) state.eofCode);
}

/*****************************************************************
 * Output --
 *	Output the given code.
 *

 * Inputs:



 *	code:	A numBits-bit integer. If == -1, then EOF. This assumes that
 *		numBits =< (long) wordsize - 1.
 * Outputs:

 *	Outputs code to the file.
 * Assumptions:
 *	Chars are 8 bits long.
 * Algorithm:
 *	Maintain a GIFBITS character long buffer (so that 8 codes will fit in
 *	it exactly). Use the VAX insv instruction to insert each code in turn.
 *	When the buffer fills up empty it and start over.
 */





static void
Output(
    GIFState_t *statePtr,





    long code)

{
    static const unsigned long masks[] = {











	0x0000,
	0x0001, 0x0003, 0x0007, 0x000F,
	0x001F, 0x003F, 0x007F, 0x00FF,
	0x01FF, 0x03FF, 0x07FF, 0x0FFF,
	0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
    };






    statePtr->currentAccumulated &= masks[statePtr->currentBits];



    if (statePtr->currentBits > 0) {



	statePtr->currentAccumulated |= ((long) code << statePtr->currentBits);



    } else {






	statePtr->currentAccumulated = code;












    }
    statePtr->currentBits += statePtr->numBits;




    while (statePtr->currentBits >= 8) {
	CharOut(statePtr, (unsigned) (statePtr->currentAccumulated & 0xff));
	statePtr->currentAccumulated >>= 8;








	statePtr->currentBits -= 8;


    }



    /*
     * If the next entry is going to be too big for the code size, then
     * increase it, if possible.
     */



    if ((statePtr->freeEntry > statePtr->maxCode) || statePtr->clearFlag) {
	if (statePtr->clearFlag) {

	    statePtr->maxCode = MAXCODE(

		    statePtr->numBits = statePtr->initialBits);

	    statePtr->clearFlag = 0;

	} else {
	    statePtr->numBits++;


	    if (statePtr->numBits == GIFBITS) {
		statePtr->maxCode = (long)1 << GIFBITS;
	    } else {
		statePtr->maxCode = MAXCODE(statePtr->numBits);
	    }
	}
    }






    if (code == statePtr->eofCode) {
	/*
	 * At EOF, write the rest of the buffer.
	 */










	while (statePtr->currentBits > 0) {
	    CharOut(statePtr,


		    (unsigned) (statePtr->currentAccumulated & 0xff));
	    statePtr->currentAccumulated >>= 8;


	    statePtr->currentBits -= 8;


	}
	FlushChar(statePtr);



    }
}




/*
 * Clear out the hash table
 */

static void
ClearForBlock(			/* Table clear for block compress. */
    GIFState_t *statePtr)



{


    ClearHashTable(statePtr, (int) statePtr->hSize);

    statePtr->freeEntry = statePtr->clearCode + 2;
    statePtr->clearFlag = 1;





    Output(statePtr, (long) statePtr->clearCode);
}


static void
ClearHashTable(			/* Reset code table. */
    GIFState_t *statePtr,
    int hSize)
{
    int *hashTablePtr = statePtr->hashTable + hSize;


    long i;



    long m1 = -1;






    i = hSize - 16;
    do {			/* might use Sys V memset(3) here */
	*(hashTablePtr-16) = m1;
	*(hashTablePtr-15) = m1;
	*(hashTablePtr-14) = m1;
	*(hashTablePtr-13) = m1;
	*(hashTablePtr-12) = m1;
	*(hashTablePtr-11) = m1;
	*(hashTablePtr-10) = m1;
	*(hashTablePtr-9) = m1;

	*(hashTablePtr-8) = m1;
	*(hashTablePtr-7) = m1;
	*(hashTablePtr-6) = m1;
	*(hashTablePtr-5) = m1;
	*(hashTablePtr-4) = m1;
	*(hashTablePtr-3) = m1;
	*(hashTablePtr-2) = m1;
	*(hashTablePtr-1) = m1;
	hashTablePtr -= 16;

    } while ((i -= 16) >= 0);

    for (i += 16; i > 0; i--) {
	*--hashTablePtr = m1;



    }
}

/*
 *****************************************************************************
 *
 * GIF Specific routines
 *
 *****************************************************************************
 */

/*
 * Set up the 'byte output' routine
 */

static void
CharInit(

    GIFState_t *statePtr)






























{



    statePtr->accumulatedByteCount = 0;
    statePtr->currentAccumulated = 0;
    statePtr->currentBits = 0;




}

/*
 * Add a character to the end of the current packet, and if it is 254
 * characters, flush the packet to disk.


 */

static void
CharOut(
    GIFState_t *statePtr,
    int c)

{

    statePtr->packetAccumulator[statePtr->accumulatedByteCount++] = c;



    if (statePtr->accumulatedByteCount >= 254) {






	FlushChar(statePtr);






    }


}

/*
 * Flush the packet to disk, and reset the accumulator
 */





static void
FlushChar(
    GIFState_t *statePtr)
{
    unsigned char c;

    if (statePtr->accumulatedByteCount > 0) {
	c = statePtr->accumulatedByteCount;
	statePtr->writeProc(statePtr->destination, (const char *) &c, 1);
	statePtr->writeProc(statePtr->destination,
		(const char *) statePtr->packetAccumulator,
		statePtr->accumulatedByteCount);
	statePtr->accumulatedByteCount = 0;
    }
}






/* The End */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|






|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<



|




<




|

|
|
|
|
|
|

|
|

|


|

|
|
|
|




|
|
|
|
|
<


|
|


|

|

|

|


|



|

|






|





|

|
|
|
|
|
|
|






|

|
|



|

|

|

|

|


|

|


|

|


|

|

|
|
|


|

|





|

|
>



|
<
|
|







|

|
>




<
|
|







|

|
>







|
|
|











|




|
|
|









|

>





|
<


|
|
|

|



|







>
>
|

|

<
<
|
|
<
<
|
|
>
>
|
|
|
|
|
|
|
<
>
|
|
|
>
>
>
>
>
>
>
>
|
<
>
>
>
|
<
<
|
<
|
|
|
<
|
<
<
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
>
>
>
>
|
|
|
>
>
|
<
<
<
|
>
|
>
|
>
|
<
<
<
|
|
>
>
>
|
>
|
>
>
>
|
>
>
>
|
<
>
>
>
>
>
|
<
<
|
|
<
>
|
<
<
<
|
|
>
|
>
>
>
|
<
<
|
|
|
<
|
|
>
>
>

>
|
|
|
<
>
>
>
|
<
<
|
>
>
>
>
|
|
|
|
<
<
<
<
<
|
>
|
|
|
<
>
|
<
|
>
|
|
<
|
|
<
<
<
|
>
|
>
>
>
|
|
|
>
|
<
|
|
|
|
<
<
|
>
>
>
>

|
|
>
>
>
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
>
>
>
>
|
>
|
>
>
>
|
>
>
>
|
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
|
|
|
|
>
>
>
>
>
>
>
>
|
>
>
|
>
>
|
<
<
|
<
|
>
>
|
|
>
|
>
|
>
|
>
|
|
>
>
|
|
<
|
|
|
|
>
>
>
>
|
>
|
<
<
<
>
>
>
>
>
>
>
>
|
>
|
|
>
>
|
|
>
>
|
>
>

|
>
>
>
|
|
>
>
>
|
<
<
<
|

|
|
>
>
>
|
>
>
|
>
|
|
>
>
>
>
|
<
|
|
>

|
|
|

|
>
>
|
>
>
>
|
>
>
>
>
>
|
<
<
|
|
|
|
|
|
|
|
>
|
<
|
|
|
<
<
<
<
>
|
|
|
|
>
>
>
|
|
|
<
<
<
<
<
<
<
|
<
<
<
|

<
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
|
|
>
>
>
>
|
<
|
<
<
>
>
|

|
<
|
<
>
|
>
|
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
|
<
<
<
>
>
>
>
|
<
<
<
<
<
|
<
|
<
<
<
|
<
|
|
>
>
|
>
>
>
|








1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501














































1502
1503
1504

1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648

1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749


1750
1751


1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762

1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775

1776
1777
1778
1779


1780

1781
1782
1783

1784


1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828



1829
1830
1831
1832
1833
1834
1835



1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851

1852
1853
1854
1855
1856
1857


1858
1859

1860
1861



1862
1863
1864
1865
1866
1867
1868
1869


1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
1880
1881
1882

1883
1884
1885
1886


1887
1888
1889
1890
1891
1892
1893
1894
1895





1896
1897
1898
1899
1900

1901
1902

1903
1904
1905
1906

1907
1908



1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923


1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952





1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014


2015

2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033

2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044



2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076



2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117


2118
2119
2120
2121
2122
2123
2124
2125
2126
2127

2128
2129
2130




2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141







2142



2143
2144

2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188

2189


2190
2191
2192
2193
2194

2195

2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221



2222
2223
2224
2225
2226





2227

2228



2229

2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
    }
    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;
}

static int














































CommonWriteGIF(
    Tcl_Interp *interp,
    Tcl_Channel handle,

    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    GifWriterState state, *statePtr = &state;
    int resolution;
    long width, height, x;
    unsigned char c;
    unsigned int top, left;


    top = 0;
    left = 0;

    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 (++statePtr->alphaOffset < statePtr->pixelSize) {
	statePtr->alphaOffset -= blockPtr->offset[0];
    } else {
	statePtr->alphaOffset = 0;
    }

    Tcl_Write(handle, (char *) (statePtr->alphaOffset ? GIF89a : GIF87a), 6);

    for (x=0 ; x<MAXCOLORMAPSIZE ; x++) {
	statePtr->mapa[x][CM_RED] = 255;
	statePtr->mapa[x][CM_GREEN] = 255;
	statePtr->mapa[x][CM_BLUE] = 255;
    }

    width = blockPtr->width;
    height = blockPtr->height;
    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 (statePtr->num<2) {
	statePtr->num = 2;
    }
    c = LSB(width);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(width);
    Tcl_Write(handle, (char *) &c, 1);
    c = LSB(height);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(height);
    Tcl_Write(handle, (char *) &c, 1);

    resolution = 0;
    while (statePtr->num >> resolution) {
	resolution++;
    }
    c = 111 + resolution * 17;
    Tcl_Write(handle, (char *) &c, 1);

    statePtr->num = 1 << resolution;

    /*
     * Background color
     */

    c = 0;
    Tcl_Write(handle, (char *) &c, 1);

    /*
     * Zero for future expansion.
     */

    Tcl_Write(handle, (char *) &c, 1);

    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 (statePtr->alphaOffset) {
	c = GIF_EXTENSION;
	Tcl_Write(handle, (char *) &c, 1);
	Tcl_Write(handle, "\371\4\1\0\0\0", 7);
    }

    c = GIF_START;
    Tcl_Write(handle, (char *) &c, 1);
    c = LSB(top);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(top);
    Tcl_Write(handle, (char *) &c, 1);
    c = LSB(left);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(left);
    Tcl_Write(handle, (char *) &c, 1);

    c = LSB(width);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(width);
    Tcl_Write(handle, (char *) &c, 1);

    c = LSB(height);
    Tcl_Write(handle, (char *) &c, 1);
    c = MSB(height);
    Tcl_Write(handle, (char *) &c, 1);

    c = 0;
    Tcl_Write(handle, (char *) &c, 1);
    c = resolution;
    Tcl_Write(handle, (char *) &c, 1);

    statePtr->ssize = statePtr->rsize = blockPtr->width;
    statePtr->csize = blockPtr->height;
    compress(resolution+1, handle, ReadValue, (ClientData) statePtr);

    c = 0;
    Tcl_Write(handle, (char *) &c, 1);
    c = GIF_TERMINATOR;
    Tcl_Write(handle, (char *) &c, 1);

    return TCL_OK;
}

static int
color(
    GifWriterState *statePtr,
    int red, int green, int blue,
    unsigned char mapa[MAXCOLORMAPSIZE][3])
{
    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;
	}
    }
    return -1;
}

static int
nuevo(
    GifWriterState *statePtr,
    int red, int green, int blue,
    unsigned char mapa[MAXCOLORMAPSIZE][3])
{
    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;
	}
    }
    return 1;
}

static void
savemap(
    GifWriterState *statePtr,
    Tk_PhotoImageBlock *blockPtr,
    unsigned char mapa[MAXCOLORMAPSIZE][3])
{
    unsigned char *colores;
    int x, y;
    unsigned char red, green, blue;

    if (statePtr->alphaOffset) {
	statePtr->num = 0;
	mapa[0][CM_RED] = 0xd9;
	mapa[0][CM_GREEN] = 0xd9;
	mapa[0][CM_BLUE] = 0xd9;
    } else {
	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 (!statePtr->alphaOffset || colores[statePtr->alphaOffset]!=0) {
		red = colores[0];
		green = colores[statePtr->greenOffset];
		blue = colores[statePtr->blueOffset];
		if (nuevo(statePtr, red, green, blue, mapa)) {
		    statePtr->num++;
		    if (statePtr->num >= MAXCOLORMAPSIZE) {
			return;
		    }
		    mapa[statePtr->num][CM_RED] = red;
		    mapa[statePtr->num][CM_GREEN] = green;
		    mapa[statePtr->num][CM_BLUE] = blue;
		}
	    }
	    colores += statePtr->pixelSize;
	}
    }
}

static int
ReadValue(
    ClientData clientData)
{
    GifWriterState *statePtr = (GifWriterState *) clientData;
    unsigned int col;

    if (statePtr->csize == 0) {
	return EOF;
    }
    if (statePtr->alphaOffset && statePtr->pixelo[statePtr->alphaOffset]==0) {

	col = 0;
    } else {
	col = color(statePtr, statePtr->pixelo[0],
		statePtr->pixelo[statePtr->greenOffset],
		statePtr->pixelo[statePtr->blueOffset], statePtr->mapa);
    }
    statePtr->pixelo += statePtr->pixelSize;
    if (--statePtr->ssize <= 0) {
	statePtr->ssize = statePtr->rsize;
	statePtr->csize--;
	statePtr->pixelo += statePtr->pixelPitch
		- (statePtr->rsize * statePtr->pixelSize);
    }

    return col;
}

/*
 *-----------------------------------------------------------------------
 *
 * miGIF Compression - mouse and ivo's GIF-compatible compression
 *
 *		-run length encoding compression routines-
 *


 * Copyright (C) 1998 Hutchison Avenue Software Corporation
 *		 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
 * 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.
 *

 *				 der Mouse
 *			mouse@rodents.montreal.qc.ca
 *	      7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
 *


 *			       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.

 *


 *-----------------------------------------------------------------------
 */

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
 */
/* #define MIGIF_DEBUGGING_ENVARS */

#ifdef MIGIF_DEBUGGING_ENVARS

/*
 * 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		(verboseSet?verbose:setVerbose())
#define DEBUGMSG(printfArgs)	if (MIGIF_VERBOSE) { printf printfArgs; }




static int
setVerbose(void)
{
    verbose = !!getenv("MIGIF_VERBOSE");
    verboseSet = 1;
    return verbose;
}




static const char *
binformat(
    unsigned int v,
    int nbits)
{
    static char bufs[8][64];
    static int bhand = 0;
    unsigned int bit;
    int bno;
    char *bp;

    bhand--;
    if (bhand < 0) {
	bhand = (sizeof(bufs) / sizeof(bufs[0])) - 1;
    }

    bp = &bufs[bhand][0];
    for (bno=nbits-1,bit=((unsigned int)1)<<bno ; bno>=0 ; bno--,bit>>=1) {
	*bp++ = (v & bit) ? '1' : '0';
	if (((bno&3) == 0) && (bno != 0)) {
	    *bp++ = '.';
	}


    }
    *bp = '\0';

    return &bufs[bhand][0];
}



#else /* !MIGIF_DEBUGGING_ENVARS */
#define DEBUGMSG(printfArgs) /* do nothing */
#endif

static void
writeBlock(
    miGIFState_t *statePtr)
{


    unsigned char c;

#ifdef MIGIF_DEBUGGING_ENVARS

    if (MIGIF_VERBOSE) {
	int i;
	printf("writeBlock %d:", statePtr->oblen);
	for (i=0 ; i<statePtr->oblen ; i++) {
	    printf(" %02x", statePtr->oblock[i]);
	}
	printf("\n");
    }
#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
blockOut(
    miGIFState_t *statePtr,
    unsigned c)
{
    DEBUGMSG(("blockOut %s\n", binformat(c, 8)));
    statePtr->oblock[statePtr->oblen++] = (unsigned char) c;
    if (statePtr->oblen >= 255) {





	writeBlock(statePtr);
    }
}

static void

blockFlush(
    miGIFState_t *statePtr)

{
    DEBUGMSG(("blockFlush\n"));
    if (statePtr->oblen > 0) {
	writeBlock(statePtr);

    }
}




static void
output(
    miGIFState_t *statePtr,
    int val)
{
    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
outputFlush(
    miGIFState_t *statePtr)
{
    DEBUGMSG(("outputFlush\n"));
    if (statePtr->obits > 0) {
	blockOut(statePtr, statePtr->obuf);
    }
    blockFlush(statePtr);
}

static void
didClear(
    miGIFState_t *statePtr)
{
    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
outputPlain(
    miGIFState_t *statePtr,
    int c)
{
    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(
    unsigned int x)
{
    unsigned int r;
    unsigned int v;

    if (x < 2) {
	return x;
    }
    for (v=x,r=1 ; v ; v>>=2,r<<=1);
    while (1) {
	v = ((x / r) + r) / 2;
	if (v==r || v==r+1) {
	    return r;
	}
	r = v;
    }
}

static int
computeTriangleCount(
    unsigned int count,
    unsigned int nrepcodes)
{
    unsigned int perrep;
    unsigned int cost;

    cost = 0;
    perrep = (nrepcodes * (nrepcodes+1)) / 2;
    while (count >= perrep) {
	cost += nrepcodes;
	count -= perrep;
    }
    if (count > 0) {
	unsigned int n = isqrt(count);

	while (n*(n+1) >= 2*count) {
	    n--;
	}
	while (n*(n+1) < 2*count) {
	    n++;
	}


	cost += n;

    }
    return (int) cost + 1;
}

static void
maxOutputClear(
    miGIFState_t *statePtr)
{
    statePtr->outputClear = statePtr->maxOcodes;
}

static void
resetOutputClear(
    miGIFState_t *statePtr)
{
    statePtr->outputClear = statePtr->outputClearInit;
    if (statePtr->outputCount >= statePtr->outputClear) {
	output(statePtr, statePtr->codeClear);

	didClear(statePtr);
    }
}

static void
runlengthFlushFromClear(
    miGIFState_t *statePtr,
    int count)
{
    int n;




    DEBUGMSG(("runlengthFlushFromClear %d\n", count));
    maxOutputClear(statePtr);
    statePtr->runlengthTablePixel = statePtr->runlengthPixel;
    n = 1;
    while (count > 0) {
	if (n == 1) {
	    statePtr->runlengthTableMax = 1;
	    outputPlain(statePtr, statePtr->runlengthPixel);
	    count--;
	} else if (count >= n) {
	    statePtr->runlengthTableMax = n;
	    outputPlain(statePtr, statePtr->runlengthBaseCode+n-2);
	    count -= n;
	} else if (count == 1) {
	    statePtr->runlengthTableMax++;
	    outputPlain(statePtr, statePtr->runlengthPixel);
	    count = 0;
	} else {
	    statePtr->runlengthTableMax++;
	    outputPlain(statePtr, statePtr->runlengthBaseCode+count-2);
	    count = 0;
	}
	if (statePtr->outputCount == 0) {
	    n = 1;
	} else {
	    n++;
	}
    }
    resetOutputClear(statePtr);
    DEBUGMSG(("runlengthFlushFromClear leaving tableMax=%d\n",
	    statePtr->runlengthTableMax));
}




static void
runlengthFlushClearOrRep(
    miGIFState_t *statePtr,
    int count)
{
    int withclr;

    DEBUGMSG(("runlengthFlushClearOrRep %d\n", count));
    withclr = computeTriangleCount((unsigned) count,
	    (unsigned) statePtr->maxOcodes);
    if (withclr < count) {
	output(statePtr, statePtr->codeClear);
	didClear(statePtr);
	runlengthFlushFromClear(statePtr, count);
    } else {
	for (; count>0 ; count--) {
	    outputPlain(statePtr, statePtr->runlengthPixel);
	}

    }
}

static void
runlengthFlushWithTable(
    miGIFState_t *statePtr,
    int count)
{
    int repmax;
    int repleft;
    int leftover;

    DEBUGMSG(("runlengthFlushWithTable %d\n", count));
    repmax = count / statePtr->runlengthTableMax;
    leftover = count % statePtr->runlengthTableMax;
    repleft = (leftover ? 1 : 0);
    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(("runlengthFlushWithTable repmax=%d leftover=%d repleft=%d\n",
	    repmax, leftover, repleft));
    if (computeTriangleCount((unsigned) count, (unsigned) statePtr->maxOcodes)
	    < repmax+repleft) {
	output(statePtr, statePtr->codeClear);
	didClear(statePtr);
	runlengthFlushFromClear(statePtr, count);
	return;
    }
    maxOutputClear(statePtr);

    for (; repmax>0 ; repmax--) {
	outputPlain(statePtr,
		statePtr->runlengthBaseCode + statePtr->runlengthTableMax - 2);




    }
    if (leftover) {
	if (statePtr->justCleared) {
	    runlengthFlushFromClear(statePtr, leftover);
	} else if (leftover == 1) {
	    outputPlain(statePtr, statePtr->runlengthPixel);
	} else {
	    outputPlain(statePtr, statePtr->runlengthBaseCode + leftover - 2);
	}
    }
    resetOutputClear(statePtr);







}




static void

runlengthFlush(
    miGIFState_t *statePtr)
{
    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 (statePtr->justCleared) {
	runlengthFlushFromClear(statePtr, statePtr->runlengthCount);
    } else if ((statePtr->runlengthTableMax < 2)
	    || (statePtr->runlengthTablePixel != statePtr->runlengthPixel)) {
	runlengthFlushClearOrRep(statePtr, statePtr->runlengthCount);
    } else {
	runlengthFlushWithTable(statePtr, statePtr->runlengthCount);
    }
    DEBUGMSG(("runlengthFlush ]\n"));
    statePtr->runlengthCount = 0;
}

static void
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;


    /*


     * For images with a lot of runs, making outputClearInit larger will give
     * better compression.
     */

    statePtr->outputClearInit =

	    (initBits <= 3) ? 9 : (statePtr->outputBumpInit-1);

#ifdef MIGIF_DEBUGGING_ENVARS
    {
	const char *ocienv = getenv("MIGIF_OUT_CLEAR_INIT");

	if (ocienv) {
	    statePtr->outputClearInit = atoi(ocienv);
	    DEBUGMSG(("[overriding outputClearInit to %d]\n",
		    statePtr->outputClearInit));
	}
    }
#endif
    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(clientData);
	if (statePtr->runlengthCount>0 && statePtr->runlengthPixel!=c) {
	    runlengthFlush(statePtr);
	}
	if (c == EOF) {
	    break;
	}
	if (statePtr->runlengthPixel == c) {



	    statePtr->runlengthCount++;
	} else {
	    statePtr->runlengthPixel = c;
	    statePtr->runlengthCount = 1;
	}





    }

    output(statePtr, statePtr->codeEOF);



    outputFlush(statePtr);

}

/*
 *-----------------------------------------------------------------------
 *
 * End of miGIF section - See copyright notice at start of section.
 *
 *-----------------------------------------------------------------------
 */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Deleted generic/tkImgListFormat.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
/*
 * tkImgListFormat.c --
 *
 *      Implements the default image data format. I.e. the format used for
 *      [imageName data] and [imageName put] if no other format is specified.
 *
 *      The default format consits of a list of scan lines (rows) with each
 *      list element being itself a list of pixels (or columns). For details,
 *      see the manpage photo.n
 *
 *      This image format cannot read/write files, it is meant for string
 *      data only.
 *
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * 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.
 *
 * Authors:
 *      Paul Mackerras (paulus@cs.anu.edu.au),
 *              Department of Computer Science,
 *              Australian National University.
 *
 *      Simon Bachmann (simonbachmann@bluewin.ch)
 */


#include "tkImgPhoto.h"

/*
 * Message to generate when an attempt to allocate memory for an image fails.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
        "not enough free memory for image buffer"


/*
 * Color name length limit: do not attempt to parse as color strings that are
 * longer than this limit
 */

#define TK_PHOTO_MAX_COLOR_CHARS 99

/*
 * Symbols for the different formats of a color string.
 */

enum ColorFormatType {
    COLORFORMAT_TKCOLOR,
    COLORFORMAT_EMPTYSTRING,
    COLORFORMAT_LIST,
    COLORFORMAT_RGB1,
    COLORFORMAT_RGB2,
    COLORFORMAT_RGBA1,
    COLORFORMAT_RGBA2
};

/*
 * Names for the color format types above.
 * Order must match the one in enum ColorFormatType
 */

static const char *const colorFormatNames[] = {
    "tkcolor",
    "emptystring",
    "list",
    "rgb-short",
    "rgb",
    "rgba-short",
    "rgba",
    NULL
};

/*
 * The following data structure is used to return information from
 * ParseFormatOptions:
 */

struct FormatOptions {
    int options;         /* Individual bits indicate which options were
                          * specified - see below. */
    Tcl_Obj *formatName; /* Name specified without an option. */
    enum ColorFormatType colorFormat;
                         /* The color format type given with the
                          * -colorformat option */
};

/*
 * Bit definitions for use with ParseFormatOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseFormatOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the FormatOptions structure if that option
 * was specified.
 *
 * OPT_COLORFORMAT:         Set if -alpha option allowed/specified.
 */

#define OPT_COLORFORMAT     1

/*
 * List of format option names. The order here must match the order of
 * declarations of the FMT_OPT_* constants above.
 */

static const char *const formatOptionNames[] = {
    "-colorformat",
    NULL
};

/*
 * Forward declarations
 */

static int      ParseFormatOptions(Tcl_Interp *interp, int allowedOptions,
                    int objc, Tcl_Obj *const objv[], int *indexPtr,
                    struct FormatOptions *optPtr);
static Tcl_Obj  *GetBadOptMsg(const char *badValue, int allowedOpts);
static int      StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString,
                    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int      StringReadDef(Tcl_Interp *interp, Tcl_Obj *data,
                    Tcl_Obj *formatString, Tk_PhotoHandle imageHandle,
                    int destX, int destY, int width, int height,
                    int srcX, int srcY);
static int      StringWriteDef(Tcl_Interp *interp,
                    Tcl_Obj *formatString,
                    Tk_PhotoImageBlock *blockPtr);
static int      ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj,
                    Display *display, Colormap colormap, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsList(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsHex(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);
static int      ParseColorAsStandard(Tcl_Interp *interp,
                    const char *colorString, int colorStrLen,
                    Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);

/*
 * The format record for the default image handler
 */

Tk_PhotoImageFormat tkImgFmtDefault = {
    "default",      /* name */
    NULL,           /* fileMatchProc: format doesn't support file ops */
    StringMatchDef, /* stringMatchProc */
    NULL,           /* fileReadProc: format doesn't support file read */
    StringReadDef,  /* stringReadProc */
    NULL,           /* fileWriteProc: format doesn't support file write */
    StringWriteDef, /* stringWriteProc */
    NULL            /* nextPtr */
};

/*
 *----------------------------------------------------------------------
 *
 * ParseFormatOptions --
 *
 *      Parse the options passed to the image format handler.
 *
 * Results:
 *      On success, the structure pointed to by optPtr is filled with the
 *      values passed or with the defaults and TCL_OK returned.
 *      If an error occurs, leaves an error message in interp and returns
 *      TCL_ERROR.
 *
 * Side effects:
 *      The value in *indexPtr is updated to the index of the fist
 *      element in argv[] that does not look like an option/value, or to
 *      argc if parsing reached the end of argv[].
 *
 *----------------------------------------------------------------------
 */
static int
ParseFormatOptions(
    Tcl_Interp *interp,               /* For error messages */
    int allowedOptions,               /* Bitfield specifying which options are
                                       * to be considered allowed */
    int objc,                         /* Number of elements in argv[] */
    Tcl_Obj *const objv[],            /* The arguments to parse */
    int *indexPtr,                    /* Index giving the first element to
                                       * parse. The value is updated to the
                                       * index where parsing ended */
    struct FormatOptions *optPtr)     /* Parsed option values are written to
                                       * this struct */

{
    int index, optIndex, first;
    enum ColorFormatType typeIndex;
    const char *option;

    first = 1;

    /*
     * Fill in default values
     */
    optPtr->options = 0;
    optPtr->formatName = NULL;
    optPtr->colorFormat = COLORFORMAT_RGB2;
    for (index = *indexPtr; index < objc; *indexPtr = ++index) {
        int optionExists;

        /*
         * The first value can be the format handler's name. It goes to
         * optPtr->name.
         */
        option = Tcl_GetString(objv[index]);
        if (option[0] != '-') {
            if (first) {
                optPtr->formatName = objv[index];
                first = 0;
                continue;
            } else {
                break;
            }
        }
        first = 0;

        /*
         * Check if option is known and allowed
         */

        optionExists = 1;
        if (Tcl_GetIndexFromObj(NULL, objv[index], formatOptionNames,
                "format option", 0, &optIndex) != TCL_OK) {
            optionExists = 0;
        }
        if (!optionExists || !((1 << optIndex) & allowedOptions)) {
            Tcl_SetObjResult(interp, GetBadOptMsg(Tcl_GetString(objv[index]),
                    allowedOptions));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
            return TCL_ERROR;
        }

        /*
         * Option-specific checks
         */

        switch (1 << optIndex) {
        case OPT_COLORFORMAT:
            *indexPtr = ++index;
            if (index >= objc) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option "
                        "requires a value", Tcl_GetString(objv[index - 1])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "MISSING_VALUE", NULL);
                return TCL_ERROR;
            }
            if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "",
                    TCL_EXACT, (int *)&typeIndex) != TCL_OK
                    || (typeIndex != COLORFORMAT_LIST
                    && typeIndex != COLORFORMAT_RGB2
                    && typeIndex != COLORFORMAT_RGBA2) ) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format "
                        "\"%s\": must be rgb, rgba, or list",
                        Tcl_GetString(objv[index])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "BAD_COLOR_FORMAT", NULL);
                return TCL_ERROR;
            }
            optPtr->colorFormat = typeIndex;
            break;
        default:
            Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough");
        }

        /*
         * Add option to bitfield in optPtr
         */
        optPtr->options |= (1 << optIndex);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 *  GetBadOptMsg --
 *
 *      Build a Tcl_Obj containing an error message in the form "bad option
 *      "xx": must be y, or z", based on the bits set in allowedOpts.
 *
 * Results:
 *      A Tcl Object containig the error message.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static Tcl_Obj *
GetBadOptMsg(
    const char *badValue,   /* the erroneous option */
    int allowedOpts)        /* bitfield specifying the allowed options */
{
    int i, bit;
    Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue);

    if (allowedOpts == 0) {
        Tcl_AppendToObj(resObj, "no options allowed", -1);
    } else {
        Tcl_AppendToObj(resObj, "must be ", -1);
        bit = 1;
        for (i = 0; formatOptionNames[i] != NULL; i++) {
            if (allowedOpts & bit) {
                if (allowedOpts & (bit -1)) {
                    /*
                     * not the first option
                     */
                    if (allowedOpts & ~((bit << 1) - 1)) {
                        /*
                         * not the last option
                         */
                        Tcl_AppendToObj(resObj, ", ", -1);
                    } else {
                        Tcl_AppendToObj(resObj, ", or ", -1);
                    }
                }
                Tcl_AppendToObj(resObj, formatOptionNames[i], -1);
            }
            bit <<=1;
        }
    }
    return resObj;
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchDef --
 *
 *      Default string match function. Test if image data in string form
 *      appears to be in the default list-of-list-of-pixel-data format
 *      accepted by the "<img> put" command.
 *
 * Results:
 *      If thte data is in the default format, writes the size of the image
 *      to widthPtr and heightPtr and returns 1. Otherwise, leaves an error
 *      message in interp (if not NULL) and returns 0.
 *      Note that this function does not parse all data points. A return
 *      value of 1 does not guarantee that the data can be read without
 *      errors.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static int
StringMatchDef(
    Tcl_Obj *data,          /* The data to check */
    Tcl_Obj *formatString,  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr,         /* Height of image is written to this location */
    Tcl_Interp *interp)     /* Error messages are left in this interpreter */
{
    int y, rowCount, colCount, curColCount;
    unsigned char dummy;
    Tcl_Obj **rowListPtr, *pixelData;
    (void)formatString;

    /*
     * See if data can be parsed as a list, if every element is itself a valid
     * list and all sublists have the same length.
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
            != TCL_OK) {
        return 0;
    }
    if (rowCount == 0) {
        /*
         * empty list is valid data
         */

        *widthPtr = 0;
        *heightPtr = 0;
        return 1;
    }
    colCount = -1;
    for (y = 0; y < rowCount; y++) {
        if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) {
            return 0;
        }
        if (colCount < 0) {
            colCount = curColCount;
        } else if (curColCount != colCount) {
            if (interp != NULL) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %d: "
                        "all rows must have the same number of elements", y));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_DATA", NULL);
            }
            return 0;
        }
    }

    /*
     * Data in base64 encoding (or even binary data), might actually pass
     * these tests. To avoid parsing it as list of lists format, check one
     * pixel for validity.
     */
    if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) {
        return 0;
    }
    if (Tcl_GetCharLength(pixelData) > TK_PHOTO_MAX_COLOR_CHARS) {
        return 0;
    }
    if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)),
            Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy)
            != TCL_OK) {
        return 0;
    }

    /*
     * Looks like we have valid data for this format.
     * We do not check any pixel values - that's the job of ImgStringRead()
     */

    *widthPtr = colCount;
    *heightPtr = rowCount;

    return 1;

}

/*
 *----------------------------------------------------------------------
 *
 * StringReadDef --
 *
 *      String read function for default format. (see manpage for details on
 *      the format).
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      If the data has valid format, write it to the image identified by
 *      imageHandle.
 *      If the image data cannot be parsed, an error message is left in
 *      interp.
 *
 *----------------------------------------------------------------------
*/

static int
StringReadDef(
    Tcl_Interp *interp,         /* leave error messages here */
    Tcl_Obj *data,              /* the data to parse */
    Tcl_Obj *formatString,      /* value of the -format option */
    Tk_PhotoHandle imageHandle, /* write data to this image */
    int destX, int destY,       /* start writing data at this point
                                 * in destination image*/
    int width, int height,      /* dimensions of area to write to */
    int srcX, int srcY)         /* start reading source data at these
                                 * coordinates */
{
    Tcl_Obj **rowListPtr, **colListPtr;
    Tcl_Obj **objv;
    int objc;
    unsigned char *curPixelPtr;
    int x, y, rowCount, colCount, curColCount;
    Tk_PhotoImageBlock srcBlock;
    Display *display;
    Colormap colormap;
    struct FormatOptions opts;
    int optIndex;

    /*
     * Parse format suboptions
     * We don't use any format suboptions, but we still need to provide useful
     * error messages if suboptions were specified.
     */

    memset(&opts, 0, sizeof(opts));
    if (formatString != NULL) {
        if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
                != TCL_OK) {
            return TCL_ERROR;
        }
        optIndex = 0;
        if (ParseFormatOptions(interp, 0, objc, objv, &optIndex, &opts)
                != TCL_OK) {
            return TCL_ERROR;
        }
        if (optIndex < objc) {
            Tcl_SetObjResult(interp,
                    GetBadOptMsg(Tcl_GetString(objv[optIndex]), 0));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
            return TCL_ERROR;
        }
    }

    /*
     * Check input data
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
            != TCL_OK ) {
        return TCL_ERROR;
    }
    if ( rowCount > 0 && Tcl_ListObjLength(interp, rowListPtr[0], &colCount)
            != TCL_OK) {
        return TCL_ERROR;
    }
    if (width <= 0 || height <= 0 || rowCount == 0 || colCount == 0) {
        /*
         * No changes with zero sized input or zero sized output region
         */

        return TCL_OK;
    }
    if (srcX < 0 || srcY < 0 || srcX >= rowCount || srcY >= colCount) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("source coordinates out of range"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL);
        return TCL_ERROR;
    }

    /*
     * Memory allocation overflow protection.
     * May not be able to trigger/ demo / test this.
     */

    if (colCount > (int)(UINT_MAX / 4 / rowCount)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "photo image dimensions exceed Tcl memory limits"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "OVERFLOW", NULL);
        return TCL_OK;
    }

    /*
     * Read data and put it to imageHandle
     */

    srcBlock.width = colCount - srcX;
    srcBlock.height = rowCount - srcY;
    srcBlock.pixelSize = 4;
    srcBlock.pitch = srcBlock.width * 4;
    srcBlock.offset[0] = 0;
    srcBlock.offset[1] = 1;
    srcBlock.offset[2] = 2;
    srcBlock.offset[3] = 3;
    srcBlock.pixelPtr = (unsigned char *)attemptckalloc(srcBlock.pitch * srcBlock.height);
    if (srcBlock.pixelPtr == NULL) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(TK_PHOTO_ALLOC_FAILURE_MESSAGE));
        Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
        return TCL_ERROR;
    }
    curPixelPtr = srcBlock.pixelPtr;
    display = Tk_Display(Tk_MainWindow(interp));
    colormap = Tk_Colormap(Tk_MainWindow(interp));
    for (y = srcY; y < rowCount; y++) {
        /*
         * We don't test the length of row, as that's been done in
         * ImgStringMatch()
         */

        if (Tcl_ListObjGetElements(interp, rowListPtr[y], &curColCount,
                &colListPtr) != TCL_OK) {
            goto errorExit;
        }
        for (x = srcX; x < colCount; x++) {
            if (ParseColor(interp, colListPtr[x], display, colormap,
                    curPixelPtr, curPixelPtr + 1, curPixelPtr + 2,
                    curPixelPtr + 3) != TCL_OK) {
                goto errorExit;
            }
            curPixelPtr += 4;
        }
    }

    /*
     * Write image data to destHandle
     */
    if (Tk_PhotoPutBlock(interp, imageHandle, &srcBlock, destX, destY,
            width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
        goto errorExit;
    }

    ckfree(srcBlock.pixelPtr);

    return TCL_OK;

  errorExit:
    ckfree(srcBlock.pixelPtr);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * StringWriteDef --
 *
 *      String write function for default image data format. See the user
 *      documentation for details.
 *
 * Results:
 *      The converted data is set as the result of interp. Returns a standard
 *      Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

static int
StringWriteDef(
    Tcl_Interp *interp,                 /* For the result and errors */
    Tcl_Obj *formatString,              /* The value of the -format option */
    Tk_PhotoImageBlock *blockPtr)       /* The image data to convert */
{
    int greenOffset, blueOffset, alphaOffset, hasAlpha;
    Tcl_Obj *result, **objv = NULL;
    int objc, allowedOpts, optIndex;
    struct FormatOptions opts;

    /*
     * Parse format suboptions
     */
    if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
            != TCL_OK) {
        return TCL_ERROR;
    }
    allowedOpts = OPT_COLORFORMAT;
    optIndex = 0;
    if (ParseFormatOptions(interp, allowedOpts, objc, objv, &optIndex, &opts)
            != TCL_OK) {
        return TCL_ERROR;
    }
    if (optIndex < objc) {
        Tcl_SetObjResult(interp,
                GetBadOptMsg(Tcl_GetString(objv[optIndex]), allowedOpts));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
        return TCL_ERROR;
    }

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    /*
     * A negative alpha offset signals that the image is fully opaque.
     * That's not really documented anywhere, but it's the way it is!
     */

    if (blockPtr->offset[3] < 0) {
        hasAlpha = 0;
        alphaOffset = 0;
    } else {
        hasAlpha = 1;
        alphaOffset = blockPtr->offset[3] - blockPtr->offset[0];
    }

    if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
        int row, col;
        Tcl_DString data, line;
        char colorBuf[11];
        unsigned char *pixelPtr;
        unsigned char alphaVal = 255;

        Tcl_DStringInit(&data);
        for (row=0; row<blockPtr->height; row++) {
            pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
                    + row * blockPtr->pitch;
            Tcl_DStringInit(&line);
            for (col=0; col<blockPtr->width; col++) {
                if (hasAlpha) {
                    alphaVal = pixelPtr[alphaOffset];
                }

                /*
                 * We don't build lines as a list for #RGBA and #RGB. Since
                 * these color formats look like comments, the first element
                 * of the list would get quoted with an additional {} .
                 * While this is not a problem if the data is used as
                 * a list, it would cause problems if someone decides to parse
                 * it as a string (and it looks kinda strange)
                 */

                switch (opts.colorFormat) {
                case COLORFORMAT_RGB2:
                    sprintf(colorBuf, "#%02x%02x%02x ",  pixelPtr[0],
                            pixelPtr[greenOffset], pixelPtr[blueOffset]);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_RGBA2:
                    sprintf(colorBuf, "#%02x%02x%02x%02x ",
                            pixelPtr[0], pixelPtr[greenOffset],
                            pixelPtr[blueOffset], alphaVal);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_LIST:
                    Tcl_DStringStartSublist(&line);
                    sprintf(colorBuf, "%d", pixelPtr[0]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[greenOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[blueOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", alphaVal);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    Tcl_DStringEndSublist(&line);
                    break;
                default:
                    Tcl_Panic("unexpected switch fallthrough");
                }
                pixelPtr += blockPtr->pixelSize;
            }
            if (opts.colorFormat != COLORFORMAT_LIST) {
                /*
                 * For the #XXX formats, we need to remove the last
                 * whitespace.
                 */

                *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1)
                        = '\0';
            }
            Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line));
            Tcl_DStringFree(&line);
        }
        result = Tcl_NewStringObj(Tcl_DStringValue(&data), -1);
        Tcl_DStringFree(&data);
    } else {
        result = Tcl_NewObj();
    }

    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColor --
 *
 *      This function extracts color and alpha values from a string. It
 *      understands standard Tk color formats, alpha suffixes and the color
 *      formats specific to photo images, which include alpha data.
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      If the input cannot be parsed, leaves an error message in
 *      interp. Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColor(
    Tcl_Interp *interp,         /* error messages go there */
    Tcl_Obj *specObj,           /* the color data to parse */
    Display *display,           /* display of main window, needed to parse
                                 * standard Tk colors */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    const char *specString;
    TkSizeT charCount;

    /*
     * Find out which color format we have
     */

    specString = TkGetStringFromObj(specObj, &charCount);

    if (charCount == 0) {
        /* Empty string */
        *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
        return TCL_OK;
    }
    if (charCount > TK_PHOTO_MAX_COLOR_CHARS) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "INVALID_COLOR", NULL);
        return TCL_ERROR;
    }
    if (specString[0] == '#') {
        return ParseColorAsHex(interp, specString, charCount, display,
                colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    if (ParseColorAsList(interp, specString, charCount,
            redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) {
        return TCL_OK;
    }

    /*
     * Parsing the color as standard Tk color always is the last option tried
     * because TkParseColor() is very slow with values it cannot parse.
     */

    Tcl_ResetResult(interp);
    return ParseColorAsStandard(interp, specString, charCount, display,
            colormap, redPtr, greenPtr, bluePtr, alphaPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsList --
 *
 *      This function extracts color and alpha values from a list of 3 or 4
 *      integers (the list color format).
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      Does *not* leave error messages in interp. The reason is that
 *      it is not always possible to tell if the list format was even
 *      intended and thus it is hard to return meaningful messages.
 *      A general error message from the caller is probably the best
 *      alternative.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsList(
    Tcl_Interp *dummy,         /* not used */
    const char *colorString,    /* the color data to parse */
    int colorStrLen,            /* length of the color string */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    /*
     * This is kinda ugly. The code would be certainly nicer if it
     * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with
     * strtol() it's *much* faster.
     */

    const char *curPos;
    int values[4];
    int i;
    (void)dummy;
    (void)colorStrLen;

    curPos = colorString;
    i = 0;

    /*
     * strtol can give false positives with a sequence of space chars.
     * To avoid that, avance the pointer to the next non-blank char.
     */

    while(isspace(UCHAR(*curPos))) {
        ++curPos;
    }
    while (i < 4 && *curPos != '\0') {
        values[i] = strtol(curPos, (char **)&curPos, 0);
        if (values[i] < 0 || values[i] > 255) {
            return TCL_ERROR;
        }
        while(isspace(UCHAR(*curPos))) {
            ++curPos;
        }
        ++i;
    }

    if (i < 3 || *curPos != '\0') {
        return TCL_ERROR;
    }
    if (i < 4) {
        values[3] = 255;
    }

    *redPtr = (unsigned char) values[0];
    *greenPtr = (unsigned char) values[1];
    *bluePtr = (unsigned char) values[2];
    *alphaPtr = (unsigned char) values[3];

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsHex --
 *
 *      This function extracts color and alpha values from a string
 *      starting with '#', followed by hex digits. It undestands both
 *      the #RGBA form and the #RBG (with optional suffix)
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsHex(
    Tcl_Interp *interp,         /* error messages are left here */
    const char *colorString,    /* the color data to parse */
    int colorStrLen,            /* length of the color string */
    Display *display,           /* display of main window */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    int i;
    unsigned long int colorValue = 0;

    if (colorStrLen - 1 != 4 && colorStrLen - 1 != 8) {
        return ParseColorAsStandard(interp, colorString, colorStrLen,
                display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    for (i = 1; i < colorStrLen; i++) {
        if (!isxdigit(UCHAR(colorString[i]))) {
            /*
             * There still is a chance that this is a Tk color with
             * an alpha suffix
             */

            return ParseColorAsStandard(interp, colorString, colorStrLen,
                    display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
        }
    }

    colorValue = strtoul(colorString + 1, NULL, 16);
    switch (colorStrLen - 1) {
    case 4:
        /* #RGBA format */
        *redPtr = (unsigned char) ((colorValue >> 12) * 0x11);
        *greenPtr = (unsigned char) (((colorValue >> 8) & 0xf) * 0x11);
        *bluePtr = (unsigned char) (((colorValue >> 4) & 0xf) * 0x11);
        *alphaPtr = (unsigned char) ((colorValue & 0xf) * 0x11);
        return TCL_OK;
    case 8:
        /* #RRGGBBAA format */
        *redPtr = (unsigned char) (colorValue >> 24);
        *greenPtr = (unsigned char) ((colorValue >> 16) & 0xff);
        *bluePtr = (unsigned char) ((colorValue >> 8) & 0xff);
        *alphaPtr = (unsigned char) (colorValue & 0xff);
        return TCL_OK;
    default:
        Tcl_Panic("unexpected switch fallthrough");
    }

    /* Shouldn't get here */
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsStandard --
 *
 *      This function tries to split a color stirng in a color and a
 *      suffix part and to extract color and alpha values from them. The
 *      color part is treated as regular Tk color.
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsStandard(
    Tcl_Interp *interp,         /* error messages are left here */
    const char *specString,    /* the color data to parse */
    int specStrLen,            /* length of the color string */
    Display *display,           /* display of main window */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    XColor parsedColor;
    const char *suffixString, *colorString;
    char colorBuffer[TK_PHOTO_MAX_COLOR_CHARS + 1];
    char *tmpString;
    double fracAlpha;
    unsigned int suffixAlpha;
    int i;

    /*
     * Split color data string in color and suffix parts
     */

    if ((suffixString = strrchr(specString, '@')) == NULL
            && ((suffixString = strrchr(specString, '#')) == NULL
                    || suffixString == specString)) {
        suffixString = specString + specStrLen;
        colorString = specString;
    } else {
        strncpy(colorBuffer, specString, suffixString - specString);
        colorBuffer[suffixString - specString] = '\0';
        colorString = (const char*)colorBuffer;
    }

    /*
     * Try to parse as standard Tk color.
     *
     * We don't use Tk_GetColor() et al. here, as those functions
     * migth return a color that does not exaxtly match the given name
     * if the colormap is full. Also, we don't really want the color to be
     * added to the colormap.
     */

    if ( ! TkParseColor(display, colormap, colorString, &parsedColor)) {
         Tcl_SetObjResult(interp, Tcl_ObjPrintf(
            "invalid color name \"%s\"", specString));
         Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                 "INVALID_COLOR", NULL);
         return TCL_ERROR;
    }

    /*
     * parse the Suffix
     */

    switch (suffixString[0]) {
    case '\0':
        suffixAlpha = 255;
        break;
    case '@':
        fracAlpha = strtod(suffixString + 1, &tmpString);
        if (*tmpString != '\0') {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha "
                    "suffix \"%s\": expected floating-point value",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID COLOR", NULL);
            return TCL_ERROR;
        }
        if (fracAlpha < 0 || fracAlpha > 1) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha suffix"
                    " \"%s\": value must be in the range from 0 to 1",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID_COLOR", NULL);
            return TCL_ERROR;
        }
        suffixAlpha = (unsigned int) floor(fracAlpha * 255 + 0.5);
        break;
    case '#':
        if (strlen(suffixString + 1) < 1 || strlen(suffixString + 1)> 2) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                    "invalid alpha suffix \"%s\"", suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID_COLOR", NULL);
            return TCL_ERROR;
        }
        for (i = 1; i <= (int)strlen(suffixString + 1); i++) {
            if ( ! isxdigit(UCHAR(suffixString[i]))) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "invalid alpha suffix \"%s\": expected hex digit",
                        suffixString));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_COLOR", NULL);
                return TCL_ERROR;
            }
        }
        if (strlen(suffixString + 1) == 1) {
            sscanf(suffixString, "#%1x", &suffixAlpha);
            suffixAlpha *= 0x11;
        } else {
            sscanf(suffixString, "#%2x", &suffixAlpha);
        }
        break;
    default:
        Tcl_Panic("unexpected switch fallthrough");
    }

    *redPtr = (unsigned char) (parsedColor.red >> 8);
    *greenPtr = (unsigned char) (parsedColor.green >> 8);
    *bluePtr = (unsigned char) (parsedColor.blue >> 8);
    *alphaPtr = (unsigned char) suffixAlpha;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugStringMatchDef --
 *
 *      Debugging function for StringMatchDef. Basically just an alias for
 *      that function, intended to expose it directly to tests, as
 *      StirngMatchDef cannot be sufficiently tested otherwise.
 *
 * Results:
 *      See StringMatchDef.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
int
TkDebugPhotoStringMatchDef(
    Tcl_Interp *interp,     /* Error messages are left in this interpreter */
    Tcl_Obj *data,          /* The data to check */
    Tcl_Obj *formatString,  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr)         /* Height of image is written to this location */
{
    return StringMatchDef(data, formatString, widthPtr, heightPtr, interp);
}


/* Local Variables: */
/* mode: c */
/* fill-column: 78 */
/* c-basic-offset: 4 */
/* tab-width: 8 */
/* indent-tabs-mode: nil */
/* End: */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted generic/tkImgPNG.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
/*
 * tkImgPNG.c --
 *
 *	A Tk photo image file handler for PNG files.
 *
 * Copyright (c) 2006-2008 Muonics, Inc.
 * Copyright (c) 2008 Donal K. Fellows
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#define	PNG_INT32(a,b,c,d)	\
	(((long)(a) << 24) | ((long)(b) << 16) | ((long)(c) << 8) | (long)(d))
#define	PNG_BLOCK_SZ	1024		/* Process up to 1k at a time. */
#define PNG_MIN(a, b) (((a) < (b)) ? (a) : (b))

/*
 * Every PNG image starts with the following 8-byte signature.
 */

#define PNG_SIG_SZ	8
static const unsigned char pngSignature[] = {
    137, 80, 78, 71, 13, 10, 26, 10
};

static const int startLine[8] = {
    0, 0, 0, 4, 0, 2, 0, 1
};

/*
 * Chunk type flags.
 */

#define PNG_CF_ANCILLARY 0x20000000L	/* Non-critical chunk (can ignore). */
#define PNG_CF_PRIVATE   0x00100000L	/* Application-specific chunk. */
#define PNG_CF_RESERVED  0x00001000L	/* Not used. */
#define PNG_CF_COPYSAFE  0x00000010L	/* Opaque data safe for copying. */

/*
 * Chunk types, not all of which have support implemented. Note that there are
 * others in the official extension set which we will never support (as they
 * are officially deprecated).
 */

#define CHUNK_IDAT	PNG_INT32('I','D','A','T')	/* Pixel data. */
#define CHUNK_IEND	PNG_INT32('I','E','N','D')	/* End of Image. */
#define CHUNK_IHDR	PNG_INT32('I','H','D','R')	/* Header. */
#define CHUNK_PLTE	PNG_INT32('P','L','T','E')	/* Palette. */

#define CHUNK_bKGD	PNG_INT32('b','K','G','D')	/* Background Color */
#define CHUNK_cHRM	PNG_INT32('c','H','R','M')	/* Chroma values. */
#define CHUNK_gAMA	PNG_INT32('g','A','M','A')	/* Gamma. */
#define CHUNK_hIST	PNG_INT32('h','I','S','T')	/* Histogram. */
#define CHUNK_iCCP	PNG_INT32('i','C','C','P')	/* Color profile. */
#define CHUNK_iTXt	PNG_INT32('i','T','X','t')	/* Internationalized
							 * text (comments,
							 * etc.) */
#define CHUNK_oFFs	PNG_INT32('o','F','F','s')	/* Image offset. */
#define CHUNK_pCAL	PNG_INT32('p','C','A','L')	/* Pixel calibration
							 * data. */
#define CHUNK_pHYs	PNG_INT32('p','H','Y','s')	/* Physical pixel
							 * dimensions. */
#define CHUNK_sBIT	PNG_INT32('s','B','I','T')	/* Significant bits */
#define CHUNK_sCAL	PNG_INT32('s','C','A','L')	/* Physical scale. */
#define CHUNK_sPLT	PNG_INT32('s','P','L','T')	/* Suggested
							 * palette. */
#define CHUNK_sRGB	PNG_INT32('s','R','G','B')	/* Standard RGB space
							 * declaration. */
#define CHUNK_tEXt	PNG_INT32('t','E','X','t')	/* Plain Latin-1
							 * text. */
#define CHUNK_tIME	PNG_INT32('t','I','M','E')	/* Time stamp. */
#define CHUNK_tRNS	PNG_INT32('t','R','N','S')	/* Transparency. */
#define CHUNK_zTXt	PNG_INT32('z','T','X','t')	/* Compressed Latin-1
							 * text. */

/*
 * Color flags.
 */

#define PNG_COLOR_INDEXED	1
#define PNG_COLOR_USED		2
#define PNG_COLOR_ALPHA		4

/*
 * Actual color types.
 */

#define PNG_COLOR_GRAY		0
#define PNG_COLOR_RGB		(PNG_COLOR_USED)
#define PNG_COLOR_PLTE		(PNG_COLOR_USED | PNG_COLOR_INDEXED)
#define PNG_COLOR_GRAYALPHA	(PNG_COLOR_GRAY | PNG_COLOR_ALPHA)
#define PNG_COLOR_RGBA		(PNG_COLOR_USED | PNG_COLOR_ALPHA)

/*
 * Compression Methods.
 */

#define PNG_COMPRESS_DEFLATE	0

/*
 * Filter Methods.
 */

#define PNG_FILTMETH_STANDARD	0

/*
 * Interlacing Methods.
 */

#define	PNG_INTERLACE_NONE	0
#define PNG_INTERLACE_ADAM7	1

/*
 * State information, used to store everything about the PNG image being
 * currently parsed or created.
 */

typedef struct {
    /*
     * PNG data source/destination channel/object/byte array.
     */

    Tcl_Channel channel;	/* Channel for from-file reads. */
    Tcl_Obj *objDataPtr;
    unsigned char *strDataBuf;	/* Raw source data for from-string reads. */
    TkSizeT strDataLen;		/* Length of source data. */
    unsigned char *base64Data;	/* base64 encoded string data. */
    unsigned char base64Bits;	/* Remaining bits from last base64 read. */
    unsigned char base64State;	/* Current state of base64 decoder. */
    double alpha;		/* Alpha from -format option. */

    /*
     * Image header information.
     */

    unsigned char bitDepth;	/* Number of bits per pixel. */
    unsigned char colorType;	/* Grayscale, TrueColor, etc. */
    unsigned char compression;	/* Compression Mode (always zlib). */
    unsigned char filter;	/* Filter mode (0 - 3). */
    unsigned char interlace;	/* Type of interlacing (if any). */
    unsigned char numChannels;	/* Number of channels per pixel. */
    unsigned char bytesPerPixel;/* Bytes per pixel in scan line. */
    int bitScale;		/* Scale factor for RGB/Gray depths < 8. */
    int currentLine;		/* Current line being unfiltered. */
    unsigned char phase;	/* Interlacing phase (0..6). */
    Tk_PhotoImageBlock block;
    int blockLen;		/* Number of bytes in Tk image pixels. */

    /*
     * For containing data read from PLTE (palette) and tRNS (transparency)
     * chunks.
     */

    int paletteLen;		/* Number of PLTE entries (1..256). */
    int useTRNS;		/* Flag to indicate whether there was a
				 * palette given. */
    struct {
	unsigned char red;
	unsigned char green;
	unsigned char blue;
	unsigned char alpha;
    } palette[256];		/* Palette RGB/Transparency table. */
    unsigned char transVal[6];	/* Fully-transparent RGB/Gray Value. */

    /*
     * For compressing and decompressing IDAT chunks.
     */

    Tcl_ZlibStream stream;	/* Inflating or deflating stream; this one is
				 * not bound to a Tcl command. */
    Tcl_Obj *lastLineObj;	/* Last line of pixels, for unfiltering. */
    Tcl_Obj *thisLineObj;	/* Current line of pixels to process. */
    int lineSize;		/* Number of bytes in a PNG line. */
    int phaseSize;		/* Number of bytes/line in current phase. */
} PNGImage;

/*
 * Maximum size of various chunks.
 */

#define	PNG_PLTE_MAXSZ 768	/* 3 bytes/RGB entry, 256 entries max */
#define	PNG_TRNS_MAXSZ 256	/* 1-byte alpha, 256 entries max */

/*
 * Forward declarations of non-global functions defined in this file:
 */

static void		ApplyAlpha(PNGImage *pngPtr);
static int		CheckColor(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	CheckCRC(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long calculated);
static void		CleanupPNGImage(PNGImage *pngPtr);
static int		DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr);
static int		DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY);
static int		EncodePNG(Tcl_Interp *interp,
			    Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr);
static int		FileMatchPNG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *fmtObj, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);
static int		FileWritePNG(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *fmtObj, Tk_PhotoImageBlock *blockPtr);
static int		InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Channel chan, Tcl_Obj *objPtr, int dir);
static inline unsigned char Paeth(int a, int b, int c);
static int		ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    PNGImage *pngPtr);
static int		ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    size_t *sizePtr, unsigned long *typePtr,
			    unsigned long *crcPtr);
static int		ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long *resultPtr, unsigned long *crcPtr);
static int		ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadTRNS(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		SkipChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		StringMatchPNG(Tcl_Obj *dataObj, Tcl_Obj *fmtObj,
			    int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		StringReadPNG(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static int		StringWritePNG(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	WriteByte(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char c, unsigned long *crcPtr);
static inline int	WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long chunkType,
			    const unsigned char *dataPtr, size_t dataSize);
static int		WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
			    const unsigned char *srcPtr, size_t srcSz,
			    unsigned long *crcPtr);
static int		WriteExtraChunks(Tcl_Interp *interp,
			    PNGImage *pngPtr);
static int		WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		WriteIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static inline int	WriteInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long l, unsigned long *crcPtr);

/*
 * The format record for the PNG file format:
 */

Tk_PhotoImageFormat tkImgFmtPNG = {
    "png",			/* name */
    FileMatchPNG,		/* fileMatchProc */
    StringMatchPNG,		/* stringMatchProc */
    FileReadPNG,		/* fileReadProc */
    StringReadPNG,		/* stringReadProc */
    FileWritePNG,		/* fileWriteProc */
    StringWritePNG,		/* stringWriteProc */
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * InitPNGImage --
 *
 *	This function is invoked by each of the Tk image handler procs
 *	(MatchStringProc, etc.) to initialize state information used during
 *	the course of encoding or decoding a PNG image.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if initialization failed.
 *
 * Side effects:
 *	The reference count of the -data Tcl_Obj*, if any, is incremented.
 *
 *----------------------------------------------------------------------
 */

static int
InitPNGImage(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Channel chan,
    Tcl_Obj *objPtr,
    int dir)
{
    memset(pngPtr, 0, sizeof(PNGImage));

    pngPtr->channel = chan;
    pngPtr->alpha = 1.0;

    /*
     * If decoding from a -data string object, increment its reference count
     * for the duration of the decode and get its length and byte array for
     * reading with ReadData().
     */

    if (objPtr) {
	Tcl_IncrRefCount(objPtr);
	pngPtr->objDataPtr = objPtr;
	pngPtr->strDataBuf =
		TkGetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
    }

    /*
     * Initialize the palette transparency table to fully opaque.
     */

    memset(pngPtr->palette, 255, sizeof(pngPtr->palette));

    /*
     * Initialize Zlib inflate/deflate stream.
     */

    if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB,
	    TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "zlib initialization failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
	}
	if (objPtr) {
	    Tcl_DecrRefCount(objPtr);
	}
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupPNGImage --
 *
 *	This function is invoked by each of the Tk image handler procs
 *	(MatchStringProc, etc.) prior to returning to Tcl in order to clean up
 *	any allocated memory and call other cleanup handlers such as zlib's
 *	inflateEnd/deflateEnd.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count of the -data Tcl_Obj*, if any, is decremented.
 *	Buffers are freed, streams are closed. The PNGImage should not be used
 *	for any purpose without being reinitialized post-cleanup.
 *
 *----------------------------------------------------------------------
 */

static void
CleanupPNGImage(
    PNGImage *pngPtr)
{
    /*
     * Don't need the object containing the -data value anymore.
     */

    if (pngPtr->objDataPtr) {
	Tcl_DecrRefCount(pngPtr->objDataPtr);
    }

    /*
     * Discard pixel buffer.
     */

    if (pngPtr->stream) {
	Tcl_ZlibStreamClose(pngPtr->stream);
    }

    if (pngPtr->block.pixelPtr) {
	ckfree(pngPtr->block.pixelPtr);
    }
    if (pngPtr->thisLineObj) {
	Tcl_DecrRefCount(pngPtr->thisLineObj);
    }
    if (pngPtr->lastLineObj) {
	Tcl_DecrRefCount(pngPtr->lastLineObj);
    }

    memset(pngPtr, 0, sizeof(PNGImage));
}

/*
 *----------------------------------------------------------------------
 *
 * ReadBase64 --
 *
 *	This function is invoked to read the specified number of bytes from
 *	base-64 encoded image data.
 *
 *	Note: It would be better if the Tk_PhotoImage stuff handled this by
 *	creating a channel from the -data value, which would take care of
 *	base64 decoding and made the data readable as if it were coming from a
 *	file.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs.
 *
 * Side effects:
 *	The file position will change. The running CRC is updated if a pointer
 *	to it is provided.
 *
 *----------------------------------------------------------------------
 */

static int
ReadBase64(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    static const unsigned char from64[] = {
	0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80,
	0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x3e,
	0x83, 0x83, 0x83, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
	0x3b, 0x3c, 0x3d, 0x83, 0x83, 0x83, 0x81, 0x83, 0x83, 0x83, 0x00,
	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
	0x17, 0x18, 0x19, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x1a, 0x1b,
	0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
	0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
	0x32, 0x33, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83
    };

    /*
     * Definitions for the base-64 decoder.
     */

#define PNG64_SPECIAL	0x80	/* Flag bit */
#define PNG64_SPACE	0x80	/* Whitespace */
#define PNG64_PAD	0x81	/* Padding */
#define PNG64_DONE	0x82	/* End of data */
#define PNG64_BAD	0x83	/* Ooooh, naughty! */

    while (destSz && pngPtr->strDataLen) {
	unsigned char c = 0;
	unsigned char c64 = from64[*pngPtr->strDataBuf++];

	pngPtr->strDataLen--;

	if (PNG64_SPACE == c64) {
	    continue;
	}

	if (c64 & PNG64_SPECIAL) {
	    c = (unsigned char) pngPtr->base64Bits;
	} else {
	    switch (pngPtr->base64State++) {
	    case 0:
		pngPtr->base64Bits = c64 << 2;
		continue;
	    case 1:
		c = (unsigned char) (pngPtr->base64Bits | (c64 >> 4));
		pngPtr->base64Bits = (c64 & 0xF) << 4;
		break;
	    case 2:
		c = (unsigned char) (pngPtr->base64Bits | (c64 >> 2));
		pngPtr->base64Bits = (c64 & 0x3) << 6;
		break;
	    case 3:
		c = (unsigned char) (pngPtr->base64Bits | c64);
		pngPtr->base64State = 0;
		pngPtr->base64Bits = 0;
		break;
	    }
	}

	if (crcPtr) {
	    *crcPtr = Tcl_ZlibCRC32(*crcPtr, &c, 1);
	}

	if (destPtr) {
	    *destPtr++ = c;
	}

	destSz--;

	if (c64 & PNG64_SPECIAL) {
	    break;
	}
    }

    if (destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadByteArray --
 *
 *	This function is invoked to read the specified number of bytes from a
 *	non-base64-encoded byte array provided via the -data option.
 *
 *	Note: It would be better if the Tk_PhotoImage stuff handled this by
 *	creating a channel from the -data value and made the data readable as
 *	if it were coming from a file.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs.
 *
 * Side effects:
 *	The file position will change. The running CRC is updated if a pointer
 *	to it is provided.
 *
 *----------------------------------------------------------------------
 */

static int
ReadByteArray(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    /*
     * Check to make sure the number of requested bytes are available.
     */

    if ((size_t)pngPtr->strDataLen < destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    while (destSz) {
	size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	memcpy(destPtr, pngPtr->strDataBuf, blockSz);

	pngPtr->strDataBuf += blockSz;
	pngPtr->strDataLen -= blockSz;

	if (crcPtr) {
	    *crcPtr = Tcl_ZlibCRC32(*crcPtr, destPtr, blockSz);
	}

	destPtr += blockSz;
	destSz -= blockSz;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadData --
 *
 *	This function is invoked to read the specified number of bytes from
 *	the image file or data. It is a wrapper around the choice of byte
 *	array Tcl_Obj or Tcl_Channel which depends on whether the image data
 *	is coming from a file or -data.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs.
 *
 * Side effects:
 *	The file position will change. The running CRC is updated if a pointer
 *	to it is provided.
 *
 *----------------------------------------------------------------------
 */

static int
ReadData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    if (pngPtr->base64Data) {
	return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr);
    } else if (pngPtr->strDataBuf) {
	return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr);
    }

    while (destSz) {
	TkSizeT blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == TCL_IO_FAILURE) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}

	/*
	 * Update CRC, pointer, and remaining count if anything was read.
	 */

	if (blockSz) {
	    if (crcPtr) {
		*crcPtr = Tcl_ZlibCRC32(*crcPtr, destPtr, blockSz);
	    }

	    destPtr += blockSz;
	    destSz -= blockSz;
	}

	/*
	 * Check for EOF before all desired data was read.
	 */

	if (destSz && Tcl_Eof(pngPtr->channel)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "unexpected end of file", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EOF", NULL);
	    return TCL_ERROR;
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadInt32 --
 *
 *	This function is invoked to read a 32-bit integer in network byte
 *	order from the image data and return the value in host byte order.
 *	This is used, for example, to read the 32-bit CRC value for a chunk
 *	stored in the image file for comparison with the calculated CRC value.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs.
 *
 * Side effects:
 *	The file position will change. The running CRC is updated if a pointer
 *	to it is provided.
 *
 *----------------------------------------------------------------------
 */

static inline int
ReadInt32(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long *resultPtr,
    unsigned long *crcPtr)
{
    unsigned char p[4];

    if (ReadData(interp, pngPtr, p, 4, crcPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    *resultPtr = PNG_INT32(p[0], p[1], p[2], p[3]);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckCRC --
 *
 *	This function is reads the final 4-byte integer CRC from a chunk and
 *	compares it to the running CRC calculated over the chunk type and data
 *	fields.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error or CRC mismatch occurs.
 *
 * Side effects:
 *	The file position will change.
 *
 *----------------------------------------------------------------------
 */

static inline int
CheckCRC(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long calculated)
{
    unsigned long chunked;

    /*
     * Read the CRC field at the end of the chunk.
     */

    if (ReadInt32(interp, pngPtr, &chunked, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Compare the read CRC to what we calculate to make sure they match.
     */

    if (calculated != chunked) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("CRC check failed", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "CRC", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SkipChunk --
 *
 *	This function is used to skip a PNG chunk that is not used by this
 *	implementation. Given the input stream has had the chunk length and
 *	chunk type fields already read, this function will read the number of
 *	bytes indicated by the chunk length, plus four for the CRC, and will
 *	verify that CRC is correct for the skipped data.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error or CRC mismatch occurs.
 *
 * Side effects:
 *	The file position will change.
 *
 *----------------------------------------------------------------------
 */

static int
SkipChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int chunkSz,
    unsigned long crc)
{
    unsigned char buffer[PNG_BLOCK_SZ];

    /*
     * Skip data in blocks until none is left. Read up to PNG_BLOCK_SZ bytes
     * at a time, rather than trusting the claimed chunk size, which may not
     * be trustworthy.
     */

    while (chunkSz) {
	int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ);

	if (ReadData(interp, pngPtr, buffer, blockSz, &crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	chunkSz -= blockSz;
    }

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 * 4.3. Summary of standard chunks
 *
 * This table summarizes some properties of the standard chunk types.
 *
 *	Critical chunks (must appear in this order, except PLTE is optional):
 *
 *		Name   Multiple	 Ordering constraints OK?
 *
 *		IHDR	No	 Must be first
 *		PLTE	No	 Before IDAT
 *		IDAT	Yes	 Multiple IDATs must be consecutive
 *		IEND	No	 Must be last
 *
 *	Ancillary chunks (need not appear in this order):
 *
 *		Name   Multiple	 Ordering constraints OK?
 *
 *		cHRM	No	 Before PLTE and IDAT
 *		gAMA	No	 Before PLTE and IDAT
 *		iCCP	No	 Before PLTE and IDAT
 *		sBIT	No	 Before PLTE and IDAT
 *		sRGB	No	 Before PLTE and IDAT
 *		bKGD	No	 After PLTE; before IDAT
 *		hIST	No	 After PLTE; before IDAT
 *		tRNS	No	 After PLTE; before IDAT
 *		pHYs	No	 Before IDAT
 *		sPLT	Yes	 Before IDAT
 *		tIME	No	 None
 *		iTXt	Yes	 None
 *		tEXt	Yes	 None
 *		zTXt	Yes	 None
 *
 *	[From the PNG specification.]
 */

/*
 *----------------------------------------------------------------------
 *
 * ReadChunkHeader --
 *
 *	This function is used at the start of each chunk to extract the
 *	four-byte chunk length and four-byte chunk type fields. It will
 *	continue reading until it finds a chunk type that is handled by this
 *	implementation, checking the CRC of any chunks it skips.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or an unknown critical
 *	chunk type is encountered.
 *
 * Side effects:
 *	The file position will change. The running CRC is updated.
 *
 *----------------------------------------------------------------------
 */

static int
ReadChunkHeader(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    size_t *sizePtr,
    unsigned long *typePtr,
    unsigned long *crcPtr)
{
    unsigned long chunkType = 0;
    int chunkSz = 0;
    unsigned long crc = 0;

    /*
     * Continue until finding a chunk type that is handled.
     */

    while (!chunkType) {
	unsigned long temp;
	unsigned char pc[4];
	int i;

	/*
	 * Read the 4-byte length field for the chunk. The length field is not
	 * included in the CRC calculation, so the running CRC must be reset
	 * afterward. Limit chunk lengths to INT_MAX, to align with the
	 * maximum size for Tcl_Read, Tcl_GetByteArrayFromObj, etc.
	 */

	if (ReadData(interp, pngPtr, pc, 4, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	temp = PNG_INT32(pc[0], pc[1], pc[2], pc[3]);

	if (temp > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "chunk size is out of supported range on this architecture",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "OUTSIZE", NULL);
	    return TCL_ERROR;
	}

	chunkSz = (int) temp;
	crc = Tcl_ZlibCRC32(0, NULL, 0);

	/*
	 * Read the 4-byte chunk type.
	 */

	if (ReadData(interp, pngPtr, pc, 4, &crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Convert it to a host-order integer for simple comparison.
	 */

	chunkType = PNG_INT32(pc[0], pc[1], pc[2], pc[3]);

	/*
	 * Check to see if this is a known/supported chunk type. Note that the
	 * PNG specs require non-critical (i.e., ancillary) chunk types that
	 * are not recognized to be ignored, rather than be treated as an
	 * error. It does, however, recommend that an unknown critical chunk
	 * type be treated as a failure.
	 *
	 * This switch/loop acts as a filter of sorts for undesired chunk
	 * types. The chunk type should still be checked elsewhere for
	 * determining it is in the correct order.
	 */

	switch (chunkType) {
	    /*
	     * These chunk types are required and/or supported.
	     */

	case CHUNK_IDAT:
	case CHUNK_IEND:
	case CHUNK_IHDR:
	case CHUNK_PLTE:
	case CHUNK_tRNS:
	    break;

	    /*
	     * These chunk types are part of the standard, but are not used by
	     * this implementation (at least not yet). Note that these are all
	     * ancillary chunks (lowercase first letter).
	     */

	case CHUNK_bKGD:
	case CHUNK_cHRM:
	case CHUNK_gAMA:
	case CHUNK_hIST:
	case CHUNK_iCCP:
	case CHUNK_iTXt:
	case CHUNK_oFFs:
	case CHUNK_pCAL:
	case CHUNK_pHYs:
	case CHUNK_sBIT:
	case CHUNK_sCAL:
	case CHUNK_sPLT:
	case CHUNK_sRGB:
	case CHUNK_tEXt:
	case CHUNK_tIME:
	case CHUNK_zTXt:
	    /*
	     * TODO: might want to check order here.
	     */

	    if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    chunkType = 0;
	    break;

	default:
	    /*
	     * Unknown chunk type. If it's critical, we can't continue.
	     */

	    if (!(chunkType & PNG_CF_ANCILLARY)) {
		if (chunkType & PNG_INT32(128,128,128,128)) {
		    /*
		     * No nice ASCII conversion; shouldn't happen either, but
		     * we'll be doubly careful.
		     */

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "encountered an unsupported critical chunk type",
			    -1));
		} else {
		    char typeString[5];

		    typeString[0] = (char) ((chunkType >> 24) & 255);
		    typeString[1] = (char) ((chunkType >> 16) & 255);
		    typeString[2] = (char) ((chunkType >> 8) & 255);
		    typeString[3] = (char) (chunkType & 255);
		    typeString[4] = '\0';
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "encountered an unsupported critical chunk type"
			    " \"%s\"", typeString));
		}
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
			"UNSUPPORTED_CRITICAL", NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Check to see if the chunk type has legal bytes.
	     */

	    for (i=0 ; i<4 ; i++) {
		if ((pc[i] < 65) || (pc[i] > 122) ||
			((pc[i] > 90) && (pc[i] < 97))) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "invalid chunk type", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
			    "INVALID_CHUNK", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
	     * It seems to be an otherwise legally labelled ancillary chunk
	     * that we don't want, so skip it after at least checking its CRC.
	     */

	    if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    chunkType = 0;
	}
    }

    /*
     * Found a known chunk type that's handled, albiet possibly not in the
     * right order. Send back the chunk type (for further checking or
     * handling), the chunk size and the current CRC for the rest of the
     * calculation.
     */

    *typePtr = chunkType;
    *sizePtr = chunkSz;
    *crcPtr = crc;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckColor --
 *
 *	Do validation on color type, depth, and related information, and
 *	calculates storage requirements and offsets based on image dimensions
 *	and color.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if color information is invalid or some other
 *	failure occurs.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
CheckColor(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    int offset;

    /*
     * Verify the color type is valid and the bit depth is allowed.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
	pngPtr->numChannels = 1;
	if ((1 != pngPtr->bitDepth) && (2 != pngPtr->bitDepth) &&
		(4 != pngPtr->bitDepth) && (8 != pngPtr->bitDepth) &&
		(16 != pngPtr->bitDepth)) {
	    goto unsupportedDepth;
	}
	break;

    case PNG_COLOR_RGB:
	pngPtr->numChannels = 3;
	if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) {
	    goto unsupportedDepth;
	}
	break;

    case PNG_COLOR_PLTE:
	pngPtr->numChannels = 1;
	if ((1 != pngPtr->bitDepth) && (2 != pngPtr->bitDepth) &&
		(4 != pngPtr->bitDepth) && (8 != pngPtr->bitDepth)) {
	    goto unsupportedDepth;
	}
	break;

    case PNG_COLOR_GRAYALPHA:
	pngPtr->numChannels = 2;
	if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) {
	    goto unsupportedDepth;
	}
	break;

    case PNG_COLOR_RGBA:
	pngPtr->numChannels = 4;
	if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) {
	unsupportedDepth:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "bit depth is not allowed for given color type", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_DEPTH", NULL);
	    return TCL_ERROR;
	}
	break;

    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown color type field %d", pngPtr->colorType));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "UNKNOWN_COLOR", NULL);
	return TCL_ERROR;
    }

    /*
     * Set up the Tk photo block's pixel size and channel offsets. offset
     * array elements should already be 0 from the memset during InitPNGImage.
     */

    offset = (pngPtr->bitDepth > 8) ? 2 : 1;

    if (pngPtr->colorType & PNG_COLOR_USED) {
	pngPtr->block.pixelSize = offset * 4;
	pngPtr->block.offset[1] = offset;
	pngPtr->block.offset[2] = offset * 2;
	pngPtr->block.offset[3] = offset * 3;
    } else {
	pngPtr->block.pixelSize = offset * 2;
	pngPtr->block.offset[3] = offset;
    }

    /*
     * Calculate the block pitch, which is the number of bytes per line in the
     * image, given image width and depth of color. Make sure that it it isn't
     * larger than Tk can handle.
     */

    if (pngPtr->block.width > INT_MAX / pngPtr->block.pixelSize) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image pitch is out of supported range on this architecture",
		-1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PITCH", NULL);
	return TCL_ERROR;
    }

    pngPtr->block.pitch = pngPtr->block.pixelSize * pngPtr->block.width;

    /*
     * Calculate the total size of the image as represented to Tk given pitch
     * and image height. Make sure that it isn't larger than Tk can handle.
     */

    if (pngPtr->block.height > INT_MAX / pngPtr->block.pitch) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image total size is out of supported range on this architecture",
		-1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "SIZE", NULL);
	return TCL_ERROR;
    }

    pngPtr->blockLen = pngPtr->block.height * pngPtr->block.pitch;

    /*
     * Determine number of bytes per pixel in the source for later use.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
	pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 2 : 1;
	break;
    case PNG_COLOR_RGB:
	pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 6 : 3;
	break;
    case PNG_COLOR_PLTE:
	pngPtr->bytesPerPixel = 1;
	break;
    case PNG_COLOR_GRAYALPHA:
	pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 4 : 2;
	break;
    case PNG_COLOR_RGBA:
	pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 8 : 4;
	break;
    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown color type %d", pngPtr->colorType));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "UNKNOWN_COLOR", NULL);
	return TCL_ERROR;
    }

    /*
     * Calculate scale factor for bit depths less than 8, in order to adjust
     * them to a minimum of 8 bits per pixel in the Tk image.
     */

    if (pngPtr->bitDepth < 8) {
	pngPtr->bitScale = 255 / (int)(pow(2, pngPtr->bitDepth) - 1);
    } else {
	pngPtr->bitScale = 1;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadIHDR --
 *
 *	This function reads the PNG header from the beginning of a PNG file
 *	and returns the dimensions of the image.
 *
 * Results:
 *	The return value is 1 if file "f" appears to start with a valid PNG
 *	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.
 *
 *----------------------------------------------------------------------
 */

static int
ReadIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char sigBuf[PNG_SIG_SZ];
    unsigned long chunkType;
    size_t chunkSz;
    unsigned long crc;
    unsigned long width, height;
    int mismatch;

    /*
     * Read the appropriate number of bytes for the PNG signature.
     */

    if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Compare the read bytes to the expected signature.
     */

    mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);

    /*
     * If reading from string, reset position and try base64 decode.
     */

    if (mismatch && pngPtr->strDataBuf) {
	pngPtr->strDataBuf = TkGetByteArrayFromObj(pngPtr->objDataPtr,
		&pngPtr->strDataLen);
	pngPtr->base64Data = pngPtr->strDataBuf;

	if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);
    }

    if (mismatch) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"data stream does not have a PNG signature", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_SIG", NULL);
	return TCL_ERROR;
    }

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Read in the IHDR (header) chunk for width, height, etc.
     *
     * The first chunk in the file must be the IHDR (headr) chunk.
     */

    if (chunkType != CHUNK_IHDR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"expected IHDR chunk type", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_IHDR", NULL);
	return TCL_ERROR;
    }

    if (chunkSz != 13) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid IHDR chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IHDR", NULL);
	return TCL_ERROR;
    }

    /*
     * Read and verify the image width and height to be sure Tk can handle its
     * dimensions. The PNG specification does not permit zero-width or
     * zero-height images.
     */

    if (ReadInt32(interp, pngPtr, &width, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (ReadInt32(interp, pngPtr, &height, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (!width || !height || (width > INT_MAX) || (height > INT_MAX)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image dimensions are invalid or beyond architecture limits",
		-1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DIMENSIONS", NULL);
	return TCL_ERROR;
    }

    /*
     * Set height and width for the Tk photo block.
     */

    pngPtr->block.width = (int) width;
    pngPtr->block.height = (int) height;

    /*
     * Read and the Bit Depth and Color Type.
     */

    if (ReadData(interp, pngPtr, &pngPtr->bitDepth, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (ReadData(interp, pngPtr, &pngPtr->colorType, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Verify that the color type is valid, the bit depth is allowed for the
     * color type, and calculate the number of channels and pixel depth (bits
     * per pixel * channels). Also set up offsets and sizes in the Tk photo
     * block for the pixel data.
     */

    if (CheckColor(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Only one compression method is currently defined by the standard.
     */

    if (ReadData(interp, pngPtr, &pngPtr->compression, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (pngPtr->compression != PNG_COMPRESS_DEFLATE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown compression method %d", pngPtr->compression));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_COMPRESS", NULL);
	return TCL_ERROR;
    }

    /*
     * Only one filter method is currently defined by the standard; the method
     * has five actual filter types associated with it.
     */

    if (ReadData(interp, pngPtr, &pngPtr->filter, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (pngPtr->filter != PNG_FILTMETH_STANDARD) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown filter method %d", pngPtr->filter));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_FILTER", NULL);
	return TCL_ERROR;
    }

    if (ReadData(interp, pngPtr, &pngPtr->interlace, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    switch (pngPtr->interlace) {
    case PNG_INTERLACE_NONE:
    case PNG_INTERLACE_ADAM7:
	break;

    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown interlace method %d", pngPtr->interlace));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_INTERLACE", NULL);
	return TCL_ERROR;
    }

    return CheckCRC(interp, pngPtr, crc);
}

/*
 *----------------------------------------------------------------------
 *
 * ReadPLTE --
 *
 *	This function reads the PLTE (indexed color palette) chunk data from
 *	the PNG file and populates the palette table in the PNGImage
 *	structure.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or the PLTE chunk is
 *	invalid.
 *
 * Side effects:
 *	The access position in f advances.
 *
 *----------------------------------------------------------------------
 */

static int
ReadPLTE(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int chunkSz,
    unsigned long crc)
{
    unsigned char buffer[PNG_PLTE_MAXSZ];
    int i, c;

    /*
     * This chunk is mandatory for color type 3 and forbidden for 2 and 6.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
    case PNG_COLOR_GRAYALPHA:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk type forbidden for grayscale", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PLTE_UNEXPECTED",
		NULL);
	return TCL_ERROR;

    default:
	break;
    }

    /*
     * The palette chunk contains from 1 to 256 palette entries. Each entry
     * consists of a 3-byte RGB value. It must therefore contain a non-zero
     * multiple of 3 bytes, up to 768.
     */

    if (!chunkSz || (chunkSz > PNG_PLTE_MAXSZ) || (chunkSz % 3)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid palette chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * Read the palette contents and stash them for later, possibly.
     */

    if (ReadData(interp, pngPtr, buffer, chunkSz, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Stash away the palette entries and entry count for later mapping each
     * pixel's palette index to its color.
     */

    for (i=0, c=0 ; c<chunkSz ; i++) {
	pngPtr->palette[i].red = buffer[c++];
	pngPtr->palette[i].green = buffer[c++];
	pngPtr->palette[i].blue = buffer[c++];
    }

    pngPtr->paletteLen = i;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadTRNS --
 *
 *	This function reads the tRNS (transparency) chunk data from the PNG
 *	file and populates the alpha field of the palette table in the
 *	PNGImage structure or the single color transparency, as appropriate
 *	for the color type.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or the tRNS chunk is
 *	invalid.
 *
 * Side effects:
 *	The access position in f advances.
 *
 *----------------------------------------------------------------------
 */

static int
ReadTRNS(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int chunkSz,
    unsigned long crc)
{
    unsigned char buffer[PNG_TRNS_MAXSZ];
    int i;

    if (pngPtr->colorType & PNG_COLOR_ALPHA) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"tRNS chunk not allowed color types with a full alpha channel",
		-1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "INVALID_TRNS", NULL);
	return TCL_ERROR;
    }

    /*
     * For indexed color, there is up to one single-byte transparency value
     * per palette entry (thus a max of 256).
     */

    if (chunkSz > PNG_TRNS_MAXSZ) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid tRNS chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	return TCL_ERROR;
    }

    /*
     * Read in the raw transparency information.
     */

    if (ReadData(interp, pngPtr, buffer, chunkSz, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAYALPHA:
    case PNG_COLOR_RGBA:
	break;

    case PNG_COLOR_PLTE:
	/*
	 * The number of tRNS entries must be less than or equal to the number
	 * of PLTE entries, and consists of a single-byte alpha level for the
	 * corresponding PLTE entry.
	 */

	if (chunkSz > pngPtr->paletteLen) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "size of tRNS chunk is too large for the palette", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TRNS_SIZE", NULL);
	    return TCL_ERROR;
	}

	for (i=0 ; i<chunkSz ; i++) {
	    pngPtr->palette[i].alpha = buffer[i];
	}
	break;

    case PNG_COLOR_GRAY:
	/*
	 * Grayscale uses a single 2-byte gray level, which we'll store in
	 * palette index 0, since we're not using the palette.
	 */

	if (chunkSz != 2) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid tRNS chunk size - must 2 bytes for grayscale",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	    return TCL_ERROR;
	}

	/*
	 * According to the PNG specs, if the bit depth is less than 16, then
	 * only the lower byte is used.
	 */

	if (16 == pngPtr->bitDepth) {
	    pngPtr->transVal[0] = buffer[0];
	    pngPtr->transVal[1] = buffer[1];
	} else {
	    pngPtr->transVal[0] = buffer[1];
	}
	pngPtr->useTRNS = 1;
	break;

    case PNG_COLOR_RGB:
	/*
	 * TrueColor uses a single RRGGBB triplet.
	 */

	if (chunkSz != 6) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid tRNS chunk size - must 6 bytes for RGB", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	    return TCL_ERROR;
	}

	/*
	 * According to the PNG specs, if the bit depth is less than 16, then
	 * only the lower byte is used. But the tRNS chunk still contains two
	 * bytes per channel.
	 */

	if (16 == pngPtr->bitDepth) {
	    memcpy(pngPtr->transVal, buffer, 6);
	} else {
	    pngPtr->transVal[0] = buffer[1];
	    pngPtr->transVal[1] = buffer[3];
	    pngPtr->transVal[2] = buffer[5];
	}
	pngPtr->useTRNS = 1;
	break;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Paeth --
 *
 *	Utility function for applying the Paeth filter to a pixel. The Paeth
 *	filter is a linear function of the pixel to be filtered and the pixels
 *	to the left, above, and above-left of the pixel to be unfiltered.
 *
 * Results:
 *	Result of the Paeth function for the left, above, and above-left
 *	pixels.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static inline unsigned char
Paeth(
    int a,
    int b,
    int c)
{
    int pa = abs(b - c);
    int pb = abs(a - c);
    int pc = abs(a + b - c - c);

    if ((pa <= pb) && (pa <= pc)) {
	return (unsigned char) a;
    }

    if (pb <= pc) {
	return (unsigned char) b;
    }

    return (unsigned char) c;
}

/*
 *----------------------------------------------------------------------
 *
 * UnfilterLine --
 *
 *	Applies the filter algorithm specified in first byte of a line to the
 *	line of pixels being read from a PNG image.
 *
 *	PNG specifies four filter algorithms (Sub, Up, Average, and Paeth)
 *	that combine a pixel's value with those of other pixels in the same
 *	and/or previous lines. Filtering is intended to make an image more
 *	compressible.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the filter type is not recognized.
 *
 * Side effects:
 *	Pixel data in thisLineObj are modified.
 *
 *----------------------------------------------------------------------
 */

static int
UnfilterLine(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char *thisLine =
	    Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL);
    unsigned char *lastLine =
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, NULL);

#define	PNG_FILTER_NONE		0
#define	PNG_FILTER_SUB		1
#define	PNG_FILTER_UP		2
#define	PNG_FILTER_AVG		3
#define	PNG_FILTER_PAETH	4

    switch (*thisLine) {
    case PNG_FILTER_NONE:	/* Nothing to do */
	break;
    case PNG_FILTER_SUB: {	/* Sub(x) = Raw(x) - Raw(x-bpp) */
	unsigned char *rawBpp = thisLine + 1;
	unsigned char *raw = rawBpp + pngPtr->bytesPerPixel;
	unsigned char *end = thisLine + pngPtr->phaseSize;

	while (raw < end) {
	    *raw++ += *rawBpp++;
	}
	break;
    }
    case PNG_FILTER_UP:		/* Up(x) = Raw(x) - Prior(x) */
	if (pngPtr->currentLine > startLine[pngPtr->phase]) {
	    unsigned char *prior = lastLine + 1;
	    unsigned char *raw = thisLine + 1;
	    unsigned char *end = thisLine + pngPtr->phaseSize;

	    while (raw < end) {
		*raw++ += *prior++;
	    }
	}
	break;
    case PNG_FILTER_AVG:
	/* Avg(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2) */
	if (pngPtr->currentLine > startLine[pngPtr->phase]) {
	    unsigned char *prior = lastLine + 1;
	    unsigned char *rawBpp = thisLine + 1;
	    unsigned char *raw = rawBpp;
	    unsigned char *end = thisLine + pngPtr->phaseSize;
	    unsigned char *end2 = raw + pngPtr->bytesPerPixel;

	    while ((raw < end2) && (raw < end)) {
		*raw++ += *prior++ / 2;
	    }

	    while (raw < end) {
		*raw++ += (unsigned char)
			(((int) *rawBpp++ + (int) *prior++) / 2);
	    }
	} else {
	    unsigned char *rawBpp = thisLine + 1;
	    unsigned char *raw = rawBpp + pngPtr->bytesPerPixel;
	    unsigned char *end = thisLine + pngPtr->phaseSize;

	    while (raw < end) {
		*raw++ += *rawBpp++ / 2;
	    }
	}
	break;
    case PNG_FILTER_PAETH:
	/* Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp)) */
	if (pngPtr->currentLine > startLine[pngPtr->phase]) {
	    unsigned char *priorBpp = lastLine + 1;
	    unsigned char *prior = priorBpp;
	    unsigned char *rawBpp = thisLine + 1;
	    unsigned char *raw = rawBpp;
	    unsigned char *end = thisLine + pngPtr->phaseSize;
	    unsigned char *end2 = rawBpp + pngPtr->bytesPerPixel;

	    while ((raw < end) && (raw < end2)) {
		*raw++ += *prior++;
	    }

	    while (raw < end) {
		*raw++ += Paeth(*rawBpp++, *prior++, *priorBpp++);
	    }
	} else {
	    unsigned char *rawBpp = thisLine + 1;
	    unsigned char *raw = rawBpp + pngPtr->bytesPerPixel;
	    unsigned char *end = thisLine + pngPtr->phaseSize;

	    while (raw < end) {
		*raw++ += *rawBpp++;
	    }
	}
	break;
    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid filter type %d", *thisLine));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_FILTER", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DecodeLine --
 *
 *	Unfilters a line of pixels from the PNG source data and decodes the
 *	data into the Tk_PhotoImageBlock for later copying into the Tk image.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the filter type is not recognized.
 *
 * Side effects:
 *	Pixel data in thisLine and block are modified and state information
 *	updated.
 *
 *----------------------------------------------------------------------
 */

static int
DecodeLine(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char *pixelPtr = pngPtr->block.pixelPtr;
    int colNum = 0;		/* Current pixel column */
    unsigned char chan = 0;	/* Current channel (0..3) = (R, G, B, A) */
    unsigned char readByte = 0;	/* Current scan line byte */
    int haveBits = 0;		/* Number of bits remaining in current byte */
    unsigned char pixBits = 0;	/* Extracted bits for current channel */
    int shifts = 0;		/* Number of channels extracted from byte */
    int offset = 0;		/* Current offset into pixelPtr */
    int colStep = 1;		/* Column increment each pass */
    int pixStep = 0;		/* extra pixelPtr increment each pass */
    unsigned char lastPixel[6];
    unsigned char *p = Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL);

    p++;
    if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (pngPtr->currentLine >= pngPtr->block.height) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PNG image data overflow"));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DATA_OVERFLOW", NULL);
	return TCL_ERROR;
    }


    if (pngPtr->interlace) {
	switch (pngPtr->phase) {
	case 1:			/* Phase 1: */
	    colStep = 8;	/* 1 pixel per block of 8 per line */
	    break;		/* Start at column 0 */
	case 2:			/* Phase 2: */
	    colStep = 8;	/* 1 pixels per block of 8 per line */
	    colNum = 4;		/* Start at column 4 */
	    break;
	case 3:			/* Phase 3: */
	    colStep = 4;	/* 2 pixels per block of 8 per line */
	    break;		/* Start at column 0 */
	case 4:			/* Phase 4: */
	    colStep = 4;	/* 2 pixels per block of 8 per line */
	    colNum = 2;		/* Start at column 2 */
	    break;
	case 5:			/* Phase 5: */
	    colStep = 2;	/* 4 pixels per block of 8 per line */
	    break;		/* Start at column 0 */
	case 6:			/* Phase 6: */
	    colStep = 2;	/* 4 pixels per block of 8 per line */
	    colNum = 1;		/* Start at column 1 */
	    break;
				/* Phase 7: */
				/* 8 pixels per block of 8 per line */
				/* Start at column 0 */
	}
    }

    /*
     * Calculate offset into pixelPtr for the first pixel of the line.
     */

    offset = pngPtr->currentLine * pngPtr->block.pitch;

    /*
     * Adjust up for the starting pixel of the line.
     */

    offset += colNum * pngPtr->block.pixelSize;

    /*
     * Calculate the extra number of bytes to skip between columns.
     */

    pixStep = (colStep - 1) * pngPtr->block.pixelSize;

    for ( ; colNum < pngPtr->block.width ; colNum += colStep) {
	if (haveBits < (pngPtr->bitDepth * pngPtr->numChannels)) {
	    haveBits = 0;
	}

	for (chan = 0 ; chan < pngPtr->numChannels ; chan++) {
	    if (!haveBits) {
		shifts = 0;
		readByte = *p++;
		haveBits += 8;
	    }

	    if (16 == pngPtr->bitDepth) {
		pngPtr->block.pixelPtr[offset++] = readByte;

		if (pngPtr->useTRNS) {
		    lastPixel[chan * 2] = readByte;
		}

		readByte = *p++;

		if (pngPtr->useTRNS) {
		    lastPixel[(chan * 2) + 1] = readByte;
		}

		pngPtr->block.pixelPtr[offset++] = readByte;

		haveBits = 0;
		continue;
	    }

	    switch (pngPtr->bitDepth) {
	    case 1:
		pixBits = (unsigned char)((readByte >> (7-shifts)) & 0x01);
		break;
	    case 2:
		pixBits = (unsigned char)((readByte >> (6-shifts*2)) & 0x03);
		break;
	    case 4:
		pixBits = (unsigned char)((readByte >> (4-shifts*4)) & 0x0f);
		break;
	    case 8:
		pixBits = readByte;
		break;
	    }

	    if (PNG_COLOR_PLTE == pngPtr->colorType) {
		pixelPtr[offset++] = pngPtr->palette[pixBits].red;
		pixelPtr[offset++] = pngPtr->palette[pixBits].green;
		pixelPtr[offset++] = pngPtr->palette[pixBits].blue;
		pixelPtr[offset++] = pngPtr->palette[pixBits].alpha;
		chan += 2;
	    } else {
		pixelPtr[offset++] = (unsigned char)
			(pixBits * pngPtr->bitScale);

		if (pngPtr->useTRNS) {
		    lastPixel[chan] = pixBits;
		}
	    }

	    haveBits -= pngPtr->bitDepth;
	    shifts++;
	}

	/*
	 * Apply boolean transparency via tRNS data if necessary (where
	 * necessary means a tRNS chunk was provided and we're not using an
	 * alpha channel or indexed alpha).
	 */

	if ((PNG_COLOR_PLTE != pngPtr->colorType) &&
		!(pngPtr->colorType & PNG_COLOR_ALPHA)) {
	    unsigned char alpha;

	    if (pngPtr->useTRNS) {
		if (memcmp(lastPixel, pngPtr->transVal,
			pngPtr->bytesPerPixel) == 0) {
		    alpha = 0x00;
		} else {
		    alpha = 0xff;
		}
	    } else {
		alpha = 0xff;
	    }

	    pixelPtr[offset++] = alpha;

	    if (16 == pngPtr->bitDepth) {
		pixelPtr[offset++] = alpha;
	    }
	}

	offset += pixStep;
    }

    if (pngPtr->interlace) {
	/* Skip lines */

	switch (pngPtr->phase) {
	case 1: case 2: case 3:
	    pngPtr->currentLine += 8;
	    break;
	case 4: case 5:
	    pngPtr->currentLine += 4;
	    break;
	case 6: case 7:
	    pngPtr->currentLine += 2;
	    break;
	}

	/*
	 * Start the next phase if there are no more lines to do.
	 */

	if (pngPtr->currentLine >= pngPtr->block.height) {
	    unsigned long pixels = 0;

	    while ((!pixels || (pngPtr->currentLine >= pngPtr->block.height))
		    && (pngPtr->phase < 7)) {
		pngPtr->phase++;

		switch (pngPtr->phase) {
		case 2:
		    pixels = (pngPtr->block.width + 3) >> 3;
		    pngPtr->currentLine = 0;
		    break;
		case 3:
		    pixels = (pngPtr->block.width + 3) >> 2;
		    pngPtr->currentLine = 4;
		    break;
		case 4:
		    pixels = (pngPtr->block.width + 1) >> 2;
		    pngPtr->currentLine = 0;
		    break;
		case 5:
		    pixels = (pngPtr->block.width + 1) >> 1;
		    pngPtr->currentLine = 2;
		    break;
		case 6:
		    pixels = pngPtr->block.width >> 1;
		    pngPtr->currentLine = 0;
		    break;
		case 7:
		    pngPtr->currentLine = 1;
		    pixels = pngPtr->block.width;
		    break;
		}
	    }

	    if (16 == pngPtr->bitDepth) {
		pngPtr->phaseSize = 1 + (pngPtr->numChannels * pixels * 2);
	    } else {
		pngPtr->phaseSize = 1 + ((pngPtr->numChannels * pixels *
			pngPtr->bitDepth + 7) >> 3);
	    }
	}
    } else {
	pngPtr->currentLine++;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadIDAT --
 *
 *	This function reads the IDAT (pixel data) chunk from the PNG file to
 *	build the image. It will continue reading until all IDAT chunks have
 *	been processed or an error occurs.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or an IDAT chunk is
 *	invalid.
 *
 * Side effects:
 *	The access position in f advances. Memory may be allocated by zlib
 *	through PNGZAlloc.
 *
 *----------------------------------------------------------------------
 */

static int
ReadIDAT(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int chunkSz,
    unsigned long crc)
{
    /*
     * Process IDAT contents until there is no more in this chunk.
     */

    while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
	TkSizeT len1, len2;

	/*
	 * Read another block of input into the zlib stream if data remains.
	 */

	if (chunkSz) {
	    Tcl_Obj *inputObj = NULL;
	    int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ);
	    unsigned char *inputPtr = NULL;

	    /*
	     * Check for end of zlib stream.
	     */

	    if (Tcl_ZlibStreamEof(pngPtr->stream)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after end of zlib stream", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
	    }

	    inputObj = Tcl_NewObj();
	    Tcl_IncrRefCount(inputObj);
	    inputPtr = Tcl_SetByteArrayLength(inputObj, blockSz);

	    /*
	     * Read the next bit of IDAT chunk data, up to read buffer size.
	     */

	    if (ReadData(interp, pngPtr, inputPtr, blockSz,
		    &crc) == TCL_ERROR) {
		Tcl_DecrRefCount(inputObj);
		return TCL_ERROR;
	    }

	    chunkSz -= blockSz;

	    Tcl_ZlibStreamPut(pngPtr->stream, inputObj, TCL_ZLIB_NO_FLUSH);
	    Tcl_DecrRefCount(inputObj);
	}

	/*
	 * Inflate, processing each output buffer's worth as a line of pixels,
	 * until we cannot fill the buffer any more.
	 */

    getNextLine:
	TkGetByteArrayFromObj(pngPtr->thisLineObj, &len1);
	if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj,
		pngPtr->phaseSize - len1) == TCL_ERROR) {
	    return TCL_ERROR;
	}
	TkGetByteArrayFromObj(pngPtr->thisLineObj, &len2);

	if (len2 == (TkSizeT)pngPtr->phaseSize) {
	    if (pngPtr->phase > 7) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after final scan line of final phase",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
	    }

	    if (DecodeLine(interp, pngPtr) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    /*
	     * Swap the current/last lines so that we always have the last
	     * line processed available, which is necessary for filtering.
	     */

	    {
		Tcl_Obj *temp = pngPtr->lastLineObj;

		pngPtr->lastLineObj = pngPtr->thisLineObj;
		pngPtr->thisLineObj = temp;
	    }
	    Tcl_SetByteArrayLength(pngPtr->thisLineObj, 0);

	    /*
	     * Try to read another line of pixels out of the buffer
	     * immediately, but don't allow write past end of block.
	     */

	    if (pngPtr->currentLine < pngPtr->block.height) {
		goto getNextLine;
	    }

	}

	/*
	 * Got less than a whole buffer-load of pixels. Either we're going to
	 * be getting more data from the next IDAT, or we've done what we can
	 * here.
	 */
    }

    /*
     * Ensure that if we've got to the end of the compressed data, we've
     * also got to the end of the compressed stream. This sanity check is
     * enforced by most PNG readers.
     */

    if (chunkSz != 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"compressed data after stream finalize in PNG data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    return CheckCRC(interp, pngPtr, crc);
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyAlpha --
 *
 *	Applies an overall alpha value to a complete image that has been read.
 *	This alpha value is specified using the -format option to [image
 *	create photo].
 *
 * Results:
 *	N/A
 *
 * Side effects:
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static void
ApplyAlpha(
    PNGImage *pngPtr)
{
    if (pngPtr->alpha != 1.0) {
	unsigned char *p = pngPtr->block.pixelPtr;
	unsigned char *endPtr = p + pngPtr->blockLen;
	int offset = pngPtr->block.offset[3];

	p += offset;

	if (16 == pngPtr->bitDepth) {
	    unsigned int channel;

	    while (p < endPtr) {
		channel = (unsigned int)
			(((p[0] << 8) | p[1]) * pngPtr->alpha);

		*p++ = (unsigned char) (channel >> 8);
		*p++ = (unsigned char) (channel & 0xff);

		p += offset;
	    }
	} else {
	    while (p < endPtr) {
		p[0] = (unsigned char) (pngPtr->alpha * p[0]);
		p += 1 + offset;
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ParseFormat --
 *
 *	This function parses the -format string that can be specified to the
 *	[image create photo] command to extract options for postprocessing of
 *	loaded images. Currently, this just allows specifying and applying an
 *	overall alpha value to the loaded image (for example, to make it
 *	entirely 50% as transparent as the actual image file).
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the format specification is invalid.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
ParseFormat(
    Tcl_Interp *interp,
    Tcl_Obj *fmtObj,
    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptionsEnum {
	OPT_ALPHA
    };

    /*
     * Extract elements of format specification as a list.
     */

    if (fmtObj &&
	    Tcl_ListObjGetElements(interp, fmtObj, &objc, &objv) != TCL_OK) {
	return TCL_ERROR;
    }

    for (; objc>0 ; objc--, objv++) {
	int optIndex;

	/*
	 * Ignore the "png" part of the format specification.
	 */

	if (!strcasecmp(Tcl_GetString(objv[0]), "png")) {
	    continue;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions,
		sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	if (objc < 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    return TCL_ERROR;
	}

	objc--;
	objv++;

	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_ALPHA:
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-alpha value must be between 0.0 and 1.0", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_ALPHA",
			NULL);
		return TCL_ERROR;
	    }
	    break;
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DecodePNG --
 *
 *	This function handles the entirety of reading a PNG file (or data)
 *	from the first byte to the last.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or any problems are
 *	detected in the PNG file.
 *
 * Side effects:
 *	The access position in f advances. Memory may be allocated and image
 *	dimensions and contents may change.
 *
 *----------------------------------------------------------------------
 */

static int
DecodePNG(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY)
{
    unsigned long chunkType;
    size_t chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Extract alpha value from -format object, if specified.
     */

    if (ParseFormat(interp, fmtObj, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * The next chunk may either be a PLTE (Palette) chunk or the first of at
     * least one IDAT (data) chunks. It could also be one of a number of
     * ancillary chunks, but those are skipped for us by the switch in
     * ReadChunkHeader().
     *
     * PLTE is mandatory for color type 3 and forbidden for 2 and 6
     */

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (CHUNK_PLTE == chunkType) {
	/*
	 * Finish parsing the PLTE chunk.
	 */

	if (ReadPLTE(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    } else if (PNG_COLOR_PLTE == pngPtr->colorType) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk required for indexed color", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * The next chunk may be a tRNS (palette transparency) chunk, depending on
     * the color type. It must come after the PLTE chunk and before the IDAT
     * chunk, but can be present if there is no PLTE chunk because it can be
     * used for Grayscale and TrueColor in lieu of an alpha channel.
     */

    if (CHUNK_tRNS == chunkType) {
	/*
	 * Finish parsing the tRNS chunk.
	 */

	if (ReadTRNS(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    /*
     * Other ancillary chunk types could appear here, but for now we're only
     * interested in IDAT. The others should have been skipped.
     */

    if (chunkType != CHUNK_IDAT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"at least one IDAT chunk is required", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_IDAT", NULL);
	return TCL_ERROR;
    }

    /*
     * Expand the photo size (if not set by the user) to provide enough space
     * for the image being parsed. It does not matter if width or height wrap
     * to negative here: Tk will not shrink the image.
     */

    if (Tk_PhotoExpand(interp, imageHandle, destX + pngPtr->block.width,
	    destY + pngPtr->block.height) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * A scan line consists of one byte for a filter type, plus the number of
     * bits per color sample times the number of color samples per pixel.
     */

    if (pngPtr->block.width > ((INT_MAX - 1) / (pngPtr->numChannels * 2))) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"line size is out of supported range on this architecture",
		-1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "LINE_SIZE", NULL);
	return TCL_ERROR;
    }

    if (16 == pngPtr->bitDepth) {
	pngPtr->lineSize = 1 + (pngPtr->numChannels * pngPtr->block.width*2);
    } else {
	pngPtr->lineSize = 1 + ((pngPtr->numChannels * pngPtr->block.width) /
		(8 / pngPtr->bitDepth));
	if (pngPtr->block.width % (8 / pngPtr->bitDepth)) {
	    pngPtr->lineSize++;
	}
    }

    /*
     * Allocate space for decoding the scan lines.
     */

    pngPtr->lastLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    pngPtr->block.pixelPtr = (unsigned char *)attemptckalloc(pngPtr->blockLen);
    if (!pngPtr->block.pixelPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"memory allocation failed", -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	return TCL_ERROR;
    }

    /*
     * Determine size of the first phase if interlaced. Phase size should
     * always be <= line size, so probably not necessary to check for
     * arithmetic overflow here: should be covered by line size check.
     */

    if (pngPtr->interlace) {
	/*
	 * Only one pixel per block of 8 per line in the first phase.
	 */

	unsigned int pixels = (pngPtr->block.width + 7) >> 3;

	pngPtr->phase = 1;
	if (16 == pngPtr->bitDepth) {
	    pngPtr->phaseSize = 1 + pngPtr->numChannels*pixels*2;
	} else {
	    pngPtr->phaseSize = 1 +
		    ((pngPtr->numChannels*pixels*pngPtr->bitDepth + 7) >> 3);
	}
    } else {
	pngPtr->phaseSize = pngPtr->lineSize;
    }

    /*
     * All of the IDAT (data) chunks must be consecutive.
     */

    while (CHUNK_IDAT == chunkType) {
	if (ReadIDAT(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    /*
     * Ensure that we've got to the end of the compressed stream now that
     * there are no more IDAT segments. This sanity check is enforced by most
     * PNG readers.
     */

    if (!Tcl_ZlibStreamEof(pngPtr->stream)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unfinalized data stream in PNG data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    /*
     * Now skip the remaining chunks which we're also not interested in.
     */

    while (CHUNK_IEND != chunkType) {
	if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    /*
     * Got the IEND (end of image) chunk. Do some final checks...
     */

    if (chunkSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"IEND chunk contents must be empty", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }

    /*
     * Check the CRC on the IEND chunk.
     */

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * TODO: verify that nothing else comes after the IEND chunk, or do we
     * really care?
     */

#if 0
    if (ReadData(interp, pngPtr, &c, 1, NULL) != TCL_ERROR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra data following IEND chunk", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }
#endif

    /*
     * Apply overall image alpha if specified.
     */

    ApplyAlpha(pngPtr);

    /*
     * Copy the decoded image block into the Tk photo image.
     */

    if (Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY,
	    pngPtr->block.width, pngPtr->block.height,
	    TK_PHOTO_COMPOSITE_SET) == TCL_ERROR) {
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FileMatchPNG --
 *
 *	This function is invoked by the photo image type to see if a file
 *	contains image data in PNG format.
 *
 * Results:
 *	The return value is 1 if the first characters in file f look like PNG
 *	data, and 0 otherwise.
 *
 * Side effects:
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchPNG(
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,
    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;
    (void)fileName;
    (void)fmtObj;

    InitPNGImage(NULL, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
    }

    CleanupPNGImage(&png);

    return match;
}

/*
 *----------------------------------------------------------------------
 *
 * FileReadPNG --
 *
 *	This function is called by the photo image type to read PNG 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.
 *
 * Side effects:
 *	The access position in file f is changed, and new data is added to the
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadPNG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY,
    int width,
    int height,
    int srcX,
    int srcY)
{
    PNGImage png;
    int result = TCL_ERROR;
    (void)fileName;
    (void)width;
    (void)height;
    (void)srcX;
    (void)srcY;

    result = InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchPNG --
 *
 *	This function is invoked by the photo image type to see if an object
 *	contains image data in PNG format.
 *
 * Results:
 *	The return value is 1 if the first characters in the data are like PNG
 *	data, and 0 otherwise.
 *
 * Side effects:
 *	The size of the image is placed in widthPre and heightPtr.
 *
 *----------------------------------------------------------------------
 */

static int
StringMatchPNG(
    Tcl_Obj *pObjData,
    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,
    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;
    (void)fmtObj;

    InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE);

    png.strDataBuf = TkGetByteArrayFromObj(pObjData, &png.strDataLen);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
    }

    CleanupPNGImage(&png);
    return match;
}

/*
 *----------------------------------------------------------------------
 *
 * StringReadPNG --
 *
 *	This function is called by the photo image type to read PNG format
 *	data from an object 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.
 *
 * Side effects:
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadPNG(
    Tcl_Interp *interp,
    Tcl_Obj *pObjData,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY,
    int width,
    int height,
    int srcX,
    int srcY)
{
    PNGImage png;
    int result = TCL_ERROR;
    (void)width;
    (void)height;
    (void)srcX;
    (void)srcY;

    result = InitPNGImage(interp, &png, NULL, pObjData,
	    TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * WriteData --
 *
 *	This function writes a bytes from a buffer out to the PNG image.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	File or buffer will be modified.
 *
 *----------------------------------------------------------------------
 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    size_t srcSz,
    unsigned long *crcPtr)
{
    if (!srcPtr || !srcSz) {
	return TCL_OK;
    }

    if (crcPtr) {
	*crcPtr = Tcl_ZlibCRC32(*crcPtr, srcPtr, srcSz);
    }

    /*
     * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the
     * objects immediately or store them in a multi-object rep?
     */

    if (pngPtr->objDataPtr) {
	TkSizeT objSz;
	unsigned char *destPtr;

	TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}

	destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz);

	if (!destPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "memory allocation failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    return TCL_ERROR;
	}

	memcpy(destPtr+objSz, srcPtr, srcSz);
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"write to channel failed: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    return TCL_OK;
}

static inline int
WriteByte(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char c,
    unsigned long *crcPtr)
{
    return WriteData(interp, pngPtr, &c, 1, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WriteInt32 --
 *
 *	This function writes a 32-bit integer value out to the PNG image as
 *	four bytes in network byte order.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	File or buffer will be modified.
 *
 *----------------------------------------------------------------------
 */

static inline int
WriteInt32(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long l,
    unsigned long *crcPtr)
{
    unsigned char pc[4];

    pc[0] = (unsigned char) ((l & 0xff000000) >> 24);
    pc[1] = (unsigned char) ((l & 0x00ff0000) >> 16);
    pc[2] = (unsigned char) ((l & 0x0000ff00) >> 8);
    pc[3] = (unsigned char) ((l & 0x000000ff) >> 0);

    return WriteData(interp, pngPtr, pc, 4, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WriteChunk --
 *
 *	Writes a complete chunk to the PNG image, including chunk type,
 *	length, contents, and CRC.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static inline int
WriteChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long chunkType,
    const unsigned char *dataPtr,
    size_t dataSize)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * Write the length field for the chunk.
     */

    result = WriteInt32(interp, pngPtr, dataSize, NULL);

    /*
     * Write the Chunk Type.
     */

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, chunkType, &crc);
    }

    /*
     * Write the contents (if any).
     */

    if (TCL_OK == result) {
	result = WriteData(interp, pngPtr, dataPtr, dataSize, &crc);
    }

    /*
     * Write out the CRC at the end of the chunk.
     */

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, crc, NULL);
    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * WriteIHDR --
 *
 *	This function writes the PNG header at the beginning of a PNG file,
 *	which includes information such as dimensions and color type.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	File or buffer will be modified.
 *
 *----------------------------------------------------------------------
 */

static int
WriteIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * The IHDR (header) chunk has a fixed size of 13 bytes.
     */

    result = WriteInt32(interp, pngPtr, 13, NULL);

    /*
     * Write the IHDR Chunk Type.
     */

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, CHUNK_IHDR, &crc);
    }

    /*
     * Write the image width, height.
     */

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, (unsigned long) blockPtr->width,
		&crc);
    }

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, (unsigned long) blockPtr->height,
		&crc);
    }

    /*
     * Write bit depth. Although the PNG format supports 16 bits per channel,
     * Tk supports only 8 in the internal representation, which blockPtr
     * points to.
     */

    if (TCL_OK == result) {
	result = WriteByte(interp, pngPtr, 8, &crc);
    }

    /*
     * Write out the color type, previously determined.
     */

    if (TCL_OK == result) {
	result = WriteByte(interp, pngPtr, pngPtr->colorType, &crc);
    }

    /*
     * Write compression method (only one method is defined).
     */

    if (TCL_OK == result) {
	result = WriteByte(interp, pngPtr, PNG_COMPRESS_DEFLATE, &crc);
    }

    /*
     * Write filter method (only one method is defined).
     */

    if (TCL_OK == result) {
	result = WriteByte(interp, pngPtr, PNG_FILTMETH_STANDARD, &crc);
    }

    /*
     * Write interlace method as not interlaced.
     *
     * TODO: support interlace through -format?
     */

    if (TCL_OK == result) {
	result = WriteByte(interp, pngPtr, PNG_INTERLACE_NONE, &crc);
    }

    /*
     * Write out the CRC at the end of the chunk.
     */

    if (TCL_OK == result) {
	result = WriteInt32(interp, pngPtr, crc, NULL);
    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * WriteIDAT --
 *
 *	Writes the IDAT (data) chunk to the PNG image, containing the pixel
 *	channel data. Currently, image lines are not filtered and writing
 *	interlaced pixels is not supported.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
WriteIDAT(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
    Tcl_Obj *outputObj;
    unsigned char *outputBytes;
    TkSizeT outputSize;

    /*
     * Filter and compress each row one at a time.
     */

    for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) {
	int colNum;
	unsigned char *srcPtr, *destPtr;

	srcPtr = blockPtr->pixelPtr + (rowNum * blockPtr->pitch);
	destPtr = Tcl_SetByteArrayLength(pngPtr->thisLineObj,
		pngPtr->lineSize);

	/*
	 * TODO: use Paeth filtering.
	 */

	*destPtr++ = PNG_FILTER_NONE;

	/*
	 * Copy each pixel into the destination buffer after the filter type
	 * before filtering.
	 */

	for (colNum = 0 ; colNum < blockPtr->width ; colNum++) {
	    /*
	     * Copy red or gray channel.
	     */

	    *destPtr++ = srcPtr[blockPtr->offset[0]];

	    /*
	     * If not grayscale, copy the green and blue channels.
	     */

	    if (pngPtr->colorType & PNG_COLOR_USED) {
		*destPtr++ = srcPtr[blockPtr->offset[1]];
		*destPtr++ = srcPtr[blockPtr->offset[2]];
	    }

	    /*
	     * Copy the alpha channel, if used.
	     */

	    if (pngPtr->colorType & PNG_COLOR_ALPHA) {
		*destPtr++ = srcPtr[blockPtr->offset[3]];
	    }

	    /*
	     * Point to the start of the next pixel.
	     */

	    srcPtr += blockPtr->pixelSize;
	}

	/*
	 * Compress the line of pixels into the destination. If this is the
	 * last line, finalize the compressor at the same time. Note that this
	 * can't be just a flush; that leads to a file that some PNG readers
	 * choke on. [Bug 2984787]
	 */

	if (rowNum + 1 == blockPtr->height) {
	    flush = TCL_ZLIB_FINALIZE;
	}
	if (Tcl_ZlibStreamPut(pngPtr->stream, pngPtr->thisLineObj,
		flush) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "deflate() returned error", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DEFLATE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Swap line buffers to keep the last around for filtering next.
	 */

	{
	    Tcl_Obj *temp = pngPtr->lastLineObj;

	    pngPtr->lastLineObj = pngPtr->thisLineObj;
	    pngPtr->thisLineObj = temp;
	}
    }

    /*
     * Now get the compressed data and write it as one big IDAT chunk.
     */

    outputObj = Tcl_NewObj();
    (void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1);
    outputBytes = TkGetByteArrayFromObj(outputObj, &outputSize);
    result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
    Tcl_DecrRefCount(outputObj);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * WriteExtraChunks --
 *
 *	Writes an sBIT and a tEXt chunks to the PNG image, describing a bunch
 *	of not very important metadata that many readers seem to need anyway.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
WriteExtraChunks(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    static const unsigned char sBIT_contents[] = {
	8, 8, 8, 8
    };
    int sBIT_length = 4;
    Tcl_DString buf;

    /*
     * Each byte of each channel is always significant; we always write RGBA
     * images with 8 bits per channel as that is what the photo image's basic
     * data model is.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
	sBIT_length = 1;
	break;
    case PNG_COLOR_GRAYALPHA:
	sBIT_length = 2;
	break;
    case PNG_COLOR_RGB:
    case PNG_COLOR_PLTE:
	sBIT_length = 3;
	break;
    case PNG_COLOR_RGBA:
	sBIT_length = 4;
	break;
    }
    if (WriteChunk(interp, pngPtr, CHUNK_sBIT, sBIT_contents, sBIT_length)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Say that it is Tk that made the PNG. Note that we *need* the NUL at the
     * end of "Software" to be transferred; do *not* change the length
     * parameter to -1 there!
     */

    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, "Software", 9);
    Tcl_DStringAppend(&buf, "Tk Toolkit v", -1);
    Tcl_DStringAppend(&buf, TK_PATCH_LEVEL, -1);
    if (WriteChunk(interp, pngPtr, CHUNK_tEXt,
	    (unsigned char *) Tcl_DStringValue(&buf),
	    Tcl_DStringLength(&buf)) != TCL_OK) {
	Tcl_DStringFree(&buf);
	return TCL_ERROR;
    }
    Tcl_DStringFree(&buf);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * EncodePNG --
 *
 *	This function handles the entirety of writing a PNG file (or data)
 *	from the first byte to the last. No effort is made to optimize the
 *	image data for best compression.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O or memory error occurs.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
EncodePNG(
    Tcl_Interp *interp,
    Tk_PhotoImageBlock *blockPtr,
    PNGImage *pngPtr)
{
    int greenOffset, blueOffset, alphaOffset;

    /*
     * Determine appropriate color type based on color usage (e.g., only red
     * and maybe alpha channel = grayscale).
     *
     * TODO: Check whether this is doing any good; Tk might just be pushing
     * full RGBA data all the time through here, even though the actual image
     * doesn't need it...
     */

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
    alphaOffset = blockPtr->offset[3];
    if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
    } else {
	alphaOffset -= blockPtr->offset[0];
    }

    if ((greenOffset != 0) || (blueOffset != 0)) {
	if (alphaOffset) {
	    pngPtr->colorType = PNG_COLOR_RGBA;
	    pngPtr->bytesPerPixel = 4;
	} else {
	    pngPtr->colorType = PNG_COLOR_RGB;
	    pngPtr->bytesPerPixel = 3;
	}
    } else {
	if (alphaOffset) {
	    pngPtr->colorType = PNG_COLOR_GRAYALPHA;
	    pngPtr->bytesPerPixel = 2;
	} else {
	    pngPtr->colorType = PNG_COLOR_GRAY;
	    pngPtr->bytesPerPixel = 1;
	}
    }

    /*
     * Allocate buffers for lines for filtering and compressed data.
     */

    pngPtr->lineSize = 1 + (pngPtr->bytesPerPixel * blockPtr->width);
    pngPtr->blockLen = pngPtr->lineSize * blockPtr->height;

    if ((blockPtr->width > (INT_MAX - 1) / (pngPtr->bytesPerPixel)) ||
	    (blockPtr->height > INT_MAX / pngPtr->lineSize)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image is too large to encode pixel data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	return TCL_ERROR;
    }

    pngPtr->lastLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    /*
     * Write out the PNG Signature that all PNGs begin with.
     */

    if (WriteData(interp, pngPtr, pngSignature, PNG_SIG_SZ,
	    NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the IHDR (header) chunk containing image dimensions, color
     * type, etc.
     */

    if (WriteIHDR(interp, pngPtr, blockPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the extra chunks containing metadata that is of interest to
     * other programs more than us.
     */

    if (WriteExtraChunks(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the image pixels in the IDAT (data) chunk.
     */

    if (WriteIDAT(interp, pngPtr, blockPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the IEND chunk that all PNGs end with.
     */

    return WriteChunk(interp, pngPtr, CHUNK_IEND, NULL, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * FileWritePNG --
 *
 *	This function is called by the photo image type to write PNG format
 *	data to a file.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	The specified file is overwritten.
 *
 *----------------------------------------------------------------------
 */

static int
FileWritePNG(
    Tcl_Interp *interp,
    const char *filename,
    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    PNGImage png;
    int result = TCL_ERROR;
    (void)fmtObj;

    /*
     * Open a Tcl file channel where the image data will be stored. Tk ought
     * to take care of this, and just provide a channel, but it doesn't.
     */

    chan = Tcl_OpenFileChannel(interp, filename, "w", 0644);

    if (!chan) {
	return TCL_ERROR;
    }

    /*
     * Initalize PNGImage instance for encoding.
     */

    if (InitPNGImage(interp, &png, chan, NULL,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }

    /*
     * Set the translation mode to binary so that CR and LF are not to the
     * platform's EOL sequence.
     */

    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */

    result = EncodePNG(interp, blockPtr, &png);

  cleanup:
    Tcl_Close(interp, chan);
    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * StringWritePNG --
 *
 *	This function is called by the photo image type to write PNG format
 *	data to a Tcl object and return it in the result.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

static int
StringWritePNG(
    Tcl_Interp *interp,
    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Obj *resultObj = Tcl_NewObj();
    PNGImage png;
    int result = TCL_ERROR;
    (void)fmtObj;

    /*
     * Initalize PNGImage instance for encoding.
     */

    if (InitPNGImage(interp, &png, NULL, resultObj,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data into the prepared Tcl_Obj buffer. Set the result
     * back to the interpreter if successful.
     */

    result = EncodePNG(interp, blockPtr, &png);

    if (TCL_OK == result) {
	Tcl_SetObjResult(interp, png.objDataPtr);
    }

  cleanup:
    CleanupPNGImage(&png);
    return result;
}

/*
 * Local Variables:
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkImgPPM.c.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define PGM 1
#define PPM 2

/*
 * The format record for the PPM file format:
 */

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,
			    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);

Tk_PhotoImageFormat tkImgFmtPPM = {
    "ppm",			/* name */
    FileMatchPPM,		/* fileMatchProc */
    StringMatchPPM,		/* stringMatchProc */
    FileReadPPM,		/* fileReadProc */
    StringReadPPM,		/* stringReadProc */
    FileWritePPM,		/* fileWriteProc */
    StringWritePPM,		/* stringWriteProc */
    NULL
};

/*
 * Prototypes for local functions defined in this file:
 */

static int		ReadPPMFileHeader(Tcl_Channel chan, int *widthPtr,







|



|


|


















<







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
#define PGM 1
#define PPM 2

/*
 * The format record for the PPM file format:
 */

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,
			    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);

Tk_PhotoImageFormat tkImgFmtPPM = {
    "ppm",			/* name */
    FileMatchPPM,		/* fileMatchProc */
    StringMatchPPM,		/* stringMatchProc */
    FileReadPPM,		/* fileReadProc */
    StringReadPPM,		/* stringReadProc */
    FileWritePPM,		/* fileWriteProc */
    StringWritePPM,		/* stringWriteProc */

};

/*
 * Prototypes for local functions defined in this file:
 */

static int		ReadPPMFileHeader(Tcl_Channel chan, int *widthPtr,
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchPPM(
    Tcl_Channel chan,		/* The image file, open for reading. */
    TCL_UNUSED(const char *),	/* The name of the image file. */
    TCL_UNUSED(Tcl_Obj *),		/* 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_UNUSED(Tcl_Interp *))		/* unused */
{
    int dummy;

    return ReadPPMFileHeader(chan, widthPtr, heightPtr, &dummy);
}

/*







|
|




|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 *
 *----------------------------------------------------------------------
 */

static int
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;

    return ReadPPMFileHeader(chan, widthPtr, heightPtr, &dummy);
}

/*
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
 *----------------------------------------------------------------------
 */

static int
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_UNUSED(Tcl_Obj *),		/* 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, h, type, bytesPerChannel = 1;
    size_t nBytes, count;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;

    type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read raw PPM header from file \"%s\"", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PPM image file \"%s\" has dimension(s) <= 0", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PPM image file \"%s\" has bad maximum intensity value %d",
		fileName, maxIntensity));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);

	return TCL_ERROR;
    } else if (maxIntensity > 0x00ff) {
	bytesPerChannel = 2;
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;







|
|









|
<





<
|
|



|
|
<



|
|
|
|
>







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148

149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
 *----------------------------------------------------------------------
 */

static int
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, bytesPerChannel = 1;

    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;

    type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
    if (type == 0) {

	Tcl_AppendResult(interp, "couldn't read raw PPM header from file \"",
		fileName, "\"", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_AppendResult(interp, "PPM image file \"", fileName,
		"\" has dimension(s) <= 0", NULL);

	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
	char buffer[TCL_INTEGER_SPACE];

	sprintf(buffer, "%d", maxIntensity);
	Tcl_AppendResult(interp, "PPM image file \"", fileName,
		"\" has bad maximum intensity value ", buffer, NULL);
	return TCL_ERROR;
    } else if (maxIntensity > 0x00ff) {
	bytesPerChannel = 2;
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {
	nLines = 1;
    }
    nBytes = nLines * block.pitch;
    pixelPtr = (unsigned char *)ckalloc(nBytes);
    block.pixelPtr = pixelPtr + srcX * block.pixelSize;

    for (h = height; h > 0; h -= nLines) {
	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	count = Tcl_Read(chan, (char *) pixelPtr, nBytes);
	if (count != nBytes) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading PPM image file \"%s\": %s", fileName,
		    Tcl_Eof(chan)?"not enough data":Tcl_PosixError(interp)));

	    if (Tcl_Eof(chan)) {
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "EOF", NULL);
	    }
	    ckfree(pixelPtr);
	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    unsigned char *p;

	    for (p = pixelPtr; count > 0; count--, p++) {
		*p = (((int) *p) * 255)/maxIntensity;







|









<
|
<
>
|
|
<
|







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222

223
224
225

226
227
228
229
230
231
232
233
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {
	nLines = 1;
    }
    nBytes = nLines * block.pitch;
    pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
    block.pixelPtr = pixelPtr + srcX * block.pixelSize;

    for (h = height; h > 0; h -= nLines) {
	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	count = Tcl_Read(chan, (char *) pixelPtr, nBytes);
	if (count != nBytes) {

	    Tcl_AppendResult(interp, "error reading PPM image file \"",

		    fileName, "\": ",
		    Tcl_Eof(chan) ? "not enough data" : Tcl_PosixError(interp),
		    NULL);

	    ckfree((char *) pixelPtr);
	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    unsigned char *p;

	    for (p = pixelPtr; count > 0; count--, p++) {
		*p = (((int) *p) * 255)/maxIntensity;
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(pixelPtr);
	    return TCL_ERROR;
	}
	destY += nLines;
    }

    ckfree(pixelPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FileWritePPM --







|





|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree((char *) pixelPtr);
	    return TCL_ERROR;
	}
	destY += nLines;
    }

    ckfree((char *) pixelPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FileWritePPM --
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
 *
 *----------------------------------------------------------------------
 */

static int
FileWritePPM(
    Tcl_Interp *interp,
    const char *fileName,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset;
    size_t nBytes;
    unsigned char *pixelPtr, *pixLinePtr;
    char header[16 + TCL_INTEGER_SPACE * 2];

    chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
    if (chan == NULL) {
	return TCL_ERROR;
    }







|
|



|
<







272
273
274
275
276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
 *
 *----------------------------------------------------------------------
 */

static int
FileWritePPM(
    Tcl_Interp *interp,
    CONST char *fileName,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset, nBytes;

    unsigned char *pixelPtr, *pixLinePtr;
    char header[16 + TCL_INTEGER_SPACE * 2];

    chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
    if (chan == NULL) {
	return TCL_ERROR;
    }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
	nBytes = blockPtr->height * blockPtr->pitch;
	if ((size_t)Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
	    goto writeerror;
	}
    } else {
	for (h = blockPtr->height; h > 0; h--) {
	    pixelPtr = pixLinePtr;
	    for (w = blockPtr->width; w > 0; w--) {
		if (Tcl_Write(chan,(char *)&pixelPtr[0], 1) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == TCL_IO_FAILURE) {
		    goto writeerror;
		}
		pixelPtr += blockPtr->pixelSize;
	    }
	    pixLinePtr += blockPtr->pitch;
	}
    }

    if (Tcl_Close(NULL, chan) == 0) {
	return TCL_OK;
    }
    chan = NULL;

  writeerror:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
	    fileName, Tcl_PosixError(interp)));
    if (chan != NULL) {
	Tcl_Close(NULL, chan);
    }
    return TCL_ERROR;
}

/*







|






|
|
|














|
|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
	nBytes = blockPtr->height * blockPtr->pitch;
	if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
	    goto writeerror;
	}
    } else {
	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) {
		    goto writeerror;
		}
		pixelPtr += blockPtr->pixelSize;
	    }
	    pixLinePtr += blockPtr->pitch;
	}
    }

    if (Tcl_Close(NULL, chan) == 0) {
	return TCL_OK;
    }
    chan = NULL;

  writeerror:
    Tcl_AppendResult(interp, "error writing \"", fileName, "\": ",
	    Tcl_PosixError(interp), NULL);
    if (chan != NULL) {
	Tcl_Close(NULL, chan);
    }
    return TCL_ERROR;
}

/*
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
 *
 *----------------------------------------------------------------------
 */

static int
StringWritePPM(
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;








|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
 *
 *----------------------------------------------------------------------
 */

static int
StringWritePPM(
    Tcl_Interp *interp,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
 *
 *----------------------------------------------------------------------
 */

static int
StringMatchPPM(
    Tcl_Obj *dataObj,		/* The image data. */
    TCL_UNUSED(Tcl_Obj *),		/* 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_UNUSED(Tcl_Interp *))		/* unused */
{
    int dummy;

    return ReadPPMStringHeader(dataObj, widthPtr, heightPtr,
	    &dummy, NULL, NULL);
}








|




|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 *
 *----------------------------------------------------------------------
 */

static int
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;

    return ReadPPMStringHeader(dataObj, widthPtr, heightPtr,
	    &dummy, NULL, NULL);
}

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512



513
514
515
516
517
518
519
520
521
522
523
 *----------------------------------------------------------------------
 */

static int
StringReadPPM(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *dataObj,		/* The image data. */
    TCL_UNUSED(Tcl_Obj *),		/* 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, bytesPerChannel = 1;
    unsigned char *pixelPtr, *dataBuffer;
    Tk_PhotoImageBlock block;

    type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight,
	    &maxIntensity, &dataBuffer, &dataSize);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't read raw PPM header from string", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PPM image data has dimension(s) <= 0", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {



	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PPM image data has bad maximum intensity value %d",
		maxIntensity));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);
	return TCL_ERROR;
    } else if (maxIntensity > 0x00ff) {
	bytesPerChannel = 2;
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;







|
















<
|
|



<
|
|



>
>
>
|
|
<
|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499

500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
517
 *----------------------------------------------------------------------
 */

static int
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, bytesPerChannel = 1;
    unsigned char *pixelPtr, *dataBuffer;
    Tk_PhotoImageBlock block;

    type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight,
	    &maxIntensity, &dataBuffer, &dataSize);
    if (type == 0) {

	Tcl_AppendResult(interp, "couldn't read raw PPM header from string",
		NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {

	Tcl_AppendResult(interp, "PPM image data has dimension(s) <= 0",
		NULL);
	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
	char buffer[TCL_INTEGER_SPACE];

	sprintf(buffer, "%d", maxIntensity);
	Tcl_AppendResult(interp,
		"PPM image data has bad maximum intensity value ", buffer,

		NULL);
	return TCL_ERROR;
    } else if (maxIntensity > 0x00ff) {
	bytesPerChannel = 2;
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

    if (maxIntensity == 0x00ff) {
	/*
	 * We have all the data in memory, so write everything in one go.
	 */

	if (block.pitch*height > dataSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	block.pixelPtr = dataBuffer + srcX * block.pixelSize;
	block.height = height;
	return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET);
    }







<
|
<







546
547
548
549
550
551
552

553

554
555
556
557
558
559
560

    if (maxIntensity == 0x00ff) {
	/*
	 * 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;
	return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET);
    }
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {
	nLines = 1;
    }
    nBytes = nLines * block.pitch;
    pixelPtr = (unsigned char *)ckalloc(nBytes);
    block.pixelPtr = pixelPtr + srcX * block.pixelSize;

    for (h = height; h > 0; h -= nLines) {
	unsigned char *p;

	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	if (dataSize < nBytes) {
	    ckfree(pixelPtr);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {

	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	dataSize -= nBytes;
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(pixelPtr);
	    return TCL_ERROR;
	}
	destY += nLines;
    }

    ckfree(pixelPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadPPMFileHeader --







|










|
<
|
<







>












|





|







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

587

588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {
	nLines = 1;
    }
    nBytes = nLines * block.pitch;
    pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
    block.pixelPtr = pixelPtr + srcX * block.pixelSize;

    for (h = height; h > 0; h -= nLines) {
	unsigned char *p;

	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	if (dataSize < nBytes) {
	    ckfree((char *) pixelPtr);

	    Tcl_AppendResult(interp, "truncated PPM data", NULL);

	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {
	    unsigned char *p;
	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	dataSize -= nBytes;
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree((char *) pixelPtr);
	    return TCL_ERROR;
	}
	destY += nLines;
    }

    ckfree((char *) pixelPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadPPMFileHeader --
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
    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], c;
    int i, numFields, type = 0;
    TkSizeT dataSize;
    unsigned char *dataBuffer;

    dataBuffer = TkGetByteArrayFromObj(dataPtr, &dataSize);

    /*
     * Read 4 space-separated fields from the string, ignoring comments (any
     * line that starts with "#").
     */

    if (dataSize-- < 1) {







|
<


|







750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765
766
767
    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], 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 "#").
     */

    if (dataSize-- < 1) {

Deleted generic/tkImgPhInstance.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
/*
 * tkImgPhInstance.c --
 *
 *	Implements the rendering of 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-2008 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.
 *
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#include "tkPort.h"

/*
 * Declaration for internal Xlib function used here:
 */
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
#ifdef __cplusplus
extern "C" {
#endif
extern int		_XInitImageFuncPtrs(XImage *image);
#ifdef __cplusplus
}
#endif
#endif

/*
 * Forward declarations
 */

#ifndef TKPUTIMAGE_CAN_BLEND
static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);
#endif
static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(unsigned mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
static int		ReclaimColors(ColorTableId *id, int numColors);

/*
 * Hash table used to hash from (display, colormap, palette, gamma) to
 * ColorTable address.
 */

static Tcl_HashTable imgPhotoColorHash;
static int imgPhotoColorHashInitialized;
#define N_COLOR_HASH	(sizeof(ColorTableId) / sizeof(int))

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoConfigureInstance --
 *
 *	This function is called to create displaying information for a photo
 *	image instance based on the configuration information in the model.
 *	It is invoked both when new instances are created and when the model
 *	is reconfigured.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates errors via Tcl_BackgroundException if there are problems in
 *	setting up the instance.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoModel *modelPtr = instancePtr->modelPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    XRectangle validBox;

    /*
     * If the -palette configuration option has been set for the model, use
     * the value specified for our palette, but only if it is a valid palette
     * for our windows. Use the gamma value specified the model.
     */

    if ((modelPtr->palette && modelPtr->palette[0])
	    && IsValidPalette(instancePtr, modelPtr->palette)) {
	instancePtr->palette = modelPtr->palette;
    } else {
	instancePtr->palette = instancePtr->defaultPalette;
    }
    instancePtr->gamma = modelPtr->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.
     */

    colorTablePtr = instancePtr->colorTablePtr;
    if ((colorTablePtr == NULL)
	    || (instancePtr->colormap != colorTablePtr->id.colormap)
	    || (instancePtr->palette != colorTablePtr->id.palette)
	    || (instancePtr->gamma != colorTablePtr->id.gamma)) {
	/*
	 * Free up our old color table, and get a new one.
	 */

	if (colorTablePtr != NULL) {
	    colorTablePtr->liveRefCount--;
	    FreeColorTable(colorTablePtr, 0);
	}
	GetColorTable(instancePtr);

	/*
	 * Create a new XImage structure for sending data to the X server, if
	 * necessary.
	 */

	if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) {
	    bitsPerPixel = 1;
	} else {
	    bitsPerPixel = instancePtr->visualInfo.depth;
	}

	if ((instancePtr->imagePtr == NULL)
		|| (instancePtr->imagePtr->bits_per_pixel != bitsPerPixel)) {
	    if (instancePtr->imagePtr != NULL) {
		XDestroyImage(instancePtr->imagePtr);
	    }
	    imagePtr = XCreateImage(instancePtr->display,
		    instancePtr->visualInfo.visual, (unsigned) bitsPerPixel,
		    (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL,
		    1, 1, 32, 0);
	    instancePtr->imagePtr = imagePtr;

	    /*
	     * We create images using the local host's endianness, rather than
	     * the endianness of the server; otherwise we would have to
	     * byte-swap any 16 or 32 bit values that we store in the image
	     * if the server's endianness is different from ours.
	     */

	    if (imagePtr != NULL) {
#ifdef WORDS_BIGENDIAN
		imagePtr->byte_order = MSBFirst;
#else
		imagePtr->byte_order = LSBFirst;
#endif
		_XInitImageFuncPtrs(imagePtr);
	    }
	}
    }

    /*
     * If the user has specified a width and/or height for the model 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)
	    || (instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)) {
	TkImgPhotoInstanceSetSize(instancePtr);
    }

    /*
     * Redither this instance if necessary.
     */

    if ((modelPtr->flags & IMAGE_CHANGED)
	    || (instancePtr->colorTablePtr != colorTablePtr)) {
	TkClipBox(modelPtr->validRegion, &validBox);
	if ((validBox.width > 0) && (validBox.height > 0)) {
	    TkImgDitherInstance(instancePtr, validBox.x, validBox.y,
		    validBox.width, validBox.height);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoGet --
 *
 *	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 TkImgPhotoDisplay and ImgPhotoFree.
 *
 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

ClientData
TkImgPhotoGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;
    Colormap colormap;
    int mono, nRed, nGreen, nBlue, numVisuals;
    XVisualInfo visualInfo, *visInfoPtr;
    char buf[TCL_INTEGER_SPACE * 3];
    XColor *white, *black;
    XGCValues gcValues;

    /*
     * Table of "best" choices for palette for PseudoColor displays with
     * between 3 and 15 bits/pixel.
     */

    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 */}
    };

    /*
     * See if there is already an instance for windows using the same
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
		&& (Tk_Display(tkwin) == instancePtr->display)) {
	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.
		 */

		Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr);
		if (instancePtr->colorTablePtr != NULL) {
		    FreeColorTable(instancePtr->colorTablePtr, 0);
		}
		GetColorTable(instancePtr);
	    }
	    instancePtr->refCount++;
	    return instancePtr;
	}
    }

    /*
     * 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));
    instancePtr->modelPtr = modelPtr;
    instancePtr->display = Tk_Display(tkwin);
    instancePtr->colormap = Tk_Colormap(tkwin);
    Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
    instancePtr->refCount = 1;
    instancePtr->colorTablePtr = NULL;
    instancePtr->pixels = None;
    instancePtr->error = NULL;
    instancePtr->width = 0;
    instancePtr->height = 0;
    instancePtr->imagePtr = 0;
    instancePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = instancePtr;

    /*
     * 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("TkImgPhotoGet couldn't find visual for window");
    }

    nRed = 2;
    nGreen = nBlue = 0;
    mono = 1;
    instancePtr->visualInfo = *visInfoPtr;
    switch (visInfoPtr->c_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);

    if (mono) {
	sprintf(buf, "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(modelPtr->interp, tkwin, "white");
    black = Tk_GetColor(modelPtr->interp, tkwin, "black");
    gcValues.foreground = (white != NULL)? white->pixel:
	    WhitePixelOfScreen(Tk_Screen(tkwin));
    gcValues.background = (black != NULL)? black->pixel:
	    BlackPixelOfScreen(Tk_Screen(tkwin));
    Tk_FreeColor(white);
    Tk_FreeColor(black);
    gcValues.graphics_exposures = False;
    instancePtr->gc = Tk_GetGC(tkwin,
	    GCForeground|GCBackground|GCGraphicsExposures, &gcValues);

    /*
     * Set configuration options and finish the initialization of the
     * instance. This will also dither the image if necessary.
     */

    TkImgPhotoConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
    }

    return instancePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * BlendComplexAlpha --
 *
 *	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.
 *
 * Side effects:
 *	Background image passed in gets drawn over with image data.
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */
#ifndef TKPUTIMAGE_CAN_BLEND
#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)  ))
#endif /* !_WIN32 */

static void
BlendComplexAlpha(
    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, *modelPtr;
    unsigned char *alphaAr = iPtr->modelPtr->pix32;

    /*
     * 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.
     */

#ifndef _WIN32
    unsigned long red_mask, green_mask, blue_mask;
    unsigned long red_shift, green_shift, blue_shift;
    Visual *visual = iPtr->visualInfo.visual;

    red_mask = visual->red_mask;
    green_mask = visual->green_mask;
    blue_mask = visual->blue_mask;
    red_shift = 0;
    green_shift = 0;
    blue_shift = 0;
    while ((0x0001 & (red_mask >> red_shift)) == 0) {
	red_shift++;
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }
#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.
     */

#if !defined(_WIN32)
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
	    line = (y + yOffset) * iPtr->modelPtr->width;
	    for (x = 0; x < width; x++) {
		modelPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = modelPtr[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 = modelPtr[0];
		    g = modelPtr[1];
		    b = modelPtr[2];
		    if (alpha != 255) {
			/*
			 * 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;	/* Calculate once. */
			r = ALPHA_BLEND(ra, r, alpha, unalpha);
			g = ALPHA_BLEND(ga, g, alpha, unalpha);
			b = ALPHA_BLEND(ba, b, alpha, unalpha);
		    }
		    XPutPixel(bgImg, x, y, RGB15(r, g, b));
		}
	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->modelPtr->width;
	for (x = 0; x < width; x++) {
	    modelPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = modelPtr[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 = modelPtr[0];
		g = modelPtr[1];
		b = modelPtr[2];
		if (alpha != 255) {
		    /*
		     * 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;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TKPUTIMAGE_CAN_BLEND */

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoDisplay(
    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;
#ifndef TKPUTIMAGE_CAN_BLEND
    XVisualInfo visInfo = instancePtr->visualInfo;
#endif

    /*
     * 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;
    }

#ifdef TKPUTIMAGE_CAN_BLEND
    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);
#else

    if ((instancePtr->modelPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
	 * 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, NULL, 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);
	    /* We failed to get the image, so draw without blending alpha.
	     * It's the best we can do.
	     */
	    goto fallBack;
	}

	BlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width, height);

	/*
	 * 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);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * modelPtr->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.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->modelPtr->validRegion);
	XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
		drawableY - imageY);
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    (void)XFlush(display);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoFree --
 *
 *	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.
 *
 * Side effects:
 *	Internal data structures get cleaned up, later.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoFree(
    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;
    (void)display;

    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * 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--;
    }

    Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoInstanceSetSize --
 *
 *	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.
 *
 * Side effects:
 *	Storage gets reallocated, here and in the X server.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoInstanceSetSize(
    PhotoInstance *instancePtr)	/* Instance whose size is to be changed. */
{
    PhotoModel *modelPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    modelPtr = instancePtr->modelPtr;
    TkClipBox(modelPtr->validRegion, &validBox);

    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,
			instancePtr->visualInfo.screen),
		(modelPtr->width > 0) ? modelPtr->width: 1,
		(modelPtr->height > 0) ? modelPtr->height: 1,
		instancePtr->visualInfo.depth);
	if (!newPixmap) {
	    Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize");
	}

	/*
	 * 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.
	 */

	TkSetPixmapColormap(newPixmap, instancePtr->colormap);

	if (instancePtr->pixels != None) {
	    /*
	     * 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);
	    Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
	}
	instancePtr->pixels = newPixmap;
    }

    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->error == NULL)) {
	if (modelPtr->height > 0 && modelPtr->width > 0) {
	    /*
	     * TODO: use attemptckalloc() here once there is a strategy that
	     * will allow us to recover from failure. Right now, there's no
	     * such possibility.
	     */

	    newError = (schar *)ckalloc(modelPtr->height * modelPtr->width
		    * 3 * sizeof(schar));

	    /*
	     * 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 == modelPtr->width)
		    || (validBox.width == modelPtr->width))) {
		if (validBox.y > 0) {
		    memset(newError, 0, (size_t)
			    validBox.y * modelPtr->width * 3 * sizeof(schar));
		}
		h = validBox.y + validBox.height;
		if (h < modelPtr->height) {
		    memset(newError + h*modelPtr->width*3, 0,
			    (size_t) (modelPtr->height - h)
			    * modelPtr->width * 3 * sizeof(schar));
		}
	    } else {
		memset(newError, 0, (size_t)
			modelPtr->height * modelPtr->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.
	     */

	    if (modelPtr->width == instancePtr->width) {
		offset = validBox.y * modelPtr->width * 3;
		memcpy(newError + offset, instancePtr->error + offset,
			(size_t) validBox.height
			* modelPtr->width * 3 * sizeof(schar));

	    } else if (validBox.width > 0 && validBox.height > 0) {
		errDestPtr = newError +
			(validBox.y * modelPtr->width + validBox.x) * 3;
		errSrcPtr = instancePtr->error +
			(validBox.y * instancePtr->width + validBox.x) * 3;

		for (h = validBox.height; h > 0; --h) {
		    memcpy(errDestPtr, errSrcPtr,
			    validBox.width * 3 * sizeof(schar));
		    errDestPtr += modelPtr->width * 3;
		    errSrcPtr += instancePtr->width * 3;
		}
	    }
	    ckfree(instancePtr->error);
	}

	instancePtr->error = newError;
    }

    instancePtr->width = modelPtr->width;
    instancePtr->height = modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * IsValidPalette --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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.
     */

    nRed = strtol(palette, &endp, 10);
    if ((endp == palette) || ((*endp != 0) && (*endp != '/'))
	    || (nRed < 2) || (nRed > 256)) {
	return 0;
    }

    if (*endp == 0) {
	mono = 1;
	nGreen = nBlue = nRed;
    } else {
	palette = endp + 1;
	nGreen = strtol(palette, &endp, 10);
	if ((endp == palette) || (*endp != '/') || (nGreen < 2)
		|| (nGreen > 256)) {
	    return 0;
	}
	palette = endp + 1;
	nBlue = strtol(palette, &endp, 10);
	if ((endp == palette) || (*endp != 0) || (nBlue < 2)
		|| (nBlue > 256)) {
	    return 0;
	}
	mono = 0;
    }

    switch (instancePtr->visualInfo.c_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;
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * CountBits --
 *
 *	This function counts how many bits are set to 1 in `mask'.
 *
 * Results:
 *	The integer number of bits.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    unsigned mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;
}

/*
 *----------------------------------------------------------------------
 *
 * GetColorTable --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
GetColorTable(
    PhotoInstance *instancePtr)	/* Instance needing a color table. */
{
    ColorTable *colorPtr;
    Tcl_HashEntry *entry;
    ColorTableId id;
    int isNew;

    /*
     * Look for an existing ColorTable in the hash table.
     */

    memset(&id, 0, sizeof(id));
    id.display = instancePtr->display;
    id.colormap = instancePtr->colormap;
    id.palette = instancePtr->palette;
    id.gamma = instancePtr->gamma;
    if (!imgPhotoColorHashInitialized) {
	Tcl_InitHashTable(&imgPhotoColorHash, N_COLOR_HASH);
	imgPhotoColorHashInitialized = 1;
    }
    entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);

    if (!isNew) {
	/*
	 * Re-use the existing entry.
	 */

	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
    } else {
	/*
	 * No color table currently available; need to make one.
	 */

	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.
	 */

	memset(&colorPtr->id, 0, sizeof(ColorTableId));
	colorPtr->id = id;
	Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap);
	colorPtr->flags = 0;
	colorPtr->refCount = 0;
	colorPtr->liveRefCount = 0;
	colorPtr->numColors = 0;
	colorPtr->visualInfo = instancePtr->visualInfo;
	colorPtr->pixelMap = NULL;
	Tcl_SetHashValue(entry, colorPtr);
    }

    colorPtr->refCount++;
    colorPtr->liveRefCount++;
    instancePtr->colorTablePtr = colorPtr;
    if (colorPtr->flags & DISPOSE_PENDING) {
	Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
	colorPtr->flags &= ~DISPOSE_PENDING;
    }

    /*
     * Allocate colors for this color table if necessary.
     */

    if ((colorPtr->numColors == 0) && !(colorPtr->flags & BLACK_AND_WHITE)) {
	AllocateColors(colorPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeColorTable --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
FreeColorTable(
    ColorTable *colorPtr,	/* Pointer to the color table which is no
				 * longer required by an instance. */
    int force)			/* Force free to happen immediately. */
{
    if (colorPtr->refCount-- > 1) {
	return;
    }

    if (force) {
	if (colorPtr->flags & DISPOSE_PENDING) {
	    Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
	    colorPtr->flags &= ~DISPOSE_PENDING;
	}
	DisposeColorTable(colorPtr);
    } else if (!(colorPtr->flags & DISPOSE_PENDING)) {
	Tcl_DoWhenIdle(DisposeColorTable, colorPtr);
	colorPtr->flags |= DISPOSE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * AllocateColors --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
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;
    double fr, fg, fb, igam;
    XColor *colors;
    unsigned long *pixels;

    /*
     * 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))))

    /*
     * First parse the palette specification to get the required number of
     * shades of each primary.
     */

    mono = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, &nGreen, &nBlue)
	    <= 1;
    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.
     */

    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 (mono && (nRed <= 2)) {
	    colorPtr->flags |= BLACK_AND_WHITE;
	    return;
	}

	/*
	 * Calculate the RGB coordinates of the colors we want to allocate and
	 * store them in *colors.
	 */

	if ((colorPtr->visualInfo.c_class == DirectColor)
		|| (colorPtr->visualInfo.c_class == TrueColor)) {

	    /*
	     * Direct/True Color: allocate shades of red, green, blue
	     * independently.
	     */

	    if (mono) {
		numColors = nGreen = nBlue = nRed;
	    } else {
		numColors = MAX(MAX(nRed, nGreen), nBlue);
	    }
	    colors = (XColor *)ckalloc(numColors * sizeof(XColor));

	    for (i = 0; i < numColors; ++i) {
		if (igam == 1.0) {
		    colors[i].red = CFRAC(i, nRed - 1);
		    colors[i].green = CFRAC(i, nGreen - 1);
		    colors[i].blue = CFRAC(i, nBlue - 1);
		} else {
		    colors[i].red = CGFRAC(i, nRed - 1, igam);
		    colors[i].green = CGFRAC(i, nGreen - 1, igam);
		    colors[i].blue = CGFRAC(i, nBlue - 1, igam);
		}
	    }
	} else {
	    /*
	     * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
	     * have to allocate each color in the color cube separately.
	     */

	    numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
	    colors = (XColor *)ckalloc(numColors * sizeof(XColor));

	    if (!mono) {
		/*
		 * Color display using a PseudoColor or StaticColor visual.
		 */

		i = 0;
		for (r = 0; r < nRed; ++r) {
		    for (g = 0; g < nGreen; ++g) {
			for (b = 0; b < nBlue; ++b) {
			    if (igam == 1.0) {
				colors[i].red = CFRAC(r, nRed - 1);
				colors[i].green = CFRAC(g, nGreen - 1);
				colors[i].blue = CFRAC(b, nBlue - 1);
			    } else {
				colors[i].red = CGFRAC(r, nRed - 1, igam);
				colors[i].green = CGFRAC(g, nGreen - 1, igam);
				colors[i].blue = CGFRAC(b, nBlue - 1, igam);
			    }
			    i++;
			}
		    }
		}
	    } else {
		/*
		 * Monochrome display - allocate the shades of gray we want.
		 */

		for (i = 0; i < numColors; ++i) {
		    if (igam == 1.0) {
			r = CFRAC(i, numColors - 1);
		    } else {
			r = CGFRAC(i, numColors - 1, igam);
		    }
		    colors[i].red = colors[i].green = colors[i].blue = r;
		}
	    }
	}

	/*
	 * Now try to allocate the colors we've calculated.
	 */

	pixels = (unsigned long *)ckalloc(numColors * sizeof(unsigned long));
	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.
		 */

		if (!ReclaimColors(&colorPtr->id, numColors - i)
			|| !XAllocColor(colorPtr->id.display,
			colorPtr->id.colormap, &colors[i])) {
		    /*
		     * Still can't allocate the color.
		     */

		    break;
		}
	    }
	    pixels[i] = colors[i].pixel;
	}

	/*
	 * 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) {
	    break;
	}
	XFreeColors(colorPtr->id.display, colorPtr->id.colormap, pixels, i, 0);
	ckfree(colors);
	ckfree(pixels);

	if (!mono) {
	    if ((nRed == 2) && (nGreen == 2) && (nBlue == 2)) {
		/*
		 * Fall back to 1-bit monochrome display.
		 */

		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.
		 */

		nRed = (nRed * 3 + 2) / 4;
		nGreen = (nGreen * 3 + 2) / 4;
		nBlue = (nBlue * 3 + 2) / 4;
	    }
	} else {
	    /*
	     * Reduce the number of shades of gray to about 1/2.
	     */

	    nRed = nRed / 2;
	}
    }

    /*
     * 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.
	 */

#ifndef _WIN32
	if ((colorPtr->visualInfo.c_class != DirectColor)
		&& (colorPtr->visualInfo.c_class != TrueColor)) {
	    colorPtr->flags |= MAP_COLORS;
	}
#endif /* _WIN32 */
    }

    colorPtr->numColors = numColors;
    colorPtr->pixelMap = pixels;

    /*
     * Set up quantization tables for dithering.
     */

    rMult = nGreen * nBlue;
    for (i = 0; i < 256; ++i) {
	r = (i * (nRed - 1) + 127) / 255;
	if (mono) {
	    fr = (double) colors[r].red / 65535.0;
	    if (colorPtr->id.gamma != 1.0 ) {
		fr = pow(fr, colorPtr->id.gamma);
	    }
	    colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
	    colorPtr->redValues[i] = colors[r].pixel;
	} else {
	    g = (i * (nGreen - 1) + 127) / 255;
	    b = (i * (nBlue - 1) + 127) / 255;
	    if ((colorPtr->visualInfo.c_class == DirectColor)
		    || (colorPtr->visualInfo.c_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;
	    } else {
		r *= rMult;
		g *= nBlue;
		colorPtr->redValues[i] = r;
		colorPtr->greenValues[i] = g;
		colorPtr->blueValues[i] = b;
	    }
	    fr = (double) colors[r].red / 65535.0;
	    fg = (double) colors[g].green / 65535.0;
	    fb = (double) colors[b].blue / 65535.0;
	    if (colorPtr->id.gamma != 1.0) {
		fr = pow(fr, colorPtr->id.gamma);
		fg = pow(fg, colorPtr->id.gamma);
		fb = pow(fb, colorPtr->id.gamma);
	    }
	    colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
	    colorPtr->colorQuant[1][i] = (int)(fg * 255.99);
	    colorPtr->colorQuant[2][i] = (int)(fb * 255.99);
	}
    }

    ckfree(colors);
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *)clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {
	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap);
	}
	ckfree(colorPtr->pixelMap);
    }

    entry = Tcl_FindHashEntry(&imgPhotoColorHash, &colorPtr->id);
    if (entry == NULL) {
	Tcl_Panic("DisposeColorTable couldn't find hash entry");
    }
    Tcl_DeleteHashEntry(entry);

    ckfree(colorPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ReclaimColors --
 *
 *	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.
 *
 * Side effects:
 *	ColorTables which are not currently in use may lose their color
 *	allocations.
 *
 *----------------------------------------------------------------------
 */

static int
ReclaimColors(
    ColorTableId *id,		/* Pointer to information identifying
				 * the color table which needs more colors. */
    int numColors)		/* Number of colors required. */
{
    Tcl_HashSearch srch;
    Tcl_HashEntry *entry;
    ColorTable *colorPtr;
    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.
     */

    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))) {
	    /*
	     * We could take this guy's colors off him.
	     */

	    nAvail += colorPtr->numColors;
	}
	entry = Tcl_NextHashEntry(&srch);
    }

    /*
     * nAvail is an (over)estimate of the number of colors we could free.
     */

    if (nAvail < numColors) {
	return 0;
    }

    /*
     * Scan through a second time freeing colors.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while ((entry != NULL) && (numColors > 0)) {
	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))) {
	    /*
	     * Free the colors that this ColorTable has.
	     */

	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    numColors -= colorPtr->numColors;
	    colorPtr->numColors = 0;
	    ckfree(colorPtr->pixelMap);
	    colorPtr->pixelMap = NULL;
	}

	entry = Tcl_NextHashEntry(&srch);
    }
    return 1;			/* We freed some colors. */
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgDisposeInstance --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

void
TkImgDisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(instancePtr->display, instancePtr->gc);
    }
    if (instancePtr->imagePtr != NULL) {
	XDestroyImage(instancePtr->imagePtr);
    }
    if (instancePtr->error != NULL) {
	ckfree(instancePtr->error);
    }
    if (instancePtr->colorTablePtr != NULL) {
	FreeColorTable(instancePtr->colorTablePtr, 1);
    }

    if (instancePtr->modelPtr->instancePtr == instancePtr) {
	instancePtr->modelPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->modelPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
    ckfree(instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgDitherInstance --
 *
 *	This function is called to update an area of an instance's pixmap by
 *	dithering the corresponding area of the model.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The instance's pixmap gets updated.
 *
 *----------------------------------------------------------------------
 */

void
TkImgDitherInstance(
    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, int height)	/* Dimensions of the block to be dithered. */
{
    PhotoModel *modelPtr = instancePtr->modelPtr;
    ColorTable *colorPtr = instancePtr->colorTablePtr;
    XImage *imagePtr;
    int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
    int bitsPerPixel, bytesPerLine, lineLength;
    unsigned char *srcLinePtr;
    schar *errLinePtr;
    unsigned firstBit, word, mask;

    /*
     * Turn dithering off in certain cases where it is not needed (TrueColor,
     * DirectColor with many colors).
     */

    if ((colorPtr->visualInfo.c_class == DirectColor)
	    || (colorPtr->visualInfo.c_class == TrueColor)) {
	int nRed, nGreen, nBlue, result;

	result = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed,
		&nGreen, &nBlue);
	if ((nRed >= 256)
		&& ((result == 1) || ((nGreen >= 256) && (nBlue >= 256)))) {
	    doDithering = 0;
	}
    }

    /*
     * 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;
    if (nLines < 1) {
	nLines = 1;
    }
    if (nLines > height ) {
	nLines = height;
    }

    imagePtr = instancePtr->imagePtr;
    if (imagePtr == NULL) {
	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;

    /*
     * TODO: use attemptckalloc() here once we have some strategy for
     * recovering from the failure.
     */

    imagePtr->data = (char *)ckalloc(imagePtr->bytes_per_line * nLines);
    bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
    firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;

    lineLength = modelPtr->width * 3;
    srcLinePtr = modelPtr->pix32 + (yStart * modelPtr->width + xStart) * 4;
    errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
    xEnd = xStart + width;

    /*
     * 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;
	}
	yEnd = yStart + nLines;
	for (y = yStart; y < yEnd; ++y) {
	    unsigned char *srcPtr = srcLinePtr;
	    schar *errPtr = errLinePtr;
	    unsigned char *destBytePtr = dstLinePtr;
	    unsigned *destLongPtr = (unsigned *) 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.
		 */

		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
			     *     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.
			     */

			    c = (x > 0) ? errPtr[-3] * 7: 0;
			    if (y > 0) {
				if (x > 0) {
				    c += errPtr[-lineLength-3];
				}
				c += errPtr[-lineLength] * 5;
				if ((x + 1) < modelPtr->width) {
				    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;
			    } else if (c > 255) {
				c = 255;
			    }
			    col[i] = colorPtr->colorQuant[i][c];
			    *errPtr++ = c - col[i];
			}
		    } else {
			/*
			 * Output is virtually continuous in this case, so
			 * don't bother dithering.
			 */

			col[0] = *srcPtr++;
			col[1] = *srcPtr++;
			col[2] = *srcPtr++;
		    }
		    srcPtr++;

		    /*
		     * Translate the quantized component values into an X
		     * pixel value, and store it in the image.
		     */

		    i = colorPtr->redValues[col[0]]
			    + colorPtr->greenValues[col[1]]
			    + colorPtr->blueValues[col[2]];
		    if (colorPtr->flags & MAP_COLORS) {
			i = colorPtr->pixelMap[i];
		    }
		    switch (bitsPerPixel) {
		    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.
			 */

		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
		}

	    } else if (bitsPerPixel > 1) {
		/*
		 * Multibit monochrome window. The operation here is similar
		 * to the color window case above, except that there is only
		 * one component. If the model image is in color, use the
		 * luminance computed as
		 *	0.344 * red + 0.5 * green + 0.156 * blue.
		 */

		for (x = xStart; x < xEnd; ++x) {
		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0) {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < modelPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if (modelPtr->flags & COLOR_IMAGE) {
			c += (unsigned) (srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    } else {
			c += srcPtr[0];
		    }
		    srcPtr += 4;

		    if (c < 0) {
			c = 0;
		    } else if (c > 255) {
			c = 255;
		    }
		    i = colorPtr->colorQuant[0][c];
		    *errPtr++ = c - i;
		    i = colorPtr->redValues[i];
		    switch (bitsPerPixel) {
		    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.
			 */

		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    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.
		 */

		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 (mask == 0) {
			*destLongPtr++ = word;
			mask = firstBit;
			word = 0;
		    }

		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0) {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < modelPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if (modelPtr->flags & COLOR_IMAGE) {
			c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    } else {
			c += srcPtr[0];
		    }
		    srcPtr += 4;

		    if (c < 0) {
			c = 0;
		    } else if (c > 255) {
			c = 255;
		    }
		    if (c >= 128) {
			word |= mask;
			*errPtr++ = c - 255;
		    } else {
			*errPtr++ = c;
		    }
		    mask = bigEndian? (mask >> 1): (mask << 1);
		}
		*destLongPtr = word;
	    }
	    srcLinePtr += modelPtr->width * 4;
	    errLinePtr += lineLength;
	    dstLinePtr += bytesPerLine;
	}

	/*
	 * Update the pixmap for this instance with the block of pixels that
	 * we have just computed.
	 */

	TkPutImage(colorPtr->pixelMap, colorPtr->numColors,
		instancePtr->display, instancePtr->pixels,
		instancePtr->gc, imagePtr, 0, 0, xStart, yStart,
		(unsigned) width, (unsigned) nLines);
	yStart = yEnd;
    }

    ckfree(imagePtr->data);
    imagePtr->data = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgResetDither --
 *
 *	This function is called to eliminate the content of a photo instance's
 *	dither error buffer. It's called when the overall image is blanked.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The instance's dither buffer gets cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkImgResetDither(
    PhotoInstance *instancePtr)
{
    if (instancePtr->error) {
	memset(instancePtr->error, 0,
		(size_t) instancePtr->modelPtr->width
		* instancePtr->modelPtr->height * 3 * sizeof(schar));
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkImgPhoto.c.

14
15
16
17
18
19
20
21










































































































































































































22
23
24
25
26
27
28
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"











































































































































































































/*
 * The following data structure is used to return information from
 * ParseSubcommandOptions:
 */

struct SubcommandOptions {







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkInt.h"
#include <ctype.h>

#ifdef __WIN32__
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#endif

/*
 * Declaration for internal Xlib function used here:
 */

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.
 */

#if defined(__STDC__) || defined(_AIX)
    typedef signed char schar;
#else
#   ifndef __CHAR_UNSIGNED__
	typedef char schar;
#   else
	typedef short schar;
#   endif
#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.
 */

typedef unsigned int pixel;

/*
 * The maximum number of pixels to transmit to the server in a single
 * XPutImage call.
 */

#define MAX_PIXELS 65536

/*
 * 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 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:
 */

typedef struct {
    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
				 * we want to allocate. */
} 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:
 */

typedef struct ColorTable {
    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	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. */
    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. */
} ColorTable;

/*
 * Bit definitions for the flags field of a ColorTable.
 * BLACK_AND_WHITE:		1 means only black and white colors are
 *				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.
 */

#ifdef COLOR_WINDOW
#undef COLOR_WINDOW
#endif

#define BLACK_AND_WHITE		1
#define COLOR_WINDOW		2
#define DISPOSE_PENDING		4
#define MAP_COLORS		8

/*
 * Definition of the data associated with each photo image master.
 */

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. */
    int	flags;			/* Sundry flags, defined below. */
    int	width, height;		/* Dimensions of image. */
    int userWidth, userHeight;	/* User-declared image dimensions. */
    Tk_Uid palette;		/* User-specified default palette for
				 * instances of this image. */
    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. */
    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. */
    struct PhotoInstance *instancePtr;
				/* 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, and so need
 *				the copy-merge-replace renderer .
 */

#define COLOR_IMAGE		1
#define IMAGE_CHANGED		2
#define COMPLEX_ALPHA		4

/*
 * Flag to OR with the compositing rule to indicate that the source, despite
 * having an alpha channel, has simple alpha.
 */

#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.
 */

typedef struct PhotoInstance {
    PhotoMaster *masterPtr;	/* Pointer to master for image. */
    Display *display;		/* Display for windows using this instance. */
    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. */
    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. */
    ColorTable *colorTablePtr;	/* Pointer to information about colors
				 * 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. */
} PhotoInstance;

/*
 * The following data structure is used to return information from
 * ParseSubcommandOptions:
 */

struct SubcommandOptions {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111






112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174


















175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

190



191
192




193
194
195









196
197
198
199
200
201
202
203





204




205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
 * 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_ALPHA:			Set if -alpha option allowed/specified.
 * OPT_BACKGROUND:		Set if -format option allowed/specified.
 * OPT_COMPOSITE:		Set if -compositingrule option allowed/spec'd.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.
 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.
 * OPT_WITHALPHA:		Set if -withalpha option allowed/specified.
 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */

#define OPT_ALPHA	1
#define OPT_BACKGROUND	2
#define OPT_COMPOSITE	4
#define OPT_FORMAT	8
#define OPT_FROM	0x10
#define OPT_GRAYSCALE	0x20
#define OPT_SHRINK	0x40
#define OPT_SUBSAMPLE	0x80
#define OPT_TO		0x100
#define OPT_WITHALPHA	0x200
#define OPT_ZOOM	0x400

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {
    "-alpha",
    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",
    "-shrink",
    "-subsample",
    "-to",
    "-withalpha",
    "-zoom",
    NULL
};

/*
 * 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"

/*
 * Functions used in the type record for photo images.
 */

static int		ImgPhotoCreate(Tcl_Interp *interp, const char *name,
			    int objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);






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);

/*
 * The type record itself for photo images:
 */

Tk_ImageType tkPhotoImageType = {
    "photo",			/* name */
    ImgPhotoCreate,		/* createProc */
    TkImgPhotoGet,		/* getProc */
    TkImgPhotoDisplay,		/* displayProc */
    TkImgPhotoFree,		/* freeProc */
    ImgPhotoDelete,		/* deleteProc */
    ImgPhotoPostscript,		/* postscriptProc */
    NULL,			/* nextPtr */
    NULL
};

typedef struct {
    Tk_PhotoImageFormat *formatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    Tk_PhotoImageFormat *oldFormatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/
#endif
    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Default configuration
 */

#define DEF_PHOTO_GAMMA		"1"
#define DEF_PHOTO_HEIGHT	"0"
#define DEF_PHOTO_PALETTE	""
#define DEF_PHOTO_WIDTH		"0"

/*
 * Information used for parsing configuration specifications:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, offsetof(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, offsetof(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, offsetof(PhotoModel, userHeight), 0, NULL},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, offsetof(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, offsetof(PhotoModel, userWidth), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};



















/*
 * Forward declarations
 */

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(ClientData clientData);
static int		ImgPhotoConfigureModel(Tcl_Interp *interp,
			    PhotoModel *modelPtr, int objc,
			    Tcl_Obj *const objv[], int flags);

static int		ToggleComplexAlphaIfNeeded(PhotoModel *mPtr);



static int		ImgPhotoSetSize(PhotoModel *modelPtr, int width,
			    int height);




static char *		ImgGetPhoto(PhotoModel *modelPtr,
			    Tk_PhotoImageBlock *blockPtr,
			    struct SubcommandOptions *optPtr);









static int		MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *formatString,
			    Tk_PhotoImageFormat **imageFormatPtr,
			    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 const char *	GetExtension(const char *path);





/*
 *----------------------------------------------------------------------
 *
 * PhotoFormatThreadExitProc --
 *
 *	Clean up the registered list of photo formats.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The thread's linked lists of photo image formats is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
PhotoFormatThreadExitProc(
    TCL_UNUSED(void *))	/* not used */
{
    Tk_PhotoImageFormat *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    while (tsdPtr->oldFormatList != NULL) {
	freePtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr;
	ckfree(freePtr);
    }
#endif
    while (tsdPtr->formatList != NULL) {
	freePtr = tsdPtr->formatList;
	tsdPtr->formatList = tsdPtr->formatList->nextPtr;
	ckfree((char *)freePtr->name);
	ckfree(freePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat --







<








<



<
|
|
|
|
|
|
|
|
<
|







<








<
















|
|
|

>
>
>
>
>
>













|
|
|


|
<


|



<



<

|
















|

|

|

|

|

|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|





|
|

>
|
>
>
>
|

>
>
>
>
|


>
>
>
>
>
>
>
>
>

|






>
>
>
>
>
|
>
>
>
>



















|





<



|

<



|
|







246
247
248
249
250
251
252

253
254
255
256
257
258
259
260

261
262
263

264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338

339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477

478
479
480
481
482
483
484
485
486
487
488
489
/*
 * 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.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.
 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.

 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */


#define OPT_BACKGROUND	1
#define OPT_COMPOSITE	2
#define OPT_FORMAT	4
#define OPT_FROM	8
#define OPT_GRAYSCALE	0x10
#define OPT_SHRINK	0x20
#define OPT_SUBSAMPLE	0x40
#define OPT_TO		0x80

#define OPT_ZOOM	0x100

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {

    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",
    "-shrink",
    "-subsample",
    "-to",

    "-zoom",
    NULL
};

/*
 * 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"

/*
 * Functions used in the type record for photo images.
 */

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(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(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);

/*
 * The type record itself for photo images:
 */

Tk_ImageType tkPhotoImageType = {
    "photo",			/* name */
    ImgPhotoCreate,		/* createProc */
    ImgPhotoGet,		/* getProc */
    ImgPhotoDisplay,		/* displayProc */
    ImgPhotoFree,		/* freeProc */
    ImgPhotoDelete,		/* deleteProc */
    ImgPhotoPostscript,		/* postscriptProc */
    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. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Default configuration
 */

#define DEF_PHOTO_GAMMA		"1"
#define DEF_PHOTO_HEIGHT	"0"
#define DEF_PHOTO_PALETTE	""
#define DEF_PHOTO_WIDTH		"0"

/*
 * Information used for parsing configuration specifications:
 */

static Tk_ConfigSpec configSpecs[] = {
    {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", NULL, NULL,
	 DEF_PHOTO_HEIGHT, Tk_Offset(PhotoMaster, userHeight), 0},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, Tk_Offset(PhotoMaster, palette), 0},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, Tk_Offset(PhotoMaster, userWidth), 0},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Hash table used to hash from (display, colormap, palette, gamma) to
 * ColorTable address.
 */

static Tcl_HashTable imgPhotoColorHash;
static int imgPhotoColorHashInitialized;
#define N_COLOR_HASH	(sizeof(ColorTableId) / sizeof(int))

/*
 * Implementation of the Porter-Duff Source-Over compositing rule.
 */

#define PD_SRC_OVER(srcColor,srcAlpha,dstColor,dstAlpha) \
	(srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255
#define PD_SRC_OVER_ALPHA(srcAlpha,dstAlpha) \
	(srcAlpha + (255-srcAlpha)*dstAlpha/255)

/*
 * Forward declarations
 */

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(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(PhotoMaster *masterPtr,
			    Tk_PhotoImageBlock *blockPtr,
			    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(Tcl_Interp *interp, Tcl_Obj *data,
			    Tcl_Obj *formatString,
			    Tk_PhotoImageFormat **imageFormatPtr,
			    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))
#undef MAX
#define MAX(a, b)	((a) > (b)? (a): (b))

/*
 *----------------------------------------------------------------------
 *
 * PhotoFormatThreadExitProc --
 *
 *	Clean up the registered list of photo formats.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The thread's linked lists of photo image formats is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
PhotoFormatThreadExitProc(
    ClientData clientData)	/* not used */
{
    Tk_PhotoImageFormat *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    while (tsdPtr->oldFormatList != NULL) {
	freePtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr;
	ckfree((char *) freePtr);
    }

    while (tsdPtr->formatList != NULL) {
	freePtr = tsdPtr->formatList;
	tsdPtr->formatList = tsdPtr->formatList->nextPtr;
	ckfree((char *) freePtr->name);
	ckfree((char *) freePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat --
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
 * Side effects:
 *	The new image file format is entered into a table used in the photo
 *	image "read" and "write" subcommands.
 *
 *----------------------------------------------------------------------
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
void
Tk_CreateOldPhotoImageFormat(
    const 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));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *)ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;
    copyPtr->nextPtr = tsdPtr->oldFormatList;
    tsdPtr->oldFormatList = copyPtr;
}
#endif

void
Tk_CreatePhotoImageFormat(
    const 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));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *)ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    if (isupper((unsigned char) *formatPtr->name)) {
	copyPtr->nextPtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = copyPtr;
    } else
#endif
    {
	/* for compatibility with aMSN: make a copy of formatPtr->name */
	char *name = (char *)ckalloc(strlen(formatPtr->name) + 1);
	strcpy(name, formatPtr->name);
	copyPtr->name = name;
	copyPtr->nextPtr = tsdPtr->formatList;
	tsdPtr->formatList = copyPtr;
    }
}








<


|












|




<



|












|

<



|
<
<

|







498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546


547
548
549
550
551
552
553
554
555
 * Side effects:
 *	The new image file format is entered into a table used in the photo
 *	image "read" and "write" subcommands.
 *
 *----------------------------------------------------------------------
 */


void
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));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;
    copyPtr->nextPtr = tsdPtr->oldFormatList;
    tsdPtr->oldFormatList = copyPtr;
}


void
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));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;

    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;
    }
}

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const 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). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* 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. */
{
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image model record.
     */

    modelPtr = (PhotoModel *)ckalloc(sizeof(PhotoModel));
    memset(modelPtr, 0, sizeof(PhotoModel));
    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    modelPtr, ImgPhotoCmdDeletedProc);
    modelPtr->palette = NULL;
    modelPtr->pix32 = NULL;
    modelPtr->instancePtr = NULL;
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Process configuration options given in the image create command.
     */

    if (ImgPhotoConfigureModel(interp, modelPtr, objc, objv, 0) != TCL_OK) {
	ImgPhotoDelete(modelPtr);
	return TCL_ERROR;
    }

    *clientDataPtr = modelPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmd --







|

|

|
|




|


|


|
|
|
|
|
|
|
|
|
|





|
|



|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
 *----------------------------------------------------------------------
 */

static int
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
				 * 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. */
{
    PhotoMaster *masterPtr;

    /*
     * Allocate and initialize the photo image master record.
     */

    masterPtr = (PhotoMaster *) ckalloc(sizeof(PhotoMaster));
    memset(masterPtr, 0, sizeof(PhotoMaster));
    masterPtr->tkMaster = master;
    masterPtr->interp = interp;
    masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    (ClientData) masterPtr, ImgPhotoCmdDeletedProc);
    masterPtr->palette = NULL;
    masterPtr->pix32 = NULL;
    masterPtr->instancePtr = NULL;
    masterPtr->validRegion = TkCreateRegion();

    /*
     * Process configuration options given in the image create command.
     */

    if (ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, 0) != TCL_OK) {
	ImgPhotoDelete((ClientData) masterPtr);
	return TCL_ERROR;
    }

    *clientDataPtr = (ClientData) masterPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmd --
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435



436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550
551
552
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    ClientData clientData,	/* Information about photo model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const photoOptions[] = {
	"blank", "cget", "configure", "copy", "data", "get", "put",
	"read", "redither", "transparency", "write", NULL
    };
    enum PhotoOptions {
	PHOTO_BLANK, PHOTO_CGET, PHOTO_CONFIGURE, PHOTO_COPY, PHOTO_DATA,
	PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS,
	PHOTO_WRITE
    };

    PhotoModel *modelPtr = (PhotoModel *)clientData;
    int result, index, x, y, width, height;
    struct SubcommandOptions options;

    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;

    Tk_PhotoImageFormat *imageFormat;
    TkSizeT length;
    int imageWidth, imageHeight, matched, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], photoOptions, "option", 0,
	    &index) != TCL_OK) {



	return TCL_ERROR;


    }

    switch ((enum PhotoOptions) index) {
    case PHOTO_BLANK:
	/*
	 * photo blank command - just call Tk_PhotoBlank.
	 */

	if (objc == 2) {
	    Tk_PhotoBlank(modelPtr);
	    return TCL_OK;
	} else {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	if (strncmp(arg,"-data", length) == 0) {
	    if (modelPtr->dataString) {
		Tcl_SetObjResult(interp, modelPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", length) == 0) {
	    if (modelPtr->format) {
		Tcl_SetObjResult(interp, modelPtr->format);
	    }
	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    (char *) modelPtr, Tcl_GetString(objv[2]), 0);
	}
	return TCL_OK;
    }

    case PHOTO_CONFIGURE:
	/*
	 * photo configure command - handle this in the standard way.
	 */

	if (objc == 2) {
	    Tcl_Obj *obj, *subobj;

	    result = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr, NULL, 0);
	    if (result != TCL_OK) {
		return result;
	    }
	    obj = Tcl_NewObj();
	    subobj = Tcl_NewStringObj("-data {} {} {}", 14);
	    if (modelPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->dataString);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-format {} {} {}", 16);
	    if (modelPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->format);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    const char *arg = TkGetStringFromObj(objv[2], &length);

	    if (length > 1 && !strncmp(arg, "-data", length)) {
		Tcl_AppendResult(interp, "-data {} {} {}", NULL);
		if (modelPtr->dataString) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->dataString);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		    !strncmp(arg, "-format", length)) {
		Tcl_AppendResult(interp, "-format {} {} {}", NULL);
		if (modelPtr->format) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->format);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) modelPtr, arg, 0);
	    }
	} else {

	    return ImgPhotoConfigureModel(interp, modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}

    case PHOTO_COPY:
	/*
	 * photo copy command - first parse options.
	 */

	index = 2;







|


|

|









|
|

>


>

<
|






|





>
>
>
|
>
>









|







|





|
|
|
|

|
|
|



|













|





|
|





|
|









|

|

|
<
<
<
<
|
|





|

|
<
<
<
<
|
|






|

<
>
|
|
<







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755




756
757
758
759
760
761
762
763
764
765




766
767
768
769
770
771
772
773
774
775

776
777
778

779
780
781
782
783
784
785
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    ClientData clientData,	/* Information about photo master. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    static const char *photoOptions[] = {
	"blank", "cget", "configure", "copy", "data", "get", "put",
	"read", "redither", "transparency", "write", NULL
    };
    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, x, y, width, height, dataWidth, dataHeight, listObjc;
    struct SubcommandOptions options;
    Tcl_Obj **listObjv, **srcObjv;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_Window tkwin;
    Tk_PhotoImageFormat *imageFormat;

    int imageWidth, imageHeight, matched, length, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], photoOptions, "option", 0,
	    &index) != TCL_OK) {
	Tcl_ObjCmdProc *proc;
	proc = PhotoOptionFind(interp, objv[1]);
	if (proc == NULL) {
	    return TCL_ERROR;
	}
	return proc(clientData, interp, objc, objv);
    }

    switch ((enum PhotoOptions) index) {
    case PHOTO_BLANK:
	/*
	 * photo blank command - just call Tk_PhotoBlank.
	 */

	if (objc == 2) {
	    Tk_PhotoBlank(masterPtr);
	    return TCL_OK;
	} else {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

    case PHOTO_CGET: {
	char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = Tcl_GetStringFromObj(objv[2], &length);
	if (strncmp(arg,"-data", (unsigned) length) == 0) {
	    if (masterPtr->dataString) {
		Tcl_SetObjResult(interp, masterPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", (unsigned) length) == 0) {
	    if (masterPtr->format) {
		Tcl_SetObjResult(interp, masterPtr->format);
	    }
	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    (char *) masterPtr, Tcl_GetString(objv[2]), 0);
	}
	return TCL_OK;
    }

    case PHOTO_CONFIGURE:
	/*
	 * photo configure command - handle this in the standard way.
	 */

	if (objc == 2) {
	    Tcl_Obj *obj, *subobj;

	    result = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) masterPtr, NULL, 0);
	    if (result != TCL_OK) {
		return result;
	    }
	    obj = Tcl_NewObj();
	    subobj = Tcl_NewStringObj("-data {} {} {}", 14);
	    if (masterPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, masterPtr->dataString);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-format {} {} {}", 16);
	    if (masterPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, masterPtr->format);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    char *arg = Tcl_GetStringFromObj(objv[2], &length);

	    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_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } 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_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) masterPtr, arg, 0);
	    }

	}
	return ImgPhotoConfigureMaster(interp, masterPtr, objc-2, objv+2,
		TK_CONFIG_ARGV_ONLY);


    case PHOTO_COPY:
	/*
	 * photo copy command - first parse options.
	 */

	index = 2;
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
	/*
	 * Look for the source image and get a pointer to its image data.
	 * Check the values given for the -from option.
	 */

	srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name));
	if (srcHandle == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image \"%s\" doesn't exist or is not a photo image",
		    Tcl_GetString(options.name)));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO",
		    Tcl_GetString(options.name), NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
		|| (options.fromX2 > block.width)
		|| (options.fromY2 > block.height)) {
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */

	if (!(((PhotoModel *) srcHandle)->flags & COMPLEX_ALPHA)) {
	    options.compositingRule |= SOURCE_IS_SIMPLE_ALPHA_PHOTO;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */








|
<
|
<
|






<
<
<
|
|
<
<








|







802
803
804
805
806
807
808
809

810

811
812
813
814
815
816
817



818
819


820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
	/*
	 * Look for the source image and get a pointer to its image data.
	 * Check the values given for the -from option.
	 */

	srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name));
	if (srcHandle == NULL) {
	    Tcl_AppendResult(interp, "image \"",

		    Tcl_GetString(options.name), "\" doesn't",

		    " exist or is not a photo image", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
		|| (options.fromX2 > block.width)
		|| (options.fromY2 > block.height)) {



	    Tcl_AppendResult(interp, "coordinates for -from option extend ",
		    "outside source image", NULL);


	    return TCL_ERROR;
	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */

	if (!(((PhotoMaster *) srcHandle)->flags & COMPLEX_ALPHA)) {
	    options.compositingRule |= SOURCE_IS_SIMPLE_ALPHA_PHOTO;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

630
631
632
633
634
635
636













637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763


764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781


782
783
784
785
786
787
788
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888

































































































































889
890
891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
		height = 0;
	    } else {
		height = (height - options.subsampleY - 1)
			/ -options.subsampleY;
	    }
	    options.toY2 = options.toY + height * options.zoomY;
	}














	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	block.pixelPtr += options.fromX * block.pixelSize
		+ options.fromY * block.pitch;
	block.width = options.fromX2 - options.fromX;
	block.height = options.fromY2 - options.fromY;
	result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
		&block, options.toX, options.toY, options.toX2 - options.toX,
		options.toY2 - options.toY, options.zoomX, options.zoomY,
		options.subsampleX, options.subsampleY,
		options.compositingRule);

	/*
	 * Set the destination image size if the -shrink option was specified.
	 * This has to be done _after_ copying the data. Otherwise, if source
	 * and destination are the same image, block.pixelPtr would point to
	 * an invalid memory block (bug [5239fd749b]).
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX2,
		    options.toY2) != TCL_OK) {
		if (options.background) {
		    Tk_FreeColor(options.background);
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
		return TCL_ERROR;
	    }
	}
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	return result;

    case PHOTO_DATA: {
        char *data = NULL;
        Tcl_Obj *freeObj = NULL;

	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;

	index = 1;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.fromX = 0;
	options.fromY = 0;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (!(options.options & OPT_FORMAT)) {
            options.format = Tcl_NewStringObj("default", -1);
            freeObj = options.format;
	}

	/*
	 * Search for an appropriate image string format handler.
	 */


	matched = 0;
	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
                imageFormat = imageFormat->nextPtr) {
	    if ((strncasecmp(Tcl_GetString(options.format),
                    imageFormat->name, strlen(imageFormat->name)) == 0)) {
                matched = 1;
                if (imageFormat->stringWriteProc != NULL) {
                    stringWriteProc = imageFormat->stringWriteProc;
                    break;
                }
	    }
	}
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
	if (stringWriteProc == NULL) {
	    oldformat = 1;
	    for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
                    imageFormat = imageFormat->nextPtr) {
                if ((strncasecmp(Tcl_GetString(options.format),
                        imageFormat->name,
                        strlen(imageFormat->name)) == 0)) {
                    matched = 1;
                    if (imageFormat->stringWriteProc != NULL) {
                        stringWriteProc = imageFormat->stringWriteProc;
                        break;
                    }
                }
	    }
	}
#endif
	if (stringWriteProc == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                    "image string format \"%s\" is %s",
                    Tcl_GetString(options.format),
                    (matched ? "not supported" : "unknown")));


	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
                    Tcl_GetString(options.format), NULL);
	    goto dataErrorExit;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);

	if (oldformat) {
	    Tcl_DString buffer;
	    typedef int (*OldStringWriteProc)(Tcl_Interp *interp,
		    Tcl_DString *dataPtr, const char *formatString,
		    Tk_PhotoImageBlock *blockPtr);

	    Tcl_DStringInit(&buffer);


	    result = ((OldStringWriteProc)(void *)stringWriteProc)(interp, &buffer,
		    Tcl_GetString(options.format), &block);
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {

	    typedef int (*NewStringWriteProc)(Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
		    void *dummy);

	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block, NULL);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return result;

      dataErrorExit:
        if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return TCL_ERROR;
    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */

	Tcl_Obj *channels[4];
	int channelCount = 3;

        index = 3;
        memset(&options, 0, sizeof(options));
        options.name = NULL;
        if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA,
                &index, objc, objv) != TCL_OK) {
            return TCL_ERROR;
        }
        if (options.name == NULL || index < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?");
	    return TCL_ERROR;
	}
        if (options.options & OPT_WITHALPHA) {
            channelCount = 4;
        }

	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s get: coordinates out of range",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
		    NULL);
	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a list.
	 */

	pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	channels[0] = Tcl_NewWideIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewWideIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewWideIntObj(pixelPtr[2]);
	channels[3] = Tcl_NewWideIntObj(pixelPtr[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	return TCL_OK;
    }

    case PHOTO_PUT: {
	Tcl_Obj *format, *data;

	/*
	 * photo put command - first parse the options.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?");
	    return TCL_ERROR;

































































































































	}

	/*
	 * See if there's a format that can read the data

	 */

	if (MatchStringFormat(interp, objv[2], options.format, &imageFormat,
		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + imageWidth;
	    options.toY2 = options.toY + imageHeight;
	}
	if (imageWidth > options.toX2 - options.toX) {
	    imageWidth = options.toX2 - options.toX;
	}
	if (imageHeight > options.toY2 - options.toY) {
	    imageHeight = options.toY2 - options.toY;
	}

	format = options.format;
	data = objv[2];
	if (oldformat) {
	    if (format) {
		format = (Tcl_Obj *) Tcl_GetString(format);
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	}

	if (imageFormat->stringReadProc(interp, data, format,
		(Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		options.toX2 - options.toX,
		options.toY2 - options.toY, 0, 0) != TCL_OK) {
	    return TCL_ERROR;
	}
	/*
	 * SB: is the next line really needed? The stringReadProc
	 * writes image data with Tk_PhotoPutBlock(), which in turn
	 * takes care to notify the changed image and to set/unset the
	 * IMAGE_CHANGED bit.
	 */
	modelPtr->flags |= IMAGE_CHANGED;


	return TCL_OK;
    }
    case PHOTO_READ: {
	Tcl_Obj *format;

	/*
	 * photo read command - first parse the options specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_TO | OPT_SHRINK,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */








>
>
>
>
>
>
>
>
>
>
>
>
>









|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<







|










|
|


|
|
|
|
<
|
|







|
|
|
<
<
<
<






>
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
|
|
|
>
>
|
|
<






|



<
<
<


>
>
|
|






>
|

|
<
<
|







<
<
<

<
<
<
<
<
<
<
<
<
<
<
<







<
<
|
<
<
<
<
<
<
|
|
|


<
<
<
<




|
|
|
|
<
<
<




|


|
|
<
|
<
|



|
<
<

|





<





|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
>


<
<
<
<
<

|
|

<
|
<
<
|
<
>
|
|
<
<
|
<
|
<
|
|
|
<
|
<
<
<
<
<
<
<
<
<
|
>
|
|

















|








|
|
<







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890


























891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929
930




931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964

965

966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982



983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998


999
1000
1001
1002
1003
1004
1005
1006



1007












1008
1009
1010
1011
1012
1013
1014


1015






1016
1017
1018
1019
1020




1021
1022
1023
1024
1025
1026
1027
1028



1029
1030
1031
1032
1033
1034
1035
1036
1037

1038

1039
1040
1041
1042
1043


1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193





1194
1195
1196
1197

1198


1199

1200
1201
1202


1203

1204

1205
1206
1207

1208









1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
		height = 0;
	    } else {
		height = (height - options.subsampleY - 1)
			/ -options.subsampleY;
	    }
	    options.toY2 = options.toY + height * options.zoomY;
	}

	/*
	 * Set the destination image size if the -shrink option was specified.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(masterPtr, options.toX2,
		    options.toY2) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	block.pixelPtr += options.fromX * block.pixelSize
		+ options.fromY * block.pitch;
	block.width = options.fromX2 - options.fromX;
	block.height = options.fromY2 - options.fromY;
	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);



























    case PHOTO_DATA: {
	char *data;


	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.fromX = 0;
	options.fromY = 0;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name != NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?options?");
	    return TCL_ERROR;
	}
	if ((options.fromX > masterPtr->width)
		|| (options.fromY > masterPtr->height)
		|| (options.fromX2 > masterPtr->width)
		|| (options.fromY2 > masterPtr->height)) {

	    Tcl_AppendResult(interp, "coordinates for -from option extend ",
		    "outside image", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

	if (((options.options & OPT_FROM) == 0) || (options.fromX2 < 0)) {
	    options.fromX2 = masterPtr->width;
	    options.fromY2 = masterPtr->height;




	}

	/*
	 * Search for an appropriate image string format handler.
	 */

	if (options.options & OPT_FORMAT) {
	    matched = 0;
	    for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
	 	imageFormat = imageFormat->nextPtr) {
		if ((strncasecmp(Tcl_GetString(options.format),
			imageFormat->name, strlen(imageFormat->name)) == 0)) {
		    matched = 1;
		    if (imageFormat->stringWriteProc != NULL) {
			stringWriteProc = imageFormat->stringWriteProc;
			break;
		    }
		}
	    }

	    if (stringWriteProc == NULL) {
		oldformat = 1;
		for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
			imageFormat = imageFormat->nextPtr) {
		    if ((strncasecmp(Tcl_GetString(options.format),
			    imageFormat->name,
			    strlen(imageFormat->name)) == 0)) {
			matched = 1;
			if (imageFormat->stringWriteProc != NULL) {
			    stringWriteProc = imageFormat->stringWriteProc;
			    break;
			}
		    }
		}
	    }

	    if (stringWriteProc == NULL) {

		Tcl_AppendResult(interp, "image string format \"",
			Tcl_GetString(options.format), "\" is ",
			(matched ? "not supported" : "unknown"), NULL);
		return TCL_ERROR;
	    }
	} else {
	    stringWriteProc = ImgStringWrite;

	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(masterPtr, &block, &options);

	if (oldformat) {
	    Tcl_DString buffer;




	    Tcl_DStringInit(&buffer);
	    result = ((int (*) (Tcl_Interp *interp,
		    Tcl_DString *dataPtr, char *formatString,
		    Tk_PhotoImageBlock *blockPtr))(void *)stringWriteProc)
		    (interp, &buffer, Tcl_GetString(options.format), &block);
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {

	    result = ((int (*) (Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
		    void *dummy))(void *)stringWriteProc)


		    (interp, options.format, &block, NULL);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}



	return result;












    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */



	char string[TCL_INTEGER_SPACE * 3];







	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y");
	    return TCL_ERROR;
	}




	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= masterPtr->width)
		|| (y < 0) || (y >= masterPtr->height)) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " get: ",
		    "coordinates out of range", NULL);



	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a string.
	 */

	pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	sprintf(string, "%d %d %d", pixelPtr[0], pixelPtr[1],

		pixelPtr[2]);

	Tcl_AppendResult(interp, string, NULL);
	return TCL_OK;
    }

    case PHOTO_PUT:


	/*
	 * photo put command - first parse the options and colors specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;

	if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?options?");
	    return TCL_ERROR;
	}

	if (MatchStringFormat(interp, options.name ? objv[2]:NULL,
		options.format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) == TCL_OK) {
	    Tcl_Obj *format, *data;

	    if (((options.options & OPT_TO) == 0) || (options.toX2 < 0)) {
		options.toX2 = options.toX + imageWidth;
		options.toY2 = options.toY + imageHeight;
	    }
	    if (imageWidth > options.toX2 - options.toX) {
		imageWidth = options.toX2 - options.toX;
	    }
	    if (imageHeight > options.toY2 - options.toY) {
		imageHeight = options.toY2 - options.toY;
	    }
	    format = options.format;
	    data = objv[2];
	    if (oldformat) {
		if (format) {
		    format = (Tcl_Obj *) Tcl_GetString(format);
		}
		data = (Tcl_Obj *) Tcl_GetString(data);
	    }
	    if ((*imageFormat->stringReadProc)(interp, data,
		    format, (Tk_PhotoHandle) masterPtr,
		    options.toX, options.toY, imageWidth, imageHeight,
		    0, 0) != TCL_OK) {
		return TCL_ERROR;
	    }
	    masterPtr->flags |= IMAGE_CHANGED;
	    return TCL_OK;
	}
	if (options.options & OPT_FORMAT) {
	    return TCL_ERROR;
	}
	Tcl_ResetResult(interp);
	if (Tcl_ListObjGetElements(interp, options.name,
		&dataHeight, &srcObjv) != TCL_OK) {
	    return TCL_ERROR;
	}
	tkwin = Tk_MainWindow(interp);
	block.pixelPtr = NULL;
	dataWidth = 0;
	pixelPtr = NULL;
	for (y = 0; y < dataHeight; ++y) {
	    if (Tcl_ListObjGetElements(interp, srcObjv[y],
		    &listObjc, &listObjv) != TCL_OK) {
		break;
	    }

	    if (y == 0) {
		if (listObjc == 0) {
		    /*
		     * Lines must be non-empty...
		     */

		    break;
		}
		dataWidth = listObjc;
		pixelPtr = (unsigned char *)
			ckalloc((unsigned) dataWidth * dataHeight * 3);
		block.pixelPtr = pixelPtr;
	    } else if (listObjc != dataWidth) {
		Tcl_AppendResult(interp, "all elements of color list must",
			" 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),
			colorString, &color)) {
		    Tcl_AppendResult(interp, "can't parse color \"",
			    colorString, "\"", NULL);
		    break;
		}
		*pixelPtr++ = color.red >> 8;
		*pixelPtr++ = color.green >> 8;
		*pixelPtr++ = color.blue >> 8;
	    }
	    if (x < dataWidth) {
		break;
	    }
	}
	if (y < dataHeight || dataHeight == 0 || dataWidth == 0) {
	    if (block.pixelPtr != NULL) {
		ckfree((char *) block.pixelPtr);
	    }
	    if (y < dataHeight) {
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}

	/*
	 * Fill in default values for the -to option, then copy the block in
	 * using Tk_PhotoPutBlock.
	 */






	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + dataWidth;
	    options.toY2 = options.toY + dataHeight;
	}

	block.width = dataWidth;


	block.height = dataHeight;

	block.pitch = dataWidth * 3;
	block.pixelSize = 3;
	block.offset[0] = 0;


	block.offset[1] = 1;

	block.offset[2] = 2;

	block.offset[3] = 0;
	result = Tk_PhotoPutBlock(interp, (ClientData)masterPtr, &block,
		options.toX, options.toY, options.toX2 - options.toX,

		options.toY2 - options.toY,









		TK_PHOTO_COMPOSITE_SET);
	ckfree((char *) block.pixelPtr);
	return result;

    case PHOTO_READ: {
	Tcl_Obj *format;

	/*
	 * photo read command - first parse the options specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_TO | OPT_SHRINK,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?options?");
	    return TCL_ERROR;
	}

	/*
	 * 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;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151


1152
1153
1154
1155
1156







1157


1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244







1245
1246
1247
1248

1249







1250



1251

1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387

1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544


















1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563





1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576





1577
1578
1579
1580
1581
1582
1583




1584



1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

1595

1596


1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616


1617

1618
1619
1620
1621
1622
1623
1624
	/*
	 * Check the values given for the -from option.
	 */

	if ((options.fromX > imageWidth) || (options.fromY > imageHeight)
		|| (options.fromX2 > imageWidth)
		|| (options.fromY2 > imageHeight)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}
	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    width = imageWidth - options.fromX;
	    height = imageHeight - options.fromY;
	} else {
	    width = options.fromX2 - options.fromX;
	    height = options.fromY2 - options.fromY;
	}

	/*
	 * If the -shrink option was specified, set the size of the image.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX + width,
		    options.toY + height) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
		Tcl_Close(NULL, chan);
		return TCL_ERROR;
	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
	 * image.
	 */

	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(format);
	}
	result = imageFormat->fileReadProc(interp, chan,
		Tcl_GetString(options.name),
		format, (Tk_PhotoHandle) modelPtr, options.toX,
		options.toY, width, height, options.fromX, options.fromY);
	if (chan != NULL) {
	    Tcl_Close(NULL, chan);
	}
	return result;
    }

    case PHOTO_REDITHER:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

	/*
	 * Call Dither if any part of the image is not correctly dithered at
	 * present.
	 */

	x = modelPtr->ditherX;
	y = modelPtr->ditherY;
	if (modelPtr->ditherX != 0) {
	    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y,
		    modelPtr->width - x, 1);
	}
	if (modelPtr->ditherY < modelPtr->height) {
	    x = 0;
	    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, 0,
		    modelPtr->ditherY, modelPtr->width,
		    modelPtr->height - modelPtr->ditherY);
	}

	if (y < modelPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y,
		    (modelPtr->width - x), (modelPtr->height - y),
		    modelPtr->width, modelPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *const photoTransOptions[] = {
	    "get", "set", NULL
	};
	enum transOptions {
	    PHOTO_TRANS_GET, PHOTO_TRANS_SET
	};

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[2], photoTransOptions, "option",
		0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch ((enum transOptions) index) {
	case PHOTO_TRANS_GET: {
	    int boolMode;

	    /*
	     * parse fixed args and option
	     */

	    if (objc > 6 || objc < 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y ?-option?");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }

	    index = 4;
	    memset(&options, 0, sizeof(options));
	    if (ParseSubcommandOptions(&options, interp,
		    OPT_ALPHA, &index, objc, objv) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		    || (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency get: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Extract and return the desired value
	     */


	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3]));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));







	    }


	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
	    int newVal, boolMode;
	    XRectangle setBox;
	    TkRegion modRegion;

	    /*
	     * Parse args and option, check for valid values
	     */

	    if (objc < 6 || objc > 7) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y newVal ?-option?");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }

	    index = 5;
	    memset(&options, 0, sizeof(options));
	    if (ParseSubcommandOptions(&options, interp,
		    OPT_ALPHA, &index, objc, objv) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency set: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    if (boolMode) {
		if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else {
		if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (newVal < 0 || newVal > 255) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "invalid alpha value \"%d\": "
			    "must be integer between 0 and 255", newVal));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "BAD_VALUE", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
	     * Set new alpha value for the pixel
	     */

	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		pixelPtr[3] = newVal ? 0 : 255;
	    } else {
		pixelPtr[3] = newVal;
	    }

	    /*
	     * Update the validRegion of the image
	     */

	    setBox.x = x;
	    setBox.y = y;
	    setBox.width = 1;
	    setBox.height = 1;







	    modRegion = TkCreateRegion();
	    TkUnionRectWithRegion(&setBox, modRegion, modRegion);
	    if (pixelPtr[3]) {
		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,

			modelPtr->validRegion);







	    } else {



		TkSubtractRegion(modelPtr->validRegion, modRegion,

			modelPtr->validRegion);

	    }
	    TkDestroyRegion(modRegion);

	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y, 1, 1,
		    modelPtr->width, modelPtr->height);
	    modelPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");
    }

    case PHOTO_WRITE: {
	char *data;
	const char *fmtString;
	Tcl_Obj *format;
	int usedExt;

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't write image to a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * photo write command - first parse and check any options given.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters. Note that a
	 * missing -format flag results in us having a guess from the file
	 * extension. [Bug 2983824]
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (options.format == NULL) {
	    fmtString = GetExtension(Tcl_GetString(options.name));
	    usedExt = (fmtString != NULL);
	} else {
	    fmtString = Tcl_GetString(options.format);
	    usedExt = 0;
	}

	/*
	 * Search for an appropriate image file format handler, and give an
	 * error if none is found.
	 */

	matched = 0;
    redoFormatLookup:
	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
	    if ((fmtString == NULL)
		    || (strncasecmp(fmtString, imageFormat->name,
			    strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->fileWriteProc != NULL) {
		    break;
		}
	    }
	}
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
	if (imageFormat == NULL) {
	    oldformat = 1;
	    for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
		    imageFormat = imageFormat->nextPtr) {
		if ((fmtString == NULL)
			|| (strncasecmp(fmtString, imageFormat->name,
				strlen(imageFormat->name)) == 0)) {
		    matched = 1;
		    if (imageFormat->fileWriteProc != NULL) {
			break;
		    }
		}
	    }
	}
#endif
	if (usedExt && !matched) {
	    /*
	     * If we didn't find one and we're using file extensions as the
	     * basis for the guessing, go back and look again without
	     * prejudice. Supports old broken code.
	     */

	    usedExt = 0;
	    fmtString = NULL;
	    goto redoFormatLookup;
	}
	if (imageFormat == NULL) {
	    if (fmtString == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no available image file format has file writing"
			" capability", -1));
	    } else if (!matched) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(

			"image file format \"%s\" is unknown", fmtString));
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(

			"image file format \"%s\" has no file writing capability",
			fmtString));
	    }
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    fmtString, NULL);
	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);
	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(options.format);
	}
	result = imageFormat->fileWriteProc(interp,
		Tcl_GetString(options.name), format, &block);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	return result;
    }

    }
    Tcl_Panic("unexpected fallthrough");
    return TCL_ERROR; /* NOT REACHED */
}

/*
 *----------------------------------------------------------------------
 *
 * GetExtension --
 *
 *	Return the extension part of a path, or NULL if there is no extension.
 *	The returned string will be a substring of the argument string, so
 *	should not be ckfree()d directly. No side effects.
 *
 *----------------------------------------------------------------------
 */

static const char *
GetExtension(
    const char *path)
{
    char c;
    const char *extension = NULL;

    for (; (c=*path++) != '\0' ;) {
	if (c == '.') {
	    extension = path;
	}
    }
    if (extension != NULL && extension[0] == '\0') {
	extension = NULL;
    }
    return extension;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseSubcommandOptions --
 *
 *	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, -compositingrule, -alpha, -boolean and
 *	-withalpha.
 *	Parsing starts at the index in *optIndexPtr and stops at the end of
 *	objv[] or at the first value that does not belong to an option.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Fields in *optPtr get filled in. The value of optIndexPtr is updated
 *	to contain the index of the first element in argv[] that was not
 *	parsed, or argc if the end of objv[] was reached.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    static const char *const compositingRules[] = {
	"overlay", "set",	/* Note that these must match the
				 * TK_PHOTO_COMPOSITE_* constants. */
	NULL
    };
    TkSizeT length;
    int index, c, bit, currentBit;
    int values[4], numValues, maxValues, argIndex;
    const char *option, *expandedOption, *needed;
    const char *const *listPtr;
    Tcl_Obj *msgObj;

    for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) {
	/*
	 * We can have one value specified without an option; it goes into
	 * optPtr->name.
	 */

	expandedOption = option = TkGetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}

	/*
	 * Work out which option this is.
	 */

	c = option[0];
	bit = 0;
	currentBit = 1;
	for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
	    if ((c == *listPtr[0])
		    && (strncmp(option, *listPtr, length) == 0)) {
		expandedOption = *listPtr;
		if (bit != 0) {
		    goto unknownOrAmbiguousOption;

		}
		bit = currentBit;
	    }
	    currentBit <<= 1;
	}

	/*
	 * If this option is not recognized and allowed, put an error message
	 * in the interpreter and return.
	 */

	if (!(allowedOptions & bit)) {
	    if (optPtr->name != NULL) {
		goto unknownOrAmbiguousOption;
	    }
	    optPtr->name = objv[index];
	    continue;


















	}

	/*
	 * 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) {
	    /*
	     * The -background option takes a single XColor value.
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->background = Tk_GetColor(interp, Tk_MainWindow(interp),
		    Tk_GetUid(Tcl_GetString(objv[index])));
	    if (!optPtr->background) {





		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.
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->format = objv[index];





	} else if (bit == OPT_COMPOSITE) {
	    /*
	     * The -compositingrule option takes a single value from a
	     * well-known set.
	     */

	    if (index + 1 >= objc) {




		goto oneValueRequired;



	    }
	    index++;
	    if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules,
		    "compositing rule", 0, &optPtr->compositingRule)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	    *optIndexPtr = index;
	} else if (bit == OPT_TO || bit == OPT_FROM
		|| bit == OPT_SUBSAMPLE || bit == OPT_ZOOM) {

	    const char *val;




	    maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2;
	    argIndex = index + 1;
	    for (numValues = 0; numValues < maxValues; ++numValues) {
		if (argIndex >= objc) {
		    break;
		}
		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])
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		} else {
		    break;
		}
		argIndex++;
	    }

	    if (numValues == 0) {


		goto manyValuesRequired;

	    }
	    *optIndexPtr = (index += numValues);

	    /*
	     * Y values default to the corresponding X value if not specified.
	     */








|
|
<
<



|












|


<
|
<
<













|

|


















|
|
|
|
|

|

|
|
|


|




|
|
|




|







|









<
|
<
|
<

|
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<



<
<
<
>
>
|
<
<
<
<
>
>
>
>
>
>
>
|
>
>




|

<

<
<
<
<
|
|



|
<
<
|
<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





>
>
>
>
>
>
>
|
|
<
|
>
|
>
>
>
>
>
>
>

>
>
>
|
>
|
>

<






|
|
|






|


<

<






|
|
<

















|


|
|
|
|
<
|
|




|
<
<



|
|
<
<
<
<
<
<
<








<


|
|
|






<




|
|
|







<
<
<
<
<
<
<
<
<
<
<
<

|
<
|
|

|
>
|

|
>
|
<

<
<







|




|


















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
<
<
<





|
<
<


















<
<
<
<
<
<
|

|

<







|

















|
<

|
>











|
|
<
<
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|
<
<
|
|
|
|
>
>
>
>
>








|
<
<
|
|
>
>
>
>
>






|
>
>
>
>
|
>
>
>
|
|
|
|
|
|
|
|
|
<
>
|
>
|
>
>
|















|



>
>
|
>







1271
1272
1273
1274
1275
1276
1277
1278
1279


1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298

1299


1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376

1377

1378

1379
1380
1381
1382
1383
1384
1385
1386
1387




















1388
1389
1390
1391



1392
1393
1394



1395
1396
1397




1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413

1414




1415
1416
1417
1418
1419
1420


1421



1422
1423
1424













1425
1426
1427
1428



1429
1430

































1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463

1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481

1482

1483
1484
1485
1486
1487
1488
1489
1490

1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521


1522
1523
1524
1525
1526







1527
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559












1560
1561

1562
1563
1564
1565
1566
1567
1568
1569
1570
1571

1572


1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603






























1604
1605
1606
1607
1608



1609
1610
1611
1612
1613
1614


1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632






1633
1634
1635
1636

1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678


1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711


1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729


1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760

1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
	/*
	 * Check the values given for the -from option.
	 */

	if ((options.fromX > imageWidth) || (options.fromY > imageHeight)
		|| (options.fromX2 > imageWidth)
		|| (options.fromY2 > imageHeight)) {
	    Tcl_AppendResult(interp, "coordinates for -from option extend ",
		    "outside source image", NULL);


	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}
	if (((options.options & OPT_FROM) == 0) || (options.fromX2 < 0)) {
	    width = imageWidth - options.fromX;
	    height = imageHeight - options.fromY;
	} else {
	    width = options.fromX2 - options.fromX;
	    height = options.fromY2 - options.fromY;
	}

	/*
	 * If the -shrink option was specified, set the size of the image.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(masterPtr, options.toX + width,
		    options.toY + height) != TCL_OK) {
		Tcl_ResetResult(interp);

		Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);


		return TCL_ERROR;
	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
	 * image.
	 */

	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(format);
	}
	result = (*imageFormat->fileReadProc)(interp, chan,
		Tcl_GetString(options.name),
		format, (Tk_PhotoHandle) masterPtr, options.toX,
		options.toY, width, height, options.fromX, options.fromY);
	if (chan != NULL) {
	    Tcl_Close(NULL, chan);
	}
	return result;
    }

    case PHOTO_REDITHER:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

	/*
	 * Call Dither if any part of the image is not correctly dithered at
	 * present.
	 */

	x = masterPtr->ditherX;
	y = masterPtr->ditherY;
	if (masterPtr->ditherX != 0) {
	    Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y,
		    masterPtr->width - x, 1);
	}
	if (masterPtr->ditherY < masterPtr->height) {
	    x = 0;
	    Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, 0,
		    masterPtr->ditherY, masterPtr->width,
		    masterPtr->height - masterPtr->ditherY);
	}

	if (y < masterPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(masterPtr->tkMaster, x, y,
		    (masterPtr->width - x), (masterPtr->height - y),
		    masterPtr->width, masterPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *photoTransOptions[] = {
	    "get", "set", NULL
	};
	enum transOptions {
	    PHOTO_TRANS_GET, PHOTO_TRANS_SET
	};

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[2], photoTransOptions, "option",
		0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch ((enum transOptions) index) {
	case PHOTO_TRANS_GET: {

	    XRectangle testBox;

	    TkRegion testRegion;


	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }




















	    if ((x < 0) || (x >= masterPtr->width)
		|| (y < 0) || (y >= masterPtr->height)) {
		Tcl_AppendResult(interp, Tcl_GetString(objv[0]),
			" transparency get: coordinates out of range", NULL);



		return TCL_ERROR;
	    }




	    testBox.x = x;
	    testBox.y = y;
	    testBox.width = 1;




	    testBox.height = 1;
	    /* What a way to do a test! */
	    testRegion = TkCreateRegion();
	    TkUnionRectWithRegion(&testBox, testRegion, testRegion);
	    TkIntersectRegion(testRegion, masterPtr->validRegion, testRegion);
	    TkClipBox(testRegion, &testBox);
	    TkDestroyRegion(testRegion);

	    Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
		    (testBox.width==0 && testBox.height==0));
	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
	    int transFlag;
	    XRectangle setBox;






	    if (objc != 6) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y boolean");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)


		    || (Tcl_GetBooleanFromObj(interp, objv[5],



		    &transFlag) != TCL_OK)) {
		return TCL_ERROR;
	    }













	    if ((x < 0) || (x >= masterPtr->width)
		|| (y < 0) || (y >= masterPtr->height)) {
		Tcl_AppendResult(interp, Tcl_GetString(objv[0]),
			" transparency set: coordinates out of range", NULL);



		return TCL_ERROR;
	    }


































	    setBox.x = x;
	    setBox.y = y;
	    setBox.width = 1;
	    setBox.height = 1;
	    pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;

	    if (transFlag) {
		/*
		 * 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;
	    }


	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(masterPtr->tkMaster, x, y, 1, 1,
		    masterPtr->width, masterPtr->height);
	    masterPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");
    }
    /* FALLTHRU */
    case PHOTO_WRITE: {
	char *data;

	Tcl_Obj *format;


	/*
	 * 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;
	}

	/*
	 * photo write command - first parse and check any options given.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?options?");
	    return TCL_ERROR;
	}
	if ((options.fromX > masterPtr->width)
		|| (options.fromY > masterPtr->height)
		|| (options.fromX2 > masterPtr->width)
		|| (options.fromY2 > masterPtr->height)) {

	    Tcl_AppendResult(interp, "coordinates for -from option extend ",
		    "outside image", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.


	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = masterPtr->width;
	    options.fromY2 = masterPtr->height;







	}

	/*
	 * Search for an appropriate image file format handler, and give an
	 * error if none is found.
	 */

	matched = 0;

	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
	    if ((options.format == NULL)
		    || (strncasecmp(Tcl_GetString(options.format),
		    imageFormat->name, strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->fileWriteProc != NULL) {
		    break;
		}
	    }
	}

	if (imageFormat == NULL) {
	    oldformat = 1;
	    for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
		    imageFormat = imageFormat->nextPtr) {
		if ((options.format == NULL)
			|| (strncasecmp(Tcl_GetString(options.format),
			imageFormat->name, strlen(imageFormat->name)) == 0)) {
		    matched = 1;
		    if (imageFormat->fileWriteProc != NULL) {
			break;
		    }
		}
	    }
	}












	if (imageFormat == NULL) {
	    if (options.format == NULL) {

		Tcl_AppendResult(interp, "no available image file format ",
			"has file writing capability", NULL);
	    } else if (!matched) {
		Tcl_AppendResult(interp, "image file format \"",
			Tcl_GetString(options.format),
			"\" is unknown", NULL);
	    } else {
		Tcl_AppendResult(interp, "image file format \"",
			Tcl_GetString(options.format),
			"\" has no file writing capability", NULL);

	    }


	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

	data = ImgGetPhoto(masterPtr, &block, &options);
	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(options.format);
	}
	result = (*imageFormat->fileWriteProc)(interp,
		Tcl_GetString(options.name), format, &block);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	return result;
    }

    }
    Tcl_Panic("unexpected fallthrough");
    return TCL_ERROR; /* NOT REACHED */
}

/*
 *----------------------------------------------------------------------
 *






























 * ParseSubcommandOptions --
 *
 *	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.
 *
 * Side effects:
 *	Fields in *optPtr get filled in.


 *
 *----------------------------------------------------------------------
 */

static int
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, 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.
	 */

	option = Tcl_GetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}

	/*
	 * Work out which option this is.
	 */

	c = option[0];
	bit = 0;
	currentBit = 1;
	for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
	    if ((c == *listPtr[0])
		    && (strncmp(option, *listPtr, (size_t) length) == 0)) {

		if (bit != 0) {
		    bit = 0;	/* An ambiguous option. */
		    break;
		}
		bit = currentBit;
	    }
	    currentBit <<= 1;
	}

	/*
	 * If this option is not recognized and allowed, put an error message
	 * in the interpreter and return.
	 */

	if ((allowedOptions & bit) == 0) {
	    if (optPtr->name == NULL) {


		optPtr->name = objv[index];
		continue;
	    }
	    Tcl_AppendResult(interp, "unrecognized option \"",
	    	    Tcl_GetString(objv[index]),
		    "\": must be ", NULL);
	    bit = 1;
	    for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
		if ((allowedOptions & bit) != 0) {
		    if ((allowedOptions & (bit - 1)) != 0) {
			Tcl_AppendResult(interp, ", ", NULL);
			if ((allowedOptions & ~((bit << 1) - 1)) == 0) {
			    Tcl_AppendResult(interp, "or ", NULL);
			}
		    }
		    Tcl_AppendResult(interp, *listPtr, NULL);
		}
		bit <<= 1;
	    }
	    return TCL_ERROR;
	}

	/*
	 * 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) {
	    /*
	     * The -background option takes a single XColor value.
	     */

	    if (index + 1 < objc) {


		*optIndexPtr = ++index;
		optPtr->background = Tk_GetColor(interp, Tk_MainWindow(interp),
			Tk_GetUid(Tcl_GetString(objv[index])));
		if (!optPtr->background) {
		    return TCL_ERROR;
		}
	    } else {
		Tcl_AppendResult(interp, "the \"-background\" option ",
			"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.
	     */

	    if (index + 1 < objc) {


		*optIndexPtr = ++index;
		optPtr->format = objv[index];
	    } else {
		Tcl_AppendResult(interp, "the \"-format\" option ",
			"requires a value", NULL);
		return TCL_ERROR;
	    }
	} else if (bit == OPT_COMPOSITE) {
	    /*
	     * The -compositingrule option takes a single value from a
	     * well-known set.
	     */

	    if (index + 1 < objc) {
		/*
		 * Note that these must match the TK_PHOTO_COMPOSITE_*
		 * constants.
		 */

		static const char *compositingRules[] = {
		    "overlay", "set", NULL
		};

		index++;
		if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules,
			"compositing rule", 0, &optPtr->compositingRule)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		*optIndexPtr = index;
	    } else {

		Tcl_AppendResult(interp, "the \"-compositingrule\" option ",
			"requires a value", NULL);
		return TCL_ERROR;
	    }
	} else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) {
	    char *val;
	    maxValues = ((bit == OPT_FROM) || (bit == OPT_TO))? 4: 2;
	    argIndex = index + 1;
	    for (numValues = 0; numValues < maxValues; ++numValues) {
		if (argIndex >= objc) {
		    break;
		}
		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])
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		} else {
		    break;
		}
		++argIndex;
	    }

	    if (numValues == 0) {
		Tcl_AppendResult(interp, "the \"", option, "\" option ",
			 "requires one ", maxValues == 2? "or two": "to four",
			 " integer values", NULL);
		return TCL_ERROR;
	    }
	    *optIndexPtr = (index += numValues);

	    /*
	     * Y values default to the corresponding X value if not specified.
	     */

1634
1635
1636
1637
1638
1639
1640

1641
1642

1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662

1663
1664

1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679

1680
1681

1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913

1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056







































































































































































































































































































































2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102

























































































































































































































































































































































2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
	     * the SubcommandOptions structure.
	     */

	    switch (bit) {
	    case OPT_FROM:
		if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2)
			&& ((values[2] < 0) || (values[3] < 0)))) {

		    needed = "non-negative";
		    goto numberOutOfRange;

		}
		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)))) {

		    needed = "non-negative";
		    goto numberOutOfRange;

		}
		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)) {

		    needed = "positive";
		    goto numberOutOfRange;

		}
		optPtr->zoomX = values[0];
		optPtr->zoomY = values[1];
		break;
	    }
	}

	/*
	 * Remember that we saw this option.
	 */

	optPtr->options |= bit;
    }
    return TCL_OK;

    /*
     * Exception generation.
     */

  oneValueRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires a value", expandedOption));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL);
    return TCL_ERROR;

  manyValuesRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires one %s integer values",
	    expandedOption, (maxValues == 2) ? "or two": "to four"));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL);
    return TCL_ERROR;

  numberOutOfRange:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "value(s) for the %s option must be %s", expandedOption, needed));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_VALUE", NULL);
    return TCL_ERROR;

  unknownOrAmbiguousOption:
    msgObj = Tcl_ObjPrintf("unrecognized option \"%s\": must be ", option);
    bit = 1;
    for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
	if (allowedOptions & bit) {
	    if (allowedOptions & (bit - 1)) {
		if (allowedOptions & ~((bit << 1) - 1)) {
		    Tcl_AppendToObj(msgObj, ", ", -1);
		} else {
		    Tcl_AppendToObj(msgObj, ", or ", -1);
		}
	    }
	    Tcl_AppendToObj(msgObj, *listPtr, -1);
	}
	bit <<= 1;
    }
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureModel --
 *
 *	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 modelPtr->interp's result.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoConfigureModel(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PhotoModel *modelPtr,	/* 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. */
{
    PhotoInstance *instancePtr;
    const char *oldFileString, *oldPaletteString;
    Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;
    Tcl_Obj *tempdata, *tempformat;
    TkSizeT length;
    int i, j, result, imageWidth, imageHeight, oldformat;
    double oldGamma;
    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;
    const char **args;

    args = (const char **)ckalloc((objc + 1) * sizeof(char *));
    for (i = 0, j = 0; i < objc; i++,j++) {
	args[j] = TkGetStringFromObj(objv[i], &length);
	if ((length > 1) && (args[j][0] == '-')) {
	    if ((args[j][1] == 'd') &&
		    !strncmp(args[j], "-data", length)) {
		if (++i < objc) {
		    data = objv[i];
		    j--;
		} else {
		    ckfree(args);
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-data\" missing", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", NULL);
		    return TCL_ERROR;
		}
	    } else if ((args[j][1] == 'f') &&
		    !strncmp(args[j], "-format", length)) {
		if (++i < objc) {
		    format = objv[i];
		    j--;
		} else {
		    ckfree(args);
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-format\" missing", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", NULL);
		    return TCL_ERROR;
		}
	    }
	}
    }

    /*
     * 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 = modelPtr->fileString;
    if (oldFileString == NULL) {
	oldData = modelPtr->dataString;
	if (oldData != NULL) {
	    Tcl_IncrRefCount(oldData);
	}
    } else {
	oldData = NULL;
    }
    oldFormat = modelPtr->format;
    if (oldFormat != NULL) {
	Tcl_IncrRefCount(oldFormat);
    }
    oldPaletteString = modelPtr->palette;
    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    j, args, (char *) modelPtr, flags) != TCL_OK) {
	ckfree(args);
	goto errorExit;
    }
    ckfree(args);

    /*
     * Regard the empty string for -file, -data or -format as the null value.
     */

    if ((modelPtr->fileString != NULL) && (modelPtr->fileString[0] == 0)) {
	ckfree(modelPtr->fileString);
	modelPtr->fileString = NULL;
    }
    if (data) {
	/*
	 * Force into ByteArray format, which most (all) image handlers will
	 * use anyway. Empty length means ignore the -data option.
	 */
	TkSizeT bytesize;

	(void) TkGetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);
	}
	modelPtr->dataString = data;
    }
    if (format) {
	/*
	 * Stringify to ignore -format "". It may come in as a list or other
	 * object.
	 */

	(void) Tcl_GetString(format);
	if (format->length) {
	    Tcl_IncrRefCount(format);
	} else {
	    format = NULL;
	}
	if (modelPtr->format) {
	    Tcl_DecrRefCount(modelPtr->format);
	}
	modelPtr->format = format;
    }
    /*
     * Set the image to the user-requested size, if any, and make sure storage
     * is correctly allocated for this image.
     */

    if (ImgPhotoSetSize(modelPtr, modelPtr->width,
	    modelPtr->height) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	goto errorExit;
    }

    /*
     * Read in the image from the file or string if the user has specified the
     * -file or -data option.
     */

    if ((modelPtr->fileString != NULL)
	    && ((modelPtr->fileString != oldFileString)
	    || (modelPtr->format != oldFormat))) {

	/*
	 * Prevent file system access in a safe interpreter.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    goto errorExit;
	}

	chan = Tcl_OpenFileChannel(interp, modelPtr->fileString, "r", 0);
	if (chan == NULL) {
	    goto errorExit;
	}

	/*
	 * -translation binary also sets -encoding binary
	 */

	if ((Tcl_SetChannelOption(interp, chan,
		"-translation", "binary") != TCL_OK) ||
		(MatchFileFormat(interp, chan, modelPtr->fileString,
			modelPtr->format, &imageFormat, &imageWidth,
			&imageHeight, &oldformat) != TCL_OK)) {
	    Tcl_Close(NULL, chan);
	    goto errorExit;
	}
	result = ImgPhotoSetSize(modelPtr, imageWidth, imageHeight);
	if (result != TCL_OK) {
	    Tcl_Close(NULL, chan);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	result = imageFormat->fileReadProc(interp, chan,
		modelPtr->fileString, tempformat, (Tk_PhotoHandle) modelPtr,
		0, 0, imageWidth, imageHeight, 0, 0);
	Tcl_Close(NULL, chan);
	if (result != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	modelPtr->flags |= IMAGE_CHANGED;
    }

    if ((modelPtr->fileString == NULL) && (modelPtr->dataString != NULL)
	    && ((modelPtr->dataString != oldData)
		    || (modelPtr->format != oldFormat))) {

	if (MatchStringFormat(interp, modelPtr->dataString,
		modelPtr->format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(modelPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	    }
	    tempdata = (Tcl_Obj *) Tcl_GetString(tempdata);
	}
	if (imageFormat->stringReadProc(interp, tempdata, tempformat,
		(Tk_PhotoHandle) modelPtr, 0, 0, imageWidth, imageHeight,
		0, 0) != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	modelPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * Enforce a reasonable value for gamma.
     */

    if (modelPtr->gamma <= 0) {
	modelPtr->gamma = 1.0;
    }

    if ((modelPtr->gamma != oldGamma)
	    || (modelPtr->palette != oldPaletteString)) {
	modelPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * 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 = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }

    ToggleComplexAlphaIfNeeded(modelPtr);

    return TCL_OK;

  errorExit:
    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







































































































































































































































































































































 * ToggleComplexAlphaIfNeeded --
 *
 *	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.
 *
 * Side effects:
 *	(Re)sets COMPLEX_ALPHA flag of model.
 *
 *----------------------------------------------------------------------
 */

static int
ToggleComplexAlphaIfNeeded(
    PhotoModel *mPtr)
{
    size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
	    (size_t)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;
    if (c == NULL) {
	return 0;
    }
    c += 3;			/* Start at first alpha byte. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }
    return (mPtr->flags & COMPLEX_ALPHA);
}

/*
 *----------------------------------------------------------------------
 *

























































































































































































































































































































































 * ImgPhotoDelete --
 *
 *	This function is called by the image code to delete the model
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    ClientData modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = modelPtr->instancePtr) != NULL) {
	if (instancePtr->refCount > 0) {
	    Tcl_Panic("tried to delete photo image when instances still exist");
	}
	Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr);
	TkImgDisposeInstance(instancePtr);
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->pix32 != NULL) {
	ckfree(modelPtr->pix32);
    }
    if (modelPtr->validRegion != NULL) {
	TkDestroyRegion(modelPtr->validRegion);
    }
    if (modelPtr->dataString != NULL) {
	Tcl_DecrRefCount(modelPtr->dataString);
    }
    if (modelPtr->format != NULL) {
	Tcl_DecrRefCount(modelPtr->format);
    }
    Tk_FreeOptions(configSpecs, (char *) modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmdDeletedProc --
 *







>
|
<
>




















>
|
<
>















>
|
<
>













<

<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|







|









|

|










<
|





|

|


|




<
|
|
<
<



|




<
|
|
<
<













|

|






|



|
|






|
|


|





|
|
|






<

|
|




|
|

|







|
|




|
|

|






|
|
|
|
<








|
|
|
>






|
|
<
<



|










|
|




|


|
|
<


|



|
|







|


|
|
|

|
|



|
|
|
<


|
|






|
|
|




|






|
|


|
|
|








|

|






|
|
|








|
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|






|

|
|









<
<
<













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|













|


|


|



|
|

|
|
|

|
|

|
|

|
|

|
|

|
|







1807
1808
1809
1810
1811
1812
1813
1814
1815

1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838

1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870

1871








1872
1873






1874



























1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924

1925
1926


1927
1928
1929
1930
1931
1932
1933
1934

1935
1936


1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989

1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027

2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047


2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072

2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102

2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535



2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
	     * 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", 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;
	    }
	}

	/*
	 * Remember that we saw this option.
	 */

	optPtr->options |= bit;
    }










    return TCL_OK;
}


































/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureMaster --
 *
 *	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.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    PhotoInstance *instancePtr;
    const char *oldFileString, *oldPaletteString;
    Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;
    Tcl_Obj *tempdata, *tempformat;

    int length, i, j, result, imageWidth, imageHeight, oldformat;
    double oldGamma;
    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;
    const char **args;

    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] == '-')) {
	    if ((args[j][1] == 'd') &&
		    !strncmp(args[j], "-data", (size_t) length)) {
		if (++i < objc) {
		    data = objv[i];
		    j--;
		} else {

		    Tcl_AppendResult(interp,
			    "value for \"-data\" missing", NULL);


		    return TCL_ERROR;
		}
	    } else if ((args[j][1] == 'f') &&
		    !strncmp(args[j], "-format", (size_t) length)) {
		if (++i < objc) {
		    format = objv[i];
		    j--;
		} else {

		    Tcl_AppendResult(interp,
			    "value for \"-format\" missing", NULL);


		    return TCL_ERROR;
		}
	    }
	}
    }

    /*
     * 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;
    if (oldFileString == NULL) {
	oldData = masterPtr->dataString;
	if (oldData != NULL) {
	    Tcl_IncrRefCount(oldData);
	}
    } else {
	oldData = NULL;
    }
    oldFormat = masterPtr->format;
    if (oldFormat != NULL) {
	Tcl_IncrRefCount(oldFormat);
    }
    oldPaletteString = masterPtr->palette;
    oldGamma = masterPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    j, args, (char *) masterPtr, flags) != TCL_OK) {
	ckfree((char *) args);
	goto errorExit;
    }
    ckfree((char *) args);

    /*
     * Regard the empty string for -file, -data or -format as the null value.
     */

    if ((masterPtr->fileString != NULL) && (masterPtr->fileString[0] == 0)) {
	ckfree(masterPtr->fileString);
	masterPtr->fileString = NULL;
    }
    if (data) {
	/*
	 * 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);
	} else {
	    data = NULL;
	}
	if (masterPtr->dataString) {
	    Tcl_DecrRefCount(masterPtr->dataString);
	}
	masterPtr->dataString = data;
    }
    if (format) {
	/*
	 * Stringify to ignore -format "". It may come in as a list or other
	 * object.
	 */

	(void) Tcl_GetStringFromObj(format, &length);
	if (length) {
	    Tcl_IncrRefCount(format);
	} else {
	    format = NULL;
	}
	if (masterPtr->format) {
	    Tcl_DecrRefCount(masterPtr->format);
	}
	masterPtr->format = format;
    }
    /*
     * 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_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.
     */

    if ((masterPtr->fileString != NULL)
	    && ((masterPtr->fileString != oldFileString)
	    || (masterPtr->format != oldFormat))) {

	/*
	 * Prevent file system access in a safe interpreter.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_ResetResult(interp);
	    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,
		"-translation", "binary") != TCL_OK) ||
		(MatchFileFormat(interp, chan, masterPtr->fileString,
			masterPtr->format, &imageFormat, &imageWidth,
			&imageHeight, &oldformat) != TCL_OK)) {
	    Tcl_Close(NULL, chan);
	    goto errorExit;
	}
	result = ImgPhotoSetSize(masterPtr, imageWidth, imageHeight);
	if (result != TCL_OK) {
	    Tcl_Close(NULL, chan);
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);

	    goto errorExit;
	}
	tempformat = masterPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	result = (*imageFormat->fileReadProc)(interp, chan,
		masterPtr->fileString, tempformat, (Tk_PhotoHandle) masterPtr,
		0, 0, imageWidth, imageHeight, 0, 0);
	Tcl_Close(NULL, chan);
	if (result != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	masterPtr->flags |= IMAGE_CHANGED;
    }

    if ((masterPtr->fileString == NULL) && (masterPtr->dataString != NULL)
	    && ((masterPtr->dataString != oldData)
		    || (masterPtr->format != oldFormat))) {

	if (MatchStringFormat(interp, masterPtr->dataString,
		masterPtr->format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(masterPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);

	    goto errorExit;
	}
	tempformat = masterPtr->format;
	tempdata = masterPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	    }
	    tempdata = (Tcl_Obj *) Tcl_GetString(tempdata);
	}
	if ((*imageFormat->stringReadProc)(interp, tempdata,
		tempformat, (Tk_PhotoHandle) masterPtr,
		0, 0, imageWidth, imageHeight, 0, 0) != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	masterPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * Enforce a reasonable value for gamma.
     */

    if (masterPtr->gamma <= 0) {
	masterPtr->gamma = 1.0;
    }

    if ((masterPtr->gamma != oldGamma)
	    || (masterPtr->palette != oldPaletteString)) {
	masterPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * 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;
	    instancePtr = instancePtr->nextPtr) {
	ImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
    masterPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }

    ToggleComplexAlphaIfNeeded(masterPtr);

    return TCL_OK;

  errorExit:
    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureInstance --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoMaster *masterPtr = instancePtr->masterPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    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 ((masterPtr->palette && masterPtr->palette[0])
	    && IsValidPalette(instancePtr, masterPtr->palette)) {
	instancePtr->palette = masterPtr->palette;
    } else {
	instancePtr->palette = instancePtr->defaultPalette;
    }
    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.
     */

    colorTablePtr = instancePtr->colorTablePtr;
    if ((colorTablePtr == NULL)
	    || (instancePtr->colormap != colorTablePtr->id.colormap)
	    || (instancePtr->palette != colorTablePtr->id.palette)
	    || (instancePtr->gamma != colorTablePtr->id.gamma)) {
	/*
	 * Free up our old color table, and get a new one.
	 */

	if (colorTablePtr != NULL) {
	    colorTablePtr->liveRefCount -= 1;
	    FreeColorTable(colorTablePtr, 0);
	}
	GetColorTable(instancePtr);

	/*
	 * Create a new XImage structure for sending data to the X server, if
	 * necessary.
	 */

	if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) {
	    bitsPerPixel = 1;
	} else {
	    bitsPerPixel = instancePtr->visualInfo.depth;
	}

	if ((instancePtr->imagePtr == NULL)
		|| (instancePtr->imagePtr->bits_per_pixel != bitsPerPixel)) {
	    if (instancePtr->imagePtr != NULL) {
		XDestroyImage(instancePtr->imagePtr);
	    }
	    imagePtr = XCreateImage(instancePtr->display,
		    instancePtr->visualInfo.visual, (unsigned) bitsPerPixel,
		    (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL,
		    1, 1, 32, 0);
	    instancePtr->imagePtr = imagePtr;

	    /*
	     * We create images using the local host's endianness, rather than
	     * the endianness of the server; otherwise we would have to
	     * byte-swap any 16 or 32 bit values that we store in the image
	     * if the server's endianness is different from ours.
	     */

	    if (imagePtr != NULL) {
#ifdef WORDS_BIGENDIAN
		imagePtr->byte_order = MSBFirst;
#else
		imagePtr->byte_order = LSBFirst;
#endif
		_XInitImageFuncPtrs(imagePtr);
	    }
	}
    }

    /*
     * 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)
	    || (instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)) {
	ImgPhotoInstanceSetSize(instancePtr);
    }

    /*
     * Redither this instance if necessary.
     */

    if ((masterPtr->flags & IMAGE_CHANGED)
	    || (instancePtr->colorTablePtr != colorTablePtr)) {
	TkClipBox(masterPtr->validRegion, &validBox);
	if ((validBox.width > 0) && (validBox.height > 0)) {
	    DitherInstance(instancePtr, validBox.x, validBox.y,
		    validBox.width, validBox.height);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoGet --
 *
 *	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.
 *
 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

static ClientData
ImgPhotoGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData masterData)	/* Pointer to our master structure for the
				 * image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) masterData;
    PhotoInstance *instancePtr;
    Colormap colormap;
    int mono, nRed, nGreen, nBlue, numVisuals;
    XVisualInfo visualInfo, *visInfoPtr;
    char buf[TCL_INTEGER_SPACE * 3];
    XColor *white, *black;
    XGCValues gcValues;

    /*
     * Table of "best" choices for palette for PseudoColor displays with
     * between 3 and 15 bits/pixel.
     */

    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 */}
    };

    /*
     * See if there is already an instance for windows using the same
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
		&& (Tk_Display(tkwin) == instancePtr->display)) {
	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.
		 */

		Tcl_CancelIdleCall(DisposeInstance, (ClientData) instancePtr);
		if (instancePtr->colorTablePtr != NULL) {
		    FreeColorTable(instancePtr->colorTablePtr, 0);
		}
		GetColorTable(instancePtr);
	    }
	    instancePtr->refCount++;
	    return (ClientData) instancePtr;
	}
    }

    /*
     * 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));
    instancePtr->masterPtr = masterPtr;
    instancePtr->display = Tk_Display(tkwin);
    instancePtr->colormap = Tk_Colormap(tkwin);
    Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
    instancePtr->refCount = 1;
    instancePtr->colorTablePtr = NULL;
    instancePtr->pixels = None;
    instancePtr->error = NULL;
    instancePtr->width = 0;
    instancePtr->height = 0;
    instancePtr->imagePtr = 0;
    instancePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = instancePtr;

    /*
     * 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;
    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);

    if (mono) {
	sprintf(buf, "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(masterPtr->interp, tkwin, "white");
    black = Tk_GetColor(masterPtr->interp, tkwin, "black");
    gcValues.foreground = (white != NULL)? white->pixel:
	    WhitePixelOfScreen(Tk_Screen(tkwin));
    gcValues.background = (black != NULL)? black->pixel:
	    BlackPixelOfScreen(Tk_Screen(tkwin));
    Tk_FreeColor(white);
    Tk_FreeColor(black);
    gcValues.graphics_exposures = False;
    instancePtr->gc = Tk_GetGC(tkwin,
	    GCForeground|GCBackground|GCGraphicsExposures, &gcValues);

    /*
     * Set configuration options and finish the initialization of the
     * instance. This will also dither the image if necessary.
     */

    ImgPhotoConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
		masterPtr->width, masterPtr->height);
    }

    return (ClientData) instancePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ToggleComplexAlphaIfNeeded --
 *
 *	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.
 *
 * Side effects:
 *	(Re)sets COMPLEX_ALPHA flag of master.
 *
 *----------------------------------------------------------------------
 */

static int
ToggleComplexAlphaIfNeeded(
    PhotoMaster *mPtr)
{
    size_t len = MAX(mPtr->userWidth, mPtr->width) *
	    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. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }
    return (mPtr->flags & COMPLEX_ALPHA);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoBlendComplexAlpha --
 *
 *	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.
 *
 * Side effects:
 *	Background image passed in gets drawn over with image data.
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

#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)  ))
#endif /* !__WIN32__ */

static void
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, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;

    /*
     * 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.
     */

#ifndef __WIN32__
    unsigned long red_mask, green_mask, blue_mask;
    unsigned long red_shift, green_shift, blue_shift;
    Visual *visual = iPtr->visualInfo.visual;

    red_mask = visual->red_mask;
    green_mask = visual->green_mask;
    blue_mask = visual->blue_mask;
    red_shift = 0;
    green_shift = 0;
    blue_shift = 0;
    while ((0x0001 & (red_mask >> red_shift)) == 0) {
	red_shift++;
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }
#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.
     */

#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
	    line = (y + yOffset) * iPtr->masterPtr->width;
	    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];
		    if (alpha != 255) {
			/*
			 * 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;	/* Calculate once. */
			r = ALPHA_BLEND(ra, r, alpha, unalpha);
			g = ALPHA_BLEND(ga, g, alpha, unalpha);
			b = ALPHA_BLEND(ba, b, alpha, unalpha);
		    }
		    XPutPixel(bgImg, x, y, RGB15(r, g, b));
		}
	    }
	}
	return;
    }
#endif /* !__WIN32__ && !MAC_OSX_TK */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->masterPtr->width;
	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];
		if (alpha != 255) {
		    /*
		     * 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;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

static void
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 (instancePtr->pixels == None) {
	return;
    }

    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
	 * 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, 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);
	    /* 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);

	/*
	 * 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);
	XDestroyImage(bgImg);
	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.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->masterPtr->validRegion);
	XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
		drawableY - imageY);
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    XFlush(display);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoFree --
 *
 *	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.
 *
 * Side effects:
 *	Internal data structures get cleaned up, later.
 *
 *----------------------------------------------------------------------
 */

static void
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;

    instancePtr->refCount -= 1;
    if (instancePtr->refCount > 0) {
	return;
    }

    /*
     * 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);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoDelete --
 *
 *	This function is called by the image code to delete the master
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
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) {
	    Tcl_Panic("tried to delete photo image when instances still exist");
	}
	Tcl_CancelIdleCall(DisposeInstance, (ClientData) instancePtr);
	DisposeInstance((ClientData) instancePtr);
    }
    masterPtr->tkMaster = NULL;
    if (masterPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(masterPtr->interp, masterPtr->imageCmd);
    }
    if (masterPtr->pix32 != NULL) {
	ckfree((char *) masterPtr->pix32);
    }
    if (masterPtr->validRegion != NULL) {
	TkDestroyRegion(masterPtr->validRegion);
    }
    if (masterPtr->dataString != NULL) {
	Tcl_DecrRefCount(masterPtr->dataString);
    }
    if (masterPtr->format != NULL) {
	Tcl_DecrRefCount(masterPtr->format);
    }
    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree((char *) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmdDeletedProc --
 *
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232



2233

2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370





























































































































































































































































































































































































































































































































































































































































































































































































































































































2371
2372
2373
2374
2375
2376
2377
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --
 *
 *	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.)
 *
 * Side effects:
 *	Storage gets reallocated, for the model and all its instances.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoSetSize(
    PhotoModel *modelPtr,
    int width, int height)
{
    unsigned char *newPix32 = NULL;
    int h, offset, pitch;
    unsigned char *srcPtr, *destPtr;
    XRectangle validBox, clipBox;
    TkRegion clipRegion;
    PhotoInstance *instancePtr;

    if (modelPtr->userWidth > 0) {
	width = modelPtr->userWidth;
    }
    if (modelPtr->userHeight > 0) {
	height = modelPtr->userHeight;
    }

    if (width > INT_MAX / 4) {
	/* Pitch overflows int */
	return TCL_ERROR;
    }
    pitch = width * 4;

    /*
     * Test if we're going to (re)allocate the main buffer now, so that any
     * failures will leave the photo unchanged.
     */

    if ((width != modelPtr->width) || (height != modelPtr->height)
	    || (modelPtr->pix32 == NULL)) {



	unsigned newPixSize;


	if (pitch && height > (int)(UINT_MAX / pitch)) {
	    return TCL_ERROR;
	}
	newPixSize = height * pitch;

	/*
	 * Some mallocs() really hate allocating zero bytes. [Bug 619544]
	 */

	if (newPixSize == 0) {
	    newPix32 = NULL;
	} else {
	    newPix32 = (unsigned char *)attemptckalloc(newPixSize);
	    if (newPix32 == NULL) {
		return TCL_ERROR;
	    }
	}
    }

    /*
     * We have to trim the valid region if it is currently larger than the new
     * image size.
     */

    TkClipBox(modelPtr->validRegion, &validBox);
    if ((validBox.x + validBox.width > width)
	    || (validBox.y + validBox.height > height)) {
	clipBox.x = 0;
	clipBox.y = 0;
	clipBox.width = width;
	clipBox.height = height;
	clipRegion = TkCreateRegion();
	TkUnionRectWithRegion(&clipBox, clipRegion, clipRegion);
	TkIntersectRegion(modelPtr->validRegion, clipRegion,
		modelPtr->validRegion);
	TkDestroyRegion(clipRegion);
	TkClipBox(modelPtr->validRegion, &validBox);
    }

    /*
     * 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.
	 */

	if ((modelPtr->pix32 != NULL)
	    && ((width == modelPtr->width) || (width == validBox.width))) {
	    if (validBox.y > 0) {
		memset(newPix32, 0, ((size_t) validBox.y * pitch));
	    }
	    h = validBox.y + validBox.height;
	    if (h < height) {
		memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch));
	    }
	} else {
	    memset(newPix32, 0, ((size_t)height * pitch));
	}

	if (modelPtr->pix32 != NULL) {
	    /*
	     * Copy the common area over to the new array array and free the
	     * old array.
	     */

	    if (width == modelPtr->width) {

		/*
		 * The region to be copied is contiguous.
		 */

		offset = validBox.y * pitch;
		memcpy(newPix32 + offset, modelPtr->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.
		 */

		destPtr = newPix32 + (validBox.y * width + validBox.x) * 4;
		srcPtr = modelPtr->pix32 + (validBox.y * modelPtr->width
			+ validBox.x) * 4;
		for (h = validBox.height; h > 0; h--) {
		    memcpy(destPtr, srcPtr, ((size_t)validBox.width * 4));
		    destPtr += width * 4;
		    srcPtr += modelPtr->width * 4;
		}
	    }

	    ckfree(modelPtr->pix32);
	}

	modelPtr->pix32 = newPix32;
	modelPtr->width = width;
	modelPtr->height = height;

	/*
	 * Dithering will be correct up to the end of the last pre-existing
	 * complete scanline.
	 */

	if ((validBox.x > 0) || (validBox.y > 0)) {
	    modelPtr->ditherX = 0;
	    modelPtr->ditherY = 0;
	} else if (validBox.width == width) {
	    if ((int) validBox.height < modelPtr->ditherY) {
		modelPtr->ditherX = 0;
		modelPtr->ditherY = validBox.height;
	    }
	} else if ((modelPtr->ditherY > 0)
		|| ((int) validBox.width < modelPtr->ditherX)) {
	    modelPtr->ditherX = validBox.width;
	    modelPtr->ditherY = 0;
	}
    }

    ToggleComplexAlphaIfNeeded(modelPtr);

    /*
     * Now adjust the sizes of the pixmaps for all of the instances.
     */

    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgPhotoInstanceSetSize(instancePtr);
    }

    return TCL_OK;
}






























































































































































































































































































































































































































































































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * MatchFileFormat --
 *
 *	This function is called to find a photo image file format handler







|


|

|
|
|

















|






|









|
|

|
|













|
|
>
>
>
|
>




<








|











|








|
|

|















|
|








|


|





|






|
|







|


|

|



|


|
|
|







|
|

|
|
|

|
|
|
|



|





|

|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032

3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoMaster structure for
				 * image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) clientData;

    masterPtr->imageCmd = NULL;
    if (masterPtr->tkMaster != NULL) {
	Tk_DeleteImage(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --
 *
 *	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.)
 *
 * Side effects:
 *	Storage gets reallocated, for the master and all its instances.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoSetSize(
    PhotoMaster *masterPtr,
    int width, int height)
{
    unsigned char *newPix32 = NULL;
    int h, offset, pitch;
    unsigned char *srcPtr, *destPtr;
    XRectangle validBox, clipBox;
    TkRegion clipRegion;
    PhotoInstance *instancePtr;

    if (masterPtr->userWidth > 0) {
	width = masterPtr->userWidth;
    }
    if (masterPtr->userHeight > 0) {
	height = masterPtr->userHeight;
    }

    if (width > INT_MAX / 4) {
	/* Pitch overflows int */
	return TCL_ERROR;
    }
    pitch = width * 4;

    /*
     * 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);

	if (pitch && height > (int)(UINT_MAX / pitch)) {
	    return TCL_ERROR;
	}


	/*
	 * Some mallocs() really hate allocating zero bytes. [Bug 619544]
	 */

	if (newPixSize == 0) {
	    newPix32 = NULL;
	} else {
	    newPix32 = (unsigned char *) attemptckalloc(newPixSize);
	    if (newPix32 == NULL) {
		return TCL_ERROR;
	    }
	}
    }

    /*
     * We have to trim the valid region if it is currently larger than the new
     * image size.
     */

    TkClipBox(masterPtr->validRegion, &validBox);
    if ((validBox.x + validBox.width > width)
	    || (validBox.y + validBox.height > height)) {
	clipBox.x = 0;
	clipBox.y = 0;
	clipBox.width = width;
	clipBox.height = height;
	clipRegion = TkCreateRegion();
	TkUnionRectWithRegion(&clipBox, clipRegion, clipRegion);
	TkIntersectRegion(masterPtr->validRegion, clipRegion,
		masterPtr->validRegion);
	TkDestroyRegion(clipRegion);
	TkClipBox(masterPtr->validRegion, &validBox);
    }

    /*
     * 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.
	 */

	if ((masterPtr->pix32 != NULL)
	    && ((width == masterPtr->width) || (width == validBox.width))) {
	    if (validBox.y > 0) {
		memset(newPix32, 0, ((size_t) validBox.y * pitch));
	    }
	    h = validBox.y + validBox.height;
	    if (h < height) {
		memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch));
	    }
	} else {
	    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.
	     */

	    if (width == masterPtr->width) {

		/*
		 * The region to be copied is contiguous.
		 */

		offset = validBox.y * pitch;
		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.
		 */

		destPtr = newPix32 + (validBox.y * width + validBox.x) * 4;
		srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width
			+ validBox.x) * 4;
		for (h = validBox.height; h > 0; h--) {
		    memcpy(destPtr, srcPtr, ((size_t) validBox.width * 4));
		    destPtr += width * 4;
		    srcPtr += masterPtr->width * 4;
		}
	    }

	    ckfree((char *) masterPtr->pix32);
	}

	masterPtr->pix32 = newPix32;
	masterPtr->width = width;
	masterPtr->height = height;

	/*
	 * Dithering will be correct up to the end of the last pre-existing
	 * complete scanline.
	 */

	if ((validBox.x > 0) || (validBox.y > 0)) {
	    masterPtr->ditherX = 0;
	    masterPtr->ditherY = 0;
	} else if (validBox.width == width) {
	    if ((int) validBox.height < masterPtr->ditherY) {
		masterPtr->ditherX = 0;
		masterPtr->ditherY = validBox.height;
	    }
	} else if ((masterPtr->ditherY > 0)
		|| ((int) validBox.width < masterPtr->ditherX)) {
	    masterPtr->ditherX = validBox.width;
	    masterPtr->ditherY = 0;
	}
    }

    ToggleComplexAlphaIfNeeded(masterPtr);

    /*
     * Now adjust the sizes of the pixmaps for all of the instances.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	ImgPhotoInstanceSetSize(instancePtr);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoInstanceSetSize --
 *
 *	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.
 *
 * Side effects:
 *	Storage gets reallocated, here and in the X server.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoInstanceSetSize(
    PhotoInstance *instancePtr)	/* Instance whose size is to be changed. */
{
    PhotoMaster *masterPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    masterPtr = instancePtr->masterPtr;
    TkClipBox(masterPtr->validRegion, &validBox);

    if ((instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,
			instancePtr->visualInfo.screen),
		(masterPtr->width > 0) ? masterPtr->width: 1,
		(masterPtr->height > 0) ? masterPtr->height: 1,
		instancePtr->visualInfo.depth);
	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.
	 */

	TkSetPixmapColormap(newPixmap, instancePtr->colormap);

	if (instancePtr->pixels != None) {
	    /*
	     * 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);
	    Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
	}
	instancePtr->pixels = newPixmap;
    }

    if ((instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)
	    || (instancePtr->error == NULL)) {

	if (masterPtr->height > 0 && masterPtr->width > 0) {
	    newError = (schar *) ckalloc((unsigned)
		    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.
	     */

	    if ((instancePtr->error != NULL)
		    && ((instancePtr->width == masterPtr->width)
		    || (validBox.width == masterPtr->width))) {
		if (validBox.y > 0) {
		    memset(newError, 0, (size_t)
			    validBox.y * masterPtr->width * 3 * sizeof(schar));
		}
		h = validBox.y + validBox.height;
		if (h < masterPtr->height) {
		    memset(newError + h*masterPtr->width*3, 0,
			    (size_t) (masterPtr->height - h)
			    * masterPtr->width * 3 * sizeof(schar));
		}
	    } else {
		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.
	     */

	    if (masterPtr->width == instancePtr->width) {
		offset = validBox.y * masterPtr->width * 3;
		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;

		for (h = validBox.height; h > 0; --h) {
		    memcpy(errDestPtr, errSrcPtr,
			    validBox.width * 3 * sizeof(schar));
		    errDestPtr += masterPtr->width * 3;
		    errSrcPtr += instancePtr->width * 3;
		}
	    }
	    ckfree((char *) instancePtr->error);
	}

	instancePtr->error = newError;
    }

    instancePtr->width = masterPtr->width;
    instancePtr->height = masterPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * IsValidPalette --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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.
     */

    nRed = strtol(palette, &endp, 10);
    if ((endp == palette) || ((*endp != 0) && (*endp != '/'))
	    || (nRed < 2) || (nRed > 256)) {
	return 0;
    }

    if (*endp == 0) {
	mono = 1;
	nGreen = nBlue = nRed;
    } else {
	palette = endp + 1;
	nGreen = strtol(palette, &endp, 10);
	if ((endp == palette) || (*endp != '/') || (nGreen < 2)
		|| (nGreen > 256)) {
	    return 0;
	}
	palette = endp + 1;
	nBlue = strtol(palette, &endp, 10);
	if ((endp == palette) || (*endp != 0) || (nBlue < 2)
		|| (nBlue > 256)) {
	    return 0;
	}
	mono = 0;
    }

    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;
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * CountBits --
 *
 *	This function counts how many bits are set to 1 in `mask'.
 *
 * Results:
 *	The integer number of bits.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    pixel mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;
}

/*
 *----------------------------------------------------------------------
 *
 * GetColorTable --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
GetColorTable(
    PhotoInstance *instancePtr)	/* Instance needing a color table. */
{
    ColorTable *colorPtr;
    Tcl_HashEntry *entry;
    ColorTableId id;
    int isNew;

    /*
     * Look for an existing ColorTable in the hash table.
     */

    memset(&id, 0, sizeof(id));
    id.display = instancePtr->display;
    id.colormap = instancePtr->colormap;
    id.palette = instancePtr->palette;
    id.gamma = instancePtr->gamma;
    if (!imgPhotoColorHashInitialized) {
	Tcl_InitHashTable(&imgPhotoColorHash, N_COLOR_HASH);
	imgPhotoColorHashInitialized = 1;
    }
    entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);

    if (!isNew) {
	/*
	 * Re-use the existing entry.
	 */

	colorPtr = (ColorTable *) Tcl_GetHashValue(entry);
    } else {
	/*
	 * No color table currently available; need to make one.
	 */

	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.
	 */

	memset(&colorPtr->id, 0, sizeof(ColorTableId));
	colorPtr->id = id;
	Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap);
	colorPtr->flags = 0;
	colorPtr->refCount = 0;
	colorPtr->liveRefCount = 0;
	colorPtr->numColors = 0;
	colorPtr->visualInfo = instancePtr->visualInfo;
	colorPtr->pixelMap = NULL;
	Tcl_SetHashValue(entry, colorPtr);
    }

    colorPtr->refCount++;
    colorPtr->liveRefCount++;
    instancePtr->colorTablePtr = colorPtr;
    if (colorPtr->flags & DISPOSE_PENDING) {
	Tcl_CancelIdleCall(DisposeColorTable, (ClientData) colorPtr);
	colorPtr->flags &= ~DISPOSE_PENDING;
    }

    /*
     * Allocate colors for this color table if necessary.
     */

    if ((colorPtr->numColors == 0)
	    && ((colorPtr->flags & BLACK_AND_WHITE) == 0)) {
	AllocateColors(colorPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeColorTable --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
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);
	    colorPtr->flags &= ~DISPOSE_PENDING;
	}
	DisposeColorTable((ClientData) colorPtr);
    } else if ((colorPtr->flags & DISPOSE_PENDING) == 0) {
	Tcl_DoWhenIdle(DisposeColorTable, (ClientData) colorPtr);
	colorPtr->flags |= DISPOSE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * AllocateColors --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
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;
    double fr, fg, fb, igam;
    XColor *colors;
    unsigned long *pixels;

    /*
     * 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))))

    /*
     * First parse the palette specification to get the required number of
     * shades of each primary.
     */

    mono = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, &nGreen, &nBlue)
	    <= 1;
    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.
     */

    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 (mono && (nRed <= 2)) {
	    colorPtr->flags |= BLACK_AND_WHITE;
	    return;
	}

	/*
	 * 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)) {

	    /*
	     * Direct/True Color: allocate shades of red, green, blue
	     * independently.
	     */

	    if (mono) {
		numColors = nGreen = nBlue = nRed;
	    } else {
		numColors = MAX(MAX(nRed, nGreen), nBlue);
	    }
	    colors = (XColor *) ckalloc(numColors * sizeof(XColor));

	    for (i = 0; i < numColors; ++i) {
		if (igam == 1.0) {
		    colors[i].red = CFRAC(i, nRed - 1);
		    colors[i].green = CFRAC(i, nGreen - 1);
		    colors[i].blue = CFRAC(i, nBlue - 1);
		} else {
		    colors[i].red = CGFRAC(i, nRed - 1, igam);
		    colors[i].green = CGFRAC(i, nGreen - 1, igam);
		    colors[i].blue = CGFRAC(i, nBlue - 1, igam);
		}
	    }
	} else {
	    /*
	     * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
	     * have to allocate each color in the color cube separately.
	     */

	    numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
	    colors = (XColor *) ckalloc(numColors * sizeof(XColor));

	    if (!mono) {
		/*
		 * Color display using a PseudoColor or StaticColor visual.
		 */

		i = 0;
		for (r = 0; r < nRed; ++r) {
		    for (g = 0; g < nGreen; ++g) {
			for (b = 0; b < nBlue; ++b) {
			    if (igam == 1.0) {
				colors[i].red = CFRAC(r, nRed - 1);
				colors[i].green = CFRAC(g, nGreen - 1);
				colors[i].blue = CFRAC(b, nBlue - 1);
			    } else {
				colors[i].red = CGFRAC(r, nRed - 1, igam);
				colors[i].green = CGFRAC(g, nGreen - 1, igam);
				colors[i].blue = CGFRAC(b, nBlue - 1, igam);
			    }
			    i++;
			}
		    }
		}
	    } else {
		/*
		 * Monochrome display - allocate the shades of grey we want.
		 */

		for (i = 0; i < numColors; ++i) {
		    if (igam == 1.0) {
			r = CFRAC(i, numColors - 1);
		    } else {
			r = CGFRAC(i, numColors - 1, igam);
		    }
		    colors[i].red = colors[i].green = colors[i].blue = r;
		}
	    }
	}

	/*
	 * Now try to allocate the colors we've calculated.
	 */

	pixels = (unsigned long *) ckalloc(numColors * sizeof(unsigned long));
	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.
		 */

		if (!ReclaimColors(&colorPtr->id, numColors - i)
			|| !XAllocColor(colorPtr->id.display,
			colorPtr->id.colormap, &colors[i])) {
		    /*
		     * Still can't allocate the color.
		     */

		    break;
		}
	    }
	    pixels[i] = colors[i].pixel;
	}

	/*
	 * 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) {
	    break;
	}
	XFreeColors(colorPtr->id.display, colorPtr->id.colormap, pixels, i, 0);
	ckfree((char *) colors);
	ckfree((char *) pixels);

	if (!mono) {
	    if ((nRed == 2) && (nGreen == 2) && (nBlue == 2)) {
		/*
		 * Fall back to 1-bit monochrome display.
		 */

		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.
		 */

		nRed = (nRed * 3 + 2) / 4;
		nGreen = (nGreen * 3 + 2) / 4;
		nBlue = (nBlue * 3 + 2) / 4;
	    }
	} else {
	    /*
	     * Reduce the number of shades of gray to about 1/2.
	     */

	    nRed = nRed / 2;
	}
    }

    /*
     * 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.
	 */

#ifndef __WIN32__
	if ((colorPtr->visualInfo.class != DirectColor)
		&& (colorPtr->visualInfo.class != TrueColor)) {
	    colorPtr->flags |= MAP_COLORS;
	}
#endif /* __WIN32__ */
    }

    colorPtr->numColors = numColors;
    colorPtr->pixelMap = pixels;

    /*
     * Set up quantization tables for dithering.
     */

    rMult = nGreen * nBlue;
    for (i = 0; i < 256; ++i) {
	r = (i * (nRed - 1) + 127) / 255;
	if (mono) {
	    fr = (double) colors[r].red / 65535.0;
	    if (colorPtr->id.gamma != 1.0 ) {
		fr = pow(fr, colorPtr->id.gamma);
	    }
	    colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
	    colorPtr->redValues[i] = colors[r].pixel;
	} else {
	    g = (i * (nGreen - 1) + 127) / 255;
	    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;
	    } else {
		r *= rMult;
		g *= nBlue;
		colorPtr->redValues[i] = r;
		colorPtr->greenValues[i] = g;
		colorPtr->blueValues[i] = b;
	    }
	    fr = (double) colors[r].red / 65535.0;
	    fg = (double) colors[g].green / 65535.0;
	    fb = (double) colors[b].blue / 65535.0;
	    if (colorPtr->id.gamma != 1.0) {
		fr = pow(fr, colorPtr->id.gamma);
		fg = pow(fg, colorPtr->id.gamma);
		fb = pow(fb, colorPtr->id.gamma);
	    }
	    colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
	    colorPtr->colorQuant[1][i] = (int)(fg * 255.99);
	    colorPtr->colorQuant[2][i] = (int)(fb * 255.99);
	}
    }

    ckfree((char *) colors);
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *) clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {
	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap);
	}
	ckfree((char *) colorPtr->pixelMap);
    }

    entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id);
    if (entry == NULL) {
	Tcl_Panic("DisposeColorTable couldn't find hash entry");
    }
    Tcl_DeleteHashEntry(entry);

    ckfree((char *) colorPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ReclaimColors --
 *
 *	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.
 *
 * Side effects:
 *	ColorTables which are not currently in use may lose their color
 *	allocations.
 *
 *----------------------------------------------------------------------
 */

static int
ReclaimColors(
    ColorTableId *id,		/* Pointer to information identifying
				 * the color table which needs more colors. */
    int numColors)		/* Number of colors required. */
{
    Tcl_HashSearch srch;
    Tcl_HashEntry *entry;
    ColorTable *colorPtr;
    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.
     */

    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))) {
	    /*
	     * We could take this guy's colors off him.
	     */

	    nAvail += colorPtr->numColors;
	}
	entry = Tcl_NextHashEntry(&srch);
    }

    /*
     * nAvail is an (over)estimate of the number of colors we could free.
     */

    if (nAvail < numColors) {
	return 0;
    }

    /*
     * Scan through a second time freeing colors.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while ((entry != NULL) && (numColors > 0)) {
	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))) {
	    /*
	     * Free the colors that this ColorTable has.
	     */

	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    numColors -= colorPtr->numColors;
	    colorPtr->numColors = 0;
	    ckfree((char *) colorPtr->pixelMap);
	    colorPtr->pixelMap = NULL;
	}

	entry = Tcl_NextHashEntry(&srch);
    }
    return 1;			/* We freed some colors. */
}

/*
 *----------------------------------------------------------------------
 *
 * DisposeInstance --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
DisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *) clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(instancePtr->display, instancePtr->gc);
    }
    if (instancePtr->imagePtr != NULL) {
	XDestroyImage(instancePtr->imagePtr);
    }
    if (instancePtr->error != NULL) {
	ckfree((char *) instancePtr->error);
    }
    if (instancePtr->colorTablePtr != NULL) {
	FreeColorTable(instancePtr->colorTablePtr, 1);
    }

    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->masterPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
    ckfree((char *) instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * MatchFileFormat --
 *
 *	This function is called to find a photo image file format handler
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
 *----------------------------------------------------------------------
 */

static int
MatchFileFormat(
    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 *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 = 0;
    int useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const 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.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {
	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->fileMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-file option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_FILE_FORMAT", 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) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		break;
	    }
	}
    }
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatString != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->fileMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-file option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_FILE_FORMAT", NULL);
		    return TCL_ERROR;
		}
	    }
	    if (formatPtr->fileMatchProc != NULL) {
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		if (formatPtr->fileMatchProc(chan, fileName, (Tcl_Obj *)
			formatString, widthPtr, heightPtr, interp)) {
		    if (*widthPtr < 1) {
			*widthPtr = 1;
		    }
		    if (*heightPtr < 1) {
			*heightPtr = 1;
		    }
		    break;
		}
	    }
	}
    }
#endif

    if (formatPtr == NULL) {
	if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image file format \"%s\" is not supported",
		    formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, NULL);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "couldn't recognize data in image file \"%s\"",
		    fileName));
	    Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE",
		    "UNRECOGNIZED_DATA", NULL);
	}
	return TCL_ERROR;
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;
    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);







|









|
<



|



















<
|
|
<
<






|











<
|










<
|
|
<
<





|












<



|
|
<
<
<

|
|
<
<
|







4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063

4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086

4087
4088


4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106

4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117

4118
4119


4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137

4138
4139
4140
4141
4142



4143
4144
4145


4146
4147
4148
4149
4150
4151
4152
4153
 *----------------------------------------------------------------------
 */

static int
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 = 0, useoldformat = 0;

    Tk_PhotoImageFormat *formatPtr;
    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.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {
	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->fileMatchProc == NULL) {

		Tcl_AppendResult(interp, "-file option isn't supported for ",
			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) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		break;
	    }
	}
    }

    if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatString != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->fileMatchProc == NULL) {

		    Tcl_AppendResult(interp, "-file option isn't supported",
			    " for ", formatString, " images", NULL);


		    return TCL_ERROR;
		}
	    }
	    if (formatPtr->fileMatchProc != NULL) {
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		if ((*formatPtr->fileMatchProc)(chan, fileName, (Tcl_Obj *)
			formatString, widthPtr, heightPtr, interp)) {
		    if (*widthPtr < 1) {
			*widthPtr = 1;
		    }
		    if (*heightPtr < 1) {
			*heightPtr = 1;
		    }
		    break;
		}
	    }
	}
    }


    if (formatPtr == NULL) {
	if ((formatObj != NULL) && !matched) {
	    Tcl_AppendResult(interp, "image file format \"", formatString,
		    "\" is not supported", NULL);



	} else {
	    Tcl_AppendResult(interp,
		    "couldn't recognize data in image file \"", fileName, "\"",


		    NULL);
	}
	return TCL_ERROR;
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;
    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723

2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
				 * 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 = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const 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.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {
	/*
	 * To keep the behaviour of older versions (Tk <= 8.6), the default
	 * list-of-lists string format is checked last. Remember its position.
	 */

	if (strncasecmp("default", formatPtr->name, strlen(formatPtr->name))
		== 0) {
	    defaultFormatPtr = formatPtr;
	}

	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->stringMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-data option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_DATA_FORMAT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * If this is the default format, and it was not passed as -format
	 * option, skip the stringMatchProc test. It'll be done later
	 */

	if (formatObj == NULL && formatPtr == defaultFormatPtr) {
	    continue;
	}

	if ((formatPtr->stringMatchProc != NULL)
		&& (formatPtr->stringReadProc != NULL)
		&& formatPtr->stringMatchProc(data, formatObj,
			widthPtr, heightPtr, interp)) {
	    break;
	}
    }

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->stringMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-data option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_DATA_FORMAT", NULL);
		    return TCL_ERROR;
		}
	    }
	    if ((formatPtr->stringMatchProc != NULL)
		    && (formatPtr->stringReadProc != NULL)
		    && formatPtr->stringMatchProc(
			    (Tcl_Obj *) Tcl_GetString(data),
			    (Tcl_Obj *) formatString,
			    widthPtr, heightPtr, interp)) {
		break;
	    }
	}
    }
#endif

    if (formatPtr == NULL) {
	/*
	 * Try the default format as last resort (only if no -format option
	 * was passed).
	 */

	if ( formatObj == NULL && defaultFormatPtr == NULL) {
	    Tcl_Panic("default image format handler not registered");
	}
	if ( formatObj == NULL
		&& defaultFormatPtr->stringMatchProc != NULL
		&& defaultFormatPtr->stringReadProc != NULL
		&& defaultFormatPtr->stringMatchProc(data, formatObj,
		widthPtr, heightPtr, interp) != 0) {
	    useoldformat = 0;
	    formatPtr = defaultFormatPtr;
	} else if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image format \"%s\" is not supported", formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, NULL);
	    return TCL_ERROR;
	} else {

            /*
             * Some lower level routine (stringMatchProc) may have already set
             * a specific error message, so just return this. Otherwise return
             * a generic image data error.
             */

            if (Tcl_GetString(Tcl_GetObjResult(interp))[0] == '\0') {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(
                        "couldn't recognize image data", -1));
	        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		        "UNRECOGNIZED_DATA", NULL);
            }
	    return TCL_ERROR;
	}
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;

    /*
     * Some stringMatchProc might have left error messages and error codes in
     * interp.	Clear them before return.
     */
    Tcl_ResetResult(interp);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FindPhoto --
 *
 *	This function is called to get an opaque handle (actually a
 *	PhotoModel *) 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_PhotoHandle
Tk_FindPhoto(
    Tcl_Interp *interp,		/* Interpreter (application) in which image
				 * exists. */
    const char *imageName)	/* Name of the desired photo image. */
{
    const Tk_ImageType *typePtr;
    ClientData clientData =
	    Tk_GetImageModelData(interp, imageName, &typePtr);


    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutBlock --
 *







|


|












<
<
<
<
<
<
<
<
<
<







<
|
|
<
<



<
<
<
<
<
<
<
<
<
<


|
|




<











<
|
|
<
<





|







<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
|
|
<




<
<
<
<
<
<









|

















|

<
|
|

>



|







4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208










4209
4210
4211
4212
4213
4214
4215

4216
4217


4218
4219
4220










4221
4222
4223
4224
4225
4226
4227
4228

4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239

4240
4241


4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254


4255















4256
4257
4258



4259









4260


4261
4262

4263
4264
4265
4266






4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295

4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
				 * 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 = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr;
    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.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {










	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->stringMatchProc == NULL) {

		Tcl_AppendResult(interp, "-data option isn't supported for ",
			formatString, " images", NULL);


		return TCL_ERROR;
	    }
	}










	if ((formatPtr->stringMatchProc != NULL)
		&& (formatPtr->stringReadProc != NULL)
		&& (*formatPtr->stringMatchProc)(data, formatObj,
		widthPtr, heightPtr, interp)) {
	    break;
	}
    }


    if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->stringMatchProc == NULL) {

		    Tcl_AppendResult(interp, "-data option isn't supported",
			    " for ", formatString, " images", NULL);


		    return TCL_ERROR;
		}
	    }
	    if ((formatPtr->stringMatchProc != NULL)
		    && (formatPtr->stringReadProc != NULL)
		    && (*formatPtr->stringMatchProc)(
			    (Tcl_Obj *) Tcl_GetString(data),
			    (Tcl_Obj *) formatString,
			    widthPtr, heightPtr, interp)) {
		break;
	    }
	}
    }


    if (formatPtr == NULL) {















	if ((formatObj != NULL) && !matched) {
	    Tcl_AppendResult(interp, "image format \"", formatString,
		    "\" is not supported", NULL);



	} else {









	    Tcl_AppendResult(interp, "couldn't recognize image data", NULL);


	}
	return TCL_ERROR;

    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;






    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FindPhoto --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_PhotoHandle
Tk_FindPhoto(
    Tcl_Interp *interp,		/* Interpreter (application) in which image
				 * exists. */
    CONST char *imageName)	/* Name of the desired photo image. */
{

    ClientData clientData;
    Tk_ImageType *typePtr;

    clientData = Tk_GetImageMasterData(interp, imageName, &typePtr);
    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return (Tk_PhotoHandle) clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutBlock --
 *
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955

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. */
    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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;
    Tk_PhotoImageBlock sourceBlock;
    unsigned char *memToFree;
    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;

    /*
     * Zero-sized blocks never cause any changes. [Bug 3078902]
     */

    if (blockPtr->height == 0 || blockPtr->width == 0) {
	return TCL_OK;
    }

    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if ((modelPtr->userWidth != 0) && ((x + width) > modelPtr->userWidth)) {
	width = modelPtr->userWidth - x;
    }
    if ((modelPtr->userHeight != 0)
	    && ((y + height) > modelPtr->userHeight)) {
	height = modelPtr->userHeight - y;
    }
    if ((width <= 0) || (height <= 0)) {
	return TCL_OK;
    }

    /*
     * Fix for bug e4336bef5d:
     *
     * Make a local copy of *blockPtr, as we might have to change some
     * of its fields and don't want to interfere with the caller's data.
     *
     * If source and destination are the same image, create a copy  of the
     * source data in our local sourceBlock.
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }


    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
	/*
	 * The dithering isn't correct past the start of this block.
	 */

	modelPtr->ditherX = x;
	modelPtr->ditherY = y;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
    blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
    alphaOffset = sourceBlock.offset[3];
    if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= sourceBlock.offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	modelPtr->flags |= COLOR_IMAGE;
    }

    /*
     * Copy the data into our local 32-bit/pixel array. If we can do it with a
     * single memmove, we do.
     */

    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
    pitch = modelPtr->width * 4;

    /*
     * 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 ((sourceBlock.pixelSize == 4)
	    && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3)
	    && (width <= sourceBlock.width) && (height <= sourceBlock.height)
	    && ((height == 1) || ((x == 0) && (width == modelPtr->width)
		&& (sourceBlock.pitch == pitch)))
	    && (compRule == TK_PHOTO_COMPOSITE_SET)) {
	memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0],
		((size_t)height * width * 4));

	/*
	 * 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 = sourceBlock.pixelSize;
	int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET);

	srcLinePtr = sourceBlock.pixelPtr + sourceBlock.offset[0];
	hCopy = MIN(hLeft, sourceBlock.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 <= sourceBlock.width)
		    && compRuleSet) {
		memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4));
		srcLinePtr += sourceBlock.pitch;
		destLinePtr += pitch;
		continue;
	    }

	    /*
	     * Have to copy the slow way.
	     */

	    destPtr = destLinePtr;
	    for (wLeft = width; wLeft > 0;) {
		wCopy = MIN(wLeft, sourceBlock.width);
		wLeft -= wCopy;
		srcPtr = srcLinePtr;

		/*
		 * But we might be lucky and be able to use fairly fast loops.
		 * It's worth checking...
		 */







|









<
|
<






<
<
<
|
<
<
<
<


|
|

|
|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
|
|
<
|
<
<
<
<
|
<
<

|
|
<



<
<
<
|
|
<
<
|
<
<
<
<
<
<
<
<



|
|




|
|







|
|
|
|



|


|







|
|







|

|
|
|

|
|














|


|
|










|

|
|










|







4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340

4341

4342
4343
4344
4345
4346
4347



4348




4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361













4362
4363


4364





4365
4366

4367




4368


4369
4370
4371

4372
4373
4374



4375
4376


4377








4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481

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, 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;




    masterPtr = (PhotoMaster *) handle;




    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) {
	width = masterPtr->userWidth - x;
    }
    if ((masterPtr->userHeight != 0)
	    && ((y + height) > masterPtr->userHeight)) {
	height = masterPtr->userHeight - y;
    }
    if ((width <= 0) || (height <= 0)) {
	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) {


	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);

	    }
	    return TCL_ERROR;
	}



	if (sameSrc) {
	    blockPtr->pixelPtr = masterPtr->pix32;


	    blockPtr->pitch = masterPtr->width * 4;








	}
    }

    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;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
    alphaOffset = blockPtr->offset[3];
    if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= blockPtr->offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	masterPtr->flags |= COLOR_IMAGE;
    }

    /*
     * 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;

    /*
     * 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(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0],
		((size_t) height * width * 4));

	/*
	 * 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)
		    && compRuleSet) {
		memcpy(destLinePtr, srcLinePtr, ((size_t) width * 4));
		srcLinePtr += blockPtr->pitch;
		destLinePtr += pitch;
		continue;
	    }

	    /*
	     * Have to copy the slow way.
	     */

	    destPtr = destLinePtr;
	    for (wLeft = width; wLeft > 0;) {
		wCopy = MIN(wLeft, blockPtr->width);
		wLeft -= wCopy;
		srcPtr = srcLinePtr;

		/*
		 * But we might be lucky and be able to use fairly fast loops.
		 * It's worth checking...
		 */
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
				destPtr[2], Alpha);
			destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha);
		    }

		    destPtr += 4;
		}
	    }
	    srcLinePtr += sourceBlock.pitch;
	    destLinePtr += pitch;
	}
    }

    /*
     * Add this new block to the region which specifies which data is valid.
     */







|







4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
				destPtr[2], Alpha);
			destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha);
		    }

		    destPtr += 4;
		}
	    }
	    srcLinePtr += blockPtr->pitch;
	    destLinePtr += pitch;
	}
    }

    /*
     * Add this new block to the region which specifies which data is valid.
     */
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
	recalculateValidRegion:
	    workRgn = TkCreateRegion();
	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = height;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(modelPtr->validRegion, workRgn,
		    modelPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	/*
	 * Factorize out the main part of the building of the region data to
	 * allow for more efficient per-platform implementations. [Bug 919066]
	 */

	TkpBuildRegionFromAlphaData(modelPtr->validRegion, (unsigned) x,
		(unsigned) y, (unsigned) width, (unsigned) height,
		modelPtr->pix32 + (y * modelPtr->width + x) * 4 + 3,
		4, (unsigned) modelPtr->width * 4);
    } else {
	rect.x = x;
	rect.y = y;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, modelPtr->validRegion,
		modelPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (height == 1)) {
	/*
	 * Optimize the single span case if we can. This speeds up code that
	 * builds up large simple-alpha images by scan-lines or individual
	 * pixels. We don't negate COMPLEX_ALPHA in this case. [Bug 1409140]
	 * [Patch 1539990]
	 */

	if (!(modelPtr->flags & COMPLEX_ALPHA)) {
	    int x1;

	    for (x1=x ; x1<x+width ; x1++) {
		unsigned char newAlpha;

		destLinePtr = modelPtr->pix32 + (y*modelPtr->width + x1)*4;
		newAlpha = destLinePtr[3];

		if (newAlpha && newAlpha != 255) {
		    modelPtr->flags |= COMPLEX_ALPHA;
		    break;
		}
	    }
	}
    } else if ((alphaOffset != 0) || (modelPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed. To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */

	ToggleComplexAlphaIfNeeded(modelPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height,
	    modelPtr->width, modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
    if (memToFree) ckfree(memToFree);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutZoomedBlock --
 *







|
|








|

|
|





|
|






|

|
|
|
<


|
<
<
<
|

|
|
>
|
|
<
|
|
<
|


|




|






|





|
|
<
<
<

<
<
<
<
<







4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639

4640
4641
4642



4643
4644
4645
4646
4647
4648
4649

4650
4651

4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674



4675





4676
4677
4678
4679
4680
4681
4682
	recalculateValidRegion:
	    workRgn = TkCreateRegion();
	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = height;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(masterPtr->validRegion, workRgn,
		    masterPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	/*
	 * 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;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, masterPtr->validRegion,
		masterPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) {
	/*
	 * Optimize the single pixel case if we can. This speeds up code that
	 * 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;

	    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	    newAlpha = destLinePtr[3];

	    if (newAlpha && newAlpha != 255) {
		masterPtr->flags |= COMPLEX_ALPHA;

	    }
	}

    } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed.  To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */

	ToggleComplexAlphaIfNeeded(masterPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height,
	    masterPtr->width, masterPtr->height);



    return TCL_OK;





}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutZoomedBlock --
 *
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370

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. */
    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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;
    Tk_PhotoImageBlock sourceBlock;
    unsigned char *memToFree;
    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;

    /*
     * Zero-sized blocks never cause any changes. [Bug 3078902]
     */

    if (blockPtr->height == 0 || blockPtr->width == 0) {
	return TCL_OK;
    }

    if (zoomX==1 && zoomY==1 && subsampleX==1 && subsampleY==1) {
	return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height,
		compRule);
    }

    sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if (zoomX <= 0 || zoomY <= 0) {
	return TCL_OK;
    }
    if ((modelPtr->userWidth != 0) && ((x + width) > modelPtr->userWidth)) {
	width = modelPtr->userWidth - x;
    }
    if ((modelPtr->userHeight != 0)
	    && ((y + height) > modelPtr->userHeight)) {
	height = modelPtr->userHeight - y;
    }
    if (width <= 0 || height <= 0) {
	return TCL_OK;
    }

    /*
     * Fix for Bug e4336bef5d:
     * Make a local copy of *blockPtr, as we might have to change some
     * of its fields and don't want to interfere with the caller's data.
     *
     * If source and destination are the same image, create a copy  of the
     * source data in our local sourceBlock.
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }

    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
	/*
	 * The dithering isn't correct past the start of this block.
	 */

	modelPtr->ditherX = x;
	modelPtr->ditherY = y;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
    blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
    alphaOffset = sourceBlock.offset[3];
    if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= sourceBlock.offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	modelPtr->flags |= COLOR_IMAGE;
    }

    /*
     * Work out what area the pixel data in the block expands to after
     * subsampling and zooming.
     */

    blockXSkip = subsampleX * sourceBlock.pixelSize;
    blockYSkip = subsampleY * sourceBlock.pitch;
    if (subsampleX > 0) {
	blockWid = ((sourceBlock.width + subsampleX - 1) / subsampleX) * zoomX;
    } else if (subsampleX == 0) {
	blockWid = width;
    } else {
	blockWid = ((sourceBlock.width - subsampleX - 1) / -subsampleX) * zoomX;
    }
    if (subsampleY > 0) {
	blockHt = ((sourceBlock.height + subsampleY - 1) / subsampleY) * zoomY;
    } else if (subsampleY == 0) {
	blockHt = height;
    } else {
	blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY;
    }

    /*
     * Copy the data into our local 32-bit/pixel array.
     */

    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
    srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0];
    if (subsampleX < 0) {
	srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize;
    }
    if (subsampleY < 0) {
	srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch;
    }

    pitch = modelPtr->width * 4;
    for (hLeft = height; hLeft > 0; ) {
	hCopy = MIN(hLeft, blockHt);
	hLeft -= hCopy;
	yRepeat = zoomY;
	srcLinePtr = srcOrigPtr;
	for (; hCopy > 0; --hCopy) {
	    destPtr = destLinePtr;







|













|
<
<






<
<
<
<
<
<
<
<











|
|

|
|
|





<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
|
<
<

|
|
<



|
|
<
|
<
<
<
<
<
<
<
<
<
<
<



|
|




|
|







|
|
|
|



|


|







|
|

|



|


|



|






|
|

|


|


|







4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716


4717
4718
4719
4720
4721
4722








4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744












4745
4746


4747







4748
4749




4750


4751
4752
4753

4754
4755
4756
4757
4758

4759











4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833

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 = (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) {
	return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height,
		compRule);
    }

    sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if (zoomX <= 0 || zoomY <= 0) {
	return TCL_OK;
    }
    if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) {
	width = masterPtr->userWidth - x;
    }
    if ((masterPtr->userHeight != 0)
	    && ((y + height) > masterPtr->userHeight)) {
	height = masterPtr->userHeight - y;
    }
    if (width <= 0 || height <= 0) {
	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) {


	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);

	    }
	    return TCL_ERROR;
	}
	if (sameSrc) {
	    blockPtr->pixelPtr = masterPtr->pix32;

	    blockPtr->pitch = masterPtr->width * 4;











	}
    }

    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;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
    alphaOffset = blockPtr->offset[3];
    if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= blockPtr->offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	masterPtr->flags |= COLOR_IMAGE;
    }

    /*
     * Work out what area the pixel data in the block expands to after
     * subsampling and zooming.
     */

    blockXSkip = subsampleX * blockPtr->pixelSize;
    blockYSkip = subsampleY * blockPtr->pitch;
    if (subsampleX > 0) {
	blockWid = ((blockPtr->width + subsampleX - 1) / subsampleX) * zoomX;
    } else if (subsampleX == 0) {
	blockWid = width;
    } else {
	blockWid = ((blockPtr->width - subsampleX - 1) / -subsampleX) * zoomX;
    }
    if (subsampleY > 0) {
	blockHt = ((blockPtr->height + subsampleY - 1) / subsampleY) * zoomY;
    } else if (subsampleY == 0) {
	blockHt = height;
    } else {
	blockHt = ((blockPtr->height - subsampleY - 1) / -subsampleY) * zoomY;
    }

    /*
     * Copy the data into our local 32-bit/pixel array.
     */

    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
    srcOrigPtr = blockPtr->pixelPtr + blockPtr->offset[0];
    if (subsampleX < 0) {
	srcOrigPtr += (blockPtr->width - 1) * blockPtr->pixelSize;
    }
    if (subsampleY < 0) {
	srcOrigPtr += (blockPtr->height - 1) * blockPtr->pitch;
    }

    pitch = masterPtr->width * 4;
    for (hLeft = height; hLeft > 0; ) {
	hCopy = MIN(hLeft, blockHt);
	hLeft -= hCopy;
	yRepeat = zoomY;
	srcLinePtr = srcOrigPtr;
	for (; hCopy > 0; --hCopy) {
	    destPtr = destLinePtr;
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592











































































































































































3593




3594





3595













3596







3597











































































































































3598
3599
3600
3601
3602
3603
3604
	    TkRegion workRgn = TkCreateRegion();

	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = 1;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(modelPtr->validRegion, workRgn,
		    modelPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	TkpBuildRegionFromAlphaData(modelPtr->validRegion,
		(unsigned)x, (unsigned)y, (unsigned)width, (unsigned)height,
		&modelPtr->pix32[(y * modelPtr->width + x) * 4 + 3], 4,
		(unsigned) modelPtr->width * 4);
    } else {
	rect.x = x;
	rect.y = y;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, modelPtr->validRegion,
		modelPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) {
	/*
	 * Optimize the single pixel case if we can. This speeds up code that
	 * builds up large simple-alpha images by single pixels. We don't
	 * negate COMPLEX_ALPHA in this case. [Bug 1409140]
	 */
	if (!(modelPtr->flags & COMPLEX_ALPHA)) {
	    unsigned char newAlpha;

	    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    newAlpha = destLinePtr[3];

	    if (newAlpha && newAlpha != 255) {
		modelPtr->flags |= COMPLEX_ALPHA;
	    }
	}
    } else if ((alphaOffset != 0) || (modelPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed. To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */
	ToggleComplexAlphaIfNeeded(modelPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height, modelPtr->width,
	    modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
    if (memToFree) ckfree(memToFree);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DitherPhoto --
 *
 *	This function is called to update an area of each instance's pixmap by
 *	dithering the corresponding area of the image model.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The pixmap of each instance of this image gets updated. The fields in
 *	*modelPtr indicating which area of the image is correctly dithered
 *	get updated.
 *
 *----------------------------------------------------------------------
 */

void
Tk_DitherPhoto(
    Tk_PhotoHandle photo,	/* Image model 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. */
{
    PhotoModel *modelPtr = (PhotoModel *) photo;
    PhotoInstance *instancePtr;

    if ((width <= 0) || (height <= 0)) {
	return;
    }

    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgDitherInstance(instancePtr, x, y, width, height);
    }

    /*
     * Work out whether this block will be correctly dithered and whether it
     * will extend the correctly dithered region.
     */

    if (((y < modelPtr->ditherY)
	    || ((y == modelPtr->ditherY) && (x <= modelPtr->ditherX)))
	    && ((y + height) > (modelPtr->ditherY))) {
	/*
	 * This block starts inside (or immediately after) the correctly
	 * dithered region, so the first scan line at least will be right.
	 * Furthermore this block extends into scanline modelPtr->ditherY.
	 */

	if ((x == 0) && (width == modelPtr->width)) {
	    /*
	     * We are doing the full width, therefore the dithering will be
	     * correct to the end.
	     */

	    modelPtr->ditherX = 0;
	    modelPtr->ditherY = y + height;
	} else {
	    /*
	     * We are doing partial scanlines, therefore the
	     * correctly-dithered region will be extended by at most one scan
	     * line.
	     */

	    if (x <= modelPtr->ditherX) {
		modelPtr->ditherX = x + width;
		if (modelPtr->ditherX >= modelPtr->width) {
		    modelPtr->ditherX = 0;











































































































































































		    modelPtr->ditherY++;




		}





	    }













	}







    }











































































































































}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoBlank --
 *







|
|



|

|
|





|
|









|


|


|



|


|


|



|






|





|
|
<
<
<

<
<
<
<
<








|






|







|





|






|

|







|
|
|



|


|





|
|







|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972



4973





4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
	    TkRegion workRgn = TkCreateRegion();

	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = 1;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(masterPtr->validRegion, workRgn,
		    masterPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	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;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, masterPtr->validRegion,
		masterPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) {
	/*
	 * Optimize the single pixel case if we can. This speeds up code that
	 * 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;

	    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	    newAlpha = destLinePtr[3];

	    if (newAlpha && newAlpha != 255) {
		masterPtr->flags |= COMPLEX_ALPHA;
	    }
	}
    } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed.  To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */
	ToggleComplexAlphaIfNeeded(masterPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width,
	    masterPtr->height);



    return TCL_OK;





}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DitherPhoto --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

void
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;

    if ((width <= 0) || (height <= 0)) {
	return;
    }

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	DitherInstance(instancePtr, x, y, width, height);
    }

    /*
     * 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.
	 * Furthermore this block extends into scanline masterPtr->ditherY.
	 */

	if ((x == 0) && (width == masterPtr->width)) {
	    /*
	     * We are doing the full width, therefore the dithering will be
	     * correct to the end.
	     */

	    masterPtr->ditherX = 0;
	    masterPtr->ditherY = y + height;
	} else {
	    /*
	     * We are doing partial scanlines, therefore the
	     * correctly-dithered region will be extended by at most one scan
	     * line.
	     */

	    if (x <= masterPtr->ditherX) {
		masterPtr->ditherX = x + width;
		if (masterPtr->ditherX >= masterPtr->width) {
		    masterPtr->ditherX = 0;
		    masterPtr->ditherY++;
		}
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DitherInstance --
 *
 *	This function is called to update an area of an instance's pixmap by
 *	dithering the corresponding area of the master.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The instance's pixmap gets updated.
 *
 *----------------------------------------------------------------------
 */

static void
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, int height)	/* Dimensions of the block to be dithered. */
{
    PhotoMaster *masterPtr = instancePtr->masterPtr;
    ColorTable *colorPtr = instancePtr->colorTablePtr;
    XImage *imagePtr;
    int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
    int bitsPerPixel, bytesPerLine, lineLength;
    unsigned char *srcLinePtr;
    schar *errLinePtr;
    pixel firstBit, word, mask;

    /*
     * Turn dithering off in certain cases where it is not needed (TrueColor,
     * DirectColor with many colors).
     */

    if ((colorPtr->visualInfo.class == DirectColor)
	    || (colorPtr->visualInfo.class == TrueColor)) {
	int nRed, nGreen, nBlue, result;

	result = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed,
		&nGreen, &nBlue);
	if ((nRed >= 256)
		&& ((result == 1) || ((nGreen >= 256) && (nBlue >= 256)))) {
	    doDithering = 0;
	}
    }

    /*
     * 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;
    if (nLines < 1) {
	nLines = 1;
    }
    if (nLines > height ) {
	nLines = height;
    }

    imagePtr = instancePtr->imagePtr;
    if (imagePtr == NULL) {
	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));
    bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
    firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;

    lineLength = masterPtr->width * 3;
    srcLinePtr = masterPtr->pix32 + (yStart * masterPtr->width + xStart) * 4;
    errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
    xEnd = xStart + width;

    /*
     * 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;
	}
	yEnd = yStart + nLines;
	for (y = yStart; y < yEnd; ++y) {
	    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.
		 */

		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
			     *     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.
			     */

			    c = (x > 0) ? errPtr[-3] * 7: 0;
			    if (y > 0) {
				if (x > 0) {
				    c += errPtr[-lineLength-3];
				}
				c += errPtr[-lineLength] * 5;
				if ((x + 1) < masterPtr->width) {
				    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;
			    } else if (c > 255) {
				c = 255;
			    }
			    col[i] = colorPtr->colorQuant[i][c];
			    *errPtr++ = c - col[i];
			}
		    } else {
			/*
			 * Output is virtually continuous in this case, so
			 * don't bother dithering.
			 */

			col[0] = *srcPtr++;
			col[1] = *srcPtr++;
			col[2] = *srcPtr++;
		    }
		    srcPtr++;

		    /*
		     * Translate the quantized component values into an X
		     * pixel value, and store it in the image.
		     */

		    i = colorPtr->redValues[col[0]]
			    + colorPtr->greenValues[col[1]]
			    + colorPtr->blueValues[col[2]];
		    if (colorPtr->flags & MAP_COLORS) {
			i = colorPtr->pixelMap[i];
		    }
		    switch (bitsPerPixel) {
		    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.
			 */

		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
		}

	    } else if (bitsPerPixel > 1) {
		/*
		 * 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
		 * luminance computed as
		 *	0.344 * red + 0.5 * green + 0.156 * blue.
		 */

		for (x = xStart; x < xEnd; ++x) {
		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0)  {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < masterPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if ((masterPtr->flags & COLOR_IMAGE) == 0) {
			c += srcPtr[0];
		    } else {
			c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    }
		    srcPtr += 4;

		    if (c < 0) {
			c = 0;
		    } else if (c > 255) {
			c = 255;
		    }
		    i = colorPtr->colorQuant[0][c];
		    *errPtr++ = c - i;
		    i = colorPtr->redValues[i];
		    switch (bitsPerPixel) {
		    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.
			 */

		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    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.
		 */

		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 (mask == 0) {
			*destLongPtr++ = word;
			mask = firstBit;
			word = 0;
		    }

		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0) {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < masterPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if ((masterPtr->flags & COLOR_IMAGE) == 0) {
			c += srcPtr[0];
		    } else {
			c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    }
		    srcPtr += 4;

		    if (c < 0) {
			c = 0;
		    } else if (c > 255) {
			c = 255;
		    }
		    if (c >= 128) {
			word |= mask;
			*errPtr++ = c - 255;
		    } else {
			*errPtr++ = c;
		    }
		    mask = bigEndian? (mask >> 1): (mask << 1);
		}
		*destLongPtr = word;
	    }
	    srcLinePtr += masterPtr->width * 4;
	    errLinePtr += lineLength;
	    dstLinePtr += bytesPerLine;
	}

	/*
	 * Update the pixmap for this instance with the block of pixels that
	 * we have just computed.
	 */

	TkPutImage(colorPtr->pixelMap, colorPtr->numColors,
		instancePtr->display, instancePtr->pixels,
		instancePtr->gc, imagePtr, 0, 0, xStart, yStart,
		(unsigned) width, (unsigned) nLines);
	yStart = yEnd;
    }

    ckfree(imagePtr->data);
    imagePtr->data = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoBlank --
 *
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645




3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
 *----------------------------------------------------------------------
 */

void
Tk_PhotoBlank(
    Tk_PhotoHandle handle)	/* Handle for the image to be blanked. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;
    PhotoInstance *instancePtr;

    modelPtr->ditherX = modelPtr->ditherY = 0;
    modelPtr->flags = 0;

    /*
     * The image has valid data nowhere.
     */

    if (modelPtr->validRegion != NULL) {
	TkDestroyRegion(modelPtr->validRegion);
    }
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    memset(modelPtr->pix32, 0,
	    ((size_t)modelPtr->width * modelPtr->height * 4));
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgResetDither(instancePtr);




    }

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --
 *







|


|
|





|
|

|






|
|
|

|
>
>
>
>






|
|







5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
 *----------------------------------------------------------------------
 */

void
Tk_PhotoBlank(
    Tk_PhotoHandle handle)	/* Handle for the image to be blanked. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoInstance *instancePtr;

    masterPtr->ditherX = masterPtr->ditherY = 0;
    masterPtr->flags = 0;

    /*
     * The image has valid data nowhere.
     */

    if (masterPtr->validRegion != NULL) {
	TkDestroyRegion(masterPtr->validRegion);
    }
    masterPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    memset(masterPtr->pix32, 0,
	    ((size_t) masterPtr->width * masterPtr->height * 4));
    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if (instancePtr->error) {
	    memset(instancePtr->error, 0,
		    ((size_t) masterPtr->width * masterPtr->height
		    * 3 * sizeof(schar)));
	}
    }

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --
 *
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;

    if (width <= modelPtr->width) {
	width = modelPtr->width;
    }
    if (height <= modelPtr->height) {
	height = modelPtr->height;
    }
    if ((width != modelPtr->width) || (height != modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(width, modelPtr->width),
		MAX(height, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

|
|

|
|

|
|
|

|
|
<



|
|







5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494

5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
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 = (PhotoMaster *) handle;

    if (width <= masterPtr->width) {
	width = masterPtr->width;
    }
    if (height <= masterPtr->height) {
	height = masterPtr->height;
    }
    if ((width != masterPtr->width) || (height != masterPtr->height)) {
	if (ImgPhotoSetSize(masterPtr, MAX(width, masterPtr->width),
		MAX(height, masterPtr->height)) == TCL_ERROR) {
	    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;
}

/*
 *----------------------------------------------------------------------
 *
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;

    *widthPtr = modelPtr->width;
    *heightPtr = modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoSetSize --
 *







|

|
|







5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
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 *) handle;

    *widthPtr = masterPtr->width;
    *heightPtr = masterPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoSetSize --
 *
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;

    modelPtr->userWidth = width;
    modelPtr->userHeight = height;
    if (ImgPhotoSetSize(modelPtr, ((width > 0) ? width: modelPtr->width),
	    ((height > 0) ? height: modelPtr->height)) == TCL_ERROR) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetPhotoValidRegion --







|

|
|
|
|

|
|
<



|
|







5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568

5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
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 = (PhotoMaster *) handle;

    masterPtr->userWidth = width;
    masterPtr->userHeight = height;
    if (ImgPhotoSetSize(masterPtr, ((width > 0) ? width: masterPtr->width),
	    ((height > 0) ? height: masterPtr->height)) == TCL_ERROR) {
	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;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetPhotoValidRegion --
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
 */

TkRegion
TkPhotoGetValidRegion(
    Tk_PhotoHandle handle)	/* Handle for the image whose valid region is
				 * to obtained. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;

    return modelPtr->validRegion;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgGetPhoto --
 *







|

|







5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
 */

TkRegion
TkPhotoGetValidRegion(
    Tk_PhotoHandle handle)	/* Handle for the image whose valid region is
				 * to obtained. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;

    return masterPtr->validRegion;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgGetPhoto --
 *
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ImgGetPhoto(
    PhotoModel *modelPtr,	/* 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;

    Tk_PhotoGetImage((Tk_PhotoHandle) modelPtr, blockPtr);
    blockPtr->pixelPtr += optPtr->fromY * blockPtr->pitch
	    + optPtr->fromX * blockPtr->pixelSize;
    blockPtr->width = optPtr->fromX2 - optPtr->fromX;
    blockPtr->height = optPtr->fromY2 - optPtr->fromY;

    if (!(modelPtr->flags & COLOR_IMAGE) &&
	    (!(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];
    }
    alphaOffset = 0;
    for (y = 0; y < blockPtr->height; y++) {







|









|





|







5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
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;

    Tk_PhotoGetImage((Tk_PhotoHandle) masterPtr, blockPtr);
    blockPtr->pixelPtr += optPtr->fromY * blockPtr->pitch
	    + optPtr->fromX * blockPtr->pixelSize;
    blockPtr->width = optPtr->fromX2 - optPtr->fromX;
    blockPtr->height = optPtr->fromY2 - optPtr->fromY;

    if (!(masterPtr->flags & COLOR_IMAGE) &&
	    (!(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];
    }
    alphaOffset = 0;
    for (y = 0; y < blockPtr->height; y++) {
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
    if (!alphaOffset) {
	blockPtr->offset[3]= -1; /* Tell caller alpha need not be read */
    }
    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))) {
	int newPixelSize;
	unsigned char *srcPtr, *destPtr;
	char *data;

	newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset)
		? 2 : 1;
	if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) {
	    newPixelSize += 2;
	}

	if (blockPtr->height > (int)((UINT_MAX/newPixelSize)/blockPtr->width)) {
	    return NULL;
	}
	data = (char *)attemptckalloc(newPixelSize*blockPtr->width*blockPtr->height);
	if (data == NULL) {
	    return NULL;
	}
	srcPtr = blockPtr->pixelPtr + blockPtr->offset[0];
	destPtr = (unsigned char *) data;
	if (!greenOffset && !blueOffset) {
	    for (y = blockPtr->height; y > 0; y--) {
		for (x = blockPtr->width; x > 0; x--) {
		    *destPtr = *srcPtr;
		    srcPtr += blockPtr->pixelSize;







|








|
|
<
<
<
<
<
<







5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684






5685
5686
5687
5688
5689
5690
5691
    if (!alphaOffset) {
	blockPtr->offset[3]= -1; /* Tell caller alpha need not be read */
    }
    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))) {
	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 += 2;
	}
	data = ckalloc((unsigned int) (newPixelSize *
		blockPtr->width * blockPtr->height));






	srcPtr = blockPtr->pixelPtr + blockPtr->offset[0];
	destPtr = (unsigned char *) data;
	if (!greenOffset && !blueOffset) {
	    for (y = blockPtr->height; y > 0; y--) {
		for (x = blockPtr->width; x > 0; x--) {
		    *destPtr = *srcPtr;
		    srcPtr += blockPtr->pixelSize;
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001





















































4002
4003
4004
4005
4006
4007
4008
			blockPtr->width * blockPtr->pixelSize;
	    }
	}
	blockPtr->pixelPtr = (unsigned char *) data;
	blockPtr->pixelSize = newPixelSize;
	blockPtr->pitch = newPixelSize * blockPtr->width;
	blockPtr->offset[0] = 0;
	if (newPixelSize > 2) {
	    blockPtr->offset[1] = 1;
	    blockPtr->offset[2] = 2;
	    blockPtr->offset[3]= 3;
	} else {
	    blockPtr->offset[1] = 0;
	    blockPtr->offset[2] = 0;
	    blockPtr->offset[3]= 1;
	}
	return data;
    }
    return NULL;
}






















































/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoGetImage --
 *
 *	This function is called to obtain image data from a photo image. This







|
|
|


|
|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
			blockPtr->width * blockPtr->pixelSize;
	    }
	}
	blockPtr->pixelPtr = (unsigned char *) data;
	blockPtr->pixelSize = newPixelSize;
	blockPtr->pitch = newPixelSize * blockPtr->width;
	blockPtr->offset[0] = 0;
	if (newPixelSize>2) {
	    blockPtr->offset[1]= 1;
	    blockPtr->offset[2]= 2;
	    blockPtr->offset[3]= 3;
	} else {
	    blockPtr->offset[1]= 0;
	    blockPtr->offset[2]= 0;
	    blockPtr->offset[3]= 1;
	}
	return data;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgStringWrite --
 *
 *	Default string write function. The data is formatted in the default
 *	format as accepted by the "<img> put" command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgStringWrite(
    Tcl_Interp *interp,
    Tcl_Obj *formatString,
    Tk_PhotoImageBlock *blockPtr)
{
    int row, col;
    char *line, *linePtr;
    unsigned char *pixelPtr;
    int greenOffset, blueOffset;
    Tcl_DString data;

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    Tcl_DStringInit(&data);
    if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
	line = (char *) ckalloc((unsigned int) ((8 * blockPtr->width) + 2));
	for (row=0; row<blockPtr->height; row++) {
	    pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0] +
		    row * blockPtr->pitch;
	    linePtr = line;
	    for (col=0; col<blockPtr->width; col++) {
		sprintf(linePtr, " #%02x%02x%02x", *pixelPtr,
			pixelPtr[greenOffset], pixelPtr[blueOffset]);
		pixelPtr += blockPtr->pixelSize;
		linePtr += 8;
	    }
	    Tcl_DStringAppendElement(&data, line+1);
	}
	ckfree (line);
    }
    Tcl_DStringResult(interp, &data);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoGetImage --
 *
 *	This function is called to obtain image data from a photo image. This
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045





























































































4046
4047



















































4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
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. */
{
    PhotoModel *modelPtr = (PhotoModel *) handle;

    blockPtr->pixelPtr = modelPtr->pix32;
    blockPtr->width = modelPtr->width;
    blockPtr->height = modelPtr->height;
    blockPtr->pitch = modelPtr->width * 4;
    blockPtr->pixelSize = 4;
    blockPtr->offset[0] = 0;
    blockPtr->offset[1] = 1;
    blockPtr->offset[2] = 2;
    blockPtr->offset[3] = 3;
    return 1;
}

/*





























































































 *--------------------------------------------------------------
 *



















































 * ImgPostscriptPhoto --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImgPhotoPostscript(
    ClientData clientData,	/* Handle for the photo image. */
    Tcl_Interp *interp,		/* Interpreter. */
    TCL_UNUSED(Tk_Window),		/* (unused) */
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    int x, int y,		/* First pixel to output. */
    int width, int height,	/* Width and height of area. */
    TCL_UNUSED(int))		/* (unused) */
{
    Tk_PhotoImageBlock block;

    Tk_PhotoGetImage(clientData, &block);
    block.pixelPtr += y * block.pitch + x * block.pixelSize;

    return Tk_PostscriptPhoto(interp, &block, psInfo, width, height);
}

/*
 *----------------------------------------------------------------------
 *
 * 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, except that the compositing rule is
 * always "overlay" and the function always panics on memory-allocation
 * failure.
 *
 *----------------------------------------------------------------------
 */
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
void
Tk_PhotoPutBlock_NoComposite(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height)
{
    if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,







|

|
|
|
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

















|



|



|










|







|







5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
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 *) handle;

    blockPtr->pixelPtr = masterPtr->pix32;
    blockPtr->width = masterPtr->width;
    blockPtr->height = masterPtr->height;
    blockPtr->pitch = masterPtr->width * 4;
    blockPtr->pixelSize = 4;
    blockPtr->offset[0] = 0;
    blockPtr->offset[1] = 1;
    blockPtr->offset[2] = 2;
    blockPtr->offset[3] = 3;
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * PhotoOptionFind --
 *
 *	Finds a specific Photo option.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	After commands are removed.
 *
 *----------------------------------------------------------------------
 */

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) */
} OptionAssocData;

static Tcl_ObjCmdProc *
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);
    char *prevname = NULL;
    Tcl_ObjCmdProc *proc = NULL;
    OptionAssocData *list = (OptionAssocData *) Tcl_GetAssocData(interp,
	    "photoOption", NULL);

    while (list != NULL) {
	if (strncmp(name, list->name, (unsigned) length) == 0) {
	    if (proc != NULL) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "ambiguous option \"", name,
			"\": must be ", prevname, NULL);
		while (list->nextPtr != NULL) {
		    Tcl_AppendResult(interp, prevname, ", ",NULL);
		    list = list->nextPtr;
		    prevname = list->name;
		}
		Tcl_AppendResult(interp, ", or", prevname, NULL);
		return NULL;
	    }
	    proc = list->command;
	    prevname = list->name;
	}
	list = list->nextPtr;
    }
    if (proc != NULL) {
	Tcl_ResetResult(interp);
    }
    return proc;
}

/*
 *----------------------------------------------------------------------
 *
 * PhotoOptionCleanupProc --
 *
 *	This function is invoked whenever an interpreter is deleted to cleanup
 *	the AssocData for "photoVisitor".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Photo Visitor options are removed.
 *
 *----------------------------------------------------------------------
 */

static void
PhotoOptionCleanupProc(
    ClientData clientData,	/* Points to "photoVisitor" AssocData for the
				 * interpreter. */
    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
{
    OptionAssocData *list = (OptionAssocData *) clientData;

    while (list != NULL) {
	register OptionAssocData *ptr;

	list = (ptr = list)->nextPtr;
	ckfree((char *) ptr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CreatePhotoOption --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

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 = (OptionAssocData *)
	    Tcl_GetAssocData(interp, "photoOption", NULL);

    /*
     * If there's already a photo option with the given name, remove it.
     */

    for (typePtr2 = list, prevPtr = NULL; typePtr2 != NULL;
	    prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) {
	if (strcmp(typePtr2->name, name) == 0) {
	    if (prevPtr == NULL) {
		list = typePtr2->nextPtr;
	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree((char *) typePtr2);
	    break;
	}
    }
    ptr = (OptionAssocData *) ckalloc(sizeof(OptionAssocData) + strlen(name));
    strcpy(&(ptr->name[0]), name);
    ptr->command = proc;
    ptr->nextPtr = list;
    Tcl_SetAssocData(interp, "photoOption", PhotoOptionCleanupProc,
	    (ClientData) ptr);
}

/*
 *--------------------------------------------------------------
 *
 * TkPostscriptPhoto --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
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;

    Tk_PhotoGetImage((Tk_PhotoHandle) clientData, &block);
    block.pixelPtr += y * block.pitch + x * block.pixelSize;

    return Tk_PostscriptPhoto(interp, &block, psInfo, width, height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutBlock_NoComposite, Tk_PhotoPutZoomedBlock_NoComposite --
 *
 * These backward-compatibility 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(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height)
{
    if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */







|







6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
 * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
 *
 * Backward compatibility 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.
 *
 *----------------------------------------------------------------------
 */
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
    Tk_PhotoHandle handle,
    int width, int height)
{
    if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}
#endif /* TK_NO_DEPRECATED */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * tab-width: 8
 * End:
 */







<






<


6159
6160
6161
6162
6163
6164
6165

6166
6167
6168
6169
6170
6171

6172
6173
    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:
 */

Deleted generic/tkImgPhoto.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
 * tkImgPhoto.h --
 *
 *	Declarations for images of type "photo" for Tk.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2008 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.
 *
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkInt.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations of the structures we define.
 */

#define PhotoMaster PhotoModel
typedef struct ColorTableId	ColorTableId;
typedef struct ColorTable	ColorTable;
typedef struct PhotoInstance	PhotoInstance;
typedef struct PhotoModel	PhotoModel;

/*
 * 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)
    typedef signed char schar;
#else
#   ifndef __CHAR_UNSIGNED__
	typedef char schar;
#   else
	typedef short schar;
#   endif
#endif

/*
 * The maximum number of pixels to transmit to the server in a single
 * XPutImage call.
 */

#define MAX_PIXELS 65536

/*
 * 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 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:
 */

struct ColorTableId {
    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
				 * we want to allocate. */
};

/*
 * 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:
 */

struct ColorTable {
    ColorTableId id;		/* Information used in selecting this color
				 * table. */
#if TCL_MAJOR_VERSION > 8
    size_t	refCount;		/* Number of instances using this map. */
    size_t liveRefCount;		/* Number of instances which are actually in
				 * use, using this map. */
    int	flags;			/* See below. */
#else
    int	flags;			/* See below. */
    unsigned int	refCount;		/* Number of instances using this map. */
    unsigned int liveRefCount;		/* Number of instances which are actually in
				 * use, using this map. */
#endif
    int	numColors;		/* Number of colors allocated for this map. */

    XVisualInfo	visualInfo;	/* Information about the visual for windows
				 * using this color table. */

    unsigned redValues[256];	/* Maps 8-bit values of red intensity to a
				 * pixel value or index in pixelMap. */
    unsigned greenValues[256];	/* Ditto for green intensity. */
    unsigned 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. */
};

/*
 * Bit definitions for the flags field of a ColorTable.
 * BLACK_AND_WHITE:		1 means only black and white colors are
 *				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.
 */

#ifdef COLOR_WINDOW
#undef COLOR_WINDOW
#endif

#define BLACK_AND_WHITE		1
#define COLOR_WINDOW		2
#define DISPOSE_PENDING		4
#define MAP_COLORS		8

/*
 * Definition of the data associated with each photo image model.
 */

struct PhotoModel {
    Tk_ImageModel tkModel;	/* Tk's token for image model. 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. */
    Tk_Uid palette;		/* User-specified default palette for
				 * instances of this image. */
    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. */
    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. */
    PhotoInstance *instancePtr;	/* First in the list of instances associated
				 * with this model. */
};

/*
 * Bit definitions for the flags field of a PhotoModel.
 * 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, and so need
 *				the copy-merge-replace renderer .
 */

#define COLOR_IMAGE		1
#define IMAGE_CHANGED		2
#define COMPLEX_ALPHA		4

/*
 * Flag to OR with the compositing rule to indicate that the source, despite
 * having an alpha channel, has simple alpha.
 */

#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.
 */

struct PhotoInstance {
    PhotoModel *modelPtr;	/* Pointer to model for image. */
    Display *display;		/* Display for windows using this instance. */
    Colormap colormap;		/* The image may only be used in windows with
				 * this particular colormap. */
    PhotoInstance *nextPtr;	/* Pointer to the next instance in the list of
				 * instances associated with this model. */
#if TCL_MAJOR_VERSION > 8
    size_t refCount;		/* Number of instances using this structure. */
#else
    unsigned int refCount;	/* Number of instances using this structure. */
#endif
    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 model. */
    ColorTable *colorTablePtr;	/* Pointer to information about colors
				 * 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. */
};

/*
 * Implementation of the Porter-Duff Source-Over compositing rule.
 */

#define PD_SRC_OVER(srcColor, srcAlpha, dstColor, dstAlpha) \
	(srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255
#define PD_SRC_OVER_ALPHA(srcAlpha, dstAlpha) \
	(srcAlpha + (255-srcAlpha)*dstAlpha/255)

#undef MIN
#define MIN(a, b)	((a) < (b)? (a): (b))
#undef MAX
#define MAX(a, b)	((a) > (b)? (a): (b))

/*
 * Declarations of functions shared between the different parts of the
 * photo image implementation.
 */

MODULE_SCOPE void	TkImgPhotoConfigureInstance(
			    PhotoInstance *instancePtr);
MODULE_SCOPE void	TkImgDisposeInstance(ClientData clientData);
MODULE_SCOPE void	TkImgPhotoInstanceSetSize(PhotoInstance *instancePtr);
MODULE_SCOPE ClientData	TkImgPhotoGet(Tk_Window tkwin, ClientData clientData);
MODULE_SCOPE void	TkImgDitherInstance(PhotoInstance *instancePtr, int x,
			    int y, int width, int height);
MODULE_SCOPE void	TkImgPhotoDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
MODULE_SCOPE void	TkImgPhotoFree(ClientData clientData,
			    Display *display);
MODULE_SCOPE void	TkImgResetDither(PhotoInstance *instancePtr);

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































Deleted generic/tkImgSVGnano.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
/*
 * tkImgSVGnano.c
 *
 *	A photo file handler for SVG files.
 *
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 * Copyright (c) 2018 Christian Gollwitzer auriocus@gmx.de
 * Copyright (c) 2018 Christian Werner https://www.androwish.org/
 * Copyright (c) 2018 Rene Zaumseil r.zaumseil@freenet.de
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This handler is build using the original nanosvg library files from
 * https://github.com/memononen/nanosvg
 *
 */

#include "tkInt.h"
#define NANOSVG_malloc	ckalloc
#define NANOSVG_realloc	ckrealloc
#define NANOSVG_free	ckfree
#define NANOSVG_SCOPE MODULE_SCOPE
#define NANOSVG_ALL_COLOR_KEYWORDS
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"

/* Additional parameters to nsvgRasterize() */

typedef struct {
    double scale;
    int scaleToHeight;
    int scaleToWidth;
} RastOpts;

/*
 * Per interp cache of last NSVGimage which was matched to
 * be immediately rasterized after the match. This helps to
 * eliminate double parsing of the SVG file/string.
 */

typedef struct {
    /* A poiner to remember if it is the same svn image (data)
     * It is a Tcl_Channel if image created by -file option
     * or a Tcl_Obj, if image is created with the -data option
     */
    ClientData dataOrChan;
    Tcl_DString formatString;
    NSVGimage *nsvgImage;
    RastOpts ropts;
} NSVGcache;

static int		FileMatchSVG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *format, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadSVG(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		StringMatchSVG(Tcl_Obj *dataObj, Tcl_Obj *format,
			    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int		StringReadSVG(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 NSVGimage *	ParseSVGWithOptions(Tcl_Interp *interp,
			    const char *input, TkSizeT length, Tcl_Obj *format,
			    RastOpts *ropts);
static int		RasterizeSVG(Tcl_Interp *interp,
			    Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, RastOpts *ropts);
static double		GetScaleFromParameters(NSVGimage *nsvgImage,
			    RastOpts *ropts, int *widthPtr, int *heightPtr);
static NSVGcache *	GetCachePtr(Tcl_Interp *interp);
static int		CacheSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, NSVGimage *nsvgImage,
			    RastOpts *ropts);
static NSVGimage *	GetCachedSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, RastOpts *ropts);
static void		CleanCache(Tcl_Interp *interp);
static void		FreeCache(ClientData clientData, Tcl_Interp *interp);

/*
 * The format record for the SVG nano file format:
 */

Tk_PhotoImageFormat tkImgFmtSVGnano = {
    "svg",			/* name */
    FileMatchSVG,		/* fileMatchProc */
    StringMatchSVG,		/* stringMatchProc */
    FileReadSVG,		/* fileReadProc */
    StringReadSVG,		/* stringReadProc */
    NULL,			/* fileWriteProc */
    NULL,			/* stringWriteProc */
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * FileMatchSVG --
 *
 *	This function is invoked by the photo image type to see if a file
 *	contains image data in SVG format.
 *
 * Results:
 *	The return value is >0 if the file can be successfully parsed,
 *	and 0 otherwise.
 *
 * Side effects:
 *	The file is saved in the internal cache for further use.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchSVG(
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    Tcl_Obj *dataObj = Tcl_NewObj();
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;
    (void)fileName;

    CleanCache(interp);
    if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {
	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    data = TkGetStringFromObj(dataObj, &length);
    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    Tcl_DecrRefCount(dataObj);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;
        }
        if (!CacheSVG(interp, chan, formatObj, nsvgImage, &ropts)) {
	    nsvgDelete(nsvgImage);
        }
        return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * FileReadSVG --
 *
 *	This function is called by the photo image type to read SVG 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.
 *
 * Side effects:
 *	The access position in file f is changed, and new data is added to the
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadSVG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, chan, formatObj, &ropts);
    (void)fileName;

    if (nsvgImage == NULL) {
        Tcl_Obj *dataObj = Tcl_NewObj();

	if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {
	    /* in case of an error reading the file */
	    Tcl_DecrRefCount(dataObj);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("read error", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "READ_ERROR", NULL);
	    return TCL_ERROR;
	}
	data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
	Tcl_DecrRefCount(dataObj);
	if (nsvgImage == NULL) {
	    return TCL_ERROR;
	}
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,
		width, height, srcX, srcY, &ropts);
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchSVG --
 *
 *	This function is invoked by the photo image type to see if a string
 *	contains image data in SVG format.
 *
 * Results:
 *	The return value is >0 if the file can be successfully parsed,
 *	and 0 otherwise.
 *
 * Side effects:
 *	The file is saved in the internal cache for further use.
 *
 *----------------------------------------------------------------------
 */

static int
StringMatchSVG(
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;

    CleanCache(interp);
    data = TkGetStringFromObj(dataObj, &length);
    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;
        }
        if (!CacheSVG(interp, dataObj, formatObj, nsvgImage, &ropts)) {
	    nsvgDelete(nsvgImage);
        }
        return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * StringReadSVG --
 *
 *	This function is called by the photo image type to read SVG 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.
 *
 * Side effects:
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadSVG(
    Tcl_Interp *interp,
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, dataObj, formatObj, &ropts);

    if (nsvgImage == NULL) {
        data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
    }
    if (nsvgImage == NULL) {
	return TCL_ERROR;
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,
		width, height, srcX, srcY, &ropts);
}

/*
 *----------------------------------------------------------------------
 *
 * ParseSVGWithOptions --
 *
 *	This function is called to parse the given input string as SVG.
 *
 * Results:
 *	Return a newly create NSVGimage on success, and NULL otherwise.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
ParseSVGWithOptions(
    Tcl_Interp *interp,
    const char *input,
    TkSizeT length,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    double dpi = 96.0;
    char *inputCopy = NULL;
    NSVGimage *nsvgImage;
    int parameterScaleSeen = 0;
    static const char *const fmtOptions[] = {
        "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL
    };
    enum fmtOptionsEnum {
	OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH
    };

    /*
     * The parser destroys the original input string,
     * therefore first duplicate.
     */

    inputCopy = (char *)attemptckalloc(length+1);
    if (inputCopy == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto error;
    }
    memcpy(inputCopy, input, length);
    inputCopy[length] = '\0';

    /*
     * Process elements of format specification as a list.
     */

    ropts->scale = 1.0;
    ropts->scaleToHeight = 0;
    ropts->scaleToWidth = 0;
    if ((formatObj != NULL) &&
	    Tcl_ListObjGetElements(interp, formatObj, &objc, &objv) != TCL_OK) {
        goto error;
    }
    for (; objc > 0 ; objc--, objv++) {
	int optIndex;

	/*
	 * Ignore the "svg" part of the format specification.
	 */

	if (!strcasecmp(Tcl_GetString(objv[0]), "svg")) {
	    continue;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions,
		sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) {
	    goto error;
	}

	if (objc < 2) {
	    ckfree(inputCopy);
	    inputCopy = NULL;
	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    goto error;
	}

	objc--;
	objv++;

	/*
	 * check that only one scale option is given
	 */
	switch ((enum fmtOptionsEnum)optIndex) {
	case OPT_SCALE:
	case OPT_SCALE_TO_HEIGHT:
	case OPT_SCALE_TO_WIDTH:
	    if ( parameterScaleSeen ) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"only one of -scale, -scaletoheight, -scaletowidth may be given", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    parameterScaleSeen = 1;
	    break;
	default:
	    break;
	}

	/*
	 * Decode parameters
	 */
	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_DPI:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) {
	        goto error;
	    }
	    if (dpi < 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-dpi value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scale <= 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scale value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_HEIGHT:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToHeight) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToHeight <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletoheight value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_WIDTH:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToWidth) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToWidth <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletowidth value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	}
    }

    nsvgImage = nsvgParse(inputCopy, "px", (float) dpi);
    if (nsvgImage == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL);
	goto error;
    }
    ckfree(inputCopy);
    return nsvgImage;

error:
    if (inputCopy != NULL) {
        ckfree(inputCopy);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * RasterizeSVG --
 *
 *	This function is called to rasterize the given nsvgImage and
 *	fill the imageHandle with data.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 *
 * Side effects:
 *	On error the given nsvgImage will be deleted.
 *
 *----------------------------------------------------------------------
 */

static int
RasterizeSVG(
    Tcl_Interp *interp,
    Tk_PhotoHandle imageHandle,
    NSVGimage *nsvgImage,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY,
    RastOpts *ropts)
{
    int w, h, c;
    NSVGrasterizer *rast;
    unsigned char *imgData;
    Tk_PhotoImageBlock svgblock;
    double scale;
    (void)srcX;
    (void)srcY;

    scale = GetScaleFromParameters(nsvgImage, ropts, &w, &h);

    rast = nsvgCreateRasterizer();
    if (rast == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR",
		NULL);
	goto cleanAST;
    }
    imgData = (unsigned char *)attemptckalloc(w * h *4);
    if (imgData == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto cleanRAST;
    }
    nsvgRasterize(rast, nsvgImage, 0, 0,
	    (float) scale, imgData, w, h, w * 4);
    /* transfer the data to a photo block */
    svgblock.pixelPtr = imgData;
    svgblock.width = w;
    svgblock.height = h;
    svgblock.pitch = w * 4;
    svgblock.pixelSize = 4;
    for (c = 0; c <= 3; c++) {
	svgblock.offset[c] = c;
    }
    if (Tk_PhotoExpand(interp, imageHandle,
		destX + width, destY + height) != TCL_OK) {
	goto cleanRAST;
    }
    if (Tk_PhotoPutBlock(interp, imageHandle, &svgblock, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	goto cleanimg;
    }
    ckfree(imgData);
    nsvgDeleteRasterizer(rast);
    nsvgDelete(nsvgImage);
    return TCL_OK;

cleanimg:
    ckfree(imgData);

cleanRAST:
    nsvgDeleteRasterizer(rast);

cleanAST:
    nsvgDelete(nsvgImage);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetScaleFromParameters --
 *
 *	Get the scale value from the already parsed parameters -scale,
 *	-scaletoheight and -scaletowidth.
 *
 *	The image width and height is also returned.
 *
 * Results:
 *	The evaluated or configured scale value, or 0.0 on failure
 *
 * Side effects:
 *	heightPtr and widthPtr are set to height and width of the image.
 *
 *----------------------------------------------------------------------
 */

static double
GetScaleFromParameters(
    NSVGimage *nsvgImage,
    RastOpts *ropts,
    int *widthPtr,
    int *heightPtr)
{
    double scale;
    int width, height;

    if ((nsvgImage->width == 0.0) || (nsvgImage->height == 0.0)) {
        width = height = 0;
        scale = 1.0;
    } else if (ropts->scaleToHeight > 0) {
	/*
	 * Fixed height
	 */
	height = ropts->scaleToHeight;
	scale = height / nsvgImage->height;
	width = (int) ceil(nsvgImage->width * scale);
    } else if (ropts->scaleToWidth > 0) {
	/*
	 * Fixed width
	 */
	width = ropts->scaleToWidth;
	scale = width / nsvgImage->width;
	height = (int) ceil(nsvgImage->height * scale);
    } else {
	/*
	 * Scale factor
	 */
	scale = ropts->scale;
	width = (int) ceil(nsvgImage->width * scale);
	height = (int) ceil(nsvgImage->height * scale);
    }

    *heightPtr = height;
    *widthPtr = width;
    return scale;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCachePtr --
 *
 *	This function is called to get the per interpreter used
 *	svg image cache.
 *
 * Results:
 * 	Return a pointer to the used cache.
 *
 * Side effects:
 *	Initialize the cache on the first call.
 *
 *----------------------------------------------------------------------
 */

static NSVGcache *
GetCachePtr(
    Tcl_Interp *interp
) {
    NSVGcache *cachePtr = (NSVGcache *)Tcl_GetAssocData(interp, "tksvgnano", NULL);
    if (cachePtr == NULL) {
	cachePtr = (NSVGcache *)ckalloc(sizeof(NSVGcache));
	cachePtr->dataOrChan = NULL;
	Tcl_DStringInit(&cachePtr->formatString);
	cachePtr->nsvgImage = NULL;
	Tcl_SetAssocData(interp, "tksvgnano", FreeCache, cachePtr);
    }
    return cachePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * CacheSVG --
 *
 *	Add the given svg image informations to the cache for further usage.
 *
 * Results:
 *	Return 1 on success, and 0 otherwise.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static int
CacheSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    NSVGimage *nsvgImage,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = dataOrChan;
	if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    Tcl_DStringAppend(&cachePtr->formatString, data, length);
	}
	cachePtr->nsvgImage = nsvgImage;
	cachePtr->ropts = *ropts;
	return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCachedSVG --
 *
 *	Try to get the NSVGimage from the internal cache.
 *
 * Results:
 *	Return the found NSVGimage on success, and NULL otherwise.
 *
 * Side effects:
 *	Calls the CleanCache() function.
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
GetCachedSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);
    NSVGimage *nsvgImage = NULL;

    if ((cachePtr != NULL) && (cachePtr->nsvgImage != NULL) &&
	(cachePtr->dataOrChan == dataOrChan)) {
        if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    if (strcmp(data, Tcl_DStringValue(&cachePtr->formatString)) == 0) {
	        nsvgImage = cachePtr->nsvgImage;
		*ropts = cachePtr->ropts;
		cachePtr->nsvgImage = NULL;
	    }
	} else if (Tcl_DStringLength(&cachePtr->formatString) == 0) {
	    nsvgImage = cachePtr->nsvgImage;
	    *ropts = cachePtr->ropts;
	    cachePtr->nsvgImage = NULL;
	}
    }
    CleanCache(interp);
    return nsvgImage;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanCache --
 *
 *	Reset the cache and delete the saved image in it.
 *
 * Results:
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static void
CleanCache(Tcl_Interp *interp)
{
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = NULL;
        Tcl_DStringSetLength(&cachePtr->formatString, 0);
	if (cachePtr->nsvgImage != NULL) {
	    nsvgDelete(cachePtr->nsvgImage);
	    cachePtr->nsvgImage = NULL;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeCache --
 *
 *	This function is called to clean up the internal cache data.
 *
 * Results:
 *
 * Side effects:
 *	Existing image data in the cache and the cache will be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeCache(ClientData clientData, Tcl_Interp *interp)
{
    NSVGcache *cachePtr = (NSVGcache *)clientData;
    (void)interp;

    Tcl_DStringFree(&cachePtr->formatString);
    if (cachePtr->nsvgImage != NULL) {
        nsvgDelete(cachePtr->nsvgImage);
    }
    ckfree(cachePtr);
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkImgUtil.c.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
     */

    dataWidth = image->bytes_per_line;
    if (dataWidth % alignment) {
	dataWidth += (alignment - (dataWidth % alignment));
    }

    data = (char *)ckalloc(dataWidth * image->height);

    destPtr = data;
    for (i = 0; i < image->height; i++) {
	srcPtr = &image->data[i * image->bytes_per_line];
	for (j = 0; j < dataWidth; j++) {
	    if (j >= image->bytes_per_line) {
		*destPtr = 0;







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
     */

    dataWidth = image->bytes_per_line;
    if (dataWidth % alignment) {
	dataWidth += (alignment - (dataWidth % alignment));
    }

    data = ckalloc((unsigned) dataWidth * image->height);

    destPtr = data;
    for (i = 0; i < image->height; i++) {
	srcPtr = &image->data[i * image->bytes_per_line];
	for (j = 0; j < dataWidth; j++) {
	    if (j >= image->bytes_per_line) {
		*destPtr = 0;

Changes to generic/tkInt.decls.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61


62
63




64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
library tk

##############################################################################

# Define the unsupported generic interfaces.

interface tkInt
scspec EXTERN

# Declare each of the functions in the unsupported internal Tcl interface.
# These interfaces are allowed to changed between versions. Use at your own
# risk. Note that the position of functions should not be changed between
# versions to avoid gratuitous incompatibilities.

declare 0 {
    TkWindow *TkAllocWindow(TkDisplay *dispPtr, int screenNum,
	    TkWindow *parentPtr)
}
declare 1 {
    void TkBezierPoints(double control[], int numSteps, double *coordPtr)
}
declare 2 {
    void TkBezierScreenPoints(Tk_Canvas canvas, double control[],
	    int numSteps, XPoint *xPointPtr)
}
#

# Slot 3 unused (WAS: TkBindDeadWindow)
#

declare 4 {
    void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr)
}
declare 5 {
    void TkBindFree(TkMainInfo *mainPtr)
}
declare 6 {
    void TkBindInit(TkMainInfo *mainPtr)
}
declare 7 {
    void TkChangeEventWindow(XEvent *eventPtr, TkWindow *winPtr)
}
declare 8 {
    int TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr)
}
declare 9 {
    void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY,
	    int innerWidth, int innerHeight, int *xPtr, int *yPtr)
}
#

# Slot 10 unused (WAS: TkCopyAndGlobalEval)


# Slot 11 unused (WAS: TkCreateBindingProcedure)
#




declare 12 {
    TkCursor *TkCreateCursorFromData(Tk_Window tkwin,
	    const char *source, const char *mask, int width, int height,
	    int xHot, int yHot, XColor fg, XColor bg)
}
declare 13 {
    int TkCreateFrame(ClientData clientData, Tcl_Interp *interp,
	    int argc, const char *const *argv, int toplevel, const char *appName)
}
declare 14 {
    Tk_Window TkCreateMainWindow(Tcl_Interp *interp,
	    const char *screenName, const char *baseName)
}
declare 15 {
    Time TkCurrentTime(TkDisplay *dispPtr)
}
declare 16 {
    void TkDeleteAllImages(TkMainInfo *mainPtr)
}







<

















<
>
|
<
>



















<
>
|
>
>
|
<
>
>
>
>







|



|







13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
library tk

##############################################################################

# Define the unsupported generic interfaces.

interface tkInt


# Declare each of the functions in the unsupported internal Tcl interface.
# These interfaces are allowed to changed between versions. Use at your own
# risk. Note that the position of functions should not be changed between
# versions to avoid gratuitous incompatibilities.

declare 0 {
    TkWindow *TkAllocWindow(TkDisplay *dispPtr, int screenNum,
	    TkWindow *parentPtr)
}
declare 1 {
    void TkBezierPoints(double control[], int numSteps, double *coordPtr)
}
declare 2 {
    void TkBezierScreenPoints(Tk_Canvas canvas, double control[],
	    int numSteps, XPoint *xPointPtr)
}

declare 3 {
    void TkBindDeadWindow(TkWindow *winPtr)

}
declare 4 {
    void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr)
}
declare 5 {
    void TkBindFree(TkMainInfo *mainPtr)
}
declare 6 {
    void TkBindInit(TkMainInfo *mainPtr)
}
declare 7 {
    void TkChangeEventWindow(XEvent *eventPtr, TkWindow *winPtr)
}
declare 8 {
    int TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr)
}
declare 9 {
    void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY,
	    int innerWidth, int innerHeight, int *xPtr, int *yPtr)
}

declare 10 {
    int TkCopyAndGlobalEval(Tcl_Interp *interp, char *script)
}
declare 11 {
    unsigned long TkCreateBindingProcedure(Tcl_Interp *interp,

	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventString, TkBindEvalProc *evalProc,
	    TkBindFreeProc *freeProc, ClientData clientData)
}
declare 12 {
    TkCursor *TkCreateCursorFromData(Tk_Window tkwin,
	    const char *source, const char *mask, int width, int height,
	    int xHot, int yHot, XColor fg, XColor bg)
}
declare 13 {
    int TkCreateFrame(ClientData clientData, Tcl_Interp *interp,
	    int argc, char **argv, int toplevel, char *appName)
}
declare 14 {
    Tk_Window TkCreateMainWindow(Tcl_Interp *interp,
	    const char *screenName, char *baseName)
}
declare 15 {
    Time TkCurrentTime(TkDisplay *dispPtr)
}
declare 16 {
    void TkDeleteAllImages(TkMainInfo *mainPtr)
}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	    Display *display, Drawable drawable, GC gc, GC outlineGC)
}
declare 21 {
    int TkFindStateNum(Tcl_Interp *interp, const char *option,
	    const TkStateMap *mapPtr, const char *strKey)
}
declare 22 {
    const char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
    void TkFocusDeadWindow(TkWindow *winPtr)
}
declare 24 {
    int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr)
}







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
	    Display *display, Drawable drawable, GC gc, GC outlineGC)
}
declare 21 {
    int TkFindStateNum(Tcl_Interp *interp, const char *option,
	    const TkStateMap *mapPtr, const char *strKey)
}
declare 22 {
    char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
    void TkFocusDeadWindow(TkWindow *winPtr)
}
declare 24 {
    int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr)
}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
}

# Name change only, TkFreeCursor in Tcl 8.0.x now TkpFreeCursor
declare 29 {
    void TkpFreeCursor(TkCursor *cursorPtr)
}
declare 30 {
    char *TkGetBitmapData(Tcl_Interp *interp, const char *string,
	    const char *fileName, int *widthPtr, int *heightPtr,
	    int *hotXPtr, int *hotYPtr)
}
declare 31 {
    void TkGetButtPoints(double p1[], double p2[],
	    double width, int project, double m1[], double m2[])
}
declare 32 {
    TkCursor *TkGetCursorByName(Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_Uid string)
}
declare 33 {
    const char *TkGetDefaultScreenName(Tcl_Interp *interp,
	    const char *screenName)
}
declare 34 {
    TkDisplay *TkGetDisplay(Display *display)
}
declare 35 {
    int TkGetDisplayOf(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],







|
|











|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
}

# Name change only, TkFreeCursor in Tcl 8.0.x now TkpFreeCursor
declare 29 {
    void TkpFreeCursor(TkCursor *cursorPtr)
}
declare 30 {
    char *TkGetBitmapData(Tcl_Interp *interp, char *string,
	    char *fileName, int *widthPtr, int *heightPtr,
	    int *hotXPtr, int *hotYPtr)
}
declare 31 {
    void TkGetButtPoints(double p1[], double p2[],
	    double width, int project, double m1[], double m2[])
}
declare 32 {
    TkCursor *TkGetCursorByName(Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_Uid string)
}
declare 33 {
    CONST84_RETURN char *TkGetDefaultScreenName(Tcl_Interp *interp,
	    const char *screenName)
}
declare 34 {
    TkDisplay *TkGetDisplay(Display *display)
}
declare 35 {
    int TkGetDisplayOf(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	    TkWindow *destPtr, int leaveType, int enterType,
	    Tcl_QueuePosition position)
}
declare 45 {
    void TkInstallFrameMenu(Tk_Window tkwin)
}
declare 46 {
    const char *TkKeysymToString(KeySym keysym)
}
declare 47 {
    int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
}
declare 48 {
    double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[])
}







|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	    TkWindow *destPtr, int leaveType, int enterType,
	    Tcl_QueuePosition position)
}
declare 45 {
    void TkInstallFrameMenu(Tk_Window tkwin)
}
declare 46 {
    char *TkKeysymToString(KeySym keysym)
}
declare 47 {
    int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
}
declare 48 {
    double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[])
}
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
declare 65 {
    void TkpMakeMenuWindow(Tk_Window tkwin, int transient)
}
declare 66 {
    Window TkpMakeWindow(TkWindow *winPtr, Window parent)
}
declare 67 {
    void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, const char *menuName)
}
declare 68 {
    TkDisplay *TkpOpenDisplay(const char *display_name)
}
declare 69 {
    int TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr)
}
declare 70 {
    int TkPolygonToArea(double *polyPtr, int numPoints, double *rectPtr)
}
declare 71 {
    double TkPolygonToPoint(double *polyPtr, int numPoints, double *pointPtr)
}
declare 72 {
    int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr)
}
declare 73 {
    void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr)
}
declare 74 {
    void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, const char *menuName)
}
declare 75 {
    int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, const char *string)
}
#

# Slot 76 unused (WAS: TkpWindowWasRecentlyDeleted)
#

declare 77 {
    void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr)
}
declare 78 {
    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)
}
declare 79 {
    int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
	    int width, int height, int dx, int dy, Region damageRgn)
}
declare 80 {
    void TkSelDeadWindow(TkWindow *winPtr)
}
declare 81 {
    void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr)
}







|




















|




<
>
|
<
>










|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
declare 65 {
    void TkpMakeMenuWindow(Tk_Window tkwin, int transient)
}
declare 66 {
    Window TkpMakeWindow(TkWindow *winPtr, Window parent)
}
declare 67 {
    void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, char *menuName)
}
declare 68 {
    TkDisplay *TkpOpenDisplay(const char *display_name)
}
declare 69 {
    int TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr)
}
declare 70 {
    int TkPolygonToArea(double *polyPtr, int numPoints, double *rectPtr)
}
declare 71 {
    double TkPolygonToPoint(double *polyPtr, int numPoints, double *pointPtr)
}
declare 72 {
    int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr)
}
declare 73 {
    void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr)
}
declare 74 {
    void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, char *menuName)
}
declare 75 {
    int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, const char *string)
}

declare 76 {
    int TkpWindowWasRecentlyDeleted(Window win, TkDisplay *dispPtr)

}
declare 77 {
    void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr)
}
declare 78 {
    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)
}
declare 79 {
    int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
	    int width, int height, int dx, int dy, TkRegion damageRgn)
}
declare 80 {
    void TkSelDeadWindow(TkWindow *winPtr)
}
declare 81 {
    void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr)
}
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# Exported publically as Tk_SetClassProcs in 8.4a2
#declare 84 {
#    void TkSetClassProcs(Tk_Window tkwin,
#	    TkClassProcs *procs, ClientData instanceData)
#}
declare 85 {
    void TkSetWindowMenuBar(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *oldMenuName, const char *menuName)
}
declare 86 {
    KeySym TkStringToKeysym(const char *name)
}
declare 87 {
    int TkThickPolyLineToArea(double *coordPtr, int numPoints,
	    double width, int capStyle, int joinStyle, double *rectPtr)
}
declare 88 {
    void TkWmAddToColormapWindows(TkWindow *winPtr)







|


|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# Exported publically as Tk_SetClassProcs in 8.4a2
#declare 84 {
#    void TkSetClassProcs(Tk_Window tkwin,
#	    TkClassProcs *procs, ClientData instanceData)
#}
declare 85 {
    void TkSetWindowMenuBar(Tcl_Interp *interp, Tk_Window tkwin,
	    char *oldMenuName, char *menuName)
}
declare 86 {
    KeySym TkStringToKeysym(char *name)
}
declare 87 {
    int TkThickPolyLineToArea(double *coordPtr, int numPoints,
	    double width, int capStyle, int joinStyle, double *rectPtr)
}
declare 88 {
    void TkWmAddToColormapWindows(TkWindow *winPtr)
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
declare 97 {
    void TkWmUnmapWindow(TkWindow *winPtr)
}

# new for 8.1

declare 98 {
    Tcl_Obj *TkDebugBitmap(Tk_Window tkwin, const char *name)
}
declare 99 {
    Tcl_Obj *TkDebugBorder(Tk_Window tkwin, const char *name)
}
declare 100 {
    Tcl_Obj *TkDebugCursor(Tk_Window tkwin, const char *name)
}
declare 101 {
    Tcl_Obj *TkDebugColor(Tk_Window tkwin, const char *name)
}
declare 102 {
    Tcl_Obj *TkDebugConfig(Tcl_Interp *interp, Tk_OptionTable table)
}
declare 103 {
    Tcl_Obj *TkDebugFont(Tk_Window tkwin, const char *name)
}
declare 104 {
    int TkFindStateNumObj(Tcl_Interp *interp, Tcl_Obj *optionPtr,
	    const TkStateMap *mapPtr, Tcl_Obj *keyPtr)
}
declare 105 {
    Tcl_HashTable *TkGetBitmapPredefTable(void)
}
declare 106 {
    TkDisplay *TkGetDisplayList(void)
}
declare 107 {
    TkMainInfo *TkGetMainInfoList(void)
}
declare 108 {
    int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, Tk_Window *windowPtr)
}
declare 109 {
    const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}
declare 111 {
    Tcl_Obj *TkpGetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    int XClipBox(Region rgn, XRectangle *rect_return)
}
declare 114 {
    Region XCreateRegion(void)
}
declare 115 {
    int XDestroyRegion(Region rgn)
}
declare 116 {
    int XIntersectRegion(Region sra, Region srcb, Region dr_return)
}
declare 117 {
    int XRectInRegion(Region rgn, int x, int y, unsigned int width,
	    unsigned int height)
}
declare 118 {
    int XSetRegion(Display *display, GC gc, Region rgn)
}
declare 119 {
    int XUnionRectWithRegion(XRectangle *rect,
	    Region src, Region dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}
declare 124 aqua {
    Pixmap TkpGetNativeAppBitmap(Display *display,
	    const char *name, int *width, int *height)







|


|


|


|





|



















|












|


|


|


|


|



|


|
|


|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
declare 97 {
    void TkWmUnmapWindow(TkWindow *winPtr)
}

# new for 8.1

declare 98 {
    Tcl_Obj *TkDebugBitmap(Tk_Window tkwin, char *name)
}
declare 99 {
    Tcl_Obj *TkDebugBorder(Tk_Window tkwin, char *name)
}
declare 100 {
    Tcl_Obj *TkDebugCursor(Tk_Window tkwin, char *name)
}
declare 101 {
    Tcl_Obj *TkDebugColor(Tk_Window tkwin, char *name)
}
declare 102 {
    Tcl_Obj *TkDebugConfig(Tcl_Interp *interp, Tk_OptionTable table)
}
declare 103 {
    Tcl_Obj *TkDebugFont(Tk_Window tkwin, char *name)
}
declare 104 {
    int TkFindStateNumObj(Tcl_Interp *interp, Tcl_Obj *optionPtr,
	    const TkStateMap *mapPtr, Tcl_Obj *keyPtr)
}
declare 105 {
    Tcl_HashTable *TkGetBitmapPredefTable(void)
}
declare 106 {
    TkDisplay *TkGetDisplayList(void)
}
declare 107 {
    TkMainInfo *TkGetMainInfoList(void)
}
declare 108 {
    int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, Tk_Window *windowPtr)
}
declare 109 {
    char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}
declare 111 {
    Tcl_Obj *TkpGetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    void TkClipBox(TkRegion rgn, XRectangle *rect_return)
}
declare 114 {
    TkRegion TkCreateRegion(void)
}
declare 115 {
    void TkDestroyRegion(TkRegion rgn)
}
declare 116 {
    void TkIntersectRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 117 {
    int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width,
	    unsigned int height)
}
declare 118 {
    void TkSetRegion(Display *display, GC gc, TkRegion rgn)
}
declare 119 {
    void TkUnionRectWithRegion(XRectangle *rect,
	    TkRegion src, TkRegion dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const char *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}
declare 124 aqua {
    Pixmap TkpGetNativeAppBitmap(Display *display,
	    const char *name, int *width, int *height)
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
declare 138 {
    KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr)
}
declare 139 {
    void TkpInitKeymapInfo(TkDisplay *dispPtr)
}
declare 140 {
    Region TkPhotoGetValidRegion(Tk_PhotoHandle handle)
}
declare 141 {
    TkWindow **TkWmStackorderToplevel(TkWindow *parentPtr)
}
declare 142 {
    void TkFocusFree(TkMainInfo *mainPtr)
}
declare 143 {
    void TkClipCleanup(TkDisplay *dispPtr)
}
declare 144 {
    void TkGCCleanup(TkDisplay *dispPtr)
}
declare 145 {
    int XSubtractRegion(Region sra, Region srcb, Region dr_return)
}
declare 146 {
    void TkStylePkgInit(TkMainInfo *mainPtr)
}
declare 147 {
    void TkStylePkgFree(TkMainInfo *mainPtr)
}







|














|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
declare 138 {
    KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr)
}
declare 139 {
    void TkpInitKeymapInfo(TkDisplay *dispPtr)
}
declare 140 {
    TkRegion TkPhotoGetValidRegion(Tk_PhotoHandle handle)
}
declare 141 {
    TkWindow **TkWmStackorderToplevel(TkWindow *parentPtr)
}
declare 142 {
    void TkFocusFree(TkMainInfo *mainPtr)
}
declare 143 {
    void TkClipCleanup(TkDisplay *dispPtr)
}
declare 144 {
    void TkGCCleanup(TkDisplay *dispPtr)
}
declare 145 {
    void TkSubtractRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 146 {
    void TkStylePkgInit(TkMainInfo *mainPtr)
}
declare 147 {
    void TkStylePkgFree(TkMainInfo *mainPtr)
}
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665



666
667
668
669
670
671
672
673
674
}
declare 154 {
    void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}

# entries needed only by tktest:
declare 156 {
    int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 157 {
    int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 158 {
    int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom selection, Atom target, Tk_GetSelProc *proc,
	    ClientData clientData)
}
declare 159 {
    int TkTextGetIndex(Tcl_Interp *interp, struct TkText *textPtr,
	    const char *string, struct TkTextIndex *indexPtr)
}
declare 160 {
    int TkTextIndexBackBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, int count,
	    struct TkTextIndex *dstPtr)
}
declare 161 {
    int TkTextIndexForwBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, int count,
	    struct TkTextIndex *dstPtr)
}
declare 162 {
    struct TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree,
	    const struct TkText *textPtr, int lineIndex,
	    int byteIndex, struct TkTextIndex *indexPtr)
}
declare 163 {
    TkSizeT TkTextPrintIndex(const struct TkText *textPtr,
	    const struct TkTextIndex *indexPtr, char *string)
}
declare 164 {
    struct TkTextSegment *TkTextSetMark(struct TkText *textPtr,
	    const char *name, struct TkTextIndex *indexPtr)
}
declare 165 {
    int TkTextXviewCmd(struct TkText *textPtr, Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[])
}
declare 166 {
    void TkTextChanged(struct TkSharedText *sharedTextPtr,
	    struct TkText *textPtr, const struct TkTextIndex *index1Ptr,
	    const struct TkTextIndex *index2Ptr)
}
declare 167 {
    int	TkBTreeNumLines(TkTextBTree tree,
	    const struct TkText *textPtr)
}
declare 168 {
    void TkTextInsertDisplayProc(struct TkText *textPtr,
	    struct TkTextDispChunk *chunkPtr, int x, int y,
	    int height, int baseline, Display *display,
	    Drawable dst, int screenY)
}
# Next group of functions exposed due to [Bug 2768945].

declare 169 {
    int TkStateParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 170 {
    const char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 171 {
    int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 172 {
    const char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 173 {
    int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 174 {
    const char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 175 {
    int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 176 {
    const char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 177 {
    int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 178 {
    const char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 179 {
    int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 180 {
    const char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}

# Angled text API, exposed for Emiliano Gavilán's RBC work.
declare 181 {
    void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y, double angle, int firstChar,
	    int lastChar)
}
declare 182 {
    void TkUnderlineAngledTextLayout(Display *display, Drawable drawable,
	    GC gc, Tk_TextLayout layout, int x, int y, double angle,
	    int underline)
}
declare 183 {
    int TkIntersectAngledTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height, double angle)
}
declare 184 {
    void TkDrawAngledChars(Display *display,Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, int numBytes, double x,
	    double y, double angle)
}

# Support for aqua's inability to draw outside [NSView drawRect:]
declare 185 macosx {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 186 macosx {
    int TkpWillDrawWidget(Tk_Window tkwin)
}

# Debugging / testing functions for photo images
declare 187 {
    int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
            Tcl_Obj *formatString, int *widthPtr, int *heightPtr)
}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.

interface tkIntPlat

################################
# Unix specific functions

declare 0 x11 {
    void TkCreateXEventSource(void)
}



declare 2 x11 {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 3 x11 {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 4 x11 {
    void TkpSync(Display *display)
}







|
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>


|


|
|



|


|
|



|


|
|



|


|
|



|


|
|



|


|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<

<














>
>
>

|







506
507
508
509
510
511
512
513
514
515
516
517
































518
519



520















521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570























571





572




573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
}
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)
}























declare 186 {





    void TkUnusedStubEntry(void)




}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.

interface tkIntPlat

################################
# Unix specific functions

declare 0 x11 {
    void TkCreateXEventSource(void)
}
declare 1 x11 {
    void TkFreeWindowId(TkDisplay *dispPtr, Window w)
}
declare 2 x11 {
    void TkInitXId(TkDisplay *dispPtr)
}
declare 3 x11 {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 4 x11 {
    void TkpSync(Display *display)
}
686
687
688
689
690
691
692



693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
}
declare 9 x11 {
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 10 x11 {
    void TkSendCleanup(TkDisplay *dispPtr)
}



declare 12 x11 {
    int TkpWmSetState(TkWindow *winPtr, int state)
}
# only needed by tktest:
declare 13 x11 {
    int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 38 x11 {
    int TkpCmapStressed_(Tk_Window tkwin, Colormap colormap)
}
declare 39 x11 {
    void TkpSync_(Display *display)
}
declare 40 x11 {
    Window TkUnixContainerId_(TkWindow *winPtr)
}
declare 41 x11 {
    int TkUnixDoOneXEvent_(Tcl_Time *timePtr)
}
declare 42 x11 {
    void TkUnixSetMenubar_(Tk_Window tkwin, Tk_Window menubar)
}
declare 43 x11 {
    void TkWmCleanup_(TkDisplay *dispPtr)
}
declare 44 x11 {
    void TkSendCleanup_(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 x11 {
    int TkpTestsendCmd_(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}

################################
# Windows specific functions

declare 0 win {
    char *TkAlignImageData(XImage *image, int alignment, int bitOrder)







>
>
>





|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627


























628
629
630
631
632
633
634
}
declare 9 x11 {
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 10 x11 {
    void TkSendCleanup(TkDisplay *dispPtr)
}
declare 11 x11 {
    void TkFreeXId(TkDisplay *dispPtr)
}
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

declare 0 win {
    char *TkAlignImageData(XImage *image, int alignment, int bitOrder)
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893






894
895

896
897
898
899
900
901
902
903
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 44 win {
    void TkSendCleanup(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 win {
    int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 47 win {
    Tk_Window TkpGetCapture(void)
}

################################
# Aqua specific functions

declare 0 aqua {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}






declare 2 aqua {
    void TkGenerateActivateEvents_(TkWindow *winPtr, int active)

}
declare 3 aqua {
    void TkPointerDeadWindow(TkWindow *winPtr)
}
declare 4 aqua {
    void TkpSetCapture(TkWindow *winPtr)
}
declare 5 aqua {







|
|
<
<
<








>
>
>
>
>
>
|
|
>
|







776
777
778
779
780
781
782
783
784



785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
    void TkWmCleanup(TkDisplay *dispPtr)
}
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

declare 0 aqua {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}

# removed duplicates from tkInt table
#declare 1 aqua {
#    Pixmap TkpCreateNativeBitmap(Display *display, const char *source)
#}
#
#declare 2 aqua {
#    void TkpDefineNativeBitmaps(void)
#}

declare 3 aqua {
    void TkPointerDeadWindow(TkWindow *winPtr)
}
declare 4 aqua {
    void TkpSetCapture(TkWindow *winPtr)
}
declare 5 aqua {
914
915
916
917
918
919
920
921
922
923
924

925
926
927






928
929
930






931
932
933
934
935
936
937
}
declare 9 aqua {
    void TkMacOSXClearMenubarActive(void)
}
declare 10 aqua {
    int TkMacOSXDispatchMenuEvent(int menuID, int index)
}
# Now a static function
# declare 11 aqua {
#     void TkMacOSXInstallCursor(int resizeOverride)
# }

declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}






declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}






declare 16 aqua {
    Window TkMacOSXGetXWindow(void *macWinPtr)
}
declare 17 aqua {
    int TkMacOSXGrowToplevel(void *whichWindow, XPoint start)
}
declare 18 aqua {







<
|
|
<
>



>
>
>
>
>
>



>
>
>
>
>
>







820
821
822
823
824
825
826

827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
}
declare 9 aqua {
    void TkMacOSXClearMenubarActive(void)
}
declare 10 aqua {
    int TkMacOSXDispatchMenuEvent(int menuID, int index)
}

declare 11 aqua {
    void TkMacOSXInstallCursor(int resizeOverride)

}
declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}

# removed duplicate from tkPlat table(tk.decls)
#declare 13 aqua {
#    void TkMacOSXInvalClipRgns(TkWindow *winPtr)
#}

declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}

# removed duplicate from tkPlat table(tk.decls)
#declare 15 aqua {
#    void *TkMacOSXGetDrawablePort(Drawable drawable)
#}

declare 16 aqua {
    Window TkMacOSXGetXWindow(void *macWinPtr)
}
declare 17 aqua {
    int TkMacOSXGrowToplevel(void *whichWindow, XPoint start)
}
declare 18 aqua {
959
960
961
962
963
964
965
966
967
968
969

970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009



1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043







1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
}
declare 24 aqua {
    void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
    void TkMacOSXMenuClick(void)
}
# The corresponding Unregister was not a stub, and this should be static.
#declare 26 aqua {
#    void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
#}

declare 27 aqua {
    int TkMacOSXResizable(TkWindow *winPtr)
}
declare 28 aqua {
    void TkMacOSXSetHelpMenuItemCount(void)
}
declare 29 aqua {
    void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag)
}
declare 30 aqua {
    void TkMacOSXSetUpClippingRgn(Drawable drawable)
}
declare 31 aqua {
    void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
    void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}
# This was not implemented.  Perhaps meant to be OffScreen ?
#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
#}

declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
    void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
    void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}
declare 38 aqua {
    int TkSetMacColor(unsigned long pixel, void *macColor)
}
declare 39 aqua {
    void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
}



declare 41 aqua {
    int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
declare 42 aqua {
    Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY,
	    int *newX, int *newY)
}
declare 43 aqua {
    MacDrawable *TkMacOSXContainerId(TkWindow *winPtr)
}
declare 44 aqua {
    MacDrawable *TkMacOSXGetHostToplevel(TkWindow *winPtr)
}
declare 45 aqua {
    void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkpGetCapture(void)
}
declare 49 aqua {
    Tk_Window TkMacOSXGetContainer(TkWindow *winPtr)
}
declare 50 aqua {
    int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
declare 52 aqua {
    void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag)
}







declare 53 aqua {
    unsigned long TkpGetMS(void)
}

# For Canvas3d, requested by Sean Woods
declare 54 aqua {
    void *TkMacOSXDrawable(Drawable drawable)
}
declare 55 aqua {
    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}







<
|
|
<
>


















<
|
|
<
>




|













>
>
>




















|


|










>
>
>
>
>
>
>



>







876
877
878
879
880
881
882

883
884

885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903

904
905

906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
}
declare 24 aqua {
    void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
    void TkMacOSXMenuClick(void)
}

declare 26 aqua {
    void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)

}
declare 27 aqua {
    int TkMacOSXResizable(TkWindow *winPtr)
}
declare 28 aqua {
    void TkMacOSXSetHelpMenuItemCount(void)
}
declare 29 aqua {
    void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag)
}
declare 30 aqua {
    void TkMacOSXSetUpClippingRgn(Drawable drawable)
}
declare 31 aqua {
    void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
    void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}

declare 33 aqua {
    void TkMacOSXUnregisterMacWindow(void *portPtr)

}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
    void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
    void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}
declare 38 aqua {
    int TkSetMacColor(unsigned long pixel, void *macColor)
}
declare 39 aqua {
    void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
}
declare 40 aqua {
    void TkSuspendClipboard(void)
}
declare 41 aqua {
    int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
declare 42 aqua {
    Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY,
	    int *newX, int *newY)
}
declare 43 aqua {
    MacDrawable *TkMacOSXContainerId(TkWindow *winPtr)
}
declare 44 aqua {
    MacDrawable *TkMacOSXGetHostToplevel(TkWindow *winPtr)
}
declare 45 aqua {
    void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkMacOSXGetCapture(void)
}
declare 49 aqua {
    Window TkGetTransientMaster(TkWindow *winPtr)
}
declare 50 aqua {
    int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
declare 52 aqua {
    void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag)
}

# removed duplicate from tkPlat table (tk.decls)
#declare 52 aqua {
#    void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y,
# 	    int width, int height, int flags)
#}

declare 53 aqua {
    unsigned long TkpGetMS(void)
}

# For Canvas3d, requested by Sean Woods
declare 54 aqua {
    void *TkMacOSXDrawable(Drawable drawable)
}
declare 55 aqua {
    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
	    unsigned int sw, unsigned int sh, int dx, int dy)
}
declare 106 win {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}

# New in Tk 8.6
declare 107 win {
    int XFlush(Display *display)
}
declare 108 win {
    int XGrabServer(Display *display)
}
declare 109 win {







|







1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
	    unsigned int sw, unsigned int sh, int dx, int dy)
}
declare 106 win {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}

# new for 8.4.20+/8.5.12+ Cygwin only
declare 107 win {
    int XFlush(Display *display)
}
declare 108 win {
    int XGrabServer(Display *display)
}
declare 109 win {
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
declare 113 win {
    int XSync(Display *display, Bool discard)
}
declare 114 win {
    VisualID XVisualIDFromVisual(Visual *visual)
}

# For tktreectrl
declare 120 win {
    int XOffsetRegion(Region rgn, int dx, int dy)
}
declare 121 win {
    int XUnionRegion(Region srca, Region srcb, Region dr_return)
}

# For 3dcanvas
declare 122 win {
    Window XCreateWindow(Display *display, Window parent, int x, int y,
	    unsigned int width, unsigned int height,
	    unsigned int border_width, int depth, unsigned int clazz,
	    Visual *visual, unsigned long value_mask,
	    XSetWindowAttributes *attributes)
}

# Various, e.g. for stub-enabled BLT
declare 129 win {
    int XLowerWindow(Display *d, Window w)
}
declare 130 win {
    int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 131 win {
    int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 132 win {
    int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
}
declare 133 win {
    int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n)
}
declare 134 win {
    int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y)
}
declare 135 win {
    int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m)
}
declare 136 win {
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 win {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 win {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 win {
    int XPointInRegion(Region rgn, int x, int y)
}
# For XIM
declare 140 win {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 win {
    char *XSetICValues(XIC xic, ...)
}
declare 142 win {
    char *XGetICValues(XIC xic, ...)
}
declare 143 win {
    void XSetICFocus(XIC xic)
}
declare 147 win {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 win {
    int XCloseIM(XIM im)
}
declare 149 win {
    Bool XRegisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 150 win {
    Bool XUnregisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 151 win {
    char *XSetLocaleModifiers(const char *modifier_list)
}
declare 152 win {
    XIM XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name,
	    char *res_class)
}
declare 153 win {
    char *XGetIMValues(XIM im, ...)
}
declare 154 win {
    char *XSetIMValues(XIM im, ...)
}
declare 155 win {
    XFontSet XCreateFontSet(Display *display, _Xconst char *base_font_name_list,
	    char ***missing_charset_list, int *missing_charset_count, char **def_string)
}
declare 156 win {
    void XFreeStringList(char **list)
}
declare 157 win {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 win {
    Display *XkbOpenDisplay(const char *name, int *ev_rtrn, int *err_rtrn,
	    int *major_rtrn, int *minor_rtrn, int *reason)

}

################################
# X functions for MacOSX

declare 0 macosx {
    int XSetDashes(Display *display, GC gc, int dash_offset,
	    _Xconst char *dash_list, int n)
}
declare 1 macosx {
    XModifierKeymap *XGetModifierMapping(Display *d)
}
declare 2 macosx {
    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)
}
declare 3 macosx {
    XImage *XGetImage(Display *d, Drawable dr, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)
}
declare 4 macosx {
    char *XGetAtomName(Display *d, Atom a)
}
declare 5 macosx {
    char *XKeysymToString(KeySym k)
}
declare 6 macosx {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 macosx {
    GContext XGContextFromGC(GC g)
}
# second parameter was of type KeyCode
declare 8 macosx {
    KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i)
}
declare 9 macosx {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 macosx {
    Window XRootWindow(Display *d, int i)
}
declare 11 macosx {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 macosx {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 macosx {
    int XBell(Display *d, int i)
}
declare 14 macosx {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 macosx {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 macosx {
    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 macosx {
    int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 18 macosx {
    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)
}
declare 19 macosx {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 macosx {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 macosx {
    int XDestroyWindow(Display *d, Window w)
}
declare 22 macosx {
    int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 23 macosx {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 macosx {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 macosx {
    int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 26 macosx {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 macosx {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 macosx {
    int XFreeColormap(Display *d, Colormap c)
}
declare 29 macosx {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 30 macosx {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 macosx {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 32 macosx {
    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)
}
declare 33 macosx {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 macosx {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 35 macosx {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 macosx {
    int XMapWindow(Display *d, Window w)
}
declare 37 macosx {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 macosx {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 macosx {
    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 40 macosx {
    int XRaiseWindow(Display *d, Window w)
}
declare 41 macosx {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 macosx {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 macosx {
    int XSelectInput(Display *d, Window w, long l)
}
declare 44 macosx {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 macosx {
    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 macosx {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 macosx {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 macosx {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 macosx {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 macosx {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 macosx {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 macosx {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 macosx {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 macosx {
    int XUngrabKeyboard(Display *d, Time t)
}
declare 55 macosx {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 macosx {
    int XUnmapWindow(Display *d, Window w)
}
declare 57 macosx {
    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)
}
declare 58 macosx {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 macosx {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 macosx {
    int XFreeGC(Display *display, GC gc)
}
declare 61 macosx {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 macosx {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 macosx {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 macosx {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 macosx {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 macosx {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 macosx {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 macosx {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 macosx {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 macosx {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 macosx {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 macosx {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 macosx {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 macosx {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 macosx {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 macosx {
    XIC XCreateIC(XIM xim, ...)
}
declare 77 macosx {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 macosx {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 macosx {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 macosx {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 macosx {
    int XForceScreenSaver(Display *display, int mode)
}
declare 82 macosx {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 macosx {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 macosx {
    int XClearWindow(Display *d, Window w)
}
declare 85 macosx {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 macosx {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 macosx {
    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)
}
declare 88 macosx {
    int XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 macosx {
    int XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 macosx {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 macosx {
    int XSync(Display *display, Bool discard)
}
declare 92 macosx {
    Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1,
	    int i2, int *i3, int *i4, Window *w3)
}
declare 93 macosx {
    int XDeleteProperty(Display *d, Window w, Atom a)
}
declare 94 macosx {
    int XFreeCursor(Display *d, Cursor c)
}
declare 95 macosx {
    int XGetInputFocus(Display *d, Window *w, int *i)
}
declare 96 macosx {
    int XmbLookupString(XIC xi, XKeyPressedEvent *xk, char *c, int i,
	    KeySym *k, Status *s)
}
declare 97 macosx {
    int XNextEvent(Display *d, XEvent *x)
}
declare 98 macosx {
    int XPutBackEvent(Display *d, XEvent *x)
}
declare 99 macosx {
    int XSetCommand(Display *d, Window w, char **c, int i)
}
declare 100 macosx {
    int XWindowEvent(Display *d, Window w, long l, XEvent *x)
}
declare 101 macosx {
    Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes *x)
}
declare 102 macosx {
    Status XGetWMColormapWindows(Display *d, Window w, Window **wpp, int *ip)
}
declare 103 macosx {
    Status XIconifyWindow(Display *d, Window w, int i)
}
declare 104 macosx {
    Status XWithdrawWindow(Display *d, Window w, int i)
}
declare 105 macosx {
    XHostAddress *XListHosts(Display *d, int *i, Bool *b)
}
declare 106 macosx {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 macosx {
    int XFlush(Display *display)
}
declare 108 macosx {
    int XGrabServer(Display *display)
}
declare 109 macosx {
    int XUngrabServer(Display *display)
}
declare 110 macosx {
    int XFree(void *data)
}
declare 111 macosx {
    int XNoOp(Display *display)
}
declare 112 macosx {
    XAfterFunction XSynchronize(Display *display, Bool onoff)
}
declare 113 macosx {
    Status XLookupColor(Display *d, Colormap c1, _Xconst char *c2,
	    XColor *x1, XColor *x2)
}
declare 114 macosx {
    VisualID XVisualIDFromVisual(Visual *visual)
}
declare 120 macosx {
    int XOffsetRegion(Region rgn, int dx, int dy)
}
declare 121 macosx {
    int XUnionRegion(Region srca, Region srcb, Region dr_return)
}
declare 122 macosx {
    Window XCreateWindow(Display *display, Window parent, int x, int y,
	    unsigned int width, unsigned int height,
	    unsigned int border_width, int depth, unsigned int clazz,
	    Visual *visual, unsigned long value_mask,
	    XSetWindowAttributes *attributes)
}
declare 129 macosx {
    int XLowerWindow(Display *d, Window w)
}
declare 130 macosx {
    int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 131 macosx {
    int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 132 macosx {
    int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
}
declare 136 macosx {
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 macosx {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 macosx {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 macosx {
    int XPointInRegion(Region rgn, int x, int y)
}
declare 140 macosx {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 macosx {
    char *XSetICValues(XIC xic, ...)
}
declare 142 macosx {
    char *XGetICValues(XIC xic, ...)
}
declare 143 macosx {
    void XSetICFocus(XIC xic)
}
declare 144 macosx {
    void XDestroyIC(XIC xic)
}
declare 145 macosx {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 146 macosx {
    Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
	    unsigned int ui1, unsigned int ui2, XColor _Xconst *x1,
	    XColor _Xconst *x2)
}
declare 147 macosx {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 macosx {
    int XCloseIM(XIM im)
}
declare 149 macosx {
    Bool XRegisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 150 macosx {
    Bool XUnregisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 151 macosx {
    char *XSetLocaleModifiers(const char *modifier_list)
}
declare 152 macosx {
    XIM XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name,
	    char *res_class)
}
declare 153 macosx {
    char *XGetIMValues(XIM im, ...)
}
declare 154 macosx {
    char *XSetIMValues(XIM im, ...)
}
declare 155 macosx {
    XFontSet XCreateFontSet(Display *display, _Xconst char *base_font_name_list,
	    char ***missing_charset_list, int *missing_charset_count, char **def_string)
}
declare 156 macosx {
    void XFreeStringList(char **list)
}
declare 157 macosx {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 macosx {
    Display *XkbOpenDisplay(const char *name, int *ev_rtrn, int *err_rtrn,
	    int *major_rtrn, int *minor_rtrn, int *reason)
}

# Local Variables:
# mode: tcl
# End:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
>



|

|



|


|




|



|


|


|


|


<
|
|

|


|


|


|


|


|
|


|
|


|
|


|
|


|
|



|



|


|
|

|
|


|


|
|


|
|


|
|


|


|


|



|


|




|




|


|



|


|
|

|
|


|
|

|



|
|

|
|

|
|


|
|

|


|
|

|
|

|


|
|

|
|

|
|

|
|

|
|

|
|

|
|

|


|
|

|




|



|



|


|



|


|


|


|



|



|


|


|


|


|


|


|


|



|


|
|

|



|



|



|



|
|

|



|



|
|

|


|



|




|
|

|
|


|



|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<





1381
1382
1383
1384
1385
1386
1387






























1388
1389
1390
1391
1392
1393
1394
1395
1396
































































1397


1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722


















































































































































1723





















1724







1725
1726
1727
1728
1729
declare 113 win {
    int XSync(Display *display, Bool discard)
}
declare 114 win {
    VisualID XVisualIDFromVisual(Visual *visual)
}































declare 133 win {
    int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n)
}
declare 134 win {
    int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y)
}
declare 135 win {
    int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m)
}
































































declare 158 win {


    void TkUnusedStubEntry(void)
}

################################
# X functions for Aqua

declare 0 aqua {
    int XSetDashes(Display *display, GC gc, int dash_offset,
	    _Xconst char *dash_list, int n)
}
declare 1 aqua {
    XModifierKeymap *XGetModifierMapping(Display *d)
}
declare 2 aqua {
    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)
}
declare 3 aqua {
    XImage *XGetImage(Display *d, Drawable dr, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)
}
declare 4 aqua {
    char *XGetAtomName(Display *d, Atom a)
}
declare 5 aqua {
    char *XKeysymToString(KeySym k)
}
declare 6 aqua {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 aqua {
    GContext XGContextFromGC(GC g)
}

declare 8 aqua {
    KeySym XKeycodeToKeysym(Display *d, KeyCode k, int i)
}
declare 9 aqua {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 aqua {
    Window XRootWindow(Display *d, int i)
}
declare 11 aqua {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 aqua {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 aqua {
    int XBell(Display *d, int i)
}
declare 14 aqua {
    void XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 aqua {
    void XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 aqua {
    void XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 aqua {
    void XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 18 aqua {
    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)
}
declare 19 aqua {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 aqua {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 aqua {
    void XDestroyWindow(Display *d, Window w)
}
declare 22 aqua {
    void XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 23 aqua {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 aqua {
    void XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 aqua {
    void XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 26 aqua {
    void XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 aqua {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 aqua {
    int XFreeColormap(Display *d, Colormap c)
}
declare 29 aqua {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 30 aqua {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 aqua {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 32 aqua {
    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)
}
declare 33 aqua {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 aqua {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 35 aqua {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 aqua {
    void XMapWindow(Display *d, Window w)
}
declare 37 aqua {
    void XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 aqua {
    void XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 aqua {
    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 40 aqua {
    void XRaiseWindow(Display *d, Window w)
}
declare 41 aqua {
    void XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 aqua {
    void XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 aqua {
    void XSelectInput(Display *d, Window w, long l)
}
declare 44 aqua {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 aqua {
    void XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 aqua {
    void XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 aqua {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 aqua {
    void XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 aqua {
    void XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 aqua {
    void XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 aqua {
    void XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 aqua {
    void XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 aqua {
    void XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 aqua {
    void XUngrabKeyboard(Display *d, Time t)
}
declare 55 aqua {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 aqua {
    void XUnmapWindow(Display *d, Window w)
}
declare 57 aqua {
    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)
}
declare 58 aqua {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 aqua {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 aqua {
    int XFreeGC(Display *display, GC gc)
}
declare 61 aqua {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 aqua {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 aqua {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 aqua {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 aqua {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 aqua {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 aqua {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 aqua {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 aqua {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 aqua {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 aqua {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 aqua {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 aqua {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 aqua {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 aqua {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 aqua {
    XIC XCreateIC(void)
}
declare 77 aqua {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 aqua {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 aqua {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 aqua {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 aqua {
    void XForceScreenSaver(Display *display, int mode)
}
declare 82 aqua {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 aqua {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 aqua {
    void XClearWindow(Display *d, Window w)
}
declare 85 aqua {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 aqua {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 aqua {
    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)
}
declare 88 aqua {
    void XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 aqua {
    void XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 aqua {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 aqua {
    int XSync(Display *display, Bool discard)
}


















































































































































declare 158 aqua {





















    void TkUnusedStubEntry(void)







}

# Local Variables:
# mode: tcl
# End:

Changes to generic/tkInt.h.

11
12
13
14
15
16
17






18
19
20
21
22
23
24
25
26
27
28
29
30
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINT
#define _TKINT







#ifndef _TKPORT
#include "tkPort.h"
#endif

/*
 * Ensure WORDS_BIGENDIAN is defined correctly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */

#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif







>
>
>
>
>
>





|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINT
#define _TKINT

#ifndef _TK
#include "tk.h"
#endif
#ifndef _TCL
#include "tcl.h"
#endif
#ifndef _TKPORT
#include "tkPort.h"
#endif

/*
 * Ensure WORDS_BIGENDIAN is defined correcly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */

#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   endif
#endif

#ifndef JOIN
#  define JOIN(a,b) JOIN1(a,b)
#  define JOIN1(a,b) a##b
#endif

#ifndef TCL_UNUSED
#   if defined(__cplusplus)
#	define TCL_UNUSED(T) T
#   elif defined(__GNUC__) && (__GNUC__ > 2)
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused))
#   else
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__)
#   endif
#endif

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_Char16ToUtfDString Tcl_UniCharToUtfDString
# define Tcl_UtfToChar16DString Tcl_UtfToUniCharDString
#endif

#if defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#endif

#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#   define Tcl_GetParent Tcl_GetMaster
#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) ((intptr_t)(p))
#   else
#	define INT2PTR(p) ((void*)(p))
#	define PTR2INT(p) ((long)(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) ((uintptr_t)(p))
#   else
#	define UINT2PTR(p) ((void*)(p))
#	define PTR2UINT(p) ((unsigned long)(p))
#   endif
#endif

#ifndef TCL_Z_MODIFIER
#   if defined(_WIN64)
#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
#	define TCL_Z_MODIFIER	"z"
#   else
#	define TCL_Z_MODIFIER	""
#   endif
#endif /* !TCL_Z_MODIFIER */

/*
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
typedef struct TkGrabEvent TkGrabEvent;
typedef struct TkpCursor_ *TkpCursor;
#define TkRegion Region
typedef struct TkStressedCmap TkStressedCmap;
typedef struct TkBindInfo_ *TkBindInfo;
typedef struct Busy *TkBusy;








/*
 * 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 {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    TkSizeT 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. */
    TkSizeT 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). */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|


|





|


|



<
<
<
<
<
<
<
<
<
<








|


|
>
>
>
>
>
>
>



|







|








|







60
61
62
63
64
65
66








































67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91










92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   endif
#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;
typedef struct TkStressedCmap TkStressedCmap;
typedef struct TkBindInfo_ *TkBindInfo;

/*
 * Function types.
 */

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.
 */

typedef struct TkCursor {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    int resourceRefCount;	/* Number of active uses of this cursor (each
				 * active use corresponds to a call to
				 * Tk_AllocPreserveFromObj or Tk_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). */
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

/*
 * 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 enum TkLockUsage {LU_IGNORE, LU_CAPS, LU_SHIFT} TkLockUsage;

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. */
    Time lastEventTime;		/* Time of last event received for this
				 * display. */







<
<







159
160
161
162
163
164
165


166
167
168
169
170
171
172

/*
 * 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. */
    Time lastEventTime;		/* Time of last event received for this
				 * display. */
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
				 * 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. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    TkLockUsage lockUsage;
				/* 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. */







|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
				 * 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. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * 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. */
    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. */
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
     * 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. */
    TkSizeT 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:
     */







|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
     * 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. */

    /*
     * Used by tkEvent.c only:
     */
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
				 * initializing. */

    /*
     * Information used by tkGeometry.c only:
     */

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a container's
				 * Tk_Window token to a list of windows managed
				 * by that container. */
    int geomInit;

#define TkGetContainer(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \
    ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr)

    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
    int uidInit;		/* 0 means uidTable needs initializing. */








|
|
|


<
<
<







326
327
328
329
330
331
332
333
334
335
336
337



338
339
340
341
342
343
344
				 * initializing. */

    /*
     * Information used by tkGeometry.c only:
     */

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a master's
				 * Tk_Window token to a list of slaves managed
				 * by that master. */
    int geomInit;




    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
    int uidInit;		/* 0 means uidTable needs initializing. */

434
435
436
437
438
439
440




441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

    /*
     * Information used by tkMacWinMenu.c only:
     */

    int postCommandGeneration;





    /*
     * Information used by tkPack.c only.
     */

    int packInit;		/* 0 means table below needs initializing. */
    Tcl_HashTable packerHashTable;
				/* Maps from Tk_Window tokens to corresponding
				 * Packer structures. */

    /*
     * Information used by tkPlace.c only.
     */

    int placeInit;		/* 0 means tables below need initializing. */
    Tcl_HashTable containerTable;	/* Maps from Tk_Window token to the Container
				 * structure for the window, if it exists. */
    Tcl_HashTable contentTable;	/* Maps from Tk_Window token to the Content
				 * structure for the window, if it exists. */

    /*
     * Information used by tkSelect.c and tkClipboard.c only:
     */

    struct TkSelectionInfo *selectionInfoPtr;







>
>
>
>














|

|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

    /*
     * Information used by tkMacWinMenu.c only:
     */

    int postCommandGeneration;

    /*
     * Information used by tkOption.c only.
     */

    /*
     * Information used by tkPack.c only.
     */

    int packInit;		/* 0 means table below needs initializing. */
    Tcl_HashTable packerHashTable;
				/* Maps from Tk_Window tokens to corresponding
				 * Packer structures. */

    /*
     * Information used by tkPlace.c only.
     */

    int placeInit;		/* 0 means tables below need initializing. */
    Tcl_HashTable masterTable;	/* Maps from Tk_Window toke to the Master
				 * structure for the window, if it exists. */
    Tcl_HashTable slaveTable;	/* Maps from Tk_Window toke to the Slave
				 * structure for the window, if it exists. */

    /*
     * Information used by tkSelect.c and tkClipboard.c only:
     */

    struct TkSelectionInfo *selectionInfoPtr;
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
    Atom timestampAtom;		/* Atom for TIMESTAMP. */
    Atom textAtom;		/* Atom for TEXT. */
    Atom compoundTextAtom;	/* Atom for COMPOUND_TEXT. */
    Atom applicationAtom;	/* Atom for TK_APPLICATION. */
    Atom windowAtom;		/* Atom for TK_WINDOW. */
    Atom clipboardAtom;		/* Atom for CLIPBOARD. */
    Atom utf8Atom;		/* Atom for UTF8_STRING. */
    Atom atomPairAtom;          /* Atom for ATOM_PAIR. */

    Tk_Window clipWindow;	/* Window used for clipboard ownership and to
				 * retrieve selections between processes. NULL
				 * means clipboard info hasn't been
				 * initialized. */
    int clipboardActive;	/* 1 means we currently own the clipboard
				 * selection, 0 means we don't. */







<







435
436
437
438
439
440
441

442
443
444
445
446
447
448
    Atom timestampAtom;		/* Atom for TIMESTAMP. */
    Atom textAtom;		/* Atom for TEXT. */
    Atom compoundTextAtom;	/* Atom for COMPOUND_TEXT. */
    Atom applicationAtom;	/* Atom for TK_APPLICATION. */
    Atom windowAtom;		/* Atom for TK_WINDOW. */
    Atom clipboardAtom;		/* Atom for CLIPBOARD. */
    Atom utf8Atom;		/* Atom for UTF8_STRING. */


    Tk_Window clipWindow;	/* Window used for clipboard ownership and to
				 * retrieve selections between processes. NULL
				 * means clipboard info hasn't been
				 * initialized. */
    int clipboardActive;	/* 1 means we currently own the clipboard
				 * selection, 0 means we don't. */
503
504
505
506
507
508
509


















510
511
512
513
514
515
516
517












518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588


589
590
591
592
593


594
595
596
597
598
599
600
				 * yet. */
    Atom commProperty;		/* X's name for comm property. */
    Atom registryProperty;	/* X's name for property containing registry
				 * of interpreter names. */
    Atom appNameProperty;	/* X's name for property used to hold the
				 * application name on each comm window. */



















    /*
     * Information used by tkUnixWm.c and tkWinWm.c only:
     */

    struct TkWmInfo *firstWmPtr;/* Points to first top-level window. */
    struct TkWmInfo *foregroundWmPtr;
				/* Points to the foreground window. */













    /*
     * Information used by tkVisual.c only:
     */

    TkColormap *cmapPtr;	/* First in list of all non-default colormaps
				 * allocated for this display. */

    /*
     * Miscellaneous information:
     */

#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    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 /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    TkSizeT 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. */

    /*
     * The following field were all added for Tk8.3
     */

#if TCL_MAJOR_VERSION < 9
#if !defined(TK_NO_DEPRECATED)
    int mouseButtonState;	/* Current mouse button state for this
				 * display. NOT USED as of 8.6.10 */
    Window mouseButtonWindow;	/* Window the button state was set in, added
				 * in Tk 8.4. */
#else
    int notused1;
    XID notused2;
#endif /* !TK_NO_DEPRECATED */
#endif
    Tk_Window warpWindow;
    Tk_Window warpMainwin;	/* For finding the root window for warping
				 * purposes. */
    int warpX;
    int warpY;

    /*
     * 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. */
    int ximGeneration;          /* Used to invalidate XIC */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    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 /* TK_USE_INPUT_METHODS */
} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	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_WM_TRACING:		(default off)
 *	Whether we should do wm tracing on this display.


 */

#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS	(1 << 0)
#define TK_DISPLAY_USE_IM			(1 << 1)
#define TK_DISPLAY_WM_TRACING			(1 << 3)



/*
 * 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 {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>











|






|








<
<

|


<
<
<
<
<
|
<
<














<
<
<
<
<
<










>
>





>
>







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535


536
537
538
539





540


541
542
543
544
545
546
547
548
549
550
551
552
553
554






555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
				 * yet. */
    Atom commProperty;		/* X's name for comm property. */
    Atom registryProperty;	/* X's name for property containing registry
				 * of interpreter names. */
    Atom appNameProperty;	/* X's name for property used to hold the
				 * application name on each comm window. */

    /*
     * Information used by tkXId.c only:
     */

    struct TkIdStack *idStackPtr;
				/* First in list of chunks of free resource
				 * identifiers, or NULL if there are no free
				 * resources. */
    XID (*defaultAllocProc) (Display *display);
				/* Default resource allocator for display. */
    struct TkIdStack *windowStackPtr;
				/* 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
				 * hasn't. */

    /*
     * 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. */

    /*
     * Information maintained by tkWindow.c for use later on by tkXId.c:
     */

    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
				 * server has seen this request and event
				 * queue is empty. */

    /*
     * Information used by tkVisual.c only:
     */

    TkColormap *cmapPtr;	/* First in list of all non-default colormaps
				 * allocated for this display. */

    /*
     * Miscellaneous information:
     */

#ifdef TK_USE_INPUT_METHODS
    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 /* 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. */

    /*
     * 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. */





    Window warpWindow;


    int warpX;
    int warpY;

    /*
     * 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. */






} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	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_WM_TRACING:		(default off)
 *	Whether we should do wm tracing on this display.
 *  TK_DISPLAY_IN_WARP:			(default off)
 *	Indicates that we are in a pointer warp
 */

#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS	(1 << 0)
#define TK_DISPLAY_USE_IM			(1 << 1)
#define TK_DISPLAY_WM_TRACING			(1 << 3)
#define TK_DISPLAY_IN_WARP			(1 << 4)
#define TK_DISPLAY_USE_XKB			(1 << 5)

/*
 * 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 {
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
/*
 * 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 {
    TkSizeT 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). */
    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. */
#if TCL_MAJOR_VERSION > 8
    size_t deletionEpoch;		/* Incremented by window deletions. */
#else
    long deletionEpoch;
#endif
    Tk_BindingTable bindingTable;
				/* 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;
				/* Information used by tkFont.c on a per







|










<
|
<
<
<







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636

637



638
639
640
641
642
643
644
/*
 * 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). */
    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. */



    Tk_BindingTable bindingTable;
				/* 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;
				/* Information used by tkFont.c on a per
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
				 * 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. */
    Tcl_HashTable imageTable;	/* Maps from image names to Tk_ImageModel
				 * 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
				 * this process. */
    Tcl_HashTable busyTable;	/* Information used by [tk busy] command. */
} 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.
 */

typedef struct {
    const void *source;		/* Bits for bitmap. */
    int width, height;		/* Dimensions of 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







|







<









|







658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
				 * 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. */
    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. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */

} 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.
 */

typedef struct {
    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. */
} TkPredefBitmap;

/*
 * Tk keeps one of the following structures for each window. Some of the
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
    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. None 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







|







704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
    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
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

    /*
     * Information kept by the event manager (tkEvent.c):
     */

    TkEventHandler *handlerList;/* First in list of event handlers declared
				 * for this window, or NULL if none. */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC inputContext;		/* XIM input context. */
#endif /* TK_USE_INPUT_METHODS */

    /*
     * Information used for event bindings (see "bind" and "bindtags" commands
     * in tkCmds.c):
     */







|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

    /*
     * Information kept by the event manager (tkEvent.c):
     */

    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):
     */
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971






972
973
974
975
976
977
978
				/* First in list of handlers for returning the
				 * selection in various forms. */

    /*
     * Information used by tkGeometry.c for geometry management.
     */

    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. */

    /*
     * 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. */

    /*
     * Information used by widget classes.
     */

    const Tk_ClassProcs *classProcsPtr;
    ClientData instanceData;

    /*
     * Platform specific information private to each port.
     */

    struct TkWindowPrivate *privatePtr;

    /*
     * More information used by tkGeometry.c for geometry management.
     */

    /* The remaining fields of internal border. */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
    char *geomMgrName;          /* Records the name of the geometry manager. */
    struct TkWindow *maintainerPtr;
				/* The geometry container for this window. The
				 * value is NULL if the window has no container or
				 * if its container is its parent. */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC inputContext;		/* XIM input context. */
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;

/*
 * 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. */
#ifdef _WIN32
    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#elif !defined(MAC_OSC_TK)
    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(). */
    TkSizeT charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
#endif
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
 */

#define TK_MAKE_MENU_TEAROFF	0	/* Only non-transient case. */
#define TK_MAKE_MENU_POPUP	1
#define TK_MAKE_MENU_DROPDOWN	2

/* See TIP #494 */
#ifndef TCL_IO_FAILURE
#   define TCL_IO_FAILURE (-1)
#endif
/* See TIP #537 */
#ifndef TCL_INDEX_NONE
#   define TCL_INDEX_NONE (-1)
#endif

/*
 * The following structure is used with TkMakeEnsemble to create ensemble
 * commands and optionally to create sub-ensembles.
 */

typedef struct TkEnsemble {
    const char *name;
    Tcl_ObjCmdProc *proc;
    const struct TkEnsemble *subensemble;
} TkEnsemble;

/*
 * 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. */
    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.
 */

typedef struct TkpClipMask {
    int type;			/* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */
    union {
	Pixmap pixmap;
	Region region;
    } value;
} TkpClipMask;

#define TKP_CLIP_PIXMAP 0
#define TKP_CLIP_REGION 1







/*
 * Return values from TkGrabState:
 */

#define TK_GRAB_NONE		0
#define TK_GRAB_IN_TREE		1
#define TK_GRAB_ANCESTOR	2







|
<


















|
<





|



















<
<
<
<
<
<
<
<
<
<
<
<









<
<
<
<
<





|



<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|






>
>
>
>
>
>







800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851












852
853
854
855
856
857
858
859
860





861
862
863
864
865
866
867
868
869

870
871




























872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
				/* First in list of handlers for returning the
				 * selection in various forms. */

    /*
     * Information used by tkGeometry.c for geometry management.
     */

    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. */

    /*
     * 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. */


    /*
     * Information used by widget classes.
     */

    Tk_ClassProcs *classProcsPtr;
    ClientData instanceData;

    /*
     * Platform specific information private to each port.
     */

    struct TkWindowPrivate *privatePtr;

    /*
     * More information used by tkGeometry.c for geometry management.
     */

    /* The remaining fields of internal border. */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */












} TkWindow;

/*
 * 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. */
    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.
 */

typedef struct TkpClipMask {
    int type;			/* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */
    union {
	Pixmap pixmap;
	TkRegion region;
    } value;
} TkpClipMask;

#define TKP_CLIP_PIXMAP 0
#define TKP_CLIP_REGION 1

/*
 * Pointer to first entry in list of all displays currently known.
 */

extern TkDisplay *tkDisplayList;

/*
 * Return values from TkGrabState:
 */

#define TK_GRAB_NONE		0
#define TK_GRAB_IN_TREE		1
#define TK_GRAB_ANCESTOR	2
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167



1168
1169
1170
1171
1172
1173
1174
 * 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)

/*
 * Buttons 8 and 9 are the Xbuttons (left and right side-buttons). On Windows/Mac, those
 * are known as Buttons 4 and 5. At script level, they also get the numbers 4 and 5.
 */

#ifndef Button8
# define Button8 8
#endif
#ifndef Button9
# define Button9 9
#endif

#ifndef Button6Mask
# define Button6Mask (1<<13)
#endif
#ifndef Button7Mask
# define Button7Mask (1<<14)
#endif
#ifndef Button8Mask
# define Button8Mask (AnyModifier<<4)
#endif
#ifndef Button9Mask
# define Button9Mask (AnyModifier<<5)
#endif

/*
 * Mask that selects any of the state bits corresponding to buttons, plus
 * masks that select individual buttons' bits:
 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask \
		|Button6Mask|Button7Mask|Button8Mask|Button9Mask)


/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;
MODULE_SCOPE const Tcl_ObjType tkBitmapObjType;
MODULE_SCOPE const Tcl_ObjType tkColorObjType;
MODULE_SCOPE const Tcl_ObjType tkCursorObjType;
MODULE_SCOPE const Tcl_ObjType tkFontObjType;

MODULE_SCOPE const Tcl_ObjType tkStateKeyObjType;
MODULE_SCOPE const Tcl_ObjType tkTextIndexType;

/*
 * Miscellaneous variables shared among Tk modules but not exported to the
 * outside world:
 */

MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType	tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
MODULE_SCOPE void		(*tkHandleEventProc) (XEvent* eventPtr);
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtSVGnano;
MODULE_SCOPE TkMainInfo		*tkMainWindowList;
MODULE_SCOPE Tk_ImageType	tkPhotoImageType;
MODULE_SCOPE Tcl_HashTable	tkPredefBitmapTable;

MODULE_SCOPE const char *const tkWebColors[20];

/*
 * The definition of pi, at least from the perspective of double-precision
 * floats.
 */

#ifndef PI
#ifdef M_PI
#define PI	M_PI
#else
#define PI	3.14159265358979323846
#endif
#endif

/*
 * Support for Clang Static Analyzer <http://clang-analyzer.llvm.org>
 */

#if defined(PURIFY) && defined(__clang__)
#if __has_feature(attribute_analyzer_noreturn) && \
	!defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED)
void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
#endif
#if !defined(CLANG_ASSERT)
#define CLANG_ASSERT(x) assert(x)
#endif
#elif !defined(CLANG_ASSERT)
#define CLANG_ASSERT(x)
#endif /* PURIFY && __clang__ */

/*
 * The following magic value is stored in the "send_event" field of FocusIn
 * and FocusOut events. This allows us to separate "real" events coming from
 * the server from those that we generated.
 */

#define GENERATED_FOCUS_EVENT_MAGIC	((Bool) 0x547321ac)

/*
 * Exported internals.
 */

#include "tkIntDecls.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * 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:
 */

MODULE_SCOPE int	Tk_BellObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindtagsObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BusyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    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[]);
MODULE_SCOPE int	Tk_CheckbuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ClipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseColorObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseDirectoryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,



			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_DestroyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_EntryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
|
|
|
|
>
|
|






|



<
<

<




|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<




















<
<
<

















>
>
>







939
940
941
942
943
944
945
946
947



































948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969


970

971
972
973
974
975
976









































977
978




979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998



999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
 * 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:
 */

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:
 */

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;

MODULE_SCOPE CONST char *const tkWebColors[20];










































#include "tkIntDecls.h"





/*
 * 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:
 */

MODULE_SCOPE int	Tk_BellObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindtagsObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    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[]);
MODULE_SCOPE int	Tk_CheckbuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ClipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseColorObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseDirectoryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseFontObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_DestroyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_EntryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ListboxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_LowerObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MenuObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MenubuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageBoxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageObjCmd(ClientData clientData,







<
<
<







1058
1059
1060
1061
1062
1063
1064



1065
1066
1067
1068
1069
1070
1071
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ListboxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_LowerObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



MODULE_SCOPE int	Tk_MenubuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageBoxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageObjCmd(ClientData clientData,
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263



1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
			    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_ScrollbarObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SelectionObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SendObjCmd(ClientData clientData,
			    Tcl_Interp *interp,int objc,
			    Tcl_Obj *const objv[]);
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_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[]);

MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);
MODULE_SCOPE void	TkFreeGeometryContainer(Tk_Window tkwin,
			    const char *name);

MODULE_SCOPE void	TkEventInit(void);
MODULE_SCOPE void	TkRegisterObjTypes(void);

MODULE_SCOPE int	TkDeadAppObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]);
MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
			    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);
#if TCL_MAJOR_VERSION > 8
MODULE_SCOPE int TkCanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
    Tk_Window tkwin, const char *value, char *widgRec, size_t offset);
MODULE_SCOPE const char *TkCanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
    char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
#define TkCanvasTagsParseProc Tk_CanvasTagsParseProc
#define TkCanvasTagsPrintProc Tk_CanvasTagsPrintProc
#endif
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(Region region,
			    unsigned x, unsigned y, unsigned width,
			    unsigned height, unsigned char *dataPtr,
			    unsigned pixelStride, unsigned lineStride);
MODULE_SCOPE void	TkAppendPadAmount(Tcl_Obj *bufferObj,
			    const char *buffer, int pad1, int pad2);
MODULE_SCOPE int	TkParsePadAmount(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void       TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void       TkFocusJoin(TkWindow *winPtr);

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 void	TkpDrawAngledCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, double x, double y, double angle);
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,
			    int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpDrawFrameEx(Tk_Window tkwin, Drawable drawable,
			    Tk_3DBorder border, int highlightWidth,
			    int borderWidth, int relief);
MODULE_SCOPE void	TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpHideBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpMakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
MODULE_SCOPE void	TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
			    Window *parentPtr, Tk_Window tkParent,
			    TkBusy busy);
MODULE_SCOPE int	TkBackgroundEvalObjv(Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv, int flags);
MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
			    const char *nsname, const char *name,
			    ClientData clientData, const TkEnsemble *map);
MODULE_SCOPE int	TkInitTkCmd(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE void	TkInitEmbeddedConfigurationInformation(
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkDoWarpWrtWin(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);
MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);
MODULE_SCOPE void	TkRotatePoint(double originX, double originY,
			    double sine, double cosine, double *xPtr,
			    double *yPtr);
MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, TkSizeT, int lastOK, TkSizeT*);

#define TkNewIndexObj(value) Tcl_NewWideIntObj((Tcl_WideInt)(value + 1) - 1)

#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);
#endif
#if !defined(_WIN32) && !defined(__CYGWIN__) /* UNIX and MacOSX */
#undef TkPutImage
#define TkPutImage(colors, ncolors, display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
	XPutImage(display, pixels, gc, image, srcx, srcy, destx, desty, width, height);
#else
#undef XPutImage
#define XPutImage(display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
	TkPutImage(NULL, 0, display, pixels, gc, image, srcx, srcy, destx, desty, width, height);
#endif

/*
 * These macros are just wrappers for the equivalent X Region calls.
 */
#define TkClipBox XClipBox
#define TkCreateRegion XCreateRegion
#define TkDestroyRegion XDestroyRegion
#define TkIntersectRegion XIntersectRegion
#define TkRectInRegion XRectInRegion
#define TkSetRegion XSetRegion
#define TkSubtractRegion XSubtractRegion
#define TkUnionRectWithRegion XUnionRectWithRegion

#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(Region clipRegion);
#endif

#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif

#if TCL_UTF_MAX > 4
#   define TkUtfToUniChar(src, ch) (size_t)(((int (*)(const char *, int *))Tcl_UtfToUniChar)(src, ch))
#   define TkUniCharToUtf(ch, src) (size_t)(((int (*)(int, char *))Tcl_UniCharToUtf)(ch, src))
#   define TkUtfPrev Tcl_UtfPrev
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);
#endif

#if TCL_MAJOR_VERSION > 8
#define TkGetStringFromObj(objPtr, lenPtr) \
	(((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
	*(lenPtr) = (objPtr)->length, (objPtr)->bytes)
MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
	size_t *lengthPtr);
#else
#define TkGetStringFromObj Tcl_GetStringFromObj
#define TkGetByteArrayFromObj Tcl_GetByteArrayFromObj
#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);

/*
 * For Tktest.
 */
MODULE_SCOPE int SquareObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
MODULE_SCOPE int	TkOldTestInit(Tcl_Interp *interp);
#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#define TkplatformtestInit(x) TCL_OK
#else
MODULE_SCOPE int	TkplatformtestInit(Tcl_Interp *interp);
#endif

#ifdef __cplusplus
}
#endif

#endif /* _TKINT */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|
<



|
|
<








>
>
>
















|
|
<
|



>
|
|








<
<
<
<
<
<
<
<
<








|



|
|





>




<
<
<
<









|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|







1088
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145









1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169




1170
1171
1172
1173
1174
1175
1176
1177
1178
1179

































1180
1181
1182
1183
1184
1185
1186






















1187
1188

























1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

















1199
1200
1201
1202
1203
1204
1205
1206
1207
			    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[]);

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);
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);
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
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, CONST char* spec,
				XColor * colorPtr);
#endif






















#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(TkRegion clipRegion);

























#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);


















#endif /* _TKINT */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkIntDecls.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


48
49
50



51
52
53



54
55
56
57



58




59
60



61
62



63
64



65
66
67



68
69



70
71
72
73



74




75









76
77
78
79
80



81
82
83
84
85



86
87
88



89
90



91
92



93
94



95
96
97



98
99



100
101
102
103



104
105
106
107



108
109
110



111
112



113
114
115



116
117



118
119



120
121



122
123



124
125



126
127
128
129

130

131
132
133
134



135
136
137



138
139
140



141
142



143
144
145



146
147



148
149



150
151
152
153



154
155
156



157
158



159
160



161
162



163
164



165
166
167
168



169
170



171
172



173
174
175



176
177
178



179
180
181
182



183
184
185
186



187
188



189
190



191
192



193
194
195



196
197



198
199



200
201



202
203



204
205



206
207



208
209



210
211



212
213
214



215
216



217
218



219
220



221
222
223



224
225



226
227



228
229
230



231
232
233



234
235



236
237
238



239
240
241



242
243
244



245





246
247
248



249
250
251
252
253
254
255



256
257
258
259



260
261



262
263



264
265



266
267

268


269
270
271
272



273
274



275
276
277
278



279
280



281
282



283
284



285
286



287
288



289
290
291



292
293



294
295
296



297
298



299
300



301
302



303
304



305
306



307
308



309
310
311



312
313



314
315
316
317



318
319



320
321



322
323



324
325
326
327



328
329
330



331
332



333
334
335



336
337



338
339



340
341



342
343



344
345
346



347
348
349



350
351



352
353
354

355
356


357
358
359

360
361


362
363

364
365
366


367
368
369

370
371
372
373
374
375
376
377
378
379
380


381
382
383
384



385
386



387
388
389



390
391



392
393



394
395



396
397



398
399



400
401



402
403



404
405
406



407
408



409
410



411
412
413



414
415
416



417
418
419
420



421
422
423
424



425
426
427
428



429
430
431



432
433
434

435


436
437
438
439



440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487


488
489
490
491

492

493
494
495
496



497
498
499
500
501


502
503
504
505



506
507
508
509

510

511
512
513
514



515
516
517
518
519


520
521
522
523



524
525
526
527
528


529
530
531
532



533
534
535
536

537

538
539
540
541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

823
824


825
826


827
828
829






830
831


832
833


834
835


836
837


838
839


840
841
842
843










844
845


846
847


848
849


850
851


852
853


854
855


856
857


858
859


860
861


862
863


864
865


866
867


868
869


870
871


872
873


874
875


876
877


878
879


880
881


882
883


884
885


886
887


888
889


890
891


892
893


894
895


896
897


898
899


900
901


902
903


904
905


906
907


908
909


910
911


912
913


914
915


916
917


918
919


920
921


922
923


924
925


926
927


928
929


930
931


932
933


934
935


936
937


938
939


940
941


942
943


944
945


946
947


948
949


950
951


952
953


954
955


956
957


958
959


960
961


962
963


964
965


966
967


968
969


970
971


972



973
974


975
976


977
978


979
980


981
982


983
984


985
986

987

988
989


990
991


992
993


994
995


996
997


998
999


1000
1001


1002
1003


1004
1005


1006
1007


1008
1009


1010
1011


1012
1013


1014
1015


1016
1017


1018
1019


1020
1021


1022
1023


1024
1025


1026
1027


1028
1029


1030
1031


1032
1033


1034
1035


1036
1037


1038
1039


1040
1041


1042
1043


1044
1045


1046
1047


1048
1049


1050
1051


1052
1053


1054
1055


1056
1057

1058
1059

1060
1061

1062
1063

1064
1065

1066
1067
1068

1069
1070

1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083


1084
1085


1086
1087


1088
1089


1090
1091


1092
1093


1094
1095


1096
1097


1098
1099


1100
1101


1102
1103


1104
1105


1106
1107


1108
1109


1110
1111


1112
1113


1114
1115


1116
1117


1118
1119


1120
1121

1122

1123
1124


1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150


1151
1152


1153
1154


1155
1156


1157
1158


1159
1160


1161
1162


1163
1164


1165
1166


1167
1168


1169
1170


1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184





1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199



1200
1201
1202
1203
1204
1205
1206

1207












1208
1209

1210
1211
1212
1213
1214
1215

 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINTDECLS
#define _TKINTDECLS

#include "X11/Xutil.h"

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

struct TkText;
typedef struct TkTextBTree_ *TkTextBTree;
struct TkTextDispChunk;
struct TkTextIndex;
struct TkTextSegment;
struct TkSharedText;

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */



/* 0 */
EXTERN TkWindow *	TkAllocWindow(TkDisplay *dispPtr, int screenNum,
				TkWindow *parentPtr);



/* 1 */
EXTERN void		TkBezierPoints(double control[], int numSteps,
				double *coordPtr);



/* 2 */
EXTERN void		TkBezierScreenPoints(Tk_Canvas canvas,
				double control[], int numSteps,
				XPoint *xPointPtr);



/* Slot 3 is reserved */




/* 4 */
EXTERN void		TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr);



/* 5 */
EXTERN void		TkBindFree(TkMainInfo *mainPtr);



/* 6 */
EXTERN void		TkBindInit(TkMainInfo *mainPtr);



/* 7 */
EXTERN void		TkChangeEventWindow(XEvent *eventPtr,
				TkWindow *winPtr);



/* 8 */
EXTERN int		TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr);



/* 9 */
EXTERN void		TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin,
				int padX, int padY, int innerWidth,
				int innerHeight, int *xPtr, int *yPtr);



/* Slot 10 is reserved */




/* Slot 11 is reserved */









/* 12 */
EXTERN TkCursor *	TkCreateCursorFromData(Tk_Window tkwin,
				const char *source, const char *mask,
				int width, int height, int xHot, int yHot,
				XColor fg, XColor bg);



/* 13 */
EXTERN int		TkCreateFrame(ClientData clientData,
				Tcl_Interp *interp, int argc,
				const char *const *argv, int toplevel,
				const char *appName);



/* 14 */
EXTERN Tk_Window	TkCreateMainWindow(Tcl_Interp *interp,
				const char *screenName, const char *baseName);



/* 15 */
EXTERN Time		TkCurrentTime(TkDisplay *dispPtr);



/* 16 */
EXTERN void		TkDeleteAllImages(TkMainInfo *mainPtr);



/* 17 */
EXTERN void		TkDoConfigureNotify(TkWindow *winPtr);



/* 18 */
EXTERN void		TkDrawInsetFocusHighlight(Tk_Window tkwin, GC gc,
				int width, Drawable drawable, int padding);



/* 19 */
EXTERN void		TkEventDeadWindow(TkWindow *winPtr);



/* 20 */
EXTERN void		TkFillPolygon(Tk_Canvas canvas, double *coordPtr,
				int numPoints, Display *display,
				Drawable drawable, GC gc, GC outlineGC);



/* 21 */
EXTERN int		TkFindStateNum(Tcl_Interp *interp,
				const char *option, const TkStateMap *mapPtr,
				const char *strKey);



/* 22 */
EXTERN const char *	TkFindStateString(const TkStateMap *mapPtr,
				int numKey);



/* 23 */
EXTERN void		TkFocusDeadWindow(TkWindow *winPtr);



/* 24 */
EXTERN int		TkFocusFilterEvent(TkWindow *winPtr,
				XEvent *eventPtr);



/* 25 */
EXTERN TkWindow *	TkFocusKeyEvent(TkWindow *winPtr, XEvent *eventPtr);



/* 26 */
EXTERN void		TkFontPkgInit(TkMainInfo *mainPtr);



/* 27 */
EXTERN void		TkFontPkgFree(TkMainInfo *mainPtr);



/* 28 */
EXTERN void		TkFreeBindingTags(TkWindow *winPtr);



/* 29 */
EXTERN void		TkpFreeCursor(TkCursor *cursorPtr);



/* 30 */
EXTERN char *		TkGetBitmapData(Tcl_Interp *interp,
				const char *string, const char *fileName,
				int *widthPtr, int *heightPtr, int *hotXPtr,

				int *hotYPtr);

/* 31 */
EXTERN void		TkGetButtPoints(double p1[], double p2[],
				double width, int project, double m1[],
				double m2[]);



/* 32 */
EXTERN TkCursor *	TkGetCursorByName(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_Uid string);



/* 33 */
EXTERN const char *	TkGetDefaultScreenName(Tcl_Interp *interp,
				const char *screenName);



/* 34 */
EXTERN TkDisplay *	TkGetDisplay(Display *display);



/* 35 */
EXTERN int		TkGetDisplayOf(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], Tk_Window *tkwinPtr);



/* 36 */
EXTERN TkWindow *	TkGetFocusWin(TkWindow *winPtr);



/* 37 */
EXTERN int		TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin);



/* 38 */
EXTERN int		TkGetMiterPoints(double p1[], double p2[],
				double p3[], double width, double m1[],
				double m2[]);



/* 39 */
EXTERN void		TkGetPointerCoords(Tk_Window tkwin, int *xPtr,
				int *yPtr);



/* 40 */
EXTERN void		TkGetServerInfo(Tcl_Interp *interp, Tk_Window tkwin);



/* 41 */
EXTERN void		TkGrabDeadWindow(TkWindow *winPtr);



/* 42 */
EXTERN int		TkGrabState(TkWindow *winPtr);



/* 43 */
EXTERN void		TkIncludePoint(Tk_Item *itemPtr, double *pointPtr);



/* 44 */
EXTERN void		TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr,
				TkWindow *destPtr, int leaveType,
				int enterType, Tcl_QueuePosition position);



/* 45 */
EXTERN void		TkInstallFrameMenu(Tk_Window tkwin);



/* 46 */
EXTERN const char *	TkKeysymToString(KeySym keysym);



/* 47 */
EXTERN int		TkLineToArea(double end1Ptr[], double end2Ptr[],
				double rectPtr[]);



/* 48 */
EXTERN double		TkLineToPoint(double end1Ptr[], double end2Ptr[],
				double pointPtr[]);



/* 49 */
EXTERN int		TkMakeBezierCurve(Tk_Canvas canvas, double *pointPtr,
				int numPoints, int numSteps,
				XPoint xPoints[], double dblPoints[]);



/* 50 */
EXTERN void		TkMakeBezierPostscript(Tcl_Interp *interp,
				Tk_Canvas canvas, double *pointPtr,
				int numPoints);



/* 51 */
EXTERN void		TkOptionClassChanged(TkWindow *winPtr);



/* 52 */
EXTERN void		TkOptionDeadWindow(TkWindow *winPtr);



/* 53 */
EXTERN int		TkOvalToArea(double *ovalPtr, double *rectPtr);



/* 54 */
EXTERN double		TkOvalToPoint(double ovalPtr[], double width,
				int filled, double pointPtr[]);



/* 55 */
EXTERN int		TkpChangeFocus(TkWindow *winPtr, int force);



/* 56 */
EXTERN void		TkpCloseDisplay(TkDisplay *dispPtr);



/* 57 */
EXTERN void		TkpClaimFocus(TkWindow *topLevelPtr, int force);



/* 58 */
EXTERN void		TkpDisplayWarning(const char *msg, const char *title);



/* 59 */
EXTERN void		TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name);



/* 60 */
EXTERN TkWindow *	TkpGetOtherWindow(TkWindow *winPtr);



/* 61 */
EXTERN TkWindow *	TkpGetWrapperWindow(TkWindow *winPtr);



/* 62 */
EXTERN int		TkpInit(Tcl_Interp *interp);



/* 63 */
EXTERN void		TkpInitializeMenuBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable);



/* 64 */
EXTERN void		TkpMakeContainer(Tk_Window tkwin);



/* 65 */
EXTERN void		TkpMakeMenuWindow(Tk_Window tkwin, int transient);



/* 66 */
EXTERN Window		TkpMakeWindow(TkWindow *winPtr, Window parent);



/* 67 */
EXTERN void		TkpMenuNotifyToplevelCreate(Tcl_Interp *interp,
				const char *menuName);



/* 68 */
EXTERN TkDisplay *	TkpOpenDisplay(const char *display_name);



/* 69 */
EXTERN int		TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr);



/* 70 */
EXTERN int		TkPolygonToArea(double *polyPtr, int numPoints,
				double *rectPtr);



/* 71 */
EXTERN double		TkPolygonToPoint(double *polyPtr, int numPoints,
				double *pointPtr);



/* 72 */
EXTERN int		TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr);



/* 73 */
EXTERN void		TkpRedirectKeyEvent(TkWindow *winPtr,
				XEvent *eventPtr);



/* 74 */
EXTERN void		TkpSetMainMenubar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *menuName);



/* 75 */
EXTERN int		TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin,
				const char *string);



/* Slot 76 is reserved */





/* 77 */
EXTERN void		TkQueueEventForAllChildren(TkWindow *winPtr,
				XEvent *eventPtr);



/* 78 */
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);



/* 79 */
EXTERN int		TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
				int width, int height, int dx, int dy,
				Region damageRgn);



/* 80 */
EXTERN void		TkSelDeadWindow(TkWindow *winPtr);



/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);



/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);



/* 83 */
EXTERN void		TkSelPropProc(XEvent *eventPtr);

/* Slot 84 is reserved */


/* 85 */
EXTERN void		TkSetWindowMenuBar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *oldMenuName,
				const char *menuName);



/* 86 */
EXTERN KeySym		TkStringToKeysym(const char *name);



/* 87 */
EXTERN int		TkThickPolyLineToArea(double *coordPtr,
				int numPoints, double width, int capStyle,
				int joinStyle, double *rectPtr);



/* 88 */
EXTERN void		TkWmAddToColormapWindows(TkWindow *winPtr);



/* 89 */
EXTERN void		TkWmDeadWindow(TkWindow *winPtr);



/* 90 */
EXTERN TkWindow *	TkWmFocusToplevel(TkWindow *winPtr);



/* 91 */
EXTERN void		TkWmMapWindow(TkWindow *winPtr);



/* 92 */
EXTERN void		TkWmNewWindow(TkWindow *winPtr);



/* 93 */
EXTERN void		TkWmProtocolEventProc(TkWindow *winPtr,
				XEvent *evenvPtr);



/* 94 */
EXTERN void		TkWmRemoveFromColormapWindows(TkWindow *winPtr);



/* 95 */
EXTERN void		TkWmRestackToplevel(TkWindow *winPtr, int aboveBelow,
				TkWindow *otherPtr);



/* 96 */
EXTERN void		TkWmSetClass(TkWindow *winPtr);



/* 97 */
EXTERN void		TkWmUnmapWindow(TkWindow *winPtr);



/* 98 */
EXTERN Tcl_Obj *	TkDebugBitmap(Tk_Window tkwin, const char *name);



/* 99 */
EXTERN Tcl_Obj *	TkDebugBorder(Tk_Window tkwin, const char *name);



/* 100 */
EXTERN Tcl_Obj *	TkDebugCursor(Tk_Window tkwin, const char *name);



/* 101 */
EXTERN Tcl_Obj *	TkDebugColor(Tk_Window tkwin, const char *name);



/* 102 */
EXTERN Tcl_Obj *	TkDebugConfig(Tcl_Interp *interp,
				Tk_OptionTable table);



/* 103 */
EXTERN Tcl_Obj *	TkDebugFont(Tk_Window tkwin, const char *name);



/* 104 */
EXTERN int		TkFindStateNumObj(Tcl_Interp *interp,
				Tcl_Obj *optionPtr, const TkStateMap *mapPtr,
				Tcl_Obj *keyPtr);



/* 105 */
EXTERN Tcl_HashTable *	TkGetBitmapPredefTable(void);



/* 106 */
EXTERN TkDisplay *	TkGetDisplayList(void);



/* 107 */
EXTERN TkMainInfo *	TkGetMainInfoList(void);



/* 108 */
EXTERN int		TkGetWindowFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);



/* 109 */
EXTERN const char *	TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);



/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);



/* 111 */
EXTERN Tcl_Obj *	TkpGetSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);



/* 112 */
EXTERN void		TkpMenuThreadInit(void);



/* 113 */
EXTERN int		XClipBox(Region rgn, XRectangle *rect_return);



/* 114 */
EXTERN Region		XCreateRegion(void);



/* 115 */
EXTERN int		XDestroyRegion(Region rgn);



/* 116 */
EXTERN int		XIntersectRegion(Region sra, Region srcb,
				Region dr_return);



/* 117 */
EXTERN int		XRectInRegion(Region rgn, int x, int y,
				unsigned int width, unsigned int height);



/* 118 */
EXTERN int		XSetRegion(Display *display, GC gc, Region rgn);



/* 119 */
EXTERN int		XUnionRectWithRegion(XRectangle *rect, Region src,
				Region dr_return);

/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */


/* 121 */
EXTERN Pixmap		TkpCreateNativeBitmap(Display *display,
				const void *source);

#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */


/* 122 */
EXTERN void		TkpDefineNativeBitmaps(void);

#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */


/* 124 */
EXTERN Pixmap		TkpGetNativeAppBitmap(Display *display,
				const char *name, int *width, int *height);

#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */


/* 135 */
EXTERN void		TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC,
				GC bgGC, int highlightWidth,
				Drawable drawable);



/* 136 */
EXTERN void		TkSetFocusWin(TkWindow *winPtr, int force);



/* 137 */
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);



/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);



/* 139 */
EXTERN void		TkpInitKeymapInfo(TkDisplay *dispPtr);



/* 140 */
EXTERN Region		TkPhotoGetValidRegion(Tk_PhotoHandle handle);



/* 141 */
EXTERN TkWindow **	TkWmStackorderToplevel(TkWindow *parentPtr);



/* 142 */
EXTERN void		TkFocusFree(TkMainInfo *mainPtr);



/* 143 */
EXTERN void		TkClipCleanup(TkDisplay *dispPtr);



/* 144 */
EXTERN void		TkGCCleanup(TkDisplay *dispPtr);



/* 145 */
EXTERN int		XSubtractRegion(Region sra, Region srcb,
				Region dr_return);



/* 146 */
EXTERN void		TkStylePkgInit(TkMainInfo *mainPtr);



/* 147 */
EXTERN void		TkStylePkgFree(TkMainInfo *mainPtr);



/* 148 */
EXTERN Tk_Window	TkToplevelWindowForCommand(Tcl_Interp *interp,
				const char *cmdName);



/* 149 */
EXTERN const Tk_OptionSpec * TkGetOptionSpec(const char *name,
				Tk_OptionTable optionTable);



/* 150 */
EXTERN int		TkMakeRawCurve(Tk_Canvas canvas, double *pointPtr,
				int numPoints, int numSteps,
				XPoint xPoints[], double dblPoints[]);



/* 151 */
EXTERN void		TkMakeRawCurvePostscript(Tcl_Interp *interp,
				Tk_Canvas canvas, double *pointPtr,
				int numPoints);



/* 152 */
EXTERN void		TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
				int highlightWidth, int borderWidth,
				int relief);



/* 153 */
EXTERN void		TkCreateThreadExitHandler(Tcl_ExitProc *proc,
				ClientData clientData);



/* 154 */
EXTERN void		TkDeleteThreadExitHandler(Tcl_ExitProc *proc,
				ClientData clientData);

/* Slot 155 is reserved */


/* 156 */
EXTERN int		TkpTestembedCmd(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);



/* 157 */
EXTERN int		TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp,
				int objc, Tcl_Obj *const objv[]);

/* 158 */
EXTERN int		TkSelGetSelection(Tcl_Interp *interp,
				Tk_Window tkwin, Atom selection, Atom target,
				Tk_GetSelProc *proc, ClientData clientData);
/* 159 */
EXTERN int		TkTextGetIndex(Tcl_Interp *interp,
				struct TkText *textPtr, const char *string,
				struct TkTextIndex *indexPtr);
/* 160 */
EXTERN int		TkTextIndexBackBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, int count,
				struct TkTextIndex *dstPtr);
/* 161 */
EXTERN int		TkTextIndexForwBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, int count,
				struct TkTextIndex *dstPtr);
/* 162 */
EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree,
				const struct TkText *textPtr, int lineIndex,
				int byteIndex, struct TkTextIndex *indexPtr);
/* 163 */
EXTERN TkSizeT		TkTextPrintIndex(const struct TkText *textPtr,
				const struct TkTextIndex *indexPtr,
				char *string);
/* 164 */
EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr,
				const char *name,
				struct TkTextIndex *indexPtr);
/* 165 */
EXTERN int		TkTextXviewCmd(struct TkText *textPtr,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* 166 */
EXTERN void		TkTextChanged(struct TkSharedText *sharedTextPtr,
				struct TkText *textPtr,
				const struct TkTextIndex *index1Ptr,
				const struct TkTextIndex *index2Ptr);
/* 167 */
EXTERN int		TkBTreeNumLines(TkTextBTree tree,
				const struct TkText *textPtr);
/* 168 */
EXTERN void		TkTextInsertDisplayProc(struct TkText *textPtr,
				struct TkTextDispChunk *chunkPtr, int x,
				int y, int height, int baseline,
				Display *display, Drawable dst, int screenY);


/* 169 */
EXTERN int		TkStateParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,

				TkSizeT offset);

/* 170 */
EXTERN const char *	TkStatePrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);



/* 171 */
EXTERN int		TkCanvasDashParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);


/* 172 */
EXTERN const char *	TkCanvasDashPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);



/* 173 */
EXTERN int		TkOffsetParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,

				TkSizeT offset);

/* 174 */
EXTERN const char *	TkOffsetPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);



/* 175 */
EXTERN int		TkPixelParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);


/* 176 */
EXTERN const char *	TkPixelPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);



/* 177 */
EXTERN int		TkOrientParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);


/* 178 */
EXTERN const char *	TkOrientPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);



/* 179 */
EXTERN int		TkSmoothParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,

				TkSizeT offset);

/* 180 */
EXTERN const char *	TkSmoothPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);

/* 181 */
EXTERN void		TkDrawAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int firstChar, int lastChar);
/* 182 */
EXTERN void		TkUnderlineAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int underline);
/* 183 */
EXTERN int		TkIntersectAngledTextLayout(Tk_TextLayout layout,
				int x, int y, int width, int height,
				double angle);
/* 184 */
EXTERN void		TkDrawAngledChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int numBytes, double x,
				double y, double angle);
#ifdef MAC_OSX_TCL /* MACOSX */
/* 185 */
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */

/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
/* 187 */
EXTERN int		TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
				Tcl_Obj *data, Tcl_Obj *formatString,
				int *widthPtr, int *heightPtr);

typedef struct TkIntStubs {
    int magic;
    void *hooks;

    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 (*reserved3)(void);
    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 */
    void (*reserved10)(void);
    void (*reserved11)(void);
    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, const char *const *argv, int toplevel, const char *appName); /* 13 */
    Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, const char *screenName, const 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 */
    const 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, const char *string, const 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 */
    const 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 */
    const 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, const 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, const char *menuName); /* 74 */
    int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 75 */
    void (*reserved76)(void);
    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, Region 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);
    void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */
    KeySym (*tkStringToKeysym) (const 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, const char *name); /* 98 */
    Tcl_Obj * (*tkDebugBorder) (Tk_Window tkwin, const char *name); /* 99 */
    Tcl_Obj * (*tkDebugCursor) (Tk_Window tkwin, const char *name); /* 100 */
    Tcl_Obj * (*tkDebugColor) (Tk_Window tkwin, const char *name); /* 101 */
    Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */
    Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, const 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 */
    const 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 */
    int (*xClipBox) (Region rgn, XRectangle *rect_return); /* 113 */
    Region (*xCreateRegion) (void); /* 114 */
    int (*xDestroyRegion) (Region rgn); /* 115 */
    int (*xIntersectRegion) (Region sra, Region srcb, Region dr_return); /* 116 */
    int (*xRectInRegion) (Region rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*xSetRegion) (Display *display, GC gc, Region rgn); /* 118 */
    int (*xUnionRectWithRegion) (XRectangle *rect, Region src, Region dr_return); /* 119 */
    void (*reserved120)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved121)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved121)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved122)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved122)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */
    void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
    void (*reserved123)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved124)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved124)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    void (*reserved129)(void);
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    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 */
    Region (*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 */
    int (*xSubtractRegion) (Region sra, Region srcb, Region 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)(void);
    int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */
    int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */
    int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */
    int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
    int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */
    int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */
    struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */
    TkSizeT (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */
    struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */
    int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */
    void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */
    int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
    void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
    int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 169 */
    const char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 170 */
    int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 171 */
    const char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 172 */
    int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 173 */
    const char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 174 */
    int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 175 */
    const char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 176 */
    int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 177 */
    const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 179 */
    const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
    void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
    int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
    void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved185)(void);
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved185)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    void (*tkpRedrawWidget) (Tk_Window tkwin); /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved186)(void);
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved186)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */


#define TkAllocWindow \
	(tkIntStubsPtr->tkAllocWindow) /* 0 */


#define TkBezierPoints \
	(tkIntStubsPtr->tkBezierPoints) /* 1 */


#define TkBezierScreenPoints \
	(tkIntStubsPtr->tkBezierScreenPoints) /* 2 */
/* Slot 3 is reserved */






#define TkBindEventProc \
	(tkIntStubsPtr->tkBindEventProc) /* 4 */


#define TkBindFree \
	(tkIntStubsPtr->tkBindFree) /* 5 */


#define TkBindInit \
	(tkIntStubsPtr->tkBindInit) /* 6 */


#define TkChangeEventWindow \
	(tkIntStubsPtr->tkChangeEventWindow) /* 7 */


#define TkClipInit \
	(tkIntStubsPtr->tkClipInit) /* 8 */


#define TkComputeAnchor \
	(tkIntStubsPtr->tkComputeAnchor) /* 9 */
/* Slot 10 is reserved */
/* Slot 11 is reserved */










#define TkCreateCursorFromData \
	(tkIntStubsPtr->tkCreateCursorFromData) /* 12 */


#define TkCreateFrame \
	(tkIntStubsPtr->tkCreateFrame) /* 13 */


#define TkCreateMainWindow \
	(tkIntStubsPtr->tkCreateMainWindow) /* 14 */


#define TkCurrentTime \
	(tkIntStubsPtr->tkCurrentTime) /* 15 */


#define TkDeleteAllImages \
	(tkIntStubsPtr->tkDeleteAllImages) /* 16 */


#define TkDoConfigureNotify \
	(tkIntStubsPtr->tkDoConfigureNotify) /* 17 */


#define TkDrawInsetFocusHighlight \
	(tkIntStubsPtr->tkDrawInsetFocusHighlight) /* 18 */


#define TkEventDeadWindow \
	(tkIntStubsPtr->tkEventDeadWindow) /* 19 */


#define TkFillPolygon \
	(tkIntStubsPtr->tkFillPolygon) /* 20 */


#define TkFindStateNum \
	(tkIntStubsPtr->tkFindStateNum) /* 21 */


#define TkFindStateString \
	(tkIntStubsPtr->tkFindStateString) /* 22 */


#define TkFocusDeadWindow \
	(tkIntStubsPtr->tkFocusDeadWindow) /* 23 */


#define TkFocusFilterEvent \
	(tkIntStubsPtr->tkFocusFilterEvent) /* 24 */


#define TkFocusKeyEvent \
	(tkIntStubsPtr->tkFocusKeyEvent) /* 25 */


#define TkFontPkgInit \
	(tkIntStubsPtr->tkFontPkgInit) /* 26 */


#define TkFontPkgFree \
	(tkIntStubsPtr->tkFontPkgFree) /* 27 */


#define TkFreeBindingTags \
	(tkIntStubsPtr->tkFreeBindingTags) /* 28 */


#define TkpFreeCursor \
	(tkIntStubsPtr->tkpFreeCursor) /* 29 */


#define TkGetBitmapData \
	(tkIntStubsPtr->tkGetBitmapData) /* 30 */


#define TkGetButtPoints \
	(tkIntStubsPtr->tkGetButtPoints) /* 31 */


#define TkGetCursorByName \
	(tkIntStubsPtr->tkGetCursorByName) /* 32 */


#define TkGetDefaultScreenName \
	(tkIntStubsPtr->tkGetDefaultScreenName) /* 33 */


#define TkGetDisplay \
	(tkIntStubsPtr->tkGetDisplay) /* 34 */


#define TkGetDisplayOf \
	(tkIntStubsPtr->tkGetDisplayOf) /* 35 */


#define TkGetFocusWin \
	(tkIntStubsPtr->tkGetFocusWin) /* 36 */


#define TkGetInterpNames \
	(tkIntStubsPtr->tkGetInterpNames) /* 37 */


#define TkGetMiterPoints \
	(tkIntStubsPtr->tkGetMiterPoints) /* 38 */


#define TkGetPointerCoords \
	(tkIntStubsPtr->tkGetPointerCoords) /* 39 */


#define TkGetServerInfo \
	(tkIntStubsPtr->tkGetServerInfo) /* 40 */


#define TkGrabDeadWindow \
	(tkIntStubsPtr->tkGrabDeadWindow) /* 41 */


#define TkGrabState \
	(tkIntStubsPtr->tkGrabState) /* 42 */


#define TkIncludePoint \
	(tkIntStubsPtr->tkIncludePoint) /* 43 */


#define TkInOutEvents \
	(tkIntStubsPtr->tkInOutEvents) /* 44 */


#define TkInstallFrameMenu \
	(tkIntStubsPtr->tkInstallFrameMenu) /* 45 */


#define TkKeysymToString \
	(tkIntStubsPtr->tkKeysymToString) /* 46 */


#define TkLineToArea \
	(tkIntStubsPtr->tkLineToArea) /* 47 */


#define TkLineToPoint \
	(tkIntStubsPtr->tkLineToPoint) /* 48 */


#define TkMakeBezierCurve \
	(tkIntStubsPtr->tkMakeBezierCurve) /* 49 */


#define TkMakeBezierPostscript \
	(tkIntStubsPtr->tkMakeBezierPostscript) /* 50 */


#define TkOptionClassChanged \
	(tkIntStubsPtr->tkOptionClassChanged) /* 51 */


#define TkOptionDeadWindow \
	(tkIntStubsPtr->tkOptionDeadWindow) /* 52 */


#define TkOvalToArea \
	(tkIntStubsPtr->tkOvalToArea) /* 53 */


#define TkOvalToPoint \
	(tkIntStubsPtr->tkOvalToPoint) /* 54 */


#define TkpChangeFocus \
	(tkIntStubsPtr->tkpChangeFocus) /* 55 */


#define TkpCloseDisplay \
	(tkIntStubsPtr->tkpCloseDisplay) /* 56 */


#define TkpClaimFocus \
	(tkIntStubsPtr->tkpClaimFocus) /* 57 */


#define TkpDisplayWarning \
	(tkIntStubsPtr->tkpDisplayWarning) /* 58 */


#define TkpGetAppName \
	(tkIntStubsPtr->tkpGetAppName) /* 59 */


#define TkpGetOtherWindow \
	(tkIntStubsPtr->tkpGetOtherWindow) /* 60 */


#define TkpGetWrapperWindow \
	(tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */


#define TkpInit \
	(tkIntStubsPtr->tkpInit) /* 62 */


#define TkpInitializeMenuBindings \
	(tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */


#define TkpMakeContainer \
	(tkIntStubsPtr->tkpMakeContainer) /* 64 */


#define TkpMakeMenuWindow \
	(tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */


#define TkpMakeWindow \
	(tkIntStubsPtr->tkpMakeWindow) /* 66 */


#define TkpMenuNotifyToplevelCreate \
	(tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */


#define TkpOpenDisplay \
	(tkIntStubsPtr->tkpOpenDisplay) /* 68 */


#define TkPointerEvent \
	(tkIntStubsPtr->tkPointerEvent) /* 69 */


#define TkPolygonToArea \
	(tkIntStubsPtr->tkPolygonToArea) /* 70 */


#define TkPolygonToPoint \
	(tkIntStubsPtr->tkPolygonToPoint) /* 71 */


#define TkPositionInTree \
	(tkIntStubsPtr->tkPositionInTree) /* 72 */


#define TkpRedirectKeyEvent \
	(tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */


#define TkpSetMainMenubar \
	(tkIntStubsPtr->tkpSetMainMenubar) /* 74 */


#define TkpUseWindow \
	(tkIntStubsPtr->tkpUseWindow) /* 75 */


/* Slot 76 is reserved */



#define TkQueueEventForAllChildren \
	(tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */


#define TkReadBitmapFile \
	(tkIntStubsPtr->tkReadBitmapFile) /* 78 */


#define TkScrollWindow \
	(tkIntStubsPtr->tkScrollWindow) /* 79 */


#define TkSelDeadWindow \
	(tkIntStubsPtr->tkSelDeadWindow) /* 80 */


#define TkSelEventProc \
	(tkIntStubsPtr->tkSelEventProc) /* 81 */


#define TkSelInit \
	(tkIntStubsPtr->tkSelInit) /* 82 */


#define TkSelPropProc \
	(tkIntStubsPtr->tkSelPropProc) /* 83 */

/* Slot 84 is reserved */

#define TkSetWindowMenuBar \
	(tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */


#define TkStringToKeysym \
	(tkIntStubsPtr->tkStringToKeysym) /* 86 */


#define TkThickPolyLineToArea \
	(tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */


#define TkWmAddToColormapWindows \
	(tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */


#define TkWmDeadWindow \
	(tkIntStubsPtr->tkWmDeadWindow) /* 89 */


#define TkWmFocusToplevel \
	(tkIntStubsPtr->tkWmFocusToplevel) /* 90 */


#define TkWmMapWindow \
	(tkIntStubsPtr->tkWmMapWindow) /* 91 */


#define TkWmNewWindow \
	(tkIntStubsPtr->tkWmNewWindow) /* 92 */


#define TkWmProtocolEventProc \
	(tkIntStubsPtr->tkWmProtocolEventProc) /* 93 */


#define TkWmRemoveFromColormapWindows \
	(tkIntStubsPtr->tkWmRemoveFromColormapWindows) /* 94 */


#define TkWmRestackToplevel \
	(tkIntStubsPtr->tkWmRestackToplevel) /* 95 */


#define TkWmSetClass \
	(tkIntStubsPtr->tkWmSetClass) /* 96 */


#define TkWmUnmapWindow \
	(tkIntStubsPtr->tkWmUnmapWindow) /* 97 */


#define TkDebugBitmap \
	(tkIntStubsPtr->tkDebugBitmap) /* 98 */


#define TkDebugBorder \
	(tkIntStubsPtr->tkDebugBorder) /* 99 */


#define TkDebugCursor \
	(tkIntStubsPtr->tkDebugCursor) /* 100 */


#define TkDebugColor \
	(tkIntStubsPtr->tkDebugColor) /* 101 */


#define TkDebugConfig \
	(tkIntStubsPtr->tkDebugConfig) /* 102 */


#define TkDebugFont \
	(tkIntStubsPtr->tkDebugFont) /* 103 */


#define TkFindStateNumObj \
	(tkIntStubsPtr->tkFindStateNumObj) /* 104 */


#define TkGetBitmapPredefTable \
	(tkIntStubsPtr->tkGetBitmapPredefTable) /* 105 */


#define TkGetDisplayList \
	(tkIntStubsPtr->tkGetDisplayList) /* 106 */


#define TkGetMainInfoList \
	(tkIntStubsPtr->tkGetMainInfoList) /* 107 */


#define TkGetWindowFromObj \
	(tkIntStubsPtr->tkGetWindowFromObj) /* 108 */


#define TkpGetString \
	(tkIntStubsPtr->tkpGetString) /* 109 */


#define TkpGetSubFonts \
	(tkIntStubsPtr->tkpGetSubFonts) /* 110 */


#define TkpGetSystemDefault \
	(tkIntStubsPtr->tkpGetSystemDefault) /* 111 */


#define TkpMenuThreadInit \
	(tkIntStubsPtr->tkpMenuThreadInit) /* 112 */


#define XClipBox \
	(tkIntStubsPtr->xClipBox) /* 113 */


#define XCreateRegion \
	(tkIntStubsPtr->xCreateRegion) /* 114 */


#define XDestroyRegion \
	(tkIntStubsPtr->xDestroyRegion) /* 115 */


#define XIntersectRegion \
	(tkIntStubsPtr->xIntersectRegion) /* 116 */


#define XRectInRegion \
	(tkIntStubsPtr->xRectInRegion) /* 117 */


#define XSetRegion \
	(tkIntStubsPtr->xSetRegion) /* 118 */


#define XUnionRectWithRegion \
	(tkIntStubsPtr->xUnionRectWithRegion) /* 119 */

/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */

#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */

#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */

#define TkpDefineNativeBitmaps \
	(tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */

#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */

#define TkpGetNativeAppBitmap \
	(tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */

#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */

#define TkpDrawHighlightBorder \
	(tkIntStubsPtr->tkpDrawHighlightBorder) /* 135 */


#define TkSetFocusWin \
	(tkIntStubsPtr->tkSetFocusWin) /* 136 */


#define TkpSetKeycodeAndState \
	(tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */


#define TkpGetKeySym \
	(tkIntStubsPtr->tkpGetKeySym) /* 138 */


#define TkpInitKeymapInfo \
	(tkIntStubsPtr->tkpInitKeymapInfo) /* 139 */


#define TkPhotoGetValidRegion \
	(tkIntStubsPtr->tkPhotoGetValidRegion) /* 140 */


#define TkWmStackorderToplevel \
	(tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */


#define TkFocusFree \
	(tkIntStubsPtr->tkFocusFree) /* 142 */


#define TkClipCleanup \
	(tkIntStubsPtr->tkClipCleanup) /* 143 */


#define TkGCCleanup \
	(tkIntStubsPtr->tkGCCleanup) /* 144 */


#define XSubtractRegion \
	(tkIntStubsPtr->xSubtractRegion) /* 145 */


#define TkStylePkgInit \
	(tkIntStubsPtr->tkStylePkgInit) /* 146 */


#define TkStylePkgFree \
	(tkIntStubsPtr->tkStylePkgFree) /* 147 */


#define TkToplevelWindowForCommand \
	(tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */


#define TkGetOptionSpec \
	(tkIntStubsPtr->tkGetOptionSpec) /* 149 */


#define TkMakeRawCurve \
	(tkIntStubsPtr->tkMakeRawCurve) /* 150 */


#define TkMakeRawCurvePostscript \
	(tkIntStubsPtr->tkMakeRawCurvePostscript) /* 151 */


#define TkpDrawFrame \
	(tkIntStubsPtr->tkpDrawFrame) /* 152 */


#define TkCreateThreadExitHandler \
	(tkIntStubsPtr->tkCreateThreadExitHandler) /* 153 */


#define TkDeleteThreadExitHandler \
	(tkIntStubsPtr->tkDeleteThreadExitHandler) /* 154 */

/* Slot 155 is reserved */

#define TkpTestembedCmd \
	(tkIntStubsPtr->tkpTestembedCmd) /* 156 */


#define TkpTesttextCmd \
	(tkIntStubsPtr->tkpTesttextCmd) /* 157 */
#define TkSelGetSelection \
	(tkIntStubsPtr->tkSelGetSelection) /* 158 */
#define TkTextGetIndex \
	(tkIntStubsPtr->tkTextGetIndex) /* 159 */
#define TkTextIndexBackBytes \
	(tkIntStubsPtr->tkTextIndexBackBytes) /* 160 */
#define TkTextIndexForwBytes \
	(tkIntStubsPtr->tkTextIndexForwBytes) /* 161 */
#define TkTextMakeByteIndex \
	(tkIntStubsPtr->tkTextMakeByteIndex) /* 162 */
#define TkTextPrintIndex \
	(tkIntStubsPtr->tkTextPrintIndex) /* 163 */
#define TkTextSetMark \
	(tkIntStubsPtr->tkTextSetMark) /* 164 */
#define TkTextXviewCmd \
	(tkIntStubsPtr->tkTextXviewCmd) /* 165 */
#define TkTextChanged \
	(tkIntStubsPtr->tkTextChanged) /* 166 */
#define TkBTreeNumLines \
	(tkIntStubsPtr->tkBTreeNumLines) /* 167 */

#define TkTextInsertDisplayProc \
	(tkIntStubsPtr->tkTextInsertDisplayProc) /* 168 */
#define TkStateParseProc \
	(tkIntStubsPtr->tkStateParseProc) /* 169 */


#define TkStatePrintProc \
	(tkIntStubsPtr->tkStatePrintProc) /* 170 */


#define TkCanvasDashParseProc \
	(tkIntStubsPtr->tkCanvasDashParseProc) /* 171 */


#define TkCanvasDashPrintProc \
	(tkIntStubsPtr->tkCanvasDashPrintProc) /* 172 */


#define TkOffsetParseProc \
	(tkIntStubsPtr->tkOffsetParseProc) /* 173 */


#define TkOffsetPrintProc \
	(tkIntStubsPtr->tkOffsetPrintProc) /* 174 */


#define TkPixelParseProc \
	(tkIntStubsPtr->tkPixelParseProc) /* 175 */


#define TkPixelPrintProc \
	(tkIntStubsPtr->tkPixelPrintProc) /* 176 */


#define TkOrientParseProc \
	(tkIntStubsPtr->tkOrientParseProc) /* 177 */


#define TkOrientPrintProc \
	(tkIntStubsPtr->tkOrientPrintProc) /* 178 */


#define TkSmoothParseProc \
	(tkIntStubsPtr->tkSmoothParseProc) /* 179 */


#define TkSmoothPrintProc \
	(tkIntStubsPtr->tkSmoothPrintProc) /* 180 */
#define TkDrawAngledTextLayout \
	(tkIntStubsPtr->tkDrawAngledTextLayout) /* 181 */
#define TkUnderlineAngledTextLayout \
	(tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */
#define TkIntersectAngledTextLayout \
	(tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */
#define TkDrawAngledChars \
	(tkIntStubsPtr->tkDrawAngledChars) /* 184 */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */
#endif /* MACOSX */





#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
#define TkDebugPhotoStringMatchDef \
	(tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 187 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT


#undef TkpCmapStressed_



#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_














#if !defined(MAC_OSX_TK)
#   undef TkpWillDrawWidget

#   undef TkpRedrawWidget
#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)
#endif

#endif /* _TKINTDECLS */








<
<





<
<
<
<
<
<
<
















>
>



>
>
>



>
>
>




>
>
>
|
>
>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>




>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>


|


>
>
>


|
<
|
>
>
>


|
>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>




>
>
>


|
|
>
>
>

|

>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>

|
|
|
>
|
>




>
>
>



>
>
>

|
|
>
>
>


>
>
>


|
>
>
>


>
>
>


>
>
>




>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


>
>
>




>
>
>


>
>
>

|
>
>
>



>
>
>



>
>
>




>
>
>




>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>

|
>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


|
>
>
>

|
>
>
>


>
>
>



>
>
>



>
>
>


>
>
>



>
>
>


|
>
>
>


|
>
>
>
|
>
>
>
>
>



>
>
>


|




>
>
>



|
>
>
>


>
>
>


>
>
>


>
>
>


>

>
>


|
|
>
>
>

|
>
>
>




>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>



>
>
>


>
>
>


>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
>
>
>



>
>
>

|
>
>
>


|

>
>
>


>
>
>


>
>
>


>
>
>




>
>
>

|

>
>
>


>
>
>


|
>
>
>


>
>
>

|
>
>
>

|
>
>
>

|
>
>
>

|
|
>
>
>

|

>
>
>

|
>
>
>

|
|
>


>
>


|
>


>
>


>



>
>


|
>











>
>




>
>
>


>
>
>



>
>
>


>
>
>


>
>
>

|
>
>
>


>
>
>


>
>
>


>
>
>


>
>
>

|
|
>
>
>


>
>
>


>
>
>


|
>
>
>

|

>
>
>




>
>
>




>
>
>




>
>
>



>
>
>



>

>
>


|
|
>
>
>


|
>
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
>
>



|
>
|
>

|
|
|
>
>
>



|
|
>
>

|
|
|
>
>
>



|
>
|
>

|
|
|
>
>
>



|
|
>
>

|
|
|
>
>
>



|
|
>
>

|
|
|
>
>
>



|
>
|
>

|
|
|
>
|
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
<
|
>

|
|
<
<
<
<



|




|






|
|
|
|
|






|
|







|


|

|










|











|








|
|





|
|
|

|
|




|
|
|











|
|
|
|

|
|




|

|

|
|
|
|
|
|
|
|
|
|

|
|


|
|

|
|

|
|


|


|
|
|

|
|


|
|

|
|
|
|
|
|
|
|
|
|





|




|


|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
|
|
<
|
<
<
<
<
<
|
<
<
|
<
<
|
<
<


|





|





>


>
>


>
>


<
>
>
>
>
>
>


>
>


>
>


>
>


>
>


>
>


<
<
>
>
>
>
>
>
>
>
>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>
|
>
>
>


>
>


>
>


>
>


>
>


>
>


>
>


>

>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>


>


>


>


>



>


>











>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>
|
|
>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>

>


>
>


|
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
|
<
<
|
>
|
<


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
>
|
|
|
|
<
<

|






>
|
>
>
>
|
|
|
|
|
|
|
>

>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
|
|
<



>
11
12
13
14
15
16
17


18
19
20
21
22







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874



875



876



877



878



879



880



881



882




883


884




885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969




970




971



972





973


974
975
976
977
978




979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191





1192
1193

1194





1195


1196


1197


1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250


1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808

1809

1810

1811

1812

1813

1814

1815
1816


1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865











1866
1867
1868
1869
1870
1871
1872
1873
1874
1875


1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINTDECLS
#define _TKINTDECLS



#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif








/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#ifndef TkAllocWindow_TCL_DECLARED
#define TkAllocWindow_TCL_DECLARED
/* 0 */
EXTERN TkWindow *	TkAllocWindow(TkDisplay *dispPtr, int screenNum,
				TkWindow *parentPtr);
#endif
#ifndef TkBezierPoints_TCL_DECLARED
#define TkBezierPoints_TCL_DECLARED
/* 1 */
EXTERN void		TkBezierPoints(double control[], int numSteps,
				double *coordPtr);
#endif
#ifndef TkBezierScreenPoints_TCL_DECLARED
#define TkBezierScreenPoints_TCL_DECLARED
/* 2 */
EXTERN void		TkBezierScreenPoints(Tk_Canvas canvas,
				double control[], int numSteps,
				XPoint *xPointPtr);
#endif
#ifndef TkBindDeadWindow_TCL_DECLARED
#define TkBindDeadWindow_TCL_DECLARED
/* 3 */
EXTERN void		TkBindDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkBindEventProc_TCL_DECLARED
#define TkBindEventProc_TCL_DECLARED
/* 4 */
EXTERN void		TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr);
#endif
#ifndef TkBindFree_TCL_DECLARED
#define TkBindFree_TCL_DECLARED
/* 5 */
EXTERN void		TkBindFree(TkMainInfo *mainPtr);
#endif
#ifndef TkBindInit_TCL_DECLARED
#define TkBindInit_TCL_DECLARED
/* 6 */
EXTERN void		TkBindInit(TkMainInfo *mainPtr);
#endif
#ifndef TkChangeEventWindow_TCL_DECLARED
#define TkChangeEventWindow_TCL_DECLARED
/* 7 */
EXTERN void		TkChangeEventWindow(XEvent *eventPtr,
				TkWindow *winPtr);
#endif
#ifndef TkClipInit_TCL_DECLARED
#define TkClipInit_TCL_DECLARED
/* 8 */
EXTERN int		TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr);
#endif
#ifndef TkComputeAnchor_TCL_DECLARED
#define TkComputeAnchor_TCL_DECLARED
/* 9 */
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(Tcl_Interp *interp, char *script);
#endif
#ifndef TkCreateBindingProcedure_TCL_DECLARED
#define TkCreateBindingProcedure_TCL_DECLARED
/* 11 */
EXTERN unsigned long	TkCreateBindingProcedure(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, CONST char *eventString,
				TkBindEvalProc *evalProc,
				TkBindFreeProc *freeProc,
				ClientData clientData);
#endif
#ifndef TkCreateCursorFromData_TCL_DECLARED
#define TkCreateCursorFromData_TCL_DECLARED
/* 12 */
EXTERN TkCursor *	TkCreateCursorFromData(Tk_Window tkwin,
				CONST char *source, CONST char *mask,
				int width, int height, int xHot, int yHot,
				XColor fg, XColor bg);
#endif
#ifndef TkCreateFrame_TCL_DECLARED
#define TkCreateFrame_TCL_DECLARED
/* 13 */
EXTERN int		TkCreateFrame(ClientData clientData,
				Tcl_Interp *interp, int argc, char **argv,

				int toplevel, char *appName);
#endif
#ifndef TkCreateMainWindow_TCL_DECLARED
#define TkCreateMainWindow_TCL_DECLARED
/* 14 */
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(TkDisplay *dispPtr);
#endif
#ifndef TkDeleteAllImages_TCL_DECLARED
#define TkDeleteAllImages_TCL_DECLARED
/* 16 */
EXTERN void		TkDeleteAllImages(TkMainInfo *mainPtr);
#endif
#ifndef TkDoConfigureNotify_TCL_DECLARED
#define TkDoConfigureNotify_TCL_DECLARED
/* 17 */
EXTERN void		TkDoConfigureNotify(TkWindow *winPtr);
#endif
#ifndef TkDrawInsetFocusHighlight_TCL_DECLARED
#define TkDrawInsetFocusHighlight_TCL_DECLARED
/* 18 */
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(TkWindow *winPtr);
#endif
#ifndef TkFillPolygon_TCL_DECLARED
#define TkFillPolygon_TCL_DECLARED
/* 20 */
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(Tcl_Interp *interp,
				CONST char *option, CONST TkStateMap *mapPtr,
				CONST char *strKey);
#endif
#ifndef TkFindStateString_TCL_DECLARED
#define TkFindStateString_TCL_DECLARED
/* 22 */
EXTERN char *		TkFindStateString(CONST TkStateMap *mapPtr,
				int numKey);
#endif
#ifndef TkFocusDeadWindow_TCL_DECLARED
#define TkFocusDeadWindow_TCL_DECLARED
/* 23 */
EXTERN void		TkFocusDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkFocusFilterEvent_TCL_DECLARED
#define TkFocusFilterEvent_TCL_DECLARED
/* 24 */
EXTERN int		TkFocusFilterEvent(TkWindow *winPtr,
				XEvent *eventPtr);
#endif
#ifndef TkFocusKeyEvent_TCL_DECLARED
#define TkFocusKeyEvent_TCL_DECLARED
/* 25 */
EXTERN TkWindow *	TkFocusKeyEvent(TkWindow *winPtr, XEvent *eventPtr);
#endif
#ifndef TkFontPkgInit_TCL_DECLARED
#define TkFontPkgInit_TCL_DECLARED
/* 26 */
EXTERN void		TkFontPkgInit(TkMainInfo *mainPtr);
#endif
#ifndef TkFontPkgFree_TCL_DECLARED
#define TkFontPkgFree_TCL_DECLARED
/* 27 */
EXTERN void		TkFontPkgFree(TkMainInfo *mainPtr);
#endif
#ifndef TkFreeBindingTags_TCL_DECLARED
#define TkFreeBindingTags_TCL_DECLARED
/* 28 */
EXTERN void		TkFreeBindingTags(TkWindow *winPtr);
#endif
#ifndef TkpFreeCursor_TCL_DECLARED
#define TkpFreeCursor_TCL_DECLARED
/* 29 */
EXTERN void		TkpFreeCursor(TkCursor *cursorPtr);
#endif
#ifndef TkGetBitmapData_TCL_DECLARED
#define TkGetBitmapData_TCL_DECLARED
/* 30 */
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(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(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_Uid string);
#endif
#ifndef TkGetDefaultScreenName_TCL_DECLARED
#define TkGetDefaultScreenName_TCL_DECLARED
/* 33 */
EXTERN CONST84_RETURN char * TkGetDefaultScreenName(Tcl_Interp *interp,
				CONST char *screenName);
#endif
#ifndef TkGetDisplay_TCL_DECLARED
#define TkGetDisplay_TCL_DECLARED
/* 34 */
EXTERN TkDisplay *	TkGetDisplay(Display *display);
#endif
#ifndef TkGetDisplayOf_TCL_DECLARED
#define TkGetDisplayOf_TCL_DECLARED
/* 35 */
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(TkWindow *winPtr);
#endif
#ifndef TkGetInterpNames_TCL_DECLARED
#define TkGetInterpNames_TCL_DECLARED
/* 37 */
EXTERN int		TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin);
#endif
#ifndef TkGetMiterPoints_TCL_DECLARED
#define TkGetMiterPoints_TCL_DECLARED
/* 38 */
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(Tk_Window tkwin, int *xPtr,
				int *yPtr);
#endif
#ifndef TkGetServerInfo_TCL_DECLARED
#define TkGetServerInfo_TCL_DECLARED
/* 40 */
EXTERN void		TkGetServerInfo(Tcl_Interp *interp, Tk_Window tkwin);
#endif
#ifndef TkGrabDeadWindow_TCL_DECLARED
#define TkGrabDeadWindow_TCL_DECLARED
/* 41 */
EXTERN void		TkGrabDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkGrabState_TCL_DECLARED
#define TkGrabState_TCL_DECLARED
/* 42 */
EXTERN int		TkGrabState(TkWindow *winPtr);
#endif
#ifndef TkIncludePoint_TCL_DECLARED
#define TkIncludePoint_TCL_DECLARED
/* 43 */
EXTERN void		TkIncludePoint(Tk_Item *itemPtr, double *pointPtr);
#endif
#ifndef TkInOutEvents_TCL_DECLARED
#define TkInOutEvents_TCL_DECLARED
/* 44 */
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(Tk_Window tkwin);
#endif
#ifndef TkKeysymToString_TCL_DECLARED
#define TkKeysymToString_TCL_DECLARED
/* 46 */
EXTERN char *		TkKeysymToString(KeySym keysym);
#endif
#ifndef TkLineToArea_TCL_DECLARED
#define TkLineToArea_TCL_DECLARED
/* 47 */
EXTERN int		TkLineToArea(double end1Ptr[], double end2Ptr[],
				double rectPtr[]);
#endif
#ifndef TkLineToPoint_TCL_DECLARED
#define TkLineToPoint_TCL_DECLARED
/* 48 */
EXTERN double		TkLineToPoint(double end1Ptr[], double end2Ptr[],
				double pointPtr[]);
#endif
#ifndef TkMakeBezierCurve_TCL_DECLARED
#define TkMakeBezierCurve_TCL_DECLARED
/* 49 */
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(Tcl_Interp *interp,
				Tk_Canvas canvas, double *pointPtr,
				int numPoints);
#endif
#ifndef TkOptionClassChanged_TCL_DECLARED
#define TkOptionClassChanged_TCL_DECLARED
/* 51 */
EXTERN void		TkOptionClassChanged(TkWindow *winPtr);
#endif
#ifndef TkOptionDeadWindow_TCL_DECLARED
#define TkOptionDeadWindow_TCL_DECLARED
/* 52 */
EXTERN void		TkOptionDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkOvalToArea_TCL_DECLARED
#define TkOvalToArea_TCL_DECLARED
/* 53 */
EXTERN int		TkOvalToArea(double *ovalPtr, double *rectPtr);
#endif
#ifndef TkOvalToPoint_TCL_DECLARED
#define TkOvalToPoint_TCL_DECLARED
/* 54 */
EXTERN double		TkOvalToPoint(double ovalPtr[], double width,
				int filled, double pointPtr[]);
#endif
#ifndef TkpChangeFocus_TCL_DECLARED
#define TkpChangeFocus_TCL_DECLARED
/* 55 */
EXTERN int		TkpChangeFocus(TkWindow *winPtr, int force);
#endif
#ifndef TkpCloseDisplay_TCL_DECLARED
#define TkpCloseDisplay_TCL_DECLARED
/* 56 */
EXTERN void		TkpCloseDisplay(TkDisplay *dispPtr);
#endif
#ifndef TkpClaimFocus_TCL_DECLARED
#define TkpClaimFocus_TCL_DECLARED
/* 57 */
EXTERN void		TkpClaimFocus(TkWindow *topLevelPtr, int force);
#endif
#ifndef TkpDisplayWarning_TCL_DECLARED
#define TkpDisplayWarning_TCL_DECLARED
/* 58 */
EXTERN void		TkpDisplayWarning(CONST char *msg, CONST char *title);
#endif
#ifndef TkpGetAppName_TCL_DECLARED
#define TkpGetAppName_TCL_DECLARED
/* 59 */
EXTERN void		TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name);
#endif
#ifndef TkpGetOtherWindow_TCL_DECLARED
#define TkpGetOtherWindow_TCL_DECLARED
/* 60 */
EXTERN TkWindow *	TkpGetOtherWindow(TkWindow *winPtr);
#endif
#ifndef TkpGetWrapperWindow_TCL_DECLARED
#define TkpGetWrapperWindow_TCL_DECLARED
/* 61 */
EXTERN TkWindow *	TkpGetWrapperWindow(TkWindow *winPtr);
#endif
#ifndef TkpInit_TCL_DECLARED
#define TkpInit_TCL_DECLARED
/* 62 */
EXTERN int		TkpInit(Tcl_Interp *interp);
#endif
#ifndef TkpInitializeMenuBindings_TCL_DECLARED
#define TkpInitializeMenuBindings_TCL_DECLARED
/* 63 */
EXTERN void		TkpInitializeMenuBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable);
#endif
#ifndef TkpMakeContainer_TCL_DECLARED
#define TkpMakeContainer_TCL_DECLARED
/* 64 */
EXTERN void		TkpMakeContainer(Tk_Window tkwin);
#endif
#ifndef TkpMakeMenuWindow_TCL_DECLARED
#define TkpMakeMenuWindow_TCL_DECLARED
/* 65 */
EXTERN void		TkpMakeMenuWindow(Tk_Window tkwin, int transient);
#endif
#ifndef TkpMakeWindow_TCL_DECLARED
#define TkpMakeWindow_TCL_DECLARED
/* 66 */
EXTERN Window		TkpMakeWindow(TkWindow *winPtr, Window parent);
#endif
#ifndef TkpMenuNotifyToplevelCreate_TCL_DECLARED
#define TkpMenuNotifyToplevelCreate_TCL_DECLARED
/* 67 */
EXTERN void		TkpMenuNotifyToplevelCreate(Tcl_Interp *interp,
				char *menuName);
#endif
#ifndef TkpOpenDisplay_TCL_DECLARED
#define TkpOpenDisplay_TCL_DECLARED
/* 68 */
EXTERN TkDisplay *	TkpOpenDisplay(CONST char *display_name);
#endif
#ifndef TkPointerEvent_TCL_DECLARED
#define TkPointerEvent_TCL_DECLARED
/* 69 */
EXTERN int		TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr);
#endif
#ifndef TkPolygonToArea_TCL_DECLARED
#define TkPolygonToArea_TCL_DECLARED
/* 70 */
EXTERN int		TkPolygonToArea(double *polyPtr, int numPoints,
				double *rectPtr);
#endif
#ifndef TkPolygonToPoint_TCL_DECLARED
#define TkPolygonToPoint_TCL_DECLARED
/* 71 */
EXTERN double		TkPolygonToPoint(double *polyPtr, int numPoints,
				double *pointPtr);
#endif
#ifndef TkPositionInTree_TCL_DECLARED
#define TkPositionInTree_TCL_DECLARED
/* 72 */
EXTERN int		TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr);
#endif
#ifndef TkpRedirectKeyEvent_TCL_DECLARED
#define TkpRedirectKeyEvent_TCL_DECLARED
/* 73 */
EXTERN void		TkpRedirectKeyEvent(TkWindow *winPtr,
				XEvent *eventPtr);
#endif
#ifndef TkpSetMainMenubar_TCL_DECLARED
#define TkpSetMainMenubar_TCL_DECLARED
/* 74 */
EXTERN void		TkpSetMainMenubar(Tcl_Interp *interp,
				Tk_Window tkwin, char *menuName);
#endif
#ifndef TkpUseWindow_TCL_DECLARED
#define TkpUseWindow_TCL_DECLARED
/* 75 */
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(Window win,
				TkDisplay *dispPtr);
#endif
#ifndef TkQueueEventForAllChildren_TCL_DECLARED
#define TkQueueEventForAllChildren_TCL_DECLARED
/* 77 */
EXTERN void		TkQueueEventForAllChildren(TkWindow *winPtr,
				XEvent *eventPtr);
#endif
#ifndef TkReadBitmapFile_TCL_DECLARED
#define TkReadBitmapFile_TCL_DECLARED
/* 78 */
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);
#endif
#ifndef TkScrollWindow_TCL_DECLARED
#define TkScrollWindow_TCL_DECLARED
/* 79 */
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(TkWindow *winPtr);
#endif
#ifndef TkSelEventProc_TCL_DECLARED
#define TkSelEventProc_TCL_DECLARED
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
#endif
#ifndef TkSelInit_TCL_DECLARED
#define TkSelInit_TCL_DECLARED
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
#endif
#ifndef TkSelPropProc_TCL_DECLARED
#define TkSelPropProc_TCL_DECLARED
/* 83 */
EXTERN void		TkSelPropProc(XEvent *eventPtr);
#endif
/* Slot 84 is reserved */
#ifndef TkSetWindowMenuBar_TCL_DECLARED
#define TkSetWindowMenuBar_TCL_DECLARED
/* 85 */
EXTERN void		TkSetWindowMenuBar(Tcl_Interp *interp,
				Tk_Window tkwin, char *oldMenuName,
				char *menuName);
#endif
#ifndef TkStringToKeysym_TCL_DECLARED
#define TkStringToKeysym_TCL_DECLARED
/* 86 */
EXTERN KeySym		TkStringToKeysym(char *name);
#endif
#ifndef TkThickPolyLineToArea_TCL_DECLARED
#define TkThickPolyLineToArea_TCL_DECLARED
/* 87 */
EXTERN int		TkThickPolyLineToArea(double *coordPtr,
				int numPoints, double width, int capStyle,
				int joinStyle, double *rectPtr);
#endif
#ifndef TkWmAddToColormapWindows_TCL_DECLARED
#define TkWmAddToColormapWindows_TCL_DECLARED
/* 88 */
EXTERN void		TkWmAddToColormapWindows(TkWindow *winPtr);
#endif
#ifndef TkWmDeadWindow_TCL_DECLARED
#define TkWmDeadWindow_TCL_DECLARED
/* 89 */
EXTERN void		TkWmDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkWmFocusToplevel_TCL_DECLARED
#define TkWmFocusToplevel_TCL_DECLARED
/* 90 */
EXTERN TkWindow *	TkWmFocusToplevel(TkWindow *winPtr);
#endif
#ifndef TkWmMapWindow_TCL_DECLARED
#define TkWmMapWindow_TCL_DECLARED
/* 91 */
EXTERN void		TkWmMapWindow(TkWindow *winPtr);
#endif
#ifndef TkWmNewWindow_TCL_DECLARED
#define TkWmNewWindow_TCL_DECLARED
/* 92 */
EXTERN void		TkWmNewWindow(TkWindow *winPtr);
#endif
#ifndef TkWmProtocolEventProc_TCL_DECLARED
#define TkWmProtocolEventProc_TCL_DECLARED
/* 93 */
EXTERN void		TkWmProtocolEventProc(TkWindow *winPtr,
				XEvent *evenvPtr);
#endif
#ifndef TkWmRemoveFromColormapWindows_TCL_DECLARED
#define TkWmRemoveFromColormapWindows_TCL_DECLARED
/* 94 */
EXTERN void		TkWmRemoveFromColormapWindows(TkWindow *winPtr);
#endif
#ifndef TkWmRestackToplevel_TCL_DECLARED
#define TkWmRestackToplevel_TCL_DECLARED
/* 95 */
EXTERN void		TkWmRestackToplevel(TkWindow *winPtr, int aboveBelow,
				TkWindow *otherPtr);
#endif
#ifndef TkWmSetClass_TCL_DECLARED
#define TkWmSetClass_TCL_DECLARED
/* 96 */
EXTERN void		TkWmSetClass(TkWindow *winPtr);
#endif
#ifndef TkWmUnmapWindow_TCL_DECLARED
#define TkWmUnmapWindow_TCL_DECLARED
/* 97 */
EXTERN void		TkWmUnmapWindow(TkWindow *winPtr);
#endif
#ifndef TkDebugBitmap_TCL_DECLARED
#define TkDebugBitmap_TCL_DECLARED
/* 98 */
EXTERN Tcl_Obj *	TkDebugBitmap(Tk_Window tkwin, char *name);
#endif
#ifndef TkDebugBorder_TCL_DECLARED
#define TkDebugBorder_TCL_DECLARED
/* 99 */
EXTERN Tcl_Obj *	TkDebugBorder(Tk_Window tkwin, char *name);
#endif
#ifndef TkDebugCursor_TCL_DECLARED
#define TkDebugCursor_TCL_DECLARED
/* 100 */
EXTERN Tcl_Obj *	TkDebugCursor(Tk_Window tkwin, char *name);
#endif
#ifndef TkDebugColor_TCL_DECLARED
#define TkDebugColor_TCL_DECLARED
/* 101 */
EXTERN Tcl_Obj *	TkDebugColor(Tk_Window tkwin, char *name);
#endif
#ifndef TkDebugConfig_TCL_DECLARED
#define TkDebugConfig_TCL_DECLARED
/* 102 */
EXTERN Tcl_Obj *	TkDebugConfig(Tcl_Interp *interp,
				Tk_OptionTable table);
#endif
#ifndef TkDebugFont_TCL_DECLARED
#define TkDebugFont_TCL_DECLARED
/* 103 */
EXTERN Tcl_Obj *	TkDebugFont(Tk_Window tkwin, char *name);
#endif
#ifndef TkFindStateNumObj_TCL_DECLARED
#define TkFindStateNumObj_TCL_DECLARED
/* 104 */
EXTERN int		TkFindStateNumObj(Tcl_Interp *interp,
				Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr,
				Tcl_Obj *keyPtr);
#endif
#ifndef TkGetBitmapPredefTable_TCL_DECLARED
#define TkGetBitmapPredefTable_TCL_DECLARED
/* 105 */
EXTERN Tcl_HashTable *	TkGetBitmapPredefTable(void);
#endif
#ifndef TkGetDisplayList_TCL_DECLARED
#define TkGetDisplayList_TCL_DECLARED
/* 106 */
EXTERN TkDisplay *	TkGetDisplayList(void);
#endif
#ifndef TkGetMainInfoList_TCL_DECLARED
#define TkGetMainInfoList_TCL_DECLARED
/* 107 */
EXTERN TkMainInfo *	TkGetMainInfoList(void);
#endif
#ifndef TkGetWindowFromObj_TCL_DECLARED
#define TkGetWindowFromObj_TCL_DECLARED
/* 108 */
EXTERN int		TkGetWindowFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);
#endif
#ifndef TkpGetString_TCL_DECLARED
#define TkpGetString_TCL_DECLARED
/* 109 */
EXTERN char *		TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);
#endif
#ifndef TkpGetSubFonts_TCL_DECLARED
#define TkpGetSubFonts_TCL_DECLARED
/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
#endif
#ifndef TkpGetSystemDefault_TCL_DECLARED
#define TkpGetSystemDefault_TCL_DECLARED
/* 111 */
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(void);
#endif
#ifndef TkClipBox_TCL_DECLARED
#define TkClipBox_TCL_DECLARED
/* 113 */
EXTERN void		TkClipBox(TkRegion rgn, XRectangle *rect_return);
#endif
#ifndef TkCreateRegion_TCL_DECLARED
#define TkCreateRegion_TCL_DECLARED
/* 114 */
EXTERN TkRegion		TkCreateRegion(void);
#endif
#ifndef TkDestroyRegion_TCL_DECLARED
#define TkDestroyRegion_TCL_DECLARED
/* 115 */
EXTERN void		TkDestroyRegion(TkRegion rgn);
#endif
#ifndef TkIntersectRegion_TCL_DECLARED
#define TkIntersectRegion_TCL_DECLARED
/* 116 */
EXTERN void		TkIntersectRegion(TkRegion sra, TkRegion srcb,
				TkRegion dr_return);
#endif
#ifndef TkRectInRegion_TCL_DECLARED
#define TkRectInRegion_TCL_DECLARED
/* 117 */
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(Display *display, GC gc, TkRegion rgn);
#endif
#ifndef TkUnionRectWithRegion_TCL_DECLARED
#define TkUnionRectWithRegion_TCL_DECLARED
/* 119 */
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(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(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(Display *display,
				CONST char *name, int *width, int *height);
#endif
#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
#ifndef TkpDrawHighlightBorder_TCL_DECLARED
#define TkpDrawHighlightBorder_TCL_DECLARED
/* 135 */
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(TkWindow *winPtr, int force);
#endif
#ifndef TkpSetKeycodeAndState_TCL_DECLARED
#define TkpSetKeycodeAndState_TCL_DECLARED
/* 137 */
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);
#endif
#ifndef TkpGetKeySym_TCL_DECLARED
#define TkpGetKeySym_TCL_DECLARED
/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);
#endif
#ifndef TkpInitKeymapInfo_TCL_DECLARED
#define TkpInitKeymapInfo_TCL_DECLARED
/* 139 */
EXTERN void		TkpInitKeymapInfo(TkDisplay *dispPtr);
#endif
#ifndef TkPhotoGetValidRegion_TCL_DECLARED
#define TkPhotoGetValidRegion_TCL_DECLARED
/* 140 */
EXTERN TkRegion		TkPhotoGetValidRegion(Tk_PhotoHandle handle);
#endif
#ifndef TkWmStackorderToplevel_TCL_DECLARED
#define TkWmStackorderToplevel_TCL_DECLARED
/* 141 */
EXTERN TkWindow **	TkWmStackorderToplevel(TkWindow *parentPtr);
#endif
#ifndef TkFocusFree_TCL_DECLARED
#define TkFocusFree_TCL_DECLARED
/* 142 */
EXTERN void		TkFocusFree(TkMainInfo *mainPtr);
#endif
#ifndef TkClipCleanup_TCL_DECLARED
#define TkClipCleanup_TCL_DECLARED
/* 143 */
EXTERN void		TkClipCleanup(TkDisplay *dispPtr);
#endif
#ifndef TkGCCleanup_TCL_DECLARED
#define TkGCCleanup_TCL_DECLARED
/* 144 */
EXTERN void		TkGCCleanup(TkDisplay *dispPtr);
#endif
#ifndef TkSubtractRegion_TCL_DECLARED
#define TkSubtractRegion_TCL_DECLARED
/* 145 */
EXTERN void		TkSubtractRegion(TkRegion sra, TkRegion srcb,
				TkRegion dr_return);
#endif
#ifndef TkStylePkgInit_TCL_DECLARED
#define TkStylePkgInit_TCL_DECLARED
/* 146 */
EXTERN void		TkStylePkgInit(TkMainInfo *mainPtr);
#endif
#ifndef TkStylePkgFree_TCL_DECLARED
#define TkStylePkgFree_TCL_DECLARED
/* 147 */
EXTERN void		TkStylePkgFree(TkMainInfo *mainPtr);
#endif
#ifndef TkToplevelWindowForCommand_TCL_DECLARED
#define TkToplevelWindowForCommand_TCL_DECLARED
/* 148 */
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(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(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
/* Slot 181 is reserved */




/* Slot 182 is reserved */




/* Slot 183 is reserved */



/* Slot 184 is reserved */





/* Slot 185 is reserved */


#ifndef TkUnusedStubEntry_TCL_DECLARED
#define TkUnusedStubEntry_TCL_DECLARED
/* 186 */
EXTERN void		TkUnusedStubEntry(void);
#endif





typedef struct TkIntStubs {
    int magic;
    struct TkIntStubHooks *hooks;

    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) (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;
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    VOID *reserved121;
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    VOID *reserved121; /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpCreateNativeBitmap) (Display *display, CONST char *source); /* 121 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
    VOID *reserved122;
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    VOID *reserved122;
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    VOID *reserved122; /* Dummy entry for stubs table backwards compatibility */
    void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
    VOID *reserved123;
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
    VOID *reserved124;
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    VOID *reserved124;
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    VOID *reserved124; /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpGetNativeAppBitmap) (Display *display, CONST char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
    VOID *reserved125;
    VOID *reserved126;
    VOID *reserved127;
    VOID *reserved128;
    VOID *reserved129;
    VOID *reserved130;
    VOID *reserved131;
    VOID *reserved132;
    VOID *reserved133;
    VOID *reserved134;
    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 */





    VOID *reserved181;
    VOID *reserved182;

    VOID *reserved183;





    VOID *reserved184;


    VOID *reserved185;


    void (*tkUnusedStubEntry) (void); /* 186 */


} TkIntStubs;

extern TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)

/*
 * Inline function declarations:
 */

#ifndef TkAllocWindow
#define TkAllocWindow \
	(tkIntStubsPtr->tkAllocWindow) /* 0 */
#endif
#ifndef TkBezierPoints
#define TkBezierPoints \
	(tkIntStubsPtr->tkBezierPoints) /* 1 */
#endif
#ifndef TkBezierScreenPoints
#define TkBezierScreenPoints \
	(tkIntStubsPtr->tkBezierScreenPoints) /* 2 */

#endif
#ifndef TkBindDeadWindow
#define TkBindDeadWindow \
	(tkIntStubsPtr->tkBindDeadWindow) /* 3 */
#endif
#ifndef TkBindEventProc
#define TkBindEventProc \
	(tkIntStubsPtr->tkBindEventProc) /* 4 */
#endif
#ifndef TkBindFree
#define TkBindFree \
	(tkIntStubsPtr->tkBindFree) /* 5 */
#endif
#ifndef TkBindInit
#define TkBindInit \
	(tkIntStubsPtr->tkBindInit) /* 6 */
#endif
#ifndef TkChangeEventWindow
#define TkChangeEventWindow \
	(tkIntStubsPtr->tkChangeEventWindow) /* 7 */
#endif
#ifndef TkClipInit
#define TkClipInit \
	(tkIntStubsPtr->tkClipInit) /* 8 */
#endif
#ifndef TkComputeAnchor
#define TkComputeAnchor \
	(tkIntStubsPtr->tkComputeAnchor) /* 9 */


#endif
#ifndef TkCopyAndGlobalEval
#define TkCopyAndGlobalEval \
	(tkIntStubsPtr->tkCopyAndGlobalEval) /* 10 */
#endif
#ifndef TkCreateBindingProcedure
#define TkCreateBindingProcedure \
	(tkIntStubsPtr->tkCreateBindingProcedure) /* 11 */
#endif
#ifndef TkCreateCursorFromData
#define TkCreateCursorFromData \
	(tkIntStubsPtr->tkCreateCursorFromData) /* 12 */
#endif
#ifndef TkCreateFrame
#define TkCreateFrame \
	(tkIntStubsPtr->tkCreateFrame) /* 13 */
#endif
#ifndef TkCreateMainWindow
#define TkCreateMainWindow \
	(tkIntStubsPtr->tkCreateMainWindow) /* 14 */
#endif
#ifndef TkCurrentTime
#define TkCurrentTime \
	(tkIntStubsPtr->tkCurrentTime) /* 15 */
#endif
#ifndef TkDeleteAllImages
#define TkDeleteAllImages \
	(tkIntStubsPtr->tkDeleteAllImages) /* 16 */
#endif
#ifndef TkDoConfigureNotify
#define TkDoConfigureNotify \
	(tkIntStubsPtr->tkDoConfigureNotify) /* 17 */
#endif
#ifndef TkDrawInsetFocusHighlight
#define TkDrawInsetFocusHighlight \
	(tkIntStubsPtr->tkDrawInsetFocusHighlight) /* 18 */
#endif
#ifndef TkEventDeadWindow
#define TkEventDeadWindow \
	(tkIntStubsPtr->tkEventDeadWindow) /* 19 */
#endif
#ifndef TkFillPolygon
#define TkFillPolygon \
	(tkIntStubsPtr->tkFillPolygon) /* 20 */
#endif
#ifndef TkFindStateNum
#define TkFindStateNum \
	(tkIntStubsPtr->tkFindStateNum) /* 21 */
#endif
#ifndef TkFindStateString
#define TkFindStateString \
	(tkIntStubsPtr->tkFindStateString) /* 22 */
#endif
#ifndef TkFocusDeadWindow
#define TkFocusDeadWindow \
	(tkIntStubsPtr->tkFocusDeadWindow) /* 23 */
#endif
#ifndef TkFocusFilterEvent
#define TkFocusFilterEvent \
	(tkIntStubsPtr->tkFocusFilterEvent) /* 24 */
#endif
#ifndef TkFocusKeyEvent
#define TkFocusKeyEvent \
	(tkIntStubsPtr->tkFocusKeyEvent) /* 25 */
#endif
#ifndef TkFontPkgInit
#define TkFontPkgInit \
	(tkIntStubsPtr->tkFontPkgInit) /* 26 */
#endif
#ifndef TkFontPkgFree
#define TkFontPkgFree \
	(tkIntStubsPtr->tkFontPkgFree) /* 27 */
#endif
#ifndef TkFreeBindingTags
#define TkFreeBindingTags \
	(tkIntStubsPtr->tkFreeBindingTags) /* 28 */
#endif
#ifndef TkpFreeCursor
#define TkpFreeCursor \
	(tkIntStubsPtr->tkpFreeCursor) /* 29 */
#endif
#ifndef TkGetBitmapData
#define TkGetBitmapData \
	(tkIntStubsPtr->tkGetBitmapData) /* 30 */
#endif
#ifndef TkGetButtPoints
#define TkGetButtPoints \
	(tkIntStubsPtr->tkGetButtPoints) /* 31 */
#endif
#ifndef TkGetCursorByName
#define TkGetCursorByName \
	(tkIntStubsPtr->tkGetCursorByName) /* 32 */
#endif
#ifndef TkGetDefaultScreenName
#define TkGetDefaultScreenName \
	(tkIntStubsPtr->tkGetDefaultScreenName) /* 33 */
#endif
#ifndef TkGetDisplay
#define TkGetDisplay \
	(tkIntStubsPtr->tkGetDisplay) /* 34 */
#endif
#ifndef TkGetDisplayOf
#define TkGetDisplayOf \
	(tkIntStubsPtr->tkGetDisplayOf) /* 35 */
#endif
#ifndef TkGetFocusWin
#define TkGetFocusWin \
	(tkIntStubsPtr->tkGetFocusWin) /* 36 */
#endif
#ifndef TkGetInterpNames
#define TkGetInterpNames \
	(tkIntStubsPtr->tkGetInterpNames) /* 37 */
#endif
#ifndef TkGetMiterPoints
#define TkGetMiterPoints \
	(tkIntStubsPtr->tkGetMiterPoints) /* 38 */
#endif
#ifndef TkGetPointerCoords
#define TkGetPointerCoords \
	(tkIntStubsPtr->tkGetPointerCoords) /* 39 */
#endif
#ifndef TkGetServerInfo
#define TkGetServerInfo \
	(tkIntStubsPtr->tkGetServerInfo) /* 40 */
#endif
#ifndef TkGrabDeadWindow
#define TkGrabDeadWindow \
	(tkIntStubsPtr->tkGrabDeadWindow) /* 41 */
#endif
#ifndef TkGrabState
#define TkGrabState \
	(tkIntStubsPtr->tkGrabState) /* 42 */
#endif
#ifndef TkIncludePoint
#define TkIncludePoint \
	(tkIntStubsPtr->tkIncludePoint) /* 43 */
#endif
#ifndef TkInOutEvents
#define TkInOutEvents \
	(tkIntStubsPtr->tkInOutEvents) /* 44 */
#endif
#ifndef TkInstallFrameMenu
#define TkInstallFrameMenu \
	(tkIntStubsPtr->tkInstallFrameMenu) /* 45 */
#endif
#ifndef TkKeysymToString
#define TkKeysymToString \
	(tkIntStubsPtr->tkKeysymToString) /* 46 */
#endif
#ifndef TkLineToArea
#define TkLineToArea \
	(tkIntStubsPtr->tkLineToArea) /* 47 */
#endif
#ifndef TkLineToPoint
#define TkLineToPoint \
	(tkIntStubsPtr->tkLineToPoint) /* 48 */
#endif
#ifndef TkMakeBezierCurve
#define TkMakeBezierCurve \
	(tkIntStubsPtr->tkMakeBezierCurve) /* 49 */
#endif
#ifndef TkMakeBezierPostscript
#define TkMakeBezierPostscript \
	(tkIntStubsPtr->tkMakeBezierPostscript) /* 50 */
#endif
#ifndef TkOptionClassChanged
#define TkOptionClassChanged \
	(tkIntStubsPtr->tkOptionClassChanged) /* 51 */
#endif
#ifndef TkOptionDeadWindow
#define TkOptionDeadWindow \
	(tkIntStubsPtr->tkOptionDeadWindow) /* 52 */
#endif
#ifndef TkOvalToArea
#define TkOvalToArea \
	(tkIntStubsPtr->tkOvalToArea) /* 53 */
#endif
#ifndef TkOvalToPoint
#define TkOvalToPoint \
	(tkIntStubsPtr->tkOvalToPoint) /* 54 */
#endif
#ifndef TkpChangeFocus
#define TkpChangeFocus \
	(tkIntStubsPtr->tkpChangeFocus) /* 55 */
#endif
#ifndef TkpCloseDisplay
#define TkpCloseDisplay \
	(tkIntStubsPtr->tkpCloseDisplay) /* 56 */
#endif
#ifndef TkpClaimFocus
#define TkpClaimFocus \
	(tkIntStubsPtr->tkpClaimFocus) /* 57 */
#endif
#ifndef TkpDisplayWarning
#define TkpDisplayWarning \
	(tkIntStubsPtr->tkpDisplayWarning) /* 58 */
#endif
#ifndef TkpGetAppName
#define TkpGetAppName \
	(tkIntStubsPtr->tkpGetAppName) /* 59 */
#endif
#ifndef TkpGetOtherWindow
#define TkpGetOtherWindow \
	(tkIntStubsPtr->tkpGetOtherWindow) /* 60 */
#endif
#ifndef TkpGetWrapperWindow
#define TkpGetWrapperWindow \
	(tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */
#endif
#ifndef TkpInit
#define TkpInit \
	(tkIntStubsPtr->tkpInit) /* 62 */
#endif
#ifndef TkpInitializeMenuBindings
#define TkpInitializeMenuBindings \
	(tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */
#endif
#ifndef TkpMakeContainer
#define TkpMakeContainer \
	(tkIntStubsPtr->tkpMakeContainer) /* 64 */
#endif
#ifndef TkpMakeMenuWindow
#define TkpMakeMenuWindow \
	(tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */
#endif
#ifndef TkpMakeWindow
#define TkpMakeWindow \
	(tkIntStubsPtr->tkpMakeWindow) /* 66 */
#endif
#ifndef TkpMenuNotifyToplevelCreate
#define TkpMenuNotifyToplevelCreate \
	(tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */
#endif
#ifndef TkpOpenDisplay
#define TkpOpenDisplay \
	(tkIntStubsPtr->tkpOpenDisplay) /* 68 */
#endif
#ifndef TkPointerEvent
#define TkPointerEvent \
	(tkIntStubsPtr->tkPointerEvent) /* 69 */
#endif
#ifndef TkPolygonToArea
#define TkPolygonToArea \
	(tkIntStubsPtr->tkPolygonToArea) /* 70 */
#endif
#ifndef TkPolygonToPoint
#define TkPolygonToPoint \
	(tkIntStubsPtr->tkPolygonToPoint) /* 71 */
#endif
#ifndef TkPositionInTree
#define TkPositionInTree \
	(tkIntStubsPtr->tkPositionInTree) /* 72 */
#endif
#ifndef TkpRedirectKeyEvent
#define TkpRedirectKeyEvent \
	(tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */
#endif
#ifndef TkpSetMainMenubar
#define TkpSetMainMenubar \
	(tkIntStubsPtr->tkpSetMainMenubar) /* 74 */
#endif
#ifndef TkpUseWindow
#define TkpUseWindow \
	(tkIntStubsPtr->tkpUseWindow) /* 75 */
#endif
#ifndef TkpWindowWasRecentlyDeleted
#define TkpWindowWasRecentlyDeleted \
	(tkIntStubsPtr->tkpWindowWasRecentlyDeleted) /* 76 */
#endif
#ifndef TkQueueEventForAllChildren
#define TkQueueEventForAllChildren \
	(tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */
#endif
#ifndef TkReadBitmapFile
#define TkReadBitmapFile \
	(tkIntStubsPtr->tkReadBitmapFile) /* 78 */
#endif
#ifndef TkScrollWindow
#define TkScrollWindow \
	(tkIntStubsPtr->tkScrollWindow) /* 79 */
#endif
#ifndef TkSelDeadWindow
#define TkSelDeadWindow \
	(tkIntStubsPtr->tkSelDeadWindow) /* 80 */
#endif
#ifndef TkSelEventProc
#define TkSelEventProc \
	(tkIntStubsPtr->tkSelEventProc) /* 81 */
#endif
#ifndef TkSelInit
#define TkSelInit \
	(tkIntStubsPtr->tkSelInit) /* 82 */
#endif
#ifndef TkSelPropProc
#define TkSelPropProc \
	(tkIntStubsPtr->tkSelPropProc) /* 83 */
#endif
/* Slot 84 is reserved */
#ifndef TkSetWindowMenuBar
#define TkSetWindowMenuBar \
	(tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */
#endif
#ifndef TkStringToKeysym
#define TkStringToKeysym \
	(tkIntStubsPtr->tkStringToKeysym) /* 86 */
#endif
#ifndef TkThickPolyLineToArea
#define TkThickPolyLineToArea \
	(tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */
#endif
#ifndef TkWmAddToColormapWindows
#define TkWmAddToColormapWindows \
	(tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */
#endif
#ifndef TkWmDeadWindow
#define TkWmDeadWindow \
	(tkIntStubsPtr->tkWmDeadWindow) /* 89 */
#endif
#ifndef TkWmFocusToplevel
#define TkWmFocusToplevel \
	(tkIntStubsPtr->tkWmFocusToplevel) /* 90 */
#endif
#ifndef TkWmMapWindow
#define TkWmMapWindow \
	(tkIntStubsPtr->tkWmMapWindow) /* 91 */
#endif
#ifndef TkWmNewWindow
#define TkWmNewWindow \
	(tkIntStubsPtr->tkWmNewWindow) /* 92 */
#endif
#ifndef TkWmProtocolEventProc
#define TkWmProtocolEventProc \
	(tkIntStubsPtr->tkWmProtocolEventProc) /* 93 */
#endif
#ifndef TkWmRemoveFromColormapWindows
#define TkWmRemoveFromColormapWindows \
	(tkIntStubsPtr->tkWmRemoveFromColormapWindows) /* 94 */
#endif
#ifndef TkWmRestackToplevel
#define TkWmRestackToplevel \
	(tkIntStubsPtr->tkWmRestackToplevel) /* 95 */
#endif
#ifndef TkWmSetClass
#define TkWmSetClass \
	(tkIntStubsPtr->tkWmSetClass) /* 96 */
#endif
#ifndef TkWmUnmapWindow
#define TkWmUnmapWindow \
	(tkIntStubsPtr->tkWmUnmapWindow) /* 97 */
#endif
#ifndef TkDebugBitmap
#define TkDebugBitmap \
	(tkIntStubsPtr->tkDebugBitmap) /* 98 */
#endif
#ifndef TkDebugBorder
#define TkDebugBorder \
	(tkIntStubsPtr->tkDebugBorder) /* 99 */
#endif
#ifndef TkDebugCursor
#define TkDebugCursor \
	(tkIntStubsPtr->tkDebugCursor) /* 100 */
#endif
#ifndef TkDebugColor
#define TkDebugColor \
	(tkIntStubsPtr->tkDebugColor) /* 101 */
#endif
#ifndef TkDebugConfig
#define TkDebugConfig \
	(tkIntStubsPtr->tkDebugConfig) /* 102 */
#endif
#ifndef TkDebugFont
#define TkDebugFont \
	(tkIntStubsPtr->tkDebugFont) /* 103 */
#endif
#ifndef TkFindStateNumObj
#define TkFindStateNumObj \
	(tkIntStubsPtr->tkFindStateNumObj) /* 104 */
#endif
#ifndef TkGetBitmapPredefTable
#define TkGetBitmapPredefTable \
	(tkIntStubsPtr->tkGetBitmapPredefTable) /* 105 */
#endif
#ifndef TkGetDisplayList
#define TkGetDisplayList \
	(tkIntStubsPtr->tkGetDisplayList) /* 106 */
#endif
#ifndef TkGetMainInfoList
#define TkGetMainInfoList \
	(tkIntStubsPtr->tkGetMainInfoList) /* 107 */
#endif
#ifndef TkGetWindowFromObj
#define TkGetWindowFromObj \
	(tkIntStubsPtr->tkGetWindowFromObj) /* 108 */
#endif
#ifndef TkpGetString
#define TkpGetString \
	(tkIntStubsPtr->tkpGetString) /* 109 */
#endif
#ifndef TkpGetSubFonts
#define TkpGetSubFonts \
	(tkIntStubsPtr->tkpGetSubFonts) /* 110 */
#endif
#ifndef TkpGetSystemDefault
#define TkpGetSystemDefault \
	(tkIntStubsPtr->tkpGetSystemDefault) /* 111 */
#endif
#ifndef TkpMenuThreadInit
#define TkpMenuThreadInit \
	(tkIntStubsPtr->tkpMenuThreadInit) /* 112 */
#endif
#ifndef TkClipBox
#define TkClipBox \
	(tkIntStubsPtr->tkClipBox) /* 113 */
#endif
#ifndef TkCreateRegion
#define TkCreateRegion \
	(tkIntStubsPtr->tkCreateRegion) /* 114 */
#endif
#ifndef TkDestroyRegion
#define TkDestroyRegion \
	(tkIntStubsPtr->tkDestroyRegion) /* 115 */
#endif
#ifndef TkIntersectRegion
#define TkIntersectRegion \
	(tkIntStubsPtr->tkIntersectRegion) /* 116 */
#endif
#ifndef TkRectInRegion
#define TkRectInRegion \
	(tkIntStubsPtr->tkRectInRegion) /* 117 */
#endif
#ifndef TkSetRegion
#define TkSetRegion \
	(tkIntStubsPtr->tkSetRegion) /* 118 */
#endif
#ifndef TkUnionRectWithRegion
#define TkUnionRectWithRegion \
	(tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */
#endif
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef TkpCreateNativeBitmap
#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */
#endif
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef TkpDefineNativeBitmaps
#define TkpDefineNativeBitmaps \
	(tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */
#endif
#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef TkpGetNativeAppBitmap
#define TkpGetNativeAppBitmap \
	(tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */
#endif
#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
#ifndef TkpDrawHighlightBorder
#define TkpDrawHighlightBorder \
	(tkIntStubsPtr->tkpDrawHighlightBorder) /* 135 */
#endif
#ifndef TkSetFocusWin
#define TkSetFocusWin \
	(tkIntStubsPtr->tkSetFocusWin) /* 136 */
#endif
#ifndef TkpSetKeycodeAndState
#define TkpSetKeycodeAndState \
	(tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */
#endif
#ifndef TkpGetKeySym
#define TkpGetKeySym \
	(tkIntStubsPtr->tkpGetKeySym) /* 138 */
#endif
#ifndef TkpInitKeymapInfo
#define TkpInitKeymapInfo \
	(tkIntStubsPtr->tkpInitKeymapInfo) /* 139 */
#endif
#ifndef TkPhotoGetValidRegion
#define TkPhotoGetValidRegion \
	(tkIntStubsPtr->tkPhotoGetValidRegion) /* 140 */
#endif
#ifndef TkWmStackorderToplevel
#define TkWmStackorderToplevel \
	(tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */
#endif
#ifndef TkFocusFree
#define TkFocusFree \
	(tkIntStubsPtr->tkFocusFree) /* 142 */
#endif
#ifndef TkClipCleanup
#define TkClipCleanup \
	(tkIntStubsPtr->tkClipCleanup) /* 143 */
#endif
#ifndef TkGCCleanup
#define TkGCCleanup \
	(tkIntStubsPtr->tkGCCleanup) /* 144 */
#endif
#ifndef TkSubtractRegion
#define TkSubtractRegion \
	(tkIntStubsPtr->tkSubtractRegion) /* 145 */
#endif
#ifndef TkStylePkgInit
#define TkStylePkgInit \
	(tkIntStubsPtr->tkStylePkgInit) /* 146 */
#endif
#ifndef TkStylePkgFree
#define TkStylePkgFree \
	(tkIntStubsPtr->tkStylePkgFree) /* 147 */
#endif
#ifndef TkToplevelWindowForCommand
#define TkToplevelWindowForCommand \
	(tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */
#endif
#ifndef TkGetOptionSpec
#define TkGetOptionSpec \
	(tkIntStubsPtr->tkGetOptionSpec) /* 149 */
#endif
#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
/* Slot 181 is reserved */
/* Slot 182 is reserved */
/* Slot 183 is reserved */
/* Slot 184 is reserved */
/* Slot 185 is reserved */
#ifndef TkUnusedStubEntry
#define TkUnusedStubEntry \
	(tkIntStubsPtr->tkUnusedStubEntry) /* 186 */
#endif



#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */

/* !END!: Do not edit above this line. */

#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__*/

#undef TkUnusedStubEntry
#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 */

#endif

#endif /* _TKINTDECLS */

Changes to generic/tkIntPlatDecls.h.

30
31
32
33
34
35
36
37


38
39
40

41


42
43
44



45
46



47
48



49
50



51
52
53



54
55



56
57



58
59



60
61



62
63



64
65



66
67
68



69
70
71



72
73
74



75
76
77



78
79



80
81



82
83



84
85
86
87



88
89



90
91
92



93
94
95



96
97



98
99



100
101
102



103
104



105
106



107
108



109
110



111
112
113




114
115



116
117



118
119



120
121



122
123
124
125




126



127
128



129
130



131
132



133
134



135
136



137
138



139
140



141
142
143
144
145
146
147
148
149


150
151
152


153
154
155
156
157
158



159
160



161
162



163
164



165
166
167




168



169
170



171
172



173




174
175

176


177
178

179


180
181



182
183



184
185
186

187
188


189
190
191
192




193
194



195
196



197
198



199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220



221
222
223


224
225



226
227
228
229

230
231
232
233
234
235

236
237
238
239
240



241





242



243













244
245
246
247
248
249


250
251
252



253
254



255
256




257



258

259
260




261
262

263
264
265
266



267
268
269


270
271




272
273
274
275



276
277




278
279
280
281
282


283
284
285
286
287


288
289



290
291




292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319



320
321



322
323



324
325



326
327



328






329



330
331



332










333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */


/* 0 */
EXTERN char *		TkAlignImageData(XImage *image, int alignment,
				int bitOrder);

/* Slot 1 is reserved */


/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);



/* 3 */
EXTERN unsigned long	TkpGetMS(void);



/* 4 */
EXTERN void		TkPointerDeadWindow(TkWindow *winPtr);



/* 5 */
EXTERN void		TkpPrintWindowId(char *buf, Window window);



/* 6 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);



/* 7 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);



/* 8 */
EXTERN void		TkpSetCursor(TkpCursor cursor);



/* 9 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);



/* 10 */
EXTERN void		TkSetPixmapColormap(Pixmap pixmap, Colormap colormap);



/* 11 */
EXTERN void		TkWinCancelMouseTimer(void);



/* 12 */
EXTERN void		TkWinClipboardRender(TkDisplay *dispPtr, UINT format);



/* 13 */
EXTERN LRESULT		TkWinEmbeddedEventProc(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam);



/* 14 */
EXTERN void		TkWinFillRect(HDC dc, int x, int y, int width,
				int height, int pixel);



/* 15 */
EXTERN COLORREF		TkWinGetBorderPixels(Tk_Window tkwin,
				Tk_3DBorder border, int which);



/* 16 */
EXTERN HDC		TkWinGetDrawableDC(Display *display, Drawable d,
				TkWinDCState *state);



/* 17 */
EXTERN int		TkWinGetModifierState(void);



/* 18 */
EXTERN HPALETTE		TkWinGetSystemPalette(void);



/* 19 */
EXTERN HWND		TkWinGetWrapperWindow(Tk_Window tkwin);



/* 20 */
EXTERN int		TkWinHandleMenuEvent(HWND *phwnd, UINT *pMessage,
				WPARAM *pwParam, LPARAM *plParam,
				LRESULT *plResult);



/* 21 */
EXTERN int		TkWinIndexOfColor(XColor *colorPtr);



/* 22 */
EXTERN void		TkWinReleaseDrawableDC(Drawable d, HDC hdc,
				TkWinDCState *state);



/* 23 */
EXTERN LRESULT		TkWinResendEvent(WNDPROC wndproc, HWND hwnd,
				XEvent *eventPtr);



/* 24 */
EXTERN HPALETTE		TkWinSelectPalette(HDC dc, Colormap colormap);



/* 25 */
EXTERN void		TkWinSetMenu(Tk_Window tkwin, HMENU hMenu);



/* 26 */
EXTERN void		TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd,
				int pos);



/* 27 */
EXTERN void		TkWinWmCleanup(HINSTANCE hInstance);



/* 28 */
EXTERN void		TkWinXCleanup(ClientData clientData);



/* 29 */
EXTERN void		TkWinXInit(HINSTANCE hInstance);



/* 30 */
EXTERN void		TkWinSetForegroundWindow(TkWindow *winPtr);



/* 31 */
EXTERN void		TkWinDialogDebug(int debug);
/* 32 */




EXTERN Tcl_Obj *	TkWinGetMenuSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);



/* 33 */
EXTERN int		TkWinGetPlatformId(void);



/* 34 */
EXTERN void		TkWinSetHINSTANCE(HINSTANCE hInstance);



/* 35 */
EXTERN int		TkWinGetPlatformTheme(void);



/* 36 */
EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam);
/* 37 */




EXTERN void		TkCreateXEventSource(void);



/* 38 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);



/* 39 */
EXTERN void		TkpSync(Display *display);



/* 40 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);



/* 41 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);



/* 42 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);



/* 43 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);



/* 44 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);



/* 45 */
EXTERN int		TkpTestsendCmd(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* Slot 46 is reserved */
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */


/* 0 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);


/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents_(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN void		TkPointerDeadWindow(TkWindow *winPtr);



/* 4 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);



/* 5 */
EXTERN void		TkpSetCursor(TkpCursor cursor);



/* 6 */
EXTERN void		TkpWmSetState(TkWindow *winPtr, int state);



/* 7 */
EXTERN void		TkAboutDlg(void);
/* 8 */




EXTERN unsigned int	TkMacOSXButtonKeyState(void);



/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);



/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);



/* Slot 11 is reserved */




/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);

/* Slot 13 is reserved */


/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);

/* Slot 15 is reserved */


/* 16 */
EXTERN Window		TkMacOSXGetXWindow(void *macWinPtr);



/* 17 */
EXTERN int		TkMacOSXGrowToplevel(void *whichWindow, XPoint start);



/* 18 */
EXTERN void		TkMacOSXHandleMenuSelect(short theMenu,
				unsigned short theItem, int optionKeyPressed);

/* Slot 19 is reserved */
/* Slot 20 is reserved */


/* 21 */
EXTERN void		TkMacOSXInvalidateWindow(MacDrawable *macWin,
				int flag);
/* 22 */




EXTERN int		TkMacOSXIsCharacterMissing(Tk_Font tkfont,
				unsigned int searchChar);



/* 23 */
EXTERN void		TkMacOSXMakeRealWindowExist(TkWindow *winPtr);



/* 24 */
EXTERN void *		TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);



/* 25 */
EXTERN void		TkMacOSXMenuClick(void);
/* Slot 26 is reserved */
/* 27 */

EXTERN int		TkMacOSXResizable(TkWindow *winPtr);
/* 28 */
EXTERN void		TkMacOSXSetHelpMenuItemCount(void);
/* 29 */
EXTERN void		TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
/* 30 */
EXTERN void		TkMacOSXSetUpClippingRgn(Drawable drawable);
/* 31 */
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* Slot 33 is reserved */
/* 34 */

EXTERN int		TkMacOSXUseMenuID(short macID);
/* 35 */
EXTERN Region		TkMacOSXVisableClipRgn(TkWindow *winPtr);
/* 36 */
EXTERN void		TkMacOSXWinBounds(TkWindow *winPtr, void *geometry);



/* 37 */
EXTERN void		TkMacOSXWindowOffset(void *wRef, int *xOffset,
				int *yOffset);


/* 38 */
EXTERN int		TkSetMacColor(unsigned long pixel, void *macColor);



/* 39 */
EXTERN void		TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
/* Slot 40 is reserved */
/* 41 */

EXTERN int		TkMacOSXZoomToplevel(void *whichWindow,
				short zoomPart);
/* 42 */
EXTERN Tk_Window	Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX,
				int rootY, int *newX, int *newY);
/* 43 */

EXTERN MacDrawable *	TkMacOSXContainerId(TkWindow *winPtr);
/* 44 */
EXTERN MacDrawable *	TkMacOSXGetHostToplevel(TkWindow *winPtr);
/* 45 */
EXTERN void		TkMacOSXPreprocessMenu(void);



/* 46 */





EXTERN int		TkpIsWindowFloating(void *window);



/* 47 */













EXTERN Tk_Window	TkpGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
EXTERN Tk_Window	TkMacOSXGetContainer(TkWindow *winPtr);
/* 50 */
EXTERN int		TkGenerateButtonEvent(int x, int y, Window window,


				unsigned int state);
/* 51 */
EXTERN void		TkGenWMDestroyEvent(Tk_Window tkwin);



/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);



/* 53 */
EXTERN unsigned long	TkpGetMS(void);




/* 54 */



EXTERN void *		TkMacOSXDrawable(Drawable drawable);

/* 55 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,




				const char *string, Window *idPtr);
#endif /* AQUA */

#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
/* 0 */
EXTERN void		TkCreateXEventSource(void);
/* Slot 1 is reserved */



/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);


/* 3 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);




/* 4 */
EXTERN void		TkpSync(Display *display);
/* 5 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);



/* 6 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);




/* 7 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
/* 8 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);


/* 9 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
/* 10 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
/* Slot 11 is reserved */


/* 12 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);



/* 13 */
EXTERN int		TkpTestsendCmd(ClientData clientData,




				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */
/* Slot 28 is reserved */
/* Slot 29 is reserved */
/* Slot 30 is reserved */
/* Slot 31 is reserved */
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
/* 38 */
EXTERN int		TkpCmapStressed_(Tk_Window tkwin, Colormap colormap);



/* 39 */
EXTERN void		TkpSync_(Display *display);



/* 40 */
EXTERN Window		TkUnixContainerId_(TkWindow *winPtr);



/* 41 */
EXTERN int		TkUnixDoOneXEvent_(Tcl_Time *timePtr);



/* 42 */
EXTERN void		TkUnixSetMenubar_(Tk_Window tkwin, Tk_Window menubar);



/* 43 */






EXTERN void		TkWmCleanup_(TkDisplay *dispPtr);



/* 44 */
EXTERN void		TkSendCleanup_(TkDisplay *dispPtr);



/* 45 */










EXTERN int		TkpTestsendCmd_(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);

#endif /* X11 */

typedef struct TkIntPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */
    void (*reserved1)(void);
    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 */







|
>
>



>

>
>



>
>
>


>
>
>


>
>
>


>
>
>


|
>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>



>
>
>



>
>
>



>
>
>


>
>
>


>
>
>


>
>
>




>
>
>


>
>
>



>
>
>



>
>
>


>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


<
>
>
>
>

|
>
>
>


>
>
>


>
>
>


>
>
>



<
>
>
>
>

>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


|
<
<
|
|


>
>



>
>
|
<
|
|


>
>
>


>
>
>


>
>
>


>
>
>


<
>
>
>
>

>
>
>


>
>
>


>
>
>
|
>
>
>
>


>

>
>

|
>

>
>

|
>
>
>

|
>
>
>



>


>
>



<
>
>
>
>


>
>
>


>
>
>

|
>
>
>


<
<
>
|
<
|
|
<
<
<
<
<
<
|
<
|
>
|
<
|
|
|
>
>
>
|
|
|
>
>
|
|
>
>
>
|
|
<
<
>
|
|
|
|
<
<
>
|
<
|
|
|
>
>
>
|
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
<
<
|
>
>
|
|
|
>
>
>
|
|
>
>
>
|
|
>
>
>
>
|
>
>
>
|
>
|
|
>
>
>
>
|
|
>
|
|
|
<
>
>
>
|
|
|
>
>
|
|
>
>
>
>
|
<
<
|
>
>
>
|
|
>
>
>
>
|
|
<
<
|
>
>
|
|
<
|
<
>
>
|
|
>
>
>
|
|
>
>
>
>
|
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
|
|
>
>
>
|
|
>
>
>
|
|
>
>
>
|
|
>
>
>
|
>
>
>
>
>
>
|
>
>
>
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
>




|

|

|




|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277


278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390


391
392

393
394






395

396
397
398

399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416


417
418
419
420
421


422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456


457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509


510
511
512
513
514
515
516
517
518
519
520
521


522
523
524
525
526

527

528
529
530
531
532
533
534
535
536
537
538
539
540
541




542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef TkAlignImageData_TCL_DECLARED
#define TkAlignImageData_TCL_DECLARED
/* 0 */
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(TkWindow *winPtr,
				int active);
#endif
#ifndef TkpGetMS_TCL_DECLARED
#define TkpGetMS_TCL_DECLARED
/* 3 */
EXTERN unsigned long	TkpGetMS(void);
#endif
#ifndef TkPointerDeadWindow_TCL_DECLARED
#define TkPointerDeadWindow_TCL_DECLARED
/* 4 */
EXTERN void		TkPointerDeadWindow(TkWindow *winPtr);
#endif
#ifndef TkpPrintWindowId_TCL_DECLARED
#define TkpPrintWindowId_TCL_DECLARED
/* 5 */
EXTERN void		TkpPrintWindowId(char *buf, Window window);
#endif
#ifndef TkpScanWindowId_TCL_DECLARED
#define TkpScanWindowId_TCL_DECLARED
/* 6 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				CONST char *string, Window *idPtr);
#endif
#ifndef TkpSetCapture_TCL_DECLARED
#define TkpSetCapture_TCL_DECLARED
/* 7 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);
#endif
#ifndef TkpSetCursor_TCL_DECLARED
#define TkpSetCursor_TCL_DECLARED
/* 8 */
EXTERN void		TkpSetCursor(TkpCursor cursor);
#endif
#ifndef TkpWmSetState_TCL_DECLARED
#define TkpWmSetState_TCL_DECLARED
/* 9 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);
#endif
#ifndef TkSetPixmapColormap_TCL_DECLARED
#define TkSetPixmapColormap_TCL_DECLARED
/* 10 */
EXTERN void		TkSetPixmapColormap(Pixmap pixmap, Colormap colormap);
#endif
#ifndef TkWinCancelMouseTimer_TCL_DECLARED
#define TkWinCancelMouseTimer_TCL_DECLARED
/* 11 */
EXTERN void		TkWinCancelMouseTimer(void);
#endif
#ifndef TkWinClipboardRender_TCL_DECLARED
#define TkWinClipboardRender_TCL_DECLARED
/* 12 */
EXTERN void		TkWinClipboardRender(TkDisplay *dispPtr, UINT format);
#endif
#ifndef TkWinEmbeddedEventProc_TCL_DECLARED
#define TkWinEmbeddedEventProc_TCL_DECLARED
/* 13 */
EXTERN LRESULT		TkWinEmbeddedEventProc(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam);
#endif
#ifndef TkWinFillRect_TCL_DECLARED
#define TkWinFillRect_TCL_DECLARED
/* 14 */
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(Tk_Window tkwin,
				Tk_3DBorder border, int which);
#endif
#ifndef TkWinGetDrawableDC_TCL_DECLARED
#define TkWinGetDrawableDC_TCL_DECLARED
/* 16 */
EXTERN HDC		TkWinGetDrawableDC(Display *display, Drawable d,
				TkWinDCState *state);
#endif
#ifndef TkWinGetModifierState_TCL_DECLARED
#define TkWinGetModifierState_TCL_DECLARED
/* 17 */
EXTERN int		TkWinGetModifierState(void);
#endif
#ifndef TkWinGetSystemPalette_TCL_DECLARED
#define TkWinGetSystemPalette_TCL_DECLARED
/* 18 */
EXTERN HPALETTE		TkWinGetSystemPalette(void);
#endif
#ifndef TkWinGetWrapperWindow_TCL_DECLARED
#define TkWinGetWrapperWindow_TCL_DECLARED
/* 19 */
EXTERN HWND		TkWinGetWrapperWindow(Tk_Window tkwin);
#endif
#ifndef TkWinHandleMenuEvent_TCL_DECLARED
#define TkWinHandleMenuEvent_TCL_DECLARED
/* 20 */
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(XColor *colorPtr);
#endif
#ifndef TkWinReleaseDrawableDC_TCL_DECLARED
#define TkWinReleaseDrawableDC_TCL_DECLARED
/* 22 */
EXTERN void		TkWinReleaseDrawableDC(Drawable d, HDC hdc,
				TkWinDCState *state);
#endif
#ifndef TkWinResendEvent_TCL_DECLARED
#define TkWinResendEvent_TCL_DECLARED
/* 23 */
EXTERN LRESULT		TkWinResendEvent(WNDPROC wndproc, HWND hwnd,
				XEvent *eventPtr);
#endif
#ifndef TkWinSelectPalette_TCL_DECLARED
#define TkWinSelectPalette_TCL_DECLARED
/* 24 */
EXTERN HPALETTE		TkWinSelectPalette(HDC dc, Colormap colormap);
#endif
#ifndef TkWinSetMenu_TCL_DECLARED
#define TkWinSetMenu_TCL_DECLARED
/* 25 */
EXTERN void		TkWinSetMenu(Tk_Window tkwin, HMENU hMenu);
#endif
#ifndef TkWinSetWindowPos_TCL_DECLARED
#define TkWinSetWindowPos_TCL_DECLARED
/* 26 */
EXTERN void		TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd,
				int pos);
#endif
#ifndef TkWinWmCleanup_TCL_DECLARED
#define TkWinWmCleanup_TCL_DECLARED
/* 27 */
EXTERN void		TkWinWmCleanup(HINSTANCE hInstance);
#endif
#ifndef TkWinXCleanup_TCL_DECLARED
#define TkWinXCleanup_TCL_DECLARED
/* 28 */
EXTERN void		TkWinXCleanup(ClientData clientData);
#endif
#ifndef TkWinXInit_TCL_DECLARED
#define TkWinXInit_TCL_DECLARED
/* 29 */
EXTERN void		TkWinXInit(HINSTANCE hInstance);
#endif
#ifndef TkWinSetForegroundWindow_TCL_DECLARED
#define TkWinSetForegroundWindow_TCL_DECLARED
/* 30 */
EXTERN void		TkWinSetForegroundWindow(TkWindow *winPtr);
#endif
#ifndef TkWinDialogDebug_TCL_DECLARED
#define TkWinDialogDebug_TCL_DECLARED
/* 31 */
EXTERN void		TkWinDialogDebug(int debug);

#endif
#ifndef TkWinGetMenuSystemDefault_TCL_DECLARED
#define TkWinGetMenuSystemDefault_TCL_DECLARED
/* 32 */
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(void);
#endif
#ifndef TkWinSetHINSTANCE_TCL_DECLARED
#define TkWinSetHINSTANCE_TCL_DECLARED
/* 34 */
EXTERN void		TkWinSetHINSTANCE(HINSTANCE hInstance);
#endif
#ifndef TkWinGetPlatformTheme_TCL_DECLARED
#define TkWinGetPlatformTheme_TCL_DECLARED
/* 35 */
EXTERN int		TkWinGetPlatformTheme(void);
#endif
#ifndef TkWinChildProc_TCL_DECLARED
#define TkWinChildProc_TCL_DECLARED
/* 36 */
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(void);
#endif
#ifndef TkpCmapStressed_TCL_DECLARED
#define TkpCmapStressed_TCL_DECLARED
/* 38 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
#endif
#ifndef TkpSync_TCL_DECLARED
#define TkpSync_TCL_DECLARED
/* 39 */
EXTERN void		TkpSync(Display *display);
#endif
#ifndef TkUnixContainerId_TCL_DECLARED
#define TkUnixContainerId_TCL_DECLARED
/* 40 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
#endif
#ifndef TkUnixDoOneXEvent_TCL_DECLARED
#define TkUnixDoOneXEvent_TCL_DECLARED
/* 41 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
#endif
#ifndef TkUnixSetMenubar_TCL_DECLARED
#define TkUnixSetMenubar_TCL_DECLARED
/* 42 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
#endif
#ifndef TkWmCleanup_TCL_DECLARED
#define TkWmCleanup_TCL_DECLARED
/* 43 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
#endif
#ifndef TkSendCleanup_TCL_DECLARED
#define TkSendCleanup_TCL_DECLARED
/* 44 */
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(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(TkWindow *winPtr);
#endif
#ifndef TkpSetCapture_TCL_DECLARED
#define TkpSetCapture_TCL_DECLARED
/* 4 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);
#endif
#ifndef TkpSetCursor_TCL_DECLARED
#define TkpSetCursor_TCL_DECLARED
/* 5 */
EXTERN void		TkpSetCursor(TkpCursor cursor);
#endif
#ifndef TkpWmSetState_TCL_DECLARED
#define TkpWmSetState_TCL_DECLARED
/* 6 */
EXTERN void		TkpWmSetState(TkWindow *winPtr, int state);
#endif
#ifndef TkAboutDlg_TCL_DECLARED
#define TkAboutDlg_TCL_DECLARED
/* 7 */
EXTERN void		TkAboutDlg(void);

#endif
#ifndef TkMacOSXButtonKeyState_TCL_DECLARED
#define TkMacOSXButtonKeyState_TCL_DECLARED
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
#endif
#ifndef TkMacOSXClearMenubarActive_TCL_DECLARED
#define TkMacOSXClearMenubarActive_TCL_DECLARED
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
#endif
#ifndef TkMacOSXDispatchMenuEvent_TCL_DECLARED
#define TkMacOSXDispatchMenuEvent_TCL_DECLARED
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
#endif
#ifndef TkMacOSXInstallCursor_TCL_DECLARED
#define TkMacOSXInstallCursor_TCL_DECLARED
/* 11 */
EXTERN void		TkMacOSXInstallCursor(int resizeOverride);
#endif
#ifndef TkMacOSXHandleTearoffMenu_TCL_DECLARED
#define TkMacOSXHandleTearoffMenu_TCL_DECLARED
/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
#endif
/* Slot 13 is reserved */
#ifndef TkMacOSXDoHLEvent_TCL_DECLARED
#define TkMacOSXDoHLEvent_TCL_DECLARED
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(VOID *theEvent);
#endif
/* Slot 15 is reserved */
#ifndef TkMacOSXGetXWindow_TCL_DECLARED
#define TkMacOSXGetXWindow_TCL_DECLARED
/* 16 */
EXTERN Window		TkMacOSXGetXWindow(VOID *macWinPtr);
#endif
#ifndef TkMacOSXGrowToplevel_TCL_DECLARED
#define TkMacOSXGrowToplevel_TCL_DECLARED
/* 17 */
EXTERN int		TkMacOSXGrowToplevel(VOID *whichWindow, XPoint start);
#endif
#ifndef TkMacOSXHandleMenuSelect_TCL_DECLARED
#define TkMacOSXHandleMenuSelect_TCL_DECLARED
/* 18 */
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(MacDrawable *macWin,
				int flag);

#endif
#ifndef TkMacOSXIsCharacterMissing_TCL_DECLARED
#define TkMacOSXIsCharacterMissing_TCL_DECLARED
/* 22 */
EXTERN int		TkMacOSXIsCharacterMissing(Tk_Font tkfont,
				unsigned int searchChar);
#endif
#ifndef TkMacOSXMakeRealWindowExist_TCL_DECLARED
#define TkMacOSXMakeRealWindowExist_TCL_DECLARED
/* 23 */
EXTERN void		TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
#endif
#ifndef TkMacOSXMakeStippleMap_TCL_DECLARED
#define TkMacOSXMakeStippleMap_TCL_DECLARED
/* 24 */
EXTERN VOID *		TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
#endif
#ifndef TkMacOSXMenuClick_TCL_DECLARED
#define TkMacOSXMenuClick_TCL_DECLARED
/* 25 */
EXTERN void		TkMacOSXMenuClick(void);


#endif
#ifndef TkMacOSXRegisterOffScreenWindow_TCL_DECLARED

#define TkMacOSXRegisterOffScreenWindow_TCL_DECLARED
/* 26 */






EXTERN void		TkMacOSXRegisterOffScreenWindow(Window window,

				VOID *portPtr);
#endif
#ifndef TkMacOSXResizable_TCL_DECLARED

#define TkMacOSXResizable_TCL_DECLARED
/* 27 */
EXTERN int		TkMacOSXResizable(TkWindow *winPtr);
#endif
#ifndef TkMacOSXSetHelpMenuItemCount_TCL_DECLARED
#define TkMacOSXSetHelpMenuItemCount_TCL_DECLARED
/* 28 */
EXTERN void		TkMacOSXSetHelpMenuItemCount(void);
#endif
#ifndef TkMacOSXSetScrollbarGrow_TCL_DECLARED
#define TkMacOSXSetScrollbarGrow_TCL_DECLARED
/* 29 */
EXTERN void		TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
#endif
#ifndef TkMacOSXSetUpClippingRgn_TCL_DECLARED
#define TkMacOSXSetUpClippingRgn_TCL_DECLARED
/* 30 */
EXTERN void		TkMacOSXSetUpClippingRgn(Drawable drawable);


#endif
#ifndef TkMacOSXSetUpGraphicsPort_TCL_DECLARED
#define TkMacOSXSetUpGraphicsPort_TCL_DECLARED
/* 31 */
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, VOID *destPort);


#endif
#ifndef TkMacOSXUpdateClipRgn_TCL_DECLARED

#define TkMacOSXUpdateClipRgn_TCL_DECLARED
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
#endif
#ifndef TkMacOSXUnregisterMacWindow_TCL_DECLARED
#define TkMacOSXUnregisterMacWindow_TCL_DECLARED
/* 33 */
EXTERN void		TkMacOSXUnregisterMacWindow(VOID *portPtr);
#endif
#ifndef TkMacOSXUseMenuID_TCL_DECLARED
#define TkMacOSXUseMenuID_TCL_DECLARED
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);
#endif
#ifndef TkMacOSXVisableClipRgn_TCL_DECLARED
#define TkMacOSXVisableClipRgn_TCL_DECLARED
/* 35 */
EXTERN TkRegion		TkMacOSXVisableClipRgn(TkWindow *winPtr);
#endif
#ifndef TkMacOSXWinBounds_TCL_DECLARED
#define TkMacOSXWinBounds_TCL_DECLARED
/* 36 */
EXTERN void		TkMacOSXWinBounds(TkWindow *winPtr, VOID *geometry);
#endif
#ifndef TkMacOSXWindowOffset_TCL_DECLARED
#define TkMacOSXWindowOffset_TCL_DECLARED
/* 37 */
EXTERN void		TkMacOSXWindowOffset(VOID *wRef, int *xOffset,
				int *yOffset);
#endif
#ifndef TkSetMacColor_TCL_DECLARED
#define TkSetMacColor_TCL_DECLARED
/* 38 */


EXTERN int		TkSetMacColor(unsigned long pixel, VOID *macColor);
#endif
#ifndef TkSetWMName_TCL_DECLARED
#define TkSetWMName_TCL_DECLARED
/* 39 */
EXTERN void		TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
#endif
#ifndef TkSuspendClipboard_TCL_DECLARED
#define TkSuspendClipboard_TCL_DECLARED
/* 40 */
EXTERN void		TkSuspendClipboard(void);
#endif
#ifndef TkMacOSXZoomToplevel_TCL_DECLARED
#define TkMacOSXZoomToplevel_TCL_DECLARED
/* 41 */
EXTERN int		TkMacOSXZoomToplevel(VOID *whichWindow,
				short zoomPart);
#endif
#ifndef Tk_TopCoordsToWindow_TCL_DECLARED
#define Tk_TopCoordsToWindow_TCL_DECLARED
/* 42 */
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(TkWindow *winPtr);
#endif
#ifndef TkMacOSXGetHostToplevel_TCL_DECLARED
#define TkMacOSXGetHostToplevel_TCL_DECLARED
/* 44 */
EXTERN MacDrawable *	TkMacOSXGetHostToplevel(TkWindow *winPtr);
#endif
#ifndef TkMacOSXPreprocessMenu_TCL_DECLARED
#define TkMacOSXPreprocessMenu_TCL_DECLARED
/* 45 */
EXTERN void		TkMacOSXPreprocessMenu(void);

#endif
#ifndef TkpIsWindowFloating_TCL_DECLARED
#define TkpIsWindowFloating_TCL_DECLARED
/* 46 */
EXTERN int		TkpIsWindowFloating(VOID *window);
#endif
#ifndef TkMacOSXGetCapture_TCL_DECLARED
#define TkMacOSXGetCapture_TCL_DECLARED
/* 47 */
EXTERN Tk_Window	TkMacOSXGetCapture(void);
#endif
/* Slot 48 is reserved */
#ifndef TkGetTransientMaster_TCL_DECLARED
#define TkGetTransientMaster_TCL_DECLARED
/* 49 */


EXTERN Window		TkGetTransientMaster(TkWindow *winPtr);
#endif
#ifndef TkGenerateButtonEvent_TCL_DECLARED
#define TkGenerateButtonEvent_TCL_DECLARED
/* 50 */
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(Tk_Window tkwin);


#endif
#ifndef TkMacOSXSetDrawingEnabled_TCL_DECLARED
#define TkMacOSXSetDrawingEnabled_TCL_DECLARED
/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);

#endif

#ifndef TkpGetMS_TCL_DECLARED
#define TkpGetMS_TCL_DECLARED
/* 53 */
EXTERN unsigned long	TkpGetMS(void);
#endif
#ifndef TkMacOSXDrawable_TCL_DECLARED
#define TkMacOSXDrawable_TCL_DECLARED
/* 54 */
EXTERN VOID *		TkMacOSXDrawable(Drawable drawable);
#endif
#ifndef TkpScanWindowId_TCL_DECLARED
#define TkpScanWindowId_TCL_DECLARED
/* 55 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,




				CONST char *string, Window *idPtr);
#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(void);
#endif
#ifndef TkFreeWindowId_TCL_DECLARED
#define TkFreeWindowId_TCL_DECLARED
/* 1 */
EXTERN void		TkFreeWindowId(TkDisplay *dispPtr, Window w);
#endif
#ifndef TkInitXId_TCL_DECLARED
#define TkInitXId_TCL_DECLARED
/* 2 */
EXTERN void		TkInitXId(TkDisplay *dispPtr);
#endif
#ifndef TkpCmapStressed_TCL_DECLARED
#define TkpCmapStressed_TCL_DECLARED
/* 3 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
#endif
#ifndef TkpSync_TCL_DECLARED
#define TkpSync_TCL_DECLARED
/* 4 */
EXTERN void		TkpSync(Display *display);
#endif
#ifndef TkUnixContainerId_TCL_DECLARED
#define TkUnixContainerId_TCL_DECLARED
/* 5 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
#endif
#ifndef TkUnixDoOneXEvent_TCL_DECLARED
#define TkUnixDoOneXEvent_TCL_DECLARED
/* 6 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
#endif
#ifndef TkUnixSetMenubar_TCL_DECLARED
#define TkUnixSetMenubar_TCL_DECLARED
/* 7 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
#endif
#ifndef TkpScanWindowId_TCL_DECLARED
#define TkpScanWindowId_TCL_DECLARED
/* 8 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				CONST char *string, Window *idPtr);
#endif
#ifndef TkWmCleanup_TCL_DECLARED
#define TkWmCleanup_TCL_DECLARED
/* 9 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
#endif
#ifndef TkSendCleanup_TCL_DECLARED
#define TkSendCleanup_TCL_DECLARED
/* 10 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
#endif
#ifndef TkFreeXId_TCL_DECLARED
#define TkFreeXId_TCL_DECLARED
/* 11 */
EXTERN void		TkFreeXId(TkDisplay *dispPtr);
#endif
#ifndef TkpWmSetState_TCL_DECLARED
#define TkpWmSetState_TCL_DECLARED
/* 12 */
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 {
    int magic;
    struct TkIntPlatStubHooks *hooks;

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */
    VOID *reserved1;
    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 */
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514

515

516
517


518
519


520
521


522
523


524
525


526
527


528
529


530
531


532
533


534
535


536
537


538
539


540
541


542
543


544
545


546
547


548
549


550
551


552
553


554
555


556
557


558
559


560
561


562
563


564
565


566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581


582
583


584
585


586
587


588
589


590
591

592
593
594
595
596
597
598
599


600
601


602
603

604
605
606
607
608
609
610
611


612
613


614
615


616
617


618
619


620
621


622
623
624

625

626
627
628
629

630


631
632
633


634
635
636

637
638


639
640


641
642
643
644


645
646


647
648


649
650


651
652


653
654

655

656
657


658
659
660
661


662
663


664
665




666
667
668


669
670


671
672


673
674


675
676


677
678


679
680
681


682
683


684
685


686
687


688
689


690
691


692
693


694
695
696


697
698


699
700






701
702


703
704


705
706


707
708


709
710
711
712
713
714
715

716
717


718
719


720
721

722
723
724
725
726
727


728
729


730
731


732
733
734


735
736


737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752





753
754
755
756
757
758
759
760
761
762
763
764


765
766


767
768


769
770


771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787

788
789
790


791











792




793

794

795
796
797
798








799

800

801
802
    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 objc, Tcl_Obj *const objv[]); /* 45 */
    void (*reserved46)(void);
    Tk_Window (*tkpGetCapture) (void); /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents_) (TkWindow *winPtr, int active); /* 2 */
    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 (*reserved11)(void);
    void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
    void (*reserved13)(void);
    int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */
    void (*reserved15)(void);
    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);
    void (*reserved20)(void);
    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 (*reserved26)(void);
    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 (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    Region (*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 (*reserved40)(void);
    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 (*tkpGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    void (*tkCreateXEventSource) (void); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 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 (*reserved11)(void);
    int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */
    int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*reserved16)(void);
    void (*reserved17)(void);
    void (*reserved18)(void);
    void (*reserved19)(void);
    void (*reserved20)(void);
    void (*reserved21)(void);
    void (*reserved22)(void);
    void (*reserved23)(void);
    void (*reserved24)(void);
    void (*reserved25)(void);
    void (*reserved26)(void);
    void (*reserved27)(void);
    void (*reserved28)(void);
    void (*reserved29)(void);
    void (*reserved30)(void);
    void (*reserved31)(void);
    void (*reserved32)(void);
    void (*reserved33)(void);
    void (*reserved34)(void);
    void (*reserved35)(void);
    void (*reserved36)(void);
    void (*reserved37)(void);
    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 objc, Tcl_Obj *const objv[]); /* 45 */
#endif /* X11 */
} TkIntPlatStubs;

extern const TkIntPlatStubs *tkIntPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */

#define TkAlignImageData \
	(tkIntPlatStubsPtr->tkAlignImageData) /* 0 */

/* Slot 1 is reserved */

#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */


#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 3 */


#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */


#define TkpPrintWindowId \
	(tkIntPlatStubsPtr->tkpPrintWindowId) /* 5 */


#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */


#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 7 */


#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 8 */


#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 9 */


#define TkSetPixmapColormap \
	(tkIntPlatStubsPtr->tkSetPixmapColormap) /* 10 */


#define TkWinCancelMouseTimer \
	(tkIntPlatStubsPtr->tkWinCancelMouseTimer) /* 11 */


#define TkWinClipboardRender \
	(tkIntPlatStubsPtr->tkWinClipboardRender) /* 12 */


#define TkWinEmbeddedEventProc \
	(tkIntPlatStubsPtr->tkWinEmbeddedEventProc) /* 13 */


#define TkWinFillRect \
	(tkIntPlatStubsPtr->tkWinFillRect) /* 14 */


#define TkWinGetBorderPixels \
	(tkIntPlatStubsPtr->tkWinGetBorderPixels) /* 15 */


#define TkWinGetDrawableDC \
	(tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 16 */


#define TkWinGetModifierState \
	(tkIntPlatStubsPtr->tkWinGetModifierState) /* 17 */


#define TkWinGetSystemPalette \
	(tkIntPlatStubsPtr->tkWinGetSystemPalette) /* 18 */


#define TkWinGetWrapperWindow \
	(tkIntPlatStubsPtr->tkWinGetWrapperWindow) /* 19 */


#define TkWinHandleMenuEvent \
	(tkIntPlatStubsPtr->tkWinHandleMenuEvent) /* 20 */


#define TkWinIndexOfColor \
	(tkIntPlatStubsPtr->tkWinIndexOfColor) /* 21 */


#define TkWinReleaseDrawableDC \
	(tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 22 */


#define TkWinResendEvent \
	(tkIntPlatStubsPtr->tkWinResendEvent) /* 23 */


#define TkWinSelectPalette \
	(tkIntPlatStubsPtr->tkWinSelectPalette) /* 24 */


#define TkWinSetMenu \
	(tkIntPlatStubsPtr->tkWinSetMenu) /* 25 */


#define TkWinSetWindowPos \
	(tkIntPlatStubsPtr->tkWinSetWindowPos) /* 26 */


#define TkWinWmCleanup \
	(tkIntPlatStubsPtr->tkWinWmCleanup) /* 27 */

#define TkWinXCleanup \
	(tkIntPlatStubsPtr->tkWinXCleanup) /* 28 */
#define TkWinXInit \
	(tkIntPlatStubsPtr->tkWinXInit) /* 29 */
#define TkWinSetForegroundWindow \
	(tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */
#define TkWinDialogDebug \
	(tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */
#define TkWinGetMenuSystemDefault \
	(tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */
#define TkWinGetPlatformId \
	(tkIntPlatStubsPtr->tkWinGetPlatformId) /* 33 */
#define TkWinSetHINSTANCE \
	(tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */


#define TkWinGetPlatformTheme \
	(tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */


#define TkWinChildProc \
	(tkIntPlatStubsPtr->tkWinChildProc) /* 36 */


#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 37 */


#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */


#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 39 */

#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 41 */
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 42 */
#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 43 */


#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 44 */


#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */

/* Slot 46 is reserved */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 0 */
/* Slot 1 is reserved */


#define TkGenerateActivateEvents_ \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents_) /* 2 */


#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 3 */


#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 4 */


#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 5 */


#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 6 */


#define TkAboutDlg \
	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */
#define TkMacOSXButtonKeyState \

	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */

#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */

/* Slot 11 is reserved */


#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */


#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */

#define TkMacOSXGetXWindow \
	(tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */


#define TkMacOSXGrowToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */


#define TkMacOSXHandleMenuSelect \
	(tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */
/* Slot 19 is reserved */
/* Slot 20 is reserved */


#define TkMacOSXInvalidateWindow \
	(tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */


#define TkMacOSXIsCharacterMissing \
	(tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */


#define TkMacOSXMakeRealWindowExist \
	(tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */


#define TkMacOSXMakeStippleMap \
	(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */


#define TkMacOSXMenuClick \
	(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */

/* Slot 26 is reserved */

#define TkMacOSXResizable \
	(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */


#define TkMacOSXSetHelpMenuItemCount \
	(tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */
#define TkMacOSXSetScrollbarGrow \
	(tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */


#define TkMacOSXSetUpClippingRgn \
	(tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */


#define TkMacOSXSetUpGraphicsPort \
	(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */




#define TkMacOSXUpdateClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
/* Slot 33 is reserved */


#define TkMacOSXUseMenuID \
	(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */


#define TkMacOSXVisableClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXVisableClipRgn) /* 35 */


#define TkMacOSXWinBounds \
	(tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */


#define TkMacOSXWindowOffset \
	(tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */


#define TkSetMacColor \
	(tkIntPlatStubsPtr->tkSetMacColor) /* 38 */


#define TkSetWMName \
	(tkIntPlatStubsPtr->tkSetWMName) /* 39 */
/* Slot 40 is reserved */


#define TkMacOSXZoomToplevel \
	(tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */


#define Tk_TopCoordsToWindow \
	(tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */


#define TkMacOSXContainerId \
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */


#define TkMacOSXGetHostToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */


#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */


#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */


#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
/* Slot 48 is reserved */


#define TkMacOSXGetContainer \
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */


#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */






#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */


#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */


#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 53 */


#define TkMacOSXDrawable \
	(tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */


#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
/* Slot 1 is reserved */

#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */


#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */


#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 4 */

#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */


#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 8 */


#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 9 */


#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 10 */
/* Slot 11 is reserved */


#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 12 */


#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 13 */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */

/* Slot 27 is reserved */





/* Slot 28 is reserved */
/* Slot 29 is reserved */
/* Slot 30 is reserved */
/* Slot 31 is reserved */
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
#define TkpCmapStressed_ \
	(tkIntPlatStubsPtr->tkpCmapStressed_) /* 38 */


#define TkpSync_ \
	(tkIntPlatStubsPtr->tkpSync_) /* 39 */


#define TkUnixContainerId_ \
	(tkIntPlatStubsPtr->tkUnixContainerId_) /* 40 */


#define TkUnixDoOneXEvent_ \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent_) /* 41 */


#define TkUnixSetMenubar_ \
	(tkIntPlatStubsPtr->tkUnixSetMenubar_) /* 42 */
#define TkWmCleanup_ \
	(tkIntPlatStubsPtr->tkWmCleanup_) /* 43 */
#define TkSendCleanup_ \
	(tkIntPlatStubsPtr->tkSendCleanup_) /* 44 */
#define TkpTestsendCmd_ \
	(tkIntPlatStubsPtr->tkpTestsendCmd_) /* 45 */
#endif /* X11 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_

#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_


#undef TkSendCleanup_











#undef TkpTestsendCmd_




#undef TkGenerateActivateEvents_

#undef TkMacOSXSetUpClippingRgn


#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT









#undef TkWinGetPlatformId

#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */


#endif /* _TKINTPLATDECLS */







|












|
<
<



|
|








|

|
|
|
|
|

|
|



|

|




|

|

|
|
|
|

|
|




|
|
|
|




|
|

|

|
|





|


|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|





|





|
>


>

>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
|
<
|
<
<
<
<
<
<
<
<
<
<
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
|
<
|
|
|
|
|
|
>
>
|
|
>
>
|
|
>
|
|
|
|
|
|
|
<
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
<
>
|
>
|
<
|
|
>
|
>
>
|
|
<
>
>
|
|
|
>
|
|
>
>
|
|
>
>
|
|
<
<
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
|
>
|
|
>
>
|
<
|
|
>
>
|
|
>
>
|
|
>
>
>
>
|
|
<
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
<
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
<
>
>
|
|
>
>
|
|
>
>
>
>
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|
|
|
|
|
>
|
|
>
>
|
|
>
>
|
|
>
|
<
|
|
|
<
>
>
|
|
>
>
|
|
>
>
|
|
<
>
>
|
|
>
>
|
|
<
<
<
<
<
|
|
|
|
|
|
|
|
>
|
>
>
>
>
>
|
|
|
|
|
|
|
|
|
<
|
|
>
>
|
|
>
>
|
|
>
>
|
|
>
>
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
>
|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
>




>
>
>
>
>
>
>
>
|
>
|
>


651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671


672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
































746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871

872










873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941

942
943
944
945

946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969


970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115

1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133
1134
1135
1136
1137
1138





1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180






1181






1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
    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) (TkWindow *winPtr, int active); /* 0 */
    VOID *reserved1;
    VOID *reserved2;
    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) (VOID *theEvent); /* 14 */
    VOID *reserved15;
    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) (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) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    VOID * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    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;

extern TkIntPlatStubs *tkIntPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)

/*
 * Inline function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef TkAlignImageData
#define TkAlignImageData \
	(tkIntPlatStubsPtr->tkAlignImageData) /* 0 */
#endif
/* Slot 1 is reserved */
#ifndef TkGenerateActivateEvents
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */
#endif
#ifndef TkpGetMS
#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 3 */
#endif
#ifndef TkPointerDeadWindow
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */
#endif
#ifndef TkpPrintWindowId
#define TkpPrintWindowId \
	(tkIntPlatStubsPtr->tkpPrintWindowId) /* 5 */
#endif
#ifndef TkpScanWindowId
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */
#endif
#ifndef TkpSetCapture
#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 7 */
#endif
#ifndef TkpSetCursor
#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 8 */
#endif
#ifndef TkpWmSetState
#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 9 */
#endif
#ifndef TkSetPixmapColormap
#define TkSetPixmapColormap \
	(tkIntPlatStubsPtr->tkSetPixmapColormap) /* 10 */
#endif
#ifndef TkWinCancelMouseTimer
#define TkWinCancelMouseTimer \
	(tkIntPlatStubsPtr->tkWinCancelMouseTimer) /* 11 */
#endif
#ifndef TkWinClipboardRender
#define TkWinClipboardRender \
	(tkIntPlatStubsPtr->tkWinClipboardRender) /* 12 */
#endif
#ifndef TkWinEmbeddedEventProc
#define TkWinEmbeddedEventProc \
	(tkIntPlatStubsPtr->tkWinEmbeddedEventProc) /* 13 */
#endif
#ifndef TkWinFillRect
#define TkWinFillRect \
	(tkIntPlatStubsPtr->tkWinFillRect) /* 14 */
#endif
#ifndef TkWinGetBorderPixels
#define TkWinGetBorderPixels \
	(tkIntPlatStubsPtr->tkWinGetBorderPixels) /* 15 */
#endif
#ifndef TkWinGetDrawableDC
#define TkWinGetDrawableDC \
	(tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 16 */
#endif
#ifndef TkWinGetModifierState
#define TkWinGetModifierState \
	(tkIntPlatStubsPtr->tkWinGetModifierState) /* 17 */
#endif
#ifndef TkWinGetSystemPalette
#define TkWinGetSystemPalette \
	(tkIntPlatStubsPtr->tkWinGetSystemPalette) /* 18 */
#endif
#ifndef TkWinGetWrapperWindow
#define TkWinGetWrapperWindow \
	(tkIntPlatStubsPtr->tkWinGetWrapperWindow) /* 19 */
#endif
#ifndef TkWinHandleMenuEvent
#define TkWinHandleMenuEvent \
	(tkIntPlatStubsPtr->tkWinHandleMenuEvent) /* 20 */
#endif
#ifndef TkWinIndexOfColor
#define TkWinIndexOfColor \
	(tkIntPlatStubsPtr->tkWinIndexOfColor) /* 21 */
#endif
#ifndef TkWinReleaseDrawableDC
#define TkWinReleaseDrawableDC \
	(tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 22 */
#endif
#ifndef TkWinResendEvent
#define TkWinResendEvent \
	(tkIntPlatStubsPtr->tkWinResendEvent) /* 23 */
#endif
#ifndef TkWinSelectPalette
#define TkWinSelectPalette \
	(tkIntPlatStubsPtr->tkWinSelectPalette) /* 24 */
#endif
#ifndef TkWinSetMenu
#define TkWinSetMenu \
	(tkIntPlatStubsPtr->tkWinSetMenu) /* 25 */
#endif
#ifndef TkWinSetWindowPos
#define TkWinSetWindowPos \
	(tkIntPlatStubsPtr->tkWinSetWindowPos) /* 26 */
#endif
#ifndef TkWinWmCleanup
#define TkWinWmCleanup \
	(tkIntPlatStubsPtr->tkWinWmCleanup) /* 27 */
#endif
#ifndef TkWinXCleanup

#define TkWinXCleanup \










	(tkIntPlatStubsPtr->tkWinXCleanup) /* 28 */
#endif
#ifndef TkWinXInit
#define TkWinXInit \
	(tkIntPlatStubsPtr->tkWinXInit) /* 29 */
#endif
#ifndef TkWinSetForegroundWindow
#define TkWinSetForegroundWindow \
	(tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */
#endif
#ifndef TkWinDialogDebug
#define TkWinDialogDebug \
	(tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */
#endif
#ifndef TkWinGetMenuSystemDefault
#define TkWinGetMenuSystemDefault \
	(tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */
#endif
#ifndef TkWinGetPlatformId
#define TkWinGetPlatformId \
	(tkIntPlatStubsPtr->tkWinGetPlatformId) /* 33 */
#endif
#ifndef TkWinSetHINSTANCE

#define TkWinSetHINSTANCE \
	(tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */
#endif
#ifndef TkWinGetPlatformTheme
#define TkWinGetPlatformTheme \
	(tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */
#endif
#ifndef TkWinChildProc
#define TkWinChildProc \
	(tkIntPlatStubsPtr->tkWinChildProc) /* 36 */
#endif
#ifndef TkCreateXEventSource
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 37 */
#endif
#ifndef TkpCmapStressed
#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */
#endif
#ifndef TkpSync
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 39 */

#endif
#ifndef TkUnixContainerId
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */
#endif
#ifndef TkUnixDoOneXEvent
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 41 */
#endif
#ifndef TkUnixSetMenubar
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 42 */
#endif
#ifndef TkWmCleanup
#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 43 */
#endif
#ifndef TkSendCleanup
#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 44 */
#endif
#ifndef TkpTestsendCmd
#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */

#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef TkGenerateActivateEvents

#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 0 */
#endif
/* Slot 1 is reserved */
/* Slot 2 is reserved */
#ifndef TkPointerDeadWindow
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 3 */

#endif
#ifndef TkpSetCapture
#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 4 */
#endif
#ifndef TkpSetCursor
#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 5 */
#endif
#ifndef TkpWmSetState
#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 6 */
#endif
#ifndef TkAboutDlg
#define TkAboutDlg \
	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */


#endif
#ifndef TkMacOSXButtonKeyState
#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#endif
#ifndef TkMacOSXClearMenubarActive
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#endif
#ifndef TkMacOSXDispatchMenuEvent
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
#endif
#ifndef TkMacOSXInstallCursor
#define TkMacOSXInstallCursor \
	(tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */
#endif
#ifndef TkMacOSXHandleTearoffMenu
#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
#endif
/* Slot 13 is reserved */
#ifndef TkMacOSXDoHLEvent
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
#endif
/* Slot 15 is reserved */
#ifndef TkMacOSXGetXWindow

#define TkMacOSXGetXWindow \
	(tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */
#endif
#ifndef TkMacOSXGrowToplevel
#define TkMacOSXGrowToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */
#endif
#ifndef TkMacOSXHandleMenuSelect
#define TkMacOSXHandleMenuSelect \
	(tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */
#endif
/* Slot 19 is reserved */
/* Slot 20 is reserved */
#ifndef TkMacOSXInvalidateWindow
#define TkMacOSXInvalidateWindow \
	(tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */

#endif
#ifndef TkMacOSXIsCharacterMissing
#define TkMacOSXIsCharacterMissing \
	(tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */
#endif
#ifndef TkMacOSXMakeRealWindowExist
#define TkMacOSXMakeRealWindowExist \
	(tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */
#endif
#ifndef TkMacOSXMakeStippleMap
#define TkMacOSXMakeStippleMap \
	(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */
#endif
#ifndef TkMacOSXMenuClick
#define TkMacOSXMenuClick \
	(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */
#endif
#ifndef TkMacOSXRegisterOffScreenWindow
#define TkMacOSXRegisterOffScreenWindow \
	(tkIntPlatStubsPtr->tkMacOSXRegisterOffScreenWindow) /* 26 */
#endif
#ifndef TkMacOSXResizable
#define TkMacOSXResizable \
	(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */

#endif
#ifndef TkMacOSXSetHelpMenuItemCount
#define TkMacOSXSetHelpMenuItemCount \
	(tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */
#endif
#ifndef TkMacOSXSetScrollbarGrow
#define TkMacOSXSetScrollbarGrow \
	(tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */
#endif
#ifndef TkMacOSXSetUpClippingRgn
#define TkMacOSXSetUpClippingRgn \
	(tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */
#endif
#ifndef TkMacOSXSetUpGraphicsPort
#define TkMacOSXSetUpGraphicsPort \
	(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */
#endif
#ifndef TkMacOSXUpdateClipRgn
#define TkMacOSXUpdateClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
#endif
#ifndef TkMacOSXUnregisterMacWindow
#define TkMacOSXUnregisterMacWindow \
	(tkIntPlatStubsPtr->tkMacOSXUnregisterMacWindow) /* 33 */
#endif
#ifndef TkMacOSXUseMenuID
#define TkMacOSXUseMenuID \
	(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */

#endif
#ifndef TkMacOSXVisableClipRgn
#define TkMacOSXVisableClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXVisableClipRgn) /* 35 */
#endif
#ifndef TkMacOSXWinBounds
#define TkMacOSXWinBounds \
	(tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */
#endif
#ifndef TkMacOSXWindowOffset
#define TkMacOSXWindowOffset \
	(tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */
#endif
#ifndef TkSetMacColor
#define TkSetMacColor \
	(tkIntPlatStubsPtr->tkSetMacColor) /* 38 */
#endif
#ifndef TkSetWMName
#define TkSetWMName \
	(tkIntPlatStubsPtr->tkSetWMName) /* 39 */
#endif
#ifndef TkSuspendClipboard
#define TkSuspendClipboard \
	(tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */
#endif
#ifndef TkMacOSXZoomToplevel
#define TkMacOSXZoomToplevel \
	(tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */
#endif
#ifndef Tk_TopCoordsToWindow
#define Tk_TopCoordsToWindow \
	(tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */
#endif
#ifndef TkMacOSXContainerId
#define TkMacOSXContainerId \
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#endif
#ifndef TkMacOSXGetHostToplevel
#define TkMacOSXGetHostToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */
#endif
#ifndef TkMacOSXPreprocessMenu
#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */
#endif
#ifndef TkpIsWindowFloating
#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */
#endif
#ifndef TkMacOSXGetCapture

#define TkMacOSXGetCapture \
	(tkIntPlatStubsPtr->tkMacOSXGetCapture) /* 47 */
#endif

/* Slot 48 is reserved */
#ifndef TkGetTransientMaster
#define TkGetTransientMaster \
	(tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */
#endif
#ifndef TkGenerateButtonEvent
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#endif
#ifndef TkGenWMDestroyEvent
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */

#endif
#ifndef TkMacOSXSetDrawingEnabled
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#endif
#ifndef TkpGetMS
#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 53 */





#endif
#ifndef TkMacOSXDrawable
#define TkMacOSXDrawable \
	(tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */
#endif
#ifndef TkpScanWindowId
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */
#endif
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#ifndef TkCreateXEventSource
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
#endif
#ifndef TkFreeWindowId
#define TkFreeWindowId \
	(tkIntPlatStubsPtr->tkFreeWindowId) /* 1 */
#endif
#ifndef TkInitXId
#define TkInitXId \
	(tkIntPlatStubsPtr->tkInitXId) /* 2 */
#endif
#ifndef TkpCmapStressed

#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */
#endif
#ifndef TkpSync
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 4 */
#endif
#ifndef TkUnixContainerId
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */
#endif
#ifndef TkUnixDoOneXEvent
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */
#endif
#ifndef TkUnixSetMenubar
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */






#endif






#ifndef TkpScanWindowId
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 8 */
#endif
#ifndef TkWmCleanup
#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 9 */
#endif
#ifndef TkSendCleanup
#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 10 */
#endif
#ifndef TkFreeXId
#define TkFreeXId \
	(tkIntPlatStubsPtr->tkFreeXId) /* 11 */
#endif
#ifndef TkpWmSetState
#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) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#ifdef __CYGWIN__
    void TkFreeXId(TkDisplay *dispPtr);
    void TkFreeWindowId(TkDisplay *dispPtr, Window w);
    void TkInitXId(TkDisplay *dispPtr);
#endif

#ifdef __WIN32__
#undef TkpCmapStressed
#undef TkpSync
#define TkpCmapStressed(tkwin,colormap) (0)
#define TkpSync(display)
#endif

#endif /* _TKINTPLATDECLS */

Changes to generic/tkIntXlibDecls.h.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


60
61
62



63
64



65
66
67
68



69
70
71
72



73
74



75
76



77
78
79



80
81
82
83



84
85
86
87



88
89



90
91



92
93



94
95



96
97



98
99



100
101



102
103



104
105
106



107
108



109
110



111
112
113
114



115
116
117



118
119



120
121
122



123
124
125
126



127
128
129
130
131



132
133
134
135



136
137



138
139



140
141



142
143
144
145



146
147
148



149
150
151



152
153
154
155



156
157
158



159
160
161



162
163



164
165



166
167
168



169
170



171
172



173
174
175
176
177



178
179



180
181
182
183
184



185
186
187



188
189
190



191
192
193
194



195
196



197
198
199



200
201



202
203
204



205
206



207
208



209
210



211
212
213



214
215
216
217



218
219
220



221
222



223
224



225
226
227



228
229



230
231
232



233
234



235
236



237
238



239
240
241



242
243
244



245
246
247



248
249
250



251
252
253



254
255
256



257
258



259
260
261
262



263
264



265
266



267
268



269
270



271
272



273
274



275
276
277



278
279
280
281
282
283

284


285
286
287



288
289
290



291
292



293
294
295



296
297
298



299
300
301



302
303



304
305
306



307
308
309



310
311
312



313
314



315
316



317
318



319
320



321
322
323



324
325



326
327
328
329



330
331



332
333



334
335
336
337



338
339
340



341
342
343



344
345
346



347
348
349
350



351
352
353
354



355
356



357
358



359
360



361
362



363
364



365
366



367
368



369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408



409
410
411



412
413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470


471
472
473
474

475
476


477
478
479



480
481



482
483
484
485



486
487
488
489



490
491



492
493



494
495
496



497
498



499
500



501
502



503
504



505
506



507
508



509
510



511
512
513
514



515
516
517



518
519
520



521
522
523
524



525
526
527
528
529



530
531
532
533



534
535



536
537



538
539
540
541



542
543
544



545
546
547



548
549
550
551



552
553
554



555
556
557



558
559



560
561
562



563
564



565
566
567
568
569



570
571
572
573
574



575
576
577



578
579
580
581



582
583



584
585



586
587
588



589
590



591
592
593
594



595
596



597
598



599
600
601



602
603



604
605
606



607
608



609
610



611
612
613



614
615
616



617
618
619



620
621
622



623
624
625



626
627
628



629
630



631
632



633
634



635
636



637
638
639
640
641
642



643
644
645



646
647
648



649
650



651
652
653



654
655
656



657
658
659



660
661



662
663
664



665
666
667



668
669
670



671
672



673
674



675
676



677
678



679
680
681



682
683



684
685
686
687



688
689



690
691



692
693
694
695



696
697
698



699
700
701



702
703
704



705
706



707
708
709



710
711
712
713



714
715



716
717
718



719
720
721



722
723
724
725
726
727



728
729
730



731
732
733



734
735
736



737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893


894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

#ifndef _TCL
#   include <tcl.h>
#endif

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

#include "X11/Xutil.h"

#ifdef BUILD_tk
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#else
#  ifndef TCL_STORAGE_CLASS
#    define TCL_STORAGE_CLASS DLLIMPORT
#  endif
#endif

#if defined(MAC_OSX_TK) && !defined(MAC_OSX_TCL)
#  define MAC_OSX_TCL 1
#endif

typedef int (*XAfterFunction) (	    /* WARNING, this type not in Xlib spec */
    Display*		/* display */
);

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */


/* 0 */
EXTERN int		XSetDashes(Display *display, GC gc, int dash_offset,
				_Xconst char *dash_list, int n);



/* 1 */
EXTERN XModifierKeymap * XGetModifierMapping(Display *d);



/* 2 */
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);



/* 3 */
EXTERN XImage *		XGetImage(Display *d, Drawable dr, int i1, int i2,
				unsigned int ui1, unsigned int ui2,
				unsigned long ul, int i3);



/* 4 */
EXTERN char *		XGetAtomName(Display *d, Atom a);



/* 5 */
EXTERN char *		XKeysymToString(KeySym k);



/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);



/* 7 */
EXTERN Cursor		XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
				XColor *x1, XColor *x2, unsigned int ui1,
				unsigned int ui2);



/* 8 */
EXTERN Cursor		XCreateGlyphCursor(Display *d, Font f1, Font f2,
				unsigned int ui1, unsigned int ui2,
				XColor _Xconst *x1, XColor _Xconst *x2);



/* 9 */
EXTERN GContext		XGContextFromGC(GC g);



/* 10 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);



/* 11 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, unsigned int k, int i);



/* 12 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);



/* 13 */
EXTERN Window		XRootWindow(Display *d, int i);



/* 14 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);



/* 15 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);



/* 16 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);



/* 17 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);



/* 18 */
EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);



/* 19 */
EXTERN int		XBell(Display *d, int i);



/* 20 */
EXTERN int		XChangeProperty(Display *d, Window w, Atom a1,
				Atom a2, int i1, int i2,
				_Xconst unsigned char *c, int i3);



/* 21 */
EXTERN int		XChangeWindowAttributes(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);



/* 22 */
EXTERN int		XClearWindow(Display *d, Window w);



/* 23 */
EXTERN int		XConfigureWindow(Display *d, Window w,
				unsigned int i, XWindowChanges *x);



/* 24 */
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);



/* 25 */
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);



/* 26 */
EXTERN Pixmap		XCreateBitmapFromData(Display *display, Drawable d,
				_Xconst char *data, unsigned int width,
				unsigned int height);



/* 27 */
EXTERN int		XDefineCursor(Display *d, Window w, Cursor c);



/* 28 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);



/* 29 */
EXTERN int		XDestroyWindow(Display *d, Window w);



/* 30 */
EXTERN int		XDrawArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);



/* 31 */
EXTERN int		XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
				int i1, int i2);



/* 32 */
EXTERN int		XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2);



/* 33 */
EXTERN int		XFillArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);



/* 34 */
EXTERN int		XFillPolygon(Display *d, Drawable dr, GC g,
				XPoint *x, int i1, int i2, int i3);



/* 35 */
EXTERN int		XFillRectangles(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);



/* 36 */
EXTERN int		XForceScreenSaver(Display *d, int i);



/* 37 */
EXTERN int		XFreeColormap(Display *d, Colormap c);



/* 38 */
EXTERN int		XFreeColors(Display *d, Colormap c,
				unsigned long *ulp, int i, unsigned long ul);



/* 39 */
EXTERN int		XFreeCursor(Display *d, Cursor c);



/* 40 */
EXTERN int		XFreeModifiermap(XModifierKeymap *x);



/* 41 */
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);



/* 42 */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);



/* 43 */
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);



/* 44 */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);



/* 45 */
EXTERN int		XGrabKeyboard(Display *d, Window w, Bool b, int i1,
				int i2, Time t);



/* 46 */
EXTERN int		XGrabPointer(Display *d, Window w1, Bool b,
				unsigned int ui, int i1, int i2, Window w2,
				Cursor c, Time t);



/* 47 */
EXTERN KeyCode		XKeysymToKeycode(Display *d, KeySym k);



/* 48 */
EXTERN Status		XLookupColor(Display *d, Colormap c1,
				_Xconst char *c2, XColor *x1, XColor *x2);



/* 49 */
EXTERN int		XMapWindow(Display *d, Window w);



/* 50 */
EXTERN int		XMoveResizeWindow(Display *d, Window w, int i1,
				int i2, unsigned int ui1, unsigned int ui2);



/* 51 */
EXTERN int		XMoveWindow(Display *d, Window w, int i1, int i2);



/* 52 */
EXTERN int		XNextEvent(Display *d, XEvent *x);



/* 53 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);



/* 54 */
EXTERN int		XQueryColors(Display *d, Colormap c, XColor *x,
				int i);



/* 55 */
EXTERN Bool		XQueryPointer(Display *d, Window w1, Window *w2,
				Window *w3, int *i1, int *i2, int *i3,
				int *i4, unsigned int *ui);



/* 56 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);



/* 57 */
EXTERN int		XRaiseWindow(Display *d, Window w);



/* 58 */
EXTERN int		XRefreshKeyboardMapping(XMappingEvent *x);



/* 59 */
EXTERN int		XResizeWindow(Display *d, Window w, unsigned int ui1,
				unsigned int ui2);



/* 60 */
EXTERN int		XSelectInput(Display *d, Window w, long l);



/* 61 */
EXTERN Status		XSendEvent(Display *d, Window w, Bool b, long l,
				XEvent *x);



/* 62 */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);



/* 63 */
EXTERN int		XSetIconName(Display *d, Window w, _Xconst char *c);



/* 64 */
EXTERN int		XSetInputFocus(Display *d, Window w, int i, Time t);



/* 65 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);



/* 66 */
EXTERN int		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);



/* 67 */
EXTERN int		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);



/* 68 */
EXTERN int		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);



/* 69 */
EXTERN int		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);



/* 70 */
EXTERN int		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);



/* 71 */
EXTERN int		XSetWindowColormap(Display *d, Window w, Colormap c);



/* 72 */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);



/* 73 */
EXTERN int		XUngrabKeyboard(Display *d, Time t);



/* 74 */
EXTERN int		XUngrabPointer(Display *d, Time t);



/* 75 */
EXTERN int		XUnmapWindow(Display *d, Window w);



/* 76 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);



/* 77 */
EXTERN void		XDestroyIC(XIC x);



/* 78 */
EXTERN Bool		XFilterEvent(XEvent *x, Window w);



/* 79 */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);



/* 80 */
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);

/* Slot 81 is reserved */


/* 82 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);



/* 83 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);



/* 84 */
EXTERN int		XFreeGC(Display *display, GC gc);



/* 85 */
EXTERN Atom		XInternAtom(Display *display,
				_Xconst char *atom_name, Bool only_if_exists);



/* 86 */
EXTERN int		XSetBackground(Display *display, GC gc,
				unsigned long foreground);



/* 87 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);



/* 88 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);



/* 89 */
EXTERN int		XSetClipOrigin(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin);



/* 90 */
EXTERN int		XSetTSOrigin(Display *display, GC gc,
				int ts_x_origin, int ts_y_origin);



/* 91 */
EXTERN int		XChangeGC(Display *d, GC gc, unsigned long mask,
				XGCValues *values);



/* 92 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);



/* 93 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);



/* 94 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);



/* 95 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);



/* 96 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);



/* 97 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);



/* 98 */
EXTERN int		XSetLineAttributes(Display *display, GC gc,
				unsigned int line_width, int line_style,
				int cap_style, int join_style);



/* 99 */
EXTERN int		_XInitImageFuncPtrs(XImage *image);



/* 100 */
EXTERN XIC		XCreateIC(XIM xim, ...);



/* 101 */
EXTERN XVisualInfo *	XGetVisualInfo(Display *display, long vinfo_mask,
				XVisualInfo *vinfo_template,
				int *nitems_return);



/* 102 */
EXTERN void		XSetWMClientMachine(Display *display, Window w,
				XTextProperty *text_prop);



/* 103 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);



/* 104 */
EXTERN int		XDrawLine(Display *d, Drawable dr, GC g, int x1,
				int y1, int x2, int y2);



/* 105 */
EXTERN int		XWarpPointer(Display *d, Window s, Window dw, int sx,
				int sy, unsigned int sw, unsigned int sh,
				int dx, int dy);



/* 106 */
EXTERN int		XFillRectangle(Display *display, Drawable d, GC gc,
				int x, int y, unsigned int width,
				unsigned int height);



/* 107 */
EXTERN int		XFlush(Display *display);



/* 108 */
EXTERN int		XGrabServer(Display *display);



/* 109 */
EXTERN int		XUngrabServer(Display *display);



/* 110 */
EXTERN int		XFree(void *data);



/* 111 */
EXTERN int		XNoOp(Display *display);



/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);



/* 113 */
EXTERN int		XSync(Display *display, Bool discard);



/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);

/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* 120 */
EXTERN int		XOffsetRegion(Region rgn, int dx, int dy);
/* 121 */
EXTERN int		XUnionRegion(Region srca, Region srcb,
				Region dr_return);
/* 122 */
EXTERN Window		XCreateWindow(Display *display, Window parent, int x,
				int y, unsigned int width,
				unsigned int height,
				unsigned int border_width, int depth,
				unsigned int clazz, Visual *visual,
				unsigned long value_mask,
				XSetWindowAttributes *attributes);
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* 129 */
EXTERN int		XLowerWindow(Display *d, Window w);
/* 130 */
EXTERN int		XFillArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 131 */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
EXTERN int		XDrawRectangles(Display *d, Drawable dr, GC gc,
				XRectangle *r, int n);

/* 133 */
EXTERN int		XDrawSegments(Display *d, Drawable dr, GC gc,
				XSegment *s, int n);



/* 134 */
EXTERN int		XDrawPoint(Display *d, Drawable dr, GC gc, int x,
				int y);



/* 135 */
EXTERN int		XDrawPoints(Display *d, Drawable dr, GC gc,
				XPoint *p, int n, int m);

/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
EXTERN void		XFreeStringList(char **list);
/* 157 */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);


/* 158 */
EXTERN Display *	XkbOpenDisplay(const char *name, int *ev_rtrn,
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);

#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */


/* 0 */
EXTERN int		XSetDashes(Display *display, GC gc, int dash_offset,
				_Xconst char *dash_list, int n);



/* 1 */
EXTERN XModifierKeymap * XGetModifierMapping(Display *d);



/* 2 */
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);



/* 3 */
EXTERN XImage *		XGetImage(Display *d, Drawable dr, int i1, int i2,
				unsigned int ui1, unsigned int ui2,
				unsigned long ul, int i3);



/* 4 */
EXTERN char *		XGetAtomName(Display *d, Atom a);



/* 5 */
EXTERN char *		XKeysymToString(KeySym k);



/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);



/* 7 */
EXTERN GContext		XGContextFromGC(GC g);



/* 8 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, unsigned int k, int i);



/* 9 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);



/* 10 */
EXTERN Window		XRootWindow(Display *d, int i);



/* 11 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);



/* 12 */
EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);



/* 13 */
EXTERN int		XBell(Display *d, int i);



/* 14 */
EXTERN int		XChangeProperty(Display *d, Window w, Atom a1,
				Atom a2, int i1, int i2,
				_Xconst unsigned char *c, int i3);



/* 15 */
EXTERN int		XChangeWindowAttributes(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);



/* 16 */
EXTERN int		XConfigureWindow(Display *d, Window w,
				unsigned int i, XWindowChanges *x);



/* 17 */
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);



/* 18 */
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);



/* 19 */
EXTERN Pixmap		XCreateBitmapFromData(Display *display, Drawable d,
				_Xconst char *data, unsigned int width,
				unsigned int height);



/* 20 */
EXTERN int		XDefineCursor(Display *d, Window w, Cursor c);



/* 21 */
EXTERN int		XDestroyWindow(Display *d, Window w);



/* 22 */
EXTERN int		XDrawArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);



/* 23 */
EXTERN int		XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
				int i1, int i2);



/* 24 */
EXTERN int		XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2);



/* 25 */
EXTERN int		XFillArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);



/* 26 */
EXTERN int		XFillPolygon(Display *d, Drawable dr, GC g,
				XPoint *x, int i1, int i2, int i3);



/* 27 */
EXTERN int		XFillRectangles(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);



/* 28 */
EXTERN int		XFreeColormap(Display *d, Colormap c);



/* 29 */
EXTERN int		XFreeColors(Display *d, Colormap c,
				unsigned long *ulp, int i, unsigned long ul);



/* 30 */
EXTERN int		XFreeModifiermap(XModifierKeymap *x);



/* 31 */
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);



/* 32 */
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);



/* 33 */
EXTERN int		XGrabKeyboard(Display *d, Window w, Bool b, int i1,
				int i2, Time t);



/* 34 */
EXTERN int		XGrabPointer(Display *d, Window w1, Bool b,
				unsigned int ui, int i1, int i2, Window w2,
				Cursor c, Time t);



/* 35 */
EXTERN KeyCode		XKeysymToKeycode(Display *d, KeySym k);



/* 36 */
EXTERN int		XMapWindow(Display *d, Window w);



/* 37 */
EXTERN int		XMoveResizeWindow(Display *d, Window w, int i1,
				int i2, unsigned int ui1, unsigned int ui2);



/* 38 */
EXTERN int		XMoveWindow(Display *d, Window w, int i1, int i2);



/* 39 */
EXTERN Bool		XQueryPointer(Display *d, Window w1, Window *w2,
				Window *w3, int *i1, int *i2, int *i3,
				int *i4, unsigned int *ui);



/* 40 */
EXTERN int		XRaiseWindow(Display *d, Window w);



/* 41 */
EXTERN int		XRefreshKeyboardMapping(XMappingEvent *x);



/* 42 */
EXTERN int		XResizeWindow(Display *d, Window w, unsigned int ui1,
				unsigned int ui2);



/* 43 */
EXTERN int		XSelectInput(Display *d, Window w, long l);



/* 44 */
EXTERN Status		XSendEvent(Display *d, Window w, Bool b, long l,
				XEvent *x);



/* 45 */
EXTERN int		XSetIconName(Display *d, Window w, _Xconst char *c);



/* 46 */
EXTERN int		XSetInputFocus(Display *d, Window w, int i, Time t);



/* 47 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);



/* 48 */
EXTERN int		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);



/* 49 */
EXTERN int		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);



/* 50 */
EXTERN int		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);



/* 51 */
EXTERN int		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);



/* 52 */
EXTERN int		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);



/* 53 */
EXTERN int		XSetWindowColormap(Display *d, Window w, Colormap c);



/* 54 */
EXTERN int		XUngrabKeyboard(Display *d, Time t);



/* 55 */
EXTERN int		XUngrabPointer(Display *d, Time t);



/* 56 */
EXTERN int		XUnmapWindow(Display *d, Window w);



/* 57 */
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);



/* 58 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);



/* 59 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);



/* 60 */
EXTERN int		XFreeGC(Display *display, GC gc);



/* 61 */
EXTERN Atom		XInternAtom(Display *display,
				_Xconst char *atom_name, Bool only_if_exists);



/* 62 */
EXTERN int		XSetBackground(Display *display, GC gc,
				unsigned long foreground);



/* 63 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);



/* 64 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);



/* 65 */
EXTERN int		XSetClipOrigin(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin);



/* 66 */
EXTERN int		XSetTSOrigin(Display *display, GC gc,
				int ts_x_origin, int ts_y_origin);



/* 67 */
EXTERN int		XChangeGC(Display *d, GC gc, unsigned long mask,
				XGCValues *values);



/* 68 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);



/* 69 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);



/* 70 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);



/* 71 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);



/* 72 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);



/* 73 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);



/* 74 */
EXTERN int		XSetLineAttributes(Display *display, GC gc,
				unsigned int line_width, int line_style,
				int cap_style, int join_style);



/* 75 */
EXTERN int		_XInitImageFuncPtrs(XImage *image);



/* 76 */
EXTERN XIC		XCreateIC(XIM xim, ...);



/* 77 */
EXTERN XVisualInfo *	XGetVisualInfo(Display *display, long vinfo_mask,
				XVisualInfo *vinfo_template,
				int *nitems_return);



/* 78 */
EXTERN void		XSetWMClientMachine(Display *display, Window w,
				XTextProperty *text_prop);



/* 79 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);



/* 80 */
EXTERN int		XDrawSegments(Display *display, Drawable d, GC gc,
				XSegment *segments, int nsegments);



/* 81 */
EXTERN int		XForceScreenSaver(Display *display, int mode);



/* 82 */
EXTERN int		XDrawLine(Display *d, Drawable dr, GC g, int x1,
				int y1, int x2, int y2);



/* 83 */
EXTERN int		XFillRectangle(Display *display, Drawable d, GC gc,
				int x, int y, unsigned int width,
				unsigned int height);



/* 84 */
EXTERN int		XClearWindow(Display *d, Window w);



/* 85 */
EXTERN int		XDrawPoint(Display *display, Drawable d, GC gc,
				int x, int y);



/* 86 */
EXTERN int		XDrawPoints(Display *display, Drawable d, GC gc,
				XPoint *points, int npoints, int mode);



/* 87 */
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);



/* 88 */
EXTERN int		XQueryColor(Display *display, Colormap colormap,
				XColor *def_in_out);



/* 89 */
EXTERN int		XQueryColors(Display *display, Colormap colormap,
				XColor *defs_in_out, int ncolors);



/* 90 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);



/* 91 */
EXTERN int		XSync(Display *display, Bool discard);
/* 92 */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);
/* 93 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
/* 94 */
EXTERN int		XFreeCursor(Display *d, Cursor c);
/* 95 */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);
/* 96 */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);
/* 97 */
EXTERN int		XNextEvent(Display *d, XEvent *x);
/* 98 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
/* 99 */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);

/* 100 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
/* 101 */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);
/* 102 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
/* 103 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 104 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 105 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
/* 106 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 107 */
EXTERN int		XFlush(Display *display);
/* 108 */
EXTERN int		XGrabServer(Display *display);
/* 109 */
EXTERN int		XUngrabServer(Display *display);
/* 110 */
EXTERN int		XFree(void *data);
/* 111 */
EXTERN int		XNoOp(Display *display);
/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);
/* 113 */
EXTERN Status		XLookupColor(Display *d, Colormap c1,
				_Xconst char *c2, XColor *x1, XColor *x2);
/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* 120 */
EXTERN int		XOffsetRegion(Region rgn, int dx, int dy);
/* 121 */
EXTERN int		XUnionRegion(Region srca, Region srcb,
				Region dr_return);
/* 122 */
EXTERN Window		XCreateWindow(Display *display, Window parent, int x,
				int y, unsigned int width,
				unsigned int height,
				unsigned int border_width, int depth,
				unsigned int clazz, Visual *visual,
				unsigned long value_mask,
				XSetWindowAttributes *attributes);
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* 129 */
EXTERN int		XLowerWindow(Display *d, Window w);
/* 130 */
EXTERN int		XFillArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 131 */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
EXTERN int		XDrawRectangles(Display *d, Drawable dr, GC gc,
				XRectangle *r, int n);
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* 144 */
EXTERN void		XDestroyIC(XIC xic);
/* 145 */
EXTERN Cursor		XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
				XColor *x1, XColor *x2, unsigned int ui1,
				unsigned int ui2);
/* 146 */
EXTERN Cursor		XCreateGlyphCursor(Display *d, Font f1, Font f2,
				unsigned int ui1, unsigned int ui2,
				XColor _Xconst *x1, XColor _Xconst *x2);
/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
EXTERN void		XFreeStringList(char **list);
/* 157 */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);


/* 158 */
EXTERN Display *	XkbOpenDisplay(const char *name, int *ev_rtrn,
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);
#endif /* MACOSX */

typedef struct TkIntXlibStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    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 */







|
|
|
|
<
<


<
<

|
|
<
<
<
<
<
<
<
<
















|
>
>



>
>
>


>
>
>




>
>
>




>
>
>


>
>
>


>
>
>



>
>
>




>
>
>




>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>


>
>
>




>
>
>



>
>
>


>
>
>



>
>
>




>
>
>





>
>
>




>
>
>


>
>
>


>
>
>


>
>
>




>
>
>



>
>
>



>
>
>




>
>
>



>
>
>



>
>
>


>
>
>


>
>
>



>
>
>


>
>
>


>
>
>





>
>
>


>
>
>





>
>
>



>
>
>



>
>
>




>
>
>


>
>
>



>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>



>
>
>




>
>
>



>
>
>


>
>
>


>
>
>



>
>
>


>
>
>



>
>
>


>
>
>


>
>
>


>
>
>



>
>
>



>
>
>



>
>
>



>
>
>



>
>
>



>
>
>


>
>
>




>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>






>

>
>



>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>




>
>
>


>
>
>


>
>
>




>
>
>



>
>
>



>
>
>



>
>
>




>
>
>




>
>
>


>
>
>


>
>
>


>
>
>

|
>
>
>


>
>
>


>
>
>


>
>
>


>





|
<
|
<
<
|
<
<
<
<
<
<
<






|
<
|
<
<
|
<
<
|
|
<
>



>
>
>



>
>
>



>
|
<
<
|
<
<
<
|
<
|
<
|
<
|
<
|
<
|
<



|
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
<
<
<
|
<
|
<
<
>
>

|
<
<
>

|
>
>



>
>
>


>
>
>




>
>
>




>
>
>


>
>
>


>
>
>



>
>
>


>
>
>

|
>
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>

|


>
>
>

|

>
>
>

|

>
>
>

|


>
>
>

|



>
>
>




>
>
>


>
>
>

|
>
>
>

|


>
>
>



>
>
>

|

>
>
>

|


>
>
>

|

>
>
>



>
>
>


>
>
>



>
>
>


>
>
>





>
>
>





>
>
>



>
>
>




>
>
>


>
>
>

|
>
>
>

|

>
>
>

|
>
>
>




>
>
>

|
>
>
>

|
>
>
>

|

>
>
>

|
>
>
>



>
>
>

|
>
>
>

|
>
>
>



>
>
>

|

>
>
>

|

>
>
>

|

>
>
>

|

>
>
>

|

>
>
>

|
>
>
>

|
>
>
>


>
>
>

|
>
>
>






>
>
>



>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>


>
>
>



>
>
>



>
>
>



>
>
>


>
>
>


>
>
>


>
>
>


>
>
>



>
>
>


>
>
>




>
>
>


>
>
>

|
>
>
>




>
>
>



>
>
>



>
>
>



>
>
>

|
>
>
>



>
>
>




>
>
>

|
>
>
>



>
>
>



>
>
>






>
>
>

|

>
>
>

|

>
>
>



>
>
>


<
<
<
|
|
<
|
<
|
<
|
<
<
|
<
|
<
|
<
>
|
<
|
<
<
|
<
<
|
<
|
<
|
<
|
<
<
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
<
|
<





|
<
|
<
<
|
<
<
<
<
<
<
<






|
<
|
<
<
|
<
<
|
<
<



|
<
<
|
<
<
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
<
<
|
<
<
<
|
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
<
<
<
|
<
|
<
<
>
>

|
|
<
|



|

|







15
16
17
18
19
20
21
22
23
24
25


26
27


28
29
30








31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707


708







709
710
711
712
713
714
715

716


717


718
719

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737


738



739

740

741

742

743

744

745
746
747
748

749

750




751




752

753


754

755

756





757

758


759
760
761
762


763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302



1303
1304

1305

1306

1307


1308

1309

1310

1311
1312

1313


1314


1315

1316

1317

1318



1319

1320

1321

1322

1323

1324

1325


1326

1327
1328
1329
1330
1331
1332

1333


1334







1335
1336
1337
1338
1339
1340
1341

1342


1343


1344


1345
1346
1347
1348


1349



1350

1351

1352

1353

1354

1355

1356

1357



1358



1359

1360

1361




1362




1363

1364


1365

1366

1367





1368

1369


1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

#ifdef MAC_TCL
#include "Xutil.h"
#else
#include "X11/Xutil.h"


#endif



#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT








#endif

typedef int (*XAfterFunction) (	    /* WARNING, this type not in Xlib spec */
    Display*		/* display */
);

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef XSetDashes_TCL_DECLARED
#define XSetDashes_TCL_DECLARED
/* 0 */
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(Display *d);
#endif
#ifndef XCreateImage_TCL_DECLARED
#define XCreateImage_TCL_DECLARED
/* 2 */
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(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(Display *d, Atom a);
#endif
#ifndef XKeysymToString_TCL_DECLARED
#define XKeysymToString_TCL_DECLARED
/* 5 */
EXTERN char *		XKeysymToString(KeySym k);
#endif
#ifndef XCreateColormap_TCL_DECLARED
#define XCreateColormap_TCL_DECLARED
/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);
#endif
#ifndef XCreatePixmapCursor_TCL_DECLARED
#define XCreatePixmapCursor_TCL_DECLARED
/* 7 */
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(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(GC g);
#endif
#ifndef XListHosts_TCL_DECLARED
#define XListHosts_TCL_DECLARED
/* 10 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
#endif
#ifndef XKeycodeToKeysym_TCL_DECLARED
#define XKeycodeToKeysym_TCL_DECLARED
/* 11 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, unsigned int k, int i);
#endif
#ifndef XStringToKeysym_TCL_DECLARED
#define XStringToKeysym_TCL_DECLARED
/* 12 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);
#endif
#ifndef XRootWindow_TCL_DECLARED
#define XRootWindow_TCL_DECLARED
/* 13 */
EXTERN Window		XRootWindow(Display *d, int i);
#endif
#ifndef XSetErrorHandler_TCL_DECLARED
#define XSetErrorHandler_TCL_DECLARED
/* 14 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);
#endif
#ifndef XIconifyWindow_TCL_DECLARED
#define XIconifyWindow_TCL_DECLARED
/* 15 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
#endif
#ifndef XWithdrawWindow_TCL_DECLARED
#define XWithdrawWindow_TCL_DECLARED
/* 16 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
#endif
#ifndef XGetWMColormapWindows_TCL_DECLARED
#define XGetWMColormapWindows_TCL_DECLARED
/* 17 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
#endif
#ifndef XAllocColor_TCL_DECLARED
#define XAllocColor_TCL_DECLARED
/* 18 */
EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);
#endif
#ifndef XBell_TCL_DECLARED
#define XBell_TCL_DECLARED
/* 19 */
EXTERN int		XBell(Display *d, int i);
#endif
#ifndef XChangeProperty_TCL_DECLARED
#define XChangeProperty_TCL_DECLARED
/* 20 */
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(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);
#endif
#ifndef XClearWindow_TCL_DECLARED
#define XClearWindow_TCL_DECLARED
/* 22 */
EXTERN int		XClearWindow(Display *d, Window w);
#endif
#ifndef XConfigureWindow_TCL_DECLARED
#define XConfigureWindow_TCL_DECLARED
/* 23 */
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(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(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(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(Display *d, Window w, Cursor c);
#endif
#ifndef XDeleteProperty_TCL_DECLARED
#define XDeleteProperty_TCL_DECLARED
/* 28 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
#endif
#ifndef XDestroyWindow_TCL_DECLARED
#define XDestroyWindow_TCL_DECLARED
/* 29 */
EXTERN int		XDestroyWindow(Display *d, Window w);
#endif
#ifndef XDrawArc_TCL_DECLARED
#define XDrawArc_TCL_DECLARED
/* 30 */
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(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(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(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(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(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);
#endif
#ifndef XForceScreenSaver_TCL_DECLARED
#define XForceScreenSaver_TCL_DECLARED
/* 36 */
EXTERN int		XForceScreenSaver(Display *d, int i);
#endif
#ifndef XFreeColormap_TCL_DECLARED
#define XFreeColormap_TCL_DECLARED
/* 37 */
EXTERN int		XFreeColormap(Display *d, Colormap c);
#endif
#ifndef XFreeColors_TCL_DECLARED
#define XFreeColors_TCL_DECLARED
/* 38 */
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(Display *d, Cursor c);
#endif
#ifndef XFreeModifiermap_TCL_DECLARED
#define XFreeModifiermap_TCL_DECLARED
/* 40 */
EXTERN int		XFreeModifiermap(XModifierKeymap *x);
#endif
#ifndef XGetGeometry_TCL_DECLARED
#define XGetGeometry_TCL_DECLARED
/* 41 */
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(Display *d, Window *w, int *i);
#endif
#ifndef XGetWindowProperty_TCL_DECLARED
#define XGetWindowProperty_TCL_DECLARED
/* 43 */
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(Display *d, Window w,
				XWindowAttributes *x);
#endif
#ifndef XGrabKeyboard_TCL_DECLARED
#define XGrabKeyboard_TCL_DECLARED
/* 45 */
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(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(Display *d, KeySym k);
#endif
#ifndef XLookupColor_TCL_DECLARED
#define XLookupColor_TCL_DECLARED
/* 48 */
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(Display *d, Window w);
#endif
#ifndef XMoveResizeWindow_TCL_DECLARED
#define XMoveResizeWindow_TCL_DECLARED
/* 50 */
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(Display *d, Window w, int i1, int i2);
#endif
#ifndef XNextEvent_TCL_DECLARED
#define XNextEvent_TCL_DECLARED
/* 52 */
EXTERN int		XNextEvent(Display *d, XEvent *x);
#endif
#ifndef XPutBackEvent_TCL_DECLARED
#define XPutBackEvent_TCL_DECLARED
/* 53 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
#endif
#ifndef XQueryColors_TCL_DECLARED
#define XQueryColors_TCL_DECLARED
/* 54 */
EXTERN int		XQueryColors(Display *d, Colormap c, XColor *x,
				int i);
#endif
#ifndef XQueryPointer_TCL_DECLARED
#define XQueryPointer_TCL_DECLARED
/* 55 */
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(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(Display *d, Window w);
#endif
#ifndef XRefreshKeyboardMapping_TCL_DECLARED
#define XRefreshKeyboardMapping_TCL_DECLARED
/* 58 */
EXTERN int		XRefreshKeyboardMapping(XMappingEvent *x);
#endif
#ifndef XResizeWindow_TCL_DECLARED
#define XResizeWindow_TCL_DECLARED
/* 59 */
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(Display *d, Window w, long l);
#endif
#ifndef XSendEvent_TCL_DECLARED
#define XSendEvent_TCL_DECLARED
/* 61 */
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(Display *d, Window w, char **c, int i);
#endif
#ifndef XSetIconName_TCL_DECLARED
#define XSetIconName_TCL_DECLARED
/* 63 */
EXTERN int		XSetIconName(Display *d, Window w, _Xconst char *c);
#endif
#ifndef XSetInputFocus_TCL_DECLARED
#define XSetInputFocus_TCL_DECLARED
/* 64 */
EXTERN int		XSetInputFocus(Display *d, Window w, int i, Time t);
#endif
#ifndef XSetSelectionOwner_TCL_DECLARED
#define XSetSelectionOwner_TCL_DECLARED
/* 65 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);
#endif
#ifndef XSetWindowBackground_TCL_DECLARED
#define XSetWindowBackground_TCL_DECLARED
/* 66 */
EXTERN int		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);
#endif
#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED
#define XSetWindowBackgroundPixmap_TCL_DECLARED
/* 67 */
EXTERN int		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);
#endif
#ifndef XSetWindowBorder_TCL_DECLARED
#define XSetWindowBorder_TCL_DECLARED
/* 68 */
EXTERN int		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);
#endif
#ifndef XSetWindowBorderPixmap_TCL_DECLARED
#define XSetWindowBorderPixmap_TCL_DECLARED
/* 69 */
EXTERN int		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);
#endif
#ifndef XSetWindowBorderWidth_TCL_DECLARED
#define XSetWindowBorderWidth_TCL_DECLARED
/* 70 */
EXTERN int		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);
#endif
#ifndef XSetWindowColormap_TCL_DECLARED
#define XSetWindowColormap_TCL_DECLARED
/* 71 */
EXTERN int		XSetWindowColormap(Display *d, Window w, Colormap c);
#endif
#ifndef XTranslateCoordinates_TCL_DECLARED
#define XTranslateCoordinates_TCL_DECLARED
/* 72 */
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(Display *d, Time t);
#endif
#ifndef XUngrabPointer_TCL_DECLARED
#define XUngrabPointer_TCL_DECLARED
/* 74 */
EXTERN int		XUngrabPointer(Display *d, Time t);
#endif
#ifndef XUnmapWindow_TCL_DECLARED
#define XUnmapWindow_TCL_DECLARED
/* 75 */
EXTERN int		XUnmapWindow(Display *d, Window w);
#endif
#ifndef XWindowEvent_TCL_DECLARED
#define XWindowEvent_TCL_DECLARED
/* 76 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
#endif
#ifndef XDestroyIC_TCL_DECLARED
#define XDestroyIC_TCL_DECLARED
/* 77 */
EXTERN void		XDestroyIC(XIC x);
#endif
#ifndef XFilterEvent_TCL_DECLARED
#define XFilterEvent_TCL_DECLARED
/* 78 */
EXTERN Bool		XFilterEvent(XEvent *x, Window w);
#endif
#ifndef XmbLookupString_TCL_DECLARED
#define XmbLookupString_TCL_DECLARED
/* 79 */
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(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);
#endif
/* Slot 81 is reserved */
#ifndef XParseColor_TCL_DECLARED
#define XParseColor_TCL_DECLARED
/* 82 */
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(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
#endif
#ifndef XFreeGC_TCL_DECLARED
#define XFreeGC_TCL_DECLARED
/* 84 */
EXTERN int		XFreeGC(Display *display, GC gc);
#endif
#ifndef XInternAtom_TCL_DECLARED
#define XInternAtom_TCL_DECLARED
/* 85 */
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(Display *display, GC gc,
				unsigned long foreground);
#endif
#ifndef XSetForeground_TCL_DECLARED
#define XSetForeground_TCL_DECLARED
/* 87 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);
#endif
#ifndef XSetClipMask_TCL_DECLARED
#define XSetClipMask_TCL_DECLARED
/* 88 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);
#endif
#ifndef XSetClipOrigin_TCL_DECLARED
#define XSetClipOrigin_TCL_DECLARED
/* 89 */
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(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(Display *d, GC gc, unsigned long mask,
				XGCValues *values);
#endif
#ifndef XSetFont_TCL_DECLARED
#define XSetFont_TCL_DECLARED
/* 92 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);
#endif
#ifndef XSetArcMode_TCL_DECLARED
#define XSetArcMode_TCL_DECLARED
/* 93 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);
#endif
#ifndef XSetStipple_TCL_DECLARED
#define XSetStipple_TCL_DECLARED
/* 94 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);
#endif
#ifndef XSetFillRule_TCL_DECLARED
#define XSetFillRule_TCL_DECLARED
/* 95 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);
#endif
#ifndef XSetFillStyle_TCL_DECLARED
#define XSetFillStyle_TCL_DECLARED
/* 96 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);
#endif
#ifndef XSetFunction_TCL_DECLARED
#define XSetFunction_TCL_DECLARED
/* 97 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);
#endif
#ifndef XSetLineAttributes_TCL_DECLARED
#define XSetLineAttributes_TCL_DECLARED
/* 98 */
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(XImage *image);
#endif
#ifndef XCreateIC_TCL_DECLARED
#define XCreateIC_TCL_DECLARED
/* 100 */
EXTERN XIC		XCreateIC(XIM xim, ...);
#endif
#ifndef XGetVisualInfo_TCL_DECLARED
#define XGetVisualInfo_TCL_DECLARED
/* 101 */
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(Display *display, Window w,
				XTextProperty *text_prop);
#endif
#ifndef XStringListToTextProperty_TCL_DECLARED
#define XStringListToTextProperty_TCL_DECLARED
/* 103 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);
#endif
#ifndef XDrawLine_TCL_DECLARED
#define XDrawLine_TCL_DECLARED
/* 104 */
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(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(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(Display *display);
#endif
#ifndef XGrabServer_TCL_DECLARED
#define XGrabServer_TCL_DECLARED
/* 108 */
EXTERN int		XGrabServer(Display *display);
#endif
#ifndef XUngrabServer_TCL_DECLARED
#define XUngrabServer_TCL_DECLARED
/* 109 */
EXTERN int		XUngrabServer(Display *display);
#endif
#ifndef XFree_TCL_DECLARED
#define XFree_TCL_DECLARED
/* 110 */
EXTERN int		XFree(VOID *data);
#endif
#ifndef XNoOp_TCL_DECLARED
#define XNoOp_TCL_DECLARED
/* 111 */
EXTERN int		XNoOp(Display *display);
#endif
#ifndef XSynchronize_TCL_DECLARED
#define XSynchronize_TCL_DECLARED
/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);
#endif
#ifndef XSync_TCL_DECLARED
#define XSync_TCL_DECLARED
/* 113 */
EXTERN int		XSync(Display *display, Bool discard);
#endif
#ifndef XVisualIDFromVisual_TCL_DECLARED
#define XVisualIDFromVisual_TCL_DECLARED
/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
#endif
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* Slot 120 is reserved */

/* Slot 121 is reserved */


/* Slot 122 is reserved */







/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */

/* Slot 130 is reserved */


/* Slot 131 is reserved */


/* Slot 132 is reserved */
#ifndef XDrawSegments_TCL_DECLARED

#define XDrawSegments_TCL_DECLARED
/* 133 */
EXTERN int		XDrawSegments(Display *d, Drawable dr, GC gc,
				XSegment *s, int n);
#endif
#ifndef XDrawPoint_TCL_DECLARED
#define XDrawPoint_TCL_DECLARED
/* 134 */
EXTERN int		XDrawPoint(Display *d, Drawable dr, GC gc, int x,
				int y);
#endif
#ifndef XDrawPoints_TCL_DECLARED
#define XDrawPoints_TCL_DECLARED
/* 135 */
EXTERN int		XDrawPoints(Display *d, Drawable dr, GC gc,
				XPoint *p, int n, int m);
#endif
/* Slot 136 is reserved */


/* Slot 137 is reserved */



/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */

/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* Slot 147 is reserved */

/* Slot 148 is reserved */

/* Slot 149 is reserved */




/* Slot 150 is reserved */




/* Slot 151 is reserved */

/* Slot 152 is reserved */


/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */





/* Slot 156 is reserved */

/* Slot 157 is reserved */


#ifndef TkUnusedStubEntry_TCL_DECLARED
#define TkUnusedStubEntry_TCL_DECLARED
/* 158 */
EXTERN void		TkUnusedStubEntry(void);


#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef XSetDashes_TCL_DECLARED
#define XSetDashes_TCL_DECLARED
/* 0 */
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(Display *d);
#endif
#ifndef XCreateImage_TCL_DECLARED
#define XCreateImage_TCL_DECLARED
/* 2 */
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(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(Display *d, Atom a);
#endif
#ifndef XKeysymToString_TCL_DECLARED
#define XKeysymToString_TCL_DECLARED
/* 5 */
EXTERN char *		XKeysymToString(KeySym k);
#endif
#ifndef XCreateColormap_TCL_DECLARED
#define XCreateColormap_TCL_DECLARED
/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);
#endif
#ifndef XGContextFromGC_TCL_DECLARED
#define XGContextFromGC_TCL_DECLARED
/* 7 */
EXTERN GContext		XGContextFromGC(GC g);
#endif
#ifndef XKeycodeToKeysym_TCL_DECLARED
#define XKeycodeToKeysym_TCL_DECLARED
/* 8 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, KeyCode k, int i);
#endif
#ifndef XStringToKeysym_TCL_DECLARED
#define XStringToKeysym_TCL_DECLARED
/* 9 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);
#endif
#ifndef XRootWindow_TCL_DECLARED
#define XRootWindow_TCL_DECLARED
/* 10 */
EXTERN Window		XRootWindow(Display *d, int i);
#endif
#ifndef XSetErrorHandler_TCL_DECLARED
#define XSetErrorHandler_TCL_DECLARED
/* 11 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);
#endif
#ifndef XAllocColor_TCL_DECLARED
#define XAllocColor_TCL_DECLARED
/* 12 */
EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);
#endif
#ifndef XBell_TCL_DECLARED
#define XBell_TCL_DECLARED
/* 13 */
EXTERN int		XBell(Display *d, int i);
#endif
#ifndef XChangeProperty_TCL_DECLARED
#define XChangeProperty_TCL_DECLARED
/* 14 */
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(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);
#endif
#ifndef XConfigureWindow_TCL_DECLARED
#define XConfigureWindow_TCL_DECLARED
/* 16 */
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(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(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(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(Display *d, Window w, Cursor c);
#endif
#ifndef XDestroyWindow_TCL_DECLARED
#define XDestroyWindow_TCL_DECLARED
/* 21 */
EXTERN void		XDestroyWindow(Display *d, Window w);
#endif
#ifndef XDrawArc_TCL_DECLARED
#define XDrawArc_TCL_DECLARED
/* 22 */
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(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(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(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(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(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);
#endif
#ifndef XFreeColormap_TCL_DECLARED
#define XFreeColormap_TCL_DECLARED
/* 28 */
EXTERN int		XFreeColormap(Display *d, Colormap c);
#endif
#ifndef XFreeColors_TCL_DECLARED
#define XFreeColors_TCL_DECLARED
/* 29 */
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(XModifierKeymap *x);
#endif
#ifndef XGetGeometry_TCL_DECLARED
#define XGetGeometry_TCL_DECLARED
/* 31 */
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(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(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(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(Display *d, KeySym k);
#endif
#ifndef XMapWindow_TCL_DECLARED
#define XMapWindow_TCL_DECLARED
/* 36 */
EXTERN void		XMapWindow(Display *d, Window w);
#endif
#ifndef XMoveResizeWindow_TCL_DECLARED
#define XMoveResizeWindow_TCL_DECLARED
/* 37 */
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(Display *d, Window w, int i1, int i2);
#endif
#ifndef XQueryPointer_TCL_DECLARED
#define XQueryPointer_TCL_DECLARED
/* 39 */
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(Display *d, Window w);
#endif
#ifndef XRefreshKeyboardMapping_TCL_DECLARED
#define XRefreshKeyboardMapping_TCL_DECLARED
/* 41 */
EXTERN void		XRefreshKeyboardMapping(XMappingEvent *x);
#endif
#ifndef XResizeWindow_TCL_DECLARED
#define XResizeWindow_TCL_DECLARED
/* 42 */
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(Display *d, Window w, long l);
#endif
#ifndef XSendEvent_TCL_DECLARED
#define XSendEvent_TCL_DECLARED
/* 44 */
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(Display *d, Window w, _Xconst char *c);
#endif
#ifndef XSetInputFocus_TCL_DECLARED
#define XSetInputFocus_TCL_DECLARED
/* 46 */
EXTERN void		XSetInputFocus(Display *d, Window w, int i, Time t);
#endif
#ifndef XSetSelectionOwner_TCL_DECLARED
#define XSetSelectionOwner_TCL_DECLARED
/* 47 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);
#endif
#ifndef XSetWindowBackground_TCL_DECLARED
#define XSetWindowBackground_TCL_DECLARED
/* 48 */
EXTERN void		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);
#endif
#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED
#define XSetWindowBackgroundPixmap_TCL_DECLARED
/* 49 */
EXTERN void		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);
#endif
#ifndef XSetWindowBorder_TCL_DECLARED
#define XSetWindowBorder_TCL_DECLARED
/* 50 */
EXTERN void		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);
#endif
#ifndef XSetWindowBorderPixmap_TCL_DECLARED
#define XSetWindowBorderPixmap_TCL_DECLARED
/* 51 */
EXTERN void		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);
#endif
#ifndef XSetWindowBorderWidth_TCL_DECLARED
#define XSetWindowBorderWidth_TCL_DECLARED
/* 52 */
EXTERN void		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);
#endif
#ifndef XSetWindowColormap_TCL_DECLARED
#define XSetWindowColormap_TCL_DECLARED
/* 53 */
EXTERN void		XSetWindowColormap(Display *d, Window w, Colormap c);
#endif
#ifndef XUngrabKeyboard_TCL_DECLARED
#define XUngrabKeyboard_TCL_DECLARED
/* 54 */
EXTERN void		XUngrabKeyboard(Display *d, Time t);
#endif
#ifndef XUngrabPointer_TCL_DECLARED
#define XUngrabPointer_TCL_DECLARED
/* 55 */
EXTERN int		XUngrabPointer(Display *d, Time t);
#endif
#ifndef XUnmapWindow_TCL_DECLARED
#define XUnmapWindow_TCL_DECLARED
/* 56 */
EXTERN void		XUnmapWindow(Display *d, Window w);
#endif
#ifndef TkPutImage_TCL_DECLARED
#define TkPutImage_TCL_DECLARED
/* 57 */
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);
#endif
#ifndef XParseColor_TCL_DECLARED
#define XParseColor_TCL_DECLARED
/* 58 */
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(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
#endif
#ifndef XFreeGC_TCL_DECLARED
#define XFreeGC_TCL_DECLARED
/* 60 */
EXTERN int		XFreeGC(Display *display, GC gc);
#endif
#ifndef XInternAtom_TCL_DECLARED
#define XInternAtom_TCL_DECLARED
/* 61 */
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(Display *display, GC gc,
				unsigned long foreground);
#endif
#ifndef XSetForeground_TCL_DECLARED
#define XSetForeground_TCL_DECLARED
/* 63 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);
#endif
#ifndef XSetClipMask_TCL_DECLARED
#define XSetClipMask_TCL_DECLARED
/* 64 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);
#endif
#ifndef XSetClipOrigin_TCL_DECLARED
#define XSetClipOrigin_TCL_DECLARED
/* 65 */
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(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(Display *d, GC gc, unsigned long mask,
				XGCValues *values);
#endif
#ifndef XSetFont_TCL_DECLARED
#define XSetFont_TCL_DECLARED
/* 68 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);
#endif
#ifndef XSetArcMode_TCL_DECLARED
#define XSetArcMode_TCL_DECLARED
/* 69 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);
#endif
#ifndef XSetStipple_TCL_DECLARED
#define XSetStipple_TCL_DECLARED
/* 70 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);
#endif
#ifndef XSetFillRule_TCL_DECLARED
#define XSetFillRule_TCL_DECLARED
/* 71 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);
#endif
#ifndef XSetFillStyle_TCL_DECLARED
#define XSetFillStyle_TCL_DECLARED
/* 72 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);
#endif
#ifndef XSetFunction_TCL_DECLARED
#define XSetFunction_TCL_DECLARED
/* 73 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);
#endif
#ifndef XSetLineAttributes_TCL_DECLARED
#define XSetLineAttributes_TCL_DECLARED
/* 74 */
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(XImage *image);
#endif
#ifndef XCreateIC_TCL_DECLARED
#define XCreateIC_TCL_DECLARED
/* 76 */
EXTERN XIC		XCreateIC(void);
#endif
#ifndef XGetVisualInfo_TCL_DECLARED
#define XGetVisualInfo_TCL_DECLARED
/* 77 */
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(Display *display, Window w,
				XTextProperty *text_prop);
#endif
#ifndef XStringListToTextProperty_TCL_DECLARED
#define XStringListToTextProperty_TCL_DECLARED
/* 79 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);
#endif
#ifndef XDrawSegments_TCL_DECLARED
#define XDrawSegments_TCL_DECLARED
/* 80 */
EXTERN int		XDrawSegments(Display *display, Drawable d, GC gc,
				XSegment *segments, int nsegments);
#endif
#ifndef XForceScreenSaver_TCL_DECLARED
#define XForceScreenSaver_TCL_DECLARED
/* 81 */
EXTERN void		XForceScreenSaver(Display *display, int mode);
#endif
#ifndef XDrawLine_TCL_DECLARED
#define XDrawLine_TCL_DECLARED
/* 82 */
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(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(Display *d, Window w);
#endif
#ifndef XDrawPoint_TCL_DECLARED
#define XDrawPoint_TCL_DECLARED
/* 85 */
EXTERN int		XDrawPoint(Display *display, Drawable d, GC gc,
				int x, int y);
#endif
#ifndef XDrawPoints_TCL_DECLARED
#define XDrawPoints_TCL_DECLARED
/* 86 */
EXTERN int		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(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);
#endif
#ifndef XQueryColor_TCL_DECLARED
#define XQueryColor_TCL_DECLARED
/* 88 */
EXTERN void		XQueryColor(Display *display, Colormap colormap,
				XColor *def_in_out);
#endif
#ifndef XQueryColors_TCL_DECLARED
#define XQueryColors_TCL_DECLARED
/* 89 */
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(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(Display *display, Bool discard);



#endif
/* Slot 92 is reserved */

/* Slot 93 is reserved */

/* Slot 94 is reserved */

/* Slot 95 is reserved */


/* Slot 96 is reserved */

/* Slot 97 is reserved */

/* Slot 98 is reserved */

/* Slot 99 is reserved */
/* Slot 100 is reserved */

/* Slot 101 is reserved */


/* Slot 102 is reserved */


/* Slot 103 is reserved */

/* Slot 104 is reserved */

/* Slot 105 is reserved */

/* Slot 106 is reserved */



/* Slot 107 is reserved */

/* Slot 108 is reserved */

/* Slot 109 is reserved */

/* Slot 110 is reserved */

/* Slot 111 is reserved */

/* Slot 112 is reserved */

/* Slot 113 is reserved */


/* Slot 114 is reserved */

/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* Slot 120 is reserved */

/* Slot 121 is reserved */


/* Slot 122 is reserved */







/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */

/* Slot 130 is reserved */


/* Slot 131 is reserved */


/* Slot 132 is reserved */


/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
/* Slot 136 is reserved */


/* Slot 137 is reserved */



/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */

/* Slot 144 is reserved */

/* Slot 145 is reserved */



/* Slot 146 is reserved */



/* Slot 147 is reserved */

/* Slot 148 is reserved */

/* Slot 149 is reserved */




/* Slot 150 is reserved */




/* Slot 151 is reserved */

/* Slot 152 is reserved */


/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */





/* Slot 156 is reserved */

/* Slot 157 is reserved */


#ifndef TkUnusedStubEntry_TCL_DECLARED
#define TkUnusedStubEntry_TCL_DECLARED
/* 158 */
EXTERN void		TkUnusedStubEntry(void);
#endif

#endif /* AQUA */

typedef struct TkIntXlibStubs {
    int magic;
    struct TkIntXlibStubHooks *hooks;

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    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 */
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    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)(void);
    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 */







|







1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
    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) (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 */
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242


1243
1244


1245
1246


1247
1248


1249
1250


1251
1252


1253
1254


1255
1256


1257
1258


1259
1260


1261
1262


1263
1264


1265
1266


1267
1268


1269
1270


1271
1272


1273
1274


1275
1276


1277
1278


1279
1280


1281
1282


1283
1284


1285
1286


1287
1288


1289
1290


1291
1292


1293
1294


1295
1296


1297
1298


1299
1300


1301
1302


1303
1304


1305
1306


1307
1308


1309
1310


1311
1312


1313
1314


1315
1316


1317
1318


1319
1320


1321
1322


1323
1324


1325
1326


1327
1328


1329
1330


1331
1332


1333
1334


1335
1336


1337
1338


1339
1340


1341
1342


1343
1344


1345
1346


1347
1348


1349
1350


1351
1352


1353
1354


1355
1356


1357
1358


1359
1360


1361
1362


1363
1364


1365
1366


1367
1368


1369
1370


1371
1372


1373
1374


1375
1376


1377
1378


1379
1380


1381
1382


1383
1384


1385
1386


1387
1388


1389
1390


1391
1392


1393
1394


1395
1396


1397
1398


1399
1400


1401
1402

1403

1404
1405


1406
1407


1408
1409


1410
1411


1412
1413


1414
1415


1416
1417


1418
1419


1420
1421


1422
1423


1424
1425


1426
1427


1428
1429


1430
1431


1432
1433


1434
1435


1436
1437


1438
1439


1440
1441


1442
1443


1444
1445


1446
1447


1448
1449


1450
1451


1452
1453


1454
1455


1456
1457


1458
1459


1460
1461


1462
1463


1464
1465


1466
1467


1468
1469

1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496


1497
1498


1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528


1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547


1548
1549


1550
1551


1552
1553


1554
1555


1556
1557


1558
1559


1560
1561


1562
1563


1564
1565


1566
1567


1568
1569


1570
1571


1572
1573


1574
1575


1576
1577


1578
1579


1580
1581


1582
1583


1584
1585


1586
1587


1588
1589


1590
1591


1592
1593


1594
1595


1596
1597


1598
1599


1600
1601


1602
1603


1604
1605


1606
1607


1608
1609


1610
1611


1612
1613


1614
1615


1616
1617


1618
1619


1620
1621


1622
1623


1624
1625


1626
1627


1628
1629


1630
1631


1632
1633


1634
1635


1636
1637


1638
1639


1640
1641


1642
1643


1644
1645


1646
1647


1648
1649


1650
1651


1652
1653


1654
1655


1656
1657


1658
1659


1660
1661


1662
1663


1664
1665


1666
1667


1668
1669


1670
1671


1672
1673


1674
1675


1676
1677


1678
1679


1680
1681


1682
1683


1684
1685


1686
1687


1688
1689


1690
1691


1692
1693


1694
1695


1696
1697


1698
1699


1700
1701


1702
1703


1704
1705


1706
1707


1708
1709


1710
1711


1712
1713


1714
1715


1716
1717


1718
1719


1720
1721


1722
1723


1724
1725


1726
1727


1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855


1856

1857
1858
1859
1860







1861










1862







































1863
    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 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
    int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
    Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
    int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
    int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*reserved144)(void);
    void (*reserved145)(void);
    void (*reserved146)(void);
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */
    char * (*xSetIMValues) (XIM im, ...); /* 154 */
    XFontSet (*xCreateFontSet) (Display *display, _Xconst char *base_font_name_list, char ***missing_charset_list, int *missing_charset_count, char **def_string); /* 155 */
    void (*xFreeStringList) (char **list); /* 156 */
    KeySym (*xkbKeycodeToKeysym) (Display *d, unsigned int k, int g, int i); /* 157 */
    Display * (*xkbOpenDisplay) (const char *name, int *ev_rtrn, int *err_rtrn, int *major_rtrn, int *minor_rtrn, int *reason); /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    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, unsigned int 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 */
    int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 14 */
    int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 15 */
    int (*xConfigureWindow) (Display *d, Window w, unsigned int i, XWindowChanges *x); /* 16 */
    int (*xCopyArea) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 17 */
    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); /* 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 */
    int (*xDestroyWindow) (Display *d, Window w); /* 21 */
    int (*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 */
    int (*xDrawRectangle) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 24 */
    int (*xFillArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 25 */
    int (*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 */
    int (*xMapWindow) (Display *d, Window w); /* 36 */
    int (*xMoveResizeWindow) (Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 37 */
    int (*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 */
    int (*xRaiseWindow) (Display *d, Window w); /* 40 */
    int (*xRefreshKeyboardMapping) (XMappingEvent *x); /* 41 */
    int (*xResizeWindow) (Display *d, Window w, unsigned int ui1, unsigned int ui2); /* 42 */
    int (*xSelectInput) (Display *d, Window w, long l); /* 43 */
    Status (*xSendEvent) (Display *d, Window w, Bool b, long l, XEvent *x); /* 44 */
    int (*xSetIconName) (Display *d, Window w, _Xconst char *c); /* 45 */
    int (*xSetInputFocus) (Display *d, Window w, int i, Time t); /* 46 */
    int (*xSetSelectionOwner) (Display *d, Atom a, Window w, Time t); /* 47 */
    int (*xSetWindowBackground) (Display *d, Window w, unsigned long ul); /* 48 */
    int (*xSetWindowBackgroundPixmap) (Display *d, Window w, Pixmap p); /* 49 */
    int (*xSetWindowBorder) (Display *d, Window w, unsigned long ul); /* 50 */
    int (*xSetWindowBorderPixmap) (Display *d, Window w, Pixmap p); /* 51 */
    int (*xSetWindowBorderWidth) (Display *d, Window w, unsigned int ui); /* 52 */
    int (*xSetWindowColormap) (Display *d, Window w, Colormap c); /* 53 */
    int (*xUngrabKeyboard) (Display *d, Time t); /* 54 */
    int (*xUngrabPointer) (Display *d, Time t); /* 55 */
    int (*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) (XIM xim, ...); /* 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 */
    int (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */
    int (*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 */
    int (*xClearWindow) (Display *d, Window w); /* 84 */
    int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
    int (*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 */
    int (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
    int (*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 discard); /* 91 */
    Bool (*xTranslateCoordinates) (Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); /* 92 */
    int (*xDeleteProperty) (Display *d, Window w, Atom a); /* 93 */
    int (*xFreeCursor) (Display *d, Cursor c); /* 94 */
    int (*xGetInputFocus) (Display *d, Window *w, int *i); /* 95 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 96 */
    int (*xNextEvent) (Display *d, XEvent *x); /* 97 */
    int (*xPutBackEvent) (Display *d, XEvent *x); /* 98 */
    int (*xSetCommand) (Display *d, Window w, char **c, int i); /* 99 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 100 */
    Status (*xGetWindowAttributes) (Display *d, Window w, XWindowAttributes *x); /* 101 */
    Status (*xGetWMColormapWindows) (Display *d, Window w, Window **wpp, int *ip); /* 102 */
    Status (*xIconifyWindow) (Display *d, Window w, int i); /* 103 */
    Status (*xWithdrawWindow) (Display *d, Window w, int i); /* 104 */
    XHostAddress * (*xListHosts) (Display *d, int *i, Bool *b); /* 105 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 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 */
    Status (*xLookupColor) (Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); /* 113 */
    VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
    int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
    Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*xDestroyIC) (XIC xic); /* 144 */
    Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 145 */
    Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 146 */
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */
    char * (*xSetIMValues) (XIM im, ...); /* 154 */
    XFontSet (*xCreateFontSet) (Display *display, _Xconst char *base_font_name_list, char ***missing_charset_list, int *missing_charset_count, char **def_string); /* 155 */
    void (*xFreeStringList) (char **list); /* 156 */
    KeySym (*xkbKeycodeToKeysym) (Display *d, unsigned int k, int g, int i); /* 157 */
    Display * (*xkbOpenDisplay) (const char *name, int *ev_rtrn, int *err_rtrn, int *major_rtrn, int *minor_rtrn, int *reason); /* 158 */
#endif /* MACOSX */
} TkIntXlibStubs;

extern const TkIntXlibStubs *tkIntXlibStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */

#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */


#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */


#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */


#define XGetImage \
	(tkIntXlibStubsPtr->xGetImage) /* 3 */


#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */


#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */


#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */


#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 7 */


#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 8 */


#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 9 */


#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 10 */


#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 11 */


#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 12 */


#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 13 */


#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 14 */


#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 15 */


#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 16 */


#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 17 */


#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 18 */


#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 19 */


#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 20 */


#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 21 */


#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 22 */


#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 23 */


#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 24 */


#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 25 */


#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 26 */


#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 27 */


#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 28 */


#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 29 */


#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 30 */


#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 31 */


#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 32 */


#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 33 */


#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 34 */


#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 35 */


#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 36 */


#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 37 */


#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 38 */


#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 39 */


#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 40 */


#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 41 */


#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 42 */


#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 43 */


#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 44 */


#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 45 */


#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 46 */


#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 47 */


#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 48 */


#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 49 */


#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 50 */


#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 51 */


#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 52 */


#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 53 */


#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 54 */


#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 55 */


#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 56 */


#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 57 */


#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 58 */


#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 59 */


#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 60 */


#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 61 */


#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 62 */


#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 63 */


#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 64 */


#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 65 */


#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 66 */


#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 67 */


#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 68 */


#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 69 */


#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 70 */


#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 71 */


#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 72 */


#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 73 */


#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 74 */


#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 75 */


#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 76 */


#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */


#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */


#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */


#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */

/* Slot 81 is reserved */

#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */


#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */


#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */


#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 85 */


#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 86 */


#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 87 */


#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 88 */


#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 89 */


#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 90 */


#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 91 */


#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 92 */


#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 93 */


#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 94 */


#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 95 */


#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 96 */


#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 97 */


#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 98 */


#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 99 */


#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 100 */


#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 101 */


#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 102 */


#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 103 */


#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 104 */


#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 105 */


#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 106 */


#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */


#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */


#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */


#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */


#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */


#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */


#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 113 */


#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */

/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
#define XOffsetRegion \
	(tkIntXlibStubsPtr->xOffsetRegion) /* 120 */
#define XUnionRegion \
	(tkIntXlibStubsPtr->xUnionRegion) /* 121 */
#define XCreateWindow \
	(tkIntXlibStubsPtr->xCreateWindow) /* 122 */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
#define XLowerWindow \
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 133 */


#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */


#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \


	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */

#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */


#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */


#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */


#define XGetImage \
	(tkIntXlibStubsPtr->xGetImage) /* 3 */


#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */


#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */


#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */


#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 7 */


#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 8 */


#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 9 */


#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 10 */


#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 11 */


#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 12 */


#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 13 */


#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 14 */


#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 15 */


#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 16 */


#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 17 */


#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 18 */


#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 19 */


#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 20 */


#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 21 */


#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 22 */


#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 23 */


#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 24 */


#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 25 */


#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 26 */


#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 27 */


#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 28 */


#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 29 */


#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 30 */


#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 31 */


#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 32 */


#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 33 */


#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 34 */


#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 35 */


#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 36 */


#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 37 */


#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 38 */


#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 39 */


#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 40 */


#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 41 */


#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 42 */


#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 43 */


#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 44 */


#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 45 */


#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 46 */


#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 47 */


#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 48 */


#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 49 */


#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 50 */


#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 51 */


#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 52 */


#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 53 */


#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 54 */


#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 55 */


#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 56 */


#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 57 */


#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 58 */


#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 59 */


#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 60 */


#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 61 */


#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 62 */


#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 63 */


#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 64 */


#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 65 */


#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 66 */


#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 67 */


#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 68 */


#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 69 */


#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 70 */


#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 71 */


#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 72 */


#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 73 */


#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 74 */


#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 75 */


#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 76 */


#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 77 */


#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 78 */


#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 79 */


#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 80 */


#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 81 */


#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 82 */


#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 83 */


#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 84 */


#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 85 */


#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 86 */


#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 87 */


#define XQueryColor \
	(tkIntXlibStubsPtr->xQueryColor) /* 88 */


#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 89 */


#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 90 */


#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 91 */
#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 92 */
#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 93 */
#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 94 */
#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 95 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 96 */
#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 97 */
#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 98 */
#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 99 */
#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 100 */
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 101 */
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 102 */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 103 */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 104 */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 105 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 106 */
#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */
#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */
#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */
#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 113 */
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
#define XOffsetRegion \
	(tkIntXlibStubsPtr->xOffsetRegion) /* 120 */
#define XUnionRegion \
	(tkIntXlibStubsPtr->xUnionRegion) /* 121 */
#define XCreateWindow \
	(tkIntXlibStubsPtr->xCreateWindow) /* 122 */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
#define XLowerWindow \
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 144 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 145 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 146 */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \
	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
#endif /* MACOSX */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */



#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* X11, Except MacOS/Cygwin */

EXTERN Display *XkbOpenDisplay(const char *, int *, int *, int *, int *, int *);
#endif

#undef TCL_STORAGE_CLASS







#define TCL_STORAGE_CLASS DLLIMPORT


















































#endif /* _TKINTXLIBDECLS */







|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|








|





|
|
|
|
|


|
|

|
|
|









|
|
|

|
|
|
|

|
|

|
|
|
|
|
|
|

|



















|




|


|



|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|





|





|
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>

>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>





<
|
<
|
<
|






|
|
|
|
|
<
<
<


>
>


>
>


|
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|



|
|
|
|
|
|
|
|
|
>
>
|
|
|
<
<
<
<
<
<
<
<
<
<
|
<

|
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


>
>


|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
|
<
|
<
<
|
<
|
<
|
<
|
<
|





<
|
<
|
<
|






<
|
<
|
<
|
<
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|



>
>
|
>
|
|

|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179

2180

2181

2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193



2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205

2206

2207

2208

2209

2210

2211

2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229










2230

2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608








2609

2610

2611

2612

2613

2614

2615

2616
2617

2618


2619

2620

2621

2622

2623
2624
2625
2626
2627
2628

2629

2630

2631
2632
2633
2634
2635
2636
2637

2638

2639

2640

2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667

2668
2669






2670













2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
    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 */
    VOID *reserved115;
    VOID *reserved116;
    VOID *reserved117;
    VOID *reserved118;
    VOID *reserved119;
    VOID *reserved120;
    VOID *reserved121;
    VOID *reserved122;
    VOID *reserved123;
    VOID *reserved124;
    VOID *reserved125;
    VOID *reserved126;
    VOID *reserved127;
    VOID *reserved128;
    VOID *reserved129;
    VOID *reserved130;
    VOID *reserved131;
    VOID *reserved132;
    int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
    int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
    int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
    VOID *reserved136;
    VOID *reserved137;
    VOID *reserved138;
    VOID *reserved139;
    VOID *reserved140;
    VOID *reserved141;
    VOID *reserved142;
    VOID *reserved143;
    VOID *reserved144;
    VOID *reserved145;
    VOID *reserved146;
    VOID *reserved147;
    VOID *reserved148;
    VOID *reserved149;
    VOID *reserved150;
    VOID *reserved151;
    VOID *reserved152;
    VOID *reserved153;
    VOID *reserved154;
    VOID *reserved155;
    VOID *reserved156;
    VOID *reserved157;
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    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 */
    int (*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 */
    int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
    int (*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 discard); /* 91 */
    VOID *reserved92;
    VOID *reserved93;
    VOID *reserved94;
    VOID *reserved95;
    VOID *reserved96;
    VOID *reserved97;
    VOID *reserved98;
    VOID *reserved99;
    VOID *reserved100;
    VOID *reserved101;
    VOID *reserved102;
    VOID *reserved103;
    VOID *reserved104;
    VOID *reserved105;
    VOID *reserved106;
    VOID *reserved107;
    VOID *reserved108;
    VOID *reserved109;
    VOID *reserved110;
    VOID *reserved111;
    VOID *reserved112;
    VOID *reserved113;
    VOID *reserved114;
    VOID *reserved115;
    VOID *reserved116;
    VOID *reserved117;
    VOID *reserved118;
    VOID *reserved119;
    VOID *reserved120;
    VOID *reserved121;
    VOID *reserved122;
    VOID *reserved123;
    VOID *reserved124;
    VOID *reserved125;
    VOID *reserved126;
    VOID *reserved127;
    VOID *reserved128;
    VOID *reserved129;
    VOID *reserved130;
    VOID *reserved131;
    VOID *reserved132;
    VOID *reserved133;
    VOID *reserved134;
    VOID *reserved135;
    VOID *reserved136;
    VOID *reserved137;
    VOID *reserved138;
    VOID *reserved139;
    VOID *reserved140;
    VOID *reserved141;
    VOID *reserved142;
    VOID *reserved143;
    VOID *reserved144;
    VOID *reserved145;
    VOID *reserved146;
    VOID *reserved147;
    VOID *reserved148;
    VOID *reserved149;
    VOID *reserved150;
    VOID *reserved151;
    VOID *reserved152;
    VOID *reserved153;
    VOID *reserved154;
    VOID *reserved155;
    VOID *reserved156;
    VOID *reserved157;
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* AQUA */
} TkIntXlibStubs;

extern TkIntXlibStubs *tkIntXlibStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)

/*
 * Inline function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef XSetDashes
#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#endif
#ifndef XGetModifierMapping
#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */
#endif
#ifndef XCreateImage
#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */
#endif
#ifndef XGetImage
#define XGetImage \
	(tkIntXlibStubsPtr->xGetImage) /* 3 */
#endif
#ifndef XGetAtomName
#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */
#endif
#ifndef XKeysymToString
#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */
#endif
#ifndef XCreateColormap
#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */
#endif
#ifndef XCreatePixmapCursor
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 7 */
#endif
#ifndef XCreateGlyphCursor
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 8 */
#endif
#ifndef XGContextFromGC
#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 9 */
#endif
#ifndef XListHosts
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 10 */
#endif
#ifndef XKeycodeToKeysym
#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 11 */
#endif
#ifndef XStringToKeysym
#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 12 */
#endif
#ifndef XRootWindow
#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 13 */
#endif
#ifndef XSetErrorHandler
#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 14 */
#endif
#ifndef XIconifyWindow
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 15 */
#endif
#ifndef XWithdrawWindow
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 16 */
#endif
#ifndef XGetWMColormapWindows
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 17 */
#endif
#ifndef XAllocColor
#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 18 */
#endif
#ifndef XBell
#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 19 */
#endif
#ifndef XChangeProperty
#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 20 */
#endif
#ifndef XChangeWindowAttributes
#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 21 */
#endif
#ifndef XClearWindow
#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 22 */
#endif
#ifndef XConfigureWindow
#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 23 */
#endif
#ifndef XCopyArea
#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 24 */
#endif
#ifndef XCopyPlane
#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 25 */
#endif
#ifndef XCreateBitmapFromData
#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 26 */
#endif
#ifndef XDefineCursor
#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 27 */
#endif
#ifndef XDeleteProperty
#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 28 */
#endif
#ifndef XDestroyWindow
#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 29 */
#endif
#ifndef XDrawArc
#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 30 */
#endif
#ifndef XDrawLines
#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 31 */
#endif
#ifndef XDrawRectangle
#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 32 */
#endif
#ifndef XFillArc
#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 33 */
#endif
#ifndef XFillPolygon
#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 34 */
#endif
#ifndef XFillRectangles
#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 35 */
#endif
#ifndef XForceScreenSaver
#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 36 */
#endif
#ifndef XFreeColormap
#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 37 */
#endif
#ifndef XFreeColors
#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 38 */
#endif
#ifndef XFreeCursor
#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 39 */
#endif
#ifndef XFreeModifiermap
#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 40 */
#endif
#ifndef XGetGeometry
#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 41 */
#endif
#ifndef XGetInputFocus
#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 42 */
#endif
#ifndef XGetWindowProperty
#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 43 */
#endif
#ifndef XGetWindowAttributes
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 44 */
#endif
#ifndef XGrabKeyboard
#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 45 */
#endif
#ifndef XGrabPointer
#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 46 */
#endif
#ifndef XKeysymToKeycode
#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 47 */
#endif
#ifndef XLookupColor
#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 48 */
#endif
#ifndef XMapWindow
#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 49 */
#endif
#ifndef XMoveResizeWindow
#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 50 */
#endif
#ifndef XMoveWindow
#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 51 */
#endif
#ifndef XNextEvent
#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 52 */
#endif
#ifndef XPutBackEvent
#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 53 */
#endif
#ifndef XQueryColors
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 54 */
#endif
#ifndef XQueryPointer
#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 55 */
#endif
#ifndef XQueryTree
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 56 */
#endif
#ifndef XRaiseWindow
#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 57 */
#endif
#ifndef XRefreshKeyboardMapping
#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 58 */
#endif
#ifndef XResizeWindow
#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 59 */
#endif
#ifndef XSelectInput
#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 60 */
#endif
#ifndef XSendEvent
#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 61 */
#endif
#ifndef XSetCommand
#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 62 */
#endif
#ifndef XSetIconName
#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 63 */
#endif
#ifndef XSetInputFocus
#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 64 */
#endif
#ifndef XSetSelectionOwner
#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 65 */
#endif
#ifndef XSetWindowBackground
#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 66 */
#endif
#ifndef XSetWindowBackgroundPixmap
#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 67 */
#endif
#ifndef XSetWindowBorder
#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 68 */
#endif
#ifndef XSetWindowBorderPixmap
#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 69 */
#endif
#ifndef XSetWindowBorderWidth
#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 70 */
#endif
#ifndef XSetWindowColormap
#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 71 */
#endif
#ifndef XTranslateCoordinates
#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 72 */
#endif
#ifndef XUngrabKeyboard
#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 73 */
#endif
#ifndef XUngrabPointer
#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 74 */
#endif
#ifndef XUnmapWindow
#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 75 */
#endif
#ifndef XWindowEvent
#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 76 */
#endif
#ifndef XDestroyIC
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#endif
#ifndef XFilterEvent
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#endif
#ifndef XmbLookupString
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#endif
#ifndef TkPutImage
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
#endif
/* Slot 81 is reserved */
#ifndef XParseColor
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#endif
#ifndef XCreateGC
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#endif
#ifndef XFreeGC
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#endif
#ifndef XInternAtom
#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 85 */
#endif
#ifndef XSetBackground
#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 86 */
#endif
#ifndef XSetForeground
#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 87 */
#endif
#ifndef XSetClipMask
#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 88 */
#endif
#ifndef XSetClipOrigin
#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 89 */
#endif
#ifndef XSetTSOrigin
#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 90 */
#endif
#ifndef XChangeGC
#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 91 */
#endif
#ifndef XSetFont
#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 92 */
#endif
#ifndef XSetArcMode
#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 93 */
#endif
#ifndef XSetStipple
#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 94 */
#endif
#ifndef XSetFillRule
#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 95 */
#endif
#ifndef XSetFillStyle
#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 96 */
#endif
#ifndef XSetFunction
#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 97 */
#endif
#ifndef XSetLineAttributes
#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 98 */
#endif
#ifndef _XInitImageFuncPtrs
#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 99 */
#endif
#ifndef XCreateIC
#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 100 */
#endif
#ifndef XGetVisualInfo
#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 101 */
#endif
#ifndef XSetWMClientMachine
#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 102 */
#endif
#ifndef XStringListToTextProperty
#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 103 */
#endif
#ifndef XDrawLine
#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 104 */
#endif
#ifndef XWarpPointer
#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 105 */
#endif
#ifndef XFillRectangle
#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 106 */
#endif
#ifndef XFlush
#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#endif
#ifndef XGrabServer
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#endif
#ifndef XUngrabServer
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#endif
#ifndef XFree
#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */
#endif
#ifndef XNoOp
#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */
#endif
#ifndef XSynchronize
#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */
#endif
#ifndef XSync
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 113 */
#endif
#ifndef XVisualIDFromVisual
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
#endif
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */

/* Slot 120 is reserved */

/* Slot 121 is reserved */

/* Slot 122 is reserved */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
#ifndef XDrawSegments



#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 133 */
#endif
#ifndef XDrawPoint
#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */
#endif
#ifndef XDrawPoints
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#endif
/* Slot 136 is reserved */

/* Slot 137 is reserved */

/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* Slot 147 is reserved */
/* Slot 148 is reserved */
/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */
/* Slot 152 is reserved */
/* Slot 153 is reserved */
/* Slot 154 is reserved */
/* Slot 155 is reserved */
/* Slot 156 is reserved */
/* Slot 157 is reserved */
#ifndef TkUnusedStubEntry
#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */










#endif

#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef XSetDashes
#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#endif
#ifndef XGetModifierMapping
#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */
#endif
#ifndef XCreateImage
#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */
#endif
#ifndef XGetImage
#define XGetImage \
	(tkIntXlibStubsPtr->xGetImage) /* 3 */
#endif
#ifndef XGetAtomName
#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */
#endif
#ifndef XKeysymToString
#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */
#endif
#ifndef XCreateColormap
#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */
#endif
#ifndef XGContextFromGC
#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 7 */
#endif
#ifndef XKeycodeToKeysym
#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 8 */
#endif
#ifndef XStringToKeysym
#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 9 */
#endif
#ifndef XRootWindow
#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 10 */
#endif
#ifndef XSetErrorHandler
#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 11 */
#endif
#ifndef XAllocColor
#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 12 */
#endif
#ifndef XBell
#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 13 */
#endif
#ifndef XChangeProperty
#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 14 */
#endif
#ifndef XChangeWindowAttributes
#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 15 */
#endif
#ifndef XConfigureWindow
#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 16 */
#endif
#ifndef XCopyArea
#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 17 */
#endif
#ifndef XCopyPlane
#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 18 */
#endif
#ifndef XCreateBitmapFromData
#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 19 */
#endif
#ifndef XDefineCursor
#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 20 */
#endif
#ifndef XDestroyWindow
#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 21 */
#endif
#ifndef XDrawArc
#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 22 */
#endif
#ifndef XDrawLines
#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 23 */
#endif
#ifndef XDrawRectangle
#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 24 */
#endif
#ifndef XFillArc
#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 25 */
#endif
#ifndef XFillPolygon
#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 26 */
#endif
#ifndef XFillRectangles
#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 27 */
#endif
#ifndef XFreeColormap
#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 28 */
#endif
#ifndef XFreeColors
#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 29 */
#endif
#ifndef XFreeModifiermap
#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 30 */
#endif
#ifndef XGetGeometry
#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 31 */
#endif
#ifndef XGetWindowProperty
#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 32 */
#endif
#ifndef XGrabKeyboard
#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 33 */
#endif
#ifndef XGrabPointer
#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 34 */
#endif
#ifndef XKeysymToKeycode
#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 35 */
#endif
#ifndef XMapWindow
#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 36 */
#endif
#ifndef XMoveResizeWindow
#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 37 */
#endif
#ifndef XMoveWindow
#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 38 */
#endif
#ifndef XQueryPointer
#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 39 */
#endif
#ifndef XRaiseWindow
#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 40 */
#endif
#ifndef XRefreshKeyboardMapping
#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 41 */
#endif
#ifndef XResizeWindow
#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 42 */
#endif
#ifndef XSelectInput
#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 43 */
#endif
#ifndef XSendEvent
#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 44 */
#endif
#ifndef XSetIconName
#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 45 */
#endif
#ifndef XSetInputFocus
#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 46 */
#endif
#ifndef XSetSelectionOwner
#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 47 */
#endif
#ifndef XSetWindowBackground
#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 48 */
#endif
#ifndef XSetWindowBackgroundPixmap
#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 49 */
#endif
#ifndef XSetWindowBorder
#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 50 */
#endif
#ifndef XSetWindowBorderPixmap
#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 51 */
#endif
#ifndef XSetWindowBorderWidth
#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 52 */
#endif
#ifndef XSetWindowColormap
#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 53 */
#endif
#ifndef XUngrabKeyboard
#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 54 */
#endif
#ifndef XUngrabPointer
#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 55 */
#endif
#ifndef XUnmapWindow
#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 56 */
#endif
#ifndef TkPutImage
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 57 */
#endif
#ifndef XParseColor
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 58 */
#endif
#ifndef XCreateGC
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 59 */
#endif
#ifndef XFreeGC
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 60 */
#endif
#ifndef XInternAtom
#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 61 */
#endif
#ifndef XSetBackground
#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 62 */
#endif
#ifndef XSetForeground
#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 63 */
#endif
#ifndef XSetClipMask
#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 64 */
#endif
#ifndef XSetClipOrigin
#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 65 */
#endif
#ifndef XSetTSOrigin
#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 66 */
#endif
#ifndef XChangeGC
#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 67 */
#endif
#ifndef XSetFont
#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 68 */
#endif
#ifndef XSetArcMode
#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 69 */
#endif
#ifndef XSetStipple
#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 70 */
#endif
#ifndef XSetFillRule
#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 71 */
#endif
#ifndef XSetFillStyle
#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 72 */
#endif
#ifndef XSetFunction
#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 73 */
#endif
#ifndef XSetLineAttributes
#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 74 */
#endif
#ifndef _XInitImageFuncPtrs
#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 75 */
#endif
#ifndef XCreateIC
#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 76 */
#endif
#ifndef XGetVisualInfo
#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 77 */
#endif
#ifndef XSetWMClientMachine
#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 78 */
#endif
#ifndef XStringListToTextProperty
#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 79 */
#endif
#ifndef XDrawSegments
#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 80 */
#endif
#ifndef XForceScreenSaver
#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 81 */
#endif
#ifndef XDrawLine
#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 82 */
#endif
#ifndef XFillRectangle
#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 83 */
#endif
#ifndef XClearWindow
#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 84 */
#endif
#ifndef XDrawPoint
#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 85 */
#endif
#ifndef XDrawPoints
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 86 */
#endif
#ifndef XWarpPointer
#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 87 */
#endif
#ifndef XQueryColor
#define XQueryColor \
	(tkIntXlibStubsPtr->xQueryColor) /* 88 */
#endif
#ifndef XQueryColors
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 89 */
#endif
#ifndef XQueryTree
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 90 */
#endif
#ifndef XSync
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 91 */
#endif
/* Slot 92 is reserved */
/* Slot 93 is reserved */
/* Slot 94 is reserved */
/* Slot 95 is reserved */
/* Slot 96 is reserved */
/* Slot 97 is reserved */
/* Slot 98 is reserved */
/* Slot 99 is reserved */








/* Slot 100 is reserved */

/* Slot 101 is reserved */

/* Slot 102 is reserved */

/* Slot 103 is reserved */

/* Slot 104 is reserved */

/* Slot 105 is reserved */

/* Slot 106 is reserved */

/* Slot 107 is reserved */
/* Slot 108 is reserved */

/* Slot 109 is reserved */


/* Slot 110 is reserved */

/* Slot 111 is reserved */

/* Slot 112 is reserved */

/* Slot 113 is reserved */

/* Slot 114 is reserved */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */

/* Slot 120 is reserved */

/* Slot 121 is reserved */

/* Slot 122 is reserved */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */

/* Slot 129 is reserved */

/* Slot 130 is reserved */

/* Slot 131 is reserved */

/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
/* Slot 136 is reserved */
/* Slot 137 is reserved */
/* Slot 138 is reserved */
/* Slot 139 is reserved */
/* Slot 140 is reserved */
/* Slot 141 is reserved */
/* Slot 142 is reserved */
/* Slot 143 is reserved */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* Slot 147 is reserved */
/* Slot 148 is reserved */
/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */
/* Slot 152 is reserved */
/* Slot 153 is reserved */
/* Slot 154 is reserved */
/* Slot 155 is reserved */
/* Slot 156 is reserved */
/* Slot 157 is reserved */
#ifndef TkUnusedStubEntry

#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */






#endif













#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkUnusedStubEntry

#if defined(__WIN32__)

#undef XFlush
#undef XGrabServer
#undef XUngrabServer
#undef XFree
#undef XNoOp
#undef XSynchronize
#undef XSync
#undef XVisualIDFromVisual

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)
/*
 * The following stubs implement various calls that don't do anything
 * under Windows. In win32 tclsh 8.4 and 8.5 holds:
 *         tkIntStubsPtr->tkBindDeadWindow != NULL
 * Then the following macros don't do anything. But when running Tcl win32
 * version 8.6 or Cygwin (8.4, 8.5 or 8.6) then the functions are available in
 * the stub table. The real function from the stub table will be called,
 * even though it might be doing nothing.
 */

#define XFlush(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xFlush(display))
#define XGrabServer(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xGrabServer(display))
#define XUngrabServer(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xUngrabServer(display))

/*
 * The following functions are implemented as macros under Windows.
 */


#define XFree(data) (tkIntStubsPtr->tkBindDeadWindow? ((data)? (ckfree((char *) (data)), 0): 0): tkIntXlibStubsPtr->xFree(data))
#define XNoOp(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xNoOp(display))
#define XSynchronize(display, bool) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xSynchronize(display, bool))
#define XSync(display, bool) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xSync(display, bool))
#define XVisualIDFromVisual(visual) (tkIntStubsPtr->tkBindDeadWindow? ((visual)->visualid): tkIntXlibStubsPtr->xVisualIDFromVisual(visual))

#else /* !USE_TK_STUBS */
/*
 * The following stubs implement various calls that don't do anything
 * under Windows.
 */

#define XFlush(display)
#define XGrabServer(display)
#define XUngrabServer(display)

/*
 * The following functions are implemented as macros under Windows.
 */

#define XFree(data) {if ((data) != NULL) ckfree((char *) (data));}
#define XNoOp(display) {display->request++;}
#define XSynchronize(display, bool) {display->request++;}
#define XSync(display, bool) {display->request++;}
#define XVisualIDFromVisual(visual) (visual->visualid)

#endif /* !USE_TK_STUBS */

#endif /* __WIN32__ */

#endif /* _TKINTXLIBDECLS */

Changes to generic/tkListbox.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * 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.
 */

#include "tkInt.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

typedef struct {
    Tk_OptionTable listboxOptionTable;
				/* Table defining configuration options
				 * available for the listbox. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table defining configuration options
				 * available for listbox items. */
} ListboxOptionTables;

/*
 * A data structure of the following type is kept for each listbox widget
 * managed by this file:
 */







|
|

|








|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * 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.
 */

#include "default.h"
#include "tkInt.h"

#ifdef WIN32
#include "tkWinInt.h"
#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. */
} ListboxOptionTables;

/*
 * A data structure of the following type is kept for each listbox widget
 * managed by this file:
 */
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    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 topIndex;		/* Index of top-most element visible in
				 * window. */
    int fullLines;		/* Number of lines that are completely
				 * 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
				 * visible. */
    int setGrid;		/* Non-zero means pass gridding information to
				 * window manager. */

    /*
     * Information to support horizontal scrolling:
     */

    int maxWidth;		/* Width (in pixels) of widest string in
				 * listbox. */
    int xScrollUnit;		/* Number of pixels in one "unit" for
				 * 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). This is x scrolling information
                                 * is not linked to justification. */

    /*
     * 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
				 * 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 activeStyle;		/* Style in which to draw the active element.
				 * One of: underline, none, dotbox */

    /*
     * Information for scanning:
     */

    int scanMarkX;		/* X-position at which scan started (e.g.







|






|
















|
<
















|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    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 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
				 * 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
				 * visble. */
    int setGrid;		/* Non-zero means pass gridding information to
				 * window manager. */

    /*
     * Information to support horizontal scrolling:
     */

    int maxWidth;		/* Width (in pixels) of widest string in
				 * listbox. */
    int xScrollUnit;		/* Number of pixels in one "unit" for
				 * 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). */


    /*
     * 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
				 * 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 activeStyle;		/* style in which to draw the active element.
				 * One of: underline, none, dotbox */

    /*
     * Information for scanning:
     */

    int scanMarkX;		/* X-position at which scan started (e.g.
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    char *xScrollCmd;		/* Command prefix for communicating with
				 * 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
				 * definitions. */
    Tk_Justify justify;         /* Justification. */
} Listbox;

/*
 * How to encode the keys for the hash tables used to store what items are
 * selected and what the attributes are.
 */

#define KEY(i)		((char *) INT2PTR(i))

/*
 * 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 */







<


<
<
<
<
<
<
<







161
162
163
164
165
166
167

168
169







170
171
172
173
174
175
176
    char *xScrollCmd;		/* Command prefix for communicating with
				 * 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
				 * definitions. */

} Listbox;








/*
 * 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 */
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 *				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.
 */

#define REDRAW_PENDING		1
#define UPDATE_V_SCROLLBAR	2
#define UPDATE_H_SCROLLBAR	4
#define GOT_FOCUS		8







|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 *				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.
 */

#define REDRAW_PENDING		1
#define UPDATE_V_SCROLLBAR	2
#define UPDATE_H_SCROLLBAR	4
#define GOT_FOCUS		8
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
/*
 * The optionSpecs table defines the valid configuration options for the
 * listbox widget.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle",
	DEF_LISTBOX_ACTIVE_STYLE, TCL_INDEX_NONE, offsetof(Listbox, activeStyle),
	0, activeStyleStrings, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_LISTBOX_BG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, normalBorder),
	 0, DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_LISTBOX_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, borderWidth),
	 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_LISTBOX_CURSOR, TCL_INDEX_NONE, offsetof(Listbox, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	 "DisabledForeground", DEF_LISTBOX_DISABLED_FG, TCL_INDEX_NONE,
	 offsetof(Listbox, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	 "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, TCL_INDEX_NONE,
	 offsetof(Listbox, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	 DEF_LISTBOX_FONT, TCL_INDEX_NONE, offsetof(Listbox, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	 DEF_LISTBOX_FG, TCL_INDEX_NONE, offsetof(Listbox, fgColorPtr), 0, 0, 0},
    {TK_OPTION_INT, "-height", "height", "Height",
	 DEF_LISTBOX_HEIGHT, TCL_INDEX_NONE, offsetof(Listbox, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, TCL_INDEX_NONE, offsetof(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder),
	 0, DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, TCL_INDEX_NONE,
	 offsetof(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, TCL_INDEX_NONE, offsetof(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	 DEF_LISTBOX_SET_GRID, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, yScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable",
	 DEF_LISTBOX_LIST_VARIABLE, TCL_INDEX_NONE, offsetof(Listbox, listVarName),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, border),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, fgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selBorder),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 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.
 */

static const char *const commandNames[] = {
    "activate", "bbox", "cget", "configure", "curselection", "delete", "get",
    "index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
    "see", "selection", "size", "xview", "yview", NULL
};
enum command {
    COMMAND_ACTIVATE, COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE,
    COMMAND_CURSELECTION, COMMAND_DELETE, COMMAND_GET, COMMAND_INDEX,
    COMMAND_INSERT, COMMAND_ITEMCGET, COMMAND_ITEMCONFIGURE,
    COMMAND_NEAREST, COMMAND_SCAN, COMMAND_SEE, COMMAND_SELECTION,
    COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW
};

static const char *const selCommandNames[] = {
    "anchor", "clear", "includes", "set", NULL
};
enum selcommand {
    SELECTION_ANCHOR, SELECTION_CLEAR, SELECTION_INCLUDES, SELECTION_SET
};

static const char *const scanCommandNames[] = {
    "mark", "dragto", NULL
};
enum scancommand {
    SCAN_MARK, SCAN_DRAGTO
};

static const char *const indexNames[] = {
    "active", "anchor", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR
};

/*
 * Declarations for procedures defined later in this file.
 */

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[]);
static int		ConfigureListboxItem(Tcl_Interp *interp,
			    Listbox *listPtr, ItemAttr *attrs, int objc,
			    Tcl_Obj *const objv[], int index);
static int		ListboxDeleteSubCmd(Listbox *listPtr,
			    int first, int last);
static void		DestroyListbox(void *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 TkSizeT	ListboxFetchSelection(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		ListboxLostSelection(ClientData clientData);
static void		GenerateListboxSelectEvent(Listbox *listPtr);
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);







|
|

|
|

|

|

|


|


|
|

|
|

|

|

|

|

|
|

|


|
|
<
<

|

|
|

|
|

|
|

|


|

|
|

|


|

|


|


|

|




|




|

|

|

|

|


|

|

|

|
|



|




|












|






|






|
|


|















|












|
|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
/*
 * The optionSpecs table defines the valid configuration options for the
 * listbox widget.
 */

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},
    {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", 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},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_LISTBOX_CURSOR, -1, Tk_Offset(Listbox, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	 "DisabledForeground", DEF_LISTBOX_DISABLED_FG, -1,
	 Tk_Offset(Listbox, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	 "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, -1,
	 Tk_Offset(Listbox, exportSelection), 0, 0, 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",
	 DEF_LISTBOX_FG, -1, Tk_Offset(Listbox, fgColorPtr), 0, 0, 0},
    {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,
	 Tk_Offset(Listbox, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, -1, Tk_Offset(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Listbox, highlightWidth), 0, 0, 0},


    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, -1, Tk_Offset(Listbox, selBorder),
	 0, (ClientData) DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, -1,
	 Tk_Offset(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, (ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, -1, Tk_Offset(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {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},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, -1, Tk_Offset(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, -1, Tk_Offset(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, -1, Tk_Offset(Listbox, xScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, -1, Tk_Offset(Listbox, yScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable",
	 DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName),
	 TK_OPTION_NULL_OK, 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[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
     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", 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",
     NULL, -1, Tk_Offset(ItemAttr, fgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
     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",
     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, 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.
 */

static const char *commandNames[] = {
    "activate", "bbox", "cget", "configure", "curselection", "delete", "get",
    "index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
    "see", "selection", "size", "xview", "yview", NULL
};
enum command {
    COMMAND_ACTIVATE, COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE,
    COMMAND_CURSELECTION, COMMAND_DELETE, COMMAND_GET, COMMAND_INDEX,
    COMMAND_INSERT, COMMAND_ITEMCGET, COMMAND_ITEMCONFIGURE,
    COMMAND_NEAREST, COMMAND_SCAN, COMMAND_SEE, COMMAND_SELECTION,
    COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW
};

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", NULL
};
enum scancommand {
    SCAN_MARK, SCAN_DRAGTO
};

static const char *indexNames[] = {
    "active", "anchor", "end", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR, INDEX_END
};

/*
 * Declarations for procedures defined later in this file.
 */

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[]);
static int		ConfigureListboxItem(Tcl_Interp *interp,
			    Listbox *listPtr, ItemAttr *attrs, int objc,
			    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		GenerateListboxSelectEvent(Listbox *listPtr);
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);
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
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);
static int		GetMaxOffset(Listbox *listPtr);

/*
 * The structure below defines button class behavior by means of procedures
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs listboxClass = {
    sizeof(Tk_ClassProcs),	/* size */
    ListboxWorldChanged,	/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_ListboxObjCmd --
 *







<






|


|
|







425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
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.
 */

static Tk_ClassProcs listboxClass = {
    sizeof(Tk_ClassProcs),	/* size */
    ListboxWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_ListboxObjCmd --
 *
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Listbox *listPtr;
    Tk_Window tkwin;
    ListboxOptionTables *optionTables;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    optionTables = (ListboxOptionTables *)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.
	 */

	optionTables = (ListboxOptionTables *)ckalloc(sizeof(ListboxOptionTables));


	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "ListboxOptionTables",
		DestroyListboxOptionTables, optionTables);

	/*
	 * Create the listbox option table and the listbox item option table.
	 */

	optionTables->listboxOptionTable =
		Tk_CreateOptionTable(interp, optionSpecs);
	optionTables->itemAttrOptionTable =
		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).
     */

    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, listPtr,
	    ListboxCmdDeletedProc);
    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));

    Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
    listPtr->relief		 = TK_RELIEF_RAISED;
    listPtr->textGC		 = NULL;
    listPtr->selFgColorPtr	 = NULL;
    listPtr->selTextGC		 = NULL;
    listPtr->fullLines		 = 1;
    listPtr->xScrollUnit	 = 1;
    listPtr->exportSelection	 = 1;
    listPtr->cursor		 = NULL;
    listPtr->state		 = STATE_NORMAL;
    listPtr->gray		 = None;
    listPtr->justify             = TK_JUSTIFY_LEFT;

    /*
     * Keep a hold of the associated tkwin until we destroy the listbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(listPtr->tkwin);

    Tk_SetClass(listPtr->tkwin, "Listbox");
    Tk_SetClassProcs(listPtr->tkwin, &listboxClass, listPtr);
    Tk_CreateEventHandler(listPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ListboxEventProc, listPtr);
    Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING,
	    ListboxFetchSelection, listPtr, XA_STRING);
    if (Tk_InitOptions(interp, listPtr,
	    optionTables->listboxOptionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(listPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --







|




|


<


|









|
>







|
>






|

















|
|





|
|


|
>

|
>











<






|


|


|

|
|










|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    ListboxOptionTables *optionTables;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    optionTables = (ListboxOptionTables *)
	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.
	 */

	optionTables = (ListboxOptionTables *)
		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.
	 */

	optionTables->listboxOptionTable =
		Tk_CreateOptionTable(interp, optionSpecs);
	optionTables->itemAttrOptionTable =
		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).
     */

    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));
    Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS);
    listPtr->itemAttrTable	 = (Tcl_HashTable *)
	    ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
    listPtr->relief		 = TK_RELIEF_RAISED;
    listPtr->textGC		 = NULL;
    listPtr->selFgColorPtr	 = NULL;
    listPtr->selTextGC		 = NULL;
    listPtr->fullLines		 = 1;
    listPtr->xScrollUnit	 = 1;
    listPtr->exportSelection	 = 1;
    listPtr->cursor		 = NULL;
    listPtr->state		 = STATE_NORMAL;
    listPtr->gray		 = None;


    /*
     * Keep a hold of the associated tkwin until we destroy the listbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve((ClientData) listPtr->tkwin);

    Tk_SetClass(listPtr->tkwin, "Listbox");
    Tk_SetClassProcs(listPtr->tkwin, &listboxClass, (ClientData) listPtr);
    Tk_CreateEventHandler(listPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ListboxEventProc, (ClientData) listPtr);
    Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING,
	    ListboxFetchSelection, (ClientData) listPtr, XA_STRING);
    if (Tk_InitOptions(interp, (char *)listPtr,
	    optionTables->listboxOptionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetResult(interp, Tk_PathName(listPtr->tkwin), TCL_STATIC);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
static int
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. */
{
    Listbox *listPtr = (Listbox *)clientData;
    int cmdIndex, index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * 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) {
	return result;
    }

    Tcl_Preserve(listPtr);

    /*
     * The subcommand was valid, so continue processing.
     */

    switch (cmdIndex) {
    case COMMAND_ACTIVATE:







|


<


|





|








|







594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
static int
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
     */

    result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
	    "option", 0, &cmdIndex);
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve((ClientData)listPtr);

    /*
     * The subcommand was valid, so continue processing.
     */

    switch (cmdIndex) {
    case COMMAND_ACTIVATE:
672
673
674
675
676
677
678
679


680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

696


697
698
699
700
701
702
703
704
705
706

707
708
709
710
711

712

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
739
740
741
742
	if (result != TCL_OK) {
	    break;
	}

	result = ListboxBboxSubCmd(interp, listPtr, index);
	break;

    case COMMAND_CGET:


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}

	objPtr = Tk_GetOptionValue(interp, listPtr,
		listPtr->optionTable, objv[2], listPtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;


    case COMMAND_CONFIGURE:


	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, listPtr,
		    listPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    result = TCL_OK;

	} else {
	    result = ConfigureListbox(interp, listPtr, objc-2, objv+2);
	}
	break;


    case COMMAND_CURSELECTION: {

	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.
	 */

	objPtr = Tcl_NewObj();
	for (i = 0; i < listPtr->nElements; i++) {
	    if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {

		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewWideIntObj(i));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;
    }

    case COMMAND_DELETE: {
	int first, last;








|
>
>






|








|
>
|
>
>

|





|
|
|
>




|
>

>
















<

|
>
|


<







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731

732
733
734
735
736
737
738
	if (result != TCL_OK) {
	    break;
	}

	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;
	}

	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;
    }

    case COMMAND_CONFIGURE: {
	Tcl_Obj *objPtr;

	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);
	}
	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 *) INT2PTR(i))) {
		sprintf(indexStringRep, "%d", i);
		Tcl_AppendElement(interp, indexStringRep);
	    }
	}

	result = TCL_OK;
	break;
    }

    case COMMAND_DELETE: {
	int first, last;

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938

939
940
941
942
943
944
945
	if (objc == 3) {
	    /*
	     * One element request - we return a string
	     */

	    Tcl_SetObjResult(interp, elemPtrs[first]);
	} else {
	    Tcl_SetObjResult(interp,
		    Tcl_NewListObj(last-first+1, elemPtrs+first));
	}
	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, TkNewIndexObj(index));
	result = TCL_OK;
	break;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (!(listPtr->state & STATE_NORMAL)) {
	    break;
	}

	result = ListboxInsertSubCmd(listPtr, index, objc-3, objv+3);
	break;

    case COMMAND_ITEMCGET: {

	ItemAttr *attrPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}

	attrPtr = ListboxGetItemAttributes(interp, listPtr, index);

	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;
	break;
    }

    case COMMAND_ITEMCONFIGURE: {

	ItemAttr *attrPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}

	attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, attrPtr,
		    listPtr->itemAttrOptionTable,
		    (objc == 4) ? objv[3] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    result = TCL_OK;

	} else {
	    result = ConfigureListboxItem(interp, listPtr, attrPtr,
		    objc-3, objv+3, index);
	}
	break;
    }








|
|















|





|

















>














<
|
|
<


















>




|










|
|
<
<






|





|
|
|
>







817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879

880
881

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917


918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
	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 = 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;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element element ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (!(listPtr->state & STATE_NORMAL)) {
	    break;
	}

	result = ListboxInsertSubCmd(listPtr, index, objc-3, objv+3);
	break;

    case COMMAND_ITEMCGET: {
	Tcl_Obj *objPtr;
	ItemAttr *attrPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    result = TCL_ERROR;
	    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", NULL);

	    result = TCL_ERROR;
	    break;
	}

	attrPtr = ListboxGetItemAttributes(interp, listPtr, index);

	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;
	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;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_AppendResult(interp, "item number \"", Tcl_GetString(objv[2]),
		    "\" out of range", 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] : 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);
	}
	break;
    }

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
	}

	result = Tcl_GetIntFromObj(interp, objv[2], &y);
	if (result != TCL_OK) {
	    break;
	}
	index = NearestListboxElement(listPtr, y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	result = TCL_OK;
	break;
    }

    case COMMAND_SCAN: {
	int x, y, scanCmdIndex;








|







948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
	}

	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_SCAN: {
	int x, y, scanCmdIndex;

1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
	    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_NewWideIntObj(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(listPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxBboxSubCmd --







|







|



















|









|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
	    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;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxBboxSubCmd --
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145

static int
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 */
{
    Tk_Window tkwin = listPtr->tkwin;
    int lastVisibleIndex;

    /*
     * Determine the index of the last visible item in the listbox.
     */

    lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
	    + listPtr->partialLine;
    if (listPtr->nElements < lastVisibleIndex) {
	lastVisibleIndex = listPtr->nElements;
    }

    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {

	Tcl_Obj *el, *results[4];
	const char *stringRep;
	int pixelWidth, x, y, result;
	TkSizeT stringLen;
	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = TkGetStringFromObj(el, &stringLen);
	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - pixelWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }
	y = ((index - listPtr->topIndex)*listPtr->lineHeight)
		+ listPtr->inset + listPtr->selBorderWidth;
	results[0] = Tcl_NewWideIntObj(x);
	results[1] = Tcl_NewWideIntObj(y);
	results[2] = Tcl_NewWideIntObj(pixelWidth);
	results[3] = Tcl_NewWideIntObj(fm.linespace);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<

















>
|
|
|
<











|



<
<
<
|
<
<
<
<
<


<
<
<
|
|







1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116



1117





1118
1119



1120
1121
1122
1123
1124
1125
1126
1127
1128

static int
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.
     */

    lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
	    + listPtr->partialLine;
    if (listPtr->nElements < lastVisibleIndex) {
	lastVisibleIndex = listPtr->nElements;
    }

    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
	char buf[TCL_INTEGER_SPACE * 4];
	Tcl_Obj *el;
	char *stringRep;
	int pixelWidth, stringLen, x, y, result;

	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = Tcl_GetStringFromObj(el, &stringLen);
	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);




	x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;





	y = ((index - listPtr->topIndex)*listPtr->lineHeight)
		+ listPtr->inset + listPtr->selBorderWidth;



	sprintf(buf, "%d %d %d %d", x, y, pixelWidth, fm.linespace);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
1216
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
	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, KEY(first)) != NULL));

	result = TCL_OK;
	break;
    case SELECTION_SET:
	result = ListboxSelect(listPtr, first, last, 1);
	break;
    }
    return result;







|
|
>







1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
	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;
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275
1276
1277
1278

1279

1280
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
static int
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, windowWidth, windowUnits;
    int offset = 0;		/* Initialized to stop gcc warnings. */
    double fraction;

    windowWidth = Tk_Width(listPtr->tkwin)
	    - 2*(listPtr->inset + listPtr->selBorderWidth);
    if (objc == 2) {
	Tcl_Obj *results[2];

	if (listPtr->maxWidth == 0) {
	    results[0] = Tcl_NewDoubleObj(0.0);
	    results[1] = Tcl_NewDoubleObj(1.0);
	} else {
	    double fraction2;


	    fraction = listPtr->xOffset / (double) listPtr->maxWidth;
	    fraction2 = (listPtr->xOffset + windowWidth)
		    / (double) listPtr->maxWidth;
	    if (fraction2 > 1.0) {
		fraction2 = 1.0;
	    }
	    results[0] = Tcl_NewDoubleObj(fraction);

	    results[1] = Tcl_NewDoubleObj(fraction2);

	}
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
    } else if (objc == 3) {
	if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {

	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;







>
|

|




<
<

|
<

<
>

|

|



|
>
|
>

<






|
>






|







1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248


1249
1250

1251

1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264

1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
static int
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);
    if (objc == 2) {


	if (listPtr->maxWidth == 0) {
	    Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC);

	} else {

	    char buf[TCL_DOUBLE_SPACE];

	    fraction = listPtr->xOffset/((double) listPtr->maxWidth);
	    fraction2 = (listPtr->xOffset + windowWidth)
		    / ((double) listPtr->maxWidth);
	    if (fraction2 > 1.0) {
		fraction2 = 1.0;
	    }
	    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) {
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
    } 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
			+ count*listPtr->xScrollUnit*(windowUnits-2);
	    } else {
		offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    }
	    break;
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345

1346
1347
1348

1349
1350
1351
1352

1353

1354
1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
static int
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;
    double fraction;

    if (objc == 2) {
	Tcl_Obj *results[2];

	if (listPtr->nElements == 0) {
	    results[0] = Tcl_NewDoubleObj(0.0);
	    results[1] = Tcl_NewDoubleObj(1.0);
	} else {
	    double fraction2, numEls = (double) listPtr->nElements;


	    fraction = listPtr->topIndex / numEls;
	    fraction2 = (listPtr->topIndex+listPtr->fullLines) / numEls;

	    if (fraction2 > 1.0) {
		fraction2 = 1.0;
	    }
	    results[0] = Tcl_NewDoubleObj(fraction);

	    results[1] = Tcl_NewDoubleObj(fraction2);

	}
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
    } else if (objc == 3) {
	if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {

	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 {







|
|


<
<

|
<

<
>

|
|
>



|
>
|
>

<






|
>







1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322


1323
1324

1325

1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338

1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
static int
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.0 1.0", TCL_STATIC);

	} else {

	    char buf[TCL_DOUBLE_SPACE];

	    fraction = listPtr->topIndex/((double) listPtr->nElements);
	    fraction2 = (listPtr->topIndex+listPtr->fullLines)
		    /((double) listPtr->nElements);
	    if (fraction2 > 1.0) {
		fraction2 = 1.0;
	    }
	    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) {
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    } else {
	type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);
	switch (type) {
	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 {
1406
1407
1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425

1426
1427
1428
1429
1430
1431
1432
    int index)			/* Index of the item to retrieve attributes
				 * for. */
{
    int isNew;
    Tcl_HashEntry *entry;
    ItemAttr *attrs;

    entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew);

    if (isNew) {
	attrs = (ItemAttr *)ckalloc(sizeof(ItemAttr));
	attrs->border = NULL;
	attrs->selBorder = NULL;
	attrs->fgColor = NULL;
	attrs->selFgColor = NULL;
	Tk_InitOptions(interp, attrs, listPtr->itemAttrOptionTable,
		listPtr->tkwin);
	Tcl_SetHashValue(entry, attrs);
    } else {
	attrs = (ItemAttr *)Tcl_GetHashValue(entry);
    }

    return attrs;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyListbox --







|
>

|




|

|
<
<

>







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412
1413
1414
1415
1416
    int index)			/* Index of the item to retrieve attributes
				 * for. */
{
    int isNew;
    Tcl_HashEntry *entry;
    ItemAttr *attrs;

    entry = Tcl_CreateHashEntry(listPtr->itemAttrTable,
	    (char *) INT2PTR(index), &isNew);
    if (isNew) {
	attrs = (ItemAttr *) ckalloc(sizeof(ItemAttr));
	attrs->border = NULL;
	attrs->selBorder = NULL;
	attrs->fgColor = NULL;
	attrs->selFgColor = NULL;
	Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable,
		listPtr->tkwin);
	Tcl_SetHashValue(entry, (ClientData) attrs);


    }
    attrs = (ItemAttr *)Tcl_GetHashValue(entry);
    return attrs;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyListbox --
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListbox(
    void *memPtr)		/* Info about listbox widget. */
{
    Listbox *listPtr = (Listbox *)memPtr;
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;

    /*
     * If we have an internal list object, free it.
     */

    if (listPtr->listObj != NULL) {
	Tcl_DecrRefCount(listPtr->listObj);
	listPtr->listObj = NULL;
    }

    if (listPtr->listVarName != NULL) {
	Tcl_UntraceVar2(listPtr->interp, listPtr->listVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ListboxListVarProc, listPtr);
    }

    /*
     * Free the selection hash table.
     */

    Tcl_DeleteHashTable(listPtr->selection);
    ckfree(listPtr->selection);

    /*
     * Free the item attribute hash table.
     */

    for (entry = Tcl_FirstHashEntry(listPtr->itemAttrTable, &search);
	    entry != NULL; entry = Tcl_NextHashEntry(&search)) {
	ckfree(Tcl_GetHashValue(entry));
    }
    Tcl_DeleteHashTable(listPtr->itemAttrTable);
    ckfree(listPtr->itemAttrTable);

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    if (listPtr->textGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->textGC);
    }
    if (listPtr->selTextGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->selTextGC);
    }
    if (listPtr->gray != None) {
	Tk_FreeBitmap(Tk_Display(listPtr->tkwin), listPtr->gray);
    }

    Tk_FreeConfigOptions((char *) listPtr, listPtr->optionTable,
	    listPtr->tkwin);
    Tcl_Release(listPtr->tkwin);
    listPtr->tkwin = NULL;
    ckfree(listPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyListboxOptionTables --
 *







|

|













|

|







|







|


|
















|

|

|







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
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 (listPtr->listObj != NULL) {
	Tcl_DecrRefCount(listPtr->listObj);
	listPtr->listObj = NULL;
    }

    if (listPtr->listVarName != NULL) {
	Tcl_UntraceVar(listPtr->interp, listPtr->listVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ListboxListVarProc, (ClientData) listPtr);
    }

    /*
     * Free the selection hash table.
     */

    Tcl_DeleteHashTable(listPtr->selection);
    ckfree((char *)listPtr->selection);

    /*
     * Free the item attribute hash table.
     */

    for (entry = Tcl_FirstHashEntry(listPtr->itemAttrTable, &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.
     */

    if (listPtr->textGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->textGC);
    }
    if (listPtr->selTextGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->selTextGC);
    }
    if (listPtr->gray != None) {
	Tk_FreeBitmap(Tk_Display(listPtr->tkwin), listPtr->gray);
    }

    Tk_FreeConfigOptions((char *)listPtr, listPtr->optionTable,
	    listPtr->tkwin);
    Tcl_Release((ClientData) listPtr->tkwin);
    listPtr->tkwin = NULL;
    ckfree((char *) listPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyListboxOptionTables --
 *
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *dummy)		/* Pointer to the calling interp */
{
    (void)dummy;

    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureListbox --







|

<
<
|







1508
1509
1510
1511
1512
1513
1514
1515
1516


1517
1518
1519
1520
1521
1522
1523
1524
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *interp)		/* Pointer to the calling interp */
{


    ckfree((char *) clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureListbox --
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureListbox(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *oldListObj = NULL;
    Tcl_Obj *errorResult = NULL;
    int oldExport, error;

    oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp));
    if (listPtr->listVarName != NULL) {
	Tcl_UntraceVar2(interp, listPtr->listVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ListboxListVarProc, listPtr);
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, listPtr,
		    listPtr->optionTable, objc, objv,
		    listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|









|

|

|








|







1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *oldListObj = NULL;
    Tcl_Obj *errorResult = NULL;
    int oldExport, error;

    oldExport = listPtr->exportSelection;
    if (listPtr->listVarName != NULL) {
	Tcl_UntraceVar(interp, listPtr->listVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ListboxListVarProc, (ClientData) listPtr);
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) listPtr,
		    listPtr->optionTable, objc, objv,
		    listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
	if (listPtr->highlightWidth < 0) {
	    listPtr->highlightWidth = 0;
	}
	listPtr->inset = listPtr->highlightWidth + listPtr->borderWidth;

	/*
	 * Claim the selection if we've suddenly started exporting it and
	 * there is a selection to export and this interp is unsafe.
	 */

	if (listPtr->exportSelection && (!oldExport)
		&& (!Tcl_IsSafe(listPtr->interp))
		&& (listPtr->numSelected != 0)) {
	    Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
		    ListboxLostSelection, listPtr);
	}

	/*
	 * Verify the current status of the list var.
	 * PREVIOUS STATE | NEW STATE  | ACTION
	 * ---------------+------------+----------------------------------
	 * no listvar     | listvar    | If listvar does not exist, create it







|


|
<

|
|







1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
	if (listPtr->highlightWidth < 0) {
	    listPtr->highlightWidth = 0;
	}
	listPtr->inset = listPtr->highlightWidth + listPtr->borderWidth;

	/*
	 * Claim the selection if we've suddenly started exporting it and
	 * there is a selection to export.
	 */

	if (listPtr->exportSelection && !oldExport

		&& (listPtr->numSelected != 0)) {
	    Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection,
		    (ClientData) listPtr);
	}

	/*
	 * Verify the current status of the list var.
	 * PREVIOUS STATE | NEW STATE  | ACTION
	 * ---------------+------------+----------------------------------
	 * no listvar     | listvar    | If listvar does not exist, create it
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
		    != TCL_OK) {
		Tcl_AppendResult(listPtr->interp,
			": invalid -listvariable value", NULL);
		continue;
	    }

	    listPtr->listObj = listVarObj;
	    Tcl_TraceVar2(listPtr->interp, listPtr->listVarName,
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ListboxListVarProc, listPtr);
	} else if (listPtr->listObj == NULL) {
	    listPtr->listObj = Tcl_NewObj();
	}
	Tcl_IncrRefCount(listPtr->listObj);
	if (oldListObj != NULL) {
	    Tcl_DecrRefCount(oldListObj);
	}







|
|
|







1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
		    != TCL_OK) {
		Tcl_AppendResult(listPtr->interp,
			": invalid -listvariable value", NULL);
		continue;
	    }

	    listPtr->listObj = listVarObj;
	    Tcl_TraceVar(listPtr->interp, listPtr->listVarName,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ListboxListVarProc, (ClientData) listPtr);
	} else if (listPtr->listObj == NULL) {
	    listPtr->listObj = Tcl_NewObj();
	}
	Tcl_IncrRefCount(listPtr->listObj);
	if (oldListObj != NULL) {
	    Tcl_DecrRefCount(oldListObj);
	}
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696

1697
1698
1699
1700
1701
1702
1703

    Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);

    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    }
    ListboxWorldChanged(listPtr);
    return TCL_OK;

}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureListboxItem --
 *







|
|
|
>







1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685

    Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);

    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    } else {
	ListboxWorldChanged((ClientData) listPtr);
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureListboxItem --
 *
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureListboxItem(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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, attrs,
	    listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
	    &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }
    Tk_FreeSavedOptions(&savedOptions);








|








|







1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
 *
 *----------------------------------------------------------------------
 */

static int
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, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }
    Tk_FreeSavedOptions(&savedOptions);

1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    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;







|







1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    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;
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    ClientData clientData)	/* Information about window. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tk_Window tkwin = listPtr->tkwin;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC;
    TkSizeT stringLen;
    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    const char *stringRep;
    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. */
    Pixmap pixmap;
    int textWidth;

    listPtr->flags &= ~REDRAW_PENDING;
    if (listPtr->flags & LISTBOX_DELETED) {
	return;
    }

    if (listPtr->flags & MAXWIDTH_IS_STALE) {
	ListboxComputeGeometry(listPtr, 0, 1, 0);
	listPtr->flags &= ~MAXWIDTH_IS_STALE;
	listPtr->flags |= UPDATE_H_SCROLLBAR;
    }

    Tcl_Preserve(listPtr);
    if (listPtr->flags & UPDATE_V_SCROLLBAR) {
	ListboxUpdateVScrollbar(listPtr);
	if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release(listPtr);
	    return;
	}
    }
    if (listPtr->flags & UPDATE_H_SCROLLBAR) {
	ListboxUpdateHScrollbar(listPtr);
	if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release(listPtr);
	    return;
	}
    }
    listPtr->flags &= ~(REDRAW_PENDING|UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR);
    Tcl_Release(listPtr);

#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







|
|

|
<



|








<












|



|






|




|







1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829

1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841

1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    ClientData clientData)	/* Information about window. */
{
    register Listbox *listPtr = (Listbox *) clientData;
    register Tk_Window tkwin = listPtr->tkwin;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC, stringLen;

    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    char *stringRep;
    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. */
    Pixmap pixmap;


    listPtr->flags &= ~REDRAW_PENDING;
    if (listPtr->flags & LISTBOX_DELETED) {
	return;
    }

    if (listPtr->flags & MAXWIDTH_IS_STALE) {
	ListboxComputeGeometry(listPtr, 0, 1, 0);
	listPtr->flags &= ~MAXWIDTH_IS_STALE;
	listPtr->flags |= UPDATE_H_SCROLLBAR;
    }

    Tcl_Preserve((ClientData) listPtr);
    if (listPtr->flags & UPDATE_V_SCROLLBAR) {
	ListboxUpdateVScrollbar(listPtr);
	if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release((ClientData) listPtr);
	    return;
	}
    }
    if (listPtr->flags & UPDATE_H_SCROLLBAR) {
	ListboxUpdateHScrollbar(listPtr);
	if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
	    Tcl_Release((ClientData) listPtr);
	    return;
	}
    }
    listPtr->flags &= ~(REDRAW_PENDING|UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR);
    Tcl_Release((ClientData) listPtr);

#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
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
	freeGC = 0;

	/*
	 * Lookup this item in the item attributes table, to see if it has
	 * special foreground/background colors.
	 */

	entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(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 (listPtr->state & STATE_NORMAL) {
	    if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
		/*
		 * Selected items are drawn differently.
		 */

		gc = listPtr->selTextGC;
		width = Tk_Width(tkwin) - 2*listPtr->inset;
		selectedBg = listPtr->selBorder;







|








|







1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
	freeGC = 0;

	/*
	 * Lookup this item in the item attributes table, to see if it has
	 * special foreground/background colors.
	 */

	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 (listPtr->state & STATE_NORMAL) {
	    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;
2024
2025
2026
2027
2028
2029
2030
2031

2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg,
			    x-left, y, width+left+right,
			    listPtr->selBorderWidth,
			    1, 1, 1, TK_RELIEF_RAISED);
		}
		/* Draw bottom bevel */
		if (i + 1 == listPtr->nElements ||
			!Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) {

		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left,
			    y + listPtr->lineHeight - listPtr->selBorderWidth,
			    width+left+right, listPtr->selBorderWidth, 0, 0, 0,
			    TK_RELIEF_RAISED);
		}
		prevSelected = 1;
	    } else {
		/*
		 * 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;







|
>









|







2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg,
			    x-left, y, width+left+right,
			    listPtr->selBorderWidth,
			    1, 1, 1, TK_RELIEF_RAISED);
		}
		/* Draw bottom bevel */
		if (i + 1 == listPtr->nElements ||
			Tcl_FindHashEntry(listPtr->selection,
				(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,
			    TK_RELIEF_RAISED);
		}
		prevSelected = 1;
	    } else {
		/*
		 * 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;
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
	    }
	}

	/*
	 * Draw the actual text of this item.
	 */

        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
        stringRep = TkGetStringFromObj(curElement, &stringLen);
        textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	y += fm.ascent + listPtr->selBorderWidth;

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - textWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - textWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }

        Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
		stringRep, stringLen, x, y);

	/*
	 * 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.
		 */

		Tk_UnderlineChars(listPtr->display, pixmap, gc,
			listPtr->tkfont, stringRep, x, y, 0, stringLen);
	    } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
#ifdef _WIN32
		/*
		 * 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.bottom = rect.top + listPtr->lineHeight;
		DrawFocusRect(dc, &rect);
		TkWinReleaseDrawableDC(pixmap, dc, &state);
#else /* !_WIN32 */
		/*
		 * Draw a dotted box around the text.
		 */

		x = listPtr->inset;
		y = ((i - listPtr->topIndex) * listPtr->lineHeight)
			+ listPtr->inset;







<
<
<
<


<
<
|
<
|
<
<
<
<
<
|
|















|
















|







2055
2056
2057
2058
2059
2060
2061




2062
2063


2064

2065





2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
	    }
	}

	/*
	 * Draw the actual text of this item.
	 */





	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	y += fm.ascent + listPtr->selBorderWidth;


	x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;

	Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);





	stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
	Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
		stringRep, stringLen, x, y);

	/*
	 * 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.
		 */

		Tk_UnderlineChars(listPtr->display, pixmap, gc,
			listPtr->tkfont, stringRep, x, y, 0, stringLen);
	    } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
#ifdef WIN32
		/*
		 * 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.bottom = rect.top + listPtr->lineHeight;
		DrawFocusRect(dc, &rect);
		TkWinReleaseDrawableDC(pixmap, dc, &state);
#else /* !WIN32 */
		/*
		 * Draw a dotted box around the text.
		 */

		x = listPtr->inset;
		y = ((i - listPtr->topIndex) * listPtr->lineHeight)
			+ listPtr->inset;
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
		    /*
		     * Don't bother changing if it is about to be freed.
		     */

		    gcValues.line_style = LineSolid;
		    XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
		}
#endif /* _WIN32 */
	    }
	}

	if (freeGC) {
	    Tk_FreeGC(listPtr->display, gc);
	}
    }







|







2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
		    /*
		     * Don't bother changing if it is about to be freed.
		     */

		    gcValues.line_style = LineSolid;
		    XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
		}
#endif /* WIN32 */
	    }
	}

	if (freeGC) {
	    Tk_FreeGC(listPtr->display, gc);
	}
    }
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
				 * 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, i, result;
    TkSizeT textLength;
    Tk_FontMetrics fm;
    Tcl_Obj *element;
    const char *text;

    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.
	     */

	    result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &element);
	    if (result != TCL_OK) {
		continue;
	    }
	    text = TkGetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }

    Tk_GetFontMetrics(listPtr->tkfont, &fm);
    listPtr->lineHeight = fm.linespace + 1 + 2*listPtr->selBorderWidth;
    width = listPtr->width;
    if (width <= 0) {
	width = (listPtr->maxWidth + listPtr->xScrollUnit - 1)
		/ listPtr->xScrollUnit;
	if (width < 1) {
	    width = 1;
	}
    }
    pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset
	    + 2*listPtr->selBorderWidth;
    height = listPtr->height;







|
<


|

















|













|







2206
2207
2208
2209
2210
2211
2212
2213

2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
				 * 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, textLength, i, result;

    Tk_FontMetrics fm;
    Tcl_Obj *element;
    char *text;

    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.
	     */

	    result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &element);
	    if (result != TCL_OK) {
		continue;
	    }
	    text = Tcl_GetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }

    Tk_GetFontMetrics(listPtr->tkfont, &fm);
    listPtr->lineHeight = fm.linespace + 1 + 2*listPtr->selBorderWidth;
    width = listPtr->width;
    if (width <= 0) {
	width = (listPtr->maxWidth + listPtr->xScrollUnit - 1)
		/listPtr->xScrollUnit;
	if (width < 1) {
	    width = 1;
	}
    }
    pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset
	    + 2*listPtr->selBorderWidth;
    height = listPtr->height;
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
 *	callback is registered for the listbox.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxInsertSubCmd(
    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 i, oldMaxWidth, pixelWidth, result;
    TkSizeT length;
    Tcl_Obj *newListObj;
    const char *stringRep;

    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 = TkGetStringFromObj(objv[i], &length);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	if (pixelWidth > listPtr->maxWidth) {
	    listPtr->maxWidth = pixelWidth;
	}
    }

    /*







|





|
<

|








|







2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300

2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
 *	callback is registered for the listbox.
 *
 *----------------------------------------------------------------------
 */

static int
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 i, oldMaxWidth, pixelWidth, result, length;

    Tcl_Obj *newListObj;
    char *stringRep;

    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;
	}
    }

    /*
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
 *	The listbox will be modified and (eventually) redisplayed.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxDeleteSubCmd(
    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, result, pixelWidth;
    TkSizeT length;
    Tcl_Obj *newListObj, *element;
    const char *stringRep;
    Tcl_HashEntry *entry;

    /*
     * Adjust the range to fit within the existing elements of the listbox,
     * and make sure there's something to delete.
     */








|



|
<

|







2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414

2415
2416
2417
2418
2419
2420
2421
2422
2423
 *	The listbox will be modified and (eventually) redisplayed.
 *
 *----------------------------------------------------------------------
 */

static int
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, length, result, pixelWidth;

    Tcl_Obj *newListObj, *element;
    char *stringRep;
    Tcl_HashEntry *entry;

    /*
     * Adjust the range to fit within the existing elements of the listbox,
     * and make sure there's something to delete.
     */

2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510

    widthChanged = 0;
    for (i = first; i <= last; i++) {
	/*
	 * Remove selection information.
	 */

	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    listPtr->numSelected--;
	    Tcl_DeleteHashEntry(entry);
	}

	entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i));
	if (entry != NULL) {
	    ckfree(Tcl_GetHashValue(entry));
	    Tcl_DeleteHashEntry(entry);
	}

	/*
	 * 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 = TkGetStringFromObj(element, &length);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	    if (pixelWidth == listPtr->maxWidth) {
		widthChanged = 1;
	    }
	}
    }








|





|

|






|




|







2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476

    widthChanged = 0;
    for (i = first; i <= last; 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 *) 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
	 * 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);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	    if (pixelWidth == listPtr->maxWidth) {
		widthChanged = 1;
	    }
	}
    }

2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
 */

static void
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),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {







|
















|







2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
 */

static void
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),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
 *----------------------------------------------------------------------
 */

static void
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.
     */







|







2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
 *----------------------------------------------------------------------
 */

static void
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.
     */
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766








2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789



2790
2791
2792
2793
2794



2795
2796
2797
2798








2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815

static int
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 lastOK,		/* 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, index;
    TkSizeT idx;
    const char *stringRep;

    result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx);
    if (result == TCL_OK) {
    	if ((idx != TCL_INDEX_NONE) && (idx > (TkSizeT)listPtr->nElements)) {
    	    idx = listPtr->nElements;
    	}
    	*indexPtr = (int)idx;
    	return TCL_OK;
    }

    /*
     * 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;








	}
	return TCL_OK;
    }

    /*
     * 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;
	const char *start;
	char *end;

	start = stringRep + 1;
	y = strtol(start, &end, 0);
	if ((start == end) || (*end != ',')) {
	    goto badIndex;



	}
	start = end+1;
	y = strtol(start, &end, 0);
	if ((start == end) || (*end != '\0')) {
	    goto badIndex;



	}
	*indexPtr = NearestListboxElement(listPtr, y);
	return TCL_OK;
    }









    /*
     * Everything failed, nothing matched. Throw up an error message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad listbox index \"%s\": must be active, anchor, end, @x,y,"
	    " or a number", Tcl_GetString(indexObj)));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "LISTBOX_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeListboxView --







|





<
|
<
<
<
<
<
<
<
<
<
















>
>
>
>
>
>
>
>










<
<
|
<
<

<
|




|
>
>
>




|
>
>
>




>
>
>
>
>
>
>
>





<
|
|
|
|







2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705

2706









2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740


2741


2742

2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776

2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787

static int
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. */
{
    int result, index;

    char *stringRep;










    /*
     * 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;
	}
	return TCL_OK;
    }

    /*
     * 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;
	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",
		    NULL);
	    return TCL_ERROR;
	}
	start = end+1;
	y = strtol(start, &end, 0);
	if ((start == end) || (*end != '\0')) {
	    Tcl_AppendResult(interp, "bad listbox index \"", stringRep,
		    "\": must be active, anchor, end, @x,y, or a number",
		    NULL);
	    return TCL_ERROR;
	}
	*indexPtr = NearestListboxElement(listPtr, y);
	return TCL_OK;
    }

    /*
     * 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.
     */


    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "bad listbox index \"",
	    Tcl_GetString(indexObj), "\": must be active, anchor, ",
	    "end, @x,y, or a number", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeListboxView --
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
 *	change its display too.
 *
 *----------------------------------------------------------------------
 */

static void
ChangeListboxView(
    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;
    }
    if (index < 0) {







|







2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
 *	change its display too.
 *
 *----------------------------------------------------------------------
 */

static void
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;
    }
    if (index < 0) {
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882


2883
2884
2885
2886
2887
2888
2889
 *	The listbox may be redrawn to reflect its new horizontal offset.
 *
 *----------------------------------------------------------------------
 */

static void
ChangeListboxOffset(
    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.
     *
     * Add half a scroll unit to do entry/text-like synchronization. [Bug
     * #225025]
     */

    offset += listPtr->xScrollUnit / 2;
    maxOffset = GetMaxOffset(listPtr);


    if (offset > maxOffset) {
	offset = maxOffset;
    }
    if (offset < 0) {
	offset = 0;
    }
    offset -= offset % listPtr->xScrollUnit;







|













|
>
>







2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
 *	The listbox may be redrawn to reflect its new horizontal offset.
 *
 *----------------------------------------------------------------------
 */

static void
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.
     *
     * Add half a scroll unit to do entry/text-like synchronization. [Bug
     * #225025]
     */

    offset += listPtr->xScrollUnit / 2;
    maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) -
	    2*listPtr->inset - 2*listPtr->selBorderWidth)
	    + listPtr->xScrollUnit - 1;
    if (offset > maxOffset) {
	offset = maxOffset;
    }
    if (offset < 0) {
	offset = 0;
    }
    offset -= offset % listPtr->xScrollUnit;
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923


2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
 *	The view in the window may change.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxScanTo(
    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 = GetMaxOffset(listPtr);



    /*
     * 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
	    - (10*(y - listPtr->scanMarkY)) / listPtr->lineHeight;
    if (newTopIndex > maxIndex) {
	newTopIndex = listPtr->scanMarkYIndex = maxIndex;
	listPtr->scanMarkY = y;
    } else if (newTopIndex < 0) {
	newTopIndex = listPtr->scanMarkYIndex = 0;
	listPtr->scanMarkY = y;
    }







|






|
>
>












|







2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
 *	The view in the window may change.
 *
 *----------------------------------------------------------------------
 */

static void
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).
     */

    newTopIndex = listPtr->scanMarkYIndex
	    - (10*(y - listPtr->scanMarkY))/listPtr->lineHeight;
    if (newTopIndex > maxIndex) {
	newTopIndex = listPtr->scanMarkYIndex = maxIndex;
	listPtr->scanMarkY = y;
    } else if (newTopIndex < 0) {
	newTopIndex = listPtr->scanMarkYIndex = 0;
	listPtr->scanMarkY = y;
    }
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
NearestListboxElement(
    Listbox *listPtr,	/* Information about widget. */
    int y)			/* Y-coordinate in listPtr's window. */
{
    int index;

    index = (y - listPtr->inset) / listPtr->lineHeight;
    if (index >= (listPtr->fullLines + listPtr->partialLine)) {
	index = listPtr->fullLines + listPtr->partialLine - 1;
    }
    if (index < 0) {
	index = 0;
    }
    index += listPtr->topIndex;







|




|







2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
NearestListboxElement(
    register Listbox *listPtr,	/* Information about widget. */
    int y)			/* Y-coordinate in listPtr's window. */
{
    int index;

    index = (y - listPtr->inset)/listPtr->lineHeight;
    if (index >= (listPtr->fullLines + listPtr->partialLine)) {
	index = listPtr->fullLines + listPtr->partialLine - 1;
    }
    if (index < 0) {
	index = 0;
    }
    index += listPtr->topIndex;
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
 *	non-zero.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxSelect(
    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. */
{







|







2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
 *	non-zero.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
    /*
     * 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, KEY(i));
	if (entry != NULL) {
	    if (!select) {
		Tcl_DeleteHashEntry(entry);
		listPtr->numSelected--;
		if (firstRedisplay < 0) {
		    firstRedisplay = i;
		}
	    }
	} else {
	    if (select) {
		entry = Tcl_CreateHashEntry(listPtr->selection, KEY(i),
			&isNew);
		Tcl_SetHashValue(entry, NULL);
		listPtr->numSelected++;
		if (firstRedisplay < 0) {
		    firstRedisplay = i;
		}
	    }
	}
    }

    if (firstRedisplay >= 0) {
	EventuallyRedrawRange(listPtr, first, last);
    }
    if ((oldCount == 0) && (listPtr->numSelected > 0)
	    && (listPtr->exportSelection)
	    && (!Tcl_IsSafe(listPtr->interp))) {
	Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
		ListboxLostSelection, listPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|










|
|
|












|
<
|
|







3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061

3062
3063
3064
3065
3066
3067
3068
3069
3070
    /*
     * 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 *) INT2PTR(i));
	if (entry != NULL) {
	    if (!select) {
		Tcl_DeleteHashEntry(entry);
		listPtr->numSelected--;
		if (firstRedisplay < 0) {
		    firstRedisplay = i;
		}
	    }
	} else {
	    if (select) {
		entry = Tcl_CreateHashEntry(listPtr->selection,
			(char *) INT2PTR(i), &isNew);
		Tcl_SetHashValue(entry, (ClientData) NULL);
		listPtr->numSelected++;
		if (firstRedisplay < 0) {
		    firstRedisplay = i;
		}
	    }
	}
    }

    if (firstRedisplay >= 0) {
	EventuallyRedrawRange(listPtr, first, last);
    }
    if ((oldCount == 0) && (listPtr->numSelected > 0)
	    && (listPtr->exportSelection)) {

	Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection,
		(ClientData) listPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166

3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ListboxFetchSelection(
    ClientData clientData,	/* Information about listbox widget. */
    TkSizeT offset,			/* Offset within selection of first byte to be
				 * returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_DString selection;
    int count, needNewline, i;
    TkSizeT length, stringLen;
    Tcl_Obj *curElement;
    const char *stringRep;
    Tcl_HashEntry *entry;

    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
	return -1;
    }

    /*
     * Use a dynamic string to accumulate the contents of the selection.
     */

    needNewline = 0;
    Tcl_DStringInit(&selection);
    for (i = 0; i < listPtr->nElements; i++) {
	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = TkGetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {
	return -1;
    }

    /*
     * Copy the requested portion of the selection to the buffer.
     */

    if (length <= offset) {

	count = 0;
    } else {
	count = length - offset;
	if (count > (int)maxBytes) {
	    count = (int)maxBytes;
	}
	memcpy(buffer, Tcl_DStringValue(&selection) + offset, count);
    }
    buffer[count] = '\0';
    Tcl_DStringFree(&selection);
    return count;
}

/*







|


|


|



|

|
<

|


|










|






|














|
>


<
|
|

|







3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102

3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143

3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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, stringLen, i;

    Tcl_Obj *curElement;
    char *stringRep;
    Tcl_HashEntry *entry;

    if (!listPtr->exportSelection) {
	return -1;
    }

    /*
     * Use a dynamic string to accumulate the contents of the selection.
     */

    needNewline = 0;
    Tcl_DStringInit(&selection);
    for (i = 0; i < listPtr->nElements; i++) {
	entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {
	return -1;
    }

    /*
     * Copy the requested portion of the selection to the buffer.
     */

    count = length - offset;
    if (count <= 0) {
	count = 0;
    } else {

	if (count > maxBytes) {
	    count = maxBytes;
	}
	memcpy(buffer, Tcl_DStringValue(&selection) + offset, (size_t) count);
    }
    buffer[count] = '\0';
    Tcl_DStringFree(&selection);
    return count;
}

/*
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
 *----------------------------------------------------------------------
 */

static void
ListboxLostSelection(
    ClientData clientData)	/* Information about listbox widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
	    && (listPtr->nElements > 0)) {
	ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
        GenerateListboxSelectEvent(listPtr);
    }
}

/*
 *----------------------------------------------------------------------







|

|
<







3169
3170
3171
3172
3173
3174
3175
3176
3177
3178

3179
3180
3181
3182
3183
3184
3185
 *----------------------------------------------------------------------
 */

static void
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);
        GenerateListboxSelectEvent(listPtr);
    }
}

/*
 *----------------------------------------------------------------------
3225
3226
3227
3228
3229
3230
3231

3232








3233
3234
3235
3236
3237
3238
3239
 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{

    Tk_SendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);








}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *







>
|
>
>
>
>
>
>
>
>







3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{
    union {XEvent general; XVirtualEvent virtual;} event;

    memset(&event, 0, sizeof(event));
    event.general.xany.type = VirtualEvent;
    event.general.xany.serial = NextRequest(Tk_Display(listPtr->tkwin));
    event.general.xany.send_event = False;
    event.general.xany.window = Tk_WindowId(listPtr->tkwin);
    event.general.xany.display = Tk_Display(listPtr->tkwin);
    event.virtual.name = Tk_GetUid("ListboxSelect");
    Tk_HandleEvent(&event.general);
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
 *	Information gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyRedrawRange(
    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. */
{
    (void)first;
    (void)last;

    /*
     * 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)) {
	return;
    }
    listPtr->flags |= REDRAW_PENDING;
    Tcl_DoWhenIdle(DisplayListbox, listPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxUpdateVScrollbar --
 *







|






<
<
<











|







3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242



3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
 *	Information gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
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.
     */

    if ((listPtr->flags & REDRAW_PENDING)
	    || (listPtr->flags & LISTBOX_DELETED)
	    || !Tk_IsMapped(listPtr->tkwin)) {
	return;
    }
    listPtr->flags |= REDRAW_PENDING;
    Tcl_DoWhenIdle(DisplayListbox, (ClientData) listPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxUpdateVScrollbar --
 *
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321

3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
 *	process errors in the command.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxUpdateVScrollbar(
    Listbox *listPtr)	/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE];
    double first, last;
    int result;
    Tcl_Interp *interp;
    Tcl_DString buf;

    if (listPtr->yScrollCmd == NULL) {
	return;
    }
    if (listPtr->nElements == 0) {
	first = 0.0;
	last = 1.0;
    } else {
	first = listPtr->topIndex / (double) listPtr->nElements;
	last = (listPtr->topIndex + listPtr->fullLines)
		/ (double) listPtr->nElements;
	if (last > 1.0) {
	    last = 1.0;
	}
    }

    Tcl_PrintDouble(NULL, first, firstStr);
    Tcl_PrintDouble(NULL, last, lastStr);

    /*
     * We must hold onto the interpreter from the listPtr because the data at
     * listPtr might be freed as a result of the Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->yScrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (vertical scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);
}

/*
 *----------------------------------------------------------------------
 *







|

|



<















>
|
|



|




<
|
<
<
<
<
<
|



|







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310

3311





3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
 *	process errors in the command.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxUpdateVScrollbar(
    register Listbox *listPtr)	/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1];
    double first, last;
    int result;
    Tcl_Interp *interp;


    if (listPtr->yScrollCmd == NULL) {
	return;
    }
    if (listPtr->nElements == 0) {
	first = 0.0;
	last = 1.0;
    } else {
	first = listPtr->topIndex / (double) listPtr->nElements;
	last = (listPtr->topIndex + listPtr->fullLines)
		/ (double) listPtr->nElements;
	if (last > 1.0) {
	    last = 1.0;
	}
    }
    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.
     */

    interp = listPtr->interp;
    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(interp);
}

/*
 *----------------------------------------------------------------------
 *
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387


3388
3389
3390
3391
3392
3393

3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
 *	process errors in the command.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxUpdateHScrollbar(
    Listbox *listPtr)	/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE];
    int result, windowWidth;
    double first, last;
    Tcl_Interp *interp;
    Tcl_DString buf;

    if (listPtr->xScrollCmd == NULL) {
	return;
    }

    windowWidth = Tk_Width(listPtr->tkwin)
	    - 2*(listPtr->inset + listPtr->selBorderWidth);
    if (listPtr->maxWidth == 0) {
	first = 0;
	last = 1.0;
    } else {


	first = listPtr->xOffset / (double) listPtr->maxWidth;
	last = (listPtr->xOffset + windowWidth) / (double) listPtr->maxWidth;
	if (last > 1.0) {
	    last = 1.0;
	}
    }

    Tcl_PrintDouble(NULL, first, firstStr);
    Tcl_PrintDouble(NULL, last, lastStr);

    /*
     * We must hold onto the interpreter because the data referred to at
     * listPtr might be freed as a result of the call to Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->xScrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (horizontal scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);
}

/*
 *----------------------------------------------------------------------
 *







|

|



<




<
|
|




>
>
|
|




>
|
|



|




<
|
<
<
<
<
<
|



|







3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348

3349
3350
3351
3352

3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377

3378





3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
 *	process errors in the command.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxUpdateHScrollbar(
    register Listbox *listPtr)	/* Information about widget. */
{
    char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1];
    int result, windowWidth;
    double first, last;
    Tcl_Interp *interp;


    if (listPtr->xScrollCmd == NULL) {
	return;
    }

    windowWidth = Tk_Width(listPtr->tkwin) - 2*(listPtr->inset
	    + listPtr->selBorderWidth);
    if (listPtr->maxWidth == 0) {
	first = 0;
	last = 1.0;
    } else {
	register double maxWide = (double) listPtr->maxWidth;

	first = listPtr->xOffset / maxWide;
	last = (listPtr->xOffset + windowWidth) / maxWide;
	if (last > 1.0) {
	    last = 1.0;
	}
    }
    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(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(interp);
}

/*
 *----------------------------------------------------------------------
 *
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_Obj *oldListObj, *varListObj;
    int oldLength, i;
    Tcl_HashEntry *entry;
    (void)name1;
    (void)name2;

    /*
     * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
     */

    if (flags & TCL_TRACE_UNSETS) {

        if (!Tcl_InterpDeleted(interp) && listPtr->listVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        listPtr->listVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ListboxListVarProc, probe);
                if (probe == (ClientData)listPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * listVarName, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
                return NULL;
            }
	    Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
		    listPtr->listObj, TCL_GLOBAL_ONLY);
	    Tcl_TraceVar2(interp, listPtr->listVarName,
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ListboxListVarProc, clientData);
	    return NULL;
	}
    } else {
	oldListObj = listPtr->listObj;
	varListObj = Tcl_GetVar2Ex(listPtr->interp, listPtr->listVarName,
		NULL, TCL_GLOBAL_ONLY);







<
<






|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|







3409
3410
3411
3412
3413
3414
3415


3416
3417
3418
3419
3420
3421
3422





















3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_Obj *oldListObj, *varListObj;
    int oldLength, i;
    Tcl_HashEntry *entry;



    /*
     * 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, NULL,
		    listPtr->listObj, TCL_GLOBAL_ONLY);
	    Tcl_TraceVar(interp, listPtr->listVarName,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ListboxListVarProc, clientData);
	    return NULL;
	}
    } else {
	oldListObj = listPtr->listObj;
	varListObj = Tcl_GetVar2Ex(listPtr->interp, listPtr->listVarName,
		NULL, TCL_GLOBAL_ONLY);
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540

3541
3542
3543
3544
3545
3546
3547
3548
3549
	 */

	Tcl_DecrRefCount(oldListObj);
    }

    /*
     * 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, KEY(i));
	    if (entry != NULL) {
		listPtr->numSelected--;
		Tcl_DeleteHashEntry(entry);
	    }

	    /*
	     * Clean up attributes.
	     */

	    entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i));

	    if (entry != NULL) {
		ckfree(Tcl_GetHashValue(entry));
		Tcl_DeleteHashEntry(entry);
	    }
	}
    }

    if (oldLength != listPtr->nElements) {
	listPtr->flags |= UPDATE_V_SCROLLBAR;







|










|









|
>

|







3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
	 */

	Tcl_DecrRefCount(oldListObj);
    }

    /*
     * 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 *) INT2PTR(i));
	    if (entry != NULL) {
		listPtr->numSelected--;
		Tcl_DeleteHashEntry(entry);
	    }

	    /*
	     * Clean up attributes.
	     */

	    entry = Tcl_FindHashEntry(listPtr->itemAttrTable,
		    (char *) INT2PTR(i));
	    if (entry != NULL) {
		ckfree((char *) Tcl_GetHashValue(entry));
		Tcl_DeleteHashEntry(entry);
	    }
	}
    }

    if (oldLength != listPtr->nElements) {
	listPtr->flags |= UPDATE_V_SCROLLBAR;
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618

3619
3620
3621
3622
3623
3624
3625
3626
3627
3628

3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
     * 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.
     */

    if (offset > 0) {
	for (i = last; i >= first; i--) {
	    entry = Tcl_FindHashEntry(table, KEY(i));
	    if (entry != NULL) {
		clientData = Tcl_GetHashValue(entry);
		Tcl_DeleteHashEntry(entry);
		entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew);

		Tcl_SetHashValue(entry, clientData);
	    }
	}
    } else {
	for (i = first; i <= last; i++) {
	    entry = Tcl_FindHashEntry(table, KEY(i));
	    if (entry != NULL) {
		clientData = Tcl_GetHashValue(entry);
		Tcl_DeleteHashEntry(entry);
		entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew);

		Tcl_SetHashValue(entry, clientData);
	    }
	}
    }
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * GetMaxOffset --
 *
 *	Passing in a listbox pointer, returns the maximum offset for the box,
 *	i.e. the maximum possible horizontal scrolling value (in pixels).
 *
 * Results:
 *	Listbox's maxOffset.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
*/
static int GetMaxOffset(
    Listbox *listPtr)
{
    int maxOffset;

    maxOffset = listPtr->maxWidth -
            (Tk_Width(listPtr->tkwin) - 2*listPtr->inset -
            2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1;
    if (maxOffset < 0) {

        /*
         * Listbox is larger in width than its largest width item.
         */

        maxOffset = 0;
    }
    maxOffset -= maxOffset % listPtr->xScrollUnit;

    return maxOffset;
}
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



|
>





|



|
>







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583




































3584
3585
3586
3587
3588
3589
3590
     * 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.
     */

    if (offset > 0) {
	for (i = last; i >= first; i--) {
	    entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i));
	    if (entry != NULL) {
		clientData = Tcl_GetHashValue(entry);
		Tcl_DeleteHashEntry(entry);
		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 *) INT2PTR(i));
	    if (entry != NULL) {
		clientData = Tcl_GetHashValue(entry);
		Tcl_DeleteHashEntry(entry);
		entry = Tcl_CreateHashEntry(table,
			(char *) INT2PTR(i + offset), &isNew);
		Tcl_SetHashValue(entry, clientData);
	    }
	}
    }
    return;
}





































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkMacWinMenu.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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 {
    int postCommandGeneration;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static int		PreprocessMenu(TkMenu *menuPtr);

/*







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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 {
    int postCommandGeneration;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static int		PreprocessMenu(TkMenu *menuPtr);

/*
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
PreprocessMenu(
    TkMenu *menuPtr)
{
    int index, result, finished;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    Tcl_Preserve(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;
    }

    /*
     * 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 < (int)menuPtr->numEntries; index++) {
	    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;








|



















|
|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
PreprocessMenu(
    TkMenu *menuPtr)
{
    int index, result, finished;
    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;
    }

    /*
     * 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++) {
	    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;

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
		    break;
		}
	    }
	}
    } while (!finished);

  done:
    Tcl_Release(menuPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPreprocessMenu --







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
		    break;
		}
	    }
	}
    } while (!finished);

  done:
    Tcl_Release((ClientData) menuPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPreprocessMenu --

Changes to generic/tkMain.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108



109
110
111
112
113

114



115




116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
 * 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.
 */

#include "tkInt.h"

extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";

/*
 * This file can be compiled on Windows in UNICODE mode, as well as
 * on all other platforms using the native encoding. This is done
 * by using the normal Windows functions like _tcscmp, but on
 * platforms which don't have <tchar.h> we have to translate that
 * to strcmp here.
 */
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just
    enough to make it work. See [600b72bfbc] */
typedef struct TclIntPlatStubs {
    int magic;
    void *hooks;
    void (*dummy[16]) (void); /* dummy entries 0-15, not used */
    int (*tclpIsAtty) (int fd); /* 16 */
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus
}
#endif
#   include "tkWinInt.h"
#else
#   define TCHAR char
#   define TEXT(arg) arg
#   define _tcscmp strcmp
#   define _tcslen strlen
#   define _tcsncmp strncmp
#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif

static inline Tcl_Obj *
NewNativeObj(
    TCHAR *string)
{

    Tcl_Obj *obj;
    Tcl_DString ds;

#ifdef UNICODE
    Tcl_DStringInit(&ds);


    Tcl_WCharToUtfDString(string, wcslen(string), &ds);
#else
    Tcl_ExternalToUtfDString(NULL, (char *) string, -1, &ds);
#endif
    obj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    return obj;
}

/*
 * 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)
#define isatty WinIsTty
static int WinIsTty(int fd) {
    HANDLE handle;

    /*
     * For now, under Windows, we assume we are not running as a console mode
     * app, so we need to use the GUI console. In order to enable this, we
     * always claim to be running on a tty. This probably isn't the right way
     * to do it.
     */

#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) {
	    /* We are running on Cygwin */
	    return tclIntPlatStubsPtr->tclpIsAtty(fd);
	}
#endif
    handle = GetStdHandle(STD_INPUT_HANDLE + fd);



	/*
	 * If it's a bad or closed handle, then it's been connected to a wish
	 * console window. A character file handle is a tty by definition.
	 */
    return (handle == INVALID_HANDLE_VALUE) || (handle == 0)

	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)



	     || (GetFileType(handle) == FILE_TYPE_CHAR);




}
#else
extern int		isatty(int fd);

#endif

typedef struct InteractiveState {
    Tcl_Channel input;		/* The standard input channel from which lines
				 * are read. */
    int tty;			/* Non-zero means standard input is a
				 * terminal-like device. Zero means it's a
				 * file. */
    Tcl_DString command;	/* Used to assemble lines of terminal input
				 * into Tcl commands. */
    Tcl_DString line;		/* Used to read the next line from the
				 * terminal input. */
    int gotPartial;
    Tcl_Interp *interp;		/* Interpreter that evaluates interactive
				 * commands. */
} InteractiveState;

/*
 * Forward declarations for functions defined later in this file.
 */

static void		Prompt(Tcl_Interp *interp, InteractiveState *isPtr);
static void		StdinProc(ClientData clientData, int mask);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MainEx --
 *







|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<



|






<
<
<

<
<
<
<
<
<

<




|
<
<
|
>
|
|
|
<
|
>
>
|
|
<
|
<
|
<
<









|






|
|
|









>
>
>

|
|

|
>
|
>
>
>
|
>
>
>
>



>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|







11
12
13
14
15
16
17
18

19













20



21
22
23
24
25
26
27
28
29
30



31






32

33
34
35
36
37


38
39
40
41
42

43
44
45
46
47

48

49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101















102
103
104
105
106
107
108
109
110
111
112
113
 * 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.
 */

#include "tkInt.h"
#if TCL_MINOR_VERSION < 6

#include "tclInt.h"













#elif defined(_WIN32)



/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just
    enough to make it work. See [600b72bfbc] */
typedef struct {
    int magic;
    void *hooks;
    void (*dummy[16]) (void); /* dummy entries 0-15, not used */
    int (*tclpIsAtty) (int fd); /* 16 */
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;



#   include "tkWinInt.h"






#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif

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
				 * into Tcl commands. */

    Tcl_DString line;		/* Used to read the next line from the
				 * terminal input. */
    int tty;			/* Non-zero means standard input is a
				 * terminal-like device. Zero means it's a
				 * file. */

} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;



/*
 * 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)
#define isatty WinIsTty
static int WinIsTty(int fd) {
    HANDLE handle;

    /*
     * For now, under Windows, we assume we are not running as a console mode
     * app, so we need to use the GUI console.  In order to enable this, we
     * always claim to be running on a tty.  This probably isn't the right
     * way to do it.
     */

#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) {
	    /* We are running on Cygwin */
	    return tclIntPlatStubsPtr->tclpIsAtty(fd);
	}
#endif
    handle = GetStdHandle(STD_INPUT_HANDLE + fd);

    if ((handle == INVALID_HANDLE_VALUE) || (handle == 0)
	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)) {
	/*
	 * If it's a bad or closed handle, then it's been connected
	 * to a wish console window.
	 */

	return 1;
    } else if (GetFileType(handle) == FILE_TYPE_CHAR) {
	/*
	 * A character file handle is a tty by definition.
	 */

	return 1;
    } else {
	return 0;
    }
}
#else
extern int		isatty(int fd);
extern char *		strrchr(CONST char *string, int c);
#endif
















/*
 * Forward declarations for functions defined later in this file.
 */

static void		Prompt(Tcl_Interp *interp, int partial);
static void		StdinProc(ClientData clientData, int mask);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MainEx --
 *
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216



217
218
219
220
221
222
223
224



225
226
227
228
229
230
231
232
233




234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276


277



278
279

280
281
282
283
284
285
286



287


288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
 *
 *----------------------------------------------------------------------
 */

void
Tk_MainEx(
    int argc,			/* Number of arguments. */
    TCHAR **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 *path, *argvPtr, *appName;
    const char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel chan;

    InteractiveState is;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
	    abort();
	} else {
	    Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
	}
    }

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)

    if (tclStubsPtr->reserved9) {
	/* We are running win32 Tk under Cygwin, so let's check
	 * whether the env("DISPLAY") variable or the -display
	 * argument is set. If so, we really want to run the
	 * Tk_MainEx function of libtk8.?.dll, not this one. */
	if (Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY)) {
	loadCygwinTk:
	    if (TkCygwinMainEx(argc, argv, appInitProc, interp)) {
		/* Should never reach here. */
		return;
	    }
	} else {
	    int i;

	    for (i = 1; i < argc; ++i) {
		if (!_tcscmp(argv[i], TEXT("-display"))) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif


    Tcl_InitMemory(interp);




    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32)
#if !defined(STATIC_BUILD)
    /* If compiled for Win32 but running on Cygwin, don't use console */
    if (!tclStubsPtr->reserved9)



#endif
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }
#endif





    /*
     * 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 (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 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& (TEXT('-') != argv[3][0])) {
	    Tcl_Obj *value = NewNativeObj(argv[2]);
	    Tcl_SetStartupScript(NewNativeObj(argv[3]), Tcl_GetString(value));
	    Tcl_DecrRefCount(value);
	    argc -= 3;
	    argv += 3;
	} else if ((argc > 1) && (TEXT('-') != argv[1][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL);
	    argc--;
	    argv++;
	} else if ((argc > 2) && (length = _tcslen(argv[1]))
		&& (length > 1) && (0 == _tcsncmp(TEXT("-file"), argv[1], length))
		&& (TEXT('-') != argv[2][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[2]), NULL);
	    argc -= 2;
	    argv += 2;
	}
    }

    path = Tcl_GetStartupScript(&encodingName);
    if (path == NULL) {
	appName = NewNativeObj(argv[0]);
    } else {


	appName = path;



    }
    Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);

    argc--;
    argv++;

    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj(argc), TCL_GLOBAL_ONLY);

    argvPtr = Tcl_NewListObj(0, NULL);
    while (argc--) {



	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++));


    }
    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */

    is.tty = isatty(0);

#if defined(MAC_OSX_TK)
    /*
     * On TkAqua, if we don't have a TTY and stdin is a special character file
     * of length 0, (e.g. /dev/null, which is what Finder sets when double
     * clicking Wish) then use the GUI console.
     */

    if (!is.tty) {
	struct stat st;

	nullStdin = fstat(0, &st) || (S_ISCHR(st.st_mode) && !st.st_blocks);
    }
#endif
    Tcl_SetVar2Ex(interp, "tcl_interactive", NULL,

	    Tcl_NewWideIntObj(!path && (is.tty || nullStdin)), TCL_GLOBAL_ONLY);

    /*
     * Invoke application-specific initialization.
     */

    if (appInitProc(interp) != TCL_OK) {
	TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)),
		"application-specific initialization failed");
    }

    /*
     * Invoke the script specified on the command line, if any. Must fetch it
     * again, as the appInitProc might have reset it.
     */

    path = Tcl_GetStartupScript(&encodingName);
    if (path != NULL) {
	Tcl_ResetResult(interp);
	code = Tcl_FSEvalFileEx(interp, path, encodingName);
	if (code != TCL_OK) {
	    /*
	     * The following statement guarantees that the errorInfo variable
	     * is set properly.
	     */

	    Tcl_AddErrorInfo(interp, "");
	    TkpDisplayWarning(Tcl_GetVar2(interp, "errorInfo", NULL,
		    TCL_GLOBAL_ONLY), "Error in startup script");
	    Tcl_DeleteInterp(interp);
	    Tcl_Exit(1);
	}
	is.tty = 0;
    } else {

	/*
	 * Evaluate the .rc file, if one has been specified.
	 */

	Tcl_SourceRCFile(interp);

	/*
	 * Establish a channel handler for stdin.
	 */

	is.input = Tcl_GetStdChannel(TCL_STDIN);
	if (is.input) {
	    Tcl_CreateChannelHandler(is.input, TCL_READABLE, StdinProc, &is);

	}
	if (is.tty) {
	    Prompt(interp, &is);
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan) {
	Tcl_Flush(chan);
    }
    Tcl_DStringInit(&is.command);
    Tcl_DStringInit(&is.line);
    Tcl_ResetResult(interp);

    /*
     * 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(interp);
    Tcl_SetStartupScript(NULL, NULL);
    Tcl_Exit(0);
}

/*
 *----------------------------------------------------------------------
 *







|






|
|

|
>
|





|



|



|
















|







>
|

>
>
>
|
<
|

<
|
<
|
>
>
>
|








>
>
>
>












|

|

|


|
|
<
|
<


|
|


|
|
|
|






|
|

>
>
|
>
>
>

|
>



|



>
>
>
|
>
>







|
>






|
|





|
>
|





|
|
|


















|




|












|
|
|
>

|
|



|
|
|

|
|









|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190

191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
 *
 *----------------------------------------------------------------------
 */

void
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 *path, *argvPtr;
    CONST char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel inChannel, outChannel;
    ThreadSpecificData *tsdPtr;
    Tcl_DString appName;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) {
	if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
	    abort();
	} else {
	    Tcl_Panic("%s", Tcl_GetStringResult(interp));
	}
    }

#if defined(__WIN32__) && !defined(STATIC_BUILD)

    if (tclStubsPtr->reserved9) {
	/* We are running win32 Tk under Cygwin, so let's check
	 * whether the env("DISPLAY") variable or the -display
	 * argument is set. If so, we really want to run the
	 * Tk_MainEx function of libtk8.?.dll, not this one. */
	if (Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY)) {
	loadCygwinTk:
	    if (TkCygwinMainEx(argc, argv, appInitProc, interp)) {
		/* Should never reach here. */
		return;
	    }
	} else {
	    int i;

	    for (i = 1; i < argc; ++i) {
		if (!strcmp(argv[i], "-display")) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif

    tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

#if TCL_MINOR_VERSION < 6
    Tcl_FindExecutable(argv[0]);
#endif
    tsdPtr->interp = interp;

    Tcl_Preserve((ClientData) interp);


#if defined(__WIN32__) && !defined(STATIC_BUILD)

    if (!tclStubsPtr->reserved9) {
	/* Only initialize console when not running under cygwin */
	Tk_InitConsoleChannels(interp);
    }
#elif  defined(__WIN32__)
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }
#endif

#ifdef TCL_MEM_DEBUG
    Tcl_InitMemory(interp);
#endif

    /*
     * 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 (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;
	}
    }

    path = Tcl_GetStartupScript(&encodingName);
    if (NULL == path) {
	Tcl_ExternalToUtfDString(NULL, argv[0], -1, &appName);
    } else {
	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);
    argc--;
    argv++;

    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);

    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)));
	Tcl_DStringFree(&ds);
    }
    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */

    tsdPtr->tty = isatty(0);

#if defined(MAC_OSX_TK)
    /*
     * On TkAqua, if we don't have a TTY and stdin is a special character file
     * 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;

	nullStdin = fstat(0, &st) || (S_ISCHR(st.st_mode) && !st.st_blocks);
    }
#endif
    Tcl_SetVar(interp, "tcl_interactive",
	    ((path == NULL) && (tsdPtr->tty || nullStdin)) ? "1" : "0",
	    TCL_GLOBAL_ONLY);

    /*
     * Invoke application-specific initialization.
     */

    if ((*appInitProc)(interp) != TCL_OK) {
	TkpDisplayWarning(Tcl_GetStringResult(interp),
		"Application initialization failed");
    }

    /*
     * Invoke the script specified on the command line, if any. Must fetch it
     * again, as the appInitProc might have reset it.
     */

    path = Tcl_GetStartupScript(&encodingName);
    if (path != NULL) {
	Tcl_ResetResult(interp);
	code = Tcl_FSEvalFileEx(interp, path, encodingName);
	if (code != TCL_OK) {
	    /*
	     * The following statement guarantees that the errorInfo variable
	     * is set properly.
	     */

	    Tcl_AddErrorInfo(interp, "");
	    TkpDisplayWarning(Tcl_GetVar(interp, "errorInfo",
		    TCL_GLOBAL_ONLY), "Error in startup script");
	    Tcl_DeleteInterp(interp);
	    Tcl_Exit(1);
	}
	tsdPtr->tty = 0;
    } else {

	/*
	 * Evaluate the .rc file, if one has been specified.
	 */

	Tcl_SourceRCFile(interp);

	/*
	 * Establish a channel handler for stdin.
	 */

	inChannel = Tcl_GetStdChannel(TCL_STDIN);
	if (inChannel) {
	    Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc,
		    (ClientData) inChannel);
	}
	if (tsdPtr->tty) {
	    Prompt(interp, 0);
	}
    }

    outChannel = Tcl_GetStdChannel(TCL_STDOUT);
    if (outChannel) {
	Tcl_Flush(outChannel);
    }
    Tcl_DStringInit(&tsdPtr->command);
    Tcl_DStringInit(&tsdPtr->line);
    Tcl_ResetResult(interp);

    /*
     * 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);
}

/*
 *----------------------------------------------------------------------
 *
396
397
398
399
400
401
402

403
404
405
406
407

408
409
410
411
412


413
414
415
416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
 *
 * Side effects:
 *	Could be almost arbitrary, depending on the command that's typed.
 *
 *----------------------------------------------------------------------
 */


static void
StdinProc(
    ClientData clientData,	/* The state of interactive cmd line */
    TCL_UNUSED(int))
{

    char *cmd;
    int code;
    TkSizeT count;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;


    Tcl_Interp *interp = isPtr->interp;

    count = Tcl_Gets(chan, &isPtr->line);

    if ((count == TCL_IO_FAILURE) && !isPtr->gotPartial) {
	if (isPtr->tty) {
	    Tcl_Exit(0);
	} else {
	    Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
	}
	return;
    }

    Tcl_DStringAppend(&isPtr->command, Tcl_DStringValue(&isPtr->line), -1);

    cmd = Tcl_DStringAppend(&isPtr->command, "\n", -1);
    Tcl_DStringFree(&isPtr->line);
    if (!Tcl_CommandComplete(cmd)) {
	isPtr->gotPartial = 1;
	goto prompt;
    }
    isPtr->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.
     */

    Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr);
    code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL);

    isPtr->input = Tcl_GetStdChannel(TCL_STDIN);
    if (isPtr->input) {
	Tcl_CreateChannelHandler(isPtr->input, TCL_READABLE, StdinProc, isPtr);

    }
    Tcl_DStringFree(&isPtr->command);
    if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {
	if ((code != TCL_OK) || (isPtr->tty)) {
	    chan = Tcl_GetStdChannel((code != TCL_OK) ? TCL_STDERR : TCL_STDOUT);
	    if (chan) {
		Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
		Tcl_WriteChars(chan, "\n", 1);
	    }
	}
    }

    /*
     * If a tty stdin is still around, output a prompt.
     */

  prompt:
    if (isPtr->tty && (isPtr->input != NULL)) {
	Prompt(interp, isPtr);
    }
    Tcl_ResetResult(interp);
}

/*
 *----------------------------------------------------------------------
 *







>


|
|

>

|
<
<
|
>
>
|

|

|
|


|




|
>
|
|

|


|








|


|
|
|
>

|
|
|
|








|



|
|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
 *
 * Side effects:
 *	Could be almost arbitrary, depending on the command that's typed.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
static void
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_Interp *interp = tsdPtr->interp;

    count = Tcl_Gets(chan, &tsdPtr->line);

    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);
    cmd = Tcl_DStringAppend(&tsdPtr->command, "\n", -1);
    Tcl_DStringFree(&tsdPtr->line);
    if (!Tcl_CommandComplete(cmd)) {
	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.
     */

    Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
    code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL);

    chan = Tcl_GetStdChannel(TCL_STDIN);
    if (chan) {
	Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc,
		(ClientData) chan);
    }
    Tcl_DStringFree(&tsdPtr->command);
    if (Tcl_GetStringResult(interp)[0] != '\0') {
	if ((code != TCL_OK) || (tsdPtr->tty)) {
	    chan = Tcl_GetStdChannel(TCL_STDOUT);
	    if (chan) {
		Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
		Tcl_WriteChars(chan, "\n", 1);
	    }
	}
    }

    /*
     * Output a prompt.
     */

  prompt:
    if (tsdPtr->tty) {
	Prompt(interp, gotPartial);
    }
    Tcl_ResetResult(interp);
}

/*
 *----------------------------------------------------------------------
 *
484
485
486
487
488
489
490


491
492
493
494
495
496
497
498
499
500
501





502

503
504
505
506
507
508
509
510
511
512
513





514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
 *
 *----------------------------------------------------------------------
 */

static void
Prompt(
    Tcl_Interp *interp,		/* Interpreter to use for prompting. */


    InteractiveState *isPtr) /* InteractiveState. */
{
    Tcl_Obj *promptCmdPtr;
    int code;
    Tcl_Channel chan;

    promptCmdPtr = Tcl_GetVar2Ex(interp,
	isPtr->gotPartial ? "tcl_prompt2" : "tcl_prompt1", NULL, TCL_GLOBAL_ONLY);
    if (promptCmdPtr == NULL) {
    defaultPrompt:
	if (!isPtr->gotPartial) {





	    chan = Tcl_GetStdChannel(TCL_STDOUT);

	    if (chan != NULL) {
		Tcl_WriteChars(chan, DEFAULT_PRIMARY_PROMPT,
			sizeof(DEFAULT_PRIMARY_PROMPT) - 1);
	    }
	}
    } else {
	code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (script that generates prompt)");
	    if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {





		chan = Tcl_GetStdChannel(TCL_STDERR);

		if (chan != NULL) {
		    Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
		    Tcl_WriteChars(chan, "\n", 1);
		}
	    }
	    goto defaultPrompt;
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan != NULL) {
	Tcl_Flush(chan);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
|

|

|

|
|
|

|
>
>
>
>
>
|
>
|
|
<



|



|
>
>
>
>
>
|
>
|
|
|
<




|
<
|
|










475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
 *
 *----------------------------------------------------------------------
 */

static void
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;
    Tcl_Channel outChannel, errChannel;

    promptCmd = Tcl_GetVar2Ex(interp,
	partial ? "tcl_prompt2" : "tcl_prompt1", NULL, TCL_GLOBAL_ONLY);
    if (promptCmd == NULL) {
    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".
	     */

	    outChannel = Tcl_GetChannel(interp, "stdout", NULL);
	    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".
	     */

	    errChannel = Tcl_GetChannel(interp, "stderr", NULL);
	    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);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkMenu.c.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 * 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. They reflect the attributes of the
 * original, or "main", 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 main menu is destroyed, all clones are also destroyed. This
 * 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







|
|




|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 * 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
 * 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.
 *
 * 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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#endif

#include "tkInt.h"
#include "tkMenu.h"

#define MENU_HASH_KEY "tkMenus"

typedef struct {
    int menusInitialized;	/* Flag indicates whether thread-specific
				 * elements of the Windows Menu module have
				 * been initialized. */
    Tk_OptionTable menuOptionTable;
				/* The option table for menus. */
    Tk_OptionTable entryOptionTables[6];
				/* The tables for menu entries. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following flag indicates whether the process-wide state for the Menu
 * module has been initialized. The Mutex protects access to that flag.
 */

static int menusInitialized;
TCL_DECLARE_MUTEX(menuMutex)

/*
 * Configuration specs for individual menu entries. If this changes, be sure
 * to update code in TkpMenuInit that changes the font string entry.
 */

static const char *const menuStateStrings[] = {"active", "normal", "disabled", NULL};

static const char *const 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
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_BG, offsetof(TkMenuEntry, activeBorderPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	offsetof(TkMenuEntry, activeFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-accelerator", NULL, NULL,
	DEF_MENU_ENTRY_ACCELERATOR,
	offsetof(TkMenuEntry, accelPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BITMAP, "-bitmap", NULL, NULL,
	DEF_MENU_ENTRY_BITMAP,
	offsetof(TkMenuEntry, bitmapPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL,
	DEF_MENU_ENTRY_COLUMN_BREAK,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, columnBreak), 0, NULL, 0},
    {TK_OPTION_STRING, "-command", NULL, NULL,
	DEF_MENU_ENTRY_COMMAND,
	offsetof(TkMenuEntry, commandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_MENU_ENTRY_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuEntry, compound), 0,
	(ClientData) compoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	offsetof(TkMenuEntry, fontPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	offsetof(TkMenuEntry, fgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, hideMargin), 0, NULL, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	offsetof(TkMenuEntry, imagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	offsetof(TkMenuEntry, labelPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_INT, "-underline", NULL, NULL,
	DEF_MENU_ENTRY_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuEntry, underline), 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_STRING, "-offvalue", NULL, NULL,
	DEF_MENU_ENTRY_OFF_VALUE,
	offsetof(TkMenuEntry, offValuePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-onvalue", NULL, NULL,
	DEF_MENU_ENTRY_ON_VALUE,
	offsetof(TkMenuEntry, onValuePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	offsetof(TkMenuEntry, indicatorFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	offsetof(TkMenuEntry, selectImagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_CHECK_VARIABLE,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	offsetof(TkMenuEntry, indicatorFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	offsetof(TkMenuEntry, selectImagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-value", NULL, NULL,
	DEF_MENU_ENTRY_VALUE,
	offsetof(TkMenuEntry, onValuePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_RADIO_VARIABLE,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkCascadeEntryConfigSpecs[] = {
    {TK_OPTION_STRING, "-menu", NULL, NULL,
	DEF_MENU_ENTRY_MENU,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE, TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec *specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *const menuTypeStrings[] = {
    "normal", "tearoff", "menubar", NULL
};

static const Tk_OptionSpec tkMenuConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground",
	"Foreground", DEF_MENU_ACTIVE_BG_COLOR,
	offsetof(TkMenu, activeBorderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth",
	"BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
	offsetof(TkMenu, activeBorderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	offsetof(TkMenu, activeFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_FG_MONO, 0},
    {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_MENU_ACTIVE_RELIEF, offsetof(TkMenu, activeReliefPtr),
	TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENU_BG_COLOR, offsetof(TkMenu, borderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	offsetof(TkMenu, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	offsetof(TkMenu, cursorPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	offsetof(TkMenu, disabledFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) DEF_MENU_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, offsetof(TkMenu, fontPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, offsetof(TkMenu, fgPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-postcommand", "postCommand", "Command",
	DEF_MENU_POST_COMMAND,
	offsetof(TkMenu, postCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, offsetof(TkMenu, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, offsetof(TkMenu, indicatorFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	offsetof(TkMenu, takeFocusPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, TCL_INDEX_NONE, offsetof(TkMenu, tearoff), 0, NULL, 0},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	offsetof(TkMenu, tearoffCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 offsetof(TkMenu, titlePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, offsetof(TkMenu, menuTypePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) menuTypeStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */

static const char *const menuOptions[] = {
    "activate", "add", "cget", "clone", "configure", "delete", "entrycget",
    "entryconfigure", "index", "insert", "invoke", "post", "postcascade",
    "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,







|



<
<
<
<





|










|

|








|





|
|


|


|


|


|


|


|

|



|


|


|


|


|


|
|

|
|





|
|





|


|


|


|


|


|

|





|


|


|


|


|

|





|

|





|

|
|
|


|









|






|
|


|


|
|
<
<
<

|
|

|

|


|


|


|
|

|

|

|


|

|

|
|


|

|


|

|
|

|
|
|







|







73
74
75
76
77
78
79
80
81
82
83




84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#endif

#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. */




} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following flag indicates whether the process-wide state for the Menu
 * module has been intialized. The Mutex protects access to that flag.
 */

static int menusInitialized;
TCL_DECLARE_MUTEX(menuMutex)

/*
 * Configuration specs for individual menu entries. If this changes, be sure
 * to update code in TkpMenuInit that changes the font string entry.
 */

const char *tkMenuStateStrings[] = {"active", "normal", "disabled", 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
 */

static const char *compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

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", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-accelerator", NULL, NULL,
	DEF_MENU_ENTRY_ACCELERATOR,
	Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_BITMAP, "-bitmap", NULL, NULL,
	DEF_MENU_ENTRY_BITMAP,
	Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL,
	DEF_MENU_ENTRY_COLUMN_BREAK,
	-1, Tk_Offset(TkMenuEntry, columnBreak)},
    {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,
	(ClientData) compoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	-1, Tk_Offset(TkMenuEntry, hideMargin)},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	Tk_Offset(TkMenuEntry, labelPtr), -1, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	-1, Tk_Offset(TkMenuEntry, state), 0,
	(ClientData) tkMenuStateStrings},
    {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", 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", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	-1, Tk_Offset(TkMenuEntry, indicatorOn)},
    {TK_OPTION_STRING, "-offvalue", NULL, NULL,
	DEF_MENU_ENTRY_OFF_VALUE,
	Tk_Offset(TkMenuEntry, offValuePtr), -1},
    {TK_OPTION_STRING, "-onvalue", NULL, NULL,
	DEF_MENU_ENTRY_ON_VALUE,
	Tk_Offset(TkMenuEntry, onValuePtr), -1},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_CHECK_VARIABLE,
	Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};

static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	-1, Tk_Offset(TkMenuEntry, indicatorOn)},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-value", NULL, NULL,
	DEF_MENU_ENTRY_VALUE,
	Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_RADIO_VARIABLE,
	Tk_Offset(TkMenuEntry, namePtr), -1, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};

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, NULL, NULL, NULL,
	NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};

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", NULL, NULL,
	DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state), 0,
	(ClientData) tkMenuStateStrings},
    {TK_OPTION_END}
};

static const Tk_OptionSpec *const specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *menuTypeStrings[] = {
    "normal", "tearoff", "menubar", NULL
};

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,
	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", 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},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	Tk_Offset(TkMenu, cursorPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	Tk_Offset(TkMenu, disabledFgPtr), -1, TK_OPTION_NULL_OK,
	(ClientData) DEF_MENU_DISABLED_FG_MONO},
    {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,
	Tk_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFgPtr), -1, 0,
	(ClientData) DEF_MENU_SELECT_MONO},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	Tk_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, -1, Tk_Offset(TkMenu, tearoff)},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	Tk_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 Tk_Offset(TkMenu, titlePtr), -1,
	TK_OPTION_NULL_OK},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1, TK_OPTION_NULL_OK,
	(ClientData) menuTypeStrings},
    {TK_OPTION_END}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */

static const char *menuOptions[] = {
    "activate", "add", "cget", "clone", "configure", "delete", "entrycget",
    "entryconfigure", "index", "insert", "invoke", "post", "postcascade",
    "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,
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

























































391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
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(void *memPtr);
static TkSizeT	GetIndexFromCoords(Tcl_Interp *interp,
			    TkMenu *menuPtr, const char *string,
			    TkSizeT *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 void		MenuCmdDeletedProc(ClientData clientData);
static TkMenuEntry *	MenuNewEntry(TkMenu *menuPtr, TkSizeT 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		MenuCleanup(ClientData unused);
static int		GetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Obj *objPtr, int lastOK, TkSizeT *indexPtr);

/*
 * 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.
 */

static const Tk_ClassProcs menuClass = {
    sizeof(Tk_ClassProcs),	/* size */
    MenuWorldChanged,		/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 *--------------------------------------------------------------
 *

























































 * Tk_MenuObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenuObjCmd(
    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;
    Tk_Window newWin;
    TkMenu *menuPtr;
    TkMenuReferences *menuRefPtr;
    int i, index, toplevel;
    const char *windowName;
    static const char *const typeStringList[] = {"-type", NULL};
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    TkMenuInit();

    toplevel = 1;
    for (i = 2; i < (objc - 1); i++) {
	if (Tcl_GetIndexFromObjStruct(NULL, objv[i], typeStringList,
		sizeof(char *), NULL, 0, &index) != TCL_ERROR) {
	    if ((Tcl_GetIndexFromObjStruct(NULL, objv[i + 1], menuTypeStrings,
		    sizeof(char *), NULL, 0, &index) == TCL_OK) && (index == MENUBAR)) {
		toplevel = 0;
	    }
	    break;
	}
    }

    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.
     */

    menuPtr = (TkMenu *)ckalloc(sizeof(TkMenu));
    memset(menuPtr, 0, sizeof(TkMenu));
    menuPtr->tkwin = newWin;
    menuPtr->display = Tk_Display(newWin);
    menuPtr->interp = interp;
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = TCL_INDEX_NONE;
    menuPtr->cursorPtr = NULL;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;

    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, menuPtr);
    if (Tk_InitOptions(interp, menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin)
	    != TCL_OK) {
    	Tk_DestroyWindow(menuPtr->tkwin);
    	return TCL_ERROR;
    }


    menuRefPtr = TkCreateMenuReferences(menuPtr->interp,







|
|
<
|







>
>

|










|
<
<







|

|
<
<





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|













|
|





|

|


|
|
|
<


|







|
|
|
|



















|





|
|
|

|

>



|


|
|
|







334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
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(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.
 */

static Tk_ClassProcs menuClass = {
    sizeof(Tk_ClassProcs),	/* size */
    MenuWorldChanged		/* worldChangedProc */


};

/*
 *--------------------------------------------------------------
 *
 * TkCreateMenuCmd --
 *
 *	Called by Tk at initialization time to create the menu command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static void
FreeOptionTables(
    ClientData clientData,
    Tcl_Interp *interp)
{
    ckfree(clientData);
}

int
TkCreateMenuCmd(
    Tcl_Interp *interp)		/* Interpreter we are creating the command
				 * in. */
{
    TkMenuOptionTables *optionTablesPtr =
	    (TkMenuOptionTables *) ckalloc(sizeof(TkMenuOptionTables));

    optionTablesPtr->menuOptionTable =
	    Tk_CreateOptionTable(interp, tkMenuConfigSpecs);
    optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]);
    optionTablesPtr->entryOptionTables[COMMAND_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[COMMAND_ENTRY]);
    optionTablesPtr->entryOptionTables[CASCADE_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[CASCADE_ENTRY]);
    optionTablesPtr->entryOptionTables[SEPARATOR_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[SEPARATOR_ENTRY]);
    optionTablesPtr->entryOptionTables[RADIO_BUTTON_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[RADIO_BUTTON_ENTRY]);
    optionTablesPtr->entryOptionTables[CHECK_BUTTON_ENTRY] =
	    Tk_CreateOptionTable(interp, specsArray[CHECK_BUTTON_ENTRY]);

    Tcl_CreateObjCommand(interp, "menu", MenuCmd, optionTablesPtr, 0);
    Tcl_CallWhenDeleted(interp, FreeOptionTables, optionTablesPtr);

    if (Tcl_IsSafe(interp)) {
	Tcl_HideCommand(interp, "menu", "menu");
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
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 newWin;
    register TkMenu *menuPtr;
    TkMenuReferences *menuRefPtr;
    int i, index, toplevel;
    char *windowName;
    static const char *typeStringList[] = {"-type", NULL};
    TkMenuOptionTables *optionTablesPtr = (TkMenuOptionTables *) clientData;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    TkMenuInit();

    toplevel = 1;
    for (i = 2; i < (objc - 1); i++) {
	if (Tcl_GetIndexFromObj(NULL, objv[i], typeStringList, NULL, 0, &index)
		!= TCL_ERROR) {
	    if ((Tcl_GetIndexFromObj(NULL, objv[i + 1], menuTypeStrings, NULL,
		    0, &index) == TCL_OK) && (index == MENUBAR)) {
		toplevel = 0;
	    }
	    break;
	}
    }

    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.
     */

    menuPtr = (TkMenu *) ckalloc(sizeof(TkMenu));
    memset(menuPtr, 0, sizeof(TkMenu));
    menuPtr->tkwin = newWin;
    menuPtr->display = Tk_Display(newWin);
    menuPtr->interp = interp;
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd,
	    (ClientData) menuPtr, MenuCmdDeletedProc);
    menuPtr->active = -1;
    menuPtr->cursorPtr = NULL;
    menuPtr->masterMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;
    menuPtr->optionTablesPtr = optionTablesPtr;
    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, (ClientData) menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, (ClientData) menuPtr);
    if (Tk_InitOptions(interp, (char *) menuPtr,
	    menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin)
	    != TCL_OK) {
    	Tk_DestroyWindow(menuPtr->tkwin);
    	return TCL_ERROR;
    }


    menuRefPtr = TkCreateMenuReferences(menuPtr->interp,
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
	TkMenuEntry *nextCascadePtr;
	Tcl_Obj *newMenuName, *newObjv[2];

	while (cascadeListPtr != NULL) {
	    nextCascadePtr = cascadeListPtr->nextCascadePtr;

     	    /*
	     * If we have a new main 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->mainMenuPtr != menuPtr)
     	    	    || ((menuPtr->mainMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->mainMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
     	    } else {
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);







|







|
|
|


|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
	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 ((menuPtr->masterMenuPtr != menuPtr)
     	    	    || ((menuPtr->masterMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->masterMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
     	    } else {
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --







|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetResult(interp, Tk_PathName(menuPtr->tkwin), TCL_STATIC);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901

902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948

949
950
951
952
953
954
955
956
957
958
static int
MenuWidgetObjCmd(
    ClientData clientData,	/* Information about menu widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    int result = TCL_OK;
    int option;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], menuOptions,
	    sizeof(char *), "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (menuPtr->active == index) {
	    goto done;
	}
	if ((index != TCL_INDEX_NONE) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = TCL_INDEX_NONE;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type ?-option value ...?");
	    goto error;
	}

	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, 2, objv, "option");
	    goto error;
	}
	resultPtr = Tk_GetOptionValue(interp, menuPtr,
		tsdPtr->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, menuPtr,
		    tsdPtr->menuOptionTable, 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, menuPtr,
		    tsdPtr->menuOptionTable, objv[2],
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	TkSizeT first, last;
	Tcl_WideInt w;

	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_GetWideIntFromObj(NULL, objv[2], &w) == TCL_OK) {
	    first = w;
	    if (first >= menuPtr->numEntries) {
		goto done;
	    }
	} else if (GetMenuIndex(interp,menuPtr,objv[2],0,&first) != TCL_OK){
	    goto error;
	}
	if (objc == 3) {
	    last = first;
	} else if (GetMenuIndex(interp,menuPtr,objv[3],0,&last) != TCL_OK) {
	    goto error;
	}

	if (menuPtr->tearoff && (first == 0)) {
	    /*
	     * Sorry, can't delete the tearoff entry; must reconfigure the
	     * menu.
	     */

	    first = 1;
	}
	if ((first == TCL_INDEX_NONE) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, mePtr,
		mePtr->optionTable, objv[3], menuPtr->tkwin);
	Tcl_Release(mePtr);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_ENTRYCONFIGURE: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
		    mePtr->optionTable, 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, 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(mePtr);
	break;
    }
    case MENU_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else
	Tcl_SetObjResult(interp, TkNewIndexObj(index));

	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
	}
	if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) {
	    goto error;
	}
	break;
    case MENU_INVOKE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	TkSizeT index = TCL_INDEX_NONE;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	if (objc == 5) {
            if (GetMenuIndex(interp, menuPtr, objv[4], 0, &index) != TCL_OK) {
                goto error;
            }
	}

	/*
	 * Tearoff menus are the same as ordinary menus on the Mac and are
	 * posted differently on Windows than non-tearoffs. TkpPostMenu
	 * does not actually map the menu's window on those platforms, and
	 * popup menus have to be handled specially.  Also, menubar menus are
	 * not intended to be posted (bug 1567681, 2160206).

	 */

	if (menuPtr->menuType == MENUBAR) {
            Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL);
            return TCL_ERROR;
        } else if (menuPtr->menuType != TEAROFF_MENU) {
	    result = TkpPostMenu(interp, menuPtr, x, y, index);
	} else {
	    result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}

	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if ((index == TCL_INDEX_NONE) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
	    result = TkPostSubmenu(interp, menuPtr, NULL);
	} else {
	    result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
	}
	break;
    }
    case MENU_TYPE: {
	TkSizeT index;
	const char *typeStr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	if (menuPtr->entries[index]->type == TEAROFF_ENTRY) {
	    typeStr = "tearoff";
	} else {

	    typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type];
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
	break;
    }
    case MENU_UNPOST:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}







|
|


<
<


|


|
|


|



|





|





|

|






|



|










|
|


















|
|








|
|
















|
<












|
<



|




|











|






|






|


|



|
|

|







|



|


|


|



|

|








|











|



|





|


|
|
|
|
>




|
<







|





|


|







<

|
|






<
<
<
|
<
<

<
|
|
|
|
>






|

|




|






|


|







|
<





|


|



|

>
|

<







665
666
667
668
669
670
671
672
673
674
675


676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930
931



932


933

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970

971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
static int
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;
    int result = TCL_OK;
    int option;



    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], menuOptions, "option", 0,
	    &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve((ClientData) menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	int index;

	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;
	}

	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, 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);
	    }
	} else if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
		    menuPtr->optionTablesPtr->menuOptionTable, objv[2],
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	int first, last;


	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;
	    }
	} 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;
	}

	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);
	    }
	} 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;
    }
    case MENU_INDEX: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "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;
    }
    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, 2, objv, "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;
    }
    case MENU_POST: {
	int x, y;


	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;
	}






	/*

	 * 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.
         * Also, menubar menues are not intended to be posted (bug 1567681,
         * 2160206).
	 */

	if (menuPtr->menuType == MENUBAR) {
            Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL);
            return TCL_ERROR;
        } else if (menuPtr->menuType != TEAROFF_MENU) {
	    result = TkpPostMenu(interp, menuPtr, x, y);
	} else {
	    result = TkPostTearoffMenu(interp, menuPtr, x, y);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	int index;

	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, NULL);
	} else {
	    result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
	}
	break;
    }
    case MENU_TYPE: {
	int index;


	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) {
	    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;
    }
    case MENU_UNPOST:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	result = MenuDoYPosition(interp, menuPtr, objv[2]);
	break;
    }
  done:
    Tcl_Release(menuPtr);
    return result;

  error:
    Tcl_Release(menuPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkInvokeMenu --







|



|







1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	result = MenuDoYPosition(interp, menuPtr, objv[2]);
	break;
    }
  done:
    Tcl_Release((ClientData) menuPtr);
    return result;

  error:
    Tcl_Release((ClientData) menuPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkInvokeMenu --
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
 *----------------------------------------------------------------------
 */

int
TkInvokeMenu(
    Tcl_Interp *interp,		/* The interp that the menu lives in. */
    TkMenu *menuPtr,		/* The menu we are invoking. */
    TkSizeT index)			/* The zero based index of the item we are
    				 * invoking. */
{
    int result = TCL_OK;
    TkMenuEntry *mePtr;

    if (index == TCL_INDEX_NONE) {
    	goto done;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    Tcl_Preserve(mePtr);
    if (mePtr->type == TEAROFF_ENTRY) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "tk::TearOffMenu ", -1);
	Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&ds), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&ds);
    } else if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;







|





|






<
|


<



|







1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
 *----------------------------------------------------------------------
 */

int
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;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    Tcl_Preserve((ClientData) mePtr);
    if (mePtr->type == TEAROFF_ENTRY) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "tk::TearOffMenu ", -1);
	Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1);
	result = Tcl_Eval(interp, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
    } else if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
	    && (mePtr->commandPtr != NULL)) {
	Tcl_Obj *commandPtr = mePtr->commandPtr;

	Tcl_IncrRefCount(commandPtr);
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
	Tcl_DecrRefCount(commandPtr);
    }
    Tcl_Release(mePtr);

  done:
    return result;
}

/*
 *----------------------------------------------------------------------
 *







|
<







1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
	    && (mePtr->commandPtr != NULL)) {
	Tcl_Obj *commandPtr = mePtr->commandPtr;

	Tcl_IncrRefCount(commandPtr);
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
	Tcl_DecrRefCount(commandPtr);
    }
    Tcl_Release((ClientData) mePtr);

  done:
    return result;
}

/*
 *----------------------------------------------------------------------
 *
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
DestroyMenuInstance(
    TkMenu *menuPtr)		/* Info about menu widget. */
{
    int i;
    TkMenu *menuInstancePtr;
    TkMenuEntry *cascadePtr, *nextCascadePtr;
    Tcl_Obj *newObjv[2];
    TkMenu *parentMainMenuPtr;
    TkMenuEntry *parentMainEntryPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * 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 main menus back to
     * this entry name if this is a main menu pointed to by another main
     * 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 main menu name so that
     * later if another menu is created the cascade hierarchy can be
     * maintained.
     */

    TkpDestroyMenu(menuPtr);
    if (menuPtr->menuRefPtr == NULL) {
	return;
    }
    cascadePtr = menuPtr->menuRefPtr->parentEntryPtr;
    menuPtr->menuRefPtr->menuPtr = NULL;
    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->mainMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;

	    /*
	     * 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]);
		ConfigureMenuEntry(cascadePtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    ConfigureMenuEntry(cascadePtr, 0, NULL);
    	}
    }

    if (menuPtr->mainMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->mainMenuPtr;
		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 main 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.
     */

    for (i = menuPtr->numEntries; --i >= 0; ) {
	/*
	 * As each menu entry is deleted from the end of the array of entries,
	 * decrement menuPtr->numEntries. Otherwise, the act of deleting menu
	 * entry i will dereference freed memory attempting to queue a redraw
	 * for menu entries (i+1)...numEntries.
	 */

	DestroyMenuEntry(menuPtr->entries[i]);
	menuPtr->numEntries = i;
    }
    if (menuPtr->entries != NULL) {
	ckfree(menuPtr->entries);
    }
    TkMenuFreeDrawOptions(menuPtr);
    Tk_FreeConfigOptions((char *) menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin);
    if (menuPtr->tkwin != NULL) {
	Tk_Window tkwin = menuPtr->tkwin;

	menuPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *
 *	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 main instance, destroys all of the
 *	instances. If called on a non-main instance, just destroys
 *	that instance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the menu is freed up.







|
|
<
<






|
|


|

















|


|
|
|

|


















|
|









|















|



|



|


<












|
|







1136
1137
1138
1139
1140
1141
1142
1143
1144


1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
DestroyMenuInstance(
    TkMenu *menuPtr)		/* Info about menu widget. */
{
    int i;
    TkMenu *menuInstancePtr;
    TkMenuEntry *cascadePtr, *nextCascadePtr;
    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.
     */

    TkpDestroyMenu(menuPtr);
    if (menuPtr->menuRefPtr == NULL) {
	return;
    }
    cascadePtr = menuPtr->menuRefPtr->parentEntryPtr;
    menuPtr->menuRefPtr->menuPtr = NULL;
    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->masterMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMasterMenuPtr = cascadePtr->menuPtr->masterMenuPtr;
	    parentMasterEntryPtr =
		    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]
	     */

	    if (newObjv[0] && newObjv[1]) {
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
		ConfigureMenuEntry(cascadePtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    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) {
	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.
     */

    for (i = menuPtr->numEntries; --i >= 0; ) {
	/*
	 * As each menu entry is deleted from the end of the array of entries,
	 * decrement menuPtr->numEntries. Otherwise, the act of deleting menu
	 * entry i will dereference freed memory attempting to queue a redraw
	 * for menu entries (i+1)...numEntries.
	 */

	DestroyMenuEntry((char *) menuPtr->entries[i]);
	menuPtr->numEntries = i;
    }
    if (menuPtr->entries != NULL) {
	ckfree((char *) menuPtr->entries);
    }
    TkMenuFreeDrawOptions(menuPtr);
    Tk_FreeConfigOptions((char *) menuPtr,
	    menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin);
    if (menuPtr->tkwin != NULL) {
	Tk_Window tkwin = menuPtr->tkwin;

	menuPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *
 *	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.
 *
 * Side effects:
 *	Everything associated with the menu is freed up.
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->mainMenuPtr == menuPtr) {
	while (menuPtr->nextInstancePtr != NULL) {
	    menuInstancePtr = menuPtr->nextInstancePtr;
	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
    	    if (menuInstancePtr->tkwin != NULL) {
		Tk_Window tkwin = menuInstancePtr->tkwin;

		/*







|







1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->masterMenuPtr == menuPtr) {
	while (menuPtr->nextInstancePtr != NULL) {
	    menuInstancePtr = menuPtr->nextInstancePtr;
	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
    	    if (menuInstancePtr->tkwin != NULL) {
		Tk_Window tkwin = menuInstancePtr->tkwin;

		/*
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421


1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(
    void *memPtr)		/* Pointer to entry to be freed. */
{
    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.
	 */

	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.
     */

    if (mePtr->type == CASCADE_ENTRY) {
	if (menuPtr->mainMenuPtr != menuPtr) {
	    TkMenu *destroyThis = NULL;
	    TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr;

	    /*
	     * The menu as a whole is a clone. We must delete the clone of the
	     * cascaded menu for the particular entry we are destroying.
	     */



	    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.
		 */

		if ((destroyThis != NULL)
			&& (destroyThis->mainMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {







|

|


















|

<
<




>
>












|







1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445


1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
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.
	 */

	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.
     */

    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.
	     */

	    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.
		 */

		if ((destroyThis != NULL)
			&& (destroyThis->masterMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
    }
    if (mePtr->selectImage != NULL) {
	Tk_FreeImage(mePtr->selectImage);
    }
    if (((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY))
	    && (mePtr->namePtr != NULL)) {
	const char *varName = Tcl_GetString(mePtr->namePtr);

	Tcl_UntraceVar2(menuPtr->interp, varName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }
    TkpDestroyMenuEntry(mePtr);
    TkMenuEntryFreeDrawOptions(mePtr);
    Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin);
    ckfree(mePtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * MenuWorldChanged --
 *







|

|

|




|







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
    }
    if (mePtr->selectImage != NULL) {
	Tk_FreeImage(mePtr->selectImage);
    }
    if (((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY))
	    && (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);
    }
    TkpDestroyMenuEntry(mePtr);
    TkMenuEntryFreeDrawOptions(mePtr);
    Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin);
    ckfree((char *) mePtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * MenuWorldChanged --
 *
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
 *---------------------------------------------------------------------------
 */

static void
MenuWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)instanceData;
    TkSizeT i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }







|
|







1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
 *---------------------------------------------------------------------------
 */

static void
MenuWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *) instanceData;
    int i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542

1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632

1633

1634
1635
1636
1637
1638
1639

1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenu(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	menuListPtr->errorStructPtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));

	result = Tk_SetOptions(interp, menuListPtr,
		tsdPtr->menuOptionTable, objc, objv,
		menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->mainMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree(cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {
		Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
		ckfree(menuListPtr->errorStructPtr);
		menuListPtr->errorStructPtr = NULL;
	    }
	    return TCL_ERROR;
	}

	/*
	 * 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_GetIndexFromObjStruct(NULL, menuListPtr->menuTypePtr,
		    menuTypeStrings, sizeof(char *), NULL, 0, &menuListPtr->menuType);

	    /*
	     * Configure the new window to be either a pop-up menu or a
	     * tear-off menu. We don't do this for menubars since they are not
	     * toplevel windows. Also, since this gets called before CloneMenu
	     * has a chance to set the menuType field, we have to look at the
	     * menuTypeName field to tell that this is a menu bar.
	     */

	    if (menuListPtr->menuType == MAIN_MENU) {
		int typeFlag = TK_MAKE_MENU_POPUP;
		Tk_Window tkwin = menuPtr->tkwin;

		/*
		 * Work out if we are the child of a menubar or a popup.
		 */

		while (1) {
		    Tk_Window parent = Tk_Parent(tkwin);

		    if (Tk_Class(parent) != Tk_Class(menuPtr->tkwin)) {
			break;
		    }
		    tkwin = parent;
		}
		if (((TkMenu *) tkwin)->menuType == MENUBAR) {
		    typeFlag = TK_MAKE_MENU_DROPDOWN;
		}

		TkpMakeMenuWindow(menuListPtr->tkwin, typeFlag);
	    } else if (menuListPtr->menuType == TEAROFF_MENU) {
		TkpMakeMenuWindow(menuListPtr->tkwin, TK_MAKE_MENU_TEAROFF);
	    }
	}


	/*
	 * 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)) {
		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {
		    for (cleanupPtr = menuPtr->mainMenuPtr;
			    cleanupPtr != menuListPtr;
			    cleanupPtr = cleanupPtr->nextInstancePtr) {
			Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
			ckfree(cleanupPtr->errorStructPtr);
			cleanupPtr->errorStructPtr = NULL;
		    }
		    if (menuListPtr->errorStructPtr != NULL) {
			Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
			ckfree(menuListPtr->errorStructPtr);
			menuListPtr->errorStructPtr = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {



	    Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry);

	    for (i = 0; i < (int)menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }

	    if (--menuListPtr->numEntries == 0) {
		ckfree(menuListPtr->entries);
		menuListPtr->entries = NULL;
	    }
	}

	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.
	 */

	for (i = 0; i < (int)menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
    }

    for (cleanupPtr = menuPtr->mainMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree(cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;
}

/*







|







<
<

|

|
>
|
|


|



|




|













|
|









|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|


>










|
|
|

|




|







>

>
|

|



>
|
|













|









|


|







1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566


1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610



















1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
 *
 *----------------------------------------------------------------------
 */

static int
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, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->masterMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree((char *) cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {
		Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
		ckfree((char *) menuListPtr->errorStructPtr);
		menuListPtr->errorStructPtr = NULL;
	    }
	    return TCL_ERROR;
	}

	/*
	 * 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
	     * menuTypeName field to tell that this is a menu bar.
	     */

	    if (menuListPtr->menuType == MASTER_MENU) {



















		TkpMakeMenuWindow(menuListPtr->tkwin, 1);
	    } else if (menuListPtr->menuType == TEAROFF_MENU) {
		TkpMakeMenuWindow(menuListPtr->tkwin, 0);
	    }
	}


	/*
	 * Depending on the -tearOff option, make sure that there is or isn't
	 * an initial tear-off entry at the beginning of the menu.
	 */

	if (menuListPtr->tearoff) {
	    if ((menuListPtr->numEntries == 0)
		    || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {
		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {
		    for (cleanupPtr = menuPtr->masterMenuPtr;
			 cleanupPtr != menuListPtr;
			 cleanupPtr = cleanupPtr->nextInstancePtr) {
			Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
			ckfree((char *) cleanupPtr->errorStructPtr);
			cleanupPtr->errorStructPtr = NULL;
		    }
		    if (menuListPtr->errorStructPtr != NULL) {
			Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
			ckfree((char *) menuListPtr->errorStructPtr);
			menuListPtr->errorStructPtr = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {
	    int i;

	    Tcl_EventuallyFree((ClientData) menuListPtr->entries[0],
	    	    DestroyMenuEntry);

	    for (i = 0; i < menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }
	    menuListPtr->numEntries--;
	    if (menuListPtr->numEntries == 0) {
		ckfree((char *) menuListPtr->entries);
		menuListPtr->entries = NULL;
	    }
	}

	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.
	 */

	for (i = 0; i < menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
    }

    for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree((char *) cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;
}

/*
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725

static int
PostProcessEntry(
    TkMenuEntry *mePtr)			/* The entry we are configuring. */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    int index = mePtr->index;
    const char *name;
    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.
     */

    if (mePtr->labelPtr == NULL) {
	mePtr->labelLength = 0;
    } else {
	(void)TkGetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
    }

    /*
     * If this is a cascade entry, the platform-specific data of the child
     * menu has to be updated. Also, the links that point to parents and
     * cascades have to be updated.
     */







|











|




|







1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739

static int
PostProcessEntry(
    TkMenuEntry *mePtr)			/* The entry we are configuring. */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    int index = mePtr->index;
    char *name;
    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.
     */

    if (mePtr->labelPtr == NULL) {
	mePtr->labelLength = 0;
    } else {
	Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
    }

    /*
     * If this is a cascade entry, the platform-specific data of the child
     * menu has to be updated. Also, the links that point to parents and
     * cascades have to be updated.
     */
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
	 * the list of entries pointing to the new menu.
	 *
	 * BUG: We are not recloning for special case #3 yet.
	 */

	name = Tcl_GetString(mePtr->namePtr);
	if (mePtr->childMenuRefPtr != NULL) {
	    oldHashKey = (char *)Tcl_GetHashKey(TkGetMenuHashTable(menuPtr->interp),
		    mePtr->childMenuRefPtr->hashEntryPtr);
	    if (strcmp(oldHashKey, name) != 0) {
		UnhookCascadeEntry(mePtr);
	    }
	}

	if ((mePtr->childMenuRefPtr == NULL)







|







1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
	 * the list of entries pointing to the new menu.
	 *
	 * BUG: We are not recloning for special case #3 yet.
	 */

	name = Tcl_GetString(mePtr->namePtr);
	if (mePtr->childMenuRefPtr != NULL) {
	    oldHashKey = Tcl_GetHashKey(TkGetMenuHashTable(menuPtr->interp),
		    mePtr->childMenuRefPtr->hashEntryPtr);
	    if (strcmp(oldHashKey, name) != 0) {
		UnhookCascadeEntry(mePtr);
	    }
	}

	if ((mePtr->childMenuRefPtr == NULL)
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
    /*
     * 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) {
	const char *imageString = Tcl_GetString(mePtr->imagePtr);

	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, imageString,
		TkMenuImageProc, mePtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (mePtr->image != NULL) {
	Tk_FreeImage(mePtr->image);
    }
    mePtr->image = image;
    if (mePtr->selectImagePtr != NULL) {
	const char *selectImageString = Tcl_GetString(mePtr->selectImagePtr);

	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, selectImageString,
		TkMenuSelectImageProc, mePtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (mePtr->selectImage != NULL) {
	Tk_FreeImage(mePtr->selectImage);
    }
    mePtr->selectImage = image;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	Tcl_Obj *valuePtr;


	if (mePtr->namePtr == NULL) {
	    if (mePtr->labelPtr == NULL) {
		mePtr->namePtr = NULL;
	    } else {
		mePtr->namePtr = Tcl_DuplicateObj(mePtr->labelPtr);
		Tcl_IncrRefCount(mePtr->namePtr);







|


|











|


|














>







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
    /*
     * 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_GetString(mePtr->imagePtr);

	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, imageString,
		TkMenuImageProc, (ClientData) mePtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (mePtr->image != NULL) {
	Tk_FreeImage(mePtr->image);
    }
    mePtr->image = image;
    if (mePtr->selectImagePtr != NULL) {
	char *selectImageString = Tcl_GetString(mePtr->selectImagePtr);

	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, selectImageString,
		TkMenuSelectImageProc, (ClientData) mePtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (mePtr->selectImage != NULL) {
	Tk_FreeImage(mePtr->selectImage);
    }
    mePtr->selectImage = image;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	Tcl_Obj *valuePtr;
	char *name;

	if (mePtr->namePtr == NULL) {
	    if (mePtr->labelPtr == NULL) {
		mePtr->namePtr = NULL;
	    } else {
		mePtr->namePtr = Tcl_DuplicateObj(mePtr->labelPtr);
		Tcl_IncrRefCount(mePtr->namePtr);
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
		    TCL_GLOBAL_ONLY);
	} else {
	    valuePtr = NULL;
	}
	mePtr->entryFlags &= ~ENTRY_SELECTED;
	if (valuePtr != NULL) {
	    if (mePtr->onValuePtr != NULL) {
		const char *value = Tcl_GetString(valuePtr);
		const char *onValue = Tcl_GetString(mePtr->onValuePtr);

		if (strcmp(value, onValue) == 0) {
		    mePtr->entryFlags |= ENTRY_SELECTED;
		}
	    }
	} else {
	    if (mePtr->namePtr != NULL) {
		Tcl_ObjSetVar2(menuPtr->interp, mePtr->namePtr, NULL,
			(mePtr->type == CHECK_BUTTON_ENTRY)
			? mePtr->offValuePtr : Tcl_NewObj(), TCL_GLOBAL_ONLY);
	    }
	}
	if (mePtr->namePtr != NULL) {
	    name = Tcl_GetString(mePtr->namePtr);
	    Tcl_TraceVar2(menuPtr->interp, name,
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MenuVarProc, mePtr);
	}
    }

    if (TkpConfigureMenuEntry(mePtr) != TCL_OK) {
	return TCL_ERROR;
    }








|
|














|
|
|







1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
		    TCL_GLOBAL_ONLY);
	} else {
	    valuePtr = NULL;
	}
	mePtr->entryFlags &= ~ENTRY_SELECTED;
	if (valuePtr != NULL) {
	    if (mePtr->onValuePtr != NULL) {
		char *value = Tcl_GetString(valuePtr);
		char *onValue = Tcl_GetString(mePtr->onValuePtr);

		if (strcmp(value, onValue) == 0) {
		    mePtr->entryFlags |= ENTRY_SELECTED;
		}
	    }
	} else {
	    if (mePtr->namePtr != NULL) {
		Tcl_ObjSetVar2(menuPtr->interp, mePtr->namePtr, NULL,
			(mePtr->type == CHECK_BUTTON_ENTRY)
			? mePtr->offValuePtr : Tcl_NewObj(), TCL_GLOBAL_ONLY);
	    }
	}
	if (mePtr->namePtr != NULL) {
	    name = Tcl_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;
    }

1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuEntry(
    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 function.
     */

    if ((mePtr->namePtr != NULL)
    	    && ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY))) {
	const char *name = Tcl_GetString(mePtr->namePtr);

	Tcl_UntraceVar2(menuPtr->interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }

    result = TCL_OK;
    if (menuPtr->tkwin != NULL) {
	if (Tk_SetOptions(menuPtr->interp, mePtr,
		mePtr->optionTable, objc, objv, menuPtr->tkwin,
		&errorStruct, NULL) != TCL_OK) {
	    return TCL_ERROR;
	}
	result = PostProcessEntry(mePtr);
	if (result != TCL_OK) {
	    Tk_RestoreSavedOptions(&errorStruct);







|
















|

|

|




|







1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
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 function.
     */

    if ((mePtr->namePtr != NULL)
    	    && ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY))) {
	char *name = Tcl_GetString(mePtr->namePtr);

	Tcl_UntraceVar(menuPtr->interp, name,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, (ClientData) mePtr);
    }

    result = TCL_OK;
    if (menuPtr->tkwin != NULL) {
	if (Tk_SetOptions(menuPtr->interp, (char *) mePtr,
		mePtr->optionTable, objc, objv, menuPtr->tkwin,
		&errorStruct, NULL) != TCL_OK) {
	    return TCL_ERROR;
	}
	result = PostProcessEntry(mePtr);
	if (result != TCL_OK) {
	    Tk_RestoreSavedOptions(&errorStruct);
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(
    Tcl_Interp *dummy,		/* 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;
    Tcl_Obj *oldCascadePtr = NULL;
    const char *newCascadeName;
    (void)dummy;

    /*
     * 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 main
     * 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->mainMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }

    if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) {
	return TCL_ERROR;
    }

    if (mePtr->type == CASCADE_ENTRY) {
	const char *oldCascadeName;

	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	} else {
	    newCascadeName = NULL;
	}








|










|
<



|






|












|







1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
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;
    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.
     */

    mePtr = menuPtr->masterMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }

    if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) {
	return TCL_ERROR;
    }

    if (mePtr->type == CASCADE_ENTRY) {
	char *oldCascadeName;

	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	} else {
	    newCascadeName = NULL;
	}

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->mainMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
		    mePtr->namePtr);

	    if ((oldCascadeMenuRefPtr != NULL)
		    && (oldCascadeMenuRefPtr->menuPtr != NULL)) {
		RecursivelyDeleteMenu(oldCascadeMenuRefPtr->menuPtr);
	    }
	}

    	if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) {
    	    return TCL_ERROR;
    	}

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    if (cascadeMenuRefPtr && cascadeMenuRefPtr->menuPtr != NULL) {
		Tcl_Obj *newObjv[2];
		Tcl_Obj *newCloneNamePtr;
		Tcl_Obj *pathNamePtr = Tcl_NewStringObj(
			Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		Tcl_Obj *menuObjPtr = Tcl_NewStringObj("-menu", -1);








|




















|







2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
		    mePtr->namePtr);

	    if ((oldCascadeMenuRefPtr != NULL)
		    && (oldCascadeMenuRefPtr->menuPtr != NULL)) {
		RecursivelyDeleteMenu(oldCascadeMenuRefPtr->menuPtr);
	    }
	}

    	if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) {
    	    return TCL_ERROR;
    	}

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    if (cascadeMenuRefPtr->menuPtr != NULL) {
		Tcl_Obj *newObjv[2];
		Tcl_Obj *newCloneNamePtr;
		Tcl_Obj *pathNamePtr = Tcl_NewStringObj(
			Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		Tcl_Obj *menuObjPtr = Tcl_NewStringObj("-menu", -1);

2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161

















2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * GetMenuIndex --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
GetMenuIndex(
    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
				 * manual entry for valid .*/
    int lastOK,			/* Non-zero means its OK to return index just
				 * *after* last entry. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *string;

    if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) {
	/* TCL_INDEX_NONE is only accepted if it does not result from a negative number */
	if (*indexPtr != TCL_INDEX_NONE || Tcl_GetString(objPtr)[0] != '-') {
	    if (*indexPtr >= menuPtr->numEntries) {
		*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	    }
	    return TCL_OK;
	}
    }

    string = Tcl_GetString(objPtr);

    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
	*indexPtr = menuPtr->active;
	goto success;
    }

    if ((string[0] == 'l') && (strcmp(string, "last") == 0)) {

	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	goto success;
    }

    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = TCL_INDEX_NONE;
	goto success;
    }

    if (string[0] == '@') {
	if (GetIndexFromCoords(NULL, menuPtr, string, indexPtr)
		== TCL_OK) {
	    goto success;
	}
    }


















    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
	const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringCaseMatch(label, string, 0))) {
	    *indexPtr = i;
	    goto success;
	}
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad menu entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
    return TCL_ERROR;

  success:
    return TCL_OK;
}

/*







|

















|







|


<
<
<
<
<
<
<
<
<
<
<
<
|






|
>





|




|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|

|





<
|
<







2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139












2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191

2192

2193
2194
2195
2196
2197
2198
2199
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkGetMenuIndex --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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
				 * 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 i;












    char *string = Tcl_GetString(objPtr);

    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
	*indexPtr = menuPtr->active;
	goto success;
    }

    if (((string[0] == 'l') && (strcmp(string, "last") == 0))
	    || ((string[0] == 'e') && (strcmp(string, "end") == 0))) {
	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	goto success;
    }

    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = -1;
	goto success;
    }

    if (string[0] == '@') {
	if (GetIndexFromCoords(interp, menuPtr, string, indexPtr)
		== TCL_OK) {
	    goto success;
	}
    }

    if (isdigit(UCHAR(string[0]))) {
	if (Tcl_GetInt(interp, string, &i) == TCL_OK) {
	    if (i >= menuPtr->numEntries) {
		if (lastOK) {
		    i = menuPtr->numEntries;
		} else {
		    i = menuPtr->numEntries-1;
		}
	    } else if (i < 0) {
		i = -1;
	    }
	    *indexPtr = i;
	    goto success;
	}
	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_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringMatch(label, string))) {
	    *indexPtr = i;
	    goto success;
	}
    }


    Tcl_AppendResult(interp, "bad menu entry index \"", string, "\"", NULL);

    return TCL_ERROR;

  success:
    return TCL_OK;
}

/*
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
 *----------------------------------------------------------------------
 */

static void
MenuCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    Tk_Window tkwin = menuPtr->tkwin;

    /*
     * 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.







|







2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
 *----------------------------------------------------------------------
 */

static void
MenuCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenu *menuPtr = (TkMenu *) clientData;
    Tk_Window tkwin = menuPtr->tkwin;

    /*
     * 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.
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
MenuNewEntry(
    TkMenu *menuPtr,		/* Menu that will hold the new entry. */
    TkSizeT index,			/* Where in the menu the new entry is to
				 * go. */
    int type)			/* The type of the new entry. */
{
    TkMenuEntry *mePtr;
    TkMenuEntry **newEntries;
    TkSizeT i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Create a new array of entries with an empty slot for the new entry.
     */

    newEntries = (TkMenuEntry **)ckalloc((menuPtr->numEntries+1) * sizeof(TkMenuEntry *));

    for (i = 0; i < index; i++) {
	newEntries[i] = menuPtr->entries[i];
    }
    for (; i < menuPtr->numEntries; i++) {
	newEntries[i+1] = menuPtr->entries[i];
	newEntries[i+1]->index = i + 1;
    }
    if (menuPtr->numEntries != 0) {
	ckfree(menuPtr->entries);
    }
    menuPtr->entries = newEntries;
    menuPtr->numEntries++;
    mePtr = (TkMenuEntry *)ckalloc(sizeof(TkMenuEntry));
    menuPtr->entries[index] = mePtr;
    mePtr->type = type;
    mePtr->optionTable = tsdPtr->entryOptionTables[type];
    mePtr->menuPtr = menuPtr;
    mePtr->labelPtr = NULL;
    mePtr->labelLength = 0;
    mePtr->underline = -1;
    mePtr->bitmapPtr = NULL;
    mePtr->imagePtr = NULL;
    mePtr->image = NULL;







|





|
<
<





|
>








|



|


|







2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269


2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
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. */
{
    TkMenuEntry *mePtr;
    TkMenuEntry **newEntries;
    int i;



    /*
     * Create a new array of entries with an empty slot for the new entry.
     */

    newEntries = (TkMenuEntry **) ckalloc((unsigned)
	    ((menuPtr->numEntries+1)*sizeof(TkMenuEntry *)));
    for (i = 0; i < index; i++) {
	newEntries[i] = menuPtr->entries[i];
    }
    for (; i < menuPtr->numEntries; i++) {
	newEntries[i+1] = menuPtr->entries[i];
	newEntries[i+1]->index = i + 1;
    }
    if (menuPtr->numEntries != 0) {
	ckfree((char *) menuPtr->entries);
    }
    menuPtr->entries = newEntries;
    menuPtr->numEntries++;
    mePtr = (TkMenuEntry *) ckalloc(sizeof(TkMenuEntry));
    menuPtr->entries[index] = mePtr;
    mePtr->type = type;
    mePtr->optionTable = menuPtr->optionTablesPtr->entryOptionTables[type];
    mePtr->menuPtr = menuPtr;
    mePtr->labelPtr = NULL;
    mePtr->labelLength = 0;
    mePtr->underline = -1;
    mePtr->bitmapPtr = NULL;
    mePtr->imagePtr = NULL;
    mePtr->image = NULL;
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
    mePtr->namePtr = NULL;
    mePtr->childMenuRefPtr = NULL;
    mePtr->onValuePtr = NULL;
    mePtr->offValuePtr = NULL;
    mePtr->entryFlags = 0;
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,
		menuPtr->tkwin);
    	ckfree(mePtr);
    	return NULL;
    }

    return mePtr;
}

/*







|

|






|







2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
    mePtr->namePtr = NULL;
    mePtr->childMenuRefPtr = NULL;
    mePtr->onValuePtr = NULL;
    mePtr->offValuePtr = NULL;
    mePtr->entryFlags = 0;
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, (char *) mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree((char *) mePtr);
	return NULL;
    }
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,
		menuPtr->tkwin);
    	ckfree((char *) mePtr);
    	return NULL;
    }

    return mePtr;
}

/*
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402

2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
    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;
    TkSizeT index;
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;

    if (indexPtr != NULL) {
	if (GetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad menu entry index \"%s\"", Tcl_GetString(indexPtr)));
	Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
	    sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    TkSizeT i;

	    for (errorMenuPtr = menuPtr->mainMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(errorMenuPtr->entries[index],
    	    		(Tcl_FreeProc *) DestroyMenuEntry);
		for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
		    errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
		    errorMenuPtr->entries[i]->index = i;
		}

		if (--errorMenuPtr->numEntries == 0) {
		    ckfree(errorMenuPtr->entries);
		    errorMenuPtr->entries = NULL;
		}
		if (errorMenuPtr == menuListPtr) {
		    break;
		}
	    }
    	    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 main menu has. This is special case #2
	 * in the comment at the top of this file.
    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->mainMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		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) {
		    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);







|
<




|





|
<
|
|










|
|







|








|

|


|
|




>
|
|













|








|

















|







2358
2359
2360
2361
2362
2363
2364
2365

2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
    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) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index < 0) {

	char *indexString = Tcl_GetString(indexPtr);
	Tcl_AppendResult(interp, "bad index \"", indexString, "\"", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObj(interp, objv[0], menuEntryTypeStrings,
	    "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    int i;

	    for (errorMenuPtr = menuPtr->masterMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree((ClientData) errorMenuPtr->entries[index],
    	    		DestroyMenuEntry);
		for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
		    errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
		    errorMenuPtr->entries[i]->index = i;
		}
		errorMenuPtr->numEntries--;
		if (errorMenuPtr->numEntries == 0) {
		    ckfree((char *) errorMenuPtr->entries);
		    errorMenuPtr->entries = NULL;
		}
		if (errorMenuPtr == menuListPtr) {
		    break;
		}
	    }
    	    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 ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->masterMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		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) {
		    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);
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495

2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
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 *name, *onValue;
    (void)name1;
    (void)name2;

    if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) {

	/*
	 * Do nothing if the interpreter is going away or we have
	 * no variable name.
	 */

    	return NULL;
    }

    menuPtr = mePtr->menuPtr;

    if (menuPtr->menuFlags & MENU_DELETION_PENDING) {
    	return NULL;
    }

    name = Tcl_GetString(mePtr->namePtr);

    /*
     * If the variable is being unset, then re-establish the trace.
     */

    if (flags & TCL_TRACE_UNSETS) {
        ClientData probe = NULL;
	mePtr->entryFlags &= ~ENTRY_SELECTED;

        do {
                probe = Tcl_VarTraceInfo(interp, name,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuVarProc, probe);
                if (probe == (ClientData)mePtr) {
                    break;
                }
        } while (probe);
        if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * namePtr, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
		return NULL;
        }
	Tcl_TraceVar2(interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, clientData);
	TkpConfigureMenuEntry(mePtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
	return NULL;
    }

    /*
     * Use the value of the variable to update the selected status of the menu
     * entry.
     */

    value = Tcl_GetVar2(interp, name, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mePtr->onValuePtr != NULL) {
	onValue = Tcl_GetString(mePtr->onValuePtr);
	if (strcmp(value, onValue) == 0) {
	    if (mePtr->entryFlags & ENTRY_SELECTED) {







|


|
|
<

<
>

|
<






<
<
<
<
<







<

|
<
|
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<










|







2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508

2509

2510
2511
2512

2513
2514
2515
2516
2517
2518





2519
2520
2521
2522
2523
2524
2525

2526
2527

2528
2529
2530


2531













2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
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;
    char *name;
    char *onValue;



    if (flags & TCL_INTERP_DESTROYED) {
	/*
	 * Do nothing if the interpreter is going away.

	 */

    	return NULL;
    }

    menuPtr = mePtr->menuPtr;





    name = Tcl_GetString(mePtr->namePtr);

    /*
     * If the variable is being unset, then re-establish the trace.
     */

    if (flags & TCL_TRACE_UNSETS) {

	mePtr->entryFlags &= ~ENTRY_SELECTED;
	if (flags & TCL_TRACE_DESTROYED) {

	    Tcl_TraceVar(interp, name,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MenuVarProc, clientData);


	}













	TkpConfigureMenuEntry(mePtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
	return NULL;
    }

    /*
     * Use the value of the variable to update the selected status of the menu
     * entry.
     */

    value = Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mePtr->onValuePtr != NULL) {
	onValue = Tcl_GetString(mePtr->onValuePtr);
	if (strcmp(value, onValue) == 0) {
	    if (mePtr->entryFlags & ENTRY_SELECTED) {
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
 *	may get posted and unposted.
 *
 *----------------------------------------------------------------------
 */

int
TkActivateMenuEntry(
    TkMenu *menuPtr,	/* Menu in which to activate. */
    TkSizeT index)			/* Index of entry to activate, or
				 * TCL_INDEX_NONE to deactivate all entries. */
{
    TkMenuEntry *mePtr;
    int result = TCL_OK;

    if (menuPtr->active != TCL_INDEX_NONE) {
	mePtr = menuPtr->entries[menuPtr->active];

	/*
	 * Don't change the state unless it's currently active (state might
	 * already have been changed to disabled).
	 */

	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	TkEventuallyRedrawMenu(menuPtr, menuPtr->entries[menuPtr->active]);
    }
    menuPtr->active = index;
    if (index != TCL_INDEX_NONE) {
	mePtr = menuPtr->entries[index];
	mePtr->state = ENTRY_ACTIVE;
	TkEventuallyRedrawMenu(menuPtr, mePtr);
    }
    return result;
}








|
|
|

|


|













|







2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
 *	may get posted and unposted.
 *
 *----------------------------------------------------------------------
 */

int
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;

    if (menuPtr->active >= 0) {
	mePtr = menuPtr->entries[menuPtr->active];

	/*
	 * Don't change the state unless it's currently active (state might
	 * already have been changed to disabled).
	 */

	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	TkEventuallyRedrawMenu(menuPtr, menuPtr->entries[menuPtr->active]);
    }
    menuPtr->active = index;
    if (index >= 0) {
	mePtr = menuPtr->entries[index];
	mePtr->state = ENTRY_ACTIVE;
	TkEventuallyRedrawMenu(menuPtr, mePtr);
    }
    return result;
}

2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
{
    int returnResult;
    int menuType, i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
		menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    menuDupCommandArray[0] = Tcl_NewStringObj("tk::MenuDup", -1);
    menuDupCommandArray[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
    menuDupCommandArray[2] = newMenuNamePtr;
    if (newMenuTypePtr == NULL) {
	menuDupCommandArray[3] = Tcl_NewStringObj("normal", -1);
    } else {
	menuDupCommandArray[3] = newMenuTypePtr;
    }
    for (i = 0; i < 4; i++) {
	Tcl_IncrRefCount(menuDupCommandArray[i]);
    }
    Tcl_Preserve(menuPtr);
    returnResult = Tcl_EvalObjv(menuPtr->interp, 4, menuDupCommandArray, 0);
    for (i = 0; i < 4; i++) {
	Tcl_DecrRefCount(menuDupCommandArray[i]);
    }

    /*
     * Make sure the tcl command actually created the clone.
     */

    if ((returnResult == TCL_OK) &&
	    ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
	    newMenuNamePtr)) != NULL)
	    && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
	TkMenu *newMenuPtr = menuRefPtr->menuPtr;
	Tcl_Obj *newObjv[3];
	int numElements;

	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = menuPtr->mainMenuPtr;
	} else {
	    TkMenu *mainMenuPtr;

	    mainMenuPtr = menuPtr->mainMenuPtr;
	    newMenuPtr->nextInstancePtr = mainMenuPtr->nextInstancePtr;
	    mainMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = mainMenuPtr;
	}

	/*
	 * Add the main 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);
	Tcl_IncrRefCount(newObjv[0]);
	Tcl_IncrRefCount(newObjv[1]);
	if (Tk_BindtagsObjCmd(newMenuPtr->tkwin, newMenuPtr->interp, 2,
		newObjv) == TCL_OK) {
	    const char *windowName;
	    Tcl_Obj *bindingsPtr =
		    Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp));
	    Tcl_Obj *elementPtr;

	    Tcl_IncrRefCount(bindingsPtr);
	    Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		windowName = Tcl_GetString(elementPtr);
		if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
			== 0) {
		    Tcl_Obj *newElementPtr = Tcl_NewStringObj(
			    Tk_PathName(newMenuPtr->mainMenuPtr->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);
		    newObjv[2] = bindingsPtr;
		    Tk_BindtagsObjCmd(newMenuPtr->tkwin, menuPtr->interp, 3,
			    newObjv);
		    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 < (int)menuPtr->numEntries; i++) {
	    TkMenuReferences *cascadeRefPtr;
	    TkMenu *oldCascadePtr;

	    if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
		&& (menuPtr->entries[i]->namePtr != NULL)) {
		cascadeRefPtr =
			TkFindMenuReferencesObj(menuPtr->interp,







|

|
|















|















|








|

|

|
|
|
|



|









|
|
|













|









|
|













|







2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
{
    int returnResult;
    int menuType, i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MASTER_MENU;
    } else {
	if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr,
		menuTypeStrings, "menu type", 0, &menuType) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    menuDupCommandArray[0] = Tcl_NewStringObj("tk::MenuDup", -1);
    menuDupCommandArray[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
    menuDupCommandArray[2] = newMenuNamePtr;
    if (newMenuTypePtr == NULL) {
	menuDupCommandArray[3] = Tcl_NewStringObj("normal", -1);
    } else {
	menuDupCommandArray[3] = newMenuTypePtr;
    }
    for (i = 0; i < 4; i++) {
	Tcl_IncrRefCount(menuDupCommandArray[i]);
    }
    Tcl_Preserve((ClientData) menuPtr);
    returnResult = Tcl_EvalObjv(menuPtr->interp, 4, menuDupCommandArray, 0);
    for (i = 0; i < 4; i++) {
	Tcl_DecrRefCount(menuDupCommandArray[i]);
    }

    /*
     * Make sure the tcl command actually created the clone.
     */

    if ((returnResult == TCL_OK) &&
	    ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
	    newMenuNamePtr)) != NULL)
	    && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
	TkMenu *newMenuPtr = menuRefPtr->menuPtr;
	Tcl_Obj *newObjv[3];
	int i, numElements;

	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    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.
	 */

	newObjv[0] = Tcl_NewStringObj("bindtags", -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 =
		    Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp));
	    Tcl_Obj *elementPtr;

	    Tcl_IncrRefCount(bindingsPtr);
	    Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		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);
		    newObjv[2] = bindingsPtr;
		    Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin,
			    menuPtr->interp, 3, newObjv);
		    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)
		&& (menuPtr->entries[i]->namePtr != NULL)) {
		cascadeRefPtr =
			TkFindMenuReferencesObj(menuPtr->interp,
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
	    }
	}

	returnResult = TCL_OK;
    } else {
	returnResult = TCL_ERROR;
    }
    Tcl_Release(menuPtr);
    return returnResult;
}

/*
 *----------------------------------------------------------------------
 *
 * MenuDoXPosition --







|







2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
	    }
	}

	returnResult = TCL_OK;
    } else {
	returnResult = TCL_ERROR;
    }
    Tcl_Release((ClientData) menuPtr);
    return returnResult;
}

/*
 *----------------------------------------------------------------------
 *
 * MenuDoXPosition --
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888

static int
MenuDoXPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->x));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|


|



|
|

|







2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880

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;
}

/*
 *----------------------------------------------------------------------
 *
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;

  error:
    return TCL_ERROR;
}







|


|



|
|

|







2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    int index;

    TkRecomputeMenu(menuPtr);
    if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;

  error:
    return TCL_ERROR;
}
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
GetIndexFromCoords(
    Tcl_Interp *interp,		/* Interpreter of menu. */
    TkMenu *menuPtr,		/* The menu we are searching. */
    const char *string,		/* The @string we are parsing. */
    TkSizeT *indexPtr)		/* The index of the item that matches. */
{
    int x, y, i;
    const char *p;
    char *end;
    int x2, borderwidth, max;

    TkRecomputeMenu(menuPtr);
    p = string + 1;
    y = strtol(p, &end, 0);
    if (end == p) {
	goto error;







|



|
|


<
|







2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945

2946
2947
2948
2949
2950
2951
2952
2953
 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static int
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;
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
	}
    } else {
	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 < (int)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 < x2)
		&& (y < (menuPtr->entries[i]->y
		+ menuPtr->entries[i]->height))) {
	    *indexPtr = i;
	    break;
	}
    }
    return TCL_OK;

  error:
    Tcl_ResetResult(interp);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * RecursivelyDeleteMenu --







|


|



|
















|







2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
	}
    } else {
	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 < x2)
		&& (y < (menuPtr->entries[i]->y
		+ menuPtr->entries[i]->height))) {
	    *indexPtr = i;
	    break;
	}
    }
    return TCL_OK;

  error:
    Tcl_SetResult(interp, NULL, TCL_STATIC);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * RecursivelyDeleteMenu --
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
 *----------------------------------------------------------------------
 */

static void
RecursivelyDeleteMenu(
    TkMenu *menuPtr)		/* The menubar instance we are deleting. */
{
    TkSizeT 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.
     */








|







3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
 *----------------------------------------------------------------------
 */

static void
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.
     */

3075
3076
3077
3078
3079
3080
3081

3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
{
    Tcl_Obj *resultPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */
    Tcl_Obj *childPtr;
    char *destString;
    int i;
    int doDot;

    Tcl_HashTable *nameTablePtr = NULL;
    TkWindow *winPtr = (TkWindow *) menuPtr->tkwin;
    const char *parentName = Tcl_GetString(parentPtr);

    if (winPtr->mainPtr != NULL) {
	nameTablePtr = &(winPtr->mainPtr->nameTable);
    }

    doDot = parentName[strlen(parentName) - 1] != '.';








>


|







3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
{
    Tcl_Obj *resultPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */
    Tcl_Obj *childPtr;
    char *destString;
    int i;
    int doDot;
    Tcl_CmdInfo cmdInfo;
    Tcl_HashTable *nameTablePtr = NULL;
    TkWindow *winPtr = (TkWindow *) menuPtr->tkwin;
    char *parentName = Tcl_GetString(parentPtr);

    if (winPtr->mainPtr != NULL) {
	nameTablePtr = &(winPtr->mainPtr->nameTable);
    }

    doDot = parentName[strlen(parentName) - 1] != '.';

3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128

	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewWideIntObj(i);
	    Tcl_AppendObjToObj(resultPtr, intPtr);
	    Tcl_DecrRefCount(intPtr);
    	}
	destString = Tcl_GetString(resultPtr);
    	if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL)
		&& ((nameTablePtr == NULL)
		|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
    	    break;
    	}
    }
    Tcl_DecrRefCount(childPtr);
    return resultPtr;







|




|







3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120

	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewIntObj(i);
	    Tcl_AppendObjToObj(resultPtr, intPtr);
	    Tcl_DecrRefCount(intPtr);
    	}
	destString = Tcl_GetString(resultPtr);
    	if ((Tcl_GetCommandInfo(interp, destString, &cmdInfo) == 0)
		&& ((nameTablePtr == NULL)
		|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
    	    break;
    	}
    }
    Tcl_DecrRefCount(childPtr);
    return resultPtr;
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
 *----------------------------------------------------------------------
 */

void
TkSetWindowMenuBar(
    Tcl_Interp *interp,		/* The interpreter the toplevel lives in. */
    Tk_Window tkwin,		/* The toplevel window. */
    const char *oldMenuName, /* The name of the menubar previously set in
    				 * this toplevel. NULL means no menu was set
    				 * previously. */
    const 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;








|


|







3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
 *----------------------------------------------------------------------
 */

void
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;

3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
	     */

	    if (menuRefPtr->menuPtr != NULL) {
		TkMenu *instancePtr;

		menuPtr = menuRefPtr->menuPtr;

		for (instancePtr = menuPtr->mainMenuPtr;
			instancePtr != NULL;
			instancePtr = instancePtr->nextInstancePtr) {
		    if (instancePtr->menuType == MENUBAR
			    && instancePtr->parentTopLevelPtr == tkwin) {
			RecursivelyDeleteMenu(instancePtr);
			break;
		    }







|







3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
	     */

	    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;
		    }
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
	    if (topLevelListPtr != NULL) {
		if (prevTopLevelPtr == NULL) {
		    menuRefPtr->topLevelListPtr =
			    menuRefPtr->topLevelListPtr->nextPtr;
		} else {
		    prevTopLevelPtr->nextPtr = topLevelListPtr->nextPtr;
		}
		ckfree(topLevelListPtr);
		TkFreeMenuReferences(menuRefPtr);
	    }
	}
    }

    /*
     * Now, add the clone references for the new menu.







|







3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
	    if (topLevelListPtr != NULL) {
		if (prevTopLevelPtr == NULL) {
		    menuRefPtr->topLevelListPtr =
			    menuRefPtr->topLevelListPtr->nextPtr;
		} else {
		    prevTopLevelPtr->nextPtr = topLevelListPtr->nextPtr;
		}
		ckfree((char *) topLevelListPtr);
		TkFreeMenuReferences(menuRefPtr);
	    }
	}
    }

    /*
     * Now, add the clone references for the new menu.
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
	    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;
		newObjv[0] = cursorPtr;
		newObjv[1] = nullPtr;
		Tcl_IncrRefCount(cursorPtr);
		Tcl_IncrRefCount(nullPtr);
		ConfigureMenu(menuPtr->interp, cloneMenuRefPtr->menuPtr,







<







3244
3245
3246
3247
3248
3249
3250

3251
3252
3253
3254
3255
3256
3257
	    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;
		newObjv[0] = cursorPtr;
		newObjv[1] = nullPtr;
		Tcl_IncrRefCount(cursorPtr);
		Tcl_IncrRefCount(nullPtr);
		ConfigureMenu(menuPtr->interp, cloneMenuRefPtr->menuPtr,
3278
3279
3280
3281
3282
3283
3284
3285

3286
3287
3288
3289
3290
3291
3292
	}

	/*
	 * Add this window to the menu's list of windows that refer to this
	 * menu.
	 */

	topLevelListPtr = (TkMenuTopLevelList *)ckalloc(sizeof(TkMenuTopLevelList));

	topLevelListPtr->tkwin = tkwin;
	topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
	menuRefPtr->topLevelListPtr = topLevelListPtr;
    } else {
	TkpSetWindowMenuBar(tkwin, NULL);
    }
    TkpSetMainMenubar(interp, tkwin, menuName);







|
>







3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
	}

	/*
	 * Add this window to the menu's list of windows that refer to this
	 * menu.
	 */

	topLevelListPtr = (TkMenuTopLevelList *)
		ckalloc(sizeof(TkMenuTopLevelList));
	topLevelListPtr->tkwin = tkwin;
	topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
	menuRefPtr->topLevelListPtr = topLevelListPtr;
    } else {
	TkpSetWindowMenuBar(tkwin, NULL);
    }
    TkpSetMainMenubar(interp, tkwin, menuName);
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuHashTable(
    ClientData clientData,	/* The menu hash table we are destroying. */
    Tcl_Interp *dummy)		/* The interpreter we are destroying. */
{
    (void)dummy;

    Tcl_DeleteHashTable((Tcl_HashTable *)clientData);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetMenuHashTable --
 *







|

<
<
|
|







3300
3301
3302
3303
3304
3305
3306
3307
3308


3309
3310
3311
3312
3313
3314
3315
3316
3317
 *
 *----------------------------------------------------------------------
 */

static void
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);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetMenuHashTable --
 *
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347


3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
 *----------------------------------------------------------------------
 */

Tcl_HashTable *
TkGetMenuHashTable(
    Tcl_Interp *interp)		/* The interp we need the hash table in.*/
{
    Tcl_HashTable *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);
	Tcl_SetAssocData(interp, MENU_HASH_KEY, DestroyMenuHashTable,
		menuTablePtr);
    }
    return menuTablePtr;
}

/*
 *----------------------------------------------------------------------
 *







|
<

>
>

|


|







3328
3329
3330
3331
3332
3333
3334
3335

3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
 *----------------------------------------------------------------------
 */

Tcl_HashTable *
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);
    if (menuTablePtr == NULL) {
	menuTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(menuTablePtr, TCL_STRING_KEYS);
	Tcl_SetAssocData(interp, MENU_HASH_KEY, DestroyMenuHashTable,
		(ClientData) menuTablePtr);
    }
    return menuTablePtr;
}

/*
 *----------------------------------------------------------------------
 *
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
 *
 *----------------------------------------------------------------------
 */

TkMenuReferences *
TkCreateMenuReferences(
    Tcl_Interp *interp,
    const char *pathName)		/* The path of the menu widget. */
{
    Tcl_HashEntry *hashEntryPtr;
    TkMenuReferences *menuRefPtr;
    int newEntry;
    Tcl_HashTable *menuTablePtr = TkGetMenuHashTable(interp);

    hashEntryPtr = Tcl_CreateHashEntry(menuTablePtr, pathName, &newEntry);
    if (newEntry) {
    	menuRefPtr = (TkMenuReferences *)ckalloc(sizeof(TkMenuReferences));
    	menuRefPtr->menuPtr = NULL;
    	menuRefPtr->topLevelListPtr = NULL;
    	menuRefPtr->parentEntryPtr = NULL;
    	menuRefPtr->hashEntryPtr = hashEntryPtr;
    	Tcl_SetHashValue(hashEntryPtr, menuRefPtr);
    } else {
    	menuRefPtr = (TkMenuReferences *)Tcl_GetHashValue(hashEntryPtr);
    }
    return menuRefPtr;
}

/*
 *----------------------------------------------------------------------
 *







|








|




|

|







3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
 *
 *----------------------------------------------------------------------
 */

TkMenuReferences *
TkCreateMenuReferences(
    Tcl_Interp *interp,
    char *pathName)		/* The path of the menu widget. */
{
    Tcl_HashEntry *hashEntryPtr;
    TkMenuReferences *menuRefPtr;
    int newEntry;
    Tcl_HashTable *menuTablePtr = TkGetMenuHashTable(interp);

    hashEntryPtr = Tcl_CreateHashEntry(menuTablePtr, pathName, &newEntry);
    if (newEntry) {
    	menuRefPtr = (TkMenuReferences *) ckalloc(sizeof(TkMenuReferences));
    	menuRefPtr->menuPtr = NULL;
    	menuRefPtr->topLevelListPtr = NULL;
    	menuRefPtr->parentEntryPtr = NULL;
    	menuRefPtr->hashEntryPtr = hashEntryPtr;
    	Tcl_SetHashValue(hashEntryPtr, (char *) menuRefPtr);
    } else {
    	menuRefPtr = (TkMenuReferences *) Tcl_GetHashValue(hashEntryPtr);
    }
    return menuRefPtr;
}

/*
 *----------------------------------------------------------------------
 *
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
 *
 *----------------------------------------------------------------------
 */

TkMenuReferences *
TkFindMenuReferences(
    Tcl_Interp *interp,		/* The interp the menu is living in. */
    const char *pathName)	/* The path of the menu widget. */
{
    Tcl_HashEntry *hashEntryPtr;
    TkMenuReferences *menuRefPtr = NULL;
    Tcl_HashTable *menuTablePtr;

    menuTablePtr = TkGetMenuHashTable(interp);
    hashEntryPtr = Tcl_FindHashEntry(menuTablePtr, pathName);
    if (hashEntryPtr != NULL) {
    	menuRefPtr = (TkMenuReferences *)Tcl_GetHashValue(hashEntryPtr);
    }
    return menuRefPtr;
}

/*
 *----------------------------------------------------------------------
 *







|








|







3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
 *
 *----------------------------------------------------------------------
 */

TkMenuReferences *
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;
    Tcl_HashTable *menuTablePtr;

    menuTablePtr = TkGetMenuHashTable(interp);
    hashEntryPtr = Tcl_FindHashEntry(menuTablePtr, pathName);
    if (hashEntryPtr != NULL) {
    	menuRefPtr = (TkMenuReferences *) Tcl_GetHashValue(hashEntryPtr);
    }
    return menuRefPtr;
}

/*
 *----------------------------------------------------------------------
 *
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
 */

TkMenuReferences *
TkFindMenuReferencesObj(
    Tcl_Interp *interp,		/* The interp the menu is living in. */
    Tcl_Obj *objPtr)		/* The path of the menu widget. */
{
    const char *pathName = Tcl_GetString(objPtr);

    return TkFindMenuReferences(interp, pathName);
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeMenuReferences --







|
<







3448
3449
3450
3451
3452
3453
3454
3455

3456
3457
3458
3459
3460
3461
3462
 */

TkMenuReferences *
TkFindMenuReferencesObj(
    Tcl_Interp *interp,		/* The interp the menu is living in. */
    Tcl_Obj *objPtr)		/* The path of the menu widget. */
{
    char *pathName = Tcl_GetString(objPtr);

    return TkFindMenuReferences(interp, pathName);
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeMenuReferences --
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
    TkMenuReferences *menuRefPtr)
				/* The menu reference to free. */
{
    if ((menuRefPtr->menuPtr == NULL)
    	    && (menuRefPtr->parentEntryPtr == NULL)
    	    && (menuRefPtr->topLevelListPtr == NULL)) {
    	Tcl_DeleteHashEntry(menuRefPtr->hashEntryPtr);
    	ckfree(menuRefPtr);
	return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------







|







3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
    TkMenuReferences *menuRefPtr)
				/* The menu reference to free. */
{
    if ((menuRefPtr->menuPtr == NULL)
    	    && (menuRefPtr->parentEntryPtr == NULL)
    	    && (menuRefPtr->topLevelListPtr == NULL)) {
    	Tcl_DeleteHashEntry(menuRefPtr->hashEntryPtr);
    	ckfree((char *) menuRefPtr);
	return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532

3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {

	    Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
	}
	for (i = last + 1; i < (int)menuListPtr->numEntries; i++) {
	    j = i - numDeleted;
	    menuListPtr->entries[j] = menuListPtr->entries[i];
	    menuListPtr->entries[j]->index = j;
	}
	menuListPtr->numEntries -= numDeleted;
	if (menuListPtr->numEntries == 0) {
	    ckfree(menuListPtr->entries);
	    menuListPtr->entries = NULL;
	}
	if (((int)menuListPtr->active >= first)
		&& ((int)menuListPtr->active <= last)) {
	    menuListPtr->active = -1;
	} else if ((int)menuListPtr->active > last) {
	    menuListPtr->active -= numDeleted;
	}
	TkEventuallyRecomputeMenu(menuListPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCleanup --
 *
 *	Resets menusInitialized to allow Tk to be finalized and reused without
 *	the DLL being unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCleanup(
    ClientData dummy)
{
    (void)dummy;

    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --







|


>
|

|






|


|
|

|









|














|
|

<
<







3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566


3567
3568
3569
3570
3571
3572
3573
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree((ClientData) menuListPtr->entries[i],
		    DestroyMenuEntry);
	}
	for (i = last + 1; i < menuListPtr->numEntries; i++) {
	    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)
		&& (menuListPtr->active <= last)) {
	    menuListPtr->active = -1;
	} else if (menuListPtr->active > last) {
	    menuListPtr->active -= numDeleted;
	}
	TkEventuallyRecomputeMenu(menuListPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
	    menusInitialized = 1;
	}

	/*
	 * Make sure we cleanup on finalize.
	 */

	TkCreateExitHandler((Tcl_ExitProc *) MenuCleanup, NULL);
	Tcl_MutexUnlock(&menuMutex);
    }
    if (!tsdPtr->menusInitialized) {
	TkpMenuThreadInit();
	tsdPtr->menuOptionTable =
		Tk_CreateOptionTable(NULL, tkMenuConfigSpecs);
	tsdPtr->entryOptionTables[TEAROFF_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[TEAROFF_ENTRY]);
	tsdPtr->entryOptionTables[COMMAND_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[COMMAND_ENTRY]);
	tsdPtr->entryOptionTables[CASCADE_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[CASCADE_ENTRY]);
	tsdPtr->entryOptionTables[SEPARATOR_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[SEPARATOR_ENTRY]);
	tsdPtr->entryOptionTables[RADIO_BUTTON_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[RADIO_BUTTON_ENTRY]);
	tsdPtr->entryOptionTables[CHECK_BUTTON_ENTRY] =
		Tk_CreateOptionTable(NULL, specsArray[CHECK_BUTTON_ENTRY]);
	tsdPtr->menusInitialized = 1;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




<
<
<
<
<
<
<
<
<
<
<
<
<
<











3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608














3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
	    menusInitialized = 1;
	}

	/*
	 * Make sure we cleanup on finalize.
	 */

	TkCreateExitHandler((Tcl_ExitProc *) TkMenuCleanup, NULL);
	Tcl_MutexUnlock(&menuMutex);
    }
    if (!tsdPtr->menusInitialized) {
	TkpMenuThreadInit();














	tsdPtr->menusInitialized = 1;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkMenu.h.

8
9
10
11
12
13
14




15
16
17
18
19
20
21
22





23
24
25
26
27
28
29
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENU
#define _TKMENU





#ifndef _TKINT
#include "tkInt.h"
#endif

#ifndef _DEFAULT
#include "default.h"
#endif






/*
 * Dummy types used by the platform menu code.
 */

typedef struct TkMenuPlatformData_ *TkMenuPlatformData;
typedef struct TkMenuPlatformEntryData_ *TkMenuPlatformEntryData;







>
>
>
>








>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENU
#define _TKMENU

#ifndef _TK
#include "tk.h"
#endif

#ifndef _TKINT
#include "tkInt.h"
#endif

#ifndef _DEFAULT
#include "default.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Dummy types used by the platform menu code.
 */

typedef struct TkMenuPlatformData_ *TkMenuPlatformData;
typedef struct TkMenuPlatformEntryData_ *TkMenuPlatformEntryData;
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    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). */
    TkSizeT labelLength;	/* Number of non-NULL characters in label. */
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (-1 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or NULL.
				 * If not NULL then label is 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
				 * 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. */
    TkSizeT accelLength;	/* Number of non-NULL characters in
				 * accelerator. */
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */







|



|
















|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    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). */
    int labelLength;		/* Number of non-NULL characters in label. */
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (<0 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or NULL.
				 * If not NULL then label is 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
				 * 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. */
    int accelLength;		/* Number of non-NULL characters in
				 * accelerator. */
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
				 * 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 accommodate a standard check mark
    				 * and a default right margin. If this is 1,
    				 * then the item has no such margins, and
    				 * checkbuttons and radiobuttons with this set
    				 * will have a rectangle drawn in the
    				 * indicator around the item if the item is
    				 * checked. This is useful for palette menus.
    				 * This field is ignored for separators and







|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
				 * 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
    				 * 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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    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 main 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.*/







|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    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.*/
239
240
241
242
243
244
245


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#define SEPARATOR_ENTRY 4
#define TEAROFF_ENTRY 5

/*
 * Menu states
 */



#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:
 */

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
				 * 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. */
    TkSizeT numEntries;		/* Number of elements in entries. */
    TkSizeT active;			/* Index of active entry. TCL_INDEX_NONE means
				 * nothing active. */
    int menuType;		/* MAIN_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:







>
>




















|
|
|
|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#define SEPARATOR_ENTRY 4
#define TEAROFF_ENTRY 5

/*
 * Menu states
 */

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:
 */

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
				 * 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. */
    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" */

    /*
     * Information used when displaying widget:
347
348
349
350
351
352
353
354
355
356
357



358
359
360
361
362
363
364
365
				 * definition. */
    TkMenuEntry *postedCascade;	/* Points to menu entry for cascaded submenu
				 * that is currently posted or NULL if no
				 * submenu posted. */
    struct TkMenu *nextInstancePtr;
    				/* The next instance of this menu in the
    				 * chain. */
    struct TkMenu *mainMenuPtr;
    				/* A pointer to the original menu for this
    				 * clone chain. Points back to this structure
    				 * if this menu is a main menu. */



    void *reserved1; /* not used any more. */
    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;
    				/* 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







|


|
>
>
>
|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
				 * definition. */
    TkMenuEntry *postedCascade;	/* Points to menu entry for cascaded submenu
				 * that is currently posted or NULL if no
				 * submenu posted. */
    struct TkMenu *nextInstancePtr;
    				/* The next instance of this menu in the
    				 * chain. */
    struct TkMenu *masterMenuPtr;
    				/* A pointer to the original menu for this
    				 * clone chain. Points back to this structure
    				 * if this menu is a master menu. */
    struct TkMenuOptionTables *optionTablesPtr;
				/* A pointer to the collection of option
				 * tables that work with menus and menu
				 * entries. */
    Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the
    				 * toplevel that owns the menu. Only
    				 * applicable for menubar clones. */
    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
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */
} 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.
 */







<







388
389
390
391
392
393
394

395
396
397
398
399
400
401
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */

} TkMenu;

/*
 * 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.
 */
420
421
422
423
424
425
426











427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493


494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
    				 * 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. */
} TkMenuReferences;












/*
 * Flag bits for menus:
 *
 * 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 main 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_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 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 MAIN_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 main 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 MAIN_MENU 		0
#define TEAROFF_MENU 		1
#define MENUBAR 		2

/*
 * Various geometry definitions:
 */

#define CASCADE_ARROW_HEIGHT	10
#define CASCADE_ARROW_WIDTH	8
#define DECORATION_BORDER_WIDTH	2

/*
 * Menu-related functions that are shared among Tk modules but not exported to
 * the outside world:
 */

MODULE_SCOPE int	TkActivateMenuEntry(TkMenu *menuPtr, TkSizeT index);
MODULE_SCOPE void	TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr);
MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp,
			    const 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, const 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 void	TkMenuInitializeDrawingFields(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    TkSizeT index);
MODULE_SCOPE void	TkMenuConfigureDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE int	TkMenuConfigureEntryDrawOptions(
			    TkMenuEntry *mePtr, TkSizeT 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);
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.
 */







>
>
>
>
>
>
>
>
>
>
>










|

















|


|





|
















|


|




|




>
>



|


|

















|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    				 * 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. */
} TkMenuReferences;

/*
 * This structure contains all of the option tables that are needed by menus.
 */

typedef struct TkMenuOptionTables {
    Tk_OptionTable menuOptionTable;
				/* The option table for menus. */
    Tk_OptionTable entryOptionTables[6];
				/* The tables for menu entries. */
} TkMenuOptionTables;

/*
 * Flag bits for menus:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler 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 (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_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 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
 * 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
#define MENUBAR 		2

/*
 * Various geometry definitions:
 */

#define CASCADE_ARROW_HEIGHT	10
#define CASCADE_ARROW_WIDTH	8
#define DECORATION_BORDER_WIDTH	2

/*
 * Menu-related functions that are shared among Tk modules but not exported to
 * the outside world:
 */

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);
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.
 */
534
535
536
537
538
539
540
541
542
543
544
545



546
			    const Tk_FontMetrics *menuMetricsPtr, int x,
			    int y, int width, int height, int strictMotif,
			    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, int index);
MODULE_SCOPE int	TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
					   int x, int y, int index);
MODULE_SCOPE void	TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);




#endif /* _TKMENU */







|
<
<


>
>
>

560
561
562
563
564
565
566
567


568
569
570
571
572
573
			    const Tk_FontMetrics *menuMetricsPtr, int x,
			    int y, int width, int height, int strictMotif,
			    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 */

Changes to generic/tkMenuDraw.c.

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    TkSizeT index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;








|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    int index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

void
TkEventuallyRecomputeMenu(
    TkMenu *menuPtr)
{
    if (!(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkRecomputeMenu --







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

void
TkEventuallyRecomputeMenu(
    TkMenu *menuPtr)
{
    if (!(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkRecomputeMenu --
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
 */

void
TkRecomputeMenu(
    TkMenu *menuPtr)
{
    if (menuPtr->menuFlags & RESIZE_PENDING) {
	Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr);
	ComputeMenuGeometry(menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkEventuallyRedrawMenu --
 *
 *	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 handler is scheduled to do the redisplay, if there isn't
 *	one already scheduled.
 *
 *----------------------------------------------------------------------
 */

void
TkEventuallyRedrawMenu(
    TkMenu *menuPtr,	/* Information about menu to redraw. */
    TkMenuEntry *mePtr)/* Entry to redraw. NULL means redraw all the
				 * entries in the menu. */
{
    TkSizeT i;

    if (menuPtr->tkwin == NULL) {
	return;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {
	for (i = 0; i < menuPtr->numEntries; i++) {
	    menuPtr->entries[i]->entryFlags |= ENTRY_NEEDS_REDISPLAY;
	}
    }
    if (!Tk_IsMapped(menuPtr->tkwin)
	    || (menuPtr->menuFlags & REDRAW_PENDING)) {
	return;
    }
    Tcl_DoWhenIdle(DisplayMenu, menuPtr);
    menuPtr->menuFlags |= REDRAW_PENDING;
}

/*
 *--------------------------------------------------------------
 *
 * ComputeMenuGeometry --







|
|















|







|
|


|















|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
 */

void
TkRecomputeMenu(
    TkMenu *menuPtr)
{
    if (menuPtr->menuFlags & RESIZE_PENDING) {
	Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr);
	ComputeMenuGeometry((ClientData) menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkEventuallyRedrawMenu --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

void
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;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {
	for (i = 0; i < menuPtr->numEntries; i++) {
	    menuPtr->entries[i]->entryFlags |= ENTRY_NEEDS_REDISPLAY;
	}
    }
    if (!Tk_IsMapped(menuPtr->tkwin)
	    || (menuPtr->menuFlags & REDRAW_PENDING)) {
	return;
    }
    Tcl_DoWhenIdle(DisplayMenu, (ClientData) menuPtr);
    menuPtr->menuFlags |= REDRAW_PENDING;
}

/*
 *--------------------------------------------------------------
 *
 * ComputeMenuGeometry --
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    ClientData clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    if (menuPtr->menuType == MENUBAR) {
	TkpComputeMenubarGeometry(menuPtr);







|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    ClientData clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = (TkMenu *) clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    if (menuPtr->menuType == MENUBAR) {
	TkpComputeMenubarGeometry(menuPtr);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
    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. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if ((mePtr->entryFlags & ENTRY_SELECTED)
	    && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) {
	mePtr->menuPtr->menuFlags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayMenu --







|
<
<
<
<
<
<




|







582
583
584
585
586
587
588
589






590
591
592
593
594
595
596
597
598
599
600
601
    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;
	Tcl_DoWhenIdle(DisplayMenu, (ClientData) mePtr->menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayMenu --
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644


645
646
647
648
649
650
651
 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    ClientData clientData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    Tk_Window tkwin = menuPtr->tkwin;
    TkSizeT index;
    int strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;

    int relief;


    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);



    if (menuPtr->menuType == MENUBAR) {
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
		borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
		Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT);
    }








|
|
|
<
|





>











>
>







611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    ClientData clientData)	/* Information about widget. */
{
    register TkMenu *menuPtr = (TkMenu *) clientData;
    register TkMenuEntry *mePtr;
    register Tk_Window tkwin = menuPtr->tkwin;

    int index, strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;
    int activeBorderWidth;
    int relief;


    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
	    menuPtr->activeBorderWidthPtr, &activeBorderWidth);

    if (menuPtr->menuType == MENUBAR) {
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
		borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
		Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT);
    }

668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691



692
693
694
695
696
697
698
699
700
701

702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
	if (menuPtr->menuType != MENUBAR) {
	    if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) {
		continue;
	    }
	}
	mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;

	TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
		&menuMetrics, mePtr->x, mePtr->y, mePtr->width,
		mePtr->height, strictMotif, 1);

        if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {

            /*
             * Paint the area at the right of an entry in the last column.
             * This has zero width except after menu resizing.
             */

            Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,

                    mePtr->x + mePtr->width, mePtr->y,
                    Tk_Width(tkwin) - mePtr->x - mePtr->width - borderWidth,
                    mePtr->height, 0, TK_RELIEF_FLAT);
        }




	if ((index > 0) && (menuPtr->menuType != MENUBAR)
		&& mePtr->columnBreak) {

            /*
             * Paint the area under the last entry in a column.
             */

	    mePtr = menuPtr->entries[index - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
		mePtr->x, mePtr->y + mePtr->height, mePtr->width,

		Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,

		0, TK_RELIEF_FLAT);
	}
    }

    if (menuPtr->menuType != MENUBAR) {
	int x, y, height;

	if (menuPtr->numEntries == 0) {
	    x = y = borderWidth;
	    width = Tk_Width(tkwin) - 2 * borderWidth;
	    height = Tk_Height(tkwin) - 2 * borderWidth;
	} else {
	    mePtr = menuPtr->entries[menuPtr->numEntries - 1];

            /*
             * Paint the area under the last entry of the menu.
             */

	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
		border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,

		0, TK_RELIEF_FLAT);
	    x = mePtr->x + mePtr->width;
	    y = mePtr->y + mePtr->height;
	    width = Tk_Width(tkwin) - x - borderWidth;
	    height = Tk_Height(tkwin) - y - borderWidth;
	}

        /*
         * Paint the area at the bottom right of the last entry.
         * This has zero width except after menu resizing.
         */

	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,







|
|
<
|
|
|
<
<
<
<
|
<
>
|
<
<
|
|
>
>
>


<
<
<
<
<


|
>
|
>
|








|
|


<
<
<
<
<


|
>
|


|
|

<
<
<
<
<
<







664
665
666
667
668
669
670
671
672

673
674
675




676

677
678


679
680
681
682
683
684
685





686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704





705
706
707
708
709
710
711
712
713
714






715
716
717
718
719
720
721
	if (menuPtr->menuType != MENUBAR) {
	    if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) {
		continue;
	    }
	}
	mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;

	if (menuPtr->menuType == MENUBAR) {
	    width = mePtr->width;

	} else {
	    if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
		width = Tk_Width(menuPtr->tkwin) - mePtr->x




			- activeBorderWidth;

	    } else {
		width = mePtr->width + borderWidth;


	    }
	}
	TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
		&menuMetrics, mePtr->x, mePtr->y, width,
		mePtr->height, strictMotif, 1);
	if ((index > 0) && (menuPtr->menuType != MENUBAR)
		&& mePtr->columnBreak) {





	    mePtr = menuPtr->entries[index - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
		mePtr->x, mePtr->y + mePtr->height,
		mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height -
		activeBorderWidth, 0,
		TK_RELIEF_FLAT);
	}
    }

    if (menuPtr->menuType != MENUBAR) {
	int x, y, height;

	if (menuPtr->numEntries == 0) {
	    x = y = borderWidth;
	    width = Tk_Width(tkwin) - 2 * activeBorderWidth;
	    height = Tk_Height(tkwin) - 2 * activeBorderWidth;
	} else {
	    mePtr = menuPtr->entries[menuPtr->numEntries - 1];





	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
		border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height
		- activeBorderWidth, 0,
		TK_RELIEF_FLAT);
	    x = mePtr->x + mePtr->width;
	    y = mePtr->y + mePtr->height;
	    width = Tk_Width(tkwin) - x - activeBorderWidth;
	    height = Tk_Height(tkwin) - y - activeBorderWidth;
	}






	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,
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
 */

void
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, NULL);
    } else if (eventPtr->type == ConfigureNotify) {
	TkEventuallyRecomputeMenu(menuPtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ActivateNotify) {







|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
 */

void
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, NULL);
    } else if (eventPtr->type == ConfigureNotify) {
	TkEventuallyRecomputeMenu(menuPtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ActivateNotify) {
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
	}
	menuPtr->menuFlags |= MENU_WIN_DESTRUCTION_PENDING;
	if (menuPtr->widgetCmd != NULL) {
	    Tcl_DeleteCommandFromToken(menuPtr->interp, menuPtr->widgetCmd);
	    menuPtr->widgetCmd = NULL;
	}
	if (menuPtr->menuFlags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayMenu, menuPtr);
	    menuPtr->menuFlags &= ~REDRAW_PENDING;
	}
	if (menuPtr->menuFlags & RESIZE_PENDING) {
	    Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr);
	    menuPtr->menuFlags &= ~RESIZE_PENDING;
	}
	Tcl_EventuallyFree(menuPtr, TCL_DYNAMIC);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuImageProc --







|



|


|







768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
	}
	menuPtr->menuFlags |= MENU_WIN_DESTRUCTION_PENDING;
	if (menuPtr->widgetCmd != NULL) {
	    Tcl_DeleteCommandFromToken(menuPtr->interp, menuPtr->widgetCmd);
	    menuPtr->widgetCmd = NULL;
	}
	if (menuPtr->menuFlags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayMenu, (ClientData) menuPtr);
	    menuPtr->menuFlags &= ~REDRAW_PENDING;
	}
	if (menuPtr->menuFlags & RESIZE_PENDING) {
	    Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr);
	    menuPtr->menuFlags &= ~RESIZE_PENDING;
	}
	Tcl_EventuallyFree((ClientData) menuPtr, TCL_DYNAMIC);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuImageProc --
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
















872









































873
874
875
876
877
878
879
    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. */
{
    TkMenu *menuPtr = (TkMenu *)((TkMenuEntry *) clientData)->menuPtr;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkPostTearoffMenu --
 *

 *	Posts a tearoff menu on the screen. Adjusts the menu's position so
 *	that it fits on the screen, and maps and raises the menu.
 *
 * Results:
 *	Returns a standard Tcl Error.
 *
 * Side effects:
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
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 */
{
















    return TkpPostTearoffMenu(interp, menuPtr, x, y, -1);









































}

/*
 *--------------------------------------------------------------
 *
 * TkPostSubmenu --
 *







|
<
<
<
<
<
<



|








>
|
|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







806
807
808
809
810
811
812
813






814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
    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)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	Returns a standard Tcl Error.
 *
 * Side effects:
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
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;

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * 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.
     */

    Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
	&vRootWidth, &vRootHeight);
    vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
    if (x > vRootX + vRootWidth) {
	x = vRootX + vRootWidth;
    }
    if (x < vRootX) {
	x = vRootX;
    }
    vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
    if (y > vRootY + vRootHeight) {
	y = vRootY + vRootHeight;
    }
    if (y < vRootY) {
	y = vRootY;
    }
    Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
    if (!Tk_IsMapped(menuPtr->tkwin)) {
	Tk_MapWindow(menuPtr->tkwin);
    }
    TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkPostSubmenu --
 *
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
 *--------------------------------------------------------------
 */

int
TkPostSubmenu(
    Tcl_Interp *interp,		/* Used for invoking sub-commands and
				 * reporting errors. */
    TkMenu *menuPtr,	/* Information about menu as a whole. */
    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) {







|
|







922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
 *--------------------------------------------------------------
 */

int
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. */
{
    int result, x, y;
    Tcl_Obj *subary[4];

    if (mePtr == menuPtr->postedCascade) {
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	subary[0] = mePtr->namePtr;
	subary[1] = Tcl_NewStringObj("post", -1);
	subary[2] = Tcl_NewWideIntObj(x);
	subary[3] = Tcl_NewWideIntObj(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]);







|
|







981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	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]);

Changes to generic/tkMenubutton.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * 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"

/*
 * The structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

static const Tk_ClassProcs menubuttonClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TkMenuButtonWorldChanged,	/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 * 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[] = {







|
<
<
<
<
<
<
<
<
<
<
<







9
10
11
12
13
14
15
16











17
18
19
20
21
22
23
 *
 * 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 "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.
 */

static const char *const directionStrings[] = {
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

/*
 * Information used for parsing configuration specs:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_MENUBUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, activeBorder), 0,
	(ClientData) DEF_MENUBUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE,
	 offsetof(TkMenuButton, activeFg),
	 0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_MENUBUTTON_ANCHOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkMenuButton, normalBorder),
	0, DEF_MENUBUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_MENUBUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkMenuButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENUBUTTON_BORDER_WIDTH, TCL_INDEX_NONE,
	offsetof(TkMenuButton, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkMenuButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	DEF_MENUBUTTON_DIRECTION, TCL_INDEX_NONE, offsetof(TkMenuButton, direction),
	0, directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_MENUBUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENUBUTTON_FONT, TCL_INDEX_NONE, offsetof(TkMenuButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENUBUTTON_FG, TCL_INDEX_NONE, offsetof(TkMenuButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_MENUBUTTON_HEIGHT, TCL_INDEX_NONE, offsetof(TkMenuButton, heightString),
	0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_MENUBUTTON_HIGHLIGHT, TCL_INDEX_NONE,
	offsetof(TkMenuButton, highlightColorPtr),	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
	TCL_INDEX_NONE, offsetof(TkMenuButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, TCL_INDEX_NONE, offsetof(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, TCL_INDEX_NONE, offsetof(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, TCL_INDEX_NONE, offsetof(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, TCL_INDEX_NONE, offsetof(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, TCL_INDEX_NONE, offsetof(TkMenuButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, TCL_INDEX_NONE,
	offsetof(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, TCL_INDEX_NONE, offsetof(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, TCL_INDEX_NONE,
	offsetof(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_MENUBUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuButton, underline),
	 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, TCL_INDEX_NONE, offsetof(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, TCL_INDEX_NONE, offsetof(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * The following tables define the menubutton widget commands and map the
 * indexes into the string tables into a single enumerated type used to
 * dispatch the scale widget command.
 */

static const char *const commandNames[] = {
    "cget", "configure", NULL
};

enum command {
    COMMAND_CGET, COMMAND_CONFIGURE
};








|
|


|
|
|

|
|

|
|
|

|


|


|
|

|


|
|


|

|


|

|

|



|

|
|


|

|


|


|

|


|


|


|


|
|

|
|

|
|

|

|
|

|


|


|

|








|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

/*
 * Information used for parsing configuration specs:
 */

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},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, -1,
	 Tk_Offset(TkMenuButton, activeFg),
	 0, (ClientData) DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_MENUBUTTON_ANCHOR, -1,
	Tk_Offset(TkMenuButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, -1, Tk_Offset(TkMenuButton, normalBorder),
	0, (ClientData) DEF_MENUBUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, -1, Tk_Offset(TkMenuButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction),
	0, (ClientData) directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_MENUBUTTON_DISABLED_FG_MONO, 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},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkMenuButton, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_MENUBUTTON_HIGHLIGHT, -1,
	Tk_Offset(TkMenuButton, highlightColorPtr),	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
	-1, Tk_Offset(TkMenuButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, -1, Tk_Offset(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, -1, Tk_Offset(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, -1, Tk_Offset(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, -1, Tk_Offset(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, -1, Tk_Offset(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, -1, Tk_Offset(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 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},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, -1, Tk_Offset(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, -1,
	Tk_Offset(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_MENUBUTTON_UNDERLINE, -1, Tk_Offset(TkMenuButton, underline),
	 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, -1, Tk_Offset(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, -1, Tk_Offset(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, 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.
 */

static const char *commandNames[] = {
    "cget", "configure", NULL
};

enum command {
    COMMAND_CGET, COMMAND_CONFIGURE
};

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
     * Create the new window.
     */








|




|


<


|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    /*
     * Create the new window.
     */

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    Tk_SetClass(tkwin, "Menubutton");
    mbPtr = TkpCreateMenuButton(tkwin);

    Tk_SetClassProcs(tkwin, &menubuttonClass, mbPtr);

    /*
     * Initialize the data structure for the button.
     */

    mbPtr->tkwin = tkwin;
    mbPtr->display = Tk_Display(tkwin);
    mbPtr->interp = interp;
    mbPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, mbPtr,
	    MenuButtonCmdDeletedProc);
    mbPtr->optionTable = optionTable;
    mbPtr->menuName = NULL;
    mbPtr->text = NULL;
    mbPtr->underline = -1;
    mbPtr->textVarName = NULL;
    mbPtr->bitmap = None;
    mbPtr->imageString = NULL;







|






|


|
|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    Tk_SetClass(tkwin, "Menubutton");
    mbPtr = TkpCreateMenuButton(tkwin);

    Tk_SetClassProcs(tkwin, &tkpMenubuttonClass, (ClientData) mbPtr);

    /*
     * Initialize the data structure for the button.
     */

    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->optionTable = optionTable;
    mbPtr->menuName = NULL;
    mbPtr->text = NULL;
    mbPtr->underline = -1;
    mbPtr->textVarName = NULL;
    mbPtr->bitmap = None;
    mbPtr->imageString = NULL;
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    mbPtr->direction = DIRECTION_FLUSH;
    mbPtr->cursor = NULL;
    mbPtr->takeFocus = NULL;
    mbPtr->flags = 0;

    Tk_CreateEventHandler(mbPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MenuButtonEventProc, mbPtr);

    if (Tk_InitOptions(interp, mbPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(mbPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --







|

|









|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    mbPtr->direction = DIRECTION_FLUSH;
    mbPtr->cursor = NULL;
    mbPtr->takeFocus = NULL;
    mbPtr->flags = 0;

    Tk_CreateEventHandler(mbPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MenuButtonEventProc, (ClientData) mbPtr);

    if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(mbPtr->tkwin), -1);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
static int
MenuButtonWidgetObjCmd(
    ClientData clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    int result, index;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames,
	    sizeof(char *), "option", 0, &index);
    if (result != TCL_OK) {
	return result;
    }
    Tcl_Preserve(mbPtr);

    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, mbPtr,
		mbPtr->optionTable, objv[2], mbPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, mbPtr,
		    mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    mbPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    result = ConfigureMenuButton(interp, mbPtr, objc-2, objv+2);
	}
	break;
    }
    Tcl_Release(mbPtr);
    return result;

  error:
    Tcl_Release(mbPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMenuButton --







|




|


|
|



|








|



|
|
>




|




|
|
>





|



|







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
static int
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 ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0,
	    &index);
    if (result != TCL_OK) {
	return result;
    }
    Tcl_Preserve((ClientData) mbPtr);

    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, (char *) mbPtr,
		mbPtr->optionTable, objv[2], mbPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	} else {
	    Tcl_SetObjResult(interp, objPtr);
	}
	break;

    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 {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureMenuButton(interp, mbPtr, objc-2, objv+2);
	}
	break;
    }
    Tcl_Release((ClientData) mbPtr);
    return result;

  error:
    Tcl_Release((ClientData) mbPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMenuButton --
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
 *----------------------------------------------------------------------
 */

static void
DestroyMenuButton(
    char *memPtr)		/* Info about button widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *) memPtr;
    TkpDestroyMenuButton(mbPtr);

    if (mbPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayMenuButton, mbPtr);
    }

    /*
     * 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);
    if (mbPtr->textVarName != NULL) {
	Tcl_UntraceVar2(mbPtr->interp, mbPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, mbPtr);
    }
    if (mbPtr->image != NULL) {
	Tk_FreeImage(mbPtr->image);
    }
    if (mbPtr->normalTextGC != NULL) {
	Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC);
    }







|



|









|

|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
 *----------------------------------------------------------------------
 */

static void
DestroyMenuButton(
    char *memPtr)		/* Info about button widget. */
{
    register TkMenuButton *mbPtr = (TkMenuButton *) memPtr;
    TkpDestroyMenuButton(mbPtr);

    if (mbPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd);
    if (mbPtr->textVarName != NULL) {
	Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, (ClientData) mbPtr);
    }
    if (mbPtr->image != NULL) {
	Tk_FreeImage(mbPtr->image);
    }
    if (mbPtr->normalTextGC != NULL) {
	Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC);
    }
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
	Tk_FreeBitmap(mbPtr->display, mbPtr->gray);
    }
    if (mbPtr->textLayout != NULL) {
	Tk_FreeTextLayout(mbPtr->textLayout);
    }
    Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin);
    mbPtr->tkwin = NULL;
    Tcl_EventuallyFree(mbPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureMenuButton --
 *







|







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
	Tk_FreeBitmap(mbPtr->display, mbPtr->gray);
    }
    if (mbPtr->textLayout != NULL) {
	Tk_FreeTextLayout(mbPtr->textLayout);
    }
    Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin);
    mbPtr->tkwin = NULL;
    Tcl_EventuallyFree((ClientData) mbPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureMenuButton --
 *
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuButton(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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;
    int error;
    Tk_Image image;

    /*
     * Eliminate any existing trace on variables monitored by the menubutton.
     */

    if (mbPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, mbPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, 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.
     */

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, mbPtr,
		    mbPtr->optionTable, objc, objv,
		    mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|















|

|















|







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
 *
 *----------------------------------------------------------------------
 */

static int
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;
    int error;
    Tk_Image image;

    /*
     * Eliminate any existing trace on variables monitored by the menubutton.
     */

    if (mbPtr->textVarName != NULL) {
	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.
     */

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) mbPtr,
		    mbPtr->optionTable, objc, objv,
		    mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
	 * 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);

	    if (image == NULL) {
		return TCL_ERROR;
	    }
	} else {
	    image = NULL;
	}
	if (mbPtr->image != NULL) {







|
>







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
	 * 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,
		    (ClientData) mbPtr);
	    if (image == NULL) {
		return TCL_ERROR;
	    }
	} else {
	    image = NULL;
	}
	if (mbPtr->image != NULL) {
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
	/*
	 * If no image or -compound is used, display the value of a variable.
	 * Set up a trace to watch for any changes in it, create the variable
	 * if it doesn't exist, and fetch its current value.
	 */
	const char *value;

	value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
	if (value == NULL) {
	    Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (mbPtr->text != NULL) {
		ckfree(mbPtr->text);
	    }
	    mbPtr->text = (char *)ckalloc(strlen(value) + 1);
	    strcpy(mbPtr->text, value);
	}
	Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, mbPtr);
    }

    TkMenuButtonWorldChanged(mbPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|

|





|


|

|


|







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
	/*
	 * If no image or -compound is used, display the value of a variable.
	 * Set up a trace to watch for any changes in it, create the variable
	 * if it doesn't exist, and fetch its current value.
	 */
	const char *value;

	value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
	if (value == NULL) {
	    Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (mbPtr->text != NULL) {
		ckfree(mbPtr->text);
	    }
	    mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1));
	    strcpy(mbPtr->text, value);
	}
	Tcl_TraceVar(interp, mbPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, (ClientData) mbPtr);
    }

    TkMenuButtonWorldChanged((ClientData) mbPtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    }
    return TCL_OK;
}
671
672
673
674
675
676
677
678


679
680
681
682
683
684
685
void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = (TkMenuButton *)instanceData;



    gcValues.font = Tk_FontId(mbPtr->tkfont);
    gcValues.foreground = mbPtr->normalFg->pixel;
    gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel;

    /*
     * Note: GraphicsExpose events are disabled in GC's because they're used







|
>
>







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr;

    mbPtr = (TkMenuButton *) instanceData;

    gcValues.font = Tk_FontId(mbPtr->tkfont);
    gcValues.foreground = mbPtr->normalFg->pixel;
    gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel;

    /*
     * Note: GraphicsExpose events are disabled in GC's because they're used
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    TkpComputeMenuButtonGeometry(mbPtr);

    /*
     * Lastly, arrange for the button to be redisplayed.
     */

    if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *







|







737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
    TkpComputeMenuButtonGeometry(mbPtr);

    /*
     * Lastly, arrange for the button to be redisplayed.
     */

    if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
 */

static void
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.
	 */







|
<







765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
 */

static void
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.
	 */
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
	    }
	}
    }
    return;

  redraw:
    if ((mbPtr->tkwin != NULL) && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
	    }
	}
    }
    return;

  redraw:
    if ((mbPtr->tkwin != NULL) && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * 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.







|







823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *) clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * 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.
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
 * Side effects:
 *	The text displayed in the menu button will change to match the
 *	variable.
 *
 *--------------------------------------------------------------
 */


static char *
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. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    const char *value;
    size_t len;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && mbPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        mbPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuButtonTextVarProc, probe);
                if (probe == (ClientData)mbPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
                return NULL;
            }
	    Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
		    TCL_GLOBAL_ONLY);
	    Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MenuButtonTextVarProc, clientData);
	}
	return NULL;
    }

    value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mbPtr->text != NULL) {
	ckfree(mbPtr->text);
    }
    len = 1 + strlen(value);
    mbPtr->text = (char *)ckalloc(len);
    memcpy(mbPtr->text, value, len);
    TkpComputeMenuButtonGeometry(mbPtr);

    if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin)
	    && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







>








|

|
<
<







<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|






|






|
|





|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874


875
876
877
878
879
880
881


882


883
















884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
 * Side effects:
 *	The text displayed in the menu button will change to match the
 *	variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
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;
    unsigned len;



    /*
     * 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_SetVar(interp, mbPtr->textVarName, mbPtr->text,
















		    TCL_GLOBAL_ONLY);
	    Tcl_TraceVar(interp, mbPtr->textVarName,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MenuButtonTextVarProc, clientData);
	}
	return NULL;
    }

    value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mbPtr->text != NULL) {
	ckfree(mbPtr->text);
    }
    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)
	    && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
    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. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if (mbPtr->tkwin != NULL) {
	TkpComputeMenuButtonGeometry(mbPtr);
	if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	    mbPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
<
<
<
<
<
<




|












932
933
934
935
936
937
938
939






940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
    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;







    if (mbPtr->tkwin != NULL) {
	TkpComputeMenuButtonGeometry(mbPtr);
	if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
	    mbPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkMenubutton.h.

17
18
19
20
21
22
23





24
25
26
27
28
29
30
#include "tkInt.h"
#endif

#ifndef _TKMENU
#include "tkMenu.h"
#endif






/*
 * Legal values for the "orient" field of TkMenubutton records.
 */

enum direction {
    DIRECTION_ABOVE, DIRECTION_BELOW, DIRECTION_FLUSH,
    DIRECTION_LEFT, DIRECTION_RIGHT







>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "tkInt.h"
#endif

#ifndef _TKMENU
#include "tkMenu.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Legal values for the "orient" field of TkMenubutton records.
 */

enum direction {
    DIRECTION_ABOVE, DIRECTION_BELOW, DIRECTION_FLUSH,
    DIRECTION_LEFT, DIRECTION_RIGHT
199
200
201
202
203
204
205






206
207
208
209
210
211
212
213
214
215



216
 * which is displayed if the "-indicatoron" option is true. The units for
 * these options are 1/10 millimeters.
 */

#define INDICATOR_WIDTH		40
#define INDICATOR_HEIGHT	17







/*
 * Declaration of procedures used in the implementation of the button widget.
 */

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);




#endif /* _TKMENUBUTTON */







>
>
>
>
>
>










>
>
>

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 * which is displayed if the "-indicatoron" option is true. The units for
 * these options are 1/10 millimeters.
 */

#define INDICATOR_WIDTH		40
#define INDICATOR_HEIGHT	17

/*
 * Declaration of variables shared between the files in the button module.
 */

MODULE_SCOPE Tk_ClassProcs tkpMenubuttonClass;

/*
 * Declaration of procedures used in the implementation of the button widget.
 */

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

#endif /* _TKMENUBUTTON */

Changes to generic/tkMessage.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "tkInt.h"
#include "default.h"

/*
 * A data structure of the following type is kept for each message widget
 * managed by this file:
 */

typedef struct {







|
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "default.h"
#include "tkInt.h"

/*
 * A data structure of the following type is kept for each message widget
 * managed by this file:
 */

typedef struct {
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MESSAGE_ANCHOR,
	 TCL_INDEX_NONE, offsetof(Message, anchor), 0, 0, 0},
    {TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
	 TCL_INDEX_NONE, offsetof(Message, aspect), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_MESSAGE_BG_COLOR, TCL_INDEX_NONE, offsetof(Message, border), 0,
	 DEF_MESSAGE_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_MESSAGE_BORDER_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, TCL_INDEX_NONE, offsetof(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MESSAGE_FONT, TCL_INDEX_NONE, offsetof(Message, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, TCL_INDEX_NONE, offsetof(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Message, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, TCL_INDEX_NONE, offsetof(Message, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, offsetof(Message, padXPtr),
	 offsetof(Message, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, offsetof(Message, padYPtr),
	 offsetof(Message, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, TCL_INDEX_NONE, offsetof(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Message, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MESSAGE_TEXT, TCL_INDEX_NONE, offsetof(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Message, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_MESSAGE_WIDTH, TCL_INDEX_NONE, offsetof(Message, width), 0, 0 ,0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

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(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    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(void *memPtr);
static void		DisplayMessage(ClientData clientData);

/*
 * The structure below defines message class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs messageClass = {
    sizeof(Tk_ClassProcs),	/* size */
    MessageWorldChanged,	/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_MessageObjCmd --
 *







|

|

|
|

|

|

|
|

|


|

|

|

|
|

|


|
|

|

|
|

|
|

|

|


|

|


|
|










|
|


|



|
|







|


<
<







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193


194
195
196
197
198
199
200

/*
 * Information used for argv parsing.
 */

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,
	 -1, Tk_Offset(Message, aspect), 0, 0, 0},
    {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", 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_MESSAGE_BORDER_WIDTH, -1,
	 Tk_Offset(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, -1, Tk_Offset(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {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},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, -1, Tk_Offset(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, -1,
	 Tk_Offset(Message, highlightBgColorPtr), 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, -1, Tk_Offset(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, -1, Tk_Offset(Message, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, Tk_Offset(Message, padXPtr),
	 Tk_Offset(Message, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, Tk_Offset(Message, padYPtr),
	 Tk_Offset(Message, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, -1, Tk_Offset(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, -1, Tk_Offset(Message, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MESSAGE_TEXT, -1, Tk_Offset(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, -1, Tk_Offset(Message, textVarName),
	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, NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

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(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    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 functions
 * that can be invoked from generic window code.
 */

static Tk_ClassProcs messageClass = {
    sizeof(Tk_ClassProcs),	/* size */
    MessageWorldChanged,	/* worldChangedProc */


};

/*
 *--------------------------------------------------------------
 *
 * Tk_MessageObjCmd --
 *
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    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.
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    msgPtr = (Message *)ckalloc(sizeof(Message));
    memset(msgPtr, 0, sizeof(Message));

    /*
     * 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,
	    Tk_PathName(msgPtr->tkwin), MessageWidgetObjCmd, msgPtr,
	    MessageCmdDeletedProc);
    msgPtr->optionTable = optionTable;
    msgPtr->relief = TK_RELIEF_FLAT;
    msgPtr->textGC = NULL;
    msgPtr->anchor = TK_ANCHOR_CENTER;
    msgPtr->aspect = 150;
    msgPtr->justify = TK_JUSTIFY_LEFT;
    msgPtr->cursor = NULL;

    Tk_SetClass(msgPtr->tkwin, "Message");
    Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr);
    Tk_CreateEventHandler(msgPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MessageEventProc, msgPtr);
    if (Tk_InitOptions(interp, msgPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(msgPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --







|


|

|


<


|
















|
|









|
|









|


|
|









|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    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.
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    msgPtr = (Message *) ckalloc(sizeof(Message));
    memset(msgPtr, 0, (size_t) sizeof(Message));

    /*
     * 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,
	    Tk_PathName(msgPtr->tkwin), MessageWidgetObjCmd,
	    (ClientData) msgPtr, MessageCmdDeletedProc);
    msgPtr->optionTable = optionTable;
    msgPtr->relief = TK_RELIEF_FLAT;
    msgPtr->textGC = NULL;
    msgPtr->anchor = TK_ANCHOR_CENTER;
    msgPtr->aspect = 150;
    msgPtr->justify = TK_JUSTIFY_LEFT;
    msgPtr->cursor = NULL;

    Tk_SetClass(msgPtr->tkwin, "Message");
    Tk_SetClassProcs(msgPtr->tkwin, &messageClass, (ClientData) msgPtr);
    Tk_CreateEventHandler(msgPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MessageEventProc, (ClientData) msgPtr);
    if (Tk_InitOptions(interp, (char *)msgPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetResult(interp, Tk_PathName(msgPtr->tkwin), TCL_STATIC);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
 */

static int
MessageWidgetObjCmd(
    ClientData clientData,	/* Information about message widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr = (Message *)clientData;
    static const char *const 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 ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(msgPtr);

    switch ((enum options) index) {
    case MESSAGE_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	} else {
	    objPtr = Tk_GetOptionValue(interp, msgPtr,
		    msgPtr->optionTable, objv[2], 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, msgPtr,
		    msgPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    msgPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;
	    }
	} else {
	    result = ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0);
	}
	break;
    }

    Tcl_Release(msgPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMessage --







|

|
|






|



|
|



|







|











|














|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
 */

static int
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", 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;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve((ClientData) msgPtr);

    switch ((enum options) index) {
    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 {
		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 {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;
	    }
	} else {
	    result = ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0);
	}
	break;
    }

    Tcl_Release((ClientData) msgPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMessage --
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
 *	Everything associated with the message is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMessage(
    void *memPtr)		/* Info about message widget. */
{
    Message *msgPtr = (Message *) memPtr;

    msgPtr->flags |= MESSAGE_DELETED;

    Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd);
    if (msgPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(DisplayMessage, msgPtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    if (msgPtr->textGC != NULL) {
	Tk_FreeGC(msgPtr->display, msgPtr->textGC);
    }
    if (msgPtr->textLayout != NULL) {
	Tk_FreeTextLayout(msgPtr->textLayout);
    }
    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(msgPtr->interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }
    Tk_FreeConfigOptions((char *) msgPtr, msgPtr->optionTable, msgPtr->tkwin);
    msgPtr->tkwin = NULL;
    ckfree(msgPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureMessage --
 *







|

|





|














|

|



|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
 *	Everything associated with the message is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMessage(
    char *memPtr)		/* Info about message widget. */
{
    register Message *msgPtr = (Message *) memPtr;

    msgPtr->flags |= MESSAGE_DELETED;

    Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd);
    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.
     */

    if (msgPtr->textGC != NULL) {
	Tk_FreeGC(msgPtr->display, msgPtr->textGC);
    }
    if (msgPtr->textLayout != NULL) {
	Tk_FreeTextLayout(msgPtr->textLayout);
    }
    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar(msgPtr->interp, msgPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, (ClientData) msgPtr);
    }
    Tk_FreeConfigOptions((char *) msgPtr, msgPtr->optionTable, msgPtr->tkwin);
    msgPtr->tkwin = NULL;
    ckfree((char *) msgPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureMessage --
 *
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMessage(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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;
    (void)flags;

    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    if (Tk_SetOptions(interp, msgPtr, msgPtr->optionTable, objc, objv,
	    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 (msgPtr->textVarName != NULL) {
	const char *value;

	value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
	if (value == NULL) {
	    Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (msgPtr->string != NULL) {
		ckfree(msgPtr->string);
	    }
	    msgPtr->string = strcpy((char *)ckalloc(strlen(value) + 1), value);
	}
	Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    /*
     * 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);

    if (msgPtr->highlightWidth < 0) {
	msgPtr->highlightWidth = 0;
    }

    Tk_FreeSavedOptions(&savedOptions);
    MessageWorldChanged(msgPtr);
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * MessageWorldChanged --







|


|



<






|

|


|












|

|

|





|

|

|















|







431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
 *
 *----------------------------------------------------------------------
 */

static int
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;


    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	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, 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 (msgPtr->textVarName != NULL) {
	CONST char *value;

	value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY);
	if (value == NULL) {
	    Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (msgPtr->string != NULL) {
		ckfree(msgPtr->string);
	    }
	    msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value);
	}
	Tcl_TraceVar(interp, msgPtr->textVarName,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, (ClientData) msgPtr);
    }

    /*
     * 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);

    if (msgPtr->highlightWidth < 0) {
	msgPtr->highlightWidth = 0;
    }

    Tk_FreeSavedOptions(&savedOptions);
    MessageWorldChanged((ClientData) msgPtr);
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * MessageWorldChanged --
525
526
527
528
529
530
531
532


533
534
535
536
537
538
539
static void
MessageWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr = (Message *)instanceData;



    if (msgPtr->border != NULL) {
	Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border);
    }

    gcValues.font = Tk_FontId(msgPtr->tkfont);
    gcValues.foreground = msgPtr->fgColorPtr->pixel;







|
>
>







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
static void
MessageWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr;

    msgPtr = (Message *) instanceData;

    if (msgPtr->border != NULL) {
	Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border);
    }

    gcValues.font = Tk_FontId(msgPtr->tkfont);
    gcValues.foreground = msgPtr->fgColorPtr->pixel;
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
     * Recompute the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */

    ComputeMessageGeometry(msgPtr);
    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *







|







553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
     * Recompute the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */

    ComputeMessageGeometry(msgPtr);
    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 *	desired geometry for this window.
 *
 *--------------------------------------------------------------
 */

static void
ComputeMessageGeometry(
    Message *msgPtr)	/* Information about window. */
{
    int width, inc, height;
    int thisWidth, thisHeight, maxWidth;
    int aspect, lowerBound, upperBound, inset;

    Tk_FreeTextLayout(msgPtr->textLayout);








|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
 *	desired geometry for this window.
 *
 *--------------------------------------------------------------
 */

static void
ComputeMessageGeometry(
    register Message *msgPtr)	/* Information about window. */
{
    int width, inc, height;
    int thisWidth, thisHeight, maxWidth;
    int aspect, lowerBound, upperBound, inset;

    Tk_FreeTextLayout(msgPtr->textLayout);

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    Message *msgPtr = (Message *)clientData;
    Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;
    if ((msgPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }







|
|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    register Message *msgPtr = (Message *) clientData;
    register Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;
    if ((msgPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *)clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMessage(clientData);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    msgPtr->flags |= GOT_FOCUS;
	    if (msgPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == FocusOut) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    msgPtr->flags &= ~GOT_FOCUS;
	    if (msgPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    }
    return;

  redraw:
    if ((msgPtr->tkwin != NULL) && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|





|



















|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *) clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMessage((char *) clientData);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    msgPtr->flags |= GOT_FOCUS;
	    if (msgPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == FocusOut) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    msgPtr->flags &= ~GOT_FOCUS;
	    if (msgPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    }
    return;

  redraw:
    if ((msgPtr->tkwin != NULL) && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = (Message *)clientData;

    /*
     * 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.
     */







|







791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = (Message *) clientData;

    /*
     * 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.
     */
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
 *
 * Side effects:
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */


static char *
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. */
{
    Message *msgPtr = (Message *)clientData;
    const char *value;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && msgPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        msgPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MessageTextVarProc, probe);
                if (probe == (ClientData)msgPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
                return NULL;
            }
	    Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
		    TCL_GLOBAL_ONLY);
	    Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MessageTextVarProc, clientData);
	}
	return NULL;
    }

    value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = (char *)ckalloc(strlen(value) + 1);
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>




|
|


|
|
<
<







<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|






|







|





|












822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839


840
841
842
843
844
845
846


847


848
















849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
 *
 * Side effects:
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
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 (flags & TCL_TRACE_UNSETS) {


	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {


	    Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string,
















		    TCL_GLOBAL_ONLY);
	    Tcl_TraceVar(interp, msgPtr->textVarName,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    MessageTextVarProc, clientData);
	}
	return NULL;
    }

    value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = (char *) ckalloc((unsigned) (strlen(value) + 1));
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
    }
    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkObj.c.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    (objPtr)->internalRep.twoPtrValue.ptr1 = INT2PTR(intval);	\
    (objPtr)->internalRep.twoPtrValue.ptr2 = 0

#define GET_SIMPLEPIXEL(objPtr)				\
    (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr1))

#define SET_COMPLEXPIXEL(objPtr, repPtr)		\
    (objPtr)->internalRep.twoPtrValue.ptr1 = NULL;		\
    (objPtr)->internalRep.twoPtrValue.ptr2 = repPtr

#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 {
    const Tcl_ObjType *doubleTypePtr;
    const Tcl_ObjType *intTypePtr;
    const Tcl_ObjType *endTypePtr;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is the internal representation for mm objects.
 */








|
|












|


<







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
    (objPtr)->internalRep.twoPtrValue.ptr1 = INT2PTR(intval);	\
    (objPtr)->internalRep.twoPtrValue.ptr2 = 0

#define GET_SIMPLEPIXEL(objPtr)				\
    (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr1))

#define SET_COMPLEXPIXEL(objPtr, repPtr)		\
    (objPtr)->internalRep.twoPtrValue.ptr1 = 0;		\
    (objPtr)->internalRep.twoPtrValue.ptr2 = (VOID *) repPtr

#define GET_COMPLEXPIXEL(objPtr)			\
    ((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2)

/*
 * 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.
 */

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
 * 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. */
#if TCL_MAJOR_VERSION > 8
    size_t epoch;			/* Value of mainPtr->deletionEpoch at last
				 * successful lookup. */
#else
    long epoch;
#endif
} WindowRep;

/*
 * Prototypes for functions defined later in this file:
 */

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);

#if TCL_MAJOR_VERSION < 9
#if defined(USE_TCL_STUBS)
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntStubs, just
    enough to make it work */
typedef struct TclIntStubs {
    int magic;
    void *hooks;
    void (*dummy[34]) (void); /* dummy entries 0-33, not used */
    int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
} TclIntStubs;
extern const struct TclIntStubs *tclIntStubsPtr;

# undef Tcl_GetIntForIndex
# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
    ((int (*)(Tcl_Interp*,  Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
	tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
#elif TCL_MINOR_VERSION < 7
extern int TclGetIntForIndex(Tcl_Interp*,  Tcl_Obj *, int, int*);
# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
#endif
#endif

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType pixelObjType = {
    "pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType mmObjType = {
    "mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static const Tcl_ObjType windowObjType = {
    "window",			/* name */
    FreeWindowInternalRep,	/* freeIntRepProc */
    DupWindowInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* 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(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr/intTypePtr without
	 * hash-table lookup or creating complete Tcl_Obj's */
	Tcl_Obj obj;
	obj.bytes = (char *)"end";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetIntForIndex(NULL, &obj, TCL_INDEX_NONE, (TkSizeT *)&obj.internalRep.doubleValue);
	tsdPtr->endTypePtr = obj.typePtr;
	obj.bytes = (char *)"0.0";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
	tsdPtr->doubleTypePtr = obj.typePtr;
	obj.bytes = (char *)"0";
	obj.length = 1;
	obj.typePtr = NULL;
	Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
	tsdPtr->intTypePtr = obj.typePtr;
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetIntForIndex --
 *
 *	Almost the same as Tcl_GetIntForIndex, but it return an int, and it is
 *	more restricted. For example it only accepts "end", not "end-1", and
 *	only "2", not "1+1"
 *
 * Results:
 *	The return value is a standard Tcl object result.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

int
TkGetIntForIndex(
    Tcl_Obj *indexObj,
    TkSizeT end,
    int lastOK,
    TkSizeT *indexPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) {
	return TCL_ERROR;
    }
    if (indexObj->typePtr == tsdPtr->endTypePtr) {
	/* check for "end", but not "end-??" or "end+??" */
	return (*indexPtr == (end + lastOK)) ? TCL_OK :  TCL_ERROR;
    }
    if (indexObj->typePtr != tsdPtr->intTypePtr) {
	/* Neither do we accept "??-??" or "??+??" */
	return TCL_ERROR;
    }
#if TCL_MAJOR_VERSION < 9
    if ((*indexPtr < -1) || (end < -1)) {
	return TCL_ERROR;
    }
#endif
    if ((*indexPtr + 1) > (end + 1)) {
	*indexPtr = end + 1;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * 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







<
|

<
<
<







|
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|


|




|





|


|




|







|




|















|





<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







69
70
71
72
73
74
75

76
77



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95























96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155












156




157
158
159
160
161


















































162
163
164
165
166
167
168
 * 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. */

    long epoch;			/* Value of mainPtr->deletionEpoch at last
				 * successful lookup. */



} WindowRep;

/*
 * Prototypes for functions defined later in this file:
 */

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.
 */

static Tcl_ObjType pixelObjType = {
    "pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetPixelFromAny		/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independant settings.
 */

static Tcl_ObjType mmObjType = {
    "mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    SetMMFromAny		/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static Tcl_ObjType windowObjType = {
    "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;
}



















































/*
 *----------------------------------------------------------------------
 *
 * 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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    Tcl_Obj *objPtr,		/* The object from which to get pixels. */
    int *intPtr,
    double *dblPtr)		/* Places to store resulting pixels. */
{
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static const double bias[] = {
	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







|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
    Tcl_Obj *objPtr,		/* The object from which to get pixels. */
    int *intPtr,
    double *dblPtr)		/* Places to store resulting pixels. */
{
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static double bias[] = {
	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
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
static void
FreePixelInternalRep(
    Tcl_Obj *objPtr)		/* Pixel object with internal rep to free. */
{
    if (!SIMPLE_PIXELREP(objPtr)) {
	PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);

	ckfree(pixelPtr);
    }
    SET_SIMPLEPIXEL(objPtr, 0);
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------







|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
static void
FreePixelInternalRep(
    Tcl_Obj *objPtr)		/* Pixel object with internal rep to free. */
{
    if (!SIMPLE_PIXELREP(objPtr)) {
	PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);

	ckfree((char *) pixelPtr);
    }
    SET_SIMPLEPIXEL(objPtr, 0);
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupPixelInternalRep(
    Tcl_Obj *srcPtr,	/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
{
    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;
	newPtr->units = oldPtr->units;
	newPtr->tkwin = oldPtr->tkwin;
	newPtr->returnValue = oldPtr->returnValue;
	SET_COMPLEXPIXEL(copyPtr, newPtr);
    }
}







|
|









|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupPixelInternalRep(
    register Tcl_Obj *srcPtr,	/* Object with internal rep to copy. */
    register Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
{
    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;
	newPtr->units = oldPtr->units;
	newPtr->tkwin = oldPtr->tkwin;
	newPtr->returnValue = oldPtr->returnValue;
	SET_COMPLEXPIXEL(copyPtr, newPtr);
    }
}
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

static int
SetPixelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    const char *string;
    char *rest;
    double d;
    int i, units;

    string = Tcl_GetString(objPtr);

    d = strtod(string, &rest);
    if (rest == string) {







|
<







438
439
440
441
442
443
444
445

446
447
448
449
450
451
452

static int
SetPixelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    char *string, *rest;

    double d;
    int i, units;

    string = Tcl_GetString(objPtr);

    d = strtod(string, &rest);
    if (rest == string) {
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600




601


602

603
604
605
606
607
608
609
610

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &pixelObjType;

    i = (int) d;
    if ((units < 0) && (i == d)) {
	SET_SIMPLEPIXEL(objPtr, i);
    } else {
	PixelRep *pixelPtr = (PixelRep *)ckalloc(sizeof(PixelRep));

	pixelPtr->value = d;
	pixelPtr->units = units;
	pixelPtr->tkwin = NULL;
	pixelPtr->returnValue = i;
	SET_COMPLEXPIXEL(objPtr, pixelPtr);
    }
    return TCL_OK;

  error:
    if (interp != NULL) {




	Tcl_SetObjResult(interp, Tcl_ObjPrintf(


		"bad screen distance \"%.50s\"", string));

	Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|








|











>
>
>
>
|
>
>
|
>
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }

    objPtr->typePtr = &pixelObjType;

    i = (int) d;
    if ((units < 0) && (i == d)) {
	SET_SIMPLEPIXEL(objPtr, i);
    } else {
	PixelRep *pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep));

	pixelPtr->value = d;
	pixelPtr->units = units;
	pixelPtr->tkwin = NULL;
	pixelPtr->returnValue = i;
	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;
}

/*
 *----------------------------------------------------------------------
 *
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    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 const double bias[] = {
	10.0,	25.4,	1.0,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;
    if (mmPtr->tkwin != tkwin) {
	d = mmPtr->value;
	if (mmPtr->units == -1) {
	    d /= WidthOfScreen(Tk_Screen(tkwin));
	    d *= WidthMMOfScreen(Tk_Screen(tkwin));
	} else {
	    d *= bias[mmPtr->units];







|










|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    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,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    mmPtr = (MMRep *) objPtr->internalRep.twoPtrValue.ptr1;
    if (mmPtr->tkwin != tkwin) {
	d = mmPtr->value;
	if (mmPtr->units == -1) {
	    d /= WidthOfScreen(Tk_Screen(tkwin));
	    d *= WidthMMOfScreen(Tk_Screen(tkwin));
	} else {
	    d *= bias[mmPtr->units];
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
 *----------------------------------------------------------------------
 */

static void
FreeMMInternalRep(
    Tcl_Obj *objPtr)		/* MM object with internal rep to free. */
{
    ckfree(objPtr->internalRep.twoPtrValue.ptr1);
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *







|







594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
 *----------------------------------------------------------------------
 */

static void
FreeMMInternalRep(
    Tcl_Obj *objPtr)		/* MM object with internal rep to free. */
{
    ckfree((char *) objPtr->internalRep.twoPtrValue.ptr1);
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupMMInternalRep(
    Tcl_Obj *srcPtr,	/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
{
    MMRep *oldPtr, *newPtr;

    copyPtr->typePtr = srcPtr->typePtr;
    oldPtr = (MMRep *)srcPtr->internalRep.twoPtrValue.ptr1;
    newPtr = (MMRep *)ckalloc(sizeof(MMRep));
    newPtr->value = oldPtr->value;
    newPtr->units = oldPtr->units;
    newPtr->tkwin = oldPtr->tkwin;
    newPtr->returnValue = oldPtr->returnValue;
    copyPtr->internalRep.twoPtrValue.ptr1 = newPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfMM --
 *







|
|




|
|




|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
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.twoPtrValue.ptr1;
    newPtr = (MMRep *) ckalloc(sizeof(MMRep));
    newPtr->value = oldPtr->value;
    newPtr->units = oldPtr->units;
    newPtr->tkwin = oldPtr->tkwin;
    newPtr->returnValue = oldPtr->returnValue;
    copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) newPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfMM --
 *
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
 *	double-to-string conversion.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfMM(
    Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    TkSizeT len;

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }

    Tcl_PrintDouble(NULL, mmPtr->value, buffer);
    len = strlen(buffer);

    objPtr->bytes = (char *)ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}

/*
 *----------------------------------------------------------------------
 *







|



|

|






|

|







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
 *	double-to-string conversion.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfMM(
    register Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    register int len;

    mmPtr = (MMRep *) objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }

    Tcl_PrintDouble(NULL, mmPtr->value, buffer);
    len = (int)strlen(buffer);

    objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}

/*
 *----------------------------------------------------------------------
 *
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    const char *string;
    char *rest;
    double d;
    int units;
    MMRep *mmPtr;

    if (objPtr->typePtr == typeCache->doubleTypePtr) {
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;







|
<







701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    char *string, *rest;

    double d;
    int units;
    MMRep *mmPtr;

    if (objPtr->typePtr == typeCache->doubleTypePtr) {
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
	if (rest == string) {
	    /*
	     * Must copy string before resetting the result in case a caller
	     * is trying to convert the interpreter's result to mms.
	     */

	error:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad screen distance \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "DISTANCE", NULL);
	    return TCL_ERROR;
	}
	while ((*rest != '\0') && isspace(UCHAR(*rest))) {
	    rest++;
	}

	switch (*rest) {







<
|
|







736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751
	if (rest == string) {
	    /*
	     * Must copy string before resetting the result in case a caller
	     * is trying to convert the interpreter's result to mms.
	     */

	error:

	    Tcl_AppendResult(interp, "bad screen distance \"", string,
		    "\"", NULL);
	    return TCL_ERROR;
	}
	while ((*rest != '\0') && isspace(UCHAR(*rest))) {
	    rest++;
	}

	switch (*rest) {
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &mmObjType;

    mmPtr = (MMRep *)ckalloc(sizeof(MMRep));
    mmPtr->value = d;
    mmPtr->units = units;
    mmPtr->tkwin = NULL;
    mmPtr->returnValue	= d;

    objPtr->internalRep.twoPtrValue.ptr1 = mmPtr;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|




|





|







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }

    objPtr->typePtr = &mmObjType;

    mmPtr = (MMRep *) ckalloc(sizeof(MMRep));
    mmPtr->value = d;
    mmPtr->units = units;
    mmPtr->tkwin = NULL;
    mmPtr->returnValue	= d;

    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) mmPtr;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
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;
    WindowRep *winPtr;


    if (objPtr->typePtr != &windowObjType) {
	int result = SetWindowFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;
    if (winPtr->tkwin == NULL
	    || winPtr->mainPtr == NULL
	    || winPtr->mainPtr != mainPtr
	    || winPtr->epoch != mainPtr->deletionEpoch) {

	/*
	 * Cache is invalid.
	 */

	winPtr->tkwin = Tk_NameToWindow(interp,
		Tcl_GetString(objPtr), tkwin);
	if (winPtr->tkwin == NULL) {







|
>

|
<
|
|
|
|
<
|



|
>







816
817
818
819
820
821
822
823
824
825
826

827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842
843
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;
    int result;

    result = Tcl_ConvertToType(interp, objPtr, &windowObjType);

    if (result != TCL_OK) {
	return result;
    }


    winPtr = (WindowRep *) objPtr->internalRep.twoPtrValue.ptr1;
    if (winPtr->tkwin == NULL
	    || winPtr->mainPtr == NULL
	    || winPtr->mainPtr != mainPtr
	    || winPtr->epoch != mainPtr->deletionEpoch)
    {
	/*
	 * Cache is invalid.
	 */

	winPtr->tkwin = Tk_NameToWindow(interp,
		Tcl_GetString(objPtr), tkwin);
	if (winPtr->tkwin == NULL) {
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
 * 	TkGetWindowFromObj, which initializes the WindowRep cache.
 *
 *----------------------------------------------------------------------
 */

static int
SetWindowFromAny(
    TCL_UNUSED(Tcl_Interp *),
    Tcl_Obj *objPtr)	/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    WindowRep *winPtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    winPtr = (WindowRep *)ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;
    winPtr->mainPtr = NULL;
    winPtr->epoch = 0;

    objPtr->internalRep.twoPtrValue.ptr1 = winPtr;
    objPtr->typePtr = &windowObjType;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
|








|


|


|




|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
 * 	TkGetWindowFromObj, which initializes the WindowRep cache.
 *
 *----------------------------------------------------------------------
 */

static int
SetWindowFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    WindowRep *winPtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    (void)Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }

    winPtr = (WindowRep *) ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;
    winPtr->mainPtr = NULL;
    winPtr->epoch = 0;

    objPtr->internalRep.twoPtrValue.ptr1 = (VOID*)winPtr;
    objPtr->typePtr = &windowObjType;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupWindowInternalRep(
    Tcl_Obj *srcPtr,
    Tcl_Obj *copyPtr)
{
    WindowRep *oldPtr, *newPtr;

    oldPtr = (WindowRep *)srcPtr->internalRep.twoPtrValue.ptr1;
    newPtr = (WindowRep *)ckalloc(sizeof(WindowRep));
    newPtr->tkwin = oldPtr->tkwin;
    newPtr->mainPtr = oldPtr->mainPtr;
    newPtr->epoch = oldPtr->epoch;
    copyPtr->internalRep.twoPtrValue.ptr1 = newPtr;
    copyPtr->typePtr = srcPtr->typePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeWindowInternalRep --







|
|

|

|
|



|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupWindowInternalRep(
    register Tcl_Obj *srcPtr,
    register Tcl_Obj *copyPtr)
{
    register WindowRep *oldPtr, *newPtr;

    oldPtr = srcPtr->internalRep.twoPtrValue.ptr1;
    newPtr = (WindowRep *) ckalloc(sizeof(WindowRep));
    newPtr->tkwin = oldPtr->tkwin;
    newPtr->mainPtr = oldPtr->mainPtr;
    newPtr->epoch = oldPtr->epoch;
    copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *)newPtr;
    copyPtr->typePtr = srcPtr->typePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeWindowInternalRep --
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
 *----------------------------------------------------------------------
 */

static void
FreeWindowInternalRep(
    Tcl_Obj *objPtr)		/* Window object with internal rep to free. */
{
    ckfree(objPtr->internalRep.twoPtrValue.ptr1);
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular to a
 *	particular Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_NewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;
    winPtr->tkwin = tkwin;
    winPtr->mainPtr = mainPtr;
    winPtr->epoch = mainPtr->deletionEpoch;
    return objPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkParsePadAmount --
 *
 *	This function parses a padding specification and returns the







|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







954
955
956
957
958
959
960
961
962
963
964


































965
966
967
968
969
970
971
 *----------------------------------------------------------------------
 */

static void
FreeWindowInternalRep(
    Tcl_Obj *objPtr)		/* Window object with internal rep to free. */
{
    ckfree((char *) objPtr->internalRep.twoPtrValue.ptr1);
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}



































/*
 *----------------------------------------------------------------------
 *
 * TkParsePadAmount --
 *
 *	This function parses a padding specification and returns the
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163

1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

    /*
     * Check for a common case where a single object would otherwise be
     * shimmered between a list and a pixel spec.
     */

    if (specObj->typePtr == &pixelObjType) {
	if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK){
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad pad value \"%s\": must be positive screen distance",
		    Tcl_GetString(specObj)));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
	    return TCL_ERROR;
	}
	secondInt = firstInt;
	goto done;
    }

    /*
     * 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) {
	return TCL_ERROR;
    }
    if (objc != 1 && objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"wrong number of parts to pad specification", -1));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the first part.
     */

    if (Tk_GetPixelsFromObj(interp, tkwin, objv[0], &firstInt) != TCL_OK ||
	    (firstInt < 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(

		"bad pad value \"%s\": must be positive screen distance",
		Tcl_GetString(objv[0])));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the second part if it exists, otherwise it is as if it was the
     * same as the first part.
     */

    if (objc == 1) {
	secondInt = firstInt;
    } else if (Tk_GetPixelsFromObj(interp, tkwin, objv[1],
	    &secondInt) != TCL_OK || (secondInt < 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad 2nd pad value \"%s\": must be positive screen distance",
		Tcl_GetString(objv[1])));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
	return TCL_ERROR;
    }

    /*
     * Write the parsed bits back into the receiving variables.
     */








|
|
|
|
|















|
|
<









|
>
|
<
<












|
|
|
|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040


1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063

    /*
     * Check for a common case where a single object would otherwise be
     * shimmered between a list and a pixel spec.
     */

    if (specObj->typePtr == &pixelObjType) {
	if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "bad pad value \"",
		    Tcl_GetString(specObj),
		    "\": must be positive screen distance", NULL);
	    return TCL_ERROR;
	}
	secondInt = firstInt;
	goto done;
    }

    /*
     * 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) {
	return TCL_ERROR;
    }
    if (objc != 1 && objc != 2) {
	Tcl_AppendResult(interp,
		"wrong number of parts to pad specification", NULL);

	return TCL_ERROR;
    }

    /*
     * Parse the first part.
     */

    if (Tk_GetPixelsFromObj(interp, tkwin, objv[0], &firstInt) != TCL_OK ||
	    (firstInt < 0)) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "bad pad value \"", Tcl_GetString(objv[0]),
		"\": 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.
     */

    if (objc == 1) {
	secondInt = firstInt;
    } else if (Tk_GetPixelsFromObj(interp, tkwin, objv[1],
	    &secondInt) != TCL_OK || (secondInt < 0)) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "bad 2nd pad value \"",
		Tcl_GetString(objv[1]),
		"\": must be positive screen distance", NULL);
	return TCL_ERROR;
    }

    /*
     * Write the parsed bits back into the receiving variables.
     */

1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
 *
 *	Registers Tk's Tcl_ObjType structures with the Tcl run-time.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	All instances of Tcl_ObjType structures used in Tk are registered with
 *	Tcl.
 *
 *----------------------------------------------------------------------
 */

void
TkRegisterObjTypes(void)
{
    Tcl_RegisterObjType(&tkBorderObjType);
    Tcl_RegisterObjType(&tkBitmapObjType);
    Tcl_RegisterObjType(&tkColorObjType);
    Tcl_RegisterObjType(&tkCursorObjType);
    Tcl_RegisterObjType(&tkFontObjType);
    Tcl_RegisterObjType(&mmObjType);

    Tcl_RegisterObjType(&pixelObjType);
    Tcl_RegisterObjType(&tkStateKeyObjType);
    Tcl_RegisterObjType(&windowObjType);
    Tcl_RegisterObjType(&tkTextIndexType);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|














>













1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
 *
 *	Registers Tk's Tcl_ObjType structures with the Tcl run-time.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	All instances of Tcl_ObjType structues used in Tk are registered with
 *	Tcl.
 *
 *----------------------------------------------------------------------
 */

void
TkRegisterObjTypes(void)
{
    Tcl_RegisterObjType(&tkBorderObjType);
    Tcl_RegisterObjType(&tkBitmapObjType);
    Tcl_RegisterObjType(&tkColorObjType);
    Tcl_RegisterObjType(&tkCursorObjType);
    Tcl_RegisterObjType(&tkFontObjType);
    Tcl_RegisterObjType(&mmObjType);
    Tcl_RegisterObjType(&tkOptionObjType);
    Tcl_RegisterObjType(&pixelObjType);
    Tcl_RegisterObjType(&tkStateKeyObjType);
    Tcl_RegisterObjType(&windowObjType);
    Tcl_RegisterObjType(&tkTextIndexType);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkOldConfig.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 * 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.
 */

#include "tkInt.h"

/*
 * Values for "flags" field of Tk_ConfigSpec structures. Be sure to coordinate
 * these values with those defined in tk.h (TK_CONFIG_COLOR_ONLY, etc.) There
 * must not be overlap!
 *
 * INIT -		Non-zero means (char *) things have been converted to
 *			Tk_Uid's.
 */

#define INIT		0x20

#ifndef TK_CONFIG_OPTION_SPECIFIED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static int		DoConfig(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_ConfigSpec *specPtr, Tk_Uid value,
			    int valueIsUid, void *widgRec);
static Tk_ConfigSpec *	FindConfigSpec(Tcl_Interp *interp,
			    Tk_ConfigSpec *specs, const char *argvName,
			    int needFlags, int hateFlags);
static char *		FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec);
static const char *	FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *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);

/*







|












<
<
<
<






|

|


|
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27




28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 * 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.
 */

#include "tkPort.h"

/*
 * Values for "flags" field of Tk_ConfigSpec structures. Be sure to coordinate
 * these values with those defined in tk.h (TK_CONFIG_COLOR_ONLY, etc.) There
 * must not be overlap!
 *
 * INIT -		Non-zero means (char *) things have been converted to
 *			Tk_Uid's.
 */

#define INIT		0x20





/*
 * Forward declarations for functions defined later in this file:
 */

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(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);

/*
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206

207

208
209
210

211
212
213
214
215
216
217
 */

int
Tk_ConfigureWidget(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    const 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. */
{
    Tk_ConfigSpec *specPtr, *staticSpecs;
    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. */

    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_SetObjResult(interp, Tcl_NewStringObj("NULL main window", -1));
	Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    staticSpecs = GetCachedSpecs(interp, specs);

    for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
	specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
    }

    /*
     * Pass one: scan through all of the arguments, processing those that
     * match entries in the specs.
     */

    for ( ; argc > 0; argc -= 2, argv += 2) {
	const char *arg;

	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) *argv);
	} else {
	    arg = *argv;
	}
	specPtr = FindConfigSpec(interp, staticSpecs, arg, needFlags, hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}

	/*
	 * Process the entry.
	 */

	if (argc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", arg));
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL);
	    return TCL_ERROR;
	}
	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) argv[1]);
	} else {
	    arg = argv[1];
	}
	if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) {

	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (processing \"%.40s\" option)",specPtr->argvName));


	    return TCL_ERROR;
	}
	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.
     */

    if (!(flags & TK_CONFIG_ARGV_ONLY)) {
	for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
	    if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)
		    || (specPtr->argvName == NULL)
		    || (specPtr->type == TK_CONFIG_SYNONYM)) {
		continue;
	    }
	    if (((specPtr->specFlags & needFlags) != needFlags)
		    || (specPtr->specFlags & hateFlags)) {
		continue;
	    }
	    value = NULL;
	    if (specPtr->dbName != NULL) {
		value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass);
	    }
	    if (value != NULL) {
		if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
			TCL_OK) {

		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			    "\n    (%s \"%.50s\" in widget \"%.50s\")",
			    "database entry for", specPtr->dbName,
			    Tk_PathName(tkwin)));

		    return TCL_ERROR;
		}
	    } else {
		if (specPtr->defValue != NULL) {
		    value = Tk_GetUid(specPtr->defValue);
		} else {
		    value = NULL;
		}
		if ((value != NULL) && !(specPtr->specFlags
			& TK_CONFIG_DONT_SET_DEFAULT)) {
		    if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
			    TCL_OK) {

			Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(

				"\n    (%s \"%.50s\" in widget \"%.50s\")",
				"default value for", specPtr->dbName,
				Tk_PathName(tkwin)));

			return TCL_ERROR;
		    }
		}
	    }
	}
    }








|

|







|












|
<














|

|
|








|


|



|









|
<
<








>
|
|
>
>














|
















>
|
|
|
|
>












>
|
>

|
|
>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
 */

int
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 *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. */

    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", NULL);

	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
       specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
    }

    /*
     * Pass one: scan through all of the arguments, processing those that
     * match entries in the specs.
     */

    for ( ; argc > 0; argc -= 2, argv += 2) {
	CONST char *arg;

	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetStringFromObj((Tcl_Obj *) *argv, NULL);
	} else {
	    arg = *argv;
	}
	specPtr = FindConfigSpec(interp, specs, arg, needFlags, hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}

	/*
	 * Process the entry.
	 */

	if (argc < 2) {
	    Tcl_AppendResult(interp, "value for \"", arg, "\" missing", NULL);


	    return TCL_ERROR;
	}
	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) argv[1]);
	} else {
	    arg = argv[1];
	}
	if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) {
	    char msg[100];

	    sprintf(msg, "\n    (processing \"%.40s\" option)",
		    specPtr->argvName);
	    Tcl_AddErrorInfo(interp, msg);
	    return TCL_ERROR;
	}
	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.
     */

    if (!(flags & TK_CONFIG_ARGV_ONLY)) {
	for (specPtr=specs; specPtr->type!=TK_CONFIG_END; specPtr++) {
	    if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)
		    || (specPtr->argvName == NULL)
		    || (specPtr->type == TK_CONFIG_SYNONYM)) {
		continue;
	    }
	    if (((specPtr->specFlags & needFlags) != needFlags)
		    || (specPtr->specFlags & hateFlags)) {
		continue;
	    }
	    value = NULL;
	    if (specPtr->dbName != NULL) {
		value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass);
	    }
	    if (value != NULL) {
		if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
			TCL_OK) {
		    char msg[200];

		    sprintf(msg, "\n    (%s \"%.50s\" in widget \"%.50s\")",
			    "database entry for",
			    specPtr->dbName, Tk_PathName(tkwin));
		    Tcl_AddErrorInfo(interp, msg);
		    return TCL_ERROR;
		}
	    } else {
		if (specPtr->defValue != NULL) {
		    value = Tk_GetUid(specPtr->defValue);
		} else {
		    value = NULL;
		}
		if ((value != NULL) && !(specPtr->specFlags
			& TK_CONFIG_DONT_SET_DEFAULT)) {
		    if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
			    TCL_OK) {
			char msg[200];

			sprintf(msg,
				"\n    (%s \"%.50s\" in widget \"%.50s\")",
				"default value for",
				specPtr->dbName, Tk_PathName(tkwin));
			Tcl_AddErrorInfo(interp, msg);
			return TCL_ERROR;
		    }
		}
	    }
	}
    }

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
 */

static Tk_ConfigSpec *
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"
				 * command) identifying particular option. */
    int needFlags,		/* Flags that must be present in matching
				 * entry. */
    int hateFlags)		/* Flags that must NOT be present in matching
				 * entry. */
{
    Tk_ConfigSpec *specPtr;
    char c;		/* First character of current argument. */
    Tk_ConfigSpec *matchPtr;	/* Matching spec, or NULL. */
    size_t length;

    c = argvName[1];
    length = strlen(argvName);
    matchPtr = NULL;
    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {







|






|
|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
 */

static Tk_ConfigSpec *
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"
				 * command) identifying particular option. */
    int needFlags,		/* Flags that must be present in matching
				 * entry. */
    int hateFlags)		/* Flags that must NOT be present in matching
				 * entry. */
{
    register Tk_ConfigSpec *specPtr;
    register char c;		/* First character of current argument. */
    Tk_ConfigSpec *matchPtr;	/* Matching spec, or NULL. */
    size_t length;

    c = argvName[1];
    length = strlen(argvName);
    matchPtr = NULL;
    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
	    continue;
	}
	if (specPtr->argvName[length] == 0) {
	    matchPtr = specPtr;
	    goto gotMatch;
	}
	if (matchPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "ambiguous option \"%s\"", argvName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,NULL);
	    return NULL;
	}
	matchPtr = specPtr;
    }

    if (matchPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", argvName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, NULL);
	return NULL;
    }

    /*
     * Found a matching entry. If it's a synonym, then find the entry that
     * it's a synonym for.
     */

  gotMatch:
    specPtr = matchPtr;
    if (specPtr->type == TK_CONFIG_SYNONYM) {
	for (specPtr = specs; ; specPtr++) {
	    if (specPtr->type == TK_CONFIG_END) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't find synonym for option \"%s\"",
			argvName));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,
			NULL);
		return NULL;
	    }
	    if ((specPtr->dbName == matchPtr->dbName)
		    && (specPtr->type != TK_CONFIG_SYNONYM)
		    && ((specPtr->specFlags & needFlags) == needFlags)
		    && !(specPtr->specFlags & hateFlags)) {
		break;







<
|
|






<
|
<













<
|
|
<
<







271
272
273
274
275
276
277

278
279
280
281
282
283
284
285

286

287
288
289
290
291
292
293
294
295
296
297
298
299

300
301


302
303
304
305
306
307
308
	    continue;
	}
	if (specPtr->argvName[length] == 0) {
	    matchPtr = specPtr;
	    goto gotMatch;
	}
	if (matchPtr != NULL) {

	    Tcl_AppendResult(interp, "ambiguous option \"", argvName,
		    "\"", NULL);
	    return NULL;
	}
	matchPtr = specPtr;
    }

    if (matchPtr == 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.
     */

  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, "\"", NULL);


		return NULL;
	    }
	    if ((specPtr->dbName == matchPtr->dbName)
		    && (specPtr->type != TK_CONFIG_SYNONYM)
		    && ((specPtr->specFlags & needFlags) == needFlags)
		    && !(specPtr->specFlags & hateFlags)) {
		break;
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    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. */
    void *widgRec)		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
{
    void *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) {
	nullValue = 1;
    }

    do {
	ptr = (char *)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:







|


|









|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
    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;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) {
	nullValue = 1;
    }

    do {
	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_INT:
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	    break;
	case TK_CONFIG_STRING: {
	    char *oldStr, *newStr;

	    if (nullValue) {
		newStr = NULL;
	    } else {
		newStr = (char *)ckalloc(strlen(value) + 1);
		strcpy(newStr, value);
	    }
	    oldStr = *((char **) ptr);
	    if (oldStr != NULL) {
		ckfree(oldStr);
	    }
	    *((char **) ptr) = newStr;







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	    break;
	case TK_CONFIG_STRING: {
	    char *oldStr, *newStr;

	    if (nullValue) {
		newStr = NULL;
	    } else {
		newStr = (char *) ckalloc((unsigned) (strlen(value) + 1));
		strcpy(newStr, value);
	    }
	    oldStr = *((char **) ptr);
	    if (oldStr != NULL) {
		ckfree(oldStr);
	    }
	    *((char **) ptr) = newStr;
545
546
547
548
549
550
551
552

553
554
555
556
557

558
559
560
561

562
563
564
565
566
567
568
		    return TCL_ERROR;
		}
	    }
	    *((Tk_Window *) ptr) = tkwin2;
	    break;
	}
	case TK_CONFIG_CUSTOM:
	    if (specPtr->customPtr->parseProc(specPtr->customPtr->clientData,

		    interp, tkwin, value, (char *)widgRec, specPtr->offset)!=TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default:

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad config table: unknown type %d", specPtr->type));
	    Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL);
	    return TCL_ERROR;

	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}

/*







|
>
|



|
>
|
|
|

>







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
		    return TCL_ERROR;
		}
	    }
	    *((Tk_Window *) ptr) = tkwin2;
	    break;
	}
	case TK_CONFIG_CUSTOM:
	    if ((*specPtr->customPtr->parseProc)(
		    specPtr->customPtr->clientData, interp, tkwin, value,
		    widgRec, specPtr->offset) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default: {
	    char buf[64 + TCL_INTEGER_SPACE];

	    sprintf(buf, "bad config table: unknown type %d", specPtr->type);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    return TCL_ERROR;
	}
	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}

/*
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
 *--------------------------------------------------------------
 */

int
Tk_ConfigureInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const 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. */
{
    Tk_ConfigSpec *specPtr, *staticSpecs;
    int needFlags, hateFlags;
    char *list;
    const char *leader = "{";

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    staticSpecs = GetCachedSpecs(interp, specs);

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    Tcl_ResetResult(interp);
    if (argvName != NULL) {
	specPtr = FindConfigSpec(interp, staticSpecs, argvName, needFlags,
		hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}

	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_SetObjResult(interp, Tcl_NewStringObj(list, -1));
	ckfree(list);
	return TCL_OK;
    }

    /*
     * Loop through all the specs, creating a big list with all their
     * information.
     */

    for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}







|


|






|


|












|






|

|
<



>
|
<
|








|







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
 *--------------------------------------------------------------
 */

int
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. */
{
    register Tk_ConfigSpec *specPtr;
    int needFlags, hateFlags;
    char *list;
    char *leader = "{";

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    Tcl_SetResult(interp, NULL, TCL_STATIC);
    if (argvName != NULL) {
	specPtr = FindConfigSpec(interp, specs, argvName, needFlags,hateFlags);

	if (specPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetResult(interp,
		FormatConfigInfo(interp, tkwin, specPtr, widgRec),

		TCL_DYNAMIC);
	return TCL_OK;
    }

    /*
     * Loop through all the specs, creating a big list with all their
     * information.
     */

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
 */

static char *
FormatConfigInfo(
    Tcl_Interp *interp,		/* Interpreter to use for things like
				 * floating-point precision. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr,
				/* Pointer to information describing
				 * option. */
    void *widgRec)		/* Pointer to record holding current values of
				 * info for widget. */
{
    const char *argv[6];
    char *result;
    char buffer[200];
    Tcl_FreeProc *freeProc = NULL;

    argv[0] = specPtr->argvName;
    argv[1] = specPtr->dbName;
    argv[2] = specPtr->dbClass;







|


|


|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
 */

static char *
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 = NULL;

    argv[0] = specPtr->argvName;
    argv[1] = specPtr->dbName;
    argv[2] = specPtr->dbClass;
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *) argv[4]);
	} else {
	    freeProc((char *) argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------







|

|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *)argv[4]);
	} else {
	    (*freeProc)((char *)argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870


871
872
873
874
875
876
877

878
879
880
881
882
883
884
885
886
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const char *
FormatConfigValue(
    Tcl_Interp *interp,		/* Interpreter for use in real conversions. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr, /* Pointer to information describing option.
				 * Must not point to a synonym option. */
    void *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
				 * function to free the result, or NULL if
				 * result is static. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;
    ptr = (char *)widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *)ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:
	result = (*(char **)ptr);
	if (result == NULL) {
	    result = "";
	}
	break;
    case TK_CONFIG_UID: {
	Tk_Uid uid = *((Tk_Uid *)ptr);

	if (uid != NULL) {
	    result = uid;
	}
	break;
    }
    case TK_CONFIG_COLOR: {
	XColor *colorPtr = *((XColor **)ptr);

	if (colorPtr != NULL) {
	    result = Tk_NameOfColor(colorPtr);
	}
	break;
    }
    case TK_CONFIG_FONT: {
	Tk_Font tkfont = *((Tk_Font *)ptr);

	if (tkfont != NULL) {
	    result = Tk_NameOfFont(tkfont);
	}
	break;
    }
    case TK_CONFIG_BITMAP: {
	Pixmap pixmap = *((Pixmap *)ptr);

	if (pixmap != None) {
	    result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
	}
	break;
    }
    case TK_CONFIG_BORDER: {
	Tk_3DBorder border = *((Tk_3DBorder *)ptr);

	if (border != NULL) {
	    result = Tk_NameOf3DBorder(border);
	}
	break;
    }
    case TK_CONFIG_RELIEF:
	result = Tk_NameOfRelief(*((int *)ptr));
	break;
    case TK_CONFIG_CURSOR:
    case TK_CONFIG_ACTIVE_CURSOR: {
	Tk_Cursor cursor = *((Tk_Cursor *)ptr);

	if (cursor != NULL) {
	    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: {


	tkwin = *((Tk_Window *)ptr);
	if (tkwin != NULL) {
	    result = Tk_PathName(tkwin);
	}
	break;
    }
    case TK_CONFIG_CUSTOM:

	result = specPtr->customPtr->printProc(specPtr->customPtr->clientData,
		tkwin, (char *)widgRec, specPtr->offset, freeProcPtr);
	break;
    default:
	result = "?? unknown type ??";
    }
    return result;
}








|



|

|







<
|


|



|






|



|



|





|







|







|







|







|







|



|







|


|


|


|


|



|



>
>
|






>
|
|







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static CONST char *
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.
				 * Must have at least 200 bytes of storage. */
    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;

    *freeProcPtr = NULL;
    ptr = widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *) ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	sprintf(buffer, "%d", *((int *) ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *) ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:
	result = (*(char **) ptr);
	if (result == NULL) {
	    result = "";
	}
	break;
    case TK_CONFIG_UID: {
	Tk_Uid uid = *((Tk_Uid *) ptr);

	if (uid != NULL) {
	    result = uid;
	}
	break;
    }
    case TK_CONFIG_COLOR: {
	XColor *colorPtr = *((XColor **) ptr);

	if (colorPtr != NULL) {
	    result = Tk_NameOfColor(colorPtr);
	}
	break;
    }
    case TK_CONFIG_FONT: {
	Tk_Font tkfont = *((Tk_Font *) ptr);

	if (tkfont != NULL) {
	    result = Tk_NameOfFont(tkfont);
	}
	break;
    }
    case TK_CONFIG_BITMAP: {
	Pixmap pixmap = *((Pixmap *) ptr);

	if (pixmap != None) {
	    result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
	}
	break;
    }
    case TK_CONFIG_BORDER: {
	Tk_3DBorder border = *((Tk_3DBorder *) ptr);

	if (border != NULL) {
	    result = Tk_NameOf3DBorder(border);
	}
	break;
    }
    case TK_CONFIG_RELIEF:
	result = Tk_NameOfRelief(*((int *) ptr));
	break;
    case TK_CONFIG_CURSOR:
    case TK_CONFIG_ACTIVE_CURSOR: {
	Tk_Cursor cursor = *((Tk_Cursor *) ptr);

	if (cursor != NULL) {
	    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;
}

904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
 *----------------------------------------------------------------------
 */

int
Tk_ConfigureValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const 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;
    Tcl_FreeProc *freeProc;
    const char *result;
    char buffer[200];

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specPtr = GetCachedSpecs(interp, specs);

    specPtr = FindConfigSpec(interp, specPtr, argvName, needFlags, hateFlags);
    if (specPtr == NULL) {
	return TCL_ERROR;
    }
    result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
	    &freeProc);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *) result);
	} else {
	    freeProc((char *) result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|


|








|













|

|





|


|

|







903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
 *----------------------------------------------------------------------
 */

int
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;
    Tcl_FreeProc *freeProc;
    CONST char *result;
    char buffer[200];

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
	hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags);
    if (specPtr == NULL) {
	return TCL_ERROR;
    }
    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)) {
	    ckfree((char *)result);
	} else {
	    (*freeProc)((char *)result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
970
971
972
973
974
975
976

977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
 * Notes:
 *	Since this is not looking anything up, this uses the static version of
 *	the config specs.
 *
 *----------------------------------------------------------------------
 */


void
Tk_FreeOptions(
    const 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. */
{
    const Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}
	ptr = widgRec + specPtr->offset;







>


|








|







969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
 * Notes:
 *	Since this is not looking anything up, this uses the static version of
 *	the config specs.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
void
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. */
{
    register Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}
	ptr = widgRec + specPtr->offset;
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
     * copies of the widget specs are stored in. In effect, this is
     * self-initializing code.
     */

    specCacheTablePtr = (Tcl_HashTable *)
	    Tcl_GetAssocData(interp, "tkConfigSpec.threadTable", NULL);
    if (specCacheTablePtr == NULL) {
	specCacheTablePtr = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(specCacheTablePtr, TCL_ONE_WORD_KEYS);
	Tcl_SetAssocData(interp, "tkConfigSpec.threadTable",
		DeleteSpecCacheTable, specCacheTablePtr);
    }

    /*
     * Look up or create the hash entry that the constant specs are mapped to,
     * which will have the writable specs as its associated value.
     */

    entryPtr = Tcl_CreateHashEntry(specCacheTablePtr, (char *) staticSpecs,
	    &isNew);
    if (isNew) {
	size_t entrySpace = sizeof(Tk_ConfigSpec);
	const Tk_ConfigSpec *staticSpecPtr;
	Tk_ConfigSpec *specPtr;

	/*
	 * OK, no working copy in this interpreter so copy. Need to work out
	 * how much space to allocate first.
	 */

	for (staticSpecPtr=staticSpecs; staticSpecPtr->type!=TK_CONFIG_END;
		staticSpecPtr++) {
	    entrySpace += sizeof(Tk_ConfigSpec);
	}

	/*
	 * Now allocate our working copy's space and copy over the contents
	 * from the origin.
	 */

	cachedSpecs = (Tk_ConfigSpec *)ckalloc(entrySpace);
	memcpy(cachedSpecs, staticSpecs, entrySpace);
	Tcl_SetHashValue(entryPtr, cachedSpecs);

	/*
	 * Finally, go through and replace database names, database classes
	 * and default values with Tk_Uids. This is the bit that has to be
	 * per-thread.
	 */








|


|










|















|


|

|







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
     * copies of the widget specs are stored in. In effect, this is
     * self-initializing code.
     */

    specCacheTablePtr = (Tcl_HashTable *)
	    Tcl_GetAssocData(interp, "tkConfigSpec.threadTable", NULL);
    if (specCacheTablePtr == NULL) {
	specCacheTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(specCacheTablePtr, TCL_ONE_WORD_KEYS);
	Tcl_SetAssocData(interp, "tkConfigSpec.threadTable",
		DeleteSpecCacheTable, (ClientData) specCacheTablePtr);
    }

    /*
     * Look up or create the hash entry that the constant specs are mapped to,
     * which will have the writable specs as its associated value.
     */

    entryPtr = Tcl_CreateHashEntry(specCacheTablePtr, (char *) staticSpecs,
	    &isNew);
    if (isNew) {
	unsigned int entrySpace = sizeof(Tk_ConfigSpec);
	const Tk_ConfigSpec *staticSpecPtr;
	Tk_ConfigSpec *specPtr;

	/*
	 * OK, no working copy in this interpreter so copy. Need to work out
	 * how much space to allocate first.
	 */

	for (staticSpecPtr=staticSpecs; staticSpecPtr->type!=TK_CONFIG_END;
		staticSpecPtr++) {
	    entrySpace += sizeof(Tk_ConfigSpec);
	}

	/*
	 * Now allocate our working copy's space and copy over the contents
	 * from the master copy.
	 */

	cachedSpecs = (Tk_ConfigSpec *) ckalloc(entrySpace);
	memcpy(cachedSpecs, staticSpecs, entrySpace);
	Tcl_SetHashValue(entryPtr, (ClientData) cachedSpecs);

	/*
	 * Finally, go through and replace database names, database classes
	 * and default values with Tk_Uids. This is the bit that has to be
	 * per-thread.
	 */

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
		}
		if (specPtr->defValue != NULL) {
		    specPtr->defValue = Tk_GetUid(specPtr->defValue);
		}
	    }
	}
    } else {
	cachedSpecs = (Tk_ConfigSpec *)Tcl_GetHashValue(entryPtr);
    }

    return cachedSpecs;
}

/*
 *--------------------------------------------------------------







|







1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
		}
		if (specPtr->defValue != NULL) {
		    specPtr->defValue = Tk_GetUid(specPtr->defValue);
		}
	    }
	}
    } else {
	cachedSpecs = (Tk_ConfigSpec *) Tcl_GetHashValue(entryPtr);
    }

    return cachedSpecs;
}

/*
 *--------------------------------------------------------------
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
 *
 *--------------------------------------------------------------
 */

static void
DeleteSpecCacheTable(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    Tcl_HashTable *tablePtr = (Tcl_HashTable *)clientData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    for (entryPtr = Tcl_FirstHashEntry(tablePtr,&search); entryPtr != NULL;
	    entryPtr = Tcl_NextHashEntry(&search)) {
	/*
	 * Someone else deallocates the Tk_Uids themselves.
	 */

	ckfree(Tcl_GetHashValue(entryPtr));
    }
    Tcl_DeleteHashTable(tablePtr);
    ckfree(tablePtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|









|


|









1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
 *
 *--------------------------------------------------------------
 */

static void
DeleteSpecCacheTable(
    ClientData clientData,
    Tcl_Interp *interp)
{
    Tcl_HashTable *tablePtr = (Tcl_HashTable *) clientData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    for (entryPtr = Tcl_FirstHashEntry(tablePtr,&search); entryPtr != NULL;
	    entryPtr = Tcl_NextHashEntry(&search)) {
	/*
	 * Someone else deallocates the Tk_Uids themselves.
	 */

	ckfree((char *) Tcl_GetHashValue(entryPtr));
    }
    Tcl_DeleteHashTable(tablePtr);
    ckfree((char *) tablePtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkOldTest.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
 * 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
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"

#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;        /* Tk's token for image model. */
    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). */
} TImageModel;

/*
 * The following data structure represents a particular use of a particular
 * test image.
 */

typedef struct TImageInstance {
    TImageModel *modelPtr;    /* Pointer to model 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_ImageModel model,
			    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 */
    NULL
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int              ImageObjCmd(ClientData dummy,
                            Tcl_Interp *interp, int objc,
            			    Tcl_Obj * const objv[]);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkOldTestInit --
 *
 *	This function performs initialization 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 *dummy)
{
    static int initialized = 0;
    (void)dummy;

    if (!initialized) {
	initialized = 1;
#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
	Tk_CreateImageType(&imageType);
#endif
    }
    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.
 *
 *----------------------------------------------------------------------
 */
#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)

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_ImageModel model,	/* 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. */
{
    TImageModel *timPtr;
    const char *varName;
    int i;
    (void)typePtr;

    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 = (TImageModel *)ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageObjCmd --
 *
 *	This function implements the commands corresponding to individual
 *	images.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */


static int
ImageObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
	if (objc != 8) {
	    Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
		    " imageWidth imageHeight");
	    return TCL_ERROR;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
	    return TCL_ERROR;
	}
	Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width,
		timPtr->height);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be changed", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







<
<
<
<
<
<


<

|


|
|





|







|










|


















|
<






|
|
|
|






|














|


<



<

<



















|
>









|




|
|

<
















|
|



|

|

|
|
|






|













>

|


|
|

|


|
>
|


|
|
|
|


|
|
|
|
|
|


|


|







12
13
14
15
16
17
18






19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107

108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
 * 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;
}

/*
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 *----------------------------------------------------------------------
 */

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
    instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
    return instPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDisplay --
 *







|

|





|


|
|



|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
 *----------------------------------------------------------------------
 */

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 --
 *
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
    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->modelPtr->imageName, imageX, imageY, width, height,
	    drawableX, drawableY);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
    if (height > (instPtr->modelPtr->height - imageY)) {
	height = instPtr->modelPtr->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),







|



|

|
|
|
|

|
|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    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),
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
 */

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->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDelete --
 *







|


|
|
|


|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
 */

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 --
 *
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
    ckfree(timPtr->imageName);
    ckfree(timPtr->varName);
    ckfree(timPtr);
}
#endif

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



|



|





|

<








374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
 *	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:
 */

Changes to generic/tkOption.c.

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
				 * 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 {
    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







|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
				 * 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
				 * 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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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, const char *string);
static int		ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *fileName, int priority);
static void		SetupStacks(TkWindow *winPtr, int leaf);

/*
 *--------------------------------------------------------------
 *
 * Tk_AddOption --
 *







|

|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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);

/*
 *--------------------------------------------------------------
 *
 * Tk_AddOption --
 *
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
 *--------------------------------------------------------------
 */

void
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. */
{
    TkWindow *winPtr = ((TkWindow *) tkwin)->mainPtr->winPtr;
    ElArray **arrayPtrPtr;
    Element *elPtr;
    Element newEl;
    const char *p;
    const char *field;
    int count, firstField;
    size_t length;
#define TMP_SIZE 100
    char tmp[TMP_SIZE+1];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->mainPtr->optionRootPtr == NULL) {
	OptionInit(winPtr->mainPtr);







|
|






|
|

|
|

|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
 *--------------------------------------------------------------
 */

void
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. */
{
    TkWindow *winPtr = ((TkWindow *) tkwin)->mainPtr->winPtr;
    register ElArray **arrayPtrPtr;
    register Element *elPtr;
    Element newEl;
    register CONST char *p;
    CONST char *field;
    int count, firstField;
    ptrdiff_t length;
#define TMP_SIZE 100
    char tmp[TMP_SIZE+1];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->mainPtr->optionRootPtr == NULL) {
	OptionInit(winPtr->mainPtr);
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
	while ((*p != 0) && (*p != '.') && (*p != '*')) {
	    p++;
	}
	length = p - field;
	if (length > TMP_SIZE) {
	    length = TMP_SIZE;
	}
	strncpy(tmp, field, length);
	tmp[length] = 0;
	newEl.nameUid = Tk_GetUid(tmp);
	if (isupper(UCHAR(*field))) {
	    newEl.flags |= CLASS;
	}

	if (*p != 0) {







|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
	while ((*p != 0) && (*p != '.') && (*p != '*')) {
	    p++;
	}
	length = p - field;
	if (length > TMP_SIZE) {
	    length = TMP_SIZE;
	}
	strncpy(tmp, field, (size_t) length);
	tmp[length] = 0;
	newEl.nameUid = Tk_GetUid(tmp);
	if (isupper(UCHAR(*field))) {
	    newEl.flags |= CLASS;
	}

	if (*p != 0) {
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 *--------------------------------------------------------------
 */

Tk_Uid
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;
    const char *masqName;
    Element *elPtr, *bestPtr;
    int count;
    StackLevel *levelPtr;
    int stackDepth[NUM_STACKS];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Note: no need to call OptionInit here: it will be done by the







|
|





|
|







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 *--------------------------------------------------------------
 */

Tk_Uid
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;
    const char *masqName;
    register Element *elPtr, *bestPtr;
    register int count;
    StackLevel *levelPtr;
    int stackDepth[NUM_STACKS];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Note: no need to call OptionInit here: it will be done by the
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    }

    /*
     * Probe the stacks for matches.
     */

    for (elPtr = tsdPtr->stacks[EXACT_LEAF_NAME]->els,
	    count = stackDepth[EXACT_LEAF_NAME]; count > 0;
	    elPtr++, count--) {
	if ((elPtr->nameUid == nameId)
		&& (elPtr->priority > bestPtr->priority)) {
	    bestPtr = elPtr;
	}
    }
    for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_NAME]->els,
	    count = stackDepth[WILDCARD_LEAF_NAME]; count > 0;
	    elPtr++, count--) {
	if ((elPtr->nameUid == nameId)
		&& (elPtr->priority > bestPtr->priority)) {
	    bestPtr = elPtr;
	}
    }

    if (className != NULL) {
	classId = Tk_GetUid(className);
	for (elPtr = tsdPtr->stacks[EXACT_LEAF_CLASS]->els,
		count = stackDepth[EXACT_LEAF_CLASS]; count > 0;
		elPtr++, count--) {
	    if ((elPtr->nameUid == classId)
		    && (elPtr->priority > bestPtr->priority)) {
		bestPtr = elPtr;
	    }
	}
	for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_CLASS]->els,
		count = stackDepth[WILDCARD_LEAF_CLASS]; count > 0;
		elPtr++, count--) {
	    if ((elPtr->nameUid == classId)
		    && (elPtr->priority > bestPtr->priority)) {
		bestPtr = elPtr;
	    }
	}
    }

    /*
     * 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.
     */

    if (masqName != NULL) {
	char *masqClass;
	Tk_Uid nodeId, winClassId, winNameId;
	TkSizeT classNameLength;
	Element *nodePtr, *leafPtr;
	static const int searchOrder[] = {
	    EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
	    WILDCARD_NODE_CLASS, -1
	};
	const int *currentPtr;
	int currentStack, leafCount;

	/*
	 * Extract the masquerade class name from the name field.
	 */

	classNameLength	= masqName - name;
	masqClass = (char *)ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	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];







|
|






|
|









|
|






|
|

















|
|
|



<
|





|
|





|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    }

    /*
     * Probe the stacks for matches.
     */

    for (elPtr = tsdPtr->stacks[EXACT_LEAF_NAME]->els,
	     count = stackDepth[EXACT_LEAF_NAME]; count > 0;
	 elPtr++, count--) {
	if ((elPtr->nameUid == nameId)
		&& (elPtr->priority > bestPtr->priority)) {
	    bestPtr = elPtr;
	}
    }
    for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_NAME]->els,
	     count = stackDepth[WILDCARD_LEAF_NAME]; count > 0;
	 elPtr++, count--) {
	if ((elPtr->nameUid == nameId)
		&& (elPtr->priority > bestPtr->priority)) {
	    bestPtr = elPtr;
	}
    }

    if (className != NULL) {
	classId = Tk_GetUid(className);
	for (elPtr = tsdPtr->stacks[EXACT_LEAF_CLASS]->els,
		 count = stackDepth[EXACT_LEAF_CLASS]; count > 0;
	     elPtr++, count--) {
	    if ((elPtr->nameUid == classId)
		    && (elPtr->priority > bestPtr->priority)) {
		bestPtr = elPtr;
	    }
	}
	for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_CLASS]->els,
		 count = stackDepth[WILDCARD_LEAF_CLASS]; count > 0;
	     elPtr++, count--) {
	    if ((elPtr->nameUid == classId)
		    && (elPtr->priority > bestPtr->priority)) {
		bestPtr = elPtr;
	    }
	}
    }

    /*
     * 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.
     */

    if (masqName != NULL) {
	char *masqClass;
	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
	};

	int *currentPtr, currentStack, leafCount;

	/*
	 * Extract the masquerade class name from the name field.
	 */

	classNameLength	= (unsigned int)(masqName - name);
	masqClass = (char *) ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	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];
609
610
611
612
613
614
615
616
617
618
619
620
621

622
623
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
 */

int
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));

    static const char *const optionCmds[] = {
	"add", "clear", "get", "readfile", NULL
    };

    enum optionVals {
	OPTION_ADD, OPTION_CLEAR, OPTION_GET, OPTION_READFILE
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "cmd arg ?arg ...?");
	return TCL_ERROR;
    }

    result = Tcl_GetIndexFromObjStruct(interp, objv[1], optionCmds,
	    sizeof(char *), "option", 0, &index);
    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?");
	    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;
    }

    case OPTION_CLEAR: {
	TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;

	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, "");
	    return TCL_ERROR;
	}

	if (mainPtr->optionRootPtr != NULL) {
	    ClearOptionTree(mainPtr->optionRootPtr);
	    mainPtr->optionRootPtr = NULL;
	}
	tsdPtr->cachedWindow = NULL;
	break;
    }







|

|



>
|


>









|
|








<



















|





>







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
 */

int
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));

    static CONST char *optionCmds[] = {
	"add", "clear", "get", "readfile", NULL
    };

    enum optionVals {
	OPTION_ADD, OPTION_CLEAR, OPTION_GET, OPTION_READFILE
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "cmd arg ?arg ...?");
	return TCL_ERROR;
    }

    result = Tcl_GetIndexFromObj(interp, objv[1], optionCmds, "option", 0,
	    &index);
    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?");
	    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;
    }

    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;
    }
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	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_SetObjResult(interp, Tcl_NewStringObj(value, -1));
	}
	break;
    }

    case OPTION_READFILE: {
	int priority;








|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
	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;

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
 *	Option-related resources are freed. See code below for details.
 *
 *--------------------------------------------------------------
 */

void
TkOptionDeadWindow(
    TkWindow *winPtr)	/* Window to be cleaned up. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * If this window is in the option stacks, then clear the stacks.
     *







|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
 *	Option-related resources are freed. See code below for details.
 *
 *--------------------------------------------------------------
 */

void
TkOptionDeadWindow(
    register TkWindow *winPtr)	/* Window to be cleaned up. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * If this window is in the option stacks, then clear the stacks.
     *
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
 *
 *----------------------------------------------------------------------
 */

static int
ParsePriority(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    const char *string)		/* Describes a priority level, either
				 * symbolically or numerically. */
{
    int priority, c;
    size_t length;

    c = string[0];
    length = strlen(string);







|







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
 *
 *----------------------------------------------------------------------
 */

static int
ParsePriority(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    char *string)		/* Describes a priority level, either
				 * symbolically or numerically. */
{
    int priority, c;
    size_t length;

    c = string[0];
    length = strlen(string);
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
	return TK_INTERACTIVE_PRIO;
    } else {
	char *end;

	priority = strtoul(string, &end, 0);
	if ((end == string) || (*end != 0) || (priority < 0)
		|| (priority > 100)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad priority level \"%s\": must be "
		    "widgetDefault, startupFile, userDefault, "
		    "interactive, or a number between 0 and 100", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "PRIORITY", NULL);
	    return -1;
	}
    }
    return priority;
}

/*







<
|
|
|
<







874
875
876
877
878
879
880

881
882
883

884
885
886
887
888
889
890
	return TK_INTERACTIVE_PRIO;
    } else {
	char *end;

	priority = strtoul(string, &end, 0);
	if ((end == string) || (*end != 0) || (priority < 0)
		|| (priority > 100)) {

	    Tcl_AppendResult(interp, "bad priority level \"", string,
		    "\": must be widgetDefault, startupFile, userDefault, ",
		    "interactive, or a number between 0 and 100", NULL);

	    return -1;
	}
    }
    return priority;
}

/*
918
919
920
921
922
923
924
925
926
927
928
929
930
931

932
933
934
935
936
937
938
				 * 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. */
{
    char *src, *dst;
    char *name, *value;
    int lineNum;

    src = string;
    lineNum = 1;
    while (1) {

	/*
	 * Skip leading white space and empty lines and comment lines, and
	 * check for the end of the spec.
	 */

	while ((*src == ' ') || (*src == '\t')) {
	    src++;







|






>







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
				 * 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;
    int lineNum;

    src = string;
    lineNum = 1;
    while (1) {

	/*
	 * Skip leading white space and empty lines and comment lines, and
	 * check for the end of the spec.
	 */

	while ((*src == ' ') || (*src == '\t')) {
	    src++;
959
960
961
962
963
964
965

966
967
968
969
970
971
972
973
974
975
	 * Parse off the option name, collapsing out backslash-newline
	 * sequences of course.
	 */

	dst = name = src;
	while (*src != ':') {
	    if ((*src == '\0') || (*src == '\n')) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"missing colon on line %d", lineNum));
		Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "COLON", NULL);
		return TCL_ERROR;
	    }
	    if ((src[0] == '\\') && (src[1] == '\n')) {
		src += 2;
		lineNum++;
	    } else {
		*dst = *src;







>
|
|
|







959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
	 * Parse off the option name, collapsing out backslash-newline
	 * sequences of course.
	 */

	dst = name = src;
	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;
	    }
	    if ((src[0] == '\\') && (src[1] == '\n')) {
		src += 2;
		lineNum++;
	    } else {
		*dst = *src;
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;
	}
	if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) {
	    src++;
	}
	if (*src == '\0') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "missing value on line %d", lineNum));
	    Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Parse off the value, squeezing out backslash-newline sequences
	 * along the way.
	 */

	dst = value = src;
	while (*src != '\n') {
	    if (*src == '\0') {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"missing newline on line %d", lineNum));
		Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "NEWLINE", NULL);
		return TCL_ERROR;
	    }
	    if (*src == '\\'){
		if (src[1] == '\n') {
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}







|
|
|
<
<
|
|











>
|
|
|











|







993
994
995
996
997
998
999
1000
1001
1002


1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;
	}
	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;
	}

	/*
	 * Parse off the value, squeezing out backslash-newline sequences
	 * along the way.
	 */

	dst = value = src;
	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;
	    }
	    if (*src == '\\'){
		if (src[1] == '\n') {
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114




1115


1116





1117


1118
1119
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135
 */

static int
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. */
    const 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;
    Tcl_Obj *buffer;
    int result;
    TkSizeT bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't read options from a file in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "OPTION_FILE", NULL);
	return TCL_ERROR;
    }

    realName = Tcl_TranslateFileName(interp, fileName, &newName);
    if (realName == NULL) {
	return TCL_ERROR;
    }
    chan = Tcl_OpenFileChannel(interp, realName, "r", 0);
    Tcl_DStringFree(&newName);
    if (chan == NULL) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't open \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	return TCL_ERROR;
    }





    buffer = Tcl_NewObj();


    Tcl_IncrRefCount(buffer);





    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");


    bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
    if (bufferSize == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);

    result = AddFromString(interp, tkwin, Tcl_GetString(buffer), priority);
    Tcl_DecrRefCount(buffer);
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * NewArray --







|





|
|
|
<








<
|
|










>
|
|



>
>
>
>
|
>
>
|
>
>
>
>
>
|
>
>
|
|
<
|
|




>
|
|







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
 */

static int
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;
    int result, bufferSize;

    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * 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", NULL);
	return TCL_ERROR;
    }

    realName = Tcl_TranslateFileName(interp, fileName, &newName);
    if (realName == NULL) {
	return TCL_ERROR;
    }
    chan = Tcl_OpenFileChannel(interp, realName, "r", 0);
    Tcl_DStringFree(&newName);
    if (chan == NULL) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "couldn't open \"", fileName,
		"\": ", Tcl_PosixError(interp), NULL);
	return TCL_ERROR;
    }

    /*
     * 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), NULL);
	Tcl_Close(NULL, chan);
	return TCL_ERROR;

    }
    buffer = (char *) ckalloc((unsigned) bufferSize+1);
    bufferSize = Tcl_Read(chan, buffer, bufferSize);
    if (bufferSize < 0) {

	Tcl_AppendResult(interp, "error reading file \"", fileName, "\":",
		Tcl_PosixError(interp), NULL);
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);
    buffer[bufferSize] = 0;
    result = AddFromString(interp, tkwin, buffer, priority);
    ckfree(buffer);
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * NewArray --
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
 *--------------------------------------------------------------
 */

static ElArray *
NewArray(
    int numEls)			/* How many elements of space to allocate. */
{
    ElArray *arrayPtr = (ElArray *)ckalloc(EL_ARRAY_SIZE(numEls));


    arrayPtr->arraySize = numEls;
    arrayPtr->numUsed = 0;
    arrayPtr->nextToUse = arrayPtr->els;
    return arrayPtr;
}

/*







|

>







1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
 *--------------------------------------------------------------
 */

static ElArray *
NewArray(
    int numEls)			/* How many elements of space to allocate. */
{
    register ElArray *arrayPtr;

    arrayPtr = (ElArray *) ckalloc(EL_ARRAY_SIZE(numEls));
    arrayPtr->arraySize = numEls;
    arrayPtr->numUsed = 0;
    arrayPtr->nextToUse = arrayPtr->els;
    return arrayPtr;
}

/*
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190




1191

1192
1193
1194
1195
1196
1197
1198
1199
 *	Memory may be allocated or freed.
 *
 *--------------------------------------------------------------
 */

static ElArray *
ExtendArray(
    ElArray *arrayPtr,	/* Array to be extended. */
    Element *elPtr)	/* Element to be copied into array. */
{
    /*
     * If the current array has filled up, make it bigger.
     */

    if (arrayPtr->numUsed >= arrayPtr->arraySize) {
	int newSize = 2*arrayPtr->arraySize;

	arrayPtr = (ElArray *)ckrealloc(arrayPtr, EL_ARRAY_SIZE(newSize));




	arrayPtr->arraySize = newSize;

	arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed];
    }

    *arrayPtr->nextToUse = *elPtr;
    arrayPtr->nextToUse++;
    arrayPtr->numUsed++;
    return arrayPtr;
}







|
|






|

|
>
>
>
>
|
>
|







1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
 *	Memory may be allocated or freed.
 *
 *--------------------------------------------------------------
 */

static ElArray *
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.
     */

    if (arrayPtr->numUsed >= arrayPtr->arraySize) {
	register ElArray *newPtr;

	newPtr = (ElArray *) ckalloc(EL_ARRAY_SIZE(2*arrayPtr->arraySize));
	newPtr->arraySize = 2*arrayPtr->arraySize;
	newPtr->numUsed = arrayPtr->numUsed;
	newPtr->nextToUse = &newPtr->els[newPtr->numUsed];
	memcpy(newPtr->els, arrayPtr->els,
		arrayPtr->arraySize * sizeof(Element));
	ckfree((char *) arrayPtr);
	arrayPtr = newPtr;
    }

    *arrayPtr->nextToUse = *elPtr;
    arrayPtr->nextToUse++;
    arrayPtr->numUsed++;
    return arrayPtr;
}
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
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;
    const int *iPtr;
    StackLevel *levelPtr;
    ElArray *arrayPtr;
    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.
     */

    static const int searchOrder[] = {WILDCARD_NODE_CLASS, WILDCARD_NODE_NAME,
	    EXACT_NODE_CLASS, EXACT_NODE_NAME, -1};

    if (winPtr->mainPtr->optionRootPtr == NULL) {
	OptionInit(winPtr->mainPtr);
    }

    /*







|
<
|
|












|







1238
1239
1240
1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
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));

    /*
     * 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,
	    EXACT_NODE_CLASS, EXACT_NODE_NAME, -1};

    if (winPtr->mainPtr->optionRootPtr == NULL) {
	OptionInit(winPtr->mainPtr);
    }

    /*
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310


1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
    /*
     * 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 = (StackLevel *)
		ckalloc(tsdPtr->numLevels * 2 * sizeof(StackLevel));



	memcpy(newLevels, tsdPtr->levels,
		tsdPtr->numLevels * sizeof(StackLevel));
	ckfree(tsdPtr->levels);
	tsdPtr->numLevels *= 2;
	tsdPtr->levels = newLevels;
    }
    levelPtr = &tsdPtr->levels[tsdPtr->curLevel];
    levelPtr->winPtr = winPtr;
    arrayPtr = tsdPtr->stacks[EXACT_LEAF_NAME];
    arrayPtr->numUsed = 0;







|
<

>
>


|







1318
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
    /*
     * 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(newLevels, tsdPtr->levels,
		tsdPtr->numLevels * sizeof(StackLevel));
	ckfree((char *) tsdPtr->levels);
	tsdPtr->numLevels *= 2;
	tsdPtr->levels = newLevels;
    }
    levelPtr = &tsdPtr->levels[tsdPtr->curLevel];
    levelPtr->winPtr = winPtr;
    arrayPtr = tsdPtr->stacks[EXACT_LEAF_NAME];
    arrayPtr->numUsed = 0;
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342

    /*
     * 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.
     */

    for (iPtr = searchOrder; *iPtr != -1; iPtr++) {
	Element *elPtr;
	int count;
	Tk_Uid id;

	i = *iPtr;
	if (i & CLASS) {
	    id = winPtr->classUid;
	} else {







|







1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360

    /*
     * 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.
     */

    for (iPtr = searchOrder; *iPtr != -1; iPtr++) {
	register Element *elPtr;
	int count;
	Tk_Uid id;

	i = *iPtr;
	if (i & CLASS) {
	    id = winPtr->classUid;
	} else {
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

static void
ExtendStacks(
    ElArray *arrayPtr,		/* Array of elements to copy onto stacks. */
    int leaf)			/* If zero, then don't copy exact leaf
				 * elements. */
{
    int count;
    Element *elPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (elPtr = arrayPtr->els, count = arrayPtr->numUsed;
	    count > 0; elPtr++, count--) {
	if (!(elPtr->flags & (NODE|WILDCARD)) && !leaf) {
	    continue;







|
|







1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416

static void
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));

    for (elPtr = arrayPtr->els, count = arrayPtr->numUsed;
	    count > 0; elPtr++, count--) {
	if (!(elPtr->flags & (NODE|WILDCARD)) && !leaf) {
	    continue;
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
 *	Option-related data structures get freed.
 *
 *--------------------------------------------------------------
 */

static void
OptionThreadExitProc(
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->initialized) {
	int i;

	for (i = 0; i < NUM_STACKS; i++) {
	    ckfree(tsdPtr->stacks[i]);
	}
	ckfree(tsdPtr->levels);
	tsdPtr->initialized = 0;
    }
}

/*
 *--------------------------------------------------------------
 *







|








|

|







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
 *	Option-related data structures get freed.
 *
 *--------------------------------------------------------------
 */

static void
OptionThreadExitProc(
    ClientData clientData)	/* not used */
{
    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]);
	}
	ckfree((char *) tsdPtr->levels);
	tsdPtr->initialized = 0;
    }
}

/*
 *--------------------------------------------------------------
 *
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478

1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
 *	Option-related data structures get initialized.
 *
 *--------------------------------------------------------------
 */

static void
OptionInit(
    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));
    Element *defaultMatchPtr = &tsdPtr->defaultMatch;

    /*
     * First, once-only initialization.
     */

    if (tsdPtr->initialized == 0) {
	tsdPtr->initialized = 1;
	tsdPtr->cachedWindow = NULL;
	tsdPtr->numLevels = 5;
	tsdPtr->curLevel = -1;
	tsdPtr->serial = 0;

	tsdPtr->levels = (StackLevel *)ckalloc(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;
	defaultMatchPtr->flags = 0;
	Tcl_CreateThreadExitHandler(OptionThreadExitProc, NULL);
    }

    /*
     * Then, per-main-window initialization. Create and delete dummy
     * interpreter for message logging.
     */

    mainPtr->optionRootPtr = NewArray(20);
    interp = Tcl_CreateInterp();
    GetDefaultOptions(interp, mainPtr->winPtr);
    Tcl_DeleteInterp(interp);
}

/*
 *--------------------------------------------------------------
 *
 * ClearOptionTree --







|




















|
>



















|







1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
 *	Option-related data structures get initialized.
 *
 *--------------------------------------------------------------
 */

static void
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));
    Element *defaultMatchPtr = &tsdPtr->defaultMatch;

    /*
     * First, once-only initialization.
     */

    if (tsdPtr->initialized == 0) {
	tsdPtr->initialized = 1;
	tsdPtr->cachedWindow = NULL;
	tsdPtr->numLevels = 5;
	tsdPtr->curLevel = -1;
	tsdPtr->serial = 0;

	tsdPtr->levels = (StackLevel *)
		ckalloc((unsigned) (5*sizeof(StackLevel)));
	for (i = 0; i < NUM_STACKS; i++) {
	    tsdPtr->stacks[i] = NewArray(10);
	    tsdPtr->levels[0].bases[i] = 0;
	}

	defaultMatchPtr->nameUid = NULL;
	defaultMatchPtr->child.valueUid = NULL;
	defaultMatchPtr->priority = -1;
	defaultMatchPtr->flags = 0;
	Tcl_CreateThreadExitHandler(OptionThreadExitProc, NULL);
    }

    /*
     * Then, per-main-window initialization. Create and delete dummy
     * interpreter for message logging.
     */

    mainPtr->optionRootPtr = NewArray(20);
    interp = Tcl_CreateInterp();
    (void) GetDefaultOptions(interp, mainPtr->winPtr);
    Tcl_DeleteInterp(interp);
}

/*
 *--------------------------------------------------------------
 *
 * ClearOptionTree --
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
 */

static void
ClearOptionTree(
    ElArray *arrayPtr)		/* Array of options; delete everything
				 * referred to recursively by this. */
{
    Element *elPtr;
    int count;

    for (count = arrayPtr->numUsed, elPtr = arrayPtr->els;  count > 0;
	    count--, elPtr++) {
	if (elPtr->flags & NODE) {
	    ClearOptionTree(elPtr->child.arrayPtr);
	}
    }
    ckfree(arrayPtr);
}

/*
 *--------------------------------------------------------------
 *
 * GetDefaultOptions --
 *







|








|







1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
 */

static void
ClearOptionTree(
    ElArray *arrayPtr)		/* Array of options; delete everything
				 * referred to recursively by this. */
{
    register Element *elPtr;
    int count;

    for (count = arrayPtr->numUsed, elPtr = arrayPtr->els;  count > 0;
	    count--, elPtr++) {
	if (elPtr->flags & NODE) {
	    ClearOptionTree(elPtr->child.arrayPtr);
	}
    }
    ckfree((char *) arrayPtr);
}

/*
 *--------------------------------------------------------------
 *
 * GetDefaultOptions --
 *

Changes to generic/tkPack.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side;
static const char *const sideNames[] = {
    "top", "bottom", "left", "right", NULL
};

/*
 * For each window that the packer cares about (either because the window is
 * managed by the packer or because the window has content that are managed by

 * the packer), there is a structure of the following type:
 */

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 *containerPtr;	/* Container 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 container. List
				 * is priority-ordered: first on list gets
				 * packed first. */
    struct Packer *contentPtr;	/* First in list of content packed inside this
				 * window (NULL means no packed content). */
    Side side;			/* Side of container 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. */
    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:
				 * 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 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 container. */
    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 content 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 content 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 container 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 container then
 *				Tk will set its requested size to fit the
 *				needs of its content.
 * ALLOCED_CONTAINER	1 means that Pack has allocated itself as
 *				geometry container for this window.
 */

#define REQUESTED_REPACK	1
#define FILLX			2
#define FILLY			4
#define EXPAND			8
#define OLD_STYLE		16
#define DONT_PROPAGATE		32
#define ALLOCED_CONTAINER	64

/*
 * The following structure is the official type record for the packer:
 */

static void		PackReqProc(ClientData clientData, Tk_Window tkwin);
static void		PackLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr packerType = {
    "pack",			/* name */
    PackReqProc,		/* requestProc */
    PackLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ArrangePacking(ClientData clientData);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyPacker(void *memPtr);
static Packer *		GetPacker(Tk_Window tkwin);
#ifndef TK_NO_DEPRECATED
static int		PackAfter(Tcl_Interp *interp, Packer *prevPtr,
			    Packer *containerPtr, int objc,Tcl_Obj *const objv[]);
#endif /* !TK_NO_DEPRECATED */
static void		PackStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		Unlink(Packer *packPtr);
static int		XExpansion(Packer *contentPtr, int cavityWidth);
static int		YExpansion(Packer *contentPtr, int cavityHeight);

/*
 *------------------------------------------------------------------------
 *
 * TkAppendPadAmount --
 *
 *	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 given Tcl_Obj.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *------------------------------------------------------------------------
 */

void
TkAppendPadAmount(
    Tcl_Obj *bufferObj,		/* The interpreter into which the result is
				 * written. */
    const char *switchName,	/* One of "padx", "pady", "ipadx" or
				 * "ipady" */
    int halfSpace,		/* The left or top padding amount */
    int allSpace)		/* The total amount of padding */
{
    Tcl_Obj *padding[2];

    if (halfSpace*2 == allSpace) {
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewWideIntObj(halfSpace));
    } else {
	padding[0] = Tcl_NewWideIntObj(halfSpace);
	padding[1] = Tcl_NewWideIntObj(allSpace - halfSpace);
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewListObj(2, padding));
    }

}

/*
 *------------------------------------------------------------------------
 *
 * Tk_PackCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *------------------------------------------------------------------------
 */

int
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;
    const char *argv2;
    static const char *const optionStrings[] = {
#ifndef TK_NO_DEPRECATED
	"after", "append", "before", "unpack",
#endif /* !TK_NO_DEPRECATED */
	"configure", "content", "forget", "info", "propagate", "slaves", NULL };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", "propagate", NULL };
    enum options {
#ifndef TK_NO_DEPRECATED
	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,
#endif /* !TK_NO_DEPRECATED */
	PACK_CONFIGURE, PACK_CONTENT, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
    int index;

    if (objc >= 2) {
	const char *string = Tcl_GetString(objv[1]);

	if (string[0] == '.') {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(NULL, objv[1], optionStrings,
	    sizeof(char *), "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
	 * deprecated and new options.
	 */


	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    argv2 = Tcl_GetString(objv[2]);
    switch ((enum options) index) {
#ifndef TK_NO_DEPRECATED
    case PACK_AFTER: {
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	prevPtr = GetPacker(tkwin2);
	if (prevPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	return PackAfter(interp, prevPtr, prevPtr->containerPtr, objc-3, objv+3);
    }
    case PACK_APPEND: {
	Packer *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = GetPacker(tkwin2);
	prevPtr = containerPtr->contentPtr;
	if (prevPtr != NULL) {
	    while (prevPtr->nextPtr != NULL) {
		prevPtr = prevPtr->nextPtr;
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
    case PACK_BEFORE: {
	Packer *packPtr, *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if (packPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	containerPtr = packPtr->containerPtr;
	prevPtr = containerPtr->contentPtr;
	if (prevPtr == packPtr) {
	    prevPtr = NULL;
	} else {
	    for ( ; ; prevPtr = prevPtr->nextPtr) {
		if (prevPtr == NULL) {
		    Tcl_Panic("\"pack before\" couldn't find predecessor");
		}
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
#endif /* !TK_NO_DEPRECATED */
    case PACK_CONFIGURE:
	if (argv2[0] != '.') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument \"%s\": must be name of window", argv2));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	    return TCL_ERROR;
	}
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case PACK_FORGET: {
	Tk_Window content;
	Packer *contentPtr;
	int i;

	for (i = 2; i < objc; i++) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		continue;
	    }
	    contentPtr = GetPacker(content);
	    if ((contentPtr != NULL) && (contentPtr->containerPtr != NULL)) {
		Tk_ManageGeometry(content, NULL, NULL);

		if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		    Tk_UnmaintainGeometry(contentPtr->tkwin,
			    contentPtr->containerPtr->tkwin);
		}
		Unlink(contentPtr);
		Tk_UnmapWindow(contentPtr->tkwin);
	    }
	}
	break;
    }
    case PACK_INFO: {
	Packer *contentPtr;
	Tk_Window content;
	Tcl_Obj *infoObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	contentPtr = GetPacker(content);
	if (contentPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}

	infoObj = Tcl_NewObj();
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1),
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), -1));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1),
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("none", -1));
	    break;
	case FILLX:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("x", -1));
	    break;
	case FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("y", -1));
	    break;
	case FILLX|FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("both", -1));
	    break;
	}
	TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
	TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
	TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft,contentPtr->padX);
	TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-side", -1),
		Tcl_NewStringObj(sideNames[contentPtr->side], -1));
	Tcl_SetObjResult(interp, infoObj);
	break;
    }
    case PACK_PROPAGATE: {
	Tk_Window container;
	Packer *containerPtr;
	int propagate;

	if (objc > 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = GetPacker(container);
	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (propagate) {
	    /*
	     * If we have content windows, we need to register as geometry container.
	     */

	    if (containerPtr->contentPtr != NULL) {
		if (TkSetGeometryContainer(interp, container, "pack") != TCL_OK) {
		    return TCL_ERROR;
		}
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	    containerPtr->flags &= ~DONT_PROPAGATE;

	    /*
	     * Repack the container to allow new geometry information to
	     * propagate upwards to the container's container.
	     */

	    if (containerPtr->abortPtr != NULL) {
		*containerPtr->abortPtr = 1;
	    }
	    if (!(containerPtr->flags & REQUESTED_REPACK)) {
		containerPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	    }
	} else {
	    if (containerPtr->flags & ALLOCED_CONTAINER) {
		TkFreeGeometryContainer(container, "pack");
		containerPtr->flags &= ~ALLOCED_CONTAINER;
	    }
	    containerPtr->flags |= DONT_PROPAGATE;
	}
	break;
    }
    case PACK_SLAVES:
    case PACK_CONTENT: {
	Tk_Window container;
	Packer *containerPtr, *contentPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	containerPtr = GetPacker(container);
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
#ifndef TK_NO_DEPRECATED
    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if ((packPtr != NULL) && (packPtr->containerPtr != NULL)) {
	    Tk_ManageGeometry(tkwin2, NULL, NULL);

	    if (packPtr->containerPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
		Tk_UnmaintainGeometry(packPtr->tkwin,
			packPtr->containerPtr->tkwin);
	    }
	    Unlink(packPtr);
	    Tk_UnmapWindow(packPtr->tkwin);
	}
	break;
    }
#endif /* !TK_NO_DEPRECATED */
    }

    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * PackReqProc --
 *
 *	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.
 *
 *------------------------------------------------------------------------
 */


static void
PackReqProc(
    ClientData clientData,	/* Packer's information about window that got
				 * new preferred geometry.  */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Packer *packPtr = (Packer *)clientData;

    packPtr = packPtr->containerPtr;
    if (!(packPtr->flags & REQUESTED_REPACK)) {
	packPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, packPtr);
    }
}

/*
 *------------------------------------------------------------------------
 *
 * PackLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all packer-related information about the content.
 *
 *------------------------------------------------------------------------
 */


static void
PackLostContentProc(
    void *clientData,	/* Packer structure for content window that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Packer *contentPtr = (Packer *)clientData;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Unlink(contentPtr);
    Tk_UnmapWindow(contentPtr->tkwin);
}

/*
 *------------------------------------------------------------------------
 *
 * ArrangePacking --
 *
 *	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 content of containerPtr may get resized or moved.
 *
 *------------------------------------------------------------------------
 */

static void
ArrangePacking(
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Packer *containerPtr = (Packer *)clientData;
    Packer *contentPtr;
    int cavityX, cavityY, cavityWidth, cavityHeight;
				/* These variables keep track of the
				 * as-yet-unallocated space remaining in the
				 * middle of the container 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 abort;			/* May get set to non-zero to abort this
				 * repacking operation. */
    int borderX, borderY;
    int borderTop, borderBtm;
    int borderLeft, borderRight;
    int maxWidth, maxHeight, tmp;

    containerPtr->flags &= ~REQUESTED_REPACK;

    /*

     * If the container has no content anymore, then leave the container's size as-is.
     * Otherwise there is no way to "relinquish" control over the container
     * so another geometry manager can take over.
     */

    if (containerPtr->contentPtr == NULL) {
	return;
    }

    /*
     * 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 (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(containerPtr);

    /*
     * Pass #1: scan all the content 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
     *			content seen so far that were packed LEFT or RIGHT.
     * height -		Holds the sum of the heights (plus padding) of all the
     *			content seen so far that were packed TOP or BOTTOM.
     *
     * maxWidth -	Gradually builds up the width needed by the container to
     *			just barely satisfy all the content's needs. For each
     *			content, the code computes the width needed for all the
     *			content so far and updates maxWidth if the new value is
     *			greater.
     * maxHeight -	Same as maxWidth, except keeps height info.
     */

    width = maxWidth = Tk_InternalBorderLeft(containerPtr->tkwin) +
	    Tk_InternalBorderRight(containerPtr->tkwin);
    height = maxHeight = Tk_InternalBorderTop(containerPtr->tkwin) +
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    tmp = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX + width;
	    if (tmp > maxWidth) {
		maxWidth = tmp;
	    }
	    height += Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY;
	} else {
	    tmp = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY + height;
	    if (tmp > maxHeight) {
		maxHeight = tmp;
	    }
	    width += Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX;
	}
    }
    if (width > maxWidth) {
	maxWidth = width;
    }
    if (height > maxHeight) {
	maxHeight = height;
    }

    if (maxWidth < Tk_MinReqWidth(containerPtr->tkwin)) {
	maxWidth = Tk_MinReqWidth(containerPtr->tkwin);
    }
    if (maxHeight < Tk_MinReqHeight(containerPtr->tkwin)) {
	maxHeight = Tk_MinReqHeight(containerPtr->tkwin);
    }

    /*
     * If the total amount of space needed in the container 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
     * container has had a chance to resize us.
     */

    if (((maxWidth != Tk_ReqWidth(containerPtr->tkwin))
	    || (maxHeight != Tk_ReqHeight(containerPtr->tkwin)))
	    && !(containerPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(containerPtr->tkwin, maxWidth, maxHeight);
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	goto done;
    }

    /*
     * Pass #2: scan the content 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(containerPtr->tkwin);
    cavityY = y = Tk_InternalBorderTop(containerPtr->tkwin);
    cavityWidth = Tk_Width(containerPtr->tkwin) -
	    Tk_InternalBorderLeft(containerPtr->tkwin) -
	    Tk_InternalBorderRight(containerPtr->tkwin);
    cavityHeight = Tk_Height(containerPtr->tkwin) -
	    Tk_InternalBorderTop(containerPtr->tkwin) -
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    frameWidth = cavityWidth;
	    frameHeight = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY;
	    if (contentPtr->flags & EXPAND) {
		frameHeight += YExpansion(contentPtr, cavityHeight);
	    }
	    cavityHeight -= frameHeight;
	    if (cavityHeight < 0) {
		frameHeight += cavityHeight;
		cavityHeight = 0;
	    }
	    frameX = cavityX;
	    if (contentPtr->side == TOP) {
		frameY = cavityY;
		cavityY += frameHeight;
	    } else {
		frameY = cavityY + cavityHeight;
	    }
	} else {
	    frameHeight = cavityHeight;
	    frameWidth = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX;
	    if (contentPtr->flags & EXPAND) {
		frameWidth += XExpansion(contentPtr, cavityWidth);
	    }
	    cavityWidth -= frameWidth;
	    if (cavityWidth < 0) {
		frameWidth += cavityWidth;
		cavityWidth = 0;
	    }
	    frameY = cavityY;
	    if (contentPtr->side == LEFT) {
		frameX = cavityX;
		cavityX += frameWidth;
	    } else {
		frameX = cavityX + cavityWidth;
	    }
	}

	/*
	 * 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 (contentPtr->flags & OLD_STYLE) {
	    borderX = borderY = 0;
	    borderTop = borderBtm = 0;
	    borderLeft = borderRight = 0;
	} else {
	    borderX = contentPtr->padX;
	    borderY = contentPtr->padY;
	    borderLeft = contentPtr->padLeft;
	    borderRight = borderX - borderLeft;
	    borderTop = contentPtr->padTop;
	    borderBtm = borderY - borderTop;
	}
	width = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->iPadX;
	if ((contentPtr->flags & FILLX)
		|| (width > (frameWidth - borderX))) {
	    width = frameWidth - borderX;
	}
	height = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->iPadY;
	if ((contentPtr->flags & FILLY)
		|| (height > (frameHeight - borderY))) {
	    height = frameHeight - borderY;
	}
	switch (contentPtr->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;







|



<
|
|
>
|







|


|
|
|
|
|
|

















|





|








|







|





|

|
<
<








<






|





|







|
|
|

<

|
<



|
|


|

|



|







|



|
|

|
<



<
|

<
|

|
|
<
<

>



|












|







|

|
|
|
|

<
|
<
<

<

<
|



|
<

|







|
|






>
|
|





<








|
|
|
<


|


|
|





|
|





|


|
|






|
|
|
<


|
|












|

<


|
|
<


|

|
|



|


|
|
|
>
|
|
|

|
|





|
|
<





|


|
|
|
|
<


|
<
<
|
|
|
|
|
|

<
|


<
|


<
|


<
|


|
|
|
|
<
<
|



|
|






|


|


|






<
<
<
<
<
<
<
<
<
<
|


|
|


|
|

|
|
|


<
<
<
<
|



|
<
|
|
<





|


<
|
|
|
|
<

<


<












|
|
>
|

|






<






|













|


>




|


|

|


|




|

|


|





|

|


>

|
|

|

|

|
|

|
|



|












|

|




|


|
|



|












|


>
|
<
<


|









|
|

|

|


|



|

|

|
|
|
|




|
|
|
|
|
|
|
|
|



|
|

|
|



|
|









|
|

|
|



|


|


|
|
|
|
|
|




|







|
|
|
|
|
|
|
|
|
|
|

|
|
|
|







|







|
|
|
|







|
















|




|
|
|

|


|
|
|



|
|
|



|







10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155

156
157

158
159
160
161


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195


196

197

198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334

335
336
337


338
339
340
341
342
343
344

345
346
347

348
349
350

351
352
353

354
355
356
357
358
359
360


361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385










386
387
388
389
390
391
392
393
394
395
396
397
398
399
400




401
402
403
404
405

406
407

408
409
410
411
412
413
414
415

416
417
418
419

420

421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566


567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side;
static CONST char *sideNames[] = {
    "top", "bottom", "left", "right", NULL
};


/* For each window that the packer cares about (either because
 * the window is managed by the packer or because the window
 * has slaves that are managed by the packer), there is a
 * structure of the following type:
 */

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 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. */
    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:
				 * 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 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 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.
 * FILLY:			Same as FILLX, except for height.
 * EXPAND:			1 means this window's frame will absorb any
 *				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.


 */

#define REQUESTED_REPACK	1
#define FILLX			2
#define FILLY			4
#define EXPAND			8
#define OLD_STYLE		16
#define DONT_PROPAGATE		32


/*
 * The following structure is the official type record for the packer:
 */

static void		PackReqProc(ClientData clientData, Tk_Window tkwin);
static void		PackLostSlaveProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr packerType = {
    "pack",			/* name */
    PackReqProc,		/* requestProc */
    PackLostSlaveProc,		/* lostSlaveProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

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 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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

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) {

	sprintf(buffer, " -%.10s %d", switchName, halfSpace);
    } else {
	sprintf(buffer, " -%.10s {%d %d}", switchName, halfSpace,
		allSpace - halfSpace);


    }
    Tcl_AppendResult(interp, buffer, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PackCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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", NULL };


    enum options {

	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,

	PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
    int index;

    if (objc >= 2) {
	char *string = Tcl_GetString(objv[1]);

	if (string[0] == '.') {
	    return ConfigureSlaves(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    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
	 * deprecated and new options.
	 */

	Tcl_ResetResult(interp);
	Tcl_GetIndexFromObj(interp, objv[1], &optionStrings[4], "option", 0,
		&index);
	return TCL_ERROR;
    }

    argv2 = Tcl_GetString(objv[2]);
    switch ((enum options) index) {

    case PACK_AFTER: {
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	prevPtr = GetPacker(tkwin2);
	if (prevPtr->masterPtr == NULL) {
	    Tcl_AppendResult(interp, "window \"", argv2,
		    "\" isn't packed", NULL);

	    return TCL_ERROR;
	}
	return PackAfter(interp, prevPtr, prevPtr->masterPtr, objc-3, objv+3);
    }
    case PACK_APPEND: {
	Packer *masterPtr;
	register Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = GetPacker(tkwin2);
	prevPtr = masterPtr->slavePtr;
	if (prevPtr != NULL) {
	    while (prevPtr->nextPtr != NULL) {
		prevPtr = prevPtr->nextPtr;
	    }
	}
	return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
    }
    case PACK_BEFORE: {
	Packer *packPtr, *masterPtr;
	register Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if (packPtr->masterPtr == NULL) {
	    Tcl_AppendResult(interp, "window \"", argv2,
		    "\" isn't packed", NULL);

	    return TCL_ERROR;
	}
	masterPtr = packPtr->masterPtr;
	prevPtr = masterPtr->slavePtr;
	if (prevPtr == packPtr) {
	    prevPtr = NULL;
	} else {
	    for ( ; ; prevPtr = prevPtr->nextPtr) {
		if (prevPtr == NULL) {
		    Tcl_Panic("\"pack before\" couldn't find predecessor");
		}
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
    }

    case PACK_CONFIGURE:
	if (argv2[0] != '.') {
	    Tcl_AppendResult(interp, "bad argument \"", argv2,
		    "\": must be name of window", NULL);

	    return TCL_ERROR;
	}
	return ConfigureSlaves(interp, tkwin, objc-2, objv+2);
    case PACK_FORGET: {
	Tk_Window slave;
	Packer *slavePtr;
	int i;

	for (i = 2; i < objc; i++) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
		continue;
	    }
	    slavePtr = GetPacker(slave);
	    if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
		Tk_ManageGeometry(slave, NULL,
			(ClientData) NULL);
		if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
		    Tk_UnmaintainGeometry(slavePtr->tkwin,
			    slavePtr->masterPtr->tkwin);
		}
		Unlink(slavePtr);
		Tk_UnmapWindow(slavePtr->tkwin);
	    }
	}
	break;
    }
    case PACK_INFO: {
	register Packer *slavePtr;
	Tk_Window slave;


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &slave) != TCL_OK) {
	    return TCL_ERROR;
	}
	slavePtr = GetPacker(slave);
	if (slavePtr->masterPtr == NULL) {
	    Tcl_AppendResult(interp, "window \"", argv2,
		    "\" isn't packed", NULL);

	    return TCL_ERROR;
	}
	Tcl_AppendElement(interp, "-in");


	Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin));
	Tcl_AppendElement(interp, "-anchor");
	Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor));
	Tcl_AppendResult(interp, " -expand ",
		(slavePtr->flags & EXPAND) ? "1" : "0", " -fill ", NULL);
	switch (slavePtr->flags & (FILLX|FILLY)) {
	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], NULL);
	break;
    }
    case PACK_PROPAGATE: {
	Tk_Window master;
	Packer *masterPtr;
	int propagate;

	if (objc > 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = GetPacker(master);
	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(!(masterPtr->flags & DONT_PROPAGATE)));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (propagate) {










	    masterPtr->flags &= ~DONT_PROPAGATE;

	    /*
	     * Repack the master to allow new geometry information to
	     * propagate upwards to the master's master.
	     */

	    if (masterPtr->abortPtr != NULL) {
		*masterPtr->abortPtr = 1;
	    }
	    if (!(masterPtr->flags & REQUESTED_REPACK)) {
		masterPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr);
	    }
	} else {




	    masterPtr->flags |= DONT_PROPAGATE;
	}
	break;
    }
    case PACK_SLAVES: {

	Tk_Window master;
	Packer *masterPtr, *slavePtr;


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	    return TCL_ERROR;
	}

	masterPtr = GetPacker(master);
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin));

	}

	break;
    }

    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if ((packPtr != NULL) && (packPtr->masterPtr != NULL)) {
	    Tk_ManageGeometry(tkwin2, NULL,
		    (ClientData) NULL);
	    if (packPtr->masterPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
		Tk_UnmaintainGeometry(packPtr->tkwin,
			packPtr->masterPtr->tkwin);
	    }
	    Unlink(packPtr);
	    Tk_UnmapWindow(packPtr->tkwin);
	}
	break;
    }

    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PackReqProc --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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;

    packPtr = packPtr->masterPtr;
    if (!(packPtr->flags & REQUESTED_REPACK)) {
	packPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PackLostSlaveProc --
 *
 *	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 packer-related information about the slave.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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;

    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
    }
    Unlink(slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
}

/*
 *--------------------------------------------------------------
 *
 * ArrangePacking --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePacking(
    ClientData clientData)	/* Structure describing master whose slaves
				 * are to be re-layed out. */
{
    register Packer *masterPtr = (Packer *) clientData;
    register Packer *slavePtr;
    int cavityX, cavityY, cavityWidth, cavityHeight;
				/* These variables keep track of the
				 * 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 abort;			/* May get set to non-zero to abort this
				 * repacking operation. */
    int borderX, borderY;
    int borderTop, borderBtm;
    int borderLeft, borderRight;
    int maxWidth, maxHeight, tmp;

    masterPtr->flags &= ~REQUESTED_REPACK;

    /*
     * 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) {
	return;
    }

    /*
     * 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) {
	*masterPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    abort = 0;
    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:
     *
     * 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.
     * maxHeight -	Same as maxWidth, except keeps height info.
     */

    width = maxWidth = Tk_InternalBorderLeft(masterPtr->tkwin) +
	    Tk_InternalBorderRight(masterPtr->tkwin);
    height = maxHeight = Tk_InternalBorderTop(masterPtr->tkwin) +
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {
	    tmp = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX + width;
	    if (tmp > maxWidth) {
		maxWidth = tmp;
	    }
	    height += Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY;
	} else {
	    tmp = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY + height;
	    if (tmp > maxHeight) {
		maxHeight = tmp;
	    }
	    width += Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX;
	}
    }
    if (width > maxWidth) {
	maxWidth = width;
    }
    if (height > maxHeight) {
	maxHeight = height;
    }

    if (maxWidth < Tk_MinReqWidth(masterPtr->tkwin)) {
	maxWidth = Tk_MinReqWidth(masterPtr->tkwin);
    }
    if (maxHeight < Tk_MinReqHeight(masterPtr->tkwin)) {
	maxHeight = Tk_MinReqHeight(masterPtr->tkwin);
    }

    /*
     * 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))
	    || (maxHeight != Tk_ReqHeight(masterPtr->tkwin)))
	    && !(masterPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(masterPtr->tkwin, maxWidth, maxHeight);
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr);
	goto done;
    }

    /*
     * 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);
    cavityY = y = Tk_InternalBorderTop(masterPtr->tkwin);
    cavityWidth = Tk_Width(masterPtr->tkwin) -
	    Tk_InternalBorderLeft(masterPtr->tkwin) -
	    Tk_InternalBorderRight(masterPtr->tkwin);
    cavityHeight = Tk_Height(masterPtr->tkwin) -
	    Tk_InternalBorderTop(masterPtr->tkwin) -
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {
	    frameWidth = cavityWidth;
	    frameHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY;
	    if (slavePtr->flags & EXPAND) {
		frameHeight += YExpansion(slavePtr, cavityHeight);
	    }
	    cavityHeight -= frameHeight;
	    if (cavityHeight < 0) {
		frameHeight += cavityHeight;
		cavityHeight = 0;
	    }
	    frameX = cavityX;
	    if (slavePtr->side == TOP) {
		frameY = cavityY;
		cavityY += frameHeight;
	    } else {
		frameY = cavityY + cavityHeight;
	    }
	} else {
	    frameHeight = cavityHeight;
	    frameWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX;
	    if (slavePtr->flags & EXPAND) {
		frameWidth += XExpansion(slavePtr, cavityWidth);
	    }
	    cavityWidth -= frameWidth;
	    if (cavityWidth < 0) {
		frameWidth += cavityWidth;
		cavityWidth = 0;
	    }
	    frameY = cavityY;
	    if (slavePtr->side == LEFT) {
		frameX = cavityX;
		cavityX += frameWidth;
	    } else {
		frameX = cavityX + cavityWidth;
	    }
	}

	/*
	 * 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) {
	    borderX = borderY = 0;
	    borderTop = borderBtm = 0;
	    borderLeft = borderRight = 0;
	} else {
	    borderX = slavePtr->padX;
	    borderY = slavePtr->padY;
	    borderLeft = slavePtr->padLeft;
	    borderRight = borderX - borderLeft;
	    borderTop = slavePtr->padTop;
	    borderBtm = borderY - borderTop;
	}
	width = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->iPadX;
	if ((slavePtr->flags & FILLX)
		|| (width > (frameWidth - borderX))) {
	    width = frameWidth - borderX;
	}
	height = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->iPadY;
	if ((slavePtr->flags & FILLY)
		|| (height > (frameHeight - borderY))) {
	    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;
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
	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 -= contentPtr->doubleBw;
	height -= contentPtr->doubleBw;

	/*
	 * The final step is to set the position, size, and mapped/unmapped
	 * state of the content. If the content is a child of the container, then do
	 * this here. Otherwise let Tk_MaintainGeometry do the work.
	 */

	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		if ((x != Tk_X(contentPtr->tkwin))
			|| (y != Tk_Y(contentPtr->tkwin))
			|| (width != Tk_Width(contentPtr->tkwin))
			|| (height != Tk_Height(contentPtr->tkwin))) {
		    Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
		}
		if (abort) {
		    goto done;
		}

		/*
		 * Don't map the content if the container isn't mapped: wait until
		 * the container gets mapped later.
		 */

		if (Tk_IsMapped(containerPtr->tkwin)) {
		    Tk_MapWindow(contentPtr->tkwin);
		}
	    }
	} else {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin,
			x, y, width, height);
	    }
	}

	/*
	 * 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) {
	    goto done;
	}
    }

  done:
    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * XExpansion --
 *
 *	Given a list of packed content, 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
XExpansion(
    Packer *contentPtr,	/* First in list of remaining content. */
    int cavityWidth)		/* Horizontal space left for all remaining
				 * content. */
{
    int numExpand, minExpand, curExpand;
    int childWidth;

    /*
     * 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;
    numExpand = 0;
    for ( ; contentPtr != NULL; contentPtr = contentPtr->nextPtr) {
	childWidth = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->padX + contentPtr->iPadX;
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    if (numExpand) {
		curExpand = (cavityWidth - childWidth)/numExpand;
		if (curExpand < minExpand) {
		    minExpand = curExpand;
		}
	    }
	} else {
	    cavityWidth -= childWidth;
	    if (contentPtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }
    if (numExpand) {
	curExpand = cavityWidth/numExpand;
	if (curExpand < minExpand) {
	    minExpand = curExpand;
	}
    }
    return (minExpand < 0) ? 0 : minExpand;
}

/*
 *----------------------------------------------------------------------
 *
 * YExpansion --
 *
 *	Given a list of packed content, 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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
YExpansion(
    Packer *contentPtr,	/* First in list of remaining content. */
    int cavityHeight)		/* Vertical space left for all remaining
				 * content. */
{
    int numExpand, minExpand, curExpand;
    int childHeight;

    /*
     * See comments for XExpansion.
     */

    minExpand = cavityHeight;
    numExpand = 0;
    for ( ; contentPtr != NULL; contentPtr = contentPtr->nextPtr) {
	childHeight = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->padY + contentPtr->iPadY;
	if ((contentPtr->side == LEFT) || (contentPtr->side == RIGHT)) {
	    if (numExpand) {
		curExpand = (cavityHeight - childHeight)/numExpand;
		if (curExpand < minExpand) {
		    minExpand = curExpand;
		}
	    }
	} else {
	    cavityHeight -= childHeight;
	    if (contentPtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }
    if (numExpand) {
	curExpand = cavityHeight/numExpand;
	if (curExpand < minExpand) {
	    minExpand = curExpand;
	}
    }
    return (minExpand < 0) ? 0 : minExpand;
}

/*
 *------------------------------------------------------------------------
 *
 * GetPacker --
 *
 *	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.
 *
 * 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.
 *
 *------------------------------------------------------------------------
 */

static Packer *
GetPacker(
    Tk_Window tkwin)		/* Token for window for which packer structure
				 * is desired. */
{
    Packer *packPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->packInit) {
	dispPtr->packInit = 1;
	Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
     * See if there's already packer for this window. If not, then create a
     * new one.
     */

    hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin,
	    &isNew);
    if (!isNew) {
	return (Packer *)Tcl_GetHashValue(hPtr);
    }
    packPtr = (Packer *)ckalloc(sizeof(Packer));
    packPtr->tkwin = tkwin;
    packPtr->containerPtr = NULL;
    packPtr->nextPtr = NULL;
    packPtr->contentPtr = NULL;
    packPtr->side = TOP;
    packPtr->anchor = TK_ANCHOR_CENTER;
    packPtr->padX = packPtr->padY = 0;
    packPtr->padLeft = packPtr->padTop = 0;
    packPtr->iPadX = packPtr->iPadY = 0;
    packPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
    packPtr->abortPtr = NULL;
    packPtr->flags = 0;
    Tcl_SetHashValue(hPtr, packPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    PackStructureProc, packPtr);
    return packPtr;
}

/*
 *------------------------------------------------------------------------
 *
 * PackAfter --
 *
 *	This function does most of the real work of adding one or more windows
 *	into the packing order for its container.
 *
 * Results:
 *	A standard Tcl return value.
 *
 * Side effects:
 *	The geometry of the specified windows may change, both now and again
 *	in the future.
 *
 *------------------------------------------------------------------------
 */

#ifndef TK_NO_DEPRECATED
static int
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
				 * containerPtr. */
    Packer *containerPtr,		/* Container 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. */
{
    Packer *packPtr;
    Tk_Window tkwin, ancestor, parent;

    Tcl_Obj **options;
    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".
     */

    for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) {
	if (objc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # args: window \"%s\" should be followed by options",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", 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.
	 */

	if (TkGetWindowFromObj(interp, containerPtr->tkwin, objv[0], &tkwin)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	parent = Tk_Parent(tkwin);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
	    badWindow:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack \"%s\" inside \"%s\"", Tcl_GetString(objv[0]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		return TCL_ERROR;
	    }
	}
	if (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY) {
	    goto badWindow;
	}
	if (tkwin == containerPtr->tkwin) {
	    goto badWindow;
	}
	packPtr = GetPacker(tkwin);

	/*
	 * Process options for this window.
	 */







|
|



|



|

|

|
|
|
|
|






|
|


|
|




|
|

|
















|
|







|














|

|

















|
|
|
|
<
|
|
|
<



|




<
|
|
|
<









|














|

|










|
|
|
|
<
|
|
|
<



|




<
|
|
|
<





|














|







|

















|

|

|

|










|




|




|








|


<





|
|

|



|

>











<
|
|
|









|





|





<
|
|
<






|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

891
892
893

894
895
896
897
898
899
900
901

902
903
904

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

946
947
948

949
950
951
952
953
954
955
956

957
958
959

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070

1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094

1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
	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.
	 */

	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) {
		    goto done;
		}

		/*
		 * 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);
	    }
	}

	/*
	 * 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) {
	    goto done;
	}
    }

  done:
    masterPtr->abortPtr = NULL;
    Tcl_Release((ClientData) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	The return value is the number of additional pixels to give to the
 *	child.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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 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;
    numExpand = 0;
    for ( ; slavePtr != NULL; slavePtr = slavePtr->nextPtr) {
	childWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->padX + slavePtr->iPadX;
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {

	    curExpand = (cavityWidth - childWidth)/numExpand;
	    if (curExpand < minExpand) {
		minExpand = curExpand;

	    }
	} else {
	    cavityWidth -= childWidth;
	    if (slavePtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }

    curExpand = cavityWidth/numExpand;
    if (curExpand < minExpand) {
	minExpand = curExpand;

    }
    return (minExpand < 0) ? 0 : minExpand;
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	The return value is the number of additional pixels to give to the
 *	child.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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;

    /*
     * See comments for XExpansion.
     */

    minExpand = cavityHeight;
    numExpand = 0;
    for ( ; slavePtr != NULL; slavePtr = slavePtr->nextPtr) {
	childHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->padY + slavePtr->iPadY;
	if ((slavePtr->side == LEFT) || (slavePtr->side == RIGHT)) {

	    curExpand = (cavityHeight - childHeight)/numExpand;
	    if (curExpand < minExpand) {
		minExpand = curExpand;

	    }
	} else {
	    cavityHeight -= childHeight;
	    if (slavePtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }

    curExpand = cavityHeight/numExpand;
    if (curExpand < minExpand) {
	minExpand = curExpand;

    }
    return (minExpand < 0) ? 0 : minExpand;
}

/*
 *--------------------------------------------------------------
 *
 * GetPacker --
 *
 *	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.
 *
 * 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.
 *
 *--------------------------------------------------------------
 */

static Packer *
GetPacker(
    Tk_Window tkwin)		/* Token for window for which packer structure
				 * is desired. */
{
    register Packer *packPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->packInit) {
	dispPtr->packInit = 1;
	Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
     * See if there's already packer for this window. If not, then create a
     * new one.
     */

    hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin,
	    &isNew);
    if (!isNew) {
	return (Packer *) Tcl_GetHashValue(hPtr);
    }
    packPtr = (Packer *) ckalloc(sizeof(Packer));
    packPtr->tkwin = tkwin;
    packPtr->masterPtr = NULL;
    packPtr->nextPtr = NULL;
    packPtr->slavePtr = NULL;
    packPtr->side = TOP;
    packPtr->anchor = TK_ANCHOR_CENTER;
    packPtr->padX = packPtr->padY = 0;
    packPtr->padLeft = packPtr->padTop = 0;
    packPtr->iPadX = packPtr->iPadY = 0;
    packPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
    packPtr->abortPtr = NULL;
    packPtr->flags = 0;
    Tcl_SetHashValue(hPtr, packPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    PackStructureProc, (ClientData) packPtr);
    return packPtr;
}

/*
 *--------------------------------------------------------------
 *
 * PackAfter --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */


static int
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;
    int length;
    Tcl_Obj **options;
    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".
     */

    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",
		    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.
	 */

	if (TkGetWindowFromObj(interp, masterPtr->tkwin, objv[0], &tkwin)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	parent = Tk_Parent(tkwin);
	for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
	    badWindow:

		Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[0]),
			" inside ", Tk_PathName(masterPtr->tkwin), NULL);

		return TCL_ERROR;
	    }
	}
	if (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY) {
	    goto badWindow;
	}
	if (tkwin == masterPtr->tkwin) {
	    goto badWindow;
	}
	packPtr = GetPacker(tkwin);

	/*
	 * Process options for this window.
	 */
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
	packPtr->padX = packPtr->padY = 0;
	packPtr->padLeft = packPtr->padTop = 0;
	packPtr->iPadX = packPtr->iPadY = 0;
	packPtr->flags &= ~(FILLX|FILLY|EXPAND);
	packPtr->flags |= OLD_STYLE;
	for (index = 0 ; index < optionCount; index++) {
	    Tcl_Obj *curOptPtr = options[index];
	    TkSizeT length;
	    const char *curOpt = TkGetStringFromObj(curOptPtr, &length);

	    c = curOpt[0];

	    if ((c == 't')
		    && (strncmp(curOpt, "top", length)) == 0) {
		packPtr->side = TOP;
	    } else if ((c == 'b')
		    && (strncmp(curOpt, "bottom", length)) == 0) {
		packPtr->side = BOTTOM;
	    } else if ((c == 'l')
		    && (strncmp(curOpt, "left", length)) == 0) {
		packPtr->side = LEFT;
	    } else if ((c == 'r')
		    && (strncmp(curOpt, "right", length)) == 0) {
		packPtr->side = RIGHT;
	    } else if ((c == 'e')
		    && (strncmp(curOpt, "expand", length)) == 0) {
		packPtr->flags |= EXPAND;
	    } else if ((c == 'f')
		    && (strcmp(curOpt, "fill")) == 0) {
		packPtr->flags |= FILLX|FILLY;
	    } else if ((length == 5) && (strcmp(curOpt, "fillx")) == 0) {
		packPtr->flags |= FILLX;
	    } else if ((length == 5) && (strcmp(curOpt, "filly")) == 0) {
		packPtr->flags |= FILLY;
	    } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) {
		if (optionCount < (index+2)) {
		missingPad:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "wrong # args: \"%s\" option must be"
			    " followed by screen distance", curOpt));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padLeft, &packPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}







<
|




|


|


|


|


|











<
|
|
<







1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155

1156
1157
1158
1159
1160
1161
1162
	packPtr->padX = packPtr->padY = 0;
	packPtr->padLeft = packPtr->padTop = 0;
	packPtr->iPadX = packPtr->iPadY = 0;
	packPtr->flags &= ~(FILLX|FILLY|EXPAND);
	packPtr->flags |= OLD_STYLE;
	for (index = 0 ; index < optionCount; index++) {
	    Tcl_Obj *curOptPtr = options[index];

	    char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length);

	    c = curOpt[0];

	    if ((c == 't')
		    && (strncmp(curOpt, "top", (size_t) length)) == 0) {
		packPtr->side = TOP;
	    } else if ((c == 'b')
		    && (strncmp(curOpt, "bottom", (size_t) length)) == 0) {
		packPtr->side = BOTTOM;
	    } else if ((c == 'l')
		    && (strncmp(curOpt, "left", (size_t) length)) == 0) {
		packPtr->side = LEFT;
	    } else if ((c == 'r')
		    && (strncmp(curOpt, "right", (size_t) length)) == 0) {
		packPtr->side = RIGHT;
	    } else if ((c == 'e')
		    && (strncmp(curOpt, "expand", (size_t) length)) == 0) {
		packPtr->flags |= EXPAND;
	    } else if ((c == 'f')
		    && (strcmp(curOpt, "fill")) == 0) {
		packPtr->flags |= FILLX|FILLY;
	    } else if ((length == 5) && (strcmp(curOpt, "fillx")) == 0) {
		packPtr->flags |= FILLX;
	    } else if ((length == 5) && (strcmp(curOpt, "filly")) == 0) {
		packPtr->flags |= FILLY;
	    } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) {
		if (optionCount < (index+2)) {
		missingPad:

		    Tcl_AppendResult(interp, "wrong # args: \"", curOpt,
			    "\" option must be followed by screen distance",

			    NULL);
		    return TCL_ERROR;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padLeft, &packPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
		    return TCL_ERROR;
		}
		packPtr->padY /= 2;
		packPtr->padTop /= 2;
		packPtr->iPadY = 0;
		index++;
	    } else if ((c == 'f') && (length > 1)
		    && (strncmp(curOpt, "frame", length) == 0)) {
		if (optionCount < (index+2)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "wrong # args: \"frame\""
			    " option must be followed by anchor point", -1));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
		if (Tk_GetAnchorFromObj(interp, options[index+1],
			&packPtr->anchor) != TCL_OK) {
		    return TCL_ERROR;
		}
		index++;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": should be top, bottom, left,"
			" right, expand, fill, fillx, filly, padx, pady, or"
			" frame", curOpt));
		Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			NULL);
		return TCL_ERROR;
	    }
	}

	if (packPtr != prevPtr) {

	    /*
	     * Unpack this window if it's currently packed.
	     */

	    if (packPtr->containerPtr != NULL) {
		if ((packPtr->containerPtr != containerPtr) &&
			(packPtr->containerPtr->tkwin
			!= Tk_Parent(packPtr->tkwin))) {
		    Tk_UnmaintainGeometry(packPtr->tkwin,
			    packPtr->containerPtr->tkwin);
		}
		Unlink(packPtr);
	    }

	    /*
	     * Add the window in the correct place in its container's packing
	     * order, then make sure that the window is managed by us.
	     */

	    packPtr->containerPtr = containerPtr;
	    if (prevPtr == NULL) {
		packPtr->nextPtr = containerPtr->contentPtr;
		containerPtr->contentPtr = packPtr;
	    } else {
		packPtr->nextPtr = prevPtr->nextPtr;
		prevPtr->nextPtr = packPtr;
	    }
	    Tk_ManageGeometry(tkwin, &packerType, packPtr);

	    if (!(containerPtr->flags & DONT_PROPAGATE)) {
		if (TkSetGeometryContainer(interp, containerPtr->tkwin, "pack")
			!= TCL_OK) {
		    Tk_ManageGeometry(tkwin, NULL, NULL);
		    Unlink(packPtr);
		    return TCL_ERROR;
		}
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	}
    }

    /*
     * Arrange for the container to be re-packed at the first idle moment.
     */

    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    if (!(containerPtr->flags & REQUESTED_REPACK)) {
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
    }
    return TCL_OK;
}
#endif /* !TK_NO_DEPRECATED */

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a packer from its container's list of content.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The container will be scheduled for repacking.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Packer *packPtr)	/* Window to unlink. */
{
    Packer *containerPtr, *packPtr2;

    containerPtr = packPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (containerPtr->contentPtr == packPtr) {
	containerPtr->contentPtr = packPtr->nextPtr;
    } else {
	for (packPtr2 = containerPtr->contentPtr; ; packPtr2 = packPtr2->nextPtr) {
	    if (packPtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (packPtr2->nextPtr == packPtr) {
		packPtr2->nextPtr = packPtr->nextPtr;
		break;
	    }
	}
    }
    if (!(containerPtr->flags & REQUESTED_REPACK)) {
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
    }
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }

    packPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "pack");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * DestroyPacker --
 *







|

<
|
|
<
<








|
|
|
<
<
<





>




|
|
|


|





|



|

|
|




|
|
<
<
<
<
<
<
|
<
|
<
<
<

|


|
|

|
|
|



<






|





|






|

|

|
|


|
|

|









|
|
|

|
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1173
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183


1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194



1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229






1230

1231



1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293















1294
1295
1296
1297
1298
1299
1300
		    return TCL_ERROR;
		}
		packPtr->padY /= 2;
		packPtr->padTop /= 2;
		packPtr->iPadY = 0;
		index++;
	    } else if ((c == 'f') && (length > 1)
		    && (strncmp(curOpt, "frame", (size_t) length) == 0)) {
		if (optionCount < (index+2)) {

		    Tcl_AppendResult(interp, "wrong # args: \"frame\" ",
			    "option must be followed by anchor point", NULL);


		    return TCL_ERROR;
		}
		if (Tk_GetAnchorFromObj(interp, options[index+1],
			&packPtr->anchor) != TCL_OK) {
		    return TCL_ERROR;
		}
		index++;
	    } else {
		Tcl_AppendResult(interp, "bad option \"", curOpt,
			"\": should be top, bottom, left, right, expand, ",
			"fill, fillx, filly, padx, pady, or frame", NULL);



		return TCL_ERROR;
	    }
	}

	if (packPtr != prevPtr) {

	    /*
	     * Unpack this window if it's currently packed.
	     */

	    if (packPtr->masterPtr != NULL) {
		if ((packPtr->masterPtr != masterPtr) &&
			(packPtr->masterPtr->tkwin
			!= Tk_Parent(packPtr->tkwin))) {
		    Tk_UnmaintainGeometry(packPtr->tkwin,
			    packPtr->masterPtr->tkwin);
		}
		Unlink(packPtr);
	    }

	    /*
	     * 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;
	    if (prevPtr == NULL) {
		packPtr->nextPtr = masterPtr->slavePtr;
		masterPtr->slavePtr = packPtr;
	    } else {
		packPtr->nextPtr = prevPtr->nextPtr;
		prevPtr->nextPtr = packPtr;
	    }
	    Tk_ManageGeometry(tkwin, &packerType, (ClientData) packPtr);
	}






    }





    /*
     * Arrange for the master to be re-packed at the first idle moment.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    }
    if (!(masterPtr->flags & REQUESTED_REPACK)) {
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr);
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a packer from its master's list of slaves.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The master will be scheduled for repacking.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    register Packer *packPtr)	/* Window to unlink. */
{
    register Packer *masterPtr, *packPtr2;

    masterPtr = packPtr->masterPtr;
    if (masterPtr == NULL) {
	return;
    }
    if (masterPtr->slavePtr == packPtr) {
	masterPtr->slavePtr = packPtr->nextPtr;
    } else {
	for (packPtr2 = masterPtr->slavePtr; ; packPtr2 = packPtr2->nextPtr) {
	    if (packPtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (packPtr2->nextPtr == packPtr) {
		packPtr2->nextPtr = packPtr->nextPtr;
		break;
	    }
	}
    }
    if (!(masterPtr->flags & REQUESTED_REPACK)) {
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr);
    }
    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    }

    packPtr->masterPtr = NULL;















}

/*
 *----------------------------------------------------------------------
 *
 * DestroyPacker --
 *
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723

1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(
    void *memPtr)		/* Info about packed window that is now
				 * dead. */
{
    Packer *packPtr = (Packer *)memPtr;

    ckfree(packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --
 *
 *	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 content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
PackStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Packer *packPtr = (Packer *)clientData;

    if (eventPtr->type == ConfigureNotify) {
	if ((packPtr->contentPtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, packPtr);
	}
	if ((packPtr->containerPtr != NULL)
	        && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) {
	    if (!(packPtr->containerPtr->flags & REQUESTED_REPACK)) {
		packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width;
		packPtr->containerPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, packPtr->containerPtr);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	Packer *contentPtr, *nextPtr;

	if (packPtr->containerPtr != NULL) {
	    Unlink(packPtr);
	}

	for (contentPtr = packPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);

	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}

	if (packPtr->tkwin != NULL) {
	    TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
            Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
		    packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
    } else if (eventPtr->type == MapNotify) {
	/*
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((packPtr->contentPtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, packPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Packer *packPtr2;

	/*
	 * Unmap all of the content when the container gets unmapped, so that they
	 * don't bother to keep redisplaying themselves.
	 */

	for (packPtr2 = packPtr->contentPtr; packPtr2 != NULL;
	     packPtr2 = packPtr2->nextPtr) {
	    Tk_UnmapWindow(packPtr2->tkwin);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureContent --
 *
 *	This implements the guts of the "pack configure" command. Given a list
 *	of content and configuration options, it arranges for the packer to
 *	manage the content 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.
 *
 * Side effects:
 *	Content windows get taken over by the packer.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * content. Used to look up content 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 *containerPtr, *contentPtr, *prevPtr, *otherPtr;
    Tk_Window other, content, parent, ancestor;
    TkWindow *container;
    int i, j, numWindows, tmp, positionGiven;
    const char *string;
    static const char *const optionStrings[] = {
	"-after", "-anchor", "-before", "-expand", "-fill",
	"-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 };
    int index, side;

    /*
     * Find out how many windows are specified.
     */

    for (numWindows = 0; numWindows < objc; numWindows++) {
	string = Tcl_GetString(objv[numWindows]);
	if (string[0] != '.') {
	    break;
	}
    }

    /*
     * Iterate over all of the content windows, parsing the configuration
     * options for each content. It's a bit wasteful to re-parse the options for
     * each content, but things get too messy if we try to parse the arguments
     * just once at the beginning. For example, if a content 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.
     */

    containerPtr = NULL;
    prevPtr = NULL;
    positionGiven = 0;
    for (j = 0; j < numWindows; j++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[j], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	contentPtr = GetPacker(content);
	contentPtr->flags &= ~OLD_STYLE;

	/*
	 * If the content isn't currently packed, reset all of its configuration
	 * information to default values (there could be old values left from
	 * a previous packing).
	 */

	if (contentPtr->containerPtr == NULL) {
	    contentPtr->side = TOP;
	    contentPtr->anchor = TK_ANCHOR_CENTER;
	    contentPtr->padX = contentPtr->padY = 0;
	    contentPtr->padLeft = contentPtr->padTop = 0;
	    contentPtr->iPadX = contentPtr->iPadY = 0;
	    contentPtr->flags &= ~(FILLX|FILLY|EXPAND);
	}

	for (i = numWindows; i < objc; i+=2) {
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    prevPtr = GetPacker(other);
		    if (prevPtr->containerPtr == NULL) {
		    notPacked:
			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
				"window \"%s\" isn't packed",
				Tcl_GetString(objv[i+1])));
			Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED",
				NULL);
			return TCL_ERROR;
		    }
		    containerPtr = prevPtr->containerPtr;
		    positionGiven = 1;
		}
		break;
	    case CONF_ANCHOR:
		if (Tk_GetAnchorFromObj(interp, objv[i+1], &contentPtr->anchor)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_BEFORE:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    otherPtr = GetPacker(other);
		    if (otherPtr->containerPtr == NULL) {
			goto notPacked;
		    }
		    containerPtr = otherPtr->containerPtr;
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;
		    } else {
			while (prevPtr->nextPtr != otherPtr) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		break;
	    case CONF_EXPAND:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->flags &= ~EXPAND;
		if (tmp) {
		    contentPtr->flags |= EXPAND;
		}
		break;
	    case CONF_FILL:
		string = Tcl_GetString(objv[i+1]);
		if (strcmp(string, "none") == 0) {
		    contentPtr->flags &= ~(FILLX|FILLY);
		} else if (strcmp(string, "x") == 0) {
		    contentPtr->flags = (contentPtr->flags & ~FILLY) | FILLX;
		} else if (strcmp(string, "y") == 0) {
		    contentPtr->flags = (contentPtr->flags & ~FILLX) | FILLY;
		} else if (strcmp(string, "both") == 0) {
		    contentPtr->flags |= FILLX|FILLY;
		} else {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad fill style \"%s\": must be "
			    "none, x, y, or both", string));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "FILL", NULL);
		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    containerPtr = GetPacker(other);
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		break;
	    case CONF_IPADX:
		if ((Tk_GetPixelsFromObj(interp, content, objv[i+1], &tmp)
			!= TCL_OK) || (tmp < 0)) {

		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipadx value \"%s\": must be positive screen"
			    " distance", Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		contentPtr->iPadX = tmp * 2;
		break;
	    case CONF_IPADY:
		if ((Tk_GetPixelsFromObj(interp, content, objv[i+1], &tmp)
			!= TCL_OK) || (tmp < 0)) {

		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipady value \"%s\": must be positive screen"
			    " distance", Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		contentPtr->iPadY = tmp * 2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padLeft, &contentPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_SIDE:
		if (Tcl_GetIndexFromObjStruct(interp, objv[i+1], sideNames,
			sizeof(char *), "side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->side = (Side) side;
		break;
	    }
	}

	/*
	 * If no position in a packing list was specified and the content is
	 * already packed, then leave it in its current location in its
	 * current packing list.
	 */

	if (!positionGiven && (contentPtr->containerPtr != NULL)) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}

	/*
	 * If the content 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 == contentPtr) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}

	/*
	 * If none of the "-in", "-before", or "-after" options has been
	 * specified, arrange for the content to go at the end of the order for
	 * its parent.
	 */

	if (!positionGiven) {
	    containerPtr = GetPacker(Tk_Parent(content));
	    prevPtr = containerPtr->contentPtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}

	/*
	 * Make sure that the content's parent is either the container or an
	 * ancestor of the container, and that the container and content aren't the
	 * same.
	 */

	parent = Tk_Parent(content);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack \"%s\" inside \"%s\"", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		return TCL_ERROR;
	    }
	}
	if (content == containerPtr->tkwin) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack \"%s\" inside itself", Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;
	}

	/*
	 * Unpack the content if it's currently packed, then position it after
	 * prevPtr.
	 */

	if (contentPtr->containerPtr != NULL) {
	    if ((contentPtr->containerPtr != containerPtr) &&
		    (contentPtr->containerPtr->tkwin
		    != Tk_Parent(contentPtr->tkwin))) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);
	    }
	    Unlink(contentPtr);
	}

	contentPtr->containerPtr = containerPtr;
	if (prevPtr == NULL) {
	    contentPtr->nextPtr = containerPtr->contentPtr;
	    containerPtr->contentPtr = contentPtr;
	} else {
	    contentPtr->nextPtr = prevPtr->nextPtr;
	    prevPtr->nextPtr = contentPtr;
	}
	Tk_ManageGeometry(content, &packerType, contentPtr);
	prevPtr = contentPtr;

	if (!(containerPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryContainer(interp, containerPtr->tkwin, "pack")
		    != TCL_OK) {
		Tk_ManageGeometry(content, NULL, NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	    containerPtr->flags |= ALLOCED_CONTAINER;
	}

	/*
	 * Arrange for the container to be re-packed at the first idle moment.
	 */

    scheduleLayout:
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(containerPtr->flags & REQUESTED_REPACK)) {
	    containerPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


|
<
|















|










|


|


|

|

|

|
|



|

|



|
|
|
>
|
|
|
|





|



|


|


|
|


|


|


|


|



|









|


|
|






|





|


|

|




|
|
<

|
|



















|
|
|
|





|



|


|
|
|
<
<


|
|


|




|
|
|
|
|
|
|




|
<
|
|


|
|











|

|
<
|
<
|


|




|











|


|
|














|

|





|

|

|

|

<
|
|
<









|
|









|
|
>
|
|
|
|


|


|
|
>
|
|
|
|


|


|
|




|
|




|
|


|





|




|
|




|




|
|





|




|
|








|
|



|
|




<
|
|
<



|
|
|
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|
|
|
|
|
|

|

|
<

|
|

|
|

|
|

<
<
<
<
<
<
<
<
<
<

|



|
|

|
|
|












1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448

1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489


1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532

1533

1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589
1590

1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705

1706
1707

1708
1709
1710
1711
1712
1713

1714
1715
1716
1717


















1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739
1740
1741










1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(
    char *memPtr)		/* Info about packed window that is now
				 * dead. */
{
    register Packer *packPtr = (Packer *) memPtr;

    ckfree((char *) packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
PackStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    register Packer *packPtr = (Packer *) clientData;

    if (eventPtr->type == ConfigureNotify) {
	if ((packPtr->slavePtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr);
	}
	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);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	register Packer *slavePtr, *nextPtr;

	if (packPtr->masterPtr != NULL) {
	    Unlink(packPtr);
	}

	for (slavePtr = packPtr->slavePtr; slavePtr != NULL;
		slavePtr = nextPtr) {
	    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);
	}
	packPtr->tkwin = NULL;
	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.
	 */

	if ((packPtr->slavePtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	register Packer *packPtr2;

	/*
	 * 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);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * 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.
 *
 * Side effects:
 *	Slave windows get taken over by the packer.
 *
 *----------------------------------------------------------------------
 */

static int
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;

    int i, j, numWindows, tmp, positionGiven;
    char *string;
    static CONST char *optionStrings[] = {
	"-after", "-anchor", "-before", "-expand", "-fill",
	"-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 };
    int index, side;

    /*
     * Find out how many windows are specified.
     */

    for (numWindows = 0; numWindows < objc; numWindows++) {
	string = Tcl_GetString(objv[numWindows]);
	if (string[0] != '.') {
	    break;
	}
    }

    /*
     * 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.
     */

    masterPtr = NULL;
    prevPtr = NULL;
    positionGiven = 0;
    for (j = 0; j < numWindows; j++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[j], &slave) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tk_TopWinHierarchy(slave)) {
	    Tcl_AppendResult(interp, "can't pack \"", Tcl_GetString(objv[j]),
		    "\": 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 (slavePtr->masterPtr == NULL) {
	    slavePtr->side = TOP;
	    slavePtr->anchor = TK_ANCHOR_CENTER;
	    slavePtr->padX = slavePtr->padY = 0;
	    slavePtr->padLeft = slavePtr->padTop = 0;
	    slavePtr->iPadX = slavePtr->iPadY = 0;
	    slavePtr->flags &= ~(FILLX|FILLY|EXPAND);
	}

	for (i = numWindows; i < objc; i+=2) {
	    if ((i+2) > objc) {
		Tcl_AppendResult(interp, "extra option \"",

			Tcl_GetString(objv[i]),
			"\" (option with no value?)", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option",
		    0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    prevPtr = GetPacker(other);
		    if (prevPtr->masterPtr == NULL) {
		    notPacked:
			Tcl_AppendResult(interp, "window \"",

				Tcl_GetString(objv[i+1]),

				"\" isn't packed", NULL);
			return TCL_ERROR;
		    }
		    masterPtr = prevPtr->masterPtr;
		    positionGiven = 1;
		}
		break;
	    case CONF_ANCHOR:
		if (Tk_GetAnchorFromObj(interp, objv[i+1], &slavePtr->anchor)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_BEFORE:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    otherPtr = GetPacker(other);
		    if (otherPtr->masterPtr == NULL) {
			goto notPacked;
		    }
		    masterPtr = otherPtr->masterPtr;
		    prevPtr = masterPtr->slavePtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;
		    } else {
			while (prevPtr->nextPtr != otherPtr) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		break;
	    case CONF_EXPAND:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		slavePtr->flags &= ~EXPAND;
		if (tmp) {
		    slavePtr->flags |= EXPAND;
		}
		break;
	    case CONF_FILL:
		string = Tcl_GetString(objv[i+1]);
		if (strcmp(string, "none") == 0) {
		    slavePtr->flags &= ~(FILLX|FILLY);
		} else if (strcmp(string, "x") == 0) {
		    slavePtr->flags = (slavePtr->flags & ~FILLY) | FILLX;
		} else if (strcmp(string, "y") == 0) {
		    slavePtr->flags = (slavePtr->flags & ~FILLX) | FILLY;
		} else if (strcmp(string, "both") == 0) {
		    slavePtr->flags |= FILLX|FILLY;
		} else {

		    Tcl_AppendResult(interp, "bad fill style \"", string,
			    "\": must be none, x, y, or both", NULL);

		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    masterPtr = GetPacker(other);
		    prevPtr = masterPtr->slavePtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		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", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadX = tmp * 2;
		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", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadY = tmp * 2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, slave, objv[i+1],
			&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, slave, objv[i+1],
			&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		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 (!positionGiven && (slavePtr->masterPtr != NULL)) {
	    masterPtr = slavePtr->masterPtr;
	    goto scheduleLayout;
	}

	/*
	 * 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 (!positionGiven) {
	    masterPtr = GetPacker(Tk_Parent(slave));
	    prevPtr = masterPtr->slavePtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}

	/*
	 * 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) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {

		Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]),
			" 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", NULL);

	    return TCL_ERROR;
	}

	/*


















	 * Unpack the slave if it's currently packed, then position it after
	 * prevPtr.
	 */

	if (slavePtr->masterPtr != NULL) {
	    if ((slavePtr->masterPtr != masterPtr) &&
		    (slavePtr->masterPtr->tkwin
		    != Tk_Parent(slavePtr->tkwin))) {
		Tk_UnmaintainGeometry(slavePtr->tkwin,
			slavePtr->masterPtr->tkwin);
	    }
	    Unlink(slavePtr);
	}
	slavePtr->masterPtr = masterPtr;

	if (prevPtr == NULL) {
	    slavePtr->nextPtr = masterPtr->slavePtr;
	    masterPtr->slavePtr = slavePtr;
	} else {
	    slavePtr->nextPtr = prevPtr->nextPtr;
	    prevPtr->nextPtr = slavePtr;
	}
	Tk_ManageGeometry(slave, &packerType, (ClientData) slavePtr);
	prevPtr = slavePtr;











	/*
	 * Arrange for the master to be re-packed at the first idle moment.
	 */

    scheduleLayout:
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_REPACK)) {
	    masterPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr);
	}
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkPanedWindow.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "tkInt.h"
#include "default.h"

/*
 * 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.







|
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "default.h"
#include "tkInt.h"

/*
 * 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.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    (((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 paneOpts;	/* Token for pane cget option table. */
} OptionTables;

/*
 * One structure of the following type is kept for each window
 * managed by a paned window widget.
 */

typedef struct Pane {
    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 pane, in
				 * the x dimension. */
    int pady;			/* Additional padding requested for pane, in
				 * the y dimension. */
    Tcl_Obj *widthPtr, *heightPtr;
				/* Tcl_Obj rep's of pane width/height, to
				 * allow for null values. */
    int width;			/* Pane width. */
    int height;			/* Pane height. */
    int sticky;			/* Sticky string. */
    int x, y;			/* Coordinates of the widget. */
    int paneWidth, paneHeight;	/* Pane dimensions (may be different from
				 * pane 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 pane grows/shrinks */
    int hide;			/* Controls visibility of pane */
    struct PanedWindow *containerPtr;
				/* Paned window managing the window. */
    Tk_Window after;		/* Placeholder for parsing options. */
    Tk_Window before;		/* Placeholder for parsing options. */
} Pane;

/*
 * A data structure of the following type is kept for each paned window widget
 * managed by this file:
 */

typedef struct PanedWindow {
    Tk_Window tkwin;		/* Window that embodies the paned window. */
    Tk_Window proxywin;		/* Window for the resizing proxy. */
    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. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    Tk_OptionTable paneOpts;	/* Token for pane cget table. */
    Tk_3DBorder background;	/* Background color. */
    int borderWidth;		/* Value of -borderwidth option. */
    int relief;			/* 3D border effect (TK_RELIEF_RAISED, etc) */
    Tcl_Obj *widthPtr;		/* Tcl_Obj rep for width. */
    Tcl_Obj *heightPtr;		/* Tcl_Obj rep for height. */
    int width, height;		/* Width and height of the widget. */
    enum orient orient;		/* Orientation of the widget. */







|







|



|

|


|

|
|



|





|

|



|














|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    (((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. */
} OptionTables;

/*
 * One structure of the following type is kept for each window
 * managed by a paned window widget.
 */

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. */
    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:
 */

typedef struct PanedWindow {
    Tk_Window tkwin;		/* Window that embodies the paned window. */
    Tk_Window proxywin;		/* Window for the resizing proxy. */
    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. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    Tk_OptionTable slaveOpts;	/* Token for slave cget table. */
    Tk_3DBorder background;	/* Background color. */
    int borderWidth;		/* Value of -borderwidth option. */
    int relief;			/* 3D border effect (TK_RELIEF_RAISED, etc) */
    Tcl_Obj *widthPtr;		/* Tcl_Obj rep for width. */
    Tcl_Obj *heightPtr;		/* Tcl_Obj rep for height. */
    int width, height;		/* Width and height of the widget. */
    enum orient orient;		/* Orientation of the widget. */
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    GC gc;			/* Graphics context for copying from
				 * off-screen pixmap onto screen. */
    int proxyx, proxyy;		/* Proxy x,y coordinates. */
    Tk_3DBorder proxyBackground;/* Background color used to draw proxy. If NULL, use background. */
    Tcl_Obj *proxyBorderWidthPtr; /* Tcl_Obj rep for proxyBorderWidth */
    int proxyBorderWidth;	/* Borderwidth used to draw proxy. */
    int proxyRelief;		/* Relief used to draw proxy, if TK_RELIEF_NULL then use relief. */
    Pane **panes;		/* Pointer to array of Panes. */
    int numPanes;		/* Number of panes. */
    int sizeofPanes;		/* Number of elements in the panes array. */
    int flags;			/* Flags for widget; see below. */
} PanedWindow;

/*
 * Flags used for paned windows:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has been







|
|
|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    GC gc;			/* Graphics context for copying from
				 * off-screen pixmap onto screen. */
    int proxyx, proxyy;		/* Proxy x,y coordinates. */
    Tk_3DBorder proxyBackground;/* Background color used to draw proxy. If NULL, use background. */
    Tcl_Obj *proxyBorderWidthPtr; /* Tcl_Obj rep for proxyBorderWidth */
    int proxyBorderWidth;	/* Borderwidth used to draw proxy. */
    int proxyRelief;		/* Relief used to draw proxy, if TK_RELIEF_NULL then use relief. */
    Slave **slaves;		/* Pointer to array of Slaves. */
    int numSlaves;		/* Number of slaves. */
    int sizeofSlaves;		/* Number of elements in the slaves array. */
    int flags;			/* Flags for widget; see below. */
} PanedWindow;

/*
 * Flags used for paned windows:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has been
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
			    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		PanedWindowLostPaneProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PanedWindowReqProc(ClientData clientData,
			    Tk_Window tkwin);
static void		ArrangePanes(ClientData clientData);
static void		Unlink(Pane *panePtr);
static Pane *		GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
static void		GetFirstLastVisiblePane(PanedWindow *pwPtr,
			    int *firstPtr, int *lastPtr);
static void		PaneStructureProc(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		ConfigurePanes(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,
			    TkSizeT internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(ClientData clientData, Tk_Window tkwin,
			    char *recordPtr, TkSizeT 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 *paneWidthPtr, int *paneHeightPtr);
static void		MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void *	ComputeSlotAddress(void *recordPtr, TkSizeT 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 panes
 */

#define ValidSashIndex(pwPtr, sash) \
	(((sash) >= 0) && ((sash) < ((pwPtr)->numPanes-1)))

static const Tk_GeomMgr panedWindowMgrType = {
    "panedwindow",		/* name */
    PanedWindowReqProc,		/* requestProc */
    PanedWindowLostPaneProc,	/* lostPaneProc */
};

/*
 * Information used for objv parsing.
 */

#define GEOMETRY		0x0001

/*
 * The following structure contains pointers to functions used for processing
 * the custom "-sticky" option for panes.
 */

static const Tk_ObjCustomOption stickyOption = {
    "sticky",			/* name */
    SetSticky,			/* setProc */
    GetSticky,			/* getProc */
    RestoreSticky,		/* restoreProc */
    NULL,			/* freeProc */
    0
};

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_PANEDWINDOW_BG_COLOR, TCL_INDEX_NONE, offsetof(PanedWindow, background), 0,
	 DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_PANEDWINDOW_BORDERWIDTH, TCL_INDEX_NONE, offsetof(PanedWindow, borderWidth),
	 0, 0, GEOMETRY},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_PANEDWINDOW_CURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-handlepad", "handlePad", "HandlePad",
	 DEF_PANEDWINDOW_HANDLEPAD, TCL_INDEX_NONE, offsetof(PanedWindow, handlePad),
	 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	 DEF_PANEDWINDOW_HANDLESIZE, offsetof(PanedWindow, handleSizePtr),
	 offsetof(PanedWindow, handleSize), 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	 DEF_PANEDWINDOW_HEIGHT, offsetof(PanedWindow, heightPtr),
	 offsetof(PanedWindow, height), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-opaqueresize", "opaqueResize", "OpaqueResize",
	 DEF_PANEDWINDOW_OPAQUERESIZE, TCL_INDEX_NONE,
	 offsetof(PanedWindow, resizeOpaque), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	 DEF_PANEDWINDOW_ORIENT, TCL_INDEX_NONE, offsetof(PanedWindow, orient),
	 0, orientStrings, GEOMETRY},
    {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
	 0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyBackground), TK_OPTION_NULL_OK,
	 (ClientData) DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
	 DEF_PANEDWINDOW_PROXYBORDER, offsetof(PanedWindow, proxyBorderWidthPtr),
	 offsetof(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	 0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_PANEDWINDOW_RELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, relief), 0, 0, 0},
    {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
	 DEF_PANEDWINDOW_SASHCURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, sashCursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
	 DEF_PANEDWINDOW_SASHPAD, TCL_INDEX_NONE, offsetof(PanedWindow, sashPad),
	 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	 DEF_PANEDWINDOW_SASHRELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, sashRelief),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
	 DEF_PANEDWINDOW_SASHWIDTH, offsetof(PanedWindow, sashWidthPtr),
	 offsetof(PanedWindow, sashWidth), 0, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
	 DEF_PANEDWINDOW_SHOWHANDLE, TCL_INDEX_NONE, offsetof(PanedWindow, showHandle),
	 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	 DEF_PANEDWINDOW_WIDTH, offsetof(PanedWindow, widthPtr),
	 offsetof(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec paneOptionSpecs[] = {
    {TK_OPTION_WINDOW, "-after", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_AFTER, TCL_INDEX_NONE, offsetof(Pane, after),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-before", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_BEFORE, TCL_INDEX_NONE, offsetof(Pane, before),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_HEIGHT, offsetof(Pane, heightPtr),
	 offsetof(Pane, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
	 DEF_PANEDWINDOW_PANE_HIDE, TCL_INDEX_NONE, offsetof(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Pane, sticky), 0,
	 &stickyOption, 0},
    {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
	DEF_PANEDWINDOW_PANE_STRETCH, TCL_INDEX_NONE, offsetof(Pane, stretch), 0,
	(ClientData) stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Pane, widthPtr),
	 offsetof(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --
 *







|




|
|


|








|






|


|




|


|




|



|




|










|













|
|

|

|

|


|


|


|
|

|
|

|
|

|
|

|
|

|
|

|


|

|


|


|


|
|

|


|
|
|


|

|


|


|
|

|

|

|

|

|
|

|


|
|
|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
			    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		GetFirstLastVisiblePane(PanedWindow *pwPtr,
			    int *firstPtr, int *lastPtr);
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
 */

#define ValidSashIndex(pwPtr, sash) \
	(((sash) >= 0) && ((sash) < ((pwPtr)->numSlaves-1)))

static const Tk_GeomMgr panedWindowMgrType = {
    "panedwindow",		/* name */
    PanedWindowReqProc,		/* requestProc */
    PanedWindowLostSlaveProc,	/* lostSlaveProc */
};

/*
 * Information used for objv parsing.
 */

#define GEOMETRY		0x0001

/*
 * The following structure contains pointers to functions used for processing
 * the custom "-sticky" option for slave windows.
 */

static const Tk_ObjCustomOption stickyOption = {
    "sticky",			/* name */
    SetSticky,			/* setProc */
    GetSticky,			/* getProc */
    RestoreSticky,		/* restoreProc */
    NULL,			/* freeProc */
    0
};

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", 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},
    {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},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	 DEF_PANEDWINDOW_HANDLESIZE, Tk_Offset(PanedWindow, handleSizePtr),
	 Tk_Offset(PanedWindow, handleSize), 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	 DEF_PANEDWINDOW_HEIGHT, Tk_Offset(PanedWindow, heightPtr),
	 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_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	 DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
	 0, (ClientData) orientStrings, GEOMETRY},
    {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
	 0, -1, Tk_Offset(PanedWindow, proxyBackground), TK_OPTION_NULL_OK,
	 (ClientData) DEF_PANEDWINDOW_BG_MONO},
    {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
	 DEF_PANEDWINDOW_PROXYBORDER, Tk_Offset(PanedWindow, proxyBorderWidthPtr),
	 Tk_Offset(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	 0, -1, Tk_Offset(PanedWindow, proxyRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(PanedWindow, relief), 0, 0, 0},
    {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
	 DEF_PANEDWINDOW_SASHCURSOR, -1, Tk_Offset(PanedWindow, sashCursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
	 DEF_PANEDWINDOW_SASHPAD, -1, Tk_Offset(PanedWindow, sashPad),
	 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	 DEF_PANEDWINDOW_SASHRELIEF, -1, Tk_Offset(PanedWindow, sashRelief),
	 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},
    {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", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_AFTER, -1, Tk_Offset(Slave, after),
	 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_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", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADX, -1, Tk_Offset(Slave, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADY, -1, Tk_Offset(Slave, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_STICKY, -1, Tk_Offset(Slave, sticky), 0,
	 (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_OPTION_END}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --
 *
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
Tk_PanedWindowObjCmd(
    TCL_UNUSED(ClientData),	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    PanedWindow *pwPtr;
    Tk_Window tkwin, parent;
    OptionTables *pwOpts;
    XSetWindowAttributes atts;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    pwOpts = (OptionTables *)
	    Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
    if (pwOpts == NULL) {
	/*
	 * 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.
	 */

	Tcl_SetAssocData(interp, "PanedWindowOptionTables",
		DestroyOptionTables, pwOpts);

	/*
	 * Create the paned window option tables.
	 */

	pwOpts->pwOptions = Tk_CreateOptionTable(interp, optionSpecs);
	pwOpts->paneOpts = Tk_CreateOptionTable(interp, paneOptionSpecs);
    }

    Tk_SetClass(tkwin, "Panedwindow");

    /*
     * Allocate and initialize the widget record.
     */

    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,
	    Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd, pwPtr,
	    PanedWindowCmdDeletedProc);
    pwPtr->optionTable = pwOpts->pwOptions;
    pwPtr->paneOpts = pwOpts->paneOpts;
    pwPtr->relief = TK_RELIEF_RAISED;
    pwPtr->gc = NULL;
    pwPtr->cursor = NULL;
    pwPtr->sashCursor = NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the widget,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(pwPtr->tkwin);

    if (Tk_InitOptions(interp, pwPtr, pwOpts->pwOptions,
	    tkwin) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask,
	    PanedWindowEventProc, 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
     * panes in the panedwindow.
     */

    parent = Tk_Parent(pwPtr->tkwin);
    while (!(Tk_IsTopLevel(parent))) {
	parent = Tk_Parent(parent);
	if (parent == NULL) {
	    parent = pwPtr->tkwin;







|










|




|














|






|






|








|





|
|

|










|

|






|




|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
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;
    OptionTables *pwOpts;
    XSetWindowAttributes atts;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    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);
    if (pwOpts == NULL) {
	/*
	 * 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.
	 */

	Tcl_SetAssocData(interp, "PanedWindowOptionTables",
		DestroyOptionTables, (ClientData) pwOpts);

	/*
	 * Create the paned window option tables.
	 */

	pwOpts->pwOptions = Tk_CreateOptionTable(interp, optionSpecs);
	pwOpts->slaveOpts = Tk_CreateOptionTable(interp, slaveOptionSpecs);
    }

    Tk_SetClass(tkwin, "Panedwindow");

    /*
     * Allocate and initialize the widget record.
     */

    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,
	    Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd,
	    (ClientData) pwPtr, PanedWindowCmdDeletedProc);
    pwPtr->optionTable = pwOpts->pwOptions;
    pwPtr->slaveOpts = pwOpts->slaveOpts;
    pwPtr->relief = TK_RELIEF_RAISED;
    pwPtr->gc = NULL;
    pwPtr->cursor = NULL;
    pwPtr->sashCursor = NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the widget,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve((ClientData) pwPtr->tkwin);

    if (Tk_InitOptions(interp, (char *) pwPtr, pwOpts->pwOptions,
	    tkwin) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask,
	    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.
     */

    parent = Tk_Parent(pwPtr->tkwin);
    while (!(Tk_IsTopLevel(parent))) {
	parent = Tk_Parent(parent);
	if (parent == NULL) {
	    parent = pwPtr->tkwin;
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
     * 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,
	    pwPtr);
    atts.save_under = True;
    Tk_ChangeWindowAttributes(pwPtr->proxywin, CWSaveUnder, &atts);

    if (ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->proxywin);
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(pwPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --







|









|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
     * 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,
	    (ClientData) pwPtr);
    atts.save_under = True;
    Tk_ChangeWindowAttributes(pwPtr->proxywin, CWSaveUnder, &atts);

    if (ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->proxywin);
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(pwPtr->tkwin), -1);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606

607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
static int
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 *const 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;
    Pane *panePtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(pwPtr);

    switch ((enum options) index) {
    case PW_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
	    result = TCL_ERROR;
	    break;
	}
	result = ConfigurePanes(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, 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, 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: {


	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++) {
	    Tk_Window pane = Tk_NameToWindow(interp, Tcl_GetString(objv[i]),
		    pwPtr->tkwin);

	    if (pane == NULL) {
		continue;
	    }
	    panePtr = GetPane(pwPtr, pane);
	    if ((panePtr != NULL) && (panePtr->containerPtr != NULL)) {
		count++;
		Tk_ManageGeometry(pane, NULL, NULL);
		Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
		Tk_DeleteEventHandler(panePtr->tkwin, StructureNotifyMask,
			PaneStructureProc, panePtr);
		Tk_UnmapWindow(panePtr->tkwin);
		Unlink(panePtr);
	    }
	    if (count != 0) {
		ComputeGeometry(pwPtr);
	    }
	}
	break;
    }







|

|










|


|








|








|








|











|













>











|

<
|


|
|

|
|
|
|
|
|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
static int
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", 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;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    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);
	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;
	}

	/*
	 * 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;
    }
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728



729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), pwPtr->tkwin);
	if (tkwin == NULL) {
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i]->tkwin == tkwin) {
		resultObj = Tk_GetOptionValue(interp,
			pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numPanes) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"not managed by this window", -1));
		Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED",
			NULL);
	    }

	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;

    case PW_PANECONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "pane ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	if (objc <= 4) {
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    pwPtr->tkwin);
            if (tkwin == NULL) {
                /*
                 * Just a plain old bad window; Tk_NameToWindow filled in an
                 * error message for us.
                 */

                result = TCL_ERROR;
                break;
            }
	    for (i = 0; i < pwPtr->numPanes; i++) {
		if (pwPtr->panes[i]->tkwin == tkwin) {
		    resultObj = Tk_GetOptionInfo(interp,
			    pwPtr->panes[i], pwPtr->paneOpts,
			    (objc == 4) ? objv[3] : NULL,
			    pwPtr->tkwin);
		    if (resultObj == NULL) {
			result = TCL_ERROR;
		    } else {
			Tcl_SetObjResult(interp, resultObj);
		    }
		    break;
		}
	    }
	} else {
	    result = ConfigurePanes(pwPtr, interp, objc, objv);
	}
	break;

    case PW_PANES:
	resultObj = Tcl_NewObj();



	for (i = 0; i < pwPtr->numPanes; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(pwPtr->panes[i]->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);

	break;

    case PW_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;

    case PW_SASH:
	result = PanedWindowSashCommand(pwPtr, interp, objc, objv);
	break;
    }
    Tcl_Release(pwPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigurePanes --
 *
 *	Add or alter the configuration options of a pane in a paned window.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Depends on options; may add a pane to the paned window, may alter the
 *	geometry management options of a pane.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigurePanes(
    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, numNewPanes, haveLoc;
    int insertIndex;
    Tk_Window tkwin = NULL, ancestor, parent;
    Pane *panePtr, **inserts, **newPanes;
    Pane options;
    const char *arg;

    /*
     * Find the non-window name arguments; these are the configure options for
     * the panes. 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] == '-') {
	    break;







|
|

|



<
|
<
|
<
<
|
>









|
















|
|

|











|





>
>
>
|
|
|


>










|






|

|





|
|





|





|


|
|
|



|







661
662
663
664
665
666
667
668
669
670
671
672
673
674

675

676


677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
	}
	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;

    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);
            if (tkwin == NULL) {
                /*
                 * Just a plain old bad window; Tk_NameToWindow filled in an
                 * error message for us.
                 */

                result = TCL_ERROR;
                break;
            }
	    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] : NULL,
			    pwPtr->tkwin);
		    if (resultObj == NULL) {
			result = TCL_ERROR;
		    } else {
			Tcl_SetObjResult(interp, resultObj);
		    }
		    break;
		}
	    }
	} else {
	    result = ConfigureSlaves(pwPtr, interp, objc, objv);
	}
	break;

    case PW_PANES:
	resultObj = Tcl_NewObj();

	Tcl_IncrRefCount(resultObj);

	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_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;

    case PW_SASH:
	result = PanedWindowSashCommand(pwPtr, interp, objc, objv);
	break;
    }
    Tcl_Release((ClientData) pwPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlaves --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static int
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, **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.).
     */

    for (i = 2; i < objc; i++) {
	arg = Tcl_GetString(objv[i]);
	if (arg[0] == '-') {
	    break;
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

		return TCL_ERROR;
	    } else if (tkwin == pwPtr->tkwin) {
		/*
		 * A panedwindow cannot manage itself.
		 */

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't add %s to itself", arg));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
		return TCL_ERROR;
	    } else if (Tk_IsTopLevel(tkwin)) {
		/*
		 * A panedwindow cannot manage a toplevel.
		 */

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't add toplevel %s to %s", arg,
			Tk_PathName(pwPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
		return TCL_ERROR;
	    } else {
		/*
		 * Make sure the panedwindow is the parent of the pane,
		 * or a descendant of the pane's parent.
		 */

		parent = Tk_Parent(tkwin);
		for (ancestor = pwPtr->tkwin;;ancestor = Tk_Parent(ancestor)) {
		    if (ancestor == parent) {
			break;
		    }
		    if (Tk_IsTopLevel(ancestor)) {
			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
				"can't add %s to %s", arg,
				Tk_PathName(pwPtr->tkwin)));
			Tcl_SetErrorCode(interp, "TK", "GEOMETRY",
				"HIERARCHY", NULL);
			return TCL_ERROR;
		    }
		}
	    }
	}
    }
    firstOptionArg = i;

    /*
     * Pre-parse the configuration options, to get the before/after specifiers
     * 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(Pane));
    if (Tk_SetOptions(interp, &options, pwPtr->paneOpts,
	    objc - firstOptionArg, objv + firstOptionArg,
	    pwPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    index = -1;
    haveLoc = 0;
    if (options.after != NULL) {
	tkwin = options.after;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (options.after == pwPtr->panes[i]->tkwin) {
		index = i + 1;
		break;
	    }
	}
    } else if (options.before != NULL) {
	tkwin = options.before;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (options.before == pwPtr->panes[i]->tkwin) {
		index = i;
		break;
	    }
	}
    }

    /*
     * 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_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" is not managed by %s",
		Tk_PathName(tkwin), Tk_PathName(pwPtr->tkwin)));
	Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED", NULL);
	Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts,
		pwPtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * Allocate an array to hold, in order, the pointers to the pane
     * structures corresponding to the windows specified. Some of those
     * structures may already have existed, some may be new.
     */

    inserts = (Pane **)ckalloc(sizeof(Pane *) * (firstOptionArg - 2));
    insertIndex = 0;

    /*
     * Populate the inserts array, creating new pane structures as necessary,
     * applying the options to each structure as we go, and, if necessary,
     * marking the spot in the original panes array as empty (for
     * pre-existing pane structures).
     */

    for (i = 0, numNewPanes = 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);

	found = 0;
	for (j = 0; j < pwPtr->numPanes; j++) {
	    if (pwPtr->panes[j] != NULL && pwPtr->panes[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, pwPtr->panes[j],
			pwPtr->paneOpts, objc - firstOptionArg,
			objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
		if (pwPtr->panes[j]->minSize < 0) {
		    pwPtr->panes[j]->minSize = 0;
		}
		found = 1;

		/*
		 * If the pane is supposed to move, add it to the inserts
		 * array now; otherwise, leave it where it is.
		 */

		if (index != -1) {
		    inserts[insertIndex++] = pwPtr->panes[j];
		    pwPtr->panes[j] = NULL;
		}
		break;
	    }
	}

	if (found) {
	    continue;
	}

	/*
	 * Make sure this pane wasn't already put into the inserts array,
	 * 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) {
		found = 1;
		break;
	    }
	}
	if (found) {
	    continue;
	}

	/*
	 * Create a new pane structure and initialize it. All panes start
	 * out with their "natural" dimensions.
	 */

	panePtr = (Pane *)ckalloc(sizeof(Pane));
	memset(panePtr, 0, sizeof(Pane));
	Tk_InitOptions(interp, panePtr, pwPtr->paneOpts,
		pwPtr->tkwin);
	Tk_SetOptions(interp, panePtr, pwPtr->paneOpts,
		objc - firstOptionArg, objv + firstOptionArg,
		pwPtr->tkwin, NULL, NULL);
	panePtr->tkwin = tkwin;
	panePtr->containerPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	if (panePtr->width > 0) {
	    panePtr->paneWidth = panePtr->width;
	} else {
	    panePtr->paneWidth = Tk_ReqWidth(tkwin) + doubleBw;
	}
	if (panePtr->height > 0) {
	    panePtr->paneHeight = panePtr->height;
	} else {
	    panePtr->paneHeight = Tk_ReqHeight(tkwin) + doubleBw;
	}
	if (panePtr->minSize < 0) {
	    panePtr->minSize = 0;
	}

	/*
	 * Set up the geometry management callbacks for this pane.
	 */

	Tk_CreateEventHandler(panePtr->tkwin, StructureNotifyMask,
		PaneStructureProc, panePtr);
	Tk_ManageGeometry(panePtr->tkwin, &panedWindowMgrType, panePtr);

	inserts[insertIndex++] = panePtr;
	numNewPanes++;
    }

    /*
     * Allocate the new panes array, then copy the panes into it, in order.
     */

    i = sizeof(Pane *) * (pwPtr->numPanes + numNewPanes);
    newPanes = (Pane **)ckalloc(i);
    memset(newPanes, 0, i);
    if (index == -1) {
	/*
	 * If none of the existing panes have to be moved, just copy the old
	 * and append the new.
	 */
	memcpy((void *)&(newPanes[0]), pwPtr->panes,
		sizeof(Pane *) * pwPtr->numPanes);
	memcpy((void *)&(newPanes[pwPtr->numPanes]), inserts,
		sizeof(Pane *) * numNewPanes);
    } else {
	/*
	 * If some of the existing panes were moved, the old panes array
	 * will be partially populated, with some valid and some invalid
	 * entries. Walk through it, copying valid entries to the new panes
	 * array as we go; when we get to the insert location for the new
	 * panes, copy the inserts array over, then finish off the old panes
	 * array.
	 */

	for (i = 0, j = 0; i < index; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}

	memcpy((void *)&(newPanes[j]), inserts, sizeof(Pane *)*insertIndex);
	j += firstOptionArg - 2;

	for (i = index; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}
    }

    /*
     * Make the new panes array the paned window's pane array, and clean up.
     */

    ckfree(pwPtr->panes);
    ckfree(inserts);
    pwPtr->panes = newPanes;

    /*
     * Set the paned window's pane count to the new value.
     */

    pwPtr->numPanes += numNewPanes;

    Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts, pwPtr->tkwin);

    ComputeGeometry(pwPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
|
|






|
|
|
<



|
|








|
|
|
<
<















|
|
















|
|







|
|












|
|
|
<
|





|




|



|

|
|


|









|
|
|
|

|
|




|




|
|










|














|



|
|
|

|


|
|
|
|
|

|

|
|

|

|
|



|


|
|
|
>
|
|



|


|
|
|


|


|
|
|
|


|

|

|




|
|




|


|
|
|






|


|
|
|


|


|

|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831


832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070

		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",
			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), 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) {
			break;
		    }
		    if (Tk_IsTopLevel(ancestor)) {
			Tcl_ResetResult(interp);
			Tcl_AppendResult(interp, "can't add ", arg, " to ",
				Tk_PathName(pwPtr->tkwin), NULL);


			return TCL_ERROR;
		    }
		}
	    }
	}
    }
    firstOptionArg = i;

    /*
     * Pre-parse the configuration options, to get the before/after specifiers
     * 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,
	    pwPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * 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.
     */

    index = -1;
    haveLoc = 0;
    if (options.after != NULL) {
	tkwin = options.after;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numSlaves; i++) {
	    if (options.after == pwPtr->slaves[i]->tkwin) {
		index = i + 1;
		break;
	    }
	}
    } else if (options.before != NULL) {
	tkwin = options.before;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numSlaves; i++) {
	    if (options.before == pwPtr->slaves[i]->tkwin) {
		index = i;
		break;
	    }
	}
    }

    /*
     * 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), NULL);

	Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts,
		pwPtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * Allocate an array to hold, in order, the pointers to the slave
     * 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).
     */

    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);

	found = 0;
	for (j = 0; j < pwPtr->numSlaves; j++) {
	    if (pwPtr->slaves[j] != NULL && pwPtr->slaves[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, (char *) pwPtr->slaves[j],
			pwPtr->slaveOpts, objc - firstOptionArg,
			objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
		if (pwPtr->slaves[j]->minSize < 0) {
		    pwPtr->slaves[j]->minSize = 0;
		}
		found = 1;

		/*
		 * If the slave is supposed to move, add it to the inserts
		 * array now; otherwise, leave it where it is.
		 */

		if (index != -1) {
		    inserts[insertIndex++] = pwPtr->slaves[j];
		    pwPtr->slaves[j] = NULL;
		}
		break;
	    }
	}

	if (found) {
	    continue;
	}

	/*
	 * Make sure this slave wasn't already put into the inserts array,
	 * 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) {
		found = 1;
		break;
	    }
	}
	if (found) {
	    continue;
	}

	/*
	 * 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,
		pwPtr->tkwin);
	Tk_SetOptions(interp, (char *)slavePtr, pwPtr->slaveOpts,
		objc - firstOptionArg, objv + firstOptionArg,
		pwPtr->tkwin, NULL, NULL);
	slavePtr->tkwin = tkwin;
	slavePtr->masterPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
	if (slavePtr->width > 0) {
	    slavePtr->paneWidth = slavePtr->width;
	} else {
	    slavePtr->paneWidth = Tk_ReqWidth(tkwin) + doubleBw;
	}
	if (slavePtr->height > 0) {
	    slavePtr->paneHeight = slavePtr->height;
	} else {
	    slavePtr->paneHeight = Tk_ReqHeight(tkwin) + doubleBw;
	}
	if (slavePtr->minSize < 0) {
	    slavePtr->minSize = 0;
	}

	/*
	 * Set up the geometry management callbacks for this slave.
	 */

	Tk_CreateEventHandler(slavePtr->tkwin, StructureNotifyMask,
		SlaveStructureProc, (ClientData) slavePtr);
	Tk_ManageGeometry(slavePtr->tkwin, &panedWindowMgrType,
		(ClientData) slavePtr);
	inserts[insertIndex++] = slavePtr;
	numNewSlaves++;
    }

    /*
     * Allocate the new slaves array, then copy the slaves into it, in order.
     */

    i = sizeof(Slave *) * (pwPtr->numSlaves+numNewSlaves);
    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 *)&(newSlaves[0]), pwPtr->slaves,
		sizeof(Slave *) * pwPtr->numSlaves);
	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
	 * 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) {
		newSlaves[j] = pwPtr->slaves[i];
		j++;
	    }
	}

	memcpy((void *)&(newSlaves[j]), inserts, sizeof(Slave *)*insertIndex);
	j += firstOptionArg - 2;

	for (i = index; i < pwPtr->numSlaves; i++) {
	    if (pwPtr->slaves[i] != NULL) {
		newSlaves[j] = pwPtr->slaves[i];
		j++;
	    }
	}
    }

    /*
     * Make the new slaves array the paned window's slave array, and clean up.
     */

    ckfree((void *)pwPtr->slaves);
    ckfree((void *)inserts);
    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;
}

/*
 *----------------------------------------------------------------------
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
static int
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 *const 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];
    Pane *panePtr;

    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) {
	return TCL_ERROR;
    }


    switch ((enum sashOptions) index) {
    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 (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewWideIntObj(panePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(panePtr->sashy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(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_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    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->panes[sash]->markx = x;
	    pwPtr->panes[sash]->marky = y;
	} else {
	    coords[0] = Tcl_NewWideIntObj(pwPtr->panes[sash]->markx);
	    coords[1] = Tcl_NewWideIntObj(pwPtr->panes[sash]->marky);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	}
	break;

    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_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    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;
	}

	panePtr = pwPtr->panes[sash];
	if (pwPtr->orient == ORIENT_HORIZONTAL) {
	    if (index == SASH_PLACE) {
		diff = x - pwPtr->panes[sash]->sashx;
	    } else {
		diff = x - pwPtr->panes[sash]->markx;
	    }
	} else {
	    if (index == SASH_PLACE) {
		diff = y - pwPtr->panes[sash]->sashy;
	    } else {
		diff = y - pwPtr->panes[sash]->marky;
	    }
	}

	MoveSash(pwPtr, sash, diff);
	ComputeGeometry(pwPtr);
    }
    return TCL_OK;







|







|











>












|
|
<


|

|
|
|













|
|
<












|
|

|
|
|















|
|
<











|


|

|



|

|







1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
static int
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", 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) {
	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;
	}

	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;

    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 (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;

    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 (Tcl_GetIntFromObj(interp, objv[4], &x) != 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;
	    }
	} else {
	    if (index == SASH_PLACE) {
		diff = y - pwPtr->slaves[sash]->sashy;
	    } else {
		diff = y - pwPtr->slaves[sash]->marky;
	    }
	}

	MoveSash(pwPtr, sash, diff);
	ComputeGeometry(pwPtr);
    }
    return TCL_OK;
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
    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, pwPtr, pwPtr->optionTable, objc, objv,
	    pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }

    Tk_FreeSavedOptions(&savedOptions);

    PanedWindowWorldChanged(pwPtr);

    /*
     * If an option that affects geometry has changed, make a re-layout
     * request.
     */

    if (typemask & GEOMETRY) {







|







|







1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
    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);
	return TCL_ERROR;
    }

    Tk_FreeSavedOptions(&savedOptions);

    PanedWindowWorldChanged((ClientData) pwPtr);

    /*
     * If an option that affects geometry has changed, make a re-layout
     * request.
     */

    if (typemask & GEOMETRY) {
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304

static void
PanedWindowWorldChanged(
    ClientData instanceData)	/* Information about the paned window. */
{
    XGCValues gcValues;
    GC newGC;
    PanedWindow *pwPtr = (PanedWindow *)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;







|







1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300

static void
PanedWindowWorldChanged(
    ClientData instanceData)	/* Information about the paned window. */
{
    XGCValues gcValues;
    GC newGC;
    PanedWindow *pwPtr = (PanedWindow *) 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;
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
    }

    /*
     * Arrange for the window to be redrawn, if neccessary.
     */

    if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr);
	pwPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *







|







1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
    }

    /*
     * Arrange for the window to be redrawn, if neccessary.
     */

    if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr);
	pwPtr->flags |= REDRAW_PENDING;
    }
}

/*
 *--------------------------------------------------------------
 *
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
 */

static void
PanedWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    int i;

    if (eventPtr->type == Expose) {
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr);
	    pwPtr->flags |= REDRAW_PENDING;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	pwPtr->flags |= REQUESTED_RELAYOUT;
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr);
	    pwPtr->flags |= REDRAW_PENDING;
	}
    } else if (eventPtr->type == DestroyNotify) {
	DestroyPanedWindow(pwPtr);
    } else if (eventPtr->type == UnmapNotify) {
        for (i = 0; i < pwPtr->numPanes; i++) {
            if (!pwPtr->panes[i]->hide) {
                Tk_UnmapWindow(pwPtr->panes[i]->tkwin);
            }
        }
    } else if (eventPtr->type == MapNotify) {
        for (i = 0; i < pwPtr->numPanes; i++) {
            if (!pwPtr->panes[i]->hide) {
                Tk_MapWindow(pwPtr->panes[i]->tkwin);
            }
        }
    }
}

/*
 *----------------------------------------------------------------------
 *







|




|





|





|
<
|
|
<

|
<
|
<







1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367

1368
1369

1370
1371

1372

1373
1374
1375
1376
1377
1378
1379
 */

static void
PanedWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *) clientData;
    int i;

    if (eventPtr->type == Expose) {
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr);
	    pwPtr->flags |= REDRAW_PENDING;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	pwPtr->flags |= REQUESTED_RELAYOUT;
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr);
	    pwPtr->flags |= REDRAW_PENDING;
	}
    } else if (eventPtr->type == DestroyNotify) {
	DestroyPanedWindow(pwPtr);
    } else if (eventPtr->type == UnmapNotify) {
        for (i = 0; i < pwPtr->numSlaves; i++) {

            Tk_UnmapWindow(pwPtr->slaves[i]->tkwin);
        }

    } else if (eventPtr->type == MapNotify) {
        for (i = 0; i < pwPtr->numSlaves; i++) {

            Tk_MapWindow(pwPtr->slaves[i]->tkwin);

        }
    }
}

/*
 *----------------------------------------------------------------------
 *
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
 *----------------------------------------------------------------------
 */

static void
PanedWindowCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    /*
     * 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.
     */







|







1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
 *----------------------------------------------------------------------
 */

static void
PanedWindowCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    PanedWindow *pwPtr = (PanedWindow *) clientData;

    /*
     * 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.
     */
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
 *--------------------------------------------------------------
 */

static void
DisplayPanedWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->tkwin;
    int i, sashWidth, sashHeight;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
    int first, last;

    pwPtr->flags &= ~REDRAW_PENDING;







|
|







1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
 *--------------------------------------------------------------
 */

static void
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);
    int first, last;

    pwPtr->flags &= ~REDRAW_PENDING;
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517

    /*
     * Set up boilerplate geometry values for sashes (width, height, common
     * coordinates).
     */

    if (horizontal) {
	sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderLeft(tkwin));
	sashWidth = pwPtr->sashWidth;
    } else {
	sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderLeft(tkwin));
	sashHeight = pwPtr->sashWidth;
    }

    /*
     * Draw the sashes.
     */

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    for (i = 0; i < pwPtr->numPanes - 1; i++) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide || i == last) {
	    continue;
	}
	if (sashWidth > 0 && sashHeight > 0) {
	    Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
		    panePtr->sashx, panePtr->sashy, sashWidth, sashHeight,
		    1, pwPtr->sashRelief);
	}
	if (pwPtr->showHandle) {
	    Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
		    panePtr->handlex, panePtr->handley,
		    pwPtr->handleSize, pwPtr->handleSize, 1,
		    TK_RELIEF_RAISED);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*







|


|








|
|
|




|




|







1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509

    /*
     * Set up boilerplate geometry values for sashes (width, height, common
     * coordinates).
     */

    if (horizontal) {
	sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderWidth(tkwin));
	sashWidth = pwPtr->sashWidth;
    } else {
	sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderWidth(tkwin));
	sashHeight = pwPtr->sashWidth;
    }

    /*
     * Draw the sashes.
     */

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    for (i = 0; i < pwPtr->numSlaves - 1; i++) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide || i == last) {
	    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,
		    pwPtr->handleSize, pwPtr->handleSize, 1,
		    TK_RELIEF_RAISED);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611

    /*
     * Cancel idle callbacks for redrawing the widget and for rearranging the
     * panes.
     */

    if (pwPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(DisplayPanedWindow, pwPtr);
    }
    if (pwPtr->flags & RESIZE_PENDING) {
	Tcl_CancelIdleCall(ArrangePanes, pwPtr);
    }

    /*
     * Clean up the pane list; foreach pane:
     *  o  Cancel the pane's structure notification callback
     *  o  Cancel geometry management for the pane.
     *  o  Free memory for the pane
     */

    for (i = 0; i < pwPtr->numPanes; i++) {
	Tk_DeleteEventHandler(pwPtr->panes[i]->tkwin, StructureNotifyMask,
		PaneStructureProc, pwPtr->panes[i]);
	Tk_ManageGeometry(pwPtr->panes[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions((char *) pwPtr->panes[i], pwPtr->paneOpts,
		pwPtr->tkwin);
	ckfree(pwPtr->panes[i]);
	pwPtr->panes[i] = NULL;
    }
    if (pwPtr->panes) {
	ckfree(pwPtr->panes);
    }

    /*
     * Remove the widget command from the interpreter.
     */

    Tcl_DeleteCommandFromToken(pwPtr->interp, pwPtr->widgetCmd);

    /*
     * Let Tk_FreeConfigOptions clean up the rest.
     */

    Tk_FreeConfigOptions((char *) pwPtr, pwPtr->optionTable, pwPtr->tkwin);
    Tcl_Release(pwPtr->tkwin);
    pwPtr->tkwin = NULL;

    Tcl_EventuallyFree(pwPtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowReqProc --
 *







|


|



|
|
|
|


|
|
|
|
|

|
|

|
|













|


|







1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603

    /*
     * Cancel idle callbacks for redrawing the widget and for rearranging the
     * panes.
     */

    if (pwPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(DisplayPanedWindow, (ClientData) pwPtr);
    }
    if (pwPtr->flags & RESIZE_PENDING) {
	Tcl_CancelIdleCall(ArrangePanes, (ClientData) pwPtr);
    }

    /*
     * Clean up the slave list; foreach slave:
     *  o  Cancel the slave's structure notification callback
     *  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]);
	Tk_ManageGeometry(pwPtr->slaves[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions((char *)pwPtr->slaves[i], pwPtr->slaveOpts,
		pwPtr->tkwin);
	ckfree((void *)pwPtr->slaves[i]);
	pwPtr->slaves[i] = NULL;
    }
    if (pwPtr->slaves) {
	ckfree((char *) pwPtr->slaves);
    }

    /*
     * Remove the widget command from the interpreter.
     */

    Tcl_DeleteCommandFromToken(pwPtr->interp, pwPtr->widgetCmd);

    /*
     * Let Tk_FreeConfigOptions clean up the rest.
     */

    Tk_FreeConfigOptions((char *) pwPtr, pwPtr->optionTable, pwPtr->tkwin);
    Tcl_Release((ClientData) pwPtr->tkwin);
    pwPtr->tkwin = NULL;

    Tcl_EventuallyFree((ClientData) pwPtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowReqProc --
 *
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
 *--------------------------------------------------------------
 */

static void
PanedWindowReqProc(
    ClientData clientData,	/* Paned window's information about window
				 * that got new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;

    if (Tk_IsMapped(pwPtr->tkwin)) {
	if (!(pwPtr->flags & RESIZE_PENDING)) {
	    pwPtr->flags |= RESIZE_PENDING;
	    Tcl_DoWhenIdle(ArrangePanes, pwPtr);
	}
    } else {
	int doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;

	if (panePtr->width <= 0) {
	    panePtr->paneWidth = Tk_ReqWidth(panePtr->tkwin) + doubleBw;
	}
	if (panePtr->height <= 0) {
	    panePtr->paneHeight = Tk_ReqHeight(panePtr->tkwin) + doubleBw;
	}
	ComputeGeometry(pwPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowLostPaneProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a pane that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all information about the pane. Causes geometry to be
 *	recomputed for the panedwindow.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowLostPaneProc(
    ClientData clientData,	/* Grid structure for the pane that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the pane. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;

    if (pwPtr->tkwin != Tk_Parent(panePtr->tkwin)) {
	Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
    }
    Unlink(panePtr);
    Tk_DeleteEventHandler(panePtr->tkwin, StructureNotifyMask,
	    PaneStructureProc, panePtr);
    Tk_UnmapWindow(panePtr->tkwin);
    panePtr->tkwin = NULL;
    ckfree(panePtr);
    ComputeGeometry(pwPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ArrangePanes --
 *
 *	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.
 *
 * Side effects:
 *	The panes of containerPtr may get resized or moved.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePanes(
    ClientData clientData)	/* Structure describing parent whose panes
				 * are to be re-layed out. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    int i, newPaneWidth, newPaneHeight, paneX, paneY;
    int paneWidth, paneHeight, paneSize, paneMinSize;
    int doubleBw;
    int x, y;
    int sashWidth, sashOffset, sashCount, handleOffset;
    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);

    pwPtr->flags &= ~(REQUESTED_RELAYOUT|RESIZE_PENDING);

    /*
     * If the parent has no panes 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->numPanes == 0) {
	return;
    }

    Tcl_Preserve(pwPtr);

    /*
     * Find index of first and last visible panes.
     */

    GetFirstLastVisiblePane(pwPtr, &first, &last);

    /*
     * First pass; compute sizes
     */

    paneDynSize = paneDynMinSize = 0;
    internalBW = Tk_InternalBorderLeft(pwPtr->tkwin);
    pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
    pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
    x = y = internalBW;
    stretchReserve = (horizontal ? pwWidth : pwHeight);

    /*
     * Calculate the sash width, including handle and padding, and the sash







|


|
|
<



|


|

|
|

|
|








|


|





|






|
|

|

|
|

|
|

|
|
|
|
|
|

















|






|


|
|
|














|





|



|












|







1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625

1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
 *--------------------------------------------------------------
 */

static void
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);

    if (Tk_IsMapped(pwPtr->tkwin)) {
	if (!(pwPtr->flags & RESIZE_PENDING)) {
	    pwPtr->flags |= RESIZE_PENDING;
	    Tcl_DoWhenIdle(ArrangePanes, (ClientData) pwPtr);
	}
    } else {
	int doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;

	if (slavePtr->width <= 0) {
	    slavePtr->paneWidth = Tk_ReqWidth(slavePtr->tkwin) + doubleBw;
	}
	if (slavePtr->height <= 0) {
	    slavePtr->paneHeight = Tk_ReqHeight(slavePtr->tkwin) + doubleBw;
	}
	ComputeGeometry(pwPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowLostSlaveProc --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
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);
    }
    Unlink(slavePtr);
    Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask,
	    SlaveStructureProc, (ClientData) slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
    slavePtr->tkwin = NULL;
    ckfree((void *)slavePtr);
    ComputeGeometry(pwPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ArrangePanes --
 *
 *	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.
 *
 * Side effects:
 *	The slaves of masterPtr may get resized or moved.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePanes(
    ClientData clientData)	/* Structure describing parent whose slaves
				 * are to be re-layed out. */
{
    register PanedWindow *pwPtr = (PanedWindow *) clientData;
    register Slave *slavePtr;
    int i, slaveWidth, slaveHeight, slaveX, slaveY;
    int paneWidth, paneHeight, paneSize, paneMinSize;
    int doubleBw;
    int x, y;
    int sashWidth, sashOffset, sashCount, handleOffset;
    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);

    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 (pwPtr->numSlaves == 0) {
	return;
    }

    Tcl_Preserve((ClientData) pwPtr);

    /*
     * Find index of first and last visible panes.
     */

    GetFirstLastVisiblePane(pwPtr, &first, &last);

    /*
     * First pass; compute sizes
     */

    paneDynSize = paneDynMinSize = 0;
    internalBW = Tk_InternalBorderWidth(pwPtr->tkwin);
    pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
    pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
    x = y = internalBW;
    stretchReserve = (horizontal ? pwWidth : pwHeight);

    /*
     * Calculate the sash width, including handle and padding, and the sash
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    for (i = sashCount = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (panePtr->hide) {
	    continue;
	}

	/*
	 * Compute the total size needed by all the panes and the left-over,
	 * or shortage of space available.
	 */

	if (horizontal) {
            if (panePtr->width > 0) {
                paneSize = panePtr->width;
            } else {
                paneSize = panePtr->paneWidth;
            }
	    stretchReserve -= paneSize + (2 * panePtr->padx);
	} else {
            if (panePtr->height > 0) {
                paneSize = panePtr->height;
            } else {
                paneSize = panePtr->paneHeight;
            }
	    stretchReserve -= paneSize + (2 * panePtr->pady);
	}
	if (IsStretchable(panePtr->stretch,i,first,last)
		&& Tk_IsMapped(pwPtr->tkwin)) {
	    paneDynSize += paneSize;
	    paneDynMinSize += panePtr->minSize;
	}
	if (i != last) {
	    stretchReserve -= sashWidth;
	    sashCount++;
	}
    }

    /*
     * Second pass; adjust/arrange panes.
     */

    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (panePtr->hide) {
	    Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(panePtr->tkwin);
	    continue;
	}

	/*
	 * Compute the size of this pane. The algorithm (assuming a
	 * horizontal paned window) is:
	 *
	 * 1.  Get "base" dimensions. If a width or height is specified for
	 *     this pane, 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.
	 */

	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	newPaneWidth = (panePtr->width > 0 ? panePtr->width :
		Tk_ReqWidth(panePtr->tkwin) + doubleBw);
	newPaneHeight = (panePtr->height > 0 ? panePtr->height :
		Tk_ReqHeight(panePtr->tkwin) + doubleBw);
	paneMinSize = panePtr->minSize;

	/*
	 * Calculate pane width and height.
	 */

	if (horizontal) {
            if (panePtr->width > 0) {
                paneSize = panePtr->width;
            } else {
                paneSize = panePtr->paneWidth;
            }
	    pwSize = pwWidth;
	} else {
            if (panePtr->height > 0) {
                paneSize = panePtr->height;
            } else {
                paneSize = panePtr->paneHeight;
            }
	    pwSize = pwHeight;
	}
	if (IsStretchable(panePtr->stretch, i, first, last)) {
	    double frac;

	    if (paneDynSize > 0) {
		frac = (double)paneSize / (double)paneDynSize;
	    } else {
		frac = (double)paneSize / (double)pwSize;
	    }

	    paneDynSize -= paneSize;
	    paneDynMinSize -= panePtr->minSize;
	    stretchAmount = (int) (frac * stretchReserve);
	    if (paneSize + stretchAmount >= paneMinSize) {
		stretchReserve -= stretchAmount;
		paneSize += stretchAmount;
	    } else {
		stretchReserve += paneSize - paneMinSize;
		paneSize = paneMinSize;







|
|

|




|




<
<
<
|
<
|

<
<
<
|
<
|

|


|











|
|

|
|
|




|



|





|
|
|
|
|
|






<
<
<
|
<


<
<
<
|
<


|









|







1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781



1782

1783
1784



1785

1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834



1835

1836
1837



1838

1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    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.
	 */

	if (horizontal) {



	    paneSize = slavePtr->paneWidth;

	    stretchReserve -= paneSize + (2 * slavePtr->padx);
	} else {



	    paneSize = slavePtr->paneHeight;

	    stretchReserve -= paneSize + (2 * slavePtr->pady);
	}
	if (IsStretchable(slavePtr->stretch,i,first,last)
		&& Tk_IsMapped(pwPtr->tkwin)) {
	    paneDynSize += paneSize;
	    paneDynMinSize += slavePtr->minSize;
	}
	if (i != last) {
	    stretchReserve -= sashWidth;
	    sashCount++;
	}
    }

    /*
     * Second pass; adjust/arrange panes.
     */

    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
	 * 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.
	 * 2.  Using base dimensions, pane dimensions, and sticky values,
	 *     determine the x and y, and actual width and height of the
	 *     widget.
	 */

	doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
	slaveWidth = (slavePtr->width > 0 ? slavePtr->width :
		Tk_ReqWidth(slavePtr->tkwin) + doubleBw);
	slaveHeight = (slavePtr->height > 0 ? slavePtr->height :
		Tk_ReqHeight(slavePtr->tkwin) + doubleBw);
	paneMinSize = slavePtr->minSize;

	/*
	 * Calculate pane width and height.
	 */

	if (horizontal) {



	    paneSize = slavePtr->paneWidth;

	    pwSize = pwWidth;
	} else {



	    paneSize = slavePtr->paneHeight;

	    pwSize = pwHeight;
	}
	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;
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
	    } else {
		paneSize += paneDynSize - paneDynMinSize + stretchReserve;
		stretchReserve = paneDynMinSize - paneDynSize;
	    }
	}
	if (horizontal) {
	    paneWidth = paneSize;
	    paneHeight = pwHeight - (2 * panePtr->pady);
	} else {
	    paneWidth = pwWidth - (2 * panePtr->padx);
	    paneHeight = paneSize;
	}

	/*
	 * Adjust for area reserved for sashes.
	 */








|

|







1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
	    } else {
		paneSize += paneDynSize - paneDynMinSize + stretchReserve;
		stretchReserve = paneDynMinSize - paneDynSize;
	    }
	}
	if (horizontal) {
	    paneWidth = paneSize;
	    paneHeight = pwHeight - (2 * slavePtr->pady);
	} else {
	    paneWidth = pwWidth - (2 * slavePtr->padx);
	    paneHeight = paneSize;
	}

	/*
	 * Adjust for area reserved for sashes.
	 */

1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
	if (pwWidth - sxReserve < x + paneWidth - internalBW) {
	    paneWidth = pwWidth - sxReserve - x + internalBW;
	}
	if (pwHeight - syReserve < y + paneHeight - internalBW) {
	    paneHeight = pwHeight - syReserve - y + internalBW;
	}

	if (newPaneWidth > paneWidth) {
	    newPaneWidth = paneWidth;
	}
	if (newPaneHeight > paneHeight) {
	    newPaneHeight = paneHeight;
	}

	panePtr->x = x;
	panePtr->y = y;

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel and the location of the next parcel.
	 */

	if (horizontal) {
	    x += paneWidth + (2 * panePtr->padx);
	    if (x < internalBW) {
		x = internalBW;
	    }
	    panePtr->sashx = x + sashOffset;
	    panePtr->sashy = y;
	    panePtr->handlex = x + handleOffset;
	    panePtr->handley = y + pwPtr->handlePad;
	    x += sashWidth;
	} else {
	    y += paneHeight + (2 * panePtr->pady);
	    if (y < internalBW) {
		y = internalBW;
	    }
	    panePtr->sashx = x;
	    panePtr->sashy = y + sashOffset;
	    panePtr->handlex = x + pwPtr->handlePad;
	    panePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Compute the actual dimensions of the pane in the pane.
	 */

	paneX = panePtr->x;
	paneY = panePtr->y;
	AdjustForSticky(panePtr->sticky, paneWidth, paneHeight,
		&paneX, &paneY, &newPaneWidth, &newPaneHeight);

	paneX += panePtr->padx;
	paneY += panePtr->pady;

	/*
	 * Now put the window in the proper spot.
	 */

	if (newPaneWidth <= 0 || newPaneHeight <= 0 ||
		(horizontal ? paneX - internalBW > pwWidth :
		paneY - internalBW > pwHeight)) {
	    Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(panePtr->tkwin);
	} else {
	    Tk_MaintainGeometry(panePtr->tkwin, pwPtr->tkwin,
		    paneX, paneY, newPaneWidth, newPaneHeight);
	}
	sashCount--;
    }
    Tcl_Release(pwPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a pane from a paned window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The paned window will be scheduled for re-arranging and redrawing.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Pane *panePtr)		/* Window to unlink. */
{
    PanedWindow *containerPtr;
    int i, j;

    containerPtr = panePtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }

    /*
     * Find the specified pane in the panedwindow's list of panes, then
     * remove it from that list.
     */

    for (i = 0; i < containerPtr->numPanes; i++) {
	if (containerPtr->panes[i] == panePtr) {
	    for (j = i; j < containerPtr->numPanes - 1; j++) {
		containerPtr->panes[j] = containerPtr->panes[j + 1];
	    }
	    break;
	}
    }

    /*
     * Clean out any -after or -before references to this pane
     */

    for (i = 0; i < containerPtr->numPanes; i++) {
	if (containerPtr->panes[i]->before == panePtr->tkwin) {
	    containerPtr->panes[i]->before = NULL;
	}
	if (containerPtr->panes[i]->after == panePtr->tkwin) {
	    containerPtr->panes[i]->after = NULL;
	}
    }

    containerPtr->flags |= REQUESTED_RELAYOUT;
    if (!(containerPtr->flags & REDRAW_PENDING)) {
	containerPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, containerPtr);
    }

    /*
     * Set the pane's containerPtr to NULL, so that we can tell that the pane
     * is no longer attached to any panedwindow.
     */

    panePtr->containerPtr = NULL;

    containerPtr->numPanes--;
}

/*
 *----------------------------------------------------------------------
 *
 * GetPane --
 *
 *	Given a token to a Tk window, find the pane that corresponds to that
 *	token in a given paned window.
 *
 * Results:
 *	Pointer to the pane structure, or NULL if the window is not managed
 *	by this paned window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Pane *
GetPane(
    PanedWindow *pwPtr,		/* Pointer to the paned window info. */
    Tk_Window tkwin)		/* Window to search for. */
{
    int i;

    for (i = 0; i < pwPtr->numPanes; i++) {
	if (pwPtr->panes[i]->tkwin == tkwin) {
	    return pwPtr->panes[i];
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







|
|

|
|


|
|







|



|
|
|
|


|



|
|
|
|




|


|
|
|
|

|
|





|
|
|
|
|

|
|



|







|












|

|


|
|




|



|
|
|
|






|


|
|
|

|
|



|
|
|
|



|



|

|











|








|






|
|
|







1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
	if (pwWidth - sxReserve < x + paneWidth - internalBW) {
	    paneWidth = pwWidth - sxReserve - x + internalBW;
	}
	if (pwHeight - syReserve < y + paneHeight - internalBW) {
	    paneHeight = pwHeight - syReserve - y + internalBW;
	}

	if (slaveWidth > paneWidth) {
	    slaveWidth = paneWidth;
	}
	if (slaveHeight > paneHeight) {
	    slaveHeight = paneHeight;
	}

	slavePtr->x = x;
	slavePtr->y = y;

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel and the location of the next parcel.
	 */

	if (horizontal) {
	    x += paneWidth + (2 * slavePtr->padx);
	    if (x < internalBW) {
		x = internalBW;
	    }
	    slavePtr->sashx = x + sashOffset;
	    slavePtr->sashy = y;
	    slavePtr->handlex = x + handleOffset;
	    slavePtr->handley = y + pwPtr->handlePad;
	    x += sashWidth;
	} else {
	    y += paneHeight + (2 * slavePtr->pady);
	    if (y < internalBW) {
		y = internalBW;
	    }
	    slavePtr->sashx = x;
	    slavePtr->sashy = y + sashOffset;
	    slavePtr->handlex = x + pwPtr->handlePad;
	    slavePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Compute the actual dimensions of the slave in the pane.
	 */

	slaveX = slavePtr->x;
	slaveY = slavePtr->y;
	AdjustForSticky(slavePtr->sticky, paneWidth, paneHeight,
		&slaveX, &slaveY, &slaveWidth, &slaveHeight);

	slaveX += slavePtr->padx;
	slaveY += slavePtr->pady;

	/*
	 * Now put the window in the proper spot.
	 */

	if (slaveWidth <= 0 || slaveHeight <= 0 ||
		(horizontal ? slaveX - internalBW > pwWidth :
		slaveY - internalBW > pwHeight)) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(slavePtr->tkwin);
	} else {
	    Tk_MaintainGeometry(slavePtr->tkwin, pwPtr->tkwin,
		    slaveX, slaveY, slaveWidth, slaveHeight);
	}
	sashCount--;
    }
    Tcl_Release((ClientData) pwPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a slave from a paned window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The paned window will be scheduled for re-arranging and redrawing.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    register Slave *slavePtr)		/* Window to unlink. */
{
    register PanedWindow *masterPtr;
    int i, j;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
	return;
    }

    /*
     * Find the specified slave in the panedwindow's list of slaves, then
     * remove it from that list.
     */

    for (i = 0; i < masterPtr->numSlaves; i++) {
	if (masterPtr->slaves[i] == slavePtr) {
	    for (j = i; j < masterPtr->numSlaves - 1; j++) {
		masterPtr->slaves[j] = masterPtr->slaves[j + 1];
	    }
	    break;
	}
    }

    /*
     * 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 = NULL;
	}
	if (masterPtr->slaves[i]->after == slavePtr->tkwin) {
	    masterPtr->slaves[i]->after = NULL;
	}
    }

    masterPtr->flags |= REQUESTED_RELAYOUT;
    if (!(masterPtr->flags & REDRAW_PENDING)) {
	masterPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) masterPtr);
    }

    /*
     * 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--;
}

/*
 *----------------------------------------------------------------------
 *
 * GetPane --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Slave *
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];
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
GetFirstLastVisiblePane(
    PanedWindow *pwPtr,		/* Pointer to the paned window info. */
    int *firstPtr, 		/* Returned index for first. */
    int *lastPtr)  		/* Returned index for last. */
{
    int i;

    for (i = 0, *lastPtr = 0, *firstPtr = -1; i < pwPtr->numPanes; i++) {
	if (pwPtr->panes[i]->hide == 0) {
	    if (*firstPtr < 0) {
		*firstPtr = i;
	    }
	    *lastPtr = i;
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * PaneStructureProc --
 *
 *	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.
 *
 * Side effects:
 *	The paned window pane structure associated with the window
 *	is freed, and the pane is disassociated from the paned
 *	window which managed it.
 *
 *--------------------------------------------------------------
 */

static void
PaneStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = panePtr->containerPtr;

    if (eventPtr->type == DestroyNotify) {
	Unlink(panePtr);
	panePtr->tkwin = NULL;
	ckfree(panePtr);
	ComputeGeometry(pwPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeGeometry --
 *
 *	Compute geometry for the paned window, including coordinates of all
 *	panes and each sash.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Recomputes geometry information for a paned window.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeGeometry(
    PanedWindow *pwPtr)		/* Pointer to the Paned Window structure. */
{
    int i, x, y, doubleBw, internalBw;
    int sashWidth, sashOffset, handleOffset;
    int reqWidth, reqHeight, dim;
    Pane *panePtr;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);

    pwPtr->flags |= REQUESTED_RELAYOUT;

    x = y = internalBw = Tk_InternalBorderLeft(pwPtr->tkwin);
    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).
     */

    sashOffset = handleOffset = pwPtr->sashPad;
    if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->handleSize;
	sashOffset = ((pwPtr->handleSize - pwPtr->sashWidth) / 2)
		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (panePtr->hide) {
	    continue;
	}

	/*
	 * First set the coordinates for the top left corner of the pane's
	 * parcel.
	 */

	panePtr->x = x;
	panePtr->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.
	 */

	if (horizontal) {
	    if (panePtr->paneWidth < panePtr->minSize) {
		panePtr->paneWidth = panePtr->minSize;
	    }
	} else {
	    if (panePtr->paneHeight < panePtr->minSize) {
		panePtr->paneHeight = panePtr->minSize;
	    }
	}

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel.
	 */

	if (horizontal) {
	    x += panePtr->paneWidth + (2 * panePtr->padx);
	    panePtr->sashx = x + sashOffset;
	    panePtr->sashy = y;
	    panePtr->handlex = x + handleOffset;
	    panePtr->handley = y + pwPtr->handlePad;
	    x += sashWidth;
	} else {
	    y += panePtr->paneHeight + (2 * panePtr->pady);
	    panePtr->sashx = x;
	    panePtr->sashy = y + sashOffset;
	    panePtr->handlex = x + pwPtr->handlePad;
	    panePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Find the maximum height/width of the panes, for computing the
	 * requested height/width of the paned window.
	 */

	if (horizontal) {
	    /*
	     * If the pane has an explicit height set, use that; otherwise,
	     * use the pane's requested height.
	     */

	    if (panePtr->height > 0) {
		dim = panePtr->height;
	    } else {
		doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
		dim = Tk_ReqHeight(panePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * panePtr->pady;
	    if (dim > reqHeight) {
		reqHeight = dim;
	    }
	} else {
	    /*
	     * If the pane has an explicit width set use that; otherwise, use
	     * the pane's requested width.
	     */

	    if (panePtr->width > 0) {
		dim = panePtr->width;
	    } else {
		doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
		dim = Tk_ReqWidth(panePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * panePtr->padx;
	    if (dim > reqWidth) {
		reqWidth = dim;
	    }
	}
    }

    /*
     * 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.
     *
     * The height (or width) is equal to the maximum height (or width) of the
     * panes, 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 (horizontal) {
	reqWidth = (pwPtr->width > 0 ?
		pwPtr->width : x - sashWidth + internalBw);
	reqHeight = (pwPtr->height > 0 ?
		pwPtr->height : reqHeight + (2 * internalBw));
    } else {
	reqWidth = (pwPtr->width > 0 ?
		pwPtr->width : reqWidth + (2 * internalBw));
	reqHeight = (pwPtr->height > 0 ?
		pwPtr->height : y - sashWidth + internalBw);
    }
    Tk_GeometryRequest(pwPtr->tkwin, reqWidth, reqHeight);
    if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) {
	pwPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyOptionTables --







|
|











|









|
|






|



|
|


|
|
|










|

















|




|




















|
|

|




|



|
|








|
|


|
|









|
|
|
|
|


|
|
|
|
|




|





|
|


|
|

|
|

|





|
|


|
|

|
|

|

















|




















|







2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
GetFirstLastVisiblePane(
    PanedWindow *pwPtr,		/* Pointer to the paned window info. */
    int *firstPtr, 		/* Returned index for first. */
    int *lastPtr)  		/* Returned index for last. */
{
    int i;

    for (i = 0, *lastPtr = 0, *firstPtr = -1; i < pwPtr->numSlaves; i++) {
	if (pwPtr->slaves[i]->hide == 0) {
	    if (*firstPtr < 0) {
		*firstPtr = i;
	    }
	    *lastPtr = i;
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * SlaveStructureProc --
 *
 *	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.
 *
 * Side effects:
 *	The paned window slave structure associated with the window
 *	is freed, and the slave is disassociated from the paned
 *	window which managed it.
 *
 *--------------------------------------------------------------
 */

static void
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;
	ckfree((void *)slavePtr);
	ComputeGeometry(pwPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeGeometry --
 *
 *	Compute geometry for the paned window, including coordinates of all
 *	slave windows and each sash.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Recomputes geometry information for a paned window.
 *
 *----------------------------------------------------------------------
 */

static void
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);

    pwPtr->flags |= REQUESTED_RELAYOUT;

    x = y = internalBw = Tk_InternalBorderWidth(pwPtr->tkwin);
    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).
     */

    sashOffset = handleOffset = pwPtr->sashPad;
    if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->handleSize;
	sashOffset = ((pwPtr->handleSize - pwPtr->sashWidth) / 2)
		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    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.
	 */

	slavePtr->x = x;
	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.
	 */

	if (horizontal) {
	    if (slavePtr->paneWidth < slavePtr->minSize) {
		slavePtr->paneWidth = slavePtr->minSize;
	    }
	} else {
	    if (slavePtr->paneHeight < slavePtr->minSize) {
		slavePtr->paneHeight = slavePtr->minSize;
	    }
	}

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel.
	 */

	if (horizontal) {
	    x += slavePtr->paneWidth + (2 * slavePtr->padx);
	    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->handlex = x + pwPtr->handlePad;
	    slavePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Find the maximum height/width of the slaves, for computing the
	 * requested height/width of the paned window.
	 */

	if (horizontal) {
	    /*
	     * If the slave has an explicit height set, use that; otherwise,
	     * use the slave's requested height.
	     */

	    if (slavePtr->height > 0) {
		dim = slavePtr->height;
	    } else {
		doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
		dim = Tk_ReqHeight(slavePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * slavePtr->pady;
	    if (dim > reqHeight) {
		reqHeight = dim;
	    }
	} else {
	    /*
	     * If the slave has an explicit width set use that; otherwise, use
	     * the slave's requested width.
	     */

	    if (slavePtr->width > 0) {
		dim = slavePtr->width;
	    } else {
		doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
		dim = Tk_ReqWidth(slavePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * slavePtr->padx;
	    if (dim > reqWidth) {
		reqWidth = dim;
	    }
	}
    }

    /*
     * 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.
     *
     * 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 (horizontal) {
	reqWidth = (pwPtr->width > 0 ?
		pwPtr->width : x - sashWidth + internalBw);
	reqHeight = (pwPtr->height > 0 ?
		pwPtr->height : reqHeight + (2 * internalBw));
    } else {
	reqWidth = (pwPtr->width > 0 ?
		pwPtr->width : reqWidth + (2 * internalBw));
	reqHeight = (pwPtr->height > 0 ?
		pwPtr->height : y - sashWidth + internalBw);
    }
    Tk_GeometryRequest(pwPtr->tkwin, reqWidth, reqHeight);
    if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) {
	pwPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyOptionTables --
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374

2375
2376
2377
2378
2379
2380
2381
 *
 *----------------------------------------------------------------------
 */

static void
DestroyOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    TCL_UNUSED(Tcl_Interp *))		/* Pointer to the calling interp */
{
    ckfree(clientData);

}

/*
 *----------------------------------------------------------------------
 *
 * GetSticky -
 *







|

|
>







2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
 *
 *----------------------------------------------------------------------
 */

static void
DestroyOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *interp)		/* Pointer to the calling interp */
{
    ckfree((char *)clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * GetSticky -
 *
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
 *	Creates a new Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];

    if (sticky & STICK_NORTH) {
	*p++ = 'n';
    }
    if (sticky & STICK_EAST) {
	*p++ = 'e';
    }
    if (sticky & STICK_SOUTH) {
	*p++ = 's';
    }
    if (sticky & STICK_WEST) {
	*p++ = 'w';
    }
    *p = '\0';

    return Tcl_NewStringObj(buffer, -1);
}

/*
 *----------------------------------------------------------------------
 *







|
|

|



|
|


|


|


|


|

|







2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
 *	Creates a new Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
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);
    static char buffer[5];
    int count = 0;

    if (sticky & STICK_NORTH) {
	buffer[count++] = 'n';
    }
    if (sticky & STICK_EAST) {
	buffer[count++] = 'e';
    }
    if (sticky & STICK_SOUTH) {
	buffer[count++] = 's';
    }
    if (sticky & STICK_WEST) {
	buffer[count++] = 'w';
    }
    buffer[count] = '\0';

    return Tcl_NewStringObj(buffer, -1);
}

/*
 *----------------------------------------------------------------------
 *
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
 *	specified string was empty and that is acceptable.
 *
 *----------------------------------------------------------------------
 */

static int
SetSticky(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* 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. */
    TkSizeT 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;
    void *internalPtr;
    const char *string;

    internalPtr = ComputeSlotAddress(recordPtr, internalOffset);

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {
	/*







|

|




|





<
|
<







2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432

2433

2434
2435
2436
2437
2438
2439
2440
 *	specified string was empty and that is acceptable.
 *
 *----------------------------------------------------------------------
 */

static int
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 {
	/*
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
		break;
	    case 'w': case 'W':
		sticky |= STICK_WEST;
		break;
	    case ' ': case ',': case '\t': case '\r': case '\n':
		break;
	    default:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad stickyness value \"%s\": must be a string"
			" containing zero or more of n, e, s, and w",
			Tcl_GetString(*value)));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "STICKY", NULL);
		return TCL_ERROR;
	    }
	}
    }

    if (internalPtr != NULL) {
	*((int *) oldInternalPtr) = *((int *) internalPtr);







|
|
<
|
|







2456
2457
2458
2459
2460
2461
2462
2463
2464

2465
2466
2467
2468
2469
2470
2471
2472
2473
		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;
	    }
	}
    }

    if (internalPtr != NULL) {
	*((int *) oldInternalPtr) = *((int *) internalPtr);
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
 *	Restores the old value.
 *
 *----------------------------------------------------------------------
 */

static void
RestoreSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr,		/* Pointer to storage for value. */
    char *oldInternalPtr)	/* Pointer to old value. */
{
    *(int *)internalPtr = *(int *)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 pane, compute the x,y coords
 *	and actual dimensions of the pane based on the pane's sticky value.
 *
 * Results:
 *	No direct return; sets the x, y, paneWidth and paneHeight to correct
 *	values.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
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 pane. */
    int *paneWidthPtr,		/* Pane width. */
    int *paneHeightPtr)	/* Pane height. */
{
    int diffx = 0;		/* Cavity width - pane width. */
    int diffy = 0;		/* Cavity hight - pane height. */

    if (cavityWidth > *paneWidthPtr) {
	diffx = cavityWidth - *paneWidthPtr;
    }

    if (cavityHeight > *paneHeightPtr) {
	diffy = cavityHeight - *paneHeightPtr;
    }

    if ((sticky & STICK_EAST) && (sticky & STICK_WEST)) {
	*paneWidthPtr += diffx;
    }
    if ((sticky & STICK_NORTH) && (sticky & STICK_SOUTH)) {
	*paneHeightPtr += diffy;
    }
    if (!(sticky & STICK_WEST)) {
	*xPtr += (sticky & STICK_EAST) ? diffx : diffx/2;
    }
    if (!(sticky & STICK_NORTH)) {
	*yPtr += (sticky & STICK_SOUTH) ? diffy : diffy/2;
    }







|
|












|
|


|
















|
|
|

|
|

|
|


|
|



|


|







2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
 *	Restores the old value.
 *
 *----------------------------------------------------------------------
 */

static void
RestoreSticky(
    ClientData clientData,
    Tk_Window tkwin,
    char *internalPtr,		/* Pointer to storage for value. */
    char *oldInternalPtr)	/* Pointer to old value. */
{
    *(int *)internalPtr = *(int *)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.
 *
 * Results:
 *	No direct return; sets the x, y, slaveWidth and slaveHeight to correct
 *	values.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
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 diffx = 0;		/* Cavity width - slave width. */
    int diffy = 0;		/* Cavity hight - slave height. */

    if (cavityWidth > *slaveWidthPtr) {
	diffx = cavityWidth - *slaveWidthPtr;
    }

    if (cavityHeight > *slaveHeightPtr) {
	diffy = cavityHeight - *slaveHeightPtr;
    }

    if ((sticky & STICK_EAST) && (sticky & STICK_WEST)) {
	*slaveWidthPtr += diffx;
    }
    if ((sticky & STICK_NORTH) && (sticky & STICK_SOUTH)) {
	*slaveHeightPtr += diffy;
    }
    if (!(sticky & STICK_WEST)) {
	*xPtr += (sticky & STICK_EAST) ? diffx : diffx/2;
    }
    if (!(sticky & STICK_NORTH)) {
	*yPtr += (sticky & STICK_SOUTH) ? diffy : diffy/2;
    }
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
static void
MoveSash(
    PanedWindow *pwPtr,
    int sash,
    int diff)
{
    int i;
    int expandPane, reduceFirst, reduceLast, reduceIncr, paneSize, sashOffset;
    Pane *panePtr;
    int stretchReserve = 0;
    int nextSash = sash + 1;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);

    if (diff == 0)
	return;

    /*
     * Update the pane sizes with their real sizes.
     */

    if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
	sashOffset = ((pwPtr->handleSize - pwPtr->sashWidth) / 2)
		+ pwPtr->sashPad;
    } else {
	sashOffset = pwPtr->sashPad;
    }
    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    panePtr->paneWidth = panePtr->width = panePtr->sashx
		    - sashOffset - panePtr->x - (2 * panePtr->padx);
	} else {
	    panePtr->paneHeight = panePtr->height = panePtr->sashy
		    - sashOffset - panePtr->y - (2 * panePtr->pady);
	}
    }

    /*
     * 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->numPanes-1 && pwPtr->panes[nextSash]->hide) {
	nextSash++;
    }

    /*
     * Consolidate +/-diff variables to reduce duplicate code.
     */

    if (diff > 0) {
	expandPane = sash;
	reduceFirst = nextSash;
	reduceLast = pwPtr->numPanes;
	reduceIncr = 1;
    } else {
	diff = abs(diff);
	expandPane = nextSash;
	reduceFirst = sash;
	reduceLast = -1;
	reduceIncr = -1;
    }

    /*
     * Calculate how much room we have to stretch in and adjust diff value
     * accordingly.
     */

    for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    stretchReserve += panePtr->width - panePtr->minSize;
	} else {
	    stretchReserve += panePtr->height - panePtr->minSize;
	}
    }
    if (stretchReserve <= 0) {
	return;
    }
    if (diff > stretchReserve) {
	diff = stretchReserve;
    }

    /*
     * Expand pane by diff amount.
     */

    panePtr = pwPtr->panes[expandPane];
    if (horizontal) {
	panePtr->paneWidth = panePtr->width += diff;
    } else {
	panePtr->paneHeight = panePtr->height += diff;
    }

    /*
     * Reduce panes, respecting minsize, until diff amount has been used.
     */

    for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    paneSize = panePtr->width;
	} else {
	    paneSize = panePtr->height;
	}
	if (diff > (paneSize - panePtr->minSize)) {
	    diff -= paneSize - panePtr->minSize;
	    paneSize = panePtr->minSize;
	} else {
	    paneSize -= diff;
	    i = reduceLast - reduceIncr;
	}
	if (horizontal) {
	    panePtr->paneWidth = panePtr->width = paneSize;
	} else {
	    panePtr->paneHeight = panePtr->height = paneSize;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ProxyWindowEventProc --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
ProxyWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    if (eventPtr->type == Expose) {
	if (pwPtr->proxywin != NULL &&!(pwPtr->flags & PROXY_REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayProxyWindow, pwPtr);
	    pwPtr->flags |= PROXY_REDRAW_PENDING;
	}
    }
}

/*
 *--------------------------------------------------------------







|
|








|








|
|
|



|
|

|
|









|










|















|
|



|

|













|

|

|







|
|



|

|

|
|
|

|



|

|
















|










|



|







2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
static void
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);

    if (diff == 0)
	return;

    /*
     * Update the slave sizes with their real sizes.
     */

    if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
	sashOffset = ((pwPtr->handleSize - pwPtr->sashWidth) / 2)
		+ pwPtr->sashPad;
    } else {
	sashOffset = pwPtr->sashPad;
    }
    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);
	} else {
	    slavePtr->paneHeight = slavePtr->height = slavePtr->sashy
		    - sashOffset - slavePtr->y - (2 * slavePtr->pady);
	}
    }

    /*
     * 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.
     */

    if (diff > 0) {
	expandPane = sash;
	reduceFirst = nextSash;
	reduceLast = pwPtr->numSlaves;
	reduceIncr = 1;
    } else {
	diff = abs(diff);
	expandPane = nextSash;
	reduceFirst = sash;
	reduceLast = -1;
	reduceIncr = -1;
    }

    /*
     * 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 {
	    stretchReserve += slavePtr->height - slavePtr->minSize;
	}
    }
    if (stretchReserve <= 0) {
	return;
    }
    if (diff > stretchReserve) {
	diff = stretchReserve;
    }

    /*
     * Expand pane by diff amount.
     */

    slavePtr = pwPtr->slaves[expandPane];
    if (horizontal) {
	slavePtr->paneWidth = slavePtr->width += diff;
    } else {
	slavePtr->paneHeight = slavePtr->height += diff;
    }

    /*
     * Reduce panes, respecting minsize, until diff amount has been used.
     */

    for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    slaveSize = slavePtr->width;
	} else {
	    slaveSize = slavePtr->height;
	}
	if (diff > (slaveSize - slavePtr->minSize)) {
	    diff -= slaveSize - slavePtr->minSize;
	    slaveSize = slavePtr->minSize;
	} else {
	    slaveSize -= diff;
	    i = reduceLast - reduceIncr;
	}
	if (horizontal) {
	    slavePtr->paneWidth = slavePtr->width = slaveSize;
	} else {
	    slavePtr->paneHeight = slavePtr->height = slaveSize;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ProxyWindowEventProc --
 *
 *	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. Whena
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ProxyWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *) clientData;

    if (eventPtr->type == Expose) {
	if (pwPtr->proxywin != NULL &&!(pwPtr->flags & PROXY_REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayProxyWindow, (ClientData) pwPtr);
	    pwPtr->flags |= PROXY_REDRAW_PENDING;
	}
    }
}

/*
 *--------------------------------------------------------------
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
 *--------------------------------------------------------------
 */

static void
DisplayProxyWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->proxywin;
    pwPtr->flags &= ~PROXY_REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }








|







2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
 *--------------------------------------------------------------
 */

static void
DisplayProxyWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *) clientData;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->proxywin;
    pwPtr->flags &= ~PROXY_REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
static int
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 *const optionStrings[] = {
	"coord", "forget", "place", NULL
    };
    enum options {
	PROXY_COORD, PROXY_FORGET, PROXY_PLACE
    };
    int index, x, y, sashWidth, sashHeight;
    int internalBW, pwWidth, pwHeight;







|







2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
static int
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", NULL
    };
    enum options {
	PROXY_COORD, PROXY_FORGET, PROXY_PLACE
    };
    int index, x, y, sashWidth, sashHeight;
    int internalBW, pwWidth, pwHeight;
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
    switch ((enum options) index) {
    case PROXY_COORD:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	coords[0] = Tcl_NewWideIntObj(pwPtr->proxyx);
	coords[1] = Tcl_NewWideIntObj(pwPtr->proxyy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case PROXY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}







|
|
|







2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
    switch ((enum options) index) {
    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;

    case PROXY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
	    return TCL_ERROR;
	}

	if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
	    return TCL_ERROR;
	}

        internalBW = Tk_InternalBorderLeft(pwPtr->tkwin);
	if (pwPtr->orient == ORIENT_HORIZONTAL) {
	    if (x < 0) {
		x = 0;
	    }
            pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
            if (x > pwWidth) {
                x = pwWidth;
            }
            y = Tk_InternalBorderLeft(pwPtr->tkwin);
	    sashWidth = pwPtr->sashWidth;
	    sashHeight = Tk_Height(pwPtr->tkwin) -
		    (2 * Tk_InternalBorderLeft(pwPtr->tkwin));
	} else {
	    if (y < 0) {
		y = 0;
	    }
            pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
            if (y > pwHeight) {
                y = pwHeight;
            }
	    x = Tk_InternalBorderLeft(pwPtr->tkwin);
	    sashHeight = pwPtr->sashWidth;
	    sashWidth = Tk_Width(pwPtr->tkwin) -
		    (2 * Tk_InternalBorderLeft(pwPtr->tkwin));
	}

	if (sashWidth < 1) {
	    sashWidth = 1;
	}
	if (sashHeight < 1) {
	    sashHeight = 1;
	}

	/*
	 * 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
	 * panes, 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 pane, 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







|








|


|








|


|


|
|
|
|
|
|










|

|







2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
	    return TCL_ERROR;
	}

	if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
	    return TCL_ERROR;
	}

        internalBW = Tk_InternalBorderWidth(pwPtr->tkwin);
	if (pwPtr->orient == ORIENT_HORIZONTAL) {
	    if (x < 0) {
		x = 0;
	    }
            pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
            if (x > pwWidth) {
                x = pwWidth;
            }
            y = Tk_InternalBorderWidth(pwPtr->tkwin);
	    sashWidth = pwPtr->sashWidth;
	    sashHeight = Tk_Height(pwPtr->tkwin) -
		    (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
	} else {
	    if (y < 0) {
		y = 0;
	    }
            pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
            if (y > pwHeight) {
                y = pwHeight;
            }
	    x = Tk_InternalBorderWidth(pwPtr->tkwin);
	    sashHeight = pwPtr->sashWidth;
	    sashWidth = Tk_Width(pwPtr->tkwin) -
		    (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
	}

        if (sashWidth < 1) {
            sashWidth = 1;
        }
        if (sashHeight < 1) {
            sashHeight = 1;
        }

	/*
	 * 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
2988
2989
2990
2991
2992
2993
2994


2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{


    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeInternalPointer --
 *
 *	Given a pointer to the start of a record and the offset of a slot
 *	within that record, compute the address of that slot.
 *
 * Results:
 *	If offset is non-negative, returns the computed address; else, returns
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void *
ComputeSlotAddress(
    void *recordPtr,	/* Pointer to the start of a record. */
    TkSizeT offset)		/* Offset of a slot within that record; may be TCL_INDEX_NONE. */
{
    if (offset != TCL_INDEX_NONE) {
	return (char *)recordPtr + offset;
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------







>
>



|
|

>
|




















|

|
|

|
|







2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
 *----------------------------------------------------------------------
 */

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);
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeInternalPointer --
 *
 *	Given a pointer to the start of a record and the offset of a slot
 *	within that record, compute the address of that slot.
 *
 * Results:
 *	If offset is non-negative, returns the computed address; else, returns
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
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;
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
3052
3053
3054
3055
3056
3057
3058

3059
3060
3061

3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076

static int
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. */
{

    int i, sashHeight, sashWidth, thisx, thisy;
    int found, isHandle, lpad, rpad, tpad, bpad;
    int first, last;


    if (pwPtr->orient == ORIENT_HORIZONTAL) {
	if (Tk_IsMapped(pwPtr->tkwin)) {
	    sashHeight = Tk_Height(pwPtr->tkwin);
	} else {
	    sashHeight = Tk_ReqHeight(pwPtr->tkwin);
	}
	sashHeight -= 2 * Tk_InternalBorderLeft(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;
	} else {







>



>







|







3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054

static int
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;
    int found, isHandle, lpad, rpad, tpad, bpad;
    int first, last;
    list = Tcl_NewObj();

    if (pwPtr->orient == ORIENT_HORIZONTAL) {
	if (Tk_IsMapped(pwPtr->tkwin)) {
	    sashHeight = Tk_Height(pwPtr->tkwin);
	} else {
	    sashHeight = Tk_ReqHeight(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;
	} else {
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141

3142

3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
	    tpad = bpad = pwPtr->sashPad;
	}
	if (Tk_IsMapped(pwPtr->tkwin)) {
	    sashWidth = Tk_Width(pwPtr->tkwin);
	} else {
	    sashWidth = Tk_ReqWidth(pwPtr->tkwin);
	}
	sashWidth -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin);
	lpad = rpad = 0;
    }

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    isHandle = 0;
    found = -1;
    for (i = 0; i < pwPtr->numPanes - 1; i++) {
	if (pwPtr->panes[i]->hide || i == last) {
	    continue;
	}
	thisx = pwPtr->panes[i]->sashx;
	thisy = pwPtr->panes[i]->sashy;

	if (((thisx - lpad) <= x && x <= (thisx + rpad + sashWidth)) &&
		((thisy - tpad) <= y && y <= (thisy + bpad + sashHeight))) {
	    found = i;

	    /*
	     * Determine if the point is over the handle or the sash.
	     */

	    if (pwPtr->showHandle) {
		thisx = pwPtr->panes[i]->handlex;
		thisy = pwPtr->panes[i]->handley;
		if (pwPtr->orient == ORIENT_HORIZONTAL) {
		    if (thisy <= y && y <= (thisy + pwPtr->handleSize)) {
			isHandle = 1;
		    }
		} else {
		    if (thisx <= x && x <= (thisx + pwPtr->handleSize)) {
			isHandle = 1;
		    }
		}
	    }
	    break;
	}
    }

    /*
     * Set results. Note that the empty string is the default (this function
     * is called inside the implementation of a command).
     */

    if (found != -1) {

	Tcl_Obj *list[2];


	list[0] = Tcl_NewWideIntObj(found);
	list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), -1);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, list));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|






|
|


|
|










|
|















|
<



>
|
>
|
|
<
|
<










3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115

3116
3117
3118
3119
3120
3121
3122
3123

3124

3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
	    tpad = bpad = pwPtr->sashPad;
	}
	if (Tk_IsMapped(pwPtr->tkwin)) {
	    sashWidth = Tk_Width(pwPtr->tkwin);
	} else {
	    sashWidth = Tk_ReqWidth(pwPtr->tkwin);
	}
	sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
	lpad = rpad = 0;
    }

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    isHandle = 0;
    found = -1;
    for (i = 0; i < pwPtr->numSlaves - 1; i++) {
	if (pwPtr->slaves[i]->hide || i == last) {
	    continue;
	}
	thisx = pwPtr->slaves[i]->sashx;
	thisy = pwPtr->slaves[i]->sashy;

	if (((thisx - lpad) <= x && x <= (thisx + rpad + sashWidth)) &&
		((thisy - tpad) <= y && y <= (thisy + bpad + sashHeight))) {
	    found = i;

	    /*
	     * Determine if the point is over the handle or the sash.
	     */

	    if (pwPtr->showHandle) {
		thisx = pwPtr->slaves[i]->handlex;
		thisy = pwPtr->slaves[i]->handley;
		if (pwPtr->orient == ORIENT_HORIZONTAL) {
		    if (thisy <= y && y <= (thisy + pwPtr->handleSize)) {
			isHandle = 1;
		    }
		} else {
		    if (thisx <= x && x <= (thisx + pwPtr->handleSize)) {
			isHandle = 1;
		    }
		}
	    }
	    break;
	}
    }

    /*
     * Set results.

     */

    if (found != -1) {
	Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(found));
	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:
 */

Deleted generic/tkPkgConfig.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * tkPkgConfig.c --
 *
 *	This file contains the configuration information to embed into the tcl
 *	binary library.
 *
 * Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
 * Copyright (c) 2017 Stuart Cassoff <stwo@users.sourceforge.net>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/* Note, the definitions in this module are influenced by the following C
 * preprocessor macros:
 *
 * OSCMa  = shortcut for "old style configuration macro activates"
 * NSCMdt = shortcut for "new style configuration macro declares that"
 *
 * - TCL_THREADS		OSCMa compilation as threaded.
 * - TCL_MEM_DEBUG		OSCMa memory debugging.
 *
 * - TCL_CFG_DO64BIT		NSCMdt tk is compiled for a 64bit system.
 * - NDEBUG			NSCMdt tk is compiled with symbol info off.
 * - TCL_CFG_OPTIMIZED		NSCMdt tk is compiled with cc optimizations on
 * - TCL_CFG_PROFILED		NSCMdt tk is compiled with profiling info.
 *
 * - _WIN32 || __CYGWIN__	The value for the fontsytem key will be
 *   MAC_OSX_TK			chosen based on these macros/defines.
 *   HAVE_XFT			NSCMdt xft font support was requested.
 *
 * - CFG_RUNTIME_*		Paths to various stuff at runtime.
 * - CFG_INSTALL_*		Paths to various stuff at installation time.
 *
 * - TCL_CFGVAL_ENCODING	string containing the encoding used for the
 *				configuration values.
 */

#include "tkInt.h"


#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "utf-8"
#endif

/*
 * Use C preprocessor statements to define the various values for the embedded
 * configuration information.
 */

#ifdef TCL_THREADS
#  define  CFG_THREADED		"1"
#else
#  define  CFG_THREADED		"0"
#endif

#ifdef TCL_MEM_DEBUG
#  define CFG_MEMDEBUG		"1"
#else
#  define CFG_MEMDEBUG		"0"
#endif

#ifdef TCL_CFG_DO64BIT
#  define CFG_64		"1"
#else
#  define CFG_64		"0"
#endif

#ifndef NDEBUG
#  define CFG_DEBUG		"1"
#else
#  define CFG_DEBUG		"0"
#endif

#ifdef TCL_CFG_OPTIMIZED
#  define CFG_OPTIMIZED		"1"
#else
#  define CFG_OPTIMIZED		"0"
#endif

#ifdef TCL_CFG_PROFILED
#  define CFG_PROFILED		"1"
#else
#  define CFG_PROFILED		"0"
#endif

#if defined(_WIN32)
#  define CFG_FONTSYSTEM	"gdi"
#elif defined(MAC_OSX_TK)
#  define CFG_FONTSYSTEM	"cocoa"
#elif defined(HAVE_XFT)
#  define CFG_FONTSYSTEM	"xft"
#else
#  define CFG_FONTSYSTEM	"x11"
#endif

static const Tcl_Config cfg[] = {
    {"debug",			CFG_DEBUG},
    {"threaded",		CFG_THREADED},
    {"profiled",		CFG_PROFILED},
    {"64bit",			CFG_64},
    {"optimized",		CFG_OPTIMIZED},
#ifdef TK_NO_DEPRECATED
    {"nodeprecated",	"1"},
#endif
    {"mem_debug",		CFG_MEMDEBUG},
    {"fontsystem",		CFG_FONTSYSTEM},

    /* Runtime paths to various stuff */

#ifdef CFG_RUNTIME_LIBDIR
    {"libdir,runtime",		CFG_RUNTIME_LIBDIR},
#endif
#ifdef CFG_RUNTIME_BINDIR
    {"bindir,runtime",		CFG_RUNTIME_BINDIR},
#endif
#ifdef CFG_RUNTIME_SCRDIR
    {"scriptdir,runtime",	CFG_RUNTIME_SCRDIR},
#endif
#ifdef CFG_RUNTIME_INCDIR
    {"includedir,runtime",	CFG_RUNTIME_INCDIR},
#endif
#ifdef CFG_RUNTIME_DOCDIR
    {"docdir,runtime",		CFG_RUNTIME_DOCDIR},
#endif
#ifdef CFG_RUNTIME_DEMODIR
    {"demodir,runtime",		CFG_RUNTIME_DEMODIR},
#endif

    /* Installation paths to various stuff */

#ifdef CFG_INSTALL_LIBDIR
    {"libdir,install",		CFG_INSTALL_LIBDIR},
#endif
#ifdef CFG_INSTALL_BINDIR
    {"bindir,install",		CFG_INSTALL_BINDIR},
#endif
#ifdef CFG_INSTALL_SCRDIR
    {"scriptdir,install",	CFG_INSTALL_SCRDIR},
#endif
#ifdef CFG_INSTALL_INCDIR
    {"includedir,install",	CFG_INSTALL_INCDIR},
#endif
#ifdef CFG_INSTALL_DOCDIR
    {"docdir,install",		CFG_INSTALL_DOCDIR},
#endif
#ifdef CFG_INSTALL_DEMODIR
    {"demodir,install",		CFG_INSTALL_DEMODIR},
#endif

    /* Last entry, closes the array */
    {NULL, NULL}
};

void
TkInitEmbeddedConfigurationInformation(
    Tcl_Interp *interp)		/* Interpreter the configuration command is
				 * registered in. */
{
    Tcl_RegisterConfig(interp, "tk", cfg, TCL_CFGVAL_ENCODING);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































Changes to generic/tkPlace.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710

711
712

713
714
715
716
717
718
719
720
721
722
723
724

725
726
727


728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

#include "tkInt.h"

/*
 * Border modes for relative placement:
 *
 * BM_INSIDE:		relative distances computed using area inside all
 *			borders of container window.
 * BM_OUTSIDE:		relative distances computed using outside area that
 *			includes all borders of container.
 * BM_IGNORE:		border issues are ignored: place relative to container's
 *			actual window size.
 */

static const char *const borderModeStrings[] = {
    "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:
 */

typedef struct Content {
    Tk_Window tkwin;		/* Tk's token for window. */
    Tk_Window inTkwin;		/* Token for the -in window. */
    struct Container *containerPtr;	/* Pointer to information for window relative
				 * to which tkwin is placed. This isn't
				 * necessarily the logical parent of tkwin.
				 * NULL means the container was deleted or never
				 * assigned. */
    struct Content *nextPtr;	/* Next in list of windows placed relative to
				 * same container (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.
     */

    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. */
    double relX, relY;		/* X and Y coordinates relative to size of
				 * container. */
    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. */
    double relWidth, relHeight;	/* Dimensions for tkwin relative to size of
				 * container. */
    Tcl_Obj *relWidthPtr;
    Tcl_Obj *relHeightPtr;
    Tk_Anchor anchor;		/* Which point on tkwin is placed at the given
				 * position. */
    BorderMode borderMode;	/* How to treat borders of container window. */
    int flags;			/* Various flags; see below for bit
				 * definitions. */
} Content;

/*
 * Type masks for options:
 */

#define IN_MASK		1

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", TCL_INDEX_NONE,
	 offsetof(Content, anchor), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", TCL_INDEX_NONE,
	 offsetof(Content, borderMode), 0, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", offsetof(Content, heightPtr),
	 offsetof(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", TCL_INDEX_NONE, offsetof(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 offsetof(Content, relHeightPtr), offsetof(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 offsetof(Content, relWidthPtr), offsetof(Content, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", offsetof(Content, widthPtr),
	 offsetof(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", offsetof(Content, xPtr),
	 offsetof(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", offsetof(Content, yPtr),
	 offsetof(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * Flag definitions for Content structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
 * CHILD_HEIGHT -		1 means -height was specified;
 * CHILD_REL_HEIGHT -		1 means -relheight was specified.
 */

#define CHILD_WIDTH		1
#define CHILD_REL_WIDTH		2
#define CHILD_HEIGHT		4
#define CHILD_REL_HEIGHT	8

/*
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */
    struct Content *contentPtr;	/* First in linked list of content windowslaced
				 * relative to this container. */
    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
				 * abort that nested call.  This happens, for
				 * example, if tkwin or any of its content
				 * is deleted. */
    int flags;			/* See below for bit definitions. */
} Container;

/*
 * Flag definitions for containers:
 *
 * 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:
 */

static void		PlaceRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PlaceLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr placerType = {
    "place",			/* name */
    PlaceRequestProc,		/* requestProc */
    PlaceLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ContentStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ConfigureContent(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 Content *		CreateContent(Tk_Window tkwin, Tk_OptionTable table);
static void		FreeContent(Content *contentPtr);
static Content *		FindContent(Tk_Window tkwin);
static Container *		CreateContainer(Tk_Window tkwin);
static Container *		FindContainer(Tk_Window tkwin);
static void		PlaceStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		RecomputePlacement(ClientData clientData);
static void		UnlinkContent(Content *contentPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_PlaceObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_PlaceObjCmd(
    ClientData clientData,	/* Interpreter main window. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window main_win = (Tk_Window)clientData;
    Tk_Window tkwin;
    Content *contentPtr;

    TkDisplay *dispPtr;
    Tk_OptionTable optionTable;
    static const char *const optionStrings[] = {
	"configure", "content", "forget", "info", "slaves", NULL
    };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", NULL
    };
    enum options { PLACE_CONFIGURE, PLACE_CONTENT, 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.
     */

     optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    /*
     * Handle special shortcut where window name is first argument.
     */

    if (Tcl_GetString(objv[1])[0] == '.') {

	if (TkGetWindowFromObj(interp, main_win, objv[1],
		&tkwin) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * Initialize, if that hasn't been done yet.
	 */

	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (!dispPtr->placeInit) {
	    Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureContent(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*
     * Handle more general case of option followed by window name followed by
     * possible additional arguments.
     */


    if (TkGetWindowFromObj(interp, main_win, objv[2],
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Initialize, if that hasn't been done yet.
     */

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "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
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case PLACE_CONFIGURE:
	if (objc == 3 || objc == 4) {
	    Tcl_Obj *objPtr;

	    contentPtr = FindContent(tkwin);
	    if (contentPtr == NULL) {
		return TCL_OK;
	    }
	    objPtr = Tk_GetOptionInfo(interp, contentPtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	return ConfigureContent(interp, tkwin, optionTable, objc-3, objv+3);

    case PLACE_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	contentPtr = FindContent(tkwin);
	if (contentPtr == NULL) {
	    return TCL_OK;
	}
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkContent(contentPtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		tkwin));
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
		contentPtr);
	Tk_ManageGeometry(tkwin, NULL, NULL);
	Tk_UnmapWindow(tkwin);
	FreeContent(contentPtr);
	break;

    case PLACE_INFO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	return PlaceInfoCommand(interp, tkwin);

    case PLACE_SLAVES:
    case PLACE_CONTENT: {
	Container *containerPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	containerPtr = FindContainer(tkwin);
	if (containerPtr != NULL) {
	    Tcl_Obj *listPtr = Tcl_NewObj();

	    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		    contentPtr = contentPtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tk_NewWindowObj(contentPtr->tkwin));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateContent --
 *
 *	Given a Tk_Window token, find the Content structure corresponding to
 *	that token, creating a new one if necessary.
 *
 * Results:
 *	Pointer to the Content structure.
 *
 * Side effects:
 *	A new Content structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Content *
CreateContent(
    Tk_Window tkwin,		/* Token for desired content. */
    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    Content *contentPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->contentTable, (char *) tkwin, &isNew);
    if (!isNew) {
	return (Content *)Tcl_GetHashValue(hPtr);
    }

    /*
     * No preexisting content structure for that window, so make a new one and
     * populate it with some default values.
     */

    contentPtr = (Content *)ckalloc(sizeof(Content));
    memset(contentPtr, 0, sizeof(Content));
    contentPtr->tkwin = tkwin;
    contentPtr->inTkwin = NULL;
    contentPtr->anchor = TK_ANCHOR_NW;
    contentPtr->borderMode = BM_INSIDE;
    contentPtr->optionTable = table;
    Tcl_SetHashValue(hPtr, contentPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    return contentPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeContent --
 *
 *	Frees the resources held by a Content structure.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Memory are freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{
    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * FindContent --
 *
 *	Given a Tk_Window token, find the Content 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 Content structure; NULL if none exists.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Content *
FindContent(
    Tk_Window tkwin)		/* Token for desired content. */
{
    Tcl_HashEntry *hPtr;

    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->contentTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Content *)Tcl_GetHashValue(hPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * UnlinkContent --
 *
 *	This function removes a content window from the chain of content windows in its
 *	container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The content list of contentPtr's container changes.
 *
 *----------------------------------------------------------------------
 */

static void
UnlinkContent(
    Content *contentPtr)		/* Content structure to be unlinked. */
{
    Container *containerPtr;
    Content *prevPtr;

    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = containerPtr->contentPtr; ; prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("UnlinkContent couldn't find content to unlink");
	    }
	    if (prevPtr->nextPtr == contentPtr) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }

    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    contentPtr->containerPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateContainer --
 *
 *	Given a Tk_Window token, find the Container structure corresponding to
 *	that token, creating a new one if necessary.
 *
 * Results:
 *	Pointer to the Container structure.
 *
 * Side effects:
 *	A new Container structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Container *
CreateContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    Container *containerPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->containerTable, (char *)tkwin, &isNew);
    if (isNew) {
	containerPtr = (Container *)ckalloc(sizeof(Container));
	containerPtr->tkwin = tkwin;
	containerPtr->contentPtr = NULL;
	containerPtr->abortPtr = NULL;
	containerPtr->flags = 0;
	Tcl_SetHashValue(hPtr, containerPtr);
	Tk_CreateEventHandler(containerPtr->tkwin, StructureNotifyMask,
		PlaceStructureProc, containerPtr);
    } else {
	containerPtr = (Container *)Tcl_GetHashValue(hPtr);
    }
    return containerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FindContainer --
 *
 *	Given a Tk_Window token, find the Container 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 Container structure; NULL if one does not exist for the
 *	given Tk_Window token.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Container *
FindContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;

    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->containerTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Container *)Tcl_GetHashValue(hPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureContent --
 *
 *	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.
 *
 * Side effects:
 *	Information in contentPtr may change, and contentPtr's container is scheduled
 *	for reconfiguration.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureContent(
    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. */
{
    Container *containerPtr;
    Tk_SavedOptions savedOptions;
    int mask;
    Content *contentPtr;
    Tk_Window containerWin = NULL;
    TkWindow *container;

    if (Tk_TopWinHierarchy(tkwin)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use placer on top-level window \"%s\"; use "
		"wm command instead", Tk_PathName(tkwin)));
	Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set content flags. First clear the field, then add bits as needed.
     */

    contentPtr->flags = 0;
    if (contentPtr->heightPtr) {
	contentPtr->flags |= CHILD_HEIGHT;

    }

    if (contentPtr->relHeightPtr) {
	contentPtr->flags |= CHILD_REL_HEIGHT;
    }

    if (contentPtr->relWidthPtr) {
	contentPtr->flags |= CHILD_REL_WIDTH;
    }

    if (contentPtr->widthPtr) {
	contentPtr->flags |= CHILD_WIDTH;
    }

    if (!(mask & IN_MASK) && (contentPtr->containerPtr != NULL)) {
	/*
	 * If no -in option was passed and the content is already placed then
	 * just recompute the placement.
	 */

	containerPtr = contentPtr->containerPtr;
	goto scheduleLayout;
    } else if (mask & IN_MASK) {
	/* -in changed */
	Tk_Window win;
	Tk_Window ancestor;

	win = contentPtr->inTkwin;

	/*
	 * Make sure that the new container is either the logical parent of the
	 * content window or a descendant of that window, and that the container and content
	 * aren't the same.
	 */

	for (ancestor = win; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(contentPtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't place \"%s\" relative to \"%s\"",
			Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		goto error;
	    }
	}
	if (contentPtr->tkwin == win) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't place \"%s\" relative to itself",
		    Tk_PathName(contentPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
	    goto error;
	}


	/*
	 * Check for management loops.

	 */

	for (container = (TkWindow *)win; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)contentPtr->tkwin) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		goto error;
	    }
	}

	if (win != Tk_Parent(contentPtr->tkwin)) {
	    ((TkWindow *)contentPtr->tkwin)->maintainerPtr = (TkWindow *)win;
	}



	if ((contentPtr->containerPtr != NULL)
		&& (contentPtr->containerPtr->tkwin == win)) {
	    /*
	     * Re-using same old container. Nothing to do.
	     */

	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkContent(contentPtr);
	containerWin = win;
    }

    /*
     * If there's no container specified for this content, use its Tk_Parent.
     */

    if (containerWin == NULL) {
	containerWin = Tk_Parent(contentPtr->tkwin);
	contentPtr->inTkwin = containerWin;
    }

    /*
     * Manage the content window in this container.
     */

    containerPtr = CreateContainer(containerWin);
    contentPtr->containerPtr = containerPtr;
    contentPtr->nextPtr = containerPtr->contentPtr;
    containerPtr->contentPtr = contentPtr;
    Tk_ManageGeometry(contentPtr->tkwin, &placerType, contentPtr);

    /*
     * Arrange for the container to be re-arranged at the first idle moment.
     */

  scheduleLayout:
    Tk_FreeSavedOptions(&savedOptions);

    if (!(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	containerPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
    }
    return TCL_OK;

    /*
     * Error while processing some option, cleanup and return.
     */








|

|
|



|










|


|


|

|
|












|






|




|


|








|
|
|
|
|
|
|


|


|

|
|
|
|
|
|
|
|
|
|
|



|













|



|
|
|
|




|


|


|













|





|






|

|

|

|
|
|
|
|
|


|




















|


|

<

|
>


|
|

<
<
<
|


















|
>
|
|









|
|



|







>
|
|









|
|



|
|
<
<
<
<
<
<
<
<








|
|


|







|






|
|


|
|
|

|
|
|
|
|
|

|









|
<
|





|
|


|
|
|
|













|

|



|


|




|
|
|



|



|

|



|



|
|
|
|
|
|
|
|
|
|
|





|

|











|
|

|
|
|





|

|




|







|
|
|


>


|



|
>





|

|
|





|





|
|

|
|

|
|


|
|

|

|

|
|




|
|
|

|





|

|



|


|




|
|
|


|



|

|
|
|
|
|
|
|
|

|

|





|

|




|








|
|
|


>


|



|
>





|









|






|




|

|


|
|
<


<
|
|
<



|

|
|




|


|
|
|
>
|
<
|
|


|
|


|
|


|

|



|



|


|


|
|



|
|



|
|
|
<



|
|
|
<
|


|
>
|
<
>
|

<
<
|
<
<
<
<
|
|
<
>
|
|

>
>
|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<

|


|
|
|



|


|
|
|
|
|


|





|
|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282








283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625

626
627

628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689

690
691
692
693
694
695

696
697
698
699
700
701

702
703
704


705




706
707

708
709
710
711
712
713
714





715











716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

#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.
 */

static CONST char *borderModeStrings[] = {
    "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:
 */

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). */
    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.
     */

    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. */
    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. */
    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. */
    BorderMode borderMode;	/* How to treat borders of master window. */
    int flags;			/* Various flags; see below for bit
				 * definitions. */
} Slave;

/*
 * Type masks for options:
 */

#define IN_MASK		1

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,
	 Tk_Offset(Slave, borderMode), 0, (ClientData) borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Slave, heightPtr),
	 Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Slave, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 Tk_Offset(Slave, relHeightPtr), Tk_Offset(Slave, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 Tk_Offset(Slave, relWidthPtr), Tk_Offset(Slave, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", -1,
	 Tk_Offset(Slave, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", -1,
	 Tk_Offset(Slave, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", Tk_Offset(Slave, widthPtr),
	 Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", Tk_Offset(Slave, xPtr),
	 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, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * Flag definitions for Slave structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
 * CHILD_HEIGHT -		1 means -height was specified;
 * CHILD_REL_HEIGHT -		1 means -relheight was specified.
 */

#define CHILD_WIDTH		1
#define CHILD_REL_WIDTH		2
#define CHILD_HEIGHT		4
#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:
 */

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. */
    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
				 * abort that nested call.  This happens, for
				 * example, if tkwin or any of its slaves
				 * is deleted. */
    int flags;			/* See below for bit definitions. */
} Master;

/*
 * Flag definitions for masters:
 *
 * 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:
 */

static void		PlaceRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PlaceLostSlaveProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr placerType = {
    "place",			/* name */
    PlaceRequestProc,		/* requestProc */
    PlaceLostSlaveProc,		/* lostSlaveProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

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 function is invoked to process the "place" Tcl commands. See the
 *	user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    char *string;
    TkDisplay *dispPtr;
    Tk_OptionTable optionTable;
    static CONST char *optionStrings[] = {
	"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.
     */

     optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    /*
     * Handle special shortcut where window name is first argument.
     */

    string = Tcl_GetString(objv[1]);
    if (string[0] == '.') {
	tkwin = Tk_NameToWindow(interp, string,	Tk_MainWindow(interp));
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}

	/*
	 * Initialize, if that hasn't been done yet.
	 */

	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (!dispPtr->placeInit) {
	    Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureSlave(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*
     * Handle more general case of option followed by window name followed by
     * possible additional arguments.
     */

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
	    Tk_MainWindow(interp));
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    /*
     * Initialize, if that hasn't been done yet.
     */

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {








	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case PLACE_CONFIGURE:
	if (objc == 3 || objc == 4) {
	    Tcl_Obj *objPtr;

	    slavePtr = FindSlave(tkwin);
	    if (slavePtr == NULL) {
		return TCL_OK;
	    }
	    objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	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, 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));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateSlave --
 *
 *	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.
 *
 * Side effects:
 *	A new Slave structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Slave *
CreateSlave(
    Tk_Window tkwin,		/* Token for desired slave. */
    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    register Slave *slavePtr;
    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 = NULL;
    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;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeSlave --
 *
 *	Frees the resources held by a Slave structure.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Memory are freed.
 *
 *----------------------------------------------------------------------
 */

static void
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.
 *
 * Results:
 *	Pointer to Slave structure; NULL if none exists.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Slave *
FindSlave(
    Tk_Window tkwin)		/* Token for desired slave. */
{
    Tcl_HashEntry *hPtr;
    register Slave *slavePtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
    return slavePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UnlinkSlave --
 *
 *	This function removes a slave window from the chain of slaves in its
 *	master.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slave list of slavePtr's master changes.
 *
 *----------------------------------------------------------------------
 */

static void
UnlinkSlave(
    Slave *slavePtr)		/* Slave structure to be unlinked. */
{
    register Master *masterPtr;
    register Slave *prevPtr;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
	return;
    }
    if (masterPtr->slavePtr == slavePtr) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    } else {
	for (prevPtr = masterPtr->slavePtr; ; prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("UnlinkSlave couldn't find slave to unlink");
	    }
	    if (prevPtr->nextPtr == slavePtr) {
		prevPtr->nextPtr = slavePtr->nextPtr;
		break;
	    }
	}
    }
    
    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    }
    slavePtr->masterPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateMaster --
 *
 *	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.
 *
 * Side effects:
 *	A new Master structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Master *
CreateMaster(
    Tk_Window tkwin)		/* Token for desired master. */
{
    Tcl_HashEntry *hPtr;
    register Master *masterPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    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;
	Tcl_SetHashValue(hPtr, masterPtr);
	Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,
		MasterStructureProc, (ClientData) masterPtr);
    } else {
	masterPtr = (Master *) Tcl_GetHashValue(hPtr);
    }
    return masterPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FindMaster --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Master *
FindMaster(
    Tk_Window tkwin)		/* Token for desired master. */
{
    Tcl_HashEntry *hPtr;
    register Master *masterPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    masterPtr = (Master *) Tcl_GetHashValue(hPtr);
    return masterPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlave --
 *
 *	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.
 *
 * Side effects:
 *	Information in slavePtr may change, and slavePtr's master is scheduled
 *	for reconfiguration.
 *
 *----------------------------------------------------------------------
 */

static int
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;
    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", NULL);

	return TCL_ERROR;
    }

    slavePtr = CreateSlave(tkwin, table);

    if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv,
	    slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	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) == 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.
	 */

	for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(slavePtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_AppendResult(interp, "can't place ",
			Tk_PathName(slavePtr->tkwin), " relative to ",
			Tk_PathName(tkwin), NULL);

		goto error;
	    }
	}
	if (slavePtr->tkwin == tkwin) {
	    Tcl_AppendResult(interp, "can't place ",
		    Tk_PathName(slavePtr->tkwin), " relative to itself",

		    NULL);
	    goto error;
	}
	if ((slavePtr->masterPtr != NULL)
		&& (slavePtr->masterPtr->tkwin == tkwin)) {
	    /*

	     * Re-using same old master. Nothing to do.
	     */



	    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;
    }

















    /*
     * If there's no master specified for this slave, use its Tk_Parent.
     */

    if (masterWin == NULL) {
	masterWin = Tk_Parent(slavePtr->tkwin);
	slavePtr->inTkwin = masterWin;
    }

    /*
     * Manage the slave window in this master.
     */

    masterPtr = CreateMaster(masterWin);
    slavePtr->masterPtr = masterPtr;
    slavePtr->nextPtr = masterPtr->slavePtr;
    masterPtr->slavePtr = slavePtr;
    Tk_ManageGeometry(slavePtr->tkwin, &placerType, (ClientData) slavePtr);

    /*
     * Arrange for the master to be re-arranged at the first idle moment.
     */

  scheduleLayout:
    Tk_FreeSavedOptions(&savedOptions);

    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	masterPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
    }
    return TCL_OK;

    /*
     * Error while processing some option, cleanup and return.
     */

803
804
805
806
807
808
809

810
811
812
813
814
815
816
817
818
819
820
821
822
823

824
825



826

827
828

829
830
831
832

833
834
835
836
837
838
839

840
841
842
843
844
845

846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
 */

static int
PlaceInfoCommand(
    Tcl_Interp *interp,		/* Interp into which to place result. */
    Tk_Window tkwin)		/* Token for the window to get info on. */
{

    Content *contentPtr;
    Tcl_Obj *infoObj;

    contentPtr = FindContent(tkwin);
    if (contentPtr == NULL) {
	return TCL_OK;
    }
    infoObj = Tcl_NewObj();
    if (contentPtr->containerPtr != NULL) {
	Tcl_AppendToObj(infoObj, "-in", -1);
	Tcl_ListObjAppendElement(NULL, infoObj,
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_AppendToObj(infoObj, " ", -1);
    }

    Tcl_AppendPrintfToObj(infoObj,
	    "-x %d -relx %.4g -y %d -rely %.4g",



	    contentPtr->x, contentPtr->relX, contentPtr->y, contentPtr->relY);

    if (contentPtr->flags & CHILD_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", contentPtr->width);

    } else {
	Tcl_AppendToObj(infoObj, " -width {}", -1);
    }
    if (contentPtr->flags & CHILD_REL_WIDTH) {

	Tcl_AppendPrintfToObj(infoObj,
		" -relwidth %.4g", contentPtr->relWidth);
    } else {
	Tcl_AppendToObj(infoObj, " -relwidth {}", -1);
    }
    if (contentPtr->flags & CHILD_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj, " -height %d", contentPtr->height);

    } else {
	Tcl_AppendToObj(infoObj, " -height {}", -1);
    }
    if (contentPtr->flags & CHILD_REL_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relheight %.4g", contentPtr->relHeight);

    } else {
	Tcl_AppendToObj(infoObj, " -relheight {}", -1);
    }

    Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s",
	    Tk_NameOfAnchor(contentPtr->anchor),
	    borderModeStrings[contentPtr->borderMode]);
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * RecomputePlacement --
 *
 *	This function is called as a when-idle handler. It recomputes the
 *	geometries of all the content of a given container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Windows may change size or shape.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputePlacement(
    ClientData clientData)	/* Pointer to Container record. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr;
    int x, y, width, height, tmp;
    int containerWidth, containerHeight, containerX, containerY;
    double x1, y1, x2, y2;

    int abort;			/* May get set to non-zero to abort this
				 * placement operation. */

    containerPtr->flags &= ~PARENT_RECONFIG_PENDING;

    /*
     * Abort any nested call to RecomputePlacement for this window, since
     * we'll do everything necessary here, and set up so this call can be
     * aborted if necessary.
     */

    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(containerPtr);

    /*
     * Iterate over all the content windows for the container. Each content's geometry can
     * be computed independently of the other content. 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 (contentPtr = containerPtr->contentPtr; contentPtr != NULL && !abort;
	    contentPtr = contentPtr->nextPtr) {
	/*
	 * Step 1: compute size and borderwidth of container, taking into account
	 * desired border mode.
	 */

	containerX = containerY = 0;
	containerWidth = Tk_Width(containerPtr->tkwin);
	containerHeight = Tk_Height(containerPtr->tkwin);
	if (contentPtr->borderMode == BM_INSIDE) {
	    containerX = Tk_InternalBorderLeft(containerPtr->tkwin);
	    containerY = Tk_InternalBorderTop(containerPtr->tkwin);
	    containerWidth -= containerX + Tk_InternalBorderRight(containerPtr->tkwin);
	    containerHeight -= containerY +
		    Tk_InternalBorderBottom(containerPtr->tkwin);
	} else if (contentPtr->borderMode == BM_OUTSIDE) {
	    containerX = containerY = -Tk_Changes(containerPtr->tkwin)->border_width;
	    containerWidth -= 2 * containerX;
	    containerHeight -= 2 * containerY;
	}

	/*
	 * Step 2: compute size of content (outside dimensions including border)
	 * and location of anchor point within container.
	 */

	x1 = contentPtr->x + containerX + (contentPtr->relX*containerWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = contentPtr->y + containerY + (contentPtr->relY*containerHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if (contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	    width = 0;
	    if (contentPtr->flags & CHILD_WIDTH) {
		width += contentPtr->width;
	    }
	    if (contentPtr->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.
		 */

		x2 = x1 + (contentPtr->relWidth*containerWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}
	if (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	    height = 0;
	    if (contentPtr->flags & CHILD_HEIGHT) {
		height += contentPtr->height;
	    }
	    if (contentPtr->flags & CHILD_REL_HEIGHT) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (contentPtr->relHeight*containerHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;
	    }
	} else {
	    height = Tk_ReqHeight(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}

	/*
	 * Step 3: adjust the x and y positions so that the desired anchor
	 * point on the content appears at that position. Also adjust for the
	 * border mode and container's border.
	 */

	switch (contentPtr->anchor) {
	case TK_ANCHOR_N:
	    x -= width/2;
	    break;
	case TK_ANCHOR_NE:
	    x -= width;
	    break;
	case TK_ANCHOR_E:







>
|
<

|
|


<
|
<
|
<
|

>
|
|
>
>
>
|
>
|
|
>

|

|
>
|
<

|

|
|
>

|

|
<
|
>

|


|
|
|
|









|












|

|
|

|

>



|
|


|
|


|
|

|

|


|
|

|


|
|

|



|
|
|
|
|
|
|
|
|
|
|
|
|



|
|


|

|

|

|
|

|








|




|
|

|

|
|

|




|




|
|




|
|


|







773
774
775
776
777
778
779
780
781

782
783
784
785
786

787

788

789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
 */

static int
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;
    }

    if (slavePtr->masterPtr != NULL) {

	Tcl_AppendElement(interp, "-in");

	Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin));
    }
    sprintf(buffer, " -x %d", slavePtr->x);
    Tcl_AppendResult(interp, buffer, NULL);
    sprintf(buffer, " -relx %.4g", slavePtr->relX);
    Tcl_AppendResult(interp, buffer, NULL);
    sprintf(buffer, " -y %d", slavePtr->y);
    Tcl_AppendResult(interp, buffer, NULL);
    sprintf(buffer, " -rely %.4g", slavePtr->relY);
    Tcl_AppendResult(interp, buffer, NULL);
    if (slavePtr->flags & CHILD_WIDTH) {
	sprintf(buffer, " -width %d", slavePtr->width);
	Tcl_AppendResult(interp, buffer, NULL);
    } else {
	Tcl_AppendResult(interp, " -width {}", NULL);
    }
    if (slavePtr->flags & CHILD_REL_WIDTH) {
	sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth);
	Tcl_AppendResult(interp, buffer, NULL);

    } else {
	Tcl_AppendResult(interp, " -relwidth {}", NULL);
    }
    if (slavePtr->flags & CHILD_HEIGHT) {
	sprintf(buffer, " -height %d", slavePtr->height);
	Tcl_AppendResult(interp, buffer, NULL);
    } else {
	Tcl_AppendResult(interp, " -height {}", NULL);
    }
    if (slavePtr->flags & CHILD_REL_HEIGHT) {

	sprintf(buffer, " -relheight %.4g", slavePtr->relHeight);
	Tcl_AppendResult(interp, buffer, NULL);
    } else {
	Tcl_AppendResult(interp, " -relheight {}", NULL);
    }

    Tcl_AppendElement(interp, "-anchor");
    Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor));
    Tcl_AppendElement(interp, "-bordermode");
    Tcl_AppendElement(interp, borderModeStrings[slavePtr->borderMode]);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * RecomputePlacement --
 *
 *	This function is called as a when-idle handler. It recomputes the
 *	geometries of all the slaves of a given master.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Windows may change size or shape.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputePlacement(
    ClientData clientData)	/* Pointer to Master record. */
{
    register Master *masterPtr = (Master *) clientData;
    register Slave *slavePtr;
    int x, y, width, height, tmp;
    int masterWidth, masterHeight, masterX, masterY;
    double x1, y1, x2, y2;

    int abort;			/* May get set to non-zero to abort this
				 * placement operation. */

    masterPtr->flags &= ~PARENT_RECONFIG_PENDING;
    
    /*
     * Abort any nested call to RecomputePlacement 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) {
	*masterPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    abort = 0;
    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.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
	    slavePtr = slavePtr->nextPtr) {
	/*
	 * Step 1: compute size and borderwidth of master, taking into account
	 * desired border mode.
	 */

	masterX = masterY = 0;
	masterWidth = Tk_Width(masterPtr->tkwin);
	masterHeight = Tk_Height(masterPtr->tkwin);
	if (slavePtr->borderMode == BM_INSIDE) {
	    masterX = Tk_InternalBorderLeft(masterPtr->tkwin);
	    masterY = Tk_InternalBorderTop(masterPtr->tkwin);
	    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;
	}

	/*
	 * Step 2: compute size of slave (outside dimensions including border)
	 * and location of anchor point within master.
	 */

	x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = slavePtr->y + masterY + (slavePtr->relY*masterHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	    width = 0;
	    if (slavePtr->flags & CHILD_WIDTH) {
		width += slavePtr->width;
	    }
	    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.
		 */

		x2 = x1 + (slavePtr->relWidth*masterWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	}
	if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	    height = 0;
	    if (slavePtr->flags & CHILD_HEIGHT) {
		height += slavePtr->height;
	    }
	    if (slavePtr->flags & CHILD_REL_HEIGHT) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (slavePtr->relHeight*masterHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;
	    }
	} else {
	    height = Tk_ReqHeight(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	}

	/*
	 * 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:
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208

1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

	/*
	 * Step 4: adjust width and height again to reflect inside dimensions
	 * of window rather than outside. Also make sure that the width and
	 * height aren't zero.
	 */

	width -= 2*Tk_Changes(contentPtr->tkwin)->border_width;
	height -= 2*Tk_Changes(contentPtr->tkwin)->border_width;
	if (width <= 0) {
	    width = 1;
	}
	if (height <= 0) {
	    height = 1;
	}

	/*
	 * Step 5: reconfigure the window and map it if needed. If the content
	 * is a child of the container, we do this ourselves. If the content isn't
	 * a child of the container, let Tk_MaintainGeometry do the work (it will
	 * re-adjust things as relevant windows map, unmap, and move).
	 */

	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((x != Tk_X(contentPtr->tkwin))
		    || (y != Tk_Y(contentPtr->tkwin))
		    || (width != Tk_Width(contentPtr->tkwin))
		    || (height != Tk_Height(contentPtr->tkwin))) {
		Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
	    }
            if (abort) {
                break;
            }

	    /*
	     * Don't map the content unless the container is mapped: the content will
	     * get mapped later, when the container is mapped.
	     */

	    if (Tk_IsMapped(containerPtr->tkwin)) {
		Tk_MapWindow(contentPtr->tkwin);
	    }
	} else {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin,
			x, y, width, height);
	    }
	}
    }

    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PlaceStructureProc --
 *
 *	This function is invoked by the Tk event handler when StructureNotify
 *	events occur for a container window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Structures get cleaned up if the window was deleted. If the window was
 *	resized then content geometries get recomputed.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceStructureProc(
    ClientData clientData,	/* Pointer to Container structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) containerPtr->tkwin)->dispPtr;

    switch (eventPtr->type) {
    case ConfigureNotify:
	if ((containerPtr->contentPtr != NULL)
		&& !(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	    containerPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
	}
	return;
    case DestroyNotify:
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->containerTable,
		containerPtr->tkwin));
	if (containerPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, containerPtr);
	}
	containerPtr->tkwin = NULL;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	Tcl_EventuallyFree(containerPtr, TCL_DYNAMIC);
	return;
    case MapNotify:
	/*
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((containerPtr->contentPtr != NULL)
		&& !(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	    containerPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
	}
	return;
    case UnmapNotify:
	/*
	 * Unmap all of the content when the container gets unmapped, so that they
	 * don't keep redisplaying themselves.
	 */

	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
	return;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ContentStructureProc --
 *
 *	This function is invoked by the Tk event handler when StructureNotify
 *	events occur for a content window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Structures get cleaned up if the window was deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ContentStructureProc(
    ClientData clientData,	/* Pointer to Content structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
	if (contentPtr->containerPtr != NULL) {
	    UnlinkContent(contentPtr);
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		contentPtr->tkwin));
	FreeContent(contentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PlaceRequestProc --
 *
 *	This function is invoked by Tk whenever a content 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.
 *
 *----------------------------------------------------------------------
 */


static void
PlaceRequestProc(
    ClientData clientData,	/* Pointer to our record for content. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Content *contentPtr = (Content *)clientData;
    Container *containerPtr;

    if ((contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
	    && (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
        /*
         * Send a ConfigureNotify to indicate that the size change
         * request was rejected.
         */

        TkDoConfigureNotify((TkWindow *)(contentPtr->tkwin));
	return;
    }
    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (!(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	containerPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PlaceLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all placer-related information about the content window.
 *
 *--------------------------------------------------------------
 */


static void
PlaceLostContentProc(
    ClientData clientData,	/* Content structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Tk_UnmapWindow(tkwin);
    UnlinkContent(contentPtr);
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
	    tkwin));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    FreeContent(contentPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|








|
|
|



|
|
|
|
|
|






|
|


|
|



|
|

|





|
|





|


|






|





|
|



|
|
|

|
<
|
|
|
|

<
|
|
|
|
|
|

|
|
|
|

|
|
|

|
<
|

|
|


|
|
|
|

<
|

|



|
|
|

<






|


|











|
|



|
|


|
|

|
|
|








|












>


|
|

|
|

|
|
<
<
<
<
<
<


|
|


|
|
|






|


|





|




>

|
|

|

|
|

|
|


|
|
|
|
|
|









993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100

1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111

1112
1113
1114
1115
1116
1117
1118
1119
1120
1121

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189






1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

	/*
	 * Step 4: adjust width and height again to reflect inside dimensions
	 * of window rather than outside. Also make sure that the width and
	 * height aren't zero.
	 */

	width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	if (width <= 0) {
	    width = 1;
	}
	if (height <= 0) {
	    height = 1;
	}

	/*
	 * 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)) {
	    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 unless the master is mapped: the slave will
	     * get mapped later, when the master is mapped.
	     */

	    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;
    Tcl_Release((ClientData) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * MasterStructureProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
MasterStructureProc(
    ClientData clientData,	/* Pointer to Master structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    register Master *masterPtr = (Master *) clientData;
    register Slave *slavePtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr;

    if (eventPtr->type == ConfigureNotify) {

	if ((masterPtr->slavePtr != NULL)
		&& !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	    masterPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
	}

    } else if (eventPtr->type == DestroyNotify) {
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = nextPtr) {
	    slavePtr->masterPtr = NULL;
	    nextPtr = slavePtr->nextPtr;
	    slavePtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
		(char *) masterPtr->tkwin));
	if (masterPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr);
	}
	masterPtr->tkwin = NULL;
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	}
	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.
	 */

	if ((masterPtr->slavePtr != NULL)
		&& !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	    masterPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
	}

    } else if (eventPtr->type == UnmapNotify) {
	/*
	 * Unmap all of the slaves when the master gets unmapped, so that they
	 * don't keep redisplaying themselves.
	 */

	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    Tk_UnmapWindow(slavePtr->tkwin);
	}

    }
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveStructureProc --
 *
 *	This function is invoked by the Tk event handler when StructureNotify
 *	events occur for a slave window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Structures get cleaned up if the window was deleted.
 *
 *----------------------------------------------------------------------
 */

static void
SlaveStructureProc(
    ClientData clientData,	/* Pointer to Slave structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    register Slave *slavePtr = (Slave *) clientData;
    TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
	if (slavePtr->masterPtr != NULL) {
	    UnlinkSlave(slavePtr);
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		(char *) slavePtr->tkwin));
	FreeSlave(slavePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PlaceRequestProc --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
PlaceRequestProc(
    ClientData clientData,	/* Pointer to our record for slave. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    Slave *slavePtr = (Slave *) clientData;
    Master *masterPtr;

    if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0)
	    && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) {






	return;
    }
    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
	return;
    }
    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	masterPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PlaceLostSlaveProc --
 *
 *	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 placer-related information about the slave.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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;

    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));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
	    (ClientData) slavePtr);
    FreeSlave(slavePtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkPlatDecls.h.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


41
42



43
44



45
46



47
48



49
50



51
52
53
54

55
56
57
58
59
60
61
62

63
64
65
66

67
68
69
70
71
72

73
74
75
76



77
78



79
80
81
82



83
84
85




































86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135


136
137


138
139


140
141


142
143


144
145

146
147
148
149
150
151

















152
153


154
155


156
157
158





159
160


161
162

163
164
165
166
167
168
169
170




171
172

173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */

#ifdef __cplusplus
extern "C" {
#endif

/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */


/* 0 */
EXTERN Window		Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);



/* 1 */
EXTERN HINSTANCE	Tk_GetHINSTANCE(void);



/* 2 */
EXTERN HWND		Tk_GetHWND(Window window);



/* 3 */
EXTERN Tk_Window	Tk_HWNDToWindow(HWND hwnd);



/* 4 */
EXTERN void		Tk_PointerEvent(HWND hwnd, int x, int y);



/* 5 */
EXTERN int		Tk_TranslateWinEvent(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam,
				LRESULT *result);

#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);

/* 5 */
EXTERN void		TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
/* 6 */

EXTERN void		TkMacOSXInvalClipRgns(Tk_Window tkwin);
/* Slot 7 is reserved */
/* 8 */
EXTERN void *		TkMacOSXGetRootControl(Drawable drawable);
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);

/* 10 */
EXTERN int		Tk_MacOSXIsAppInFront(void);
/* 11 */
EXTERN Tk_Window	Tk_MacOSXGetTkWindow(void *w);



/* 12 */
EXTERN void *		Tk_MacOSXGetCGContextForDrawable(Drawable drawable);



/* 13 */
EXTERN void *		Tk_MacOSXGetNSWindowForDrawable(Drawable drawable);
/* Slot 14 is reserved */
/* Slot 15 is reserved */



/* 16 */
EXTERN void		TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);




































#endif /* AQUA */

typedef struct TkPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    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 (*reserved0)(void);
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
    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 (*reserved7)(void);
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */
    void * (*tk_MacOSXGetNSWindowForDrawable) (Drawable drawable); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 16 */
#endif /* AQUA */
} TkPlatStubs;

extern const TkPlatStubs *tkPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */

#define Tk_AttachHWND \
	(tkPlatStubsPtr->tk_AttachHWND) /* 0 */


#define Tk_GetHINSTANCE \
	(tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */


#define Tk_GetHWND \
	(tkPlatStubsPtr->tk_GetHWND) /* 2 */


#define Tk_HWNDToWindow \
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */


#define Tk_PointerEvent \
	(tkPlatStubsPtr->tk_PointerEvent) /* 4 */


#define Tk_TranslateWinEvent \
	(tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */

#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */

















#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */


#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 5 */


#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
/* Slot 7 is reserved */





#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */


#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */

#define Tk_MacOSXIsAppInFront \
	(tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */
#define Tk_MacOSXGetTkWindow \
	(tkPlatStubsPtr->tk_MacOSXGetTkWindow) /* 11 */
#define Tk_MacOSXGetCGContextForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetCGContextForDrawable) /* 12 */
#define Tk_MacOSXGetNSWindowForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetNSWindowForDrawable) /* 13 */




/* Slot 14 is reserved */
/* Slot 15 is reserved */

#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 16 */

#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#ifdef __cplusplus
}
#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkGenWMConfigureEvent_
#define Tk_MacOSXGetNSViewForDrawable TkMacOSXGetRootControl

#endif /* _TKPLATDECLS */







<
<
<
<










|
>
>


>
>
>


>
>
>


>
>
>


>
>
>


>
>
>




>


<
|
|
<
|
|
>
|
|
|
|
>
|
<
<
|
|
|
>
|
|
|
|
>
>
>
|
|
>
>
>
|
|
<
<
>
>
>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|

|








|
|
|
|

|

|
|


|
|
|
|
|
|



|





|





|
>


>
>


>
>


>
>


>
>


>
>


>


<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
|
|
>
>


|
>
>
>
>
>


>
>


>
|
<
|
|
<
<
<
<
>
>
>
>


>
|
|
>


|



<
<
<
<



<
<
<

19
20
21
22
23
24
25




26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72

73
74
75
76
77
78
79
80
81


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215




216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258




259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274




275
276
277



278

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */





/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef Tk_AttachHWND_TCL_DECLARED
#define Tk_AttachHWND_TCL_DECLARED
/* 0 */
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(void);
#endif
#ifndef Tk_GetHWND_TCL_DECLARED
#define Tk_GetHWND_TCL_DECLARED
/* 2 */
EXTERN HWND		Tk_GetHWND(Window window);
#endif
#ifndef Tk_HWNDToWindow_TCL_DECLARED
#define Tk_HWNDToWindow_TCL_DECLARED
/* 3 */
EXTERN Tk_Window	Tk_HWNDToWindow(HWND hwnd);
#endif
#ifndef Tk_PointerEvent_TCL_DECLARED
#define Tk_PointerEvent_TCL_DECLARED
/* 4 */
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(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(
				Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
				Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
				Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
				Tk_MacOSXEmbedGetClipProc *getClipProc,
				Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
#endif
#ifndef Tk_MacOSXTurnOffMenus_TCL_DECLARED


#define Tk_MacOSXTurnOffMenus_TCL_DECLARED
/* 1 */
EXTERN void		Tk_MacOSXTurnOffMenus(void);
#endif
#ifndef Tk_MacOSXTkOwnsCursor_TCL_DECLARED
#define Tk_MacOSXTkOwnsCursor_TCL_DECLARED
/* 2 */
EXTERN void		Tk_MacOSXTkOwnsCursor(int tkOwnsIt);
#endif
#ifndef TkMacOSXInitMenus_TCL_DECLARED
#define TkMacOSXInitMenus_TCL_DECLARED
/* 3 */
EXTERN void		TkMacOSXInitMenus(Tcl_Interp *interp);
#endif
#ifndef TkMacOSXInitAppleEvents_TCL_DECLARED
#define TkMacOSXInitAppleEvents_TCL_DECLARED
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);


#endif
#ifndef TkGenWMConfigureEvent_TCL_DECLARED
#define TkGenWMConfigureEvent_TCL_DECLARED
/* 5 */
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(Tk_Window tkwin);
#endif
#ifndef TkMacOSXGetDrawablePort_TCL_DECLARED
#define TkMacOSXGetDrawablePort_TCL_DECLARED
/* 7 */
EXTERN VOID *		TkMacOSXGetDrawablePort(Drawable drawable);
#endif
#ifndef TkMacOSXGetRootControl_TCL_DECLARED
#define TkMacOSXGetRootControl_TCL_DECLARED
/* 8 */
EXTERN VOID *		TkMacOSXGetRootControl(Drawable drawable);
#endif
#ifndef Tk_MacOSXSetupTkNotifier_TCL_DECLARED
#define Tk_MacOSXSetupTkNotifier_TCL_DECLARED
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);
#endif
#ifndef Tk_MacOSXIsAppInFront_TCL_DECLARED
#define Tk_MacOSXIsAppInFront_TCL_DECLARED
/* 10 */
EXTERN int		Tk_MacOSXIsAppInFront(void);
#endif
/* Slot 11 is reserved */
/* Slot 12 is reserved */
/* Slot 13 is reserved */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
#ifndef TkUnusedStubEntry_TCL_DECLARED
#define TkUnusedStubEntry_TCL_DECLARED
/* 16 */
EXTERN void		TkUnusedStubEntry(void);
#endif
#endif /* AQUA */

typedef struct TkPlatStubs {
    int magic;
    struct TkPlatStubHooks *hooks;

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    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) (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 */
    VOID *reserved11;
    VOID *reserved12;
    VOID *reserved13;
    VOID *reserved14;
    VOID *reserved15;
    void (*tkUnusedStubEntry) (void); /* 16 */
#endif /* AQUA */
} TkPlatStubs;

extern TkPlatStubs *tkPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)

/*
 * Inline function declarations:
 */

#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#ifndef Tk_AttachHWND
#define Tk_AttachHWND \
	(tkPlatStubsPtr->tk_AttachHWND) /* 0 */
#endif
#ifndef Tk_GetHINSTANCE
#define Tk_GetHINSTANCE \
	(tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */
#endif
#ifndef Tk_GetHWND
#define Tk_GetHWND \
	(tkPlatStubsPtr->tk_GetHWND) /* 2 */
#endif
#ifndef Tk_HWNDToWindow
#define Tk_HWNDToWindow \
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */
#endif
#ifndef Tk_PointerEvent
#define Tk_PointerEvent \
	(tkPlatStubsPtr->tk_PointerEvent) /* 4 */
#endif
#ifndef Tk_TranslateWinEvent
#define Tk_TranslateWinEvent \
	(tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */
#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */




#ifndef Tk_MacOSXSetEmbedHandler
#define Tk_MacOSXSetEmbedHandler \
	(tkPlatStubsPtr->tk_MacOSXSetEmbedHandler) /* 0 */
#endif
#ifndef Tk_MacOSXTurnOffMenus
#define Tk_MacOSXTurnOffMenus \
	(tkPlatStubsPtr->tk_MacOSXTurnOffMenus) /* 1 */
#endif
#ifndef Tk_MacOSXTkOwnsCursor
#define Tk_MacOSXTkOwnsCursor \
	(tkPlatStubsPtr->tk_MacOSXTkOwnsCursor) /* 2 */
#endif
#ifndef TkMacOSXInitMenus
#define TkMacOSXInitMenus \
	(tkPlatStubsPtr->tkMacOSXInitMenus) /* 3 */
#endif
#ifndef TkMacOSXInitAppleEvents
#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
#endif
#ifndef TkGenWMConfigureEvent
#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 5 */
#endif
#ifndef TkMacOSXInvalClipRgns
#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
#endif
#ifndef TkMacOSXGetDrawablePort
#define TkMacOSXGetDrawablePort \
	(tkPlatStubsPtr->tkMacOSXGetDrawablePort) /* 7 */
#endif
#ifndef TkMacOSXGetRootControl
#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#endif
#ifndef Tk_MacOSXSetupTkNotifier
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */
#endif
#ifndef Tk_MacOSXIsAppInFront

#define Tk_MacOSXIsAppInFront \
	(tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */




#endif
/* Slot 11 is reserved */
/* Slot 12 is reserved */
/* Slot 13 is reserved */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
#ifndef TkUnusedStubEntry
#define TkUnusedStubEntry \
	(tkPlatStubsPtr->tkUnusedStubEntry) /* 16 */
#endif
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */

/* !END!: Do not edit above this line. */





#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT




#endif /* _TKPLATDECLS */

Changes to generic/tkPointer.c.

10
11
12
13
14
15
16
17
18
19
20
21
22

23
24












25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"

#endif













typedef struct {
    TkWindow *grabWinPtr;	/* Window that defines the top of the grab
				 * tree in a global grab. */
    unsigned lastState;		/* Last known state flags. */
    XPoint lastPos;		/* Last reported mouse position. */
    TkWindow *lastWinPtr;	/* Last reported mouse window. */
    TkWindow *restrictWinPtr;	/* Window to which all mouse events will be
				 * reported. */
    TkWindow *cursorWinPtr;	/* Window that is currently controlling the
				 * global cursor. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of procedures used in this file.
 */

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);

/*
 *----------------------------------------------------------------------
 *
 * InitializeEvent --







|





>


>
>
>
>
>
>
>
>
>
>
>
>
|


|















|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef __WIN32__
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#define Cursor XCursor
#endif

/*
 * Mask that selects any of the state bits corresponding to buttons, plus
 * masks that select individual buttons' bits:
 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)
static unsigned int buttonMasks[] = {
    Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask
};
#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. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of procedures used in this file.
 */

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);

/*
 *----------------------------------------------------------------------
 *
 * InitializeEvent --
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    unsigned changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b;
    unsigned mask;

    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.







|
|
<







233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b, mask;


    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    }

    /*
     * Generate ButtonPress/ButtonRelease events based on the differences
     * between the current button state and the last known button state.
     */

    for (b = Button1; b <= Button9; b++) {
	mask = Tk_GetButtonMask(b);
	if (changes & 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.
			 */

			tsdPtr->restrictWinPtr = winPtr;
			TkpSetCapture(tsdPtr->restrictWinPtr);

		    } else if (!(tsdPtr->lastState & ALL_BUTTONS)) {
			/*
			 * Mouse is in a non-button grab, so ensure the button
			 * grab is inside the grab tree.
			 */

			if (TkPositionInTree(winPtr, tsdPtr->grabWinPtr)
				== TK_GRAB_IN_TREE) {







|
|


















|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    }

    /*
     * Generate ButtonPress/ButtonRelease events based on the differences
     * between the current button state and the last known button state.
     */

    for (b = Button1; b <= Button5; b++) {
	mask = ButtonMask(b);
	if (changes & 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.
			 */

			tsdPtr->restrictWinPtr = winPtr;
			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.
			 */

			if (TkPositionInTree(winPtr, tsdPtr->grabWinPtr)
				== TK_GRAB_IN_TREE) {
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    int keyboard_mode,
    Window confine_to,
    Cursor cursor,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)owner_events;
    (void)event_mask;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)confine_to;
    (void)cursor;
    (void)time;

    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) {







<
<
<
<
<
<
<







434
435
436
437
438
439
440







441
442
443
444
445
446
447
    int keyboard_mode,
    Window confine_to,
    Cursor cursor,
    Time time)
{
    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) {
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
int
XUngrabPointer(
    Display *display,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)time;

    display->request++;
    tsdPtr->grabWinPtr = NULL;
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(NULL);
    UpdateCursor(tsdPtr->lastWinPtr);
    return Success;







<







469
470
471
472
473
474
475

476
477
478
479
480
481
482
int
XUngrabPointer(
    Display *display,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    display->request++;
    tsdPtr->grabWinPtr = NULL;
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(NULL);
    UpdateCursor(tsdPtr->lastWinPtr);
    return Success;
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;
    }
    if (!(tsdPtr->restrictWinPtr || tsdPtr->grabWinPtr)) {

        /*
         * Release mouse capture only if the dead window is the capturing
         * window.
         */

        if (winPtr == (TkWindow *)TkpGetCapture()) {
	    TkpSetCapture(NULL);
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateCursor --







<
<
<
<
<
<
<
|
<







511
512
513
514
515
516
517







518

519
520
521
522
523
524
525
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;
    }
    if (!(tsdPtr->restrictWinPtr || tsdPtr->grabWinPtr)) {







	TkpSetCapture(NULL);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateCursor --
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603









































604
605
606
607
608
609
610
611

int
XDefineCursor(
    Display *display,
    Window w,
    Cursor cursor)
{
    TkWindow *winPtr = (TkWindow *) Tk_IdToWindow(display, w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)cursor;

    if (tsdPtr->cursorWinPtr == winPtr) {
	UpdateCursor(winPtr);
    }
    display->request++;
    return Success;
}










































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

int
XDefineCursor(
    Display *display,
    Window w,
    Cursor cursor)
{
    TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (tsdPtr->cursorWinPtr == winPtr) {
	UpdateCursor(winPtr);
    }
    display->request++;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates X events.
 *
 *----------------------------------------------------------------------
 */

void
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.
     */

    event.xany.serial = winPtr->display->request++;
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xany.window = winPtr->window;

    event.xany.type = active ? ActivateNotify : DeactivateNotify;
    TkQueueEventForAllChildren(winPtr, &event);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkPort.h.

10
11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29
30
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKPORT
#define _TKPORT

#if defined(_WIN32)
#   include "tkWinPort.h"
#endif
#ifndef _TK
#   include "tk.h"
#endif
#if !defined(_WIN32)



#   if defined(MAC_OSX_TK)
#	include "tkMacOSXPort.h"
#   else
#	include "tkUnixPort.h"
#   endif
#endif








|
|

|
|

|
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKPORT
#define _TKPORT

#ifndef _TK
#include "tk.h"
#endif
#ifndef _TCL
#include "tcl.h"
#endif

#if defined(__WIN32__) || defined(_WIN32)
#   include "tkWinPort.h"
#else
#   if defined(MAC_OSX_TK)
#	include "tkMacOSXPort.h"
#   else
#	include "tkUnixPort.h"
#   endif
#endif

Changes to generic/tkRectOval.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
/*
 * tkRectOval.c --
 *
 *	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.
 */


#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

/*
 * The structure below defines the record for each rectangle/oval item.
 */

typedef struct RectOvalItem  {
    Tk_Item header;		/* Generic stuff that's the same for all












>


<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
/*
 * tkRectOval.c --
 *
 *	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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"


/*
 * The structure below defines the record for each rectangle/oval item.
 */

typedef struct RectOvalItem  {
    Tk_Item header;		/* Generic stuff that's the same for all
39
40
41
42
43
44
45
46

47
48
49

50
51
52

53
54
55
56

57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    GC fillGC;			/* Graphics context for filling item. */
} RectOvalItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {

    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {

    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {

    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)

};
static const Tk_CustomOption pixelOption = {

    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(RectOvalItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(RectOvalItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(RectOvalItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(RectOvalItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(RectOvalItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

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		RotateRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
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);

/*







|
>
|

|
>
|

|
>
|

|
|
>

|
>
|


|

|


|

|

|
|

|

|


|


|
|

|


|

|
|

|
|

|

|


|

|


|

|


|

|

|



|

|









|


|










|






<
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
    GC fillGC;			/* Graphics context for filling item. */
} RectOvalItem;

/*
 * Information used for parsing configuration specs:
 */

static Tk_CustomOption stateOption = {
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
};
static Tk_CustomOption tagsOption = {
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_CustomOption dashOption = {
    (Tk_OptionParseProc *) TkCanvasDashParseProc,
    TkCanvasDashPrintProc, (ClientData) NULL
};
static Tk_CustomOption offsetOption = {
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc, (ClientData) TK_OFFSET_RELATIVE
};
static Tk_CustomOption pixelOption = {
    (Tk_OptionParseProc *) TkPixelParseProc,
    TkPixelPrintProc, (ClientData) NULL
};

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(RectOvalItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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_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", NULL, NULL,
	NULL, Tk_Offset(RectOvalItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(RectOvalItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(RectOvalItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {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_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(RectOvalItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK},
    {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", 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", NULL, NULL,
	"black", Tk_Offset(RectOvalItem, outline.color), TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(RectOvalItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {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, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Prototypes for functions defined in this file:
 */

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);

/*
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateRectOval,		/* rotateProc */
    0, NULL, NULL
};

Tk_ItemType tkOvalType = {
    "oval",			/* name */
    sizeof(RectOvalItem),	/* itemSize */
    CreateRectOval,		/* createProc */
    configSpecs,		/* configSpecs */







<
<







182
183
184
185
186
187
188


189
190
191
192
193
194
195
    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 */
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateRectOval,		/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateRectOval --
 *







<
<







205
206
207
208
209
210
211


212
213
214
215
216
217
218
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */


};

/*
 *--------------------------------------------------------------
 *
 * CreateRectOval --
 *
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
static int
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) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
     * errors during the the remainder of this function.
     */








|





|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
static int
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) {
	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 function.
     */

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    rectOvalPtr->fillGC = NULL;

    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if ((RectOvalCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {
	goto error;







|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    rectOvalPtr->fillGC = NULL;

    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if ((RectOvalCoords(interp, canvas, itemPtr, i, objv) != TCL_OK)) {
	goto error;
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328

329

330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
static int
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 *bbox[4];


	bbox[0] = Tcl_NewDoubleObj(rectOvalPtr->bbox[0]);

	bbox[1] = Tcl_NewDoubleObj(rectOvalPtr->bbox[1]);

	bbox[2] = Tcl_NewDoubleObj(rectOvalPtr->bbox[2]);

	bbox[3] = Tcl_NewDoubleObj(rectOvalPtr->bbox[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	return 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;
	}
    }

    /*
     * Better have four coordinates now. Spit out an error message otherwise.
     */

    if (objc != 4) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS",
		(rectOvalPtr->header.typePtr == &tkRectangleType
			? "RECTANGLE" : "OVAL"), NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the coordinates and update our bounding box.
     */








|








|

>
|
>
|
>
|
>
|
|



















>
|
|
|
<
<







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358


359
360
361
362
363
364
365
static int
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_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);
	return 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;
	}
    }

    /*
     * 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.
     */

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

static int
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;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);

    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (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.







|















|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

static int
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;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);

    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (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.
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
    }
    if (rectOvalPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), rectOvalPtr->outline.gc);
    }
    rectOvalPtr->outline.gc = newGC;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputeRectOvalBbox(canvas, rectOvalPtr);
	return TCL_OK;
    }

    color = rectOvalPtr->fillColor;
    stipple = rectOvalPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (rectOvalPtr->activeFillColor!=NULL) {
	    color = rectOvalPtr->activeFillColor;
	}
	if (rectOvalPtr->activeFillStipple!=None) {
	    stipple = rectOvalPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {







|








|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
    }
    if (rectOvalPtr->outline.gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), rectOvalPtr->outline.gc);
    }
    rectOvalPtr->outline.gc = newGC;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputeRectOvalBbox(canvas, rectOvalPtr);
	return TCL_OK;
    }

    color = rectOvalPtr->fillColor;
    stipple = rectOvalPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (rectOvalPtr->activeFillColor!=NULL) {
	    color = rectOvalPtr->activeFillColor;
	}
	if (rectOvalPtr->activeFillStipple!=None) {
	    stipple = rectOvalPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
	    gcValues.fill_style = FillStippled;
	    mask = GCForeground|GCStipple|GCFillStyle;
	} else {
	    mask = GCForeground;
	}
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to the outline linewidth even for
	 * fills (as linewidth controls antialiasing).
	 */
	gcValues.line_width = rectOvalPtr->outline.gc != NULL ?
		rectOvalPtr->outline.gc->line_width : 0;
	mask |= GCLineWidth;
#endif
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    }







|
|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	    gcValues.fill_style = FillStippled;
	    mask = GCForeground|GCStipple|GCFillStyle;
	} else {
	    mask = GCForeground;
	}
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to the outline linewidth
	 * even for fills (as linewidth controls antialiasing).
	 */
	gcValues.line_width = rectOvalPtr->outline.gc != NULL ?
		rectOvalPtr->outline.gc->line_width : 0;
	mask |= GCLineWidth;
#endif
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    }
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
static void
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;
    (void)canvas;

    Tk_DeleteOutline(display, &(rectOvalPtr->outline));
    if (rectOvalPtr->fillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->fillColor);
    }
    if (rectOvalPtr->activeFillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->activeFillColor);







<







577
578
579
580
581
582
583

584
585
586
587
588
589
590
static void
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;


    Tk_DeleteOutline(display, &(rectOvalPtr->outline));
    if (rectOvalPtr->fillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->fillColor);
    }
    if (rectOvalPtr->activeFillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->activeFillColor);
618
619
620
621
622
623
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = rectOvalPtr->outline.width;
    if (state == TK_STATE_HIDDEN) {
	rectOvalPtr->header.x1 = rectOvalPtr->header.y1 =
	rectOvalPtr->header.x2 = rectOvalPtr->header.y2 = -1;
	return;
    }
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) rectOvalPtr) {
	if (rectOvalPtr->outline.activeWidth>width) {
	    width = rectOvalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectOvalPtr->outline.disabledWidth>0) {
	    width = rectOvalPtr->outline.disabledWidth;
	}







>










|








|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = rectOvalPtr->outline.width;
    if (state == TK_STATE_HIDDEN) {
	rectOvalPtr->header.x1 = rectOvalPtr->header.y1 =
	rectOvalPtr->header.x2 = rectOvalPtr->header.y2 = -1;
	return;
    }
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) {
	if (rectOvalPtr->outline.activeWidth>width) {
	    width = rectOvalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectOvalPtr->outline.disabledWidth>0) {
	    width = rectOvalPtr->outline.disabledWidth;
	}
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
    if (rectOvalPtr->outline.gc == NULL) {
	/*
	 * 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
	bloat = 0;
#endif /* _WIN32 */
    } 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?
	 */

	bloat = (int) (width+1.5)/2;
#else
	bloat = (int) (width+1)/2;
#endif /* MAC_OSX_TK */
    }

    /*
     * 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.
     */







|



|











|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
    if (rectOvalPtr->outline.gc == NULL) {
	/*
	 * 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
	bloat = 0;
#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?
	 */

	bloat = (int) (width+1.5)/2;
#else
	bloat = (int) (width+1)/2;
#endif
    }

    /*
     * 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.
     */
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    short x1, y1, x2, y2;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    (void)x;
    (void)y;
    (void)width;
    (void)height;

    /*
     * 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],
	    &x1, &y1);
    Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3],
	    &x2, &y2);
    if (x2 == x1) {

        /*
         * The width of the bounding box corresponds to less than one pixel
         * on screen. Adjustment is needed to avoid drawing attempts with zero
         * width items (which would draw nothing). The bounding box spans
         * either 1 or 2 pixels. Select which pixel will be drawn.
         */

        short ix1 = (short) (rectOvalPtr->bbox[0]);
        short ix2 = (short) (rectOvalPtr->bbox[2]);

        if (ix1 == ix2) {

            /*
             * x1 and x2 are "within the same pixel". Use this pixel.
             * Note: the degenerated case (bbox[0]==bbox[2]) of a completely
             * flat box results in arbitrary selection of the pixel at the
             * right (with positive coordinate) or left (with negative
             * coordinate) of the box. There is no "best choice" here.
             */

            if (ix1 > 0) {
                x2 += 1;
            } else {
                x1 -= 1;
            }
        } else {

            /*
             * (x1,x2) span two pixels. Select the one with the larger
             * covered "area".
             */

            if (ix1 > 0) {
                if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) {
                    x2 += 1;
                } else {
                    x1 -= 1;
                }
            } else {
                if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) {
                    x2 += 1;
                } else {
                    x1 -= 1;
                }
            }
        }
    }
    if (y2 == y1) {

        /*
         * The height of the bounding box corresponds to less than one pixel
         * on screen. Adjustment is needed to avoid drawing attempts with zero
         * height items (which would draw nothing). The bounding box spans
         * either 1 or 2 pixels. Select which pixel will be drawn.
         */

        short iy1 = (short) (rectOvalPtr->bbox[1]);
        short iy2 = (short) (rectOvalPtr->bbox[3]);

        if (iy1 == iy2) {

            /*
             * y1 and y2 are "within the same pixel". Use this pixel.
             * Note: the degenerated case (bbox[1]==bbox[3]) of a completely
             * flat box results in arbitrary selection of the pixel below
             * (with positive coordinate) or above (with negative coordinate)
             * the box. There is no "best choice" here.
             */

            if (iy1 > 0) {
                y2 += 1;
            } else {
                y1 -= 1;
            }
        } else {

            /*
             * (y1,y2) span two pixels. Select the one with the larger
             * covered "area".
             */

            if (iy1 > 0) {
                if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) {
                    y2 += 1;
                } else {
                    y1 -= 1;
                }
            } else {
                if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) {
                    y2 += 1;
                } else {
                    y1 -= 1;
                }
            }
        }
    }

    /*
     * 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) {
	state = Canvas(canvas)->canvas_state;
    }
    fillStipple = rectOvalPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) rectOvalPtr) {
	if (rectOvalPtr->activeFillStipple != None) {
	    fillStipple = rectOvalPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectOvalPtr->disabledFillStipple != None) {
	    fillStipple = rectOvalPtr->disabledFillStipple;
	}







<
<
<
<







|

|

|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|


|







750
751
752
753
754
755
756




757
758
759
760
761
762
763
764
765
766
767
768
769






770








































771
772














































773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    short x1, y1, x2, y2;
    Pixmap fillStipple;
    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.
     */

    Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0], rectOvalPtr->bbox[1],
	    &x1, &y1);
    Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2], rectOvalPtr->bbox[3],
	    &x2, &y2);
    if (x2 <= x1) {
	x2 = x1+1;






    }








































    if (y2 <= y1) {
	y2 = y1+1;














































    }

    /*
     * 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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    fillStipple = rectOvalPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) {
	if (rectOvalPtr->activeFillStipple != None) {
	    fillStipple = rectOvalPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectOvalPtr->disabledFillStipple != None) {
	    fillStipple = rectOvalPtr->disabledFillStipple;
	}
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = rectPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (rectPtr->outline.activeWidth>width) {
	    width = rectPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectPtr->outline.disabledWidth>0) {
	    width = rectPtr->outline.disabledWidth;
	}







>












|



|







867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = rectPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (rectPtr->outline.activeWidth>width) {
	    width = rectPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectPtr->outline.disabledWidth>0) {
	    width = rectPtr->outline.disabledWidth;
	}
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = (double) ovalPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (ovalPtr->outline.activeWidth>width) {
	    width = (double) ovalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (ovalPtr->outline.disabledWidth>0) {
	    width = (double) ovalPtr->outline.disabledWidth;
	}







>












|



|







987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = (double) ovalPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (ovalPtr->outline.activeWidth>width) {
	    width = (double) ovalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (ovalPtr->outline.disabledWidth>0) {
	    width = (double) ovalPtr->outline.disabledWidth;
	}
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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) {
	state = Canvas(canvas)->canvas_state;
    }

    width = rectPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (rectPtr->outline.activeWidth > width) {
	    width = rectPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectPtr->outline.disabledWidth > 0) {
	    width = rectPtr->outline.disabledWidth;
	}
    }

    halfWidth = width/2.0;
    if (rectPtr->outline.gc == NULL) {
	halfWidth = 0.0;







>













|



|
|



|







1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = rectPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (rectPtr->outline.activeWidth>width) {
	    width = rectPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (rectPtr->outline.disabledWidth>0) {
	    width = rectPtr->outline.disabledWidth;
	}
    }

    halfWidth = width/2.0;
    if (rectPtr->outline.gc == NULL) {
	halfWidth = 0.0;
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
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, width;
    int result;

    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = ovalPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (ovalPtr->outline.activeWidth > width) {
	    width = ovalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (ovalPtr->outline.disabledWidth > 0) {
	    width = ovalPtr->outline.disabledWidth;
	}
    }

    /*
     * Expand the oval to include the width of the outline, if any.
     */







>








|

>



|



|
|



|







1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
    int result;
    double width;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }

    width = ovalPtr->outline.width;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (ovalPtr->outline.activeWidth>width) {
	    width = ovalPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (ovalPtr->outline.disabledWidth>0) {
	    width = ovalPtr->outline.disabledWidth;
	}
    }

    /*
     * Expand the oval to include the width of the outline, if any.
     */
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
		&& ((xDelta2 + yDelta1) < 1.0)
		&& ((xDelta2 + yDelta2) < 1.0)) {
	    return -1;
	}
    }
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * RotateRectOval --
 *
 *	This function is invoked to rotate a rectangle or oval item's
 *	coordinates. It works by rotating a computed point in the centre of
 *	the bounding box, NOT by rotating the corners of the bounding box.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the rectangle or oval is rotated by angleRad about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateRectOval(
    Tk_Canvas canvas,		/* Canvas containing rectangle. */
    Tk_Item *itemPtr,		/* Rectangle to be scaled. */
    double originX, double originY,
				/* Origin about which to rotate rect. */
    double angleRad)		/* Amount to scale in X direction. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double newX, newY, oldX, oldY;

    /*
     * Compute the centre of the box, then rotate that about the origin.
     */

    newX = oldX = (rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2]) / 2.0;
    newY = oldY = (rectOvalPtr->bbox[1] + rectOvalPtr->bbox[3]) / 2.0;
    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &newX, &newY);

    /*
     * Apply the translation to the box.
     */

    rectOvalPtr->bbox[0] += newX - oldX;
    rectOvalPtr->bbox[1] += newY - oldY;
    rectOvalPtr->bbox[2] += newX - oldX;
    rectOvalPtr->bbox[3] += newY - oldY;
    ComputeRectOvalBbox(canvas, rectOvalPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleRectOval --
 *
 *	This function is invoked to rescale a rectangle or oval item.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1193
1194
1195
1196
1197
1198
1199



















































1200
1201
1202
1203
1204
1205
1206
		&& ((xDelta2 + yDelta1) < 1.0)
		&& ((xDelta2 + yDelta2) < 1.0)) {
	    return -1;
	}
    }
    return result;
}




















































/*
 *--------------------------------------------------------------
 *
 * ScaleRectOval --
 *
 *	This function is invoked to rescale a rectangle or oval item.
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
    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. */
{
    Tcl_Obj *pathObj, *psObj;
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double y1, y2;
    XColor *color;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    Tcl_InterpState interpState;
    (void)prepass;

    y1 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[1]);
    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 function's code that is type-specific.
     */

    if (rectOvalPtr->header.typePtr == &tkRectangleType) {
	pathObj = Tcl_ObjPrintf(
		"%.15g %.15g moveto "
		"%.15g 0 rlineto "
		"0 %.15g rlineto "
		"%.15g 0 rlineto "
		"closepath\n",
		rectOvalPtr->bbox[0], y1,
		rectOvalPtr->bbox[2]-rectOvalPtr->bbox[0],
		y2-y1,
		rectOvalPtr->bbox[0]-rectOvalPtr->bbox[2]);
    } else {
	pathObj = Tcl_ObjPrintf(
		"matrix currentmatrix\n"
		"%.15g %.15g translate "
		"%.15g %.15g scale "
		"1 0 moveto 0 0 1 0 360 arc\n"
		"setmatrix\n",
		(rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2])/2, (y1 + y2)/2,
		(rectOvalPtr->bbox[2] - rectOvalPtr->bbox[0])/2, (y1 - y2)/2);
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    color = rectOvalPtr->outline.color;
    fillColor = rectOvalPtr->fillColor;
    fillStipple = rectOvalPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (rectOvalPtr->outline.activeColor!=NULL) {
	    color = rectOvalPtr->outline.activeColor;
	}
	if (rectOvalPtr->activeFillColor!=NULL) {
	    fillColor = rectOvalPtr->activeFillColor;
	}
	if (rectOvalPtr->activeFillStipple!=None) {







|






<
<










<
|
<
<
<
<

|
<


<
<
<
<
|
<





|




|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307


1308
1309
1310
1311
1312
1313
1314
1315
1316
1317

1318




1319
1320

1321
1322




1323

1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
    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;
    double y1, y2;
    XColor *color;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;



    y1 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[1]);
    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 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,
		rectOvalPtr->bbox[2]-rectOvalPtr->bbox[0], y2-y1,

		rectOvalPtr->bbox[0]-rectOvalPtr->bbox[2]);
    } else {




	sprintf(pathCmd, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n",

		(rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2])/2, (y1 + y2)/2,
		(rectOvalPtr->bbox[2] - rectOvalPtr->bbox[0])/2, (y1 - y2)/2);
    }

    if (state == TK_STATE_NULL) {
	state = ((TkCanvas *)canvas)->canvas_state;
    }
    color = rectOvalPtr->outline.color;
    fillColor = rectOvalPtr->fillColor;
    fillStipple = rectOvalPtr->fillStipple;
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
	if (rectOvalPtr->outline.activeColor!=NULL) {
	    color = rectOvalPtr->outline.activeColor;
	}
	if (rectOvalPtr->activeFillColor!=NULL) {
	    fillColor = rectOvalPtr->activeFillColor;
	}
	if (rectOvalPtr->activeFillStipple!=None) {
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528


1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551


1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
	    fillColor = rectOvalPtr->disabledFillColor;
	}
	if (rectOvalPtr->disabledFillStipple!=None) {
	    fillStipple = rectOvalPtr->disabledFillStipple;
	}
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * First draw the filled area of the rectangle.
     */

    if (fillColor != NULL) {
	Tcl_AppendObjToObj(psObj, pathObj);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);



	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {
	Tcl_AppendObjToObj(psObj, pathObj);
	Tcl_AppendToObj(psObj, "0 setlinejoin 2 setlinecap\n", -1);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &rectOvalPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));


    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    Tcl_DecrRefCount(pathObj);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<





<
<
|
|
<
>
|

|
>
>
|
<
<
<

|


|








<
|
|
<
|
<
>
>
|
|
<
<
<
<
<
<
<
<










1349
1350
1351
1352
1353
1354
1355







1356
1357
1358
1359
1360


1361
1362

1363
1364
1365
1366
1367
1368
1369



1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384

1385

1386
1387
1388
1389








1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
	    fillColor = rectOvalPtr->disabledFillColor;
	}
	if (rectOvalPtr->disabledFillStipple!=None) {
	    fillStipple = rectOvalPtr->disabledFillStipple;
	}
    }








    /*
     * First draw the filled area of the rectangle.
     */

    if (fillColor != NULL) {


	Tcl_AppendResult(interp, pathCmd, NULL);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (fillStipple != None) {
	    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", NULL);
	    }
	} else {
	    Tcl_AppendResult(interp, "fill\n", NULL);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {

	Tcl_AppendResult(interp, pathCmd, "0 setlinejoin 2 setlinecap\n",
		NULL);

	if (Tk_CanvasPsOutline(canvas, itemPtr,

		&(rectOvalPtr->outline))!= TCL_OK) {
	    return TCL_ERROR;
	}
    }








    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkScale.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * 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.
 */

#include "tkInt.h"
#include "tkScale.h"
#include "default.h"

#if defined(_WIN32)
#define snprintf _snprintf
#endif

/*
 * 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[] = {







|
|
|
<
<
<
<







13
14
15
16
17
18
19
20
21
22




23
24
25
26
27
28
29
 * 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.
 */

#include "default.h"
#include "tkInt.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.
 */

static const char *const orientStrings[] = {
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCALE_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, activeBorder),
	0, DEF_SCALE_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_SCALE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, bgBorder),
	0, DEF_SCALE_BG_MONO, 0},
    {TK_OPTION_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement",
	DEF_SCALE_BIG_INCREMENT, TCL_INDEX_NONE, offsetof(TkScale, bigIncrement),
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_SCALE_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(TkScale, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SCALE_COMMAND, TCL_INDEX_NONE, offsetof(TkScale, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_SCALE_CURSOR, TCL_INDEX_NONE, offsetof(TkScale, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-digits", "digits", "Digits",
	DEF_SCALE_DIGITS, TCL_INDEX_NONE, offsetof(TkScale, digits),
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_SCALE_FONT, TCL_INDEX_NONE, offsetof(TkScale, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_SCALE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, textColorPtr), 0,
	(ClientData) DEF_SCALE_FG_MONO, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From", DEF_SCALE_FROM, TCL_INDEX_NONE,
	offsetof(TkScale, fromValue), 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkScale, highlightBorder),
	0, DEF_SCALE_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCALE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkScale, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(TkScale, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-label", "label", "Label",
	DEF_SCALE_LABEL, TCL_INDEX_NONE, offsetof(TkScale, label),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, length), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_SCALE_ORIENT, TCL_INDEX_NONE, offsetof(TkScale, orient),
	0, orientStrings, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_SCALE_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, relief), 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCALE_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkScale, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCALE_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, repeatInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-resolution", "resolution", "Resolution",
	DEF_SCALE_RESOLUTION, TCL_INDEX_NONE, offsetof(TkScale, resolution),
	0, 0, 0},
    {TK_OPTION_BOOLEAN, "-showvalue", "showValue", "ShowValue",
	DEF_SCALE_SHOW_VALUE, TCL_INDEX_NONE, offsetof(TkScale, showValue),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sliderlength", "sliderLength", "SliderLength",
	DEF_SCALE_SLIDER_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, sliderLength),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief",
	DEF_SCALE_SLIDER_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, sliderRelief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_SCALE_STATE, TCL_INDEX_NONE, offsetof(TkScale, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCALE_TAKE_FOCUS, offsetof(TkScale, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-tickinterval", "tickInterval", "TickInterval",
	DEF_SCALE_TICK_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, tickInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SCALE_TO, TCL_INDEX_NONE, offsetof(TkScale, toValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCALE_TROUGH_COLOR, TCL_INDEX_NONE, offsetof(TkScale, troughColorPtr),
	0, DEF_SCALE_TROUGH_MONO, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_SCALE_VARIABLE, offsetof(TkScale, varNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_SCALE_WIDTH, TCL_INDEX_NONE, offsetof(TkScale, width), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The following tables define the scale widget commands and map the indexes
 * into the string tables into a single enumerated type used to dispatch the
 * scale widget command.
 */

static const char *const commandNames[] = {
    "cget", "configure", "coords", "get", "identify", "set", NULL
};

enum command {
    COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_COORDS, COMMAND_GET,
    COMMAND_IDENTIFY, COMMAND_SET
};

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		ComputeFormat(TkScale *scalePtr, int forTicks);
static void		ComputeScaleGeometry(TkScale *scalePtr);
static int		ConfigureScale(Tcl_Interp *interp, TkScale *scalePtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyScale(void *memPtr);
static double		MaxTickRoundingError(TkScale *scalePtr,
			    double tickResolution);
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
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs scaleClass = {
    sizeof(Tk_ClassProcs),	/* size */
    ScaleWorldChanged,		/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 *--------------------------------------------------------------
 *
 * ScaleDigit, ScaleMax, ScaleMin, ScaleRound --
 *
 *	Simple math helper functions, designed to be automatically inlined by
 *	the compiler most of the time.
 *
 *--------------------------------------------------------------
 */

static inline int
ScaleDigit(
    double value)
{
    return (int) floor(log10(fabs(value)));
}

static inline double
ScaleMax(
    double a,
    double b)
{
    return (a > b) ? a : b;
}

static inline double
ScaleMin(
    double a,
    double b)
{
    return (a < b) ? a : b;
}

static inline int
ScaleRound(
    double value)
{
    return (int) floor(value + 0.5);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_ScaleObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScaleObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    TkScale *scalePtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;







|
|

|
|

|


|

|

|


|


|


|


|

|

|

|
|


|
|

|


|
|

|


|

|
|

|

|


|


|


|


|


|


|
|

|


|


|

|
|

|


|
|








|












|



|
<
<

















|


<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|




|


<


|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180


181









































182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

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},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_SCALE_BG_COLOR, -1, Tk_Offset(TkScale, bgBorder),
	0, (ClientData) DEF_SCALE_BG_MONO, 0},
    {TK_OPTION_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement",
	DEF_SCALE_BIG_INCREMENT, -1, Tk_Offset(TkScale, bigIncrement),
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", 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},
    {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", 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},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkScale, highlightBorder),
	0, (ClientData) DEF_SCALE_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCALE_HIGHLIGHT, -1, Tk_Offset(TkScale, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(TkScale, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-label", "label", "Label",
	DEF_SCALE_LABEL, -1, Tk_Offset(TkScale, label),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, -1, Tk_Offset(TkScale, length), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_SCALE_ORIENT, -1, Tk_Offset(TkScale, orient),
	0, (ClientData) orientStrings, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_SCALE_RELIEF, -1, Tk_Offset(TkScale, relief), 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCALE_REPEAT_DELAY, -1, Tk_Offset(TkScale, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCALE_REPEAT_INTERVAL, -1, Tk_Offset(TkScale, repeatInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-resolution", "resolution", "Resolution",
	DEF_SCALE_RESOLUTION, -1, Tk_Offset(TkScale, resolution),
	0, 0, 0},
    {TK_OPTION_BOOLEAN, "-showvalue", "showValue", "ShowValue",
	DEF_SCALE_SHOW_VALUE, -1, Tk_Offset(TkScale, showValue),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sliderlength", "sliderLength", "SliderLength",
	DEF_SCALE_SLIDER_LENGTH, -1, Tk_Offset(TkScale, sliderLength),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief",
	DEF_SCALE_SLIDER_RELIEF, -1, Tk_Offset(TkScale, sliderRelief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_SCALE_STATE, -1, Tk_Offset(TkScale, state),
	0, (ClientData) stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCALE_TAKE_FOCUS, Tk_Offset(TkScale, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-tickinterval", "tickInterval", "TickInterval",
	DEF_SCALE_TICK_INTERVAL, -1, Tk_Offset(TkScale, tickInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SCALE_TO, -1, Tk_Offset(TkScale, toValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCALE_TROUGH_COLOR, -1, Tk_Offset(TkScale, troughColorPtr),
	0, (ClientData) DEF_SCALE_TROUGH_MONO, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_SCALE_VARIABLE, Tk_Offset(TkScale, varNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_SCALE_WIDTH, -1, Tk_Offset(TkScale, width), 0, 0, 0},
    {TK_OPTION_END, 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.
 */

static const char *commandNames[] = {
    "cget", "configure", "coords", "get", "identify", "set", NULL
};

enum command {
    COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_COORDS, COMMAND_GET,
    COMMAND_IDENTIFY, COMMAND_SET
};

/*
 * Forward declarations for procedures defined later in this file:
 */

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
 * that can be invoked from generic window code.
 */

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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
     */

    scalePtr->tkwin		= tkwin;
    scalePtr->display		= Tk_Display(tkwin);
    scalePtr->interp		= interp;
    scalePtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(scalePtr->tkwin), ScaleWidgetObjCmd,
	    scalePtr, ScaleCmdDeletedProc);
    scalePtr->optionTable	= optionTable;
    scalePtr->orient		= ORIENT_VERTICAL;
    scalePtr->width		= 0;
    scalePtr->length		= 0;
    scalePtr->value		= 0.0;
    scalePtr->varNamePtr	= NULL;
    scalePtr->fromValue		= 0.0;







|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
     */

    scalePtr->tkwin		= tkwin;
    scalePtr->display		= Tk_Display(tkwin);
    scalePtr->interp		= interp;
    scalePtr->widgetCmd		= Tcl_CreateObjCommand(interp,
	    Tk_PathName(scalePtr->tkwin), ScaleWidgetObjCmd,
	    (ClientData) scalePtr, ScaleCmdDeletedProc);
    scalePtr->optionTable	= optionTable;
    scalePtr->orient		= ORIENT_VERTICAL;
    scalePtr->width		= 0;
    scalePtr->length		= 0;
    scalePtr->value		= 0.0;
    scalePtr->varNamePtr	= NULL;
    scalePtr->fromValue		= 0.0;
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    scalePtr->vertTroughX	= 0;
    scalePtr->vertLabelX	= 0;
    scalePtr->fontHeight	= 0;
    scalePtr->cursor		= NULL;
    scalePtr->takeFocusPtr	= NULL;
    scalePtr->flags		= NEVER_SET;

    Tk_SetClassProcs(scalePtr->tkwin, &scaleClass, scalePtr);
    Tk_CreateEventHandler(scalePtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ScaleEventProc, scalePtr);

    if ((Tk_InitOptions(interp, scalePtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureScale(interp, scalePtr, objc - 2, objv + 2) != TCL_OK)) {
	Tk_DestroyWindow(scalePtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * The widget was just created, no command callback must be invoked.
     */

    scalePtr->flags &= ~INVOKE_COMMAND;

    Tcl_SetObjResult(interp, Tk_NewWindowObj(scalePtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWidgetObjCmd --







|


|

|






<
<
<
|
<
<
<







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303



304



305
306
307
308
309
310
311
    scalePtr->vertTroughX	= 0;
    scalePtr->vertLabelX	= 0;
    scalePtr->fontHeight	= 0;
    scalePtr->cursor		= NULL;
    scalePtr->takeFocusPtr	= NULL;
    scalePtr->flags		= NEVER_SET;

    Tk_SetClassProcs(scalePtr->tkwin, &scaleClass, (ClientData) scalePtr);
    Tk_CreateEventHandler(scalePtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ScaleEventProc, (ClientData) scalePtr);

    if ((Tk_InitOptions(interp, (char *) scalePtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureScale(interp, scalePtr, objc - 2, objv + 2) != TCL_OK)) {
	Tk_DestroyWindow(scalePtr->tkwin);
	return TCL_ERROR;
    }




    Tcl_SetResult(interp, Tk_PathName(scalePtr->tkwin), TCL_STATIC);



    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWidgetObjCmd --
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
static int
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 ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames,
	    sizeof(char *), "option", 0, &index);
    if (result != TCL_OK) {
	return result;
    }
    Tcl_Preserve(scalePtr);

    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}
	objPtr = Tk_GetOptionValue(interp, scalePtr,
		scalePtr->optionTable, objv[2], scalePtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);

	break;
    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, scalePtr,
		    scalePtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, scalePtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    result = ConfigureScale(interp, scalePtr, objc-2, objv+2);
	}
	break;
    case COMMAND_COORDS: {
	int x, y;
	double value;
	Tcl_Obj *coords[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) {







|




|


|
|



|







|



|
|
>



|




|
|
>





|

|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
static int
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 ...?");
	return TCL_ERROR;
    }
    result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
	    "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);
	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;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
	} else {
	    result = ConfigureScale(interp, scalePtr, objc-2, objv+2);
	}
	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;
	}
	if (objc == 3) {
	    if (Tcl_GetDoubleFromObj(interp, objv[2], &value) != TCL_OK) {
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

493


494


495


496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
		    + scalePtr->borderWidth;
	    y = TkScaleValueToPixel(scalePtr, value);
	} else {
	    x = TkScaleValueToPixel(scalePtr, value);
	    y = scalePtr->horizTroughY + scalePtr->width/2
		    + scalePtr->borderWidth;
	}
	coords[0] = Tcl_NewWideIntObj(x);
	coords[1] = Tcl_NewWideIntObj(y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;
    }
    case COMMAND_GET: {
	double value;
	int x, y;


	if ((objc != 2) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?");
	    goto error;
	}
	if (objc == 2) {
	    value = scalePtr->value;
	} else {
	    if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
		    (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
		goto error;
	    }
	    value = TkScalePixelToValue(scalePtr, x, y);
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(scalePtr->valueFormat, value));
	break;
    }
    case COMMAND_IDENTIFY: {
	int x, y;
	const char *zone = "";

	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;
	}
	switch (TkpScaleElement(scalePtr, x, y)) {

	case TROUGH1:	zone = "trough1"; break;


	case SLIDER:	zone = "slider";  break;


	case TROUGH2:	zone = "trough2"; break;


	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	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(scalePtr);
    return result;

  error:
    Tcl_Release(scalePtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyScale --







|
<
|





>














>
|



|
<









|
>
|
>
>
|
>
>
|
>
>

<


















|



|







394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
		    + 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;
	    }
	    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");
	    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:
    Tcl_Release((ClientData) scalePtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyScale --
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
 *	Everything associated with the scale is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyScale(
    void *memPtr)	/* Info about scale widget. */
{
    TkScale *scalePtr = (TkScale *) memPtr;

    scalePtr->flags |= SCALE_DELETED;

    Tcl_DeleteCommandFromToken(scalePtr->interp, scalePtr->widgetCmd);
    if (scalePtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayScale, scalePtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    if (scalePtr->varNamePtr != NULL) {
	Tcl_UntraceVar2(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ScaleVarProc, scalePtr);
    }
    if (scalePtr->troughGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
    }
    if (scalePtr->copyGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->copyGC);
    }







|

|





|








|
|
|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
 *	Everything associated with the scale is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyScale(
    char *memPtr)	/* Info about scale widget. */
{
    register TkScale *scalePtr = (TkScale *) memPtr;

    scalePtr->flags |= SCALE_DELETED;

    Tcl_DeleteCommandFromToken(scalePtr->interp, scalePtr->widgetCmd);
    if (scalePtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayScale, (ClientData) scalePtr);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    if (scalePtr->varNamePtr != NULL) {
	Tcl_UntraceVar(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ScaleVarProc, (ClientData) scalePtr);
    }
    if (scalePtr->troughGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
    }
    if (scalePtr->copyGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->copyGC);
    }
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureScale(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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;
    int error;
    double varValue;

    /*
     * Eliminate any existing trace on a variable monitored by the scale.
     */

    if (scalePtr->varNamePtr != NULL) {
	Tcl_UntraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ScaleVarProc, scalePtr);
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, scalePtr,
		    scalePtr->optionTable, objc, objv, scalePtr->tkwin,
		    &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
	     */








|














|
|
|








|
|
|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
 *
 *----------------------------------------------------------------------
 */

static int
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;
    int error;
    double varValue;

    /*
     * Eliminate any existing trace on a variable monitored by the scale.
     */

    if (scalePtr->varNamePtr != NULL) {
	Tcl_UntraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ScaleVarProc, (ClientData) scalePtr);
    }

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) scalePtr,
		    scalePtr->optionTable, objc, objv,
		    scalePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
	     */

651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666


667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
	    double value;
	    Tcl_Obj *valuePtr;

	    valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
		    TCL_GLOBAL_ONLY);
	    if ((valuePtr != NULL) &&
		    (Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
		scalePtr->value = TkRoundValueToResolution(scalePtr, value);
	    }
	}

        /*
         * The fromValue shall not be rounded to the resolution, but the
         * toValue and tickInterval do.
         */



	scalePtr->toValue = TkRoundValueToResolution(scalePtr, scalePtr->toValue);
	scalePtr->tickInterval = TkRoundIntervalToResolution(scalePtr,
		scalePtr->tickInterval);

	/*
	 * Make sure that the tick interval has the right sign so that
	 * addition moves from fromValue to toValue.
	 */

	if ((scalePtr->tickInterval < 0)
		^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
	    scalePtr->tickInterval = -scalePtr->tickInterval;
	}

	ComputeFormat(scalePtr, 0);
	ComputeFormat(scalePtr, 1);

	scalePtr->labelLength = scalePtr->label ? strlen(scalePtr->label) : 0;

	Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder);

	if (scalePtr->highlightWidth < 0) {
	    scalePtr->highlightWidth = 0;
	}
	scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth;







|



|
|
|
|

>
>
|
|












|
<

|







603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

636
637
638
639
640
641
642
643
644
	    double value;
	    Tcl_Obj *valuePtr;

	    valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
		    TCL_GLOBAL_ONLY);
	    if ((valuePtr != NULL) &&
		    (Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
		scalePtr->value = TkRoundToResolution(scalePtr, value);
	    }
	}

	/*
	 * Several options need special processing, such as parsing the
	 * orientation and creating GCs.
	 */

	scalePtr->fromValue = TkRoundToResolution(scalePtr,
		scalePtr->fromValue);
	scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue);
	scalePtr->tickInterval = TkRoundToResolution(scalePtr,
		scalePtr->tickInterval);

	/*
	 * Make sure that the tick interval has the right sign so that
	 * addition moves from fromValue to toValue.
	 */

	if ((scalePtr->tickInterval < 0)
		^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
	    scalePtr->tickInterval = -scalePtr->tickInterval;
	}

	ComputeFormat(scalePtr);


	scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0;

	Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder);

	if (scalePtr->highlightWidth < 0) {
	    scalePtr->highlightWidth = 0;
	}
	scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth;
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
		TCL_GLOBAL_ONLY);
	if ((valuePtr == NULL) || (Tcl_GetDoubleFromObj(NULL,
		valuePtr, &varValue) != TCL_OK)) {
	    ScaleSetVariable(scalePtr);
	} else {
	    char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];

            Tcl_PrintDouble(NULL, varValue, varString);
            Tcl_PrintDouble(NULL, scalePtr->value, scaleString);
            if (strcmp(varString, scaleString)) {
		ScaleSetVariable(scalePtr);
	    }
	}
	Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ScaleVarProc, scalePtr);
    }

    ScaleWorldChanged(scalePtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|
|
|



|
|
|


|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
		TCL_GLOBAL_ONLY);
	if ((valuePtr == NULL) || (Tcl_GetDoubleFromObj(NULL,
		valuePtr, &varValue) != TCL_OK)) {
	    ScaleSetVariable(scalePtr);
	} else {
	    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);
    }

    ScaleWorldChanged((ClientData) scalePtr);
    if (error) {
	Tcl_SetObjResult(interp, errorResult);
	Tcl_DecrRefCount(errorResult);
	return TCL_ERROR;
    }
    return TCL_OK;
}
764
765
766
767
768
769
770
771


772
773
774
775
776
777
778

static void
ScaleWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    TkScale *scalePtr = (TkScale *)instanceData;



    gcValues.foreground = scalePtr->troughColorPtr->pixel;
    gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues);
    if (scalePtr->troughGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
    }
    scalePtr->troughGC = gc;







|
>
>







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

static void
ScaleWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    TkScale *scalePtr;

    scalePtr = (TkScale *) instanceData;

    gcValues.foreground = scalePtr->troughColorPtr->pixel;
    gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues);
    if (scalePtr->troughGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->troughGC);
    }
    scalePtr->troughGC = gc;
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866

867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
     * know how much space is needed now.
     */

    ComputeScaleGeometry(scalePtr);

    TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
}

 /*
  *----------------------------------------------------------------------
  *
  * MaxTickRoundingError --
  *
  *      Given the separation between values that can be displayed on ticks,
  *      this calculates the maximum magnitude of error for the displayed
  *      value. Tries to be clever by working out the increment in error
  *      between ticks rather than testing all of them, so may overestimate
  *      error if it is greater than 0.25 x the value separation.
  *
  * Results:
  *      Maximum error magnitude of tick numbers.
  *
  * Side effects:
  *      None.
  *
  *----------------------------------------------------------------------
  */

static double
MaxTickRoundingError(
    TkScale *scalePtr,		/* Information about scale widget. */
    double tickResolution)      /* Separation between displayable values. */
{
    double tickPosn, firstTickError, lastTickError, intervalError;
    int tickCount;

    /*
     * Compute the error for each tick-related measure.
     */

    tickPosn = scalePtr->fromValue / tickResolution;
    firstTickError = tickPosn - ScaleRound(tickPosn);

    tickPosn = scalePtr->tickInterval / tickResolution;
    intervalError = tickPosn - ScaleRound(tickPosn);

    tickCount = (int) ((scalePtr->toValue - scalePtr->fromValue) /
	    scalePtr->tickInterval);	/* not including first */
    lastTickError = ScaleMin(0.5,
	    fabs(firstTickError + tickCount * intervalError));

    /*
     * Compute the maximum cumulative rounding error.
     */

    return ScaleMax(fabs(firstTickError), lastTickError) * tickResolution;
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeFormat --
 *
 *	This procedure is invoked to recompute the "valueFormat" or
 *	"tickFormat" field of a scale's widget record, which determines how
 *	the value of the scale or one of its ticks is converted to a string.
 *
 * Results:
 *	None.
 *

 * Side effects: The valueFormat or tickFormat field of scalePtr is modified.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeFormat(
    TkScale *scalePtr,		/* Information about scale widget. */
    int forTicks)               /* Do for ticks rather than value */
{
    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.
     */

    maxValue = fabs(scalePtr->fromValue);
    x = fabs(scalePtr->toValue);
    if (x > maxValue) {
	maxValue = x;
    }
    if (maxValue == 0) {
	maxValue = 1;
    }
    mostSigDigit = ScaleDigit(maxValue);

    if (forTicks) {
	/*
	 * Display only enough digits to ensure adjacent ticks have different
	 * values.
	 */

	if (scalePtr->tickInterval != 0) {
	    leastSigDigit = ScaleDigit(scalePtr->tickInterval);

	    /*
	     * Now add more digits until max error is less than
	     * TICK_VALUES_DISPLAY_ACCURACY intervals
	     */

	    while (MaxTickRoundingError(scalePtr, pow(10, leastSigDigit))
		    > fabs(TICK_VALUES_DISPLAY_ACCURACY * scalePtr->tickInterval)) {
		--leastSigDigit;
	    }
	    numDigits = 1 + mostSigDigit - leastSigDigit;
	} else {
	    numDigits = 1;
	}
    } else {
	/*
	 * 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.
	 */

	numDigits = scalePtr->digits;
	if (numDigits > TCL_MAX_PREC) {
	    numDigits = 0;
	}
	if (numDigits <= 0) {
	    if (scalePtr->resolution > 0) {
		/*
		 * A resolution was specified for the scale, so just use it.
		 */

		leastSigDigit = ScaleDigit(scalePtr->resolution);
	    } else {
		/*
		 * 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);
		if (scalePtr->length > 0) {
		    x /= scalePtr->length;
		}
		if (x > 0) {
		    leastSigDigit = ScaleDigit(x);
		} else {
		    leastSigDigit = 0;
		}
	    }
	    numDigits = mostSigDigit - leastSigDigit + 1;
	    if (numDigits < 1) {
		numDigits = 1;
	    }
	}
    }

    /*
     * Compute the number of characters required using "e" format and "f"
     * format, and then choose whichever one takes fewer characters.
     */








|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|




>
|






|
<


















|

<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
<







752
753
754
755
756
757
758
759
760
761
762


















































763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800

801






















802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840

841
842
843
844
845
846
847
     * know how much space is needed now.
     */

    ComputeScaleGeometry(scalePtr);

    TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
}

/*
 *----------------------------------------------------------------------
 *


















































 * 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.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The format field of scalePtr is modified.
 *
 *----------------------------------------------------------------------
 */

static void
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.
     */

    maxValue = fabs(scalePtr->fromValue);
    x = fabs(scalePtr->toValue);
    if (x > maxValue) {
	maxValue = x;
    }
    if (maxValue == 0) {
	maxValue = 1;
    }
    mostSigDigit = (int) floor(log10(maxValue));


    /*






















     * 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.

     */

    numDigits = scalePtr->digits;
    if (numDigits > TCL_MAX_PREC) {
	numDigits = 0;
    }
    if (numDigits <= 0) {
	if (scalePtr->resolution > 0) {
	    /*
	     * A resolution was specified for the scale, so just use it.
	     */

	    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.
	     */

	    x = fabs(scalePtr->fromValue - scalePtr->toValue);
	    if (scalePtr->length > 0) {
		x /= scalePtr->length;
	    }
	    if (x > 0){
		leastSigDigit = (int) floor(log10(x));
	    } else {
		leastSigDigit = 0;
	    }
	}
	numDigits = mostSigDigit - leastSigDigit + 1;
	if (numDigits < 1) {
	    numDigits = 1;

	}
    }

    /*
     * Compute the number of characters required using "e" format and "f"
     * format, and then choose whichever one takes fewer characters.
     */
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
    fDigits = (mostSigDigit >= 0) ? mostSigDigit + afterDecimal : afterDecimal;
    if (afterDecimal > 0) {
	fDigits++;			/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;			/* Zero to left of decimal point. */
    }

    if (forTicks) {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->tickFormat, "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->tickFormat, "%%.%de", numDigits - 1);
	}
    } else {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->valueFormat, "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->valueFormat, "%%.%de", numDigits - 1);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeScaleGeometry --







<
<
|
|
|
|
<
<
<
<
<
<
<







857
858
859
860
861
862
863


864
865
866
867







868
869
870
871
872
873
874
    fDigits = (mostSigDigit >= 0) ? mostSigDigit + afterDecimal : afterDecimal;
    if (afterDecimal > 0) {
	fDigits++;			/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;			/* Zero to left of decimal point. */
    }


    if (fDigits <= eDigits) {
	sprintf(scalePtr->format, "%%.%df", afterDecimal);
    } else {
	sprintf(scalePtr->format, "%%.%de", numDigits-1);







    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeScaleGeometry --
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
 *	gets told about the window's preferred size.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeScaleGeometry(
    TkScale *scalePtr)	/* Information about widget. */
{
    char valueString[TCL_DOUBLE_SPACE];
    int tmp, valuePixels, tickPixels, x, y, extraSpace;
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    scalePtr->fontHeight = fm.linespace + SPACING;

    /*
     * Horizontal scales are simpler than vertical ones because all sizes are







|


|







885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
 *	gets told about the window's preferred size.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeScaleGeometry(
    register TkScale *scalePtr)	/* Information about widget. */
{
    char valueString[TCL_DOUBLE_SPACE];
    int tmp, valuePixels, x, y, extraSpace;
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    scalePtr->fontHeight = fm.linespace + SPACING;

    /*
     * Horizontal scales are simpler than vertical ones because all sizes are
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123

    /*
     * 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.
     */

    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
            scalePtr->fromValue) < 0) {
        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);

    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
            scalePtr->toValue) < 0) {
        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
    if (valuePixels < tmp) {
	valuePixels = tmp;
    }

    /*
     * Now do the same thing for the tick values
     */

    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->tickFormat,
            scalePtr->fromValue) < 0) {
        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    tickPixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);

    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->tickFormat,
            scalePtr->toValue) < 0) {
        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
    if (tickPixels < tmp) {
	tickPixels = tmp;
    }

    /*
     * Assign x-locations to the elements of the scale, working from left to
     * right.
     */

    x = scalePtr->inset;
    if ((scalePtr->tickInterval != 0) && (scalePtr->showValue)) {
	scalePtr->vertTickRightX = x + SPACING + tickPixels;
	scalePtr->vertValueRightX = scalePtr->vertTickRightX + valuePixels
		+ fm.ascent/2;
	x = scalePtr->vertValueRightX + SPACING;
    } else if (scalePtr->tickInterval != 0) {
	scalePtr->vertTickRightX = x + SPACING + tickPixels;
	scalePtr->vertValueRightX = scalePtr->vertTickRightX;
	x = scalePtr->vertTickRightX + SPACING;
    } else if (scalePtr->showValue) {
	scalePtr->vertTickRightX = x;
	scalePtr->vertValueRightX = x + SPACING + valuePixels;
	x = scalePtr->vertValueRightX + SPACING;
    } else {







<
|
<
<


<
|
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|




|







934
935
936
937
938
939
940

941


942
943

944


945
946
947
948
949



















950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969

    /*
     * 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);


    valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);


    sprintf(valueString, scalePtr->format, scalePtr->toValue);


    tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
    if (valuePixels < tmp) {
	valuePixels = tmp;
    }




















    /*
     * Assign x-locations to the elements of the scale, working from left to
     * right.
     */

    x = scalePtr->inset;
    if ((scalePtr->tickInterval != 0) && (scalePtr->showValue)) {
	scalePtr->vertTickRightX = x + SPACING + valuePixels;
	scalePtr->vertValueRightX = scalePtr->vertTickRightX + valuePixels
		+ fm.ascent/2;
	x = scalePtr->vertValueRightX + SPACING;
    } else if (scalePtr->tickInterval != 0) {
	scalePtr->vertTickRightX = x + SPACING + valuePixels;
	scalePtr->vertValueRightX = scalePtr->vertTickRightX;
	x = scalePtr->vertTickRightX + SPACING;
    } else if (scalePtr->showValue) {
	scalePtr->vertTickRightX = x;
	scalePtr->vertValueRightX = x + SPACING + valuePixels;
	x = scalePtr->vertValueRightX + SPACING;
    } else {
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
 */

static void
ScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScale *scalePtr = (TkScale *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == DestroyNotify) {
	DestroyScale(clientData);
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeScaleGeometry(scalePtr);
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scalePtr->flags |= GOT_FOCUS;
	    if (scalePtr->highlightWidth > 0) {







|




|







1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
 */

static void
ScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScale *scalePtr = (TkScale *) clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == DestroyNotify) {
	DestroyScale((char *) clientData);
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeScaleGeometry(scalePtr);
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scalePtr->flags |= GOT_FOCUS;
	    if (scalePtr->highlightWidth > 0) {
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
 *----------------------------------------------------------------------
 */

static void
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.







|







1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
 *----------------------------------------------------------------------
 */

static void
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.
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
 *	be redrawn.
 *
 *--------------------------------------------------------------
 */

void
TkEventuallyRedrawScale(
    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)) {
	return;
    }
    if (!(scalePtr->flags & REDRAW_PENDING)) {
	scalePtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(TkpDisplayScale, scalePtr);
    }
    scalePtr->flags |= what;
}

/*
 *--------------------------------------------------------------
 *
 * TkRoundValueToResolution, TkRoundIntervalToResolution --
 *
 *	Round a given floating-point value to the nearest multiple of the
 *	scale's resolution.
 *	TkRoundValueToResolution rounds an absolute value based on the from
 *	value as a reference.
 *	TkRoundIntervalToResolution rounds a relative value without
 *	reference, i.e.	it rounds an interval.
 *
 * Results:
 *	The return value is the rounded result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkRoundValueToResolution(
    TkScale *scalePtr,		/* Information about scale widget. */
    double value)		/* Value to round. */
{
    return TkRoundIntervalToResolution(scalePtr, value - scalePtr->fromValue)
            + scalePtr->fromValue;
}

double
TkRoundIntervalToResolution(
    TkScale *scalePtr,		/* Information about scale widget. */
    double value)		/* Value to round. */
{
    double rem, rounded, tick;

    if (scalePtr->resolution <= 0) {
	return value;
    }
    tick = floor(value/scalePtr->resolution);
    rounded = scalePtr->resolution * tick;
    rem = value - rounded;
    if (rem < 0) {
        if (rem <= -scalePtr->resolution/2) {
            rounded = (tick - 1.0) * scalePtr->resolution;
        }
    } else {
        if (rem >= scalePtr->resolution/2) {
            rounded = (tick + 1.0) * scalePtr->resolution;
        }
    }
    return rounded;
}

/*
 *----------------------------------------------------------------------
 *







|









|







|



<
<
<
<











|
<
<
<
<
<
<
<
<
<












|
|
|

|
|
|







1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117




1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129









1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
 *	be redrawn.
 *
 *--------------------------------------------------------------
 */

void
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)) {
	return;
    }
    if (!(scalePtr->flags & REDRAW_PENDING)) {
	scalePtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(TkpDisplayScale, (ClientData) scalePtr);
    }
    scalePtr->flags |= what;
}

/*
 *--------------------------------------------------------------
 *
 * TkRoundToResolution --
 *
 *	Round a given floating-point value to the nearest multiple of the
 *	scale's resolution.




 *
 * Results:
 *	The return value is the rounded result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkRoundToResolution(









    TkScale *scalePtr,		/* Information about scale widget. */
    double value)		/* Value to round. */
{
    double rem, rounded, tick;

    if (scalePtr->resolution <= 0) {
	return value;
    }
    tick = floor(value/scalePtr->resolution);
    rounded = scalePtr->resolution * tick;
    rem = value - rounded;
    if (rem < 0) {
	if (rem <= -scalePtr->resolution/2) {
	    rounded = (tick - 1.0) * scalePtr->resolution;
	}
    } else {
	if (rem >= scalePtr->resolution/2) {
	    rounded = (tick + 1.0) * scalePtr->resolution;
	}
    }
    return rounded;
}

/*
 *----------------------------------------------------------------------
 *
1332
1333
1334
1335
1336
1337
1338

1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
 *	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.
 *
 *----------------------------------------------------------------------
 */


static char *
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. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    const char *resultStr;
    double value;
    Tcl_Obj *valuePtr;
    int result;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && scalePtr->varNamePtr) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        Tcl_GetString(scalePtr->varNamePtr),
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ScaleVarProc, probe);
                if (probe == (ClientData)scalePtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * varNamePtr, which means it is not unset and not
                 * the cause of this unset trace. Instead some outdated
                 * former variable must be, and we should ignore it.
                 */
                return NULL;
            }
	    Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
		    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ScaleVarProc, clientData);
	    scalePtr->flags |= NEVER_SET;
	    TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
	}
	return NULL;
    }








>








|
|



<
<







<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185


1186
1187
1188
1189
1190
1191
1192


1193


1194
1195
















1196
1197
1198
1199
1200
1201
1202
 *	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 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;
    double value;
    Tcl_Obj *valuePtr;
    int result;



    /*
     * 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_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
















		    ScaleVarProc, clientData);
	    scalePtr->flags |= NEVER_SET;
	    TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
	}
	return NULL;
    }

1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
    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";
	ScaleSetVariable(scalePtr);
    } else {
	scalePtr->value = TkRoundValueToResolution(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.
	 */

	TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
    }
    TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);

    return (char *) resultStr;
}

/*
 *--------------------------------------------------------------
 *
 * TkScaleSetValue --
 *







|












|







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
    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";
	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.
	 */

	TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
    }
    TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);

    return resultStr;
}

/*
 *--------------------------------------------------------------
 *
 * TkScaleSetValue --
 *
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
 *	may also be invoked. The scale's slider is redrawn.
 *
 *--------------------------------------------------------------
 */

void
TkScaleSetValue(
    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 = TkRoundValueToResolution(scalePtr, value);
    if ((value < scalePtr->fromValue)
	    ^ (scalePtr->toValue < scalePtr->fromValue)) {
	value = scalePtr->fromValue;
    }
    if ((value > scalePtr->toValue)
	    ^ (scalePtr->toValue < scalePtr->fromValue)) {
	value = scalePtr->toValue;
    }
    if (scalePtr->flags & NEVER_SET) {
	scalePtr->flags &= ~NEVER_SET;
    } else if (scalePtr->value == value) {
	return;
    }
    scalePtr->value = value;

    /*
     * Schedule command callback invocation only if there is such a command
     * already registered, otherwise the callback would trigger later when
     * configuring the widget -command option even if the value did not change.
     */

    if ((invokeCommand) && (scalePtr->command != NULL)) {
	scalePtr->flags |= INVOKE_COMMAND;
    }
    TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);

    if (setVar && scalePtr->varNamePtr) {
	ScaleSetVariable(scalePtr);
    }







|







|














<
<
<
<
<
<
<
|







1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278







1279
1280
1281
1282
1283
1284
1285
1286
 *	may also be invoked. The scale's slider is redrawn.
 *
 *--------------------------------------------------------------
 */

void
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)
	    ^ (scalePtr->toValue < scalePtr->fromValue)) {
	value = scalePtr->fromValue;
    }
    if ((value > scalePtr->toValue)
	    ^ (scalePtr->toValue < scalePtr->fromValue)) {
	value = scalePtr->toValue;
    }
    if (scalePtr->flags & NEVER_SET) {
	scalePtr->flags &= ~NEVER_SET;
    } else if (scalePtr->value == value) {
	return;
    }
    scalePtr->value = value;







    if (invokeCommand) {
	scalePtr->flags |= INVOKE_COMMAND;
    }
    TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);

    if (setVar && scalePtr->varNamePtr) {
	ScaleSetVariable(scalePtr);
    }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
 *	Other write traces on the variable will trigger.
 *
 *--------------------------------------------------------------
 */

static void
ScaleSetVariable(
    TkScale *scalePtr)	/* Info about widget. */
{
    if (scalePtr->varNamePtr != NULL) {
	char string[TCL_DOUBLE_SPACE];

        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	scalePtr->flags |= SETTING_VAR;
	Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
		Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
	scalePtr->flags &= ~SETTING_VAR;
    }
}








|




<
|
<
<







1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311

1312


1313
1314
1315
1316
1317
1318
1319
 *	Other write traces on the variable will trigger.
 *
 *--------------------------------------------------------------
 */

static void
ScaleSetVariable(
    register TkScale *scalePtr)	/* Info about widget. */
{
    if (scalePtr->varNamePtr != NULL) {
	char string[TCL_DOUBLE_SPACE];


	sprintf(string, scalePtr->format, scalePtr->value);


	scalePtr->flags |= SETTING_VAR;
	Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
		Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
	scalePtr->flags &= ~SETTING_VAR;
    }
}

1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
 *	None.
 *
 *----------------------------------------------------------------------
 */

double
TkScalePixelToValue(
    TkScale *scalePtr,	/* Information about widget. */
    int x, int y)		/* Coordinates of point within window. */
{
    double value, pixelRange;

    if (scalePtr->orient == ORIENT_VERTICAL) {
	pixelRange = Tk_Height(scalePtr->tkwin) - scalePtr->sliderLength
		- 2*scalePtr->inset - 2*scalePtr->borderWidth;







|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
 *	None.
 *
 *----------------------------------------------------------------------
 */

double
TkScalePixelToValue(
    register TkScale *scalePtr,	/* Information about widget. */
    int x, int y)		/* Coordinates of point within window. */
{
    double value, pixelRange;

    if (scalePtr->orient == ORIENT_VERTICAL) {
	pixelRange = Tk_Height(scalePtr->tkwin) - scalePtr->sliderLength
		- 2*scalePtr->inset - 2*scalePtr->borderWidth;
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
	value = 0;
    }
    if (value > 1) {
	value = 1;
    }
    value = scalePtr->fromValue +
		value * (scalePtr->toValue - scalePtr->fromValue);
    return TkRoundValueToResolution(scalePtr, value);
}

/*
 *----------------------------------------------------------------------
 *
 * TkScaleValueToPixel --
 *







|







1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
	value = 0;
    }
    if (value > 1) {
	value = 1;
    }
    value = scalePtr->fromValue +
		value * (scalePtr->toValue - scalePtr->fromValue);
    return TkRoundToResolution(scalePtr, value);
}

/*
 *----------------------------------------------------------------------
 *
 * TkScaleValueToPixel --
 *
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkScaleValueToPixel(
    TkScale *scalePtr,	/* Information about widget. */
    double value)		/* Reading of the widget. */
{
    int y, pixelRange;
    double valueRange;

    valueRange = scalePtr->toValue - scalePtr->fromValue;
    pixelRange = ((scalePtr->orient == ORIENT_VERTICAL)
	    ? Tk_Height(scalePtr->tkwin) : Tk_Width(scalePtr->tkwin))
	- scalePtr->sliderLength - 2*scalePtr->inset - 2*scalePtr->borderWidth;
    if (valueRange == 0) {
	y = 0;
    } else {
	y = ScaleRound((value - scalePtr->fromValue) * pixelRange
		/ valueRange);
	if (y < 0) {
	    y = 0;
	} else if (y > pixelRange) {
	    y = pixelRange;
	}
    }
    y += scalePtr->sliderLength/2 + scalePtr->inset + scalePtr->borderWidth;







|












|
|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkScaleValueToPixel(
    register TkScale *scalePtr,	/* Information about widget. */
    double value)		/* Reading of the widget. */
{
    int y, pixelRange;
    double valueRange;

    valueRange = scalePtr->toValue - scalePtr->fromValue;
    pixelRange = ((scalePtr->orient == ORIENT_VERTICAL)
	    ? Tk_Height(scalePtr->tkwin) : Tk_Width(scalePtr->tkwin))
	- scalePtr->sliderLength - 2*scalePtr->inset - 2*scalePtr->borderWidth;
    if (valueRange == 0) {
	y = 0;
    } else {
	y = (int) ((value - scalePtr->fromValue) * pixelRange
		/ valueRange + 0.5);
	if (y < 0) {
	    y = 0;
	} else if (y > pixelRange) {
	    y = pixelRange;
	}
    }
    y += scalePtr->sliderLength/2 + scalePtr->inset + scalePtr->borderWidth;

Changes to generic/tkScale.h.

14
15
16
17
18
19
20





21
22
23
24
25
26
27
#ifndef _TKSCALE
#define _TKSCALE

#ifndef _TKINT
#include "tkInt.h"
#endif






/*
 * Legal values for the "orient" field of TkScale records.
 */

enum orient {
    ORIENT_HORIZONTAL, ORIENT_VERTICAL
};







>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef _TKSCALE
#define _TKSCALE

#ifndef _TKINT
#include "tkInt.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Legal values for the "orient" field of TkScale records.
 */

enum orient {
    ORIENT_HORIZONTAL, ORIENT_VERTICAL
};
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
				 * 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 valueFormat[16];	/* Sprintf conversion specifier computed from
				 * digits and other information. */
    char tickFormat[16];	/* Sprintf conversion specifier computed from
				 * tick interval. */
    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 repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * scale; NULL means don't display a label. */
    TkSizeT labelLength;	/* Number of non-NULL chars. in label. */
    enum state state;		/* Values are active, normal, or disabled.
				 * Value of scale cannot be changed when
				 * disabled. */

    /*
     * Information used when displaying widget:
     */







|

<
<










|







74
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
				 * 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[16];		/* 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). */
    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 repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * 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
				 * disabled. */

    /*
     * Information used when displaying widget:
     */
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242



243
/*
 * Space to leave between scale area and text, and between text and edge of
 * window.
 */

#define SPACING 2

/*
 * The tick values are all displayed with the same number of decimal places.
 * This number of decimal places is such that the displayed values are all
 * accurate to within the following proportion of a tick interval.
 */

#define TICK_VALUES_DISPLAY_ACCURACY 0.2

/*
 * Declaration of procedures used in the implementation of the scale widget.
 */

MODULE_SCOPE void	TkEventuallyRedrawScale(TkScale *scalePtr, int what);
MODULE_SCOPE double	TkRoundValueToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE double	TkRoundIntervalToResolution(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);




#endif /* _TKSCALE */







<
<
<
<
<
<
<
<





|
<









>
>
>

215
216
217
218
219
220
221








222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
/*
 * Space to leave between scale area and text, and between text and edge of
 * window.
 */

#define SPACING 2









/*
 * Declaration of procedures used in the implementation of the scale widget.
 */

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

#endif /* _TKSCALE */

Changes to generic/tkScrollbar.c.

16
17
18
19
20
21
22
23

24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include "tkScrollbar.h"
#include "default.h"

/*
 * Custom option for handling "-orient"
 */

static const Tk_CustomOption orientOption = {

    TkOrientParseProc, TkOrientPrintProc, NULL

};

/* non-const space for "-width" default value for scrollbars */
char tkDefScrollbarWidth[TCL_INTEGER_SPACE] = DEF_SCROLLBAR_WIDTH;

/*
 * Information used for argv parsing.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_COLOR, offsetof(TkScrollbar, activeBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_MONO, offsetof(TkScrollbar, activeBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_SCROLLBAR_ACTIVE_RELIEF, offsetof(TkScrollbar, activeRelief), 0, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_COLOR, offsetof(TkScrollbar, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_MONO, offsetof(TkScrollbar, bgBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_SCROLLBAR_BORDER_WIDTH, offsetof(TkScrollbar, borderWidth), 0, NULL},
    {TK_CONFIG_STRING, "-command", "command", "Command",
	DEF_SCROLLBAR_COMMAND, offsetof(TkScrollbar, command),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_SCROLLBAR_CURSOR, offsetof(TkScrollbar, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth",
	"BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH,
	offsetof(TkScrollbar, elementBorderWidth), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
	offsetof(TkScrollbar, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCROLLBAR_HIGHLIGHT,
	offsetof(TkScrollbar, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, offsetof(TkScrollbar, highlightWidth), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
	DEF_SCROLLBAR_JUMP, offsetof(TkScrollbar, jump), 0, NULL},
    {TK_CONFIG_CUSTOM, "-orient", "orient", "Orient",
	DEF_SCROLLBAR_ORIENT, offsetof(TkScrollbar, vertical), 0,
	&orientOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_SCROLLBAR_RELIEF, offsetof(TkScrollbar, relief), 0, NULL},
    {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCROLLBAR_REPEAT_DELAY, offsetof(TkScrollbar, repeatDelay), 0, NULL},
    {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCROLLBAR_REPEAT_INTERVAL, offsetof(TkScrollbar, repeatInterval), 0, NULL},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCROLLBAR_TAKE_FOCUS, offsetof(TkScrollbar, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_COLOR, offsetof(TkScrollbar, troughColorPtr),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_MONO, offsetof(TkScrollbar, troughColorPtr),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	tkDefScrollbarWidth, offsetof(TkScrollbar, width), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureScrollbar(Tcl_Interp *interp,
			    TkScrollbar *scrollPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static void		ScrollbarCmdDeletedProc(ClientData clientData);
static int		ScrollbarWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *, int objc, Tcl_Obj *const objv[]);

/*
 *--------------------------------------------------------------
 *
 * Tk_ScrollbarObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScrollbarObjCmd(
    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;
    TkScrollbar *scrollPtr;
    Tk_Window newWin;

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), NULL);
    if (newWin == NULL) {
	return TCL_ERROR;
    }

    Tk_SetClass(newWin, "Scrollbar");
    scrollPtr = TkpCreateScrollbar(newWin);

    Tk_SetClassProcs(newWin, &tkpScrollbarProcs, scrollPtr);

    /*
     * Initialize fields that won't be initialized by ConfigureScrollbar, or
     * which ConfigureScrollbar expects to have reasonable values (e.g.
     * resource pointers).
     */

    scrollPtr->tkwin = newWin;
    scrollPtr->display = Tk_Display(newWin);
    scrollPtr->interp = interp;
    scrollPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetObjCmd,
	    scrollPtr, ScrollbarCmdDeletedProc);
    scrollPtr->vertical = 0;
    scrollPtr->width = 0;
    scrollPtr->command = NULL;
    scrollPtr->commandSize = 0;
    scrollPtr->repeatDelay = 0;
    scrollPtr->repeatInterval = 0;
    scrollPtr->borderWidth = 0;







|
>
|
>









|

|
|

|
|

|

|
|

|
|
|
|

|

|
|

|


|


|


|


|

|

|


|

|

|

|
|

|
|

|
|

|
|







|
|

|
|




|














|


|
|

|
|


|
>
|



|







|










|
|
|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "tkScrollbar.h"
#include "default.h"

/*
 * Custom option for handling "-orient"
 */

static Tk_CustomOption orientOption = {
    (Tk_OptionParseProc *) TkOrientParseProc,
    TkOrientPrintProc,
    (ClientData) NULL
};

/* non-const space for "-width" default value for scrollbars */
char tkDefScrollbarWidth[TCL_INTEGER_SPACE] = DEF_SCROLLBAR_WIDTH;

/*
 * Information used for argv parsing.
 */

static Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(TkScrollbar, activeBorder),
	TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(TkScrollbar, activeBorder),
	TK_CONFIG_MONO_ONLY},
    {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(TkScrollbar, activeRelief), 0},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_COLOR, Tk_Offset(TkScrollbar, bgBorder),
	TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_MONO, Tk_Offset(TkScrollbar, bgBorder),
	TK_CONFIG_MONO_ONLY},
    {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",
	DEF_SCROLLBAR_COMMAND, Tk_Offset(TkScrollbar, command),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_SCROLLBAR_CURSOR, Tk_Offset(TkScrollbar, cursor), TK_CONFIG_NULL_OK},
    {TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth",
	"BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH,
	Tk_Offset(TkScrollbar, elementBorderWidth), 0},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
	Tk_Offset(TkScrollbar, highlightBgColorPtr), 0},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCROLLBAR_HIGHLIGHT,
	Tk_Offset(TkScrollbar, highlightColorPtr), 0},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0},
    {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
	DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0},
    {TK_CONFIG_CUSTOM, "-orient", "orient", "Orient",
	DEF_SCROLLBAR_ORIENT, Tk_Offset(TkScrollbar, vertical), 0,
	&orientOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_SCROLLBAR_RELIEF, Tk_Offset(TkScrollbar, relief), 0},
    {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(TkScrollbar, repeatDelay), 0},
    {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCROLLBAR_REPEAT_INTERVAL, Tk_Offset(TkScrollbar, repeatInterval), 0},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCROLLBAR_TAKE_FOCUS, Tk_Offset(TkScrollbar, takeFocus),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(TkScrollbar, troughColorPtr),
	TK_CONFIG_COLOR_ONLY},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(TkScrollbar, troughColorPtr),
	TK_CONFIG_MONO_ONLY},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	tkDefScrollbarWidth, Tk_Offset(TkScrollbar, width), 0},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

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 function is invoked to process the "scrollbar" Tcl command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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 newWin;

    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " pathName ?options?\"", NULL);
	return TCL_ERROR;
    }

    newWin = Tk_CreateWindowFromPath(interp, tkwin, argv[1], NULL);
    if (newWin == NULL) {
	return TCL_ERROR;
    }

    Tk_SetClass(newWin, "Scrollbar");
    scrollPtr = TkpCreateScrollbar(newWin);

    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).
     */

    scrollPtr->tkwin = newWin;
    scrollPtr->display = Tk_Display(newWin);
    scrollPtr->interp = interp;
    scrollPtr->widgetCmd = Tcl_CreateCommand(interp,
	    Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetCmd,
	    (ClientData) scrollPtr, ScrollbarCmdDeletedProc);
    scrollPtr->vertical = 0;
    scrollPtr->width = 0;
    scrollPtr->command = NULL;
    scrollPtr->commandSize = 0;
    scrollPtr->repeatDelay = 0;
    scrollPtr->repeatInterval = 0;
    scrollPtr->borderWidth = 0;
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256



257
258
259
260
261
262
263


264


265


266
267
268
269
270

271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291

292

293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312

313
314

315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343

344
345

346
347
348
349
350
351
352
353
354
355
356
357
    scrollPtr->inset = 0;
    scrollPtr->elementBorderWidth = -1;
    scrollPtr->arrowLength = 0;
    scrollPtr->sliderFirst = 0;
    scrollPtr->sliderLast = 0;
    scrollPtr->activeField = 0;
    scrollPtr->activeRelief = TK_RELIEF_RAISED;
#ifndef TK_NO_DEPRECATED
    scrollPtr->totalUnits = 0;
    scrollPtr->windowUnits = 0;
    scrollPtr->firstUnit = 0;
    scrollPtr->lastUnit = 0;
#endif /* TK_NO_DEPRECATED */
    scrollPtr->firstFraction = 0.0;
    scrollPtr->lastFraction = 0.0;
    scrollPtr->cursor = NULL;
    scrollPtr->takeFocus = NULL;
    scrollPtr->flags = 0;

    if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(scrollPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(scrollPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarWidgetObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarWidgetObjCmd(
    ClientData clientData,	/* Information about scrollbar widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    int result = TCL_OK, cmdIndex, length;
    TkSizeT len;
    static const char *const commandNames[] = {
        "activate", "cget", "configure", "delta", "fraction",
        "get", "identify", "set", NULL
    };
    enum command {
        COMMAND_ACTIVATE, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELTA,
        COMMAND_FRACTION, COMMAND_GET, COMMAND_IDENTIFY, COMMAND_SET
    };

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    /*
     * 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) {
	return result;
    }
    Tcl_Preserve(scrollPtr);
    switch (cmdIndex) {
    case COMMAND_ACTIVATE: {



	int oldActiveField, c;

	if (objc == 2) {
	    const char *zone = "";

	    switch (scrollPtr->activeField) {
	    case TOP_ARROW:	zone = "arrow1"; break;


	    case SLIDER:	zone = "slider"; break;


	    case BOTTOM_ARROW:	zone = "arrow2"; break;


	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	    goto done;
	}
	if (objc != 3) {

		Tcl_WrongNumArgs(interp, 1, objv, "activate element");
	    goto error;
	}
	c = TkGetStringFromObj(objv[2], &len)[0];

	oldActiveField = scrollPtr->activeField;
	if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) {
	    scrollPtr->activeField = TOP_ARROW;
	} else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) {
	    scrollPtr->activeField = BOTTOM_ARROW;
	} else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", len) == 0)) {
	    scrollPtr->activeField = SLIDER;
	} else {
	    scrollPtr->activeField = OUTSIDE;
	}
	if (oldActiveField != scrollPtr->activeField) {
	    TkScrollbarEventuallyRedraw(scrollPtr);
	}
	break;
    }
    case COMMAND_CGET: {

	if (objc != 3) {

		Tcl_WrongNumArgs(interp, 1, objv, "cget option");

	    goto error;
	}
	result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
		configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
	break;
    }
    case COMMAND_CONFIGURE: {

	if (objc == 2) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, (char *) scrollPtr, NULL, 0);
	} else if (objc == 3) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
	} else {
	    result = ConfigureScrollbar(interp, scrollPtr, objc-2,
		    objv+2, TK_CONFIG_ARGV_ONLY);
	}
	break;
    }
    case COMMAND_DELTA: {

	int xDelta, yDelta, pixels;
	double fraction;


	if (objc != 4) {

		Tcl_WrongNumArgs(interp, 1, objv, "delta xDelta yDelta");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &xDelta) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &yDelta) != TCL_OK)) {
	    goto error;
	}
	if (scrollPtr->vertical) {
	    pixels = yDelta;
	    length = Tk_Height(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	} else {
	    pixels = xDelta;
	    length = Tk_Width(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	}
	if (length == 0) {
	    fraction = 0.0;
	} else {
	    fraction = ((double) pixels / (double) length);
	}

	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
	break;
    }
    case COMMAND_FRACTION: {
	int x, y, pos;
	double fraction;


	if (objc != 4) {

		Tcl_WrongNumArgs(interp, 1, objv, "fraction x y");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	if (scrollPtr->vertical) {
	    pos = y - (scrollPtr->arrowLength + scrollPtr->inset);
	    length = Tk_Height(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	} else {







<




<






|




|






|















|


|
|

|
|
|
<
<
<
<
|
<
<
<

|
>
|


<
<
<
<
<
<
<
<
<
<
|
<
<
>
>
>
|
<
|
<
<

|
>
>
|
>
>
|
>
>

<


|
>
|


|
>

|

|

|







|
<
<
>
|
>
|
>



|
|
<
<
>
|


|

|

|
|

<
<
<
>
|

>

|
>
|


|
|
















>
|
<
|
<
|

>

|
>
|


|
|







178
179
180
181
182
183
184

185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231




232



233
234
235
236
237
238










239


240
241
242
243

244


245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286
287
288


289
290
291
292
293
294
295
296
297
298
299



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    scrollPtr->inset = 0;
    scrollPtr->elementBorderWidth = -1;
    scrollPtr->arrowLength = 0;
    scrollPtr->sliderFirst = 0;
    scrollPtr->sliderLast = 0;
    scrollPtr->activeField = 0;
    scrollPtr->activeRelief = TK_RELIEF_RAISED;

    scrollPtr->totalUnits = 0;
    scrollPtr->windowUnits = 0;
    scrollPtr->firstUnit = 0;
    scrollPtr->lastUnit = 0;

    scrollPtr->firstFraction = 0.0;
    scrollPtr->lastFraction = 0.0;
    scrollPtr->cursor = NULL;
    scrollPtr->takeFocus = NULL;
    scrollPtr->flags = 0;

    if (ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(scrollPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetResult(interp, Tk_PathName(scrollPtr->tkwin), TCL_STATIC);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarWidgetCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
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;
    size_t length;




    int c;




    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option ?arg arg ...?\"", NULL);
	return TCL_ERROR;
    }










    Tcl_Preserve((ClientData) scrollPtr);


    c = argv[1][0];
    length = strlen(argv[1]);
    if ((c == 'a') && (strncmp(argv[1], "activate", length) == 0)) {
	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;
	    }

	    goto done;
	}
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " activate element\"", NULL);
	    goto error;
	}
	c = argv[2][0];
	length = strlen(argv[2]);
	oldActiveField = scrollPtr->activeField;
	if ((c == 'a') && (strcmp(argv[2], "arrow1") == 0)) {
	    scrollPtr->activeField = TOP_ARROW;
	} else if ((c == 'a') && (strcmp(argv[2], "arrow2") == 0)) {
	    scrollPtr->activeField = BOTTOM_ARROW;
	} else if ((c == 's') && (strncmp(argv[2], "slider", length) == 0)) {
	    scrollPtr->activeField = SLIDER;
	} else {
	    scrollPtr->activeField = OUTSIDE;
	}
	if (oldActiveField != scrollPtr->activeField) {
	    TkScrollbarEventuallyRedraw(scrollPtr);
	}
    } 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\"",
		    NULL);
	    goto error;
	}
	result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
		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,
		    configSpecs, (char *) scrollPtr, NULL, 0);
	} else if (argc == 3) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, (char *) scrollPtr, argv[2], 0);
	} else {
	    result = ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2,
		    TK_CONFIG_ARGV_ONLY);
	}



    } else if ((c == 'd') && (strncmp(argv[1], "delta", length) == 0)) {
	int xDelta, yDelta, pixels, length;
	double fraction;
	char buf[TCL_DOUBLE_SPACE];

	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " delta xDelta yDelta\"", NULL);
	    goto error;
	}
	if ((Tcl_GetInt(interp, argv[2], &xDelta) != TCL_OK)
		|| (Tcl_GetInt(interp, argv[3], &yDelta) != TCL_OK)) {
	    goto error;
	}
	if (scrollPtr->vertical) {
	    pixels = yDelta;
	    length = Tk_Height(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	} else {
	    pixels = xDelta;
	    length = Tk_Width(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	}
	if (length == 0) {
	    fraction = 0.0;
	} else {
	    fraction = ((double) pixels / (double) length);
	}
	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;
	double fraction;
	char buf[TCL_DOUBLE_SPACE];

	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " fraction x y\"", NULL);
	    goto error;
	}
	if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
		|| (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
	    goto error;
	}
	if (scrollPtr->vertical) {
	    pos = y - (scrollPtr->arrowLength + scrollPtr->inset);
	    length = Tk_Height(scrollPtr->tkwin) - 1
		    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
	} else {
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379

380
381
382
383

384
385
386
387
388
389

390
391

392
393
394
395
396
397

398
399






400
401
402
403
404
405
406
407
408
409

410


411


412


413


414
415
416
417
418


419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

486


487
488
489
490
491
492




493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
	    fraction = ((double) pos / (double) length);
	}
	if (fraction < 0) {
	    fraction = 0;
	} else if (fraction > 1.0) {
	    fraction = 1.0;
	}

	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
	break;
    }
    case COMMAND_GET: {
	Tcl_Obj *resObjs[4];

	if (objc != 2) {
		Tcl_WrongNumArgs(interp, 1, objv, "get");

	    goto error;
	}
#ifndef TK_NO_DEPRECATED
	if (scrollPtr->flags & OLD_STYLE_COMMANDS) {

	    resObjs[0] = Tcl_NewWideIntObj(scrollPtr->totalUnits);
	    resObjs[1] = Tcl_NewWideIntObj(scrollPtr->windowUnits);
	    resObjs[2] = Tcl_NewWideIntObj(scrollPtr->firstUnit);
	    resObjs[3] = Tcl_NewWideIntObj(scrollPtr->lastUnit);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs));
	    break;

	}
#endif /* TK_NO_DEPRECATED */

	resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
	resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
	break;
    }
    case COMMAND_IDENTIFY: {

	int x, y;
	const char *zone = "";







	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;
	}
	switch (TkpScrollbarPosition(scrollPtr, x, y)) {

	case TOP_ARROW:		zone = "arrow1";  break;


	case TOP_GAP:		zone = "trough1"; break;


	case SLIDER:		zone = "slider";  break;


	case BOTTOM_GAP:	zone = "trough2"; break;


	case BOTTOM_ARROW:	zone = "arrow2";  break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	break;
    }


    case COMMAND_SET: {
	if (objc == 4) {
	    double first, last;

	    if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &last) != TCL_OK) {
		goto error;
	    }
	    if (first < 0) {
		scrollPtr->firstFraction = 0;
	    } else if (first > 1.0) {
		scrollPtr->firstFraction = 1.0;
	    } else {
		scrollPtr->firstFraction = first;
	    }
	    if (last < scrollPtr->firstFraction) {
		scrollPtr->lastFraction = scrollPtr->firstFraction;
	    } else if (last > 1.0) {
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->lastFraction = last;
	    }
#ifndef TK_NO_DEPRECATED
	    scrollPtr->flags &= ~OLD_STYLE_COMMANDS;
	} else if (objc == 6) {
	    int totalUnits, windowUnits, firstUnit, lastUnit;
	    if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits < 0) {
		totalUnits = 0;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[3], &windowUnits) != TCL_OK) {
		goto error;
	    }
	    if (windowUnits < 0) {
		windowUnits = 0;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[4], &firstUnit) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[5], &lastUnit) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits > 0) {
		if (lastUnit < firstUnit) {
		    lastUnit = firstUnit;
		}
	    } else {
		firstUnit = lastUnit = 0;
	    }
	    scrollPtr->totalUnits = totalUnits;
	    scrollPtr->windowUnits = windowUnits;
	    scrollPtr->firstUnit = firstUnit;
	    scrollPtr->lastUnit = lastUnit;
	    if (scrollPtr->totalUnits == 0) {
		scrollPtr->firstFraction = 0.0;
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->firstFraction = ((double) firstUnit)/totalUnits;
		scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits;
	    }
	    scrollPtr->flags |= OLD_STYLE_COMMANDS;
#endif /* !TK_NO_DEPRECATED */
	} else {

		Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction");


	    goto error;
	}
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    }




    }

  done:
    Tcl_Release(scrollPtr);
    return result;

  error:
    Tcl_Release(scrollPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureScrollbar --







>
|
<
<
<
<
|
|
|
>


<
|
>
|
<
|
|
|
|
>
|
<
>
|
|
|
<
|
<
>
|
|
>
>
>
>
>
>
<
<
<
<
<
<
|


|
>
|
>
>
|
>
>
|
>
>
|
>
>
|
<
|
|
|
>
>
|
|


|


|
















<
|
|
<
|





|





|


|




















|
<

>
|
>
>




<
|
>
>
>
>



|



|







356
357
358
359
360
361
362
363
364




365
366
367
368
369
370

371
372
373

374
375
376
377
378
379

380
381
382
383

384

385
386
387
388
389
390
391
392
393






394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
	    fraction = ((double) pos / (double) length);
	}
	if (fraction < 0) {
	    fraction = 0;
	} else if (fraction > 1.0) {
	    fraction = 1.0;
	}
	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\"", NULL);
	    goto error;
	}

	if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
	    char first[TCL_DOUBLE_SPACE], last[TCL_DOUBLE_SPACE];


	    Tcl_PrintDouble(interp, scrollPtr->firstFraction, first);
	    Tcl_PrintDouble(interp, scrollPtr->lastFraction, last);
	    Tcl_AppendResult(interp, first, " ", last, NULL);
	} else {
	    char buf[TCL_INTEGER_SPACE * 4];


	    sprintf(buf, "%d %d %d %d", scrollPtr->totalUnits,
		    scrollPtr->windowUnits, scrollPtr->firstUnit,
		    scrollPtr->lastUnit);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);

	}

    } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) {
	int x, y, thing;

	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " identify x y\"", NULL);
	    goto error;
	}
	if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)






		|| (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
	    goto error;
	}
	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;
	}
    } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) {
	int totalUnits, windowUnits, firstUnit, lastUnit;

	if (argc == 4) {
	    double first, last;

	    if (Tcl_GetDouble(interp, argv[2], &first) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_GetDouble(interp, argv[3], &last) != TCL_OK) {
		goto error;
	    }
	    if (first < 0) {
		scrollPtr->firstFraction = 0;
	    } else if (first > 1.0) {
		scrollPtr->firstFraction = 1.0;
	    } else {
		scrollPtr->firstFraction = first;
	    }
	    if (last < scrollPtr->firstFraction) {
		scrollPtr->lastFraction = scrollPtr->firstFraction;
	    } else if (last > 1.0) {
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->lastFraction = last;
	    }

	    scrollPtr->flags |= NEW_STYLE_COMMANDS;
	} else if (argc == 6) {

	    if (Tcl_GetInt(interp, argv[2], &totalUnits) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits < 0) {
		totalUnits = 0;
	    }
	    if (Tcl_GetInt(interp, argv[3], &windowUnits) != TCL_OK) {
		goto error;
	    }
	    if (windowUnits < 0) {
		windowUnits = 0;
	    }
	    if (Tcl_GetInt(interp, argv[4], &firstUnit) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_GetInt(interp, argv[5], &lastUnit) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits > 0) {
		if (lastUnit < firstUnit) {
		    lastUnit = firstUnit;
		}
	    } else {
		firstUnit = lastUnit = 0;
	    }
	    scrollPtr->totalUnits = totalUnits;
	    scrollPtr->windowUnits = windowUnits;
	    scrollPtr->firstUnit = firstUnit;
	    scrollPtr->lastUnit = lastUnit;
	    if (scrollPtr->totalUnits == 0) {
		scrollPtr->firstFraction = 0.0;
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->firstFraction = ((double) firstUnit)/totalUnits;
		scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits;
	    }
	    scrollPtr->flags &= ~NEW_STYLE_COMMANDS;

	} else {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " set firstFraction lastFraction\" or \"",
		    argv[0],
		    " set totalUnits windowUnits firstUnit lastUnit\"", NULL);
	    goto error;
	}
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);

    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be activate, cget, configure, delta, fraction, ",
		"get, identify, or set", NULL);
	goto error;
    }

  done:
    Tcl_Release((ClientData) scrollPtr);
    return result;

  error:
    Tcl_Release((ClientData) scrollPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureScrollbar --
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureScrollbar(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkScrollbar *scrollPtr,
				/* 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. */
{
    if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc,
	    (const char **)objv, (char *) scrollPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * A few options need special processing, such as setting the background
     * from a 3-D border.
     */

    if (scrollPtr->command != NULL) {
        scrollPtr->commandSize = (int) strlen(scrollPtr->command);
    } else {
	scrollPtr->commandSize = 0;
    }

    /*
     * Configure platform specific options.
     */







|


|
|


|
|









|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
 *
 *----------------------------------------------------------------------
 */

static int
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, 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.
     */

    if (scrollPtr->command != NULL) {
        scrollPtr->commandSize = (int)strlen(scrollPtr->command);
    } else {
	scrollPtr->commandSize = 0;
    }

    /*
     * Configure platform specific options.
     */
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
 */

void
TkScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == DestroyNotify) {
	TkpDestroyScrollbar(scrollPtr);
	if (scrollPtr->tkwin != NULL) {
	    scrollPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(scrollPtr->interp,
		    scrollPtr->widgetCmd);
	}
	if (scrollPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(TkpDisplayScrollbar, scrollPtr);
	}
	/*
	 * Free up all the stuff that requires special handling, then let
	 * Tk_FreeOptions handle all the standard option-related stuff.
	 */

	Tk_FreeOptions(configSpecs, (char*) scrollPtr, scrollPtr->display, 0);

	Tcl_EventuallyFree(scrollPtr, TCL_DYNAMIC);
    } else if (eventPtr->type == ConfigureNotify) {
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scrollPtr->flags |= GOT_FOCUS;
	    if (scrollPtr->highlightWidth > 0) {







|











|






|
>
|







584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 */

void
TkScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *) clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == DestroyNotify) {
	TkpDestroyScrollbar(scrollPtr);
	if (scrollPtr->tkwin != NULL) {
	    scrollPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(scrollPtr->interp,
		    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.
	 */

	Tk_FreeOptions(configSpecs, (char *) scrollPtr,
		scrollPtr->display, 0);
	Tcl_EventuallyFree((ClientData) scrollPtr, TCL_DYNAMIC);
    } else if (eventPtr->type == ConfigureNotify) {
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scrollPtr->flags |= GOT_FOCUS;
	    if (scrollPtr->highlightWidth > 0) {
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
 *----------------------------------------------------------------------
 */

static void
ScrollbarCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;

    /*
     * 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.







|







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
 *----------------------------------------------------------------------
 */

static void
ScrollbarCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
    Tk_Window tkwin = scrollPtr->tkwin;

    /*
     * 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.
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
 *--------------------------------------------------------------
 */

void
TkScrollbarEventuallyRedraw(
    TkScrollbar *scrollPtr)	/* Information about widget. */
{
    if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(scrollPtr->tkwin)) {
	return;
    }
    if (!(scrollPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayScrollbar, scrollPtr);
	scrollPtr->flags |= REDRAW_PENDING;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


|
|











686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
 *--------------------------------------------------------------
 */

void
TkScrollbarEventuallyRedraw(
    TkScrollbar *scrollPtr)	/* Information about widget. */
{
    if ((scrollPtr->tkwin == NULL) || (!Tk_IsMapped(scrollPtr->tkwin))) {
	return;
    }
    if ((scrollPtr->flags & REDRAW_PENDING) == 0) {
	Tcl_DoWhenIdle(TkpDisplayScrollbar, (ClientData) scrollPtr);
	scrollPtr->flags |= REDRAW_PENDING;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkScrollbar.h.

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    /*
     * 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 OLD_STYLE_COMMANDS flag is 1.
     */

#ifndef TK_NO_DEPRECATED
    int totalUnits;		/* Total dimension of application, in units.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * is set. */
    int windowUnits;		/* Maximum number of units that can be
				 * displayed in the window at once. Valid only
				 * if the OLD_STYLE_COMMANDS flag is set. */
    int firstUnit;		/* Number of last unit visible in
				 * application's window. Valid only if the
				 * OLD_STYLE_COMMANDS flag is set. */
    int lastUnit;		/* Index of last unit visible in window.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * isn't set. */
#else
    int dummy1,dummy2,dummy3,dummy4; /* sizeof(TkScrollbar) should not depend on TK_NO_DEPRECATED */
#endif /* TK_NO_DEPRECATED */
    double firstFraction;	/* Position of first visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */
    double lastFraction;	/* Position of last visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */








|


<

|
|


|


|

|

<
<
<







89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110



111
112
113
114
115
116
117
    /*
     * 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 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. */
    int firstUnit;		/* Number of last unit visible in
				 * 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. */



    double firstFraction;	/* Position of first visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */
    double lastFraction;	/* Position of last visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */

144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#define BOTTOM_ARROW	5

/*
 * Flag bits for scrollbars:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has
 *				already been queued to redraw this window.
 * OLD_STYLE_COMMANDS:		Non-zero means the old style of commands
 *				should be used to communicate with the widget:
 *				".t yview 40", instead of
 *				".t yview scroll 2 lines", for example.

 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 */

#define REDRAW_PENDING		1
#ifndef TK_NO_DEPRECATED
#   define OLD_STYLE_COMMANDS	2
#endif /* TK_NO_DEPRECATED */
#define GOT_FOCUS		4

/*
 * Declaration of scrollbar class functions structure
 * and default scrollbar width, for use in configSpec.
 */

MODULE_SCOPE const Tk_ClassProcs tkpScrollbarProcs;
MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE];

/*
 * Declaration of functions used in the implementation of the scrollbar
 * widget.
 */








|

<
|
>





<
|
<







|







140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155

156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#define BOTTOM_ARROW	5

/*
 * Flag bits for scrollbars:
 *
 * 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.
 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 */

#define REDRAW_PENDING		1

#define NEW_STYLE_COMMANDS	2

#define GOT_FOCUS		4

/*
 * Declaration of scrollbar class functions structure
 * and default scrollbar width, for use in configSpec.
 */

MODULE_SCOPE Tk_ClassProcs tkpScrollbarProcs;
MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE];

/*
 * Declaration of functions used in the implementation of the scrollbar
 * widget.
 */

Changes to generic/tkSelect.c.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

typedef struct {
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    int cmdLength;		/* # of non-NULL bytes in command. */
    int charOffset;		/* The offset of the next char to retrieve. */
    int byteOffset;		/* The expected byte offset of the next
				 * chunk. */
    char buffer[4];		/* A buffer to hold part of a UTF character
				 * that is split across chunks. */
    char command[TKFLEXARRAY];		/* 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.
 */

typedef struct LostCommand {
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    Tcl_Obj *cmdObj;		/* Reference to command to invoke. */


} LostCommand;

/*
 * The structure below is used to keep each thread's pending list separate.
 */

typedef struct {
    TkSelInProgress *pendingPtr;
				/* Topmost search in progress, or NULL if
				 * none. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static TkSizeT	HandleTclCommand(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		LostSelection(ClientData clientData);
static int		SelGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateSelHandler --
 *
 *	This function is called to register a function as the handler for







|

|












|
>
>






|










|
|


|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

typedef struct {
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    int cmdLength;		/* # of non-NULL bytes in command. */
    int charOffset;		/* The offset of the next char to retrieve. */
    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. */
} 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.
 */

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. */
} LostCommand;

/*
 * 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. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

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 function is called to register a function as the handler for
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    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). */
{
    TkSelHandler *selPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }

    /*
     * 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) {
	if (selPtr == NULL) {
	    selPtr = (TkSelHandler *)ckalloc(sizeof(TkSelHandler));
	    selPtr->nextPtr = winPtr->selHandlerList;
	    winPtr->selHandlerList = selPtr;
	    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?
	     */

	    if (selPtr->proc == HandleTclCommand) {
		ckfree(selPtr->clientData);
	    }
	    break;
	}
    }
    selPtr->selection = selection;
    selPtr->target = target;
    selPtr->format = format;







|













|












|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    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;

    if (winPtr->dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }

    /*
     * 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) {
	if (selPtr == NULL) {
	    selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler));
	    selPtr->nextPtr = winPtr->selHandlerList;
	    winPtr->selHandlerList = selPtr;
	    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?
	     */

	    if (selPtr->proc == HandleTclCommand) {
		ckfree((char *) selPtr->clientData);
	    }
	    break;
	}
    }
    selPtr->selection = selection;
    selPtr->target = target;
    selPtr->format = format;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	 * 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) {
	    if (selPtr == NULL) {
		selPtr = (TkSelHandler *)ckalloc(sizeof(TkSelHandler));
		selPtr->nextPtr = winPtr->selHandlerList;
		winPtr->selHandlerList = selPtr;
		selPtr->selection = selection;
		selPtr->target = target;
		selPtr->format = target; /* We want UTF8_STRING format */
		selPtr->proc = proc;
		if (selPtr->proc == HandleTclCommand) {
		    /*
		     * The clientData is selection controlled memory, so we
		     * should make a copy for this selPtr.
		     */

		    size_t cmdInfoLen = offsetof(CommandInfo, command) + 1 +
			    ((CommandInfo *)clientData)->cmdLength;

		    selPtr->clientData = ckalloc(cmdInfoLen);
		    memcpy(selPtr->clientData, clientData, cmdInfoLen);
		} else {
		    selPtr->clientData = clientData;
		}
		selPtr->size = 8;
		break;
	    }







|












|
|

|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
	 * 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) {
	    if (selPtr == NULL) {
		selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler));
		selPtr->nextPtr = winPtr->selHandlerList;
		winPtr->selHandlerList = selPtr;
		selPtr->selection = selection;
		selPtr->target = target;
		selPtr->format = target; /* We want UTF8_STRING format */
		selPtr->proc = proc;
		if (selPtr->proc == HandleTclCommand) {
		    /*
		     * The clientData is selection controlled memory, so we
		     * should make a copy for this selPtr.
		     */

		    unsigned cmdInfoLen = sizeof(CommandInfo) +
			    ((CommandInfo*)clientData)->cmdLength - 3;

		    selPtr->clientData = (ClientData)ckalloc(cmdInfoLen);
		    memcpy(selPtr->clientData, clientData, cmdInfoLen);
		} else {
		    selPtr->clientData = clientData;
		}
		selPtr->size = 8;
		break;
	    }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    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;
    TkSelHandler *selPtr, *prevPtr;
    TkSelInProgress *ipPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Find the selection handler to be deleted, or return if it doesn't
     * exist.
     */







|
|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    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));

    /*
     * Find the selection handler to be deleted, or return if it doesn't
     * exist.
     */
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    }

    if (selPtr->proc == HandleTclCommand) {
	/*
	 * Mark the CommandInfo as deleted and free it if we can.
	 */

	((CommandInfo *) selPtr->clientData)->interp = NULL;
	Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC);
    }
    ckfree(selPtr);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_OwnSelection --
 *







|


|







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
    }

    if (selPtr->proc == HandleTclCommand) {
	/*
	 * Mark the CommandInfo as deleted and free it if we can.
	 */

	((CommandInfo*)selPtr->clientData)->interp = NULL;
	Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC);
    }
    ckfree((char *) selPtr);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_OwnSelection --
 *
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    Tk_LostSelProc *clearProc = NULL;
    void *clearData = NULL;/* Initialization needed only to prevent
				 * compiler warning. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }
    Tk_MakeWindowExist(tkwin);








|



|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
    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. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }
    Tk_MakeWindowExist(tkwin);

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
    for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr == NULL) {
	infoPtr = (TkSelectionInfo *)ckalloc(sizeof(TkSelectionInfo));
	infoPtr->selection = selection;
	infoPtr->nextPtr = dispPtr->selectionInfoPtr;
	dispPtr->selectionInfoPtr = infoPtr;
    } else if (infoPtr->clearProc != NULL) {
	if (infoPtr->owner != tkwin) {
	    clearProc = infoPtr->clearProc;
	    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.
	     */

	    ckfree(infoPtr->clearData);
	}
    }

    infoPtr->owner = tkwin;
    infoPtr->serial = NextRequest(winPtr->display);
    infoPtr->clearProc = proc;
    infoPtr->clearData = clientData;







|














|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
    for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr == NULL) {
	infoPtr = (TkSelectionInfo*) ckalloc(sizeof(TkSelectionInfo));
	infoPtr->selection = selection;
	infoPtr->nextPtr = dispPtr->selectionInfoPtr;
	dispPtr->selectionInfoPtr = infoPtr;
    } else if (infoPtr->clearProc != NULL) {
	if (infoPtr->owner != tkwin) {
	    clearProc = infoPtr->clearProc;
	    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.
	     */

	    ckfree((char *) infoPtr->clearData);
	}
    }

    infoPtr->owner = tkwin;
    infoPtr->serial = NextRequest(winPtr->display);
    infoPtr->clearProc = proc;
    infoPtr->clearData = clientData;
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

    /*
     * Now that we are done, we can invoke clearProc without running into
     * reentrancy problems.
     */

    if (clearProc != NULL) {
	clearProc(clearData);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ClearSelection --







|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

    /*
     * Now that we are done, we can invoke clearProc without running into
     * reentrancy problems.
     */

    if (clearProc != NULL) {
	(*clearProc)(clearData);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ClearSelection --
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
 */

void
Tk_ClearSelection(
    Tk_Window tkwin,		/* Window that selects a display. */
    Atom selection)		/* Selection to be cancelled. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    TkSelectionInfo *prevPtr;
    TkSelectionInfo *nextPtr;
    Tk_LostSelProc *clearProc = NULL;
    void *clearData = NULL;/* Initialization needed only to prevent
				 * compiler warning. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }

    for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;







|





|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
 */

void
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;
    TkSelectionInfo *infoPtr;
    TkSelectionInfo *prevPtr;
    TkSelectionInfo *nextPtr;
    Tk_LostSelProc *clearProc = NULL;
    ClientData clearData = NULL;/* Initialization needed only to prevent
				 * compiler warning. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }

    for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
	}
	prevPtr = infoPtr;
    }

    if (infoPtr != NULL) {
	clearProc = infoPtr->clearProc;
	clearData = infoPtr->clearData;
	ckfree(infoPtr);
    }
    XSetSelectionOwner(winPtr->display, selection, None, CurrentTime);

    if (clearProc != NULL) {
	clearProc(clearData);
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetSelection --







|




|







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
	}
	prevPtr = infoPtr;
    }

    if (infoPtr != NULL) {
	clearProc = infoPtr->clearProc;
	clearData = infoPtr->clearData;
	ckfree((char *) infoPtr);
    }
    XSetSelectionOwner(winPtr->display, selection, None, CurrentTime);

    if (clearProc != NULL) {
	(*clearProc)(clearData);
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetSelection --
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
    for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr != NULL) {
	TkSelHandler *selPtr;
	int offset, result, count;
	char buffer[TK_SEL_BYTES_AT_ONCE+1];
	TkSelInProgress ip;

	for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList;
		selPtr != NULL; selPtr = selPtr->nextPtr) {
	    if (selPtr->target==target && selPtr->selection==selection) {







|







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
    for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr != NULL) {
	register TkSelHandler *selPtr;
	int offset, result, count;
	char buffer[TK_SEL_BYTES_AT_ONCE+1];
	TkSelInProgress ip;

	for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList;
		selPtr != NULL; selPtr = selPtr->nextPtr) {
	    if (selPtr->target==target && selPtr->selection==selection) {
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
	    if (count > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    if (count < 0) {
		goto cantget;
	    }
	    buffer[count] = 0;
	    result = proc(clientData, interp, buffer);
	} else {
	    offset = 0;
	    result = TCL_OK;
	    ip.selPtr = selPtr;
	    ip.nextPtr = tsdPtr->pendingPtr;
	    tsdPtr->pendingPtr = &ip;
	    while (1) {
		count = selPtr->proc(selPtr->clientData, offset, buffer,
			TK_SEL_BYTES_AT_ONCE);
		if ((count < 0) || (ip.selPtr == NULL)) {
		    tsdPtr->pendingPtr = ip.nextPtr;
		    goto cantget;
		}
		if (count > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
		buffer[count] = '\0';
		result = proc(clientData, interp, buffer);
		if ((result != TCL_OK) || (count < TK_SEL_BYTES_AT_ONCE)
			|| (ip.selPtr == NULL)) {
		    break;
		}
		offset += count;
	    }
	    tsdPtr->pendingPtr = ip.nextPtr;
	}
	return result;
    }

    /*
     * The selection is owned by some other process.
     */

    return TkSelGetSelection(interp, tkwin, selection, target, proc,
	    clientData);

  cantget:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "%s selection doesn't exist or form \"%s\" not defined",
	    Tk_GetAtomName(tkwin, selection),
	    Tk_GetAtomName(tkwin, target)));
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SelectionObjCmd --







|







|









|



















|
|
<
|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
	    if (count > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    if (count < 0) {
		goto cantget;
	    }
	    buffer[count] = 0;
	    result = (*proc)(clientData, interp, buffer);
	} else {
	    offset = 0;
	    result = TCL_OK;
	    ip.selPtr = selPtr;
	    ip.nextPtr = tsdPtr->pendingPtr;
	    tsdPtr->pendingPtr = &ip;
	    while (1) {
		count = (selPtr->proc)(selPtr->clientData, offset, buffer,
			TK_SEL_BYTES_AT_ONCE);
		if ((count < 0) || (ip.selPtr == NULL)) {
		    tsdPtr->pendingPtr = ip.nextPtr;
		    goto cantget;
		}
		if (count > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
		buffer[count] = '\0';
		result = (*proc)(clientData, interp, buffer);
		if ((result != TCL_OK) || (count < TK_SEL_BYTES_AT_ONCE)
			|| (ip.selPtr == NULL)) {
		    break;
		}
		offset += count;
	    }
	    tsdPtr->pendingPtr = ip.nextPtr;
	}
	return result;
    }

    /*
     * The selection is owned by some other process.
     */

    return TkSelGetSelection(interp, tkwin, selection, target, proc,
	    clientData);

  cantget:
    Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
	    " selection doesn't exist or form \"",

	    Tk_GetAtomName(tkwin, target), "\" not defined", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SelectionObjCmd --
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

int
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. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *path = NULL;
    Atom selection;
    const char *selName = NULL;
    const char *string;
    int count, index;
    Tcl_Obj **objs;
    static const char *const optionStrings[] = {
	"clear", "get", "handle", "own", NULL
    };
    enum options {
	SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case SELECTION_CLEAR: {
	static const char *const 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 < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", 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;
	    }
	}

	if (count == 1) {
	    path = Tcl_GetString(objs[0]);
	} else if (count > 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    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;
	}

	Tk_ClearSelection(tkwin, selection);
	break;
    }

    case SELECTION_GET: {
	Atom target;
	const char *targetName = NULL;
	Tcl_DString selBytes;
	int result;
	static const char *const 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 (count < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL);
		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0], getOptionStrings,
		    "option", 0, &getIndex) != TCL_OK) {
		return TCL_ERROR;
	    }







|

|
|

|
<


|







|










|












|
|
<




















|




















|


|












|
|
<







665
666
667
668
669
670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779

int
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. */
{
    Tk_Window tkwin = (Tk_Window) clientData;
    char *path = NULL;
    Atom selection;
    char *selName = NULL, *string;

    int count, index;
    Tcl_Obj **objs;
    static CONST char *optionStrings[] = {
	"clear", "get", "handle", "own", NULL
    };
    enum options {
	SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN
    };

    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 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 < 2) {
		Tcl_AppendResult(interp, "value for \"", string,
			"\" missing", 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;
	    }
	}

	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;
	}

	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 (count < 2) {
		Tcl_AppendResult(interp, "value for \"", string,
			"\" missing", NULL);

		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0], getOptionStrings,
		    "option", 0, &getIndex) != TCL_OK) {
		return TCL_ERROR;
	    }
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
	}
	if (selName != NULL) {
	    selection = Tk_InternAtom(tkwin, selName);
	} else {
	    selection = XA_PRIMARY;
	}
	if (count > 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    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, &selBytes);
	if (result == TCL_OK) {
	    Tcl_DStringResult(interp, &selBytes);
	} else {
	    Tcl_DStringFree(&selBytes);
	}
	return result;
    }

    case SELECTION_HANDLE: {
	Atom target, format;
	const char *targetName = NULL;
	const char *formatName = NULL;
	CommandInfo *cmdInfoPtr;
	TkSizeT cmdLength;
	static const char *const 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) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL);
		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0],handleOptionStrings,
		    "option", 0, &handleIndex) != TCL_OK) {
		return TCL_ERROR;
	    }







|











|










|
|
|
|
|














|
|
<







799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856
	}
	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;
	}

	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;
    }

    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) {
		Tcl_AppendResult(interp, "value for \"", string,
			"\" missing", NULL);

		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0],handleOptionStrings,
		    "option", 0, &handleIndex) != TCL_OK) {
		return TCL_ERROR;
	    }
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
	    case HANDLE_TYPE:
		targetName = Tcl_GetString(objs[1]);
		break;
	    }
	}

	if ((count < 2) || (count > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-option value ...? window command");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	if (selName != NULL) {







|
<







865
866
867
868
869
870
871
872

873
874
875
876
877
878
879
	    case HANDLE_TYPE:
		targetName = Tcl_GetString(objs[1]);
		break;
	    }
	}

	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) {
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

1011

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
	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 = TkGetStringFromObj(objs[1], &cmdLength);
	if (cmdLength == 0) {
	    Tk_DeleteSelHandler(tkwin, selection, target);
	} else {
	    cmdInfoPtr = (CommandInfo *)ckalloc(offsetof(CommandInfo, command)
		    + 1 + 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,
		    cmdInfoPtr, format);
	}
	return TCL_OK;
    }

    case SELECTION_OWN: {
	LostCommand *lostPtr;
	Tcl_Obj *commandObj = NULL;

	static const char *const 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_SetObjResult(interp, Tcl_ObjPrintf(
			"value for \"%s\" missing", string));
		Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL);
		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0], ownOptionStrings,
		    "option", 0, &ownIndex) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum ownOptions) ownIndex) {
	    case OWN_COMMAND:
		commandObj = 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, "?-option value ...? ?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);
	    }
	    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_SetObjResult(interp, Tk_NewWindowObj(infoPtr->owner));
	    }
	    return TCL_OK;
	}

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	if (count == 2) {
	    commandObj = objs[1];
	}
	if (commandObj == NULL) {
	    Tk_OwnSelection(tkwin, selection, NULL, NULL);
	    return TCL_OK;
	}

	lostPtr = (LostCommand *)ckalloc(sizeof(LostCommand));

	lostPtr->interp = interp;
	lostPtr->cmdObj = commandObj;
	Tcl_IncrRefCount(commandObj);
	Tk_OwnSelection(tkwin, selection, LostSelection, lostPtr);
	return TCL_OK;
    }
    }
    return TCL_OK;
}

/*







|



|
|







|





|
|
>
|












|
|
<










|











|


















|













|









|

|
|


>
|
>

|
<
|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019
	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_AppendResult(interp, "value for \"", string,
			"\" missing", NULL);

		return TCL_ERROR;
	    }

	    if (Tcl_GetIndexFromObj(interp, objs[0], ownOptionStrings,
		    "option", 0, &ownIndex) != TCL_OK) {
		return TCL_ERROR;
	    }

	    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);
	    }
	    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;
	}

	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;
}

/*
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
 *	Frees up memory associated with the selection.
 *
 *----------------------------------------------------------------------
 */

void
TkSelDeadWindow(
    TkWindow *winPtr)	/* Window that's being deleted. */
{
    TkSelHandler *selPtr;
    TkSelInProgress *ipPtr;
    TkSelectionInfo *infoPtr, *prevPtr, *nextPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * While deleting all the handlers, be careful to check whether
     * ConvertSelection or TkSelPropProc are about to process one of the







|

|
|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
 *	Frees up memory associated with the selection.
 *
 *----------------------------------------------------------------------
 */

void
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));

    /*
     * While deleting all the handlers, be careful to check whether
     * ConvertSelection or TkSelPropProc are about to process one of the
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
	    }
	}
	if (selPtr->proc == HandleTclCommand) {
	    /*
	     * Mark the CommandInfo as deleted and free it when we can.
	     */

	    ((CommandInfo *) selPtr->clientData)->interp = NULL;
	    Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC);
	}
	ckfree(selPtr);
    }

    /*
     * Remove selections owned by window being deleted.
     */

    for (infoPtr = winPtr->dispPtr->selectionInfoPtr, prevPtr = NULL;
	    infoPtr != NULL; infoPtr = nextPtr) {
	nextPtr = infoPtr->nextPtr;
	if (infoPtr->owner == (Tk_Window) winPtr) {
	    if (infoPtr->clearProc == LostSelection) {
		ckfree(infoPtr->clearData);
	    }
	    ckfree(infoPtr);
	    infoPtr = prevPtr;
	    if (prevPtr == NULL) {
		winPtr->dispPtr->selectionInfoPtr = nextPtr;
	    } else {
		prevPtr->nextPtr = nextPtr;
	    }
	}







|


|











|

|







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
	    }
	}
	if (selPtr->proc == HandleTclCommand) {
	    /*
	     * Mark the CommandInfo as deleted and free it when we can.
	     */

	    ((CommandInfo*)selPtr->clientData)->interp = NULL;
	    Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC);
	}
	ckfree((char *) selPtr);
    }

    /*
     * Remove selections owned by window being deleted.
     */

    for (infoPtr = winPtr->dispPtr->selectionInfoPtr, prevPtr = NULL;
	    infoPtr != NULL; infoPtr = nextPtr) {
	nextPtr = infoPtr->nextPtr;
	if (infoPtr->owner == (Tk_Window) winPtr) {
	    if (infoPtr->clearProc == LostSelection) {
		ckfree((char *) infoPtr->clearData);
	    }
	    ckfree((char *) infoPtr);
	    infoPtr = prevPtr;
	    if (prevPtr == NULL) {
		winPtr->dispPtr->selectionInfoPtr = nextPtr;
	    } else {
		prevPtr->nextPtr = nextPtr;
	    }
	}
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
 */

void
TkSelInit(
    Tk_Window tkwin)		/* Window token (used to find display to
				 * initialize). */
{
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    /*
     * Fetch commonly-used atoms.
     */

    dispPtr->multipleAtom	= Tk_InternAtom(tkwin, "MULTIPLE");
    dispPtr->incrAtom		= Tk_InternAtom(tkwin, "INCR");
    dispPtr->targetsAtom	= Tk_InternAtom(tkwin, "TARGETS");
    dispPtr->timestampAtom	= Tk_InternAtom(tkwin, "TIMESTAMP");
    dispPtr->textAtom		= Tk_InternAtom(tkwin, "TEXT");
    dispPtr->compoundTextAtom	= Tk_InternAtom(tkwin, "COMPOUND_TEXT");
    dispPtr->applicationAtom	= Tk_InternAtom(tkwin, "TK_APPLICATION");
    dispPtr->windowAtom		= Tk_InternAtom(tkwin, "TK_WINDOW");
    dispPtr->clipboardAtom	= Tk_InternAtom(tkwin, "CLIPBOARD");
    dispPtr->atomPairAtom	= Tk_InternAtom(tkwin, "ATOM_PAIR");

    /*
     * 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)
    dispPtr->utf8Atom		= Tk_InternAtom(tkwin, "UTF8_STRING");
#else
    dispPtr->utf8Atom		= (Atom) 0;
#endif
}

/*







|














<








|







1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
 */

void
TkSelInit(
    Tk_Window tkwin)		/* Window token (used to find display to
				 * initialize). */
{
    register TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    /*
     * Fetch commonly-used atoms.
     */

    dispPtr->multipleAtom	= Tk_InternAtom(tkwin, "MULTIPLE");
    dispPtr->incrAtom		= Tk_InternAtom(tkwin, "INCR");
    dispPtr->targetsAtom	= Tk_InternAtom(tkwin, "TARGETS");
    dispPtr->timestampAtom	= Tk_InternAtom(tkwin, "TIMESTAMP");
    dispPtr->textAtom		= Tk_InternAtom(tkwin, "TEXT");
    dispPtr->compoundTextAtom	= Tk_InternAtom(tkwin, "COMPOUND_TEXT");
    dispPtr->applicationAtom	= Tk_InternAtom(tkwin, "TK_APPLICATION");
    dispPtr->windowAtom		= Tk_InternAtom(tkwin, "TK_WINDOW");
    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
     */

#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
    dispPtr->utf8Atom		= Tk_InternAtom(tkwin, "UTF8_STRING");
#else
    dispPtr->utf8Atom		= (Atom) 0;
#endif
}

/*
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
 *
 *----------------------------------------------------------------------
 */

void
TkSelClearSelection(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    XEvent *eventPtr)	/* X SelectionClear event. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    TkSelectionInfo *prevPtr;

    /*
     * Invoke clear function for window that just lost the selection. This
     * code is a bit tricky, because any callbacks due to selection changes







|

|







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
 *
 *----------------------------------------------------------------------
 */

void
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;
    TkSelectionInfo *infoPtr;
    TkSelectionInfo *prevPtr;

    /*
     * Invoke clear function for window that just lost the selection. This
     * code is a bit tricky, because any callbacks due to selection changes
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
	if (infoPtr->selection == eventPtr->xselectionclear.selection) {
	    break;
	}
	prevPtr = infoPtr;
    }

    if (infoPtr != NULL && (infoPtr->owner == tkwin) &&
	    (eventPtr->xselectionclear.serial >= (unsigned long) infoPtr->serial)) {
	if (prevPtr == NULL) {
	    dispPtr->selectionInfoPtr = infoPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = infoPtr->nextPtr;
	}

	/*
	 * 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).
	 */

	if (infoPtr->clearProc != NULL) {
	    infoPtr->clearProc(infoPtr->clearData);
	}
	ckfree(infoPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * SelGetProc --







|














|

|







1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
	if (infoPtr->selection == eventPtr->xselectionclear.selection) {
	    break;
	}
	prevPtr = infoPtr;
    }

    if (infoPtr != NULL && (infoPtr->owner == tkwin) &&
	    (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) {
	if (prevPtr == NULL) {
	    dispPtr->selectionInfoPtr = infoPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = infoPtr->nextPtr;
	}

	/*
	 * 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).
	 */

	if (infoPtr->clearProc != NULL) {
	    (*infoPtr->clearProc)(infoPtr->clearData);
	}
	ckfree((char *) infoPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * SelGetProc --
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
 * Side effects:
 *	Bytes get appended to the dynamic string pointed to by the clientData
 *	argument.
 *
 *--------------------------------------------------------------
 */


static int
SelGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleTclCommand --







>




|

|

|







1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
 * Side effects:
 *	Bytes get appended to the dynamic string pointed to by the clientData
 *	argument.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleTclCommand --
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329


1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369


1370



1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
 *
 * Side effects:
 *	None except for things done by the Tcl command.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
HandleTclCommand(
    ClientData clientData,	/* Information about command to execute. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    CommandInfo *cmdInfoPtr = (CommandInfo *)clientData;
    int length;


    Tcl_Obj *command;
    const char *string;
    Tcl_Interp *interp = cmdInfoPtr->interp;

    Tcl_InterpState savedState;
    int extraBytes, charOffset, count, numChars, code;
    const char *p;

    /*
     * We must also protect the interpreter and the command from being deleted
     * too soon.
     */

    Tcl_Preserve(clientData);
    Tcl_Preserve(interp);

    /*
     * Compute the proper byte offset in the case where the last chunk split a
     * character.
     */

    if ((int)offset == cmdInfoPtr->byteOffset) {
	charOffset = cmdInfoPtr->charOffset;
	extraBytes = strlen(cmdInfoPtr->buffer);
	if (extraBytes > 0) {
	    strcpy(buffer, cmdInfoPtr->buffer);
	    maxBytes -= extraBytes;
	    buffer += extraBytes;
	}
    } else {
	cmdInfoPtr->byteOffset = 0;
	cmdInfoPtr->charOffset = 0;
	extraBytes = 0;
	charOffset = 0;
    }

    /*
     * First, generate a command by taking the command string and appending
     * the offset and maximum # of bytes.
     */



    command = Tcl_ObjPrintf("%s %d %d",



	    cmdInfoPtr->command, charOffset, (int)maxBytes);
    Tcl_IncrRefCount(command);

    /*
     * Execute the command. Be sure to restore the state of the interpreter
     * after executing the command.
     */

    savedState = Tcl_SaveInterpState(interp, TCL_OK);
    code = Tcl_EvalObjEx(interp, command, TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(command);
    if (code == TCL_OK) {
	/*
	 * TODO: This assumes that bytes are characters; that's not true!
	 */

	string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	count = (length > (int)maxBytes) ? (int)maxBytes : length;
	memcpy(buffer, string, count);
	buffer[count] = '\0';

	/*
	 * Update the partial character information for the next retrieval if
	 * the command has not been deleted.
	 */

	if (cmdInfoPtr->interp != NULL) {
	    if (length <= (int)maxBytes) {
		cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1);
		cmdInfoPtr->buffer[0] = '\0';
	    } else {
		int ch;
		p = string;
		string += count;
		numChars = 0;
		while (p < string) {
		    p += TkUtfToUniChar(p, &ch);
		    numChars++;
		}
		cmdInfoPtr->charOffset += numChars;
		length = p - string;
		if (length > 0) {
		    strncpy(cmdInfoPtr->buffer, string, length);
		}
		cmdInfoPtr->buffer[length] = '\0';
	    }
	    cmdInfoPtr->byteOffset += count + extraBytes;
	}
	count += extraBytes;
    } else {
	/*
	 * Something went wrong. Log errors as background errors, and silently
	 * drop everything else.
	 */


	if (code == TCL_ERROR) {
	    Tcl_AddErrorInfo(interp, "\n    (command handling selection)");
	    Tcl_BackgroundException(interp, code);
	}

	count = -1;
    }
    (void) Tcl_RestoreInterpState(interp, savedState);

    Tcl_Release(clientData);
    Tcl_Release(interp);
    return count;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSelDefaultSelection --







|


|


|

|
|
>
>
|
<

>
|
|
|







|






|



















>
>
|
>
>
>
|
<






|
|
<
|
<
<
<
|
|
|
|








|



<




|





|







<
<
<
<
>
|
<
<
|
|
>
|

<


|







1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
1383

1384



1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400

1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418




1419
1420


1421
1422
1423
1424
1425

1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
 *
 * Side effects:
 *	None except for things done by the Tcl command.
 *
 *----------------------------------------------------------------------
 */

static int
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. */
{
    CommandInfo *cmdInfoPtr = (CommandInfo *) clientData;
    int spaceNeeded, length;
#define MAX_STATIC_SIZE 100
    char staticSpace[MAX_STATIC_SIZE];
    char *command, *string;

    Tcl_Interp *interp = cmdInfoPtr->interp;
    Tcl_DString oldResult;
    Tcl_Obj *objPtr;
    int extraBytes, charOffset, count, numChars;
    CONST char *p;

    /*
     * 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.
     */

    if (offset == cmdInfoPtr->byteOffset) {
	charOffset = cmdInfoPtr->charOffset;
	extraBytes = strlen(cmdInfoPtr->buffer);
	if (extraBytes > 0) {
	    strcpy(buffer, cmdInfoPtr->buffer);
	    maxBytes -= extraBytes;
	    buffer += extraBytes;
	}
    } else {
	cmdInfoPtr->byteOffset = 0;
	cmdInfoPtr->charOffset = 0;
	extraBytes = 0;
	charOffset = 0;
    }

    /*
     * First, generate a command by taking the command string and appending
     * the offset and maximum # of bytes.
     */

    spaceNeeded = cmdInfoPtr->cmdLength + 30;
    if (spaceNeeded < MAX_STATIC_SIZE) {
	command = staticSpace;
    } else {
	command = (char *) ckalloc((unsigned) spaceNeeded);
    }
    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.
     */

    Tcl_DStringInit(&oldResult);
    Tcl_DStringGetResult(interp, &oldResult);

    if (TkCopyAndGlobalEval(interp, command) == TCL_OK) {



	objPtr = Tcl_GetObjResult(interp);
	string = Tcl_GetStringFromObj(objPtr, &length);
	count = (length > maxBytes) ? maxBytes : length;
	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.
	 */

	if (cmdInfoPtr->interp != NULL) {
	    if (length <= maxBytes) {
		cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1);
		cmdInfoPtr->buffer[0] = '\0';
	    } else {

		p = string;
		string += count;
		numChars = 0;
		while (p < string) {
		    p = Tcl_UtfNext(p);
		    numChars++;
		}
		cmdInfoPtr->charOffset += numChars;
		length = p - string;
		if (length > 0) {
		    strncpy(cmdInfoPtr->buffer, string, (size_t) length);
		}
		cmdInfoPtr->buffer[length] = '\0';
	    }
	    cmdInfoPtr->byteOffset += count + extraBytes;
	}
	count += extraBytes;
    } else {




	count = -1;
    }


    Tcl_DStringResult(interp, &oldResult);

    if (command != staticSpace) {
	ckfree(command);
    }


    Tcl_Release(clientData);
    Tcl_Release((ClientData) interp);
    return count;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSelDefaultSelection --
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
    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. */
{
    TkWindow *winPtr = (TkWindow *) infoPtr->owner;
    TkDisplay *dispPtr = winPtr->dispPtr;

    if (target == dispPtr->timestampAtom) {
	if (maxBytes < 20) {
	    return -1;
	}
	sprintf(buffer, "0x%x", (unsigned int) infoPtr->time);
	*typePtr = XA_INTEGER;
	return strlen(buffer);
    }

    if (target == dispPtr->targetsAtom) {
	TkSelHandler *selPtr;
	int length;
	Tcl_DString ds;

	if (maxBytes < 50) {
	    return -1;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds,
		"MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW", -1);
	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->selection == infoPtr->selection)
		    && (selPtr->target != dispPtr->applicationAtom)
		    && (selPtr->target != dispPtr->windowAtom)) {
		const char *atomString = Tk_GetAtomName((Tk_Window) winPtr,
			selPtr->target);

		Tcl_DStringAppendElement(&ds, atomString);
	    }
	}
	length = Tcl_DStringLength(&ds);
	if (length >= maxBytes) {
	    Tcl_DStringFree(&ds);
	    return -1;
	}
	memcpy(buffer, Tcl_DStringValue(&ds), length + 1);
	Tcl_DStringFree(&ds);
	*typePtr = XA_ATOM;
	return length;
    }

    if (target == dispPtr->applicationAtom) {
	int length;







|












|














|

<








|







1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
    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;

    if (target == dispPtr->timestampAtom) {
	if (maxBytes < 20) {
	    return -1;
	}
	sprintf(buffer, "0x%x", (unsigned int) infoPtr->time);
	*typePtr = XA_INTEGER;
	return strlen(buffer);
    }

    if (target == dispPtr->targetsAtom) {
	register TkSelHandler *selPtr;
	int length;
	Tcl_DString ds;

	if (maxBytes < 50) {
	    return -1;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds,
		"MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW", -1);
	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->selection == infoPtr->selection)
		    && (selPtr->target != dispPtr->applicationAtom)
		    && (selPtr->target != dispPtr->windowAtom)) {
		CONST char *atomString = Tk_GetAtomName((Tk_Window) winPtr,
			selPtr->target);

		Tcl_DStringAppendElement(&ds, atomString);
	    }
	}
	length = Tcl_DStringLength(&ds);
	if (length >= maxBytes) {
	    Tcl_DStringFree(&ds);
	    return -1;
	}
	memcpy(buffer, Tcl_DStringValue(&ds), (unsigned) (1+length));
	Tcl_DStringFree(&ds);
	*typePtr = XA_ATOM;
	return length;
    }

    if (target == dispPtr->applicationAtom) {
	int length;
1561
1562
1563
1564
1565
1566
1567
1568

1569
1570
1571
1572

1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586




1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
 *----------------------------------------------------------------------
 */

static void
LostSelection(
    ClientData clientData)	/* Pointer to LostCommand structure. */
{
    LostCommand *lostPtr = (LostCommand *)clientData;

    Tcl_Interp *interp = lostPtr->interp;
    Tcl_InterpState savedState;
    int code;


    Tcl_Preserve(interp);

    /*
     * Execute the command. Save the interpreter's result, if any, and restore
     * it after executing the command.
     */

    savedState = Tcl_SaveInterpState(interp, TCL_OK);

    Tcl_ResetResult(interp);
    code = Tcl_EvalObjEx(interp, lostPtr->cmdObj, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(interp, code);
    }
    (void) Tcl_RestoreInterpState(interp, savedState);





    /*
     * Free the storage for the command, since we're done with it now.
     */

    Tcl_DecrRefCount(lostPtr->cmdObj);
    ckfree(lostPtr);
    Tcl_Release(interp);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>
|
<
<

>
|






|
>

|
|
|

|
>
>
>
>





<
|
<









1553
1554
1555
1556
1557
1558
1559
1560
1561
1562


1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
 *----------------------------------------------------------------------
 */

static void
LostSelection(
    ClientData clientData)	/* Pointer to LostCommand structure. */
{
    LostCommand *lostPtr = (LostCommand *) clientData;
    Tcl_Obj *objPtr;
    Tcl_Interp *interp;



    interp = lostPtr->interp;
    Tcl_Preserve((ClientData) interp);

    /*
     * Execute the command. Save the interpreter's result, if any, and restore
     * it after executing the command.
     */

    objPtr = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(objPtr);
    Tcl_ResetResult(interp);

    if (TkCopyAndGlobalEval(interp, lostPtr->command) != TCL_OK) {
	Tcl_BackgroundError(interp);
    }

    Tcl_SetObjResult(interp, objPtr);
    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:
 */

Changes to generic/tkSelect.h.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 * 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. */
#if TCL_MAJOR_VERSION > 8
    unsigned long serial;	/* Serial number of last XSelectionSetOwner
				 * request made to server for this selection
				 * (used to filter out redundant
				 * SelectionClear events). */
#else
    int serial;
#endif
    Time time;			/* Timestamp used to acquire selection. */
    Tk_LostSelProc *clearProc;	/* Procedure to call when owner loses
				 * selection. */
    void *clearData;	/* Info to pass to clearProc. */
    struct TkSelectionInfo *nextPtr;
				/* 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.
 */

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. */
    void *clientData;	/* Argument to pass to proc. */
    TkSizeT 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). */
} TkSelHandler;

/*







<
|



<
<
<



|



















|
|







21
22
23
24
25
26
27

28
29
30
31



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 * 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
				 * 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. */
} 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.
 */

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. */
    ClientData clientData;	/* Argument to pass to proc. */
    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). */
} TkSelHandler;

/*
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89

typedef struct TkSelRetrievalInfo {
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    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. */

    Tk_GetSelProc *proc;	/* 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. */
    Tcl_TimerToken timeout;	/* Token for current timeout procedure. */
    int idleTime;		/* Number of seconds that have gone by without
				 * hearing anything from the selection







>
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

typedef struct TkSelRetrievalInfo {
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    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. */
    ClientData clientData;	/* Argument for proc. */
    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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 * 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. */
    TkSizeT 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. */







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 * 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 . */
} TkClipboardBuffer;

typedef struct TkClipboardTarget {
    Atom type;			/* Type conversion supported. */
159
160
161
162
163
164
165



166
167
168
169
170
171

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);



#ifndef TkSelUpdateClipboard
MODULE_SCOPE void	TkSelUpdateClipboard(TkWindow *winPtr,
			    TkClipboardTarget *targetPtr);
#endif

#endif /* _TKSELECT */







>
>
>






156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

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
MODULE_SCOPE void	TkSelUpdateClipboard(TkWindow *winPtr,
			    TkClipboardTarget *targetPtr);
#endif

#endif /* _TKSELECT */

Changes to generic/tkSquare.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#if 0
#define __NO_OLD_CONFIG
#endif
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"

/*
 * A data structure of the following type is kept for each square widget
 * managed by this file:
 */








<
<
<
<
<
<







12
13
14
15
16
17
18






19
20
21
22
23
24
25
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#if 0
#define __NO_OLD_CONFIG
#endif






#include "tkInt.h"

/*
 * A data structure of the following type is kept for each square widget
 * managed by this file:
 */

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	    "#d9d9d9", offsetof(Square, bgBorderPtr), TCL_INDEX_NONE, 0,
	    "white", 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	    "2", offsetof(Square, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BOOLEAN, "-dbl", "doubleBuffer", "DoubleBuffer",
	    "1", offsetof(Square, doubleBufferPtr), TCL_INDEX_NONE, 0 , NULL, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-foreground", 0},
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
	    "#b03060", offsetof(Square, fgBorderPtr), TCL_INDEX_NONE, 0,
	    "black", 0},
    {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0",
	    offsetof(Square, xPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0",
	    offsetof(Square, yPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	    "raised", offsetof(Square, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-size", "size", "Size", "20",
	    offsetof(Square, sizeObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * Forward declarations for procedures defined later in this file:
 */




static void		SquareDeletedProc(ClientData clientData);
static int		SquareConfigure(Tcl_Interp *interp, Square *squarePtr);
static void		SquareDestroy(void *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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
SquareObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Square *squarePtr;
    Tk_Window tkwin;
    Tk_OptionTable optionTable;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;







|
|
|
|
|
|

|

|
|
|

|
|

|

|

|

|
|






>
>
>


|





|




















|


|




<


|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	    "#d9d9d9", Tk_Offset(Square, bgBorderPtr), -1, 0,
	    (ClientData) "white"},
    {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", NULL, NULL, NULL, 0, -1, 0,
	    (ClientData) "-foreground"},
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
	    "#b03060", Tk_Offset(Square, fgBorderPtr), -1, 0,
	    (ClientData) "black"},
    {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0",
	    Tk_Offset(Square, xPtr), -1},
    {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0",
	    Tk_Offset(Square, yPtr), -1},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	    "raised", Tk_Offset(Square, reliefPtr), -1},
    {TK_OPTION_PIXELS, "-size", "size", "Size", "20",
	    Tk_Offset(Square, sizeObjPtr), -1},
    {TK_OPTION_END}
};

/*
 * Forward declarations for procedures defined later in this file:
 */

int			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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
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;
    Tk_OptionTable optionTable;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    /*
     * Allocate and initialize the widget record. The memset allows us to set
     * just the non-NULL/0 items.
     */

    squarePtr = (Square *)ckalloc(sizeof(Square));
    memset(squarePtr, 0, sizeof(Square));

    squarePtr->tkwin = tkwin;
    squarePtr->display = Tk_Display(tkwin);
    squarePtr->interp = interp;
    squarePtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd, squarePtr,
	    SquareDeletedProc);
    squarePtr->gc = NULL;
    squarePtr->optionTable = optionTable;

    if (Tk_InitOptions(interp, squarePtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(squarePtr->tkwin);
	ckfree(squarePtr);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask,
	    SquareObjEventProc, squarePtr);
    if (Tk_SetOptions(interp, squarePtr, optionTable, objc - 2,
	    objv + 2, tkwin, NULL, NULL) != TCL_OK) {
	goto error;
    }
    if (SquareConfigure(interp, squarePtr) != TCL_OK) {
	goto error;
    }








|
|





|
|



|


|




|
|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    /*
     * Allocate and initialize the widget record. The memset allows us to set
     * just the non-NULL/0 items.
     */

    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,
	    Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd,
	    (ClientData) squarePtr, SquareDeletedProc);
    squarePtr->gc = NULL;
    squarePtr->optionTable = optionTable;

    if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(squarePtr->tkwin);
	ckfree((char *) squarePtr);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask,
	    SquareObjEventProc, (ClientData) squarePtr);
    if (Tk_SetOptions(interp, (char *) squarePtr, optionTable, objc - 2,
	    objv + 2, tkwin, NULL, NULL) != TCL_OK) {
	goto error;
    }
    if (SquareConfigure(interp, squarePtr) != TCL_OK) {
	goto error;
    }

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
 */

static int
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 *const squareOptions[] = {"cget", "configure", NULL};
    enum {
	SQUARE_CGET, SQUARE_CONFIGURE
    };
    Tcl_Obj *resultObjPtr;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], squareOptions,
	    sizeof(char *), "command", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(squarePtr);

    switch (index) {
    case SQUARE_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}
	resultObjPtr = Tk_GetOptionValue(interp, 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, squarePtr,
		    squarePtr->optionTable, NULL, squarePtr->tkwin);
	    if (resultObjPtr == NULL) {
		result = TCL_ERROR;
	    }
	} else if (objc == 3) {
	    resultObjPtr = Tk_GetOptionInfo(interp, squarePtr,
		    squarePtr->optionTable, objv[2], squarePtr->tkwin);
	    if (resultObjPtr == NULL) {
		result = TCL_ERROR;
	    }
	} else {
	    result = Tk_SetOptions(interp, squarePtr,
		    squarePtr->optionTable, objc - 2, objv + 2,
		    squarePtr->tkwin, NULL, NULL);
	    if (result == TCL_OK) {
		result = SquareConfigure(interp, squarePtr);
	    }
	    if (!squarePtr->updatePending) {
		Tcl_DoWhenIdle(SquareDisplay, squarePtr);
		squarePtr->updatePending = 1;
	    }
	}
	if (resultObjPtr != NULL) {
	    Tcl_SetObjResult(interp, resultObjPtr);
	}
    }
    Tcl_Release(squarePtr);
    return result;

  error:
    Tcl_Release(squarePtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * SquareConfigure --







|

|

|







|



|
|



|







|










|





|





|






|







|



|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
 */

static int
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", NULL};
    enum {
	SQUARE_CGET, SQUARE_CONFIGURE
    };
    Tcl_Obj *resultObjPtr;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], squareOptions, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve((ClientData) squarePtr);

    switch (index) {
    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;
	    }
	} 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, NULL);
	    if (result == TCL_OK) {
		result = SquareConfigure(interp, squarePtr);
	    }
	    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:
    Tcl_Release((ClientData) squarePtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * SquareConfigure --
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
 *	for squarePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
SquareConfigure(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    Square *squarePtr)		/* Information about widget. */
{
    int borderWidth;
    Tk_3DBorder bgBorder;
    int doubleBuffer;
    (void)dummy;

    /*
     * Set the background for the window and create a graphics context for use
     * during redisplay.
     */

    bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,







|





<







311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
 *	for squarePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
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.
     */

    bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
     */

    Tk_GeometryRequest(squarePtr->tkwin, 200, 150);
    Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
	    &borderWidth);
    Tk_SetInternalBorder(squarePtr->tkwin, borderWidth);
    if (!squarePtr->updatePending) {
	Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	squarePtr->updatePending = 1;
    }
    KeepInWindow(squarePtr);
    return TCL_OK;
}

/*







|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
     */

    Tk_GeometryRequest(squarePtr->tkwin, 200, 150);
    Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
	    &borderWidth);
    Tk_SetInternalBorder(squarePtr->tkwin, borderWidth);
    if (!squarePtr->updatePending) {
	Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr);
	squarePtr->updatePending = 1;
    }
    KeepInWindow(squarePtr);
    return TCL_OK;
}

/*
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
 */

static void
SquareObjEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Square *squarePtr = (Square *)clientData;

    if (eventPtr->type == Expose) {
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	KeepInWindow(squarePtr);
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (squarePtr->tkwin != NULL) {
	    Tk_FreeConfigOptions((char *) squarePtr, squarePtr->optionTable,
		    squarePtr->tkwin);
	    if (squarePtr->gc != NULL) {
		Tk_FreeGC(squarePtr->display, squarePtr->gc);
	    }
	    squarePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(squarePtr->interp,
		    squarePtr->widgetCmd);
	}
	if (squarePtr->updatePending) {
	    Tcl_CancelIdleCall(SquareDisplay, squarePtr);
	}
	Tcl_EventuallyFree(squarePtr, (Tcl_FreeProc *) SquareDestroy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDeletedProc --







|



|





|














|

|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
 */

static void
SquareObjEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Square *squarePtr = (Square *) clientData;

    if (eventPtr->type == Expose) {
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	KeepInWindow(squarePtr);
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (squarePtr->tkwin != NULL) {
	    Tk_FreeConfigOptions((char *) squarePtr, squarePtr->optionTable,
		    squarePtr->tkwin);
	    if (squarePtr->gc != NULL) {
		Tk_FreeGC(squarePtr->display, squarePtr->gc);
	    }
	    squarePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(squarePtr->interp,
		    squarePtr->widgetCmd);
	}
	if (squarePtr->updatePending) {
	    Tcl_CancelIdleCall(SquareDisplay, (ClientData) squarePtr);
	}
	Tcl_EventuallyFree((ClientData) squarePtr, SquareDestroy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDeletedProc --
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
 *----------------------------------------------------------------------
 */

static void
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.







|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
 *----------------------------------------------------------------------
 */

static void
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.
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
 *--------------------------------------------------------------
 */

static void
SquareDisplay(
    ClientData clientData)	/* Information about window. */
{
    Square *squarePtr = (Square *)clientData;
    Tk_Window tkwin = squarePtr->tkwin;
    Pixmap pm = None;
    Drawable d;
    int borderWidth, size, relief;
    Tk_3DBorder bgBorder, fgBorder;
    int doubleBuffer;








|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
 *--------------------------------------------------------------
 */

static void
SquareDisplay(
    ClientData clientData)	/* Information about window. */
{
    Square *squarePtr = (Square *) clientData;
    Tk_Window tkwin = squarePtr->tkwin;
    Pixmap pm = None;
    Drawable d;
    int borderWidth, size, relief;
    Tk_3DBorder bgBorder, fgBorder;
    int doubleBuffer;

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
 *	Everything associated with the square is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDestroy(
    void *memPtr)		/* Info about square widget. */
{
    Square *squarePtr = (Square *)memPtr;

    ckfree(squarePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * KeepInWindow --
 *







|

|

|







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
 *	Everything associated with the square is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDestroy(
    char *memPtr)		/* Info about square widget. */
{
    Square *squarePtr = (Square *) memPtr;

    ckfree((char *) squarePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * KeepInWindow --
 *
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
 *	the square in the window.
 *
 *----------------------------------------------------------------------
 */

static void
KeepInWindow(
    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,







|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
 *	the square in the window.
 *
 *----------------------------------------------------------------------
 */

static void
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,

Changes to generic/tkStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

































141
142
143
144
145
146






147
148
149
150
151
152
153
154
155
156
157


158
159
160
161
162
163
164
165
166
167
168



169
170



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203


204




205

206


207



208
209

























210
211
212
213


214
215
216
217
218
219
220
221
222
223
/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * 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 "tkInt.h"

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
/* UNIX */
#define UNIX_TK
#include "tkUnixInt.h"
#endif

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"
#include "tkMacOSXPrivate.h"
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"

MODULE_SCOPE const TkStubs tkStubs;

/*
 * Remove macro that might interfere with the definition below.
 */

#undef Tk_MainEx
#undef Tk_FreeXId
#undef Tk_FreeStyleFromObj
#undef Tk_GetStyleFromObj
#undef TkWinGetPlatformId
#undef TkPutImage
#undef XPutImage
#define TkMacOSXSetUpClippingRgn (void (*)(Drawable))(void *)doNothing

#if defined(_WIN32) && !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#   define Tk_TranslateWinEvent TkTranslateWinEvent
#   define Tk_PointerEvent TkWinPointerEvent
#define TkWinGetPlatformId winGetPlatformId
static int TkWinGetPlatformId(void) {
    return 2;
}
#else
#   define Tk_TranslateWinEvent 0
#   define Tk_PointerEvent 0
#   define TkWinGetPlatformId 0
#endif

static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}

#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#define Tk_MainEx 0
#define Tk_FreeXId 0
#define Tk_FreeStyleFromObj 0
#define Tk_GetStyleFromObj 0
#define TkWinGetPlatformId 0
#define Tk_PhotoPutBlock_NoComposite 0
#define Tk_PhotoPutZoomedBlock_NoComposite 0
#define Tk_PhotoExpand_Panic 0
#define Tk_PhotoPutBlock_Panic 0
#define Tk_PhotoPutZoomedBlock_Panic 0
#define Tk_PhotoSetSize_Panic 0
#define Tk_CreateOldPhotoImageFormat 0
#else
#define Tk_FreeXId ((void (*)(Display *, XID))(void *)doNothing)
#define Tk_FreeStyleFromObj ((void (*)(Tcl_Obj *))(void *)doNothing)
#define Tk_GetStyleFromObj getStyleFromObj
static Tk_Style Tk_GetStyleFromObj(Tcl_Obj *obj)
{
	return Tk_AllocStyleFromObj(NULL, obj);
}
#endif /* !TK_NO_DEPRECATED */

#define TkpCmapStressed_ TkpCmapStressed
#define TkpSync_ TkpSync
#define TkUnixContainerId_ TkUnixContainerId
#define TkUnixDoOneXEvent_ TkUnixDoOneXEvent
#define TkUnixSetMenubar_ TkUnixSetMenubar
#define TkWmCleanup_ TkWmCleanup
#define TkSendCleanup_ TkSendCleanup
#define TkpTestsendCmd_ TkpTestsendCmd
#define TkGenWMConfigureEvent_ TkGenWMConfigureEvent
#define TkGenerateActivateEvents_ TkGenerateActivateEvents
#define TkMacOSXDrawable Tk_MacOSXGetNSWindowForDrawable
#define Tk_CanvasTagsParseProc \
		(int (*) (void *, Tcl_Interp *,Tk_Window, const char *, char *, \
		int offset))(void *)TkCanvasTagsParseProc
#define Tk_CanvasTagsPrintProc \
		(const char *(*) (void *,Tk_Window, char *, int, \
		Tcl_FreeProc **))(void *)TkCanvasTagsPrintProc

#if !defined(MAC_OSX_TK) && defined(MAC_OSX_TCL)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget ((int (*)(Tk_Window))(void *)doNothing)
#   define TkpRedrawWidget ((void (*)(Tk_Window))(void *)doNothing)
#endif

#ifdef _WIN32

int
TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
{
    (void)tkwin;
    (void)colormap;

    /* dummy implementation, no need to do anything */
    return 0;
}
void
TkpSync(Display *display)
{
    (void)display;
    /* dummy implementation, no need to do anything */
}

void
TkCreateXEventSource(void)
{
    TkWinXInit(Tk_GetHINSTANCE());
}


































#   define TkUnixContainerId 0
#   define TkUnixDoOneXEvent 0
#   define TkUnixSetMenubar 0
#   define TkWmCleanup (void (*)(TkDisplay *))(void *)TkpSync
#   define TkSendCleanup (void (*)(TkDisplay *))(void *)TkpSync
#   define TkpTestsendCmd 0







#else /* !_WIN32 */

/*
 * Make sure that extensions which call XParseColor through the stub
 * table, call TkParseColor instead. [Bug 3486474]
 */
#   define XParseColor	TkParseColor

#   ifdef __CYGWIN__



/*
 * Trick, so we don't have to include <windows.h> here, which in any
 * case lacks this function anyway.
 */

#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS	0x00000004
#ifdef __cplusplus
extern "C" {
#endif
int __stdcall GetModuleHandleExW(unsigned int, const char *, void *);
#ifdef __cplusplus



}
#endif




void
TkSetPixmapColormap(
    Pixmap pixmap,
    Colormap colormap)
{
    (void)pixmap;
    (void)colormap;
}

void
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold
				 * the hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
}

int
TkPutImage(
    unsigned long *colors,	/* Array of pixel values used by this image.
				 * May be NULL. */
    int ncolors,		/* Number of colors used, or 0. */
    Display *display,
    Drawable d,			/* Destination drawable. */
    GC gc,
    XImage *image,		/* Source image. */
    int src_x, int src_y,	/* Offset of subimage. */
    int dest_x, int dest_y,	/* Position of subimage origin in drawable. */
    unsigned int width, unsigned int height)
				/* Dimensions of subimage. */
{


    (void)colors;




    (void)ncolors;




    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);



}


























	/* TODO: To be implemented for Cygwin */
#	define Tk_AttachHWND 0
#	define Tk_GetHWND 0
#	define Tk_HWNDToWindow 0


#	define TkAlignImageData 0
#	define TkpGetMS 0
#	define TkpGetCapture 0
#	define TkPointerDeadWindow 0
#	define TkpSetCapture 0
#	define TkpSetCursor 0
#	define TkWinCancelMouseTimer 0
#	define TkWinClipboardRender 0
#	define TkWinEmbeddedEventProc 0
#	define TkWinFillRect 0













|





|






<






<
|
<
<
<

<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<








<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|

>
>
>
>
>
>

|









>
>






<
<
<

|
>
>
>
|
|
>
>
>






<
<








|
















>
>
|
>
>
>
>
|
>
|
>
>
|
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32

33



34








35












36
37
38
39
40
41
42
43

44

























































45







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * 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 "tkInt.h"

#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
/* UNIX */
#define UNIX_TK
#include "tkUnixInt.h"
#endif

#ifdef __WIN32__
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"

#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"


#define TkUnusedStubEntry NULL












#ifdef __WIN32__













static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}


#define TkCreateXEventSource TkPlatCreateXEventSource

























































static void







TkCreateXEventSource(void)
{
	TkWinXInit(Tk_GetHINSTANCE());
}

#undef XFree
#define XFree TkPlatXFree
static int
XFree(void *data)
{
	if (data != NULL) {
		ckfree((char *) data);
	}
	return 0;
}

#undef XVisualIDFromVisual
#define XVisualIDFromVisual TkPlatXVisualIDFromVisual
static VisualID
XVisualIDFromVisual(Visual *visual)
{
    return visual->visualid;
}

/*
 * Remove macros that will interfere with the definitions below.
 */
#   undef TkpCmapStressed
#   undef TkpSync
#   undef XFlush
#   undef XGrabServer
#   undef XUngrabServer
#   undef XNoOp
#   undef XSynchronize
#   undef XSync

#   define TkpCmapStressed (int (*) (Tk_Window, Colormap))(void *)doNothing
#   define TkpSync (void (*) (Display *))(void *)doNothing
#   define TkUnixContainerId 0
#   define TkUnixDoOneXEvent 0
#   define TkUnixSetMenubar 0
#   define TkWmCleanup (void (*) (TkDisplay *))(void *)doNothing
#   define TkSendCleanup (void (*) (TkDisplay *))(void *)doNothing
#   define TkpTestsendCmd 0
#   define XFlush (int (*) (Display *))(void *)doNothing
#   define XGrabServer (int (*) (Display *))(void *)doNothing
#   define XUngrabServer (int (*) (Display *))(void *)doNothing
#   define XNoOp (int (*) (Display *))(void *)doNothing
#   define XSynchronize (XAfterFunction (*) (Display *, Bool))(void *)doNothing
#   define XSync (int (*) (Display *, Bool))(void *)doNothing

#else /* !__WIN32__ */

/*
 * Make sure that extensions which call XParseColor through the stub
 * table, call TkParseColor instead. [Bug 3486474]
 */
#   define XParseColor	TkParseColor

#   ifdef __CYGWIN__

	TkIntStubs tkIntStubs;

/*
 * Trick, so we don't have to include <windows.h> here, which in any
 * case lacks this function anyway.
 */

#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS	0x00000004



int __stdcall GetModuleHandleExW(unsigned int, const char *, void *);

void *Tk_GetHINSTANCE()
{
    void *hInstance = NULL;

    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
	    (const char *) &tkIntStubs, &hInstance);
    return hInstance;
}

void
TkSetPixmapColormap(
    Pixmap pixmap,
    Colormap colormap)
{


}

void
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold
				 * the hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
	sprintf(buf, "%#08lx", (unsigned long) (window));
}

int
TkPutImage(
    unsigned long *colors,	/* Array of pixel values used by this image.
				 * May be NULL. */
    int ncolors,		/* Number of colors used, or 0. */
    Display *display,
    Drawable d,			/* Destination drawable. */
    GC gc,
    XImage *image,		/* Source image. */
    int src_x, int src_y,	/* Offset of subimage. */
    int dest_x, int dest_y,	/* Position of subimage origin in drawable. */
    unsigned int width, unsigned int height)
				/* Dimensions of subimage. */
{
    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
}

TkRegion TkCreateRegion()
{
    return (TkRegion) XCreateRegion();
}

void TkDestroyRegion(TkRegion r)
{
    XDestroyRegion((Region)r);
}

void TkSetRegion(Display *d, GC g, TkRegion r)
{
    XSetRegion(d, g, (Region)r);
}

void TkUnionRectWithRegion(XRectangle *a, TkRegion b, TkRegion c)
{
    XUnionRectWithRegion(a, (Region) b, (Region) c);
}

void TkClipBox(TkRegion a, XRectangle *b)
{
    XClipBox((Region) a, b);
}

void TkIntersectRegion(TkRegion a, TkRegion b, TkRegion c)
{
    XIntersectRegion((Region) a, (Region) b, (Region) c);
}

int TkRectInRegion (TkRegion r, int a, int b, unsigned int c, unsigned int d)
{
    return XRectInRegion((Region) r, a, b, c, d);
}

void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
{
    XSubtractRegion((Region) a, (Region) b, (Region) c);
}

	/* TODO: To be implemented for Cygwin */
#	define Tk_AttachHWND 0
#	define Tk_GetHWND 0
#	define Tk_HWNDToWindow 0
#	define Tk_PointerEvent 0
#	define Tk_TranslateWinEvent 0
#	define TkAlignImageData 0
#	define TkGenerateActivateEvents 0
#	define TkpGetMS 0
#	define TkPointerDeadWindow 0
#	define TkpSetCapture 0
#	define TkpSetCursor 0
#	define TkWinCancelMouseTimer 0
#	define TkWinClipboardRender 0
#	define TkWinEmbeddedEventProc 0
#	define TkWinFillRect 0
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269




270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#	define TkWinSetWindowPos 0
#	define TkWinWmCleanup 0
#	define TkWinXCleanup 0
#	define TkWinXInit 0
#	define TkWinSetForegroundWindow 0
#	define TkWinDialogDebug 0
#	define TkWinGetMenuSystemDefault 0

#	define TkWinSetHINSTANCE 0
#	define TkWinGetPlatformTheme 0
#	define TkWinChildProc 0

#   endif
#endif /* !_WIN32 */

#if defined(MAC_OSX_TCL)

int
TkPutImage(

    unsigned long *colors,	/* Array of pixel values used by this image.
				 * May be NULL. */
    int ncolors,		/* Number of colors used, or 0. */
    Display *display,
    Drawable d,			/* Destination drawable. */
    GC gc,
    XImage *image,		/* Source image. */
    int src_x, int src_y,	/* Offset of subimage. */
    int dest_x, int dest_y,	/* Position of subimage origin in drawable. */
    unsigned int width, unsigned int height)
				/* Dimensions of subimage. */
{
	(void)colors;

	(void)ncolors;

    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
}




#endif /* MAC_OSX_TCL */


/*
 * WARNING: The contents of this file is automatically generated by the
 * tools/genStubs.tcl script. Any modifications to the function declarations
 * below should be made in the generic/tk.decls script.
 */

#ifdef __GNUC__
/*
 * The rest of this file shouldn't warn about deprecated functions; they're
 * there because we intend them to be so and know that this file is OK to
 * touch those fields.
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
/* !BEGIN!: Do not edit below this line. */

static const TkIntStubs tkIntStubs = {
    TCL_STUB_MAGIC,
    0,

    TkAllocWindow, /* 0 */
    TkBezierPoints, /* 1 */
    TkBezierScreenPoints, /* 2 */
    0, /* 3 */
    TkBindEventProc, /* 4 */
    TkBindFree, /* 5 */
    TkBindInit, /* 6 */
    TkChangeEventWindow, /* 7 */
    TkClipInit, /* 8 */
    TkComputeAnchor, /* 9 */
    0, /* 10 */
    0, /* 11 */
    TkCreateCursorFromData, /* 12 */
    TkCreateFrame, /* 13 */
    TkCreateMainWindow, /* 14 */
    TkCurrentTime, /* 15 */
    TkDeleteAllImages, /* 16 */
    TkDoConfigureNotify, /* 17 */
    TkDrawInsetFocusHighlight, /* 18 */







>




|
<

|

|
|
>
|
|
|
|
<
<
<
<
<
<
|
|
|
>
|
|
<
<
>
>
>
>
|
|







<
<
<
<
<
<
<
<


|

<
>



|






|
|







226
227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248






249
250
251
252
253
254


255
256
257
258
259
260
261
262
263
264
265
266
267








268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#	define TkWinSetWindowPos 0
#	define TkWinWmCleanup 0
#	define TkWinXCleanup 0
#	define TkWinXInit 0
#	define TkWinSetForegroundWindow 0
#	define TkWinDialogDebug 0
#	define TkWinGetMenuSystemDefault 0
#	define TkWinGetPlatformId 0
#	define TkWinSetHINSTANCE 0
#	define TkWinGetPlatformTheme 0
#	define TkWinChildProc 0

#	define TkBindDeadWindow 0 /* On purpose not in Cygwin's stub table */


#   elif !defined(MAC_OSX_TK) /* UNIX */

#	undef TkClipBox
#	undef TkCreateRegion
#	undef TkDestroyRegion
#	undef TkIntersectRegion
#	undef TkRectInRegion
#	undef TkSetRegion
#	undef TkUnionRectWithRegion






#	undef TkSubtractRegion

#	define TkClipBox (void (*) (TkRegion, XRectangle *)) XClipBox
#	define TkCreateRegion (TkRegion (*) ()) XCreateRegion
#	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__ */

/*
 * WARNING: The contents of this file is automatically generated by the
 * tools/genStubs.tcl script. Any modifications to the function declarations
 * below should be made in the generic/tk.decls script.
 */









/* !BEGIN!: Do not edit below this line. */

TkIntStubs tkIntStubs = {
    TCL_STUB_MAGIC,

    NULL,
    TkAllocWindow, /* 0 */
    TkBezierPoints, /* 1 */
    TkBezierScreenPoints, /* 2 */
    TkBindDeadWindow, /* 3 */
    TkBindEventProc, /* 4 */
    TkBindFree, /* 5 */
    TkBindInit, /* 6 */
    TkChangeEventWindow, /* 7 */
    TkClipInit, /* 8 */
    TkComputeAnchor, /* 9 */
    TkCopyAndGlobalEval, /* 10 */
    TkCreateBindingProcedure, /* 11 */
    TkCreateCursorFromData, /* 12 */
    TkCreateFrame, /* 13 */
    TkCreateMainWindow, /* 14 */
    TkCurrentTime, /* 15 */
    TkDeleteAllImages, /* 16 */
    TkDoConfigureNotify, /* 17 */
    TkDrawInsetFocusHighlight, /* 18 */
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
    TkPointerEvent, /* 69 */
    TkPolygonToArea, /* 70 */
    TkPolygonToPoint, /* 71 */
    TkPositionInTree, /* 72 */
    TkpRedirectKeyEvent, /* 73 */
    TkpSetMainMenubar, /* 74 */
    TkpUseWindow, /* 75 */
    0, /* 76 */
    TkQueueEventForAllChildren, /* 77 */
    TkReadBitmapFile, /* 78 */
    TkScrollWindow, /* 79 */
    TkSelDeadWindow, /* 80 */
    TkSelEventProc, /* 81 */
    TkSelInit, /* 82 */
    TkSelPropProc, /* 83 */
    0, /* 84 */
    TkSetWindowMenuBar, /* 85 */
    TkStringToKeysym, /* 86 */
    TkThickPolyLineToArea, /* 87 */
    TkWmAddToColormapWindows, /* 88 */
    TkWmDeadWindow, /* 89 */
    TkWmFocusToplevel, /* 90 */
    TkWmMapWindow, /* 91 */







|







|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    TkPointerEvent, /* 69 */
    TkPolygonToArea, /* 70 */
    TkPolygonToPoint, /* 71 */
    TkPositionInTree, /* 72 */
    TkpRedirectKeyEvent, /* 73 */
    TkpSetMainMenubar, /* 74 */
    TkpUseWindow, /* 75 */
    TkpWindowWasRecentlyDeleted, /* 76 */
    TkQueueEventForAllChildren, /* 77 */
    TkReadBitmapFile, /* 78 */
    TkScrollWindow, /* 79 */
    TkSelDeadWindow, /* 80 */
    TkSelEventProc, /* 81 */
    TkSelInit, /* 82 */
    TkSelPropProc, /* 83 */
    NULL, /* 84 */
    TkSetWindowMenuBar, /* 85 */
    TkStringToKeysym, /* 86 */
    TkThickPolyLineToArea, /* 87 */
    TkWmAddToColormapWindows, /* 88 */
    TkWmDeadWindow, /* 89 */
    TkWmFocusToplevel, /* 90 */
    TkWmMapWindow, /* 91 */
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
    TkGetDisplayList, /* 106 */
    TkGetMainInfoList, /* 107 */
    TkGetWindowFromObj, /* 108 */
    TkpGetString, /* 109 */
    TkpGetSubFonts, /* 110 */
    TkpGetSystemDefault, /* 111 */
    TkpMenuThreadInit, /* 112 */
    XClipBox, /* 113 */
    XCreateRegion, /* 114 */
    XDestroyRegion, /* 115 */
    XIntersectRegion, /* 116 */
    XRectInRegion, /* 117 */
    XSetRegion, /* 118 */
    XUnionRectWithRegion, /* 119 */
    0, /* 120 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 121 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 121 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 121 */ /* Dummy entry for stubs table backwards compatibility */
    TkpCreateNativeBitmap, /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 122 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 122 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 122 */ /* Dummy entry for stubs table backwards compatibility */
    TkpDefineNativeBitmaps, /* 122 */
#endif /* AQUA */
    0, /* 123 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 124 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 124 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 124 */ /* Dummy entry for stubs table backwards compatibility */
    TkpGetNativeAppBitmap, /* 124 */
#endif /* AQUA */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    0, /* 129 */
    0, /* 130 */
    0, /* 131 */
    0, /* 132 */
    0, /* 133 */
    0, /* 134 */
    TkpDrawHighlightBorder, /* 135 */
    TkSetFocusWin, /* 136 */
    TkpSetKeycodeAndState, /* 137 */
    TkpGetKeySym, /* 138 */
    TkpInitKeymapInfo, /* 139 */
    TkPhotoGetValidRegion, /* 140 */
    TkWmStackorderToplevel, /* 141 */
    TkFocusFree, /* 142 */
    TkClipCleanup, /* 143 */
    TkGCCleanup, /* 144 */
    XSubtractRegion, /* 145 */
    TkStylePkgInit, /* 146 */
    TkStylePkgFree, /* 147 */
    TkToplevelWindowForCommand, /* 148 */
    TkGetOptionSpec, /* 149 */
    TkMakeRawCurve, /* 150 */
    TkMakeRawCurvePostscript, /* 151 */
    TkpDrawFrame, /* 152 */
    TkCreateThreadExitHandler, /* 153 */
    TkDeleteThreadExitHandler, /* 154 */
    0, /* 155 */
    TkpTestembedCmd, /* 156 */
    TkpTesttextCmd, /* 157 */
    TkSelGetSelection, /* 158 */
    TkTextGetIndex, /* 159 */
    TkTextIndexBackBytes, /* 160 */
    TkTextIndexForwBytes, /* 161 */
    TkTextMakeByteIndex, /* 162 */
    TkTextPrintIndex, /* 163 */
    TkTextSetMark, /* 164 */
    TkTextXviewCmd, /* 165 */
    TkTextChanged, /* 166 */
    TkBTreeNumLines, /* 167 */
    TkTextInsertDisplayProc, /* 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 */
    TkDrawAngledTextLayout, /* 181 */
    TkUnderlineAngledTextLayout, /* 182 */
    TkIntersectAngledTextLayout, /* 183 */
    TkDrawAngledChars, /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    0, /* 185 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 185 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpRedrawWidget, /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    0, /* 186 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 186 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpWillDrawWidget, /* 186 */
#endif /* MACOSX */
    TkDebugPhotoStringMatchDef, /* 187 */
};

static const TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,
    0,

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    TkAlignImageData, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpGetMS, /* 3 */
    TkPointerDeadWindow, /* 4 */
    TkpPrintWindowId, /* 5 */
    TkpScanWindowId, /* 6 */
    TkpSetCapture, /* 7 */
    TkpSetCursor, /* 8 */







|
|
|
|
|
|
|
|
|
|

|
|


|


|
|

|
|


|


|
|
|

|
|


|


|
|
|
|
|
|
|
|
|
|










|









|


|
|
|
|
|
|
|
|
|
|
|












|
|
|
<
<
|
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<


|

<
>
|

|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483


484


485





486








487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
    TkGetDisplayList, /* 106 */
    TkGetMainInfoList, /* 107 */
    TkGetWindowFromObj, /* 108 */
    TkpGetString, /* 109 */
    TkpGetSubFonts, /* 110 */
    TkpGetSystemDefault, /* 111 */
    TkpMenuThreadInit, /* 112 */
    TkClipBox, /* 113 */
    TkCreateRegion, /* 114 */
    TkDestroyRegion, /* 115 */
    TkIntersectRegion, /* 116 */
    TkRectInRegion, /* 117 */
    TkSetRegion, /* 118 */
    TkUnionRectWithRegion, /* 119 */
    NULL, /* 120 */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
    NULL, /* 121 */
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    NULL, /* 121 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    NULL, /* 121 */ /* Dummy entry for stubs table backwards compatibility */
    TkpCreateNativeBitmap, /* 121 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
    NULL, /* 122 */
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    NULL, /* 122 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    NULL, /* 122 */ /* Dummy entry for stubs table backwards compatibility */
    TkpDefineNativeBitmaps, /* 122 */
#endif /* AQUA */
    NULL, /* 123 */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
    NULL, /* 124 */
#endif /* X11 */
#if defined(__WIN32__) /* WIN */
    NULL, /* 124 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    NULL, /* 124 */ /* Dummy entry for stubs table backwards compatibility */
    TkpGetNativeAppBitmap, /* 124 */
#endif /* AQUA */
    NULL, /* 125 */
    NULL, /* 126 */
    NULL, /* 127 */
    NULL, /* 128 */
    NULL, /* 129 */
    NULL, /* 130 */
    NULL, /* 131 */
    NULL, /* 132 */
    NULL, /* 133 */
    NULL, /* 134 */
    TkpDrawHighlightBorder, /* 135 */
    TkSetFocusWin, /* 136 */
    TkpSetKeycodeAndState, /* 137 */
    TkpGetKeySym, /* 138 */
    TkpInitKeymapInfo, /* 139 */
    TkPhotoGetValidRegion, /* 140 */
    TkWmStackorderToplevel, /* 141 */
    TkFocusFree, /* 142 */
    TkClipCleanup, /* 143 */
    TkGCCleanup, /* 144 */
    TkSubtractRegion, /* 145 */
    TkStylePkgInit, /* 146 */
    TkStylePkgFree, /* 147 */
    TkToplevelWindowForCommand, /* 148 */
    TkGetOptionSpec, /* 149 */
    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 */
    NULL, /* 181 */
    NULL, /* 182 */
    NULL, /* 183 */


    NULL, /* 184 */


    NULL, /* 185 */





    TkUnusedStubEntry, /* 186 */








};

TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,

    NULL,
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    TkAlignImageData, /* 0 */
    NULL, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpGetMS, /* 3 */
    TkPointerDeadWindow, /* 4 */
    TkpPrintWindowId, /* 5 */
    TkpScanWindowId, /* 6 */
    TkpSetCapture, /* 7 */
    TkpSetCursor, /* 8 */
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
    TkpSync, /* 39 */
    TkUnixContainerId, /* 40 */
    TkUnixDoOneXEvent, /* 41 */
    TkUnixSetMenubar, /* 42 */
    TkWmCleanup, /* 43 */
    TkSendCleanup, /* 44 */
    TkpTestsendCmd, /* 45 */
    0, /* 46 */
    TkpGetCapture, /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    TkGenerateActivateEvents, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents_, /* 2 */
    TkPointerDeadWindow, /* 3 */
    TkpSetCapture, /* 4 */
    TkpSetCursor, /* 5 */
    TkpWmSetState, /* 6 */
    TkAboutDlg, /* 7 */
    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    0, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    0, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    0, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
    0, /* 19 */
    0, /* 20 */
    TkMacOSXInvalidateWindow, /* 21 */
    TkMacOSXIsCharacterMissing, /* 22 */
    TkMacOSXMakeRealWindowExist, /* 23 */
    TkMacOSXMakeStippleMap, /* 24 */
    TkMacOSXMenuClick, /* 25 */
    0, /* 26 */
    TkMacOSXResizable, /* 27 */
    TkMacOSXSetHelpMenuItemCount, /* 28 */
    TkMacOSXSetScrollbarGrow, /* 29 */
    TkMacOSXSetUpClippingRgn, /* 30 */
    TkMacOSXSetUpGraphicsPort, /* 31 */
    TkMacOSXUpdateClipRgn, /* 32 */
    0, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
    TkSetMacColor, /* 38 */
    TkSetWMName, /* 39 */
    0, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkpGetCapture, /* 47 */
    0, /* 48 */
    TkMacOSXGetContainer, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */
    TkpGetMS, /* 53 */
    TkMacOSXDrawable, /* 54 */
    TkpScanWindowId, /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    TkCreateXEventSource, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpCmapStressed, /* 3 */
    TkpSync, /* 4 */
    TkUnixContainerId, /* 5 */
    TkUnixDoOneXEvent, /* 6 */
    TkUnixSetMenubar, /* 7 */
    TkpScanWindowId, /* 8 */
    TkWmCleanup, /* 9 */
    TkSendCleanup, /* 10 */
    0, /* 11 */
    TkpWmSetState, /* 12 */
    TkpTestsendCmd, /* 13 */
    0, /* 14 */
    0, /* 15 */
    0, /* 16 */
    0, /* 17 */
    0, /* 18 */
    0, /* 19 */
    0, /* 20 */
    0, /* 21 */
    0, /* 22 */
    0, /* 23 */
    0, /* 24 */
    0, /* 25 */
    0, /* 26 */
    0, /* 27 */
    0, /* 28 */
    0, /* 29 */
    0, /* 30 */
    0, /* 31 */
    0, /* 32 */
    0, /* 33 */
    0, /* 34 */
    0, /* 35 */
    0, /* 36 */
    0, /* 37 */
    TkpCmapStressed_, /* 38 */
    TkpSync_, /* 39 */
    TkUnixContainerId_, /* 40 */
    TkUnixDoOneXEvent_, /* 41 */
    TkUnixSetMenubar_, /* 42 */
    TkWmCleanup_, /* 43 */
    TkSendCleanup_, /* 44 */
    TkpTestsendCmd_, /* 45 */
#endif /* X11 */
};

static const TkIntXlibStubs tkIntXlibStubs = {
    TCL_STUB_MAGIC,
    0,

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */







<
<



|
|








|

|

|



|
|





|






|






|






|
|
|







|

|
|








|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|

<
>
|







532
533
534
535
536
537
538


539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
































613
614
615
616
617

618
619
620
621
622
623
624
625
626
    TkpSync, /* 39 */
    TkUnixContainerId, /* 40 */
    TkUnixDoOneXEvent, /* 41 */
    TkUnixSetMenubar, /* 42 */
    TkWmCleanup, /* 43 */
    TkSendCleanup, /* 44 */
    TkpTestsendCmd, /* 45 */


#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    TkGenerateActivateEvents, /* 0 */
    NULL, /* 1 */
    NULL, /* 2 */
    TkPointerDeadWindow, /* 3 */
    TkpSetCapture, /* 4 */
    TkpSetCursor, /* 5 */
    TkpWmSetState, /* 6 */
    TkAboutDlg, /* 7 */
    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    TkMacOSXInstallCursor, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    NULL, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    NULL, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
    NULL, /* 19 */
    NULL, /* 20 */
    TkMacOSXInvalidateWindow, /* 21 */
    TkMacOSXIsCharacterMissing, /* 22 */
    TkMacOSXMakeRealWindowExist, /* 23 */
    TkMacOSXMakeStippleMap, /* 24 */
    TkMacOSXMenuClick, /* 25 */
    TkMacOSXRegisterOffScreenWindow, /* 26 */
    TkMacOSXResizable, /* 27 */
    TkMacOSXSetHelpMenuItemCount, /* 28 */
    TkMacOSXSetScrollbarGrow, /* 29 */
    TkMacOSXSetUpClippingRgn, /* 30 */
    TkMacOSXSetUpGraphicsPort, /* 31 */
    TkMacOSXUpdateClipRgn, /* 32 */
    TkMacOSXUnregisterMacWindow, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
    TkSetMacColor, /* 38 */
    TkSetWMName, /* 39 */
    TkSuspendClipboard, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkMacOSXGetCapture, /* 47 */
    NULL, /* 48 */
    TkGetTransientMaster, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */
    TkpGetMS, /* 53 */
    TkMacOSXDrawable, /* 54 */
    TkpScanWindowId, /* 55 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    TkCreateXEventSource, /* 0 */
    TkFreeWindowId, /* 1 */
    TkInitXId, /* 2 */
    TkpCmapStressed, /* 3 */
    TkpSync, /* 4 */
    TkUnixContainerId, /* 5 */
    TkUnixDoOneXEvent, /* 6 */
    TkUnixSetMenubar, /* 7 */
    TkpScanWindowId, /* 8 */
    TkWmCleanup, /* 9 */
    TkSendCleanup, /* 10 */
    TkFreeXId, /* 11 */
    TkpWmSetState, /* 12 */
    TkpTestsendCmd, /* 13 */
































#endif /* X11 */
};

TkIntXlibStubs tkIntXlibStubs = {
    TCL_STUB_MAGIC,

    NULL,
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */
    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    0, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */







|







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */
    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    NULL, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XSync, /* 113 */
    XVisualIDFromVisual, /* 114 */
    0, /* 115 */
    0, /* 116 */
    0, /* 117 */
    0, /* 118 */
    0, /* 119 */
    XOffsetRegion, /* 120 */
    XUnionRegion, /* 121 */
    XCreateWindow, /* 122 */
    0, /* 123 */
    0, /* 124 */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    XLowerWindow, /* 129 */
    XFillArcs, /* 130 */
    XDrawArcs, /* 131 */
    XDrawRectangles, /* 132 */
    XDrawSegments, /* 133 */
    XDrawPoint, /* 134 */
    XDrawPoints, /* 135 */
    XReparentWindow, /* 136 */
    XPutImage, /* 137 */
    XPolygonRegion, /* 138 */
    XPointInRegion, /* 139 */
    XVaCreateNestedList, /* 140 */
    XSetICValues, /* 141 */
    XGetICValues, /* 142 */
    XSetICFocus, /* 143 */
    0, /* 144 */
    0, /* 145 */
    0, /* 146 */
    XFreeFontSet, /* 147 */
    XCloseIM, /* 148 */
    XRegisterIMInstantiateCallback, /* 149 */
    XUnregisterIMInstantiateCallback, /* 150 */
    XSetLocaleModifiers, /* 151 */
    XOpenIM, /* 152 */
    XGetIMValues, /* 153 */
    XSetIMValues, /* 154 */
    XCreateFontSet, /* 155 */
    XFreeStringList, /* 156 */
    XkbKeycodeToKeysym, /* 157 */
    XkbOpenDisplay, /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|







728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XSync, /* 113 */
    XVisualIDFromVisual, /* 114 */
    NULL, /* 115 */
    NULL, /* 116 */
    NULL, /* 117 */
    NULL, /* 118 */
    NULL, /* 119 */
    NULL, /* 120 */
    NULL, /* 121 */
    NULL, /* 122 */
    NULL, /* 123 */
    NULL, /* 124 */
    NULL, /* 125 */
    NULL, /* 126 */
    NULL, /* 127 */
    NULL, /* 128 */
    NULL, /* 129 */
    NULL, /* 130 */
    NULL, /* 131 */
    NULL, /* 132 */
    XDrawSegments, /* 133 */
    XDrawPoint, /* 134 */
    XDrawPoints, /* 135 */
    NULL, /* 136 */
    NULL, /* 137 */
    NULL, /* 138 */
    NULL, /* 139 */
    NULL, /* 140 */
    NULL, /* 141 */
    NULL, /* 142 */
    NULL, /* 143 */
    NULL, /* 144 */
    NULL, /* 145 */
    NULL, /* 146 */
    NULL, /* 147 */
    NULL, /* 148 */
    NULL, /* 149 */
    NULL, /* 150 */
    NULL, /* 151 */
    NULL, /* 152 */
    NULL, /* 153 */
    NULL, /* 154 */
    NULL, /* 155 */
    NULL, /* 156 */
    NULL, /* 157 */
    TkUnusedStubEntry, /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    XDrawPoint, /* 85 */
    XDrawPoints, /* 86 */
    XWarpPointer, /* 87 */
    XQueryColor, /* 88 */
    XQueryColors, /* 89 */
    XQueryTree, /* 90 */
    XSync, /* 91 */
    XTranslateCoordinates, /* 92 */
    XDeleteProperty, /* 93 */
    XFreeCursor, /* 94 */
    XGetInputFocus, /* 95 */
    XmbLookupString, /* 96 */
    XNextEvent, /* 97 */
    XPutBackEvent, /* 98 */
    XSetCommand, /* 99 */
    XWindowEvent, /* 100 */
    XGetWindowAttributes, /* 101 */
    XGetWMColormapWindows, /* 102 */
    XIconifyWindow, /* 103 */
    XWithdrawWindow, /* 104 */
    XListHosts, /* 105 */
    XSetClipRectangles, /* 106 */
    XFlush, /* 107 */
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XLookupColor, /* 113 */
    XVisualIDFromVisual, /* 114 */
    0, /* 115 */
    0, /* 116 */
    0, /* 117 */
    0, /* 118 */
    0, /* 119 */
    XOffsetRegion, /* 120 */
    XUnionRegion, /* 121 */
    XCreateWindow, /* 122 */
    0, /* 123 */
    0, /* 124 */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    XLowerWindow, /* 129 */
    XFillArcs, /* 130 */
    XDrawArcs, /* 131 */
    XDrawRectangles, /* 132 */
    0, /* 133 */
    0, /* 134 */
    0, /* 135 */
    XReparentWindow, /* 136 */
    XPutImage, /* 137 */
    XPolygonRegion, /* 138 */
    XPointInRegion, /* 139 */
    XVaCreateNestedList, /* 140 */
    XSetICValues, /* 141 */
    XGetICValues, /* 142 */
    XSetICFocus, /* 143 */
    XDestroyIC, /* 144 */
    XCreatePixmapCursor, /* 145 */
    XCreateGlyphCursor, /* 146 */
    XFreeFontSet, /* 147 */
    XCloseIM, /* 148 */
    XRegisterIMInstantiateCallback, /* 149 */
    XUnregisterIMInstantiateCallback, /* 150 */
    XSetLocaleModifiers, /* 151 */
    XOpenIM, /* 152 */
    XGetIMValues, /* 153 */
    XSetIMValues, /* 154 */
    XCreateFontSet, /* 155 */
    XFreeStringList, /* 156 */
    XkbKeycodeToKeysym, /* 157 */
    XkbOpenDisplay, /* 158 */
#endif /* MACOSX */
};

static const TkPlatStubs tkPlatStubs = {
    TCL_STUB_MAGIC,
    0,

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Tk_AttachHWND, /* 0 */
    Tk_GetHINSTANCE, /* 1 */
    Tk_GetHWND, /* 2 */
    Tk_HWNDToWindow, /* 3 */
    Tk_PointerEvent, /* 4 */
    Tk_TranslateWinEvent, /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 0 */
    0, /* 1 */
    0, /* 2 */
    0, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    TkGenWMConfigureEvent_, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    0, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    Tk_MacOSXGetTkWindow, /* 11 */
    Tk_MacOSXGetCGContextForDrawable, /* 12 */
    Tk_MacOSXGetNSWindowForDrawable, /* 13 */
    0, /* 14 */
    0, /* 15 */
    TkGenWMConfigureEvent, /* 16 */
#endif /* AQUA */
};

static const TkStubHooks tkStubHooks = {
    &tkPlatStubs,
    &tkIntStubs,
    &tkIntPlatStubs,
    &tkIntXlibStubs
};

const TkStubs tkStubs = {
    TCL_STUB_MAGIC,
    &tkStubHooks,
    Tk_MainLoop, /* 0 */
    Tk_3DBorderColor, /* 1 */
    Tk_3DBorderGC, /* 2 */
    Tk_3DHorizontalBevel, /* 3 */
    Tk_3DVerticalBevel, /* 4 */







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|

<
>
|








|
|
|
|

|

|



|
|
|
|
|
|



|






|







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944

945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
    XDrawPoint, /* 85 */
    XDrawPoints, /* 86 */
    XWarpPointer, /* 87 */
    XQueryColor, /* 88 */
    XQueryColors, /* 89 */
    XQueryTree, /* 90 */
    XSync, /* 91 */
    NULL, /* 92 */
    NULL, /* 93 */
    NULL, /* 94 */
    NULL, /* 95 */
    NULL, /* 96 */
    NULL, /* 97 */
    NULL, /* 98 */
    NULL, /* 99 */
    NULL, /* 100 */
    NULL, /* 101 */
    NULL, /* 102 */
    NULL, /* 103 */
    NULL, /* 104 */
    NULL, /* 105 */
    NULL, /* 106 */
    NULL, /* 107 */
    NULL, /* 108 */
    NULL, /* 109 */
    NULL, /* 110 */
    NULL, /* 111 */
    NULL, /* 112 */
    NULL, /* 113 */
    NULL, /* 114 */
    NULL, /* 115 */
    NULL, /* 116 */
    NULL, /* 117 */
    NULL, /* 118 */
    NULL, /* 119 */
    NULL, /* 120 */
    NULL, /* 121 */
    NULL, /* 122 */
    NULL, /* 123 */
    NULL, /* 124 */
    NULL, /* 125 */
    NULL, /* 126 */
    NULL, /* 127 */
    NULL, /* 128 */
    NULL, /* 129 */
    NULL, /* 130 */
    NULL, /* 131 */
    NULL, /* 132 */
    NULL, /* 133 */
    NULL, /* 134 */
    NULL, /* 135 */
    NULL, /* 136 */
    NULL, /* 137 */
    NULL, /* 138 */
    NULL, /* 139 */
    NULL, /* 140 */
    NULL, /* 141 */
    NULL, /* 142 */
    NULL, /* 143 */
    NULL, /* 144 */
    NULL, /* 145 */
    NULL, /* 146 */
    NULL, /* 147 */
    NULL, /* 148 */
    NULL, /* 149 */
    NULL, /* 150 */
    NULL, /* 151 */
    NULL, /* 152 */
    NULL, /* 153 */
    NULL, /* 154 */
    NULL, /* 155 */
    NULL, /* 156 */
    NULL, /* 157 */
    TkUnusedStubEntry, /* 158 */
#endif /* AQUA */
};

TkPlatStubs tkPlatStubs = {
    TCL_STUB_MAGIC,

    NULL,
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
    Tk_AttachHWND, /* 0 */
    Tk_GetHINSTANCE, /* 1 */
    Tk_GetHWND, /* 2 */
    Tk_HWNDToWindow, /* 3 */
    Tk_PointerEvent, /* 4 */
    Tk_TranslateWinEvent, /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    Tk_MacOSXSetEmbedHandler, /* 0 */
    Tk_MacOSXTurnOffMenus, /* 1 */
    Tk_MacOSXTkOwnsCursor, /* 2 */
    TkMacOSXInitMenus, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    TkGenWMConfigureEvent, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    TkMacOSXGetDrawablePort, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    NULL, /* 11 */
    NULL, /* 12 */
    NULL, /* 13 */
    NULL, /* 14 */
    NULL, /* 15 */
    TkUnusedStubEntry, /* 16 */
#endif /* AQUA */
};

static TkStubHooks tkStubHooks = {
    &tkPlatStubs,
    &tkIntStubs,
    &tkIntPlatStubs,
    &tkIntXlibStubs
};

TkStubs tkStubs = {
    TCL_STUB_MAGIC,
    &tkStubHooks,
    Tk_MainLoop, /* 0 */
    Tk_3DBorderColor, /* 1 */
    Tk_3DBorderGC, /* 2 */
    Tk_3DHorizontalBevel, /* 3 */
    Tk_3DVerticalBevel, /* 4 */
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
    Tk_GetCursor, /* 91 */
    Tk_GetCursorFromData, /* 92 */
    Tk_GetFont, /* 93 */
    Tk_GetFontFromObj, /* 94 */
    Tk_GetFontMetrics, /* 95 */
    Tk_GetGC, /* 96 */
    Tk_GetImage, /* 97 */
    Tk_GetImageModelData, /* 98 */
    Tk_GetItemTypes, /* 99 */
    Tk_GetJoinStyle, /* 100 */
    Tk_GetJustify, /* 101 */
    Tk_GetNumMainWindows, /* 102 */
    Tk_GetOption, /* 103 */
    Tk_GetPixels, /* 104 */
    Tk_GetPixmap, /* 105 */







|







1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
    Tk_GetCursor, /* 91 */
    Tk_GetCursorFromData, /* 92 */
    Tk_GetFont, /* 93 */
    Tk_GetFontFromObj, /* 94 */
    Tk_GetFontMetrics, /* 95 */
    Tk_GetGC, /* 96 */
    Tk_GetImage, /* 97 */
    Tk_GetImageMasterData, /* 98 */
    Tk_GetItemTypes, /* 99 */
    Tk_GetJoinStyle, /* 100 */
    Tk_GetJustify, /* 101 */
    Tk_GetNumMainWindows, /* 102 */
    Tk_GetOption, /* 103 */
    Tk_GetPixels, /* 104 */
    Tk_GetPixmap, /* 105 */
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
    Tk_InitOptions, /* 211 */
    Tk_MainEx, /* 212 */
    Tk_RestoreSavedOptions, /* 213 */
    Tk_SetOptions, /* 214 */
    Tk_InitConsoleChannels, /* 215 */
    Tk_CreateConsoleWindow, /* 216 */
    Tk_CreateSmoothMethod, /* 217 */
    0, /* 218 */
    0, /* 219 */
    Tk_GetDash, /* 220 */
    Tk_CreateOutline, /* 221 */
    Tk_DeleteOutline, /* 222 */
    Tk_ConfigOutlineGC, /* 223 */
    Tk_ChangeOutlineGC, /* 224 */
    Tk_ResetOutlineGC, /* 225 */
    Tk_CanvasPsOutline, /* 226 */







|
|







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
    Tk_InitOptions, /* 211 */
    Tk_MainEx, /* 212 */
    Tk_RestoreSavedOptions, /* 213 */
    Tk_SetOptions, /* 214 */
    Tk_InitConsoleChannels, /* 215 */
    Tk_CreateConsoleWindow, /* 216 */
    Tk_CreateSmoothMethod, /* 217 */
    NULL, /* 218 */
    NULL, /* 219 */
    Tk_GetDash, /* 220 */
    Tk_CreateOutline, /* 221 */
    Tk_DeleteOutline, /* 222 */
    Tk_ConfigOutlineGC, /* 223 */
    Tk_ChangeOutlineGC, /* 224 */
    Tk_ResetOutlineGC, /* 225 */
    Tk_CanvasPsOutline, /* 226 */
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
    Tk_PhotoPutZoomedBlock, /* 267 */
    Tk_PhotoSetSize, /* 268 */
    Tk_GetUserInactiveTime, /* 269 */
    Tk_ResetUserInactiveTime, /* 270 */
    Tk_Interp, /* 271 */
    Tk_CreateOldImageType, /* 272 */
    Tk_CreateOldPhotoImageFormat, /* 273 */
    Tk_AlwaysShowSelection, /* 274 */
    Tk_GetButtonMask, /* 275 */
    Tk_GetDoublePixelsFromObj, /* 276 */
    Tk_NewWindowObj, /* 277 */
    Tk_SendVirtualEvent, /* 278 */
    Tk_FontGetDescription, /* 279 */

};

/* !END!: Do not edit above this line. */


#ifdef __CYGWIN__
void *Tk_GetHINSTANCE(void)
{
    void *hInstance = NULL;

    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
	    (const char *) &tkIntStubs, &hInstance);
    return hInstance;
}
#endif








|
|
|
|
|
|
>




|
<
<
<
<
|
<
<
<
<
<
<
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270




1271






    Tk_PhotoPutZoomedBlock, /* 267 */
    Tk_PhotoSetSize, /* 268 */
    Tk_GetUserInactiveTime, /* 269 */
    Tk_ResetUserInactiveTime, /* 270 */
    Tk_Interp, /* 271 */
    Tk_CreateOldImageType, /* 272 */
    Tk_CreateOldPhotoImageFormat, /* 273 */
    NULL, /* 274 */
    NULL, /* 275 */
    NULL, /* 276 */
    NULL, /* 277 */
    NULL, /* 278 */
    NULL, /* 279 */
    TkUnusedStubEntry, /* 280 */
};

/* !END!: Do not edit above this line. */

#undef UNIX_TK




#undef MAC_OSX_TK






Changes to generic/tkStubLib.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"

MODULE_SCOPE const TkStubs *tkStubsPtr;
MODULE_SCOPE const TkPlatStubs *tkPlatStubsPtr;
MODULE_SCOPE const TkIntStubs *tkIntStubsPtr;
MODULE_SCOPE const TkIntPlatStubs *tkIntPlatStubsPtr;
MODULE_SCOPE const TkIntXlibStubs *tkIntXlibStubsPtr;

const TkStubs *tkStubsPtr = NULL;
const TkPlatStubs *tkPlatStubsPtr = NULL;
const TkIntStubs *tkIntStubsPtr = NULL;
const TkIntPlatStubs *tkIntPlatStubsPtr = NULL;
const TkIntXlibStubs *tkIntXlibStubsPtr = NULL;

/*
 * Use our own isdigit to avoid linking to libc on windows
 */

static int
isDigit(const int c)







|







|







<
<
<
<
<
<
|
|
|
|
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31






32
33
34
35
36
37
38
39
40
41
42
43
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef __WIN32__
#include "tkWinInt.h"
#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif

#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"







TkStubs *tkStubsPtr = NULL;
TkPlatStubs *tkPlatStubsPtr = NULL;
TkIntStubs *tkIntStubsPtr = NULL;
TkIntPlatStubs *tkIntPlatStubsPtr = NULL;
TkIntXlibStubs *tkIntXlibStubsPtr = NULL;

/*
 * Use our own isdigit to avoid linking to libc on windows
 */

static int
isDigit(const int c)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 *
 * Side effects:
 *	Sets the stub table pointers.
 *
 *----------------------------------------------------------------------
 */
#undef Tk_InitStubs
MODULE_SCOPE const char *
Tk_InitStubs(
    Tcl_Interp *interp,
    const char *version,
    int exact)
{
    const char *packageName = "Tk";
    const char *errMsg = NULL;
    void *clientData = NULL;
    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);
    const TkStubs *stubsPtr = (const TkStubs *)clientData;

    if (actualVersion == NULL) {
	return NULL;
    }

    if (exact) {
	const char *p = version;
	int count = 0;

	while (*p) {
	    count += !isDigit(*p++);
	}
	if (count == 1) {
	    const char *q = actualVersion;

	    p = version;
	    while (*p && (*p == *q)) {
		p++; q++;
	    }
	    if (*p || isDigit(*q)) {
		/* Construct error message */
		tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 1, NULL);
		return NULL;
	    }
	} else {
	    actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName,
		    version, 1, NULL);
	    if (actualVersion == NULL) {
		return NULL;
	    }
	}
    }
    if (stubsPtr == NULL) {







|


|




|
|

|






|






|







|



|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 *
 * Side effects:
 *	Sets the stub table pointers.
 *
 *----------------------------------------------------------------------
 */
#undef Tk_InitStubs
CONST char *
Tk_InitStubs(
    Tcl_Interp *interp,
    CONST char *version,
    int exact)
{
    const char *packageName = "Tk";
    const char *errMsg = NULL;
    ClientData clientData = NULL;
    CONST char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);
    TkStubs *stubsPtr = (TkStubs *)clientData;

    if (actualVersion == NULL) {
	return NULL;
    }

    if (exact) {
	CONST char *p = version;
	int count = 0;

	while (*p) {
	    count += !isDigit(*p++);
	}
	if (count == 1) {
	    CONST char *q = actualVersion;

	    p = version;
	    while (*p && (*p == *q)) {
		p++; q++;
	    }
	    if (*p || isDigit(*q)) {
		/* Construct error message */
		tclStubsPtr->tcl_PkgRequireEx(interp, "Tk", version, 1, NULL);
		return NULL;
	    }
	} else {
	    actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, "Tk",
		    version, 1, NULL);
	    if (actualVersion == NULL) {
		return NULL;
	    }
	}
    }
    if (stubsPtr == NULL) {

Changes to generic/tkStyle.c.

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
				 * (by a derived element). */
} Element;

/*
 * Thread-local data.
 */

typedef struct {
    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
				 * pointers. */
    StyleEngine *defaultEnginePtr;
				/* Default, core-defined style engine. Global
				 * fallback for all engines. */







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
				 * (by a derived element). */
} Element;

/*
 * Thread-local data.
 */

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
				 * pointers. */
    StyleEngine *defaultEnginePtr;
				/* Default, core-defined style engine. Global
				 * fallback for all engines. */
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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.twoPtrValue.ptr1 field of each
 * style object points to the Style structure for the stylefont, or NULL.
 */

static const Tcl_ObjType styleObjType = {
    "style",			/* name */
    FreeStyleObjProc,		/* freeIntRepProc */
    DupStyleObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkStylePkgInit --
 *







|
|


|




|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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.twoPtrValue.ptr1 field of each style
 * object points to the Style structure for the stylefont, or NULL.
 */

static Tcl_ObjType styleObjType = {
    "style",			/* name */
    FreeStyleObjProc,		/* freeIntRepProc */
    DupStyleObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetStyleFromAny		/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkStylePkgInit --
 *
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgInit(
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->nbInit != 0) {
	return;
    }







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->nbInit != 0) {
	return;
    }
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
    tsdPtr->defaultEnginePtr = (StyleEngine *)
	    Tk_RegisterStyleEngine(NULL, NULL);

    /*
     * Create the default system style.
     */

    Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr, NULL);


    tsdPtr->nbInit++;
}

/*
 *---------------------------------------------------------------------------
 *







|
>







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    tsdPtr->defaultEnginePtr = (StyleEngine *)
	    Tk_RegisterStyleEngine(NULL, NULL);

    /*
     * Create the default system style.
     */

    Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr,
	    (ClientData) 0);

    tsdPtr->nbInit++;
}

/*
 *---------------------------------------------------------------------------
 *
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgFree(
    TCL_UNUSED(TkMainInfo *))	/* The application being deleted. */
{
    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;
    }

    /*
     * Free styles.
     */

    entryPtr = Tcl_FirstHashEntry(&tsdPtr->styleTable, &search);
    while (entryPtr != NULL) {
	ckfree(Tcl_GetHashValue(entryPtr));
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&tsdPtr->styleTable);

    /*
     * Free engines.
     */

    entryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search);
    while (entryPtr != NULL) {
	enginePtr = (StyleEngine *)Tcl_GetHashValue(entryPtr);
	FreeStyleEngine(enginePtr);
	ckfree(enginePtr);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&tsdPtr->engineTable);

    /*
     * Free elements.
     */

    for (i = 0; i < tsdPtr->nbElements; i++) {
	FreeElement(tsdPtr->elements+i);
    }
    Tcl_DeleteHashTable(&tsdPtr->elementTable);
    ckfree(tsdPtr->elements);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_RegisterStyleEngine --
 *







|



















|










|

|












|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    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;
    }

    /*
     * Free styles.
     */

    entryPtr = Tcl_FirstHashEntry(&tsdPtr->styleTable, &search);
    while (entryPtr != NULL) {
	ckfree((char *) Tcl_GetHashValue(entryPtr));
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&tsdPtr->styleTable);

    /*
     * Free engines.
     */

    entryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search);
    while (entryPtr != NULL) {
	enginePtr = (StyleEngine *) Tcl_GetHashValue(entryPtr);
	FreeStyleEngine(enginePtr);
	ckfree((char *) enginePtr);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&tsdPtr->engineTable);

    /*
     * Free elements.
     */

    for (i = 0; i < tsdPtr->nbElements; i++) {
	FreeElement(tsdPtr->elements+i);
    }
    Tcl_DeleteHashTable(&tsdPtr->elementTable);
    ckfree((char *) tsdPtr->elements);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_RegisterStyleEngine --
 *
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
	return NULL;
    }

    /*
     * Allocate and intitialize a new engine.
     */

    enginePtr = (StyleEngine *)ckalloc(sizeof(StyleEngine));
    InitStyleEngine(enginePtr, (const char *)Tcl_GetHashKey(&tsdPtr->engineTable, entryPtr),
	    (StyleEngine *) parent);
    Tcl_SetHashValue(entryPtr, enginePtr);

    return (Tk_StyleEngine) enginePtr;
}

/*
 *---------------------------------------------------------------------------
 *







|
|

|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
	return NULL;
    }

    /*
     * Allocate and intitialize a new engine.
     */

    enginePtr = (StyleEngine *) ckalloc(sizeof(StyleEngine));
    InitStyleEngine(enginePtr, Tcl_GetHashKey(&tsdPtr->engineTable, entryPtr),
	    (StyleEngine *) parent);
    Tcl_SetHashValue(entryPtr, (ClientData) enginePtr);

    return (Tk_StyleEngine) enginePtr;
}

/*
 *---------------------------------------------------------------------------
 *
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    }

    /*
     * Allocate and initialize elements array.
     */

    if (tsdPtr->nbElements > 0) {
	enginePtr->elements = (StyledElement *)ckalloc(
		sizeof(StyledElement) * tsdPtr->nbElements);
	for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	    InitStyledElement(enginePtr->elements+elementId);
	}
    } else {
	enginePtr->elements = NULL;
    }







|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
    }

    /*
     * Allocate and initialize elements array.
     */

    if (tsdPtr->nbElements > 0) {
	enginePtr->elements = (StyledElement *) ckalloc(
		sizeof(StyledElement) * tsdPtr->nbElements);
	for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	    InitStyledElement(enginePtr->elements+elementId);
	}
    } else {
	enginePtr->elements = NULL;
    }
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    /*
     * Free allocated elements.
     */

    for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	FreeStyledElement(enginePtr->elements+elementId);
    }
    ckfree(enginePtr->elements);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetStyleEngine --
 *







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    /*
     * Free allocated elements.
     */

    for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	FreeStyledElement(enginePtr->elements+elementId);
    }
    ckfree((char *) enginePtr->elements);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetStyleEngine --
 *
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    }

    entryPtr = Tcl_FindHashEntry(&tsdPtr->engineTable, (name!=NULL?name:""));
    if (!entryPtr) {
	return NULL;
    }

    return (Tk_StyleEngine)Tcl_GetHashValue(entryPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * InitElement --
 *







|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
    }

    entryPtr = Tcl_FindHashEntry(&tsdPtr->engineTable, (name!=NULL?name:""));
    if (!entryPtr) {
	return NULL;
    }

    return (Tk_StyleEngine) Tcl_GetHashValue(entryPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * InitElement --
 *
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeElement(
    TCL_UNUSED(Element *))	/* The element to free. */
{
    /* Nothing to do. */
}

/*
 *---------------------------------------------------------------------------
 *







|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeElement(
    Element *elementPtr)	/* The element to free. */
{
    /* Nothing to do. */
}

/*
 *---------------------------------------------------------------------------
 *
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
    /*
     * Free allocated widget specs.
     */

    for (i = 0; i < elementPtr->nbWidgetSpecs; i++) {
	FreeWidgetSpec(elementPtr->widgetSpecs+i);
    }
    ckfree(elementPtr->widgetSpecs);
}

/*
 *---------------------------------------------------------------------------
 *
 * CreateElement --
 *







|







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
    /*
     * Free allocated widget specs.
     */

    for (i = 0; i < elementPtr->nbWidgetSpecs; i++) {
	FreeWidgetSpec(elementPtr->widgetSpecs+i);
    }
    ckfree((char *) elementPtr->widgetSpecs);
}

/*
 *---------------------------------------------------------------------------
 *
 * CreateElement --
 *
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666

    dot = strchr(name, '.');
    if (dot) {
	genericId = CreateElement(dot+1, 0);
    }

    elementId = tsdPtr->nbElements++;
    Tcl_SetHashValue(entryPtr, INT2PTR(elementId));

    /*
     * Reallocate element table.
     */

    tsdPtr->elements = (Element *)ckrealloc(tsdPtr->elements,
	    sizeof(Element) * tsdPtr->nbElements);
    InitElement(tsdPtr->elements+elementId,
	    (const char *)Tcl_GetHashKey(&tsdPtr->elementTable, entryPtr), elementId,
	    genericId, create);

    /*
     * Reallocate style engines' element table.
     */

    engineEntryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search);
    while (engineEntryPtr != NULL) {
	enginePtr = (StyleEngine *)Tcl_GetHashValue(engineEntryPtr);

	enginePtr->elements = (StyledElement *)ckrealloc(enginePtr->elements,

		sizeof(StyledElement) * tsdPtr->nbElements);
	InitStyledElement(enginePtr->elements+elementId);

	engineEntryPtr = Tcl_NextHashEntry(&search);
    }

    return elementId;







|





|


|








|

|
>







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

    dot = strchr(name, '.');
    if (dot) {
	genericId = CreateElement(dot+1, 0);
    }

    elementId = tsdPtr->nbElements++;
    Tcl_SetHashValue(entryPtr, (ClientData) INT2PTR(elementId));

    /*
     * Reallocate element table.
     */

    tsdPtr->elements = (Element *) ckrealloc((char *) tsdPtr->elements,
	    sizeof(Element) * tsdPtr->nbElements);
    InitElement(tsdPtr->elements+elementId,
	    Tcl_GetHashKey(&tsdPtr->elementTable, entryPtr), elementId,
	    genericId, create);

    /*
     * Reallocate style engines' element table.
     */

    engineEntryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search);
    while (engineEntryPtr != NULL) {
	enginePtr = (StyleEngine *) Tcl_GetHashValue(engineEntryPtr);

	enginePtr->elements = (StyledElement *) ckrealloc(
		(char *) enginePtr->elements,
		sizeof(StyledElement) * tsdPtr->nbElements);
	InitStyledElement(enginePtr->elements+elementId);

	engineEntryPtr = Tcl_NextHashEntry(&search);
    }

    return elementId;
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
    Tk_ElementSpec *templatePtr)/* Static template information about the
				 * element. */
{
    int elementId;
    StyledElement *elementPtr;
    Tk_ElementSpec *specPtr;
    int nbOptions;
    Tk_ElementOptionSpec *srcOptions, *dstOptions;

    if (templatePtr->version != TK_STYLE_VERSION_1) {
	/*
	 * Version mismatch. Do nothing.
	 */

	return -1;







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
    Tk_ElementSpec *templatePtr)/* Static template information about the
				 * element. */
{
    int elementId;
    StyledElement *elementPtr;
    Tk_ElementSpec *specPtr;
    int nbOptions;
    register Tk_ElementOptionSpec *srcOptions, *dstOptions;

    if (templatePtr->version != TK_STYLE_VERSION_1) {
	/*
	 * Version mismatch. Do nothing.
	 */

	return -1;
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814

    /*
     * Initialize the styled element.
     */

    elementPtr = ((StyleEngine *) engine)->elements+elementId;

    specPtr = (Tk_ElementSpec *)ckalloc(sizeof(Tk_ElementSpec));
    specPtr->version = templatePtr->version;
    specPtr->name = (char *)ckalloc(strlen(templatePtr->name)+1);
    strcpy(specPtr->name, templatePtr->name);
    nbOptions = 0;
    for (nbOptions = 0, srcOptions = templatePtr->options;
	    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++) {
	if (srcOptions->name == NULL) {
	    dstOptions->name = NULL;
	    break;
	}

	dstOptions->name = (char *)ckalloc(strlen(srcOptions->name)+1);
	strcpy(dstOptions->name, srcOptions->name);
	dstOptions->type = srcOptions->type;
    }
    specPtr->getSize = templatePtr->getSize;
    specPtr->getBox = templatePtr->getBox;
    specPtr->getBorderWidth = templatePtr->getBorderWidth;
    specPtr->draw = templatePtr->draw;







|

|















|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

    /*
     * Initialize the styled element.
     */

    elementPtr = ((StyleEngine *) engine)->elements+elementId;

    specPtr = (Tk_ElementSpec *) ckalloc(sizeof(Tk_ElementSpec));
    specPtr->version = templatePtr->version;
    specPtr->name = ckalloc(strlen(templatePtr->name)+1);
    strcpy(specPtr->name, templatePtr->name);
    nbOptions = 0;
    for (nbOptions = 0, srcOptions = templatePtr->options;
	    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++) {
	if (srcOptions->name == NULL) {
	    dstOptions->name = NULL;
	    break;
	}

	dstOptions->name = ckalloc(strlen(srcOptions->name)+1);
	strcpy(dstOptions->name, srcOptions->name);
	dstOptions->type = srcOptions->type;
    }
    specPtr->getSize = templatePtr->getSize;
    specPtr->getBox = templatePtr->getBox;
    specPtr->getBorderWidth = templatePtr->getBorderWidth;
    specPtr->draw = templatePtr->draw;
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
	/* 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++) {
	widgetOptionPtr = TkGetOptionSpec(elementOptionPtr->name, optionTable);

	/*
	 * Check that the widget option type is compatible with one of the
	 * element's required types.







|
|







921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	/* 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++) {
	widgetOptionPtr = TkGetOptionSpec(elementOptionPtr->name, optionTable);

	/*
	 * Check that the widget option type is compatible with one of the
	 * element's required types.
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
 */

static void
FreeWidgetSpec(
    StyledWidgetSpec *widgetSpecPtr)
				/* The widget spec to free. */
{
    ckfree(widgetSpecPtr->optionsPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetWidgetSpec --
 *







|







962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
 */

static void
FreeWidgetSpec(
    StyledWidgetSpec *widgetSpecPtr)
				/* The widget spec to free. */
{
    ckfree((char *) widgetSpecPtr->optionsPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetWidgetSpec --
 *
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
    }

    /*
     * Create and initialize a new widget spec.
     */

    i = elementPtr->nbWidgetSpecs++;
    elementPtr->widgetSpecs = (StyledWidgetSpec *)ckrealloc(elementPtr->widgetSpecs,

	    sizeof(StyledWidgetSpec) * elementPtr->nbWidgetSpecs);
    widgetSpecPtr = elementPtr->widgetSpecs+i;
    InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable);

    return widgetSpecPtr;
}








|
>







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    }

    /*
     * Create and initialize a new widget spec.
     */

    i = elementPtr->nbWidgetSpecs++;
    elementPtr->widgetSpecs = (StyledWidgetSpec *) ckrealloc(
	    (char *) elementPtr->widgetSpecs,
	    sizeof(StyledWidgetSpec) * elementPtr->nbWidgetSpecs);
    widgetSpecPtr = elementPtr->widgetSpecs+i;
    InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable);

    return widgetSpecPtr;
}

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
 */

void
Tk_GetElementSize(
    Tk_Style style,		/* The widget style. */
    Tk_StyledElement element,	/* The styled element, previously returned by
				 * Tk_GetStyledElement. */
    void *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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, width, height, inner,
	    widthPtr, heightPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetElementBox --







|













|







1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
 */

void
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,
	    widthPtr, heightPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetElementBox --
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
 */

void
Tk_GetElementBox(
    Tk_Style style,		/* The widget style. */
    Tk_StyledElement element,	/* The styled element, previously returned by
				 * Tk_GetStyledElement. */
    void *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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, x, y, width, height,
	    inner, xPtr, yPtr, widthPtr, heightPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetElementBorderWidth --







|















|







1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
 */

void
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,
	    inner, xPtr, yPtr, widthPtr, heightPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_GetElementBorderWidth --
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
 */

int
Tk_GetElementBorderWidth(
    Tk_Style style,		/* The widget style. */
    Tk_StyledElement element,	/* The styled element, previously returned by
				 * Tk_GetStyledElement. */
    void *recordPtr,		/* The widget record. */
    Tk_Window tkwin)		/* The widget window. */
{
    Style *stylePtr = (Style *) style;
    StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element;

    return widgetSpecPtr->elementPtr->specPtr->getBorderWidth(
	    stylePtr->clientData, (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawElement --
 *







|






|







1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
 */

int
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;

    return widgetSpecPtr->elementPtr->specPtr->getBorderWidth(
	    stylePtr->clientData, recordPtr, widgetSpecPtr->optionsPtr, tkwin);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawElement --
 *
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
 */

void
Tk_DrawElement(
    Tk_Style style,		/* The widget style. */
    Tk_StyledElement element,	/* The styled element, previously returned by
				 * Tk_GetStyledElement. */
    void *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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, d, x, y, width,
	    height, state);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_CreateStyle --







|










|







1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
 */

void
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,
	    height, state);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_CreateStyle --
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
	return NULL;
    }

    /*
     * Allocate and intitialize a new style.
     */

    stylePtr = (Style *)ckalloc(sizeof(Style));
    InitStyle(stylePtr, (const char *)Tcl_GetHashKey(&tsdPtr->styleTable, entryPtr),
	    (engine!=NULL ? (StyleEngine*) engine : tsdPtr->defaultEnginePtr),
	    clientData);
    Tcl_SetHashValue(entryPtr, stylePtr);

    return (Tk_Style) stylePtr;
}

/*
 *---------------------------------------------------------------------------
 *







|
|
|

|







1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
	return NULL;
    }

    /*
     * Allocate and intitialize a new style.
     */

    stylePtr = (Style *) ckalloc(sizeof(Style));
    InitStyle(stylePtr, Tcl_GetHashKey(&tsdPtr->styleTable, entryPtr),
	    (engine!=NULL ? (StyleEngine *) engine : tsdPtr->defaultEnginePtr),
	    clientData);
    Tcl_SetHashValue(entryPtr, (ClientData) stylePtr);

    return (Tk_Style) stylePtr;
}

/*
 *---------------------------------------------------------------------------
 *
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363


1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
    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));
    Tcl_HashEntry *entryPtr;


    /*
     * Search for a corresponding entry in the style table.
     */

    entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name!=NULL?name:""));
    if (entryPtr == NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "style \"%s\" doesn't exist", name));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "STYLE", name, NULL);
	}
	return NULL;
    }


    return (Tk_Style)Tcl_GetHashValue(entryPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeStyle --
 *
 *	No-op. Present only for stubs compatibility.
 *
 *---------------------------------------------------------------------------
 */

void
Tk_FreeStyle(
    TCL_UNUSED(Tk_Style))
{
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_AllocStyleFromObj --







>








|
<
|

|

>
>
|














|







1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
    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));
    Tcl_HashEntry *entryPtr;
    Style *stylePtr;

    /*
     * Search for a corresponding entry in the style table.
     */

    entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name!=NULL?name:""));
    if (entryPtr == NULL) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "style \"", name, "\" doesn't exist",

		    NULL);
	}
	return (Tk_Style) NULL;
    }
    stylePtr = (Style *) Tcl_GetHashValue(entryPtr);

    return (Tk_Style) stylePtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeStyle --
 *
 *	No-op. Present only for stubs compatibility.
 *
 *---------------------------------------------------------------------------
 */

void
Tk_FreeStyle(
    Tk_Style style)
{
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_AllocStyleFromObj --
1398
1399
1400
1401
1402
1403
1404


1405
1406



1407
1408
1409



























1410















1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462

Tk_Style
Tk_AllocStyleFromObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    Tcl_Obj *objPtr)		/* Object containing name of the style to
				 * retrieve. */
{


    if (objPtr->typePtr != &styleObjType) {
	if (SetStyleFromAny(interp, objPtr) != TCL_OK) {



	    return NULL;
	}
    }



























    return (Tk_Style)objPtr->internalRep.twoPtrValue.ptr1;















}

/*
 *----------------------------------------------------------------------
 *
 * SetStyleFromAny --
 *
 *	Convert the internal representation of a Tcl object to the style
 *	internal form.
 *
 * Results:
 *	If an error occurs is returned (e.g. the style doesn't exist), an
 *	error message will be left in interp's result and TCL_ERROR is returned.
 *
 * Side effects:
 *	The object is left with its typePtr pointing to styleObjType.
 *
 *----------------------------------------------------------------------
 */

static int
SetStyleFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    const char *name;
    Tk_Style style;

    /*
     * Free the old internalRep before setting the new one.
     */

    name = Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    style = Tk_GetStyle(interp, name);
    if (style == NULL) {
    	return TCL_ERROR;
    }
    objPtr->typePtr = &styleObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = style;

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *







>
>

|
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
|














<








|


<
<
<
<

|







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500




1501
1502
1503
1504
1505
1506
1507
1508
1509

Tk_Style
Tk_AllocStyleFromObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    Tcl_Obj *objPtr)		/* Object containing name of the style to
				 * retrieve. */
{
    Style *stylePtr;

    if (objPtr->typePtr != &styleObjType) {
	SetStyleFromAny(interp, objPtr);
    }
    stylePtr = (Style *) objPtr->internalRep.twoPtrValue.ptr1;

    return (Tk_Style) stylePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetStyleFromObj --
 *
 *	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.
 *
 * Side effects:
 *	If the object is not already a style ref, the conversion will free any
 *	old internal representation.
 *
 *----------------------------------------------------------------------
 */

Tk_Style
Tk_GetStyleFromObj(
    Tcl_Obj *objPtr)		/* The object from which to get the style. */
{
    if (objPtr->typePtr != &styleObjType) {
	SetStyleFromAny(NULL, objPtr);
    }

    return (Tk_Style) objPtr->internalRep.twoPtrValue.ptr1;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FreeStyleFromObj --
 *
 *	No-op. Present only for stubs compatibility.
 *
 *---------------------------------------------------------------------------
 */
void
Tk_FreeStyleFromObj(
    Tcl_Obj *objPtr)
{
}

/*
 *----------------------------------------------------------------------
 *
 * SetStyleFromAny --
 *
 *	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.
 *
 * Side effects:
 *	The object is left with its typePtr pointing to styleObjType.
 *
 *----------------------------------------------------------------------
 */

static int
SetStyleFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    const char *name;


    /*
     * Free the old internalRep before setting the new one.
     */

    name = Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }





    objPtr->typePtr = &styleObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) Tk_GetStyle(interp, name);

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *

Changes to generic/tkTest.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126














127
128
129
130
131
132
133
134
135
136
137
138
139
 * 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.
 */

#undef STATIC_BUILD
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"
#include "tkText.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#define LOG_DISPLAY(drawable) TkTestLogDisplay(drawable)
#else
#define LOG_DISPLAY(drawable) 1
#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
 * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
 * Tcltest_Init declaration is in the source file itself, which is only
 * accessed when we are building a library.
 */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#ifdef __cplusplus
extern "C" {
#endif
EXTERN int		Tktest_Init(Tcl_Interp *interp);
#ifdef __cplusplus
}
#endif

/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;	/* Tk's token for image model. */
    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). */
} TImageModel;

/*
 * The following data structure represents a particular use of a particular
 * test image.
 */

typedef struct TImageInstance {
    TImageModel *modelPtr;	/* Pointer to model for image. */
    XColor *fg;			/* Foreground color for drawing in image. */
    GC gc;			/* Graphics context for drawing in image. */
    Bool displayFailed;         /* macOS display attempted out of drawRect. */
    char buffer[200 + TCL_INTEGER_SPACE * 6]; /* message to log on display. */
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    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 = {
    "test",			/* name */
    ImageCreate,		/* createProc */
    ImageGet,			/* getProc */
    ImageDisplay,		/* displayProc */
    ImageFree,			/* freeProc */
    ImageDelete,		/* deleteProc */
    NULL,			/* postscriptPtr */
    NULL,			/* nextPtr */
    NULL
};

/*
 * 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 {
    Tcl_Interp *interp;		/* Token for interpreter. */
    struct NewApp *nextPtr;	/* Next in list of new interpreters. */
} NewApp;

static NewApp *newAppPtr = NULL;/* First in list of all new interpreters. */















/*
 * Header for trivial configuration command items.
 */

#define ODD	TK_CONFIG_USER_BIT
#define EVEN	(TK_CONFIG_USER_BIT << 1)

enum {
    NONE,
    ODD_TYPE,
    EVEN_TYPE
};








<
<
<
<
<
<
<



|






<
<
<







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


|
|





|







|


<
<







|
|


















|
<















>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|







10
11
12
13
14
15
16







17
18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
















34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 * 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.
 */








#include "tkInt.h"
#include "tkText.h"

#ifdef __WIN32__
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"



#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
















 * 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, Tcl_Obj *const objv[],
			    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 = {
    "test",			/* name */
    ImageCreate,		/* createProc */
    ImageGet,			/* getProc */
    ImageDisplay,		/* displayProc */
    ImageFree,			/* freeProc */
    ImageDelete,		/* deleteProc */
    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.
 */

typedef struct NewApp {
    Tcl_Interp *interp;		/* Token for interpreter. */
    struct NewApp *nextPtr;	/* Next in list of new interpreters. */
} NewApp;

static NewApp *newAppPtr = NULL;/* First in list of all new interpreters. */

/*
 * Declaration for the square widget's class command function:
 */

extern int		SquareObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);

typedef struct CBinding {
    Tcl_Interp *interp;
    char *command;
    char *delete;
} CBinding;

/*
 * Header for trivial configuration command items.
 */

#define ODD TK_CONFIG_USER_BIT
#define EVEN (TK_CONFIG_USER_BIT << 1)

enum {
    NONE,
    ODD_TYPE,
    EVEN_TYPE
};

147
148
149
150
151
152
153





154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197










198
199
200
201
202
203
204
205
206
207
208
209
210
211
212







213

214




215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
				 * this widget. */
} TrivialCommandHeader;

/*
 * Forward declarations for functions defined later in this file:
 */






static int		ImageObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,

			    Tcl_Obj * const objv[]);
static int		TestbitmapObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestborderObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcolorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcursorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestdeleteappsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestfontObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestmakeexistObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestmenubarObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#endif
#if defined(_WIN32)
static int		TestmetricsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static int		TestobjconfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static Tk_CustomOptionSetProc CustomOptionSet;
static Tk_CustomOptionGetProc CustomOptionGet;
static Tk_CustomOptionRestoreProc CustomOptionRestore;
static Tk_CustomOptionFreeProc CustomOptionFree;
static int		TestpropObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);










static int		TestprintfObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestwrapperObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static void		TrivialCmdDeletedProc(ClientData clientData);
static int		TrivialConfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		TrivialEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int              TestPhotoStringMatchCmd(ClientData dummy,







                            Tcl_Interp *interp, int objc,

                            Tcl_Obj * const objv[]);





/*
 *----------------------------------------------------------------------
 *
 * Tktest_Init --
 *
 *	This function performs initialization for the Tk test suite extensions.
 *
 * 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
Tktest_Init(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    static int initialized = 0;

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * Create additional commands for testing Tk.
     */

    if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL);



    Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testdeleteapps", TestdeleteappsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testembed", TkpTestembedCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprintf", TestprintfObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testphotostringmatch",
            TestPhotoStringMatchCmd, (ClientData) Tk_MainWindow(interp),
            NULL);

#if defined(_WIN32)
    Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
    Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#endif /* _WIN32 */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;







>
>
>
>
>
|
|
>
|












|
|
<



|
|
<
|
|
|
<

|
|
|
<




|
<
<
<
<
|
|
>
>
>
>
>
>
>
>
>
>
|
|
<
|
|
|
<







|
>
>
>
>
>
>
>
|
>
|
>
>
>
>






|

















<
<
<
<
<
<
<




|
|


|
>
>
>








|

|





|

|

<
|

<
<
<

|
|

|
|

|

|

|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166

167
168
169

170
171
172
173

174
175
176
177
178




179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
				 * this widget. */
} TrivialCommandHeader;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		CBindingEvalProc(ClientData clientData,
			    Tcl_Interp *interp, XEvent *eventPtr,
			    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(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcolorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcursorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    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(ClientData dummy,
			    Tcl_Interp *interp, int argc, const char **argv);

#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestmenubarCmd(ClientData dummy,
			    Tcl_Interp *interp, int argc, const char **argv);

#endif
#if defined(__WIN32__) || defined(MAC_OSX_TK)
static int		TestmetricsCmd(ClientData dummy,
			    Tcl_Interp *interp, int argc, const char **argv);

#endif
static int		TestobjconfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    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) || defined(__CYGWIN__))
static int		TestwrapperCmd(ClientData dummy,
			    Tcl_Interp *interp, int argc, const char **argv);

#endif
static void		TrivialCmdDeletedProc(ClientData clientData);
static int		TrivialConfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		TrivialEventProc(ClientData clientData,
			    XEvent *eventPtr);

/*
 * External (platform specific) initialization routine:
 */

#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 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.
 *
 * Side effects:
 *	Creates several test commands.
 *
 *----------------------------------------------------------------------
 */

int
Tktest_Init(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    static int initialized = 0;








    /*
     * Create additional commands for testing Tk.
     */

    if (Tcl_PkgProvide(interp, "Tktest", TK_VERSION) == TCL_ERROR) {
        return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "square", SquareObjCmd,
	    (ClientData) NULL, NULL);
    Tcl_CreateCommand(interp, "testcbind", TestcbindCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateCommand(interp, "testdeleteapps", TestdeleteappsCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateCommand(interp, "testembed", TkpTestembedCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateCommand(interp, "testmakeexist", TestmakeexistCmd,
	    (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), NULL);
#elif !defined(__CYGWIN__)
    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), NULL);
#endif /* __WIN32__ || MAC_OSX_TK */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;
314
315
316
317
318
319
320











































































































321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341

342
343
344
345
346
347
348

    return TkplatformtestInit(interp);
}

/*
 *----------------------------------------------------------------------
 *











































































































 * TestbitmapObjCmd --
 *
 *	This function implements the "testbitmap" command, which is used to
 *	test color resource handling in tkBitmap tmp.c.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestbitmapObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "bitmap");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugBitmap(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














>


|




>







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

    return TkplatformtestInit(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * TestcbindCmd --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

static int
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?", NULL);
	return TCL_ERROR;
    }

    tkwin = (Tk_Window) clientData;

    if (argv[1][0] == '.') {
	winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	object = (ClientData) winPtr->pathName;
    } else {
	winPtr = (TkWindow *) clientData;
	object = (ClientData) Tk_GetUid(argv[1]);
    }

    if (argv[3][0] == '\0') {
	return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable,
		object, argv[2]);
    }

    cbindPtr = (CBinding *) ckalloc(sizeof(CBinding));
    cbindPtr->interp = interp;
    cbindPtr->command =
	    strcpy((char *) ckalloc(strlen(argv[3]) + 1), argv[3]);
    if (argc == 4) {
	cbindPtr->delete = NULL;
    } else {
	cbindPtr->delete =
		strcpy((char *) ckalloc(strlen(argv[4]) + 1), argv[4]);
    }

    if (TkCreateBindingProcedure(interp, winPtr->mainPtr->bindingTable,
	    object, argv[2], CBindingEvalProc, CBindingFreeProc,
	    (ClientData) cbindPtr) == 0) {
	ckfree((char *) cbindPtr->command);
	if (cbindPtr->delete != NULL) {
	    ckfree((char *) cbindPtr->delete);
	}
	ckfree((char *) cbindPtr);
	return TCL_ERROR;
    }
    return TCL_OK;
}

static int
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)
{
    CBinding *cbindPtr = (CBinding *) clientData;

    if (cbindPtr->delete != NULL) {
	Tcl_EvalEx(cbindPtr->interp, cbindPtr->delete, -1, TCL_EVAL_GLOBAL);
	ckfree((char *) cbindPtr->delete);
    }
    ckfree((char *) cbindPtr->command);
    ckfree((char *) cbindPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TestbitmapObjCmd --
 *
 *	This function implements the "testbitmap" command, which is used to
 *	test color resource handling in tkBitmap tmp.c.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestbitmapObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "bitmap");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugBitmap(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
361
362
363
364
365
366
367

368
369
370
371
372
373
374

375
376
377
378
379
380
381
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestborderObjCmd(
    TCL_UNUSED(ClientData),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "border");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugBorder(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;







>


|




>







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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) {
	Tcl_WrongNumArgs(interp, 1, objv, "border");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugBorder(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestcolorObjCmd(
    TCL_UNUSED(void *),	/* 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;







>


|







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestcursorObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "cursor");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugCursor(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestdeleteappsObjCmd --
 *
 *	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 interpreters created by previous calls to "testnewapp" get
 *	deleted.
 *
 *----------------------------------------------------------------------
 */


static int
TestdeleteappsObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))		/* Argument strings. */
{
    NewApp *nextPtr;

    while (newAppPtr != NULL) {
	nextPtr = newAppPtr->nextPtr;
	Tcl_DeleteInterp(newAppPtr->interp);
	ckfree(newAppPtr);
	newAppPtr = nextPtr;
    }

    return TCL_OK;
}

/*







>


|
















|








|





>

|
|
|
|
|






|







534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
    }
    Tcl_SetObjResult(interp, TkDebugCursor(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestdeleteappsCmd --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestdeleteappsCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char **argv)		/* Argument strings. */
{
    NewApp *nextPtr;

    while (newAppPtr != NULL) {
	nextPtr = newAppPtr->nextPtr;
	Tcl_DeleteInterp(newAppPtr->interp);
	ckfree((char *) newAppPtr);
	newAppPtr = nextPtr;
    }

    return TCL_OK;
}

/*
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
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 *const options[] = {
	"alltypes", "chain1", "chain2", "chain3", "configerror", "delete", "info",
	"internal", "new", "notenoughparams", "twowindows", NULL
    };
    enum {
	ALL_TYPES, CHAIN1, CHAIN2, CHAIN3, CONFIG_ERROR,
	DEL,			/* Can't use DELETE: VC++ compiler barfs. */
	INFO, INTERNAL, NEW, NOT_ENOUGH_PARAMS, TWO_WINDOWS
    };
    static Tk_OptionTable tables[11];
				/* Holds pointers to option tables created by
				 * commands below; indexed with same values as
				 * "options" array. */
    static const Tk_ObjCustomOption CustomOption = {
	"custom option",
	CustomOptionSet,
	CustomOptionGet,
	CustomOptionRestore,
	CustomOptionFree,
	INT2PTR(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:
     */

    typedef struct {
	TrivialCommandHeader header;
	Tcl_Obj *base1ObjPtr;
	Tcl_Obj *base2ObjPtr;
	Tcl_Obj *extension3ObjPtr;
	Tcl_Obj *extension4ObjPtr;
	Tcl_Obj *extension5ObjPtr;
    } ExtensionWidgetRecord;
    static const Tk_OptionSpec baseSpecs[] = {
	{TK_OPTION_STRING, "-one", "one", "One", "one",
		offsetof(ExtensionWidgetRecord, base1ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	{TK_OPTION_STRING, "-two", "two", "Two", "two",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "command");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "command", 0, &index)!= TCL_OK) {
	return TCL_ERROR;
    }

    switch (index) {
    case ALL_TYPES: {
	typedef struct {
	    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", NULL
	};
	static const Tk_OptionSpec typesSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", "1",
		offsetof(TypesRecord, booleanPtr), TCL_INDEX_NONE, 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "7",
		offsetof(TypesRecord, integerPtr), TCL_INDEX_NONE, 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		offsetof(TypesRecord, doublePtr), TCL_INDEX_NONE, 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String",
		"foo", offsetof(TypesRecord, stringPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x8},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable", "StringTable", "stringTable",
		"one", offsetof(TypesRecord, stringTablePtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, stringTable, 0x10},
	    {TK_OPTION_COLOR, "-color", "color", "Color",
		"red", offsetof(TypesRecord, colorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		offsetof(TypesRecord, fontPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		offsetof(TypesRecord, bitmapPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border",
		"blue", offsetof(TypesRecord, borderPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		offsetof(TypesRecord, reliefPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		offsetof(TypesRecord, cursorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		offsetof(TypesRecord, justifyPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL,
		offsetof(TypesRecord, anchorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel",
		"1", offsetof(TypesRecord, pixelPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL,
		"", offsetof(TypesRecord, customPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, 0, TCL_INDEX_NONE, 0, "-color", 0x8000},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;


	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, 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, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_DestroyWindow(tkwin);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);
	    ckfree(recordPtr);
	}
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN1: {
	ExtensionWidgetRecord *recordPtr;

	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, 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, recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions(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);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN2:
    case CHAIN3: {
	ExtensionWidgetRecord *recordPtr;
	static const Tk_OptionSpec extensionSpecs[] = {
	    {TK_OPTION_STRING, "-three", "three", "Three", "three",
		offsetof(ExtensionWidgetRecord, extension3ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-four", "four", "Four", "four",
		offsetof(ExtensionWidgetRecord, extension4ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-two", "two", "Two", "two and a half",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING,
		"-oneAgain", "oneAgain", "OneAgain", "one again",
		offsetof(ExtensionWidgetRecord, extension5ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
		(ClientData) baseSpecs, 0}
	};

	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, recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, 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_GetString(objv[2]), TrivialConfigObjCmd,
		    (ClientData) recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, (ClientData) recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CONFIG_ERROR: {
	typedef struct {
	    Tcl_Obj *intPtr;
	} ErrorWidgetRecord;
	ErrorWidgetRecord widgetRecord;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-int", "integer", "Integer", "bogus",
		offsetof(ErrorWidgetRecord, intPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;

	widgetRecord.intPtr = NULL;
	optionTable = Tk_CreateOptionTable(interp, errorSpecs);
	tables[index] = optionTable;
	return Tk_InitOptions(interp, &widgetRecord, optionTable,
		(Tk_Window) NULL);
    }

    case DEL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tableName");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[2], options,
		sizeof(char *), "table", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (tables[index] != NULL) {
	    Tk_DeleteOptionTable(tables[index]);
	    /* Make sure that Tk_DeleteOptionTable() is never done
	     * twice for the same table. */
	    tables[index] = NULL;
	}
	break;

    case INFO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tableName");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[2], options,
		sizeof(char *), "table", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, TkDebugConfig(interp, tables[index]));
	break;

    case INTERNAL: {
	/*
	 * This command is similar to the "alltypes" command except that it
	 * stores all the configuration options as internal forms instead of
	 * objects.
	 */

	typedef struct {
	    TrivialCommandHeader header;
	    int boolean;
	    int integer;
	    double doubleValue;
	    char *string;
	    int index;
	    XColor *colorPtr;







>







|
|



|













|

|








|









|

|
|







|
|





|




















|




|

|

|

|



|
|

|
|

|


|


|
|

|


|


|


|


|


|
|

|
|


>



|






|



















|







|






|









>


|








|
>





|

|


|













|
<



|

|

|


|
|
|

>


|








|
>






|

|

















|





|
|






|








|
|




<
<
<








|
|












|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929



930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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", NULL
    };
    enum {
	ALL_TYPES, CHAIN1, CHAIN2, CONFIG_ERROR,
	DEL,			/* Can't use DELETE: VC++ compiler barfs. */
	INFO, INTERNAL, NEW, NOT_ENOUGH_PARAMS, TWO_WINDOWS
    };
    static Tk_OptionTable tables[11];
				/* Holds pointers to option tables created by
				 * commands below; indexed with same values as
				 * "options" array. */
    static const Tk_ObjCustomOption CustomOption = {
	"custom option",
	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:
     */

    typedef struct ExtensionWidgetRecord {
	TrivialCommandHeader header;
	Tcl_Obj *base1ObjPtr;
	Tcl_Obj *base2ObjPtr;
	Tcl_Obj *extension3ObjPtr;
	Tcl_Obj *extension4ObjPtr;
	Tcl_Obj *extension5ObjPtr;
    } ExtensionWidgetRecord;
    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_Offset(ExtensionWidgetRecord, base2ObjPtr), -1},
	{TK_OPTION_END}
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "command");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    switch (index) {
    case ALL_TYPES: {
	typedef struct TypesRecord {
	    TrivialCommandHeader header;
	    Tcl_Obj *booleanPtr;
	    Tcl_Obj *integerPtr;
	    Tcl_Obj *doublePtr;
	    Tcl_Obj *stringPtr;
	    Tcl_Obj *stringTablePtr;
	    Tcl_Obj *colorPtr;
	    Tcl_Obj *fontPtr;
	    Tcl_Obj *bitmapPtr;
	    Tcl_Obj *borderPtr;
	    Tcl_Obj *reliefPtr;
	    Tcl_Obj *cursorPtr;
	    Tcl_Obj *activeCursorPtr;
	    Tcl_Obj *justifyPtr;
	    Tcl_Obj *anchorPtr;
	    Tcl_Obj *pixelPtr;
	    Tcl_Obj *mmPtr;
	    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);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);
	    ckfree((char *) recordPtr);
	}
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN1: {
	ExtensionWidgetRecord *recordPtr;
	Tk_Window tkwin;
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData,
		Tcl_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_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);
	    }
	}
	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 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 DEL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tableName");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (tables[index] != NULL) {
	    Tk_DeleteOptionTable(tables[index]);



	}
	break;

    case INFO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tableName");
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, TkDebugConfig(interp, tables[index]));
	break;

    case INTERNAL: {
	/*
	 * This command is similar to the "alltypes" command except that it
	 * stores all the configuration options as internal forms instead of
	 * objects.
	 */

	typedef struct InternalRecord {
	    TrivialCommandHeader header;
	    int boolean;
	    int integer;
	    double doubleValue;
	    char *string;
	    int index;
	    XColor *colorPtr;
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916

917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
	} 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",
		TCL_INDEX_NONE, offsetof(InternalRecord, boolean), 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "148962237",
		TCL_INDEX_NONE, offsetof(InternalRecord, integer), 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		TCL_INDEX_NONE, offsetof(InternalRecord, doubleValue), 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String", "foo",
		TCL_INDEX_NONE, offsetof(InternalRecord, string),
		TK_CONFIG_NULL_OK, 0, 0x8},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable", "StringTable", "stringTable", "one",
		TCL_INDEX_NONE, offsetof(InternalRecord, index),
		TK_CONFIG_NULL_OK, internalStringTable, 0x10},
	    {TK_OPTION_COLOR, "-color", "color", "Color", "red",
		TCL_INDEX_NONE, offsetof(InternalRecord, colorPtr),
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		TCL_INDEX_NONE, offsetof(InternalRecord, tkfont),
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		TCL_INDEX_NONE, offsetof(InternalRecord, bitmap),
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border", "blue",
		TCL_INDEX_NONE, offsetof(InternalRecord, border),
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		TCL_INDEX_NONE, offsetof(InternalRecord, relief),
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		TCL_INDEX_NONE, offsetof(InternalRecord, cursor),
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		TCL_INDEX_NONE, offsetof(InternalRecord, justify),
		TK_CONFIG_NULL_OK, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, anchor),
		TK_CONFIG_NULL_OK, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, pixels),
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_WINDOW, "-window", "window", "Window", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, tkwin),
		TK_CONFIG_NULL_OK, 0, 0},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "",
		TCL_INDEX_NONE, offsetof(InternalRecord, custom),
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, TCL_INDEX_NONE, TCL_INDEX_NONE, 0, "-color", 0x8000},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;


	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, recordPtr, optionTable,
		tkwin);
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, recordPtr);
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc - 3, objv + 3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_DestroyWindow(tkwin);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);
	    ckfree(recordPtr);
	}
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case NEW: {
	typedef struct {
	    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",
		offsetof(FiveRecord, one), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_INT, "-two", "two", "Two", "2",
		offsetof(FiveRecord, two), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_INT, "-three", "three", "Three", "3",
		offsetof(FiveRecord, three), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_INT, "-four", "four", "Four", "4",
		offsetof(FiveRecord, four), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-five", NULL, NULL, NULL,
		offsetof(FiveRecord, five), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "new name ?-option value ...?");
	    return TCL_ERROR;
	}

	recordPtr = (FiveRecord *)ckalloc(sizeof(FiveRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = Tk_CreateOptionTable(interp,
		smallSpecs);
	tables[index] = recordPtr->header.optionTable;
	recordPtr->header.tkwin = NULL;
	recordPtr->one = recordPtr->two = recordPtr->three = NULL;
	recordPtr->four = recordPtr->five = NULL;
	Tcl_SetObjResult(interp, objv[2]);
	result = Tk_InitOptions(interp, recordPtr,
		recordPtr->header.optionTable, (Tk_Window) NULL);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
		    recordPtr->header.optionTable, objc - 3, objv + 3,
		    (Tk_Window) NULL, NULL, NULL);
	    if (result == TCL_OK) {
		recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
			Tcl_GetString(objv[2]), TrivialConfigObjCmd,
			(ClientData) recordPtr, TrivialCmdDeletedProc);
	    } else {
		Tk_FreeConfigOptions(recordPtr,
			recordPtr->header.optionTable, (Tk_Window) NULL);
	    }
	}
	if (result != TCL_OK) {
	    ckfree(recordPtr);
	}

	break;
    }
    case NOT_ENOUGH_PARAMS: {
	typedef struct {
	    Tcl_Obj *fooObjPtr;
	} NotEnoughRecord;
	NotEnoughRecord record;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-foo", "foo", "Foo", "0",
		offsetof(NotEnoughRecord, fooObjPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	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, &record, optionTable, tkwin);
	if (Tk_SetOptions(interp, &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;
    }

    case TWO_WINDOWS: {
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *windowPtr;
	} ContentRecord;
	ContentRecord *recordPtr;
	static const Tk_OptionSpec contentSpecs[] = {
	    {TK_OPTION_WINDOW, "-window", "window", "Window", ".bar",
		offsetof(ContentRecord, windowPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	tkwin = Tk_CreateWindowFromPath(interp,
		(Tk_Window)clientData, Tcl_GetString(objv[2]), NULL);

	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	Tk_SetClass(tkwin, "Test");

	recordPtr = (ContentRecord *)ckalloc(sizeof(ContentRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = Tk_CreateOptionTable(interp,
		contentSpecs);
	tables[index] = recordPtr->header.optionTable;
	recordPtr->header.tkwin = tkwin;
	recordPtr->windowPtr = NULL;

	result = Tk_InitOptions(interp, recordPtr,
		recordPtr->header.optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
		    recordPtr->header.optionTable, objc - 3, objv + 3,
		    tkwin, NULL, NULL);
	    if (result == TCL_OK) {
		recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
			Tcl_GetString(objv[2]), TrivialConfigObjCmd,
			recordPtr, TrivialCmdDeletedProc);
		Tk_CreateEventHandler(tkwin, StructureNotifyMask,
			TrivialEventProc, recordPtr);
		Tcl_SetObjResult(interp, objv[2]);
	    } else {
		Tk_FreeConfigOptions(recordPtr,
			recordPtr->header.optionTable, tkwin);
	    }
	}
	if (result != TCL_OK) {
	    Tk_DestroyWindow(tkwin);
	    ckfree(recordPtr);
	}
    }
    }

    return result;
}








|

|

|

|



|
|

|
|

|


|


|
|

|


|


|


|


|


|


|
|

|
|


>



|






|




















|




|

|
|






|








|










|

|

|

|

|
|



|



|








|


|







|




|





|





|
|










|
|










|


|
|
|

|
|

|
|






|


|




|


|





|

|


|





|







971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
	} 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);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);
	    ckfree((char *) recordPtr);
	}
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case NEW: {
	typedef struct FiveRecord {
	    TrivialCommandHeader header;
	    Tcl_Obj *one;
	    Tcl_Obj *two;
	    Tcl_Obj *three;
	    Tcl_Obj *four;
	    Tcl_Obj *five;
	} FiveRecord;
	FiveRecord *recordPtr;
	static 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;
	}

	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_GetString(objv[2]), TrivialConfigObjCmd,
			(ClientData) recordPtr, TrivialCmdDeletedProc);
	    } else {
		Tk_FreeConfigOptions((char *) recordPtr,
			recordPtr->header.optionTable, (Tk_Window) NULL);
	    }
	}
	if (result != TCL_OK) {
	    ckfree((char *) recordPtr);
	}

	break;
    }
    case NOT_ENOUGH_PARAMS: {
	typedef struct NotEnoughRecord {
	    Tcl_Obj *fooObjPtr;
	} NotEnoughRecord;
	NotEnoughRecord record;
	static 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;
    }

    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);

	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	Tk_SetClass(tkwin, "Test");

	recordPtr = (SlaveRecord *) ckalloc(sizeof(SlaveRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = Tk_CreateOptionTable(interp,
		slaveSpecs);
	tables[index] = recordPtr->header.optionTable;
	recordPtr->header.tkwin = tkwin;
	recordPtr->windowPtr = NULL;

	result = Tk_InitOptions(interp,  (char *) recordPtr,
		recordPtr->header.optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, (char *) recordPtr,
		    recordPtr->header.optionTable, objc - 3, objv + 3,
		    tkwin, NULL, NULL);
	    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]);
	    } else {
		Tk_FreeConfigOptions((char *) recordPtr,
			recordPtr->header.optionTable, tkwin);
	    }
	}
	if (result != TCL_OK) {
	    Tk_DestroyWindow(tkwin);
	    ckfree((char *) recordPtr);
	}
    }
    }

    return result;
}

1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
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 *const options[] = {
	"cget", "configure", "csave", NULL
    };
    enum {
	CGET, CONFIGURE, CSAVE
    };
    Tcl_Obj *resultObjPtr;
    int index, mask;
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    Tk_Window tkwin = headerPtr->tkwin;
    Tk_SavedOptions saved;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "command", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(clientData);

    switch (index) {
    case CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	resultObjPtr = Tk_GetOptionValue(interp, 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, clientData,
		    headerPtr->optionTable, NULL, tkwin);
	    if (resultObjPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, resultObjPtr);
	    }
	} else if (objc == 3) {
	    resultObjPtr = Tk_GetOptionInfo(interp, clientData,
		    headerPtr->optionTable, objv[2], tkwin);
	    if (resultObjPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, resultObjPtr);
	    }
	} else {
	    result = Tk_SetOptions(interp, clientData,
		    headerPtr->optionTable, objc - 2, objv + 2,
		    tkwin, NULL, &mask);
	    if (result == TCL_OK) {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(mask));
	    }
	}
	break;
    case CSAVE:
	result = Tk_SetOptions(interp, clientData,
		headerPtr->optionTable, objc - 2, objv + 2,
		tkwin, &saved, &mask);
	Tk_FreeSavedOptions(&saved);
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(mask));
	}
	break;
    }
  done:
    Tcl_Release(clientData);
    return result;
}







>








|







|




|



|
|












|










|







|







|



|




|




|







1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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", NULL
    };
    enum {
	CGET, CONFIGURE, CSAVE
    };
    Tcl_Obj *resultObjPtr;
    int index, mask;
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;
    Tk_Window tkwin = headerPtr->tkwin;
    Tk_SavedOptions saved;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(clientData);

    switch (index) {
    case CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	resultObjPtr = Tk_GetOptionValue(interp, (char *) clientData,
		headerPtr->optionTable, objv[2], tkwin);
	if (resultObjPtr != NULL) {
	    Tcl_SetObjResult(interp, resultObjPtr);
	    result = TCL_OK;
	} else {
	    result = TCL_ERROR;
	}
	break;
    case CONFIGURE:
	if (objc == 2) {
	    resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData,
		    headerPtr->optionTable, 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, NULL, &mask);
	    if (result == TCL_OK) {
		Tcl_SetIntObj(Tcl_GetObjResult(interp), mask);
	    }
	}
	break;
    case CSAVE:
	result = Tk_SetOptions(interp, (char *) clientData,
		headerPtr->optionTable, objc - 2, objv + 2,
		tkwin, &saved, &mask);
	Tk_FreeSavedOptions(&saved);
	if (result == TCL_OK) {
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), mask);
	}
	break;
    }
  done:
    Tcl_Release(clientData);
    return result;
}
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
 *----------------------------------------------------------------------
 */

static void
TrivialCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    Tk_Window tkwin = headerPtr->tkwin;

    if (tkwin != NULL) {
	Tk_DestroyWindow(tkwin);
    } else if (headerPtr->optionTable != NULL) {
	/*
	 * This is a "new" object, which doesn't have a window, so we can't
	 * depend on cleaning up in the event function. Free its resources
	 * here.
	 */

	Tk_FreeConfigOptions(clientData,
		headerPtr->optionTable, NULL);
	Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
    }
}

/*
 *--------------------------------------------------------------
 *







|











|
|







1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
 *----------------------------------------------------------------------
 */

static void
TrivialCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;
    Tk_Window tkwin = headerPtr->tkwin;

    if (tkwin != NULL) {
	Tk_DestroyWindow(tkwin);
    } else if (headerPtr->optionTable != NULL) {
	/*
	 * This is a "new" object, which doesn't have a window, so we can't
	 * depend on cleaning up in the event function. Free its resources
	 * here.
	 */

	Tk_FreeConfigOptions((char *) clientData,
		headerPtr->optionTable, (Tk_Window) NULL);
	Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
    }
}

/*
 *--------------------------------------------------------------
 *
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
 */

static void
TrivialEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;

    if (eventPtr->type == DestroyNotify) {
	if (headerPtr->tkwin != NULL) {
	    Tk_FreeConfigOptions(clientData,
		    headerPtr->optionTable, headerPtr->tkwin);
	    headerPtr->optionTable = NULL;
	    headerPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(headerPtr->interp,
		    headerPtr->widgetCmd);
	}
	Tcl_EventuallyFree(clientData, TCL_DYNAMIC);







|



|







1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
 */

static void
TrivialEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;

    if (eventPtr->type == DestroyNotify) {
	if (headerPtr->tkwin != NULL) {
	    Tk_FreeConfigOptions((char *) clientData,
		    headerPtr->optionTable, headerPtr->tkwin);
	    headerPtr->optionTable = NULL;
	    headerPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(headerPtr->interp,
		    headerPtr->widgetCmd);
	}
	Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
1307
1308
1309
1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
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 *const options[] = {"counts", "subfonts", NULL};
    enum option {COUNTS, SUBFONTS};
    int index;
    Tk_Window tkwin;
    Tk_Font tkfont;

    tkwin = (Tk_Window)clientData;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option fontName");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "command", 0, &index)!= TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum option) index) {
    case COUNTS:
	Tcl_SetObjResult(interp,
		TkDebugFont(Tk_MainWindow(interp), Tcl_GetString(objv[2])));







>







|





|






|
|







1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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", NULL};
    enum option {COUNTS, SUBFONTS};
    int index;
    Tk_Window tkwin;
    Tk_Font tkfont;

    tkwin = (Tk_Window) clientData;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option fontName");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum option) index) {
    case COUNTS:
	Tcl_SetObjResult(interp,
		TkDebugFont(Tk_MainWindow(interp), Tcl_GetString(objv[2])));
1366
1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448

1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */


static int
ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const 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). */
    TCL_UNUSED(const Tk_ImageType *),	/* Pointer to our type record (not used). */
	Tk_ImageModel model,	/* 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. */
{
    TImageModel *timPtr;
    const char *varName;
    int i;

    varName = "log";
    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]), "\"", NULL);
	    return TCL_ERROR;
	}
	if ((i+1) == objc) {
	    Tcl_AppendResult(interp, "no value given for \"",
		    Tcl_GetString(objv[i]), "\" option", NULL);
	    return TCL_ERROR;
	}
	varName = Tcl_GetString(objv[i+1]);
    }

    timPtr = (TImageModel *)ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageObjCmd --
 *
 *	This function implements the commands corresponding to individual
 *	images.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */


static int
ImageObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
	if (objc != 8) {
		Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
			" imageWidth imageHeight");
	    return TCL_ERROR;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
	    return TCL_ERROR;
	}
	Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width,
		timPtr->height);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be changed", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







>




|



|
|




|
|

















|
|



|

|

|
|
|






|













>

|


|
|

|


|
>
|


|
|
|
|


|
|
|
|
|
|


|


|







1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
 *
 * 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 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;

    varName = "log";
    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]), "\"", NULL);
	    return TCL_ERROR;
	}
	if ((i+1) == objc) {
	    Tcl_AppendResult(interp, "no value given for \"",
		    Tcl_GetString(objv[i]), "\" option", NULL);
	    return TCL_ERROR;
	}
	varName = Tcl_GetString(objv[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;
}

/*
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
 *----------------------------------------------------------------------
 */

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
    instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
    instPtr->displayFailed = False;
    return instPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDisplay --
 *







|

|





|


|
|



<
|







1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
1638
 *----------------------------------------------------------------------
 */

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 --
 *
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
    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;

    /*
     * The purpose of the test image type is to track the calls to an image
     * display proc and record the parameters passed in each call.  On macOS a
     * display proc must be run inside of the drawRect method of an NSView in
     * order for the graphics operations to have any effect.  To deal with
     * this, whenever a display proc is called outside of any drawRect method
     * it schedules a redraw of the NSView.
     *
     * In an attempt to work around this, each image instance maintains it own
     * copy of the log message which gets written on the first call to the
     * display proc.  This usually means that the message created on macOS is
     * the same as that created on other platforms.  However it is possible
     * for the messages to differ for other reasons, namely differences in
     * how damage regions are computed.
     */

    if (LOG_DISPLAY(drawable)) {
	if (instPtr->displayFailed == False) {

	    /*
	     * Drawing is possible on the first call to DisplayImage.
	     * Log the message.
	     */

	    sprintf(instPtr->buffer, "%s display %d %d %d %d",
	    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName,

		    NULL, instPtr->buffer,
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
	instPtr->displayFailed = False;
    } else {

	/*
         * Drawing is not possible on the first call to DisplayImage.
	 * Save the message, but do not log it until the actual display.
	 */

	if (instPtr->displayFailed == False) {
	    sprintf(instPtr->buffer, "%s display %d %d %d %d",
		    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	instPtr->displayFailed = True;
    }
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
    if (height > (instPtr->modelPtr->height - imageY)) {
	height = instPtr->modelPtr->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);







|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

|
|

<







1657
1658
1659
1660
1661
1662
1663
1664
1665







1666
















1667
1668


1669
1670
1671














1672
1673
1674
1675
1676
1677

1678
1679
1680
1681
1682
1683
1684
    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);
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
 */

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->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDelete --
 *







|


|
|
|


|







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
 */

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 --
 *
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696

1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755

1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813

1814

1815
1816
1817



1818












1819

1820



1821

1822



1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
    ckfree(timPtr->imageName);
    ckfree(timPtr->varName);
    ckfree(timPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TestmakeexistObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */


static int
TestmakeexistObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int i;
    Tk_Window tkwin;

    for (i = 1; i < objc; i++) {
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), mainWin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestmenubarObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	Changes menubar related stuff.
 *
 *----------------------------------------------------------------------
 */


#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int
TestmenubarObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
#ifdef __UNIX__
    Tk_Window mainWin = (Tk_Window)clientData;
    Tk_Window tkwin, menubar;

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (strcmp(Tcl_GetString(objv[1]), "window") == 0) {
	if (objc != 4) {

	    Tcl_WrongNumArgs(interp, 1, objv, "windows toplevel menubar");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainWin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	if (Tcl_GetString(objv[3])[0] == 0) {
	    TkUnixSetMenubar(tkwin, NULL);
	} else {
	    menubar = Tk_NameToWindow(interp, Tcl_GetString(objv[3]), mainWin);
	    if (menubar == NULL) {
		return TCL_ERROR;
	    }
	    TkUnixSetMenubar(tkwin, menubar);
	}
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be  window", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
#else
    Tcl_AppendResult(interp, "testmenubar is supported only under Unix", NULL);

    return TCL_ERROR;
#endif
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TestmetricsObjCmd --
 *
 *	This function implements the testmetrics command. It provides a way to
 *	determine the size of various widget components.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if defined(_WIN32)
static int
TestmetricsObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    char buf[TCL_INTEGER_SPACE];
    int val;


    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
















    if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {

	val = GetSystemMetrics(SM_CYVSCROLL);



    } else  if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {

	val = GetSystemMetrics(SM_CXHSCROLL);



    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    sprintf(buf, "%d", val);
    Tcl_AppendResult(interp, buf, NULL);
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TestpropObjCmd --
 *
 *	This function implements the "testprop" command. It fetches and prints
 *	the value of a property on a window.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestpropObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int result, actualFormat;
    unsigned long bytesAfter, length, value;
    Atom actualType, propName;
    unsigned char *property, *p;
    char *end;
    Window w;
    char buffer[30];

    if (objc != 3) {

	Tcl_WrongNumArgs(interp, 1, objv, "window property");
	return TCL_ERROR;
    }

    w = strtoul(Tcl_GetString(objv[1]), &end, 0);
    propName = Tk_InternAtom(mainWin, Tcl_GetString(objv[2]));
    property = NULL;
    result = XGetWindowProperty(Tk_Display(mainWin),
	    w, propName, 0, 100000, False, AnyPropertyType,
	    &actualType, &actualFormat, &length,
	    &bytesAfter, &property);
    if ((result == Success) && (actualType != None)) {
	if ((actualFormat == 8) && (actualType == XA_STRING)) {
	    for (p = property; ((unsigned long)(p-property)) < length; p++) {
		if (*p == 0) {
		    *p = '\n';
		}
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj((/*!unsigned*/char*)property, -1));
	} else {
	    for (p = property; length > 0; length--) {
		if (actualFormat == 32) {
		    value = *((long *) p);
		    p += sizeof(long);
		} else if (actualFormat == 16) {
		    value = 0xffff & (*((short *) p));







|



|



|





|





|














>

|


|
|

|



|
|












|














>
|

|


|
|


|


|
>
|



|
|
>
|


|



|


|






|






|
>








|













|

|
|

|
|




>
|
>
|


>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
|
>

>
>
>
|
>

>
>
>

|












|













>

|


|
|

|








|
>
|



|
|












|







1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
 *	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);
}

/*
 *----------------------------------------------------------------------
 *
 * TestmakeexistCmd --
 *
 *	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.
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
    Tk_Window tkwin;

    for (i = 1; i < argc; i++) {
	tkwin = Tk_NameToWindow(interp, argv[i], mainWin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestmenubarCmd --
 *
 *	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.
 *
 * Side effects:
 *	Changes menubar related stuff.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int
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;
    Tk_Window tkwin, menubar;

    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args;  must be \"", argv[0],
		" 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\"", NULL);
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, argv[2], mainWin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	if (argv[3][0] == 0) {
	    TkUnixSetMenubar(tkwin, NULL);
	} else {
	    menubar = Tk_NameToWindow(interp, argv[3], mainWin);
	    if (menubar == NULL) {
		return TCL_ERROR;
	    }
	    TkUnixSetMenubar(tkwin, menubar);
	}
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be  window", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
#else
    Tcl_SetResult(interp, "testmenubar is supported only under Unix",
	    TCL_STATIC);
    return TCL_ERROR;
#endif
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TestmetricsCmd --
 *
 *	This function implements the testmetrics command. It provides a way to
 *	determine the size of various widget components.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if defined(__WIN32__) || defined(MAC_OSX_TK)
static int
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;

#ifdef __WIN32__
    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args;  must be \"", argv[0],
		" option ?arg ...?\"", NULL);
	return TCL_ERROR;
    }
#else
    Tk_Window tkwin = (Tk_Window) clientData;
    TkWindow *winPtr;

    if (argc != 3) {
	Tcl_AppendResult(interp, "wrong # args;  must be \"", argv[0],
		" option window\"", NULL);
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
#endif

    if (strcmp(argv[1], "cyvscroll") == 0) {
#ifdef __WIN32__
	val = GetSystemMetrics(SM_CYVSCROLL);
#else
	val = ((TkScrollbar *) winPtr->instanceData)->width;
#endif
    } else  if (strcmp(argv[1], "cxhscroll") == 0) {
#ifdef __WIN32__
	val = GetSystemMetrics(SM_CXHSCROLL);
#else
	val = ((TkScrollbar *) winPtr->instanceData)->width;
#endif
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    sprintf(buf, "%d", val);
    Tcl_AppendResult(interp, buf, NULL);
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TestpropCmd --
 *
 *	This function implements the "testprop" command. It fetches and prints
 *	the value of a property on a window.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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;
    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\"", NULL);
	return TCL_ERROR;
    }

    w = strtoul(argv[1], &end, 0);
    propName = Tk_InternAtom(mainWin, argv[2]);
    property = NULL;
    result = XGetWindowProperty(Tk_Display(mainWin),
	    w, propName, 0, 100000, False, AnyPropertyType,
	    &actualType, &actualFormat, &length,
	    &bytesAfter, &property);
    if ((result == Success) && (actualType != None)) {
	if ((actualFormat == 8) && (actualType == XA_STRING)) {
	    for (p = property; ((unsigned long)(p-property)) < length; p++) {
		if (*p == 0) {
		    *p = '\n';
		}
	    }
	    Tcl_SetResult(interp, (/*!unsigned*/char*)property, TCL_VOLATILE);
	} else {
	    for (p = property; length > 0; length--) {
		if (actualFormat == 32) {
		    value = *((long *) p);
		    p += sizeof(long);
		} else if (actualFormat == 16) {
		    value = 0xffff & (*((short *) p));
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993

1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
    }
    if (property != NULL) {
	XFree(property);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestpropObjCmd --
 *
 *	This function implements the "testprop" command. It fetches and prints
 *	the value of a property on a window.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestprintfObjCmd(
    ClientData dummy,	/* Not used */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    char buffer[256];
    Tcl_WideInt wideInt;
#ifdef _WIN32
    __int64 longLongInt;
#else
    long long longLongInt;
#endif
    (void)dummy;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "wideint");
	return TCL_ERROR;
    }
    if (Tcl_GetWideIntFromObj(interp, objv[1], &wideInt) != TCL_OK) {
	return TCL_ERROR;
    }
    longLongInt = wideInt;

    /* Just add a lot of arguments to sprintf. Reason: on AMD64, the first
     * 4 or 6 arguments (we assume 8, just in case) might be put in registers,
     * which still woudn't tell if the assumed size is correct: We want this
     * test-case to fail if the 64-bit value is printed as truncated to 32-bit.
     */
    sprintf(buffer, "%s%s%s%s%s%s%s%s%" TCL_LL_MODIFIER "d %"
	    TCL_LL_MODIFIER "u", "", "", "", "", "", "", "", "",
	    (Tcl_WideInt)longLongInt, (Tcl_WideUInt)longLongInt);
    Tcl_AppendResult(interp, buffer, NULL);
    return TCL_OK;
}

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
 *----------------------------------------------------------------------
 *
 * TestwrapperObjCmd --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static int
TestwrapperObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkWindow *winPtr, *wrapperPtr;
    Tk_Window tkwin;

    if (objc != 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "window");
	return TCL_ERROR;
    }

    tkwin = (Tk_Window)clientData;
    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }

    wrapperPtr = TkpGetWrapperWindow(winPtr);
    if (wrapperPtr != NULL) {
	char buf[TCL_INTEGER_SPACE];

	TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    }
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|














>

|


|
|




|
>
|



|
|









|







2012
2013
2014
2015
2016
2017
2018






















































2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
    }
    if (property != NULL) {
	XFree(property);
    }
    return TCL_OK;
}























































#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
 *----------------------------------------------------------------------
 *
 * TestwrapperCmd --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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\"", NULL);
	return TCL_ERROR;
    }

    tkwin = (Tk_Window) clientData;
    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }

    wrapperPtr = TkpGetWrapperWindow(winPtr);
    if (wrapperPtr != NULL) {
	char buf[TCL_INTEGER_SPACE];

	TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    }
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
2028
2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
 *		CustomOptionFree	None.
 *
 * Side effects:
 *	Depends on the function.
 *		CustomOptionSet		Sets option value to new setting.
 *		CustomOptionGet		Creates a new Tcl_Obj.
 *		CustomOptionRestore	Resets option value to original value.
 *		CustomOptionFree	Free storage for internal rep of option.

 *
 *----------------------------------------------------------------------
 */

static int
CustomOptionSet(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(Tk_Window),
    Tcl_Obj **value,
    char *recordPtr,
    TkSizeT internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty;
    char *newStr, *string, *internalPtr;

    objEmpty = 0;

    if (internalOffset != TCL_INDEX_NONE) {
	internalPtr = recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
    }

    /*
     * See if the object is empty.
     */

    if (value == NULL) {
	objEmpty = 1;
	CLANG_ASSERT(value);
    } else if ((*value)->bytes != NULL) {
	objEmpty = ((*value)->length == 0);
    } else {
	(void)Tcl_GetString(*value);
	objEmpty = ((*value)->length == 0);
    }

    if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
	*value = NULL;
    } else {
	string = Tcl_GetString(*value);
	Tcl_UtfToUpper(string);
	if (strcmp(string, "BAD") == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected good value, got \"BAD\"", -1));

	    return TCL_ERROR;
	}
    }
    if (internalPtr != NULL) {
	if (*value != NULL) {
	    string = Tcl_GetString(*value);
	    newStr = (char *)ckalloc((*value)->length + 1);
	    strcpy(newStr, string);
	} else {
	    newStr = NULL;
	}
	*((char **) saveInternalPtr) = *((char **) internalPtr);
	*((char **) internalPtr) = newStr;
    }

    return TCL_OK;
}

static Tcl_Obj *
CustomOptionGet(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,
    TkSizeT internalOffset)
{
    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}

static void
CustomOptionRestore(
    ClientData dummy,
    Tk_Window tkwin,
    char *internalPtr,
    char *saveInternalPtr)
{
    (void)dummy;
    (void)tkwin;

    *(char **)internalPtr = *(char **)saveInternalPtr;
    return;
}

static void
CustomOptionFree(
    ClientData dummy,
    Tk_Window tkwin,
    char *internalPtr)
{
    (void)dummy;
    (void)tkwin;

    if (*(char **)internalPtr != NULL) {
	ckfree(*(char **)internalPtr);
    }
}
/*
 *----------------------------------------------------------------------
 *
 * TestPhotoStringMatchCmd --
 *
 *	This function implements the "testphotostringmatch" command. It
 *	provides a way from Tcl to call the string match function for the
 *	default image handler directly.
 *
 * Results:
 *	A standard Tcl result. If data is in the proper format, the result in
 *	interp will contain width and height as a list. If the data cannot be
 *	parsed as default image format, returns TCL_ERROR and leaves an
 *	appropriate error message in interp.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestPhotoStringMatchCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tcl_Obj *dummy = NULL;
    Tcl_Obj *resultObj[2];
    int width, height;
    (void)clientData;

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "imageData");
        return TCL_ERROR;
    }
    if (TkDebugPhotoStringMatchDef(interp, objv[1], dummy, &width, &height)) {
        resultObj[0] = Tcl_NewWideIntObj(width);
        resultObj[1] = Tcl_NewWideIntObj(height);
        Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObj));
        return TCL_OK;
    } else {
        return TCL_ERROR;
    }
}



/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>






|

|


|



|




|











<



|
|





|


|
>




|
|
|













|
|

|






|




<
<
<






|



<
<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125

2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175



2176
2177
2178
2179
2180
2181
2182
2183
2184
2185



2186
2187
2188
2189
















































2190
2191
2192
2193
2194
2195
2196
2197
 *		CustomOptionFree	None.
 *
 * Side effects:
 *	Depends on the function.
 *		CustomOptionSet		Sets option value to new setting.
 *		CustomOptionGet		Creates a new Tcl_Obj.
 *		CustomOptionRestore	Resets option value to original value.
 *		CustomOptionFree	Free storage for internal rep of
 *					option.
 *
 *----------------------------------------------------------------------
 */

static int
CustomOptionSet(
    ClientData clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj **value,
    char *recordPtr,
    int internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty, length;
    char *newStr, *string, *internalPtr;

    objEmpty = 0;

    if (internalOffset >= 0) {
	internalPtr = 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 {
	Tcl_GetStringFromObj((*value), &length);
	objEmpty = (length == 0);
    }

    if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
	*value = NULL;
    } else {
	string = Tcl_GetStringFromObj((*value), &length);
	Tcl_UtfToUpper(string);
	if (strcmp(string, "BAD") == 0) {
	    Tcl_SetResult(interp, "expected good value, got \"BAD\"",
		    TCL_STATIC);
	    return TCL_ERROR;
	}
    }
    if (internalPtr != NULL) {
	if ((*value) != NULL) {
	    string = Tcl_GetStringFromObj((*value), &length);
	    newStr = ckalloc((size_t) (length + 1));
	    strcpy(newStr, string);
	} else {
	    newStr = NULL;
	}
	*((char **) saveInternalPtr) = *((char **) internalPtr);
	*((char **) internalPtr) = newStr;
    }

    return TCL_OK;
}

static Tcl_Obj *
CustomOptionGet(
    ClientData clientData,
    Tk_Window tkwin,
    char *recordPtr,
    int internalOffset)
{
    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}

static void
CustomOptionRestore(
    ClientData clientData,
    Tk_Window tkwin,
    char *internalPtr,
    char *saveInternalPtr)
{



    *(char **)internalPtr = *(char **)saveInternalPtr;
    return;
}

static void
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:
 */

Changes to generic/tkText.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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.
 */

#include "tkInt.h"
#include "tkUndo.h"
#include "default.h"

#if defined(MAC_OSX_TK)
#define Style TkStyle
#define DInfo TkDInfo
#endif

/*







|
|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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.
 */

#include "default.h"
#include "tkInt.h"
#include "tkUndo.h"

#if defined(MAC_OSX_TK)
#define Style TkStyle
#define DInfo TkDInfo
#endif

/*
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
 * the string table below.
 */

static const char *const tabStyleStrings[] = {
    "tabular", "wordprocessor", NULL
};

/*
 * The 'TkTextInsertUnfocussed' enum in tkText.h is used to define a type for
 * the -insertunfocussed option of the Text widget. These values are used as
 * indice into the string table below.
 */

static const char *const insertUnfocussedStrings[] = {
    "hollow", "none", "solid", NULL
};

/*
 * The following functions and custom option type are used to define the
 * "line" option type, and thereby handle the text widget '-startline',
 * '-endline' configuration options which are of that type.
 *
 * 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		SetLineStartEnd(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tcl_Obj **value, char *recordPtr,
			    TkSizeT internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetLineStartEnd(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr,
			    TkSizeT 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
};

/*
 * Information used to parse text configuration options:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators",
	"AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, TCL_INDEX_NONE,
	offsetof(TkText, autoSeparators),
	TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_TEXT_BG_COLOR, TCL_INDEX_NONE, offsetof(TkText, border),
	0, DEF_TEXT_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth",
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor",
	"BlockCursor", DEF_TEXT_BLOCK_CURSOR, TCL_INDEX_NONE,
	offsetof(TkText, insertCursorType), 0, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_TEXT_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(TkText, borderWidth),
	0, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_TEXT_CURSOR, TCL_INDEX_NONE, offsetof(TkText, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-endline", NULL, NULL,
	 NULL, TCL_INDEX_NONE, offsetof(TkText, end), TK_OPTION_NULL_OK,
	 &lineOption, TK_TEXT_LINE_RANGE},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_TEXT_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(TkText, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_TEXT_FONT, TCL_INDEX_NONE, offsetof(TkText, tkfont), 0, 0,
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_TEXT_FG, TCL_INDEX_NONE, offsetof(TkText, fgColor), 0,
	0, 0},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TEXT_HEIGHT, TCL_INDEX_NONE, offsetof(TkText, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_TEXT_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(TkText, highlightBgColorPtr),
	0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_TEXT_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkText, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_TEXT_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(TkText, highlightWidth), 0, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_BORDER, "-inactiveselectbackground","inactiveSelectBackground",
	"Foreground",
	DEF_TEXT_INACTIVE_SELECT_COLOR,
	TCL_INDEX_NONE, offsetof(TkText, inactiveSelBorder),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_MONO, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_TEXT_INSERT_BG,
	TCL_INDEX_NONE, offsetof(TkText, insertBorder),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_TEXT_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(TkText, insertBorderWidth), 0,
	(ClientData) DEF_TEXT_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_TEXT_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(TkText, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_TEXT_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(TkText, insertOnTime),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE,
	"-insertunfocussed", "insertUnfocussed", "InsertUnfocussed",
	DEF_TEXT_INSERT_UNFOCUSSED, TCL_INDEX_NONE, offsetof(TkText, insertUnfocussed),
	0, insertUnfocussedStrings, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_TEXT_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(TkText, insertWidth),
	0, 0, 0},
    {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo",
	DEF_TEXT_MAX_UNDO, TCL_INDEX_NONE, offsetof(TkText, maxUndo),
	TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_TEXT_PADX, TCL_INDEX_NONE, offsetof(TkText, padX), 0, 0,
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_TEXT_PADY, TCL_INDEX_NONE, offsetof(TkText, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_TEXT_RELIEF, TCL_INDEX_NONE, offsetof(TkText, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_TEXT_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkText, selBorder),
	0, DEF_TEXT_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_TEXT_SELECT_BD_COLOR,
	offsetof(TkText, selBorderWidthPtr),
	offsetof(TkText, selBorderWidth),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_TEXT_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(TkText, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	DEF_TEXT_SET_GRID, TCL_INDEX_NONE, offsetof(TkText, setGrid), 0, 0, 0},
    {TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing",
	DEF_TEXT_SPACING1, TCL_INDEX_NONE, offsetof(TkText, spacing1),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
	DEF_TEXT_SPACING2, TCL_INDEX_NONE, offsetof(TkText, spacing2),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
	DEF_TEXT_SPACING3, TCL_INDEX_NONE, offsetof(TkText, spacing3),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_CUSTOM, "-startline", NULL, NULL,
	 NULL, TCL_INDEX_NONE, offsetof(TkText, start), TK_OPTION_NULL_OK,
	 &lineOption, TK_TEXT_LINE_RANGE},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_TEXT_STATE, TCL_INDEX_NONE, offsetof(TkText, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-tabs", "tabs", "Tabs",
	DEF_TEXT_TABS, offsetof(TkText, tabOptionPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle",
	DEF_TEXT_TABSTYLE, TCL_INDEX_NONE, offsetof(TkText, tabStyle),
	0, tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_TEXT_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(TkText, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo",
	DEF_TEXT_UNDO, TCL_INDEX_NONE, offsetof(TkText, undo),
	TK_OPTION_DONT_SET_DEFAULT, 0 , 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_TEXT_WIDTH, TCL_INDEX_NONE, offsetof(TkText, width), 0, 0,
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap",
	DEF_TEXT_WRAP, TCL_INDEX_NONE, offsetof(TkText, wrapMode),
	0, wrapStrings, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_TEXT_XSCROLL_COMMAND, TCL_INDEX_NONE, offsetof(TkText, xScrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_TEXT_YSCROLL_COMMAND, TCL_INDEX_NONE, offsetof(TkText, yScrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0}
};

/*
 * These three typedefs, the structure and the SearchPerform, SearchCore
 * functions below are used for line-based searches of the text widget, and,







<
<
<
<
<
<
<
<
<
<














|



|




















|
|
<

|
|

|


|

|
|

|


|


|
|

|
|

|

|


|


|


|


|


|
|



|
|


|


|
|


|


|

<
<
<
<

|


|
<

|


|

|

|
|


|
|
|

|
|

|

|


|


|


|
|

|
|

|


|
|

|


|
<

|


|
|

|


|







68
69
70
71
72
73
74










75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177




178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
 * the string table below.
 */

static const char *const tabStyleStrings[] = {
    "tabular", "wordprocessor", NULL
};











/*
 * The following functions and custom option type are used to define the
 * "line" option type, and thereby handle the text widget '-startline',
 * '-endline' configuration options which are of that type.
 *
 * 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		SetLineStartEnd(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    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
};

/*
 * Information used to parse text configuration options:
 */

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_OPTION_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),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
	DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
	DEF_TEXT_SPACING3, -1, Tk_Offset(TkText, spacing3),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_CUSTOM, "-startline", NULL, NULL,
	 NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK,
	 (ClientData) &lineOption, TK_TEXT_LINE_RANGE},
    {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}
};

/*
 * These three typedefs, the structure and the SearchPerform, SearchCore
 * functions below are used for line-based searches of the text widget, and,
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
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,
			    TkSizeT matchOffset, TkSizeT matchLength);
typedef int		SearchLineIndexProc(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, struct SearchSpec *searchSpecPtr,
			    int *linePosPtr, TkSizeT *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. */
    TkSizeT startOffset;		/* Index in first line to start at. */
    int stopLine;		/* Last line to examine, or -1 when we search
				 * all available text. */
    TkSizeT 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 */







|


|















|


|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
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 */
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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 TkSizeT	TextFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT 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,







|
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
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,
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
			    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		GenerateUndoStackEvent(TkText *textPtr);
static void		UpdateDirtyFlag(TkSharedText *sharedPtr);
static void		TextPushUndoAction(TkText *textPtr,
			    Tcl_Obj *undoString, int insert,
			    const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr);
static TkSizeT		TextSearchIndexInLine(const SearchSpec *searchSpecPtr,
			    TkTextLine *linePtr, TkSizeT 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 functions that
 * can be invoked from generic window code.
 */

static const Tk_ClassProcs textClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TextWorldChangedCallback,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*







<





|
|


















|







383
384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
			    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(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 functions that
 * can be invoked from generic window code.
 */

static Tk_ClassProcs textClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TextWorldChangedCallback,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
int
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;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    return CreateWidget(NULL, tkwin, interp, NULL, objc, objv);
}

/*







|


|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
int
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;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
	return TCL_ERROR;
    }

    return CreateWidget(NULL, tkwin, interp, NULL, objc, objv);
}

/*
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
    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. */
{
    TkText *textPtr;
    Tk_OptionTable optionTable;
    TkTextIndex startIndex;
    Tk_Window newWin;

    /*
     * Create the window.
     */

    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. It is important that the 'set' tag
     * and 'insert', 'current' mark pointers are all NULL to start.
     */

    textPtr = (TkText *)ckalloc(sizeof(TkText));
    memset(textPtr, 0, sizeof(TkText));

    textPtr->tkwin = newWin;
    textPtr->display = Tk_Display(newWin);
    textPtr->interp = interp;
    textPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(textPtr->tkwin), TextWidgetObjCmd,
	    textPtr, TextCmdDeletedProc);

    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 = 0;
	sharedPtr->isDirty = 0;
	sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
	sharedPtr->autoSeparators = 1;
	sharedPtr->lastEditMode = TK_TEXT_EDIT_OTHER;
	sharedPtr->stateEpoch = 0;
    }








|




















|







|


|











|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
    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.
     */

    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. It is important that the 'set' tag
     * and 'insert', 'current' mark pointers are all NULL to start.
     */

    textPtr = (TkText *) ckalloc(sizeof(TkText));
    memset(textPtr, 0, sizeof(TkText));

    textPtr->tkwin = newWin;
    textPtr->display = Tk_Display(newWin);
    textPtr->interp = interp;
    textPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(textPtr->tkwin), TextWidgetObjCmd,
	    (ClientData) textPtr, TextCmdDeletedProc);

    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;
    }

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
     * 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, textPtr);
    textPtr->optionTable = optionTable;

    Tk_CreateEventHandler(textPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    TextEventProc, textPtr);
    Tk_CreateEventHandler(textPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    TkTextBindProc, textPtr);
    Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING,
	    TextFetchSelection, textPtr, XA_STRING);

    if (Tk_InitOptions(interp, 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_SetObjResult(interp, Tk_NewWindowObj(textPtr->tkwin));

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TextWidgetObjCmd --







|




|



|

|

|









|
>







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
     * 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);
    Tk_CreateEventHandler(textPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    TkTextBindProc, (ClientData) textPtr);
    Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING,
	    TextFetchSelection, (ClientData) textPtr, XA_STRING);

    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_SetObjResult(interp,
	    Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TextWidgetObjCmd --
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
static int
TextWidgetObjCmd(
    ClientData clientData,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkText *textPtr = (TkText *)clientData;
    int result = TCL_OK;
    int idx;

    static const char *const optionStrings[] = {
	"bbox", "cget", "compare", "configure", "count", "debug", "delete",
	"dlineinfo", "dump", "edit", "get", "image", "index", "insert",
	"mark", "peer", "pendingsync", "replace", "scan", "search",
	"see", "sync", "tag", "window", "xview", "yview", NULL
    };
    enum options {
	TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT,
	TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT,
	TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK,
	TEXT_PEER, TEXT_PENDINGSYNC, TEXT_REPLACE, TEXT_SCAN,
	TEXT_SEARCH, TEXT_SEE, TEXT_SYNC, TEXT_TAG, TEXT_WINDOW,
	TEXT_XVIEW, TEXT_YVIEW
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    textPtr->refCount++;

    switch ((enum options) idx) {
    case TEXT_BBOX: {
	int x, y, width, height;
	const TkTextIndex *indexPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    result = TCL_ERROR;
	    goto done;
	}
	indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
	if (indexPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	if (TkTextIndexBbox(textPtr, indexPtr, &x, &y, &width, &height,
		NULL) == 0) {
	    Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);

	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(x));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(y));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(width));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(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, textPtr,
		    textPtr->optionTable, objv[2], textPtr->tkwin);

	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    result = TCL_OK;

	}
	break;
    case TEXT_COMPARE: {
	int relation, value;
	const char *p;
	const TkTextIndex *index1Ptr, *index2Ptr;








|

|

|


|
|





|
<
|



|



|
|




|


















|
|
|
|











|

<



|
|
|
>







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
static int
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 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 (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    textPtr->refCount++;

    switch ((enum options) index) {
    case TEXT_BBOX: {
	int x, y, width, height;
	const TkTextIndex *indexPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    result = TCL_ERROR;
	    goto done;
	}
	indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
	if (indexPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	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;
	    }
	}
	break;
    case TEXT_COMPARE: {
	int relation, value;
	const char *p;
	const TkTextIndex *index1Ptr, *index2Ptr;

793
794
795
796
797
798
799
800





801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872








873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
	relation = TkTextIndexCmp(index1Ptr, index2Ptr);
	p = Tcl_GetString(objv[3]);
	if (p[0] == '<') {
	    value = (relation < 0);
	    if ((p[1] == '=') && (p[2] == 0)) {
		value = (relation <= 0);
	    } else if (p[1] != 0) {
		goto compareError;





	    }
	} else if (p[0] == '>') {
	    value = (relation > 0);
	    if ((p[1] == '=') && (p[2] == 0)) {
		value = (relation >= 0);
	    } else if (p[1] != 0) {
		goto compareError;
	    }
	} else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) {
	    value = (relation == 0);
	} else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) {
	    value = (relation != 0);
	} else {
	    goto compareError;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
	break;

    compareError:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad comparison operator \"%s\": must be"
		" <, <=, ==, >=, >, or !=", Tcl_GetString(objv[3])));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "COMPARISON", NULL);
	result = TCL_ERROR;
	goto done;
    }
    case TEXT_CONFIGURE:
	if (objc <= 3) {
	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, textPtr,
		    textPtr->optionTable, ((objc == 3) ? objv[2] : NULL),
		    textPtr->tkwin);

	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	} else {
	    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,
		    "?-option value ...? 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;
	}

	for (i = 2; i < objc-2; i++) {
	    int value;
	    TkSizeT length;
	    const char *option = TkGetStringFromObj(objv[i], &length);
	    char c;

	    if (length < 2 || option[0] != '-') {
		goto badOption;








	    }
	    c = option[1];
	    if (c == 'c' && !strncmp("-chars", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaychars", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displayindices", option,length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_INDICES);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaylines", option, length)) {
		TkTextLine *fromPtr, *lastPtr;
		TkTextIndex index, index2;

		int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
		value = 0;

		if (compare == 0) {







|
>
>
>
>
>

















<
<
<
<
<
<
<
<



|


<



|
|
>










|
<
















|
<
|



|
>
>
>
>
>
>
>
>


|



|



|



|







775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804








805
806
807
808
809
810

811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827

828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
	relation = TkTextIndexCmp(index1Ptr, index2Ptr);
	p = Tcl_GetString(objv[3]);
	if (p[0] == '<') {
	    value = (relation < 0);
	    if ((p[1] == '=') && (p[2] == 0)) {
		value = (relation <= 0);
	    } else if (p[1] != 0) {
	    compareError:
		Tcl_AppendResult(interp, "bad comparison operator \"",
			Tcl_GetString(objv[3]),
			"\": must be <, <=, ==, >=, >, or !=", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else if (p[0] == '>') {
	    value = (relation > 0);
	    if ((p[1] == '=') && (p[2] == 0)) {
		value = (relation >= 0);
	    } else if (p[1] != 0) {
		goto compareError;
	    }
	} else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) {
	    value = (relation == 0);
	} else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) {
	    value = (relation != 0);
	} else {
	    goto compareError;
	}
	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, 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;
	}

	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, index2;

		int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
		value = 0;

		if (compare == 0) {
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
		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' (except if this line is elided), and
		 * then subtract off what came in too much from elided lines,
		 * also subtract off what we didn't want from 'from' and add
		 * on what we didn't count from 'to'.
		 */

		while (TkTextIndexCmp(&index,indexToPtr) < 0) {
		    value += TkTextUpdateOneLine(textPtr, index.linePtr,
			    0, &index, 0);
		}

		index2 = index;

		/*
		 * Now we need to adjust the count to:
		 *   - subtract off the number of display lines between
		 *     indexToPtr and index2, since we might have skipped past
		 *     indexToPtr, if we have several logical lines in a
		 *     single display line
		 *   - subtract off the number of display lines overcounted
		 *     in the first logical line
		 *   - add on the number of display lines in the last logical
		 *     line
		 * This logic is still ok if both indexFromPtr and indexToPtr
		 * are in the same logical line.
		 */

		index = *indexToPtr;
		index.byteIndex = 0;
		while (TkTextIndexCmp(&index,&index2) < 0) {
		    value -= TkTextUpdateOneLine(textPtr, index.linePtr,
			    0, &index, 0);
		}
		index.linePtr = indexFromPtr->linePtr;
		index.byteIndex = 0;
		while (1) {
		    TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
		    if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
			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 (TkTextIndexCmp(&index,indexToPtr) >= 0) {
			    break;
			}
			TkTextIndexForwBytes(textPtr, &index, 1, &index);
			value++;
		    }
		}

		if (compare > 0) {
		    value = -value;
		}
	    } else if (c == 'i'
		    && !strncmp("-indices", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_INDICES);
	    } else if (c == 'l'
		    && !strncmp("-lines", option, length)) {
		value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr)
			- TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
	    } else if (c == 'u'
		    && !strncmp("-update", option, length)) {
		update = 1;
		continue;
	    } else if (c == 'x'
		    && !strncmp("-xpixels", option, 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, 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_NewWideIntObj(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_NewWideIntObj(value));
	    }
	}

	if (found == 0) {
	    /*
	     * Use the default '-indices'.
	     */

	    int value = CountIndices(textPtr, indexFromPtr, indexToPtr,
		    COUNT_INDICES);

	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
	} else if (found > 1) {
	    Tcl_SetObjResult(interp, objPtr);
	}
	break;

    badOption:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad option \"%s\": must be -chars, -displaychars, "
		"-displayindices, -displaylines, -indices, -lines, -update, "
		"-xpixels, or -ypixels", Tcl_GetString(objv[i])));
	Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_OPTION", NULL);
	result = TCL_ERROR;
	goto done;
    }
    case TEXT_DEBUG:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "boolean");
	    result = TCL_ERROR;
	    goto done;
	}







|
|



|

|


|

|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|




|











|











|



|



|



|









|














|











|











|




<
<
<
<
<
<
<
<
<







903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035









1036
1037
1038
1039
1040
1041
1042
		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' (except if this line is elided), and
                 * then subtract off what came in too much from elided lines,
                 * also subtract off what we didn't want from 'from' and add
		 * on what we didn't count from 'to'.
		 */

                while (TkTextIndexCmp(&index,indexToPtr) < 0) {
		    value += TkTextUpdateOneLine(textPtr, index.linePtr,
                            0, &index, 0);
		}

                index2 = index;

                /*
                 * Now we need to adjust the count to:
                 *   - subtract off the number of display lines between 
                 *     indexToPtr and index2, since we might have skipped past
                 *     indexToPtr, if we have several logical lines in a
                 *     single display line
                 *   - subtract off the number of display lines overcounted
                 *     in the first logical line
                 *   - add on the number of display lines in the last logical
                 *     line
                 * This logic is still ok if both indexFromPtr and indexToPtr
                 * are in the same logical line.
                 */

                index = *indexToPtr;
                index.byteIndex = 0;
                while (TkTextIndexCmp(&index,&index2) < 0) {
                    value -= TkTextUpdateOneLine(textPtr, index.linePtr,
                            0, &index, 0);
                }
		index.linePtr = indexFromPtr->linePtr;
		index.byteIndex = 0;
		while (1) {
		    TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
                    if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
			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 (TkTextIndexCmp(&index,indexToPtr) >= 0) {
			    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;
	}
1121
1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

		TkTextIndex *indices, *ixStart, *ixEnd, *lastStart;
		char *useIdx;
		int i;

		objc -= 2;
		objv += 2;
		indices = (TkTextIndex *)ckalloc((objc + 1) * sizeof(TkTextIndex));


		/*
		 * First pass verifies that all indices are valid.
		 */

		for (i = 0; i < objc; i++) {
		    const TkTextIndex *indexPtr =
			    TkTextGetIndexFromObj(interp, textPtr, objv[i]);

		    if (indexPtr == NULL) {
			result = TCL_ERROR;
			ckfree(indices);
			goto done;
		    }
		    indices[i] = *indexPtr;
		}

		/*
		 * Pad out the pairs evenly to make later code easier.
		 */

		if (objc & 1) {
		    indices[i] = indices[i-1];
		    TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i],
			    COUNT_INDICES);
		    objc++;
		}
		useIdx = (char *)ckalloc(objc);
		memset(useIdx, 0, objc);

		/*
		 * Do a decreasing order sort so that we delete the end ranges
		 * first to maintain index consistency.
		 */

		qsort(indices, (size_t) objc / 2,
			2 * sizeof(TkTextIndex), TextIndexSortProc);
		lastStart = NULL;

		/*
		 * Second pass will handle bogus ranges (end < start) and
		 * overlapping ranges.
		 */







|
>











|















|
|






|







1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

		TkTextIndex *indices, *ixStart, *ixEnd, *lastStart;
		char *useIdx;
		int i;

		objc -= 2;
		objv += 2;
		indices = (TkTextIndex *)
			ckalloc((objc + 1) * sizeof(TkTextIndex));

		/*
		 * First pass verifies that all indices are valid.
		 */

		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 (objc & 1) {
		    indices[i] = indices[i-1];
		    TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i],
			    COUNT_INDICES);
		    objc++;
		}
		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.
		 */

		qsort(indices, (unsigned) objc / 2,
			2 * sizeof(TkTextIndex), TextIndexSortProc);
		lastStart = NULL;

		/*
		 * Second pass will handle bogus ranges (end < start) and
		 * overlapping ranges.
		 */
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
			 * indices are preparsed above.
			 */

			DeleteIndexRange(NULL, textPtr, &indices[i],
				&indices[i+1], 1);
		    }
		}
		ckfree(indices);
	    }
	}
	break;
    case TEXT_DLINEINFO: {
	int x, y, width, height, base;
	const TkTextIndex *indexPtr;








|







1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
			 * indices are preparsed above.
			 */

			DeleteIndexRange(NULL, textPtr, &indices[i],
				&indices[i+1], 1);
		    }
		}
		ckfree((char *) indices);
	    }
	}
	break;
    case TEXT_DLINEINFO: {
	int x, y, width, height, base;
	const TkTextIndex *indexPtr;

1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
	    result = TCL_ERROR;
	    goto done;
	}
	if (TkTextDLineInfo(textPtr, indexPtr, &x, &y, &width, &height,
		&base) == 0) {
	    Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);

	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(x));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(y));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(width));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(height));
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(base));

	    Tcl_SetObjResult(interp, listObj);
	}
	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;
	int i, found = 0, visible = 0;
	const char *name;
	TkSizeT length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displaychars? ?--? index1 ?index2 ...?");
	    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 = TkGetStringFromObj(objv[i], &length);
	    if (length > 1 && name[0] == '-') {
		if (strncmp("-displaychars", name, length) == 0) {
		    i++;
		    visible = 1;
		    name = TkGetStringFromObj(objv[i], &length);
		}
		if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
		    i++;
		}
	    }
	}








|
|
|
|
|















|















|

|


|







1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
	    result = TCL_ERROR;
	    goto done;
	}
	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);
	}
	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;
	int i, found = 0, visible = 0;
	const char *name;
	int length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displaychars? ?--? index1 ?index2 ...?");
	    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++;
		}
	    }
	}

1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
    }
    case TEXT_MARK:
	result = TkTextMarkCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_PEER:
	result = TextPeerCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_PENDINGSYNC: {
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(TkTextPendingsync(textPtr)));
	break;
    }
    case TEXT_REPLACE: {
	const TkTextIndex *indexFromPtr, *indexToPtr;

	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_SetObjResult(interp, Tcl_ObjPrintf(
		    "index \"%s\" before \"%s\" in the text",
		    Tcl_GetString(objv[3]), Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	if (textPtr->state == TK_TEXT_STATE_NORMAL) {
	    int lineNum, byteIndex;
	    TkTextIndex index;








<
<
<
<
<
<
<
<
<
<




















|
<
|
|







1368
1369
1370
1371
1372
1373
1374










1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1403
1404
    }
    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;

1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
		    && (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, indexFromLine, indexFromByteOffset;

		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;
		}

                indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
                indexFromByteOffset = indexFromPtr->byteIndex;

		result = TextReplaceCmd(textPtr, interp, indexFromPtr,
			indexToPtr, objc, objv, 0);

		if (result == TCL_OK) {
		    /*
		     * Move the insertion position to the correct place.
		     */

                    TkTextIndex indexTmp;

                    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine,
                            indexFromByteOffset, &indexTmp);
                    TkTextIndexForwChars(NULL, &indexTmp,
			    deleteInsertOffset, &index, COUNT_INDICES);
		    TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
			    textPtr->insertMarkPtr->body.mark.linePtr);
		    TkBTreeLinkSegment(textPtr->insertMarkPtr, &index);
		}
	    } else {
		result = TextReplaceCmd(textPtr, interp, indexFromPtr,







|

















<
<
<








<
<
<
<
|







1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448



1449
1450
1451
1452
1453
1454
1455
1456




1457
1458
1459
1460
1461
1462
1463
1464
		    && (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,
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
1584
1585
	break;
    case TEXT_SEARCH:
	result = TextSearchCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_SEE:
	result = TkTextSeeCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_SYNC: {
	if (objc == 4) {
	    Tcl_Obj *cmd = objv[3];
	    const char *option = Tcl_GetString(objv[2]);
	    if (strncmp(option, "-command", objv[2]->length)) {
		Tcl_AppendResult(interp, "wrong option \"", option, "\": should be \"-command\"", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_IncrRefCount(cmd);
	    if (TkTextPendingsync(textPtr)) {
		if (textPtr->afterSyncCmd) {
		    Tcl_DecrRefCount(textPtr->afterSyncCmd);
		}
		textPtr->afterSyncCmd = cmd;
	    } else {
		textPtr->afterSyncCmd = cmd;
		Tcl_DoWhenIdle(TkTextRunAfterSyncCmd, (ClientData) textPtr);
	    }
	    break;
	} else if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-command command?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (textPtr->afterSyncCmd) {
	    Tcl_DecrRefCount(textPtr->afterSyncCmd);
	}
	textPtr->afterSyncCmd = NULL;
	TkTextUpdateLineMetrics(textPtr, 0,
		TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1);
	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:

    if (textPtr->refCount-- <= 1) {
	ckfree(textPtr);
    }
    return result;
}

/*
 *--------------------------------------------------------------
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















>
|
|







1481
1482
1483
1484
1485
1486
1487

































1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
	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;
}

/*
 *--------------------------------------------------------------
 *
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
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. */
{
    TkSharedText *sharedPtr = (TkSharedText *)clientData;
    int result = TCL_OK;
    int index;

    static const char *const optionStrings[] = {
	"delete", "insert", NULL
    };
    enum options {
	TEXT_DELETE, TEXT_INSERT
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "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 ...?");







|



|







|



|
|







1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
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 ...?");
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
    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 *const peerOptionStrings[] = {
	"create", "names", NULL
    };
    enum peerOptions {
	PEER_CREATE, PEER_NAMES
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], peerOptionStrings,
	    sizeof(char *), "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 ?-option value ...?");
	    return TCL_ERROR;
	}
	return CreateWidget(textPtr->sharedTextPtr, tkwin, interp, textPtr,
		objc-2, objv+2);
    case PEER_NAMES: {
	TkText *tPtr = textPtr->sharedTextPtr->peers;
	Tcl_Obj *peersObj;

	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	peersObj = Tcl_NewObj();
	while (tPtr != NULL) {
	    if (tPtr != textPtr) {
		Tcl_ListObjAppendElement(NULL, peersObj,
			Tk_NewWindowObj(tPtr->tkwin));
	    }
	    tPtr = tPtr->next;
	}
	Tcl_SetObjResult(interp, peersObj);
    }
    }

    return TCL_OK;
}

/*







|







|



|
|



|


|






<





<


|
<



<







1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677

1678
1679
1680

1681
1682
1683

1684
1685
1686
1687
1688
1689
1690
    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;
}

/*
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969


1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
     * 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(textPtr->insertMarkPtr);
    TkBTreeUnlinkSegment(textPtr->currentMarkPtr,
	    textPtr->currentMarkPtr->body.mark.linePtr);
    ckfree(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.
     */



    if (sharedTextPtr->refCount-- > 1) {
	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;







|


|









>
>
|









|







1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
     * 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;
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045

2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
	 * 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(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(sharedTextPtr);
    }

    if (textPtr->tabArrayPtr != NULL) {
	ckfree(textPtr->tabArrayPtr);
    }
    if (textPtr->insertBlinkHandler != NULL) {
	Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
    }

    textPtr->tkwin = NULL;

    Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);
    if (textPtr->afterSyncCmd){
	Tcl_DecrRefCount(textPtr->afterSyncCmd);
	textPtr->afterSyncCmd = NULL;
    }
    if (textPtr->refCount-- <= 1) {
	ckfree(textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureText --







|











|










|



|






>

<
<
<
<
|
|







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972




1973
1974
1975
1976
1977
1978
1979
1980
1981
	 * 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);
    }

    textPtr->tkwin = NULL;
    textPtr->refCount--;
    Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);




    if (textPtr->refCount == 0) {
	ckfree((char *) textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureText --
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureText(
    Tcl_Interp *interp,		/* Used for error reporting. */
    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) && (!Tcl_IsSafe(textPtr->interp));
    int mask = 0;

    if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable,
	    objc, objv, textPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Copy down shared flags.
     */

    textPtr->sharedTextPtr->undo = textPtr->undo;
    textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo;
    textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators;

    TkUndoSetMaxDepth(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.
     */








|





|















|







1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
 *
 *----------------------------------------------------------------------
 */

static int
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_SetOptions(interp, (char *) textPtr, textPtr->optionTable,
	    objc, objv, textPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * 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.
     */

2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
	}
	if (textPtr->end != NULL) {
	    end = TkBTreeLinesTo(NULL, textPtr->end);
	} else {
	    end = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL);
	}
	if (start > end) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "-startline must be less than or equal to -endline", -1));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL);
	    Tk_RestoreSavedOptions(&savedOptions);
	    return TCL_ERROR;
	}
	current = TkBTreeLinesTo(NULL, textPtr->topIndex.linePtr);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
		    &index1);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,







|
|
|







2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
	}
	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,
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
		    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;







<







2082
2083
2084
2085
2086
2087
2088

2089
2090
2091
2092
2093
2094
2095
		    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;
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
	}

	/* 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);
	}







|
|
|
|







2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
	}

	/* 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);
	}
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
    }

    /*
     * Parse tab stops.
     */

    if (textPtr->tabArrayPtr != NULL) {
	ckfree(textPtr->tabArrayPtr);
	textPtr->tabArrayPtr = NULL;
    }
    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.
     */

    if (textPtr->selTagPtr->selBorder == NULL) {
	textPtr->selTagPtr->border = textPtr->selBorder;
    } else {
	textPtr->selTagPtr->selBorder = textPtr->selBorder;
    }
    if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) {
	textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr;
	textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth;
    }
    if (textPtr->selTagPtr->selFgColor == NULL) {
	textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
    } else {
	textPtr->selTagPtr->selFgColor = textPtr->selFgColorPtr;
    }
    textPtr->selTagPtr->affectsDisplay = 0;
    textPtr->selTagPtr->affectsDisplayGeometry = 0;
    if ((textPtr->selTagPtr->elideString != NULL)
	    || (textPtr->selTagPtr->tkfont != NULL)
	    || (textPtr->selTagPtr->justifyString != NULL)
	    || (textPtr->selTagPtr->lMargin1String != NULL)
	    || (textPtr->selTagPtr->lMargin2String != NULL)
	    || (textPtr->selTagPtr->offsetString != NULL)
	    || (textPtr->selTagPtr->rMarginString != NULL)
	    || (textPtr->selTagPtr->spacing1String != NULL)
	    || (textPtr->selTagPtr->spacing2String != NULL)
	    || (textPtr->selTagPtr->spacing3String != NULL)
	    || (textPtr->selTagPtr->tabStringPtr != NULL)
	    || (textPtr->selTagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
	textPtr->selTagPtr->affectsDisplay = 1;
	textPtr->selTagPtr->affectsDisplayGeometry = 1;
    }
    if ((textPtr->selTagPtr->border != NULL)
	    || (textPtr->selTagPtr->selBorder != NULL)
	    || (textPtr->selTagPtr->reliefString != NULL)
	    || (textPtr->selTagPtr->bgStipple != None)
	    || (textPtr->selTagPtr->fgColor != NULL)
	    || (textPtr->selTagPtr->selFgColor != NULL)
	    || (textPtr->selTagPtr->fgStipple != None)
	    || (textPtr->selTagPtr->overstrikeString != NULL)
	    || (textPtr->selTagPtr->overstrikeColor != NULL)
	    || (textPtr->selTagPtr->underlineString != NULL)
	    || (textPtr->selTagPtr->underlineColor != NULL)
	    || (textPtr->selTagPtr->lMarginColor != NULL)
	    || (textPtr->selTagPtr->rMarginColor != NULL)) {
	textPtr->selTagPtr->affectsDisplay = 1;
    }
    TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1);

    /*
     * Claim the selection if we've suddenly started exporting it and there
     * are tagged characters.
     */

    if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) {
	TkTextSearch search;
	TkTextIndex first, 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)) {
	    Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection,
		    textPtr);
	    textPtr->flags |= GOT_SELECTION;
	}
    }

    /*
     * Account for state changes that would reenable blinking cursor state.
     */

    if (textPtr->flags & GOT_FOCUS) {
	Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
	textPtr->insertBlinkHandler = NULL;
	TextBlinkProc(textPtr);
    }

    /*
     * Register the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */








|



















<
|
<
<
<




<
|
<
<
<


















<



<


<
|
<
<
<









|












|










|
|







2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180

2181



2182
2183
2184
2185

2186



2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204

2205
2206
2207

2208
2209

2210



2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
    }

    /*
     * Parse tab stops.
     */

    if (textPtr->tabArrayPtr != NULL) {
	ckfree((char *) textPtr->tabArrayPtr);
	textPtr->tabArrayPtr = NULL;
    }
    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.
     */


    textPtr->selTagPtr->border = textPtr->selBorder;



    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;
    textPtr->selTagPtr->affectsDisplayGeometry = 0;
    if ((textPtr->selTagPtr->elideString != NULL)
	    || (textPtr->selTagPtr->tkfont != NULL)
	    || (textPtr->selTagPtr->justifyString != NULL)
	    || (textPtr->selTagPtr->lMargin1String != NULL)
	    || (textPtr->selTagPtr->lMargin2String != NULL)
	    || (textPtr->selTagPtr->offsetString != NULL)
	    || (textPtr->selTagPtr->rMarginString != NULL)
	    || (textPtr->selTagPtr->spacing1String != NULL)
	    || (textPtr->selTagPtr->spacing2String != NULL)
	    || (textPtr->selTagPtr->spacing3String != NULL)
	    || (textPtr->selTagPtr->tabStringPtr != NULL)
	    || (textPtr->selTagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
	textPtr->selTagPtr->affectsDisplay = 1;
	textPtr->selTagPtr->affectsDisplayGeometry = 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
     * are tagged characters.
     */

    if (textPtr->exportSelection && (!oldExport)) {
	TkTextSearch search;
	TkTextIndex first, 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)) {
	    Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection,
		    (ClientData) textPtr);
	    textPtr->flags |= GOT_SELECTION;
	}
    }

    /*
     * Account for state changes that would reenable blinking cursor state.
     */

    if (textPtr->flags & GOT_FOCUS) {
	Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
	textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
	TextBlinkProc((ClientData) textPtr);
    }

    /*
     * Register the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */

2374
2375
2376
2377
2378
2379
2380
2381
2382

2383
2384
2385
2386
2387
2388
2389
 *---------------------------------------------------------------------------
 */

static void
TextWorldChangedCallback(
    ClientData instanceData)	/* Information about widget. */
{
    TkText *textPtr = (TkText *)instanceData;


    TextWorldChanged(textPtr, TK_TEXT_LINE_GEOMETRY);
}

/*
 *---------------------------------------------------------------------------
 *
 * TextWorldChanged --







|

>







2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
 *---------------------------------------------------------------------------
 */

static void
TextWorldChangedCallback(
    ClientData instanceData)	/* Information about widget. */
{
    TkText *textPtr;

    textPtr = (TkText *) instanceData;
    TextWorldChanged(textPtr, TK_TEXT_LINE_GEOMETRY);
}

/*
 *---------------------------------------------------------------------------
 *
 * TextWorldChanged --
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    textPtr->charHeight = fm.linespace;
    if (textPtr->charHeight <= 0) {
	textPtr->charHeight = 1;
    }
    if (textPtr->charHeight != oldCharHeight) {
	TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
    }
    border = textPtr->borderWidth + textPtr->highlightWidth;
    Tk_GeometryRequest(textPtr->tkwin,
	    textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
	    textPtr->height*(fm.linespace+textPtr->spacing1+textPtr->spacing3)
		    + 2*textPtr->padY + 2*border);








|







2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    textPtr->charHeight = fm.linespace;
    if (textPtr->charHeight <= 0) {
	textPtr->charHeight = 1;
    }
    if (textPtr->charHeight != oldCharHeight) {
        TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
    }
    border = textPtr->borderWidth + textPtr->highlightWidth;
    Tk_GeometryRequest(textPtr->tkwin,
	    textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
	    textPtr->height*(fm.linespace+textPtr->spacing1+textPtr->spacing3)
		    + 2*textPtr->padY + 2*border);

2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
 *
 *--------------------------------------------------------------
 */

static void
TextEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)	/* Information about event. */
{
    TkText *textPtr = (TkText *)clientData;
    TkTextIndex index, index2;

    if (eventPtr->type == Expose) {
	TkTextRedrawRegion(textPtr, eventPtr->xexpose.x,
		eventPtr->xexpose.y, eventPtr->xexpose.width,
		eventPtr->xexpose.height);
    } else if (eventPtr->type == ConfigureNotify) {







|

|







2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
 *
 *--------------------------------------------------------------
 */

static void
TextEventProc(
    ClientData clientData,	/* Information about window. */
    register XEvent *eventPtr)	/* Information about event. */
{
    register TkText *textPtr = (TkText *) clientData;
    TkTextIndex index, index2;

    if (eventPtr->type == Expose) {
	TkTextRedrawRegion(textPtr, eventPtr->xexpose.x,
		eventPtr->xexpose.y, eventPtr->xexpose.width,
		eventPtr->xexpose.height);
    } else if (eventPtr->type == ConfigureNotify) {
2525
2526
2527
2528
2529
2530
2531
2532

2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
		|| eventPtr->xfocus.detail == NotifyAncestor
		|| eventPtr->xfocus.detail == NotifyNonlinear) {
	    Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
	    if (eventPtr->type == FocusIn) {
		textPtr->flags |= GOT_FOCUS | INSERT_ON;
		if (textPtr->insertOffTime != 0) {
		    textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
			    textPtr->insertOnTime, TextBlinkProc, textPtr);

		}
	    } else {
		textPtr->flags &= ~(GOT_FOCUS | INSERT_ON);
		textPtr->insertBlinkHandler = NULL;
	    }
	    if (textPtr->inactiveSelBorder != textPtr->selBorder) {
		TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr,
			1);
	    }
	    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	    TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);







|
>



|







2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
		|| eventPtr->xfocus.detail == NotifyAncestor
		|| eventPtr->xfocus.detail == NotifyNonlinear) {
	    Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
	    if (eventPtr->type == FocusIn) {
		textPtr->flags |= GOT_FOCUS | INSERT_ON;
		if (textPtr->insertOffTime != 0) {
		    textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
			    textPtr->insertOnTime, TextBlinkProc,
			    (ClientData) textPtr);
		}
	    } else {
		textPtr->flags &= ~(GOT_FOCUS | INSERT_ON);
		textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
	    }
	    if (textPtr->inactiveSelBorder != textPtr->selBorder) {
		TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr,
			1);
	    }
	    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	    TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
 *----------------------------------------------------------------------
 */

static void
TextCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkText *textPtr = (TkText *)clientData;
    Tk_Window tkwin = textPtr->tkwin;

    /*
     * 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.







|







2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
 *----------------------------------------------------------------------
 */

static void
TextCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkText *textPtr = (TkText *) clientData;
    Tk_Window tkwin = textPtr->tkwin;

    /*
     * 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.
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638

2639
2640
2641
2642
2643
2644
2645
2646
    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;
    TkSizeT length;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];

    const char *string = TkGetStringFromObj(stringPtr, &length);

    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Don't allow insertions on the last (dummy) line of the text. This is







|
<




>
|







2535
2536
2537
2538
2539
2540
2541
2542

2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
    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, length;

    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];

    const char *string = Tcl_GetStringFromObj(stringPtr, &length);

    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Don't allow insertions on the last (dummy) line of the text. This is
2659
2660
2661
2662
2663
2664
2665

2666
2667
2668
2669
2670
2671
2672
2673
     * 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.
     */

    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] =







>
|







2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
     * 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.
     */

    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] =
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
			lineAndByteIndex[resetViewCount+1], &newTop);
		TkTextSetYView(tPtr, &newTop, 0);
	    }
	}
	resetViewCount += 2;
    }
    if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
	ckfree(lineAndByteIndex);
    }

    /*
     * Invalidate any selection retrievals in progress, and send an event
     * that the selection changed if that is the case.
     */

    for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
        if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) {
            TkTextSelectionEvent(tPtr);
        }
	tPtr->abortSelections = 1;
    }

    /*
     * For convenience, return the length of the string.
     */








|



|
<



<
<
<







2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642

2643
2644
2645



2646
2647
2648
2649
2650
2651
2652
			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;
    }

    /*
     * For convenience, return the length of the string.
     */

2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
    int insert,			/* 1 if insert, else delete. */
    const TkTextIndex *index1Ptr,
				/* Index describing first location. */
    const TkTextIndex *index2Ptr)
				/* Index describing second location. */
{
    TkUndoSubAtom *iAtom, *dAtom;
    int canUndo, canRedo;
    char lMarkName[20] = "tk::undoMarkL";
    char rMarkName[20] = "tk::undoMarkR";
    char stringUndoMarkId[16] = "";

    /*
     * Create the helpers.
     */

    Tcl_Obj *seeInsertObj = Tcl_NewObj();
    Tcl_Obj *markSet1InsertObj = Tcl_NewObj();
    Tcl_Obj *markSet2InsertObj = NULL;
    Tcl_Obj *insertCmdObj = Tcl_NewObj();
    Tcl_Obj *deleteCmdObj = Tcl_NewObj();
    Tcl_Obj *markSetLUndoMarkCmdObj = Tcl_NewObj();
    Tcl_Obj *markSetRUndoMarkCmdObj = NULL;
    Tcl_Obj *markGravityLUndoMarkCmdObj = Tcl_NewObj();
    Tcl_Obj *markGravityRUndoMarkCmdObj = NULL;

    /*
     * Get the index positions.
     */

    Tcl_Obj *index1Obj = TkTextNewIndexObj(NULL, index1Ptr);
    Tcl_Obj *index2Obj = TkTextNewIndexObj(NULL, index2Ptr);







<
<
<
<










<
<
<
<







2679
2680
2681
2682
2683
2684
2685




2686
2687
2688
2689
2690
2691
2692
2693
2694
2695




2696
2697
2698
2699
2700
2701
2702
    int insert,			/* 1 if insert, else delete. */
    const TkTextIndex *index1Ptr,
				/* Index describing first location. */
    const TkTextIndex *index2Ptr)
				/* Index describing second location. */
{
    TkUndoSubAtom *iAtom, *dAtom;





    /*
     * Create the helpers.
     */

    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);
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
    Tcl_ListObjAppendElement(NULL, insertCmdObj, undoString);

    Tcl_ListObjAppendElement(NULL, deleteCmdObj,
	    Tcl_NewStringObj("delete", 6));
    Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj);
    Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj);

    Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
	    Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
    Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
	    Tcl_NewStringObj("mark", 4));
    Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
	    Tcl_NewStringObj("set", 3));
    markSetRUndoMarkCmdObj = Tcl_DuplicateObj(markSetLUndoMarkCmdObj);
    textPtr->sharedTextPtr->undoMarkId++;
    sprintf(stringUndoMarkId, "%d", textPtr->sharedTextPtr->undoMarkId);
    strcat(lMarkName, stringUndoMarkId);
    strcat(rMarkName, stringUndoMarkId);
    Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
	    Tcl_NewStringObj(lMarkName, -1));
    Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj,
	    Tcl_NewStringObj(rMarkName, -1));
    Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, index1Obj);
    Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, index2Obj);

    Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
	    Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
    Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
	    Tcl_NewStringObj("mark", 4));
    Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
	    Tcl_NewStringObj("gravity", 7));
    markGravityRUndoMarkCmdObj = Tcl_DuplicateObj(markGravityLUndoMarkCmdObj);
    Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
	    Tcl_NewStringObj(lMarkName, -1));
    Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj,
	    Tcl_NewStringObj(rMarkName, -1));
    Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
            Tcl_NewStringObj("left", 4));
    Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj,
            Tcl_NewStringObj("right", 5));

    /*
     * 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, textPtr->sharedTextPtr,
	    insertCmdObj, NULL);
    TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom);
    TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom);
    TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, iAtom);
    TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, iAtom);
    TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, iAtom);
    TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, iAtom);

    dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr,
	    deleteCmdObj, NULL);
    TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, dAtom);

    Tcl_DecrRefCount(seeInsertObj);
    Tcl_DecrRefCount(index1Obj);
    Tcl_DecrRefCount(index2Obj);

    canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
    canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);

    /*
     * Depending whether the action is to insert or delete, we provide the
     * appropriate second and third arguments to TkUndoPushAction. (The first
     * is the 'actionCommand', and the second the 'revertCommand').
     */

    if (insert) {
	TkUndoPushAction(textPtr->sharedTextPtr->undoStack, iAtom, dAtom);
    } else {
	TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
    }

    if (!canUndo || canRedo) {
	GenerateUndoStackEvent(textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TextUndoRedoCallback --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
|


<
<
<
<

|
|


<
<
<
<





<
<
<











<
<
<
<







2738
2739
2740
2741
2742
2743
2744


































2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761




2762
2763
2764
2765
2766




2767
2768
2769
2770
2771



2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782




2783
2784
2785
2786
2787
2788
2789
    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);
    }




}

/*
 *----------------------------------------------------------------------
 *
 * TextUndoRedoCallback --
 *
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
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;







|







2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
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;
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036

    /*
     * 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.
     */

    return SharedTextObjCmd(sharedPtr, interp, objc+1, objv-1);
}

/*
 *----------------------------------------------------------------------
 *
 * CountIndices --
 *







|







2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885

    /*
     * 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.
     */

    return SharedTextObjCmd((ClientData)sharedPtr, interp, objc+1, objv-1);
}

/*
 *----------------------------------------------------------------------
 *
 * CountIndices --
 *
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
 * 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 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.
 *
 *----------------------------------------------------------------------







|







2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
 * 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.
 *
 *----------------------------------------------------------------------
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
{
    int line1, line2;
    TkTextIndex index1, index2;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int i;

    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Prepare the starting and stopping indices.







<
<
<







2970
2971
2972
2973
2974
2975
2976



2977
2978
2979
2980
2981
2982
2983
{
    int line1, line2;
    TkTextIndex index1, index2;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];




    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Prepare the starting and stopping indices.
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194

3195
3196
3197
3198
3199
3200




3201
3202


3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222

3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236

3237
3238
3239
3240
3241
3242
3243
3244
     * deleted but tags might be removed.
     */

    line1 = TkBTreeLinesTo(textPtr, index1.linePtr);
    line2 = TkBTreeLinesTo(textPtr, index2.linePtr);
    if (line2 == TkBTreeNumLines(sharedTextPtr->tree, textPtr)) {
	TkTextTag **arrayPtr;
	int arraySize;
	TkTextIndex oldIndex2;

	oldIndex2 = index2;
	TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES);
	line2--;
	if ((index1.byteIndex == 0) && (line1 != 0)) {
	    TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES);
	    line1--;
	}
	arrayPtr = TkBTreeGetTags(&index2, NULL, &arraySize);
	if (arrayPtr != NULL) {
	    for (i = 0; i < arraySize; i++) {
		TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
	    }
	    ckfree(arrayPtr);
	}
    }


    /*
     * 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.
     */





    for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
	    hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {


        TkBTreeTag(&index1, &index2, (TkTextTag *)Tcl_GetHashValue(hPtr), 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.
     */

    TkTextChanged(sharedTextPtr, NULL, &index1, &index2);

    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;







|














|



>
|
|
|
|
|

>
>
>
>
|
|
>
>
|
|

|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
>














>
|







3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
     * deleted but tags might be removed.
     */

    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(NULL, &oldIndex2, 1, &index2, COUNT_INDICES);
	line2--;
	if ((index1.byteIndex == 0) && (line1 != 0)) {
	    TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES);
	    line1--;
	}
	arrayPtr = TkBTreeGetTags(&index2, NULL, &arraySize);
	if (arrayPtr != NULL) {
	    for (i = 0; i < arraySize; i++) {
		TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
	    }
	    ckfree((char *) arrayPtr);
	}
    }

    if (line1 < line2) {
	/*
	 * 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.
	 */

	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	int i;

	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.
     */

    TkTextChanged(sharedTextPtr, NULL, &index1, &index2);

    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;
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
		 * 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 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 = 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.
	     */
	}
	if (resetView) {
	    lineAndByteIndex[resetViewCount] = line;
	    lineAndByteIndex[resetViewCount+1] = byteIndex;
	} else {
	    lineAndByteIndex[resetViewCount] = -1;
	}
	resetViewCount += 2;
    }

    /*
     * Push the deletion on the undo stack if something was actually deleted.
     */

    if (TkTextIndexCmp(&index1, &index2) < 0) {







|
|
|
|
|
















|
|
|
|
|







|







3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
		 * 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 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 = 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.
             */
	}
	if (resetView) {
	    lineAndByteIndex[resetViewCount] = line;
	    lineAndByteIndex[resetViewCount+1] = byteIndex;
	} else {
	    lineAndByteIndex[resetViewCount] = -1;
	}
	resetViewCount+=2;
    }

    /*
     * Push the deletion on the undo stack if something was actually deleted.
     */

    if (TkTextIndexCmp(&index1, &index2) < 0) {
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
	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(lineAndByteIndex);
    }

    if (line1 >= line2) {
	/*
	 * Invalidate any selection retrievals in progress, assuming we didn't
	 * check for this case above.
	 */







|
|
|
|
|
|
|
|






|

|
|
|
|
|
|
|
|
|

|
|
|

|
|

|
|
|
|






|







3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
	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);
    }

    if (line1 >= line2) {
	/*
	 * Invalidate any selection retrievals in progress, assuming we didn't
	 * check for this case above.
	 */
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
TextFetchSelection(
    ClientData clientData,	/* Information about text widget. */
    TkSizeT offset,			/* Offset within selection of first character
				 * to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkText *textPtr = (TkText *)clientData;
    TkTextIndex eof;
    int count, chunkSize;
    TkSizeT offsetInSeg;
    TkTextSearch search;
    TkTextSegment *segPtr;

    if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
	return -1;
    }

    /*
     * 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







|


|


|



|

|
<



|







3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283

3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
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;
    int count, chunkSize, offsetInSeg;

    TkTextSearch search;
    TkTextSegment *segPtr;

    if (!textPtr->exportSelection) {
	return -1;
    }

    /*
     * 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
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518

	while (1) {
	    if (maxBytes == 0) {
		goto fetchDone;
	    }
	    segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg);
	    chunkSize = segPtr->size - offsetInSeg;
	    if (chunkSize > (int)maxBytes) {
		chunkSize = (int)maxBytes;
	    }
	    if (textPtr->selIndex.linePtr == search.curIndex.linePtr) {
		int leftInRange;

		leftInRange = search.curIndex.byteIndex
			- textPtr->selIndex.byteIndex;
		if (leftInRange < chunkSize) {
		    chunkSize = leftInRange;
		    if (chunkSize <= 0) {
			break;
		    }
		}
	    }
	    if ((segPtr->typePtr == &tkTextCharType)
		    && !TkTextIsElided(textPtr, &textPtr->selIndex, NULL)) {
		memcpy(buffer, segPtr->body.chars + offsetInSeg,
			chunkSize);
		buffer += chunkSize;
		maxBytes -= chunkSize;
		count += chunkSize;
	    }
	    TkTextIndexForwBytes(textPtr, &textPtr->selIndex, chunkSize,
		    &textPtr->selIndex);
	}







|
|
















|







3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372

	while (1) {
	    if (maxBytes == 0) {
		goto fetchDone;
	    }
	    segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg);
	    chunkSize = segPtr->size - offsetInSeg;
	    if (chunkSize > maxBytes) {
		chunkSize = maxBytes;
	    }
	    if (textPtr->selIndex.linePtr == search.curIndex.linePtr) {
		int leftInRange;

		leftInRange = search.curIndex.byteIndex
			- textPtr->selIndex.byteIndex;
		if (leftInRange < chunkSize) {
		    chunkSize = leftInRange;
		    if (chunkSize <= 0) {
			break;
		    }
		}
	    }
	    if ((segPtr->typePtr == &tkTextCharType)
		    && !TkTextIsElided(textPtr, &textPtr->selIndex, NULL)) {
		memcpy(buffer, segPtr->body.chars + offsetInSeg,
			(size_t) chunkSize);
		buffer += chunkSize;
		maxBytes -= chunkSize;
		count += chunkSize;
	    }
	    TkTextIndexForwBytes(textPtr, &textPtr->selIndex, chunkSize,
		    &textPtr->selIndex);
	}
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
 *----------------------------------------------------------------------
 */

void
TkTextLostSelection(
    ClientData clientData)	/* Information about text widget. */
{
    TkText *textPtr = (TkText *)clientData;

    if (Tk_AlwaysShowSelection(textPtr->tkwin)) {
	TkTextIndex start, end;

	if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
	    return;
	}

	/*
	 * 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.







|

|


|







3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
 *----------------------------------------------------------------------
 */

void
TkTextLostSelection(
    ClientData clientData)	/* Information about text widget. */
{
    register TkText *textPtr = (TkText *) clientData;

    if (TkpAlwaysShowSelection(textPtr->tkwin)) {
	TkTextIndex start, end;

	if (!textPtr->exportSelection) {
	    return;
	}

	/*
	 * 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.
3611
3612
3613
3614
3615
3616
3617

3618








3619
3620
3621
3622
3623
3624
3625
    TkText *textPtr)
{
    /*
     * Send an event that the selection changed. This is equivalent to:
     *     event generate $textWidget <<Selection>>
     */


    Tk_SendVirtualEvent(textPtr->tkwin, "Selection", NULL);








}

/*
 *----------------------------------------------------------------------
 *
 * TextBlinkProc --
 *







>
|
>
>
>
>
>
>
>
>







3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
    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 --
 *
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
 *----------------------------------------------------------------------
 */

static void
TextBlinkProc(
    ClientData clientData)	/* Pointer to record describing text. */
{
    TkText *textPtr = (TkText *)clientData;
    TkTextIndex index;
    int x, y, w, h, charWidth;

    if ((textPtr->state == TK_TEXT_STATE_DISABLED) ||
	    !(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) {
	if (!(textPtr->flags & GOT_FOCUS) &&
		(textPtr->insertUnfocussed != TK_TEXT_INSERT_NOFOCUS_NONE)) {
	    /*
	     * The widget doesn't have the focus yet it is configured to
	     * display the cursor when it doesn't have the focus. Act now!
	     */

	    textPtr->flags |= INSERT_ON;
	    goto redrawInsert;
	}
	if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) {
	    /*
	     * The widget was configured to have zero offtime while the
	     * insertion point was not displayed. We have to display it once.
	     */

	    textPtr->flags |= INSERT_ON;
	    goto redrawInsert;
	}
	return;
    }
    if (textPtr->flags & INSERT_ON) {
	textPtr->flags &= ~INSERT_ON;
	textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		textPtr->insertOffTime, TextBlinkProc, textPtr);
    } else {
	textPtr->flags |= INSERT_ON;
	textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		textPtr->insertOnTime, TextBlinkProc, textPtr);
    }
  redrawInsert:
    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
    if (TkTextIndexBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) {
	if (textPtr->insertCursorType) {
	    /* Block cursor */
	    TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y,







|





<
<
<
<
<
<
<
<
<
<














|



|







3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511










3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
 *----------------------------------------------------------------------
 */

static void
TextBlinkProc(
    ClientData clientData)	/* Pointer to record describing text. */
{
    register TkText *textPtr = (TkText *) clientData;
    TkTextIndex index;
    int x, y, w, h, charWidth;

    if ((textPtr->state == TK_TEXT_STATE_DISABLED) ||
	    !(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) {










	if ((textPtr->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) {
	textPtr->flags &= ~INSERT_ON;
	textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		textPtr->insertOffTime, TextBlinkProc, (ClientData) textPtr);
    } else {
	textPtr->flags |= INSERT_ON;
	textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		textPtr->insertOnTime, TextBlinkProc, (ClientData) textPtr);
    }
  redrawInsert:
    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
    if (TkTextIndexBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) {
	if (textPtr->insertCursorType) {
	    /* Block cursor */
	    TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y,
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
	    oldTagArrayPtr = TkBTreeGetTags(&index1, NULL, &numTags);
	    if (oldTagArrayPtr != NULL) {
		int i;

		for (i = 0; i < numTags; i++) {
		    TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0);
		}
		ckfree(oldTagArrayPtr);
	    }
	    if (Tcl_ListObjGetElements(interp, objv[j+1], &numTags,
		    &tagNamePtrs) != TCL_OK) {
		return TCL_ERROR;
	    } else {
		int i;








|







3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
	    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;

3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807

3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858



3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876

3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int i, argsLeft, code;
    SearchSpec searchSpec;

    static const char *const switchStrings[] = {
	"-hidden",
	"--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards",
	"-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL

    };
    enum SearchSwitches {
	TK_TEXT_SEARCH_HIDDEN,
	TK_TEXT_SEARCH_END, TK_TEXT_SEARCH_ALL, TK_TEXT_SEARCH_BACK, TK_TEXT_SEARCH_COUNT, TK_TEXT_SEARCH_ELIDE,
	TK_TEXT_SEARCH_EXACT, TK_TEXT_SEARCH_FWD, TK_TEXT_SEARCH_NOCASE,
	TK_TEXT_SEARCH_NOLINESTOP, TK_TEXT_SEARCH_OVERLAP, TK_TEXT_SEARCH_REGEXP, TK_TEXT_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 = textPtr;
    searchSpec.addLineProc = &TextSearchAddNextLine;
    searchSpec.foundMatchProc = &TextSearchFoundMatch;
    searchSpec.lineIndexProc = &TextSearchGetLineIndex;

    /*
     * Parse switches and other arguments.
     */

    for (i=2 ; i<objc ; i++) {
	int index;

	if (Tcl_GetString(objv[i])[0] != '-') {
	    break;
	}

	if (Tcl_GetIndexFromObjStruct(NULL, objv[i], switchStrings,
		sizeof(char *), "switch", 0, &index) != TCL_OK) {
	    /*
	     * Hide the -hidden option, generating the error description with
	     * the side effects of T_GIFO.
	     */

	    (void) Tcl_GetIndexFromObjStruct(interp, objv[i], switchStrings+1,
		    sizeof(char *), "switch", 0, &index);



	    return TCL_ERROR;
	}

	switch ((enum SearchSwitches) index) {
	case TK_TEXT_SEARCH_END:
	    i++;
	    goto endOfSwitchProcessing;
	case TK_TEXT_SEARCH_ALL:
	    searchSpec.all = 1;
	    break;
	case TK_TEXT_SEARCH_BACK:
	    searchSpec.backwards = 1;
	    break;
	case TK_TEXT_SEARCH_COUNT:
	    if (i >= objc-1) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no value given for \"-count\" option", -1));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "VALUE", NULL);

		return TCL_ERROR;
	    }
	    i++;

	    /*
	     * Assumption objv[i] isn't going to disappear on us during this
	     * function, which is fair.
	     */

	    searchSpec.varPtr = objv[i];
	    break;
	case TK_TEXT_SEARCH_ELIDE:
	case TK_TEXT_SEARCH_HIDDEN:
	    searchSpec.searchElide = 1;
	    break;
	case TK_TEXT_SEARCH_EXACT:
	    searchSpec.exact = 1;
	    break;
	case TK_TEXT_SEARCH_FWD:
	    searchSpec.backwards = 0;
	    break;
	case TK_TEXT_SEARCH_NOCASE:
	    searchSpec.noCase = 1;
	    break;
	case TK_TEXT_SEARCH_NOLINESTOP:
	    searchSpec.noLineStop = 1;
	    break;
	case TK_TEXT_SEARCH_OVERLAP:
	    searchSpec.overlap = 1;
	    break;
	case TK_TEXT_SEARCH_STRICTLIMITS:
	    searchSpec.strictLimits = 1;
	    break;
	case TK_TEXT_SEARCH_REGEXP:
	    searchSpec.exact = 0;
	    break;
	default:
	    Tcl_Panic("unexpected switch fallthrough");
	}
    }
  endOfSwitchProcessing:

    argsLeft = objc - (i+2);
    if ((argsLeft != 0) && (argsLeft != 1)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"?switches? pattern index ?stopIndex?");
	return TCL_ERROR;
    }

    if (searchSpec.noLineStop && searchSpec.exact) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"the \"-nolinestop\" option requires the \"-regexp\" option"
		" to be present", -1));
	Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL);
	return TCL_ERROR;
    }

    if (searchSpec.overlap && !searchSpec.all) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"the \"-overlap\" option requires the \"-all\" option"
		" to be present", -1));
	Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL);
	return TCL_ERROR;
    }

    /*
     * 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.







|
<

|
>


|
<
|
|




















|










<




|
|

|
<


|
|
>
>
>




|


|


|


|

<
|
<
>











|
|


|


|


|


|


|


|


|
















<
|
|
<




<
|
|
<







3650
3651
3652
3653
3654
3655
3656
3657

3658
3659
3660
3661
3662
3663

3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696

3697
3698
3699
3700
3701
3702
3703
3704

3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726

3727

3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778

3779
3780

3781
3782
3783
3784

3785
3786

3787
3788
3789
3790
3791
3792
3793
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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.
     */

    for (i=2 ; i<objc ; i++) {
	int index;

	if (Tcl_GetString(objv[i])[0] != '-') {
	    break;
	}

	if (Tcl_GetIndexFromObj(interp, objv[i], switchStrings, "switch", 0,
		&index) != TCL_OK) {
	    /*
	     * 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;
	}

	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++;

	    /*
	     * Assumption objv[i] isn't going to disappear on us during this
	     * function, which is fair.
	     */

	    searchSpec.varPtr = objv[i];
	    break;
	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");
	}
    }
  endOfSwitchProcessing:

    argsLeft = objc - (i+2);
    if ((argsLeft != 0) && (argsLeft != 1)) {
	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;
    }

    /*
     * 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.
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030

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. */
    TkSizeT *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);







|




|







3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878

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);
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
TextSearchIndexInLine(
    const SearchSpec *searchSpecPtr,
				/* Search parameters. */
    TkTextLine *linePtr,	/* The line we're looking at. */
    TkSizeT byteIndex)		/* Index into the line. */
{
    TkTextSegment *segPtr;
    TkTextIndex curIndex;
    TkSizeT index;
    int 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 + 1 > 1;
	    curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) {
	if ((segPtr->typePtr == &tkTextCharType) &&
		(searchSpecPtr->searchElide
		|| !TkTextIsElided(textPtr, &curIndex, NULL))) {
	    if (leftToScan + 1 < (int)segPtr->size + 1) {
		if (searchSpecPtr->exact) {
		    index += leftToScan;
		} else {
		    index += Tcl_NumUtfChars(segPtr->body.chars, leftToScan);
		}
	    } else if (searchSpecPtr->exact) {
		index += segPtr->size;







|




|



<
|
|





|




|







3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934

3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
 *
 * 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;
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
				 * 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);







|







3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
				 * 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);
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244

    if (searchSpecPtr->exact && searchSpecPtr->noCase) {
	Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine)));
    }

    if (lenPtr != NULL) {
	if (searchSpecPtr->exact) {
	    Tcl_GetString(theLine);
	    *lenPtr = theLine->length;
	} else {
	    *lenPtr = Tcl_GetCharLength(theLine);
	}
    }
    return linePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TextSearchFoundMatch --
 *







|
<




|







4071
4072
4073
4074
4075
4076
4077
4078

4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090

    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 --
 *
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
    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. */
    TkSizeT matchOffset,		/* Offset of found item in utf-8 bytes for
				 * exact search, Unicode chars for regexp. */
    TkSizeT matchLength)		/* Length also in bytes/chars as per search
				 * type. */
{
    TkSizeT numChars;
    int leftToScan;
    TkTextIndex curIndex, foundIndex;
    TkTextSegment *segPtr;
    TkTextLine *linePtr;
    TkText *textPtr = (TkText *)searchSpecPtr->clientData;

    if (lineNum == searchSpecPtr->stopLine) {
	/*
	 * 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.
	 */

	if (searchSpecPtr->backwards ^
		(matchOffset + 1 >= searchSpecPtr->stopOffset + 1)) {
	    return 0;
	}
    }

    /*
     * Calculate the character count, which may need augmenting if there are
     * embedded windows or elidden text.







|

|


|




|









|







4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
    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) {
	/*
	 * 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.
	 */

	if (searchSpecPtr->backwards ^
		(matchOffset >= searchSpecPtr->stopOffset)) {
	    return 0;
	}
    }

    /*
     * Calculate the character count, which may need augmenting if there are
     * embedded windows or elidden text.
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
    /*
     * 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 + 1) > searchSpecPtr->stopOffset + 1)) {
	    return 0;
	}
    }

    /*
     * The index information returned by the regular expression parser only
     * considers textual information: it doesn't account for embedded windows,







|







4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
    /*
     * 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,
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
		if (searchSpecPtr->exact) {
		    matchOffset += segPtr->size;
		} else {
		    matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1);
		}
	    } else {
		if (searchSpecPtr->exact) {
		    leftToScan -= (int)segPtr->size;
		} else {
		    leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1);
		}
	    }
	    curIndex.byteIndex += segPtr->size;
	}
	if (segPtr == NULL && leftToScan >= 0) {







|







4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
		if (searchSpecPtr->exact) {
		    matchOffset += segPtr->size;
		} else {
		    matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1);
		}
	    } else {
		if (searchSpecPtr->exact) {
		    leftToScan -= segPtr->size;
		} else {
		    leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1);
		}
	    }
	    curIndex.byteIndex += segPtr->size;
	}
	if (segPtr == NULL && leftToScan >= 0) {
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
    }

    /*
     * Now store the count result, if it is wanted.
     */

    if (searchSpecPtr->varPtr != NULL) {
	Tcl_Obj *tmpPtr = Tcl_NewWideIntObj(numChars);
	if (searchSpecPtr->all) {
	    if (searchSpecPtr->countPtr == NULL) {
		searchSpecPtr->countPtr = Tcl_NewObj();
	    }
	    Tcl_ListObjAppendElement(NULL, searchSpecPtr->countPtr, tmpPtr);
	} else {
	    searchSpecPtr->countPtr = tmpPtr;







|







4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
    }

    /*
     * Now store the count result, if it is wanted.
     */

    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 {
	    searchSpecPtr->countPtr = tmpPtr;
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
    Tcl_Obj *stringPtr)		/* Description of the tab stops. See the text
				 * manual entry for details. */
{
    int objc, i, count;
    Tcl_Obj **objv;
    TkTextTabArray *tabArrayPtr;
    TkTextTab *tabPtr;
    int ch;
    double prevStop, lastStop;
    /*
     * Map these strings to TkTextTabAlign values.
     */
    static const char *const tabOptionStrings[] = {
	"left", "right", "center", "numeric", NULL
    };

    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.
     */

    count = 0;
    for (i = 0; i < objc; i++) {
	char c = Tcl_GetString(objv[i])[0];

	if ((c != 'l') && (c != 'r') && (c != 'c') && (c != 'n')) {
	    count++;
	}
    }

    /*
     * Parse the elements of the list one at a time to fill in the array.
     */

    tabArrayPtr = (TkTextTabArray *)ckalloc(offsetof(TkTextTabArray, tabs)
	    + count * sizeof(TkTextTab));
    tabArrayPtr->numTabs = 0;
    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_SetObjResult(interp, Tcl_ObjPrintf(
		    "tab stop \"%s\" is not at a positive distance",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL);
	    goto error;
	}

	prevStop = lastStop;
	if (Tk_GetDoublePixelsFromObj(interp, textPtr->tkwin, objv[i],
		&lastStop) != TCL_OK) {
	    goto error;
	}

	if (i > 0 && (tabPtr->location <= (tabPtr-1)->location)) {
	    /*
	     * This tab is actually to the left of the previous one, which is
	     * illegal.







|




|














<









|
|

















|
|
<
<




|
|







4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377

4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407


4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
    Tcl_Obj *stringPtr)		/* Description of the tab stops. See the text
				 * manual entry for details. */
{
    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_ListObjGetElements(interp, stringPtr, &objc, &objv) != TCL_OK) {
	return NULL;
    }

    /*
     * First find out how many entries we need to allocate in the tab array.
     */

    count = 0;
    for (i = 0; i < objc; i++) {
	char c = Tcl_GetString(objv[i])[0];

	if ((c != 'l') && (c != 'r') && (c != 'c') && (c != 'n')) {
	    count++;
	}
    }

    /*
     * 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;
    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.
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597

4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
	    if (textPtr->charWidth > 0) {
		tabPtr->location = (tabPtr-1)->location + textPtr->charWidth;
	    } else {
		tabPtr->location = (tabPtr-1)->location + 8;
	    }
	    lastStop = tabPtr->location;
#else
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "tabs must be monotonically increasing, but \"%s\" is "
		    "smaller than or equal to the previous tab",
		    Tcl_GetString(objv[i])));

	    Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL);
	    goto error;
#endif /* _TK_ALLOW_DECREASING_TABS */
	}

	tabArrayPtr->numTabs++;

	/*
	 * See if there is an explicit alignment in the next list element.
	 * Otherwise just use "left".
	 */

	tabPtr->alignment = LEFT;
	if ((i+1) == objc) {
	    continue;
	}

	/*
	 * There may be a more efficient way of getting this.
	 */

	TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch);
	if (!Tcl_UniCharIsAlpha(ch)) {
	    continue;
	}
	i += 1;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], tabOptionStrings,
		sizeof(char *), "tab alignment", 0, &index) != TCL_OK) {
	    goto error;
	}
	tabPtr->alignment = (TkTextTabAlign) index;
    }

    /*
     * 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:
    ckfree(tabArrayPtr);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TextDumpCmd --







|
|
<
|
>
|




















|





|
|


|














|







4430
4431
4432
4433
4434
4435
4436
4437
4438

4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
	    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".
	 */

	tabPtr->alignment = LEFT;
	if ((i+1) == objc) {
	    continue;
	}

	/*
	 * 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;

	if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings,
		"tab alignment", 0, &index) != TCL_OK) {
	    goto error;
	}
	tabPtr->alignment = ((TkTextTabAlign)index);
    }

    /*
     * 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:
    ckfree((char *) tabArrayPtr);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TextDumpCmd --
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
 *	side effects).
 *
 *----------------------------------------------------------------------
 */

static int
TextDumpCmd(
    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
				 * 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. */
    TkTextLine *linePtr;
    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
#define TK_DUMP_WIN	0x8
#define TK_DUMP_IMG	0x10
#define TK_DUMP_ALL	(TK_DUMP_TEXT|TK_DUMP_MARK|TK_DUMP_TAG| \
	TK_DUMP_WIN|TK_DUMP_IMG)
    static const char *const 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;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[arg], optStrings,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum opts) index) {
	case DUMP_ALL:
	    what = TK_DUMP_ALL;
	    break;
	case DUMP_TXT:







|




















|












|
|







4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
 *	side effects).
 *
 *----------------------------------------------------------------------
 */

static int
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
				 * 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. */
    TkTextLine *linePtr;
    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
#define TK_DUMP_WIN	0x8
#define TK_DUMP_IMG	0x10
#define TK_DUMP_ALL	(TK_DUMP_TEXT|TK_DUMP_MARK|TK_DUMP_TAG| \
	TK_DUMP_WIN|TK_DUMP_IMG)
    static const char *optStrings[] = {
	"-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;
	}
	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;
	    break;
	case DUMP_TXT:
4722
4723
4724
4725
4726
4727
4728
4729



4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
	    break;
	case DUMP_WIN:
	    what |= TK_DUMP_WIN;
	    break;
	case DUMP_CMD:
	    arg++;
	    if (arg >= objc) {
		goto wrongArgs;



	    }
	    command = objv[arg];
	    break;
	default:
	    Tcl_Panic("unexpected switch fallthrough");
	}
    }
    if (arg >= objc || arg+2 < objc) {
    wrongArgs:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Usage: %s dump ?-all -image -text -mark -tag -window? "
		"?-command script? index ?index2?", Tcl_GetString(objv[0])));
	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	return TCL_ERROR;
    }
    if (what == 0) {
	what = TK_DUMP_ALL;
    }
    if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index1) != TCL_OK) {
	return TCL_ERROR;
    }
    arg++;
    atEnd = 0;
    if (objc == arg) {
	TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
    } else {
	TkSizeT length;
	const char *str;

	if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(objv[arg], &length);
	if (strncmp(str, "end", length) == 0) {
	    atEnd = 1;
	}
    }
    if (TkTextIndexCmp(&index1, &index2) >= 0) {
	return TCL_OK;
    }
    lineno = TkBTreeLinesTo(textPtr, index1.linePtr);







|
>
>
>








<
|
|
|
<













|
|




|
|







4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583

4584
4585
4586

4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
	    break;
	case DUMP_WIN:
	    what |= TK_DUMP_WIN;
	    break;
	case DUMP_CMD:
	    arg++;
	    if (arg >= objc) {
		Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]),
			" dump ?-all -image -text -mark -tag -window? ",
			"?-command script? index ?index2?", NULL);
		return TCL_ERROR;
	    }
	    command = objv[arg];
	    break;
	default:
	    Tcl_Panic("unexpected switch fallthrough");
	}
    }
    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 (TkTextGetObjIndex(interp, textPtr, objv[arg], &index1) != TCL_OK) {
	return TCL_ERROR;
    }
    arg++;
    atEnd = 0;
    if (objc == arg) {
	TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
    } else {
	int length;
	char *str;

	if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
	    return TCL_ERROR;
	}
	str = Tcl_GetStringFromObj(objv[arg], &length);
	if (strncmp(str, "end", (unsigned)length) == 0) {
	    atEnd = 1;
	}
    }
    if (TkTextIndexCmp(&index1, &index2) >= 0) {
	return TCL_OK;
    }
    lineno = TkBTreeLinesTo(textPtr, index1.linePtr);
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
	    linePtr = index1.linePtr;
	}
	while ((linePtr = TkBTreeNextLine(textPtr, linePtr)) != NULL) {
	    lineno++;
	    if (lineno == lineend) {
		break;
	    }
	    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;







|
|







4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
	    linePtr = index1.linePtr;
	}
	while ((linePtr = TkBTreeNextLine(textPtr, linePtr)) != NULL) {
	    lineno++;
	    if (lineno == lineend) {
		break;
	    }
	    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;
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908

4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
		 * 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 = (char *)ckalloc(length + 1);

		memcpy(range, segPtr->body.chars + first, length);

		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 == &tkTextLeftMarkType
		    || segPtr->typePtr == &tkTextRightMarkType)) {
		const char *name;
		TkTextMark *markPtr = &segPtr->body.mark;

		if (segPtr == textPtr->insertMarkPtr) {
		    name = "insert";
		} else if (segPtr == textPtr->currentMarkPtr) {
		    name = "current";
		} else if (markPtr->hPtr == NULL) {
		    name = NULL;
		    lineChanged = 0;
		} else {
		    name = (const char *)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);







|

|
>














|
<
<
|
|









|







4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768


4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
		 * 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')) {


		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);
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003


5004
5005
5006
5007
5008
5009
5010
		    (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 == &tkTextEmbImageType)) {
		TkTextEmbImage *eiPtr = &segPtr->body.ei;
		const char *name = (eiPtr->name == NULL) ? "" : eiPtr->name;

		TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
			lineno, offset, &index);
		lineChanged = DumpSegment(textPtr, interp, "image", name,
			command, &index, what);
	    } else if ((what & TK_DUMP_WIN) &&
		    (segPtr->typePtr == &tkTextEmbWindowType)) {
		TkTextEmbWindow *ewPtr = &segPtr->body.ew;
		const char *pathname;

		if (ewPtr->tkwin == NULL) {
		    pathname = "";
		} else {
		    pathname = Tk_PathName(ewPtr->tkwin);
		}
		TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
			lineno, offset, &index);
		lineChanged = DumpSegment(textPtr, interp, "window", pathname,
			command, &index, what);
	    }
	}

	offset += currentSize;
	if (lineChanged) {
	    TkTextSegment *newSegPtr;
	    int newOffset = 0;

	    textChanged = 1;

	    /*
	     * Our indices are no longer valid.
	     */

	    if (textPtr->flags & DESTROYED) {
		return textChanged;
	    }
	    linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
		    textPtr, lineno);
	    newSegPtr = linePtr->segPtr;
	    if (segPtr != newSegPtr) {


		while ((newOffset < endByte) && (newOffset < offset)
			&& (newSegPtr != NULL)) {
		    newOffset += currentSize;
		    newSegPtr = newSegPtr->nextPtr;
		    if (segPtr == newSegPtr) {
			break;
		    }







|
|
|






|
|
|

|










<

















|
>
>







4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827

4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
		    (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->sharedTextPtr->tree, textPtr,
			lineno, offset, &index);
		lineChanged = DumpSegment(textPtr, interp, "image", name,
			command, &index, what);
	    } else if ((what & TK_DUMP_WIN) &&
		    (segPtr->typePtr->name[0] == 'w')) {
		TkTextEmbWindow *ewPtr = (TkTextEmbWindow *)&segPtr->body;
		char *pathname;

		if (ewPtr->tkwin == (Tk_Window) NULL) {
		    pathname = "";
		} else {
		    pathname = Tk_PathName(ewPtr->tkwin);
		}
		TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
			lineno, offset, &index);
		lineChanged = DumpSegment(textPtr, interp, "window", pathname,
			command, &index, what);
	    }
	}

	offset += currentSize;
	if (lineChanged) {
	    TkTextSegment *newSegPtr;
	    int newOffset = 0;

	    textChanged = 1;

	    /*
	     * Our indices are no longer valid.
	     */

	    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;
		    }
5018
5019
5020
5021
5022
5023
5024


5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
			    newSegPtr = searchPtr;
			    break;
			}
			searchPtr = searchPtr->nextPtr;
		    }
		}
		segPtr = newSegPtr;


	    }
	}
	if (segPtr != NULL) {
	    segPtr = segPtr->nextPtr;
	}
    }
    return textChanged;
}

/*







>
>
|
|
|







4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
			    newSegPtr = searchPtr;
			    break;
			}
			searchPtr = searchPtr->nextPtr;
		    }
		}
		segPtr = newSegPtr;
		if (segPtr != NULL) {
		    segPtr = segPtr->nextPtr;
		}
	    }
	} else {
	    segPtr = segPtr->nextPtr;
	}
    }
    return textChanged;
}

/*
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075

5076
5077


5078
5079
5080
5081




5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095




5096
5097
5098
5099
5100
5101
5102
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. */
    TCL_UNUSED(int))		/* Look for TK_DUMP_INDEX bit. */
{
    char buffer[TK_POS_CHARS];
    Tcl_Obj *values[3], *tuple;

    TkTextPrintIndex(textPtr, index, buffer);
    values[0] = Tcl_NewStringObj(key, -1);
    values[1] = Tcl_NewStringObj(value, -1);
    values[2] = Tcl_NewStringObj(buffer, -1);
    tuple = Tcl_NewListObj(3, values);
    if (command == NULL) {
	Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple);
	Tcl_DecrRefCount(tuple);

	return 0;
    } else {


	TkSizeT oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
	Tcl_DString buf;
	int code;





	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, Tcl_GetString(command), -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, Tcl_GetString(tuple), -1);
	code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (segment dumping command executed by text)");
	    Tcl_BackgroundException(interp, code);
	}
	Tcl_DecrRefCount(tuple);
	return ((textPtr->flags & DESTROYED) ||
		TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch);




    }
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditUndo --







|


<


<
<
<
<

|
|
>


>
>
|
<
<

>
>
>
>
|
|
<
<
<
|
<
<
<
<
<
<
|
|
>
>
>
>







4902
4903
4904
4905
4906
4907
4908
4909
4910
4911

4912
4913




4914
4915
4916
4917
4918
4919
4920
4921
4922


4923
4924
4925
4926
4927
4928
4929



4930






4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
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[TK_POS_CHARS];


    TkTextPrintIndex(textPtr, index, buffer);




    if (command == NULL) {
	Tcl_AppendElement(interp, key);
	Tcl_AppendElement(interp, value);
	Tcl_AppendElement(interp, buffer);
	return 0;
    } else {
	const char *argv[4];
	char *list;
	int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);



	argv[0] = key;
	argv[1] = value;
	argv[2] = buffer;
	argv[3] = NULL;
	list = Tcl_Merge(3, argv);
	Tcl_VarEval(interp, Tcl_GetString(command), " ", list, NULL);



	ckfree(list);






	if ((textPtr->flags & DESTROYED) ||
		TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch) {
	    return 1;
	} else {
	    return 0;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditUndo --
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
 */

static int
TextEditUndo(
    TkText *textPtr)		/* Overall information about text widget. */
{
    int status;
    Tcl_Obj *cmdObj;
    int code;

    if (!textPtr->sharedTextPtr->undo) {
	return TCL_OK;
    }

    /*
     * Turn off the undo feature while we revert a compound action, setting







<
<







4955
4956
4957
4958
4959
4960
4961


4962
4963
4964
4965
4966
4967
4968
 */

static int
TextEditUndo(
    TkText *textPtr)		/* Overall information about text widget. */
{
    int status;



    if (!textPtr->sharedTextPtr->undo) {
	return TCL_OK;
    }

    /*
     * Turn off the undo feature while we revert a compound action, setting
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
    status = TkUndoRevert(textPtr->sharedTextPtr->undoStack);

    if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
	textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
    }
    textPtr->sharedTextPtr->undo = 1;

    /*
     * Convert undo/redo temporary marks set by TkUndoRevert() into
     * indices left in the interp result.
     */

    cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s",
            Tk_PathName(textPtr->tkwin));
    Tcl_IncrRefCount(cmdObj);
    code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
        Tcl_AddErrorInfo(textPtr->interp,
                "\n    (on undoing)");
        Tcl_BackgroundException(textPtr->interp, code);
    }
    Tcl_DecrRefCount(cmdObj);

    return status;
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditRedo --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







4978
4979
4980
4981
4982
4983
4984
















4985
4986
4987
4988
4989
4990
4991
    status = TkUndoRevert(textPtr->sharedTextPtr->undoStack);

    if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
	textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
    }
    textPtr->sharedTextPtr->undo = 1;

















    return status;
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditRedo --
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
 */

static int
TextEditRedo(
    TkText *textPtr)		/* Overall information about text widget. */
{
    int status;
    Tcl_Obj *cmdObj;
    int code;

    if (!textPtr->sharedTextPtr->undo) {
	return TCL_OK;
    }

    /*
     * Turn off the undo feature temporarily while we revert a previously







<
<







5003
5004
5005
5006
5007
5008
5009


5010
5011
5012
5013
5014
5015
5016
 */

static int
TextEditRedo(
    TkText *textPtr)		/* Overall information about text widget. */
{
    int status;



    if (!textPtr->sharedTextPtr->undo) {
	return TCL_OK;
    }

    /*
     * Turn off the undo feature temporarily while we revert a previously
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234

    status = TkUndoApply(textPtr->sharedTextPtr->undoStack);

    if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
	textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
    }
    textPtr->sharedTextPtr->undo = 1;

    /*
     * Convert undo/redo temporary marks set by TkUndoApply() into
     * indices left in the interp result.
     */

    cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s",
            Tk_PathName(textPtr->tkwin));
    Tcl_IncrRefCount(cmdObj);
    code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
        Tcl_AddErrorInfo(textPtr->interp,
                "\n    (on undoing)");
        Tcl_BackgroundException(textPtr->interp, code);
    }
    Tcl_DecrRefCount(cmdObj);

    return status;
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditCmd --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5025
5026
5027
5028
5029
5030
5031

















5032
5033
5034
5035
5036
5037
5038

    status = TkUndoApply(textPtr->sharedTextPtr->undoStack);

    if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
	textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
    }
    textPtr->sharedTextPtr->undo = 1;

















    return status;
}

/*
 *----------------------------------------------------------------------
 *
 * TextEditCmd --
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306



5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332

5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403





5404
5405
5406
5407
5408
5409
5410
static int
TextEditCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, setModified, oldModified;
    int canRedo = 0;
    int canUndo = 0;

    static const char *const editOptionStrings[] = {
	"canundo", "canredo", "modified", "redo", "reset", "separator",
	"undo", NULL
    };
    enum editOptions {
	EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET,
	EDIT_SEPARATOR, EDIT_UNDO
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], editOptionStrings,
	    sizeof(char *), "edit option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum editOptions) index) {
    case EDIT_CANREDO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	     return TCL_ERROR;
	}
	if (textPtr->sharedTextPtr->undo) {
	    canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo));
	break;
    case EDIT_CANUNDO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	     return TCL_ERROR;
	}
	if (textPtr->sharedTextPtr->undo) {
	    canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo));
	break;
    case EDIT_MODIFIED:
	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty));
	    return TCL_OK;
	} else if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?boolean?");
	    return TCL_ERROR;



	} else if (Tcl_GetBooleanFromObj(interp, objv[3],
		&setModified) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * Set or reset the dirty info, and trigger a Modified event.
	 */

	setModified = setModified ? 1 : 0;

	oldModified = textPtr->sharedTextPtr->isDirty;
	textPtr->sharedTextPtr->isDirty = setModified;
	if (setModified) {
	    textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
	} else {
	    textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
	}

	/*
	 * 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);

	}
	break;
    case EDIT_REDO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
	if (TextEditRedo(textPtr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
	    return TCL_ERROR;
	}
	canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	if (!canUndo || !canRedo) {
	    GenerateUndoStackEvent(textPtr);
	}
	break;
    case EDIT_RESET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
	canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
	if (canUndo || canRedo) {
	    GenerateUndoStackEvent(textPtr);
	}
	break;
    case EDIT_SEPARATOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
	break;
    case EDIT_UNDO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	if (TextEditUndo(textPtr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
	    return TCL_ERROR;
	}
	canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
	if (!canRedo || !canUndo) {
	    GenerateUndoStackEvent(textPtr);
	}
	break;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TextGetText --
 *
 *	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).





 *
 * Results:
 *	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.
 *







|
<
<

|
|
<


|
<



|



|
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<



>
>
>
|
|
|
|

|
|
|

|

|
|
|
|
|
|
|

|
|
|
|

|
|
>







<

|
<


<
<
<
<






<
<

<
<
<













<

|
<


<
<
<
<



















>
>
>
>
>







5052
5053
5054
5055
5056
5057
5058
5059


5060
5061
5062

5063
5064
5065

5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078




















5079
5080
5081
5082

5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122

5123
5124

5125
5126




5127
5128
5129
5130
5131
5132


5133



5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146

5147
5148

5149
5150




5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
static int
TextEditCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index;



    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;
    }

    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, oldModified;

	    if (Tcl_GetBooleanFromObj(interp, objv[3],
		    &setModified) != TCL_OK) {
		return TCL_ERROR;
	    }

	    /*
	     * Set or reset the dirty info, and trigger a Modified event.
	     */

	    setModified = setModified ? 1 : 0;

	    oldModified = textPtr->sharedTextPtr->isDirty;
	    textPtr->sharedTextPtr->isDirty = setModified;
	    if (setModified) {
		textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
	    } else {
		textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
	    }

	    /*
	     * 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);
	    }
	}
	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", NULL);

	    return TCL_ERROR;
	}




	break;
    case EDIT_RESET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}


	TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);



	break;
    case EDIT_SEPARATOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	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", NULL);

	    return TCL_ERROR;
	}




	break;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TextGetText --
 *
 *	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:
 *	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.
 *
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440


5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451


5452
5453
5454
5455

5456
5457
5458
5459

5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521

5522
5523
5524
5525
5526
5527
5528
5529
5530

    TkTextMakeByteIndex(indexPtr1->tree, textPtr,
	    TkBTreeLinesTo(textPtr, indexPtr1->linePtr),
	    indexPtr1->byteIndex, &tmpIndex);

    if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) {
	while (1) {
	    TkSizeT offset;
	    TkTextSegment *segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
	    int last = segPtr->size, last2;



	    if (tmpIndex.linePtr == indexPtr2->linePtr) {
		/*
		 * 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;
		}
	    }

	    if (segPtr->typePtr == &tkTextCharType &&
		    !(visibleOnly && TkTextIsElided(textPtr,&tmpIndex,NULL))){
		Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset,
			last - offset);

	    }
	    TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex);
	}
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateModifiedEvent --
 *
 *	Send an event that the text was modified. This is equivalent to:
 *	   event generate $textWidget <<Modified>>
 *	for all peers of $textWidget.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	May force the text window into existence.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateModifiedEvent(
    TkText *textPtr)	/* Information about text widget. */
{
    for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
	    textPtr = textPtr->next) {
	Tk_MakeWindowExist(textPtr->tkwin);
	Tk_SendVirtualEvent(textPtr->tkwin, "Modified", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateUndoStackEvent --
 *
 *	Send an event that the undo or redo stack became empty or unempty.
 *	This is equivalent to:
 *	   event generate $textWidget <<UndoStack>>
 *	for all peers of $textWidget.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	May force the text window (and all peers) into existence.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateUndoStackEvent(
    TkText *textPtr)	/* Information about text widget. */
{
    for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
	    textPtr = textPtr->next) {
	Tk_MakeWindowExist(textPtr->tkwin);

	Tk_SendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateDirtyFlag --
 *







|
|
<

>
>









|
|
>
>
|
|
|
|
>
|
|
|
|
>












|

<














|
|
|
<
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
|
|
>
|
<







5201
5202
5203
5204
5205
5206
5207
5208
5209

5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249

5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266

5267

5268



5269














5270

5271



5272
5273
5274
5275

5276
5277
5278
5279
5280
5281
5282

    TkTextMakeByteIndex(indexPtr1->tree, textPtr,
	    TkBTreeLinesTo(textPtr, indexPtr1->linePtr),
	    indexPtr1->byteIndex, &tmpIndex);

    if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) {
	while (1) {
	    int offset, last;
	    TkTextSegment *segPtr;


	    segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
	    last = segPtr->size;
	    if (tmpIndex.linePtr == indexPtr2->linePtr) {
		/*
		 * 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;
		} else {
		    int last2 = indexPtr2->byteIndex - tmpIndex.byteIndex
			    + offset;

		    if (last2 < last) {
			last = last2;
		    }
		}
	    }
	    if (segPtr->typePtr == &tkTextCharType) {
		if (!visibleOnly || !TkTextIsElided(textPtr,&tmpIndex,NULL)) {
		    Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset,
			    last - offset);
		}
	    }
	    TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex);
	}
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateModifiedEvent --
 *
 *	Send an event that the text was modified. This is equivalent to
 *	   event generate $textWidget <<Modified>>

 *
 * Results:
 *	None
 *
 * Side effects:
 *	May force the text window into existence.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateModifiedEvent(
    TkText *textPtr)	/* Information about text widget. */
{
    union {XEvent general; XVirtualEvent virtual;} event;

    Tk_MakeWindowExist(textPtr->tkwin);



    memset(&event, 0, sizeof(event));



    event.general.xany.type = VirtualEvent;














    event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));

    event.general.xany.send_event = False;



    event.general.xany.window = Tk_WindowId(textPtr->tkwin);
    event.general.xany.display = Tk_Display(textPtr->tkwin);
    event.virtual.name = Tk_GetUid("Modified");
    Tk_HandleEvent(&event.general);

}

/*
 *----------------------------------------------------------------------
 *
 * UpdateDirtyFlag --
 *
5540
5541
5542
5543
5544
5545
5546

5547
5548
5549
5550
5551
5552
5553
 */

static void
UpdateDirtyFlag(
    TkSharedText *sharedTextPtr)/* Information about text widget. */
{
    int oldDirtyFlag;


    /*
     * If we've been forced to be dirty, we stay dirty (until explicitly
     * reset, of course).
     */

    if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_FIXED) {







>







5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
 */

static void
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) {
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
    if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_UNDO) {
	sharedTextPtr->isDirty--;
    } else {
	sharedTextPtr->isDirty++;
    }

    if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) {
	GenerateModifiedEvent(sharedTextPtr->peers);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextRunAfterSyncCmd --
 *
 *	This function is called by the event loop and executes the command
 *      scheduled by [.text sync -command $cmd].
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Anything may happen, depending on $cmd contents.
 *
 *----------------------------------------------------------------------
 */

void
TkTextRunAfterSyncCmd(
    ClientData clientData)		/* Information about text widget. */
{
    TkText *textPtr = (TkText *)clientData;
    int code;

    if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	/*
	* The widget has been deleted. Don't do anything.
	*/

	if (textPtr->refCount-- <= 1) {
	    ckfree((char *) textPtr);
	}
	return;
    }

    Tcl_Preserve((ClientData) textPtr->interp);
    code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL);
    if (code == TCL_ERROR) {
	Tcl_AddErrorInfo(textPtr->interp, "\n    (text sync)");
	Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
    }
    Tcl_Release((ClientData) textPtr->interp);
    Tcl_DecrRefCount(textPtr->afterSyncCmd);
    textPtr->afterSyncCmd = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * SearchPerform --
 *







|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5323
5324
5325
5326
5327
5328
5329
5330


5331
















5332






5333




5334















5335
5336
5337
5338
5339
5340
5341
    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 --
 *
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689

5690
5691
5692
5693



5694


5695
5696
5697
5698
5699
5700
5701
5702
				 * index. */
{
    /*
     * Find the starting line and starting offset (measured in Unicode chars
     * for regexp search, utf-8 bytes for exact search).
     */

    if (searchSpecPtr->lineIndexProc(interp, fromPtr, searchSpecPtr,
	    &searchSpecPtr->startLine,
	    &searchSpecPtr->startOffset) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Find the optional end location, similarly.
     */

    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 (TkTextIndexCmp(indexFromPtr, indexToPtr) ==
		(searchSpecPtr->backwards ? -1 : 1)) {
	    return TCL_OK;
	}






	if (searchSpecPtr->lineIndexProc(interp, toPtr, searchSpecPtr,
		&searchSpecPtr->stopLine,
		&searchSpecPtr->stopOffset) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	searchSpecPtr->stopLine = -1;
    }







|











|













>
|
<
|
|
>
>
>
|
>
>
|







5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401

5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
				 * index. */
{
    /*
     * Find the starting line and starting offset (measured in Unicode chars
     * for regexp search, utf-8 bytes for exact search).
     */

    if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr,
	    &searchSpecPtr->startLine,
	    &searchSpecPtr->startOffset) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Find the optional end location, similarly.
     */

    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;
    }
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
				 * 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;
    TkSizeT 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;
    TkSizeT smArray[2 * LOTS_OF_MATCHES];
    TkSizeT *storeMatch = smArray;
    TkSizeT *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.
	 */







|
<




















|
|
|







5465
5466
5467
5468
5469
5470
5471
5472

5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
				 * 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.
	 */
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838

	/*
	 * 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 = TkGetStringFromObj(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.
	 */







|







5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552

	/*
	 * 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.
	 */
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
	/*
	 * 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 >= 0) {
	    if (searchSpecPtr->backwards) {
		if (alreadySearchOffset < lastOffset) {
		    lastOffset = alreadySearchOffset;
		}
	    } else {
		if (alreadySearchOffset > firstOffset) {
		    firstOffset = alreadySearchOffset;







|
|

















|







5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
	/*
	 * 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;
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
		/*
		 * Forward search and first pass, or backward search and
		 * second pass.
		 *
		 * Only use the last part of the line.
		 */

		if (searchSpecPtr->startOffset + 1 > (TkSizeT)firstOffset + 1) {
		    firstOffset = searchSpecPtr->startOffset;
		}
		if ((firstOffset >= lastOffset)
		    && ((lastOffset != 0) || searchSpecPtr->exact)) {
		    goto nextLine;
		}
	    } else {
		/*
		 * Use only the first part of the line.
		 */

		if (searchSpecPtr->startOffset + 1 < (TkSizeT)lastOffset + 1) {
		    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 = TCL_INDEX_NONE;

	if (searchSpecPtr->exact) {
	    int maxExtraLines = 0;
	    const char *startOfLine = Tcl_GetString(theLine);

	    CLANG_ASSERT(pattern);
	    do {
		int ch;
		const char *p;
		TkSizeT lastFullLine = lastOffset;

		if (firstNewLine == -1) {
		    if (searchSpecPtr->strictLimits
			    && (firstOffset + matchLength + 1 > (TkSizeT)lastOffset + 1)) {
			/*
			 * 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 = matchLength ? pattern[0] : '\0';

			if (alreadySearchOffset >= 0) {
			    p = startOfLine + alreadySearchOffset;
			    alreadySearchOffset = -1;
			} else {
			    p = startOfLine + lastOffset -1;
			}
			while (p >= startOfLine + firstOffset) {
			    if (matchLength == 0 || (p[0] == c && !strncmp(
				     p, pattern, matchLength))) {
				goto backwardsMatch;
			    }
			    p--;
			}
			break;
		    } else {
			p = strstr(startOfLine + firstOffset, pattern);







|











|













|





<

|

|



|



















|

|






|
|







5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675

5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
		/*
		 * 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);
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
		} 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, firstNewLine + 1)) {
			/*
			 * No match.
			 */

			break;
		    } else {
			int extraLines = 1;







|







5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
		} 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;
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102

			    /*
			     * 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 ((TkSizeT)lastTotal - skipFirst + 1 >= matchLength + 1) {
				/*
				 * We now have enough text to match, so we
				 * make a final test and break whatever the
				 * result.
				 */

				if (strncmp(p, pattern, matchLength)) {
				    p = NULL;
				}
				break;
			    } else {
				/*
				 * Not enough text yet, but check the prefix.
				 */







|



















|






|







5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815

			    /*
			     * 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.
				 */
6141
6142
6143
6144
6145
6146
6147
6148
6149

6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
		/*
		 * 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 ? matchLength : 1);
                            if (alreadySearchOffset < 0) {
                                break;
                            }
			}
		    } else {
                        firstOffset = matchLength ? p - startOfLine + matchLength
                                                  : p - startOfLine + (TkSizeT)1;
			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.







|
|
>













|
<
<
|
<

|
<







5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877


5878

5879
5880

5881
5882
5883
5884
5885
5886
5887
		/*
		 * 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.
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
		    if (searchSpecPtr->backwards) {
			alreadySearchOffset = p - startOfLine - 1;
			if (alreadySearchOffset < 0) {
			    break;
			}
		    } else {
			firstOffset = p - startOfLine +
				TkUtfToUniChar(startOfLine+matchOffset,&ch);
		    }
		}
	    } while (searchSpecPtr->all);
	} else {
	    int maxExtraLines = 0;
	    int matches = 0;
	    int lastNonOverlap = -1;

	    do {
		Tcl_RegExpInfo info;
		int match;
		TkSizeT 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 == (TkSizeT) (lastOffset - firstOffset)))) {
		    int extraLines = 0;
		    TkSizeT 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 == TCL_INDEX_NONE) {
			/*
			 * No multi-line match is possible.
			 */

			break;
		    }








|











|

















|

|















|







5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
		    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;
		    }

6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
			}

			/*
			 * 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.
				 */








|







5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
			}

			/*
			 * 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.
				 */

6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
			 * 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 != (TkSizeT) lastTotal &&
				firstOffset + info.matches[0].end + 1 < prevFullLine + 1)
				|| info.extendStart == TCL_INDEX_NONE) {
			    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 + 1 >= (TkSizeT) lastOffset + 1)) {
			    break;
			}
			if (match && ((firstOffset + info.matches[0].end)
				>= prevFullLine)) {
			    if (extraLines > 0) {
				extraLinesSearched = extraLines - 1;
			    }







|
|
|










|







6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
			 * 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;
			    }
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
				    - info.matches[0].start;

			    if (lastNonOverlap != -1) {
				/*
				 * Possible overlap or enclosure.
				 */

				if ((TkSizeT)thisOffset - lastNonOverlap >=
					lastBackwardsMatchOffset + matchLength + 1){
				    /*
				     * Totally encloses previous match, so
				     * forget the previous match.
				     */

				    lastBackwardsLineMatch = -1;
				} else if ((thisOffset - lastNonOverlap)







|
|







6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
				    - 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)
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
		} 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 == TCL_INDEX_NONE ||
			((searchSpecPtr->all || searchSpecPtr->backwards)
			&& (((TkSizeT)firstOffset + 1 < matchOffset + 1)
			|| ((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.
			     */

			    TkSizeT *newArray = (TkSizeT *)
				    ckalloc(4 * matchNum * sizeof(TkSizeT));
			    memcpy(newArray, storeMatch, matchNum*sizeof(TkSizeT));
			    memcpy(newArray + 2*matchNum, storeLength,
				    matchNum * sizeof(TkSizeT));
			    if (storeMatch != smArray) {
				ckfree(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 + 1 > 1 && !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







|
|
|



















|

|


|

















|
|
|

|

|















|
















|







6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
		} 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
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
			 * 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] + 1
			    >= matchOffset + matchLength + 1) {
			/*
			 * 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 != TCL_INDEX_NONE)
		&& !searchSpecPtr->all) {
	    searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo,
		    theLine, matchOffset, matchLength);
	    goto searchDone;
	}

	/*
	 * Go to the next (or previous) line;
	 */







|
|















|














|
















|

|







6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
			 * 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;
	 */
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699

	    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;
		    }
		}







|







6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409

	    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;
		    }
		}
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
	}

	Tcl_SetObjLength(theLine, 0);
    }
  searchDone:

    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(storeMatch);
    }

    return code;
}

/*
 *----------------------------------------------------------------------







|















|







6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
	}

	Tcl_SetObjLength(theLine, 0);
    }
  searchDone:

    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;
}

/*
 *----------------------------------------------------------------------
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788


6789
6790
6791
6792
6793
6794
6795
6796
6797
 *	Creates a new Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetLineStartEnd(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
				 * line value. */
{
    TkTextLine *linePtr = *(TkTextLine **)(recordPtr + internalOffset);

    if (linePtr == NULL) {
	return Tcl_NewObj();


    }
    return Tcl_NewWideIntObj(1 + TkBTreeLinesTo(NULL, linePtr));
}

/*
 *----------------------------------------------------------------------
 *
 * SetLineStartEnd --
 *







|
|

|






>
>

<







6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501

6502
6503
6504
6505
6506
6507
6508
 *	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 --
 *
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
 *	that the specified string was empty and that is acceptable.
 *
 *----------------------------------------------------------------------
 */

static int
SetLineStartEnd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* 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. */
    TkSizeT 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 != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
    }

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {







|

|




|








|
|







6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
 *	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 {
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
 *	Restores the old value.
 *
 *----------------------------------------------------------------------
 */

static void
RestoreLineStartEnd(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr,		/* Pointer to storage for value. */
    char *oldInternalPtr)	/* Pointer to old value. */
{
    *(TkTextLine **)internalPtr = *(TkTextLine **)oldInternalPtr;
}

/*







|
|







6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
 *	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;
}

/*
6896
6897
6898
6899
6900
6901
6902


6903
6904
6905
6906
6907
6908

6909
6910
6911
6912
6913
6914
6915
6916
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{


    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTesttextCmd --
 *







>
>



|
|

>
|







6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
 *----------------------------------------------------------------------
 */

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 --
 *
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950



6951

6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985


6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */

int
TkpTesttextCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkText *textPtr;
    size_t len;
    int lineIndex, byteIndex, byteOffset;
    TkTextIndex index;
    char buf[64];
    Tcl_CmdInfo info;

    if (objc < 3) {
	return TCL_ERROR;
    }

    if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) == 0) {
	return TCL_ERROR;
    }



    textPtr = (TkText *)info.objClientData;

    len = strlen(Tcl_GetString(objv[2]));
    if (strncmp(Tcl_GetString(objv[2]), "byteindex", len) == 0) {
	if (objc != 5) {
	    return TCL_ERROR;
	}
	lineIndex = atoi(Tcl_GetString(objv[3])) - 1;
	byteIndex = atoi(Tcl_GetString(objv[4]));

	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineIndex,
		byteIndex, &index);
    } else if (strncmp(Tcl_GetString(objv[2]), "forwbytes", len) == 0) {
	if (objc != 5) {
	    return TCL_ERROR;
	}
	if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	byteOffset = atoi(Tcl_GetString(objv[4]));
	TkTextIndexForwBytes(textPtr, &index, byteOffset, &index);
    } else if (strncmp(Tcl_GetString(objv[2]), "backbytes", len) == 0) {
	if (objc != 5) {
	    return TCL_ERROR;
	}
	if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	byteOffset = atoi(Tcl_GetString(objv[4]));
	TkTextIndexBackBytes(textPtr, &index, byteOffset, &index);
    } else {
	return TCL_ERROR;
    }

    TkTextSetMark(textPtr, "insert", &index);
    TkTextPrintIndex(textPtr, &index, buf);


    Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s %d", buf, index.byteIndex));
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|
|








|



|


>
>
>
|
>
|
|
|


|
|



|
|


|


|

|
|


|


|







>
>
|










6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
 *	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:
 */

Changes to generic/tkText.h.

17
18
19
20
21
22
23











24
25
26
27
28
29
30
#include "tk.h"
#endif

#ifndef _TKUNDO
#include "tkUndo.h"
#endif












/*
 * 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 {







>
>
>
>
>
>
>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "tk.h"
#endif

#ifndef _TKUNDO
#include "tkUndo.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Opaque types for structures whose guts are only needed by a single file.
 */

typedef struct TkTextBTree_ *TkTextBTree;

/*
 * 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 {
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
typedef struct TkTextSegment {
    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. */
    TkSizeT size;			/* Size of this segment (# of bytes of index
				 * space it occupies). */
    union {
	char chars[TKFLEXARRAY];		/* 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;







|


|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
typedef struct TkTextSegment {
    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. */
    } body;
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
				 * 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
				 * valid if lMargin2String is non-NULL. */
    Tk_3DBorder lMarginColor;	/* Used for drawing background in left margins.
                                 * This is used for both lmargin1 and lmargin2.
				 * NULL means no value specified here. */
    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. */
    int overstrike;		/* Non-zero means draw horizontal line through
				 * middle of text. Only valid if
				 * overstrikeString is non-NULL. */
    XColor *overstrikeColor;    /* Color for the overstrike. NULL means same
                                 * color as foreground. */
    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. */
    Tk_3DBorder rMarginColor;	/* Used for drawing background in right margin.
				 * NULL means no value specified here. */
    Tk_3DBorder selBorder;	/* Used for drawing background for selected text.
				 * NULL means no value specified here. */
    XColor *selFgColor;		/* Foreground color for selected text. NULL means
				 * no value specified here. */
    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. */







<
<
<











<
<




<
<
<
<
<
<







354
355
356
357
358
359
360



361
362
363
364
365
366
367
368
369
370
371


372
373
374
375






376
377
378
379
380
381
382
				 * 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
				 * valid if lMargin2String is non-NULL. */



    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. */
    int overstrike;		/* Non-zero means draw horizontal line through
				 * 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
				 * 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. */
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    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
				 * non-NULL. */
    XColor *underlineColor;     /* Color for the underline. NULL means same
                                 * color as foreground. */
    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
				 * whole widget. */
    char *elideString;		/* -elide option string (malloc-ed). NULL
				 * means option not specified. */







<
<







396
397
398
399
400
401
402


403
404
405
406
407
408
409
    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
				 * 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
				 * whole widget. */
    char *elideString;		/* -elide option string (malloc-ed). NULL
				 * means option not specified. */
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
typedef struct TkTextTabArray {
    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[TKFLEXARRAY];/* Array of tabs. The actual size will be
				 * numTabs. THIS FIELD MUST BE THE LAST IN THE
				 * STRUCTURE. */
} TkTextTabArray;

/*
 * Enumeration defining the edit modes of the widget.
 */

typedef enum {
    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 */







|





|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
typedef struct TkTextTabArray {
    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;

/*
 * 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_REPLACE,	/* replace mode */
    TK_TEXT_EDIT_OTHER		/* none of the above */
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
} TkTextState;

/*
 * A data structure of the following type is shared between each text widget
 * that are peers.
 */

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

typedef struct TkSharedText {
    TkSizeT 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. 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







<
<
<
<
<
<
<
<

|







526
527
528
529
530
531
532








533
534
535
536
537
538
539
540
541
} 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. 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
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
				 * 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. */
    TkSizeT 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 undoMarkId;             /* Counts undo marks temporarily used during
                                   undo and redo operations. */
    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;

/*
 * The following enum is used to define a type for the -insertunfocussed
 * option of the Text widget.
 */

typedef enum {
    TK_TEXT_INSERT_NOFOCUS_HOLLOW,
    TK_TEXT_INSERT_NOFOCUS_NONE,
    TK_TEXT_INSERT_NOFOCUS_SOLID
} TkTextInsertUnfocussed;

/*
 * A data structure of the following type is kept for each text widget that
 * currently exists for this process:
 */

typedef struct TkText {
    /*







|

















<
<
















<
<
<
<
<
<
<
<
<
<
<







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580


581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596











597
598
599
600
601
602
603
				 * 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 {
    /*
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
     */

    TkTextSegment *insertMarkPtr;
				/* Points to segment for "insert" mark. */
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. */
    int insertWidth;		/* Total width of insert cursor. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor */
    TkTextInsertUnfocussed insertUnfocussed;
				/* How to display the insert cursor when the
				 * text widget does not have the focus. */
    int insertOnTime;		/* Number of milliseconds cursor should spend
				 * in "on" state for each blink. */
    int insertOffTime;		/* Number of milliseconds cursor should spend
				 * in "off" state for each blink. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */







|
<
<
<







722
723
724
725
726
727
728
729



730
731
732
733
734
735
736
     */

    TkTextSegment *insertMarkPtr;
				/* Points to segment for "insert" mark. */
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. */
    int insertWidth;		/* Total width of insert cursor. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor. */



    int insertOnTime;		/* Number of milliseconds cursor should spend
				 * in "on" state for each blink. */
    int insertOffTime;		/* Number of milliseconds cursor should spend
				 * in "off" state for each blink. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
				 * 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
				 * definitions. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    TkSizeT refCount;		/* Number of cached TkTextIndex objects
				 * refering to us. */
    int insertCursorType;	/* 0 = standard insertion cursor, 1 = block
				 * cursor. */

    /*
     * Copies of information from the shared section relating to the undo/redo
     * functonality
     */

    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. */
    Tcl_Obj *afterSyncCmd;	/* Command to be executed when lines are up to
                                 * date */
} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.







|
















<
<







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784


785
786
787
788
789
790
791
				 * 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
				 * 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. */

    /*
     * Copies of information from the shared section relating to the undo/redo
     * functonality
     */

    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. */


} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

/*
 * 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,
			    TkSizeT 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, TkSizeT offset, int maxX,
			    TkSizeT maxChars, int noCharsYet, TkWrapMode wrapMode,
			    struct TkTextDispChunk *chunkPtr);
typedef void		Tk_SegCheckProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);

typedef struct Tk_SegType {
    const char *name;		/* Name of this kind of segment. */
    int leftGravity;		/* If a segment has zero size (e.g. a mark or







|








|
|







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839

/*
 * 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 {
    const char *name;		/* Name of this kind of segment. */
    int leftGravity;		/* If a segment has zero size (e.g. a mark or
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
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;
MODULE_SCOPE const Tk_SegType tkTextEmbWindowType;
MODULE_SCOPE const Tk_SegType tkTextEmbImageType;

/*
 * 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) \







<
<







951
952
953
954
955
956
957


958
959
960
961
962
963
964
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) \
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038


1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057



1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077


1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088



1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100



1101
1102
1103
1104
1105
1106
1107
1108
1109




1110
1111
1112
1113
1114
1115
1116
1117
1118
1119



1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140


1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155


1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172



1173
1174
1175
1176
1177
1178
1179
1180
1181
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 TkSizeT	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	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);
MODULE_SCOPE void	TkBTreeStartSearchBack(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    TkTextSearch *searchPtr);
MODULE_SCOPE int	TkBTreeTag(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    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 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,
			    TkSizeT offset, int maxX, TkSizeT maxChars, int noBreakYet,
			    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	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 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	TkTextIndexCountBytes(const TkText *textPtr,
			    const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr);
MODULE_SCOPE int	TkTextIndexCount(const TkText *textPtr,
			    const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr,
			    TkTextCountType type);



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,
			    TkSizeT *offsetPtr);




MODULE_SCOPE void	TkTextLostSelection(ClientData clientData);
MODULE_SCOPE TkTextIndex *TkTextMakeCharIndex(TkTextBTree tree, TkText *textPtr,
			    int lineIndex, int charIndex,
			    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 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 Bool	TkTextPendingsync(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 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 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	TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE void	TkTextWinFreeClient(Tcl_HashEntry *hPtr,
			    TkTextEmbWindowClient *client);
MODULE_SCOPE void       TkTextRunAfterSyncCmd(ClientData clientData);



#endif /* _TKTEXT */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


















>
>



















>
>
>





|














>
>





|





>
>
>












>
>
>








|
>
>
>
>










>
>
>

















<



>
>















>
>












>
>




|
>
>
>









983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
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);
MODULE_SCOPE void	TkBTreeStartSearchBack(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    TkTextSearch *searchPtr);
MODULE_SCOPE int	TkBTreeTag(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    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);
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	TkTextIndexCountBytes(const TkText *textPtr,
			    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);
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:
 */

Changes to generic/tkTextBTree.c.

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
 */

typedef struct BTree {
    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. */
    TkSizeT 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;







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
 */

typedef struct BTree {
    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;
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

int tkBTreeDebug = 0;

/*
 * Macros that determine how much space to allocate for new segments:
 */

#define CSEG_SIZE(chars) (offsetof(TkTextSegment, body) \
	+ 1 + (chars))
#define TSEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextToggle))

/*
 * 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, TkSizeT 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,







|
|
|
|

















|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

int tkBTreeDebug = 0;

/*
 * Macros that determine how much space to allocate for new segments:
 */

#define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \
	+ 1 + (chars)))
#define TSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
	+ sizeof(TkTextToggle)))

/*
 * 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,
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
 *----------------------------------------------------------------------
 */

TkTextBTree
TkBTreeCreate(
    TkSharedText *sharedTextPtr)
{
    BTree *treePtr;
    Node *rootPtr;
    TkTextLine *linePtr, *linePtr2;
    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.
     */

    rootPtr = (Node *)ckalloc(sizeof(Node));
    linePtr = (TkTextLine *)ckalloc(sizeof(TkTextLine));
    linePtr2 = (TkTextLine *)ckalloc(sizeof(TkTextLine));

    rootPtr->parentPtr = NULL;
    rootPtr->nextPtr = NULL;
    rootPtr->summaryPtr = NULL;
    rootPtr->level = 0;
    rootPtr->children.linePtr = linePtr;
    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));
    linePtr->segPtr = segPtr;
    segPtr->typePtr = &tkTextCharType;
    segPtr->nextPtr = NULL;
    segPtr->size = 1;
    segPtr->body.chars[0] = '\n';
    segPtr->body.chars[1] = 0;

    linePtr2->parentPtr = rootPtr;
    linePtr2->nextPtr = NULL;
    segPtr = (TkTextSegment *)ckalloc(CSEG_SIZE(1));
    linePtr2->segPtr = segPtr;
    segPtr->typePtr = &tkTextCharType;
    segPtr->nextPtr = NULL;
    segPtr->size = 1;
    segPtr->body.chars[0] = '\n';
    segPtr->body.chars[1] = 0;

    treePtr = (BTree *)ckalloc(sizeof(BTree));
    treePtr->sharedTextPtr = sharedTextPtr;
    treePtr->rootPtr = rootPtr;
    treePtr->clients = 0;
    treePtr->stateEpoch = 0;
    treePtr->pixelReferences = 0;
    treePtr->startEndCount = 0;
    treePtr->startEnd = NULL;







|
|
|
|








|
|
|




















|









|







|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
 *----------------------------------------------------------------------
 */

TkTextBTree
TkBTreeCreate(
    TkSharedText *sharedTextPtr)
{
    register BTree *treePtr;
    register Node *rootPtr;
    register TkTextLine *linePtr, *linePtr2;
    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.
     */

    rootPtr = (Node *) ckalloc(sizeof(Node));
    linePtr = (TkTextLine *) ckalloc(sizeof(TkTextLine));
    linePtr2 = (TkTextLine *) ckalloc(sizeof(TkTextLine));

    rootPtr->parentPtr = NULL;
    rootPtr->nextPtr = NULL;
    rootPtr->summaryPtr = NULL;
    rootPtr->level = 0;
    rootPtr->children.linePtr = linePtr;
    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));
    linePtr->segPtr = segPtr;
    segPtr->typePtr = &tkTextCharType;
    segPtr->nextPtr = NULL;
    segPtr->size = 1;
    segPtr->body.chars[0] = '\n';
    segPtr->body.chars[1] = 0;

    linePtr2->parentPtr = rootPtr;
    linePtr2->nextPtr = NULL;
    segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(1));
    linePtr2->segPtr = segPtr;
    segPtr->typePtr = &tkTextCharType;
    segPtr->nextPtr = NULL;
    segPtr->size = 1;
    segPtr->body.chars[0] = '\n';
    segPtr->body.chars[1] = 0;

    treePtr = (BTree *) ckalloc(sizeof(BTree));
    treePtr->sharedTextPtr = sharedTextPtr;
    treePtr->rootPtr = rootPtr;
    treePtr->clients = 0;
    treePtr->stateEpoch = 0;
    treePtr->pixelReferences = 0;
    treePtr->startEndCount = 0;
    treePtr->startEnd = NULL;
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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. */
{
    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);







|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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);
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
     * 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(treePtr->startEnd);
	ckfree(treePtr->startEndRef);
    }
    ckfree(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.
 *
 *----------------------------------------------------------------------
 */

TkSizeT
TkBTreeEpoch(
    TkTextBTree tree)		/* Tree to get epoch for. */
{
    BTree *treePtr = (BTree *) tree;
    return treePtr->stateEpoch;
}








|
|

|



















|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
     * 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;
}

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

    if (treePtr->clients == 1) {
	/*
	 * The last reference to the tree.
	 */

	DestroyNode(treePtr->rootPtr);
	ckfree(treePtr);
	return;
    } else if (pixelReference == -1) {
	/*
	 * A client which doesn't care about pixels.
	 */

	treePtr->clients--;







|







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

    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--;
628
629
630
631
632
633
634
635

636
637

638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

654
655

656
657
658
659
660
661
662
	    }
	    if (treePtr->startEndRef[i] != textPtr) {
		count++;
	    }
	    i++;
	}
	treePtr->startEndCount = count;
	treePtr->startEnd = (TkTextLine **)ckrealloc(treePtr->startEnd,

		sizeof(TkTextLine *) * count);
	treePtr->startEndRef = (TkText **)ckrealloc(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(treePtr->startEnd,

		sizeof(TkTextLine *) * count);
	treePtr->startEndRef = (TkText **)ckrealloc(treePtr->startEndRef,

		sizeof(TkText *) * count);

	if (textPtr->start != NULL) {
	    count--;
	    treePtr->startEnd[count] = textPtr->start;
	    treePtr->startEndRef[count] = textPtr;
	}







|
>

|
>















|
>

|
>







628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
	    }
	    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;
	}
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762

	while (loopPtr != NULL) {
	    pixelCount += AdjustPixelClient(treePtr, defaultHeight, loopPtr,
		    start, end, useReference, newPixelReferences, counting);
	    loopPtr = loopPtr->nextPtr;
	}
    } else {
	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(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(nodePtr->numPixels,
		sizeof(int) * newPixelReferences);
    }
    nodePtr->numPixels[useReference] = pixelCount;
    return pixelCount;
}

/*







|









|
















|







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

	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;
}

/*
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
     */

    if (overwriteWithLast != -1) {
	nodePtr->numPixels[overwriteWithLast] =
		nodePtr->numPixels[treePtr->pixelReferences-1];
    }
    if (treePtr->pixelReferences == 1) {
	ckfree(nodePtr->numPixels);
	nodePtr->numPixels = NULL;
    } else {
	nodePtr->numPixels = (int *)ckrealloc(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 {
	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(linePtr->pixels,
			sizeof(int) * 2 * (treePtr->pixelReferences-1));
	    }
	    linePtr = linePtr->nextPtr;
	}
    }
}








<


|









|










|







799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
     */

    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;
	}
    }
}

846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
 *	All the storage for nodePtr and its descendants is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyNode(
    Node *nodePtr)	/* Destroy from this node downwards. */
{
    if (nodePtr->level == 0) {
	TkTextLine *linePtr;
	TkTextSegment *segPtr;

	while (nodePtr->children.linePtr != NULL) {
	    linePtr = nodePtr->children.linePtr;
	    nodePtr->children.linePtr = linePtr->nextPtr;
	    while (linePtr->segPtr != NULL) {
		segPtr = linePtr->segPtr;
		linePtr->segPtr = segPtr->nextPtr;
		segPtr->typePtr->deleteProc(segPtr, linePtr, 1);
	    }
	    ckfree(linePtr->pixels);
	    ckfree(linePtr);
	}
    } else {
	Node *childPtr;

	while (nodePtr->children.nodePtr != NULL) {
	    childPtr = nodePtr->children.nodePtr;
	    nodePtr->children.nodePtr = childPtr->nextPtr;
	    DestroyNode(childPtr);
	}
    }
    DeleteSummaries(nodePtr->summaryPtr);
    ckfree(nodePtr->numPixels);
    ckfree(nodePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteSummaries --
 *







|











|

|
|


|








|
|







849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
 *	All the storage for nodePtr and its descendants is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyNode(
    register Node *nodePtr)	/* Destroy from this node downwards. */
{
    if (nodePtr->level == 0) {
	TkTextLine *linePtr;
	TkTextSegment *segPtr;

	while (nodePtr->children.linePtr != NULL) {
	    linePtr = nodePtr->children.linePtr;
	    nodePtr->children.linePtr = linePtr->nextPtr;
	    while (linePtr->segPtr != NULL) {
		segPtr = linePtr->segPtr;
		linePtr->segPtr = segPtr->nextPtr;
		(*segPtr->typePtr->deleteProc)(segPtr, linePtr, 1);
	    }
	    ckfree((char *) linePtr->pixels);
	    ckfree((char *) linePtr);
	}
    } else {
	register Node *childPtr;

	while (nodePtr->children.nodePtr != NULL) {
	    childPtr = nodePtr->children.nodePtr;
	    nodePtr->children.nodePtr = childPtr->nextPtr;
	    DestroyNode(childPtr);
	}
    }
    DeleteSummaries(nodePtr->summaryPtr);
    ckfree((char *) nodePtr->numPixels);
    ckfree((char *) nodePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteSummaries --
 *
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
 *	Storage is released.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteSummaries(
    Summary *summaryPtr)
				/* First in list of node's tag summaries. */
{
    Summary *nextPtr;

    while (summaryPtr != NULL) {
	nextPtr = summaryPtr->nextPtr;
	ckfree(summaryPtr);
	summaryPtr = nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *







|


|



|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
 *	Storage is released.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteSummaries(
    register Summary *summaryPtr)
				/* First in list of node's tag summaries. */
{
    register Summary *nextPtr;

    while (summaryPtr != NULL) {
	nextPtr = summaryPtr->nextPtr;
	ckfree((char *) summaryPtr);
	summaryPtr = nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
 *
 *----------------------------------------------------------------------
 */

int
TkBTreeAdjustPixelHeight(
    const TkText *textPtr,	/* Client of the B-tree. */
    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. */
{
    Node *nodePtr;
    int changeToPixelCount;	/* Counts change to total number of pixels in
				 * file. */
    int pixelReference = textPtr->pixelReference;

    changeToPixelCount = newPixelHeight - linePtr->pixels[2 * pixelReference];

    /*







|









|







931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
 *
 *----------------------------------------------------------------------
 */

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];

    /*
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
 *
 *----------------------------------------------------------------------
 */

void
TkBTreeInsertChars(
    TkTextBTree tree,		/* Tree to insert into. */
    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). */
{
    Node *nodePtr;
    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). */
    TkTextSegment *segPtr;
    TkTextLine *newLinePtr;
    size_t chunkSize;		/* # characters in current chunk. */
    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];







|







|
|








|

|
|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
 *
 *----------------------------------------------------------------------
 */

void
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 *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 *changeToPixelCount;	/* Counts change to total number of pixels in
				 * file. */
    int ref;
    int pixels[PIXEL_CLIENTS];
1040
1041
1042
1043
1044
1045
1046
1047

1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
    /*
     * 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') {
		eol++;
		break;
	    }
	}
	chunkSize = eol-string;
	segPtr = (TkTextSegment *)ckalloc(CSEG_SIZE(chunkSize));
	segPtr->typePtr = &tkTextCharType;
	if (curPtr == NULL) {
	    segPtr->nextPtr = linePtr->segPtr;
	    linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = curPtr->nextPtr;
	    curPtr->nextPtr = segPtr;
	}
	segPtr->size = chunkSize;
	memcpy(segPtr->body.chars, string, chunkSize);
	segPtr->body.chars[chunkSize] = 0;

	if (eol[-1] != '\n') {
	    break;
	}

	/*
	 * 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;







|
>















|









|











|







1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
    /*
     * 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') {
		eol++;
		break;
	    }
	}
	chunkSize = eol-string;
	segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(chunkSize));
	segPtr->typePtr = &tkTextCharType;
	if (curPtr == NULL) {
	    segPtr->nextPtr = linePtr->segPtr;
	    linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = curPtr->nextPtr;
	    curPtr->nextPtr = segPtr;
	}
	segPtr->size = chunkSize;
	memcpy(segPtr->body.chars, string, (size_t) chunkSize);
	segPtr->body.chars[chunkSize] = 0;

	if (eol[-1] != '\n') {
	    break;
	}

	/*
	 * 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;
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
	    nodePtr = nodePtr->parentPtr) {
	nodePtr->numLines += changeToLineCount;
	for (ref = 0; ref < treePtr->pixelReferences; ref++) {
	    nodePtr->numPixels[ref] += changeToPixelCount[ref];
	}
    }
    if (treePtr->pixelReferences > PIXEL_CLIENTS) {
	ckfree(changeToPixelCount);
    }

    nodePtr = linePtr->parentPtr;
    nodePtr->numChildren += changeToLineCount;
    if (nodePtr->numChildren > MAX_CHILDREN) {
	Rebalance(treePtr, nodePtr);
    }







|







1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
	    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(treePtr, nodePtr);
    }
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
static TkTextSegment *
SplitSeg(
    TkTextIndex *indexPtr)	/* Index identifying position at which to
				 * split a segment. */
{
    TkTextSegment *prevPtr, *segPtr;
    TkTextLine *linePtr;
    TkSizeT count = indexPtr->byteIndex;

    linePtr = indexPtr->linePtr;
    prevPtr = NULL;
    segPtr = linePtr->segPtr;

    while (segPtr != NULL) {
	if (segPtr->size + 1 > count + 1) {
	    if (count == 0) {
		return prevPtr;
	    }
	    segPtr = segPtr->typePtr->splitProc(segPtr, count);
	    if (prevPtr == NULL) {
		indexPtr->linePtr->segPtr = segPtr;
	    } else {
		prevPtr->nextPtr = segPtr;
	    }
	    return segPtr;
	} else if ((segPtr->size == 0) && (count == 0)







|






|



|







1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
static TkTextSegment *
SplitSeg(
    TkTextIndex *indexPtr)	/* Index identifying position at which to
				 * split a segment. */
{
    TkTextSegment *prevPtr, *segPtr;
    TkTextLine *linePtr;
    int count = indexPtr->byteIndex;

    linePtr = indexPtr->linePtr;
    prevPtr = NULL;
    segPtr = linePtr->segPtr;

    while (segPtr != NULL) {
	if (segPtr->size > count) {
	    if (count == 0) {
		return prevPtr;
	    }
	    segPtr = (*segPtr->typePtr->splitProc)(segPtr, count);
	    if (prevPtr == NULL) {
		indexPtr->linePtr->segPtr = segPtr;
	    } else {
		prevPtr->nextPtr = segPtr;
	    }
	    return segPtr;
	} else if ((segPtr->size == 0) && (count == 0)
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236
1237
1238
1239
	     */

	    linePtr = TkBTreeNextLine(NULL, linePtr);
	    if (linePtr == NULL) {
		/*
		 * Reached end of the text.
		 */
	    } else {
		segPtr = linePtr->segPtr;
	    }

	}
    }
    Tcl_Panic("SplitSeg reached end of line!");
    return NULL;
}

/*







<
<

>







1227
1228
1229
1230
1231
1232
1233


1234
1235
1236
1237
1238
1239
1240
1241
1242
	     */

	    linePtr = TkBTreeNextLine(NULL, linePtr);
	    if (linePtr == NULL) {
		/*
		 * Reached end of the text.
		 */


	    }
	    segPtr = linePtr->segPtr;
	}
    }
    Tcl_Panic("SplitSeg reached end of line!");
    return NULL;
}

/*
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287

    while (1) {
	anyChanges = 0;
	for (prevPtrPtr = &linePtr->segPtr, segPtr = *prevPtrPtr;
		segPtr != NULL;
		prevPtrPtr = &(*prevPtrPtr)->nextPtr, segPtr = *prevPtrPtr) {
	    if (segPtr->typePtr->cleanupProc != NULL) {
		*prevPtrPtr = segPtr->typePtr->cleanupProc(segPtr, linePtr);
		if (segPtr != *prevPtrPtr) {
		    anyChanges = 1;
		}
	    }
	}
	if (!anyChanges) {
	    break;







|







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290

    while (1) {
	anyChanges = 0;
	for (prevPtrPtr = &linePtr->segPtr, segPtr = *prevPtrPtr;
		segPtr != NULL;
		prevPtrPtr = &(*prevPtrPtr)->nextPtr, segPtr = *prevPtrPtr) {
	    if (segPtr->typePtr->cleanupProc != NULL) {
		*prevPtrPtr = (*segPtr->typePtr->cleanupProc)(segPtr, linePtr);
		if (segPtr != *prevPtrPtr) {
		    anyChanges = 1;
		}
	    }
	}
	if (!anyChanges) {
	    break;
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
 *
 *----------------------------------------------------------------------
 */

void
TkBTreeDeleteIndexRange(
    TkTextBTree tree,		/* Tree to delete from. */
    TkTextIndex *index1Ptr,
				/* Indicates first character that is to be
				 * deleted. */
    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. */







|


|







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
 *
 *----------------------------------------------------------------------
 */

void
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. */
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
			nodePtr = nodePtr->parentPtr) {
		    nodePtr->numLines--;
		    for (ref = 0; ref < treePtr->pixelReferences; ref++) {
			nodePtr->numPixels[ref] -= curLinePtr->pixels[2*ref];
		    }
		}
		changeToLineCount++;
		CLANG_ASSERT(curNodePtr);
		curNodePtr->numChildren--;

		/*
		 * Check if we need to adjust any partial clients.
		 */

		if (treePtr->startEnd != NULL) {







<







1383
1384
1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
			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) {
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
			    if (peer->end == curLinePtr) {
				peer->end = nextLinePtr;
			    }
			}
			checkCount++;
		    }
		}
		ckfree(curLinePtr->pixels);
		ckfree(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.







|
|







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
			    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.
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
		    Node *prevNodePtr = parentPtr->children.nodePtr;
		    while (prevNodePtr->nextPtr != curNodePtr) {
			prevNodePtr = prevNodePtr->nextPtr;
		    }
		    prevNodePtr->nextPtr = curNodePtr->nextPtr;
		}
		parentPtr->numChildren--;
		DeleteSummaries(curNodePtr->summaryPtr);
		ckfree(curNodePtr->numPixels);
		ckfree(curNodePtr);
		curNodePtr = parentPtr;
	    }
	    curNodePtr = curLinePtr->parentPtr;
	    continue;
	}

	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.
	     */

	    if (prevPtr == NULL) {
		segPtr->nextPtr = index1Ptr->linePtr->segPtr;







<
<
|







|







1438
1439
1440
1441
1442
1443
1444


1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
		    Node *prevNodePtr = parentPtr->children.nodePtr;
		    while (prevNodePtr->nextPtr != curNodePtr) {
			prevNodePtr = prevNodePtr->nextPtr;
		    }
		    prevNodePtr->nextPtr = curNodePtr->nextPtr;
		}
		parentPtr->numChildren--;


		ckfree((char *) curNodePtr);
		curNodePtr = parentPtr;
	    }
	    curNodePtr = curLinePtr->parentPtr;
	    continue;
	}

	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.
	     */

	    if (prevPtr == NULL) {
		segPtr->nextPtr = index1Ptr->linePtr->segPtr;
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

    if (index1Ptr->linePtr != index2Ptr->linePtr) {
	TkTextLine *prevLinePtr;

	for (segPtr = lastPtr; segPtr != NULL;
		segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr->lineChangeProc != NULL) {
		segPtr->typePtr->lineChangeProc(segPtr, index2Ptr->linePtr);
	    }
	}
	curNodePtr = index2Ptr->linePtr->parentPtr;
	for (nodePtr = curNodePtr; nodePtr != NULL;
		nodePtr = nodePtr->parentPtr) {
	    nodePtr->numLines--;
	    for (ref = 0; ref < treePtr->pixelReferences; ref++) {







|







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

    if (index1Ptr->linePtr != index2Ptr->linePtr) {
	TkTextLine *prevLinePtr;

	for (segPtr = lastPtr; segPtr != NULL;
		segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr->lineChangeProc != NULL) {
		(*segPtr->typePtr->lineChangeProc)(segPtr, index2Ptr->linePtr);
	    }
	}
	curNodePtr = index2Ptr->linePtr->parentPtr;
	for (nodePtr = curNodePtr; nodePtr != NULL;
		nodePtr = nodePtr->parentPtr) {
	    nodePtr->numLines--;
	    for (ref = 0; ref < treePtr->pixelReferences; ref++) {
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
		    if (peer->end == index2Ptr->linePtr) {
			peer->end = index1Ptr->linePtr;
		    }
		}
		checkCount++;
	    }
	}
	ckfree(index2Ptr->linePtr->pixels);
	ckfree(index2Ptr->linePtr);

	Rebalance((BTree *) index2Ptr->tree, curNodePtr);
    }

    /*
     * Cleanup the segments in the new line.
     */







|
|







1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
		    if (peer->end == index2Ptr->linePtr) {
			peer->end = index1Ptr->linePtr;
		    }
		}
		checkCount++;
	    }
	}
	ckfree((char *) index2Ptr->linePtr->pixels);
	ckfree((char *) index2Ptr->linePtr);

	Rebalance((BTree *) index2Ptr->tree, curNodePtr);
    }

    /*
     * Cleanup the segments in the new line.
     */
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
TkTextLine *
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;
    Node *nodePtr;
    TkTextLine *linePtr;

    if (treePtr == NULL) {
	treePtr = (BTree *) textPtr->sharedTextPtr->tree;
    }

    nodePtr = treePtr->rootPtr;
    if ((line < 0) || (line >= nodePtr->numLines)) {







|
|







1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
TkTextLine *
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;

    if (treePtr == NULL) {
	treePtr = (BTree *) textPtr->sharedTextPtr->tree;
    }

    nodePtr = treePtr->rootPtr;
    if ((line < 0) || (line >= nodePtr->numLines)) {
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
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;
    Node *nodePtr;
    TkTextLine *linePtr;
    int pixelReference = textPtr->pixelReference;

    nodePtr = treePtr->rootPtr;

    if ((pixels < 0) || (pixels > nodePtr->numPixels[pixelReference])) {
	return NULL;
    }







|
|







1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
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;
    }
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
 *
 *----------------------------------------------------------------------
 */

TkTextLine *
TkBTreeNextLine(
    const TkText *textPtr,	/* Next line in the context of this client. */
    TkTextLine *linePtr)
				/* Pointer to existing line in B-tree. */
{
    Node *nodePtr;

    if (linePtr->nextPtr != NULL) {
	if (textPtr != NULL && (linePtr == textPtr->end)) {
	    return NULL;
	} else {
	    return linePtr->nextPtr;
	}







|


|







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
 *
 *----------------------------------------------------------------------
 */

TkTextLine *
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) {
	if (textPtr != NULL && (linePtr == textPtr->end)) {
	    return NULL;
	} else {
	    return linePtr->nextPtr;
	}
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
 *
 *----------------------------------------------------------------------
 */

TkTextLine *
TkBTreePreviousLine(
    TkText *textPtr,		/* Relative to this client of the B-tree. */
    TkTextLine *linePtr)
				/* Pointer to existing line in B-tree. */
{
    Node *nodePtr;
    Node *node2Ptr;
    TkTextLine *prevPtr;

    if (textPtr != NULL && textPtr->start == linePtr) {
	return NULL;
    }

    /*
     * Find the line under this node just before the starting line.







|


|
|
|







1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
 *
 *----------------------------------------------------------------------
 */

TkTextLine *
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.
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
 */

int
TkBTreePixelsTo(
    const TkText *textPtr,	/* Relative to this client of the B-tree. */
    TkTextLine *linePtr)	/* Pointer to existing line in B-tree. */
{
    TkTextLine *linePtr2;
    Node *nodePtr, *parentPtr;
    int index;
    int pixelReference = textPtr->pixelReference;

    /*
     * First count how many pixels precede this line in its level-0 node.
     */








|
|







1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
 */

int
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.
     */

1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
    /*
     * 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) {
	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];







|







1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
    /*
     * 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];
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
 */

int
TkBTreeLinesTo(
    const TkText *textPtr,	/* Relative to this client of the B-tree. */
    TkTextLine *linePtr)	/* Pointer to existing line in B-tree. */
{
    TkTextLine *linePtr2;
    Node *nodePtr, *parentPtr, *nodePtr2;
    int index;

    /*
     * First count how many lines precede this one in its level-0 node.
     */

    nodePtr = linePtr->parentPtr;







|
|







1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
 */

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.
     */

    nodePtr = linePtr->parentPtr;
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
	    if (nodePtr2 == NULL) {
		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;







|







1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
	    if (nodePtr2 == NULL) {
		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;
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
 *
 * Side effects:
 *	SegPtr will be linked into its tree.
 *
 *----------------------------------------------------------------------
 */


void
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. */
{
    TkTextSegment *prevPtr;

    prevPtr = SplitSeg(indexPtr);
    if (prevPtr == NULL) {
	segPtr->nextPtr = indexPtr->linePtr->segPtr;
	indexPtr->linePtr->segPtr = segPtr;
    } else {
	segPtr->nextPtr = prevPtr->nextPtr;







>








|







2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
 *
 * Side effects:
 *	SegPtr will be linked into its tree.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
void
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;

    prevPtr = SplitSeg(indexPtr);
    if (prevPtr == NULL) {
	segPtr->nextPtr = indexPtr->linePtr->segPtr;
	indexPtr->linePtr->segPtr = segPtr;
    } else {
	segPtr->nextPtr = prevPtr->nextPtr;
2075
2076
2077
2078
2079
2080
2081

2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
 * Side effects:
 *	SegPtr will be unlinked from linePtr. The segment itself isn't
 *	modified by this function.
 *
 *----------------------------------------------------------------------
 */


void
TkBTreeUnlinkSegment(
    TkTextSegment *segPtr,	/* Segment to be unlinked. */
    TkTextLine *linePtr)	/* Line that currently contains segment. */
{
    TkTextSegment *prevPtr;

    if (linePtr->segPtr == segPtr) {
	linePtr->segPtr = segPtr->nextPtr;
    } else {
	prevPtr = linePtr->segPtr;
	while (prevPtr->nextPtr != segPtr) {
	    prevPtr = prevPtr->nextPtr;







>





|







2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
 * Side effects:
 *	SegPtr will be unlinked from linePtr. The segment itself isn't
 *	modified by this function.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
void
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 {
	prevPtr = linePtr->segPtr;
	while (prevPtr->nextPtr != segPtr) {
	    prevPtr = prevPtr->nextPtr;
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
 *	indexes may be modified by this function.
 *
 *----------------------------------------------------------------------
 */

int
TkBTreeTag(
    TkTextIndex *index1Ptr,
				/* Indicates first character in range. */
    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, 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.
     */

    oldState = TkBTreeCharTagged(index1Ptr, tagPtr);
    if ((add != 0) ^ oldState) {
	segPtr = (TkTextSegment *)ckalloc(TSEG_SIZE);
	segPtr->typePtr = (add) ? &tkTextToggleOnType : &tkTextToggleOffType;
	prevPtr = SplitSeg(index1Ptr);
	if (prevPtr == NULL) {
	    segPtr->nextPtr = index1Ptr->linePtr->segPtr;
	    index1Ptr->linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = prevPtr->nextPtr;







|

|



















|







2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
 *	indexes may be modified by this function.
 *
 *----------------------------------------------------------------------
 */

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, 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.
     */

    oldState = TkBTreeCharTagged(index1Ptr, tagPtr);
    if ((add != 0) ^ oldState) {
	segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE);
	segPtr->typePtr = (add) ? &tkTextToggleOnType : &tkTextToggleOffType;
	prevPtr = SplitSeg(index1Ptr);
	if (prevPtr == NULL) {
	    segPtr->nextPtr = index1Ptr->linePtr->segPtr;
	    index1Ptr->linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = prevPtr->nextPtr;
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
	    ChangeNodeToggleCount(search.curIndex.linePtr->parentPtr,
		    segPtr->body.toggle.tagPtr, -1);
	    segPtr->body.toggle.inNodeCounts = 0;
	    changed = 1;
	} else {
	    changed = 0;
	}
	ckfree(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







|







2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
	    ChangeNodeToggleCount(search.curIndex.linePtr->parentPtr,
		    segPtr->body.toggle.tagPtr, -1);
	    segPtr->body.toggle.inNodeCounts = 0;
	    changed = 1;
	} else {
	    changed = 0;
	}
	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
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
	 */

	if (changed) {
	    TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);
	}
    }
    if ((add != 0) ^ oldState) {
	segPtr = (TkTextSegment *)ckalloc(TSEG_SIZE);
	segPtr->typePtr = (add) ? &tkTextToggleOffType : &tkTextToggleOnType;
	prevPtr = SplitSeg(index2Ptr);
	if (prevPtr == NULL) {
	    segPtr->nextPtr = index2Ptr->linePtr->segPtr;
	    index2Ptr->linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = prevPtr->nextPtr;







|







2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
	 */

	if (changed) {
	    TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);
	}
    }
    if ((add != 0) ^ oldState) {
	segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE);
	segPtr->typePtr = (add) ? &tkTextToggleOffType : &tkTextToggleOnType;
	prevPtr = SplitSeg(index2Ptr);
	if (prevPtr == NULL) {
	    segPtr->nextPtr = index2Ptr->linePtr->segPtr;
	    index2Ptr->linePtr->segPtr = segPtr;
	} else {
	    segPtr->nextPtr = prevPtr->nextPtr;
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
 *	for the tag, moving it up or down the tree as needed.
 *
 *----------------------------------------------------------------------
 */

static void
ChangeNodeToggleCount(
    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). */
{
    Summary *summaryPtr, *prevPtr;
    Node *node2Ptr;
    int rootLevel;		/* Level of original tag root. */

    tagPtr->toggleCount += delta;
    if (tagPtr->tagRootPtr == NULL) {
	tagPtr->tagRootPtr = nodePtr;
	return;
    }







|





|
|







2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
 *	for the tag, moving it up or down the tree as needed.
 *
 *----------------------------------------------------------------------
 */

static void
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. */

    tagPtr->toggleCount += delta;
    if (tagPtr->tagRootPtr == NULL) {
	tagPtr->tagRootPtr = nodePtr;
	return;
    }
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
	     */

	    if (prevPtr == NULL) {
		nodePtr->summaryPtr = summaryPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = summaryPtr->nextPtr;
	    }
	    ckfree(summaryPtr);
	} else {
	    /*
	     * 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 *rootNodePtr = tagPtr->tagRootPtr;

		summaryPtr = (Summary *)ckalloc(sizeof(Summary));
		summaryPtr->tagPtr = tagPtr;
		summaryPtr->toggleCount = tagPtr->toggleCount - delta;
		summaryPtr->nextPtr = rootNodePtr->summaryPtr;
		rootNodePtr->summaryPtr = summaryPtr;
		rootNodePtr = rootNodePtr->parentPtr;
		rootLevel = rootNodePtr->level;
		tagPtr->tagRootPtr = rootNodePtr;
	    }
	    summaryPtr = (Summary *)ckalloc(sizeof(Summary));
	    summaryPtr->tagPtr = tagPtr;
	    summaryPtr->toggleCount = delta;
	    summaryPtr->nextPtr = nodePtr->summaryPtr;
	    nodePtr->summaryPtr = summaryPtr;
	}
    }








|


















|








|







2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
	     */

	    if (prevPtr == NULL) {
		nodePtr->summaryPtr = summaryPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = summaryPtr->nextPtr;
	    }
	    ckfree((char *) summaryPtr);
	} else {
	    /*
	     * 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 *rootNodePtr = tagPtr->tagRootPtr;

		summaryPtr = (Summary *) ckalloc(sizeof(Summary));
		summaryPtr->tagPtr = tagPtr;
		summaryPtr->toggleCount = tagPtr->toggleCount - delta;
		summaryPtr->nextPtr = rootNodePtr->summaryPtr;
		rootNodePtr->summaryPtr = summaryPtr;
		rootNodePtr = rootNodePtr->parentPtr;
		rootLevel = rootNodePtr->level;
		tagPtr->tagRootPtr = rootNodePtr;
	    }
	    summaryPtr = (Summary *) ckalloc(sizeof(Summary));
	    summaryPtr->tagPtr = tagPtr;
	    summaryPtr->toggleCount = delta;
	    summaryPtr->nextPtr = nodePtr->summaryPtr;
	    nodePtr->summaryPtr = summaryPtr;
	}
    }

2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
	     */

	    if (prevPtr == NULL) {
		node2Ptr->summaryPtr = summaryPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = summaryPtr->nextPtr;
	    }
	    ckfree(summaryPtr);
	    tagPtr->tagRootPtr = node2Ptr;
	    break;
	}
	nodePtr = tagPtr->tagRootPtr;
    }
}








|







2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
	     */

	    if (prevPtr == NULL) {
		node2Ptr->summaryPtr = summaryPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = summaryPtr->nextPtr;
	    }
	    ckfree((char *) summaryPtr);
	    tagPtr->tagRootPtr = node2Ptr;
	    break;
	}
	nodePtr = tagPtr->tagRootPtr;
    }
}

2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512

static TkTextSegment *
FindTagStart(
    TkTextBTree tree,		/* Tree to search within. */
    TkTextTag *tagPtr,		/* Tag to search for. */
    TkTextIndex *indexPtr)	/* Return - index information. */
{
    Node *nodePtr;
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    Summary *summaryPtr;
    int offset;

    nodePtr = tagPtr->tagRootPtr;
    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * Search from the root of the subtree that contains the tag down to the
     * level 0 node.
     */

    while (nodePtr && nodePtr->level > 0) {
	for (nodePtr = nodePtr->children.nodePtr ; nodePtr != NULL;
		nodePtr = nodePtr->nextPtr) {
	    for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    goto gotNodeWithTag;
		}
	    }
	}
    gotNodeWithTag:
	continue;
    }

    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * Work through the lines attached to the level-0 node.
     */

    for (linePtr = nodePtr->children.linePtr; linePtr != NULL;
	    linePtr = linePtr->nextPtr) {
	for (offset = 0, segPtr = linePtr->segPtr ; segPtr != NULL;







|
|
|
|












|













<
<
<
<







2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503




2504
2505
2506
2507
2508
2509
2510

static TkTextSegment *
FindTagStart(
    TkTextBTree tree,		/* Tree to search within. */
    TkTextTag *tagPtr,		/* Tag to search for. */
    TkTextIndex *indexPtr)	/* Return - index information. */
{
    register Node *nodePtr;
    register TkTextLine *linePtr;
    register TkTextSegment *segPtr;
    register Summary *summaryPtr;
    int offset;

    nodePtr = tagPtr->tagRootPtr;
    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * 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 != NULL;
		nodePtr = nodePtr->nextPtr) {
	    for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    goto gotNodeWithTag;
		}
	    }
	}
    gotNodeWithTag:
	continue;
    }





    /*
     * Work through the lines attached to the level-0 node.
     */

    for (linePtr = nodePtr->children.linePtr; linePtr != NULL;
	    linePtr = linePtr->nextPtr) {
	for (offset = 0, segPtr = linePtr->segPtr ; segPtr != NULL;
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597

static TkTextSegment *
FindTagEnd(
    TkTextBTree tree,		/* Tree to search within. */
    TkTextTag *tagPtr,		/* Tag to search for. */
    TkTextIndex *indexPtr)	/* Return - index information. */
{
    Node *nodePtr, *lastNodePtr;
    TkTextLine *linePtr ,*lastLinePtr;
    TkTextSegment *segPtr, *lastSegPtr, *last2SegPtr;
    Summary *summaryPtr;
    int lastoffset, lastoffset2, offset;

    nodePtr = tagPtr->tagRootPtr;
    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * Search from the root of the subtree that contains the tag down to the
     * level 0 node.
     */

    while (nodePtr && nodePtr->level > 0) {
	for (lastNodePtr = NULL, nodePtr = nodePtr->children.nodePtr ;
		nodePtr != NULL; nodePtr = nodePtr->nextPtr) {
	    for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    lastNodePtr = nodePtr;
		    break;
		}
	    }
	}
	nodePtr = lastNodePtr;
    }

    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * Work through the lines attached to the level-0 node.
     */

    last2SegPtr = NULL;
    lastoffset2 = 0;
    lastoffset = 0;







|
|
|
|












|













<
<
<
<







2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584




2585
2586
2587
2588
2589
2590
2591

static TkTextSegment *
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;
    register TkTextSegment *segPtr, *lastSegPtr, *last2SegPtr;
    register Summary *summaryPtr;
    int lastoffset, lastoffset2, offset;

    nodePtr = tagPtr->tagRootPtr;
    if (nodePtr == NULL) {
	return NULL;
    }

    /*
     * 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 != NULL; nodePtr = nodePtr->nextPtr) {
	    for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    lastNodePtr = nodePtr;
		    break;
		}
	    }
	}
	nodePtr = lastNodePtr;
    }





    /*
     * Work through the lines attached to the level-0 node.
     */

    last2SegPtr = NULL;
    lastoffset2 = 0;
    lastoffset = 0;
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
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. */
    TkTextSearch *searchPtr)
				/* Where to store information about search's
				 * progress. */
{
    TkSizeT offset;
    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.
     */







|



|







2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
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. */

    /*
     * Find the segment that contains the first toggle for the tag. This may
     * become the starting point in the search.
     */
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
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. */
    TkTextSearch *searchPtr)
				/* Where to store information about search's
				 * progress. */
{
    TkSizeT offset;
    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.







|



|







2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
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. */

    /*
     * Find the segment that contains the last toggle for the tag. This may
     * become the starting point in the search.
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
 *	search and indicate where the next tag toggle is located.
 *
 *----------------------------------------------------------------------
 */

int
TkBTreeNextTag(
    TkTextSearch *searchPtr)
				/* Information about search in progress; must
				 * have been set up by call to
				 * TkBTreeStartSearch. */
{
    TkTextSegment *segPtr;
    Node *nodePtr;
    Summary *summaryPtr;

    if (searchPtr->linesLeft <= 0) {
	goto searchOver;
    }

    /*
     * The outermost loop iterates over lines that may potentially contain a







|




|
|
|







2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
 *	search and indicate where the next tag toggle is located.
 *
 *----------------------------------------------------------------------
 */

int
TkBTreeNextTag(
    register TkTextSearch *searchPtr)
				/* Information about search in progress; must
				 * have been set up by call to
				 * TkBTreeStartSearch. */
{
    register TkTextSegment *segPtr;
    register Node *nodePtr;
    register Summary *summaryPtr;

    if (searchPtr->linesLeft <= 0) {
	goto searchOver;
    }

    /*
     * The outermost loop iterates over lines that may potentially contain a
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
			 */

			goto nextChild;
		    }
		}
		searchPtr->linesLeft -= nodePtr->numLines;
		if (nodePtr->nextPtr == NULL) {
		    Tcl_Panic("TkBTreeNextTag found incorrect tag summary info");
		}
	    }
	nextChild:
	    continue;
	}

	/*







|







2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
			 */

			goto nextChild;
		    }
		}
		searchPtr->linesLeft -= nodePtr->numLines;
		if (nodePtr->nextPtr == NULL) {
		    Tcl_Panic("TkBTreeNextTag found incorrect tag summary info.");
		}
	    }
	nextChild:
	    continue;
	}

	/*
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
 *	search and indicate where the next tag toggle is located.
 *
 *----------------------------------------------------------------------
 */

int
TkBTreePrevTag(
    TkTextSearch *searchPtr)
				/* Information about search in progress; must
				 * have been set up by call to
				 * TkBTreeStartSearch. */
{
    TkTextSegment *segPtr, *prevPtr;
    TkTextLine *linePtr, *prevLinePtr;
    Node *nodePtr, *node2Ptr, *prevNodePtr;
    Summary *summaryPtr;
    int byteIndex, linesSkipped;
    int pastLast;		/* Saw last marker during scan. */

    if (searchPtr->linesLeft <= 0) {
	goto searchOver;
    }








|




|
|
|
|







3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
 *	search and indicate where the next tag toggle is located.
 *
 *----------------------------------------------------------------------
 */

int
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, linesSkipped;
    int pastLast;		/* Saw last marker during scan. */

    if (searchPtr->linesLeft <= 0) {
	goto searchOver;
    }

3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
		}
		linesSkipped += nodePtr->numLines;

	    keepLooking2:
		continue;
	    }
	    if (prevNodePtr == NULL) {
		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







|







3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
		}
		linesSkipped += nodePtr->numLines;

	    keepLooking2:
		continue;
	    }
	    if (prevNodePtr == NULL) {
		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
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254

int
TkBTreeCharTagged(
    const TkTextIndex *indexPtr,/* Indicates a character position at which to
				 * check for a tag. */
    TkTextTag *tagPtr)		/* Tag of interest. */
{
    Node *nodePtr;
    TkTextLine *siblingLinePtr;
    TkTextSegment *segPtr;
    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.
     */

    toggleSegPtr = NULL;
    for (index = 0, segPtr = indexPtr->linePtr->segPtr;
	    (index + (int)segPtr->size) <= indexPtr->byteIndex;
	    index += segPtr->size, segPtr = segPtr->nextPtr) {
	if (((segPtr->typePtr == &tkTextToggleOnType)
		|| (segPtr->typePtr == &tkTextToggleOffType))
		&& (segPtr->body.toggle.tagPtr == tagPtr)) {
	    toggleSegPtr = segPtr;
	}
    }







|
|
|











|







3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248

int
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;
    register TkTextSegment *segPtr;
    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.
     */

    toggleSegPtr = NULL;
    for (index = 0, segPtr = indexPtr->linePtr->segPtr;
	    (index + segPtr->size) <= indexPtr->byteIndex;
	    index += segPtr->size, segPtr = segPtr->nextPtr) {
	if (((segPtr->typePtr == &tkTextToggleOnType)
		|| (segPtr->typePtr == &tkTextToggleOffType))
		&& (segPtr->body.toggle.tagPtr == tagPtr)) {
	    toggleSegPtr = segPtr;
	}
    }
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
     * node, counting the number of toggles of the given tag in siblings that
     * precede that node.
     */

    toggles = 0;
    for (nodePtr = indexPtr->linePtr->parentPtr; nodePtr->parentPtr != NULL;
	    nodePtr = nodePtr->parentPtr) {
	Node *siblingPtr;
	Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    toggles += summaryPtr->toggleCount;







|
|







3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
     * node, counting the number of toggles of the given tag in siblings that
     * precede that node.
     */

    toggles = 0;
    for (nodePtr = indexPtr->linePtr->parentPtr; nodePtr->parentPtr != NULL;
	    nodePtr = nodePtr->parentPtr) {
	register Node *siblingPtr;
	register Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->tagPtr == tagPtr) {
		    toggles += summaryPtr->toggleCount;
3330
3331
3332
3333
3334
3335
3336

3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357

3358

3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


TkTextTag **
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. */
{
    Node *nodePtr;
    TkTextLine *siblingLinePtr;
    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(NUM_TAG_INFOS * sizeof(TkTextTag *));

    tagInfo.counts = (int *)ckalloc(NUM_TAG_INFOS * sizeof(int));


    /*
     * Record tag toggles within the line of indexPtr but preceding indexPtr.
     */

    linePtr = indexPtr->linePtr;
    index = 0;
    segPtr = linePtr->segPtr;
    while ((index + (int)segPtr->size) <= indexPtr->byteIndex) {
	if ((segPtr->typePtr == &tkTextToggleOnType)
		|| (segPtr->typePtr == &tkTextToggleOffType)) {
	    IncCount(segPtr->body.toggle.tagPtr, 1, &tagInfo);
	}
	index += segPtr->size;
	segPtr = segPtr->nextPtr;








>










|
|
|







|
>
|
>








|







3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
TkTextTag **
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));

    /*
     * Record tag toggles within the line of indexPtr but preceding indexPtr.
     */

    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;

3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
    /*
     * 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) {
	Node *siblingPtr;
	Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->toggleCount & 1) {
		    IncCount(summaryPtr->tagPtr, summaryPtr->toggleCount,







|
|







3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
    /*
     * 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) {
	register Node *siblingPtr;
	register Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->toggleCount & 1) {
		    IncCount(summaryPtr->tagPtr, summaryPtr->toggleCount,
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
	    if (tagTextPtr==NULL || textPtr==NULL || tagTextPtr==textPtr) {
		tagInfo.tagPtrs[dst] = tagInfo.tagPtrs[src];
		dst++;
	    }
	}
    }
    *numTagsPtr = dst;
    ckfree(tagInfo.counts);
    if (dst == 0) {
	ckfree(tagInfo.tagPtrs);
	return NULL;
    }
    return tagInfo.tagPtrs;
}

/*
 *----------------------------------------------------------------------







|

|







3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
	    if (tagTextPtr==NULL || textPtr==NULL || tagTextPtr==textPtr) {
		tagInfo.tagPtrs[dst] = tagInfo.tagPtrs[src];
		dst++;
	    }
	}
    }
    *numTagsPtr = dst;
    ckfree((char *) tagInfo.counts);
    if (dst == 0) {
	ckfree((char *) tagInfo.tagPtrs);
	return NULL;
    }
    return tagInfo.tagPtrs;
}

/*
 *----------------------------------------------------------------------
3475
3476
3477
3478
3479
3480
3481

3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501

3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516

3517

3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


int
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. */
{
    Node *nodePtr;
    TkTextLine *siblingLinePtr;
    TkTextSegment *segPtr;
    TkTextTag *tagPtr = NULL;
    int i, index;
    TkTextElideInfo *infoPtr;
    TkTextLine *linePtr;
    int elide;

    if (elideInfo == NULL) {
	infoPtr = (TkTextElideInfo *)ckalloc(sizeof(TkTextElideInfo));

    } else {
	infoPtr = elideInfo;
    }

    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(sizeof(int) * infoPtr->numTags);

	infoPtr->tagPtrs = (TkTextTag **)ckalloc(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.
     */

    index = 0;
    linePtr = indexPtr->linePtr;
    segPtr = linePtr->segPtr;
    while ((index + (int)segPtr->size) <= indexPtr->byteIndex) {
	if ((segPtr->typePtr == &tkTextToggleOnType)
		|| (segPtr->typePtr == &tkTextToggleOffType)) {
	    tagPtr = segPtr->body.toggle.tagPtr;
	    if (tagPtr->elideString != NULL) {
		infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
		infoPtr->tagCnts[tagPtr->priority]++;
	    }







>









|
|
|
|
|
|




|
>














|
>
|
>













|







3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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. */
{
    register Node *nodePtr;
    register TkTextLine *siblingLinePtr;
    register TkTextSegment *segPtr;
    register TkTextTag *tagPtr = NULL;
    register int i, index;
    register TkTextElideInfo *infoPtr;
    TkTextLine *linePtr;
    int elide;

    if (elideInfo == NULL) {
	infoPtr = (TkTextElideInfo *)
		ckalloc((unsigned) sizeof(TkTextElideInfo));
    } else {
	infoPtr = elideInfo;
    }

    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.
     */

    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) {
		infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
		infoPtr->tagCnts[tagPtr->priority]++;
	    }
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
    /*
     * 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) {
	Node *siblingPtr;
	Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->toggleCount & 1) {
		    tagPtr = summaryPtr->tagPtr;







|
|







3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
    /*
     * 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) {
	register Node *siblingPtr;
	register Summary *summaryPtr;

	for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
		siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
	    for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
		    summaryPtr = summaryPtr->nextPtr) {
		if (summaryPtr->toggleCount & 1) {
		    tagPtr = summaryPtr->tagPtr;
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
	}
    }

    elide = infoPtr->elide;

    if (elideInfo == NULL) {
	if (LOTSA_TAGS < infoPtr->numTags) {
	    ckfree(infoPtr->tagCnts);
	    ckfree(infoPtr->tagPtrs);
	}

	ckfree(infoPtr);
    }

    return elide;
}

/*
 *----------------------------------------------------------------------







|
|


|







3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
	}
    }

    elide = infoPtr->elide;

    if (elideInfo == NULL) {
	if (LOTSA_TAGS < infoPtr->numTags) {
	    ckfree((char *) infoPtr->tagCnts);
	    ckfree((char *) infoPtr->tagPtrs);
	}

	ckfree((char *) infoPtr);
    }

    return elide;
}

/*
 *----------------------------------------------------------------------
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673

void
TkTextFreeElideInfo(
    TkTextElideInfo *elideInfo)	/* Free any allocated memory in this
				 * structure. */
{
    if (LOTSA_TAGS < elideInfo->numTags) {
	ckfree(elideInfo->tagCnts);
	ckfree(elideInfo->tagPtrs);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * IncCount --







|
|







3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674

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 --
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717

3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
static void
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. */
{
    TkTextTag **tagPtrPtr;
    int count;

    for (tagPtrPtr = tagInfoPtr->tagPtrs, count = tagInfoPtr->numTags;
	    count > 0; tagPtrPtr++, count--) {
	if (*tagPtrPtr == tagPtr) {
	    tagInfoPtr->counts[tagInfoPtr->numTags-count] += inc;
	    return;
	}
    }

    /*
     * 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(newSize * sizeof(TkTextTag *));

	memcpy(newTags, tagInfoPtr->tagPtrs,
		tagInfoPtr->arraySize * sizeof(TkTextTag *));
	ckfree(tagInfoPtr->tagPtrs);
	tagInfoPtr->tagPtrs = newTags;
	newCounts = (int *)ckalloc(newSize * sizeof(int));
	memcpy(newCounts, tagInfoPtr->counts,
		tagInfoPtr->arraySize * sizeof(int));
	ckfree(tagInfoPtr->counts);
	tagInfoPtr->counts = newCounts;
	tagInfoPtr->arraySize = newSize;
    }

    tagInfoPtr->tagPtrs[tagInfoPtr->numTags] = tagPtr;
    tagInfoPtr->counts[tagInfoPtr->numTags] = inc;
    tagInfoPtr->numTags++;







|




















|
>


|

|


|







3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
static void
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;
    int count;

    for (tagPtrPtr = tagInfoPtr->tagPtrs, count = tagInfoPtr->numTags;
	    count > 0; tagPtrPtr++, count--) {
	if (*tagPtrPtr == tagPtr) {
	    tagInfoPtr->counts[tagInfoPtr->numTags-count] += inc;
	    return;
	}
    }

    /*
     * 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(newTags, tagInfoPtr->tagPtrs,
		tagInfoPtr->arraySize * sizeof(TkTextTag *));
	ckfree((char *) tagInfoPtr->tagPtrs);
	tagInfoPtr->tagPtrs = newTags;
	newCounts = (int *) ckalloc((unsigned) newSize * sizeof(int));
	memcpy(newCounts, tagInfoPtr->counts,
		tagInfoPtr->arraySize * sizeof(int));
	ckfree((char *) tagInfoPtr->counts);
	tagInfoPtr->counts = newCounts;
	tagInfoPtr->arraySize = newSize;
    }

    tagInfoPtr->tagPtrs[tagInfoPtr->numTags] = tagPtr;
    tagInfoPtr->counts[tagInfoPtr->numTags] = inc;
    tagInfoPtr->numTags++;
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
 */

void
TkBTreeCheck(
    TkTextBTree tree)		/* Tree to check. */
{
    BTree *treePtr = (BTree *) tree;
    Summary *summaryPtr;
    Node *nodePtr;
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    TkTextTag *tagPtr;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    int count;

    /*
     * Make sure that the tag toggle counts and the tag root pointers are OK.
     */

    for (entryPtr=Tcl_FirstHashEntry(&treePtr->sharedTextPtr->tagTable,&search);
	    entryPtr != NULL ; entryPtr = Tcl_NextHashEntry(&search)) {
	tagPtr = (TkTextTag *)Tcl_GetHashValue(entryPtr);
	nodePtr = tagPtr->tagRootPtr;
	if (nodePtr == NULL) {
	    if (tagPtr->toggleCount != 0) {
		Tcl_Panic("TkBTreeCheck found \"%s\" with toggles (%d) but no root",
			tagPtr->name, tagPtr->toggleCount);
	    }
	    continue;		/* No ranges for the tag. */







|
|
|
|
|










|







3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
 */

void
TkBTreeCheck(
    TkTextBTree tree)		/* Tree to check. */
{
    BTree *treePtr = (BTree *) tree;
    register Summary *summaryPtr;
    register Node *nodePtr;
    register TkTextLine *linePtr;
    register TkTextSegment *segPtr;
    register TkTextTag *tagPtr;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    int count;

    /*
     * Make sure that the tag toggle counts and the tag root pointers are OK.
     */

    for (entryPtr=Tcl_FirstHashEntry(&treePtr->sharedTextPtr->tagTable,&search);
	    entryPtr != NULL ; entryPtr = Tcl_NextHashEntry(&search)) {
	tagPtr = (TkTextTag *) Tcl_GetHashValue(entryPtr);
	nodePtr = tagPtr->tagRootPtr;
	if (nodePtr == NULL) {
	    if (tagPtr->toggleCount != 0) {
		Tcl_Panic("TkBTreeCheck found \"%s\" with toggles (%d) but no root",
			tagPtr->name, tagPtr->toggleCount);
	    }
	    continue;		/* No ranges for the tag. */
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
	Tcl_Panic("TkBTreeCheck: last line has bogus segment type");
    }
    if (segPtr->nextPtr != NULL) {
	Tcl_Panic("TkBTreeCheck: last line has too many segments");
    }
    if (segPtr->size != 1) {
	Tcl_Panic("TkBTreeCheck: last line has wrong # characters: %d",
		(int)segPtr->size);
    }
    if ((segPtr->body.chars[0] != '\n') || (segPtr->body.chars[1] != 0)) {
	Tcl_Panic("TkBTreeCheck: last line had bad value: %s",
		segPtr->body.chars);
    }
}








|







3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
	Tcl_Panic("TkBTreeCheck: last line has bogus segment type");
    }
    if (segPtr->nextPtr != NULL) {
	Tcl_Panic("TkBTreeCheck: last line has too many segments");
    }
    if (segPtr->size != 1) {
	Tcl_Panic("TkBTreeCheck: last line has wrong # characters: %d",
		segPtr->size);
    }
    if ((segPtr->body.chars[0] != '\n') || (segPtr->body.chars[1] != 0)) {
	Tcl_Panic("TkBTreeCheck: last line had bad value: %s",
		segPtr->body.chars);
    }
}

3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
 *	panics.
 *
 *----------------------------------------------------------------------
 */

static void
CheckNodeConsistency(
    Node *nodePtr,	/* Node whose subtree should be checked. */
    int references)		/* Number of referring widgets which have
				 * pixel counts. */
{
    Node *childNodePtr;
    Summary *summaryPtr, *summaryPtr2;
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    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 {
	minChildren = 1;
    }
    if ((nodePtr->numChildren < minChildren)
	    || (nodePtr->numChildren > MAX_CHILDREN)) {
	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) {
		Tcl_Panic("CheckNodeConsistency: line doesn't point to parent");
	    }
	    if (linePtr->segPtr == NULL) {
		Tcl_Panic("CheckNodeConsistency: line has no segments");
	    }
	    for (segPtr = linePtr->segPtr; segPtr != NULL;
		    segPtr = segPtr->nextPtr) {
		if (segPtr->typePtr->checkProc != NULL) {
		    segPtr->typePtr->checkProc(segPtr, linePtr);
		}
		if ((segPtr->size == 0) && (!segPtr->typePtr->leftGravity)
			&& (segPtr->nextPtr != NULL)
			&& (segPtr->nextPtr->size == 0)
			&& (segPtr->nextPtr->typePtr->leftGravity)) {
		    Tcl_Panic("CheckNodeConsistency: wrong segment order for gravity");
		}







|



|
|
|
|




















|



















|







3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
 *	panics.
 *
 *----------------------------------------------------------------------
 */

static void
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, i;
    int *numPixels;
    int pixels[PIXEL_CLIENTS];

    if (nodePtr->parentPtr != NULL) {
	minChildren = MIN_CHILDREN;
    } else if (nodePtr->level > 0) {
	minChildren = 2;
    } else {
	minChildren = 1;
    }
    if ((nodePtr->numChildren < minChildren)
	    || (nodePtr->numChildren > MAX_CHILDREN)) {
	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) {
		Tcl_Panic("CheckNodeConsistency: line doesn't point to parent");
	    }
	    if (linePtr->segPtr == NULL) {
		Tcl_Panic("CheckNodeConsistency: line has no segments");
	    }
	    for (segPtr = linePtr->segPtr; segPtr != NULL;
		    segPtr = segPtr->nextPtr) {
		if (segPtr->typePtr->checkProc != NULL) {
		    (*segPtr->typePtr->checkProc)(segPtr, linePtr);
		}
		if ((segPtr->size == 0) && (!segPtr->typePtr->leftGravity)
			&& (segPtr->nextPtr != NULL)
			&& (segPtr->nextPtr->size == 0)
			&& (segPtr->nextPtr->typePtr->leftGravity)) {
		    Tcl_Panic("CheckNodeConsistency: wrong segment order for gravity");
		}
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
    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(numPixels);
    }

    for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL;
	    summaryPtr = summaryPtr->nextPtr) {
	if (summaryPtr->tagPtr->toggleCount == summaryPtr->toggleCount) {
	    Tcl_Panic("CheckNodeConsistency: found unpruned root for \"%s\"",
		    summaryPtr->tagPtr->name);







|







4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
    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) {
	    Tcl_Panic("CheckNodeConsistency: found unpruned root for \"%s\"",
		    summaryPtr->tagPtr->name);
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
 *
 *----------------------------------------------------------------------
 */

static void
Rebalance(
    BTree *treePtr,		/* Tree that is being rebalanced. */
    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.
     */

    for ( ; nodePtr != NULL; nodePtr = nodePtr->parentPtr) {
	Node *newPtr, *childPtr;
	TkTextLine *linePtr;
	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.
	 */

	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 (nodePtr->parentPtr == NULL) {
		    newPtr = (Node *)ckalloc(sizeof(Node));
		    newPtr->parentPtr = NULL;
		    newPtr->nextPtr = NULL;
		    newPtr->summaryPtr = NULL;
		    newPtr->level = nodePtr->level + 1;
		    newPtr->children.nodePtr = nodePtr;
		    newPtr->numChildren = 1;
		    newPtr->numLines = nodePtr->numLines;
		    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;







|







|
|

















|















|







4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
 *
 *----------------------------------------------------------------------
 */

static void
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.
     */

    for ( ; nodePtr != NULL; nodePtr = nodePtr->parentPtr) {
	register Node *newPtr, *childPtr;
	register TkTextLine *linePtr;
	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.
	 */

	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 (nodePtr->parentPtr == NULL) {
		    newPtr = (Node *) ckalloc(sizeof(Node));
		    newPtr->parentPtr = NULL;
		    newPtr->nextPtr = NULL;
		    newPtr->summaryPtr = NULL;
		    newPtr->level = nodePtr->level + 1;
		    newPtr->children.nodePtr = nodePtr;
		    newPtr->numChildren = 1;
		    newPtr->numLines = nodePtr->numLines;
		    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;
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
		    RecomputeNodeCounts(treePtr, nodePtr);
		    break;
		}
	    }
	}

	while (nodePtr->numChildren < MIN_CHILDREN) {
	    Node *otherPtr;
	    Node *halfwayNodePtr = NULL;       /* Initialization needed only */
	    TkTextLine *halfwayLinePtr = NULL; /* to prevent cc warnings. */
	    int totalChildren, firstChildren;

	    /*
	     * 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) {
		if ((nodePtr->numChildren == 1) && (nodePtr->level > 0)) {
		    treePtr->rootPtr = nodePtr->children.nodePtr;
		    treePtr->rootPtr->parentPtr = NULL;
		    DeleteSummaries(nodePtr->summaryPtr);
		    ckfree(nodePtr->numPixels);
		    ckfree(nodePtr);
		}
		return;
	    }

	    /*
	     * Not the root. Make sure that there are siblings to balance
	     * with.







|


|














<
|







4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188

4189
4190
4191
4192
4193
4194
4195
4196
		    RecomputeNodeCounts(treePtr, nodePtr);
		    break;
		}
	    }
	}

	while (nodePtr->numChildren < MIN_CHILDREN) {
	    register Node *otherPtr;
	    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.
	     */

	    if (nodePtr->parentPtr == NULL) {
		if ((nodePtr->numChildren == 1) && (nodePtr->level > 0)) {
		    treePtr->rootPtr = nodePtr->children.nodePtr;
		    treePtr->rootPtr->parentPtr = NULL;
		    DeleteSummaries(nodePtr->summaryPtr);

		    ckfree((char *) nodePtr);
		}
		return;
	    }

	    /*
	     * Not the root. Make sure that there are siblings to balance
	     * with.
4226
4227
4228
4229
4230
4231
4232


4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246


4247
4248
4249
4250
4251
4252
4253
	    firstChildren = totalChildren/2;
	    if (nodePtr->children.nodePtr == NULL) {
		nodePtr->children = otherPtr->children;
		otherPtr->children.nodePtr = NULL;
		otherPtr->children.linePtr = NULL;
	    }
	    if (nodePtr->level == 0) {


		for (linePtr = nodePtr->children.linePtr, i = 1;
			linePtr->nextPtr != NULL;
			linePtr = linePtr->nextPtr, i++) {
		    if (i == firstChildren) {
			halfwayLinePtr = linePtr;
		    }
		}
		linePtr->nextPtr = otherPtr->children.linePtr;
		while (i <= firstChildren) {
		    halfwayLinePtr = linePtr;
		    linePtr = linePtr->nextPtr;
		    i++;
		}
	    } else {


		for (childPtr = nodePtr->children.nodePtr, i = 1;
			childPtr->nextPtr != NULL;
			childPtr = childPtr->nextPtr, i++) {
		    if (i <= firstChildren) {
			if (i == firstChildren) {
			    halfwayNodePtr = childPtr;
			}







>
>














>
>







4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
	    firstChildren = totalChildren/2;
	    if (nodePtr->children.nodePtr == NULL) {
		nodePtr->children = otherPtr->children;
		otherPtr->children.nodePtr = NULL;
		otherPtr->children.linePtr = NULL;
	    }
	    if (nodePtr->level == 0) {
		register TkTextLine *linePtr;

		for (linePtr = nodePtr->children.linePtr, i = 1;
			linePtr->nextPtr != NULL;
			linePtr = linePtr->nextPtr, i++) {
		    if (i == firstChildren) {
			halfwayLinePtr = linePtr;
		    }
		}
		linePtr->nextPtr = otherPtr->children.linePtr;
		while (i <= firstChildren) {
		    halfwayLinePtr = linePtr;
		    linePtr = linePtr->nextPtr;
		    i++;
		}
	    } else {
		register Node *childPtr;

		for (childPtr = nodePtr->children.nodePtr, i = 1;
			childPtr->nextPtr != NULL;
			childPtr = childPtr->nextPtr, i++) {
		    if (i <= firstChildren) {
			if (i == firstChildren) {
			    halfwayNodePtr = childPtr;
			}
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
	     */

	    if (totalChildren <= MAX_CHILDREN) {
		RecomputeNodeCounts(treePtr, nodePtr);
		nodePtr->nextPtr = otherPtr->nextPtr;
		nodePtr->parentPtr->numChildren--;
		DeleteSummaries(otherPtr->summaryPtr);
		ckfree(otherPtr->numPixels);
		ckfree(otherPtr);
		continue;
	    }

	    /*
	     * The siblings can't be merged, so just divide their children
	     * evenly between them.
	     */

	    if (nodePtr->level == 0) {
		CLANG_ASSERT(halfwayLinePtr);
		otherPtr->children.linePtr = halfwayLinePtr->nextPtr;
		halfwayLinePtr->nextPtr = NULL;
	    } else {
		CLANG_ASSERT(halfwayNodePtr);
		otherPtr->children.nodePtr = halfwayNodePtr->nextPtr;
		halfwayNodePtr->nextPtr = NULL;
	    }
	    RecomputeNodeCounts(treePtr, nodePtr);
	    RecomputeNodeCounts(treePtr, otherPtr);
	}
    }







<
|









<



<







4271
4272
4273
4274
4275
4276
4277

4278
4279
4280
4281
4282
4283
4284
4285
4286
4287

4288
4289
4290

4291
4292
4293
4294
4295
4296
4297
	     */

	    if (totalChildren <= MAX_CHILDREN) {
		RecomputeNodeCounts(treePtr, nodePtr);
		nodePtr->nextPtr = otherPtr->nextPtr;
		nodePtr->parentPtr->numChildren--;
		DeleteSummaries(otherPtr->summaryPtr);

		ckfree((char *) otherPtr);
		continue;
	    }

	    /*
	     * The siblings can't be merged, so just divide their children
	     * evenly between them.
	     */

	    if (nodePtr->level == 0) {

		otherPtr->children.linePtr = halfwayLinePtr->nextPtr;
		halfwayLinePtr->nextPtr = NULL;
	    } else {

		otherPtr->children.nodePtr = halfwayNodePtr->nextPtr;
		halfwayNodePtr->nextPtr = NULL;
	    }
	    RecomputeNodeCounts(treePtr, nodePtr);
	    RecomputeNodeCounts(treePtr, otherPtr);
	}
    }
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
 *	the childrens' parentPtr fields are made to point to nodePtr.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputeNodeCounts(
    BTree *treePtr,	/* The whole B-tree. */
    Node *nodePtr)	/* Node whose tag summary information must be
				 * recomputed. */
{
    Summary *summaryPtr, *summaryPtr2;
    Node *childPtr;
    TkTextLine *linePtr;
    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).
     */







|
|


|
|
|
|







4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
 *	the childrens' parentPtr fields are made to point to nodePtr.
 *
 *----------------------------------------------------------------------
 */

static void
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).
     */
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
			|| !(segPtr->body.toggle.inNodeCounts)) {
		    continue;
		}
		tagPtr = segPtr->body.toggle.tagPtr;
		for (summaryPtr = nodePtr->summaryPtr; ;
			summaryPtr = summaryPtr->nextPtr) {
		    if (summaryPtr == NULL) {
			summaryPtr = (Summary *)ckalloc(sizeof(Summary));
			summaryPtr->tagPtr = tagPtr;
			summaryPtr->toggleCount = 1;
			summaryPtr->nextPtr = nodePtr->summaryPtr;
			nodePtr->summaryPtr = summaryPtr;
			break;
		    }
		    if (summaryPtr->tagPtr == tagPtr) {







|







4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
			|| !(segPtr->body.toggle.inNodeCounts)) {
		    continue;
		}
		tagPtr = segPtr->body.toggle.tagPtr;
		for (summaryPtr = nodePtr->summaryPtr; ;
			summaryPtr = summaryPtr->nextPtr) {
		    if (summaryPtr == NULL) {
			summaryPtr = (Summary *) ckalloc(sizeof(Summary));
			summaryPtr->tagPtr = tagPtr;
			summaryPtr->toggleCount = 1;
			summaryPtr->nextPtr = nodePtr->summaryPtr;
			nodePtr->summaryPtr = summaryPtr;
			break;
		    }
		    if (summaryPtr->tagPtr == tagPtr) {
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
	    }
	    childPtr->parentPtr = nodePtr;
	    for (summaryPtr2 = childPtr->summaryPtr; summaryPtr2 != NULL;
		    summaryPtr2 = summaryPtr2->nextPtr) {
		for (summaryPtr = nodePtr->summaryPtr; ;
			summaryPtr = summaryPtr->nextPtr) {
		    if (summaryPtr == NULL) {
			summaryPtr = (Summary *)ckalloc(sizeof(Summary));
			summaryPtr->tagPtr = summaryPtr2->tagPtr;
			summaryPtr->toggleCount = summaryPtr2->toggleCount;
			summaryPtr->nextPtr = nodePtr->summaryPtr;
			nodePtr->summaryPtr = summaryPtr;
			break;
		    }
		    if (summaryPtr->tagPtr == summaryPtr2->tagPtr) {







|







4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
	    }
	    childPtr->parentPtr = nodePtr;
	    for (summaryPtr2 = childPtr->summaryPtr; summaryPtr2 != NULL;
		    summaryPtr2 = summaryPtr2->nextPtr) {
		for (summaryPtr = nodePtr->summaryPtr; ;
			summaryPtr = summaryPtr->nextPtr) {
		    if (summaryPtr == NULL) {
			summaryPtr = (Summary *) ckalloc(sizeof(Summary));
			summaryPtr->tagPtr = summaryPtr2->tagPtr;
			summaryPtr->toggleCount = summaryPtr2->toggleCount;
			summaryPtr->nextPtr = nodePtr->summaryPtr;
			nodePtr->summaryPtr = summaryPtr;
			break;
		    }
		    if (summaryPtr->tagPtr == summaryPtr2->tagPtr) {
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
	     * the root down to this level.
	     */

	    summaryPtr->tagPtr->tagRootPtr = nodePtr;
	}
	if (summaryPtr2 != NULL) {
	    summaryPtr2->nextPtr = summaryPtr->nextPtr;
	    ckfree(summaryPtr);
	    summaryPtr = summaryPtr2->nextPtr;
	} else {
	    nodePtr->summaryPtr = summaryPtr->nextPtr;
	    ckfree(summaryPtr);
	    summaryPtr = nodePtr->summaryPtr;
	}
    }
}

/*
 *----------------------------------------------------------------------







|



|







4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
	     * the root down to this level.
	     */

	    summaryPtr->tagPtr->tagRootPtr = nodePtr;
	}
	if (summaryPtr2 != NULL) {
	    summaryPtr2->nextPtr = summaryPtr->nextPtr;
	    ckfree((char *) summaryPtr);
	    summaryPtr = summaryPtr2->nextPtr;
	} else {
	    nodePtr->summaryPtr = summaryPtr->nextPtr;
	    ckfree((char *) summaryPtr);
	    summaryPtr = nodePtr->summaryPtr;
	}
    }
}

/*
 *----------------------------------------------------------------------
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554

4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
CharSplitProc(
    TkTextSegment *segPtr,	/* Pointer to segment to split. */
    TkSizeT index)			/* Position within segment at which to
				 * split. */
{
    TkTextSegment *newPtr1, *newPtr2;

    newPtr1 = (TkTextSegment *)ckalloc(CSEG_SIZE(index));
    newPtr2 = (TkTextSegment *)ckalloc(CSEG_SIZE(segPtr->size - index));

    newPtr1->typePtr = &tkTextCharType;
    newPtr1->nextPtr = newPtr2;
    newPtr1->size = index;
    memcpy(newPtr1->body.chars, segPtr->body.chars, index);
    newPtr1->body.chars[index] = 0;
    newPtr2->typePtr = &tkTextCharType;
    newPtr2->nextPtr = segPtr->nextPtr;
    newPtr2->size = segPtr->size - index;
    memcpy(newPtr2->body.chars, segPtr->body.chars + index, newPtr2->size);
    newPtr2->body.chars[newPtr2->size] = 0;
    ckfree(segPtr);
    return newPtr1;
}

/*
 *--------------------------------------------------------------
 *
 * CharCleanupProc --







|




|
|
>



|






|







4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
CharSplitProc(
    TkTextSegment *segPtr,	/* Pointer to segment to split. */
    int index)			/* Position within segment at which to
				 * split. */
{
    TkTextSegment *newPtr1, *newPtr2;

    newPtr1 = (TkTextSegment *) ckalloc(CSEG_SIZE(index));
    newPtr2 = (TkTextSegment *) ckalloc(
	    CSEG_SIZE(segPtr->size - index));
    newPtr1->typePtr = &tkTextCharType;
    newPtr1->nextPtr = newPtr2;
    newPtr1->size = index;
    memcpy(newPtr1->body.chars, segPtr->body.chars, (size_t) index);
    newPtr1->body.chars[index] = 0;
    newPtr2->typePtr = &tkTextCharType;
    newPtr2->nextPtr = segPtr->nextPtr;
    newPtr2->size = segPtr->size - index;
    memcpy(newPtr2->body.chars, segPtr->body.chars + index, newPtr2->size);
    newPtr2->body.chars[newPtr2->size] = 0;
    ckfree((char *) segPtr);
    return newPtr1;
}

/*
 *--------------------------------------------------------------
 *
 * CharCleanupProc --
4580
4581
4582
4583
4584
4585
4586

4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599

4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626

4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655

4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
 *
 * Side effects:
 *	Storage for the segments may be allocated and freed.
 *
 *--------------------------------------------------------------
 */


static TkTextSegment *
CharCleanupProc(
    TkTextSegment *segPtr,	/* Pointer to first of two adjacent segments
				 * to join. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segments (not used). */
{
    TkTextSegment *segPtr2, *newPtr;

    segPtr2 = segPtr->nextPtr;
    if ((segPtr2 == NULL) || (segPtr2->typePtr != &tkTextCharType)) {
	return segPtr;
    }
    newPtr = (TkTextSegment *)ckalloc(CSEG_SIZE(segPtr->size + segPtr2->size));

    newPtr->typePtr = &tkTextCharType;
    newPtr->nextPtr = segPtr2->nextPtr;
    newPtr->size = segPtr->size + segPtr2->size;
    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(segPtr);
    ckfree(segPtr2);
    return newPtr;
}

/*
 *--------------------------------------------------------------
 *
 * CharDeleteProc --
 *
 *	This function is invoked to delete a character segment.
 *
 * Results:
 *	Always returns 0 to indicate that the segment was deleted.
 *
 * Side effects:
 *	Storage for the segment is freed.
 *
 *--------------------------------------------------------------
 */


static int
CharDeleteProc(
    TkTextSegment *segPtr,	/* Segment to delete. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    ckfree(segPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * CharCheckProc --
 *
 *	This function is invoked to perform consistency checks on character
 *	segments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If the segment isn't inconsistent then the function panics.
 *
 *--------------------------------------------------------------
 */


static void
CharCheckProc(
    TkTextSegment *segPtr,	/* Segment to check. */
    TCL_UNUSED(TkTextLine *))	/* 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.
     */

    if (segPtr->size + 1 <= 1) {
	Tcl_Panic("CharCheckProc: segment has size <= 0");
    }
    if (strlen(segPtr->body.chars) != (size_t)segPtr->size) {
	Tcl_Panic("CharCheckProc: segment has wrong size");
    }
    if (segPtr->nextPtr == NULL) {
	if (segPtr->body.chars[segPtr->size-1] != '\n') {
	    Tcl_Panic("CharCheckProc: line doesn't end with newline");
	}
    } else if (segPtr->nextPtr->typePtr == &tkTextCharType) {







>




|







|
>






|
|



















>



|
|



|




















>



|








|


|







4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
 *
 * Side effects:
 *	Storage for the segments may be allocated and freed.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static TkTextSegment *
CharCleanupProc(
    TkTextSegment *segPtr,	/* Pointer to first of two adjacent segments
				 * to join. */
    TkTextLine *linePtr)	/* Line containing segments (not used). */
{
    TkTextSegment *segPtr2, *newPtr;

    segPtr2 = segPtr->nextPtr;
    if ((segPtr2 == NULL) || (segPtr2->typePtr != &tkTextCharType)) {
	return segPtr;
    }
    newPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(
	    segPtr->size + segPtr2->size));
    newPtr->typePtr = &tkTextCharType;
    newPtr->nextPtr = segPtr2->nextPtr;
    newPtr->size = segPtr->size + segPtr2->size;
    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);
    return newPtr;
}

/*
 *--------------------------------------------------------------
 *
 * CharDeleteProc --
 *
 *	This function is invoked to delete a character segment.
 *
 * Results:
 *	Always returns 0 to indicate that the segment was deleted.
 *
 * Side effects:
 *	Storage for the segment is freed.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * CharCheckProc --
 *
 *	This function is invoked to perform consistency checks on character
 *	segments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If the segment isn't inconsistent then the function panics.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
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.
     */

    if (segPtr->size <= 0) {
	Tcl_Panic("CharCheckProc: segment has size <= 0");
    }
    if (strlen(segPtr->body.chars) != (size_t) segPtr->size) {
	Tcl_Panic("CharCheckProc: segment has wrong size");
    }
    if (segPtr->nextPtr == NULL) {
	if (segPtr->body.chars[segPtr->size-1] != '\n') {
	    Tcl_Panic("CharCheckProc: line doesn't end with newline");
	}
    } else if (segPtr->nextPtr->typePtr == &tkTextCharType) {
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
    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(segPtr);
	return 0;
    }

    /*
     * 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







|







4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
    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);
	return 0;
    }

    /*
     * 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
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
	    counts = segPtr->body.toggle.inNodeCounts
		    + segPtr2->body.toggle.inNodeCounts;
	    if (counts != 0) {
		ChangeNodeToggleCount(linePtr->parentPtr,
			segPtr->body.toggle.tagPtr, -counts);
	    }
	    prevPtr->nextPtr = segPtr2->nextPtr;
	    ckfree(segPtr2);
	    segPtr2 = segPtr->nextPtr;
	    ckfree(segPtr);
	    return segPtr2;
	}
    }

    if (!segPtr->body.toggle.inNodeCounts) {
	ChangeNodeToggleCount(linePtr->parentPtr,
		segPtr->body.toggle.tagPtr, 1);







|

|







4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
	    counts = segPtr->body.toggle.inNodeCounts
		    + segPtr2->body.toggle.inNodeCounts;
	    if (counts != 0) {
		ChangeNodeToggleCount(linePtr->parentPtr,
			segPtr->body.toggle.tagPtr, -counts);
	    }
	    prevPtr->nextPtr = segPtr2->nextPtr;
	    ckfree((char *) segPtr2);
	    segPtr2 = segPtr->nextPtr;
	    ckfree((char *) segPtr);
	    return segPtr2;
	}
    }

    if (!segPtr->body.toggle.inNodeCounts) {
	ChangeNodeToggleCount(linePtr->parentPtr,
		segPtr->body.toggle.tagPtr, 1);
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
 */

static void
ToggleCheckProc(
    TkTextSegment *segPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
{
    Summary *summaryPtr;
    int needSummary;

    if (segPtr->size != 0) {
	Tcl_Panic("ToggleCheckProc: segment had non-zero size");
    }
    if (!segPtr->body.toggle.inNodeCounts) {
	Tcl_Panic("ToggleCheckProc: toggle counts not updated in nodes");







|







4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
 */

static void
ToggleCheckProc(
    TkTextSegment *segPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
{
    register Summary *summaryPtr;
    int needSummary;

    if (segPtr->size != 0) {
	Tcl_Panic("ToggleCheckProc: segment had non-zero size");
    }
    if (!segPtr->body.toggle.inNodeCounts) {
	Tcl_Panic("ToggleCheckProc: toggle counts not updated in nodes");

Changes to generic/tkTextDisp.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#define OK_TO_LOG (!TkpWillDrawWidget(textPtr->tkwin))
#endif

#if !defined(MAC_OSX_TK)
#define OK_TO_LOG 1
#endif

/*
 * "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







|



<
<
<


|
|







12
13
14
15
16
17
18
19
20
21
22



23
24
25
26
27
28
29
30
31
32
33
 * 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"

#ifdef __WIN32__
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"



#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif

/*
 * "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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    Pixmap fgStipple;		/* Stipple bitmap for text and other
				 * 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. */
    int lMargin2;		/* Left margin, in pixels, for second and
				 * later display lines of each text line. */
    Tk_3DBorder lMarginColor;	/* Color of left margins (1 and 2). */
    int offset;			/* Offset in pixels of baseline, relative to
				 * baseline of line. */
    int overstrike;		/* Non-zero means draw overstrike through
				 * text. */
    XColor *overstrikeColor;	/* Foreground color for overstrike through
                                 * text. */
    int rMargin;		/* Right margin, in pixels. */
    Tk_3DBorder rMarginColor;	/* Color of right margin. */
    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). */
    int tabStyle;		/* One of TABULAR or WORDPROCESSOR. */
    int underline;		/* Non-zero means draw underline underneath
				 * text. */
    XColor *underlineColor;	/* Foreground color for underline underneath
                                 * 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.*/
} 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.
 */

typedef struct TextStyle {
    TkSizeT refCount;		/* Number of times this structure is
				 * referenced in Chunks. */
    GC bgGC;			/* Graphics context for background. None means
				 * use widget background. */
    GC fgGC;			/* Graphics context for foreground. */
    GC ulGC;			/* Graphics context for underline. */
    GC ovGC;			/* Graphics context for overstrike. */
    StyleValues *sValuePtr;	/* Raw information from which GCs were
				 * derived. */
    Tcl_HashEntry *hPtr;	/* Pointer to entry in styleTable. Used to
				 * delete entry. */
} TextStyle;

/*







<




<
<

<








<
<













|




<
<







132
133
134
135
136
137
138

139
140
141
142


143

144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169


170
171
172
173
174
175
176
    Pixmap fgStipple;		/* Stipple bitmap for text and other
				 * 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. */
    int lMargin2;		/* Left margin, in pixels, for second and
				 * later display lines of each text line. */

    int offset;			/* Offset in pixels of baseline, relative to
				 * baseline of line. */
    int overstrike;		/* Non-zero means draw overstrike through
				 * text. */


    int rMargin;		/* Right margin, in pixels. */

    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). */
    int tabStyle;		/* One of TABULAR or WORDPROCESSOR. */
    int underline;		/* Non-zero means draw underline underneath
				 * 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.*/
} 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.
 */

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 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. */
} TextStyle;

/*
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 * precision is different (e.g. Intel)
 */

#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \
    (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)

/*
 * Macros to make debugging/testing logging a little easier.
 *
 * On OSX 10.14 Drawing procedures are sometimes run because the system has
 * decided to redraw the window.  This can corrupt the data that a test is
 * trying to collect.  So we don't write to the logging variables when the
 * drawing procedure is being run that way.  Other systems can always log.
 */

#define LOG(toVar,what)							\
    if (OK_TO_LOG)							\
        Tcl_SetVar2(textPtr->interp, toVar, NULL, (what),		\
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)
#define CLEAR(var)							\
    if (OK_TO_LOG)							\
	Tcl_SetVar2(interp, var, NULL, "", TCL_GLOBAL_ONLY)

/*
 * 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 {







|
<
<
<
<
<


|
<
|
|
<
<
<







191
192
193
194
195
196
197
198





199
200
201

202
203



204
205
206
207
208
209
210
 * precision is different (e.g. Intel)
 */

#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \
    (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)

/*
 * 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 {
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
				 * 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 spaceBelow;		/* How much extra space was added to the
				 * bottom of the line because of spacing
				 * options. This is included in height. */
    Tk_3DBorder lMarginColor;	/* Background color of the area corresponding
				 * to the left margin of the display line. */
    int lMarginWidth;           /* Pixel width of the area corresponding to
                                 * the left margin. */
    Tk_3DBorder rMarginColor;	/* Background color of the area corresponding
				 * to the right margin of the display line. */
    int rMarginWidth;           /* Pixel width of the area corresponding to
                                 * the right margin. */
    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







<
<
<
<
<
<
<
<







230
231
232
233
234
235
236








237
238
239
240
241
242
243
				 * 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 spaceBelow;		/* How much extra space was added to the
				 * bottom of the line because of spacing
				 * 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
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
				 * 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...*/
    TkSizeT 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







|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
				 * 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
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
} TextDInfo;

/*
 * In TkTextDispChunk structures for character segments, the clientData field
 * points to one of the following structures:
 */

#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)

typedef struct CharInfo {
    int numBytes;		/* Number of bytes to display. */
    char chars[TKFLEXARRAY];		/* UTF characters to display.
				 * Allocated as large as necessary. THIS MUST BE THE LAST
				 * FIELD IN THE STRUCTURE. */
} CharInfo;

#else /* TK_LAYOUT_WITH_BASE_CHUNKS */

typedef struct CharInfo {
    TkTextDispChunk *baseChunkPtr;







|



|
|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
} TextDInfo;

/*
 * 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. */
} CharInfo;

#else /* TK_LAYOUT_WITH_BASE_CHUNKS */

typedef struct CharInfo {
    TkTextDispChunk *baseChunkPtr;
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    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;

/* TODO: Thread safety */
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.
 * 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.
 * OUT_OF_SYNC                  1 means that the last <<WidgetViewSync>> event had
 *                              value 0, indicating that the widget is out of sync.
 */

#define DINFO_OUT_OF_DATE	1
#define REDRAW_PENDING		2
#define REDRAW_BORDERS		4
#define REPICK_NEEDED		8
#define OUT_OF_SYNC             16
/*
 * 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







<



















<
<






|







443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468


469
470
471
472
473
474
475
476
477
478
479
480
481
482
    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.
 * 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.


 */

#define DINFO_OUT_OF_DATE	1
#define REDRAW_PENDING		2
#define REDRAW_BORDERS		4
#define REPICK_NEEDED		8

/*
 * 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
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
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);
#ifdef 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







|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
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
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
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(TkText *textPtr, 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		GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync);
static void		AsyncUpdateYScrollbar(ClientData clientData);
static int              IsStartOfNotMergedLine(TkText *textPtr,
                            const TkTextIndex *indexPtr);

/*
 * Result values returned by TextGetScrollInfoObj:
 */

#define TKTEXT_SCROLL_MOVETO	1
#define TKTEXT_SCROLL_PAGES	2







|



|






|
|



|









|
|







|







|


<


|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
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(TkText *textPtr, 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);
static int              IsStartOfNotMergedLine(TkText *textPtr,
                            CONST TkTextIndex *indexPtr);

/*
 * Result values returned by TextGetScrollInfoObj:
 */

#define TKTEXT_SCROLL_MOVETO	1
#define TKTEXT_SCROLL_PAGES	2
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
 *----------------------------------------------------------------------
 */

void
TkTextCreateDInfo(
    TkText *textPtr)		/* Overall information for text widget. */
{
    TextDInfo *dInfoPtr;
    XGCValues gcValues;

    dInfoPtr = (TextDInfo *)ckalloc(sizeof(TextDInfo));
    Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int));
    dInfoPtr->dLinePtr = NULL;
    dInfoPtr->copyGC = NULL;
    gcValues.graphics_exposures = True;
    dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures,
	    &gcValues);
    dInfoPtr->topOfEof = 0;
    dInfoPtr->newXPixelOffset = 0;
    dInfoPtr->curXPixelOffset = 0;
    dInfoPtr->maxLength = 0;
    dInfoPtr->xScrollFirst = -1;
    dInfoPtr->xScrollLast = -1;
    dInfoPtr->yScrollFirst = -1;
    dInfoPtr->yScrollLast = -1;
    dInfoPtr->scanMarkXPixel = 0;
    dInfoPtr->scanMarkX = 0;
    dInfoPtr->scanTotalYScroll = 0;
    dInfoPtr->scanMarkY = 0;
    dInfoPtr->dLinesInvalidated = 0;
    dInfoPtr->flags = 0;
    dInfoPtr->topPixelOffset = 0;
    dInfoPtr->newTopPixelOffset = 0;
    dInfoPtr->currentMetricUpdateLine = -1;
    dInfoPtr->lastMetricUpdateLine = -1;
    dInfoPtr->lineMetricUpdateEpoch = 1;
    dInfoPtr->metricEpoch = -1;
    dInfoPtr->metricIndex.textPtr = NULL;







|


|



















|







622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
 *----------------------------------------------------------------------
 */

void
TkTextCreateDInfo(
    TkText *textPtr)		/* Overall information for text widget. */
{
    register TextDInfo *dInfoPtr;
    XGCValues gcValues;

    dInfoPtr = (TextDInfo *) ckalloc(sizeof(TextDInfo));
    Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int));
    dInfoPtr->dLinePtr = NULL;
    dInfoPtr->copyGC = NULL;
    gcValues.graphics_exposures = True;
    dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures,
	    &gcValues);
    dInfoPtr->topOfEof = 0;
    dInfoPtr->newXPixelOffset = 0;
    dInfoPtr->curXPixelOffset = 0;
    dInfoPtr->maxLength = 0;
    dInfoPtr->xScrollFirst = -1;
    dInfoPtr->xScrollLast = -1;
    dInfoPtr->yScrollFirst = -1;
    dInfoPtr->yScrollLast = -1;
    dInfoPtr->scanMarkXPixel = 0;
    dInfoPtr->scanMarkX = 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;
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
 *----------------------------------------------------------------------
 */

void
TkTextFreeDInfo(
    TkText *textPtr)		/* Overall information for text widget. */
{
    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.
     */

    FreeDLines(textPtr, dInfoPtr->dLinePtr, NULL, DLINE_UNLINK);
    Tcl_DeleteHashTable(&dInfoPtr->styleTable);
    if (dInfoPtr->copyGC != NULL) {
	Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
    }
    Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC);
    if (dInfoPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(DisplayText, 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(dInfoPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GetStyle --
 *







|















|











|







681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
 *----------------------------------------------------------------------
 */

void
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.
     */

    FreeDLines(textPtr, dInfoPtr->dLinePtr, NULL, DLINE_UNLINK);
    Tcl_DeleteHashTable(&dInfoPtr->styleTable);
    if (dInfoPtr->copyGC != NULL) {
	Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
    }
    Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC);
    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);
}

/*
 *----------------------------------------------------------------------
 *
 * GetStyle --
 *
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
 *
 *----------------------------------------------------------------------
 */

static TextStyle *
GetStyle(
    TkText *textPtr,		/* Overall information about text widget. */
    const TkTextIndex *indexPtr)/* The character in the text for which display
				 * information is wanted. */
{
    TkTextTag **tagPtrs;
    TkTextTag *tagPtr;
    StyleValues styleValues;
    TextStyle *stylePtr;
    Tcl_HashEntry *hPtr;
    int numTags, isNew, i;
    int isSelected;
    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 lMarginColorPrio, rMarginColorPrio;
    int spacing1Prio, spacing2Prio, spacing3Prio;
    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).
     */

    tagPtrs = TkBTreeGetTags(indexPtr, textPtr, &numTags);
    borderPrio = borderWidthPrio = reliefPrio = bgStipplePrio = -1;
    fgPrio = fontPrio = fgStipplePrio = -1;
    underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
    lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
    lMarginColorPrio = rMarginColorPrio = -1;
    spacing1Prio = spacing2Prio = spacing3Prio = -1;
    overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1;
    memset(&styleValues, 0, sizeof(StyleValues));
    styleValues.relief = TK_RELIEF_FLAT;
    styleValues.fgColor = textPtr->fgColor;
    styleValues.underlineColor = textPtr->fgColor;
    styleValues.overstrikeColor = textPtr->fgColor;
    styleValues.tkfont = textPtr->tkfont;
    styleValues.justify = TK_JUSTIFY_LEFT;
    styleValues.spacing1 = textPtr->spacing1;
    styleValues.spacing2 = textPtr->spacing2;
    styleValues.spacing3 = textPtr->spacing3;
    styleValues.tabArrayPtr = textPtr->tabArrayPtr;
    styleValues.tabStyle = textPtr->tabStyle;
    styleValues.wrapMode = textPtr->wrapMode;
    styleValues.elide = 0;
    isSelected = 0;

    for (i = 0 ; i < numTags; i++) {
        if (textPtr->selTagPtr == tagPtrs[i]) {
            isSelected = 1;
            break;
        }
    }

    for (i = 0 ; i < numTags; i++) {
	Tk_3DBorder border;
        XColor *fgColor;

	tagPtr = tagPtrs[i];
	border = tagPtr->border;
        fgColor = tagPtr->fgColor;

	/*
	 * 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 ((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
	    ) {
		continue;
	    }
	    border = textPtr->inactiveSelBorder;
	}

        if ((tagPtr->selBorder != NULL) && (isSelected)) {
            border = tagPtr->selBorder;
        }

        if ((tagPtr->selFgColor != NULL) && isSelected) {
            fgColor = tagPtr->selFgColor;
        }

	if ((border != NULL) && (tagPtr->priority > borderPrio)) {
	    styleValues.border = border;
	    borderPrio = tagPtr->priority;
	}
	if ((tagPtr->borderWidthPtr != NULL)
		&& (Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0')
		&& (tagPtr->priority > borderWidthPrio)) {







|



|




<










<














<





<
<









<
<
<
<
<
<
<
<



<



<



















<
<
<
<
<
<
<
<







733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777


778
779
780
781
782
783
784
785
786








787
788
789

790
791
792

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811








812
813
814
815
816
817
818
 *
 *----------------------------------------------------------------------
 */

static TextStyle *
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, 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, 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).
     */

    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 = tabStylePrio = wrapPrio = -1;
    memset(&styleValues, 0, sizeof(StyleValues));
    styleValues.relief = TK_RELIEF_FLAT;
    styleValues.fgColor = textPtr->fgColor;


    styleValues.tkfont = textPtr->tkfont;
    styleValues.justify = TK_JUSTIFY_LEFT;
    styleValues.spacing1 = textPtr->spacing1;
    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;


	/*
	 * 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 ((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
	    ) {
		continue;
	    }
	    border = textPtr->inactiveSelBorder;
	}









	if ((border != NULL) && (tagPtr->priority > borderPrio)) {
	    styleValues.border = border;
	    borderPrio = tagPtr->priority;
	}
	if ((tagPtr->borderWidthPtr != NULL)
		&& (Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0')
		&& (tagPtr->priority > borderWidthPrio)) {
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
	    reliefPrio = tagPtr->priority;
	}
	if ((tagPtr->bgStipple != None)
		&& (tagPtr->priority > bgStipplePrio)) {
	    styleValues.bgStipple = tagPtr->bgStipple;
	    bgStipplePrio = tagPtr->priority;
	}
	if ((fgColor != NULL) && (tagPtr->priority > fgPrio)) {
	    styleValues.fgColor = fgColor;
	    fgPrio = tagPtr->priority;
	}
	if ((tagPtr->tkfont != NULL) && (tagPtr->priority > fontPrio)) {
	    styleValues.tkfont = tagPtr->tkfont;
	    fontPrio = tagPtr->priority;
	}
	if ((tagPtr->fgStipple != None)







|
|







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
	    reliefPrio = tagPtr->priority;
	}
	if ((tagPtr->bgStipple != None)
		&& (tagPtr->priority > bgStipplePrio)) {
	    styleValues.bgStipple = tagPtr->bgStipple;
	    bgStipplePrio = tagPtr->priority;
	}
	if ((tagPtr->fgColor != NULL) && (tagPtr->priority > fgPrio)) {
	    styleValues.fgColor = tagPtr->fgColor;
	    fgPrio = tagPtr->priority;
	}
	if ((tagPtr->tkfont != NULL) && (tagPtr->priority > fontPrio)) {
	    styleValues.tkfont = tagPtr->tkfont;
	    fontPrio = tagPtr->priority;
	}
	if ((tagPtr->fgStipple != None)
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
	    lMargin1Prio = tagPtr->priority;
	}
	if ((tagPtr->lMargin2String != NULL)
		&& (tagPtr->priority > lMargin2Prio)) {
	    styleValues.lMargin2 = tagPtr->lMargin2;
	    lMargin2Prio = tagPtr->priority;
	}
	if ((tagPtr->lMarginColor != NULL)
		&& (tagPtr->priority > lMarginColorPrio)) {
	    styleValues.lMarginColor = tagPtr->lMarginColor;
	    lMarginColorPrio = tagPtr->priority;
	}
	if ((tagPtr->offsetString != NULL)
		&& (tagPtr->priority > offsetPrio)) {
	    styleValues.offset = tagPtr->offset;
	    offsetPrio = tagPtr->priority;
	}
	if ((tagPtr->overstrikeString != NULL)
		&& (tagPtr->priority > overstrikePrio)) {
	    styleValues.overstrike = tagPtr->overstrike;
	    overstrikePrio = tagPtr->priority;
            if (tagPtr->overstrikeColor != NULL) {
                 styleValues.overstrikeColor = tagPtr->overstrikeColor;
            } else if (fgColor != NULL) {
                 styleValues.overstrikeColor = fgColor;
            }
	}
	if ((tagPtr->rMarginString != NULL)
		&& (tagPtr->priority > rMarginPrio)) {
	    styleValues.rMargin = tagPtr->rMargin;
	    rMarginPrio = tagPtr->priority;
	}
	if ((tagPtr->rMarginColor != NULL)
		&& (tagPtr->priority > rMarginColorPrio)) {
	    styleValues.rMarginColor = tagPtr->rMarginColor;
	    rMarginColorPrio = tagPtr->priority;
	}
	if ((tagPtr->spacing1String != NULL)
		&& (tagPtr->priority > spacing1Prio)) {
	    styleValues.spacing1 = tagPtr->spacing1;
	    spacing1Prio = tagPtr->priority;
	}
	if ((tagPtr->spacing2String != NULL)
		&& (tagPtr->priority > spacing2Prio)) {







<
<
<
<
<









<
<
<
<
<






<
<
<
<
<







856
857
858
859
860
861
862





863
864
865
866
867
868
869
870
871





872
873
874
875
876
877





878
879
880
881
882
883
884
	    lMargin1Prio = tagPtr->priority;
	}
	if ((tagPtr->lMargin2String != NULL)
		&& (tagPtr->priority > lMargin2Prio)) {
	    styleValues.lMargin2 = tagPtr->lMargin2;
	    lMargin2Prio = tagPtr->priority;
	}





	if ((tagPtr->offsetString != NULL)
		&& (tagPtr->priority > offsetPrio)) {
	    styleValues.offset = tagPtr->offset;
	    offsetPrio = tagPtr->priority;
	}
	if ((tagPtr->overstrikeString != NULL)
		&& (tagPtr->priority > overstrikePrio)) {
	    styleValues.overstrike = tagPtr->overstrike;
	    overstrikePrio = tagPtr->priority;





	}
	if ((tagPtr->rMarginString != NULL)
		&& (tagPtr->priority > rMarginPrio)) {
	    styleValues.rMargin = tagPtr->rMargin;
	    rMarginPrio = tagPtr->priority;
	}





	if ((tagPtr->spacing1String != NULL)
		&& (tagPtr->priority > spacing1Prio)) {
	    styleValues.spacing1 = tagPtr->spacing1;
	    spacing1Prio = tagPtr->priority;
	}
	if ((tagPtr->spacing2String != NULL)
		&& (tagPtr->priority > spacing2Prio)) {
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
	    styleValues.tabStyle = tagPtr->tabStyle;
	    tabStylePrio = tagPtr->priority;
	}
	if ((tagPtr->underlineString != NULL)
		&& (tagPtr->priority > underlinePrio)) {
	    styleValues.underline = tagPtr->underline;
	    underlinePrio = tagPtr->priority;
            if (tagPtr->underlineColor != NULL) {
                 styleValues.underlineColor = tagPtr->underlineColor;
            } else if (fgColor != NULL) {
                 styleValues.underlineColor = fgColor;
            }
	}
	if ((tagPtr->elideString != NULL)
		&& (tagPtr->priority > elidePrio)) {
	    styleValues.elide = tagPtr->elide;
	    elidePrio = tagPtr->priority;
	}
	if ((tagPtr->wrapMode != TEXT_WRAPMODE_NULL)
		&& (tagPtr->priority > wrapPrio)) {
	    styleValues.wrapMode = tagPtr->wrapMode;
	    wrapPrio = tagPtr->priority;
	}
    }
    if (tagPtrs != NULL) {
	ckfree(tagPtrs);
    }

    /*
     * Use an existing style if there's one around that matches.
     */

    hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable,
	    (char *) &styleValues, &isNew);
    if (!isNew) {
	stylePtr = (TextStyle *)Tcl_GetHashValue(hPtr);
	stylePtr->refCount++;
	return stylePtr;
    }

    /*
     * No existing style matched. Make a new one.
     */

    stylePtr = (TextStyle *)ckalloc(sizeof(TextStyle));
    stylePtr->refCount = 1;
    if (styleValues.border != NULL) {
	gcValues.foreground = Tk_3DBorderColor(styleValues.border)->pixel;
	mask = GCForeground;
	if (styleValues.bgStipple != None) {
	    gcValues.stipple = styleValues.bgStipple;
	    gcValues.fill_style = FillStippled;







<
<
<
<
<













|









|








|







900
901
902
903
904
905
906





907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
	    styleValues.tabStyle = tagPtr->tabStyle;
	    tabStylePrio = tagPtr->priority;
	}
	if ((tagPtr->underlineString != NULL)
		&& (tagPtr->priority > underlinePrio)) {
	    styleValues.underline = tagPtr->underline;
	    underlinePrio = tagPtr->priority;





	}
	if ((tagPtr->elideString != NULL)
		&& (tagPtr->priority > elidePrio)) {
	    styleValues.elide = tagPtr->elide;
	    elidePrio = tagPtr->priority;
	}
	if ((tagPtr->wrapMode != TEXT_WRAPMODE_NULL)
		&& (tagPtr->priority > wrapPrio)) {
	    styleValues.wrapMode = tagPtr->wrapMode;
	    wrapPrio = tagPtr->priority;
	}
    }
    if (tagPtrs != NULL) {
	ckfree((char *) tagPtrs);
    }

    /*
     * Use an existing style if there's one around that matches.
     */

    hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable,
	    (char *) &styleValues, &isNew);
    if (!isNew) {
	stylePtr = (TextStyle *) Tcl_GetHashValue(hPtr);
	stylePtr->refCount++;
	return stylePtr;
    }

    /*
     * No existing style matched. Make a new one.
     */

    stylePtr = (TextStyle *) ckalloc(sizeof(TextStyle));
    stylePtr->refCount = 1;
    if (styleValues.border != NULL) {
	gcValues.foreground = Tk_3DBorderColor(styleValues.border)->pixel;
	mask = GCForeground;
	if (styleValues.bgStipple != None) {
	    gcValues.stipple = styleValues.bgStipple;
	    gcValues.fill_style = FillStippled;
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
    gcValues.foreground = styleValues.fgColor->pixel;
    if (styleValues.fgStipple != None) {
	gcValues.stipple = styleValues.fgStipple;
	gcValues.fill_style = FillStippled;
	mask |= GCStipple|GCFillStyle;
    }
    stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
    mask = GCForeground;
    gcValues.foreground = styleValues.underlineColor->pixel;
    stylePtr->ulGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
    gcValues.foreground = styleValues.overstrikeColor->pixel;
    stylePtr->ovGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
    stylePtr->sValuePtr = (StyleValues *)
	    Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr);
    stylePtr->hPtr = hPtr;
    Tcl_SetHashValue(hPtr, stylePtr);
    return stylePtr;
}








<
<
<
<
<







956
957
958
959
960
961
962





963
964
965
966
967
968
969
    gcValues.foreground = styleValues.fgColor->pixel;
    if (styleValues.fgStipple != None) {
	gcValues.stipple = styleValues.fgStipple;
	gcValues.fill_style = FillStippled;
	mask |= GCStipple|GCFillStyle;
    }
    stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);





    stylePtr->sValuePtr = (StyleValues *)
	    Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr);
    stylePtr->hPtr = hPtr;
    Tcl_SetHashValue(hPtr, stylePtr);
    return stylePtr;
}

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
 *
 *----------------------------------------------------------------------
 */

static void
FreeStyle(
    TkText *textPtr,		/* Information about overall widget. */
    TextStyle *stylePtr)
				/* Information about style to free. */
{

    if (stylePtr->refCount-- <= 1) {
	if (stylePtr->bgGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->bgGC);
	}
	if (stylePtr->fgGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->fgGC);
	}
	if (stylePtr->ulGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->ulGC);
	}
	if (stylePtr->ovGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->ovGC);
	}
	Tcl_DeleteHashEntry(stylePtr->hPtr);
	ckfree(stylePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * LayoutDLine --







|


>
|






<
<
<
<
<
<

|







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002






1003
1004
1005
1006
1007
1008
1009
1010
1011
 *
 *----------------------------------------------------------------------
 */

static void
FreeStyle(
    TkText *textPtr,		/* Information about overall widget. */
    register TextStyle *stylePtr)
				/* Information about style to free. */
{
    stylePtr->refCount--;
    if (stylePtr->refCount == 0) {
	if (stylePtr->bgGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->bgGC);
	}
	if (stylePtr->fgGC != NULL) {
	    Tk_FreeGC(textPtr->display, stylePtr->fgGC);
	}






	Tcl_DeleteHashEntry(stylePtr->hPtr);
	ckfree((char *) stylePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * LayoutDLine --
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
 *
 *----------------------------------------------------------------------
 */

static DLine *
LayoutDLine(
    TkText *textPtr,		/* Overall information about text widget. */
    const TkTextIndex *indexPtr)/* Beginning of display line. May not
				 * necessarily point to a character
				 * segment. */
{
    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







|



|







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
 *
 *----------------------------------------------------------------------
 */

static DLine *
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. */
    TkTextIndex curIndex;
    TkTextDispChunk *breakChunkPtr;
				/* Chunk containing best word break point, if
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
    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. */
    TkSizeT byteOffset;
    int ascent, descent, code, elide, elidesize;
    StyleValues *sValuePtr;
    TkTextElideInfo info;	/* Keep track of elide state. */

    /*
     * Create and initialize a new DLine structure.
     */

    dlPtr = (DLine *)ckalloc(sizeof(DLine));
    dlPtr->index = *indexPtr;
    dlPtr->byteCount = 0;
    dlPtr->y = 0;
    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 | OLD_Y_INVALID;
    dlPtr->logicalLinesMerged = 0;
    dlPtr->lMarginColor = NULL;
    dlPtr->lMarginWidth = 0;
    dlPtr->rMarginColor = NULL;
    dlPtr->rMarginWidth = 0;

    /*
     * 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.
     */

    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 = info.segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
	    if (segPtr->size + 1 > 1) {
		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.
		     */








<
|







|










<
<
<
<

















|







1088
1089
1090
1091
1092
1093
1094

1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113




1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
    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.
     */

    dlPtr = (DLine *) ckalloc(sizeof(DLine));
    dlPtr->index = *indexPtr;
    dlPtr->byteCount = 0;
    dlPtr->y = 0;
    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 | OLD_Y_INVALID;
    dlPtr->logicalLinesMerged = 0;





    /*
     * 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.
     */

    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 = 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.
		     */

1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360



1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
     * TkTextIndexToSeg for this because it won't return a segment with zero
     * size (such as the insertion cursor's mark).
     */

  connectNextLogicalLine:
    byteOffset = curIndex.byteIndex;
    segPtr = curIndex.linePtr->segPtr;
    while ((byteOffset + 1 > 1) && (byteOffset + 1 >= segPtr->size + 1)) {
	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) {
		break;
	    }

	    dlPtr->logicalLinesMerged++;
	    curIndex.byteIndex = 0;
	    curIndex.linePtr = linePtr;
	    segPtr = curIndex.linePtr->segPtr;



	}
    }

    while (segPtr != NULL) {
	/*
	 * 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, coalesce.
	 *
	 * 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*/)) {
	    elidesize = segPtr->size - byteOffset;
	    if (segPtr->size + 1 > byteOffset + 1) {
		curIndex.byteIndex += elidesize;
		lastChunkPtr->numBytes += elidesize;
		breakByteOffset = lastChunkPtr->breakIndex
			= lastChunkPtr->numBytes;

		/*
		 * If have we have a tag toggle, there is a chance that







|










|
<
<
<
|
|
|
|
>
>
>









|











|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263



1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
     * TkTextIndexToSeg for this because it won't return a segment with zero
     * size (such as the insertion cursor's mark).
     */

  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 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*/)) {
	    elidesize = segPtr->size - byteOffset;
	    if (elidesize > 0) {
		curIndex.byteIndex += elidesize;
		lastChunkPtr->numBytes += elidesize;
		breakByteOffset = lastChunkPtr->breakIndex
			= lastChunkPtr->numBytes;

		/*
		 * If have we have a tag toggle, there is a chance that
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
	    }

	    /*
	     * Code no longer needed, now that we allow logical lines to merge
	     * into a single display line.
	     *
	    if (segPtr == NULL && chunkPtr != NULL) {
		ckfree(chunkPtr);
		chunkPtr = NULL;
	    }
	     */

	    continue;
	}

	if (segPtr->typePtr->layoutProc == NULL) {
	    segPtr = segPtr->nextPtr;
	    byteOffset = 0;
	    continue;
	}
	if (chunkPtr == NULL) {
	    chunkPtr = (TkTextDispChunk *)ckalloc(sizeof(TkTextDispChunk));
	    chunkPtr->nextPtr = NULL;
	    chunkPtr->clientData = NULL;
	}
	chunkPtr->stylePtr = GetStyle(textPtr, &curIndex);
	elide = chunkPtr->stylePtr->sValuePtr->elide;

	/*







|













|







1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
	    }

	    /*
	     * 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;
	}

	if (segPtr->typePtr->layoutProc == NULL) {
	    segPtr = segPtr->nextPtr;
	    byteOffset = 0;
	    continue;
	}
	if (chunkPtr == NULL) {
	    chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk));
	    chunkPtr->nextPtr = NULL;
	    chunkPtr->clientData = NULL;
	}
	chunkPtr->stylePtr = GetStyle(textPtr, &curIndex);
	elide = chunkPtr->stylePtr->sValuePtr->elide;

	/*
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
	    } else {
		/*
		 * Beginning of display line.
		 */

		x = chunkPtr->stylePtr->sValuePtr->lMargin2;
	    }
            dlPtr->lMarginWidth = x;
	    if (wrapMode == TEXT_WRAPMODE_NONE) {
		maxX = -1;
	    } else {
		maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x
			- rMargin;
		if (maxX < x) {
		    maxX = x;







<







1381
1382
1383
1384
1385
1386
1387

1388
1389
1390
1391
1392
1393
1394
	    } else {
		/*
		 * Beginning of display line.
		 */

		x = chunkPtr->stylePtr->sValuePtr->lMargin2;
	    }

	    if (wrapMode == TEXT_WRAPMODE_NONE) {
		maxX = -1;
	    } else {
		maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x
			- rMargin;
		if (maxX < x) {
		    maxX = x;
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
			maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
			gotTab = 1;
			break;
		    }
		}
	    }

#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    if (baseCharChunkPtr != NULL) {
		int expectedX =
			((BaseCharInfo *) baseCharChunkPtr->clientData)->width
			+ baseCharChunkPtr->x;

		if ((expectedX != x) || !IsSameFGStyle(
			baseCharChunkPtr->stylePtr, chunkPtr->stylePtr)) {







|







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
			maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
			gotTab = 1;
			break;
		    }
		}
	    }

#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)) {
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
	    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);
	}
	if (code <= 0) {
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    if (code < 0) {
		/*







|







1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
	    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);
	}
	if (code <= 0) {
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    if (code < 0) {
		/*
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578

	    /*
	     * No characters from this segment fit in the window: this means
	     * we're at the end of the display line.
	     */

	    if (chunkPtr != NULL) {
		ckfree(chunkPtr);
	    }
	    break;
	}

	/*
	 * We currently say we have some characters (and therefore something
	 * from which to examine tag values for the first character of the







|







1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487

	    /*
	     * No characters from this segment fit in the window: this means
	     * we're at the end of the display line.
	     */

	    if (chunkPtr != NULL) {
		ckfree((char *) chunkPtr);
	    }
	    break;
	}

	/*
	 * We currently say we have some characters (and therefore something
	 * from which to examine tag values for the first character of the
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
		    goto connectNextLogicalLine;
		}
	    }
	}

	chunkPtr = NULL;
    }
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
    if (noCharsYet) {
	dlPtr->spaceAbove = 0;
	dlPtr->spaceBelow = 0;
	dlPtr->length = 0;








|







1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
		    goto connectNextLogicalLine;
		}
	    }
	}

	chunkPtr = NULL;
    }
#if TK_LAYOUT_WITH_BASE_CHUNKS
    FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
    if (noCharsYet) {
	dlPtr->spaceAbove = 0;
	dlPtr->spaceBelow = 0;
	dlPtr->length = 0;

1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
	    chunkPtr = breakChunkPtr->nextPtr;
	    if (chunkPtr == NULL) {
		break;
	    }
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    breakChunkPtr->nextPtr = chunkPtr->nextPtr;
	    if (chunkPtr->undisplayProc != NULL) {
		chunkPtr->undisplayProc(textPtr, chunkPtr);
	    }
	    ckfree(chunkPtr);
	}
	if (breakByteOffset != breakChunkPtr->numBytes) {
	    if (breakChunkPtr->undisplayProc != NULL) {
		breakChunkPtr->undisplayProc(textPtr, breakChunkPtr);
	    }
	    segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset);
	    segPtr->typePtr->layoutProc(textPtr, &breakIndex, segPtr,
		    byteOffset, maxX, breakByteOffset, 0, wrapMode,
		    breakChunkPtr);
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
	}
	lastChunkPtr = breakChunkPtr;
	wholeLine = 0;
    }








|

|



|


|
|
|
|







1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
	    chunkPtr = breakChunkPtr->nextPtr;
	    if (chunkPtr == NULL) {
		break;
	    }
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    breakChunkPtr->nextPtr = chunkPtr->nextPtr;
	    if (chunkPtr->undisplayProc != NULL) {
		(*chunkPtr->undisplayProc)(textPtr, chunkPtr);
	    }
	    ckfree((char *) chunkPtr);
	}
	if (breakByteOffset != breakChunkPtr->numBytes) {
	    if (breakChunkPtr->undisplayProc != NULL) {
		(*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr);
	    }
	    segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset);
	    (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex,
		    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;
    }

1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
    if (wholeLine) {
	dlPtr->spaceBelow = sValuePtr->spacing3;
    } else {
	dlPtr->spaceBelow = sValuePtr->spacing2/2;
    }
    dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow;
    dlPtr->baseline += dlPtr->spaceAbove;
    dlPtr->lMarginColor = sValuePtr->lMarginColor;
    dlPtr->rMarginColor = sValuePtr->rMarginColor;
    if (wrapMode != TEXT_WRAPMODE_NONE) {
        dlPtr->rMarginWidth = rMargin;
    }

    /*
     * Recompute line length: may have changed because of justification.
     */

    dlPtr->length = lastChunkPtr->x + lastChunkPtr->width;








<
<
<
<
<







1692
1693
1694
1695
1696
1697
1698





1699
1700
1701
1702
1703
1704
1705
    if (wholeLine) {
	dlPtr->spaceBelow = sValuePtr->spacing3;
    } else {
	dlPtr->spaceBelow = sValuePtr->spacing2/2;
    }
    dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow;
    dlPtr->baseline += dlPtr->spaceAbove;






    /*
     * Recompute line length: may have changed because of justification.
     */

    dlPtr->length = lastChunkPtr->x + lastChunkPtr->width;

1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
 *----------------------------------------------------------------------
 */

static void
UpdateDisplayInfo(
    TkText *textPtr)		/* Text widget to update. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    DLine *dlPtr, *prevPtr;
    TkTextIndex index;
    TkTextLine *lastLinePtr;
    int y, maxY, xPixelOffset, maxOffset, lineHeight;

    if (!(dInfoPtr->flags & DINFO_OUT_OF_DATE)) {
	return;
    }







|
|







1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
 *----------------------------------------------------------------------
 */

static void
UpdateDisplayInfo(
    TkText *textPtr)		/* Text widget to update. */
{
    register TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    register DLine *dlPtr, *prevPtr;
    TkTextIndex index;
    TkTextLine *lastLinePtr;
    int y, maxY, xPixelOffset, maxOffset, lineHeight;

    if (!(dInfoPtr->flags & DINFO_OUT_OF_DATE)) {
	return;
    }
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
    lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
	    TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
    dlPtr = dInfoPtr->dLinePtr;
    prevPtr = NULL;
    y = dInfoPtr->y - dInfoPtr->newTopPixelOffset;
    maxY = dInfoPtr->maxY;
    while (1) {
	DLine *newPtr;

	if (index.linePtr == lastLinePtr) {
	    break;
	}

	/*
	 * There are three possibilities right now:







|







1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
    lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
	    TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
    dlPtr = dInfoPtr->dLinePtr;
    prevPtr = NULL;
    y = dInfoPtr->y - dInfoPtr->newTopPixelOffset;
    maxY = dInfoPtr->maxY;
    while (1) {
	register DLine *newPtr;

	if (index.linePtr == lastLinePtr) {
	    break;
	}

	/*
	 * There are three possibilities right now:
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992

	/*
	 * If we switched text lines, delete any DLines left for the old text
	 * line.
	 */

	if (index.linePtr != prevPtr->index.linePtr) {
	    DLine *nextPtr;

	    nextPtr = dlPtr;
	    while ((nextPtr != NULL)
		    && (nextPtr->index.linePtr == prevPtr->index.linePtr)) {
		nextPtr = nextPtr->nextPtr;
	    }
	    if (nextPtr != dlPtr) {







|







1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896

	/*
	 * If we switched text lines, delete any DLines left for the old text
	 * line.
	 */

	if (index.linePtr != prevPtr->index.linePtr) {
	    register DLine *nextPtr;

	    nextPtr = dlPtr;
	    while ((nextPtr != NULL)
		    && (nextPtr->index.linePtr == prevPtr->index.linePtr)) {
		nextPtr = nextPtr->nextPtr;
	    }
	    if (nextPtr != dlPtr) {
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
 *
 *----------------------------------------------------------------------
 */

static void
FreeDLines(
    TkText *textPtr,		/* Information about overall text widget. */
    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. */
{
    TkTextDispChunk *chunkPtr, *nextChunkPtr;
    DLine *nextDLinePtr;

    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 {
	    DLine *prevPtr;

	    for (prevPtr = textPtr->dInfoPtr->dLinePtr;
		    prevPtr->nextPtr != firstPtr; prevPtr = prevPtr->nextPtr) {
		/* Empty loop body. */
	    }
	    prevPtr->nextPtr = lastPtr;
	}
    }
    while (firstPtr != lastPtr) {
	nextDLinePtr = firstPtr->nextPtr;
	for (chunkPtr = firstPtr->chunkPtr; chunkPtr != NULL;
		chunkPtr = nextChunkPtr) {
	    if (chunkPtr->undisplayProc != NULL) {
		chunkPtr->undisplayProc(textPtr, chunkPtr);
	    }
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    nextChunkPtr = chunkPtr->nextPtr;
	    ckfree(chunkPtr);
	}
	ckfree(firstPtr);
	firstPtr = nextDLinePtr;
    }
    if (action != DLINE_FREE_TEMP) {
	textPtr->dInfoPtr->dLinesInvalidated = 1;
    }
}








|












|
|


















|













|



|

|







2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
 *
 *----------------------------------------------------------------------
 */

static void
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 (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. */
	    }
	    prevPtr->nextPtr = lastPtr;
	}
    }
    while (firstPtr != lastPtr) {
	nextDLinePtr = firstPtr->nextPtr;
	for (chunkPtr = firstPtr->chunkPtr; chunkPtr != NULL;
		chunkPtr = nextChunkPtr) {
	    if (chunkPtr->undisplayProc != NULL) {
		(*chunkPtr->undisplayProc)(textPtr, chunkPtr);
	    }
	    FreeStyle(textPtr, chunkPtr->stylePtr);
	    nextChunkPtr = chunkPtr->nextPtr;
	    ckfree((char *) chunkPtr);
	}
	ckfree((char *) firstPtr);
	firstPtr = nextDLinePtr;
    }
    if (action != DLINE_FREE_TEMP) {
	textPtr->dInfoPtr->dLinesInvalidated = 1;
    }
}

2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
 *
 *----------------------------------------------------------------------
 */

static void
DisplayDLine(
    TkText *textPtr,		/* Text widget in which to draw line. */
    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. */
{
    TkTextDispChunk *chunkPtr;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    Display *display;
    int height, y_off;
#ifndef TK_NO_DOUBLE_BUFFERING
    const int y = 0;
#else
    const int y = dlPtr->y;







|






|







2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
 *
 *----------------------------------------------------------------------
 */

static void
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, y_off;
#ifndef TK_NO_DOUBLE_BUFFERING
    const int y = 0;
#else
    const int y = dlPtr->y;
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
     * widget.
     */

    Tk_Fill3DRectangle(textPtr->tkwin, pixmap, textPtr->border, 0, y,
	    Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT);

    /*
     * Second, draw background information for the whole line.
     */

    DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap);

    /*
     * Third, draw the background color of the left and right margins.
     */
    if (dlPtr->lMarginColor != NULL) {
        Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->lMarginColor, 0, y,
                dlPtr->lMarginWidth + dInfoPtr->x - dInfoPtr->curXPixelOffset,
                dlPtr->height, 0, TK_RELIEF_FLAT);
    }
    if (dlPtr->rMarginColor != NULL) {
        Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->rMarginColor,
                dInfoPtr->maxX - dlPtr->rMarginWidth + dInfoPtr->curXPixelOffset,
                y, dlPtr->rMarginWidth, dlPtr->height, 0, TK_RELIEF_FLAT);
    }

    /*
     * 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_TEXT_STATE_NORMAL) {
	for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
		chunkPtr = chunkPtr->nextPtr) {
	    if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
		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);
	    }
	}
    }







|




<
<
<
<
<
<
<
<
<
<
<
<
<
<













|







2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389














2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
     * widget.
     */

    Tk_Fill3DRectangle(textPtr->tkwin, pixmap, textPtr->border, 0, y,
	    Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT);

    /*
     * Next, draw background information for the whole line.
     */

    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.
     */

    if (textPtr->state == TK_TEXT_STATE_NORMAL) {
	for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
		chunkPtr = chunkPtr->nextPtr) {
	    if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
		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);
	    }
	}
    }
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
		 * 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;







|







2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
		 * 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;
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
 *
 *--------------------------------------------------------------
 */

static void
DisplayLineBackground(
    TkText *textPtr,		/* Text widget containing line. */
    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. */
{







|







2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
 *
 *--------------------------------------------------------------
 */

static void
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. */
{
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103

3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
 *----------------------------------------------------------------------
 */

static void
AsyncUpdateLineMetrics(
    ClientData clientData)	/* Information about widget. */
{
    TkText *textPtr = (TkText *)clientData;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int lineNum;

    dInfoPtr->lineUpdateTimer = NULL;

    if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)
            || !Tk_IsMapped(textPtr->tkwin)) {
	/*
	 * The widget has been deleted, or is not mapped. Don't do anything.
	 */

	if (textPtr->refCount-- <= 1) {
	    ckfree(textPtr);
	}
	return;
    }

    if (dInfoPtr->flags & REDRAW_PENDING) {
	dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		AsyncUpdateLineMetrics, clientData);
	return;
    }

    /*
     * Reify where we end or all hell breaks loose with the calculations when
     * we try to update. [Bug 2677890]
     */

    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);

    dInfoPtr->currentMetricUpdateLine = lineNum;

    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 == TCL_INDEX_NONE
	    && 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). If there is a registered aftersync command, run that first.
	 * Cancel any pending idle task which would try to run the command
	 * after the afterSyncCmd pointer had been set to NULL.
	 */

        if (textPtr->afterSyncCmd) {
            int code;
	    Tcl_CancelIdleCall(TkTextRunAfterSyncCmd, textPtr);
            Tcl_Preserve((ClientData) textPtr->interp);
            code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd,
                    TCL_EVAL_GLOBAL);
	    if (code == TCL_ERROR) {
                Tcl_AddErrorInfo(textPtr->interp, "\n    (text sync)");
                Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    }
            Tcl_Release((ClientData) textPtr->interp);
            Tcl_DecrRefCount(textPtr->afterSyncCmd);
            textPtr->afterSyncCmd = NULL;
	}

        /*
         * Fire the <<WidgetViewSync>> event since the widget view is in sync
         * with its internal data (actually it will be after the next trip
         * through the event loop, because the widget redraws at idle-time).
         */
        GenerateWidgetViewSyncEvent(textPtr, 1);

	if (textPtr->refCount-- <= 1) {
	    ckfree(textPtr);
	}
	return;
    }


    /*
     * 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, textPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateWidgetViewSyncEvent --
 *
 *      Send the <<WidgetViewSync>> event related to the text widget
 *      line metrics asynchronous update.  These events should only
 *      be sent when the sync status has changed.  So this function
 *      compares the requested state with the state saved in the
 *      TkText structure, and only generates the event if they are
 *      different.  This means that it is safe to call this function
 *      at any time when the state is known.
 *
 *      If an event is sent, the effect is equivalent to:
 *         event generate $textWidget <<WidgetViewSync>> -data $s
 *      where $s is the sync status: true (when the widget view is in
 *      sync with its internal data) or false (when it is not).
 *
 * Results:
 *      None
 *
 * Side effects:
 *      If corresponding bindings are present, they will trigger.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateWidgetViewSyncEvent(
    TkText *textPtr,	  /* Information about text widget. */
    Bool InSync)          /* true if becoming in sync, false otherwise */
{
    Bool NewSyncState = (InSync != 0); /* ensure 0 or 1 value */
    Bool OldSyncState = !(textPtr->dInfoPtr->flags & OUT_OF_SYNC);

    /*
     * OSX 10.14 needs to be told to display the window when the Text Widget
     * is in sync.  (That is, to run DisplayText inside of the drawRect
     * method.)  Otherwise the screen might not get updated until an event
     * like a mouse click is received.  But that extra drawing corrupts the
     * data that the test suite is trying to collect.
     */

    if (!tkTextDebug) {
	TkpRedrawWidget(textPtr->tkwin);
    }

    if (NewSyncState != OldSyncState) {
	if (NewSyncState) {
	    textPtr->dInfoPtr->flags &= ~OUT_OF_SYNC;
	} else {
	    textPtr->dInfoPtr->flags |= OUT_OF_SYNC;
	}
	Tk_SendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
		Tcl_NewBooleanObj(NewSyncState));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
 *







|











|
|










<
<
<
<
<














<
<












|




|
<
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|



>







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923





2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937


2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955


2956
2957
2958





















2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972


























































2973
2974
2975
2976
2977
2978
2979
 *----------------------------------------------------------------------
 */

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)
            || !Tk_IsMapped(textPtr->tkwin)) {
	/*
	 * The widget has been deleted, or is not mapped. 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 --
 *
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
				 * 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);
    int fullUpdateRequested = (lineNum == 0 &&
                               endLine == totalLines &&
                               doThisMuch == -1);

    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,







<
<
<










<







3008
3009
3010
3011
3012
3013
3014



3015
3016
3017
3018
3019
3020
3021
3022
3023
3024

3025
3026
3027
3028
3029
3030
3031
				 * 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,
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
	    }

	    /*
	     * If we're in the middle of a partial-line height calculation,
	     * then we can't be done.
	     */

	    if (textPtr->dInfoPtr->metricEpoch == TCL_INDEX_NONE && lineNum == endLine) {


		/*
		 * We have looped over all lines, so we're done.
		 */

		break;
	    }
	}







|
<
<







3043
3044
3045
3046
3047
3048
3049
3050


3051
3052
3053
3054
3055
3056
3057
	    }

	    /*
	     * 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;
	    }
	}
3269
3270
3271
3272
3273
3274
3275
3276







3277



































































3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
	    }

	    /*
	     * Now update the line's metrics if necessary.
	     */

	    if (TkBTreeLinePixelEpoch(textPtr, linePtr)
		    == textPtr->dInfoPtr->lineMetricUpdateEpoch) {











































































		/*
		 * This line is already up to date. That means there's nothing
		 * to do here.
		 */

	    } else 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, which must be because
		     * 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;
		}

		/*
		 * We're done with this long line.
		 */

		textPtr->dInfoPtr->metricEpoch = -1;
	    }
	} 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) {







|
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153


3154










































































3155
3156
3157
3158
3159
3160
3161
	    }

	    /*
	     * 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) {
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
	count++;

	if (doThisMuch != -1 && count >= doThisMuch) {
	    break;
	}
    }
    if (doThisMuch == -1) {

	/*
	 * If we were requested to update the entire range, then also update
	 * the scrollbar.
	 */

	GetYView(textPtr->interp, textPtr, 1);
    }
    if (fullUpdateRequested) {
        GenerateWidgetViewSyncEvent(textPtr, 1);
    }
    return lineNum;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextInvalidateLineMetrics, TextInvalidateLineMetrics --







<

|
|




<
<
<







3172
3173
3174
3175
3176
3177
3178

3179
3180
3181
3182
3183
3184
3185



3186
3187
3188
3189
3190
3191
3192
	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 --
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
    /*
     * Now re-set the current update calculations.
     */

    if (dInfoPtr->lineUpdateTimer == NULL) {
	textPtr->refCount++;
	dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		AsyncUpdateLineMetrics, textPtr);
    }

    /*
     * The widget is out of sync: send a <<WidgetViewSync>> event.
     */
    GenerateWidgetViewSyncEvent(textPtr, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFindDisplayLineEnd --
 *







|

<
<
<
<
<







3346
3347
3348
3349
3350
3351
3352
3353
3354





3355
3356
3357
3358
3359
3360
3361
    /*
     * Now re-set the current update calculations.
     */

    if (dInfoPtr->lineUpdateTimer == NULL) {
	textPtr->refCount++;
	dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		AsyncUpdateLineMetrics, (ClientData) textPtr);
    }





}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFindDisplayLineEnd --
 *
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628

3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678

3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693

3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715

3716
3717
3718
3719
3720
3721
3722
    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. */
{
    TkTextIndex index;

    if (!end && IsStartOfNotMergedLine(textPtr, indexPtr)) {
	/*
	 * Nothing to do.
	 */

	if (xOffset != NULL) {
	    *xOffset = 0;
	}
	return;
    }


    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,
			TkTextIndexCountBytes(textPtr, &dlPtr->index,
			indexPtr));
	    }
	    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 --







<
<









|
>

<
|
|

|
|

|
|
|
|

|
|

|
|
|
|
|

|
|

|
|
|
|
|

|
|
|

|
|
|
|

|
|

|

|
|
|
|
|
>
|

|
|
|
|
|
|
|

|
|
|
|
|
>
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
<
|
|
>







3396
3397
3398
3399
3400
3401
3402


3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414

3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
    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 && IsStartOfNotMergedLine(textPtr, indexPtr)) {
	/*
	 * 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,
                            TkTextIndexCountBytes(textPtr, &dlPtr->index,
                            indexPtr));
		}
		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 --
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
 *
 *----------------------------------------------------------------------
 */

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). */
{







|







3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
 *
 *----------------------------------------------------------------------
 */

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). */
{
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
 *
 *----------------------------------------------------------------------
 */

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;
    int alreadyStartOfLine = 1;








|







3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
 *
 *----------------------------------------------------------------------
 */

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;
    int alreadyStartOfLine = 1;

4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149

	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, textPtr);
    }
    return displayLines;
}

/*
 *----------------------------------------------------------------------
 *







|







3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935

	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;
}

/*
 *----------------------------------------------------------------------
 *
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177












4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
 *----------------------------------------------------------------------
 */

static void
DisplayText(
    ClientData clientData)	/* Information about widget. */
{
    TkText *textPtr = (TkText *)clientData;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    DLine *dlPtr;
    DLine *prevPtr;
    Pixmap pixmap;
    int maxHeight, borders;
    int bottomY = 0;		/* Initialization needed only to stop compiler
				 * warnings. */
    Tcl_Interp *interp;














    if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	/*
	 * The widget has been deleted.	 Don't do anything.
	 */

	return;
    }

#ifdef MAC_OSX_TK
    /*
     * If the toplevel is being resized it would be dangerous to try redrawing
     * the widget.  But we can just clear the REDRAW_PENDING flag and return.
     * This display proc will be called again after the widget has been
     * reconfigured.
     */

    TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
    MacDrawable *macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
	dInfoPtr->flags &= ~REDRAW_PENDING;
    	return;
     }
#endif

    interp = textPtr->interp;
    Tcl_Preserve(interp);

    if (tkTextDebug) {
	CLEAR("tk_textRelayout");
    }

    if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
	    || (dInfoPtr->maxY <= dInfoPtr->y)) {
	UpdateDisplayInfo(textPtr);
	dInfoPtr->flags &= ~REDRAW_PENDING;
	goto doScrollbars;
    }
    numRedisplays++;
    if (tkTextDebug) {
	CLEAR("tk_textRedraw");
    }

    /*
     * 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) {
	textPtr->refCount++;
	dInfoPtr->flags &= ~REPICK_NEEDED;
	TkTextPickCurrent(textPtr, &textPtr->pickEvent);
	if (textPtr->refCount-- <= 1) {
	    ckfree(textPtr);
	    goto end;
	}
	if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	    goto end;
	}
    }








|

|







>
>
>
>
>
>
>
>
>
>
>
>









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|


|










|














|
|







3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
















3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
 *----------------------------------------------------------------------
 */

static void
DisplayText(
    ClientData clientData)	/* Information about widget. */
{
    register TkText *textPtr = (TkText *) clientData;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    register DLine *dlPtr;
    DLine *prevPtr;
    Pixmap pixmap;
    int maxHeight, borders;
    int bottomY = 0;		/* Initialization needed only to stop compiler
				 * warnings. */
    Tcl_Interp *interp;

#ifdef MAC_OSX_TK
    /*
     * If drawing is disabled, all we need to do is
     * clear the REDRAW_PENDING flag.
     */
    TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
    MacDrawable *macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
      dInfoPtr->flags &= ~REDRAW_PENDING;
      return;
    }
#endif

    if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	/*
	 * The widget has been deleted.	 Don't do anything.
	 */

	return;
    }

















    interp = textPtr->interp;
    Tcl_Preserve((ClientData) interp);

    if (tkTextDebug) {
	Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
    }

    if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
	    || (dInfoPtr->maxY <= dInfoPtr->y)) {
	UpdateDisplayInfo(textPtr);
	dInfoPtr->flags &= ~REDRAW_PENDING;
	goto doScrollbars;
    }
    numRedisplays++;
    if (tkTextDebug) {
	Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY);
    }

    /*
     * 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) {
	textPtr->refCount++;
	dInfoPtr->flags &= ~REPICK_NEEDED;
	TkTextPickCurrent(textPtr, &textPtr->pickEvent);
	if (--textPtr->refCount == 0) {
	    ckfree((char *) textPtr);
	    goto end;
	}
	if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	    goto end;
	}
    }

4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
     * 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) {
	DLine *dlPtr2;
	int offset, height, y, oldY;
	TkRegion damageRgn;

	/*
	 * These tests are, in order:
	 *
	 * 1. If the line is already marked as invalid







|







4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
     * 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) {
	register DLine *dlPtr2;
	int offset, height, y, oldY;
	TkRegion damageRgn;

	/*
	 * These tests are, in order:
	 *
	 * 1. If the line is already marked as invalid
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321

	/*
	 * 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).
	     */







|







4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103

	/*
	 * 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).
	     */
4338
4339
4340
4341
4342
4343
4344

4345
4346
4347
4348
4349
4350
4351

	    dlPtr->oldY = dlPtr->y;
	    if (dlPtr->nextPtr == dlPtr2) {
		break;
	    }
	    dlPtr = dlPtr->nextPtr;
	}

	/*
	 * 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) {







>







4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134

	    dlPtr->oldY = dlPtr->y;
	    if (dlPtr->nextPtr == dlPtr2) {
		break;
	    }
	    dlPtr = dlPtr->nextPtr;
	}

	/*
	 * 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) {
4362
4363
4364
4365
4366
4367
4368

4369
4370
4371
4372
4373
4374
4375
	 */

	damageRgn = TkCreateRegion();
	if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
		oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
		damageRgn)) {
	    TextInvalidateRegion(textPtr, damageRgn);

	}
	numCopies++;
	TkDestroyRegion(damageRgn);
    }

    /*
     * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We







>







4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
	 */

	damageRgn = TkCreateRegion();
	if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
		oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
		damageRgn)) {
	    TextInvalidateRegion(textPtr, damageRgn);

	}
	numCopies++;
	TkDestroyRegion(damageRgn);
    }

    /*
     * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540

4541

4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
#ifndef TK_NO_DOUBLE_BUFFERING
		    Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
		    return;
		}
		dlPtr->oldY = dlPtr->y;
		dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID);
#ifdef MAC_OSX_TK
	    } else if (dlPtr->chunkPtr != NULL) {
		/*
		 * On macOS we need to redisplay all embedded windows which
		 * were moved by the call to TkScrollWindows above.  This is
		 * not necessary on Unix or Windows because XScrollWindow will
		 * have included the bounding rectangles of all of these
		 * windows in the damage region.  The macosx implementation of
		 * TkScrollWindow does not do this.  It simply generates a
		 * damage region which is the scroll source rectangle minus
		 * the scroll destination rectangle.  This is because there is
		 * no efficient process available for iterating through the
		 * subwindows which meet the scrolled area.  (On Unix this is
		 * handled by GraphicsExpose events generated by XCopyArea and
		 * on Windows by ScrollWindowEx.  On macOS the low level
		 * scrolling is accomplished by calling [view scrollRect:by:].
		 * This method does not provide any damage information and, in
		 * any case, could not be aware of Tk windows which were not
		 * based on NSView objects.
		 *
		 * On the other hand, this loop is already iterating through
		 * all embedded windows which could possibly have been moved
		 * by the scrolling.  So it is as efficient to redisplay them
		 * here as it would have been if they had been redisplayed by
		 * the call to TextInvalidateRegion above.
		 */
#else
	    } else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0)
		    || (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) {
		/*
		 * On platforms other than the Mac:

		 *

		 * 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.
		 */
#endif
		TkTextDispChunk *chunkPtr;

		for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
			chunkPtr = chunkPtr->nextPtr) {
		    int x;
		    if (chunkPtr->displayProc != TkTextEmbWinDisplayProc) {
			continue;
		    }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
>
|
>













<
<







4287
4288
4289
4290
4291
4292
4293



























4294
4295


4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311


4312
4313
4314
4315
4316
4317
4318
#ifndef TK_NO_DOUBLE_BUFFERING
		    Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
		    return;
		}
		dlPtr->oldY = dlPtr->y;
		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;
		    }
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590

4591
4592
4593
4594
4595
4596
4597
			 * 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;
		    }
		    if (tkTextDebug) {
			char string[TK_POS_CHARS];

			TkTextPrintIndex(textPtr, &dlPtr->index, string);
			LOG("tk_textEmbWinDisplay", string);
		    }
		    TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
			    dlPtr->spaceAbove,
			    dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
			    dlPtr->baseline - dlPtr->spaceAbove, NULL,
			    None, dlPtr->y + dlPtr->spaceAbove);
		}

	    }
	}
#ifndef TK_NO_DOUBLE_BUFFERING
	Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }








<
<
<
<
<
<






>







4327
4328
4329
4330
4331
4332
4333






4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
			 * 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,
			    None, dlPtr->y + dlPtr->spaceAbove);
		}

	    }
	}
#ifndef TK_NO_DOUBLE_BUFFERING
	Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }

4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666

	if (textPtr->xScrollCmd != NULL) {
	    GetXView(textPtr->interp, textPtr, 1);
	}
    }

  end:
    Tcl_Release(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextEventuallyRepick --
 *







|







4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416

	if (textPtr->xScrollCmd != NULL) {
	    GetXView(textPtr->interp, textPtr, 1);
	}
    }

  end:
    Tcl_Release((ClientData) interp);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextEventuallyRepick --
 *
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
    TkText *textPtr)		/* Widget record for text widget. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;

    dInfoPtr->flags |= REPICK_NEEDED;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextRedrawRegion --







|







4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
    TkText *textPtr)		/* Widget record for text widget. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;

    dInfoPtr->flags |= REPICK_NEEDED;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextRedrawRegion --
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
    rect.height = height;
    TkUnionRectWithRegion(&rect, damageRgn, damageRgn);

    TextInvalidateRegion(textPtr, damageRgn);

    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    TkDestroyRegion(damageRgn);
}

/*
 *----------------------------------------------------------------------
 *







|







4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
    rect.height = height;
    TkUnionRectWithRegion(&rect, damageRgn, damageRgn);

    TextInvalidateRegion(textPtr, damageRgn);

    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    TkDestroyRegion(damageRgn);
}

/*
 *----------------------------------------------------------------------
 *
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
 */

static void
TextInvalidateRegion(
    TkText *textPtr,		/* Widget record for text widget. */
    TkRegion region)		/* Region of area to redraw. */
{
    DLine *dlPtr;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int maxY, inset;
    XRectangle rect;

    /*
     * Find all lines that overlap the given region and mark them for
     * redisplay.







|







4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
 */

static void
TextInvalidateRegion(
    TkText *textPtr,		/* Widget record for text widget. */
    TkRegion region)		/* Region of area to redraw. */
{
    register DLine *dlPtr;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int maxY, inset;
    XRectangle rect;

    /*
     * Find all lines that overlap the given region and mark them for
     * redisplay.
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
 *----------------------------------------------------------------------
 */

void
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;
    TkTextIndex rounded;
    TkTextLine *linePtr;
    int notBegin;







|
|
















|
|







4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
 *----------------------------------------------------------------------
 */

void
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;
    TkTextIndex rounded;
    TkTextLine *linePtr;
    int notBegin;
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
     *	  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)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    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: This is necessary because the indices stored in the display







|







4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
     *	  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)) {
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    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: This is necessary because the indices stored in the display
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
    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. */
{
    DLine *dlPtr;
    DLine *endPtr;
    int tagOn;
    TkTextSearch search;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex *curIndexPtr;
    TkTextIndex endOfText, *endIndexPtr;








|







4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
    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;
    DLine *endPtr;
    int tagOn;
    TkTextSearch search;
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex *curIndexPtr;
    TkTextIndex endOfText, *endIndexPtr;

5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
    /*
     * 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)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    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







|







4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
    /*
     * 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)) {
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    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
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
    TkText *textPtr,		/* Widget record for text widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    GC newGC;
    XGCValues gcValues;
    Bool inSync = 1;

    /*
     * 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)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
	inSync = 0;
    }
    dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
	    |REPICK_NEEDED;

    /*
     * (Re-)create the graphics context for drawing the traversal highlight.
     */







<







|
<







4948
4949
4950
4951
4952
4953
4954

4955
4956
4957
4958
4959
4960
4961
4962

4963
4964
4965
4966
4967
4968
4969
    TkText *textPtr,		/* Widget record for text widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    GC newGC;
    XGCValues gcValues;


    /*
     * 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)) {
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);

    }
    dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
	    |REPICK_NEEDED;

    /*
     * (Re-)create the graphics context for drawing the traversal highlight.
     */
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293

    if (!IsStartOfNotMergedLine(textPtr, &textPtr->topIndex)) {
	TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
    }

    /*
     * Invalidate cached scrollbar positions, so that scrollbars sliders will
     * be updated.
     */

    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.
	 */








|






<







5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033

5034
5035
5036
5037
5038
5039
5040

    if (!IsStartOfNotMergedLine(textPtr, &textPtr->topIndex)) {
	TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
    }

    /*
     * 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.
	 */

5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
	 */

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, textPtr);
	    inSync = 0;
	}

        GenerateWidgetViewSyncEvent(textPtr, inSync);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSetYView --







|
<

<
<







5050
5051
5052
5053
5054
5055
5056
5057

5058


5059
5060
5061
5062
5063
5064
5065
	 */

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, (ClientData) textPtr);

	}


    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSetYView --
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
				 * 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;
    DLine *dlPtr;
    int bottomY, close, lineIndex;
    TkTextIndex tmpIndex, rounded;
    int lineHeight;

    /*
     * If the specified position is the extra line at the end of the text,
     * round it back to the last real line.







|







5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
				 * 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;
    int lineHeight;

    /*
     * If the specified position is the extra line at the end of the text,
     * round it back to the last real line.
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
     */

    MeasureUp(textPtr, indexPtr, bottomY, &textPtr->topIndex,
	    &dInfoPtr->newTopPixelOffset);

  scheduleUpdate:
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}

/*
 *--------------------------------------------------------------
 *







|







5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
     */

    MeasureUp(textPtr, indexPtr, bottomY, &textPtr->topIndex,
	    &dInfoPtr->newTopPixelOffset);

  scheduleUpdate:
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}

/*
 *--------------------------------------------------------------
 *
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
 *
 *--------------------------------------------------------------
 */

static void
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 *overlap)		/* Used to store how much of the final index
				 * returned was not covered by 'distance'. */







|







5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
 *
 *--------------------------------------------------------------
 */

static void
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 *overlap)		/* Used to store how much of the final index
				 * returned was not covered by 'distance'. */
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
 */

int
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
				 * objv[1] is "see". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex index;
    int x, y, width, height, lineWidth, byteCount, oneThird, delta;
    DLine *dlPtr;







|







5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
 */

int
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
				 * objv[1] is "see". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex index;
    int x, y, width, height, lineWidth, byteCount, oneThird, delta;
    DLine *dlPtr;
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822



5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
    /*
     * 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(textPtr, chunkPtr, byteCount,
                dlPtr->y + dlPtr->spaceAbove,
                dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
                dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
                &height);
        delta = x - dInfoPtr->curXPixelOffset;
        oneThird = lineWidth/3;
        if (delta < 0) {
            if (delta < -oneThird) {
                dInfoPtr->newXPixelOffset = x - lineWidth/2;
            } else {
                dInfoPtr->newXPixelOffset += delta;
            }
        } else {
            delta -= lineWidth - width;
            if (delta <= 0) {
                return TCL_OK;
            }
            if (delta > oneThird) {
                dInfoPtr->newXPixelOffset = x - lineWidth/2;
            } else {
                dInfoPtr->newXPixelOffset += delta;



            }
        }
    }
    dInfoPtr->flags |= DINFO_OUT_OF_DATE;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *







|








|

|


|
|
<
<
|
|
|
|
>
>
>






|







5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560


5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
    /*
     * 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)(textPtr, chunkPtr, byteCount,
                dlPtr->y + dlPtr->spaceAbove,
                dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
                dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
                &height);
        delta = x - dInfoPtr->curXPixelOffset;
        oneThird = lineWidth/3;
        if (delta < 0) {
            if (delta < -oneThird) {
                dInfoPtr->newXPixelOffset = (x - lineWidth/2);
            } else {
                dInfoPtr->newXPixelOffset -= ((-delta) );
            }
        } else {
            delta -= (lineWidth - width);
            if (delta > 0) {


                if (delta > oneThird) {
                    dInfoPtr->newXPixelOffset = (x - lineWidth/2);
                } else {
                    dInfoPtr->newXPixelOffset += (delta );
                }
            } else {
                return TCL_OK;
            }
        }
    }
    dInfoPtr->flags |= DINFO_OUT_OF_DATE;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
 */

int
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
				 * objv[1] is "xview". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int type, count;
    double fraction;








|







5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
 */

int
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
				 * objv[1] is "xview". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int type, count;
    double fraction;

5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
	dInfoPtr->newXPixelOffset += count;
	break;
    }

    dInfoPtr->flags |= DINFO_OUT_OF_DATE;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
	dInfoPtr->newXPixelOffset += count;
	break;
    }

    dInfoPtr->flags |= DINFO_OUT_OF_DATE;
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
	/*
	 * offset = 0, so no scrolling required.
	 */

	return;
    }
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}

/*
 *----------------------------------------------------------------------
 *







|







5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
	/*
	 * 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;
}

/*
 *----------------------------------------------------------------------
 *
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
	    }
	    textPtr->topIndex = newIdx;
	}
    }

  scheduleUpdate:
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}

/*
 *--------------------------------------------------------------
 *







|







5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
	    }
	    textPtr->topIndex = newIdx;
	}
    }

  scheduleUpdate:
    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
    }
    dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}

/*
 *--------------------------------------------------------------
 *
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
 */

int
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
				 * objv[1] is "yview". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int pickPlace, type;
    int pixels, count;
    TkSizeT switchLength;
    double fraction;
    TkTextIndex index;

    if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
	UpdateDisplayInfo(textPtr);
    }

    if (objc == 2) {
	GetYView(interp, textPtr, 0);
	return TCL_OK;
    }

    /*
     * Next, handle the old syntax: "pathName yview ?-pickplace? where"
     */

    pickPlace = 0;
    if (Tcl_GetString(objv[2])[0] == '-') {
	const char *switchStr =
		TkGetStringFromObj(objv[2], &switchLength);

	if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace",
		(unsigned) switchLength) == 0)) {
	    pickPlace = 1;
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "lineNum|index");
		return TCL_ERROR;







|






|


















|
|







5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
 */

int
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
				 * objv[1] is "yview". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    int pickPlace, type;
    int pixels, count;
    int switchLength;
    double fraction;
    TkTextIndex index;

    if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
	UpdateDisplayInfo(textPtr);
    }

    if (objc == 2) {
	GetYView(interp, textPtr, 0);
	return TCL_OK;
    }

    /*
     * Next, handle the old syntax: "pathName yview ?-pickplace? where"
     */

    pickPlace = 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 (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "lineNum|index");
		return TCL_ERROR;
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextPendingsync --
 *
 *	This function checks if any line heights are not up-to-date.
 *
 * Results:
 *	Returns a boolean true if it is the case, or false if all line
 *      heights are up-to-date.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

Bool
TkTextPendingsync(
    TkText *textPtr)		/* Information about text widget. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;

    return ((dInfoPtr->flags & OUT_OF_SYNC) != 0);
}

/*
 *--------------------------------------------------------------
 *
 * TkTextScanCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextScanCmd(
    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
				 * objv[1] is "scan". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex index;
    int c, x, y, totalScroll, gain=10;
    size_t length;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















|


|







6057
6058
6059
6060
6061
6062
6063


























6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *


























 * TkTextScanCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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
				 * objv[1] is "scan". */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    TkTextIndex index;
    int c, x, y, totalScroll, gain=10;
    size_t length;
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
		dInfoPtr->scanTotalYScroll = 0;
		dInfoPtr->scanMarkY = y;
	    }
	}
	dInfoPtr->flags |= DINFO_OUT_OF_DATE;
	if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	    dInfoPtr->flags |= REDRAW_PENDING;
	    Tcl_DoWhenIdle(DisplayText, textPtr);
	}
    } else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) {
	dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset;
	dInfoPtr->scanMarkX = x;
	dInfoPtr->scanTotalYScroll = 0;
	dInfoPtr->scanMarkY = y;
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad scan option \"%s\": must be mark or dragto",
		Tcl_GetString(objv[2])));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		Tcl_GetString(objv[2]), NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|







|
|
<
<
<







6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164



6165
6166
6167
6168
6169
6170
6171
		dInfoPtr->scanTotalYScroll = 0;
		dInfoPtr->scanMarkY = y;
	    }
	}
	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->scanTotalYScroll = 0;
	dInfoPtr->scanMarkY = y;
    } else {
	Tcl_AppendResult(interp, "bad scan option \"", Tcl_GetString(objv[2]),
		"\": must be mark or dragto", NULL);



	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
	return;
    }
    dInfoPtr->xScrollFirst = first;
    dInfoPtr->xScrollLast = last;
    if (textPtr->xScrollCmd != NULL) {
	char buf1[TCL_DOUBLE_SPACE+1];
	char buf2[TCL_DOUBLE_SPACE+1];
	Tcl_DString buf;

	buf1[0] = ' ';
	buf2[0] = ' ';
	Tcl_PrintDouble(NULL, first, buf1+1);
	Tcl_PrintDouble(NULL, last, buf2+1);
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, textPtr->xScrollCmd, -1);
	Tcl_DStringAppend(&buf, buf1, -1);
	Tcl_DStringAppend(&buf, buf2, -1);
	code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (horizontal scrolling command executed by text)");
	    Tcl_BackgroundException(interp, code);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *







<





<
|
<
<
<
<



|







6230
6231
6232
6233
6234
6235
6236

6237
6238
6239
6240
6241

6242




6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
	return;
    }
    dInfoPtr->xScrollFirst = first;
    dInfoPtr->xScrollLast = last;
    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);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
6648
6649
6650
6651
6652
6653
6654
6655
6656

6657
6658
6659
6660
6661
6662
6663
		    TkTextPrintIndex(textPtr, &index, string);
		    LOG("tk_textHeightCalc", string);
		}
		count -= dlPtr->height;
		notFirst = 1;
	    }
	    break;
	}
	dlPtr = dlPtr->nextPtr;

    } while (dlPtr->index.linePtr == linePtr);

    return count;
}

/*
 *----------------------------------------------------------------------







|
|
>







6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
		    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;
}

/*
 *----------------------------------------------------------------------
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
    }

    dInfoPtr->yScrollFirst = first;
    dInfoPtr->yScrollLast = last;
    if (textPtr->yScrollCmd != NULL) {
	char buf1[TCL_DOUBLE_SPACE+1];
	char buf2[TCL_DOUBLE_SPACE+1];
	Tcl_DString buf;

	buf1[0] = ' ';
	buf2[0] = ' ';
	Tcl_PrintDouble(NULL, first, buf1+1);
	Tcl_PrintDouble(NULL, last, buf2+1);
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, textPtr->yScrollCmd, -1);
	Tcl_DStringAppend(&buf, buf1, -1);
	Tcl_DStringAppend(&buf, buf2, -1);
	code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (vertical scrolling command executed by text)");
	    Tcl_BackgroundException(interp, code);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *







<





<
|
<
<
<
<



|







6510
6511
6512
6513
6514
6515
6516

6517
6518
6519
6520
6521

6522




6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
    }

    dInfoPtr->yScrollFirst = first;
    dInfoPtr->yScrollLast = last;
    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);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
 *----------------------------------------------------------------------
 */

static void
AsyncUpdateYScrollbar(
    ClientData clientData)	/* Information about widget. */
{
    TkText *textPtr = (TkText *)clientData;

    textPtr->dInfoPtr->scrollbarTimer = NULL;

    if (!(textPtr->flags & DESTROYED)) {
	GetYView(textPtr->interp, textPtr, 1);
    }

    if (textPtr->refCount-- <= 1) {
	ckfree(textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FindDLine --







|







|
|







6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
 *----------------------------------------------------------------------
 */

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);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FindDLine --
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
 *
 *----------------------------------------------------------------------
 */

static DLine *
FindDLine(
    TkText *textPtr,		/* Widget record for text widget. */
    DLine *dlPtr,	/* Pointer to first in list of DLines to
				 * search. */
    const TkTextIndex *indexPtr)/* Index of desired character. */
{
    DLine *dlPtrPrev;
    TkTextIndex indexPtr2;

    if (dlPtr == NULL) {
	return NULL;
    }







|

|







6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
 *
 *----------------------------------------------------------------------
 */

static DLine *
FindDLine(
    TkText *textPtr,		/* Widget record for text widget. */
    register DLine *dlPtr,	/* Pointer to first in list of DLines to
				 * search. */
    CONST TkTextIndex *indexPtr)/* Index of desired character. */
{
    DLine *dlPtrPrev;
    TkTextIndex indexPtr2;

    if (dlPtr == NULL) {
	return NULL;
    }
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
 *
 *----------------------------------------------------------------------
 */

static int
IsStartOfNotMergedLine(
      TkText *textPtr,              /* Widget record for text widget. */
      const TkTextIndex *indexPtr)  /* Index to check. */
{
    TkTextIndex indexPtr2;

    if (indexPtr->byteIndex != 0) {
        /*
         * Not the start of a logical line.
         */







|







6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
 *
 *----------------------------------------------------------------------
 */

static int
IsStartOfNotMergedLine(
      TkText *textPtr,              /* Widget record for text widget. */
      CONST TkTextIndex *indexPtr)  /* Index to check. */
{
    TkTextIndex indexPtr2;

    if (indexPtr->byteIndex != 0) {
        /*
         * Not the start of a logical line.
         */
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
				 * 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;
    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.
     */








|







6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
				 * 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;
    int nearby = 0;

    /*
     * Make sure that all of the layout information about what's displayed
     * where on the screen is up-to-date.
     */

7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121

    if (dInfoPtr->dLinePtr == NULL) {
	if (nearest != NULL) {
	    *nearest = 1;
	}
	*indexPtr = textPtr->topIndex;
	return;
    }
    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;
	    nearby = 1;
	    break;
	}
    }
    if (dlPtr->chunkPtr == NULL) {
	dlPtr = validDlPtr;
    }

    if (nearest != NULL) {
	*nearest = nearby;
    }

    DlineIndexOfX(textPtr, dlPtr, x, indexPtr);







|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
<







6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818

6819
6820
6821
6822
6823
6824
6825

    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;
		nearby = 1;
		break;
	    }
	}
	if (dlPtr->chunkPtr == NULL) dlPtr = validDlPtr;

    }

    if (nearest != NULL) {
	*nearest = nearby;
    }

    DlineIndexOfX(textPtr, dlPtr, x, indexPtr);
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
				 * 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;
    TkTextDispChunk *chunkPtr;

    /*
     * 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).
     */







|







6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
				 * 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;

    /*
     * 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).
     */
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
     * 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) {
	indexPtr->byteIndex += chunkPtr->measureProc(chunkPtr, x);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexOfX --







|







6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
     * 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) {
	indexPtr->byteIndex += (*chunkPtr->measureProc)(chunkPtr, x);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexOfX --
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307

7308
7309
7310
7311
7312
7313
7314
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. */
{
    TkTextDispChunk *chunkPtr = dlPtr->chunkPtr;
    int x = 0;

    if (byteIndex == 0 || chunkPtr == NULL) {
	return x;
    }

    /*
     * 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;
	}
	byteIndex -= chunkPtr->numBytes;

	if (chunkPtr->nextPtr == NULL || byteIndex == 0) {
	    x = chunkPtr->x + chunkPtr->width;
	    break;
	}
	chunkPtr = chunkPtr->nextPtr;
    }








|



|












|





|
|
>







6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
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 = 0;

    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;
    }

7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
 *
 *----------------------------------------------------------------------
 */

int
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, 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;
    TkTextDispChunk *chunkPtr;
    int byteCount;

    /*
     * Make sure that all of the screen layout information is up to date.
     */

    if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
	UpdateDisplayInfo(textPtr);
    }

    /*
     * Find the display line containing the desired index.
     */

    dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);

    /*
     * Two cases shall be trapped here because the logic later really
     * needs dlPtr to be the display line containing indexPtr:
     *   1. if no display line contains the desired index (NULL dlPtr)
     *   2. if indexPtr is before the first display line, in which case
     *      dlPtr currently points to the first display line
     */








|











|
















|







7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
 *
 *----------------------------------------------------------------------
 */

int
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, 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;
    register TkTextDispChunk *chunkPtr;
    int byteCount;

    /*
     * Make sure that all of the screen layout information is up to date.
     */

    if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
	UpdateDisplayInfo(textPtr);
    }

    /*
     * Find the display line containing the desired index.
     */

    dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);

    /* 
     * Two cases shall be trapped here because the logic later really
     * needs dlPtr to be the display line containing indexPtr:
     *   1. if no display line contains the desired index (NULL dlPtr)
     *   2. if indexPtr is before the first display line, in which case
     *      dlPtr currently points to the first display line
     */

7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
    /*
     * 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(textPtr, chunkPtr, byteCount,
	    dlPtr->y + dlPtr->spaceAbove,
	    dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
	    dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr,
	    heightPtr);
    *xPtr = *xPtr + dInfoPtr->x - dInfoPtr->curXPixelOffset;
    if ((byteCount == chunkPtr->numBytes-1) && (chunkPtr->nextPtr == NULL)) {
	/*







|







7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
    /*
     * 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)(textPtr, chunkPtr, byteCount,
	    dlPtr->y + dlPtr->spaceAbove,
	    dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
	    dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr,
	    heightPtr);
    *xPtr = *xPtr + dInfoPtr->x - dInfoPtr->curXPixelOffset;
    if ((byteCount == chunkPtr->numBytes-1) && (chunkPtr->nextPtr == NULL)) {
	/*
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
 *
 *----------------------------------------------------------------------
 */

int
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, int *heightPtr,
				/* Filled in with line's dimensions. */
    int *basePtr)		/* Filled in with the baseline position,
				 * measured as an offset down from *yPtr. */







|







7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
 *
 *----------------------------------------------------------------------
 */

int
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, int *heightPtr,
				/* Filled in with line's dimensions. */
    int *basePtr)		/* Filled in with the baseline position,
				 * measured as an offset down from *yPtr. */
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521

    /*
     * Find the display line containing the desired index.
     */

    dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);

    /*
     * Two cases shall be trapped here because the logic later really
     * needs dlPtr to be the display line containing indexPtr:
     *   1. if no display line contains the desired index (NULL dlPtr)
     *   2. if indexPtr is before the first display line, in which case
     *      dlPtr currently points to the first display line
     */








|







7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226

    /*
     * Find the display line containing the desired index.
     */

    dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);

    /* 
     * Two cases shall be trapped here because the logic later really
     * needs dlPtr to be the display line containing indexPtr:
     *   1. if no display line contains the desired index (NULL dlPtr)
     *   2. if indexPtr is before the first display line, in which case
     *      dlPtr currently points to the first display line
     */

7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582

/*
 * Get bounding-box information about an elided chunk.
 */

static void
ElideBboxProc(
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(int),		/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    TCL_UNUSED(int),	/* Height of line, in pixels. */
    TCL_UNUSED(int),	/* 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(
    TCL_UNUSED(TkTextDispChunk *),	/* Chunk containing desired coord. */
    TCL_UNUSED(int))		/* X-coordinate, in same coordinate system as
				 * chunkPtr->x. */
{
    return 0 /*chunkPtr->numBytes - 1*/;
}

/*
 *--------------------------------------------------------------







|

|



|
|









<











|
|







7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266

7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286

/*
 * Get bounding-box information about an elided chunk.
 */

static void
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(
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired coord. */
    int x)			/* X-coordinate, in same coordinate system as
				 * chunkPtr->x. */
{
    return 0 /*chunkPtr->numBytes - 1*/;
}

/*
 *--------------------------------------------------------------
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
 *	Memory is allocated to hold additional information about the chunk.
 *
 *--------------------------------------------------------------
 */

int
TkTextCharLayoutProc(
    TCL_UNUSED(TkText *),	/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Index of first character to lay out
				 * (corresponds to segPtr and offset). */
    TkTextSegment *segPtr,	/* Segment being layed out. */
    TkSizeT byteOffset,		/* Byte offset within segment of first
				 * character to consider. */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TkSizeT 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. */
    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, count;
    TkSizeT bytesThatFit;
    CharInfo *ciPtr;
    char *p;
    TkTextSegment *nextPtr;
    Tk_FontMetrics fm;
#ifdef 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 have not
     *	     already exceeded the character limit, and the next character is a
     *	     white space character.
     * In the specific case of 'word' wrapping mode however, include all space
     * characters following the characters that fit in the space we've got,
     * even if no pixel of them is visible.
     */

    p = segPtr->body.chars + byteOffset;
    tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;

#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    if (baseCharChunkPtr == NULL) {
	baseCharChunkPtr = chunkPtr;
	bciPtr = ckalloc(sizeof(BaseCharInfo));
	baseString = &bciPtr->baseChars;
	Tcl_DStringInit(baseString);
	bciPtr->width = 0;

	ciPtr = &bciPtr->ci;
    } else {
	bciPtr = baseCharChunkPtr->clientData;
	ciPtr = ckalloc(sizeof(CharInfo));
	baseString = &bciPtr->baseChars;
    }

    lineOffset = Tcl_DStringLength(baseString);
    line = Tcl_DStringAppend(baseString,p,maxBytes);

    chunkPtr->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 + 1 <= maxBytes) {
	if ((bytesThatFit == 0) && noCharsYet) {
	    int ch;
	    int chLen = TkUtfToUniChar(p, &ch);

#ifdef 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.
	     */

	    nextX = maxX;
	    bytesThatFit++;
	}
        if (wrapMode == TEXT_WRAPMODE_WORD) {
            while (p[bytesThatFit] == ' ') {
                /*
                 * Space characters that would go at the beginning of the
                 * next line are allocated to the current line. This gives
                 * the effect of trimming white spaces that would otherwise
                 * be seen at the beginning of wrapped lines.
                 * Note that testing for '\t' is useless here because the
                 * chunk always includes at most one trailing \t, see
                 * LayoutDLine.
                 */

                bytesThatFit++;
            }
        }
	if (p[bytesThatFit] == '\n') {
	    /*
	     * A newline character takes up no space, so if the previous
	     * character fits then so does the newline.
	     */

	    bytesThatFit++;
	}
	if (bytesThatFit == 0) {
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    chunkPtr->clientData = NULL;
	    if (chunkPtr == baseCharChunkPtr) {
		baseCharChunkPtr = NULL;
		Tcl_DStringFree(baseString);
	    } else {
		Tcl_DStringSetLength(baseString,lineOffset);
	    }
	    ckfree(ciPtr);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
	    return 0;
	}
    }

    Tk_GetFontMetrics(tkfont, &fm);








|
|


|



|






|





|
<




|
















<
<
<





|


|






|
|






|













|

|
|

|



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|







|







7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329

7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350



7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412















7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
 *	Memory is allocated to hold additional information about the chunk.
 *
 *--------------------------------------------------------------
 */

int
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
				 * character to consider. */
    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
				 * 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. */
{
    Tk_Font tkfont;
    int nextX, bytesThatFit, count;

    CharInfo *ciPtr;
    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 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;

#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;
	    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.
	     */

	    nextX = maxX;
	    bytesThatFit++;
	}















	if (p[bytesThatFit] == '\n') {
	    /*
	     * A newline character takes up no space, so if the previous
	     * character fits then so does the newline.
	     */

	    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);

7763
7764
7765
7766
7767
7768
7769
7770
7771

7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
    chunkPtr->numBytes = bytesThatFit;
    chunkPtr->minAscent = fm.ascent + chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minDescent = fm.descent - chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minHeight = 0;
    chunkPtr->width = nextX - chunkPtr->x;
    chunkPtr->breakIndex = -1;

#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
    ciPtr = (CharInfo *)ckalloc(offsetof(CharInfo, chars) + 1 + bytesThatFit);

    chunkPtr->clientData = ciPtr;
    memcpy(ciPtr->chars, p, bytesThatFit);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

    ciPtr->numBytes = bytesThatFit;
    if (p[bytesThatFit - 1] == '\n') {
	ciPtr->numBytes--;
    }

#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    /*
     * Final update for the current base chunk data.
     */

    Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
    bciPtr->width = nextX - baseCharChunkPtr->x;








|
|
>
|
|







|







7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
    chunkPtr->numBytes = bytesThatFit;
    chunkPtr->minAscent = fm.ascent + chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minDescent = fm.descent - chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minHeight = 0;
    chunkPtr->width = nextX - chunkPtr->x;
    chunkPtr->breakIndex = -1;

#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;
    if (p[bytesThatFit - 1] == '\n') {
	ciPtr->numBytes--;
    }

#if TK_LAYOUT_WITH_BASE_CHUNKS
    /*
     * Final update for the current base chunk data.
     */

    Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
    bciPtr->width = nextX - baseCharChunkPtr->x;

7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821

7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
     */

    if (wrapMode != TEXT_WRAPMODE_WORD) {
	chunkPtr->breakIndex = chunkPtr->numBytes;
    } else {
	for (count = bytesThatFit, p += bytesThatFit - 1; count > 0;
		count--, p--) {
	    /*
	     * Don't use isspace(); effects are unpredictable and can lead to
	     * odd word-wrapping problems on some platforms. Also don't use
	     * Tcl_UniCharIsSpace here either, as it identifies non-breaking
	     * spaces as places to break. What we actually want is only the
	     * ASCII space characters, so use them explicitly...
	     */

	    switch (*p) {
	    case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
		chunkPtr->breakIndex = count;
		goto checkForNextChunk;

	    }
	}
    checkForNextChunk:
	if ((bytesThatFit + byteOffset) == segPtr->size) {
	    for (nextPtr = segPtr->nextPtr; nextPtr != NULL;
		    nextPtr = nextPtr->nextPtr) {
		if (nextPtr->size != 0) {
		    if (nextPtr->typePtr != &tkTextCharType) {
			chunkPtr->breakIndex = chunkPtr->numBytes;
		    }







<
<
<
<
<
<
<
|
<
<

<
>


<







7489
7490
7491
7492
7493
7494
7495







7496


7497

7498
7499
7500

7501
7502
7503
7504
7505
7506
7507
     */

    if (wrapMode != TEXT_WRAPMODE_WORD) {
	chunkPtr->breakIndex = chunkPtr->numBytes;
    } else {
	for (count = bytesThatFit, p += bytesThatFit - 1; count > 0;
		count--, p--) {







	    if (UCHAR(*p) < 0x80 && isspace(UCHAR(*p))) {


		chunkPtr->breakIndex = count;

		break;
	    }
	}

	if ((bytesThatFit + byteOffset) == segPtr->size) {
	    for (nextPtr = segPtr->nextPtr; nextPtr != NULL;
		    nextPtr = nextPtr->nextPtr) {
		if (nextPtr->size != 0) {
		    if (nextPtr->typePtr != &tkTextCharType) {
			chunkPtr->breakIndex = chunkPtr->numBytes;
		    }
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
				 * 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 !defined(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 /* TK_LAYOUT_WITH_BASE_CHUNKS */
    {
	int xDisplacement;
	int fit, bstart = start, bend = end;

	if (chars == NULL) {
	    Tcl_DString *baseChars = &((BaseCharInfo *)
		    ciPtr->baseChunkPtr->clientData)->baseChars;







|

|










|







7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
				 * 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;
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
	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 - ciPtr->baseChunkPtr->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 /* TK_LAYOUT_WITH_BASE_CHUNKS */
}

/*
 *--------------------------------------------------------------
 *
 * CharDisplayProc --
 *







|











|







7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
	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 --
 *
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

static void
CharDisplayProc(
    TCL_UNUSED(TkText *),
    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. */
    TCL_UNUSED(int),		/* 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. */
    TCL_UNUSED(int))	/* Y-coordinate in text window that
				 * corresponds to y. */
{
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
    const char *string;
    TextStyle *stylePtr;
    StyleValues *sValuePtr;
    int numBytes, offsetBytes, offsetX;
#ifdef TK_DRAW_IN_CONTEXT
    BaseCharInfo *bciPtr;
#endif /* TK_DRAW_IN_CONTEXT */

    if ((x + chunkPtr->width) <= 0) {
	/*
	 * The chunk is off-screen.
	 */

	return;
    }

#ifdef TK_DRAW_IN_CONTEXT
    bciPtr = ciPtr->baseChunkPtr->clientData;
    numBytes = Tcl_DStringLength(&bciPtr->baseChars);
    string = Tcl_DStringValue(&bciPtr->baseChars);

#elif defined(TK_LAYOUT_WITH_BASE_CHUNKS)
    if (ciPtr->baseChunkPtr != chunkPtr) {
	/*
	 * Without context drawing only base chunks display their foreground.
	 */

	return;
    }







|






|



|


|




|











|
|



|







7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

static void
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 numBytes, offsetBytes, offsetX;
#if TK_DRAW_IN_CONTEXT
    BaseCharInfo *bciPtr;
#endif /* TK_DRAW_IN_CONTEXT */

    if ((x + chunkPtr->width) <= 0) {
	/*
	 * The chunk is off-screen.
	 */

	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;
    }
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098

    /*
     * Draw the text, underline, and overstrike for this chunk.
     */

    if (!sValuePtr->elide && (numBytes > offsetBytes)
	    && (stylePtr->fgGC != NULL)) {
#ifdef 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->ulGC,
		    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->ovGC,
		    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--;
	}
	Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
		numBytes, offsetX, y + baseline - sValuePtr->offset);
	if (sValuePtr->underline) {
	    Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont,
		    string, offsetX,
		    y + baseline - sValuePtr->offset,
		    0, numBytes);

	}
	if (sValuePtr->overstrike) {
	    Tk_FontMetrics fm;

	    Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
	    Tk_UnderlineChars(display, dst, stylePtr->ovGC, sValuePtr->tkfont,
		    string, offsetX,
		    y + baseline - sValuePtr->offset
			    - fm.descent - (fm.ascent * 3) / 10,
		    0, numBytes);
	}
#endif /* TK_DRAW_IN_CONTEXT */
    }







|

















|









|
















|









|







7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774

    /*
     * Draw the text, underline, and overstrike for this chunk.
     */

    if (!sValuePtr->elide && (numBytes > offsetBytes)
	    && (stylePtr->fgGC != NULL)) {
#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--;
	}
	Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
		numBytes, offsetX, y + baseline - sValuePtr->offset);
	if (sValuePtr->underline) {
	    Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
		    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,
		    string, offsetX,
		    y + baseline - sValuePtr->offset
			    - fm.descent - (fm.ascent * 3) / 10,
		    0, numBytes);
	}
#endif /* TK_DRAW_IN_CONTEXT */
    }
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
 *	Memory and other resources get freed.
 *
 *--------------------------------------------------------------
 */

static void
CharUndisplayProc(
    TCL_UNUSED(TkText *),	/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;

    if (ciPtr) {
#ifdef 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.
	     */








|


|


|







7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
 *	Memory and other resources get freed.
 *
 *--------------------------------------------------------------
 */

static void
CharUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;

    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.
	     */

8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
	}

	ciPtr->baseChunkPtr = NULL;
	ciPtr->chars = NULL;
	ciPtr->numBytes = 0;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

	ckfree(ciPtr);
	chunkPtr->clientData = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *







|







7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
	}

	ciPtr->baseChunkPtr = NULL;
	ciPtr->chars = NULL;
	ciPtr->numBytes = 0;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

	ckfree((char *) ciPtr);
	chunkPtr->clientData = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
CharBboxProc(
    TCL_UNUSED(TkText *),
    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. */
    TCL_UNUSED(int),	/* 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;
    CharChunkMeasureChars(chunkPtr, NULL, 0, 0, byteIndex,
	    chunkPtr->x, -1, 0, xPtr);

    if (byteIndex == ciPtr->numBytes) {







|





|










|







7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
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;
    CharChunkMeasureChars(chunkPtr, NULL, 0, 0, byteIndex,
	    chunkPtr->x, -1, 0, xPtr);

    if (byteIndex == ciPtr->numBytes) {
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427

8428
8429
8430
8431
8432
8433
8434
    decimalChunkPtr = NULL;
    decimal = gotDigit = 0;
    for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
	    chunkPtr2 = chunkPtr2->nextPtr) {
	if (chunkPtr2->displayProc != CharDisplayProc) {
	    continue;
	}
	ciPtr = (CharInfo *)chunkPtr2->clientData;
	for (p = ciPtr->chars, i = 0; i < ciPtr->numBytes; p++, i++) {
	    if (isdigit(UCHAR(*p))) {
		gotDigit = 1;
	    } else if ((*p == '.') || (*p == ',')) {
		decimal = p-ciPtr->chars;
		decimalChunkPtr = chunkPtr2;
	    } else if (gotDigit) {
		if (decimalChunkPtr == NULL) {
		    decimal = p-ciPtr->chars;
		    decimalChunkPtr = chunkPtr2;
		}
		goto endOfNumber;
	    }
	}
    }

  endOfNumber:
    if (decimalChunkPtr != NULL) {
	int curX;

	ciPtr = (CharInfo *)decimalChunkPtr->clientData;
	CharChunkMeasureChars(decimalChunkPtr, NULL, 0, 0, decimal,
		decimalChunkPtr->x, -1, 0, &curX);
	desired = tabX - (curX - x);
	goto update;
    }

    /*
     * There wasn't a decimal point. Right justify the text.
     */

    width = 0;
    for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
	    chunkPtr2 = chunkPtr2->nextPtr) {
	width += chunkPtr2->width;
    }
    desired = tabX - width;


    /*
     * 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.
     */








|




















|




<
|
|
|
|

|
|
|
|
|
|
>







8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091

8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
    decimalChunkPtr = NULL;
    decimal = gotDigit = 0;
    for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
	    chunkPtr2 = chunkPtr2->nextPtr) {
	if (chunkPtr2->displayProc != CharDisplayProc) {
	    continue;
	}
	ciPtr = (CharInfo *) chunkPtr2->clientData;
	for (p = ciPtr->chars, i = 0; i < ciPtr->numBytes; p++, i++) {
	    if (isdigit(UCHAR(*p))) {
		gotDigit = 1;
	    } else if ((*p == '.') || (*p == ',')) {
		decimal = p-ciPtr->chars;
		decimalChunkPtr = chunkPtr2;
	    } else if (gotDigit) {
		if (decimalChunkPtr == NULL) {
		    decimal = p-ciPtr->chars;
		    decimalChunkPtr = chunkPtr2;
		}
		goto endOfNumber;
	    }
	}
    }

  endOfNumber:
    if (decimalChunkPtr != NULL) {
	int curX;

	ciPtr = (CharInfo *) decimalChunkPtr->clientData;
	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.
	 */

	width = 0;
	for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
		chunkPtr2 = chunkPtr2->nextPtr) {
	    width += chunkPtr2->width;
	}
	desired = tabX - width;
    }

    /*
     * 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.
     */

8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
 *
 *--------------------------------------------------------------
 */

static int
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 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 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;
    curX = startX;
    start = source + rangeStart;
    end = start + rangeLength;
    special = start;
    while (start < end) {
	if (start >= special) {
	    /*







|














|

|







8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
 *
 *--------------------------------------------------------------
 */

static int
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 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 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;
    start = source + rangeStart;
    end = start + rangeLength;
    special = start;
    while (start < end) {
	if (start >= special) {
	    /*
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727


8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
	 * Special points at the next special character (or the end of the
	 * string). Process characters between start and special.
	 */

	if ((maxX >= 0) && (curX >= maxX)) {
	    break;
	}
#ifdef 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) {
	    /*
	     * No more chars fit in line.
	     */

	    break;
	}
	if (special < end) {
	    if (ch != '\t') {


		break;
	    }
	    start++;
	}
    }

    *nextXPtr = curX;
    return start - (source+rangeStart);
}








|

















|
>
>


<







8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407

8408
8409
8410
8411
8412
8413
8414
	 * Special points at the next special character (or the end of the
	 * string). Process characters between start and special.
	 */

	if ((maxX >= 0) && (curX >= maxX)) {
	    break;
	}
#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) {
	    /*
	     * No more chars fit in line.
	     */

	    break;
	}
	if (special < end) {
	    if (ch == '\t') {
		start++;
	    } else {
		break;
	    }

	}
    }

    *nextXPtr = curX;
    return start - (source+rangeStart);
}

8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
 */

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 *const subcommands[] = {
	"moveto", "scroll", NULL
    };
    enum viewSubcmds {
	VIEW_MOVETO, VIEW_SCROLL
    };
    static const char *const units[] = {
	"pages", "pixels", "units", NULL
    };
    enum viewUnits {
	VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS, VIEW_SCROLL_UNITS
    };
    int index;
    double d;

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands,
	    sizeof(char *), "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 pages|pixels|units");
	    return TKTEXT_SCROLL_ERROR;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[4], units,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TKTEXT_SCROLL_ERROR;
	}
	switch ((enum viewUnits) index) {
	case VIEW_SCROLL_PAGES:
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    return TKTEXT_SCROLL_PAGES;
	case VIEW_SCROLL_PIXELS:
	    if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[3],
		    intPtr) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    if (dblPtr) {
		*dblPtr = (double)*intPtr;
	    }
	    return TKTEXT_SCROLL_PIXELS;
	case VIEW_SCROLL_UNITS:
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    return TKTEXT_SCROLL_UNITS;
	}
    }
    Tcl_Panic("unexpected switch fallthrough");
    return TKTEXT_SCROLL_ERROR;
}

#ifdef 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







|





|





|
|


|


<

|
|















|


|
|




|


<
<
<
<






<
<
<


|


<
<
<
<







|







8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466

8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496




8497
8498
8499
8500
8501
8502



8503
8504
8505
8506
8507




8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
 */

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
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
				 * even though it may not be in the linked
				 * list yet. Used by the LayoutProc, otherwise
				 * NULL. */
{
    const char *baseChars;
    TkTextDispChunk *chunkPtr;
    CharInfo *ciPtr;
#ifdef 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) {
#ifdef TK_DRAW_IN_CONTEXT
	chunkPtr->x += widthAdjust;
#endif /* TK_DRAW_IN_CONTEXT */

	if (chunkPtr->displayProc != CharDisplayProc) {
	    continue;
	}
	ciPtr = chunkPtr->clientData;
	if (ciPtr->baseChunkPtr != baseCharChunkPtr) {
	    break;
	}
	ciPtr->chars = baseChars + ciPtr->baseOffset;

#ifdef 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 = addChunkPtr->clientData;
	ciPtr->chars = baseChars + ciPtr->baseOffset;

#ifdef 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;







|













|






|





|


|







|


|







8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
				 * 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;
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
	baseCharChunkPtr = NULL;
    }

    for (chunkPtr=baseChunkPtr; chunkPtr!=NULL; chunkPtr=chunkPtr->nextPtr) {
	if (chunkPtr->undisplayProc != CharUndisplayProc) {
	    continue;
	}
	ciPtr = chunkPtr->clientData;
	if (ciPtr->baseChunkPtr != baseChunkPtr) {
	    break;
	}

	ciPtr->baseChunkPtr = NULL;
	ciPtr->chars = NULL;
    }

    if (baseChunkPtr) {
	Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * IsSameFGStyle --
 *







|








<
|
<







8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643

8644

8645
8646
8647
8648
8649
8650
8651
	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 --
 *
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
    StyleValues *sv1;
    StyleValues *sv2;

    if (style1 == style2) {
	return 1;
    }

#if !defined(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;

#ifdef 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







|















|







8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
    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
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101

9102
9103
9104
9105

9106
9107
9108
9109
9110
9111
9112
	return;
    }

    /*
     * Reinstitute this base chunk for re-layout.
     */

    ciPtr = chunkPtr->clientData;
    baseCharChunkPtr = ciPtr->baseChunkPtr;

    /*
     * Remove the chunk data from the base chunk data.
     */

    bciPtr = baseCharChunkPtr->clientData;

#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS
    if ((ciPtr->baseOffset + ciPtr->numBytes)
	    != Tcl_DStringLength(&bciPtr->baseChars)) {

	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.
     */








|






|

<


>


<

>







8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761

8762
8763
8764
8765
8766

8767
8768
8769
8770
8771
8772
8773
8774
8775
	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.
     */

Changes to generic/tkTextImage.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "tkText.h"

/*
 * Macro that determines the size of an embedded image segment:
 */

#define EI_SEG_SIZE \
	(offsetof(TkTextSegment, body) + sizeof(TkTextEmbImage))

/*
 * Prototypes for functions defined in this file:
 */

static TkTextSegment *	EmbImageCleanupProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "tkText.h"

/*
 * Macro that determines the size of an embedded image segment:
 */

#define EI_SEG_SIZE \
	((unsigned) (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage)))

/*
 * Prototypes for functions defined in this file:
 */

static TkTextSegment *	EmbImageCleanupProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
			    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(TkText *textPtr,
			    TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    TkSizeT offset, int maxX, TkSizeT maxChars,
			    int noCharsYet, TkWrapMode wrapMode,
			    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.
 */

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 *const 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 const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbImage, align),
	0, alignStrings, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-name", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};


/*
 *--------------------------------------------------------------
 *
 * TkTextImageCmd --
 *
 *	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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextImageCmd(
    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
				 * objv[1] is "image". */
{
    int idx;
    TkTextSegment *eiPtr;
    TkTextIndex index;
    static const char *const 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 ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], optionStrings,
	    sizeof(char *), "option", 0, &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum opts) idx) {
    case CMD_CGET: {
	Tcl_Obj *objPtr;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded image at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL);
	    return TCL_ERROR;
	}
	objPtr = Tk_GetOptionValue(interp, &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;
	}
    }
    case CMD_CONF:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded image at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL);
	    return TCL_ERROR;
	}
	if (objc <= 5) {
	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp,
		    &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 {







|










|














|













|
|

|

|

|


|

|

>




















|







|

|







|


|
|















<
|
|
<


|










|







<
|
|
<




|

<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183

184
185
186
187
188
189

190
191
192
193
194
195
196
			    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(TkText *textPtr,
			    TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    int offset, int maxX, int maxChars,
			    int noCharsYet, TkWrapMode wrapMode,
			    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 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 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 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.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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
				 * objv[1] is "image". */
{
    int idx;
    register TkTextSegment *eiPtr;
    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;
    }
    switch ((enum opts) idx) {
    case CMD_CGET: {
	Tcl_Obj *objPtr;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {

	    Tcl_AppendResult(interp, "no embedded image at index \"",
		    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;
	}
    }
    case CMD_CONF:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {

	    Tcl_AppendResult(interp, "no embedded image at index \"",
		    Tcl_GetString(objv[3]), "\"", NULL);

	    return TCL_ERROR;
	}
	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 {
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

	/*
	 * Add a new image. Find where to put the new image, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*







|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

	/*
	 * Add a new image. Find where to put the new image, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new image segment and initialize it.
	 */

	eiPtr = (TkTextSegment *)ckalloc(EI_SEG_SIZE);
	eiPtr->typePtr = &tkTextEmbImageType;
	eiPtr->size = 1;
	eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr;
	eiPtr->body.ei.linePtr = NULL;
	eiPtr->body.ei.imageName = NULL;
	eiPtr->body.ei.imageString = NULL;
	eiPtr->body.ei.name = NULL;







|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new image segment and initialize it.
	 */

	eiPtr = (TkTextSegment *) ckalloc(EI_SEG_SIZE);
	eiPtr->typePtr = &tkTextEmbImageType;
	eiPtr->size = 1;
	eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr;
	eiPtr->body.ei.linePtr = NULL;
	eiPtr->body.ei.imageName = NULL;
	eiPtr->body.ei.imageString = NULL;
	eiPtr->body.ei.name = NULL;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	return TCL_OK;
    }
    case CMD_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	if (resultObj == NULL) {
	    return TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	}
    }
    default:
	Tcl_Panic("unexpected switch fallthrough");
    }
    return TCL_ERROR;
}








<





<


|
|
<

<
<
<
<
|
<







269
270
271
272
273
274
275

276
277
278
279
280

281
282
283
284

285




286

287
288
289
290
291
292
293
	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	return TCL_OK;
    }
    case CMD_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendElement(interp,
		    Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr));

	}




	return TCL_OK;

    }
    default:
	Tcl_Panic("unexpected switch fallthrough");
    }
    return TCL_ERROR;
}

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
				 * options. */
{
    Tk_Image image;
    Tcl_DString newName;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char *name;
    int dummy;
    int count = 0;		/* The counter for picking a unique name */
    int conflict = 0;		/* True if we have a name conflict */
    size_t len;			/* length of image name */

    if (Tk_SetOptions(textPtr->interp, &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.
     */

    if (eiPtr->body.ei.imageString != NULL) {
	image = Tk_GetImage(textPtr->interp, textPtr->tkwin,
		eiPtr->body.ei.imageString, EmbImageProc, eiPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (eiPtr->body.ei.image != NULL) {







<


|

|














|







320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
				 * options. */
{
    Tk_Image image;
    Tcl_DString newName;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char *name;

    int count = 0;		/* The counter for picking a unique name */
    int conflict = 0;		/* True if we have a name conflict */
    size_t len;		/* length of image name */

    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.
     */

    if (eiPtr->body.ei.imageString != NULL) {
	image = Tk_GetImage(textPtr->interp, textPtr->tkwin,
		eiPtr->body.ei.imageString, EmbImageProc, (ClientData) eiPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (eiPtr->body.ei.image != NULL) {
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
     */

    name = eiPtr->body.ei.imageName;
    if (name == NULL) {
    	name = eiPtr->body.ei.imageString;
    }
    if (name == NULL) {
	Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(
		"Either a \"-name\" or a \"-image\" argument must be"
		" provided to the \"image create\" subcommand", -1));
	Tcl_SetErrorCode(textPtr->interp, "TK", "TEXT", "IMAGE_CREATE_USAGE",
		NULL);
	return TCL_ERROR;
    }
    len = strlen(name);
    for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
	    &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	char *haveName = (char *)
		Tcl_GetHashKey(&textPtr->sharedTextPtr->imageTable, hPtr);

	if (strncmp(name, haveName, len) == 0) {
	    int newVal = 0;

	    sscanf(haveName+len, "#%d", &newVal);
	    if (newVal > count) {







|
|
|
<
<





|







366
367
368
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384
385
386
387
388
     */

    name = eiPtr->body.ei.imageName;
    if (name == NULL) {
    	name = eiPtr->body.ei.imageString;
    }
    if (name == NULL) {
	Tcl_AppendResult(textPtr->interp, "Either a \"-name\" ",
		"or a \"-image\" argument must be provided ",
		"to the \"image create\" subcommand.", NULL);


	return TCL_ERROR;
    }
    len = strlen(name);
    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) {
	    int newVal = 0;

	    sscanf(haveName+len, "#%d", &newVal);
	    if (newVal > count) {
415
416
417
418
419
420
421



422
423

424
425
426
427
428
429
430
431
432
433
    if (conflict) {
    	char buf[4 + TCL_INTEGER_SPACE];

	sprintf(buf, "#%d", count+1);
	Tcl_DStringAppend(&newName, buf, -1);
    }
    name = Tcl_DStringValue(&newName);



    hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name,
	    &dummy);

    Tcl_SetHashValue(hPtr, eiPtr);
    Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(name, -1));
    eiPtr->body.ei.name = (char *)ckalloc(Tcl_DStringLength(&newName) + 1);
    strcpy(eiPtr->body.ei.name, name);
    Tcl_DStringFree(&newName);

    return TCL_OK;
}

/*







>
>
>
|
|
>

|
|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    if (conflict) {
    	char buf[4 + TCL_INTEGER_SPACE];

	sprintf(buf, "#%d", count+1);
	Tcl_DStringAppend(&newName, buf, -1);
    }
    name = Tcl_DStringValue(&newName);
    {
	int dummy;

	hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name,
		&dummy);
    }
    Tcl_SetHashValue(hPtr, eiPtr);
    Tcl_AppendResult(textPtr->interp, name, NULL);
    eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1);
    strcpy(eiPtr->body.ei.name, name);
    Tcl_DStringFree(&newName);

    return TCL_OK;
}

/*
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
 * Side effects:
 *	The embedded image is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */


static int
EmbImageDeleteProc(
    TkTextSegment *eiPtr,	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* 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.sharedTextPtr->imageTable,







>



|
|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
 * Side effects:
 *	The embedded image is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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.sharedTextPtr->imageTable,
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
     */

    Tk_FreeConfigOptions((char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
	    NULL);
    if (eiPtr->body.ei.name) {
	ckfree(eiPtr->body.ei.name);
    }
    ckfree(eiPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageCleanupProc --







|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
     */

    Tk_FreeConfigOptions((char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
	    NULL);
    if (eiPtr->body.ei.name) {
	ckfree(eiPtr->body.ei.name);
    }
    ckfree((char *) eiPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageCleanupProc --
526
527
528
529
530
531
532

533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
 *
 * Side effects:
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */


static int
EmbImageLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *eiPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    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) {







>



|

|



|



|


|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
 *
 * Side effects:
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

	/*ARGSUSED*/
static int
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
				 * position or higher. */
    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. */
{
    int width, height;

    if (offset != 0) {
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = eiPtr;
    eiPtr->body.ei.chunkCount += 1;
    return 1;
}

/*
 *--------------------------------------------------------------
 *







|







582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = (ClientData) eiPtr;
    eiPtr->body.ei.chunkCount += 1;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
 *
 *--------------------------------------------------------------
 */

static void
EmbImageCheckProc(
    TkTextSegment *eiPtr,	/* Segment to check. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    if (eiPtr->nextPtr == NULL) {
	Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line");
    }
    if (eiPtr->size != 1) {
	Tcl_Panic("EmbImageCheckProc: embedded image has size %d",
		(int)eiPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDisplayProc --







|






|







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
 *
 *--------------------------------------------------------------
 */

static void
EmbImageCheckProc(
    TkTextSegment *eiPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
{
    if (eiPtr->nextPtr == NULL) {
	Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line");
    }
    if (eiPtr->size != 1) {
	Tcl_Panic("EmbImageCheckProc: embedded image has size %d",
		eiPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDisplayProc --
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
				 * 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. */
    TCL_UNUSED(Display *),	/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw */
    TCL_UNUSED(int))	/* Y-coordinate in text window that
				 * corresponds to y. */
{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;
    int lineX, imageX, imageY, width, height;
    Tk_Image image;

    image = eiPtr->body.ei.image;
    if (image == NULL) {
	return;
    }







|

|


|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
				 * 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;
    Tk_Image image;

    image = eiPtr->body.ei.image;
    if (image == NULL) {
	return;
    }
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
EmbImageBboxProc(
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(int),			/* 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;

    image = eiPtr->body.ei.image;
    if (image != NULL) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    } else {
	*widthPtr = 0;







|

|













|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
 *	None.
 *
 *--------------------------------------------------------------
 */

static void
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;

    image = eiPtr->body.ei.image;
    if (image != NULL) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    } else {
	*widthPtr = 0;
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
	return 0;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
    if (hPtr == NULL) {
	return 0;
    }
    eiPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = eiPtr->body.ei.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);
    return 1;
}

/*







|







783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
	return 0;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
    if (hPtr == NULL) {
	return 0;
    }
    eiPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = eiPtr->body.ei.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);
    return 1;
}

/*
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
 *
 *--------------------------------------------------------------
 */

static void
EmbImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    TCL_UNUSED(int),		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),	/* Dimensions of area to redisplay (may be
				 * <= 0). */
    TCL_UNUSED(int),
    TCL_UNUSED(int),/* New dimensions of image. */
    TCL_UNUSED(int))

{
    TkTextSegment *eiPtr = (TkTextSegment *)clientData;
    TkTextIndex index;

    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.sharedTextPtr, NULL, &index, &index);








|

<
|

<
|
<


|







810
811
812
813
814
815
816
817
818

819
820

821

822
823
824
825
826
827
828
829
830
831
 *
 *--------------------------------------------------------------
 */

static void
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.sharedTextPtr->tree;
    index.linePtr = eiPtr->body.ei.linePtr;
    index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr);
    TkTextChanged(eiPtr->body.ei.sharedTextPtr, NULL, &index, &index);

Changes to generic/tkTextIndex.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145











146
147
148
149
150
151
152
/*
 * tkTextIndex.c --
 *
 *	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.
 */

#include "tkInt.h"
#include "tkText.h"
#include "default.h"

/*
 * Index to use to select last character in line (very large integer):
 */

#define LAST_CHAR 1000000

/*
 * 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);
static int              IndexCountBytesOrdered(const TkText *textPtr,
                            const TkTextIndex *indexPtr1,
                            const TkTextIndex *indexPtr2);

/*
 * The "textindex" Tcl_Obj definition:
 */

static void		DupTextIndexInternalRep(Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr);
static void		FreeTextIndexInternalRep(Tcl_Obj *listPtr);


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 = (void *) (size_t) (epoch))

/*
 * Define the 'textindex' object type, which Tk uses to represent indices in
 * text widgets internally.
 */

const Tcl_ObjType tkTextIndexType = {
    "textindex",		/* name */
    FreeTextIndexInternalRep,	/* freeIntRepProc */
    DupTextIndexInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* 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-- <= 1) {
	    /*
	     * The text widget has been deleted and we need to free it now.
	     */

	    ckfree(indexPtr->textPtr);
	}
    }
    ckfree(indexPtr);
    indexObjPtr->typePtr = NULL;
}

static void
DupTextIndexInternalRep(
    Tcl_Obj *srcPtr,		/* TextIndex obj with internal rep to copy. */
    Tcl_Obj *copyPtr)		/* TextIndex obj with internal rep to set. */
{
    TkSizeT 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 void
UpdateStringOfTextIndex(
    Tcl_Obj *objPtr)
{
    char buffer[TK_POS_CHARS];
    size_t len;

    const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);

    len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);

    objPtr->bytes = (char *)ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}












/*
 *---------------------------------------------------------------------------
 *
 * MakeObjIndex --
 *
 *	This function generates a Tcl_Obj description of an index, suitable













|
|
|



















|

|


|

|
|
|








>
>











|

|
|





|




|

|






<

|




|


|
<







|


|














|











|
>
|



|



>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * tkTextIndex.c --
 *
 *	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.
 */

#include "default.h"
#include "tkInt.h"
#include "tkText.h"

/*
 * Index to use to select last character in line (very large integer):
 */

#define LAST_CHAR 1000000

/*
 * 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);
static int              IndexCountBytesOrdered(CONST TkText *textPtr,
                            CONST TkTextIndex *indexPtr1,
                            CONST TkTextIndex *indexPtr2);

/*
 * 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 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 */

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) {
	TkSizeT epoch;

	indexPtr = GET_TEXTINDEX(objPtr);
	epoch = GET_INDEXEPOCH(objPtr);

	if (epoch == textPtr->sharedTextPtr->stateEpoch) {
	    if (indexPtr->textPtr == textPtr) {
		return indexPtr;







|

|
















|
|











|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
 */

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;
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
	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);
}

/*







|
|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	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);
}

/*
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
 *
 *---------------------------------------------------------------------------
 */

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;

    /*







|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
 *
 *---------------------------------------------------------------------------
 */

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;

    /*
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextIndex *
TkTextMakeByteIndex(
    TkTextBTree tree,	/* Tree that lineIndex and byteIndex refer
				 * to. */
    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;
    const char *p, *start;
    int ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	byteIndex = 0;
    }
    if (byteIndex < 0) {







|

|







|
|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextIndex *
TkTextMakeByteIndex(
    TkTextBTree tree,		/* Tree that lineIndex and byteIndex refer
				 * to. */
    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;
    CONST char *p, *start;
    Tcl_UniChar ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	byteIndex = 0;
    }
    if (byteIndex < 0) {
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
	     * character on the line is guaranteed to be a '\n', we can back
	     * up a constant sizeof(char) bytes.
	     */

	    indexPtr->byteIndex = index - sizeof(char);
	    break;
	}
	if (index + (int)segPtr->size > byteIndex) {
	    indexPtr->byteIndex = byteIndex;
	    if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) {
		/*
		 * Prevent UTF-8 character from being split up by ensuring
		 * that byteIndex falls on a character boundary. If the index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
		 */

		start = segPtr->body.chars + (byteIndex - index);
		p = TkUtfPrev(start, segPtr->body.chars);
		p += TkUtfToUniChar(p, &ch);
		indexPtr->byteIndex += p - start;
	    }
	    break;
	}
	index += segPtr->size;
    }
    return indexPtr;







|




|





|
|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
	     * character on the line is guaranteed to be a '\n', we can back
	     * up a constant sizeof(char) bytes.
	     */

	    indexPtr->byteIndex = index - sizeof(char);
	    break;
	}
	if (index + segPtr->size > byteIndex) {
	    indexPtr->byteIndex = byteIndex;
	    if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) {
		/*
		 * Prevent UTF-8 character from being split up by ensuring
		 * that byteIndex falls on a character boundary. If index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
		 */

		start = segPtr->body.chars + (byteIndex - index);
		p = Tcl_UtfPrev(start, segPtr->body.chars);
		p += Tcl_UtfToUniChar(p, &ch);
		indexPtr->byteIndex += p - start;
	    }
	    break;
	}
	index += segPtr->size;
    }
    return indexPtr;
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
				 * to. */
    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. */
{
    TkTextSegment *segPtr;
    char *p, *start, *end;
    int index, offset;
    int ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	charIndex = 0;
    }
    if (charIndex < 0) {







|


|







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
				 * to. */
    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;
    int index, offset;
    Tcl_UniChar ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	charIndex = 0;
    }
    if (charIndex < 0) {
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
	    end = start + segPtr->size;
	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;
		offset = TkUtfToUniChar(p, &ch);
		index += offset;
	    }
	} else {
	    if (charIndex < (int)segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }
	    charIndex -= segPtr->size;
	    index += segPtr->size;
	}
    }







|



|







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
	    end = start + segPtr->size;
	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;
		offset = Tcl_UtfToUniChar(p, &ch);
		index += offset;
	    }
	} else {
	    if (charIndex < segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }
	    charIndex -= segPtr->size;
	    index += segPtr->size;
	}
    }
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexToSeg(
    const TkTextIndex *indexPtr,/* Text index. */
    TkSizeT *offsetPtr)		/* Where to store offset within segment, or
				 * NULL if offset isn't wanted. */
{
    TkTextSegment *segPtr;
    TkSizeT offset;

    for (offset = indexPtr->byteIndex, segPtr = indexPtr->linePtr->segPtr;
	    offset >= segPtr->size;
	    offset -= segPtr->size, segPtr = segPtr->nextPtr) {
	/* Empty loop body. */
    }
    if (offsetPtr != NULL) {







|
|



|







572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexToSeg(
    CONST TkTextIndex *indexPtr,/* Text index. */
    int *offsetPtr)		/* Where to store offset within segment, or
				 * NULL if offset isn't wanted. */
{
    TkTextSegment *segPtr;
    int offset;

    for (offset = indexPtr->byteIndex, segPtr = indexPtr->linePtr->segPtr;
	    offset >= segPtr->size;
	    offset -= segPtr->size, segPtr = segPtr->nextPtr) {
	/* Empty loop body. */
    }
    if (offsetPtr != NULL) {
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSegToOffset(
    const TkTextSegment *segPtr,/* Segment whose offset is desired. */
    const TkTextLine *linePtr)	/* Line containing segPtr. */
{
    const TkTextSegment *segPtr2;
    int offset = 0;

    for (segPtr2 = linePtr->segPtr; segPtr2 != segPtr;
	    segPtr2 = segPtr2->nextPtr) {
	offset += segPtr2->size;
    }
    return offset;







|
|

|







610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSegToOffset(
    CONST TkTextSegment *segPtr,/* Segment whose offset is desired. */
    CONST TkTextLine *linePtr)	/* Line containing segPtr. */
{
    CONST TkTextSegment *segPtr2;
    int offset = 0;

    for (segPtr2 = linePtr->segPtr; segPtr2 != segPtr;
	    segPtr2 = segPtr2->nextPtr) {
	offset += segPtr2->size;
    }
    return offset;
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
 *---------------------------------------------------------------------------
 */

int
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);
}

/*
 *---------------------------------------------------------------------------







|







704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
 *---------------------------------------------------------------------------
 */

int
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);
}

/*
 *---------------------------------------------------------------------------
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
 */

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;
    TkTextIndex first, last;
    int wantLast, result;
    char c;
    const char *cp;
    Tcl_DString copy;
    int canCache = 0;

    if (sharedPtr == NULL) {
	sharedPtr = textPtr->sharedTextPtr;
    }








|








|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
 */

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;
    TkTextIndex first, last;
    int wantLast, result;
    char c;
    CONST char *cp;
    Tcl_DString copy;
    int canCache = 0;

    if (sharedPtr == NULL) {
	sharedPtr = textPtr->sharedTextPtr;
    }

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801

    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;
	} else if ((p[1] == 'l') && (strncmp(p+1, "last", 4) == 0)) {
	    wantLast = 1;
	    endOfBase = p+5;







|







799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

    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;
	} else if ((p[1] == 'l') && (strncmp(p+1, "last", 4) == 0)) {
	    wantLast = 1;
	    endOfBase = p+5;
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
844
845
846
847
848

	    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;
	}

	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 if (hPtr != NULL) {
		tagName = (const char *)Tcl_GetHashKey(&sharedPtr->tagTable, hPtr);
	    }

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "text doesn't contain any characters tagged with \"%s\"",
		    tagName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_INDEX", tagName,
		    NULL);
	    Tcl_DStringFree(&copy);
	    return TCL_ERROR;
	}
	*indexPtr = search.curIndex;
	if (wantLast) {
	    while (TkBTreeNextTag(&search)) {
		*indexPtr = search.curIndex;







|














|
|

>
|
|
|
<
<







824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852


853
854
855
856
857
858
859

	    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;
	}

	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 \"",
		    tagName, "\"", NULL);


	    Tcl_DStringFree(&copy);
	    return TCL_ERROR;
	}
	*indexPtr = search.curIndex;
	if (wantLast) {
	    while (TkBTreeNextTag(&search)) {
		*indexPtr = search.curIndex;
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
	*endOfBase = c;
	if (result != 0) {
	    goto gotBase;
	}
    }
    if ((string[0] == 'e')
	    && (strncmp(string, "end",
	    endOfBase-Tcl_DStringValue(&copy)) == 0)) {
	/*
	 * Base position is end of text.
	 */

	TkTextMakeByteIndex(sharedPtr->tree, textPtr,
		TkBTreeNumLines(sharedPtr->tree, textPtr), 0, indexPtr);
	canCache = 1;







|







930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
	*endOfBase = c;
	if (result != 0) {
	    goto gotBase;
	}
    }
    if ((string[0] == 'e')
	    && (strncmp(string, "end",
	    (size_t) (endOfBase-Tcl_DStringValue(&copy))) == 0)) {
	/*
	 * Base position is end of text.
	 */

	TkTextMakeByteIndex(sharedPtr->tree, textPtr,
		TkBTreeNumLines(sharedPtr->tree, textPtr), 0, indexPtr);
	canCache = 1;
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
    if (indexPtr->linePtr == NULL) {
	Tcl_Panic("Bad index created");
    }
    return TCL_OK;

  error:
    Tcl_DStringFree(&copy);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad text index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextPrintIndex --







|
|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
    if (indexPtr->linePtr == NULL) {
	Tcl_Panic("Bad index created");
    }
    return TCL_OK;

  error:
    Tcl_DStringFree(&copy);
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "bad text index \"", string, "\"", NULL);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextPrintIndex --
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkSizeT
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;








|

|
|







1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

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;

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
	     * Two logical lines merged into one display line through eliding
	     * of a newline.
	     */

	    linePtr = TkBTreeNextLine(NULL, linePtr);
	    segPtr = linePtr->segPtr;
	}
	if (numBytes <= (int)segPtr->size) {
	    break;
	}
	if (segPtr->typePtr == &tkTextCharType) {
	    charIndex += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size);
	} else {
	    charIndex += segPtr->size;
	}







|







1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
	     * 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;
	}
	if (segPtr->typePtr == &tkTextCharType) {
	    charIndex += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size);
	} else {
	    charIndex += segPtr->size;
	}
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCmp(
    const TkTextIndex*index1Ptr,/* First index. */
    const TkTextIndex*index2Ptr)/* Second index. */
{
    int line1, line2;

    if (index1Ptr->linePtr == index2Ptr->linePtr) {
	if (index1Ptr->byteIndex < index2Ptr->byteIndex) {
	    return -1;
	} else if (index1Ptr->byteIndex > index2Ptr->byteIndex) {







|
|







1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCmp(
    CONST TkTextIndex*index1Ptr,/* First index. */
    CONST TkTextIndex*index2Ptr)/* Second index. */
{
    int line1, line2;

    if (index1Ptr->linePtr == index2Ptr->linePtr) {
	if (index1Ptr->byteIndex < index2Ptr->byteIndex) {
	    return -1;
	} else if (index1Ptr->byteIndex > index2Ptr->byteIndex) {
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static const char *
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. */
{
    const char *p, *units;
    char *end;
    int count, lineIndex, modifier;
    size_t length;

    /*
     * Get the count (how many units forward or backward).
     */







|


|




|







1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static CONST char *
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, modifier;
    size_t length;

    /*
     * Get the count (how many units forward or backward).
     */
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
	    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) {
                    TkTextIndex indexPtr2;

		    /*
		     * 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, &indexPtr2,
			    COUNT_DISPLAY_INDICES);

                    /*
                     * If we couldn't go to the previous line, then we wanted
                       to go before the start of the text: arrange for returning
                       the first index of the first display line.
                     */

                    if (!TkTextIndexCmp(indexPtr, &indexPtr2)) {
                        xOffset = 0;
                        break;
                    }
                    *indexPtr = indexPtr2;
		}
	    }
            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.
	     */








<












<
<






|

|
<
<
<
<
<
|
<
<
<
|
<
<
<
<







1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323


1324
1325
1326
1327
1328
1329
1330
1331
1332





1333



1334




1335
1336
1337
1338
1339
1340
1341
	    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.
	     */

1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
 *	None.
 *
 *---------------------------------------------------------------------------
 */

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. */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    int lineLength;







|
|







1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
 *	None.
 *
 *---------------------------------------------------------------------------
 */

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. */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    int lineLength;
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502

1503
1504
1505
1506
1507
1508
1509
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
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;
    TkSizeT byteOffset;
    char *start, *end, *p;
    int ch;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
	return;
    }
    if (checkElided) {
	infoPtr = (TkTextElideInfo *)ckalloc(sizeof(TkTextElideInfo));

	elide = TkTextIsElided(textPtr, srcPtr, infoPtr);
    }

    *dstPtr = *srcPtr;

    /*
     * Find seg that contains src byteIndex. Move forward specified number of







|
|








|

|








|
>







1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
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(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
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
		}
	    }

	    if (!elide) {
		if (segPtr->typePtr == &tkTextCharType) {
		    start = segPtr->body.chars + byteOffset;
		    end = segPtr->body.chars + segPtr->size;
		    for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) {
			if (charCount == 0) {
			    dstPtr->byteIndex += (p - start);
			    goto forwardCharDone;
			}
			charCount--;
		    }
		} else if (type & COUNT_INDICES) {
		    if (charCount + byteOffset < segPtr->size) {
			dstPtr->byteIndex += charCount;
			goto forwardCharDone;
		    }
		    charCount -= segPtr->size - byteOffset;
		}
	    }








|







|







1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
		}
	    }

	    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;
		}
	    }

1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
	dstPtr->byteIndex = 0;
	segPtr = dstPtr->linePtr->segPtr;
    }

  forwardCharDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree(infoPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCountBytes --







|







1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
	dstPtr->byteIndex = 0;
	segPtr = dstPtr->linePtr->segPtr;
    }

  forwardCharDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree((char *) infoPtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCountBytes --
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCountBytes(
    const TkText *textPtr,
    const TkTextIndex *indexPtr1, /* Index describing one location. */
    const TkTextIndex *indexPtr2) /* Index describing second location. */
{
    int compare = TkTextIndexCmp(indexPtr1, indexPtr2);

    if (compare == 0) {
	return 0;
    } else if (compare > 0) {
	return IndexCountBytesOrdered(textPtr, indexPtr2, indexPtr1);
    } else {
	return IndexCountBytesOrdered(textPtr, indexPtr1, indexPtr2);
    }
}

static int
IndexCountBytesOrdered(
    const TkText *textPtr,
    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. */
{
    TkSizeT byteCount, offset;
    TkTextSegment *segPtr, *segPtr1;
    TkTextLine *linePtr;

    if (indexPtr1->linePtr == indexPtr2->linePtr) {
        return indexPtr2->byteIndex - indexPtr1->byteIndex;
    }








|
|
|














|
|


|



|







1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCountBytes(
    CONST TkText *textPtr,
    CONST TkTextIndex *indexPtr1, /* Index describing one location. */
    CONST TkTextIndex *indexPtr2) /* Index describing second location. */
{
    int compare = TkTextIndexCmp(indexPtr1, indexPtr2);

    if (compare == 0) {
	return 0;
    } else if (compare > 0) {
	return IndexCountBytesOrdered(textPtr, indexPtr2, indexPtr1);
    } else {
	return IndexCountBytesOrdered(textPtr, indexPtr1, indexPtr2);
    }
}

static int
IndexCountBytesOrdered(
    CONST TkText *textPtr,
    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. */
{
    int byteCount, offset;
    TkTextSegment *segPtr, *segPtr1;
    TkTextLine *linePtr;

    if (indexPtr1->linePtr == indexPtr2->linePtr) {
        return indexPtr2->byteIndex - indexPtr1->byteIndex;
    }

1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
 *	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;
    TkSizeT byteOffset, maxBytes, count = 0;
    int 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(sizeof(TkTextElideInfo));

	elide = TkTextIsElided(textPtr, indexPtr1, infoPtr);
    }

    while (1) {
	/*
	 * Go through each segment in line adding up the number of characters.
	 */







|
|


|







|
<













|
>







1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
 *	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.
	 */
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
		    }
		    byteOffset = 0;
		    continue;
		}
	    }

	    if (segPtr->typePtr == &tkTextCharType) {
		TkSizeT byteLen = segPtr->size - byteOffset;
		unsigned char *str = (unsigned char *)
			segPtr->body.chars + byteOffset;
		TkSizeT i;

		if (segPtr == seg2Ptr) {
		    if (byteLen + byteOffset > maxBytes) {
			byteLen = maxBytes - byteOffset;
		    }
		}
		i = byteLen;

		/*
		 * This is a speed sensitive function, so run specially over







|
|

|


|







1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
		    }
		    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
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
		count += byteLen - i;
		if (i) {
		    count += Tcl_NumUtfChars(segPtr->body.chars + byteOffset
			    + (byteLen - i), i);
		}
	    } else {
		if (type & COUNT_INDICES) {
		    TkSizeT byteLen = segPtr->size - byteOffset;

		    if (segPtr == seg2Ptr) {
			if (byteLen + byteOffset > maxBytes) {
			    byteLen = maxBytes - byteOffset;
			}
		    }
		    count += byteLen;
		}
	    }
	    if (segPtr == seg2Ptr) {







|


|







1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
		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) {
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
	}
	segPtr = linePtr1->segPtr;
    }

  countDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree(infoPtr);
    }
    return count;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexBackBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" bytes earlier than the source index.







|



|







1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
	}
	segPtr = linePtr1->segPtr;
    }

  countDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree((char *) infoPtr);
    }
    return count;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexBackBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" bytes earlier than the source index.
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
 *	None.
 *
 *---------------------------------------------------------------------------
 */

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. */
{
    TkTextSegment *segPtr;
    int lineIndex;








|
|







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
 *	None.
 *
 *---------------------------------------------------------------------------
 */

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. */
{
    TkTextSegment *segPtr;
    int lineIndex;

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
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(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







|
|








|








|







2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
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(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
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
		 * Two logical lines merged into one display line through
		 * eliding of a newline.
		 */

		linePtr = TkBTreeNextLine(NULL, linePtr);
		segPtr = linePtr->segPtr;
	    }
	    if (segSize <= (int)segPtr->size) {
		break;
	    }
	    segSize -= segPtr->size;
	}
    }

    /*







|







2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
		 * 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;
	}
    }

    /*
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
	    }
	}

	if (!elide) {
	    if (segPtr->typePtr == &tkTextCharType) {
		start = segPtr->body.chars;
		end = segPtr->body.chars + segSize;
		for (p = end; ; p = TkUtfPrev(p, start)) {
		    if (charCount == 0) {
			dstPtr->byteIndex -= (end - p);
			goto backwardCharDone;
		    }
		    if (p == start) {
			break;
		    }







|







2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
	    }
	}

	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;
		    }
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
	segPtr = oldPtr;
	segSize = segPtr->size;
    }

  backwardCharDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree(infoPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * StartEnd --







|







2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
	segPtr = oldPtr;
	segSize = segPtr->size;
    }

  backwardCharDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree((char *) infoPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * StartEnd --
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const char *
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 modifier word. */
    TkTextIndex *indexPtr)	/* Index to modify based on string. */
{
    const char *p;
    size_t length;
    TkTextSegment *segPtr;
    int modifier;

    /*
     * Find the end of the modifier word.
     */

    for (p = string; isalnum(UCHAR(*p)); p++) {







|


|




|

|







2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static CONST char *
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 modifier word. */
    TkTextIndex *indexPtr)	/* Index to modify based on string. */
{
    CONST char *p;
    size_t length;
    register TkTextSegment *segPtr;
    int modifier;

    /*
     * Find the end of the modifier word.
     */

    for (p = string; isalnum(UCHAR(*p)); p++) {
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
	    TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
	} else {
	    indexPtr->byteIndex = 0;
	}
    } else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0)
	    && (length >= 5)) {
	int firstChar = 1;
	TkSizeT 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.
	 */

	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) {
		int ch;

		chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch);
		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		firstChar = 0;
	    }
	    offset += chSize;
	    indexPtr->byteIndex += chSize;







|
















|

|







2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
	    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.
	 */

	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) {
		Tcl_UniChar ch;

		chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch);
		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		firstChar = 0;
	    }
	    offset += chSize;
	    indexPtr->byteIndex += chSize;
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361

2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
		TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
			COUNT_INDICES);
	    }
	}
    } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0)
	    && (length >= 5)) {
	int firstChar = 1;
	TkSizeT offset;

	if (modifier == TKINDEX_DISPLAY) {
	    TkTextIndexForwChars(textPtr, 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.
	 */

	segPtr = TkTextIndexToSeg(indexPtr, &offset);
	while (1) {
	    int chSize = 1;

	    if (segPtr->typePtr == &tkTextCharType) {


		int ch;
		TkUtfToUniChar(segPtr->body.chars + offset, &ch);
		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		if (offset + 1 > 1) {
		    chSize = (segPtr->body.chars + offset
			    - TkUtfPrev(segPtr->body.chars + offset,
			    segPtr->body.chars));
		}
		firstChar = 0;
	    }
            if (offset == 0) {
                if (modifier == TKINDEX_DISPLAY) {
                    TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr,
                        COUNT_DISPLAY_INDICES);
                } else {
                    TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr,
                        COUNT_INDICES);
                }
            } else {
                indexPtr->byteIndex -= chSize;
            }
            offset -= chSize;
	    if ((int)offset < 0) {
		if (indexPtr->byteIndex == 0) {
		    goto done;
		}
		segPtr = TkTextIndexToSeg(indexPtr, &offset);
	    }
	}








|


















>

<
|



|

|
















|







2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
		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(textPtr, 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.
	 */

	segPtr = TkTextIndexToSeg(indexPtr, &offset);
	while (1) {
	    int chSize = 1;

	    if (segPtr->typePtr == &tkTextCharType) {
		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;
	    }
            if (offset == 0) {
                if (modifier == TKINDEX_DISPLAY) {
                    TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr,
                        COUNT_DISPLAY_INDICES);
                } else {
                    TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr,
                        COUNT_INDICES);
                }
            } else {
                indexPtr->byteIndex -= chSize;
            }
            offset -= chSize;
	    if (offset < 0) {
		if (indexPtr->byteIndex == 0) {
		    goto done;
		}
		segPtr = TkTextIndexToSeg(indexPtr, &offset);
	    }
	}

Changes to generic/tkTextMark.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 *
 * 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 "tk3d.h"

/*
 * Macro that determines the size of a mark segment:
 */

#define MSEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextMark))

/*
 * Forward references for functions defined in this file:
 */

static Tcl_Obj *	GetMarkName(TkText *textPtr, TkTextSegment *segPtr);
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, TkSizeT offset, int maxX,
			    TkSizeT maxChars, int noCharsYet, TkWrapMode wrapMode,
			    TkTextDispChunk *chunkPtr);
static int		MarkFindNext(Tcl_Interp *interp,
			    TkText *textPtr, Tcl_Obj *markName);
static int		MarkFindPrev(Tcl_Interp *interp,
			    TkText *textPtr, Tcl_Obj *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.
 */







<





|
|





<









|
|


|

|







9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 *
 * 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"


/*
 * Macro that determines the size of a mark segment:
 */

#define MSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
	+ sizeof(TkTextMark)))

/*
 * Forward references for functions defined in this file:
 */


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.
 */
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextMarkCmd(
    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
				 * objv[1] is "mark". */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *markPtr;
    Tcl_HashSearch search;
    TkTextIndex index;
    const Tk_SegType *newTypePtr;
    int optionIndex;
    static const char *const 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 ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], markOptionStrings,
	    sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum markOptions) optionIndex) {
    case MARK_GRAVITY: {
	char c;
	TkSizeT length;
	const char *str;

	if (objc < 4 || objc > 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(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_SetObjResult(interp, Tcl_ObjPrintf(
			"there is no mark named \"%s\"", str));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_MARK", str,
			NULL);
		return TCL_ERROR;
	    }
	    markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	}
	if (objc == 4) {
	    const char *typeStr;

	    if (markPtr->typePtr == &tkTextRightMarkType) {
		typeStr = "right";
	    } else {
		typeStr = "left";
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
	    return TCL_OK;
	}
	str = TkGetStringFromObj(objv[4],&length);
	c = str[0];
	if ((c == 'l') && (strncmp(str, "left", length) == 0)) {
	    newTypePtr = &tkTextLeftMarkType;
	} else if ((c == 'r') &&
		(strncmp(str, "right", length) == 0)) {
	    newTypePtr = &tkTextRightMarkType;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad mark gravity \"%s\": must be left or right", str));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_GRAVITY", NULL);
	    return TCL_ERROR;
	}
	TkTextMarkSegToIndex(textPtr, markPtr, &index);
	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
	markPtr->typePtr = newTypePtr;
	TkBTreeLinkSegment(markPtr, &index);
	break;
    }
    case MARK_NAMES: {
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		"insert", -1));
	Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		"current", -1));
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->markTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    case MARK_NEXT:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	return MarkFindNext(interp, textPtr, objv[3]);
    case MARK_PREVIOUS:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	return MarkFindPrev(interp, textPtr, objv[3]);
    case MARK_SET:
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName index");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[4], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	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(markPtr, markPtr->body.mark.linePtr);
		Tcl_DeleteHashEntry(hPtr);
		ckfree(markPtr);
	    }
	}
	break;
    }
    }
    return TCL_OK;
}







|












|








|


|
|






|
|





|







<
|
<
|


|


<
<

|

|

<


|

|


|


|
|
<








|
<
<




<
<
|
<
|


|
|
<

<

<





|





|

















|











|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142

143
144
145
146
147
148


149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174


175
176
177
178


179

180
181
182
183
184

185

186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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
				 * objv[1] is "mark". */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *markPtr;
    Tcl_HashSearch search;
    TkTextIndex index;
    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;
    }

    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;
	}
	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);
	}
	if (objc == 4) {


	    if (markPtr->typePtr == &tkTextRightMarkType) {
		Tcl_SetResult(interp, "right", TCL_STATIC);
	    } else {
		Tcl_SetResult(interp, "left", TCL_STATIC);
	    }

	    return TCL_OK;
	}
	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(str, "right", (unsigned)length) == 0)) {
	    newTypePtr = &tkTextRightMarkType;
	} else {
	    Tcl_AppendResult(interp, "bad mark gravity \"", str,
		    "\": must be left or right", NULL);

	    return TCL_ERROR;
	}
	TkTextMarkSegToIndex(textPtr, markPtr, &index);
	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
	markPtr->typePtr = newTypePtr;
	TkBTreeLinkSegment(markPtr, &index);
	break;
    }
    case MARK_NAMES:


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}


	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->sharedTextPtr->markTable, hPtr));

	}

	break;

    case MARK_NEXT:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	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, Tcl_GetString(objv[3]));
    case MARK_SET:
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName index");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[4], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	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(markPtr, markPtr->body.mark.linePtr);
		Tcl_DeleteHashEntry(hPtr);
		ckfree((char *) markPtr);
	    }
	}
	break;
    }
    }
    return TCL_OK;
}
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
	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 (markPtr == textPtr->insertMarkPtr) {
	    TkTextIndex index, index2;
            int nblines;

	    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	    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);







|













|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
	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 (markPtr == textPtr->insertMarkPtr) {
	    TkTextIndex index, index2;
            int nblines;

	    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	    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);
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
		TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,
			COUNT_INDICES);
		indexPtr = &insertIndex;
	    }
	}
	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
    } else {
	markPtr = (TkTextSegment *)ckalloc(MSEG_SIZE);
	markPtr->typePtr = &tkTextRightMarkType;
	markPtr->size = 0;
	markPtr->body.mark.textPtr = textPtr;
	markPtr->body.mark.linePtr = indexPtr->linePtr;
	markPtr->body.mark.hPtr = hPtr;
	if (widgetSpecific == 0) {
	    Tcl_SetHashValue(hPtr, markPtr);







|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
		TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,
			COUNT_INDICES);
		indexPtr = &insertIndex;
	    }
	}
	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
    } else {
	markPtr = (TkTextSegment *) ckalloc(MSEG_SIZE);
	markPtr->typePtr = &tkTextRightMarkType;
	markPtr->size = 0;
	markPtr->body.mark.textPtr = textPtr;
	markPtr->body.mark.linePtr = indexPtr->linePtr;
	markPtr->body.mark.hPtr = hPtr;
	if (widgetSpecific == 0) {
	    Tcl_SetHashValue(hPtr, markPtr);
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
     * If the mark is the insertion cursor, then update the screen at the
     * mark's new location.
     */

    if (markPtr == textPtr->insertMarkPtr) {
	TkTextIndex 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);







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
     * If the mark is the insertion cursor, then update the screen at the
     * mark's new location.
     */

    if (markPtr == textPtr->insertMarkPtr) {
	TkTextIndex 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);
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
    }

    if (!strcmp(name, "insert")) {
	segPtr = textPtr->insertMarkPtr;
    } else if (!strcmp(name, "current")) {
	segPtr = textPtr->currentMarkPtr;
    } else {
	Tcl_HashEntry *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).







|
|
<



|







426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
    }

    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).
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510
511
512
513
 * Side effects:
 *	None (even if the whole tree is being deleted we don't free up the
 *	mark; it will be done elsewhere).
 *
 *--------------------------------------------------------------
 */


static int
MarkDeleteProc(
    TCL_UNUSED(TkTextSegment *),	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    return 1;
}

/*







>


|
|
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
 * Side effects:
 *	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(
    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;
}

/*
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
 *
 *--------------------------------------------------------------
 */

static int
MarkLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *segPtr,	/* Segment corresponding to indexPtr. */
    TCL_UNUSED(TkSizeT),		/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    TCL_UNUSED(int),			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),		/* Chunk must not include more than this many
				 * characters. */
    TCL_UNUSED(int),		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Not used. */
    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;
    }







|

|

|

|

|

|
|







538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
 *
 *--------------------------------------------------------------
 */

static int
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
				 * position or higher. */
    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. */
{
    if (segPtr != textPtr->insertMarkPtr) {
	return -1;
    }
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

    /*
     * 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;
    chunkPtr->clientData = textPtr;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextInsertDisplayProc --
 *
 *	This function is called to display the insertion cursor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */


void
TkTextInsertDisplayProc(
    TkText *textPtr,		/* The current text widget. */
    TCL_UNUSED(TkTextDispChunk *),	/* 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. */
    TCL_UNUSED(int),		/* Offset of baseline from y. */
    TCL_UNUSED(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. */
{
    /*
     * We have no need for the clientData.
     */

    /* TkText *textPtr = 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;
    }








|



















>



|






|
|








|





|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

    /*
     * 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;
    chunkPtr->clientData = (ClientData) textPtr;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextInsertDisplayProc --
 *
 *	This function is called to display the insertion cursor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
void
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. */
{
    /*
     * 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;
    }

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732
     * 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 & GOT_FOCUS) {
	if (textPtr->flags & INSERT_ON) {
	    Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		    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, charWidth + textPtr->insertWidth,
		    height, 0, TK_RELIEF_FLAT);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_HOLLOW) {
	if (textPtr->insertBorderWidth < 1) {
	    /*
	     * Hack to work around the fact that a "solid" border always
	     * paints in black.
	     */

	    TkBorder *borderPtr = (TkBorder *) textPtr->insertBorder;

	    XDrawRectangle(Tk_Display(textPtr->tkwin), dst, borderPtr->bgGC,
		    x - halfWidth, y, charWidth + textPtr->insertWidth - 1,
		    height - 1);
	} else {
	    Tk_Draw3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		    x - halfWidth, y, charWidth + textPtr->insertWidth,
		    height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) {
	Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		x - halfWidth, y, charWidth + textPtr->insertWidth, height,
		textPtr->insertBorderWidth, TK_RELIEF_RAISED);
    }
}

/*
 *--------------------------------------------------------------
 *
 * InsertUndisplayProc --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static void
InsertUndisplayProc(
    TCL_UNUSED(TkText *),		/* Overall information about text widget. */
    TCL_UNUSED(TkTextDispChunk *))	/* Chunk that is about to be freed. */
{
    return;
}

/*
 *--------------------------------------------------------------
 *







<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















>


|
|







649
650
651
652
653
654
655

656
657
658
659
660
661
662
663






















664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
     * 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, 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, charWidth + textPtr->insertWidth, height,
		0, TK_RELIEF_FLAT);






















    }
}

/*
 *--------------------------------------------------------------
 *
 * InsertUndisplayProc --
 *
 *	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.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
InsertUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    return;
}

/*
 *--------------------------------------------------------------
 *
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860


861












862

863
864

865
866
867
868
869
870
871
 *--------------------------------------------------------------
 */

static int
MarkFindNext(
    Tcl_Interp *interp,		/* For error reporting */
    TkText *textPtr,		/* The widget */
    Tcl_Obj *obj)			/* The starting index or mark name */
{
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextSegment *segPtr;
    int offset;
    const char *string = Tcl_GetString(obj);

    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 {
	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 (TkTextGetObjIndex(interp, textPtr, obj, &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.
	 */

	for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextRightMarkType ||
		    segPtr->typePtr == &tkTextLeftMarkType) {
		Tcl_Obj *markName = GetMarkName(textPtr, segPtr);



		if (markName != NULL) {












		    Tcl_SetObjResult(interp, markName);

		    return TCL_OK;
		}

	    }
	}
	index.linePtr = TkBTreeNextLine(textPtr, index.linePtr);
	if (index.linePtr == NULL) {
	    return TCL_OK;
	}
	index.byteIndex = 0;







|



|

<


















|








|



















|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|

>







761
762
763
764
765
766
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
 *--------------------------------------------------------------
 */

static int
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;


    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 {
	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.
	 */

	for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextRightMarkType ||
		    segPtr->typePtr == &tkTextLeftMarkType) {
		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(textPtr, index.linePtr);
	if (index.linePtr == NULL) {
	    return TCL_OK;
	}
	index.byteIndex = 0;
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
 *--------------------------------------------------------------
 */

static int
MarkFindPrev(
    Tcl_Interp *interp,		/* For error reporting */
    TkText *textPtr,		/* The widget */
    Tcl_Obj *obj)			/* The starting index or mark name */
{
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextSegment *segPtr, *seg2Ptr, *prevPtr;
    int offset;
    const char *string = Tcl_GetString(obj);

    if (!strcmp(string, "insert")) {
	segPtr = textPtr->insertMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else if (!strcmp(string, "current")) {
	segPtr = textPtr->currentMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else {
	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 (TkTextGetObjIndex(interp, textPtr, obj, &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 */
	    }







|



|

<
















|







|







867
868
869
870
871
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
 *--------------------------------------------------------------
 */

static int
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;


    if (!strcmp(string, "insert")) {
	segPtr = textPtr->insertMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else if (!strcmp(string, "current")) {
	segPtr = textPtr->currentMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else {
	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 */
	    }
956
957
958
959
960
961
962
963
964




965











966


967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
                        continue;
                    }
	        }
		prevPtr = seg2Ptr;
	    }
	}
	if (prevPtr != NULL) {
	    Tcl_Obj *markName = GetMarkName(textPtr, prevPtr);





	    if (markName != NULL) {











		Tcl_SetObjResult(interp, markName);


		return TCL_OK;
	    }
	}
	index.linePtr = TkBTreePreviousLine(textPtr, index.linePtr);
	if (index.linePtr == NULL) {
	    return TCL_OK;
	}
	segPtr = NULL;
    }
}

/*
 * ------------------------------------------------------------------------
 *
 * GetMarkName --
 *	Returns the name of the mark that is the given text segment, or NULL
 *	if it is unnamed (i.e., a widget-specific mark that isn't "current" or
 *	"insert").
 *
 * ------------------------------------------------------------------------
 */

static Tcl_Obj *
GetMarkName(
    TkText *textPtr,
    TkTextSegment *segPtr)
{
    const char *markName;

    if (segPtr == textPtr->currentMarkPtr) {
	markName = "current";
    } else if (segPtr == textPtr->insertMarkPtr) {
	markName = "insert";
    } 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.
	 */

	return NULL;
    } else {
	markName = (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable,
		segPtr->body.mark.hPtr);
    }
    return Tcl_NewStringObj(markName, -1);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970








































971
972
973
974
975
976
977
978
                        continue;
                    }
	        }
		prevPtr = seg2Ptr;
	    }
	}
	if (prevPtr != NULL) {
	    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(textPtr, index.linePtr);
	if (index.linePtr == NULL) {
	    return TCL_OK;
	}
	segPtr = NULL;
    }
}









































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkTextTag.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 * 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.
 */

#include "tkInt.h"
#include "tkText.h"
#include "default.h"

/*
 * 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 *const wrapStrings[] = {
    "char", "none", "word", "", NULL
};

/*
 * 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 tabstyle value, but the
 * widget as a whole is not.
 */

static const char *const tabStyleStrings[] = {
    "tabular", "wordprocessor", "", NULL
};

static const Tk_OptionSpec tagOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
	NULL, offsetof(TkTextTag, borderWidthPtr), offsetof(TkTextTag, borderWidth),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_STRING, "-elide", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, elideString),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-justify", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0,0},
    {TK_OPTION_STRING, "-lmargin1", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-lmargin2", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-offset", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-overstrike", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrikeString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrikeColor),
        TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-relief", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-rmargin", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0},
    {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-spacing1", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-spacing2", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing2String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-spacing3", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-tabs", NULL, NULL,
	NULL, offsetof(TkTextTag, tabStringPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tabStyle),
	TK_OPTION_NULL_OK, tabStyleStrings, 0},
    {TK_OPTION_STRING, "-underline", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-underlinefg", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineColor),
        TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, wrapMode),
	TK_OPTION_NULL_OK, wrapStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * 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 --
 *







|
|
|








|






|



|





|

|

|


|


|

|

|

|

|

|
<
<

|

|

<
<
<

|

|
<
<
<
<
<
<

|

|

|

|

|
|

|

<
<
<

|
|
|











|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68



69
70
71
72






73
74
75
76
77
78
79
80
81
82
83
84
85
86



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 * 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.
 */

#include "default.h"
#include "tkInt.h"
#include "tkText.h"

/*
 * 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
};

/*
 * 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 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,
	NULL, Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_STRING, "-elide", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, elideString),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 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 --
 *
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextTagCmd(
    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
				 * objv[1] is "tag". */
{
    static const char *const 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;
    TkTextTag *tagPtr;
    TkTextIndex index1, index2;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], tagOptionStrings,
	    sizeof(char *), "tag option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum tagOptions)optionIndex) {
    case TAG_ADD:
    case TAG_REMOVE: {
	int addTag;







|


|



|









|



|



|
|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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
				 * objv[1] is "tag". */
{
    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 index1, index2;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings,
	    "tag option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum tagOptions)optionIndex) {
    case TAG_ADD:
    case TAG_REMOVE: {
	int addTag;
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
		 * textPtr (not for other peer widget's "sel" tags) because we
		 * cannot reach this code path with a different widget's "sel"
		 * tag.
		 */

		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
			    && (!Tcl_IsSafe(textPtr->interp))
			    && !(textPtr->flags & GOT_SELECTION)) {
			Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
				TkTextLostSelection, textPtr);
			textPtr->flags |= GOT_SELECTION;
		    }
		    textPtr->abortSelections = 1;
		}
	    }
	}
	break;







|







<


|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
		 * textPtr (not for other peer widget's "sel" tags) because we
		 * cannot reach this code path with a different widget's "sel"
		 * tag.
		 */

		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;
		}
	    }
	}
	break;
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
	    textPtr->sharedTextPtr->bindingTable =
		    Tk_CreateBindingTable(interp);
	}

	if (objc == 6) {
	    int append = 0;
	    unsigned long mask;
	    const char *fifth = Tcl_GetString(objv[5]);

	    if (fifth[0] == 0) {
		return Tk_DeleteBinding(interp,
			textPtr->sharedTextPtr->bindingTable,
			(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    }
	    if (fifth[0] == '+') {
		fifth++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]), fifth,
		    append);
	    if (mask == 0) {
		return TCL_ERROR;
	    }
	    if (mask & ~(unsigned long)(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable,
			(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"requested illegal events; only key, button, motion,"
			" enter, leave, and virtual events may be used", -1));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "TAG_BIND_EVENT",NULL);
		return TCL_ERROR;
	    }
	} else if (objc == 5) {
	    const char *command;

	    command = Tk_GetBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    if (command == NULL) {
		const char *string = Tcl_GetString(Tcl_GetObjResult(interp));

		/*
		 * Ignore missing binding errors. This is a special hack that
		 * relies on the error message returned by FindSequence in
		 * tkBind.c.
		 */

		if (string[0] != '\0') {
		    return TCL_ERROR;
		}
		Tcl_ResetResult(interp);
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
	    }
	} else {
	    Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name);
	}
	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, tagPtr,
		    tagPtr->optionTable, objv[4], textPtr->tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	break;
    case TAG_CONFIGURE: {
	int newTag;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv,
		    "tagName ?-option value ...?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag);
	if (objc <= 5) {
	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, 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 = TCL_OK;

	    if (Tk_SetOptions(interp, tagPtr, tagPtr->optionTable,
		    objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) {
		return TCL_ERROR;
	    }

	    /*
	     * Some of the configuration options, like -underline and
	     * -justify, require additional translation (this is needed







|

















|






|
|
|
|



|





|












|

















|













|




|











|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
	    textPtr->sharedTextPtr->bindingTable =
		    Tk_CreateBindingTable(interp);
	}

	if (objc == 6) {
	    int append = 0;
	    unsigned long mask;
	    char *fifth = Tcl_GetString(objv[5]);

	    if (fifth[0] == 0) {
		return Tk_DeleteBinding(interp,
			textPtr->sharedTextPtr->bindingTable,
			(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    }
	    if (fifth[0] == '+') {
		fifth++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]), fifth,
		    append);
	    if (mask == 0) {
		return TCL_ERROR;
	    }
	    if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		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", NULL);
		return TCL_ERROR;
	    }
	} else if (objc == 5) {
	    CONST char *command;

	    command = Tk_GetBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    if (command == NULL) {
		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.
		 */

		if (string[0] != '\0') {
		    return TCL_ERROR;
		}
		Tcl_ResetResult(interp);
	    } else {
		Tcl_SetResult(interp, (char *) command, TCL_STATIC);
	    }
	} else {
	    Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name);
	}
	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;
	}
	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, 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 = TCL_OK;

	    if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable,
		    objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) {
		return TCL_ERROR;
	    }

	    /*
	     * Some of the configuration options, like -underline and
	     * -justify, require additional translation (this is needed
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
		    return TCL_ERROR;
		}
		if (tagPtr->spacing3 < 0) {
		    tagPtr->spacing3 = 0;
		}
	    }
	    if (tagPtr->tabArrayPtr != NULL) {
		ckfree(tagPtr->tabArrayPtr);
		tagPtr->tabArrayPtr = NULL;
	    }
	    if (tagPtr->tabStringPtr != NULL) {
		tagPtr->tabArrayPtr =
			TkTextGetTabs(interp, textPtr, tagPtr->tabStringPtr);
		if (tagPtr->tabArrayPtr == NULL) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->underlineString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->underlineString,
			&tagPtr->underline) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->elideString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->elideString,
			&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.
	     */

	    if (tagPtr == textPtr->selTagPtr) {
                if (tagPtr->selBorder == NULL) {
                    textPtr->selBorder = tagPtr->border;
                } else {
                    textPtr->selBorder = tagPtr->selBorder;
                }
		textPtr->selBorderWidth = tagPtr->borderWidth;
		textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr;
                if (tagPtr->selFgColor == NULL) {
                    textPtr->selFgColorPtr = tagPtr->fgColor;
                } else {
                    textPtr->selFgColorPtr = tagPtr->selFgColor;
                }
	    }

	    tagPtr->affectsDisplay = 0;
	    tagPtr->affectsDisplayGeometry = 0;
	    if ((tagPtr->elideString != NULL)
		    || (tagPtr->tkfont != NULL)
		    || (tagPtr->justifyString != NULL)







|




















<
<
|
|
|
|
<
|











<
|
<
<
<


<
|
<
<
<







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467


468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483

484



485
486

487



488
489
490
491
492
493
494
		    return TCL_ERROR;
		}
		if (tagPtr->spacing3 < 0) {
		    tagPtr->spacing3 = 0;
		}
	    }
	    if (tagPtr->tabArrayPtr != NULL) {
		ckfree((char *) tagPtr->tabArrayPtr);
		tagPtr->tabArrayPtr = NULL;
	    }
	    if (tagPtr->tabStringPtr != NULL) {
		tagPtr->tabArrayPtr =
			TkTextGetTabs(interp, textPtr, tagPtr->tabStringPtr);
		if (tagPtr->tabArrayPtr == NULL) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->underlineString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->underlineString,
			&tagPtr->underline) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->elideString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->elideString,
			&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.
	     */

	    if (tagPtr == textPtr->selTagPtr) {

		textPtr->selBorder = tagPtr->border;



		textPtr->selBorderWidth = tagPtr->borderWidth;
		textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr;

		textPtr->selFgColorPtr = tagPtr->fgColor;



	    }

	    tagPtr->affectsDisplay = 0;
	    tagPtr->affectsDisplayGeometry = 0;
	    if ((tagPtr->elideString != NULL)
		    || (tagPtr->tkfont != NULL)
		    || (tagPtr->justifyString != NULL)
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
		    || (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->selBorder != NULL)
		    || (tagPtr->reliefString != NULL)
		    || (tagPtr->bgStipple != None)
		    || (tagPtr->fgColor != NULL)
		    || (tagPtr->selFgColor != NULL)
		    || (tagPtr->fgStipple != None)
		    || (tagPtr->overstrikeString != NULL)
                    || (tagPtr->overstrikeColor != NULL)
		    || (tagPtr->underlineString != NULL)
                    || (tagPtr->underlineColor != NULL)
                    || (tagPtr->lMarginColor != NULL)
                    || (tagPtr->rMarginColor != 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.
		 */







<



<


<
|
<
<
<







502
503
504
505
506
507
508

509
510
511

512
513

514



515
516
517
518
519
520
521
		    || (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.
		 */
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
		 * 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);
	    if (tagPtr == textPtr->selTagPtr) {
		continue;
	    }
	    if (tagPtr->affectsDisplay) {
		TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
			NULL, NULL, tagPtr, 1);
	    }







|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
		 * 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);
	    if (tagPtr == textPtr->selTagPtr) {
		continue;
	    }
	    if (tagPtr->affectsDisplay) {
		TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
			NULL, NULL, tagPtr, 1);
	    }
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
	    Tcl_WrongNumArgs(interp, 3, objv, "?index?");
	    return TCL_ERROR;
	}
	if (objc == 3) {
	    Tcl_HashSearch search;
	    Tcl_HashEntry *hPtr;

	    arrayPtr = (TkTextTag **)ckalloc(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);
	    }

	    /*
	     * The 'sel' tag is not in the hash table.
	     */

	    arrayPtr[i] = textPtr->selTagPtr;







|
|



|







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
	    Tcl_WrongNumArgs(interp, 3, objv, "?index?");
	    return TCL_ERROR;
	}
	if (objc == 3) {
	    Tcl_HashSearch search;
	    Tcl_HashEntry *hPtr;

	    arrayPtr = (TkTextTag **) ckalloc((unsigned)
		    (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);
	    }

	    /*
	     * The 'sel' tag is not in the hash table.
	     */

	    arrayPtr[i] = textPtr->selTagPtr;
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

	for (i = 0; i < arraySize; i++) {
	    tagPtr = arrayPtr[i];
	    Tcl_ListObjAppendElement(interp, listObj,
		    Tcl_NewStringObj(tagPtr->name,-1));
	}
	Tcl_SetObjResult(interp, listObj);
	ckfree(arrayPtr);
	break;
    }
    case TAG_NEXTRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {







|






<







643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663

	for (i = 0; i < arraySize; i++) {
	    tagPtr = arrayPtr[i];
	    Tcl_ListObjAppendElement(interp, listObj,
		    Tcl_NewStringObj(tagPtr->name,-1));
	}
	Tcl_SetObjResult(interp, listObj);
	ckfree((char *) arrayPtr);
	break;
    }
    case TAG_NEXTRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position[TK_POS_CHARS];


	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
	    return TCL_OK;
	}

    gotStart:
	if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) {
	    return TCL_OK;
	}
	resultObj = Tcl_NewObj();
	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position, -1));
	TkBTreeNextTag(&tSearch);
	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position, -1));
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    case TAG_PREVRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position1[TK_POS_CHARS];
	char position2[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {







<

|
<


|
<
<







<







718
719
720
721
722
723
724

725
726

727
728
729


730
731
732
733
734
735
736

737
738
739
740
741
742
743
	    return TCL_OK;
	}

    gotStart:
	if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) {
	    return TCL_OK;
	}

	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_AppendElement(interp, position);

	TkBTreeNextTag(&tSearch);
	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_AppendElement(interp, position);


	break;
    }
    case TAG_PREVRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position1[TK_POS_CHARS];
	char position2[TK_POS_CHARS];


	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {
815
816
817
818
819
820
821
822

823
824
825
826
827
828
829
		/*
		 * 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);
		goto gotPrevIndexPair;

	    }
	    return TCL_OK;
	}

	if (tSearch.segPtr->typePtr == &tkTextToggleOnType) {
	    TkTextPrintIndex(textPtr, &tSearch.curIndex, position1);
	    if (textPtr->start != NULL) {







|
>







777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
		/*
		 * 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(textPtr, &tSearch.curIndex, position1);
	    if (textPtr->start != NULL) {
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
		    /* It's ok */
		    TkTextPrintIndex(textPtr, &index2, position1);
		} else {
		    return TCL_OK;
		}
	    }
	}

    gotPrevIndexPair:
	resultObj = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position1, -1));
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position2, -1));
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    case TAG_RAISE: {
	TkTextTag *tagPtr2;
	int prio;

	if ((objc != 4) && (objc != 5)) {







<
<
<
|
<
|
<
<







828
829
830
831
832
833
834



835

836


837
838
839
840
841
842
843
		    /* It's ok */
		    TkTextPrintIndex(textPtr, &index2, position1);
		} else {
		    return TCL_OK;
		}
	    }
	}



	Tcl_AppendElement(interp, position1);

	Tcl_AppendElement(interp, position2);


	break;
    }
    case TAG_RAISE: {
	TkTextTag *tagPtr2;
	int prio;

	if ((objc != 4) && (objc != 5)) {
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
	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)) {
	    Tcl_ListObjAppendElement(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &first));
	    count++;
	}
	while (TkBTreeNextTag(&tSearch)) {
	    Tcl_ListObjAppendElement(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &tSearch.curIndex));
	    count++;
	}
	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(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &last));
	}
	Tcl_SetObjResult(interp, listObj);
	break;
    }
    }
    return TCL_OK;







|




|










|







888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
	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)) {
	    Tcl_ListObjAppendElement(interp, listObj,
		    TkTextNewIndexObj(textPtr, &first));
	    count++;
	}
	while (TkBTreeNextTag(&tSearch)) {
	    Tcl_ListObjAppendElement(interp, listObj,
		    TkTextNewIndexObj(textPtr, &tSearch.curIndex));
	    count++;
	}
	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;
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
 *
 *----------------------------------------------------------------------
 */

TkTextTag *
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. */
{
    TkTextTag *tagPtr;
    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 = (const char *)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.
     */

    tagPtr = (TkTextTag *)ckalloc(sizeof(TkTextTag));
    tagPtr->name = name;
    tagPtr->textPtr = NULL;
    tagPtr->toggleCount = 0;
    tagPtr->tagRootPtr = NULL;
    tagPtr->priority = textPtr->sharedTextPtr->numTags;
    tagPtr->border = NULL;
    tagPtr->borderWidth = 0;
    tagPtr->borderWidthPtr = NULL;
    tagPtr->reliefString = NULL;
    tagPtr->relief = TK_RELIEF_FLAT;
    tagPtr->bgStipple = None;
    tagPtr->fgColor = NULL;
    tagPtr->tkfont = NULL;
    tagPtr->fgStipple = None;
    tagPtr->justifyString = NULL;
    tagPtr->justify = TK_JUSTIFY_LEFT;
    tagPtr->lMargin1String = NULL;
    tagPtr->lMargin1 = 0;
    tagPtr->lMargin2String = NULL;
    tagPtr->lMargin2 = 0;
    tagPtr->lMarginColor = NULL;
    tagPtr->offsetString = NULL;
    tagPtr->offset = 0;
    tagPtr->overstrikeString = NULL;
    tagPtr->overstrike = 0;
    tagPtr->overstrikeColor = NULL;
    tagPtr->rMarginString = NULL;
    tagPtr->rMargin = 0;
    tagPtr->rMarginColor = NULL;
    tagPtr->selBorder = NULL;
    tagPtr->selFgColor = NULL;
    tagPtr->spacing1String = NULL;
    tagPtr->spacing1 = 0;
    tagPtr->spacing2String = NULL;
    tagPtr->spacing2 = 0;
    tagPtr->spacing3String = NULL;
    tagPtr->spacing3 = 0;
    tagPtr->tabStringPtr = NULL;
    tagPtr->tabArrayPtr = NULL;
    tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
    tagPtr->underlineString = NULL;
    tagPtr->underline = 0;
    tagPtr->underlineColor = NULL;
    tagPtr->elideString = NULL;
    tagPtr->elide = 0;
    tagPtr->wrapMode = TEXT_WRAPMODE_NULL;
    tagPtr->affectsDisplay = 0;
    tagPtr->affectsDisplayGeometry = 0;
    textPtr->sharedTextPtr->numTags++;
    if (!strcmp(tagName, "sel")) {
	tagPtr->textPtr = textPtr;
	textPtr->refCount++;
    } else {
	CLANG_ASSERT(hPtr);
	Tcl_SetHashValue(hPtr, tagPtr);
    }
    tagPtr->optionTable =
	    Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs);
    return tagPtr;
}








|



|


|


|

|

|
|


|








|

|







|




















<




<


<
<
<











<










<







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999

1000
1001
1002
1003

1004
1005



1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
 *
 *----------------------------------------------------------------------
 */

TkTextTag *
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 = 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.
     */

    tagPtr = (TkTextTag *) ckalloc(sizeof(TkTextTag));
    tagPtr->name = name;
    tagPtr->textPtr = NULL;
    tagPtr->toggleCount = 0;
    tagPtr->tagRootPtr = NULL;
    tagPtr->priority = textPtr->sharedTextPtr->numTags;
    tagPtr->border = NULL;
    tagPtr->borderWidth = 0;
    tagPtr->borderWidthPtr = NULL;
    tagPtr->reliefString = NULL;
    tagPtr->relief = TK_RELIEF_FLAT;
    tagPtr->bgStipple = None;
    tagPtr->fgColor = NULL;
    tagPtr->tkfont = NULL;
    tagPtr->fgStipple = None;
    tagPtr->justifyString = NULL;
    tagPtr->justify = TK_JUSTIFY_LEFT;
    tagPtr->lMargin1String = NULL;
    tagPtr->lMargin1 = 0;
    tagPtr->lMargin2String = NULL;
    tagPtr->lMargin2 = 0;

    tagPtr->offsetString = NULL;
    tagPtr->offset = 0;
    tagPtr->overstrikeString = NULL;
    tagPtr->overstrike = 0;

    tagPtr->rMarginString = NULL;
    tagPtr->rMargin = 0;



    tagPtr->spacing1String = NULL;
    tagPtr->spacing1 = 0;
    tagPtr->spacing2String = NULL;
    tagPtr->spacing2 = 0;
    tagPtr->spacing3String = NULL;
    tagPtr->spacing3 = 0;
    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;
    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;
}

1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

static TkTextTag *
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. */
    Tcl_Obj *tagName)		/* Name of desired tag. */
{
    Tcl_HashEntry *hPtr;
    TkSizeT len;
    const char *str;

    str = TkGetStringFromObj(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_SetObjResult(interp, Tcl_ObjPrintf(
		"tag \"%s\" isn't defined in text widget",
		Tcl_GetString(tagName)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_TAG",
		Tcl_GetString(tagName), NULL);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|


|
|

|
|
|




|


|
|
<
<
<







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075



1076
1077
1078
1079
1080
1081
1082

static TkTextTag *
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. */
    Tcl_Obj *tagName)	        /* Name of desired tag. */
{
    Tcl_HashEntry *hPtr;
    int len;
    CONST char *str;

    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 \"", Tcl_GetString(tagName),
		"\" isn't defined in text widget", NULL);



    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
 *
 *----------------------------------------------------------------------
 */

void
TkTextDeleteTag(
    TkText *textPtr,		/* Info about overall widget. */
    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);







|







1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
 *
 *----------------------------------------------------------------------
 */

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);
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
 *
 *----------------------------------------------------------------------
 */

void
TkTextFreeTag(
    TkText *textPtr,		/* Info about overall widget. */
    TkTextTag *tagPtr)	/* Tag being deleted. */
{
    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(tagPtr->tabArrayPtr);
    }

    /*
     * Make sure this tag isn't referenced from the 'current' tag array.
     */

    for (i = 0; i < textPtr->numCurTags; i++) {







|















|







1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
 *
 *----------------------------------------------------------------------
 */

void
TkTextFreeTag(
    TkText *textPtr,		/* Info about overall widget. */
    register TkTextTag *tagPtr)	/* Tag being deleted. */
{
    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);
    }

    /*
     * Make sure this tag isn't referenced from the 'current' tag array.
     */

    for (i = 0; i < textPtr->numCurTags; i++) {
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
     * refCount it holds.
     */

    if (tagPtr->textPtr != NULL) {
	if (textPtr != tagPtr->textPtr) {
	    Tcl_Panic("Tag being deleted from wrong widget");
	}

	if (textPtr->refCount-- <= 1) {
	    ckfree(textPtr);
	}
	tagPtr->textPtr = NULL;
    }

    /*
     * Finally free the tag's memory.
     */

    ckfree(tagPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * SortTags --
 *







>
|
|








|







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
     * 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);
}

/*
 *----------------------------------------------------------------------
 *
 * SortTags --
 *
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305

static void
SortTags(
    int numTags,		/* Number of tag pointers at *tagArrayPtr. */
    TkTextTag **tagArrayPtr)	/* Pointer to array of pointers. */
{
    int i, j, prio;
    TkTextTag **tagPtrPtr;
    TkTextTag **maxPtrPtr, *tmp;

    if (numTags < 2) {
	return;
    }
    if (numTags < 20) {
	for (i = numTags-1; i > 0; i--, tagArrayPtr++) {







|







1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253

static void
SortTags(
    int numTags,		/* Number of tag pointers at *tagArrayPtr. */
    TkTextTag **tagArrayPtr)	/* Pointer to array of pointers. */
{
    int i, j, prio;
    register TkTextTag **tagPtrPtr;
    TkTextTag **maxPtrPtr, *tmp;

    if (numTags < 2) {
	return;
    }
    if (numTags < 20) {
	for (i = numTags-1; i > 0; i--, tagArrayPtr++) {
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TagSortProc(
    const void *first,
    const void *second)		/* Elements to be compared. */
{
    TkTextTag *tagPtr1, *tagPtr2;

    tagPtr1 = * (TkTextTag **) first;
    tagPtr2 = * (TkTextTag **) second;
    return tagPtr1->priority - tagPtr2->priority;
}







|
|







1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TagSortProc(
    CONST void *first,
    CONST void *second)		/* Elements to be compared. */
{
    TkTextTag *tagPtr1, *tagPtr2;

    tagPtr1 = * (TkTextTag **) first;
    tagPtr2 = * (TkTextTag **) second;
    return tagPtr1->priority - tagPtr2->priority;
}
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
static void
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;
    TkTextTag *tagPtr2;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    if (prio < 0) {
	prio = 0;
    }
    if (prio >= textPtr->sharedTextPtr->numTags) {







|







1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
static void
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;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    if (prio < 0) {
	prio = 0;
    }
    if (prio >= textPtr->sharedTextPtr->numTags) {
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422

    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)) {
	    tagPtr2->priority += delta;
	}
    }
    tagPtr->priority = prio;
}








|







1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370

    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)) {
	    tagPtr2->priority += delta;
	}
    }
    tagPtr->priority = prio;
}

1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447



1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462



















1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
 *	any).
 *
 *--------------------------------------------------------------
 */

void
TkTextBindProc(
    ClientData clientData,	/* Pointer to text widget structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkText *textPtr = (TkText *)clientData;
    int repick = 0;




    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.
     */

    if (eventPtr->type == ButtonPress) {
	textPtr->flags |= BUTTON_DOWN;
    } else if (eventPtr->type == ButtonRelease) {
	unsigned long mask;

	mask = Tk_GetButtonMask(eventPtr->xbutton.button);



















	if ((eventPtr->xbutton.state & ALL_BUTTONS) == mask) {
	    textPtr->flags &= ~BUTTON_DOWN;
	    repick = 1;
	}
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	if (eventPtr->xcrossing.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
	goto done;
    } else if (eventPtr->type == MotionNotify) {
	if (eventPtr->xmotion.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
    }
    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;

	oldState = eventPtr->xbutton.state;
	eventPtr->xbutton.state &= ~(unsigned long)ALL_BUTTONS;

	if (!(textPtr->flags & DESTROYED)) {
	    TkTextPickCurrent(textPtr, eventPtr);
	}
	eventPtr->xbutton.state = oldState;
    }

  done:
    if (textPtr->refCount-- <= 1) {
	ckfree(textPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextPickCurrent --







|


|
|
>
>
>












|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|





|







|
















|
>







|
|







1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
 *	any).
 *
 *--------------------------------------------------------------
 */

void
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)

    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.
     */

    if (eventPtr->type == ButtonPress) {
	textPtr->flags |= BUTTON_DOWN;
    } else if (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;
	}
	if ((eventPtr->xbutton.state & AnyButtonMask) == (unsigned) mask) {
	    textPtr->flags &= ~BUTTON_DOWN;
	    repick = 1;
	}
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	if (eventPtr->xcrossing.state & AnyButtonMask)  {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
	goto done;
    } else if (eventPtr->type == MotionNotify) {
	if (eventPtr->xmotion.state & AnyButtonMask)  {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
    }
    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;

	oldState = eventPtr->xbutton.state;
	eventPtr->xbutton.state &= ~(Button1Mask|Button2Mask
		|Button3Mask|Button4Mask|Button5Mask);
	if (!(textPtr->flags & DESTROYED)) {
	    TkTextPickCurrent(textPtr, eventPtr);
	}
	eventPtr->xbutton.state = oldState;
    }

  done:
    if (--textPtr->refCount == 0) {
	ckfree((char *) textPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextPickCurrent --
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
 *	widget.
 *
 *--------------------------------------------------------------
 */

void
TkTextPickCurrent(
    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, nearby;
    size_t size;
    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.
     */







|










|
<







1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521
 *	widget.
 *
 *--------------------------------------------------------------
 */

void
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, 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.
     */
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
	    textPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    textPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    textPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    textPtr->pickEvent.xcrossing.same_screen
		    = eventPtr->xmotion.same_screen;
	    textPtr->pickEvent.xcrossing.focus = False;
	    textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else {
	    textPtr->pickEvent = *eventPtr;
	}
    }

    /*
     * Find the new current character, then find and sort all of the tags
     * associated with it.







|







1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
	    textPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    textPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    textPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    textPtr->pickEvent.xcrossing.same_screen
		    = eventPtr->xmotion.same_screen;
	    textPtr->pickEvent.xcrossing.focus = False;
	    textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else  {
	    textPtr->pickEvent = *eventPtr;
	}
    }

    /*
     * Find the new current character, then find and sort all of the tags
     * associated with it.
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
     * 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(size);
	memcpy(copyArrayPtr, newArrayPtr, size);
	for (i = 0; i < textPtr->numCurTags; i++) {
	    for (j = 0; j < numNewTags; j++) {
		if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {
		    textPtr->curTagArrayPtr[i] = NULL;
		    copyArrayPtr[j] = NULL;
		    break;
		}







|
|







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
     * 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(copyArrayPtr, newArrayPtr, (size_t) size);
	for (i = 0; i < textPtr->numCurTags; i++) {
	    for (j = 0; j < numNewTags; j++) {
		if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {
		    textPtr->curTagArrayPtr[i] = NULL;
		    copyArrayPtr[j] = NULL;
		    break;
		}
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
	     * consistent, this avoids problems where the binding code will
	     * discard NotifyInferior events.
	     */

	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numOldTags, oldArrayPtr);
	}
	ckfree(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.







|







1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
	     * consistent, this avoids problems where the binding code will
	     * discard NotifyInferior events.
	     */

	    event.xcrossing.detail = NotifyAncestor;
	    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.
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
		&& (textPtr->tkwin != NULL)
		&& !(textPtr->flags & DESTROYED) && !nearby) {
	    event = textPtr->pickEvent;
	    event.type = EnterNotify;
	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numNewTags, copyArrayPtr);
	}
	ckfree(copyArrayPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagBindEvent --







|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
		&& (textPtr->tkwin != NULL)
		&& !(textPtr->flags & DESTROYED) && !nearby) {
	    event = textPtr->pickEvent;
	    event.type = EnterNotify;
	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numNewTags, copyArrayPtr);
	}
	ckfree((char *) copyArrayPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TagBindEvent --
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
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(nameArrPtr);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|
|







|












<
















|










1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722

1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
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:
 */

Changes to generic/tkTextWind.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * The following structure is the official type record for the embedded window
 * geometry manager:
 */

static void		EmbWinRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		EmbWinLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostContentProc,	/* lostContentProc */
};

/*
 * Macro that determines the size of an embedded window segment:
 */

#define EW_SEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextEmbWindow))

/*
 * Prototypes for functions defined in this file:
 */

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,
			    TkSizeT offset, int maxX, TkSizeT 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.
 */

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 *const 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 const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, align),
	0, alignStrings, 0},
    {TK_OPTION_STRING, "-create", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padY), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-stretch", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, stretch), 0, 0, 0},
    {TK_OPTION_WINDOW, "-window", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowCmd --
 *







|





|






|
|




















|





|






|














|













|
|

|

|

|

|

|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * The following structure is the official type record for the embedded window
 * geometry manager:
 */

static void		EmbWinRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		EmbWinLostSlaveProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostSlaveProc,	/* lostSlaveProc */
};

/*
 * Macro that determines the size of an embedded window segment:
 */

#define EW_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
	+ sizeof(TkTextEmbWindow)))

/*
 * Prototypes for functions defined in this file:
 */

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(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 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 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}
};

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowCmd --
 *
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextWindowCmd(
    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
				 * objv[1] is "window". */
{
    int optionIndex;
    static const char *const windOptionStrings[] = {
	"cget", "configure", "create", "names", NULL
    };
    enum windOptions {
	WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES
    };
    TkTextSegment *ewPtr;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings,
	    sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum windOptions) optionIndex) {
    case WIND_CGET: {
	TkTextIndex index;

	Tcl_Obj *objPtr;
	TkTextEmbWindowClient *client;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", 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, &ewPtr->body.ew,
		ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
	if (objPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    case WIND_CONFIGURE: {
	TkTextIndex index;


	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL);
	    return TCL_ERROR;
	}
	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, &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;







|







|





|


|


|
|





>












<
|
|
<














|









>


|







<
|
|
<




|












|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
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
				 * objv[1] is "window". */
{
    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 (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;
    }
    switch ((enum windOptions) optionIndex) {
    case WIND_CGET: {
	TkTextIndex index;
	TkTextSegment *ewPtr;
	Tcl_Obj *objPtr;
	TkTextEmbWindowClient *client;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {

	    Tcl_AppendResult(interp, "no embedded window at index \"",
		    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;
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    case WIND_CONFIGURE: {
	TkTextIndex index;
	TkTextSegment *ewPtr;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {

	    Tcl_AppendResult(interp, "no embedded window at index \"",
		    Tcl_GetString(objv[3]), "\"", NULL);

	    return TCL_ERROR;
	}
	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;
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

	/*
	 * Add a new window. Find where to put the new window, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

	/*
	 * Add a new window. Find where to put the new window, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new window segment and initialize it.
	 */

	ewPtr = (TkTextSegment *)ckalloc(EW_SEG_SIZE);
	ewPtr->typePtr = &tkTextEmbWindowType;
	ewPtr->size = 1;
	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.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;







|











|
>







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new window segment and initialize it.
	 */

	ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE);
	ewPtr->typePtr = &tkTextEmbWindowType;
	ewPtr->size = 1;
	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.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;
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	break;
    }
    case WIND_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    }
    return TCL_OK;
}

/*







<





<


|
|
<

<







328
329
330
331
332
333
334

335
336
337
338
339

340
341
342
343

344

345
346
347
348
349
350
351
	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	break;
    }
    case WIND_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendElement(interp,
		    Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr));

	}

	break;
    }
    }
    return TCL_OK;
}

/*
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
    if (client != NULL) {
	ewPtr->body.ew.tkwin = client->tkwin;
    } else {
	ewPtr->body.ew.tkwin = NULL;
    }

    oldWindow = ewPtr->body.ew.tkwin;
    if (Tk_SetOptions(textPtr->interp, &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->sharedTextPtr->windowTable,
		    Tk_PathName(oldWindow)));
	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
		    EmbWinStructureProc, client);
	    Tk_ManageGeometry(oldWindow, NULL, NULL);
	    if (textPtr->tkwin != Tk_Parent(oldWindow)) {
		Tk_UnmaintainGeometry(oldWindow, textPtr->tkwin);
	    } else {
		Tk_UnmapWindow(oldWindow);
	    }
	}
	if (client != NULL) {







|











|
|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    if (client != NULL) {
	ewPtr->body.ew.tkwin = client->tkwin;
    } else {
	ewPtr->body.ew.tkwin = NULL;
    }

    oldWindow = ewPtr->body.ew.tkwin;
    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->sharedTextPtr->windowTable,
		    Tk_PathName(oldWindow)));
	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
		    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) {
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
492
493

	    parent = Tk_Parent(ewPtr->body.ew.tkwin);
	    for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (Tk_TopWinHierarchy(ancestor)) {
		badContainer:
		    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
			    "can't embed %s in %s",
			    Tk_PathName(ewPtr->body.ew.tkwin),
			    Tk_PathName(textPtr->tkwin)));
		    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY",
			    "HIERARCHY", NULL);
		    ewPtr->body.ew.tkwin = NULL;
		    if (client != NULL) {
			client->tkwin = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	    if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		    || (ewPtr->body.ew.tkwin == textPtr->tkwin)) {
		goto badContainer;
	    }

	    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.
	     */

	    Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType, client);

	    Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
		    EmbWinStructureProc, 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.
	     */







|
|
<
|
|
<
<









|







|
>















|
>

|







432
433
434
435
436
437
438
439
440

441
442


443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

	    parent = Tk_Parent(ewPtr->body.ew.tkwin);
	    for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (Tk_TopWinHierarchy(ancestor)) {
		badMaster:
		    Tcl_AppendResult(textPtr->interp, "can't embed ",

			    Tk_PathName(ewPtr->body.ew.tkwin), " in ",
			    Tk_PathName(textPtr->tkwin), NULL);


		    ewPtr->body.ew.tkwin = NULL;
		    if (client != NULL) {
			client->tkwin = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	    if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		    || (ewPtr->body.ew.tkwin == textPtr->tkwin)) {
		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.
	     */

	    Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType,
		    (ClientData) client);
	    Tk_CreateEventHandler(ewPtr->body.ew.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.
	     */
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 */

static void
EmbWinStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
    Tcl_HashEntry *hPtr;

    if (eventPtr->type != DestroyNotify) {
	return;
    }







|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
 */

static void
EmbWinStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
    Tcl_HashEntry *hPtr;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
 * Side effects:
 *	The size and location on the screen of the window may change,
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */


static void
EmbWinRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;

    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.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLostContentProc --
 *
 *	This function is invoked by the Tk geometry manager when a content
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinLostContentProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    Tk_Window tkwin)		/* Window that was claimed away by another
				 * geometry manager. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextEmbWindowClient *loop;

    Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask,
	    EmbWinStructureProc, client);
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);
    if (client->textPtr->tkwin != Tk_Parent(tkwin)) {
	Tk_UnmaintainGeometry(tkwin, client->textPtr->tkwin);
    } else {
	Tk_UnmapWindow(tkwin);
    }
    hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(client->tkwin));







>



|

|














|

|














|




|






|
|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
 * Side effects:
 *	The size and location on the screen of the window may change,
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
EmbWinRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;

    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.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLostSlaveProc --
 *
 *	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.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinLostSlaveProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    Tk_Window tkwin)		/* Window that was claimed away by another
				 * geometry manager. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextEmbWindowClient *loop;

    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);
    }
    hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(client->tkwin));
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
	ewPtr->body.ew.clients = client->next;
    } else {
	while (loop->next != client) {
	    loop = loop->next;
	}
	loop->next = client->next;
    }
    ckfree(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.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);







|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
	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.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
     * 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, client);
	Tk_DestroyWindow(client->tkwin);
    }
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);

    /*
     * Free up this client.
     */

    ckfree(client);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinDeleteProc --
 *
 *	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.
 *
 * Side effects:
 *	The embedded window is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */


static int
EmbWinDeleteProc(
    TkTextSegment *ewPtr,	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    TkTextEmbWindowClient *client;
    client = ewPtr->body.ew.clients;

    while (client != NULL) {







|


|





|




















>



|
|







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
     * 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);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinDeleteProc --
 *
 *	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.
 *
 * Side effects:
 *	The embedded window is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
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. */
{
    TkTextEmbWindowClient *client;
    client = ewPtr->body.ew.clients;

    while (client != NULL) {
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable,
	    NULL);

    /*
     * Free up all memory allocated.
     */

    ckfree(ewPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinCleanupProc --







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
    Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable,
	    NULL);

    /*
     * Free up all memory allocated.
     */

    ckfree((char *) ewPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinCleanupProc --
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
 *
 * Side effects:
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */


static int
EmbWinLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *ewPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    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;








>



|

|



|



|


|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
 *
 * Side effects:
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

	/*ARGSUSED*/
static int
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
				 * position or higher. */
    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. */
{
    int width, height;
    TkTextEmbWindowClient *client;

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
    }

    if ((ewPtr->body.ew.tkwin == NULL) && (ewPtr->body.ew.create != NULL)) {
	int code, isNew;
	Tk_Window ancestor;
	Tcl_HashEntry *hPtr;
	const char *before, *string;
	Tcl_DString buf, *dsPtr = NULL;
	Tcl_Obj *nameObj;

	before = ewPtr->body.ew.create;

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */







|
<







845
846
847
848
849
850
851
852

853
854
855
856
857
858
859
    }

    if ((ewPtr->body.ew.tkwin == NULL) && (ewPtr->body.ew.create != NULL)) {
	int code, isNew;
	Tk_Window ancestor;
	Tcl_HashEntry *hPtr;
	const char *before, *string;
	Tcl_DString name, buf, *dsPtr = NULL;


	before = ewPtr->body.ew.create;

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */
908
909
910
911
912
913
914

915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933






934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
	    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) {

	    Tcl_BackgroundException(textPtr->interp, code);
	    goto gotWindow;
	}

	nameObj = Tcl_GetObjResult(textPtr->interp);
	Tcl_IncrRefCount(nameObj);
	Tcl_ResetResult(textPtr->interp);
	ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp,
		Tcl_GetString(nameObj), textPtr->tkwin);
	Tcl_DecrRefCount(nameObj);
	if (ewPtr->body.ew.tkwin == NULL) {
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    goto gotWindow;
	}

	for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {






		goto badContainer;
	    }
	}
	if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		|| (textPtr->tkwin == ewPtr->body.ew.tkwin)) {
	badContainer:
	    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
		    "can't embed %s relative to %s",
		    Tk_PathName(ewPtr->body.ew.tkwin),
		    Tk_PathName(textPtr->tkwin)));
	    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY",
		    NULL);
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    ewPtr->body.ew.tkwin = NULL;
	    goto gotWindow;
	}

	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, client);

	Tk_CreateEventHandler(client->tkwin, StructureNotifyMask,
		EmbWinStructureProc, 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.
	 */







>
|


>
|
<


|
|

<
|

<





>
>
>
>
>
>
|




<
<
<
<
<
<
<
<
<
|








|
>










|
>

|







904
905
906
907
908
909
910
911
912
913
914
915
916

917
918
919
920
921

922
923

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939









940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
	    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:
	    Tcl_BackgroundError(textPtr->interp);
	    goto gotWindow;
	}
	Tcl_DStringInit(&name);
	Tcl_DStringAppend(&name, Tcl_GetStringResult(textPtr->interp), -1);

	Tcl_ResetResult(textPtr->interp);
	ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp,
		Tcl_DStringValue(&name), textPtr->tkwin);
	Tcl_DStringFree(&name);
	if (ewPtr->body.ew.tkwin == NULL) {

	    goto createError;
	}

	for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
	    badMaster:
		Tcl_AppendResult(textPtr->interp, "can't embed ",
			Tk_PathName(ewPtr->body.ew.tkwin), " relative to ",
			Tk_PathName(textPtr->tkwin), NULL);
		Tcl_BackgroundError(textPtr->interp);
		ewPtr->body.ew.tkwin = NULL;
		goto gotWindow;
	    }
	}
	if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		|| (textPtr->tkwin == ewPtr->body.ew.tkwin)) {









	    goto badMaster;
	}

	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.
	 */
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = ewPtr;
    if (client != NULL) {
	client->chunkCount += 1;
    }
    return 1;
}

/*







|







1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = (ClientData) ewPtr;
    if (client != NULL) {
	client->chunkCount += 1;
    }
    return 1;
}

/*
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
 *
 *--------------------------------------------------------------
 */

static void
EmbWinCheckProc(
    TkTextSegment *ewPtr,	/* Segment to check. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    if (ewPtr->nextPtr == NULL) {
	Tcl_Panic("EmbWinCheckProc: embedded window is last segment in line");
    }
    if (ewPtr->size != 1) {
	Tcl_Panic("EmbWinCheckProc: embedded window has size %d", (int)ewPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextEmbWinDisplayProc --







|





|







1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
 *
 *--------------------------------------------------------------
 */

static void
EmbWinCheckProc(
    TkTextSegment *ewPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
{
    if (ewPtr->nextPtr == NULL) {
	Tcl_Panic("EmbWinCheckProc: embedded window is last segment in line");
    }
    if (ewPtr->size != 1) {
	Tcl_Panic("EmbWinCheckProc: embedded window has size %d", ewPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextEmbWinDisplayProc --
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
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). */
    TCL_UNUSED(int),	/* 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. */
    TCL_UNUSED(Display *),	/* Display to use for drawing (unused).  */
    TCL_UNUSED(Drawable),	/* Pixmap or window in which to draw
				 * (unused).  */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	return;
    }

    tkwin = client->tkwin;







|




|
|






|







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
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. */
{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	return;
    }

    tkwin = client->tkwin;
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
 */

static void
EmbWinUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    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.
	 */

	client->displayed = 0;
	Tcl_DoWhenIdle(EmbWinDelayedUnmap, client);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinBboxProc --







|

















|







1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
 */

static void
EmbWinUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    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.
	 */

	client->displayed = 0;
	Tcl_DoWhenIdle(EmbWinDelayedUnmap, (ClientData) client);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinBboxProc --
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
 *--------------------------------------------------------------
 */

static void
EmbWinBboxProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(int),			/* 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. */
{
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	tkwin = NULL;
    } else {
	tkwin = client->tkwin;
    }







|














|







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
 *--------------------------------------------------------------
 */

static void
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. */
{
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	tkwin = NULL;
    } else {
	tkwin = client->tkwin;
    }
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
 *--------------------------------------------------------------
 */

static void
EmbWinDelayedUnmap(
    ClientData clientData)	/* Token for the window to be unmapped. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;

    if (!client->displayed && (client->tkwin != NULL)) {
	if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) {
	    Tk_UnmaintainGeometry(client->tkwin, client->textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(client->tkwin);
	}







|







1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
 *--------------------------------------------------------------
 */

static void
EmbWinDelayedUnmap(
    ClientData clientData)	/* Token for the window to be unmapped. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient*) clientData;

    if (!client->displayed && (client->tkwin != NULL)) {
	if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) {
	    Tk_UnmaintainGeometry(client->tkwin, client->textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(client->tkwin);
	}
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
    if (hPtr == NULL) {
	return 0;
    }

    ewPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = ewPtr->body.ew.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr);
    return 1;
}

/*







|







1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
    if (hPtr == NULL) {
	return 0;
    }

    ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = ewPtr->body.ew.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr);
    return 1;
}

/*
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
 *
 * 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) {







|







1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
 *
 * 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) {

Changes to generic/tkTrig.c.

8
9
10
11
12
13
14

15
16
17
18
19
20
21



22
23
24
25
26
27
28
 * 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.
 */


#include "tkInt.h"
#include "tkCanvas.h"

#undef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#undef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))




/*
 *--------------------------------------------------------------
 *
 * TkLineToPoint --
 *
 *	Compute the distance from a point to a finite line segment.







>







>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 * 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.
 */

#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"

#undef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#undef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#ifndef PI
#   define PI 3.14159265358979323846
#endif /* PI */

/*
 *--------------------------------------------------------------
 *
 * TkLineToPoint --
 *
 *	Compute the distance from a point to a finite line segment.
278
279
280
281
282
283
284

285
286
287
288
289
290
291
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


int
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?







>







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
int
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?
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
{
    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. */
    int count;
    double *pPtr;

    /*
     * 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







|







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
{
    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. */
    int count;
    register double *pPtr;

    /*
     * 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
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

int
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. */
    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
				 * 0). */
    int count;
    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".
     */

    state = TkLineToArea(polyPtr, polyPtr+2, rectPtr);







|







|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

int
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
				 * 0). */
    int count;
    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".
     */

    state = TkLineToArea(polyPtr, polyPtr+2, rectPtr);
647
648
649
650
651
652
653

654
655
656
657
658
659
660
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


double
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







>







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
double
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
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkOvalToArea(
    double *ovalPtr,	/* Points to coordinates defining the
				 * bounding rectangle for the oval: x1, y1,
				 * x2, y2. X1 must be less than x2 and y1 less
				 * than y2. */
    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







|



|







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
 *	None.
 *
 *--------------------------------------------------------------
 */

int
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. */
{
    double centerX, centerY, radX, radY, deltaX, deltaY;

    /*
     * First, see if oval is entirely inside rectangle or entirely outside
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
 *
 * Side effects:
 *	The boudn.
 *
 *--------------------------------------------------------------
 */


void
TkIncludePoint(
    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;

    tmp = (int) (pointPtr[0] + 0.5);







>


|







867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
 *
 * Side effects:
 *	The boudn.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
void
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;

    tmp = (int) (pointPtr[0] + 0.5);
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

void
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. */
    XPoint *xPointPtr)	/* Where to put new points. */
{
    int i;
    double u, u2, u3, t, t2, t3;

    for (i = 1; i <= numSteps; i++, xPointPtr++) {
	t = ((double) i)/((double) numSteps);
	t2 = t*t;







|







919
920
921
922
923
924
925
926
927
928
929
930
931
932
933

void
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;

    for (i = 1; i <= numSteps; i++, xPointPtr++) {
	t = ((double) i)/((double) numSteps);
	t2 = t*t;
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
 */

void
TkBezierPoints(
    double control[],		/* Array of coordinates for four control
				 * points: x0, y0, x1, y1, ... x3 y3. */
    int numSteps,		/* Number of curve points to generate. */
    double *coordPtr)	/* Where to put new points. */
{
    int i;
    double u, u2, u3, t, t2, t3;

    for (i = 1; i <= numSteps; i++, coordPtr += 2) {
	t = ((double) i)/((double) numSteps);
	t2 = t*t;







|







965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
 */

void
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;

    for (i = 1; i <= numSteps; i++, coordPtr += 2) {
	t = ((double) i)/((double) numSteps);
	t2 = t*t;
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
    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;
    double control[8];
    Tcl_Obj *psObj;

    /*
     * 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])
	    && (pointPtr[1] == pointPtr[numCoords-1])) {
	closed = 1;
	control[0] = 0.5*pointPtr[numCoords-4] + 0.5*pointPtr[0];
	control[1] = 0.5*pointPtr[numCoords-3] + 0.5*pointPtr[1];
	control[2] = 0.167*pointPtr[numCoords-4] + 0.833*pointPtr[0];
	control[3] = 0.167*pointPtr[numCoords-3] + 0.833*pointPtr[1];
	control[4] = 0.833*pointPtr[0] + 0.167*pointPtr[2];
	control[5] = 0.833*pointPtr[1] + 0.167*pointPtr[3];
	control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2];
	control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3];
	psObj = Tcl_ObjPrintf(
		"%.15g %.15g moveto\n"
		"%.15g %.15g %.15g %.15g %.15g %.15g curveto\n",
		control[0], Tk_CanvasPsY(canvas, control[1]),
		control[2], Tk_CanvasPsY(canvas, control[3]),
		control[4], Tk_CanvasPsY(canvas, control[5]),
		control[6], Tk_CanvasPsY(canvas, control[7]));
    } else {
	closed = 0;
	control[6] = pointPtr[0];
	control[7] = pointPtr[1];
	psObj = Tcl_ObjPrintf("%.15g %.15g moveto\n",
		control[6], Tk_CanvasPsY(canvas, control[7]));
    }


    /*
     * 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) {







|


















<
|
<








|


>







1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400

1401

1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
    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;
    double control[8];
    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 ((pointPtr[0] == pointPtr[numCoords-2])
	    && (pointPtr[1] == pointPtr[numCoords-1])) {
	closed = 1;
	control[0] = 0.5*pointPtr[numCoords-4] + 0.5*pointPtr[0];
	control[1] = 0.5*pointPtr[numCoords-3] + 0.5*pointPtr[1];
	control[2] = 0.167*pointPtr[numCoords-4] + 0.833*pointPtr[0];
	control[3] = 0.167*pointPtr[numCoords-3] + 0.833*pointPtr[1];
	control[4] = 0.833*pointPtr[0] + 0.167*pointPtr[2];
	control[5] = 0.833*pointPtr[1] + 0.167*pointPtr[3];
	control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2];
	control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3];

	sprintf(buffer, "%.15g %.15g moveto\n%.15g %.15g %.15g %.15g %.15g %.15g curveto\n",

		control[0], Tk_CanvasPsY(canvas, control[1]),
		control[2], Tk_CanvasPsY(canvas, control[3]),
		control[4], Tk_CanvasPsY(canvas, control[5]),
		control[6], Tk_CanvasPsY(canvas, control[7]));
    } else {
	closed = 0;
	control[6] = pointPtr[0];
	control[7] = pointPtr[1];
	sprintf(buffer, "%.15g %.15g moveto\n",
		control[6], Tk_CanvasPsY(canvas, control[7]));
    }
    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.
     */

    for (i = numPoints-2, pointPtr += 2; i > 0; i--, pointPtr += 2) {
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
	} else {
	    control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2];
	    control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3];
	}
	control[4] = 0.333*control[6] + 0.667*pointPtr[0];
	control[5] = 0.333*control[7] + 0.667*pointPtr[1];

	Tcl_AppendPrintfToObj(psObj,
		"%.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_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
}

/*
 *--------------------------------------------------------------
 *
 * TkMakeRawCurvePostscript --
 *







<
|



>

<
<
<







1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444



1445
1446
1447
1448
1449
1450
1451
	} else {
	    control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2];
	    control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3];
	}
	control[4] = 0.333*control[6] + 0.667*pointPtr[0];
	control[5] = 0.333*control[7] + 0.667*pointPtr[1];


	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);
    }



}

/*
 *--------------------------------------------------------------
 *
 * TkMakeRawCurvePostscript --
 *
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514
1515
1516
1517
				 * being generated. */
    double *pointPtr,		/* Array of input coordinates: x0, y0, x1, y1,
				 * etc.. */
    int numPoints)		/* Number of points at pointPtr. */
{
    int i;
    double *segPtr;
    Tcl_Obj *psObj;

    /*
     * Put the first point into the path.
     */

    psObj = Tcl_ObjPrintf("%.15g %.15g moveto\n",
	    pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1]));


    /*
     * 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.
	     */

	    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n",
		    segPtr[6], Tk_CanvasPsY(canvas, segPtr[7]));
	} else {
	    /*
	     * This is a generic Bezier curve segment.
	     */

	    Tcl_AppendPrintfToObj(psObj,
		    "%.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]));
	}

    }

    /*
     * 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.
     */








|





|

>














|






<
|




>







1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
				 * 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.
     */

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

	if (control[0]==control[2] && control[1]==control[3] &&
		control[4]==control[6] && control[5]==control[7]) {
	    /*
	     * Straight line.
	     */

	    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n",
		    control[6], Tk_CanvasPsY(canvas, control[7]));
	} else {
	    /*
	     * Bezier curve segment.
	     */

	    Tcl_AppendPrintfToObj(psObj,
		    "%.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_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
}

/*
 *--------------------------------------------------------------
 *
 * TkGetMiterPoints --
 *







|






<
|




>

<
<
<







1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552



1553
1554
1555
1556
1557
1558
1559

	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);
    }



}

/*
 *--------------------------------------------------------------
 *
 * TkGetMiterPoints --
 *

Changes to generic/tkUndo.c.

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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;
    }
    return 0;
}








|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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;
    }
    return 0;
}

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	    sub = elem->apply;
	    while (sub != NULL) {
		TkUndoSubAtom *next = sub->next;

		if (sub->action != NULL) {
		    Tcl_DecrRefCount(sub->action);
		}
		ckfree(sub);
		sub = next;
	    }

	    sub = elem->revert;
	    while (sub != NULL) {
		TkUndoSubAtom *next = sub->next;

		if (sub->action != NULL) {
		    Tcl_DecrRefCount(sub->action);
		}
		ckfree(sub);
		sub = next;
	    }
	}
	ckfree(elem);
    }
    *stack = NULL;
}

/*
 *----------------------------------------------------------------------
 *







|










|



|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	    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;
}

/*
 *----------------------------------------------------------------------
 *
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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;

    TkUndoPushStack(&stack->undoStack, atom);
    TkUndoClearStack(&stack->redoStack);
}







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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;

    TkUndoPushStack(&stack->undoStack, atom);
    TkUndoClearStack(&stack->redoStack);
}
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
{
    TkUndoSubAtom *atom;

    if (command == NULL && actionScript == NULL) {
	Tcl_Panic("NULL command and actionScript in TkUndoMakeCmdSubAtom");
    }

    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);







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
{
    TkUndoSubAtom *atom;

    if (command == NULL && actionScript == NULL) {
	Tcl_Panic("NULL command and actionScript in TkUndoMakeCmdSubAtom");
    }

    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);
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
{
    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);







|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
{
    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);
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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;
    return stack;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoSetMaxDepth --
 *
 *	Set the maximum depth of stack.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May delete elements from the stack if the new maximum depth is smaller
 *	than the number of elements previously in the stack.
 *
 *----------------------------------------------------------------------
 */

void
TkUndoSetMaxDepth(
    TkUndoRedoStack *stack,	/* An Undo/Redo stack */
    int maxdepth)		/* The maximum stack depth */
{
    stack->maxdepth = maxdepth;

    if (stack->maxdepth>0 && stack->depth>stack->maxdepth) {
	TkUndoAtom *elem, *prevelem;







|











|














|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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;
    return stack;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoSetDepth --
 *
 *	Set the maximum depth of stack.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May delete elements from the stack if the new maximum depth is smaller
 *	than the number of elements previously in the stack.
 *
 *----------------------------------------------------------------------
 */

void
TkUndoSetDepth(
    TkUndoRedoStack *stack,	/* An Undo/Redo stack */
    int maxdepth)		/* The maximum stack depth */
{
    stack->maxdepth = maxdepth;

    if (stack->maxdepth>0 && stack->depth>stack->maxdepth) {
	TkUndoAtom *elem, *prevelem;
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
	while ((elem != NULL) && (sepNumber <= stack->maxdepth)) {
	    if (elem->type == TK_UNDO_SEPARATOR) {
		sepNumber++;
	    }
	    prevelem = elem;
	    elem = elem->next;
	}
	CLANG_ASSERT(prevelem);
	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(sub);
		    sub = next;
		}
		sub = elem->revert;
		while (sub != NULL) {
		    TkUndoSubAtom *next = sub->next;

		    if (sub->action != NULL) {
			Tcl_DecrRefCount(sub->action);
		    }
		    ckfree(sub);
		    sub = next;
		}
	    }
	    elem = elem->next;
	    ckfree(prevelem);
	}
	stack->depth = stack->maxdepth;
    }
}

/*
 *----------------------------------------------------------------------







<











|









|




|







388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
	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;
    }
}

/*
 *----------------------------------------------------------------------
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
 */

void
TkUndoFreeStack(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    TkUndoClearStacks(stack);
    ckfree(stack);
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoCanRedo --
 *
 *	Returns true if redo is possible, i.e. if the redo stack is not empty.
 *
 * Results:
 *	 A boolean.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkUndoCanRedo(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    return stack->redoStack != NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoCanUndo --
 *
 *	Returns true if undo is possible, i.e. if the undo stack is not empty.
 *
 * Results:
 *	 A boolean.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkUndoCanUndo(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    return stack->undoStack != NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoInsertUndoSeparator --
 *







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







467
468
469
470
471
472
473
474














































475
476
477
478
479
480
481
 */

void
TkUndoFreeStack(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    TkUndoClearStacks(stack);
    ckfree((char *) stack);














































}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoInsertUndoSeparator --
 *
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

void
TkUndoInsertUndoSeparator(
    TkUndoRedoStack *stack)
{
    if (TkUndoInsertSeparator(&stack->undoStack)) {
	stack->depth++;
	TkUndoSetMaxDepth(stack, stack->maxdepth);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoRevert --







|







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507

void
TkUndoInsertUndoSeparator(
    TkUndoRedoStack *stack)
{
    if (TkUndoInsertSeparator(&stack->undoStack)) {
	stack->depth++;
	TkUndoSetDepth(stack, stack->maxdepth);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoRevert --
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

    elem = TkUndoPopStack(&stack->undoStack);
    if (elem == NULL) {
	return TCL_ERROR;
    }

    if (elem->type == TK_UNDO_SEPARATOR) {
	ckfree(elem);
	elem = TkUndoPopStack(&stack->undoStack);
    }

    while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
	/*
	 * Note that we currently ignore errors thrown here.
	 */







|







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

    elem = TkUndoPopStack(&stack->undoStack);
    if (elem == NULL) {
	return TCL_ERROR;
    }

    if (elem->type == TK_UNDO_SEPARATOR) {
	ckfree((char *) elem);
	elem = TkUndoPopStack(&stack->undoStack);
    }

    while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
	/*
	 * Note that we currently ignore errors thrown here.
	 */
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

    elem = TkUndoPopStack(&stack->redoStack);
    if (elem == NULL) {
	return TCL_ERROR;
    }

    if (elem->type == TK_UNDO_SEPARATOR) {
	ckfree(elem);
	elem = TkUndoPopStack(&stack->redoStack);
    }

    while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
	/*
	 * Note that we currently ignore errors thrown here.
	 */







|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

    elem = TkUndoPopStack(&stack->redoStack);
    if (elem == NULL) {
	return TCL_ERROR;
    }

    if (elem->type == TK_UNDO_SEPARATOR) {
	ckfree((char *) elem);
	elem = TkUndoPopStack(&stack->redoStack);
    }

    while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
	/*
	 * Note that we currently ignore errors thrown here.
	 */
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
    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);







|







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
    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);

Changes to generic/tkUndo.h.

12
13
14
15
16
17
18





19
20
21
22
23
24
25
26
27
#ifndef _TKUNDO
#define _TKUNDO

#ifndef _TKINT
#include "tkInt.h"
#endif






/*
 * Enum defining the types used in an undo stack.
 */

typedef enum {
    TK_UNDO_SEPARATOR,		/* Marker */
    TK_UNDO_ACTION		/* Command */
} TkUndoAtomType;








>
>
>
>
>

|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef _TKUNDO
#define _TKUNDO

#ifndef _TKINT
#include "tkInt.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Enum definining the types used in an undo stack.
 */

typedef enum {
    TK_UNDO_SEPARATOR,		/* Marker */
    TK_UNDO_ACTION		/* Command */
} TkUndoAtomType;

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114



115
MODULE_SCOPE void	TkUndoClearStack(TkUndoAtom **stack);

/*
 * Functions for working on an undo/redo stack.
 */

MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth);
MODULE_SCOPE void	TkUndoSetMaxDepth(TkUndoRedoStack *stack, int maxdepth);
MODULE_SCOPE void	TkUndoClearStacks(TkUndoRedoStack *stack);
MODULE_SCOPE void	TkUndoFreeStack(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanRedo(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanUndo(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);




#endif /* _TKUNDO */







|


<
<











>
>
>

97
98
99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
MODULE_SCOPE void	TkUndoClearStack(TkUndoAtom **stack);

/*
 * Functions for working on an undo/redo 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

#endif /* _TKUNDO */

Changes to generic/tkUtil.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "tkInt.h"

/*
 * The structure below defines the implementation of the "statekey" Tcl
 * object, used for quickly finding a mapping in a TkStateMap.
 */

const Tcl_ObjType tkStateKeyObjType = {
    "statekey",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};








|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "tkInt.h"

/*
 * 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 */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 *--------------------------------------------------------------
 */

int
TkStateParseProc(
    ClientData clientData,	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    int flags = PTR2INT(clientData);
    size_t length;
    Tcl_Obj *msgObj;
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*statePtr = TK_STATE_NULL;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);








|


|




|
|

|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 *--------------------------------------------------------------
 */

int
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 = PTR2INT(clientData);
    size_t length;

    register Tk_State *statePtr = (Tk_State *) (widgRec + offset);

    if(value == NULL || *value == 0) {
	*statePtr = TK_STATE_NULL;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);

80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	return TCL_OK;
    }
    if ((c == 'h') && (flags&2) && (strncmp(value, "hidden", length) == 0)) {
	*statePtr = TK_STATE_HIDDEN;
	return TCL_OK;
    }

    msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be normal",
	    ((flags & 4) ? "-default" : "state"), value);

    if (flags & 1) {
	Tcl_AppendToObj(msgObj, ", active", -1);
    }
    if (flags & 2) {
	Tcl_AppendToObj(msgObj, ", hidden", -1);
    }
    if (flags & 3) {
	Tcl_AppendToObj(msgObj, ",", -1);
    }
    Tcl_AppendToObj(msgObj, " or disabled", -1);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "STATE", NULL);
    *statePtr = TK_STATE_NORMAL;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







<
|
>
|
|

|
|

|
|

|
<
<







80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
	return TCL_OK;
    }
    if ((c == 'h') && (flags&2) && (strncmp(value, "hidden", length) == 0)) {
	*statePtr = TK_STATE_HIDDEN;
	return TCL_OK;
    }


    Tcl_AppendResult(interp, "bad ", (flags&4)?"-default" : "state",
	    " value \"", value, "\": must be normal", NULL);
    if (flags&1) {
	Tcl_AppendResult(interp, ", active", NULL);
    }
    if (flags&2) {
	Tcl_AppendResult(interp, ", hidden", NULL);
    }
    if (flags&3) {
	Tcl_AppendResult(interp, ",", NULL);
    }
    Tcl_AppendResult(interp, " or disabled", NULL);


    *statePtr = TK_STATE_NORMAL;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkStatePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

    switch (*statePtr) {
    case TK_STATE_NORMAL:
	return "normal";
    case TK_STATE_DISABLED:
	return "disabled";
    case TK_STATE_HIDDEN:







|

|
|

|
|



|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

char *
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);

    switch (*statePtr) {
    case TK_STATE_NORMAL:
	return "normal";
    case TK_STATE_DISABLED:
	return "disabled";
    case TK_STATE_HIDDEN:
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkOrientParseProc(
    TCL_UNUSED(void *),	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;

    int *orientPtr = (int *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*orientPtr = 0;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);

    if ((c == 'h') && (strncmp(value, "horizontal", length) == 0)) {
	*orientPtr = 0;
	return TCL_OK;
    }
    if ((c == 'v') && (strncmp(value, "vertical", length) == 0)) {
	*orientPtr = 1;
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad orientation \"%s\": must be vertical or horizontal",
	    value));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "ORIENTATION", NULL);
    *orientPtr = 0;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







|

|


|



>
|

|















|
|
<
<







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199


200
201
202
203
204
205
206
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
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;

    register int *orientPtr = (int *) (widgRec + offset);

    if(value == NULL || *value == 0) {
	*orientPtr = 0;
	return TCL_OK;
    }

    c = value[0];
    length = strlen(value);

    if ((c == 'h') && (strncmp(value, "horizontal", length) == 0)) {
	*orientPtr = 0;
	return TCL_OK;
    }
    if ((c == 'v') && (strncmp(value, "vertical", length) == 0)) {
	*orientPtr = 1;
	return TCL_OK;
    }
    Tcl_AppendResult(interp, "bad orientation \"", value,
	    "\": must be vertical or horizontal", NULL);


    *orientPtr = 0;
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkOrientPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    int *statePtr = (int *) (widgRec + offset);

    if (*statePtr) {
	return "vertical";
    } else {
	return "horizontal";
    }
}







|

|
|

|
|



|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

char *
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);

    if (*statePtr) {
	return "vertical";
    } else {
	return "horizontal";
    }
}
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
int
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 */
    TkSizeT offset)			/* Offset of tile in record */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    Tk_TSOffset tsoffset;
    const char *q, *p;
    int result;
    Tcl_Obj *msgObj;

    if ((value == NULL) || (*value == 0)) {
	tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
	goto goodTSOffset;
    }
    tsoffset.flags = 0;
    p = value;

    switch (value[0]) {
    case '#':
	if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	    tsoffset.flags = TK_OFFSET_RELATIVE;
	    p++;
	    break;
	}
	goto badTSOffset;







|





<








|







255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
int
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 tsoffset;
    const char *q, *p;
    int result;


    if ((value == NULL) || (*value == 0)) {
	tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
	goto goodTSOffset;
    }
    tsoffset.flags = 0;
    p = value;

    switch(value[0]) {
    case '#':
	if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	    tsoffset.flags = TK_OFFSET_RELATIVE;
	    p++;
	    break;
	}
	goto badTSOffset;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    case 'c':
	if (strncmp(value, "center", strlen(value)) != 0) {
	    goto badTSOffset;
	}
	tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
	goto goodTSOffset;
    }

    /*
     * Check for an extra offset.
     */

    q = strchr(p, ',');
    if (q == NULL) {
	if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
	    if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) {
		Tcl_ResetResult(interp);
		goto badTSOffset;
	    }
	    tsoffset.flags |= TK_OFFSET_INDEX;
	    goto goodTSOffset;
	}
	goto badTSOffset;
    }

    *((char *) q) = 0;
    result = Tk_GetPixels(interp, tkwin, (char *) p, &tsoffset.xoffset);
    *((char *) q) = ',';
    if (result != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tk_GetPixels(interp, tkwin, (char*)q+1, &tsoffset.yoffset) != TCL_OK) {
	return TCL_ERROR;
    }


    /*
     * 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:
    memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset));
    return TCL_OK;

  badTSOffset:

    msgObj = Tcl_ObjPrintf("bad offset \"%s\": expected \"x,y\"", value);
    if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	Tcl_AppendToObj(msgObj, ", \"#x,y\"", -1);
    }
    if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
	Tcl_AppendToObj(msgObj, ", <index>", -1);
    }
    Tcl_AppendToObj(msgObj, ", n, ne, e, se, s, sw, w, nw, or center", -1);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "OFFSET", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkOffsetPrintProc --
 *
 *	Returns the offset of the tile.
 *
 * Results:
 *	The offset of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

const char *
TkOffsetPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    char *p, *q;

    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);
	*freeProcPtr = TCL_DYNAMIC;
	return p;
    }
    if (offsetPtr->flags & TK_OFFSET_TOP) {
	if (offsetPtr->flags & TK_OFFSET_LEFT) {
	    return "nw";







<
<
<
<
<
|
<










<










>




|


<




>
|

|


|

|
<
<
















|

|
|

|









|







333
334
335
336
337
338
339





340

341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381


382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    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 (PTR2INT(clientData) & TK_OFFSET_INDEX) {
	    if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) {
		Tcl_ResetResult(interp);
		goto badTSOffset;
	    }
	    tsoffset.flags |= TK_OFFSET_INDEX;
	    goto goodTSOffset;
	}
	goto badTSOffset;
    }

    *((char *) q) = 0;
    result = Tk_GetPixels(interp, tkwin, (char *) p, &tsoffset.xoffset);
    *((char *) q) = ',';
    if (result != TCL_OK) {
	return TCL_ERROR;
    }
    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()!!!!;
     */


    memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset));
    return TCL_OK;

  badTSOffset:
    Tcl_AppendResult(interp, "bad offset \"", value,
	    "\": expected \"x,y\"", NULL);
    if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	Tcl_AppendResult(interp, ", \"#x,y\"", 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", NULL);


    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkOffsetPrintProc --
 *
 *	Returns the offset of the tile.
 *
 * Results:
 *	The offset of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

char *
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);
    char *p, *q;

    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);
	*freeProcPtr = TCL_DYNAMIC;
	return p;
    }
    if (offsetPtr->flags & TK_OFFSET_TOP) {
	if (offsetPtr->flags & TK_OFFSET_LEFT) {
	    return "nw";
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
	    return "sw";
	} else if (offsetPtr->flags & TK_OFFSET_CENTER) {
	    return "s";
	} else if (offsetPtr->flags & TK_OFFSET_RIGHT) {
	    return "se";
	}
    }
    q = p = (char *)ckalloc(32);
    if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
	*q++ = '#';
    }
    sprintf(q, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}







|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
	    return "sw";
	} else if (offsetPtr->flags & TK_OFFSET_CENTER) {
	    return "s";
	} else if (offsetPtr->flags & TK_OFFSET_RIGHT) {
	    return "se";
	}
    }
    q = p = (char *) ckalloc(32);
    if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
	*q++ = '#';
    }
    sprintf(q, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
 *
 *----------------------------------------------------------------------
 */

int
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 */
    TkSizeT offset)			/* Offset of tile in record */
{
    double *doublePtr = (double *) (widgRec + offset);
    int result;

    result = TkGetDoublePixels(interp, tkwin, value, doublePtr);

    if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad screen distance \"%s\"", value));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	return TCL_ERROR;
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPixelPrintProc --
 *
 *	Returns the name of the tile.
 *
 * Results:
 *	The name of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

const char *
TkPixelPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    double *doublePtr = (double *) (widgRec + offset);
    char *p = (char *)ckalloc(24);

    Tcl_PrintDouble(NULL, *doublePtr, p);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

/*







|




|







<
|
<


















|

|
|

|



|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
 *
 *----------------------------------------------------------------------
 */

int
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);
    int result;

    result = TkGetDoublePixels(interp, tkwin, value, doublePtr);

    if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {

	Tcl_AppendResult(interp, "bad screen distance \"", value, "\"", NULL);

	return TCL_ERROR;
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPixelPrintProc --
 *
 *	Returns the name of the tile.
 *
 * Results:
 *	The name of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

char *
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 = (char *) ckalloc(24);

    Tcl_PrintDouble(NULL, *doublePtr, p);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

/*
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
				 * scroll, if any. */
{
    int c = argv[2][0];
    size_t length = strlen(argv[2]);

    if ((c == 'm') && (strncmp(argv[2], "moveto", length) == 0)) {
	if (argc != 4) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # args: should be \"%s %s %s\"",
		    argv[0], argv[1], "moveto fraction"));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } else if ((c == 's')
	    && (strncmp(argv[2], "scroll", length) == 0)) {
	double d;
	if (argc != 5) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # args: should be \"%s %s %s\"",
		    argv[0], argv[1], "scroll number pages|units"));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d > 0) ? ceil(d) : floor(d);
	length = strlen(argv[4]);
	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)) {
	    return TK_SCROLL_UNITS;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad argument \"%s\": must be pages or units", argv[4]));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "SCROLL_UNITS", NULL);
	return TK_SCROLL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown option \"%s\": must be moveto or scroll", argv[2]));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", argv[2],
	    NULL);
    return TK_SCROLL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetScrollInfoObj --







<
|
|
<








<

<
|
|
<


|


<








|
|
<


|
|
<
<







634
635
636
637
638
639
640

641
642

643
644
645
646
647
648
649
650

651

652
653

654
655
656
657
658

659
660
661
662
663
664
665
666
667
668

669
670
671
672


673
674
675
676
677
678
679
				 * scroll, if any. */
{
    int c = argv[2][0];
    size_t length = strlen(argv[2]);

    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\"", NULL);

	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } 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\"", NULL);

	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetInt(interp, argv[3], intPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}

	length = strlen(argv[4]);
	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)) {
	    return TK_SCROLL_UNITS;
	}

	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", NULL);


    return TK_SCROLL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetScrollInfoObj --
726
727
728
729
730
731
732
733


734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
    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. */
{
    TkSizeT length;


    const char *arg = TkGetStringFromObj(objv[2], &length);

#define ArgPfxEq(str) \
	((arg[0] == str[0]) && !strncmp(arg, str, length))

    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } else if (ArgPfxEq("scroll")) {
	double d;
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "scroll number pages|units");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d >= 0) ? ceil(d) : floor(d);
	if (dblPtr) {
	    *dblPtr = d;
	}

	arg = TkGetStringFromObj(objv[4], &length);
	if (ArgPfxEq("pages")) {
	    return TK_SCROLL_PAGES;
	} else if (ArgPfxEq("units")) {
	    return TK_SCROLL_UNITS;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad argument \"%s\": must be pages or units", arg));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "SCROLL_UNITS", NULL);
	return TK_SCROLL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown option \"%s\": must be moveto or scroll", arg));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", arg, NULL);
    return TK_SCROLL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkComputeAnchor --







|
>
>
|

|
<











<

|


|


<
<
<
|
<
|






|
|
<


|
|
<







703
704
705
706
707
708
709
710
711
712
713
714
715

716
717
718
719
720
721
722
723
724
725
726

727
728
729
730
731
732
733



734

735
736
737
738
739
740
741
742
743

744
745
746
747

748
749
750
751
752
753
754
    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 length;
    const char *arg;

    arg = Tcl_GetStringFromObj(objv[2], &length);

#define ArgPfxEq(str) ((arg[0]==str[0])&&!strncmp(arg,str,(unsigned)length))


    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } else if (ArgPfxEq("scroll")) {

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "scroll number units|pages");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}





	arg = Tcl_GetStringFromObj(objv[4], &length);
	if (ArgPfxEq("pages")) {
	    return TK_SCROLL_PAGES;
	} else if (ArgPfxEq("units")) {
	    return TK_SCROLL_UNITS;
	}

	Tcl_AppendResult(interp, "bad argument \"", arg,
		"\": must be units or pages", NULL);

	return TK_SCROLL_ERROR;
    }
    Tcl_AppendResult(interp, "unknown option \"", arg,
	    "\": must be moveto or scroll", NULL);

    return TK_SCROLL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkComputeAnchor --
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
 *
 * Side effects.
 *	None.
 *
 *---------------------------------------------------------------------------
 */

const char *
TkFindStateString(
    const TkStateMap *mapPtr,	/* The state table. */
    int numKey)			/* The key to try to find in the table. */
{
    for (; mapPtr->strKey!=NULL ; mapPtr++) {
	if (numKey == mapPtr->numKey) {
	    return mapPtr->strKey;
	}
    }
    return NULL;
}

/*
 *---------------------------------------------------------------------------







|






|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
 *
 * Side effects.
 *	None.
 *
 *---------------------------------------------------------------------------
 */

char *
TkFindStateString(
    const TkStateMap *mapPtr,	/* The state table. */
    int numKey)			/* The key to try to find in the table. */
{
    for (; mapPtr->strKey!=NULL ; mapPtr++) {
	if (numKey == mapPtr->numKey) {
	    return (char *) mapPtr->strKey;
	}
    }
    return NULL;
}

/*
 *---------------------------------------------------------------------------
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
955
956
957

    /*
     * Not there. Generate an error message (if we can) and return the
     * default.
     */

    if (interp != NULL) {
	Tcl_Obj *msgObj;

	mPtr = mapPtr;
	msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be %s",
		option, strKey, mPtr->strKey);
	for (mPtr++; mPtr->strKey != NULL; mPtr++) {
	    Tcl_AppendPrintfToObj(msgObj, ",%s %s",
		    ((mPtr[1].strKey != NULL) ? "" : "or "), mPtr->strKey);

	}
	Tcl_SetObjResult(interp, msgObj);
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", option, strKey, NULL);
    }
    return mPtr->numKey;
}

int
TkFindStateNumObj(
    Tcl_Interp *interp,		/* Interp for error reporting. */







<
<

|
|

|
|
>

<
<







904
905
906
907
908
909
910


911
912
913
914
915
916
917
918


919
920
921
922
923
924
925

    /*
     * 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, NULL);
	for (mPtr++; mPtr->strKey != NULL; mPtr++) {
	    Tcl_AppendResult(interp,
		    ((mPtr[1].strKey != NULL) ? ", " : ", or "),
		    mPtr->strKey, NULL);
	}


    }
    return mPtr->numKey;
}

int
TkFindStateNumObj(
    Tcl_Interp *interp,		/* Interp for error reporting. */
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004

1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
	return PTR2INT(keyPtr->internalRep.twoPtrValue.ptr2);
    }

    /*
     * Not there. Look in the state map.
     */

    key = Tcl_GetString(keyPtr);
    for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
	if (strcmp(key, mPtr->strKey) == 0) {
	    typePtr = keyPtr->typePtr;
	    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
		typePtr->freeIntRepProc(keyPtr);
	    }
	    keyPtr->internalRep.twoPtrValue.ptr1 = (void *) mapPtr;
	    keyPtr->internalRep.twoPtrValue.ptr2 = 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) {
	Tcl_Obj *msgObj;

	mPtr = mapPtr;
	msgObj = Tcl_ObjPrintf(
		"bad %s value \"%s\": must be %s",
		Tcl_GetString(optionPtr), key, mPtr->strKey);

	for (mPtr++; mPtr->strKey != NULL; mPtr++) {
	    Tcl_AppendPrintfToObj(msgObj, ",%s %s",
		    ((mPtr[1].strKey != NULL) ? "" : " or"), mPtr->strKey);

	}
	Tcl_SetObjResult(interp, msgObj);
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", Tcl_GetString(optionPtr),
		key, NULL);
    }
    return mPtr->numKey;
}

/*
 * ----------------------------------------------------------------------
 *
 * TkBackgroundEvalObjv --
 *
 *	Evaluate a command while ensuring that we do not affect the
 *	interpreters state. This is important when evaluating script
 *	during background tasks.
 *
 * Results:
 *	A standard Tcl result code.
 *
 * Side Effects:
 *	The interpreters variables and code may be modified by the script
 *	but the result will not be modified.
 *
 * ----------------------------------------------------------------------
 */

int
TkBackgroundEvalObjv(
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const *objv,
    int flags)
{
    Tcl_InterpState state;
    int n, r = TCL_OK;

    /*
     * Record the state of the interpreter.
     */

    Tcl_Preserve(interp);
    state = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * 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_BackgroundException(interp, r);
    }

    /*
     * Restore the state of the interpreter.
     */

    (void) Tcl_RestoreInterpState(interp, state);
    Tcl_Release(interp);

    return r;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMakeEnsemble --
 *
 *	Create an ensemble from a table of implementation commands. This may
 *	be called recursively to create sub-ensembles.
 *
 * Results:
 *	Handle for the ensemble, or NULL if creation of it fails.
 *
 *----------------------------------------------------------------------
 */

Tcl_Command
TkMakeEnsemble(
    Tcl_Interp *interp,
    const char *namesp,
    const char *name,
    ClientData clientData,
    const TkEnsemble map[])
{
    Tcl_Namespace *namespacePtr = NULL;
    Tcl_Command ensemble = NULL;
    Tcl_Obj *dictObj = NULL, *nameObj;
    Tcl_DString ds;
    int i;

    if (map == NULL) {
	return NULL;
    }

    Tcl_DStringInit(&ds);

    namespacePtr = Tcl_FindNamespace(interp, namesp, NULL, 0);
    if (namespacePtr == NULL) {
	namespacePtr = Tcl_CreateNamespace(interp, namesp, NULL, NULL);
	if (namespacePtr == NULL) {
	    Tcl_Panic("failed to create namespace \"%s\"", namesp);
	}
    }

    nameObj = Tcl_NewStringObj(name, -1);
    ensemble = Tcl_FindEnsemble(interp, nameObj, 0);
    Tcl_DecrRefCount(nameObj);
    if (ensemble == NULL) {
	ensemble = Tcl_CreateEnsemble(interp, name, namespacePtr,
		TCL_ENSEMBLE_PREFIX);
	if (ensemble == NULL) {
	    Tcl_Panic("failed to create ensemble \"%s\"", name);
	}
    }

    Tcl_DStringSetLength(&ds, 0);
    Tcl_DStringAppend(&ds, namesp, -1);
    if (!(strlen(namesp) == 2 && namesp[1] == ':')) {
	Tcl_DStringAppend(&ds, "::", -1);
    }
    Tcl_DStringAppend(&ds, name, -1);

    dictObj = Tcl_NewObj();
    for (i = 0; map[i].name != NULL ; ++i) {
	Tcl_Obj *fqdnObj;

	nameObj = Tcl_NewStringObj(map[i].name, -1);
	fqdnObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds));
	Tcl_AppendStringsToObj(fqdnObj, "::", map[i].name, NULL);
	Tcl_DictObjPut(NULL, dictObj, nameObj, fqdnObj);
	if (map[i].proc) {
	    Tcl_CreateObjCommand(interp, Tcl_GetString(fqdnObj),
		    map[i].proc, clientData, NULL);
	} else if (map[i].subensemble) {
	    TkMakeEnsemble(interp, Tcl_DStringValue(&ds),
		    map[i].name, clientData, map[i].subensemble);
	}
    }

    if (ensemble) {
	Tcl_SetEnsembleMappingDict(interp, ensemble, dictObj);
    }

    Tcl_DStringFree(&ds);
    return ensemble;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SendVirtualEvent --
 *
 * 	Send a virtual event notification to the specified target window.
 * 	Equivalent to:
 * 	    "event generate $target <<$eventName>> -data $detail"
 *
 * 	Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent, so this
 * 	routine does not reenter the interpreter.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SendVirtualEvent(
    Tk_Window target,
    const char *eventName,
    Tcl_Obj *detail)
{
    union {XEvent general; XVirtualEvent virt;} event;

    memset(&event, 0, sizeof(event));
    event.general.xany.type = VirtualEvent;
    event.general.xany.serial = NextRequest(Tk_Display(target));
    event.general.xany.send_event = False;
    event.general.xany.window = Tk_WindowId(target);
    event.general.xany.display = Tk_Display(target);
    event.virt.name = Tk_GetUid(eventName);
    event.virt.user_data = detail;

    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

#if TCL_UTF_MAX <= 4
/*
 *---------------------------------------------------------------------------
 *
 * TkUtfToUniChar --
 *
 *	Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar.
 *	This function is capable of collapsing a upper/lower surrogate pair to a
 *	single unicode character. So, up to 6 bytes might be consumed.
 *
 * Results:
 *	*chPtr is filled with the Tcl_UniChar, and the return value is the
 *	number of bytes from the UTF-8 string that were consumed.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

size_t
TkUtfToUniChar(
    const char *src,	/* The UTF-8 string. */
    int *chPtr)		/* Filled with the Unicode value represented by
			 * the UTF-8 string. */
{
    Tcl_UniChar uniChar = 0;

    size_t len = Tcl_UtfToUniChar(src, &uniChar);
    if ((sizeof(Tcl_UniChar) == 2)
	    && ((uniChar & 0xFC00) == 0xD800)
#if TCL_MAJOR_VERSION > 8
	    && (len == 1)
#endif
	) {
	Tcl_UniChar low = uniChar;
	/* This can only happen if Tcl is compiled with TCL_UTF_MAX=4,
	 * or when a high surrogate character is detected in UTF-8 form */
	size_t len2 = Tcl_UtfToUniChar(src+len, &low);
	if ((low & 0xFC00) == 0xDC00) {
	    *chPtr = (((uniChar & 0x3FF) << 10) | (low & 0x3FF)) + 0x10000;
	    return len + len2;
	}
    }
    *chPtr = uniChar;
    return len;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkUniCharToUtf --
 *
 *	Almost the same as Tcl_UniCharToUtf but producing 2 x 3-byte UTF-8
 *	sequences for out-of-bmp characters when TCL_UTF_MAX==3.
 *	So, up to 6 bytes might be produced.
 *
 * Results:
 *	*buf is filled with the UTF-8 string, and the return value is the
 *	number of bytes produced.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

size_t TkUniCharToUtf(int ch, char *buf)
{
    if ((sizeof(Tcl_UniChar) == 2) && (((unsigned)(ch - 0x10000) <= 0xFFFFF))) {
	/* Spit out a 4-byte UTF-8 character or 2 x 3-byte UTF-8 characters, depending on Tcl
	 * version and/or TCL_UTF_MAX build value */
	int len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf);
	return len + Tcl_UniCharToUtf(0xDC00 | (ch & 0x7FF), buf + len);
    }
    return Tcl_UniCharToUtf(ch, buf);
}
/*
 *---------------------------------------------------------------------------
 *
 * TkUtfPrev --
 *
 *	Almost the same as Tcl_UtfPrev.
 *	This function is capable of jumping over a upper/lower surrogate pair.
 *	So, might jump back up to 6 bytes.
 *
 * Results:
 *	pointer to the first byte of the current UTF-8 character. A surrogate
 *	pair is also handled as being a single entity.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

const char *
TkUtfPrev(
    const char *src,	/* The UTF-8 string. */
    const char *start)		/* Start position of string */
{
    const char *p = Tcl_UtfPrev(src, start);
    const char *first = Tcl_UtfPrev(p, start);
    int ch;

#if TCL_UTF_MAX == 3
    if ((src - start > 3) && ((src[-1] & 0xC0) == 0x80) && ((src[-2] & 0xC0) == 0x80)
	    && ((src[-3] & 0xC0) == 0x80) && (UCHAR(src[-4]) >= 0xF0)) {
	return src - 4;
    }
#endif

    return (first + TkUtfToUniChar(first, &ch) >= src) ? first : p ;
}

#endif

#if TCL_MAJOR_VERSION > 8
unsigned char *
TkGetByteArrayFromObj(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, NULL);
    *lengthPtr = *(size_t *) objPtr->internalRep.twoPtrValue.ptr1;
    return result;
}
#endif /* TCL_MAJOR_VERSION > 8 */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




|














<
<

<
<
|
>

|
|
>

<
<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966


967


968
969
970
971
972
973
974



975
976
977
978
























































































































































































































































































































979
980
981
982
983
984
985
	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) {
	    typePtr = keyPtr->typePtr;
	    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
		(*typePtr->freeIntRepProc)(keyPtr);
	    }
	    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_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, NULL);
	}



    }
    return mPtr->numKey;
}

























































































































































































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkVisual.c.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/*
 * The table below maps from symbolic names for visual classes to the
 * associated X class symbols.
 */

typedef struct VisualDictionary {
    char name[12];		/* Textual name of class. */
    unsigned short minLength;		/* Minimum # characters that must be specified
				 * for an unambiguous match. */
    short c_class;			/* X symbol for class. */
} VisualDictionary;
static const VisualDictionary visualNames[] = {
    {"best",		1,	0},
    {"directcolor",	2,	DirectColor},
    {"grayscale",	1,	GrayScale},
    {"greyscale",	1,	GrayScale},
    {"pseudocolor",	1,	PseudoColor},
    {"staticcolor",	7,	StaticColor},
    {"staticgray",	7,	StaticGray},
    {"staticgrey",	7,	StaticGray},
    {"truecolor",	1,	TrueColor},
    {"",		0,	0},
};

/*
 * One of the following structures exists for each distinct non-default
 * colormap allocated for a display by Tk_GetColormap.
 */

struct TkColormap {
    Colormap colormap;		/* X's identifier for the colormap. */
    Visual *visual;		/* Visual for which colormap was allocated. */
    size_t 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







|
|

|

|









|










|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/*
 * 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 class;			/* X symbol for class. */
} VisualDictionary;
static VisualDictionary visualNames[] = {
    {"best",		1,	0},
    {"directcolor",	2,	DirectColor},
    {"grayscale",	1,	GrayScale},
    {"greyscale",	1,	GrayScale},
    {"pseudocolor",	1,	PseudoColor},
    {"staticcolor",	7,	StaticColor},
    {"staticgray",	7,	StaticGray},
    {"staticgrey",	7,	StaticGray},
    {"truecolor",	1,	TrueColor},
    {NULL,		0,	0},
};

/*
 * One of the following structures exists for each distinct non-default
 * colormap allocated for a display by Tk_GetColormap.
 */

struct TkColormap {
    Colormap colormap;		/* X's identifier for the colormap. */
    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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
 *----------------------------------------------------------------------
 */

Visual *
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 templ, *visInfoList, *bestPtr;
    long mask;
    Visual *visual;
    size_t length;
    int c, numVisuals, prio, bestPrio, i;
    const char *p;
    const VisualDictionary *dictPtr;
    TkColormap *cmapPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    /*
     * Parse string and set up a template for use in searching for an
     * appropriate visual.
     */







|









|


|

|
|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
 *----------------------------------------------------------------------
 */

Visual *
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;
    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.
     */
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
		 * allocated here).
		 */

		*colormapPtr = Tk_Colormap(tkwin2);
		for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
			cmapPtr = cmapPtr->nextPtr) {
		    if (cmapPtr->colormap == *colormapPtr) {
			cmapPtr->refCount++;
			break;
		    }
		}
	    }
	    return visual;
	}
	templ.depth = Tk_Depth(tkwin2);
	templ.c_class = visual->c_class;
	templ.red_mask = visual->red_mask;
	templ.green_mask = visual->green_mask;
	templ.blue_mask = visual->blue_mask;
	templ.colormap_size = visual->map_entries;
	templ.bits_per_rgb = visual->bits_per_rgb;
	mask = VisualDepthMask|VisualClassMask|VisualRedMaskMask
		|VisualGreenMaskMask|VisualBlueMaskMask|VisualColormapSizeMask
		|VisualBitsPerRGBMask;
    } else if ((c == 0) || ((c == 'd') && (string[1] != 0)
	    && (strncmp(string, "default", strlen(string)) == 0))) {
	/*
	 * Use the default visual for the window's screen.







|






|
|
|
|
|
|
|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
		 * allocated here).
		 */

		*colormapPtr = Tk_Colormap(tkwin2);
		for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
			cmapPtr = cmapPtr->nextPtr) {
		    if (cmapPtr->colormap == *colormapPtr) {
			cmapPtr->refCount += 1;
			break;
		    }
		}
	    }
	    return visual;
	}
	template.depth = Tk_Depth(tkwin2);
	template.class = visual->class;
	template.red_mask = visual->red_mask;
	template.green_mask = visual->green_mask;
	template.blue_mask = visual->blue_mask;
	template.colormap_size = visual->map_entries;
	template.bits_per_rgb = visual->bits_per_rgb;
	mask = VisualDepthMask|VisualClassMask|VisualRedMaskMask
		|VisualGreenMaskMask|VisualBlueMaskMask|VisualColormapSizeMask
		|VisualBitsPerRGBMask;
    } else if ((c == 0) || ((c == 'd') && (string[1] != 0)
	    && (strncmp(string, "default", strlen(string)) == 0))) {
	/*
	 * Use the default visual for the window's screen.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
	int visualId;

	/*
	 * This is a visual ID.
	 */

	if (Tcl_GetInt(interp, string, &visualId) == TCL_ERROR) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad X identifier for visual: \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "VISUALID", NULL);
	    return NULL;
	}
	templ.visualid = visualId;
	mask = VisualIDMask;
    } else {
	/*
	 * Parse the string into a class name (or "best") optionally followed
	 * by whitespace and a depth.
	 */

	for (p = string; *p != 0; p++) {
	    if (isspace(UCHAR(*p)) || isdigit(UCHAR(*p))) {
		break;
	    }
	}
	length = p - string;
	templ.c_class = -1;
	for (dictPtr = visualNames; dictPtr->minLength; dictPtr++) {
	    if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength)
		    && (strncmp(string, dictPtr->name, length) == 0)) {

		templ.c_class = dictPtr->c_class;
		break;
	    }
	}
	if (templ.c_class == -1) {
	    Tcl_Obj *msgObj = Tcl_ObjPrintf(
		    "unknown or ambiguous visual name \"%s\": class must be ",
		    string);

	    for (dictPtr = visualNames; dictPtr->minLength; dictPtr++) {
		Tcl_AppendPrintfToObj(msgObj, "%s, ", dictPtr->name);
	    }
	    Tcl_AppendToObj(msgObj, "or default", -1);
	    Tcl_SetObjResult(interp, msgObj);
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "VISUAL", string, NULL);
	    return NULL;
	}
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	if (*p == 0) {
	    templ.depth = 10000;

	} else if (Tcl_GetInt(interp, p, &templ.depth) != TCL_OK) {
	    return NULL;

	}
	if (c == 'b') {
	    mask = 0;
	} else {
	    mask = VisualClassMask;
	}
    }

    /*
     * Find all visuals that match the template we've just created, and return
     * an error if there are none that match.
     */

    templ.screen = Tk_ScreenNumber(tkwin);
    mask |= VisualScreenMask;
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &templ,
	    &numVisuals);
    if (visInfoList == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't find an appropriate visual", -1));
	Tcl_SetErrorCode(interp, "TK", "VISUAL", "INAPPROPRIATE", NULL);

	return NULL;
    }

    /*
     * 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.
     */

    bestPrio = 0;
    bestPtr = NULL;
    for (i = 0; i < numVisuals; i++) {
	switch (visInfoList[i].c_class) {
	case DirectColor:
	    prio = 5; break;
	case GrayScale:
	    prio = 1; break;
	case PseudoColor:
	    prio = 7; break;
	case StaticColor:







|
|
|


|













|
|

|
>
|



|
<
|
|
<
|
|

<
|
<






|
>
|
|
>













|

|


<
|
<
>




















|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206

207
208
209

210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
	int visualId;

	/*
	 * 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, "\"", 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.
	 */

	for (p = string; *p != 0; p++) {
	    if (isspace(UCHAR(*p)) || isdigit(UCHAR(*p))) {
		break;
	    }
	}
	length = p - string;
	template.class = -1;
	for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
	    if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength)
		    && (strncmp(string, dictPtr->name,
		    (size_t) length) == 0)) {
		template.class = dictPtr->class;
		break;
	    }
	}
	if (template.class == -1) {

	    Tcl_AppendResult(interp, "unknown or ambiguous visual name \"",
		    string, "\": class must be ", NULL);

	    for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
		Tcl_AppendResult(interp, dictPtr->name, ", ", NULL);
	    }

	    Tcl_AppendResult(interp, "or default", NULL);

	    return NULL;
	}
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	if (*p == 0) {
	    template.depth = 10000;
	} else {
	    if (Tcl_GetInt(interp, p, &template.depth) != TCL_OK) {
		return NULL;
	    }
	}
	if (c == 'b') {
	    mask = 0;
	} else {
	    mask = VisualClassMask;
	}
    }

    /*
     * 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);
    mask |= VisualScreenMask;
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &template,
	    &numVisuals);
    if (visInfoList == NULL) {

	Tcl_SetResult(interp, "couldn't find an appropriate visual",

		TCL_STATIC);
	return NULL;
    }

    /*
     * 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.
     */

    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:
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
		== DefaultVisualOfScreen(Tk_Screen(tkwin))) {
	    prio++;
	}
	if (bestPtr == NULL) {
	    goto newBest;
	}
	if (visInfoList[i].depth < bestPtr->depth) {
	    if (visInfoList[i].depth >= templ.depth) {
		goto newBest;
	    }
	} else if (visInfoList[i].depth > bestPtr->depth) {
	    if (bestPtr->depth < templ.depth) {
		goto newBest;
	    }
	} else {
	    if (prio > bestPrio) {
		goto newBest;
	    }
	}
	continue;

    newBest:
	bestPtr = &visInfoList[i];
	bestPrio = prio;
    }
    CLANG_ASSERT(bestPtr);
    *depthPtr = bestPtr->depth;
    visual = bestPtr->visual;
    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 (colormapPtr != NULL) {
	if (visual == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
	    *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
	} else {
	    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
		    cmapPtr = cmapPtr->nextPtr) {
		if (cmapPtr->shareable && (cmapPtr->visual == visual)) {
		    *colormapPtr = cmapPtr->colormap;
		    cmapPtr->refCount++;
		    goto done;
		}
	    }
	    cmapPtr = (TkColormap *)ckalloc(sizeof(TkColormap));
	    cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
		    RootWindowOfScreen(Tk_Screen(tkwin)), visual,
		    AllocNone);
	    cmapPtr->visual = visual;
	    cmapPtr->refCount = 1;
	    cmapPtr->shareable = 1;
	    cmapPtr->nextPtr = dispPtr->cmapPtr;







|



|













<



















|



|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
		== DefaultVisualOfScreen(Tk_Screen(tkwin))) {
	    prio++;
	}
	if (bestPtr == NULL) {
	    goto newBest;
	}
	if (visInfoList[i].depth < bestPtr->depth) {
	    if (visInfoList[i].depth >= template.depth) {
		goto newBest;
	    }
	} else if (visInfoList[i].depth > bestPtr->depth) {
	    if (bestPtr->depth < template.depth) {
		goto newBest;
	    }
	} else {
	    if (prio > bestPrio) {
		goto newBest;
	    }
	}
	continue;

    newBest:
	bestPtr = &visInfoList[i];
	bestPrio = prio;
    }

    *depthPtr = bestPtr->depth;
    visual = bestPtr->visual;
    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 (colormapPtr != NULL) {
	if (visual == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
	    *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
	} else {
	    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
		    cmapPtr = cmapPtr->nextPtr) {
		if (cmapPtr->shareable && (cmapPtr->visual == visual)) {
		    *colormapPtr = cmapPtr->colormap;
		    cmapPtr->refCount += 1;
		    goto done;
		}
	    }
	    cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
	    cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
		    RootWindowOfScreen(Tk_Screen(tkwin)), visual,
		    AllocNone);
	    cmapPtr->visual = visual;
	    cmapPtr->refCount = 1;
	    cmapPtr->shareable = 1;
	    cmapPtr->nextPtr = dispPtr->cmapPtr;
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
 *----------------------------------------------------------------------
 */

Colormap
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;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Tk_Window other;

    /*
     * Allocate a new colormap, if that's what is wanted.
     */

    if (strcmp(string, "new") == 0) {
	cmapPtr = (TkColormap *)ckalloc(sizeof(TkColormap));
	cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), Tk_Visual(tkwin),
		AllocNone);
	cmapPtr->visual = Tk_Visual(tkwin);
	cmapPtr->refCount = 1;
	cmapPtr->shareable = 0;
	cmapPtr->nextPtr = dispPtr->cmapPtr;







|












|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
 *----------------------------------------------------------------------
 */

Colormap
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;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Tk_Window other;

    /*
     * Allocate a new colormap, if that's what is wanted.
     */

    if (strcmp(string, "new") == 0) {
	cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
	cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), Tk_Visual(tkwin),
		AllocNone);
	cmapPtr->visual = Tk_Visual(tkwin);
	cmapPtr->refCount = 1;
	cmapPtr->shareable = 0;
	cmapPtr->nextPtr = dispPtr->cmapPtr;
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
     */

    other = Tk_NameToWindow(interp, string, tkwin);
    if (other == NULL) {
	return None;
    }
    if (Tk_Screen(other) != Tk_Screen(tkwin)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use colormap for %s: not on same screen", string));
	Tcl_SetErrorCode(interp, "TK", "COLORMAP", "SCREEN", NULL);
	return None;
    }
    if (Tk_Visual(other) != Tk_Visual(tkwin)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use colormap for %s: incompatible visuals", string));
	Tcl_SetErrorCode(interp, "TK", "COLORMAP", "INCOMPATIBLE", NULL);
	return None;
    }
    colormap = Tk_Colormap(other);

    /*
     * If the colormap was a special one allocated by code in this file,
     * increment its reference count.
     */

    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {
	    cmapPtr->refCount++;
	}
    }
    return colormap;
}

/*
 *----------------------------------------------------------------------







|
|
<



|
|
<












|







398
399
400
401
402
403
404
405
406

407
408
409
410
411

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
     */

    other = Tk_NameToWindow(interp, string, tkwin);
    if (other == NULL) {
	return None;
    }
    if (Tk_Screen(other) != Tk_Screen(tkwin)) {
	Tcl_AppendResult(interp, "can't use colormap for ", string,
		": 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", NULL);

	return None;
    }
    colormap = Tk_Colormap(other);

    /*
     * If the colormap was a special one allocated by code in this file,
     * increment its reference count.
     */

    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {
	    cmapPtr->refCount += 1;
	}
    }
    return colormap;
}

/*
 *----------------------------------------------------------------------
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
	Tcl_Panic("unknown display passed to Tk_FreeColormap");
    }
    for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {

	    if (cmapPtr->refCount-- <= 1) {
		XFreeColormap(display, colormap);
		if (prevPtr == NULL) {
		    dispPtr->cmapPtr = cmapPtr->nextPtr;
		} else {
		    prevPtr->nextPtr = cmapPtr->nextPtr;
		}
		ckfree(cmapPtr);
	    }
	    return;
	}
    }
}

/*







>
|






|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
	Tcl_Panic("unknown display passed to Tk_FreeColormap");
    }
    for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {
	    cmapPtr->refCount -= 1;
	    if (cmapPtr->refCount == 0) {
		XFreeColormap(display, colormap);
		if (prevPtr == NULL) {
		    dispPtr->cmapPtr = cmapPtr->nextPtr;
		} else {
		    prevPtr->nextPtr = cmapPtr->nextPtr;
		}
		ckfree((char *) cmapPtr);
	    }
	    return;
	}
    }
}

/*
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
	Tcl_Panic("unknown display passed to Tk_PreserveColormap");
    }
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {
	    cmapPtr->refCount++;
	    return;
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|












524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
	Tcl_Panic("unknown display passed to Tk_PreserveColormap");
    }
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
	    cmapPtr = cmapPtr->nextPtr) {
	if (cmapPtr->colormap == colormap) {
	    cmapPtr->refCount += 1;
	    return;
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkWindow.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "tkInt.h"
#include "tkPort.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif

/*
 * Type used to keep track of Window objects that were only partially







|
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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.
 */

#include "tkInt.h"

#ifdef __WIN32__
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif

/*
 * Type used to keep track of Window objects that were only partially
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55






56
57
58
59
60
61
62

typedef struct TkHalfdeadWindow {
    int flags;
    struct TkWindow *winPtr;
    struct TkHalfdeadWindow *nextPtr;
} TkHalfdeadWindow;

typedef struct {
    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. */
    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. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;







/*
 * 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 = {







|















>
>
>
>
>
>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

typedef struct TkHalfdeadWindow {
    int flags;
    struct TkWindow *winPtr;
    struct TkHalfdeadWindow *nextPtr;
} TkHalfdeadWindow;

typedef struct ThreadSpecificData {
    int numMainWindows;		/* Count of numver of main windows currently
				 * open in this thread. */
    TkMainInfo *mainWindowList;
				/* First in list of all main windows managed
				 * by this thread. */
    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. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The Mutex below is used to lock access to the Tk_Uid structs above.
 */

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.
 */

static const XWindowChanges defChanges = {
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * The following structure defines all of the commands supported by Tk, and
 * the C functions that execute them.
 */

#define ISSAFE 1
#define PASSMAINWINDOW 2

#define WINMACONLY 4
#define USEINITPROC 8

typedef int (TkInitProc)(Tcl_Interp *interp, ClientData clientData);
typedef struct {
    const char *name;		/* Name of command. */
    Tcl_ObjCmdProc *objProc;	/* Command's object- (or string-) based
				 * function, or initProc. */
    int flags;
} TkCmd;

static const TkCmd commands[] = {
    /*
     * Commands that are part of the intrinsics:
     */







>
|
<

<

|
|
<







93
94
95
96
97
98
99
100
101

102

103
104
105

106
107
108
109
110
111
112
/*
 * The following structure defines all of the commands supported by Tk, and
 * the C functions that execute them.
 */

#define ISSAFE 1
#define PASSMAINWINDOW 2
#define NOOBJPROC 4
#define WINMACONLY 8



typedef struct {
    const char *name;			/* Name of command. */
    Tcl_ObjCmdProc *objProc;	/* Command's object- (or string-) based function. */

    int flags;
} TkCmd;

static const TkCmd commands[] = {
    /*
     * Commands that are part of the intrinsics:
     */
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    {"font",		Tk_FontObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"grab",		Tk_GrabObjCmd,		PASSMAINWINDOW},
    {"grid",		Tk_GridObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"image",		Tk_ImageObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"lower",		Tk_LowerObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"option",		Tk_OptionObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"pack",		Tk_PackObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"place",		Tk_PlaceObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"raise",		Tk_RaiseObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"selection",	Tk_SelectionObjCmd,	PASSMAINWINDOW},
    {"tk",		(Tcl_ObjCmdProc *)(void *)TkInitTkCmd,  USEINITPROC|PASSMAINWINDOW|ISSAFE},
    {"tkwait",		Tk_TkwaitObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"update",		Tk_UpdateObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"winfo",		Tk_WinfoObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"wm",		Tk_WmObjCmd,		PASSMAINWINDOW},

    /*
     * Default widget class commands.
     */

    {"button",		Tk_ButtonObjCmd,	ISSAFE},
    {"canvas",		Tk_CanvasObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"checkbutton",	Tk_CheckbuttonObjCmd,	ISSAFE},
    {"entry",		Tk_EntryObjCmd,		ISSAFE},
    {"frame",		Tk_FrameObjCmd,		ISSAFE},
    {"label",		Tk_LabelObjCmd,		ISSAFE},
    {"labelframe",	Tk_LabelframeObjCmd,	ISSAFE},
    {"listbox",		Tk_ListboxObjCmd,	ISSAFE},
    {"menu",		Tk_MenuObjCmd,	PASSMAINWINDOW},
    {"menubutton",	Tk_MenubuttonObjCmd,	ISSAFE},
    {"message",		Tk_MessageObjCmd,	ISSAFE},
    {"panedwindow",	Tk_PanedWindowObjCmd,	ISSAFE},
    {"radiobutton",	Tk_RadiobuttonObjCmd,	ISSAFE},
    {"scale",		Tk_ScaleObjCmd,		ISSAFE},
    {"scrollbar",	Tk_ScrollbarObjCmd, PASSMAINWINDOW|ISSAFE},
    {"spinbox",		Tk_SpinboxObjCmd,	ISSAFE},
    {"text",		Tk_TextObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"toplevel",	Tk_ToplevelObjCmd,	0},

    /*
     * Classic widget class commands.
     */







|


|

















<





|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
    {"font",		Tk_FontObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"grab",		Tk_GrabObjCmd,		PASSMAINWINDOW},
    {"grid",		Tk_GridObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"image",		Tk_ImageObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"lower",		Tk_LowerObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"option",		Tk_OptionObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"pack",		Tk_PackObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"place",		Tk_PlaceObjCmd,		ISSAFE},
    {"raise",		Tk_RaiseObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"selection",	Tk_SelectionObjCmd,	PASSMAINWINDOW},
    {"tk",		Tk_TkObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"tkwait",		Tk_TkwaitObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"update",		Tk_UpdateObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"winfo",		Tk_WinfoObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"wm",		Tk_WmObjCmd,		PASSMAINWINDOW},

    /*
     * Default widget class commands.
     */

    {"button",		Tk_ButtonObjCmd,	ISSAFE},
    {"canvas",		Tk_CanvasObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"checkbutton",	Tk_CheckbuttonObjCmd,	ISSAFE},
    {"entry",		Tk_EntryObjCmd,		ISSAFE},
    {"frame",		Tk_FrameObjCmd,		ISSAFE},
    {"label",		Tk_LabelObjCmd,		ISSAFE},
    {"labelframe",	Tk_LabelframeObjCmd,	ISSAFE},
    {"listbox",		Tk_ListboxObjCmd,	ISSAFE},

    {"menubutton",	Tk_MenubuttonObjCmd,	ISSAFE},
    {"message",		Tk_MessageObjCmd,	ISSAFE},
    {"panedwindow",	Tk_PanedWindowObjCmd,	ISSAFE},
    {"radiobutton",	Tk_RadiobuttonObjCmd,	ISSAFE},
    {"scale",		Tk_ScaleObjCmd,		ISSAFE},
    {"scrollbar",	(Tcl_ObjCmdProc *) Tk_ScrollbarCmd,	NOOBJPROC|PASSMAINWINDOW|ISSAFE},
    {"spinbox",		Tk_SpinboxObjCmd,	ISSAFE},
    {"text",		Tk_TextObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"toplevel",	Tk_ToplevelObjCmd,	0},

    /*
     * Classic widget class commands.
     */
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201


































202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    {"::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",	Tk_ScrollbarObjCmd, 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.
     */

#ifdef MAC_OSX_TK
    {"::tk::unsupported::MacWindowStyle",
			TkUnsupported1ObjCmd,	PASSMAINWINDOW|ISSAFE},
#endif
    {NULL,		NULL,			0}
};



































/*
 * Forward declarations to functions defined later in this file:
 */

static Tk_Window	CreateTopLevelWindow(Tcl_Interp *interp,
			    Tk_Window parent, const char *name,
			    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 --
 *







|









|











|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|

|



|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    {"::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},
#endif
    {NULL,		NULL,			0}
};

/*
 * The variables and table below are used to parse arguments from the "argv"
 * variable in Tk_Init.
 */

static int synchronize = 0;
static char *name = NULL;
static char *display = NULL;
static char *geometry = NULL;
static char *colormap = NULL;
static char *use = NULL;
static char *visual = NULL;
static int rest = 0;

static Tk_ArgvInfo argTable[] = {
    {"-colormap", TK_ARGV_STRING, NULL, (char *) &colormap,
	"Colormap for main window"},
    {"-display", TK_ARGV_STRING, NULL, (char *) &display,
	"Display to use"},
    {"-geometry", TK_ARGV_STRING, NULL, (char *) &geometry,
	"Initial geometry for window"},
    {"-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, NULL, (char *) &visual,
	"Visual for main window"},
    {"-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"},
    {NULL, TK_ARGV_END, NULL, NULL, NULL}
};

/*
 * Forward declarations to functions defined later in this file:
 */

static Tk_Window	CreateTopLevelWindow(Tcl_Interp *interp,
			    Tk_Window parent, CONST char *name,
			    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 --
 *
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	Tcl_DeleteHashTable(&dispPtr->nameTable);
	Tcl_DeleteHashTable(&dispPtr->atomTable);
	dispPtr->atomInit = 0;
    }

    if (dispPtr->errorPtr != NULL) {
	TkErrorHandler *errorPtr;

	for (errorPtr = dispPtr->errorPtr;
		errorPtr != NULL;
		errorPtr = dispPtr->errorPtr) {
	    dispPtr->errorPtr = errorPtr->nextPtr;
	    ckfree(errorPtr);
	}
    }

    TkGCCleanup(dispPtr);

    TkpCloseDisplay(dispPtr);

    /*
     * Delete winTable after TkpCloseDisplay since special windows may need
     * call Tk_DestroyWindow and it checks the winTable.
     */

    Tcl_DeleteHashTable(&dispPtr->winTable);

    ckfree(dispPtr);

    /*
     * There is more to clean up, we leave it at this for the time being.
     */
}

/*







<




|














|







284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	Tcl_DeleteHashTable(&dispPtr->nameTable);
	Tcl_DeleteHashTable(&dispPtr->atomTable);
	dispPtr->atomInit = 0;
    }

    if (dispPtr->errorPtr != NULL) {
	TkErrorHandler *errorPtr;

	for (errorPtr = dispPtr->errorPtr;
		errorPtr != NULL;
		errorPtr = dispPtr->errorPtr) {
	    dispPtr->errorPtr = errorPtr->nextPtr;
	    ckfree((char *) errorPtr);
	}
    }

    TkGCCleanup(dispPtr);

    TkpCloseDisplay(dispPtr);

    /*
     * Delete winTable after TkpCloseDisplay since special windows may need
     * call Tk_DestroyWindow and it checks the winTable.
     */

    Tcl_DeleteHashTable(&dispPtr->winTable);

    ckfree((char *) dispPtr);

    /*
     * There is more to clean up, we leave it at this for the time being.
     */
}

/*
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

static Tk_Window
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. */
{
    TkWindow *winPtr;
    TkDisplay *dispPtr;
    int screenId;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;

	/*
	 * Create built-in image types.
	 */

	Tk_CreateImageType(&tkBitmapImageType);
	Tk_CreateImageType(&tkPhotoImageType);

	/*
	 * Create built-in photo image formats.
	 */

        Tk_CreatePhotoImageFormat(&tkImgFmtDefault);
	Tk_CreatePhotoImageFormat(&tkImgFmtGIF);
	Tk_CreatePhotoImageFormat(&tkImgFmtPNG);
	Tk_CreatePhotoImageFormat(&tkImgFmtPPM);
	Tk_CreatePhotoImageFormat(&tkImgFmtSVGnano);
    }

    if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
	dispPtr = ((TkWindow *) parent)->dispPtr;
	screenId = Tk_ScreenNumber(parent);
    } else {
	dispPtr = GetScreen(interp, screenName, &screenId);
	if (dispPtr == NULL) {
	    return NULL;
	}
    }

    winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent);

    /*
     * Set the flags specified in the call.
     */

    winPtr->ximGeneration = 0;
    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.







|

|






|
|


















<

<

<








|









<







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373

374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399

static Tk_Window
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. */
{
    register TkWindow *winPtr;
    register TkDisplay *dispPtr;
    int screenId;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;

	/*
	 * Create built-in image types.
	 */

	Tk_CreateImageType(&tkBitmapImageType);
	Tk_CreateImageType(&tkPhotoImageType);

	/*
	 * Create built-in photo image formats.
	 */


	Tk_CreatePhotoImageFormat(&tkImgFmtGIF);

	Tk_CreatePhotoImageFormat(&tkImgFmtPPM);

    }

    if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
	dispPtr = ((TkWindow *) parent)->dispPtr;
	screenId = Tk_ScreenNumber(parent);
    } else {
	dispPtr = GetScreen(interp, screenName, &screenId);
	if (dispPtr == NULL) {
	    return (Tk_Window) NULL;
	}
    }

    winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent);

    /*
     * 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.
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

    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) {
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    return NULL;
	}
    }
    TkWmNewWindow(winPtr);

    return (Tk_Window) winPtr;
}








|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

    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) {
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    return (Tk_Window) NULL;
	}
    }
    TkWmNewWindow(winPtr);

    return (Tk_Window) winPtr;
}

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
 *
 *----------------------------------------------------------------------
 */

static TkDisplay *
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. */
{
    TkDisplay *dispPtr;
    const char *p;
    int screenId;
    size_t length;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Separate the screen number from the rest of the display name.
     * ScreenName is assumed to have the syntax <display>.<screen> with the
     * dot and the screen being optional.
     */

    screenName = TkGetDefaultScreenName(interp, screenName);
    if (screenName == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no display name and no $DISPLAY environment variable", -1));
	Tcl_SetErrorCode(interp, "TK", "NO_DISPLAY", NULL);
	return NULL;
    }
    length = strlen(screenName);
    screenId = 0;
    p = screenName+length-1;
    while (isdigit(UCHAR(*p)) && (p != screenName)) {
	p--;







|



|
|













|
|
|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
 *
 *----------------------------------------------------------------------
 */

static TkDisplay *
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));

    /*
     * 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);
    if (screenName == NULL) {
	Tcl_SetResult(interp,
		"no display name and no $DISPLAY environment variable",
		TCL_STATIC);
	return NULL;
    }
    length = strlen(screenName);
    screenId = 0;
    p = screenName+length-1;
    while (isdigit(UCHAR(*p)) && (p != screenName)) {
	p--;
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490


491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508
	    /*
	     * 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_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't connect to display \"%s\"", screenName));
		Tcl_SetErrorCode(interp, "TK", "DISPLAY", "CONNECT", NULL);
		return NULL;
	    }
	    dispPtr->nextPtr = tsdPtr->displayList; /* TkGetDisplayList(); */
	    tsdPtr->displayList = dispPtr;

	    dispPtr->lastEventTime = CurrentTime;
	    dispPtr->bindInfoStale = 1;
	    dispPtr->cursorFont = None;
	    dispPtr->warpWindow = NULL;
	    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);

	    dispPtr->name = (char *)ckalloc(length + 1);
	    strncpy(dispPtr->name, screenName, length);
	    dispPtr->name[length] = '\0';


	    break;
	}
	if ((strncmp(dispPtr->name, screenName, length) == 0)
		&& (dispPtr->name[length] == '\0')) {
	    break;
	}
    }
    if (screenId >= ScreenCount(dispPtr->display)) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad screen number \"%d\"", screenId));
	Tcl_SetErrorCode(interp, "TK", "DISPLAY", "SCREEN_NUMBER", NULL);
	return NULL;
    }
    *screenPtr = screenId;
    return dispPtr;
}

/*







|
|
|








|











|


>
>








>
|
|
|







490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
	    /*
	     * 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, "\"", NULL);
		return NULL;
	    }
	    dispPtr->nextPtr = tsdPtr->displayList; /* TkGetDisplayList(); */
	    tsdPtr->displayList = dispPtr;

	    dispPtr->lastEventTime = CurrentTime;
	    dispPtr->bindInfoStale = 1;
	    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);

	    dispPtr->name = (char *) ckalloc((unsigned) (length+1));
	    strncpy(dispPtr->name, screenName, length);
	    dispPtr->name[length] = '\0';

	    TkInitXId(dispPtr);
	    break;
	}
	if ((strncmp(dispPtr->name, screenName, length) == 0)
		&& (dispPtr->name[length] == '\0')) {
	    break;
	}
    }
    if (screenId >= ScreenCount(dispPtr->display)) {
	char buf[32 + TCL_INTEGER_SPACE];

	sprintf(buf, "bad screen number \"%d\"", screenId);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return NULL;
    }
    *screenPtr = screenId;
    return dispPtr;
}

/*
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
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. */
{
    TkWindow *winPtr = (TkWindow *)ckalloc(sizeof(TkWindow));


    winPtr->display = dispPtr->display;
    winPtr->dispPtr = dispPtr;
    winPtr->screenNum = screenNum;
    if ((parentPtr != NULL) && (parentPtr->display == winPtr->display)
	    && (parentPtr->screenNum == winPtr->screenNum)) {
	winPtr->visual = parentPtr->visual;
	winPtr->depth = parentPtr->depth;







|

>







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
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;

    winPtr = (TkWindow *) ckalloc(sizeof(TkWindow));
    winPtr->display = dispPtr->display;
    winPtr->dispPtr = dispPtr;
    winPtr->screenNum = screenNum;
    if ((parentPtr != NULL) && (parentPtr->display == winPtr->display)
	    && (parentPtr->screenNum == winPtr->screenNum)) {
	winPtr->visual = parentPtr->visual;
	winPtr->depth = parentPtr->depth;
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
	winPtr->atts.colormap = parentPtr->atts.colormap;
    } else {
	winPtr->atts.colormap = DefaultColormap(dispPtr->display, screenNum);
    }
    winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity;
    winPtr->flags = 0;
    winPtr->handlerList = NULL;
    winPtr->ximGeneration = 0;
    winPtr->inputContext = NULL;

    winPtr->tagPtr = NULL;
    winPtr->numTags = 0;
    winPtr->optionLevel = -1;
    winPtr->selHandlerList = NULL;
    winPtr->geomMgrPtr = NULL;
    winPtr->geomData = NULL;
    winPtr->geomMgrName = NULL;
    winPtr->maintainerPtr = NULL;
    winPtr->reqWidth = winPtr->reqHeight = 1;
    winPtr->internalBorderLeft = 0;
    winPtr->wmInfoPtr = NULL;
    winPtr->classProcsPtr = NULL;
    winPtr->instanceData = NULL;
    winPtr->privatePtr = NULL;
    winPtr->internalBorderRight = 0;







|

>






<
<







684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699


700
701
702
703
704
705
706
	winPtr->atts.colormap = parentPtr->atts.colormap;
    } else {
	winPtr->atts.colormap = DefaultColormap(dispPtr->display, screenNum);
    }
    winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity;
    winPtr->flags = 0;
    winPtr->handlerList = NULL;
#ifdef TK_USE_INPUT_METHODS
    winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
    winPtr->tagPtr = NULL;
    winPtr->numTags = 0;
    winPtr->optionLevel = -1;
    winPtr->selHandlerList = NULL;
    winPtr->geomMgrPtr = NULL;
    winPtr->geomData = NULL;


    winPtr->reqWidth = winPtr->reqHeight = 1;
    winPtr->internalBorderLeft = 0;
    winPtr->wmInfoPtr = NULL;
    winPtr->classProcsPtr = NULL;
    winPtr->instanceData = NULL;
    winPtr->privatePtr = NULL;
    winPtr->internalBorderRight = 0;
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
 *
 *----------------------------------------------------------------------
 */

static int
NameWindow(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    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 isNew;
    Tcl_HashEntry *hPtr;







|


|







728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
 *
 *----------------------------------------------------------------------
 */

static int
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 isNew;
    Tcl_HashEntry *hPtr;
733
734
735
736
737
738
739






740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
     * now.
     */

    if (winPtr->flags & TK_ANONYMOUS_WINDOW) {
	return TCL_OK;
    }







    /*
     * 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_SetObjResult(interp, Tcl_ObjPrintf(
		"window name starts with an upper-case letter: \"%s\"",
		name));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW", "NOTCLASS", NULL);
	return TCL_ERROR;
    }

    /*
     * For non-anonymous windows, set up the window name.
     */

    winPtr->nameUid = Tk_GetUid(name);

    /*
     * 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);
    length2 = strlen(name);
    if ((length1 + length2 + 2) <= FIXED_SIZE) {
	pathName = staticSpace;
    } else {
	pathName = (char *)ckalloc(length1 + length2 + 2);
    }
    if (length1 == 1) {
	pathName[0] = '.';
	strcpy(pathName+1, name);
    } else {
	strcpy(pathName, parentPtr->pathName);
	pathName[length1] = '.';
	strcpy(pathName+length1+1, name);
    }
    hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName,
	    &isNew);
    if (pathName != staticSpace) {
	ckfree(pathName);
    }
    if (!isNew) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window name \"%s\" already exists in parent", name));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW", "EXISTS", NULL);
	return TCL_ERROR;
    }
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->pathName = (char *)Tcl_GetHashKey(&parentPtr->mainPtr->nameTable, hPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkCreateMainWindow --







>
>
>
>
>
>






|
|
|
<



<
<
<
<
<
<








|


|















|
|
<



|







768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789

790
791
792






793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
829
830
831
832
     * now.
     */

    if (winPtr->flags & TK_ANONYMOUS_WINDOW) {
	return TCL_OK;
    }

    /*
     * For non-anonymous windows, set up the window 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.
     */

    if (isupper(UCHAR(name[0]))) {
	Tcl_AppendResult(interp,
		"window name starts with an upper-case letter: \"",
		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.
     */

    length1 = strlen(parentPtr->pathName);
    length2 = strlen(name);
    if ((length1+length2+2) <= FIXED_SIZE) {
	pathName = staticSpace;
    } else {
	pathName = (char *) ckalloc((unsigned) (length1+length2+2));
    }
    if (length1 == 1) {
	pathName[0] = '.';
	strcpy(pathName+1, name);
    } else {
	strcpy(pathName, parentPtr->pathName);
	pathName[length1] = '.';
	strcpy(pathName+length1+1, name);
    }
    hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName,
	    &isNew);
    if (pathName != staticSpace) {
	ckfree(pathName);
    }
    if (!isNew) {
	Tcl_AppendResult(interp, "window name \"", name,
		"\" already exists in parent", NULL);

	return TCL_ERROR;
    }
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->pathName = Tcl_GetHashKey(&parentPtr->mainPtr->nameTable, hPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkCreateMainWindow --
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
 *
 *----------------------------------------------------------------------
 */

Tk_Window
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. */
    const char *baseName)	/* Base name for application; usually of the
				 * form "prog instance". */
{
    Tk_Window tkwin;
    int dummy, isSafe;
    Tcl_HashEntry *hPtr;
    TkMainInfo *mainPtr;
    TkWindow *winPtr;
    const TkCmd *cmdPtr;
    ClientData clientData;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Panic if someone updated the TkWindow structure without also updating
     * the Tk_FakeWin structure (or vice versa).
     */

    if (sizeof(TkWindow) != sizeof(Tk_FakeWin)) {
	Tcl_Panic("TkWindow and Tk_FakeWin are not the same size");
    }

    /*
     * Create the basic TkWindow structure.
     */

    tkwin = CreateTopLevelWindow(interp, NULL, baseName,
	    screenName, /* flags */ 0);
    if (tkwin == NULL) {
	return NULL;
    }

    /*
     * Create the TkMainInfo structure for this application, and set up
     * name-related information for the new window.
     */

    winPtr = (TkWindow *) tkwin;
    mainPtr = (TkMainInfo *)ckalloc(sizeof(TkMainInfo));
    mainPtr->winPtr = winPtr;
    mainPtr->refCount = 1;
    mainPtr->interp = interp;
    Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS);
    mainPtr->deletionEpoch = 0l;
    TkEventInit();
    TkBindInit(mainPtr);







|


|





|
|
|

















|











|







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 *
 *----------------------------------------------------------------------
 */

Tk_Window
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, isSafe;
    Tcl_HashEntry *hPtr;
    register TkMainInfo *mainPtr;
    register TkWindow *winPtr;
    register const TkCmd *cmdPtr;
    ClientData clientData;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Panic if someone updated the TkWindow structure without also updating
     * the Tk_FakeWin structure (or vice versa).
     */

    if (sizeof(TkWindow) != sizeof(Tk_FakeWin)) {
	Tcl_Panic("TkWindow and Tk_FakeWin are not the same size");
    }

    /*
     * Create the basic TkWindow structure.
     */

    tkwin = CreateTopLevelWindow(interp, (Tk_Window) NULL, baseName,
	    screenName, /* flags */ 0);
    if (tkwin == NULL) {
	return NULL;
    }

    /*
     * Create the TkMainInfo structure for this application, and set up
     * name-related information for the new window.
     */

    winPtr = (TkWindow *) tkwin;
    mainPtr = (TkMainInfo *) ckalloc(sizeof(TkMainInfo));
    mainPtr->winPtr = winPtr;
    mainPtr->refCount = 1;
    mainPtr->interp = interp;
    Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS);
    mainPtr->deletionEpoch = 0l;
    TkEventInit();
    TkBindInit(mainPtr);
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
	Tcl_ResetResult(interp);
    }
    mainPtr->nextPtr = tsdPtr->mainWindowList;
    tsdPtr->mainWindowList = mainPtr;
    winPtr->mainPtr = mainPtr;
    hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->pathName = (char *)Tcl_GetHashKey(&mainPtr->nameTable, hPtr);
    Tcl_InitHashTable(&mainPtr->busyTable, TCL_ONE_WORD_KEYS);

    /*
     * We have just created another Tk application; increment the refcount on
     * the display pointer.
     */

    winPtr->dispPtr->refCount++;







|
<







922
923
924
925
926
927
928
929

930
931
932
933
934
935
936
	Tcl_ResetResult(interp);
    }
    mainPtr->nextPtr = tsdPtr->mainWindowList;
    tsdPtr->mainWindowList = mainPtr;
    winPtr->mainPtr = mainPtr;
    hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr);


    /*
     * We have just created another Tk application; increment the refcount on
     * the display pointer.
     */

    winPtr->dispPtr->refCount++;
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937

938
939
940
941
942

943
944

945
946
947


948
949
950
951
952
953
954
955
956
957
958
959
960
     */

    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
	if (cmdPtr->objProc == NULL) {
	    Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
	}

#if defined(_WIN32) && !defined(STATIC_BUILD)
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {
	    /*
	     * We are running on Cygwin, so don't use the win32 dialogs.
	     */

	    continue;
	}
#endif /* _WIN32 && !STATIC_BUILD */

	if (cmdPtr->flags & PASSMAINWINDOW) {
	    clientData = tkwin;
	} else {
	    clientData = NULL;
	}
	if (cmdPtr->flags & USEINITPROC) {

	    ((TkInitProc *)(void *)cmdPtr->objProc)(interp, clientData);
	} else {
	    Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
		    clientData, NULL);
	}

	if (isSafe && !(cmdPtr->flags & ISSAFE)) {
	    Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name);

	}
    }



    /*
     * Set variables for the interpreter.
     */

    Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
    Tcl_SetVar2(interp, "tk_version",    NULL, TK_VERSION,     TCL_GLOBAL_ONLY);

    tsdPtr->numMainWindows++;
    return tkwin;
}

/*
 *--------------------------------------------------------------







<
|

<
|
<
<


|
<

|

|

|
>
|




>
|
|
>



>
>

|


|
|







946
947
948
949
950
951
952

953
954

955


956
957
958

959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
     */

    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
	if (cmdPtr->objProc == NULL) {
	    Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
	}

#if defined(__WIN32__) && !defined(STATIC_BUILD)
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {

	    /* We are running on Cygwin, so don't use the win32 dialogs */


	    continue;
	}
#endif

	if (cmdPtr->flags & PASSMAINWINDOW) {
	    clientData = (ClientData) tkwin;
	} else {
	    clientData = (ClientData) NULL;
	}
	if (cmdPtr->flags & NOOBJPROC) {
	    Tcl_CreateCommand(interp, cmdPtr->name,
		    (Tcl_CmdProc *)(void *)cmdPtr->objProc, clientData, NULL);
	} else {
	    Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
		    clientData, NULL);
	}
	if (isSafe) {
	    if (!(cmdPtr->flags & ISSAFE)) {
		Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name);
	    }
	}
    }

    TkCreateMenuCmd(interp);

    /*
     * Set variables for the intepreter.
     */

    Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "tk_version",    TK_VERSION,     TCL_GLOBAL_ONLY);

    tsdPtr->numMainWindows++;
    return tkwin;
}

/*
 *--------------------------------------------------------------
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008


1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

Tk_Window
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
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;


    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;

	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;


	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);

	    if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) {
		Tk_DestroyWindow((Tk_Window) winPtr);
		return NULL;
	    }
	    return (Tk_Window) winPtr;
	}
    }
    return CreateTopLevelWindow(interp, parent, name, screenName,
	    /* flags */ 0);
}

/*
 *--------------------------------------------------------------







|

|






>

<
|
|
|
<
|
>
|
|
|
<
<
|
>
>
|
|
|
<
|
|
|
|
|
<







1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029

1030
1031
1032

1033
1034
1035
1036
1037


1038
1039
1040
1041
1042
1043

1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055

Tk_Window
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
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;
    TkWindow *winPtr;


    if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) {
	Tcl_AppendResult(interp,
		"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", 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;
	}
	return (Tk_Window) winPtr;

    }
    return CreateTopLevelWindow(interp, parent, name, screenName,
	    /* flags */ 0);
}

/*
 *--------------------------------------------------------------
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059

1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094

Tk_Window
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
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;


    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;

	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;

	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);
	    /*
	     * Add the anonymous window flag now, so that NameWindow will
	     * behave correctly.
	     */

	    winPtr->flags |= TK_ANONYMOUS_WINDOW;
	    if (NameWindow(interp, winPtr, parentPtr, NULL) != TCL_OK) {
		Tk_DestroyWindow((Tk_Window) winPtr);
		return NULL;
	    }
	    return (Tk_Window) winPtr;
	}
    }
    return CreateTopLevelWindow(interp, parent, NULL, screenName,
	    TK_ANONYMOUS_WINDOW);
}

/*
 *----------------------------------------------------------------------







|






>

<
|
|
|
<
|
>
|
|
|
<
<
|
>
|
|
|
|
|
|
|

|
|
|
|
|
|
<







1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094

1095
1096
1097
1098
1099


1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115

1116
1117
1118
1119
1120
1121
1122

Tk_Window
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
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;
    TkWindow *winPtr;


    if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) {
	Tcl_AppendResult(interp,
		"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", NULL);


	return NULL;
    }
    if (screenName == NULL) {
	winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum,
		parentPtr);
	/*
	 * Add the anonymous window flag now, so that NameWindow will behave
	 * correctly.
	 */

	winPtr->flags |= TK_ANONYMOUS_WINDOW;
	if (NameWindow(interp, winPtr, parentPtr, NULL) != TCL_OK) {
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    return NULL;
	}
	return (Tk_Window) winPtr;

    }
    return CreateTopLevelWindow(interp, parent, NULL, screenName,
	    TK_ANONYMOUS_WINDOW);
}

/*
 *----------------------------------------------------------------------
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
Tk_Window
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. */
{
#define FIXED_SPACE 5
    char fixedSpace[FIXED_SPACE+1];
    char *p;
    Tk_Window parent;
    size_t 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 ".".
     */

    p = (char *)strrchr(pathName, '.');
    if (p == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad window path name \"%s\"", pathName));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	return NULL;
    }
    numChars = p-pathName;
    if (numChars > FIXED_SPACE) {
	p = (char *)ckalloc(numChars + 1);
    } else {
	p = fixedSpace;
    }
    if (numChars == 0) {
	*p = '.';
	p[1] = '\0';
    } else {
	strncpy(p, pathName, numChars);
	p[numChars] = '\0';
    }

    /*
     * Find the parent window.
     */

    parent = Tk_NameToWindow(interp, p, tkwin);
    if (p != fixedSpace) {
	ckfree(p);
    }
    if (parent == NULL) {
	return NULL;
    }
    if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: parent has been destroyed", -1));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	return NULL;

    } else if (((TkWindow *) parent)->flags & TK_CONTAINER) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: its parent has -container = yes", -1));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	return NULL;
    }

    /*
     * Create the window.
     */








|



|








|









|

<
|
|


|

|







|















|
|
<

>
|
|
|
<







1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211

1212
1213
1214
1215
1216
1217
1218
Tk_Window
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. */
{
#define FIXED_SPACE 5
    char fixedSpace[FIXED_SPACE+1];
    char *p;
    Tk_Window parent;
    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 ".".
     */

    p = strrchr(pathName, '.');
    if (p == NULL) {

	Tcl_AppendResult(interp, "bad window path name \"", pathName,
		"\"", NULL);
	return NULL;
    }
    numChars = (int) (p-pathName);
    if (numChars > FIXED_SPACE) {
	p = (char *) ckalloc((unsigned) (numChars+1));
    } else {
	p = fixedSpace;
    }
    if (numChars == 0) {
	*p = '.';
	p[1] = '\0';
    } else {
	strncpy(p, pathName, (size_t) numChars);
	p[numChars] = '\0';
    }

    /*
     * Find the parent window.
     */

    parent = Tk_NameToWindow(interp, p, tkwin);
    if (p != fixedSpace) {
	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", NULL);

	return NULL;
    }
    if (((TkWindow *) parent)->flags & TK_CONTAINER) {
	Tcl_AppendResult(interp,
		"can't create window: its parent has -container = yes", NULL);

	return NULL;
    }

    /*
     * Create the window.
     */

1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
     */

    if (tsdPtr->halfdeadWindowList &&
	    (tsdPtr->halfdeadWindowList->flags & HD_CLEANUP) &&
	    (tsdPtr->halfdeadWindowList->winPtr == winPtr)) {
	halfdeadPtr = tsdPtr->halfdeadWindowList;
    } else {
	halfdeadPtr = (TkHalfdeadWindow *)ckalloc(sizeof(TkHalfdeadWindow));
	halfdeadPtr->flags = 0;
	halfdeadPtr->winPtr = winPtr;
	halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList;
	tsdPtr->halfdeadWindowList = halfdeadPtr;
    }

    /*







|







1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
     */

    if (tsdPtr->halfdeadWindowList &&
	    (tsdPtr->halfdeadWindowList->flags & HD_CLEANUP) &&
	    (tsdPtr->halfdeadWindowList->winPtr == winPtr)) {
	halfdeadPtr = tsdPtr->halfdeadWindowList;
    } else {
	halfdeadPtr = (TkHalfdeadWindow *) ckalloc(sizeof(TkHalfdeadWindow));
	halfdeadPtr->flags = 0;
	halfdeadPtr->winPtr = winPtr;
	halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList;
	tsdPtr->halfdeadWindowList = halfdeadPtr;
    }

    /*
1317
1318
1319
1320
1321
1322
1323

1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
     * 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)) {
	halfdeadPtr->flags |= HD_DESTROY_COUNT;

    }

    while (winPtr->childList != NULL) {
	TkWindow *childPtr = winPtr->childList;

	childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	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







>



|
|







1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
     * 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)) {
	halfdeadPtr->flags |= HD_DESTROY_COUNT;
	dispPtr->destroyCount++;
    }

    while (winPtr->childList != NULL) {
	TkWindow *childPtr;
	childPtr = winPtr->childList;
	childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	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
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
	 * 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 = TkpGetOtherWindow(winPtr);

	if (childPtr != NULL) {
	    childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	    Tk_DestroyWindow((Tk_Window) childPtr);
	}
    }

    /*







|
|







1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
	 * 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;
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL) {
	    childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	    Tk_DestroyWindow((Tk_Window) childPtr);
	}
    }

    /*
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440

1441
1442
1443
1444

1445
1446


1447
1448
1449
1450
1451


1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
	    halfdeadPtr != NULL; ) {
	if (halfdeadPtr->winPtr == winPtr) {
	    if (prev_halfdeadPtr == NULL) {
		tsdPtr->halfdeadWindowList = halfdeadPtr->nextPtr;
	    } else {
		prev_halfdeadPtr->nextPtr = halfdeadPtr->nextPtr;
	    }
	    ckfree(halfdeadPtr);
	    break;
	}
	prev_halfdeadPtr = halfdeadPtr;
	halfdeadPtr = halfdeadPtr->nextPtr;
    }
    if (halfdeadPtr == NULL) {
	Tcl_Panic("window not found on half dead list");
    }

    /*
     * Cleanup the data structures associated with this window.
     */

    if (winPtr->flags & TK_WIN_MANAGED) {
	TkWmDeadWindow(winPtr);
    } else if (winPtr->flags & TK_WM_COLORMAP_WINDOW) {
	TkWmRemoveFromColormapWindows(winPtr);
    }
    if (winPtr->window != None) {
#if defined(MAC_OSX_TK) || defined(_WIN32)
	XDestroyWindow(winPtr->display, winPtr->window);
#else
	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.
	     */


	    XDestroyWindow(winPtr->display, winPtr->window);
	}
#endif

	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable,
		winPtr->window));
	winPtr->window = None;
    }

    UnlinkWindow(winPtr);
    TkEventDeadWindow(winPtr);


    if (winPtr->inputContext != NULL &&
	winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
	XDestroyIC(winPtr->inputContext);
    }
    winPtr->inputContext = NULL;


    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    TkOptionDeadWindow(winPtr);
    TkSelDeadWindow(winPtr);
    TkGrabDeadWindow(winPtr);
    if (winPtr->geomMgrName != NULL) {
	ckfree(winPtr->geomMgrName);
	winPtr->geomMgrName = NULL;
    }
    if (winPtr->mainPtr != NULL) {
	if (winPtr->pathName != NULL) {
	    Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable,
		    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.
	     */

	    winPtr->mainPtr->deletionEpoch++;
	}

	if (winPtr->mainPtr->refCount-- <= 1) {
	    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.
	     *
	     * 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_CreateObjCommand(winPtr->mainPtr->interp, cmdPtr->name,
			    TkDeadAppObjCmd, NULL, NULL);
		}
		Tcl_CreateObjCommand(winPtr->mainPtr->interp, "send",
			TkDeadAppObjCmd, NULL, NULL);
		Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
		Tcl_UnlinkVar(winPtr->mainPtr->interp,
			"::tk::AlwaysShowSelection");
	    }

	    Tcl_DeleteHashTable(&winPtr->mainPtr->busyTable);
	    Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable);
	    TkBindFree(winPtr->mainPtr);
	    TkDeleteAllImages(winPtr->mainPtr);
	    TkFontPkgFree(winPtr->mainPtr);
	    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
	     */

	    if (winPtr->flags & TK_EMBEDDED) {
		XSync(winPtr->display, False);
	    }
	    ckfree(winPtr->mainPtr);

	    /*
	     * 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
		 *







|



















|











>



>

|


>


>
>
|
<

<
|
>
>






<
<
<
<



|


















>
|
|













|

|
|

|
|

|



<

















|






|







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479

1480

1481
1482
1483
1484
1485
1486
1487
1488
1489




1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
	    halfdeadPtr != NULL; ) {
	if (halfdeadPtr->winPtr == winPtr) {
	    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) {
	Tcl_Panic("window not found on half dead list");
    }

    /*
     * Cleanup the data structures associated with this window.
     */

    if (winPtr->flags & TK_WIN_MANAGED) {
	TkWmDeadWindow(winPtr);
    } else if (winPtr->flags & TK_WM_COLORMAP_WINDOW) {
	TkWmRemoveFromColormapWindows(winPtr);
    }
    if (winPtr->window != None) {
#if defined(MAC_OSX_TK) || defined(__WIN32__)
	XDestroyWindow(winPtr->display, winPtr->window);
#else
	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.
	     */

	    dispPtr->lastDestroyRequest = NextRequest(winPtr->display);
	    XDestroyWindow(winPtr->display, winPtr->window);
	}
#endif
	TkFreeWindowId(dispPtr, winPtr->window);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable,
		(char *) winPtr->window));
	winPtr->window = None;
    }
    dispPtr->destroyCount--;
    UnlinkWindow(winPtr);
    TkEventDeadWindow(winPtr);
    TkBindDeadWindow(winPtr);
#ifdef TK_USE_INPUT_METHODS
    if (winPtr->inputContext != NULL) {

	XDestroyIC(winPtr->inputContext);

	winPtr->inputContext = NULL;
    }
#endif /* TK_USE_INPUT_METHODS */
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    TkOptionDeadWindow(winPtr);
    TkSelDeadWindow(winPtr);
    TkGrabDeadWindow(winPtr);




    if (winPtr->mainPtr != NULL) {
	if (winPtr->pathName != NULL) {
	    Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable,
		    (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.
	     */

	    winPtr->mainPtr->deletionEpoch++;
	}
	winPtr->mainPtr->refCount--;
	if (winPtr->mainPtr->refCount == 0) {
	    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.
	     *
	     * 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, 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);
	    TkDeleteAllImages(winPtr->mainPtr);
	    TkFontPkgFree(winPtr->mainPtr);
	    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
	     */

	    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 !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
		 *
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

		/*
		 * Found and spliced it out, now actually do the cleanup.
		 */

		TkCloseDisplay(dispPtr);
	    }
#endif /* !_WIN32 && NOT_YET */
	}
    }
    Tcl_EventuallyFree(winPtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MapWindow --
 *







|


|







1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622

		/*
		 * Found and spliced it out, now actually do the cleanup.
		 */

		TkCloseDisplay(dispPtr);
	    }
#endif
	}
    }
    Tcl_EventuallyFree((ClientData) winPtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MapWindow --
 *
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
    event.type = MapNotify;
    event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
    event.xmap.send_event = False;
    event.xmap.display = winPtr->display;
    event.xmap.event = winPtr->window;
    event.xmap.window = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *







|







1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
    event.type = MapNotify;
    event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
    event.xmap.send_event = False;
    event.xmap.display = winPtr->display;
    event.xmap.event = winPtr->window;
    event.xmap.window = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    Tk_HandleEvent(&event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
 *--------------------------------------------------------------
 */

void
Tk_MakeWindowExist(
    Tk_Window tkwin)		/* Token for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr2;
    Window parent;
    Tcl_HashEntry *hPtr;
    Tk_ClassCreateProc *createProc;
    int isNew;

    if (winPtr->window != None) {







|







1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
 *--------------------------------------------------------------
 */

void
Tk_MakeWindowExist(
    Tk_Window tkwin)		/* Token for window. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr2;
    Window parent;
    Tcl_HashEntry *hPtr;
    Tk_ClassCreateProc *createProc;
    int isNew;

    if (winPtr->window != None) {
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
	    Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr);
	}
	parent = winPtr->parentPtr->window;
    }

    createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc);
    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, &isNew);
    Tcl_SetHashValue(hPtr, winPtr);







|







1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
	    Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr);
	}
	parent = winPtr->parentPtr->window;
    }

    createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc);
    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, &isNew);
    Tcl_SetHashValue(hPtr, winPtr);
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
	 */

	for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL;
		winPtr2 = winPtr2->nextPtr) {
	    if ((winPtr2->window != None)
		    && !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) {
		XWindowChanges changes;

		changes.sibling = winPtr2->window;
		changes.stack_mode = Below;
		XConfigureWindow(winPtr->display, winPtr->window,
			CWSibling|CWStackMode, &changes);
		break;
	    }
	}







<







1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755
1756
	 */

	for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL;
		winPtr2 = winPtr2->nextPtr) {
	    if ((winPtr2->window != None)
		    && !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) {
		XWindowChanges changes;

		changes.sibling = winPtr2->window;
		changes.stack_mode = Below;
		XConfigureWindow(winPtr->display, winPtr->window,
			CWSibling|CWStackMode, &changes);
		break;
	    }
	}
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
 *--------------------------------------------------------------
 */

void
Tk_UnmapWindow(
    Tk_Window tkwin)		/* Token for window to unmap. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (!(winPtr->flags & TK_MAPPED) || (winPtr->flags & TK_ALREADY_DEAD)) {
	return;
    }
    if (winPtr->flags & TK_WIN_MANAGED) {
	/*
	 * Special processing has to be done for top-level windows. Let tkWm.c







|







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
 *--------------------------------------------------------------
 */

void
Tk_UnmapWindow(
    Tk_Window tkwin)		/* Token for window to unmap. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    if (!(winPtr->flags & TK_MAPPED) || (winPtr->flags & TK_ALREADY_DEAD)) {
	return;
    }
    if (winPtr->flags & TK_WIN_MANAGED) {
	/*
	 * Special processing has to be done for top-level windows. Let tkWm.c
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
	event.type = UnmapNotify;
	event.xunmap.serial = LastKnownRequestProcessed(winPtr->display);
	event.xunmap.send_event = False;
	event.xunmap.display = winPtr->display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
    }
}

void
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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (valueMask & CWX) {
	winPtr->changes.x = valuePtr->x;
    }
    if (valueMask & CWY) {
	winPtr->changes.y = valuePtr->y;
    }
    if (valueMask & CWWidth) {
	winPtr->changes.width = valuePtr->width;
    }
    if (valueMask & CWHeight) {
	winPtr->changes.height = valuePtr->height;
    }
    if (valueMask & CWBorderWidth) {
	winPtr->changes.border_width = valuePtr->border_width;
    }
    if (valueMask & (CWSibling|CWStackMode)) {
	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);
    } else {
	winPtr->dirtyChanges |= valueMask;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_MoveWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    if (winPtr->window != None) {
	XMoveWindow(winPtr->display, winPtr->window, x, y);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_ResizeWindow(
    Tk_Window tkwin,		/* Window to resize. */
    int width, int height)	/* New dimensions for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
		(unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
		(unsigned) width, (unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_SetWindowBorderWidth(
    Tk_Window tkwin,		/* Window to modify. */
    int width)			/* New border width for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.border_width = width;
    if (winPtr->window != None) {
	XSetWindowBorderWidth(winPtr->display, winPtr->window,
		(unsigned) width);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWBorderWidth;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
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. */
    XSetWindowAttributes *attsPtr)
				/* New values for some attributes. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (valueMask & CWBackPixmap) {
	winPtr->atts.background_pixmap = attsPtr->background_pixmap;
    }
    if (valueMask & CWBackPixel) {
	winPtr->atts.background_pixel = attsPtr->background_pixel;
    }







|










|

















|

















|

















|



















|




















|

















|


|







1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
	event.type = UnmapNotify;
	event.xunmap.serial = LastKnownRequestProcessed(winPtr->display);
	event.xunmap.send_event = False;
	event.xunmap.display = winPtr->display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
    }
}

void
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;

    if (valueMask & CWX) {
	winPtr->changes.x = valuePtr->x;
    }
    if (valueMask & CWY) {
	winPtr->changes.y = valuePtr->y;
    }
    if (valueMask & CWWidth) {
	winPtr->changes.width = valuePtr->width;
    }
    if (valueMask & CWHeight) {
	winPtr->changes.height = valuePtr->height;
    }
    if (valueMask & CWBorderWidth) {
	winPtr->changes.border_width = valuePtr->border_width;
    }
    if (valueMask & (CWSibling|CWStackMode)) {
	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);
    } else {
	winPtr->dirtyChanges |= valueMask;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_MoveWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    if (winPtr->window != None) {
	XMoveWindow(winPtr->display, winPtr->window, x, y);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_ResizeWindow(
    Tk_Window tkwin,		/* Window to resize. */
    int width, int height)	/* New dimensions for window. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
		(unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
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;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
		(unsigned) width, (unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_SetWindowBorderWidth(
    Tk_Window tkwin,		/* Window to modify. */
    int width)			/* New border width for window. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.border_width = width;
    if (winPtr->window != None) {
	XSetWindowBorderWidth(winPtr->display, winPtr->window,
		(unsigned) width);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWBorderWidth;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
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;

    if (valueMask & CWBackPixmap) {
	winPtr->atts.background_pixmap = attsPtr->background_pixmap;
    }
    if (valueMask & CWBackPixel) {
	winPtr->atts.background_pixel = attsPtr->background_pixel;
    }
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068



2069

2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097

void
Tk_SetWindowBackground(
    Tk_Window tkwin,		/* Window to manipulate. */
    unsigned long pixel)	/* Pixel value to use for window's
				 * background. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.background_pixel = pixel;

    if (winPtr->window != None) {
	XSetWindowBackground(winPtr->display, winPtr->window, pixel);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixmap)
		| CWBackPixel;
    }
}

void
Tk_SetWindowBackgroundPixmap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Pixmap pixmap)		/* Pixmap to use for window's background. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.background_pixmap = pixmap;

    if (winPtr->window != None) {
	XSetWindowBackgroundPixmap(winPtr->display,
		winPtr->window, pixmap);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixel)
		| CWBackPixmap;
    }
}

void
Tk_SetWindowBorder(
    Tk_Window tkwin,		/* Window to manipulate. */
    unsigned long pixel)	/* Pixel value to use for window's border. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.border_pixel = pixel;

    if (winPtr->window != None) {
	XSetWindowBorder(winPtr->display, winPtr->window, pixel);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixmap)
		| CWBorderPixel;
    }
}

void
Tk_SetWindowBorderPixmap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Pixmap pixmap)		/* Pixmap to use for window's border. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.border_pixmap = pixmap;

    if (winPtr->window != None) {
	XSetWindowBorderPixmap(winPtr->display,
		winPtr->window, pixmap);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixel)
		| CWBorderPixmap;
    }
}

void
Tk_DefineCursor(
    Tk_Window tkwin,		/* Window to manipulate. */
    Tk_Cursor cursor)		/* Cursor to use for window (may be None). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;




    winPtr->atts.cursor = (Cursor) cursor;


    if (winPtr->window != None) {
	XDefineCursor(winPtr->display, winPtr->window, winPtr->atts.cursor);
    } else {
	winPtr->dirtyAtts = winPtr->dirtyAtts | CWCursor;
    }
}

void
Tk_UndefineCursor(
    Tk_Window tkwin)		/* Window to manipulate. */
{
    Tk_DefineCursor(tkwin, NULL);
}

void
Tk_SetWindowColormap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Colormap colormap)		/* Colormap to use for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.colormap = colormap;

    if (winPtr->window != None) {
	XSetWindowColormap(winPtr->display, winPtr->window, colormap);
	if (!(winPtr->flags & TK_WIN_MANAGED)) {
	    TkWmAddToColormapWindows(winPtr);







|
















|

















|
















|

















|

>
>
>

>




















|







2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128

void
Tk_SetWindowBackground(
    Tk_Window tkwin,		/* Window to manipulate. */
    unsigned long pixel)	/* Pixel value to use for window's
				 * background. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.background_pixel = pixel;

    if (winPtr->window != None) {
	XSetWindowBackground(winPtr->display, winPtr->window, pixel);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixmap)
		| CWBackPixel;
    }
}

void
Tk_SetWindowBackgroundPixmap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Pixmap pixmap)		/* Pixmap to use for window's background. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.background_pixmap = pixmap;

    if (winPtr->window != None) {
	XSetWindowBackgroundPixmap(winPtr->display,
		winPtr->window, pixmap);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBackPixel)
		| CWBackPixmap;
    }
}

void
Tk_SetWindowBorder(
    Tk_Window tkwin,		/* Window to manipulate. */
    unsigned long pixel)	/* Pixel value to use for window's border. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.border_pixel = pixel;

    if (winPtr->window != None) {
	XSetWindowBorder(winPtr->display, winPtr->window, pixel);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixmap)
		| CWBorderPixel;
    }
}

void
Tk_SetWindowBorderPixmap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Pixmap pixmap)		/* Pixmap to use for window's border. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.border_pixmap = pixmap;

    if (winPtr->window != None) {
	XSetWindowBorderPixmap(winPtr->display,
		winPtr->window, pixmap);
    } else {
	winPtr->dirtyAtts = (winPtr->dirtyAtts & (unsigned) ~CWBorderPixel)
		| CWBorderPixmap;
    }
}

void
Tk_DefineCursor(
    Tk_Window tkwin,		/* Window to manipulate. */
    Tk_Cursor cursor)		/* Cursor to use for window (may be None). */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

#if defined(MAC_OSX_TK)
    winPtr->atts.cursor = (XCursor) cursor;
#else
    winPtr->atts.cursor = (Cursor) cursor;
#endif

    if (winPtr->window != None) {
	XDefineCursor(winPtr->display, winPtr->window, winPtr->atts.cursor);
    } else {
	winPtr->dirtyAtts = winPtr->dirtyAtts | CWCursor;
    }
}

void
Tk_UndefineCursor(
    Tk_Window tkwin)		/* Window to manipulate. */
{
    Tk_DefineCursor(tkwin, NULL);
}

void
Tk_SetWindowColormap(
    Tk_Window tkwin,		/* Window to manipulate. */
    Colormap colormap)		/* Colormap to use for window. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->atts.colormap = colormap;

    if (winPtr->window != None) {
	XSetWindowColormap(winPtr->display, winPtr->window, colormap);
	if (!(winPtr->flags & TK_WIN_MANAGED)) {
	    TkWmAddToColormapWindows(winPtr);
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
int
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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->window != None) {
	/* Too late! */
	return 0;
    }

    winPtr->visual = visual;







|







2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
int
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) {
	/* Too late! */
	return 0;
    }

    winPtr->visual = visual;
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
 *	An event is generated and processed by Tk_HandleEvent.
 *
 *----------------------------------------------------------------------
 */

void
TkDoConfigureNotify(
    TkWindow *winPtr)	/* Window whose configuration was just
				 * changed. */
{
    XEvent event;

    event.type = ConfigureNotify;
    event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display);
    event.xconfigure.send_event = False;







|







2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
 *	An event is generated and processed by Tk_HandleEvent.
 *
 *----------------------------------------------------------------------
 */

void
TkDoConfigureNotify(
    register TkWindow *winPtr)	/* Window whose configuration was just
				 * changed. */
{
    XEvent event;

    event.type = ConfigureNotify;
    event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display);
    event.xconfigure.send_event = False;
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetClass(
    Tk_Window tkwin,		/* Token for window to assign class. */
    const char *className)	/* New class for tkwin. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->classUid = Tk_GetUid(className);
    if (winPtr->flags & TK_WIN_MANAGED) {
	TkWmSetClass(winPtr);
    }
    TkOptionClassChanged(winPtr);
}







|

|







2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetClass(
    Tk_Window tkwin,		/* Token for window to assign class. */
    CONST char *className)	/* New class for tkwin. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->classUid = Tk_GetUid(className);
    if (winPtr->flags & TK_WIN_MANAGED) {
	TkWmSetClass(winPtr);
    }
    TkOptionClassChanged(winPtr);
}
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetClassProcs(
    Tk_Window tkwin,		/* Token for window to modify. */
    const Tk_ClassProcs *procs,	/* Class procs structure. */
    ClientData instanceData)	/* Data to be passed to class functions. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->classProcsPtr = procs;
    winPtr->instanceData = instanceData;
}

/*
 *----------------------------------------------------------------------







|


|







2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
 *
 *----------------------------------------------------------------------
 */

void
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;

    winPtr->classProcsPtr = procs;
    winPtr->instanceData = instanceData;
}

/*
 *----------------------------------------------------------------------
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
 *
 *----------------------------------------------------------------------
 */

Tk_Window
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.
	 */

	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window",-1));
	    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
	}
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
	    pathName);
    if (hPtr == NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad window path name \"%s\"", pathName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", pathName,
		    NULL);
	}
	return NULL;
    }
    return (Tk_Window)Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_IdToWindow --
 *







|












|
<








<
|
<
|



|







2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327

2328
2329
2330
2331
2332
2333
2334
2335

2336

2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
 *
 *----------------------------------------------------------------------
 */

Tk_Window
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.
	 */

	if (interp != NULL) {
	    Tcl_AppendResult(interp, "NULL main window", NULL);

	}
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
	    pathName);
    if (hPtr == NULL) {
	if (interp != NULL) {

	    Tcl_AppendResult(interp, "bad window path name \"",

		    pathName, "\"", NULL);
	}
	return NULL;
    }
    return (Tk_Window) Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_IdToWindow --
 *
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
	if (dispPtr == NULL) {
	    return NULL;
	}
	if (dispPtr->display == display) {
	    break;
	}
    }
    if (window == None) {
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&dispPtr->winTable, window);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Tk_Window)Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DisplayName --
 *
 *	Return the textual name of a window's display.
 *
 * Results:
 *	The return value is the string name of the display associated with
 *	tkwin.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
Tk_DisplayName(
    Tk_Window tkwin)		/* Window whose display name is desired. */
{
    return ((TkWindow *) tkwin)->dispPtr->name;
}

/*







<
<
|
<
|



|



















|







2372
2373
2374
2375
2376
2377
2378


2379

2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
	if (dispPtr == NULL) {
	    return NULL;
	}
	if (dispPtr->display == display) {
	    break;
	}
    }




    hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Tk_Window) Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DisplayName --
 *
 *	Return the textual name of a window's display.
 *
 * Results:
 *	The return value is the string name of the display associated with
 *	tkwin.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CONST char *
Tk_DisplayName(
    Tk_Window tkwin)		/* Window whose display name is desired. */
{
    return ((TkWindow *) tkwin)->dispPtr->name;
}

/*
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tk_Interp(
    Tk_Window tkwin)
{
    if (tkwin != NULL && ((TkWindow *) tkwin)->mainPtr != NULL) {
	return ((TkWindow *) tkwin)->mainPtr->interp;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|
|







2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tk_Interp(
    Tk_Window tkwin)
{
    if (tkwin != NULL && ((TkWindow *)tkwin)->mainPtr != NULL) {
	return ((TkWindow *)tkwin)->mainPtr->interp;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
2558
2559
2560
2561
2562
2563
2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
     * 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) {
	XWindowChanges changes;
	unsigned int mask = CWStackMode;


	changes.stack_mode = Above;
	for (otherPtr = winPtr->nextPtr; otherPtr != NULL;
		otherPtr = otherPtr->nextPtr) {
	    if ((otherPtr->window != None)
		    && !(otherPtr->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))){
		changes.sibling = otherPtr->window;
		changes.stack_mode = Below;







|

>







2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
     * 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) {
	XWindowChanges changes;
	unsigned int mask;

	mask = CWStackMode;
	changes.stack_mode = Above;
	for (otherPtr = winPtr->nextPtr; otherPtr != NULL;
		otherPtr = otherPtr->nextPtr) {
	    if ((otherPtr->window != None)
		    && !(otherPtr->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))){
		changes.sibling = otherPtr->window;
		changes.stack_mode = Below;
2610
2611
2612
2613
2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
	return NULL;
    }
#ifdef USE_TCL_STUBS
    if (tclStubsPtr == NULL) {
	return NULL;
    }
#endif
    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL;
	    mainPtr = mainPtr->nextPtr) {
	if (mainPtr->interp == interp) {
	    return (Tk_Window) mainPtr->winPtr;
	}
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "this isn't a Tk application", -1));
    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_StrictMotif --







|
>







<
|
<







2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651

2652

2653
2654
2655
2656
2657
2658
2659
	return NULL;
    }
#ifdef USE_TCL_STUBS
    if (tclStubsPtr == NULL) {
	return NULL;
    }
#endif
    tsdPtr = (ThreadSpecificData *)
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL;
	    mainPtr = mainPtr->nextPtr) {
	if (mainPtr->interp == interp) {
	    return (Tk_Window) mainPtr->winPtr;
	}
    }

    Tcl_SetResult(interp, "this isn't a Tk application", TCL_STATIC);

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_StrictMotif --
2680
2681
2682
2683
2684
2685
2686
2687

2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720

#ifdef USE_TCL_STUBS
    if (tclStubsPtr == NULL) {
	return 0;
    }
#endif

    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    return tsdPtr->numMainWindows;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_AlwaysShowSelection --
 *
 *	Indicates whether text/entry widgets should always display
 *	their selection, regardless of window focus.
 *
 * Results:
 *	The return value is 1 if always showing the selection has been
 *	requested for tkwin's application by setting the
 *	::tk::AlwaysShowSelection variable in its interpreter to a true value.
 *	0 is returned if it has a false value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tk_AlwaysShowSelection(
    Tk_Window tkwin)		/* Window whose application is to be
				 * checked. */
{
    return ((TkWindow *) tkwin)->mainPtr->alwaysShowSelection;
}

/*







|
>







|

















|







2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746

#ifdef USE_TCL_STUBS
    if (tclStubsPtr == NULL) {
	return 0;
    }
#endif

    tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    return tsdPtr->numMainWindows;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpAlwaysShowSelection --
 *
 *	Indicates whether text/entry widgets should always display
 *	their selection, regardless of window focus.
 *
 * Results:
 *	The return value is 1 if always showing the selection has been
 *	requested for tkwin's application by setting the
 *	::tk::AlwaysShowSelection variable in its interpreter to a true value.
 *	0 is returned if it has a false value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpAlwaysShowSelection(
    Tk_Window tkwin)		/* Window whose application is to be
				 * checked. */
{
    return ((TkWindow *) tkwin)->mainPtr->alwaysShowSelection;
}

/*
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795

static void
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
     * deleted memory, causing core dumps.
     */

    while (tsdPtr->halfdeadWindowList != NULL) {
	interp = tsdPtr->halfdeadWindowList->winPtr->mainPtr->interp;
	Tcl_Preserve(interp);
	tsdPtr->halfdeadWindowList->flags |= HD_CLEANUP;
	tsdPtr->halfdeadWindowList->winPtr->flags &= ~TK_ALREADY_DEAD;
	Tk_DestroyWindow((Tk_Window) tsdPtr->halfdeadWindowList->winPtr);
	Tcl_Release(interp);
    }

    /*
     * Destroy any remaining main windows.
     */

    while (tsdPtr->mainWindowList != NULL) {
	interp = tsdPtr->mainWindowList->interp;
	Tcl_Preserve(interp);
	Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr);
	Tcl_Release(interp);
    }

    /*
     * Let error handlers catch up before actual close of displays.
     * Must be done before tsdPtr->displayList is cleared, otherwise
     * ErrorProc() in tkError.c cannot associate the pending X errors
     * to the remaining error handlers.
     */

    for (dispPtr = tsdPtr->displayList; dispPtr != NULL;
           dispPtr = dispPtr->nextPtr) {
       XSync(dispPtr->display, False);
    }

    /*
     * 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.







|















|



|








|

|
<
<
<
<
<
<
<
<
<
<
<
<







2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802












2803
2804
2805
2806
2807
2808
2809

static void
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
     * 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);
    }

    /*
     * Destroy any remaining main windows.
     */

    while (tsdPtr->mainWindowList != NULL) {
	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.
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
    }

    tsdPtr->numMainWindows = 0;
    tsdPtr->mainWindowList = NULL;
    tsdPtr->initialized = 0;
}

#if defined(_WIN32)

static HMODULE tkcygwindll = NULL;

/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.?.exe, the cygwin port of Tcl.
 * This means that the system encoding is utf-8, so we don't have to do any
 * encoding conversions.
 */

int
TkCygwinMainEx(
    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)
{
    WCHAR name[MAX_PATH];
    size_t len;
    void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
    name[len-2] = '.';
    name[len-1] = name[len-5];
    wcscpy(name+len, L".dll");
    memcpy(name+len-8, L"libtk8", 6 * sizeof(WCHAR));

    tkcygwindll = LoadLibraryW(name);
    if (!tkcygwindll) {
	/* dll is not present */
	return 0;
    }
    tkmainex = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *))
	    (void *)GetProcAddress(tkcygwindll, "Tk_MainEx");
    if (!tkmainex) {
	return 0;
    }
    tkmainex(argc, argv, appInitProc, interp);
    return 1;
}
#endif /* _WIN32 */

/*
 *----------------------------------------------------------------------
 *
 * Tk_Init --
 *
 *	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







|






|
|
|

<


|
|
|
<
|
>
|


|
|
|


|
|
|
|
|

|
|
|
|
|
|
<
|
|
|
|


|
<







2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844

2845
2846
2847
2848
2849

2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871

2872
2873
2874
2875
2876
2877
2878

2879
2880
2881
2882
2883
2884
2885
    }

    tsdPtr->numMainWindows = 0;
    tsdPtr->mainWindowList = NULL;
    tsdPtr->initialized = 0;
}

#if defined(__WIN32__)

static HMODULE tkcygwindll = NULL;

/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.4.exe, the cygwin
 * port of Tcl. This means that the system encoding is utf-8,
 * so we don't have to do any encoding conversions.
 */

int
TkCygwinMainEx(
    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)
{
    char name[MAX_PATH];
    int len;
    void (*sym)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
	len = GetModuleFileName(Tk_GetHINSTANCE(), name, MAX_PATH);
	name[len-2] = '.';
	name[len-1] = name[len-5];
	strcpy(name+len, ".dll");
	memcpy(name+len-8, "libtk8", 6);

	tkcygwindll = LoadLibrary(name);
	if (!tkcygwindll) {
	    /* dll is not present */
	    return 0;
	}
	sym = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *))(void *)GetProcAddress(tkcygwindll, "Tk_MainEx");

	if (!sym) {
		return 0;
	}
	sym(argc, argv, appInitProc, interp);
    return 1;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * Tk_Init --
 *
 *	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
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
 *----------------------------------------------------------------------
 */

int
Tk_Init(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
#if defined(_WIN32)
    if (tkcygwindll) {
	int (*tkinit)(Tcl_Interp *);

	tkinit = (int(*)(Tcl_Interp *))(void *)GetProcAddress(tkcygwindll,"Tk_Init");
	if (tkinit) {
	    return tkinit(interp);
	}
    }
#endif /* _WIN32 */
    return Initialize(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SafeInit --







|

|

|
|
|


|







2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
 *----------------------------------------------------------------------
 */

int
Tk_Init(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
#if defined(__WIN32__)
    if (tkcygwindll) {
	int (*sym)(Tcl_Interp *);

	sym = (int (*)(Tcl_Interp *))(void *)GetProcAddress(tkcygwindll, "Tk_Init");
	if (sym) {
	    return sym(interp);
	}
    }
#endif
    return Initialize(interp);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SafeInit --
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071

3072
3073

















3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084


3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100





3101
3102
3103
3104
3105
3106
3107
3108
3109
3110

3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131




3132




3133

3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162

3163
3164
3165

3166


3167



3168
3169

3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195



3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224

3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239

3240
3241
3242
3243
3244

3245
3246
3247
3248
3249

3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282

3283
3284
3285
3286
3287
3288
3289
     * - 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 parent interpreter.
     *
     * 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)
    if (tkcygwindll) {
	int (*tksafeinit)(Tcl_Interp *);

	tksafeinit = (int (*)(Tcl_Interp *))
		(void *)GetProcAddress(tkcygwindll, "Tk_SafeInit");
	if (tksafeinit) {
	    return tksafeinit(interp);
	}
    }
#endif /* _WIN32 */
    return Initialize(interp);
}

MODULE_SCOPE const TkStubs tkStubs;

/*
 *----------------------------------------------------------------------
 *
 * Initialize --
 *
 *	The core of the initialization code for Tk, called from Tk_Init and
 *	Tk_SafeInit.
 *
 * Results:
 *	A standard Tcl result. Also leaves an error message in the interp's
 *	result if there was an error.
 *
 * Side effects:
 *	Depends on the initialization scripts that are invoked.
 *
 *----------------------------------------------------------------------
 */

static int
CopyValue(
    ClientData dummy,
    Tcl_Obj *objPtr,
    void *dstPtr)
{
    (void)dummy;

    *(Tcl_Obj **)dstPtr = objPtr;
    return 1;
}

static int
Initialize(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
    int code = TCL_OK;
    ThreadSpecificData *tsdPtr;
    Tcl_Obj *value = NULL;
    Tcl_Obj *cmd;

    Tcl_Obj *nameObj = NULL;
    Tcl_Obj *classObj = NULL;
    Tcl_Obj *displayObj = NULL;
    Tcl_Obj *colorMapObj = NULL;
    Tcl_Obj *useObj = NULL;
    Tcl_Obj *visualObj = NULL;
    Tcl_Obj *geometryObj = NULL;

    int sync = 0;

    const Tcl_ArgvInfo table[] = {
	{TCL_ARGV_CONSTANT, "-sync", INT2PTR(1), &sync,
		"Use synchronous mode for display server", NULL},
	{TCL_ARGV_FUNC, "-colormap", (void *)CopyValue, &colorMapObj,
		"Colormap for main window", NULL},
	{TCL_ARGV_FUNC, "-display", (void *)CopyValue, &displayObj,
		"Display to use", NULL},
	{TCL_ARGV_FUNC, "-geometry", (void *)CopyValue, &geometryObj,
		"Initial geometry for window", NULL},
	{TCL_ARGV_FUNC, "-name", (void *)CopyValue, &nameObj,
		"Name to use for application", NULL},
	{TCL_ARGV_FUNC, "-visual", (void *)CopyValue, &visualObj,
		"Visual for main window", NULL},
	{TCL_ARGV_FUNC, "-use", (void *)CopyValue, &useObj,
		"Id of window in which to embed application", NULL},
	TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
    };

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * TIP #59: Make embedded configuration information available.
     */

    TkInitEmbeddedConfigurationInformation(interp);

    /*
     * Ensure that our obj-types are registered with the Tcl runtime.
     */

    TkRegisterObjTypes();

    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    /*

















     * 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
	 * parent.
	 */



	/*
	 * Step 1 : find the parent 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 *parent = interp;

	while (Tcl_IsSafe(parent)) {
	    parent = Tcl_GetParent(parent);
	    if (parent == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no controlling parent interpreter", -1));
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_PARENT", NULL);
		return TCL_ERROR;





	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */

	code = Tcl_GetInterpPath(parent, interp);
	if (code != TCL_OK) {
	    Tcl_Panic("Tcl_GetInterpPath broken!");

	}

	/*
	 * Build the command to eval in trusted parent.
	 */

	cmd = Tcl_NewListObj(2, NULL);
	Tcl_ListObjAppendElement(NULL, cmd,
		Tcl_NewStringObj("::safe::TkInit", -1));
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(parent));

	/*
	 * Step 2 : Eval in the parent. The argument is the *reversed* interp
	 * path of the child.
	 */

	Tcl_IncrRefCount(cmd);
	code = Tcl_EvalObjEx(parent, cmd, 0);
	Tcl_DecrRefCount(cmd);
	Tcl_TransferResult(parent, code, interp);
	if (code != TCL_OK) {




	    return code;




	}


	/*
	 * Use the parent's result as argv. Note: We don't use the Obj
	 * interfaces to avoid dealing with cross interp refcounting and
	 * changing the code below.
	 */

	value = Tcl_GetObjResult(interp);
    } 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.
	 */

	value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
    }

    if (value) {
	int objc;
	Tcl_Obj **objv, **rest;
	Tcl_Obj *parseList = Tcl_NewListObj(1, NULL);

	Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj());

	Tcl_IncrRefCount(value);
	if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) ||
	    TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) ||
	    TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) {

	    Tcl_AddErrorInfo(interp,
		    "\n    (processing arguments in argv variable)");
	    code = TCL_ERROR;

	}


	if (code == TCL_OK) {



	    Tcl_SetVar2Ex(interp, "argv", NULL,
		    Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY);

	    Tcl_SetVar2Ex(interp, "argc", NULL,
		    Tcl_NewWideIntObj(objc-1), TCL_GLOBAL_ONLY);
	    ckfree(rest);
	}
	Tcl_DecrRefCount(parseList);
	if (code != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Figure out the application's name and class.
     */

    /*
     * If we got no -name argument, fetch from TkpGetAppName().
     */

    if (nameObj == NULL) {
	Tcl_DString nameDS;

	Tcl_DStringInit(&nameDS);
	TkpGetAppName(interp, &nameDS);
	nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS),
		Tcl_DStringLength(&nameDS));
	Tcl_DStringFree(&nameDS);



    }

    /*
     * The -class argument is always the ToTitle of the -name
     */

    {
	TkSizeT numBytes;
	const char *bytes = TkGetStringFromObj(nameObj, &numBytes);

	classObj = Tcl_NewStringObj(bytes, numBytes);

	numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
	Tcl_SetObjLength(classObj, numBytes);
    }

    /*
     * Create an argument list for creating the top-level window, using the
     * information parsed from argv, if any.
     */

    cmd = Tcl_NewStringObj("toplevel . -class", -1);

    Tcl_ListObjAppendElement(NULL, cmd, classObj);
    classObj = NULL;

    if (displayObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", -1));
	Tcl_ListObjAppendElement(NULL, cmd, displayObj);


	/*
	 * 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) {
	    Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY);
	}
	displayObj = NULL;
    }
    if (colorMapObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", -1));
	Tcl_ListObjAppendElement(NULL, cmd, colorMapObj);

	colorMapObj = NULL;
    }
    if (useObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", -1));
	Tcl_ListObjAppendElement(NULL, cmd, useObj);

	useObj = NULL;
    }
    if (visualObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", -1));
	Tcl_ListObjAppendElement(NULL, cmd, visualObj);

	visualObj = NULL;
    }

    code = TkListCreateFrame(NULL, interp, cmd, 1, nameObj);

    Tcl_DecrRefCount(cmd);

    if (code != TCL_OK) {
	goto done;
    }
    Tcl_ResetResult(interp);
    if (sync) {
	(void)XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
    }

    /*
     * Set the geometry of the main window, if requested. Put the requested
     * geometry into the "geometry" variable.
     */

    if (geometryObj) {

	Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY);

	cmd = Tcl_NewStringObj("wm geometry .", -1);
	Tcl_ListObjAppendElement(NULL, cmd, geometryObj);
	Tcl_IncrRefCount(cmd);
	code = Tcl_EvalObjEx(interp, cmd, 0);
	Tcl_DecrRefCount(cmd);
	geometryObj = NULL;
	if (code != TCL_OK) {
	    goto done;
	}

    }

    /*
     * Provide Tk and its stub table.
     */

    code = Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,







|





|

|

<
|
|
|


|



|






<
|











<
<
<
<
<
<
<
<
<
<
<
<




<
<
<
|
|
|
|
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|



<
<
<
<
<
<






|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







|


>
>

|





|

|
|
|
|
<
<
|
>
>
>
>
>







|

|
>



|


|
<
|
|


|
|


<
|
<
<

>
>
>
>
|
>
>
>
>

>


|




|







|

|
<
<
<
<
|
<

<
|
<
<
>



>

>
>
|
>
>
>
|
<
>
|
<
|
<
<
<
<
<






<
<
<
|
|
|

<
|
<
|
|
>
>
>
|
|
<
<
<
|
|
<
<
|
<
|
|
<







|
|
|
|
|
|
|
|
>








|

<

|
|
|
>
|

|
|
|
>
|

|
|
|
>
|

|
|

<
|




|
|







|
|
<
|
<
<
<
<
<
<



>







2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982

2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998

2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010












3011
3012
3013
3014



3015
3016
3017
3018


3019


3020

3021

















3022
3023
3024
3025
3026
3027
3028
3029
3030






3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083


3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107

3108
3109
3110
3111
3112
3113
3114
3115

3116


3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146




3147

3148

3149


3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162

3163
3164

3165





3166
3167
3168
3169
3170
3171



3172
3173
3174
3175

3176

3177
3178
3179
3180
3181
3182
3183



3184
3185


3186

3187
3188

3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214

3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236

3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252

3253






3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
     * - 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.
     */

#if defined(__WIN32__)
    if (tkcygwindll) {
	int (*sym)(Tcl_Interp *);


	sym = (int (*)(Tcl_Interp *))(void *)GetProcAddress(tkcygwindll, "Tk_SafeInit");
	if (sym) {
	    return sym(interp);
	}
    }
#endif
    return Initialize(interp);
}

extern TkStubs tkStubs;

/*
 *----------------------------------------------------------------------
 *
 * Initialize --
 *

 *	???TODO???
 *
 * Results:
 *	A standard Tcl result. Also leaves an error message in the interp's
 *	result if there was an error.
 *
 * Side effects:
 *	Depends on the initialization scripts that are invoked.
 *
 *----------------------------------------------------------------------
 */













static int
Initialize(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{



    char *p;
    int argc, code;
    CONST char **argv;
    char *args[20];


    CONST char *argString = NULL;


    Tcl_DString class;

    ThreadSpecificData *tsdPtr;


















    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    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));

    /*
     * Start by initializing all the static variables to default acceptable
     * values so that no information is leaked from a previous run of this
     * code.
     */

    Tcl_MutexLock(&windowMutex);
    synchronize = 0;
    name = NULL;
    display = NULL;
    geometry = NULL;
    colormap = NULL;
    use = NULL;
    visual = NULL;
    rest = 0;
    argv = NULL;

    /*
     * 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.
	 */

	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.
	 */

	Tcl_Interp *master = interp;

	while (1) {
	    master = Tcl_GetMaster(master);
	    if (master == NULL) {
		Tcl_AppendResult(interp, "NULL master", NULL);


		code = TCL_ERROR;
		goto done;
	    }
	    if (!Tcl_IsSafe(master)) {
		/* Found the trusted master. */
		break;
	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */

	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.
	 */


	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).
	     */

	    Tcl_DStringFree(&ds);
	    Tcl_AppendResult(interp,
		    "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.
	 */

	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.
	 */

	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:
	    Tcl_AddErrorInfo(interp,
		    "\n    (processing arguments in argv variable)");
	    code = TCL_ERROR;
	    goto done;
	}
	if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv,
		argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS)
		!= TCL_OK) {
	    goto argError;
	}
	p = Tcl_Merge(argc, argv);
	Tcl_SetVar2(interp, "argv", NULL, p, TCL_GLOBAL_ONLY);

	sprintf(buffer, "%d", argc);
	Tcl_SetVar2(interp, "argc", NULL, buffer, TCL_GLOBAL_ONLY);

	ckfree(p);





    }

    /*
     * Figure out the application's name and class.
     */




    Tcl_DStringInit(&class);
    if (name == NULL) {
	int offset;


	TkpGetAppName(interp, &class);

	offset = Tcl_DStringLength(&class)+1;
	Tcl_DStringSetLength(&class, 2*offset);
	Tcl_DStringSetLength(&class, offset-1);
	Tcl_DStringAppend(&class, Tcl_DStringValue(&class), offset-1);
	name = Tcl_DStringValue(&class) + offset;
    } else {
	Tcl_DStringAppend(&class, name, -1);



    }



    p = Tcl_DStringValue(&class);

    if (*p) {
	Tcl_UtfToTitle(p);

    }

    /*
     * Create an argument list for creating the top-level window, using the
     * information parsed from argv, if any.
     */

    args[0] = "toplevel";
    args[1] = ".";
    args[2] = "-class";
    args[3] = Tcl_DStringValue(&class);
    argc = 4;
    if (display != NULL) {
	args[argc] = "-screen";
	args[argc+1] = display;
	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 (tsdPtr->numMainWindows == 0) {
	    Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);
	}

    }
    if (colormap != NULL) {
	args[argc] = "-colormap";
	args[argc+1] = colormap;
	argc += 2;
	colormap = NULL;
    }
    if (use != NULL) {
	args[argc] = "-use";
	args[argc+1] = use;
	argc += 2;
	use = NULL;
    }
    if (visual != NULL) {
	args[argc] = "-visual";
	args[argc+1] = visual;
	argc += 2;
	visual = NULL;
    }
    args[argc] = NULL;
    code = TkCreateFrame((ClientData) NULL, interp, argc, args, 1, name);


    Tcl_DStringFree(&class);
    if (code != TCL_OK) {
	goto done;
    }
    Tcl_ResetResult(interp);
    if (synchronize) {
	XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
    }

    /*
     * 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, NULL);






	if (code != TCL_OK) {
	    goto done;
	}
	geometry = NULL;
    }

    /*
     * Provide Tk and its stub table.
     */

    code = Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
3297
3298
3299
3300
3301
3302
3303






3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318




3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350


3351
3352
3353
3354

3355
3356
3357
3358
3359
3360
3361
     * 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);







    /*
     * 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.
     */





    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_EvalEx(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", -1, TCL_EVAL_GLOBAL);
    }
    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, tsdPtr);
    }


  done:
    if (value) {
	Tcl_DecrRefCount(value);
	value = NULL;

    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>
>















>
>
>
>













|







|








|

>
>

<
|
|
>







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338

3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
     * 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);

#if !defined(_WIN32) && !defined(STATIC_BUILD)
    /* On Windows, this has no added value. */
#   undef Tk_InitStubs
    Tk_InitStubs(interp, TK_VERSION, 1);
#endif

    /*
     * 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);
    }
    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:

    Tcl_MutexUnlock(&windowMutex);
    if (argv != NULL) {
	ckfree((char *) argv);
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
Tk_PkgInitStubsCheck(
    Tcl_Interp *interp,
    const char * version,
    int exact)
{
    const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0, NULL);

    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_PkgPresentEx(interp, "Tk", version, 1, NULL);
		return NULL;
	    }
	} else {
	    return Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
	}
    }
    return actualVersion;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


|


|


|








|



|




<







3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391

3392
3393
3394
3395
3396
3397
3398
 *
 * 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:
 */

Changes to generic/ttk/ttk.decls.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc)
}

declare 5 {
    int Ttk_RegisterElementSpec(
	Ttk_Theme theme,
	const char *elementName,
	const Ttk_ElementSpec *elementSpec,
	void *clientData)
}

declare 6 {
    Ttk_ElementClass *Ttk_RegisterElement(
	Tcl_Interp *interp,
	Ttk_Theme theme,
	const char *elementName,
	const Ttk_ElementSpec *elementSpec,
	void *clientData)
}

declare 7 {
    int Ttk_RegisterElementFactory(
	Tcl_Interp *interp,
	const char *name,







|








|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc)
}

declare 5 {
    int Ttk_RegisterElementSpec(
	Ttk_Theme theme,
	const char *elementName,
	Ttk_ElementSpec *elementSpec,
	void *clientData)
}

declare 6 {
    Ttk_ElementClass *Ttk_RegisterElement(
	Tcl_Interp *interp,
	Ttk_Theme theme,
	const char *elementName,
	Ttk_ElementSpec *elementSpec,
	void *clientData)
}

declare 7 {
    int Ttk_RegisterElementFactory(
	Tcl_Interp *interp,
	const char *name,
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
}
declare 13 {
    Tcl_Obj *Ttk_StateMapLookup(
	Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state)
}
declare 14 {
    int Ttk_StateTableLookup(
    	const Ttk_StateTable *map, Ttk_State state)
}


#
# Low-level geometry utilities.
#
declare 20 {







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
}
declare 13 {
    Tcl_Obj *Ttk_StateMapLookup(
	Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state)
}
declare 14 {
    int Ttk_StateTableLookup(
    	Ttk_StateTable map[], Ttk_State state)
}


#
# Low-level geometry utilities.
#
declare 20 {
139
140
141
142
143
144
145
146
147
148
149
150
declare 35 {
    Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box)
}

#
# Utilities.
#
declare 40 {deprecated {}} {
    int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient)
}









|




139
140
141
142
143
144
145
146
147
148
149
150
declare 35 {
    Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box)
}

#
# Utilities.
#
declare 40 {
    int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient)
}


Changes to generic/ttk/ttkBlink.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 * 	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 "tkInt.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 *dummy)
{
    CursorManager *cm = (CursorManager*)clientData;
    (void)dummy;

    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, 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;







|



















|


<
<












|


|




|










|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * 	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;

Changes to generic/ttk/ttkButton.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * Copyright (c) 2003, Joe English
 *
 * label, button, checkbutton, radiobutton, and menubutton widgets.
 */


#include "tkInt.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 *justifyObj;
    Tcl_Obj *textVariableObj;
    Tcl_Obj *underlineObj;
    Tcl_Obj *widthObj;

    Ttk_TraceHandle	*textVariableTrace;
    Ttk_ImageSpec	*imageSpec;







>
|

















<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
/*
 * 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;

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

typedef struct
{
    WidgetCore	core;
    BasePart	base;
} Base;

static const Tk_OptionSpec BaseOptionSpecs[] =
{
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
        "left", offsetof(Base,base.justifyObj), TCL_INDEX_NONE,
        TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Base,base.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "",
	offsetof(Base,base.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Base,base.underlineObj), TCL_INDEX_NONE,
	0,0,0 },
    /* SB: OPTION_INT, see <<NOTE-NULLOPTIONS>> */
    {TK_OPTION_STRING, "-width", "width", "Width",
	NULL, offsetof(Base,base.widthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Image options
     */
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Base,base.imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Compound base/image options
     */
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 NULL, offsetof(Base,base.compoundObj), TCL_INDEX_NONE,
	 TK_OPTION_NULL_OK, (void *)ttkCompoundStrings,
         GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Base,base.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},

    /*
     * Compatibility/legacy options
     */
    {TK_OPTION_STRING, "-state", "state", "State",
	 "normal", offsetof(Base,base.stateObj), TCL_INDEX_NONE,
	 0,0,STATE_CHANGED },

    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Variable trace procedure for -textvariable option:
 */
static void TextVariableChanged(void *clientData, const char *value)
{
    Base *basePtr = (Base *)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 *dummy, void *recordPtr)
{
    Base *basePtr = (Base *)recordPtr;
    (void)dummy;

    basePtr->base.textVariableTrace = 0;
    basePtr->base.imageSpec = NULL;
}

static void
BaseCleanup(void *recordPtr)
{
    Base *basePtr = (Base *)recordPtr;
    if (basePtr->base.textVariableTrace)
	Ttk_UntraceVariable(basePtr->base.textVariableTrace);
    if (basePtr->base.imageSpec)
    	TtkFreeImageSpec(basePtr->base.imageSpec);
}

static void
BaseImageChanged(
	ClientData clientData, int x, int y, int width, int height,
	int imageWidth, int imageHeight)
{
    Base *basePtr = (Base *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;

    TtkResizeWidget(&basePtr->core);
}

static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Base *basePtr = (Base *)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;







|

<
<
<

|


|


|



|






|






|
<
|

|






|










|
















|

|
<
<







|












<
<
<
<
<
<
<





|







50
51
52
53
54
55
56
57
58



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







145
146
147
148
149
150
151
152
153
154
155
156
157

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 void
BaseImageChanged(
	ClientData clientData, int x, int y, int width, int height,
	int imageWidth, int imageHeight)
{
    Base *basePtr = (Base *)clientData;







    TtkResizeWidget(&basePtr->core);
}

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;
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
	TtkCheckStateOption(&basePtr->core, basePtr->base.stateObj);
    }

    return TCL_OK;
}

static int
BasePostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)
{
    Base *basePtr = (Base *)recordPtr;
    int status = TCL_OK;
    (void)dummy;
    (void)mask;

    if (basePtr->base.textVariableTrace) {
	status = Ttk_FireTrace(basePtr->base.textVariableTrace);
    }

    return status;
}







|

|

<
<







186
187
188
189
190
191
192
193
194
195
196


197
198
199
200
201
202
203
	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;
}
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
typedef struct
{
    WidgetCore	core;
    BasePart	base;
    LabelPart	label;
} Label;

static const Tk_OptionSpec LabelOptionSpecs[] =
{
    {TK_OPTION_BORDER, "-background", "frameColor", "FrameColor",
	NULL, offsetof(Label,label.backgroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(Label,label.foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(Label,label.fontObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	NULL, offsetof(Label,label.borderWidthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	NULL, offsetof(Label,label.reliefObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	NULL, offsetof(Label,label.anchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	NULL, offsetof(Label, label.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	NULL, offsetof(Label, label.wrapLengthObj), TCL_INDEX_NONE,
	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 const WidgetSpec LabelWidgetSpec =
{
    "TLabel",			/* className */
    sizeof(Label),		/* recordSize */
    LabelOptionSpecs,		/* optionSpecs */
    LabelCommands,		/* subcommands */
    BaseInitialize,		/* initializeProc */
    BaseCleanup,		/* cleanupProc */







|


|


|


|


|


|


|


|


|















|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
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 */
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    BasePart	base;
    ButtonPart	button;
} Button;

/*
 * Option specifications:
 */
static const Tk_OptionSpec ButtonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Button, button.commandObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	"normal", offsetof(Button, button.defaultStateObj), TCL_INDEX_NONE,
	0, (void *)ttkDefaultStrings, DEFAULTSTATE_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static int ButtonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Button *buttonPtr = (Button *)recordPtr;

    if (BaseConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }

    /* Handle "-default" option:
     */
    if (mask & DEFAULTSTATE_CHANGED) {
	Ttk_ButtonDefaultState 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 = (Button *)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 const WidgetSpec ButtonWidgetSpec =
{
    "TButton",			/* className */
    sizeof(Button),		/* recordSize */
    ButtonOptionSpecs,		/* optionSpecs */
    ButtonCommands,		/* subcommands */
    BaseInitialize,		/* initializeProc */
    BaseCleanup,		/* cleanupProc */







|


|

|
|







|








|


















|




















|







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    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 */
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
    BasePart base;
    CheckbuttonPart checkbutton;
} Checkbutton;

/*
 * Option specifications:
 */
static const Tk_OptionSpec CheckbuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	NULL, offsetof(Checkbutton, checkbutton.variableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "OnValue",
	"1", offsetof(Checkbutton, checkbutton.onValueObj), TCL_INDEX_NONE,
	0,0,0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "OffValue",
	"0", offsetof(Checkbutton, checkbutton.offValueObj), TCL_INDEX_NONE,
	0,0,0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Checkbutton, checkbutton.commandObj), TCL_INDEX_NONE,
	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 = (Checkbutton *)clientData;

    if (WidgetDestroyed(&checkPtr->core)) {
	return;
    }

    if (!value) {
	TtkWidgetChangeState(&checkPtr->core, TTK_STATE_ALTERNATE, 0);







|


|


|


|


|











|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    BasePart base;
    CheckbuttonPart checkbutton;
} Checkbutton;

/*
 * Option specifications:
 */
static Tk_OptionSpec CheckbuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	NULL, Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
	TK_OPTION_NULL_OK,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);
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
	TtkWidgetChangeState(&checkPtr->core, 0, TTK_STATE_SELECTED);
    }
}

static void
CheckbuttonInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Checkbutton *checkPtr = (Checkbutton *)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 = (Checkbutton *)recordPtr;
    Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
    checkPtr->checkbutton.variableTrace = 0;
    BaseCleanup(recordPtr);
}

static int
CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Checkbutton *checkPtr = (Checkbutton *)recordPtr;
    Tcl_Obj *varName = checkPtr->checkbutton.variableObj;
    Ttk_TraceHandle *vt = NULL;

    if (varName != NULL && *Tcl_GetString(varName) != '\0') {
        vt = Ttk_TraceVariable(interp, varName,
	    CheckbuttonVariableChanged, checkPtr);

        if (!vt) {
	    return TCL_ERROR;
        }
    }

    if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){
	Ttk_UntraceVariable(vt);
	return TCL_ERROR;
    }

    if (checkPtr->checkbutton.variableTrace) {
        Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
    }
    checkPtr->checkbutton.variableTrace = vt;

    return TCL_OK;
}

static int
CheckbuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Checkbutton *checkPtr = (Checkbutton *)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 = (Checkbutton *)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 (checkPtr->checkbutton.variableObj == NULL ||
        *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0')
        CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue));
    else 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 const WidgetSpec CheckbuttonWidgetSpec =
{
    "TCheckbutton",		/* className */
    sizeof(Checkbutton),	/* recordSize */
    CheckbuttonOptionSpecs,	/* optionSpecs */
    CheckbuttonCommands,	/* subcommands */
    CheckbuttonInitialize,	/* initializeProc */
    CheckbuttonCleanup,		/* cleanupProc */







|













|








|
<
|
|
<
<
|
>
|
|
<







<
|
<








|

















|


















<
<
<
|
|
|
|




















|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

492
493


494
495
496
497

498
499
500
501
502
503
504

505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550



551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
	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 */
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
    BasePart base;
    RadiobuttonPart radiobutton;
} Radiobutton;

/*
 * Option specifications:
 */
static const Tk_OptionSpec RadiobuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	"::selectedButton", offsetof(Radiobutton, radiobutton.variableObj),TCL_INDEX_NONE,
	0,0,0},
    {TK_OPTION_STRING, "-value", "Value", "Value",
	"1", offsetof(Radiobutton, radiobutton.valueObj), TCL_INDEX_NONE,
	0,0,0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Radiobutton, radiobutton.commandObj), TCL_INDEX_NONE,
	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 = (Radiobutton *)clientData;

    if (WidgetDestroyed(&radioPtr->core)) {
	return;
    }

    if (!value) {
	TtkWidgetChangeState(&radioPtr->core, TTK_STATE_ALTERNATE, 0);







|


|


|


|












|







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
    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);
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
	TtkWidgetChangeState(&radioPtr->core, 0, TTK_STATE_SELECTED);
    }
}

static void
RadiobuttonCleanup(void *recordPtr)
{
    Radiobutton *radioPtr = (Radiobutton *)recordPtr;
    Ttk_UntraceVariable(radioPtr->radiobutton.variableTrace);
    radioPtr->radiobutton.variableTrace = 0;
    BaseCleanup(recordPtr);
}

static int
RadiobuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Radiobutton *radioPtr = (Radiobutton *)recordPtr;
    Ttk_TraceHandle *vt = Ttk_TraceVariable(
	interp, radioPtr->radiobutton.variableObj,
	RadiobuttonVariableChanged, radioPtr);

    if (!vt) {
	return TCL_ERROR;
    }







|








|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
	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;
    }
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

    return TCL_OK;
}

static int
RadiobuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Radiobutton *radioPtr = (Radiobutton *)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 = (Radiobutton *)recordPtr;
    WidgetCore *corePtr = &radioPtr->core;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
	return TCL_ERROR;
    }
    if (corePtr->state & TTK_STATE_DISABLED)







|

















|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

    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)
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    /* MISSING: select, deselect */
    { 0,0,0 }
};

static const WidgetSpec RadiobuttonWidgetSpec =
{
    "TRadiobutton",		/* className */
    sizeof(Radiobutton),	/* recordSize */
    RadiobuttonOptionSpecs,	/* optionSpecs */
    RadiobuttonCommands,	/* subcommands */
    BaseInitialize,		/* initializeProc */
    RadiobuttonCleanup,		/* cleanupProc */







|







744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    { "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 */
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

/*
 * Option specifications:
 */
static const char *const directionStrings[] = {
    "above", "below", "left", "right", "flush", NULL
};
static const Tk_OptionSpec MenubuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	"", offsetof(Menubutton, menubutton.menuObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	"below", offsetof(Menubutton, menubutton.directionObj), TCL_INDEX_NONE,
	0, (void *)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 const 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_FILL_X,
	        TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */








|


|

|
|














|



















|







790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845

/*
 * 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.
 */

Changes to generic/ttk/ttkCache.c.

24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
 * @@@ 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 "tkInt.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 */







>
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * @@@ 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 */
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    Tcl_HashEntry *entryPtr;

    /*
     * Free fonts:
     */
    entryPtr = Tcl_FirstHashEntry(&cache->fontTable, &search);
    while (entryPtr != NULL) {
	Tcl_Obj *fontObj = (Tcl_Obj *)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_Obj *)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_Obj *)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 = (Tk_Image)Tcl_GetHashValue(entryPtr);
	if (image) {
	    Tk_FreeImage(image);
	}
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&cache->imageTable);
    Tcl_InitHashTable(&cache->imageTable, TCL_STRING_KEYS);







|














|














|














|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    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);
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    Tcl_DeleteHashTable(&cache->imageTable);

    /*
     * Free named colors:
     */
    entryPtr = Tcl_FirstHashEntry(&cache->namedColors, &search);
    while (entryPtr != NULL) {
	Tcl_Obj *colorNameObj = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
	Tcl_DecrRefCount(colorNameObj);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&cache->namedColors);

    ckfree(cache);
}

/*
 * CacheWinEventHandler --
 * 	Detect when the cache window is destroyed, clear cache.
 */
static void CacheWinEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Ttk_ResourceCache cache = (Ttk_ResourceCache)clientData;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
    Tk_DeleteEventHandler(cache->tkwin, StructureNotifyMask,
	    CacheWinEventHandler, clientData);
    Ttk_ClearCache(cache);







|





|








|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    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);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    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_Obj *)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_Obj *)Tcl_GetHashValue(entryPtr);
    }
    return objPtr;
}

/*
 * Template for allocation routines:
 */







|

















|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    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:
 */
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
{
    int newEntry;
    Tcl_HashEntry *entryPtr =
	Tcl_CreateHashEntry(table,Tcl_GetString(objPtr),&newEntry);
    Tcl_Obj *cacheObj;

    if (!newEntry) {
	return (Tcl_Obj *)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_BackgroundException(interp, TCL_ERROR);
	return NULL;
    }
}

/*
 * Ttk_UseFont --
 * 	Acquire a font from the cache.







|











|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
{
    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.
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
	&cache->borderTable,(Allocator)Tk_Alloc3DBorderFromObj, tkwin, objPtr);
}

/* NullImageChanged --
 * 	Tk_ImageChangedProc for Ttk_UseImage
 */

static void NullImageChanged(ClientData dummy,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */
    (void)dummy;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;
}

/*
 * 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 (Tk_Image)Tcl_GetHashValue(entryPtr);
    }

    image = Tk_GetImage(cache->interp, tkwin, imageName, NullImageChanged,0);
    Tcl_SetHashValue(entryPtr, image);

    if (!image) {
	Tcl_BackgroundException(cache->interp, TCL_ERROR);
    }

    return image;
}

/*EOF*/







|

|
<
<
<
<
<
<
<
<
















|






|






311
312
313
314
315
316
317
318
319
320








321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
	&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*/

Changes to generic/ttk/ttkClamTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * Copyright (C) 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.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






|


|
|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*reliefObj;
    Tcl_Obj 	*borderWidthObj;	/* See <<NOTE-BORDERWIDTH>> */
} BorderElement;

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(BorderElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(BorderElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(BorderElement,darkColorObj), DARK_COLOR },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(BorderElement,borderWidthObj), "2" },
    { NULL, TK_OPTION_BOOLEAN, 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 *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *border = (BorderElement*)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);
    if (borderWidth == 1) ++borderWidth;
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    BorderElement *border = (BorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    int borderWidth = 2;
    Tcl_Obj *outer = 0, *upper = 0, *lower = 0;
    (void)dummy;
    (void)state;

    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);
    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);

    if (borderWidth == 0) return;

    switch (relief) {







|

|

|

|

|

|
|





|
|




|




<
<
<
<






|


|



<
<







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136




137
138
139
140
141
142
143
144
145
146
147
148
149


150
151
152
153
154
155
156
    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) {
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
	    outer = upper = lower = border->borderColorObj;
	    break;
    }

    DrawSmoothBorder(tkwin, d, b, outer, upper, lower);
}

static const 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 const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(FieldElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,darkColorObj), DARK_COLOR },
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    FieldElement *field = (FieldElement *)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;
    (void)dummy;
    (void)state;

    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 const 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 = (FieldElement *)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 const 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 const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,sizeObj), "10" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "1" },
    { "-indicatorbackground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,backgroundObj), "white" },
    { "-indicatorforeground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,foregroundObj), "black" },
    { "-upperbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,upperColorObj), DARKEST_COLOR },
    { "-lowerbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,lowerColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int size = 10;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    IndicatorElement *indicator = (IndicatorElement *)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;
    (void)dummy;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    Display *display = Tk_Display(tkwin);
    IndicatorElement *indicator = (IndicatorElement *)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;
    (void)dummy;

    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*/







|


















|

|

|

|

|
|



|


<
<
<
<
<
<




|


|




<
<






|















|










|




















|

|

|

|

|

|

|
|



|


|


<
<
<







|


|





<



















|



|
<






<







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214






215
216
217
218
219
220
221
222
223
224
225
226


227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349

350
351
352
353
354
355
356
	    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*/
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485




486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
	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 const Ttk_ElementSpec RadioIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    RadioIndicatorElementDraw
};

static const 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 const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
{
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,sizeObj),
	STR(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(MenuIndicatorElement,colorObj),
	"black" },
    { "-arrowpadding",TK_OPTION_STRING,
	offsetof(MenuIndicatorElement,paddingObj),
	"3" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void MenuIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int size = MENUBUTTON_ARROW_SIZE;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);
    int size = MENUBUTTON_ARROW_SIZE;
    int width, height;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec MenuIndicatorElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(MenuIndicatorElement),
    MenuIndicatorElementOptions,
    MenuIndicatorElementSize,
    MenuIndicatorElementDraw
};

/*------------------------------------------------------------------------
 * +++ Grips.
 *
 * TODO: factor this with ThumbElementDraw
 */





typedef struct {
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*gripCountObj;
} GripElement;

static const Ttk_ElementOptionSpec GripElementOptions[] = {
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(GripElement,lightColorObj), LIGHT_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(GripElement,borderColorObj), DARKEST_COLOR },
    { "-gripcount", TK_OPTION_INT,
	offsetof(GripElement,gripCountObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void GripElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    int gripCount = 0;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);
    if (orient == TTK_ORIENT_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;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    GC lightGC = Ttk_GCForColor(tkwin,grip->lightColorObj,d);
    GC darkGC = Ttk_GCForColor(tkwin,grip->borderColorObj,d);
    int gripPad = 1, gripCount = 0;
    int i;
    (void)state;

    Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);

    if (orient == TTK_ORIENT_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 const Ttk_ElementSpec GripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(GripElement),
    GripElementOptions,
    GripElementSize,
    GripElementDraw
};








|







|















|


|


|


|

|



|


|


<
<
<








|


|




<
<








|













>
>
>
>







|

|

|

|
|






|
|

<
<


|











|
|




<



|
















|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438


439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488


489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
	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
};

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*arrowColorObj;
    Tcl_Obj 	*arrowSizeObj;
    Tcl_Obj 	*gripCountObj;
    Tcl_Obj 	*sliderlengthObj;
} ScrollbarElement;

static const Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ScrollbarElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ScrollbarElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,borderColorObj), DARKEST_COLOR },
    { "-troughcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,troughColorObj), DARKER_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,darkColorObj), DARK_COLOR },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,arrowColorObj), "#000000" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
    { "-gripcount", TK_OPTION_INT,
	offsetof(ScrollbarElement,gripCountObj), "5" },
    { "-sliderlength", TK_OPTION_INT,
	offsetof(ScrollbarElement,sliderlengthObj), "30" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    GC gcb = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
    GC gct = Ttk_GCForColor(tkwin,sb->troughColorObj,d);
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

static void ThumbElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ThumbElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int gripCount = 0;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    GC lightGC, darkGC;
    int x1, y1, x2, y2, dx, dy, i;
    const int w = WIN32_XDRAWLINE_HACK;
    (void)dummy;
    (void)state;

    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:
     */
    TtkGetOrientFromObj(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 const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*------------------------------------------------------------------------
 * +++ Slider element.
 */
static void SliderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int length, thickness;
    Ttk_Orient orient;
    (void)dummy;
    (void)paddingPtr;

    length = thickness = SCROLLBAR_THICKNESS;
    TtkGetOrientFromObj(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 const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    SliderElementSize,
    ThumbElementDraw
};








|

|

|

|

|

|

|

|

|

|

|
|



|


|


<
<
<




|








|


|

<
<
<
<





|


|
|
<



<
<










|



|




















|











|


|
|
<
<
<


|












|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587



588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605




606
607
608
609
610
611
612
613
614
615

616
617
618


619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670



671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
    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
};

739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774


775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
	    widthPtr, heightPtr, paddingPtr);
    *paddingPtr = Ttk_UniformPadding(2);
    *widthPtr += 4;
    *heightPtr += 4;
}

static void PbarElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    PbarElementSize,
    PbarElementDraw
};


/*------------------------------------------------------------------------
 * +++ Scrollbar arrows.
 */


static void ArrowElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    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 direction = (ArrowDirection)PTR2INT(clientData);
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    GC gc = Ttk_GCForColor(tkwin,sb->arrowColorObj, d);
    int h, cx, cy;
    (void)state;

    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, direction, &cx, &cy);
    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
}

static const 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 const Ttk_ElementOptionSpec NotebookElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(NotebookElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,darkColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TabElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    int borderWidth = 2;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
    paddingPtr->bottom = 0;
}

static void TabElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    NotebookElement *tab = (NotebookElement *)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;
    (void)dummy;

    if (state & TTK_STATE_SELECTED) {
	dh = borderWidth;
    }

    if (state & TTK_STATE_USER2) {	/* Rightmost tab */
	--b.width;







|


|
<
<
|




|





|











>
>

|


|

<
<
<
<








|
|


<










|


|


|










|
|










|

|

|

|

|
|



|



<
<
<
<
<
<





|


|






<







702
703
704
705
706
707
708
709
710
711
712


713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743




744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811






812
813
814
815
816
817
818
819
820
821
822
823
824
825
826

827
828
829
830
831
832
833
	    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;
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
    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 const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NotebookElement),
    NotebookElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    int borderWidth = 2;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void ClientElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    NotebookElement *ce = (NotebookElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    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 const 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_FILL_BOTH,
	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)))








|









|



<
<
<
<
<
<




|


|


<
<







|
















|







846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866






867
868
869
870
871
872
873
874
875
876


877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
    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)))

989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
    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, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp,
	theme, "downarrow", &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp,
	theme, "leftarrow", &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp,
	theme, "rightarrow", &ArrowElementSpec, INT2PTR(ARROW_RIGHT));

    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,  INT2PTR(TTK_ORIENT_HORIZONTAL));
    Ttk_RegisterElement(interp, theme, "vgrip",
	    &GripElementSpec,  INT2PTR(TTK_ORIENT_VERTICAL));

    Ttk_RegisterLayouts(theme, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::clam", TTK_VERSION);

    return TCL_OK;
}







|

|

|

|
















|

|







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
    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;
}

Changes to generic/ttk/ttkClassicTheme.c.

1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * Copyright (c) 2004, Joe English
 *
 * "classic" theme; implements the classic Motif-like Tk look.
 *
 */

#include "tkInt.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 const Ttk_ElementOptionSpec HighlightElementOptions[] = {
    { "-highlightcolor",TK_OPTION_COLOR,
	offsetof(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
    { "-highlightthickness",TK_OPTION_PIXELS,
	offsetof(HighlightElement,highlightThicknessObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void HighlightElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    *paddingPtr = Ttk_UniformPadding((short)highlightThickness);
}

static void HighlightElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    XColor *highlightColor = Tk_GetColorFromObj(tkwin, hl->highlightColorObj);
    (void)dummy;
    (void)b;
    (void)state;

    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    if (highlightColor && highlightThickness > 0) {
	GC gc = Tk_GCForColor(highlightColor, d);
	Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
    }
}

static const 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 const Ttk_ElementOptionSpec ButtonBorderElementOptions[] =
{
    { "-background", TK_OPTION_BORDER,
	offsetof(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ButtonBorderElement,reliefObj), "flat" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ButtonBorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int borderWidth = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int inset = 0;
    (void)dummy;
    (void)state;

    /*
     * Get option values.
     */
    border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);







|
>
>















|

|

|
|



|


|

<
<
<
<






|


|


<
<
<








|










|














|

|
|
|
|
|
|
|
|
|



|


|
|

<
<
<
<












|



|


|


|

<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




40
41
42
43
44
45
46
47
48
49
50
51



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105




106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136
/*
 * 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);
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    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 const 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.
 */


typedef struct
{
    Tcl_Obj *sizeObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] =
{
    { "-arrowsize", TK_OPTION_PIXELS, offsetof(ArrowElement,sizeObj),
	DEFAULT_ARROW_SIZE },
    { "-background", TK_OPTION_BORDER, offsetof(ArrowElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(ArrowElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(ArrowElement,reliefObj),"raised" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ArrowElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int size = 12;
    (void)dummy;
    (void)paddingPtr;

    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)
{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)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];
    (void)state;

    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;







|















>








|

|

|

|

|
|



|


|

<
<









|
|





<







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
    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;
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306




307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
	    points[2].x = b.x;		points[2].y = b.y + size;
	    break;
    }

    Tk_Fill3DPolygon(tkwin, d, border, points, 3, borderWidth, relief);
}

static const 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.
 */





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 const Ttk_ElementOptionSpec SashOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SashElement,borderObj), DEFAULT_BACKGROUND },
    { "-sashrelief", TK_OPTION_RELIEF,
	offsetof(SashElement,sashReliefObj), "sunken" },
    { "-sashthickness", TK_OPTION_PIXELS,
	offsetof(SashElement,sashThicknessObj), "6" },
    { "-sashpad", TK_OPTION_PIXELS,
	offsetof(SashElement,sashPadObj), "2" },
    { "-handlesize", TK_OPTION_PIXELS,
	offsetof(SashElement,handleSizeObj), "8" },
    { "-handlepad", TK_OPTION_PIXELS,
	offsetof(SashElement,handlePadObj), "8" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SashElement *sash = (SashElement *)elementRecord;
    int sashPad = 2, sashThickness = 6, handleSize = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    (void)paddingPtr;
    (void)paddingPtr;

    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 (orient == TTK_ORIENT_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 = (SashElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, sash->borderObj);
    GC gc1,gc2;
    int relief = TK_RELIEF_RAISED;
    int handleSize = 8, handlePad = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    Ttk_Box hb;
    (void)state;

    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 (orient == TTK_ORIENT_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 (orient == TTK_ORIENT_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 const Ttk_ElementSpec SashElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SashElement),
    SashOptions,
    SashElementSize,
    SashElementDraw
};








|












|






|


>
>
>
>










|
|
|
|
|

|
|
|

|

|
|






|

|
<
<








|









|




|

<














|


|







|












|






|




|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330


331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
	    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
};

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
	        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_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,







|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
	        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,
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
    Ttk_RegisterElement(interp, theme, "highlight",
	    &HighlightElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Button.border",
	    &ButtonBorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    Ttk_RegisterElement(interp, theme, "hsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_HORIZONTAL));
    Ttk_RegisterElement(interp, theme, "vsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_VERTICAL));

    /*
     * Register layouts:
     */
    Ttk_RegisterLayouts(theme, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::classic", TTK_VERSION);

    return TCL_OK;
}

/*EOF*/







|

|

|

|

|

|
|

|












481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    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*/

Changes to generic/ttk/ttkDecls.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

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_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL)

#endif

#if !defined(BUILD_tk)
# define TTK_DEPRECATED(msg) TTKAPI TCL_DEPRECATED_API(msg)
#elif defined(TK_NO_DEPRECATED)
# define TTK_DEPRECATED(msg) MODULE_SCOPE
#else
# define TTK_DEPRECATED(msg) TTKAPI
#endif



/* !BEGIN!: Do not edit below this line. */

#define TTK_STUBS_EPOCH 0
#define TTK_STUBS_REVISION 31

#ifdef __cplusplus
extern "C" {
#endif

/*
 * 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,
				const Ttk_ElementSpec *elementSpec,
				void *clientData);
/* 6 */
TTKAPI Ttk_ElementClass * Ttk_RegisterElement(Tcl_Interp *interp,
				Ttk_Theme theme, const char *elementName,
				const 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(const 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 */







|


<
<
<
<
<
<
<
<
<
















|





|



|



|
|
|


|
|
|


|

|


|















|







9
10
11
12
13
14
15
16
17
18









19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

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

#ifdef __cplusplus
extern "C" {
#endif

/*
 * 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 */
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* 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 */
TTK_DEPRECATED("")
int			Ttk_GetOrientFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *orient);

typedef struct TtkStubs {
    int magic;
    int epoch;
    int revision;
    void *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, const Ttk_ElementSpec *elementSpec, void *clientData); /* 5 */
    Ttk_ElementClass * (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, const 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) (const 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 */







<
|






|

|


|
|
|
|
|
|





|







126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* 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 */
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    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);
    TCL_DEPRECATED_API("") int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); /* 40 */
} TtkStubs;

extern const TtkStubs *ttkStubsPtr;

#ifdef __cplusplus
}
#endif







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    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;

extern const TtkStubs *ttkStubsPtr;

#ifdef __cplusplus
}
#endif

Changes to generic/ttk/ttkDefaultTheme.c.

1
2
3
4
5
6
7





8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * Copyright (c) 2003, Joe English
 *
 * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
 */

#include "tkInt.h"





#include "ttkTheme.h"

#if defined(_WIN32)
static const int WIN32_XDRAWLINE_HACK = 1;
#else
static const int WIN32_XDRAWLINE_HACK = 0;
#endif

#if defined(MAC_OSX_TK)
  #define IGNORES_VISUAL
#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 const enum BorderColor 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 const enum BorderColor 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*/
};






|
>
>
>
>
>


|





<
<
<
<




















|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20




21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * 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*/
};
112
113
114
115
116
117
118


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
	    break;
    }
}

/* Alternate shadow colors for entry fields:
 * NOTE: FLAT color is normally white, and the LITE color is a darker shade.
 */


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, DARK);
    DrawCorner(tkwin, d, border, borderGC,
	b.x+1, b.y+1, b.width-2, b.height-2, 0, BRDR);
    DrawCorner(tkwin, d, border, borderGC,
	b.x+1, b.y+1, b.width-2, b.height-2, 1, LITE);
    DrawCorner(tkwin, d, border, borderGC,
	b.x, b.y, b.width, b.height, 1, FLAT);
    return;
}

/*
 * ArrowPoints --
 * 	Compute points of arrow polygon.
 */
static void ArrowPoints(Ttk_Box b, ArrowDirection direction, XPoint points[4])
{
    int cx, cy, h;

    switch (direction) {
	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;







>
>






|

|

|

|







|



|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
	    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;
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    }

    points[3].x = points[0].x;
    points[3].y = points[0].y;
}

/*public*/
void TtkArrowSize(int h, ArrowDirection direction, int *widthPtr, int *heightPtr)
{
    switch (direction) {
	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 direction)
{
    XPoint points[4];
    ArrowPoints(b, direction, points);
    XFillPolygon(display, d, gc, points, 3, Convex, CoordModeOrigin);
    XDrawLines(display, d, gc, points, 4, CoordModeOrigin);

    /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */
    XDrawPoint(display, d, gc, points[2].x, points[2].y);
}

/*public*/
void TtkDrawArrow(
    Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection direction)
{
    XPoint points[4];
    ArrowPoints(b, direction, points);
    XDrawLines(display, d, gc, points, 4, CoordModeOrigin);

    /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */
    XDrawPoint(display, d, gc, points[2].x, points[2].y);
}

/*
 *----------------------------------------------------------------------
 * +++ Border element implementation.
 *
 * This border consists of (from outside-in):







|

|













|


|


<
<
<




|


|

<
<
<







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211



212
213
214
215
216
217
218
219
220



221
222
223
224
225
226
227
    }

    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):
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderColorObj;	/* Extra border color */
    Tcl_Obj	*borderWidthObj;
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*defaultStateObj;	/* for buttons */
} BorderElement;

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-background", TK_OPTION_BORDER, offsetof(BorderElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-bordercolor",TK_OPTION_COLOR,
	offsetof(BorderElement,borderColorObj), "black" },
    { "-default", TK_OPTION_ANY, offsetof(BorderElement,defaultStateObj),
    	"disabled" },
    { "-borderwidth",TK_OPTION_PIXELS, offsetof(BorderElement,borderWidthObj),
    	STRINGIFY(BORDERWIDTH) },
    { "-relief", TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj),
    	"flat" },
        { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    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 *dummy, void *elementRecord,
    Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, bd->borderColorObj);
    int borderWidth = 2;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)state;

    /*
     * Get option values.
     */
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);







|
|


|
|

|

|

|



|


|

|
<
<
<
<












|


|




|
<
<







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262




263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283


284
285
286
287
288
289
290
    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);
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	/* Space for default ring: */
	b = Ttk_PadBox(b, Ttk_UniformPadding(1));
    }

    DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);
}

static const 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 const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER, offsetof(FieldElement,borderObj),
    	"white" },
    { "-bordercolor",TK_OPTION_COLOR, offsetof(FieldElement,borderColorObj),
	"black" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, field->borderColorObj);
    (void)dummy;
    (void)state;

    Tk_Fill3DRectangle(
	tkwin, d, border, b.x, b.y, b.width, b.height, 0, TK_RELIEF_SUNKEN);
    DrawFieldBorder(tkwin, d, border, borderColor, b);
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};








|
















|
|

|

|



|


<
<
<
<
<
<




|


|


<
<






|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333






334
335
336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
351
352
353
354
355
356
357
	/* 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
};

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
 * 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] */
    const 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 const 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 }
};








|



















|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
 * 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 }
};

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

static IndicatorSpec checkbutton_spec = {
    13, 13, 4,		/* width, height, nimages */
    checkbutton_pixels,
    checkbutton_states
};

static const 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 }
};








|







416
417
418
419
420
421
422
423
424
425
426
427
428
429
430

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 }
};

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
    Tcl_Obj *colorObj;
    Tcl_Obj *lightColorObj;
    Tcl_Obj *shadeColorObj;
    Tcl_Obj *borderColorObj;
    Tcl_Obj *marginObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-background", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-foreground", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,foregroundObj), DEFAULT_FOREGROUND },
    { "-indicatorcolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,colorObj), "#FFFFFF" },
    { "-lightcolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,lightColorObj), "#DDDDDD" },
    { "-shadecolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,shadeColorObj), "#888888" },
    { "-bordercolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,borderColorObj), "black" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(IndicatorElement,marginObj), "0 2 4 2" },
	    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorSpec *spec = (IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    (void)paddingPtr;

    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 = (IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)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 = NULL;

    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







|

|

|

|

|

|

|

|
|






|
|

<
<









|
|








|







456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    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
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
    imgColors[5 /*F*/] = frameColor->pixel;
    imgColors[6 /*G*/] = fgColor->pixel;
    imgColors[7 /*H*/] = fgColor->pixel;

    /*
     * Create a scratch buffer to store the image:
     */

#if defined(IGNORES_VISUAL)

    /*
     * Platforms which ignore the VisualInfo can use XCreateImage to get the
     * scratch image.  This is essential on macOS, where it is not safe to call
     * XGetImage in a display procedure.
     */

    img = XCreateImage(display, NULL, 32, ZPixmap, 0, NULL,
		       (unsigned int)spec->width, (unsigned int)spec->height,
		       0, 0);
#else

    /*
     * This trick allows creating the scratch XImage without having to
     * construct a VisualInfo.
     */

    img = XGetImage(display, d, 0, 0,
		    (unsigned int)spec->width, (unsigned int)spec->height,
		    AllPlanes, ZPixmap);
#endif

    if (img == NULL) {
        return;
    }

#if defined(IGNORES_VISUAL)

    img->data = (char *)ckalloc(img->bytes_per_line * img->height);
    if (img->data == NULL) {
        XDestroyImage(img);
	return;
    }

#endif

    /*
     * Create the image, painting it into the 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 the image 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);

    /*
     * Protect against the possibility that some future platform might
     * not use the Tk memory manager in its implementation of XDestroyImage,
     * even though that would be an extremely strange thing to do.
     */

#if defined(IGNORES_VISUAL)
    ckfree(img->data);
    img->data = NULL;
#endif

    XDestroyImage(img);
}

static const 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.
 */


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 const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,borderColorObj), "black" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj),"black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * Note asymmetric padding:
 * top/left padding is 1 less than bottom/right,
 * since in this theme 2-pixel borders are asymmetric.
 */
static const 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 = (ArrowElement *)elementRecord;
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    int width = SCROLLBAR_WIDTH;
    (void)paddingPtr;

    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)
{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)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;
    (void)state;

    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 const 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 *const directionStrings[] = {	/* See also: button.c */
    "above", "below", "left", "right", "flush", NULL
};
enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH };

static const Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = {
    { "-direction", TK_OPTION_STRING,
	offsetof(MenubuttonArrowElement,directionObj), "below" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(MenubuttonArrowElement,colorObj), "black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };

static void MenubuttonArrowElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)elementRecord;
    int size = MENUBUTTON_ARROW_SIZE;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    *widthPtr = *heightPtr = 2 * size + 1;
    *widthPtr += Ttk_PaddingWidth(MenubuttonArrowPadding);
    *heightPtr += Ttk_PaddingHeight(MenubuttonArrowPadding);
}

static void MenubuttonArrowElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)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;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    Tcl_GetIndexFromObjStruct(NULL, arrow->directionObj, directionStrings,
	   sizeof(char *), ""/*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 const Ttk_ElementSpec MenubuttonArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenubuttonArrowElement),
    MenubuttonArrowElementOptions,
    MenubuttonArrowElementSize,
    MenubuttonArrowElementDraw
};








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<

|

<









|

<


>






<

<
<
<
<
<
<
<
<
<
<
<
<



|














>








|

|

|

|

|

|
|







|





|
|

<












|
|





<











|




















|




|

|

|

|
|


|


|


|

<
<
<







|


|






<
<


|
|
















|







540
541
542
543
544
545
546



















547
548
549


550
551
552











553
554
555

556
557
558
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574
575

576












577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705



706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722


723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
    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
};

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    Tcl_Obj *colorObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *grooveWidthObj;
    Tcl_Obj *orientObj;
} TroughElement;

static const Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(TroughElement, orientObj), "horizontal" },
    { "-troughborderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), "1" },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
    { "-groovewidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,grooveWidthObj), "-1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    int borderWidth = 2, grooveWidth = 0;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN, groove = -1;
    Ttk_Orient orient;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
    TtkGetOrientFromObj(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 const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TroughElement),
    TroughElementOptions,
    TroughElementSize,
    TroughElementDraw
};








|

|

|

|

|

|
|



|


|

<
<
<










|


|

|
<
<
<


|


















|







765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791



792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807



808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    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
};

922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
    Tcl_Obj *lastObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderColorObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *orientObj;
} ThumbElement;

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-width", TK_OPTION_PIXELS, offsetof(ThumbElement,sizeObj),
        STRINGIFY(SCROLLBAR_WIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(ThumbElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(ThumbElement,borderColorObj),
	"black" },
    { "-relief", TK_OPTION_RELIEF, offsetof(ThumbElement,reliefObj),"raised" },
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int size;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->sizeObj, &size);
    TtkGetOrientFromObj(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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, thumb->borderColorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    /*
     * 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 const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};








|
|

|

|

|
|
|



|


|
|
<
<
<
<

|











|


|




<
<















|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869




870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890


891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    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
};

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
    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 const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"15" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	STRINGIFY(BORDERWIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(ThumbElement,borderColorObj),
	"black" },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness, borderWidth;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, slider->borderColorObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    (void)dummy;
    (void)state;

    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 const 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 const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-diameter", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,diameterObj), "9" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    int diameter = 0;
    Ttk_Padding margins;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)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;
    (void)dummy;

    if (state & TTK_STATE_LEAF) {
	/* don't draw anything ... */
	return;
    }

    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);







|
|

|

|

|

|

|

|

|



|


|
<
|
<
<

|


















|


|



<
<










|




















|

|

|

|
|



|


|


<
<








|


|





<







928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

958


959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985


986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033


1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
    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);
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

    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 const Ttk_ElementSpec TreeitemIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TreeitemIndicator),
    TreeitemIndicatorOptions,
    TreeitemIndicatorSize,
    TreeitemIndicatorDraw
};








|







1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

    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
};

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208



1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
    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, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));




    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);

    Tcl_PkgProvide(interp, "ttk::theme::alt", TTK_VERSION);

    return TCL_OK;
}

/*EOF*/







|

|

|

|

|
>
>
>










1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
    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*/

Changes to generic/ttk/ttkElements.c.

1
2
3
4
5
6
7

8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * Copyright (c) 2003, Joe English
 *
 * Default implementation for themed elements.
 *
 */


#include "tkInt.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 */ const Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, TK_OPTION_BOOLEAN, 0, NULL } };

/* public */ void
TtkNullElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;
    (void)paddingPtr;
}

/* public */ void
TtkNullElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)d;
    (void)b;
    (void)state;
}

/* public */ Ttk_ElementSpec ttkNullElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,







>
|
>













|



|


<
<
<
<
<
<




|


<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30






31
32
33
34
35
36
37






38
39
40
41
42
43
44
/*
 * 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,
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 * Ttk_GetLayout() automatically includes a background element.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;
} BackgroundElement;

static const Ttk_ElementOptionSpec BackgroundElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	    offsetof(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FillElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    BackgroundElement *bg = (BackgroundElement *)elementRecord;
    Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);
    (void)dummy;
    (void)state;

    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)
{
    (void)b;

    FillElementDraw(
	clientData, elementRecord, tkwin,
	d, Ttk_WinBox(tkwin), state);
}

static const Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BackgroundElement),
    BackgroundElementOptions,
    TtkNullElementSize,
    FillElementDraw
};

static const 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 const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(BorderElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    (void)dummy;
    (void)state;

    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 const 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 const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,borderObj), "white" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(FieldElement,borderWidthObj), "2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FieldElement *field = (FieldElement *)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void FieldElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};








|

|
|



|


|

<
<










<
<





|







|

















|

|

|

|
|



|


|

<
<
<
<
<





|


|


<
<











|
















|

|

|
|



|


|

<
<
<
<





|


|


<
<






|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129





130
131
132
133
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182




183
184
185
186
187
188
189
190
191
192
193


194
195
196
197
198
199
200
201
202
203
204
205
206
207
 * 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
};

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

typedef struct {
    Tcl_Obj	*paddingObj;
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*shiftreliefObj;
} PaddingElement;

static const Ttk_ElementOptionSpec PaddingElementOptions[] = {
    { "-padding", TK_OPTION_STRING,
	offsetof(PaddingElement,paddingObj), "0" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(PaddingElement,reliefObj), "flat" },
    { "-shiftrelief", TK_OPTION_INT,
	offsetof(PaddingElement,shiftreliefObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PaddingElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    PaddingElement *padding = (PaddingElement *)elementRecord;
    int shiftRelief = 0;
    int relief = TK_RELIEF_FLAT;
    Ttk_Padding pad;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    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 const Ttk_ElementSpec PaddingElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PaddingElement),
    PaddingElementOptions,
    PaddingElementSize,
    TtkNullElementDraw
};








|

|

|

|
|



|


|



<
<
<







|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

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
};

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    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 const Ttk_ElementOptionSpec FocusElementOptions[] = {
    { "-focuscolor",TK_OPTION_COLOR,
	offsetof(FocusElement,focusColorObj), "black" },
    { "-focusthickness",TK_OPTION_PIXELS,
	offsetof(FocusElement,focusThicknessObj), "1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FocusElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, focus->focusThicknessObj, &focusThickness);
    *paddingPtr = Ttk_UniformPadding((short)focusThickness);
}

static void FocusElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;
    (void)dummy;

    if (state & TTK_STATE_FOCUS) {
	Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
	DrawFocusRing(tkwin, d, focus->focusColorObj, b);
    }
}

static const 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 const Ttk_ElementOptionSpec SeparatorElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(SeparatorElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SeparatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    *widthPtr = *heightPtr = 2;
}

static void HorizontalSeparatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SeparatorElement *separator = (SeparatorElement *)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);
    (void)dummy;
    (void)state;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SeparatorElement *separator = (SeparatorElement *)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);
    (void)dummy;
    (void)state;

    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 = (SeparatorElement *)elementRecord;
    Ttk_Orient orient;

    TtkGetOrientFromObj(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 const Ttk_ElementSpec HorizontalSeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SeparatorElement),
    SeparatorElementOptions,
    SeparatorElementSize,
    HorizontalSeparatorElementDraw
};

static const Ttk_ElementSpec VerticalSeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SeparatorElement),
    SeparatorElementOptions,
    SeparatorElementSize,
    HorizontalSeparatorElementDraw
};

static const 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 const Ttk_ElementOptionSpec SizegripOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
    {0,TK_OPTION_BOOLEAN,0,0}
};

static void SizegripSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    int gripCount = 3, gripSpace = 2, gripThickness = 3;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    *widthPtr = *heightPtr = gripCount * (gripSpace + gripThickness);
}

static void SizegripDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    SizegripElement *grip = (SizegripElement *)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;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec SizegripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SizegripElement),
    SizegripOptions,
    SizegripSize,
    SizegripDraw
};








|

|

|
|



|


|

<
<
<
<






|


|

<







|



















|

|

|
|



|


<
<
<
<
<




|


|



<
<






|


|



<
<









|
|
<
|












|







|







|















|

|
|



|



<
<
<
<
<




|


|





<
<









|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304




305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354





355
356
357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
373
374
375
376
377
378


379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445





446
447
448
449
450
451
452
453
454
455
456
457
458


459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    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
};

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *diameterObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *borderWidthObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorcolor", TK_OPTION_BORDER,
	offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(IndicatorElement,reliefObj), "raised" },
    { "-indicatordiameter", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,diameterObj), "12" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "0 2 4 2" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * Checkbutton indicators (default): 3-D square.
 */
static void SquareIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Tk_3DBorder border = 0, interior = 0;
    int relief = TK_RELIEF_RAISED;
    Ttk_Padding padding;
    int borderWidth = 2;
    int diameter;
    (void)dummy;
    (void)state;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Tk_3DBorder border = 0, interior = 0;
    int borderWidth = 2;
    int relief = TK_RELIEF_RAISED;
    int diameter, radius;
    XPoint points[4];
    Ttk_Padding padding;
    (void)dummy;
    (void)state;

    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);








|

|

|

|

|

|

|
|






|


|


<
<
<







|


|





<
<




















|


|


<
<
<







|


|






<
<







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537


538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563



564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580


581
582
583
584
585
586
587
    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);

661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
    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 const Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    SquareIndicatorElementSize,
    SquareIndicatorElementDraw
};

static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    DiamondIndicatorElementSize,
    DiamondIndicatorElementDraw
};








|







|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    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
};

697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
    Tcl_Obj *widthObj;
    Tcl_Obj *heightObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *marginObj;
} MenuIndicatorElement;

static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,widthObj), "4.0m" },
    { "-indicatorheight", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,heightObj), "1.7m" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(MenuIndicatorElement,reliefObj),"raised" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(MenuIndicatorElement,marginObj), "5 0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void MenuIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, mi->backgroundObj);
    Ttk_Padding margins;
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    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 const 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.
 */


typedef struct {
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-relief",TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ArrowElement,borderWidthObj), "1" },
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj),"black"},
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), "14" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const 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 = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    int width = 14;
    (void)paddingPtr;

    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)
{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 1;
    (void)state;

    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 const 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 const Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void TroughElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TroughElement),
    TroughElementOptions,
    TroughElementSize,
    TroughElementDraw
};








|

|

|

|

|

|

|
|



|


|

<
<
<








|


|



<
<








|














>








|

|

|

|

|

|
|


|





|
|

<












|
|




<



|
|


|


|



















|

|

|

|
|



|


|

<
<
<






|


|


<
<









|







635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663



664
665
666
667
668
669
670
671
672
673
674
675
676
677
678


679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797



798
799
800
801
802
803
804
805
806
807
808
809


810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
    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
};

908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
    Tcl_Obj *orientObj;
    Tcl_Obj *thicknessObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
} ThumbElement;

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ThumbElement, orientObj), "horizontal" },
    { "-width", TK_OPTION_PIXELS,
	offsetof(ThumbElement,thicknessObj), DEFAULT_ARROW_SIZE },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ThumbElement,reliefObj), "raised" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ThumbElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int thickness;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
    TtkGetOrientFromObj(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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder  border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    (void)dummy;
    (void)state;

    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 const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};








|

|

|

|

|

|
|



|


|
<
|
<
<


|











|


|


<
<







|







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

861


862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881


882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
    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
};

984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
    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 const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"30" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    Ttk_Orient orient;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    TtkGetOrientFromObj(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);








|
|

|

|

|

|

|

|



|


|
<
|
<
<

|

















|


|

|
<
<
<


|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933

934


935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959



960
961
962
963
964
965
966
967
968
969
    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);

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
		    Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		    b.x+borderWidth, b.y, b.x+b.width-borderWidth, b.y);
	    }
	}
    }
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};








|







988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
		    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
};

1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
    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 const Ttk_ElementOptionSpec PbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(PbarElement,orientObj),
	"horizontal" },
    { "-thickness", TK_OPTION_PIXELS, offsetof(PbarElement,thicknessObj),
	DEFAULT_PBAR_THICKNESS },
    { "-barsize", TK_OPTION_PIXELS, offsetof(PbarElement,lengthObj),
	DEFAULT_PBAR_LENGTH },
    { "-pbarrelief", TK_OPTION_RELIEF, offsetof(PbarElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(PbarElement,borderWidthObj),
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(PbarElement,borderObj),
	DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PbarElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Ttk_Orient orient;
    int thickness = 15, length = 30, borderWidth = 2;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, pbar->borderObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    (void)dummy;
    (void)state;

    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 const 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 const Ttk_ElementOptionSpec TabElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TabElement,borderWidthObj),"1" },
    { "-background", TK_OPTION_BORDER,
	offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND },
    {0,TK_OPTION_BOOLEAN,0,0}
};

static void TabElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
    paddingPtr->bottom = 0;
}

static void TabElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    int borderWidth = 1;
    int cut = 2;
    XPoint pts[6];
    int n = 0;
    (void)dummy;

    Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);

    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.







|
|

|

|

|

|

|

|



|


|
<
|
<
<

|

















|


|


<
<









|
















|

|

|
|



|


|

<
<
<
<






|


|





<







1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044

1045


1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070


1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110




1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
    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.
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
    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 const 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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ClientElement *ce = (ClientElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 1;
    (void)dummy;
    (void)state;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ClientElement *ce = (ClientElement *)elementRecord;
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ClientElement),
    ClientElementOptions,
    ClientElementSize,
    ClientElementDraw
};








|



















|















|


|


<
<








|


|

<
<
<
<




|







1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189


1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202




1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
    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
};

1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
	    &RadiobuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    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",







|

|

|

|

|







1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
	    &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",
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381

    Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);

    /*
     * Register "default" as a user-loadable theme (for now):
     */
    Tcl_PkgProvideEx(interp, "ttk::theme::default", TTK_VERSION, NULL);
}

/*EOF*/







|



1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

    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*/

Changes to generic/ttk/ttkEntry.c.

1
2
3
4
5
6
7
8
9
10
11




12
13
14
15
16
17
18
/*
 * 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 "tkInt.h"




#include "ttkTheme.h"
#include "ttkWidget.h"

/*
 * Extra bits for core.flags:
 */
#define GOT_SELECTION		(WIDGET_USER_FLAG<<1)










|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 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)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 * displayString points to string if showChar == NULL,
 * or to malloc'ed storage if showChar != NULL.
 */

/* Style parameters:
 */
typedef struct {
    Tcl_Obj *placeholderForegroundObj;/* Foreground color for placeholder text */
    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) */
    TkSizeT numBytes;		/* Length of string in bytes. */
    TkSizeT numChars;		/* Length of string in characters. */

    TkSizeT insertPos;		/* Insert index */
    TkSizeT selectFirst;		/* Index of start of selection, or TCL_INDEX_NONE */
    TkSizeT selectLast;		/* Index of end of selection, or TCL_INDEX_NONE */

    Scrollable xscroll;		/* Current scroll position */
    ScrollHandle xscrollHandle;

    /*
     * Options managed by Tk_SetOptions:
     */







<














|
|

|
|
|







69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
 * 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:
     */
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    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 */

    Tcl_Obj *placeholderObj;	/* Text to display for placeholder text */

    /*
     * Derived resources:
     */
    Ttk_TraceHandle *textVariableTrace;

    char *displayString;	/* String to use when displaying */
    Tk_TextLayout textLayout;	/* Cached text layout information. */







<
<







114
115
116
117
118
119
120


121
122
123
124
125
126
127
    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. */
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#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_PLACEHOLDER_FG	"#b3b3b3"
#define DEF_INSERT_BG		"black"
#define DEF_ENTRY_WIDTH		"20"
#define DEF_ENTRY_FONT		"TkTextFont"
#define DEF_LIST_HEIGHT		"10"

static const Tk_OptionSpec EntryOptionSpecs[] = {
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
        "ExportSelection", "1", TCL_INDEX_NONE, offsetof(Entry, entry.exportSelection),
	0,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, offsetof(Entry, entry.fontObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", TCL_INDEX_NONE, offsetof(Entry, entry.justify),
	0, 0, GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	NULL, offsetof(Entry, entry.placeholderObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
        NULL, TCL_INDEX_NONE, offsetof(Entry, entry.showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Entry, entry.stateObj), TCL_INDEX_NONE,
        0,0,STATE_CHANGED},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	NULL, offsetof(Entry, entry.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,TEXTVAR_CHANGED},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	"none", TCL_INDEX_NONE, offsetof(Entry, entry.validate),
	0, (void *) validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.validateCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, offsetof(Entry, entry.widthObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.xscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},

    /* EntryStyleData options:
     */
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
	NULL, offsetof(Entry, entry.styleData.backgroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(Entry, entry.styleData.foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", NULL,
        offsetof(Entry, entry.styleData.placeholderForegroundObj), TCL_INDEX_NONE,
	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(placeholderForegroundObj, DEF_PLACEHOLDER_FG)
    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->placeholderForegroundObj);
    Tcl_DecrRefCount(es->foregroundObj);
    Tcl_DecrRefCount(es->selBorderObj);
    Tcl_DecrRefCount(es->selForegroundObj);
    Tcl_DecrRefCount(es->insertColorObj);
    Tcl_DecrRefCount(es->selBorderWidthObj);
    Tcl_DecrRefCount(es->insertWidthObj);
}







|
|
<
|
|
|
|

|

|


|


|


|

<
<
<

|


|


|


|
|

|


|


|




<
<
<

|

|
<
|




















<











<







143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193



194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
#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);
}
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377



378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    /* 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(placeholderForegroundObj, "-placeholderforeground");
    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->placeholderForegroundObj = Ttk_UseColor(cache, tkwin, es->placeholderForegroundObj);
    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;
    int ch;
    char buf[6];

    TkUtfToUniChar(showChar, &ch);
    size = TkUniCharToUtf(ch, buf);
    p = displayString = (char *)ckalloc(numChars * size + 1);

    while (numChars--) {
	memcpy(p, buf, size);
	p += size;
    }
    *p = '\0';

    return displayString;
}

/* EntryUpdateTextLayout --
 * 	Recompute textLayout, layoutWidth, and layoutHeight
 * 	from displayString and fontObj.
 */
static void EntryUpdateTextLayout(Entry *entryPtr)
{
    TkSizeT length;
    char *text;
    Tk_FreeTextLayout(entryPtr->entry.textLayout);
    if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) {
        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);
    } else {
        text = TkGetStringFromObj(entryPtr->entry.placeholderObj, &length);
        entryPtr->entry.textLayout = Tk_ComputeTextLayout(
	    Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
	    text, length,
	    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 TkSizeT
EntryFetchSelection(
    ClientData clientData, TkSizeT offset, char *buffer, TkSizeT maxBytes)
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if (entryPtr->entry.selectFirst == TCL_INDEX_NONE || (!entryPtr->entry.exportSelection)
	    || Tcl_IsSafe(entryPtr->core.interp)) {
	return TCL_INDEX_NONE;
    }
    string = entryPtr->entry.displayString;

    selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->entry.selectLast - entryPtr->entry.selectFirst);
    if (selEnd  <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
    /* @@@POSSIBLE BUG: Can transfer partial UTF-8 sequences.  Is this OK? */
	byteCount = maxBytes;



    }
    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 = TCL_INDEX_NONE;
    TtkRedisplayWidget(&entryPtr->core);
}

/* EntryOwnSelection --
 * 	Assert ownership of the PRIMARY selection,
 * 	if -exportselection set and selection is present and interp is unsafe.
 */
static void EntryOwnSelection(Entry *entryPtr)
{
    if (entryPtr->entry.exportSelection
	&& (!Tcl_IsSafe(entryPtr->core.interp))
	&& !(entryPtr->core.flags & GOT_SELECTION)) {
	Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection,
		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 *templ, 	/* Script template */
     const char *newValue,		/* Potential new value of entry string */
     TkSizeT 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;
    int ch;
    char numStorage[2*TCL_INTEGER_SPACE];

    while (*templ) {
	/* Find everything up to the next % character and append it
	 * to the result string.
	 */
	string = Tcl_UtfFindFirst(templ, '%');
	if (string == NULL) {
	    /* No more %-sequences to expand.
	     * Copy the rest of the template.
	     */
	    Tcl_DStringAppend(dsPtr, templ, -1);
	    return;
	}
	if (string != templ) {
	    Tcl_DStringAppend(dsPtr, templ, string - templ);
	    templ = string;
	}

	/* There's a percent sequence here.  Process it.
	 */
	++templ; /* skip over % */
	if (*templ != '\0') {
	    templ += TkUtfToUniChar(templ, &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", (int)index);
		string = numStorage;
		break;
	    case 'P': /* 'Peeked' new value of the string */
		string = newValue;
		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(newValue, 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 = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	}

	spaceNeeded = Tcl_ScanCountedElement(string, stringLength, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);







<










<



















|
|

|
|
|


<
|












<
<

<
|




<
<
<
<
<
<
<
<


















|

|

|
|



|
<
|






<
<
<




>
>
>












|

|





|




<


|















|
|
|








|


|



|




|


|
|
|




|
|
|


















|



|






|



















|







249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305


306

307
308
309
310
311








312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    /* 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;
    int 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 > 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);
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
 * 	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 *templ,	/* Script template */
    const char *optionName,	/* "-validatecommand", "-invalidcommand" */
    const char *newValue,	/* Potential new value of entry string */
    TkSizeT index,			/* index of insert/delete */
    TkSizeT count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_DString script;
    int code;

    Tcl_DStringInit(&script);
    ExpandPercents(entryPtr, templ, newValue, 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;








|

|
|
|






|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
 * 	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;

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
/* 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 occurred
 *
 * 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 */
    TkSizeT index,			/* index of insert/delete, TCL_INDEX_NONE otherwise */
    TkSizeT 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:







|








|
|






|

|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
/* 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:
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
/* 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 *dummy, Entry *entryPtr, VREASON reason)
{
    int code = EntryValidateChange(
		    entryPtr, entryPtr->entry.string, -1,0, reason);
    (void)dummy;

    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;
    VMODE vmode = entryPtr->entry.validate;

    if (EntryNeedsValidation(vmode, reason)) {
        if (EntryRevalidate(interp, entryPtr, reason) == TCL_ERROR) {
	    Tcl_BackgroundException(interp, TCL_ERROR);
        }
    }
}

/*------------------------------------------------------------------------
 * +++ Entry widget modification.
 */








|



<
















<
<
<
|
|
<







627
628
629
630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653



654
655

656
657
658
659
660
661
662
/* 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.
 */

716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
    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 + 1 <= e->selectFirst + 1)
	e->selectFirst = e->selectLast = TCL_INDEX_NONE;
}

/* 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);
    TkSizeT 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 = (char *)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)







|
|












|

















|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    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)
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
    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_SetVar2(entryPtr->core.interp, textVarName,
		    NULL, 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 = (Entry *)recordPtr;

    if (WidgetDestroyed(&entryPtr->core)) {
	return;
    }

    if (entryPtr->core.flags & SYNCING_VARIABLE) {
	/* Trace was fired due to Tcl_SetVar2 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. */
    TkSizeT 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 *newBytes;
    int code;

    if (byteCount == 0) {
	return TCL_OK;
    }

    newBytes =  (char *)ckalloc(newByteCount);
    memcpy(newBytes, string, byteIndex);
    strcpy(newBytes + byteIndex, value);
    strcpy(newBytes + byteIndex + byteCount, string + byteIndex);

    code = EntryValidateChange(
	    entryPtr, newBytes, index, charsAdded, VALIDATE_INSERT);

    if (code == TCL_OK) {
	AdjustIndices(entryPtr, index, charsAdded);
	code = EntrySetValue(entryPtr, newBytes);
    } else if (code == TCL_BREAK) {
	code = TCL_OK;
    }

    ckfree(newBytes);
    return code;
}

/* DeleteChars --
 *	Remove one or more characters from an entry widget.
 */
static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    TkSizeT index,			/* Index of first character to delete. */
    TkSizeT count)			/* How many characters to delete. */
{
    char *string = entryPtr->entry.string;
    size_t byteIndex, byteCount, newByteCount;
    char *newBytes;
    int code;

    if (index == TCL_INDEX_NONE) {
	index = 0;
    }
    if (count + index + 1 > entryPtr->entry.numChars + 1) {
	count = entryPtr->entry.numChars - index;
    }
    if (count + 1 <= 1) {
	return TCL_OK;
    }

    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string+byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->entry.numBytes + 1 - byteCount;
    newBytes =  (char *)ckalloc(newByteCount);
    memcpy(newBytes, string, byteIndex);
    strcpy(newBytes + byteIndex, string + byteIndex + byteCount);

    code = EntryValidateChange(
	    entryPtr, newBytes, index, count, VALIDATE_DELETE);

    if (code == TCL_OK) {
	AdjustIndices(entryPtr, index, -count);
	code = EntrySetValue(entryPtr, newBytes);
    } else if (code == TCL_BREAK) {
	code = TCL_OK;
    }
    ckfree(newBytes);

    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;







|
|



















|






|


















|







|






|
|
|
|


|



|




|









|
|



|


|


|


|







|
|
|


|



|



|
















|







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
    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;
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup.
 */

static void
EntryInitialize(Tcl_Interp *dummy, void *recordPtr)
{
    Entry *entryPtr = (Entry *)recordPtr;
    (void)dummy;

    Tk_CreateEventHandler(
	entryPtr->core.tkwin, EntryEventMask, EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING,
	EntryFetchSelection, entryPtr, XA_STRING);
    TtkBlinkCursor(&entryPtr->core);

    entryPtr->entry.string		= (char *)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 	= TCL_INDEX_NONE;
    entryPtr->entry.selectLast		= TCL_INDEX_NONE;
}

static void
EntryCleanup(void *recordPtr)
{
    Entry *entryPtr = (Entry *)recordPtr;

    if (entryPtr->entry.textVariableTrace)
	Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);

    TtkFreeScrollHandle(entryPtr->entry.xscrollHandle);

    EntryFreeStyleDefaults(&entryPtr->entry.styleDefaults);







|

|
<




|


|











|
|





|







916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
}

/*------------------------------------------------------------------------
 * +++ 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);
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
}

/* EntryConfigure --
 * 	Configure hook for Entry widgets.
 */
static int EntryConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Entry *entryPtr = (Entry *)recordPtr;
    Tcl_Obj *textVarName = entryPtr->entry.textVariableObj;
    Ttk_TraceHandle *vt = 0;

    if (mask & TEXTVAR_CHANGED) {
	if (textVarName && *Tcl_GetString(textVarName) != '\0') {
	    vt = Ttk_TraceVariable(interp,
		    textVarName,EntryTextVariableTrace,entryPtr);
	    if (!vt) return TCL_ERROR;
	}
    }

    if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {







|




|







967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
}

/* 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) {
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
	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 != TCL_INDEX_NONE)
	    && (!Tcl_IsSafe(entryPtr->core.interp))) {
	EntryOwnSelection(entryPtr);
    }

    /* Handle -state compatibility option:
     */
    if (mask & STATE_CHANGED) {
	TtkCheckStateOption(&entryPtr->core, entryPtr->entry.stateObj);







|
<







994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
	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);
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
    EntryUpdateTextLayout(entryPtr);
    return TCL_OK;
}

/* EntryPostConfigure --
 * 	Post-configuration hook for entry widgets.
 */
static int EntryPostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)
{
    Entry *entryPtr = (Entry *)recordPtr;
    int status = TCL_OK;
    (void)dummy;

    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, TkSizeT 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 = (Entry *)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));







|

|

<

















|



















|







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
    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));
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
}

/* EntryDisplay --
 *	Redraws the contents of an entry window.
 */
static void EntryDisplay(void *clientData, Drawable d)
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->core.tkwin;
    TkSizeT 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;
    Tcl_Obj *foregroundObj;

    EntryInitStyleData(entryPtr, &es);

    textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea");
    showCursor =
	   (entryPtr->core.flags & CURSOR_ON)
	&& EntryEditable(entryPtr)
	&& entryPtr->entry.insertPos + 1 >= leftIndex + 1
	&& entryPtr->entry.insertPos + 1 <= rightIndex + 1
	;
    showSelection =
	   !(entryPtr->core.state & TTK_STATE_DISABLED)
	&& selFirst != TCL_INDEX_NONE
	&& selLast + 1 > leftIndex + 1
	&& selFirst + 1 <= rightIndex + 1;


    /* Adjust selection range to keep in display bounds.
     */
    if (showSelection) {
	if (selFirst + 1 < leftIndex + 1)
	    selFirst = leftIndex;
	if (selLast + 1 > rightIndex + 1)
	    selLast = rightIndex;
    }

    /* Draw widget background & border
     */
    Ttk_DrawLayout(entryPtr->core.layout, entryPtr->core.state, d);








|

|









<





|

|
|


|
|
|
|
>




|

|







1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
}

/* 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);

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
#ifdef HAVE_XFT
    TkUnixSetXftClipRegion(clipRegion);
#endif

    /* Draw cursor:
     */
    if (showCursor) {
        Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field");
	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);

	cursorX -= cursorWidth/2;
	if (cursorX < field.x) {
	    cursorX = field.x;
	} else if (cursorX + cursorWidth > field.x + field.width) {
	    cursorX = field.x + field.width - cursorWidth;
	}

	gc = EntryGetGC(entryPtr, es.insertColorObj, NULL);
	XFillRectangle(Tk_Display(tkwin), d, gc,
	    cursorX, cursorY, cursorWidth, cursorHeight);

	Tk_FreeGC(Tk_Display(tkwin), gc);
    }

    /* Draw the text:
     */
    if ((*(entryPtr->entry.displayString) == '\0')
		&& (entryPtr->entry.placeholderObj != NULL)) {
	/* No text displayed, but -placeholder is given */
	if (Tcl_GetCharLength(es.placeholderForegroundObj) > 0) {
	    foregroundObj = es.placeholderForegroundObj;
	} else {
            foregroundObj = es.foregroundObj;
	}
	/* Use placeholder text width */
	leftIndex = 0;
	(void)TkGetStringFromObj(entryPtr->entry.placeholderObj, &rightIndex);
    } else {
	foregroundObj = es.foregroundObj;
    }
    gc = EntryGetGC(entryPtr, foregroundObj, clipRegion);
    if (showSelection) {

        /* Draw the selected and unselected portions separately.
	 */
	if (leftIndex < selFirst) {
	    Tk_DrawTextLayout(
		Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
		entryPtr->entry.layoutX, entryPtr->entry.layoutY,
		leftIndex, selFirst);
	}
	if (selLast < rightIndex) {
	    Tk_DrawTextLayout(
		Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
		entryPtr->entry.layoutX, entryPtr->entry.layoutY,
		selLast, rightIndex);
	}
	XSetClipMask(Tk_Display(tkwin), gc, None);
	Tk_FreeGC(Tk_Display(tkwin), gc);

	/* Draw the selected portion in the -selectforeground color:
	 */

	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);
    } else {

        /* Draw the entire visible text
         */
	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);
    }

    /* Drop the region. Note that we have to manually remove the reference to
     * it from the Xft guts (if they're being used).
     */







<













<
<
<
<
<
<
<
|

|
>





<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
|
|
|
<
<
<
<
<
<
<
|
|

|
|
>





<
<
<
<
<
<
<
<
<
<







1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255







1256
1257
1258
1259
1260
1261
1262
1263
1264














1265





1266
1267
1268
1269







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280










1281
1282
1283
1284
1285
1286
1287
#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).
     */
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
 *	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 */
    TkSizeT *indexPtr)		/* Return value */
{
#   define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
    TkSizeT length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars - 1, 1, &idx)) {
    	if ((idx != TCL_INDEX_NONE) && (idx > entryPtr->entry.numChars)) {
    	    idx = entryPtr->entry.numChars;
    	}
    	*indexPtr = idx;
    	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);

    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 == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->core.tkwin)));
	    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "NO_SELECTION", 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 {







|


|
|

|
<
|
<
<
<
<
<
<
<
|






|
|
|
|
<







1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320

1321







1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
 *	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 {
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456

1457






1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
	if (x > maxWidth) {
	    x = maxWidth;
	    roundUp = 1;
	}
	*indexPtr = Tk_PointToChar(entryPtr->entry.textLayout,
		x - entryPtr->entry.layoutX, 0);

        TtkUpdateScrollInfo(entryPtr->entry.xscrollHandle);
	if (*indexPtr + 1 < (TkSizeT)entryPtr->entry.xscroll.first + 1) {
	    *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 && ((TkSizeT)*indexPtr + 1 < entryPtr->entry.numChars + 1 )) {
	    *indexPtr += 1;
	}
    } else {

	goto badIndex;






    }
    return TCL_OK;

badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "INDEX", 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 = (Entry *)recordPtr;
    Ttk_Box b;
    TkSizeT 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 + 1 > 1)) {
	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 = (Entry *)recordPtr;
    TkSizeT 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 + 1 >= first + 1 && 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 = (Entry *)recordPtr;
    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->entry.string, -1));
    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 = (Entry *)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 = (Entry *)recordPtr;
    TkSizeT 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, TkNewIndexObj(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 = (Entry *)recordPtr;
    TkSizeT 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 = (Entry *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    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 = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewWideIntObj(entryPtr->entry.selectFirst != TCL_INDEX_NONE));
    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 = (Entry *)recordPtr;
    TkSizeT 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 + 1 >= end + 1 ) {
	entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    } else {
	entryPtr->entry.selectFirst = start;
	entryPtr->entry.selectLast = end;
	EntryOwnSelection(entryPtr);
    }
    TtkRedisplayWidget(&entryPtr->core);
    return TCL_OK;







<
|










|



>
|
>
>
>
>
>
>




|
|
<










|

|








|


















|
|














|












|




|










|



















|
|








|











|
|




















|





|










|





|









|
|




|







|
|







1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
	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;
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708

/* $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 = (Entry *)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 = (Entry *)recordPtr;
    int code;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;
    }








|















|







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629

/* $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;
    }

1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
}

/* $entry xview	-- horizontal scrolling interface
 */
static int EntryXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc == 3) {
	TkSizeT newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
}

static const Ttk_Ensemble EntryCommands[] = {
    { "bbox", 		EntryBBoxCommand,0 },







|

|



|







1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
}

/* $entry xview	-- horizontal scrolling interface
 */
static int EntryXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = recordPtr;
    if (objc == 3) {
	int newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
}

static const Ttk_Ensemble EntryCommands[] = {
    { "bbox", 		EntryBBoxCommand,0 },
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Entry widget definition.
 */

static const WidgetSpec EntryWidgetSpec = {
    "TEntry",			/* className */
    sizeof(Entry), 		/* recordSize */
    EntryOptionSpecs, 		/* optionSpecs */
    EntryCommands,  		/* subcommands */
    EntryInitialize,     	/* initializeProc */
    EntryCleanup,		/* cleanupProc */
    EntryConfigure,		/* configureProc */







|







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Entry widget definition.
 */

static WidgetSpec EntryWidgetSpec = {
    "TEntry",			/* className */
    sizeof(Entry), 		/* recordSize */
    EntryOptionSpecs, 		/* optionSpecs */
    EntryCommands,  		/* subcommands */
    EntryInitialize,     	/* initializeProc */
    EntryCleanup,		/* cleanupProc */
    EntryConfigure,		/* configureProc */
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
 * +++ Combobox widget record.
 */

typedef struct {
    Tcl_Obj	*postCommandObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*heightObj;
    TkSizeT	currentIndex;
} ComboboxPart;

typedef struct {
    WidgetCore core;
    EntryPart entry;
    ComboboxPart combobox;
} Combobox;

static const Tk_OptionSpec ComboboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-height", "height", "Height",
        DEF_LIST_HEIGHT, offsetof(Combobox, combobox.heightObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-postcommand", "postCommand", "PostCommand",
        "", offsetof(Combobox, combobox.postCommandObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Combobox, combobox.valuesObj), TCL_INDEX_NONE,
	0,0,0 },
    WIDGET_INHERIT_OPTIONS(EntryOptionSpecs)
};

/* ComboboxInitialize --
 * 	Initialization hook for combobox widgets.
 */
static void
ComboboxInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Combobox *cb = (Combobox *)recordPtr;

    cb->combobox.currentIndex = TCL_INDEX_NONE;
    TtkTrackElementState(&cb->core);
    EntryInitialize(interp, recordPtr);
}

/* ComboboxConfigure --
 * 	Configuration hook for combobox widgets.
 */
static int
ComboboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Combobox *cbPtr = (Combobox *)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 = (Combobox *)recordPtr;
    TkSizeT 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 == TCL_INDEX_NONE
	     || currentIndex >= (TkSizeT)nValues
	     || strcmp(currentValue,Tcl_GetString(values[currentIndex]))
	   )
	{
	    /* Not valid.  Check current value against each element in -values:
	     */
	    for (currentIndex = 0; currentIndex < (TkSizeT)nValues; ++currentIndex) {
		if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
		    break;
		}
	    }
	    if (currentIndex >= (TkSizeT)nValues) {
		/* Not found */
		currentIndex = TCL_INDEX_NONE;
	    }
	}
	cbPtr->combobox.currentIndex = currentIndex;
	Tcl_SetObjResult(interp, TkNewIndexObj(currentIndex));
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT idx;

	if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) {
	    if (idx == TCL_INDEX_NONE || idx > (TkSizeT)nValues) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "index \"%s\" out of range", Tcl_GetString(objv[2])));
	        Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_RANGE", NULL);
	        return TCL_ERROR;
	    }
	    currentIndex = idx;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Incorrect index %s", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_VALUE", NULL);
	    return TCL_ERROR;
	}

	cbPtr->combobox.currentIndex = currentIndex;

	return EntrySetValue((Entry *)recordPtr, Tcl_GetString(values[currentIndex]));
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "?newIndex?");
	return TCL_ERROR;
    }
    return TCL_OK;
}








|








|

|


|


|










|

|










|



















|
|




|




|
|





|




|

|



|


<
|
<
<
<
<
<
|
|
|
<
|
|
|





|







1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793

1794





1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
 * +++ 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;
}

1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ComboboxWidgetSpec = {
    "TCombobox",		/* className */
    sizeof(Combobox), 		/* recordSize */
    ComboboxOptionSpecs,	/* optionSpecs */
    ComboboxCommands,  		/* subcommands */
    ComboboxInitialize,     	/* initializeProc */
    EntryCleanup,		/* cleanupProc */
    ComboboxConfigure,		/* configureProc */







|







1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
    { "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 */
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012

typedef struct {
    WidgetCore core;
    EntryPart entry;
    SpinboxPart spinbox;
} Spinbox;

static const Tk_OptionSpec SpinboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Spinbox, spinbox.valuesObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_DOUBLE, "-from", "from", "From",
	"0", offsetof(Spinbox,spinbox.fromObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	"0", offsetof(Spinbox,spinbox.toObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	"1", offsetof(Spinbox,spinbox.incrementObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-format", "format", "Format",
	"", offsetof(Spinbox, spinbox.formatObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Spinbox, spinbox.commandObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	"0", offsetof(Spinbox,spinbox.wrapObj), TCL_INDEX_NONE,
	0,0,0 },

    WIDGET_INHERIT_OPTIONS(EntryOptionSpecs)
};

/* SpinboxInitialize --
 * 	Initialization hook for spinbox widgets.
 */
static void
SpinboxInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Spinbox *sb = (Spinbox *)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 = (Spinbox *)recordPtr;
    int unused;

    /* Make sure -values is a valid list:
     */
    if (Tcl_ListObjLength(interp,sb->spinbox.valuesObj,&unused) != TCL_OK)
	return TCL_ERROR;








|

|



|


|


|


|



|


|











|










|







1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926

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;

2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SpinboxWidgetSpec = {
    "TSpinbox",			/* className */
    sizeof(Spinbox), 		/* recordSize */
    SpinboxOptionSpecs,		/* optionSpecs */
    SpinboxCommands,  		/* subcommands */
    SpinboxInitialize,     	/* initializeProc */
    EntryCleanup,		/* cleanupProc */
    SpinboxConfigure,		/* configureProc */







|







1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
    { "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 */
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
 */

typedef struct {
    Tcl_Obj	*fontObj;
    Tcl_Obj	*widthObj;
} TextareaElement;

static const Ttk_ElementOptionSpec TextareaElementOptions[] = {
    { "-font", TK_OPTION_FONT,
	offsetof(TextareaElement,fontObj), DEF_ENTRY_FONT },
    { "-width", TK_OPTION_INT,
	offsetof(TextareaElement,widthObj), "20" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TextareaElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextareaElement *textarea = (TextareaElement *)elementRecord;
    Tk_Font font = Tk_GetFontFromObj(tkwin, textarea->fontObj);
    int avgWidth = Tk_TextWidth(font, "0", 1);
    Tk_FontMetrics fm;
    int prefWidth = 1;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetFontMetrics(font, &fm);
    Tcl_GetIntFromObj(NULL, textarea->widthObj, &prefWidth);
    if (prefWidth <= 0)
	prefWidth = 1;

    *heightPtr = fm.linespace;
    *widthPtr = prefWidth * avgWidth;
}

static const 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_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)







|

|

|
|



|


|




<
<










|




















|







1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992


1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
 */

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)

Changes to generic/ttk/ttkFrame.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::frame and ttk::labelframe widgets.
 */

#include "tkInt.h"

#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"

/* ======================================================================
 * +++ Frame widget:
 */






|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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:
 */
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
} FramePart;

typedef struct {
    WidgetCore	core;
    FramePart	frame;
} Frame;

static const Tk_OptionSpec FrameOptionSpecs[] = {
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", NULL,
	offsetof(Frame,frame.borderWidthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
	offsetof(Frame,frame.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
	offsetof(Frame,frame.reliefObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
	offsetof(Frame,frame.widthObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
	offsetof(Frame,frame.heightObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble FrameCommands[] = {







|

|


|


|


|


|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
} 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[] = {
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    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,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Frame *framePtr = (Frame *)recordPtr;
    Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
    return 0;
}

/*







|
<
<
<







85
86
87
88
89
90
91
92



93
94
95
96
97
98
99
    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 = (Frame *)recordPtr;
    Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
    return 0;
}

/*
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    if ((width > 0 || height > 0) && (mask & GEOMETRY_CHANGED)) {
	Tk_GeometryRequest(framePtr->core.tkwin, width, height);
    }

    return TtkCoreConfigure(interp, recordPtr, mask);
}

static const WidgetSpec FrameWidgetSpec = {
    "TFrame",			/* className */
    sizeof(Frame),		/* recordSize */
    FrameOptionSpecs,		/* optionSpecs */
    FrameCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */
    FrameConfigure,		/* configureProc */







|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    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 */
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
    }

    *anchorPtr = flags;
    return TCL_OK;

error:
    if (interp) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Bad label anchor specification %s", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "LABEL", "ANCHOR", NULL);
    }
    return TCL_ERROR;
}

/* LabelAnchorSide --
 * 	Returns the side corresponding to a LabelAnchor value.
 */







>
|
|
|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    }

    *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.
 */
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    WidgetCore  	core;
    FramePart   	frame;
    LabelframePart	label;
} Labelframe;

#define LABELWIDGET_CHANGED 0x100

static const Tk_OptionSpec LabelframeOptionSpecs[] = {
    {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
	"nw", offsetof(Labelframe, label.labelAnchorObj),TCL_INDEX_NONE,
        0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Labelframe,label.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Labelframe,label.underlineObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
	TCL_INDEX_NONE, offsetof(Labelframe,label.labelWidget),
	TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },

    WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
};

/*
 * Labelframe style parameters:







|

|


|


|


|







245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    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:
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
}

/*
 * 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,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Labelframe *lframePtr = (Labelframe *)recordPtr;
    WidgetCore *corePtr = &lframePtr->core;
    Ttk_Padding margins;
    LabelframeStyle style;
    int labelWidth, labelHeight;








|
<
<
<







335
336
337
338
339
340
341
342



343
344
345
346
347
348
349
}

/*
 * 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 = (Labelframe *)recordPtr;
    WidgetCore *corePtr = &lframePtr->core;
    Ttk_Padding margins;
    LabelframeStyle style;
    int labelWidth, labelHeight;

457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
     * 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 LabelframePlaceContent GM hook */
    lframePtr->label.labelParcel = labelParcel;
}

static void LabelframeDisplay(void *recordPtr, Drawable d)
{
    Labelframe *lframePtr = (Labelframe *)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.
 */

/* LabelframePlaceContent --
 * 	Sets the position and size of the labelwidget.
 */
static void LabelframePlaceContent(void *recordPtr)
{
    Labelframe *lframe = (Labelframe *)recordPtr;

    if (Ttk_NumberContent(lframe->label.mgr) == 1) {
	Ttk_Box b;
	LabelframeDoLayout(recordPtr);
	b = lframe->label.labelParcel;
	/* ASSERT: content #0 is lframe->label.labelWidget */
	Ttk_PlaceContent(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
    }
}

static int LabelRequest(
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    return 1;
}

/* LabelRemoved --
 * 	Unset the -labelwidget option.
 *
 * <<NOTE-LABELREMOVED>>:
 * 	This routine is also called when the widget voluntarily forgets
 * 	the window in LabelframeConfigure.
 */
static void LabelRemoved(
    void *managerData,
    TCL_UNUSED(TkSizeT))
{
    Labelframe *lframe = (Labelframe *)managerData;

    lframe->label.labelWidget = 0;
}

static Ttk_ManagerSpec LabelframeManagerSpec = {
    { "labelframe", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    LabelframeSize,
    LabelframePlaceContent,
    LabelRequest,
    LabelRemoved
};

/* LabelframeInitialize --
 * 	Initialization hook.
 */
static void LabelframeInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Labelframe *lframe = (Labelframe *)recordPtr;

    lframe->label.mgr = Ttk_CreateManager(
	&LabelframeManagerSpec, lframe, lframe->core.tkwin);
    lframe->label.labelWidget = 0;
    lframe->label.labelLayout = 0;







|















|


|



|



|
|



|
<
<
<
<









|

|
<
<

|
<




|

|







|
<
<







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492




493
494
495
496
497
498
499
500
501
502
503
504


505
506

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521


522
523
524
525
526
527
528
     * 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 = (Labelframe *)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 = (Labelframe *)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 = (Labelframe *)recordPtr;

    lframe->label.mgr = Ttk_CreateManager(
	&LabelframeManagerSpec, lframe, lframe->core.tkwin);
    lframe->label.labelWidget = 0;
    lframe->label.labelLayout = 0;
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    if (FrameConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }

    /* Update -labelwidget changes, if any:
     */
    if (mask & LABELWIDGET_CHANGED) {
	if (Ttk_NumberContent(lframePtr->label.mgr) == 1) {
	    Ttk_ForgetContent(lframePtr->label.mgr, 0);
	    /* Restore labelWidget field (see <<NOTE-LABELREMOVED>>)
	     */
	    lframePtr->label.labelWidget = labelWidget;
	}

	if (labelWidget) {
		Ttk_InsertContent(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 const WidgetSpec LabelframeWidgetSpec = {
    "TLabelframe",		/* className */
    sizeof(Labelframe),		/* recordSize */
    LabelframeOptionSpecs, 	/* optionSpecs */
    FrameCommands,		/* subcommands */
    LabelframeInitialize,	/* initializeProc */
    LabelframeCleanup,		/* cleanupProc */
    LabelframeConfigure,	/* configureProc */







|
|






|












|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
    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 */

Added generic/ttk/ttkGenStubs.tcl.















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
# 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
#

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::export --
#
#	This function is used in the declarations file to declare a symbol
#	that is exported from the library but is not in the stubs table.
#
# Arguments:
#	decl		The C function declaration, or {} for an undefined
#			entry.
#
# Results:
#	None.

proc genStubs::export {args} {
    if {[llength $args] != 1} {
	puts stderr "wrong # args: export $args"
    }
    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"

    append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\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 "extern const ${capName}Stubs *${name}StubsPtr;\n\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

Changes to generic/ttk/ttkImage.c.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 *	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 "tkInt.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 */
    Tk_ImageChangedProc *imageChanged;
    ClientData		imageChangedClientData;
};

/* NullImageChanged --
 * 	Do-nothing Tk_ImageChangedProc.
 */
static void NullImageChanged(ClientData dummy,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */
    (void)dummy;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;
}

/* ImageSpecImageChanged --
 *     Image changes should trigger a repaint.
 */
static void ImageSpecImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{












>
|




















|

|
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








38
39
40
41
42
43
44
/*
 *	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 */
    Tk_ImageChangedProc *imageChanged;
    ClientData		imageChangedClientData;
};

/* NullImageChanged --
 * 	Do-nothing Tk_ImageChangedProc.
 */
static void NullImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */ }









/* ImageSpecImageChanged --
 *     Image changes should trigger a repaint.
 */
static void ImageSpecImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
	goto error;
    }

    if ((objc % 2) != 1) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image specification must contain an odd number of elements",
		-1));
	    Tcl_SetErrorCode(interp, "TTK", "IMAGE", "SPEC", NULL);
	}
	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]), ImageSpecImageChanged, imageSpec);
    if (!imageSpec->baseImage) {
    	goto error;







|

|
<





|
|







85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108

    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]), ImageSpecImageChanged, imageSpec);
    if (!imageSpec->baseImage) {
    	goto error;
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    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(imageSpec->states); }
    if (imageSpec->images) { ckfree(imageSpec->images); }

    ckfree(imageSpec);
}

/* TtkSelectImage --
 * 	Return a state-specific image from an ImageSpec
 */
Tk_Image TtkSelectImage(Ttk_ImageSpec *imageSpec, Ttk_State state)
{







|
|

|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    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)
{
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 */
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;
    (void)tkwin;

    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) {







<







201
202
203
204
205
206
207

208
209
210
211
212
213
214
 */
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) {
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    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 */

#ifdef 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 = (ImageData *)clientData;
    if (imageData->imageSpec)	{ TtkFreeImageSpec(imageData->imageSpec); }
#ifdef 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 = (ImageData *)clientData;
    Tk_Image image = imageData->imageSpec->baseImage;
    (void)elementRecord;
    (void)tkwin;

    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 = (ImageData *)clientData;
    Tk_Image image = 0;
    int imgWidth, imgHeight;
    Ttk_Box src, dst;
    (void)elementRecord;

#ifdef 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) {







|







|

|









|

<
<


















|



<

|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
    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) {
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
    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 const Ttk_ElementSpec ImageElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ImageElementSize,
    ImageElementDraw
};

/*------------------------------------------------------------------------
 * +++ Image element factory.
 */
static int
Ttk_CreateImageElement(
    Tcl_Interp *interp,
    void *dummy,
    Ttk_Theme theme,
    const char *elementName,
    int objc, Tcl_Obj *const objv[])
{
    static const char *const 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;
    (void)dummy;

    if (objc <= 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Must supply a base image", -1));
	Tcl_SetErrorCode(interp, "TTK", "IMAGE", "BASE", 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);
#ifdef 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_SetObjResult(interp, Tcl_ObjPrintf(
		    "Value for %s missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TTK", "IMAGE", "VALUE", NULL);
	    goto error;
	}

#ifdef TILE_07_COMPAT
	if (!strcmp("-map", Tcl_GetString(objv[i]))) {
	    imageData->imageMap = objv[i+1];
	    Tcl_IncrRefCount(imageData->imageMap);
	    continue;
	}
#endif

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *), "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; }







|














|




|







<


<
|
<








|




|








|
|
|



|







|
|
<
<




|
<
<







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356

357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395


396
397
398
399
400


401
402
403
404
405
406
407
    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; }

Changes to generic/ttk/ttkInit.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125






















126
127
128
129
130
131
132
/*
 * Copyright (c) 2003, Joe English
 *
 * Ttk package: initialization routine and miscellaneous utilities.
 */


#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*
 * Legal values for the button -default option.
 * See also: enum Ttk_ButtonDefaultState.
 */
const char *const ttkDefaultStrings[] = {
    "normal", "active", "disabled", NULL
};

int Ttk_GetButtonDefaultStateFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_ButtonDefaultState *statePtr)
{
    int state = (int)TTK_BUTTON_DEFAULT_DISABLED;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
	    sizeof(char *), "default state", 0, &state);

    *statePtr = (Ttk_ButtonDefaultState)state;
    return result;
}

/*
 * Legal values for the -compound option.
 * See also: enum Ttk_Compound.
 */
const char *const ttkCompoundStrings[] = {
    "none", "text", "image", "center",
    "top", "bottom", "left", "right", NULL
};

int Ttk_GetCompoundFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Compound *compoundPtr)
{
    int compound = (int)TTK_COMPOUND_NONE;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
	    sizeof(char *), "compound layout", 0, &compound);

    *compoundPtr = (Ttk_Compound)compound;
    return result;
}

/*
 * Legal values for the -orient option.
 * See also: enum Ttk_Orient.
 */
const char *const ttkOrientStrings[] = {
    "horizontal", "vertical", NULL
};

#if !defined(TK_NO_DEPRECATED) && TK_MAJOR_VERSION < 9
int Ttk_GetOrientFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
{
    *resultPtr = TTK_ORIENT_HORIZONTAL;
    return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
	    sizeof(char *), "orientation", 0, resultPtr);
}
#endif

int TtkGetOrientFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *resultPtr)
{
    int orient = (int)TTK_ORIENT_HORIZONTAL;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
    	    sizeof(char *), "orientation", 0, &orient);

    *resultPtr = (Ttk_Orient)orient;
    return result;
}

/*
 * Recognized values for the -state compatibility option.
 * Other options are accepted and interpreted as synonyms for "normal".
 */
static const char *const 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_GetIndexFromObjStruct(NULL, objPtr, ttkStateStrings,
	    sizeof(char *), "", 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
}























/* 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)






>
|







|




|

|
|
|
<
<
<






|





|

|
|
|
<
<
<






|



<




|
|
<
<
<
<
<
<
<
<
<
<
<
<






|


|






|


|
|









|
<

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42



43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58












59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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)
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	    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 = (const Tk_OptionSpec *)specPtr->clientData;
	}
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

int TtkGetOptionValue(







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
	    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(
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189


/*------------------------------------------------------------------------
 * Core Option specifications:
 * type name dbName dbClass default objOffset intOffset flags clientData mask
 */

/* public */
const Tk_OptionSpec ttkCoreOptionSpecs[] =
{
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL,
	offsetof(WidgetCore, cursorObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "-style", "style", "Style", "",
	offsetof(WidgetCore,styleObj), TCL_INDEX_NONE, 0,0,STYLE_CHANGED},
    {TK_OPTION_STRING, "-class", "", "", NULL,
	offsetof(WidgetCore,classObj), TCL_INDEX_NONE, 0,0,READONLY_OPTION},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*------------------------------------------------------------------------
 * +++ Initialization: elements and element factories.
 */








|
|


|

|

|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192


/*------------------------------------------------------------------------
 * 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.
 */

267
268
269
270
271
272
273
274
275
276
277
278
279

    RegisterElements(interp);
    RegisterWidgets(interp);
    RegisterThemes(interp);

    Ttk_PlatformInit(interp);

    Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);

    return TCL_OK;
}

/*EOF*/







|





270
271
272
273
274
275
276
277
278
279
280
281
282

    RegisterElements(interp);
    RegisterWidgets(interp);
    RegisterThemes(interp);

    Ttk_PlatformInit(interp);

    Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (ClientData)&ttkStubs);

    return TCL_OK;
}

/*EOF*/

Changes to generic/ttk/ttkLabel.c.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
/*
 * text, image, and label elements.
 *
 * The label element combines text and image elements,
 * with layout determined by the "-compound" option.
 *
 */

#include "tkInt.h"

#include "ttkTheme.h"

/*----------------------------------------------------------------------
 * +++ Text element.
 *
 * This element displays a textual label in the foreground color.
 *








|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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.
 *
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    int			embossed;

} TextElement;

/* Text element options table.
 * NB: Keep in sync with label element option table.
 */
static const Ttk_ElementOptionSpec TextElementOptions[] = {
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TextElement,foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(TextElement,underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(TextElement,widthObj), "-1"},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(TextElement,anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(TextElement,justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	offsetof(TextElement,wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	offsetof(TextElement,embossedObj), "0"},
    { NULL, TK_OPTION_BOOLEAN, 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;







|

|

|

|

|

|

|

|

|

|
|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    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;
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

    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:







|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

    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:
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
	TkDestroyRegion(clipRegion);
    }
    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}

static void TextElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *text = (TextElement *)elementRecord;
    (void)dummy;
    (void)paddingPtr;

    if (!TextSetup(text, tkwin))
	return;

    *heightPtr = text->height;
    *widthPtr = TextReqWidth(text);

    TextCleanup(text);

    return;
}

static void TextElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TextElement *text = (TextElement *)elementRecord;
    (void)dummy;
    (void)state;

    if (TextSetup(text, tkwin)) {
	TextDraw(text, tkwin, d, b);
	TextCleanup(text);
    }
}

static const Ttk_ElementSpec TextElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};








|


|
<
<













|


|
<
<
<






|







190
191
192
193
194
195
196
197
198
199
200


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217



218
219
220
221
222
223
224
225
226
227
228
229
230
231
	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
};

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    Tk_Image	tkimg;
    int 	width;
    int		height;
} ImageElement;

/* ===> NB: Keep in sync with label element option table.  <===
 */
static const Ttk_ElementOptionSpec ImageElementOptions[] = {
    { "-image", TK_OPTION_STRING,
	offsetof(ImageElement,imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	offsetof(ImageElement,stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	offsetof(ImageElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * ImageSetup() --
 * 	Look up the Tk_Image from the image element's imageObj resource.
 * 	Caller must release the image with ImageCleanup().
 *







|

|

|

|
|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    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().
 *
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
	/* 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 *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ImageElement *image = (ImageElement *)elementRecord;
    (void)dummy;
    (void)paddingPtr;

    if (ImageSetup(image, tkwin, 0)) {
	*widthPtr = image->width;
	*heightPtr = image->height;
	ImageCleanup(image);
    }
}

static void ImageElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    ImageElement *image = (ImageElement *)elementRecord;
    (void)dummy;

    if (ImageSetup(image, tkwin, state)) {
	ImageDraw(image, tkwin, d, b, state);
	ImageCleanup(image);
    }
}

static const Ttk_ElementSpec ImageElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ImageElement),
    ImageElementOptions,
    ImageElementSize,
    ImageElementDraw
};








|



|



|










|


|
<
<









|


|
<







|







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367


368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
	/* 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
};

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
     * Computed values (see LabelSetup)
     */
    Ttk_Compound	compound;
    int  		space;
    int 		totalWidth, totalHeight;
} LabelElement;

static const Ttk_ElementOptionSpec LabelElementOptions[] = {
    { "-compound", TK_OPTION_ANY,
	offsetof(LabelElement,compoundObj), "none" },
    { "-space", TK_OPTION_PIXELS,
	offsetof(LabelElement,spaceObj), "4" },

    /* Text element part:
     * NB: Keep in sync with TextElementOptions.
     */
    { "-text", TK_OPTION_STRING,
	offsetof(LabelElement,text.textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(LabelElement,text.fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(LabelElement,text.foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(LabelElement,text.underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(LabelElement,text.widthObj), ""},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(LabelElement,text.anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(LabelElement,text.justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	offsetof(LabelElement,text.wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	offsetof(LabelElement,text.embossedObj), "0"},

    /* Image element part:
     * NB: Keep in sync with ImageElementOptions.
     */
    { "-image", TK_OPTION_STRING,
	offsetof(LabelElement,image.imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	offsetof(LabelElement,image.stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	offsetof(LabelElement,image.backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * LabelSetup --
 * 	Fills in computed fields of the label element.
 *
 * 	Calculate the text, image, and total width and height.
 */

#undef  MAX
#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, compoundPtr);

    /*
     * Deal with TTK_COMPOUND_NONE.
     */
    if (c->compound == TTK_COMPOUND_NONE) {
	if (ImageSetup(&c->image, tkwin, state)) {
	    c->compound = TTK_COMPOUND_IMAGE;







|

|

|





|

|

|

|

|

|

|

|

|





|

|

|
|
















|
|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
     * 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.
 */

#undef  MAX
#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;
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    LabelElement *label = (LabelElement *)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,
	Ttk_Side imageSide, Ttk_Side 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(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    LabelElement *l = (LabelElement *)elementRecord;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;

    LabelSetup(l, tkwin, state);

    /*
     * Adjust overall parcel based on -anchor:
     */







<
|
<
|
<
<

|











|










|



|















|










<
|
<
|
<
<

|







558
559
560
561
562
563
564

565

566


567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621

622

623


624
625
626
627
628
629
630
631
632
    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:
     */
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_RIGHT, TTK_SIDE_LEFT);
	    break;
    }

    LabelCleanup(l);
}

static const Ttk_ElementSpec LabelElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(LabelElement),
    LabelElementOptions,
    LabelElementSize,
    LabelElementDraw
};








|







670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
	    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
};

Changes to generic/ttk/ttkLayout.c.

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
/*
 * ttkLayout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 */


#include "tkInt.h"
#include "ttkThemeInt.h"

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)

/*------------------------------------------------------------------------








>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * ttkLayout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 */

#include <string.h>
#include "tkInt.h"
#include "ttkThemeInt.h"

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)

/*------------------------------------------------------------------------
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
}

Tcl_Obj *
Ttk_NewBoxObj(Ttk_Box box)
{
    Tcl_Obj *result[4];

    result[0] = Tcl_NewWideIntObj(box.x);
    result[1] = Tcl_NewWideIntObj(box.y);
    result[2] = Tcl_NewWideIntObj(box.width);
    result[3] = Tcl_NewWideIntObj(box.height);

    return Tcl_NewListObj(4, result);
}

/*
 * packTop, packBottom, packLeft, packRight --
 * 	Carve out a parcel of the specified height (resp width)







|
|
|
|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
}

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)
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Wrong #elements in padding spec", -1));
	    Tcl_SetErrorCode(interp, "TTK", "VALUE", "PADDING", NULL);
	}
	goto error;
    }

    for (i=0; i < padc; ++i) {
	if (Tk_GetPixelsFromObj(interp, tkwin, padv[i], &pixels[i]) != TCL_OK) {
	    goto error;







|
|
<







322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337

    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;
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Wrong #elements in padding spec", -1));
	    Tcl_SetErrorCode(interp, "TTK", "VALUE", "BORDER", NULL);
	}
	goto error;
    }

    for (i=0; i < padc; ++i) {
	if (Tcl_GetIntFromObj(interp, padv[i], &pixels[i]) != TCL_OK) {
	    goto error;







|
|
<







359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374

    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;
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
	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_SetObjResult(interp, Tcl_ObjPrintf(
			"Bad -sticky specification %s",
			Tcl_GetString(objPtr)));
		    Tcl_SetErrorCode(interp, "TTK", "VALUE", "STICKY", NULL);
		}
		return TCL_ERROR;
	}
    }

    *result = sticky;
    return TCL_OK;







>
|
|
|
|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
	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;
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
    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(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 = (char *)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(op);
	op = next;
    }
}

/* InstantiateLayout --
 *	Create a layout tree from a template.
 */







|















|
















|
|











|







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
    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.
 */
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 *	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 *const 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 *const 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)







|





|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 *	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)
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
	while (i < objc) {
	    const char *optName = Tcl_GetString(objv[i]);
	    int option, value;

	    if (optName[0] != '-')
		break;

	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings,
		    sizeof(char *), "option", 0, &option)
		!= TCL_OK)
	    {
		goto error;
	    }

	    if (++i >= objc) {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Missing value for option %s",
			Tcl_GetString(objv[i-1])));
		Tcl_SetErrorCode(interp, "TTK", "VALUE", "LAYOUT", NULL);
		goto error;
	    }

	    switch (option) {
		case OP_SIDE:	/* <<NOTE-PACKSIDE>> */
		    if (Tcl_GetIndexFromObjStruct(interp, objv[i], packSideStrings,
				sizeof(char *), "side", 0, &value) != TCL_OK)
		    {
			goto error;
		    }
		    flags |= (TTK_PACK_LEFT << value);

		    break;
		case OP_STICKY:







|
|






>
|
|
<
|





|
|







631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
	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:
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
	    tail = tail->next;
	} else {
	    head = tail = Ttk_NewTemplateNode(elementName, flags | sticky);
	}
	if (childSpec) {
	    tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
	    if (!tail->child) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value"));
                Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL);
		goto error;
	    }
	}
    }

    return head;








<
<







697
698
699
700
701
702
703


704
705
706
707
708
709
710
	    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;

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
	    APPENDSTR("-expand");
	    APPENDSTR("1");
	} else {
	    if (flags & _TTK_MASK_PACK) {
		int side = 0;
		unsigned sideFlags = flags & _TTK_MASK_PACK;

		while (!(sideFlags & TTK_PACK_LEFT)) {
		    ++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? Can't see any effect! */
	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));
	}







|








<
|
|

<



|







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801

802
803
804

805
806
807
808
809
810
811
812
813
814
815
	    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));
	}
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
    layout->root = root;
    return layout;
}

void Ttk_FreeLayout(Ttk_Layout layout)
{
    Ttk_FreeLayoutNode(layout->root);
    ckfree(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.







|







847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
    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.
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
    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_SetObjResult(interp, Tcl_ObjPrintf(
		"Layout %s not found", styleName));
	Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", styleName, NULL);
	return 0;
    }

    bgnode = Ttk_NewLayoutNode(TTK_FILL_BOTH, bgelement);
    bgnode->next = Ttk_InstantiateLayout(themePtr, layoutTemplate);

    return TTKNewLayout(style, recordPtr, optionTable, tkwin, bgnode);







|
|
<







871
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
    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);
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
    Tcl_DStringAppend(&buf, baseName, -1);
    styleName = Tcl_DStringValue(&buf);

    style = Ttk_GetStyle(themePtr, styleName);
    layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName);

    if (!layoutTemplate) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Layout %s not found", styleName));
	Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", styleName, NULL);
	return 0;
    }

    Tcl_DStringFree(&buf);

    return TTKNewLayout(
	    style, 0, optionTable, parentLayout->tkwin,







|
|
<







911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
    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,

Changes to generic/ttk/ttkManager.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * Copyright 2005, Joe English.  Freely redistributable.
 *
 * Support routines for geometry managers.
 */


#include "tkInt.h"
#include "ttkManager.h"

/*------------------------------------------------------------------------
 * +++ The Geometry Propagation Dance.
 *
 * When a content window requests a new size or some other parameter changes,
 * the manager recomputes the required size for the container 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 container's manager will process the request
 * (and so on up the chain to the toplevel window), and the container
 * window will eventually receive a <Configure> event.  At this point
 * it recomputes the size and position of all content windows and places them.
 *
 * If all does not go well, however, the container'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.
 *
 * +++ Content window removal <<NOTE-LOSTCONTENT>>.
 *
 * There are three conditions under which a content window is removed:
 *
 * (1) Another GM claims control
 * (2) Manager voluntarily relinquishes control
 * (3) Content window is destroyed
 *
 * In case (1), Tk calls the manager's lostContentProc.
 * Case (2) is performed by calling Tk_ManageGeometry(window,NULL,0);
 * in this case Tk does _not_ call the lostContentProc (documented behavior).
 * Tk doesn't handle case (3) either; to account for that we
 * register an event handler on the content window to track <Destroy> events.
 */

/* ++ Data structures.
 */
typedef struct
{
    Tk_Window 		window;
    Ttk_Manager 	*manager;
    void 		*data;
    unsigned		flags;
} Ttk_Content;

/* content->flags bits:
 */
#define CONTENT_MAPPED 	0x1	/* content windows to be mapped when container is */

struct TtkManager_
{
    Ttk_ManagerSpec	*managerSpec;
    void 		*managerData;
    Tk_Window   	window;
    unsigned		flags;
    TkSizeT 	 	nContent;
    Ttk_Content 		**content;
};

/* manager->flags bits:
 */
#define MGR_UPDATE_PENDING	0x1
#define MGR_RESIZE_REQUIRED	0x2
#define MGR_RELAYOUT_REQUIRED	0x4






>
|





|
|



|
|

|

|





|

|



|

|
|
|

|






|

|

|

|

|





|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468

469
470

471
472
473
474
475
476
477
478
479


480



481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545
546
547
	Tcl_DoWhenIdle(ManagerIdleProc, mgr);
	mgr->flags |= MGR_UPDATE_PENDING;
    }
    mgr->flags |= flags;
}

/* ++ RecomputeSize --
 * 	Recomputes the required size of the container 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->window, width, height);
	ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
    }
    mgr->flags &= ~MGR_RESIZE_REQUIRED;
}

/* ++ RecomputeLayout --
 * 	Recompute geometry of all content windows.
 */
static void RecomputeLayout(Ttk_Manager *mgr)
{
    mgr->managerSpec->PlaceContent(mgr->managerData);
    mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
}

/* ++ ManagerIdleProc --
 * 	DoWhenIdle procedure for deferred updates.
 */
static void ManagerIdleProc(ClientData clientData)
{
    Ttk_Manager *mgr = (Ttk_Manager *)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 content layout when container widget is resized.
 * 	Keep the content's map state in sync with the container's.
 */
static const int ManagerEventMask = StructureNotifyMask;
static void ManagerEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT i;

    switch (eventPtr->type)
    {
	case ConfigureNotify:
	    RecomputeLayout(mgr);
	    break;
	case MapNotify:
	    for (i = 0; i < mgr->nContent; ++i) {
		Ttk_Content *content = mgr->content[i];
		if (content->flags & CONTENT_MAPPED) {
		    Tk_MapWindow(content->window);
		}
	    }
	    break;
	case UnmapNotify:
	    for (i = 0; i < mgr->nContent; ++i) {
		Ttk_Content *content = mgr->content[i];
		Tk_UnmapWindow(content->window);
	    }
	    break;
    }
}

/* ++ ContentLostEventHandler --
 * 	Notifies manager when a content window is destroyed
 * 	(see <<NOTE-LOSTCONTENT>>).
 */

static void ContentLostEventHandler(void *clientData, XEvent *eventPtr)
{
    Ttk_Content *content = (Ttk_Content *)clientData;
    if (eventPtr->type == DestroyNotify) {
	content->manager->managerSpec->tkGeomMgr.lostContentProc(
	    content->manager, content->window);
    }
}

/*------------------------------------------------------------------------
 * +++ Content initialization and cleanup.
 */

static Ttk_Content *NewContent(
    Ttk_Manager *mgr, Tk_Window window, void *data)
{
    Ttk_Content *content = (Ttk_Content *)ckalloc(sizeof(Ttk_Content));

    content->window = window;
    content->manager = mgr;
    content->flags = 0;
    content->data = data;

    return content;
}

static void DeleteContent(Ttk_Content *content)
{
    ckfree(content);
}

/*------------------------------------------------------------------------
 * +++ Manager initialization and cleanup.
 */

Ttk_Manager *Ttk_CreateManager(
    Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)ckalloc(sizeof(*mgr));

    mgr->managerSpec 	= managerSpec;
    mgr->managerData	= managerData;
    mgr->window	= window;
    mgr->nContent 	= 0;
    mgr->content 	= NULL;
    mgr->flags  	= 0;

    Tk_CreateEventHandler(
	mgr->window, ManagerEventMask, ManagerEventHandler, mgr);

    return mgr;
}

void Ttk_DeleteManager(Ttk_Manager *mgr)
{
    Tk_DeleteEventHandler(
	mgr->window, ManagerEventMask, ManagerEventHandler, mgr);

    while (mgr->nContent > 0) {
	Ttk_ForgetContent(mgr, mgr->nContent - 1);
    }
    if (mgr->content) {
	ckfree(mgr->content);
    }

    Tcl_CancelIdleCall(ManagerIdleProc, mgr);

    ckfree(mgr);
}

/*------------------------------------------------------------------------
 * +++ Content window management.
 */

/* ++ InsertContent --
 * 	Adds content to the list of managed windows.
 */
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, TkSizeT index)
{
    TkSizeT endIndex = mgr->nContent++;
    mgr->content = (Ttk_Content **)ckrealloc(mgr->content, mgr->nContent * sizeof(Ttk_Content *));


    while (endIndex > index) {
	mgr->content[endIndex] = mgr->content[endIndex - 1];
	--endIndex;
    }

    mgr->content[index] = content;

    Tk_ManageGeometry(content->window,
	&mgr->managerSpec->tkGeomMgr, mgr);

    Tk_CreateEventHandler(content->window,
	StructureNotifyMask, ContentLostEventHandler, content);

    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* RemoveContent --
 * 	Unmanage and delete the content window.
 *
 * NOTES/ASSUMPTIONS:
 *
 * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
 * routine is called from the content window's DestroyNotify event handler.
 */
static void RemoveContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Content *content = mgr->content[index];
    TkSizeT i;

    /* Notify manager:
     */
    mgr->managerSpec->ContentRemoved(mgr->managerData, index);

    /* Remove from array:
     */
    --mgr->nContent;
    for (i = index ; i < mgr->nContent; ++i) {
	mgr->content[i] = mgr->content[i+1];
    }

    /* Clean up:
     */
    Tk_DeleteEventHandler(
	content->window, StructureNotifyMask, ContentLostEventHandler, content);

    /* Note [1] */
    Tk_UnmaintainGeometry(content->window, mgr->window);
    Tk_UnmapWindow(content->window);

    DeleteContent(content);

    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/*------------------------------------------------------------------------
 * +++ Tk_GeomMgr hooks.
 */

void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT index = Ttk_ContentIndex(mgr, window);
    int reqWidth = Tk_ReqWidth(window);
    int reqHeight= Tk_ReqHeight(window);

    if (mgr->managerSpec->ContentRequest(
		mgr->managerData, index, reqWidth, reqHeight))
    {
	ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
    }
}

void Ttk_LostContentProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT index = Ttk_ContentIndex(mgr, window);

    /* ASSERT: index >= 0 */
    RemoveContent(mgr, index);
}

/*------------------------------------------------------------------------
 * +++ Public API.
 */

/* ++ Ttk_InsertContent --
 * 	Add a new content window at the specified index.
 */
void Ttk_InsertContent(
    Ttk_Manager *mgr, TkSizeT index, Tk_Window tkwin, void *data)
{
    Ttk_Content *content = NewContent(mgr, tkwin, data);
    InsertContent(mgr, content, index);
}

/* ++ Ttk_ForgetContent --
 * 	Unmanage the specified content window.
 */
void Ttk_ForgetContent(Ttk_Manager *mgr, TkSizeT index)
{
    Tk_Window window = mgr->content[index]->window;
    RemoveContent(mgr, index);
    Tk_ManageGeometry(window, NULL, 0);
}

/* ++ Ttk_PlaceContent --
 * 	Set the position and size of the specified content window.
 *
 * NOTES:
 * 	Contrary to documentation, Tk_MaintainGeometry doesn't always
 * 	map the content window.
 */
void Ttk_PlaceContent(
    Ttk_Manager *mgr, TkSizeT index, int x, int y, int width, int height)
{
    Ttk_Content *content = mgr->content[index];
    Tk_MaintainGeometry(content->window,mgr->window,x,y,width,height);
    content->flags |= CONTENT_MAPPED;
    if (Tk_IsMapped(mgr->window)) {
	Tk_MapWindow(content->window);
    }
}

/* ++ Ttk_UnmapContent --
 * 	Unmap the specified content window, but leave it managed.
 */
void Ttk_UnmapContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Content *content = mgr->content[index];
    Tk_UnmaintainGeometry(content->window, mgr->window);
    content->flags &= ~CONTENT_MAPPED;
    /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
     * unmap the content window:
     */
    Tk_UnmapWindow(content->window);
}

/* 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.
 */
TkSizeT Ttk_NumberContent(Ttk_Manager *mgr)
{
    return mgr->nContent;
}
void *Ttk_ContentData(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->content[index]->data;
}
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->content[index]->window;
}

/*------------------------------------------------------------------------
 * +++ Utility routines.
 */

/* ++ Ttk_ContentIndex --
 * 	Returns the index of specified content window, -1 if not found.
 */
TkSizeT Ttk_ContentIndex(Ttk_Manager *mgr, Tk_Window window)
{
    TkSizeT index;
    for (index = 0; index < mgr->nContent; ++index)
	if (mgr->content[index]->window == window)
	    return index;
    return TCL_INDEX_NONE;
}

/* ++ Ttk_GetContentIndexFromObj(interp, mgr, objPtr, indexPtr) --
 * 	Return the index of the content window specified by objPtr.
 * 	Content windows 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_GetContentIndexFromObj(
    Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, TkSizeT *indexPtr)
{
    const char *string = Tcl_GetString(objPtr);
    TkSizeT index = 0;
    Tk_Window tkwin;

    /* Try interpreting as an integer first:
     */
    if (TkGetIntForIndex(objPtr, mgr->nContent - 1, 1, &index) == TCL_OK) {
	if (index + 1 > mgr->nContent + 1) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Managed window index %d out of bounds", (int)index));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "INDEX", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }

    /* Try interpreting as a window name;
     */
    if ((*string == '.') &&
	    (tkwin = Tk_NameToWindow(interp, string, mgr->window))) {

	index = Ttk_ContentIndex(mgr, tkwin);
	if (index == TCL_INDEX_NONE) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is not managed by %s", string,
		    Tk_PathName(mgr->window)));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "MANAGER", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }






    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Invalid managed window specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "SPEC", NULL);

    return TCL_ERROR;
}

/* ++ Ttk_ReorderContent(mgr, fromIndex, toIndex) --
 * 	Change content window order.
 */
void Ttk_ReorderContent(Ttk_Manager *mgr, TkSizeT fromIndex, TkSizeT toIndex)
{
    Ttk_Content *moved = mgr->content[fromIndex];

    /* Shuffle down: */
    while (fromIndex > toIndex) {
	mgr->content[fromIndex] = mgr->content[fromIndex - 1];
	--fromIndex;
    }
    /* Or, shuffle up: */
    while (fromIndex < toIndex) {
	mgr->content[fromIndex] = mgr->content[fromIndex + 1];
	++fromIndex;
    }
    /* ASSERT: fromIndex == toIndex */
    mgr->content[fromIndex] = moved;

    /* Schedule a relayout.  In general, rearranging content
     * may also change the size:
     */
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* ++ Ttk_Maintainable(interp, window, container) --
 * 	Utility routine.  Verifies that 'container' may be used to maintain
 *	the geometry of 'window' via Tk_MaintainGeometry:
 *
 * 	+ 'container' is either 'window's parent -OR-
 * 	+ 'container is a descendant of 'window's parent.
 * 	+ 'window' is not a toplevel window
 * 	+ 'window' belongs to the same toplevel as 'container'
 *
 * Returns: 1 if OK; otherwise 0, leaving an error message in 'interp'.
 */
int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window window, Tk_Window container)
{
    Tk_Window ancestor = container, parent = Tk_Parent(window);

    if (Tk_IsTopLevel(window) || window == container) {
	goto badWindow;
    }

    while (ancestor != parent) {
	if (Tk_IsTopLevel(ancestor)) {
	    goto badWindow;
	}
	ancestor = Tk_Parent(ancestor);
    }

    return 1;

badWindow:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as content of %s",
	    Tk_PathName(window), Tk_PathName(container)));

    Tcl_SetErrorCode(interp, "TTK", "GEOMETRY", "MAINTAINABLE", NULL);
    return 0;
}








|







|






|



|








|



















|
|




|
|







|
|
|
|




|
|
|





|
|
|

>
|

|

|
|




|


|
|

|

|
|
|
|

|


|

|







|

|



|
|
|



|







|

|
|

|
|




|



|


|
|

|

|
|
>


|



|

|
|

|
|




|
|




|

|

|
|



|



|
|
|





|


|
|

|








|

|
|
|
|

|
|





|

|
|


|






|
|

|
|

|
|


|
|

|

|
|
|


|
|



|

|
|

|
|
|
|
|



|
|

|

|
|
|

|

|

















|

|

|

|

|

|






|
|

|

|
|
|

|


|
|
|






|
|


|




|
|
>
|
|
|


|



|

|
|
>
|
|
>
|
<
|
<
<
<
<
<
<
>
>
|
>
>
>
|
<
|
>



|
|

|

|



|




|



|

|





|
|
|

|
|
|
|



|

|

|













|
|
>
|



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478






479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
	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);
    }

    Tcl_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;
}

Changes to generic/ttk/ttkManager.h.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "ttkTheme.h"

typedef struct TtkManager_ Ttk_Manager;

/*
 * Geometry manager specification record:
 *
 * RequestedSize computes the requested size of the container window.
 *
 * PlaceContent sets the position and size of all managed content windows
 * by calling Ttk_PlaceContent().
 *
 * ContentRemoved() is called immediately before a content window is removed.
 * NB: the associated content window may have been destroyed when this
 * routine is called.
 *
 * ContentRequest() is called when a content window 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 (*PlaceContent)(void *managerData);
    int  (*ContentRequest)(void *managerData, TkSizeT index, int w, int h);
    void (*ContentRemoved)(void *managerData, TkSizeT index);
} Ttk_ManagerSpec;

/*
 * Default implementations for Tk_GeomMgr hooks:
 */
#define Ttk_LostSlaveProc Ttk_LostContentProc
MODULE_SCOPE void Ttk_GeometryRequestProc(ClientData, Tk_Window window);
MODULE_SCOPE void Ttk_LostContentProc(ClientData, Tk_Window window);

/*
 * Public API:
 */
MODULE_SCOPE Ttk_Manager *Ttk_CreateManager(
	Ttk_ManagerSpec *, void *managerData, Tk_Window window);
MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);

#define  Ttk_InsertSlave Ttk_InsertContent
MODULE_SCOPE void Ttk_InsertContent(
    Ttk_Manager *, TkSizeT position, Tk_Window, void *clientData);

#define Ttk_ForgetSlave Ttk_ForgetContent
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, TkSizeT index);

#define Ttk_ReorderSlave Ttk_ReorderContent
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, TkSizeT fromIndex, TkSizeT toIndex);
    /* Rearrange content window positions */

#define Ttk_PlaceSlave Ttk_PlaceContent
MODULE_SCOPE void Ttk_PlaceContent(
    Ttk_Manager *, TkSizeT index, int x, int y, int width, int height);
    /* Position and map the content window */

#define Ttk_UnmapSlave Ttk_UnmapContent
MODULE_SCOPE void Ttk_UnmapContent(Ttk_Manager *, TkSizeT index);
    /* Unmap the content window */

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:
 */
#define Ttk_SlaveIndex Ttk_ContentIndex
MODULE_SCOPE TkSizeT Ttk_ContentIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in content array of specified window, TCL_INDEX_NONE if not found */

#define Ttk_GetSlaveIndexFromObj Ttk_GetContentIndexFromObj
MODULE_SCOPE int Ttk_GetContentIndexFromObj(
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, TkSizeT *indexPtr);

/* Accessor functions:
 */
#define Ttk_NumberSlaves Ttk_NumberContent
MODULE_SCOPE TkSizeT Ttk_NumberContent(Ttk_Manager *);
    /* Returns: number of managed content windows */

#define Ttk_SlaveData Ttk_ContentData
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, TkSizeT index);
    /* Returns: client data associated with content window */

#define Ttk_SlaveWindow Ttk_ContentWindow
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, TkSizeT index);
    /* Returns: content window */

MODULE_SCOPE int Ttk_Maintainable(Tcl_Interp *, Tk_Window content, Tk_Window container);
    /* Returns: 1 if container can manage content; 0 otherwise leaving error msg */

#endif /* _TTKMANAGER */







|

|
|

|
|

|
|






|
|
|





<
|
|





|


<
|
|

<
|

<
|
|

<
|
|
|

<
|
|







<
|
|

<
|
|



|
<
|

<
|
|

<
|
|

|
|


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50

51
52
53

54
55

56
57
58

59
60
61
62

63
64
65
66
67
68
69
70
71

72
73
74

75
76
77
78
79
80

81
82

83
84
85

86
87
88
89
90
91
92
#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 */

Changes to generic/ttk/ttkNotebook.c.

1
2
3
4



5

6
7
8
9
10
11
12
/*
 * Copyright (c) 2004, Joe English
 */




#include "tkInt.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))





>
>
>
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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))

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
} 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 pane.
 */
static const Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", TCL_INDEX_NONE, offsetof(Tab,state),
	0, (void *)TabStateStrings, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Tab,imageObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	NULL, offsetof(Tab,compoundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,(void *)ttkCompoundStrings,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
	offsetof(Tab,underlineObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
};

static const Tk_OptionSpec PaneOptionSpecs[] =
{
    {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
	offsetof(Tab,paddingObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
	offsetof(Tab,stickyObj), TCL_INDEX_NONE, 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 */
    TkSizeT currentIndex;		/* index of currently selected tab */
    TkSizeT activeIndex;		/* index of currently active tab */
    Ttk_Layout tabLayout;	/* Sublayout for tabs */

    Ttk_Box clientArea;		/* Where to pack content windows */
} NotebookPart;

typedef struct
{
    WidgetCore core;
    NotebookPart notebook;
} Notebook;

static const Tk_OptionSpec NotebookOptionSpecs[] =
{
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	offsetof(Notebook,notebook.widthObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	offsetof(Notebook,notebook.heightObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
	offsetof(Notebook,notebook.paddingObj),TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/* Notebook style options:







|

|


|


|

|

|
|

|



|


|

|
















|
|


|








|


|


|


|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
} 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 content window.
 */
static Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", -1,Tk_Offset(Tab,state),
	0, (void *)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",
	NULL, Tk_Offset(Tab,compoundObj), -1,
	TK_OPTION_NULL_OK, (void *)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 content 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:
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window window)
{
    Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
    Tab *record = (Tab *)ckalloc(sizeof(Tab));
    memset(record, 0, sizeof(Tab));

    if (Tk_InitOptions(interp, record, optionTable, window) != TCL_OK) {
	ckfree(record);
	return NULL;
    }

    return record;
}

static void DestroyTab(Notebook *nb, Tab *tab)







|
|







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window window)
{
    Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
    Tab *record = (Tab *)ckalloc(sizeof(Tab));
    memset(record, 0, sizeof(Tab));

    if (Tk_InitOptions(interp, (char *)record, optionTable, window) != TCL_OK) {
	ckfree((ClientData)record);
	return NULL;
    }

    return record;
}

static void DestroyTab(Notebook *nb, Tab *tab)
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    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, tab, nb->notebook.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Check options:
     * @@@ TODO: validate -image option.







|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    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, (void *)tab, nb->notebook.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Check options:
     * @@@ TODO: validate -image option.
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
}

/*
 * IdentifyTab --
 * 	Return the index of the tab at point x,y,
 * 	or -1 if no tab at that point.
 */
static TkSizeT IdentifyTab(Notebook *nb, int x, int y)
{
    TkSizeT index;
    for (index = 0; index < Ttk_NumberContent(nb->notebook.mgr); ++index) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr,index);
	if (	tab->state != TAB_STATE_HIDDEN
	     && Ttk_BoxContains(tab->parcel, x,y))
	{
	    return index;
	}
    }
    return TCL_INDEX_NONE;
}

/*
 * ActivateTab --
 * 	Set the active tab index, redisplay if necessary.
 */
static void ActivateTab(Notebook *nb, TkSizeT 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 visible tab, and USER2
 * 	is set for the rightmost visible tab.
 */
static Ttk_State TabState(Notebook *nb, TkSizeT index)
{
    Ttk_State state = nb->core.state;
    Tab *itab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT i = 0;

    if (index == nb->notebook.currentIndex) {
	state |= TTK_STATE_SELECTED;
    } else {
	state &= ~TTK_STATE_FOCUS;
    }

    if (index == nb->notebook.activeIndex) {
	state |= TTK_STATE_ACTIVE;
    }
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER1;
	}
	break;
    }
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i != TCL_INDEX_NONE; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}
	break;
    }
    if (itab->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).
 *	The -mintabwidth style option is taken into account (for the width
 *	only).
 *
 * 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 minTabWidth, int *widthPtr, int *heightPtr)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    int tabrowWidth = 0, tabrowHeight = 0;
    TkSizeT i;

    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	Ttk_State tabState = TabState(nb,i);

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
        tab->width = MAX(tab->width, minTabWidth);

	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; }







|

|
|
|






|






|











|
|

|


|
<










<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
|
|
<
<















<
<









|



|

|
|




<







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307





308
309
310







311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
}

/*
 * 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 = (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 *itab = (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 (itab->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 = (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; }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    Notebook *nb = (Notebook *)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;
    TkSizeT i;

    NotebookStyleOptions(nb, &nbstyle);

    /* Compute max requested size of all content windows:
     */
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	int width
	    = Tk_ReqWidth(window) + Ttk_PaddingWidth(tab->padding);
	int height
	    = Tk_ReqHeight(window) + Ttk_PaddingHeight(tab->padding);

	clientWidth = MAX(clientWidth, width);
	clientHeight = MAX(clientHeight, height);
    }

    /* 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, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
    tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
    tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);

    /* Account for exterior and interior padding:
     */
    padding = nbstyle.padding;
    if (clientNode) {







|





|
|
|




















|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
    Notebook *nb = (Notebook *)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 content windows:
     */
    for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
	Tk_Window window = Ttk_SlaveWindow(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
	int width
	    = Tk_ReqWidth(window) + Ttk_PaddingWidth(tab->padding);
	int height
	    = Tk_ReqHeight(window) + Ttk_PaddingHeight(tab->padding);

	clientWidth = MAX(clientWidth, width);
	clientHeight = MAX(clientHeight, height);
    }

    /* 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) {
446
447
448
449
450
451
452
453
454
455









456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471


472
473

474

475
476




477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

/*------------------------------------------------------------------------
 * +++ Geometry management - layout.
 */

/* SqueezeTabs --
 *	Squeeze or stretch tabs to fit within the tab area parcel.
 *	This happens independently of the -mintabwidth style option.
 *
 *	All tabs are adjusted by an equal amount.









 *
 * @@@ <<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 nTabs = Ttk_NumberContent(nb->notebook.mgr);

    if (nTabs > 0) {
	int difference = available - needed;
	double delta = (double)difference / needed;

	double slack = 0;
	int i;



	for (i = 0; i < nTabs; ++i) {
	    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr,i);

	    double ad = slack + tab->width * delta;

	    tab->width += (int)ad;
	    slack = ad - (int)ad;




	}
    }
}

/* 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_NumberContent(nb->notebook.mgr);
    int i;

    for (i = 0; i < nTabs; ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(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) {







<

|
>
>
>
>
>
>
>
>
>






|

|


|
|
>
|


>
>

|
>
|
>
|
|
>
>
>
>











|



|







432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

/*------------------------------------------------------------------------
 * +++ 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 = (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 = (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) {
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
    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:
     * Note: TabrowSize() takes into account -mintabwidth, but the tabs will
     * actually have this minimum size when displayed only if there is enough
     * space to draw the tabs with this width. Otherwise some of the tabs can
     * be squeezed to a size smaller than -mintabwidth because we prefer
     * displaying all tabs than than honoring -mintabwidth for all of them.
     */
    TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &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);
    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;
}

/*
 * NotebookPlaceContent --
 * 	Set the position and size of a child widget
 * 	based on the current client area and content window options:
 */
static void NotebookPlaceContent(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, index);
    Ttk_Box box =
	Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
	    Tk_ReqWidth(window), Tk_ReqHeight(window),tab->sticky);

    Ttk_PlaceContent(nb->notebook.mgr, index,
	box.x, box.y, box.width, box.height);
}

/* NotebookPlaceContents --
 * 	Geometry manager hook.
 */
static void NotebookPlaceContents(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT currentIndex = nb->notebook.currentIndex;
    if (currentIndex != TCL_INDEX_NONE) {
	NotebookDoLayout(nb);
	NotebookPlaceContent(nb, currentIndex);
    }
}

/*
 * SelectTab(nb, index) --
 * 	Change the currently-selected tab.
 */
static void SelectTab(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT 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 != TCL_INDEX_NONE) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }

    /* Must be set before calling NotebookPlaceContent(), otherwise it may
     * happen that NotebookPlaceContents(), triggered by an interveaning
     * geometry request, will swap to old index. */
    nb->notebook.currentIndex = index;

    NotebookPlaceContent(nb, index);
    TtkRedisplayWidget(&nb->core);

    Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
}

/* 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)
{
    TkSizeT nTabs = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT nextIndex;

    /* Scan forward for following usable tab:
     */
    for (nextIndex = index + 1; nextIndex + 1 < nTabs + 1; ++nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Not found -- scan backwards.
     */
    for (nextIndex = index - 1; nextIndex != TCL_INDEX_NONE; --nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(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)
{
    TkSizeT currentIndex = nb->notebook.currentIndex;
    TkSizeT nextIndex = NextTab(nb, currentIndex);

    if (currentIndex != TCL_INDEX_NONE) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }
    if (currentIndex != nextIndex) {
	Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
    }

    nb->notebook.currentIndex = nextIndex;
    Ttk_ManagerLayoutChanged(nb->notebook.mgr);
    TtkRedisplayWidget(&nb->core);
}

/* TabRemoved -- GM TabRemoved hook.
 * 	Select the next tab if the current one is being removed.
 * 	Adjust currentIndex to account for removed content window.
 */
static void TabRemoved(void *managerData, TkSizeT index)
{
    Notebook *nb = (Notebook *)managerData;
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);

    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    if (index + 1 < nb->notebook.currentIndex + 1) {
	--nb->notebook.currentIndex;
    }

    DestroyTab(nb, tab);

    TtkRedisplayWidget(&nb->core);
}

static int TabRequest(
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    return 1;
}

/* AddTab --
 * 	Add new tab at specified index.
 */
static int AddTab(
    Tcl_Interp *interp, Notebook *nb,
    TkSizeT destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Tab *tab;
    if (!Ttk_Maintainable(interp, window, nb->core.tkwin)) {
	return TCL_ERROR;
    }
#if 0 /* can't happen */
    if (Ttk_ContentIndex(nb->notebook.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added",
	    Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL);
	return TCL_ERROR;
    }
#endif

    /* Create and insert tab.
     */
    tab = CreateTab(interp, nb, window);
    if (!tab) {
	return TCL_ERROR;
    }
    if (ConfigureTab(interp, nb, tab, window, objc, objv) != TCL_OK) {
	DestroyTab(nb, tab);
	return TCL_ERROR;
    }

    Ttk_InsertContent(nb->notebook.mgr, destIndex, window, tab);

    /* Adjust indices and/or autoselect first tab:
     */
    if (nb->notebook.currentIndex == TCL_INDEX_NONE) {
	SelectTab(nb, destIndex);
    } else if (nb->notebook.currentIndex + 1 >= destIndex + 1) {
	++nb->notebook.currentIndex;
    }

    return TCL_OK;
}

static Ttk_ManagerSpec NotebookManagerSpec = {
    { "notebook", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    NotebookSize,
    NotebookPlaceContents,
    TabRequest,
    TabRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */







<
<
<
<
<

|







|
















|



|

|
|




|



|


|


|
|

|







|

|
|















|
|


|
|



|


|









|
|



|
|







|
|



















|
|

|
|


|







|



|


|





|








|
<
<
<
<









|







|
|
|
|















|



|

|







|

|







535
536
537
538
539
540
541





542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714




715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
    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 content window options:
 */
static void NotebookPlaceSlave(Notebook *nb, int index)
{
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    Tk_Window window = Ttk_SlaveWindow(nb->notebook.mgr, index);
    Ttk_Box box =
	Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
	    Tk_ReqWidth(window), Tk_ReqHeight(window),tab->sticky);

    Ttk_PlaceSlave(nb->notebook.mgr, index,
	box.x, box.y, box.width, box.height);
}

/* NotebookPlaceSlaves --
 * 	Geometry manager hook.
 */
static void NotebookPlaceSlaves(void *recordPtr)
{
    Notebook *nb = (Notebook *)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 = (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);
    }

    /* Must be set before calling NotebookPlaceSlave(), otherwise it may
     * happen that NotebookPlaceSlaves(), triggered by an interveaning
     * geometry request, will swap to old index. */
    nb->notebook.currentIndex = index;

    NotebookPlaceSlave(nb, 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 = (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 = (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 content window.
 */
static void TabRemoved(void *managerData, int index)
{
    Notebook *nb = (Notebook *)managerData;
    Tab *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 window,
    int objc, Tcl_Obj *const objv[])
{
    Tab *tab;
    if (!Ttk_Maintainable(interp, window, nb->core.tkwin)) {
	return TCL_ERROR;
    }
#if 0 /* can't happen */
    if (Ttk_SlaveIndex(nb->notebook.mgr, window) >= 0) {
	Tcl_AppendResult(interp,
	    Tk_PathName(slaveWindow), " already added",
	    NULL);
	return TCL_ERROR;
    }
#endif

    /* Create and insert tab.
     */
    tab = CreateTab(interp, nb, window);
    if (!tab) {
	return TCL_ERROR;
    }
    if (ConfigureTab(interp, nb, tab, window, objc, objv) != TCL_OK) {
	DestroyTab(nb, tab);
	return TCL_ERROR;
    }

    Ttk_InsertSlave(nb->notebook.mgr, destIndex, window, 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.
 */
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
{
    Notebook *nb = (Notebook *)clientData;

    if (eventPtr->type == DestroyNotify) { /* Remove self */
	Tk_DeleteEventHandler(nb->core.tkwin,
	    NotebookEventMask, NotebookEventHandler, clientData);
    } else if (eventPtr->type == MotionNotify) {
	TkSizeT index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
	ActivateTab(nb, index);
    } else if (eventPtr->type == LeaveNotify) {
	ActivateTab(nb, -1);
    }
}

/*------------------------------------------------------------------------







|







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
{
    Notebook *nb = (Notebook *)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);
    }
}

/*------------------------------------------------------------------------
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
 *
 *	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, TkSizeT *index_rtn)
{
    const char *string = Tcl_GetString(objPtr);
    int x, y;

    *index_rtn = TCL_INDEX_NONE;

    /* 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 content window name:
     */
    if (Ttk_GetContentIndexFromObj(
	    interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
    {
	return TCL_OK;
    }
    if (*index_rtn == Ttk_NumberContent(nb->notebook.mgr)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Invalid tab specification %s", string));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "SPEC", NULL);
	return TCL_ERROR;
    }

    /* Nothing matched; Ttk_GetContentIndexFromObj 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, TkSizeT *index_rtn)
{
    int status = FindTabIndex(interp, nb, objPtr, index_rtn);
	if (status == TCL_OK && *index_rtn + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"tab index %s out of bounds", Tcl_GetString(objPtr)));
	    Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "INDEX", NULL);
	    return TCL_ERROR;
	}

    if (status == TCL_OK && *index_rtn == TCL_INDEX_NONE) {

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "tab '%s' not found", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL);
	status = TCL_ERROR;
    }
    return status;
}

/*------------------------------------------------------------------------
 * +++ Widget command routines.







|




|

















|




<
<
<
<
<
|
<
|










|


<
<
<
<
<
|
<
|
>
|
|
|







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847





848

849
850
851
852
853
854
855
856
857
858
859
860
861
862





863

864
865
866
867
868
869
870
871
872
873
874
875
 *
 *	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 content 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.
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948


949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132









1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }
    index = Ttk_ContentIndex(nb->notebook.mgr, window);

    if (index < 0) { /* New tab */
	return AddTab(interp, nb, Ttk_NumberContent(nb->notebook.mgr), window, objc-3,objv+3);
    }

    tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }
    if (ConfigureTab(interp, nb, tab, window, objc-3,objv+3) != 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 = (Notebook *)recordPtr;
    TkSizeT current = nb->notebook.currentIndex;
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT srcIndex, destIndex;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }



    if (TCL_OK != Ttk_GetContentIndexFromObj(
		interp, nb->notebook.mgr, objv[2], &destIndex)) {
	return TCL_ERROR;
    }

    if (Tcl_GetString(objv[3])[0] == '.') {
	/* Window name -- could be new or existing content window.
	 */
	Tk_Window window =
	    Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);

	if (!window) {
	    return TCL_ERROR;
	}

	srcIndex = Ttk_ContentIndex(nb->notebook.mgr, window);
	if (srcIndex == TCL_INDEX_NONE) {	/* New content window */
	    return AddTab(interp, nb, destIndex, window, objc-4,objv+4);
	}
    } else if (Ttk_GetContentIndexFromObj(
		interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
    {
	return TCL_ERROR;
    } else if (srcIndex + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	srcIndex = Ttk_NumberContent(nb->notebook.mgr) - 1;
    }

    /* Move existing content window:
     */
    if (ConfigureTab(interp, nb,
	     (Tab *)Ttk_ContentData(nb->notebook.mgr, srcIndex),
		 Ttk_ContentWindow(nb->notebook.mgr, srcIndex),
	     objc-4,objv+4) != TCL_OK)
    {
	return TCL_ERROR;
    }

    if (destIndex + 1 >= nContent + 1) {
	destIndex  = nContent - 1;
    }
    Ttk_ReorderContent(nb->notebook.mgr, srcIndex, destIndex);

    /* Adjust internal indexes:
     */
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    if (current == srcIndex) {
	nb->notebook.currentIndex = destIndex;
    } else if (destIndex + 1 <= current + 1 && current + 1 < srcIndex + 1) {
	++nb->notebook.currentIndex;
    } else if (srcIndex + 1 < current + 1 && current + 1 <= destIndex + 1) {
	--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 = (Notebook *)recordPtr;
    TkSizeT 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_ForgetContent(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 = (Notebook *)recordPtr;
    TkSizeT 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 = (Tab *)Ttk_ContentData(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 *const whatTable[] = { "element", "tab", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_TAB };
    int what = IDENTIFY_ELEMENT;
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Element element = NULL;
    int x, y;
    TkSizeT 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_GetIndexFromObjStruct(interp, objv[2], whatTable,
		sizeof(char *), "option", 0, &what) != TCL_OK)
    ) {
	return TCL_ERROR;
    }

    tabIndex = IdentifyTab(nb, x, y);
    if (tabIndex != TCL_INDEX_NONE) {
	Tab *tab = (Tab *)Ttk_ContentData(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 != TCL_INDEX_NONE)
	    Tcl_SetObjResult(interp, TkNewIndexObj(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 = (Notebook *)recordPtr;
    TkSizeT index;
    int status;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }










    status = FindTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
	if (index != TCL_INDEX_NONE)
	Tcl_SetObjResult(interp, TkNewIndexObj(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 = (Notebook *)recordPtr;

    if (objc == 2) {
	if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	    Tk_Window pane = Ttk_ContentWindow(
		nb->notebook.mgr, nb->notebook.currentIndex);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
	}
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT index;
	int 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 = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    Tcl_Obj *result;
    TkSizeT i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    result = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(mgr,i));

	Tcl_ListObjAppendElement(NULL, 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 = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    TkSizeT index;
    Tk_Window window;
    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 = (Tab *)Ttk_ContentData(mgr, index);
    window = Ttk_ContentWindow(mgr, index);

    if (objc == 3) {
	return TtkEnumerateOptions(interp, tab,
	    PaneOptionSpecs, nb->notebook.paneOptionTable, window);
    } else if (objc == 4) {
	return TtkGetOptionValue(interp, tab, objv[3],
	    nb->notebook.paneOptionTable, window);







|


|


|



















|
|
|


|



>
>
|














|
|


|



<
<





|
|





|


|



|


|

|















|










|












|











|
















|





|








|
|





|
|


















|
|
>














|







>
>
>
>
>
>
>
>
>

|
<
|















|
|





<
|


















|







|
|














|












|
|







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956


957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }
    index = Ttk_SlaveIndex(nb->notebook.mgr, window);

    if (index < 0) { /* New tab */
	return AddTab(interp, nb, Ttk_NumberSlaves(nb->notebook.mgr), window, objc-3,objv+3);
    }

    tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }
    if (ConfigureTab(interp, nb, tab, window, objc-3,objv+3) != 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 = (Notebook *)recordPtr;
    int current = nb->notebook.currentIndex;
    int nContent = 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 content window.
	 */
	Tk_Window window =
	    Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);

	if (!window) {
	    return TCL_ERROR;
	}

	srcIndex = Ttk_SlaveIndex(nb->notebook.mgr, window);
	if (srcIndex < 0) {	/* New content window */
	    return AddTab(interp, nb, destIndex, window, objc-4,objv+4);
	}
    } else if (Ttk_GetSlaveIndexFromObj(
		interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
    {
	return TCL_ERROR;


    }

    /* Move existing content window:
     */
    if (ConfigureTab(interp, nb,
	     (Tab *)Ttk_SlaveData(nb->notebook.mgr, srcIndex),
		 Ttk_SlaveWindow(nb->notebook.mgr, srcIndex),
	     objc-4,objv+4) != TCL_OK)
    {
	return TCL_ERROR;
    }

    if (destIndex >= nContent) {
	destIndex  = nContent - 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 = (Notebook *)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 = (Notebook *)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 = (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 = (Notebook *)recordPtr;
    Ttk_Element element = NULL;
    int x, y;
    int 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 = (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 = (Notebook *)recordPtr;
    int index;
    int 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 nContent = Ttk_NumberSlaves(nb->notebook.mgr);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(nContent));
	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 = (Notebook *)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 = (Notebook *)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(NULL, 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 = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    int index;
    Tk_Window window;
    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 = (Tab *)Ttk_SlaveData(mgr, index);
    window = Ttk_SlaveWindow(mgr, index);

    if (objc == 3) {
	return TtkEnumerateOptions(interp, tab,
	    PaneOptionSpecs, nb->notebook.paneOptionTable, window);
    } else if (objc == 4) {
	return TtkGetOptionValue(interp, tab, objv[3],
	    nb->notebook.paneOptionTable, window);
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

    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 = TCL_INDEX_NONE;
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    nb->notebook.tabLayout = 0;

    nb->notebook.clientArea = Ttk_MakeBox(0,0,1,1);

    Tk_CreateEventHandler(
	nb->core.tkwin, NotebookEventMask, NotebookEventHandler, recordPtr);
}







|
|







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273

    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);
}
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
/*------------------------------------------------------------------------
 * +++ Display routines.
 */

static void DisplayTab(Notebook *nb, int index, Drawable d)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    Tab *tab = (Tab *)Ttk_ContentData(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 = (Notebook *)clientData;
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT 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 < nContent; ++index) {
	if (index != nb->notebook.currentIndex) {
	    DisplayTab(nb, index, d);
	}
    }
    if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	DisplayTab(nb, nb->notebook.currentIndex, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget specification and layout definitions.
 */

static const WidgetSpec NotebookWidgetSpec =
{
    "TNotebook",		/* className */
    sizeof(Notebook),		/* recordSize */
    NotebookOptionSpecs,	/* optionSpecs */
    NotebookCommands,		/* subcommands */
    NotebookInitialize,		/* initializeProc */
    NotebookCleanup,		/* cleanupProc */







|












|
|













|








|







1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
/*------------------------------------------------------------------------
 * +++ Display routines.
 */

static void DisplayTab(Notebook *nb, int index, Drawable d)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    Tab *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 = (Notebook *)clientData;
    int nContent = 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 < nContent; ++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 */

Changes to generic/ttk/ttkPanedwindow.c.

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
/*
 * Copyright (c) 2005, Joe English.  Freely redistributable.
 *
 * ttk::panedwindow widget implementation.
 *
 * TODO: track active/pressed sash.
 */


#include "tkInt.h"
#include "ttkManager.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*------------------------------------------------------------------------
 * +++ Layout algorithm.
 *








>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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.
 *
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * 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 content 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.
 *







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * 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.
 *
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
typedef struct {
    WidgetCore	core;
    PanedPart	paned;
} Paned;

/* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
 */
static const Tk_OptionSpec PanedOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Paned,paned.orientObj), offsetof(Paned,paned.orient),
	0, (void *)ttkOrientStrings, READONLY_OPTION|STYLE_CHANGED },
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.width),
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.height),
	0, 0, GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Pane record.
 */
typedef struct {
    int 	reqSize;		/* Pane request size */
    int 	sashPos;		/* Folowing sash position */
    int 	weight; 		/* Pane -weight, for resizing */
} Pane;

static const Tk_OptionSpec PaneOptionSpecs[] = {
    {TK_OPTION_INT, "-weight", "weight", "Weight", "0",
	TCL_INDEX_NONE, offsetof(Pane,weight), 0,0,GEOMETRY_CHANGED },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/* CreatePane --
 * 	Create a new pane record.
 */
static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window window)
{
    Tk_OptionTable optionTable = pw->paned.paneOptionTable;
    void *record = ckalloc(sizeof(Pane));
    Pane *pane = (Pane *)record;

    memset(record, 0, sizeof(Pane));
    if (Tk_InitOptions(interp, record, optionTable, window) != TCL_OK) {
	ckfree(record);
	return NULL;
    }

    pane->reqSize
	= pw->paned.orient == TTK_ORIENT_HORIZONTAL
	? Tk_ReqWidth(window) : Tk_ReqHeight(window);

    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 window,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Manager *mgr = pw->paned.mgr;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Sanity-check:
     */
    if (pane->weight < 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"-weight must be nonnegative", -1));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "WEIGHT", NULL);
	goto error;
    }

    /* Done.
     */
    Tk_FreeSavedOptions(&savedOptions);
    Ttk_ManagerSizeChanged(mgr);







|

|
|

|
|

|
|






|







|

|
|





|



|


|






|


















|






|
|







<
|
<







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160

161
162
163
164
165
166
167
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);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
 * 	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 = (Pane *)Ttk_ContentData(pw->paned.mgr, i);
    int sashThickness = pw->paned.sashThickness;

    if (i == 0) {
	if (pos < 0)
	    pos = 0;
    } else {
	Pane *prevPane = (Pane *)Ttk_ContentData(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, TkSizeT i, int pos)
{
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr,i);
    int sashThickness = pw->paned.sashThickness;

    if (i == Ttk_NumberContent(pw->paned.mgr) - 1) {
	pos = pane->sashPos; /* Sentinel value == container window size */
    } else {
	Pane *nextPane = (Pane *)Ttk_ContentData(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 = (Paned *)recordPtr;
    int nPanes = Ttk_NumberContent(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 = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);

	    if (height < Tk_ReqHeight(window))
		height = Tk_ReqHeight(window);
	    width += pane->reqSize;
	}
	width += nSashes * sashThickness;
    } else {
	for (index = 0; index < nPanes; ++index) {
	    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);

	    if (width < Tk_ReqWidth(window))
		width = Tk_ReqWidth(window);
	    height += pane->reqSize;
	}
	height += nSashes * sashThickness;
    }

    *widthPtr = pw->paned.width > 0 ? pw->paned.width : width;
    *heightPtr = pw->paned.height > 0 ? pw->paned.height : height;







|






|










|

|


|
|

|














|
|







|
|

|
|





|
|

|
|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
 * 	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;
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
 * 	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;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;
	pane->reqSize = size >= 0 ? size : 0;
	pos = pane->sashPos + sashThickness;
    }
}

/* PlaceSashes --







|

|
|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
 * 	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 --
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 * 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_NumberContent(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 = (Pane *)Ttk_ContentData(mgr, i);
	reqSize += pane->reqSize;
	totalWeight += pane->weight * (pane->reqSize != 0);
    }

    /* Compute difference to be redistributed:
     */
    difference = available - reqSize - sashThickness*(nPanes-1);







|











|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 * 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);
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    }
    /* ASSERT: 0 <= remainder < totalWeight */

    /* Place sashes:
     */
    pos = 0;
    for (i = 0; i < nPanes; ++i) {
	Pane *pane = (Pane *)Ttk_ContentData(mgr, i);
	int weight = pane->weight * (pane->reqSize != 0);
	int size = pane->reqSize + delta * weight;

	if (weight > remainder)
	    weight = remainder;
	remainder -= weight;
	size += weight;







|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
    }
    /* 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;
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
     * Set sentinel sash position to end of widget,
     * shove preceding sashes up.
     */
    ShoveUp(pw, nPanes - 1, available);
}

/* PlacePanes --
 *	Places 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;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;

	if (size > 0) {
	    if (horizontal) {
		Ttk_PlaceContent(pw->paned.mgr, index, pos, 0, size, height);
	    } else {
		Ttk_PlaceContent(pw->paned.mgr, index, 0, pos, width, size);
	    }
	} else {
	    Ttk_UnmapContent(pw->paned.mgr, index);
	}

	pos = pane->sashPos + sashThickness;
    }
}

/*------------------------------------------------------------------------
 * +++ Manager specification.
 */

static void PanedPlaceContent(void *managerData)
{
    Paned *pw = (Paned *)managerData;
    PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
    PlacePanes(pw);
}

static void PaneRemoved(void *managerData, TkSizeT index)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    DestroyPane(pw, pane);
}

static int AddPane(
    Tcl_Interp *interp, Paned *pw,
    int destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Pane *pane;
    if (!Ttk_Maintainable(interp, window, pw->core.tkwin)) {
	return TCL_ERROR;
    }
    if (Ttk_ContentIndex(pw->paned.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s already added", Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "PRESENT", NULL);
	return TCL_ERROR;
    }

    pane = CreatePane(interp, pw, window);
    if (!pane) {
	return TCL_ERROR;
    }
    if (ConfigurePane(interp, pw, pane, window, objc, objv) != TCL_OK) {
	DestroyPane(pw, pane);
	return TCL_ERROR;
    }

    Ttk_InsertContent(pw->paned.mgr, destIndex, window, pane);
    return TCL_OK;
}

/* PaneRequest --
 * 	Only update pane request size if pane is currently unmapped.
 * 	Geometry requests from mapped panes 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, TkSizeT index, int width, int height)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;

    if (!Tk_IsMapped(window)) {
	pane->reqSize = horizontal ? width : height;
    }
    return 1;
}

static Ttk_ManagerSpec PanedManagerSpec = {
    { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    PanedSize,
    PanedPlaceContent,
    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 = (WidgetCore *)clientData;
    if (   eventPtr->type == LeaveNotify
	&& eventPtr->xcrossing.detail == NotifyInferior)
    {
	Tk_SendVirtualEvent(corePtr->tkwin, "EnteredChild", NULL);
    }
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup hooks.
 */

static void PanedInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Paned *pw = (Paned *)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 = (Paned *)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_UNUSED(Tcl_Interp *),
    void *clientData,
    int mask)
{
    Paned *pw = (Paned *)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 = (Paned *)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(







|







|

|
|




|

|


|










|

|




|

|
|





|



|


|
|
|
|



|



|




|




|
|



|

|
|
|


|






|

|




















|



|









|











|










|
<
<
<

|




















|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
     * 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(
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

/* SashLayout --
 * 	Place the sash sublayout after the specified pane,
 * 	in preparation for drawing.
 */
static Ttk_Layout SashLayout(Paned *pw, int index)
{
    Pane *pane = (Pane *)Ttk_ContentData(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,







|







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

/* 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,
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666


667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
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 = (Paned *)recordPtr;
    TkSizeT i, nContent = Ttk_NumberContent(pw->paned.mgr);

    TtkWidgetDisplay(recordPtr, d);
    for (i = 1; i < nContent; ++i) {
	DrawSash(pw, i - 1, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget commands.
 */

/* $pw add window [ options ... ]
 */
static int PanedAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tk_Window window;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[2]), pw->core.tkwin);

    if (!window) {
	return TCL_ERROR;
    }

    return AddPane(interp, pw, Ttk_NumberContent(pw->paned.mgr), window,
	    objc - 3, objv + 3);
}

/* $pw insert $index $window ?-option value ...?
 * 	Insert new content window, or move existing one.
 */
static int PanedInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT nContent = Ttk_NumberContent(pw->paned.mgr);
    TkSizeT srcIndex, destIndex;
    Tk_Window window;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[3]), pw->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }



    if (TCL_OK != Ttk_GetContentIndexFromObj(
		interp,pw->paned.mgr, objv[2], &destIndex))
    {
	return TCL_ERROR;
    }

    srcIndex = Ttk_ContentIndex(pw->paned.mgr, window);
    if (srcIndex == TCL_INDEX_NONE) { /* New content: */
	return AddPane(interp, pw, destIndex, window, objc-4, objv+4);
    } /* else -- move existing content: */

    if (destIndex + 1 >= nContent + 1)
	destIndex  = nContent - 1;
    Ttk_ReorderContent(pw->paned.mgr, srcIndex, destIndex);

    return objc == 4 ? TCL_OK :
	ConfigurePane(interp, pw,
		(Pane *)Ttk_ContentData(pw->paned.mgr, destIndex),
		Ttk_ContentWindow(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 = (Paned *)recordPtr;
    TkSizeT paneIndex;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp, pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }
    Ttk_ForgetContent(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 *const whatTable[] = { "element", "sash", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
    int what = IDENTIFY_SASH;
    Paned *pw = (Paned *)recordPtr;
    int sashThickness = pw->paned.sashThickness;
    int nSashes = Ttk_NumberContent(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_GetIndexFromObjStruct(interp, objv[2], whatTable,
	    sizeof(char *), "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 = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	if (pane->sashPos <= pos && pos <= pane->sashPos + sashThickness) {
	    /* Found it. */
	    switch (what) {
		case IDENTIFY_SASH:
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
		    return TCL_OK;
		case IDENTIFY_ELEMENT:
		{
		    Ttk_Element element =
			Ttk_IdentifyElement(SashLayout(pw, index), x, y);
		    if (element) {
			Tcl_SetObjResult(interp,







|
|


|
|












|
|






|


|



|



|
|




|
|
|
|


|



|

|



>
>
|
|




|
|
|
|

|
|
|



|
|
|







|
|






|



<
<

|










|


|

|










|
|
>






|




|







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703


704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
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,
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

/* $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 = (Paned *)recordPtr;
    TkSizeT paneIndex;
    Tk_Window window;
    Pane *pane;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp,pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, paneIndex);
    window = Ttk_ContentWindow(pw->paned.mgr, paneIndex);

    switch (objc) {
	case 3:
	    return TtkEnumerateOptions(interp, pane, PaneOptionSpecs,
			pw->paned.paneOptionTable, window);
	case 4:
	    return TtkGetOptionValue(interp, pane, objv[3],
			pw->paned.paneOptionTable, window);
	default:
	    return ConfigurePane(interp, pw, pane, window, 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 = (Paned *)recordPtr;
    Ttk_Manager *mgr = pw->paned.mgr;
    Tcl_Obj *panes;
    TkSizeT i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    panes = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(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 = (Paned *)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 || (TkSizeT)sashIndex + 1 >= Ttk_NumberContent(pw->paned.mgr)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "sash index %d out of range", sashIndex));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "SASH_INDEX", NULL);
	return TCL_ERROR;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, sashIndex);

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(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_NewWideIntObj(pane->sashPos));
    return TCL_OK;
}

static const Ttk_Ensemble PanedCommands[] = {
    { "add", 		PanedAddCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },







|
|
|







|
|


<
<


|
|




|


|

|









|


|







|
|














|










|
|
|
|



|


|

















|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784


785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

/* $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 },
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */

static const WidgetSpec PanedWidgetSpec =
{
    "TPanedwindow",		/* className */
    sizeof(Paned),		/* recordSize */
    PanedOptionSpecs,		/* optionSpecs */
    PanedCommands,		/* subcommands */
    PanedInitialize,		/* initializeProc */
    PanedCleanup,		/* cleanupProc */







|







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */

static WidgetSpec PanedWidgetSpec =
{
    "TPanedwindow",		/* className */
    sizeof(Paned),		/* recordSize */
    PanedOptionSpecs,		/* optionSpecs */
    PanedCommands,		/* subcommands */
    PanedInitialize,		/* initializeProc */
    PanedCleanup,		/* cleanupProc */
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956

static const int DEFAULT_SASH_THICKNESS = 5;

typedef struct {
    Tcl_Obj *thicknessObj;
} SashElement;

static const Ttk_ElementOptionSpec SashElementOptions[] = {
    { "-sashthickness", TK_OPTION_INT,
	    offsetof(SashElement,thicknessObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;
    int thickness = DEFAULT_SASH_THICKNESS;

    Tcl_GetIntFromObj(NULL, sash->thicknessObj, &thickness);
    *widthPtr = *heightPtr = thickness;
}

static const Ttk_ElementSpec SashElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SashElement),
    SashElementOptions,
    SashElementSize,
    TtkNullElementDraw
};








|

|
|



<
|
<
|
<
<

|

<




|







916
917
918
919
920
921
922
923
924
925
926
927
928
929

930

931


932
933
934

935
936
937
938
939
940
941
942
943
944
945
946

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
};

Changes to generic/ttk/ttkProgress.c.

1
2
3
4
5
6

7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham
 *
 * ttk::progressbar widget.
 */


#include "tkInt.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 	*anchorObj;
    Tcl_Obj 	*fontObj;
    Tcl_Obj 	*foregroundObj;
    Tcl_Obj 	*justifyObj;
    Tcl_Obj 	*lengthObj;
    Tcl_Obj 	*maximumObj;
    Tcl_Obj 	*modeObj;
    Tcl_Obj 	*orientObj;
    Tcl_Obj 	*phaseObj;
    Tcl_Obj 	*textObj;
    Tcl_Obj 	*valueObj;
    Tcl_Obj 	*variableObj;
    Tcl_Obj 	*wrapLengthObj;

    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 const Tk_OptionSpec ProgressbarOptionSpecs[] =
{
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(Progressbar,progress.anchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEFAULT_FONT, offsetof(Progressbar,progress.fontObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	"black", offsetof(Progressbar,progress.foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Progressbar,progress.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-length", "length", "Length",
        DEF_PROGRESSBAR_LENGTH, offsetof(Progressbar,progress.lengthObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
	"100", offsetof(Progressbar,progress.maximumObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING_TABLE, "-mode", "mode", "ProgressMode", "determinate",
	offsetof(Progressbar,progress.modeObj),
	offsetof(Progressbar,progress.mode),
	0, (void *)ProgressbarModeStrings, 0 },
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	"horizontal", offsetof(Progressbar,progress.orientObj), TCL_INDEX_NONE,
	0, (void *)ttkOrientStrings, STYLE_CHANGED },
    {TK_OPTION_INT, "-phase", "phase", "Phase",
	"0", offsetof(Progressbar,progress.phaseObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Progressbar,progress.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },

    {TK_OPTION_DOUBLE, "-value", "value", "Value",
	"0.0", offsetof(Progressbar,progress.valueObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	NULL, offsetof(Progressbar,progress.variableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0 },
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	"0", offsetof(Progressbar, progress.wrapLengthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Animation procedures:






>
|
>
















<
|
<
<

<

<
|
|

|
<














|

<
<
<
<
<
<
<
<
|
<
|
|

|

<
<
<

|
|
|
<
<
<
|
|

|
|
<
>

|

|
|
|
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26


27

28

29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48








49

50
51
52
53
54



55
56
57
58



59
60
61
62
63

64
65
66
67
68
69
70



71
72
73
74
75
76
77
/*
 * 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:
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* 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 = (Progressbar *)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_NewWideIntObj(phase);
	Tcl_IncrRefCount(pb->progress.phaseObj);

	/*
	 * Reschedule:
	 */
	pb->progress.timer = Tcl_CreateTimerHandler(
	    pb->progress.period, AnimateProgressProc, clientData);







|














|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* 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);
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
 * 	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, 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 = (Progressbar *)recordPtr;
    Tcl_Obj *newValue;
    double scratch;

    if (WidgetDestroyed(&pb->core)) {
	return;
    }








|















|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * 	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;
    }

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    TtkRedisplayWidget(&pb->core);
}

/*------------------------------------------------------------------------
 * +++ Widget class methods:
 */

static void ProgressbarInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Progressbar *pb = (Progressbar *)recordPtr;

    pb->progress.variableTrace = 0;
    pb->progress.timer = 0;
}

static void ProgressbarCleanup(void *recordPtr)
{
    Progressbar *pb = (Progressbar *)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 = (Progressbar *)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;
    }







|
<
<

|
<






|













|







182
183
184
185
186
187
188
189


190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    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;
    }
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    return TCL_OK;
}

/*
 * Post-configuration hook:
 */
static int ProgressbarPostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr,
    TCL_UNUSED(int))
{
    Progressbar *pb = (Progressbar *)recordPtr;
    int status = TCL_OK;

    if (pb->progress.variableTrace) {
	status = Ttk_FireTrace(pb->progress.variableTrace);
	if (WidgetDestroyed(&pb->core)) {
	    return TCL_ERROR;
	}







<
|
<

|







231
232
233
234
235
236
237

238

239
240
241
242
243
244
245
246
247
    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;
	}
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

/*
 * Size hook:
 * 	Compute base layout size, overrid
 */
static int ProgressbarSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
    Progressbar *pb = (Progressbar *)recordPtr;
    int length = 100;
    Ttk_Orient 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);
    TtkGetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = length;
    } else {
	*heightPtr = length;
    }








|
|
<






|







262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284

/*
 * 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;
    }

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
	pbarBox.y = parcel.y + (int)(fraction * (parcel.height-pbarBox.height));
    }
    Ttk_PlaceElement(pb->core.layout, pbar, pbarBox);
}

static void ProgressbarDoLayout(void *recordPtr)
{
    Progressbar *pb = (Progressbar *)recordPtr;
    WidgetCore *corePtr = &pb->core;
    Ttk_Element pbar = Ttk_FindElement(corePtr->layout, "pbar");
    double value = 0.0, maximum = 100.0;
    Ttk_Orient 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);
    TtkGetOrientFromObj(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 = (Progressbar *)recordPtr;
    Ttk_Layout layout = TtkWidgetGetOrientedLayout(
	interp, theme, recordPtr, pb->progress.orientObj);

    /*
     * Check if the style supports animation:
     */
    pb->progress.period = 0;







|



|








|


















|







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
	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;
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 */

/* $sb step ?amount?
 */
static int ProgressbarStepCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Progressbar *pb = (Progressbar *)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?");







|

|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
 */

/* $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?");
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
    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);
    Tcl_IncrRefCount(newValueObj);

    TtkRedisplayWidget(&pb->core);

    /* Update value by setting the linked -variable, if there is one:
     */
    if (pb->progress.variableTrace) {
	int result = Tcl_ObjSetVar2(
		        interp, pb->progress.variableObj, 0, newValueObj,
		        TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
	        ? TCL_OK : TCL_ERROR;
        Tcl_DecrRefCount(newValueObj);
        return result;
    }

    /* Otherwise, change the -value directly:
     */

    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];







<



|


|
|
|
|
<
<




>








|







417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
    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];
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
    status = Tcl_EvalObjEx(interp, cmd, 0);
    Tcl_DecrRefCount(cmd);

    return status;
}

static int ProgressbarStartCommand(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	    interp, "::ttk::progressbar::start", objc, objv);
}

static int ProgressbarStopCommand(
    TCL_UNUSED(void *),
    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 const WidgetSpec ProgressbarWidgetSpec =
{
    "TProgressbar",		/* className */
    sizeof(Progressbar),	/* recordSize */
    ProgressbarOptionSpecs,	/* optionSpecs */
    ProgressbarCommands,	/* subcommands */
    ProgressbarInitialize,	/* initializeProc */
    ProgressbarCleanup,		/* cleanupProc */







<
<
<
|


|



<
<
<
|


|

















|







464
465
466
467
468
469
470



471
472
473
474
475
476
477



478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    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 */
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
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_NODE("Horizontal.Progressbar.text", TTK_PACK_LEFT))
TTK_END_LAYOUT

/*
 * Initialization:
 */

MODULE_SCOPE







|
<







518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
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

Changes to generic/ttk/ttkScale.c.

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
 *
 * ttk::scale widget.
 */

#include "tkInt.h"
#include "tkInt.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))

/* Bit fields for OptionSpec mask field:
 */
#define STATE_CHANGED	 	(0x100)		/* -state option changed */

/*
 * 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;

    /*
     * Compatibility/legacy options:
     */
    Tcl_Obj *stateObj;

} ScalePart;

typedef struct
{
    WidgetCore core;
    ScalePart  scale;
} Scale;

static const Tk_OptionSpec ScaleOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scale,scale.commandObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
	offsetof(Scale,scale.variableObj), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Scale,scale.orientObj),
	offsetof(Scale,scale.orient), 0,
	(void *)ttkOrientStrings, STYLE_CHANGED },

    {TK_OPTION_DOUBLE, "-from", "from", "From", "0",
	offsetof(Scale,scale.fromObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
	offsetof(Scale,scale.toObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
	offsetof(Scale,scale.valueObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, offsetof(Scale,scale.lengthObj), TCL_INDEX_NONE, 0, 0,
    	GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Scale,scale.stateObj), TCL_INDEX_NONE,
        0, 0, STATE_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 = (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_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Scale *scalePtr = (Scale *)recordPtr;

    TtkTrackElementState(&scalePtr->core);
}

static void ScaleCleanup(void *recordPtr)
{
    Scale *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 = (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;

    if (mask & STATE_CHANGED) {
	TtkCheckStateOption(&scale->core, scale->scale.stateObj);
    }

    return TCL_OK;
}

/* ScalePostConfigure --
 * 	Post-configuration hook.
 */
static int ScalePostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr,
    TCL_UNUSED(int))
{
    Scale *scale = (Scale *)recordPtr;
    int status = TCL_OK;

    if (scale->scale.variableTrace) {
	status = Ttk_FireTrace(scale->scale.variableTrace);
	if (WidgetDestroyed(&scale->core)) {
	    return TCL_ERROR;
	}






|
|
>








<
<
<
<




















<
<
<
<
<








|


|


|
|

|
|
|


|

|

|

|


<
<
<
<










|




|

















|
<
<

|
<





|












|


















<
<
<
<







<
|
<

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17




18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37





38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68




69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141




142
143
144
145
146
147
148

149

150
151
152
153
154
155
156
157
158
/*
 * 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;
	}
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

    return status;
}

/* ScaleGetLayout --
 *	getLayout hook.
 */
static Ttk_Layout
ScaleGetLayout(Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
{
    Scale *scalePtr = (Scale *)recordPtr;
    return TtkWidgetGetOrientedLayout(
	interp, theme, recordPtr, scalePtr->scale.orientObj);
}

/*
 * TroughBox --
 * 	Returns the inner area of the trough element.







|


|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

    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.
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

    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 = (Scale *)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;
    }







|






|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

    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;
    }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

/* $scale set $newValue
 */
static int
ScaleSetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)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;
    }







|







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

/* $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;
    }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
    return result;
}

static int
ScaleCoordsCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)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_NewWideIntObj(pt.x);
	point[1] = Tcl_NewWideIntObj(pt.y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, point));
    }
    return r;
}

static void ScaleDoLayout(void *clientData)
{
    WidgetCore *corePtr = (WidgetCore *)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 = (Scale *)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);







|

















|
|







|







|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    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);
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

/*
 * ScaleSize --
 * 	Compute requested size of scale.
 */
static int ScaleSize(void *clientData, int *widthPtr, int *heightPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    Scale *scalePtr = (Scale *)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);







|
|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

/*
 * 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);
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "set",         ScaleSetCommand,0 },
    { "get",         ScaleGetCommand,0 },
    { "coords",      ScaleCoordsCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ScaleWidgetSpec =
{
    "TScale",			/* Class name */
    sizeof(Scale),		/* record size */
    ScaleOptionSpecs,		/* option specs */
    ScaleCommands,		/* widget commands */
    ScaleInitialize,		/* initialization proc */
    ScaleCleanup,		/* cleanup proc */







|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    { "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 */

Changes to generic/ttk/ttkScroll.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * 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 "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/* Private data:
 */
#define SCROLL_UPDATE_PENDING  (0x1)
#define SCROLL_UPDATE_REQUIRED (0x2)









|








|

|
|




|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * 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 <tkInt.h>
#include "ttkTheme.h"
#include "ttkWidget.h"

/* Private data:
 */
#define SCROLL_UPDATE_PENDING  (0x1)
#define SCROLL_UPDATE_REQUIRED (0x2)
100
101
102
103
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    if (WidgetDestroyed(corePtr)) {
	Tcl_Release(corePtr);
	return TCL_ERROR;
    }
    Tcl_Release(corePtr);

    if (code != TCL_OK && !Tcl_InterpDeleted(interp)) {
	/* Add error to stack trace.
         * Also set the SCROLL_UPDATE_REQUIRED flag so that a later call to
         * TtkScrolled has an effect. Indeed, the error in the -scrollcommand
         * callback may later be gone, for instance the callback proc got
         * defined in the meantime.
	 */



	Tcl_AddErrorInfo(interp, /* @@@ "horizontal" / "vertical" */
		"\n    (scrolling command executed by ");
	Tcl_AddErrorInfo(interp, Tk_PathName(h->corePtr->tkwin));
	Tcl_AddErrorInfo(interp, ")");
        TtkScrollbarUpdateRequired(h);
    }
    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(interp);
    code = UpdateScrollbar(interp, h);
    if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
	Tcl_BackgroundException(interp, code);
    }
    Tcl_Release(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;
    }







<
<
|
<
<

>
>





<














|


|

|








|







100
101
102
103
104
105
106


107


108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    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;
    }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	    || (h->flags & SCROLL_UPDATE_REQUIRED))
    {
	s->first = first;
	s->last = last;
	s->total = total;

	if (!(h->flags & SCROLL_UPDATE_PENDING)) {
	    Tcl_DoWhenIdle(UpdateScrollbarBG, 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;
}

/* TtkUpdateScrollInfo --
 * 	Call the layoutProc to update the scroll info first, last, and total.
 * 	Do it only if needed, that is when a redisplay is pending (which
 * 	indicates scroll info are possibly out of date).
 */

void TtkUpdateScrollInfo(ScrollHandle h)
{
    if (h->corePtr->flags & REDISPLAY_PENDING) {
        h->corePtr->widgetSpec->layoutProc(h->corePtr);
    }
}

/* 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;

    TtkUpdateScrollInfo(h);
    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;







|
















<
<
<
<
<
<
<
<
<
<
<
<
<












<
<
<
|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183













184
185
186
187
188
189
190
191
192
193
194
195



196
197
198
199
200
201
202
203
	    || (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;
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
		int perPage = s->last - s->first;	/* @@@ */
		newFirst = s->first + count * perPage;
		break;
	    }
	}
    }

    TtkScrollTo(h, newFirst, 0);

    return TCL_OK;
}

void TtkScrollTo(ScrollHandle h, int newFirst, int updateScrollInfo)
{
    Scrollable *s = h->scrollPtr;

    if (updateScrollInfo) {
        TtkUpdateScrollInfo(h);
    }

    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, h);
    }
    ckfree(h);
}








|




|



<
<
<
<
















|

|


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237




238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
		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);
}

Changes to generic/ttk/ttkScrollbar.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * Copyright (c) 2003, Joe English
 *
 * ttk::scrollbar widget.
 */

#include "tkInt.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 const Tk_OptionSpec ScrollbarOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scrollbar, scrollbar.commandObj), TCL_INDEX_NONE, 0, 0, 0},

    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Scrollbar, scrollbar.orientObj),
	offsetof(Scrollbar, scrollbar.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Widget hooks.
 */

static void
ScrollbarInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Scrollbar *sb = (Scrollbar *)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 = (Scrollbar *)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 = (Scrollbar *)recordPtr;
    WidgetCore *corePtr = &sb->core;
    Ttk_Element thumb;
    Ttk_Box thumbBox;
    int thumbWidth, thumbHeight;
    double first, last, size;
    int minSize;







|
>
















|









|


|


|
|
|









|
|
<
<

|
<









|













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
 * 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;

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* $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 = (Scrollbar *)recordPtr;
    Tcl_Obj *firstObj, *lastObj;
    double first, last;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "first last");
	return TCL_ERROR;
    }







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* $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;
    }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* $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 = (Scrollbar *)recordPtr;
    Tcl_Obj *result[2];

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }








|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* $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;
    }

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
 * 	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 = (Scrollbar *)recordPtr;
    double dx, dy;
    double delta = 0.0;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "dx dy");
	return TCL_ERROR;
    }







|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
 * 	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;
    }
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

    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 = (Scrollbar *)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");







|





|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

    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");
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
    { "state",  	TtkWidgetStateCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */
static const 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_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_FILL_BOTH))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE







|



















>
|






>
|







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
    { "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

Changes to generic/ttk/ttkSeparator.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::separator and ttk::sizegrip widgets.
 */

#include "tkInt.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 const Tk_OptionSpec SeparatorOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Separator,separator.orientObj),
	offsetof(Separator,separator.orient),
	0, (void *)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 = (Separator *)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 const WidgetSpec SeparatorWidgetSpec =
{
    "TSeparator",		/* className */
    sizeof(Separator),		/* recordSize */
    SeparatorOptionSpecs,	/* optionSpecs */
    SeparatorCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */






|
>

















|

|
|
|












|



















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
 * 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 */
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    TTK_NODE("Separator.separator", TTK_FILL_BOTH)
TTK_END_LAYOUT

/* +++ Sizegrip widget:
 * 	Has no options or methods other than the standard ones.
 */

static const 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 const WidgetSpec SizegripWidgetSpec =
{
    "TSizegrip",		/* className */
    sizeof(WidgetCore),		/* recordSize */
    SizegripOptionSpecs, 	/* optionSpecs */
    SizegripCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */







|













|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    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 */

Changes to generic/ttk/ttkSquare.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
/* square.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
 *
 * Minimal sample ttk widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#if defined(TTK_SQUARE_WIDGET) || 1

#ifndef DEFAULT_BORDERWIDTH
#define DEFAULT_BORDERWIDTH "2"





|







1
2
3
4
5
6
7
8
9
10
11
12
13
/* 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"
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * 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 const Tk_OptionSpec SquareOptionSpecs[] =
{
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
     DEFAULT_BORDERWIDTH, offsetof(Square,square.borderWidthObj), TCL_INDEX_NONE,
     0,0,GEOMETRY_CHANGED },
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
     DEFAULT_BACKGROUND, offsetof(Square,square.foregroundObj),
     TCL_INDEX_NONE, 0, 0, 0},

    {TK_OPTION_PIXELS, "-width", "width", "Width",
     "50", offsetof(Square,square.widthObj), TCL_INDEX_NONE, 0, 0,
     GEOMETRY_CHANGED},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
     "50", offsetof(Square,square.heightObj), TCL_INDEX_NONE, 0, 0,
     GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
     offsetof(Square,square.paddingObj), TCL_INDEX_NONE,
     TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
     NULL, offsetof(Square,square.reliefObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
     NULL, offsetof(Square,square.anchorObj), TCL_INDEX_NONE, 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







|


|


|
|
|

|


|

|

|

|

|
|

|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

    /*
     * Adjust the position of the square element within the widget according
     * to the -anchor option.
     */

    if (squareNode) {
	Square *squarePtr = (Square *)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);







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

    /*
     * 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);
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    { "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 const 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 const Ttk_ElementOptionSpec SquareElementOptions[] =
{
    { "-background", TK_OPTION_BORDER, offsetof(SquareElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-foreground", TK_OPTION_BORDER, offsetof(SquareElement,foregroundObj),
    	DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SquareElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(SquareElement,reliefObj),
    	"raised" },
    { "-width",  TK_OPTION_PIXELS, offsetof(SquareElement,widthObj), "20"},
    { "-height", TK_OPTION_PIXELS, offsetof(SquareElement,heightObj), "20"},
    { NULL, TK_OPTION_BOOLEAN, 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(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    SquareElement *square = (SquareElement *)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(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(unsigned int))
{
    SquareElement *square = (SquareElement *)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 const 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







|




|















|
















|

|

|

|

|

|
|
|









<
|
<
|
<
<

|













<
|
<
|
<
<

|











|

















|








|




|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201

202


203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218

219


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    { "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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/* 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 */








|


|








283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/* 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 */

Changes to generic/ttk/ttkState.c.

1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
/*
 * Tk widget state utilities.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 */



#include "tkInt.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[] =







>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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[] =
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
	for (j = 0; stateNames[j] != 0; ++j) {
	    if (strcmp(stateName, stateNames[j]) == 0)
		break;
	}

    	if (stateNames[j] == 0) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Invalid state name %s", stateName));
		Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATE", NULL);
	    }
	    return TCL_ERROR;
	}

	if (on) {
	    onbits |= (1<<j);
	} else {







|
|
<







94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
	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 {
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

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;
    int 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 = (char *)ckalloc(len);
	objPtr->length = len-1;
	strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1);
	objPtr->bytes[len-1] = '\0';
    } else {
	/* empty string */
	objPtr->length = 0;
	objPtr->bytes = (char *)ckalloc(1);
	*objPtr->bytes = '\0';
    }

    Tcl_DStringFree(&result);
}

Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)







|
<















|

|




|







125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

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)
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
	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_SetObjResult(interp, Tcl_NewStringObj("No match in state map", -1));
	Tcl_SetErrorCode(interp, "TTK", "STATE", "UNMATCHED", NULL);
    }
    return NULL;
}

/* Ttk_GetStateMapFromObj --
 * 	Returns a Ttk_StateMap from a Tcl_Obj*.
 * 	Since a Ttk_StateMap is just a specially-formatted Tcl_Obj,







>
|
<







212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
	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,
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    int j, status;

    status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    if (nSpecs % 2 != 0) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "State map must have an even number of elements", -1));
	    Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATEMAP", NULL);
	}
	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(const Ttk_StateTable *map, unsigned int state)
{
    while ((state & map->onBits) != map->onBits
	    || (~state & map->offBits) != map->offBits)
    {
	++map;
    }
    return map->index;
}

/*EOF*/







|
|
|
|
<
















|










236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
    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*/

Changes to generic/ttk/ttkStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * This file is (mostly) automatically generated from ttk.decls.
 * It is compiled and linked in with the ttk package proper.
 */

#include "tkInt.h"
#include "ttkTheme.h"

MODULE_SCOPE const TtkStubs ttkStubs;

#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#define Ttk_GetOrientFromObj 0
#endif

#ifdef __GNUC__
/*
 * The rest of this file shouldn't warn about deprecated functions; they're
 * there because we intend them to be so and know that this file is OK to
 * touch those fields.
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
/* !BEGIN!: Do not edit below this line. */

const TtkStubs ttkStubs = {
    TCL_STUB_MAGIC,
    TTK_STUBS_EPOCH,
    TTK_STUBS_REVISION,
    0,





|




<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10












11
12
13
14
15
16
17
/*
 * 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,

Changes to generic/ttk/ttkStubLib.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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 "tkInt.h"

#define USE_TTK_STUBS 1
#include "ttkTheme.h"

MODULE_SCOPE const TtkStubs *ttkStubsPtr;
const TtkStubs *ttkStubsPtr = NULL;









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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;

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
    void *pkgClientData = NULL;
    const char *actualVersion = Tcl_PkgRequireEx(
	interp, packageName, version, exact, &pkgClientData);
    const TtkStubs *stubsPtr = (const TtkStubs *)pkgClientData;

    if (!actualVersion) {
	return NULL;
    }

    if (!stubsPtr) {
	errMsg = "missing stub table pointer";







|


|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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";
63
64
65
66
67
68
69
70
71
72
73
74

error:
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp,
	"Error loading ", packageName, " package",
	" (requested version '", version,
	"', loaded version '", actualVersion, "'): ",
	errMsg,
	NULL);
    return NULL;
}








|




63
64
65
66
67
68
69
70
71
72
73
74

error:
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp,
	"Error loading ", packageName, " package",
	" (requested version '", version,
	"', loaded version '", actualVersion, "'): ",
	errMsg, 
	NULL);
    return NULL;
}

Changes to generic/ttk/ttkTagSet.c.

1
2
3
4
5
6


7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * Tag tables.  3/4-baked, work in progress.
 *
 * Copyright (C) 2005, Joe English.  Freely redistributable.
 */



#include "tkInt.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 */
    const Tk_OptionSpec	*optionSpecs;	/* ... */
    Tk_OptionTable	optionTable;	/* ... */
    int         	recordSize;	/* size of tag record */
    int 		nTags;		/* #tags defined so far */
    Tcl_HashTable	tags;		/* defined tags */
};

/*------------------------------------------------------------------------






>
>
|
>














|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * 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 */
};

/*------------------------------------------------------------------------
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    return tag;
}

static void DeleteTag(Ttk_TagTable tagTable, Ttk_Tag tag)
{
    Tk_FreeConfigOptions(tag->tagRecord,tagTable->optionTable,tagTable->tkwin);
    ckfree(tag->tagRecord);
    ckfree(tag);
}

/*------------------------------------------------------------------------
 * +++ Tag tables.
 */

Ttk_TagTable Ttk_CreateTagTable(
    Tcl_Interp *interp, Tk_Window tkwin,
    const 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, (Ttk_Tag)Tcl_GetHashValue(entryPtr));
	entryPtr = Tcl_NextHashEntry(&search);
    }

    Tcl_DeleteHashTable(&tagTable->tags);
    ckfree(tagTable);
}

void Ttk_DeleteTagFromTable(Ttk_TagTable tagTable, Ttk_Tag tag)
{
    Tcl_HashEntry *entryPtr;

    entryPtr = Tcl_FindHashEntry(&tagTable->tags, tag->tagName);
    if (entryPtr != NULL) {
        DeleteTag(tagTable, tag);
        Tcl_DeleteHashEntry(entryPtr);
    }
}

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 = (char *)Tcl_GetHashKey(&tagTable->tags, entryPtr);
	Tcl_SetHashValue(entryPtr, NewTag(tagTable,tagName));
    }
    return (Ttk_Tag)Tcl_GetHashValue(entryPtr);
}

Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable tagTable, Tcl_Obj *objPtr)
{
    return Ttk_GetTag(tagTable, Tcl_GetString(objPtr));
}








|








|


















|




|
<
<
<
<
<
<
<
<
<
<
<









|


|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83











84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    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));
}

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
 * 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(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;







|










|



|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 * 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;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
	    NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1));
    }
    return result;
}

void Ttk_FreeTagSet(Ttk_TagSet tagset)
{
    ckfree(tagset->tags);
    ckfree(tagset);
}

/* Ttk_TagSetContains -- test if tag set contains a tag.
 */
int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag)
{
    int i;







|
|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	    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;
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
{
    int i;
    for (i = 0; i < tagset->nTags; ++i) {
	if (tagset->tags[i] == tag) {
	    return 0;
	}
    }
    tagset->tags = (Ttk_Tag *)ckrealloc(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.
 *







|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
{
    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.
 *
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
{
    const int LOWEST_PRIORITY = 0x7FFFFFFF;
    int i, j;

    memset(record, 0, tagTable->recordSize);

    for (i = 0; tagTable->optionSpecs[i].type != TK_OPTION_END; ++i) {
	const Tk_OptionSpec *optionSpec = tagTable->optionSpecs + i;
	TkSizeT 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)
{
    const Tk_OptionSpec *optionSpec = tagTable->optionSpecs;

    while (optionSpec->type != TK_OPTION_END) {
	TkSizeT 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;
    }
}








|
|















|


|











268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
{
    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;
    }
}

Changes to generic/ttk/ttkTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12


13

14
15
16
17
18
19
20
/*
 * 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 "tkInt.h"

#include "ttkThemeInt.h"

#define PKG_ASSOC_KEY "Ttk"

/*------------------------------------------------------------------------
 * +++ Styles.
 *












>
>
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * 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.
 *
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    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(void)
{
    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 = (Ttk_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_Obj *)Tcl_GetHashValue(entryPtr);
	Tcl_DecrRefCount(defaultValue);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&stylePtr->defaultsTable);

    Ttk_FreeLayoutTemplate(stylePtr->layoutTemplate);

    ckfree(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 = (Ttk_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_Obj *)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 */
    const 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 */
};








|


















|







|







|












|

















|













|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    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(void)
{
    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 */
};

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    const Tk_OptionSpec *optionSpec = TkGetOptionSpec(optionName, optionTable);

    if (!optionSpec)
	return 0;

    /* Make sure widget option has a Tcl_Obj* entry:
     */
    if (optionSpec->objOffset == TCL_INDEX_NONE) {
	return 0;
    }

    /* Grrr.  Ignore accidental mismatches caused by prefix-matching:
     */
    if (strcmp(optionSpec->optionName, optionName)) {
	return 0;







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    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;
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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) {
	const Ttk_ElementOptionSpec *e = elementClass->specPtr->options+i;
	optionMap[i] = TTKGetOptionSpec(e->optionName, optionTable, e->type);
    }

    return optionMap;
}

/* GetOptionMap --







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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 --
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
	&elementClass->optMapCache, (void*)optionTable, &isNew);

    if (isNew) {
	optionMap = BuildOptionMap(elementClass, optionTable);
	Tcl_SetHashValue(entryPtr, optionMap);
    } else {
	optionMap = (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, const 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 {







|











|

|
>















|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    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 {
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
     * Free default values:
     */
    for (i = 0; i < elementClass->nResources; ++i) {
	if (elementClass->defaultValues[i]) {
	    Tcl_DecrRefCount(elementClass->defaultValues[i]);
	}
    }
    ckfree(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(elementClass);
}

/*------------------------------------------------------------------------
 * +++ Themes.
 */

static int ThemeEnabled(
    TCL_UNUSED(Ttk_Theme),
    TCL_UNUSED(void *))
{
    /* Default ThemeEnabledProc -- always return true */
    return 1;
}

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 =
	(const char *)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 = (Ttk_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 = (Style *)Tcl_GetHashValue(entryPtr);
	FreeStyle(stylePtr);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&themePtr->styleTable);

    /*
     * Free theme record:
     */
    ckfree(themePtr);

    return;
}

/*
 * Element constructors.
 */







|












|






|
<
<
<

<
<














|
















|
















|










|








|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298



299


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
     * 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.
 */
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
typedef struct CleanupStruct {
    void *clientData;
    Ttk_CleanupProc *cleanupProc;
    struct CleanupStruct *next;
} Cleanup;

/*------------------------------------------------------------------------
 * +++ 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(void *);	/* Forward */

/* Ttk_StylePkgFree --
 *	Cleanup procedure for StylePackageData.
 */
static void Ttk_StylePkgFree(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    StylePackageData *pkgPtr = (StylePackageData *)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 = (Theme *)Tcl_GetHashValue(entryPtr);
	FreeTheme(themePtr);
	entryPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&pkgPtr->themeTable);

    /*
     * Free element constructor table:







|













|




|
<
<

|
















|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410


411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
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:
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
    /*
     * Call all registered cleanup procedures:
     */
    cleanup = pkgPtr->cleanupList;
    while (cleanup) {
	Cleanup *next = cleanup->next;
	cleanup->cleanupProc(cleanup->clientData);
	ckfree(cleanup);
	cleanup = next;
    }

    ckfree(pkgPtr);
}

/*
 * GetStylePackageData --
 * 	Look up the package data registered with the interp.
 */

static StylePackageData *GetStylePackageData(Tcl_Interp *interp)
{
    return (StylePackageData *)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 = (StylePackageData *)GetStylePackageData(interp);
    Cleanup *cleanup = (Cleanup *)ckalloc(sizeof(*cleanup));

    cleanup->clientData = clientData;
    cleanup->cleanupProc = cleanupProc;
    cleanup->next = pkgPtr->cleanupList;
    pkgPtr->cleanupList = cleanup;
}








|



|









|














|
|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    /*
     * 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;
}

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
 * 	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 = (StylePackageData *)clientData;

    int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(pkgPtr->interp, code);
    }
    pkgPtr->themeChangePending = 0;
}

/*
 * ThemeChanged --
 * 	Schedule a call to ThemeChanged if one is not already pending.







|

|
<
|







503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
 * 	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.
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
    StylePackageData *pkgPtr = GetStylePackageData(interp);
    Tcl_HashEntry *entryPtr;
    int newEntry;
    Theme *themePtr;

    entryPtr = Tcl_CreateHashEntry(&pkgPtr->themeTable, name, &newEntry);
    if (!newEntry) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Theme %s already exists", name));
	Tcl_SetErrorCode(interp, "TTK", "THEME", "EXISTS", NULL);
	return NULL;
    }

    /*
     * Initialize new theme:
     */
    if (!parent) parent = pkgPtr->defaultTheme;







|
|
<







545
546
547
548
549
550
551
552
553

554
555
556
557
558
559
560
    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;
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
 * 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 record */
    const char *name)		/* theme name */
{
    Tcl_HashEntry *entryPtr;

    entryPtr = Tcl_FindHashEntry(&pkgPtr->themeTable, name);
    if (!entryPtr) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"theme \"%s\" doesn't exist", name));
	Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "THEME", name, NULL);
	return NULL;
    }

    return (Ttk_Theme)Tcl_GetHashValue(entryPtr);
}

/*
 * Ttk_GetTheme --
 *	Public interface to LookupTheme.
 */
Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *themeName)







|






|
|
<



|







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605
606
607
 * 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)
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

	if (dot) {
	    stylePtr->parentStyle = Ttk_GetStyle(themePtr, dot + 1);
	} else {
	    stylePtr->parentStyle = themePtr->rootStyle;
	}

	stylePtr->styleName = (const char *)Tcl_GetHashKey(&themePtr->styleTable, entryPtr);
	stylePtr->cache = stylePtr->parentStyle->cache;
	Tcl_SetHashValue(entryPtr, stylePtr);
	return stylePtr;
    }
    return (Ttk_Style)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.
 */







|




|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720

	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.
 */
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
    const char *dot = elementName;

    /*
     * Check if element has already been registered:
     */
    entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, elementName);
    if (entryPtr) {
	return (Ttk_ElementClass *)Tcl_GetHashValue(entryPtr);
    }

    /*
     * Check generic names:
     */
    while (!entryPtr && ((dot = strchr(dot, '.')) != NULL)) {
	dot++;
	entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, dot);
    }
    if (entryPtr) {
	return (Ttk_ElementClass *)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 (Ttk_ElementClass *)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, TCL_UNUSED(void *),
    Ttk_Theme theme, const char *elementName,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Theme fromTheme;
    Ttk_ElementClass *fromElement;

    if (objc <= 0 || objc > 2) {







|










|















|
















|




















|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
    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) {
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
 *	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 */
    const 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_SetObjResult(interp, Tcl_ObjPrintf(
		"Internal error: Ttk_RegisterElement (%s): invalid version",
		name));
	    Tcl_SetErrorCode(interp, "TTK", "REGISTER_ELEMENT", "VERSION",
		NULL);
	}
	return 0;
    }

    entryPtr = Tcl_CreateHashEntry(&theme->elementTable, name, &newEntry);
    if (!newEntry) {
	if (interp) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Duplicate element %s", name));
	    Tcl_SetErrorCode(interp, "TTK", "REGISTER_ELEMENT", "DUPE", NULL);
	}
	return 0;
    }

    name = (char *)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, const Ttk_ElementSpec *specPtr, void *clientData)
{
    return Ttk_RegisterElement(NULL, theme, name, specPtr, clientData)
	   ? TCL_OK : TCL_ERROR;
}

/*------------------------------------------------------------------------
 * +++ Element record initialization.







|









|
|
|
<









<
|
<




|










|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
889
890

891

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
 *	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.
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
 * 	Tcl_Obj * reference counts are _NOT_ adjusted.
 */

static
int InitializeElementRecord(
    Ttk_ElementClass *eclass,	/* Element instance to initialize */
    Ttk_Style style,		/* Style table */
    void *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 */
{
    void *elementRecord = eclass->elementRecord;
    OptionMap optionMap = GetOptionMap(eclass,optionTable);
    int nResources = eclass->nResources;
    Ttk_ResourceCache cache = style->cache;
    const Ttk_ElementOptionSpec *elementOption = eclass->specPtr->options;

    int i;
    for (i=0; i<nResources; ++i, ++elementOption) {
	Tcl_Obj **dest = (Tcl_Obj **)
	    ((char *)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 **)
		((char *)widgetRecord + optionMap[i]->objOffset);
	}

	if (widgetValue) {
	    *dest = widgetValue;
	} else if (dynamicSetting) {
	    *dest = dynamicSetting;
	} else {







|




|



|




|







|







964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
 * 	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 {
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
 *	Compute the requested size of the given element.
 */

void
Ttk_ElementSize(
    Ttk_ElementClass *eclass,		/* Element to query */
    Ttk_Style style,			/* Style settings */
    void *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 */
{







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
 *	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 */
{
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
 *	Draw the given widget element in a given drawable area.
 */

void
Ttk_DrawElement(
    Ttk_ElementClass *eclass,		/* Element instance */
    Ttk_Style style,			/* Style settings */
    void *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)







|







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
 *	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)
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
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((const char *)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((const char *)Tcl_GetHashKey(ht, entryPtr),-1);
	Tcl_Obj *valueObj = (Tcl_Obj *)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,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;

    if (objc < 3) {
usage:







|



















|
|















|




|







1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
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:
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
}

/* + style configure $style -option ?value...
 */
static int StyleConfigureCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;

    if (objc < 3) {
usage:







|







1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
}

/* + 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:
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
}

/* + style lookup $style -option ?statespec? ?defaultValue?
 */
static int StyleLookupCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)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) {







|







1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
}

/* + 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) {
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409

    return TCL_OK;
}

static int StyleThemeCurrentCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)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 = (Theme *)Tcl_GetHashValue(entryPtr);
	if (ptr == pkgPtr->currentTheme) {
	    name = (char *)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));
	Tcl_SetErrorCode(interp, "TTK", "THEME", "NAMELESS", NULL);
	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 = (StylePackageData *)clientData;
    static const char *const 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_GetIndexFromObjStruct(interp, objv[i], optStrings,
	    sizeof(char *), "option", 0, &option) != TCL_OK)
	{
	    return TCL_ERROR;
	}

	switch (option) {
	    case OP_PARENT:
		parentTheme = LookupTheme(







|











|

|






|
|
<












|
|
















|
|







1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399

    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(
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
    }
}

/* + style theme names --
 * 	Return list of registered themes.
 */
static int StyleThemeNamesCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    StylePackageData *pkgPtr = (StylePackageData *)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,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme oldTheme = pkgPtr->currentTheme;
    Ttk_Theme newTheme;
    int status;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "theme script");
	return TCL_ERROR;







|
<
<
<

|
<










|




|







1428
1429
1430
1431
1432
1433
1434
1435



1436
1437

1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
    }
}

/* + 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;
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
}

/* + style element create name type ? ...args ?
 */
static int StyleElementCreateCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)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_SetObjResult(interp, Tcl_ObjPrintf(
		"No such element type %s", factoryName));
	Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT_TYPE", factoryName,
		NULL);
	return TCL_ERROR;
    }

    recPtr = (FactoryRec *)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 = (StylePackageData *)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 = (StylePackageData *)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) {
	const Ttk_ElementSpec *specPtr = elementClass->specPtr;
	const 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_SetObjResult(interp, Tcl_ObjPrintf(
	"element %s not found", elementName));
    Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT", elementName, NULL);
    return TCL_ERROR;
}

/* + style layout name ?spec?
 */
static int StyleLayoutCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)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_SetObjResult(interp, Tcl_ObjPrintf(
		"Layout %s not found", layoutName));
	    Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", layoutName,
		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,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "?theme?");
	return TCL_ERROR;
    }








|















<
|
<
<



|











|















|












|
|












|
<
<








|














|
<
<
<



















|




|







1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494

1495


1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554


1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578



1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
}

/* + 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;
    }

1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
    { "theme", 0, StyleThemeEnsemble },
    { "element", 0, StyleElementEnsemble },
    { NULL, 0, 0 }
};

static int
StyleObjCmd(
    ClientData clientData,		/* 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,







|







|







1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
    { "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,
1713
1714
1715
1716
1717
1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
 *	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;







|
>







1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
 *	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;

Changes to generic/ttk/ttkTheme.h.

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#define TTK_VERSION    TK_VERSION
#define TTK_PATCH_LEVEL TK_PATCH_LEVEL

/*------------------------------------------------------------------------
 * +++ Defaults for element option specifications.
 */
#define DEFAULT_FONT 		"TkDefaultFont"
#ifdef MAC_OSX_TK
#define DEFAULT_BACKGROUND	"systemTextBackgroundColor"
#define DEFAULT_FOREGROUND	"systemTextColor"
#else
#define DEFAULT_BACKGROUND	"#d9d9d9"
#define DEFAULT_FOREGROUND	"black"
#endif
/*------------------------------------------------------------------------
 * +++ Widget states.
 * 	Keep in sync with stateNames[] in tkstate.c.
 */

typedef unsigned int Ttk_State;








<
<
<
<


|







25
26
27
28
29
30
31




32
33
34
35
36
37
38
39
40
41
#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;

71
72
73
74
75
76
77



78
79
80
81
82



83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103








104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121



122
123
124
125
126
127
128

#define Ttk_StateMatches(state, spec) \
    (((state) & ((spec)->onbits|(spec)->offbits)) == (spec)->onbits)

#define Ttk_ModifyState(state, spec) \
    (((state) & ~(spec)->offbits) | (spec)->onbits)




/*------------------------------------------------------------------------
 * +++ State maps and state tables.
 */
typedef Tcl_Obj *Ttk_StateMap;




/*
 * 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;



/*------------------------------------------------------------------------
 * +++ Padding.
 * 	Used to represent internal padding and borders.
 */
typedef struct
{
    short left;
    short top;
    short right;
    short bottom;
} Ttk_Padding;









#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;




#define Ttk_WinBox(tkwin) Ttk_MakeBox(0,0,Tk_Width(tkwin),Tk_Height(tkwin))

/*------------------------------------------------------------------------
 * +++ Layout utilities.
 */
typedef enum {







>
>
>





>
>
>









>
>












>
>
>
>
>
>
>
>


















>
>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

#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 {
142
143
144
145
146
147
148

149
150
151
152
153
154
155
/*
 * 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 Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky);

/*
 * Extra bits for position specifications (combine -side and -sticky)
 */

typedef unsigned int Ttk_PositionSpec;	/* See below */







>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * 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 */
168
169
170
171
172
173
174






175
176
177
178
179
180
181
182
183
184
185
186







187
188
189
190
191
192
193


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231




232
233
234
235



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#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_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;








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);



/*------------------------------------------------------------------------
 * +++ 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);

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

typedef struct Ttk_ElementOptionSpec
{
    const char *optionName;		/* Command-line name of the widget option */
    Tk_OptionType type; 	/* Accepted option types */
    TkSizeT 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 */
    const Ttk_ElementOptionSpec *options;	/* List of options, NULL-terminated */
    Ttk_ElementSizeProc *size;		/* Compute min size and padding */
    Ttk_ElementDrawProc *draw;  	/* Draw the element */
} Ttk_ElementSpec;





typedef int (*Ttk_ElementFactory)
	(Tcl_Interp *, void *clientData,
	 Ttk_Theme, const char *elementName, int objc, Tcl_Obj *const objv[]);




/*
 * 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 const Ttk_ElementOptionSpec TtkNullElementOptions[];
MODULE_SCOPE Ttk_ElementSpec ttkNullElementSpec;

/*------------------------------------------------------------------------
 * +++ Layout templates.
 */
typedef struct {
    const char *	elementName;







>
>
>
>
>
>












>
>
>
>
>
>
>







>
>












<
<
<
<
<
<
<
<




|








|




>
>
>
>




>
>
>













|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236








237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#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;
269
270
271
272
273
274
275



276
277
278
279
280
281
282
				{ 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_RegisterLayouts(
    Ttk_Theme theme, Ttk_LayoutSpec layoutTable);

/*------------------------------------------------------------------------
 * +++ Layout instances.
 */








>
>
>







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
				{ 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.
 */

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
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 *, Ttk_ButtonDefaultState *);

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 *, Ttk_Compound *);

typedef enum { 		/* -orient option values */
    TTK_ORIENT_HORIZONTAL,
    TTK_ORIENT_VERTICAL
} Ttk_Orient;

MODULE_SCOPE int		TtkGetOrientFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Ttk_Orient *orient);

/*------------------------------------------------------------------------
 * +++ Utilities.
 */

typedef struct TtkEnsemble {
    const char *name;			/* subcommand name */
    Tcl_ObjCmdProc *command; 		/* subcommand implementation, OR: */







|













|






<
<
<







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411



412
413
414
415
416
417
418
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: */

Changes to generic/ttk/ttkThemeInt.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

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, void *recordPtr, Tk_OptionTable,
	Tk_Window tkwin, Ttk_State state,
	int *widthPtr, int *heightPtr, Ttk_Padding*);
MODULE_SCOPE void Ttk_DrawElement(
	Ttk_ElementClass *, Ttk_Style, void *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 *);







|



|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

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 *);

Changes to generic/ttk/ttkTrace.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * 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 "tkInt.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. */
    TCL_UNUSED(const char *),	/* name1 */
    TCL_UNUSED(const char *),	/* name2 */
    int flags)			/* Information about what happened. */
{
    Ttk_TraceHandle *tracePtr = (Ttk_TraceHandle *)clientData;
    const char *name, *value;
    Tcl_Obj *valuePtr;

    if (Tcl_InterpDeleted(interp)) {
	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(tracePtr);
	    return NULL;
	}
	Tcl_TraceVar2(interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		VarTraceProc, clientData);
	tracePtr->callback(tracePtr->clientData, NULL);
	return NULL;
    }

    /*





|



|


















|
|


|



|
















|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * 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;
    }

    /*
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 */
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_TraceVar2(interp, Tcl_GetString(varnameObj),
	    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VarTraceProc, h);

    if (status != TCL_OK) {
	Tcl_DecrRefCount(h->varnameObj);
	ckfree(h);
	return NULL;
    }

    return h;
}

/*







|








|
|
|



|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 */
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;
}

/*
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

	/*
	 * 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 == 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_UntraceVar2(h->interp, Tcl_GetString(h->varnameObj),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		VarTraceProc, h);
	Tcl_DecrRefCount(h->varnameObj);
	ckfree(h);
    }
}

/*
 * Ttk_FireTrace --
 * 	Executes a trace handle as if the variable has been written.
 *







|












|
|
|

|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

	/*
	 * 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.
 *

Changes to generic/ttk/ttkTrack.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * 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 <Button> events,
 * and remains "active" and "pressed" until the corresponding
 * <ButtonRelease> event.
 *
 * TODO: Handle "chords" properly (e.g., <B1-Button-2>)
 */

#include "tkInt.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 */







|



|


|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * 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 */
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    | EnterWindowMask
    | StructureNotifyMask
    ;

static void
ElementStateEventProc(ClientData clientData, XEvent *ev)
{
    ElementStateTracker *es = (ElementStateTracker *)clientData;
    Ttk_Layout layout = es->corePtr->layout;
    Ttk_Element element;

    /* Guard against dangling pointers [#2431428]
     */
    if (es->tracking != layout) {
	es->pressedElement = es->activeElement = 0;







|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    | 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;
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
 * 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);
}








|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
 * 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);
}

Changes to generic/ttk/ttkTreeview.c.

1
2
3
4
5
6


7
8
9
10
11
12
13
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */



#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#define DEF_TREE_ROWS		"10"
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"






>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */

#include <string.h>
#include <stdio.h>
#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#define DEF_TREE_ROWS		"10"
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    Ttk_TagSet	tagset;
    Ttk_ImageSpec *imagespec;
};

#define ITEM_OPTION_TAGS_CHANGED	0x100
#define ITEM_OPTION_IMAGE_CHANGED	0x200

static const Tk_OptionSpec ItemOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeItem,textObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(TreeItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED },
    {TK_OPTION_STRING, "-values", "values", "Values",
	NULL, offsetof(TreeItem,valuesObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_BOOLEAN, "-open", "open", "Open",
	"0", offsetof(TreeItem,openObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-tags", "tags", "Tags",
	NULL, offsetof(TreeItem,tagsObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_TAGS_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/* Forward declaration */
static void RemoveTag(TreeItem *, Ttk_Tag);

/* + 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;







|

|


|


|


|


|


|


<
<
<





|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83



84
85
86
87
88
89
90
91
92
93
94
95
96
    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;
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    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(item);
}

static void FreeItemCB(void *clientData) { FreeItem((TreeItem *)clientData); }

/* + DetachItem --
 * 	Unlink an item from the tree.
 */
static void DetachItem(TreeItem *item)
{
    if (item->parent && item->parent->children == item)







|


|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    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)
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    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 const Tk_OptionSpec TagOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	NULL, offsetof(DisplayItem,textObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(DisplayItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	NULL, offsetof(DisplayItem,anchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},	/* <<NOTE-ANCHOR>> */
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
	NULL, offsetof(DisplayItem,backgroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(DisplayItem,foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(DisplayItem,fontObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/*------------------------------------------------------------------------
 * +++ Columns.
 *
 * There are separate option tables associated with the column record:
 * ColumnOptionSpecs is for configuring the column,







|

|


|


|


|


|


|


|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    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,
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    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 const Tk_OptionSpec ColumnOptionSpecs[] = {
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_COLWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,width),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-minwidth", "minWidth", "MinWidth",
	DEF_MINWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,minWidth),
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch",
	"1", TCL_INDEX_NONE, offsetof(TreeColumn,stretch),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(TreeColumn,anchorObj), TCL_INDEX_NONE,	/* <<NOTE-ANCHOR>> */
	0,0,0 },
    {TK_OPTION_STRING, "-id", "id", "ID",
	NULL, offsetof(TreeColumn,idObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,READONLY_OPTION },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

static const Tk_OptionSpec HeadingOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeColumn,headingObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	"", offsetof(TreeColumn,headingImageObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"center", offsetof(TreeColumn,headingAnchorObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-command", "", "",
	"", offsetof(TreeColumn,headingCommandObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "state", "", "",
	"", offsetof(TreeColumn,headingStateObj), TCL_INDEX_NONE,
	0,0,STATE_CHANGED },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 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 *const showStrings[] = {
    "tree", "headings", NULL
};

static int GetEnumSetFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    const char *const 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_GetIndexFromObjStruct(interp, objv[i], table,
		sizeof(char *), "value", TCL_EXACT, &index))
	{
	    return TCL_ERROR;
	}
	result |= (1 << index);
    }

    *resultPtr = result;







|

|


|


|
|

|


|

|


|

|


|


|


|


|

|












|






|











|
|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
    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;
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

#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 *const SelectModeStrings[] = { "none", "browse", "extended", NULL };

static const Tk_OptionSpec TreeviewOptionSpecs[] = {
    {TK_OPTION_STRING, "-columns", "columns", "Columns",
	"", offsetof(Treeview,tree.columnsObj), TCL_INDEX_NONE,
	0, 0,COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ },
    {TK_OPTION_STRING, "-displaycolumns","displayColumns","DisplayColumns",
	"#all", offsetof(Treeview,tree.displayColumnsObj), TCL_INDEX_NONE,
	0, 0,DCOLUMNS_CHANGED | GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEFAULT_SHOW, offsetof(Treeview,tree.showObj), TCL_INDEX_NONE,
	0, 0,SHOW_CHANGED | GEOMETRY_CHANGED },

    {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode",
	"extended", offsetof(Treeview,tree.selectModeObj), TCL_INDEX_NONE,
	0, (void *)SelectModeStrings, 0 },

    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TREE_ROWS, offsetof(Treeview,tree.heightObj), TCL_INDEX_NONE,
	0, 0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Treeview,tree.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.xscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.yscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------







|

|

|
|

|
|

|
|


|
|


|
|

|



|


|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

#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)
};

/*------------------------------------------------------------------------
524
525
526
527
528
529
530
531
532
533
534
535
536
537

538
539
540

541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
    int columnIndex;

    /* Check for named column:
     */
    entryPtr = Tcl_FindHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnIDObj));
    if (entryPtr) {
	return (TreeColumn *)Tcl_GetHashValue(entryPtr);
    }

    /* Check for number:
     */
    if (Tcl_GetIntFromObj(NULL, columnIDObj, &columnIndex) == TCL_OK) {
	if (columnIndex < 0 || columnIndex >= tv->tree.nColumns) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Column index %s out of bounds",
		    Tcl_GetString(columnIDObj)));

	    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLBOUND", NULL);
	    return NULL;
	}

	return tv->tree.columns + columnIndex;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"Invalid column index %s", Tcl_GetString(columnIDObj)));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", 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_SetObjResult(interp, Tcl_ObjPrintf(
	    "Column %s out of range", Tcl_GetString(columnIDObj)));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", 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_SetObjResult(interp, Tcl_ObjPrintf(
		"Item %s not found", itemName));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "ITEM", NULL);
	return 0;
    }
    return (TreeItem *)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(items);
	    return NULL;
	}
    }
    items[i] = NULL;
    return items;
}

/* + ItemName --
 * 	Returns the item's ID.
 */
static const char *ItemName(Treeview *tv, TreeItem *item)
{
    return (const char *)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)







|






>
|
|
|
>
|





>
|
|
|

















>
|
|
|

















|
|
<


|




















|



|












|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    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)
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

    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(tv->tree.columns);
	tv->tree.columns = 0;
    }
}

/* + TreeviewInitColumns --
 *	Initialize column data when -columns changes.
 *	Returns: TCL_OK or TCL_ERROR;







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

    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;
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695
     */
    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);







>
|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
     */
    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);
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
    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(displayColumns);
		return TCL_ERROR;
	    }
	}
    }
    displayColumns[0] = &tv->tree.column0;

    if (tv->tree.displayColumns)
	ckfree(tv->tree.displayColumns);
    tv->tree.displayColumns = displayColumns;
    tv->tree.nDisplayColumns = ndcols + 1;

    return TCL_OK;
}

/*------------------------------------------------------------------------







|




|



|







|







729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
    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;
}

/*------------------------------------------------------------------------
788
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
 * 	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;
    }
}







|
|
>







791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
 * 	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;
    }
}
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

static TreeItem *IdentifyItem(Treeview *tv, int y); /*forward*/

static const unsigned long TreeviewBindEventMask =
      KeyPressMask|KeyReleaseMask
    | ButtonPressMask|ButtonReleaseMask
    | PointerMotionMask|ButtonMotionMask
    | VirtualEventMask
    ;

static void TreeviewBindEventProc(void *clientData, XEvent *event)
{
    Treeview *tv = (Treeview *)clientData;
    TreeItem *item = NULL;
    Ttk_TagSet tagset;

    /*
     * Figure out where to deliver the event.
     */
    switch (event->type)







|








|







923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

/*------------------------------------------------------------------------
 * +++ 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)
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup.
 */

static void TreeviewInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Treeview *tv = (Treeview *)recordPtr;
    int unused;

    tv->tree.itemOptionTable =
	Tk_CreateOptionTable(interp, ItemOptionSpecs);
    tv->tree.columnOptionTable =
	Tk_CreateOptionTable(interp, ColumnOptionSpecs);
    tv->tree.headingOptionTable =







|







984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

/*------------------------------------------------------------------------
 * +++ 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 =
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
     */
    tv->tree.treeArea = tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
    tv->tree.slack = 0;
}

static void TreeviewCleanup(void *recordPtr)
{
    Treeview *tv = (Treeview *)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)
	ckfree((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 = (Treeview *)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;
    }








|














|

















|















|
|
|
>







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
     */
    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;
    }

1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
    int objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;
    Ttk_ImageSpec *newImageSpec = NULL;
    Ttk_TagSet newTagSet = NULL;

    if (Tk_SetOptions(interp, item, tv->tree.itemOptionTable,
		objc, objv, tv->core.tkwin, &savedOptions, &mask)
		!= TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Make sure that -values is a valid list:







|







1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
    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:
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237

1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
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, column,
	    tv->tree.columnOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    if (mask & READONLY_OPTION) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Attempt to change read-only option", -1));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "READONLY", 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);
        } else {

	    RecomputeSlack(tv);
	    ResizeColumns(tv, TreeWidth(tv));
        }

    }
    TtkRedisplayWidget(&tv->core);

    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, column,
	    tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* @@@ testing ... */







|







|
|
<










<
>
|
<
|
>
|
|



















|







1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227

1228
1229
1230
1231
1232
1233
1234
1235
1236
1237

1238
1239

1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
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 ... */
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
    REGION_NOTHING = 0,
    REGION_HEADING,
    REGION_SEPARATOR,
    REGION_TREE,
    REGION_CELL
} TreeRegion;

static const char *const regionStrings[] = {
    "nothing", "heading", "separator", "tree", "cell", 0
};

static TreeRegion IdentifyRegion(Treeview *tv, int x, int y)
{
    int x1 = 0, colno;








|







1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
    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;

1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572

/* + TreeviewGetLayout --
 * 	GetLayout() widget hook.
 */
static Ttk_Layout TreeviewGetLayout(
    Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Layout treeLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
    Tcl_Obj *objPtr;
    int unused;

    if (!(
	treeLayout
     && GetSublayout(interp, themePtr, treeLayout, ".Item",







|







1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576

/* + 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",
1607
1608
1609
1610
1611
1612
1613
1614
1615


1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
 * Side effects:
 * 	Computes headingArea and treeArea.
 * 	Computes subtree height.
 * 	Invokes scroll callbacks.
 */
static void TreeviewDoLayout(void *clientData)
{
    Treeview *tv = (Treeview *)clientData;
    int visibleRows;



    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);


    TtkScrolled(tv->tree.xscrollHandle,
	    tv->tree.xscroll.first,
	    tv->tree.xscroll.first + tv->tree.treeArea.width,
	    TreeWidth(tv));

    if (tv->tree.showFlags & SHOW_HEADINGS) {







|

>
>





>







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
 * 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) {
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655

/* + TreeviewSize --
 * 	SizeProc() widget hook.  Size is determined by
 * 	-height option and column widths.
 */
static int TreeviewSize(void *clientData, int *widthPtr, int *heightPtr)
{
    Treeview *tv = (Treeview *)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;







|







1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662

/* + 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;
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
}

/* + TreeviewDisplay --
 * 	Display() widget hook.  Draw the widget contents.
 */
static void TreeviewDisplay(void *clientData, Drawable d)
{
    Treeview *tv = (Treeview *)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);
}







|







1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
}

/* + 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);
}
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
 */
static int AncestryCheck(
    Tcl_Interp *interp, Treeview *tv, TreeItem *item, TreeItem *parent)
{
    TreeItem *p = parent;
    while (p) {
	if (p == item) {

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Cannot insert %s as descendant of %s",
		    ItemName(tv, item), ItemName(tv, parent)));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ANCESTRY", NULL);
	    return 0;
	}
	p = p->parent;
    }
    return 1;
}








>
|
|
|
|







1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
 */
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 descendant of ", ItemName(tv, parent),
		    NULL);
	    return 0;
	}
	p = p->parent;
    }
    return 1;
}

1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957

/* + $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 = (Treeview *)recordPtr;
    TreeItem *item;
    Tcl_Obj *result;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?newchildren?");
	return TCL_ERROR;
    }







|







1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965

/* + $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;
    }
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
	if (!newChildren)
	    return TCL_ERROR;

	/* Sanity-check:
	 */
	for (i=0; newChildren[i]; ++i) {
	    if (!AncestryCheck(interp, tv, newChildren[i], item)) {
		ckfree(newChildren);
		return TCL_ERROR;
	    }
	}

	/* Detach old children:
	 */
	child = item->children;







|







1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
	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;
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
		 */
		continue;
	    }
	    InsertItem(item, child, newChildren[i]);
	    child = newChildren[i];
	}

	ckfree(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 = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);







|












|







2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
		 */
		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]);
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065

/* + $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 = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);







|







2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073

/* + $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]);
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090

/* + $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 = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);







|







2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098

/* + $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]);
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162

/* + $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 = (Treeview *)recordPtr;
    TreeItem *item;
    TkSizeT 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, TkNewIndexObj(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 = (Treeview *)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_NewWideIntObj(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 = (Treeview *)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;







|

|















|









|








|









|







2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170

/* + $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;
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203

2204
2205
2206
2207
2208
2209
2210
{
    const char *what = "nothing", *detail = NULL;
    TreeItem *item = 0;
    Tcl_Obj *result;
    int dColumnNumber;
    char dcolbuf[16];
    int x, y, x1;
    (void)objc;

    /* 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;
    }







<



|
|
>







2199
2200
2201
2202
2203
2204
2205

2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
{
    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;
    }
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
	} 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);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    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);







|
<
<







2233
2234
2235
2236
2237
2238
2239
2240


2241
2242
2243
2244
2245
2246
2247
	} 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);
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
/* + $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 *const submethodStrings[] =
	 { "region", "item", "column", "row", "element", NULL };
    enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT };

    Treeview *tv = (Treeview *)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_GetIndexFromObjStruct(interp, objv[2], submethodStrings,
		sizeof(char *), "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);







|



|
















|
|







2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
/* + $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);
2309
2310
2311
2312
2313
2314
2315


2316
2317
2318
2319
2320
2321
2322
2323
	    if (item) {
		Tcl_SetObjResult(interp, ItemID(tv, item));
	    }
	    break;

	case I_COLUMN :
	    if (colno >= 0) {


		Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%d", colno));
	    }
	    break;

	case I_ELEMENT :
	{
	    Ttk_Layout layout = 0;
	    DisplayItem displayItem;







>
>
|







2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
	    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;
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
		    break;
	    }

	    if (!BoundingBox(tv, item, column, &bbox)) {
		return TCL_OK;
	    }

	    PrepareItem(tv, item, &displayItem);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    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));







|
<
<







2347
2348
2349
2350
2351
2352
2353
2354


2355
2356
2357
2358
2359
2360
2361
		    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));
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384

/* + $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 = (Treeview *)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) {







|



|







2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390

/* + $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) {
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408

/* + $tv column column ?options ....?
 * 	Column data accessor
 */
static int TreeviewColumnCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeColumn *column;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "column -option value...");
	return TCL_ERROR;
    }
    if (!(column = FindColumn(interp, tv, objv[2]))) {







|







2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414

/* + $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]))) {
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436

/* + $tv heading column ?options ....?
 * 	Heading data accessor
 */
static int TreeviewHeadingCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)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;







|







2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442

/* + $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;
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466

/* + $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 = (Treeview *)recordPtr;
    TreeItem *item;
    TreeColumn *column;
    int columnNumber;

    if (objc < 3 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?column ?value??");
	return TCL_ERROR;







|







2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472

/* + $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;
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
    /* 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_SetObjResult(interp, Tcl_NewStringObj(
		"Display column #0 cannot be set", -1));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_0", 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;







<
|
<







2501
2502
2503
2504
2505
2506
2507

2508

2509
2510
2511
2512
2513
2514
2515
    /* 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;
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560

/* + $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 = (Treeview *)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;







|







2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564

/* + $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;
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
     */
    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_SetObjResult(interp, Tcl_ObjPrintf(
		"Item %s already exists", itemName));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ITEM_EXISTS", NULL);
	    return TCL_ERROR;
	}
	objc -= 2; objv += 2;
    } else {
	char idbuf[16];
	do {
	    ++tv->tree.serial;







|
<
<







2587
2588
2589
2590
2591
2592
2593
2594


2595
2596
2597
2598
2599
2600
2601
     */
    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;
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751

2752
2753
2754
2755
2756
2757
2758

/* + $tv detach $item --
 * 	Unlink $item from the tree.
 */
static int TreeviewDetachCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)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_SetObjResult(interp, Tcl_NewStringObj(
		"Cannot detach root item", -1));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL);
	    ckfree(items);
	    return TCL_ERROR;
	}
    }

    for (i = 0; items[i]; ++i) {
	DetachItem(items[i]);
    }

    TtkRedisplayWidget(&tv->core);
    ckfree(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 = (Treeview *)recordPtr;
    TreeItem **items, *delq;
    int i, selItemDeleted = 0;

    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(items);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Cannot delete root item", -1));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL);
	    return TCL_ERROR;
	}
    }

    /* Remove items from hash table.
     */
    delq = 0;
    for (i=0; items[i]; ++i) {
        if (items[i]->state & TTK_STATE_SELECTED) {
            selItemDeleted = 1;
        }
	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(items);
    if (selItemDeleted) {
        Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    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 = (Treeview *)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);







|














<
|
<
|









|


















|

|














|
<
|
<








<
<
<















|
<
<
<










|







|
|
>







2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650

2651

2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698

2699

2700
2701
2702
2703
2704
2705
2706
2707



2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723



2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751

/* + $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);
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
/*------------------------------------------------------------------------
 * +++ Widget commands -- scrolling
 */

static int TreeviewXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)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 = (Treeview *)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 = (Treeview *)recordPtr;
    TreeItem *item, *parent;
    int rowNumber;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }







|






|









|







2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
/*------------------------------------------------------------------------
 * +++ 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;
    }
2836
2837
2838
2839
2840
2841
2842

2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879

2880
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891
2892
2893

2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
	if (!(parent->state & TTK_STATE_OPEN)) {
	    parent->openObj = unshareObj(parent->openObj);
	    Tcl_SetBooleanObj(parent->openObj, 1);
	    parent->state |= TTK_STATE_OPEN;
	    TtkRedisplayWidget(&tv->core);
	}
    }


    /* Make sure item is visible:
     */
    rowNumber = RowNumber(tv, item);
    if (rowNumber < tv->tree.yscroll.first) {
	TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1);
    } else if (rowNumber >= tv->tree.yscroll.last) {
	TtkScrollTo(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1);
    }

    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 = (Treeview *)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);

	    TtkRedisplayWidget(&tv->core);
	    return TCL_OK;
	}
	left = right;
    }


    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"column %s is not displayed", Tcl_GetString(objv[2])));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_INVISIBLE", NULL);
    return TCL_ERROR;
}

static int TreeviewDropCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "drop");
	return TCL_ERROR;
    }
    ResizeColumns(tv, TreeWidth(tv));
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- focus and selection
 */

/* + $tree focus ?item?
 */
static int TreeviewFocusCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc == 2) {
	if (tv->tree.focus) {
	    Tcl_SetObjResult(interp, ItemID(tv, tv->tree.focus));
	}
	return TCL_OK;
    } else if (objc == 3) {







>





|


|















|










|
|
>








>






>
|
|
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<











|







2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892



2893







2894




2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
	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) {
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
 */
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 *const selopStrings[] = {
	"set", "add", "remove", "toggle", NULL
    };

    Treeview *tv = (Treeview *)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_GetIndexFromObjStruct(interp, objv[2], selopStrings,
	    sizeof(char *), "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(items);
    Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    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 = (Treeview *)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;







|



|





|












|
|











|




















|
|














|







2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
 */
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;
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
	    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_SetObjResult(interp, Tcl_ObjPrintf(
		    "unsupported event %s\nonly key, button, motion, and"
		    " virtual events supported", sequence));
		Tcl_SetErrorCode(interp, "TTK", "TREE", "BIND_EVENTS", 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 = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    Ttk_Tag tag;

    if (objc < 4) {
    	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option ?value ...??");
	return TCL_ERROR;
    }







|
|
|
|












|







3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
	    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;
    }
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
	return TCL_ERROR;
    }
    /* else */
    TtkRedisplayWidget(&tv->core);
    return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4);
}

/* + $tv tag delete $tag
 */
static int TreeviewTagDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    TreeItem *item = tv->tree.root;
    Ttk_Tag tag;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);
    /* remove the tag from all items */
    while (item) {
	RemoveTag(item, tag);
	item = NextPreorder(item);
    }
    /* then remove the tag from the tag table */
    Ttk_DeleteTagFromTable(tagTable, tag);
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag has $tag ?$item?
 */
static int TreeviewTagHasCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)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) {







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|







3079
3080
3081
3082
3083
3084
3085




























3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
	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) {
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
    } 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_NewWideIntObj(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 = (Treeview *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, "");
	return TCL_ERROR;
    }

    return Ttk_EnumerateTags(interp, tv->tree.tagTable);







|












|







3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
    } 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);
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
	Tcl_IncrRefCount(item->tagsObj);
    }
}

static int TreeviewTagAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;
    TreeItem **items;
    int i;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
	return TCL_ERROR;







|







3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
	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;
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
	Tcl_IncrRefCount(item->tagsObj);
    }
}

static int TreeviewTagRemoveCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
	return TCL_ERROR;
    }








|







3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
	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;
    }

3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
	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);
	}
    }

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

static const Ttk_Ensemble TreeviewTagCommands[] = {
    { "add",		TreeviewTagAddCommand,0 },
    { "bind",		TreeviewTagBindCommand,0 },
    { "configure",	TreeviewTagConfigureCommand,0 },
    { "delete",		TreeviewTagDeleteCommand,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 },
    { "drop",   	TreeviewDropCommand,0 },
    { "exists", 	TreeviewExistsCommand,0 },
    { "focus", 		TreeviewFocusCommand,0 },
    { "heading", 	TreeviewHeadingCommand,0 },
    { "identify",  	TreeviewIdentifyCommand,0 },
    { "index",  	TreeviewIndexCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "insert", 	TreeviewInsertCommand,0 },







|












<


















<







3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227

3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245

3246
3247
3248
3249
3250
3251
3252
	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);
	}
    }

    TtkRedisplayWidget(&tv->core);

    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 },
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget definition.
 */

static const WidgetSpec TreeviewWidgetSpec = {
    "Treeview",			/* className */
    sizeof(Treeview),   	/* recordSize */
    TreeviewOptionSpecs,	/* optionSpecs */
    TreeviewCommands,   	/* subcommands */
    TreeviewInitialize,   	/* initializeProc */
    TreeviewCleanup,		/* cleanupProc */
    TreeviewConfigure,    	/* configureProc */







|







3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget definition.
 */

static WidgetSpec TreeviewWidgetSpec = {
    "Treeview",			/* className */
    sizeof(Treeview),   	/* recordSize */
    TreeviewOptionSpecs,	/* optionSpecs */
    TreeviewCommands,   	/* subcommands */
    TreeviewInitialize,   	/* initializeProc */
    TreeviewCleanup,		/* cleanupProc */
    TreeviewConfigure,    	/* configureProc */
3342
3343
3344
3345
3346
3347
3348

3349
3350
3351
3352
3353
3354
3355
3356
	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_NODE("Treeitem.text", TTK_FILL_BOTH)))

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)







>
|







3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
	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)
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *marginsObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,sizeObj), "12" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginsObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    Ttk_Padding margins;
    int size = 0;
    (void)dummy;
    (void)paddingPtr;

    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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)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;
    (void)dummy;

    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 const Ttk_ElementSpec TreeitemIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TreeitemIndicator),
    TreeitemIndicatorOptions,
    TreeitemIndicatorSize,
    TreeitemIndicatorDraw
};

/*------------------------------------------------------------------------
 * +++ Row element.
 */

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *rowNumberObj;
} RowElement;

static const Ttk_ElementOptionSpec RowElementOptions[] = {
    { "-background", TK_OPTION_COLOR,
	offsetof(RowElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-rownumber", TK_OPTION_INT,
	offsetof(RowElement,rowNumberObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void RowElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    RowElement *row = (RowElement *)elementRecord;
    XColor *color = Tk_GetColorFromObj(tkwin, row->backgroundObj);
    GC gc = Tk_GCForColor(color, d);
    (void)dummy;
    (void)state;

    XFillRectangle(Tk_Display(tkwin), d, gc,
	    b.x, b.y, b.width, b.height);
}

static const Ttk_ElementSpec RowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(RowElement),
    RowElementOptions,
    TtkNullElementSize,
    RowElementDraw
};








|

|

|

|
|



|


|


<
<









|


|





<

















|
















|

|

|
|



|


|


<
<
<




|







3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347


3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365

3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414



3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426

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
};

Changes to generic/ttk/ttkWidget.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
/*
 * Copyright (c) 2003, Joe English
 *
 * Core widget utilities.
 */


#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#ifdef MAC_OSX_TK
#define TK_NO_DOUBLE_BUFFERING 1
#endif






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * Copyright (c) 2003, Joe English
 *
 * Core widget utilities.
 */

#include <string.h>
#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#ifdef MAC_OSX_TK
#define TK_NO_DOUBLE_BUFFERING 1
#endif
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

    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) { (void)tkwin; (void)d;}
#endif

/* DrawWidget --
 *	Redraw a widget.  Called as an idle handler.
 */
static void DrawWidget(ClientData recordPtr)
{
    WidgetCore *corePtr = (WidgetCore *)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);







|







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

    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);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* WidgetInstanceObjCmd --
 *	Widget instance command implementation.
 */
static int
WidgetInstanceObjCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)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);








|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* 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);

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

/* WidgetInstanceObjCmdDeleted --
 * 	Widget instance command	deletion callback.
 */
static void
WidgetInstanceObjCmdDeleted(ClientData clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    corePtr->widgetCmd = NULL;
    if (corePtr->tkwin != NULL)
	Tk_DestroyWindow(corePtr->tkwin);
}

/* FreeWidget --
 *	 Final cleanup for widget; called via Tcl_EventuallyFree().
 */
static void
FreeWidget(void *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(
	    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, (Tcl_FreeProc *) FreeWidget);
}

/*
 * CoreEventProc --
 *	Event handler for basic events.
 *	Processes Expose, Configure, FocusIn/Out, and Destroy events.
 *	Also handles <<ThemeChanged>> virtual events.







|









|















|
















|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

/* 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.
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    | ActivateMask
    | EnterWindowMask
    | LeaveWindowMask
    ;

static void CoreEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;

    switch (eventPtr->type)
    {
	case ConfigureNotify :
	    TtkRedisplayWidget(corePtr);
	    break;
	case Expose :







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
    | ActivateMask
    | EnterWindowMask
    | LeaveWindowMask
    ;

static void CoreEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = clientData;

    switch (eventPtr->type)
    {
	case ConfigureNotify :
	    TtkRedisplayWidget(corePtr);
	    break;
	case Expose :
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	    corePtr->state &= ~TTK_STATE_HOVER;
	    TtkRedisplayWidget(corePtr);
	    break;
	case EnterNotify:
	    corePtr->state |= TTK_STATE_HOVER;
	    TtkRedisplayWidget(corePtr);
	    break;
	case VirtualEvent: {
	    const char *name = ((XVirtualEvent *)eventPtr)->name;
	    if ((name != NULL) && !strcmp("ThemeChanged", name)) {
		(void)UpdateLayout(corePtr->interp, corePtr);
		SizeChanged(corePtr);
		TtkRedisplayWidget(corePtr);
	    }
	    break;
	}
	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 = (WidgetCore *)clientData;
    SizeChanged(corePtr);
    TtkRedisplayWidget(corePtr);
}

static const 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 = (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;







|
<
|




<
<














|




|














|







306
307
308
309
310
311
312
313

314
315
316
317
318


319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
	    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;
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
	return TCL_ERROR;

    /*
     * Allocate and initialize the widget record.
     */
    recordPtr = ckalloc(widgetSpec->recordSize);
    memset(recordPtr, 0, widgetSpec->recordSize);
    corePtr = (WidgetCore *)recordPtr;

    corePtr->tkwin	= tkwin;
    corePtr->interp 	= interp;
    corePtr->widgetSpec	= widgetSpec;
    corePtr->widgetCmd	= Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
	WidgetInstanceObjCmd, recordPtr, WidgetInstanceObjCmdDeleted);
    corePtr->optionTable = optionTable;







|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
	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;
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
    Tk_MakeWindowExist(tkwin);

    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), -1));
    return TCL_OK;

error:
    if (WidgetDestroyed(corePtr)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"widget has been destroyed", -1));
    } 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 = (WidgetCore *)recordPtr;
    const char *styleName = 0;

    if (corePtr->styleObj)
    	styleName = Tcl_GetString(corePtr->styleObj);

    if (!styleName || *styleName == '\0')
    	styleName = corePtr->widgetSpec->className;







<
|



















|







436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
    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;
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
 * 	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 = (WidgetCore *)recordPtr;
    const char *baseStyleName = 0;
    Tcl_DString styleName;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    Ttk_Layout layout;

    Tcl_DStringInit(&styleName);

    /* Prefix:
     */
    TtkGetOrientFromObj(NULL, orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL)
	Tcl_DStringAppend(&styleName, "Horizontal.", -1);
    else
	Tcl_DStringAppend(&styleName, "Vertical.", -1);

    /* Add base style name:
     */







|


|






|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
 * 	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:
     */
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
}

/* TtkNullInitialize --
 * 	Default widget initializeProc (no-op)
 */
void TtkNullInitialize(Tcl_Interp *interp, void *recordPtr)
{
    (void)interp;
    (void)recordPtr;
}

/* TtkNullPostConfigure --
 * 	Default widget postConfigureProc (no-op)
 */
int TtkNullPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
{
    (void)interp;
    (void)clientData;
    (void)mask;

    return TCL_OK;
}

/* TtkCoreConfigure --
 * 	Default widget configureProc.
 * 	Handles -style option.
 */
int TtkCoreConfigure(Tcl_Interp *interp, void *clientData, int mask)
{
    WidgetCore *corePtr = (WidgetCore *)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)
{
    (void)recordPtr;
    return;
}

/* TtkWidgetDoLayout --
 * 	Default widget layoutProc.
 */
void TtkWidgetDoLayout(void *clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
}

/* TtkWidgetDisplay --
 * 	Default widget displayProc.
 */
void TtkWidgetDisplay(void *recordPtr, Drawable d)
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_DrawLayout(corePtr->layout, corePtr->state, d);
}

/* TtkWidgetSize --
 * 	Default widget sizeProc()
 */
int TtkWidgetSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
    WidgetCore *corePtr = (WidgetCore *)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 = (WidgetCore *)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 = (WidgetCore *)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_SetObjResult(interp, Tcl_NewStringObj(
		    "attempt to change read-only option", -1));
	    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_SetObjResult(interp, Tcl_NewStringObj(
		    "widget has been destroyed", -1));
	    status = TCL_ERROR;
	}
	if (status != TCL_OK) {
	    return status;
	}

	if (mask & (STYLE_CHANGED | GEOMETRY_CHANGED)) {







<
<







<
<
<
<









|














<








|








|








|













|



















|




















|
|













<
|







518
519
520
521
522
523
524


525
526
527
528
529
530
531




532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
}

/* 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)) {
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
 *
 * 	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 = (WidgetCore *)recordPtr;
    Ttk_StateSpec spec;
    int status;
    Ttk_State oldState, changed;

    if (objc == 2) {
	Tcl_SetObjResult(interp,
	    Ttk_NewStateSpecObj(corePtr->state, 0ul));







|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
 *
 * 	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));
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
 *	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 = (WidgetCore *)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_NewWideIntObj(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 = (WidgetCore *)recordPtr;
    Ttk_Element element;
    static const char *const 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_GetIndexFromObjStruct(interp, objv[2], whatTable,
		sizeof(char *), "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







|














|















|

|








|
|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
 *	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

Changes to generic/ttk/ttkWidget.h.

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

#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", offsetof(WidgetCore, takeFocusPtr), TCL_INDEX_NONE, 0,0,0 }
#define WIDGET_TAKEFOCUS_FALSE \
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", \
	"", offsetof(WidgetCore, takeFocusPtr), TCL_INDEX_NONE, 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, TCL_INDEX_NONE,TCL_INDEX_NONE, 0, baseOptionSpecs, 0}

/* All widgets should inherit from ttkCoreOptionSpecs[].
 */
MODULE_SCOPE const Tk_OptionSpec ttkCoreOptionSpecs[];

/*
 * Useful routines for use inside widget implementations:
 */
/* extern int WidgetDestroyed(WidgetCore *); */
#define WidgetDestroyed(corePtr) ((corePtr)->flags & WIDGET_DESTROYED)








|
|




|


|






|



|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

#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)

160
161
162
163
164
165
166





167
168
169
170
171
172
173
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 *);






/*
 * 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);







>
>
>
>
>







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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);
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

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 TtkUpdateScrollInfo(ScrollHandle h);
MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo);
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, const 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 void Ttk_DeleteTagFromTable(Ttk_TagTable, Ttk_Tag);

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);







<
|















|













<
<







191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234

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);
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
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 *const ttkOrientStrings[];
MODULE_SCOPE const char *const ttkCompoundStrings[];
MODULE_SCOPE const char *const ttkDefaultStrings[];

/*
 * ... other option types...
 */
MODULE_SCOPE int TtkGetLabelAnchorFromObj(
	Tcl_Interp*, Tcl_Obj*, Ttk_PositionSpec *);

/*
 * Platform-specific initialization.
 */

#ifdef _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 */







|
|
|











|










242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
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 */

Changes to library/bgerror.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169




170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195


196






197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249




250
251
252
253
254
255
256
# bgerror.tcl --
#
#	Implementation of the bgerror procedure.  It posts a dialog box with
#	the error message and gives the user a chance to see a more detailed
#	stack trace, and possible do something more interesting with that
#	trace (like save it to a log).  This is adapted from work done by
#	Donal K. Fellows.
#
# Copyright © 1998-2000 by Ajuba Solutions.
# Copyright © 2007 by ActiveState Software Inc.
# Copyright © 2007 Daniel A. Steffen <das@users.sourceforge.net>
# Copyright © 2009 Pat Thoyts <patthoyts@users.sourceforge.net>

namespace eval ::tk::dialog::error {
    namespace import -force ::tk::msgcat::*
    namespace export bgerror
    option add *ErrorDialog.function.text [mc "Save To Log"] \
	widgetDefault
    option add *ErrorDialog.function.command [namespace code SaveToLog]
    option add *ErrorDialog*Label.font TkCaptionFont widgetDefault
    if {[tk windowingsystem] eq "aqua"} {
	option add *ErrorDialog*background systemAlertBackgroundActive \
		widgetDefault
	option add *ErrorDialog*info.text.background \
	        systemTextBackgroundColor widgetDefault
	option add *ErrorDialog*Button.highlightBackground \
		systemAlertBackgroundActive widgetDefault
    }
}

proc ::tk::dialog::error::Return {which code} {
    variable button

    .bgerrorDialog.$which state {active selected focus}
    update idletasks
    after 100
    set button $code
}

proc ::tk::dialog::error::Details {} {
    set w .bgerrorDialog
    set caption [option get $w.function text {}]
    set command [option get $w.function command {}]
    if {($caption eq "") || ($command eq "")} {
	grid forget $w.function
    }
    lappend command [$w.top.info.text get 1.0 end-1c]
    $w.function configure -text $caption -command $command
    grid $w.top.info - -sticky nsew -padx 3m -pady 3m
}

proc ::tk::dialog::error::SaveToLog {text} {
    if {$::tcl_platform(platform) eq "windows"} {
	set allFiles *.*
    } else {
	set allFiles *
    }
    set types [list \
	    [list [mc "Log Files"] .log]      \
	    [list [mc "Text Files"] .txt]     \
	    [list [mc "All Files"] $allFiles] \
	    ]
    set filename [tk_getSaveFile -title [mc "Select Log File"] \
	    -filetypes $types -defaultextension .log -parent .bgerrorDialog]
    if {$filename ne {}} {


        set f [open $filename w]
        puts -nonewline $f $text
        close $f
    }
    return
}

proc ::tk::dialog::error::Destroy {w} {
    if {$w eq ".bgerrorDialog"} {
	variable button
	set button -1
    }
}

proc ::tk::dialog::error::DeleteByProtocol {} {
    variable button
    set button 1
}

proc ::tk::dialog::error::ReturnInDetails w {
    bind $w <Return> {}; # Remove this binding
    $w invoke
    return -code break
}

# ::tk::dialog::error::bgerror --
#
#	This is the default version of bgerror.
#	It tries to execute tkerror, if that fails it posts a dialog box
#	containing the error message and gives the user a chance to ask
#	to see a stack trace.
#
# Arguments:
#	err - The error message.
#
proc ::tk::dialog::error::bgerror {err {flag 1}} {
    global errorInfo
    variable button

    set info $errorInfo

    set ret [catch {::tkerror $err} msg];
    if {$ret != 1} {return -code $ret $msg}

    # The application's tkerror either failed or was not found
    # so we use the default dialog.  But on Aqua we cannot display
    # the dialog if the background error occurs in an idle task
    # being processed inside of [NSView drawRect].  In that case
    # we post the dialog as an after task instead.
    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {
	if $flag {
	    set errorInfo $info
	    after 500 [list bgerror "$err" 0]
	    return
	}

    }

    set ok [mc OK]
    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45
    foreach line [split $err \n] {
	if {[string length $line] > $maxLine} {
	    append displayedErr "[string range $line 0 $maxLine-3]..."
	    break
	}
	if {$lines > 4} {
	    append displayedErr "..."
	    break
	} else {
	    append displayedErr "${line}\n"
	}
	incr lines
    }

    set title [mc "Application Error"]
    set text [mc "Error: %1\$s" $displayedErr]
    set buttons [list ok $ok dismiss [mc "Skip Messages"] \
		     function [mc "Details >>"]]

    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    set dlg .bgerrorDialog
    set bg [ttk::style lookup . -background]
    destroy $dlg
    toplevel $dlg -class ErrorDialog -background $bg
    wm withdraw $dlg
    wm title $dlg $title
    wm iconname $dlg ErrorDialog
    wm protocol $dlg WM_DELETE_WINDOW [namespace code DeleteByProtocol]

    if {$windowingsystem eq "aqua"} {
	::tk::unsupported::MacWindowStyle style $dlg moveableAlert {}
    } elseif {$windowingsystem eq "x11"} {
	wm attributes $dlg -type dialog
    }

    ttk::frame $dlg.bot
    ttk::frame $dlg.top




    pack $dlg.bot -side bottom -fill both
    pack $dlg.top -side top -fill both -expand 1

    set W [ttk::frame $dlg.top.info]
    text $W.text -setgrid true -height 10 -wrap char \
	-yscrollcommand [list $W.scroll set]
    if {$windowingsystem ne "aqua"} {
	$W.text configure -width 40
    }

    ttk::scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y
    pack $W.text -side left -expand yes -fill both
    $W.text insert 0.0 "$err\n$info"
    $W.text mark set insert 0.0
    bind $W.text <Button-1> {focus %W}
    $W.text configure -state disabled

    # 2. Fill the top part with bitmap and message

    # Max-width of message is the width of the screen...
    set wrapwidth [winfo screenwidth $dlg]
    # ...minus the width of the icon, padding and a fudge factor for
    # the window manager decorations and aesthetics.
    set wrapwidth [expr {$wrapwidth-60-[winfo pixels $dlg 9m]}]
    ttk::label $dlg.msg -justify left -text $text -wraplength $wrapwidth


    ttk::label $dlg.bitmap -image ::tk::icons::error







    grid $dlg.bitmap $dlg.msg -in $dlg.top -row 0 -padx 3m -pady 3m
    grid configure       $dlg.bitmap -sticky ne
    grid configure	 $dlg.msg -sticky nsw -padx {0 3m}
    grid rowconfigure	 $dlg.top 1 -weight 1
    grid columnconfigure $dlg.top 1 -weight 1

    # 3. Create a row of buttons at the bottom of the dialog.

    set i 0
    foreach {name caption} $buttons {
	ttk::button $dlg.$name -text $caption -default normal \
	    -command [namespace code [list set button $i]]
	grid $dlg.$name -in $dlg.bot -column $i -row 0 -sticky ew -padx 10
	grid columnconfigure $dlg.bot $i -weight 1
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    if {($name eq "ok") || ($name eq "dismiss")} {
		grid columnconfigure $dlg.bot $i -minsize 90
	    }
	    grid configure $dlg.$name -pady 7
	}
	incr i
    }
    # The "OK" button is the default for this dialog.
    $dlg.ok configure -default active

    bind $dlg <Return>	[namespace code {Return ok 0}]
    bind $dlg <Escape>	[namespace code {Return dismiss 1}]
    bind $dlg <Destroy>	[namespace code {Destroy %W}]
    bind $dlg.function <Return>	[namespace code {ReturnInDetails %W}]
    $dlg.function configure -command [namespace code Details]

    # 6. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $dlg

    # 7. Set a grab and claim the focus too.

    ::tk::SetFocusGrab $dlg $dlg.ok

    # 8. Ensure that we are topmost.

    raise $dlg
    if {[tk windowingsystem] eq "win32"} {
	# Place it topmost if we aren't at the top of the stacking
	# order to ensure that it's seen
	if {[lindex [wm stackorder .] end] ne "$dlg"} {
	    wm attributes $dlg -topmost 1
        }
    }





    # 9. Wait for the user to respond, then restore the focus and
    # return the index of the selected button.  Restore the focus
    # before deleting the window, since otherwise the window manager
    # may take the focus away so we can't redirect it.  Finally,
    # restore any grab that was in effect.









|
|
|
<











|
<





|


|


|






|








|




|
|
|




|
>
>
|
|
|
<
<









<
<
<
<
<
<
<
<
<
<
<

<
|
|
|
|
<

|
|
|
|







|
|
<
<
<


<
|
<
<
|
>


<







|
|


|

















<

|



|







|
|
>
>
>
>



|






|




|









|
>
>
|
>
>
>
>
>
>
|

<








|















|
<
|
<








<
<
<
<
|







|

>
>
>
>







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68


69
70
71
72
73
74
75
76
77











78

79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96



97
98

99


100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214

215
216
217
218
219
220
221
222




223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# bgerror.tcl --
#
#	Implementation of the bgerror procedure.  It posts a dialog box with
#	the error message and gives the user a chance to see a more detailed
#	stack trace, and possible do something more interesting with that
#	trace (like save it to a log).  This is adapted from work done by
#	Donal K. Fellows.
#
# Copyright (c) 1998-2000 by Ajuba Solutions.
# Copyright (c) 2007 by ActiveState Software Inc.
# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>


namespace eval ::tk::dialog::error {
    namespace import -force ::tk::msgcat::*
    namespace export bgerror
    option add *ErrorDialog.function.text [mc "Save To Log"] \
	widgetDefault
    option add *ErrorDialog.function.command [namespace code SaveToLog]
    option add *ErrorDialog*Label.font TkCaptionFont widgetDefault
    if {[tk windowingsystem] eq "aqua"} {
	option add *ErrorDialog*background systemAlertBackgroundActive \
		widgetDefault
	option add *ErrorDialog*info.text.background white widgetDefault

	option add *ErrorDialog*Button.highlightBackground \
		systemAlertBackgroundActive widgetDefault
    }
}

proc ::tk::dialog::error::Return {} {
    variable button

    .bgerrorDialog.ok configure -state active -relief sunken
    update idletasks
    after 100
    set button 0
}

proc ::tk::dialog::error::Details {} {
    set w .bgerrorDialog
    set caption [option get $w.function text {}]
    set command [option get $w.function command {}]
    if { ($caption eq "") || ($command eq "") } {
	grid forget $w.function
    }
    lappend command [$w.top.info.text get 1.0 end-1c]
    $w.function configure -text $caption -command $command
    grid $w.top.info - -sticky nsew -padx 3m -pady 3m
}

proc ::tk::dialog::error::SaveToLog {text} {
    if { $::tcl_platform(platform) eq "windows" } {
	set allFiles *.*
    } else {
	set allFiles *
    }
    set types [list	\
	    [list [mc "Log Files"] .log]	\
	    [list [mc "Text Files"] .txt]	\
	    [list [mc "All Files"] $allFiles] \
	    ]
    set filename [tk_getSaveFile -title [mc "Select Log File"] \
	    -filetypes $types -defaultextension .log -parent .bgerrorDialog]
    if {![string length $filename]} {
	return
    }
    set f [open $filename w]
    puts -nonewline $f $text
    close $f


}

proc ::tk::dialog::error::Destroy {w} {
    if {$w eq ".bgerrorDialog"} {
	variable button
	set button -1
    }
}












# ::tk::dialog::error::bgerror --

# This is the default version of bgerror.
# It tries to execute tkerror, if that fails it posts a dialog box containing
# the error message and gives the user a chance to ask to see a stack
# trace.

# Arguments:
# err -			The error message.

proc ::tk::dialog::error::bgerror err {
    global errorInfo tcl_platform
    variable button

    set info $errorInfo

    set ret [catch {::tkerror $err} msg];
    if {$ret != 1} {return -code $ret $msg}

    # Ok the application's tkerror either failed or was not found
    # we use the default dialog then :



    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {

	set ok [mc Ok]


    } else {
	set ok [mc OK]
    }


    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45
    foreach line [split $err \n] {
	if { [string length $line] > $maxLine } {
	    append displayedErr "[string range $line 0 [expr {$maxLine-3}]]..."
	    break
	}
	if { $lines > 4 } {
	    append displayedErr "..."
	    break
	} else {
	    append displayedErr "${line}\n"
	}
	incr lines
    }

    set title [mc "Application Error"]
    set text [mc "Error: %1\$s" $displayedErr]
    set buttons [list ok $ok dismiss [mc "Skip Messages"] \
		     function [mc "Details >>"]]

    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    set dlg .bgerrorDialog

    destroy $dlg
    toplevel $dlg -class ErrorDialog
    wm withdraw $dlg
    wm title $dlg $title
    wm iconname $dlg ErrorDialog
    wm protocol $dlg WM_DELETE_WINDOW { }

    if {$windowingsystem eq "aqua"} {
	::tk::unsupported::MacWindowStyle style $dlg moveableAlert {}
    } elseif {$windowingsystem eq "x11"} {
	wm attributes $dlg -type dialog
    }

    frame $dlg.bot
    frame $dlg.top
    if {$windowingsystem eq "x11"} {
	$dlg.bot configure -relief raised -bd 1
	$dlg.top configure -relief raised -bd 1
    }
    pack $dlg.bot -side bottom -fill both
    pack $dlg.top -side top -fill both -expand 1

    set W [frame $dlg.top.info]
    text $W.text -setgrid true -height 10 -wrap char \
	-yscrollcommand [list $W.scroll set]
    if {$windowingsystem ne "aqua"} {
	$W.text configure -width 40
    }

    scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y
    pack $W.text -side left -expand yes -fill both
    $W.text insert 0.0 "$err\n$info"
    $W.text mark set insert 0.0
    bind $W.text <ButtonPress-1> { focus %W }
    $W.text configure -state disabled

    # 2. Fill the top part with bitmap and message

    # Max-width of message is the width of the screen...
    set wrapwidth [winfo screenwidth $dlg]
    # ...minus the width of the icon, padding and a fudge factor for
    # the window manager decorations and aesthetics.
    set wrapwidth [expr {$wrapwidth-60-[winfo pixels $dlg 9m]}]
    label $dlg.msg -justify left -text $text -wraplength $wrapwidth
    if {$windowingsystem eq "aqua"} {
	# On the Macintosh, use the stop bitmap
	label $dlg.bitmap -bitmap stop
    } else {
	# On other platforms, make the error icon
	canvas $dlg.bitmap -width 32 -height 32 -highlightthickness 0
	$dlg.bitmap create oval 0 0 31 31 -fill red -outline black
	$dlg.bitmap create line 9 9 23 23 -fill white -width 4
	$dlg.bitmap create line 9 23 23 9 -fill white -width 4
    }
    grid $dlg.bitmap $dlg.msg -in $dlg.top -row 0 -padx 3m -pady 3m

    grid configure	 $dlg.msg -sticky nsw -padx {0 3m}
    grid rowconfigure	 $dlg.top 1 -weight 1
    grid columnconfigure $dlg.top 1 -weight 1

    # 3. Create a row of buttons at the bottom of the dialog.

    set i 0
    foreach {name caption} $buttons {
	button $dlg.$name -text $caption -default normal \
	    -command [namespace code [list set button $i]]
	grid $dlg.$name -in $dlg.bot -column $i -row 0 -sticky ew -padx 10
	grid columnconfigure $dlg.bot $i -weight 1
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    if {($name eq "ok") || ($name eq "dismiss")} {
		grid columnconfigure $dlg.bot $i -minsize 90
	    }
	    grid configure $dlg.$name -pady 7
	}
	incr i
    }
    # The "OK" button is the default for this dialog.
    $dlg.ok configure -default active

    bind $dlg <Return>	[namespace code Return]

    bind $dlg <Destroy>	[namespace code [list Destroy %W]]

    $dlg.function configure -command [namespace code Details]

    # 6. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $dlg





    # 7. Ensure that we are topmost.

    raise $dlg
    if {[tk windowingsystem] eq "win32"} {
	# Place it topmost if we aren't at the top of the stacking
	# order to ensure that it's seen
	if {[lindex [wm stackorder .] end] ne "$dlg"} {
	    wm attributes $dlg -topmost 1
	}
    }

    # 8. Set a grab and claim the focus too.

    ::tk::SetFocusGrab $dlg $dlg.ok

    # 9. Wait for the user to respond, then restore the focus and
    # return the index of the selected button.  Restore the focus
    # before deleting the window, since otherwise the window manager
    # may take the focus away so we can't redirect it.  Finally,
    # restore any grab that was in effect.

Changes to library/button.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# button.tcl --
#
# This file defines the default bindings for Tk label, button,
# checkbutton, and radiobutton widgets and provides procedures
# that help in implementing those bindings.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 2002 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for buttons.
#-------------------------------------------------------------------------

if {[tk windowingsystem] eq "aqua"} {

    bind Radiobutton <Enter> {
	tk::ButtonEnter %W
    }
    bind Radiobutton <Button-1> {
	tk::ButtonDown %W
    }
    bind Radiobutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Enter> {
	tk::ButtonEnter %W
    }
    bind Checkbutton <Button-1> {
	tk::ButtonDown %W
    }
    bind Checkbutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Leave> {
	tk::ButtonLeave %W
    }
}
if {"win32" eq [tk windowingsystem]} {
    bind Checkbutton <equal> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <plus> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <minus> {
	tk::CheckRadioInvoke %W deselect
    }
    bind Checkbutton <Button-1> {
	tk::CheckRadioDown %W
    }
    bind Checkbutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Enter> {
	tk::CheckRadioEnter %W
    }
    bind Checkbutton <Leave> {
	tk::ButtonLeave %W
    }

    bind Radiobutton <Button-1> {
	tk::CheckRadioDown %W
    }
    bind Radiobutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Radiobutton <Enter> {
	tk::CheckRadioEnter %W
    }
}
if {"x11" eq [tk windowingsystem]} {
    bind Checkbutton <Return> {
	if {!$tk_strictMotif} {
	    tk::CheckInvoke %W
	}
    }
    bind Radiobutton <Return> {
	if {!$tk_strictMotif} {
	    tk::CheckRadioInvoke %W
	}
    }
    bind Checkbutton <Button-1> {
	tk::CheckInvoke %W
    }
    bind Radiobutton <Button-1> {
	tk::CheckRadioInvoke %W
    }
    bind Checkbutton <Enter> {
	tk::CheckEnter %W
    }
    bind Radiobutton <Enter> {
	tk::ButtonEnter %W






|
|
|










<



|








|



















|












|




















|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# button.tcl --
#
# This file defines the default bindings for Tk label, button,
# checkbutton, and radiobutton widgets and provides procedures
# that help in implementing those bindings.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# 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.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for buttons.
#-------------------------------------------------------------------------

if {[tk windowingsystem] eq "aqua"} {

    bind Radiobutton <Enter> {
	tk::ButtonEnter %W
    }
    bind Radiobutton <1> {
	tk::ButtonDown %W
    }
    bind Radiobutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Enter> {
	tk::ButtonEnter %W
    }
    bind Checkbutton <1> {
	tk::ButtonDown %W
    }
    bind Checkbutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Leave> {
	tk::ButtonLeave %W
    }
}
if {"win32" eq [tk windowingsystem]} {
    bind Checkbutton <equal> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <plus> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <minus> {
	tk::CheckRadioInvoke %W deselect
    }
    bind Checkbutton <1> {
	tk::CheckRadioDown %W
    }
    bind Checkbutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Enter> {
	tk::CheckRadioEnter %W
    }
    bind Checkbutton <Leave> {
	tk::ButtonLeave %W
    }

    bind Radiobutton <1> {
	tk::CheckRadioDown %W
    }
    bind Radiobutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Radiobutton <Enter> {
	tk::CheckRadioEnter %W
    }
}
if {"x11" eq [tk windowingsystem]} {
    bind Checkbutton <Return> {
	if {!$tk_strictMotif} {
	    tk::CheckInvoke %W
	}
    }
    bind Radiobutton <Return> {
	if {!$tk_strictMotif} {
	    tk::CheckRadioInvoke %W
	}
    }
    bind Checkbutton <1> {
	tk::CheckInvoke %W
    }
    bind Radiobutton <1> {
	tk::CheckRadioInvoke %W
    }
    bind Checkbutton <Enter> {
	tk::CheckEnter %W
    }
    bind Radiobutton <Enter> {
	tk::ButtonEnter %W
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
bind Button <FocusIn> {}
bind Button <Enter> {
    tk::ButtonEnter %W
}
bind Button <Leave> {
    tk::ButtonLeave %W
}
bind Button <Button-1> {
    tk::ButtonDown %W
}
bind Button <ButtonRelease-1> {
    tk::ButtonUp %W
}

bind Checkbutton <FocusIn> {}

bind Radiobutton <FocusIn> {}
bind Radiobutton <Leave> {
    tk::ButtonLeave %W
}

if {"win32" eq [tk windowingsystem]} {

#########################
# Windows implementation
#########################

# ::tk::ButtonEnter --
# The procedure below is invoked when the mouse pointer enters a
# button widget.  It records the button we're in and changes the
# state of the button to active unless the button is disabled.
#







|
















|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
bind Button <FocusIn> {}
bind Button <Enter> {
    tk::ButtonEnter %W
}
bind Button <Leave> {
    tk::ButtonLeave %W
}
bind Button <1> {
    tk::ButtonDown %W
}
bind Button <ButtonRelease-1> {
    tk::ButtonUp %W
}

bind Checkbutton <FocusIn> {}

bind Radiobutton <FocusIn> {}
bind Radiobutton <Leave> {
    tk::ButtonLeave %W
}

if {"win32" eq [tk windowingsystem]} {

#########################
# Windows implementation 
#########################

# ::tk::ButtonEnter --
# The procedure below is invoked when the mouse pointer enters a
# button widget.  It records the button we're in and changes the
# state of the button to active unless the button is disabled.
#
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
# The procedure below is called when a button is invoked through
# the keyboard.  It simulate a press of the button via the mouse.
#
# Arguments:
# w -		The name of the widget.

proc ::tk::ButtonInvoke w {
    if {[winfo exists $w] && [$w cget -state] ne "disabled"} {
	set oldRelief [$w cget -relief]
	set oldState [$w cget -state]
	$w configure -state active -relief sunken
	after 100 [list ::tk::ButtonInvokeEnd $w $oldState $oldRelief]
    }
}

# ::tk::ButtonInvokeEnd --
# The procedure below is called after a button is invoked through
# the keyboard.  It simulate a release of the button via the mouse.
#
# Arguments:
# w -         The name of the widget.
# oldState -  Old state to be set back.
# oldRelief - Old relief to be set back.

proc ::tk::ButtonInvokeEnd {w oldState oldRelief} {
    if {[winfo exists $w]} {
	$w configure -state $oldState -relief $oldRelief
	uplevel #0 [list $w invoke]
    }
}

# ::tk::ButtonAutoInvoke --
#







|



<
<
<
|
<
<
<
<
<
<
<
<
|
<
<







592
593
594
595
596
597
598
599
600
601
602



603








604


605
606
607
608
609
610
611
# The procedure below is called when a button is invoked through
# the keyboard.  It simulate a press of the button via the mouse.
#
# Arguments:
# w -		The name of the widget.

proc ::tk::ButtonInvoke w {
    if {[$w cget -state] ne "disabled"} {
	set oldRelief [$w cget -relief]
	set oldState [$w cget -state]
	$w configure -state active -relief sunken



	update idletasks








	after 100


	$w configure -state $oldState -relief $oldRelief
	uplevel #0 [list $w invoke]
    }
}

# ::tk::ButtonAutoInvoke --
#
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782

proc ::tk::CheckLeave {w} {
    variable ::tk::Priv
    if {[$w cget -state] ne "disabled"} {
	$w configure -state normal
    }

    # Restore the original button "selected" color; but only if the user
    # has not changed it in the meantime.

    if {![$w cget -indicatoron] && [info exist Priv($w,selectcolor)]} {
        if {[$w cget -selectcolor] eq $Priv($w,selectcolor)
                || ([info exist Priv($w,aselectcolor)] &&
                    [$w cget -selectcolor] eq $Priv($w,aselectcolor))} {
	    $w configure -selectcolor $Priv($w,selectcolor)
	}
    }
    unset -nocomplain Priv($w,selectcolor) Priv($w,aselectcolor)

    # Restore the original button relief if it was changed by Tk. That is
    # signaled by the existence of Priv($w,prelief).

    if {[info exists Priv($w,relief)]} {
	if {[info exists Priv($w,prelief)] && \
		$Priv($w,prelief) eq [$w cget -relief]} {
	    $w configure -relief $Priv($w,relief)
	}
	unset -nocomplain Priv($w,relief) Priv($w,prelief)
    }

    set Priv(window) ""
}

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|
|


<
<
<
|
<
















<
<
<
<
<
<
<
730
731
732
733
734
735
736
737
738
739
740



741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757








proc ::tk::CheckLeave {w} {
    variable ::tk::Priv
    if {[$w cget -state] ne "disabled"} {
	$w configure -state normal
    }

    # Restore the original button "selected" color; assume that the user
    # wasn't monkeying around with things too much.

    if {![$w cget -indicatoron] && [info exist Priv($w,selectcolor)]} {



	$w configure -selectcolor $Priv($w,selectcolor)

    }
    unset -nocomplain Priv($w,selectcolor) Priv($w,aselectcolor)

    # Restore the original button relief if it was changed by Tk. That is
    # signaled by the existence of Priv($w,prelief).

    if {[info exists Priv($w,relief)]} {
	if {[info exists Priv($w,prelief)] && \
		$Priv($w,prelief) eq [$w cget -relief]} {
	    $w configure -relief $Priv($w,relief)
	}
	unset -nocomplain Priv($w,relief) Priv($w,prelief)
    }

    set Priv(window) ""
}







Changes to library/choosedir.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
# choosedir.tcl --
#
#	Choose directory dialog implementation for Unix/Mac.
#
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

# Make sure the tk::dialog namespace, in which all dialogs should live, exists
namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}

# Make the chooseDir namespace inside the dialog namespace




|







1
2
3
4
5
6
7
8
9
10
11
12
# choosedir.tcl --
#
#	Choose directory dialog implementation for Unix/Mac.
#
# Copyright (c) 1998-2000 by Scriptics Corporation.
# All rights reserved.

# Make sure the tk::dialog namespace, in which all dialogs should live, exists
namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}

# Make the chooseDir namespace inside the dialog namespace
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }
    $data(dirMenuBtn) configure -textvariable {}

    # Return value to user
    #

    return $Priv(selectFilePath)
}

# ::tk::dialog::file::chooseDir::Config --
#
#	Configures the Tk choosedir dialog according to the argument list
#







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }
    $data(dirMenuBtn) configure -textvariable {}

    # Return value to user
    #
    
    return $Priv(selectFilePath)
}

# ::tk::dialog::file::chooseDir::Config --
#
#	Configures the Tk choosedir dialog according to the argument list
#
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    # 3: parse the arguments
    #
    tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList

    if {$data(-title) eq ""} {
	set data(-title) "[mc "Choose Directory"]"
    }

    # Stub out the -multiple value for the dialog; it doesn't make sense for
    # choose directory dialogs, but we have to have something there because we
    # share so much code with the file dialogs.
    set data(-multiple) 0

    # 4: set the default directory and selection according to the -initial
    #    settings







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    # 3: parse the arguments
    #
    tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList

    if {$data(-title) eq ""} {
	set data(-title) "[mc "Choose Directory"]"
    }
    
    # Stub out the -multiple value for the dialog; it doesn't make sense for
    # choose directory dialogs, but we have to have something there because we
    # share so much code with the file dialogs.
    set data(-multiple) 0

    # 4: set the default directory and selection according to the -initial
    #    settings
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	    cd $old
	} else {
	    set data(selectPath) [pwd]
	}
    }

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }
}

# Gets called when user presses Return in the "Selection" entry or presses OK.
#
proc ::tk::dialog::file::chooseDir::OkCmd {w} {
    upvar ::tk::dialog::file::[winfo name $w] data







<
|







182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
	    cd $old
	} else {
	    set data(selectPath) [pwd]
	}
    }

    if {![winfo exists $data(-parent)]} {

	error "bad window path name \"$data(-parent)\""
    }
}

# Gets called when user presses Return in the "Selection" entry or presses OK.
#
proc ::tk::dialog::file::chooseDir::OkCmd {w} {
    upvar ::tk::dialog::file::[winfo name $w] data
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    # 3a.   If the value is the same as last time through here, end dialog.
    # 3b.   If the value is different than last time, save it and return.
    # 4.  If entry contains a valid directory, then...
    # 4a.   If the value is the same as the current directory, end dialog.
    # 4b.   If the value is different from the current directory, change to
    #       that directory.

    set selection [$data(icons) selection get]
    if {[llength $selection] != 0} {
	set iconText [$data(icons) get [lindex $selection 0]]
	set iconText [file join $data(selectPath) $iconText]
	Done $w $iconText
    } else {
	set text [$data(ent) get]
	if {$text eq ""} {
	    return
	}







|

|







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    # 3a.   If the value is the same as last time through here, end dialog.
    # 3b.   If the value is different than last time, save it and return.
    # 4.  If entry contains a valid directory, then...
    # 4a.   If the value is the same as the current directory, end dialog.
    # 4b.   If the value is different from the current directory, change to
    #       that directory.

    set selection [tk::IconList_CurSelection $data(icons)]
    if {[llength $selection] != 0} {
	set iconText [tk::IconList_Get $data(icons) [lindex $selection 0]]
	set iconText [file join $data(selectPath) $iconText]
	Done $w $iconText
    } else {
	set text [$data(ent) get]
	if {$text eq ""} {
	    return
	}
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272

    # always return 1
    return 1
}

proc ::tk::dialog::file::chooseDir::DblClick {w} {
    upvar ::tk::dialog::file::[winfo name $w] data
    set selection [$data(icons) selection get]
    if {[llength $selection] != 0} {
	set filenameFragment [$data(icons) get [lindex $selection 0]]

	set file $data(selectPath)
	if {[file isdirectory $file]} {
	    ::tk::dialog::file::ListInvoke $w [list $filenameFragment]
	    return
	}
    }
}







|

|
>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

    # always return 1
    return 1
}

proc ::tk::dialog::file::chooseDir::DblClick {w} {
    upvar ::tk::dialog::file::[winfo name $w] data
    set selection [tk::IconList_CurSelection $data(icons)]
    if {[llength $selection] != 0} {
	set filenameFragment \
		[tk::IconList_Get $data(icons) [lindex $selection 0]]
	set file $data(selectPath)
	if {[file isdirectory $file]} {
	    ::tk::dialog::file::ListInvoke $w [list $filenameFragment]
	    return
	}
    }
}

Changes to library/clrpick.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# clrpick.tcl --
#
#	Color selection dialog for platforms that do not support a
#	standard color selection dialog.
#
# Copyright © 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.
#
# ToDo:
#
#	(1): Find out how many free colors are left in the colormap and
#	     don't allocate too many colors.
#	(2): Implement HSV color selection.
#

# Make sure namespaces exist
namespace eval ::tk {}
namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::color {
    namespace import ::tk::msgcat::*





|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# clrpick.tcl --
#
#	Color selection dialog for platforms that do not support a
#	standard color selection dialog.
#
# 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.
#
# ToDo:
#
#	(1): Find out how many free colors are left in the colormap and
#	     don't allocate too many colors.
#	(2): Implement HSV color selection. 
#

# Make sure namespaces exist
namespace eval ::tk {}
namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::color {
    namespace import ::tk::msgcat::*
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    set data(NUM_COLORBARS) 16

    # BARS_WIDTH is the number of pixels wide the color bar portion of the
    # canvas is. This number must be a multiple of NUM_COLORBARS
    set data(BARS_WIDTH) 160

    # PLGN_WIDTH is the number of pixels wide of the triangular selection
    # polygon. This also results in the definition of the padding on the
    # left and right sides which is half of PLGN_WIDTH. Make this number even.
    set data(PLGN_HEIGHT) 10

    # PLGN_HEIGHT is the height of the selection polygon and the height of the
    # selection rectangle at the bottom of the color bar. No restrictions.
    set data(PLGN_WIDTH) 10

    Config $dataName $args
    InitValues $dataName

    set sc [winfo screen $data(-parent)]







|



|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    set data(NUM_COLORBARS) 16

    # BARS_WIDTH is the number of pixels wide the color bar portion of the
    # canvas is. This number must be a multiple of NUM_COLORBARS
    set data(BARS_WIDTH) 160

    # PLGN_WIDTH is the number of pixels wide of the triangular selection
    # polygon. This also results in the definition of the padding on the 
    # left and right sides which is half of PLGN_WIDTH. Make this number even.
    set data(PLGN_HEIGHT) 10

    # PLGN_HEIGHT is the height of the selection polygon and the height of the 
    # selection rectangle at the bottom of the color bar. No restrictions.
    set data(PLGN_WIDTH) 10

    Config $dataName $args
    InitValues $dataName

    set sc [winfo screen $data(-parent)]
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    #
    tclParseConfigSpec ::tk::dialog::color::$dataName $specs "" $argList

    if {$data(-title) eq ""} {
	set data(-title) " "
    }
    if {[catch {winfo rgb . $data(-initialcolor)} err]} {
	return -code error -errorcode [list TK LOOKUP COLOR $data(-initialcolor)] \
	    $err
    }

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }
}

# ::tk::dialog::color::BuildDialog --
#
#	Build the dialog.
#







<
|



<
|







186
187
188
189
190
191
192

193
194
195
196

197
198
199
200
201
202
203
204
    #
    tclParseConfigSpec ::tk::dialog::color::$dataName $specs "" $argList

    if {$data(-title) eq ""} {
	set data(-title) " "
    }
    if {[catch {winfo rgb . $data(-initialcolor)} err]} {

	error $err
    }

    if {![winfo exists $data(-parent)]} {

	error "bad window path name \"$data(-parent)\""
    }
}

# ::tk::dialog::color::BuildDialog --
#
#	Build the dialog.
#
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
    grid columnconfigure $botFrame {0 4} -weight 1 -uniform space
    grid columnconfigure $botFrame {1 3} -weight 1 -uniform button
    grid columnconfigure $botFrame 2 -weight 2 -uniform space
    pack $botFrame -side bottom -fill x

    # Accelerator bindings
    bind $lab <<AltUnderlined>> [list focus $ent]
    bind $w <Escape> [list tk::ButtonInvoke $data(cancelBtn)]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    wm protocol $w WM_DELETE_WINDOW [list tk::dialog::color::CancelCmd $w]
    bind $lab <Destroy> [list tk::dialog::color::CancelCmd $w]
}

# ::tk::dialog::color::SetRGBValue --
#
#	Sets the current selection of the dialog box
#
proc ::tk::dialog::color::SetRGBValue {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data

    set data(red,intensity)   [lindex $color 0]
    set data(green,intensity) [lindex $color 1]
    set data(blue,intensity)  [lindex $color 2]

    RedrawColorBars $w all








|











|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    grid columnconfigure $botFrame {0 4} -weight 1 -uniform space
    grid columnconfigure $botFrame {1 3} -weight 1 -uniform button
    grid columnconfigure $botFrame 2 -weight 2 -uniform space
    pack $botFrame -side bottom -fill x

    # Accelerator bindings
    bind $lab <<AltUnderlined>> [list focus $ent]
    bind $w <KeyPress-Escape> [list tk::ButtonInvoke $data(cancelBtn)]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    wm protocol $w WM_DELETE_WINDOW [list tk::dialog::color::CancelCmd $w]
    bind $lab <Destroy> [list tk::dialog::color::CancelCmd $w]
}

# ::tk::dialog::color::SetRGBValue --
#
#	Sets the current selection of the dialog box
#
proc ::tk::dialog::color::SetRGBValue {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data 

    set data(red,intensity)   [lindex $color 0]
    set data(green,intensity) [lindex $color 1]
    set data(blue,intensity)  [lindex $color 2]

    RedrawColorBars $w all

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
proc ::tk::dialog::color::RgbToX {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data

    return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}]
}

# ::tk::dialog::color::DrawColorScale --
#
#	Draw color scale is called whenever the size of one of the color
#	scale canvases is changed.
#
proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
    upvar ::tk::dialog::color::[winfo name $w] data

    # col: color bar canvas







|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
proc ::tk::dialog::color::RgbToX {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data

    return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}]
}

# ::tk::dialog::color::DrawColorScale --
# 
#	Draw color scale is called whenever the size of one of the color
#	scale canvases is changed.
#
proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
    upvar ::tk::dialog::color::[winfo name $w] data

    # col: color bar canvas
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
	# Delete the selector if it exists
	if {[info exists data($c,index)]} {
	    $sel delete $data($c,index)
	}

	# Draw the selection polygons
	CreateSelector $w $sel $c
	$sel bind $data($c,index) <Button-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(selPad) 1]
	$sel bind $data($c,index) <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)]
	$sel bind $data($c,index) <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)]

	set height [winfo height $col]
	# Create an invisible region under the colorstrip to catch mouse clicks
	# that aren't on the selector.
	set data($c,clickRegion) [$sel create rectangle 0 0 \
		$data(canvasWidth) $height -fill {} -outline {}]

	bind $col <Button-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(colorPad)]
	bind $col <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(colorPad)]
	bind $col <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(colorPad)]

	$sel bind $data($c,clickRegion) <Button-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(selPad)]
	$sel bind $data($c,clickRegion) <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)]
	$sel bind $data($c,clickRegion) <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)]
    } else {
	# l is the canvas index of the first colorbar.







|












|






|







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
	# Delete the selector if it exists
	if {[info exists data($c,index)]} {
	    $sel delete $data($c,index)
	}

	# Draw the selection polygons
	CreateSelector $w $sel $c
	$sel bind $data($c,index) <ButtonPress-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(selPad) 1]
	$sel bind $data($c,index) <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)]
	$sel bind $data($c,index) <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)]

	set height [winfo height $col]
	# Create an invisible region under the colorstrip to catch mouse clicks
	# that aren't on the selector.
	set data($c,clickRegion) [$sel create rectangle 0 0 \
		$data(canvasWidth) $height -fill {} -outline {}]

	bind $col <ButtonPress-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(colorPad)]
	bind $col <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(colorPad)]
	bind $col <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(colorPad)]

	$sel bind $data($c,clickRegion) <ButtonPress-1> \
		[list tk::dialog::color::StartMove $w $sel $c %x $data(selPad)]
	$sel bind $data($c,clickRegion) <B1-Motion> \
		[list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)]
	$sel bind $data($c,clickRegion) <ButtonRelease-1> \
		[list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)]
    } else {
	# l is the canvas index of the first colorbar.
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# Params: color of colorstrip that changed. If color is not [red|green|blue]
#         Then all colorstrips will be updated
#
proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
    upvar ::tk::dialog::color::[winfo name $w] data

    switch $colorChanged {
	red {
	    DrawColorScale $w green
	    DrawColorScale $w blue
	}
	green {
	    DrawColorScale $w red
	    DrawColorScale $w blue
	}







|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# Params: color of colorstrip that changed. If color is not [red|green|blue]
#         Then all colorstrips will be updated
#
proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
    upvar ::tk::dialog::color::[winfo name $w] data

    switch $colorChanged {
	red { 
	    DrawColorScale $w green
	    DrawColorScale $w blue
	}
	green {
	    DrawColorScale $w red
	    DrawColorScale $w blue
	}
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
#----------------------------------------------------------------------

# ::tk::dialog::color::StartMove --
#
#	Handles a mousedown button event over the selector polygon.
#	Adds the bindings for moving the mouse while the button is
#	pressed.  Sets the binding for the button-release event.
#
# Params: sel is the selector canvas window, color is the color of the strip.
#
proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
    upvar ::tk::dialog::color::[winfo name $w] data

    if {!$dontMove} {
	MoveSelector $w $sel $color $x $delta
    }
}

# ::tk::dialog::color::MoveSelector --
#
# Moves the polygon selector so that its middle point has the same
# x value as the specified x. If x is outside the bounds [0,255],
# the selector is set to the closest endpoint.
#
# Params: sel is the selector canvas, c is [red|green|blue]
#         x is a x-coordinate.
#







|











|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
#----------------------------------------------------------------------

# ::tk::dialog::color::StartMove --
#
#	Handles a mousedown button event over the selector polygon.
#	Adds the bindings for moving the mouse while the button is
#	pressed.  Sets the binding for the button-release event.
# 
# Params: sel is the selector canvas window, color is the color of the strip.
#
proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
    upvar ::tk::dialog::color::[winfo name $w] data

    if {!$dontMove} {
	MoveSelector $w $sel $color $x $delta
    }
}

# ::tk::dialog::color::MoveSelector --
# 
# Moves the polygon selector so that its middle point has the same
# x value as the specified x. If x is outside the bounds [0,255],
# the selector is set to the closest endpoint.
#
# Params: sel is the selector canvas, c is [red|green|blue]
#         x is a x-coordinate.
#
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
#
# Removes mouse tracking bindings, updates the colorbars.
#
# Params: sel is the selector canvas, color is the color of the strip,
#         x is the x-coord of the mouse.
#
proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
    upvar ::tk::dialog::color::[winfo name $w] data

    set x [MoveSelector $w $sel $color $x $delta]

    # Determine exactly what color we are looking at.
    set data($color,intensity) [XToRgb $w $x]

    RedrawColorBars $w $color
}

# ::tk::dialog::color::ResizeColorbars --
#
#	Completely redraws the colorbars, including resizing the
#	colorstrips
#
proc ::tk::dialog::color::ResizeColorBars {w} {
    upvar ::tk::dialog::color::[winfo name $w] data

    if {
	($data(BARS_WIDTH) < $data(NUM_COLORBARS)) ||
	(($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)
    } then {
	set data(BARS_WIDTH) $data(NUM_COLORBARS)
    }
    InitValues [winfo name $w]
    foreach color {red green blue} {
	$data($color,col) configure -width $data(canvasWidth)







|


















|







577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
#
# Removes mouse tracking bindings, updates the colorbars.
#
# Params: sel is the selector canvas, color is the color of the strip,
#         x is the x-coord of the mouse.
#
proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
    upvar ::tk::dialog::color::[winfo name $w] data 

    set x [MoveSelector $w $sel $color $x $delta]

    # Determine exactly what color we are looking at.
    set data($color,intensity) [XToRgb $w $x]

    RedrawColorBars $w $color
}

# ::tk::dialog::color::ResizeColorbars --
#
#	Completely redraws the colorbars, including resizing the
#	colorstrips
#
proc ::tk::dialog::color::ResizeColorBars {w} {
    upvar ::tk::dialog::color::[winfo name $w] data

    if {
	($data(BARS_WIDTH) < $data(NUM_COLORBARS)) || 
	(($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)
    } then {
	set data(BARS_WIDTH) $data(NUM_COLORBARS)
    }
    InitValues [winfo name $w]
    foreach color {red green blue} {
	$data($color,col) configure -width $data(canvasWidth)
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
	if {$data($c,intensity) > 255} {
	    set data($c,intensity) 255
	}
    }

    SetRGBValue $w "$data(red,intensity) \
	$data(green,intensity) $data(blue,intensity)"
}

# mouse cursor enters a color bar
#
proc ::tk::dialog::color::EnterColorBar {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data

    $data($color,sel) itemconfigure $data($color,index) -fill red







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	if {$data($c,intensity) > 255} {
	    set data($c,intensity) 255
	}
    }

    SetRGBValue $w "$data(red,intensity) \
	$data(green,intensity) $data(blue,intensity)"
}    

# mouse cursor enters a color bar
#
proc ::tk::dialog::color::EnterColorBar {w color} {
    upvar ::tk::dialog::color::[winfo name $w] data

    $data($color,sel) itemconfigure $data($color,index) -fill red

Changes to library/comdlg.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
# comdlg.tcl --
#
#	Some functions needed for the common dialog boxes. Probably need to go
#	in a different file.
#
# Copyright © 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.
#

# tclParseConfigSpec --
#





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# comdlg.tcl --
#
#	Some functions needed for the common dialog boxes. Probably need to go
#	in a different file.
#
# 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.
#

# tclParseConfigSpec --
#
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
proc tclParseConfigSpec {w specs flags argList} {
    upvar #0 $w data

    # 1: Put the specs in associative arrays for faster access
    #
    foreach spec $specs {
	if {[llength $spec] < 4} {
	    return -code error -errorcode {TK VALUE CONFIG_SPEC} \
		"\"spec\" should contain 5 or 4 elements"
	}
	set cmdsw [lindex $spec 0]
	set cmd($cmdsw) ""
	set rname($cmdsw)   [lindex $spec 1]
	set rclass($cmdsw)  [lindex $spec 2]
	set def($cmdsw)     [lindex $spec 3]
	set verproc($cmdsw) [lindex $spec 4]
    }

    if {[llength $argList] & 1} {
	set cmdsw [lindex $argList end]
	if {![info exists cmd($cmdsw)]} {
	    return -code error -errorcode [list TK LOOKUP OPTION $cmdsw] \
		"bad option \"$cmdsw\": must be [tclListValidFlags cmd]"
	}
	return -code error -errorcode {TK VALUE_MISSING} \
	    "value for \"$cmdsw\" missing"
    }

    # 2: set the default values
    #
    foreach cmdsw [array names cmd] {
	set data($cmdsw) $def($cmdsw)
    }

    # 3: parse the argument list
    #
    foreach {cmdsw value} $argList {
	if {![info exists cmd($cmdsw)]} {
	    return -code error -errorcode [list TK LOOKUP OPTION $cmdsw] \
		"bad option \"$cmdsw\": must be [tclListValidFlags cmd]"
	}
	set data($cmdsw) $value
    }

    # Done!
}








<
|












<
|

<
|












<
|







36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55

56
57

58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
proc tclParseConfigSpec {w specs flags argList} {
    upvar #0 $w data

    # 1: Put the specs in associative arrays for faster access
    #
    foreach spec $specs {
	if {[llength $spec] < 4} {

	    error "\"spec\" should contain 5 or 4 elements"
	}
	set cmdsw [lindex $spec 0]
	set cmd($cmdsw) ""
	set rname($cmdsw)   [lindex $spec 1]
	set rclass($cmdsw)  [lindex $spec 2]
	set def($cmdsw)     [lindex $spec 3]
	set verproc($cmdsw) [lindex $spec 4]
    }

    if {[llength $argList] & 1} {
	set cmdsw [lindex $argList end]
	if {![info exists cmd($cmdsw)]} {

	    error "bad option \"$cmdsw\": must be [tclListValidFlags cmd]"
	}

	error "value for \"$cmdsw\" missing"
    }

    # 2: set the default values
    #
    foreach cmdsw [array names cmd] {
	set data($cmdsw) $def($cmdsw)
    }

    # 3: parse the argument list
    #
    foreach {cmdsw value} $argList {
	if {![info exists cmd($cmdsw)]} {

	    error "bad option \"$cmdsw\": must be [tclListValidFlags cmd]"
	}
	set data($cmdsw) $value
    }

    # Done!
}

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#	within the same focus toplevel. Each toplevel can have only
#	one focus group, which is identified by the name of the
#	toplevel widget.
#
proc ::tk::FocusGroup_Create {t} {
    variable ::tk::Priv
    if {[winfo toplevel $t] ne $t} {
	return -code error -errorcode [list TK LOOKUP TOPLEVEL $t] \
	    "$t is not a toplevel window"
    }
    if {![info exists Priv(fg,$t)]} {
	set Priv(fg,$t) 1
	set Priv(focus,$t) ""
	bind $t <FocusIn>  [list tk::FocusGroup_In  $t %W %d]
	bind $t <FocusOut> [list tk::FocusGroup_Out $t %W %d]
	bind $t <Destroy>  [list tk::FocusGroup_Destroy $t %W]
    }
}

# ::tk::FocusGroup_BindIn --
#
# Add a widget into the "FocusIn" list of the focus group. The $cmd will be
# called when the widget is focused on by the user.
#
proc ::tk::FocusGroup_BindIn {t w cmd} {
    variable FocusIn
    variable ::tk::Priv
    if {![info exists Priv(fg,$t)]} {
	return -code error -errorcode [list TK LOOKUP FOCUS_GROUP $t] \
	    "focus group \"$t\" doesn't exist"
    }
    set FocusIn($t,$w) $cmd
}


# ::tk::FocusGroup_BindOut --
#
#	Add a widget into the "FocusOut" list of the focus group. The
#	$cmd will be called when the widget loses the focus (User
#	types Tab or click on another widget).
#
proc ::tk::FocusGroup_BindOut {t w cmd} {
    variable FocusOut
    variable ::tk::Priv
    if {![info exists Priv(fg,$t)]} {
	return -code error -errorcode [list TK LOOKUP FOCUS_GROUP $t] \
	    "focus group \"$t\" doesn't exist"
    }
    set FocusOut($t,$w) $cmd
}

# ::tk::FocusGroup_Destroy --
#
#	Cleans up when members of the focus group is deleted, or when the
#	toplevel itself gets deleted.
#
proc ::tk::FocusGroup_Destroy {t w} {
    variable FocusIn
    variable FocusOut
    variable ::tk::Priv

    if {$t eq $w} {
	unset Priv(fg,$t)
	unset Priv(focus,$t)

	foreach name [array names FocusIn $t,*] {
	    unset FocusIn($name)
	}
	foreach name [array names FocusOut $t,*] {
	    unset FocusOut($name)
	}







<
|



















<
|















<
|
















|







116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#	within the same focus toplevel. Each toplevel can have only
#	one focus group, which is identified by the name of the
#	toplevel widget.
#
proc ::tk::FocusGroup_Create {t} {
    variable ::tk::Priv
    if {[winfo toplevel $t] ne $t} {

	error "$t is not a toplevel window"
    }
    if {![info exists Priv(fg,$t)]} {
	set Priv(fg,$t) 1
	set Priv(focus,$t) ""
	bind $t <FocusIn>  [list tk::FocusGroup_In  $t %W %d]
	bind $t <FocusOut> [list tk::FocusGroup_Out $t %W %d]
	bind $t <Destroy>  [list tk::FocusGroup_Destroy $t %W]
    }
}

# ::tk::FocusGroup_BindIn --
#
# Add a widget into the "FocusIn" list of the focus group. The $cmd will be
# called when the widget is focused on by the user.
#
proc ::tk::FocusGroup_BindIn {t w cmd} {
    variable FocusIn
    variable ::tk::Priv
    if {![info exists Priv(fg,$t)]} {

	error "focus group \"$t\" doesn't exist"
    }
    set FocusIn($t,$w) $cmd
}


# ::tk::FocusGroup_BindOut --
#
#	Add a widget into the "FocusOut" list of the focus group. The
#	$cmd will be called when the widget loses the focus (User
#	types Tab or click on another widget).
#
proc ::tk::FocusGroup_BindOut {t w cmd} {
    variable FocusOut
    variable ::tk::Priv
    if {![info exists Priv(fg,$t)]} {

	error "focus group \"$t\" doesn't exist"
    }
    set FocusOut($t,$w) $cmd
}

# ::tk::FocusGroup_Destroy --
#
#	Cleans up when members of the focus group is deleted, or when the
#	toplevel itself gets deleted.
#
proc ::tk::FocusGroup_Destroy {t w} {
    variable FocusIn
    variable FocusOut
    variable ::tk::Priv

    if {$t eq $w} {
	unset Priv(fg,$t)
	unset Priv(focus,$t) 

	foreach name [array names FocusIn $t,*] {
	    unset FocusIn($name)
	}
	foreach name [array names FocusOut $t,*] {
	    unset FocusOut($name)
	}
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#	Process the string given by the -filetypes option of the file
#	dialogs. Similar to the C function TkGetFileFilters() on the Mac
#	and Windows platform.
#
proc ::tk::FDGetFileTypes {string} {
    foreach t $string {
	if {[llength $t] < 2 || [llength $t] > 3} {
	    return -code error -errorcode {TK VALUE FILE_TYPE} \
		"bad file type \"$t\", should be \"typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?\""
	}
	lappend fileTypes([lindex $t 0]) {*}[lindex $t 1]
    }

    set types {}
    foreach t $string {
	set label [lindex $t 0]
	set exts {}

	if {[info exists hasDoneType($label)]} {
	    continue
	}

	# Validate each macType.  This is to agree with the
	# behaviour of TkGetFileFilters().  This list may be
	# empty.
	foreach macType [lindex $t 2] {
	    if {[string length $macType] != 4} {
		return -code error -errorcode {TK VALUE MAC_TYPE} \
		    "bad Macintosh file type \"$macType\""
	    }
	}

	set name "$label \("
	set sep ""
	set doAppend 1
	foreach ext $fileTypes($label) {
	    if {$ext eq ""} {
		continue
	    }







<
|













|




<
|


|







251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
#	Process the string given by the -filetypes option of the file
#	dialogs. Similar to the C function TkGetFileFilters() on the Mac
#	and Windows platform.
#
proc ::tk::FDGetFileTypes {string} {
    foreach t $string {
	if {[llength $t] < 2 || [llength $t] > 3} {

	    error "bad file type \"$t\", should be \"typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?\""
	}
	lappend fileTypes([lindex $t 0]) {*}[lindex $t 1]
    }

    set types {}
    foreach t $string {
	set label [lindex $t 0]
	set exts {}

	if {[info exists hasDoneType($label)]} {
	    continue
	}

	# Validate each macType.  This is to agree with the 
	# behaviour of TkGetFileFilters().  This list may be
	# empty.
	foreach macType [lindex $t 2] {
	    if {[string length $macType] != 4} {

		error "bad Macintosh file type \"$macType\""
	    }
	}
	
	set name "$label \("
	set sep ""
	set doAppend 1
	foreach ext $fileTypes($label) {
	    if {$ext eq ""} {
		continue
	    }

Changes to library/console.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43


44
45
46
47
48
49
50
# console.tcl --
#
# This code constructs the console window for an application.  It
# can be used by non-unix systems that do not have built-in support
# for shells.
#
# Copyright © 1995-1997 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2007-2008 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.
#

# TODO: history - remember partially written command

namespace eval ::tk::console {
    variable blinkTime   500 ; # msecs to blink braced range for
    variable blinkRange  1   ; # enable blinking of the entire braced range
    variable magicKeys   1   ; # enable brace matching and proc/var recognition
    variable maxLines    600 ; # maximum # of lines buffered in console
    variable showMatches 1   ; # show multiple expand matches
    variable useFontchooser [llength [info command ::tk::fontchooser]]
    variable inPlugin [info exists embed_args]
    variable defaultPrompt   ; # default prompt if tcl_prompt1 isn't used


    if {$inPlugin} {
	set defaultPrompt {subst {[history nextid] % }}
    } else {
	set defaultPrompt {subst {([file tail [pwd]]) [history nextid] % }}
    }
}

# simple compat function for tkcon code added for this console
interp alias {} EvalAttached {} consoleinterp eval

# ::tk::ConsoleInit --
# This procedure constructs and configures the console windows.
#
# Arguments:
# 	None.

proc ::tk::ConsoleInit {} {


    if {![consoleinterp eval {set tcl_interactive}]} {
	wm withdraw .
    }

    if {[tk windowingsystem] eq "aqua"} {
	set mod "Cmd"
    } else {






|
|
|













|


>


















>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# console.tcl --
#
# This code constructs the console window for an application.  It
# can be used by non-unix systems that do not have built-in support
# for shells.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# 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.
#

# TODO: history - remember partially written command

namespace eval ::tk::console {
    variable blinkTime   500 ; # msecs to blink braced range for
    variable blinkRange  1   ; # enable blinking of the entire braced range
    variable magicKeys   1   ; # enable brace matching and proc/var recognition
    variable maxLines    600 ; # maximum # of lines buffered in console
    variable showMatches 1   ; # show multiple expand matches

    variable inPlugin [info exists embed_args]
    variable defaultPrompt   ; # default prompt if tcl_prompt1 isn't used


    if {$inPlugin} {
	set defaultPrompt {subst {[history nextid] % }}
    } else {
	set defaultPrompt {subst {([file tail [pwd]]) [history nextid] % }}
    }
}

# simple compat function for tkcon code added for this console
interp alias {} EvalAttached {} consoleinterp eval

# ::tk::ConsoleInit --
# This procedure constructs and configures the console windows.
#
# Arguments:
# 	None.

proc ::tk::ConsoleInit {} {
    global tcl_platform

    if {![consoleinterp eval {set tcl_interactive}]} {
	wm withdraw .
    }

    if {[tk windowingsystem] eq "aqua"} {
	set mod "Cmd"
    } else {
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    AmpMenuArgs	.menubar.edit add command -label [mc Cu&t]   -accel "$mod+X"\
	    -command {event generate .console <<Cut>>}
    AmpMenuArgs	.menubar.edit add command -label [mc &Copy]  -accel "$mod+C"\
	    -command {event generate .console <<Copy>>}
    AmpMenuArgs	.menubar.edit add command -label [mc P&aste] -accel "$mod+V"\
	    -command {event generate .console <<Paste>>}

    if {[tk windowingsystem] ne "win32"} {
	AmpMenuArgs .menubar.edit add command -label [mc Cl&ear] \
		-command {event generate .console <<Clear>>}
    } else {
	AmpMenuArgs .menubar.edit add command -label [mc &Delete] \
		-command {event generate .console <<Clear>>} -accel "Del"

	AmpMenuArgs .menubar add cascade -label [mc &Help] -menu .menubar.help
	menu .menubar.help -tearoff 0
	AmpMenuArgs .menubar.help add command -label [mc &About...] \
		-command tk::ConsoleAbout
    }

    AmpMenuArgs .menubar.edit add separator
    if {$::tk::console::useFontchooser} {
        if {[tk windowingsystem] eq "aqua"} {
            .menubar.edit add command -label tk_choose_font_marker
            set index [.menubar.edit index tk_choose_font_marker]
            .menubar.edit entryconfigure $index \
                -label [mc "Show Fonts"]\
                -accelerator "$mod-T"\
                -command [list ::tk::console::FontchooserToggle]
            bind Console <<TkFontchooserVisibility>> \
                [list ::tk::console::FontchooserVisibility $index]
	    ::tk::console::FontchooserVisibility $index
        } else {
            AmpMenuArgs .menubar.edit add command -label [mc "&Font..."] \
                -command [list ::tk::console::FontchooserToggle]
        }
	bind Console <FocusIn>  [list ::tk::console::FontchooserFocus %W 1]
	bind Console <FocusOut> [list ::tk::console::FontchooserFocus %W 0]
    }
    AmpMenuArgs .menubar.edit add command -label [mc "&Increase Font Size"] \
        -accel "$mod++" -command {event generate .console <<Console_FontSizeIncr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "&Decrease Font Size"] \
        -accel "$mod+-" -command {event generate .console <<Console_FontSizeDecr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "Fit To Screen Width"] \
        -command {event generate .console <<Console_FitScreenWidth>>}

    if {[tk windowingsystem] eq "aqua"} {
	.menubar add cascade -label [mc Window] -menu [menu .menubar.window]
	.menubar add cascade -label [mc Help] -menu [menu .menubar.help]
    }

    . configure -menu .menubar

    # See if we can find a better font than the TkFixedFont
    catch {font create TkConsoleFont {*}[font configure TkFixedFont]}
    set families [font families]
    switch -exact -- [tk windowingsystem] {
        aqua { set preferred {Monaco 10} }
        win32 { set preferred {ProFontWindows 8 Consolas 8} }
        default { set preferred {} }
    }
    foreach {family size} $preferred {
        if {$family in $families} {
            font configure TkConsoleFont -family $family -size $size
            break
        }
    }

    # Provide the right border for the text widget (platform dependent).
    ::ttk::style layout ConsoleFrame {







|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
<
<
<
<
<
<












|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95


















96
97
98
99







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    AmpMenuArgs	.menubar.edit add command -label [mc Cu&t]   -accel "$mod+X"\
	    -command {event generate .console <<Cut>>}
    AmpMenuArgs	.menubar.edit add command -label [mc &Copy]  -accel "$mod+C"\
	    -command {event generate .console <<Copy>>}
    AmpMenuArgs	.menubar.edit add command -label [mc P&aste] -accel "$mod+V"\
	    -command {event generate .console <<Paste>>}

    if {$tcl_platform(platform) ne "windows"} {
	AmpMenuArgs .menubar.edit add command -label [mc Cl&ear] \
		-command {event generate .console <<Clear>>}
    } else {
	AmpMenuArgs .menubar.edit add command -label [mc &Delete] \
		-command {event generate .console <<Clear>>} -accel "Del"

	AmpMenuArgs .menubar add cascade -label [mc &Help] -menu .menubar.help
	menu .menubar.help -tearoff 0
	AmpMenuArgs .menubar.help add command -label [mc &About...] \
		-command tk::ConsoleAbout
    }

    AmpMenuArgs .menubar.edit add separator


















    AmpMenuArgs .menubar.edit add command -label [mc "&Increase Font Size"] \
        -accel "$mod++" -command {event generate .console <<Console_FontSizeIncr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "&Decrease Font Size"] \
        -accel "$mod+-" -command {event generate .console <<Console_FontSizeDecr>>}








    . configure -menu .menubar

    # See if we can find a better font than the TkFixedFont
    catch {font create TkConsoleFont {*}[font configure TkFixedFont]}
    set families [font families]
    switch -exact -- [tk windowingsystem] {
        aqua { set preferred {Monaco 10} }
        win32 { set preferred {ProFontWindows 8 Consolas 8} }
        default { set preferred {} }
    }
    foreach {family size} $preferred {
        if {[lsearch -exact $families $family] != -1} {
            font configure TkConsoleFont -family $family -size $size
            break
        }
    }

    # Provide the right border for the text widget (platform dependent).
    ::ttk::style layout ConsoleFrame {
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	$w insert output $string stdout
    }
    $w mark set output $temp
    ::tk::TextSetCursor $w end
    $w mark set promptEnd insert
    $w mark gravity promptEnd left

    if {[tk windowingsystem] ne "aqua"} {
	# Subtle work-around to erase the '% ' that tclMain.c prints out
	after idle [subst -nocommand {
	    if {[$con get 1.0 output] eq "% "} { $con delete 1.0 output }
	}]
    }
}








|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	$w insert output $string stdout
    }
    $w mark set output $temp
    ::tk::TextSetCursor $w end
    $w mark set promptEnd insert
    $w mark gravity promptEnd left

    if {$tcl_platform(platform) eq "windows"} {
	# Subtle work-around to erase the '% ' that tclMain.c prints out
	after idle [subst -nocommand {
	    if {[$con get 1.0 output] eq "% "} { $con delete 1.0 output }
	}]
    }
}

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
proc ::tk::ConsoleSource {} {
    set filename [tk_getOpenFile -defaultextension .tcl -parent . \
	    -title [mc "Select a file to source"] \
	    -filetypes [list \
	    [list [mc "Tcl Scripts"] .tcl] \
	    [list [mc "All Files"] *]]]
    if {$filename ne ""} {
    	set cmd [list source -encoding utf-8 $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --







|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
proc ::tk::ConsoleSource {} {
    set filename [tk_getOpenFile -defaultextension .tcl -parent . \
	    -title [mc "Select a file to source"] \
	    -filetypes [list \
	    [list [mc "Tcl Scripts"] .tcl] \
	    [list [mc "All Files"] *]]]
    if {$filename ne ""} {
    	set cmd [list source $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	    }
    	    if {[catch {consoleinterp eval $cmd} cmd]} {
    	    	incr HistNum
    	    	return
    	    }
	    .console delete promptEnd end
    	    .console insert promptEnd $cmd {input stdin}
	    .console see end
    	}
    	next {
	    incr HistNum
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } elseif {$HistNum > 0} {
		set cmd ""
		set HistNum 1
	    } else {
		set cmd "history event $HistNum"
	    }
	    if {$cmd ne ""} {
		catch {consoleinterp eval $cmd} cmd
	    }
	    .console delete promptEnd end
	    .console insert promptEnd $cmd {input stdin}
	    .console see end
    	}
    	reset {
    	    set HistNum 1
    	}
    }
}

# ::tk::ConsolePrompt --
# This procedure draws the prompt.  If tcl_prompt1 or tcl_prompt2
# exists in the main interpreter it will be called to generate the
# prompt.  Otherwise, a hard coded default prompt is printed.
#
# Arguments:
# partial -	Flag to specify which prompt to print.

proc ::tk::ConsolePrompt {{partial normal}} {
    set w .console







<
















<









|







260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
	    }
    	    if {[catch {consoleinterp eval $cmd} cmd]} {
    	    	incr HistNum
    	    	return
    	    }
	    .console delete promptEnd end
    	    .console insert promptEnd $cmd {input stdin}

    	}
    	next {
	    incr HistNum
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } elseif {$HistNum > 0} {
		set cmd ""
		set HistNum 1
	    } else {
		set cmd "history event $HistNum"
	    }
	    if {$cmd ne ""} {
		catch {consoleinterp eval $cmd} cmd
	    }
	    .console delete promptEnd end
	    .console insert promptEnd $cmd {input stdin}

    	}
    	reset {
    	    set HistNum 1
    	}
    }
}

# ::tk::ConsolePrompt --
# This procedure draws the prompt.  If tcl_prompt1 or tcl_prompt2
# exists in the main interpreter it will be called to generate the 
# prompt.  Otherwise, a hard coded default prompt is printed.
#
# Arguments:
# partial -	Flag to specify which prompt to print.

proc ::tk::ConsolePrompt {{partial normal}} {
    set w .console
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
            tk::ConsoleInsert $w "\n"
            tk::ConsoleInvoke
            tk::ConsoleInsert $w $x
        }
    }
}

# Fit TkConsoleFont to window width
proc ::tk::console::FitScreenWidth {w} {
    set width [winfo screenwidth $w]
    set cwidth [$w cget -width]
    set s -50
    set fit 0
    array set fi [font configure TkConsoleFont]
    while {$s < 0} {
        set fi(-size) $s
        set f [font create {*}[array get fi]]
        set c [font measure $f "eM"]
        font delete $f
        if {$c * $cwidth < 1.667 * $width} {
            font configure TkConsoleFont -size $s
            break
        }
	incr s 2
    }
}

# ::tk::ConsoleBind --
# This procedure first ensures that the default bindings for the Text
# class have been defined.  Then certain bindings are overridden for
# the class.
#
# Arguments:
# None.

proc ::tk::ConsoleBind {w} {
    bindtags $w [list $w Console PostConsole [winfo toplevel $w] all]

    ## Get all Text bindings into Console
    foreach ev [bind Text] {
	bind Console $ev [bind Text $ev]
    }
    ## We really didn't want the newline insertion...
    bind Console <Control-o> {}
    ## ...or any Control-v binding (would block <<Paste>>)
    bind Console <Control-v> {}

    # For the moment, transpose isn't enabled until the console
    # gets and overhaul of how it handles input -- hobbs
    bind Console <Control-t> {}

    # Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
    # Otherwise, if a widget binding for one of these is defined, the
    # <Keypress> class binding will also fire and insert the character
    # which is wrong.

    bind Console <Alt-Key> {# nothing }
    bind Console <Meta-Key> {# nothing}
    bind Console <Control-Key> {# nothing}

    foreach {ev key} {


	<<Console_NextImmediate>>	<Control-n>
	<<Console_PrevImmediate>>	<Control-p>
	<<Console_PrevSearch>>		<Control-r>
	<<Console_NextSearch>>		<Control-s>

	<<Console_Expand>>		<Tab>
	<<Console_Expand>>		<Escape>
	<<Console_ExpandFile>>		<Control-Shift-F>
	<<Console_ExpandProc>>		<Control-Shift-P>
	<<Console_ExpandVar>>		<Control-Shift-V>
	<<Console_Tab>>			<Control-i>
	<<Console_Tab>>			<Meta-i>
	<<Console_Eval>>		<Return>
	<<Console_Eval>>		<KP_Enter>

	<<Console_Clear>>		<Control-l>
	<<Console_KillLine>>		<Control-k>
	<<Console_Transpose>>		<Control-t>
	<<Console_ClearLine>>		<Control-u>
	<<Console_SaveCommand>>		<Control-z>
	<<Console_FontSizeIncr>>	<Control-plus>
	<<Console_FontSizeDecr>>	<Control-minus>
    } {
	event add $ev $key
	bind Console $key {}
    }
    if {[tk windowingsystem] eq "aqua"} {
	foreach {ev key} {
	    <<Console_FontSizeIncr>>	<Command-plus>
	    <<Console_FontSizeDecr>>	<Command-minus>
	} {
	    event add $ev $key
	    bind Console $key {}
	}
	if {$::tk::console::useFontchooser} {
	    bind Console <Command-t> [list ::tk::console::FontchooserToggle]
	}
    }
    bind Console <<Console_Expand>> {
	if {[%W compare insert > promptEnd]} {
	    ::tk::console::Expand %W
	}
    }
    bind Console <<Console_ExpandFile>> {







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|

|



|






|
|
|


>
>
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|






|
|




<
<
<







352
353
354
355
356
357
358




















359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428



429
430
431
432
433
434
435
            tk::ConsoleInsert $w "\n"
            tk::ConsoleInvoke
            tk::ConsoleInsert $w $x
        }
    }
}





















# ::tk::ConsoleBind --
# This procedure first ensures that the default bindings for the Text
# class have been defined.  Then certain bindings are overridden for
# the class.
#
# Arguments:
# None.

proc ::tk::ConsoleBind {w} {
    bindtags $w [list $w Console PostConsole [winfo toplevel $w] all]

    ## Get all Text bindings into Console
    foreach ev [bind Text] {
	bind Console $ev [bind Text $ev]
    }
    ## We really didn't want the newline insertion...
    bind Console <Control-Key-o> {}
    ## ...or any Control-v binding (would block <<Paste>>)
    bind Console <Control-Key-v> {}

    # For the moment, transpose isn't enabled until the console
    # gets and overhaul of how it handles input -- hobbs
    bind Console <Control-Key-t> {}

    # Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
    # Otherwise, if a widget binding for one of these is defined, the
    # <Keypress> class binding will also fire and insert the character
    # which is wrong.

    bind Console <Alt-KeyPress> {# nothing }
    bind Console <Meta-KeyPress> {# nothing}
    bind Console <Control-KeyPress> {# nothing}

    foreach {ev key} {
	<<Console_Prev>>		<Key-Up>
	<<Console_Next>>		<Key-Down>
	<<Console_NextImmediate>>	<Control-Key-n>
	<<Console_PrevImmediate>>	<Control-Key-p>
	<<Console_PrevSearch>>		<Control-Key-r>
	<<Console_NextSearch>>		<Control-Key-s>

	<<Console_Expand>>		<Key-Tab>
	<<Console_Expand>>		<Key-Escape>
	<<Console_ExpandFile>>		<Control-Shift-Key-F>
	<<Console_ExpandProc>>		<Control-Shift-Key-P>
	<<Console_ExpandVar>>		<Control-Shift-Key-V>
	<<Console_Tab>>			<Control-Key-i>
	<<Console_Tab>>			<Meta-Key-i>
	<<Console_Eval>>		<Key-Return>
	<<Console_Eval>>		<Key-KP_Enter>

	<<Console_Clear>>		<Control-Key-l>
	<<Console_KillLine>>		<Control-Key-k>
	<<Console_Transpose>>		<Control-Key-t>
	<<Console_ClearLine>>		<Control-Key-u>
	<<Console_SaveCommand>>		<Control-Key-z>
        <<Console_FontSizeIncr>>	<Control-Key-plus>
        <<Console_FontSizeDecr>>	<Control-Key-minus>
    } {
	event add $ev $key
	bind Console $key {}
    }
    if {[tk windowingsystem] eq "aqua"} {
	foreach {ev key} {
	    <<Console_FontSizeIncr>>	<Command-Key-plus>
	    <<Console_FontSizeDecr>>	<Command-Key-minus>
	} {
	    event add $ev $key
	    bind Console $key {}
	}



    }
    bind Console <<Console_Expand>> {
	if {[%W compare insert > promptEnd]} {
	    ::tk::console::Expand %W
	}
    }
    bind Console <<Console_ExpandFile>> {
515
516
517
518
519
520
521
522
523
524
525
526
527
528

529
530
531

532
533
534
535
536
537
538
		[%W compare insert > promptEnd]} {
	    %W delete insert-1c
	    %W see insert
	}
    }
    bind Console <Control-h> [bind Console <BackSpace>]

    bind Console <<LineStart>> {
	if {[%W compare insert < promptEnd]} {
	    tk::TextSetCursor %W {insert linestart}
	} else {
	    tk::TextSetCursor %W promptEnd
	}
    }

    bind Console <<LineEnd>> {
	tk::TextSetCursor %W {insert lineend}
    }

    bind Console <Control-d> {
	if {[%W compare insert < promptEnd]} {
	    break
	}
	%W delete insert
    }
    bind Console <<Console_KillLine>> {







|






>
|


>







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
		[%W compare insert > promptEnd]} {
	    %W delete insert-1c
	    %W see insert
	}
    }
    bind Console <Control-h> [bind Console <BackSpace>]

    bind Console <Home> {
	if {[%W compare insert < promptEnd]} {
	    tk::TextSetCursor %W {insert linestart}
	} else {
	    tk::TextSetCursor %W promptEnd
	}
    }
    bind Console <Control-a> [bind Console <Home>]
    bind Console <End> {
	tk::TextSetCursor %W {insert lineend}
    }
    bind Console <Control-e> [bind Console <End>]
    bind Console <Control-d> {
	if {[%W compare insert < promptEnd]} {
	    break
	}
	%W delete insert
    }
    bind Console <<Console_KillLine>> {
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
	}
    }
    bind Console <Meta-Delete> {
	if {[%W compare insert >= promptEnd]} {
	    %W delete insert {insert wordend}
	}
    }
    bind Console <<PrevLine>> {
	tk::ConsoleHistory prev
    }
    bind Console <<NextLine>> {
	tk::ConsoleHistory next
    }
    bind Console <Insert> {
	catch {tk::ConsoleInsert %W [::tk::GetSelection %W PRIMARY]}
    }
    bind Console <Key> {
	tk::ConsoleInsert %W %A
    }
    bind Console <F9> {
	eval destroy [winfo child .]
	source -encoding utf-8 [file join $tk_library console.tcl]
    }
    if {[tk windowingsystem] eq "aqua"} {
	bind Console <Command-q> {
	    exit
	}
    }
    bind Console <<Cut>> { ::tk::console::Cut %W }
    bind Console <<Copy>> { ::tk::console::Copy %W }
    bind Console <<Paste>> { ::tk::console::Paste %W }

    bind Console <<Console_FontSizeIncr>> {
        set size [font configure TkConsoleFont -size]
        if {$size < 0} {set sign -1} else {set sign 1}
        set size [expr {(abs($size) + 1) * $sign}]
        font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FontSizeDecr>> {
        set size [font configure TkConsoleFont -size]
        if {abs($size) < 2} { return }
        if {$size < 0} {set sign -1} else {set sign 1}
        set size [expr {(abs($size) - 1) * $sign}]
        font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FitScreenWidth>> {
	::tk::console::FitScreenWidth %W
    }

    ##
    ## Bindings for doing special things based on certain keys
    ##
    bind PostConsole <parenright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \( \) promptEnd
	}
    }
    bind PostConsole <bracketright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \[ \] promptEnd
	}
    }
    bind PostConsole <braceright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \{ \} promptEnd
	}
    }
    bind PostConsole <quotedbl> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchQuote %W promptEnd
	}
    }

    bind PostConsole <Key> {
	if {"%A" ne ""} {
	    ::tk::console::TagProc %W
	}
    }
}

# ::tk::ConsoleInsert --







|


|





|




|












<
<
|
<
<
<



<
<
<
|
<
<
<
<
<
<





|




|




|




|





|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564


565



566
567
568



569






570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
	}
    }
    bind Console <Meta-Delete> {
	if {[%W compare insert >= promptEnd]} {
	    %W delete insert {insert wordend}
	}
    }
    bind Console <<Console_Prev>> {
	tk::ConsoleHistory prev
    }
    bind Console <<Console_Next>> {
	tk::ConsoleHistory next
    }
    bind Console <Insert> {
	catch {tk::ConsoleInsert %W [::tk::GetSelection %W PRIMARY]}
    }
    bind Console <KeyPress> {
	tk::ConsoleInsert %W %A
    }
    bind Console <F9> {
	eval destroy [winfo child .]
	source [file join $tk_library console.tcl]
    }
    if {[tk windowingsystem] eq "aqua"} {
	bind Console <Command-q> {
	    exit
	}
    }
    bind Console <<Cut>> { ::tk::console::Cut %W }
    bind Console <<Copy>> { ::tk::console::Copy %W }
    bind Console <<Paste>> { ::tk::console::Paste %W }

    bind Console <<Console_FontSizeIncr>> {
        set size [font configure TkConsoleFont -size]


        font configure TkConsoleFont -size [incr size]



    }
    bind Console <<Console_FontSizeDecr>> {
        set size [font configure TkConsoleFont -size]



        font configure TkConsoleFont -size [incr size -1]






    }

    ##
    ## Bindings for doing special things based on certain keys
    ##
    bind PostConsole <Key-parenright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \( \) promptEnd
	}
    }
    bind PostConsole <Key-bracketright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \[ \] promptEnd
	}
    }
    bind PostConsole <Key-braceright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \{ \} promptEnd
	}
    }
    bind PostConsole <Key-quotedbl> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchQuote %W promptEnd
	}
    }

    bind PostConsole <KeyPress> {
	if {"%A" ne ""} {
	    ::tk::console::TagProc %W
	}
    }
}

# ::tk::ConsoleInsert --
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
proc ::tk::ConsoleAbout {} {
    tk_messageBox -type ok -message "[mc {Tcl for Windows}]

Tcl $::tcl_patchLevel
Tk $::tk_patchLevel"
}

# ::tk::console::Fontchooser* --
# 	Let the user select the console font (TIP 324).

proc ::tk::console::FontchooserToggle {} {
    if {[tk fontchooser configure -visible]} {
	tk fontchooser hide
    } else {
	tk fontchooser show
    }
}
proc ::tk::console::FontchooserVisibility {index} {
    if {[tk fontchooser configure -visible]} {
	.menubar.edit entryconfigure $index -label [::tk::msgcat::mc "Hide Fonts"]
    } else {
	.menubar.edit entryconfigure $index -label [::tk::msgcat::mc "Show Fonts"]
    }
}
proc ::tk::console::FontchooserFocus {w isFocusIn} {
    if {$isFocusIn} {
	tk fontchooser configure -parent $w -font TkConsoleFont \
		-command [namespace code [list FontchooserApply]]
    } else {
	tk fontchooser configure -parent $w -font {} -command {}
    }
}
proc ::tk::console::FontchooserApply {font args} {
    catch {font configure TkConsoleFont {*}[font actual $font]}
}

# ::tk::console::TagProc --
#
# Tags a procedure in the console if it's recognized
# This procedure is not perfect.  However, making it perfect wastes
# too much CPU time...
#
# Arguments:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







667
668
669
670
671
672
673





























674
675
676
677
678
679
680
proc ::tk::ConsoleAbout {} {
    tk_messageBox -type ok -message "[mc {Tcl for Windows}]

Tcl $::tcl_patchLevel
Tk $::tk_patchLevel"
}






























# ::tk::console::TagProc --
#
# Tags a procedure in the console if it's recognized
# This procedure is not perfect.  However, making it perfect wastes
# too much CPU time...
#
# Arguments:
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
#
# Arguments:
#	w	- console text widget
# 	c1	- first char of pair
# 	c2	- second char of pair
#
# Calls:	::tk::console::Blink

proc ::tk::console::MatchPair {w c1 c2 {lim 1.0}} {
    if {!$::tk::console::magicKeys} {
	return
    }
    if {{} ne [set ix [$w search -back $c1 insert $lim]]} {
	while {
	    [string match {\\} [$w get $ix-1c]] &&







|







716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
#
# Arguments:
#	w	- console text widget
# 	c1	- first char of pair
# 	c2	- second char of pair
#
# Calls:	::tk::console::Blink
 
proc ::tk::console::MatchPair {w c1 c2 {lim 1.0}} {
    if {!$::tk::console::magicKeys} {
	return
    }
    if {{} ne [set ix [$w search -back $c1 insert $lim]]} {
	while {
	    [string match {\\} [$w get $ix-1c]] &&
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
# Blinks just the quote if it's unmatched, otherwise blinks quoted string
# The quote to match is assumed to be at the text index 'insert'.
#
# Arguments:
#	w	- console text widget
#
# Calls:	::tk::console::Blink

proc ::tk::console::MatchQuote {w {lim 1.0}} {
    if {!$::tk::console::magicKeys} {
	return
    }
    set i insert-1c
    set j 0
    while {[set i [$w search -back \" $i $lim]] ne {}} {







|







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# Blinks just the quote if it's unmatched, otherwise blinks quoted string
# The quote to match is assumed to be at the text index 'insert'.
#
# Arguments:
#	w	- console text widget
#
# Calls:	::tk::console::Blink
 
proc ::tk::console::MatchQuote {w {lim 1.0}} {
    if {!$::tk::console::magicKeys} {
	return
    }
    set i insert-1c
    set j 0
    while {[set i [$w search -back \" $i $lim]] ne {}} {
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022
# Arguments:
#	str	- partial file pathname to expand
#
# Calls:	::tk::console::ExpandBestMatch
#
# Returns:	list containing longest unique match followed by all the
#		possible further matches

proc ::tk::console::ExpandPathname str {
    set pwd [EvalAttached pwd]
    if {[catch {EvalAttached [list cd [file dirname $str]]} err opt]} {
	return -options $opt $err
    }
    set dir [file tail $str]
    ## Check to see if it was known to be a directory and keep the trailing
    ## slash if so (file tail cuts it off)
    if {[string match */ $str]} {
	append dir /
    }
    if {[catch {lsort [EvalAttached [list glob $dir*]]} m]} {
	set match {}
    } else {
	if {[llength $m] > 1} {

	    if { $::tcl_platform(platform) eq "windows" } {
		## Windows is screwy because it's case insensitive
		set tmp [ExpandBestMatch [string tolower $m] \
			[string tolower $dir]]
		## Don't change case if we haven't changed the word
		if {[string length $dir]==[string length $tmp]} {
		    set tmp $dir
		}







|


|
|











>
|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
# Arguments:
#	str	- partial file pathname to expand
#
# Calls:	::tk::console::ExpandBestMatch
#
# Returns:	list containing longest unique match followed by all the
#		possible further matches
 
proc ::tk::console::ExpandPathname str {
    set pwd [EvalAttached pwd]
    if {[catch {EvalAttached [list cd [file dirname $str]]} err]} {
	return -code error $err
    }
    set dir [file tail $str]
    ## Check to see if it was known to be a directory and keep the trailing
    ## slash if so (file tail cuts it off)
    if {[string match */ $str]} {
	append dir /
    }
    if {[catch {lsort [EvalAttached [list glob $dir*]]} m]} {
	set match {}
    } else {
	if {[llength $m] > 1} {
	    global tcl_platform
	    if {[string match windows $tcl_platform(platform)]} {
		## Windows is screwy because it's case insensitive
		set tmp [ExpandBestMatch [string tolower $m] \
			[string tolower $dir]]
		## Don't change case if we haven't changed the word
		if {[string length $dir]==[string length $tmp]} {
		    set tmp $dir
		}

Changes to library/demos/aniwave.tcl.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
set w .aniwave
catch {destroy $w}
toplevel $w
wm title $w "Animated Wave Demonstration"
wm iconname $w "aniwave"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration contains a canvas widget with a line item inside it. The animation routines work by adjusting the coordinates list of the line; a trace on a variable is used so updates to the variable result in a change of position of the line."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create a canvas large enough to hold the wave. In fact, the wave







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
set w .aniwave
catch {destroy $w}
toplevel $w
wm title $w "Animated Wave Demonstration"
wm iconname $w "aniwave"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration contains a canvas widget with a line item inside it. The animation routines work by adjusting the coordinates list of the line; a trace on a variable is used so updates to the variable result in a change of position of the line." 
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create a canvas large enough to hold the wave. In fact, the wave

Changes to library/demos/arrow.tcl.

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
set demo_arrowInfo(motionProc) arrowMoveNull
set demo_arrowInfo(x1) 40
set demo_arrowInfo(x2) 350
set demo_arrowInfo(y) 150
set demo_arrowInfo(smallTips) {5 5 2}
set demo_arrowInfo(count) 0
if {[winfo depth $c] > 1} {
    if {[tk windowingsystem] eq "aqua"} {
	set demo_arrowInfo(bigLineStyle) "-fill systemSelectedTextBackgroundColor"
    } else {
	set demo_arrowInfo(bigLineStyle) "-fill LightSeaGreen"
    }
    set demo_arrowInfo(boxStyle) "-fill {} -width 1"
    set demo_arrowInfo(activeStyle) "-fill red -width 1"
} else {
    # Main widget program sets variable tk_demoDirectory
    set demo_arrowInfo(bigLineStyle) "-fill black \
	-stipple @[file join $tk_demoDirectory images grey.25]"
    set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1"
    set demo_arrowInfo(activeStyle) "-fill black -outline black -width 1"
}
arrowSetup $c
$c bind box <Enter> "$c itemconfigure current $demo_arrowInfo(activeStyle)"
$c bind box <Leave> "$c itemconfigure current $demo_arrowInfo(boxStyle)"
$c bind box <B1-Enter> " "
$c bind box <B1-Leave> " "
$c bind box1 <Button-1> {set demo_arrowInfo(motionProc) arrowMove1}
$c bind box2 <Button-1> {set demo_arrowInfo(motionProc) arrowMove2}
$c bind box3 <Button-1> {set demo_arrowInfo(motionProc) arrowMove3}
$c bind box <B1-Motion> "\$demo_arrowInfo(motionProc) $c %x %y"
bind $c <ButtonRelease-1> "arrowSetup $c"

# arrowMove1 --
# This procedure is called for each mouse motion event on box1 (the
# one at the vertex of the arrow).  It updates the controlling parameters
# for the line and arrowhead.
#
# Arguments:







<
|
<
<
<
|
|












|
|
|

|







131
132
133
134
135
136
137

138



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
set demo_arrowInfo(motionProc) arrowMoveNull
set demo_arrowInfo(x1) 40
set demo_arrowInfo(x2) 350
set demo_arrowInfo(y) 150
set demo_arrowInfo(smallTips) {5 5 2}
set demo_arrowInfo(count) 0
if {[winfo depth $c] > 1} {

    set demo_arrowInfo(bigLineStyle) "-fill SkyBlue1"



    set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1"
    set demo_arrowInfo(activeStyle) "-fill red -outline black -width 1"
} else {
    # Main widget program sets variable tk_demoDirectory
    set demo_arrowInfo(bigLineStyle) "-fill black \
	-stipple @[file join $tk_demoDirectory images grey.25]"
    set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1"
    set demo_arrowInfo(activeStyle) "-fill black -outline black -width 1"
}
arrowSetup $c
$c bind box <Enter> "$c itemconfigure current $demo_arrowInfo(activeStyle)"
$c bind box <Leave> "$c itemconfigure current $demo_arrowInfo(boxStyle)"
$c bind box <B1-Enter> " "
$c bind box <B1-Leave> " "
$c bind box1 <1> {set demo_arrowInfo(motionProc) arrowMove1}
$c bind box2 <1> {set demo_arrowInfo(motionProc) arrowMove2}
$c bind box3 <1> {set demo_arrowInfo(motionProc) arrowMove3}
$c bind box <B1-Motion> "\$demo_arrowInfo(motionProc) $c %x %y"
bind $c <Any-ButtonRelease-1> "arrowSetup $c"

# arrowMove1 --
# This procedure is called for each mouse motion event on box1 (the
# one at the vertex of the arrow).  It updates the controlling parameters
# for the line and arrowhead.
#
# Arguments:

Changes to library/demos/bind.tcl.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
	-width 60 -height 24 -font $font -wrap word
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles.

if {[winfo depth $w] > 1} {
    set bold "-background #43ce80 -relief raised -borderwidth 1"







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
	-width 60 -height 24 -font $font -wrap word
scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles.

if {[winfo depth $w] > 1} {
    set bold "-background #43ce80 -relief raised -borderwidth 1"
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
$w.text insert end \n\n
$w.text insert end \
{6. A grid that demonstrates how canvases can be scrolled.} d6

# Create bindings for tags.

foreach tag {d1 d2 d3 d4 d5 d6} {
    $w.text tag bind $tag <Enter> "$w.text tag configure $tag $bold"
    $w.text tag bind $tag <Leave> "$w.text tag configure $tag $normal"
}
# Main widget program sets variable tk_demoDirectory
$w.text tag bind d1 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory items.tcl]}
$w.text tag bind d2 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory plot.tcl]}
$w.text tag bind d3 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory ctext.tcl]}
$w.text tag bind d4 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory arrow.tcl]}
$w.text tag bind d5 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory ruler.tcl]}
$w.text tag bind d6 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory cscroll.tcl]}

$w.text mark set insert 0.0
$w.text configure -state disabled







|
|


|
|
|
|
|
|



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
$w.text insert end \n\n
$w.text insert end \
{6. A grid that demonstrates how canvases can be scrolled.} d6

# Create bindings for tags.

foreach tag {d1 d2 d3 d4 d5 d6} {
    $w.text tag bind $tag <Any-Enter> "$w.text tag configure $tag $bold"
    $w.text tag bind $tag <Any-Leave> "$w.text tag configure $tag $normal"
}
# Main widget program sets variable tk_demoDirectory
$w.text tag bind d1 <1> {source -encoding utf-8 [file join $tk_demoDirectory items.tcl]}
$w.text tag bind d2 <1> {source -encoding utf-8 [file join $tk_demoDirectory plot.tcl]}
$w.text tag bind d3 <1> {source -encoding utf-8 [file join $tk_demoDirectory ctext.tcl]}
$w.text tag bind d4 <1> {source -encoding utf-8 [file join $tk_demoDirectory arrow.tcl]}
$w.text tag bind d5 <1> {source -encoding utf-8 [file join $tk_demoDirectory ruler.tcl]}
$w.text tag bind d6 <1> {source -encoding utf-8 [file join $tk_demoDirectory cscroll.tcl]}

$w.text mark set insert 0.0
$w.text configure -state disabled

Changes to library/demos/colors.tcl.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pack $w.frame -side top -expand yes -fill y

scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" \
	-width 20 -height 16 -setgrid 1
pack $w.frame.list $w.frame.scroll -side left -fill y -expand 1

bind $w.frame.list <Double-Button-1> {
    tk_setPalette [selection get]
}
$w.frame.list insert 0 gray60 gray70 gray80 gray85 gray90 gray95 \
    snow1 snow2 snow3 snow4 seashell1 seashell2 \
    seashell3 seashell4 AntiqueWhite1 AntiqueWhite2 AntiqueWhite3 \
    AntiqueWhite4 bisque1 bisque2 bisque3 bisque4 PeachPuff1 \
    PeachPuff2 PeachPuff3 PeachPuff4 NavajoWhite1 NavajoWhite2 \







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pack $w.frame -side top -expand yes -fill y

scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" \
	-width 20 -height 16 -setgrid 1
pack $w.frame.list $w.frame.scroll -side left -fill y -expand 1

bind $w.frame.list <Double-1> {
    tk_setPalette [selection get]
}
$w.frame.list insert 0 gray60 gray70 gray80 gray85 gray90 gray95 \
    snow1 snow2 snow3 snow4 seashell1 seashell2 \
    seashell3 seashell4 AntiqueWhite1 AntiqueWhite2 AntiqueWhite3 \
    AntiqueWhite4 bisque1 bisque2 bisque3 bisque4 PeachPuff1 \
    PeachPuff2 PeachPuff3 PeachPuff4 NavajoWhite1 NavajoWhite2 \

Changes to library/demos/combo.tcl.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
# combo.tcl --
#
# This demonstration script creates several combobox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .combo
catch {destroy $w}
toplevel $w
wm title $w "Combobox Demonstration"
wm iconname $w "combo"
positionWindow $w









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# combo.tcl --
#
# This demonstration script creates several combobox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .combo
catch {destroy $w}
toplevel $w
wm title $w "Combobox Demonstration"
wm iconname $w "combo"
positionWindow $w
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    Canberra Sydney Melbourne Perth Adelaide Brisbane
    Hobart Darwin "Alice Springs"
}
set secondValue unchangable
set ozCity Sydney

ttk::labelframe $w.c1 -text "Fully Editable"
ttk::combobox $w.c1.c -textvariable firstValue -placeholder {Enter text here}
ttk::style configure TEntry -placeholderforeground gray50
ttk::labelframe $w.c2 -text Disabled
ttk::combobox $w.c2.c -textvariable secondValue -state disabled
ttk::labelframe $w.c3 -text "Defined List Only"
ttk::combobox $w.c3.c -textvariable ozCity -state readonly \
	-values $australianCities
bind $w.c1.c <Return> {
    if {[%W get] ni [%W cget -values]} {







|
<







40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
    Canberra Sydney Melbourne Perth Adelaide Brisbane
    Hobart Darwin "Alice Springs"
}
set secondValue unchangable
set ozCity Sydney

ttk::labelframe $w.c1 -text "Fully Editable"
ttk::combobox $w.c1.c -textvariable firstValue

ttk::labelframe $w.c2 -text Disabled
ttk::combobox $w.c2.c -textvariable secondValue -state disabled
ttk::labelframe $w.c3 -text "Defined List Only"
ttk::combobox $w.c3.c -textvariable ozCity -state readonly \
	-values $australianCities
bind $w.c1.c <Return> {
    if {[%W get] ni [%W cget -values]} {

Changes to library/demos/cscroll.tcl.

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163

164
165
166

167
168
169
170
171
172


set bg [lindex [$c config -bg] 4]
for {set i 0} {$i < 20} {incr i} {
    set x [expr {-10 + 3*$i}]
    for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} {
	$c create rect ${x}c ${y}c [expr {$x+2}]c [expr {$y+2}]c \
		-fill $bg -tags rect
	$c create text [expr {$x+1}]c [expr {$y+1}]c -text "$i,$j" \
	    -anchor center -tags text
    }
}

$c bind all <Enter> "scrollEnter $c"
$c bind all <Leave> "scrollLeave $c"
$c bind all <Button-1> "scrollButton $c"
if {([tk windowingsystem] eq "aqua") && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
    bind $c <MouseWheel> {
	%W yview scroll [expr {-%D}] units
    }
    bind $c <Option-MouseWheel> {
	%W yview scroll [expr {-10*%D}] units
    }
    bind $c <Shift-MouseWheel> {
	%W xview scroll [expr {-%D}] units
    }
    bind $c <Shift-Option-MouseWheel> {
	%W xview scroll [expr {-10*%D}] units
    }
} else {
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/-30 = -1,
    # but
    #     (int)-1/-30 = 0
    # The following code ensure equal +/- behaviour.
    bind $c <MouseWheel> {
	if {%D >= 0} {
	    %W yview scroll [expr {%D/-30}] units
	} else {
	    %W yview scroll [expr {(%D-29)/-30}] units
	}
    }
    bind $c <Option-MouseWheel> {
	if {%D >= 0} {
	    %W yview scroll [expr {%D/-3}] units
	} else {
	    %W yview scroll [expr {(%D-2)/-3}] units
	}
    }
    bind $c <Shift-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {%D/-30}] units
	} else {
	    %W xview scroll [expr {(%D-29)/-30}] units
	}
    }
    bind $c <Shift-Option-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {%D/-3}] units
	} else {
	    %W xview scroll [expr {(%D-2)/-3}] units
	}
    }
}

if {[tk windowingsystem] eq "x11" && ![package vsatisfies [package provide Tk] 8.7-]} {
    # Support for mousewheels on Linux/Unix commonly comes through mapping
    # the wheel to the extended buttons.  If you have a mousewheel, find
    # Linux configuration info at:
    #	http://linuxreviews.org/howtos/xfree/mouse/
    bind $c <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind $c <Shift-Button-4> {
	if {!$tk_strictMotif} {
	    %W xview scroll -5 units
	}
    }
    bind $c <Button-5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 5 units
	}
    }
    bind $c <Shift-Button-5> {
	if {!$tk_strictMotif} {
	    %W xview scroll 5 units
	}
    }
}


proc scrollEnter canvas {
    global oldFill
    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] >= 0} {
	set id [expr {$id-1}]
    }
    set oldFill [lindex [$canvas itemconfig $id -fill] 4]
    if {[winfo depth $canvas] > 1} {
	if {[tk windowingsystem] eq "aqua"} {
	    $canvas itemconfigure $id -fill systemSelectedTextBackgroundColor
	} else {
	    $canvas itemconfigure $id -fill LightSeaGreen
	}

    }
}

proc scrollLeave canvas {
    global oldFill
    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] >= 0} {
	set id [expr {$id-1}]
    }
    $canvas itemconfigure $id -fill $oldFill

}

proc scrollButton canvas {

    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] < 0} {
	set id [expr {$id+1}]
    }
    puts stdout "You buttoned at [lindex [$canvas itemconf $id -text] 4]"
}







|





|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
<
|
<
|
|
<
|
<
|
|
<
<
<
<
<
<
|
<
|
|
|
<
<









<
|
|
|
<
>










>



>






43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
















59
60





















61





62

63


64








65

66
67

68

69
70






71

72
73
74


75
76
77
78
79
80
81
82
83

84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108


set bg [lindex [$c config -bg] 4]
for {set i 0} {$i < 20} {incr i} {
    set x [expr {-10 + 3*$i}]
    for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} {
	$c create rect ${x}c ${y}c [expr {$x+2}]c [expr {$y+2}]c \
		-outline black -fill $bg -tags rect
	$c create text [expr {$x+1}]c [expr {$y+1}]c -text "$i,$j" \
	    -anchor center -tags text
    }
}

$c bind all <Any-Enter> "scrollEnter $c"
$c bind all <Any-Leave> "scrollLeave $c"
$c bind all <1> "scrollButton $c"
















bind $c <2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"





















if {[tk windowingsystem] eq "aqua"} {





    bind $c <MouseWheel> {

        %W yview scroll [expr {- (%D)}] units


    }








    bind $c <Option-MouseWheel> {

        %W yview scroll [expr {-10 * (%D)}] units
    }

    bind $c <Shift-MouseWheel> {

        %W xview scroll [expr {- (%D)}] units
    }






    bind $c <Shift-Option-MouseWheel> {

        %W xview scroll [expr {-10 * (%D)}] units
    }
}



proc scrollEnter canvas {
    global oldFill
    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] >= 0} {
	set id [expr {$id-1}]
    }
    set oldFill [lindex [$canvas itemconfig $id -fill] 4]
    if {[winfo depth $canvas] > 1} {

	$canvas itemconfigure $id -fill SeaGreen1
    } else {
	$canvas itemconfigure $id -fill black

	$canvas itemconfigure [expr {$id+1}] -fill white
    }
}

proc scrollLeave canvas {
    global oldFill
    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] >= 0} {
	set id [expr {$id-1}]
    }
    $canvas itemconfigure $id -fill $oldFill
    $canvas itemconfigure [expr {$id+1}] -fill black
}

proc scrollButton canvas {
    global oldFill
    set id [$canvas find withtag current]
    if {[lsearch [$canvas gettags current] text] < 0} {
	set id [expr {$id+1}]
    }
    puts stdout "You buttoned at [lindex [$canvas itemconf $id -text] 4]"
}

Changes to library/demos/ctext.tcl.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
catch {destroy $w}
toplevel $w
wm title $w "Canvas Text Demonstration"
wm iconname $w "Text"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 5i -justify left -text "This window displays a string of text to demonstrate the text facilities of canvas widgets.  You can click in the boxes to adjust the position of the text relative to its positioning point or change its justification, and on a pie slice to change its angle.  The text also supports the following simple bindings for editing:
  1. You can point, click, and type.
  2. You can also select with button 1.
  3. You can copy the selection to the mouse position with button 2.
  4. Backspace and Control+h delete the selection if there is one;
     otherwise they delete the character just before the insertion cursor.
  5. Delete deletes the selection if there is one; otherwise it deletes
     the character just after the insertion cursor."







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
catch {destroy $w}
toplevel $w
wm title $w "Canvas Text Demonstration"
wm iconname $w "Text"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 5i -justify left -text "This window displays a string of text to demonstrate the text facilities of canvas widgets.  You can click in the boxes to adjust the position of the text relative to its positioning point or change its justification.  The text also supports the following simple bindings for editing:
  1. You can point, click, and type.
  2. You can also select with button 1.
  3. You can copy the selection to the mouse position with button 2.
  4. Backspace and Control+h delete the selection if there is one;
     otherwise they delete the character just before the insertion cursor.
  5. Delete deletes the selection if there is one; otherwise it deletes
     the character just after the insertion cursor."
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

set textFont {Helvetica 24}

$c create rectangle 245 195 255 205 -outline black -fill red

# First, create the text item and give it bindings so it can be edited.

$c addtag text withtag [$c create text 250 200 -text "This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been defined to support editing (see above)." -width 440 -anchor n -font $textFont -justify left]
$c bind text <Button-1> "textB1Press $c %x %y"
$c bind text <B1-Motion> "textB1Move $c %x %y"
$c bind text <Shift-Button-1> "$c select adjust current @%x,%y"
$c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
$c bind text <Key> "textInsert $c %A"
$c bind text <Return> "textInsert $c \\n"
$c bind text <Control-h> "textBs $c"
$c bind text <BackSpace> "textBs $c"
$c bind text <Delete> "textDel $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    $c bind text <Button-3> "textPaste $c @%x,%y"
} else {
    $c bind text <Button-2> "textPaste $c @%x,%y"
}

# Next, create some items that allow the text's anchor position
# to be edited.

proc mkTextConfigBox {w x y option value color} {
    set item [$w create rect $x $y [expr {$x+30}] [expr {$y+30}] \
	    -outline black -fill $color -width 1]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}
proc mkTextConfigPie {w x y a option value color} {
    set item [$w create arc $x $y [expr {$x+90}] [expr {$y+90}] \
	    -start [expr {$a-15}] -extent 30 -outline black -fill $color \
	    -width 1]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}

set x 50
set y 50
set color LightSkyBlue1
mkTextConfigBox $c $x $y -anchor se $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y   }] -anchor s      $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y   }] -anchor sw     $color
mkTextConfigBox $c [expr {$x   }] [expr {$y+30}] -anchor e      $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y+30}] -anchor center $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y+30}] -anchor w      $color
mkTextConfigBox $c [expr {$x   }] [expr {$y+60}] -anchor ne     $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y+60}] -anchor n      $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y+60}] -anchor nw     $color
set item [$c create rect \
	[expr {$x+40}] [expr {$y+40}] [expr {$x+50}] [expr {$y+50}] \
	-outline black -fill red]
$c bind $item <Button-1> "$c itemconf text -anchor center"
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Text Position}  -anchor s  -font {Times 20}  -fill brown

# Now create some items that allow the text's angle to be changed.

set x 205
set y 50
set color Yellow
mkTextConfigPie $c $x $y   0 -angle  90 $color
mkTextConfigPie $c $x $y  30 -angle 120 $color
mkTextConfigPie $c $x $y  60 -angle 150 $color
mkTextConfigPie $c $x $y  90 -angle 180 $color
mkTextConfigPie $c $x $y 120 -angle 210 $color
mkTextConfigPie $c $x $y 150 -angle 240 $color
mkTextConfigPie $c $x $y 180 -angle 270 $color
mkTextConfigPie $c $x $y 210 -angle 300 $color
mkTextConfigPie $c $x $y 240 -angle 330 $color
mkTextConfigPie $c $x $y 270 -angle   0 $color
mkTextConfigPie $c $x $y 300 -angle  30 $color
mkTextConfigPie $c $x $y 330 -angle  60 $color
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Text Angle}  -anchor s  -font {Times 20}  -fill brown

# Lastly, create some items that allow the text's justification to be
# changed.

set x 350
set y 50
set color SeaGreen2
mkTextConfigBox $c $x $y -justify left $color
mkTextConfigBox $c [expr {$x+30}] $y -justify center $color
mkTextConfigBox $c [expr {$x+60}] $y -justify right $color
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Justification}  -anchor s  -font {Times 20}  -fill brown

$c bind config <Enter> "textEnter $c"
$c bind config <Leave> "$c itemconf current -fill \$textConfigFill"

set textConfigFill {}

proc textEnter {w} {







|
|

|

|




<
<
<
|
<




|


|
<
<
<
<
<
<
<






|
|
|
|
|
|
|
|
|



|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|
|

|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52



53

54
55
56
57
58
59
60
61







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82




















83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

set textFont {Helvetica 24}

$c create rectangle 245 195 255 205 -outline black -fill red

# First, create the text item and give it bindings so it can be edited.

$c addtag text withtag [$c create text 250 200 -text "This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been been defined to support editing (see above)." -width 440 -anchor n -font $textFont -justify left]
$c bind text <1> "textB1Press $c %x %y"
$c bind text <B1-Motion> "textB1Move $c %x %y"
$c bind text <Shift-1> "$c select adjust current @%x,%y"
$c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
$c bind text <KeyPress> "textInsert $c %A"
$c bind text <Return> "textInsert $c \\n"
$c bind text <Control-h> "textBs $c"
$c bind text <BackSpace> "textBs $c"
$c bind text <Delete> "textDel $c"



$c bind text <2> "textPaste $c @%x,%y" 


# Next, create some items that allow the text's anchor position
# to be edited.

proc mkTextConfig {w x y option value color} {
    set item [$w create rect $x $y [expr {$x+30}] [expr {$y+30}] \
	    -outline black -fill $color -width 1]
    $w bind $item <1> "$w itemconf text $option $value"







    $w addtag config withtag $item
}

set x 50
set y 50
set color LightSkyBlue1
mkTextConfig $c $x $y -anchor se $color
mkTextConfig $c [expr {$x+30}] [expr {$y   }] -anchor s      $color
mkTextConfig $c [expr {$x+60}] [expr {$y   }] -anchor sw     $color
mkTextConfig $c [expr {$x   }] [expr {$y+30}] -anchor e      $color
mkTextConfig $c [expr {$x+30}] [expr {$y+30}] -anchor center $color
mkTextConfig $c [expr {$x+60}] [expr {$y+30}] -anchor w      $color
mkTextConfig $c [expr {$x   }] [expr {$y+60}] -anchor ne     $color
mkTextConfig $c [expr {$x+30}] [expr {$y+60}] -anchor n      $color
mkTextConfig $c [expr {$x+60}] [expr {$y+60}] -anchor nw     $color
set item [$c create rect \
	[expr {$x+40}] [expr {$y+40}] [expr {$x+50}] [expr {$y+50}] \
	-outline black -fill red]
$c bind $item <1> "$c itemconf text -anchor center"
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Text Position}  -anchor s  -font {Times 24}  -fill brown





















# Lastly, create some items that allow the text's justification to be
# changed.

set x 350
set y 50
set color SeaGreen2
mkTextConfig $c $x $y -justify left $color
mkTextConfig $c [expr {$x+30}] $y -justify center $color
mkTextConfig $c [expr {$x+60}] $y -justify right $color
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Justification}  -anchor s  -font {Times 24}  -fill brown

$c bind config <Enter> "textEnter $c"
$c bind config <Leave> "$c itemconf current -fill \$textConfigFill"

set textConfigFill {}

proc textEnter {w} {

Changes to library/demos/dialog1.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# dialog1.tcl --
#
# This demonstration script creates a dialog box with a local grab.

interp create child
load {} Tk child
child eval {
    wm title . child
    wm geometry . +700+30
    pack [text .t -width 30 -height 10]
}

after idle {.dialog1.msg configure -wraplength 4i}
set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box.  It uses Tk's "grab" command to create a "local grab" on the dialog box.  The grab prevents any mouse or keyboard events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below.  However, you can still interact with other applications.  For example, you should be able to edit text in the window named "child" which was created by a child interpreter.} \
info 0 OK Cancel {Show Code}]

switch $i {
    0 {puts "You pressed OK"}
    1 {puts "You pressed Cancel"}
    2 {showCode .dialog1}
}

if {[interp exists child]} {
    interp delete child
}




<
<
<
<
<
<
<
<

|







<
<
<
<
1
2
3
4








5
6
7
8
9
10
11
12
13




# dialog1.tcl --
#
# This demonstration script creates a dialog box with a local grab.









after idle {.dialog1.msg configure -wraplength 4i}
set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box.  It uses Tk's "grab" command to create a "local grab" on the dialog box.  The grab prevents any pointer-related events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below.  However, you can still interact with other applications.} \
info 0 OK Cancel {Show Code}]

switch $i {
    0 {puts "You pressed OK"}
    1 {puts "You pressed Cancel"}
    2 {showCode .dialog1}
}




Changes to library/demos/dialog2.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# dialog2.tcl --
#
# This demonstration script creates a dialog box with a global grab.

after idle {
    .dialog2.msg configure -wraplength 4i
}
after 100 {
    grab -global .dialog2
}
set i [tk_dialog .dialog2 "Dialog with global grab" {This dialog box uses a global grab. If you are using an X11 window manager you will be prevented from interacting with anything on your display until you invoke one of the buttons below.  This is almost always a bad idea; don't use global grabs with X11 unless you're truly desperate.  On macOS systems you will not be able to interact with any window belonging to this process, but interaction with other macOS Applications will still be possible.}\
warning 0 OK Cancel {Show Code}]

switch $i {
    0 {puts "You pressed OK"}
    1 {puts "You pressed Cancel"}
    2 {showCode .dialog2}
}










|
<






1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
# dialog2.tcl --
#
# This demonstration script creates a dialog box with a global grab.

after idle {
    .dialog2.msg configure -wraplength 4i
}
after 100 {
    grab -global .dialog2
}
set i [tk_dialog .dialog2 "Dialog with global grab" {This dialog box uses a global grab, so it prevents you from interacting with anything on your display until you invoke one of the buttons below.  Global grabs are almost always a bad idea; don't use them unless you're truly desperate.} warning 0 OK Cancel {Show Code}]


switch $i {
    0 {puts "You pressed OK"}
    1 {puts "You pressed Cancel"}
    2 {showCode .dialog2}
}

Changes to library/demos/entry1.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (no scrollbars)"
wm iconname $w "entry1"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

entry $w.e1
entry $w.e2
entry $w.e3 -placeholder {Enter text here} -placeholderforeground gray75
pack $w.e1 $w.e2 $w.e3 -side top -pady 5 -padx 10 -fill x

$w.e1 insert 0 "Initial value"
$w.e2 insert end "This entry contains a long value, much too long "
$w.e2 insert end "to fit in the window at one time, so long in fact "
$w.e2 insert end "that you'll have to scan or scroll to see the end."







|








|






12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (no scrollbars)"
wm iconname $w "entry1"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse button2 pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

entry $w.e1
entry $w.e2
entry $w.e3
pack $w.e1 $w.e2 $w.e3 -side top -pady 5 -padx 10 -fill x

$w.e1 insert 0 "Initial value"
$w.e2 insert end "This entry contains a long value, much too long "
$w.e2 insert end "to fit in the window at one time, so long in fact "
$w.e2 insert end "that you'll have to scan or scroll to see the end."

Changes to library/demos/entry2.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
set w .entry2
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (with scrollbars)"
wm iconname $w "entry2"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below, with a scrollbar for each entry.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -fill x -expand 1

entry $w.frame.e1 -xscrollcommand "$w.frame.s1 set"
ttk::scrollbar $w.frame.s1 -orient horiz -command \
	"$w.frame.e1 xview"
frame $w.frame.spacer1 -width 20 -height 10
entry $w.frame.e2 -xscrollcommand "$w.frame.s2 set"
ttk::scrollbar $w.frame.s2 -orient horiz -command \
	"$w.frame.e2 xview"
frame $w.frame.spacer2 -width 20 -height 10
entry $w.frame.e3 -xscrollcommand "$w.frame.s3 set"
ttk::scrollbar $w.frame.s3 -orient horiz -command \
	"$w.frame.e3 xview"
pack $w.frame.e1 $w.frame.s1 $w.frame.spacer1 $w.frame.e2 $w.frame.s2 \
	$w.frame.spacer2 $w.frame.e3 $w.frame.s3 -side top -fill x

$w.frame.e1 insert 0 "Initial value"
$w.frame.e2 insert end "This entry contains a long value, much too long "
$w.frame.e2 insert end "to fit in the window at one time, so long in fact "
$w.frame.e2 insert end "that you'll have to scan or scroll to see the end."
$w.frame.e3 configure -placeholder {Enter text here} -placeholderforeground gray75







|










|



|



|








<
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

set w .entry2
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (with scrollbars)"
wm iconname $w "entry2"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below, with a scrollbar for each entry.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with mouse button2 pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -fill x -expand 1

entry $w.frame.e1 -xscrollcommand "$w.frame.s1 set"
scrollbar $w.frame.s1 -relief sunken -orient horiz -command \
	"$w.frame.e1 xview"
frame $w.frame.spacer1 -width 20 -height 10
entry $w.frame.e2 -xscrollcommand "$w.frame.s2 set"
scrollbar $w.frame.s2 -relief sunken -orient horiz -command \
	"$w.frame.e2 xview"
frame $w.frame.spacer2 -width 20 -height 10
entry $w.frame.e3 -xscrollcommand "$w.frame.s3 set"
scrollbar $w.frame.s3 -relief sunken -orient horiz -command \
	"$w.frame.e3 xview"
pack $w.frame.e1 $w.frame.s1 $w.frame.spacer1 $w.frame.e2 $w.frame.s2 \
	$w.frame.spacer2 $w.frame.e3 $w.frame.s3 -side top -fill x

$w.frame.e1 insert 0 "Initial value"
$w.frame.e2 insert end "This entry contains a long value, much too long "
$w.frame.e2 insert end "to fit in the window at one time, so long in fact "
$w.frame.e2 insert end "that you'll have to scan or scroll to see the end."

Changes to library/demos/entry3.tcl.

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# vmode - The widget's validation mode
# idx -	  The index where replacement is to occur
# char -  The character (or string, though that will always be
#	  refused) to be overwritten at that point.

proc validatePhoneChange {W vmode idx char} {
    global phoneNumberMap entry3content
    if {$idx < 0} {return 1}
    after idle [list $W configure -validate $vmode -invcmd bell]
    if {
	!($idx<3 || $idx==6 || $idx==7 || $idx==11 || $idx>15) &&
	[string match {[0-9A-Za-z]} $char]
    } then {
	$W delete $idx
	$W insert $idx [string map $phoneNumberMap $char]







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# vmode - The widget's validation mode
# idx -	  The index where replacement is to occur
# char -  The character (or string, though that will always be
#	  refused) to be overwritten at that point.

proc validatePhoneChange {W vmode idx char} {
    global phoneNumberMap entry3content
    if {$idx == -1} {return 1}
    after idle [list $W configure -validate $vmode -invcmd bell]
    if {
	!($idx<3 || $idx==6 || $idx==7 || $idx==11 || $idx>15) &&
	[string match {[0-9A-Za-z]} $char]
    } then {
	$W delete $idx
	$W insert $idx [string map $phoneNumberMap $char]
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Click to focus goes to the first editable character...
bind $w.l3.e <FocusIn> {
    if {"%d" ne "NotifyAncestor"} {
	%W icursor 3
	after idle {%W selection clear}
    }
}
bind $w.l3.e <<PrevChar>> {phoneSkipLeft  %W}
bind $w.l3.e <<NextChar>> {phoneSkipRight %W}
pack $w.l3.e -fill x -expand 1 -padx 1m -pady 1m

labelframe $w.l4 -text "Password Entry"
entry $w.l4.e -validate key -show "*" -vcmd {expr {[string length %P]<=8}}
pack $w.l4.e -fill x -expand 1 -padx 1m -pady 1m

lower [frame $w.mid]
grid $w.l1 $w.l2 -in $w.mid -padx 3m -pady 1m -sticky ew
grid $w.l3 $w.l4 -in $w.mid -padx 3m -pady 1m -sticky ew
grid columnconfigure $w.mid {0 1} -uniform 1
pack $w.msg -side top
pack $w.mid -fill both -expand 1







|
|












165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Click to focus goes to the first editable character...
bind $w.l3.e <FocusIn> {
    if {"%d" ne "NotifyAncestor"} {
	%W icursor 3
	after idle {%W selection clear}
    }
}
bind $w.l3.e <Left>  {phoneSkipLeft  %W}
bind $w.l3.e <Right> {phoneSkipRight %W}
pack $w.l3.e -fill x -expand 1 -padx 1m -pady 1m

labelframe $w.l4 -text "Password Entry"
entry $w.l4.e -validate key -show "*" -vcmd {expr {[string length %P]<=8}}
pack $w.l4.e -fill x -expand 1 -padx 1m -pady 1m

lower [frame $w.mid]
grid $w.l1 $w.l2 -in $w.mid -padx 3m -pady 1m -sticky ew
grid $w.l3 $w.l4 -in $w.mid -padx 3m -pady 1m -sticky ew
grid columnconfigure $w.mid {0 1} -uniform 1
pack $w.msg -side top
pack $w.mid -fill both -expand 1

Changes to library/demos/filebox.tcl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
set w .filebox
catch {destroy $w}
toplevel $w
wm title $w "File Selection Dialogs"
wm iconname $w "filebox"
positionWindow $w

ttk::frame $w._bg
place $w._bg -x 0 -y 0 -relwidth 1 -relheight 1

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

foreach i {open save} {
    set f [ttk::frame $w.$i]
    ttk::label $f.lab -text "Select a file to $i: " -anchor e
    ttk::entry $f.ent -width 20
    ttk::button $f.but -text "Browse ..." -command "fileDialog $w $f.ent $i"
    pack $f.lab -side left
    pack $f.ent -side left -expand yes -fill x
    pack $f.but -side left
    pack $f -fill x -padx 1c -pady 3
}

if {[tk windowingsystem] eq "x11"} {
    ttk::checkbutton $w.strict -text "Use Motif Style Dialog" \
	-variable tk_strictMotif -onvalue 1 -offvalue 0
    pack $w.strict -anchor c

    # This binding ensures that we don't run the rest of the demos
    # with motif style interactions
    bind $w.strict <Destroy> {set tk_strictMotif 0}
}







<
<
<
|







|
|
|
|







|







11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
set w .filebox
catch {destroy $w}
toplevel $w
wm title $w "File Selection Dialogs"
wm iconname $w "filebox"
positionWindow $w




label $w.msg -font $font -wraplength 4i -justify left -text "Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

foreach i {open save} {
    set f [frame $w.$i]
    label $f.lab -text "Select a file to $i: " -anchor e
    entry $f.ent -width 20
    button $f.but -text "Browse ..." -command "fileDialog $w $f.ent $i"
    pack $f.lab -side left
    pack $f.ent -side left -expand yes -fill x
    pack $f.but -side left
    pack $f -fill x -padx 1c -pady 3
}

if {[tk windowingsystem] eq "x11"} {
    checkbutton $w.strict -text "Use Motif Style Dialog" \
	-variable tk_strictMotif -onvalue 1 -offvalue 0
    pack $w.strict -anchor c

    # This binding ensures that we don't run the rest of the demos
    # with motif style interactions
    bind $w.strict <Destroy> {set tk_strictMotif 0}
}

Changes to library/demos/floor.tcl.

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    global currentRoom floorItems colors
    $w delete highlight
    if {[catch {set item $floorItems($currentRoom)}]} {
	return
    }
    set new [eval \
	"$w create polygon [$w coords $item] -fill $colors(active) \
	-outline {} -tags highlight"]
    $w raise $new marker
}

# bg1 --
# This procedure represents part of the floorplan database.  When
# invoked, it instantiates the background information for the first
# floor.
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg1 {w fill outline} {
    $w create polygon 347 80 349 82 351 84 353 85 363 92 375 99 386 104 \
	386 129 398 129 398 162 484 162 484 129 559 129 559 133 725 \
	133 725 129 802 129 802 389 644 389 644 391 559 391 559 327 \
	508 327 508 311 484 311 484 278 395 278 395 288 400 288 404 \
	288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 \
	411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 \
	342 331 347 332 351 334 354 336 357 341 359 340 360 335 363 \
	331 365 326 366 304 366 304 355 258 355 258 387 60 387 60 391 \
	0 391 0 337 3 337 3 114 8 114 8 25 30 25 30 5 93 5 98 5 104 7 \
	110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 34 221 \
	22 223 17 227 13 231 8 236 4 242 2 246 0 260 0 283 1 300 5 \
	321 14 335 22 348 25 365 29 363 39 358 48 352 56 337 70 \
	344 76 347 80 \
	-tags {floor1 bg} -fill $fill -outline {}
    $w create line 386 129 398 129 -fill $outline -tags {floor1 bg}
    $w create line 258 355 258 387 -fill $outline -tags {floor1 bg}
    $w create line 60 387 60 391 -fill $outline -tags {floor1 bg}
    $w create line 0 337 0 391 -fill $outline -tags {floor1 bg}
    $w create line 60 391 0 391 -fill $outline -tags {floor1 bg}
    $w create line 3 114 3 337 -fill $outline -tags {floor1 bg}
    $w create line 258 387 60 387 -fill $outline -tags {floor1 bg}







|














|












|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    global currentRoom floorItems colors
    $w delete highlight
    if {[catch {set item $floorItems($currentRoom)}]} {
	return
    }
    set new [eval \
	"$w create polygon [$w coords $item] -fill $colors(active) \
	-tags highlight"]
    $w raise $new marker
}

# bg1 --
# This procedure represents part of the floorplan database.  When
# invoked, it instantiates the background information for the first
# floor.
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg1 {w fill outline} {
    $w create poly 347 80 349 82 351 84 353 85 363 92 375 99 386 104 \
	386 129 398 129 398 162 484 162 484 129 559 129 559 133 725 \
	133 725 129 802 129 802 389 644 389 644 391 559 391 559 327 \
	508 327 508 311 484 311 484 278 395 278 395 288 400 288 404 \
	288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 \
	411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 \
	342 331 347 332 351 334 354 336 357 341 359 340 360 335 363 \
	331 365 326 366 304 366 304 355 258 355 258 387 60 387 60 391 \
	0 391 0 337 3 337 3 114 8 114 8 25 30 25 30 5 93 5 98 5 104 7 \
	110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 34 221 \
	22 223 17 227 13 231 8 236 4 242 2 246 0 260 0 283 1 300 5 \
	321 14 335 22 348 25 365 29 363 39 358 48 352 56 337 70 \
	344 76 347 80 \
	-tags {floor1 bg} -fill $fill
    $w create line 386 129 398 129 -fill $outline -tags {floor1 bg}
    $w create line 258 355 258 387 -fill $outline -tags {floor1 bg}
    $w create line 60 387 60 391 -fill $outline -tags {floor1 bg}
    $w create line 0 337 0 391 -fill $outline -tags {floor1 bg}
    $w create line 60 391 0 391 -fill $outline -tags {floor1 bg}
    $w create line 3 114 3 337 -fill $outline -tags {floor1 bg}
    $w create line 258 387 60 387 -fill $outline -tags {floor1 bg}
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg2 {w fill outline} {
    $w create polygon 559 129 484 129 484 162 398 162 398 129 315 129 \
	315 133 176 133 176 129 96 129 96 133 3 133 3 339 0 339 0 391 \
	60 391 60 387 258 387 258 329 350 329 350 311 395 311 395 280 \
	484 280 484 311 508 311 508 327 558 327 558 391 644 391 644 \
	367 802 367 802 129 725 129 725 133 559 133 559 129 \
	-tags {floor2 bg} -fill $fill -outline {}
    $w create line 350 311 350 329 -fill $outline -tags {floor2 bg}
    $w create line 398 129 398 162 -fill $outline -tags {floor2 bg}
    $w create line 802 367 802 129 -fill $outline -tags {floor2 bg}
    $w create line 802 129 725 129 -fill $outline -tags {floor2 bg}
    $w create line 725 133 725 129 -fill $outline -tags {floor2 bg}
    $w create line 559 129 559 133 -fill $outline -tags {floor2 bg}
    $w create line 559 133 725 133 -fill $outline -tags {floor2 bg}







|




|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg2 {w fill outline} {
    $w create poly 559 129 484 129 484 162 398 162 398 129 315 129 \
	315 133 176 133 176 129 96 129 96 133 3 133 3 339 0 339 0 391 \
	60 391 60 387 258 387 258 329 350 329 350 311 395 311 395 280 \
	484 280 484 311 508 311 508 327 558 327 558 391 644 391 644 \
	367 802 367 802 129 725 129 725 133 559 133 559 129 \
	-tags {floor2 bg} -fill $fill
    $w create line 350 311 350 329 -fill $outline -tags {floor2 bg}
    $w create line 398 129 398 162 -fill $outline -tags {floor2 bg}
    $w create line 802 367 802 129 -fill $outline -tags {floor2 bg}
    $w create line 802 129 725 129 -fill $outline -tags {floor2 bg}
    $w create line 725 133 725 129 -fill $outline -tags {floor2 bg}
    $w create line 559 129 559 133 -fill $outline -tags {floor2 bg}
    $w create line 559 133 725 133 -fill $outline -tags {floor2 bg}
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg3 {w fill outline} {
    $w create polygon 159 300 107 300 107 248 159 248 159 129 96 129 96 \
	133 21 133 21 331 0 331 0 391 60 391 60 370 159 370 159 300 \
	-tags {floor3 bg} -fill $fill -outline {}
    $w create polygon 258 370 258 329 350 329 350 311 399 311 399 129 \
	315 129 315 133 176 133 176 129 159 129 159 370 258 370 \
	-tags {floor3 bg} -fill $fill -outline {}
    $w create line 96 133 96 129 -fill $outline -tags {floor3 bg}
    $w create line 176 129 96 129 -fill $outline -tags {floor3 bg}
    $w create line 176 129 176 133 -fill $outline -tags {floor3 bg}
    $w create line 315 133 176 133 -fill $outline -tags {floor3 bg}
    $w create line 315 133 315 129 -fill $outline -tags {floor3 bg}
    $w create line 399 129 315 129 -fill $outline -tags {floor3 bg}
    $w create line 399 311 399 129 -fill $outline -tags {floor3 bg}







|

|
|

|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#
# Arguments:
# w -		The canvas window.
# fill -	Fill color to use for the floor's background.
# outline -	Color to use for the floor's outline.

proc bg3 {w fill outline} {
    $w create poly 159 300 107 300 107 248 159 248 159 129 96 129 96 \
	133 21 133 21 331 0 331 0 391 60 391 60 370 159 370 159 300 \
	-tags {floor3 bg} -fill $fill
    $w create poly 258 370 258 329 350 329 350 311 399 311 399 129 \
	315 129 315 133 176 133 176 129 159 129 159 370 258 370 \
	-tags {floor3 bg} -fill $fill
    $w create line 96 133 96 129 -fill $outline -tags {floor3 bg}
    $w create line 176 129 96 129 -fill $outline -tags {floor3 bg}
    $w create line 176 129 176 133 -fill $outline -tags {floor3 bg}
    $w create line 315 133 176 133 -fill $outline -tags {floor3 bg}
    $w create line 315 133 315 129 -fill $outline -tags {floor3 bg}
    $w create line 399 129 315 129 -fill $outline -tags {floor3 bg}
    $w create line 399 311 399 129 -fill $outline -tags {floor3 bg}
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg1 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 101
    set {floorItems(101)} $i
    $w create text 358 209 -text 101 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Pub Lift1}
    set {floorItems(Pub Lift1)} $i
    $w create text 323 223 -text {Pub Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Priv Lift1}
    set {floorItems(Priv Lift1)} $i
    $w create text 323 188 -text {Priv Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 42 389 42 337 1 337 1 389 -outline {} -tags {floor1 room}]
    set floorLabels($i) 110
    set {floorItems(110)} $i
    $w create text 21.5 363 -text 110 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -outline {} -tags {floor1 room}]
    set floorLabels($i) 109
    set {floorItems(109)} $i
    $w create text 67 363 -text 109 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 300 51 253 6 253 6 300 -outline {} -tags {floor1 room}]
    set floorLabels($i) 111
    set {floorItems(111)} $i
    $w create text 28.5 276.5 -text 111 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 98 248 98 309 79 309 79 248 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117B
    set {floorItems(117B)} $i
    $w create text 88.5 278.5 -text 117B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 251 51 204 6 204 6 251 -outline {} -tags {floor1 room}]
    set floorLabels($i) 112
    set {floorItems(112)} $i
    $w create text 28.5 227.5 -text 112 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 6 156 51 156 51 203 6 203 -outline {} -tags {floor1 room}]
    set floorLabels($i) 113
    set {floorItems(113)} $i
    $w create text 28.5 179.5 -text 113 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 85 169 79 169 79 192 85 192 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117A
    set {floorItems(117A)} $i
    $w create text 82 180.5 -text 117A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 77 302 77 168 53 168 53 302 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117
    set {floorItems(117)} $i
    $w create text 65 235 -text 117 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 155 51 115 6 115 6 155 -outline {} -tags {floor1 room}]
    set floorLabels($i) 114
    set {floorItems(114)} $i
    $w create text 28.5 135 -text 114 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 95 115 53 115 53 168 95 168 -outline {} -tags {floor1 room}]
    set floorLabels($i) 115
    set {floorItems(115)} $i
    $w create text 74 141.5 -text 115 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 87 113 87 27 10 27 10 113 -outline {} -tags {floor1 room}]
    set floorLabels($i) 116
    set {floorItems(116)} $i
    $w create text 48.5 70 -text 116 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 89 91 128 91 128 113 89 113 -outline {} -tags {floor1 room}]
    set floorLabels($i) 118
    set {floorItems(118)} $i
    $w create text 108.5 102 -text 118 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -outline {} -tags {floor1 room}]
    set floorLabels($i) 120
    set {floorItems(120)} $i
    $w create text 189.5 111.5 -text 120 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 79 193 87 193 87 169 136 169 136 192 156 192 156 169 175 169 175 246 79 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 122
    set {floorItems(122)} $i
    $w create text 131 207.5 -text 122 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 169 154 169 154 191 138 191 -outline {} -tags {floor1 room}]
    set floorLabels($i) 121
    set {floorItems(121)} $i
    $w create text 146 180 -text 121 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 99 300 126 300 126 309 99 309 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106A
    set {floorItems(106A)} $i
    $w create text 112.5 304.5 -text 106A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -outline {} -tags {floor1 room}]
    set floorLabels($i) 105
    set {floorItems(105)} $i
    $w create text 124.5 278.5 -text 105 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 174 309 174 300 152 300 152 309 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106B
    set {floorItems(106B)} $i
    $w create text 163 304.5 -text 106B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -outline {} -tags {floor1 room}]
    set floorLabels($i) 104
    set {floorItems(104)} $i
    $w create text 184 278.5 -text 104 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 385 138 337 91 337 91 385 -outline {} -tags {floor1 room}]
    set floorLabels($i) 108
    set {floorItems(108)} $i
    $w create text 114.5 361 -text 108 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 256 337 140 337 140 385 256 385 -outline {} -tags {floor1 room}]
    set floorLabels($i) 107
    set {floorItems(107)} $i
    $w create text 198 361 -text 107 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 300 353 300 329 260 329 260 353 -outline {} -tags {floor1 room}]
    set floorLabels($i) Smoking
    set {floorItems(Smoking)} $i
    $w create text 280 341 -text Smoking -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -outline {} -tags {floor1 room}]
    set floorLabels($i) 123
    set {floorItems(123)} $i
    $w create text 245.5 190.5 -text 123 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -outline {} -tags {floor1 room}]
    set floorLabels($i) 103
    set {floorItems(103)} $i
    $w create text 259 287 -text 103 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 124
    set {floorItems(124)} $i
    $w create text 356 150 -text 124 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 125
    set {floorItems(125)} $i
    $w create text 392 217.5 -text 125 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -outline {} -tags {floor1 room}]
    set floorLabels($i) 126
    set {floorItems(126)} $i
    $w create text 436.5 185.5 -text 126 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -outline {} -tags {floor1 room}]
    set floorLabels($i) 127
    set {floorItems(127)} $i
    $w create text 436.5 231 -text 127 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -outline {} -tags {floor1 room}]
    set floorLabels($i) MShower
    set {floorItems(MShower)} $i
    $w create text 488.5 184 -text MShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -outline {} -tags {floor1 room}]
    set floorLabels($i) Closet
    set {floorItems(Closet)} $i
    $w create text 502.5 190 -text Closet -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -outline {} -tags {floor1 room}]
    set floorLabels($i) WShower
    set {floorItems(WShower)} $i
    $w create text 494.5 230 -text WShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 486 131 558 131 558 135 724 135 724 166 697 166 697 275 553 275 531 254 515 254 515 174 503 174 503 161 486 161 -outline {} -tags {floor1 room}]
    set floorLabels($i) 130
    set {floorItems(130)} $i
    $w create text 638.5 205 -text 130 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 308 242 339 242 339 248 342 248 342 246 397 246 397 276 393 276 393 309 300 309 300 248 308 248 -outline {} -tags {floor1 room}]
    set floorLabels($i) 102
    set {floorItems(102)} $i
    $w create text 367.5 278.5 -text 102 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 255 486 255 486 276 397 276 -outline {} -tags {floor1 room}]
    set floorLabels($i) 128
    set {floorItems(128)} $i
    $w create text 441.5 265.5 -text 128 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -outline {} -tags {floor1 room}]
    set floorLabels($i) 129
    set {floorItems(129)} $i
    $w create text 535.5 293 -text 129 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -outline {} -tags {floor1 room}]
    set floorLabels($i) 133
    set {floorItems(133)} $i
    $w create text 628.5 335 -text 133 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 742 387 742 281 800 281 800 387 -outline {} -tags {floor1 room}]
    set floorLabels($i) 132
    set {floorItems(132)} $i
    $w create text 771 334 -text 132 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 800 168 800 280 699 280 699 168 -outline {} -tags {floor1 room}]
    set floorLabels($i) 134
    set {floorItems(134)} $i
    $w create text 749.5 224 -text 134 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 726 131 726 166 800 166 800 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 135
    set {floorItems(135)} $i
    $w create text 763 148.5 -text 135 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 340 360 335 363 331 365 326 366 304 366 304 312 396 312 396 288 400 288 404 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 342 331 347 332 351 334 354 336 357 341 359 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Ramona Stair}
    set {floorItems(Ramona Stair)} $i
    $w create text 368 323 -text {Ramona Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 30 23 30 5 93 5 98 5 104 7 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 87 90 87 90 23 -outline {} -tags {floor1 room}]
    set floorLabels($i) {University Stair}
    set {floorItems(University Stair)} $i
    $w create text 155 77.5 -text {University Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 282 37 295 40 312 49 323 56 337 70 352 56 358 48 363 39 365 29 348 25 335 22 321 14 300 5 283 1 260 0 246 0 242 2 236 4 231 8 227 13 223 17 221 22 220 34 260 34 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Stair}
    set {floorItems(Plaza Stair)} $i
    $w create text 317.5 28.5 -text {Plaza Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 220 34 260 34 282 37 295 40 312 49 323 56 337 70 350 83 365 94 377 100 386 104 386 128 220 128 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Deck}
    set {floorItems(Plaza Deck)} $i
    $w create text 303 81 -text {Plaza Deck} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106
    set {floorItems(106)} $i
    $w create text 131.5 318.5 -text 106 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 146 110 162 110 162 91 130 91 130 115 95 115 95 128 114 128 114 151 157 151 157 153 112 153 112 130 97 130 97 168 175 168 175 131 146 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 119
    set {floorItems(119)} $i
    $w create text 143.5 133 -text 119 -fill $color -anchor c -tags {floor1 label}
    $w create line 155 191 155 189 -fill $color -tags {floor1 wall}
    $w create line 155 177 155 169 -fill $color -tags {floor1 wall}
    $w create line 96 129 96 169 -fill $color -tags {floor1 wall}
    $w create line 78 169 176 169 -fill $color -tags {floor1 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg1 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor1 room}]
    set floorLabels($i) 101
    set {floorItems(101)} $i
    $w create text 358 209 -text 101 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor1 room}]
    set floorLabels($i) {Pub Lift1}
    set {floorItems(Pub Lift1)} $i
    $w create text 323 223 -text {Pub Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor1 room}]
    set floorLabels($i) {Priv Lift1}
    set {floorItems(Priv Lift1)} $i
    $w create text 323 188 -text {Priv Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 42 389 42 337 1 337 1 389 -fill {} -tags {floor1 room}]
    set floorLabels($i) 110
    set {floorItems(110)} $i
    $w create text 21.5 363 -text 110 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -fill {} -tags {floor1 room}]
    set floorLabels($i) 109
    set {floorItems(109)} $i
    $w create text 67 363 -text 109 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 300 51 253 6 253 6 300 -fill {} -tags {floor1 room}]
    set floorLabels($i) 111
    set {floorItems(111)} $i
    $w create text 28.5 276.5 -text 111 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 98 248 98 309 79 309 79 248 -fill {} -tags {floor1 room}]
    set floorLabels($i) 117B
    set {floorItems(117B)} $i
    $w create text 88.5 278.5 -text 117B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 251 51 204 6 204 6 251 -fill {} -tags {floor1 room}]
    set floorLabels($i) 112
    set {floorItems(112)} $i
    $w create text 28.5 227.5 -text 112 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 6 156 51 156 51 203 6 203 -fill {} -tags {floor1 room}]
    set floorLabels($i) 113
    set {floorItems(113)} $i
    $w create text 28.5 179.5 -text 113 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 85 169 79 169 79 192 85 192 -fill {} -tags {floor1 room}]
    set floorLabels($i) 117A
    set {floorItems(117A)} $i
    $w create text 82 180.5 -text 117A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 77 302 77 168 53 168 53 302 -fill {} -tags {floor1 room}]
    set floorLabels($i) 117
    set {floorItems(117)} $i
    $w create text 65 235 -text 117 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 155 51 115 6 115 6 155 -fill {} -tags {floor1 room}]
    set floorLabels($i) 114
    set {floorItems(114)} $i
    $w create text 28.5 135 -text 114 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 95 115 53 115 53 168 95 168 -fill {} -tags {floor1 room}]
    set floorLabels($i) 115
    set {floorItems(115)} $i
    $w create text 74 141.5 -text 115 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 87 113 87 27 10 27 10 113 -fill {} -tags {floor1 room}]
    set floorLabels($i) 116
    set {floorItems(116)} $i
    $w create text 48.5 70 -text 116 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 89 91 128 91 128 113 89 113 -fill {} -tags {floor1 room}]
    set floorLabels($i) 118
    set {floorItems(118)} $i
    $w create text 108.5 102 -text 118 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -fill {} -tags {floor1 room}]
    set floorLabels($i) 120
    set {floorItems(120)} $i
    $w create text 189.5 111.5 -text 120 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 79 193 87 193 87 169 136 169 136 192 156 192 156 169 175 169 175 246 79 246 -fill {} -tags {floor1 room}]
    set floorLabels($i) 122
    set {floorItems(122)} $i
    $w create text 131 207.5 -text 122 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 169 154 169 154 191 138 191 -fill {} -tags {floor1 room}]
    set floorLabels($i) 121
    set {floorItems(121)} $i
    $w create text 146 180 -text 121 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 99 300 126 300 126 309 99 309 -fill {} -tags {floor1 room}]
    set floorLabels($i) 106A
    set {floorItems(106A)} $i
    $w create text 112.5 304.5 -text 106A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -fill {} -tags {floor1 room}]
    set floorLabels($i) 105
    set {floorItems(105)} $i
    $w create text 124.5 278.5 -text 105 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 174 309 174 300 152 300 152 309 -fill {} -tags {floor1 room}]
    set floorLabels($i) 106B
    set {floorItems(106B)} $i
    $w create text 163 304.5 -text 106B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -fill {} -tags {floor1 room}]
    set floorLabels($i) 104
    set {floorItems(104)} $i
    $w create text 184 278.5 -text 104 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 385 138 337 91 337 91 385 -fill {} -tags {floor1 room}]
    set floorLabels($i) 108
    set {floorItems(108)} $i
    $w create text 114.5 361 -text 108 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 256 337 140 337 140 385 256 385 -fill {} -tags {floor1 room}]
    set floorLabels($i) 107
    set {floorItems(107)} $i
    $w create text 198 361 -text 107 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 300 353 300 329 260 329 260 353 -fill {} -tags {floor1 room}]
    set floorLabels($i) Smoking
    set {floorItems(Smoking)} $i
    $w create text 280 341 -text Smoking -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -fill {} -tags {floor1 room}]
    set floorLabels($i) 123
    set {floorItems(123)} $i
    $w create text 245.5 190.5 -text 123 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -fill {} -tags {floor1 room}]
    set floorLabels($i) 103
    set {floorItems(103)} $i
    $w create text 259 287 -text 103 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -fill {} -tags {floor1 room}]
    set floorLabels($i) 124
    set {floorItems(124)} $i
    $w create text 356 150 -text 124 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -fill {} -tags {floor1 room}]
    set floorLabels($i) 125
    set {floorItems(125)} $i
    $w create text 392 217.5 -text 125 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -fill {} -tags {floor1 room}]
    set floorLabels($i) 126
    set {floorItems(126)} $i
    $w create text 436.5 185.5 -text 126 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -fill {} -tags {floor1 room}]
    set floorLabels($i) 127
    set {floorItems(127)} $i
    $w create text 436.5 231 -text 127 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -fill {} -tags {floor1 room}]
    set floorLabels($i) MShower
    set {floorItems(MShower)} $i
    $w create text 488.5 184 -text MShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -fill {} -tags {floor1 room}]
    set floorLabels($i) Closet
    set {floorItems(Closet)} $i
    $w create text 502.5 190 -text Closet -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -fill {} -tags {floor1 room}]
    set floorLabels($i) WShower
    set {floorItems(WShower)} $i
    $w create text 494.5 230 -text WShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 486 131 558 131 558 135 724 135 724 166 697 166 697 275 553 275 531 254 515 254 515 174 503 174 503 161 486 161 -fill {} -tags {floor1 room}]
    set floorLabels($i) 130
    set {floorItems(130)} $i
    $w create text 638.5 205 -text 130 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 308 242 339 242 339 248 342 248 342 246 397 246 397 276 393 276 393 309 300 309 300 248 308 248 -fill {} -tags {floor1 room}]
    set floorLabels($i) 102
    set {floorItems(102)} $i
    $w create text 367.5 278.5 -text 102 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 255 486 255 486 276 397 276 -fill {} -tags {floor1 room}]
    set floorLabels($i) 128
    set {floorItems(128)} $i
    $w create text 441.5 265.5 -text 128 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -fill {} -tags {floor1 room}]
    set floorLabels($i) 129
    set {floorItems(129)} $i
    $w create text 535.5 293 -text 129 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -fill {} -tags {floor1 room}]
    set floorLabels($i) 133
    set {floorItems(133)} $i
    $w create text 628.5 335 -text 133 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 742 387 742 281 800 281 800 387 -fill {} -tags {floor1 room}]
    set floorLabels($i) 132
    set {floorItems(132)} $i
    $w create text 771 334 -text 132 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 800 168 800 280 699 280 699 168 -fill {} -tags {floor1 room}]
    set floorLabels($i) 134
    set {floorItems(134)} $i
    $w create text 749.5 224 -text 134 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 726 131 726 166 800 166 800 131 -fill {} -tags {floor1 room}]
    set floorLabels($i) 135
    set {floorItems(135)} $i
    $w create text 763 148.5 -text 135 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 340 360 335 363 331 365 326 366 304 366 304 312 396 312 396 288 400 288 404 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 342 331 347 332 351 334 354 336 357 341 359 -fill {} -tags {floor1 room}]
    set floorLabels($i) {Ramona Stair}
    set {floorItems(Ramona Stair)} $i
    $w create text 368 323 -text {Ramona Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 30 23 30 5 93 5 98 5 104 7 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 87 90 87 90 23 -fill {} -tags {floor1 room}]
    set floorLabels($i) {University Stair}
    set {floorItems(University Stair)} $i
    $w create text 155 77.5 -text {University Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 282 37 295 40 312 49 323 56 337 70 352 56 358 48 363 39 365 29 348 25 335 22 321 14 300 5 283 1 260 0 246 0 242 2 236 4 231 8 227 13 223 17 221 22 220 34 260 34 -fill {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Stair}
    set {floorItems(Plaza Stair)} $i
    $w create text 317.5 28.5 -text {Plaza Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 220 34 260 34 282 37 295 40 312 49 323 56 337 70 350 83 365 94 377 100 386 104 386 128 220 128 -fill {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Deck}
    set {floorItems(Plaza Deck)} $i
    $w create text 303 81 -text {Plaza Deck} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -fill {} -tags {floor1 room}]
    set floorLabels($i) 106
    set {floorItems(106)} $i
    $w create text 131.5 318.5 -text 106 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 146 110 162 110 162 91 130 91 130 115 95 115 95 128 114 128 114 151 157 151 157 153 112 153 112 130 97 130 97 168 175 168 175 131 146 131 -fill {} -tags {floor1 room}]
    set floorLabels($i) 119
    set {floorItems(119)} $i
    $w create text 143.5 133 -text 119 -fill $color -anchor c -tags {floor1 label}
    $w create line 155 191 155 189 -fill $color -tags {floor1 wall}
    $w create line 155 177 155 169 -fill $color -tags {floor1 wall}
    $w create line 96 129 96 169 -fill $color -tags {floor1 wall}
    $w create line 78 169 176 169 -fill $color -tags {floor1 wall}
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg2 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -outline {} -tags {floor2 room}]
    set floorLabels($i) 238
    set {floorItems(238)} $i
    $w create text 774 195 -text 238 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 237
    set {floorItems(237)} $i
    $w create text 763 148.5 -text 237 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 497 187 497 204 559 204 559 324 641 324 643 324 643 291 641 291 641 205 696 205 696 291 694 291 694 314 715 314 715 291 715 205 755 205 755 190 724 190 724 187 -outline {} -tags {floor2 room}]
    set floorLabels($i) 246
    set {floorItems(246)} $i
    $w create text 600 264 -text 246 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 694 279 643 279 643 314 694 314 -outline {} -tags {floor2 room}]
    set floorLabels($i) 247
    set {floorItems(247)} $i
    $w create text 668.5 296.5 -text 247 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 232 250 308 250 308 242 339 242 339 246 397 246 397 255 476 255 476 250 482 250 559 250 559 274 482 274 482 278 396 278 396 274 232 274 -outline {} -tags {floor2 room}]
    set floorLabels($i) 202
    set {floorItems(202)} $i
    $w create text 285.5 260 -text 202 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 53 228 53 338 176 338 233 338 233 196 306 196 306 180 175 180 175 169 156 169 156 196 176 196 176 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 206
    set {floorItems(206)} $i
    $w create text 143 267 -text 206 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 277 6 277 6 338 51 338 -outline {} -tags {floor2 room}]
    set floorLabels($i) 212
    set {floorItems(212)} $i
    $w create text 28.5 307.5 -text 212 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -outline {} -tags {floor2 room}]
    set floorLabels($i) 245
    set {floorItems(245)} $i
    $w create text 521.5 300.5 -text 245 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 560 389 599 389 599 326 560 326 -outline {} -tags {floor2 room}]
    set floorLabels($i) 244
    set {floorItems(244)} $i
    $w create text 579.5 357.5 -text 244 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 601 389 601 326 643 326 643 389 -outline {} -tags {floor2 room}]
    set floorLabels($i) 243
    set {floorItems(243)} $i
    $w create text 622 357.5 -text 243 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 688 316 645 316 645 365 688 365 -outline {} -tags {floor2 room}]
    set floorLabels($i) 242
    set {floorItems(242)} $i
    $w create text 666.5 340.5 -text 242 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 802 367 759 367 759 226 802 226 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Barbecue Deck}
    set {floorItems(Barbecue Deck)} $i
    $w create text 780.5 296.5 -text {Barbecue Deck} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 262 755 314 717 314 717 262 -outline {} -tags {floor2 room}]
    set floorLabels($i) 240
    set {floorItems(240)} $i
    $w create text 736 288 -text 240 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 316 689 316 689 365 755 365 -outline {} -tags {floor2 room}]
    set floorLabels($i) 241
    set {floorItems(241)} $i
    $w create text 722 340.5 -text 241 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 206 717 206 717 261 755 261 -outline {} -tags {floor2 room}]
    set floorLabels($i) 239
    set {floorItems(239)} $i
    $w create text 736 233.5 -text 239 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 695 277 643 277 643 206 695 206 -outline {} -tags {floor2 room}]
    set floorLabels($i) 248
    set {floorItems(248)} $i
    $w create text 669 241.5 -text 248 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 676 135 676 185 724 185 724 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 236
    set {floorItems(236)} $i
    $w create text 700 160 -text 236 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 235
    set {floorItems(235)} $i
    $w create text 651.5 160 -text 235 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 234
    set {floorItems(234)} $i
    $w create text 606 160 -text 234 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 233
    set {floorItems(233)} $i
    $w create text 552.5 158 -text 233 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 249 557 249 557 205 476 205 -outline {} -tags {floor2 room}]
    set floorLabels($i) 230
    set {floorItems(230)} $i
    $w create text 516.5 227 -text 230 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 232
    set {floorItems(232)} $i
    $w create text 500.5 158 -text 232 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 186 495 186 495 204 476 204 -outline {} -tags {floor2 room}]
    set floorLabels($i) 229
    set {floorItems(229)} $i
    $w create text 485.5 195 -text 229 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -outline {} -tags {floor2 room}]
    set floorLabels($i) 227
    set {floorItems(227)} $i
    $w create text 436.5 185.5 -text 227 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 228
    set {floorItems(228)} $i
    $w create text 436.5 231 -text 228 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -outline {} -tags {floor2 room}]
    set floorLabels($i) 226
    set {floorItems(226)} $i
    $w create text 392 217.5 -text 226 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -outline {} -tags {floor2 room}]
    set floorLabels($i) 225
    set {floorItems(225)} $i
    $w create text 356.5 150 -text 225 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 198 306 198 306 249 234 249 -outline {} -tags {floor2 room}]
    set floorLabels($i) 224
    set {floorItems(224)} $i
    $w create text 270 223.5 -text 224 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 223
    set {floorItems(223)} $i
    $w create text 292 157 -text 223 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 268 179 221 179 221 135 268 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 222
    set {floorItems(222)} $i
    $w create text 244.5 157 -text 222 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 177 179 219 179 219 135 177 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 221
    set {floorItems(221)} $i
    $w create text 198 157 -text 221 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -outline {} -tags {floor2 room}]
    set floorLabels($i) 204
    set {floorItems(204)} $i
    $w create text 324 301.5 -text 204 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -outline {} -tags {floor2 room}]
    set floorLabels($i) 205
    set {floorItems(205)} $i
    $w create text 265.5 307 -text 205 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 256 385 256 340 212 340 212 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 207
    set {floorItems(207)} $i
    $w create text 234 362.5 -text 207 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 210 340 164 340 164 385 210 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 208
    set {floorItems(208)} $i
    $w create text 187 362.5 -text 208 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 115 340 162 340 162 385 115 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 209
    set {floorItems(209)} $i
    $w create text 138.5 362.5 -text 209 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 228 89 156 53 156 53 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 217
    set {floorItems(217)} $i
    $w create text 71 192 -text 217 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 169 97 169 97 190 89 190 -outline {} -tags {floor2 room}]
    set floorLabels($i) 217A
    set {floorItems(217A)} $i
    $w create text 93 179.5 -text 217A -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -outline {} -tags {floor2 room}]
    set floorLabels($i) 216
    set {floorItems(216)} $i
    $w create text 71 145.5 -text 216 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 179 51 135 6 135 6 179 -outline {} -tags {floor2 room}]
    set floorLabels($i) 215
    set {floorItems(215)} $i
    $w create text 28.5 157 -text 215 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 227 6 227 6 180 51 180 -outline {} -tags {floor2 room}]
    set floorLabels($i) 214
    set {floorItems(214)} $i
    $w create text 28.5 203.5 -text 214 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 275 6 275 6 229 51 229 -outline {} -tags {floor2 room}]
    set floorLabels($i) 213
    set {floorItems(213)} $i
    $w create text 28.5 252 -text 213 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 114 340 67 340 67 385 114 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 210
    set {floorItems(210)} $i
    $w create text 90.5 362.5 -text 210 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -outline {} -tags {floor2 room}]
    set floorLabels($i) 211
    set {floorItems(211)} $i
    $w create text 33 364.5 -text 211 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -outline {} -tags {floor2 room}]
    set floorLabels($i) 203
    set {floorItems(203)} $i
    $w create text 367.5 292.5 -text 203 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 99 191 91 191 91 226 174 226 174 198 154 198 154 192 109 192 109 169 99 169 -outline {} -tags {floor2 room}]
    set floorLabels($i) 220
    set {floorItems(220)} $i
    $w create text 132.5 208.5 -text 220 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Priv Lift2}
    set {floorItems(Priv Lift2)} $i
    $w create text 323 188 -text {Priv Lift2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Pub Lift 2}
    set {floorItems(Pub Lift 2)} $i
    $w create text 323 223 -text {Pub Lift 2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 218
    set {floorItems(218)} $i
    $w create text 136 149.5 -text 218 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -outline {} -tags {floor2 room}]
    set floorLabels($i) 219
    set {floorItems(219)} $i
    $w create text 132.5 180 -text 219 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor2 room}]
    set floorLabels($i) 201
    set {floorItems(201)} $i
    $w create text 358 209 -text 201 -fill $color -anchor c -tags {floor2 label}
    $w create line 641 186 678 186 -fill $color -tags {floor2 wall}
    $w create line 757 350 757 367 -fill $color -tags {floor2 wall}
    $w create line 634 133 634 144 -fill $color -tags {floor2 wall}
    $w create line 634 144 627 144 -fill $color -tags {floor2 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg2 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -fill {} -tags {floor2 room}]
    set floorLabels($i) 238
    set {floorItems(238)} $i
    $w create text 774 195 -text 238 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -fill {} -tags {floor2 room}]
    set floorLabels($i) 237
    set {floorItems(237)} $i
    $w create text 763 148.5 -text 237 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 497 187 497 204 559 204 559 324 641 324 643 324 643 291 641 291 641 205 696 205 696 291 694 291 694 314 715 314 715 291 715 205 755 205 755 190 724 190 724 187 -fill {} -tags {floor2 room}]
    set floorLabels($i) 246
    set {floorItems(246)} $i
    $w create text 600 264 -text 246 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 694 279 643 279 643 314 694 314 -fill {} -tags {floor2 room}]
    set floorLabels($i) 247
    set {floorItems(247)} $i
    $w create text 668.5 296.5 -text 247 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 232 250 308 250 308 242 339 242 339 246 397 246 397 255 476 255 476 250 482 250 559 250 559 274 482 274 482 278 396 278 396 274 232 274 -fill {} -tags {floor2 room}]
    set floorLabels($i) 202
    set {floorItems(202)} $i
    $w create text 285.5 260 -text 202 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 53 228 53 338 176 338 233 338 233 196 306 196 306 180 175 180 175 169 156 169 156 196 176 196 176 228 -fill {} -tags {floor2 room}]
    set floorLabels($i) 206
    set {floorItems(206)} $i
    $w create text 143 267 -text 206 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 277 6 277 6 338 51 338 -fill {} -tags {floor2 room}]
    set floorLabels($i) 212
    set {floorItems(212)} $i
    $w create text 28.5 307.5 -text 212 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -fill {} -tags {floor2 room}]
    set floorLabels($i) 245
    set {floorItems(245)} $i
    $w create text 521.5 300.5 -text 245 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 560 389 599 389 599 326 560 326 -fill {} -tags {floor2 room}]
    set floorLabels($i) 244
    set {floorItems(244)} $i
    $w create text 579.5 357.5 -text 244 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 601 389 601 326 643 326 643 389 -fill {} -tags {floor2 room}]
    set floorLabels($i) 243
    set {floorItems(243)} $i
    $w create text 622 357.5 -text 243 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 688 316 645 316 645 365 688 365 -fill {} -tags {floor2 room}]
    set floorLabels($i) 242
    set {floorItems(242)} $i
    $w create text 666.5 340.5 -text 242 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 802 367 759 367 759 226 802 226 -fill {} -tags {floor2 room}]
    set floorLabels($i) {Barbecue Deck}
    set {floorItems(Barbecue Deck)} $i
    $w create text 780.5 296.5 -text {Barbecue Deck} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 262 755 314 717 314 717 262 -fill {} -tags {floor2 room}]
    set floorLabels($i) 240
    set {floorItems(240)} $i
    $w create text 736 288 -text 240 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 316 689 316 689 365 755 365 -fill {} -tags {floor2 room}]
    set floorLabels($i) 241
    set {floorItems(241)} $i
    $w create text 722 340.5 -text 241 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 206 717 206 717 261 755 261 -fill {} -tags {floor2 room}]
    set floorLabels($i) 239
    set {floorItems(239)} $i
    $w create text 736 233.5 -text 239 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 695 277 643 277 643 206 695 206 -fill {} -tags {floor2 room}]
    set floorLabels($i) 248
    set {floorItems(248)} $i
    $w create text 669 241.5 -text 248 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 676 135 676 185 724 185 724 135 -fill {} -tags {floor2 room}]
    set floorLabels($i) 236
    set {floorItems(236)} $i
    $w create text 700 160 -text 236 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -fill {} -tags {floor2 room}]
    set floorLabels($i) 235
    set {floorItems(235)} $i
    $w create text 651.5 160 -text 235 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -fill {} -tags {floor2 room}]
    set floorLabels($i) 234
    set {floorItems(234)} $i
    $w create text 606 160 -text 234 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -fill {} -tags {floor2 room}]
    set floorLabels($i) 233
    set {floorItems(233)} $i
    $w create text 552.5 158 -text 233 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 249 557 249 557 205 476 205 -fill {} -tags {floor2 room}]
    set floorLabels($i) 230
    set {floorItems(230)} $i
    $w create text 516.5 227 -text 230 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -fill {} -tags {floor2 room}]
    set floorLabels($i) 232
    set {floorItems(232)} $i
    $w create text 500.5 158 -text 232 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 186 495 186 495 204 476 204 -fill {} -tags {floor2 room}]
    set floorLabels($i) 229
    set {floorItems(229)} $i
    $w create text 485.5 195 -text 229 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -fill {} -tags {floor2 room}]
    set floorLabels($i) 227
    set {floorItems(227)} $i
    $w create text 436.5 185.5 -text 227 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -fill {} -tags {floor2 room}]
    set floorLabels($i) 228
    set {floorItems(228)} $i
    $w create text 436.5 231 -text 228 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -fill {} -tags {floor2 room}]
    set floorLabels($i) 226
    set {floorItems(226)} $i
    $w create text 392 217.5 -text 226 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -fill {} -tags {floor2 room}]
    set floorLabels($i) 225
    set {floorItems(225)} $i
    $w create text 356.5 150 -text 225 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 198 306 198 306 249 234 249 -fill {} -tags {floor2 room}]
    set floorLabels($i) 224
    set {floorItems(224)} $i
    $w create text 270 223.5 -text 224 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -fill {} -tags {floor2 room}]
    set floorLabels($i) 223
    set {floorItems(223)} $i
    $w create text 292 157 -text 223 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 268 179 221 179 221 135 268 135 -fill {} -tags {floor2 room}]
    set floorLabels($i) 222
    set {floorItems(222)} $i
    $w create text 244.5 157 -text 222 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 177 179 219 179 219 135 177 135 -fill {} -tags {floor2 room}]
    set floorLabels($i) 221
    set {floorItems(221)} $i
    $w create text 198 157 -text 221 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -fill {} -tags {floor2 room}]
    set floorLabels($i) 204
    set {floorItems(204)} $i
    $w create text 324 301.5 -text 204 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -fill {} -tags {floor2 room}]
    set floorLabels($i) 205
    set {floorItems(205)} $i
    $w create text 265.5 307 -text 205 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 256 385 256 340 212 340 212 385 -fill {} -tags {floor2 room}]
    set floorLabels($i) 207
    set {floorItems(207)} $i
    $w create text 234 362.5 -text 207 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 210 340 164 340 164 385 210 385 -fill {} -tags {floor2 room}]
    set floorLabels($i) 208
    set {floorItems(208)} $i
    $w create text 187 362.5 -text 208 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 115 340 162 340 162 385 115 385 -fill {} -tags {floor2 room}]
    set floorLabels($i) 209
    set {floorItems(209)} $i
    $w create text 138.5 362.5 -text 209 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 228 89 156 53 156 53 228 -fill {} -tags {floor2 room}]
    set floorLabels($i) 217
    set {floorItems(217)} $i
    $w create text 71 192 -text 217 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 169 97 169 97 190 89 190 -fill {} -tags {floor2 room}]
    set floorLabels($i) 217A
    set {floorItems(217A)} $i
    $w create text 93 179.5 -text 217A -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -fill {} -tags {floor2 room}]
    set floorLabels($i) 216
    set {floorItems(216)} $i
    $w create text 71 145.5 -text 216 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 179 51 135 6 135 6 179 -fill {} -tags {floor2 room}]
    set floorLabels($i) 215
    set {floorItems(215)} $i
    $w create text 28.5 157 -text 215 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 227 6 227 6 180 51 180 -fill {} -tags {floor2 room}]
    set floorLabels($i) 214
    set {floorItems(214)} $i
    $w create text 28.5 203.5 -text 214 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 275 6 275 6 229 51 229 -fill {} -tags {floor2 room}]
    set floorLabels($i) 213
    set {floorItems(213)} $i
    $w create text 28.5 252 -text 213 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 114 340 67 340 67 385 114 385 -fill {} -tags {floor2 room}]
    set floorLabels($i) 210
    set {floorItems(210)} $i
    $w create text 90.5 362.5 -text 210 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -fill {} -tags {floor2 room}]
    set floorLabels($i) 211
    set {floorItems(211)} $i
    $w create text 33 364.5 -text 211 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -fill {} -tags {floor2 room}]
    set floorLabels($i) 203
    set {floorItems(203)} $i
    $w create text 367.5 292.5 -text 203 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 99 191 91 191 91 226 174 226 174 198 154 198 154 192 109 192 109 169 99 169 -fill {} -tags {floor2 room}]
    set floorLabels($i) 220
    set {floorItems(220)} $i
    $w create text 132.5 208.5 -text 220 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor2 room}]
    set floorLabels($i) {Priv Lift2}
    set {floorItems(Priv Lift2)} $i
    $w create text 323 188 -text {Priv Lift2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor2 room}]
    set floorLabels($i) {Pub Lift 2}
    set {floorItems(Pub Lift 2)} $i
    $w create text 323 223 -text {Pub Lift 2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -tags {floor2 room}]
    set floorLabels($i) 218
    set {floorItems(218)} $i
    $w create text 136 149.5 -text 218 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -tags {floor2 room}]
    set floorLabels($i) 219
    set {floorItems(219)} $i
    $w create text 132.5 180 -text 219 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor2 room}]
    set floorLabels($i) 201
    set {floorItems(201)} $i
    $w create text 358 209 -text 201 -fill $color -anchor c -tags {floor2 label}
    $w create line 641 186 678 186 -fill $color -tags {floor2 wall}
    $w create line 757 350 757 367 -fill $color -tags {floor2 wall}
    $w create line 634 133 634 144 -fill $color -tags {floor2 wall}
    $w create line 634 144 627 144 -fill $color -tags {floor2 wall}
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg3 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 89 228 89 180 70 180 70 228 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316
    set {floorItems(316)} $i
    $w create text 79.5 204 -text 316 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 115 368 162 368 162 323 115 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 309
    set {floorItems(309)} $i
    $w create text 138.5 345.5 -text 309 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 164 323 164 368 211 368 211 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 308
    set {floorItems(308)} $i
    $w create text 187.5 345.5 -text 308 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 256 368 212 368 212 323 256 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 307
    set {floorItems(307)} $i
    $w create text 234 345.5 -text 307 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -outline {} -tags {floor3 room}]
    set floorLabels($i) 305
    set {floorItems(305)} $i
    $w create text 270.5 301.5 -text 305 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 219 251 203 244 203 244 219 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324B
    set {floorItems(324B)} $i
    $w create text 247.5 211 -text 324B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 249 244 249 244 232 251 232 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324A
    set {floorItems(324A)} $i
    $w create text 247.5 240.5 -text 324A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 223 135 223 179 177 179 177 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 320
    set {floorItems(320)} $i
    $w create text 200 157 -text 320 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 114 368 114 323 67 323 67 368 -outline {} -tags {floor3 room}]
    set floorLabels($i) 310
    set {floorItems(310)} $i
    $w create text 90.5 345.5 -text 310 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 277 23 321 68 321 68 277 -outline {} -tags {floor3 room}]
    set floorLabels($i) 312
    set {floorItems(312)} $i
    $w create text 45.5 299 -text 312 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 229 68 229 68 275 23 275 -outline {} -tags {floor3 room}]
    set floorLabels($i) 313
    set {floorItems(313)} $i
    $w create text 45.5 252 -text 313 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 68 227 23 227 23 180 68 180 -outline {} -tags {floor3 room}]
    set floorLabels($i) 314
    set {floorItems(314)} $i
    $w create text 45.5 203.5 -text 314 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 95 179 95 135 23 135 23 179 -outline {} -tags {floor3 room}]
    set floorLabels($i) 315
    set {floorItems(315)} $i
    $w create text 59 157 -text 315 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 99 226 99 204 91 204 91 226 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316B
    set {floorItems(316B)} $i
    $w create text 95 215 -text 316B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 91 202 99 202 99 180 91 180 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316A
    set {floorItems(316A)} $i
    $w create text 95 191 -text 316A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 97 169 109 169 109 192 154 192 154 198 174 198 174 226 101 226 101 179 97 179 -outline {} -tags {floor3 room}]
    set floorLabels($i) 319
    set {floorItems(319)} $i
    $w create text 141.5 209 -text 319 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 311
    set {floorItems(311)} $i
    $w create text 29.5 361 -text 311 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -outline {} -tags {floor3 room}]
    set floorLabels($i) 318
    set {floorItems(318)} $i
    $w create text 132.5 180 -text 318 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -outline {} -tags {floor3 room}]
    set floorLabels($i) 317
    set {floorItems(317)} $i
    $w create text 136 149.5 -text 317 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 274 194 274 221 306 221 306 194 -outline {} -tags {floor3 room}]
    set floorLabels($i) 323
    set {floorItems(323)} $i
    $w create text 290 207.5 -text 323 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 306 222 274 222 274 249 306 249 -outline {} -tags {floor3 room}]
    set floorLabels($i) 325
    set {floorItems(325)} $i
    $w create text 290 235.5 -text 325 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 263 179 224 179 224 135 263 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 321
    set {floorItems(321)} $i
    $w create text 243.5 157 -text 321 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 322
    set {floorItems(322)} $i
    $w create text 293.5 163.5 -text 322 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor3 room}]
    set floorLabels($i) {Pub Lift3}
    set {floorItems(Pub Lift3)} $i
    $w create text 323 223 -text {Pub Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor3 room}]
    set floorLabels($i) {Priv Lift3}
    set {floorItems(Priv Lift3)} $i
    $w create text 323 188 -text {Priv Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -outline {} -tags {floor3 room}]
    set floorLabels($i) 303
    set {floorItems(303)} $i
    $w create text 373.5 292.5 -text 303 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324
    set {floorItems(324)} $i
    $w create text 262 226 -text 324 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -outline {} -tags {floor3 room}]
    set floorLabels($i) 304
    set {floorItems(304)} $i
    $w create text 324 301.5 -text 304 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor3 room}]
    set floorLabels($i) 301
    set {floorItems(301)} $i
    $w create text 358 209 -text 301 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 397 246 377 246 377 185 397 185 -outline {} -tags {floor3 room}]
    set floorLabels($i) 327
    set {floorItems(327)} $i
    $w create text 387 215.5 -text 327 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -outline {} -tags {floor3 room}]
    set floorLabels($i) 326
    set {floorItems(326)} $i
    $w create text 356.5 150 -text 326 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 308 251 242 251 242 274 342 274 342 282 375 282 375 274 397 274 397 248 339 248 339 242 308 242 -outline {} -tags {floor3 room}]
    set floorLabels($i) 302
    set {floorItems(302)} $i
    $w create text 319.5 261 -text 302 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 70 321 242 321 242 200 259 200 259 203 272 203 272 193 263 180 242 180 175 180 175 169 156 169 156 196 177 196 177 228 107 228 70 228 70 275 107 275 107 248 160 248 160 301 107 301 107 275 70 275 -outline {} -tags {floor3 room}]
    set floorLabels($i) 306
    set {floorItems(306)} $i
    $w create text 200.5 284.5 -text 306 -fill $color -anchor c -tags {floor3 label}
    $w create line 341 275 341 283 -fill $color -tags {floor3 wall}
    $w create line 162 197 155 197 -fill $color -tags {floor3 wall}
    $w create line 396 247 399 247 -fill $color -tags {floor3 wall}
    $w create line 399 129 399 311 -fill $color -tags {floor3 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg3 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 89 228 89 180 70 180 70 228 -fill {} -tags {floor3 room}]
    set floorLabels($i) 316
    set {floorItems(316)} $i
    $w create text 79.5 204 -text 316 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 115 368 162 368 162 323 115 323 -fill {} -tags {floor3 room}]
    set floorLabels($i) 309
    set {floorItems(309)} $i
    $w create text 138.5 345.5 -text 309 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 164 323 164 368 211 368 211 323 -fill {} -tags {floor3 room}]
    set floorLabels($i) 308
    set {floorItems(308)} $i
    $w create text 187.5 345.5 -text 308 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 256 368 212 368 212 323 256 323 -fill {} -tags {floor3 room}]
    set floorLabels($i) 307
    set {floorItems(307)} $i
    $w create text 234 345.5 -text 307 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -fill {} -tags {floor3 room}]
    set floorLabels($i) 305
    set {floorItems(305)} $i
    $w create text 270.5 301.5 -text 305 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 219 251 203 244 203 244 219 -fill {} -tags {floor3 room}]
    set floorLabels($i) 324B
    set {floorItems(324B)} $i
    $w create text 247.5 211 -text 324B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 249 244 249 244 232 251 232 -fill {} -tags {floor3 room}]
    set floorLabels($i) 324A
    set {floorItems(324A)} $i
    $w create text 247.5 240.5 -text 324A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 223 135 223 179 177 179 177 135 -fill {} -tags {floor3 room}]
    set floorLabels($i) 320
    set {floorItems(320)} $i
    $w create text 200 157 -text 320 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 114 368 114 323 67 323 67 368 -fill {} -tags {floor3 room}]
    set floorLabels($i) 310
    set {floorItems(310)} $i
    $w create text 90.5 345.5 -text 310 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 277 23 321 68 321 68 277 -fill {} -tags {floor3 room}]
    set floorLabels($i) 312
    set {floorItems(312)} $i
    $w create text 45.5 299 -text 312 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 229 68 229 68 275 23 275 -fill {} -tags {floor3 room}]
    set floorLabels($i) 313
    set {floorItems(313)} $i
    $w create text 45.5 252 -text 313 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 68 227 23 227 23 180 68 180 -fill {} -tags {floor3 room}]
    set floorLabels($i) 314
    set {floorItems(314)} $i
    $w create text 45.5 203.5 -text 314 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 95 179 95 135 23 135 23 179 -fill {} -tags {floor3 room}]
    set floorLabels($i) 315
    set {floorItems(315)} $i
    $w create text 59 157 -text 315 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 99 226 99 204 91 204 91 226 -fill {} -tags {floor3 room}]
    set floorLabels($i) 316B
    set {floorItems(316B)} $i
    $w create text 95 215 -text 316B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 91 202 99 202 99 180 91 180 -fill {} -tags {floor3 room}]
    set floorLabels($i) 316A
    set {floorItems(316A)} $i
    $w create text 95 191 -text 316A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 97 169 109 169 109 192 154 192 154 198 174 198 174 226 101 226 101 179 97 179 -fill {} -tags {floor3 room}]
    set floorLabels($i) 319
    set {floorItems(319)} $i
    $w create text 141.5 209 -text 319 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -fill {} -tags {floor3 room}]
    set floorLabels($i) 311
    set {floorItems(311)} $i
    $w create text 29.5 361 -text 311 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -tags {floor3 room}]
    set floorLabels($i) 318
    set {floorItems(318)} $i
    $w create text 132.5 180 -text 318 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -tags {floor3 room}]
    set floorLabels($i) 317
    set {floorItems(317)} $i
    $w create text 136 149.5 -text 317 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 274 194 274 221 306 221 306 194 -fill {} -tags {floor3 room}]
    set floorLabels($i) 323
    set {floorItems(323)} $i
    $w create text 290 207.5 -text 323 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 306 222 274 222 274 249 306 249 -fill {} -tags {floor3 room}]
    set floorLabels($i) 325
    set {floorItems(325)} $i
    $w create text 290 235.5 -text 325 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 263 179 224 179 224 135 263 135 -fill {} -tags {floor3 room}]
    set floorLabels($i) 321
    set {floorItems(321)} $i
    $w create text 243.5 157 -text 321 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -fill {} -tags {floor3 room}]
    set floorLabels($i) 322
    set {floorItems(322)} $i
    $w create text 293.5 163.5 -text 322 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor3 room}]
    set floorLabels($i) {Pub Lift3}
    set {floorItems(Pub Lift3)} $i
    $w create text 323 223 -text {Pub Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor3 room}]
    set floorLabels($i) {Priv Lift3}
    set {floorItems(Priv Lift3)} $i
    $w create text 323 188 -text {Priv Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -fill {} -tags {floor3 room}]
    set floorLabels($i) 303
    set {floorItems(303)} $i
    $w create text 373.5 292.5 -text 303 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -fill {} -tags {floor3 room}]
    set floorLabels($i) 324
    set {floorItems(324)} $i
    $w create text 262 226 -text 324 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -fill {} -tags {floor3 room}]
    set floorLabels($i) 304
    set {floorItems(304)} $i
    $w create text 324 301.5 -text 304 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor3 room}]
    set floorLabels($i) 301
    set {floorItems(301)} $i
    $w create text 358 209 -text 301 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 397 246 377 246 377 185 397 185 -fill {} -tags {floor3 room}]
    set floorLabels($i) 327
    set {floorItems(327)} $i
    $w create text 387 215.5 -text 327 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -fill {} -tags {floor3 room}]
    set floorLabels($i) 326
    set {floorItems(326)} $i
    $w create text 356.5 150 -text 326 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 308 251 242 251 242 274 342 274 342 282 375 282 375 274 397 274 397 248 339 248 339 242 308 242 -fill {} -tags {floor3 room}]
    set floorLabels($i) 302
    set {floorItems(302)} $i
    $w create text 319.5 261 -text 302 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 70 321 242 321 242 200 259 200 259 203 272 203 272 193 263 180 242 180 175 180 175 169 156 169 156 196 177 196 177 228 107 228 70 228 70 275 107 275 107 248 160 248 160 301 107 301 107 275 70 275 -fill {} -tags {floor3 room}]
    set floorLabels($i) 306
    set {floorItems(306)} $i
    $w create text 200.5 284.5 -text 306 -fill $color -anchor c -tags {floor3 label}
    $w create line 341 275 341 283 -fill $color -tags {floor3 wall}
    $w create line 162 197 155 197 -fill $color -tags {floor3 wall}
    $w create line 396 247 399 247 -fill $color -tags {floor3 wall}
    $w create line 399 129 399 311 -fill $color -tags {floor3 wall}
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set f [frame $w.frame]
pack $f -side top -fill both -expand yes
set h [ttk::scrollbar $f.hscroll -orient horizontal]
set v [ttk::scrollbar $f.vscroll -orient vertical]
set f1 [frame $f.f1 -borderwidth 2 -relief sunken]
set c [canvas $f1.c -width 900 -height 500 -highlightthickness 0 \
	   -xscrollcommand [list $h set] \
	   -yscrollcommand [list $v set]]
pack $c -expand yes -fill both
grid $f1 -padx 1 -pady 1 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $v -padx 1 -pady 1 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news







|
|







1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set f [frame $w.frame]
pack $f -side top -fill both -expand yes
set h [scrollbar $f.hscroll -orient horizontal]
set v [scrollbar $f.vscroll -orient vertical]
set f1 [frame $f.f1 -borderwidth 2 -relief sunken]
set c [canvas $f1.c -width 900 -height 500 -highlightthickness 0 \
	   -xscrollcommand [list $h set] \
	   -yscrollcommand [list $v set]]
pack $c -expand yes -fill both
grid $f1 -padx 1 -pady 1 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $v -padx 1 -pady 1 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
    set colors(active) black
}
set activeFloor ""
floorDisplay $c 3

# Set up event bindings for canvas:

$c bind floor1 <Button-1> "floorDisplay $c 1"
$c bind floor2 <Button-1> "floorDisplay $c 2"
$c bind floor3 <Button-1> "floorDisplay $c 3"
$c bind room <Enter> "newRoom $c"
$c bind room <Leave> {set currentRoom ""}
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
} else {
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
}
bind $c <Destroy> "unset currentRoom"
set currentRoom ""
trace variable currentRoom w "roomChanged $c"







|
|
|


<
<
<
<
|
|
<



1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361




1362
1363

1364
1365
1366
    set colors(active) black
}
set activeFloor ""
floorDisplay $c 3

# Set up event bindings for canvas:

$c bind floor1 <1> "floorDisplay $c 1"
$c bind floor2 <1> "floorDisplay $c 2"
$c bind floor3 <1> "floorDisplay $c 3"
$c bind room <Enter> "newRoom $c"
$c bind room <Leave> {set currentRoom ""}




bind $c <2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"

bind $c <Destroy> "unset currentRoom"
set currentRoom ""
trace variable currentRoom w "roomChanged $c"

Deleted library/demos/fontchoose.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# fontchoose.tcl --
#
# Show off the stock font selector dialog

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .fontchoose
catch {destroy $w}
toplevel $w
wm title $w "Font Selection Dialog"
wm iconname $w "fontchooser"
positionWindow $w

catch {font create FontchooseDemoFont {*}[font actual TkDefaultFont]}

# The font chooser needs to be configured and then shown.
proc SelectFont {parent} {
    tk fontchooser configure -font FontchooseDemoFont \
        -command ApplyFont -parent $parent
    tk fontchooser show
}

proc ApplyFont {font} {
    font configure FontchooseDemoFont {*}[font actual $font]
}

# When the visibility of the fontchooser changes, the following event is fired
# to the parent widget.
#
bind $w <<TkFontchooserVisibility>> {
    if {[tk fontchooser configure -visible]} {
        %W.f.font state disabled
    } else {
        %W.f.font state !disabled
    }
}


set f [ttk::frame $w.f -relief sunken -padding 2]

text $f.msg -font FontchooseDemoFont -width 40 -height 6 -borderwidth 0 \
    -yscrollcommand [list $f.vs set]
ttk::scrollbar $f.vs -command [list $f.msg yview]

$f.msg insert end "Press the buttons below to choose a new font for the\
  text shown in this window.\n" {}

ttk::button $f.font -text "Set font ..." -command [list SelectFont $w]

grid $f.msg $f.vs -sticky news
grid $f.font -    -sticky e
grid columnconfigure $f 0 -weight 1
grid rowconfigure $f 0 -weight 1

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]

grid $f -sticky news
grid $btns -sticky ew
grid columnconfigure $w 0 -weight 1
grid rowconfigure $w 0 -weight 1
update idletasks
grid propagate $f 0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































Changes to library/demos/goldberg.tcl.

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
	    -side left -fill both -expand 1

    canvas $w.c -width 860 -height 730 -bg $C(bg) -highlightthickness 0
    $w.c config -scrollregion {0 0 1000 1000}	;# Kludge: move everything up
    $w.c yview moveto .05
    pack $w.c -in $w.screen -side top -fill both -expand 1

    bind $w.c <Button-3> [list $w.pause invoke]
    bind $w.c <Destroy> {
	after cancel $animationCallbacks(goldberg)
	unset animationCallbacks(goldberg)
    }
    DoCtrlFrame $w
    DoDetailFrame $w
    if {[tk windowingsystem] ne "aqua"} {
	ttk::button $w.show -text "»" -command [list ShowCtrl $w] -width 2
    } else {
	button $w.show -text "»" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
    }
    place $w.show -in $w.c -relx 1 -rely 0 -anchor ne
    update
}

proc DoCtrlFrame {w} {
    global S







|







|

|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
	    -side left -fill both -expand 1

    canvas $w.c -width 860 -height 730 -bg $C(bg) -highlightthickness 0
    $w.c config -scrollregion {0 0 1000 1000}	;# Kludge: move everything up
    $w.c yview moveto .05
    pack $w.c -in $w.screen -side top -fill both -expand 1

    bind $w.c <3> [list $w.pause invoke]
    bind $w.c <Destroy> {
	after cancel $animationCallbacks(goldberg)
	unset animationCallbacks(goldberg)
    }
    DoCtrlFrame $w
    DoDetailFrame $w
    if {[tk windowingsystem] ne "aqua"} {
	ttk::button $w.show -text "\u00bb" -command [list ShowCtrl $w] -width 2
    } else {
	button $w.show -text "\u00bb" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
    }
    place $w.show -in $w.c -relx 1 -rely 0 -anchor ne
    update
}

proc DoCtrlFrame {w} {
    global S
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    trace variable ::S(speed) w	  [list ActiveGUI $w]

    grid $w.message -in $w.ctrl -row 98 -sticky ew -pady 5
    grid $w.message.e -sticky nsew
    grid $w.speed -in $w.ctrl -row 99 -sticky ew -pady {0 5}
    pack $w.speed.scale -fill both -expand 1
    grid $w.about -in $w.ctrl -row 100 -sticky ew
    bind $w.reset <Button-3> {set S(mode) -1}		;# Debugging

    ## See Code / Dismiss buttons hack!
    set btns [addSeeDismiss $w.ctrl.buttons $w]
    grid [ttk::separator $w.ctrl.sep] -sticky ew -pady 4
    set i 0
    foreach b [winfo children $btns] {
	if {[winfo class $b] eq "TButton"} {







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    trace variable ::S(speed) w	  [list ActiveGUI $w]

    grid $w.message -in $w.ctrl -row 98 -sticky ew -pady 5
    grid $w.message.e -sticky nsew
    grid $w.speed -in $w.ctrl -row 99 -sticky ew -pady {0 5}
    pack $w.speed.scale -fill both -expand 1
    grid $w.about -in $w.ctrl -row 100 -sticky ew
    bind $w.reset <3> {set S(mode) -1}		;# Debugging

    ## See Code / Dismiss buttons hack!
    set btns [addSeeDismiss $w.ctrl.buttons $w]
    grid [ttk::separator $w.ctrl.sep] -sticky ew -pady 4
    set i 0
    foreach b [winfo children $btns] {
	if {[winfo class $b] eq "TButton"} {
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    grid columnconfigure $w2 1 -weight 1
}

# Map or unmap the ctrl window
proc ShowCtrl {w} {
    if {[winfo ismapped $w.ctrl]} {
	pack forget $w.ctrl
	$w.show config -text "»"
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text "»"
    }
}

proc DrawAll {w} {
    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {







|


|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    grid columnconfigure $w2 1 -weight 1
}

# Map or unmap the ctrl window
proc ShowCtrl {w} {
    if {[winfo ismapped $w.ctrl]} {
	pack forget $w.ctrl
	$w.show config -text "\u00bb"
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text "\u00ab"
    }
}

proc DrawAll {w} {
    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    set color $::C(0)
    set xy {579 119}
    $w.c create text $xy -text "START HERE!" -fill $color -anchor w \
	    -tag I0 -font {{Times Roman} 12 italic bold}
    set xy {719 119 763 119}
    $w.c create line $xy -tag I0 -fill $color -width 5 -arrow last \
	    -arrowshape {18 18 5}
    $w.c bind I0 <Button-1> Start
}
proc Move0 {w {step {}}} {
    set step [GetStep 0 $step]

    if {$::S(mode) > $::MSTART} {		;# Start the ball rolling
	MoveAbs $w I0 {-100 -100}		;# Hide the banner
	return 2







|







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    set color $::C(0)
    set xy {579 119}
    $w.c create text $xy -text "START HERE!" -fill $color -anchor w \
	    -tag I0 -font {{Times Roman} 12 italic bold}
    set xy {719 119 763 119}
    $w.c create line $xy -tag I0 -fill $color -width 5 -arrow last \
	    -arrowshape {18 18 5}
    $w.c bind I0 <1> Start
}
proc Move0 {w {step {}}} {
    set step [GetStep 0 $step]

    if {$::S(mode) > $::MSTART} {		;# Start the ball rolling
	MoveAbs $w I0 {-100 -100}		;# Hide the banner
	return 2
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    set xy {844 133 800 133 800 346 820 346 820 168 844 168 844 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}
    set xy {771 133 685 133 685 168 751 168 751 346 771 346 771 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}

    set xy [box 812 122 9]
    $w.c create oval $xy -tag I1 -fill $color2 -outline {}
    $w.c bind I1 <Button-1> Start
}
proc Move1 {w {step {}}} {
    set step [GetStep 1 $step]
    set pos {
	{807 122} {802 122} {797 123} {793 124} {789 129} {785 153}
	{785 203} {785 278 x} {785 367} {810 392} {816 438} {821 503}
	{824 585 y} {838 587} {848 593} {857 601} {-100 -100}







|







368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    set xy {844 133 800 133 800 346 820 346 820 168 844 168 844 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}
    set xy {771 133 685 133 685 168 751 168 751 346 771 346 771 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}

    set xy [box 812 122 9]
    $w.c create oval $xy -tag I1 -fill $color2 -outline {}
    $w.c bind I1 <1> Start
}
proc Move1 {w {step {}}} {
    set step [GetStep 1 $step]
    set pos {
	{807 122} {802 122} {797 123} {793 124} {789 129} {785 153}
	{785 203} {785 278 x} {785 367} {810 392} {816 438} {821 503}
	{824 585 y} {838 587} {848 593} {857 601} {-100 -100}
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
    global S
    set step [GetStep 26 $step]

    if {$step >= 3} {
	$w.c delete I24 I26
	$w.c create text 430 755 -anchor s -tag I26 \
		-text "click to continue" -font {{Times Roman} 24 bold}
	bind $w.c <Button-1> [list Reset $w]
	return 4
    }

    $w.c scale I24 {*}[Centroid $w I24] .8 .8
    $w.c move I24 0 60
    $w.c itemconfig I24t -font [list {Times Roman} [expr {30 - 6*$step}] bold]
    return 1







|







1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
    global S
    set step [GetStep 26 $step]

    if {$step >= 3} {
	$w.c delete I24 I26
	$w.c create text 430 755 -anchor s -tag I26 \
		-text "click to continue" -font {{Times Roman} 24 bold}
	bind $w.c <1> [list Reset $w]
	return 4
    }

    $w.c scale I24 {*}[Centroid $w I24] .8 .8
    $w.c move I24 0 60
    $w.c itemconfig I24t -font [list {Times Roman} [expr {30 - 6*$step}] bold]
    return 1
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685

    return [list $xx $yy]
}

proc Reset {w} {
    global S
    DrawAll $w
    bind $w.c <Button-1> {}
    set S(mode) $::MSTART
    set S(active) 0
}

# Each Move## keeps its state info in STEP, this retrieves and increments it
proc GetStep {who step} {
    global STEP







|







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685

    return [list $xx $yy]
}

proc Reset {w} {
    global S
    DrawAll $w
    bind $w.c <1> {}
    set S(mode) $::MSTART
    set S(active) 0
}

# Each Move## keeps its state info in STEP, this retrieves and increments it
proc GetStep {who step} {
    global STEP

Changes to library/demos/image2.tcl.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#
# Arguments:
# w -			Name of the toplevel window of the demo.

proc selectAndLoadDir w {
    global dirName
    set dir [tk_chooseDirectory -initialdir $dirName -parent $w -mustexist 1]
    if {$dir ne ""} {
	set dirName $dir
	loadDir $w
    }
}

# loadImage --
# Given the name of the toplevel window of the demo and the mouse







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#
# Arguments:
# w -			Name of the toplevel window of the demo.

proc selectAndLoadDir w {
    global dirName
    set dir [tk_chooseDirectory -initialdir $dirName -parent $w -mustexist 1]
    if {[string length $dir] != 0} {
	set dirName $dir
	loadDir $w
    }
}

# loadImage --
# Given the name of the toplevel window of the demo and the mouse
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
	-command "selectAndLoadDir $w"
bind $w.dir.e <Return> "loadDir $w"
pack $w.dir.e -side left -fill both -padx 2m     -pady 2m -expand true
pack $w.dir.b -side left -fill y    -padx {0 2m} -pady 2m
labelframe $w.f -text "File:" -padx 2m -pady 2m

listbox $w.f.list -width 20 -height 10 -yscrollcommand "$w.f.scroll set"
ttk::scrollbar $w.f.scroll -command "$w.f.list yview"
pack $w.f.list $w.f.scroll -side left -fill y -expand 1
$w.f.list insert 0 earth.gif earthris.gif teapot.ppm
bind $w.f.list <Double-Button-1> "loadImage $w %x %y"

catch {image delete image2a}
image create photo image2a
labelframe $w.image -text "Image:"
label $w.image.image -image image2a
pack $w.image.image -padx 2m -pady 2m

grid $w.dir -        -sticky ew -padx 1m -pady 1m -in $w.mid
grid $w.f   $w.image -sticky nw -padx 1m -pady 1m -in $w.mid
grid columnconfigure $w.mid 1 -weight 1







|


|










88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
	-command "selectAndLoadDir $w"
bind $w.dir.e <Return> "loadDir $w"
pack $w.dir.e -side left -fill both -padx 2m     -pady 2m -expand true
pack $w.dir.b -side left -fill y    -padx {0 2m} -pady 2m
labelframe $w.f -text "File:" -padx 2m -pady 2m

listbox $w.f.list -width 20 -height 10 -yscrollcommand "$w.f.scroll set"
scrollbar $w.f.scroll -command "$w.f.list yview"
pack $w.f.list $w.f.scroll -side left -fill y -expand 1
$w.f.list insert 0 earth.gif earthris.gif teapot.ppm
bind $w.f.list <Double-1> "loadImage $w %x %y"

catch {image delete image2a}
image create photo image2a
labelframe $w.image -text "Image:"
label $w.image.image -image image2a
pack $w.image.image -padx 2m -pady 2m

grid $w.dir -        -sticky ew -padx 1m -pady 1m -in $w.mid
grid $w.f   $w.image -sticky nw -padx 1m -pady 1m -in $w.mid
grid columnconfigure $w.mid 1 -weight 1

Deleted library/demos/images/earthmenu.png.

cannot compute difference between binary files

Added library/demos/images/face.xbm.



























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#define face_width 108
#define face_height 144
#define face_x_hot 48
#define face_y_hot 80
static char face_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09,
   0x20, 0x80, 0x24, 0x05, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88,
   0x24, 0x20, 0x80, 0x24, 0x00, 0x00, 0x00, 0x10, 0x80, 0x04, 0x00, 0x01,
   0x00, 0x01, 0x40, 0x0a, 0x09, 0x00, 0x92, 0x04, 0x80, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x10, 0x40, 0x12, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x84,
   0x24, 0x40, 0x22, 0xa8, 0x02, 0x14, 0x84, 0x92, 0x40, 0x42, 0x12, 0x04,
   0x10, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52, 0x11, 0x00, 0x12, 0x00,
   0x40, 0x02, 0x00, 0x20, 0x00, 0x08, 0x00, 0xaa, 0x02, 0x54, 0x85, 0x24,
   0x00, 0x10, 0x12, 0x00, 0x00, 0x81, 0x44, 0x00, 0x90, 0x5a, 0x00, 0xea,
   0x1b, 0x00, 0x80, 0x40, 0x40, 0x02, 0x00, 0x08, 0x00, 0x20, 0xa2, 0x05,
   0x8a, 0xb4, 0x6e, 0x45, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10, 0x02,
   0xa8, 0x92, 0x00, 0xda, 0x5f, 0x10, 0x00, 0x10, 0xa1, 0x04, 0x20, 0x41,
   0x02, 0x00, 0x5a, 0x25, 0xa0, 0xff, 0xfb, 0x05, 0x41, 0x02, 0x04, 0x00,
   0x00, 0x08, 0x40, 0x80, 0xec, 0x9b, 0xec, 0xfe, 0x7f, 0x01, 0x04, 0x20,
   0x90, 0x02, 0x04, 0x00, 0x08, 0x20, 0xfb, 0x2e, 0xf5, 0xff, 0xff, 0x57,
   0x00, 0x04, 0x02, 0x00, 0x00, 0x20, 0x01, 0xc1, 0x6e, 0xab, 0xfa, 0xff,
   0xff, 0x05, 0x90, 0x20, 0x48, 0x02, 0x00, 0x04, 0x20, 0xa8, 0xdf, 0xb5,
   0xfe, 0xff, 0xff, 0x0b, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x04, 0xe0,
   0xbb, 0xef, 0xff, 0xff, 0x7f, 0x01, 0x00, 0x04, 0x48, 0x02, 0x00, 0x20,
   0x80, 0xf4, 0x6f, 0xfb, 0xff, 0xff, 0xff, 0x20, 0x90, 0x40, 0x02, 0x00,
   0x00, 0x04, 0x08, 0xb8, 0xf6, 0xff, 0xff, 0xdf, 0xbe, 0x12, 0x45, 0x10,
   0x90, 0x04, 0x90, 0x00, 0x22, 0xfa, 0xff, 0xff, 0xff, 0xbb, 0xd7, 0xe9,
   0x3a, 0x02, 0x02, 0x00, 0x04, 0x90, 0x80, 0xfe, 0xdf, 0xf6, 0xb7, 0xef,
   0xbe, 0x56, 0x57, 0x40, 0x48, 0x09, 0x00, 0x04, 0x00, 0xfa, 0xf5, 0xdf,
   0xed, 0x5a, 0xd5, 0xea, 0xbd, 0x09, 0x00, 0x00, 0x40, 0x00, 0x92, 0xfe,
   0xbf, 0x7d, 0xb7, 0x6a, 0x55, 0xbf, 0xf7, 0x02, 0x11, 0x01, 0x00, 0x91,
   0x00, 0xff, 0xff, 0xaf, 0x55, 0x55, 0x5b, 0xeb, 0xef, 0x22, 0x04, 0x04,
   0x04, 0x00, 0xa4, 0xff, 0xf7, 0xad, 0xaa, 0xaa, 0xaa, 0xbe, 0xfe, 0x03,
   0x20, 0x00, 0x10, 0x44, 0x80, 0xff, 0x7f, 0x55, 0x12, 0x91, 0x2a, 0xeb,
   0xbf, 0x0b, 0x82, 0x02, 0x00, 0x00, 0xd1, 0x7f, 0xdf, 0xa2, 0xa4, 0x54,
   0x55, 0xfd, 0xfd, 0x47, 0x08, 0x08, 0x00, 0x21, 0xe4, 0xff, 0x37, 0x11,
   0x09, 0xa5, 0xaa, 0xb6, 0xff, 0x0d, 0x80, 0x00, 0x00, 0x04, 0xd0, 0xff,
   0x4f, 0x44, 0x20, 0x48, 0x55, 0xfb, 0xff, 0x27, 0x11, 0x02, 0x40, 0x40,
   0xe2, 0xfb, 0x15, 0x11, 0x4a, 0x55, 0x4a, 0x7d, 0xf7, 0x0f, 0x00, 0x00,
   0x04, 0x08, 0xf8, 0xdf, 0x52, 0x44, 0x01, 0x52, 0xb5, 0xfa, 0xff, 0x0f,
   0x49, 0x02, 0x00, 0x02, 0xe9, 0xf6, 0x0a, 0x11, 0xa4, 0x88, 0x4a, 0x6d,
   0xff, 0x5f, 0x00, 0x00, 0x10, 0x20, 0xf0, 0x2f, 0x21, 0x44, 0x10, 0x52,
   0xb5, 0xfa, 0xff, 0x0f, 0x44, 0x04, 0x80, 0x08, 0xf8, 0xab, 0x8a, 0x00,
   0x81, 0xa4, 0xd4, 0xd6, 0xfe, 0x2f, 0x00, 0x00, 0x04, 0x40, 0xb5, 0x2d,
   0x21, 0x08, 0x04, 0x90, 0xaa, 0xfa, 0xff, 0x1f, 0x11, 0x01, 0x00, 0x04,
   0xf0, 0x57, 0x0a, 0x22, 0x40, 0x4a, 0xda, 0x5e, 0xfb, 0x1f, 0x40, 0x00,
   0x40, 0x20, 0xba, 0x95, 0x90, 0x00, 0x01, 0xa0, 0xaa, 0xea, 0xff, 0x5f,
   0x02, 0x02, 0x00, 0x01, 0xe8, 0x57, 0x05, 0x00, 0x00, 0x12, 0xd5, 0xfe,
   0xfd, 0x1f, 0x48, 0x00, 0x04, 0x48, 0x7a, 0x95, 0x08, 0x02, 0x10, 0x40,
   0xaa, 0x55, 0xf7, 0x1f, 0x00, 0x09, 0x20, 0x00, 0xf8, 0x57, 0x22, 0x10,
   0x00, 0x28, 0xa9, 0xfa, 0xff, 0x5f, 0x02, 0x00, 0x00, 0x49, 0xdd, 0x29,
   0x01, 0x00, 0x80, 0x80, 0xaa, 0xd7, 0xff, 0x0f, 0x10, 0x00, 0x08, 0x00,
   0xf8, 0x96, 0x08, 0x00, 0x00, 0x20, 0x54, 0xfa, 0xee, 0x3f, 0x81, 0x04,
   0x40, 0x24, 0xfe, 0x55, 0x82, 0x00, 0x00, 0x82, 0xd2, 0xad, 0xff, 0x0f,
   0x08, 0x00, 0x04, 0x80, 0x6c, 0x97, 0x00, 0x00, 0x02, 0x20, 0xa9, 0xf6,
   0xdf, 0x5f, 0x00, 0x02, 0x20, 0x09, 0xfa, 0x49, 0x12, 0x00, 0x20, 0x84,
   0x54, 0xdb, 0xfe, 0x1f, 0x91, 0x00, 0x00, 0x00, 0xf8, 0x2b, 0x00, 0x20,
   0x00, 0x40, 0xa4, 0xf6, 0xbb, 0x1f, 0x04, 0x00, 0x44, 0x92, 0x7e, 0x95,
   0x02, 0x00, 0x00, 0x89, 0xaa, 0xdd, 0xff, 0x1f, 0x20, 0x09, 0x10, 0x00,
   0xf4, 0x57, 0x20, 0x01, 0x08, 0x20, 0xa9, 0x76, 0xff, 0x5f, 0x02, 0x00,
   0x00, 0x21, 0xfc, 0x4a, 0x05, 0x00, 0x01, 0x80, 0x54, 0xdb, 0xff, 0x1e,
   0x08, 0x02, 0x04, 0x08, 0xf9, 0x2b, 0x00, 0x00, 0x40, 0x28, 0xd2, 0xf6,
   0xff, 0xbf, 0x80, 0x00, 0x90, 0x00, 0xbc, 0x92, 0x08, 0x10, 0x00, 0x82,
   0x54, 0xdb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x44, 0xf9, 0x55, 0x02, 0x01,
   0x00, 0x20, 0xaa, 0xbd, 0xfd, 0x3f, 0x08, 0x04, 0x04, 0x10, 0xf4, 0x2a,
   0x01, 0x00, 0x22, 0x80, 0xd4, 0xf6, 0xff, 0x5f, 0x82, 0x00, 0x40, 0x02,
   0xf8, 0x55, 0x20, 0x00, 0x00, 0x50, 0x6a, 0xdf, 0xfe, 0x3f, 0x00, 0x00,
   0x00, 0x48, 0xe9, 0x4a, 0x05, 0x08, 0x00, 0xa5, 0xd5, 0xf5, 0xff, 0x3f,
   0x10, 0x01, 0x10, 0x01, 0xb0, 0xab, 0x92, 0x02, 0x40, 0xf8, 0xbf, 0xde,
   0xfe, 0x5f, 0x02, 0x04, 0x04, 0x48, 0xfa, 0xd4, 0x6f, 0x20, 0x84, 0xef,
   0xff, 0xfb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xed, 0xbf, 0x0b,
   0xa1, 0x7e, 0xff, 0xbf, 0xfd, 0x5f, 0x04, 0x01, 0x20, 0x49, 0xd2, 0xfb,
   0xfe, 0x55, 0xd4, 0xff, 0xff, 0xf6, 0xff, 0x07, 0x00, 0x04, 0x00, 0x00,
   0xc0, 0xaa, 0xfb, 0x2b, 0xa2, 0xfe, 0xff, 0xdf, 0xee, 0x1f, 0x91, 0x00,
   0x82, 0xa4, 0xa4, 0xf5, 0xff, 0x57, 0xd5, 0xff, 0xbf, 0xfd, 0xff, 0x4d,
   0x00, 0x00, 0x20, 0x00, 0x88, 0x5b, 0xff, 0x2f, 0x69, 0xff, 0xff, 0xdb,
   0xfe, 0x1f, 0x24, 0x02, 0x00, 0x49, 0xa2, 0xd6, 0xff, 0x5f, 0xea, 0xff,
   0x7f, 0x7f, 0x7f, 0x0d, 0x00, 0x00, 0x10, 0x00, 0x40, 0xab, 0xf7, 0xbb,
   0xf0, 0xdf, 0xff, 0xd5, 0xff, 0xbf, 0x82, 0x04, 0x42, 0x24, 0x91, 0xd5,
   0xaa, 0xae, 0xd4, 0xaa, 0x52, 0x7b, 0xff, 0x15, 0x08, 0x00, 0x00, 0x01,
   0x04, 0x55, 0xd5, 0x55, 0x70, 0x5b, 0x75, 0xdd, 0xdf, 0x1f, 0x40, 0x00,
   0x08, 0x48, 0xa0, 0x4a, 0xa9, 0x56, 0xea, 0x56, 0xad, 0x6a, 0x7d, 0x9b,
   0x04, 0x01, 0x00, 0x02, 0x42, 0x2a, 0xd5, 0xaa, 0xa8, 0xaa, 0xaa, 0xfa,
   0xdf, 0x2f, 0x10, 0x04, 0x22, 0x48, 0x08, 0x45, 0x2a, 0x15, 0x68, 0x55,
   0x55, 0xd7, 0x76, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x40, 0x2a, 0x80, 0xa0,
   0xb2, 0x09, 0x48, 0xb9, 0xdf, 0x17, 0x22, 0x01, 0x00, 0x24, 0x45, 0x8a,
   0x24, 0x4a, 0x54, 0x51, 0x91, 0xf6, 0x6e, 0x4b, 0x00, 0x04, 0x90, 0x00,
   0x80, 0x52, 0x00, 0x20, 0x69, 0x05, 0xa4, 0xaa, 0xff, 0x1e, 0x48, 0x00,
   0x02, 0x92, 0x08, 0x05, 0x81, 0x94, 0xd4, 0x92, 0x40, 0xfd, 0xb6, 0x8b,
   0x00, 0x01, 0x40, 0x00, 0x82, 0x54, 0x00, 0x48, 0x68, 0x05, 0x90, 0xa4,
   0xef, 0x06, 0x24, 0x00, 0x08, 0x12, 0x10, 0x05, 0x00, 0x10, 0xb5, 0x01,
   0x42, 0xfb, 0xbf, 0x43, 0x00, 0x09, 0x00, 0x40, 0x81, 0xa8, 0x08, 0x4a,
   0xaa, 0x96, 0x90, 0xac, 0x6d, 0x15, 0x22, 0x00, 0x20, 0x09, 0x04, 0x15,
   0x80, 0x28, 0xdc, 0x01, 0x24, 0xfb, 0xbf, 0x01, 0x80, 0x04, 0x09, 0x00,
   0x40, 0x48, 0x02, 0x45, 0xb2, 0x2e, 0x41, 0x6d, 0xef, 0x05, 0x11, 0x00,
   0x40, 0x52, 0x02, 0x15, 0x29, 0x2a, 0xac, 0x42, 0x54, 0xfb, 0x3b, 0x51,
   0x84, 0x00, 0x08, 0x00, 0x20, 0x54, 0x80, 0x05, 0xb5, 0x3d, 0xa2, 0xb6,
   0xdf, 0x00, 0x20, 0x04, 0x20, 0x49, 0x89, 0xa8, 0x6a, 0x29, 0xac, 0xd6,
   0x54, 0xff, 0x3f, 0x84, 0x00, 0x01, 0x04, 0x10, 0x00, 0x94, 0xa8, 0x56,
   0xda, 0x5f, 0xab, 0xd5, 0x1e, 0x10, 0x48, 0x00, 0x90, 0x82, 0x48, 0xa8,
   0xb2, 0xac, 0xfd, 0x55, 0xd5, 0xfe, 0x9f, 0x80, 0x00, 0x0a, 0x02, 0x08,
   0x02, 0x55, 0x5a, 0x75, 0xff, 0xaf, 0xb6, 0xf7, 0x2d, 0x12, 0x92, 0x00,
   0x10, 0x20, 0x10, 0xa8, 0x54, 0xd5, 0xbf, 0x5d, 0xad, 0xdd, 0x0f, 0x00,
   0x00, 0x04, 0x40, 0x09, 0x84, 0xa8, 0xaa, 0x5a, 0xed, 0xeb, 0x6a, 0xff,
   0x9f, 0xa4, 0x24, 0x01, 0x02, 0xa0, 0x20, 0x50, 0x55, 0xd5, 0xbe, 0xae,
   0xad, 0xfd, 0x16, 0x00, 0x10, 0x04, 0x20, 0x0a, 0x08, 0xb4, 0xaa, 0x95,
   0xaa, 0x7b, 0xb7, 0xdb, 0x5f, 0x92, 0x04, 0x01, 0x84, 0x20, 0x21, 0x51,
   0xd5, 0x2a, 0xa9, 0xee, 0xd5, 0xfe, 0x0d, 0x00, 0x20, 0x04, 0x10, 0x00,
   0x08, 0x50, 0xe9, 0xd7, 0xd4, 0xfb, 0xb5, 0xff, 0x9f, 0x24, 0x09, 0x01,
   0x42, 0x4a, 0xa2, 0x64, 0xd5, 0x55, 0x7b, 0x7f, 0xda, 0x7d, 0x4f, 0x00,
   0x20, 0x04, 0x00, 0x80, 0x00, 0xa0, 0x2a, 0x13, 0x84, 0x6a, 0x55, 0xff,
   0x1d, 0x48, 0x8a, 0x00, 0x94, 0x24, 0x8a, 0xc8, 0xaa, 0x42, 0x20, 0x5d,
   0xf5, 0xff, 0x5f, 0x01, 0x00, 0x02, 0x01, 0x00, 0x20, 0xa2, 0x4a, 0x1a,
   0x82, 0x56, 0xda, 0xbd, 0x3f, 0x92, 0x92, 0x00, 0x90, 0x92, 0x00, 0x40,
   0x95, 0x6a, 0xf4, 0x55, 0x6d, 0xff, 0xd6, 0x00, 0x00, 0x0a, 0x04, 0x20,
   0x14, 0x49, 0x4b, 0xaa, 0xaa, 0x56, 0xf5, 0xff, 0xbf, 0xab, 0xa4, 0x00,
   0x20, 0x89, 0x40, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xde, 0xbf, 0xeb, 0x03,
   0x00, 0x02, 0x04, 0x02, 0x0a, 0x10, 0x2b, 0x2a, 0x55, 0x5b, 0xf5, 0xff,
   0xd7, 0x2f, 0x92, 0x00, 0x10, 0x28, 0x21, 0x01, 0x56, 0x95, 0xa0, 0x56,
   0xdf, 0xef, 0xea, 0x87, 0x40, 0x0a, 0x42, 0x41, 0x00, 0x90, 0xaa, 0x52,
   0xb6, 0xad, 0xfa, 0xff, 0xd5, 0x2f, 0x14, 0x00, 0x00, 0x04, 0x95, 0x04,
   0xaa, 0xac, 0x55, 0x6b, 0xff, 0xb7, 0xea, 0x9f, 0x40, 0x02, 0x28, 0x51,
   0x00, 0x40, 0x58, 0xd5, 0xda, 0xd6, 0x6e, 0x7f, 0xf9, 0x3f, 0x12, 0x04,
   0x02, 0x04, 0x49, 0x25, 0x55, 0xaa, 0x77, 0xab, 0xff, 0x2b, 0xfd, 0x3f,
   0x48, 0x01, 0x20, 0x41, 0x00, 0x00, 0x58, 0xa9, 0xda, 0xea, 0xfd, 0xaf,
   0xfa, 0xff, 0x02, 0x04, 0x08, 0x14, 0x29, 0x49, 0x52, 0x55, 0x55, 0x55,
   0xff, 0x8d, 0xfe, 0x3f, 0xa8, 0x00, 0x02, 0x41, 0x00, 0x02, 0xa0, 0xa2,
   0xaa, 0xea, 0xff, 0x53, 0xfd, 0xff, 0x02, 0x04, 0x50, 0x04, 0x25, 0xa8,
   0x54, 0x49, 0x52, 0xb5, 0xbf, 0x8a, 0xfe, 0xff, 0xa9, 0x08, 0x04, 0x50,
   0x80, 0x02, 0xa1, 0x2a, 0x95, 0xea, 0xff, 0xa1, 0xff, 0xff, 0x03, 0x02,
   0x90, 0x02, 0x09, 0x08, 0x44, 0x49, 0x52, 0xbd, 0x7f, 0xca, 0xff, 0xff,
   0x2b, 0x09, 0x04, 0x48, 0x40, 0x82, 0x90, 0x56, 0xa9, 0xf6, 0xbf, 0xd0,
   0xff, 0xff, 0x47, 0x00, 0x50, 0x02, 0x15, 0x11, 0x40, 0x95, 0xaa, 0xfd,
   0x2f, 0xe9, 0xff, 0xff, 0x8f, 0x0a, 0x84, 0x50, 0x40, 0x84, 0x14, 0xaa,
   0x6a, 0xff, 0x5f, 0xf2, 0xff, 0xff, 0x7f, 0x00, 0x10, 0x02, 0x09, 0x10,
   0x40, 0x7d, 0xf7, 0xff, 0x0b, 0xfc, 0xff, 0xff, 0xaf, 0x02, 0x84, 0x50,
   0x42, 0x85, 0x12, 0xd0, 0xdd, 0xff, 0xa7, 0xf2, 0xff, 0xff, 0xff, 0x04,
   0x00, 0x0a, 0x08, 0x10, 0x48, 0xf8, 0xff, 0xff, 0x0a, 0xfe, 0xff, 0xff,
   0x7f, 0x03, 0xa4, 0x80, 0xa2, 0x8a, 0x02, 0x68, 0xff, 0xff, 0x52, 0xfd,
   0xff, 0xff, 0xff, 0x07, 0x00, 0x2a, 0x08, 0x20, 0x28, 0xdc, 0xff, 0x5f,
   0x05, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x92, 0x40, 0x22, 0x09, 0x02, 0xea,
   0xfb, 0xaf, 0x48, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x12, 0x81, 0xa0,
   0x48, 0x9c, 0x6e, 0x93, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa8, 0x40,
   0x28, 0x0a, 0x02, 0x74, 0xb5, 0x45, 0x81, 0xff, 0xff, 0xff, 0xff, 0x0f,
   0x02, 0x0a, 0x81, 0x20, 0x08, 0xae, 0xaa, 0x90, 0xe8, 0xff, 0xff, 0xff,
   0xff, 0x0f, 0x90, 0x40, 0x28, 0x88, 0x12, 0x58, 0x15, 0x50, 0xd0, 0xff,
   0xff, 0xff, 0xff, 0x0f, 0x44, 0x0a, 0x41, 0x21, 0x08, 0xae, 0x04, 0x14,
   0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, 0x14, 0x88, 0x04, 0xba,
   0x02, 0x28, 0xe8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x15, 0x41, 0x21,
   0x05, 0xad, 0x00, 0x05, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40,
   0x24, 0x8a, 0x0e, 0x36, 0x00, 0x0a, 0xf4, 0xff, 0xff, 0xff, 0xff, 0x0f,
   0x42, 0x25, 0x90, 0xd0, 0x8b, 0xc2, 0x41, 0x05, 0xfc, 0xff, 0xff, 0xff,
   0xff, 0x0f, 0x10, 0x08, 0x05, 0xe8, 0x8e, 0x58, 0x80, 0x02, 0xfa, 0xff,
   0xff, 0xff, 0xff, 0x0f, 0x4a, 0x20, 0xa8, 0xba, 0x0b, 0x2b, 0x51, 0x01,
   0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x8a, 0x02, 0xe8, 0xaf, 0x84,
   0x90, 0x04, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x52, 0x21, 0x54, 0xbf,
   0x1f, 0x15, 0xa5, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x08,
   0x01, 0xfa, 0xb6, 0xa4, 0x52, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
   0x4a, 0xa2, 0x54, 0xef, 0x5f, 0x4b, 0xa4, 0x80, 0xff, 0xff, 0xff, 0xff,
   0xff, 0x0f, 0x80, 0x10, 0x82, 0xfe, 0xbf, 0x92, 0x52, 0x42, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x0f, 0x12, 0x42, 0xa8, 0xbf, 0x1f, 0x24, 0x80, 0xa0,
   0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, 0x8a, 0xf7, 0x37, 0x80,
   0x52, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x82, 0xe0, 0xff,
   0x1f, 0x00, 0x20, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28,
   0xca, 0xff, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
   0x10, 0x42, 0xf0, 0xfd, 0x1b, 0x00, 0x50, 0xf0, 0xff, 0xff, 0xff, 0xff,
   0xff, 0x0f, 0xa4, 0x10, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x0f, 0x00, 0x22, 0xf8, 0xff, 0x0e, 0x00, 0x00, 0xf0,
   0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xaa, 0x88, 0xe2, 0xff, 0x0f, 0x10,
   0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x25, 0xfa, 0xff,
   0x0f, 0x01, 0x11, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xfb,
   0xfb, 0xff, 0x7f, 0x5d, 0xd5, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f};

Deleted library/demos/images/ouster.png.

cannot compute difference between binary files

Changes to library/demos/items.tcl.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
catch {destroy $w}
toplevel $w
wm title $w "Canvas Item Demonstration"
wm iconname $w "Items"
positionWindow $w
set c $w.frame.c

label $w.msg -font $font -wraplength 5i -justify left -text "This window contains a canvas widget with examples of the various kinds of items supported by canvases.  The following operations are supported:\n  Left-Button drag:\tmoves item under pointer.\n  Middle-Button drag:\trepositions view.\n  Right-Button drag:\tstrokes out area.\n  Ctrl+f:\t\tprints items under area."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame
pack $w.frame -side top -fill both -expand yes

canvas $c -scrollregion {0c 0c 30c 24c} -width 15c -height 10c \
	-relief sunken -borderwidth 2 \
	-xscrollcommand "$w.frame.hscroll set" \
	-yscrollcommand "$w.frame.vscroll set"
ttk::scrollbar $w.frame.vscroll -command "$c yview"
ttk::scrollbar $w.frame.hscroll -orient horiz -command "$c xview"

grid $c -in $w.frame \
    -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.vscroll \
    -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.hscroll \
    -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news







|













|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
catch {destroy $w}
toplevel $w
wm title $w "Canvas Item Demonstration"
wm iconname $w "Items"
positionWindow $w
set c $w.frame.c

label $w.msg -font $font -wraplength 5i -justify left -text "This window contains a canvas widget with examples of the various kinds of items supported by canvases.  The following operations are supported:\n  Button-1 drag:\tmoves item under pointer.\n  Button-2 drag:\trepositions view.\n  Button-3 drag:\tstrokes out area.\n  Ctrl+f:\t\tprints items under area."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame
pack $w.frame -side top -fill both -expand yes

canvas $c -scrollregion {0c 0c 30c 24c} -width 15c -height 10c \
	-relief sunken -borderwidth 2 \
	-xscrollcommand "$w.frame.hscroll set" \
	-yscrollcommand "$w.frame.vscroll set"
scrollbar $w.frame.vscroll -command "$c yview"
scrollbar $w.frame.hscroll -orient horiz -command "$c xview"

grid $c -in $w.frame \
    -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.vscroll \
    -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.hscroll \
    -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	16.5c 4.5c 13.5c 7.5c 12c 6c -smooth on -width 3m -cap round \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $red -tags item

$c create text 25c .2c -text Polygons -anchor n
$c create polygon 21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c \
	24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c -fill $green \
	-outline {} -width 4 -tags item
$c create polygon 25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c \
	29c 1c 29c 4c 29c 4c -fill $red -outline {} -smooth on -tags item
$c create polygon 22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c \
	28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $blue -outline {} -tags item

$c create text 5c 8.2c -text Rectangles -anchor n
$c create rectangle 1c 9.5c 4c 12.5c -outline $red -width 3m -tags item
$c create rectangle 0.5c 13.5c 4.5c 15.5c -fill $green -tags item
$c create rectangle 6c 10c 9c 15c -outline {} \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $blue -tags item







|

|



|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	16.5c 4.5c 13.5c 7.5c 12c 6c -smooth on -width 3m -cap round \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $red -tags item

$c create text 25c .2c -text Polygons -anchor n
$c create polygon 21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c \
	24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c -fill $green \
	-outline black -width 4 -tags item
$c create polygon 25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c \
	29c 1c 29c 4c 29c 4c -fill $red -smooth on -tags item
$c create polygon 22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c \
	28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-outline black -tags item

$c create text 5c 8.2c -text Rectangles -anchor n
$c create rectangle 1c 9.5c 4c 12.5c -outline $red -width 3m -tags item
$c create rectangle 0.5c 13.5c 4.5c 15.5c -fill $green -tags item
$c create rectangle 6c 10c 9c 15c -outline {} \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $blue -tags item
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
$c create text 22.5c 9c -anchor n -font $font1 -width 4c \
	-text "A short string of text, word-wrapped, justified left, and anchored north (at the top).  The rectangles show the anchor points for each piece of text." -tags item
$c create rectangle 25.4c 10.9c 25.6c 11.1c
$c create text 25.5c 11c -anchor w -font $font1 -fill $blue \
	-text "Several lines,\n each centered\nindividually,\nand all anchored\nat the left edge." \
	-justify center -tags item
$c create rectangle 24.9c 13.9c 25.1c 14.1c
catch {
$c create text 25c 14c -font $font2 -anchor c -fill $red -angle 15 \
	-text "Angled characters" -tags item
}

$c create text 5c 16.2c -text Arcs -anchor n
$c create arc 0.5c 17c 7c 20c -fill $green -outline black \
	-start 45 -extent 270 -style pieslice -tags item
$c create arc 6.5c 17c 9.5c 20c -width 4m -style arc \
	-outline $blue -start -135 -extent 270 -tags item \
	-outlinestipple @[file join $tk_demoDirectory images gray25.xbm]
$c create arc 0.5c 20c 9.5c 24c -width 4m -style pieslice \
	-fill {} -outline $red -start 225 -extent -90 -tags item
$c create arc 5.5c 20.5c 9.5c 23.5c -width 4m -style chord \
	-fill $blue -outline {} -start 45 -extent 270  -tags item

$c create text 15c 16.2c -text "Bitmaps and Images" -anchor n
catch {
image create photo items.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]
image create photo items.ousterhout.active -format "png -alpha 0.5" \
    -file [file join $tk_demoDirectory images ouster.png]
$c create image 13c 20c -tags item -image items.ousterhout \
    -activeimage items.ousterhout.active
}
$c create bitmap 17c 18.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images noletter.xbm]
$c create bitmap 17c 21.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images letters.xbm]

$c create text 25c 16.2c -text Windows -anchor n
button $c.button -text "Press Me" -command "butPress $c $red"
$c create window 21c 18c -window $c.button -anchor nw -tags item
entry $c.entry -width 20 -relief sunken
$c.entry insert end "Edit this text"
$c create window 21c 21c -window $c.entry -anchor nw -tags item
scale $c.scale -from 0 -to 100 -length 6c -sliderlength .4c \
	-width .5c -tickinterval 0
$c create window 28.5c 17.5c -window $c.scale -anchor n -tags item
$c create text 21c 17.9c -text Button: -anchor sw
$c create text 21c 20.9c -text Entry: -anchor sw
$c create text 28.5c 17.4c -text Scale: -anchor s

# Set up event bindings for canvas:

$c bind item <Enter> "itemEnter $c"
$c bind item <Leave> "itemLeave $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-2> "itemMark $c %x %y"
    bind $c <B2-Motion> "itemStroke $c %x %y"
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
} else {
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
    bind $c <Button-3> "itemMark $c %x %y"
    bind $c <B3-Motion> "itemStroke $c %x %y"
}
bind $c <<NextChar>> "itemsUnderArea $c"
bind $c <Button-1> "itemStartDrag $c %x %y"
bind $c <B1-Motion> "itemDrag $c %x %y"

# Utility procedures for highlighting the item under the pointer:

proc itemEnter {c} {
    global restoreCmd

    if {[winfo depth $c] == 1} {
	set restoreCmd {}
	return
    }
    set type [$c type current]
    if {$type == "window" || $type == "image"} {
	set restoreCmd {}
	return

    } elseif {$type == "bitmap"} {
	set bg [lindex [$c itemconf current -background] 4]
	set restoreCmd [list $c itemconfig current -background $bg]
	$c itemconfig current -background SteelBlue2
	return
    } elseif {$type == "image"} {
	set restoreCmd [list $c itemconfig current -state normal]
	$c itemconfig current -state active
	return
    }
    set fill [lindex [$c itemconfig current -fill] 4]
    if {(($type == "rectangle") || ($type == "oval") || ($type == "arc"))
	    && ($fill == "")} {
	set outline [lindex [$c itemconfig current -outline] 4]
	set restoreCmd "$c itemconfig current -outline $outline"
	$c itemconfig current -outline SteelBlue2







<
|
|
<












|
<
|
|
<
<
<
<
<




















|
|
<
<
<
<
<
<
|
|
|
|
<
|
|












|


>
|




<
<
<
<







122
123
124
125
126
127
128

129
130

131
132
133
134
135
136
137
138
139
140
141
142
143

144
145





146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167






168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194




195
196
197
198
199
200
201
$c create text 22.5c 9c -anchor n -font $font1 -width 4c \
	-text "A short string of text, word-wrapped, justified left, and anchored north (at the top).  The rectangles show the anchor points for each piece of text." -tags item
$c create rectangle 25.4c 10.9c 25.6c 11.1c
$c create text 25.5c 11c -anchor w -font $font1 -fill $blue \
	-text "Several lines,\n each centered\nindividually,\nand all anchored\nat the left edge." \
	-justify center -tags item
$c create rectangle 24.9c 13.9c 25.1c 14.1c

$c create text 25c 14c -font $font2 -anchor c -fill $red -stipple gray50 \
	-text "Stippled characters" -tags item


$c create text 5c 16.2c -text Arcs -anchor n
$c create arc 0.5c 17c 7c 20c -fill $green -outline black \
	-start 45 -extent 270 -style pieslice -tags item
$c create arc 6.5c 17c 9.5c 20c -width 4m -style arc \
	-outline $blue -start -135 -extent 270 -tags item \
	-outlinestipple @[file join $tk_demoDirectory images gray25.xbm]
$c create arc 0.5c 20c 9.5c 24c -width 4m -style pieslice \
	-fill {} -outline $red -start 225 -extent -90 -tags item
$c create arc 5.5c 20.5c 9.5c 23.5c -width 4m -style chord \
	-fill $blue -outline {} -start 45 -extent 270  -tags item

$c create text 15c 16.2c -text Bitmaps -anchor n

$c create bitmap 13c 20c -tags item \
	-bitmap @[file join $tk_demoDirectory images face.xbm]





$c create bitmap 17c 18.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images noletter.xbm]
$c create bitmap 17c 21.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images letters.xbm]

$c create text 25c 16.2c -text Windows -anchor n
button $c.button -text "Press Me" -command "butPress $c $red"
$c create window 21c 18c -window $c.button -anchor nw -tags item
entry $c.entry -width 20 -relief sunken
$c.entry insert end "Edit this text"
$c create window 21c 21c -window $c.entry -anchor nw -tags item
scale $c.scale -from 0 -to 100 -length 6c -sliderlength .4c \
	-width .5c -tickinterval 0
$c create window 28.5c 17.5c -window $c.scale -anchor n -tags item
$c create text 21c 17.9c -text Button: -anchor sw
$c create text 21c 20.9c -text Entry: -anchor sw
$c create text 28.5c 17.4c -text Scale: -anchor s

# Set up event bindings for canvas:

$c bind item <Any-Enter> "itemEnter $c"
$c bind item <Any-Leave> "itemLeave $c"






bind $c <2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"
bind $c <3> "itemMark $c %x %y"
bind $c <B3-Motion> "itemStroke $c %x %y"

bind $c <Control-f> "itemsUnderArea $c"
bind $c <1> "itemStartDrag $c %x %y"
bind $c <B1-Motion> "itemDrag $c %x %y"

# Utility procedures for highlighting the item under the pointer:

proc itemEnter {c} {
    global restoreCmd

    if {[winfo depth $c] == 1} {
	set restoreCmd {}
	return
    }
    set type [$c type current]
    if {$type == "window"} {
	set restoreCmd {}
	return
    }
    if {$type == "bitmap"} {
	set bg [lindex [$c itemconf current -background] 4]
	set restoreCmd [list $c itemconfig current -background $bg]
	$c itemconfig current -background SteelBlue2
	return




    }
    set fill [lindex [$c itemconfig current -fill] 4]
    if {(($type == "rectangle") || ($type == "oval") || ($type == "arc"))
	    && ($fill == "")} {
	set outline [lindex [$c itemconfig current -outline] 4]
	set restoreCmd "$c itemconfig current -outline $outline"
	$c itemconfig current -outline SteelBlue2
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
}

proc itemsUnderArea {c} {
    global areaX1 areaY1 areaX2 areaY2
    set area [$c find withtag area]
    set items ""
    foreach i [$c find enclosed $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] >= 0} {
	    lappend items $i
	}
    }
    puts stdout "Items enclosed by area: $items"
    set items ""
    foreach i [$c find overlapping $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] >= 0} {
	    lappend items $i
	}
    }
    puts stdout "Items overlapping area: $items"
}

set areaX1 0







|






|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
}

proc itemsUnderArea {c} {
    global areaX1 areaY1 areaX2 areaY2
    set area [$c find withtag area]
    set items ""
    foreach i [$c find enclosed $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] != -1} {
	    lappend items $i
	}
    }
    puts stdout "Items enclosed by area: $items"
    set items ""
    foreach i [$c find overlapping $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] != -1} {
	    lappend items $i
	}
    }
    puts stdout "Items overlapping area: $items"
}

set areaX1 0
293
294
295
296
297
298
299
300
301
302
    set lastY $y
}

# Procedure that's invoked when the button embedded in the canvas
# is invoked.

proc butPress {w color} {
    set i [$w create text 25c 18.1c -text "Oooohhh!!" -fill $color -anchor n]
    after 500 "$w delete $i"
}







|


275
276
277
278
279
280
281
282
283
284
    set lastY $y
}

# Procedure that's invoked when the button embedded in the canvas
# is invoked.

proc butPress {w color} {
    set i [$w create text 25c 18.1c -text "Ouch!!" -fill $color -anchor n]
    after 500 "$w delete $i"
}

Changes to library/demos/ixset.

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    global mouseacc ;	set mouseacc	"3/1"
    global mousethr ;	set mousethr	4
    global screenbla ;	set screenbla	"blank"
    global screentim ;	set screentim	600
    global screencyc ;	set screencyc	600

    set xfd [open "|xset q" r]
    while {[gets $xfd line] >= 0} {
	switch -- [lindex $line 0] {
	    auto {
		set rpt [lindex $line 1]
		if {$rpt eq "repeat:"} {
		    set kbdrep [lindex $line 2]
		    set kbdcli [lindex $line 6]
		}







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    global mouseacc ;	set mouseacc	"3/1"
    global mousethr ;	set mousethr	4
    global screenbla ;	set screenbla	"blank"
    global screentim ;	set screentim	600
    global screencyc ;	set screencyc	600

    set xfd [open "|xset q" r]
    while {[gets $xfd line] > -1} {
	switch -- [lindex $line 0] {
	    auto {
		set rpt [lindex $line 1]
		if {$rpt eq "repeat:"} {
		    set kbdrep [lindex $line 2]
		    set kbdcli [lindex $line 6]
		}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

proc createwindows {} {
    #
    # Buttons
    #

    frame .buttons
    button .buttons.ok	   -default active -command ok     -text "Ok"
    button .buttons.apply  -default normal -command apply  -text "Apply" \
	    -state disabled
    button .buttons.cancel -default normal -command cancel -text "Cancel" \
	    -state disabled
    button .buttons.quit   -default normal -command quit   -text "Quit"

    pack .buttons.ok .buttons.apply .buttons.cancel .buttons.quit \
	    -side left -expand yes -pady 5

    bind . <Return> {.buttons.ok   flash; .buttons.ok   invoke}
    bind . <Escape> {.buttons.quit flash; .buttons.quit invoke}
    bind . <Button-1> {
	if {![string match .buttons* %W]} {
	    .buttons.apply  configure -state normal
	    .buttons.cancel configure -state normal
	}
    }
    bind . <Key> {
	if {![string match .buttons* %W]} {







|




|






|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

proc createwindows {} {
    #
    # Buttons
    #

    frame .buttons
    button .buttons.ok	   -default active -command ok     -text "Ok"    
    button .buttons.apply  -default normal -command apply  -text "Apply" \
	    -state disabled
    button .buttons.cancel -default normal -command cancel -text "Cancel" \
	    -state disabled
    button .buttons.quit   -default normal -command quit   -text "Quit"  

    pack .buttons.ok .buttons.apply .buttons.cancel .buttons.quit \
	    -side left -expand yes -pady 5

    bind . <Return> {.buttons.ok   flash; .buttons.ok   invoke}
    bind . <Escape> {.buttons.quit flash; .buttons.quit invoke}
    bind . <1> {
	if {![string match .buttons* %W]} {
	    .buttons.apply  configure -state normal
	    .buttons.cancel configure -state normal
	}
    }
    bind . <Key> {
	if {![string match .buttons* %W]} {

Changes to library/demos/knightstour.tcl.

1
2
3
4
5
6
7
8
# Copyright © 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
#
#	Calculate a Knight's tour of a chessboard.
#
#	This uses Warnsdorff's rule to calculate the next square each
#	time. This specifies that the next square should be the one that
#	has the least number of available moves.
#
|







1
2
3
4
5
6
7
8
# Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
#
#	Calculate a Knight's tour of a chessboard.
#
#	This uses Warnsdorff's rule to calculate the next square each
#	time. This specifies that the next square should be the one that
#	has the least number of available moves.
#
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#	If the call to the Edgemost function is commented out you can see
#	this occur.
#
#	You can drag the knight to a specific square to start if you wish.
#	If you let it repeat then it will choose random start positions
#	for each new tour.

package require Tk

# Return a list of accessible squares from a given square
proc ValidMoves {square} {
    set moves {}
    foreach pair {{-1 -2} {-2 -1} {-2 1} {-1 2} {1 2} {2 1} {2 -1} {1 -2}} {
        set col [expr {($square % 8) + [lindex $pair 0]}]
        set row [expr {($square / 8) + [lindex $pair 1]}]
        if {$row >= 0 && $row < 8 && $col >= 0 && $col < 8} {
            lappend moves [expr {$row * 8 + $col}]
        }
    }
    return $moves
}

# Return the number of available moves for this square
proc CheckSquare {square} {
    variable visited
    set moves 0
    foreach test [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $test] < 0} {
            incr moves
        }
    }
    return $moves
}

# Select the next square to move to. Returns -1 if there are no available
# squares remaining that we can move to.
proc Next {square} {
    variable visited
    set minimum 9
    set nextSquare -1
    foreach testSquare [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $testSquare] < 0} {
            set count [CheckSquare $testSquare]
            if {$count < $minimum} {
                set minimum $count
                set nextSquare $testSquare
            } elseif {$count == $minimum} {
                # to remove the enhancement to Warnsdorff's rule
                # remove the next line:
                set nextSquare [Edgemost $nextSquare $testSquare]
            }
        }
    }
    return $nextSquare
}








|







|











|













|





<
<







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
#	If the call to the Edgemost function is commented out you can see
#	this occur.
#
#	You can drag the knight to a specific square to start if you wish.
#	If you let it repeat then it will choose random start positions
#	for each new tour.

package require Tk 8.5

# Return a list of accessible squares from a given square
proc ValidMoves {square} {
    set moves {}
    foreach pair {{-1 -2} {-2 -1} {-2 1} {-1 2} {1 2} {2 1} {2 -1} {1 -2}} {
        set col [expr {($square % 8) + [lindex $pair 0]}]
        set row [expr {($square / 8) + [lindex $pair 1]}]
        if {$row > -1 && $row < 8 && $col > -1 && $col < 8} {
            lappend moves [expr {$row * 8 + $col}]
        }
    }
    return $moves
}

# Return the number of available moves for this square
proc CheckSquare {square} {
    variable visited
    set moves 0
    foreach test [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $test] == -1} {
            incr moves
        }
    }
    return $moves
}

# Select the next square to move to. Returns -1 if there are no available
# squares remaining that we can move to.
proc Next {square} {
    variable visited
    set minimum 9
    set nextSquare -1
    foreach testSquare [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $testSquare] == -1} {
            set count [CheckSquare $testSquare]
            if {$count < $minimum} {
                set minimum $count
                set nextSquare $testSquare
            } elseif {$count == $minimum} {


                set nextSquare [Edgemost $nextSquare $testSquare]
            }
        }
    }
    return $nextSquare
}

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    variable visited
    variable delay
    variable continuous
    $dlg.f.txt insert end "[llength $visited]. [N $last] .. [N $square]\n" {}
    $dlg.f.txt see end
    $dlg.f.c itemconfigure [expr {1+$last}] -state normal -outline black
    $dlg.f.c itemconfigure [expr {1+$square}] -state normal -outline red
    $dlg.f.c moveto knight {*}[lrange [$dlg.f.c coords [expr {1+$square}]] 0 1]
    lappend visited $square
    set next [Next $square]
    if {$next ne -1} {
        variable aid [after $delay [list MovePiece $dlg $square $next]]
    } else {
        $dlg.tf.b1 configure -state normal
        if {[llength $visited] == 64} {







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    variable visited
    variable delay
    variable continuous
    $dlg.f.txt insert end "[llength $visited]. [N $last] .. [N $square]\n" {}
    $dlg.f.txt see end
    $dlg.f.c itemconfigure [expr {1+$last}] -state normal -outline black
    $dlg.f.c itemconfigure [expr {1+$square}] -state normal -outline red
    $dlg.f.c coords knight [lrange [$dlg.f.c coords [expr {1+$square}]] 0 1]
    lappend visited $square
    set next [Next $square]
    if {$next ne -1} {
        variable aid [after $delay [list MovePiece $dlg $square $next]]
    } else {
        $dlg.tf.b1 configure -state normal
        if {[llength $visited] == 64} {
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
    variable visited {}
    $dlg.f.txt delete 1.0 end
    $dlg.tf.b1 configure -state disabled
    for {set n 0} {$n < 64} {incr n} {
        $dlg.f.c itemconfigure $n -state disabled -outline black
    }
    if {$square eq {}} {
        set coords [lrange [$dlg.f.c coords knight] 0 1]
        set square [expr {[$dlg.f.c find closest {*}$coords 0 65]-1}]

    }
    variable initial $square
    after idle [list MovePiece $dlg $initial $initial]
}

proc Stop {} {
    variable aid







<
|
>







121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
    variable visited {}
    $dlg.f.txt delete 1.0 end
    $dlg.tf.b1 configure -state disabled
    for {set n 0} {$n < 64} {incr n} {
        $dlg.f.c itemconfigure $n -state disabled -outline black
    }
    if {$square eq {}} {

        set square [expr {[$dlg.f.c find closest \
                               {*}[$dlg.f.c coords knight] 0 65]-1}]
    }
    variable initial $square
    after idle [list MovePiece $dlg $initial $initial]
}

proc Stop {} {
    variable aid
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
        $w move selected [expr {$x - [lindex $dragging 0]}] \
            [expr {$y - [lindex $dragging 1]}]
        variable dragging [list $x $y]
    }
}
proc DragEnd {w x y} {
    set square [$w find closest $x $y 0 65]
    $w moveto selected {*}[lrange [$w coords $square] 0 1]
    $w dtag selected
    variable dragging ; unset dragging
}

proc CreateGUI {} {
    catch {destroy .knightstour}
    set dlg [toplevel .knightstour]
    wm title $dlg "Knights tour"
    wm withdraw $dlg
    set f [ttk::frame $dlg.f]
    set c [canvas $f.c -width 240 -height 240]
    text $f.txt -width 10 -height 1 \
        -yscrollcommand [list $f.vs set] -font {Arial 8}
    ttk::scrollbar $f.vs -command [list $f.txt yview]

    variable delay 600
    variable continuous 0
    ttk::frame $dlg.tf
    ttk::label $dlg.tf.ls -text Speed
    ttk::scale $dlg.tf.sc  -from 8 -to 2000 -command [list SetDelay] \
        -variable [namespace which -variable delay]
    ttk::checkbutton $dlg.tf.cc -text Repeat \
        -variable [namespace which -variable continuous]
    ttk::button $dlg.tf.b1 -text Start -command [list Tour $dlg]
    ttk::button $dlg.tf.b2 -text Exit -command [list Exit $dlg]
    set square 0
    for {set row 7} {$row >= 0} {incr row -1} {
        for {set col 0} {$col < 8} {incr col} {
            if {(($col & 1) ^ ($row & 1))} {
                set fill tan3 ; set dfill tan4
            } else {
                set fill bisque ; set dfill bisque3
            }
            set coords [list [expr {$col * 30 + 4}] [expr {$row * 30 + 4}] \
                            [expr {$col * 30 + 30}] [expr {$row * 30 + 30}]]
            $c create rectangle $coords -fill $fill -disabledfill $dfill \
                -width 2 -state disabled -outline black
        }
    }
    if {[tk windowingsystem] ne "x11"} {
        catch {eval font create KnightFont -size -24}
        $c create text 0 0 -font KnightFont -text "" \
            -anchor nw -tags knight -fill black -activefill "#600000"
    } else {
        # On X11 we cannot reliably tell if the ♞ glyph is available
        # so just use a polygon
        set pts {
            2 25   24 25  21 19   20 8   14 0   10 0   0 13   0 16
            2 17    4 14   5 15    3 17   5 17   9 14  10 15  5 21
        }
        $c create polygon $pts -tag knight -offset 8 \
            -fill black -activefill "#600000"
    }
    $c moveto knight {*}[lrange [$c coords [expr {1 + int(rand() * 64)}]] 0 1]
    $c bind knight <Button-1> [namespace code [list DragStart %W %x %y]]
    $c bind knight <Motion> [namespace code [list DragMotion %W %x %y]]
    $c bind knight <ButtonRelease-1> [namespace code [list DragEnd %W %x %y]]

    grid $c $f.txt $f.vs  -sticky news
    grid rowconfigure    $f 0 -weight 1
    grid columnconfigure $f 1 -weight 1

    grid $f - - - - - -sticky news
    set things [list $dlg.tf.ls $dlg.tf.sc $dlg.tf.cc $dlg.tf.b1]
    if {![info exists ::widgetDemo]} {







|











|














|









|


<
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|


|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

204
205
206










207
208
209
210
211
212
213
214
215
216
217
218
        $w move selected [expr {$x - [lindex $dragging 0]}] \
            [expr {$y - [lindex $dragging 1]}]
        variable dragging [list $x $y]
    }
}
proc DragEnd {w x y} {
    set square [$w find closest $x $y 0 65]
    $w coords selected [lrange [$w coords $square] 0 1]
    $w dtag selected
    variable dragging ; unset dragging
}

proc CreateGUI {} {
    catch {destroy .knightstour}
    set dlg [toplevel .knightstour]
    wm title $dlg "Knights tour"
    wm withdraw $dlg
    set f [ttk::frame $dlg.f]
    set c [canvas $f.c -width 240 -height 240]
    text $f.txt -width 10 -height 1 -background white \
        -yscrollcommand [list $f.vs set] -font {Arial 8}
    ttk::scrollbar $f.vs -command [list $f.txt yview]

    variable delay 600
    variable continuous 0
    ttk::frame $dlg.tf
    ttk::label $dlg.tf.ls -text Speed
    ttk::scale $dlg.tf.sc  -from 8 -to 2000 -command [list SetDelay] \
        -variable [namespace which -variable delay]
    ttk::checkbutton $dlg.tf.cc -text Repeat \
        -variable [namespace which -variable continuous]
    ttk::button $dlg.tf.b1 -text Start -command [list Tour $dlg]
    ttk::button $dlg.tf.b2 -text Exit -command [list Exit $dlg]
    set square 0
    for {set row 7} {$row != -1} {incr row -1} {
        for {set col 0} {$col < 8} {incr col} {
            if {(($col & 1) ^ ($row & 1))} {
                set fill tan3 ; set dfill tan4
            } else {
                set fill bisque ; set dfill bisque3
            }
            set coords [list [expr {$col * 30 + 4}] [expr {$row * 30 + 4}] \
                            [expr {$col * 30 + 30}] [expr {$row * 30 + 30}]]
            $c create rectangle $coords -fill $fill -disabledfill $dfill \
                -width 2 -state disabled
        }
    }

    catch {eval font create KnightFont -size -24}
    $c create text 0 0 -font KnightFont -text "\u265e" \
        -anchor nw -tags knight -fill black -activefill "#600000"










    $c coords knight [lrange [$c coords [expr {1 + int(rand() * 64)}]] 0 1]
    $c bind knight <ButtonPress-1> [namespace code [list DragStart %W %x %y]]
    $c bind knight <Motion> [namespace code [list DragMotion %W %x %y]]
    $c bind knight <ButtonRelease-1> [namespace code [list DragEnd %W %x %y]]
    
    grid $c $f.txt $f.vs  -sticky news
    grid rowconfigure    $f 0 -weight 1
    grid columnconfigure $f 1 -weight 1

    grid $f - - - - - -sticky news
    set things [list $dlg.tf.ls $dlg.tf.sc $dlg.tf.cc $dlg.tf.b1]
    if {![info exists ::widgetDemo]} {
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
	pack configure [lindex $things 0] -padx {4 24}
	pack configure [lindex $things end] -padx {16 4}
    }
    grid $dlg.tf  - - - - - -sticky ew
    if {[info exists ::widgetDemo]} {
        grid [addSeeDismiss $dlg.buttons $dlg] - - - - - -sticky ew
    }

    grid rowconfigure $dlg 0 -weight 1
    grid columnconfigure $dlg 0 -weight 1

    bind $dlg <Control-F2> {console show}
    bind $dlg <Return> [list $dlg.tf.b1 invoke]
    bind $dlg <Escape> [list $dlg.tf.b2 invoke]
    bind $dlg <Destroy> [namespace code [list Stop]]







|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	pack configure [lindex $things 0] -padx {4 24}
	pack configure [lindex $things end] -padx {16 4}
    }
    grid $dlg.tf  - - - - - -sticky ew
    if {[info exists ::widgetDemo]} {
        grid [addSeeDismiss $dlg.buttons $dlg] - - - - - -sticky ew
    }
    
    grid rowconfigure $dlg 0 -weight 1
    grid columnconfigure $dlg 0 -weight 1

    bind $dlg <Control-F2> {console show}
    bind $dlg <Return> [list $dlg.tf.b1 invoke]
    bind $dlg <Escape> [list $dlg.tf.b2 invoke]
    bind $dlg <Destroy> [namespace code [list Stop]]

Changes to library/demos/label.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
set w .label
catch {destroy $w}
toplevel $w
wm title $w "Label Demonstration"
wm iconname $w "label"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Five labels are displayed below: three textual ones on the left, and an image label and a text label on the right.  Labels are pretty boring because you can't do anything with them."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.left
frame $w.right
pack $w.left $w.right -side left -expand yes -padx 10 -pady 10 -fill both

label $w.left.l1 -text "First label"
label $w.left.l2 -text "Second label, raised" -relief raised
label $w.left.l3 -text "Third label, sunken" -relief sunken
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -pady 2 -anchor w

# Main widget program sets variable tk_demoDirectory
image create photo label.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]
label $w.right.picture -borderwidth 2 -relief sunken -image label.ousterhout
label $w.right.caption -text "Tcl/Tk Creator"
pack $w.right.picture $w.right.caption -side top







|
















|
|
<
|
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
set w .label
catch {destroy $w}
toplevel $w
wm title $w "Label Demonstration"
wm iconname $w "label"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Five labels are displayed below: three textual ones on the left, and a bitmap label and a text label on the right.  Labels are pretty boring because you can't do anything with them."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.left
frame $w.right
pack $w.left $w.right -side left -expand yes -padx 10 -pady 10 -fill both

label $w.left.l1 -text "First label"
label $w.left.l2 -text "Second label, raised" -relief raised
label $w.left.l3 -text "Third label, sunken" -relief sunken
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -pady 2 -anchor w

# Main widget program sets variable tk_demoDirectory
label $w.right.bitmap -borderwidth 2 -relief sunken \
	-bitmap @[file join $tk_demoDirectory images face.xbm]

label $w.right.caption -text "Tcl/Tk Proprietor"
pack $w.right.bitmap $w.right.caption -side top

Changes to library/demos/mclist.tcl.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30




31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# mclist.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget configured as a multi-column listbox.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .mclist
catch {destroy $w}
toplevel $w
wm title $w "Multi-Column List"
wm iconname $w "mclist"
positionWindow $w

## Explanatory text
ttk::label $w.msg -font $font -wraplength 4i -justify left -anchor n -padding {10 2 10 6} -text "Ttk is the new Tk themed widget set. One of the widgets it includes is a tree widget, which can be configured to display multiple columns of informational data without displaying the tree itself. This is a simple way to build a listbox that has multiple columns. Clicking on the heading for a column will sort the data by that column. You can also change the width of the columns by dragging the boundary between them."
pack $w.msg -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w] -side bottom -fill x

ttk::frame $w.container
ttk::treeview $w.tree -columns {country capital currency} -show headings \
    -yscroll "$w.vsb set" -xscroll "$w.hsb set"

ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"




pack $w.container -fill both -expand 1
grid $w.tree $w.vsb -in $w.container -sticky nsew
grid $w.hsb         -in $w.container -sticky nsew
grid column $w.container 0 -weight 1
grid row    $w.container 0 -weight 1

image create photo upArrow -data {
    R0lGODlhDgAOAJEAANnZ2YCAgPz8/P///yH5BAEAAAAALAAAAAAOAA4AAAImhI+
    py+1LIsJHiBAh+BgmiEAJQITgW6DgUQIAECH4JN8IPqYuNxUAOw==}
image create photo downArrow -data {
    R0lGODlhDgAOAJEAANnZ2YCAgPz8/P///yH5BAEAAAAALAAAAAAOAA4AAAInhI+
    py+1I4ocQ/IgDEYIPgYJICUCE4F+YIBolEoKPEJKZmVJK6ZACADs=}
image create photo noArrow -height 14 -width 14

## The data we're going to insert
set data {
    Argentina		{Buenos Aires}		ARS
    Australia		Canberra		AUD
    Brazil		Brazilia		BRL
    Canada		Ottawa			CAD
    China		Beijing			CNY
    France		Paris			EUR
    Germany		Berlin			EUR
    India		{New Delhi}		INR
    Italy		Rome			EUR
    Japan		Tokyo			JPY
    Mexico		{Mexico City}		MXN
    Russia		Moscow			RUB
    {South Africa}	Pretoria		ZAR
    {United Kingdom}	London			GBP
    {United States}	{Washington, D.C.}	USD
}

## Code to insert the data nicely
set font [ttk::style lookup Heading -font]
foreach col {country capital currency} name {Country Capital Currency} {
    $w.tree heading $col -text $name -image noArrow -anchor w \
	-command [list SortBy $w.tree $col 0]
    $w.tree column $col -width [expr {
	[font measure $font $name] + [image width noArrow] + 5
    }]
}
set font [ttk::style lookup Treeview -font]
foreach {country capital currency} $data {
    $w.tree insert {} end -values [list $country $capital $currency]
    foreach col {country capital currency} {
	set len [font measure $font "[set $col]  "]
	if {[$w.tree column $col -width] < $len} {
	    $w.tree column $col -width $len
	}
    }
}

## Code to do the sorting of the tree contents when clicked on
proc SortBy {tree col direction} {
    # Determine currently sorted column and its sort direction
    foreach c {country capital currency} {
	set s [$tree heading $c state]
	if {("selected" in $s || "alternate" in $s) && $col ne $c} {
	    # Sorted column has changed
	    $tree heading $c -image noArrow state {!selected !alternate !user1}
	    set direction [expr {"alternate" in $s}]
	}
    }

    # Build something we can sort
    set data {}
    foreach row [$tree children {}] {










>


















>
|
|
>
>
>
>






<
<
<
<
<
<
<
<




















|

<
|
|
<
<

<

















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42








43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66


67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# mclist.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget configured as a multi-column listbox.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .mclist
catch {destroy $w}
toplevel $w
wm title $w "Multi-Column List"
wm iconname $w "mclist"
positionWindow $w

## Explanatory text
ttk::label $w.msg -font $font -wraplength 4i -justify left -anchor n -padding {10 2 10 6} -text "Ttk is the new Tk themed widget set. One of the widgets it includes is a tree widget, which can be configured to display multiple columns of informational data without displaying the tree itself. This is a simple way to build a listbox that has multiple columns. Clicking on the heading for a column will sort the data by that column. You can also change the width of the columns by dragging the boundary between them."
pack $w.msg -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w] -side bottom -fill x

ttk::frame $w.container
ttk::treeview $w.tree -columns {country capital currency} -show headings \
    -yscroll "$w.vsb set" -xscroll "$w.hsb set"
if {[tk windowingsystem] ne "aqua"} {
    ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
    ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
} else {
    scrollbar $w.vsb -orient vertical -command "$w.tree yview"
    scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
}
pack $w.container -fill both -expand 1
grid $w.tree $w.vsb -in $w.container -sticky nsew
grid $w.hsb         -in $w.container -sticky nsew
grid column $w.container 0 -weight 1
grid row    $w.container 0 -weight 1









## The data we're going to insert
set data {
    Argentina		{Buenos Aires}		ARS
    Australia		Canberra		AUD
    Brazil		Brazilia		BRL
    Canada		Ottawa			CAD
    China		Beijing			CNY
    France		Paris			EUR
    Germany		Berlin			EUR
    India		{New Delhi}		INR
    Italy		Rome			EUR
    Japan		Tokyo			JPY
    Mexico		{Mexico City}		MXN
    Russia		Moscow			RUB
    {South Africa}	Pretoria		ZAR
    {United Kingdom}	London			GBP
    {United States}	{Washington, D.C.}	USD
}

## Code to insert the data nicely
set font [ttk::style lookup [$w.tree cget -style] -font]
foreach col {country capital currency} name {Country Capital Currency} {

    $w.tree heading $col -command [list SortBy $w.tree $col 0] -text $name
    $w.tree column $col -width [font measure $font $name]


}

foreach {country capital currency} $data {
    $w.tree insert {} end -values [list $country $capital $currency]
    foreach col {country capital currency} {
	set len [font measure $font "[set $col]  "]
	if {[$w.tree column $col -width] < $len} {
	    $w.tree column $col -width $len
	}
    }
}

## Code to do the sorting of the tree contents when clicked on
proc SortBy {tree col direction} {
    # Determine currently sorted column and its sort direction
    foreach c {country capital currency} {
	set s [$tree heading $c state]
	if {("selected" in $s || "alternate" in $s) && $col ne $c} {
	    # Sorted column has changed
	    $tree heading $c state {!selected !alternate !user1}
	    set direction [expr {"alternate" in $s}]
	}
    }

    # Build something we can sort
    set data {}
    foreach row [$tree children {}] {
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    foreach info [lsort -dictionary -index 0 $dir $data] {
	$tree move [lindex $info 1] {} [incr r]
    }

    # Switch the heading so that it will sort in the opposite direction
    $tree heading $col -command [list SortBy $tree $col [expr {!$direction}]] \
	state [expr {$direction?"!selected alternate":"selected !alternate"}]
    if {[ttk::style theme use] eq "aqua"} {
	# Aqua theme displays native sort arrows when user1 state is set
	$tree heading $col state "user1"
    } else {
	$tree heading $col -image [expr {$direction?"upArrow":"downArrow"}]
    }
}







|


<
<


100
101
102
103
104
105
106
107
108
109


110
111
    foreach info [lsort -dictionary -index 0 $dir $data] {
	$tree move [lindex $info 1] {} [incr r]
    }

    # Switch the heading so that it will sort in the opposite direction
    $tree heading $col -command [list SortBy $tree $col [expr {!$direction}]] \
	state [expr {$direction?"!selected alternate":"selected !alternate"}]
    if {[tk windowingsystem] eq "aqua"} {
	# Aqua theme displays native sort arrows when user1 state is set
	$tree heading $col state "user1"


    }
}

Changes to library/demos/menu.tcl.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
} elseif {[tk windowingsystem] == "win32"} {
    set modifier Control
} else {
    set modifier Meta
}
foreach i {A B C D E F} {
    $m add command -label "Print letter \"$i\"" -underline 14 \
	    -accelerator Meta+$i -command "puts $i" -accelerator $modifier+$i
    bind $w <$modifier-[string tolower $i]> "puts $i"
}

set m $w.menu.cascade
$w.menu add cascade -label "Cascades" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Print hello" \







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
} elseif {[tk windowingsystem] == "win32"} {
    set modifier Control
} else {
    set modifier Meta
}
foreach i {A B C D E F} {
    $m add command -label "Print letter \"$i\"" -underline 14 \
	    -accelerator $modifier+$i -command "puts $i"
    bind $w <$modifier-[string tolower $i]> "puts $i"
}

set m $w.menu.cascade
$w.menu add cascade -label "Cascades" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Print hello" \
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
$m invoke 1
$m invoke 7

set m $w.menu.icon
$w.menu add cascade -label "Icons" -menu $m -underline 0
menu $m -tearoff 0
# Main widget program sets variable tk_demoDirectory
image create photo lilearth -file [file join $tk_demoDirectory \
images earthmenu.png]
$m add command -image lilearth \
    -hidemargin 1 -command [list \
	tk_dialog $w.pattern {Bitmap Menu Entry} \
		"The menu entry you invoked displays a photoimage rather than\
		a text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]
foreach i {info questhead error} {
    $m add command -bitmap $i -hidemargin 1 -command [list \
	    puts "You invoked the $i bitmap" ]
}
$m entryconfigure 2 -columnbreak 1

set m $w.menu.more
$w.menu add cascade -label "More" -menu $m -underline 0
menu $m -tearoff 0
foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Does almost nothing also} {Make life meaningful}} {
    $m add command -label $i -command [list puts "You invoked \"$i\""]
}
$m entryconfigure "Does almost nothing" -bitmap questhead -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a bitmap and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

$m entryconfigure "Does almost nothing also" -image lilearth -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a image and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

set m $w.menu.colors
$w.menu add cascade -label "Colors" -menu $m -underline 1
menu $m -tearoff 1
foreach i {red orange yellow green blue} {







|
<
<


|











|






<
<
<
<
<
<
<







110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138







139
140
141
142
143
144
145
$m invoke 1
$m invoke 7

set m $w.menu.icon
$w.menu add cascade -label "Icons" -menu $m -underline 0
menu $m -tearoff 0
# Main widget program sets variable tk_demoDirectory
$m add command -bitmap @[file join $tk_demoDirectory images pattern.xbm] \


    -hidemargin 1 -command [list \
	tk_dialog $w.pattern {Bitmap Menu Entry} \
		"The menu entry you invoked displays a bitmap rather than\
		a text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]
foreach i {info questhead error} {
    $m add command -bitmap $i -hidemargin 1 -command [list \
	    puts "You invoked the $i bitmap" ]
}
$m entryconfigure 2 -columnbreak 1

set m $w.menu.more
$w.menu add cascade -label "More" -menu $m -underline 0
menu $m -tearoff 0
foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Make life meaningful}} {
    $m add command -label $i -command [list puts "You invoked \"$i\""]
}
$m entryconfigure "Does almost nothing" -bitmap questhead -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a bitmap and a\







		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

set m $w.menu.colors
$w.menu add cascade -label "Colors" -menu $m -underline 1
menu $m -tearoff 1
foreach i {red orange yellow green blue} {

Changes to library/demos/menubu.tcl.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
positionWindow $w

frame $w.body
pack $w.body -expand 1 -fill both
if {[tk windowingsystem] eq "aqua"} {catch {set origUseCustomMDEF $::tk::mac::useCustomMDEF; set ::tk::mac::useCustomMDEF 1}}

menubutton $w.body.below -text "Below" -underline 0 -direction below -menu $w.body.below.m -relief raised
menu $w.body.below.m -tearoff 0
$w.body.below.m add command -label "Below menu: first item" -command "puts \"You have selected the first item from the Below menu.\""
$w.body.below.m add command -label "Below menu: second item" -command "puts \"You have selected the second item from the Below menu.\""
grid $w.body.below -row 0 -column 1 -sticky n
menubutton $w.body.right -text "Right" -underline 0 -direction right -menu $w.body.right.m -relief raised
menu $w.body.right.m -tearoff 0
$w.body.right.m add command -label "Right menu: first item" -command "puts \"You have selected the first item from the Right menu.\""
$w.body.right.m add command -label "Right menu: second item" -command "puts \"You have selected the second item from the Right menu.\""







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
positionWindow $w

frame $w.body
pack $w.body -expand 1 -fill both
if {[tk windowingsystem] eq "aqua"} {catch {set origUseCustomMDEF $::tk::mac::useCustomMDEF; set ::tk::mac::useCustomMDEF 1}}

menubutton $w.body.below -text "Below" -underline 0 -direction below -menu $w.body.below.m -relief raised
menu $w.body.below.m -tearoff 0 
$w.body.below.m add command -label "Below menu: first item" -command "puts \"You have selected the first item from the Below menu.\""
$w.body.below.m add command -label "Below menu: second item" -command "puts \"You have selected the second item from the Below menu.\""
grid $w.body.below -row 0 -column 1 -sticky n
menubutton $w.body.right -text "Right" -underline 0 -direction right -menu $w.body.right.m -relief raised
menu $w.body.right.m -tearoff 0
$w.body.right.m add command -label "Right menu: first item" -command "puts \"You have selected the first item from the Right menu.\""
$w.body.right.m add command -label "Right menu: second item" -command "puts \"You have selected the second item from the Right menu.\""

Changes to library/demos/msgbox.tcl.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# msgbox.tcl --
#
# This demonstration script creates message boxes of various type

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .msgbox
catch {destroy $w}
toplevel $w
wm title $w "Message Box Demonstration"
wm iconname $w "messagebox"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Choose the icon and type option of the message box. Then press the \"Message Box\" button to see the message box."
pack $w.msg -side top

pack [addSeeDismiss $w.buttons $w {} {
    ttk::button $w.buttons.vars -text "Message Box" -command "showMessageBox $w"
}] -side bottom -fill x
#pack $w.buttons.dismiss $w.buttons.code $w.buttons.vars -side left -expand 1

frame $w.left
frame $w.right
pack $w.left $w.right -side left -expand yes -fill y  -pady .5c -padx .5c

label $w.left.label -text "Icon"
frame $w.left.sep -relief ridge -bd 1 -height 2
pack $w.left.label -side top
pack $w.left.sep -side top -fill x -expand no









>
















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# msgbox.tcl --
#
# This demonstration script creates message boxes of various type

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .msgbox
catch {destroy $w}
toplevel $w
wm title $w "Message Box Demonstration"
wm iconname $w "messagebox"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Choose the icon and type option of the message box. Then press the \"Message Box\" button to see the message box."
pack $w.msg -side top

pack [addSeeDismiss $w.buttons $w {} {
    ttk::button $w.buttons.vars -text "Message Box" -command "showMessageBox $w"
}] -side bottom -fill x
#pack $w.buttons.dismiss $w.buttons.code $w.buttons.vars -side left -expand 1

frame $w.left 
frame $w.right
pack $w.left $w.right -side left -expand yes -fill y  -pady .5c -padx .5c

label $w.left.label -text "Icon"
frame $w.left.sep -relief ridge -bd 1 -height 2
pack $w.left.label -side top
pack $w.left.sep -side top -fill x -expand no
52
53
54
55
56
57
58
59
60
61
62
}

proc showMessageBox {w} {
    global msgboxIcon msgboxType
    set button [tk_messageBox -icon $msgboxIcon -type $msgboxType \
	-title Message -parent $w\
	-message "This is a \"$msgboxType\" type messagebox with the \"$msgboxIcon\" icon"]

    tk_messageBox -icon info -message "You have selected \"$button\"" -type ok\
	-parent $w
}







|



53
54
55
56
57
58
59
60
61
62
63
}

proc showMessageBox {w} {
    global msgboxIcon msgboxType
    set button [tk_messageBox -icon $msgboxIcon -type $msgboxType \
	-title Message -parent $w\
	-message "This is a \"$msgboxType\" type messagebox with the \"$msgboxIcon\" icon"]
    
    tk_messageBox -icon info -message "You have selected \"$button\"" -type ok\
	-parent $w
}

Changes to library/demos/paned1.tcl.

22
23
24
25
26
27
28
29
30
31
32
## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

panedwindow $w.pane
pack $w.pane -side top -expand yes -fill both -pady 2 -padx 2m

label $w.pane.left  -text "This is the\nleft side"  -fg black -bg yellow
label $w.pane.right -text "This is the\nright side" -fg black -bg cyan

$w.pane add $w.pane.left $w.pane.right







|
|


22
23
24
25
26
27
28
29
30
31
32
## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

panedwindow $w.pane
pack $w.pane -side top -expand yes -fill both -pady 2 -padx 2m

label $w.pane.left  -text "This is the\nleft side"  -bg yellow
label $w.pane.right -text "This is the\nright side" -bg cyan

$w.pane add $w.pane.left $w.pane.right

Changes to library/demos/paned2.tcl.

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    toplevel
}
set f [frame $w.pane.top]
listbox $f.list -listvariable paneList -yscrollcommand "$f.scr set"
# Invert the first item to highlight it
$f.list itemconfigure 0 \
	-background [$f.list cget -fg] -foreground [$f.list cget -bg]
ttk::scrollbar $f.scr -orient vertical -command "$f.list yview"
pack $f.scr -side right -fill y
pack $f.list -fill both -expand 1

# The bottom window is a text widget with scrollbar
set f [frame $w.pane.bottom]
text $f.text -xscrollcommand "$f.xscr set" -yscrollcommand "$f.yscr set" \
	-width 30 -height 8 -wrap none
ttk::scrollbar $f.xscr -orient horizontal -command "$f.text xview"
ttk::scrollbar $f.yscr -orient vertical -command "$f.text yview"
grid $f.text $f.yscr -sticky nsew
grid $f.xscr         -sticky nsew
grid columnconfigure $f 0 -weight 1
grid rowconfigure    $f 0 -weight 1
$f.text insert 1.0 "This is just a normal text widget"

# Now add our contents to the paned window







|







|
|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    toplevel
}
set f [frame $w.pane.top]
listbox $f.list -listvariable paneList -yscrollcommand "$f.scr set"
# Invert the first item to highlight it
$f.list itemconfigure 0 \
	-background [$f.list cget -fg] -foreground [$f.list cget -bg]
scrollbar $f.scr -orient vertical -command "$f.list yview"
pack $f.scr -side right -fill y
pack $f.list -fill both -expand 1

# The bottom window is a text widget with scrollbar
set f [frame $w.pane.bottom]
text $f.text -xscrollcommand "$f.xscr set" -yscrollcommand "$f.yscr set" \
	-width 30 -height 8 -wrap none
scrollbar $f.xscr -orient horizontal -command "$f.text xview"
scrollbar $f.yscr -orient vertical -command "$f.text yview"
grid $f.text $f.yscr -sticky nsew
grid $f.xscr         -sticky nsew
grid columnconfigure $f 0 -weight 1
grid rowconfigure    $f 0 -weight 1
$f.text insert 1.0 "This is just a normal text widget"

# Now add our contents to the paned window

Changes to library/demos/pendulum.tcl.

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
canvas $w.k -width 320 -height 200 -background white -bd 2 -relief sunken
$w.k create line 160 200 160 0 -fill grey75 -arrow last -tags y_axis
$w.k create line 0 100 320 100 -fill grey75 -arrow last -tags x_axis
for {set i 90} {$i>=0} {incr i -10} {
    # Coordinates of these items don't matter; they will be set properly below
    $w.k create line 0 0 1 1 -smooth true -tags graph$i -fill grey$i
}

$w.k create text 0 0 -anchor ne -text "θ" -tags label_theta
$w.k create text 0 0 -anchor ne -text "δθ" -tags label_dtheta
pack $w.k -in $w.p.l2 -fill both -expand true

# Initialize some variables
set points {}
set Theta   45.0
set dTheta   0.0
set pi       3.1415926535897933







|
|
|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
canvas $w.k -width 320 -height 200 -background white -bd 2 -relief sunken
$w.k create line 160 200 160 0 -fill grey75 -arrow last -tags y_axis
$w.k create line 0 100 320 100 -fill grey75 -arrow last -tags x_axis
for {set i 90} {$i>=0} {incr i -10} {
    # Coordinates of these items don't matter; they will be set properly below
    $w.k create line 0 0 1 1 -smooth true -tags graph$i -fill grey$i
}
# FIXME: UNICODE labels
$w.k create text 0 0 -anchor ne -text "q" -font {Symbol 8} -tags label_theta
$w.k create text 0 0 -anchor ne -text "dq" -font {Symbol 8} -tags label_dtheta
pack $w.k -in $w.p.l2 -fill both -expand true

# Initialize some variables
set points {}
set Theta   45.0
set dTheta   0.0
set pi       3.1415926535897933
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# button. Also note that both canvases are sensitive to <Configure>
# events, which allows them to find out when they have been resized by
# the user.
bind $w.c <Destroy> {
    after cancel $animationCallbacks(pendulum)
    unset animationCallbacks(pendulum)
}
bind $w.c <Button-1> {
    after cancel $animationCallbacks(pendulum)
    showPendulum %W at %x %y
}
bind $w.c <B1-Motion> {
    showPendulum %W at %x %y
}
bind $w.c <ButtonRelease-1> {
    showPendulum %W at %x %y
    set animationCallbacks(pendulum) [after 15 repeat [winfo toplevel %W]]
}
bind $w.c <Configure> {
    %W coords plate 0 25 %w 25
    set home [expr {%w/2}]
    %W coords pivot [expr {$home-5}] 20 [expr {$home+5}] 30
}
bind $w.k <Configure> {
    set psh [expr {%h/2}]
    set psw [expr {%w/2}]
    %W coords x_axis 2 $psh [expr {%w-2}] $psh
    %W coords y_axis $psw [expr {%h-2}] $psw 2
    %W coords label_dtheta [expr {$psw-4}] 6
    %W coords label_theta [expr {%w-6}] [expr {$psh+4}]
}

# This procedure is the "business" part of the simulation that does
# simple numerical integration of the formula for a simple rotational
# pendulum.
proc recomputeAngle {} {
    global Theta dTheta pi length







|












|
|


|
|
|
|
|
|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# button. Also note that both canvases are sensitive to <Configure>
# events, which allows them to find out when they have been resized by
# the user.
bind $w.c <Destroy> {
    after cancel $animationCallbacks(pendulum)
    unset animationCallbacks(pendulum)
}
bind $w.c <1> {
    after cancel $animationCallbacks(pendulum)
    showPendulum %W at %x %y
}
bind $w.c <B1-Motion> {
    showPendulum %W at %x %y
}
bind $w.c <ButtonRelease-1> {
    showPendulum %W at %x %y
    set animationCallbacks(pendulum) [after 15 repeat [winfo toplevel %W]]
}
bind $w.c <Configure> {
    %W coords plate 0 25 %w 25
    set home [expr %w/2]
    %W coords pivot [expr $home-5] 20 [expr $home+5] 30
}
bind $w.k <Configure> {
    set psh [expr %h/2]
    set psw [expr %w/2]
    %W coords x_axis 2 $psh [expr %w-2] $psh
    %W coords y_axis $psw [expr %h-2] $psw 2
    %W coords label_dtheta [expr $psw-4] 6
    %W coords label_theta [expr %w-6] [expr $psh+4]
}

# This procedure is the "business" part of the simulation that does
# simple numerical integration of the formula for a simple rotational
# pendulum.
proc recomputeAngle {} {
    global Theta dTheta pi length

Changes to library/demos/plot.tcl.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    set y [expr {250 - (4*[lindex $point 1])/5}]
    set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
	    [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
	    -fill SkyBlue2]
    $c addtag point withtag $item
}

$c bind point <Enter> "$c itemconfig current -fill red"
$c bind point <Leave> "$c itemconfig current -fill SkyBlue2"
$c bind point <Button-1> "plotDown $c %x %y"
$c bind point <ButtonRelease-1> "$c dtag selected"
bind $c <B1-Motion> "plotMove $c %x %y"

set plot(lastX) 0
set plot(lastY) 0

# plotDown --







|
|
|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    set y [expr {250 - (4*[lindex $point 1])/5}]
    set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
	    [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
	    -fill SkyBlue2]
    $c addtag point withtag $item
}

$c bind point <Any-Enter> "$c itemconfig current -fill red"
$c bind point <Any-Leave> "$c itemconfig current -fill SkyBlue2"
$c bind point <1> "plotDown $c %x %y"
$c bind point <ButtonRelease-1> "$c dtag selected"
bind $c <B1-Motion> "plotMove $c %x %y"

set plot(lastX) 0
set plot(lastY) 0

# plotDown --

Changes to library/demos/puzzle.tcl.

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

# Special trick: select a darker color for the space by creating a
# scrollbar widget and using its trough color.

scrollbar $w.s

# The button metrics are a bit bigger in Aqua, and since we are
# using place which doesn't autosize, then we need to have a
# slightly larger frame here...

if {[tk windowingsystem] eq "aqua"} {
    set frameSize 168
} else {
    set frameSize 120
}

frame $w.frame -width $frameSize -height $frameSize -borderwidth 2\
	-relief sunken -bg [$w.s cget -troughcolor]
pack $w.frame -side top -pady 1c -padx 1c
destroy $w.s

set order {3 1 6 2 5 7 15 13 4 11 8 9 14 10 12}
for {set i 0} {$i < 15} {set i [expr {$i+1}]} {
    set num [lindex $order $i]
    set xpos($num) [expr {($i%4)*.25}]
    set ypos($num) [expr {($i/4)*.25}]
    button $w.frame.$num -relief raised -text $num -bd 0 -highlightthickness 0 \
	    -command "puzzleSwitch $w $num"
    place $w.frame.$num -relx $xpos($num) -rely $ypos($num) \
	-relwidth .25 -relheight .25
}
set xpos(space) .75
set ypos(space) .75







|


















|






50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

# Special trick: select a darker color for the space by creating a
# scrollbar widget and using its trough color.

scrollbar $w.s

# The button metrics are a bit bigger in Aqua, and since we are
# using place which doesn't autosize, then we need to have a 
# slightly larger frame here...

if {[tk windowingsystem] eq "aqua"} {
    set frameSize 168
} else {
    set frameSize 120
}

frame $w.frame -width $frameSize -height $frameSize -borderwidth 2\
	-relief sunken -bg [$w.s cget -troughcolor]
pack $w.frame -side top -pady 1c -padx 1c
destroy $w.s

set order {3 1 6 2 5 7 15 13 4 11 8 9 14 10 12}
for {set i 0} {$i < 15} {set i [expr {$i+1}]} {
    set num [lindex $order $i]
    set xpos($num) [expr {($i%4)*.25}]
    set ypos($num) [expr {($i/4)*.25}]
    button $w.frame.$num -relief raised -text $num -highlightthickness 0 \
	    -command "puzzleSwitch $w $num"
    place $w.frame.$num -relx $xpos($num) -rely $ypos($num) \
	-relwidth .25 -relheight .25
}
set xpos(space) .75
set ypos(space) .75

Changes to library/demos/ruler.tcl.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#
# Arguments:
# c -		The canvas window.
# x, y -	Coordinates at which to create the tab stop.

proc rulerMkTab {c x y} {
    upvar #0 demo_rulerInfo v
    set newTab [$c create polygon $x $y \
	    [expr {$x+$v(size)}] [expr {$y+$v(size)}] \
	    [expr {$x-$v(size)}] [expr {$y+$v(size)}]]
    set fill [$c itemcget $newTab -outline]
    $c itemconfigure $newTab -fill $fill -outline {}
    set v(normalStyle) "-fill $fill"
    return $newTab
}

set w .ruler
catch {destroy $w}
toplevel $w
wm title $w "Ruler Demonstration"
wm iconname $w "ruler"







<
|
|
<
<
<
<







15
16
17
18
19
20
21

22
23




24
25
26
27
28
29
30
#
# Arguments:
# c -		The canvas window.
# x, y -	Coordinates at which to create the tab stop.

proc rulerMkTab {c x y} {
    upvar #0 demo_rulerInfo v

    $c create polygon $x $y [expr {$x+$v(size)}] [expr {$y+$v(size)}] \
	    [expr {$x-$v(size)}] [expr {$y+$v(size)}]




}

set w .ruler
catch {destroy $w}
toplevel $w
wm title $w "Ruler Demonstration"
wm iconname $w "ruler"
48
49
50
51
52
53
54

55
56
57
58
59
60
61

set demo_rulerInfo(grid) .25c
set demo_rulerInfo(left) [winfo fpixels $c 1c]
set demo_rulerInfo(right) [winfo fpixels $c 13c]
set demo_rulerInfo(top) [winfo fpixels $c 1c]
set demo_rulerInfo(bottom) [winfo fpixels $c 1.5c]
set demo_rulerInfo(size) [winfo fpixels $c .2c]

# Main widget program sets variable tk_demoDirectory
if {[winfo depth $c] > 1} {
    set demo_rulerInfo(activeStyle) "-fill red -stipple {}"
    set demo_rulerInfo(deleteStyle) [list -fill red \
	    -stipple @[file join $tk_demoDirectory images gray25.xbm]]
} else {
    set demo_rulerInfo(activeStyle) "-fill black -stipple {}"







>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

set demo_rulerInfo(grid) .25c
set demo_rulerInfo(left) [winfo fpixels $c 1c]
set demo_rulerInfo(right) [winfo fpixels $c 13c]
set demo_rulerInfo(top) [winfo fpixels $c 1c]
set demo_rulerInfo(bottom) [winfo fpixels $c 1.5c]
set demo_rulerInfo(size) [winfo fpixels $c .2c]
set demo_rulerInfo(normalStyle) "-fill black"
# Main widget program sets variable tk_demoDirectory
if {[winfo depth $c] > 1} {
    set demo_rulerInfo(activeStyle) "-fill red -stipple {}"
    set demo_rulerInfo(deleteStyle) [list -fill red \
	    -stipple @[file join $tk_demoDirectory images gray25.xbm]]
} else {
    set demo_rulerInfo(activeStyle) "-fill black -stipple {}"
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    $c create line ${x}c 1c ${x}c 0.6c -width 1
    $c create line $x.25c 1c $x.25c 0.8c -width 1
    $c create line $x.5c 1c $x.5c 0.7c -width 1
    $c create line $x.75c 1c $x.75c 0.8c -width 1
    $c create text $x.15c .75c -text $i -anchor sw
}
$c addtag well withtag [$c create rect 13.2c 1c 13.8c 0.5c \
	-fill [lindex [$c config -bg] 4]]
$c addtag well withtag [rulerMkTab $c [winfo pixels $c 13.5c] \
	[winfo pixels $c .65c]]

$c bind well <Button-1> "rulerNewTab $c %x %y"
$c bind tab <Button-1> "rulerSelectTab $c %x %y"
bind $c <B1-Motion> "rulerMoveTab $c %x %y"
bind $c <ButtonRelease-1> "rulerReleaseTab $c"

# rulerNewTab --
# Does all the work of creating a tab stop, including creating the
# triangle object and adding tags to it to give it tab behavior.
#
# Arguments:
# c -		The canvas window.







|



|
|

|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    $c create line ${x}c 1c ${x}c 0.6c -width 1
    $c create line $x.25c 1c $x.25c 0.8c -width 1
    $c create line $x.5c 1c $x.5c 0.7c -width 1
    $c create line $x.75c 1c $x.75c 0.8c -width 1
    $c create text $x.15c .75c -text $i -anchor sw
}
$c addtag well withtag [$c create rect 13.2c 1c 13.8c 0.5c \
	-outline black -fill [lindex [$c config -bg] 4]]
$c addtag well withtag [rulerMkTab $c [winfo pixels $c 13.5c] \
	[winfo pixels $c .65c]]

$c bind well <1> "rulerNewTab $c %x %y"
$c bind tab <1> "rulerSelectTab $c %x %y"
bind $c <B1-Motion> "rulerMoveTab $c %x %y"
bind $c <Any-ButtonRelease-1> "rulerReleaseTab $c"

# rulerNewTab --
# Does all the work of creating a tab stop, including creating the
# triangle object and adding tags to it to give it tab behavior.
#
# Arguments:
# c -		The canvas window.

Changes to library/demos/sayings.tcl.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -expand yes -fill both -padx 1c


ttk::scrollbar $w.frame.yscroll -command "$w.frame.list yview"
ttk::scrollbar $w.frame.xscroll -orient horizontal \
    -command "$w.frame.list xview"
listbox $w.frame.list -width 20 -height 10 -setgrid 1 \
    -yscroll "$w.frame.yscroll set" -xscroll "$w.frame.xscroll set"

grid $w.frame.list -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.yscroll -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.xscroll -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news







|
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -expand yes -fill both -padx 1c


scrollbar $w.frame.yscroll -command "$w.frame.list yview"
scrollbar $w.frame.xscroll -orient horizontal \
    -command "$w.frame.list xview"
listbox $w.frame.list -width 20 -height 10 -setgrid 1 \
    -yscroll "$w.frame.yscroll set" -xscroll "$w.frame.xscroll set"

grid $w.frame.list -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.yscroll -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.xscroll -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news

Changes to library/demos/search.tcl.

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
button $w.string.button -text "Highlight" \
	-command "textSearch $w.text \$searchString search"
pack $w.string.label $w.string.entry -side left
pack $w.string.button -side left -pady 5 -padx 10
bind $w.string.entry <Return> "textSearch $w.text \$searchString search"

text $w.text -yscrollcommand "$w.scroll set" -setgrid true
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.file $w.string -side top -fill x
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles for text highlighting.

if {[winfo depth $w] > 1} {







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
button $w.string.button -text "Highlight" \
	-command "textSearch $w.text \$searchString search"
pack $w.string.label $w.string.entry -side left
pack $w.string.button -side left -pady 5 -padx 10
bind $w.string.entry <Return> "textSearch $w.text \$searchString search"

text $w.text -yscrollcommand "$w.scroll set" -setgrid true
scrollbar $w.scroll -command "$w.text yview"
pack $w.file $w.string -side top -fill x
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles for text highlighting.

if {[winfo depth $w] > 1} {

Changes to library/demos/square.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# square --
# This script generates a demo application containing only a "square"
# widget.  It's only usable in the "tktest" application or if Tk has
# been compiled with tkSquare.c. This demo arranges the following
# bindings for the widget:
#
# Button-1 press/drag:		moves square to mouse
# "a":				toggle size animation on/off

package require Tk		;# We use Tk generally, and...
package require Tktest		;# ... we use the square widget too.

square .s
pack .s -expand yes -fill both
wm minsize . 1 1

bind .s <Button-1> {center %x %y}
bind .s <B1-Motion> {center %x %y}
bind .s a animate
focus .s

# The procedure below centers the square on a given position.

proc center {x y} {
    set a [.s size]
    .s position [expr {$x-($a/2)}] [expr {$y-($a/2)}]
}

# The procedures below provide a simple form of animation where
# the box changes size in a pulsing pattern: larger, smaller, larger,
# and so on.

set inc 0









|










|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# square --
# This script generates a demo application containing only a "square"
# widget.  It's only usable in the "tktest" application or if Tk has
# been compiled with tkSquare.c. This demo arranges the following
# bindings for the widget:
# 
# Button-1 press/drag:		moves square to mouse
# "a":				toggle size animation on/off

package require Tk		;# We use Tk generally, and...
package require Tktest		;# ... we use the square widget too.

square .s
pack .s -expand yes -fill both
wm minsize . 1 1

bind .s <1> {center %x %y}
bind .s <B1-Motion> {center %x %y}
bind .s a animate
focus .s

# The procedure below centers the square on a given position.

proc center {x y} {
    set a [.s size]
    .s position [expr $x-($a/2)] [expr $y-($a/2)]
}

# The procedures below provide a simple form of animation where
# the box changes size in a pulsing pattern: larger, smaller, larger,
# and so on.

set inc 0

Changes to library/demos/states.tcl.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
wm title $w "Listbox Demonstration (50 states)"
wm iconname $w "states"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down."
pack $w.msg -side top

labelframe $w.justif -text Justification
foreach c {Left Center Right} {
    set lower [string tolower $c]
    radiobutton $w.justif.$lower -text $c -variable just \
        -relief flat -value $lower -anchor w \
        -command "$w.frame.list configure -justify \$just" \
        -tristatevalue "multi"
    pack $w.justif.$lower -side left -pady 2 -fill x
}
pack $w.justif

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth .5c
pack $w.frame -side top -expand yes -fill y

ttk::scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" -setgrid 1 -height 12
pack $w.frame.scroll -side right -fill y
pack $w.frame.list -side left -expand 1 -fill both

$w.frame.list insert 0 Alabama Alaska Arizona Arkansas California \
    Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois \
    Indiana Iowa Kansas Kentucky Louisiana Maine Maryland \







<
<
<
<
<
<
<
<
<
<
<







|







15
16
17
18
19
20
21











22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
wm title $w "Listbox Demonstration (50 states)"
wm iconname $w "states"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down."
pack $w.msg -side top












## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth .5c
pack $w.frame -side top -expand yes -fill y

scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" -setgrid 1 -height 12
pack $w.frame.scroll -side right -fill y
pack $w.frame.list -side left -expand 1 -fill both

$w.frame.list insert 0 Alabama Alaska Arizona Arkansas California \
    Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois \
    Indiana Iowa Kansas Kentucky Louisiana Maine Maryland \

Changes to library/demos/style.tcl.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# Only set the font family in one place for simplicity and consistency

set family Courier

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
	-width 70 -height 32 -wrap word -font "$family 12"
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles

$w.text tag configure bold -font "$family 12 bold italic"
$w.text tag configure big -font "$family 14 bold"







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# Only set the font family in one place for simplicity and consistency

set family Courier

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
	-width 70 -height 32 -wrap word -font "$family 12"
scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles

$w.text tag configure bold -font "$family 12 bold italic"
$w.text tag configure big -font "$family 14 bold"

Changes to library/demos/tcolor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# tcolor --
# This script implements a simple color editor, where you can
# create colors using either the RGB, HSB, or CYM color spaces
# and apply the color to existing applications.

package require Tk
wm title . "Color Editor"

# Global variables that control the program:
#
# colorSpace -			Color space currently being used for
#				editing.  Must be "rgb", "cmy", or "hsb".
# label1, label2, label3 -	Labels for the scales.









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# tcolor --
# This script implements a simple color editor, where you can
# create colors using either the RGB, HSB, or CYM color spaces
# and apply the color to existing applications.

package require Tk 8.4
wm title . "Color Editor"

# Global variables that control the program:
#
# colorSpace -			Color space currently being used for
#				editing.  Must be "rgb", "cmy", or "hsb".
# label1, label2, label3 -	Labels for the scales.
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    }
    set f [open $i]
    labelframe .names -text "Select:" -padx .1c -pady .1c
    grid .names -row 0 -column 0 -sticky nsew -padx .15c -pady .15c -rowspan 2
    grid columnconfigure . 0 -weight 1
    listbox .names.lb -width 20 -height 12 -yscrollcommand ".names.s set" \
	-exportselection false
    bind .names.lb <Double-Button-1> {
	    tc_loadNamedColor [.names.lb get [.names.lb curselection]]
    }
    scrollbar .names.s -orient vertical -command ".names.lb yview"
    pack .names.lb .names.s -side left -fill y -expand 1
    while {[gets $f line] >= 0} {
	if {[regexp {^\s*\d+\s+\d+\s+\d+\s+(\S+)$} $line -> col]} {
	    .names.lb insert end $col







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    }
    set f [open $i]
    labelframe .names -text "Select:" -padx .1c -pady .1c
    grid .names -row 0 -column 0 -sticky nsew -padx .15c -pady .15c -rowspan 2
    grid columnconfigure . 0 -weight 1
    listbox .names.lb -width 20 -height 12 -yscrollcommand ".names.s set" \
	-exportselection false
    bind .names.lb <Double-1> {
	    tc_loadNamedColor [.names.lb get [.names.lb curselection]]
    }
    scrollbar .names.s -orient vertical -command ".names.lb yview"
    pack .names.lb .names.s -side left -fill y -expand 1
    while {[gets $f line] >= 0} {
	if {[regexp {^\s*\d+\s+\d+\s+\d+\s+(\S+)$} $line -> col]} {
	    .names.lb insert end $col

Changes to library/demos/text.tcl.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Basic Facilities"
wm iconname $w "text"
positionWindow $w

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w {} \
	{ttk::button $w.buttons.fontchooser -command fontchooserToggle}]
pack $btns -side bottom -fill x

text $w.text -yscrollcommand [list $w.scroll set] -setgrid 1 \
	-height 30 -undo 1 -autosep 1
ttk::scrollbar $w.scroll -command [list $w.text yview]
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# TIP 324 Demo: [tk fontchooser]
proc fontchooserToggle {} {
    tk fontchooser [expr {[tk fontchooser configure -visible] ?
            "hide" : "show"}]
}
proc fontchooserVisibility {w} {
    $w configure -text [expr {[tk fontchooser configure -visible] ?
            "Hide Font Dialog" : "Show Font Dialog"}]
}
proc fontchooserFocus {w} {
    tk fontchooser configure -font [$w cget -font] \
	    -command [list fontchooserFontSel $w]
}
proc fontchooserFontSel {w font args} {
    $w configure -font [font actual $font]
}
tk fontchooser configure -parent $w
bind $w.text <FocusIn> [list fontchooserFocus $w.text]
fontchooserVisibility $w.buttons.fontchooser
bind $w <<TkFontchooserVisibility>> [list \
	fontchooserVisibility $w.buttons.fontchooser]
focus $w.text

$w.text insert 0.0 \
{This window is a text widget.  It displays one or more lines of text
and allows you to edit the text.  Here is a summary of the things you
can do to a text widget:

1. Scrolling. Use the scrollbar to adjust the view in the text window.

2. Scanning. Press the middle mouse button in the text window and drag up
or down. This will drag the text at high speed to allow you to scan its
contents.

3. Insert text. Press mouse button 1 to set the insertion cursor, then
type text.  What you type will be added to the widget.

4. Select. Press mouse button 1 and drag to select a range of characters.
Once you've released the button, you can adjust the selection by pressing
button 1 with the shift key down.  This will reset the end of the
selection nearest the mouse cursor and you can drag that end of the
selection by dragging the mouse before releasing the mouse button.
You can double-click to select whole words or triple-click to select
whole lines.

5. Delete and replace. To delete text, select the characters you'd like
to delete and type Backspace or Delete.  Alternatively, you can type new
text, in which case it will replace the selected text.

6. Copy the selection. To copy the selection into this window, select
what you want to copy (either here or in another application), then
click the middle mouse button to copy the selection to the point of the
mouse cursor.

7. Edit.  Text widgets support the standard Motif editing characters
plus many Emacs editing characters.  Backspace and Control-h erase the
character to the left of the insertion cursor.  Delete and Control-d
erase the character to the right of the insertion cursor.  Meta-backspace
deletes the word to the left of the insertion cursor, and Meta-d deletes
the word to the right of the insertion cursor.  Control-k deletes from







|
<




|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|
<


















|
<







13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
























28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Basic Facilities"
wm iconname $w "text"
positionWindow $w

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]

pack $btns -side bottom -fill x

text $w.text -yscrollcommand [list $w.scroll set] -setgrid 1 \
	-height 30 -undo 1 -autosep 1
scrollbar $w.scroll -command [list $w.text yview]
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both
























$w.text insert 0.0 \
{This window is a text widget.  It displays one or more lines of text
and allows you to edit the text.  Here is a summary of the things you
can do to a text widget:

1. Scrolling. Use the scrollbar to adjust the view in the text window.

2. Scanning. Press mouse button 2 in the text window and drag up or down.
This will drag the text at high speed to allow you to scan its contents.


3. Insert text. Press mouse button 1 to set the insertion cursor, then
type text.  What you type will be added to the widget.

4. Select. Press mouse button 1 and drag to select a range of characters.
Once you've released the button, you can adjust the selection by pressing
button 1 with the shift key down.  This will reset the end of the
selection nearest the mouse cursor and you can drag that end of the
selection by dragging the mouse before releasing the mouse button.
You can double-click to select whole words or triple-click to select
whole lines.

5. Delete and replace. To delete text, select the characters you'd like
to delete and type Backspace or Delete.  Alternatively, you can type new
text, in which case it will replace the selected text.

6. Copy the selection. To copy the selection into this window, select
what you want to copy (either here or in another application), then
click button 2 to copy the selection to the point of the mouse cursor.


7. Edit.  Text widgets support the standard Motif editing characters
plus many Emacs editing characters.  Backspace and Control-h erase the
character to the left of the insertion cursor.  Delete and Control-d
erase the character to the right of the insertion cursor.  Meta-backspace
deletes the word to the left of the insertion cursor, and Meta-d deletes
the word to the right of the insertion cursor.  Control-k deletes from

Changes to library/demos/textpeer.tcl.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

## Procedures to make and kill clones; most of this is just so that the demo
## looks nice...
proc makeClone {w parent} {
    global count
    set t [$parent peer create $w.text[incr count] -yscroll "$w.sb$count set"\
		  -height 10 -wrap word]
    set sb [ttk::scrollbar $w.sb$count -command "$t yview" -orient vertical]
    set b1 [button $w.clone$count -command "makeClone $w $t" \
		    -text "Make Peer"]
    set b2 [button $w.kill$count -command "killClone $w $count" \
		    -text "Delete Peer"]
    set row [expr {$count * 2}]
    grid $t $sb $b1 -sticky nsew -row $row
    grid ^  ^   $b2 -row [incr row]







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

## Procedures to make and kill clones; most of this is just so that the demo
## looks nice...
proc makeClone {w parent} {
    global count
    set t [$parent peer create $w.text[incr count] -yscroll "$w.sb$count set"\
		  -height 10 -wrap word]
    set sb [scrollbar $w.sb$count -command "$t yview" -orient vertical]
    set b1 [button $w.clone$count -command "makeClone $w $t" \
		    -text "Make Peer"]
    set b2 [button $w.kill$count -command "killClone $w $count" \
		    -text "Delete Peer"]
    set row [expr {$count * 2}]
    grid $t $sb $b1 -sticky nsew -row $row
    grid ^  ^   $b2 -row [incr row]

Changes to library/demos/toolbar.tcl.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
toplevel $w
wm title $w "Toolbar Demonstration"
wm iconname $w "toolbar"
positionWindow $w

ttk::label $w.msg -wraplength 4i -text "This is a demonstration of how to do\
	a toolbar that is styled correctly and which can be torn off. The\
	buttons are configured to be toolbar style buttons by\
	telling them that they are to use the Toolbutton style. At the left\
	end of the toolbar is a simple marker that the cursor changes to a\
	movement icon over; drag that away from the toolbar to tear off the\
	whole toolbar into a separate toplevel widget. When the dragged-off\
	toolbar is no longer needed, just close it like any normal toplevel\
	and it will reattach to the window it was torn off from."

## Set up the toolbar hull
set t [frame $w.toolbar]		;# Must be a frame!
ttk::separator $w.sep
ttk::frame $t.tearoff -cursor fleur
ttk::separator $t.tearoff.to -orient vertical
ttk::separator $t.tearoff.to2 -orient vertical
pack $t.tearoff.to -fill y -expand 1 -padx 4 -side left
pack $t.tearoff.to2 -fill y -expand 1 -side left
ttk::frame $t.contents
grid $t.tearoff $t.contents -sticky nsew
grid columnconfigure $t $t.contents -weight 1
grid columnconfigure $t.contents 1000 -weight 1

## Bindings so that the toolbar can be torn off and reattached







|













|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
toplevel $w
wm title $w "Toolbar Demonstration"
wm iconname $w "toolbar"
positionWindow $w

ttk::label $w.msg -wraplength 4i -text "This is a demonstration of how to do\
	a toolbar that is styled correctly and which can be torn off. The\
	buttons are configured to be \u201Ctoolbar style\u201D buttons by\
	telling them that they are to use the Toolbutton style. At the left\
	end of the toolbar is a simple marker that the cursor changes to a\
	movement icon over; drag that away from the toolbar to tear off the\
	whole toolbar into a separate toplevel widget. When the dragged-off\
	toolbar is no longer needed, just close it like any normal toplevel\
	and it will reattach to the window it was torn off from."

## Set up the toolbar hull
set t [frame $w.toolbar]		;# Must be a frame!
ttk::separator $w.sep
ttk::frame $t.tearoff -cursor fleur
ttk::separator $t.tearoff.to -orient vertical
ttk::separator $t.tearoff.to2 -orient vertical
pack $t.tearoff.to -fill y -expand 1 -padx 2 -side left
pack $t.tearoff.to2 -fill y -expand 1 -side left
ttk::frame $t.contents
grid $t.tearoff $t.contents -sticky nsew
grid columnconfigure $t $t.contents -weight 1
grid columnconfigure $t.contents 1000 -weight 1

## Bindings so that the toolbar can be torn off and reattached
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}

## Some content for the rest of the toplevel
text $w.txt -width 40 -height 10
interp alias {} doInsert {} $w.txt insert end	;# Make bindings easy to write

## Arrange contents
grid $t.button $t.check $t.menu $t.combo -in $t.contents -padx 2 -pady 4 -sticky ns
grid $t -sticky ew
grid $w.sep -sticky ew
grid $w.msg -sticky ew
grid $w.txt -sticky nsew
grid rowconfigure $w $w.txt -weight 1
grid columnconfigure $w $w.txt -weight 1

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
grid $btns -sticky ew







|










75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}

## Some content for the rest of the toplevel
text $w.txt -width 40 -height 10
interp alias {} doInsert {} $w.txt insert end	;# Make bindings easy to write

## Arrange contents
grid $t.button $t.check $t.menu $t.combo -in $t.contents -padx 2 -sticky ns
grid $t -sticky ew
grid $w.sep -sticky ew
grid $w.msg -sticky ew
grid $w.txt -sticky nsew
grid rowconfigure $w $w.txt -weight 1
grid columnconfigure $w $w.txt -weight 1

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
grid $btns -sticky ew

Changes to library/demos/tree.tcl.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
# tree.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .tree
catch {destroy $w}
toplevel $w
wm title $w "Directory Browser"
wm iconname $w "tree"
positionWindow $w










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# tree.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .tree
catch {destroy $w}
toplevel $w
wm title $w "Directory Browser"
wm iconname $w "tree"
positionWindow $w
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
proc populateTree {tree node} {
    if {[$tree set $node type] ne "directory"} {
	return
    }
    set path [$tree set $node fullpath]
    $tree delete [$tree children $node]
    foreach f [lsort -dictionary [glob -nocomplain -dir $path *]] {
	set f [file normalize $f]
	set type [file type $f]
	set id [$tree insert $node end -text [file tail $f] \
		-values [list $f $type]]

	if {$type eq "directory"} {
	    ## Make it so that this node is openable
	    $tree insert $id 0 -text dummy ;# a dummy







<







36
37
38
39
40
41
42

43
44
45
46
47
48
49
proc populateTree {tree node} {
    if {[$tree set $node type] ne "directory"} {
	return
    }
    set path [$tree set $node fullpath]
    $tree delete [$tree children $node]
    foreach f [lsort -dictionary [glob -nocomplain -dir $path *]] {

	set type [file type $f]
	set id [$tree insert $node end -text [file tail $f] \
		-values [list $f $type]]

	if {$type eq "directory"} {
	    ## Make it so that this node is openable
	    $tree insert $id 0 -text dummy ;# a dummy
68
69
70
71
72
73
74

75
76




77
78
79
80
81
82
83
84
85
86
87
88
89
    # Stop this code from rerunning on the current node
    $tree set $node type processedDirectory
}

## Create the tree and set it up
ttk::treeview $w.tree -columns {fullpath type size} -displaycolumns {size} \
	-yscroll "$w.vsb set" -xscroll "$w.hsb set"

ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"




$w.tree heading \#0 -text "Directory Structure"
$w.tree heading size -text "File Size"
$w.tree column size -width 70
populateRoots $w.tree
bind $w.tree <<TreeviewOpen>> {populateTree %W [%W focus]}

## Arrange the tree and its scrollbars in the toplevel
lower [ttk::frame $w.dummy]
pack $w.dummy -fill both -expand 1
grid $w.tree $w.vsb -sticky nsew -in $w.dummy
grid $w.hsb -sticky nsew -in $w.dummy
grid columnconfigure $w.dummy 0 -weight 1
grid rowconfigure $w.dummy 0 -weight 1







>
|
|
>
>
>
>


|










68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    # Stop this code from rerunning on the current node
    $tree set $node type processedDirectory
}

## Create the tree and set it up
ttk::treeview $w.tree -columns {fullpath type size} -displaycolumns {size} \
	-yscroll "$w.vsb set" -xscroll "$w.hsb set"
if {[tk windowingsystem] ne "aqua"} {
    ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
    ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
} else {
    scrollbar $w.vsb -orient vertical -command "$w.tree yview"
    scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
}
$w.tree heading \#0 -text "Directory Structure"
$w.tree heading size -text "File Size"
$w.tree column size -stretch 0 -width 70
populateRoots $w.tree
bind $w.tree <<TreeviewOpen>> {populateTree %W [%W focus]}

## Arrange the tree and its scrollbars in the toplevel
lower [ttk::frame $w.dummy]
pack $w.dummy -fill both -expand 1
grid $w.tree $w.vsb -sticky nsew -in $w.dummy
grid $w.hsb -sticky nsew -in $w.dummy
grid columnconfigure $w.dummy 0 -weight 1
grid rowconfigure $w.dummy 0 -weight 1

Changes to library/demos/ttkbut.tcl.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# ttkbut.tcl --
#
# This demonstration script creates a toplevel window containing several
# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and
# radiobuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .ttkbut
catch {destroy $w}
toplevel $w
wm title $w "Simple Ttk Widgets"
wm iconname $w "ttkbut"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Ttk is the new Tk themed widget set. This is a Ttk themed label, and below are three groups of Ttk widgets in Ttk labelframes. The first group are all buttons that set the current application theme when pressed. The second group contains three sets of checkbuttons, with a separator widget between the sets. Note that the Enabled button controls whether all the other themed widgets in this toplevel are in the disabled state. The third group has a collection of linked radiobuttons."
pack $w.msg -side top -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {enabled cheese tomato basil oregano happiness}]\
	-side bottom -fill x

## Add buttons for setting the theme
ttk::labelframe $w.buttons -text "Buttons"
foreach theme [ttk::themes] {
    ttk::button $w.buttons.$theme -text $theme \
	    -command [list ttk::setTheme $theme]











>








|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# ttkbut.tcl --
#
# This demonstration script creates a toplevel window containing several
# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and
# radiobuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .ttkbut
catch {destroy $w}
toplevel $w
wm title $w "Simple Ttk Widgets"
wm iconname $w "ttkbut"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Ttk is the new Tk themed widget set. This is a Ttk themed label, and below are three groups of Ttk widgets in Ttk labelframes. The first group are all buttons that set the current application theme when pressed. The second group contains three sets of checkbuttons, with a separator widget between the sets. Note that the \u201cEnabled\u201d button controls whether all the other themed widgets in this toplevel are in the disabled state. The third group has a collection of linked radiobuttons."
pack $w.msg -side top -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {enabled cheese tomato basil oregano happyness}]\
	-side bottom -fill x

## Add buttons for setting the theme
ttk::labelframe $w.buttons -text "Buttons"
foreach theme [ttk::themes] {
    ttk::button $w.buttons.$theme -text $theme \
	    -command [list ttk::setTheme $theme]
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
ttk::checkbutton $w.checks.c3 -text Basil   -variable basil
ttk::checkbutton $w.checks.c4 -text Oregano -variable oregano
pack $w.checks.e $w.checks.sep1 $w.checks.c1 $w.checks.c2 $w.checks.sep2 \
	$w.checks.c3 $w.checks.c4   -fill x -pady 2

## Set up the radiobutton group
ttk::labelframe $w.radios -text "Radiobuttons"
ttk::radiobutton $w.radios.r1 -text "Great" -variable happiness -value great
ttk::radiobutton $w.radios.r2 -text "Good" -variable happiness -value good
ttk::radiobutton $w.radios.r3 -text "OK" -variable happiness -value ok
ttk::radiobutton $w.radios.r4 -text "Poor" -variable happiness -value poor
ttk::radiobutton $w.radios.r5 -text "Awful" -variable happiness -value awful
pack $w.radios.r1 $w.radios.r2 $w.radios.r3 $w.radios.r4 $w.radios.r5 \
	-fill x -padx 3 -pady 2

## Arrange things neatly
pack [ttk::frame $w.f] -fill both -expand 1
lower $w.f
grid $w.buttons $w.checks $w.radios -in $w.f -sticky nwe -pady 2 -padx 3
grid columnconfigure $w.f {0 1 2} -weight 1 -uniform yes







|
|
|
|
|








66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
ttk::checkbutton $w.checks.c3 -text Basil   -variable basil
ttk::checkbutton $w.checks.c4 -text Oregano -variable oregano
pack $w.checks.e $w.checks.sep1 $w.checks.c1 $w.checks.c2 $w.checks.sep2 \
	$w.checks.c3 $w.checks.c4   -fill x -pady 2

## Set up the radiobutton group
ttk::labelframe $w.radios -text "Radiobuttons"
ttk::radiobutton $w.radios.r1 -text "Great" -variable happyness -value great
ttk::radiobutton $w.radios.r2 -text "Good" -variable happyness -value good
ttk::radiobutton $w.radios.r3 -text "OK" -variable happyness -value ok
ttk::radiobutton $w.radios.r4 -text "Poor" -variable happyness -value poor
ttk::radiobutton $w.radios.r5 -text "Awful" -variable happyness -value awful
pack $w.radios.r1 $w.radios.r2 $w.radios.r3 $w.radios.r4 $w.radios.r5 \
	-fill x -padx 3 -pady 2

## Arrange things neatly
pack [ttk::frame $w.f] -fill both -expand 1
lower $w.f
grid $w.buttons $w.checks $w.radios -in $w.f -sticky nwe -pady 2 -padx 3
grid columnconfigure $w.f {0 1 2} -weight 1 -uniform yes

Changes to library/demos/ttkmenu.tcl.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
# ttkmenu.tcl --
#
# This demonstration script creates a toplevel window containing several Ttk
# menubutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .ttkmenu
catch {destroy $w}
toplevel $w
wm title $w "Ttk Menu Buttons"
wm iconname $w "ttkmenu"
positionWindow $w










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ttkmenu.tcl --
#
# This demonstration script creates a toplevel window containing several Ttk
# menubutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .ttkmenu
catch {destroy $w}
toplevel $w
wm title $w "Ttk Menu Buttons"
wm iconname $w "ttkmenu"
positionWindow $w

Changes to library/demos/ttknote.tcl.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
# ttknote.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# notebook widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .ttknote
catch {destroy $w}
toplevel $w
wm title $w "Ttk Notebook Widget"
wm iconname $w "ttknote"
positionWindow $w










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ttknote.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# notebook widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .ttknote
catch {destroy $w}
toplevel $w
wm title $w "Ttk Notebook Widget"
wm iconname $w "ttknote"
positionWindow $w
48
49
50
51
52
53
54

55



56
57
$w.note add $w.note.disabled -text "Disabled" -state disabled

## Popuplate the third pane
ttk::frame $w.note.editor
$w.note add $w.note.editor -text "Text Editor" -underline 0
text $w.note.editor.t -width 40 -height 10 -wrap char \
	-yscroll "$w.note.editor.s set"

ttk::scrollbar $w.note.editor.s -orient vertical -command "$w.note.editor.t yview"



pack $w.note.editor.s -side right -fill y -padx {0 2} -pady 2
pack $w.note.editor.t -fill both -expand 1 -pady 2 -padx {2 0}







>
|
>
>
>


49
50
51
52
53
54
55
56
57
58
59
60
61
62
$w.note add $w.note.disabled -text "Disabled" -state disabled

## Popuplate the third pane
ttk::frame $w.note.editor
$w.note add $w.note.editor -text "Text Editor" -underline 0
text $w.note.editor.t -width 40 -height 10 -wrap char \
	-yscroll "$w.note.editor.s set"
if {[tk windowingsystem] ne "aqua"} {
    ttk::scrollbar $w.note.editor.s -orient vertical -command "$w.note.editor.t yview"
} else {
    scrollbar $w.note.editor.s -orient vertical -command "$w.note.editor.t yview"
}
pack $w.note.editor.s -side right -fill y -padx {0 2} -pady 2
pack $w.note.editor.t -fill both -expand 1 -pady 2 -padx {2 0}

Changes to library/demos/ttkpane.tcl.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
# ttkpane.tcl --
#
# This demonstration script creates a Ttk pane with some content.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .ttkpane
catch {destroy $w}
toplevel $w
wm title $w "Themed Nested Panes"
wm iconname $w "ttkpane"
positionWindow $w









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ttkpane.tcl --
#
# This demonstration script creates a Ttk pane with some content.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .ttkpane
catch {destroy $w}
toplevel $w
wm title $w "Themed Nested Panes"
wm iconname $w "ttkpane"
positionWindow $w
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

# Fill the clocks pane
set i 0
proc every {delay script} {
    uplevel #0 $script
    after $delay [list every $delay $script]
}
set testzones {
    :Europe/Berlin
    :America/Argentina/Buenos_Aires
    :Africa/Johannesburg
    :Europe/London
    :America/Los_Angeles
    :Europe/Moscow
    :America/New_York
    :Asia/Singapore
    :Australia/Sydney
    :Asia/Tokyo
}
# Force a pre-load of all the timezones needed; otherwise can end up
# poor-looking synch problems!
set zones {}
foreach zone $testzones {
    if {![catch {clock format 0 -timezone $zone}]} {
        lappend zones $zone
    }
}
if {[llength $zones] < 2} { lappend zones -0200 :GMT :UTC +0200 }
foreach zone $zones {
    set city [string map {_ " "} [regexp -inline {[^/]+$} $zone]]
    if {$i} {
	pack [ttk::separator $w.outer.inLeft.bot.s$i] -fill x
    }
    ttk::label $w.outer.inLeft.bot.l$i -text $city -anchor w
    ttk::label $w.outer.inLeft.bot.t$i -textvariable time($zone) -anchor w







|













<
<
|
<
<
<
<







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67


68




69
70
71
72
73
74
75

# Fill the clocks pane
set i 0
proc every {delay script} {
    uplevel #0 $script
    after $delay [list every $delay $script]
}
set zones {
    :Europe/Berlin
    :America/Argentina/Buenos_Aires
    :Africa/Johannesburg
    :Europe/London
    :America/Los_Angeles
    :Europe/Moscow
    :America/New_York
    :Asia/Singapore
    :Australia/Sydney
    :Asia/Tokyo
}
# Force a pre-load of all the timezones needed; otherwise can end up
# poor-looking synch problems!


foreach zone $zones {clock format 0 -timezone $zone}




foreach zone $zones {
    set city [string map {_ " "} [regexp -inline {[^/]+$} $zone]]
    if {$i} {
	pack [ttk::separator $w.outer.inLeft.bot.s$i] -fill x
    }
    ttk::label $w.outer.inLeft.bot.l$i -text $city -anchor w
    ttk::label $w.outer.inLeft.bot.t$i -textvariable time($zone) -anchor w
100
101
102
103
104
105
106
107
108
109
110
111
112
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot.f	-pady 2 -padx 2
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.outer.inRight.bot.f -fill both -expand 1
    pack $w.outer -fill both -expand 1
} else {
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30 -borderwidth 0
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot
    pack $w.outer -fill both -expand 1 -padx 10 -pady {6 10}
}








|





95
96
97
98
99
100
101
102
103
104
105
106
107
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot.f	-pady 2 -padx 2
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.outer.inRight.bot.f -fill both -expand 1
    pack $w.outer -fill both -expand 1
} else {
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30 -borderwidth 0
    scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot
    pack $w.outer -fill both -expand 1 -padx 10 -pady {6 10}
}

Changes to library/demos/ttkprogress.tcl.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# ttkprogress.tcl --
#
# This demonstration script creates several progress bar widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk


set w .ttkprogress
catch {destroy $w}
toplevel $w
wm title $w "Progress Bar Demonstration"
wm iconname $w "ttkprogress"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Below are two progress bars. The top one is a determinate progress bar, which is used for showing how far through a defined task the program has got. The bottom one is an indeterminate progress bar, which is used to show that the program is busy but does not know how long for. Both are run here in self-animated mode, which can be turned on and off using the buttons underneath."
pack $w.msg -side top -fill x

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

ttk::frame $w.f









>








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ttkprogress.tcl --
#
# This demonstration script creates several progress bar widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk
package require Ttk

set w .ttkprogress
catch {destroy $w}
toplevel $w
wm title $w "Progress Bar Demonstration"
wm iconname $w "ttkprogress"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Below are two progress bars. The top one is a \u201Cdeterminate\u201D progress bar, which is used for showing how far through a defined task the program has got. The bottom one is an \u201Cindeterminate\u201D progress bar, which is used to show that the program is busy but does not know how long for. Both are run here in self-animated mode, which can be turned on and off using the buttons underneath."
pack $w.msg -side top -fill x

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

ttk::frame $w.f

Changes to library/demos/twind.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# twind.tcl --
#
# This demonstration script creates a text widget with a bunch of
# embedded windows.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# Make an Aqua button's fill color match its parent's background
proc blend {bt} {
    if {[tk windowingsystem] eq "aqua"} {
	$bt configure -highlightbackground [[winfo parent $bt] cget -background]
    }
    return $bt
}

set w .twind
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Embedded Windows and Other Features"
wm iconname $w "Embedded Windows"
positionWindow $w

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
set t $w.f.text
text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \
	-height 35 -wrap word -highlightthickness 0 -borderwidth 0
pack $t -expand  yes -fill both
ttk::scrollbar $w.scroll -command "$t yview"
pack $w.scroll -side right -fill y
panedwindow $w.pane
pack $w.pane -expand yes -fill both
$w.pane add $w.f
# Import to raise given creation order above
raise $w.f












<
<
<
<
<
<
<
<
















|







1
2
3
4
5
6
7
8
9
10
11








12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# twind.tcl --
#
# This demonstration script creates a text widget with a bunch of
# embedded windows.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk









set w .twind
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Embedded Windows and Other Features"
wm iconname $w "Embedded Windows"
positionWindow $w

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
set t $w.f.text
text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \
	-height 35 -wrap word -highlightthickness 0 -borderwidth 0
pack $t -expand  yes -fill both
scrollbar $w.scroll -command "$t yview"
pack $w.scroll -side right -fill y
panedwindow $w.pane
pack $w.pane -expand yes -fill both
$w.pane add $w.f
# Import to raise given creation order above
raise $w.f

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
$t insert end "scrolling in all directions is provided.\n\n"

$t insert end "A text widget can contain other widgets embedded "
$t insert end "it.  These are called \"embedded windows\", "
$t insert end "and they can consist of arbitrary widgets.  "
$t insert end "For example, here are two embedded button "
$t insert end "widgets.  You can click on the first button to "
$t window create end -window [blend $t.on]
$t insert end " horizontal scrolling, which also turns off "
$t insert end "word wrapping.  Or, you can click on the second "
$t insert end "button to\n"
$t window create end -window [blend $t.off]
$t insert end " horizontal scrolling and turn back on word wrapping.\n\n"

$t insert end "Or, here is another example.  If you "
$t window create end -create {
    button %W.click -text "Click Here" -command "textWindPlot %W" \
	-cursor top_left_arrow
    blend %W.click
}

$t insert end " a canvas displaying an x-y plot will appear right here."
$t mark set plot insert
$t mark gravity plot left
$t insert end "  You can drag the data points around with the mouse, "
$t insert end "or you can click here to "
$t window create end -create {
    button %W.delete -text "Delete" -command "textWindDel %W" \
	-cursor top_left_arrow
    blend %W.delete
}
$t insert end " the plot again.\n\n"

$t insert end "You can also create multiple text widgets each of which "
$t insert end "display the same underlying text. Click this button to "
$t window create end \
  -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \
	       -cursor top_left_arrow
      blend %W.peer} -padx 3
$t insert end " widget.  Notice how peer widgets can have different "
$t insert end "font settings, and by default contain all the images "
$t insert end "of the 'parent', but that the embedded windows, "
$t insert end "such as buttons may not appear in the peer.  To ensure "
$t insert end "that embedded windows appear in all peers you can set the "
$t insert end "'-create' option to a script or a string containing %W.  "
$t insert end "(The plot above and the 'Make A Peer' button are "
$t insert end "designed to show up in all peers.)  A good use of "
$t insert end "peers is for "
$t window create end \
  -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \
	       -cursor top_left_arrow
      blend %W.split} -padx 3
$t insert end " \n\n"

$t insert end "Users of previous versions of Tk will also be interested "
$t insert end "to note that now cursor movement is now by visual line by "
$t insert end "default, and that all scrolling of this widget is by pixel.\n\n"

$t insert end "You may also find it useful to put embedded windows in "
$t insert end "a text without any actual text.  In this case the "
$t insert end "text widget acts like a geometry manager.  For "
$t insert end "example, here is a collection of buttons laid out "
$t insert end "neatly into rows by the text widget.  These buttons "
$t insert end "can be used to change the background color of the "
$t insert end "text widget (\"Default\" restores the color to "
$t insert end "its default).  If you click on the button labeled "
$t insert end "\"Short\", it changes to a longer string so that "
$t insert end "you can see how the text widget automatically "
$t insert end "changes the layout.  Click on the button again "
$t insert end "to restore the short string.\n"

$t insert end "\nNOTE: these buttons will not appear in peers!\n" "peer_warning"
button $t.default -text Default -command "embDefBg $t" \
	-cursor top_left_arrow
$t window create end -window $t.default -padx 3
global embToggle
set embToggle Short
checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \
	-variable embToggle -onvalue "A much longer string" \
	-offvalue "Short" -cursor top_left_arrow -pady 5 -padx 2
$t window create end -window $t.toggle -padx 3 -pady 2
set i 1
foreach color {AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4
	SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3 LightBlue1
	DarkSlateGray1 Aquamarine2 DarkSeaGreen2 SeaGreen1
	Yellow1 IndianRed1 IndianRed2 Tan1 Tan4} {
    button $t.color$i -text $color -cursor top_left_arrow -command \
	    "changeBg $t $color"
    $t window create end -window [blend $t.color$i] -padx 3 -pady 2
    incr i
}
$t tag add buttons [blend $t.default] end

button $t.bigB -text "Big borders" -command "textWindBigB $t" \
  -cursor top_left_arrow
button $t.smallB -text "Small borders" -command "textWindSmallB $t" \
  -cursor top_left_arrow
button $t.bigH -text "Big highlight" -command "textWindBigH $t" \
  -cursor top_left_arrow
button $t.smallH -text "Small highlight" -command "textWindSmallH $t" \
  -cursor top_left_arrow
button $t.bigP -text "Big pad" -command "textWindBigP $t" \
  -cursor top_left_arrow
button $t.smallP -text "Small pad" -command "textWindSmallP $t" \
  -cursor top_left_arrow

set text_normal(border) [$t cget -borderwidth]
set text_normal(highlight) [$t cget -highlightthickness]
set text_normal(pad) [$t cget -padx]

$t insert end "\nYou can also change the usual border width and "
$t insert end "highlightthickness and padding.\n"
$t window create end -window [blend $t.bigB]
$t window create end -window [blend $t.smallB]
$t window create end -window [blend $t.bigH]
$t window create end -window [blend $t.smallH]
$t window create end -window [blend $t.bigP]
$t window create end -window [blend $t.smallP]

$t insert end "\n\nFinally, images fit comfortably in text widgets too:"

$t image create end -image \
    [image create photo -file [file join $tk_demoDirectory images ouster.png]]


proc textWindBigB w {
    $w configure -borderwidth 15
}

proc textWindBigH w {
    $w configure -highlightthickness 15
}

proc textWindBigP w {







|



|





|
<
<








|
<







|
<


|
|
|
|
|
|



|
<



















<















|
|


|




















|
|
|
|
|
|




|

>

|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
$t insert end "scrolling in all directions is provided.\n\n"

$t insert end "A text widget can contain other widgets embedded "
$t insert end "it.  These are called \"embedded windows\", "
$t insert end "and they can consist of arbitrary widgets.  "
$t insert end "For example, here are two embedded button "
$t insert end "widgets.  You can click on the first button to "
$t window create end -window $t.on
$t insert end " horizontal scrolling, which also turns off "
$t insert end "word wrapping.  Or, you can click on the second "
$t insert end "button to\n"
$t window create end -window $t.off
$t insert end " horizontal scrolling and turn back on word wrapping.\n\n"

$t insert end "Or, here is another example.  If you "
$t window create end -create {
    button %W.click -text "Click Here" -command "textWindPlot %W" \
	    -cursor top_left_arrow}



$t insert end " a canvas displaying an x-y plot will appear right here."
$t mark set plot insert
$t mark gravity plot left
$t insert end "  You can drag the data points around with the mouse, "
$t insert end "or you can click here to "
$t window create end -create {
    button %W.delete -text "Delete" -command "textWindDel %W" \
	    -cursor top_left_arrow

}
$t insert end " the plot again.\n\n"

$t insert end "You can also create multiple text widgets each of which "
$t insert end "display the same underlying text. Click this button to "
$t window create end \
  -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \
  -cursor top_left_arrow} -padx 3

$t insert end " widget.  Notice how peer widgets can have different "
$t insert end "font settings, and by default contain all the images "
$t insert end "of the 'parent', but many of the embedded windows, "
$t insert end "such as buttons will not be there.  The easiest way "
$t insert end "to ensure they are in all peers is to use '-create' "
$t insert end "embedded window creation scripts "
$t insert end "(the plot above and the 'Make A Peer' button are "
$t insert end "designed to show up in all peers).  A good use of "
$t insert end "peers is for "
$t window create end \
  -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \
  -cursor top_left_arrow} -padx 3

$t insert end " \n\n"

$t insert end "Users of previous versions of Tk will also be interested "
$t insert end "to note that now cursor movement is now by visual line by "
$t insert end "default, and that all scrolling of this widget is by pixel.\n\n"

$t insert end "You may also find it useful to put embedded windows in "
$t insert end "a text without any actual text.  In this case the "
$t insert end "text widget acts like a geometry manager.  For "
$t insert end "example, here is a collection of buttons laid out "
$t insert end "neatly into rows by the text widget.  These buttons "
$t insert end "can be used to change the background color of the "
$t insert end "text widget (\"Default\" restores the color to "
$t insert end "its default).  If you click on the button labeled "
$t insert end "\"Short\", it changes to a longer string so that "
$t insert end "you can see how the text widget automatically "
$t insert end "changes the layout.  Click on the button again "
$t insert end "to restore the short string.\n"


button $t.default -text Default -command "embDefBg $t" \
	-cursor top_left_arrow
$t window create end -window $t.default -padx 3
global embToggle
set embToggle Short
checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \
	-variable embToggle -onvalue "A much longer string" \
	-offvalue "Short" -cursor top_left_arrow -pady 5 -padx 2
$t window create end -window $t.toggle -padx 3 -pady 2
set i 1
foreach color {AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4
	SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3 LightBlue1
	DarkSlateGray1 Aquamarine2 DarkSeaGreen2 SeaGreen1
	Yellow1 IndianRed1 IndianRed2 Tan1 Tan4} {
    button $t.color$i -text $color -cursor top_left_arrow -command \
	    "$t configure -bg $color"
    $t window create end -window $t.color$i -padx 3 -pady 2
    incr i
}
$t tag add buttons $t.default end

button $t.bigB -text "Big borders" -command "textWindBigB $t" \
  -cursor top_left_arrow
button $t.smallB -text "Small borders" -command "textWindSmallB $t" \
  -cursor top_left_arrow
button $t.bigH -text "Big highlight" -command "textWindBigH $t" \
  -cursor top_left_arrow
button $t.smallH -text "Small highlight" -command "textWindSmallH $t" \
  -cursor top_left_arrow
button $t.bigP -text "Big pad" -command "textWindBigP $t" \
  -cursor top_left_arrow
button $t.smallP -text "Small pad" -command "textWindSmallP $t" \
  -cursor top_left_arrow

set text_normal(border) [$t cget -borderwidth]
set text_normal(highlight) [$t cget -highlightthickness]
set text_normal(pad) [$t cget -padx]

$t insert end "\nYou can also change the usual border width and "
$t insert end "highlightthickness and padding.\n"
$t window create end -window $t.bigB
$t window create end -window $t.smallB
$t window create end -window $t.bigH
$t window create end -window $t.smallH
$t window create end -window $t.bigP
$t window create end -window $t.smallP

$t insert end "\n\nFinally, images fit comfortably in text widgets too:"

$t image create end -image \
  [image create bitmap -file [file join $tk_demoDirectory images face.xbm]]


proc textWindBigB w {
    $w configure -borderwidth 15 
}

proc textWindBigH w {
    $w configure -highlightthickness 15
}

proc textWindBigP w {
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213
214
215
proc textWindSmallH w {
    $w configure -highlightthickness $::text_normal(highlight)
}

proc textWindSmallP w {
    $w configure -padx $::text_normal(pad) -pady $::text_normal(pad)
}


proc textWindOn w {
    catch {destroy $w.scroll2}
    set t $w.f.text
    ttk::scrollbar $w.scroll2 -orient horizontal -command "$t xview"
    pack $w.scroll2 -after $w.buttons -side bottom -fill x
    $t configure -xscrollcommand "$w.scroll2 set" -wrap none
}

proc textWindOff w {
    catch {destroy $w.scroll2}
    set t $w.f.text







>




|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
proc textWindSmallH w {
    $w configure -highlightthickness $::text_normal(highlight)
}

proc textWindSmallP w {
    $w configure -padx $::text_normal(pad) -pady $::text_normal(pad)
}


proc textWindOn w {
    catch {destroy $w.scroll2}
    set t $w.f.text
    scrollbar $w.scroll2 -orient horizontal -command "$t xview"
    pack $w.scroll2 -after $w.buttons -side bottom -fill x
    $t configure -xscrollcommand "$w.scroll2 set" -wrap none
}

proc textWindOff w {
    catch {destroy $w.scroll2}
    set t $w.f.text
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
    canvas $c -relief sunken -width 450 -height 300 -cursor top_left_arrow

    set font {Helvetica 18}

    $c create line 100 250 400 250 -width 2
    $c create line 100 250 100 50 -width 2
    $c create text 225 20 -text "A Simple Plot" -font $font -fill brown

    for {set i 0} {$i <= 10} {incr i} {
	set x [expr {100 + ($i*30)}]
	$c create line $x 250 $x 245 -width 2
	$c create text $x 254 -text [expr {10*$i}] -anchor n -font $font
    }
    for {set i 0} {$i <= 5} {incr i} {
	set y [expr {250 - ($i*40)}]
	$c create line 100 $y 105 $y -width 2
	$c create text 96 $y -text [expr {$i*50}].0 -anchor e -font $font
    }

    foreach point {
	{12 56} {20 94} {33 98} {32 120} {61 180} {75 160} {98 223}
    } {
	set x [expr {100 + (3*[lindex $point 0])}]
	set y [expr {250 - (4*[lindex $point 1])/5}]
	set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
		[expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
		-fill SkyBlue2]
	$c addtag point withtag $item
    }

    $c bind point <Enter> "$c itemconfig current -fill red"
    $c bind point <Leave> "$c itemconfig current -fill SkyBlue2"
    $c bind point <Button-1> "embPlotDown $c %x %y"
    $c bind point <ButtonRelease-1> "$c dtag selected"
    bind $c <B1-Motion> "embPlotMove $c %x %y"
    return $c
}

set embPlot(lastX) 0
set embPlot(lastY) 0







|










|











|
|
|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    canvas $c -relief sunken -width 450 -height 300 -cursor top_left_arrow

    set font {Helvetica 18}

    $c create line 100 250 400 250 -width 2
    $c create line 100 250 100 50 -width 2
    $c create text 225 20 -text "A Simple Plot" -font $font -fill brown
    
    for {set i 0} {$i <= 10} {incr i} {
	set x [expr {100 + ($i*30)}]
	$c create line $x 250 $x 245 -width 2
	$c create text $x 254 -text [expr {10*$i}] -anchor n -font $font
    }
    for {set i 0} {$i <= 5} {incr i} {
	set y [expr {250 - ($i*40)}]
	$c create line 100 $y 105 $y -width 2
	$c create text 96 $y -text [expr {$i*50}].0 -anchor e -font $font
    }
    
    foreach point {
	{12 56} {20 94} {33 98} {32 120} {61 180} {75 160} {98 223}
    } {
	set x [expr {100 + (3*[lindex $point 0])}]
	set y [expr {250 - (4*[lindex $point 1])/5}]
	set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
		[expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
		-fill SkyBlue2]
	$c addtag point withtag $item
    }

    $c bind point <Any-Enter> "$c itemconfig current -fill red"
    $c bind point <Any-Leave> "$c itemconfig current -fill SkyBlue2"
    $c bind point <1> "embPlotDown $c %x %y"
    $c bind point <ButtonRelease-1> "$c dtag selected"
    bind $c <B1-Motion> "embPlotMove $c %x %y"
    return $c
}

set embPlot(lastX) 0
set embPlot(lastY) 0
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
	while {[string first [$t get plot] " \t\n"] >= 0} {
	    $t delete plot
	}
	$t insert plot "  "
    }
}

proc changeBg {t c} {
    $t configure -background $c
    if {[tk windowingsystem] eq "aqua"} {
	foreach b [$t window names] {
	    if {[winfo class $b] eq "Button"} {
		$b configure -highlightbackground $c
	    }
	}
    }
}

proc embDefBg t {
    set bg [lindex [$t configure -background] 3]
    changeBg $t $bg
}

proc textMakePeer {parent} {
    set n 1
    while {[winfo exists .peer$n]} { incr n }
    set w [toplevel .peer$n]
    wm title $w "Text Peer #$n"
    frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
    set t [$parent peer create $w.f.text -yscrollcommand "$w.scroll set" \
	       -borderwidth 0 -highlightthickness 0]
    $t tag configure peer_warning -font boldFont
    pack $t -expand  yes -fill both
    ttk::scrollbar $w.scroll -command "$t yview"
    pack $w.scroll -side right -fill y
    pack $w.f -expand yes -fill both
}

proc textSplitWindow {textW} {
    if {$textW eq ".twind.f.text"} {
	if {[winfo exists .twind.peer]} {
	    destroy .twind.peer
	} else {
	    set parent [winfo parent $textW]
	    set w [winfo parent $parent]
	    set t [$textW peer create $w.peer \
	      -yscrollcommand "$w.scroll set"]
	    $t tag configure peer_warning -font boldFont
	    $w.pane add $t
	}
    } else {
        return
    }
}







<
<
<
<
<
<
<
<
<
<
<

|
<










<

|













<






286
287
288
289
290
291
292











293
294

295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
	while {[string first [$t get plot] " \t\n"] >= 0} {
	    $t delete plot
	}
	$t insert plot "  "
    }
}












proc embDefBg t {
    $t configure -background [lindex [$t configure -background] 3]

}

proc textMakePeer {parent} {
    set n 1
    while {[winfo exists .peer$n]} { incr n }
    set w [toplevel .peer$n]
    wm title $w "Text Peer #$n"
    frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
    set t [$parent peer create $w.f.text -yscrollcommand "$w.scroll set" \
	       -borderwidth 0 -highlightthickness 0]

    pack $t -expand  yes -fill both
    scrollbar $w.scroll -command "$t yview"
    pack $w.scroll -side right -fill y
    pack $w.f -expand yes -fill both
}

proc textSplitWindow {textW} {
    if {$textW eq ".twind.f.text"} {
	if {[winfo exists .twind.peer]} {
	    destroy .twind.peer
	} else {
	    set parent [winfo parent $textW]
	    set w [winfo parent $parent]
	    set t [$textW peer create $w.peer \
	      -yscrollcommand "$w.scroll set"]

	    $w.pane add $t
	}
    } else {
        return
    }
}

Changes to library/demos/unicodeout.tcl.

1
2
3
4
5
6
7
8
9
10




















11
12
13
14
15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31

32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99


100
101
102


103
104
105
106
107


108

109
110


111
112
113


114
115
116
117


118
119
120
121

122
123
124
125
126
# unicodeout.tcl --
#
# This demonstration script shows how you can produce output (in label
# widgets) using many different alphabets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk





















set w .unicodeout
catch {destroy $w}
toplevel $w
wm title $w "Unicode Label Demonstration"
wm iconname $w "unicodeout"
positionWindow $w

label $w.msg -font $font -wraplength 4i -anchor w -justify left \
	-text "This is a sample of Tk's support for languages that use\
	non-Western character sets.  However, what you will actually see\
	below depends largely on what character sets you have installed,\
	and what you see for characters that are not present varies greatly\
	between platforms as well."


pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

## The frame that will contain the sample texts.

pack [frame $w.f] -side bottom -expand 1 -fill both -padx 2m -pady 1m
grid columnconfigure $w.f 1 -weight 1

set i 0
proc addSample {w language args} {
    global font i
    set sample [join $args ""]
    set j [incr i]
    label $w.f.l$j -font $font -text "${language}:" -anchor nw -pady 0
    label $w.f.s$j -font $font -text $sample -anchor nw -width 30 -pady 0
    grid $w.f.l$j $w.f.s$j -sticky ew -pady 0
    grid configure $w.f.l$j -padx 1m
}

## A helper procedure that determines what form to use to express languages
## that have complex rendering rules...
proc usePresentationFormsFor {language} {
    switch [tk windowingsystem] {
	aqua {
	    # OSX wants natural character order; the renderer knows how to
	    # compose things for display for all languages.
	    return false
	}
	x11 {
	    # The X11 font renderers that Tk supports all know nothing about
	    # composing characters, so we need to use presentation forms.
	    return true
	}
	win32 {
	    # On Windows, we need to determine whether the font system will
	    # render right-to-left text. This varies by language!
	    try {
		package require registry
		set rkey [join {
		    HKEY_LOCAL_MACHINE
		    SOFTWARE
		    Microsoft
		    {Windows NT}
		    CurrentVersion
		    LanguagePack
		} \\]
		return [expr {
		    [string toupper $language] ni [registry values $rkey]
		}]
	    } trap error {} {
		# Cannot work it out, so use presentation forms.
		return true
	    }
	}
	default {
	    # Default to using presentation forms.
	    return true
	}
    }
}

## Processing when some characters are not currently cached by the display
## engine might take a while, so make sure we're displaying something in the
## meantime...
pack [label $w.wait -text "Please wait while loading fonts..." \
	-font {Helvetica 12 italic}]
set oldCursor [$w cget -cursor]
$w conf -cursor watch
update

## Add the samples...
if {[usePresentationFormsFor Arabic]} {

    # Using presentation forms (pre-layouted)
    addSample $w Arabic "ﺔﻴﺑﺮﻌﻟﺍ ﺔﻤﻠﻜﻟﺍ"


} else {
    # Using standard text characters
    addSample $w Arabic "الكلمة العربية"


}
addSample $w "Trad. Chinese"  "中國的漢字"
addSample $w "Simpl. Chinese" "汉语"
addSample $w French "Langue française"
addSample $w Greek "Ελληνική γλώσσα"


if {[usePresentationFormsFor Hebrew]} {

    # Visual order (pre-layouted)
    addSample $w Hebrew "תירבע בתכ"


} else {
    # Standard logical order
    addSample $w Hebrew "כתב עברית"


}
addSample $w Hindi "हिन्दी भाषा"
addSample $w Icelandic "Íslenska"
addSample $w Japanese "日本語のひらがな, 漢字とカタカナ"


addSample $w Korean "대한민국의 한글"
addSample $w Russian "Русский язык"
if {([tk windowingsystem] ne "x11") || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))} {
    addSample $w Emoji "😀💩👍🇳🇱"

}

## We're done processing, so change things back to normal running...
destroy $w.wait
$w conf -cursor $oldCursor










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|
>
>






|
>
|

>











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<




<
|
>

|
>
>


|
>
>

|
|
<
|
>
>
|
>

|
>
>


|
>
>

<
<
|
>
>
|
|
<
<
>
|
<
|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68










































69
70
71


72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


105
106
107
108
109


110
111

112
113
114
# unicodeout.tcl --
#
# This demonstration script shows how you can produce output (in label
# widgets) using many different alphabets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# On Windows, we need to determine whether the font system will render
# right-to-left text.

if {[tk windowingsystem] eq {win32}} {
    set rkey [join {
	HKEY_LOCAL_MACHINE
	SOFTWARE
	Microsoft
	{Windows NT}
	CurrentVersion
	LanguagePack
    } \\]
    set w32langs {}
    if {![catch {package require registry}]} {
	if {[catch {registry values $rkey} w32langs]} {
	    set w32langs {}
	}
    }
}

set w .unicodeout
catch {destroy $w}
toplevel $w
wm title $w "Unicode Label Demonstration"
wm iconname $w "unicodeout"
positionWindow $w

label $w.msg -font $font -wraplength 4i -anchor w -justify left \
	-text "This is a sample of Tk's support for languages that use\
	non-Western character sets.  However, what you will actually see\
	below depends largely on what character sets you have installed,\
	and what you see for characters that are not present varies greatly\
	between platforms as well.  The strings are written in Tcl using\
	UNICODE characters using the \\uXXXX escape so as to do so in a\
	portable fashion."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

pack [label $w.wait -text "Please wait while loading fonts..." \
	-font {Helvetica 12 italic}]
pack [frame $w.f] -expand 1 -fill both -padx 2m -pady 1m
grid columnconfigure $w.f 1 -weight 1

set i 0
proc addSample {w language args} {
    global font i
    set sample [join $args ""]
    set j [incr i]
    label $w.f.l$j -font $font -text "${language}:" -anchor nw -pady 0
    label $w.f.s$j -font $font -text $sample -anchor nw -width 30 -pady 0
    grid $w.f.l$j $w.f.s$j -sticky ew -pady 0
    grid configure $w.f.l$j -padx 1m
}











































# Processing when some characters are missing might take a while, so make
# sure we're displaying something in the meantime...



set oldCursor [$w cget -cursor]
$w conf -cursor watch
update


if {[tk windowingsystem] eq {x11}
    || (([tk windowingsystem] eq {win32}) && ({ARABIC} ni $w32langs))} {
    # Using presentation forms (pre-layouted)
    addSample $w Arabic \
	"\uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D " \
	"\uFE94\uFEE4\uFEE0\uFEDC\uFEDF\uFE8D"
} else {
    # Using standard text characters
    addSample $w Arabic \
	"\u0627\u0644\u0643\u0644\u0645\u0629 " \
	"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"
}
addSample $w "Trad. Chinese" "\u4E2D\u570B\u7684\u6F22\u5B57"
addSample $w "Simpl. Chinese" "\u6C49\u8BED"

addSample $w Greek \
	 "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AE " \
	 "\u03B3\u03BB\u03CE\u03C3\u03C3\u03B1"
if {[tk windowingsystem] eq {x11}
    || (([tk windowingsystem] eq {win32}) && ({HEBREW} ni $w32langs))} {
    # Visual order (pre-layouted)
    addSample $w Hebrew \
	"\u05EA\u05D9\u05E8\u05D1\u05E2 " \
	"\u05D1\u05EA\u05DB"
} else {
    # Standard logical order
    addSample $w Hebrew \
	"\u05DB\u05EA\u05D1 " \
	"\u05E2\u05D1\u05E8\u05D9\u05EA"
}


addSample $w Japanese \
	 "\u65E5\u672C\u8A9E\u306E\u3072\u3089\u304C\u306A, " \
	 "\u6F22\u5B57\u3068\u30AB\u30BF\u30AB\u30CA"
addSample $w Korean "\uB300\uD55C\uBBFC\uAD6D\uC758 \uD55C\uAE00"
addSample $w Russian \


	"\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u044F\u0437\u044B\u043A"


# We're done processing, so change things back to normal running...
destroy $w.wait
$w conf -cursor $oldCursor

Changes to library/demos/widget.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
# the main window for the application, which invokes individual
# demonstrations. The code for the actual demonstrations is contained in
# separate ".tcl" files is this directory, which are sourced by this script as
# needed.

package require Tk	8.5
package require msgcat


eval destroy [winfo child .]
set tk_demoDirectory [file join [pwd] [file dirname [info script]]]
::msgcat::mcload $tk_demoDirectory
namespace import ::msgcat::mc
wm title . [mc "Widget Demonstration"]
if {[tk windowingsystem] eq "x11"} {







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# the main window for the application, which invokes individual
# demonstrations. The code for the actual demonstrations is contained in
# separate ".tcl" files is this directory, which are sourced by this script as
# needed.

package require Tk	8.5
package require msgcat
package require Ttk

eval destroy [winfo child .]
set tk_demoDirectory [file join [pwd] [file dirname [info script]]]
::msgcat::mcload $tk_demoDirectory
namespace import ::msgcat::mc
wm title . [mc "Widget Demonstration"]
if {[tk windowingsystem] eq "x11"} {
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131


132
133
134
135
136
137
138
    AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ
    fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g
    ryhH5pgnEQA7
}

# Note that this is run through the message catalog! This is because this is
# actually an image of a word.
image create photo ::img::new -format PNG -data [mc {
    iVBORw0KGgoAAAANSUhEUgAAAB4AAAAOCAYAAAA45qw5AAACMElEQVR4AeVTAwxd
    QRCc2tZHGtQ2w9q2bdsOa9u2bUW1bdt2Z372JZe6DapJLqtb3h7+T8yKi5j4CsYD
    EUQXxETclT7kWOlH2VV+tFkdQHPSwksSISF+BauCqL0qgOcMWgGfgEkaMsHxqUBk
    3plE/sOnh/qDPAPJH/CKFBivGHWzFwBRnHhlqbu1Mh6CoFNnC/JshQ9p4YC2lrKt
    DCAV+THiVejyhMjAbrNSrroiEfKR9g7ZfCgOog8QfnUQV62wAk68ndQ9ZbyoWO1H
    Y6eDY1LCQL6a9ApOp9Hi1T0+gQq2JKMlky/oTKQliKWxEZvyG575kpW4pl1aZnQK
    CLOVt45Lkp8uXp2SL8KO6uitNTZLdpK6s+I/eZbhpmsmWeOGOVQNKYLITzpKPAO3
    tY7LSNZ7ccSLxX9y3uuOxRkg3dKESMoCHvL+GRVCutXsB3guLgDCeXOv4iWWkvwG
    BaS+PmlpK6SI9ApI2oC2UtrwZQEkhkH+NtolVlQXJl1I+QltuU3XEc721bIRFpa8
    IA5iqTo6vNNWmkNBLQbPeXwF2g17Q94nTQAfY3YzeY+WSu8MDzQ2kpELUhSGJUHE
    0zeR3rY1L+Xl5G/re+jbiK6KhThwwInsts1fbMUUcpZszKeVtggZEiGdZDe5AtHh
    7vL4CGiRvvKPS8FAvq9Nr4ZkFadR2y6kggu1z4vlyIbBp6BugQ8JLEg4bTkD9eMZ
    QZ8hpJ3VvTtuvbWrY/ElvP/9R+Aj3603+iE3fkEAAAAASUVORK5CYII=
}]

#----------------------------------------------------------------
# The code below creates the main window, consisting of a menu bar and a text
# widget that explains how to use the program, plus lists all of the demos as
# hypertext items.
#----------------------------------------------------------------

menu .menuBar -tearoff 0

# On Aqua, just use the default menu.
if {[tk windowingsystem] ne "aqua"} {
    # This is a tk-internal procedure to make i18n easier
    ::tk::AmpMenuArgs .menuBar add cascade -label [mc "&File"] \
	    -menu .menuBar.file
    menu .menuBar.file -tearoff 0
    ::tk::AmpMenuArgs .menuBar.file add command -label [mc "&About..."] \
	    -command {tkAboutDialog} -accelerator [mc "<F1>"]
    bind . <F1> {tkAboutDialog}
    .menuBar.file add sep
    if {[string match win* [tk windowingsystem]]} {
	# Windows doesn't usually have a Meta key
	::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
		-command {exit} -accelerator [mc "Ctrl+Q"]
	bind . <[mc "Control-q"]> {exit}
    } else {
	::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
		-command {exit} -accelerator [mc "Meta-Q"]
	bind . <[mc "Meta-q"]> {exit}
    }
    . configure -menu .menuBar
}



ttk::frame .statusBar
ttk::label .statusBar.lab -text "   " -anchor w
if {[tk windowingsystem] eq "aqua"} {
    ttk::separator .statusBar.sep
    pack .statusBar.sep -side top -expand yes -fill x -pady 0
}







|
|
|
|
|
|
<
<
<
<
<
<
<
<



|






<



















<

>
>







80
81
82
83
84
85
86
87
88
89
90
91
92








93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
    AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ
    fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g
    ryhH5pgnEQA7
}

# Note that this is run through the message catalog! This is because this is
# actually an image of a word.
image create photo ::img::new -format GIF -data [mc {
    R0lGODlhHgAOALMPALMAANyIiOu7u8dEROaqqvru7sxVVeGZmbgREfXd3b0iItZ3
    d8IzM9FmZvDMzP///yH5BAEAAA8ALAAAAAAeAA4AAASa8MlJq7046827WVOCHEkw
    nANhUgJlEBIABJIwL3K+4IcUALCHjfbItYZDSgJgkBiYPmBMAUAkkLPKs/BAyLgM
    wAQwOAAY2ByCaw4QAFQSoDEePJ6DmU1xInYZTw5nOEFFdgVUelkVDTIMd3AKFGQ1
    MgI2AwEmQW8APZ0gdRONAks5nhIFVVxdAAkUAS2pAVwFl7ITB4UqHb0XEQA7








}]

#----------------------------------------------------------------
# The code below create the main window, consisting of a menu bar and a text
# widget that explains how to use the program, plus lists all of the demos as
# hypertext items.
#----------------------------------------------------------------

menu .menuBar -tearoff 0


if {[tk windowingsystem] ne "aqua"} {
    # This is a tk-internal procedure to make i18n easier
    ::tk::AmpMenuArgs .menuBar add cascade -label [mc "&File"] \
	    -menu .menuBar.file
    menu .menuBar.file -tearoff 0
    ::tk::AmpMenuArgs .menuBar.file add command -label [mc "&About..."] \
	    -command {tkAboutDialog} -accelerator [mc "<F1>"]
    bind . <F1> {tkAboutDialog}
    .menuBar.file add sep
    if {[string match win* [tk windowingsystem]]} {
	# Windows doesn't usually have a Meta key
	::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
		-command {exit} -accelerator [mc "Ctrl+Q"]
	bind . <[mc "Control-q"]> {exit}
    } else {
	::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
		-command {exit} -accelerator [mc "Meta-Q"]
	bind . <[mc "Meta-q"]> {exit}
    }

}

. configure -menu .menuBar

ttk::frame .statusBar
ttk::label .statusBar.lab -text "   " -anchor w
if {[tk windowingsystem] eq "aqua"} {
    ttk::separator .statusBar.sep
    pack .statusBar.sep -side top -expand yes -fill x -pady 0
}
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    set textheight [expr {
	([winfo screenheight .] * 0.7) /
	[font metrics mainFont -displayof . -linespace]
    }]
}

ttk::frame .textFrame
ttk::scrollbar .s -orient vertical -command {.t yview} -takefocus 1
pack .s -in .textFrame -side right -fill y
text .t -yscrollcommand {.s set} -wrap word -width 70 -height $textheight \
	-font mainFont -setgrid 1 -highlightthickness 0 \
	-padx 4 -pady 2 -takefocus 0
pack .t -in .textFrame -expand y -fill both -padx 1
pack .textFrame -expand yes -fill both
if {[tk windowingsystem] eq "aqua"} {







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    set textheight [expr {
	([winfo screenheight .] * 0.7) /
	[font metrics mainFont -displayof . -linespace]
    }]
}

ttk::frame .textFrame
scrollbar .s -orient vertical -command {.t yview} -takefocus 1
pack .s -in .textFrame -side right -fill y
text .t -yscrollcommand {.s set} -wrap word -width 70 -height $textheight \
	-font mainFont -setgrid 1 -highlightthickness 0 \
	-padx 4 -pady 2 -takefocus 0
pack .t -in .textFrame -expand y -fill both -padx 1
pack .textFrame -expand yes -fill both
if {[tk windowingsystem] eq "aqua"} {
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
	-underline 1
    .t tag configure hot -background black -foreground white
} else {
    .t tag configure demo -lmargin1 1c -lmargin2 1c \
	-foreground blue -underline 1
    .t tag configure visited -lmargin1 1c -lmargin2 1c \
	-foreground #303080 -underline 1
    if {[tk windowingsystem] eq "aqua"} {
	.t tag configure demo -foreground systemLinkColor
	.t tag configure visited -foreground purple
    }
    .t tag configure hot -foreground red -underline 1
}
.t tag bind demo <ButtonRelease-1> {
    invoke [.t index {@%x,%y}]
}
set lastLine ""
.t tag bind demo <Enter> {







<
<
<
<







183
184
185
186
187
188
189




190
191
192
193
194
195
196
	-underline 1
    .t tag configure hot -background black -foreground white
} else {
    .t tag configure demo -lmargin1 1c -lmargin2 1c \
	-foreground blue -underline 1
    .t tag configure visited -lmargin1 1c -lmargin2 1c \
	-foreground #303080 -underline 1




    .t tag configure hot -foreground red -underline 1
}
.t tag bind demo <ButtonRelease-1> {
    invoke [.t index {@%x,%y}]
}
set lastLine ""
.t tag bind demo <Enter> {
324
325
326
327
328
329
330

331
332
333
334
335
336

337

338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370

371
372
373
374
375

376

377
378
379
380
381

382

383
384
385
386
387
388
389
390
391

392

393

394

395
396
397
398
399
400
401
    @@demo check	Check-buttons (select any of a group)
    @@demo radio	Radio-buttons (select one of a group)
    @@demo puzzle	A 15-puzzle game made out of buttons
    @@demo icon		Iconic buttons that use bitmaps
    @@demo image1	Two labels displaying images
    @@demo image2	A simple user interface for viewing images
    @@demo labelframe	Labelled frames

    @@demo ttkbut	The simple Themed Tk widgets

    @@subtitle	Listboxes and Trees
    @@demo states	The 50 states
    @@demo colors	Colors: change the color scheme for the application
    @@demo sayings	A collection of famous and infamous sayings

    @@demo mclist	A multi-column list of countries

    @@demo tree		A directory browser tree

    @@subtitle	Entries, Spin-boxes and Combo-boxes
    @@demo entry1	Entries without scrollbars
    @@demo entry2	Entries with scrollbars
    @@demo entry3	Validated entries and password fields
    @@demo spin		Spin-boxes

    @@demo combo	Combo-boxes
    @@demo form		Simple Rolodex-like form

    @@subtitle	Text
    @@demo text		Basic editable text
    @@demo style	Text display styles
    @@demo bind		Hypertext (tag bindings)
    @@demo twind	A text widget with embedded windows and other features
    @@demo search	A search tool built with a text widget

    @@demo textpeer	Peering text widgets

    @@subtitle	Canvases
    @@demo items	The canvas item types
    @@demo plot		A simple 2-D plot
    @@demo ctext	Text items in canvases
    @@demo arrow	An editor for arrowheads on canvas lines
    @@demo ruler	A ruler with adjustable tab stops
    @@demo floor	A building floor plan
    @@demo cscroll	A simple scrollable canvas

    @@demo knightstour  A Knight's tour of the chess board

    @@subtitle	Scales and Progress Bars
    @@demo hscale	Horizontal scale
    @@demo vscale	Vertical scale
    @@new
    @@demo ttkscale	Themed scale linked to a label with traces

    @@demo ttkprogress	Progress bar

    @@subtitle	Paned Windows and Notebooks
    @@demo paned1	Horizontal paned window
    @@demo paned2	Vertical paned window

    @@demo ttkpane	Themed nested panes

    @@demo ttknote	Notebook widget

    @@subtitle	Menus and Toolbars
    @@demo menu		Menus and cascades (sub-menus)
    @@demo menubu	Menu-buttons

    @@demo ttkmenu	Themed menu buttons

    @@demo toolbar	Themed toolbar

    @@subtitle	Common Dialogs
    @@demo msgbox	Message boxes
    @@demo filebox	File selection dialog
    @@demo clrpick	Color picker
    @@demo fontchoose	Font selection dialog

    @@subtitle	Animation

    @@demo anilabel	Animated labels

    @@demo aniwave	Animated wave

    @@demo pendulum	Pendulum simulation

    @@demo goldberg	A celebration of Rube Goldberg

    @@subtitle	Miscellaneous
    @@demo bitmap	The built-in bitmaps
    @@demo dialog1	A dialog box with a local grab
    @@demo dialog2	A dialog box with a global grab
}







>






>

>







>









>










>







>





>

>





>

>






<


>

>

>

>







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    @@demo check	Check-buttons (select any of a group)
    @@demo radio	Radio-buttons (select one of a group)
    @@demo puzzle	A 15-puzzle game made out of buttons
    @@demo icon		Iconic buttons that use bitmaps
    @@demo image1	Two labels displaying images
    @@demo image2	A simple user interface for viewing images
    @@demo labelframe	Labelled frames
    @@new
    @@demo ttkbut	The simple Themed Tk widgets

    @@subtitle	Listboxes and Trees
    @@demo states	The 50 states
    @@demo colors	Colors: change the color scheme for the application
    @@demo sayings	A collection of famous and infamous sayings
    @@new
    @@demo mclist	A multi-column list of countries
    @@new
    @@demo tree		A directory browser tree

    @@subtitle	Entries, Spin-boxes and Combo-boxes
    @@demo entry1	Entries without scrollbars
    @@demo entry2	Entries with scrollbars
    @@demo entry3	Validated entries and password fields
    @@demo spin		Spin-boxes
    @@new
    @@demo combo	Combo-boxes
    @@demo form		Simple Rolodex-like form

    @@subtitle	Text
    @@demo text		Basic editable text
    @@demo style	Text display styles
    @@demo bind		Hypertext (tag bindings)
    @@demo twind	A text widget with embedded windows and other features
    @@demo search	A search tool built with a text widget
    @@new
    @@demo textpeer	Peering text widgets

    @@subtitle	Canvases
    @@demo items	The canvas item types
    @@demo plot		A simple 2-D plot
    @@demo ctext	Text items in canvases
    @@demo arrow	An editor for arrowheads on canvas lines
    @@demo ruler	A ruler with adjustable tab stops
    @@demo floor	A building floor plan
    @@demo cscroll	A simple scrollable canvas
    @@new
    @@demo knightstour  A Knight's tour of the chess board

    @@subtitle	Scales and Progress Bars
    @@demo hscale	Horizontal scale
    @@demo vscale	Vertical scale
    @@new
    @@demo ttkscale	Themed scale linked to a label with traces
    @@new
    @@demo ttkprogress	Progress bar

    @@subtitle	Paned Windows and Notebooks
    @@demo paned1	Horizontal paned window
    @@demo paned2	Vertical paned window
    @@new
    @@demo ttkpane	Themed nested panes
    @@new
    @@demo ttknote	Notebook widget

    @@subtitle	Menus and Toolbars
    @@demo menu		Menus and cascades (sub-menus)
    @@demo menubu	Menu-buttons
    @@new
    @@demo ttkmenu	Themed menu buttons
    @@new
    @@demo toolbar	Themed toolbar

    @@subtitle	Common Dialogs
    @@demo msgbox	Message boxes
    @@demo filebox	File selection dialog
    @@demo clrpick	Color picker


    @@subtitle	Animation
    @@new
    @@demo anilabel	Animated labels
    @@new
    @@demo aniwave	Animated wave
    @@new
    @@demo pendulum	Pendulum simulation
    @@new
    @@demo goldberg	A celebration of Rube Goldberg

    @@subtitle	Miscellaneous
    @@demo bitmap	The built-in bitmaps
    @@demo dialog1	A dialog box with a local grab
    @@demo dialog2	A dialog box with a global grab
}
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
	if {[tk windowingsystem] eq "x11"} {wm attributes $top -type dialog}

	set t [frame $top.f]
	set text [text $t.text -font fixedFont -height 24 -wrap word \
		      -xscrollcommand [list $t.xscroll set] \
		      -yscrollcommand [list $t.yscroll set] \
		      -setgrid 1 -highlightthickness 0 -pady 2 -padx 3]
	ttk::scrollbar $t.xscroll -command [list $t.text xview] \
	    -orient horizontal
	ttk::scrollbar $t.yscroll -command [list $t.text yview] \
	    -orient vertical

	grid $t.text $t.yscroll -sticky news
	#grid $t.xscroll
	grid rowconfigure $t 0 -weight 1
	grid columnconfig $t 0 -weight 1

	set btns [ttk::frame $top.btns]







|
<
|
<







575
576
577
578
579
580
581
582

583

584
585
586
587
588
589
590
	if {[tk windowingsystem] eq "x11"} {wm attributes $top -type dialog}

	set t [frame $top.f]
	set text [text $t.text -font fixedFont -height 24 -wrap word \
		      -xscrollcommand [list $t.xscroll set] \
		      -yscrollcommand [list $t.yscroll set] \
		      -setgrid 1 -highlightthickness 0 -pady 2 -padx 3]
	scrollbar $t.xscroll -command [list $t.text xview] -orient horizontal

	scrollbar $t.yscroll -command [list $t.text yview] -orient vertical


	grid $t.text $t.yscroll -sticky news
	#grid $t.xscroll
	grid rowconfigure $t 0 -weight 1
	grid columnconfig $t 0 -weight 1

	set btns [ttk::frame $top.btns]
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
    } else {
	wm deiconify $top
	raise $top
    }
    wm title $top [mc "Demo code: %s" [file join $tk_demoDirectory $file]]
    wm iconname $top $file
    set id [open [file join $tk_demoDirectory $file]]
    fconfigure $id -encoding utf-8 -eofchar \032
    $top.f.text delete 1.0 end
    $top.f.text insert 1.0 [read $id]
    $top.f.text mark set insert 1.0
    close $id
}

# printCode --







<







621
622
623
624
625
626
627

628
629
630
631
632
633
634
    } else {
	wm deiconify $top
	raise $top
    }
    wm title $top [mc "Demo code: %s" [file join $tk_demoDirectory $file]]
    wm iconname $top $file
    set id [open [file join $tk_demoDirectory $file]]

    $top.f.text delete 1.0 end
    $top.f.text insert 1.0 [read $id]
    $top.f.text mark set insert 1.0
    close $id
}

# printCode --
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# tkAboutDialog --
#
#	Pops up a message box with an "about" message
#
proc tkAboutDialog {} {
    tk_messageBox -icon info -type ok -title [mc "About Widget Demo"] \
	    -message [mc "Tk widget demonstration application"] -detail \
"[mc "Copyright © %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright © %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright © %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright © %s" {2002-2007 Daniel A. Steffen}]"
}

# Local Variables:
# mode: tcl
# End:







|
|
|
|





719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# tkAboutDialog --
#
#	Pops up a message box with an "about" message
#
proc tkAboutDialog {} {
    tk_messageBox -icon info -type ok -title [mc "About Widget Demo"] \
	    -message [mc "Tk widget demonstration application"] -detail \
"[mc "Copyright \u00a9 %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright \u00a9 %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright \u00a9 %s" {2001-2007 Donal K. Fellows}]
[mc "Copyright \u00a9 %s" {2002-2007 Daniel A. Steffen}]"
}

# Local Variables:
# mode: tcl
# End:

Changes to library/dialog.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# dialog.tcl --
#
# This file defines the procedure tk_dialog, which creates a dialog
# box containing a bitmap, a message, and one or more buttons.
#
# Copyright © 1992-1993 The Regents of the University of California.
# Copyright © 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.
#

#
# ::tk_dialog:





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# dialog.tcl --
#
# This file defines the procedure tk_dialog, which creates a dialog
# box containing a bitmap, a message, and one or more buttons.
#
# Copyright (c) 1992-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.
#

#
# ::tk_dialog:
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46





47
48
49
50
51
52
53
# bitmap -	Bitmap to display in dialog (empty string means none).
# default -	Index of button that is to display the default ring
#		(-1 means none).
# args -	One or more strings to display in buttons across the
#		bottom of the dialog box.

proc ::tk_dialog {w title text bitmap default args} {

    variable ::tk::Priv

    # Check that $default was properly given
    if {[string is integer -strict $default]} {
	if {$default >= [llength $args]} {
	    return -code error -errorcode {TK DIALOG BAD_DEFAULT} \
		"default button index greater than number of buttons\
		specified for tk_dialog"
	}
    } elseif {"" eq $default} {
	set default -1
    } else {
	set default [lsearch -exact $args $default]
    }

    set windowingsystem [tk windowingsystem]






    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    destroy $w
    toplevel $w -class Dialog
    wm title $w $title







>





<
|
|








>
>
>
>
>







24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# bitmap -	Bitmap to display in dialog (empty string means none).
# default -	Index of button that is to display the default ring
#		(-1 means none).
# args -	One or more strings to display in buttons across the
#		bottom of the dialog box.

proc ::tk_dialog {w title text bitmap default args} {
    global tcl_platform
    variable ::tk::Priv

    # Check that $default was properly given
    if {[string is integer -strict $default]} {
	if {$default >= [llength $args]} {

	    return -code error "default button index greater than number of\
		    buttons specified for tk_dialog"
	}
    } elseif {"" eq $default} {
	set default -1
    } else {
	set default [lsearch -exact $args $default]
    }

    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {
	option add *Dialog*background systemDialogBackgroundActive widgetDefault
	option add *Dialog*Button.highlightBackground \
		systemDialogBackgroundActive widgetDefault
    }

    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    destroy $w
    toplevel $w -class Dialog
    wm title $w $title
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    # Convention also dictates that if the keyboard focus moves among the
    # the buttons that the <Return> binding affects the button with the focus.

    if {$default >= 0} {
	bind $w <Return> [list $w.button$default invoke]
    }
    bind $w <<PrevWindow>> [list bind $w <Return> {[tk_focusPrev %W] invoke}]
    bind $w <<NextWindow>> [list bind $w <Return> {[tk_focusNext %W] invoke}]

    # 5. Create a <Destroy> binding for the window that sets the
    # button variable to -1;  this is needed in case something happens
    # that destroys the window, such as its parent window being destroyed.

    bind $w <Destroy> {set ::tk::Priv(button) -1}

    # 6. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $w
    tkwait visibility $w

    # 7. Set a grab and claim the focus too.

    if {$default >= 0} {
        set focus $w.button$default
    } else {







|











|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    # Convention also dictates that if the keyboard focus moves among the
    # the buttons that the <Return> binding affects the button with the focus.

    if {$default >= 0} {
	bind $w <Return> [list $w.button$default invoke]
    }
    bind $w <<PrevWindow>> [list bind $w <Return> {[tk_focusPrev %W] invoke}]
    bind $w <Tab> [list bind $w <Return> {[tk_focusNext %W] invoke}]

    # 5. Create a <Destroy> binding for the window that sets the
    # button variable to -1;  this is needed in case something happens
    # that destroys the window, such as its parent window being destroyed.

    bind $w <Destroy> {set ::tk::Priv(button) -1}

    # 6. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $w 
    tkwait visibility $w

    # 7. Set a grab and claim the focus too.

    if {$default >= 0} {
        set focus $w.button$default
    } else {

Changes to library/entry.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# entry.tcl --
#
# This file defines the default bindings for Tk entry widgets and provides
# procedures that help in implementing those bindings.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 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.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# entry.tcl --
#
# This file defines the default bindings for Tk entry widgets and provides
# procedures that help in implementing those bindings.
#
# 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.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    if {![catch {tk::EntryGetSelection %W} tk::Priv(data)]} {
	clipboard clear -displayof %W
	clipboard append -displayof %W $tk::Priv(data)
	unset tk::Priv(data)
    }
}
bind Entry <<Paste>> {

    catch {
	if {[tk windowingsystem] ne "x11"} {
	    catch {
		%W delete sel.first sel.last
	    }
	}
	%W insert insert [::tk::GetSelection %W CLIPBOARD]
	tk::EntrySeeInsert %W
    }
}
bind Entry <<Clear>> {
    # ignore if there is no selection
    catch {%W delete sel.first sel.last}
}
bind Entry <<PasteSelection>> {
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	|| !$tk::Priv(mouseMoved)} {
	tk::EntryPaste %W %x
    }
}

bind Entry <<TraverseIn>> {
    %W selection range 0 end
    %W icursor end
}

# Standard Motif bindings:

bind Entry <Button-1> {
    tk::EntryButton1 %W %x
    %W selection clear
}
bind Entry <B1-Motion> {
    set tk::Priv(x) %x
    tk::EntryMouseSelect %W %x
}
bind Entry <Double-Button-1> {
    set tk::Priv(selectMode) word
    tk::EntryMouseSelect %W %x
    catch {%W icursor sel.last}
}
bind Entry <Triple-Button-1> {
    set tk::Priv(selectMode) line
    tk::EntryMouseSelect %W %x
    catch {%W icursor sel.last}
}
bind Entry <Shift-Button-1> {
    set tk::Priv(selectMode) char
    %W selection adjust @%x
}
bind Entry <Double-Shift-Button-1>	{
    set tk::Priv(selectMode) word
    tk::EntryMouseSelect %W %x
}
bind Entry <Triple-Shift-Button-1>	{
    set tk::Priv(selectMode) line
    tk::EntryMouseSelect %W %x
}
bind Entry <B1-Leave> {
    set tk::Priv(x) %x
    tk::EntryAutoScan %W
}
bind Entry <B1-Enter> {
    tk::CancelRepeat
}
bind Entry <ButtonRelease-1> {
    tk::CancelRepeat
}
bind Entry <Control-Button-1> {
    %W icursor @%x
}

bind Entry <<PrevChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert]-1}]
}
bind Entry <<NextChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert]+1}]
}
bind Entry <<SelectPrevChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert]-1}]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert]+1}]
    tk::EntrySeeInsert %W
}
bind Entry <<PrevWord>> {
    tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
}
bind Entry <<NextWord>> {
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <<SelectPrevWord>> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextWord>> {
    tk::EntryKeySelect %W [tk::EntryNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<LineStart>> {
    tk::EntrySetCursor %W 0
}
bind Entry <<SelectLineStart>> {
    tk::EntryKeySelect %W 0
    tk::EntrySeeInsert %W
}
bind Entry <<LineEnd>> {
    tk::EntrySetCursor %W end
}
bind Entry <<SelectLineEnd>> {
    tk::EntryKeySelect %W end
    tk::EntrySeeInsert %W
}

bind Entry <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last







>












|









|
|




|







|




|




|



|



|













|



|
|

|
|

|
|


|
|


|


|


|



|



|


|



|


|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    if {![catch {tk::EntryGetSelection %W} tk::Priv(data)]} {
	clipboard clear -displayof %W
	clipboard append -displayof %W $tk::Priv(data)
	unset tk::Priv(data)
    }
}
bind Entry <<Paste>> {
    global tcl_platform
    catch {
	if {[tk windowingsystem] ne "x11"} {
	    catch {
		%W delete sel.first sel.last
	    }
	}
	%W insert insert [::tk::GetSelection %W CLIPBOARD]
	tk::EntrySeeInsert %W
    }
}
bind Entry <<Clear>> {
    # ignore if there is no selection
    catch { %W delete sel.first sel.last }
}
bind Entry <<PasteSelection>> {
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	|| !$tk::Priv(mouseMoved)} {
	tk::EntryPaste %W %x
    }
}

bind Entry <<TraverseIn>> {
    %W selection range 0 end 
    %W icursor end 
}

# Standard Motif bindings:

bind Entry <1> {
    tk::EntryButton1 %W %x
    %W selection clear
}
bind Entry <B1-Motion> {
    set tk::Priv(x) %x
    tk::EntryMouseSelect %W %x
}
bind Entry <Double-1> {
    set tk::Priv(selectMode) word
    tk::EntryMouseSelect %W %x
    catch {%W icursor sel.last}
}
bind Entry <Triple-1> {
    set tk::Priv(selectMode) line
    tk::EntryMouseSelect %W %x
    catch {%W icursor sel.last}
}
bind Entry <Shift-1> {
    set tk::Priv(selectMode) char
    %W selection adjust @%x
}
bind Entry <Double-Shift-1>	{
    set tk::Priv(selectMode) word
    tk::EntryMouseSelect %W %x
}
bind Entry <Triple-Shift-1>	{
    set tk::Priv(selectMode) line
    tk::EntryMouseSelect %W %x
}
bind Entry <B1-Leave> {
    set tk::Priv(x) %x
    tk::EntryAutoScan %W
}
bind Entry <B1-Enter> {
    tk::CancelRepeat
}
bind Entry <ButtonRelease-1> {
    tk::CancelRepeat
}
bind Entry <Control-1> {
    %W icursor @%x
}

bind Entry <Left> {
    tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
}
bind Entry <Right> {
    tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
}
bind Entry <Shift-Left> {
    tk::EntryKeySelect %W [expr {[%W index insert] - 1}]
    tk::EntrySeeInsert %W
}
bind Entry <Shift-Right> {
    tk::EntryKeySelect %W [expr {[%W index insert] + 1}]
    tk::EntrySeeInsert %W
}
bind Entry <Control-Left> {
    tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
}
bind Entry <Control-Right> {
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <Shift-Control-Left> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <Shift-Control-Right> {
    tk::EntryKeySelect %W [tk::EntryNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <Home> {
    tk::EntrySetCursor %W 0
}
bind Entry <Shift-Home> {
    tk::EntryKeySelect %W 0
    tk::EntrySeeInsert %W
}
bind Entry <End> {
    tk::EntrySetCursor %W end
}
bind Entry <Shift-End> {
    tk::EntryKeySelect %W end
    tk::EntrySeeInsert %W
}

bind Entry <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228










229
230
231
232










233
234
235
236
237
238
239
}
bind Entry <Control-Shift-space> {
    %W selection adjust insert
}
bind Entry <Shift-Select> {
    %W selection adjust insert
}
bind Entry <<SelectAll>> {
    %W selection range 0 end
}
bind Entry <<SelectNone>> {
    %W selection clear
}
bind Entry <Key> {
    tk::CancelRepeat
    tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Entry <Alt-Key> {# nothing}
bind Entry <Meta-Key> {# nothing}
bind Entry <Control-Key> {# nothing}
bind Entry <Escape> {# nothing}
bind Entry <Return> {# nothing}
bind Entry <KP_Enter> {# nothing}
bind Entry <Tab> {# nothing}
bind Entry <Prior> {# nothing}
bind Entry <Next> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Entry <Command-Key> {# nothing}
}
# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind Entry <<NextLine>> {# nothing}
bind Entry <<PrevLine>> {# nothing}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Entry <Insert> {
	catch {tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }
}

# Additional emacs-like bindings:











bind Entry <Control-d> {
    if {!$tk_strictMotif} {
	%W delete insert
    }










}
bind Entry <Control-h> {
    if {!$tk_strictMotif} {
	tk::EntryBackspace %W
    }
}
bind Entry <Control-k> {







|


|


|






|


|
|
|




<
<

|

<
<
<











>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210


211
212
213



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
}
bind Entry <Control-Shift-space> {
    %W selection adjust insert
}
bind Entry <Shift-Select> {
    %W selection adjust insert
}
bind Entry <Control-slash> {
    %W selection range 0 end
}
bind Entry <Control-backslash> {
    %W selection clear
}
bind Entry <KeyPress> {
    tk::CancelRepeat
    tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <KeyPress> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Entry <Alt-KeyPress> {# nothing}
bind Entry <Meta-KeyPress> {# nothing}
bind Entry <Control-KeyPress> {# nothing}
bind Entry <Escape> {# nothing}
bind Entry <Return> {# nothing}
bind Entry <KP_Enter> {# nothing}
bind Entry <Tab> {# nothing}


if {[tk windowingsystem] eq "aqua"} {
    bind Entry <Command-KeyPress> {# nothing}
}




# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Entry <Insert> {
	catch {tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }
}

# Additional emacs-like bindings:

bind Entry <Control-a> {
    if {!$tk_strictMotif} {
	tk::EntrySetCursor %W 0
    }
}
bind Entry <Control-b> {
    if {!$tk_strictMotif} {
	tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
    }
}
bind Entry <Control-d> {
    if {!$tk_strictMotif} {
	%W delete insert
    }
}
bind Entry <Control-e> {
    if {!$tk_strictMotif} {
	tk::EntrySetCursor %W end
    }
}
bind Entry <Control-f> {
    if {!$tk_strictMotif} {
	tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
    }
}
bind Entry <Control-h> {
    if {!$tk_strictMotif} {
	tk::EntryBackspace %W
    }
}
bind Entry <Control-k> {
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
}
bind Entry <Meta-Delete> {
    if {!$tk_strictMotif} {
	%W delete [tk::EntryPreviousWord %W insert] insert
    }
}

# Bindings for IME text input and accents.

bind Entry <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Entry <<TkEndIMEMarkedText>> {
    if {[catch {dict get $::tk::Priv(IMETextMark) "%W"} mark]} {
	bell
    } else {
	%W selection range $mark insert
    }
}
bind Entry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind Entry <<TkAccentBackspace>> {
    tk::EntryBackspace %W
}

# A few additional bindings of my own.

bind Entry <Button-2> {
    if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
    }
}
bind Entry <B2-Motion> {
    if {!$tk_strictMotif} {
        ::tk::EntryScanDrag %W %x
     }
}

# ::tk::EntryClosestGap --
# Given x and y coordinates, this procedure finds the closest boundary
# between characters to the given coordinates and returns the index
# of the character just after the boundary.
#







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

|




|
|







284
285
286
287
288
289
290



















291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
}
bind Entry <Meta-Delete> {
    if {!$tk_strictMotif} {
	%W delete [tk::EntryPreviousWord %W insert] insert
    }
}




















# A few additional bindings of my own.

bind Entry <2> {
    if {!$tk_strictMotif} {
	::tk::EntryScanMark %W %x
    }
}
bind Entry <B2-Motion> {
    if {!$tk_strictMotif} {
	::tk::EntryScanDrag %W %x
    }
}

# ::tk::EntryClosestGap --
# Given x and y coordinates, this procedure finds the closest boundary
# between characters to the given coordinates and returns the index
# of the character just after the boundary.
#
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } elseif {$cur > $anchor} {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $anchor]
	    }







|


|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]
	    } elseif {$cur > $anchor} {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $anchor]
	    }
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# Arguments:
# w -		The entry window in which to backspace.

proc ::tk::EntryBackspace w {
    if {[$w selection present]} {
	$w delete sel.first sel.last
    } else {
	set x [$w index insert]
	if {$x > 0} {
	    $w delete [expr {$x-1}]
	}
	if {[$w index @0] >= [$w index insert]} {
	    set range [$w xview]
	    set left [lindex $range 0]
	    set right [lindex $range 1]
	    $w xview moveto [expr {$left - ($right - $left)/2.0}]
	}







|
|
|







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# Arguments:
# w -		The entry window in which to backspace.

proc ::tk::EntryBackspace w {
    if {[$w selection present]} {
	$w delete sel.first sel.last
    } else {
	set x [expr {[$w index insert] - 1}]
	if {$x >= 0} {
	    $w delete $x
	}
	if {[$w index @0] >= [$w index insert]} {
	    set range [$w xview]
	    set left [lindex $range 0]
	    set right [lindex $range 1]
	    $w xview moveto [expr {$left - ($right - $left)/2.0}]
	}
558
559
560
561
562
563
564

565
566
567
568
569
570
571
572
573
574
575
576
577
# w -		The entry window.

proc ::tk::EntryTranspose w {
    set i [$w index insert]
    if {$i < [$w index end]} {
	incr i
    }

    if {$i < 2} {
	return
    }
    set first [expr {$i-2}]
    set data [$w get]
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --
# Returns the index of the next word position after a given position in the







>
|


<

|







555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
# w -		The entry window.

proc ::tk::EntryTranspose w {
    set i [$w index insert]
    if {$i < [$w index end]} {
	incr i
    }
    set first [expr {$i-2}]
    if {$first < 0} {
	return
    }

    set data [$w get]
    set new [string index $data [expr {$i-1}]][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --
# Returns the index of the next word position after a given position in the
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
# Arguments:
# w -	The entry window from which the text to get
# x -	x location on screen

proc ::tk::EntryScanDrag {w x} {
    # Make sure these exist, as some weird situations can trigger the
    # motion binding without the initial press.  [Bug #220269]
    if {![info exists ::tk::Priv(x)]} {set ::tk::Priv(x) $x}
    # allow for a delta
    if {abs($x-$::tk::Priv(x)) > 2} {
	set ::tk::Priv(mouseMoved) 1
    }
    $w scan dragto $x
}

# ::tk::EntryGetSelection --
#
# Returns the selected text of the entry with respect to the -show option.
#
# Arguments:
# w -         The entry window from which the text to get

proc ::tk::EntryGetSelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [$w index sel.last]-1]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}







|
















|






640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
# Arguments:
# w -	The entry window from which the text to get
# x -	x location on screen

proc ::tk::EntryScanDrag {w x} {
    # Make sure these exist, as some weird situations can trigger the
    # motion binding without the initial press.  [Bug #220269]
    if {![info exists ::tk::Priv(x)]} { set ::tk::Priv(x) $x }
    # allow for a delta
    if {abs($x-$::tk::Priv(x)) > 2} {
	set ::tk::Priv(mouseMoved) 1
    }
    $w scan dragto $x
}

# ::tk::EntryGetSelection --
#
# Returns the selected text of the entry with respect to the -show option.
#
# Arguments:
# w -         The entry window from which the text to get

proc ::tk::EntryGetSelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}

Changes to library/focus.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
# focus.tcl --
#
# This file defines several procedures for managing the input
# focus.
#
# Copyright © 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.
#

# ::tk_focusNext --
# This procedure returns the name of the next window after "w" in





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# focus.tcl --
#
# This file defines several procedures for managing the input
# focus.
#
# 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.
#

# ::tk_focusNext --
# This procedure returns the name of the next window after "w" in

Deleted library/fontchooser.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# fontchooser.tcl -
#
#	A themeable Tk font selection dialog. See TIP #324.
#
# Copyright (C) 2008 Keith Vetter
# Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::fontchooser {
    variable S

    set S(W) .__tk__fontchooser
    set S(fonts) [lsort -dictionary [font families]]
    set S(styles) [list \
	[::msgcat::mc "Regular"] \
	[::msgcat::mc "Italic"] \
	[::msgcat::mc "Bold"] \
	[::msgcat::mc "Bold Italic"] \
    ]

    set S(sizes) {8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72}
    set S(strike) 0
    set S(under) 0
    set S(first) 1
    set S(sampletext) [::msgcat::mc "AaBbYyZz01"]
    set S(-parent) .
    set S(-title) [::msgcat::mc "Font"]
    set S(-command) ""
    set S(-font) TkDefaultFont
}

proc ::tk::fontchooser::Setup {} {
    variable S

    # Canonical versions of font families, styles, etc. for easier searching
    set S(fonts,lcase) {}
    foreach font $S(fonts) {lappend S(fonts,lcase) [string tolower $font]}
    set S(styles,lcase) {}
    foreach style $S(styles) {lappend S(styles,lcase) [string tolower $style]}
    set S(sizes,lcase) $S(sizes)

    ::ttk::style layout FontchooserFrame {
        Entry.field -sticky news -border true -children {
            FontchooserFrame.padding -sticky news
        }
    }
    bind [winfo class .] <<ThemeChanged>> \
        [list +ttk::style layout FontchooserFrame \
             [ttk::style layout FontchooserFrame]]

    namespace ensemble create -map {
        show ::tk::fontchooser::Show
        hide ::tk::fontchooser::Hide
        configure ::tk::fontchooser::Configure
    }
}
::tk::fontchooser::Setup

proc ::tk::fontchooser::Show {} {
    variable S
    if {![winfo exists $S(W)]} {
        Create
        wm transient $S(W) [winfo toplevel $S(-parent)]
        tk::PlaceWindow $S(W) widget $S(-parent)
    }
    set S(fonts) [lsort -dictionary [font families]]
    set S(fonts,lcase) {}
    foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]}
    wm deiconify $S(W)
}

proc ::tk::fontchooser::Hide {} {
    variable S
    wm withdraw $S(W)
}

proc ::tk::fontchooser::Configure {args} {
    variable S

    set specs {
        {-parent  "" "" . }
        {-title   "" "" ""}
        {-font    "" "" ""}
        {-command "" "" ""}
    }

    if {[llength $args] == 0} {
        set result {}
        foreach spec $specs {
            foreach {name xx yy default} $spec break
            lappend result $name \
                [expr {[info exists S($name)] ? $S($name) : $default}]
        }
        lappend result -visible \
            [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        return $result
    }
    if {[llength $args] == 1} {
        set option [lindex $args 0]
        if {[string equal $option "-visible"]} {
            return [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        } elseif {[info exists S($option)]} {
            return $S($option)
        }
        return -code error -errorcode [list TK LOOKUP OPTION $option] \
	    "bad option \"$option\": must be\
            -command, -font, -parent, -title or -visible"
    }

    set cache [dict create -parent $S(-parent) -title $S(-title) \
                   -font $S(-font) -command $S(-command)]
    set r [tclParseConfigSpec [namespace which -variable S] $specs "" $args]
    if {![winfo exists $S(-parent)]} {
	set code [list TK LOOKUP WINDOW $S(-parent)]
        set err "bad window path name \"$S(-parent)\""
        array set S $cache
        return -code error -errorcode $code $err
    }
    if {[string trim $S(-title)] eq ""} {
        set S(-title) [::msgcat::mc "Font"]
    }
    if {[winfo exists $S(W)] && ("-font" in $args)} {
	Init $S(-font)
	event generate $S(-parent) <<TkFontchooserFontChanged>>
    }
    return $r
}

proc ::tk::fontchooser::Create {} {
    variable S
    set windowName __tk__fontchooser
    if {$S(-parent) eq "."} {
        set S(W) .$windowName
    } else {
        set S(W) $S(-parent).$windowName
    }

    # Now build the dialog
    if {![winfo exists $S(W)]} {
        toplevel $S(W) -class TkFontDialog
        if {[package provide tcltest] ne {}} {set ::tk_dialog $S(W)}
        wm withdraw $S(W)
        wm title $S(W) $S(-title)
        wm transient $S(W) [winfo toplevel $S(-parent)]

        set scaling [tk scaling]
        set sizeWidth [expr {int([string length [::msgcat::mc "&Size:"]] * $scaling)}]

        set outer [::ttk::frame $S(W).outer -padding {10 10}]
        ::tk::AmpWidget ::ttk::label $S(W).font -text [::msgcat::mc "&Font:"]
        ::tk::AmpWidget ::ttk::label $S(W).style -text [::msgcat::mc "Font st&yle:"]
        ::tk::AmpWidget ::ttk::label $S(W).size -text [::msgcat::mc "&Size:"] -width $sizeWidth
        ttk::entry $S(W).efont -width 18 \
            -textvariable [namespace which -variable S](font)
        ttk::entry $S(W).estyle -width 10 \
            -textvariable [namespace which -variable S](style)
        ttk::entry $S(W).esize -textvariable [namespace which -variable S](size) \
            -width 3 -validate key -validatecommand {string is double %P}

        ttk_slistbox $S(W).lfonts -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](fonts)
        ttk_slistbox $S(W).lstyles -width 5 -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](styles)
        ttk_slistbox $S(W).lsizes -width 4 -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](sizes)

        set WE $S(W).effects
        ::ttk::labelframe $WE -text [::msgcat::mc "Effects"]
        ::tk::AmpWidget ::ttk::checkbutton $WE.strike \
            -variable [namespace which -variable S](strike) \
            -text [::msgcat::mc "Stri&keout"] \
            -command [namespace code [list Click strike]]
        ::tk::AmpWidget ::ttk::checkbutton $WE.under \
            -variable [namespace which -variable S](under) \
            -text [::msgcat::mc "&Underline"] \
            -command [namespace code [list Click under]]

        set bbox [::ttk::frame $S(W).bbox]
        ::ttk::button $S(W).ok -text [::msgcat::mc OK] -default active\
            -command [namespace code [list Done 1]]
        ::ttk::button $S(W).cancel -text [::msgcat::mc Cancel] \
            -command [namespace code [list Done 0]]
        ::tk::AmpWidget ::ttk::button $S(W).apply -text [::msgcat::mc "&Apply"] \
            -command [namespace code [list Apply]]
        wm protocol $S(W) WM_DELETE_WINDOW [namespace code [list Done 0]]

        # Calculate minimum sizes
        ttk::scrollbar $S(W).tmpvs
        set scroll_width [winfo reqwidth $S(W).tmpvs]
        destroy $S(W).tmpvs
        set minsize(gap) 10
        set minsize(bbox) [winfo reqwidth $S(W).ok]
        set minsize(fonts) \
            [expr {[font measure TkDefaultFont "Helvetica"] + $scroll_width}]
        set minsize(styles) \
            [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
        set minsize(sizes) \
            [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
        set min [expr {$minsize(gap) * 4}]
        foreach {what width} [array get minsize] {incr min $width}
        wm minsize $S(W) $min 260

        bind $S(W) <Return> [namespace code [list Done 1]]
        bind $S(W) <Escape> [namespace code [list Done 0]]
        bind $S(W) <Map> [namespace code [list Visibility %W 1]]
        bind $S(W) <Unmap> [namespace code [list Visibility %W 0]]
        bind $S(W) <Destroy> [namespace code [list Visibility %W 0]]
        bind $S(W).lfonts.list <<ListboxSelect>> [namespace code [list Click font]]
        bind $S(W).lstyles.list <<ListboxSelect>> [namespace code [list Click style]]
        bind $S(W).lsizes.list <<ListboxSelect>> [namespace code [list Click size]]
        bind $S(W) <Alt-Key> [list ::tk::AltKeyInDialog $S(W) %A]
        bind $S(W).font <<AltUnderlined>> [list ::focus $S(W).efont]
        bind $S(W).style <<AltUnderlined>> [list ::focus $S(W).estyle]
        bind $S(W).size <<AltUnderlined>> [list ::focus $S(W).esize]
        bind $S(W).apply <<AltUnderlined>> [namespace code [list Apply]]
        bind $WE.strike <<AltUnderlined>> [list $WE.strike invoke]
        bind $WE.under <<AltUnderlined>> [list $WE.under invoke]

        set WS $S(W).sample
        ::ttk::labelframe $WS -text [::msgcat::mc "Sample"]
        ::ttk::label $WS.sample -relief sunken -anchor center \
            -textvariable [namespace which -variable S](sampletext)
        set S(sample) $WS.sample
        grid $WS.sample -sticky news -padx 6 -pady 4
        grid rowconfigure $WS 0 -weight 1
        grid columnconfigure $WS 0 -weight 1
        grid propagate $WS 0

        grid $S(W).ok     -in $bbox -sticky new -pady {0 2}
        grid $S(W).cancel -in $bbox -sticky new -pady 2
        if {$S(-command) ne ""} {
            grid $S(W).apply -in $bbox -sticky new -pady 2
        }
        grid columnconfigure $bbox 0 -weight 1

        grid $WE.strike -sticky w -padx 10
        grid $WE.under -sticky w -padx 10 -pady {0 30}
        grid columnconfigure $WE 1 -weight 1

        grid $S(W).font   x $S(W).style   x $S(W).size   x       -in $outer -sticky w
        grid $S(W).efont  x $S(W).estyle  x $S(W).esize  x $bbox -in $outer -sticky ew
        grid $S(W).lfonts x $S(W).lstyles x $S(W).lsizes x ^     -in $outer -sticky news
        grid $WE          x $WS           - -            x ^     -in $outer -sticky news -pady {15 30}
        grid configure $bbox -sticky n
        grid columnconfigure $outer {1 3 5} -minsize $minsize(gap)
        grid columnconfigure $outer {0 2 4} -weight 1
        grid columnconfigure $outer 0 -minsize $minsize(fonts)
        grid columnconfigure $outer 2 -minsize $minsize(styles)
        grid columnconfigure $outer 4 -minsize $minsize(sizes)
        grid columnconfigure $outer 6 -minsize $minsize(bbox)

        grid $outer -sticky news
        grid rowconfigure $S(W) 0 -weight 1
        grid columnconfigure $S(W) 0 -weight 1

        Init $S(-font)

        trace add variable [namespace which -variable S](size) \
            write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](style) \
            write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](font) \
            write [namespace code [list Tracer]]
    } else {
        Init $S(-font)
    }

    return
}

# ::tk::fontchooser::Done --
#
#       Handles teardown of the dialog, calling -command if needed
#
# Arguments:
#       ok              true if user pressed OK
#
proc ::tk::fontchooser::Done {ok} {
    variable S

    if {! $ok} {
        set S(result) ""
    }
    trace vdelete S(size) w [namespace code [list Tracer]]
    trace vdelete S(style) w [namespace code [list Tracer]]
    trace vdelete S(font) w [namespace code [list Tracer]]
    destroy $S(W)
    if {$ok && $S(-command) ne ""} {
        uplevel #0 $S(-command) [list $S(result)]
    }
}

# ::tk::fontchooser::Apply --
#
#	Call the -command procedure appending the current font
#	Errors are reported via the background error mechanism
#
proc ::tk::fontchooser::Apply {} {
    variable S
    if {$S(-command) ne ""} {
        if {[catch {uplevel #0 $S(-command) [list $S(result)]} err]} {
            ::bgerror $err
        }
    }
    event generate $S(-parent) <<TkFontchooserFontChanged>>
}

# ::tk::fontchooser::Init --
#
#       Initializes dialog to a default font
#
# Arguments:
#       defaultFont     font to use as the default
#
proc ::tk::fontchooser::Init {{defaultFont ""}} {
    variable S

    if {$S(first) || $defaultFont ne ""} {
        if {$defaultFont eq ""} {
            set defaultFont [[entry .___e] cget -font]
            destroy .___e
        }
        array set F [font actual $defaultFont]
        set S(font) $F(-family)
        set S(size) $F(-size)
        set S(strike) $F(-overstrike)
        set S(under) $F(-underline)
        set S(style) [::msgcat::mc "Regular"]
        if {$F(-weight) eq "bold" && $F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Bold Italic"]
        } elseif {$F(-weight) eq "bold"} {
            set S(style) [::msgcat::mc "Bold"]
        } elseif {$F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Italic"]
        }

        set S(first) 0
    }

    Tracer a b c
    Update
}

# ::tk::fontchooser::Click --
#
#       Handles all button clicks, updating the appropriate widgets
#
# Arguments:
#       who             which widget got pressed
#
proc ::tk::fontchooser::Click {who} {
    variable S

    if {$who eq "font"} {
        set S(font) [$S(W).lfonts get [$S(W).lfonts curselection]]
    } elseif {$who eq "style"} {
        set S(style) [$S(W).lstyles get [$S(W).lstyles curselection]]
    } elseif {$who eq "size"} {
        set S(size) [$S(W).lsizes get [$S(W).lsizes curselection]]
    }
    Update
}

# ::tk::fontchooser::Tracer --
#
#       Handles traces on key variables, updating the appropriate widgets
#
# Arguments:
#       standard trace arguments (not used)
#
proc ::tk::fontchooser::Tracer {var1 var2 op} {
    variable S

    set bad 0
    set nstate normal
    # Make selection in each listbox
    foreach var {font style size} {
        set value [string tolower $S($var)]
        $S(W).l${var}s selection clear 0 end
        set n [lsearch -exact $S(${var}s,lcase) $value]
        $S(W).l${var}s selection set $n
        if {$n >= 0} {
            set S($var) [lindex $S(${var}s) $n]
            $S(W).e$var icursor end
            $S(W).e$var selection clear
        } else {                                ;# No match, try prefix
            # Size is weird: valid numbers are legal but don't display
            # unless in the font size list
            set n [lsearch -glob $S(${var}s,lcase) "$value*"]
            set bad 1
            if {$var ne "size" || ! [string is double -strict $value]} {
                set nstate disabled
            }
        }
        $S(W).l${var}s see $n
    }
    if {!$bad} {Update}
    $S(W).ok configure -state $nstate
}

# ::tk::fontchooser::Update --
#
#       Shows a sample of the currently selected font
#
proc ::tk::fontchooser::Update {} {
    variable S

    set S(result) [list $S(font) $S(size)]
    if {$S(style) eq [::msgcat::mc "Bold"]} {lappend S(result) bold}
    if {$S(style) eq [::msgcat::mc "Italic"]} {lappend S(result) italic}
    if {$S(style) eq [::msgcat::mc "Bold Italic"]} {lappend S(result) bold italic}
    if {$S(strike)} {lappend S(result) overstrike}
    if {$S(under)} {lappend S(result) underline}

    $S(sample) configure -font $S(result)
}

# ::tk::fontchooser::Visibility --
#
#	Notify the parent when the dialog visibility changes
#
proc ::tk::fontchooser::Visibility {w visible} {
    variable S
    if {$w eq $S(W)} {
        event generate $S(-parent) <<TkFontchooserVisibility>>
    }
}

# ::tk::fontchooser::ttk_listbox --
#
#	Create a properly themed scrolled listbox.
#	This is exactly right on XP but may need adjusting on other platforms.
#
proc ::tk::fontchooser::ttk_slistbox {w args} {
    set f [ttk::frame $w -style FontchooserFrame -padding 2]
    if {[catch {
        listbox $f.list -relief flat -highlightthickness 0 -borderwidth 0 {*}$args
        ttk::scrollbar $f.vs -command [list $f.list yview]
        $f.list configure -yscrollcommand [list $f.vs set]
        grid $f.list $f.vs -sticky news
        grid rowconfigure $f 0 -weight 1
        grid columnconfigure $f 0 -weight 1
        interp hide {} $w
        interp alias {} $w {} $f.list
    } err opt]} {
        destroy $f
        return -options $opt $err
    }
    return $w
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted library/iconlist.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
# iconlist.tcl
#
#	Implements the icon-list megawidget used in the "Tk" standard file
#	selection dialog boxes.
#
# Copyright © 1994-1998 Sun Microsystems, Inc.
# Copyright © 2009 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# API Summary:
#	tk::IconList <path> ?<option> <value>? ...
#	<path> add <imageName> <itemList>
#	<path> cget <option>
#	<path> configure ?<option>? ?<value>? ...
#	<path> deleteall
#	<path> destroy
#	<path> get <itemIndex>
#	<path> index <index>
#	<path> invoke
#	<path> see <index>
#	<path> selection anchor ?<int>?
#	<path> selection clear <first> ?<last>?
#	<path> selection get
#	<path> selection includes <item>
#	<path> selection set <first> ?<last>?

package require Tk

::tk::Megawidget create ::tk::IconList ::tk::FocusableWidget {
    variable w canvas sbar accel accelCB fill font index \
	itemList itemsPerColumn list maxIH maxIW maxTH maxTW noScroll \
	numItems oldX oldY options rect selected selection textList
    constructor args {
	next {*}$args
	set accelCB {}
    }
    destructor {
	my Reset
	next
    }

    method GetSpecs {} {
	concat [next] {
	    {-command "" "" ""}
	    {-font "" "" "TkIconFont"}
	    {-multiple "" "" "0"}
	}
    }

    # ----------------------------------------------------------------------

    method index i {
	if {![info exist list]} {
	    set list {}
	}
	switch -regexp -- $i {
	    "^-?[0-9]+$" {
		if {$i < 0} {
		    set i 0
		}
		if {$i >= [llength $list]} {
		    set i [expr {[llength $list] - 1}]
		}
		return $i
	    }
	    "^anchor$" {
		return $index(anchor)
	    }
	    "^end$" {
		return [llength $list]
	    }
	    "@-?[0-9]+,-?[0-9]+" {
		scan $i "@%d,%d" x y
		set item [$canvas find closest \
			[$canvas canvasx $x] [$canvas canvasy $y]]
		return [lindex [$canvas itemcget $item -tags] 1]
	    }
	}
    }

    method selection {op args} {
	switch -exact -- $op {
	    anchor {
		if {[llength $args] == 1} {
		    set index(anchor) [$w index [lindex $args 0]]
		} else {
		    return $index(anchor)
		}
	    }
	    clear {
		switch [llength $args] {
		    2 {
			lassign $args first last
		    }
		    1 {
			set first [set last [lindex $args 0]]
		    }
		    default {
			return -code error -errorcode {TCL WRONGARGS} \
			    "wrong # args: should be\
			    \"[lrange [info level 0] 0 1] first ?last?\""
		    }
		}

		set first [$w index $first]
		set last [$w index $last]
		if {$first > $last} {
		    set tmp $first
		    set first $last
		    set last $tmp
		}
		set ind 0
		foreach item $selection {
		    if {$item >= $first} {
			set first $ind
			break
		    }
		    incr ind
		}
		set ind [expr {[llength $selection] - 1}]
		for {} {$ind >= 0} {incr ind -1} {
		    set item [lindex $selection $ind]
		    if {$item <= $last} {
			set last $ind
			break
		    }
		}

		if {$first > $last} {
		    return
		}
		set selection [lreplace $selection $first $last]
		event generate $w <<ListboxSelect>>
		my DrawSelection
	    }
	    get {
		return $selection
	    }
	    includes {
		return [expr {[lindex $args 0] in $selection}]
	    }
	    set {
		switch [llength $args] {
		    2 {
			lassign $args first last
		    }
		    1 {
			set first [set last [lindex $args 0]]
		    }
		    default {
			return -code error -errorcode {TCL WRONGARGS} \
			    "wrong # args: should be\
			    \"[lrange [info level 0] 0 1] first ?last?\""
		    }
		}

		set first [$w index $first]
		set last [$w index $last]
		if {$first > $last} {
		    set tmp $first
		    set first $last
		    set last $tmp
		}

		for {set i $first} {$i <= $last} {incr i} {
		    lappend selection $i
		}
		set selection [lsort -integer -unique $selection]
		event generate $w <<ListboxSelect>>
		my DrawSelection
	    }
	}
    }

    method get item {
	set rTag [lindex $list $item 2]
	lassign $itemList($rTag) iTag tTag text serial
	return $text
    }

    #	Deletes all the items inside the canvas subwidget and reset the
    #	iconList's state.
    #
    method deleteall {} {
	$canvas delete all
	unset -nocomplain selected rect list itemList
	set maxIW 1
	set maxIH 1
	set maxTW 1
	set maxTH 1
	set numItems 0
	set noScroll 1
	set selection {}
	set index(anchor) ""
	$sbar set 0.0 1.0
	$canvas xview moveto 0
    }

    #	Adds an icon into the IconList with the designated image and text
    #
    method add {image items} {
	foreach text $items {
	    set iID item$numItems
	    set iTag [$canvas create image 0 0 -image $image -anchor nw \
			  -tags [list icon $numItems $iID]]
	    set tTag [$canvas create text  0 0 -text  $text  -anchor nw \
			  -font $options(-font) -fill $fill \
			  -tags [list text $numItems $iID]]
	    set rTag [$canvas create rect  0 0 0 0 -fill "" -outline "" \
			  -tags [list rect $numItems $iID]]

	    lassign [$canvas bbox $iTag] x1 y1 x2 y2
	    set iW [expr {$x2 - $x1}]
	    set iH [expr {$y2 - $y1}]
	    if {$maxIW < $iW} {
		set maxIW $iW
	    }
	    if {$maxIH < $iH} {
		set maxIH $iH
	    }

	    lassign [$canvas bbox $tTag] x1 y1 x2 y2
	    set tW [expr {$x2 - $x1}]
	    set tH [expr {$y2 - $y1}]
	    if {$maxTW < $tW} {
		set maxTW $tW
	    }
	    if {$maxTH < $tH} {
		set maxTH $tH
	    }

	    lappend list [list $iTag $tTag $rTag $iW $iH $tW $tH $numItems]
	    set itemList($rTag) [list $iTag $tTag $text $numItems]
	    set textList($numItems) [string tolower $text]
	    incr numItems
	}
	my WhenIdle Arrange
	return
    }

    #	Gets called when the user invokes the IconList (usually by
    #	double-clicking or pressing the Return key).
    #
    method invoke {} {
	if {$options(-command) ne "" && [llength $selection]} {
	    uplevel #0 $options(-command)
	}
    }

    #	If the item is not (completely) visible, scroll the canvas so that it
    #	becomes visible.
    #
    method see rTag {
	if {$noScroll} {
	    return
	}
	set sRegion [$canvas cget -scrollregion]
	if {$sRegion eq ""} {
	    return
	}

	if {$rTag < 0 || $rTag >= [llength $list]} {
	    return
	}

	set bbox [$canvas bbox item$rTag]
	set pad [expr {[$canvas cget -highlightthickness]+[$canvas cget -bd]}]

	set x1 [lindex $bbox 0]
	set x2 [lindex $bbox 2]
	incr x1 [expr {$pad * -2}]
	incr x2 [expr {$pad * -1}]

	set cW [expr {[winfo width $canvas] - $pad*2}]

	set scrollW [expr {[lindex $sRegion 2]-[lindex $sRegion 0]+1}]
	set dispX [expr {int([lindex [$canvas xview] 0]*$scrollW)}]
	set oldDispX $dispX

	# check if out of the right edge
	#
	if {($x2 - $dispX) >= $cW} {
	    set dispX [expr {$x2 - $cW}]
	}
	# check if out of the left edge
	#
	if {($x1 - $dispX) < 0} {
	    set dispX $x1
	}

	if {$oldDispX ne $dispX} {
	    set fraction [expr {double($dispX) / double($scrollW)}]
	    $canvas xview moveto $fraction
	}
    }

    # ----------------------------------------------------------------------

    #	Places the icons in a column-major arrangement.
    #
    method Arrange {} {
	if {![info exists list]} {
	    if {[info exists canvas] && [winfo exists $canvas]} {
		set noScroll 1
		$sbar configure -command ""
	    }
	    return
	}

	set W [winfo width  $canvas]
	set H [winfo height $canvas]
	set pad [expr {[$canvas cget -highlightthickness]+[$canvas cget -bd]}]
	if {$pad < 2} {
	    set pad 2
	}

	incr W [expr {$pad*-2}]
	incr H [expr {$pad*-2}]

	set dx [expr {$maxIW + $maxTW + 8}]
	if {$maxTH > $maxIH} {
	    set dy $maxTH
	} else {
	    set dy $maxIH
	}
	incr dy 2
	set shift [expr {$maxIW + 4}]

	set x [expr {$pad * 2}]
	set y [expr {$pad * 1}] ; # Why * 1 ?
	set usedColumn 0
	foreach sublist $list {
	    set usedColumn 1
	    lassign $sublist iTag tTag rTag iW iH tW tH

	    set i_dy [expr {($dy - $iH)/2}]
	    set t_dy [expr {($dy - $tH)/2}]

	    $canvas coords $iTag $x                    [expr {$y + $i_dy}]
	    $canvas coords $tTag [expr {$x + $shift}]  [expr {$y + $t_dy}]
	    $canvas coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}]

	    incr y $dy
	    if {($y + $dy) > $H} {
		set y [expr {$pad * 1}] ; # *1 ?
		incr x $dx
		set usedColumn 0
	    }
	}

	if {$usedColumn} {
	    set sW [expr {$x + $dx}]
	} else {
	    set sW $x
	}

	if {$sW < $W} {
	    $canvas configure -scrollregion [list $pad $pad $sW $H]
	    $sbar configure -command ""
	    $canvas xview moveto 0
	    set noScroll 1
	} else {
	    $canvas configure -scrollregion [list $pad $pad $sW $H]
	    $sbar configure -command [list $canvas xview]
	    set noScroll 0
	}

	set itemsPerColumn [expr {($H-$pad) / $dy}]
	if {$itemsPerColumn < 1} {
	    set itemsPerColumn 1
	}

	my DrawSelection
    }

    method DrawSelection {} {
	$canvas delete selection
	$canvas itemconfigure selectionText -fill black
	$canvas dtag selectionText
	set cbg [ttk::style lookup TEntry -selectbackground focus]
	set cfg [ttk::style lookup TEntry -selectforeground focus]
	foreach item $selection {
	    set rTag [lindex $list $item 2]
	    foreach {iTag tTag text serial} $itemList($rTag) {
		break
	    }

	    set bbox [$canvas bbox $tTag]
	    $canvas create rect $bbox -fill $cbg -outline $cbg \
		-tags selection
	    $canvas itemconfigure $tTag -fill $cfg -tags selectionText
	}
	$canvas lower selection
	return
    }

    #	Creates an IconList widget by assembling a canvas widget and a
    #	scrollbar widget. Sets all the bindings necessary for the IconList's
    #	operations.
    #
    method Create {} {
	variable hull
	set sbar [ttk::scrollbar $hull.sbar -orient horizontal -takefocus 0]
	catch {$sbar configure -highlightthickness 0}
	set canvas [canvas $hull.canvas -highlightthick 0 -takefocus 1 \
			-width 400 -height 120 -background white]
	pack $sbar -side bottom -fill x -padx 2 -pady {0 2}
	pack $canvas -expand yes -fill both -padx 2 -pady {2 0}

	$sbar configure -command [list $canvas xview]
	$canvas configure -xscrollcommand [list $sbar set]

	# Initializes the max icon/text width and height and other variables
	#
	set maxIW 1
	set maxIH 1
	set maxTW 1
	set maxTH 1
	set numItems 0
	set noScroll 1
	set selection {}
	set index(anchor) ""
	set fg [option get $canvas foreground Foreground]
	if {$fg eq ""} {
	    set fill black
	} else {
	    set fill $fg
	}

	# Creates the event bindings.
	#
	bind $canvas <Configure>	[namespace code {my WhenIdle Arrange}]

	bind $canvas <Button-1>		[namespace code {my Btn1 %x %y}]
	bind $canvas <B1-Motion>	[namespace code {my Motion1 %x %y}]
	bind $canvas <B1-Leave>		[namespace code {my Leave1 %x %y}]
	bind $canvas <Control-Button-1>	[namespace code {my CtrlBtn1 %x %y}]
	bind $canvas <Shift-Button-1>	[namespace code {my ShiftBtn1 %x %y}]
	bind $canvas <B1-Enter>		[list tk::CancelRepeat]
	bind $canvas <ButtonRelease-1>	[list tk::CancelRepeat]
	bind $canvas <Double-ButtonRelease-1> \
	    [namespace code {my Double1 %x %y}]

	bind $canvas <Control-B1-Motion> {;}
	bind $canvas <Shift-B1-Motion>	[namespace code {my ShiftMotion1 %x %y}]

	bind $canvas <Shift-MouseWheel>	[namespace code {my MouseWheel %D}]
	bind $canvas <Option-Shift-MouseWheel>	[namespace code {my MouseWheel %D -12}]


	bind $canvas <<PrevLine>>	[namespace code {my UpDown -1}]
	bind $canvas <<NextLine>>	[namespace code {my UpDown  1}]
	bind $canvas <<PrevChar>>	[namespace code {my LeftRight -1}]
	bind $canvas <<NextChar>>	[namespace code {my LeftRight  1}]
	bind $canvas <Return>		[namespace code {my ReturnKey}]
	bind $canvas <Key>		[namespace code {my KeyPress %A}]
	bind $canvas <Control-Key> ";"
	bind $canvas <Alt-Key>	";"

	bind $canvas <FocusIn>		[namespace code {my FocusIn}]
	bind $canvas <FocusOut>		[namespace code {my FocusOut}]

	return $w
    }

    #	This procedure is invoked when the mouse leaves an entry window with
    #	button 1 down.  It scrolls the window up, down, left, or right,
    #	depending on where the mouse left the window, and reschedules itself
    #	as an "after" command so that the window continues to scroll until the
    #	mouse moves back into the window or the mouse button is released.
    #
    method AutoScan {} {
	if {![winfo exists $w]} return
	set x $oldX
	set y $oldY
	if {$noScroll} {
	    return
	}
	if {$x >= [winfo width $canvas]} {
	    $canvas xview scroll 1 units
	} elseif {$x < 0} {
	    $canvas xview scroll -1 units
	} elseif {$y >= [winfo height $canvas]} {
	    # do nothing
	} elseif {$y < 0} {
	    # do nothing
	} else {
	    return
	}
	my Motion1 $x $y
	set ::tk::Priv(afterId) [after 50 [namespace code {my AutoScan}]]
    }

    # ----------------------------------------------------------------------

    # Event handlers
    method MouseWheel {amount {factor -120.0}} {
	if {$noScroll || $::tk_strictMotif} {
	    return
	}
	$canvas xview scroll [expr {$amount/$factor}] units
    }
    method Btn1 {x y} {
	focus $canvas
	set i [$w index @$x,$y]
	if {$i eq ""} {
	    return
	}
	$w selection clear 0 end
	$w selection set $i
	$w selection anchor $i
    }
    method CtrlBtn1 {x y} {
	if {$options(-multiple)} {
	    focus $canvas
	    set i [$w index @$x,$y]
	    if {$i eq ""} {
		return
	    }
	    if {[$w selection includes $i]} {
		$w selection clear $i
	    } else {
		$w selection set $i
		$w selection anchor $i
	    }
	}
    }
    method ShiftBtn1 {x y} {
	if {$options(-multiple)} {
	    focus $canvas
	    set i [$w index @$x,$y]
	    if {$i eq ""} {
		return
	    }
	    if {[$w index anchor] eq ""} {
		$w selection anchor $i
	    }
	    $w selection clear 0 end
	    $w selection set anchor $i
	}
    }

    #	Gets called on button-1 motions
    #
    method Motion1 {x y} {
	set oldX $x
	set oldY $y
	set i [$w index @$x,$y]
	if {$i eq ""} {
	    return
	}
	$w selection clear 0 end
	$w selection set $i
    }
    method ShiftMotion1 {x y} {
	set oldX $x
	set oldY $y
	set i [$w index @$x,$y]
	if {$i eq ""} {
	    return
	}
	$w selection clear 0 end
	$w selection set anchor $i
    }
    method Double1 {x y} {
	if {[llength $selection]} {
	    $w invoke
	}
    }
    method ReturnKey {} {
	$w invoke
    }
    method Leave1 {x y} {
	set oldX $x
	set oldY $y
	my AutoScan
    }
    method FocusIn {} {
	$w state focus
	if {![info exists list]} {
	    return
	}
	if {[llength $selection]} {
	    my DrawSelection
	}
    }
    method FocusOut {} {
	$w state !focus
	$w selection clear 0 end
    }

    #	Moves the active element up or down by one element
    #
    # Arguments:
    #	amount -	+1 to move down one item, -1 to move back one item.
    #
    method UpDown amount {
	if {![info exists list]} {
	    return
	}
	set curr [$w selection get]
	if {[llength $curr] == 0} {
	    set i 0
	} else {
	    set i [$w index anchor]
	    if {$i eq ""} {
		return
	    }
	    incr i $amount
	}
	$w selection clear 0 end
	$w selection set $i
	$w selection anchor $i
	$w see $i
    }

    #	Moves the active element left or right by one column
    #
    # Arguments:
    #	amount -	+1 to move right one column, -1 to move left one
    #			column
    #
    method LeftRight amount {
	if {![info exists list]} {
	    return
	}
	set curr [$w selection get]
	if {[llength $curr] == 0} {
	    set i 0
	} else {
	    set i [$w index anchor]
	    if {$i eq ""} {
		return
	    }
	    incr i [expr {$amount * $itemsPerColumn}]
	}
	$w selection clear 0 end
	$w selection set $i
	$w selection anchor $i
	$w see $i
    }

    #	Gets called when user enters an arbitrary key in the listbox.
    #
    method KeyPress key {
	append accel $key
	my Goto $accel
	after cancel $accelCB
	set accelCB [after 500 [namespace code {my Reset}]]
    }

    method Goto text {
	if {![info exists list]} {
	    return
	}
	if {$text eq "" || $numItems == 0} {
	    return
	}

	if {[llength [$w selection get]]} {
	    set start [$w index anchor]
	} else {
	    set start 0
	}
	set theIndex -1
	set less 0
	set len [string length $text]
	set len0 [expr {$len - 1}]
	set i $start

	# Search forward until we find a filename whose prefix is a
	# case-insensitive match with $text
	while {1} {
	    if {[string equal -nocase -length $len0 $textList($i) $text]} {
		set theIndex $i
		break
	    }
	    incr i
	    if {$i == $numItems} {
		set i 0
	    }
	    if {$i == $start} {
		break
	    }
	}

	if {$theIndex >= 0} {
	    $w selection clear 0 end
	    $w selection set $theIndex
	    $w selection anchor $theIndex
	    $w see $theIndex
	}
    }
    method Reset {} {
	unset -nocomplain accel
    }
}

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted library/icons.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# icons.tcl --
#
#	A set of stock icons for use in Tk dialogs. The icons used here
#	were provided by the Tango Desktop project which provides a
#	unified set of high quality icons licensed under the
#	Creative Commons Attribution Share-Alike license
#	(http://creativecommons.org/licenses/by-sa/3.0/)
#
#	See http://tango.freedesktop.org/Tango_Desktop_Project
#
# Copyright © 2009 Pat Thoyts <patthoyts@users.sourceforge.net>

namespace eval ::tk::icons {}

image create photo ::tk::icons::warning -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABSZJREFU
    WIXll1toVEcYgL+Zc87u2Yu7MYmrWRuTJuvdiMuqiJd4yYKXgMQKVkSjFR80kFIVJfWCWlvpg4h9
    8sXGWGof8iKNICYSo6JgkCBEJRG8ImYThNrNxmaTeM7pQ5IlJkabi0/9YZhhZv7///4z/8zPgf+7
    KCNRLgdlJijXwRyuDTlcxV9hbzv8nQmxMjg+XDtiOEplkG9PSfkztGmTgmFQd+FCVzwa3fYN/PHZ
    AcpBaReicW5xcbb64IEQqko8Lc26d/58cxS+/BY6hmJvyEfQBoUpwWCmW1FErKaGWHU13uRk4QkE
    UtxQNFR7QwIoB4eiKD9PWbVKbb10CZmaCqmpxCormRYO26QQx85B0mcD+AeK0xYvHqu1tNDx+DH6
    gQM4jh0j3tCA3tGBLyfHLuD7zwJwAcYqun44sHy51nr5MsqsWWj5+djCYdS5c4ldvUr24sU2qarf
    lUL6qAN0wqH0vDy7+fAhXZEI+v79CNmt7igpofPVK5SmJvyhkJBwYlQBSiHd7vUWZ86bp8WqqtCW
    LkVbuBAhBEIItGAQ2+rVxG7cICMY1KTDsekc5IwagIQTmStXis47dzBiMfR9+xCi+wb39s79+zFi
    MczGRjLmzTMlnBoVgLMwyzF+/Cb/lClq2/Xr2AoKUKdPxzAMWltbiUajmKaJkpGBY8sW3tbW4g8E
    VNXrXVEKK0YMoMKp7Px8K15Tg2VZOHbvBiASiRAMBgkGg0QiEYQQOIuLsRSFrnv3yJo/HxVOW594
    7D4KUAa57qysvNSUFOVtbS32rVuRfj9CCFwuV2Kfy+VCCIFMScFVVET7/fukJidLm883rQy+HhaA
    BUII8cvUNWt4W1WFcLvRd+5MnHl/AOjOB+eOHchx44jX1ZEdCqkSTpaDbcgA5+GrpNmzc9ymKdvr
    67Hv2oVMSko4cjgcKIqCoijoup64EdLpxLV3Lx1PnuCVUrgmTfK9hV1DAjgKqlSUk1PCYdl25QrS
    70cvLEw4SWS+04nT6XxvXgiBc8MGtKlTaa+rIysnR1Ok/OF38PxngAzY4VuwYKL99WvR8fQpjj17
    kLqeiL6393g8eDyeAWBSVfEcOkRXczOOaBRvVpZuDPJEDwD4DVyKrv+UlZurxSorUWfMQC8oGOBc
    CDHgC/Rdc4TD2BctIl5fT+bkyTahaXvOw8RPApiwd2Ju7hjZ2EhXSwvOkhKQcoADgIqKCioqKgYc
    QW9LOnIEIxZDbWpiXCCABT9+FKAUxtm83pKMUEiLVVejLVqEtmTJB50LIdi2bRuFPbnRd7232efM
    wbVuHR2PHjHR77dJXS8sg5mDAihweFJenmrevYvR1oazpGTQ6IQQaJqG7ClI/dd655IOHsSyLMSL
    F6QFAib9nugEQClk2Xy+orTsbK3t1i3sa9ei5eQMGr0QgvLyci5evDiocyEEtsxMPNu30/nsGRO8
    XlVzu8NlkNvrV+0T/fHMZcusrtu3MeNx9PXrobUVq8cYQrw3TrRub1h9+v573Bs3Ej1zBvP5c/zp
    6dbLhoaTwPy+ANKCfF92thq7dg2A6JYt/fNlxGK8eUNSerryHEJHQT8K8V4A5ztojty8OeaLzZul
    1DSwLCzDANPEMozusWFgmWZ33288YK3/nGlixuM0v3xpWfDX0Z4i1VupXEWwIgRnJfhGPfQ+YsLr
    +7DzNFwCuvqWyiRg7DSYoIBu9smPkYqEd4AwIN4ITUAL0A4Da7UC6ICdEfy2fUBMoAvo7GnWKNoe
    mfwLcAuinuFNL7QAAAAASUVORK5CYII=
}

image create photo ::tk::icons::error -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABiRJREFU
    WIXFl11sHFcVgL97Z/bX693sbtd2ipOqCU7sQKukFYUigQgv/a+hoZGoqipvfQKpAsEDD0hIvCHE
    j/pQ3sIDUdOiIqUyqXioEFSUhqit7cRJFJpEruxs1mt77Z3d2Z259/KwM5vZXTtOERJXOrozZ+6e
    852fuXcW/s9D3O3Cs1Bow1Nx234BKQ9qpYpK6yFLSseScsVoveApdUrAzNOw9j8DOAMTtmX9RsM3
    SqOjevcXDqUzu8dI5AvEc8O0axu4q6s4yzdZvnCxUSmXLWHMXzxjXpmGq/81wGmIZ6T8NXDi8w8d
    id//+GPS8j1YWQXHgVYbfA/sGCRiMDQExTzKtvn3zDv6k9m5FsacXNT6+y+D95kAZqCEEO/cMzIy
    9eBLLybjyodrN6DpDqw1/dfpFNw3TtuSfPz7P7irlZUL2pjHn4GVuwJ4G/JCiLl9U1OjB58/ZnP5
    Mqxv3NGpMWZAz64cHNzHlTf/5N9YuHzTMeaLx6HW78+K3pwGKynEu/snJycOHPuWzdw81BuDUQZO
    dfQ+MmvAuC1MdY3i178izUo15VZXj07DyTf6OGX0Jivlz0vFwgMTz3/bNnMXO0ZCo8b0iIk4C0WF
    zsP1TRc1e4l9x56N5YuFwxkpf9afgW4J/gi7M1IuHH3lezm5uAQbmwOpjc79ujArA2uMgWwGMz7K
    P377u/WW1pPTUB7IQFrKXx44NJWRbQ9d2+hGqbeRMEoTZEQFJdERfVgmvVFH+D57Jw9k4lL+YqAE
    pyGnjZm+95knLHVjcVvHA6WIPgtLE+hVH4i6vsS9T3zTVsY8NwPZHoAUPFUs5JVQCt1q9zqORKm3
    iLKrF6IjkfSHOiUlqu0hhCSXHdYePNYDEBPiu6MT+zOquo6JGNGhESkxUnYNmkCnLQtjWRgpMRG9
    CtZ3JdD7axsU9+3N2EK8EALYQcNMpvfuQTcaXUMIAa+/Hi0Xgs9weASjefx4p5mFQDdbpD63G/HR
    hakeAA2l+EgJU652iIMMyO2sRoYxBq1191oIgZQSITqooT0A7fnEirswUAp/LwG0MZlYIY9WqpPa
    IHU7Da01Sqluo4UQSil830dr3emVsBeMIZbLoI0Z7gGQQtTbjoOOxW/XewcApVQ38jsBNs6fx6tW
    O70Si+GWKwghNsM1NoCAW81KJTeUjKNbrR2N7uS4B7TRwJ+fR6TTxO4fxzUeAio9AMCl+tVrE0NH
    DmM2nU4DAu6JE53UGoNfLuNdv45xnO4OF/ZKz+4X2T179I6D5To0NupouNgD4Btzqjx/8WjpS0cy
    PU1Tr6MqFfylpc4bss1W26/rBwyfybECtcvXNrUxp3oAXJjZ2Kxb7cVP8P61gDGgWy2M624Z5d1E
    3wNkDDKdwMQkjtuygbMhgAQ4DjUhxFvL/5z15X1jeLUaynW7p1u484WiuL3V9m/NoV6F50Ogjx3Y
    Q/mDBV8a3piGzR4AAFfrHy4vlesmm0bks7edRQ6aAafcPoZVH2AUXOYzkI5TvbVa9+FHREYX4Bgs
    I8RrV9/9oJF4eBKTjO8YvdoCJgqujcGkEqQemmDxb7OOFOLV6FHcAwBQ1/onTtOd/fTvH3rJRx/A
    pBIDqd0q+p5sRaInnWDoywdZem+u7bbaH9W1/il9Y2Brfwt22TBfKOVHxr92JOacv4S/UuttuC06
    PKoHsEs5hg7vZ/m9eW+zWltuwoNbfRNuebacgXsEnE2lkof2Hn04ZRouzQvXUU5z29cwFGs4TWpy
    HJGK8+lfP256bnuuDU8+B9WtfG17uL0GsTF4VQrxYn60kBh55JDEbdG6uYq/7qDdFtpTELOQyQRW
    Lk1sLI+MW9w6d8Wv3Vrz2nDyJPzgDDS287MVgAAywBCQ+Q5MTsOPs/BIMpVQ2bFCKlnMYg+nsYeS
    eE6TVq1Be3WD9ZtrTc9tWetw7k341dtwBagDTmTeESAdAAxH5z0w9iQ8ehi+moWxBGRsiPvguVBf
    h8qH8P6f4dxSp9PrdN73cN6k859R3U0J0nS+28JMpIM5FUgCiNP5X2ECox7gAk06KQ8ldLzZ7/xO
    ANHnscBhCkgGjuOB3gb8CEAbaAWO3UA34DQ6/gPnmhBFs5mqXAAAAABJRU5ErkJggg==
}

image create photo ::tk::icons::information -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
    WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gUdFDM4pWaDogAABwNJREFUWMPFlltsVNcVhv+199ln
    bh7PjAdfMGNDcA04EKMkJlIsBVJVbRqlEVUrqyW0QAtFTVWpjVpFfamUF6K+tCTKQyXn0jaiShOr
    bRqRoHJpEEoIEBucENuk2OViPB5f5j5zrvuc3YcMFQ8FPBFVj7S0paN91v+tf1/OAv7PD9UzeeCp
    p0KRCrYyHtymoPrgySYAANdyBBr2Peu1agP+NrR/v3nHAb6/52d7wfivWlet11NdvZG21laEwzo0
    RvA9F4uLi7h08bxxaWLUVp78xSsv/XrwjgAMDDyjRxPWUGOy5Uu9/VsjEA3I5KvIVQ240gHIh9CA
    5YkwelIJRATw94NvGpnpK0fL+eDA0NAzzq3ya7cDjCbsoWWr1j+y4f4vB/41Z8JTeaxqE7hndSNi
    EeELzn3LkapQdfzJTE5JV/GBb28LHz327lcnzp4ZAvB1AOpmAvyWtv/g6R9GW1c+uf6Bx0Kfzpjo
    TmnYtDaKtkTAj4aEFBqTnJPUOfciIeG3N4XVQtmyzl/JuY8/fH9wOjO/smvVmuy5s+8P1w2wa9dP
    46SLN3sf2ha7uiixaU0Qna06NA6PMXIZQRJBMiIXRBKABygv3hBQV+bK1dmcoR7d3Bc5c/pk/8YN
    fYOjo6es/6bDbgbAdLa9uXNj2PYF2pOEloQGAiRIuUTkME42J7IZweYES+NkckZWWNfseEPAKJtO
    oWxLu69/c5jpbPtNdW7qPwvsbO1cF8pVLKxs0+HD94gpl0AOQTlEsDkjizFmMk4WESyNM4NzMgOC
    VYI6q17OlIp9992ngek769+EvtfVEI3jWqaKgAgAIAlFLuOwGZHDiTnElGQgF4DvM1LKV7Bdz2NE
    xaCuhQpVm1Y0p5qhvNV1AyjlRTWhwVM2TMdzgkJzieAQyGGMbMZgfwZBEiBPA3xX+VSouAvBAFeM
    yDddD7rgpHw/WjcAMa0EZScZk5heqFrxiO4BzCGCzYgsBrI4I5sYcxlBKl/5WdOdd6S0gxoLEZEi
    Iq4AnzGq1r0HiPhYuZRFU1R3FgqWkS1aZQA2gWzOyGQcJudkaAwVR3qz8yXzvCXlzJoViaagrlWC
    jJnLm8Jarli2GNMm6wbwPPO31y6Ollc2N3pcI+fyYjW/8a5EKqQTz5WtdLHsTi1W7Im5vDlcMdxx
    wVk2Ys9/pTI3+WhAaIauM+MLbYnlH46MVKVyX6v7Hhg9e2ps3doN32ld0Rlrb1nmmK4stCdCSCUj
    Le1NwW6uXJ08m/t2OarBXh0ie0syHu0plKtTFGw8n4o33q1z1XngD7+X3C/uHBkZces7hoAi1946
    fPSvtpDlYFdLPDI8mR03HC87frXwFpgqLYuFuzrbkg8m49EeDsqDa+cizXcNpppia5ui+sYXnn+O
    29LbOTg4aHzun9GOPT/pDemhf3xzx25DicjkiqaAIs4zhumMRUJaPhzgJZ0LQ5C7gXjQL1kS0YD+
    o337nhWlYvHJV178zZ9vlZ/dDuDVl57/2HWt755894hINoYSmZx11TYKCUZKCs4cnQuDmGtfvDiR
    dD3n04aA6J4YHzeLhfLg7cSXBAAA5NPpufS1WFjwkFSelZ6ZLWfn0kliTDJdue8dO9qenp2d1DVR
    4cTarlyZJgV5dim5lwTw8sv7c1L6H89cm6FlDcHVhlOJffThsa9d+ud72y5+cnTn2PjJJ1avjOoE
    SnBiPadOfRDTGT5YSm5tqR2R7Zp7//L6gRPf27NjVaolqS9MCzh28W6mgDXdKxCNRb/oOlV18O3D
    1xzXGXpx8LnZO94Tbt/x+MFYouexh7dsQU/PWjRGI+BcAyMgm1vAO28fxvj4xOX5jL7u0KEX7Dvq
    AAC0Nucf2rLZhq8Y3njjT8gulOBKDw0NAQjNQT435eQWL3iHDk3YS81ZF0B6psI/GbuAXbu+gQf7
    H4ArPeQWC5jLZKCUhQvjWb2QD3bVk5PVM9nz5LML8waOH38fekBHIhFDqqMFXd0pnDhxGmMTU3Bd
    9/X/GQDntO/eezswMPBjaFwAABxH4sKFq+jt7cX6ni6EQuJbdeWsZ3J3d/PTmqaEYUyhXDZBTEOh
    WIIQwOi5jzA1eRnZXPFSPO7/bmbGlLfqhus5BVotRH9/x7rGxtBeIQJPACrMOYNSPpRiUIpnlTIO
    nzmT+eX8fLH8WZMKF4Csje7ncUAHEKhFcHq6ZE5OZoc7O3tlc3N33+7dP9c2bXoE09NlO52uHDhy
    ZOTVatUWte+otsTXg2pQSwagG6r/jwsAQul0erqjo+OesbGx1tHRUT+fz48dP378j57neQD8mtB1
    B1TtnV9zo64loJqoXhtFDUQHEGhvb2/2fZ9nMpliTcAFYNdC1sIBYN1sCeq5Ca9bqtWcu9Fe3FDl
    9Uqvu3HLjfhvTUo85WzjhogAAAAASUVORK5CYII=
}

image create photo ::tk::icons::question -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAACG5JREFU
    WIXFl3twVdUVxn97n3Nubm7euZcghEdeBBICEQUFIgVECqIo1uJMp3WodqyjMzpjZ7TTh20cK31N
    /2jL2FYdKXaqRcbnDKGpoBFaAY1BHgHMgyRKQkJy87yv3Nyzd/84594k1RlppzPumTXn3Dl3r/Wd
    b31rrbPhS17iSv+4bl2t2ZFhrRGI7QKxRkMAyHEfjwgYEOgjNnpfcXjiSENDbeL/AqBoW22uGE/7
    MYL7yubN4MYVpVkrquaKqwJZ+LPTARgcjdIbHKOx+aI+9EH7WGvnZdA8q9PGf9b5eu3w/wygaPPO
    h6Uhntxcsyj9/q+vtMrnBa6Is7ZPgzzzyvGJ/YfPRpWWj3fWff93/xWAonW1Xu3z/nVx6cxNTz74
    1YzK4gIQjuN/nfyEEx9fIjgaYXAkhhAQyE3Hn5PBsvJZrF46l5I5+QB83NnP40+/FT7d1ltPOPrN
    zoba2BcCWLy91hMOp72/bX1VxU/u3+BJ91i0fhrkuTcaaTzbjTQkhpQIIZBSIBApL1prtNYsryhk
    xy1XUzonn1g8wVPPvh1/5dDpcz5f7LrmfbXxqfGM6eG1yCw+9uq2G6tW7nxoU5plGrzecJYnnnub
    SwMhTNPAmmKmYWCaBoYpMQyJaRhIQ3IpGOKt4+1k+dKoLJ7BjStKjb6hcN7JloFrhlsO7oUnPh9A
    8Rbvo6uuLrr3N4/ckm4Ykt/vPcqe/R9hGAamaWJZbnDL+W2axqRJA8NlxzAkAI3newhF4lxbMZs1
    y4rNM+19c0PZ++NDLQff+0wKCu/Y6c/UVsubv/12/ryZubxUf5Ln3vgQ0zKnvK1kadkMlpQUUFEU
    oCDPR25WOuPxBH2DYZpa+qg/3kEoGsdWCttWJGzF3ZuXcuf6Ci5eHmXrw7sHR4mXd7/2w+A0Bvyl
    N+265/bl19+8eqE8c6GPn+85jGkYWC4Ay3Luf/3AV1g038+MXB8+rwfDkKR5TPKyvCyan8+qqtmc
    au8nFrcdnQCn2vuoLptJSWEeE7bynDjdXTDUcvBNAAmweF1tpmXKu+65bYWh0Ty97zhSyGkUO0BM
    hBAI4RAXTyjiCYWUEukKMz/Ly/b1C7EsE49lYlkmhjTYvf8jNHD3lmsM0zTuWryuNhPABIj4vFvW
    Xl0s87PTOdXWS8snQTwec4ro3DSYBglbcfx8P+8199I7FMEQgg3L53N7TWkKXOV8Px7LJCFtXKx0
    dA9zrnOAyqIAa68tkQePtm4BXpaO9vWOm65b4EPAkY+6HDEZTt4NN/dJML946QSv/fMCA6PjpHks
    LI/F2a5BtNYpMUtJirGpLL7f3A3AxpXlPiHFjhQDaJZVlc0EoPWT4DQ1m8ZkKizTJDRuY1mmC04i
    pWDNksJUD9Bac7E/jGUZrmuN1qCU5sKlIQAqSwrQWi+bBCDwF+RnAk5fl27wqeYAkZM9wLWaxVex
    qnJmKritFO+e7sMyDdBOc1JKYxiSkdA4CMGM3Aw02j+VAfLcwTIWibuiEpNApJMSw208ydJcu3QW
    axZPCW7bHGjspmcwimkYTmAlMWzHTyTmDMiczLRU/ctkNxgajboPvUghppuUGFJMY6O6OJ/ViwIo
    pVBKYds2dR9e4uPuMbc7Tm9MUgqyM70AjITHUy1IAghNsH8oDEAgz4cQOIqWjkkpEC4rSYfXL/Sn
    giulONYyRFd/1GXKAZxkUrgvkp/tAAgORxAQnAQg5InmC5cBWDgv4NS5EAhAINzyIlVmUgiy040U
    9Uop2voiKYakEAiRvDp7EYKS2XkAnOvsR0h5IqUBrfWeQ8fb1t2xvtJXs3QuB462TfZokbxMGZxC
    8If6DtI8Fh6PhcdjojSpBuXin7Kc3csXzQLgrWOtEWWrPSkAvkis7kjTBTU8FqOypIAF8/x09Y6Q
    FGjyTdHJstLsWDsnNZIBXj7Wj1LKYSS5B412nRTNymHBnHxGQ+O8836r8kVidakUNDfUhhIJtfcv
    dU22AO69dRlCCNeZU8fJe6U0ylZYBlgGmNKx+ESCiYRNwlYoWzn/UxqtHOB3ra8AAX/7x0nbttXe
    5oba0GQVAPGE9dju1z4Y7u4fY9F8P9/YWOUEV06O7eTVnXBTBaiUIj4xwcSETSJhk7BtbNtOPdta
    U0ZpYS59wRB/2ndsOBa3HkvGTU3D0fb6aE7ZBt3RM1yzuabcqiwKEI5N0N495ChaSKcihJPRa0pz
    sbUmYTugPmgbJmErB4DLxETC5oYlhWxdXUrCVvxgV32krav/qa4Djx76D4kllxalt/7q9e2bqjf9
    9Lsb0oQQHGrsYO+hc0gp3emW/Bhxm5NbZlqD0g79CTcFt60u4YYlhWhg5/MN4y/WNdW3vfnoNhD6
    Mww46wlmV9/w6snzA1sHRqKBVUvnGQvm+qkuKyA4GqVvKOJAdrcn8zz14yNh2ywozOVbGyuoKg4w
    PmHzyxcOx1+sazqTlhbZ3H92vT29Pj5nzVn1SLqVH3ipunzOxqceutlX6n7lXrw8yqn2flq7hxgL
    TzAWiyOFICfTS44vjbLCXKqK/cwOOHOl49IwP9r192hT84V3e4+9cF90sC0IRL8QAOADsgvXfu9B
    b3bgkTs3LPN+52srzPlX5V7RUerTy6M8/0Zj4uUDH45Hg13PdB/9425gzLUhQH0RgDQgC8hKLyid
    7a/c9oCV4d9WVTpLbF5TmX5tRaGYkecjJ8MLAkZD4wyMRGg636PrDjfHzrT26NhYT33w1Kt/Hh/u
    6XUDh4BBIHwlDIBTohlANpBhWb6s7PKNK30FCzZa6dnVYORoIX2OExVF26Px8NCZSN/5d0bb3mlK
    JGIhHLpDwLAL4jPnxSs9nBqABXhddrw4XdRygSrABuKuxYBx9/6KDqlf2vo3PYe56vmkuwMAAAAA
    SUVORK5CYII=
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































Changes to library/images/logo.eps.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
%AI5_NumLayers: 1
%AI5_OpenToView: 90 576 2 938 673 18 1 1 2 40
%AI5_OpenViewLayers: 7
%%EndComments
%%BeginProlog
%%BeginResource: procset Adobe_level2_AI5 1.0 0
%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
%%Version: 1.0
%%CreationDate: (04/10/93) ()
%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
userdict /Adobe_level2_AI5 21 dict dup begin
	put
	/packedarray where not
	{
		userdict begin







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
%AI5_NumLayers: 1
%AI5_OpenToView: 90 576 2 938 673 18 1 1 2 40
%AI5_OpenViewLayers: 7
%%EndComments
%%BeginProlog
%%BeginResource: procset Adobe_level2_AI5 1.0 0
%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
%%Version: 1.0 
%%CreationDate: (04/10/93) ()
%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
userdict /Adobe_level2_AI5 21 dict dup begin
	put
	/packedarray where not
	{
		userdict begin
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
				4 index mul 4 1 roll
			} repeat
			5 -1 roll pop
			setcmykcolor
		}
		def
	} if

	/gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
	userdict /level2?
	systemdict /languagelevel known dup
	{
		pop systemdict /languagelevel get 2 ge
	} if







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
				4 index mul 4 1 roll
			} repeat
			5 -1 roll pop
			setcmykcolor
		}
		def
	} if
	
	/gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
	userdict /level2?
	systemdict /languagelevel known dup
	{
		pop systemdict /languagelevel get 2 ge
	} if
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		/customColor? isCMYKSep? not def
	 end
	} if
 end defaultpacking setpacking
%%EndResource
%%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0
%%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog)
%%Version: 1.1
%%CreationDate: (3/7/1994) ()
%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
currentpacking true setpacking
userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin
put
/_lp /none def
/_pf







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		/customColor? isCMYKSep? not def
	 end
	} if
 end defaultpacking setpacking
%%EndResource
%%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0
%%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog)
%%Version: 1.1 
%%CreationDate: (3/7/1994) ()
%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
currentpacking true setpacking
userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin
put
/_lp /none def
/_pf
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	{
		0 eq
		{
			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
		}
		{
			/clipForward? true def

			/Tx /pop load def
			/Tj /pop load def
			currentdict end clipRenderOff begin begin
		} ifelse
	}
	{
		0 eq







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	{
		0 eq
		{
			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
		}
		{
			/clipForward? true def
			
			/Tx /pop load def
			/Tj /pop load def
			currentdict end clipRenderOff begin begin
		} ifelse
	}
	{
		0 eq
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		pop
		clipForward?
		{
			currentdict
		 end
		 end
		 begin

			/clipForward? false ddef
		} if
	} ifelse
} bind def
/Pb
{
	pop pop







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		pop
		clipForward?
		{
			currentdict
		 end
		 end
		 begin
			
			/clipForward? false ddef
		} if
	} ifelse
} bind def
/Pb
{
	pop pop

Changes to library/images/pwrdLogo.eps.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
%AI5_NumLayers: 1
%AI5_OpenToView: 102 564 2 938 673 18 1 1 2 40
%AI5_OpenViewLayers: 7
%%EndComments
%%BeginProlog
%%BeginResource: procset Adobe_level2_AI5 1.0 0
%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
%%Version: 1.0
%%CreationDate: (04/10/93) ()
%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
userdict /Adobe_level2_AI5 21 dict dup begin
	put
	/packedarray where not
	{
		userdict begin







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
%AI5_NumLayers: 1
%AI5_OpenToView: 102 564 2 938 673 18 1 1 2 40
%AI5_OpenViewLayers: 7
%%EndComments
%%BeginProlog
%%BeginResource: procset Adobe_level2_AI5 1.0 0
%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
%%Version: 1.0 
%%CreationDate: (04/10/93) ()
%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
userdict /Adobe_level2_AI5 21 dict dup begin
	put
	/packedarray where not
	{
		userdict begin
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
				4 index mul 4 1 roll
			} repeat
			5 -1 roll pop
			setcmykcolor
		}
		def
	} if

	/gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
	userdict /level2?
	systemdict /languagelevel known dup
	{
		pop systemdict /languagelevel get 2 ge
	} if







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
				4 index mul 4 1 roll
			} repeat
			5 -1 roll pop
			setcmykcolor
		}
		def
	} if
	
	/gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
	userdict /level2?
	systemdict /languagelevel known dup
	{
		pop systemdict /languagelevel get 2 ge
	} if
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		/customColor? isCMYKSep? not def
	 end
	} if
 end defaultpacking setpacking
%%EndResource
%%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0
%%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog)
%%Version: 1.1
%%CreationDate: (3/7/1994) ()
%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
currentpacking true setpacking
userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin
put
/_lp /none def
/_pf







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		/customColor? isCMYKSep? not def
	 end
	} if
 end defaultpacking setpacking
%%EndResource
%%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0
%%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog)
%%Version: 1.1 
%%CreationDate: (3/7/1994) ()
%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
currentpacking true setpacking
userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin
put
/_lp /none def
/_pf
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	{
		0 eq
		{
			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
		}
		{
			/clipForward? true def

			/Tx /pop load def
			/Tj /pop load def
			currentdict end clipRenderOff begin begin
		} ifelse
	}
	{
		0 eq







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	{
		0 eq
		{
			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
		}
		{
			/clipForward? true def
			
			/Tx /pop load def
			/Tj /pop load def
			currentdict end clipRenderOff begin begin
		} ifelse
	}
	{
		0 eq
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		pop
		clipForward?
		{
			currentdict
		 end
		 end
		 begin

			/clipForward? false ddef
		} if
	} ifelse
} bind def
/Pb
{
	pop pop







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		pop
		clipForward?
		{
			currentdict
		 end
		 end
		 begin
			
			/clipForward? false ddef
		} if
	} ifelse
} bind def
/Pb
{
	pop pop

Changes to library/listbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# listbox.tcl --
#
# This file defines the default bindings for Tk listbox widgets
# and provides procedures that help in implementing those bindings.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 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.

#--------------------------------------------------------------------------
# tk::Priv elements used in this file:
#
# afterId -		Token returned by "after" for autoscanning.
# listboxPrev -	The last element to be selected or deselected
#			during a selection operation.
# listboxSelection -	All of the items that were selected before the
#			current selection operation (such as a mouse
#			drag) started;  used to cancel an operation.
#--------------------------------------------------------------------------

#-------------------------------------------------------------------------
# The code below creates the default class bindings for listboxes.
#-------------------------------------------------------------------------

# Note: the check for existence of %W below is because this binding
# is sometimes invoked after a window has been deleted (e.g. because
# there is a double-click binding on the widget that deletes it).  Users
# can put "break"s in their bindings to avoid the error, but this check
# makes that unnecessary.

bind Listbox <Button-1> {
    if {[winfo exists %W]} {
	tk::ListboxBeginSelect %W [%W index @%x,%y] 1
    }
}

# Ignore double clicks so that users can define their own behaviors.
# Among other things, this prevents errors if the user deletes the
# listbox on a double click.

bind Listbox <Double-Button-1> {
    # Empty script
}

bind Listbox <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::ListboxMotion %W [%W index @%x,%y]
}
bind Listbox <ButtonRelease-1> {
    tk::CancelRepeat
    %W activate @%x,%y
}
bind Listbox <Shift-Button-1> {
    tk::ListboxBeginExtend %W [%W index @%x,%y]
}
bind Listbox <Control-Button-1> {
    tk::ListboxBeginToggle %W [%W index @%x,%y]
}
bind Listbox <B1-Leave> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::ListboxAutoScan %W
}
bind Listbox <B1-Enter> {
    tk::CancelRepeat
}

bind Listbox <<PrevLine>> {
    tk::ListboxUpDown %W -1
}
bind Listbox <<SelectPrevLine>> {
    tk::ListboxExtendUpDown %W -1
}
bind Listbox <<NextLine>> {
    tk::ListboxUpDown %W 1
}
bind Listbox <<SelectNextLine>> {
    tk::ListboxExtendUpDown %W 1
}
bind Listbox <<PrevChar>> {
    %W xview scroll -1 units
}
bind Listbox <<PrevWord>> {
    %W xview scroll -1 pages
}
bind Listbox <<NextChar>> {
    %W xview scroll 1 units
}
bind Listbox <<NextWord>> {
    %W xview scroll 1 pages
}
bind Listbox <Prior> {
    %W yview scroll -1 pages
    %W activate @0,0
}
bind Listbox <Next> {
    %W yview scroll 1 pages
    %W activate @0,0
}
bind Listbox <Control-Prior> {
    %W xview scroll -1 pages
}
bind Listbox <Control-Next> {
    %W xview scroll 1 pages
}
bind Listbox <<LineStart>> {
    %W xview moveto 0
}
bind Listbox <<LineEnd>> {
    %W xview moveto 1
}
bind Listbox <Control-Home> {
    %W activate 0
    %W see 0
    %W selection clear 0 end
    %W selection set 0
    tk::FireListboxSelectEvent %W
}
bind Listbox <Control-Shift-Home> {
    tk::ListboxDataExtend %W 0
}
bind Listbox <Control-End> {
    %W activate end
    %W see end
    %W selection clear 0 end
    %W selection set end
    tk::FireListboxSelectEvent %W
}
bind Listbox <Control-Shift-End> {
    tk::ListboxDataExtend %W [%W index end]
}
bind Listbox <<Copy>> {
    if {[selection own -displayof %W] eq "%W"} {
	clipboard clear -displayof %W
	clipboard append -displayof %W [selection get -displayof %W]
    }





|
|
|








|
















|









|












|


|











|


|


|


|


|


|


|


|
















|


|









|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# listbox.tcl --
#
# This file defines the default bindings for Tk listbox widgets
# and provides procedures that help in implementing those bindings.
#
# Copyright (c) 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.

#--------------------------------------------------------------------------
# tk::Priv elements used in this file:
#
# afterId -		Token returned by "after" for autoscanning.
# listboxPrev -		The last element to be selected or deselected
#			during a selection operation.
# listboxSelection -	All of the items that were selected before the
#			current selection operation (such as a mouse
#			drag) started;  used to cancel an operation.
#--------------------------------------------------------------------------

#-------------------------------------------------------------------------
# The code below creates the default class bindings for listboxes.
#-------------------------------------------------------------------------

# Note: the check for existence of %W below is because this binding
# is sometimes invoked after a window has been deleted (e.g. because
# there is a double-click binding on the widget that deletes it).  Users
# can put "break"s in their bindings to avoid the error, but this check
# makes that unnecessary.

bind Listbox <1> {
    if {[winfo exists %W]} {
	tk::ListboxBeginSelect %W [%W index @%x,%y] 1
    }
}

# Ignore double clicks so that users can define their own behaviors.
# Among other things, this prevents errors if the user deletes the
# listbox on a double click.

bind Listbox <Double-1> {
    # Empty script
}

bind Listbox <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::ListboxMotion %W [%W index @%x,%y]
}
bind Listbox <ButtonRelease-1> {
    tk::CancelRepeat
    %W activate @%x,%y
}
bind Listbox <Shift-1> {
    tk::ListboxBeginExtend %W [%W index @%x,%y]
}
bind Listbox <Control-1> {
    tk::ListboxBeginToggle %W [%W index @%x,%y]
}
bind Listbox <B1-Leave> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::ListboxAutoScan %W
}
bind Listbox <B1-Enter> {
    tk::CancelRepeat
}

bind Listbox <Up> {
    tk::ListboxUpDown %W -1
}
bind Listbox <Shift-Up> {
    tk::ListboxExtendUpDown %W -1
}
bind Listbox <Down> {
    tk::ListboxUpDown %W 1
}
bind Listbox <Shift-Down> {
    tk::ListboxExtendUpDown %W 1
}
bind Listbox <Left> {
    %W xview scroll -1 units
}
bind Listbox <Control-Left> {
    %W xview scroll -1 pages
}
bind Listbox <Right> {
    %W xview scroll 1 units
}
bind Listbox <Control-Right> {
    %W xview scroll 1 pages
}
bind Listbox <Prior> {
    %W yview scroll -1 pages
    %W activate @0,0
}
bind Listbox <Next> {
    %W yview scroll 1 pages
    %W activate @0,0
}
bind Listbox <Control-Prior> {
    %W xview scroll -1 pages
}
bind Listbox <Control-Next> {
    %W xview scroll 1 pages
}
bind Listbox <Home> {
    %W xview moveto 0
}
bind Listbox <End> {
    %W xview moveto 1
}
bind Listbox <Control-Home> {
    %W activate 0
    %W see 0
    %W selection clear 0 end
    %W selection set 0
    tk::FireListboxSelectEvent %W
}
bind Listbox <Shift-Control-Home> {
    tk::ListboxDataExtend %W 0
}
bind Listbox <Control-End> {
    %W activate end
    %W see end
    %W selection clear 0 end
    %W selection set end
    tk::FireListboxSelectEvent %W
}
bind Listbox <Shift-Control-End> {
    tk::ListboxDataExtend %W [%W index end]
}
bind Listbox <<Copy>> {
    if {[selection own -displayof %W] eq "%W"} {
	clipboard clear -displayof %W
	clipboard append -displayof %W [selection get -displayof %W]
    }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178





179
180
181
182
183
184
185
186
187
188



189



















190
191
192
193
194
195
196
}
bind Listbox <Shift-Select> {
    tk::ListboxBeginExtend %W [%W index active]
}
bind Listbox <Escape> {
    tk::ListboxCancel %W
}
bind Listbox <<SelectAll>> {
    tk::ListboxSelectAll %W
}
bind Listbox <<SelectNone>> {
    if {[%W cget -selectmode] ne "browse"} {
	%W selection clear 0 end
        tk::FireListboxSelectEvent %W
    }
}

# Additional Tk bindings that aren't part of the Motif look and feel:

bind Listbox <Button-2> {
    %W scan mark %x %y
}
bind Listbox <B2-Motion> {
    %W scan dragto %x %y
}






bind Listbox <MouseWheel> {
    tk::MouseWheel %W y %D -30.0
}
bind Listbox <Option-MouseWheel> {
    tk::MouseWheel %W y %D -3.0
}
bind Listbox <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -30.0
}
bind Listbox <Shift-Option-MouseWheel> {



    tk::MouseWheel %W x %D -3.0



















}

# ::tk::ListboxBeginSelect --
#
# This procedure is typically invoked on button-1 presses.  It begins
# the process of making a selection in the listbox.  Its exact behavior
# depends on the selection mode currently in effect for the listbox;







|


|








|






>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
}
bind Listbox <Shift-Select> {
    tk::ListboxBeginExtend %W [%W index active]
}
bind Listbox <Escape> {
    tk::ListboxCancel %W
}
bind Listbox <Control-slash> {
    tk::ListboxSelectAll %W
}
bind Listbox <Control-backslash> {
    if {[%W cget -selectmode] ne "browse"} {
	%W selection clear 0 end
        tk::FireListboxSelectEvent %W
    }
}

# Additional Tk bindings that aren't part of the Motif look and feel:

bind Listbox <2> {
    %W scan mark %x %y
}
bind Listbox <B2-Motion> {
    %W scan dragto %x %y
}

# The MouseWheel will typically only fire on Windows and Mac OS X.
# However, someone could use the "event generate" command to produce
# one on other platforms.

if {[tk windowingsystem] eq "aqua"} {
    bind Listbox <MouseWheel> {
        %W yview scroll [expr {- (%D)}] units
    }
    bind Listbox <Option-MouseWheel> {
        %W yview scroll [expr {-10 * (%D)}] units
    }
    bind Listbox <Shift-MouseWheel> {
        %W xview scroll [expr {- (%D)}] units
    }
    bind Listbox <Shift-Option-MouseWheel> {
        %W xview scroll [expr {-10 * (%D)}] units
    }
} else {
    bind Listbox <MouseWheel> {
        %W yview scroll [expr {- (%D / 120) * 4}] units
    }
}

if {"x11" eq [tk windowingsystem]} {
    # Support for mousewheels on Linux/Unix commonly comes through mapping
    # the wheel to the extended buttons.  If you have a mousewheel, find
    # Linux configuration info at:
    #	http://www.inria.fr/koala/colas/mouse-wheel-scroll/
    bind Listbox <4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind Listbox <5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 5 units
	}
    }
}

# ::tk::ListboxBeginSelect --
#
# This procedure is typically invoked on button-1 presses.  It begins
# the process of making a selection in the listbox.  Its exact behavior
# depends on the selection mode currently in effect for the listbox;
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
		$w selection clear $i $el
		$w selection clear anchor $el
	    }
	    if {![info exists Priv(listboxSelection)]} {
		set Priv(listboxSelection) [$w curselection]
	    }
	    while {($i < $el) && ($i < $anchor)} {
		if {$i in $Priv(listboxSelection)} {
		    $w selection set $i
		}
		incr i
	    }
	    while {($i > $el) && ($i > $anchor)} {
		if {$i in $Priv(listboxSelection)} {
		    $w selection set $i
		}
		incr i -1
	    }
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}







|





|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
		$w selection clear $i $el
		$w selection clear anchor $el
	    }
	    if {![info exists Priv(listboxSelection)]} {
		set Priv(listboxSelection) [$w curselection]
	    }
	    while {($i < $el) && ($i < $anchor)} {
		if {[lsearch $Priv(listboxSelection) $i] >= 0} {
		    $w selection set $i
		}
		incr i
	    }
	    while {($i > $el) && ($i > $anchor)} {
		if {[lsearch $Priv(listboxSelection) $i] >= 0} {
		    $w selection set $i
		}
		incr i -1
	    }
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
    if {$first > $last} {
	set tmp $first
	set first $last
	set last $tmp
    }
    $w selection clear $first $last
    while {$first <= $last} {
	if {$first in $Priv(listboxSelection)} {
	    $w selection set $first
	}
	incr first
    }
    tk::FireListboxSelectEvent $w
}








|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    if {$first > $last} {
	set tmp $first
	set first $last
	set last $tmp
    }
    $w selection clear $first $last
    while {$first <= $last} {
	if {[lsearch $Priv(listboxSelection) $first] >= 0} {
	    $w selection set $first
	}
	incr first
    }
    tk::FireListboxSelectEvent $w
}

Deleted library/megawidget.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# megawidget.tcl
#
#	Basic megawidget support classes. Experimental for any use other than
#	the ::tk::IconList megawdget, which is itself only designed for use in
#	the Unix file dialogs.
#
# Copyright © 2009-2010 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

package require Tk

::oo::class create ::tk::Megawidget {
    superclass ::oo::class
    method unknown {w args} {
	if {[string match .* $w]} {
	    [self] create $w {*}$args
	    return $w
	}
	next $w {*}$args
    }
    unexport new unknown
    self method create {name superclasses body} {
	next $name [list \
		superclass ::tk::MegawidgetClass {*}$superclasses]\;$body
    }
}

::oo::class create ::tk::MegawidgetClass {
    variable w hull options IdleCallbacks
    constructor args {
	# Extract the "widget name" from the object name
	set w [namespace tail [self]]

	# Configure things
	tclParseConfigSpec [my varname options] [my GetSpecs] "" $args

	# Move the object out of the way of the hull widget
	rename [self] _tmp

	# Make the hull widget(s)
	my CreateHull
	bind $hull <Destroy> [list [namespace which my] destroy]

	# Rename things into their final places
	rename ::$w theWidget
	rename [self] ::$w

	# Make the contents
	my Create
    }
    destructor {
	foreach {name cb} [array get IdleCallbacks] {
	    after cancel $cb
	    unset IdleCallbacks($name)
	}
	if {[winfo exists $w]} {
	    bind $hull <Destroy> {}
	    destroy $w
	}
    }

    ####################################################################
    #
    # MegawidgetClass::configure --
    #
    #	Implementation of 'configure' for megawidgets. Emulates the operation
    #	of the standard Tk configure method fairly closely, which makes things
    #	substantially more complex than they otherwise would be.
    #
    #	This method assumes that the 'GetSpecs' method returns a description
    #	of all the specifications of the options (i.e., as Tk returns except
    #	with the actual values removed). It also assumes that the 'options'
    #	array in the class holds all options; it is up to subclasses to set
    #	traces on that array if they want to respond to configuration changes.
    #
    #	TODO: allow unambiguous abbreviations.
    #
    method configure args {
	# Configure behaves differently depending on the number of arguments
	set argc [llength $args]
	if {$argc == 0} {
	    return [lmap spec [my GetSpecs] {
		lappend spec $options([lindex $spec 0])
	    }]
	} elseif {$argc == 1} {
	    set opt [lindex $args 0]
	    if {[info exists options($opt)]} {
		set spec [lsearch -inline -index 0 -exact [my GetSpecs] $opt]
		return [linsert $spec end $options($opt)]
	    }
	} elseif {$argc == 2} {
	    # Special case for where we're setting a single option. This
	    # avoids some of the costly operations. We still do the [array
	    # get] as this gives a sufficiently-consistent trace.
	    set opt [lindex $args 0]
	    if {[dict exists [array get options] $opt]} {
		# Actually set the new value of the option. Use a catch to
		# allow a megawidget user to throw an error from a write trace
		# on the options array to reject invalid values.
		try {
		    array set options $args
		} on error {ret info} {
		    # Rethrow the error to get a clean stack trace
		    return -code error -errorcode [dict get $info -errorcode] $ret
		}
		return
	    }
	} elseif {$argc % 2 == 0} {
	    # Check that all specified options exist. Any unknown option will
	    # cause the merged dictionary to be bigger than the options array
	    set merge [dict merge [array get options] $args]
	    if {[dict size $merge] == [array size options]} {
		# Actually set the new values of the options. Use a catch to
		# allow a megawidget user to throw an error from a write trace
		# on the options array to reject invalid values
		try {
		    array set options $args
		} on error {ret info} {
		    # Rethrow the error to get a clean stack trace
		    return -code error -errorcode [dict get $info -errorcode] $ret
		}
		return
	    }
	    # Due to the order of the merge, the unknown options will be at
	    # the end of the dict. This makes the first unknown option easy to
	    # find.
	    set opt [lindex [dict keys $merge] [array size options]]
	} else {
	    set opt [lindex $args end]
	    return -code error -errorcode [list TK VALUE_MISSING] \
		"value for \"$opt\" missing"
	}
	return -code error -errorcode [list TK LOOKUP OPTION $opt] \
	    "bad option \"$opt\": must be [tclListValidFlags options]"
    }

    ####################################################################
    #
    # MegawidgetClass::cget --
    #
    #	Implementation of 'cget' for megawidgets. Emulates the operation of
    #	the standard Tk cget method fairly closely.
    #
    #	This method assumes that the 'options' array in the class holds all
    #	options; it is up to subclasses to set traces on that array if they
    #	want to respond to configuration reads.
    #
    #	TODO: allow unambiguous abbreviations.
    #
    method cget option {
	return $options($option)
    }

    ####################################################################
    #
    # MegawidgetClass::TraceOption --
    #
    #	Sets up the tracing of an element of the options variable.
    #
    method TraceOption {option method args} {
	set callback [list my $method {*}$args]
	trace add variable options($option) write [namespace code $callback]
    }

    ####################################################################
    #
    # MegawidgetClass::GetSpecs --
    #
    #	Return a list of descriptions of options supported by this
    #	megawidget. Each option is described by the 4-tuple list, consisting
    #	of the name of the option, the "option database" name, the "option
    #	database" class-name, and the default value of the option. These are
    #	the same values returned by calling the configure method of a widget,
    #	except without the current values of the options.
    #
    method GetSpecs {} {
	return {
	    {-takefocus takeFocus TakeFocus {}}
	}
    }

    ####################################################################
    #
    # MegawidgetClass::CreateHull --
    #
    #	Creates the real main widget of the megawidget. This is often a frame
    #	or toplevel widget, but isn't always (lightweight megawidgets might
    #	use a content widget directly).
    #
    #	The name of the hull widget is given by the 'w' instance variable. The
    #	name should be written into the 'hull' instance variable. The command
    #	created by this method will be renamed.
    #
    method CreateHull {} {
	return -code error -errorcode {TCL OO ABSTRACT_METHOD} \
	    "method must be overridden"
    }

    ####################################################################
    #
    # MegawidgetClass::Create --
    #
    #	Creates the content of the megawidget. The name of the widget to
    #	create the content in will be in the 'hull' instance variable.
    #
    method Create {} {
	return -code error -errorcode {TCL OO ABSTRACT_METHOD} \
	    "method must be overridden"
    }

    ####################################################################
    #
    # MegawidgetClass::WhenIdle --
    #
    #	Arrange for a method to be called on the current instance when Tk is
    #	idle. Only one such method call per method will be queued; subsequent
    #	queuing actions before the callback fires will be silently ignored.
    #	The additional args will be passed to the callback, and the callbacks
    #	will be properly cancelled if the widget is destroyed.
    #
    method WhenIdle {method args} {
	if {![info exists IdleCallbacks($method)]} {
	    set IdleCallbacks($method) [after idle [list \
		    [namespace which my] DoWhenIdle $method $args]]
	}
    }
    method DoWhenIdle {method arguments} {
	unset IdleCallbacks($method)
	tailcall my $method {*}$arguments
    }
}

####################################################################
#
# tk::SimpleWidget --
#
#	Simple megawidget class that makes it easy create widgets that behave
#	like a ttk widget. It creates the hull as a ttk::frame and maps the
#	state manipulation methods of the overall megawidget to the equivalent
#	operations on the ttk::frame.
#
::tk::Megawidget create ::tk::SimpleWidget {} {
    variable w hull options
    method GetSpecs {} {
	return {
	    {-cursor cursor Cursor {}}
	    {-takefocus takeFocus TakeFocus {}}
	}
    }
    method CreateHull {} {
	set hull [::ttk::frame $w -cursor $options(-cursor)]
	my TraceOption -cursor UpdateCursorOption
    }
    method UpdateCursorOption args {
	$hull configure -cursor $options(-cursor)
    }
    # Not fixed names, so can't forward
    method state args {
	tailcall $hull state {*}$args
    }
    method instate args {
	tailcall $hull instate {*}$args
    }
}

####################################################################
#
# tk::FocusableWidget --
#
#	Simple megawidget class that makes a ttk-like widget that has a focus
#	ring.
#
::tk::Megawidget create ::tk::FocusableWidget ::tk::SimpleWidget {
    variable w hull options
    method GetSpecs {} {
	return {
	    {-cursor cursor Cursor {}}
	    {-takefocus takeFocus TakeFocus ::ttk::takefocus}
	}
    }
    method CreateHull {} {
	ttk::frame $w
	set hull [ttk::entry $w.cHull -takefocus 0 -cursor $options(-cursor)]
	pack $hull -expand yes -fill both -ipadx 2 -ipady 2
	my TraceOption -cursor UpdateCursorOption
    }
}

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































Changes to library/menu.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# menu.tcl --
#
# This file defines the default bindings for Tk menus and menubuttons.
# It also implements keyboard traversal of menus and implements a few
# other utility procedures related to menus.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 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.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:






|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# menu.tcl --
#
# This file defines the default bindings for Tk menus and menubuttons.
# It also implements keyboard traversal of menus and implements a few
# other utility procedures related to menus.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# 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.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
bind Menubutton <FocusIn> {}
bind Menubutton <Enter> {
    tk::MbEnter %W
}
bind Menubutton <Leave> {
    tk::MbLeave %W
}
bind Menubutton <Button-1> {
    if {$tk::Priv(inMenubutton) ne ""} {
	tk::MbPost $tk::Priv(inMenubutton) %X %Y
    }
}
bind Menubutton <Motion> {
    tk::MbMotion %W up %X %Y
}







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
bind Menubutton <FocusIn> {}
bind Menubutton <Enter> {
    tk::MbEnter %W
}
bind Menubutton <Leave> {
    tk::MbLeave %W
}
bind Menubutton <1> {
    if {$tk::Priv(inMenubutton) ne ""} {
	tk::MbPost $tk::Priv(inMenubutton) %X %Y
    }
}
bind Menubutton <Motion> {
    tk::MbMotion %W up %X %Y
}
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

bind Menu <Leave> {
    tk::MenuLeave %W %X %Y %s
}
bind Menu <Motion> {
    tk::MenuMotion %W %x %y %s
}
bind Menu <Button> {
    tk::MenuButtonDown %W
}
bind Menu <ButtonRelease> {
   tk::MenuInvoke %W 1
}
bind Menu <space> {
    tk::MenuInvoke %W 0
}
bind Menu <<Invoke>> {
    tk::MenuInvoke %W 0
}
bind Menu <Return> {
    tk::MenuInvoke %W 0
}
bind Menu <Escape> {
    tk::MenuEscape %W
}
bind Menu <<PrevChar>> {
    tk::MenuLeftArrow %W
}
bind Menu <<NextChar>> {
    tk::MenuRightArrow %W
}
bind Menu <<PrevLine>> {
    tk::MenuUpArrow %W
}
bind Menu <<NextLine>> {
    tk::MenuDownArrow %W
}
bind Menu <Key> {
    tk::TraverseWithinMenu %W %A
    break
}

# The following bindings apply to all windows, and are used to
# implement keyboard menu traversal.

if {[tk windowingsystem] eq "x11"} {
    bind all <Alt-Key> {
	tk::TraverseToMenu %W %A
    }

    bind all <F10> {
	tk::FirstMenu %W
    }
} else {
    bind Menubutton <Alt-Key> {
	tk::TraverseToMenu %W %A
    }

    bind Menubutton <F10> {
	tk::FirstMenu %W
    }
}







|

















|


|


|


|


|

<






|







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

bind Menu <Leave> {
    tk::MenuLeave %W %X %Y %s
}
bind Menu <Motion> {
    tk::MenuMotion %W %x %y %s
}
bind Menu <ButtonPress> {
    tk::MenuButtonDown %W
}
bind Menu <ButtonRelease> {
   tk::MenuInvoke %W 1
}
bind Menu <space> {
    tk::MenuInvoke %W 0
}
bind Menu <<Invoke>> {
    tk::MenuInvoke %W 0
}
bind Menu <Return> {
    tk::MenuInvoke %W 0
}
bind Menu <Escape> {
    tk::MenuEscape %W
}
bind Menu <Left> {
    tk::MenuLeftArrow %W
}
bind Menu <Right> {
    tk::MenuRightArrow %W
}
bind Menu <Up> {
    tk::MenuUpArrow %W
}
bind Menu <Down> {
    tk::MenuDownArrow %W
}
bind Menu <KeyPress> {
    tk::TraverseWithinMenu %W %A

}

# The following bindings apply to all windows, and are used to
# implement keyboard menu traversal.

if {[tk windowingsystem] eq "x11"} {
    bind all <Alt-KeyPress> {
	tk::TraverseToMenu %W %A
    }

    bind all <F10> {
	tk::FirstMenu %W
    }
} else {
    bind Menubutton <Alt-KeyPress> {
	tk::TraverseToMenu %W %A
    }

    bind Menubutton <F10> {
	tk::FirstMenu %W
    }
}
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285





286








287






































































288
289
290


291

292
293
294
295
296
297
298
299
300
301
302
303
	return
    }
    if {[$w cget -state] eq "active" && [tk windowingsystem] ne "aqua"} {
	$w configure -state normal
    }
}


# ::tk::MbPost --
# Given a menubutton, this procedure does all the work of posting
# its associated menu and unposting any other menu that is currently
# posted.
#
# Arguments:
# w -			The name of the menubutton widget whose menu
#			is to be posted.
# x, y -		Root coordinates of cursor, used for positioning
#			option menus.  If not specified, then the center
#			of the menubutton is used for an option menu.

proc ::tk::MbPost {w {x {}} {y {}}} {
    global errorInfo
    variable ::tk::Priv


    if {[$w cget -state] eq "disabled" || $w eq $Priv(postedMb)} {
	return
    }
    set menu [$w cget -menu]
    if {$menu eq ""} {
	return
    }
    set tearoff [expr {[tk windowingsystem] eq "x11" \
	    || [$menu cget -type] eq "tearoff"}]
    if {[string first $w $menu] != 0} {
	return -code error -errorcode {TK MENUBUTTON POST_NONCHILD} \
	    "can't post $menu: it isn't a descendant of $w"
    }
    set cur $Priv(postedMb)
    if {$cur ne ""} {
	MenuUnpost {}
    }
    if {$::tk_strictMotif} {
        set Priv(cursor) [$w cget -cursor]
        $w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised
    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate none
    GenerateMenuSelect $menu





    update idletasks















































































    if {[catch {PostMenubuttonMenu $w $menu} msg opt]} {
	# Error posting menu (e.g. bogus -postcommand). Unpost it and
	# reflect the error.


	MenuUnpost {}

	return -options $opt $msg
    }

    set Priv(tearoff) $tearoff
    if {$tearoff != 0 && [tk windowingsystem] ne "aqua"} {
	focus $menu
	if {[winfo viewable $w]} {
	    SaveGrabInfo $w
	    grab -global $w
	}
    }
}







<















>











<
|




















>
>
>
>
>

>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


>
>

>
|



|







229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
	return
    }
    if {[$w cget -state] eq "active" && [tk windowingsystem] ne "aqua"} {
	$w configure -state normal
    }
}


# ::tk::MbPost --
# Given a menubutton, this procedure does all the work of posting
# its associated menu and unposting any other menu that is currently
# posted.
#
# Arguments:
# w -			The name of the menubutton widget whose menu
#			is to be posted.
# x, y -		Root coordinates of cursor, used for positioning
#			option menus.  If not specified, then the center
#			of the menubutton is used for an option menu.

proc ::tk::MbPost {w {x {}} {y {}}} {
    global errorInfo
    variable ::tk::Priv
    global tcl_platform

    if {[$w cget -state] eq "disabled" || $w eq $Priv(postedMb)} {
	return
    }
    set menu [$w cget -menu]
    if {$menu eq ""} {
	return
    }
    set tearoff [expr {[tk windowingsystem] eq "x11" \
	    || [$menu cget -type] eq "tearoff"}]
    if {[string first $w $menu] != 0} {

	error "can't post $menu:  it isn't a descendant of $w (this is a new requirement in Tk versions 3.0 and later)"
    }
    set cur $Priv(postedMb)
    if {$cur ne ""} {
	MenuUnpost {}
    }
    if {$::tk_strictMotif} {
        set Priv(cursor) [$w cget -cursor]
        $w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised
    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate none
    GenerateMenuSelect $menu

    # If this looks like an option menubutton then post the menu so
    # that the current entry is on top of the mouse.  Otherwise post
    # the menu just below the menubutton, as for a pull-down.

    update idletasks
    if {[catch {
	switch [$w cget -direction] {
	    above {
		set x [winfo rootx $w]
		set y [expr {[winfo rooty $w] - [winfo reqheight $menu]}]
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $w]} {
		    set y [expr {[winfo vrooty $w] + [winfo rooty $w] + [winfo reqheight $w]}]
		}
		PostOverPoint $menu $x $y
	    }
	    below {
		set x [winfo rootx $w]
		set y [expr {[winfo rooty $w] + [winfo height $w]}]
		# if we go offscreen to the bottom, show as 'above'
		set mh [winfo reqheight $menu]
		if {($y + $mh) > ([winfo vrooty $w] + [winfo vrootheight $w])} {
		    set y [expr {[winfo vrooty $w] + [winfo vrootheight $w] + [winfo rooty $w] - $mh}]
		}
		PostOverPoint $menu $x $y
	    }
	    left {
		set x [expr {[winfo rootx $w] - [winfo reqwidth $menu]}]
		set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}]
		set entry [MenuFindName $menu [$w cget -text]]
		if {$entry eq ""} {
                    set entry 0
		}
		if {[$w cget -indicatoron]} {
		    if {$entry == [$menu index last]} {
			incr y [expr {-([$menu yposition $entry] \
				+ [winfo reqheight $menu])/2}]
		    } else {
			incr y [expr {-([$menu yposition $entry] \
			        + [$menu yposition [expr {$entry+1}]])/2}]
		    }
		}
		PostOverPoint $menu $x $y
		if {$entry ne "" \
			&& [$menu entrycget $entry -state] ne "disabled"} {
		    $menu activate $entry
		    GenerateMenuSelect $menu
		}
	}
	    right {
		set x [expr {[winfo rootx $w] + [winfo width $w]}]
		set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}]
		set entry [MenuFindName $menu [$w cget -text]]
		if {$entry eq ""} {
                    set entry 0
		}
		if {[$w cget -indicatoron]} {
		    if {$entry == [$menu index last]} {
			incr y [expr {-([$menu yposition $entry] \
				+ [winfo reqheight $menu])/2}]
		    } else {
			incr y [expr {-([$menu yposition $entry] \
			        + [$menu yposition [expr {$entry+1}]])/2}]
		    }
		}
		PostOverPoint $menu $x $y
		if {$entry ne "" \
			&& [$menu entrycget $entry -state] ne "disabled"} {
		    $menu activate $entry
		    GenerateMenuSelect $menu
		}
	    }
	    default {
		if {[$w cget -indicatoron]} {
		    if {$y eq ""} {
			set x [expr {[winfo rootx $w] + [winfo width $w]/2}]
			set y [expr {[winfo rooty $w] + [winfo height $w]/2}]
		    }
	            PostOverPoint $menu $x $y [MenuFindName $menu [$w cget -text]]
		} else {
		    PostOverPoint $menu [winfo rootx $w] [expr {[winfo rooty $w]+[winfo height $w]}]
		}
	    }
	}
    } msg]} {
	# Error posting menu (e.g. bogus -postcommand). Unpost it and
	# reflect the error.

	set savedInfo $errorInfo
	MenuUnpost {}
	error $msg $savedInfo

    }

    set Priv(tearoff) $tearoff
    if {$tearoff != 0} {
	focus $menu
	if {[winfo viewable $w]} {
	    SaveGrabInfo $w
	    grab -global $w
	}
    }
}
315
316
317
318
319
320
321

322
323
324
325
326
327
328
#    or the grab window has been deleted.
#
# Arguments:
# menu -		Name of a menu to unpost.  Ignored if there
#			is a posted menubutton.

proc ::tk::MenuUnpost menu {

    variable ::tk::Priv
    set mb $Priv(postedMb)

    # Restore focus right away (otherwise X will take focus away when
    # the menu is unmapped and under some window managers (e.g. olvwm)
    # we'll lose the focus completely).








>







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
#    or the grab window has been deleted.
#
# Arguments:
# menu -		Name of a menu to unpost.  Ignored if there
#			is a posted menubutton.

proc ::tk::MenuUnpost menu {
    global tcl_platform
    variable ::tk::Priv
    set mb $Priv(postedMb)

    # Restore focus right away (otherwise X will take focus away when
    # the menu is unmapped and under some window managers (e.g. olvwm)
    # we'll lose the focus completely).

443
444
445
446
447
448
449

450
451
452
453
454
455
456
# posted with element 0 activated.  Otherwise, unpost the menu.
#
# Arguments:
# w -			The name of the menubutton widget.

proc ::tk::MbButtonUp w {
    variable ::tk::Priv


    set menu [$w cget -menu]
    set tearoff [expr {[tk windowingsystem] eq "x11" || \
	    ($menu ne "" && [$menu cget -type] eq "tearoff")}]
    if {($tearoff != 0) && $Priv(postedMb) eq $w \
	    && $Priv(inMenubutton) eq $w} {
	MenuFirstEntry [$Priv(postedMb) cget -menu]







>







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
# posted with element 0 activated.  Otherwise, unpost the menu.
#
# Arguments:
# w -			The name of the menubutton widget.

proc ::tk::MbButtonUp w {
    variable ::tk::Priv
    global tcl_platform

    set menu [$w cget -menu]
    set tearoff [expr {[tk windowingsystem] eq "x11" || \
	    ($menu ne "" && [$menu cget -type] eq "tearoff")}]
    if {($tearoff != 0) && $Priv(postedMb) eq $w \
	    && $Priv(inMenubutton) eq $w} {
	MenuFirstEntry [$Priv(postedMb) cget -menu]
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
        if {[info exists Priv(menuActivated)] \
                && $index ne "none" \
                && $index ne $activeindex} {
            set mode [option get $menu clickToFocus ClickToFocus]
            if {[string is false $mode]} {
                set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}]
                if {[$menu type $index] eq "cascade"} {
                    # Catch these postcascade commands since the menu could be
                    # destroyed before they run.
                    set Priv(menuActivatedTimer) \
                        [after $delay "catch {$menu postcascade active}"]
                } else {
                    set Priv(menuDeactivatedTimer) \
                        [after $delay "catch {$menu postcascade none}"]
                }
            }
        }
    }
}

# ::tk::MenuButtonDown --







<
<

|


|







575
576
577
578
579
580
581


582
583
584
585
586
587
588
589
590
591
592
593
        if {[info exists Priv(menuActivated)] \
                && $index ne "none" \
                && $index ne $activeindex} {
            set mode [option get $menu clickToFocus ClickToFocus]
            if {[string is false $mode]} {
                set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}]
                if {[$menu type $index] eq "cascade"} {


                    set Priv(menuActivatedTimer) \
                        [after $delay [list $menu postcascade active]]
                } else {
                    set Priv(menuDeactivatedTimer) \
                        [after $delay [list $menu postcascade none]]
                }
            }
        }
    }
}

# ::tk::MenuButtonDown --
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
#    we can track mouse motions across the entire menu hierarchy.
#
# Arguments:
# menu -		The menu window.

proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv


    if {![winfo viewable $menu]} {
        return
    }
    if {[$menu index active] eq "none"} {
        if {[$menu cget -type] ne "menubar" } {
            set Priv(window) {}
        }
        return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \







>


<
<
<
<
<
<







603
604
605
606
607
608
609
610
611
612






613
614
615
616
617
618
619
#    we can track mouse motions across the entire menu hierarchy.
#
# Arguments:
# menu -		The menu window.

proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv
    global tcl_platform

    if {![winfo viewable $menu]} {






        return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242


1243
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285

1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
		return $i
	    }
	}
    }
    return ""
}

# ::tk::PostMenubuttonMenu --
#
# Given a menubutton and a menu, this procedure posts the menu at the
# appropriate location.  If the menubutton looks like an option
# menubutton, meaning that the indicator is on and the direction is
# neither above nor below, then the menu is posted so that the current
# entry is vertically aligned with the menubutton.  On the Mac this
# will expose a small amount of the blue indicator on the right hand
# side.  On other platforms the entry is centered over the button.

if {[tk windowingsystem] eq "aqua"} {
    proc ::tk::PostMenubuttonMenu {button menu} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
	set x [winfo rootx $button]
	set y [expr {2 + [winfo rooty $button]}]
	switch [$button cget -direction] {
	    above {
		set entry ""
		incr y [expr {4 - [winfo reqheight $menu]}]
	    }
	    below {
		set entry ""
		incr y [expr {2 + [winfo height $button]}]
	    }
	    left {
		incr x [expr {-[winfo reqwidth $menu]}]
	    }
	    right {
		incr x [winfo width $button]
	    }
	    default {
		incr x [expr {[winfo width $button] - [winfo reqwidth $menu] - 5}]
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
} else {
    proc ::tk::PostMenubuttonMenu {button menu} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
	set x [winfo rootx $button]
	set y [winfo rooty $button]
	switch [$button cget -direction] {
	    above {
		incr y [expr {-[winfo reqheight $menu]}]
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $button]} {
		    set y [expr {[winfo vrooty $button] + [winfo rooty $button]\
                           + [winfo reqheight $button]}]
		}
		set entry {}
	    }
	    below {
		incr y [winfo height $button]
		# if we go offscreen to the bottom, show as 'above'
		set mh [winfo reqheight $menu]
		if {($y + $mh) > ([winfo vrooty $button] + [winfo vrootheight $button])} {
		    set y [expr {[winfo vrooty $button] + [winfo vrootheight $button] \
			   + [winfo rooty $button] - $mh}]
		}
		set entry {}
	    }
	    left {
		# It is not clear why this is needed.
		if {[tk windowingsystem] eq "win32"} {
		    incr x [expr {-4 - [winfo reqwidth $button] / 2}]
		}
		incr x [expr {- [winfo reqwidth $menu]}]
	    }
	    right {
		incr x [expr {[winfo width $button]}]
	    }
	    default {
		if {[$button cget -indicatoron]} {
		    incr x [expr {([winfo width $button] - \
				   [winfo reqwidth $menu])/ 2}]
		} else {
		    incr y [winfo height $button]
		}
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
}

# ::tk::PostOverPoint --
#
# This procedure posts a menu on the screen so that a given entry in
# the menu is positioned with its upper left corner at a given point
# in the root window.  The procedure also activates that entry.  If no
# entry is specified the upper left corner of the entire menu is
# placed at the point.
#
# Arguments:
# menu -		Menu to post.
# x, y -		Root coordinates of point.
# entry -		Index of entry within menu to center over (x,y).
#			If omitted or specified as {}, then the menu's
#			upper-left corner goes at (x,y).

if {[tk windowingsystem] ne "win32"} {
    proc ::tk::PostOverPoint {menu x y {entry {}}}  {


	if {$entry ne ""} {
	    $menu post $x $y $entry
	    if {[$menu entrycget $entry -state] ne "disabled"} {
		$menu activate $entry
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu post $x $y

	}
	return
    }
} else {
    proc ::tk::PostOverPoint {menu x y {entry {}}}  {
	if {$entry ne ""} {
	    incr y [expr {-[$menu yposition $entry]}]
	}

	# osVersion is not available in safe interps
	set ver 5
	if {[info exists ::tcl_platform(osVersion)]} {
	    scan $::tcl_platform(osVersion) %d ver
	}

	# We need to fix some problems with menu posting on Windows,
	# where, if the menu would overlap top or bottom of screen,
	# Windows puts it in the wrong place for us.  We must also
	# subtract an extra amount for half the height of the current
	# entry.  To be safe we subtract an extra 10.
	# NOTE: this issue appears to have been resolved in the Window
	# manager provided with Vista and Windows 7.
	if {$ver < 6} {
	    set yoffset [expr {[winfo screenheight $menu] \
				   - $y - [winfo reqheight $menu] - 10}]
	    if {$yoffset < [winfo vrooty $menu]} {
		# The bottom of the menu is offscreen, so adjust upwards
		incr y [expr {$yoffset - [winfo vrooty $menu]}]
	    }
	    # If we're off the top of the screen (either because we were
	    # originally or because we just adjusted too far upwards),
	    # then make the menu popup on the top edge.
	    if {$y < [winfo vrooty $menu]} {
		set y [winfo vrooty $menu]
	    }
	}

	$menu post $x $y
	if {$entry ne "" && [$menu entrycget $entry -state] ne "disabled"} {
	    $menu activate $entry
	    GenerateMenuSelect $menu
	}
    }
}

# ::tk::SaveGrabInfo --
# Sets the variables tk::Priv(oldGrab) and tk::Priv(grabStatus) to record
# the state of any existing grab on the w's display.
#







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|
|
<
<








<
|
>
>
|
|
<
|
|
<

|
>

|

<
<
<
<
|
>


|
|











|











>
|
|
|
|
<







1202
1203
1204
1205
1206
1207
1208
































































































1209

1210
1211
1212


1213
1214
1215
1216
1217
1218
1219
1220

1221
1222
1223
1224
1225

1226
1227

1228
1229
1230
1231
1232
1233




1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
		return $i
	    }
	}
    }
    return ""
}

































































































# ::tk::PostOverPoint --

# This procedure posts a given menu such that a given entry in the
# menu is centered over a given point in the root window.  It also
# activates the given entry.


#
# Arguments:
# menu -		Menu to post.
# x, y -		Root coordinates of point.
# entry -		Index of entry within menu to center over (x,y).
#			If omitted or specified as {}, then the menu's
#			upper-left corner goes at (x,y).


proc ::tk::PostOverPoint {menu x y {entry {}}}  {
    global tcl_platform

    if {$entry ne ""} {
	if {$entry == [$menu index last]} {

	    incr y [expr {-([$menu yposition $entry] \
		    + [winfo reqheight $menu])/2}]

	} else {
	    incr y [expr {-([$menu yposition $entry] \
		    + [$menu yposition [expr {$entry+1}]])/2}]
	}
	incr x [expr {-[winfo reqwidth $menu]/2}]
    }





    if {[tk windowingsystem] eq "win32"} {
	# osVersion is not available in safe interps
	set ver 5
	if {[info exists tcl_platform(osVersion)]} {
	    scan $tcl_platform(osVersion) %d ver
	}

	# We need to fix some problems with menu posting on Windows,
	# where, if the menu would overlap top or bottom of screen,
	# Windows puts it in the wrong place for us.  We must also
	# subtract an extra amount for half the height of the current
	# entry.  To be safe we subtract an extra 10.
	# NOTE: this issue appears to have been resolved in the Window
	# manager provided with Vista and Windows 7.
	if {$ver < 6} {
	    set yoffset [expr {[winfo screenheight $menu] \
		    - $y - [winfo reqheight $menu] - 10}]
	    if {$yoffset < [winfo vrooty $menu]} {
		# The bottom of the menu is offscreen, so adjust upwards
		incr y [expr {$yoffset - [winfo vrooty $menu]}]
	    }
	    # If we're off the top of the screen (either because we were
	    # originally or because we just adjusted too far upwards),
	    # then make the menu popup on the top edge.
	    if {$y < [winfo vrooty $menu]} {
		set y [winfo vrooty $menu]
	    }
	}
    }
    $menu post $x $y
    if {$entry ne "" && [$menu entrycget $entry -state] ne "disabled"} {
	$menu activate $entry
	GenerateMenuSelect $menu

    }
}

# ::tk::SaveGrabInfo --
# Sets the variables tk::Priv(oldGrab) and tk::Priv(grabStatus) to record
# the state of any existing grab on the w's display.
#
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
#			menu.
# entry -		Index of a menu entry to center over (x,y).
#			If omitted or specified as {}, then menu's
#			upper-left corner goes at (x,y).

proc ::tk_popup {menu x y {entry {}}} {
    variable ::tk::Priv

    if {$Priv(popup) ne "" || $Priv(postedMb) ne ""} {
	tk::MenuUnpost {}
    }
    tk::PostOverPoint $menu $x $y $entry
    if {[tk windowingsystem] eq "x11" && [winfo viewable $menu]} {
        tk::SaveGrabInfo $menu
	grab -global $menu
	set Priv(popup) $menu
	set Priv(window) $menu
	set Priv(menuActivated) 1
	tk_menuSetFocus $menu
    }
}







>













1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
#			menu.
# entry -		Index of a menu entry to center over (x,y).
#			If omitted or specified as {}, then menu's
#			upper-left corner goes at (x,y).

proc ::tk_popup {menu x y {entry {}}} {
    variable ::tk::Priv
    global tcl_platform
    if {$Priv(popup) ne "" || $Priv(postedMb) ne ""} {
	tk::MenuUnpost {}
    }
    tk::PostOverPoint $menu $x $y $entry
    if {[tk windowingsystem] eq "x11" && [winfo viewable $menu]} {
        tk::SaveGrabInfo $menu
	grab -global $menu
	set Priv(popup) $menu
	set Priv(window) $menu
	set Priv(menuActivated) 1
	tk_menuSetFocus $menu
    }
}

Changes to library/mkpsenc.tcl.

1
2


3






















4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158

1159

1160
1161

1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

1172
1173
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186

1187
1188
1189

1190
1191
1192
1193
1194

1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1206
1207
1208

1209
1210
1211
1212
1213

1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231

1232
1233

1234

1235
1236
1237

1238
1239
1240
1241


1242
1243
1244
1245

1246
1247
1248
1249
1250

1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267


1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294

1295
1296

1297
1298

1299
1300
1301
1302
1303
1304
1305

1306

1307
1308
1309
1310
1311
1312

1313

1314
1315
1316
1317

1318
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328

1329

1330
1331
1332

1333
1334
1335
1336


1337
1338
1339
1340
1341

1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
# mkpsenc.tcl --
#


# This file generates the postscript prolog used by Tk.























namespace eval ::tk {
    # Creates Postscript encoding vector for ISO-8859-1 (could theoretically
    # handle any 8-bit encoding, but Tk never generates characters outside
    # ASCII).
    #
    proc CreatePostscriptEncoding {} {
	variable psglyphs
	# Now check for known. Even if it is known, it can be other than we
	# need. GhostScript seems to be happy with such approach
	set result "\[\n"
	for {set i 0} {$i<256} {incr i 8} {
	    for {set j 0} {$j<8} {incr j} {
		set enc [encoding convertfrom "iso8859-1" \
			[format %c [expr {$i+$j}]]]
		catch {
		    set hexcode {}
		    set hexcode [format %04X [scan $enc %c]]
		}
		if {[info exists psglyphs($hexcode)]} {
		    append result "/$psglyphs($hexcode)"
		} else {
		    append result "/space"
		}
	    }
	    append result "\n"
	}
	append result "\]"
	return $result
    }

    # List of adobe glyph names. Converted from glyphlist.txt, downloaded from
    # Adobe.

    variable psglyphs
    array set psglyphs {
	0020 space
	0021 exclam
	0022 quotedbl
	0023 numbersign
	0024 dollar
	0025 percent
	0026 ampersand
	0027 quotesingle
	0028 parenleft
	0029 parenright
	002A asterisk
	002B plus
	002C comma
	002D hyphen
	002E period
	002F slash
	0030 zero
	0031 one
	0032 two
	0033 three
	0034 four
	0035 five
	0036 six
	0037 seven
	0038 eight
	0039 nine
	003A colon
	003B semicolon
	003C less
	003D equal
	003E greater
	003F question
	0040 at
	0041 A
	0042 B
	0043 C
	0044 D
	0045 E
	0046 F
	0047 G
	0048 H
	0049 I
	004A J
	004B K
	004C L
	004D M
	004E N
	004F O
	0050 P
	0051 Q
	0052 R
	0053 S
	0054 T
	0055 U
	0056 V
	0057 W
	0058 X
	0059 Y
	005A Z
	005B bracketleft
	005C backslash
	005D bracketright
	005E asciicircum
	005F underscore
	0060 grave
	0061 a
	0062 b
	0063 c
	0064 d
	0065 e
	0066 f
	0067 g
	0068 h
	0069 i
	006A j
	006B k
	006C l
	006D m
	006E n
	006F o
	0070 p
	0071 q
	0072 r
	0073 s
	0074 t
	0075 u
	0076 v
	0077 w
	0078 x
	0079 y
	007A z
	007B braceleft
	007C bar
	007D braceright
	007E asciitilde
	00A0 space
	00A1 exclamdown
	00A2 cent
	00A3 sterling
	00A4 currency
	00A5 yen
	00A6 brokenbar
	00A7 section
	00A8 dieresis
	00A9 copyright
	00AA ordfeminine
	00AB guillemotleft
	00AC logicalnot
	00AD hyphen
	00AE registered
	00AF macron
	00B0 degree
	00B1 plusminus
	00B2 twosuperior
	00B3 threesuperior
	00B4 acute
	00B5 mu
	00B6 paragraph
	00B7 periodcentered
	00B8 cedilla
	00B9 onesuperior
	00BA ordmasculine
	00BB guillemotright
	00BC onequarter
	00BD onehalf
	00BE threequarters
	00BF questiondown
	00C0 Agrave
	00C1 Aacute
	00C2 Acircumflex
	00C3 Atilde
	00C4 Adieresis
	00C5 Aring
	00C6 AE
	00C7 Ccedilla
	00C8 Egrave
	00C9 Eacute
	00CA Ecircumflex
	00CB Edieresis
	00CC Igrave
	00CD Iacute
	00CE Icircumflex
	00CF Idieresis
	00D0 Eth
	00D1 Ntilde
	00D2 Ograve
	00D3 Oacute
	00D4 Ocircumflex
	00D5 Otilde
	00D6 Odieresis
	00D7 multiply
	00D8 Oslash
	00D9 Ugrave
	00DA Uacute
	00DB Ucircumflex
	00DC Udieresis
	00DD Yacute
	00DE Thorn
	00DF germandbls
	00E0 agrave
	00E1 aacute
	00E2 acircumflex
	00E3 atilde
	00E4 adieresis
	00E5 aring
	00E6 ae
	00E7 ccedilla
	00E8 egrave
	00E9 eacute
	00EA ecircumflex
	00EB edieresis
	00EC igrave
	00ED iacute
	00EE icircumflex
	00EF idieresis
	00F0 eth
	00F1 ntilde
	00F2 ograve
	00F3 oacute
	00F4 ocircumflex
	00F5 otilde
	00F6 odieresis
	00F7 divide
	00F8 oslash
	00F9 ugrave
	00FA uacute
	00FB ucircumflex
	00FC udieresis
	00FD yacute
	00FE thorn
	00FF ydieresis
	0100 Amacron
	0101 amacron
	0102 Abreve
	0103 abreve
	0104 Aogonek
	0105 aogonek
	0106 Cacute
	0107 cacute
	0108 Ccircumflex
	0109 ccircumflex
	010A Cdotaccent
	010B cdotaccent
	010C Ccaron
	010D ccaron
	010E Dcaron
	010F dcaron
	0110 Dcroat
	0111 dcroat
	0112 Emacron
	0113 emacron
	0114 Ebreve
	0115 ebreve
	0116 Edotaccent
	0117 edotaccent
	0118 Eogonek
	0119 eogonek
	011A Ecaron
	011B ecaron
	011C Gcircumflex
	011D gcircumflex
	011E Gbreve
	011F gbreve
	0120 Gdotaccent
	0121 gdotaccent
	0122 Gcommaaccent
	0123 gcommaaccent
	0124 Hcircumflex
	0125 hcircumflex
	0126 Hbar
	0127 hbar
	0128 Itilde
	0129 itilde
	012A Imacron
	012B imacron
	012C Ibreve
	012D ibreve
	012E Iogonek
	012F iogonek
	0130 Idotaccent
	0131 dotlessi
	0132 IJ
	0133 ij
	0134 Jcircumflex
	0135 jcircumflex
	0136 Kcommaaccent
	0137 kcommaaccent
	0138 kgreenlandic
	0139 Lacute
	013A lacute
	013B Lcommaaccent
	013C lcommaaccent
	013D Lcaron
	013E lcaron
	013F Ldot
	0140 ldot
	0141 Lslash
	0142 lslash
	0143 Nacute
	0144 nacute
	0145 Ncommaaccent
	0146 ncommaaccent
	0147 Ncaron
	0148 ncaron
	0149 napostrophe
	014A Eng
	014B eng
	014C Omacron
	014D omacron
	014E Obreve
	014F obreve
	0150 Ohungarumlaut
	0151 ohungarumlaut
	0152 OE
	0153 oe
	0154 Racute
	0155 racute
	0156 Rcommaaccent
	0157 rcommaaccent
	0158 Rcaron
	0159 rcaron
	015A Sacute
	015B sacute
	015C Scircumflex
	015D scircumflex
	015E Scedilla
	015F scedilla
	0160 Scaron
	0161 scaron
	0162 Tcommaaccent
	0163 tcommaaccent
	0164 Tcaron
	0165 tcaron
	0166 Tbar
	0167 tbar
	0168 Utilde
	0169 utilde
	016A Umacron
	016B umacron
	016C Ubreve
	016D ubreve
	016E Uring
	016F uring
	0170 Uhungarumlaut
	0171 uhungarumlaut
	0172 Uogonek
	0173 uogonek
	0174 Wcircumflex
	0175 wcircumflex
	0176 Ycircumflex
	0177 ycircumflex
	0178 Ydieresis
	0179 Zacute
	017A zacute
	017B Zdotaccent
	017C zdotaccent
	017D Zcaron
	017E zcaron
	017F longs
	0192 florin
	01A0 Ohorn
	01A1 ohorn
	01AF Uhorn
	01B0 uhorn
	01E6 Gcaron
	01E7 gcaron
	01FA Aringacute
	01FB aringacute
	01FC AEacute
	01FD aeacute
	01FE Oslashacute
	01FF oslashacute
	0218 Scommaaccent
	0219 scommaaccent
	021A Tcommaaccent
	021B tcommaaccent
	02BC afii57929
	02BD afii64937
	02C6 circumflex
	02C7 caron
	02C9 macron
	02D8 breve
	02D9 dotaccent
	02DA ring
	02DB ogonek
	02DC tilde
	02DD hungarumlaut
	0300 gravecomb
	0301 acutecomb
	0303 tildecomb
	0309 hookabovecomb
	0323 dotbelowcomb
	0384 tonos
	0385 dieresistonos
	0386 Alphatonos
	0387 anoteleia
	0388 Epsilontonos
	0389 Etatonos
	038A Iotatonos
	038C Omicrontonos
	038E Upsilontonos
	038F Omegatonos
	0390 iotadieresistonos
	0391 Alpha
	0392 Beta
	0393 Gamma
	0394 Delta
	0395 Epsilon
	0396 Zeta
	0397 Eta
	0398 Theta
	0399 Iota
	039A Kappa
	039B Lambda
	039C Mu
	039D Nu
	039E Xi
	039F Omicron
	03A0 Pi
	03A1 Rho
	03A3 Sigma
	03A4 Tau
	03A5 Upsilon
	03A6 Phi
	03A7 Chi
	03A8 Psi
	03A9 Omega
	03AA Iotadieresis
	03AB Upsilondieresis
	03AC alphatonos
	03AD epsilontonos
	03AE etatonos
	03AF iotatonos
	03B0 upsilondieresistonos
	03B1 alpha
	03B2 beta
	03B3 gamma
	03B4 delta
	03B5 epsilon
	03B6 zeta
	03B7 eta
	03B8 theta
	03B9 iota
	03BA kappa
	03BB lambda
	03BC mu
	03BD nu
	03BE xi
	03BF omicron
	03C0 pi
	03C1 rho
	03C2 sigma1
	03C3 sigma
	03C4 tau
	03C5 upsilon
	03C6 phi
	03C7 chi
	03C8 psi
	03C9 omega
	03CA iotadieresis
	03CB upsilondieresis
	03CC omicrontonos
	03CD upsilontonos
	03CE omegatonos
	03D1 theta1
	03D2 Upsilon1
	03D5 phi1
	03D6 omega1
	0401 afii10023
	0402 afii10051
	0403 afii10052
	0404 afii10053
	0405 afii10054
	0406 afii10055
	0407 afii10056
	0408 afii10057
	0409 afii10058
	040A afii10059
	040B afii10060
	040C afii10061
	040E afii10062
	040F afii10145
	0410 afii10017
	0411 afii10018
	0412 afii10019
	0413 afii10020
	0414 afii10021
	0415 afii10022
	0416 afii10024
	0417 afii10025
	0418 afii10026
	0419 afii10027
	041A afii10028
	041B afii10029
	041C afii10030
	041D afii10031
	041E afii10032
	041F afii10033
	0420 afii10034
	0421 afii10035
	0422 afii10036
	0423 afii10037
	0424 afii10038
	0425 afii10039
	0426 afii10040
	0427 afii10041
	0428 afii10042
	0429 afii10043
	042A afii10044
	042B afii10045
	042C afii10046
	042D afii10047
	042E afii10048
	042F afii10049
	0430 afii10065
	0431 afii10066
	0432 afii10067
	0433 afii10068
	0434 afii10069
	0435 afii10070
	0436 afii10072
	0437 afii10073
	0438 afii10074
	0439 afii10075
	043A afii10076
	043B afii10077
	043C afii10078
	043D afii10079
	043E afii10080
	043F afii10081
	0440 afii10082
	0441 afii10083
	0442 afii10084
	0443 afii10085
	0444 afii10086
	0445 afii10087
	0446 afii10088
	0447 afii10089
	0448 afii10090
	0449 afii10091
	044A afii10092
	044B afii10093
	044C afii10094
	044D afii10095
	044E afii10096
	044F afii10097
	0451 afii10071
	0452 afii10099
	0453 afii10100
	0454 afii10101
	0455 afii10102
	0456 afii10103
	0457 afii10104
	0458 afii10105
	0459 afii10106
	045A afii10107
	045B afii10108
	045C afii10109
	045E afii10110
	045F afii10193
	0462 afii10146
	0463 afii10194
	0472 afii10147
	0473 afii10195
	0474 afii10148
	0475 afii10196
	0490 afii10050
	0491 afii10098
	04D9 afii10846
	05B0 afii57799
	05B1 afii57801
	05B2 afii57800
	05B3 afii57802
	05B4 afii57793
	05B5 afii57794
	05B6 afii57795
	05B7 afii57798
	05B8 afii57797
	05B9 afii57806
	05BB afii57796
	05BC afii57807
	05BD afii57839
	05BE afii57645
	05BF afii57841
	05C0 afii57842
	05C1 afii57804
	05C2 afii57803
	05C3 afii57658
	05D0 afii57664
	05D1 afii57665
	05D2 afii57666
	05D3 afii57667
	05D4 afii57668
	05D5 afii57669
	05D6 afii57670
	05D7 afii57671
	05D8 afii57672
	05D9 afii57673
	05DA afii57674
	05DB afii57675
	05DC afii57676
	05DD afii57677
	05DE afii57678
	05DF afii57679
	05E0 afii57680
	05E1 afii57681
	05E2 afii57682
	05E3 afii57683
	05E4 afii57684
	05E5 afii57685
	05E6 afii57686
	05E7 afii57687
	05E8 afii57688
	05E9 afii57689
	05EA afii57690
	05F0 afii57716
	05F1 afii57717
	05F2 afii57718
	060C afii57388
	061B afii57403
	061F afii57407
	0621 afii57409
	0622 afii57410
	0623 afii57411
	0624 afii57412
	0625 afii57413
	0626 afii57414
	0627 afii57415
	0628 afii57416
	0629 afii57417
	062A afii57418
	062B afii57419
	062C afii57420
	062D afii57421
	062E afii57422
	062F afii57423
	0630 afii57424
	0631 afii57425
	0632 afii57426
	0633 afii57427
	0634 afii57428
	0635 afii57429
	0636 afii57430
	0637 afii57431
	0638 afii57432
	0639 afii57433
	063A afii57434
	0640 afii57440
	0641 afii57441
	0642 afii57442
	0643 afii57443
	0644 afii57444
	0645 afii57445
	0646 afii57446
	0647 afii57470
	0648 afii57448
	0649 afii57449
	064A afii57450
	064B afii57451
	064C afii57452
	064D afii57453
	064E afii57454
	064F afii57455
	0650 afii57456
	0651 afii57457
	0652 afii57458
	0660 afii57392
	0661 afii57393
	0662 afii57394
	0663 afii57395
	0664 afii57396
	0665 afii57397
	0666 afii57398
	0667 afii57399
	0668 afii57400
	0669 afii57401
	066A afii57381
	066D afii63167
	0679 afii57511
	067E afii57506
	0686 afii57507
	0688 afii57512
	0691 afii57513
	0698 afii57508
	06A4 afii57505
	06AF afii57509
	06BA afii57514
	06D2 afii57519
	06D5 afii57534
	1E80 Wgrave
	1E81 wgrave
	1E82 Wacute
	1E83 wacute
	1E84 Wdieresis
	1E85 wdieresis
	1EF2 Ygrave
	1EF3 ygrave
	200C afii61664
	200D afii301
	200E afii299
	200F afii300
	2012 figuredash
	2013 endash
	2014 emdash
	2015 afii00208
	2017 underscoredbl
	2018 quoteleft
	2019 quoteright
	201A quotesinglbase
	201B quotereversed
	201C quotedblleft
	201D quotedblright
	201E quotedblbase
	2020 dagger
	2021 daggerdbl
	2022 bullet
	2024 onedotenleader
	2025 twodotenleader
	2026 ellipsis
	202C afii61573
	202D afii61574
	202E afii61575
	2030 perthousand
	2032 minute
	2033 second
	2039 guilsinglleft
	203A guilsinglright
	203C exclamdbl
	2044 fraction
	2070 zerosuperior
	2074 foursuperior
	2075 fivesuperior
	2076 sixsuperior
	2077 sevensuperior
	2078 eightsuperior
	2079 ninesuperior
	207D parenleftsuperior
	207E parenrightsuperior
	207F nsuperior
	2080 zeroinferior
	2081 oneinferior
	2082 twoinferior
	2083 threeinferior
	2084 fourinferior
	2085 fiveinferior
	2086 sixinferior
	2087 seveninferior
	2088 eightinferior
	2089 nineinferior
	208D parenleftinferior
	208E parenrightinferior
	20A1 colonmonetary
	20A3 franc
	20A4 lira
	20A7 peseta
	20AA afii57636
	20AB dong
	20AC Euro
	2105 afii61248
	2111 Ifraktur
	2113 afii61289
	2116 afii61352
	2118 weierstrass
	211C Rfraktur
	211E prescription
	2122 trademark
	2126 Omega
	212E estimated
	2135 aleph
	2153 onethird
	2154 twothirds
	215B oneeighth
	215C threeeighths
	215D fiveeighths
	215E seveneighths
	2190 arrowleft
	2191 arrowup
	2192 arrowright
	2193 arrowdown
	2194 arrowboth
	2195 arrowupdn
	21A8 arrowupdnbse
	21B5 carriagereturn
	21D0 arrowdblleft
	21D1 arrowdblup
	21D2 arrowdblright
	21D3 arrowdbldown
	21D4 arrowdblboth
	2200 universal
	2202 partialdiff
	2203 existential
	2205 emptyset
	2206 Delta
	2207 gradient
	2208 element
	2209 notelement
	220B suchthat
	220F product
	2211 summation
	2212 minus
	2215 fraction
	2217 asteriskmath
	2219 periodcentered
	221A radical
	221D proportional
	221E infinity
	221F orthogonal
	2220 angle
	2227 logicaland
	2228 logicalor
	2229 intersection
	222A union
	222B integral
	2234 therefore
	223C similar
	2245 congruent
	2248 approxequal
	2260 notequal
	2261 equivalence
	2264 lessequal
	2265 greaterequal
	2282 propersubset
	2283 propersuperset
	2284 notsubset
	2286 reflexsubset
	2287 reflexsuperset
	2295 circleplus
	2297 circlemultiply
	22A5 perpendicular
	22C5 dotmath
	2302 house
	2310 revlogicalnot
	2320 integraltp
	2321 integralbt
	2329 angleleft
	232A angleright
	2500 SF100000
	2502 SF110000
	250C SF010000
	2510 SF030000
	2514 SF020000
	2518 SF040000
	251C SF080000
	2524 SF090000
	252C SF060000
	2534 SF070000
	253C SF050000
	2550 SF430000
	2551 SF240000
	2552 SF510000
	2553 SF520000
	2554 SF390000
	2555 SF220000
	2556 SF210000
	2557 SF250000
	2558 SF500000
	2559 SF490000
	255A SF380000
	255B SF280000
	255C SF270000
	255D SF260000
	255E SF360000
	255F SF370000
	2560 SF420000
	2561 SF190000
	2562 SF200000
	2563 SF230000
	2564 SF470000
	2565 SF480000
	2566 SF410000
	2567 SF450000
	2568 SF460000
	2569 SF400000
	256A SF540000
	256B SF530000
	256C SF440000
	2580 upblock
	2584 dnblock
	2588 block
	258C lfblock
	2590 rtblock
	2591 ltshade
	2592 shade
	2593 dkshade
	25A0 filledbox
	25A1 H22073
	25AA H18543
	25AB H18551
	25AC filledrect
	25B2 triagup
	25BA triagrt
	25BC triagdn
	25C4 triaglf
	25CA lozenge
	25CB circle
	25CF H18533
	25D8 invbullet
	25D9 invcircle
	25E6 openbullet
	263A smileface
	263B invsmileface
	263C sun
	2640 female
	2642 male
	2660 spade
	2663 club
	2665 heart
	2666 diamond
	266A musicalnote
	266B musicalnotedbl
	F6BE dotlessj
	F6BF LL
	F6C0 ll
	F6C1 Scedilla
	F6C2 scedilla
	F6C3 commaaccent
	F6C4 afii10063
	F6C5 afii10064
	F6C6 afii10192
	F6C7 afii10831
	F6C8 afii10832
	F6C9 Acute
	F6CA Caron
	F6CB Dieresis
	F6CC DieresisAcute
	F6CD DieresisGrave
	F6CE Grave
	F6CF Hungarumlaut
	F6D0 Macron
	F6D1 cyrBreve
	F6D2 cyrFlex
	F6D3 dblGrave
	F6D4 cyrbreve
	F6D5 cyrflex
	F6D6 dblgrave
	F6D7 dieresisacute
	F6D8 dieresisgrave
	F6D9 copyrightserif
	F6DA registerserif
	F6DB trademarkserif
	F6DC onefitted
	F6DD rupiah
	F6DE threequartersemdash
	F6DF centinferior
	F6E0 centsuperior
	F6E1 commainferior
	F6E2 commasuperior
	F6E3 dollarinferior
	F6E4 dollarsuperior
	F6E5 hypheninferior
	F6E6 hyphensuperior
	F6E7 periodinferior
	F6E8 periodsuperior
	F6E9 asuperior
	F6EA bsuperior
	F6EB dsuperior
	F6EC esuperior
	F6ED isuperior
	F6EE lsuperior
	F6EF msuperior
	F6F0 osuperior
	F6F1 rsuperior
	F6F2 ssuperior
	F6F3 tsuperior
	F6F4 Brevesmall
	F6F5 Caronsmall
	F6F6 Circumflexsmall
	F6F7 Dotaccentsmall
	F6F8 Hungarumlautsmall
	F6F9 Lslashsmall
	F6FA OEsmall
	F6FB Ogoneksmall
	F6FC Ringsmall
	F6FD Scaronsmall
	F6FE Tildesmall
	F6FF Zcaronsmall
	F721 exclamsmall
	F724 dollaroldstyle
	F726 ampersandsmall
	F730 zerooldstyle
	F731 oneoldstyle
	F732 twooldstyle
	F733 threeoldstyle
	F734 fouroldstyle
	F735 fiveoldstyle
	F736 sixoldstyle
	F737 sevenoldstyle
	F738 eightoldstyle
	F739 nineoldstyle
	F73F questionsmall
	F760 Gravesmall
	F761 Asmall
	F762 Bsmall
	F763 Csmall
	F764 Dsmall
	F765 Esmall
	F766 Fsmall
	F767 Gsmall
	F768 Hsmall
	F769 Ismall
	F76A Jsmall
	F76B Ksmall
	F76C Lsmall
	F76D Msmall
	F76E Nsmall
	F76F Osmall
	F770 Psmall
	F771 Qsmall
	F772 Rsmall
	F773 Ssmall
	F774 Tsmall
	F775 Usmall
	F776 Vsmall
	F777 Wsmall
	F778 Xsmall
	F779 Ysmall
	F77A Zsmall
	F7A1 exclamdownsmall
	F7A2 centoldstyle
	F7A8 Dieresissmall
	F7AF Macronsmall
	F7B4 Acutesmall
	F7B8 Cedillasmall
	F7BF questiondownsmall
	F7E0 Agravesmall
	F7E1 Aacutesmall
	F7E2 Acircumflexsmall
	F7E3 Atildesmall
	F7E4 Adieresissmall
	F7E5 Aringsmall
	F7E6 AEsmall
	F7E7 Ccedillasmall
	F7E8 Egravesmall
	F7E9 Eacutesmall
	F7EA Ecircumflexsmall
	F7EB Edieresissmall
	F7EC Igravesmall
	F7ED Iacutesmall
	F7EE Icircumflexsmall
	F7EF Idieresissmall
	F7F0 Ethsmall
	F7F1 Ntildesmall
	F7F2 Ogravesmall
	F7F3 Oacutesmall
	F7F4 Ocircumflexsmall
	F7F5 Otildesmall
	F7F6 Odieresissmall
	F7F8 Oslashsmall
	F7F9 Ugravesmall
	F7FA Uacutesmall
	F7FB Ucircumflexsmall
	F7FC Udieresissmall
	F7FD Yacutesmall
	F7FE Thornsmall
	F7FF Ydieresissmall
	F8E5 radicalex
	F8E6 arrowvertex
	F8E7 arrowhorizex
	F8E8 registersans
	F8E9 copyrightsans
	F8EA trademarksans
	F8EB parenlefttp
	F8EC parenleftex
	F8ED parenleftbt
	F8EE bracketlefttp
	F8EF bracketleftex
	F8F0 bracketleftbt
	F8F1 bracelefttp
	F8F2 braceleftmid
	F8F3 braceleftbt
	F8F4 braceex
	F8F5 integralex
	F8F6 parenrighttp
	F8F7 parenrightex
	F8F8 parenrightbt
	F8F9 bracketrighttp
	F8FA bracketrightex
	F8FB bracketrightbt
	F8FC bracerighttp
	F8FD bracerightmid
	F8FE bracerightbt
	FB00 ff
	FB01 fi
	FB02 fl
	FB03 ffi
	FB04 ffl
	FB1F afii57705
	FB2A afii57694
	FB2B afii57695
	FB35 afii57723
	FB4B afii57700
    }

    variable ps_preamble {}

    namespace eval ps {
	namespace ensemble create
	namespace export {[a-z]*}
	proc literal {string} {
	    upvar 0 ::tk::ps_preamble preamble
	    foreach line [split $string \n] {
		set line [string trim $line]
		if {$line eq ""} continue
		append preamble $line \n
	    }
	    return
	}
	proc variable {name value} {
	    upvar 0 ::tk::ps_preamble preamble
	    append preamble "/$name $value def\n"
	    return
	}
	proc function {name body} {
	    upvar 0 ::tk::ps_preamble preamble
	    append preamble "/$name \{"
	    foreach line [split $body \n] {
		set line [string trim $line]
		# Strip blank lines and comments from the bodies of functions
		if {$line eq "" } continue
		if {[string match {[%#]*} $line]} continue
		append preamble $line " "
	    }
	    append preamble "\} bind def\n"
	    return
	}
    }

    ps literal {
	%%BeginProlog
	% This is a standard prolog for Postscript generated by Tk's canvas
	% widget.
    }
    ps variable CurrentEncoding [CreatePostscriptEncoding]
    ps literal {50 dict begin}

    # 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).

    ps variable baseline 0
    ps variable stipimage 0
    ps variable height 0
    ps variable justify 0
    ps variable lineLength 0
    ps variable spacing 0
    ps variable stipple 0
    ps variable strings 0
    ps variable xoffset 0
    ps variable yoffset 0
    ps variable tmpstip null
    ps variable baselineSampler "( TXygqPZ)"
    # Put an extra-tall character in; done this way to avoid encoding trouble
    ps literal {baselineSampler 0 196 put}

    ps function cstringshow {
	{
	    dup type /stringtype eq
	    { show } { glyphshow }
	    ifelse

	} forall

    }


    ps function cstringwidth {
	0 exch 0 exch
	{
	    dup type /stringtype eq
	    { stringwidth } {
		currentfont /Encoding get exch 1 exch put (\001)
		stringwidth
	    }
	    ifelse
	    exch 3 1 roll add 3 1 roll add exch

	} forall
    }

    # font ISOEncode font
    #
    # This procedure changes the encoding of a font from the default
    # Postscript encoding to current system encoding. It's typically invoked
    # just before invoking "setfont". The body of this procedure comes from
    # Section 5.6.1 of the Postscript book.

    ps function ISOEncode {
	dup length dict begin
	{1 index /FID ne {def} {pop pop} ifelse} forall
	/Encoding CurrentEncoding 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
    }

    # 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.

    ps function StrokeClip {
	{strokepath} stopped {
	    (This Postscript printer gets limitcheck overflows when) =
	    (stippling dashed lines;  lines will be printed solid instead.) =
	    [] 0 setdash strokepath} if
	clip
    }

    # 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.

    ps function 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
    }

    # 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.

    ps function 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
    }

    # -- 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.


    ps function AdjustColor {
	CL 2 lt {
	    currentgray
	    CL 0 eq {
		.5 lt {0} {1} ifelse
	    } if
	    setgray
	} if
    }

    # 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, function 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.

    ps function 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 {
	    cstringwidth pop
	    dup lineLength gt {/lineLength exch def} {pop} ifelse
	    newpath
	} forall

	% Compute the baseline offset and the actual font height.

	0 0 moveto baselineSampler false charpath
	pathbbox dup /baseline exch def
	exch pop exch sub /height exch def pop
	newpath

	% Translate and rotate coordinates first so that the origin is at
	% the upper-left corner of the text's bounding box. Remember that
	% angle for rotating, and x and y for positioning are still on the
	% stack.
	translate
	rotate
	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 cstringwidth 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
		{
		    dup type /stringtype eq {
			% This segment is a string.
			{
			    char 0 3 -1 roll put
			    currentpoint
			    gsave
			    char true charpath clip StippleText
			    grestore
			    char stringwidth translate
			    moveto
			} forall
		    } {
			% This segment is glyph name
			% Temporary override
			currentfont /Encoding get exch 1 exch put
			currentpoint
			gsave (\001) true charpath clip StippleText
			grestore
			(\001) stringwidth translate
			moveto
		    } ifelse
		} forall
		grestore
	    } {cstringshow} ifelse
	    0 spacing neg translate
	} forall
    }

    # Define the "TkPhoto" function variants, which are modified versions
    # 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.

    ps function TkPhotoColor {
	gsave
	32 dict begin
	/tinteger exch def
	/transparent 1 string def
	transparent 0 tinteger put
	/olddict exch def
	olddict /DataSource get dup type /filetype ne {
	    olddict /DataSource 3 -1 roll
	    0 () /SubFileDecode filter put
	} {
	    pop
	} ifelse
	/newdict olddict maxlength dict def
	olddict newdict copy pop
	/w newdict /Width get def
	/crpp newdict /Decode get length 2 idiv def
	/str w string def
	/pix w crpp mul string def
	/substrlen 2 w log 2 log div floor exp cvi def
	/substrs [ {
	    substrlen string
	    0 1 substrlen 1 sub {
		1 index exch tinteger put
	    } for
	    /substrlen substrlen 2 idiv def
	    substrlen 0 eq {exit} if
	} loop ] def
	/h newdict /Height get def
	1 w div 1 h div matrix scale
	olddict /ImageMatrix get exch matrix concatmatrix
	matrix invertmatrix concat
	newdict /Height 1 put
	newdict /DataSource pix put
	/mat [w 0 0 h 0 0] def
	newdict /ImageMatrix mat put
	0 1 h 1 sub {
	    mat 5 3 -1 roll neg put
	    olddict /DataSource get str readstring pop pop
	    /tail str def
	    /x 0 def
	    olddict /DataSource get pix readstring pop pop
	    {
		tail transparent search dup /done exch not def
		{exch pop exch pop} if
		/w1 exch length def
		w1 0 ne {
		    newdict /DataSource
		    pix x crpp mul w1 crpp mul getinterval put
		    newdict /Width w1 put
		    mat 4 x neg put
		    /x x w1 add def
		    newdict image
		    /tail tail w1 tail length w1 sub getinterval def
		} if
		done {exit} if
		tail substrs {
		    anchorsearch {pop} if
		} forall
		/tail exch def
		tail length 0 eq {exit} if
		/x w tail length sub def
	    } loop
	} for
	end
	grestore
    }
    ps function TkPhotoMono {
	gsave
	32 dict begin
	/dummyInteger exch def
	/olddict exch def
	olddict /DataSource get dup type /filetype ne {
	    olddict /DataSource 3 -1 roll
	    0 () /SubFileDecode filter put
	} {
	    pop
	} ifelse
	/newdict olddict maxlength dict def
	olddict newdict copy pop
	/w newdict /Width get def
	/pix w 7 add 8 idiv string def
	/h newdict /Height get def
	1 w div 1 h div matrix scale
	olddict /ImageMatrix get exch matrix concatmatrix
	matrix invertmatrix concat
	newdict /Height 1 put
	newdict /DataSource pix put
	/mat [w 0 0 h 0 0] def
	newdict /ImageMatrix mat put
	0 1 h 1 sub {
	    mat 5 3 -1 roll neg put
	    0.000 0.000 0.000 setrgbcolor
	    olddict /DataSource get pix readstring pop pop
	    newdict /DataSource pix put
	    newdict imagemask
	    1.000 1.000 1.000 setrgbcolor
	    olddict /DataSource get pix readstring pop pop
	    newdict /DataSource pix put
	    newdict imagemask
	} for
	end
	grestore
    }

    ps literal %%EndProlog
}

proc tk::ensure_psenc_is_loaded {} {
}


>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
|
<
<
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
|
|
|
<
<
<
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
<
<

|
|
|
|
|
>
|
>
|

>
|
|
|
|
|
|
<
|
|
|
>
|
|

|
<
|
|
|
|
>
|
|



|
>
|
|
|
>
|
|

|
<
>
|
|
|
|
>
|
|
|
|
|
|
|

|
<
>
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|

|
<
>
|
|
|
|
|
|
>
|
|
>
|
>
|
|
|
>
|
|
|
|
>
>
|
|
|
|
>
|
|
|
|
|
>
|
|
|
>
|
|
|
|
|
|
|
|
|

|
<
|
|
>
>
|
|
|
|
|
|
|
|
|

|
<
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
>
|
<
>
|
|
>
|
|
|
|
|
|
|
>
|
>
|
|
|
|
|
|
>
|
>
|
|
|
|
>
|
|
|
|
|
<
|
|
>
|
|
|
>
|
>
|
|
|
>
|
|
|
|
>
>
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

































30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083

1084



1085
1086



1087
















1088





1089


1090
1091
1092



1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109


1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238

1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
















































1358

1359





















1360

1361




































1362


1363
1364
1365
1366
# mkpsenc.tcl --
#
# Creates Postscript encoding vector for given encoding
# 

proc ::tk::CreatePostscriptEncoding {encoding} {
    # now check for known. Even if it is known, it can be other
    # than we need. GhostScript seems to be happy with such approach
    set result "/CurrentEncoding \[\n"
    for {set i 0} {$i<256} {incr i 8} {
        for {set j 0} {$j<8} {incr j} {
	    set enc [encoding convertfrom $encoding [format %c [expr {$i+$j}]]]
	    if {[catch {format %04X [scan $enc %c]} hexcode]} {set hexcode {}}
	    if [info exists ::tk::psglyphs($hexcode)] {
		append result "/$::tk::psglyphs($hexcode)"
	    } else {
		append result "/space"
	    }
	}
	append result "\n"
    }
    append result "\] def\n"
    return $result
}

# List of adobe glyph names. Converted from glyphlist.txt, downloaded
# from Adobe

namespace eval ::tk {

































array set psglyphs {
   0020 space
   0021 exclam
   0022 quotedbl
   0023 numbersign
   0024 dollar
   0025 percent
   0026 ampersand
   0027 quotesingle
   0028 parenleft
   0029 parenright
   002A asterisk
   002B plus
   002C comma
   002D hyphen
   002E period
   002F slash
   0030 zero
   0031 one
   0032 two
   0033 three
   0034 four
   0035 five
   0036 six
   0037 seven
   0038 eight
   0039 nine
   003A colon
   003B semicolon
   003C less
   003D equal
   003E greater
   003F question
   0040 at
   0041 A
   0042 B
   0043 C
   0044 D
   0045 E
   0046 F
   0047 G
   0048 H
   0049 I
   004A J
   004B K
   004C L
   004D M
   004E N
   004F O
   0050 P
   0051 Q
   0052 R
   0053 S
   0054 T
   0055 U
   0056 V
   0057 W
   0058 X
   0059 Y
   005A Z
   005B bracketleft
   005C backslash
   005D bracketright
   005E asciicircum
   005F underscore
   0060 grave
   0061 a
   0062 b
   0063 c
   0064 d
   0065 e
   0066 f
   0067 g
   0068 h
   0069 i
   006A j
   006B k
   006C l
   006D m
   006E n
   006F o
   0070 p
   0071 q
   0072 r
   0073 s
   0074 t
   0075 u
   0076 v
   0077 w
   0078 x
   0079 y
   007A z
   007B braceleft
   007C bar
   007D braceright
   007E asciitilde
   00A0 space
   00A1 exclamdown
   00A2 cent
   00A3 sterling
   00A4 currency
   00A5 yen
   00A6 brokenbar
   00A7 section
   00A8 dieresis
   00A9 copyright
   00AA ordfeminine
   00AB guillemotleft
   00AC logicalnot
   00AD hyphen
   00AE registered
   00AF macron
   00B0 degree
   00B1 plusminus
   00B2 twosuperior
   00B3 threesuperior
   00B4 acute
   00B5 mu
   00B6 paragraph
   00B7 periodcentered
   00B8 cedilla
   00B9 onesuperior
   00BA ordmasculine
   00BB guillemotright
   00BC onequarter
   00BD onehalf
   00BE threequarters
   00BF questiondown
   00C0 Agrave
   00C1 Aacute
   00C2 Acircumflex
   00C3 Atilde
   00C4 Adieresis
   00C5 Aring
   00C6 AE
   00C7 Ccedilla
   00C8 Egrave
   00C9 Eacute
   00CA Ecircumflex
   00CB Edieresis
   00CC Igrave
   00CD Iacute
   00CE Icircumflex
   00CF Idieresis
   00D0 Eth
   00D1 Ntilde
   00D2 Ograve
   00D3 Oacute
   00D4 Ocircumflex
   00D5 Otilde
   00D6 Odieresis
   00D7 multiply
   00D8 Oslash
   00D9 Ugrave
   00DA Uacute
   00DB Ucircumflex
   00DC Udieresis
   00DD Yacute
   00DE Thorn
   00DF germandbls
   00E0 agrave
   00E1 aacute
   00E2 acircumflex
   00E3 atilde
   00E4 adieresis
   00E5 aring
   00E6 ae
   00E7 ccedilla
   00E8 egrave
   00E9 eacute
   00EA ecircumflex
   00EB edieresis
   00EC igrave
   00ED iacute
   00EE icircumflex
   00EF idieresis
   00F0 eth
   00F1 ntilde
   00F2 ograve
   00F3 oacute
   00F4 ocircumflex
   00F5 otilde
   00F6 odieresis
   00F7 divide
   00F8 oslash
   00F9 ugrave
   00FA uacute
   00FB ucircumflex
   00FC udieresis
   00FD yacute
   00FE thorn
   00FF ydieresis
   0100 Amacron
   0101 amacron
   0102 Abreve
   0103 abreve
   0104 Aogonek
   0105 aogonek
   0106 Cacute
   0107 cacute
   0108 Ccircumflex
   0109 ccircumflex
   010A Cdotaccent
   010B cdotaccent
   010C Ccaron
   010D ccaron
   010E Dcaron
   010F dcaron
   0110 Dcroat
   0111 dcroat
   0112 Emacron
   0113 emacron
   0114 Ebreve
   0115 ebreve
   0116 Edotaccent
   0117 edotaccent
   0118 Eogonek
   0119 eogonek
   011A Ecaron
   011B ecaron
   011C Gcircumflex
   011D gcircumflex
   011E Gbreve
   011F gbreve
   0120 Gdotaccent
   0121 gdotaccent
   0122 Gcommaaccent
   0123 gcommaaccent
   0124 Hcircumflex
   0125 hcircumflex
   0126 Hbar
   0127 hbar
   0128 Itilde
   0129 itilde
   012A Imacron
   012B imacron
   012C Ibreve
   012D ibreve
   012E Iogonek
   012F iogonek
   0130 Idotaccent
   0131 dotlessi
   0132 IJ
   0133 ij
   0134 Jcircumflex
   0135 jcircumflex
   0136 Kcommaaccent
   0137 kcommaaccent
   0138 kgreenlandic
   0139 Lacute
   013A lacute
   013B Lcommaaccent
   013C lcommaaccent
   013D Lcaron
   013E lcaron
   013F Ldot
   0140 ldot
   0141 Lslash
   0142 lslash
   0143 Nacute
   0144 nacute
   0145 Ncommaaccent
   0146 ncommaaccent
   0147 Ncaron
   0148 ncaron
   0149 napostrophe
   014A Eng
   014B eng
   014C Omacron
   014D omacron
   014E Obreve
   014F obreve
   0150 Ohungarumlaut
   0151 ohungarumlaut
   0152 OE
   0153 oe
   0154 Racute
   0155 racute
   0156 Rcommaaccent
   0157 rcommaaccent
   0158 Rcaron
   0159 rcaron
   015A Sacute
   015B sacute
   015C Scircumflex
   015D scircumflex
   015E Scedilla
   015F scedilla
   0160 Scaron
   0161 scaron
   0162 Tcommaaccent
   0163 tcommaaccent
   0164 Tcaron
   0165 tcaron
   0166 Tbar
   0167 tbar
   0168 Utilde
   0169 utilde
   016A Umacron
   016B umacron
   016C Ubreve
   016D ubreve
   016E Uring
   016F uring
   0170 Uhungarumlaut
   0171 uhungarumlaut
   0172 Uogonek
   0173 uogonek
   0174 Wcircumflex
   0175 wcircumflex
   0176 Ycircumflex
   0177 ycircumflex
   0178 Ydieresis
   0179 Zacute
   017A zacute
   017B Zdotaccent
   017C zdotaccent
   017D Zcaron
   017E zcaron
   017F longs
   0192 florin
   01A0 Ohorn
   01A1 ohorn
   01AF Uhorn
   01B0 uhorn
   01E6 Gcaron
   01E7 gcaron
   01FA Aringacute
   01FB aringacute
   01FC AEacute
   01FD aeacute
   01FE Oslashacute
   01FF oslashacute
   0218 Scommaaccent
   0219 scommaaccent
   021A Tcommaaccent
   021B tcommaaccent
   02BC afii57929
   02BD afii64937
   02C6 circumflex
   02C7 caron
   02C9 macron
   02D8 breve
   02D9 dotaccent
   02DA ring
   02DB ogonek
   02DC tilde
   02DD hungarumlaut
   0300 gravecomb
   0301 acutecomb
   0303 tildecomb
   0309 hookabovecomb
   0323 dotbelowcomb
   0384 tonos
   0385 dieresistonos
   0386 Alphatonos
   0387 anoteleia
   0388 Epsilontonos
   0389 Etatonos
   038A Iotatonos
   038C Omicrontonos
   038E Upsilontonos
   038F Omegatonos
   0390 iotadieresistonos
   0391 Alpha
   0392 Beta
   0393 Gamma
   0394 Delta
   0395 Epsilon
   0396 Zeta
   0397 Eta
   0398 Theta
   0399 Iota
   039A Kappa
   039B Lambda
   039C Mu
   039D Nu
   039E Xi
   039F Omicron
   03A0 Pi
   03A1 Rho
   03A3 Sigma
   03A4 Tau
   03A5 Upsilon
   03A6 Phi
   03A7 Chi
   03A8 Psi
   03A9 Omega
   03AA Iotadieresis
   03AB Upsilondieresis
   03AC alphatonos
   03AD epsilontonos
   03AE etatonos
   03AF iotatonos
   03B0 upsilondieresistonos
   03B1 alpha
   03B2 beta
   03B3 gamma
   03B4 delta
   03B5 epsilon
   03B6 zeta
   03B7 eta
   03B8 theta
   03B9 iota
   03BA kappa
   03BB lambda
   03BC mu
   03BD nu
   03BE xi
   03BF omicron
   03C0 pi
   03C1 rho
   03C2 sigma1
   03C3 sigma
   03C4 tau
   03C5 upsilon
   03C6 phi
   03C7 chi
   03C8 psi
   03C9 omega
   03CA iotadieresis
   03CB upsilondieresis
   03CC omicrontonos
   03CD upsilontonos
   03CE omegatonos
   03D1 theta1
   03D2 Upsilon1
   03D5 phi1
   03D6 omega1
   0401 afii10023
   0402 afii10051
   0403 afii10052
   0404 afii10053
   0405 afii10054
   0406 afii10055
   0407 afii10056
   0408 afii10057
   0409 afii10058
   040A afii10059
   040B afii10060
   040C afii10061
   040E afii10062
   040F afii10145
   0410 afii10017
   0411 afii10018
   0412 afii10019
   0413 afii10020
   0414 afii10021
   0415 afii10022
   0416 afii10024
   0417 afii10025
   0418 afii10026
   0419 afii10027
   041A afii10028
   041B afii10029
   041C afii10030
   041D afii10031
   041E afii10032
   041F afii10033
   0420 afii10034
   0421 afii10035
   0422 afii10036
   0423 afii10037
   0424 afii10038
   0425 afii10039
   0426 afii10040
   0427 afii10041
   0428 afii10042
   0429 afii10043
   042A afii10044
   042B afii10045
   042C afii10046
   042D afii10047
   042E afii10048
   042F afii10049
   0430 afii10065
   0431 afii10066
   0432 afii10067
   0433 afii10068
   0434 afii10069
   0435 afii10070
   0436 afii10072
   0437 afii10073
   0438 afii10074
   0439 afii10075
   043A afii10076
   043B afii10077
   043C afii10078
   043D afii10079
   043E afii10080
   043F afii10081
   0440 afii10082
   0441 afii10083
   0442 afii10084
   0443 afii10085
   0444 afii10086
   0445 afii10087
   0446 afii10088
   0447 afii10089
   0448 afii10090
   0449 afii10091
   044A afii10092
   044B afii10093
   044C afii10094
   044D afii10095
   044E afii10096
   044F afii10097
   0451 afii10071
   0452 afii10099
   0453 afii10100
   0454 afii10101
   0455 afii10102
   0456 afii10103
   0457 afii10104
   0458 afii10105
   0459 afii10106
   045A afii10107
   045B afii10108
   045C afii10109
   045E afii10110
   045F afii10193
   0462 afii10146
   0463 afii10194
   0472 afii10147
   0473 afii10195
   0474 afii10148
   0475 afii10196
   0490 afii10050
   0491 afii10098
   04D9 afii10846
   05B0 afii57799
   05B1 afii57801
   05B2 afii57800
   05B3 afii57802
   05B4 afii57793
   05B5 afii57794
   05B6 afii57795
   05B7 afii57798
   05B8 afii57797
   05B9 afii57806
   05BB afii57796
   05BC afii57807
   05BD afii57839
   05BE afii57645
   05BF afii57841
   05C0 afii57842
   05C1 afii57804
   05C2 afii57803
   05C3 afii57658
   05D0 afii57664
   05D1 afii57665
   05D2 afii57666
   05D3 afii57667
   05D4 afii57668
   05D5 afii57669
   05D6 afii57670
   05D7 afii57671
   05D8 afii57672
   05D9 afii57673
   05DA afii57674
   05DB afii57675
   05DC afii57676
   05DD afii57677
   05DE afii57678
   05DF afii57679
   05E0 afii57680
   05E1 afii57681
   05E2 afii57682
   05E3 afii57683
   05E4 afii57684
   05E5 afii57685
   05E6 afii57686
   05E7 afii57687
   05E8 afii57688
   05E9 afii57689
   05EA afii57690
   05F0 afii57716
   05F1 afii57717
   05F2 afii57718
   060C afii57388
   061B afii57403
   061F afii57407
   0621 afii57409
   0622 afii57410
   0623 afii57411
   0624 afii57412
   0625 afii57413
   0626 afii57414
   0627 afii57415
   0628 afii57416
   0629 afii57417
   062A afii57418
   062B afii57419
   062C afii57420
   062D afii57421
   062E afii57422
   062F afii57423
   0630 afii57424
   0631 afii57425
   0632 afii57426
   0633 afii57427
   0634 afii57428
   0635 afii57429
   0636 afii57430
   0637 afii57431
   0638 afii57432
   0639 afii57433
   063A afii57434
   0640 afii57440
   0641 afii57441
   0642 afii57442
   0643 afii57443
   0644 afii57444
   0645 afii57445
   0646 afii57446
   0647 afii57470
   0648 afii57448
   0649 afii57449
   064A afii57450
   064B afii57451
   064C afii57452
   064D afii57453
   064E afii57454
   064F afii57455
   0650 afii57456
   0651 afii57457
   0652 afii57458
   0660 afii57392
   0661 afii57393
   0662 afii57394
   0663 afii57395
   0664 afii57396
   0665 afii57397
   0666 afii57398
   0667 afii57399
   0668 afii57400
   0669 afii57401
   066A afii57381
   066D afii63167
   0679 afii57511
   067E afii57506
   0686 afii57507
   0688 afii57512
   0691 afii57513
   0698 afii57508
   06A4 afii57505
   06AF afii57509
   06BA afii57514
   06D2 afii57519
   06D5 afii57534
   1E80 Wgrave
   1E81 wgrave
   1E82 Wacute
   1E83 wacute
   1E84 Wdieresis
   1E85 wdieresis
   1EF2 Ygrave
   1EF3 ygrave
   200C afii61664
   200D afii301
   200E afii299
   200F afii300
   2012 figuredash
   2013 endash
   2014 emdash
   2015 afii00208
   2017 underscoredbl
   2018 quoteleft
   2019 quoteright
   201A quotesinglbase
   201B quotereversed
   201C quotedblleft
   201D quotedblright
   201E quotedblbase
   2020 dagger
   2021 daggerdbl
   2022 bullet
   2024 onedotenleader
   2025 twodotenleader
   2026 ellipsis
   202C afii61573
   202D afii61574
   202E afii61575
   2030 perthousand
   2032 minute
   2033 second
   2039 guilsinglleft
   203A guilsinglright
   203C exclamdbl
   2044 fraction
   2070 zerosuperior
   2074 foursuperior
   2075 fivesuperior
   2076 sixsuperior
   2077 sevensuperior
   2078 eightsuperior
   2079 ninesuperior
   207D parenleftsuperior
   207E parenrightsuperior
   207F nsuperior
   2080 zeroinferior
   2081 oneinferior
   2082 twoinferior
   2083 threeinferior
   2084 fourinferior
   2085 fiveinferior
   2086 sixinferior
   2087 seveninferior
   2088 eightinferior
   2089 nineinferior
   208D parenleftinferior
   208E parenrightinferior
   20A1 colonmonetary
   20A3 franc
   20A4 lira
   20A7 peseta
   20AA afii57636
   20AB dong
   20AC Euro
   2105 afii61248
   2111 Ifraktur
   2113 afii61289
   2116 afii61352
   2118 weierstrass
   211C Rfraktur
   211E prescription
   2122 trademark
   2126 Omega
   212E estimated
   2135 aleph
   2153 onethird
   2154 twothirds
   215B oneeighth
   215C threeeighths
   215D fiveeighths
   215E seveneighths
   2190 arrowleft
   2191 arrowup
   2192 arrowright
   2193 arrowdown
   2194 arrowboth
   2195 arrowupdn
   21A8 arrowupdnbse
   21B5 carriagereturn
   21D0 arrowdblleft
   21D1 arrowdblup
   21D2 arrowdblright
   21D3 arrowdbldown
   21D4 arrowdblboth
   2200 universal
   2202 partialdiff
   2203 existential
   2205 emptyset
   2206 Delta
   2207 gradient
   2208 element
   2209 notelement
   220B suchthat
   220F product
   2211 summation
   2212 minus
   2215 fraction
   2217 asteriskmath
   2219 periodcentered
   221A radical
   221D proportional
   221E infinity
   221F orthogonal
   2220 angle
   2227 logicaland
   2228 logicalor
   2229 intersection
   222A union
   222B integral
   2234 therefore
   223C similar
   2245 congruent
   2248 approxequal
   2260 notequal
   2261 equivalence
   2264 lessequal
   2265 greaterequal
   2282 propersubset
   2283 propersuperset
   2284 notsubset
   2286 reflexsubset
   2287 reflexsuperset
   2295 circleplus
   2297 circlemultiply
   22A5 perpendicular
   22C5 dotmath
   2302 house
   2310 revlogicalnot
   2320 integraltp
   2321 integralbt
   2329 angleleft
   232A angleright
   2500 SF100000
   2502 SF110000
   250C SF010000
   2510 SF030000
   2514 SF020000
   2518 SF040000
   251C SF080000
   2524 SF090000
   252C SF060000
   2534 SF070000
   253C SF050000
   2550 SF430000
   2551 SF240000
   2552 SF510000
   2553 SF520000
   2554 SF390000
   2555 SF220000
   2556 SF210000
   2557 SF250000
   2558 SF500000
   2559 SF490000
   255A SF380000
   255B SF280000
   255C SF270000
   255D SF260000
   255E SF360000
   255F SF370000
   2560 SF420000
   2561 SF190000
   2562 SF200000
   2563 SF230000
   2564 SF470000
   2565 SF480000
   2566 SF410000
   2567 SF450000
   2568 SF460000
   2569 SF400000
   256A SF540000
   256B SF530000
   256C SF440000
   2580 upblock
   2584 dnblock
   2588 block
   258C lfblock
   2590 rtblock
   2591 ltshade
   2592 shade
   2593 dkshade
   25A0 filledbox
   25A1 H22073
   25AA H18543
   25AB H18551
   25AC filledrect
   25B2 triagup
   25BA triagrt
   25BC triagdn
   25C4 triaglf
   25CA lozenge
   25CB circle
   25CF H18533
   25D8 invbullet
   25D9 invcircle
   25E6 openbullet
   263A smileface
   263B invsmileface
   263C sun
   2640 female
   2642 male
   2660 spade
   2663 club
   2665 heart
   2666 diamond
   266A musicalnote
   266B musicalnotedbl
   F6BE dotlessj
   F6BF LL
   F6C0 ll
   F6C1 Scedilla
   F6C2 scedilla
   F6C3 commaaccent
   F6C4 afii10063
   F6C5 afii10064
   F6C6 afii10192
   F6C7 afii10831
   F6C8 afii10832
   F6C9 Acute
   F6CA Caron
   F6CB Dieresis
   F6CC DieresisAcute
   F6CD DieresisGrave
   F6CE Grave
   F6CF Hungarumlaut
   F6D0 Macron
   F6D1 cyrBreve
   F6D2 cyrFlex
   F6D3 dblGrave
   F6D4 cyrbreve
   F6D5 cyrflex
   F6D6 dblgrave
   F6D7 dieresisacute
   F6D8 dieresisgrave
   F6D9 copyrightserif
   F6DA registerserif
   F6DB trademarkserif
   F6DC onefitted
   F6DD rupiah
   F6DE threequartersemdash
   F6DF centinferior
   F6E0 centsuperior
   F6E1 commainferior
   F6E2 commasuperior
   F6E3 dollarinferior
   F6E4 dollarsuperior
   F6E5 hypheninferior
   F6E6 hyphensuperior
   F6E7 periodinferior
   F6E8 periodsuperior
   F6E9 asuperior
   F6EA bsuperior
   F6EB dsuperior
   F6EC esuperior
   F6ED isuperior
   F6EE lsuperior
   F6EF msuperior
   F6F0 osuperior
   F6F1 rsuperior
   F6F2 ssuperior
   F6F3 tsuperior
   F6F4 Brevesmall
   F6F5 Caronsmall
   F6F6 Circumflexsmall
   F6F7 Dotaccentsmall
   F6F8 Hungarumlautsmall
   F6F9 Lslashsmall
   F6FA OEsmall
   F6FB Ogoneksmall
   F6FC Ringsmall
   F6FD Scaronsmall
   F6FE Tildesmall
   F6FF Zcaronsmall
   F721 exclamsmall
   F724 dollaroldstyle
   F726 ampersandsmall
   F730 zerooldstyle
   F731 oneoldstyle
   F732 twooldstyle
   F733 threeoldstyle
   F734 fouroldstyle
   F735 fiveoldstyle
   F736 sixoldstyle
   F737 sevenoldstyle
   F738 eightoldstyle
   F739 nineoldstyle
   F73F questionsmall
   F760 Gravesmall
   F761 Asmall
   F762 Bsmall
   F763 Csmall
   F764 Dsmall
   F765 Esmall
   F766 Fsmall
   F767 Gsmall
   F768 Hsmall
   F769 Ismall
   F76A Jsmall
   F76B Ksmall
   F76C Lsmall
   F76D Msmall
   F76E Nsmall
   F76F Osmall
   F770 Psmall
   F771 Qsmall
   F772 Rsmall
   F773 Ssmall
   F774 Tsmall
   F775 Usmall
   F776 Vsmall
   F777 Wsmall
   F778 Xsmall
   F779 Ysmall
   F77A Zsmall
   F7A1 exclamdownsmall
   F7A2 centoldstyle
   F7A8 Dieresissmall
   F7AF Macronsmall
   F7B4 Acutesmall
   F7B8 Cedillasmall
   F7BF questiondownsmall
   F7E0 Agravesmall
   F7E1 Aacutesmall
   F7E2 Acircumflexsmall
   F7E3 Atildesmall
   F7E4 Adieresissmall
   F7E5 Aringsmall
   F7E6 AEsmall
   F7E7 Ccedillasmall
   F7E8 Egravesmall
   F7E9 Eacutesmall
   F7EA Ecircumflexsmall
   F7EB Edieresissmall
   F7EC Igravesmall
   F7ED Iacutesmall
   F7EE Icircumflexsmall
   F7EF Idieresissmall
   F7F0 Ethsmall
   F7F1 Ntildesmall
   F7F2 Ogravesmall
   F7F3 Oacutesmall
   F7F4 Ocircumflexsmall
   F7F5 Otildesmall
   F7F6 Odieresissmall
   F7F8 Oslashsmall
   F7F9 Ugravesmall
   F7FA Uacutesmall
   F7FB Ucircumflexsmall
   F7FC Udieresissmall
   F7FD Yacutesmall
   F7FE Thornsmall
   F7FF Ydieresissmall
   F8E5 radicalex
   F8E6 arrowvertex
   F8E7 arrowhorizex
   F8E8 registersans
   F8E9 copyrightsans
   F8EA trademarksans
   F8EB parenlefttp
   F8EC parenleftex
   F8ED parenleftbt
   F8EE bracketlefttp
   F8EF bracketleftex
   F8F0 bracketleftbt
   F8F1 bracelefttp
   F8F2 braceleftmid
   F8F3 braceleftbt
   F8F4 braceex
   F8F5 integralex
   F8F6 parenrighttp
   F8F7 parenrightex
   F8F8 parenrightbt
   F8F9 bracketrighttp
   F8FA bracketrightex
   F8FB bracketrightbt
   F8FC bracerighttp
   F8FD bracerightmid
   F8FE bracerightbt
   FB00 ff
   FB01 fi
   FB02 fl
   FB03 ffi
   FB04 ffl
   FB1F afii57705
   FB2A afii57694
   FB2B afii57695
   FB35 afii57723
   FB4B afii57700
}


# precalculate entire prolog when this file is loaded 



# (to speed things up)
set ps_preamable "%%BeginProlog\n"



append ps_preamable [CreatePostscriptEncoding [encoding system]]
















append ps_preamable {





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




/cstringshow {
    {
	dup type /stringtype eq
	{ show } { glyphshow }
	ifelse
    }
    forall
} bind def



/cstringwidth {
    0 exch 0 exch
    {
	dup type /stringtype eq
	{ stringwidth } { 
	    currentfont /Encoding get exch 1 exch put (\001) stringwidth 

        }
	ifelse 
	exch 3 1 roll add 3 1 roll add exch
    }
    forall
} bind def

% font ISOEncode font

% This procedure changes the encoding of a font from the default
% Postscript encoding to current system encoding.  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 CurrentEncoding 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 {
	cstringwidth 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 cstringwidth 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
	    {
		dup type /stringtype eq {
		    % This segment is a string.
		    {
		        char 0 3 -1 roll put
		        currentpoint
		        gsave
		        char true charpath clip StippleText
		        grestore
		        char stringwidth translate
		        moveto
		    } forall
		} {
		    % This segment is glyph name
		    % Temporary override
		    currentfont /Encoding get exch 1 exch put
		    currentpoint
		    gsave (\001) true charpath clip StippleText
		    grestore
	            (\001) stringwidth translate
		    moveto
		} ifelse
	    } forall
	    grestore 
	} {cstringshow} ifelse
	0 spacing neg translate
    } forall
















































} bind def























%%EndProlog

}







































}

proc tk::ensure_psenc_is_loaded {} {
}

Changes to library/msgbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
# msgbox.tcl --
#
#	Implements messageboxes for platforms that do not have native
#	messagebox support.
#
# Copyright © 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.
#

# Ensure existence of ::tk::dialog namespace
#





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# msgbox.tcl --
#
#	Implements messageboxes for platforms that do not have native
#	messagebox support.
#
# 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.
#

# Ensure existence of ::tk::dialog namespace
#
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
   0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00,
   0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"

# ::tk::MessageBox --
#
#	Pops up a messagebox with an application-supplied message with
#	an icon and a list of buttons. This procedure will be called
#	by tk_messageBox if the platform does not have native
#	messagebox support, or if the particular type of messagebox is
#	not supported natively.
#
#	Color icons are used on Unix displays that have a color
#	depth of 4 or more and $tk_strictMotif is not on.
#
#	This procedure is a private procedure shouldn't be called
#	directly. Call tk_messageBox instead.
#
#	See the user documentation for details on what tk_messageBox does.
#
proc ::tk::MessageBox {args} {
    global tk_strictMotif
    variable ::tk::Priv

    set w ::tk::PrivMsgBox
    upvar $w data

    #
    # The default value of the title is space (" ") not the empty string
    # because for some window managers, a
    #		wm title .foo ""
    # causes the window title to be "foo" instead of the empty string.
    #
    set specs {
	{-default "" "" ""}
	{-detail "" "" ""}
        {-icon "" "" "info"}
        {-message "" "" ""}
        {-parent "" "" .}
        {-title "" "" " "}
        {-type "" "" "ok"}
    }

    tclParseConfigSpec $w $specs "" $args

    if {$data(-icon) ni {info warning error question}} {
	return -code error -errorcode [list TK LOOKUP ICON $data(-icon)] \
	    "bad -icon value \"$data(-icon)\": must be error, info, question, or warning"
    }
    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {
	switch -- $data(-icon) {
	    "error"     {set data(-icon) "stop"}
	    "warning"   {set data(-icon) "caution"}
	    "info"      {set data(-icon) "note"}
	}



    }

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }

    switch -- $data(-type) {
	abortretryignore {
	    set names [list abort retry ignore]
	    set labels [list &Abort &Retry &Ignore]
	    set cancel abort
	}
	ok {
	    set names [list ok]
	    set labels {&OK}







|

















|







|















|
<
|








>
>
>



<
|



|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
   0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00,
   0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"

# ::tk::MessageBox --
#
#	Pops up a messagebox with an application-supplied message with
#	an icon and a list of buttons. This procedure will be called
#	by tk_messageBox if the platform does not have native
#	messagebox support, or if the particular type of messagebox is
#	not supported natively.
#
#	Color icons are used on Unix displays that have a color
#	depth of 4 or more and $tk_strictMotif is not on.
#
#	This procedure is a private procedure shouldn't be called
#	directly. Call tk_messageBox instead.
#
#	See the user documentation for details on what tk_messageBox does.
#
proc ::tk::MessageBox {args} {
    global tcl_platform tk_strictMotif
    variable ::tk::Priv

    set w ::tk::PrivMsgBox
    upvar $w data

    #
    # The default value of the title is space (" ") not the empty string
    # because for some window managers, a 
    #		wm title .foo ""
    # causes the window title to be "foo" instead of the empty string.
    #
    set specs {
	{-default "" "" ""}
	{-detail "" "" ""}
        {-icon "" "" "info"}
        {-message "" "" ""}
        {-parent "" "" .}
        {-title "" "" " "}
        {-type "" "" "ok"}
    }

    tclParseConfigSpec $w $specs "" $args

    if {[lsearch -exact {info warning error question} $data(-icon)] == -1} {

	error "bad -icon value \"$data(-icon)\": must be error, info, question, or warning"
    }
    set windowingsystem [tk windowingsystem]
    if {$windowingsystem eq "aqua"} {
	switch -- $data(-icon) {
	    "error"     {set data(-icon) "stop"}
	    "warning"   {set data(-icon) "caution"}
	    "info"      {set data(-icon) "note"}
	}
	option add *Dialog*background systemDialogBackgroundActive widgetDefault
	option add *Dialog*Button.highlightBackground \
		systemDialogBackgroundActive widgetDefault
    }

    if {![winfo exists $data(-parent)]} {

	error "bad window path name \"$data(-parent)\""
    }

    switch -- $data(-type) {
	abortretryignore { 
	    set names [list abort retry ignore]
	    set labels [list &Abort &Retry &Ignore]
	    set cancel abort
	}
	ok {
	    set names [list ok]
	    set labels {&OK}
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
	}
	yesnocancel {
	    set names [list yes no cancel]
	    set labels [list &Yes &No &Cancel]
	    set cancel cancel
	}
	default {
	    return -code error -errorcode [list TK LOOKUP DLG_TYPE $data(-type)] \
		"bad -type value \"$data(-type)\": must be\
		abortretryignore, ok, okcancel, retrycancel,\
		yesno, or yesnocancel"
	}
    }

    set buttons {}
    foreach name $names lab $labels {
	lappend buttons [list $name -text [mc $lab]]
    }

    # If no default button was specified, the default default is the
    # first button (Bug: 2218).

    if {$data(-default) eq ""} {
	set data(-default) [lindex [lindex $buttons 0] 0]
    }

    set valid 0
    foreach btn $buttons {
	if {[lindex $btn 0] eq $data(-default)} {
	    set valid 1
	    break
	}
    }
    if {!$valid} {
	return -code error -errorcode {TK MSGBOX DEFAULT} \
	    "bad -default value \"$data(-default)\": must be\
	    abort, retry, ignore, ok, cancel, no, or yes"
    }

    # 2. Set the dialog to be a child window of $parent
    #
    #
    if {$data(-parent) ne "."} {
	set w $data(-parent).__tk__messagebox







<
|
|
|








|














<
|
<







200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233

234
235
236
237
238
239
240
	}
	yesnocancel {
	    set names [list yes no cancel]
	    set labels [list &Yes &No &Cancel]
	    set cancel cancel
	}
	default {

	    error "bad -type value \"$data(-type)\": must be\
		    abortretryignore, ok, okcancel, retrycancel,\
		    yesno, or yesnocancel"
	}
    }

    set buttons {}
    foreach name $names lab $labels {
	lappend buttons [list $name -text [mc $lab]]
    }

    # If no default button was specified, the default default is the 
    # first button (Bug: 2218).

    if {$data(-default) eq ""} {
	set data(-default) [lindex [lindex $buttons 0] 0]
    }

    set valid 0
    foreach btn $buttons {
	if {[lindex $btn 0] eq $data(-default)} {
	    set valid 1
	    break
	}
    }
    if {!$valid} {

	error "invalid default button \"$data(-default)\""

    }

    # 2. Set the dialog to be a child window of $parent
    #
    #
    if {$data(-parent) ne "."} {
	set w $data(-parent).__tk__messagebox
269
270
271
272
273
274
275
276
277
278
279
280




281
282
283
284
285
286
287
288
289
290
291

292
293

294
295

296
297
298
299


300
301

302

303
304

305




306
307





308
309
310

311




312
313
314
315
316
317
318
319
320
321
322
323
324

    if {$windowingsystem eq "aqua"} {
	::tk::unsupported::MacWindowStyle style $w moveableModal {}
    } elseif {$windowingsystem eq "x11"} {
        wm attributes $w -type dialog
    }

    ttk::frame $w.bot
    grid anchor $w.bot center
    pack $w.bot -side bottom -fill both
    ttk::frame $w.top
    pack $w.top -side top -fill both -expand 1





    # 4. Fill the top part with bitmap, message and detail (use the
    # option database for -wraplength and -font so that they can be
    # overridden by the caller).

    option add *Dialog.msg.wrapLength 3i widgetDefault
    option add *Dialog.dtl.wrapLength 3i widgetDefault
    option add *Dialog.msg.font TkCaptionFont widgetDefault
    option add *Dialog.dtl.font TkDefaultFont widgetDefault

    ttk::label $w.msg -anchor nw -justify left -text $data(-message)

    if {$data(-detail) ne ""} {
	ttk::label $w.dtl -anchor nw -justify left -text $data(-detail)

    }
    if {$data(-icon) ne ""} {

	if {([winfo depth $w] < 4) || $tk_strictMotif} {
	    # ttk::label has no -bitmap option
	    label $w.bitmap -bitmap $data(-icon) -background $bg
	} else {


	    switch $data(-icon) {
                error {

                    ttk::label $w.bitmap -image ::tk::icons::error

                }
                info {

                    ttk::label $w.bitmap -image ::tk::icons::information




                }
                question {





                    ttk::label $w.bitmap -image ::tk::icons::question
                }
                default {

                    ttk::label $w.bitmap -image ::tk::icons::warning




                }
	    }
	}
    }
    grid $w.bitmap $w.msg -in $w.top -sticky news -padx 2m -pady 2m
    grid configure $w.bitmap -sticky nw
    grid columnconfigure $w.top 1 -weight 1
    if {$data(-detail) ne ""} {
	grid ^ $w.dtl -in $w.top -sticky news -padx 2m -pady {0 2m}
	grid rowconfigure $w.top 1 -weight 1
    } else {
	grid rowconfigure $w.top 0 -weight 1
    }







|


|

>
>
>
>











>


>


>
|

|

>
>

|
>
|
>
|
|
>
|
>
>
>
>
|
|
>
>
>
>
>
|
|
|
>
|
>
>
>
>
|




<







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347

    if {$windowingsystem eq "aqua"} {
	::tk::unsupported::MacWindowStyle style $w moveableModal {}
    } elseif {$windowingsystem eq "x11"} {
        wm attributes $w -type dialog
    }

    ttk::frame $w.bot;# -background $bg
    grid anchor $w.bot center
    pack $w.bot -side bottom -fill both
    ttk::frame $w.top;# -background $bg
    pack $w.top -side top -fill both -expand 1
    if {$windowingsystem ne "aqua"} {
	#$w.bot configure -relief raised -bd 1
	#$w.top configure -relief raised -bd 1
    }

    # 4. Fill the top part with bitmap, message and detail (use the
    # option database for -wraplength and -font so that they can be
    # overridden by the caller).

    option add *Dialog.msg.wrapLength 3i widgetDefault
    option add *Dialog.dtl.wrapLength 3i widgetDefault
    option add *Dialog.msg.font TkCaptionFont widgetDefault
    option add *Dialog.dtl.font TkDefaultFont widgetDefault

    ttk::label $w.msg -anchor nw -justify left -text $data(-message)
    #-background $bg
    if {$data(-detail) ne ""} {
	ttk::label $w.dtl -anchor nw -justify left -text $data(-detail)
	#-background $bg
    }
    if {$data(-icon) ne ""} {
	if {$windowingsystem eq "aqua"
		|| ([winfo depth $w] < 4) || $tk_strictMotif} {
	    # ttk::label has no -bitmap option
	    label $w.bitmap -bitmap $data(-icon);# -background $bg
	} else {
	    canvas $w.bitmap -width 32 -height 32 -highlightthickness 0 \
		    -background $bg
	    switch $data(-icon) {
		error {
		    $w.bitmap create oval 0 0 31 31 -fill red -outline black
		    $w.bitmap create line 9 9 23 23 -fill white -width 4
		    $w.bitmap create line 9 23 23 9 -fill white -width 4
		}
		info {
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::b1
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::b2
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::i
		}
		question {
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::b1
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::b2
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::q
		}
		default {
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::w1
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::w2
		    $w.bitmap create image 0 0 -anchor nw \
			    -image ::tk::dialog::w3
		}
	    }
	}
    }
    grid $w.bitmap $w.msg -in $w.top -sticky news -padx 2m -pady 2m

    grid columnconfigure $w.top 1 -weight 1
    if {$data(-detail) ne ""} {
	grid ^ $w.dtl -in $w.top -sticky news -padx 2m -pady {0 2m}
	grid rowconfigure $w.top 1 -weight 1
    } else {
	grid rowconfigure $w.top 0 -weight 1
    }
333
334
335
336
337
338
339

340
341
342
343
344
345
346
	    # Capitalize the first letter of $name
	    set capName [string toupper $name 0]
	    set opts [list -text $capName]
	}

	eval [list tk::AmpWidget ttk::button $w.$name] $opts \
		[list -command [list set tk::Priv(button) $name]]


	if {$name eq $data(-default)} {
	    $w.$name configure -default active
	} else {
	    $w.$name configure -default normal
	}
	grid $w.$name -in $w.bot -row 0 -column $i -padx 3m -pady 2m -sticky ew







>







356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
	    # Capitalize the first letter of $name
	    set capName [string toupper $name 0]
	    set opts [list -text $capName]
	}

	eval [list tk::AmpWidget ttk::button $w.$name] $opts \
		[list -command [list set tk::Priv(button) $name]]
	# -padx 3m

	if {$name eq $data(-default)} {
	    $w.$name configure -default active
	} else {
	    $w.$name configure -default normal
	}
	grid $w.$name -in $w.bot -row 0 -column $i -padx 3m -pady 2m -sticky ew

Changes to library/msgs/cs.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55








































56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
namespace eval ::tk {
    ::msgcat::mcset cs "&Abort" "&Přerušit"
    ::msgcat::mcset cs "&About..." "&O programu..."
    ::msgcat::mcset cs "All Files" "Všechny soubory"
    ::msgcat::mcset cs "Application Error" "Chyba programu"
    ::msgcat::mcset cs "Bold Italic"
    ::msgcat::mcset cs "&Blue" "&Modá"
    ::msgcat::mcset cs "Cancel" "Zrušit"
    ::msgcat::mcset cs "&Cancel" "&Zrušit"
    ::msgcat::mcset cs "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nemohu změnit atkálí adreář na \"%1\$s\".\nPístup odítnut."
    ::msgcat::mcset cs "Choose Directory" "ýběr adreáře"
    ::msgcat::mcset cs "Cl&ear" "Sma&zat"
    ::msgcat::mcset cs "&Clear Console" "&Smazat konzolu"
    ::msgcat::mcset cs "Color" "Barva"
    ::msgcat::mcset cs "Console" "Konzole"
    ::msgcat::mcset cs "&Copy" "&Koírovat"
    ::msgcat::mcset cs "Cu&t" "V&yíznout"
    ::msgcat::mcset cs "&Delete" "&Smazat"
    ::msgcat::mcset cs "Details >>" "Detaily >>"
    ::msgcat::mcset cs "Directory \"%1\$s\" does not exist." "Adreář \"%1\$s\" neexistuje."
    ::msgcat::mcset cs "&Directory:" "&Adreář:"
    ::msgcat::mcset cs "&Edit" "Úpravy"
    ::msgcat::mcset cs "Error: %1\$s" "Chyba: %1\$s"
    ::msgcat::mcset cs "E&xit" "&Konec"
    ::msgcat::mcset cs "&File" "&Soubor"
    ::msgcat::mcset cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" již existuje.\nChcete jej přepsat?"
    ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" již existuje.\n\n"
    ::msgcat::mcset cs "File \"%1\$s\" does not exist." "Soubor \"%1\$s\" neexistuje."
    ::msgcat::mcset cs "File &name:" "&Jéno souboru:"
    ::msgcat::mcset cs "File &names:" "&Jéna souborů:"
    ::msgcat::mcset cs "Files of &type:" "&Typy souborů:"
    ::msgcat::mcset cs "Fi&les:" "Sou&bory:"
    ::msgcat::mcset cs "&Filter" "&Filtr"
    ::msgcat::mcset cs "Fil&ter:" "Fil&tr:"
    ::msgcat::mcset cs "Font st&yle:"
    ::msgcat::mcset cs "&Green" "Ze&leá"
    ::msgcat::mcset cs "&Help" "&ápověda"
    ::msgcat::mcset cs "Hi" "Ahoj"
    ::msgcat::mcset cs "&Hide Console" "&Schovat Konzolu"
    ::msgcat::mcset cs "&Ignore" "&Ignorovat"
    ::msgcat::mcset cs "Invalid file name \"%1\$s\"." "Špaté jéno souboru \"%1\$s\"."
    ::msgcat::mcset cs "Log Files" "Log soubory"
    ::msgcat::mcset cs "&No" "&Ne"
    ::msgcat::mcset cs "&OK"
    ::msgcat::mcset cs "OK"
    ::msgcat::mcset cs "Ok"
    ::msgcat::mcset cs "Open" "Otevít"
    ::msgcat::mcset cs "&Open" "&Otevít"
    ::msgcat::mcset cs "Open Multiple Files" "Otevít íce souborů"
    ::msgcat::mcset cs "P&aste" "&Vložit"
    ::msgcat::mcset cs "&Quit" "&Ukončit"
    ::msgcat::mcset cs "&Red" "Če&rveá"
    ::msgcat::mcset cs "Replace existing file?" "Nahradit sávaíí soubor?"
    ::msgcat::mcset cs "&Retry" "Z&novu"
    ::msgcat::mcset cs "&Save" "&Uložit"








































    ::msgcat::mcset cs "Save As" "Uložit jako"
    ::msgcat::mcset cs "Save To Log" "Uložit do logu"
    ::msgcat::mcset cs "Select Log File" "Vybrat log soubor"
    ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k naháí"
    ::msgcat::mcset cs "&Selection:" "&ýběr:"
    ::msgcat::mcset cs "Skip Messages" "Přeskočit zpávy"
    ::msgcat::mcset cs "&Source..." "&Zdroj..."
    ::msgcat::mcset cs "Tcl Scripts" "Tcl skripty"
    ::msgcat::mcset cs "Tcl for Windows" "Tcl pro Windows"
    ::msgcat::mcset cs "Text Files" "Textoé soubory"
    ::msgcat::mcset cs "abort" "přerušit"
    ::msgcat::mcset cs "blue" "modá"
    ::msgcat::mcset cs "cancel" "zrušit"
    ::msgcat::mcset cs "extension" "pípona"
    ::msgcat::mcset cs "extensions" "pípony"
    ::msgcat::mcset cs "green" "zeleá"
    ::msgcat::mcset cs "ignore" "ignorovat"
    ::msgcat::mcset cs "ok"
    ::msgcat::mcset cs "red" "červeá"
    ::msgcat::mcset cs "retry" "znovu"
    ::msgcat::mcset cs "yes" "ano"
}

|

<
<
<
|
<
|
<
<
<

<
<
|
<

<
<
|
|
<
<

<
<
<
<
<
<
<

<
<
|
|
<


<
<


<
<
<
|
<
<
|
|
<

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
<
|
|


|
|
|
|
|
|
|


|



1
2
3



4

5



6


7

8


9
10


11







12


13
14

15
16


17
18



19


20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
namespace eval ::tk {
    ::msgcat::mcset cs "&Abort" "&P\u0159eru\u0161it"
    ::msgcat::mcset cs "&About..." "&O programu..."



    ::msgcat::mcset cs "&Blue" "&Modr\341"

    ::msgcat::mcset cs "&Cancel" "&Zru\u0161it"



    ::msgcat::mcset cs "&Clear Console" "&Smazat konzolu"


    ::msgcat::mcset cs "&Copy" "&Kop\355rovat"

    ::msgcat::mcset cs "&Delete" "&Smazat"


    ::msgcat::mcset cs "&Directory:" "&Adres\341\u0159:"
    ::msgcat::mcset cs "&Edit" "&\332pravy"


    ::msgcat::mcset cs "&File" "&Soubor"







    ::msgcat::mcset cs "&Filter" "&Filtr"


    ::msgcat::mcset cs "&Green" "Ze&len\341"
    ::msgcat::mcset cs "&Help" "&N\341pov\u011bda"

    ::msgcat::mcset cs "&Hide Console" "&Schovat Konzolu"
    ::msgcat::mcset cs "&Ignore" "&Ignorovat"


    ::msgcat::mcset cs "&No" "&Ne"
    ::msgcat::mcset cs "&OK"



    ::msgcat::mcset cs "&Open" "&Otev\u0159\355t"


    ::msgcat::mcset cs "&Quit" "&Ukon\u010dit"
    ::msgcat::mcset cs "&Red" "\u010ce&rven\341"

    ::msgcat::mcset cs "&Retry" "Z&novu"
    ::msgcat::mcset cs "&Save" "&Ulo\u017eit"
    ::msgcat::mcset cs "&Selection:" "&V\375b\u011br:"
    ::msgcat::mcset cs "&Source..." "&Zdroj..."
    ::msgcat::mcset cs "&Yes" "&Ano"
    ::msgcat::mcset cs "About..." "O programu..."
    ::msgcat::mcset cs "All Files" "V\u0161echny soubory"
    ::msgcat::mcset cs "Application Error" "Chyba programu"
    ::msgcat::mcset cs "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nemohu zm\u011bnit atku\341ln\355 adres\341\u0159 na \"%1\$s\".\nP\u0159\355stup odm\355tnut."
    ::msgcat::mcset cs "Choose Directory" "V\375b\u011br adres\341\u0159e"
    ::msgcat::mcset cs "Cl&ear" "Sma&zat"
    ::msgcat::mcset cs "Clear" "Smazat"
    ::msgcat::mcset cs "Color" "Barva"
    ::msgcat::mcset cs "Console" "Konzole"
    ::msgcat::mcset cs "Copy" "Kop\355rovat"
    ::msgcat::mcset cs "Cu&t" "V&y\u0159\355znout"
    ::msgcat::mcset cs "Cut" "Vy\u0159\355znout"
    ::msgcat::mcset cs "Delete" "Smazat"
    ::msgcat::mcset cs "Details >>" "Detaily >>"
    ::msgcat::mcset cs "Directory \"%1\$s\" does not exist." "Adres\341\u0159 \"%1\$s\" neexistuje."
    ::msgcat::mcset cs "E&xit" "&Konec"
    ::msgcat::mcset cs "Error: %1\$s" "Chyba: %1\$s"
    ::msgcat::mcset cs "Exit" "Konec"
    ::msgcat::mcset cs "Fi&les:" "Sou&bory:"
    ::msgcat::mcset cs "Fil&ter:" "Fil&tr:"
    ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" ji\u017e existuje.\n\n"
    ::msgcat::mcset cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" ji\u017e existuje.\nChcete jej p\u0159epsat?"
    ::msgcat::mcset cs "File \"%1\$s\" does not exist." "Soubor \"%1\$s\" neexistuje."
    ::msgcat::mcset cs "File &name:" "&Jm\351no souboru:"
    ::msgcat::mcset cs "File &names:" "&Jm\351na soubor\u016f:"
    ::msgcat::mcset cs "Files of &type:" "&Typy soubor\u016f:"
    ::msgcat::mcset cs "Hi" "Ahoj"
    ::msgcat::mcset cs "Hide Console" "Skr\375t konsolu"
    ::msgcat::mcset cs "Invalid file name \"%1\$s\"." "\u0160patn\351 jm\351no souboru \"%1\$s\"."
    ::msgcat::mcset cs "Log Files" "Log soubory"
    ::msgcat::mcset cs "Ok"
    ::msgcat::mcset cs "Open" "Otev\u0159\355t"
    ::msgcat::mcset cs "Open Multiple Files" "Otev\u0159\355t v\355ce soubor\u016f"
    ::msgcat::mcset cs "P&aste" "&Vlo\u017eit"
    ::msgcat::mcset cs "Paste" "Vlo\u017eit"
    ::msgcat::mcset cs "Quit" "Skon\u010dit"
    ::msgcat::mcset cs "Replace existing file?" "Nahradit st\341vaj\355c\355 soubor?"
    ::msgcat::mcset cs "Save As" "Ulo\u017eit jako"
    ::msgcat::mcset cs "Save To Log" "Ulo\u017eit do logu"
    ::msgcat::mcset cs "Select Log File" "Vybrat log soubor"
    ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k nahr\341n\355"

    ::msgcat::mcset cs "Skip Messages" "P\u0159esko\u010dit zpr\341vy"
    ::msgcat::mcset cs "Source..." "Nahr\341t..."
    ::msgcat::mcset cs "Tcl Scripts" "Tcl skripty"
    ::msgcat::mcset cs "Tcl for Windows" "Tcl pro Windows"
    ::msgcat::mcset cs "Text Files" "Textov\351 soubory"
    ::msgcat::mcset cs "abort" "p\u0159eru\u0161it"
    ::msgcat::mcset cs "blue" "modr\341"
    ::msgcat::mcset cs "cancel" "zru\u0161it"
    ::msgcat::mcset cs "extension" "p\u0159\355pona"
    ::msgcat::mcset cs "extensions" "p\u0159\355pony"
    ::msgcat::mcset cs "green" "zelen\341"
    ::msgcat::mcset cs "ignore" "ignorovat"
    ::msgcat::mcset cs "ok"
    ::msgcat::mcset cs "red" "\u010derven\341"
    ::msgcat::mcset cs "retry" "znovu"
    ::msgcat::mcset cs "yes" "ano"
}

Changes to library/msgs/da.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace eval ::tk {
    ::msgcat::mcset da "&Abort" "&Afbryd"
    ::msgcat::mcset da "&About..." "&Om..."
    ::msgcat::mcset da "All Files" "Alle filer"
    ::msgcat::mcset da "Application Error" "Programfejl"
    ::msgcat::mcset da "&Blue" "&Blå"
    ::msgcat::mcset da "Cancel" "Annuller"
    ::msgcat::mcset da "&Cancel" "&Annuller"
    ::msgcat::mcset da "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ikke skifte til katalog \"%1\$s\".\nIngen rettigheder."
    ::msgcat::mcset da "Choose Directory" "Vælg katalog"
    ::msgcat::mcset da "Cl&ear" "&Ryd"
    ::msgcat::mcset da "&Clear Console" "&Ryd konsolen"
    ::msgcat::mcset da "Color" "Farve"
    ::msgcat::mcset da "Console" "Konsol"
    ::msgcat::mcset da "&Copy" "&Kopier"
    ::msgcat::mcset da "Cu&t" "Kli&p"
    ::msgcat::mcset da "&Delete" "&Slet"
    ::msgcat::mcset da "Details >>" "Detailer"





|
<


|
|







1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
namespace eval ::tk {
    ::msgcat::mcset da "&Abort" "&Afbryd"
    ::msgcat::mcset da "&About..." "&Om..."
    ::msgcat::mcset da "All Files" "Alle filer"
    ::msgcat::mcset da "Application Error" "Programfejl"
    ::msgcat::mcset da "&Blue" "&Bl\u00E5"

    ::msgcat::mcset da "&Cancel" "&Annuller"
    ::msgcat::mcset da "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ikke skifte til katalog \"%1\$s\".\nIngen rettigheder."
    ::msgcat::mcset da "Choose Directory" "V\u00E6lg katalog"
    ::msgcat::mcset da "&Clear" "&Ryd"
    ::msgcat::mcset da "&Clear Console" "&Ryd konsolen"
    ::msgcat::mcset da "Color" "Farve"
    ::msgcat::mcset da "Console" "Konsol"
    ::msgcat::mcset da "&Copy" "&Kopier"
    ::msgcat::mcset da "Cu&t" "Kli&p"
    ::msgcat::mcset da "&Delete" "&Slet"
    ::msgcat::mcset da "Details >>" "Detailer"
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    ::msgcat::mcset da "File \"%1\$s\" does not exist." "Filen \"%1\$s\" findes ikke."
    ::msgcat::mcset da "File &name:" "Fil&navn:"
    ::msgcat::mcset da "File &names:" "Fil&navne:"
    ::msgcat::mcset da "Files of &type:" "Fil&typer:"
    ::msgcat::mcset da "Fi&les:" "Fi&ler:"
    ::msgcat::mcset da "&Filter"
    ::msgcat::mcset da "Fil&ter:"
    ::msgcat::mcset da "&Green" "&Grøn"
    ::msgcat::mcset da "&Help" "&Hjælp"
    ::msgcat::mcset da "Hi" "Hej"
    ::msgcat::mcset da "&Hide Console" "Skjul &konsol"
    ::msgcat::mcset da "&Ignore" "&Ignorer"
    ::msgcat::mcset da "Invalid file name \"%1\$s\"." "Ugyldig fil navn \"%1\$s\"."
    ::msgcat::mcset da "Log Files" "Logfiler"
    ::msgcat::mcset da "&No" "&Nej"
    ::msgcat::mcset da "&OK" "&O.K."
    ::msgcat::mcset da "OK" "O.K."
    ::msgcat::mcset da "Ok"
    ::msgcat::mcset da "Open" "Åbn"
    ::msgcat::mcset da "&Open" "&Åbn"
    ::msgcat::mcset da "Open Multiple Files" "Åbn flere filer"
    ::msgcat::mcset da "P&aste" "&Indsæt"
    ::msgcat::mcset da "&Quit" "&Afslut"
    ::msgcat::mcset da "&Red" "&Rød"
    ::msgcat::mcset da "Replace existing file?" "Erstat eksisterende fil?"
    ::msgcat::mcset da "&Retry" "&Gentag"
    ::msgcat::mcset da "&Save" "&Gem"
    ::msgcat::mcset da "Save As" "Gem som"
    ::msgcat::mcset da "Save To Log" "Gem i log"
    ::msgcat::mcset da "Select Log File" "Vælg logfil"
    ::msgcat::mcset da "Select a file to source" "Vælg kørbar fil"
    ::msgcat::mcset da "&Selection:" "&Udvalg:"
    ::msgcat::mcset da "Show &Hidden Directories" "Vis &skjulte kataloger"
    ::msgcat::mcset da "Show &Hidden Files and Directories" "Vis &skjulte filer og kataloger"
    ::msgcat::mcset da "Skip Messages" "Overspring beskeder"
    ::msgcat::mcset da "&Source..." "&Kør..."
    ::msgcat::mcset da "Tcl Scripts" "Tcl-Skripter"
    ::msgcat::mcset da "Tcl for Windows" "Tcl for Windows"
    ::msgcat::mcset da "Text Files" "Tekstfiler"
    ::msgcat::mcset da "&Yes" "&Ja"
    ::msgcat::mcset da "abort" "afbryd"
    ::msgcat::mcset da "blue" "blå"
    ::msgcat::mcset da "cancel" "afbryd"
    ::msgcat::mcset da "extension"
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "grøn"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "rød"
    ::msgcat::mcset da "retry" "gentag"
    ::msgcat::mcset da "yes" "ja"
}







|
|






|
|

|
|
|
|

|





|
|




|





|



|


|



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    ::msgcat::mcset da "File \"%1\$s\" does not exist." "Filen \"%1\$s\" findes ikke."
    ::msgcat::mcset da "File &name:" "Fil&navn:"
    ::msgcat::mcset da "File &names:" "Fil&navne:"
    ::msgcat::mcset da "Files of &type:" "Fil&typer:"
    ::msgcat::mcset da "Fi&les:" "Fi&ler:"
    ::msgcat::mcset da "&Filter"
    ::msgcat::mcset da "Fil&ter:"
    ::msgcat::mcset da "&Green" "&Gr\u00F8n"
    ::msgcat::mcset da "&Help" "&Hj\u00E6lp"
    ::msgcat::mcset da "Hi" "Hej"
    ::msgcat::mcset da "&Hide Console" "Skjul &konsol"
    ::msgcat::mcset da "&Ignore" "&Ignorer"
    ::msgcat::mcset da "Invalid file name \"%1\$s\"." "Ugyldig fil navn \"%1\$s\"."
    ::msgcat::mcset da "Log Files" "Logfiler"
    ::msgcat::mcset da "&No" "&Nej"
    ::msgcat::mcset da "OK" "O.K."
    ::msgcat::mcset da "&OK" "&O.K."
    ::msgcat::mcset da "Ok"
    ::msgcat::mcset da "Open" "\u00C5bn"
    ::msgcat::mcset da "&Open" "&\u00C5bn"
    ::msgcat::mcset da "Open Multiple Files" "\u00C5bn flere filer"
    ::msgcat::mcset da "P&aste" "&Inds\u00E6t"
    ::msgcat::mcset da "&Quit" "&Afslut"
    ::msgcat::mcset da "&Red" "&R\u00F8d"
    ::msgcat::mcset da "Replace existing file?" "Erstat eksisterende fil?"
    ::msgcat::mcset da "&Retry" "&Gentag"
    ::msgcat::mcset da "&Save" "&Gem"
    ::msgcat::mcset da "Save As" "Gem som"
    ::msgcat::mcset da "Save To Log" "Gem i log"
    ::msgcat::mcset da "Select Log File" "V\u00E6lg logfil"
    ::msgcat::mcset da "Select a file to source" "V\u00E6lg k\u00F8rbar fil"
    ::msgcat::mcset da "&Selection:" "&Udvalg:"
    ::msgcat::mcset da "Show &Hidden Directories" "Vis &skjulte kataloger"
    ::msgcat::mcset da "Show &Hidden Files and Directories" "Vis &skjulte filer og kataloger"
    ::msgcat::mcset da "Skip Messages" "Overspring beskeder"
    ::msgcat::mcset da "&Source..." "&K\u00F8r..."
    ::msgcat::mcset da "Tcl Scripts" "Tcl-Skripter"
    ::msgcat::mcset da "Tcl for Windows" "Tcl for Windows"
    ::msgcat::mcset da "Text Files" "Tekstfiler"
    ::msgcat::mcset da "&Yes" "&Ja"
    ::msgcat::mcset da "abort" "afbryd"
    ::msgcat::mcset da "blue" "bl\u00E5"
    ::msgcat::mcset da "cancel" "afbryd"
    ::msgcat::mcset da "extension"
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "gr\u00F8n"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "r\u00F8d"
    ::msgcat::mcset da "retry" "gentag"
    ::msgcat::mcset da "yes" "ja"
}

Changes to library/msgs/de.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
namespace eval ::tk {
    ::msgcat::mcset de "&Abort" "&Abbruch"
    ::msgcat::mcset de "&About..." "&Über..."
    ::msgcat::mcset de "All Files" "Alle Dateien"
    ::msgcat::mcset de "Application Error" "Applikationsfehler"
    ::msgcat::mcset de "&Apply" "&Anwenden"
    ::msgcat::mcset de "Bold" "Fett"
    ::msgcat::mcset de "Bold Italic" "Fett kursiv"
    ::msgcat::mcset de "&Blue" "&Blau"
    ::msgcat::mcset de "Cancel" "Abbruch"
    ::msgcat::mcset de "&Cancel" "&Abbruch"
    ::msgcat::mcset de "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden."
    ::msgcat::mcset de "Choose Directory" "Wähle Verzeichnis"
    ::msgcat::mcset de "Cl&ear" "&Rücksetzen"
    ::msgcat::mcset de "&Clear Console" "&Konsole löschen"
    ::msgcat::mcset de "Color" "Farbe"
    ::msgcat::mcset de "Console" "Konsole"
    ::msgcat::mcset de "&Copy" "&Kopieren"
    ::msgcat::mcset de "Cu&t" "Aus&schneiden"
    ::msgcat::mcset de "&Delete" "&Löschen"
    ::msgcat::mcset de "Details >>"
    ::msgcat::mcset de "Directory \"%1\$s\" does not exist." "Das Verzeichnis \"%1\$s\" existiert nicht."
    ::msgcat::mcset de "&Directory:" "&Verzeichnis:"
    ::msgcat::mcset de "&Edit" "&Bearbeiten"
    ::msgcat::mcset de "Effects" "Effekte"
    ::msgcat::mcset de "Error: %1\$s" "Fehler: %1\$s"
    ::msgcat::mcset de "E&xit" "&Ende"
    ::msgcat::mcset de "&File" "&Datei"
    ::msgcat::mcset de "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei überschreiben ?"
    ::msgcat::mcset de "File \"%1\$s\" already exists.\n\n" "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n"
    ::msgcat::mcset de "File \"%1\$s\" does not exist." "Die Datei \"%1\$s\" existiert nicht."
    ::msgcat::mcset de "File &name:" "Datei&name:"
    ::msgcat::mcset de "File &names:" "Datei&namen:"
    ::msgcat::mcset de "Files of &type:" "Dateien des &Typs:"
    ::msgcat::mcset de "Fi&les:" "Dat&eien:"
    ::msgcat::mcset de "&Filter"
    ::msgcat::mcset de "Fil&ter:"
    ::msgcat::mcset de "Font" "Schriftart"
    ::msgcat::mcset de "&Font:" "Schriftart:"
    ::msgcat::mcset de "Font st&yle:" "Schriftschnitt:"
    ::msgcat::mcset de "&Green" "&Grün"
    ::msgcat::mcset de "&Help" "&Hilfe"
    ::msgcat::mcset de "Hi" "Hallo"
    ::msgcat::mcset de "&Hide Console" "&Konsole unsichtbar machen"
    ::msgcat::mcset de "&Ignore" "&Ignorieren"
    ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ungültiger Dateiname \"%1\$s\"."
    ::msgcat::mcset de "Italic" "Kursiv"
    ::msgcat::mcset de "Log Files" "Protokolldatei"
    ::msgcat::mcset de "&No" "&Nein"
    ::msgcat::mcset de "&OK"
    ::msgcat::mcset de "OK"
    ::msgcat::mcset de "Ok"
    ::msgcat::mcset de "Open" "Öffnen"
    ::msgcat::mcset de "&Open" "Ö&ffnen"
    ::msgcat::mcset de "Open Multiple Files" "Mehrere Dateien Öffnen"
    ::msgcat::mcset de "P&aste" "E&infügen"
    ::msgcat::mcset de "&Quit" "&Beenden"
    ::msgcat::mcset de "&Red" "&Rot"
    ::msgcat::mcset de "Regular" "Standard"
    ::msgcat::mcset de "Replace existing file?" "Existierende Datei ersetzen?"
    ::msgcat::mcset de "&Retry" "&Wiederholen"
    ::msgcat::mcset de "Sample" "Beispiel"
    ::msgcat::mcset de "&Save" "&Speichern"
    ::msgcat::mcset de "Save As" "Speichern unter"
    ::msgcat::mcset de "Save To Log" "In Protokoll speichern"
    ::msgcat::mcset de "Select Log File" "Protokolldatei auswählen"
    ::msgcat::mcset de "Select a file to source" "Auszuführende Datei auswählen"
    ::msgcat::mcset de "&Selection:" "Auswah&l:"
    ::msgcat::mcset de "&Size:" "Schriftgrad:"
    ::msgcat::mcset de "Show &Hidden Directories" "Zeige versteckte Dateien"
    ::msgcat::mcset de "Show &Hidden Files and Directories" "Zeige versteckte Dateien und Verzeichnisse"
    ::msgcat::mcset de "Skip Messages" "Weitere Nachrichten überspringen"
    ::msgcat::mcset de "&Source..." "&Ausführen..."
    ::msgcat::mcset de "Stri&keout" "&Durchgestrichen"
    ::msgcat::mcset de "Tcl Scripts" "Tcl-Skripte"
    ::msgcat::mcset de "Tcl for Windows" "Tcl für Windows"
    ::msgcat::mcset de "Text Files" "Textdateien"
    ::msgcat::mcset de "&Underline" "&Unterstrichen"
    ::msgcat::mcset de "&Yes" "&Ja"
    ::msgcat::mcset de "abort" "abbrechen"
    ::msgcat::mcset de "blue" "blau"
    ::msgcat::mcset de "cancel" "abbrechen"
    ::msgcat::mcset de "extension" "Erweiterung"
    ::msgcat::mcset de "extensions" "Erweiterungen"
    ::msgcat::mcset de "green" "grün"
    ::msgcat::mcset de "ignore" "ignorieren"
    ::msgcat::mcset de "ok"
    ::msgcat::mcset de "red" "rot"
    ::msgcat::mcset de "retry" "wiederholen"
    ::msgcat::mcset de "yes" "ja"
}


|


<
<
<

<


|
|
|




|




<



|








<
<
<
|




|
<



<

|
|
|
|


<


<



|
|

<


|
|
<

|

<






|






1
2
3
4
5



6

7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32



33
34
35
36
37
38

39
40
41

42
43
44
45
46
47
48

49
50

51
52
53
54
55
56

57
58
59
60

61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
namespace eval ::tk {
    ::msgcat::mcset de "&Abort" "&Abbruch"
    ::msgcat::mcset de "&About..." "&\u00dcber..."
    ::msgcat::mcset de "All Files" "Alle Dateien"
    ::msgcat::mcset de "Application Error" "Applikationsfehler"



    ::msgcat::mcset de "&Blue" "&Blau"

    ::msgcat::mcset de "&Cancel" "&Abbruch"
    ::msgcat::mcset de "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden."
    ::msgcat::mcset de "Choose Directory" "W\u00e4hle Verzeichnis"
    ::msgcat::mcset de "Cl&ear" "&R\u00fccksetzen"
    ::msgcat::mcset de "&Clear Console" "&Konsole l\u00f6schen"
    ::msgcat::mcset de "Color" "Farbe"
    ::msgcat::mcset de "Console" "Konsole"
    ::msgcat::mcset de "&Copy" "&Kopieren"
    ::msgcat::mcset de "Cu&t" "Aus&schneiden"
    ::msgcat::mcset de "&Delete" "&L\u00f6schen"
    ::msgcat::mcset de "Details >>"
    ::msgcat::mcset de "Directory \"%1\$s\" does not exist." "Das Verzeichnis \"%1\$s\" existiert nicht."
    ::msgcat::mcset de "&Directory:" "&Verzeichnis:"
    ::msgcat::mcset de "&Edit" "&Bearbeiten"

    ::msgcat::mcset de "Error: %1\$s" "Fehler: %1\$s"
    ::msgcat::mcset de "E&xit" "&Ende"
    ::msgcat::mcset de "&File" "&Datei"
    ::msgcat::mcset de "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei \u00fcberschreiben ?"
    ::msgcat::mcset de "File \"%1\$s\" already exists.\n\n" "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n"
    ::msgcat::mcset de "File \"%1\$s\" does not exist." "Die Datei \"%1\$s\" existiert nicht."
    ::msgcat::mcset de "File &name:" "Datei&name:"
    ::msgcat::mcset de "File &names:" "Datei&namen:"
    ::msgcat::mcset de "Files of &type:" "Dateien des &Typs:"
    ::msgcat::mcset de "Fi&les:" "Dat&eien:"
    ::msgcat::mcset de "&Filter"
    ::msgcat::mcset de "Fil&ter:"



    ::msgcat::mcset de "&Green" "&Gr\u00fcn"
    ::msgcat::mcset de "&Help" "&Hilfe"
    ::msgcat::mcset de "Hi" "Hallo"
    ::msgcat::mcset de "&Hide Console" "&Konsole unsichtbar machen"
    ::msgcat::mcset de "&Ignore" "&Ignorieren"
    ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ung\u00fcltiger Dateiname \"%1\$s\"."

    ::msgcat::mcset de "Log Files" "Protokolldatei"
    ::msgcat::mcset de "&No" "&Nein"
    ::msgcat::mcset de "&OK"

    ::msgcat::mcset de "Ok"
    ::msgcat::mcset de "Open" "\u00d6ffnen"
    ::msgcat::mcset de "&Open" "\u00d6&ffnen"
    ::msgcat::mcset de "Open Multiple Files" "Mehrere Dateien \u00F6ffnen"
    ::msgcat::mcset de "P&aste" "E&inf\u00fcgen"
    ::msgcat::mcset de "&Quit" "&Beenden"
    ::msgcat::mcset de "&Red" "&Rot"

    ::msgcat::mcset de "Replace existing file?" "Existierende Datei ersetzen?"
    ::msgcat::mcset de "&Retry" "&Wiederholen"

    ::msgcat::mcset de "&Save" "&Speichern"
    ::msgcat::mcset de "Save As" "Speichern unter"
    ::msgcat::mcset de "Save To Log" "In Protokoll speichern"
    ::msgcat::mcset de "Select Log File" "Protokolldatei ausw\u00e4hlen"
    ::msgcat::mcset de "Select a file to source" "Auszuf\u00fchrende Datei ausw\u00e4hlen"
    ::msgcat::mcset de "&Selection:" "Auswah&l:"

    ::msgcat::mcset de "Show &Hidden Directories" "Zeige versteckte Dateien"
    ::msgcat::mcset de "Show &Hidden Files and Directories" "Zeige versteckte Dateien und Verzeichnisse"
    ::msgcat::mcset de "Skip Messages" "Weitere Nachrichten \u00fcberspringen"
    ::msgcat::mcset de "&Source..." "&Ausf\u00fchren..."

    ::msgcat::mcset de "Tcl Scripts" "Tcl-Skripte"
    ::msgcat::mcset de "Tcl for Windows" "Tcl f\u00fcr Windows"
    ::msgcat::mcset de "Text Files" "Textdateien"

    ::msgcat::mcset de "&Yes" "&Ja"
    ::msgcat::mcset de "abort" "abbrechen"
    ::msgcat::mcset de "blue" "blau"
    ::msgcat::mcset de "cancel" "abbrechen"
    ::msgcat::mcset de "extension" "Erweiterung"
    ::msgcat::mcset de "extensions" "Erweiterungen"
    ::msgcat::mcset de "green" "gr\u00fcn"
    ::msgcat::mcset de "ignore" "ignorieren"
    ::msgcat::mcset de "ok"
    ::msgcat::mcset de "red" "rot"
    ::msgcat::mcset de "retry" "wiederholen"
    ::msgcat::mcset de "yes" "ja"
}

Changes to library/msgs/el.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

## Messages for the Greek (Hellenic - "el") language.
## Please report any changes/suggestions to:
##    petasis@iit.demokritos.gr

namespace eval ::tk {
    ::msgcat::mcset el "&Abort"              "Τερματισμός"
    ::msgcat::mcset el "About..."           "Σχετικά..."
    ::msgcat::mcset el "All Files"          "Όλα τα Αρχεία"
    ::msgcat::mcset el "Application Error"  "Λάθος Εφαρμογής"
    ::msgcat::mcset el "&Blue"               "Μπλε"
    ::msgcat::mcset el "&Cancel"             "Ακύρωση"
    ::msgcat::mcset el \
"Cannot change to the directory \"%1\$s\".\nPermission denied." \
"Δεν είναι δυνατή η αλλαγή καταλόγου σε \"%1\$s\".\nΗ πρόσβαση δεν επιτρέπεται."
    ::msgcat::mcset el "Choose Directory"   "Επιλογή Καταλόγου"
    ::msgcat::mcset el "Clear"              "Καθαρισμός"
    ::msgcat::mcset el "Color"              "Χρώμα"
    ::msgcat::mcset el "Console"            "Κονσόλα"
    ::msgcat::mcset el "Copy"               "Αντιγραφή"
    ::msgcat::mcset el "Cut"                "Αποκοπή"
    ::msgcat::mcset el "Delete"             "Διαγραφή"
    ::msgcat::mcset el "Details >>"         "Λεπτομέρειες >>"
    ::msgcat::mcset el "Directory \"%1\$s\" does not exist." \
                                        "Ο κατάλογος \"%1\$s\" δεν υπάρχει."
    ::msgcat::mcset el "&Directory:"         "&Κατάλογος:"
    ::msgcat::mcset el "Error: %1\$s"       "Λάθος: %1\$s"
    ::msgcat::mcset el "Exit"               "Έξοδος"
    ::msgcat::mcset el \
               "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
               "Το αρχείο \"%1\$s\" ήδη υπάρχει.\nΘέλετε να επικαλυφθεί;"
    ::msgcat::mcset el "File \"%1\$s\" already exists.\n\n" \
                   "Το αρχείο \"%1\$s\" ήδη υπάρχει.\n\n"
    ::msgcat::mcset el "File \"%1\$s\" does not exist." \
                   "Το αρχείο \"%1\$s\" δεν υπάρχει."
    ::msgcat::mcset el "File &name:"         "Ό&νομα αρχείου:"
    ::msgcat::mcset el "File &names:"        "Ό&νομα αρχείων:"
    ::msgcat::mcset el "Files of &type:"     "Αρχεία του &τύπου:"
    ::msgcat::mcset el "Fi&les:"             "Αρχεία:"
    ::msgcat::mcset el "&Filter"             "Φίλτρο"
    ::msgcat::mcset el "Fil&ter:"            "Φίλτρο:"
    ::msgcat::mcset el "&Green"              "Πράσινο"
    ::msgcat::mcset el "Hi"                 "Γεια"
    ::msgcat::mcset el "Hide Console"       "Απόκρυψη κονσόλας"
    ::msgcat::mcset el "&Ignore"             "Αγνόηση"
    ::msgcat::mcset el "Invalid file name \"%1\$s\"." \
                   "Άκυρο όνομα αρχείου \"%1\$s\"."
    ::msgcat::mcset el "Log Files"          "Αρχεία Καταγραφής"
    ::msgcat::mcset el "&No"                 "Όχι"
    ::msgcat::mcset el "&OK"                 "Εντάξει"
    ::msgcat::mcset el "OK"                 "Εντάξει"
    ::msgcat::mcset el "Ok"                 "Εντάξει"
    ::msgcat::mcset el "Open"               "Άνοιγμα"
    ::msgcat::mcset el "&Open"               "Άνοιγμα"
    ::msgcat::mcset el "Open Multiple Files" \
                                        "Άνοιγμα πολλαπλών αρχείων"

    ::msgcat::mcset el "P&aste"              "Επικόλληση"
    ::msgcat::mcset el "Quit"               "Έξοδος"
    ::msgcat::mcset el "&Red"                "Κόκκινο"
    ::msgcat::mcset el "Replace existing file?" \
                                        "Επικάλυψη υπάρχοντος αρχείου;"

    ::msgcat::mcset el "&Retry"              "Προσπάθησε ξανά"
    ::msgcat::mcset el "&Save"               "Αποθήκευση"
    ::msgcat::mcset el "Save As"            "Αποθήκευση σαν"
    ::msgcat::mcset el "Save To Log"        "Αποθήκευση στο αρχείο καταγραφής"
    ::msgcat::mcset el "Select Log File"    "Επιλογή αρχείου καταγραφής"
    ::msgcat::mcset el "Select a file to source" \
                                        "Επιλέξτε αρχείο για εκτέλεση"
    ::msgcat::mcset el "&Selection:"         "Επιλογή:"
    ::msgcat::mcset el "Skip Messages"      "Αποφυγήμηνυμάτων"
    ::msgcat::mcset el "&Source..."          "Εκτέλεση..."
    ::msgcat::mcset el "Tcl Scripts"        "Tcl Scripts"
    ::msgcat::mcset el "Tcl for Windows"    "Tcl για Windows"
    ::msgcat::mcset el "Text Files"         "Αρχεία Κειμένου"
    ::msgcat::mcset el "&Yes"                "Ναι"
    ::msgcat::mcset el "abort"              "τερματισμός"
    ::msgcat::mcset el "blue"               "μπλε"
    ::msgcat::mcset el "cancel"             "ακύρωση"
    ::msgcat::mcset el "extension"          "επέκταση"
    ::msgcat::mcset el "extensions"         "επεκτάσεις"
    ::msgcat::mcset el "green"              "πράσινο"
    ::msgcat::mcset el "ignore"             "αγνόηση"
    ::msgcat::mcset el "ok"                 "εντάξει"
    ::msgcat::mcset el "red"                "κόκκινο"
    ::msgcat::mcset el "retry"              "προσπάθησε ξανά"
    ::msgcat::mcset el "yes"                "ναι"
}






|
|
|
|
|
|


|
|
|
|
|
|
|
|
|

|
|
|
|


|

|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
<
|
|
|

<
>
|
|
|

<
>
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53

54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
## Messages for the Greek (Hellenic - "el") language.
## Please report any changes/suggestions to:
##    petasis@iit.demokritos.gr

namespace eval ::tk {
    ::msgcat::mcset el "&Abort"              "\u03a4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2"
    ::msgcat::mcset el "About..."           "\u03a3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac..."
    ::msgcat::mcset el "All Files"          "\u038c\u03bb\u03b1 \u03c4\u03b1 \u0391\u03c1\u03c7\u03b5\u03af\u03b1"
    ::msgcat::mcset el "Application Error"  "\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2"
    ::msgcat::mcset el "&Blue"               "\u039c\u03c0\u03bb\u03b5"
    ::msgcat::mcset el "&Cancel"             "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7"
    ::msgcat::mcset el \
"Cannot change to the directory \"%1\$s\".\nPermission denied." \
"\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03ba\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5 \u03c3\u03b5 \"%1\$s\".\n\u0397 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03c4\u03b1\u03b9."
    ::msgcat::mcset el "Choose Directory"   "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u039a\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5"
    ::msgcat::mcset el "Clear"              "\u039a\u03b1\u03b8\u03b1\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2"
    ::msgcat::mcset el "Color"              "\u03a7\u03c1\u03ce\u03bc\u03b1"
    ::msgcat::mcset el "Console"            "\u039a\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1"
    ::msgcat::mcset el "Copy"               "\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae"
    ::msgcat::mcset el "Cut"                "\u0391\u03c0\u03bf\u03ba\u03bf\u03c0\u03ae"
    ::msgcat::mcset el "Delete"             "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae"
    ::msgcat::mcset el "Details >>"         "\u039b\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 >>"
    ::msgcat::mcset el "Directory \"%1\$s\" does not exist." \
                                        "\u039f \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9."
    ::msgcat::mcset el "&Directory:"         "&\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2:"
    ::msgcat::mcset el "Error: %1\$s"       "\u039b\u03ac\u03b8\u03bf\u03c2: %1\$s"
    ::msgcat::mcset el "Exit"               "\u0388\u03be\u03bf\u03b4\u03bf\u03c2"
    ::msgcat::mcset el \
               "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
               "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03ba\u03b1\u03bb\u03c5\u03c6\u03b8\u03b5\u03af;"
    ::msgcat::mcset el "File \"%1\$s\" already exists.\n\n" \
                   "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\n"
    ::msgcat::mcset el "File \"%1\$s\" does not exist." \
                   "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9."
    ::msgcat::mcset el "File &name:"         "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5:"
    ::msgcat::mcset el "File &names:"        "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd:"
    ::msgcat::mcset el "Files of &type:"     "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03c4\u03bf\u03c5 &\u03c4\u03cd\u03c0\u03bf\u03c5:"
    ::msgcat::mcset el "Fi&les:"             "\u0391\u03c1\u03c7\u03b5\u03af\u03b1:"
    ::msgcat::mcset el "&Filter"             "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf"
    ::msgcat::mcset el "Fil&ter:"            "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf:"
    ::msgcat::mcset el "&Green"              "\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf"
    ::msgcat::mcset el "Hi"                 "\u0393\u03b5\u03b9\u03b1"
    ::msgcat::mcset el "Hide Console"       "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03ba\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1\u03c2"
    ::msgcat::mcset el "&Ignore"             "\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7"
    ::msgcat::mcset el "Invalid file name \"%1\$s\"." \
                   "\u0386\u03ba\u03c5\u03c1\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \"%1\$s\"."
    ::msgcat::mcset el "Log Files"          "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2"
    ::msgcat::mcset el "&No"                 "\u038c\u03c7\u03b9"
    ::msgcat::mcset el "&OK"                 "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9"

    ::msgcat::mcset el "&Ok"                 "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9"
    ::msgcat::mcset el "Open"               "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1"
    ::msgcat::mcset el "&Open"               "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1"
    ::msgcat::mcset el "Open Multiple Files" \

                                        "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bf\u03bb\u03bb\u03b1\u03c0\u03bb\u03ce\u03bd \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd"
    ::msgcat::mcset el "Paste"              "\u0395\u03c0\u03b9\u03ba\u03cc\u03bb\u03bb\u03b7\u03c3\u03b7"
    ::msgcat::mcset el "Quit"               "\u0388\u03be\u03bf\u03b4\u03bf\u03c2"
    ::msgcat::mcset el "&Red"                "\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf"
    ::msgcat::mcset el "Replace existing file?" \

                                        "\u0395\u03c0\u03b9\u03ba\u03ac\u03bb\u03c5\u03c8\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03bd\u03c4\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5;"
    ::msgcat::mcset el "&Retry"              "\u03a0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac"
    ::msgcat::mcset el "&Save"               "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7"
    ::msgcat::mcset el "Save As"            "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03b1\u03bd"
    ::msgcat::mcset el "Save To Log"        "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2"
    ::msgcat::mcset el "Select Log File"    "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2"
    ::msgcat::mcset el "Select a file to source" \
                                        "\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b3\u03b9\u03b1 \u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7"
    ::msgcat::mcset el "&Selection:"         "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae:"
    ::msgcat::mcset el "Skip Messages"      "\u0391\u03c0\u03bf\u03c6\u03c5\u03b3\u03ae\u03bc\u03b7\u03bd\u03c5\u03bc\u03ac\u03c4\u03c9\u03bd"
    ::msgcat::mcset el "Source..."          "\u0395\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7..."
    ::msgcat::mcset el "Tcl Scripts"        "Tcl Scripts"
    ::msgcat::mcset el "Tcl for Windows"    "Tcl \u03b3\u03b9\u03b1 Windows"
    ::msgcat::mcset el "Text Files"         "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5"
    ::msgcat::mcset el "&Yes"                "\u039d\u03b1\u03b9"
    ::msgcat::mcset el "abort"              "\u03c4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2"
    ::msgcat::mcset el "blue"               "\u03bc\u03c0\u03bb\u03b5"
    ::msgcat::mcset el "cancel"             "\u03b1\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7"
    ::msgcat::mcset el "extension"          "\u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7"
    ::msgcat::mcset el "extensions"         "\u03b5\u03c0\u03b5\u03ba\u03c4\u03ac\u03c3\u03b5\u03b9\u03c2"
    ::msgcat::mcset el "green"              "\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf"
    ::msgcat::mcset el "ignore"             "\u03b1\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7"
    ::msgcat::mcset el "ok"                 "\u03b5\u03bd\u03c4\u03ac\u03be\u03b5\u03b9"
    ::msgcat::mcset el "red"                "\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf"
    ::msgcat::mcset el "retry"              "\u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac"
    ::msgcat::mcset el "yes"                "\u03bd\u03b1\u03b9"
}

Changes to library/msgs/en.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
namespace eval ::tk {
    ::msgcat::mcset en "&Abort"
    ::msgcat::mcset en "&About..."
    ::msgcat::mcset en "All Files"
    ::msgcat::mcset en "Application Error"
    ::msgcat::mcset en "&Apply"
    ::msgcat::mcset en "Bold"
    ::msgcat::mcset en "Bold Italic"
    ::msgcat::mcset en "&Blue"
    ::msgcat::mcset en "Cancel"
    ::msgcat::mcset en "&Cancel"
    ::msgcat::mcset en "Cannot change to the directory \"%1\$s\".\nPermission denied."
    ::msgcat::mcset en "Choose Directory"
    ::msgcat::mcset en "Cl&ear"
    ::msgcat::mcset en "&Clear Console"
    ::msgcat::mcset en "Color"
    ::msgcat::mcset en "Console"
    ::msgcat::mcset en "&Copy"
    ::msgcat::mcset en "Cu&t"
    ::msgcat::mcset en "&Delete"
    ::msgcat::mcset en "Details >>"
    ::msgcat::mcset en "Directory \"%1\$s\" does not exist."
    ::msgcat::mcset en "&Directory:"
    ::msgcat::mcset en "&Edit"
    ::msgcat::mcset en "Effects"
    ::msgcat::mcset en "Error: %1\$s"
    ::msgcat::mcset en "E&xit"
    ::msgcat::mcset en "&File"
    ::msgcat::mcset en "File \"%1\$s\" already exists.\nDo you want to overwrite it?"
    ::msgcat::mcset en "File \"%1\$s\" already exists.\n\n"
    ::msgcat::mcset en "File \"%1\$s\" does not exist."
    ::msgcat::mcset en "File &name:"
    ::msgcat::mcset en "File &names:"
    ::msgcat::mcset en "Files of &type:"
    ::msgcat::mcset en "Fi&les:"
    ::msgcat::mcset en "&Filter"
    ::msgcat::mcset en "Fil&ter:"
    ::msgcat::mcset en "Font"
    ::msgcat::mcset en "&Font:"
    ::msgcat::mcset en "Font st&yle:"
    ::msgcat::mcset en "&Green"
    ::msgcat::mcset en "&Help"
    ::msgcat::mcset en "Hi"
    ::msgcat::mcset en "&Hide Console"
    ::msgcat::mcset en "&Ignore"
    ::msgcat::mcset en "Invalid file name \"%1\$s\"."
    ::msgcat::mcset en "Italic"
    ::msgcat::mcset en "Log Files"
    ::msgcat::mcset en "&No"
    ::msgcat::mcset en "&OK"
    ::msgcat::mcset en "OK"
    ::msgcat::mcset en "Ok"
    ::msgcat::mcset en "Open"
    ::msgcat::mcset en "&Open"
    ::msgcat::mcset en "Open Multiple Files"
    ::msgcat::mcset en "P&aste"
    ::msgcat::mcset en "&Quit"
    ::msgcat::mcset en "&Red"
    ::msgcat::mcset en "Regular"
    ::msgcat::mcset en "Replace existing file?"
    ::msgcat::mcset en "&Retry"
    ::msgcat::mcset en "Sample"
    ::msgcat::mcset en "&Save"
    ::msgcat::mcset en "Save As"
    ::msgcat::mcset en "Save To Log"
    ::msgcat::mcset en "Select Log File"
    ::msgcat::mcset en "Select a file to source"
    ::msgcat::mcset en "&Selection:"
    ::msgcat::mcset en "&Size:"
    ::msgcat::mcset en "Show &Hidden Directories"
    ::msgcat::mcset en "Show &Hidden Files and Directories"
    ::msgcat::mcset en "Skip Messages"
    ::msgcat::mcset en "&Source..."
    ::msgcat::mcset en "Stri&keout"
    ::msgcat::mcset en "Tcl Scripts"
    ::msgcat::mcset en "Tcl for Windows"
    ::msgcat::mcset en "Text Files"
    ::msgcat::mcset en "&Underline"
    ::msgcat::mcset en "&Yes"
    ::msgcat::mcset en "abort"
    ::msgcat::mcset en "blue"
    ::msgcat::mcset en "cancel"
    ::msgcat::mcset en "extension"
    ::msgcat::mcset en "extensions"
    ::msgcat::mcset en "green"
    ::msgcat::mcset en "ignore"
    ::msgcat::mcset en "ok"
    ::msgcat::mcset en "red"
    ::msgcat::mcset en "retry"
    ::msgcat::mcset en "yes"
}





<
<
<

<














<












<
<
<






<



<







<


<






<




<



<













1
2
3
4
5



6

7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32



33
34
35
36
37
38

39
40
41

42
43
44
45
46
47
48

49
50

51
52
53
54
55
56

57
58
59
60

61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
namespace eval ::tk {
    ::msgcat::mcset en "&Abort"
    ::msgcat::mcset en "&About..."
    ::msgcat::mcset en "All Files"
    ::msgcat::mcset en "Application Error"



    ::msgcat::mcset en "&Blue"

    ::msgcat::mcset en "&Cancel"
    ::msgcat::mcset en "Cannot change to the directory \"%1\$s\".\nPermission denied."
    ::msgcat::mcset en "Choose Directory"
    ::msgcat::mcset en "Cl&ear"
    ::msgcat::mcset en "&Clear Console"
    ::msgcat::mcset en "Color"
    ::msgcat::mcset en "Console"
    ::msgcat::mcset en "&Copy"
    ::msgcat::mcset en "Cu&t"
    ::msgcat::mcset en "&Delete"
    ::msgcat::mcset en "Details >>"
    ::msgcat::mcset en "Directory \"%1\$s\" does not exist."
    ::msgcat::mcset en "&Directory:"
    ::msgcat::mcset en "&Edit"

    ::msgcat::mcset en "Error: %1\$s"
    ::msgcat::mcset en "E&xit"
    ::msgcat::mcset en "&File"
    ::msgcat::mcset en "File \"%1\$s\" already exists.\nDo you want to overwrite it?"
    ::msgcat::mcset en "File \"%1\$s\" already exists.\n\n"
    ::msgcat::mcset en "File \"%1\$s\" does not exist."
    ::msgcat::mcset en "File &name:"
    ::msgcat::mcset en "File &names:"
    ::msgcat::mcset en "Files of &type:"
    ::msgcat::mcset en "Fi&les:"
    ::msgcat::mcset en "&Filter"
    ::msgcat::mcset en "Fil&ter:"



    ::msgcat::mcset en "&Green"
    ::msgcat::mcset en "&Help"
    ::msgcat::mcset en "Hi"
    ::msgcat::mcset en "&Hide Console"
    ::msgcat::mcset en "&Ignore"
    ::msgcat::mcset en "Invalid file name \"%1\$s\"."

    ::msgcat::mcset en "Log Files"
    ::msgcat::mcset en "&No"
    ::msgcat::mcset en "&OK"

    ::msgcat::mcset en "Ok"
    ::msgcat::mcset en "Open"
    ::msgcat::mcset en "&Open"
    ::msgcat::mcset en "Open Multiple Files"
    ::msgcat::mcset en "P&aste"
    ::msgcat::mcset en "&Quit"
    ::msgcat::mcset en "&Red"

    ::msgcat::mcset en "Replace existing file?"
    ::msgcat::mcset en "&Retry"

    ::msgcat::mcset en "&Save"
    ::msgcat::mcset en "Save As"
    ::msgcat::mcset en "Save To Log"
    ::msgcat::mcset en "Select Log File"
    ::msgcat::mcset en "Select a file to source"
    ::msgcat::mcset en "&Selection:"

    ::msgcat::mcset en "Show &Hidden Directories"
    ::msgcat::mcset en "Show &Hidden Files and Directories"
    ::msgcat::mcset en "Skip Messages"
    ::msgcat::mcset en "&Source..."

    ::msgcat::mcset en "Tcl Scripts"
    ::msgcat::mcset en "Tcl for Windows"
    ::msgcat::mcset en "Text Files"

    ::msgcat::mcset en "&Yes"
    ::msgcat::mcset en "abort"
    ::msgcat::mcset en "blue"
    ::msgcat::mcset en "cancel"
    ::msgcat::mcset en "extension"
    ::msgcat::mcset en "extensions"
    ::msgcat::mcset en "green"
    ::msgcat::mcset en "ignore"
    ::msgcat::mcset en "ok"
    ::msgcat::mcset en "red"
    ::msgcat::mcset en "retry"
    ::msgcat::mcset en "yes"
}

Changes to library/msgs/eo.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
namespace eval ::tk {
    ::msgcat::mcset eo "&Abort" "&Ĉesigo"
    ::msgcat::mcset eo "&About..." "Pri..."
    ::msgcat::mcset eo "All Files" "Ĉioj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoerraro"
    ::msgcat::mcset eo "&Blue" "&Blua"
    ::msgcat::mcset eo "Cancel" "Rezignu"
    ::msgcat::mcset eo "&Cancel" "&Rezignu"
    ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble ĉangi al dosierulon \"%1\$s\".\nVi ne rajtas tion."
    ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujo"
    ::msgcat::mcset eo "Cl&ear" "&Klaru"
    ::msgcat::mcset eo "&Clear Console" "&Klaru konzolon"
    ::msgcat::mcset eo "Color" "Farbo"
    ::msgcat::mcset eo "Console" "Konzolo"
    ::msgcat::mcset eo "&Copy" "&Kopiu"
    ::msgcat::mcset eo "Cu&t" "&Enpoŝigu"
    ::msgcat::mcset eo "&Delete" "&Forprenu"
    ::msgcat::mcset eo "Details >>" "Detaloj >>"
    ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas."
    ::msgcat::mcset eo "&Directory:" "&Dosierujo:"
    ::msgcat::mcset eo "&Edit" "&Redaktu"
    ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s"
    ::msgcat::mcset eo "E&xit" "&Eliru"
    ::msgcat::mcset eo "&File" "&Dosiero"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\nĈu vi volas anstataûigi la dosieron?"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam egzistas. \n\n"
    ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosierp \"%1\$s\" ne estas."
    ::msgcat::mcset eo "File &name:" "Dosiero&nomo:"
    ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:"
    ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Typo:"
    ::msgcat::mcset eo "Fi&les:" "Do&sieroj:"
    ::msgcat::mcset eo "&Filter" "&Filtrilo"
    ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:"
    ::msgcat::mcset eo "&Green" "&Verda"
    ::msgcat::mcset eo "&Help" "&Helpu"
    ::msgcat::mcset eo "Hi" "Saluton"
    ::msgcat::mcset eo "&Hide Console" "&Kaŝu konzolon"
    ::msgcat::mcset eo "&Ignore" "&Ignoru"
    ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"."
    ::msgcat::mcset eo "Log Files" "Protokolo"
    ::msgcat::mcset eo "&No" "&Ne"
    ::msgcat::mcset eo "&OK"
    ::msgcat::mcset eo "OK"
    ::msgcat::mcset eo "Ok"
    ::msgcat::mcset eo "Open" "Malfermu"
    ::msgcat::mcset eo "&Open" "&Malfermu"
    ::msgcat::mcset eo "Open Multiple Files" "Melfermu multan dosierojn"
    ::msgcat::mcset eo "P&aste" "&Elpoŝigi"
    ::msgcat::mcset eo "&Quit" "&Finigu"
    ::msgcat::mcset eo "&Red" "&Rosa"
    ::msgcat::mcset eo "Replace existing file?" "Ĉu anstataûu ekzistantan dosieron?"
    ::msgcat::mcset eo "&Retry" "&Ripetu"
    ::msgcat::mcset eo "&Save" "&Savu"
    ::msgcat::mcset eo "Save As" "Savu kiel"
    ::msgcat::mcset eo "Save To Log" "Savu en protokolon"
    ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron"
    ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti"
    ::msgcat::mcset eo "&Selection:" "&Elekto:"
    ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesaĝojn"
    ::msgcat::mcset eo "&Source..." "&Fontoprogramo..."
    ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj"
    ::msgcat::mcset eo "Tcl for Windows" "Tcl por vindoso"
    ::msgcat::mcset eo "Text Files" "Tekstodosierojn"
    ::msgcat::mcset eo "&Yes" "&Jes"
    ::msgcat::mcset eo "abort" "ĉesigo"
    ::msgcat::mcset eo "blue" "blua"
    ::msgcat::mcset eo "cancel" "rezignu"
    ::msgcat::mcset eo "extension" "ekspansio"
    ::msgcat::mcset eo "extensions" "ekspansioj"
    ::msgcat::mcset eo "green" "verda"
    ::msgcat::mcset eo "ignore" "ignorieren"
    ::msgcat::mcset eo "red" "ruĝa"
    ::msgcat::mcset eo "retry" "ripetu"
    ::msgcat::mcset eo "yes" "jes"
}

|

|


<

|

|




|








|











|




<





|


|







|





|






|



1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
namespace eval ::tk {
    ::msgcat::mcset eo "&Abort" "&\u0108esigo"
    ::msgcat::mcset eo "&About..." "Pri..."
    ::msgcat::mcset eo "All Files" "\u0108ioj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoerraro"
    ::msgcat::mcset eo "&Blue" "&Blua"

    ::msgcat::mcset eo "&Cancel" "&Rezignu"
    ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble \u0109angi al dosierulon \"%1\$s\".\nVi ne rajtas tion."
    ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujo"
    ::msgcat::mcset eo "&Clear" "&Klaru"
    ::msgcat::mcset eo "&Clear Console" "&Klaru konzolon"
    ::msgcat::mcset eo "Color" "Farbo"
    ::msgcat::mcset eo "Console" "Konzolo"
    ::msgcat::mcset eo "&Copy" "&Kopiu"
    ::msgcat::mcset eo "Cu&t" "&Enpo\u015digu"
    ::msgcat::mcset eo "&Delete" "&Forprenu"
    ::msgcat::mcset eo "Details >>" "Detaloj >>"
    ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas."
    ::msgcat::mcset eo "&Directory:" "&Dosierujo:"
    ::msgcat::mcset eo "&Edit" "&Redaktu"
    ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s"
    ::msgcat::mcset eo "E&xit" "&Eliru"
    ::msgcat::mcset eo "&File" "&Dosiero"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\n\u0108u vi volas anstata\u00fbigi la dosieron?"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam egzistas. \n\n"
    ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosierp \"%1\$s\" ne estas."
    ::msgcat::mcset eo "File &name:" "Dosiero&nomo:"
    ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:"
    ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Typo:"
    ::msgcat::mcset eo "Fi&les:" "Do&sieroj:"
    ::msgcat::mcset eo "&Filter" "&Filtrilo"
    ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:"
    ::msgcat::mcset eo "&Green" "&Verda"
    ::msgcat::mcset eo "&Help" "&Helpu"
    ::msgcat::mcset eo "Hi" "Saluton"
    ::msgcat::mcset eo "&Hide Console" "&Ka\u015du konzolon"
    ::msgcat::mcset eo "&Ignore" "&Ignoru"
    ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"."
    ::msgcat::mcset eo "Log Files" "Protokolo"
    ::msgcat::mcset eo "&No" "&Ne"

    ::msgcat::mcset eo "OK"
    ::msgcat::mcset eo "Ok"
    ::msgcat::mcset eo "Open" "Malfermu"
    ::msgcat::mcset eo "&Open" "&Malfermu"
    ::msgcat::mcset eo "Open Multiple Files" "Melfermu multan dosierojn"
    ::msgcat::mcset eo "P&aste" "&Elpo\u015digi"
    ::msgcat::mcset eo "&Quit" "&Finigu"
    ::msgcat::mcset eo "&Red" "&Rosa"
    ::msgcat::mcset eo "Replace existing file?" "\u0108u anstata\u00fbu ekzistantan dosieron?"
    ::msgcat::mcset eo "&Retry" "&Ripetu"
    ::msgcat::mcset eo "&Save" "&Savu"
    ::msgcat::mcset eo "Save As" "Savu kiel"
    ::msgcat::mcset eo "Save To Log" "Savu en protokolon"
    ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron"
    ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti"
    ::msgcat::mcset eo "&Selection:" "&Elekto:"
    ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesa\u011dojn"
    ::msgcat::mcset eo "&Source..." "&Fontoprogramo..."
    ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj"
    ::msgcat::mcset eo "Tcl for Windows" "Tcl por vindoso"
    ::msgcat::mcset eo "Text Files" "Tekstodosierojn"
    ::msgcat::mcset eo "&Yes" "&Jes"
    ::msgcat::mcset eo "abort" "\u0109esigo"
    ::msgcat::mcset eo "blue" "blua"
    ::msgcat::mcset eo "cancel" "rezignu"
    ::msgcat::mcset eo "extension" "ekspansio"
    ::msgcat::mcset eo "extensions" "ekspansioj"
    ::msgcat::mcset eo "green" "verda"
    ::msgcat::mcset eo "ignore" "ignorieren"
    ::msgcat::mcset eo "red" "ru\u011da"
    ::msgcat::mcset eo "retry" "ripetu"
    ::msgcat::mcset eo "yes" "jes"
}

Changes to library/msgs/es.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
namespace eval ::tk {
    ::msgcat::mcset es "&Abort" "&Abortar"
    ::msgcat::mcset es "&About..." "&Acerca de ..."
    ::msgcat::mcset es "All Files" "Todos los archivos"
    ::msgcat::mcset es "Application Error" "Error de la aplicación"
    ::msgcat::mcset es "&Blue" "&Azul"
    ::msgcat::mcset es "Cancel" "Cancelar"
    ::msgcat::mcset es "&Cancel" "&Cancelar"
    ::msgcat::mcset es "Cannot change to the directory \"%1\$s\".\nPermission denied." "No es posible acceder al directorio \"%1\$s\".\nPermiso denegado."
    ::msgcat::mcset es "Choose Directory" "Elegir directorio"
    ::msgcat::mcset es "Cl&ear" "&Borrar"
    ::msgcat::mcset es "&Clear Console" "&Borrar consola"
    ::msgcat::mcset es "Color"
    ::msgcat::mcset es "Console" "Consola"
    ::msgcat::mcset es "&Copy" "&Copiar"
    ::msgcat::mcset es "Cu&t" "Cor&tar"
    ::msgcat::mcset es "&Delete" "&Borrar"
    ::msgcat::mcset es "Details >>" "Detalles >>"
    ::msgcat::mcset es "Directory \"%1\$s\" does not exist." "El directorio \"%1\$s\" no existe."
    ::msgcat::mcset es "&Directory:" "&Directorio:"
    ::msgcat::mcset es "&Edit" "&Editar"
    ::msgcat::mcset es "Error: %1\$s"
    ::msgcat::mcset es "E&xit" "Salir"
    ::msgcat::mcset es "&File" "&Archivo"
    ::msgcat::mcset es "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "El archivo \"%1\$s\" ya existe.\n¿Desea sobreescribirlo?"
    ::msgcat::mcset es "File \"%1\$s\" already exists.\n\n" "El archivo \"%1\$s\" ya existe.\n\n"
    ::msgcat::mcset es "File \"%1\$s\" does not exist." "El archivo \"%1\$s\" no existe."
    ::msgcat::mcset es "File &name:" "&Nombre de archivo:"
    ::msgcat::mcset es "File &names:" "&Nombres de archivo:"
    ::msgcat::mcset es "Files of &type:" "Archivos de &tipo:"
    ::msgcat::mcset es "Fi&les:" "&Archivos:"
    ::msgcat::mcset es "&Filter" "&Filtro"
    ::msgcat::mcset es "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset es "&Green" "&Verde"
    ::msgcat::mcset es "&Help" "&Ayuda"
    ::msgcat::mcset es "Hi"  "Hola"
    ::msgcat::mcset es "&Hide Console" "&Esconder la consola"
    ::msgcat::mcset es "&Ignore" "&Ignorar"
    ::msgcat::mcset es "Invalid file name \"%1\$s\"." "Nombre de archivo inválido \"%1\$s\"."
    ::msgcat::mcset es "Log Files"  "Ficheros de traza"
    ::msgcat::mcset es "&No"
    ::msgcat::mcset es "&OK"
    ::msgcat::mcset es "OK"
    ::msgcat::mcset es "Ok"
    ::msgcat::mcset es "Open" "Abrir"
    ::msgcat::mcset es "&Open" "&Abrir"
    ::msgcat::mcset es "Open Multiple Files" "Abrir múltiples archivos"
    ::msgcat::mcset es "P&aste" "Peg&ar"
    ::msgcat::mcset es "&Quit" "&Abandonar"
    ::msgcat::mcset es "&Red" "&Rojo"
    ::msgcat::mcset es "Replace existing file?" "¿Reemplazar el archivo existente?"
    ::msgcat::mcset es "&Retry" "&Reintentar"
    ::msgcat::mcset es "&Save" "&Guardar"
    ::msgcat::mcset es "Save As" "Guardar como"
    ::msgcat::mcset es "Save To Log" "Guardar al archivo de traza"
    ::msgcat::mcset es "Select Log File"  "Elegir un archivo de traza"
    ::msgcat::mcset es "Select a file to source" "Seleccionar un archivo a evaluar"
    ::msgcat::mcset es "&Selection:" "&Selección:"
    ::msgcat::mcset es "Skip Messages" "Omitir los mensajes"
    ::msgcat::mcset es "&Source..." "E&valuar..."
    ::msgcat::mcset es "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset es "Tcl for Windows" "Tcl para Windows"
    ::msgcat::mcset es "Text Files" "Archivos de texto"
    ::msgcat::mcset es "&Yes" "&Sí"
    ::msgcat::mcset es "abort" "abortar"
    ::msgcat::mcset es "blue" "azul"
    ::msgcat::mcset es "cancel" "cancelar"
    ::msgcat::mcset es "extension"  "extensión"
    ::msgcat::mcset es "extensions" "extensiones"
    ::msgcat::mcset es "green" "verde"
    ::msgcat::mcset es "ignore" "ignorar"
    ::msgcat::mcset es "ok"
    ::msgcat::mcset es "red" "rojo"
    ::msgcat::mcset es "retry" "reintentar"
    ::msgcat::mcset es "yes" "sí"
}




|

<





|








|


|













|

|
|
|
<


|



|






|





|



|



|


|

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
namespace eval ::tk {
    ::msgcat::mcset es "&Abort" "&Abortar"
    ::msgcat::mcset es "&About..." "&Acerca de ..."
    ::msgcat::mcset es "All Files" "Todos los archivos"
    ::msgcat::mcset es "Application Error" "Error de la aplicaci\u00f3n"
    ::msgcat::mcset es "&Blue" "&Azul"

    ::msgcat::mcset es "&Cancel" "&Cancelar"
    ::msgcat::mcset es "Cannot change to the directory \"%1\$s\".\nPermission denied." "No es posible acceder al directorio \"%1\$s\".\nPermiso denegado."
    ::msgcat::mcset es "Choose Directory" "Elegir directorio"
    ::msgcat::mcset es "Cl&ear" "&Borrar"
    ::msgcat::mcset es "&Clear Console" "&Borrar consola"
    ::msgcat::mcset es "Color" "Color"
    ::msgcat::mcset es "Console" "Consola"
    ::msgcat::mcset es "&Copy" "&Copiar"
    ::msgcat::mcset es "Cu&t" "Cor&tar"
    ::msgcat::mcset es "&Delete" "&Borrar"
    ::msgcat::mcset es "Details >>" "Detalles >>"
    ::msgcat::mcset es "Directory \"%1\$s\" does not exist." "El directorio \"%1\$s\" no existe."
    ::msgcat::mcset es "&Directory:" "&Directorio:"
    ::msgcat::mcset es "&Edit" "&Editar"
    ::msgcat::mcset es "Error: %1\$s" "Error: %1\$s"
    ::msgcat::mcset es "E&xit" "Salir"
    ::msgcat::mcset es "&File" "&Archivo"
    ::msgcat::mcset es "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "El archivo \"%1\$s\" ya existe.\n\u00bfDesea sobreescribirlo?"
    ::msgcat::mcset es "File \"%1\$s\" already exists.\n\n" "El archivo \"%1\$s\" ya existe.\n\n"
    ::msgcat::mcset es "File \"%1\$s\" does not exist." "El archivo \"%1\$s\" no existe."
    ::msgcat::mcset es "File &name:" "&Nombre de archivo:"
    ::msgcat::mcset es "File &names:" "&Nombres de archivo:"
    ::msgcat::mcset es "Files of &type:" "Archivos de &tipo:"
    ::msgcat::mcset es "Fi&les:" "&Archivos:"
    ::msgcat::mcset es "&Filter" "&Filtro"
    ::msgcat::mcset es "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset es "&Green" "&Verde"
    ::msgcat::mcset es "&Help" "&Ayuda"
    ::msgcat::mcset es "Hi"  "Hola"
    ::msgcat::mcset es "&Hide Console" "&Esconder la consola"
    ::msgcat::mcset es "&Ignore" "&Ignorar"
    ::msgcat::mcset es "Invalid file name \"%1\$s\"." "Nombre de archivo inv\u00e1lido \"%1\$s\"."
    ::msgcat::mcset es "Log Files"  "Ficheros de traza"
    ::msgcat::mcset es "&No" "&No"
    ::msgcat::mcset es "&OK" "&OK"
    ::msgcat::mcset es "Ok" "Ok"

    ::msgcat::mcset es "Open" "Abrir"
    ::msgcat::mcset es "&Open" "&Abrir"
    ::msgcat::mcset es "Open Multiple Files" "Abrir m\u00faltiples archivos"
    ::msgcat::mcset es "P&aste" "Peg&ar"
    ::msgcat::mcset es "&Quit" "&Abandonar"
    ::msgcat::mcset es "&Red" "&Rojo"
    ::msgcat::mcset es "Replace existing file?" "\u00bfReemplazar el archivo existente?"
    ::msgcat::mcset es "&Retry" "&Reintentar"
    ::msgcat::mcset es "&Save" "&Guardar"
    ::msgcat::mcset es "Save As" "Guardar como"
    ::msgcat::mcset es "Save To Log" "Guardar al archivo de traza"
    ::msgcat::mcset es "Select Log File"  "Elegir un archivo de traza"
    ::msgcat::mcset es "Select a file to source" "Seleccionar un archivo a evaluar"
    ::msgcat::mcset es "&Selection:" "&Selecci\u00f3n:"
    ::msgcat::mcset es "Skip Messages" "Omitir los mensajes"
    ::msgcat::mcset es "&Source..." "E&valuar..."
    ::msgcat::mcset es "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset es "Tcl for Windows" "Tcl para Windows"
    ::msgcat::mcset es "Text Files" "Archivos de texto"
    ::msgcat::mcset es "&Yes" "&S\u00ed"
    ::msgcat::mcset es "abort" "abortar"
    ::msgcat::mcset es "blue" "azul"
    ::msgcat::mcset es "cancel" "cancelar"
    ::msgcat::mcset es "extension"  "extensi\u00f3n"
    ::msgcat::mcset es "extensions" "extensiones"
    ::msgcat::mcset es "green" "verde"
    ::msgcat::mcset es "ignore" "ignorar"
    ::msgcat::mcset es "ok" "ok"
    ::msgcat::mcset es "red" "rojo"
    ::msgcat::mcset es "retry" "reintentar"
    ::msgcat::mcset es "yes" "s\u00ed"
}

Changes to library/msgs/fr.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
namespace eval ::tk {
    ::msgcat::mcset fr "&Abort" "&Annuler"
    ::msgcat::mcset fr "About..." "À propos..."
    ::msgcat::mcset fr "All Files" "Tous les fichiers"
    ::msgcat::mcset fr "Application Error" "Erreur d'application"
    ::msgcat::mcset fr "&Blue" "&Bleu"
    ::msgcat::mcset fr "Cancel" "Annuler"
    ::msgcat::mcset fr "&Cancel" "&Annuler"
    ::msgcat::mcset fr "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossible d'accéder au répertoire \"%1\$s\".\nPermission refusée."
    ::msgcat::mcset fr "Choose Directory" "Choisir répertoire"
    ::msgcat::mcset fr "Cl&ear" "Effacer"
    ::msgcat::mcset fr "Color" "Couleur"
    ::msgcat::mcset fr "Console"
    ::msgcat::mcset fr "Copy" "Copier"
    ::msgcat::mcset fr "Cu&t" "Couper"
    ::msgcat::mcset fr "Delete" "Effacer"
    ::msgcat::mcset fr "Details >>" "Détails >>"
    ::msgcat::mcset fr "Directory \"%1\$s\" does not exist." "Le répertoire \"%1\$s\" n'existe pas."
    ::msgcat::mcset fr "&Directory:" "&Répertoire:"
    ::msgcat::mcset fr "Error: %1\$s" "Erreur: %1\$s"
    ::msgcat::mcset fr "E&xit" "Quitter"
    ::msgcat::mcset fr "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Le fichier \"%1\$s\" existe déjà.\nVoulez-vous l'écraser?"
    ::msgcat::mcset fr "File \"%1\$s\" already exists.\n\n" "Le fichier \"%1\$s\" existe déjà.\n\n"
    ::msgcat::mcset fr "File \"%1\$s\" does not exist." "Le fichier \"%1\$s\" n'existe pas."
    ::msgcat::mcset fr "File &name:" "&Nom de fichier:"
    ::msgcat::mcset fr "File &names:" "&Noms de fichiers:"
    ::msgcat::mcset fr "Files of &type:" "&Type de fichiers:"
    ::msgcat::mcset fr "Fi&les:" "Fich&iers:"
    ::msgcat::mcset fr "&Filter" "&Filtre"
    ::msgcat::mcset fr "Fil&ter:" "Fil&tre:"
    ::msgcat::mcset fr "&Green" "&Vert"
    ::msgcat::mcset fr "Hi" "Salut"
    ::msgcat::mcset fr "&Hide Console" "Cacher la Console"
    ::msgcat::mcset fr "&Ignore" "&Ignorer"
    ::msgcat::mcset fr "Invalid file name \"%1\$s\"." "Nom de fichier invalide \"%1\$s\"."
    ::msgcat::mcset fr "Log Files" "Fichiers de trace"
    ::msgcat::mcset fr "&No" "&Non"
    ::msgcat::mcset fr "&OK"
    ::msgcat::mcset fr "OK"
    ::msgcat::mcset fr "Ok"
    ::msgcat::mcset fr "Open" "Ouvrir"
    ::msgcat::mcset fr "&Open" "&Ouvrir"
    ::msgcat::mcset fr "Open Multiple Files" "Ouvrir plusieurs fichiers"
    ::msgcat::mcset fr "P&aste" "Coller"
    ::msgcat::mcset fr "&Quit" "&Quitter"
    ::msgcat::mcset fr "&Red" "&Rouge"
    ::msgcat::mcset fr "Replace existing file?" "Remplacer le fichier existant?"
    ::msgcat::mcset fr "&Retry" "&Ré-essayer"
    ::msgcat::mcset fr "&Save" "&Sauvegarder"
    ::msgcat::mcset fr "Save As" "Sauvegarder sous"
    ::msgcat::mcset fr "Save To Log" "Sauvegarde au fichier de trace"
    ::msgcat::mcset fr "Select Log File" "Choisir un fichier de trace"
    ::msgcat::mcset fr "Select a file to source" "Choisir un fichier à évaluer"
    ::msgcat::mcset fr "&Selection:" "&Sélection:"
    ::msgcat::mcset fr "Skip Messages" "Omettre les messages"
    ::msgcat::mcset fr "&Source..." "Évaluer..."
    ::msgcat::mcset fr "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset fr "Tcl for Windows" "Tcl pour Windows"
    ::msgcat::mcset fr "Text Files" "Fichiers texte"
    ::msgcat::mcset fr "&Yes" "&Oui"
    ::msgcat::mcset fr "abort" "abandonner"
    ::msgcat::mcset fr "blue" "bleu"
    ::msgcat::mcset fr "cancel" "annuler"
    ::msgcat::mcset fr "extension"
    ::msgcat::mcset fr "extensions"
    ::msgcat::mcset fr "green" "vert"
    ::msgcat::mcset fr "ignore" "ignorer"
    ::msgcat::mcset fr "ok"
    ::msgcat::mcset fr "red" "rouge"
    ::msgcat::mcset fr "retry" "réessayer"
    ::msgcat::mcset fr "yes" "oui"
}


|



<

|
|
|



|

|
|
|

|
|
|









|





<




|
|


|




|
|

|













|


1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
namespace eval ::tk {
    ::msgcat::mcset fr "&Abort" "&Annuler"
    ::msgcat::mcset fr "About..." "\u00c0 propos..."
    ::msgcat::mcset fr "All Files" "Tous les fichiers"
    ::msgcat::mcset fr "Application Error" "Erreur d'application"
    ::msgcat::mcset fr "&Blue" "&Bleu"

    ::msgcat::mcset fr "&Cancel" "&Annuler"
    ::msgcat::mcset fr "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossible d'acc\u00e9der au r\u00e9pertoire \"%1\$s\".\nPermission refus\u00e9e."
    ::msgcat::mcset fr "Choose Directory" "Choisir r\u00e9pertoire"
    ::msgcat::mcset fr "Clear" "Effacer"
    ::msgcat::mcset fr "Color" "Couleur"
    ::msgcat::mcset fr "Console"
    ::msgcat::mcset fr "Copy" "Copier"
    ::msgcat::mcset fr "Cut" "Couper"
    ::msgcat::mcset fr "Delete" "Effacer"
    ::msgcat::mcset fr "Details >>" "D\u00e9tails >>"
    ::msgcat::mcset fr "Directory \"%1\$s\" does not exist." "Le r\u00e9pertoire \"%1\$s\" n'existe pas."
    ::msgcat::mcset fr "&Directory:" "&R\u00e9pertoire:"
    ::msgcat::mcset fr "Error: %1\$s" "Erreur: %1\$s"
    ::msgcat::mcset fr "Exit" "Quitter"
    ::msgcat::mcset fr "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\nVoulez-vous l'\u00e9craser?"
    ::msgcat::mcset fr "File \"%1\$s\" already exists.\n\n" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\n\n"
    ::msgcat::mcset fr "File \"%1\$s\" does not exist." "Le fichier \"%1\$s\" n'existe pas."
    ::msgcat::mcset fr "File &name:" "&Nom de fichier:"
    ::msgcat::mcset fr "File &names:" "&Noms de fichiers:"
    ::msgcat::mcset fr "Files of &type:" "&Type de fichiers:"
    ::msgcat::mcset fr "Fi&les:" "Fich&iers:"
    ::msgcat::mcset fr "&Filter" "&Filtre"
    ::msgcat::mcset fr "Fil&ter:" "Fil&tre:"
    ::msgcat::mcset fr "&Green" "&Vert"
    ::msgcat::mcset fr "Hi" "Salut"
    ::msgcat::mcset fr "Hide Console" "Cacher la Console"
    ::msgcat::mcset fr "&Ignore" "&Ignorer"
    ::msgcat::mcset fr "Invalid file name \"%1\$s\"." "Nom de fichier invalide \"%1\$s\"."
    ::msgcat::mcset fr "Log Files" "Fichiers de trace"
    ::msgcat::mcset fr "&No" "&Non"
    ::msgcat::mcset fr "&OK"

    ::msgcat::mcset fr "Ok"
    ::msgcat::mcset fr "Open" "Ouvrir"
    ::msgcat::mcset fr "&Open" "&Ouvrir"
    ::msgcat::mcset fr "Open Multiple Files" "Ouvrir plusieurs fichiers"
    ::msgcat::mcset fr "Paste" "Coller"
    ::msgcat::mcset fr "Quit" "Quitter"
    ::msgcat::mcset fr "&Red" "&Rouge"
    ::msgcat::mcset fr "Replace existing file?" "Remplacer le fichier existant?"
    ::msgcat::mcset fr "&Retry" "&R\u00e9-essayer"
    ::msgcat::mcset fr "&Save" "&Sauvegarder"
    ::msgcat::mcset fr "Save As" "Sauvegarder sous"
    ::msgcat::mcset fr "Save To Log" "Sauvegarde au fichier de trace"
    ::msgcat::mcset fr "Select Log File" "Choisir un fichier de trace"
    ::msgcat::mcset fr "Select a file to source" "Choisir un fichier \u00e0 \u00e9valuer"
    ::msgcat::mcset fr "&Selection:" "&S\u00e9lection:"
    ::msgcat::mcset fr "Skip Messages" "Omettre les messages"
    ::msgcat::mcset fr "Source..." "\u00c9valuer..."
    ::msgcat::mcset fr "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset fr "Tcl for Windows" "Tcl pour Windows"
    ::msgcat::mcset fr "Text Files" "Fichiers texte"
    ::msgcat::mcset fr "&Yes" "&Oui"
    ::msgcat::mcset fr "abort" "abandonner"
    ::msgcat::mcset fr "blue" "bleu"
    ::msgcat::mcset fr "cancel" "annuler"
    ::msgcat::mcset fr "extension"
    ::msgcat::mcset fr "extensions"
    ::msgcat::mcset fr "green" "vert"
    ::msgcat::mcset fr "ignore" "ignorer"
    ::msgcat::mcset fr "ok"
    ::msgcat::mcset fr "red" "rouge"
    ::msgcat::mcset fr "retry" "r\u00e9essayer"
    ::msgcat::mcset fr "yes" "oui"
}

Changes to library/msgs/hu.msg.

1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
namespace eval ::tk {
    ::msgcat::mcset hu "&Abort" "&Megszakítás"
    ::msgcat::mcset hu "&About..." "Névjegy..."
    ::msgcat::mcset hu "All Files" "Minden fájl"

    ::msgcat::mcset hu "Application Error" "Alkalmazás hiba"
    ::msgcat::mcset hu "&Blue" "&Kék"
    ::msgcat::mcset hu "Cancel" "Mégsem"
    ::msgcat::mcset hu "&Cancel" "Még&sem"
    ::msgcat::mcset hu "Cannot change to the directory \"%1\$s\".\nPermission denied." "A könyvtárváltás nem sikerült: \"%1\$s\".\nHozzáférés megtagadva."
    ::msgcat::mcset hu "Choose Directory" "Könyvtár kiválasztása"
    ::msgcat::mcset hu "Cl&ear" "Törlés"
    ::msgcat::mcset hu "&Clear Console" "&Törlés Konzol"
    ::msgcat::mcset hu "Color" "Szín"
    ::msgcat::mcset hu "Console" "Konzol"
    ::msgcat::mcset hu "&Copy" "&Másolás"
    ::msgcat::mcset hu "Cu&t" "&Kivágás"
    ::msgcat::mcset hu "&Delete" "&Törlés"
    ::msgcat::mcset hu "Details >>" "Részletek >>"
    ::msgcat::mcset hu "Directory \"%1\$s\" does not exist." "\"%1\$s\" könyvtár nem létezik."
    ::msgcat::mcset hu "&Directory:" "&Könyvtár:"
    #::msgcat::mcset hu "&Edit"
    ::msgcat::mcset hu "Error: %1\$s" "Hiba: %1\$s"
    ::msgcat::mcset hu "E&xit" "Kilépés"
    ::msgcat::mcset hu "&File" "&Fájl"
    ::msgcat::mcset hu "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "\"%1\$s\" fájl már létezik.\nFelülírjam?"
    ::msgcat::mcset hu "File \"%1\$s\" already exists.\n\n" "\"%1\$s\" fájl már létezik.\n\n"
    ::msgcat::mcset hu "File \"%1\$s\" does not exist." "\"%1\$s\" fájl nem létezik."
    ::msgcat::mcset hu "File &name:" "Fájl &neve:"
    ::msgcat::mcset hu "File &names:" "Fájlok &nevei:"
    ::msgcat::mcset hu "Files of &type:" "Fájlok &típusa:"
    ::msgcat::mcset hu "Fi&les:" "Fáj&lok:"
    ::msgcat::mcset hu "&Filter" "&Szűrő"
    ::msgcat::mcset hu "Fil&ter:" "S&zűrő:"
    ::msgcat::mcset hu "&Green" "&Zöld"
    #::msgcat::mcset hu "&Help"
    ::msgcat::mcset hu "Hi" "Üdv"
    ::msgcat::mcset hu "&Hide Console" "Konzol &elrejtése"
    ::msgcat::mcset hu "&Ignore" "K&ihagyás"
    ::msgcat::mcset hu "Invalid file name \"%1\$s\"." "Érvénytelen fájlnév: \"%1\$s\"."
    ::msgcat::mcset hu "Log Files" "Log fájlok"
    ::msgcat::mcset hu "&No" "&Nem"
    ::msgcat::mcset hu "&OK"
    ::msgcat::mcset hu "OK"
    ::msgcat::mcset hu "Ok"
    ::msgcat::mcset hu "Open" "Megnyitás"
    ::msgcat::mcset hu "&Open" "&Megnyitás"
    ::msgcat::mcset hu "Open Multiple Files" "Több fájl megnyitása"
    ::msgcat::mcset hu "P&aste" "&Beillesztés"
    ::msgcat::mcset hu "&Quit" "&Kilépés"
    ::msgcat::mcset hu "&Red" "&Vörös"
    ::msgcat::mcset hu "Replace existing file?" "Meglévő fájl cseréje?"
    ::msgcat::mcset hu "&Retry" "Új&ra"
    ::msgcat::mcset hu "&Save" "&Mentés"
    ::msgcat::mcset hu "Save As" "Mentés másként"
    ::msgcat::mcset hu "Save To Log" "Mentés log fájlba"
    ::msgcat::mcset hu "Select Log File" "Log fájl kiválasztása"
    ::msgcat::mcset hu "Select a file to source" "Forrásfájl kiválasztása"
    ::msgcat::mcset hu "&Selection:" "&Kijelölés:"
    ::msgcat::mcset hu "Show &Hidden Directories" "&Rejtett könyvtárak megjelenítése"
    ::msgcat::mcset hu "Show &Hidden Files and Directories" "&Rejtett fájlok és könyvtárak megjelenítése"
    ::msgcat::mcset hu "Skip Messages" "Üzenetek kihagyása"
    ::msgcat::mcset hu "&Source..." "&Forrás..."
    ::msgcat::mcset hu "Tcl Scripts" "Tcl scriptek"
    ::msgcat::mcset hu "Tcl for Windows" "Tcl Windows-hoz"
    ::msgcat::mcset hu "Text Files" "Szövegfájlok"
    ::msgcat::mcset hu "&Yes" "&Igen"
    ::msgcat::mcset hu "abort" "megszakítás"
    ::msgcat::mcset hu "blue" "kék"
    ::msgcat::mcset hu "cancel" "mégsem"
    ::msgcat::mcset hu "extension" "kiterjesztés"
    ::msgcat::mcset hu "extensions" "kiterjesztések"
    ::msgcat::mcset hu "green" "zöld"
    ::msgcat::mcset hu "ignore" "ignorer"
    ::msgcat::mcset hu "ok"
    ::msgcat::mcset hu "red" "vörös"
    ::msgcat::mcset hu "retry" "újra"
    ::msgcat::mcset hu "yes" "igen"
}

|
|
|
>
|
|
<
|
|
|
|
|
|

|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|



<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|

|
|
|
|
|
|


|
|


1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
namespace eval ::tk {
    ::msgcat::mcset hu "&Abort" "&Megszak\u00edt\u00e1s"
    ::msgcat::mcset hu "About..." "N\u00e9vjegy..."
    ::msgcat::mcset hu "All Files" "Minden f\u00e1jl"
    ::msgcat::mcset hu "All Files (*) " "Minden f\u00e1jl (*) "
    ::msgcat::mcset hu "Application Error" "Alkalmaz\u00e1s hiba"
    ::msgcat::mcset hu "&Blue" "&K\u00e9k"

    ::msgcat::mcset hu "&Cancel" "M\u00e9g&sem"
    ::msgcat::mcset hu "Cannot change to the directory \"%1\$s\".\nPermission denied." "A k\u00f6nyvt\u00e1rv\u00e1lt\u00e1s nem siker\u00fclt: \"%1\$s\".\nHozz\u00e1f\u00e9r\u00e9s megtagadva."
    ::msgcat::mcset hu "Choose Directory" "K\u00f6nyvt\u00e1r kiv\u00e1laszt\u00e1sa"
    ::msgcat::mcset hu "Clear" "T\u00f6rl\u00e9s"
    ::msgcat::mcset hu "&Clear Console" "&T\u00f6rl\u00e9s Konzol"
    ::msgcat::mcset hu "Color" "Sz\u00edn"
    ::msgcat::mcset hu "Console" "Konzol"
    ::msgcat::mcset hu "&Copy" "&M\u00e1sol\u00e1s"
    ::msgcat::mcset hu "Cu&t" "&Kiv\u00e1g\u00e1s"
    ::msgcat::mcset hu "&Delete" "&T\u00f6rl\u00e9s"
    ::msgcat::mcset hu "Details >>" "R\u00e9szletek >>"
    ::msgcat::mcset hu "Directory \"%1\$s\" does not exist." "\"%1\$s\" k\u00f6nyvt\u00e1r nem l\u00e9tezik."
    ::msgcat::mcset hu "&Directory:" "&K\u00f6nyvt\u00e1r:"
    #::msgcat::mcset hu "&Edit"
    ::msgcat::mcset hu "Error: %1\$s" "Hiba: %1\$s"
    ::msgcat::mcset hu "E&xit" "Kil\u00e9p\u00e9s"
    ::msgcat::mcset hu "&File" "&F\u00e1jl"
    ::msgcat::mcset hu "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "\"%1\$s\" f\u00e1jl m\u00e1r l\u00e9tezik.\nFel\u00fcl\u00edrjam?"
    ::msgcat::mcset hu "File \"%1\$s\" already exists.\n\n" "\"%1\$s\" f\u00e1jl m\u00e1r l\u00e9tezik.\n\n"
    ::msgcat::mcset hu "File \"%1\$s\" does not exist." "\"%1\$s\" f\u00e1jl nem l\u00e9tezik."
    ::msgcat::mcset hu "File &name:" "F\u00e1jl &neve:"
    ::msgcat::mcset hu "File &names:" "F\u00e1jlok &nevei:"
    ::msgcat::mcset hu "Files of &type:" "F\u00e1jlok &t\u00edpusa:"
    ::msgcat::mcset hu "Fi&les:" "F\u00e1j&lok:"
    ::msgcat::mcset hu "&Filter" "&Sz\u0171r\u0151"
    ::msgcat::mcset hu "Fil&ter:" "S&z\u0171r\u0151:"
    ::msgcat::mcset hu "&Green" "&Z\u00f6ld"
    #::msgcat::mcset hu "&Help"
    ::msgcat::mcset hu "Hi" "\u00dcdv"
    ::msgcat::mcset hu "&Hide Console" "Konzol &elrejt\u00e9se"
    ::msgcat::mcset hu "&Ignore" "K&ihagy\u00e1s"
    ::msgcat::mcset hu "Invalid file name \"%1\$s\"." "\u00c9rv\u00e9nytelen f\u00e1jln\u00e9v: \"%1\$s\"."
    ::msgcat::mcset hu "Log Files" "Log f\u00e1jlok"
    ::msgcat::mcset hu "&No" "&Nem"
    ::msgcat::mcset hu "&OK"
    ::msgcat::mcset hu "OK"

    ::msgcat::mcset hu "Open" "Megnyit\u00e1s"
    ::msgcat::mcset hu "&Open" "&Megnyit\u00e1s"
    ::msgcat::mcset hu "Open Multiple Files" "T\u00f6bb f\u00e1jl megnyit\u00e1sa"
    ::msgcat::mcset hu "P&aste" "&Beilleszt\u00e9s"
    ::msgcat::mcset hu "&Quit" "&Kil\u00e9p\u00e9s"
    ::msgcat::mcset hu "&Red" "&V\u00f6r\u00f6s"
    ::msgcat::mcset hu "Replace existing file?" "Megl\u00e9v\u0151 f\u00e1jl cser\u00e9je?"
    ::msgcat::mcset hu "&Retry" "\u00daj&ra"
    ::msgcat::mcset hu "&Save" "&Ment\u00e9s"
    ::msgcat::mcset hu "Save As" "Ment\u00e9s m\u00e1sk\u00e9nt"
    ::msgcat::mcset hu "Save To Log" "Ment\u00e9s log f\u00e1jlba"
    ::msgcat::mcset hu "Select Log File" "Log f\u00e1jl kiv\u00e1laszt\u00e1sa"
    ::msgcat::mcset hu "Select a file to source" "Forr\u00e1sf\u00e1jl kiv\u00e1laszt\u00e1sa"
    ::msgcat::mcset hu "&Selection:" "&Kijel\u00f6l\u00e9s:"
    ::msgcat::mcset hu "Show &Hidden Directories" "&Rejtett k\u00f6nyvt\u00e1rak megjelen\u00edt\u00e9se"
    ::msgcat::mcset hu "Show &Hidden Files and Directories" "&Rejtett f\u00e1jlok \u00e9s k\u00f6nyvt\u00e1rak megjelen\u00edt\u00e9se"
    ::msgcat::mcset hu "Skip Messages" "\u00dczenetek kihagy\u00e1sa"
    ::msgcat::mcset hu "&Source..." "&Forr\u00e1s..."
    ::msgcat::mcset hu "Tcl Scripts" "Tcl scriptek"
    ::msgcat::mcset hu "Tcl for Windows" "Tcl Windows-hoz"
    ::msgcat::mcset hu "Text Files" "Sz\u00f6vegf\u00e1jlok"
    ::msgcat::mcset hu "&Yes" "&Igen"
    ::msgcat::mcset hu "abort" "megszak\u00edt\u00e1s"
    ::msgcat::mcset hu "blue" "k\u00e9k"
    ::msgcat::mcset hu "cancel" "m\u00e9gsem"
    ::msgcat::mcset hu "extension" "kiterjeszt\u00e9s"
    ::msgcat::mcset hu "extensions" "kiterjeszt\u00e9sek"
    ::msgcat::mcset hu "green" "z\u00f6ld"
    ::msgcat::mcset hu "ignore" "ignorer"
    ::msgcat::mcset hu "ok"
    ::msgcat::mcset hu "red" "v\u00f6r\u00f6s"
    ::msgcat::mcset hu "retry" "\u00fajra"
    ::msgcat::mcset hu "yes" "igen"
}

Changes to library/msgs/it.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
namespace eval ::tk {
    ::msgcat::mcset it "&Abort" "&Interrompi"
    ::msgcat::mcset it "&About..." "Informazioni..."
    ::msgcat::mcset it "All Files" "Tutti i file"
    ::msgcat::mcset it "Application Error" "Errore dell' applicazione"
    ::msgcat::mcset it "&Blue" "&Blu"
    ::msgcat::mcset it "Cancel" "Annulla"
    ::msgcat::mcset it "&Cancel" "&Annulla"
    ::msgcat::mcset it "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossibile accedere alla directory \"%1\$s\".\nPermesso negato."
    ::msgcat::mcset it "Choose Directory" "Scegli una directory"
    ::msgcat::mcset it "Cl&ear" "Azzera"
    ::msgcat::mcset it "&Clear Console" "Azzera Console"
    ::msgcat::mcset it "Color" "Colore"
    ::msgcat::mcset it "Console"
    ::msgcat::mcset it "&Copy" "Copia"
    ::msgcat::mcset it "Cu&t" "Taglia"
    ::msgcat::mcset it "Delete" "Cancella"
    ::msgcat::mcset it "Details >>" "Dettagli >>"
    ::msgcat::mcset it "Directory \"%1\$s\" does not exist." "La directory \"%1\$s\" non esiste."
    ::msgcat::mcset it "&Directory:"
    ::msgcat::mcset it "Error: %1\$s" "Errore: %1\$s"
    ::msgcat::mcset it "E&xit" "Esci"
    ::msgcat::mcset it "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Il file \"%1\$s\" esiste già.\nVuoi sovrascriverlo?"
    ::msgcat::mcset it "File \"%1\$s\" already exists.\n\n" "Il file \"%1\$s\" esiste già.\n\n"
    ::msgcat::mcset it "File \"%1\$s\" does not exist." "Il file \"%1\$s\" non esiste."
    ::msgcat::mcset it "File &name:" "&Nome del file:"
    ::msgcat::mcset it "File &names:" "&Nomi dei file:"
    ::msgcat::mcset it "Files of &type:" "File di &tipo:"
    ::msgcat::mcset it "Fi&les:" "Fi&le:"
    ::msgcat::mcset it "&Filter" "&Filtro"
    ::msgcat::mcset it "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset it "&Green" "&Verde"
    ::msgcat::mcset it "Hi" "Salve"
    ::msgcat::mcset it "&Hide Console" "Nascondi la console"
    ::msgcat::mcset it "&Ignore" "&Ignora"
    ::msgcat::mcset it "Invalid file name \"%1\$s\"." "Nome di file non valido \"%1\$s\"."
    ::msgcat::mcset it "Log Files" "File di log"
    ::msgcat::mcset it "&No"
    ::msgcat::mcset it "&OK"
    ::msgcat::mcset it "OK"
    ::msgcat::mcset it "Ok"
    ::msgcat::mcset it "Open" "Apri"
    ::msgcat::mcset it "&Open" "A&pri"
    ::msgcat::mcset it "Open Multiple Files" "Apri file multipli"
    ::msgcat::mcset it "P&aste" "Incolla"
    ::msgcat::mcset it "&Quit" "Esci"
    ::msgcat::mcset it "&Red" "&Rosso"
    ::msgcat::mcset it "Replace existing file?" "Sostituisci il file esistente?"
    ::msgcat::mcset it "&Retry" "&Riprova"
    ::msgcat::mcset it "&Save" "&Salva"
    ::msgcat::mcset it "Save As" "Salva come"
    ::msgcat::mcset it "Save To Log" "Salva il log"
    ::msgcat::mcset it "Select Log File" "Scegli un file di log"
    ::msgcat::mcset it "Select a file to source" "Scegli un file da eseguire"
    ::msgcat::mcset it "&Selection:" "&Selezione:"
    ::msgcat::mcset it "Skip Messages" "Salta i messaggi"
    ::msgcat::mcset it "Source..." "Esegui..."
    ::msgcat::mcset it "Tcl Scripts" "Script Tcl"
    ::msgcat::mcset it "Tcl for Windows" "Tcl per Windows"
    ::msgcat::mcset it "Text Files" "File di testo"
    ::msgcat::mcset it "&Yes" "&Sì"
    ::msgcat::mcset it "abort" "interrompi"
    ::msgcat::mcset it "blue" "blu"
    ::msgcat::mcset it "cancel" "annulla"
    ::msgcat::mcset it "extension" "estensione"
    ::msgcat::mcset it "extensions" "estensioni"
    ::msgcat::mcset it "green" "verde"
    ::msgcat::mcset it "ignore" "ignora"
    ::msgcat::mcset it "ok"
    ::msgcat::mcset it "red" "rosso"
    ::msgcat::mcset it "retry" "riprova"
    ::msgcat::mcset it "yes" "sì"
}


|



<



|
<


|
|





|
|
|









|





|
|

<

|
|














|










|

1
2
3
4
5
6

7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
namespace eval ::tk {
    ::msgcat::mcset it "&Abort" "&Interrompi"
    ::msgcat::mcset it "About..." "Informazioni..."
    ::msgcat::mcset it "All Files" "Tutti i file"
    ::msgcat::mcset it "Application Error" "Errore dell' applicazione"
    ::msgcat::mcset it "&Blue" "&Blu"

    ::msgcat::mcset it "&Cancel" "&Annulla"
    ::msgcat::mcset it "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossibile accedere alla directory \"%1\$s\".\nPermesso negato."
    ::msgcat::mcset it "Choose Directory" "Scegli una directory"
    ::msgcat::mcset it "Clear" "Azzera"

    ::msgcat::mcset it "Color" "Colore"
    ::msgcat::mcset it "Console"
    ::msgcat::mcset it "Copy" "Copia"
    ::msgcat::mcset it "Cut" "Taglia"
    ::msgcat::mcset it "Delete" "Cancella"
    ::msgcat::mcset it "Details >>" "Dettagli >>"
    ::msgcat::mcset it "Directory \"%1\$s\" does not exist." "La directory \"%1\$s\" non esiste."
    ::msgcat::mcset it "&Directory:"
    ::msgcat::mcset it "Error: %1\$s" "Errore: %1\$s"
    ::msgcat::mcset it "Exit" "Esci"
    ::msgcat::mcset it "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Il file \"%1\$s\" esiste gi\u00e0.\nVuoi sovrascriverlo?"
    ::msgcat::mcset it "File \"%1\$s\" already exists.\n\n" "Il file \"%1\$s\" esiste gi\u00e0.\n\n"
    ::msgcat::mcset it "File \"%1\$s\" does not exist." "Il file \"%1\$s\" non esiste."
    ::msgcat::mcset it "File &name:" "&Nome del file:"
    ::msgcat::mcset it "File &names:" "&Nomi dei file:"
    ::msgcat::mcset it "Files of &type:" "File di &tipo:"
    ::msgcat::mcset it "Fi&les:" "Fi&le:"
    ::msgcat::mcset it "&Filter" "&Filtro"
    ::msgcat::mcset it "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset it "&Green" "&Verde"
    ::msgcat::mcset it "Hi" "Salve"
    ::msgcat::mcset it "Hide Console" "Nascondi la console"
    ::msgcat::mcset it "&Ignore" "&Ignora"
    ::msgcat::mcset it "Invalid file name \"%1\$s\"." "Nome di file non valido \"%1\$s\"."
    ::msgcat::mcset it "Log Files" "File di log"
    ::msgcat::mcset it "&No"
    ::msgcat::mcset it "&OK"
    ::msgcat::mcset it "Ok"
    ::msgcat::mcset it "&Open" "A&pri"
    ::msgcat::mcset it "Open" "Apri"

    ::msgcat::mcset it "Open Multiple Files" "Apri file multipli"
    ::msgcat::mcset it "Paste" "Incolla"
    ::msgcat::mcset it "Quit" "Esci"
    ::msgcat::mcset it "&Red" "&Rosso"
    ::msgcat::mcset it "Replace existing file?" "Sostituisci il file esistente?"
    ::msgcat::mcset it "&Retry" "&Riprova"
    ::msgcat::mcset it "&Save" "&Salva"
    ::msgcat::mcset it "Save As" "Salva come"
    ::msgcat::mcset it "Save To Log" "Salva il log"
    ::msgcat::mcset it "Select Log File" "Scegli un file di log"
    ::msgcat::mcset it "Select a file to source" "Scegli un file da eseguire"
    ::msgcat::mcset it "&Selection:" "&Selezione:"
    ::msgcat::mcset it "Skip Messages" "Salta i messaggi"
    ::msgcat::mcset it "Source..." "Esegui..."
    ::msgcat::mcset it "Tcl Scripts" "Script Tcl"
    ::msgcat::mcset it "Tcl for Windows" "Tcl per Windows"
    ::msgcat::mcset it "Text Files" "File di testo"
    ::msgcat::mcset it "&Yes" "&S\u00ec"
    ::msgcat::mcset it "abort" "interrompi"
    ::msgcat::mcset it "blue" "blu"
    ::msgcat::mcset it "cancel" "annulla"
    ::msgcat::mcset it "extension" "estensione"
    ::msgcat::mcset it "extensions" "estensioni"
    ::msgcat::mcset it "green" "verde"
    ::msgcat::mcset it "ignore" "ignora"
    ::msgcat::mcset it "ok"
    ::msgcat::mcset it "red" "rosso"
    ::msgcat::mcset it "retry" "riprova"
    ::msgcat::mcset it "yes" "s\u00ec"
}

Changes to library/msgs/nl.msg.

1

2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19

20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79





80
81

82



83
84

85

86






87
88
89





90
91
namespace eval ::tk {

    ::msgcat::mcset nl "&Abort" "&Afbreken"
    ::msgcat::mcset nl "&About..." "Over..."
    ::msgcat::mcset nl "All Files" "Alle Bestanden"
    ::msgcat::mcset nl "Application Error" "Toepassingsfout"
    ::msgcat::mcset nl "&Apply" "Toepassen"
    ::msgcat::mcset nl "Bold" "Vet"
    ::msgcat::mcset nl "Bold Italic" "Vet Cursief"
    ::msgcat::mcset nl "&Blue" "&Blauw"
    ::msgcat::mcset nl "Cancel" "Annuleren"
    ::msgcat::mcset nl "&Cancel" "&Annuleren"
    ::msgcat::mcset nl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan niet naar map \"%1\$s\" gaan.\nU heeft hiervoor geen toestemming."
    ::msgcat::mcset nl "Choose Directory" "Kies map"
    ::msgcat::mcset nl "Cl&ear" "Wissen"

    ::msgcat::mcset nl "&Clear Console" "&Wis Console"
    ::msgcat::mcset nl "Color" "Kleur"
    ::msgcat::mcset nl "Console"
    ::msgcat::mcset nl "&Copy" "Kopiëren"
    ::msgcat::mcset nl "Cu&t" "Knippen"

    ::msgcat::mcset nl "&Delete" "Wissen"
    ::msgcat::mcset nl "Details >>"
    ::msgcat::mcset nl "Directory \"%1\$s\" does not exist." "Map \"%1\$s\" bestaat niet."
    ::msgcat::mcset nl "&Directory:" "&Map:"
    ::msgcat::mcset nl "&Edit" "Bewerken"
    ::msgcat::mcset nl "Effects" "Effecten"

    ::msgcat::mcset nl "Error: %1\$s" "Fout: %1\$s"
    ::msgcat::mcset nl "E&xit" "Beëindigen"
    ::msgcat::mcset nl "&File" "Bestand"
    ::msgcat::mcset nl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Bestand \"%1\$s\" bestaat al.\nWilt u het overschrijven?"
    ::msgcat::mcset nl "File \"%1\$s\" already exists.\n\n" "Bestand \"%1\$s\" bestaat al.\n\n"
    ::msgcat::mcset nl "File \"%1\$s\" does not exist." "Bestand \"%1\$s\" bestaat niet."
    ::msgcat::mcset nl "File &name:" "Bestands&naam:"
    ::msgcat::mcset nl "File &names:" "Bestands&namen:"
    ::msgcat::mcset nl "Files of &type:" "Bestanden van het &type:"
    ::msgcat::mcset nl "Fi&les:" "&Bestanden:"
    ::msgcat::mcset nl "&Filter"
    ::msgcat::mcset nl "Fil&ter:"
    ::msgcat::mcset nl "Font"
    ::msgcat::mcset nl "&Font:"
    ::msgcat::mcset nl "Font st&yle:" "Font stijl:"
    ::msgcat::mcset nl "&Green" "&Groen"
    ::msgcat::mcset nl "&Help"
    ::msgcat::mcset nl "Hi" ""
    ::msgcat::mcset nl "&Hide Console" "Verberg Console"
    ::msgcat::mcset nl "&Ignore" "&Negeren"
    ::msgcat::mcset nl "Invalid file name \"%1\$s\"." "Ongeldige bestandsnaam \"%1\$s\"."
    ::msgcat::mcset nl "Italic" "Cursief"
    ::msgcat::mcset nl "Log Files" "Log Bestanden"
    ::msgcat::mcset nl "&No" "&Nee"
    ::msgcat::mcset nl "&OK"
    ::msgcat::mcset nl "OK"
    ::msgcat::mcset nl "Ok"
    ::msgcat::mcset nl "Open" "Openen"
    ::msgcat::mcset nl "&Open" "&Openen"
    ::msgcat::mcset nl "Open Multiple Files" "Open meerdere bestanden"
    ::msgcat::mcset nl "P&aste" "Pl&akken"



    ::msgcat::mcset nl "&Quit" "Stoppen"
    ::msgcat::mcset nl "&Red" "&Rood"
    ::msgcat::mcset nl "Regular" "Standaard"
    ::msgcat::mcset nl "Replace existing file?" "Vervang bestaand bestand?"
    ::msgcat::mcset nl "&Retry" "&Herhalen"
    ::msgcat::mcset nl "Sample"
    ::msgcat::mcset nl "&Save" "Op&slaan"
    ::msgcat::mcset nl "Save As" "Opslaan als"
    ::msgcat::mcset nl "Save To Log" "Opslaan naar Log"
    ::msgcat::mcset nl "Select Log File" "Selecteer Log bestand"
    ::msgcat::mcset nl "Select a file to source" "Selecteer bronbestand"
    ::msgcat::mcset nl "&Selection:" "&Selectie:"
    ::msgcat::mcset nl "&Size:" "Grootte"
    ::msgcat::mcset nl "Show &Hidden Directories" "Laat verborgen mappen zien"
    ::msgcat::mcset nl "Show &Hidden Files and Directories" "Laat verborgen bestanden mappen zien"
    ::msgcat::mcset nl "Skip Messages" "Berichten overslaan"
    ::msgcat::mcset nl "&Source..." "Bron..."
    ::msgcat::mcset nl "Stri&keout"
    ::msgcat::mcset nl "Tcl Scripts"
    ::msgcat::mcset nl "Tcl for Windows" "Tcl voor Windows"
    ::msgcat::mcset nl "Text Files" "Tekstbestanden"
    ::msgcat::mcset nl "&Underline" "Onderstreept"
    ::msgcat::mcset nl "&Yes" "&Ja"





    ::msgcat::mcset nl "abort" "afbreken"
    ::msgcat::mcset nl "blue" "blauw"

    ::msgcat::mcset nl "cancel" "annuleren"



    ::msgcat::mcset nl "extension"
    ::msgcat::mcset nl "extensions"

    ::msgcat::mcset nl "green" "groen"

    ::msgcat::mcset nl "ignore" "negeren"






    ::msgcat::mcset nl "ok"
    ::msgcat::mcset nl "red" "rood"
    ::msgcat::mcset nl "retry" "opnieuw"





    ::msgcat::mcset nl "yes" "ja"
}

>
|
|
|
|
|
|
|
|
|



|
>



|
|
>
|



|
|
>

|
|
|
|







<
<
<

|
|
<


<



|
|

<

|
>
>
>
|
|
|


<






<
<
<

<
|



|
|
>
>
>
>
>
|

>

>
>
>


>

>

>
>
>
>
>
>



>
>
>
>
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41



42
43
44

45
46

47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68



69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
namespace eval ::tk {
    ::msgcat::mcset nl "\"%1\$s\" must be an absolute pathname" "\"%1\$s\" moet een absolute pad-naam zijn"
    ::msgcat::mcset nl "%1\$s is not a toplevel window" "%1\$s is geen toplevel window"
    ::msgcat::mcset nl ", or" ", of"
    ::msgcat::mcset nl "-default, -icon, -message, -parent, -title, or -type" "-default, -icon, -message, -parent, -title, of -type"
    ::msgcat::mcset nl "-initialdir, -mustexist, -parent, or -title" "-initialdir, -mustexist, -parent, of -title"
    ::msgcat::mcset nl "&Abort" "&Afbreken"
    ::msgcat::mcset nl "About..." "Over..."
    ::msgcat::mcset nl "All Files" "Alle Bestanden"
    ::msgcat::mcset nl "Application Error" "Toepassingsfout"
    ::msgcat::mcset nl "&Blue" "&Blauw"
    ::msgcat::mcset nl "&Cancel" "&Annuleren"
    ::msgcat::mcset nl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan niet naar map \"%1\$s\" gaan.\nU heeft hiervoor geen toestemming."
    ::msgcat::mcset nl "Choose Directory" "Kies map"
    ::msgcat::mcset nl "Clear" "Wissen"
    ::msgcat::mcset nl "Clear entry, Press OK; Enter %1\$s, press OK" "Wis veld, Druk op OK; typ %1\$s in, druk op OK"
    ::msgcat::mcset nl "&Clear Console" "&Wis Console"
    ::msgcat::mcset nl "Color" "Kleur"
    ::msgcat::mcset nl "Console"
    ::msgcat::mcset nl "Copy" "Kopi\u00ebren"
    ::msgcat::mcset nl "Cut" "Knippen"
    ::msgcat::mcset nl "Delete" "Wissen"
    ::msgcat::mcset nl "Details"
    ::msgcat::mcset nl "Details >>"
    ::msgcat::mcset nl "Directory \"%1\$s\" does not exist." "Map \"%1\$s\" bestaat niet."
    ::msgcat::mcset nl "&Directory:" "&Map:"
    ::msgcat::mcset nl "Edit" "Bewerken"
    ::msgcat::mcset nl "Enter \"%1\$s\", press OK" "Typ \"%1\$s\", druk op OK"
    ::msgcat::mcset nl "Enter \"%1\$s\", press OK, enter \"%2\$s\", press OK" "Typ \"%1\$s\", druk op OK, typ \"%2\$s\", druk op OK"
    ::msgcat::mcset nl "Error: %1\$s" "Fout: %1\$s"
    ::msgcat::mcset nl "Exit" "Be\u00ebindigen"
    ::msgcat::mcset nl "File" "Bestand"
    ::msgcat::mcset nl "File \"%1\$s\" already exists.\n\n" "Bestand \"%1\$s\" bestaat al.\n\n"
    ::msgcat::mcset nl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Bestand \"%1\$s\" bestaat al.\nWilt u het overschrijven?"
    ::msgcat::mcset nl "File \"%1\$s\" does not exist." "Bestand \"%1\$s\" bestaat niet."
    ::msgcat::mcset nl "File &name:" "Bestands&naam:"
    ::msgcat::mcset nl "File &names:" "Bestands&namen:"
    ::msgcat::mcset nl "Files of &type:" "Bestanden van het &type:"
    ::msgcat::mcset nl "Fi&les:" "&Bestanden:"
    ::msgcat::mcset nl "&Filter"
    ::msgcat::mcset nl "Fil&ter:"



    ::msgcat::mcset nl "&Green" "&Groen"
    ::msgcat::mcset nl "Hi" "H\u00e9"
    ::msgcat::mcset nl "Hide Console" "Verberg Console"

    ::msgcat::mcset nl "&Ignore" "&Negeren"
    ::msgcat::mcset nl "Invalid file name \"%1\$s\"." "Ongeldige bestandsnaam \"%1\$s\"."

    ::msgcat::mcset nl "Log Files" "Log Bestanden"
    ::msgcat::mcset nl "&No" "&Nee"
    ::msgcat::mcset nl "&OK"
    ::msgcat::mcset nl "Ok"
    ::msgcat::mcset nl "&Open" "&Openen"
    ::msgcat::mcset nl "Open" "Openen"

    ::msgcat::mcset nl "Open Multiple Files" "Open meerdere bestanden"
    ::msgcat::mcset nl "Paste" "Plakken"
    ::msgcat::mcset nl "Please press %1\$s" "Druk op %1\$s, A.U.B."
    ::msgcat::mcset nl "Please press ok" "Druk op ok, A.U.B."
    ::msgcat::mcset nl "Press Cancel" "Druk op Annuleren"
    ::msgcat::mcset nl "Press Ok" "Druk op Ok"
    ::msgcat::mcset nl "Quit" "Stoppen"
    ::msgcat::mcset nl "&Red" "&Rood"
    ::msgcat::mcset nl "Replace existing file?" "Vervang bestaand bestand?"
    ::msgcat::mcset nl "&Retry" "&Herhalen"

    ::msgcat::mcset nl "&Save" "Op&slaan"
    ::msgcat::mcset nl "Save As" "Opslaan als"
    ::msgcat::mcset nl "Save To Log" "Opslaan naar Log"
    ::msgcat::mcset nl "Select Log File" "Selecteer Log bestand"
    ::msgcat::mcset nl "Select a file to source" "Selecteer bronbestand"
    ::msgcat::mcset nl "&Selection:" "&Selectie:"



    ::msgcat::mcset nl "Skip Messages" "Berichten overslaan"

    ::msgcat::mcset nl "Source..." "Bron..."
    ::msgcat::mcset nl "Tcl Scripts"
    ::msgcat::mcset nl "Tcl for Windows" "Tcl voor Windows"
    ::msgcat::mcset nl "Text Files" "Tekstbestanden"
    ::msgcat::mcset nl "&Yes" "&Ja"
    ::msgcat::mcset nl "abort" "afbreken"
    ::msgcat::mcset nl "abort, retry, ignore, ok, cancel, no, or yes" "afbreken, opnieuw, negeren, ok, annuleren, nee, of ja"
    ::msgcat::mcset nl "abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel" "abortretryignore, ok, okcancel, retrycancel, yesno, of yesnocancel"
    ::msgcat::mcset nl "bad %1\$s value \"%2\$s\": must be %3\$s" "verkeerde %1\$s waarde \"%2\$s\": moet zijn %3\$s"
    ::msgcat::mcset nl "bad file type \"%1\$s\", should be" "verkeerd bestandstype \"%1\$s\", moet zijn"
    ::msgcat::mcset nl "bad option \"%1\$s\": should be %2\$s" "verkeerde optie \"%1\$s\": moet zijn %2\$s"
    ::msgcat::mcset nl "bad window path name \"%1\$s\"" "verkeerde window-padnaam \"%1\$s\""
    ::msgcat::mcset nl "blue" "blauw"
    ::msgcat::mcset nl "can't post %1\$s:  it isn't a descendant of %2\$s (this is a new requirement in Tk versions 3.0 and later)" "kan %1\$s niet verzenden:  het is geen afstammeling van %2\$s (dit is een nieuwe eis in Tk versies 3.0 en later)"
    ::msgcat::mcset nl "cancel" "annuleren"
    ::msgcat::mcset nl "default button index greater than number of buttons specified for tk_dialog" "default knop index is groter dan het aantal knoppen beschikbaar voor tk_dialog"
    ::msgcat::mcset nl "display name to use (current one otherwise)" "te gebruiken schermnaam (anders huidige scherm)"
    ::msgcat::mcset nl "error, info, question, or warning" "error, info, question, of warning"
    ::msgcat::mcset nl "extension"
    ::msgcat::mcset nl "extensions"
    ::msgcat::mcset nl "focus group \"%1\$s\" doesn't exist" "focusgroep \"%1\$s\" bestaat niet"
    ::msgcat::mcset nl "green" "groen"
    ::msgcat::mcset nl "history event %1\$s"
    ::msgcat::mcset nl "ignore" "negeren"
    ::msgcat::mcset nl "invalid default button \"%1\$s\"" "ongeldige default knop \"%1\$s\""
    ::msgcat::mcset nl "macType"
    ::msgcat::mcset nl "macTypes"
    ::msgcat::mcset nl "must specify a background color" "een achtergrondkleur is verplicht"
    ::msgcat::mcset nl "name of the slave interpreter" "naam van de slaaf-interpreter"
    ::msgcat::mcset nl "no winfo screen . nor env(DISPLAY)" "geen winfo scherm . noch env(DISPLAY)"
    ::msgcat::mcset nl "ok"
    ::msgcat::mcset nl "red" "rood"
    ::msgcat::mcset nl "retry" "opnieuw"
    ::msgcat::mcset nl "should contain 5 or 4 elements" "moet 4 of 5 elementen bevatten"
    ::msgcat::mcset nl "spec"
    ::msgcat::mcset nl "tk_chooseDirectory command" "tk_chooseDirectory opdracht"
    ::msgcat::mcset nl "tk_chooseDirectory command, cancel gives null" "tk_chooseDirectory opdracht, annuleren geeft lege waarde"
    ::msgcat::mcset nl "tk_chooseDirectory command, initialdir" "tk_chooseDirectory opdracht, initi\u00eble map"
    ::msgcat::mcset nl "yes" "ja"
}

Changes to library/msgs/pl.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
namespace eval ::tk {
    ::msgcat::mcset pl "&Abort" "&Przerwij"
    ::msgcat::mcset pl "&About..." "O programie..."
    ::msgcat::mcset pl "All Files" "Wszystkie pliki"
    ::msgcat::mcset pl "Application Error" "Błąd w programie"
    ::msgcat::mcset pl "&Apply" "Zastosuj"
    ::msgcat::mcset pl "Bold" "Pogrubienie"
    ::msgcat::mcset pl "Bold Italic" "Pogrubiona kursywa"
    ::msgcat::mcset pl "&Blue" "&Niebieski"
    ::msgcat::mcset pl "Cancel" "Anuluj"
    ::msgcat::mcset pl "&Cancel" "&Anuluj"
    ::msgcat::mcset pl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nie można otworzyć katalogu \"%1\$s\".\nOdmowa dostępu."
    ::msgcat::mcset pl "Choose Directory" "Wybierz katalog"
    ::msgcat::mcset pl "Cl&ear" "&Wyczyść"
    ::msgcat::mcset pl "&Clear Console" "&Wyczyść konsolę"
    ::msgcat::mcset pl "Color" "Kolor"
    ::msgcat::mcset pl "Console" "Konsola"
    ::msgcat::mcset pl "&Copy" "&Kopiuj"
    ::msgcat::mcset pl "Cu&t" "&Wytnij"
    ::msgcat::mcset pl "&Delete" "&Usuń"
    ::msgcat::mcset pl "Details >>" "Szczegóły >>"
    ::msgcat::mcset pl "Directory \"%1\$s\" does not exist." "Katalog \"%1\$s\" nie istnieje."
    ::msgcat::mcset pl "&Directory:" "&Katalog:"
    ::msgcat::mcset pl "&Edit" "&Edytuj"
    ::msgcat::mcset pl "Effects" "Efekty"
    ::msgcat::mcset pl "Error: %1\$s" "Błąd: %1\$s"
    ::msgcat::mcset pl "E&xit" "&Wyjdź"
    ::msgcat::mcset pl "&File" "&Plik"
    ::msgcat::mcset pl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Plik \"%1\$s\" już istnieje.\nCzy chcesz go nadpisać?"
    ::msgcat::mcset pl "File \"%1\$s\" already exists.\n\n" "Plik \"%1\$s\" już istnieje.\n\n"
    ::msgcat::mcset pl "File \"%1\$s\" does not exist." "Plik \"%1\$s\" nie istnieje."
    ::msgcat::mcset pl "File &name:" "Nazwa &pliku:"
    ::msgcat::mcset pl "File &names:" "Nazwy &plików:"
    ::msgcat::mcset pl "Files of &type:" "Pliki &typu:"
    ::msgcat::mcset pl "Fi&les:" "Pli&ki:"
    ::msgcat::mcset pl "&Filter" "&Filtr"
    ::msgcat::mcset pl "Fil&ter:" "&Filtr:"
    ::msgcat::mcset pl "Font" "Czcionka"
    ::msgcat::mcset pl "&Font:" "Czcio&nka:"
    ::msgcat::mcset pl "Font st&yle:" "&Styl czcionki:"
    ::msgcat::mcset pl "&Green" "&Zielony"
    ::msgcat::mcset pl "&Help" "&Pomoc"
    ::msgcat::mcset pl "Hi" "Witaj"
    ::msgcat::mcset pl "&Hide Console" "&Ukryj konsolę"
    ::msgcat::mcset pl "&Ignore" "&Ignoruj"
    ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niewłaściwa nazwa pliku \"%1\$s\"."
    ::msgcat::mcset pl "Italic" "Kursywa"
    ::msgcat::mcset pl "Log Files" "Pliki dziennika"
    ::msgcat::mcset pl "&No" "&Nie"
    ::msgcat::mcset pl "&OK"
    ::msgcat::mcset pl "OK"
    ::msgcat::mcset pl "Ok"
    ::msgcat::mcset pl "Open" "Otwórz"
    ::msgcat::mcset pl "&Open" "&Otwórz"
    ::msgcat::mcset pl "Open Multiple Files" "Otwórz wiele plików"
    ::msgcat::mcset pl "P&aste" "&Wklej"
    ::msgcat::mcset pl "&Quit" "&Zakończ"
    ::msgcat::mcset pl "&Red" "&Czerwony"
    ::msgcat::mcset pl "Regular" "Regularne"
    ::msgcat::mcset pl "Replace existing file?" "Czy zastąpić istniejący plik?"
    ::msgcat::mcset pl "&Retry" "&Ponów"
    ::msgcat::mcset pl "Sample" "Przykład"
    ::msgcat::mcset pl "&Save" "&Zapisz"
    ::msgcat::mcset pl "Save As" "Zapisz jako"
    ::msgcat::mcset pl "Save To Log" "Wpisz do dziennika"
    ::msgcat::mcset pl "Select Log File" "Wybierz plik dziennika"
    ::msgcat::mcset pl "Select a file to source" "Wybierz plik do wykonania"
    ::msgcat::mcset pl "&Selection:" "&Wybór:"
    ::msgcat::mcset pl "&Size:" "&Rozmiar:"
    ::msgcat::mcset pl "Show &Hidden Directories" "Pokaż &ukryte katalogi"
    ::msgcat::mcset pl "Show &Hidden Files and Directories" "Pokaż &ukryte pliki i katalogi"
    ::msgcat::mcset pl "Skip Messages" "Pomiń pozostałe komunikaty"
    ::msgcat::mcset pl "&Source..." "&Kod źródłowy..."
    ::msgcat::mcset pl "Stri&keout" "&Przekreślenie"
    ::msgcat::mcset pl "Tcl Scripts" "Skrypty Tcl"
    ::msgcat::mcset pl "Tcl for Windows" "Tcl dla Windows"
    ::msgcat::mcset pl "Text Files" "Pliki tekstowe"
    ::msgcat::mcset pl "&Underline" "Po&dkreślenie"
    ::msgcat::mcset pl "&Yes" "&Tak"
    ::msgcat::mcset pl "abort" "przerwij"
    ::msgcat::mcset pl "blue" "niebieski"
    ::msgcat::mcset pl "cancel" "anuluj"
    ::msgcat::mcset pl "extension" "rozszerzenie"
    ::msgcat::mcset pl "extensions" "rozszerzenia"
    ::msgcat::mcset pl "green" "zielony"
    ::msgcat::mcset pl "ignore" "ignoruj"
    ::msgcat::mcset pl "ok"
    ::msgcat::mcset pl "red" "czerwony"
    ::msgcat::mcset pl "retry" "ponów"
    ::msgcat::mcset pl "yes" "tak"
}




|
<
<
<

<

|

|
|




|
|



<
|
|

|
|


|




<
<
<



|

|
<


|
|
<
|
|
|

|

<
|
|
<





|
<
<
<
|
|
<



<








<

|


1
2
3
4
5



6

7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32



33
34
35
36
37
38

39
40
41
42

43
44
45
46
47
48

49
50

51
52
53
54
55
56



57
58

59
60
61

62
63
64
65
66
67
68
69

70
71
72
73
namespace eval ::tk {
    ::msgcat::mcset pl "&Abort" "&Przerwij"
    ::msgcat::mcset pl "&About..." "O programie..."
    ::msgcat::mcset pl "All Files" "Wszystkie pliki"
    ::msgcat::mcset pl "Application Error" "B\u0142\u0105d w programie"



    ::msgcat::mcset pl "&Blue" "&Niebieski"

    ::msgcat::mcset pl "&Cancel" "&Anuluj"
    ::msgcat::mcset pl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nie mo\u017cna otworzy\u0107 katalogu \"%1\$s\".\nOdmowa dost\u0119pu."
    ::msgcat::mcset pl "Choose Directory" "Wybierz katalog"
    ::msgcat::mcset pl "Cl&ear" "&Wyczy\u015b\u0107"
    ::msgcat::mcset pl "&Clear Console" "&Wyczy\u015b\u0107 konsol\u0119"
    ::msgcat::mcset pl "Color" "Kolor"
    ::msgcat::mcset pl "Console" "Konsola"
    ::msgcat::mcset pl "&Copy" "&Kopiuj"
    ::msgcat::mcset pl "Cu&t" "&Wytnij"
    ::msgcat::mcset pl "&Delete" "&Usu\u0144"
    ::msgcat::mcset pl "Details >>" "Szczeg\u00f3\u0142y >>"
    ::msgcat::mcset pl "Directory \"%1\$s\" does not exist." "Katalog \"%1\$s\" nie istnieje."
    ::msgcat::mcset pl "&Directory:" "&Katalog:"
    ::msgcat::mcset pl "&Edit" "&Edytuj"

    ::msgcat::mcset pl "Error: %1\$s" "B\u0142\u0105d: %1\$s"
    ::msgcat::mcset pl "E&xit" "&Wyjd\u017a"
    ::msgcat::mcset pl "&File" "&Plik"
    ::msgcat::mcset pl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Plik \"%1\$s\" ju\u017c istnieje.\nCzy chcesz go nadpisa\u0107?"
    ::msgcat::mcset pl "File \"%1\$s\" already exists.\n\n" "Plik \"%1\$s\" ju\u017c istnieje.\n\n"
    ::msgcat::mcset pl "File \"%1\$s\" does not exist." "Plik \"%1\$s\" nie istnieje."
    ::msgcat::mcset pl "File &name:" "Nazwa &pliku:"
    ::msgcat::mcset pl "File &names:" "Nazwy &plik\u00f3w:"
    ::msgcat::mcset pl "Files of &type:" "Pliki &typu:"
    ::msgcat::mcset pl "Fi&les:" "Pli&ki:"
    ::msgcat::mcset pl "&Filter" "&Filtr"
    ::msgcat::mcset pl "Fil&ter:" "&Filtr:"



    ::msgcat::mcset pl "&Green" "&Zielony"
    ::msgcat::mcset pl "&Help" "&Pomoc"
    ::msgcat::mcset pl "Hi" "Witaj"
    ::msgcat::mcset pl "&Hide Console" "&Ukryj konsol\u0119"
    ::msgcat::mcset pl "&Ignore" "&Ignoruj"
    ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niew\u0142a\u015bciwa nazwa pliku \"%1\$s\"."

    ::msgcat::mcset pl "Log Files" "Pliki dziennika"
    ::msgcat::mcset pl "&No" "&Nie"
    ::msgcat::mcset pl "OK" "OK"
    ::msgcat::mcset pl "Ok" "Ok"

    ::msgcat::mcset pl "Open" "Otw\u00f3rz"
    ::msgcat::mcset pl "&Open" "&Otw\u00f3rz"
    ::msgcat::mcset pl "Open Multiple Files" "Otw\u00f3rz wiele plik\u00f3w"
    ::msgcat::mcset pl "P&aste" "&Wklej"
    ::msgcat::mcset pl "&Quit" "&Zako\u0144cz"
    ::msgcat::mcset pl "&Red" "&Czerwony"

    ::msgcat::mcset pl "Replace existing file?" "Czy zast\u0105pi\u0107 istniej\u0105cy plik?"
    ::msgcat::mcset pl "&Retry" "&Pon\u00f3w"

    ::msgcat::mcset pl "&Save" "&Zapisz"
    ::msgcat::mcset pl "Save As" "Zapisz jako"
    ::msgcat::mcset pl "Save To Log" "Wpisz do dziennika"
    ::msgcat::mcset pl "Select Log File" "Wybierz plik dziennika"
    ::msgcat::mcset pl "Select a file to source" "Wybierz plik do wykonania"
    ::msgcat::mcset pl "&Selection:" "&Wyb\u00f3r:"



    ::msgcat::mcset pl "Skip Messages" "Pomi\u0144 pozosta\u0142e komunikaty"
    ::msgcat::mcset pl "&Source..." "&Kod \u017ar\u00f3d\u0142owy..."

    ::msgcat::mcset pl "Tcl Scripts" "Skrypty Tcl"
    ::msgcat::mcset pl "Tcl for Windows" "Tcl dla Windows"
    ::msgcat::mcset pl "Text Files" "Pliki tekstowe"

    ::msgcat::mcset pl "&Yes" "&Tak"
    ::msgcat::mcset pl "abort" "przerwij"
    ::msgcat::mcset pl "blue" "niebieski"
    ::msgcat::mcset pl "cancel" "anuluj"
    ::msgcat::mcset pl "extension" "rozszerzenie"
    ::msgcat::mcset pl "extensions" "rozszerzenia"
    ::msgcat::mcset pl "green" "zielony"
    ::msgcat::mcset pl "ignore" "ignoruj"

    ::msgcat::mcset pl "red" "czerwony"
    ::msgcat::mcset pl "retry" "pon\u00f3w"
    ::msgcat::mcset pl "yes" "tak"
}

Changes to library/msgs/pt.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
namespace eval ::tk {
    ::msgcat::mcset pt "&Abort" "&Abortar"
    ::msgcat::mcset pt "About..." "Sobre ..."
    ::msgcat::mcset pt "All Files" "Todos os arquivos"
    ::msgcat::mcset pt "Application Error" "Erro de aplicação"
    ::msgcat::mcset pt "&Blue" "&Azul"
    ::msgcat::mcset pt "Cancel" "Cancelar"
    ::msgcat::mcset pt "&Cancel" "&Cancelar"
    ::msgcat::mcset pt "Cannot change to the directory \"%1\$s\".\nPermission denied." "Não foi possível mudar para o diretório \"%1\$s\".\nPermissão negada."
    ::msgcat::mcset pt "Choose Directory" "Escolha um diretório"
    ::msgcat::mcset pt "Cl&ear" "Apagar"
    ::msgcat::mcset pt "&Clear Console" "Apagar Console"
    ::msgcat::mcset pt "Color" "Cor"
    ::msgcat::mcset pt "Console"
    ::msgcat::mcset pt "&Copy" "Copiar"
    ::msgcat::mcset pt "Cu&t" "Recortar"
    ::msgcat::mcset pt "&Delete" "Excluir"
    ::msgcat::mcset pt "Details >>" "Detalhes >>"
    ::msgcat::mcset pt "Directory \"%1\$s\" does not exist." "O diretório \"%1\$s\" não existe."


    ::msgcat::mcset pt "&Directory:" "&Diretório:"
    ::msgcat::mcset pt "Error: %1\$s" "Erro: %1\$s"
    ::msgcat::mcset pt "E&xit" "Sair"
    ::msgcat::mcset pt "&File" "Arquivo"
    ::msgcat::mcset pt "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "O arquivo \"%1\$s\" já existe.\nDeseja sobrescreve-lo?"
    ::msgcat::mcset pt "File \"%1\$s\" already exists.\n\n" "O arquivo \"%1\$s\" já existe.\n\n"
    ::msgcat::mcset pt "File \"%1\$s\" does not exist." "Arquivo \"%1\$s\" não existe."
    ::msgcat::mcset pt "File &name:" "&Nome do arquivo:"
    ::msgcat::mcset pt "File &names:" "&Nomes dos arquivos:"
    ::msgcat::mcset pt "Files of &type:" "Arquivos do &tipo:"
    ::msgcat::mcset pt "Fi&les:" "&Arquivos:"
    ::msgcat::mcset pt "&Filter" "&Filtro"
    ::msgcat::mcset pt "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset pt "&Green" "&Verde"
    ::msgcat::mcset pt "Hi" "Oi"
    ::msgcat::mcset pt "&Hide Console" "Ocultar console"
    ::msgcat::mcset pt "&Ignore" "&Ignorar"
    ::msgcat::mcset pt "Invalid file name \"%1\$s\"." "O nome do arquivo é inválido \"%1\$s\"."


    ::msgcat::mcset pt "Log Files" "Arquivos de log"
    ::msgcat::mcset pt "&No" "&Não"
    ::msgcat::mcset pt "&OK"
    ::msgcat::mcset pt "OK"
    ::msgcat::mcset pt "Ok"
    ::msgcat::mcset pt "Open" "Abrir"
    ::msgcat::mcset pt "&Open" "&Abrir"
    ::msgcat::mcset pt "Open Multiple Files" "Abrir múltiplos arquivos"
    ::msgcat::mcset pt "P&aste" "Col&ar"
    ::msgcat::mcset pt "Quit" "Encerrar"
    ::msgcat::mcset pt "&Red" "&Vermelho"
    ::msgcat::mcset pt "Replace existing file?" "Substituir arquivo existente?"
    ::msgcat::mcset pt "&Retry" "Tenta&r novamente"
    ::msgcat::mcset pt "&Save" "&Salvar"
    ::msgcat::mcset pt "Save As" "Salvar como"
    ::msgcat::mcset pt "Save To Log" "Salvar arquivo de log"
    ::msgcat::mcset pt "Select Log File" "Selecionar arquivo de log"
    ::msgcat::mcset pt "Select a file to source" "Selecione um arquivo como fonte"
    ::msgcat::mcset pt "&Selection:" "&Seleção:"
    ::msgcat::mcset pt "Skip Messages" "Omitir as mensagens"
    ::msgcat::mcset pt "&Source..." "&Fonte..."
    ::msgcat::mcset pt "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset pt "Tcl for Windows" "Tcl para Windows"
    ::msgcat::mcset pt "Text Files" "Arquivos de texto"
    ::msgcat::mcset pt "&Yes" "&Sim"
    ::msgcat::mcset pt "abort" "abortar"
    ::msgcat::mcset pt "blue" "azul"
    ::msgcat::mcset pt "cancel" "cancelar"
    ::msgcat::mcset pt "extension" "extensão"
    ::msgcat::mcset pt "extensions" "extensões"
    ::msgcat::mcset pt "green" "verde"
    ::msgcat::mcset pt "ignore" "ignorar"
    ::msgcat::mcset pt "ok"
    ::msgcat::mcset pt "red" "vermelho"
    ::msgcat::mcset pt "retry" "tentar novamente"
    ::msgcat::mcset pt "yes" "sim"
}

|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
<
|
|
>
>
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
<
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15

16
17
18
19


20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
namespace eval ::tk {
    ::msgcat::mcset pt_br "&Abort" "&Abortar"
    ::msgcat::mcset pt_br "About..." "Sobre ..."
    ::msgcat::mcset pt_br "All Files" "Todos os arquivos"
    ::msgcat::mcset pt_br "Application Error" "Erro de aplica\u00e7\u00e3o"
    ::msgcat::mcset pt_br "&Blue" "&Azul"

    ::msgcat::mcset pt_br "&Cancel" "&Cancelar"
    ::msgcat::mcset pt_br "Cannot change to the directory \"%1\$s\".\nPermission denied." "N\u00e3o foi poss\u00edvel mudar para o diret\u00f3rio \"%1\$s\".\nPermiss\u00e3o negada."
    ::msgcat::mcset pt_br "Choose Directory" "Escolha um diret\u00f3rio"
    ::msgcat::mcset pt_br "Clear" "Apagar"
    ::msgcat::mcset pt_br "Color" "Cor"
    ::msgcat::mcset pt_br "Console" "Console"
    ::msgcat::mcset pt_br "Copy" "Copiar"
    ::msgcat::mcset pt_br "Cut" "Recortar"
    ::msgcat::mcset pt_br "Delete" "Excluir"

    ::msgcat::mcset pt_br "Details >>" "Detalhes >>"
    ::msgcat::mcset pt_br "Directory \"%1\$s\" does not exist." "O diret\u00f3rio \"%1\$s\" n\u00e3o existe."
    ::msgcat::mcset pt_br "&Directory:" "&Diret\u00f3rio:"
    ::msgcat::mcset pt_br "Error: %1\$s" "Erro: %1\$s"


    ::msgcat::mcset pt_br "Exit" "Sair"

    ::msgcat::mcset pt_br "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "O arquivo \"%1\$s\" j\u00e1 existe.\nDeseja sobrescreve-lo?"
    ::msgcat::mcset pt_br "File \"%1\$s\" already exists.\n\n" "O arquivo \"%1\$s\" j\u00e1 existe.\n\n"
    ::msgcat::mcset pt_br "File \"%1\$s\" does not exist." "Arquivo \"%1\$s\" n\u00e3o existe."
    ::msgcat::mcset pt_br "File &name:" "&Nome do arquivo:"
    ::msgcat::mcset pt_br "File &names:" "&Nomes dos arquivos:"
    ::msgcat::mcset pt_br "Files of &type:" "Arquivos do &tipo:"
    ::msgcat::mcset pt_br "Fi&les:" "&Arquivos:"
    ::msgcat::mcset pt_br "&Filter" "&Filtro"
    ::msgcat::mcset pt_br "Fil&ter:" "Fil&tro:"
    ::msgcat::mcset pt_br "&Green" "&Verde"
    ::msgcat::mcset pt_br "Hi" "Oi"
    ::msgcat::mcset pt_br "Hide Console" "Ocultar console"
    ::msgcat::mcset pt_br "&Ignore" "&Ignorar"
    ::msgcat::mcset pt_br "Invalid file name \"%1\$s\"." "O nome do arquivo \u00e9 inv\u00e1lido \"%1\$s\"."
    ::msgcat::mcset pt_br "Log Files" "Arquivos de log"
    ::msgcat::mcset pt_br "&No" "&N\u00e3o"
    ::msgcat::mcset pt_br "&OK" "&OK"
    ::msgcat::mcset pt_br "Ok" "Ok"
    ::msgcat::mcset pt_br "Open" "Abrir"
    ::msgcat::mcset pt_br "&Open" "&Abrir"
    ::msgcat::mcset pt_br "Open Multiple Files" "Abrir m\u00faltiplos arquivos"
    ::msgcat::mcset pt_br "Paste" "Colar"
    ::msgcat::mcset pt_br "Quit" "Encerrar"

    ::msgcat::mcset pt_br "&Red" "&Vermelho"


    ::msgcat::mcset pt_br "Replace existing file?" "Substituir arquivo existente?"
    ::msgcat::mcset pt_br "&Retry" "Tenta&r novamente"
    ::msgcat::mcset pt_br "&Save" "&Salvar"
    ::msgcat::mcset pt_br "Save As" "Salvar como"
    ::msgcat::mcset pt_br "Save To Log" "Salvar arquivo de log"
    ::msgcat::mcset pt_br "Select Log File" "Selecionar arquivo de log"
    ::msgcat::mcset pt_br "Select a file to source" "Selecione um arquivo como fonte(source)"
    ::msgcat::mcset pt_br "&Selection:" "&Sele\u00e7\u00e3o:"
    ::msgcat::mcset pt_br "Skip Messages" "Omitir as mensagens"
    ::msgcat::mcset pt_br "Source..." "Source..."
    ::msgcat::mcset pt_br "Tcl Scripts" "Scripts Tcl"
    ::msgcat::mcset pt_br "Tcl for Windows" "Tcl para Windows"
    ::msgcat::mcset pt_br "Text Files" "Arquivos de texto"
    ::msgcat::mcset pt_br "&Yes" "&Sim"
    ::msgcat::mcset pt_br "abort" "abortar"
    ::msgcat::mcset pt_br "blue" "azul"
    ::msgcat::mcset pt_br "cancel" "cancelar"
    ::msgcat::mcset pt_br "extension" "extens\u00e3o"
    ::msgcat::mcset pt_br "extensions" "extens\u00f5es"
    ::msgcat::mcset pt_br "green" "verde"
    ::msgcat::mcset pt_br "ignore" "ignorar"
    ::msgcat::mcset pt_br "ok" "ok"
    ::msgcat::mcset pt_br "red" "vermelho"
    ::msgcat::mcset pt_br "retry" "tentar novamente"
    ::msgcat::mcset pt_br "yes" "sim"
}

Changes to library/msgs/ru.msg.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
namespace eval ::tk {
    ::msgcat::mcset ru "&Abort" "&Отменить"
    ::msgcat::mcset ru "&About..." "Про..."
    ::msgcat::mcset ru "All Files" "Все файлы"
    ::msgcat::mcset ru "Application Error" "Ошибка в программе"
    ::msgcat::mcset ru "&Blue" " &Голубой"
    ::msgcat::mcset ru "Cancel" "От&мена"
    ::msgcat::mcset ru "&Cancel" "От&мена"
    ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \
			"Не могу перейти в каталог \"%1\$s\".\nНедостаточно прав доступа"

    ::msgcat::mcset ru "Choose Directory" "Выберите каталог"
    ::msgcat::mcset ru "Cl&ear" "Очистить"
    ::msgcat::mcset ru "Color" "Цвет"
    ::msgcat::mcset ru "Console" "Консоль"
    ::msgcat::mcset ru "&Copy" "Копировать"
    ::msgcat::mcset ru "Cu&t" "Вырезать"
    ::msgcat::mcset ru "&Delete" "Удалить"
    ::msgcat::mcset ru "Details >>" "Подробнее >>"
    ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "Каталога \"%1\$s\" не существует."
    ::msgcat::mcset ru "&Directory:" "&Каталог:"
    ::msgcat::mcset ru "Error: %1\$s" "Ошибка: %1\$s"
    ::msgcat::mcset ru "E&xit" "Выход"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
			    "Файл \"%1\$s\" уже существует.\nЗаменить его?"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "Файл \"%1\$s\" уже существует.\n\n"
    ::msgcat::mcset ru "File \"%1\$s\" does not exist." "Файл \"%1\$s\" не найден."
    ::msgcat::mcset ru "File &name:" "&Имя файла:"
    ::msgcat::mcset ru "File &names:" "&Имена файлов:"
    ::msgcat::mcset ru "Files of &type:" "&Тип файлов:"
    ::msgcat::mcset ru "Fi&les:" "Фай&лы:"
    ::msgcat::mcset ru "&Filter" "&Фильтр"
    ::msgcat::mcset ru "Fil&ter:" "Филь&тр:"
    ::msgcat::mcset ru "&Green" " &Зеленый"
    ::msgcat::mcset ru "Hi" "Привет"
    ::msgcat::mcset ru "&Hide Console" "Спрятать консоль"
    ::msgcat::mcset ru "&Ignore" "&Игнорировать"
    ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "Неверное имя файла \"%1\$s\"."
    ::msgcat::mcset ru "Log Files" "Файлы журнала"
    ::msgcat::mcset ru "&No" "&Нет"
    ::msgcat::mcset ru "&OK" "&ОК"
    ::msgcat::mcset ru "OK" "ОК"
    ::msgcat::mcset ru "Ok" "Да"
    ::msgcat::mcset ru "Open" "Открыть"
    ::msgcat::mcset ru "&Open" "&Открыть"
    ::msgcat::mcset ru "Open Multiple Files" "Открыть несколько файлов"
    ::msgcat::mcset ru "P&aste" "Вставить"
    ::msgcat::mcset ru "&Quit" "Выход"
    ::msgcat::mcset ru "&Red" " &Красный"
    ::msgcat::mcset ru "Replace existing file?" "Заменить существующий файл?"
    ::msgcat::mcset ru "&Retry" "&Повторить"
    ::msgcat::mcset ru "&Save" "&Сохранить"
    ::msgcat::mcset ru "Save As" "Сохранить как"
    ::msgcat::mcset ru "Save To Log" "Сохранить в журнал"
    ::msgcat::mcset ru "Select Log File" "Выбрать журнал"
    ::msgcat::mcset ru "Select a file to source" "Выберите файл для интерпретации"
    ::msgcat::mcset ru "&Selection:"
    ::msgcat::mcset ru "Skip Messages" "Пропустить сообщения"
    ::msgcat::mcset ru "&Source..." "Интерпретировать файл..."
    ::msgcat::mcset ru "Tcl Scripts" "Программа на языке TCL"
    ::msgcat::mcset ru "Tcl for Windows" "TCL для Windows"
    ::msgcat::mcset ru "Text Files" "Текстовые файлы"
    ::msgcat::mcset ru "&Yes" "&Да"
    ::msgcat::mcset ru "abort" "отмена"
    ::msgcat::mcset ru "blue" " голубой"
    ::msgcat::mcset ru "cancel" "отмена"
    ::msgcat::mcset ru "extension" "расширение"
    ::msgcat::mcset ru "extensions" "расширения"
    ::msgcat::mcset ru "green" " зеленый"
    ::msgcat::mcset ru "ignore" "пропустить"
    ::msgcat::mcset ru "ok" "ок"
    ::msgcat::mcset ru "red" " красный"
    ::msgcat::mcset ru "retry" "повторить"
    ::msgcat::mcset ru "yes" "да"
}


|
|
|
|
|
<
|

<
>
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


1
2
3
4
5
6

7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
namespace eval ::tk {
    ::msgcat::mcset ru "&Abort" "&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c"
    ::msgcat::mcset ru "About..." "\u041f\u0440\u043e..."
    ::msgcat::mcset ru "All Files" "\u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b"
    ::msgcat::mcset ru "Application Error" "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435"
    ::msgcat::mcset ru "&Blue" " &\u0413\u043e\u043b\u0443\u0431\u043e\u0439"

    ::msgcat::mcset ru "&Cancel" "\u041e\u0442&\u043c\u0435\u043d\u0430"
    ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \

			"\u041d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \"%1\$s\".\n\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430"
    ::msgcat::mcset ru "Choose Directory" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433"
    ::msgcat::mcset ru "Clear" "\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c"
    ::msgcat::mcset ru "Color" "\u0426\u0432\u0435\u0442"
    ::msgcat::mcset ru "Console" "\u041a\u043e\u043d\u0441\u043e\u043b\u044c"
    ::msgcat::mcset ru "Copy" "\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c"
    ::msgcat::mcset ru "Cut" "\u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c"
    ::msgcat::mcset ru "Delete" "\u0423\u0434\u0430\u043b\u0438\u0442\u044c"
    ::msgcat::mcset ru "Details >>" "\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 >>"
    ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "\u041a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \"%1\$s\" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442."
    ::msgcat::mcset ru "&Directory:" "&\u041a\u0430\u0442\u0430\u043b\u043e\u0433:"
    ::msgcat::mcset ru "Error: %1\$s" "\u041e\u0448\u0438\u0431\u043a\u0430: %1\$s"
    ::msgcat::mcset ru "Exit" "\u0412\u044b\u0445\u043e\u0434"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
			    "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e?"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\n"
    ::msgcat::mcset ru "File \"%1\$s\" does not exist." "\u0424\u0430\u0439\u043b \"%1\$s\" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d."
    ::msgcat::mcset ru "File &name:" "&\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430:"
    ::msgcat::mcset ru "File &names:" "&\u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:"
    ::msgcat::mcset ru "Files of &type:" "&\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u043e\u0432:"
    ::msgcat::mcset ru "Fi&les:" "\u0424\u0430\u0439&\u043b\u044b:"
    ::msgcat::mcset ru "&Filter" "&\u0424\u0438\u043b\u044c\u0442\u0440"
    ::msgcat::mcset ru "Fil&ter:" "\u0424\u0438\u043b\u044c&\u0442\u0440:"
    ::msgcat::mcset ru "&Green" " &\u0417\u0435\u043b\u0435\u043d\u044b\u0439"
    ::msgcat::mcset ru "Hi" "\u041f\u0440\u0438\u0432\u0435\u0442"
    ::msgcat::mcset ru "Hide Console" "\u0421\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c"
    ::msgcat::mcset ru "&Ignore" "&\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c"
    ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \"%1\$s\"."
    ::msgcat::mcset ru "Log Files" "\u0424\u0430\u0439\u043b\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u0430"
    ::msgcat::mcset ru "&No" "&\u041d\u0435\u0442"
    ::msgcat::mcset ru "&OK" "&\u041e\u041a"

    ::msgcat::mcset ru "Ok" "\u0414\u0430"
    ::msgcat::mcset ru "Open" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c"
    ::msgcat::mcset ru "&Open" "&\u041e\u0442\u043a\u0440\u044b\u0442\u044c"
    ::msgcat::mcset ru "Open Multiple Files" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432"
    ::msgcat::mcset ru "Paste" "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c"
    ::msgcat::mcset ru "Quit" "\u0412\u044b\u0445\u043e\u0434"
    ::msgcat::mcset ru "&Red" " &\u041a\u0440\u0430\u0441\u043d\u044b\u0439"
    ::msgcat::mcset ru "Replace existing file?" "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b?"
    ::msgcat::mcset ru "&Retry" "&\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c"
    ::msgcat::mcset ru "&Save" "&\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c"
    ::msgcat::mcset ru "Save As" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a"
    ::msgcat::mcset ru "Save To Log" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b"
    ::msgcat::mcset ru "Select Log File" "\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b"
    ::msgcat::mcset ru "Select a file to source" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438"
    ::msgcat::mcset ru "&Selection:" "&Selection:"
    ::msgcat::mcset ru "Skip Messages" "\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f"
    ::msgcat::mcset ru "Source..." "\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b..."
    ::msgcat::mcset ru "Tcl Scripts" "\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 TCL"
    ::msgcat::mcset ru "Tcl for Windows" "TCL \u0434\u043b\u044f Windows"
    ::msgcat::mcset ru "Text Files" "\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b"
    ::msgcat::mcset ru "&Yes" "&\u0414\u0430"
    ::msgcat::mcset ru "abort" "\u043e\u0442\u043c\u0435\u043d\u0430"
    ::msgcat::mcset ru "blue" " \u0433\u043e\u043b\u0443\u0431\u043e\u0439"
    ::msgcat::mcset ru "cancel" "\u043e\u0442\u043c\u0435\u043d\u0430"
    ::msgcat::mcset ru "extension" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435"
    ::msgcat::mcset ru "extensions" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f"
    ::msgcat::mcset ru "green" " \u0437\u0435\u043b\u0435\u043d\u044b\u0439"
    ::msgcat::mcset ru "ignore" "\u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c"
    ::msgcat::mcset ru "ok" "\u043e\u043a"
    ::msgcat::mcset ru "red" " \u043a\u0440\u0430\u0441\u043d\u044b\u0439"
    ::msgcat::mcset ru "retry" "\u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c"
    ::msgcat::mcset ru "yes" "\u0434\u0430"
}

Changes to library/msgs/sv.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
namespace eval ::tk {
    ::msgcat::mcset sv "&Abort" "&Avsluta"
    ::msgcat::mcset sv "&About..." "&Om..."
    ::msgcat::mcset sv "All Files" "Samtliga filer"
    ::msgcat::mcset sv "Application Error" "Programfel"
    ::msgcat::mcset sv "&Blue" "&Blå"
    ::msgcat::mcset sv "Cancel" "Avbryt"
    ::msgcat::mcset sv "&Cancel" "&Avbryt"
    ::msgcat::mcset sv "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ej nå mappen \"%1\$s\".\nSaknar rättigheter."
    ::msgcat::mcset sv "Choose Directory" "Välj mapp"
    ::msgcat::mcset sv "Cl&ear" "&Radera"
    ::msgcat::mcset sv "&Clear Console" "&Radera konsollen"
    ::msgcat::mcset sv "Color" "Färg"
    ::msgcat::mcset sv "Console" "Konsoll"
    ::msgcat::mcset sv "&Copy" "&Kopiera"
    ::msgcat::mcset sv "Cu&t" "Klipp u&t"
    ::msgcat::mcset sv "&Delete" "&Radera"
    ::msgcat::mcset sv "Details >>" "Detaljer >>"
    ::msgcat::mcset sv "Directory \"%1\$s\" does not exist." "Mappen \"%1\$s\" finns ej."
    ::msgcat::mcset sv "&Directory:" "&Mapp:"
    ::msgcat::mcset sv "&Edit" "R&edigera"
    ::msgcat::mcset sv "Error: %1\$s" "Fel: %1\$s"
    ::msgcat::mcset sv "E&xit" "&Avsluta"
    ::msgcat::mcset sv "&File" "&Fil"
    ::msgcat::mcset sv "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Filen \"%1\$s\" finns redan.\nVill du skriva över den?"
    ::msgcat::mcset sv "File \"%1\$s\" already exists.\n\n" "Filen \"%1\$s\" finns redan.\n\n"
    ::msgcat::mcset sv "File \"%1\$s\" does not exist." "Filen \"%1\$s\" finns ej."
    ::msgcat::mcset sv "File &name:" "Fil&namn:"
    ::msgcat::mcset sv "File &names:" "Fil&namn:"
    ::msgcat::mcset sv "Files of &type:" "Filer av &typ:"
    ::msgcat::mcset sv "Fi&les:" "Fi&ler:"
    ::msgcat::mcset sv "&Filter"
    ::msgcat::mcset sv "Fil&ter:"
    ::msgcat::mcset sv "&Green" "&Grön"
    ::msgcat::mcset sv "&Help" "&Hjälp"
    ::msgcat::mcset sv "Hi" "Hej"
    ::msgcat::mcset sv "&Hide Console" "&Göm konsollen"
    ::msgcat::mcset sv "&Ignore" "&Ignorera"
    ::msgcat::mcset sv "Invalid file name \"%1\$s\"." "Ogiltigt filnamn \"%1\$s\"."
    ::msgcat::mcset sv "Log Files" "Loggfiler"
    ::msgcat::mcset sv "&No" "&Nej"
    ::msgcat::mcset sv "&OK"
    ::msgcat::mcset sv "OK"
    ::msgcat::mcset sv "Ok"
    ::msgcat::mcset sv "Open" "Öppna"
    ::msgcat::mcset sv "&Open" "&Öppna"
    ::msgcat::mcset sv "Open Multiple Files" "Öppna flera filer"
    ::msgcat::mcset sv "P&aste" "&Klistra in"
    ::msgcat::mcset sv "&Quit" "&Avsluta"
    ::msgcat::mcset sv "&Red" "&Röd"
    ::msgcat::mcset sv "Replace existing file?" "Ersätt existerande fil?"
    ::msgcat::mcset sv "&Retry" "&Försök igen"
    ::msgcat::mcset sv "&Save" "&Spara"
    ::msgcat::mcset sv "Save As" "Spara som"
    ::msgcat::mcset sv "Save To Log" "Spara till logg"
    ::msgcat::mcset sv "Select Log File" "Välj loggfil"
    ::msgcat::mcset sv "Select a file to source" "Välj källfil"
    ::msgcat::mcset sv "&Selection:" "&Val:"
    ::msgcat::mcset sv "Skip Messages" "Hoppa över meddelanden"
    ::msgcat::mcset sv "&Source..." "&Källa..."
    ::msgcat::mcset sv "Tcl Scripts" "Tcl skript"
    ::msgcat::mcset sv "Tcl for Windows" "Tcl för Windows"
    ::msgcat::mcset sv "Text Files" "Textfiler"
    ::msgcat::mcset sv "&Yes" "&Ja"
    ::msgcat::mcset sv "abort" "avbryt"
    ::msgcat::mcset sv "blue" "blå"
    ::msgcat::mcset sv "cancel" "avbryt"
    ::msgcat::mcset sv "extension" "utvidgning"
    ::msgcat::mcset sv "extensions" "utvidgningar"
    ::msgcat::mcset sv "green" "grön"
    ::msgcat::mcset sv "ignore" "ignorera"
    ::msgcat::mcset sv "ok"
    ::msgcat::mcset sv "red" "röd"
    ::msgcat::mcset sv "retry" "försök igen"
    ::msgcat::mcset sv "yes" "ja"
}





|
<

|
|
|

|











|








|
|

|




<


|
|
|


|
|
|



|
|

|
|

|



|



|


|
|


1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
namespace eval ::tk {
    ::msgcat::mcset sv "&Abort" "&Avsluta"
    ::msgcat::mcset sv "&About..." "&Om..."
    ::msgcat::mcset sv "All Files" "Samtliga filer"
    ::msgcat::mcset sv "Application Error" "Programfel"
    ::msgcat::mcset sv "&Blue" "&Bl\u00e5"

    ::msgcat::mcset sv "&Cancel" "&Avbryt"
    ::msgcat::mcset sv "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ej n\u00e5 mappen \"%1\$s\".\nSaknar r\u00e4ttigheter."
    ::msgcat::mcset sv "Choose Directory" "V\u00e4lj mapp"
    ::msgcat::mcset sv "&Clear" "&Radera"
    ::msgcat::mcset sv "&Clear Console" "&Radera konsollen"
    ::msgcat::mcset sv "Color" "F\u00e4rg"
    ::msgcat::mcset sv "Console" "Konsoll"
    ::msgcat::mcset sv "&Copy" "&Kopiera"
    ::msgcat::mcset sv "Cu&t" "Klipp u&t"
    ::msgcat::mcset sv "&Delete" "&Radera"
    ::msgcat::mcset sv "Details >>" "Detaljer >>"
    ::msgcat::mcset sv "Directory \"%1\$s\" does not exist." "Mappen \"%1\$s\" finns ej."
    ::msgcat::mcset sv "&Directory:" "&Mapp:"
    ::msgcat::mcset sv "&Edit" "R&edigera"
    ::msgcat::mcset sv "Error: %1\$s" "Fel: %1\$s"
    ::msgcat::mcset sv "E&xit" "&Avsluta"
    ::msgcat::mcset sv "&File" "&Fil"
    ::msgcat::mcset sv "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Filen \"%1\$s\" finns redan.\nVill du skriva \u00f6ver den?"
    ::msgcat::mcset sv "File \"%1\$s\" already exists.\n\n" "Filen \"%1\$s\" finns redan.\n\n"
    ::msgcat::mcset sv "File \"%1\$s\" does not exist." "Filen \"%1\$s\" finns ej."
    ::msgcat::mcset sv "File &name:" "Fil&namn:"
    ::msgcat::mcset sv "File &names:" "Fil&namn:"
    ::msgcat::mcset sv "Files of &type:" "Filer av &typ:"
    ::msgcat::mcset sv "Fi&les:" "Fi&ler:"
    ::msgcat::mcset sv "&Filter"
    ::msgcat::mcset sv "Fil&ter:"
    ::msgcat::mcset sv "&Green" "&Gr\u00f6n"
    ::msgcat::mcset sv "&Help" "&Hj\u00e4lp"
    ::msgcat::mcset sv "Hi" "Hej"
    ::msgcat::mcset sv "&Hide Console" "&G\u00f6m konsollen"
    ::msgcat::mcset sv "&Ignore" "&Ignorera"
    ::msgcat::mcset sv "Invalid file name \"%1\$s\"." "Ogiltigt filnamn \"%1\$s\"."
    ::msgcat::mcset sv "Log Files" "Loggfiler"
    ::msgcat::mcset sv "&No" "&Nej"

    ::msgcat::mcset sv "OK"
    ::msgcat::mcset sv "Ok"
    ::msgcat::mcset sv "Open" "\u00d6ppna"
    ::msgcat::mcset sv "&Open" "&\u00d6ppna"
    ::msgcat::mcset sv "Open Multiple Files" "\u00d6ppna flera filer"
    ::msgcat::mcset sv "P&aste" "&Klistra in"
    ::msgcat::mcset sv "&Quit" "&Avsluta"
    ::msgcat::mcset sv "&Red" "&R\u00f6d"
    ::msgcat::mcset sv "Replace existing file?" "Ers\u00e4tt existerande fil?"
    ::msgcat::mcset sv "&Retry" "&F\u00f6rs\u00f6k igen"
    ::msgcat::mcset sv "&Save" "&Spara"
    ::msgcat::mcset sv "Save As" "Spara som"
    ::msgcat::mcset sv "Save To Log" "Spara till logg"
    ::msgcat::mcset sv "Select Log File" "V\u00e4lj loggfil"
    ::msgcat::mcset sv "Select a file to source" "V\u00e4lj k\u00e4llfil"
    ::msgcat::mcset sv "&Selection:" "&Val:"
    ::msgcat::mcset sv "Skip Messages" "Hoppa \u00f6ver meddelanden"
    ::msgcat::mcset sv "&Source..." "&K\u00e4lla..."
    ::msgcat::mcset sv "Tcl Scripts" "Tcl skript"
    ::msgcat::mcset sv "Tcl for Windows" "Tcl f\u00f6r Windows"
    ::msgcat::mcset sv "Text Files" "Textfiler"
    ::msgcat::mcset sv "&Yes" "&Ja"
    ::msgcat::mcset sv "abort" "avbryt"
    ::msgcat::mcset sv "blue" "bl\u00e5"
    ::msgcat::mcset sv "cancel" "avbryt"
    ::msgcat::mcset sv "extension" "utvidgning"
    ::msgcat::mcset sv "extensions" "utvidgningar"
    ::msgcat::mcset sv "green" "gr\u00f6n"
    ::msgcat::mcset sv "ignore" "ignorera"
    ::msgcat::mcset sv "ok"
    ::msgcat::mcset sv "red" "r\u00f6d"
    ::msgcat::mcset sv "retry" "f\u00f6rs\u00f6k igen"
    ::msgcat::mcset sv "yes" "ja"
}

Changes to library/obsolete.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# obsolete.tcl --
#
# This file contains obsolete procedures that people really shouldn't
# be using anymore, but which are kept around for backward compatibility.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 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.
#

# The procedures below are here strictly for backward compatibility with
# Tk version 3.6 and earlier.  The procedures are no longer needed, so





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# obsolete.tcl --
#
# This file contains obsolete procedures that people really shouldn't
# be using anymore, but which are kept around for backward compatibility.
#
# Copyright (c) 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.
#

# The procedures below are here strictly for backward compatibility with
# Tk version 3.6 and earlier.  The procedures are no longer needed, so
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    if {[tk windowingsystem] ne "aqua"} {
	option add *Listbox.borderWidth		2 $prio; # 1
    }
    if {[tk windowingsystem] eq "x11"} {
	option add *Listbox.selectBorderWidth	1 $prio; # 0
    }
    # Remove focus into Listbox added for 8.5
    bind Listbox <Button-1> {
	if {[winfo exists %W]} {
	    tk::ListboxBeginSelect %W [%W index @%x,%y]
	}
    }
}

proc ::tk::classic::restore_menu {args} {







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    if {[tk windowingsystem] ne "aqua"} {
	option add *Listbox.borderWidth		2 $prio; # 1
    }
    if {[tk windowingsystem] eq "x11"} {
	option add *Listbox.selectBorderWidth	1 $prio; # 0
    }
    # Remove focus into Listbox added for 8.5
    bind Listbox <1> {
	if {[winfo exists %W]} {
	    tk::ListboxBeginSelect %W [%W index @%x,%y]
	}
    }
}

proc ::tk::classic::restore_menu {args} {

Changes to library/optMenu.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# optMenu.tcl --
#
# This file defines the procedure tk_optionMenu, which creates
# an option button and its associated menu.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 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.
#

# ::tk_optionMenu --
# This procedure creates an option button named $w and an associated





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# optMenu.tcl --
#
# This file defines the procedure tk_optionMenu, which creates
# an option button and its associated menu.
#
# Copyright (c) 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.
#

# ::tk_optionMenu --
# This procedure creates an option button named $w and an associated

Changes to library/palette.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
# palette.tcl --
#
# This file contains procedures that change the color palette used
# by Tk.
#
# Copyright © 1995-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.
#

# ::tk_setPalette --
# Changes the default color scheme for a Tk application by setting





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# palette.tcl --
#
# This file contains procedures that change the color palette used
# by Tk.
#
# Copyright (c) 1995-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.
#

# ::tk_setPalette --
# Changes the default color scheme for a Tk application by setting
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

    if {[llength $args] == 1} {
	set new(background) [lindex $args 0]
    } else {
	array set new $args
    }
    if {![info exists new(background)]} {
	return -code error -errorcode {TK SET_PALETTE BACKGROUND} \
	    "must specify a background color"
    }
    set bg [winfo rgb . $new(background)]
    if {![info exists new(foreground)]} {
	# Note that the range of each value in the triple returned by
	# [winfo rgb] is 0-65535, and your eyes are more sensitive to
	# green than to red, and more to red than to blue.
	foreach {r g b} $bg {break}







<
|







32
33
34
35
36
37
38

39
40
41
42
43
44
45
46

    if {[llength $args] == 1} {
	set new(background) [lindex $args 0]
    } else {
	array set new $args
    }
    if {![info exists new(background)]} {

	error "must specify a background color"
    }
    set bg [winfo rgb . $new(background)]
    if {![info exists new(foreground)]} {
	# Note that the range of each value in the triple returned by
	# [winfo rgb] is 0-65535, and your eyes are more sensitive to
	# green than to red, and more to red than to blue.
	foreach {r g b} $bg {break}
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    if {![info exists new(selectBackground)]} {
	set new(selectBackground) $darkerBg
    }
    if {![info exists new(troughColor)]} {
	set new(troughColor) $darkerBg
    }

    # let's make one of each of the widgets so we know what the
    # defaults are currently for this platform.
    toplevel .___tk_set_palette
    wm withdraw .___tk_set_palette
    foreach q {
	button canvas checkbutton entry frame label labelframe
	listbox menubutton menu message radiobutton scale scrollbar
	spinbox text
    } {
	$q .___tk_set_palette.$q
    }

    # Walk the widget hierarchy, recoloring all existing windows.
    # The option database must be set according to what we do here,
    # but it breaks things if we set things in the database while
    # we are changing colors...so, ::tk::RecolorTree now returns the
    # option database changes that need to be made, and they
    # need to be evalled here to take effect.
    # We have to walk the whole widget tree instead of just
    # relying on the widgets we've created above to do the work
    # because different extensions may provide other kinds
    # of widgets that we don't currently know about, so we'll
    # walk the whole hierarchy just in case.

    eval [tk::RecolorTree . new]








|












|
|



|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    if {![info exists new(selectBackground)]} {
	set new(selectBackground) $darkerBg
    }
    if {![info exists new(troughColor)]} {
	set new(troughColor) $darkerBg
    }

    # let's make one of each of the widgets so we know what the 
    # defaults are currently for this platform.
    toplevel .___tk_set_palette
    wm withdraw .___tk_set_palette
    foreach q {
	button canvas checkbutton entry frame label labelframe
	listbox menubutton menu message radiobutton scale scrollbar
	spinbox text
    } {
	$q .___tk_set_palette.$q
    }

    # Walk the widget hierarchy, recoloring all existing windows.
    # The option database must be set according to what we do here, 
    # but it breaks things if we set things in the database while 
    # we are changing colors...so, ::tk::RecolorTree now returns the
    # option database changes that need to be made, and they
    # need to be evalled here to take effect.
    # We have to walk the whole widget tree instead of just 
    # relying on the widgets we've created above to do the work
    # because different extensions may provide other kinds
    # of widgets that we don't currently know about, so we'll
    # walk the whole hierarchy just in case.

    eval [tk::RecolorTree . new]

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

    array set ::tk::Palette [array get new]
}

# ::tk::RecolorTree --
# This procedure changes the colors in a window and all of its
# descendants, according to information provided by the colors
# argument. This looks at the defaults provided by the option
# database, if it exists, and if not, then it looks at the default
# value of the widget itself.
#
# Arguments:
# w -			The name of a window.  This window and all its
#			descendants are recolored.
# colors -		The name of an array variable in the caller,







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

    array set ::tk::Palette [array get new]
}

# ::tk::RecolorTree --
# This procedure changes the colors in a window and all of its
# descendants, according to information provided by the colors
# argument. This looks at the defaults provided by the option 
# database, if it exists, and if not, then it looks at the default
# value of the widget itself.
#
# Arguments:
# w -			The name of a window.  This window and all its
#			descendants are recolored.
# colors -		The name of an array variable in the caller,
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224


225


226
227
228
229
230
231
232
233
234
235

# ::tk::Darken --
# Given a color name, computes a new color value that darkens (or
# brightens) the given color by a given percent.
#
# Arguments:
# color -	Name of starting color.
# percent -	Integer telling how much to brighten or darken as a
#		percent: 50 means darken by 50%, 110 means brighten
#		by 10%.

proc ::tk::Darken {color percent} {
    if {$percent < 0} {
        return #000000
    } elseif {$percent > 200} {
        return #ffffff
    } elseif {$percent <= 100} {
        lassign [winfo rgb . $color] r g b
        set r [expr {($r/256)*$percent/100}]
        set g [expr {($g/256)*$percent/100}]
        set b [expr {($b/256)*$percent/100}]


    } elseif {$percent > 100} {
        lassign [winfo rgb . $color] r g b
        set r [expr {255 - ((65535-$r)/256)*(200-$percent)/100}]


        set g [expr {255 - ((65535-$g)/256)*(200-$percent)/100}]


        set b [expr {255 - ((65535-$b)/256)*(200-$percent)/100}]
    }
    return [format #%02x%02x%02x $r $g $b]
}

# ::tk_bisque --
# Reset the Tk color palette to the old "bisque" colors.
#
# Arguments:
# None.







|




<
<
<
<
<
|
|
|
|
>
>
|
<
|
>
>
|
>
>
|

|







200
201
202
203
204
205
206
207
208
209
210
211





212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

# ::tk::Darken --
# Given a color name, computes a new color value that darkens (or
# brightens) the given color by a given percent.
#
# Arguments:
# color -	Name of starting color.
# perecent -	Integer telling how much to brighten or darken as a
#		percent: 50 means darken by 50%, 110 means brighten
#		by 10%.

proc ::tk::Darken {color percent} {





    foreach {red green blue} [winfo rgb . $color] {
	set red [expr {($red/256)*$percent/100}]
	set green [expr {($green/256)*$percent/100}]
	set blue [expr {($blue/256)*$percent/100}]
	break
    }
    if {$red > 255} {

	set red 255
    }
    if {$green > 255} {
	set green 255
    }
    if {$blue > 255} {
	set blue 255
    }
    return [format "#%02x%02x%02x" $red $green $blue]
}

# ::tk_bisque --
# Reset the Tk color palette to the old "bisque" colors.
#
# Arguments:
# None.

Changes to library/safetk.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93

94
95
96
97
98
99
100
101
102
# safetk.tcl --
#
# Support procs to use Tk in safe interpreters.
#
# Copyright © 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 safetk.n for documentation

#
#
# Note: It is now ok to let untrusted code being executed
#       between the creation of the interp and the actual loading
#       of Tk in that interp because the C side Tk_Init will
#       now look up the parent interp and ask its safe::TkInit
#       for the actual parameters to use for it's initialization (if allowed),
#       not relying on the child state.
#

# We use opt (optional arguments parsing)
package require opt 0.4.1;

namespace eval ::safe {

    # counter for safe toplevels
    variable tkSafeId 0
}

#
# tkInterpInit : prepare the child interpreter for tk loading
#                most of the real job is done by loadTk
# returns the child name (tkInterpInit does)
#
proc ::safe::tkInterpInit {child argv} {
    global env tk_library

    # We have to make sure that the tk_library variable is normalized.
    set tk_library [file normalize $tk_library]

    # Clear Tk's access for that interp (path).
    allowTk $child $argv

    # Ensure tk_library and subdirs (eg, ttk) are on the access path
    ::interp eval $child [list set tk_library [::safe::interpAddToAccessPath $child $tk_library]]
    foreach subdir [::safe::AddSubDirs [list $tk_library]] {
	::safe::interpAddToAccessPath $child $subdir
    }
    return $child
}


# tkInterpLoadTk:
# Do additional configuration as needed (calling tkInterpInit)
# and actually load Tk into the child.
#
# Either contained in the specified windowId (-use) or
# creating a decorated toplevel for it.

# empty definition for auto_mkIndex
proc ::safe::loadTk {} {}

::tcl::OptProc ::safe::loadTk {
    {child -interp "name of the child interpreter"}
    {-use  -windowId {} "window Id to use (new toplevel otherwise)"}
    {-display -displayName {} "display name to use (current one otherwise)"}
} {
    set displayGiven [::tcl::OptProcArgGiven "-display"]
    if {!$displayGiven} {
	# Try to get the current display from "."
	# (which might not exist if the parent is tk-less)
	if {[catch {set display [winfo screen .]}]} {
	    if {[info exists ::env(DISPLAY)]} {
		set display $::env(DISPLAY)
	    } else {
		Log $child "no winfo screen . nor env(DISPLAY)" WARNING
		set display ":0.0"
	    }
	}
    }

    # Get state for access to the cleanupHook.
    namespace upvar ::safe S$child state

    if {![::tcl::OptProcArgGiven "-use"]} {
	# create a decorated toplevel
	lassign [tkTopLevel $child $display] w use

	# set our delete hook (child arg is added by interpDelete)
	# to clean up both window related code and tkInit(child)
	set state(cleanupHook) [list tkDelete {} $w]

    } else {

	# set our delete hook (child arg is added by interpDelete)
	# to clean up tkInit(child)
	set state(cleanupHook) [list disallowTk]

	# Let's be nice and also accept tk window names instead of ids
	if {[string match ".*" $use]} {
	    set windowName $use
	    set use [winfo id $windowName]
	    set nDisplay [winfo screen $windowName]




|











|

|












|

|

|






|


|

|

|





|








|






|




|






|



|

|
|

>

>
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# safetk.tcl --
#
# Support procs to use Tk in safe interpreters.
#
# 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 safetk.n for documentation

#
#
# Note: It is now ok to let untrusted code being executed
#       between the creation of the interp and the actual loading
#       of Tk in that interp because the C side Tk_Init will
#       now look up the master interp and ask its safe::TkInit
#       for the actual parameters to use for it's initialization (if allowed),
#       not relying on the slave state.
#

# We use opt (optional arguments parsing)
package require opt 0.4.1;

namespace eval ::safe {

    # counter for safe toplevels
    variable tkSafeId 0
}

#
# tkInterpInit : prepare the slave interpreter for tk loading
#                most of the real job is done by loadTk
# returns the slave name (tkInterpInit does)
#
proc ::safe::tkInterpInit {slave argv} {
    global env tk_library

    # We have to make sure that the tk_library variable is normalized.
    set tk_library [file normalize $tk_library]

    # Clear Tk's access for that interp (path).
    allowTk $slave $argv

    # Ensure tk_library and subdirs (eg, ttk) are on the access path
    ::interp eval $slave [list set tk_library [::safe::interpAddToAccessPath $slave $tk_library]]
    foreach subdir [::safe::AddSubDirs [list $tk_library]] {
	::safe::interpAddToAccessPath $slave $subdir
    }
    return $slave
}


# tkInterpLoadTk:
# Do additional configuration as needed (calling tkInterpInit)
# and actually load Tk into the slave.
#
# Either contained in the specified windowId (-use) or
# creating a decorated toplevel for it.

# empty definition for auto_mkIndex
proc ::safe::loadTk {} {}

::tcl::OptProc ::safe::loadTk {
    {slave -interp "name of the slave interpreter"}
    {-use  -windowId {} "window Id to use (new toplevel otherwise)"}
    {-display -displayName {} "display name to use (current one otherwise)"}
} {
    set displayGiven [::tcl::OptProcArgGiven "-display"]
    if {!$displayGiven} {
	# Try to get the current display from "."
	# (which might not exist if the master is tk-less)
	if {[catch {set display [winfo screen .]}]} {
	    if {[info exists ::env(DISPLAY)]} {
		set display $::env(DISPLAY)
	    } else {
		Log $slave "no winfo screen . nor env(DISPLAY)" WARNING
		set display ":0.0"
	    }
	}
    }

    # Get state for access to the cleanupHook.
    namespace upvar ::safe S$slave state

    if {![::tcl::OptProcArgGiven "-use"]} {
	# create a decorated toplevel
	::tcl::Lassign [tkTopLevel $slave $display] w use

	# set our delete hook (slave arg is added by interpDelete)
	# to clean up both window related code and tkInit(slave)
	set state(cleanupHook) [list tkDelete {} $w]

    } else {

	# set our delete hook (slave arg is added by interpDelete)
	# to clean up tkInit(slave)
	set state(cleanupHook) [list disallowTk]

	# Let's be nice and also accept tk window names instead of ids
	if {[string match ".*" $use]} {
	    set windowName $use
	    set use [winfo id $windowName]
	    set nDisplay [winfo screen $windowName]
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
	    } else {
		# Can't have a better one
		set nDisplay $display
	    }
	}
	if {$nDisplay ne $display} {
	    if {$displayGiven} {
		return -code error -errorcode {TK DISPLAY SAFE} \
		    "conflicting -display $display and -use $use -> $nDisplay"

	    } else {
		set display $nDisplay
	    }
	}
    }

    # Prepares the child for tk with those parameters
    tkInterpInit $child [list "-use" $use "-display" $display]

    load {} Tk $child

    return $child
}

proc ::safe::TkInit {interpPath} {
    variable tkInit
    if {[info exists tkInit($interpPath)]} {
	set value $tkInit($interpPath)
	Log $interpPath "TkInit called, returning \"$value\"" NOTICE
	return $value
    } else {
	Log $interpPath "TkInit called for interp with clearance:\
		preventing Tk init" ERROR
	return -code error -errorcode {TK SAFE PERMISSION} "not allowed"
    }
}

# safe::allowTk --
#
#	Set tkInit(interpPath) to allow Tk to be initialized in
#	safe::TkInit.
#
# Arguments:
#	interpPath	child interpreter handle
#	argv		arguments passed to safe::TkInterpInit
#
# Results:
#	none.

proc ::safe::allowTk {interpPath argv} {
    variable tkInit
    set tkInit($interpPath) $argv
    return
}


# safe::disallowTk --
#
#	Unset tkInit(interpPath) to disallow Tk from getting initialized
#	in safe::TkInit.
#
# Arguments:
#	interpPath	child interpreter handle
#
# Results:
#	none.

proc ::safe::disallowTk {interpPath} {
    variable tkInit
    # This can already be deleted by the DeleteHook of the interp
    if {[info exists tkInit($interpPath)]} {
	unset tkInit($interpPath)
    }
    return
}


# safe::tkDelete --
#
#	Clean up the window associated with the interp being deleted.
#
# Arguments:
#	interpPath	child interpreter handle
#
# Results:
#	none.

proc ::safe::tkDelete {W window child} {

    # we are going to be called for each widget... skip untill it's
    # top level

    Log $child "Called tkDelete $W $window" NOTICE
    if {[::interp exists $child]} {
	if {[catch {::safe::interpDelete $child} msg]} {
	    Log $child "Deletion error : $msg"
	}
    }
    if {[winfo exists $window]} {
	Log $child "Destroy toplevel $window" NOTICE
	destroy $window
    }

    # clean up tkInit(child)
    disallowTk $child
    return
}

proc ::safe::tkTopLevel {child display} {
    variable tkSafeId
    incr tkSafeId
    set w ".safe$tkSafeId"
    if {[catch {toplevel $w -screen $display -class SafeTk} msg]} {
	return -code error -errorcode {TK TOPLEVEL SAFE} \
	    "Unable to create toplevel for \"$child\" ($msg)"

    }
    Log $child "New toplevel $w" NOTICE

    set msg "Untrusted Tcl applet ($child)"
    wm title $w $msg

    # Control frame (we must create a style for it)
    ttk::style layout TWarningFrame {WarningFrame.border -sticky nswe}
    ttk::style configure TWarningFrame -background red

    set wc $w.fc
    ttk::frame $wc -relief ridge -borderwidth 4 -style TWarningFrame

    # We will destroy the interp when the window is destroyed
    bindtags $wc [concat Safe$wc [bindtags $wc]]
    bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $child]

    ttk::label $wc.l -text $msg -anchor w

    # We want the button to be the last visible item
    # (so be packed first) and at the right and not resizing horizontally

    # frame the button so it does not expand horizontally
    # but still have the default background instead of red one from the parent
    ttk::frame  $wc.fb -borderwidth 0
    ttk::button $wc.fb.b -text "Delete" \
	    -command [list ::safe::tkDelete $w $w $child]
    pack $wc.fb.b -side right -fill both
    pack $wc.fb -side right -fill both -expand 1
    pack $wc.l -side left -fill both -expand 1 -ipady 2
    pack $wc -side bottom -fill x

    # Container frame
    frame $w.c -container 1
    pack $w.c -fill both -expand 1

    # return both the toplevel window name and the id to use for embedding
    list $w [winfo id $w.c]
}







<
|
>






|
|

|

|











|









|


















|



















|




|




|
|
|
|



|



|
|



|




<
|
>

|

|











|










|












112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
	    } else {
		# Can't have a better one
		set nDisplay $display
	    }
	}
	if {$nDisplay ne $display} {
	    if {$displayGiven} {

		error "conflicting -display $display and -use\
			$use -> $nDisplay"
	    } else {
		set display $nDisplay
	    }
	}
    }

    # Prepares the slave for tk with those parameters
    tkInterpInit $slave [list "-use" $use "-display" $display]

    load {} Tk $slave

    return $slave
}

proc ::safe::TkInit {interpPath} {
    variable tkInit
    if {[info exists tkInit($interpPath)]} {
	set value $tkInit($interpPath)
	Log $interpPath "TkInit called, returning \"$value\"" NOTICE
	return $value
    } else {
	Log $interpPath "TkInit called for interp with clearance:\
		preventing Tk init" ERROR
	error "not allowed"
    }
}

# safe::allowTk --
#
#	Set tkInit(interpPath) to allow Tk to be initialized in
#	safe::TkInit.
#
# Arguments:
#	interpPath	slave interpreter handle
#	argv		arguments passed to safe::TkInterpInit
#
# Results:
#	none.

proc ::safe::allowTk {interpPath argv} {
    variable tkInit
    set tkInit($interpPath) $argv
    return
}


# safe::disallowTk --
#
#	Unset tkInit(interpPath) to disallow Tk from getting initialized
#	in safe::TkInit.
#
# Arguments:
#	interpPath	slave interpreter handle
#
# Results:
#	none.

proc ::safe::disallowTk {interpPath} {
    variable tkInit
    # This can already be deleted by the DeleteHook of the interp
    if {[info exists tkInit($interpPath)]} {
	unset tkInit($interpPath)
    }
    return
}


# safe::tkDelete --
#
#	Clean up the window associated with the interp being deleted.
#
# Arguments:
#	interpPath	slave interpreter handle
#
# Results:
#	none.

proc ::safe::tkDelete {W window slave} {

    # we are going to be called for each widget... skip untill it's
    # top level

    Log $slave "Called tkDelete $W $window" NOTICE
    if {[::interp exists $slave]} {
	if {[catch {::safe::interpDelete $slave} msg]} {
	    Log $slave "Deletion error : $msg"
	}
    }
    if {[winfo exists $window]} {
	Log $slave "Destroy toplevel $window" NOTICE
	destroy $window
    }

    # clean up tkInit(slave)
    disallowTk $slave
    return
}

proc ::safe::tkTopLevel {slave display} {
    variable tkSafeId
    incr tkSafeId
    set w ".safe$tkSafeId"
    if {[catch {toplevel $w -screen $display -class SafeTk} msg]} {

	return -code error "Unable to create toplevel for\
		safe slave \"$slave\" ($msg)"
    }
    Log $slave "New toplevel $w" NOTICE

    set msg "Untrusted Tcl applet ($slave)"
    wm title $w $msg

    # Control frame (we must create a style for it)
    ttk::style layout TWarningFrame {WarningFrame.border -sticky nswe}
    ttk::style configure TWarningFrame -background red

    set wc $w.fc
    ttk::frame $wc -relief ridge -borderwidth 4 -style TWarningFrame

    # We will destroy the interp when the window is destroyed
    bindtags $wc [concat Safe$wc [bindtags $wc]]
    bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $slave]

    ttk::label $wc.l -text $msg -anchor w

    # We want the button to be the last visible item
    # (so be packed first) and at the right and not resizing horizontally

    # frame the button so it does not expand horizontally
    # but still have the default background instead of red one from the parent
    ttk::frame  $wc.fb -borderwidth 0
    ttk::button $wc.fb.b -text "Delete" \
	    -command [list ::safe::tkDelete $w $w $slave]
    pack $wc.fb.b -side right -fill both
    pack $wc.fb -side right -fill both -expand 1
    pack $wc.l -side left -fill both -expand 1 -ipady 2
    pack $wc -side bottom -fill x

    # Container frame
    frame $w.c -container 1
    pack $w.c -fill both -expand 1

    # return both the toplevel window name and the id to use for embedding
    list $w [winfo id $w.c]
}

Changes to library/scale.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# scale.tcl --
#
# This file defines the default bindings for Tk scale widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 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.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for entries.





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# scale.tcl --
#
# This file defines the default bindings for Tk scale widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright (c) 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.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for entries.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62








63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    if {$tk_strictMotif} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    if {[%W cget -state] eq "active"} {
	%W configure -state normal
    }
}
bind Scale <Button-1> {
    tk::ScaleButtonDown %W %x %y
}
bind Scale <B1-Motion> {
    tk::ScaleDrag %W %x %y
}
bind Scale <B1-Leave> { }
bind Scale <B1-Enter> { }
bind Scale <ButtonRelease-1> {
    tk::CancelRepeat
    tk::ScaleEndDrag %W
    tk::ScaleActivate %W %x %y
}
bind Scale <Button-2> {
    tk::ScaleButton2Down %W %x %y
}
bind Scale <B2-Motion> {
    tk::ScaleDrag %W %x %y
}
bind Scale <B2-Leave> { }
bind Scale <B2-Enter> { }
bind Scale <ButtonRelease-2> {
    tk::CancelRepeat
    tk::ScaleEndDrag %W
    tk::ScaleActivate %W %x %y
}








bind Scale <Control-Button-1> {
    tk::ScaleControlPress %W %x %y
}
bind Scale <<PrevLine>> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <<NextLine>> {
    tk::ScaleIncrement %W down little noRepeat
}
bind Scale <<PrevChar>> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <<NextChar>> {
    tk::ScaleIncrement %W down little noRepeat
}
bind Scale <<PrevPara>> {
    tk::ScaleIncrement %W up big noRepeat
}
bind Scale <<NextPara>> {
    tk::ScaleIncrement %W down big noRepeat
}
bind Scale <<PrevWord>> {
    tk::ScaleIncrement %W up big noRepeat
}
bind Scale <<NextWord>> {
    tk::ScaleIncrement %W down big noRepeat
}
bind Scale <<LineStart>> {
    %W set [%W cget -from]
}
bind Scale <<LineEnd>> {
    %W set [%W cget -to]
}

# ::tk::ScaleActivate --
# This procedure is invoked to check a given x-y position in the
# scale and activate the slider if the x-y position falls within
# the slider.







|












|












>
>
>
>
>
>
>
>
|


|


|


|


|


|


|


|


|


|


|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    if {$tk_strictMotif} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    if {[%W cget -state] eq "active"} {
	%W configure -state normal
    }
}
bind Scale <1> {
    tk::ScaleButtonDown %W %x %y
}
bind Scale <B1-Motion> {
    tk::ScaleDrag %W %x %y
}
bind Scale <B1-Leave> { }
bind Scale <B1-Enter> { }
bind Scale <ButtonRelease-1> {
    tk::CancelRepeat
    tk::ScaleEndDrag %W
    tk::ScaleActivate %W %x %y
}
bind Scale <2> {
    tk::ScaleButton2Down %W %x %y
}
bind Scale <B2-Motion> {
    tk::ScaleDrag %W %x %y
}
bind Scale <B2-Leave> { }
bind Scale <B2-Enter> { }
bind Scale <ButtonRelease-2> {
    tk::CancelRepeat
    tk::ScaleEndDrag %W
    tk::ScaleActivate %W %x %y
}
if {[tk windowingsystem] eq "win32"} {
    # On Windows do the same with button 3, as that is the right mouse button
    bind Scale <3>		[bind Scale <2>]
    bind Scale <B3-Motion>	[bind Scale <B2-Motion>]
    bind Scale <B3-Leave>	[bind Scale <B2-Leave>]
    bind Scale <B3-Enter>	[bind Scale <B2-Enter>]
    bind Scale <ButtonRelease-3> [bind Scale <ButtonRelease-2>]
}
bind Scale <Control-1> {
    tk::ScaleControlPress %W %x %y
}
bind Scale <Up> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <Down> {
    tk::ScaleIncrement %W down little noRepeat
}
bind Scale <Left> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <Right> {
    tk::ScaleIncrement %W down little noRepeat
}
bind Scale <Control-Up> {
    tk::ScaleIncrement %W up big noRepeat
}
bind Scale <Control-Down> {
    tk::ScaleIncrement %W down big noRepeat
}
bind Scale <Control-Left> {
    tk::ScaleIncrement %W up big noRepeat
}
bind Scale <Control-Right> {
    tk::ScaleIncrement %W down big noRepeat
}
bind Scale <Home> {
    %W set [%W cget -from]
}
bind Scale <End> {
    %W set [%W cget -to]
}

# ::tk::ScaleActivate --
# This procedure is invoked to check a given x-y position in the
# scale and activate the slider if the x-y position falls within
# the slider.

Changes to library/scrlbar.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# scrlbar.tcl --
#
# This file defines the default bindings for Tk scrollbar widgets.
# It also provides procedures that help in implementing the bindings.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-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.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for scrollbars.





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# scrlbar.tcl --
#
# This file defines the default bindings for Tk scrollbar widgets.
# It also provides procedures that help in implementing the bindings.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-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.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for scrollbars.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130



131
132



133
134




135



136
137
138
139
140
141
142
143
144
145

bind Scrollbar <Leave> {
    if {$tk_strictMotif && [info exists tk::Priv(activeBg)]} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    %W activate {}
}
bind Scrollbar <Button-1> {
    tk::ScrollButtonDown %W %x %y
}
bind Scrollbar <B1-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <B1-B2-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <ButtonRelease-1> {
    tk::ScrollButtonUp %W %x %y
}
bind Scrollbar <B1-Leave> {
    # Prevents <Leave> binding from being invoked.
}
bind Scrollbar <B1-Enter> {
    # Prevents <Enter> binding from being invoked.
}
bind Scrollbar <Button-2> {
    tk::ScrollButton2Down %W %x %y
}
bind Scrollbar <B1-Button-2> {
    # Do nothing, since button 1 is already down.
}
bind Scrollbar <B2-Button-1> {
    # Do nothing, since button 2 is already down.
}
bind Scrollbar <B2-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <ButtonRelease-2> {
    tk::ScrollButtonUp %W %x %y
}
bind Scrollbar <B1-ButtonRelease-2> {
    # Do nothing:  B1 release will handle it.
}
bind Scrollbar <B2-ButtonRelease-1> {
    # Do nothing:  B2 release will handle it.
}
bind Scrollbar <B2-Leave> {
    # Prevents <Leave> binding from being invoked.
}
bind Scrollbar <B2-Enter> {
    # Prevents <Enter> binding from being invoked.
}
bind Scrollbar <Control-Button-1> {
    tk::ScrollTopBottom %W %x %y
}
bind Scrollbar <Control-Button-2> {
    tk::ScrollTopBottom %W %x %y
}

bind Scrollbar <<PrevLine>> {
    tk::ScrollByUnits %W v -1
}
bind Scrollbar <<NextLine>> {
    tk::ScrollByUnits %W v 1
}
bind Scrollbar <<PrevPara>> {
    tk::ScrollByPages %W v -1
}
bind Scrollbar <<NextPara>> {
    tk::ScrollByPages %W v 1
}
bind Scrollbar <<PrevChar>> {
    tk::ScrollByUnits %W h -1
}
bind Scrollbar <<NextChar>> {
    tk::ScrollByUnits %W h 1
}
bind Scrollbar <<PrevWord>> {
    tk::ScrollByPages %W h -1
}
bind Scrollbar <<NextWord>> {
    tk::ScrollByPages %W h 1
}
bind Scrollbar <Prior> {
    tk::ScrollByPages %W hv -1
}
bind Scrollbar <Next> {
    tk::ScrollByPages %W hv 1
}
bind Scrollbar <<LineStart>> {
    tk::ScrollToPos %W 0
}
bind Scrollbar <<LineEnd>> {
    tk::ScrollToPos %W 1
}
}




bind Scrollbar <MouseWheel> {



    tk::ScrollByUnits %W hv %D -30.0
}




bind Scrollbar <Option-MouseWheel> {



    tk::ScrollByUnits %W hv %D -3.0
}

# tk::ScrollButtonDown --
# This procedure is invoked when a button is pressed in a scrollbar.
# It changes the way the scrollbar is displayed and takes actions
# depending on where the mouse is.
#
# Arguments:
# w -		The scrollbar widget.







|

















|


|


|




















|


|



|


|


|


|


|


|


|


|








|


|



>
>
>
|
|
>
>
>
|
|
>
>
>
>
|
>
>
>
|
|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

bind Scrollbar <Leave> {
    if {$tk_strictMotif && [info exists tk::Priv(activeBg)]} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    %W activate {}
}
bind Scrollbar <1> {
    tk::ScrollButtonDown %W %x %y
}
bind Scrollbar <B1-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <B1-B2-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <ButtonRelease-1> {
    tk::ScrollButtonUp %W %x %y
}
bind Scrollbar <B1-Leave> {
    # Prevents <Leave> binding from being invoked.
}
bind Scrollbar <B1-Enter> {
    # Prevents <Enter> binding from being invoked.
}
bind Scrollbar <2> {
    tk::ScrollButton2Down %W %x %y
}
bind Scrollbar <B1-2> {
    # Do nothing, since button 1 is already down.
}
bind Scrollbar <B2-1> {
    # Do nothing, since button 2 is already down.
}
bind Scrollbar <B2-Motion> {
    tk::ScrollDrag %W %x %y
}
bind Scrollbar <ButtonRelease-2> {
    tk::ScrollButtonUp %W %x %y
}
bind Scrollbar <B1-ButtonRelease-2> {
    # Do nothing:  B1 release will handle it.
}
bind Scrollbar <B2-ButtonRelease-1> {
    # Do nothing:  B2 release will handle it.
}
bind Scrollbar <B2-Leave> {
    # Prevents <Leave> binding from being invoked.
}
bind Scrollbar <B2-Enter> {
    # Prevents <Enter> binding from being invoked.
}
bind Scrollbar <Control-1> {
    tk::ScrollTopBottom %W %x %y
}
bind Scrollbar <Control-2> {
    tk::ScrollTopBottom %W %x %y
}

bind Scrollbar <Up> {
    tk::ScrollByUnits %W v -1
}
bind Scrollbar <Down> {
    tk::ScrollByUnits %W v 1
}
bind Scrollbar <Control-Up> {
    tk::ScrollByPages %W v -1
}
bind Scrollbar <Control-Down> {
    tk::ScrollByPages %W v 1
}
bind Scrollbar <Left> {
    tk::ScrollByUnits %W h -1
}
bind Scrollbar <Right> {
    tk::ScrollByUnits %W h 1
}
bind Scrollbar <Control-Left> {
    tk::ScrollByPages %W h -1
}
bind Scrollbar <Control-Right> {
    tk::ScrollByPages %W h 1
}
bind Scrollbar <Prior> {
    tk::ScrollByPages %W hv -1
}
bind Scrollbar <Next> {
    tk::ScrollByPages %W hv 1
}
bind Scrollbar <Home> {
    tk::ScrollToPos %W 0
}
bind Scrollbar <End> {
    tk::ScrollToPos %W 1
}
}
if {[tk windowingsystem] eq "aqua"} {
    bind Scrollbar <MouseWheel> {
        tk::ScrollByUnits %W v [expr {- (%D)}]
    }
    bind Scrollbar <Option-MouseWheel> {
        tk::ScrollByUnits %W v [expr {-10 * (%D)}]
    }
    bind Scrollbar <Shift-MouseWheel> {
        tk::ScrollByUnits %W h [expr {- (%D)}]
    }
    bind Scrollbar <Shift-Option-MouseWheel> {
        tk::ScrollByUnits %W h [expr {-10 * (%D)}]
    }
} else {
    bind Scrollbar <MouseWheel> {
	tk::ScrollByUnits %W v [expr {- (%D /120 ) * 4}]
    }
    bind Scrollbar <Shift-MouseWheel> {
	tk::ScrollByUnits %W h [expr {- (%D /120 ) * 4}]
    }
}
# tk::ScrollButtonDown --
# This procedure is invoked when a button is pressed in a scrollbar.
# It changes the way the scrollbar is displayed and takes actions
# depending on where the mouse is.
#
# Arguments:
# w -		The scrollbar widget.
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kinds of scrollbars this applies to:  "h" for
#		horizontal, "v" for vertical, "hv" for both.
# amount -	How many units to scroll:  typically 1 or -1.

proc ::tk::ScrollByUnits {w orient amount {factor 1.0}} {
    set cmd [$w cget -command]
    if {$cmd eq "" || ([string first \
	    [string index [$w cget -orient] 0] $orient] < 0)} {
	return
    }
    set info [$w get]
    if {[llength $info] == 2} {
	uplevel #0 $cmd scroll [expr {$amount/$factor}] units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}]
    }
}

# ::tk::ScrollByPages --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of screenfuls.  It notifies the associated
# widget in different ways for old and new command syntaxes.







|







|

|







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kinds of scrollbars this applies to:  "h" for
#		horizontal, "v" for vertical, "hv" for both.
# amount -	How many units to scroll:  typically 1 or -1.

proc ::tk::ScrollByUnits {w orient amount} {
    set cmd [$w cget -command]
    if {$cmd eq "" || ([string first \
	    [string index [$w cget -orient] 0] $orient] < 0)} {
	return
    }
    set info [$w get]
    if {[llength $info] == 2} {
	uplevel #0 $cmd scroll $amount units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + $amount}]
    }
}

# ::tk::ScrollByPages --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of screenfuls.  It notifies the associated
# widget in different ways for old and new command syntaxes.
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
#
# Arguments:
# w -		The scrollbar widget.
# x, y -	Mouse coordinates within the widget.

proc ::tk::ScrollButton2Down {w x y} {
    variable ::tk::Priv
    if {![winfo exists $w]} {
        return
    }
    set element [$w identify $x $y]
    if {[string match {arrow[12]} $element]} {
	ScrollButtonDown $w $x $y
	return
    }
    ScrollToPos $w [$w fraction $x $y]
    set Priv(relief) [$w cget -activerelief]

    # Need the "update idletasks" below so that the widget calls us
    # back to reset the actual scrollbar position before we start the
    # slider drag.

    update idletasks
    if {[winfo exists $w]} {
        $w configure -activerelief sunken
        $w activate slider
        ScrollStartDrag $w $x $y
    }
}







<
<
<













<
|
|
|
|
<
411
412
413
414
415
416
417



418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434

#
# Arguments:
# w -		The scrollbar widget.
# x, y -	Mouse coordinates within the widget.

proc ::tk::ScrollButton2Down {w x y} {
    variable ::tk::Priv



    set element [$w identify $x $y]
    if {[string match {arrow[12]} $element]} {
	ScrollButtonDown $w $x $y
	return
    }
    ScrollToPos $w [$w fraction $x $y]
    set Priv(relief) [$w cget -activerelief]

    # Need the "update idletasks" below so that the widget calls us
    # back to reset the actual scrollbar position before we start the
    # slider drag.

    update idletasks

    $w configure -activerelief sunken
    $w activate slider
    ScrollStartDrag $w $x $y
}

Changes to library/spinbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# spinbox.tcl --
#
# This file defines the default bindings for Tk spinbox widgets and provides
# procedures that help in implementing those bindings.  The spinbox builds
# off the entry widget, so it can reuse Entry bindings and procedures.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1999-2000 Jeffrey Hobbs
# Copyright © 2000 Ajuba Solutions
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:






|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# spinbox.tcl --
#
# This file defines the default bindings for Tk spinbox widgets and provides
# procedures that help in implementing those bindings.  The spinbox builds
# off the entry widget, so it can reuse Entry bindings and procedures.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1999-2000 Jeffrey Hobbs
# 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.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:
48
49
50
51
52
53
54

55
56
57
58
59
60
61
    if {![catch {::tk::spinbox::GetSelection %W} tk::Priv(data)]} {
	clipboard clear -displayof %W
	clipboard append -displayof %W $tk::Priv(data)
	unset tk::Priv(data)
    }
}
bind Spinbox <<Paste>> {

    catch {
	if {[tk windowingsystem] ne "x11"} {
	    catch {
		%W delete sel.first sel.last
	    }
	}
	%W insert insert [::tk::GetSelection %W CLIPBOARD]







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    if {![catch {::tk::spinbox::GetSelection %W} tk::Priv(data)]} {
	clipboard clear -displayof %W
	clipboard append -displayof %W $tk::Priv(data)
	unset tk::Priv(data)
    }
}
bind Spinbox <<Paste>> {
    global tcl_platform
    catch {
	if {[tk windowingsystem] ne "x11"} {
	    catch {
		%W delete sel.first sel.last
	    }
	}
	%W insert insert [::tk::GetSelection %W CLIPBOARD]
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	|| !$tk::Priv(mouseMoved)} {
	::tk::spinbox::Paste %W %x
    }
}

bind Spinbox <<TraverseIn>> {
    %W selection range 0 end
    %W icursor end
}

# Standard Motif bindings:

bind Spinbox <Button-1> {
    ::tk::spinbox::ButtonDown %W %x %y
}
bind Spinbox <B1-Motion> {
    ::tk::spinbox::Motion %W %x %y
}
bind Spinbox <Double-Button-1> {
    ::tk::spinbox::ArrowPress %W %x %y
    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x sel.first
}
bind Spinbox <Triple-Button-1> {
    ::tk::spinbox::ArrowPress %W %x %y
    set tk::Priv(selectMode) line
    ::tk::spinbox::MouseSelect %W %x 0
}
bind Spinbox <Shift-Button-1> {
    set tk::Priv(selectMode) char
    %W selection adjust @%x
}
bind Spinbox <Double-Shift-Button-1> {
    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x
}
bind Spinbox <Triple-Shift-Button-1> {
    set tk::Priv(selectMode) line
    ::tk::spinbox::MouseSelect %W %x
}
bind Spinbox <B1-Leave> {
    set tk::Priv(x) %x
    ::tk::spinbox::AutoScan %W
}
bind Spinbox <B1-Enter> {
    tk::CancelRepeat
}
bind Spinbox <ButtonRelease-1> {
    ::tk::spinbox::ButtonUp %W %x %y
}
bind Spinbox <Control-Button-1> {
    %W icursor @%x
}

bind Spinbox <<PrevLine>> {
    %W invoke buttonup
}
bind Spinbox <<NextLine>> {
    %W invoke buttondown
}

bind Spinbox <<PrevChar>> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
}
bind Spinbox <<NextChar>> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
}
bind Spinbox <<SelectPrevChar>> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] - 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextChar>> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] + 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<PrevWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryPreviousWord %W insert]
}
bind Spinbox <<NextWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <<SelectPrevWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineStart>> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <<SelectLineStart>> {
    ::tk::EntryKeySelect %W 0
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineEnd>> {
    ::tk::EntrySetCursor %W end
}
bind Spinbox <<SelectLineEnd>> {
    ::tk::EntryKeySelect %W end
    ::tk::EntrySeeInsert %W
}

bind Spinbox <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last







|
|




|





|
<



|
<



|



|



|













|



|


|



|


|


|



|



|


|


|



|



|


|



|


|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	|| !$tk::Priv(mouseMoved)} {
	::tk::spinbox::Paste %W %x
    }
}

bind Spinbox <<TraverseIn>> {
    %W selection range 0 end 
    %W icursor end 
}

# Standard Motif bindings:

bind Spinbox <1> {
    ::tk::spinbox::ButtonDown %W %x %y
}
bind Spinbox <B1-Motion> {
    ::tk::spinbox::Motion %W %x %y
}
bind Spinbox <Double-1> {

    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x sel.first
}
bind Spinbox <Triple-1> {

    set tk::Priv(selectMode) line
    ::tk::spinbox::MouseSelect %W %x 0
}
bind Spinbox <Shift-1> {
    set tk::Priv(selectMode) char
    %W selection adjust @%x
}
bind Spinbox <Double-Shift-1> {
    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x
}
bind Spinbox <Triple-Shift-1> {
    set tk::Priv(selectMode) line
    ::tk::spinbox::MouseSelect %W %x
}
bind Spinbox <B1-Leave> {
    set tk::Priv(x) %x
    ::tk::spinbox::AutoScan %W
}
bind Spinbox <B1-Enter> {
    tk::CancelRepeat
}
bind Spinbox <ButtonRelease-1> {
    ::tk::spinbox::ButtonUp %W %x %y
}
bind Spinbox <Control-1> {
    %W icursor @%x
}

bind Spinbox <Up> {
    %W invoke buttonup
}
bind Spinbox <Down> {
    %W invoke buttondown
}

bind Spinbox <Left> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
}
bind Spinbox <Right> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
}
bind Spinbox <Shift-Left> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] - 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <Shift-Right> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] + 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <Control-Left> {
    ::tk::EntrySetCursor %W [::tk::EntryPreviousWord %W insert]
}
bind Spinbox <Control-Right> {
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <Shift-Control-Left> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <Shift-Control-Right> {
    ::tk::EntryKeySelect %W [::tk::EntryNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <Home> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <Shift-Home> {
    ::tk::EntryKeySelect %W 0
    ::tk::EntrySeeInsert %W
}
bind Spinbox <End> {
    ::tk::EntrySetCursor %W end
}
bind Spinbox <Shift-End> {
    ::tk::EntryKeySelect %W end
    ::tk::EntrySeeInsert %W
}

bind Spinbox <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234










235
236
237
238










239
240
241
242
243
244
245
}
bind Spinbox <Control-Shift-space> {
    %W selection adjust insert
}
bind Spinbox <Shift-Select> {
    %W selection adjust insert
}
bind Spinbox <<SelectAll>> {
    %W selection range 0 end
}
bind Spinbox <<SelectNone>> {
    %W selection clear
}
bind Spinbox <Key> {
    ::tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Spinbox <Alt-Key> {# nothing}
bind Spinbox <Meta-Key> {# nothing}
bind Spinbox <Control-Key> {# nothing}
bind Spinbox <Escape> {# nothing}
bind Spinbox <Return> {# nothing}
bind Spinbox <KP_Enter> {# nothing}
bind Spinbox <Tab> {# nothing}
bind Spinbox <Prior> {# nothing}
bind Spinbox <Next> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Spinbox <Command-Key> {# nothing}
}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Spinbox <Insert> {
	catch {::tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }
}

# Additional emacs-like bindings:











bind Spinbox <Control-d> {
    if {!$tk_strictMotif} {
	%W delete insert
    }










}
bind Spinbox <Control-h> {
    if {!$tk_strictMotif} {
	::tk::EntryBackspace %W
    }
}
bind Spinbox <Control-k> {







|


|


|





|


|
|
|




<
<

|












>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
}
bind Spinbox <Control-Shift-space> {
    %W selection adjust insert
}
bind Spinbox <Shift-Select> {
    %W selection adjust insert
}
bind Spinbox <Control-slash> {
    %W selection range 0 end
}
bind Spinbox <Control-backslash> {
    %W selection clear
}
bind Spinbox <KeyPress> {
    ::tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <KeyPress> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Spinbox <Alt-KeyPress> {# nothing}
bind Spinbox <Meta-KeyPress> {# nothing}
bind Spinbox <Control-KeyPress> {# nothing}
bind Spinbox <Escape> {# nothing}
bind Spinbox <Return> {# nothing}
bind Spinbox <KP_Enter> {# nothing}
bind Spinbox <Tab> {# nothing}


if {[tk windowingsystem] eq "aqua"} {
    bind Spinbox <Command-KeyPress> {# nothing}
}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Spinbox <Insert> {
	catch {::tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }
}

# Additional emacs-like bindings:

bind Spinbox <Control-a> {
    if {!$tk_strictMotif} {
	::tk::EntrySetCursor %W 0
    }
}
bind Spinbox <Control-b> {
    if {!$tk_strictMotif} {
	::tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
    }
}
bind Spinbox <Control-d> {
    if {!$tk_strictMotif} {
	%W delete insert
    }
}
bind Spinbox <Control-e> {
    if {!$tk_strictMotif} {
	::tk::EntrySetCursor %W end
    }
}
bind Spinbox <Control-f> {
    if {!$tk_strictMotif} {
	::tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
    }
}
bind Spinbox <Control-h> {
    if {!$tk_strictMotif} {
	::tk::EntryBackspace %W
    }
}
bind Spinbox <Control-k> {
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    if {!$tk_strictMotif} {
	%W delete [::tk::EntryPreviousWord %W insert] insert
    }
}

# A few additional bindings of my own.

bind Spinbox <Button-2> {
    if {!$tk_strictMotif} {
	::tk::EntryScanMark %W %x
    }
}
bind Spinbox <B2-Motion> {
    if {!$tk_strictMotif} {
	::tk::EntryScanDrag %W %x
    }
}

# ::tk::spinbox::Invoke --
# Invoke an element of the spinbox
#
# Arguments:
# w -		The spinbox window.
# elem -	Element to invoke

proc ::tk::spinbox::Invoke {w elem} {
    variable ::tk::Priv

    if {![winfo exists $w]} {
      return
    }

    if {![info exists Priv(outsideElement)]} {
	$w invoke $elem
	incr Priv(repeated)
    }
    set delay [$w cget -repeatinterval]
    if {$delay > 0} {
	set Priv(afterId) [after $delay \







|




















<
<
<
<







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320




321
322
323
324
325
326
327
    if {!$tk_strictMotif} {
	%W delete [::tk::EntryPreviousWord %W insert] insert
    }
}

# A few additional bindings of my own.

bind Spinbox <2> {
    if {!$tk_strictMotif} {
	::tk::EntryScanMark %W %x
    }
}
bind Spinbox <B2-Motion> {
    if {!$tk_strictMotif} {
	::tk::EntryScanDrag %W %x
    }
}

# ::tk::spinbox::Invoke --
# Invoke an element of the spinbox
#
# Arguments:
# w -		The spinbox window.
# elem -	Element to invoke

proc ::tk::spinbox::Invoke {w elem} {
    variable ::tk::Priv





    if {![info exists Priv(outsideElement)]} {
	$w invoke $elem
	incr Priv(repeated)
    }
    set delay [$w cget -repeatinterval]
    if {$delay > 0} {
	set Priv(afterId) [after $delay \
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388








389





390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
    set bbox [$w bbox $pos]
    if {($x - [lindex $bbox 0]) < ([lindex $bbox 2]/2)} {
	return $pos
    }
    incr pos
}

# ::tk::spinbox::ArrowPress --
# This procedure is invoked to handle button-1 presses in buttonup
# or buttondown elements of spinbox widgets.
#
# Arguments:
# w -		The spinbox window in which the button was pressed.
# x -		The x-coordinate of the button press.
# y -		The y-coordinate of the button press.

proc ::tk::spinbox::ArrowPress {w x y} {
    variable ::tk::Priv

    if {[$w cget -state] ne "disabled" && \
            [string match "button*" $Priv(element)]} {
        $w selection element $Priv(element)
        set Priv(repeated) 0
        set Priv(relief) [$w cget -$Priv(element)relief]
        catch {after cancel $Priv(afterId)}
        set delay [$w cget -repeatdelay]
        if {$delay > 0} {
            set Priv(afterId) [after $delay \
                    [list ::tk::spinbox::Invoke $w $Priv(element)]]
        }
        if {[info exists Priv(outsideElement)]} {
            unset Priv(outsideElement)
        }
    }
}

# ::tk::spinbox::ButtonDown --
# This procedure is invoked to handle button-1 presses in spinbox
# widgets.  It moves the insertion cursor, sets the selection anchor,
# and claims the input focus.
#
# Arguments:
# w -		The spinbox window in which the button was pressed.
# x -		The x-coordinate of the button press.
# y -		The y-coordinate of the button press.

proc ::tk::spinbox::ButtonDown {w x y} {
    variable ::tk::Priv

    # Get the element that was clicked in.  If we are not directly over
    # the spinbox, default to entry.  This is necessary for spinbox grabs.
    #
    set Priv(element) [$w identify $x $y]
    if {$Priv(element) eq ""} {
	set Priv(element) "entry"
    }

    switch -exact $Priv(element) {
	"buttonup" - "buttondown" {








	    ::tk::spinbox::ArrowPress $w $x $y





	}
	"entry" {
	    set Priv(selectMode) char
	    set Priv(mouseMoved) 0
	    set Priv(pressX) $x
	    $w icursor [::tk::spinbox::ClosestGap $w $x]
	    $w selection from insert
	    if {"disabled" ne [$w cget -state]} {focus $w}
	    $w selection clear
	}
	default {
	    return -code error -errorcode {TK SPINBOX UNKNOWN_ELEMENT} \
		"unknown spinbox element \"$Priv(element)\""
	}
    }
}

# ::tk::spinbox::ButtonUp --
# This procedure is invoked to handle button-1 releases in spinbox
# widgets.
#
# Arguments:
# w -		The spinbox window in which the button was pressed.
# x -		The x-coordinate of the button press.
# y -		The y-coordinate of the button press.

proc ::tk::spinbox::ButtonUp {w x y} {
    variable ::tk::Priv

    ::tk::CancelRepeat

    # Priv(relief) may not exist if the ButtonUp is not paired with







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<














>
>
>
>
>
>
>
>
|
>
>
>
>
>











<
|











<







343
344
345
346
347
348
349





























350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
    set bbox [$w bbox $pos]
    if {($x - [lindex $bbox 0]) < ([lindex $bbox 2]/2)} {
	return $pos
    }
    incr pos
}






























# ::tk::spinbox::ButtonDown --
# This procedure is invoked to handle button-1 presses in spinbox
# widgets.  It moves the insertion cursor, sets the selection anchor,
# and claims the input focus.
#
# Arguments:
# w -		The spinbox window in which the button was pressed.
# x -		The x-coordinate of the button press.


proc ::tk::spinbox::ButtonDown {w x y} {
    variable ::tk::Priv

    # Get the element that was clicked in.  If we are not directly over
    # the spinbox, default to entry.  This is necessary for spinbox grabs.
    #
    set Priv(element) [$w identify $x $y]
    if {$Priv(element) eq ""} {
	set Priv(element) "entry"
    }

    switch -exact $Priv(element) {
	"buttonup" - "buttondown" {
	    if {"disabled" ne [$w cget -state]} {
		$w selection element $Priv(element)
		set Priv(repeated) 0
		set Priv(relief) [$w cget -$Priv(element)relief]
		catch {after cancel $Priv(afterId)}
		set delay [$w cget -repeatdelay]
		if {$delay > 0} {
		    set Priv(afterId) [after $delay \
			    [list ::tk::spinbox::Invoke $w $Priv(element)]]
		}
		if {[info exists Priv(outsideElement)]} {
		    unset Priv(outsideElement)
		}
	    }
	}
	"entry" {
	    set Priv(selectMode) char
	    set Priv(mouseMoved) 0
	    set Priv(pressX) $x
	    $w icursor [::tk::spinbox::ClosestGap $w $x]
	    $w selection from insert
	    if {"disabled" ne [$w cget -state]} {focus $w}
	    $w selection clear
	}
	default {

	    return -code error "unknown spinbox element \"$Priv(element)\""
	}
    }
}

# ::tk::spinbox::ButtonUp --
# This procedure is invoked to handle button-1 releases in spinbox
# widgets.
#
# Arguments:
# w -		The spinbox window in which the button was pressed.
# x -		The x-coordinate of the button press.


proc ::tk::spinbox::ButtonUp {w x y} {
    variable ::tk::Priv

    ::tk::CancelRepeat

    # Priv(relief) may not exist if the ButtonUp is not paired with
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } else {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }







|


|







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]
	    } else {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

# ::tk::spinbox::Motion --
# This procedure is invoked when the mouse moves in a spinbox window
# with button 1 down.
#
# Arguments:
# w -		The spinbox window.
# x -		The x-coordinate of the mouse.
# y -		The y-coordinate of the mouse.

proc ::tk::spinbox::Motion {w x y} {
    variable ::tk::Priv

    if {![info exists Priv(element)]} {
	set Priv(element) [$w identify $x $y]
    }







<
<







505
506
507
508
509
510
511


512
513
514
515
516
517
518

# ::tk::spinbox::Motion --
# This procedure is invoked when the mouse moves in a spinbox window
# with button 1 down.
#
# Arguments:
# w -		The spinbox window.



proc ::tk::spinbox::Motion {w x y} {
    variable ::tk::Priv

    if {![info exists Priv(element)]} {
	set Priv(element) [$w identify $x $y]
    }
572
573
574
575
576
577
578
579
580
# a spinbox has no -show option to obscure contents.
#
# Arguments:
# w -         The spinbox window from which the text to get

proc ::tk::spinbox::GetSelection {w} {
    return [string range [$w get] [$w index sel.first] \
	    [$w index sel.last]-1]
}







|

564
565
566
567
568
569
570
571
572
# a spinbox has no -show option to obscure contents.
#
# Arguments:
# w -         The spinbox window from which the text to get

proc ::tk::spinbox::GetSelection {w} {
    return [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
}

Changes to library/tclIndex.

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
set auto_index(::tk::EntryTranspose) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryPreviousWord) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryGetSelection) [list source [file join $dir entry.tcl]]
set auto_index(tk_focusNext) [list source [file join $dir focus.tcl]]
set auto_index(tk_focusPrev) [list source [file join $dir focus.tcl]]
set auto_index(::tk::FocusOK) [list source [file join $dir focus.tcl]]
set auto_index(tk_focusFollowsMouse) [list source [file join $dir focus.tcl]]
set auto_index(::tk::IconList) [list source [file join $dir iconlist.tcl]]
set auto_index(::tk::ListboxBeginSelect) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxMotion) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginExtend) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginToggle) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxAutoScan) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxUpDown) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxExtendUpDown) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxDataExtend) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxCancel) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxSelectAll) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::Megawidget) [list source [file join $dir megawidget.tcl]]
set auto_index(::tk::MbEnter) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbLeave) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbPost) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuUnpost) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbMotion) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbButtonUp) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuMotion) [list source [file join $dir menu.tcl]]







<










<







75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
set auto_index(::tk::EntryTranspose) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryPreviousWord) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryGetSelection) [list source [file join $dir entry.tcl]]
set auto_index(tk_focusNext) [list source [file join $dir focus.tcl]]
set auto_index(tk_focusPrev) [list source [file join $dir focus.tcl]]
set auto_index(::tk::FocusOK) [list source [file join $dir focus.tcl]]
set auto_index(tk_focusFollowsMouse) [list source [file join $dir focus.tcl]]

set auto_index(::tk::ListboxBeginSelect) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxMotion) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginExtend) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginToggle) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxAutoScan) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxUpDown) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxExtendUpDown) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxDataExtend) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxCancel) [list source [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxSelectAll) [list source [file join $dir listbox.tcl]]

set auto_index(::tk::MbEnter) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbLeave) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbPost) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuUnpost) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbMotion) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MbButtonUp) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuMotion) [list source [file join $dir menu.tcl]]
195
196
197
198
199
200
201
202
203




























204
205
206
207
208
209
210
set auto_index(::tk::TextPrevPos) [list source [file join $dir text.tcl]]
set auto_index(::tk::PlaceWindow) [list source [file join $dir tk.tcl]]
set auto_index(::tk::SetFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::RestoreFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::ScreenChanged) [list source [file join $dir tk.tcl]]
set auto_index(::tk::EventMotifBindings) [list source [file join $dir tk.tcl]]
set auto_index(::tk::CancelRepeat) [list source [file join $dir tk.tcl]]
set auto_index(::tk::MouseWheel) [list source [file join $dir tk.tcl]]
set auto_index(::tk::TabToWindow) [list source [file join $dir tk.tcl]]




























set auto_index(::tk::dialog::file::) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Config) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Create) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetSelectMode) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpdateWhenIdle) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Update) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetPathSilently) [list source [file join $dir tkfbox.tcl]]







<

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
set auto_index(::tk::TextPrevPos) [list source [file join $dir text.tcl]]
set auto_index(::tk::PlaceWindow) [list source [file join $dir tk.tcl]]
set auto_index(::tk::SetFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::RestoreFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::ScreenChanged) [list source [file join $dir tk.tcl]]
set auto_index(::tk::EventMotifBindings) [list source [file join $dir tk.tcl]]
set auto_index(::tk::CancelRepeat) [list source [file join $dir tk.tcl]]

set auto_index(::tk::TabToWindow) [list source [file join $dir tk.tcl]]
set auto_index(::tk::IconList) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Index) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Selection) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_CurSelection) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_DrawSelection) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Get) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Config) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Create) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_AutoScan) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_DeleteAll) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Add) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Arrange) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Invoke) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_See) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Btn1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_CtrlBtn1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_ShiftBtn1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Motion1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Double1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_ReturnKey) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Leave1) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_FocusIn) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_FocusOut) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_UpDown) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_LeftRight) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_KeyPress) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Goto) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::IconList_Reset) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Config) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Create) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetSelectMode) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpdateWhenIdle) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Update) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetPathSilently) [list source [file join $dir tkfbox.tcl]]
244
245
246
247
248
249
250

251
252
253
set auto_index(::tk::MotifFDialog_FilterCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_CancelCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Set) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Unset) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Key) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Goto) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Reset) [list source [file join $dir xmfbox.tcl]]

set auto_index(::tk::unsupported::ExposePrivateCommand) [list source [file join $dir unsupported.tcl]]
set auto_index(::tk::unsupported::ExposePrivateVariable) [list source [file join $dir unsupported.tcl]]
set auto_index(::tk::fontchooser) [list source [file join $dir fontchooser.tcl]]







>


<
269
270
271
272
273
274
275
276
277
278

set auto_index(::tk::MotifFDialog_FilterCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_CancelCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Set) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Unset) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Key) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Goto) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Reset) [list source [file join $dir xmfbox.tcl]]
set auto_index(tk_getFileType) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::unsupported::ExposePrivateCommand) [list source [file join $dir unsupported.tcl]]
set auto_index(::tk::unsupported::ExposePrivateVariable) [list source [file join $dir unsupported.tcl]]

Changes to library/tearoff.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
# tearoff.tcl --
#
# This file contains procedures that implement tear-off menus.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 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.
#

# ::tk::TearoffMenu --
# Given the name of a menu, this procedure creates a torn-off menu




|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
# tearoff.tcl --
#
# This file contains procedures that implement tear-off menus.
#
# 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.
#

# ::tk::TearoffMenu --
# Given the name of a menu, this procedure creates a torn-off menu
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    }
    if {$y == 0} {
    	set y [winfo rooty $w]
	if {[tk windowingsystem] eq "aqua"} {
	    # Shift by height of tearoff entry minus height of window titlebar
	    catch {incr y [expr {[$w yposition 1] - 16}]}
	    # Avoid the native menu bar which sits on top of everything.
	    if {$y < 22} {set y 22}
	}
    }

    set parent [winfo parent $w]
    while {[winfo toplevel $parent] ne $parent \
	    || [winfo class $parent] eq "Menu"} {
	set parent [winfo parent $parent]







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    }
    if {$y == 0} {
    	set y [winfo rooty $w]
	if {[tk windowingsystem] eq "aqua"} {
	    # Shift by height of tearoff entry minus height of window titlebar
	    catch {incr y [expr {[$w yposition 1] - 16}]}
	    # Avoid the native menu bar which sits on top of everything.
	    if {$y < 22} { set y 22 }
	}
    }

    set parent [winfo parent $w]
    while {[winfo toplevel $parent] ne $parent \
	    || [winfo class $parent] eq "Menu"} {
	set parent [winfo parent $parent]
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
	eval $cmd
    }

    # Duplicate the binding tags and bindings from the source menu.

    set tags [bindtags $src]
    set srcLen [string length $src]

    # Copy tags to x, replacing each substring of src with dst.

    while {[set index [string first $src $tags]] >= 0} {
	if {$index > 0} {
	    append x [string range $tags 0 $index-1]$dst
	}
	set tags [string range $tags $index+$srcLen end]
    }
    append x $tags

    bindtags $dst $x

    foreach event [bind $src] {
	unset x
	set script [bind $src $event]
	set eventLen [string length $event]

	# Copy script to x, replacing each substring of event with dst.

	while {[set index [string first $event $script]] >= 0} {
	    if {$index > 0} {
		append x [string range $script 0 $index-1]
	    }
	    append x $dst
	    set script [string range $script $index+$eventLen end]
	}
	append x $script

	bind $dst $event $x
    }
}







|


|
<
|
<
|












|
<
|
<

|






146
147
148
149
150
151
152
153
154
155
156

157

158
159
160
161
162
163
164
165
166
167
168
169
170
171

172

173
174
175
176
177
178
179
180
	eval $cmd
    }

    # Duplicate the binding tags and bindings from the source menu.

    set tags [bindtags $src]
    set srcLen [string length $src]
 
    # Copy tags to x, replacing each substring of src with dst.

    while {[set index [string first $src $tags]] != -1} {

	append x [string range $tags 0 [expr {$index - 1}]]$dst

	set tags [string range $tags [expr {$index + $srcLen}] end]
    }
    append x $tags

    bindtags $dst $x

    foreach event [bind $src] {
	unset x
	set script [bind $src $event]
	set eventLen [string length $event]

	# Copy script to x, replacing each substring of event with dst.

	while {[set index [string first $event $script]] != -1} {

	    append x [string range $script 0 [expr {$index - 1}]]

	    append x $dst
	    set script [string range $script [expr {$index + $eventLen}] end]
	}
	append x $script

	bind $dst $event $x
    }
}

Changes to library/text.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# text.tcl --
#
# This file defines the default bindings for Tk text widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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.
#

#-------------------------------------------------------------------------
# Elements of ::tk::Priv that are used in this file:





|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# text.tcl --
#
# This file defines the default bindings for Tk text widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright (c) 1992-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.
#

#-------------------------------------------------------------------------
# Elements of ::tk::Priv that are used in this file:
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
#-------------------------------------------------------------------------

#-------------------------------------------------------------------------
# The code below creates the default class bindings for text widgets.
#-------------------------------------------------------------------------



# Standard Motif bindings:

bind Text <Button-1> {
    tk::TextButton1 %W %x %y
    %W tag remove sel 0.0 end
}
bind Text <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Button-1> {
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Triple-Button-1> {
    set tk::Priv(selectMode) line
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Shift-Button-1> {
    tk::TextResetAnchor %W @%x,%y
    set tk::Priv(selectMode) char
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Shift-Button-1>	{
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y 1
}
bind Text <Triple-Shift-Button-1>	{
    set tk::Priv(selectMode) line
    tk::TextSelectTo %W %x %y
}
bind Text <B1-Leave> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextAutoScan %W
}
bind Text <B1-Enter> {
    tk::CancelRepeat
}
bind Text <ButtonRelease-1> {
    tk::CancelRepeat
}

bind Text <Control-Button-1> {
    %W mark set insert @%x,%y
    # An operation that moves the insert mark without making it
    # one end of the selection must insert an autoseparator
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}
# stop an accidental double click triggering <Double-Button-1>
bind Text <Double-Control-Button-1> { # nothing }
# stop an accidental movement triggering <B1-Motion>
bind Text <Control-B1-Motion> { # nothing }
bind Text <<PrevChar>> {
    tk::TextSetCursor %W insert-1displayindices
}
bind Text <<NextChar>> {
    tk::TextSetCursor %W insert+1displayindices
}
bind Text <<PrevLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W -1]
}
bind Text <<NextLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W 1]
}
bind Text <<SelectPrevChar>> {
    tk::TextKeySelect %W [%W index {insert - 1displayindices}]
}
bind Text <<SelectNextChar>> {
    tk::TextKeySelect %W [%W index {insert + 1displayindices}]
}
bind Text <<SelectPrevLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W -1]
}
bind Text <<SelectNextLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W 1]
}
bind Text <<PrevWord>> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <<NextWord>> {
    tk::TextSetCursor %W [tk::TextNextWord %W insert]
}
bind Text <<PrevPara>> {
    tk::TextSetCursor %W [tk::TextPrevPara %W insert]
}
bind Text <<NextPara>> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <<SelectPrevWord>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <<SelectNextWord>> {
    tk::TextKeySelect %W [tk::TextNextWord %W insert]
}
bind Text <<SelectPrevPara>> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <<SelectNextPara>> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}
bind Text <Prior> {
    tk::TextSetCursor %W [tk::TextScrollPages %W -1]
}
bind Text <Shift-Prior> {
    tk::TextKeySelect %W [tk::TextScrollPages %W -1]







<
<


|








|




|




|




|



|














<
|








|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|







34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#
#-------------------------------------------------------------------------

#-------------------------------------------------------------------------
# The code below creates the default class bindings for text widgets.
#-------------------------------------------------------------------------



# Standard Motif bindings:

bind Text <1> {
    tk::TextButton1 %W %x %y
    %W tag remove sel 0.0 end
}
bind Text <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextSelectTo %W %x %y
}
bind Text <Double-1> {
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Triple-1> {
    set tk::Priv(selectMode) line
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Shift-1> {
    tk::TextResetAnchor %W @%x,%y
    set tk::Priv(selectMode) char
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Shift-1>	{
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y 1
}
bind Text <Triple-Shift-1>	{
    set tk::Priv(selectMode) line
    tk::TextSelectTo %W %x %y
}
bind Text <B1-Leave> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextAutoScan %W
}
bind Text <B1-Enter> {
    tk::CancelRepeat
}
bind Text <ButtonRelease-1> {
    tk::CancelRepeat
}

bind Text <Control-1> {
    %W mark set insert @%x,%y
    # An operation that moves the insert mark without making it
    # one end of the selection must insert an autoseparator
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}
# stop an accidental double click triggering <Double-Button-1>
bind Text <Double-Control-1> { # nothing }
# stop an accidental movement triggering <B1-Motion>
bind Text <Control-B1-Motion> { # nothing }
bind Text <Left> {
    tk::TextSetCursor %W insert-1displayindices
}
bind Text <Right> {
    tk::TextSetCursor %W insert+1displayindices
}
bind Text <Up> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W -1]
}
bind Text <Down> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W 1]
}
bind Text <Shift-Left> {
    tk::TextKeySelect %W [%W index {insert - 1displayindices}]
}
bind Text <Shift-Right> {
    tk::TextKeySelect %W [%W index {insert + 1displayindices}]
}
bind Text <Shift-Up> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W -1]
}
bind Text <Shift-Down> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W 1]
}
bind Text <Control-Left> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <Control-Right> {
    tk::TextSetCursor %W [tk::TextNextWord %W insert]
}
bind Text <Control-Up> {
    tk::TextSetCursor %W [tk::TextPrevPara %W insert]
}
bind Text <Control-Down> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <Shift-Control-Left> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <Shift-Control-Right> {
    tk::TextKeySelect %W [tk::TextNextWord %W insert]
}
bind Text <Shift-Control-Up> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <Shift-Control-Down> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}
bind Text <Prior> {
    tk::TextSetCursor %W [tk::TextScrollPages %W -1]
}
bind Text <Shift-Prior> {
    tk::TextKeySelect %W [tk::TextScrollPages %W -1]
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
bind Text <Control-Prior> {
    %W xview scroll -1 page
}
bind Text <Control-Next> {
    %W xview scroll 1 page
}

bind Text <<LineStart>> {
    tk::TextSetCursor %W {insert display linestart}
}
bind Text <<SelectLineStart>> {
    tk::TextKeySelect %W {insert display linestart}
}
bind Text <<LineEnd>> {
    tk::TextSetCursor %W {insert display lineend}
}
bind Text <<SelectLineEnd>> {
    tk::TextKeySelect %W {insert display lineend}
}
bind Text <Control-Home> {
    tk::TextSetCursor %W 1.0
}
bind Text <Control-Shift-Home> {
    tk::TextKeySelect %W 1.0







|


|


|


|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
bind Text <Control-Prior> {
    %W xview scroll -1 page
}
bind Text <Control-Next> {
    %W xview scroll 1 page
}

bind Text <Home> {
    tk::TextSetCursor %W {insert display linestart}
}
bind Text <Shift-Home> {
    tk::TextKeySelect %W {insert display linestart}
}
bind Text <End> {
    tk::TextSetCursor %W {insert display lineend}
}
bind Text <Shift-End> {
    tk::TextKeySelect %W {insert display lineend}
}
bind Text <Control-Home> {
    tk::TextSetCursor %W 1.0
}
bind Text <Control-Shift-Home> {
    tk::TextKeySelect %W 1.0
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}
bind Text <Delete> {
    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last
    } else {
	if {[%W compare end != insert+1c]} {
	    %W delete insert
	}
	%W see insert
    }
}
bind Text <BackSpace> {
    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last
    } else {
	if {[%W compare insert != 1.0]} {
	    %W delete insert-1c
	}
	%W see insert
    }
}

bind Text <Control-space> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Select> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Control-Shift-space> {
    set tk::Priv(selectMode) char
    tk::TextKeyExtend %W insert
}
bind Text <Shift-Select> {
    set tk::Priv(selectMode) char
    tk::TextKeyExtend %W insert
}
bind Text <<SelectAll>> {
    %W tag add sel 1.0 end
}
bind Text <<SelectNone>> {
    %W tag remove sel 1.0 end
    # An operation that clears the selection must insert an autoseparator,
    # because the selection operation may have moved the insert mark
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}







<
|
|
|
|
<




<
|
|
|
|
<
















|


|







213
214
215
216
217
218
219

220
221
222
223

224
225
226
227

228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}
bind Text <Delete> {
    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last

    } elseif {[%W compare end != insert+1c]} {
	%W delete insert
    }
    %W see insert

}
bind Text <BackSpace> {
    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last

    } elseif {[%W compare insert != 1.0]} {
	%W delete insert-1c
    }
    %W see insert

}

bind Text <Control-space> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Select> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Control-Shift-space> {
    set tk::Priv(selectMode) char
    tk::TextKeyExtend %W insert
}
bind Text <Shift-Select> {
    set tk::Priv(selectMode) char
    tk::TextKeyExtend %W insert
}
bind Text <Control-slash> {
    %W tag add sel 1.0 end
}
bind Text <Control-backslash> {
    %W tag remove sel 1.0 end
    # An operation that clears the selection must insert an autoseparator,
    # because the selection operation may have moved the insert mark
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314










315
316
317
318










319
320
321
322
323
324
325
326
327





328
329
330
331
332
333





334
335
336
337
338
339
340
	    || !$tk::Priv(mouseMoved)} {
	tk::TextPasteSelection %W %x %y
    }
}
bind Text <Insert> {
    catch {tk::TextInsert %W [::tk::GetSelection %W PRIMARY]}
}
bind Text <Key> {
    tk::TextInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for <Escape>.

bind Text <Alt-Key> {# nothing }
bind Text <Meta-Key> {# nothing}
bind Text <Control-Key> {# nothing}
bind Text <Escape> {# nothing}
bind Text <KP_Enter> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Text <Command-Key> {# nothing}
}

# Additional emacs-like bindings:











bind Text <Control-d> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	%W delete insert
    }










}
bind Text <Control-k> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	if {[%W compare insert == {insert lineend}]} {
	    %W delete insert
	} else {
	    %W delete insert {insert lineend}
	}
    }





}
bind Text <Control-o> {
    if {!$tk_strictMotif} {
	%W insert insert \n
	%W mark set insert insert-1c
    }





}
bind Text <Control-t> {
    if {!$tk_strictMotif} {
	tk::TextTranspose %W
    }
}








|





|


|
|
|



|




>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>









>
>
>
>
>






>
>
>
>
>







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
	    || !$tk::Priv(mouseMoved)} {
	tk::TextPasteSelection %W %x %y
    }
}
bind Text <Insert> {
    catch {tk::TextInsert %W [::tk::GetSelection %W PRIMARY]}
}
bind Text <KeyPress> {
    tk::TextInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <KeyPress> class binding will also fire and insert the character,
# which is wrong.  Ditto for <Escape>.

bind Text <Alt-KeyPress> {# nothing }
bind Text <Meta-KeyPress> {# nothing}
bind Text <Control-KeyPress> {# nothing}
bind Text <Escape> {# nothing}
bind Text <KP_Enter> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Text <Command-KeyPress> {# nothing}
}

# Additional emacs-like bindings:

bind Text <Control-a> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W {insert display linestart}
    }
}
bind Text <Control-b> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W insert-1displayindices
    }
}
bind Text <Control-d> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	%W delete insert
    }
}
bind Text <Control-e> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W {insert display lineend}
    }
}
bind Text <Control-f> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W insert+1displayindices
    }
}
bind Text <Control-k> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	if {[%W compare insert == {insert lineend}]} {
	    %W delete insert
	} else {
	    %W delete insert {insert lineend}
	}
    }
}
bind Text <Control-n> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextUpDownLine %W 1]
    }
}
bind Text <Control-o> {
    if {!$tk_strictMotif} {
	%W insert insert \n
	%W mark set insert insert-1c
    }
}
bind Text <Control-p> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextUpDownLine %W -1]
    }
}
bind Text <Control-t> {
    if {!$tk_strictMotif} {
	tk::TextTranspose %W
    }
}

387
388
389
390
391
392
393

394



395
396
397
398
399
400
401
402
403
404
405


406
407
408

409
410
411
412


413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443






444
445
446
447
448
449
450
451
452
453









454























455
456
457
458
459
460
461
}
bind Text <Meta-Delete> {
    if {!$tk_strictMotif} {
	%W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert
    }
}


# Bindings for IME text input.




bind Text <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Text <<TkEndIMEMarkedText>> {
    if { [catch {dict get $::tk::Priv(IMETextMark) "%W"} mark] } {
	bell
    } else {
	%W tag add IMEmarkedtext $mark insert
	%W tag configure IMEmarkedtext -underline on
    }


}
bind Text <<TkClearIMEMarkedText>> {
    %W delete IMEmarkedtext.first IMEmarkedtext.last

}
bind Text <<TkAccentBackspace>> {
    %W delete insert-1c
}



# Macintosh only bindings:


if {[tk windowingsystem] eq "aqua"} {
bind Text <Control-v> {
    tk::TextScrollPages %W 1
}

# End of Mac only bindings
}

# A few additional bindings of my own.

bind Text <Control-h> {
    if {!$tk_strictMotif && [%W compare insert != 1.0]} {
	%W delete insert-1c
	%W see insert
    }
}
bind Text <Button-2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
    }
}
set ::tk::Priv(prevPos) {}







bind Text <MouseWheel> {
    tk::MouseWheel %W y %D -3.0 pixels
}
bind Text <Option-MouseWheel> {
    tk::MouseWheel %W y %D -0.3 pixels
}
bind Text <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -3.0 pixels
}
bind Text <Shift-Option-MouseWheel> {









    tk::MouseWheel %W x %D -0.3 pixels























}

# ::tk::TextClosestGap --
# Given x and y coordinates, this procedure finds the closest boundary
# between characters to the given coordinates and returns the index
# of the character just after the boundary.
#







>
|
>
>
>
|
|
|

|
<
<
<
|
<
|
>
>

|
<
>

|
|

>
>
|
|
>
|
<















|











>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426



427

428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
}
bind Text <Meta-Delete> {
    if {!$tk_strictMotif} {
	%W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert
    }
}

# Macintosh only bindings:

if {[tk windowingsystem] eq "aqua"} {
bind Text <Option-Left> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <Option-Right> {
    tk::TextSetCursor %W [tk::TextNextWord %W insert]
}
bind Text <Option-Up> {



    tk::TextSetCursor %W [tk::TextPrevPara %W insert]

}
bind Text <Option-Down> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <Shift-Option-Left> {

    tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <Shift-Option-Right> {
    tk::TextKeySelect %W [tk::TextNextWord %W insert]
}
bind Text <Shift-Option-Up> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <Shift-Option-Down> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}

bind Text <Control-v> {
    tk::TextScrollPages %W 1
}

# End of Mac only bindings
}

# A few additional bindings of my own.

bind Text <Control-h> {
    if {!$tk_strictMotif && [%W compare insert != 1.0]} {
	%W delete insert-1c
	%W see insert
    }
}
bind Text <2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
    }
}
set ::tk::Priv(prevPos) {}

# The MouseWheel will typically only fire on Windows and MacOS X.
# However, someone could use the "event generate" command to produce one
# on other platforms.  We must be careful not to round -ve values of %D
# down to zero.

if {[tk windowingsystem] eq "aqua"} {
    bind Text <MouseWheel> {
        %W yview scroll [expr {-15 * (%D)}] pixels
    }
    bind Text <Option-MouseWheel> {
        %W yview scroll [expr {-150 * (%D)}] pixels
    }
    bind Text <Shift-MouseWheel> {
        %W xview scroll [expr {-15 * (%D)}] pixels
    }
    bind Text <Shift-Option-MouseWheel> {
        %W xview scroll [expr {-150 * (%D)}] pixels
    }
} else {
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/3 = 0,
    # but
    #     (int)-1/3 = -1
    # The following code ensure equal +/- behaviour.
    bind Text <MouseWheel> {
	if {%D >= 0} {
	    %W yview scroll [expr {-%D/3}] pixels
	} else {
	    %W yview scroll [expr {(2-%D)/3}] pixels
	}
    }
}

if {"x11" eq [tk windowingsystem]} {
    # Support for mousewheels on Linux/Unix commonly comes through mapping
    # the wheel to the extended buttons.  If you have a mousewheel, find
    # Linux configuration info at:
    #	http://www.inria.fr/koala/colas/mouse-wheel-scroll/
    bind Text <4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -50 pixels
	}
    }
    bind Text <5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 50 pixels
	}
    }
}

# ::tk::TextClosestGap --
# Given x and y coordinates, this procedure finds the closest boundary
# between characters to the given coordinates and returns the index
# of the character just after the boundary.
#
499
500
501
502
503
504
505




506

507
508
509
510
511
512
513
    # relative to the gap
    set bbox [$w bbox [$w index $anchorname]]
    if {$x > [lindex $bbox 0]} {
	$w mark gravity $anchorname right
    } else {
	$w mark gravity $anchorname left
    }




    focus $w

    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextSelectTo --
# This procedure is invoked to extend the selection, typically when







>
>
>
>
|
>







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
    # relative to the gap
    set bbox [$w bbox [$w index $anchorname]]
    if {$x > [lindex $bbox 0]} {
	$w mark gravity $anchorname right
    } else {
	$w mark gravity $anchorname left
    }
    # Allow focus in any case on Windows, because that will let the
    # selection be displayed even for state disabled text widgets.
    if {[tk windowingsystem] eq "win32" \
	    || [$w cget -state] eq "normal"} {
	focus $w
    }
    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextSelectTo --
# This procedure is invoked to extend the selection, typically when
533
534
535
536
537
538
539

540
541
542
543
544
545
546
    if {![info exists Priv(textanchor,$w)]} {
        set Priv(textanchor,$w) tk::anchor[incr Priv(textanchoruid)]
    }
    return $Priv(textanchor,$w)
}

proc ::tk::TextSelectTo {w x y {extend 0}} {

    variable ::tk::Priv

    set anchorname [tk::TextAnchor $w]
    set cur [TextClosestGap $w $x $y]
    if {[catch {$w index $anchorname}]} {
	$w mark set $anchorname $cur
    }







>







603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
    if {![info exists Priv(textanchor,$w)]} {
        set Priv(textanchor,$w) tk::anchor[incr Priv(textanchoruid)]
    }
    return $Priv(textanchor,$w)
}

proc ::tk::TextSelectTo {w x y {extend 0}} {
    global tcl_platform
    variable ::tk::Priv

    set anchorname [tk::TextAnchor $w]
    set cur [TextClosestGap $w $x $y]
    if {[catch {$w index $anchorname}]} {
	$w mark set $anchorname $cur
    }
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
	if {[$w compare $new < insert]} {
	    $w tag add sel $new insert
	} else {
	    $w tag add sel insert $new
	}
	$w mark set $anchorname insert
    } else {
        if {[catch {$w index $anchorname}]} {
            $w mark set $anchorname insert
        }
	if {[$w compare $new < $anchorname]} {
	    set first $new
	    set last $anchorname
	} else {
	    set first $anchorname
	    set last $new
	}







<
<
<







798
799
800
801
802
803
804



805
806
807
808
809
810
811
	if {[$w compare $new < insert]} {
	    $w tag add sel $new insert
	} else {
	    $w tag add sel insert $new
	}
	$w mark set $anchorname insert
    } else {



	if {[$w compare $new < $anchorname]} {
	    set first $new
	    set last $anchorname
	} else {
	    set first $anchorname
	    set last $new
	}
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888

proc ::tk::TextInsert {w s} {
    if {$s eq "" || [$w cget -state] eq "disabled"} {
	return
    }
    set compound 0
    if {[TextCursorInSelection $w]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	    set compound 1
	}
	$w delete sel.first sel.last
    }
    $w insert insert $s
    $w see insert
    if {$compound && $oldSeparator} {
	$w edit separator
	$w configure -autoseparators 1
    }
}

# ::tk::TextUpDownLine --
# Returns the index of the character one display line above or below the
# insertion cursor.  There is a tricky thing here: we want to maintain the
# original x position across repeated operations, even though some lines
# that will get passed through don't have enough characters to cover the
# original column.

#
# Arguments:
# w -		The text window in which the cursor is to move.
# n -		The number of display lines to move: -1 for up one line,
#		+1 for down one line.

proc ::tk::TextUpDownLine {w n} {
    variable ::tk::Priv

    set i [$w index insert]
    if {$Priv(prevPos) ne $i} {
	set Priv(textPosOrig) $i
    }
    set lines [$w count -displaylines $Priv(textPosOrig) $i]
    set new [$w index \
	    "$Priv(textPosOrig) + [expr {$lines + $n}] displaylines"]
    set Priv(prevPos) $new
    if {[$w compare $new == "end display lineend"] \
            || [$w compare $new == "insert display linestart"]} {
        set Priv(textPosOrig) $new
    }

    return $new
}

# ::tk::TextPrevPara --
# Returns the index of the beginning of the paragraph just before a given
# position in the text (the beginning of a paragraph is the first non-blank
# character after a blank line).







|
|


<





|







|
|
|
|
>
















<
|
|
|

>







900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944

945
946
947
948
949
950
951
952
953
954
955
956

proc ::tk::TextInsert {w s} {
    if {$s eq "" || [$w cget -state] eq "disabled"} {
	return
    }
    set compound 0
    if {[TextCursorInSelection $w]} {
	set compound [$w cget -autoseparators]
	if {$compound} {
	    $w configure -autoseparators 0
	    $w edit separator

	}
	$w delete sel.first sel.last
    }
    $w insert insert $s
    $w see insert
    if {$compound} {
	$w edit separator
	$w configure -autoseparators 1
    }
}

# ::tk::TextUpDownLine --
# Returns the index of the character one display line above or below the
# insertion cursor.  There are two tricky things here.  First, we want to
# maintain the original x position across repeated operations, even though
# some lines that will get passed through don't have enough characters to
# cover the original column.  Second, don't try to scroll past the
# beginning or end of the text.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# n -		The number of display lines to move: -1 for up one line,
#		+1 for down one line.

proc ::tk::TextUpDownLine {w n} {
    variable ::tk::Priv

    set i [$w index insert]
    if {$Priv(prevPos) ne $i} {
	set Priv(textPosOrig) $i
    }
    set lines [$w count -displaylines $Priv(textPosOrig) $i]
    set new [$w index \
	    "$Priv(textPosOrig) + [expr {$lines + $n}] displaylines"]

    if {[$w compare $new == end] \
	    || [$w compare $new == "insert display linestart"]} {
	set new $i
    }
    set Priv(prevPos) $new
    return $new
}

# ::tk::TextPrevPara --
# Returns the index of the beginning of the paragraph just before a given
# position in the text (the beginning of a paragraph is the first non-blank
# character after a blank line).
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042

1043
1044
1045
1046
1047
1048
1049
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        # make <<Cut>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
	set oldSeparator [$w cget -autoseparators]
	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	$w delete sel.first sel.last
	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion
# point in a text widget.
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textPaste w {

    if {![catch {::tk::GetSelection $w CLIPBOARD} sel]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	}
	if {[tk windowingsystem] ne "x11"} {







|





|













>







1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        # make <<Cut>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	$w delete sel.first sel.last
	if {$oldSeparator} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion
# point in a text widget.
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textPaste w {
    global tcl_platform
    if {![catch {::tk::GetSelection $w CLIPBOARD} sel]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	}
	if {[tk windowingsystem] ne "x11"} {
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
    if {($x != $Priv(x)) || ($y != $Priv(y))} {
	set Priv(mouseMoved) 1
    }
    if {[info exists Priv(mouseMoved)] && $Priv(mouseMoved)} {
	$w scan dragto $x $y
    }
}
# ::tk::TextUndoRedoProcessMarks --
#
# This proc is executed after an undo or redo action.
# It processes the list of undo/redo marks temporarily set in the
# text widget to positions delimiting where changes happened, and
# returns a flat list of ranges. The temporary marks are removed
# from the text widget.
#
# Arguments:
# w -	The text widget

proc ::tk::TextUndoRedoProcessMarks {w} {
    set indices {}
    set undoMarks {}

    # only consider the temporary marks set by an undo/redo action
    foreach mark [$w mark names] {
        if {[string range $mark 0 11] eq "tk::undoMark"} {
            lappend undoMarks $mark
        }
    }

    # transform marks into indices
    # the number of undo/redo marks is always even, each right mark
    # completes a left mark to give a range
    # this is true because:
    #   - undo/redo only deals with insertions and deletions of text
    #   - insertions may move marks but not delete them
    #   - when deleting text, marks located inside the deleted range
    #     are not erased but moved to the start of the deletion range
    #         . this is done in TkBTreeDeleteIndexRange ("This segment
    #           refuses to die...")
    #         . because MarkDeleteProc does nothing else than returning
    #           a value indicating that marks are not deleted by this
    #           deleteProc
    #         . mark deletion rather happen through [.text mark unset xxx]
    #           which was not used _up to this point of the code_ (it
    #           is a bit later just before exiting the present proc)
    set nUndoMarks [llength $undoMarks]
    set n [expr {$nUndoMarks / 2}]
    set undoMarks [lsort -dictionary $undoMarks]
    if {$n > 0} {
	set Lmarks [lrange $undoMarks 0 [expr {$n - 1}]]
    } else {
	set Lmarks {}
    }
    set Rmarks [lrange $undoMarks $n [llength $undoMarks]]
    foreach Lmark $Lmarks Rmark $Rmarks {
        lappend indices [$w index $Lmark] [$w index $Rmark]
        $w mark unset $Lmark $Rmark
    }

    # process ranges to:
    #   - remove those already fully included in another range
    #   - merge overlapping ranges
    set ind [lsort -dictionary -stride 2 $indices]
    set indices {}

    for {set i 0} {$i < $nUndoMarks} {incr i 2} {
        set il1 [lindex $ind $i]
        set ir1 [lindex $ind [expr {$i + 1}]]
        lappend indices $il1 $ir1

        for {set j [expr {$i + 2}]} {$j < $nUndoMarks} {incr j 2} {
            set il2 [lindex $ind $j]
            set ir2 [lindex $ind [expr {$j + 1}]]

            if {[$w compare $il2 > $ir1]} {
                # second range starts after the end of first range
                # -> further second ranges do not need to be considered
                #    because ranges were sorted by increasing first index
                set j $nUndoMarks
            } else {
                if {[$w compare $ir2 > $ir1]} {
                    # second range overlaps first range
                    # -> merge them into a single range
                    set indices [lreplace $indices end-1 end]
                    lappend indices $il1 $ir2
                } else {
                    # second range is fully included in first range
                    # -> ignore it
                }
                # in both cases above, the second range shall be
                # trimmed out from the list of ranges
                set ind [lreplace $ind $j [expr {$j + 1}]]
                incr j -2
                incr nUndoMarks -2
            }
        }
    }

    return $indices
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1232
1233
1234
1235
1236
1237
1238





























































































    if {($x != $Priv(x)) || ($y != $Priv(y))} {
	set Priv(mouseMoved) 1
    }
    if {[info exists Priv(mouseMoved)] && $Priv(mouseMoved)} {
	$w scan dragto $x $y
    }
}





























































































Changes to library/tk.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 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.

# Verify that we have Tk binary and script components from the same release
package require -exact Tk  8.7a4

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {
            # The msgcat package is not available.  Supply our own
            # minimal replacement.
            proc mc {src args} {
                return [format $src {*}$args]
            }
            proc mcmax {args} {
                set max 0
                foreach string $args {
                    set len [string length $string]





|
|
|





|
|






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 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.

# Verify that we have Tk binary and script components from the same release
package require -exact Tk  8.5.19

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {
            # The msgcat package is not available.  Supply our own minimal
            # replacement.
            proc mc {src args} {
                return [format $src {*}$args]
            }
            proc mcmax {args} {
                set max 0
                foreach string $args {
                    set len [string length $string]
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    }
}

# Add Ttk & Tk's directory to the end of the auto-load search path, if it
# isn't already on the path:

if {[info exists ::auto_path] && ($::tk_library ne "")
    && ($::tk_library ni $::auto_path)
} then {
    lappend ::auto_path $::tk_library $::ttk::library
}

# Turn off strict Motif look and feel as a default.

set ::tk_strictMotif 0

# Turn on useinputmethods (X Input Methods) by default.
# We catch this because safe interpreters may not allow the call.

catch {tk useinputmethods 1}

# ::tk::PlaceWindow --
#   place a toplevel at a particular position
# Arguments:
#   toplevel	name of toplevel window
#   ?placement?	pointer ?center? ; places $w centered on the pointer
#		widget widgetPath ; centers $w over widget_name
#		defaults to placing toplevel in the middle of the screen
#   ?anchor?	center or widgetPath
# Results:







|
<







|
|




|







51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    }
}

# Add Ttk & Tk's directory to the end of the auto-load search path, if it
# isn't already on the path:

if {[info exists ::auto_path] && ($::tk_library ne "")
    && ($::tk_library ni $::auto_path)} {

    lappend ::auto_path $::tk_library $::ttk::library
}

# Turn off strict Motif look and feel as a default.

set ::tk_strictMotif 0

# Turn on useinputmethods (X Input Methods) by default. We catch this because
# safe interpreters may not allow the call.

catch {tk useinputmethods 1}

# ::tk::PlaceWindow --
#   Place a toplevel at a particular position
# Arguments:
#   toplevel	name of toplevel window
#   ?placement?	pointer ?center? ; places $w centered on the pointer
#		widget widgetPath ; centers $w over widget_name
#		defaults to placing toplevel in the middle of the screen
#   ?anchor?	center or widgetPath
# Results:
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	if {$y < [winfo vrooty $w]} {
	    set y [winfo vrooty $w]
	} elseif {$y > ([winfo vrooty $w]+[winfo vrootheight $w]-[winfo reqheight $w])} {
	    set y [expr {[winfo vrooty $w]+[winfo vrootheight $w]-[winfo reqheight $w]}]
	}
	if {[tk windowingsystem] eq "aqua"} {
	    # Avoid the native menu bar which sits on top of everything.
	    if {$y < 22} {
		set y 22
	    }
	}
    }
    wm maxsize $w [winfo vrootwidth $w] [winfo vrootheight $w]
    wm geometry $w +$x+$y
    wm deiconify $w
}

# ::tk::SetFocusGrab --
#   swap out current focus and grab temporarily (for dialogs)
# Arguments:
#   grab	new window to grab
#   focus	window to give focus to
# Results:
#   Returns nothing
#
proc ::tk::SetFocusGrab {grab {focus {}}} {
    set index "$grab,$focus"
    upvar ::tk::FocusGrab($index) data

    lappend data [focus]
    set oldGrab [grab current $grab]
    lappend data $oldGrab
    if {[winfo exists $oldGrab]} {
	lappend data [grab status $oldGrab]
    }
    # The "grab" command will fail if another application
    # already holds the grab.  So catch it.
    catch {grab $grab}
    if {[winfo exists $focus]} {
	focus $focus
    }
}

# ::tk::RestoreFocusGrab --
#   restore old focus and grab (for dialogs)
# Arguments:
#   grab	window that had taken grab
#   focus	window that had taken focus
#   destroy	destroy|withdraw - how to handle the old grabbed window
# Results:
#   Returns nothing
#







|
<
<








|
















|
|







|







117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	if {$y < [winfo vrooty $w]} {
	    set y [winfo vrooty $w]
	} elseif {$y > ([winfo vrooty $w]+[winfo vrootheight $w]-[winfo reqheight $w])} {
	    set y [expr {[winfo vrooty $w]+[winfo vrootheight $w]-[winfo reqheight $w]}]
	}
	if {[tk windowingsystem] eq "aqua"} {
	    # Avoid the native menu bar which sits on top of everything.
	    if {$y < 22} { set y 22 }


	}
    }
    wm maxsize $w [winfo vrootwidth $w] [winfo vrootheight $w]
    wm geometry $w +$x+$y
    wm deiconify $w
}

# ::tk::SetFocusGrab --
#   Swap out current focus and grab temporarily (for dialogs)
# Arguments:
#   grab	new window to grab
#   focus	window to give focus to
# Results:
#   Returns nothing
#
proc ::tk::SetFocusGrab {grab {focus {}}} {
    set index "$grab,$focus"
    upvar ::tk::FocusGrab($index) data

    lappend data [focus]
    set oldGrab [grab current $grab]
    lappend data $oldGrab
    if {[winfo exists $oldGrab]} {
	lappend data [grab status $oldGrab]
    }
    # The "grab" command will fail if another application already holds the
    # grab.  So catch it.
    catch {grab $grab}
    if {[winfo exists $focus]} {
	focus $focus
    }
}

# ::tk::RestoreFocusGrab --
#   Restore old focus and grab (for dialogs)
# Arguments:
#   grab	window that had taken grab
#   focus	window that had taken focus
#   destroy	destroy|withdraw - how to handle the old grabbed window
# Results:
#   Returns nothing
#
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245



246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
	} else {
	    grab $oldGrab
	}
    }
}

# ::tk::GetSelection --
#   This tries to obtain the default selection.  On Unix, we first try
#   and get a UTF8_STRING, a type supported by modern Unix apps for
#   passing Unicode data safely.  We fall back on the default STRING
#   type otherwise.  On Windows, only the STRING type is necessary.
# Arguments:
#   w	The widget for which the selection will be retrieved.
#	Important for the -displayof property.
#   sel	The source of the selection (PRIMARY or CLIPBOARD)
# Results:
#   Returns the selection, or an error if none could be found
#
if {[tk windowingsystem] ne "win32"} {
    proc ::tk::GetSelection {w {sel PRIMARY}} {
	if {[catch {
	    selection get -displayof $w -selection $sel -type UTF8_STRING
	} txt] && [catch {
	    selection get -displayof $w -selection $sel
	} txt]} then {
	    return -code error -errorcode {TK SELECTION NONE} \
		"could not find default selection"
	} else {
	    return $txt
	}
    }
} else {
    proc ::tk::GetSelection {w {sel PRIMARY}} {
	if {[catch {
	    selection get -displayof $w -selection $sel
	} txt]} then {
	    return -code error -errorcode {TK SELECTION NONE} \
		"could not find default selection"
	} else {
	    return $txt
	}
    }
}

# ::tk::ScreenChanged --
# This procedure is invoked by the binding mechanism whenever the
# "current" screen is changing.  The procedure does two things.
# First, it uses "upvar" to make variable "::tk::Priv" point at an
# array variable that holds state for the current display.  Second,
# it initializes the array if it didn't already exist.
#
# Arguments:
# screen -		The name of the new screen.

proc ::tk::ScreenChanged screen {
    # Extract the display name.

    set disp [string range $screen 0 [string last . $screen]-1]




    # Ensure that namespace separators never occur in the display name (as
    # they cause problems in variable names). Double-colons exist in some VNC
    # display names. [Bug 2912473]
    set disp [string map {:: _doublecolon_} $disp]

    uplevel #0 [list upvar #0 ::tk::Priv.$disp ::tk::Priv]
    variable ::tk::Priv


    if {[info exists Priv]} {
	set Priv(screen) $screen
	return
    }
    array set Priv {
	activeMenu	{}







|
|
|
|









<
|
|
|
<
<
|






<
|
<
<
|







|
|
|
|
|




|
|
>
|
>
>
>








>







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208


209
210
211
212
213
214
215

216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	} else {
	    grab $oldGrab
	}
    }
}

# ::tk::GetSelection --
#   This tries to obtain the default selection.  On Unix, we first try and get
#   a UTF8_STRING, a type supported by modern Unix apps for passing Unicode
#   data safely.  We fall back on the default STRING type otherwise.  On
#   Windows, only the STRING type is necessary.
# Arguments:
#   w	The widget for which the selection will be retrieved.
#	Important for the -displayof property.
#   sel	The source of the selection (PRIMARY or CLIPBOARD)
# Results:
#   Returns the selection, or an error if none could be found
#
if {[tk windowingsystem] ne "win32"} {
    proc ::tk::GetSelection {w {sel PRIMARY}} {

	if {[catch {selection get -displayof $w -selection $sel \
		-type UTF8_STRING} txt] \
		&& [catch {selection get -displayof $w -selection $sel} txt]} {


	    return -code error "could not find default selection"
	} else {
	    return $txt
	}
    }
} else {
    proc ::tk::GetSelection {w {sel PRIMARY}} {

	if {[catch {selection get -displayof $w -selection $sel} txt]} {


	    return -code error "could not find default selection"
	} else {
	    return $txt
	}
    }
}

# ::tk::ScreenChanged --
# This procedure is invoked by the binding mechanism whenever the "current"
# screen is changing.  The procedure does two things.  First, it uses "upvar"
# to make variable "::tk::Priv" point at an array variable that holds state
# for the current display.  Second, it initializes the array if it didn't
# already exist.
#
# Arguments:
# screen -		The name of the new screen.

proc ::tk::ScreenChanged {screen} {
    set x [string last . $screen]
    if {$x > 0} {
	set disp [string range $screen 0 [expr {$x - 1}]]
    } else {
	set disp $screen
    }

    # Ensure that namespace separators never occur in the display name (as
    # they cause problems in variable names). Double-colons exist in some VNC
    # display names. [Bug 2912473]
    set disp [string map {:: _doublecolon_} $disp]

    uplevel #0 [list upvar #0 ::tk::Priv.$disp ::tk::Priv]
    variable ::tk::Priv
    global tcl_platform

    if {[info exists Priv]} {
	set Priv(screen) $screen
	return
    }
    array set Priv {
	activeMenu	{}
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646

647
648
649
650
651



652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
# Do initial setup for Priv, so that it is always bound to something
# (otherwise, if someone references it, it may get set to a non-upvar-ed
# value, which will cause trouble later).

tk::ScreenChanged [winfo screen .]

# ::tk::EventMotifBindings --
# This procedure is invoked as a trace whenever ::tk_strictMotif is
# changed.  It is used to turn on or turn off the motif virtual
# bindings.
#
# Arguments:
# n1 - the name of the variable being changed ("::tk_strictMotif").

proc ::tk::EventMotifBindings {n1 dummy dummy} {
    upvar $n1 name

    if {$name} {
	set op delete
    } else {
	set op add
    }

    event $op <<Cut>> <Control-w> <Control-Lock-W> <Shift-Delete>
    event $op <<Copy>> <Meta-w> <Meta-Lock-W> <Control-Insert>
    event $op <<Paste>> <Control-y> <Control-Lock-Y> <Shift-Insert>
    event $op <<PrevChar>> <Control-b> <Control-Lock-B>
    event $op <<NextChar>> <Control-f> <Control-Lock-F>
    event $op <<PrevLine>> <Control-p> <Control-Lock-P>
    event $op <<NextLine>> <Control-n> <Control-Lock-N>
    event $op <<LineStart>> <Control-a> <Control-Lock-A>
    event $op <<LineEnd>> <Control-e> <Control-Lock-E>
    event $op <<SelectPrevChar>> <Control-B> <Control-Lock-b>
    event $op <<SelectNextChar>> <Control-F> <Control-Lock-f>
    event $op <<SelectPrevLine>> <Control-P> <Control-Lock-p>
    event $op <<SelectNextLine>> <Control-N> <Control-Lock-n>
    event $op <<SelectLineStart>> <Control-A> <Control-Lock-a>
    event $op <<SelectLineEnd>> <Control-E> <Control-Lock-e>
}

#----------------------------------------------------------------------
# Define common dialogs on platforms where they are not implemented
# using compiled code.
#----------------------------------------------------------------------

if {![llength [info commands tk_chooseColor]]} {
    proc ::tk_chooseColor {args} {
	return [::tk::dialog::color:: {*}$args]
    }
}
if {![llength [info commands tk_getOpenFile]]} {
    proc ::tk_getOpenFile {args} {
	if {$::tk_strictMotif} {
	    return [::tk::MotifFDialog open {*}$args]
	} else {
	    return [::tk::dialog::file:: open {*}$args]
	}
    }
}
if {![llength [info commands tk_getSaveFile]]} {
    proc ::tk_getSaveFile {args} {
	if {$::tk_strictMotif} {
	    return [::tk::MotifFDialog save {*}$args]
	} else {
	    return [::tk::dialog::file:: save {*}$args]
	}
    }
}
if {![llength [info commands tk_messageBox]]} {
    proc ::tk_messageBox {args} {
	return [::tk::MessageBox {*}$args]
    }
}
if {![llength [info command tk_chooseDirectory]]} {
    proc ::tk_chooseDirectory {args} {
	return [::tk::dialog::file::chooseDir:: {*}$args]
    }
}

#----------------------------------------------------------------------
# Define the set of common virtual events.
#----------------------------------------------------------------------

event add <<ContextMenu>>	<Button-3>
event add <<PasteSelection>>	<ButtonRelease-2>

switch -exact -- [tk windowingsystem] {
    "x11" {
	event add <<Cut>>		<Control-x> <F20> <Control-Lock-X>
	event add <<Copy>>		<Control-c> <F16> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <F18> <Control-Lock-V>
	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-Z> <Control-Lock-z>
	# On Darwin/Aqua, buttons from left to right are 1,3,2.  On Darwin/X11 with recent
	# XQuartz as the X server, they are 1,2,3; other X servers may differ.

	event add <<SelectAll>>		<Control-slash>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>
	event add <<PrevWord>>		<Control-Left>
	event add <<SelectPrevWord>>	<Control-Shift-Left>
	event add <<LineStart>>		<Home>
	event add <<SelectLineStart>>	<Shift-Home>
	event add <<LineEnd>>		<End>
	event add <<SelectLineEnd>>	<Shift-End>
	event add <<PrevLine>>		<Up>
	event add <<NextLine>>		<Down>
	event add <<SelectPrevLine>>	<Shift-Up>
	event add <<SelectNextLine>>	<Shift-Down>
	event add <<PrevPara>>		<Control-Up>
	event add <<NextPara>>		<Control-Down>
	event add <<SelectPrevPara>>	<Control-Shift-Up>
	event add <<SelectNextPara>>	<Control-Shift-Down>
	event add <<ToggleSelection>>	<Control-Button-1>

	# Some OS's define a goofy (as in, not <Shift-Tab>) keysym that is
	# returned when the user presses <Shift-Tab>. In order for tab
	# traversal to work, we have to add these keysyms to the PrevWindow
	# event. We use catch just in case the keysym isn't recognized.

	# This is needed for XFree86 systems
	catch { event add <<PrevWindow>> <ISO_Left_Tab> }
	# This seems to be correct on *some* HP systems.
	catch { event add <<PrevWindow>> <hpBackTab> }

	trace add variable ::tk_strictMotif write ::tk::EventMotifBindings
	set ::tk_strictMotif $::tk_strictMotif
	# On unix, we want to always display entry/text selection,
	# regardless of which window has focus
	set ::tk::AlwaysShowSelection 1
    }
    "win32" {
	event add <<Cut>>		<Control-x> <Shift-Delete> <Control-Lock-X>
	event add <<Copy>>		<Control-c> <Control-Insert> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <Shift-Insert> <Control-Lock-V>
  	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-y> <Control-Lock-Y>

	event add <<SelectAll>>		<Control-slash> <Control-a> <Control-Lock-A>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>
	event add <<PrevWord>>		<Control-Left>
	event add <<SelectPrevWord>>	<Control-Shift-Left>
	event add <<LineStart>>		<Home>
	event add <<SelectLineStart>>	<Shift-Home>
	event add <<LineEnd>>		<End>
	event add <<SelectLineEnd>>	<Shift-End>
	event add <<PrevLine>>		<Up>
	event add <<NextLine>>		<Down>
	event add <<SelectPrevLine>>	<Shift-Up>
	event add <<SelectNextLine>>	<Shift-Down>
	event add <<PrevPara>>		<Control-Up>
	event add <<NextPara>>		<Control-Down>
	event add <<SelectPrevPara>>	<Control-Shift-Up>
	event add <<SelectNextPara>>	<Control-Shift-Down>
	event add <<ToggleSelection>>	<Control-Button-1>
    }
    "aqua" {
	event add <<Cut>>		<Command-x> <F2> <Command-Lock-X>
	event add <<Copy>>		<Command-c> <F3> <Command-Lock-C>

	event add <<Paste>>		<Command-v> <F4> <Command-Lock-V>
	event add <<Clear>>		<Clear>

	# Official bindings
	# See http://support.apple.com/kb/HT1343
	event add <<SelectAll>>		<Command-a>
	event add <<Undo>>		<Command-Key-z> <Command-Lock-Key-Z>
	event add <<Redo>>		<Shift-Command-Key-z> <Shift-Command-Lock-Key-z>
	event add <<NextChar>>		<Right> <Control-Key-f> <Control-Lock-Key-F>
	event add <<SelectNextChar>>	<Shift-Right> <Shift-Control-Key-F> <Shift-Control-Lock-Key-F>
	event add <<PrevChar>>		<Left> <Control-Key-b> <Control-Lock-Key-B>
	event add <<SelectPrevChar>>	<Shift-Left> <Shift-Control-Key-B> <Shift-Control-Lock-Key-B>
	event add <<NextWord>>		<Option-Right>
	event add <<SelectNextWord>>	<Shift-Option-Right>
	event add <<PrevWord>>		<Option-Left>
	event add <<SelectPrevWord>>	<Shift-Option-Left>
	event add <<LineStart>>		<Home> <Command-Left> <Control-a> <Control-Lock-A>
	event add <<SelectLineStart>>	<Shift-Home> <Shift-Command-Left> <Shift-Control-A> <Shift-Control-Lock-A>
	event add <<LineEnd>>		<End> <Command-Right> <Control-e> <Control-Lock-E>
	event add <<SelectLineEnd>>	<Shift-End> <Shift-Command-Right> <Shift-Control-E> <Shift-Control-Lock-E>
	event add <<PrevLine>>		<Up> <Control-p> <Control-Lock-P>
	event add <<SelectPrevLine>>	<Shift-Up> <Shift-Control-P> <Shift-Control-Lock-P>
	event add <<NextLine>>		<Down> <Control-n> <Control-Lock-N>
	event add <<SelectNextLine>>	<Shift-Down> <Shift-Control-N> <Shift-Control-Lock-N>
	# Not official, but logical extensions of above. Also derived from
	# bindings present in MS Word on OSX.
	event add <<PrevPara>>		<Option-Up>
	event add <<NextPara>>		<Option-Down>
	event add <<SelectPrevPara>>	<Shift-Option-Up>
	event add <<SelectNextPara>>	<Shift-Option-Down>
	event add <<ToggleSelection>>	<Command-Button-1>
    }
}

# ----------------------------------------------------------------------
# Read in files that define all of the class bindings.
# ----------------------------------------------------------------------

if {$::tk_library ne ""} {
    proc ::tk::SourceLibFile {file} {
        namespace eval :: [list source -encoding utf-8 [file join $::tk_library $file.tcl]]
    }
    namespace eval ::tk {
	SourceLibFile icons
	SourceLibFile button
	SourceLibFile entry
	SourceLibFile listbox
	SourceLibFile menu
	SourceLibFile panedwindow
	SourceLibFile scale
	SourceLibFile scrlbar
	SourceLibFile spinbox
	SourceLibFile text
    }
}

# ----------------------------------------------------------------------
# Default bindings for keyboard traversal.
# ----------------------------------------------------------------------

event add <<PrevWindow>> <Shift-Tab>
event add <<NextWindow>> <Tab>
bind all <<NextWindow>> {tk::TabToWindow [tk_focusNext %W]}
bind all <<PrevWindow>> {tk::TabToWindow [tk_focusPrev %W]}

# ::tk::CancelRepeat --
# This procedure is invoked to cancel an auto-repeat action described
# by ::tk::Priv(afterId).  It's used by several widgets to auto-scroll
# the widget when the mouse is dragged out of the widget with a
# button pressed.
#
# Arguments:
# None.

proc ::tk::CancelRepeat {} {
    variable ::tk::Priv
    after cancel $Priv(afterId)
    set Priv(afterId) {}
}

## ::tk::MouseWheel $w $dir $amount $factor $units

proc ::tk::MouseWheel {w dir amount {factor -120.0} {units units}} {
    $w ${dir}view scroll [expr {$amount/$factor}] $units
}


# ::tk::TabToWindow --
# This procedure moves the focus to the given widget.
# It sends a <<TraverseOut>> virtual event to the previous focus window,
# if any, before changing the focus, and a <<TraverseIn>> event
# to the new focus window afterwards.
#
# Arguments:
# w - Window to which focus should be set.

proc ::tk::TabToWindow {w} {
    set focus [focus]
    if {$focus ne ""} {
	event generate $focus <<TraverseOut>>
    }
    focus $w
    event generate $w <<TraverseIn>>
}

# ::tk::UnderlineAmpersand --
#	This procedure takes some text with ampersand and returns text w/o
#	ampersand and position of the ampersand.  Double ampersands are
#	converted to single ones.  Position returned is -1 when there is no
#	ampersand.
#
proc ::tk::UnderlineAmpersand {text} {
    set s [string map {&& & & \ufeff} $text]
    set idx [string first \ufeff $s]
    return [list [string map {\ufeff {}} $s] $idx]
}

# ::tk::SetAmpText --
#	Given widget path and text with "magic ampersands", sets -text and
#	-underline options for the widget
#
proc ::tk::SetAmpText {widget text} {
    lassign [UnderlineAmpersand $text] newtext under
    $widget configure -text $newtext -underline $under
}

# ::tk::AmpWidget --
#	Creates new widget, turning -text option into -text and -underline
#	options, returned by ::tk::UnderlineAmpersand.
#
proc ::tk::AmpWidget {class path args} {
    set options {}
    foreach {opt val} $args {
	if {$opt eq "-text"} {
	    lassign [UnderlineAmpersand $val] newtext under
	    lappend options -text $newtext -underline $under
	} else {
	    lappend options $opt $val
	}
    }
    set result [$class $path {*}$options]
    if {[string match "*button" $class]} {
	bind $path <<AltUnderlined>> [list $path invoke]
    }
    return $result
}

# ::tk::AmpMenuArgs --
#	Processes arguments for a menu entry, turning -label option into
#	-label and -underline options, returned by ::tk::UnderlineAmpersand.
#      The cmd argument is supposed to be either "add" or "entryconfigure"
#
proc ::tk::AmpMenuArgs {widget cmd type args} {
    set options {}
    foreach {opt val} $args {
	if {$opt eq "-label"} {
	    lassign [UnderlineAmpersand $val] newlabel under
	    lappend options -label $newlabel -underline $under
	} else {
	    lappend options $opt $val
	}
    }
    $widget $cmd $type {*}$options
}

# ::tk::FindAltKeyTarget --
#	Search recursively through the hierarchy of visible widgets to find
#	button or label which has $char as underlined character.
#
proc ::tk::FindAltKeyTarget {path char} {
    set class [winfo class $path]
    if {$class in {
	Button Checkbutton Label Radiobutton
	TButton TCheckbutton TLabel TRadiobutton
    } && [string equal -nocase $char \
	    [string index [$path cget -text] [$path cget -underline]]]} {
	return $path
    }
    set subwins [concat [grid content $path] [pack content $path] \
	    [place content $path]]
    if {$class eq "Canvas"} {
	foreach item [$path find all] {
	    if {[$path type $item] eq "window"} {
		set w [$path itemcget $item -window]
		if {$w ne ""} {lappend subwins $w}
	    }
	}
    } elseif {$class eq "Text"} {
	lappend subwins {*}[$path window names]
    }

    foreach child $subwins {

	set target [FindAltKeyTarget $child $char]
	if {$target ne ""} {
	    return $target
	}
    }



}

# ::tk::AltKeyInDialog --
#	<Alt-Key> event handler for standard dialogs. Sends <<AltUnderlined>>
#	to button or label which has appropriate underlined character.
#
proc ::tk::AltKeyInDialog {path key} {
    set target [FindAltKeyTarget $path $key]
    if {$target ne ""} {
	event generate $target <<AltUnderlined>>
    }
}

# ::tk::mcmaxamp --
#	Replacement for mcmax, used for texts with "magic ampersand" in it.
#

proc ::tk::mcmaxamp {args} {
    set maxlen 0
    foreach arg $args {
	# Should we run [mc] in caller's namespace?
	lassign [UnderlineAmpersand [mc $arg]] msg
	set length [string length $msg]
	if {$length > $maxlen} {
	    set maxlen $length
	}
    }
    return $maxlen
}

# For now, turn off the custom mdef proc for the Mac:

if {[tk windowingsystem] eq "aqua"} {
    namespace eval ::tk::mac {
	set useCustomMDEF 0
    }
}


if {[tk windowingsystem] eq "aqua"} {
    #stub procedures to respond to "do script" Apple Events
    proc ::tk::mac::DoScriptFile {file} {
	uplevel #0 $file
    	source -encoding utf-8 $file
    }
    proc ::tk::mac::DoScriptText {script} {
	uplevel #0 $script
    	eval $script
    }
}

# Create a dictionary to store the starting index of the IME marked
# text in an Entry or Text widget.

set ::tk::Priv(IMETextMark) [dict create]

# Run the Ttk themed widget set initialization
if {$::ttk::library ne ""} {
    uplevel \#0 [list source -encoding utf-8 $::ttk::library/ttk.tcl]
}

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|
|
<






|






|
|
|
<
<
<
<
<
<
<
<
<
<
<
<



|
|




|





|








|







|












<
<
<


|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|



|
<
|






|
|



|
<
<
|
<
|
|
<
<
<
|
<
<
<
|
<
<
<
<
<
|
|
<
<
|
<
<
<
<


|
|
>
|
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|






|


<

















<
|



|
|
|
<










<
<
<
<
<
<
<


|
|
|














|
|
|
<







|
|
|







|
|



















|
|
<

|









|

|

|
|


|
<
|
|
|
|
|
|
<
<
|
<
<
<
<


<
<
<
>
|
>
|
|
|
|
|
>
>
>



|
|



|
|
|
|
<

|















|



|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|






282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306












307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351



352
353
354
355





356














357
358







359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375
376


377

378
379



380



381





382
383


384




385
386
387
388
389
390
391
392




393























394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429

430
431
432
433
434
435
436
437
438
439







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527


528




529
530



531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578


















579
580
581
582
583
584
585
586
587
# Do initial setup for Priv, so that it is always bound to something
# (otherwise, if someone references it, it may get set to a non-upvar-ed
# value, which will cause trouble later).

tk::ScreenChanged [winfo screen .]

# ::tk::EventMotifBindings --
# This procedure is invoked as a trace whenever ::tk_strictMotif is changed.
# It is used to turn on or turn off the motif virtual bindings.

#
# Arguments:
# n1 - the name of the variable being changed ("::tk_strictMotif").

proc ::tk::EventMotifBindings {n1 dummy dummy} {
    upvar $n1 name
    
    if {$name} {
	set op delete
    } else {
	set op add
    }

    event $op <<Cut>> <Control-Key-w>
    event $op <<Copy>> <Meta-Key-w> 
    event $op <<Paste>> <Control-Key-y>












}

#----------------------------------------------------------------------
# Define common dialogs on platforms where they are not implemented using
# compiled code.
#----------------------------------------------------------------------

if {![llength [info commands tk_chooseColor]]} {
    proc ::tk_chooseColor {args} {
	return [tk::dialog::color:: {*}$args]
    }
}
if {![llength [info commands tk_getOpenFile]]} {
    proc ::tk_getOpenFile {args} {
	if {$::tk_strictMotif} {
	    return [tk::MotifFDialog open {*}$args]
	} else {
	    return [::tk::dialog::file:: open {*}$args]
	}
    }
}
if {![llength [info commands tk_getSaveFile]]} {
    proc ::tk_getSaveFile {args} {
	if {$::tk_strictMotif} {
	    return [tk::MotifFDialog save {*}$args]
	} else {
	    return [::tk::dialog::file:: save {*}$args]
	}
    }
}
if {![llength [info commands tk_messageBox]]} {
    proc ::tk_messageBox {args} {
	return [tk::MessageBox {*}$args]
    }
}
if {![llength [info command tk_chooseDirectory]]} {
    proc ::tk_chooseDirectory {args} {
	return [::tk::dialog::file::chooseDir:: {*}$args]
    }
}

#----------------------------------------------------------------------
# Define the set of common virtual events.
#----------------------------------------------------------------------




switch -exact -- [tk windowingsystem] {
    "x11" {
	event add <<Cut>> <Control-Key-x> <Key-F20> <Control-Lock-Key-X>
	event add <<Copy>> <Control-Key-c> <Key-F16> <Control-Lock-Key-C>





	event add <<Paste>> <Control-Key-v> <Key-F18> <Control-Lock-Key-V>














	event add <<PasteSelection>> <ButtonRelease-2>
	event add <<Undo>> <Control-Key-z> <Control-Lock-Key-Z>







	event add <<Redo>> <Control-Key-Z> <Control-Lock-Key-z>
	# Some OS's define a goofy (as in, not <Shift-Tab>) keysym that is
	# returned when the user presses <Shift-Tab>. In order for tab
	# traversal to work, we have to add these keysyms to the PrevWindow
	# event. We use catch just in case the keysym isn't recognized. This

	# is needed for XFree86 systems
	catch { event add <<PrevWindow>> <ISO_Left_Tab> }
	# This seems to be correct on *some* HP systems.
	catch { event add <<PrevWindow>> <hpBackTab> }

	trace add variable ::tk_strictMotif write ::tk::EventMotifBindings
	set ::tk_strictMotif $::tk_strictMotif
	# On unix, we want to always display entry/text selection, regardless
	# of which window has focus
	set ::tk::AlwaysShowSelection 1
    }
    "win32" {
	event add <<Cut>> <Control-Key-x> <Shift-Key-Delete> \


	    <Control-Lock-Key-X>

	event add <<Copy>> <Control-Key-c> <Control-Key-Insert> \
	    <Control-Lock-Key-C>



	event add <<Paste>> <Control-Key-v> <Shift-Key-Insert> \



	    <Control-Lock-Key-V>





	event add <<PasteSelection>> <ButtonRelease-2>
  	event add <<Undo>> <Control-Key-z> <Control-Lock-Key-Z>


	event add <<Redo>> <Control-Key-y> <Control-Lock-Key-Y>




    }
    "aqua" {
	event add <<Cut>> <Command-Key-x> <Key-F2> <Control-Lock-Key-X>
	event add <<Copy>> <Command-Key-c> <Key-F3> <Control-Lock-Key-C>
	event add <<Paste>> <Command-Key-v> <Key-F4> <Control-Lock-Key-V>
	event add <<PasteSelection>> <ButtonRelease-2>
	event add <<Clear>> <Clear>
  	event add <<Undo>> <Command-Key-z> <Control-Lock-Key-Z>




	event add <<Redo>> <Command-Key-y> <Control-Lock-Key-Y>























    }
}

# ----------------------------------------------------------------------
# Read in files that define all of the class bindings.
# ----------------------------------------------------------------------

if {$::tk_library ne ""} {
    proc ::tk::SourceLibFile {file} {
        namespace eval :: [list source [file join $::tk_library $file.tcl]]
    }
    namespace eval ::tk {

	SourceLibFile button
	SourceLibFile entry
	SourceLibFile listbox
	SourceLibFile menu
	SourceLibFile panedwindow
	SourceLibFile scale
	SourceLibFile scrlbar
	SourceLibFile spinbox
	SourceLibFile text
    }
}

# ----------------------------------------------------------------------
# Default bindings for keyboard traversal.
# ----------------------------------------------------------------------

event add <<PrevWindow>> <Shift-Tab>

bind all <Tab> {tk::TabToWindow [tk_focusNext %W]}
bind all <<PrevWindow>> {tk::TabToWindow [tk_focusPrev %W]}

# ::tk::CancelRepeat --
# This procedure is invoked to cancel an auto-repeat action described by
# ::tk::Priv(afterId).  It's used by several widgets to auto-scroll the widget
# when the mouse is dragged out of the widget with a button pressed.

#
# Arguments:
# None.

proc ::tk::CancelRepeat {} {
    variable ::tk::Priv
    after cancel $Priv(afterId)
    set Priv(afterId) {}
}








# ::tk::TabToWindow --
# This procedure moves the focus to the given widget.
# It sends a <<TraverseOut>> virtual event to the previous focus window, if
# any, before changing the focus, and a <<TraverseIn>> event to the new focus
# window afterwards.
#
# Arguments:
# w - Window to which focus should be set.

proc ::tk::TabToWindow {w} {
    set focus [focus]
    if {$focus ne ""} {
	event generate $focus <<TraverseOut>>
    }
    focus $w
    event generate $w <<TraverseIn>>
}

# ::tk::UnderlineAmpersand --
# This procedure takes some text with ampersand and returns text w/o ampersand
# and position of the ampersand.  Double ampersands are converted to single
# ones.  Position returned is -1 when there is no ampersand.

#
proc ::tk::UnderlineAmpersand {text} {
    set s [string map {&& & & \ufeff} $text]
    set idx [string first \ufeff $s]
    return [list [string map {\ufeff {}} $s] $idx]
}

# ::tk::SetAmpText -- 
# Given widget path and text with "magic ampersands", sets -text and
# -underline options for the widget
#
proc ::tk::SetAmpText {widget text} {
    lassign [UnderlineAmpersand $text] newtext under
    $widget configure -text $newtext -underline $under
}

# ::tk::AmpWidget --
# Creates new widget, turning -text option into -text and -underline options,
# returned by ::tk::UnderlineAmpersand.
#
proc ::tk::AmpWidget {class path args} {
    set options {}
    foreach {opt val} $args {
	if {$opt eq "-text"} {
	    lassign [UnderlineAmpersand $val] newtext under
	    lappend options -text $newtext -underline $under
	} else {
	    lappend options $opt $val
	}
    }
    set result [$class $path {*}$options]
    if {[string match "*button" $class]} {
	bind $path <<AltUnderlined>> [list $path invoke]
    }
    return $result
}

# ::tk::AmpMenuArgs --
# Processes arguments for a menu entry, turning -label option into -label and
# -underline options, returned by ::tk::UnderlineAmpersand.

#
proc ::tk::AmpMenuArgs {widget add type args} {
    set options {}
    foreach {opt val} $args {
	if {$opt eq "-label"} {
	    lassign [UnderlineAmpersand $val] newlabel under
	    lappend options -label $newlabel -underline $under
	} else {
	    lappend options $opt $val
	}
    }
    $widget add $type {*}$options
}

# ::tk::FindAltKeyTarget --
# Search recursively through the hierarchy of visible widgets to find button
# or label which has $char as underlined character
#
proc ::tk::FindAltKeyTarget {path char} {
    switch -- [winfo class $path] {

	Button - Label - 
        TButton - TLabel - TCheckbutton {
	    if {[string equal -nocase $char \
		  [string index [$path cget -text] [$path cget -underline]]]} {
		return $path
	    } else {


		return {}




	    }
	}



	default {
	    foreach child [concat [grid slaves $path] \
		    [pack slaves $path] [place slaves $path]] {
		set target [FindAltKeyTarget $child $char]
		if {$target ne ""} {
		    return $target
		}
	    }
	}
    }
    return {}
}

# ::tk::AltKeyInDialog --
# <Alt-Key> event handler for standard dialogs. Sends <<AltUnderlined>> to
# button or label which has appropriate underlined character
#
proc ::tk::AltKeyInDialog {path key} {
    set target [FindAltKeyTarget $path $key]
    if { $target eq ""} return
    event generate $target <<AltUnderlined>>
}


# ::tk::mcmaxamp --
# Replacement for mcmax, used for texts with "magic ampersand" in it.
#

proc ::tk::mcmaxamp {args} {
    set maxlen 0
    foreach arg $args {
	# Should we run [mc] in caller's namespace?
	lassign [UnderlineAmpersand [mc $arg]] msg
	set length [string length $msg]
	if {$length > $maxlen} {
	    set maxlen $length
	}
    }
    return $maxlen
}

# For now, turn off the custom mdef proc for the mac:

if {[tk windowingsystem] eq "aqua"} {
    namespace eval ::tk::mac {
	variable useCustomMDEF 0
    }
}



















# Run the Ttk themed widget set initialization
if {$::ttk::library ne ""} {
    uplevel \#0 [list source [file join $::ttk::library ttk.tcl]]
}

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to library/tkfbox.tcl.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18








































































































































































































































































































































































































































































































































































































































































































































































































19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# tkfbox.tcl --
#
#	Implements the "TK" standard file selection dialog box.  This dialog
#	box is used on the Unix platforms whenever the tk_strictMotif flag is
#	not set.
#
#	The "TK" standard file selection dialog box is similar to the file
#	selection dialog box on Win95(TM).  The user can navigate the
#	directories by clicking on the folder icons or by selecting the
#	"Directory" option menu.  The user can select files by clicking on the

#	file icons or by entering a filename in the "Filename:" entry.
#
# Copyright © 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.
#









































































































































































































































































































































































































































































































































































































































































































































































































namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {
    namespace import -force ::tk::msgcat::*
    variable showHiddenBtn 0
    variable showHiddenVar 1

    # Create the images if they did not already exist.
    if {![info exists ::tk::Priv(updirImage)]} {
	set ::tk::Priv(updirImage) [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QA/gD+AP7rGN
	    SCAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAACXZwQWcAAAAWAAAAFgDcxelYAAAENUlE
	    QVQ4y7WUbWiVZRjHf/f9POcc9+Kc5bC2aIq5sGG0XnTzNU13zAIlFMNc9CEhTCKwCC
	    JIgt7AglaR0RcrolAKg14+GBbiGL6xZiYyy63cmzvu7MVznnOe537rw7bDyvlBoT/c
	    n+6L3/3nf13XLZLJJP+HfICysjKvqqpq+rWKysvLR1tbW+11g+fPn/+bEGIe4KYqCs
	    Owu66u7oG2trah6wJrrRc0NTVhjME5h7Vj5pxzCCE4duxYZUdHx/aGhoZmgJ+yb+wF
	    uCO19RmAffv25f8LFslkktraWtvU1CS6u7vRWmOtxVpbAPu+T0tLS04pFU/J34Wd3S
	    cdFtlfZWeZBU4IcaS5uXn1ZLAEMMY4ay1aa4wx/zpKKYIgoL6+vmjxqoXe5ZLTcsPq
	    bTyycjODpe1y3WMrvDAMV14jCuW0VhhjiJQpOJ5w7Zwjk8/y9R+vsHHNNq6oFMrkeX
	    BxI+8d2sktap3YvOPD0lRQrH+Z81fE7t3WB4gihVKazsuaA20aKSUgAG/seQdy2l6W
	    37+EyopqTv39I6HJUT2zlnlza2jLdgiTaxwmDov6alLHcZUTzXPGGAauWJbfO4dHl9
	    bgJs3HyfNf0N4ZsOa+jbT3/ownY/hO09p1kBULtjBw+Tvq7xzwauds4dWPDleAcP5E
	    xlprgtBRUZRgYCRPTzoHwEi2g6OnX+eFrW/RM9qBE4p43CeTz5ATaU6nDrFm2cPs/+
	    E1SopqkZ7MFJqntXZaa7IKppckwIEvJbg8LWd28OT6nVihCPQQ8UScWCLGqO4hXuQx
	    qDtJ204eWrqWb1ufRspwtABWaqx5gRKUFSdwDnxPcuLcyyxbuIyaqntIBV34MY9YzC
	    Owg+S9YeJFkniRpGPkCLMrZzG3+jbktA/KClMxFoUhiKC0OAbAhd79CO8i6xe/STyW
	    4O7KVRgUJ/sP0heeJV4kEVKw/vZd40sFKxat4mLvp6VLdvnb/XHHGGPIKwBBpC1/9n
	    3DpfRZnn9/AwCxRII9O79kVPdjvByxuET6Ai8mePeTt4lyheXzhOSpCcdWa00uckTG
	    kckbGu76nEhbIm2xznH4VB3OWYaiXqQn8GKSWGIMHuXyPL76LBcupmhp69pz4uMnXi
	    w4VloTGcdQRtGdzmHs1f+RdYZslMZJhzUOHVnceN1ooEiP5JUzdqCQMWCD0JCIeQzn
	    NNpO+clhrCYf5rC+A2cxWmDUWG2oHEOZMEKIwclgMnnLrTeXUV7sUzpNXgU9DmijWV
	    v9LEKCkAIhKIBnlvpks6F21qUZ31u/sbExPa9h0/RzwzMov2nGlG5TmW1YOzzlnSfL
	    mVnyGf19Q7lwZHBp+1fPtflAIgiC7389n9qkihP+lWyeqfUO15ZwQTqlw9H+o2cOvN
	    QJCAHEgEqgYnI0NyALjAJdyWQy7wMa6AEujUdzo3LjcAXwD/XCTKIRjWytAAAAJXRF
	    WHRjcmVhdGUtZGF0ZQAyMDA5LTA0LTA2VDIxOjI1OjQxLTAzOjAw8s+uCAAAACV0RV
	    h0bW9kaWZ5LWRhdGUAMjAwOC0wMS0wM1QxNTowODoyMS0wMjowMJEc/44AAAAZdEVY
	    dFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC
	}]
    }
    if {![info exists ::tk::Priv(folderImage)]} {
	set ::tk::Priv(folderImage) [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiA
	    AAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBl
	    Lm9yZ5vuPBoAAAHCSURBVDiNpZAxa5NRFIafc+9XLCni4BC6FBycMnbrLpkcgtDVX6
	    C70D/g4lZX/4coxLlgxFkpiiSSUGm/JiXfveee45AmNlhawXc53HvPee55X+l2u/yP
	    qt3d3Tfu/viatwt3fzIYDI5uBJhZr9fr3TMzzAx3B+D09PR+v98/7HQ6z5fNOWdCCG
	    U4HH6s67oAVDlnV1UmkwmllBUkhMD29nYHeLuEAkyn06qU8qqu64MrgIyqYmZrkHa7
	    3drc3KTVahFjJITAaDRiPB4/XFlQVVMtHH5IzJo/P4EA4MyB+erWPQB7++zs7ccYvl
	    U5Z08pMW2cl88eIXLZeDUpXzsBkNQ5eP1+p0opmaoCTgzw6fjs6gLLsp58FB60t0Dc
	    K1Ul54yIEIMQ43Uj68pquDmCeJVztpwzuBNE2LgBoMVpslHMCUEAFgDVxQbzVAiA+a
	    K5uGPmmDtZF3VpoUm2ArhqQaRiUjcMf81p1G60UEVhcjZfAFTVUkrgkS+jc06mDX9n
	    vq4YhJ9nlxZExMwMEaHJRutOdWuIIsJFUoBSuTvHJ4YIfP46unV4qdlsjsBRZRtb/X
	    fHd5+C8+P7+J8BIoxFwovfRxYhnhxjpzEAAAAASUVORK5CYII=
	}]
    }
    if {![info exists ::tk::Priv(fileImage)]} {
	set ::tk::Priv(fileImage)   [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gva
	    eTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1QQWFA84umAmQgAAANpJREFU
	    OMutkj1uhDAQhb8HSLtbISGfgZ+zbJkix0HmFhwhUdocBnMBGvqtTIqIFSReWKK8ai
	    x73nwzHrVt+zEMwwvH9FrX9TsA1trpqKy10+yUzME4jnjvAZB0LzXHkojjmDRNVyh3
	    A+89zrlVwlKSqKrqVy/J8lAUxSZBSMny4ZLgp54iyPM8UPHGNJ2IomibAKDv+9VlWZ
	    bABbgB5/0WQgSSkC4PF2JF4JzbHN430c4vhAm0TyCJruuClefph4yCBCGT3T3Isoy/
	    KDHGfDZNcz2SZIx547/0BVRRX7n8uT/sAAAAAElFTkSuQmCC
	}]
    }
}

# ::tk::dialog::file:: --
#
#	Implements the TK file selection dialog.  This dialog is used when the
#	tk_strictMotif flag is set to false.  This procedure shouldn't be
#	called directly.  Call tk_getOpenFile or tk_getSaveFile instead.
#
# Arguments:
#	type		"open" or "save"
#	args		Options parsed by the procedure.
#

proc ::tk::dialog::file:: {type args} {
    variable ::tk::Priv
    variable showHiddenBtn
    set dataName __tk_filedialog
    upvar ::tk::dialog::file::$dataName data

    Config $dataName $type $args

    if {$data(-parent) eq "."} {
	set w .$dataName


|
|
|

|
|
|
|
>
|

|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|








<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801































802





























803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
# tkfbox.tcl --
#
#	Implements the "TK" standard file selection dialog box. This
#	dialog box is used on the Unix platforms whenever the tk_strictMotif
#	flag is not set.
#
#	The "TK" standard file selection dialog box is similar to the
#	file selection dialog box on Win95(TM). The user can navigate
#	the directories by clicking on the folder icons or by
#	selecting the "Directory" option menu. The user can select
#	files by clicking on the file icons or by entering a filename
#	in the "Filename:" entry.
#
# 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.
#

package require Ttk

#----------------------------------------------------------------------
#
#		      I C O N   L I S T
#
# This is a pseudo-widget that implements the icon list inside the
# ::tk::dialog::file:: dialog box.
#
#----------------------------------------------------------------------

# ::tk::IconList --
#
#	Creates an IconList widget.
#
proc ::tk::IconList {w args} {
    IconList_Config $w $args
    IconList_Create $w
}

proc ::tk::IconList_Index {w i} {
    upvar #0 ::tk::$w data ::tk::$w:itemList itemList
    if {![info exists data(list)]} {
	set data(list) {}
    }
    switch -regexp -- $i {
	"^-?[0-9]+$" {
	    if {$i < 0} {
		set i 0
	    }
	    if {$i >= [llength $data(list)]} {
		set i [expr {[llength $data(list)] - 1}]
	    }
	    return $i
	}
	"^active$" {
	    return $data(index,active)
	}
	"^anchor$" {
	    return $data(index,anchor)
	}
	"^end$" {
	    return [llength $data(list)]
	}
	"@-?[0-9]+,-?[0-9]+" {
	    foreach {x y} [scan $i "@%d,%d"] {
		break
	    }
	    set item [$data(canvas) find closest \
		    [$data(canvas) canvasx $x] [$data(canvas) canvasy $y]]
	    return [lindex [$data(canvas) itemcget $item -tags] 1]
	}
    }
}

proc ::tk::IconList_Selection {w op args} {
    upvar ::tk::$w data
    switch -exact -- $op {
	"anchor" {
	    if {[llength $args] == 1} {
		set data(index,anchor) [tk::IconList_Index $w [lindex $args 0]]
	    } else {
		return $data(index,anchor)
	    }
	}
	"clear" {
	    if {[llength $args] == 2} {
		foreach {first last} $args {
		    break
		}
	    } elseif {[llength $args] == 1} {
		set first [set last [lindex $args 0]]
	    } else {
		error "wrong # args: should be [lindex [info level 0] 0] path\
			clear first ?last?"
	    }
	    set first [IconList_Index $w $first]
	    set last [IconList_Index $w $last]
	    if {$first > $last} {
		set tmp $first
		set first $last
		set last $tmp
	    }
	    set ind 0
	    foreach item $data(selection) {
		if { $item >= $first } {
		    set first $ind
		    break
		}
		incr ind
	    }
	    set ind [expr {[llength $data(selection)] - 1}]
	    for {} {$ind >= 0} {incr ind -1} {
		set item [lindex $data(selection) $ind]
		if { $item <= $last } {
		    set last $ind
		    break
		}
	    }

	    if { $first > $last } {
		return
	    }
	    set data(selection) [lreplace $data(selection) $first $last]
	    event generate $w <<ListboxSelect>>
	    IconList_DrawSelection $w
	}
	"includes" {
	    set index [lsearch -exact $data(selection) [lindex $args 0]]
	    return [expr {$index != -1}]
	}
	"set" {
	    if { [llength $args] == 2 } {
		foreach {first last} $args {
		    break
		}
	    } elseif { [llength $args] == 1 } {
		set last [set first [lindex $args 0]]
	    } else {
		error "wrong # args: should be [lindex [info level 0] 0] path\
			set first ?last?"
	    }

	    set first [IconList_Index $w $first]
	    set last [IconList_Index $w $last]
	    if { $first > $last } {
		set tmp $first
		set first $last
		set last $tmp
	    }
	    for {set i $first} {$i <= $last} {incr i} {
		lappend data(selection) $i
	    }
	    set data(selection) [lsort -integer -unique $data(selection)]
	    event generate $w <<ListboxSelect>>
	    IconList_DrawSelection $w
	}
    }
}

proc ::tk::IconList_CurSelection {w} {
    upvar ::tk::$w data
    return $data(selection)
}

proc ::tk::IconList_DrawSelection {w} {
    upvar ::tk::$w data
    upvar ::tk::$w:itemList itemList

    $data(canvas) delete selection
    $data(canvas) itemconfigure selectionText -fill black
    $data(canvas) dtag selectionText
    set cbg [ttk::style lookup TEntry -selectbackground focus]
    set cfg [ttk::style lookup TEntry -selectforeground focus]
    foreach item $data(selection) {
	set rTag [lindex [lindex $data(list) $item] 2]
	foreach {iTag tTag text serial} $itemList($rTag) {
	    break
	}

	set bbox [$data(canvas) bbox $tTag]
	$data(canvas) create rect $bbox -fill $cbg -outline $cbg \
		-tags selection
	$data(canvas) itemconfigure $tTag -fill $cfg -tags selectionText
    }
    $data(canvas) lower selection
    return
}

proc ::tk::IconList_Get {w item} {
    upvar ::tk::$w data
    upvar ::tk::$w:itemList itemList
    set rTag [lindex [lindex $data(list) $item] 2]
    foreach {iTag tTag text serial} $itemList($rTag) {
	break
    }
    return $text
}

# ::tk::IconList_Config --
#
#	Configure the widget variables of IconList, according to the command
#	line arguments.
#
proc ::tk::IconList_Config {w argList} {

    # 1: the configuration specs
    #
    set specs {
	{-command "" "" ""}
	{-multiple "" "" "0"}
    }

    # 2: parse the arguments
    #
    tclParseConfigSpec ::tk::$w $specs "" $argList
}

# ::tk::IconList_Create --
#
#	Creates an IconList widget by assembling a canvas widget and a
#	scrollbar widget. Sets all the bindings necessary for the IconList's
#	operations.
#
proc ::tk::IconList_Create {w} {
    upvar ::tk::$w data

    ttk::frame $w
    ttk::entry $w.cHull -takefocus 0 -cursor {}
    set data(sbar)   [ttk::scrollbar $w.cHull.sbar -orient horizontal -takefocus 0]
    catch {$data(sbar) configure -highlightthickness 0}
    set data(canvas) [canvas $w.cHull.canvas -highlightthick 0 \
	    -width 400 -height 120 -takefocus 1 -background white]
    pack $data(sbar) -side bottom -fill x -padx 2 -in $w.cHull -pady {0 2}
    pack $data(canvas) -expand yes -fill both -padx 2 -pady {2 0}
    pack $w.cHull -expand yes -fill both -ipadx 2 -ipady 2

    $data(sbar) configure -command [list $data(canvas) xview]
    $data(canvas) configure -xscrollcommand [list $data(sbar) set]

    # Initializes the max icon/text width and height and other variables
    #
    set data(maxIW) 1
    set data(maxIH) 1
    set data(maxTW) 1
    set data(maxTH) 1
    set data(numItems) 0
    set data(noScroll) 1
    set data(selection) {}
    set data(index,anchor) ""
    set fg [option get $data(canvas) foreground Foreground]
    if {$fg eq ""} {
	set data(fill) black
    } else {
	set data(fill) $fg
    }

    # Creates the event bindings.
    #
    bind $data(canvas) <Configure>	[list tk::IconList_Arrange $w]

    bind $data(canvas) <1>		[list tk::IconList_Btn1 $w %x %y]
    bind $data(canvas) <B1-Motion>	[list tk::IconList_Motion1 $w %x %y]
    bind $data(canvas) <B1-Leave>	[list tk::IconList_Leave1 $w %x %y]
    bind $data(canvas) <Control-1>	[list tk::IconList_CtrlBtn1 $w %x %y]
    bind $data(canvas) <Shift-1>	[list tk::IconList_ShiftBtn1 $w %x %y]
    bind $data(canvas) <B1-Enter>	[list tk::CancelRepeat]
    bind $data(canvas) <ButtonRelease-1> [list tk::CancelRepeat]
    bind $data(canvas) <Double-ButtonRelease-1> \
	    [list tk::IconList_Double1 $w %x %y]

    bind $data(canvas) <Control-B1-Motion> {;}
    bind $data(canvas) <Shift-B1-Motion> \
	    [list tk::IconList_ShiftMotion1 $w %x %y]

    bind $data(canvas) <Up>		[list tk::IconList_UpDown $w -1]
    bind $data(canvas) <Down>		[list tk::IconList_UpDown $w  1]
    bind $data(canvas) <Left>		[list tk::IconList_LeftRight $w -1]
    bind $data(canvas) <Right>		[list tk::IconList_LeftRight $w  1]
    bind $data(canvas) <Return>		[list tk::IconList_ReturnKey $w]
    bind $data(canvas) <KeyPress>	[list tk::IconList_KeyPress $w %A]
    bind $data(canvas) <Control-KeyPress> ";"
    bind $data(canvas) <Alt-KeyPress>	";"

    bind $data(canvas) <FocusIn>	[list tk::IconList_FocusIn $w]
    bind $data(canvas) <FocusOut>	[list tk::IconList_FocusOut $w]

    return $w
}

# ::tk::IconList_AutoScan --
#
# This procedure is invoked when the mouse leaves an entry window
# with button 1 down.  It scrolls the window up, down, left, or
# right, depending on where the mouse left the window, and reschedules
# itself as an "after" command so that the window continues to scroll until
# the mouse moves back into the window or the mouse button is released.
#
# Arguments:
# w -		The IconList window.
#
proc ::tk::IconList_AutoScan {w} {
    upvar ::tk::$w data
    variable ::tk::Priv

    if {![winfo exists $w]} return
    set x $Priv(x)
    set y $Priv(y)

    if {$data(noScroll)} {
	return
    }
    if {$x >= [winfo width $data(canvas)]} {
	$data(canvas) xview scroll 1 units
    } elseif {$x < 0} {
	$data(canvas) xview scroll -1 units
    } elseif {$y >= [winfo height $data(canvas)]} {
	# do nothing
    } elseif {$y < 0} {
	# do nothing
    } else {
	return
    }

    IconList_Motion1 $w $x $y
    set Priv(afterId) [after 50 [list tk::IconList_AutoScan $w]]
}

# Deletes all the items inside the canvas subwidget and reset the IconList's
# state.
#
proc ::tk::IconList_DeleteAll {w} {
    upvar ::tk::$w data
    upvar ::tk::$w:itemList itemList

    $data(canvas) delete all
    unset -nocomplain data(selected) data(rect) data(list) itemList
    set data(maxIW) 1
    set data(maxIH) 1
    set data(maxTW) 1
    set data(maxTH) 1
    set data(numItems) 0
    set data(noScroll) 1
    set data(selection) {}
    set data(index,anchor) ""
    $data(sbar) set 0.0 1.0
    $data(canvas) xview moveto 0
}

# Adds an icon into the IconList with the designated image and text
#
proc ::tk::IconList_Add {w image items} {
    upvar ::tk::$w data
    upvar ::tk::$w:itemList itemList
    upvar ::tk::$w:textList textList

    foreach text $items {
	set iTag [$data(canvas) create image 0 0 -image $image -anchor nw \
		-tags [list icon $data(numItems) item$data(numItems)]]
	set tTag [$data(canvas) create text  0 0 -text  $text  -anchor nw \
		-font $data(font) -fill $data(fill) \
		-tags [list text $data(numItems) item$data(numItems)]]
	set rTag [$data(canvas) create rect  0 0 0 0 -fill "" -outline "" \
		-tags [list rect $data(numItems) item$data(numItems)]]

	foreach {x1 y1 x2 y2} [$data(canvas) bbox $iTag] {
	    break
	}
	set iW [expr {$x2 - $x1}]
	set iH [expr {$y2 - $y1}]
	if {$data(maxIW) < $iW} {
	    set data(maxIW) $iW
	}
	if {$data(maxIH) < $iH} {
	    set data(maxIH) $iH
	}

	foreach {x1 y1 x2 y2} [$data(canvas) bbox $tTag] {
	    break
	}
	set tW [expr {$x2 - $x1}]
	set tH [expr {$y2 - $y1}]
	if {$data(maxTW) < $tW} {
	    set data(maxTW) $tW
	}
	if {$data(maxTH) < $tH} {
	    set data(maxTH) $tH
	}

	lappend data(list) [list $iTag $tTag $rTag $iW $iH $tW \
		$tH $data(numItems)]
	set itemList($rTag) [list $iTag $tTag $text $data(numItems)]
	set textList($data(numItems)) [string tolower $text]
	incr data(numItems)
    }
}

# Places the icons in a column-major arrangement.
#
proc ::tk::IconList_Arrange {w} {
    upvar ::tk::$w data

    if {![info exists data(list)]} {
	if {[info exists data(canvas)] && [winfo exists $data(canvas)]} {
	    set data(noScroll) 1
	    $data(sbar) configure -command ""
	}
	return
    }

    set W [winfo width  $data(canvas)]
    set H [winfo height $data(canvas)]
    set pad [expr {[$data(canvas) cget -highlightthickness] + \
	    [$data(canvas) cget -bd]}]
    if {$pad < 2} {
	set pad 2
    }

    incr W -[expr {$pad*2}]
    incr H -[expr {$pad*2}]

    set dx [expr {$data(maxIW) + $data(maxTW) + 8}]
    if {$data(maxTH) > $data(maxIH)} {
	set dy $data(maxTH)
    } else {
	set dy $data(maxIH)
    }
    incr dy 2
    set shift [expr {$data(maxIW) + 4}]

    set x [expr {$pad * 2}]
    set y [expr {$pad * 1}] ; # Why * 1 ?
    set usedColumn 0
    foreach sublist $data(list) {
	set usedColumn 1
	foreach {iTag tTag rTag iW iH tW tH} $sublist {
	    break
	}

	set i_dy [expr {($dy - $iH)/2}]
	set t_dy [expr {($dy - $tH)/2}]

	$data(canvas) coords $iTag $x                    [expr {$y + $i_dy}]
	$data(canvas) coords $tTag [expr {$x + $shift}]  [expr {$y + $t_dy}]
	$data(canvas) coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}]

	incr y $dy
	if {($y + $dy) > $H} {
	    set y [expr {$pad * 1}] ; # *1 ?
	    incr x $dx
	    set usedColumn 0
	}
    }

    if {$usedColumn} {
	set sW [expr {$x + $dx}]
    } else {
	set sW $x
    }

    if {$sW < $W} {
	$data(canvas) configure -scrollregion [list $pad $pad $sW $H]
	$data(sbar) configure -command ""
	$data(canvas) xview moveto 0
	set data(noScroll) 1
    } else {
	$data(canvas) configure -scrollregion [list $pad $pad $sW $H]
	$data(sbar) configure -command [list $data(canvas) xview]
	set data(noScroll) 0
    }

    set data(itemsPerColumn) [expr {($H-$pad)/$dy}]
    if {$data(itemsPerColumn) < 1} {
	set data(itemsPerColumn) 1
    }

    IconList_DrawSelection $w
}

# Gets called when the user invokes the IconList (usually by double-clicking
# or pressing the Return key).
#
proc ::tk::IconList_Invoke {w} {
    upvar ::tk::$w data

    if {$data(-command) ne "" && [llength $data(selection)]} {
	uplevel #0 $data(-command)
    }
}

# ::tk::IconList_See --
#
#	If the item is not (completely) visible, scroll the canvas so that
#	it becomes visible.
proc ::tk::IconList_See {w rTag} {
    upvar ::tk::$w data
    upvar ::tk::$w:itemList itemList

    if {$data(noScroll)} {
	return
    }
    set sRegion [$data(canvas) cget -scrollregion]
    if {$sRegion eq ""} {
	return
    }

    if { $rTag < 0 || $rTag >= [llength $data(list)] } {
	return
    }

    set bbox [$data(canvas) bbox item$rTag]
    set pad [expr {[$data(canvas) cget -highlightthickness] + \
	    [$data(canvas) cget -bd]}]

    set x1 [lindex $bbox 0]
    set x2 [lindex $bbox 2]
    incr x1 -[expr {$pad * 2}]
    incr x2 -[expr {$pad * 1}] ; # *1 ?

    set cW [expr {[winfo width $data(canvas)] - $pad*2}]

    set scrollW [expr {[lindex $sRegion 2]-[lindex $sRegion 0]+1}]
    set dispX [expr {int([lindex [$data(canvas) xview] 0]*$scrollW)}]
    set oldDispX $dispX

    # check if out of the right edge
    #
    if {($x2 - $dispX) >= $cW} {
	set dispX [expr {$x2 - $cW}]
    }
    # check if out of the left edge
    #
    if {($x1 - $dispX) < 0} {
	set dispX $x1
    }

    if {$oldDispX ne $dispX} {
	set fraction [expr {double($dispX)/double($scrollW)}]
	$data(canvas) xview moveto $fraction
    }
}

proc ::tk::IconList_Btn1 {w x y} {
    upvar ::tk::$w data

    focus $data(canvas)
    set i [IconList_Index $w @$x,$y]
    if {$i eq ""} {
	return
    }
    IconList_Selection $w clear 0 end
    IconList_Selection $w set $i
    IconList_Selection $w anchor $i
}

proc ::tk::IconList_CtrlBtn1 {w x y} {
    upvar ::tk::$w data

    if { $data(-multiple) } {
	focus $data(canvas)
	set i [IconList_Index $w @$x,$y]
	if {$i eq ""} {
	    return
	}
	if { [IconList_Selection $w includes $i] } {
	    IconList_Selection $w clear $i
	} else {
	    IconList_Selection $w set $i
	    IconList_Selection $w anchor $i
	}
    }
}

proc ::tk::IconList_ShiftBtn1 {w x y} {
    upvar ::tk::$w data

    if { $data(-multiple) } {
	focus $data(canvas)
	set i [IconList_Index $w @$x,$y]
	if {$i eq ""} {
	    return
	}
	if {[IconList_Index $w anchor] eq ""} {
		IconList_Selection $w anchor $i
	}
	IconList_Selection $w clear 0 end
	IconList_Selection $w set anchor $i
    }
}

# Gets called on button-1 motions
#
proc ::tk::IconList_Motion1 {w x y} {
    variable ::tk::Priv
    set Priv(x) $x
    set Priv(y) $y
    set i [IconList_Index $w @$x,$y]
    if {$i eq ""} {
	return
    }
    IconList_Selection $w clear 0 end
    IconList_Selection $w set $i
}

proc ::tk::IconList_ShiftMotion1 {w x y} {
    upvar ::tk::$w data
    variable ::tk::Priv
    set Priv(x) $x
    set Priv(y) $y
    set i [IconList_Index $w @$x,$y]
    if {$i eq ""} {
	return
    }
    IconList_Selection $w clear 0 end
    IconList_Selection $w set anchor $i
}

proc ::tk::IconList_Double1 {w x y} {
    upvar ::tk::$w data

    if {[llength $data(selection)]} {
	IconList_Invoke $w
    }
}

proc ::tk::IconList_ReturnKey {w} {
    IconList_Invoke $w
}

proc ::tk::IconList_Leave1 {w x y} {
    variable ::tk::Priv

    set Priv(x) $x
    set Priv(y) $y
    IconList_AutoScan $w
}

proc ::tk::IconList_FocusIn {w} {
    upvar ::tk::$w data

    $w.cHull state focus
    if {![info exists data(list)]} {
	return
    }

    if {[llength $data(selection)]} {
	IconList_DrawSelection $w
    }
}

proc ::tk::IconList_FocusOut {w} {
    $w.cHull state !focus
    IconList_Selection $w clear 0 end
}

# ::tk::IconList_UpDown --
#
# Moves the active element up or down by one element
#
# Arguments:
# w -		The IconList widget.
# amount -	+1 to move down one item, -1 to move back one item.
#
proc ::tk::IconList_UpDown {w amount} {
    upvar ::tk::$w data

    if {![info exists data(list)]} {
	return
    }

    set curr [tk::IconList_CurSelection $w]
    if { [llength $curr] == 0 } {
	set i 0
    } else {
	set i [tk::IconList_Index $w anchor]
	if {$i eq ""} {
	    return
	}
	incr i $amount
    }
    IconList_Selection $w clear 0 end
    IconList_Selection $w set $i
    IconList_Selection $w anchor $i
    IconList_See $w $i
}

# ::tk::IconList_LeftRight --
#
# Moves the active element left or right by one column
#
# Arguments:
# w -		The IconList widget.
# amount -	+1 to move right one column, -1 to move left one column.
#
proc ::tk::IconList_LeftRight {w amount} {
    upvar ::tk::$w data

    if {![info exists data(list)]} {
	return
    }

    set curr [IconList_CurSelection $w]
    if { [llength $curr] == 0 } {
	set i 0
    } else {
	set i [IconList_Index $w anchor]
	if {$i eq ""} {
	    return
	}
	incr i [expr {$amount*$data(itemsPerColumn)}]
    }
    IconList_Selection $w clear 0 end
    IconList_Selection $w set $i
    IconList_Selection $w anchor $i
    IconList_See $w $i
}

#----------------------------------------------------------------------
#		Accelerator key bindings
#----------------------------------------------------------------------

# ::tk::IconList_KeyPress --
#
#	Gets called when user enters an arbitrary key in the listbox.
#
proc ::tk::IconList_KeyPress {w key} {
    variable ::tk::Priv

    append Priv(ILAccel,$w) $key
    IconList_Goto $w $Priv(ILAccel,$w)
    catch {
	after cancel $Priv(ILAccel,$w,afterId)
    }
    set Priv(ILAccel,$w,afterId) [after 500 [list tk::IconList_Reset $w]]
}

proc ::tk::IconList_Goto {w text} {
    upvar ::tk::$w data
    upvar ::tk::$w:textList textList

    if {![info exists data(list)]} {
	return
    }

    if {$text eq "" || $data(numItems) == 0} {
	return
    }

    if {[llength [IconList_CurSelection $w]]} {
	set start [IconList_Index $w anchor]
    } else {
	set start 0
    }

    set theIndex -1
    set less 0
    set len [string length $text]
    set len0 [expr {$len-1}]
    set i $start

    # Search forward until we find a filename whose prefix is a
    # case-insensitive match with $text
    while {1} {
	if {[string equal -nocase -length $len0 $textList($i) $text]} {
	    set theIndex $i
	    break
	}
	incr i
	if {$i == $data(numItems)} {
	    set i 0
	}
	if {$i == $start} {
	    break
	}
    }

    if {$theIndex > -1} {
	IconList_Selection $w clear 0 end
	IconList_Selection $w set $theIndex
	IconList_Selection $w anchor $theIndex
	IconList_See $w $theIndex
    }
}

proc ::tk::IconList_Reset {w} {
    variable ::tk::Priv

    unset -nocomplain Priv(ILAccel,$w)
}

#----------------------------------------------------------------------
#
#		      F I L E   D I A L O G
#
#----------------------------------------------------------------------

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {
    namespace import -force ::tk::msgcat::*
    set ::tk::dialog::file::showHiddenBtn 0
    set ::tk::dialog::file::showHiddenVar 1
}





























































# ::tk::dialog::file:: --
#
#	Implements the TK file selection dialog. This dialog is used when
#	the tk_strictMotif flag is set to false. This procedure shouldn't
#	be called directly. Call tk_getOpenFile or tk_getSaveFile instead.
#
# Arguments:
#	type		"open" or "save"
#	args		Options parsed by the procedure.
#

proc ::tk::dialog::file:: {type args} {
    variable ::tk::Priv

    set dataName __tk_filedialog
    upvar ::tk::dialog::file::$dataName data

    Config $dataName $type $args

    if {$data(-parent) eq "."} {
	set w .$dataName
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	set data(typeMenuBtn) $w.contents.f2.menu
	set data(typeMenu) $data(typeMenuBtn).m
	set data(okBtn) $w.contents.f2.ok
	set data(cancelBtn) $w.contents.f2.cancel
	set data(hiddenBtn) $w.contents.f2.hidden
	SetSelectMode $w $data(-multiple)
    }
    if {$showHiddenBtn} {
	$data(hiddenBtn) configure -state normal
	grid $data(hiddenBtn)
    } else {
	$data(hiddenBtn) configure -state disabled
	grid remove $data(hiddenBtn)
    }

    # Make sure subseqent uses of this dialog are independent [Bug 845189]
    unset -nocomplain data(extUsed)

    # Dialog boxes should be transient with respect to their parent, so that
    # they will always stay on top of their parent window.  However, some
    # window managers will create the window as withdrawn if the parent window
    # is withdrawn or iconified.  Combined with the grab we put on the window,
    # this can hang the entire application.  Therefore we only make the dialog
    # transient if the parent is viewable.

    if {[winfo viewable [winfo toplevel $data(-parent)]]} {
	wm transient $w $data(-parent)
    }

    # Add traces on the selectPath variable
    #







|










|
|
|
|
|
|







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
	set data(typeMenuBtn) $w.contents.f2.menu
	set data(typeMenu) $data(typeMenuBtn).m
	set data(okBtn) $w.contents.f2.ok
	set data(cancelBtn) $w.contents.f2.cancel
	set data(hiddenBtn) $w.contents.f2.hidden
	SetSelectMode $w $data(-multiple)
    }
    if {$::tk::dialog::file::showHiddenBtn} {
	$data(hiddenBtn) configure -state normal
	grid $data(hiddenBtn)
    } else {
	$data(hiddenBtn) configure -state disabled
	grid remove $data(hiddenBtn)
    }

    # Make sure subseqent uses of this dialog are independent [Bug 845189]
    unset -nocomplain data(extUsed)

    # Dialog boxes should be transient with respect to their parent,
    # so that they will always stay on top of their parent window.  However,
    # some window managers will create the window as withdrawn if the parent
    # window is withdrawn or iconified.  Combined with the grab we put on the
    # window, this can hang the entire application.  Therefore we only make
    # the dialog transient if the parent is viewable.

    if {[winfo viewable [winfo toplevel $data(-parent)]]} {
	wm transient $w $data(-parent)
    }

    # Add traces on the selectPath variable
    #
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
	    }
	}
	foreach type $data(-filetypes) {
	    set title  [lindex $type 0]
	    set filter [lindex $type 1]
	    $data(typeMenu) add command -label $title \
		-command [list ::tk::dialog::file::SetFilter $w $type]
	    # [string first] avoids glob-pattern char issues
	    if {[string first ${initialTypeName} $title] == 0} {
		set initialtype $type
	    }
	}
	SetFilter $w $initialtype
	$data(typeMenuBtn) configure -state normal
	$data(typeMenuLab) configure -state normal







|







893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
	    }
	}
	foreach type $data(-filetypes) {
	    set title  [lindex $type 0]
	    set filter [lindex $type 1]
	    $data(typeMenu) add command -label $title \
		-command [list ::tk::dialog::file::SetFilter $w $type]
	    # string first avoids glob-pattern char issues
	    if {[string first ${initialTypeName} $title] == 0} {
		set initialtype $type
	    }
	}
	SetFilter $w $initialtype
	$data(typeMenuBtn) configure -state normal
	$data(typeMenuLab) configure -state normal
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

    ::tk::SetFocusGrab $w $data(ent)
    $data(ent) delete 0 end
    $data(ent) insert 0 $data(selectFile)
    $data(ent) selection range 0 end
    $data(ent) icursor end

    # Wait for the user to respond, then restore the focus and return the
    # index of the selected button.  Restore the focus before deleting the
    # window, since otherwise the window manager may take the focus away so we

    # can't redirect it.  Finally, restore any grab that was in effect.

    vwait ::tk::Priv(selectFilePath)

    ::tk::RestoreFocusGrab $w $data(ent) withdraw

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) {*}$trace
    }
    $data(dirMenuBtn) configure -textvariable {}

    return $Priv(selectFilePath)
}

# ::tk::dialog::file::Config --
#
#	Configures the TK filedialog according to the argument list
#
proc ::tk::dialog::file::Config {dataName type argList} {
    upvar ::tk::dialog::file::$dataName data

    set data(type) $type

    # 0: Delete all variable that were set on data(selectPath) the
    # last time the file dialog is used. The traces may cause troubles
    # if the dialog is now used with a different -parent option.

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) {*}$trace
    }

    # 1: the configuration specs
    #
    set specs {
	{-defaultextension "" "" ""}
	{-filetypes "" "" ""}







|
|
|
>
|









|




















|







923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

    ::tk::SetFocusGrab $w $data(ent)
    $data(ent) delete 0 end
    $data(ent) insert 0 $data(selectFile)
    $data(ent) selection range 0 end
    $data(ent) icursor end

    # Wait for the user to respond, then restore the focus and
    # return the index of the selected button.  Restore the focus
    # before deleting the window, since otherwise the window manager
    # may take the focus away so we can't redirect it.  Finally,
    # restore any grab that was in effect.

    vwait ::tk::Priv(selectFilePath)

    ::tk::RestoreFocusGrab $w $data(ent) withdraw

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }
    $data(dirMenuBtn) configure -textvariable {}

    return $Priv(selectFilePath)
}

# ::tk::dialog::file::Config --
#
#	Configures the TK filedialog according to the argument list
#
proc ::tk::dialog::file::Config {dataName type argList} {
    upvar ::tk::dialog::file::$dataName data

    set data(type) $type

    # 0: Delete all variable that were set on data(selectPath) the
    # last time the file dialog is used. The traces may cause troubles
    # if the dialog is now used with a different -parent option.

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }

    # 1: the configuration specs
    #
    set specs {
	{-defaultextension "" "" ""}
	{-filetypes "" "" ""}
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
	    set data(selectPath) [pwd]
	}
    }
    set data(selectFile) $data(-initialfile)

    # 5. Parse the -filetypes option
    #
    set data(origfiletypes) $data(-filetypes)
    set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }

    # Set -multiple to a one or zero value (not other boolean types like
    # "yes") so we can use it in tests more easily.
    if {$type eq "save"} {
	set data(-multiple) 0
    } elseif {$data(-multiple)} {
	set data(-multiple) 1
    } else {
	set data(-multiple) 0
    }







<



<
|


|
|







1023
1024
1025
1026
1027
1028
1029

1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
	    set data(selectPath) [pwd]
	}
    }
    set data(selectFile) $data(-initialfile)

    # 5. Parse the -filetypes option
    #

    set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]

    if {![winfo exists $data(-parent)]} {

	error "bad window path name \"$data(-parent)\""
    }

    # Set -multiple to a one or zero value (not other boolean types
    # like "yes") so we can use it in tests more easily.
    if {$type eq "save"} {
	set data(-multiple) 0
    } elseif {$data(-multiple)} {
	set data(-multiple) 1
    } else {
	set data(-multiple) 0
    }
349
350
351
352
353
354
355
356
357
358
359












360
361
362
363
364
365
366
    set data(dirMenuBtn) $f1.menu
    if {![info exists data(selectPath)]} {
	set data(selectPath) ""
    }
    set data(dirMenu) $f1.menu.menu
    ttk::menubutton $f1.menu -menu $data(dirMenu) -direction flush \
	    -textvariable [format %s(selectPath) ::tk::dialog::file::$dataName]
    menu $data(dirMenu) -tearoff 0
    $data(dirMenu) add radiobutton -label "" -variable \
	    [format %s(selectPath) ::tk::dialog::file::$dataName]
    set data(upBtn) [ttk::button $f1.up]












    $data(upBtn) configure -image $Priv(updirImage)

    $f1.menu configure -takefocus 1;# -highlightthickness 2

    pack $data(upBtn) -side right -padx 4 -fill both
    pack $f1.lab -side left -padx 4 -fill both
    pack $f1.menu -expand yes -fill both -padx 4







|
<


>
>
>
>
>
>
>
>
>
>
>
>







1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
    set data(dirMenuBtn) $f1.menu
    if {![info exists data(selectPath)]} {
	set data(selectPath) ""
    }
    set data(dirMenu) $f1.menu.menu
    ttk::menubutton $f1.menu -menu $data(dirMenu) -direction flush \
	    -textvariable [format %s(selectPath) ::tk::dialog::file::$dataName]
    [menu $data(dirMenu) -tearoff 0] add radiobutton -label "" -variable \

	    [format %s(selectPath) ::tk::dialog::file::$dataName]
    set data(upBtn) [ttk::button $f1.up]
    if {![info exists Priv(updirImage)]} {
	set Priv(updirImage) [image create bitmap -data {
#define updir_width 28
#define updir_height 16
static char updir_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00,
   0x20, 0x40, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x10, 0x00, 0x00, 0x01,
   0x10, 0x02, 0x00, 0x01, 0x10, 0x07, 0x00, 0x01, 0x90, 0x0f, 0x00, 0x01,
   0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01,
   0x10, 0xfe, 0x07, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01,
   0xf0, 0xff, 0xff, 0x01};}]
    }
    $data(upBtn) configure -image $Priv(updirImage)

    $f1.menu configure -takefocus 1;# -highlightthickness 2

    pack $data(upBtn) -side right -padx 4 -fill both
    pack $f1.lab -side left -padx 4 -fill both
    pack $f1.menu -expand yes -fill both -padx 4
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
    #
    set f2 [ttk::frame $w.contents.f2]
    bind [::tk::AmpWidget ttk::label $f2.lab -text $fNameCaption -anchor e]\
	    <<AltUnderlined>> [list focus $f2.ent]
    # -pady 0
    set data(ent) [ttk::entry $f2.ent]

    # The font to use for the icons. The default Canvas font on Unix is just
    # deviant.
    set ::tk::$w.contents.icons(font) [$data(ent) cget -font]

    # Make the file types bits only if this is a File Dialog
    if {$class eq "TkFDialog"} {
	set data(typeMenuLab) [::tk::AmpWidget ttk::label $f2.lab2 \
		-text $fTypeCaption -anchor e]
	# -pady [$f2.lab cget -pady]
	set data(typeMenuBtn) [ttk::menubutton $f2.menu \
		-menu $f2.menu.m]
	# -indicatoron 1
	set data(typeMenu) [menu $data(typeMenuBtn).m -tearoff 0]
	# $data(typeMenuBtn) configure -takefocus 1 -relief raised -anchor w
	bind $data(typeMenuLab) <<AltUnderlined>> [list \
		focus $data(typeMenuBtn)]
    }

    # The hidden button is displayed when ::tk::dialog::file::showHiddenBtn is
    # true.  Create it disabled so the binding doesn't trigger if it isn't
    # shown.
    if {$class eq "TkFDialog"} {
	set text [mc "Show &Hidden Files and Directories"]
    } else {
	set text [mc "Show &Hidden Directories"]
    }
    set data(hiddenBtn) [::tk::AmpWidget ttk::checkbutton $f2.hidden \
	    -text $text -state disabled \







|
|
















|
|
|







1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
    #
    set f2 [ttk::frame $w.contents.f2]
    bind [::tk::AmpWidget ttk::label $f2.lab -text $fNameCaption -anchor e]\
	    <<AltUnderlined>> [list focus $f2.ent]
    # -pady 0
    set data(ent) [ttk::entry $f2.ent]

    # The font to use for the icons. The default Canvas font on Unix
    # is just deviant.
    set ::tk::$w.contents.icons(font) [$data(ent) cget -font]

    # Make the file types bits only if this is a File Dialog
    if {$class eq "TkFDialog"} {
	set data(typeMenuLab) [::tk::AmpWidget ttk::label $f2.lab2 \
		-text $fTypeCaption -anchor e]
	# -pady [$f2.lab cget -pady]
	set data(typeMenuBtn) [ttk::menubutton $f2.menu \
		-menu $f2.menu.m]
	# -indicatoron 1
	set data(typeMenu) [menu $data(typeMenuBtn).m -tearoff 0]
	# $data(typeMenuBtn) configure -takefocus 1 -relief raised -anchor w
	bind $data(typeMenuLab) <<AltUnderlined>> [list \
		focus $data(typeMenuBtn)]
    }

    # The hidden button is displayed when ::tk::dialog::file::showHiddenBtn
    # is true.  Create it disabled so the binding doesn't trigger if it
    # isn't shown.
    if {$class eq "TkFDialog"} {
	set text [mc "Show &Hidden Files and Directories"]
    } else {
	set text [mc "Show &Hidden Directories"]
    }
    set data(hiddenBtn) [::tk::AmpWidget ttk::checkbutton $f2.hidden \
	    -text $text -state disabled \
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

    # Set up the event handlers that are common to Directory and File Dialogs
    #

    wm protocol $w WM_DELETE_WINDOW [list ::tk::dialog::file::CancelCmd $w]
    $data(upBtn)     configure -command [list ::tk::dialog::file::UpDirCmd $w]
    $data(cancelBtn) configure -command [list ::tk::dialog::file::CancelCmd $w]
    bind $w <Escape> [list $data(cancelBtn) invoke]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    # Set up event handlers specific to File or Directory Dialogs
    #
    if {$class eq "TkFDialog"} {
	bind $data(ent) <Return> [list ::tk::dialog::file::ActivateEnt $w]
	$data(okBtn)     configure -command [list ::tk::dialog::file::OkCmd $w]







|







1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

    # Set up the event handlers that are common to Directory and File Dialogs
    #

    wm protocol $w WM_DELETE_WINDOW [list ::tk::dialog::file::CancelCmd $w]
    $data(upBtn)     configure -command [list ::tk::dialog::file::UpDirCmd $w]
    $data(cancelBtn) configure -command [list ::tk::dialog::file::CancelCmd $w]
    bind $w <KeyPress-Escape> [list $data(cancelBtn) invoke]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    # Set up event handlers specific to File or Directory Dialogs
    #
    if {$class eq "TkFDialog"} {
	bind $data(ent) <Return> [list ::tk::dialog::file::ActivateEnt $w]
	$data(okBtn)     configure -command [list ::tk::dialog::file::OkCmd $w]
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538
539
540
541
542

543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561








562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

601
602


603
604
605
606
607
608
609
    if { $multi } {
	set fNameCaption [mc "File &names:"]
    } else {
	set fNameCaption [mc "File &name:"]
    }
    set iconListCommand [list ::tk::dialog::file::OkCmd $w]
    ::tk::SetAmpText $w.contents.f2.lab $fNameCaption

    $data(icons) configure -multiple $multi -command $iconListCommand
    return
}

# ::tk::dialog::file::UpdateWhenIdle --
#
#	Creates an idle event handler which updates the dialog in idle time.
#	This is important because loading the directory may take a long time
#	and we don't want to load the same directory for multiple times due to
#	multiple concurrent events.
#
proc ::tk::dialog::file::UpdateWhenIdle {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[info exists data(updateId)]} {
	return
    }
    set data(updateId) [after idle [list ::tk::dialog::file::Update $w]]

}

# ::tk::dialog::file::Update --
#
#	Loads the files and directories into the IconList widget. Also sets up
#	the directory option menu for quick access to parent directories.

#
proc ::tk::dialog::file::Update {w} {

    # This proc may be called within an idle handler. Make sure that the
    # window has not been destroyed before this proc is called
    if {![winfo exists $w]} {
	return
    }
    set class [winfo class $w]
    if {($class ne "TkFDialog") && ($class ne "TkChooseDir")} {
	return
    }

    set dataName [winfo name $w]
    upvar ::tk::dialog::file::$dataName data
    variable ::tk::Priv
    variable showHiddenVar
    global tk_library
    unset -nocomplain data(updateId)









    set folder $Priv(folderImage)
    set file   $Priv(fileImage)

    set appPWD [pwd]
    if {[catch {
	cd $data(selectPath)
    }]} then {
	# We cannot change directory to $data(selectPath). $data(selectPath)
	# should have been checked before ::tk::dialog::file::Update is
	# called, so we normally won't come to here. Anyways, give an error
	# and abort action.
	tk_messageBox -type ok -parent $w -icon warning -message [mc \
	       "Cannot change to the directory \"%1\$s\".\nPermission denied."\
		$data(selectPath)]
	cd $appPWD
	return
    }

    # Turn on the busy cursor. BUG?? We haven't disabled X events, though,
    # so the user may still click and cause havoc ...
    #
    set entCursor [$data(ent) cget -cursor]
    set dlgCursor [$w         cget -cursor]
    $data(ent) configure -cursor watch
    $w         configure -cursor watch
    update idletasks

    $data(icons) deleteall

    set showHidden $showHiddenVar

    # Make the dir list. Note that using an explicit [pwd] (instead of '.') is
    # better in some VFS cases.
    $data(icons) add $folder [GlobFiltered [pwd] d 1]

    if {$class eq "TkFDialog"} {
	# Make the file list if this is a File Dialog, selecting all but
	# 'd'irectory type files.
	#

	$data(icons) add $file [GlobFiltered [pwd] {f b c l p s}]
    }



    # Update the Directory: option menu
    #
    set list ""
    set dir ""
    foreach subdir [file split $data(selectPath)] {
	set dir [file join $dir $subdir]







>
|





|
|
|
|






|
|
>




|
|
>


>













<



>
>
>
>
>
>
>
>






|

|
|
|
|
|
<













|

|



|





>
|

>
>







1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
    if { $multi } {
	set fNameCaption [mc "File &names:"]
    } else {
	set fNameCaption [mc "File &name:"]
    }
    set iconListCommand [list ::tk::dialog::file::OkCmd $w]
    ::tk::SetAmpText $w.contents.f2.lab $fNameCaption
    ::tk::IconList_Config $data(icons) \
	    [list -multiple $multi -command $iconListCommand]
    return
}

# ::tk::dialog::file::UpdateWhenIdle --
#
#	Creates an idle event handler which updates the dialog in idle
#	time. This is important because loading the directory may take a long
#	time and we don't want to load the same directory for multiple times
#	due to multiple concurrent events.
#
proc ::tk::dialog::file::UpdateWhenIdle {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[info exists data(updateId)]} {
	return
    } else {
	set data(updateId) [after idle [list ::tk::dialog::file::Update $w]]
    }
}

# ::tk::dialog::file::Update --
#
#	Loads the files and directories into the IconList widget. Also
#	sets up the directory option menu for quick access to parent
#	directories.
#
proc ::tk::dialog::file::Update {w} {

    # This proc may be called within an idle handler. Make sure that the
    # window has not been destroyed before this proc is called
    if {![winfo exists $w]} {
	return
    }
    set class [winfo class $w]
    if {($class ne "TkFDialog") && ($class ne "TkChooseDir")} {
	return
    }

    set dataName [winfo name $w]
    upvar ::tk::dialog::file::$dataName data
    variable ::tk::Priv

    global tk_library
    unset -nocomplain data(updateId)

    if {![info exists Priv(folderImage)]} {
	set Priv(folderImage) [image create photo -data {
R0lGODlhEAAMAKEAAAD//wAAAPD/gAAAACH5BAEAAAAALAAAAAAQAAwAAAIghINhyycvVFsB
QtmS3rjaH1Hg141WaT5ouprt2HHcUgAAOw==}]
	set Priv(fileImage)   [image create photo -data {
R0lGODlhDAAMAKEAALLA3AAAAP//8wAAACH5BAEAAAAALAAAAAAMAAwAAAIgRI4Ha+IfWHsO
rSASvJTGhnhcV3EJlo3kh53ltF5nAhQAOw==}]
    }
    set folder $Priv(folderImage)
    set file   $Priv(fileImage)

    set appPWD [pwd]
    if {[catch {
	cd $data(selectPath)
    }]} {
	# We cannot change directory to $data(selectPath). $data(selectPath)
	# should have been checked before ::tk::dialog::file::Update is called, so
	# we normally won't come to here. Anyways, give an error and abort
	# action.
	tk_messageBox -type ok -parent $w -icon warning -message \
		[mc "Cannot change to the directory \"%1\$s\".\nPermission denied." $data(selectPath)]

	cd $appPWD
	return
    }

    # Turn on the busy cursor. BUG?? We haven't disabled X events, though,
    # so the user may still click and cause havoc ...
    #
    set entCursor [$data(ent) cget -cursor]
    set dlgCursor [$w         cget -cursor]
    $data(ent) configure -cursor watch
    $w         configure -cursor watch
    update idletasks

    ::tk::IconList_DeleteAll $data(icons)

    set showHidden $::tk::dialog::file::showHiddenVar

    # Make the dir list. Note that using an explicit [pwd] (instead of '.') is
    # better in some VFS cases.
    ::tk::IconList_Add $data(icons) $folder [GlobFiltered [pwd] d 1]

    if {$class eq "TkFDialog"} {
	# Make the file list if this is a File Dialog, selecting all but
	# 'd'irectory type files.
	#
	::tk::IconList_Add $data(icons) $file \
	    [GlobFiltered [pwd] {f b c l p s}]
    }

    ::tk::IconList_Arrange $data(icons)

    # Update the Directory: option menu
    #
    set list ""
    set dir ""
    foreach subdir [file split $data(selectPath)] {
	set dir [file join $dir $subdir]
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
# ::tk::dialog::file::SetPathSilently --
#
# 	Sets data(selectPath) without invoking the trace procedure
#
proc ::tk::dialog::file::SetPathSilently {w path} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set cb [list ::tk::dialog::file::SetPath $w]
    trace remove variable data(selectPath) write $cb
    set data(selectPath) $path
    trace add variable data(selectPath) write $cb
}


# This proc gets called whenever data(selectPath) is set
#
proc ::tk::dialog::file::SetPath {w name1 name2 op} {
    if {[winfo exists $w]} {







<
|

|







1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
# ::tk::dialog::file::SetPathSilently --
#
# 	Sets data(selectPath) without invoking the trace procedure
#
proc ::tk::dialog::file::SetPathSilently {w path} {
    upvar ::tk::dialog::file::[winfo name $w] data


    trace remove variable data(selectPath) write [list ::tk::dialog::file::SetPath $w]
    set data(selectPath) $path
    trace add variable data(selectPath) write [list ::tk::dialog::file::SetPath $w]
}


# This proc gets called whenever data(selectPath) is set
#
proc ::tk::dialog::file::SetPath {w name1 name2 op} {
    if {[winfo exists $w]} {
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
    }
}

# This proc gets called whenever data(filter) is set
#
proc ::tk::dialog::file::SetFilter {w type} {
    upvar ::tk::dialog::file::[winfo name $w] data


    set data(filterType) $type
    set data(filter) [lindex $type 1]
    $data(typeMenuBtn) configure -text [lindex $type 0] ;#-indicatoron 1

    # If we aren't using a default extension, use the one suppled by the
    # filter.
    if {![info exists data(extUsed)]} {
	if {[string length $data(-defaultextension)]} {
	    set data(extUsed) 1
	} else {
	    set data(extUsed) 0
	}
    }

    if {!$data(extUsed)} {
	# Get the first extension in the list that matches {^\*\.\w+$} and
	# remove all * from the filter.
	set index [lsearch -regexp $data(filter) {^\*\.\w+$}]
	if {$index >= 0} {
	    set data(-defaultextension) \
		    [string trimleft [lindex $data(filter) $index] "*"]
	} else {
	    # Couldn't find anything!  Reset to a safe default...
	    set data(-defaultextension) ""
	}
    }

    $data(icons) see 0

    UpdateWhenIdle $w
}

# tk::dialog::file::ResolveFile --
#
#	Interpret the user's text input in a file selection dialog.  Performs:

#
#	(1) ~ substitution
#	(2) resolve all instances of . and ..
#	(3) check for non-existent files/directories
#	(4) check for chdir permissions
#	(5) conversion of environment variable references to their
#	    contents (once only)
#
# Arguments:
#	context:  the current directory you are in
#	text:	  the text entered by the user
#	defaultext: the default extension to add to files with no extension
#	expandEnv: whether to expand environment variables (yes by default)
#
# Return vaue:
#	[list $flag $directory $file]
#
#	 flag = OK	: valid input
#	      = PATTERN	: valid directory/pattern
#	      = PATH	: the directory does not exist
#	      = FILE	: the directory exists by the file doesn't exist

#	      = CHDIR	: Cannot change to the directory
#	      = ERROR	: Invalid entry
#
#	 directory      : valid only if flag = OK or PATTERN or FILE
#	 file           : valid only if flag = OK or PATTERN
#
#	directory may not be the same as context, because text may contain a
#	subdirectory name
#
proc ::tk::dialog::file::ResolveFile {context text defaultext {expandEnv 1}} {
    set appPWD [pwd]

    set path [JoinFile $context $text]

    # If the file has no extension, append the default.  Be careful not to do
    # this for directories, otherwise typing a dirname in the box will give
    # back "dirname.extension" instead of trying to change dir.
    if {
	![file isdirectory $path] && ([file ext $path] eq "") &&
	![string match {$*} [file tail $path]]
    } then {
	set path "$path$defaultext"
    }

    if {[catch {file exists $path}]} {
	# This "if" block can be safely removed if the following code stop
	# generating errors.
	#
	#	file exists ~nonsuchuser
	#
	return [list ERROR $path ""]
    }

    if {[file exists $path]} {







>





|
|









|
|










|






|
>




















|
>






|
|






|
|
|








|
|







1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
    }
}

# This proc gets called whenever data(filter) is set
#
proc ::tk::dialog::file::SetFilter {w type} {
    upvar ::tk::dialog::file::[winfo name $w] data
    upvar ::tk::$data(icons) icons

    set data(filterType) $type
    set data(filter) [lindex $type 1]
    $data(typeMenuBtn) configure -text [lindex $type 0] ;#-indicatoron 1

    # If we aren't using a default extension, use the one suppled
    # by the filter.
    if {![info exists data(extUsed)]} {
	if {[string length $data(-defaultextension)]} {
	    set data(extUsed) 1
	} else {
	    set data(extUsed) 0
	}
    }

    if {!$data(extUsed)} {
	# Get the first extension in the list that matches {^\*\.\w+$}
	# and remove all * from the filter.
	set index [lsearch -regexp $data(filter) {^\*\.\w+$}]
	if {$index >= 0} {
	    set data(-defaultextension) \
		    [string trimleft [lindex $data(filter) $index] "*"]
	} else {
	    # Couldn't find anything!  Reset to a safe default...
	    set data(-defaultextension) ""
	}
    }

    $icons(sbar) set 0.0 0.0

    UpdateWhenIdle $w
}

# tk::dialog::file::ResolveFile --
#
#	Interpret the user's text input in a file selection dialog.
#	Performs:
#
#	(1) ~ substitution
#	(2) resolve all instances of . and ..
#	(3) check for non-existent files/directories
#	(4) check for chdir permissions
#	(5) conversion of environment variable references to their
#	    contents (once only)
#
# Arguments:
#	context:  the current directory you are in
#	text:	  the text entered by the user
#	defaultext: the default extension to add to files with no extension
#	expandEnv: whether to expand environment variables (yes by default)
#
# Return vaue:
#	[list $flag $directory $file]
#
#	 flag = OK	: valid input
#	      = PATTERN	: valid directory/pattern
#	      = PATH	: the directory does not exist
#	      = FILE	: the directory exists by the file doesn't
#			  exist
#	      = CHDIR	: Cannot change to the directory
#	      = ERROR	: Invalid entry
#
#	 directory      : valid only if flag = OK or PATTERN or FILE
#	 file           : valid only if flag = OK or PATTERN
#
#	directory may not be the same as context, because text may contain
#	a subdirectory name
#
proc ::tk::dialog::file::ResolveFile {context text defaultext {expandEnv 1}} {
    set appPWD [pwd]

    set path [JoinFile $context $text]

    # If the file has no extension, append the default.  Be careful not
    # to do this for directories, otherwise typing a dirname in the box
    # will give back "dirname.extension" instead of trying to change dir.
    if {
	![file isdirectory $path] && ([file ext $path] eq "") &&
	![string match {$*} [file tail $path]]
    } then {
	set path "$path$defaultext"
    }

    if {[catch {file exists $path}]} {
	# This "if" block can be safely removed if the following code
	# stop generating errors.
	#
	#	file exists ~nonsuchuser
	#
	return [list ERROR $path ""]
    }

    if {[file exists $path]} {
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
    upvar ::tk::dialog::file::[winfo name $w] data

    if {$data(selectPath) ne "/"} {
	set data(selectPath) [file dirname $data(selectPath)]
    }
}

# Join a file name to a path name. The "file join" command will break if the
# filename begins with ~
#
proc ::tk::dialog::file::JoinFile {path file} {
    if {[string match {~*} $file] && [file exists $path/$file]} {
	return [file join $path ./$file]
    } else {
	return [file join $path $file]
    }
}

# Gets called when user presses the "OK" button
#
proc ::tk::dialog::file::OkCmd {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set filenames {}
    foreach item [$data(icons) selection get] {
	lappend filenames [$data(icons) get $item]
    }

    if {
	([llength $filenames] && !$data(-multiple)) ||
	($data(-multiple) && ([llength $filenames] == 1))
    } then {
	set filename [lindex $filenames 0]
	set file [JoinFile $data(selectPath) $filename]
	if {[file isdirectory $file]} {
	    ListInvoke $w [list $filename]
	    return
	}
    }







|
|















|
|


<
|
|
<







1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714

1715
1716

1717
1718
1719
1720
1721
1722
1723
    upvar ::tk::dialog::file::[winfo name $w] data

    if {$data(selectPath) ne "/"} {
	set data(selectPath) [file dirname $data(selectPath)]
    }
}

# Join a file name to a path name. The "file join" command will break
# if the filename begins with ~
#
proc ::tk::dialog::file::JoinFile {path file} {
    if {[string match {~*} $file] && [file exists $path/$file]} {
	return [file join $path ./$file]
    } else {
	return [file join $path $file]
    }
}

# Gets called when user presses the "OK" button
#
proc ::tk::dialog::file::OkCmd {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set filenames {}
    foreach item [::tk::IconList_CurSelection $data(icons)] {
	lappend filenames [::tk::IconList_Get $data(icons) $item]
    }


    if {([llength $filenames] && !$data(-multiple)) || \
	    ($data(-multiple) && ([llength $filenames] == 1))} {

	set filename [lindex $filenames 0]
	set file [JoinFile $data(selectPath) $filename]
	if {[file isdirectory $file]} {
	    ListInvoke $w [list $filename]
	    return
	}
    }
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
# Gets called when user browses the IconList widget (dragging mouse, arrow
# keys, etc)
#
proc ::tk::dialog::file::ListBrowse {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set text {}
    foreach item [$data(icons) selection get] {
	lappend text [$data(icons) get $item]
    }
    if {[llength $text] == 0} {
	return
    }
    if {$data(-multiple)} {
	set newtext {}
	foreach file $text {







|
|







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
# Gets called when user browses the IconList widget (dragging mouse, arrow
# keys, etc)
#
proc ::tk::dialog::file::ListBrowse {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set text {}
    foreach item [::tk::IconList_CurSelection $data(icons)] {
	lappend text [::tk::IconList_Get $data(icons) $item]
    }
    if {[llength $text] == 0} {
	return
    }
    if {$data(-multiple)} {
	set newtext {}
	foreach file $text {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
	    }
	}
    } elseif {[winfo class $w] eq "TkFDialog"} {
	::tk::SetAmpText $data(okBtn) [mc "&Open"]
    }
}

# Gets called when user invokes the IconList widget (double-click, Return key,
# etc)
#
proc ::tk::dialog::file::ListInvoke {w filenames} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[llength $filenames] == 0} {
	return
    }







|
|







1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
	    }
	}
    } elseif {[winfo class $w] eq "TkFDialog"} {
	::tk::SetAmpText $data(okBtn) [mc "&Open"]
    }
}

# Gets called when user invokes the IconList widget (double-click,
# Return key, etc)
#
proc ::tk::dialog::file::ListInvoke {w filenames} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[llength $filenames] == 0} {
	return
    }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
	}
	Done $w
    }
}

# ::tk::dialog::file::Done --
#
#	Gets called when user has input a valid filename.  Pops up a dialog
#	box to confirm selection when necessary.  Sets the
#	tk::Priv(selectFilePath) variable, which will break the "vwait" loop
#	in ::tk::dialog::file:: and return the selected filename to the script
#	that calls tk_getOpenFile or tk_getSaveFile
#
proc ::tk::dialog::file::Done {w {selectFilePath ""}} {
    upvar ::tk::dialog::file::[winfo name $w] data
    variable ::tk::Priv

    if {$selectFilePath eq ""} {
	if {$data(-multiple)} {







|
|
|
|
|







1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
	}
	Done $w
    }
}

# ::tk::dialog::file::Done --
#
#	Gets called when user has input a valid filename.  Pops up a
#	dialog box to confirm selection when necessary. Sets the
#	tk::Priv(selectFilePath) variable, which will break the "vwait"
#	loop in ::tk::dialog::file:: and return the selected filename to the
#	script that calls tk_getOpenFile or tk_getSaveFile
#
proc ::tk::dialog::file::Done {w {selectFilePath ""}} {
    upvar ::tk::dialog::file::[winfo name $w] data
    variable ::tk::Priv

    if {$selectFilePath eq ""} {
	if {$data(-multiple)} {
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
	    set reply [tk_messageBox -icon warning -type yesno -parent $w \
		    -message [mc "File \"%1\$s\" already exists.\nDo you want\
		    to overwrite it?" $selectFilePath]]
	    if {$reply eq "no"} {
		return
	    }
	}
	if {
	    [info exists data(-typevariable)] && $data(-typevariable) ne ""
	    && [info exists data(-filetypes)] && [llength $data(-filetypes)]
	    && [info exists data(filterType)] && $data(filterType) ne ""
	} then {
	    upvar #0 $data(-typevariable) typeVariable
	    set typeVariable [lindex $data(origfiletypes) \
	            [lsearch -exact $data(-filetypes) $data(filterType)] 0]

	}
    }
    bind $data(okBtn) <Destroy> {}
    set Priv(selectFilePath) $selectFilePath
}

# ::tk::dialog::file::GlobFiltered --
#
#	Gets called to do globbing, returning the results and filtering them
#	according to the current filter (and removing the entries for '.' and
#	'..' which are never shown). Deals with evil cases such as where the
#	user is supplying a filter which is an invalid list or where it has an
#	unbalanced brace. The resulting list will be dictionary sorted.
#
#	Arguments:
#	  dir		 Which directory to search
#	  type		 List of filetypes to look for ('d' or 'f b c l p s')
#	  overrideFilter Whether to ignore the filter for this search.
#
#	NB: Assumes that the caller has mapped the state variable to 'data'.
#
proc ::tk::dialog::file::GlobFiltered {dir type {overrideFilter 0}} {
    variable showHiddenVar
    upvar 1 data(filter) filter

    if {$filter eq "*" || $overrideFilter} {
	set patterns [list *]
	if {$showHiddenVar} {
	    lappend patterns .*







<
|
|
|
<

|
<
<






|
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<







1849
1850
1851
1852
1853
1854
1855

1856
1857
1858

1859
1860


1861
1862
1863
1864
1865
1866
1867








1868
1869
1870
1871



1872
1873
1874
1875
1876
1877
1878
	    set reply [tk_messageBox -icon warning -type yesno -parent $w \
		    -message [mc "File \"%1\$s\" already exists.\nDo you want\
		    to overwrite it?" $selectFilePath]]
	    if {$reply eq "no"} {
		return
	    }
	}

	if {[info exists data(-typevariable)] && $data(-typevariable) ne ""
		&& [info exists data(-filetypes)] && [llength $data(-filetypes)]
		&& [info exists data(filterType)] && $data(filterType) ne ""} {

	    upvar #0 $data(-typevariable) typeVariable
	    set typeVariable [lindex $data(filterType) 0]


	}
    }
    bind $data(okBtn) <Destroy> {}
    set Priv(selectFilePath) $selectFilePath
}

proc ::tk::dialog::file::GlobFiltered {dir type {overrideFilter 0}} {








    # $dir == where to search
    # $type == what to look for ('d' or 'f b c l p s')
    # $overrideFilter == whether to ignore the filter




    variable showHiddenVar
    upvar 1 data(filter) filter

    if {$filter eq "*" || $overrideFilter} {
	set patterns [list *]
	if {$showHiddenVar} {
	    lappend patterns .*

Changes to library/ttk/altTheme.tcl.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	-window		"#ffffff"
	-darker 	"#c3c3c3"
	-border		"#414141"
	-activebg 	"#ececec"
	-disabledfg	"#a3a3a3"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"
	-altindicator	"#aaaaaa"
    }

    ttk::style theme settings alt {

	ttk::style configure "." \
	    -background 	$colors(-frame) \
	    -foreground 	black \







<







10
11
12
13
14
15
16

17
18
19
20
21
22
23
	-window		"#ffffff"
	-darker 	"#c3c3c3"
	-border		"#414141"
	-activebg 	"#ececec"
	-disabledfg	"#a3a3a3"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"

    }

    ttk::style theme settings alt {

	ttk::style configure "." \
	    -background 	$colors(-frame) \
	    -foreground 	black \
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
	    {pressed !disabled} 	sunken
	    {active !disabled} 	raised
	} -highlightcolor {alternate black}

	ttk::style configure TCheckbutton -indicatorcolor "#ffffff" -padding 2
	ttk::style configure TRadiobutton -indicatorcolor "#ffffff" -padding 2
	ttk::style map TCheckbutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding "3 3" -relief raised

	ttk::style configure TEntry -padding 1
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
	ttk::style configure TCombobox -padding 1
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)] \
		-arrowcolor [list disabled $colors(-disabledfg)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]







<
<
|

<
<
|









|
<







42
43
44
45
46
47
48


49
50


51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
	    {pressed !disabled} 	sunken
	    {active !disabled} 	raised
	} -highlightcolor {alternate black}

	ttk::style configure TCheckbutton -indicatorcolor "#ffffff" -padding 2
	ttk::style configure TRadiobutton -indicatorcolor "#ffffff" -padding 2
	ttk::style map TCheckbutton -indicatorcolor \


	    [list  disabled $colors(-frame)  pressed $colors(-frame)]
	ttk::style map TRadiobutton -indicatorcolor \


	    [list  disabled $colors(-frame)  pressed $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding "3 3" -relief raised

	ttk::style configure TEntry -padding 1
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
	ttk::style configure TCombobox -padding 1
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	    -expand [list selected {2 2 1 0}] \
	    ;

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	ttk::style configure TScale \
	    -groovewidth 4 -troughrelief sunken \
	    -sliderwidth raised -borderwidth 2
	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) -borderwidth 0
    }
}







<
|
<
|








85
86
87
88
89
90
91

92

93
94
95
96
97
98
99
100
101
	    -expand [list selected {2 2 1 0}] \
	    ;

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \

	    -background [list selected $colors(-selectbg)] \

	    -foreground [list selected $colors(-selectfg)] ;

	ttk::style configure TScale \
	    -groovewidth 4 -troughrelief sunken \
	    -sliderwidth raised -borderwidth 2
	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) -borderwidth 0
    }
}

Changes to library/ttk/aquaTheme.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#
# Aqua theme (OSX native look and feel)
#

namespace eval ttk::theme::aqua {
    ttk::style theme settings aqua {

	ttk::style configure . \
	    -font TkDefaultFont \
	    -background systemWindowBackgroundColor \
	    -foreground systemLabelColor \
	    -selectbackground systemSelectedTextBackgroundColor \
	    -selectforeground systemSelectedTextColor \
	    -selectborderwidth 0 \
	    -insertwidth 1

	ttk::style map . \
	    -foreground {
		disabled systemDisabledControlTextColor
		background systemLabelColor} \
	    -selectbackground {
		background systemSelectedTextBackgroundColor
		!focus systemSelectedTextBackgroundColor} \
	    -selectforeground {
		background systemSelectedTextColor
		!focus systemSelectedTextColor}

	# Button
	ttk::style configure TButton -anchor center -width -6 \
	    -foreground systemControlTextColor
	ttk::style map TButton \
	    -foreground {
		pressed white
	        {alternate !pressed !background} white}
	ttk::style configure TMenubutton -anchor center -padding {2 0 0 2}
	ttk::style configure Toolbutton -anchor center

	# Entry
	ttk::style configure TEntry \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor
	ttk::style map TEntry \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectforeground {
		background systemTextColor
	    } \
	    -selectbackground {
		background systemTextBackgroundColor
	    }


	# Workaround for #1100117:
	# Actually, on Aqua we probably shouldn't stipple images in
	# disabled buttons even if it did work...
	ttk::style configure . -stipple {}



	# Notebook
	ttk::style configure TNotebook -tabmargins {10 0} -tabposition n
	ttk::style configure TNotebook -padding {18 8 18 17}
	ttk::style configure TNotebook.Tab -padding {12 3 12 2}
	ttk::style configure TNotebook.Tab -foreground systemControlTextColor
	ttk::style map TNotebook.Tab \
	    -foreground {
		background systemControlTextColor
		disabled systemDisabledControlTextColor
		selected systemSelectedTabTextColor}

	# Combobox:
	ttk::style configure TCombobox \
	    -foreground systemTextColor \
	    -background systemTransparent
	ttk::style map TCombobox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectforeground {
		background systemTextColor
	    } \
	    -selectbackground {
		background systemTransparent
	    }

	# Spinbox
	ttk::style configure TSpinbox \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor \
	    -selectforeground systemSelectedTextColor \
	    -selectbackground systemSelectedTextBackgroundColor
	ttk::style map TSpinbox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectforeground {
		!active systemTextColor
	    } \
	    -selectbackground {
		!active systemTextBackgroundColor
		!focus systemTextBackgroundColor
		focus systemSelectedTextBackgroundColor
	    }

	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont \
	    -foreground systemTextColor \
	    -background systemWindowBackgroundColor
	ttk::style configure Treeview -rowheight 18 \
	    -background systemTextBackgroundColor \
	    -foreground systemTextColor \
	    -fieldbackground systemTextBackgroundColor
	ttk::style map Treeview \
	    -background {
		selected systemSelectedTextBackgroundColor
	    }

	# Enable animation for ttk::progressbar widget:
	ttk::style configure TProgressbar -period 100 -maxphase 255

	# For Aqua, labelframe labels should appear outside the border,
	# with a 14 pixel inset and 4 pixels spacing between border and label
	# (ref: Apple Human Interface Guidelines / Controls / Grouping Controls)









|
|
|
|




|
<
|
|
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






>
>
|



<
<
<
<
<
<


|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
|
<
<
<

|
|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20

21
22

23


























24
25
26
27
28
29
30
31
32
33
34
35






36
37
38











39




















40
41



42



43
44
45

46
47
48
49
50
51
52
#
# Aqua theme (OSX native look and feel)
#

namespace eval ttk::theme::aqua {
    ttk::style theme settings aqua {

	ttk::style configure . \
	    -font TkDefaultFont \
	    -background systemWindowBody \
	    -foreground systemModelessDialogActiveText \
	    -selectbackground systemHighlight \
	    -selectforeground systemModelessDialogActiveText \
	    -selectborderwidth 0 \
	    -insertwidth 1

	ttk::style map . \
	    -foreground {disabled systemModelessDialogInactiveText

		    background systemModelessDialogInactiveText} \
	    -selectbackground {background systemHighlightSecondary

		    !focus systemHighlightSecondary} \
	    -selectforeground {background systemModelessDialogInactiveText

		    !focus systemDialogActiveText}



























	# Workaround for #1100117:
	# Actually, on Aqua we probably shouldn't stipple images in
	# disabled buttons even if it did work...
	ttk::style configure . -stipple {}

	ttk::style configure TButton -anchor center -width -6
	ttk::style configure Toolbutton -padding 4

	ttk::style configure TNotebook -tabmargins {10 0} -tabposition n
	ttk::style configure TNotebook -padding {18 8 18 17}
	ttk::style configure TNotebook.Tab -padding {12 3 12 2}







	# Combobox:
	ttk::style configure TCombobox -postoffset {5 -2 -10 0}
































	# Treeview:
	ttk::style configure Heading -font TkHeadingFont



	ttk::style configure Treeview -rowheight 18 -background White



	ttk::style map Treeview \
	    -background {{selected background} systemHighlightSecondary
		    selected systemHighlight}


	# Enable animation for ttk::progressbar widget:
	ttk::style configure TProgressbar -period 100 -maxphase 255

	# For Aqua, labelframe labels should appear outside the border,
	# with a 14 pixel inset and 4 pixels spacing between border and label
	# (ref: Apple Human Interface Guidelines / Controls / Grouping Controls)

Changes to library/ttk/button.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#
# Bindings for Buttons, Checkbuttons, and Radiobuttons.
#
# Notes: <Button1-Leave>, <Button1-Enter> only control the "pressed"
# state; widgets remain "active" if the pointer is dragged out.
# This doesn't seem to be conventional, but it's a nice way
# to provide extra feedback while the grab is active.
# (If the button is released off the widget, the grab deactivates and
# we get a <Leave> event then, which turns off the "active" state)
#
# Normally, <ButtonRelease> and <ButtonN-Enter/Leave> events are
# delivered to the widget which received the initial <Button>
# event.  However, Tk [grab]s (#1223103) and menu interactions
# (#1222605) can interfere with this.  To guard against spurious
# <Button1-Enter> events, the <Button1-Enter> binding only sets
# the pressed state if the button is currently active.
#

namespace eval ttk::button {}

bind TButton <Enter> 		{ %W instate !disabled {%W state active} }
bind TButton <Leave>		{ %W state !active }
bind TButton <space>		{ ttk::button::activate %W }
bind TButton <<Invoke>> 	{ ttk::button::activate %W }

bind TButton <Button-1> \
    { %W instate !disabled { ttk::clickToFocus %W; %W state pressed } }
bind TButton <ButtonRelease-1> \
    { %W instate pressed { %W state !pressed; %W instate !disabled { %W invoke } } }
bind TButton <Button1-Leave> \
    { %W state !pressed }
bind TButton <Button1-Enter> \
    { %W instate {active !disabled} { %W state pressed } }

# Checkbuttons and Radiobuttons have the same bindings as Buttons:
#
ttk::copyBindings TButton TCheckbutton
ttk::copyBindings TButton TRadiobutton

# ...plus a few more:

bind TRadiobutton <Up>  		{ ttk::button::RadioTraverse %W -1 }
bind TRadiobutton <Down> 		{ ttk::button::RadioTraverse %W +1 }

# bind TCheckbutton <plus> { %W select }
# bind TCheckbutton <minus> { %W deselect }

# activate --
#	Simulate a button press: temporarily set the state to 'pressed',
#	then invoke the button.
#
proc ttk::button::activate {w} {
    $w instate disabled { return }










|
|










|


|















|
|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#
# Bindings for Buttons, Checkbuttons, and Radiobuttons.
#
# Notes: <Button1-Leave>, <Button1-Enter> only control the "pressed"
# state; widgets remain "active" if the pointer is dragged out.
# This doesn't seem to be conventional, but it's a nice way
# to provide extra feedback while the grab is active.
# (If the button is released off the widget, the grab deactivates and
# we get a <Leave> event then, which turns off the "active" state)
#
# Normally, <ButtonRelease> and <ButtonN-Enter/Leave> events are 
# delivered to the widget which received the initial <ButtonPress>
# event.  However, Tk [grab]s (#1223103) and menu interactions
# (#1222605) can interfere with this.  To guard against spurious
# <Button1-Enter> events, the <Button1-Enter> binding only sets
# the pressed state if the button is currently active.
#

namespace eval ttk::button {}

bind TButton <Enter> 		{ %W instate !disabled {%W state active} }
bind TButton <Leave>		{ %W state !active }
bind TButton <Key-space>	{ ttk::button::activate %W }
bind TButton <<Invoke>> 	{ ttk::button::activate %W }

bind TButton <ButtonPress-1> \
    { %W instate !disabled { ttk::clickToFocus %W; %W state pressed } }
bind TButton <ButtonRelease-1> \
    { %W instate pressed { %W state !pressed; %W instate !disabled { %W invoke } } }
bind TButton <Button1-Leave> \
    { %W state !pressed }
bind TButton <Button1-Enter> \
    { %W instate {active !disabled} { %W state pressed } }

# Checkbuttons and Radiobuttons have the same bindings as Buttons:
#
ttk::copyBindings TButton TCheckbutton
ttk::copyBindings TButton TRadiobutton

# ...plus a few more:

bind TRadiobutton <KeyPress-Up> 	{ ttk::button::RadioTraverse %W -1 }
bind TRadiobutton <KeyPress-Down> 	{ ttk::button::RadioTraverse %W +1 }

# bind TCheckbutton <KeyPress-plus> { %W select }
# bind TCheckbutton <KeyPress-minus> { %W deselect }

# activate --
#	Simulate a button press: temporarily set the state to 'pressed',
#	then invoke the button.
#
proc ttk::button::activate {w} {
    $w instate disabled { return }

Changes to library/ttk/clamTheme.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#
# "Clam" theme.
#
# Inspired by the XFCE family of Gnome themes.
#

namespace eval ttk::theme::clam {
    variable colors
    array set colors {
	-disabledfg		"#999999"
	-frame  		"#dcdad5"
	-window  		"#ffffff"
	-dark			"#cfcdc8"
	-darker 		"#bab5ab"
	-darkest		"#9e9a91"
	-lighter		"#eeebe7"
	-lightest 		"#ffffff"
	-selectbg		"#4a6984"
	-selectfg		"#ffffff"
	-altindicator		"#5895bc"
	-disabledaltindicator	"#a0a0a0"
    }

    ttk::style theme settings clam {

	ttk::style configure "." \
	    -background $colors(-frame) \
	    -foreground black \







|

|
|
|
|
|
|
|
|
|
|
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
#
# "Clam" theme.
#
# Inspired by the XFCE family of Gnome themes.
#

namespace eval ttk::theme::clam {
    variable colors 
    array set colors {
	-disabledfg	"#999999"
	-frame  	"#dcdad5"
	-window  	"#ffffff"
	-dark		"#cfcdc8"
	-darker 	"#bab5ab"
	-darkest	"#9e9a91"
	-lighter	"#eeebe7"
	-lightest 	"#ffffff"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"


    }

    ttk::style theme settings clam {

	ttk::style configure "." \
	    -background $colors(-frame) \
	    -foreground black \
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style configure TRadiobutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style map TCheckbutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding 5 -relief raised

	ttk::style configure TEntry -padding 1 -insertwidth 1
	ttk::style map TEntry \
	    -background [list  readonly $colors(-frame)] \
	    -bordercolor [list  focus $colors(-selectbg)] \
	    -lightcolor [list  focus "#6f9dc6"] \
	    -darkcolor [list  focus "#6f9dc6"] \
	    ;

	ttk::style configure TCombobox -padding 1 -insertwidth 1
	ttk::style map TCombobox \
	    -background [list active $colors(-lighter) \
			     pressed $colors(-lighter)] \
	    -fieldbackground [list {readonly focus} $colors(-selectbg) \
				  readonly $colors(-frame)] \
	    -foreground [list {readonly focus} $colors(-selectfg)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox \
	    -background [list  readonly $colors(-frame)] \
            -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TNotebook.Tab -padding {6 2 6 2}
	ttk::style map TNotebook.Tab \
	    -padding [list selected {6 4 6 2}] \
	    -background [list selected $colors(-frame) {} $colors(-darker)] \
	    -lightcolor [list selected $colors(-lighter) {} $colors(-dark)] \
	    ;

	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont -relief raised -padding {3}
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

    	ttk::style configure TLabelframe \
	    -labeloutside true -labelmargins {0 0 0 4} \
	    -borderwidth 2 -relief raised

	ttk::style configure TProgressbar -background $colors(-frame)

	ttk::style configure Sash -sashthickness 6 -gripcount 10
    }
}







<
<
<
|

<
<
<
|



















<
>




















<
|
<
|










76
77
78
79
80
81
82



83
84



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126

127
128
129
130
131
132
133
134
135
136
137
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style configure TRadiobutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style map TCheckbutton -indicatorbackground \



	    [list  disabled $colors(-frame)  pressed $colors(-frame)]
	ttk::style map TRadiobutton -indicatorbackground \



	    [list  disabled $colors(-frame)  pressed $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding 5 -relief raised

	ttk::style configure TEntry -padding 1 -insertwidth 1
	ttk::style map TEntry \
	    -background [list  readonly $colors(-frame)] \
	    -bordercolor [list  focus $colors(-selectbg)] \
	    -lightcolor [list  focus "#6f9dc6"] \
	    -darkcolor [list  focus "#6f9dc6"] \
	    ;

	ttk::style configure TCombobox -padding 1 -insertwidth 1
	ttk::style map TCombobox \
	    -background [list active $colors(-lighter) \
			     pressed $colors(-lighter)] \
	    -fieldbackground [list {readonly focus} $colors(-selectbg) \
				  readonly $colors(-frame)] \
	    -foreground [list {readonly focus} $colors(-selectfg)] \

	    ;
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox \
	    -background [list  readonly $colors(-frame)] \
            -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TNotebook.Tab -padding {6 2 6 2}
	ttk::style map TNotebook.Tab \
	    -padding [list selected {6 4 6 2}] \
	    -background [list selected $colors(-frame) {} $colors(-darker)] \
	    -lightcolor [list selected $colors(-lighter) {} $colors(-dark)] \
	    ;

	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont -relief raised -padding {3}
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \

	    -background [list selected $colors(-selectbg)] \

	    -foreground [list selected $colors(-selectfg)] ;

    	ttk::style configure TLabelframe \
	    -labeloutside true -labelmargins {0 0 0 4} \
	    -borderwidth 2 -relief raised

	ttk::style configure TProgressbar -background $colors(-frame)

	ttk::style configure Sash -sashthickness 6 -gripcount 10
    }
}

Changes to library/ttk/classicTheme.tcl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	-window		"#ffffff"
	-activebg	"#ececec"
	-troughbg	"#c3c3c3"
	-selectbg	"#c3c3c3"
	-selectfg	"#000000"
	-disabledfg	"#a3a3a3"
	-indicator	"#b03060"
	-altindicator	"#b05e5e"
    }

    ttk::style theme settings classic {
	ttk::style configure "." \
	    -font		TkDefaultFont \
	    -background		$colors(-frame) \
	    -foreground		black \







<







11
12
13
14
15
16
17

18
19
20
21
22
23
24
	-window		"#ffffff"
	-activebg	"#ececec"
	-troughbg	"#c3c3c3"
	-selectbg	"#c3c3c3"
	-selectfg	"#000000"
	-disabledfg	"#a3a3a3"
	-indicator	"#b03060"

    }

    ttk::style theme settings classic {
	ttk::style configure "." \
	    -font		TkDefaultFont \
	    -background		$colors(-frame) \
	    -foreground		black \
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
	ttk::style configure TButton \
	    -anchor center -padding "3m 1m" -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]

	ttk::style configure TCheckbutton -indicatorrelief raised
	ttk::style map TCheckbutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken} \
	    ;

	ttk::style configure TRadiobutton -indicatorrelief raised
	ttk::style map TRadiobutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken} \
	    ;

	ttk::style configure TMenubutton -relief raised -padding "3m 1m"

	ttk::style configure TEntry -relief sunken -padding 1 -font TkTextFont
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]







|
<
<
|





|
<
<
|







45
46
47
48
49
50
51
52


53
54
55
56
57
58
59


60
61
62
63
64
65
66
67
	ttk::style configure TButton \
	    -anchor center -padding "3m 1m" -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]

	ttk::style configure TCheckbutton -indicatorrelief raised
	ttk::style map TCheckbutton \
	    -indicatorcolor [list \
		pressed $colors(-frame)  selected $colors(-indicator)] \


	    -indicatorrelief {selected sunken  pressed sunken} \
	    ;

	ttk::style configure TRadiobutton -indicatorrelief raised
	ttk::style map TRadiobutton \
	    -indicatorcolor [list \
		pressed $colors(-frame)  selected $colors(-indicator)] \


	    -indicatorrelief {selected sunken  pressed sunken} \
	    ;

	ttk::style configure TMenubutton -relief raised -padding "3m 1m"

	ttk::style configure TEntry -relief sunken -padding 1 -font TkTextFont
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	    -background $colors(-troughbg)
	ttk::style map TNotebook.Tab -background [list selected $colors(-frame)]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	#
	# Toolbar buttons:
	#
	ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-troughbg)  active $colors(-activebg)]
    }
}







<
|
<
|











89
90
91
92
93
94
95

96

97
98
99
100
101
102
103
104
105
106
107
108
	    -background $colors(-troughbg)
	ttk::style map TNotebook.Tab -background [list selected $colors(-frame)]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background $colors(-window)
	ttk::style map Treeview \

	    -background [list selected $colors(-selectbg)] \

	    -foreground [list selected $colors(-selectfg)] ;

	#
	# Toolbar buttons:
	#
	ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-troughbg)  active $colors(-activebg)]
    }
}

Changes to library/ttk/combobox.tcl.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
### Combobox bindings.
#
# Duplicate the Entry bindings, override if needed:
#

ttk::copyBindings TEntry TCombobox

bind TCombobox <Down> 			{ ttk::combobox::Post %W }
bind TCombobox <Escape> 		{ ttk::combobox::Unpost %W }

bind TCombobox <Button-1> 		{ ttk::combobox::Press "" %W %x %y }
bind TCombobox <Shift-Button-1>		{ ttk::combobox::Press "s" %W %x %y }
bind TCombobox <Double-Button-1> 	{ ttk::combobox::Press "2" %W %x %y }
bind TCombobox <Triple-Button-1> 	{ ttk::combobox::Press "3" %W %x %y }
bind TCombobox <B1-Motion>		{ ttk::combobox::Drag %W %x }
bind TCombobox <Motion>			{ ttk::combobox::Motion %W %x %y }

ttk::bindMouseWheel TCombobox [list ttk::combobox::Scroll %W]

bind TCombobox <<TraverseIn>> 		{ ttk::combobox::TraverseIn %W }

### Combobox listbox bindings.
#
bind ComboboxListbox <ButtonRelease-1>	{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Return>		{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Escape>		{ ttk::combobox::LBCancel %W }
bind ComboboxListbox <Tab>		{ ttk::combobox::LBTab %W next }
bind ComboboxListbox <<PrevWindow>>	{ ttk::combobox::LBTab %W prev }
bind ComboboxListbox <Destroy>		{ ttk::combobox::LBCleanup %W }
bind ComboboxListbox <Motion>		{ ttk::combobox::LBHover %W %x %y }
bind ComboboxListbox <Map>		{ focus -force %W }

switch -- [tk windowingsystem] {
    win32 {
	# Dismiss listbox when user switches to a different application.
	# NB: *only* do this on Windows (see #1814778)
	bind ComboboxListbox <FocusOut>		{ ttk::combobox::LBCancel %W }
    }
}

### Combobox popdown window bindings.
#
bind ComboboxPopdown	<Map>		{ ttk::combobox::MapPopdown %W }
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<Button> \
			{ ttk::combobox::Unpost [winfo parent %W] }

### Option database settings.
#

option add *TCombobox*Listbox.font TkTextFont widgetDefault
option add *TCombobox*Listbox.relief flat widgetDefault
option add *TCombobox*Listbox.highlightThickness 0 widgetDefault

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white widgetDefault
    }
    aqua {
	option add *TCombobox*Listbox.borderWidth 0 widgetDefault
    }
}

### Binding procedures.
#

## Press $mode $x $y -- Button binding for comboboxes.
#	Either post/unpost the listbox, or perform Entry widget binding,
#	depending on widget state and location of button press.
#
proc ttk::combobox::Press {mode w x y} {
    variable State

    $w instate disabled { return }







|
|

|
|
|
|










|
|
|

















|





|
|
|





|


|






|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
### Combobox bindings.
#
# Duplicate the Entry bindings, override if needed:
#

ttk::copyBindings TEntry TCombobox

bind TCombobox <KeyPress-Down> 		{ ttk::combobox::Post %W }
bind TCombobox <KeyPress-Escape> 	{ ttk::combobox::Unpost %W }

bind TCombobox <ButtonPress-1> 		{ ttk::combobox::Press "" %W %x %y }
bind TCombobox <Shift-ButtonPress-1>	{ ttk::combobox::Press "s" %W %x %y }
bind TCombobox <Double-ButtonPress-1> 	{ ttk::combobox::Press "2" %W %x %y }
bind TCombobox <Triple-ButtonPress-1> 	{ ttk::combobox::Press "3" %W %x %y }
bind TCombobox <B1-Motion>		{ ttk::combobox::Drag %W %x }
bind TCombobox <Motion>			{ ttk::combobox::Motion %W %x %y }

ttk::bindMouseWheel TCombobox [list ttk::combobox::Scroll %W]

bind TCombobox <<TraverseIn>> 		{ ttk::combobox::TraverseIn %W }

### Combobox listbox bindings.
#
bind ComboboxListbox <ButtonRelease-1>	{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <KeyPress-Return>	{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <KeyPress-Escape>  { ttk::combobox::LBCancel %W }
bind ComboboxListbox <KeyPress-Tab>	{ ttk::combobox::LBTab %W next }
bind ComboboxListbox <<PrevWindow>>	{ ttk::combobox::LBTab %W prev }
bind ComboboxListbox <Destroy>		{ ttk::combobox::LBCleanup %W }
bind ComboboxListbox <Motion>		{ ttk::combobox::LBHover %W %x %y }
bind ComboboxListbox <Map>		{ focus -force %W }

switch -- [tk windowingsystem] {
    win32 {
	# Dismiss listbox when user switches to a different application.
	# NB: *only* do this on Windows (see #1814778)
	bind ComboboxListbox <FocusOut>		{ ttk::combobox::LBCancel %W }
    }
}

### Combobox popdown window bindings.
#
bind ComboboxPopdown	<Map>		{ ttk::combobox::MapPopdown %W }
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<ButtonPress> \
			{ ttk::combobox::Unpost [winfo parent %W] }

### Option database settings.
#

option add *TCombobox*Listbox.font TkTextFont
option add *TCombobox*Listbox.relief flat
option add *TCombobox*Listbox.highlightThickness 0

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white
    }
    aqua {
	option add *TCombobox*Listbox.borderWidth 0
    }
}

### Binding procedures.
#

## Press $mode $x $y -- ButtonPress binding for comboboxes.
#	Either post/unpost the listbox, or perform Entry widget binding,
#	depending on widget state and location of button press.
#
proc ttk::combobox::Press {mode w x y} {
    variable State

    $w instate disabled { return }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	}
    } else {
	Post $w
    }
}

## Drag -- B1-Motion binding for comboboxes.
#	If the initial Button event was handled by Entry binding,
#	perform Entry widget drag binding; otherwise nothing.
#
proc ttk::combobox::Drag {w x}  {
    variable State
    if {$State(entryPress)} {
	ttk::entry::Drag $w $x
    }
}

## Motion --
#	Set cursor.
#
proc ttk::combobox::Motion {w x y} {
    variable State
    ttk::saveCursor $w State(userConfCursor) [ttk::cursor text]
    if {   [$w identify $x $y] eq "textarea"
        && [$w instate {!readonly !disabled}]
    } {
	ttk::setCursor $w text
    } else {
	ttk::setCursor $w $State(userConfCursor)
    }
}

## TraverseIn -- receive focus due to keyboard navigation
#	For editable comboboxes, set the selection and insert cursor.
#
proc ttk::combobox::TraverseIn {w} {







|













<
<





|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162
163
164
	}
    } else {
	Post $w
    }
}

## Drag -- B1-Motion binding for comboboxes.
#	If the initial ButtonPress event was handled by Entry binding,
#	perform Entry widget drag binding; otherwise nothing.
#
proc ttk::combobox::Drag {w x}  {
    variable State
    if {$State(entryPress)} {
	ttk::entry::Drag $w $x
    }
}

## Motion --
#	Set cursor.
#
proc ttk::combobox::Motion {w x y} {


    if {   [$w identify $x $y] eq "textarea"
        && [$w instate {!readonly !disabled}]
    } {
	ttk::setCursor $w text
    } else {
	ttk::setCursor $w ""
    }
}

## TraverseIn -- receive focus due to keyboard navigation
#	For editable comboboxes, set the selection and insert cursor.
#
proc ttk::combobox::TraverseIn {w} {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    $cb selection range 0 end
    $cb icursor end
    event generate $cb <<ComboboxSelected>> -when mark
}

## Scroll -- Mousewheel binding
#
proc ttk::combobox::Scroll {cb dir {factor 1.0}} {
    $cb instate disabled { return }
    set max [llength [$cb cget -values]]
    set current [$cb current]
    set d [expr {round($dir/factor)}]
    if {$d == 0 && $dir != 0} {
	if {$dir > 0} {set d 1} else {set d -1}
    }
    incr current $d
    if {$max != 0 && $current == $current % $max} {
	SelectEntry $cb $current
    }
}

## LBSelected $lb -- Activation binding for listbox
#	Set the combobox value to the currently-selected listbox value
#	and unpost the listbox.
#
proc ttk::combobox::LBSelected {lb} {
    set cb [LBMain $lb]
    LBSelect $lb
    Unpost $cb
    focus $cb
}

## LBCancel --
#	Unpost the listbox.
#
proc ttk::combobox::LBCancel {lb} {
    Unpost [LBMain $lb]
}

## LBTab -- Tab key binding for combobox listbox.
#	Set the selection, and navigate to next/prev widget.
#
proc ttk::combobox::LBTab {lb dir} {
    set cb [LBMain $lb]
    switch -- $dir {
	next	{ set newFocus [tk_focusNext $cb] }
	prev	{ set newFocus [tk_focusPrev $cb] }
    }

    if {$newFocus ne ""} {
	LBSelect $lb







|



<
<
<
<
|










|









|






|







176
177
178
179
180
181
182
183
184
185
186




187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    $cb selection range 0 end
    $cb icursor end
    event generate $cb <<ComboboxSelected>> -when mark
}

## Scroll -- Mousewheel binding
#
proc ttk::combobox::Scroll {cb dir} {
    $cb instate disabled { return }
    set max [llength [$cb cget -values]]
    set current [$cb current]




    incr current $dir
    if {$max != 0 && $current == $current % $max} {
	SelectEntry $cb $current
    }
}

## LBSelected $lb -- Activation binding for listbox
#	Set the combobox value to the currently-selected listbox value
#	and unpost the listbox.
#
proc ttk::combobox::LBSelected {lb} {
    set cb [LBMaster $lb]
    LBSelect $lb
    Unpost $cb
    focus $cb
}

## LBCancel --
#	Unpost the listbox.
#
proc ttk::combobox::LBCancel {lb} {
    Unpost [LBMaster $lb]
}

## LBTab -- Tab key binding for combobox listbox.
#	Set the selection, and navigate to next/prev widget.
#
proc ttk::combobox::LBTab {lb dir} {
    set cb [LBMaster $lb]
    switch -- $dir {
	next	{ set newFocus [tk_focusNext $cb] }
	prev	{ set newFocus [tk_focusPrev $cb] }
    }

    if {$newFocus ne ""} {
	LBSelect $lb
252
253
254
255
256
257
258












259
260
261
262
263
264


265
266
267
268
269
270
271
272
273
274
275
276

## UnmapPopdown -- <Unmap> binding for ComboboxPopdown
#
proc ttk::combobox::UnmapPopdown {w} {
    [winfo parent $w] state !pressed
    ttk::releaseGrab $w
}













## PopdownWindow --
#	Returns the popdown widget associated with a combobox,
#	creating it if necessary.
#
proc ttk::combobox::PopdownWindow {cb} {


    if {![winfo exists $cb.popdown]} {
	set poplevel [PopdownToplevel $cb.popdown]
	set popdown [ttk::frame $poplevel.f -style ComboboxPopdownFrame]

	ttk::scrollbar $popdown.sb \
	    -orient vertical -command [list $popdown.l yview]
	listbox $popdown.l \
	    -listvariable ttk::combobox::Values($cb) \
	    -yscrollcommand [list $popdown.sb set] \
	    -exportselection false \
	    -selectmode browse \
	    -activestyle none \







>
>
>
>
>
>
>
>
>
>
>
>






>
>




|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

## UnmapPopdown -- <Unmap> binding for ComboboxPopdown
#
proc ttk::combobox::UnmapPopdown {w} {
    [winfo parent $w] state !pressed
    ttk::releaseGrab $w
}

###
#

namespace eval ::ttk::combobox {
    # @@@ Until we have a proper native scrollbar on Aqua, use
    # @@@ the regular Tk one.  Use ttk::scrollbar on other platforms.
    variable scrollbar ttk::scrollbar
    if {[tk windowingsystem] eq "aqua"} {
	set scrollbar ::scrollbar
    }
}

## PopdownWindow --
#	Returns the popdown widget associated with a combobox,
#	creating it if necessary.
#
proc ttk::combobox::PopdownWindow {cb} {
    variable scrollbar

    if {![winfo exists $cb.popdown]} {
	set poplevel [PopdownToplevel $cb.popdown]
	set popdown [ttk::frame $poplevel.f -style ComboboxPopdownFrame]

	$scrollbar $popdown.sb \
	    -orient vertical -command [list $popdown.l yview]
	listbox $popdown.l \
	    -listvariable ttk::combobox::Values($cb) \
	    -yscrollcommand [list $popdown.sb set] \
	    -exportselection false \
	    -selectmode browse \
	    -activestyle none \
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# @@@TODO: factor with menubutton::PostPosition
#
proc ttk::combobox::PlacePopdown {cb popdown} {
    set x [winfo rootx $cb]
    set y [winfo rooty $cb]
    set w [winfo width $cb]
    set h [winfo height $cb]
    set style [$cb cget -style]
    if { $style eq {} } {
      set style TCombobox
    }
    set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
    	incr $var $delta
    }

    set H [winfo reqheight $popdown]
    if {$y + $h + $H > [winfo screenheight $popdown]} {
	set Y [expr {$y - $H}]







<
<
<
<
|







364
365
366
367
368
369
370




371
372
373
374
375
376
377
378
# @@@TODO: factor with menubutton::PostPosition
#
proc ttk::combobox::PlacePopdown {cb popdown} {
    set x [winfo rootx $cb]
    set y [winfo rooty $cb]
    set w [winfo width $cb]
    set h [winfo height $cb]




    set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
    	incr $var $delta
    }

    set H [winfo reqheight $popdown]
    if {$y + $h + $H > [winfo screenheight $popdown]} {
	set Y [expr {$y - $H}]
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
proc ttk::combobox::Unpost {cb} {
    if {[winfo exists $cb.popdown]} {
	wm withdraw $cb.popdown
    }
    grab release $cb.popdown ;# in case of stuck or unexpected grab [#1239190]
}

## LBMain $lb --
#	Return the combobox main widget that owns the listbox.
#
proc ttk::combobox::LBMain {lb} {
    winfo parent [winfo parent [winfo parent $lb]]
}

## LBSelect $lb --
#	Transfer listbox selection to combobox value.
#
proc ttk::combobox::LBSelect {lb} {
    set cb [LBMain $lb]
    set selection [$lb curselection]
    if {[llength $selection] == 1} {
	SelectEntry $cb [lindex $selection 0]
    }
}

## LBCleanup $lb --
#	<Destroy> binding for combobox listboxes.
#	Cleans up by unsetting the linked textvariable.
#
#	Note: we can't just use { unset [%W cget -listvariable] }
#	because the widget command is already gone when this binding fires).
#	[winfo parent] still works, fortunately.
#
proc ttk::combobox::LBCleanup {lb} {
    variable Values
    unset Values([LBMain $lb])
}

#*EOF*







|


|







|
















|



418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
proc ttk::combobox::Unpost {cb} {
    if {[winfo exists $cb.popdown]} {
	wm withdraw $cb.popdown
    }
    grab release $cb.popdown ;# in case of stuck or unexpected grab [#1239190]
}

## LBMaster $lb --
#	Return the combobox main widget that owns the listbox.
#
proc ttk::combobox::LBMaster {lb} {
    winfo parent [winfo parent [winfo parent $lb]]
}

## LBSelect $lb --
#	Transfer listbox selection to combobox value.
#
proc ttk::combobox::LBSelect {lb} {
    set cb [LBMaster $lb]
    set selection [$lb curselection]
    if {[llength $selection] == 1} {
	SelectEntry $cb [lindex $selection 0]
    }
}

## LBCleanup $lb --
#	<Destroy> binding for combobox listboxes.
#	Cleans up by unsetting the linked textvariable.
#
#	Note: we can't just use { unset [%W cget -listvariable] }
#	because the widget command is already gone when this binding fires).
#	[winfo parent] still works, fortunately.
#
proc ttk::combobox::LBCleanup {lb} {
    variable Values
    unset Values([LBMaster $lb])
}

#*EOF*

Changes to library/ttk/cursors.tcl.

95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122

		neresize	size_ne_sw
		seresize	size_nw_se
	    }
	}

	"aqua" {


	    array set Cursors {
		standard	arrow
		text 	ibeam
		link	pointinghand
		crosshair	crosshair
		busy	watch
		forbidden	notallowed

		hresize 	resizeleftright
		vresize 	resizeupdown
		nresize	resizeup
		sresize	resizedown
		wresize	resizeleft
		eresize	resizeright

	    }
	}
    }
}

## ttk::cursor $cursor --
#	Return platform-specific cursor for specified symbolic cursor.







>
>
|
|
|
|
|
|
|

|
|
|
|
|
|
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

		neresize	size_ne_sw
		seresize	size_nw_se
	    }
	}

	"aqua" {
	    if {[package vsatisfies [package provide Tk] 8.5]} {
		# appeared 2007-04-23, Tk 8.5a6
		array set Cursors {
		    standard	arrow
		    text 	ibeam
		    link	pointinghand
		    crosshair	crosshair
		    busy	watch
		    forbidden	notallowed

		    hresize 	resizeleftright
		    vresize 	resizeupdown
		    nresize	resizeup
		    sresize	resizedown
		    wresize	resizeleft
		    eresize	resizeright
		}
	    }
	}
    }
}

## ttk::cursor $cursor --
#	Return platform-specific cursor for specified symbolic cursor.
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# instead of directly calling [$w configure -cursor ...],
# as the latter always incurs a server round-trip and
# can lead to high CPU load (see [#1184746])
#

proc ttk::setCursor {w name} {
    variable Cursors
    if {[info exists Cursors($name)]} {
        set cursorname $Cursors($name)
    }  else {
        set cursorname $name
    }
    if {[$w cget -cursor] ne $cursorname} {
        $w configure -cursor $cursorname
    }
}

## ttk::saveCursor $w $saveVar $excludeList --
#       Set variable $saveVar to the -cursor value from widget $w,
#       if either:
#       a. $saveVar does not yet exist
#       b. the currently user-specified cursor for $w is not in
#          $excludeList

proc ttk::saveCursor {w saveVar excludeList} {
    upvar $saveVar sv
    if {![info exists sv]} {
        set sv [$w cget -cursor]
    }
    if {[$w cget -cursor] ni $excludeList} {
        set sv [$w cget -cursor]
    }
}

## Interactive test harness:
#
proc ttk::CursorSampler {f} {
    ttk::frame $f







<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







136
137
138
139
140
141
142





143
144

















145
146
147
148
149
150
151
# instead of directly calling [$w configure -cursor ...],
# as the latter always incurs a server round-trip and
# can lead to high CPU load (see [#1184746])
#

proc ttk::setCursor {w name} {
    variable Cursors





    if {[$w cget -cursor] ne $Cursors($name)} {
	$w configure -cursor $Cursors($name)

















    }
}

## Interactive test harness:
#
proc ttk::CursorSampler {f} {
    ttk::frame $f
194
195
196
197
198
199
200
201
202
203
204
205

    return $f
}

if {[info exists argv0] && $argv0 eq [info script]} {
    wm title . "[array size ::ttk::Cursors] cursors"
    pack [ttk::CursorSampler .f] -expand true -fill both
    bind . <Escape> [list destroy .]
    focus .f
}

#*EOF*







|




175
176
177
178
179
180
181
182
183
184
185
186

    return $f
}

if {[info exists argv0] && $argv0 eq [info script]} {
    wm title . "[array size ::ttk::Cursors] cursors"
    pack [ttk::CursorSampler .f] -expand true -fill both
    bind . <KeyPress-Escape> [list destroy .]
    focus .f
}

#*EOF*

Changes to library/ttk/defaults.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#
# Settings for default theme.
#

namespace eval ttk::theme::default {
    variable colors
    array set colors {
	-frame			"#d9d9d9"
	-foreground		"#000000"
	-window			"#ffffff"
	-text   		"#000000"
	-activebg		"#ececec"
	-selectbg		"#4a6984"
	-selectfg		"#ffffff"
	-darker 		"#c3c3c3"
	-disabledfg		"#a3a3a3"
	-indicator		"#4a6984"
	-disabledindicator	"#a3a3a3"
	-altindicator		"#9fbdd8"
	-disabledaltindicator	"#c0c0c0"
    }

    ttk::style theme settings default {

	ttk::style configure "." \
	    -borderwidth 	1 \
	    -background 	$colors(-frame) \







|
|
|
|
|
|
|
|
|
|
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
#
# Settings for default theme.
#

namespace eval ttk::theme::default {
    variable colors
    array set colors {
	-frame		"#d9d9d9"
	-foreground	"#000000"
	-window		"#ffffff"
	-text   	"#000000"
	-activebg	"#ececec"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"
	-darker 	"#c3c3c3"
	-disabledfg	"#a3a3a3"
	-indicator	"#4a6984"



    }

    ttk::style theme settings default {

	ttk::style configure "." \
	    -borderwidth 	1 \
	    -background 	$colors(-frame) \
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style configure TButton \
	    -anchor center -padding "3 3" -width -9 \
	    -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]

	ttk::style configure TCheckbutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TCheckbutton -indicatorcolor \
	    [list pressed $colors(-activebg)  \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			{!disabled selected} $colors(-indicator) \
			{disabled selected} $colors(-disabledindicator)]
	ttk::style map TCheckbutton -indicatorrelief \
	    [list alternate raised]

	ttk::style configure TRadiobutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TRadiobutton -indicatorcolor \
	    [list pressed $colors(-activebg)  \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			{!disabled selected} $colors(-indicator) \
			{disabled selected} $colors(-disabledindicator)]
	ttk::style map TRadiobutton -indicatorrelief \
	    [list alternate raised]

	ttk::style configure TMenubutton \
	    -relief raised -padding "10 3"

	ttk::style configure TEntry \
	    -relief sunken -fieldbackground white -padding 1
	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -arrowsize 12 -padding 1
	ttk::style map TCombobox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TLabelframe \







|




|
<
<
<
<
<
<




|
<
<
<
<
<
<











|
<







36
37
38
39
40
41
42
43
44
45
46
47
48






49
50
51
52
53






54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style configure TButton \
	    -anchor center -padding "3 3" -width -9 \
	    -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken] 

	ttk::style configure TCheckbutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TCheckbutton -indicatorcolor \
	    [list pressed $colors(-activebg)  selected $colors(-indicator)]







	ttk::style configure TRadiobutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TRadiobutton -indicatorcolor \
	    [list pressed $colors(-activebg)  selected $colors(-indicator)]







	ttk::style configure TMenubutton \
	    -relief raised -padding "10 3"

	ttk::style configure TEntry \
	    -relief sunken -fieldbackground white -padding 1
	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -arrowsize 12 -padding 1
	ttk::style map TCombobox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]


	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TLabelframe \
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	# Treeview.
	#
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview \
	    -background $colors(-window) \
	    -foreground $colors(-text) ;
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	# Combobox popdown frame
	ttk::style layout ComboboxPopdownFrame {
	    ComboboxPopdownFrame.border -sticky nswe
	}
 	ttk::style configure ComboboxPopdownFrame \
	    -borderwidth 1 -relief solid







<
|
<
|







90
91
92
93
94
95
96

97

98
99
100
101
102
103
104
105
	# Treeview.
	#
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview \
	    -background $colors(-window) \
	    -foreground $colors(-text) ;
	ttk::style map Treeview \

	    -background [list selected $colors(-selectbg)] \

	    -foreground [list selected $colors(-selectfg)] ;

	# Combobox popdown frame
	ttk::style layout ComboboxPopdownFrame {
	    ComboboxPopdownFrame.border -sticky nswe
	}
 	ttk::style configure ComboboxPopdownFrame \
	    -borderwidth 1 -relief solid

Changes to library/ttk/entry.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
#
# DERIVED FROM: tk/library/entry.tcl r1.22
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 2004, Joe English
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

namespace eval ttk {
    namespace eval entry {



|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
#
# DERIVED FROM: tk/library/entry.tcl r1.22
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 2004, Joe English
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

namespace eval ttk {
    namespace eval entry {
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
	set State(scanDen) 1
	set State(deadband) 3	;# #pixels for mouse-moved deadband.
    }
}

### Option database settings.
#
option add *TEntry.cursor [ttk::cursor text] widgetDefault

### Bindings.
#
# Removed the following standard Tk bindings:
#
# <Control-space>, <Control-Shift-space>,
# <Select>,  <Shift-Select>:
#	Ttk entry widget doesn't use selection anchor.
# <Insert>:
#	Inserts PRIMARY selection (on non-Windows platforms).
#	This is inconsistent with typical platform bindings.
# <Double-Shift-Button-1>, <Triple-Shift-Button-1>:
#	These don't do the right thing to start with.
# <Meta-b>, <Meta-d>, <Meta-f>,
# <Meta-BackSpace>, <Meta-Delete>:
#	Judgment call.  If <Meta> happens to be assigned to the Alt key,
#	these could conflict with application accelerators.
#	(Plus, who has a Meta key these days?)
# <Control-t>:
#	Another judgment call.  If anyone misses this, let me know
#	and I'll put it back.
#

## Clipboard events:
#
bind TEntry <<Cut>> 			{ ttk::entry::Cut %W }
bind TEntry <<Copy>> 			{ ttk::entry::Copy %W }
bind TEntry <<Paste>> 			{ ttk::entry::Paste %W }
bind TEntry <<Clear>> 			{ ttk::entry::Clear %W }

## Button1 bindings:
#	Used for selection and navigation.
#
bind TEntry <Button-1> 			{ ttk::entry::Press %W %x }
bind TEntry <Shift-Button-1>		{ ttk::entry::Shift-Press %W %x }
bind TEntry <Double-Button-1> 		{ ttk::entry::Select %W %x word }
bind TEntry <Triple-Button-1> 		{ ttk::entry::Select %W %x line }
bind TEntry <B1-Motion>			{ ttk::entry::Drag %W %x }

bind TEntry <B1-Leave> 			{ ttk::entry::DragOut %W %m }
bind TEntry <B1-Enter>			{ ttk::entry::DragIn %W }
bind TEntry <ButtonRelease-1>		{ ttk::entry::Release %W }

bind TEntry <<ToggleSelection>> {
    %W instate {!readonly !disabled} { %W icursor @%x ; focus %W }
}

## Button2 bindings:
#	Used for scanning and primary transfer.
#	Note: ButtonRelease-2
#	is mapped to <<PasteSelection>> in tk.tcl.
#
bind TEntry <Button-2> 			{ ttk::entry::ScanMark %W %x }
bind TEntry <B2-Motion> 		{ ttk::entry::ScanDrag %W %x }
bind TEntry <ButtonRelease-2>		{ ttk::entry::ScanRelease %W %x }
bind TEntry <<PasteSelection>>		{ ttk::entry::ScanRelease %W %x }

## Keyboard navigation bindings:
#
bind TEntry <<PrevChar>>		{ ttk::entry::Move %W prevchar }
bind TEntry <<NextChar>> 		{ ttk::entry::Move %W nextchar }
bind TEntry <<PrevWord>>		{ ttk::entry::Move %W prevword }
bind TEntry <<NextWord>>		{ ttk::entry::Move %W nextword }
bind TEntry <<LineStart>>		{ ttk::entry::Move %W home }
bind TEntry <<LineEnd>>			{ ttk::entry::Move %W end }

bind TEntry <<SelectPrevChar>> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <<SelectNextChar>>		{ ttk::entry::Extend %W nextchar }
bind TEntry <<SelectPrevWord>>		{ ttk::entry::Extend %W prevword }
bind TEntry <<SelectNextWord>>		{ ttk::entry::Extend %W nextword }
bind TEntry <<SelectLineStart>>		{ ttk::entry::Extend %W home }
bind TEntry <<SelectLineEnd>>		{ ttk::entry::Extend %W end }

bind TEntry <<SelectAll>> 		{ %W selection range 0 end }
bind TEntry <<SelectNone>> 		{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }

## Edit bindings:
#
bind TEntry <Key> 			{ ttk::entry::Insert %W %A }
bind TEntry <Delete>			{ ttk::entry::Delete %W }
bind TEntry <BackSpace> 		{ ttk::entry::Backspace %W }

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, the <Key> class binding will fire and insert the character.
# Ditto for Escape, Return, and Tab.
#
bind TEntry <Alt-Key>			{# nothing}
bind TEntry <Meta-Key>			{# nothing}
bind TEntry <Control-Key> 		{# nothing}
bind TEntry <Escape> 			{# nothing}
bind TEntry <Return> 			{# nothing}
bind TEntry <KP_Enter> 			{# nothing}
bind TEntry <Tab> 			{# nothing}

# Argh.  Apparently on Windows, the NumLock modifier is interpreted
# as a Command modifier.
if {[tk windowingsystem] eq "aqua"} {
    bind TEntry <Command-Key>		{# nothing}
}
# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind TEntry <<PrevLine>>		{# nothing}
bind TEntry <<NextLine>>		{# nothing}

## Additional emacs-like bindings:
#
bind TEntry <Control-d>			{ ttk::entry::Delete %W }
bind TEntry <Control-h>			{ ttk::entry::Backspace %W }
bind TEntry <Control-k>			{ %W delete insert end }

# Bindings for IME text input.

bind TEntry <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind TEntry <<TkEndIMEMarkedText>> {
    if { [catch {dict get $::tk::Priv(IMETextMark) "%W"} mark] } {
	bell
    } else {
	%W selection range $mark insert
    }
}
bind TEntry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind TEntry <<TkAccentBackspace>> {
    ttk::entry::Backspace %W
}


### Clipboard procedures.
#

## EntrySelection -- Return the selected text of the entry.
#	Raises an error if there is no selection.
#
proc ttk::entry::EntrySelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [$w index sel.last]-1]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}








|





|
|
|
|


|

|
|



|














|
|
|
|


|
|
|

|





|
<

|






|
|
|
|
|
|

|
|
|
|
|
|

|
|





|
|
|


|


|
|
|
|
|
|
|




|


|
|



|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>









|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148














149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
	set State(scanDen) 1
	set State(deadband) 3	;# #pixels for mouse-moved deadband.
    }
}

### Option database settings.
#
option add *TEntry.cursor [ttk::cursor text]

### Bindings.
#
# Removed the following standard Tk bindings:
#
# <Control-Key-space>, <Control-Shift-Key-space>,
# <Key-Select>,  <Shift-Key-Select>:
#	ttk::entry widget doesn't use selection anchor.
# <Key-Insert>:
#	Inserts PRIMARY selection (on non-Windows platforms).
#	This is inconsistent with typical platform bindings.
# <Double-Shift-ButtonPress-1>, <Triple-Shift-ButtonPress-1>:
#	These don't do the right thing to start with.
# <Meta-Key-b>, <Meta-Key-d>, <Meta-Key-f>,
# <Meta-Key-BackSpace>, <Meta-Key-Delete>:
#	Judgment call.  If <Meta> happens to be assigned to the Alt key,
#	these could conflict with application accelerators.
#	(Plus, who has a Meta key these days?)
# <Control-Key-t>:
#	Another judgment call.  If anyone misses this, let me know
#	and I'll put it back.
#

## Clipboard events:
#
bind TEntry <<Cut>> 			{ ttk::entry::Cut %W }
bind TEntry <<Copy>> 			{ ttk::entry::Copy %W }
bind TEntry <<Paste>> 			{ ttk::entry::Paste %W }
bind TEntry <<Clear>> 			{ ttk::entry::Clear %W }

## Button1 bindings:
#	Used for selection and navigation.
#
bind TEntry <ButtonPress-1> 		{ ttk::entry::Press %W %x }
bind TEntry <Shift-ButtonPress-1>	{ ttk::entry::Shift-Press %W %x }
bind TEntry <Double-ButtonPress-1> 	{ ttk::entry::Select %W %x word }
bind TEntry <Triple-ButtonPress-1> 	{ ttk::entry::Select %W %x line }
bind TEntry <B1-Motion>			{ ttk::entry::Drag %W %x }

bind TEntry <B1-Leave> 		{ ttk::entry::DragOut %W %m }
bind TEntry <B1-Enter>		{ ttk::entry::DragIn %W }
bind TEntry <ButtonRelease-1>	{ ttk::entry::Release %W }

bind TEntry <Control-ButtonPress-1> {
    %W instate {!readonly !disabled} { %W icursor @%x ; focus %W }
}

## Button2 bindings:
#	Used for scanning and primary transfer.
#	Note: ButtonRelease-2 is mapped to <<PasteSelection>> in tk.tcl.

#
bind TEntry <ButtonPress-2> 		{ ttk::entry::ScanMark %W %x }
bind TEntry <B2-Motion> 		{ ttk::entry::ScanDrag %W %x }
bind TEntry <ButtonRelease-2>		{ ttk::entry::ScanRelease %W %x }
bind TEntry <<PasteSelection>>		{ ttk::entry::ScanRelease %W %x }

## Keyboard navigation bindings:
#
bind TEntry <Key-Left> 			{ ttk::entry::Move %W prevchar }
bind TEntry <Key-Right> 		{ ttk::entry::Move %W nextchar }
bind TEntry <Control-Key-Left>		{ ttk::entry::Move %W prevword }
bind TEntry <Control-Key-Right>		{ ttk::entry::Move %W nextword }
bind TEntry <Key-Home>			{ ttk::entry::Move %W home }
bind TEntry <Key-End>			{ ttk::entry::Move %W end }

bind TEntry <Shift-Key-Left> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <Shift-Key-Right>		{ ttk::entry::Extend %W nextchar }
bind TEntry <Shift-Control-Key-Left>	{ ttk::entry::Extend %W prevword }
bind TEntry <Shift-Control-Key-Right>	{ ttk::entry::Extend %W nextword }
bind TEntry <Shift-Key-Home>		{ ttk::entry::Extend %W home }
bind TEntry <Shift-Key-End>		{ ttk::entry::Extend %W end }

bind TEntry <Control-Key-slash> 	{ %W selection range 0 end }
bind TEntry <Control-Key-backslash> 	{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }

## Edit bindings:
#
bind TEntry <KeyPress> 			{ ttk::entry::Insert %W %A }
bind TEntry <Key-Delete>		{ ttk::entry::Delete %W }
bind TEntry <Key-BackSpace> 		{ ttk::entry::Backspace %W }

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, the <KeyPress> class binding will fire and insert the character.
# Ditto for Escape, Return, and Tab.
#
bind TEntry <Alt-KeyPress>		{# nothing}
bind TEntry <Meta-KeyPress>		{# nothing}
bind TEntry <Control-KeyPress> 		{# nothing}
bind TEntry <Key-Escape> 		{# nothing}
bind TEntry <Key-Return> 		{# nothing}
bind TEntry <Key-KP_Enter> 		{# nothing}
bind TEntry <Key-Tab> 			{# nothing}

# Argh.  Apparently on Windows, the NumLock modifier is interpreted
# as a Command modifier.
if {[tk windowingsystem] eq "aqua"} {
    bind TEntry <Command-KeyPress>	{# nothing}
}
# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind TEntry <Down>			{# nothing}
bind TEntry <Up>			{# nothing}

## Additional emacs-like bindings:
#
bind TEntry <Control-Key-a>		{ ttk::entry::Move %W home }
bind TEntry <Control-Key-b>		{ ttk::entry::Move %W prevchar }
bind TEntry <Control-Key-d> 		{ ttk::entry::Delete %W }
bind TEntry <Control-Key-e> 		{ ttk::entry::Move %W end }

bind TEntry <Control-Key-f> 		{ ttk::entry::Move %W nextchar }














bind TEntry <Control-Key-h>		{ ttk::entry::Backspace %W }

bind TEntry <Control-Key-k>		{ %W delete insert end }

### Clipboard procedures.
#

## EntrySelection -- Return the selected text of the entry.
#	Raises an error if there is no selection.
#
proc ttk::entry::EntrySelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}

227
228
229
230
231
232
233

234
235
236
237
238
239
240
    }
    return $pos
}

## See $index -- Make sure that the character at $index is visible.
#
proc ttk::entry::See {w {index insert}} {

    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}








>







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    }
    return $pos
}

## See $index -- Make sure that the character at $index is visible.
#
proc ttk::entry::See {w {index insert}} {
    update idletasks	;# ensure scroll data up-to-date
    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

### Button 1 binding procedures.
#
# Double-clicking followed by a drag enters "word-select" mode.
# Triple-clicking enters "line-select" mode.
#

## Press -- Button-1 binding.
#	Set the insertion cursor, claim the input focus, set up for
#	future drag operations.
#
proc ttk::entry::Press {w x} {
    variable State

    $w icursor [ClosestGap $w $x]
    $w selection clear
    $w instate !disabled { focus $w }

    # Set up for future drag, double-click, or triple-click.
    set State(x) $x
    set State(selectMode) char
    set State(anchor) [$w index insert]
}

## Shift-Press -- Shift-Button-1 binding.
#	Extends the selection, sets anchor for future drag operations.
#
proc ttk::entry::Shift-Press {w x} {
    variable State

    focus $w
    set anchor [ExtendTo $w @$x]







|
















|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

### Button 1 binding procedures.
#
# Double-clicking followed by a drag enters "word-select" mode.
# Triple-clicking enters "line-select" mode.
#

## Press -- ButtonPress-1 binding.
#	Set the insertion cursor, claim the input focus, set up for
#	future drag operations.
#
proc ttk::entry::Press {w x} {
    variable State

    $w icursor [ClosestGap $w $x]
    $w selection clear
    $w instate !disabled { focus $w }

    # Set up for future drag, double-click, or triple-click.
    set State(x) $x
    set State(selectMode) char
    set State(anchor) [$w index insert]
}

## Shift-Press -- Shift-ButtonPress-1 binding.
#	Extends the selection, sets anchor for future drag operations.
#
proc ttk::entry::Shift-Press {w x} {
    variable State

    focus $w
    set anchor [ExtendTo $w @$x]
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    }
}

## <B1-Enter> binding
# 	Suspend autoscroll.
#
proc ttk::entry::DragIn {w} {
    ttk::CancelRepeat
}

## <ButtonRelease-1> binding
#
proc ttk::entry::Release {w} {
    variable State
    set State(selectMode) none
    ttk::CancelRepeat 	;# suspend autoscroll
}

## AutoScroll
#	Called repeatedly when the mouse is outside an entry window
#	with Button 1 down.  Scroll the window left or right,
#	depending on where the mouse left the window, and extend
#	the selection according to the current selection mode.
#
# TODO: AutoScroll should repeat faster (50ms) than normal autorepeat.
# TODO: Need a way for Repeat scripts to cancel themselves.
#
proc ttk::entry::AutoScroll {w} {
    variable State







|













|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    }
}

## <B1-Enter> binding
# 	Suspend autoscroll.
#
proc ttk::entry::DragIn {w} {
    ttk::CancelRepeat 
}

## <ButtonRelease-1> binding
#
proc ttk::entry::Release {w} {
    variable State
    set State(selectMode) none
    ttk::CancelRepeat 	;# suspend autoscroll
}

## AutoScroll
#	Called repeatedly when the mouse is outside an entry window
#	with Button 1 down.  Scroll the window left or right,
#	depending on where the mouse left the window, and extend 
#	the selection according to the current selection mode.
#
# TODO: AutoScroll should repeat faster (50ms) than normal autorepeat.
# TODO: Need a way for Repeat scripts to cancel themselves.
#
proc ttk::entry::AutoScroll {w} {
    variable State
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    $w selection range 0 end
    $w icursor end
}

### Button 2 binding procedures.
#

## ScanMark -- Button-2 binding.
#	Marks the start of a scan or primary transfer operation.
#
proc ttk::entry::ScanMark {w x} {
    variable State
    set State(scanX) $x
    set State(scanIndex) [$w index @0]
    set State(scanMoved) 0







|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    $w selection range 0 end
    $w icursor end
}

### Button 2 binding procedures.
#

## ScanMark -- ButtonPress-2 binding.
#	Marks the start of a scan or primary transfer operation.
#
proc ttk::entry::ScanMark {w x} {
    variable State
    set State(scanX) $x
    set State(scanIndex) [$w index @0]
    set State(scanMoved) 0

Changes to library/ttk/fonts.tcl.

49
50
51
52
53
54
55




56
57
58
59
60
61
62
#	For now, assume patch #971980 applied.
#
#	"Classic" look used Helvetica bold for everything except
#	for entry widgets, which use Helvetica medium.
#	Most other toolkits use medium weight for all UI elements,
#	which is what we do now.
#





namespace eval ttk {

variable tip145 [catch {font create TkDefaultFont}]
catch {font create TkTextFont}
catch {font create TkHeadingFont}
catch {font create TkCaptionFont}







>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#	For now, assume patch #971980 applied.
#
#	"Classic" look used Helvetica bold for everything except
#	for entry widgets, which use Helvetica medium.
#	Most other toolkits use medium weight for all UI elements,
#	which is what we do now.
#
#	Font size specified in pixels on X11, not points.
#	This is Theoretically Wrong, but in practice works better; using
#	points leads to huge inconsistencies across different servers.
#

namespace eval ttk {

variable tip145 [catch {font create TkDefaultFont}]
catch {font create TkTextFont}
catch {font create TkHeadingFont}
catch {font create TkCaptionFont}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
	if {[info exists tcl_platform(osVersion)]} {
            if {$tcl_platform(osVersion) >= 5.0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        } else {
            if {[lsearch -exact [font families] Tahoma] >= 0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        }
	set F(size) 8








|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	if {[info exists tcl_platform(osVersion)]} {
            if {$tcl_platform(osVersion) >= 5.0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        } else {
            if {[lsearch -exact [font families] Tahoma] != -1} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        }
	set F(size) 8

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
	if {![catch {tk::pkgconfig get fontsystem} F(fs)] && $F(fs) eq "xft"} {
	    set F(family) "sans-serif"
	    set F(fixed)  "monospace"
	} else {
	    set F(family) "Helvetica"
	    set F(fixed)  "courier"
	}
	set F(size) 10
	set F(ttsize) 9
	set F(capsize) 12
	set F(fixedsize) 10

	font configure TkDefaultFont -family $F(family) -size $F(size)
	font configure TkTextFont    -family $F(family) -size $F(size)
	font configure TkHeadingFont -family $F(family) -size $F(size) \
			-weight bold
	font configure TkCaptionFont -family $F(family) -size $F(capsize) \
			-weight bold







|
|
|
|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	if {![catch {tk::pkgconfig get fontsystem} F(fs)] && $F(fs) eq "xft"} {
	    set F(family) "sans-serif"
	    set F(fixed)  "monospace"
	} else {
	    set F(family) "Helvetica"
	    set F(fixed)  "courier"
	}
	set F(size) -12
	set F(ttsize) -10
	set F(capsize) -14
	set F(fixedsize) -12

	font configure TkDefaultFont -family $F(family) -size $F(size)
	font configure TkTextFont    -family $F(family) -size $F(size)
	font configure TkHeadingFont -family $F(family) -size $F(size) \
			-weight bold
	font configure TkCaptionFont -family $F(family) -size $F(capsize) \
			-weight bold

Changes to library/ttk/menubutton.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#
# Bindings for Menubuttons.
#
# Menubuttons have three interaction modes:
#
# Pulldown: Press menubutton, drag over menu, release to activate menu entry
# Popdown: Click menubutton to post menu
# Keyboard: <space> or accelerator key to post menu
#
# (In addition, when menu system is active, "dropdown" -- menu posts
# on mouse-over.  Ttk menubuttons don't implement this).
#
# For keyboard and popdown mode, we hand off to tk_popup and let
# the built-in Tk bindings handle the rest of the interaction.
#
# ON X11:
#
# Standard Tk menubuttons use a global grab on the menubutton.
# This won't work for Ttk menubuttons in pulldown mode,
# since we need to process the final <ButtonRelease> event,
# and this might be delivered to the menu.  So instead we
# rely on the passive grab that occurs on <Button> events,
# and transition to popdown mode when the mouse is released
# or dragged outside the menubutton.
#
# ON WINDOWS:
#
# I'm not sure what the hell is going on here.  [$menu post] apparently
# sets up some kind of internal grab for native menus.
# On this platform, just use [tk_popup] for all menu actions.
#
# ON MACOS:
#
# Same probably applies here.
#

namespace eval ttk {
    namespace eval menubutton {
	variable State
	array set State {
	    pulldown	0
	    oldcursor	{}
	}
    }
}

bind TMenubutton <Enter>	{ %W instate !disabled {%W state active } }
bind TMenubutton <Leave>	{ %W state !active }
bind TMenubutton <space>	{ ttk::menubutton::Popdown %W }
bind TMenubutton <<Invoke>> 	{ ttk::menubutton::Popdown %W }

if {[tk windowingsystem] eq "x11"} {
    bind TMenubutton <Button-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <Button-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \
	{ if {[winfo exists %W]} { %W state !pressed } }
}

# PostPosition --
#	Returns x and y coordinates and a menu item index.
#       If the index is not an empty string the menu should
#       be posted so that the upper left corner of the indexed
#       menu item is located at the point (x, y).  Otherwise
#       the top left corner of the menu itself should be located
#       at that point.

#
# TODO: adjust menu width to be at least as wide as the button
#	for -direction above, below.
#

if {[tk windowingsystem] eq "aqua"} {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set menuPad 5
	set buttonPad 1
	set bevelPad 4
	set mh [winfo reqheight $menu]
	set bh [expr {[winfo height $mb]} + $buttonPad]
	set bbh [expr {[winfo height $mb]} + $bevelPad]
	set mw [winfo reqwidth $menu]
	set bw [winfo width $mb]
	set dF [expr {[winfo width $mb] - [winfo reqwidth $menu] - $menuPad}]
	set entry ""
	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry eq ""} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry ""
		incr y [expr {-$mh + 2 * $menuPad}]
	    }
	    below {
		set entry ""
		incr y $bh
	    }
	    left {
		incr y $menuPad
		incr x -$mw
	    }
	    right {
		incr y $menuPad
		incr x $bw
	    }
	    default {
		incr y $bbh
	    }
	}
	return [list $x $y $entry]
    }
} else {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set mh [expr {[winfo reqheight $menu]}]
	set bh [expr {[winfo height $mb]}]
	set mw [expr {[winfo reqwidth $menu]}]
	set bw [expr {[winfo width $mb]}]
	set dF [expr {[winfo width $mb] - [winfo reqwidth $menu]}]
	if {[tk windowingsystem] eq "win32"} {
	    incr mh 6
	    incr mw 16
	}
	set entry {}
	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry eq {}} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry {}
		incr y -$mh
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $mb]} {
		    set y [expr {[winfo vrooty $mb] + [winfo rooty $mb]\
                           + [winfo reqheight $mb]}]
		}
	    }
	    below {



		set entry {}
		incr y $bh
		# if we go offscreen to the bottom, show as 'above'
		if {($y + $mh) > ([winfo vrooty $mb] + [winfo vrootheight $mb])} {
		    set y [expr {[winfo vrooty $mb] + [winfo vrootheight $mb] \
			   + [winfo rooty $mb] - $mh}]
		}
	    }
	    left {
		incr x -$mw
	    }
	    right {
		incr x $bw
	    }
	    default {
		if {[$mb cget -style] eq ""} {
		    incr x [expr {([winfo width $mb] - \
				   [winfo reqwidth $menu])/ 2}]
		} else {
		    incr y $bh
		}
	    }
	}
	return [list $x $y $entry]
    }
}

# Popdown --
#	Post the menu and set a grab on the menu.
#
proc ttk::menubutton::Popdown {mb} {
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }
    foreach {x y entry} [PostPosition $mb $menu] { break }
    tk_popup $menu $x $y $entry
}

# Pulldown (X11 only) --
#	Called when Button1 is pressed on a menubutton.
#	Posts the menu; a subsequent ButtonRelease
#	or Leave event will set a grab on the menu.
#
proc ttk::menubutton::Pulldown {mb} {
    variable State
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }

    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]

    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]
    foreach {x y entry} [PostPosition $mb $menu] { break }
    if {$entry ne {}} {
	$menu post $x $y $entry
    } else {
	$menu post $x $y
    }
    tk_menuSetFocus $menu
}

# TransferGrab (X11 only) --
#	Switch from pulldown mode (menubutton has an implicit grab)
#	to popdown mode (menu has an explicit grab).
#
proc ttk::menubutton::TransferGrab {mb} {
    variable State
    if {$State(pulldown)} {
	$mb configure -cursor $State(oldcursor)
	$mb state {!pressed !active}
	set State(pulldown) 0

	set menu [$mb cget -menu]
	foreach {x y entry} [PostPosition $mb $menu] { break }
    	tk_popup $menu [winfo rootx $menu] [winfo rooty $menu]
    }
}

# FindMenuEntry --
#	Hack to support tk_optionMenus.
#	Returns the index of the menu entry with a matching -label,
#	"" if not found.
#
proc ttk::menubutton::FindMenuEntry {menu s} {
    set last [$menu index last]
    if {$last eq "none" || $last eq ""} {
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]
	    && ($label eq $s)} {
	    return $i
	}
    }
    return ""
}

#*EOF*







|




|








|


|


|


|

















|



|



|


|



|
<
|
<
<
<
>




<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
<
|
<
<
|
|
<
<
|
|
<
|
<
|
<
|
<
<
|
>
>
>
|
<
<
<
<
|
<
<
|
|

<
<
|
<
<
<
<
<
<
|
|
<
|
<









|
|




|







>





<
<
<
<
|
<















<







|



|












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65



66
67
68
69
70


71














72
73
74



75

76



















77


78

79


80


81
82


83
84

85

86

87


88
89
90
91
92




93


94
95
96


97






98
99

100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129




130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#
# Bindings for Menubuttons.
#
# Menubuttons have three interaction modes:
#
# Pulldown: Press menubutton, drag over menu, release to activate menu entry
# Popdown: Click menubutton to post menu
# Keyboard: <Key-space> or accelerator key to post menu
#
# (In addition, when menu system is active, "dropdown" -- menu posts
# on mouse-over.  Ttk menubuttons don't implement this).
#
# For keyboard and popdown mode, we hand off to tk_popup and let 
# the built-in Tk bindings handle the rest of the interaction.
#
# ON X11:
#
# Standard Tk menubuttons use a global grab on the menubutton.
# This won't work for Ttk menubuttons in pulldown mode,
# since we need to process the final <ButtonRelease> event,
# and this might be delivered to the menu.  So instead we
# rely on the passive grab that occurs on <ButtonPress> events,
# and transition to popdown mode when the mouse is released
# or dragged outside the menubutton.
# 
# ON WINDOWS:
#
# I'm not sure what the hell is going on here.  [$menu post] apparently 
# sets up some kind of internal grab for native menus.
# On this platform, just use [tk_popup] for all menu actions.
# 
# ON MACOS:
#
# Same probably applies here.
#

namespace eval ttk {
    namespace eval menubutton {
	variable State
	array set State {
	    pulldown	0
	    oldcursor	{}
	}
    }
}

bind TMenubutton <Enter>	{ %W instate !disabled {%W state active } }
bind TMenubutton <Leave>	{ %W state !active }
bind TMenubutton <Key-space> 	{ ttk::menubutton::Popdown %W }
bind TMenubutton <<Invoke>> 	{ ttk::menubutton::Popdown %W }

if {[tk windowingsystem] eq "x11"} {
    bind TMenubutton <ButtonPress-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <ButtonPress-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \
	{ %W state !pressed }
}

# PostPosition --
#	Returns the x and y coordinates where the menu 

#	should be posted, based on the menubutton and menu size



#	and -direction option.
#
# TODO: adjust menu width to be at least as wide as the button
#	for -direction above, below.
#


proc ttk::menubutton::PostPosition {mb menu} {














    set x [winfo rootx $mb]
    set y [winfo rooty $mb]
    set dir [$mb cget -direction]





    set bw [winfo width $mb]



















    set bh [winfo height $mb]


    set mw [winfo reqwidth $menu]

    set mh [winfo reqheight $menu]


    set sw [expr {[winfo screenwidth  $menu] - $bw - $mw}]


    set sh [expr {[winfo screenheight $menu] - $bh - $mh}]



    switch -- $dir {
	above { if {$y >= $mh} { incr y -$mh } { incr y  $bh } }

	below { if {$y <= $sh} { incr y  $bh } { incr y -$mh } }

	left  { if {$x >= $mw} { incr x -$mw } { incr x  $bw } }

	right { if {$x <= $sw} { incr x  $bw } { incr x -$mw } }


	flush { 
	    # post menu atop menubutton.
	    # If there's a menu entry whose label matches the
	    # menubutton -text, assume this is an optionmenu
	    # and place that entry over the menubutton.




	    set index [FindMenuEntry $menu [$mb cget -text]]


	    if {$index ne ""} {
		incr y -[$menu yposition $index]
	    }


	}






    }


    return [list $x $y]

}

# Popdown --
#	Post the menu and set a grab on the menu.
#
proc ttk::menubutton::Popdown {mb} {
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }
    foreach {x y} [PostPosition $mb $menu] { break }
    tk_popup $menu $x $y
}

# Pulldown (X11 only) --
#	Called when Button1 is pressed on a menubutton.
#	Posts the menu; a subsequent ButtonRelease 
#	or Leave event will set a grab on the menu.
#
proc ttk::menubutton::Pulldown {mb} {
    variable State
    if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} {
	return
    }
    foreach {x y} [PostPosition $mb $menu] { break }
    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]

    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]




    $menu post $x $y

    tk_menuSetFocus $menu
}

# TransferGrab (X11 only) --
#	Switch from pulldown mode (menubutton has an implicit grab)
#	to popdown mode (menu has an explicit grab).
#
proc ttk::menubutton::TransferGrab {mb} {
    variable State
    if {$State(pulldown)} {
	$mb configure -cursor $State(oldcursor)
	$mb state {!pressed !active}
	set State(pulldown) 0

	set menu [$mb cget -menu]

    	tk_popup $menu [winfo rootx $menu] [winfo rooty $menu]
    }
}

# FindMenuEntry --
#	Hack to support tk_optionMenus.
#	Returns the index of the menu entry with a matching -label,
#	-1 if not found.
#
proc ttk::menubutton::FindMenuEntry {menu s} {
    set last [$menu index last]
    if {$last eq "none"} {
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]
	    && ($label eq $s)} {
	    return $i
	}
    }
    return ""
}

#*EOF*

Changes to library/ttk/notebook.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
# Bindings for TNotebook widget
#

namespace eval ttk::notebook {
    variable TLNotebooks ;# See enableTraversal
}

bind TNotebook <Button-1>		{ ttk::notebook::Press %W %x %y }
bind TNotebook <Right>			{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Left>			{ ttk::notebook::CycleTab %W -1; break }
bind TNotebook <Control-Tab>		{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Control-Shift-Tab>	{ ttk::notebook::CycleTab %W -1; break }
catch {
bind TNotebook <Control-ISO_Left_Tab>	{ ttk::notebook::CycleTab %W -1; break }
}
bind TNotebook <Destroy>		{ ttk::notebook::Cleanup %W }

# ActivateTab $nb $tab --
#	Select the specified tab and set focus.








|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
# Bindings for TNotebook widget
#

namespace eval ttk::notebook {
    variable TLNotebooks ;# See enableTraversal
}

bind TNotebook <ButtonPress-1>		{ ttk::notebook::Press %W %x %y }
bind TNotebook <Key-Right>		{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Key-Left>		{ ttk::notebook::CycleTab %W -1; break }
bind TNotebook <Control-Key-Tab>	{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Control-Shift-Key-Tab>	{ ttk::notebook::CycleTab %W -1; break }
catch {
bind TNotebook <Control-ISO_Left_Tab>	{ ttk::notebook::CycleTab %W -1; break }
}
bind TNotebook <Destroy>		{ ttk::notebook::Cleanup %W }

# ActivateTab $nb $tab --
#	Select the specified tab and set focus.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	ttk::traverseTo $f
    } else {
	focus $w
    }
}

# Press $nb $x $y --
#	Button-1 binding for notebook widgets.
#	Activate the tab under the mouse cursor, if any.
#
proc ttk::notebook::Press {w x y} {
    set index [$w index @$x,$y]
    if {$index ne ""} {
	ActivateTab $w $index
    }







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	ttk::traverseTo $f
    } else {
	focus $w
    }
}

# Press $nb $x $y --
#	ButtonPress-1 binding for notebook widgets.
#	Activate the tab under the mouse cursor, if any.
#
proc ttk::notebook::Press {w x y} {
    set index [$w index @$x,$y]
    if {$index ne ""} {
	ActivateTab $w $index
    }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	if {$select != $current} {
	    ActivateTab $w $select
	}
    }
}

# MnemonicTab $nb $key --
#	Scan all tabs in the specified notebook for one with the
#	specified mnemonic. If found, returns path name of tab;
#	otherwise returns ""
#
proc ttk::notebook::MnemonicTab {nb key} {
    set key [string toupper $key]
    foreach tab [$nb tabs] {
	set label [$nb tab $tab -text]







|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	if {$select != $current} {
	    ActivateTab $w $select
	}
    }
}

# MnemonicTab $nb $key --
#	Scan all tabs in the specified notebook for one with the 
#	specified mnemonic. If found, returns path name of tab;
#	otherwise returns ""
#
proc ttk::notebook::MnemonicTab {nb key} {
    set key [string toupper $key]
    foreach tab [$nb tabs] {
	set label [$nb tab $tab -text]
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# +++ Toplevel keyboard traversal.
#

# enableTraversal --
#	Enable keyboard traversal for a notebook widget
#	by adding bindings to the containing toplevel window.
#
#	TLNotebooks($top) keeps track of the list of all traversal-enabled
#	notebooks contained in the toplevel
#
proc ttk::notebook::enableTraversal {nb} {
    variable TLNotebooks

    set top [winfo toplevel $nb]

    if {![info exists TLNotebooks($top)]} {
	# Augment $top bindings:
	#
	bind $top <Control-Next>             {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Prior>            {+ttk::notebook::TLCycleTab %W -1}
	bind $top <Control-Tab> 	     {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Shift-Tab>        {+ttk::notebook::TLCycleTab %W -1}
	catch {
	bind $top <Control-ISO_Left_Tab>     {+ttk::notebook::TLCycleTab %W -1}
	}
	if {[tk windowingsystem] eq "aqua"} {
	    bind $top <Option-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	} else {
	    bind $top <Alt-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	}
	bind $top <Destroy> {+ttk::notebook::TLCleanup %W}
    }

    lappend TLNotebooks($top) $nb
}







|
|









|
|
|
|

|


|


|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# +++ Toplevel keyboard traversal.
#

# enableTraversal --
#	Enable keyboard traversal for a notebook widget
#	by adding bindings to the containing toplevel window.
#
#	TLNotebooks($top) keeps track of the list of all traversal-enabled 
#	notebooks contained in the toplevel 
#
proc ttk::notebook::enableTraversal {nb} {
    variable TLNotebooks

    set top [winfo toplevel $nb]

    if {![info exists TLNotebooks($top)]} {
	# Augment $top bindings:
	#
	bind $top <Control-Key-Next>         {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Key-Prior>        {+ttk::notebook::TLCycleTab %W -1}
	bind $top <Control-Key-Tab> 	     {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Shift-Control-Key-Tab>    {+ttk::notebook::TLCycleTab %W -1}
	catch {
	bind $top <Control-Key-ISO_Left_Tab> {+ttk::notebook::TLCycleTab %W -1}
	}
	if {[tk windowingsystem] eq "aqua"} {
	    bind $top <Option-KeyPress> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	} else {
	    bind $top <Alt-KeyPress> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	}
	bind $top <Destroy> {+ttk::notebook::TLCleanup %W}
    }

    lappend TLNotebooks($top) $nb
}
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    set top [winfo toplevel $nb]
    if {[info exists TLNotebooks($top)]} {
	set index [lsearch -exact $TLNotebooks($top) $nb]
        set TLNotebooks($top) [lreplace $TLNotebooks($top) $index $index]
    }
}

# EnclosingNotebook $w --
#	Return the nearest traversal-enabled notebook widget
#	that contains $w.
#
# BUGS: this only works properly for tabs that are direct children
#	of the notebook widget.  This routine should follow the
#	geometry manager hierarchy, not window ancestry, but that
#	information is not available in Tk.







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    set top [winfo toplevel $nb]
    if {[info exists TLNotebooks($top)]} {
	set index [lsearch -exact $TLNotebooks($top) $nb]
        set TLNotebooks($top) [lreplace $TLNotebooks($top) $index $index]
    }
}

# EnclosingNotebook $w -- 
#	Return the nearest traversal-enabled notebook widget
#	that contains $w.
#
# BUGS: this only works properly for tabs that are direct children
#	of the notebook widget.  This routine should follow the
#	geometry manager hierarchy, not window ancestry, but that
#	information is not available in Tk.
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	}
	set w [winfo parent $w]
    }
    return ""
}

# TLCycleTab --
#	toplevel binding procedure for Control-Tab / Control-Shift-Tab
#	Select the next/previous tab in the nearest ancestor notebook.
#
proc ttk::notebook::TLCycleTab {w dir} {
    set nb [EnclosingNotebook $w]
    if {$nb ne ""} {
	CycleTab $nb $dir
	return -code break
    }
}

# MnemonicActivation $nb $key --
#	Alt-Key binding procedure for mnemonic activation.
#	Scan all notebooks in specified toplevel for a tab with the
#	the specified mnemonic.  If found, activate it and return TCL_BREAK.
#
proc ttk::notebook::MnemonicActivation {top key} {
    variable TLNotebooks
    foreach nb $TLNotebooks($top) {
	if {[set tab [MnemonicTab $nb $key]] ne ""} {
	    ActivateTab $nb [$nb index $tab]
	    return -code break
	}
    }
}







|
|










|












166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	}
	set w [winfo parent $w]
    }
    return ""
}

# TLCycleTab --
#	toplevel binding procedure for Control-Tab / Shift-Control-Tab
#	Select the next/previous tab in the nearest ancestor notebook. 
#
proc ttk::notebook::TLCycleTab {w dir} {
    set nb [EnclosingNotebook $w]
    if {$nb ne ""} {
	CycleTab $nb $dir
	return -code break
    }
}

# MnemonicActivation $nb $key --
#	Alt-KeyPress binding procedure for mnemonic activation.
#	Scan all notebooks in specified toplevel for a tab with the
#	the specified mnemonic.  If found, activate it and return TCL_BREAK.
#
proc ttk::notebook::MnemonicActivation {top key} {
    variable TLNotebooks
    foreach nb $TLNotebooks($top) {
	if {[set tab [MnemonicTab $nb $key]] ne ""} {
	    ActivateTab $nb [$nb index $tab]
	    return -code break
	}
    }
}

Changes to library/ttk/panedwindow.tcl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	sash 	-
	sashPos -
    }
}

## Bindings:
#
bind TPanedwindow <Button-1> 		{ ttk::panedwindow::Press %W %x %y }
bind TPanedwindow <B1-Motion>		{ ttk::panedwindow::Drag %W %x %y }
bind TPanedwindow <ButtonRelease-1> 	{ ttk::panedwindow::Release %W %x %y }

bind TPanedwindow <Motion> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Enter> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Leave> 		{ ttk::panedwindow::ResetCursor %W }
# See <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	sash 	-
	sashPos -
    }
}

## Bindings:
#
bind TPanedwindow <ButtonPress-1> 	{ ttk::panedwindow::Press %W %x %y }
bind TPanedwindow <B1-Motion>		{ ttk::panedwindow::Drag %W %x %y }
bind TPanedwindow <ButtonRelease-1> 	{ ttk::panedwindow::Release %W %x %y }

bind TPanedwindow <Motion> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Enter> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Leave> 		{ ttk::panedwindow::ResetCursor %W }
# See <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    SetCursor $w $x $y
}

## Cursor management:
#
proc ttk::panedwindow::ResetCursor {w} {
    variable State

    ttk::saveCursor $w State(userConfCursor) \
            [list [ttk::cursor hresize] [ttk::cursor vresize]]

    if {!$State(pressed)} {
	ttk::setCursor $w $State(userConfCursor)
    }
}

proc ttk::panedwindow::SetCursor {w x y} {
    variable State

    ttk::saveCursor $w State(userConfCursor) \
            [list [ttk::cursor hresize] [ttk::cursor vresize]]

    set cursor $State(userConfCursor)
    if {[llength [$w identify $x $y]]} {
    	# Assume we're over a sash.
	switch -- [$w cget -orient] {
	    horizontal 	{ set cursor hresize }
	    vertical 	{ set cursor vresize }
	}
    }
    ttk::setCursor $w $cursor
}

#*EOF*







<
<
<
<

|




<
<
<
<
<
|











58
59
60
61
62
63
64




65
66
67
68
69
70





71
72
73
74
75
76
77
78
79
80
81
82
    SetCursor $w $x $y
}

## Cursor management:
#
proc ttk::panedwindow::ResetCursor {w} {
    variable State




    if {!$State(pressed)} {
	ttk::setCursor $w {}
    }
}

proc ttk::panedwindow::SetCursor {w x y} {





    set cursor ""
    if {[llength [$w identify $x $y]]} {
    	# Assume we're over a sash.
	switch -- [$w cget -orient] {
	    horizontal 	{ set cursor hresize }
	    vertical 	{ set cursor vresize }
	}
    }
    ttk::setCursor $w $cursor
}

#*EOF*

Changes to library/ttk/scale.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# scale.tcl - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
#
# Bindings for the TScale widget

namespace eval ttk::scale {
    variable State
    array set State  {
	dragging 0
    }
}

bind TScale <Button-1>        { ttk::scale::Press %W %x %y }
bind TScale <B1-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-1> { ttk::scale::Release %W %x %y }

bind TScale <Button-2>        { ttk::scale::Jump %W %x %y }
bind TScale <B2-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-2> { ttk::scale::Release %W %x %y }

bind TScale <Button-3>        { ttk::scale::Jump %W %x %y }
bind TScale <B3-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-3> { ttk::scale::Release %W %x %y }

## Keyboard navigation bindings:
#
bind TScale <<LineStart>>     { %W set [%W cget -from] }
bind TScale <<LineEnd>>       { %W set [%W cget -to] }

bind TScale <<PrevChar>>      { ttk::scale::Increment %W -1 }
bind TScale <<PrevLine>>      { ttk::scale::Increment %W -1 }
bind TScale <<NextChar>>      { ttk::scale::Increment %W 1 }
bind TScale <<NextLine>>      { ttk::scale::Increment %W 1 }
bind TScale <<PrevWord>>      { ttk::scale::Increment %W -10 }
bind TScale <<PrevPara>>      { ttk::scale::Increment %W -10 }
bind TScale <<NextWord>>      { ttk::scale::Increment %W 10 }
bind TScale <<NextPara>>      { ttk::scale::Increment %W 10 }



proc ttk::scale::Press {w x y} {
    variable State
    set State(dragging) 0

    switch -glob -- [$w identify $x $y] {
	*track -
        *trough {
            set inc [expr {([$w get $x $y] <= [$w get]) ^ ([$w cget -from] > [$w cget -to]) ? -1 : 1}]
            ttk::Repeatedly Increment $w $inc
        }
        *slider {
            set State(dragging) 1
            set State(initial) [$w get]
        }
    }
}

# scale::Jump -- Button-2/3 binding for scale acts like
#	Press except that clicking in the trough jumps to the
#	clicked position.
proc ttk::scale::Jump {w x y} {
    variable State
    set State(dragging) 0

    switch -glob -- [$w identify $x $y] {











|



|



|



<
<
<
<
<
|
|
|
|
|
|
|
|
>
>


















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23





24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# scale.tcl - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
#
# Bindings for the TScale widget

namespace eval ttk::scale {
    variable State
    array set State  {
	dragging 0
    }
}

bind TScale <ButtonPress-1>   { ttk::scale::Press %W %x %y }
bind TScale <B1-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-1> { ttk::scale::Release %W %x %y }

bind TScale <ButtonPress-2>   { ttk::scale::Jump %W %x %y }
bind TScale <B2-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-2> { ttk::scale::Release %W %x %y }

bind TScale <ButtonPress-3>   { ttk::scale::Jump %W %x %y }
bind TScale <B3-Motion>       { ttk::scale::Drag %W %x %y }
bind TScale <ButtonRelease-3> { ttk::scale::Release %W %x %y }






bind TScale <Left>            { ttk::scale::Increment %W -1 }
bind TScale <Up>              { ttk::scale::Increment %W -1 }
bind TScale <Right>           { ttk::scale::Increment %W 1 }
bind TScale <Down>            { ttk::scale::Increment %W 1 }
bind TScale <Control-Left>    { ttk::scale::Increment %W -10 }
bind TScale <Control-Up>      { ttk::scale::Increment %W -10 }
bind TScale <Control-Right>   { ttk::scale::Increment %W 10 }
bind TScale <Control-Down>    { ttk::scale::Increment %W 10 }
bind TScale <Home>            { %W set [%W cget -from] }
bind TScale <End>             { %W set [%W cget -to] }

proc ttk::scale::Press {w x y} {
    variable State
    set State(dragging) 0

    switch -glob -- [$w identify $x $y] {
	*track -
        *trough {
            set inc [expr {([$w get $x $y] <= [$w get]) ^ ([$w cget -from] > [$w cget -to]) ? -1 : 1}]
            ttk::Repeatedly Increment $w $inc
        }
        *slider {
            set State(dragging) 1
            set State(initial) [$w get]
        }
    }
}

# scale::Jump -- ButtonPress-2/3 binding for scale acts like
#	Press except that clicking in the trough jumps to the
#	clicked position.
proc ttk::scale::Jump {w x y} {
    variable State
    set State(dragging) 0

    switch -glob -- [$w identify $x $y] {

Changes to library/ttk/scrollbar.tcl.

1
2
3


















4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#
# Bindings for TScrollbar widget
#



















namespace eval ttk::scrollbar {
    variable State
    # State(xPress)	--
    # State(yPress)	-- initial position of mouse at start of drag.
    # State(first)	-- value of -first at start of drag.
}

bind TScrollbar <Button-1> 		{ ttk::scrollbar::Press %W %x %y }
bind TScrollbar <B1-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-1>	{ ttk::scrollbar::Release %W %x %y }

bind TScrollbar <Button-2> 		{ ttk::scrollbar::Jump %W %x %y }
bind TScrollbar <B2-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-2>	{ ttk::scrollbar::Release %W %x %y }

# Redirect scrollwheel bindings to the scrollbar widget
#
bind TScrollbar <MouseWheel> [bind Scrollbar <MouseWheel>]
bind TScrollbar <Option-MouseWheel> [bind Scrollbar <Option-MouseWheel>]

proc ttk::scrollbar::Scroll {w n units} {
    set cmd [$w cget -command]
    if {$cmd ne ""} {
	uplevel #0 $cmd scroll $n $units
    }
}




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|



|



<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37





38
39
40
41
42
43
44
#
# Bindings for TScrollbar widget
#

# Still don't have a working ttk::scrollbar under OSX -
# Swap in a [tk::scrollbar] on that platform,
# unless user specifies -class or -style.
#
if {[tk windowingsystem] eq "aqua"} {
    rename ::ttk::scrollbar ::ttk::_scrollbar
    proc ttk::scrollbar {w args} {
	set constructor ::tk::scrollbar
	foreach {option _} $args {
	    if {$option eq "-class" || $option eq "-style"} {
		set constructor ::ttk::_scrollbar
		break
	    }
	}
	return [$constructor $w {*}$args]
    }
}

namespace eval ttk::scrollbar {
    variable State
    # State(xPress)	--
    # State(yPress)	-- initial position of mouse at start of drag.
    # State(first)	-- value of -first at start of drag.
}

bind TScrollbar <ButtonPress-1> 	{ ttk::scrollbar::Press %W %x %y }
bind TScrollbar <B1-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-1>	{ ttk::scrollbar::Release %W %x %y }

bind TScrollbar <ButtonPress-2> 	{ ttk::scrollbar::Jump %W %x %y }
bind TScrollbar <B2-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-2>	{ ttk::scrollbar::Release %W %x %y }






proc ttk::scrollbar::Scroll {w n units} {
    set cmd [$w cget -command]
    if {$cmd ne ""} {
	uplevel #0 $cmd scroll $n $units
    }
}

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
proc ttk::scrollbar::Press {w x y} {
    variable State

    set State(xPress) $x
    set State(yPress) $y

    switch -glob -- [$w identify $x $y] {
	*uparrow -
	*leftarrow {
	    ttk::Repeatedly Scroll $w -1 units
	}
	*downarrow -
	*rightarrow {
	    ttk::Repeatedly Scroll $w  1 units
	}
	*grip -
	*thumb {
	    set State(first) [lindex [$w get] 0]
	}
	*trough {
	    set f [$w fraction $x $y]
	    if {$f < [lindex [$w get] 0]} {
		# Clicked in upper/left trough







|







<







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
proc ttk::scrollbar::Press {w x y} {
    variable State

    set State(xPress) $x
    set State(yPress) $y

    switch -glob -- [$w identify $x $y] {
    	*uparrow -
	*leftarrow {
	    ttk::Repeatedly Scroll $w -1 units
	}
	*downarrow -
	*rightarrow {
	    ttk::Repeatedly Scroll $w  1 units
	}

	*thumb {
	    set State(first) [lindex [$w get] 0]
	}
	*trough {
	    set f [$w fraction $x $y]
	    if {$f < [lindex [$w get] 0]} {
		# Clicked in upper/left trough
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	}
    }
}

proc ttk::scrollbar::Drag {w x y} {
    variable State
    if {![info exists State(first)]} {
    	# Initial buttonpress was not on the thumb,
	# or something screwy has happened.  In either case, ignore:
	return;
    }
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}

proc ttk::scrollbar::Release {w x y} {
    variable State
    unset -nocomplain State(xPress) State(yPress) State(first)
    ttk::CancelRepeat
}

# scrollbar::Jump -- Button-2 binding for scrollbars.
# 	Behaves exactly like scrollbar::Press, except that
#	clicking in the trough jumps to the the selected position.
#
proc ttk::scrollbar::Jump {w x y} {
    variable State

    switch -glob -- [$w identify $x $y] {
	*grip -
	*thumb -
	*trough {
	    set State(first) [$w fraction $x $y]
	    Moveto $w $State(first)
	    set State(xPress) $x
	    set State(yPress) $y
	}
	default {
	    Press $w $x $y
	}
    }
}







|














|







<












82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
	}
    }
}

proc ttk::scrollbar::Drag {w x y} {
    variable State
    if {![info exists State(first)]} {
    	# Initial buttonpress was not on the thumb, 
	# or something screwy has happened.  In either case, ignore:
	return;
    }
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}

proc ttk::scrollbar::Release {w x y} {
    variable State
    unset -nocomplain State(xPress) State(yPress) State(first)
    ttk::CancelRepeat
}

# scrollbar::Jump -- ButtonPress-2 binding for scrollbars.
# 	Behaves exactly like scrollbar::Press, except that
#	clicking in the trough jumps to the the selected position.
#
proc ttk::scrollbar::Jump {w x y} {
    variable State

    switch -glob -- [$w identify $x $y] {

	*thumb -
	*trough {
	    set State(first) [$w fraction $x $y]
	    Moveto $w $State(first)
	    set State(xPress) $x
	    set State(yPress) $y
	}
	default {
	    Press $w $x $y
	}
    }
}

Changes to library/ttk/sizegrip.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# Sizegrip widget bindings.
#
# Dragging a sizegrip widget resizes the containing toplevel.
#
# NOTE: the sizegrip widget must be in the lower right hand corner.
#

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault
    }
    aqua {
    	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# Sizegrip widget bindings.
#
# Dragging a sizegrip widget resizes the containing toplevel.
#
# NOTE: the sizegrip widget must be in the lower right hand corner.
#

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize]
    }
    aqua {
    	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
	heightInc	1
        resizeX         1
        resizeY         1
	toplevel 	{}
    }
}

bind TSizegrip <Button-1> 		{ ttk::sizegrip::Press	%W %X %Y }
bind TSizegrip <B1-Motion> 		{ ttk::sizegrip::Drag 	%W %X %Y }
bind TSizegrip <ButtonRelease-1> 	{ ttk::sizegrip::Release %W %X %Y }

proc ttk::sizegrip::Press {W X Y} {
    variable State

    if {[$W instate disabled]} { return }







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
	heightInc	1
        resizeX         1
        resizeY         1
	toplevel 	{}
    }
}

bind TSizegrip <ButtonPress-1> 		{ ttk::sizegrip::Press	%W %X %Y }
bind TSizegrip <B1-Motion> 		{ ttk::sizegrip::Drag 	%W %X %Y }
bind TSizegrip <ButtonRelease-1> 	{ ttk::sizegrip::Release %W %X %Y }

proc ttk::sizegrip::Press {W X Y} {
    variable State

    if {[$W instate disabled]} { return }

Changes to library/ttk/spinbox.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#
# Duplicate the Entry bindings, override if needed:
#

ttk::copyBindings TEntry TSpinbox

bind TSpinbox <Motion>			{ ttk::spinbox::Motion %W %x %y }
bind TSpinbox <Button-1> 		{ ttk::spinbox::Press %W %x %y }
bind TSpinbox <ButtonRelease-1> 	{ ttk::spinbox::Release %W }
bind TSpinbox <Double-Button-1> 	{ ttk::spinbox::DoubleClick %W %x %y }
bind TSpinbox <Triple-Button-1> 	{} ;# disable TEntry triple-click

bind TSpinbox <Up>			{ event generate %W <<Increment>> }
bind TSpinbox <Down> 			{ event generate %W <<Decrement>> }

bind TSpinbox <<Increment>>		{ ttk::spinbox::Spin %W +1 }
bind TSpinbox <<Decrement>> 		{ ttk::spinbox::Spin %W -1 }

ttk::bindMouseWheel TSpinbox 		[list ttk::spinbox::MouseWheel %W]

## Motion --
#	Sets cursor.
#
proc ttk::spinbox::Motion {w x y} {
    variable State
    ttk::saveCursor $w State(userConfCursor) [ttk::cursor text]
    if {   [$w identify $x $y] eq "textarea"
	&& [$w instate {!readonly !disabled}]
    } {
	ttk::setCursor $w text
    } else {
	ttk::setCursor $w $State(userConfCursor)
    }
}

## Press --
#
proc ttk::spinbox::Press {w x y} {
    if {[$w instate disabled]} { return }
    focus $w
    switch -glob -- [$w identify $x $y] {
	*textarea	{ ttk::entry::Press $w $x }
	*rightarrow	-
	*uparrow 	{ ttk::Repeatedly event generate $w <<Increment>> }
	*leftarrow	-
	*downarrow	{ ttk::Repeatedly event generate $w <<Decrement>> }
	*spinbutton {
	    if {$y * 2 >= [winfo height $w]} {
		set event <<Decrement>>
	    } else {
		set event <<Increment>>
	    }
	    ttk::Repeatedly event generate $w $event
	}
    }
}

## DoubleClick --
#	Select all if over the text area; otherwise same as Press.
#
proc ttk::spinbox::DoubleClick {w x y} {
    if {[$w instate disabled]} { return }

    switch -glob -- [$w identify $x $y] {
	*textarea	{ SelectAll $w }
	*		{ Press $w $x $y }
    }
}

proc ttk::spinbox::Release {w} {
    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events.
#
proc ttk::spinbox::MouseWheel {w dir {factor 1}} {
    if {[$w instate disabled]} { return }
    if {($dir < 0) ^ ($factor < 0)} {
	event generate $w <<Increment>>
    } elseif {$dir > 0} {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#







|




|
|










<
<

|



|









|

|

|


|

|













|












|
<
|

|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
#
# Duplicate the Entry bindings, override if needed:
#

ttk::copyBindings TEntry TSpinbox

bind TSpinbox <Motion>			{ ttk::spinbox::Motion %W %x %y }
bind TSpinbox <ButtonPress-1> 		{ ttk::spinbox::Press %W %x %y }
bind TSpinbox <ButtonRelease-1> 	{ ttk::spinbox::Release %W }
bind TSpinbox <Double-Button-1> 	{ ttk::spinbox::DoubleClick %W %x %y }
bind TSpinbox <Triple-Button-1> 	{} ;# disable TEntry triple-click

bind TSpinbox <KeyPress-Up>		{ event generate %W <<Increment>> }
bind TSpinbox <KeyPress-Down> 		{ event generate %W <<Decrement>> }

bind TSpinbox <<Increment>>		{ ttk::spinbox::Spin %W +1 }
bind TSpinbox <<Decrement>> 		{ ttk::spinbox::Spin %W -1 }

ttk::bindMouseWheel TSpinbox 		[list ttk::spinbox::MouseWheel %W]

## Motion --
#	Sets cursor.
#
proc ttk::spinbox::Motion {w x y} {


    if {   [$w identify $x $y] eq "textarea"
        && [$w instate {!readonly !disabled}]
    } {
	ttk::setCursor $w text
    } else {
	ttk::setCursor $w ""
    }
}

## Press --
#
proc ttk::spinbox::Press {w x y} {
    if {[$w instate disabled]} { return }
    focus $w
    switch -glob -- [$w identify $x $y] {
        *textarea	{ ttk::entry::Press $w $x }
	*rightarrow	-
        *uparrow 	{ ttk::Repeatedly event generate $w <<Increment>> }
	*leftarrow	-
        *downarrow	{ ttk::Repeatedly event generate $w <<Decrement>> }
	*spinbutton {
	    if {$y * 2 >= [winfo height $w]} {
	    	set event <<Decrement>>
	    } else {
	    	set event <<Increment>>
	    }
	    ttk::Repeatedly event generate $w $event
	}
    }
}

## DoubleClick --
#	Select all if over the text area; otherwise same as Press.
#
proc ttk::spinbox::DoubleClick {w x y} {
    if {[$w instate disabled]} { return }

    switch -glob -- [$w identify $x $y] {
        *textarea	{ SelectAll $w }
	*		{ Press $w $x $y }
    }
}

proc ttk::spinbox::Release {w} {
    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events.
#
proc ttk::spinbox::MouseWheel {w dir} {

    if {$dir < 0} {
	event generate $w <<Increment>>
    } else {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
## Spin --
#	Handle <<Increment>> and <<Decrement>> events.
#	If -values is specified, cycle through the list.
#	Otherwise cycle through numeric range based on
#	-from, -to, and -increment.
#
proc ttk::spinbox::Spin {w dir} {
    variable State

    if {[$w instate disabled]} { return }

    if {![info exists State($w,values.length)]} {
	set State($w,values.index) -1
	set State($w,values.last) {}
    }
    set State($w,values) [$w cget -values]
    set State($w,values.length) [llength $State($w,values)]

    if {$State($w,values.length) > 0} {
	set value [$w get]
	set current $State($w,values.index)
	if {$value ne $State($w,values.last)} {
	    set current [lsearch -exact $State($w,values) $value]
	    if {$current < 0} {set current -1}
	}
	set State($w,values.index) [Adjust $w [expr {$current + $dir}] 0 \
		[expr {$State($w,values.length) - 1}]]
	set State($w,values.last) [lindex $State($w,values) $State($w,values.index)]
	$w set $State($w,values.last)
    } else {
	if {[catch {
	    set v [expr {[scan [$w get] %f] + $dir * [$w cget -increment]}]
	}]} {
	    set v [$w cget -from]
	}
	$w set [FormatValue $w [Adjust $w $v [$w cget -from] [$w cget -to]]]
    }
    SelectAll $w
    uplevel #0 [$w cget -command]
}

## FormatValue --
#	Reformat numeric value based on -format.
#
proc ttk::spinbox::FormatValue {w val} {
    set fmt [$w cget -format]
    if {$fmt eq ""} {
	# Try to guess a suitable -format based on -increment.
	set delta [expr {abs([$w cget -increment])}]
	if {0 < $delta && $delta < 1} {
	    # NB: This guesses wrong if -increment has more than 1
	    # significant digit itself, e.g., -increment 0.25
	    set nsd [expr {int(ceil(-log10($delta)))}]
	    set fmt "%.${nsd}f"
	} else {
	    set fmt "%.0f"
	}
    }
    return [format $fmt $val]
}

#*EOF*







<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
|
<
<
|
<
<
|

|
|

















|












128
129
130
131
132
133
134








135



136
137

138


139


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
## Spin --
#	Handle <<Increment>> and <<Decrement>> events.
#	If -values is specified, cycle through the list.
#	Otherwise cycle through numeric range based on
#	-from, -to, and -increment.
#
proc ttk::spinbox::Spin {w dir} {








    set nvalues [llength [set values [$w cget -values]]]



    set value [$w get]
    if {$nvalues} {

	set current [lsearch -exact $values $value]


	set index [Adjust $w [expr {$current + $dir}] 0 [expr {$nvalues - 1}]]


	$w set [lindex $values $index]
    } else {
        if {[catch {
    	    set v [expr {[scan [$w get] %f] + $dir * [$w cget -increment]}]
	}]} {
	    set v [$w cget -from]
	}
	$w set [FormatValue $w [Adjust $w $v [$w cget -from] [$w cget -to]]]
    }
    SelectAll $w
    uplevel #0 [$w cget -command]
}

## FormatValue --
#	Reformat numeric value based on -format.
#
proc ttk::spinbox::FormatValue {w val} {
    set fmt [$w cget -format]
    if {$fmt eq ""} {
	# Try to guess a suitable -format based on -increment.
	set delta [expr {abs([$w cget -increment])}]
        if {0 < $delta && $delta < 1} {
	    # NB: This guesses wrong if -increment has more than 1
	    # significant digit itself, e.g., -increment 0.25
	    set nsd [expr {int(ceil(-log10($delta)))}]
	    set fmt "%.${nsd}f"
	} else {
	    set fmt "%.0f"
	}
    }
    return [format $fmt $val]
}

#*EOF*

Changes to library/ttk/treeview.tcl.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

### Widget bindings.
#

bind Treeview	<Motion> 		{ ttk::treeview::Motion %W %x %y }
bind Treeview	<B1-Leave>		{ #nothing }
bind Treeview	<Leave>			{ ttk::treeview::ActivateHeading {} {}}
bind Treeview	<Button-1> 		{ ttk::treeview::Press %W %x %y }
bind Treeview	<Double-Button-1> 	{ ttk::treeview::DoubleClick %W %x %y }
bind Treeview	<ButtonRelease-1> 	{ ttk::treeview::Release %W %x %y }
bind Treeview	<B1-Motion> 		{ ttk::treeview::Drag %W %x %y }
bind Treeview 	<Up>    		{ ttk::treeview::Keynav %W up }
bind Treeview 	<Down>  		{ ttk::treeview::Keynav %W down }
bind Treeview 	<Right> 		{ ttk::treeview::Keynav %W right }
bind Treeview 	<Left>  		{ ttk::treeview::Keynav %W left }
bind Treeview	<Prior>			{ %W yview scroll -1 pages }
bind Treeview	<Next> 			{ %W yview scroll  1 pages }
bind Treeview	<Return>		{ ttk::treeview::ToggleFocus %W }
bind Treeview	<space>			{ ttk::treeview::ToggleFocus %W }

bind Treeview	<Shift-Button-1> \
		{ ttk::treeview::Select %W %x %y extend }
bind Treeview	<<ToggleSelection>> \
		{ ttk::treeview::Select %W %x %y toggle }

ttk::copyBindings TtkScrollable Treeview

### Binding procedures.
#

## Keynav -- Keyboard navigation
#
# @@@ TODO: verify/rewrite up and down code.







|
|


|
|
|
|
|
|
|
|

|

|


|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

### Widget bindings.
#

bind Treeview	<Motion> 		{ ttk::treeview::Motion %W %x %y }
bind Treeview	<B1-Leave>		{ #nothing }
bind Treeview	<Leave>			{ ttk::treeview::ActivateHeading {} {}}
bind Treeview	<ButtonPress-1> 	{ ttk::treeview::Press %W %x %y }
bind Treeview	<Double-ButtonPress-1> 	{ ttk::treeview::DoubleClick %W %x %y }
bind Treeview	<ButtonRelease-1> 	{ ttk::treeview::Release %W %x %y }
bind Treeview	<B1-Motion> 		{ ttk::treeview::Drag %W %x %y }
bind Treeview 	<KeyPress-Up>    	{ ttk::treeview::Keynav %W up }
bind Treeview 	<KeyPress-Down>  	{ ttk::treeview::Keynav %W down }
bind Treeview 	<KeyPress-Right> 	{ ttk::treeview::Keynav %W right }
bind Treeview 	<KeyPress-Left>  	{ ttk::treeview::Keynav %W left }
bind Treeview	<KeyPress-Prior>	{ %W yview scroll -1 pages }
bind Treeview	<KeyPress-Next> 	{ %W yview scroll  1 pages }
bind Treeview	<KeyPress-Return>	{ ttk::treeview::ToggleFocus %W }
bind Treeview	<KeyPress-space>	{ ttk::treeview::ToggleFocus %W }

bind Treeview	<Shift-ButtonPress-1> \
		{ ttk::treeview::Select %W %x %y extend }
bind Treeview	<Control-ButtonPress-1> \
		{ ttk::treeview::Select %W %x %y toggle }

ttk::copyBindings TtkScrollable Treeview 

### Binding procedures.
#

## Keynav -- Keyboard navigation
#
# @@@ TODO: verify/rewrite up and down code.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    }
}

## Motion -- pointer motion binding.
#	Sets cursor, active element ...
#
proc ttk::treeview::Motion {w x y} {
    variable State

    ttk::saveCursor $w State(userConfCursor) [ttk::cursor hresize]

    set cursor $State(userConfCursor)
    set activeHeading {}

    switch -- [$w identify region $x $y] {
	separator { set cursor hresize }
	heading { set activeHeading [$w identify column $x $y] }
    }

    ttk::setCursor $w $cursor
    ActivateHeading $w $activeHeading
}

## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {[winfo exists $State(activeWidget)] && $State(activeHeading) != {}} {
	    # It may happen that $State(activeHeading) no longer corresponds
	    # to an existing display column. This happens for instance when
	    # changing -displaycolumns in a bound script when this change
	    # triggers a <Leave> event. A proc checking if the display column
	    # $State(activeHeading) is really still present or not could be
	    # written but it would need to check several special cases:
	    #   a. -displaycolumns "#all" or being an explicit columns list
	    #   b. column #0 display is not governed by the -displaycolumn
	    #      list but by the value of the -show option
	    # --> Let's rather catch the following line.
	    catch {$State(activeWidget) heading $State(activeHeading) state !active}
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w
    }
}

## Select $w $x $y $selectop
#	Binding procedure for selection operations.
#	See "Selection modes", below.
#
proc ttk::treeview::Select {w x y op} {
    if {[set item [$w identify row $x $y]] ne "" } {
	SelectOp $w $item $op
    }
}

## DoubleClick -- Double-Button-1 binding.
#
proc ttk::treeview::DoubleClick {w x y} {
    if {[set row [$w identify row $x $y]] ne ""} {
	Toggle $w $row
    } else {
	Press $w $x $y ;# perform single-click action
    }
}

## Press -- Button binding.
#
proc ttk::treeview::Press {w x y} {
    focus $w
    switch -- [$w identify region $x $y] {
	nothing { }
	heading { heading.press $w $x $y }
	separator { resize.press $w $x $y }







<
<
<
<
|

















|
<
<
<
<
<
<
<
<
<
<
|



















|









|







98
99
100
101
102
103
104




105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123










124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    }
}

## Motion -- pointer motion binding.
#	Sets cursor, active element ...
#
proc ttk::treeview::Motion {w x y} {




    set cursor {}
    set activeHeading {}

    switch -- [$w identify region $x $y] {
	separator { set cursor hresize }
	heading { set activeHeading [$w identify column $x $y] }
    }

    ttk::setCursor $w $cursor
    ActivateHeading $w $activeHeading
}

## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {$State(activeHeading) != {}} {










	    $State(activeWidget) heading $State(activeHeading) state !active
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w
    }
}

## Select $w $x $y $selectop
#	Binding procedure for selection operations.
#	See "Selection modes", below.
#
proc ttk::treeview::Select {w x y op} {
    if {[set item [$w identify row $x $y]] ne "" } {
	SelectOp $w $item $op
    }
}

## DoubleClick -- Double-ButtonPress-1 binding.
#
proc ttk::treeview::DoubleClick {w x y} {
    if {[set row [$w identify row $x $y]] ne ""} {
	Toggle $w $row
    } else {
	Press $w $x $y ;# perform single-click action
    }
}

## Press -- ButtonPress binding.
#
proc ttk::treeview::Press {w x y} {
    focus $w
    switch -- [$w identify region $x $y] {
	nothing { }
	heading { heading.press $w $x $y }
	separator { resize.press $w $x $y }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

proc ttk::treeview::resize.drag {w x} {
    variable State
    $w drag $State(resizeColumn) $x
}

proc ttk::treeview::resize.release {w x} {
    $w drop
}

### Heading activation.
#

proc ttk::treeview::heading.press {w x y} {
    variable State







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

proc ttk::treeview::resize.drag {w x} {
    variable State
    $w drag $State(resizeColumn) $x
}

proc ttk::treeview::resize.release {w x} {
    # no-op
}

### Heading activation.
#

proc ttk::treeview::heading.press {w x y} {
    variable State
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#
proc ttk::treeview::SelectOp {w item op} {
    select.$op.[$w cget -selectmode] $w $item
}

## -selectmode none:
#
proc ttk::treeview::select.choose.none {w item} { $w focus $item; $w see $item }
proc ttk::treeview::select.toggle.none {w item} { $w focus $item; $w see $item }
proc ttk::treeview::select.extend.none {w item} { $w focus $item; $w see $item }

## -selectmode browse:
#
proc ttk::treeview::select.choose.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.toggle.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.extend.browse {w item} { BrowseTo $w $item }








|
|
|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#
proc ttk::treeview::SelectOp {w item op} {
    select.$op.[$w cget -selectmode] $w $item
}

## -selectmode none:
#
proc ttk::treeview::select.choose.none {w item} { $w focus $item }
proc ttk::treeview::select.toggle.none {w item} { $w focus $item }
proc ttk::treeview::select.extend.none {w item} { $w focus $item }

## -selectmode browse:
#
proc ttk::treeview::select.choose.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.toggle.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.extend.browse {w item} { BrowseTo $w $item }

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
    $w focus $item
    event generate $w <<TreeviewClose>>
}

## Toggle -- toggle opened/closed state of item
#
proc ttk::treeview::Toggle {w item} {
    # don't allow toggling on indicators that
    # are not present in front of leaf items
    if {[$w children $item] == {}} {
        return
    }
    # not a leaf, toggle!
    if {[$w item $item -open]} {
	CloseItem $w $item
    } else {
	OpenItem $w $item
    }
}








<
<
<
<
<
<







332
333
334
335
336
337
338






339
340
341
342
343
344
345
    $w focus $item
    event generate $w <<TreeviewClose>>
}

## Toggle -- toggle opened/closed state of item
#
proc ttk::treeview::Toggle {w item} {






    if {[$w item $item -open]} {
	CloseItem $w $item
    } else {
	OpenItem $w $item
    }
}

Changes to library/ttk/ttk.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace eval ::ttk {
    variable library
    if {![info exists library]} {
	set library [file dirname [info script]]
    }
}

source -encoding utf-8 [file join $::ttk::library fonts.tcl]
source -encoding utf-8 [file join $::ttk::library cursors.tcl]
source -encoding utf-8 [file join $::ttk::library utils.tcl]

## ttk::deprecated $old $new --
#	Define $old command as a deprecated alias for $new command
#	$old and $new must be fully namespace-qualified.
#
proc ttk::deprecated {old new} {
    interp alias {} $old {} ttk::do'deprecate $old $new







|
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace eval ::ttk {
    variable library
    if {![info exists library]} {
	set library [file dirname [info script]]
    }
}

source [file join $::ttk::library fonts.tcl]
source [file join $::ttk::library cursors.tcl]
source [file join $::ttk::library utils.tcl]

## ttk::deprecated $old $new --
#	Define $old command as a deprecated alias for $new command
#	$old and $new must be fully namespace-qualified.
#
proc ttk::deprecated {old new} {
    interp alias {} $old {} ttk::do'deprecate $old $new
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}

### Load widget bindings.
#
source -encoding utf-8 [file join $::ttk::library button.tcl]
source -encoding utf-8 [file join $::ttk::library menubutton.tcl]
source -encoding utf-8 [file join $::ttk::library scrollbar.tcl]
source -encoding utf-8 [file join $::ttk::library scale.tcl]
source -encoding utf-8 [file join $::ttk::library progress.tcl]
source -encoding utf-8 [file join $::ttk::library notebook.tcl]
source -encoding utf-8 [file join $::ttk::library panedwindow.tcl]
source -encoding utf-8 [file join $::ttk::library entry.tcl]
source -encoding utf-8 [file join $::ttk::library combobox.tcl]	;# dependency: entry.tcl
source -encoding utf-8 [file join $::ttk::library spinbox.tcl]  ;# dependency: entry.tcl
source -encoding utf-8 [file join $::ttk::library treeview.tcl]
source -encoding utf-8 [file join $::ttk::library sizegrip.tcl]

## Label and Labelframe bindings:
#  (not enough to justify their own file...)
#
bind TLabelframe <<Invoke>>	{ tk::TabToWindow [tk_focusNext %W] }
bind TLabel <<Invoke>>		{ tk::TabToWindow [tk_focusNext %W] }

### Load settings for built-in themes:
#
proc ttk::LoadThemes {} {
    variable library

    # "default" always present:
    uplevel #0 [list source -encoding utf-8 [file join $library defaults.tcl]]

    set builtinThemes [style theme names]
    foreach {theme scripts} {
	classic 	classicTheme.tcl
	alt 		altTheme.tcl
	clam 		clamTheme.tcl
	winnative	winTheme.tcl
	xpnative	{xpTheme.tcl vistaTheme.tcl}
	aqua 		aquaTheme.tcl
    } {
	if {[lsearch -exact $builtinThemes $theme] >= 0} {
            foreach script $scripts {
                uplevel #0 [list source -encoding utf-8 [file join $library $script]]
            }
	}
    }
}

ttk::LoadThemes; rename ::ttk::LoadThemes {}








|
|
|
|
|
|
|
|
|
|
|
|













|












|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}

### Load widget bindings.
#
source [file join $::ttk::library button.tcl]
source [file join $::ttk::library menubutton.tcl]
source [file join $::ttk::library scrollbar.tcl]
source [file join $::ttk::library scale.tcl]
source [file join $::ttk::library progress.tcl]
source [file join $::ttk::library notebook.tcl]
source [file join $::ttk::library panedwindow.tcl]
source [file join $::ttk::library entry.tcl]
source [file join $::ttk::library combobox.tcl]	;# dependency: entry.tcl
source [file join $::ttk::library spinbox.tcl]  ;# dependency: entry.tcl
source [file join $::ttk::library treeview.tcl]
source [file join $::ttk::library sizegrip.tcl]

## Label and Labelframe bindings:
#  (not enough to justify their own file...)
#
bind TLabelframe <<Invoke>>	{ tk::TabToWindow [tk_focusNext %W] }
bind TLabel <<Invoke>>		{ tk::TabToWindow [tk_focusNext %W] }

### Load settings for built-in themes:
#
proc ttk::LoadThemes {} {
    variable library

    # "default" always present:
    uplevel #0 [list source [file join $library defaults.tcl]] 

    set builtinThemes [style theme names]
    foreach {theme scripts} {
	classic 	classicTheme.tcl
	alt 		altTheme.tcl
	clam 		clamTheme.tcl
	winnative	winTheme.tcl
	xpnative	{xpTheme.tcl vistaTheme.tcl}
	aqua 		aquaTheme.tcl
    } {
	if {[lsearch -exact $builtinThemes $theme] >= 0} {
            foreach script $scripts {
                uplevel #0 [list source [file join $library $script]]
            }
	}
    }
}

ttk::LoadThemes; rename ::ttk::LoadThemes {}

Changes to library/ttk/utils.tcl.

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	event generate $focus <<TraverseOut>>
    }
    focus $w
    event generate $w <<TraverseIn>>
}

## ttk::clickToFocus $w --
#	Utility routine, used in <Button-1> bindings --
#	Assign keyboard focus to the specified widget if -takefocus is enabled.
#
proc ttk::clickToFocus {w} {
    if {[ttk::takesFocus $w]} { focus $w }
}

## ttk::takesFocus w --







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	event generate $focus <<TraverseOut>>
    }
    focus $w
    event generate $w <<TraverseIn>>
}

## ttk::clickToFocus $w --
#	Utility routine, used in <ButtonPress-1> bindings --
#	Assign keyboard focus to the specified widget if -takefocus is enabled.
#
proc ttk::clickToFocus {w} {
    if {[ttk::takesFocus $w]} { focus $w }
}

## ttk::takesFocus w --
268
269
270
271
272
273
274















275
276
277
278
279
280
281
282
283
284
285
286
287






288


289


290
291
292
293
294
295
296
297
298
299








300

301



302
303
304

305

306
307
308


309
	bind $to $event [bind $from $event]
    }
}

### Mousewheel bindings.
#
# Platform inconsistencies:















#
# MouseWheel scrolling is accelerated on X11, which is conventional
# for Tk and appears to be conventional for other toolkits (although
# Gtk+ and Qt do not appear to use as large a factor).
#

## ttk::bindMouseWheel $bindtag $command...
#	Adds basic mousewheel support to $bindtag.
#	$command will be passed one additional argument
#	specifying the mousewheel direction (-1: up, +1: down).
#

proc ttk::bindMouseWheel {bindtag callback} {






    bind $bindtag <MouseWheel> [append callback { %D -120.0}]


    bind $bindtag <Option-MouseWheel> [append callback { %D -12.0}]


}

## Mousewheel bindings for standard scrollable widgets.
#
# Usage: [ttk::copyBindings TtkScrollable $bindtag]
#
# $bindtag should be for a widget that supports the
# standard scrollbar protocol.
#









bind TtkScrollable <MouseWheel> \

	{ tk::MouseWheel %W y %D }



bind TtkScrollable <Option-MouseWheel> \
	{ tk::MouseWheel %W y %D -12.0 }
bind TtkScrollable <Shift-MouseWheel> \

	{ tk::MouseWheel %W x %D }

bind TtkScrollable <Shift-Option-MouseWheel> \
	{ tk::MouseWheel %W x %D -12.0 }



#*EOF*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













>
>
>
>
>
>
|
>
>
|
>
>










>
>
>
>
>
>
>
>
|
>
|
>
>
>
|
|
|
>
|
>
|
|
|
>
>

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
	bind $to $event [bind $from $event]
    }
}

### Mousewheel bindings.
#
# Platform inconsistencies:
#
# On X11, the server typically maps the mouse wheel to Button4 and Button5.
#
# On OSX, Tk generates sensible values for the %D field in <MouseWheel> events.
#
# On Windows, %D must be scaled by a factor of 120.
# In addition, Tk redirects mousewheel events to the window with
# keyboard focus instead of sending them to the window under the pointer.
# We do not attempt to fix that here, see also TIP#171.
#
# OSX conventionally uses Shift+MouseWheel for horizontal scrolling,
# and Option+MouseWheel for accelerated scrolling.
#
# The Shift+MouseWheel behavior is not conventional on Windows or most
# X11 toolkits, but it's useful.
#
# MouseWheel scrolling is accelerated on X11, which is conventional
# for Tk and appears to be conventional for other toolkits (although
# Gtk+ and Qt do not appear to use as large a factor).
#

## ttk::bindMouseWheel $bindtag $command...
#	Adds basic mousewheel support to $bindtag.
#	$command will be passed one additional argument
#	specifying the mousewheel direction (-1: up, +1: down).
#

proc ttk::bindMouseWheel {bindtag callback} {
    switch -- [tk windowingsystem] {
	x11 {
	    bind $bindtag <ButtonPress-4> "$callback -1"
	    bind $bindtag <ButtonPress-5> "$callback +1"
	}
	win32 {
	    bind $bindtag <MouseWheel> [append callback { [expr {-(%D/120)}]}]
	}
	aqua {
	    bind $bindtag <MouseWheel> [append callback { [expr {-(%D)}]} ]
	}
    }
}

## Mousewheel bindings for standard scrollable widgets.
#
# Usage: [ttk::copyBindings TtkScrollable $bindtag]
#
# $bindtag should be for a widget that supports the
# standard scrollbar protocol.
#

switch -- [tk windowingsystem] {
    x11 {
	bind TtkScrollable <ButtonPress-4>       { %W yview scroll -5 units }
	bind TtkScrollable <ButtonPress-5>       { %W yview scroll  5 units }
	bind TtkScrollable <Shift-ButtonPress-4> { %W xview scroll -5 units }
	bind TtkScrollable <Shift-ButtonPress-5> { %W xview scroll  5 units }
    }
    win32 {
	bind TtkScrollable <MouseWheel> \
	    { %W yview scroll [expr {-(%D/120)}] units }
	bind TtkScrollable <Shift-MouseWheel> \
	    { %W xview scroll [expr {-(%D/120)}] units }
    }
    aqua {
	bind TtkScrollable <MouseWheel> \
	    { %W yview scroll [expr {-(%D)}] units }
	bind TtkScrollable <Shift-MouseWheel> \
	    { %W xview scroll [expr {-(%D)}] units }
	bind TtkScrollable <Option-MouseWheel> \
	    { %W yview scroll  [expr {-10*(%D)}] units }
	bind TtkScrollable <Shift-Option-MouseWheel> \
	    { %W xview scroll [expr {-10*(%D)}] units }
    }
}

#*EOF*

Changes to library/ttk/vistaTheme.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#
# Settings for Microsoft Windows Vista and Server 2008
#

# The Vista theme can only be defined on Windows Vista and above. The theme
# is created in C due to the need to assign a theme-enabled function for
# detecting when themeing is disabled. On systems that cannot support the
# Vista theme, there will be no such theme created and we must not
# evaluate this script.

if {"vista" ni [ttk::style theme names]} {
    return
}

namespace eval ttk::theme::vista {

    ttk::style theme settings vista {

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;






|

















<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
#
# Settings for Microsoft Windows Vista and Server 2008
#

# The Vista theme can only be defined on Windows Vista and above. The theme
# is created in C due to the need to assign a theme-enabled function for 
# detecting when themeing is disabled. On systems that cannot support the
# Vista theme, there will be no such theme created and we must not
# evaluate this script.

if {"vista" ni [ttk::style theme names]} {
    return
}

namespace eval ttk::theme::vista {

    ttk::style theme settings vista {

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \

	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground SystemButtonText

	ttk::style configure Toolbutton -padding {4 4}

        # Combobox
	ttk::style configure TCombobox -padding 2
        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}
        ttk::style element create Combobox.background vsapi \
            EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style layout TCombobox {
            Combobox.border -sticky nswe -border 0 -children {
                Combobox.rightdownarrow -side right -sticky ns
                Combobox.padding -sticky nswe -children {
                    Combobox.background -sticky nswe -children {
                        Combobox.focus -sticky nswe -children {
                            Combobox.textarea -sticky nswe
                        }
                    }
                }
            }
        }
        # Vista.Combobox droplist frame
        ttk::style element create ComboboxPopdownFrame.background vsapi\
            LISTBOX 3 {disabled 4 active 3 focus 2 {} 1}







<
|
<
|


|





|
|
|
|






|
<
|
|
<







42
43
44
45
46
47
48

49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71

72
73
74
75
76
77
78
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \

	    -background [list selected SystemHighlight] \

	    -foreground [list selected SystemHighlightText] ;

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	ttk::style configure Toolbutton -padding {4 4}

        # Combobox
	ttk::style configure TCombobox -padding 2
        ttk::style element create Combobox.field vsapi \
            COMBOBOX 2 {{} 1}
        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style layout TCombobox {
            Combobox.border -sticky nswe -border 0 -children {
                Combobox.rightdownarrow -side right -sticky ns
                Combobox.padding -expand 1 -sticky nswe -children {

                    Combobox.focus -expand 1 -sticky nswe -children {
                        Combobox.textarea -sticky nswe

                    }
                }
            }
        }
        # Vista.Combobox droplist frame
        ttk::style element create ComboboxPopdownFrame.background vsapi\
            LISTBOX 3 {disabled 4 active 3 focus 2 {} 1}
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
            -padding 1 -halfheight 1 \
            -syssize { SM_CXVSCROLL SM_CYVSCROLL }
        ttk::style layout TSpinbox {
            Spinbox.field -sticky nswe -children {
                Spinbox.background -sticky news -children {
                    Spinbox.padding -sticky news -children {
                        Spinbox.innerbg -sticky news -children {
                            Spinbox.textarea
                        }
                    }
                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;


        # SCROLLBAR elements (Vista includes a state for 'hover')
        ttk::style element create Vertical.Scrollbar.uparrow vsapi \
            SCROLLBAR 1 {disabled 4 pressed 3 active 2 hover 17 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style element create Vertical.Scrollbar.downarrow vsapi \
            SCROLLBAR 1 {disabled 8 pressed 7 active 6 hover 18 {} 5} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}







|












|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
            -padding 1 -halfheight 1 \
            -syssize { SM_CXVSCROLL SM_CYVSCROLL }
        ttk::style layout TSpinbox {
            Spinbox.field -sticky nswe -children {
                Spinbox.background -sticky news -children {
                    Spinbox.padding -sticky news -children {
                        Spinbox.innerbg -sticky news -children {
                            Spinbox.textarea -expand 1
                        }
                    }
                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

        
        # SCROLLBAR elements (Vista includes a state for 'hover')
        ttk::style element create Vertical.Scrollbar.uparrow vsapi \
            SCROLLBAR 1 {disabled 4 pressed 3 active 2 hover 17 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style element create Vertical.Scrollbar.downarrow vsapi \
            SCROLLBAR 1 {disabled 8 pressed 7 active 6 hover 18 {} 5} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

        # Progressbar
        ttk::style element create Horizontal.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Horizontal.TProgressbar {
            Horizontal.Progressbar.trough -sticky nswe -children {
                Horizontal.Progressbar.pbar -side left -sticky ns
                Horizontal.Progressbar.text -sticky nesw
            }
        }
        ttk::style element create Vertical.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Vertical.TProgressbar {
            Vertical.Progressbar.trough -sticky nswe -children {
                Vertical.Progressbar.pbar -side bottom -sticky we
            }
        }

        # Scale
        ttk::style element create Horizontal.Scale.slider vsapi \
            TRACKBAR 3 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 6 -height 12
        ttk::style layout Horizontal.TScale {
            Scale.focus -sticky nswe -children {
                Horizontal.Scale.trough -sticky nswe -children {
                    Horizontal.Scale.track -sticky we
                    Horizontal.Scale.slider -side left -sticky {}
                }
            }
        }
        ttk::style element create Vertical.Scale.slider vsapi \
            TRACKBAR 6 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 12 -height 6
        ttk::style layout Vertical.TScale {
            Scale.focus -sticky nswe -children {
                Vertical.Scale.trough -sticky nswe -children {
                    Vertical.Scale.track -sticky ns
                    Vertical.Scale.slider -side top -sticky {}
                }
            }
        }

        # Treeview
        ttk::style configure Item -padding {4 0 0 0}

        package provide ttk::theme::vista 1.0
    }
}







<









|





|
|









|
|





|


|



178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

        # Progressbar
        ttk::style element create Horizontal.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Horizontal.TProgressbar {
            Horizontal.Progressbar.trough -sticky nswe -children {
                Horizontal.Progressbar.pbar -side left -sticky ns

            }
        }
        ttk::style element create Vertical.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Vertical.TProgressbar {
            Vertical.Progressbar.trough -sticky nswe -children {
                Vertical.Progressbar.pbar -side bottom -sticky we
            }
        }
        
        # Scale
        ttk::style element create Horizontal.Scale.slider vsapi \
            TRACKBAR 3 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 6 -height 12
        ttk::style layout Horizontal.TScale {
            Scale.focus -expand 1 -sticky nswe -children {
                Horizontal.Scale.trough -expand 1 -sticky nswe -children {
                    Horizontal.Scale.track -sticky we
                    Horizontal.Scale.slider -side left -sticky {}
                }
            }
        }
        ttk::style element create Vertical.Scale.slider vsapi \
            TRACKBAR 6 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 12 -height 6
        ttk::style layout Vertical.TScale {
            Scale.focus -expand 1 -sticky nswe -children {
                Vertical.Scale.trough -expand 1 -sticky nswe -children {
                    Vertical.Scale.track -sticky ns
                    Vertical.Scale.slider -side top -sticky {}
                }
            }
        }
        
        # Treeview
        ttk::style configure Item -padding {4 0 0 0}
        
        package provide ttk::theme::vista 1.0
    }
}

Changes to library/ttk/winTheme.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
# Settings for 'winnative' theme.
#

namespace eval ttk::theme::winnative {
    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -fieldbackground SystemWindow \
	    -insertcolor SystemWindowText \
	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;













<
<







1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
#
# Settings for 'winnative' theme.
#

namespace eval ttk::theme::winnative {
    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \


	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
	ttk::style configure TNotebook.Tab -padding {3 1} -borderwidth 1
	ttk::style map TNotebook.Tab -expand [list selected {2 2 2 0}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        ttk::style configure TProgressbar \
	    -background SystemHighlight -borderwidth 0 ;
    }
}







<
|
<
|





67
68
69
70
71
72
73

74

75
76
77
78
79
80
	ttk::style configure TNotebook.Tab -padding {3 1} -borderwidth 1
	ttk::style map TNotebook.Tab -expand [list selected {2 2 2 0}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \

	    -background [list selected SystemHighlight] \

	    -foreground [list selected SystemHighlightText] ;

        ttk::style configure TProgressbar \
	    -background SystemHighlight -borderwidth 0 ;
    }
}

Changes to library/ttk/xpTheme.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







31
32
33
34
35
36
37
#
# Settings for 'xpnative' theme
#

namespace eval ttk::theme::xpnative {

    ttk::style theme settings xpnative {

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

	ttk::style configure TButton -anchor center -padding {1 1} -width -11
	ttk::style configure TRadiobutton -padding 2
	ttk::style configure TCheckbutton -padding 2
	ttk::style configure TMenubutton -padding {8 4}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]








	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	# OR: -padding {3 3 3 6}, which some apps seem to use.
	ttk::style configure TEntry -padding {2 2 2 4}
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \













<
















>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
# Settings for 'xpnative' theme
#

namespace eval ttk::theme::xpnative {

    ttk::style theme settings xpnative {

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \

	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

	ttk::style configure TButton -anchor center -padding {1 1} -width -11
	ttk::style configure TRadiobutton -padding 2
	ttk::style configure TCheckbutton -padding 2
	ttk::style configure TMenubutton -padding {8 4}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \
	    -background [list selected SystemHighlight] \
	    -foreground [list selected SystemHighlightText] ;

	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	# OR: -padding {3 3 3 6}, which some apps seem to use.
	ttk::style configure TEntry -padding {2 2 2 4}
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

	ttk::style configure Toolbutton -padding {4 4}

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview -background SystemWindow
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText];
    }
}







<
<
<
<
<
<
<
<


57
58
59
60
61
62
63








64
65
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

	ttk::style configure Toolbutton -padding {4 4}









    }
}

Changes to library/unsupported.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ----------------------------------------------------------------------

namespace eval ::tk::unsupported {

    # Map from the old global names of Tk private commands to their
    # new namespace-encapsulated names.

    variable PrivateCommands
    array set PrivateCommands {
	tkButtonAutoInvoke		::tk::ButtonAutoInvoke
	tkButtonDown			::tk::ButtonDown
	tkButtonEnter			::tk::ButtonEnter
	tkButtonInvoke			::tk::ButtonInvoke
	tkButtonLeave			::tk::ButtonLeave
	tkButtonUp			::tk::ButtonUp







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ----------------------------------------------------------------------

namespace eval ::tk::unsupported {

    # Map from the old global names of Tk private commands to their
    # new namespace-encapsulated names.

    variable PrivateCommands 
    array set PrivateCommands {
	tkButtonAutoInvoke		::tk::ButtonAutoInvoke
	tkButtonDown			::tk::ButtonDown
	tkButtonEnter			::tk::ButtonEnter
	tkButtonInvoke			::tk::ButtonInvoke
	tkButtonLeave			::tk::ButtonLeave
	tkButtonUp			::tk::ButtonUp
82
83
84
85
86
87
88




























89
90
91
92
93
94
95
	tkFocusGroup_Create		::tk::FocusGroup_Create
	tkFocusGroup_Destroy		::tk::FocusGroup_Destroy
	tkFocusGroup_In			::tk::FocusGroup_In
	tkFocusGroup_Out		::tk::FocusGroup_Out
	tkFocusOK			::tk::FocusOK
	tkGenerateMenuSelect		::tk::GenerateMenuSelect
	tkIconList			::tk::IconList




























	tkListbox			::tk::Listbox
	tkListboxAutoScan		::tk::ListboxAutoScan
	tkListboxBeginExtend		::tk::ListboxBeginExtend
	tkListboxBeginSelect		::tk::ListboxBeginSelect
	tkListboxBeginToggle		::tk::ListboxBeginToggle
	tkListboxCancel			::tk::ListboxCancel
	tkListboxDataExtend		::tk::ListboxDataExtend







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	tkFocusGroup_Create		::tk::FocusGroup_Create
	tkFocusGroup_Destroy		::tk::FocusGroup_Destroy
	tkFocusGroup_In			::tk::FocusGroup_In
	tkFocusGroup_Out		::tk::FocusGroup_Out
	tkFocusOK			::tk::FocusOK
	tkGenerateMenuSelect		::tk::GenerateMenuSelect
	tkIconList			::tk::IconList
	tkIconList_Add			::tk::IconList_Add
	tkIconList_Arrange		::tk::IconList_Arrange
	tkIconList_AutoScan		::tk::IconList_AutoScan
	tkIconList_Btn1			::tk::IconList_Btn1
	tkIconList_Config		::tk::IconList_Config
	tkIconList_Create		::tk::IconList_Create
	tkIconList_CtrlBtn1		::tk::IconList_CtrlBtn1
	tkIconList_Curselection		::tk::IconList_CurSelection
	tkIconList_DeleteAll		::tk::IconList_DeleteAll
	tkIconList_Double1		::tk::IconList_Double1
	tkIconList_DrawSelection	::tk::IconList_DrawSelection
	tkIconList_FocusIn		::tk::IconList_FocusIn
	tkIconList_FocusOut		::tk::IconList_FocusOut
	tkIconList_Get			::tk::IconList_Get
	tkIconList_Goto			::tk::IconList_Goto
	tkIconList_Index		::tk::IconList_Index
	tkIconList_Invoke		::tk::IconList_Invoke
	tkIconList_KeyPress		::tk::IconList_KeyPress
	tkIconList_Leave1		::tk::IconList_Leave1
	tkIconList_LeftRight		::tk::IconList_LeftRight
	tkIconList_Motion1		::tk::IconList_Motion1
	tkIconList_Reset		::tk::IconList_Reset
	tkIconList_ReturnKey		::tk::IconList_ReturnKey
	tkIconList_See			::tk::IconList_See
	tkIconList_Select		::tk::IconList_Select
	tkIconList_Selection		::tk::IconList_Selection
	tkIconList_ShiftBtn1		::tk::IconList_ShiftBtn1
	tkIconList_UpDown		::tk::IconList_UpDown
	tkListbox			::tk::Listbox
	tkListboxAutoScan		::tk::ListboxAutoScan
	tkListboxBeginExtend		::tk::ListboxBeginExtend
	tkListboxBeginSelect		::tk::ListboxBeginSelect
	tkListboxBeginToggle		::tk::ListboxBeginToggle
	tkListboxCancel			::tk::ListboxCancel
	tkListboxDataExtend		::tk::ListboxDataExtend
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#	The old command name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateCommand {cmd} {
    variable PrivateCommands
    set cmds [array get PrivateCommands $cmd]
    if {[llength $cmds] == 0} {
	return -code error -errorcode {TK EXPOSE_PRIVATE_COMMAND} \
	    "No compatibility support for \[$cmd]"
    }
    foreach {old new} $cmds {
	namespace eval :: [list interp alias {} $old {}] $new
    }
}

# ::tk::unsupported::ExposePrivateVariable --







<
|







255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
#	The old command name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateCommand {cmd} {
    variable PrivateCommands
    set cmds [array get PrivateCommands $cmd]
    if {[llength $cmds] == 0} {

	return -code error "No compatibility support for \[$cmd]"
    }
    foreach {old new} $cmds {
	namespace eval :: [list interp alias {} $old {}] $new
    }
}

# ::tk::unsupported::ExposePrivateVariable --
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#	The old variable name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateVariable {var} {
    variable PrivateVariables
    set vars [array get PrivateVariables $var]
    if {[llength $vars] == 0} {
	return -code error -errorcode {TK EXPOSE_PRIVATE_VARIABLE} \
	    "No compatibility support for \$$var"
    }
    namespace eval ::tk::mac {}
    foreach {old new} $vars {
	namespace eval :: [list upvar "#0" $new $old]
    }
}







<
|






282
283
284
285
286
287
288

289
290
291
292
293
294
295
#	The old variable name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateVariable {var} {
    variable PrivateVariables
    set vars [array get PrivateVariables $var]
    if {[llength $vars] == 0} {

	return -code error "No compatibility support for \$$var"
    }
    namespace eval ::tk::mac {}
    foreach {old new} $vars {
	namespace eval :: [list upvar "#0" $new $old]
    }
}

Changes to library/xmfbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# xmfbox.tcl --
#
#	Implements the "Motif" style file selection dialog for the
#	Unix platform. This implementation is used only if the
#	"::tk_strictMotif" flag is set.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Scriptics Corporation
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}







|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# xmfbox.tcl --
#
#	Implements the "Motif" style file selection dialog for the
#	Unix platform. This implementation is used only if the
#	"::tk_strictMotif" flag is set.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Scriptics Corporation
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#	type		"open" or "save"
#	args		Options parsed by the procedure.
#
# Results:
#	When -multiple is set to 0, this returns the absolute pathname
#	of the selected file. (NOTE: This is not the same as a single
#	element list.)
#
#	When -multiple is set to > 0, this returns a Tcl list of absolute
#       pathnames. The argument for -multiple is ignored, but for consistency
#       with Windows it defines the maximum amount of memory to allocate for
#       the returned filenames.

proc ::tk::MotifFDialog {type args} {
    variable ::tk::Priv







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#	type		"open" or "save"
#	args		Options parsed by the procedure.
#
# Results:
#	When -multiple is set to 0, this returns the absolute pathname
#	of the selected file. (NOTE: This is not the same as a single
#	element list.)
# 
#	When -multiple is set to > 0, this returns a Tcl list of absolute
#       pathnames. The argument for -multiple is ignored, but for consistency
#       with Windows it defines the maximum amount of memory to allocate for
#       the returned filenames.

proc ::tk::MotifFDialog {type args} {
    variable ::tk::Priv
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
	set data(filter) *
	return
    }

    # The filetypes radiobuttons
    # set data(fileType) $data(-defaulttype)
    # Default type to first entry
    set initialTypeName [lindex $data(origfiletypes) 0 0]
    if {$data(-typevariable) ne ""} {
	upvar #0 $data(-typevariable) typeVariable
	if {[info exists typeVariable]} {
	    set initialTypeName $typeVariable
	}
    }
    set ix 0
    set data(fileType) 0
    foreach fltr $data(origfiletypes) {
	set fname [lindex $fltr 0]
	if {[string first $initialTypeName $fname] == 0} {
	    set data(fileType) $ix
	    break
	}
	incr ix
    }

    MotifFDialog_SetFilter $w [lindex $data(-filetypes) $data(fileType)]

    #don't produce radiobuttons for only one filetype
    if {[llength $data(-filetypes)] == 1} {
	return
    }

    frame $f
    set cnt 0
    if {$data(-filetypes) ne {}} {
	foreach type $data(-filetypes) {
	    set title  [lindex $type 0]
	    set filter [lindex $type 1]
	    radiobutton $f.b$cnt \
		-text $title \
		-variable ::tk::dialog::file::[winfo name $w](fileType) \
		-value $cnt \
		-command [list tk::MotifFDialog_SetFilter $w $type]
	    pack $f.b$cnt -side left







|


|





|



















|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
	set data(filter) *
	return
    }

    # The filetypes radiobuttons
    # set data(fileType) $data(-defaulttype)
    # Default type to first entry
    set initialTypeName [lindex $data(-filetypes) 0 0]
    if {$data(-typevariable) ne ""} {
	upvar #0 $data(-typevariable) typeVariable
	if {[info exist typeVariable]} {
	    set initialTypeName $typeVariable
	}
    }
    set ix 0
    set data(fileType) 0
    foreach fltr $data(-filetypes) {
	set fname [lindex $fltr 0]
	if {[string first $initialTypeName $fname] == 0} {
	    set data(fileType) $ix
	    break
	}
	incr ix
    }

    MotifFDialog_SetFilter $w [lindex $data(-filetypes) $data(fileType)]

    #don't produce radiobuttons for only one filetype
    if {[llength $data(-filetypes)] == 1} {
	return
    }

    frame $f
    set cnt 0
    if {$data(-filetypes) ne {}} {
	foreach type $data(-filetypes) {
	    set title  [lindex [lindex $type 0] 0]
	    set filter [lindex $type 1]
	    radiobutton $f.b$cnt \
		-text $title \
		-variable ::tk::dialog::file::[winfo name $w](fileType) \
		-value $cnt \
		-command [list tk::MotifFDialog_SetFilter $w $type]
	    pack $f.b$cnt -side left
206
207
208
209
210
211
212

213
214
215
216
217
218
219
# This proc gets called whenever data(filter) is set
#
proc ::tk::MotifFDialog_SetFilter {w type} {
    upvar ::tk::dialog::file::[winfo name $w] data
    variable ::tk::Priv

    set data(filter) [lindex $type 1]


    MotifFDialog_Update $w
}

# ::tk::MotifFDialog_Config --
#
#	Iterates over the optional arguments to determine the option







>







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# This proc gets called whenever data(filter) is set
#
proc ::tk::MotifFDialog_SetFilter {w type} {
    upvar ::tk::dialog::file::[winfo name $w] data
    variable ::tk::Priv

    set data(filter) [lindex $type 1]
    set Priv(selectFileType) [lindex [lindex $type 0] 0]

    MotifFDialog_Update $w
}

# ::tk::MotifFDialog_Config --
#
#	Iterates over the optional arguments to determine the option
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    }
    set data(selectFile) $data(-initialfile)

    # 5. Parse the -filetypes option. It is not used by the motif
    #    file dialog, but we check for validity of the value to make sure
    #    the application code also runs fine with the TK file dialog.
    #
    set data(origfiletypes) $data(-filetypes)
    set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]

    if {![info exists data(filter)]} {
	set data(filter) *
    }
    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }
}

# ::tk::MotifFDialog_BuildUI --
#
#	Builds the UI components of the Motif file dialog.
#







<






<
|







295
296
297
298
299
300
301

302
303
304
305
306
307

308
309
310
311
312
313
314
315
    }
    set data(selectFile) $data(-initialfile)

    # 5. Parse the -filetypes option. It is not used by the motif
    #    file dialog, but we check for validity of the value to make sure
    #    the application code also runs fine with the TK file dialog.
    #

    set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]

    if {![info exists data(filter)]} {
	set data(filter) *
    }
    if {![winfo exists $data(-parent)]} {

	error "bad window path name \"$data(-parent)\""
    }
}

# ::tk::MotifFDialog_BuildUI --
#
#	Builds the UI components of the Motif file dialog.
#
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
    # If the string is a relative pathname, combine it
    # with the current selectPath.

    set relative 0
    if {[file pathtype $text] eq "relative"} {
	set relative 1
    } elseif {$badTilde} {
	set relative 1
    }

    if {$relative} {
	tk_messageBox -icon warning -type ok \
		-message "\"$text\" must be an absolute pathname"

	$data(fEnt) delete 0 end







|







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    # If the string is a relative pathname, combine it
    # with the current selectPath.

    set relative 0
    if {[file pathtype $text] eq "relative"} {
	set relative 1
    } elseif {$badTilde} {
	set relative 1	
    }

    if {$relative} {
	tk_messageBox -icon warning -type ok \
		-message "\"$text\" must be an absolute pathname"

	$data(fEnt) delete 0 end
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 \
            [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
    $data(sEnt) delete 0 end
    $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(selectFile)]

    MotifFDialog_LoadFiles $w
}

# ::tk::MotifFDialog_LoadFiles --
#
#	Loads the files and directories into the two listboxes according
#	to the filter setting.







|







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 \
            [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
    $data(sEnt) delete 0 end
    $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(selectFile)]
 
    MotifFDialog_LoadFiles $w
}

# ::tk::MotifFDialog_LoadFiles --
#
#	Loads the files and directories into the two listboxes according
#	to the filter setting.
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
#	This procedure is called when the directory list is browsed
#	(clicked-over) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_BrowseDList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    focus $data(dList)
    if {[$data(dList) curselection] eq ""} {
	return







|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
#	This procedure is called when the directory list is browsed
#	(clicked-over) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_BrowseDList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    focus $data(dList)
    if {[$data(dList) curselection] eq ""} {
	return
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
#	This procedure is called when the directory list is activated
#	(double-clicked) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_ActivateDList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[$data(dList) curselection] eq ""} {
	return
    }







|







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
#	This procedure is called when the directory list is activated
#	(double-clicked) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_ActivateDList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[$data(dList) curselection] eq ""} {
	return
    }
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
#	This procedure is called when the file list is browsed
#	(clicked-over) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_BrowseFList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    focus $data(fList)
    set data(selectFile) ""
    foreach item [$data(fList) curselection] {
	lappend data(selectFile) [$data(fList) get $item]
    }
    if {[llength $data(selectFile)] == 0} {
	return
    }

    $data(dList) selection clear 0 end

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(filter)]
    $data(fEnt) xview end

    # if it's a multiple selection box, just put in the filenames
    # otherwise put in the full path as usual
    $data(sEnt) delete 0 end
    if {$data(-multiple) != 0} {
	$data(sEnt) insert 0 $data(selectFile)
    } else {
	$data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
		[lindex $data(selectFile) 0]]
    }
    $data(sEnt) xview end
}

# ::tk::MotifFDialog_ActivateFList --
#
#	This procedure is called when the file list is activated
#	(double-clicked) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_ActivateFList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[$data(fList) curselection] eq ""} {
	return
    }







|



















|
|
|



















|







715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
#	This procedure is called when the file list is browsed
#	(clicked-over) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_BrowseFList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    focus $data(fList)
    set data(selectFile) ""
    foreach item [$data(fList) curselection] {
	lappend data(selectFile) [$data(fList) get $item]
    }
    if {[llength $data(selectFile)] == 0} {
	return
    }

    $data(dList) selection clear 0 end

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(filter)]
    $data(fEnt) xview end
 
    # if it's a multiple selection box, just put in the filenames 
    # otherwise put in the full path as usual 
    $data(sEnt) delete 0 end
    if {$data(-multiple) != 0} {
	$data(sEnt) insert 0 $data(selectFile)
    } else {
	$data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
		[lindex $data(selectFile) 0]]
    }
    $data(sEnt) xview end
}

# ::tk::MotifFDialog_ActivateFList --
#
#	This procedure is called when the file list is activated
#	(double-clicked) by the user.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_ActivateFList {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    if {[$data(fList) curselection] eq ""} {
	return
    }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
#	the "filter" entry. It updates the dialog according to the
#	text inside the filter entry.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_ActivateFEnt {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set list [MotifFDialog_InterpFilter $w]
    set data(selectPath) [lindex $list 0]
    set data(filter)    [lindex $list 1]

    MotifFDialog_Update $w
}

# ::tk::MotifFDialog_ActivateSEnt --
#
#	This procedure is called when the user presses Return inside
#	the "selection" entry. It sets the ::tk::Priv(selectFilePath)
#	variable so that the vwait loop in tk::MotifFDialog will be
#	terminated.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.

proc ::tk::MotifFDialog_ActivateSEnt {w} {
    variable ::tk::Priv
    upvar ::tk::dialog::file::[winfo name $w] data

    set selectFilePath [string trim [$data(sEnt) get]]








|














|







|







783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
#	the "filter" entry. It updates the dialog according to the
#	text inside the filter entry.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_ActivateFEnt {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    set list [MotifFDialog_InterpFilter $w]
    set data(selectPath) [lindex $list 0]
    set data(filter)    [lindex $list 1]

    MotifFDialog_Update $w
}

# ::tk::MotifFDialog_ActivateSEnt --
#
#	This procedure is called when the user presses Return inside
#	the "selection" entry. It sets the ::tk::Priv(selectFilePath) 
#	variable so that the vwait loop in tk::MotifFDialog will be
#	terminated.
#
# Arguments:
# 	w		The pathname of the dialog box.
#
# Results:
#	None.	

proc ::tk::MotifFDialog_ActivateSEnt {w} {
    variable ::tk::Priv
    upvar ::tk::dialog::file::[winfo name $w] data

    set selectFilePath [string trim [$data(sEnt) get]]

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
	lappend newFileList $item
    }

    # Return selected filter
    if {[info exists data(-typevariable)] && $data(-typevariable) ne ""
	    && [info exists data(-filetypes)] && $data(-filetypes) ne ""} {
	upvar #0 $data(-typevariable) typeVariable
	set typeVariable [lindex $data(origfiletypes) $data(fileType) 0]
    }

    if {$data(-multiple) != 0} {
	set Priv(selectFilePath) $newFileList
    } else {
	set Priv(selectFilePath) [lindex $newFileList 0]
    }







|







865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
	lappend newFileList $item
    }

    # Return selected filter
    if {[info exists data(-typevariable)] && $data(-typevariable) ne ""
	    && [info exists data(-filetypes)] && $data(-filetypes) ne ""} {
	upvar #0 $data(-typevariable) typeVariable
	set typeVariable [lindex $data(-filetypes) $data(fileType) 0]
    }

    if {$data(-multiple) != 0} {
	set Priv(selectFilePath) $newFileList
    } else {
	set Priv(selectFilePath) [lindex $newFileList 0]
    }
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

    set Priv(selectFilePath) ""
    set Priv(selectFile)     ""
    set Priv(selectPath)     ""
}

proc ::tk::ListBoxKeyAccel_Set {w} {
    bind Listbox <Key> ""
    bind $w <Destroy> [list tk::ListBoxKeyAccel_Unset $w]
    bind $w <Key> [list tk::ListBoxKeyAccel_Key $w %A]
}

proc ::tk::ListBoxKeyAccel_Unset {w} {
    variable ::tk::Priv

    catch {after cancel $Priv(lbAccel,$w,afterId)}
    unset -nocomplain Priv(lbAccel,$w) Priv(lbAccel,$w,afterId)







|

|







901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

    set Priv(selectFilePath) ""
    set Priv(selectFile)     ""
    set Priv(selectPath)     ""
}

proc ::tk::ListBoxKeyAccel_Set {w} {
    bind Listbox <Any-KeyPress> ""
    bind $w <Destroy> [list tk::ListBoxKeyAccel_Unset $w]
    bind $w <Any-KeyPress> [list tk::ListBoxKeyAccel_Key $w %A]
}

proc ::tk::ListBoxKeyAccel_Unset {w} {
    variable ::tk::Priv

    catch {after cancel $Priv(lbAccel,$w,afterId)}
    unset -nocomplain Priv(lbAccel,$w) Priv(lbAccel,$w,afterId)
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
#	keystrokes.
#
# Arguments:
# 	w		The pathname of the listbox.
#	key		The key which the user just pressed.
#
# Results:
#	None.

proc ::tk::ListBoxKeyAccel_Key {w key} {
    variable ::tk::Priv

    if { $key eq "" } {
	return
    }







|







925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
#	keystrokes.
#
# Arguments:
# 	w		The pathname of the listbox.
#	key		The key which the user just pressed.
#
# Results:
#	None.	

proc ::tk::ListBoxKeyAccel_Key {w key} {
    variable ::tk::Priv

    if { $key eq "" } {
	return
    }
975
976
977
978
979
980
981
982






}

proc ::tk::ListBoxKeyAccel_Reset {w} {
    variable ::tk::Priv

    unset -nocomplain Priv(lbAccel,$w)
}















>
>
>
>
>
>
974
975
976
977
978
979
980
981
982
983
984
985
986
987
}

proc ::tk::ListBoxKeyAccel_Reset {w} {
    variable ::tk::Priv

    unset -nocomplain Priv(lbAccel,$w)
}

proc ::tk_getFileType {} {
    variable ::tk::Priv

    return $Priv(selectFileType)
}

Changes to license.terms.

1
2
3
4
5
6
7
8
9
10
11
12
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
Corporation, Apple Inc. and other parties.  The following terms apply to
all files associated with the software unless explicitly disclaimed in
individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors

|
<
|
|







1
2

3
4
5
6
7
8
9
10
11
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., and other parties.  The following

terms apply to all files associated with the software unless explicitly
disclaimed in individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors

Changes to macosx/GNUmakefile.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
SYMROOT			?= ${BUILD_DIR}/${PROJECT}
OBJROOT			?= ${SYMROOT}

EXTRA_CONFIGURE_ARGS	?=
EXTRA_MAKE_ARGS		?=

INSTALL_PATH		?= /Library/Frameworks
TCL_INSTALL_PATH	?= ${INSTALL_PATH}/Tcl.framework
APPLICATION_INSTALL_PATH ?= /Applications/Utilities
PREFIX			?= /usr/local
BINDIR			?= ${PREFIX}/bin
LIBDIR			?= ${INSTALL_PATH}
MANDIR			?= ${PREFIX}/man

# tcl build directory (containing tclConfig.sh and Makefile)
TCL_BUILD_DIR		?= ${BUILD_DIR}/tcl/${BUILD_STYLE}
# location of installed tcl, only used if tcl in TCL_BUILD_DIR can't be found
TCL_FRAMEWORK_DIR	?= /Library/Frameworks
TCLSH_DIR		?= ${PREFIX}/bin

# set to non-empty value to install manpages in addition to html help:
INSTALL_MANPAGES	?=

# set to non-empty value to build TkX11 instead of TkAqua:
TK_X11			?=

# Checks and overrides for subframework builds
ifeq (${SUBFRAMEWORK}_${TK_X11},1_)
ifeq (${DYLIB_INSTALL_DIR},)
	@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
endif
ifeq (${DESTDIR},)
	@echo "Cannot install subframework with empty DESTDIR !" && false
endif
override BUILD_DIR = ${DESTDIR}/build
override INSTALL_PATH = /Frameworks
endif

#-------------------------------------------------------------------------------------------------------
# meta targets

meta			:= all install embedded install-embedded clean distclean test

styles			:= develop deploy








<


















<
<
<
<
<
<
<
<
<
<
<
<







21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45












46
47
48
49
50
51
52
SYMROOT			?= ${BUILD_DIR}/${PROJECT}
OBJROOT			?= ${SYMROOT}

EXTRA_CONFIGURE_ARGS	?=
EXTRA_MAKE_ARGS		?=

INSTALL_PATH		?= /Library/Frameworks

APPLICATION_INSTALL_PATH ?= /Applications/Utilities
PREFIX			?= /usr/local
BINDIR			?= ${PREFIX}/bin
LIBDIR			?= ${INSTALL_PATH}
MANDIR			?= ${PREFIX}/man

# tcl build directory (containing tclConfig.sh and Makefile)
TCL_BUILD_DIR		?= ${BUILD_DIR}/tcl/${BUILD_STYLE}
# location of installed tcl, only used if tcl in TCL_BUILD_DIR can't be found
TCL_FRAMEWORK_DIR	?= /Library/Frameworks
TCLSH_DIR		?= ${PREFIX}/bin

# set to non-empty value to install manpages in addition to html help:
INSTALL_MANPAGES	?=

# set to non-empty value to build TkX11 instead of TkAqua:
TK_X11			?=













#-------------------------------------------------------------------------------------------------------
# meta targets

meta			:= all install embedded install-embedded clean distclean test

styles			:= develop deploy

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#-------------------------------------------------------------------------------------------------------
# project specific settings

PROJECT			:= tk
PRODUCT_NAME		:= Tk

UNIX_DIR		:= ${CURDIR}/../unix
VERSION			:= $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.ac)
TCL_VERSION		:= ${VERSION}
wish			:= wish
WISH			= wish${VERSION}

BUILD_TARGET		:= binaries libraries tktest
INSTALL_TARGET		:= install

ifneq ($(wildcard $(subst ${space},\ ,${TCL_BUILD_DIR})/tclConfig.sh),)
TCL_DIR			:= ${TCL_BUILD_DIR}
TCL_FRAMEWORK_DIR	:= ${TCL_BUILD_DIR}/..
MAKE_VARS		:=
else
TCL_DIR			:= ${TCL_INSTALL_PATH}
TCL_EXE			:= ${TCLSH_DIR}/tclsh${TCL_VERSION}
MAKE_VARS		:= TCL_EXE
export DYLD_FRAMEWORK_PATH := ${TCL_FRAMEWORK_DIR}
endif

export CPPROG		:= cp -p

ifeq (${TK_X11},)
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-aqua
else
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-xft
VERSION			:= ${VERSION}-X11
wish			:= ${wish}-X11
override EMBEDDED_BUILD :=
endif

INSTALL_TARGETS		= install-binaries install-libraries
ifeq (${EMBEDDED_BUILD},)
INSTALL_TARGETS		+= install-private-headers install-headers install-demos
endif
ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment)
INSTALL_TARGETS		+= html-tk
ifneq (${INSTALL_MANPAGES},)
INSTALL_TARGETS		+= install-doc
endif
endif







|




|







|
















|

|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#-------------------------------------------------------------------------------------------------------
# project specific settings

PROJECT			:= tk
PRODUCT_NAME		:= Tk

UNIX_DIR		:= ${CURDIR}/../unix
VERSION			:= $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in)
TCL_VERSION		:= ${VERSION}
wish			:= wish
WISH			= wish${VERSION}

BUILD_TARGET		:= all tktest
INSTALL_TARGET		:= install

ifneq ($(wildcard $(subst ${space},\ ,${TCL_BUILD_DIR})/tclConfig.sh),)
TCL_DIR			:= ${TCL_BUILD_DIR}
TCL_FRAMEWORK_DIR	:= ${TCL_BUILD_DIR}/..
MAKE_VARS		:=
else
TCL_DIR			:= ${TCL_FRAMEWORK_DIR}/Tcl.framework
TCL_EXE			:= ${TCLSH_DIR}/tclsh${TCL_VERSION}
MAKE_VARS		:= TCL_EXE
export DYLD_FRAMEWORK_PATH := ${TCL_FRAMEWORK_DIR}
endif

export CPPROG		:= cp -p

ifeq (${TK_X11},)
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-aqua
else
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-xft
VERSION			:= ${VERSION}-X11
wish			:= ${wish}-X11
override EMBEDDED_BUILD :=
endif

INSTALL_TARGETS		= install-binaries install-headers install-libraries
ifeq (${EMBEDDED_BUILD},)
INSTALL_TARGETS		+= install-private-headers install-demos
endif
ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment)
INSTALL_TARGETS		+= html-tk
ifneq (${INSTALL_MANPAGES},)
INSTALL_TARGETS		+= install-doc
endif
endif
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	${MAKE} install-${PROJECT} INSTALL_ROOT="${OBJ_DIR}/"

${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \
		     ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in
	mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \
	if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \
	--prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \
	--mandir="${MANDIR}" --enable-framework \
	--with-tcl="${TCL_DIR}" \
	${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi
ifneq (${VERSION},${TCL_VERSION})
	@cd "${OBJ_DIR}" && sed -e 's#/Versions/${TCL_VERSION}#/Versions/${VERSION}#' \
	tkConfig.sh > tkConfig.sh.1 && mv -f tkConfig.sh.1 tkConfig.sh
endif








|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
	${MAKE} install-${PROJECT} INSTALL_ROOT="${OBJ_DIR}/"

${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \
		     ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in
	mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \
	if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \
	--prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \
	--mandir="${MANDIR}" --enable-threads --enable-framework \
	--with-tcl="${TCL_DIR}" \
	${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi
ifneq (${VERSION},${TCL_VERSION})
	@cd "${OBJ_DIR}" && sed -e 's#/Versions/${TCL_VERSION}#/Versions/${VERSION}#' \
	tkConfig.sh > tkConfig.sh.1 && mv -f tkConfig.sh.1 tkConfig.sh
endif

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
















247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
	rm -f Tcl.framework && ln -s "${TCL_FRAMEWORK_DIR}/Tcl.framework" . ; fi
endif

install-${PROJECT}: build-${PROJECT}
ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_)
	@echo "Cannot install-embedded with empty INSTALL_ROOT !" && false
endif
ifeq (${SUBFRAMEWORK}_${DYLIB_INSTALL_DIR},1_)
	@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
endif
ifeq (${EMBEDDED_BUILD},1)
	@rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tk.framework"
endif
ifeq (${SUBFRAMEWORK},1)
	@rm -rf "${INSTALL_ROOT}/Frameworks/Tk.framework"
endif
	${DO_MAKE}
ifeq (${EMBEDDED_BUILD}_${TK_X11},1_)
# workaround bug with 'cp -pRH' on Darwin 6 and earlier
	@if [ "`uname -r | awk -F. '{print $$1}'`" -lt 7 ]; then \
	mkdir -p "${TOP_DIR}"/{"${TCL_FMWK_DIR}","${TK_FMWK_DIR}"}/PrivateHeaders; fi
endif
ifeq (${INSTALL_BUILD},1)
ifeq (${EMBEDDED_BUILD},1)
# if we are embedding frameworks, don't install wish
	@rm -f "${INSTALL_ROOT}${BINDIR}/${WISH}" && \
	rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true
else
















# install wish symbolic link
	@ln -fs ${WISH} "${INSTALL_ROOT}${BINDIR}/${wish}"
endif # embedded
endif # install
ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
# keep copy of debug library around, so that
# Deployment build can be installed on top
# of Development build without overwriting
# the debug library
	@cd "${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}" && \
	ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug"
endif # Development, not embedded
ifeq (${TK_X11},)
ifeq (${SUBFRAMEWORK},)
ifeq (${EMBEDDED_BUILD},)
# install Wish.app link in APPLICATION_INSTALL_PATH and setup 'Wish Shell' compatibility links
	@cd "${TOP_DIR}" && if [ -n "${APP_DIR}" ]; then mkdir -p "./${APP_DIR}" && rm -rf "./${APP_DIR}/Wish.app" && \
	ln -fsh "./$$(echo "${APP_DIR}" | sed -e 's#/[^/][^/]*#/..#g')/${FMWK_DIR}/${PRODUCT_NAME}.framework/Resources/Wish.app" "./${APP_DIR}" && \
	ln -fsh Wish.app "./${APP_DIR}/Wish Shell.app"; fi && \
	ln -fsh Wish.app "./${TK_FMWK_DIR}/Resources/Wish Shell.app" && \
	ln -fsh Wish "./${TK_FMWK_DIR}/Resources/Wish.app/Contents/MacOS/Wish Shell"







<
<
<



<
<
<












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|







|

<







206
207
208
209
210
211
212



213
214
215



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
	rm -f Tcl.framework && ln -s "${TCL_FRAMEWORK_DIR}/Tcl.framework" . ; fi
endif

install-${PROJECT}: build-${PROJECT}
ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_)
	@echo "Cannot install-embedded with empty INSTALL_ROOT !" && false
endif



ifeq (${EMBEDDED_BUILD},1)
	@rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tk.framework"
endif



	${DO_MAKE}
ifeq (${EMBEDDED_BUILD}_${TK_X11},1_)
# workaround bug with 'cp -pRH' on Darwin 6 and earlier
	@if [ "`uname -r | awk -F. '{print $$1}'`" -lt 7 ]; then \
	mkdir -p "${TOP_DIR}"/{"${TCL_FMWK_DIR}","${TK_FMWK_DIR}"}/PrivateHeaders; fi
endif
ifeq (${INSTALL_BUILD},1)
ifeq (${EMBEDDED_BUILD},1)
# if we are embedding frameworks, don't install wish
	@rm -f "${INSTALL_ROOT}${BINDIR}/${WISH}" && \
	rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true
else
# redo prebinding (when not building for Mac OS X 10.4 or later only)
	@if [ "`echo "$${MACOSX_DEPLOYMENT_TARGET}" | \
	awk -F '10\\.' '{print int($$2)}'`" -lt 4 -a "`echo "$${CFLAGS}" | \
	awk -F '-mmacosx-version-min=10\\.' '{print int($$2)}'`" -lt 4 ]; \
	then cd ${INSTALL_ROOT}/; \
	if [ ! -d usr/lib ]; then mkdir -p usr && ln -fs /usr/lib usr/ && RM_USRLIB=1; fi; \
	if [ -n "${TK_X11}" -a ! -d usr/X11R6 ]; then mkdir -p usr && ln -fs /usr/X11R6 usr/ && RM_USRX11=1; fi; \
	if [ ! -d System ]; then ln -fs /System . && RM_SYSTEM=1; fi; \
	if [ ! -d "./${LIBDIR}/Tcl.framework" ]; then ln -fs "${TCL_FRAMEWORK_DIR}/Tcl.framework" "./${LIBDIR}"; RM_TCL=1; fi; \
	redo_prebinding -r . "./${TK_FMWK_DIR}/${PRODUCT_NAME}"; \
	if [ -z "${TK_X11}" ]; then redo_prebinding -r . "./${TK_FMWK_DIR}/Resources/Wish.app/Contents/MacOS/Wish"; \
	else redo_prebinding -r . "./${BINDIR}/${WISH}"; fi; \
	if [ -n "$${RM_USRLIB:-}" ]; then rm -f usr/lib; rmdir -p usr 2>&-; fi; \
	if [ -n "$${RM_USRX11:-}" ]; then rm -f usr/X11R6; rmdir -p usr 2>&-; fi; \
	if [ -n "$${RM_SYSTEM:-}" ]; then rm -f System; fi; \
	if [ -n "$${RM_TCL:-}" ]; then rm -f "./${LIBDIR}/Tcl.framework"; fi; fi
# install wish symbolic link
	@ln -fs ${WISH} "${INSTALL_ROOT}${BINDIR}/${wish}"
endif
endif
ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
# keep copy of debug library around, so that
# Deployment build can be installed on top
# of Development build without overwriting
# the debug library
	@cd "${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}" && \
	ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug"
endif
ifeq (${TK_X11},)

ifeq (${EMBEDDED_BUILD},)
# install Wish.app link in APPLICATION_INSTALL_PATH and setup 'Wish Shell' compatibility links
	@cd "${TOP_DIR}" && if [ -n "${APP_DIR}" ]; then mkdir -p "./${APP_DIR}" && rm -rf "./${APP_DIR}/Wish.app" && \
	ln -fsh "./$$(echo "${APP_DIR}" | sed -e 's#/[^/][^/]*#/..#g')/${FMWK_DIR}/${PRODUCT_NAME}.framework/Resources/Wish.app" "./${APP_DIR}" && \
	ln -fsh Wish.app "./${APP_DIR}/Wish Shell.app"; fi && \
	ln -fsh Wish.app "./${TK_FMWK_DIR}/Resources/Wish Shell.app" && \
	ln -fsh Wish "./${TK_FMWK_DIR}/Resources/Wish.app/Contents/MacOS/Wish Shell"
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	    install_name_tool -change $$(otool -L "$$1" | awk "/$$2\.framework.*[^:]\$$/ {print \$$1; sub(\"^.*/Frameworks\",\"@executable_path/../Frameworks\",\$$1); print \$$1}") "$$1"; \
	    chmod -RH a-w "$$1"; \
	} && \
	fix_install_id Frameworks/Tcl.framework/Tcl Tcl && fix_install_id Frameworks/Tk.framework/Tk Tk && \
	fix_install_name MacOS/Wish Tcl && fix_install_name MacOS/Wish Tk
ifeq (${INSTALL_BUILD},1)
	@cd "${TOP_DIR}" && rm -rf "./${FMWK_DIR}"/T{cl,k}.framework && rmdir -p "./${FMWK_DIR}" 2>&- || true
endif # install not subframework
endif # embedded
endif # not subframework
endif # not X11

clean-${PROJECT}: %-${PROJECT}:
	${DO_MAKE}
	rm -rf "${SYMROOT}"/{${PRODUCT_NAME}.framework,${WISH},tktest}
	rm -f "${OBJ_DIR}"{"${LIBDIR}","${BINDIR}"} && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${LIBDIR})) 2>&- || true && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${BINDIR})) 2>&- || true







<
|
|
|







283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
	    install_name_tool -change $$(otool -L "$$1" | awk "/$$2\.framework.*[^:]\$$/ {print \$$1; sub(\"^.*/Frameworks\",\"@executable_path/../Frameworks\",\$$1); print \$$1}") "$$1"; \
	    chmod -RH a-w "$$1"; \
	} && \
	fix_install_id Frameworks/Tcl.framework/Tcl Tcl && fix_install_id Frameworks/Tk.framework/Tk Tk && \
	fix_install_name MacOS/Wish Tcl && fix_install_name MacOS/Wish Tk
ifeq (${INSTALL_BUILD},1)
	@cd "${TOP_DIR}" && rm -rf "./${FMWK_DIR}"/T{cl,k}.framework && rmdir -p "./${FMWK_DIR}" 2>&- || true

endif
endif
endif

clean-${PROJECT}: %-${PROJECT}:
	${DO_MAKE}
	rm -rf "${SYMROOT}"/{${PRODUCT_NAME}.framework,${WISH},tktest}
	rm -f "${OBJ_DIR}"{"${LIBDIR}","${BINDIR}"} && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${LIBDIR})) 2>&- || true && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${BINDIR})) 2>&- || true

Changes to macosx/README.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58






59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81






















82
83
84
85
86
87
88
Tcl/Tk macOS README
----------------------

This is the README file for the macOS/Darwin version of Tcl/Tk.

1. Where to go for support
--------------------------

- The tcl-mac mailing list on sourceforge is the best place to ask questions
specific to Tcl & Tk on macOS:
	http://lists.sourceforge.net/lists/listinfo/tcl-mac
(this page also has a link to searchable archives of the list, please check them
before asking on the list, many questions have already been answered).

- For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet:
	http://groups.google.com/group/comp.lang.tcl/

- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on macOS, see
	https://wiki.tcl-lang.org/page/MacOS


- Please report bugs with Tk on macOS to the tracker:
	https://core.tcl-lang.org/tk/reportlist

2. Using Tcl/Tk on macOS
---------------------------

- There are two versions of Tk available on macOS: TkAqua using the native
aqua widgets and look&feel, and TkX11 using the traditional unix X11 widgets.
TkX11 requires an X11 server to be installed, such as XQuartz (available from www.xquartz.org).

TkAqua and TkX11 can be distinguished at runtime via [tk windowingsystem].

- At a minimum, macOS 10.3 is required to run Tcl and TkX11.
TkAqua requires macOS 10.6 or later.

- Unless weak-linking is used, Tcl/Tk built on macOS 10.x will not run on
10.y with y < x; on the other hand Tcl/Tk built on 10.y will always run on 10.x
with y <= x (but without any of the fixes and optimizations that would be
available in a binary built on 10.x).
Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl/Tk
built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).

- Wish checks the Resources/Scripts directory in its application bundle for a
file called AppMain.tcl, if found it is used as the startup script and the
Scripts folder is added to the auto_path. This can be used to emulate the old
OS9 TclTk droplets.

- If standard input is a special file of zero length (e.g. /dev/null), Wish
brings up the Tk console window at startup. This is the case when double
clicking Wish in the Finder (or using 'open Wish.app' from the Terminal).

- Tcl extensions can be installed in any of:
	$HOME/Library/Tcl /Library/Tcl
	$HOME/Library/Frameworks /Library/Frameworks
	(searched in that order).
Given a potential package directory $pkg, Tcl on OSX checks for the file
$pkg/Resources/Scripts/pkgIndex.tcl as well as the usual $pkg/pkgIndex.tcl.
This allows building extensions as frameworks with all script files contained in
the Resources/Scripts directory of the framework.







- The 'deploy' target of macosx/GNUmakefile installs the html manpages into the
standard documentation location in the Tcl/Tk frameworks:
	Tcl.framework/Resources/Documentation/Reference/Tcl
	Tk.framework/Resources/Documentation/Reference/Tk
No nroff manpages are installed by default by the GNUmakefile.

- The Tcl and Tk frameworks can be installed in any of the system's standard
framework directories:
	$HOME/Library/Frameworks /Library/Frameworks

- ${prefix}/bin/wish8.x is a script that calls a copy of 'Wish' contained in
	Tk.framework/Resources

- if 'Wish' is started from the Finder or via 'open', $argv may contain a
"-psn_XXXX" argument. This is the process serial number, you may need to filter
it out for cross platform compatibility of your scripts.

- the env array is different when Wish is started from the Finder (i.e. via
LaunchServices) than when it (or tclsh) is invoked from the Terminal, in
particular PATH may not be what you expect. (Wish started by LaunchServices
inherits loginwindow's environment variables, which are essentially those set in
$HOME/.MacOSX/environment.plist, and are unrelated to those set in your shell).























- TkAqua provides access to native OS X images via the Tk native bitmap facility
(including any image file readable by NSImage). A native bitmap name is
interpreted as follows (in order):
    - predefined builtin 32x32 icon name (stop, caution, document, etc)
    - name defined by [tk::mac::iconBitmap]
    - NSImage named image name
|


|





|







|
|
>

|
|

|


|
|
|
>


|
|

|
















|
|





>
>
>
>
>
>









|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Tcl/Tk Mac OS X README
----------------------

This is the README file for the Mac OS X/Darwin version of Tcl/Tk.

1. Where to go for support
--------------------------

- The tcl-mac mailing list on sourceforge is the best place to ask questions
specific to Tcl & Tk on Mac OS X:
	http://lists.sourceforge.net/lists/listinfo/tcl-mac
(this page also has a link to searchable archives of the list, please check them
before asking on the list, many questions have already been answered).

- For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet:
	http://groups.google.com/group/comp.lang.tcl/

- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on Mac OS X, see
	http://wiki.tcl.tk/_/ref?N=3753
	http://wiki.tcl.tk/_/ref?N=8361

- Please report bugs with Tk on Mac OS X to the tracker:
	http://core.tcl.tk/tk/reportlist

2. Using Tcl/Tk on Mac OS X
---------------------------

- There are two versions of Tk available on Mac OS X: TkAqua using the native
aqua widgets and look&feel, and TkX11 using the traditional unix X11 wigets.
TkX11 requires an X11 server to be installed, such as Apple's X11 (which is
available as an optional or default install on recent Mac OS X).
TkAqua and TkX11 can be distinguished at runtime via [tk windowingsystem].

- At a minimum, Mac OS X 10.3 is required to run Tcl and TkX11.
TkAqua requires Mac OS X 10.5 or later (starting with the Cocoa-based Tk 8.5.7).

- Unless weak-linking is used, Tcl/Tk built on Mac OS X 10.x will not run on
10.y with y < x; on the other hand Tcl/Tk built on 10.y will always run on 10.x
with y <= x (but without any of the fixes and optimizations that would be
available in a binary built on 10.x).
Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl/Tk
built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).

- Wish checks the Resources/Scripts directory in its application bundle for a
file called AppMain.tcl, if found it is used as the startup script and the
Scripts folder is added to the auto_path. This can be used to emulate the old
OS9 TclTk droplets.

- If standard input is a special file of zero length (e.g. /dev/null), Wish
brings up the Tk console window at startup. This is the case when double
clicking Wish in the Finder (or using 'open Wish.app' from the Terminal).

- Tcl extensions can be installed in any of:
	$HOME/Library/Tcl /Library/Tcl /System/Library/Tcl
	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks
	(searched in that order).
Given a potential package directory $pkg, Tcl on OSX checks for the file
$pkg/Resources/Scripts/pkgIndex.tcl as well as the usual $pkg/pkgIndex.tcl.
This allows building extensions as frameworks with all script files contained in
the Resources/Scripts directory of the framework.

- [load]able binary extensions can linked as either ordinary shared libraries
(.dylib) or as MachO bundles (since 8.4.10/8.5a3); bundles have the advantage
that they are [load]ed more efficiently from a tcl VFS (no temporary copy to the
native filesystem required), and prior to Mac OS X 10.5, only bundles can be
[unload]ed.

- The 'deploy' target of macosx/GNUmakefile installs the html manpages into the
standard documentation location in the Tcl/Tk frameworks:
	Tcl.framework/Resources/Documentation/Reference/Tcl
	Tk.framework/Resources/Documentation/Reference/Tk
No nroff manpages are installed by default by the GNUmakefile.

- The Tcl and Tk frameworks can be installed in any of the system's standard
framework directories:
	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks

- ${prefix}/bin/wish8.x is a script that calls a copy of 'Wish' contained in
	Tk.framework/Resources

- if 'Wish' is started from the Finder or via 'open', $argv may contain a
"-psn_XXXX" argument. This is the process serial number, you may need to filter
it out for cross platform compatibility of your scripts.

- the env array is different when Wish is started from the Finder (i.e. via
LaunchServices) than when it (or tclsh) is invoked from the Terminal, in
particular PATH may not be what you expect. (Wish started by LaunchServices
inherits loginwindow's environment variables, which are essentially those set in
$HOME/.MacOSX/environment.plist, and are unrelated to those set in your shell).

- TkAqua drawing is antialiased by default, but (outline) linewidth can be used
to control whether a line/shape is drawn antialiased. The antialiasing threshold
is 0 by default (i.e. antialias everything), it can be changed by setting
	set tk::mac::CGAntialiasLimit <limit>
in your script before drawing, in which case lines (or shapes with outlines)
thinner than <limit> pixels will not be antialiased.

- Text antialiasing by default uses the standard OS antialising settings.
Setting the global variable '::tk::mac::antialiasedtext' allows to control text
antialiasing from Tcl: a value of 1 enables AA, 0 disables AA and -1 restores
the default behaviour of respecting the OS settings.

- Scrollbars: There are two scrollbar variants in Aqua, normal & small. The
normal scrollbar has a small dimension of 15, the small variant 11.
Access to the small variant was added in Tk 8.4.2.

- The default metrics of native buttons, radiobuttons, checkboxes and
menubuttons in the Cocoa-based Tk 8.5.7 and later preserve compatibility with
the older Carbon-based implementation, you can turn off the compatibility
metrics to get more native-looking spacing by setting:
	set tk::mac::useCompatibilityMetrics 0

- TkAqua provides access to native OS X images via the Tk native bitmap facility
(including any image file readable by NSImage). A native bitmap name is
interpreted as follows (in order):
    - predefined builtin 32x32 icon name (stop, caution, document, etc)
    - name defined by [tk::mac::iconBitmap]
    - NSImage named image name
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157

158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173















174
175

176
177
178
179


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315


316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372











373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
application bundle files (i.e. standard about panel with no options specified).
See Apple Technote TN2179 and the AppKit documentation for -[NSApplication
orderFrontStandardAboutPanelWithOptions:] for details on the Info.plist keys and
app bundle files used by the about panel.
This support was added with the Cocoa-based Tk 8.5.7.

- TkAqua has three special menu names that give access to the standard
Application, Window and Help menus, see menu.n for details.  By default, the
platform-specific standard Help menu item "YourApp Help" performs the default
Cocoa action of showing the Help Book configured in the application's
Info.plist (or displaying an alert if no Help Book is set). This action can be
customized by defining a procedure named [tk::mac::ShowHelp]. If present, this
procedure is invoked instead by the standard Help menu item.  Support for the
Window menu and [tk::mac::ShowHelp] was added with the Cocoa-based Tk 8.5.7.


- The TkAqua-specific command [tk::unsupported::MacWindowStyle style] is used to
get and set macOS-specific toplevel window class and attributes. Note that
the window class and many attributes have to be set before the window is first
mapped for the change to have any effect.
The command has the following syntax:
	tk::unsupported::MacWindowStyle style window ?class? ?attributes?
The 2 argument form returns a list of the current class and attributes for the
given window. The 3 argument form sets the class for the given window using the
default attributes for that class. The 4 argument form sets the class and the
list of attributes for the given window.
Window class names:
    document, modal, floating, utility, toolbar, simple, help, overlay
Window attribute names:
    standardDocument, standardFloating, resizable, fullZoom, horizontalZoom,
    verticalZoom, closeBox, collapseBox, toolbarButton, sideTitlebar,
    noTitleBar, unifiedTitleAndToolbar, metal, hud, noShadow, doesNotCycle,
    noActivates, hideOnSuspend, inWindowMenu, ignoreClicks, doesNotHide,
    canJoinAllSpaces, moveToActiveSpace, nonActivating



Note that not all attributes are valid for all window classes.  Support for the
3 argument form was added with the Cocoa-based Tk 8.5.7, at the same time
support for some legacy Carbon-specific classes and attributes was removed
(they are still accepted by the command but no longer have any effect).


- Another command available in the tk::unsupported::MacWindowStyle namespace is:

  tk::unsupported::MacWindowStyle tabbingid window ?newId?
which can be used to get or set the tabbingIdentifier for the NSWindow
associated with a Tk Window.  See section 3 for details.

- The command:
  tk::unsupported::MacWindowStyle appearance window ?newAppearance?
is available when Tk is built and run on macOS 10.14 (Mojave) or later.  In
that case the Ttk widgets all support the "Dark Mode" appearance which was
introduced in 10.14. The command accepts the following values for the optional
newAppearance option: "aqua", "darkaqua", or "auto".  If the appearance is set
to aqua or darkaqua then the window will be displayed with the corresponding
appearance independent of any preferences settings.  If it is set to "auto"
the appearance will be determined by the preferences.  This command can be
used to opt out of Dark Mode on a per-window basis.  It may be best to run the "update" command before setting the appearance property, to allow the event loop to run.

















- To determine the current appearance of a window in macOS 10.14 (Mojave) and

higher, one can use the command:
  tk::unsupported::MacWindowStyle isdark
The boolean return value is true if the window is currently displayed with the
dark appearance.



- If you want to use Remote Debugging with Xcode, you need to set the
environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will
cause us to force closing stdin & stdout.  Otherwise, given how Xcode launches
Wish remotely, they will be left open and then Wish & gdb will fight for stdin.

3. FullScreen, Split View and Tabbed Windows
--------------------------------------------

Since the release of OSX 10.6 (Snow Leopard) a steadily expanding sequence of
high level window operations have been added to Apple's window manager.  These
operations are launched by user actions which are handled directly by the
window manager; they are not initiated by the application.  In some, but not
all cases, the application is notified before and after the operations are
carried out.

In OSX releases up to and including 10.6 there were three buttons with
stoplight colors located on the left side of a window's title bar.  The
function of the green button was to "zoom" or "maximize" the window, i.e. to
expand the window so that it fills the entire screen, while preserving the
appearance of the window including its title bar.  The release of OSX 10.7
(Lion) introduced the "FullScreen" window which not only filled the screen but
also hid the window's title bar and the menu bar which normally appears at the
top of the screen. These hidden objects would only become visible when the
mouse hovered near the top of the screen.  FullScreen mode was initiated by
pressing a button showing two outward pointing arrows located on the right side
of the title bar; it was terminated by pressing a similar button with inward
pointing arrows on the right hand side of the menu bar.  In OSX 10.10
(Yosemite) the FullScreen button was removed. The green button was repurposed
to cause a window to become a FullScreen window. To zoom a window the user had
to hold down the option key while pressing the green button.  The release of
OSX 10.11 added a third function to the green button: to create two half-screen
windows with hidden title bars and a hidden menu bar, called Split View
windows.  If the green button is held down for one second its window expands to
fill half of the screen.  It can be moved to one side or the other with the
mouse.  The opposite side shows thumbnail images of other windows.  Selecting
one of the thumbnails expands its window to fill that half of the screen.  The
divider between the two windows can be moved to adjust the percentage of the
screen occupied by each of the two tiles.  In OSX 10.12 (Sierra) Tabbed windows
were introduced.  These allow an application with multiple windows to display
its windows as tabs within a single window frame.  Clicking on a tab brings its
window into view.  Tabs can be rearranged by dragging.  Dragging a tab to the
desktop turns it into a separate window.  Items in the Window menu can be used
to cycle through the tabs, move tabbed windows to separate windows, or merge a
set of separate windows as tabs in the same window frame.

Tk now fully supports all of these high level window operations on any system
where the operation exists.  The FullScreen and Split View windows are handled
automatically with no action required on the part of the programmer.  Tabbed
windows, on the other hand, require some attention from the programmer.
Because many of the operations with tabs are handled through the application's
Window menu, it is essential that an application provide a Windows menu to
avoid presenting a confusing interface to the user. This cannot be ignored, in
part because the systemwide Dock Preferences offers an option to always attempt
to open application windows as tabs. An application which does not provide a
Window menu will necessarily present a confusing interface to any user who has
selected this option.

A further complication is that it is not neccessarily appropriate for all of an
application's windows to be grouped together as tabs in the same frame.  In
fact, the Apple guidelines insist that windows which are grouped together as
tabs should be similar to each other.  The mechanism provided for arranging
this was to assign to each NSwindow a tabbingIdentifier, and to require that
all windows grouped together as tabs in the same window frame must have the
same tabbingIdentifier.  A tabbingIdentifier is implemented as an arbitrary
string, and a system-generated default tabbingIdentifier is provided to all new
windows.

Tk provides a means for getting and setting the tabbingIdentifier of
the NSWindow underlying a Tk Window. This is handled by the command

tk::unsupported::MacWindowStyle tabbingid window ?newId?

(This command generates an error if used on OSX 10.11 or earlier, since the
tabbingIdentifier does not exist on those systems.)  The command returns the
tabbingIdentifier which had been assigned to the window prior to execution of
the command.  If the optional newId argument is omitted, the window's
tabbingIdentifier is not changed.  Otherwise it is set to the string specified
by the argument.

Since NSWindows can only be grouped together as tabs if they all have the same
tabbingIdentifier, one can prevent a window from becoming a tab by giving it a
unique tabbingIdentifier. This is independent of any preferences setting. To
ensure that we maintain consistency, changing the tabbingIdentifier of a window
which is already displayed as a tab will also cause it to become a separate
window.

4. Ttk, Dark Mode and semantic colors
---------------------------------------

With the release of OSX 10.14 (Mojave), Apple introduced the DarkAqua
appearance.  Part of the implementation of the Dark Mode was to make
some of the named NSColors have dynamic values.  Apple calls these
"semantic colors" because the name does not specify a specific color,
but rather refers to the context in which the color should be used.
In particular, when a user selects Dark Mode in the system preferences
these colors change appearance.  For example systemTextColor is dark in
Aqua and light in DarkAqua.

Tk now provides colors corresponding to all of the NSColors in Apple's System
ColorList.  The convention for naming these colors is that the Tk name is
generated by capitalizing the macOS name and adding the prefix "system". The
System ColorList differs between releases of macOS and some colors, such as
systemLinkColor and systemControlAccentColor, are simulated on older systems
which did not provide them.  The following colors are available on all
supported macOS releases, although newer systems will support additional
colors: systemControlAccentColor, systemControlTextColor,
systemDisabledControlTextColor, systemLabelColor, systemLinkColor,
systemPlaceholderTextColor, systemSelectedTextBackgroundColor,
systemSelectedTextColor, systemSeparatorColor, systemTextBackgroundColor, and
systemTextColor.  One additional color, systemSelectedTabTextColor, does not
exist in macOS but is used by Tk to match the different colors used for
Notebook tab titles in different OS versions.

The default background and foreground colors of most of the Tk widgets
have been set to semantic colors, which means that the widgets will change
appearance, and remain usable, when Dark Mode is selected in the system
preferences.  However, to get a close match to the native Dark Mode style it
is recommended to use Ttk widgets when possible.

Apple's tab view and GroupBox objects delimit their content by
displaying it within a rounded rectangle with a background color that
contrasts with the background of the containing object.  This means
that the background color of a Ttk widget depends on how deeply it is
nested inside of other widgets that use contrasting backgrounds.  To
support this, there are 8 contrasting system colors named
systemWindowBackgroundColor, and systemWindowBackgroundColor1 - 7.
The systemWindowBackgroundColor is the standard background for a
dialog window and the others match the contrasting background colors
used in ttk::notebooks and ttk::labelframes which are nested to the
corresponding depth.

5. Building Tcl/Tk on macOS
------------------------------


- macOS 10.6 is required to build TkAqua and TkX11.  The XCode application provides everything needed to build Tk, but it is not necessary to install the full XCode.


It suffices to install the Command Line Tools package, which can be done
by running the command:
xcode-select --install


- Tcl/Tk are most easily built as macOS frameworks via GNUmakefile in
tcl/macosx and tk/macosx (see below for details), but can also be built with the
standard unix configure and make buildsystem in tcl/unix resp. tk/unix as on any
other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
buildsystem).
The macOS specific configure flags are --enable-aqua, --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier). Note that --enable-aqua is incompatible with
--disable-corefoundation (for both Tcl and Tk configure).

- It was once possible to build with the Xcode IDE via the projects in
tk/macosx, but this has not been tested recently. Take care to use the
project matching your DevTools and OS version:
	Tk.xcode: 		    for Xcode 3.1 on 10.5
	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
These have the following targets:
	Tk:			    calls through to tk/macosx/GNUMakefile,
				    requires a corresponding build of the Tcl
				    target of tcl/macosx/Tcl.xcode.
	tktest:			    static build of TkAqua tktest for debugging.
	tktest-X11:		    static build of TkX11 tktest for debugging.
The following build configurations are available:
	Debug:			    debug build for the active architecture,
				    with Fix & Continue enabled.
	Debug clang:		    use clang compiler.
	Debug llvm-gcc:		    use llvm-gcc compiler.
	Debug gcc40:		    use gcc 4.0 compiler.
	DebugNoGC:		    disable Objective-C garbage collection.

	DebugNoFixAndContinue:      disable Fix & Continue.
	DebugUnthreaded:	    disable threading.
	DebugNoCF:		    disable corefoundation (X11 only).
	DebugNoCFUnthreaded:	    disable corefoundation an threading.
	DebugMemCompile:	    enable memory and bytecode debugging.
	DebugLeaks:		    define PURIFY.
	DebugGCov:		    enable generation of gcov data files.
	Debug64bit:		    configure with --enable-64bit (requires
				    building on a 64bit capable processor).
	Release:		    release build for the active architecture.
	ReleaseUniversal:	    32/64-bit universal build.
	ReleaseUniversal clang:	    use clang compiler.
	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
				    deployment target).
	Note that the non-SDK configurations have their deployment target set to
	10.5 (Tk.xcode) resp. 10.6 (Tk.xcodeproj).
The Xcode projects refer to the toplevel tcl and tk source directories via the
the TCL_SRCROOT and TK_SRCROOT user build settings, by default these are set to
the project-relative paths '../../tcl' and '../../tk', if your source
directories are named differently, e.g. '../../tcl8.6' and '../../tk8.6', you
need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
text editor.












- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
to the minimal OS version the binaries should be able to run on, e.g:
	export MACOSX_DEPLOYMENT_TARGET=10.6
This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead:
	export CFLAGS="-mmacosx-version-min=10.6"
Support for weak-linking was added with 8.4.14/8.5a5.

Detailed Instructions for building with macosx/GNUmakefile
----------------------------------------------------------

- Unpack the Tcl and Tk source release archives and place the tcl and tk source
trees in a common parent directory.
[ If you don't want have the two source trees in one directory, you'll need to ]
[ create the following symbolic link for the build to work as setup by default ]
[      ln -fs /path_to_tcl/build /path_to_tk/build			       ]
[ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree)  ]
[ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make.  ]

- The following instructions assume the Tcl and Tk source trees are named
"tcl${ver}" and "tk${ver}" (where ${ver} is a shell variable containing the
Tcl/Tk version number, e.g. '8.6').
Setup this shell variable as follows:
	ver="8.6"
If you are building from CVS, omit this step (CVS source tree names usually do
not contain a version number).

- Setup environment variables as desired, e.g. for a universal build on 10.5:
	CFLAGS="-arch i386 -arch x86_64 -arch ppc -mmacosx-version-min=10.5"
	export CFLAGS








|
|
|
|
|
|
|
>


|















|
>
>

|
|
|
|

>
|
>
|
<
<

<
<
|
|
|
|
|
<
<
<

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
>
|
<
<
<
>
>






<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


>
|
>
>
|
<
|
>

|




|




|
<
|











<
<
|
|
>











|
|
<







|



>
>
>
>
>
>
>
>
>
>
>



|

|















|

|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194


195


196
197
198
199
200



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219



220
221
222
223
224
225
226
227


228



























































































































229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
application bundle files (i.e. standard about panel with no options specified).
See Apple Technote TN2179 and the AppKit documentation for -[NSApplication
orderFrontStandardAboutPanelWithOptions:] for details on the Info.plist keys and
app bundle files used by the about panel.
This support was added with the Cocoa-based Tk 8.5.7.

- TkAqua has three special menu names that give access to the standard
Application, Window and Help menus, see menu.n for details.
By default, the platform-specific standard Help menu item "YourApp Help" peforms
the default Cocoa action of showing the Help Book configured in the
application's Info.plist (or displaying an alert if no Help Book is set). This
action can be customized by defining a procedure named [tk::mac::ShowHelp], if
present, this procedure is invoked instead by the standard Help menu item.
Support for the Window menu and [tk::mac::ShowHelp] was added with the
Cocoa-based Tk 8.5.7.

- The TkAqua-specific command [tk::unsupported::MacWindowStyle style] is used to
get and set Mac OS X-specific toplevel window class and attributes. Note that
the window class and many attributes have to be set before the window is first
mapped for the change to have any effect.
The command has the following syntax:
	tk::unsupported::MacWindowStyle style window ?class? ?attributes?
The 2 argument form returns a list of the current class and attributes for the
given window. The 3 argument form sets the class for the given window using the
default attributes for that class. The 4 argument form sets the class and the
list of attributes for the given window.
Window class names:
    document, modal, floating, utility, toolbar, simple, help, overlay
Window attribute names:
    standardDocument, standardFloating, resizable, fullZoom, horizontalZoom,
    verticalZoom, closeBox, collapseBox, toolbarButton, sideTitlebar,
    noTitleBar, unifiedTitleAndToolbar, metal, hud, noShadow, doesNotCycle,
    noActivates, hideOnSuspend, inWindowMenu, ignoreClicks, doesNotHide,
    canJoinAllSpaces, moveToActiveSpace, nonActivating, black, dark, light,
    gray, red, green, blue, cyan, yellow, magenta, orange, purple,
    brown, clear, opacity

Note that not all attributes are valid for all window classes.
Support for the 3 argument form was added with the Cocoa-based Tk 8.5.7, at the
same time support for some legacy Carbon-specific classes and attributes was
removed (they are still accepted by the command but no longer have any effect).

The color window attributes (black, dark, red, etc.) and the "opacity" allow  one to set the background and opacity of a textured ("metal") window. This allows a Tk window to implement a window without the dividing line between the titlebar and the rest of the window, or the "unified toolbar" effect, which is increasingly standard in Mac applications. An example:

toplevel .f
tk::unsupported::MacWindowStyle style .f document {metal light opaque closeBox collapseBox resizable standardDocument }





pack [label .f.f -bg  #ababab -text "This is a textured window\nwith opacity and a gray background\nsimilar to other Mac applications"] -fill both -expand yes

The color attributes correspond to system-defined NSColor constants (e.g., red is [NSColor redColor]. The "light" and "dark" attributes correspond to lightGrayColor and darkGrayColor, respectively (because of the way the attributes are parsed, using "lightgray" and "darkgray" would cause a conflict with the core "gray" attribute).

Below are the corresponding hex and/or Tk-defined colors that can be used from Tk widgets to match the NSColor-based attributes:




black	#000000
dark	#545454
light	#ababab
white	#ffffff
gray	#7f7f7f
red 	#ff0000
green	#00ff00
blue	#0000ff
cyan	#00ffff
yellow	#ffff00
magenta	#ff00ff
orange	#ff8000
purple 	#800080
brown	#996633
clear	systemTransparent


- The Cocoa-based TkAqua can be distinguished from the older Carbon-based
version via the [winfo server .] command, example output on Mac OS X 10.5.7:



    Cocoa-based:	CG409.3 Apple AppKit GC 949.46 Mac OS X 1057
    Carbon-based:	QD10R30 Apple 1057

- If you want to use Remote Debugging with Xcode, you need to set the
environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will
cause us to force closing stdin & stdout.  Otherwise, given how Xcode launches
Wish remotely, they will be left open and then Wish & gdb will fight for stdin.































































































































3. Building Tcl/Tk on Mac OS X
------------------------------

- At least Mac OS X 10.3 is required to build Tcl and TkX11, and Mac OS X 10.5
is required to build TkAqua.
Apple's Xcode Developer Tools need to be installed (only the most recent version
matching your OS release is supported), the Xcode installer is available on Mac
OS X install media or may be present in /Applications/Installers on Macs that

came with OS X preinstalled. The most recent version can always be downloaded
from the ADC website http://connect.apple.com (free ADC membership required).

- Tcl/Tk are most easily built as Mac OS X frameworks via GNUmakefile in
tcl/macosx and tk/macosx (see below for details), but can also be built with the
standard unix configure and make buildsystem in tcl/unix resp. tk/unix as on any
other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
buildsystem).
The Mac OS X specific configure flags are --enable-aqua, --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier). Note that --enable-aqua is incompatible with
--disable-corefoundation (for both Tcl and Tk configure).

- It is also possible to build with the Xcode IDE via the projects in

tk/macosx, take care to use the project matching your DevTools and OS version:
	Tk.xcode: 		    for Xcode 3.1 on 10.5
	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
These have the following targets:
	Tk:			    calls through to tk/macosx/GNUMakefile,
				    requires a corresponding build of the Tcl
				    target of tcl/macosx/Tcl.xcode.
	tktest:			    static build of TkAqua tktest for debugging.
	tktest-X11:		    static build of TkX11 tktest for debugging.
The following build configurations are available:
	Debug:			    debug build for the active architecture,
				    with Fix & Continue enabled.


	Debug gcc42:		    use gcc 4.2 compiler.
	Debug gcc42 nogc:	    disable Objective-C garbage collection.
	Debug llvmgcc42:	    use llvm-gcc 4.2 compiler.
	DebugNoFixAndContinue:      disable Fix & Continue.
	DebugUnthreaded:	    disable threading.
	DebugNoCF:		    disable corefoundation (X11 only).
	DebugNoCFUnthreaded:	    disable corefoundation an threading.
	DebugMemCompile:	    enable memory and bytecode debugging.
	DebugLeaks:		    define PURIFY.
	DebugGCov:		    enable generation of gcov data files.
	Debug64bit:		    configure with --enable-64bit (requires
				    building on a 64bit capable processor).
	Release:		    release build for the active architecture.
	ReleaseUniversal:	    32/64-bit universal build.
	ReleaseUniversal gcc42:     use gcc 4.2 compiler.
	ReleaseUniversal llvmgcc42: use llvm-gcc 4.2 compiler.

	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
				    deployment target).
	Note that the non-SDK configurations have their deployment target set to
	10.5 (Tk.xcode) resp. 10.6 (Tk.xcodeproj).
The Xcode projects refer to the toplevel tcl and tk source directories via the
the TCL_SRCROOT and TK_SRCROOT user build settings, by default these are set to
the project-relative paths '../../tcl' and '../../tk', if your source
directories are named differently, e.g. '../../tcl8.5' and '../../tk8.5', you
need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
text editor.

- To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
	export CFLAGS="-arch i386 -arch x86_64 -arch ppc"
This requires Mac OS X 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is
omitted, but _not_ Xcode 2.1) and will work on any architecture (on PowerPC
Tiger you need to add "-isysroot /Developer/SDKs/MacOSX10.4u.sdk").
Note that configure requires CFLAGS to contain a least one architecture that can
be run on the build machine (i.e. ppc on G3/G4, ppc or ppc64 on G5, ppc or i386
on Core and ppc, i386 or x86_64 on Core2/Xeon).
Universal builds of Tcl TEA extensions are also possible with CFLAGS set as
above, they will be [load]able by universal as well as thin binaries of Tcl.

- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
to the minimal OS version the binaries should be able to run on, e.g:
	export MACOSX_DEPLOYMENT_TARGET=10.4
This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead:
	export CFLAGS="-mmacosx-version-min=10.4"
Support for weak-linking was added with 8.4.14/8.5a5.

Detailed Instructions for building with macosx/GNUmakefile
----------------------------------------------------------

- Unpack the Tcl and Tk source release archives and place the tcl and tk source
trees in a common parent directory.
[ If you don't want have the two source trees in one directory, you'll need to ]
[ create the following symbolic link for the build to work as setup by default ]
[      ln -fs /path_to_tcl/build /path_to_tk/build			       ]
[ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree)  ]
[ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make.  ]

- The following instructions assume the Tcl and Tk source trees are named
"tcl${ver}" and "tk${ver}" (where ${ver} is a shell variable containing the
Tcl/Tk version number, e.g. '8.5').
Setup this shell variable as follows:
	ver="8.5"
If you are building from CVS, omit this step (CVS source tree names usually do
not contain a version number).

- Setup environment variables as desired, e.g. for a universal build on 10.5:
	CFLAGS="-arch i386 -arch x86_64 -arch ppc -mmacosx-version-min=10.5"
	export CFLAGS

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
make overrides to the tk/macosx GNUmakefile, e.g.
	make -C tk${ver}/macosx \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
	sudo make -C tk${ver}/macosx install \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.

- To build a Tcl.framework and Tk.framework for use as subframeworks in another
framework, use the install-embedded target and set SUBFRAMEWORK=1.  Set the
DYLIB_INSTALL_DIR variable to the path which should be the install_name path of
the shared library and set the DESTDIR variable to the pathname of a staging
directory where the frameworks will be written.  The Tcl framework must be
built first.
For example, running the commands:
	make -C ../tcl8.6/macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
	DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tcl.framework
	make -C macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
	DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tk.framework
will produce a Tcl.framework and a Tk.framework usable as subframeworks of
Some.framework.  The frameworks will be found in /tmp/tcltk/Frameworks/

5. Details regarding the macOS port of Tk.
-------------------------------------------

5.1 About the event loop
~~~~~~~~~~~~~~~~~~~~~~~~

The main program in a typical OSX application looks like this (see
https://developer.apple.com/library/mac/documentation/Cocoa/\
Reference/ApplicationKit/Classes/NSApplication_Class)

    void NSApplicationMain(int argc, char *argv[]) {
        [NSApplication sharedApplication];
        [NSBundle loadNibNamed:@"myMain" owner:NSApp];
        [NSApp run];
    }
Here NSApp is a standard global variable, initialized by the OS, which
points to an object in a subclass of NSApplication (called
TKApplication in the case of the macOS port of Tk).

The [NSApp run] method implements the event loop for a typical Mac
application.  There are three key steps in the run method.  First it
calls [NSApp finishLaunching], which creates the bouncing application
icon and does other mysterious things. Second it creates an
NSAutoreleasePool.  Third, it starts an event loop which drains the
NSAutoreleasePool every time the queue is empty, and replaces the
drained pool with a new one.  This third step is essential to
preventing memory leaks, since the internal methods of Appkit objects
all assume that an autorelease pool is in scope and will be drained
when the event processing cycle ends.

The macOS Tk application does not call the [NSApp run] method at
all.  Instead it uses the event loop built in to Tk.  So the
application must take care to replicate the important features of the
method ourselves.  The way that autorelease pools are handled is
discussed in 5.2 below.  Here we discuss the event handling itself.


The Tcl event loop simply consists of repeated calls to TclDoOneEvent.
Each call to TclDoOneEvent begins by collecting all pending events from
an "event source", converting them to Tcl events and adding them
to the Tcl event queue. For macOS, the event source is the NSApp
object, which maintains an event queue even though its run method
will never be called to process them.  The NSApp provides methods for
inspecting the queue and removing events from it as well as the
[NSApp sendevent] which sends an event to all of the application's
NSWindows which can then send it to subwindows, etc.

The event collection process consists of first calling a platform
specific SetupProc and then a platform specific CheckProc.  In
the macOS port, these are named TkMacOSXEventsSetupProc and
TkMacOSXEventsCheckProc.

It is important to understand that the Apple window manager does not
have the concept of an expose event.  Their replacement for an expose
event is to have the window manager call the [NSView drawRect] method
in any situation where an expose event for that NSView would be
generated in X11.  The [NSView drawRect] method is a no-op which is
expected to be overridden by any application.  In the case of Tcl, the
replacement [NSView drawRect] method creates a Tcl expose event
for each dirty rectangle of the NSView, and then adds the expose
event to the Tcl queue.


5.2 Autorelease pools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to carry out the job of managing autorelease pools, which
would normally be handled by the [NSApp run] method, a private
NSAutoreleasePool* property is added to the TkApplication subclass of
NSApplication. The TkpInit function calls [NSApp _setup] which
initializes this property by creating an NSAutoreleasePool prior to
calling [NSApp finishLaunching].  This mimics the behavior of the
[NSApp run] method, which calls [NSApp finishLaunching] just before
starting the event loop.

Since the CheckProc function gets called for every Tk event, it is an
appropriate place to drain the main NSAutoreleasePool and replace it
with a new pool.  This is done by calling the method [NSApp
_resetAutoreleasePool], where _resetAutoreleasePool is a method which
we define for the subclass.  Unfortunately, by itself this is not
sufficient for safe memory managememt because, as was made painfully
evident with the release of OS X 10.13, it is possible for calls to
TclDoOneEvent, and hence to CheckProc, to be nested.  Draining the
autorelease pool in a nested call leads to crashes as objects in use
by the outer call can get freed by the inner call and then reused later.
One particular situation where this happens is when a modal dialogue
gets posted by a Tk Application.  To address this, the NSApp object
also implements a semaphore to prevent draining the autorelease pool
in nested calls to CheckProc.

One additional minor caveat for developers is that there are several
steps of the Tk initialization which precede the call to TkpInit.
Notably, the font package is initialized first.  Since there is no
NSAutoreleasePool in scope prior to calling TkpInit, the functions
called in these preliminary stages need to create and drain their own
NSAutoreleasePools whenever they call methods of Appkit objects
(e.g. NSFont).

5.3 Clipping regions and "ghost windows"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Another unusual aspect of the macOS port is its use of clipping
regions.  It was part of Daniel Steffen's original design that the
TkWindowPrivate struct maintains three HIShapeRef regions, named
visRgn, aboveVisRgn and drawRgn.  These regions are used as clipping
masks whenever drawing into an NSView.  The visRgn is the bounding box
of the window with a rectangle removed for each subwindow and for each
sibling window at a higher stacking level.  The drawRgn is the
intersection of the visRgn with the clipping rectangle of the
window. (Normally, the clipping rectangle is the same as the bounding
rectangle, but drawing can be clipped to a smaller rectangle by
calling TkpClipDrawableToRect.) The aboveVisRgn is the intersection of
the window's bounding rectangle with the bounding rectangle of the
parent window.  Much of the code in tkMacOSXSubwindows.c is devoted to
rebuilding these clipping regions whenever something changes in the
layout of the windows.  This turns out to be a tricky thing to do and
it is extremely prone to errors which can be difficult to trace.

It is not entirely clear what the original reason for using these
clipping regions was.  But one benefit is that if they are correctly
maintained then it allows windows to be drawn in any order.  You do
not have to draw them in the order of the window hierarchy.  Each
window can draw its entire rectangle through its own mask and never
have to worry about drawing in the wrong place.  It is likely that
the need for using clipping regions arose because, as Apple explicitly
states in the documentation for [NSView subviews],

    "The order of the subviews may be considered as being
    back-to-front, but this does not imply invalidation and drawing
    behavior."

In the early versions of the macOS port, buttons were implemented as
subviews of class TkButton.  This probably exacerbated the likelihood
that Tk windows would need to be drawn in arbitrary order.

The most obvious side effect caused by not maintaining the clipping
regions is the appearance of so-called "ghost windows".  A common
situation where these may arise is when a window containing buttons
is being scrolled.  A user may see two images of the same button on
the screen, one in the pre-scroll location and one in the post-scroll
location.

To see how these 'ghost windows' can arise, think about what happens if
the clipping regions are not maintained correctly.  A window might
have a rectangle missing from its clipping region because that
rectangle is the bounding rectangle for a subwindow, say a button.
The parent should not draw in the missing rectangle since doing so
would trash the button.  The button is responsible for drawing
there. Now imagine that the button gets moved, say by a scroll, but
the missing rectangle in the parent's clipping region does not get
moved correctly, or it gets moved later on, after the parent has
redrawn itself.  The parent would still not be allowed to draw in the
old rectangle, so the user would continue to see the image of the
button in its old location, as well as another image in the new
location.  This is a prototypical example of a "ghost window".
Anytime you see a "ghost window", you should suspect problems with the
updates to the clipping region visRgn.  It is natural to look for
timing issues, race conditions, or other "event loop problems".  But
in fact, the whole design of the code is to make those timing issues
irrelevant.  As long as the clipping regions are correctly maintained
the timing does not matter.  And if they are not correctly maintained
then you will see "ghost windows".

It is worth including a detailed description of one specific place
where the failure to correctly maintain clipping regions caused "ghost
window" artifacts that plagued the macOS port for years.  These
occurred when scrolling a Text widget which contained embedded
subwindows.  It involved some specific differences between the
low-level behavior of Apple's window manager versus those of the other
platforms, and the fix ultimately required changes in the generic Tk
implementation (documented in the comments in the DisplayText
function).

The Text widget attempts to improve perfomance when scrolling by
minimizing the number of text lines which need to be redisplayed.  It
does this by calling the platform-specific TkScrollWindow function
which uses a low-level routine to map one rectangle of the window to
another.  The TkScrollWindow function returns a damage region which is
then used by the Text widget's DisplayText function to determine which
text lines need to be redrawn.  On the unix and win platforms, this
damage region includes bounding rectangles for all embedded windows
inside the Text widget.  The way that this works is system dependent.
On unix, the low level scrolling is done by XCopyRegion, which
generates a GraphicsExpose event for each embedded window.  These
GraphicsExposed events are processsed within TkScrollWindow, using a
special handler which adds the bounding rectangle of each subwindow to
the damage region.  On the win platform the damage region is built by
the low level function ScrollWindowEx, and it also includes bounding
rectangles for all embedded windows.  This is possible because on X11
and Windows every Tk widget is also known to the window manager as a
window.  The situation is different on macOS.  The underlying object
for a top level window on macOS is the NSView.  However, Apple
explicitly warns in its documentation that performance degradation
occurs when an NSView has more than about 100 subviews.  A Text widget
with thousands of lines of text could easily contain more than 100
embedded windows.  In fact, while the original Cocoa port of Tk did
use the NSButton object, which is derived from NSView, as the basis
for its Tk Buttons, that was changed in order to improve performance.
Moreover, the low level routine used for scrolling on macOS, namely
[NSView scrollrect:by], does not provide any damage information.  So
TkScrollWindow needs to work differently on macOS.  Since it would be
inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.

6.0 Virtual events on macOS 10.14 and later
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 10.14 release added support for system appearance changes,
including a "Dark Mode" that renders all window frames and menus in
dark colors. Tk 8.6.11 provides three virtual events <<LightAqua>>,
<<DarkAqua>> and <<AppearanceChanged>>, to allow you to update your Tk
app's appearance when the system appearance changes.  These events are
generated in [NSView effectiveAppearanceChanged], which is called by
the Apple window manager when the General Preferences is changed
either by switching between Light Mode and Dark Mode or by changing
the Accent Color or Highlight Color.

The <<AppearanceChanged>> virtual event has a data string which can be
accessed with the %d substitution.  The format of the data string is
that it consists of 6 words:
  "Appearance XXXX Accent YYYY Highlight ZZZZ"
For example, the following code will print the current appearance
name, accent color and highlight color when the <<AppearanceChanged>>
virtual event fires:

bind . <<AppearanceChanged>> {
    array set data [split %d]
    puts "  Appearance: $data(Appearance)"
    puts "  Accent: $data(Accent)"
    puts "  Highlight: $data(Highlight)\n"
}



7.0 Mac Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~

With 8.6.10, Tk supports the Mac's NSServices API, documented at
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/SysServices/introduction.html#//apple_ref/doc/uid/10000101-SW1
and in TIP 536 and Tk's man page. Tk presents a simple,
straightforward API to implement the Services functionality.

The Tk implementation of the NSServices API is intended for standalone
applications, such as one wrapped by the standalone version of Wish
and re-named into a different application.  In particular such an
application would specify its own unique CFBundleIdentifier in its
Info.plist file.  During development, however, if Wish itself is being
used as the receiver, it may be necessary to take some care to ensure
that the correct version of Wish.app is available as a receiver of
NSServices data.

When one macOS app uses NSServices to send data to another app that is
not running, LaunchServices will launch the receiver.  LaunchServices
assumes that the CFBundleIdentifier uniquely identifies an app among
all of the apps installed on a system.  But this may not be the case
for Wish.app if, for example, you have compiled Tk from source at some
time in the past.  In that case the Tk build directory will contain
its own copy of Wish.app that will be visible to LaunchServices.  It
may be necessary when testing your app to take some steps to ensure
that LaunchServices is launching the correct Wish.app.  Instructions
for doing this are provided below.

The command line tool which manages the LaunchServices database has
an amazingly unwieldy path name.  So, first, run this command:

alias lsregister='/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister'

Then you can reset the LaunchServices database like this:

$ lsregister -kill
$ lsregister -seed

To find out which versions of Wish.app have been located by
LaunchServices, run:

$ lsregister -dump | grep path | grep Wish

If more than one version of Wish is showing up in this list, eliminate
all of the unintended targets by running

lsregister -u /path/to/bad/Wish.app

Continue this until only the correct version of Wish shows up in the
list.







<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|

<
<
<
|
<
<






<
<
<

|
|
|
|







|
|
|
<
|

>
|
|
|
|
|
<
<
|
<

|
|
<
|
|
<
<
<
<
<
<
<
<
|
|
|
<
<
|
<
<
<
<
<
<
<
<
|


|
|
|
<
<
<
<
<
<
<
<
<

|
|
|
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
383
384
385
386
387
388
389













390

391
392



393


394
395
396
397
398
399



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422


423

424
425
426

427
428








429
430
431


432








433
434
435
436
437
438









439
440
441
442
443
444
445
446
447
















































































































































448


449










































make overrides to the tk/macosx GNUmakefile, e.g.
	make -C tk${ver}/macosx \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
	sudo make -C tk${ver}/macosx install \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.














4. About the event loop in Tk for Mac OSX

-----------------------------------------




The main program in a typical OSX application looks like this (see *)



    void NSApplicationMain(int argc, char *argv[]) {
        [NSApplication sharedApplication];
        [NSBundle loadNibNamed:@"myMain" owner:NSApp];
        [NSApp run];
    }




The run method implements the event loop for the application.  There
are three key steps in the run method.  First it calls
[NSApp finishLaunching], which creates the bouncing application icon
and does other mysterious things. Second it creates an
NSAutoreleasePool.  Third, it starts an event loop which drains the
NSAutoreleasePool every time the queue is empty, and replaces the
drained pool with a new one.  This third step is essential to
preventing memory leaks, since the internal methods of Appkit objects
all assume that an autorelease pool is in scope and will be drained
when the event processing cycle ends.

Mac OSX Tk does not call the [NSApp run] method at all.  Instead it
uses the event loop built in to Tk.  So we must take care to replicate
the important features of the method ourselves.  Here is how this

works in outline.

We add a private NSAUtoreleasePool* property to our subclass of
NSApplication.  (The subclass is called TKApplication but can be
referenced with the global variable NSApp).  The TkpInit
function calls [NSApp _setup] which initializes this property by
creating an NSAutoreleasePool. A bit later on, TkpInit calls
[NSAPP _setupEventLoop] which in turn calls the


[NSApp finishLaunching] method.


Each time that Tcl processes an event in its queue, it calls a
platform specific function which, in the case of Mac OSX, is named

TkMacOSXEventsCheckProc.  In the unix implementations of Tk, including
the Mac OSX version, this function collects events from an "event








source", and transfers them to the Tcl event queue.  In Mac OSX the
event source is the NSApplication event queue.  Each NSEvent is
converted to a Tcl event which is added to the Tcl event queue.  The


NSEvent is also passed to [NSApp sendevent], which sends the event on








to the application's NSWindows, which send it to their NSViews, etc.
Since the CheckProc function gets called for every Tk event, it is an
appropriate place to drain the main NSAutoreleasePool and replace it
with a new pool.  This is done by calling the method
[NSApp _resetAutoreleasePool], where _resetAutoreleasePool is a method
which we define for the subclass TKApplication.










One minor caveat is that there are several steps of the Tk
initialization which precede the call to TkpInit.  Notably, the font
package is initialized first.  Since there is no NSAUtoreleasePool in
scope prior to calling TkpInit, the functions called in these
preliminary stages need to create and drain their own
NSAutoreleasePools whenever they call methods of Appkit objects
(e.g. NSFont).

















































































































































* https://developer.apple.com/library/mac/documentation/Cocoa/\


Reference/ApplicationKit/Classes/NSApplication_Class










































Deleted macosx/Tk-Common.xcconfig.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//
// Tk-Common.xcconfig --
//
//	This file contains the Xcode build settings comon to all
//	project configurations in Wish.xcodeproj.
//
// Copyright (c) 2007-2009 Daniel A. Steffen <das@users.sourceforge.net>
// Copyright 2008-2009, Apple Inc.
//
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

HEADER_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TK_SRCROOT)/xlib "$(DERIVED_FILE_DIR)/tcl" "$(DERIVED_FILE_DIR)/tk" $(HEADER_SEARCH_PATHS)
REZ_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TCL_SRCROOT)/generic $(REZ_SEARCH_PATHS)
OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __info_plist "$(DERIVED_FILE_DIR)/tk/Wish-Info.plist" $(OTHER_LDFLAGS)
OTHER_LDFLAGS_AQUA =
INSTALL_PATH = $(APPLICATION_INSTALL_PATH)
INSTALL_MODE_FLAG = go-w,a+rX
GCC_PREFIX_HEADER = $(DERIVED_FILE_DIR)/tk/tkConfig.h
OTHER_CFLAGS = -imacros "$(DERIVED_FILE_DIR)/tcl/tclConfig.h" $(OTHER_CFLAGS)
GCC_GENERATE_DEBUGGING_SYMBOLS = YES
GCC_NO_COMMON_BLOCKS = YES
GCC_DYNAMIC_NO_PIC = YES
GCC_VERSION = 4.2
GCC = gcc-$(GCC_VERSION)
WARNING_CFLAGS = -Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -Winit-self -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS)
REZ_RESOURCE_MAP_READ_ONLY = YES
APPLICATION_INSTALL_PATH = /Applications/Utilities
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
MANDIR = $(PREFIX)/man
PER_ARCH_CFLAGS_ppc = -mcpu=G3 -mtune=G4 $(PER_ARCH_CFLAGS_ppc)
PREFIX = /usr/local
TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects
TCL_CONFIGURE_ARGS = --enable-dtrace
TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION)
TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED
VERSION = 8.7
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































Deleted macosx/Tk-Debug.xcconfig.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
// Tk-Debug.xcconfig --
//
//	This file contains the Xcode build settings for all Debug
//	project configurations in Wish.xcodeproj.
//
// 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.

#include "Tk-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf
DEPLOYMENT_POSTPROCESSING = NO
GCC_OPTIMIZATION_LEVEL = 0
GCC_PREPROCESSOR_DEFINITIONS = DEBUGLEVEL=4 $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --enable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = develop
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Changes to macosx/Tk-Info.plist.in.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
	<key>CFBundleGetInfoString</key>
	<string>Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@@TK_PATCH_LEVEL@,
Copyright © 1989-@TK_YEAR@ Tcl Core Team,
Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
	Copyright © 1989-@TK_YEAR@ Contributors,
	Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech
	Communications LLC,
	Copyright © 2014-@TK_YEAR@ Marc Culler,
Copyright © 2001-2009 Apple Inc.,
Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
	<key>CFBundleIdentifier</key>
	<string>com.tcltk.tklibrary</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>







<







16
17
18
19
20
21
22

23
24
25
26
27
28
29
	<key>CFBundleGetInfoString</key>
	<string>Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@@TK_PATCH_LEVEL@,
Copyright © 1989-@TK_YEAR@ Tcl Core Team,
Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
	Copyright © 1989-@TK_YEAR@ Contributors,
	Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech
	Communications LLC,

Copyright © 2001-2009 Apple Inc.,
Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
	<key>CFBundleIdentifier</key>
	<string>com.tcltk.tklibrary</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>

Deleted macosx/Tk-Release.xcconfig.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
// Tk-Release.xcconfig --
//
//	This file contains the Xcode build settings for all Release
//	project configurations in Wish.xcodeproj.
//
// 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.

#include "Tk-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
// DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = s
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Deleted macosx/Tk.xcode/default.pbxuser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* Wish */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tk */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
			F944EB8F08F798100049FDD4 /* tktest */,
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f75708692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a0b707265666572656e63657386928497960892849a9a07666e6d617463688692849a9a008692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a0572656765788692849a9a065c2e286329248692849a9a097265637572736976658692848484084e534e756d626572008484074e5356616c7565009584012a849696018692849a9a0669734c656166869284b09db296008692849a9a0763616e536176658692af92849a9a1250425850726f6a65637453636f70654b65798692849a9a03594553868692849a9a08676c6f62616c49448692849a9a18314343304541343030343335304546393030343434313042868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			SYMROOT = "${SRCROOT}/../../build/tk";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
			TK_SRCROOT = "${SRCROOT}/../../tk";
		};
	};
	8DD76FA90486AB0100D96B5E /* tktest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tktest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tktest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = TK_SRCROOT;
				value = "${TK_SRCROOT}";
			},
			{
				active = NO;
				name = TK_CONSOLE;
				value = 1;
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = NSTraceEvents;
				value = YES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
			{
				active = NO;
				name = NSZombieEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSDeallocateZombies;
				value = YES;
			},
			{
				active = NO;
				name = NSAutoreleaseFreedObjectCheckEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSEnableAutoreleasePool;
				value = NO;
			},
			{
				active = NO;
				name = AUTO_LOG_ALL;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_LOG_NOISY;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_REFERENCE_COUNT_LOGGING;
				value = YES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tktest;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
			repositoryNamesForRoots = {
				.. = "";
			};
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F97258A50A86873C00096C78 /* tktest-X11 */ = {
		activeExec = 0;
		executables = (
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
	};
	F9E61D16090A3E94002B3151 /* Tk */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
		);
	};
	F9E61D1C090A4282002B3151 /* Wish */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = Wish;
		sourceDirectories = (
		);
	};
	F9FD31F50CC1AD070073837D /* tktest-X11 */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = DISPLAY;
				value = ":0";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = "tktest-X11";
		sourceDirectories = (
		);
	};
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































Deleted macosx/Tk.xcode/project.pbxproj.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 45;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
		F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F94523A10E6FC2AC00C1D987 /* Cocoa.framework */; };
		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F96437E80EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F966BDD308F27A3F005CB29B /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F966BDD508F27A3F005CB29B /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F966BDE508F27A3F005CB29B /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F966BDED08F27A3F005CB29B /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F966BDF208F27A3F005CB29B /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F966BDF508F27A3F005CB29B /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F966BDF708F27A3F005CB29B /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F966BE0908F27A3F005CB29B /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F966BE1008F27A3F005CB29B /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F966BE1208F27A3F005CB29B /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F966BE1308F27A3F005CB29B /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF408F27A39005CB29B /* tkPointer.c */; };
		F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F966BE2008F27A40005CB29B /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F966BE2408F27A40005CB29B /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F966BE2508F27A40005CB29B /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F966BE2608F27A40005CB29B /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F966BE3008F27A40005CB29B /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F966BE3108F27A40005CB29B /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F966BE3308F27A40005CB29B /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F966BE3408F27A40005CB29B /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F966BE3508F27A40005CB29B /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */; };
		F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */; };
		F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */; };
		F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */; };
		F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */; };
		F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */; };
		F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */; };
		F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */; };
		F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */; };
		F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */; };
		F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */; };
		F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */; };
		F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */; };
		F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */; };
		F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */; settings = {COMPILER_FLAGS = "-DTK_LIBRARY=\\\"$(TK_LIBRARY)\\\""; }; };
		F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */; };
		F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */; };
		F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */; };
		F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */; };
		F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */; };
		F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */; };
		F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */; };
		F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */; };
		F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */; };
		F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */; };
		F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */; };
		F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */; };
		F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */; };
		F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */; };
		F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */; };
		F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F966C02A08F27A42005CB29B /* xcolors.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2408F27A3F005CB29B /* xcolors.c */; };
		F966C02B08F27A42005CB29B /* xdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2508F27A3F005CB29B /* xdraw.c */; };
		F966C02C08F27A42005CB29B /* xgc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2608F27A3F005CB29B /* xgc.c */; };
		F966C02D08F27A42005CB29B /* ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2708F27A3F005CB29B /* ximage.c */; };
		F966C02E08F27A42005CB29B /* xutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2808F27A3F005CB29B /* xutil.c */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07608F2821B005CB29B /* Carbon.framework */; };
		F966C07908F28233005CB29B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07808F28233005CB29B /* IOKit.framework */; };
		F96888050AF786D5000797B5 /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F96888060AF786D5000797B5 /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F96888070AF786D5000797B5 /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F968880B0AF786D5000797B5 /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F968880E0AF786D5000797B5 /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F968880F0AF786D5000797B5 /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F96888100AF786D5000797B5 /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F96888110AF786D5000797B5 /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F96888120AF786D5000797B5 /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F96888150AF786D5000797B5 /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F96888160AF786D5000797B5 /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F96888170AF786D5000797B5 /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F968881B0AF786D5000797B5 /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F96888200AF786D5000797B5 /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F96888210AF786D5000797B5 /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F96888230AF786D5000797B5 /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888840AF78938000797B5 /* ttkMacOSXTheme.c */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */; };
		F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F9FD30BD0CC1AD070073837D /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F9FD30BE0CC1AD070073837D /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F9FD30BF0CC1AD070073837D /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F9FD30C50CC1AD070073837D /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F9FD30D50CC1AD070073837D /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F9FD30D60CC1AD070073837D /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F9FD30E00CC1AD070073837D /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F9FD30E40CC1AD070073837D /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F9FD30E70CC1AD070073837D /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F9FD30E90CC1AD070073837D /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F9FD30F00CC1AD070073837D /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F9FD30F30CC1AD070073837D /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F9FD30F40CC1AD070073837D /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F9FD30F90CC1AD070073837D /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F9FD31000CC1AD070073837D /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F9FD31010CC1AD070073837D /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F9FD31020CC1AD070073837D /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F9FD313F0CC1AD070073837D /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9FD314F0CC1AD070073837D /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F9FD31500CC1AD070073837D /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F9FD31510CC1AD070073837D /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F9FD31520CC1AD070073837D /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F9FD31540CC1AD070073837D /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F9FD31600CC1AD070073837D /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F9FD31610CC1AD070073837D /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F9FD31620CC1AD070073837D /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F9FD31630CC1AD070073837D /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F9FD31640CC1AD070073837D /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F9FD31650CC1AD070073837D /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F9FD31660CC1AD070073837D /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F9FD31670CC1AD070073837D /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F9FD31690CC1AD070073837D /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F9FD316A0CC1AD070073837D /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F9FD316C0CC1AD070073837D /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F9FD316E0CC1AD070073837D /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F9FD31700CC1AD070073837D /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F9FD31710CC1AD070073837D /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F9FD31760CC1AD070073837D /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F9FD31880CC1AD070073837D /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F9FD31890CC1AD070073837D /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F9FD318D0CC1AD070073837D /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F9FD318E0CC1AD070073837D /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F9FD31960CC1AD070073837D /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F9FD31970CC1AD070073837D /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F9FD31980CC1AD070073837D /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F9FD31990CC1AD070073837D /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F9FD31B10CC1AD070073837D /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */; };
		F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8708F27A3D005CB29B /* tkUnixKey.c */; };
		F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9108F27A3D005CB29B /* tkUnixXId.c */; };
		F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8508F27A3D005CB29B /* tkUnixInit.c */; };
		F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */; };
		F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8F08F27A3D005CB29B /* tkUnixSend.c */; };
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
		F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32150CC1AF170073837D /* libXext.dylib */; };
		F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32160CC1AF170073837D /* libXss.dylib */; };
		F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34990CC1BB0D0073837D /* libfreetype.dylib */; };
		F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD349A0CC1BB0D0073837D /* libXft.dylib */; };
		F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */; };
		F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tktest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tktest; sourceTree = BUILT_PRODUCTS_DIR; };
		F9099B8A0CC67D30005A9580 /* textpeer.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textpeer.tcl; sourceTree = "<group>"; };
		F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkbut.tcl; sourceTree = "<group>"; };
		F9152B080EAF8A5000CD5C7B /* tkBusy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBusy.c; sourceTree = "<group>"; };
		F91543270EF201A90032D1E8 /* fontchoose.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchoose.tcl; sourceTree = "<group>"; };
		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92240290D7C620F005EC715 /* knightstour.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = knightstour.tcl; sourceTree = "<group>"; };
		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
		F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhInstance.c; sourceTree = "<group>"; };
		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
		F936FCD70CCD984500716967 /* ttkprogress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkprogress.tcl; sourceTree = "<group>"; };
		F936FCD80CCD984600716967 /* tree.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tree.tcl; sourceTree = "<group>"; };
		F936FCD90CCD984600716967 /* toolbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = toolbar.tcl; sourceTree = "<group>"; };
		F936FCDA0CCD984600716967 /* ttknote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttknote.tcl; sourceTree = "<group>"; };
		F936FCDB0CCD984600716967 /* combo.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combo.tcl; sourceTree = "<group>"; };
		F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXFont.h; sourceTree = "<group>"; };
		F94523A10E6FC2AC00C1D987 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
		F95D8D4B0F1715610006B020 /* Tk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Tk.icns; sourceTree = "<group>"; };
		F95D8D4C0F1715610006B020 /* Tk.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Tk.tiff; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F962F7C60DADC26200648DB8 /* vsapi.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vsapi.test; sourceTree = "<group>"; };
		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
		F966BA0408F27A37005CB29B /* error.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = error.xbm; sourceTree = "<group>"; };
		F966BA0508F27A37005CB29B /* gray12.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray12.xbm; sourceTree = "<group>"; };
		F966BA0608F27A37005CB29B /* gray25.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray25.xbm; sourceTree = "<group>"; };
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
		F966BA1808F27A37005CB29B /* button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = button.n; sourceTree = "<group>"; };
		F966BA1908F27A37005CB29B /* canvas.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = canvas.n; sourceTree = "<group>"; };
		F966BA1A08F27A37005CB29B /* CanvPsY.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvPsY.3; sourceTree = "<group>"; };
		F966BA1B08F27A37005CB29B /* CanvTkwin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTkwin.3; sourceTree = "<group>"; };
		F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTxtInfo.3; sourceTree = "<group>"; };
		F966BA1D08F27A37005CB29B /* checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = checkbutton.n; sourceTree = "<group>"; };
		F966BA1E08F27A37005CB29B /* chooseColor.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseColor.n; sourceTree = "<group>"; };
		F966BA1F08F27A37005CB29B /* chooseDirectory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseDirectory.n; sourceTree = "<group>"; };
		F966BA2008F27A37005CB29B /* Clipboard.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Clipboard.3; sourceTree = "<group>"; };
		F966BA2108F27A37005CB29B /* clipboard.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clipboard.n; sourceTree = "<group>"; };
		F966BA2208F27A37005CB29B /* ClrSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ClrSelect.3; sourceTree = "<group>"; };
		F966BA2308F27A37005CB29B /* colors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = colors.n; sourceTree = "<group>"; };
		F966BA2408F27A37005CB29B /* ConfigWidg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWidg.3; sourceTree = "<group>"; };
		F966BA2508F27A37005CB29B /* ConfigWind.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWind.3; sourceTree = "<group>"; };
		F966BA2608F27A37005CB29B /* console.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = console.n; sourceTree = "<group>"; };
		F966BA2708F27A37005CB29B /* CoordToWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CoordToWin.3; sourceTree = "<group>"; };
		F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCmHdlr.3; sourceTree = "<group>"; };
		F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtErrHdlr.3; sourceTree = "<group>"; };
		F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtGenHdlr.3; sourceTree = "<group>"; };
		F966BA2B08F27A37005CB29B /* CrtImgType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtImgType.3; sourceTree = "<group>"; };
		F966BA2C08F27A37005CB29B /* CrtItemType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtItemType.3; sourceTree = "<group>"; };
		F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtPhImgFmt.3; sourceTree = "<group>"; };
		F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSelHdlr.3; sourceTree = "<group>"; };
		F966BA2F08F27A37005CB29B /* CrtWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtWindow.3; sourceTree = "<group>"; };
		F966BA3008F27A37005CB29B /* cursors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cursors.n; sourceTree = "<group>"; };
		F966BA3108F27A37005CB29B /* DeleteImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DeleteImg.3; sourceTree = "<group>"; };
		F966BA3208F27A37005CB29B /* destroy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = destroy.n; sourceTree = "<group>"; };
		F966BA3308F27A37005CB29B /* dialog.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dialog.n; sourceTree = "<group>"; };
		F966BA3408F27A37005CB29B /* DrawFocHlt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DrawFocHlt.3; sourceTree = "<group>"; };
		F966BA3508F27A37005CB29B /* entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = entry.n; sourceTree = "<group>"; };
		F966BA3608F27A37005CB29B /* event.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = event.n; sourceTree = "<group>"; };
		F966BA3708F27A37005CB29B /* EventHndlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = EventHndlr.3; sourceTree = "<group>"; };
		F966BA3808F27A37005CB29B /* FindPhoto.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindPhoto.3; sourceTree = "<group>"; };
		F966BA3908F27A37005CB29B /* focus.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focus.n; sourceTree = "<group>"; };
		F966BA3A08F27A37005CB29B /* focusNext.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focusNext.n; sourceTree = "<group>"; };
		F966BA3B08F27A37005CB29B /* font.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = font.n; sourceTree = "<group>"; };
		F966BA3C08F27A37005CB29B /* FontId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FontId.3; sourceTree = "<group>"; };
		F966BA3D08F27A37005CB29B /* frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = frame.n; sourceTree = "<group>"; };
		F966BA3E08F27A37005CB29B /* FreeXId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FreeXId.3; sourceTree = "<group>"; };
		F966BA3F08F27A37005CB29B /* GeomReq.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GeomReq.3; sourceTree = "<group>"; };
		F966BA4008F27A37005CB29B /* GetAnchor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetAnchor.3; sourceTree = "<group>"; };
		F966BA4108F27A37005CB29B /* GetBitmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetBitmap.3; sourceTree = "<group>"; };
		F966BA4208F27A37005CB29B /* GetCapStyl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCapStyl.3; sourceTree = "<group>"; };
		F966BA4308F27A37005CB29B /* GetClrmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetClrmap.3; sourceTree = "<group>"; };
		F966BA4408F27A37005CB29B /* GetColor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetColor.3; sourceTree = "<group>"; };
		F966BA4508F27A37005CB29B /* GetCursor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCursor.3; sourceTree = "<group>"; };
		F966BA4608F27A37005CB29B /* GetDash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetDash.3; sourceTree = "<group>"; };
		F966BA4708F27A37005CB29B /* GetFont.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetFont.3; sourceTree = "<group>"; };
		F966BA4808F27A37005CB29B /* GetGC.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetGC.3; sourceTree = "<group>"; };
		F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHINSTANCE.3; sourceTree = "<group>"; };
		F966BA4A08F27A37005CB29B /* GetHWND.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHWND.3; sourceTree = "<group>"; };
		F966BA4B08F27A37005CB29B /* GetImage.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetImage.3; sourceTree = "<group>"; };
		F966BA4C08F27A37005CB29B /* GetJoinStl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJoinStl.3; sourceTree = "<group>"; };
		F966BA4D08F27A37005CB29B /* GetJustify.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJustify.3; sourceTree = "<group>"; };
		F966BA4E08F27A37005CB29B /* getOpenFile.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = getOpenFile.n; sourceTree = "<group>"; };
		F966BA4F08F27A37005CB29B /* GetOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOption.3; sourceTree = "<group>"; };
		F966BA5008F27A38005CB29B /* GetPixels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixels.3; sourceTree = "<group>"; };
		F966BA5108F27A38005CB29B /* GetPixmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixmap.3; sourceTree = "<group>"; };
		F966BA5208F27A38005CB29B /* GetRelief.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRelief.3; sourceTree = "<group>"; };
		F966BA5308F27A38005CB29B /* GetRootCrd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRootCrd.3; sourceTree = "<group>"; };
		F966BA5408F27A38005CB29B /* GetScroll.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetScroll.3; sourceTree = "<group>"; };
		F966BA5508F27A38005CB29B /* GetSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetSelect.3; sourceTree = "<group>"; };
		F966BA5608F27A38005CB29B /* GetUid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetUid.3; sourceTree = "<group>"; };
		F966BA5708F27A38005CB29B /* GetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVisual.3; sourceTree = "<group>"; };
		F966BA5808F27A38005CB29B /* GetVRoot.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVRoot.3; sourceTree = "<group>"; };
		F966BA5908F27A38005CB29B /* Grab.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Grab.3; sourceTree = "<group>"; };
		F966BA5A08F27A38005CB29B /* grab.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grab.n; sourceTree = "<group>"; };
		F966BA5B08F27A38005CB29B /* grid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grid.n; sourceTree = "<group>"; };
		F966BA5C08F27A38005CB29B /* HandleEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HandleEvent.3; sourceTree = "<group>"; };
		F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HWNDToWindow.3; sourceTree = "<group>"; };
		F966BA5E08F27A38005CB29B /* IdToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IdToWindow.3; sourceTree = "<group>"; };
		F966BA5F08F27A38005CB29B /* image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = image.n; sourceTree = "<group>"; };
		F966BA6008F27A38005CB29B /* ImgChanged.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ImgChanged.3; sourceTree = "<group>"; };
		F966BA6108F27A38005CB29B /* Inactive.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Inactive.3; sourceTree = "<group>"; };
		F966BA6208F27A38005CB29B /* InternAtom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InternAtom.3; sourceTree = "<group>"; };
		F966BA6308F27A38005CB29B /* keysyms.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = keysyms.n; sourceTree = "<group>"; };
		F966BA6408F27A38005CB29B /* label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = label.n; sourceTree = "<group>"; };
		F966BA6508F27A38005CB29B /* labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = labelframe.n; sourceTree = "<group>"; };
		F966BA6608F27A38005CB29B /* listbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = listbox.n; sourceTree = "<group>"; };
		F966BA6708F27A38005CB29B /* loadTk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = loadTk.n; sourceTree = "<group>"; };
		F966BA6808F27A38005CB29B /* lower.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lower.n; sourceTree = "<group>"; };
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
		F966BA8408F27A38005CB29B /* QWinEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = QWinEvent.3; sourceTree = "<group>"; };
		F966BA8508F27A38005CB29B /* radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = radiobutton.n; sourceTree = "<group>"; };
		F966BA8608F27A38005CB29B /* raise.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = raise.n; sourceTree = "<group>"; };
		F966BA8708F27A38005CB29B /* Restack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Restack.3; sourceTree = "<group>"; };
		F966BA8808F27A38005CB29B /* RestrictEv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RestrictEv.3; sourceTree = "<group>"; };
		F966BA8908F27A38005CB29B /* scale.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scale.n; sourceTree = "<group>"; };
		F966BA8A08F27A38005CB29B /* scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scrollbar.n; sourceTree = "<group>"; };
		F966BA8B08F27A38005CB29B /* selection.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = selection.n; sourceTree = "<group>"; };
		F966BA8C08F27A38005CB29B /* send.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = send.n; sourceTree = "<group>"; };
		F966BA8D08F27A38005CB29B /* SetAppName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetAppName.3; sourceTree = "<group>"; };
		F966BA8E08F27A38005CB29B /* SetCaret.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetCaret.3; sourceTree = "<group>"; };
		F966BA8F08F27A38005CB29B /* SetClass.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClass.3; sourceTree = "<group>"; };
		F966BA9008F27A38005CB29B /* SetClassProcs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClassProcs.3; sourceTree = "<group>"; };
		F966BA9108F27A38005CB29B /* SetGrid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetGrid.3; sourceTree = "<group>"; };
		F966BA9208F27A38005CB29B /* SetOptions.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetOptions.3; sourceTree = "<group>"; };
		F966BA9308F27A38005CB29B /* SetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVisual.3; sourceTree = "<group>"; };
		F966BA9408F27A38005CB29B /* spinbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = spinbox.n; sourceTree = "<group>"; };
		F966BA9508F27A38005CB29B /* StrictMotif.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrictMotif.3; sourceTree = "<group>"; };
		F966BA9608F27A38005CB29B /* text.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = text.n; sourceTree = "<group>"; };
		F966BA9708F27A38005CB29B /* TextLayout.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TextLayout.3; sourceTree = "<group>"; };
		F966BA9808F27A38005CB29B /* tk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tk.n; sourceTree = "<group>"; };
		F966BA9A08F27A38005CB29B /* Tk_Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Init.3; sourceTree = "<group>"; };
		F966BA9B08F27A38005CB29B /* Tk_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Main.3; sourceTree = "<group>"; };
		F966BA9C08F27A38005CB29B /* tkerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkerror.n; sourceTree = "<group>"; };
		F966BA9D08F27A38005CB29B /* TkInitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TkInitStubs.3; sourceTree = "<group>"; };
		F966BA9E08F27A38005CB29B /* tkvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkvars.n; sourceTree = "<group>"; };
		F966BA9F08F27A38005CB29B /* tkwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkwait.n; sourceTree = "<group>"; };
		F966BAA008F27A38005CB29B /* toplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = toplevel.n; sourceTree = "<group>"; };
		F966BAA108F27A38005CB29B /* WindowId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WindowId.3; sourceTree = "<group>"; };
		F966BAA208F27A38005CB29B /* winfo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = winfo.n; sourceTree = "<group>"; };
		F966BAA308F27A38005CB29B /* wish.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wish.1; sourceTree = "<group>"; };
		F966BAA408F27A38005CB29B /* wm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wm.n; sourceTree = "<group>"; };
		F966BAA608F27A38005CB29B /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = "<group>"; };
		F966BAA708F27A38005CB29B /* ks_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ks_names.h; sourceTree = "<group>"; };
		F966BAA908F27A39005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BAAA08F27A39005CB29B /* tk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.decls; sourceTree = "<group>"; };
		F966BAAB08F27A39005CB29B /* tk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk.h; sourceTree = "<group>"; };
		F966BAAC08F27A39005CB29B /* tk3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tk3d.c; sourceTree = "<group>"; };
		F966BAAD08F27A39005CB29B /* tk3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk3d.h; sourceTree = "<group>"; };
		F966BAAE08F27A39005CB29B /* tkArgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkArgv.c; sourceTree = "<group>"; };
		F966BAAF08F27A39005CB29B /* tkAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAtom.c; sourceTree = "<group>"; };
		F966BAB008F27A39005CB29B /* tkBind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBind.c; sourceTree = "<group>"; };
		F966BAB108F27A39005CB29B /* tkBitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBitmap.c; sourceTree = "<group>"; };
		F966BAB208F27A39005CB29B /* tkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkButton.c; sourceTree = "<group>"; };
		F966BAB308F27A39005CB29B /* tkButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkButton.h; sourceTree = "<group>"; };
		F966BAB408F27A39005CB29B /* tkCanvArc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvArc.c; sourceTree = "<group>"; };
		F966BAB508F27A39005CB29B /* tkCanvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvas.c; sourceTree = "<group>"; };
		F966BAB608F27A39005CB29B /* tkCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkCanvas.h; sourceTree = "<group>"; };
		F966BAB708F27A39005CB29B /* tkCanvBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvBmap.c; sourceTree = "<group>"; };
		F966BAB808F27A39005CB29B /* tkCanvImg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvImg.c; sourceTree = "<group>"; };
		F966BAB908F27A39005CB29B /* tkCanvLine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvLine.c; sourceTree = "<group>"; };
		F966BABA08F27A39005CB29B /* tkCanvPoly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPoly.c; sourceTree = "<group>"; };
		F966BABB08F27A39005CB29B /* tkCanvPs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPs.c; sourceTree = "<group>"; };
		F966BABD08F27A39005CB29B /* tkCanvText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvText.c; sourceTree = "<group>"; };
		F966BABE08F27A39005CB29B /* tkCanvUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvUtil.c; sourceTree = "<group>"; };
		F966BABF08F27A39005CB29B /* tkCanvWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvWind.c; sourceTree = "<group>"; };
		F966BAC008F27A39005CB29B /* tkClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkClipboard.c; sourceTree = "<group>"; };
		F966BAC108F27A39005CB29B /* tkCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCmds.c; sourceTree = "<group>"; };
		F966BAC208F27A39005CB29B /* tkColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkColor.c; sourceTree = "<group>"; };
		F966BAC308F27A39005CB29B /* tkColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkColor.h; sourceTree = "<group>"; };
		F966BAC408F27A39005CB29B /* tkConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConfig.c; sourceTree = "<group>"; };
		F966BAC508F27A39005CB29B /* tkConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConsole.c; sourceTree = "<group>"; };
		F966BAC608F27A39005CB29B /* tkCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCursor.c; sourceTree = "<group>"; };
		F966BAC708F27A39005CB29B /* tkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkDecls.h; sourceTree = "<group>"; };
		F966BAC808F27A39005CB29B /* tkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEntry.c; sourceTree = "<group>"; };
		F966BAC908F27A39005CB29B /* tkEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkEntry.h; sourceTree = "<group>"; };
		F966BACA08F27A39005CB29B /* tkError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkError.c; sourceTree = "<group>"; };
		F966BACB08F27A39005CB29B /* tkEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEvent.c; sourceTree = "<group>"; };
		F966BACC08F27A39005CB29B /* tkFileFilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFileFilter.c; sourceTree = "<group>"; };
		F966BACD08F27A39005CB29B /* tkFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFileFilter.h; sourceTree = "<group>"; };
		F966BACE08F27A39005CB29B /* tkFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFocus.c; sourceTree = "<group>"; };
		F966BACF08F27A39005CB29B /* tkFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFont.c; sourceTree = "<group>"; };
		F966BAD008F27A39005CB29B /* tkFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFont.h; sourceTree = "<group>"; };
		F966BAD108F27A39005CB29B /* tkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFrame.c; sourceTree = "<group>"; };
		F966BAD208F27A39005CB29B /* tkGC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGC.c; sourceTree = "<group>"; };
		F966BAD308F27A39005CB29B /* tkGeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGeometry.c; sourceTree = "<group>"; };
		F966BAD408F27A39005CB29B /* tkGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGet.c; sourceTree = "<group>"; };
		F966BAD508F27A39005CB29B /* tkGrab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrab.c; sourceTree = "<group>"; };
		F966BAD608F27A39005CB29B /* tkGrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrid.c; sourceTree = "<group>"; };
		F966BAD708F27A39005CB29B /* tkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImage.c; sourceTree = "<group>"; };
		F966BAD808F27A39005CB29B /* tkImgBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgBmap.c; sourceTree = "<group>"; };
		F966BAD908F27A39005CB29B /* tkImgGIF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgGIF.c; sourceTree = "<group>"; };
		F966BADA08F27A39005CB29B /* tkImgPhoto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhoto.c; sourceTree = "<group>"; };
		F966BADB08F27A39005CB29B /* tkImgPPM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPPM.c; sourceTree = "<group>"; };
		F966BADC08F27A39005CB29B /* tkImgUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgUtil.c; sourceTree = "<group>"; };
		F966BADE08F27A39005CB29B /* tkInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkInt.decls; sourceTree = "<group>"; };
		F966BADF08F27A39005CB29B /* tkInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkInt.h; sourceTree = "<group>"; };
		F966BAE108F27A39005CB29B /* tkIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntDecls.h; sourceTree = "<group>"; };
		F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntPlatDecls.h; sourceTree = "<group>"; };
		F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntXlibDecls.h; sourceTree = "<group>"; };
		F966BAE408F27A39005CB29B /* tkListbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkListbox.c; sourceTree = "<group>"; };
		F966BAE508F27A39005CB29B /* tkMacWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacWinMenu.c; sourceTree = "<group>"; };
		F966BAE608F27A39005CB29B /* tkMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMain.c; sourceTree = "<group>"; };
		F966BAE708F27A39005CB29B /* tkMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenu.c; sourceTree = "<group>"; };
		F966BAE808F27A39005CB29B /* tkMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenu.h; sourceTree = "<group>"; };
		F966BAE908F27A39005CB29B /* tkMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenubutton.c; sourceTree = "<group>"; };
		F966BAEA08F27A39005CB29B /* tkMenubutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenubutton.h; sourceTree = "<group>"; };
		F966BAEB08F27A39005CB29B /* tkMenuDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenuDraw.c; sourceTree = "<group>"; };
		F966BAEC08F27A39005CB29B /* tkMessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMessage.c; sourceTree = "<group>"; };
		F966BAED08F27A39005CB29B /* tkObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkObj.c; sourceTree = "<group>"; };
		F966BAEE08F27A39005CB29B /* tkOldConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldConfig.c; sourceTree = "<group>"; };
		F966BAEF08F27A39005CB29B /* tkOption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOption.c; sourceTree = "<group>"; };
		F966BAF008F27A39005CB29B /* tkPack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPack.c; sourceTree = "<group>"; };
		F966BAF108F27A39005CB29B /* tkPanedWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPanedWindow.c; sourceTree = "<group>"; };
		F966BAF208F27A39005CB29B /* tkPlace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPlace.c; sourceTree = "<group>"; };
		F966BAF308F27A39005CB29B /* tkPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPlatDecls.h; sourceTree = "<group>"; };
		F966BAF408F27A39005CB29B /* tkPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPointer.c; sourceTree = "<group>"; };
		F966BAF508F27A39005CB29B /* tkPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPort.h; sourceTree = "<group>"; };
		F966BAF608F27A39005CB29B /* tkRectOval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkRectOval.c; sourceTree = "<group>"; };
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
		F966BB0608F27A39005CB29B /* tkTextDisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextDisp.c; sourceTree = "<group>"; };
		F966BB0808F27A39005CB29B /* tkTextImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextImage.c; sourceTree = "<group>"; };
		F966BB0908F27A39005CB29B /* tkTextIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextIndex.c; sourceTree = "<group>"; };
		F966BB0A08F27A39005CB29B /* tkTextMark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextMark.c; sourceTree = "<group>"; };
		F966BB0B08F27A39005CB29B /* tkTextTag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextTag.c; sourceTree = "<group>"; };
		F966BB0C08F27A39005CB29B /* tkTextWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextWind.c; sourceTree = "<group>"; };
		F966BB0D08F27A39005CB29B /* tkTrig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTrig.c; sourceTree = "<group>"; };
		F966BB0E08F27A39005CB29B /* tkUndo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUndo.c; sourceTree = "<group>"; };
		F966BB0F08F27A39005CB29B /* tkUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUndo.h; sourceTree = "<group>"; };
		F966BB1008F27A39005CB29B /* tkUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUtil.c; sourceTree = "<group>"; };
		F966BB1108F27A39005CB29B /* tkVisual.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkVisual.c; sourceTree = "<group>"; };
		F966BB1208F27A39005CB29B /* tkWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWindow.c; sourceTree = "<group>"; };
		F966BB1408F27A39005CB29B /* bgerror.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.tcl; sourceTree = "<group>"; };
		F966BB1508F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB1608F27A39005CB29B /* choosedir.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.tcl; sourceTree = "<group>"; };
		F966BB1708F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB1808F27A39005CB29B /* comdlg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = comdlg.tcl; sourceTree = "<group>"; };
		F966BB1908F27A39005CB29B /* console.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = console.tcl; sourceTree = "<group>"; };
		F966BB1B08F27A39005CB29B /* anilabel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = anilabel.tcl; sourceTree = "<group>"; };
		F966BB1C08F27A39005CB29B /* aniwave.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aniwave.tcl; sourceTree = "<group>"; };
		F966BB1D08F27A39005CB29B /* arrow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arrow.tcl; sourceTree = "<group>"; };
		F966BB1E08F27A39005CB29B /* bind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.tcl; sourceTree = "<group>"; };
		F966BB1F08F27A39005CB29B /* bitmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.tcl; sourceTree = "<group>"; };
		F966BB2008F27A39005CB29B /* browse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = browse; sourceTree = "<group>"; };
		F966BB2108F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB2208F27A39005CB29B /* check.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = check.tcl; sourceTree = "<group>"; };
		F966BB2308F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB2408F27A39005CB29B /* colors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = colors.tcl; sourceTree = "<group>"; };
		F966BB2508F27A39005CB29B /* cscroll.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cscroll.tcl; sourceTree = "<group>"; };
		F966BB2608F27A39005CB29B /* ctext.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ctext.tcl; sourceTree = "<group>"; };
		F966BB2708F27A39005CB29B /* dialog1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog1.tcl; sourceTree = "<group>"; };
		F966BB2808F27A39005CB29B /* dialog2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog2.tcl; sourceTree = "<group>"; };
		F966BB2A08F27A39005CB29B /* entry1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry1.tcl; sourceTree = "<group>"; };
		F966BB2B08F27A39005CB29B /* entry2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry2.tcl; sourceTree = "<group>"; };
		F966BB2C08F27A39005CB29B /* entry3.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry3.tcl; sourceTree = "<group>"; };
		F966BB2D08F27A39005CB29B /* filebox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.tcl; sourceTree = "<group>"; };
		F966BB2E08F27A39005CB29B /* floor.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = floor.tcl; sourceTree = "<group>"; };
		F966BB2F08F27A39005CB29B /* form.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = form.tcl; sourceTree = "<group>"; };
		F966BB3008F27A39005CB29B /* goldberg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = goldberg.tcl; sourceTree = "<group>"; };
		F966BB3108F27A39005CB29B /* hello */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = hello; sourceTree = "<group>"; };
		F966BB3208F27A39005CB29B /* hscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = hscale.tcl; sourceTree = "<group>"; };
		F966BB3308F27A39005CB29B /* icon.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icon.tcl; sourceTree = "<group>"; };
		F966BB3408F27A39005CB29B /* image1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image1.tcl; sourceTree = "<group>"; };
		F966BB3508F27A39005CB29B /* image2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image2.tcl; sourceTree = "<group>"; };
		F966BB4208F27A3A005CB29B /* items.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = items.tcl; sourceTree = "<group>"; };
		F966BB4308F27A3A005CB29B /* ixset */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ixset; sourceTree = "<group>"; };
		F966BB4408F27A3A005CB29B /* label.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = label.tcl; sourceTree = "<group>"; };
		F966BB4508F27A3A005CB29B /* labelframe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.tcl; sourceTree = "<group>"; };
		F966BB4608F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB4708F27A3A005CB29B /* menubu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubu.tcl; sourceTree = "<group>"; };
		F966BB4808F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB4A08F27A3A005CB29B /* paned1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned1.tcl; sourceTree = "<group>"; };
		F966BB4B08F27A3A005CB29B /* paned2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned2.tcl; sourceTree = "<group>"; };
		F966BB4C08F27A3A005CB29B /* pendulum.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pendulum.tcl; sourceTree = "<group>"; };
		F966BB4D08F27A3A005CB29B /* plot.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = plot.tcl; sourceTree = "<group>"; };
		F966BB4E08F27A3A005CB29B /* puzzle.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = puzzle.tcl; sourceTree = "<group>"; };
		F966BB4F08F27A3A005CB29B /* radio.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radio.tcl; sourceTree = "<group>"; };
		F966BB5008F27A3A005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BB5108F27A3A005CB29B /* rmt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rmt; sourceTree = "<group>"; };
		F966BB5208F27A3A005CB29B /* rolodex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rolodex; sourceTree = "<group>"; };
		F966BB5308F27A3A005CB29B /* ruler.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ruler.tcl; sourceTree = "<group>"; };
		F966BB5408F27A3A005CB29B /* sayings.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sayings.tcl; sourceTree = "<group>"; };
		F966BB5508F27A3A005CB29B /* search.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = search.tcl; sourceTree = "<group>"; };
		F966BB5608F27A3A005CB29B /* spin.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spin.tcl; sourceTree = "<group>"; };
		F966BB5708F27A3A005CB29B /* square */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = square; sourceTree = "<group>"; };
		F966BB5808F27A3A005CB29B /* states.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = states.tcl; sourceTree = "<group>"; };
		F966BB5908F27A3A005CB29B /* style.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = style.tcl; sourceTree = "<group>"; };
		F966BB5A08F27A3A005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB5B08F27A3A005CB29B /* tcolor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tcolor; sourceTree = "<group>"; };
		F966BB5C08F27A3A005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB5D08F27A3A005CB29B /* timer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = timer; sourceTree = "<group>"; };
		F966BB5E08F27A3A005CB29B /* twind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = twind.tcl; sourceTree = "<group>"; };
		F966BB5F08F27A3A005CB29B /* unicodeout.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unicodeout.tcl; sourceTree = "<group>"; };
		F966BB6008F27A3A005CB29B /* vscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vscale.tcl; sourceTree = "<group>"; };
		F966BB6108F27A3A005CB29B /* widget */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = widget; sourceTree = "<group>"; };
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
		F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXBitmap.c; sourceTree = "<group>"; };
		F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXButton.c; sourceTree = "<group>"; };
		F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXClipboard.c; sourceTree = "<group>"; };
		F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXColor.c; sourceTree = "<group>"; };
		F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXConfig.c; sourceTree = "<group>"; };
		F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXCursor.c; sourceTree = "<group>"; };
		F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXCursors.h; sourceTree = "<group>"; };
		F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDebug.c; sourceTree = "<group>"; };
		F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDebug.h; sourceTree = "<group>"; };
		F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDefault.h; sourceTree = "<group>"; };
		F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDialog.c; sourceTree = "<group>"; };
		F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDraw.c; sourceTree = "<group>"; };
		F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEmbed.c; sourceTree = "<group>"; };
		F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEntry.c; sourceTree = "<group>"; };
		F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEvent.c; sourceTree = "<group>"; };
		F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXFont.c; sourceTree = "<group>"; };
		F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXHLEvents.c; sourceTree = "<group>"; };
		F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXInit.c; sourceTree = "<group>"; };
		F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXInt.h; sourceTree = "<group>"; };
		F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; };
		F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; };
		F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenu.c; sourceTree = "<group>"; };
		F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; };
		F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenus.c; sourceTree = "<group>"; };
		F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; };
		F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXNotify.c; sourceTree = "<group>"; };
		F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPort.h; sourceTree = "<group>"; };
		F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXRegion.c; sourceTree = "<group>"; };
		F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScale.c; sourceTree = "<group>"; };
		F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScrlbr.c; sourceTree = "<group>"; };
		F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSend.c; sourceTree = "<group>"; };
		F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSubwindows.c; sourceTree = "<group>"; };
		F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXTest.c; sourceTree = "<group>"; };
		F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWindowEvent.c; sourceTree = "<group>"; };
		F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWm.c; sourceTree = "<group>"; };
		F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXWm.h; sourceTree = "<group>"; };
		F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXXCursors.h; sourceTree = "<group>"; };
		F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXXStubs.c; sourceTree = "<group>"; };
		F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Wish-Info.plist.in"; sourceTree = "<group>"; };
		F966BC0308F27A3C005CB29B /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F966BC0508F27A3C005CB29B /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F966BC0608F27A3C005CB29B /* arc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arc.tcl; sourceTree = "<group>"; };
		F966BC0708F27A3C005CB29B /* bell.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bell.test; sourceTree = "<group>"; };
		F966BC0808F27A3C005CB29B /* bevel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bevel.tcl; sourceTree = "<group>"; };
		F966BC0908F27A3C005CB29B /* bgerror.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.test; sourceTree = "<group>"; };
		F966BC0A08F27A3C005CB29B /* bind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.test; sourceTree = "<group>"; };
		F966BC0B08F27A3C005CB29B /* bitmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.test; sourceTree = "<group>"; };
		F966BC0C08F27A3C005CB29B /* border.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = border.test; sourceTree = "<group>"; };
		F966BC0D08F27A3C005CB29B /* bugs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bugs.tcl; sourceTree = "<group>"; };
		F966BC0E08F27A3C005CB29B /* butGeom.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom.tcl; sourceTree = "<group>"; };
		F966BC0F08F27A3C005CB29B /* butGeom2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom2.tcl; sourceTree = "<group>"; };
		F966BC1008F27A3C005CB29B /* button.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.test; sourceTree = "<group>"; };
		F966BC1108F27A3C005CB29B /* canvas.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvas.test; sourceTree = "<group>"; };
		F966BC1208F27A3C005CB29B /* canvImg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvImg.test; sourceTree = "<group>"; };
		F966BC1308F27A3C005CB29B /* canvPs.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPs.test; sourceTree = "<group>"; };
		F966BC1408F27A3C005CB29B /* canvPsArc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsArc.tcl; sourceTree = "<group>"; };
		F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsBmap.tcl; sourceTree = "<group>"; };
		F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsGrph.tcl; sourceTree = "<group>"; };
		F966BC1708F27A3C005CB29B /* canvPsImg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsImg.tcl; sourceTree = "<group>"; };
		F966BC1808F27A3C005CB29B /* canvPsText.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsText.tcl; sourceTree = "<group>"; };
		F966BC1908F27A3C005CB29B /* canvRect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvRect.test; sourceTree = "<group>"; };
		F966BC1A08F27A3C005CB29B /* canvText.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvText.test; sourceTree = "<group>"; };
		F966BC1B08F27A3C005CB29B /* canvWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvWind.test; sourceTree = "<group>"; };
		F966BC1C08F27A3C005CB29B /* choosedir.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.test; sourceTree = "<group>"; };
		F966BC1D08F27A3C005CB29B /* clipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clipboard.test; sourceTree = "<group>"; };
		F966BC1E08F27A3C005CB29B /* clrpick.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.test; sourceTree = "<group>"; };
		F966BC1F08F27A3C005CB29B /* cmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmap.tcl; sourceTree = "<group>"; };
		F966BC2008F27A3C005CB29B /* cmds.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmds.test; sourceTree = "<group>"; };
		F966BC2108F27A3C005CB29B /* color.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = color.test; sourceTree = "<group>"; };
		F966BC2208F27A3C005CB29B /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F966BC2308F27A3C005CB29B /* constraints.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = constraints.tcl; sourceTree = "<group>"; };
		F966BC2408F27A3C005CB29B /* cursor.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursor.test; sourceTree = "<group>"; };
		F966BC2508F27A3C005CB29B /* dialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.test; sourceTree = "<group>"; };
		F966BC2608F27A3C005CB29B /* embed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = embed.test; sourceTree = "<group>"; };
		F966BC2708F27A3C005CB29B /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F966BC2808F27A3C005CB29B /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F966BC2908F27A3C005CB29B /* filebox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.test; sourceTree = "<group>"; };
		F966BC2A08F27A3C005CB29B /* focus.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.test; sourceTree = "<group>"; };
		F966BC2B08F27A3C005CB29B /* focusTcl.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focusTcl.test; sourceTree = "<group>"; };
		F966BC2C08F27A3C005CB29B /* font.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = font.test; sourceTree = "<group>"; };
		F966BC2D08F27A3C005CB29B /* frame.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = frame.test; sourceTree = "<group>"; };
		F966BC2E08F27A3C005CB29B /* geometry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = geometry.test; sourceTree = "<group>"; };
		F966BC2F08F27A3C005CB29B /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F966BC3008F27A3C005CB29B /* grab.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grab.test; sourceTree = "<group>"; };
		F966BC3108F27A3C005CB29B /* grid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grid.test; sourceTree = "<group>"; };
		F966BC3308F27A3C005CB29B /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F966BC3408F27A3C005CB29B /* imgBmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgBmap.test; sourceTree = "<group>"; };
		F966BC3508F27A3C005CB29B /* imgPhoto.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPhoto.test; sourceTree = "<group>"; };
		F966BC3608F27A3C005CB29B /* imgPPM.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPPM.test; sourceTree = "<group>"; };
		F966BC3708F27A3C005CB29B /* listbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.test; sourceTree = "<group>"; };
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
		F966BC4708F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC4808F27A3D005CB29B /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F966BC4908F27A3D005CB29B /* scale.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.test; sourceTree = "<group>"; };
		F966BC4A08F27A3D005CB29B /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F966BC4B08F27A3D005CB29B /* select.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = select.test; sourceTree = "<group>"; };
		F966BC4C08F27A3D005CB29B /* send.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = send.test; sourceTree = "<group>"; };
		F966BC4D08F27A3D005CB29B /* spinbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.test; sourceTree = "<group>"; };
		F966BC4E08F27A3D005CB29B /* text.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.test; sourceTree = "<group>"; };
		F966BC4F08F27A3D005CB29B /* textBTree.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textBTree.test; sourceTree = "<group>"; };
		F966BC5008F27A3D005CB29B /* textDisp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textDisp.test; sourceTree = "<group>"; };
		F966BC5108F27A3D005CB29B /* textImage.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textImage.test; sourceTree = "<group>"; };
		F966BC5208F27A3D005CB29B /* textIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textIndex.test; sourceTree = "<group>"; };
		F966BC5308F27A3D005CB29B /* textMark.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textMark.test; sourceTree = "<group>"; };
		F966BC5408F27A3D005CB29B /* textTag.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textTag.test; sourceTree = "<group>"; };
		F966BC5508F27A3D005CB29B /* textWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textWind.test; sourceTree = "<group>"; };
		F966BC5608F27A3D005CB29B /* tk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.test; sourceTree = "<group>"; };
		F966BC5708F27A3D005CB29B /* unixButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixButton.test; sourceTree = "<group>"; };
		F966BC5808F27A3D005CB29B /* unixEmbed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixEmbed.test; sourceTree = "<group>"; };
		F966BC5908F27A3D005CB29B /* unixFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFont.test; sourceTree = "<group>"; };
		F966BC5A08F27A3D005CB29B /* unixMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixMenu.test; sourceTree = "<group>"; };
		F966BC5B08F27A3D005CB29B /* unixSelect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixSelect.test; sourceTree = "<group>"; };
		F966BC5C08F27A3D005CB29B /* unixWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixWm.test; sourceTree = "<group>"; };
		F966BC5D08F27A3D005CB29B /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F966BC5E08F27A3D005CB29B /* visual.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual.test; sourceTree = "<group>"; };
		F966BC5F08F27A3D005CB29B /* visual_bb.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual_bb.test; sourceTree = "<group>"; };
		F966BC6008F27A3D005CB29B /* winButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winButton.test; sourceTree = "<group>"; };
		F966BC6108F27A3D005CB29B /* winClipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winClipboard.test; sourceTree = "<group>"; };
		F966BC6208F27A3D005CB29B /* winDialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDialog.test; sourceTree = "<group>"; };
		F966BC6308F27A3D005CB29B /* window.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = window.test; sourceTree = "<group>"; };
		F966BC6408F27A3D005CB29B /* winfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winfo.test; sourceTree = "<group>"; };
		F966BC6508F27A3D005CB29B /* winFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFont.test; sourceTree = "<group>"; };
		F966BC6608F27A3D005CB29B /* winMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winMenu.test; sourceTree = "<group>"; };
		F966BC6708F27A3D005CB29B /* winSend.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winSend.test; sourceTree = "<group>"; };
		F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = "<group>"; };
		F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = "<group>"; };
		F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
		F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BC7408F27A3D005CB29B /* tk.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.spec; sourceTree = "<group>"; };
		F966BC7508F27A3D005CB29B /* tkAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAppInit.c; sourceTree = "<group>"; };
		F966BC7608F27A3D005CB29B /* tkConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tkConfig.h.in; sourceTree = "<group>"; };
		F966BC7708F27A3D005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
		F966BC8708F27A3D005CB29B /* tkUnixKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixKey.c; sourceTree = "<group>"; };
		F966BC8808F27A3D005CB29B /* tkUnixMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenu.c; sourceTree = "<group>"; };
		F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenubu.c; sourceTree = "<group>"; };
		F966BC8A08F27A3D005CB29B /* tkUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixPort.h; sourceTree = "<group>"; };
		F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixRFont.c; sourceTree = "<group>"; };
		F966BC8C08F27A3D005CB29B /* tkUnixScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScale.c; sourceTree = "<group>"; };
		F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScrlbr.c; sourceTree = "<group>"; };
		F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSelect.c; sourceTree = "<group>"; };
		F966BC8F08F27A3D005CB29B /* tkUnixSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSend.c; sourceTree = "<group>"; };
		F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = "<group>"; };
		F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = "<group>"; };
		F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = "<group>"; };
		F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = "<group>"; };
		F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = "<group>"; };
		F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = "<group>"; };
		F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = "<group>"; };
		F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin32Dll.c; sourceTree = "<group>"; };
		F966BCFB08F27A3F005CB29B /* tkWin3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin3d.c; sourceTree = "<group>"; };
		F966BCFC08F27A3F005CB29B /* tkWinButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinButton.c; sourceTree = "<group>"; };
		F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinClipboard.c; sourceTree = "<group>"; };
		F966BCFE08F27A3F005CB29B /* tkWinColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinColor.c; sourceTree = "<group>"; };
		F966BCFF08F27A3F005CB29B /* tkWinConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinConfig.c; sourceTree = "<group>"; };
		F966BD0008F27A3F005CB29B /* tkWinCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinCursor.c; sourceTree = "<group>"; };
		F966BD0108F27A3F005CB29B /* tkWinDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinDefault.h; sourceTree = "<group>"; };
		F966BD0208F27A3F005CB29B /* tkWinDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDialog.c; sourceTree = "<group>"; };
		F966BD0308F27A3F005CB29B /* tkWinDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDraw.c; sourceTree = "<group>"; };
		F966BD0408F27A3F005CB29B /* tkWinEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinEmbed.c; sourceTree = "<group>"; };
		F966BD0508F27A3F005CB29B /* tkWinFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinFont.c; sourceTree = "<group>"; };
		F966BD0708F27A3F005CB29B /* tkWinImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinImage.c; sourceTree = "<group>"; };
		F966BD0808F27A3F005CB29B /* tkWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinInit.c; sourceTree = "<group>"; };
		F966BD0908F27A3F005CB29B /* tkWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinInt.h; sourceTree = "<group>"; };
		F966BD0A08F27A3F005CB29B /* tkWinKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinKey.c; sourceTree = "<group>"; };
		F966BD0B08F27A3F005CB29B /* tkWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinMenu.c; sourceTree = "<group>"; };
		F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPixmap.c; sourceTree = "<group>"; };
		F966BD0D08F27A3F005CB29B /* tkWinPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPointer.c; sourceTree = "<group>"; };
		F966BD0E08F27A3F005CB29B /* tkWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinPort.h; sourceTree = "<group>"; };
		F966BD0F08F27A3F005CB29B /* tkWinRegion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinRegion.c; sourceTree = "<group>"; };
		F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinScrlbr.c; sourceTree = "<group>"; };
		F966BD1108F27A3F005CB29B /* tkWinSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSend.c; sourceTree = "<group>"; };
		F966BD1208F27A3F005CB29B /* tkWinSendCom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSendCom.c; sourceTree = "<group>"; };
		F966BD1308F27A3F005CB29B /* tkWinSendCom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinSendCom.h; sourceTree = "<group>"; };
		F966BD1408F27A3F005CB29B /* tkWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinTest.c; sourceTree = "<group>"; };
		F966BD1508F27A3F005CB29B /* tkWinWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWindow.c; sourceTree = "<group>"; };
		F966BD1608F27A3F005CB29B /* tkWinWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWm.c; sourceTree = "<group>"; };
		F966BD1708F27A3F005CB29B /* tkWinX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinX.c; sourceTree = "<group>"; };
		F966BD1808F27A3F005CB29B /* winMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winMain.c; sourceTree = "<group>"; };
		F966BD1B08F27A3F005CB29B /* cursorfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorfont.h; sourceTree = "<group>"; };
		F966BD1C08F27A3F005CB29B /* keysym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysym.h; sourceTree = "<group>"; };
		F966BD1D08F27A3F005CB29B /* keysymdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysymdef.h; sourceTree = "<group>"; };
		F966BD1E08F27A3F005CB29B /* X.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X.h; sourceTree = "<group>"; };
		F966BD1F08F27A3F005CB29B /* Xatom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xatom.h; sourceTree = "<group>"; };
		F966BD2008F27A3F005CB29B /* Xfuncproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xfuncproto.h; sourceTree = "<group>"; };
		F966BD2108F27A3F005CB29B /* Xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xlib.h; sourceTree = "<group>"; };
		F966BD2208F27A3F005CB29B /* Xutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xutil.h; sourceTree = "<group>"; };
		F966BD2308F27A3F005CB29B /* xbytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbytes.h; sourceTree = "<group>"; };
		F966BD2408F27A3F005CB29B /* xcolors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xcolors.c; sourceTree = "<group>"; };
		F966BD2508F27A3F005CB29B /* xdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdraw.c; sourceTree = "<group>"; };
		F966BD2608F27A3F005CB29B /* xgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xgc.c; sourceTree = "<group>"; };
		F966BD2708F27A3F005CB29B /* ximage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ximage.c; sourceTree = "<group>"; };
		F966BD2808F27A3F005CB29B /* xutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xutil.c; sourceTree = "<group>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F966C07608F2821B005CB29B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
		F966C07808F28233005CB29B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
		F96887E00AF786D5000797B5 /* ttk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.decls; sourceTree = "<group>"; };
		F96887E10AF786D5000797B5 /* ttkBlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkBlink.c; sourceTree = "<group>"; };
		F96887E20AF786D5000797B5 /* ttkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkButton.c; sourceTree = "<group>"; };
		F96887E30AF786D5000797B5 /* ttkCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkCache.c; sourceTree = "<group>"; };
		F96887E40AF786D5000797B5 /* ttkClamTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClamTheme.c; sourceTree = "<group>"; };
		F96887E50AF786D5000797B5 /* ttkClassicTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClassicTheme.c; sourceTree = "<group>"; };
		F96887E60AF786D5000797B5 /* ttkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkDecls.h; sourceTree = "<group>"; };
		F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkDefaultTheme.c; sourceTree = "<group>"; };
		F96887E80AF786D5000797B5 /* ttkElements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkElements.c; sourceTree = "<group>"; };
		F96887E90AF786D5000797B5 /* ttkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkEntry.c; sourceTree = "<group>"; };
		F96887EA0AF786D5000797B5 /* ttkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkFrame.c; sourceTree = "<group>"; };
		F96887EB0AF786D5000797B5 /* ttkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkImage.c; sourceTree = "<group>"; };
		F96887EC0AF786D5000797B5 /* ttkInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkInit.c; sourceTree = "<group>"; };
		F96887ED0AF786D5000797B5 /* ttkLabel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLabel.c; sourceTree = "<group>"; };
		F96887EE0AF786D5000797B5 /* ttkLayout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLayout.c; sourceTree = "<group>"; };
		F96887EF0AF786D5000797B5 /* ttkManager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkManager.c; sourceTree = "<group>"; };
		F96887F00AF786D5000797B5 /* ttkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkManager.h; sourceTree = "<group>"; };
		F96887F10AF786D5000797B5 /* ttkNotebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkNotebook.c; sourceTree = "<group>"; };
		F96887F20AF786D5000797B5 /* ttkPanedwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkPanedwindow.c; sourceTree = "<group>"; };
		F96887F30AF786D5000797B5 /* ttkProgress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkProgress.c; sourceTree = "<group>"; };
		F96887F40AF786D5000797B5 /* ttkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScale.c; sourceTree = "<group>"; };
		F96887F50AF786D5000797B5 /* ttkScroll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScroll.c; sourceTree = "<group>"; };
		F96887F60AF786D5000797B5 /* ttkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScrollbar.c; sourceTree = "<group>"; };
		F96887F70AF786D5000797B5 /* ttkSeparator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSeparator.c; sourceTree = "<group>"; };
		F96887F80AF786D5000797B5 /* ttkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSquare.c; sourceTree = "<group>"; };
		F96887F90AF786D5000797B5 /* ttkState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkState.c; sourceTree = "<group>"; };
		F96887FA0AF786D5000797B5 /* ttkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubInit.c; sourceTree = "<group>"; };
		F96887FB0AF786D5000797B5 /* ttkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubLib.c; sourceTree = "<group>"; };
		F96887FC0AF786D5000797B5 /* ttkTagSet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTagSet.c; sourceTree = "<group>"; };
		F96887FD0AF786D5000797B5 /* ttkTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTheme.c; sourceTree = "<group>"; };
		F96887FE0AF786D5000797B5 /* ttkTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkTheme.h; sourceTree = "<group>"; };
		F96887FF0AF786D5000797B5 /* ttkThemeInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkThemeInt.h; sourceTree = "<group>"; };
		F96888000AF786D5000797B5 /* ttkTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrace.c; sourceTree = "<group>"; };
		F96888010AF786D5000797B5 /* ttkTrack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrack.c; sourceTree = "<group>"; };
		F96888020AF786D5000797B5 /* ttkTreeview.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTreeview.c; sourceTree = "<group>"; };
		F96888030AF786D5000797B5 /* ttkWidget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWidget.c; sourceTree = "<group>"; };
		F96888040AF786D5000797B5 /* ttkWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkWidget.h; sourceTree = "<group>"; };
		F96888370AF787B3000797B5 /* altTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = altTheme.tcl; sourceTree = "<group>"; };
		F96888380AF787B3000797B5 /* aquaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aquaTheme.tcl; sourceTree = "<group>"; };
		F96888390AF787B3000797B5 /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F968883A0AF787B3000797B5 /* clamTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clamTheme.tcl; sourceTree = "<group>"; };
		F968883B0AF787B3000797B5 /* classicTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = classicTheme.tcl; sourceTree = "<group>"; };
		F968883C0AF787B3000797B5 /* combobox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.tcl; sourceTree = "<group>"; };
		F968883D0AF787B3000797B5 /* cursors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursors.tcl; sourceTree = "<group>"; };
		F968883E0AF787B3000797B5 /* defaults.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = defaults.tcl; sourceTree = "<group>"; };
		F96888400AF787B3000797B5 /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F96888410AF787B3000797B5 /* fonts.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fonts.tcl; sourceTree = "<group>"; };
		F96888440AF787B3000797B5 /* menubutton.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubutton.tcl; sourceTree = "<group>"; };
		F96888450AF787B3000797B5 /* notebook.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.tcl; sourceTree = "<group>"; };
		F96888460AF787B3000797B5 /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F96888470AF787B3000797B5 /* progress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progress.tcl; sourceTree = "<group>"; };
		F96888480AF787B3000797B5 /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F96888490AF787B3000797B5 /* scrollbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.tcl; sourceTree = "<group>"; };
		F968884A0AF787B3000797B5 /* sizegrip.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sizegrip.tcl; sourceTree = "<group>"; };
		F968884B0AF787B3000797B5 /* treeview.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.tcl; sourceTree = "<group>"; };
		F968884C0AF787B3000797B5 /* ttk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.tcl; sourceTree = "<group>"; };
		F968884D0AF787B3000797B5 /* utils.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utils.tcl; sourceTree = "<group>"; };
		F968884E0AF787B3000797B5 /* winTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTheme.tcl; sourceTree = "<group>"; };
		F968884F0AF787B3000797B5 /* xpTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xpTheme.tcl; sourceTree = "<group>"; };
		F96888540AF7880C000797B5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96888560AF7880C000797B5 /* combobox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.test; sourceTree = "<group>"; };
		F96888570AF7880C000797B5 /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F96888580AF7880C000797B5 /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F96888590AF7880C000797B5 /* labelframe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.test; sourceTree = "<group>"; };
		F968885A0AF7880C000797B5 /* layout.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = layout.test; sourceTree = "<group>"; };
		F968885C0AF7880C000797B5 /* notebook.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.test; sourceTree = "<group>"; };
		F968885D0AF7880C000797B5 /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F968885E0AF7880C000797B5 /* progressbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progressbar.test; sourceTree = "<group>"; };
		F968885F0AF7880C000797B5 /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F96888600AF7880C000797B5 /* treetags.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treetags.test; sourceTree = "<group>"; };
		F96888610AF7880C000797B5 /* treeview.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.test; sourceTree = "<group>"; };
		F96888620AF7880C000797B5 /* ttk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.test; sourceTree = "<group>"; };
		F96888630AF7880C000797B5 /* validate.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = validate.test; sourceTree = "<group>"; };
		F968886B0AF788F6000797B5 /* ttk_button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_button.n; sourceTree = "<group>"; };
		F968886C0AF788F6000797B5 /* ttk_checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_checkbutton.n; sourceTree = "<group>"; };
		F968886D0AF788F6000797B5 /* ttk_combobox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_combobox.n; sourceTree = "<group>"; };
		F968886F0AF788F6000797B5 /* ttk_entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_entry.n; sourceTree = "<group>"; };
		F96888700AF788F6000797B5 /* ttk_frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_frame.n; sourceTree = "<group>"; };
		F96888710AF788F6000797B5 /* ttk_Geometry.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Geometry.3; sourceTree = "<group>"; };
		F96888720AF788F6000797B5 /* ttk_image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_image.n; sourceTree = "<group>"; };
		F96888730AF788F6000797B5 /* ttk_intro.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_intro.n; sourceTree = "<group>"; };
		F96888740AF788F6000797B5 /* ttk_label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_label.n; sourceTree = "<group>"; };
		F96888750AF788F6000797B5 /* ttk_labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_labelframe.n; sourceTree = "<group>"; };
		F96888760AF788F6000797B5 /* ttk_menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_menubutton.n; sourceTree = "<group>"; };
		F96888770AF788F6000797B5 /* ttk_notebook.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_notebook.n; sourceTree = "<group>"; };
		F96888780AF788F6000797B5 /* ttk_panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_panedwindow.n; sourceTree = "<group>"; };
		F96888790AF788F6000797B5 /* ttk_progressbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_progressbar.n; sourceTree = "<group>"; };
		F968887A0AF788F6000797B5 /* ttk_radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_radiobutton.n; sourceTree = "<group>"; };
		F968887B0AF788F6000797B5 /* ttk_scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_scrollbar.n; sourceTree = "<group>"; };
		F968887C0AF788F6000797B5 /* ttk_separator.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_separator.n; sourceTree = "<group>"; };
		F968887D0AF788F6000797B5 /* ttk_sizegrip.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_sizegrip.n; sourceTree = "<group>"; };
		F968887E0AF788F6000797B5 /* ttk_style.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_style.n; sourceTree = "<group>"; };
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = "<group>"; };
		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F973E5960EE99384001A648E /* vistaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vistaTheme.tcl; sourceTree = "<group>"; };
		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
		F974D57B0FBE7EC000BF728B /* tk.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.pc.in; sourceTree = "<group>"; };
		F974D57C0FBE7EFF00BF728B /* iconlist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iconlist.tcl; sourceTree = "<group>"; };
		F974D57D0FBE7EFF00BF728B /* icons.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icons.tcl; sourceTree = "<group>"; };
		F97590AE1039A96200558A9A /* Wish.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.sdef; path = Wish.sdef; sourceTree = "<group>"; };
		F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPrivate.h; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Debug.xcconfig"; sourceTree = "<group>"; };
		F98383650F0FA43900171CA6 /* checkbutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkbutton.test; sourceTree = "<group>"; };
		F98383680F0FA44700171CA6 /* radiobutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radiobutton.test; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F99388380EE0114B0065FE6B /* fontchooser.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.tcl; sourceTree = "<group>"; };
		F99388950EE02D980065FE6B /* fontchooser.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.test; sourceTree = "<group>"; };
		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
		F9A3082D08F2D4AB00BAE1AB /* Tk.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084B08F2D4CE00BAE1AB /* Wish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wish.app; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9C888C20EEF6571003F63AD /* fontchooser.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fontchooser.n; sourceTree = "<group>"; };
		F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
		F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mclist.tcl; sourceTree = "<group>"; };
		F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPNG.c; sourceTree = "<group>"; };
		F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPNG.test; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkpane.tcl; sourceTree = "<group>"; };
		F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkmenu.tcl; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
		F9FD31F40CC1AD070073837D /* tktest-X11 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "tktest-X11"; sourceTree = BUILT_PRODUCTS_DIR; };
		F9FD32140CC1AF170073837D /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = /usr/X11R6/lib/libX11.dylib; sourceTree = "<absolute>"; };
		F9FD32150CC1AF170073837D /* libXext.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXext.dylib; path = /usr/X11R6/lib/libXext.dylib; sourceTree = "<absolute>"; };
		F9FD32160CC1AF170073837D /* libXss.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXss.dylib; path = /usr/X11R6/lib/libXss.dylib; sourceTree = "<absolute>"; };
		F9FD34990CC1BB0D0073837D /* libfreetype.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreetype.dylib; path = /usr/X11R6/lib/libfreetype.dylib; sourceTree = "<absolute>"; };
		F9FD349A0CC1BB0D0073837D /* libXft.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXft.dylib; path = /usr/X11R6/lib/libXft.dylib; sourceTree = "<absolute>"; };
		F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfontconfig.dylib; path = /usr/X11R6/lib/libfontconfig.dylib; sourceTree = "<absolute>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
				F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */,
				F966C07908F28233005CB29B /* IOKit.framework in Frameworks */,
				F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */,
				F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD31E30CC1AD070073837D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */,
				F96437E80EF0D652003F468E /* libz.dylib in Frameworks */,
				F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */,
				F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */,
				F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */,
				F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */,
				F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */,
				F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Tk */ = {
			isa = PBXGroup;
			children = (
				F96D3DF708F271BE004A47F5 /* Tk Sources */,
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n";
			name = Tk;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* Wish.app */,
				F9A3082D08F2D4AB00BAE1AB /* Tk.framework */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
				8DD76FB20486AB0100D96B5E /* tktest */,
				F9FD31F40CC1AD070073837D /* tktest-X11 */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F9183E690EFC81560030B814 /* pkgs */ = {
			isa = PBXGroup;
			children = (
				F9183E6A0EFC81560030B814 /* README */,
				F946FB8B0FBE3AED00CD6495 /* itcl */,
				F9183E8F0EFC817B0030B814 /* tdbc */,
			);
			path = pkgs;
			sourceTree = "<group>";
		};
		F966BA0308F27A37005CB29B /* bitmaps */ = {
			isa = PBXGroup;
			children = (
				F966BA0408F27A37005CB29B /* error.xbm */,
				F966BA0508F27A37005CB29B /* gray12.xbm */,
				F966BA0608F27A37005CB29B /* gray25.xbm */,
				F966BA0708F27A37005CB29B /* gray50.xbm */,
				F966BA0808F27A37005CB29B /* gray75.xbm */,
				F966BA0908F27A37005CB29B /* hourglass.xbm */,
				F966BA0A08F27A37005CB29B /* info.xbm */,
				F966BA0B08F27A37005CB29B /* questhead.xbm */,
				F966BA0C08F27A37005CB29B /* question.xbm */,
				F966BA0D08F27A37005CB29B /* warning.xbm */,
			);
			path = bitmaps;
			sourceTree = "<group>";
		};
		F966BA1008F27A37005CB29B /* doc */ = {
			isa = PBXGroup;
			children = (
				F966BA1108F27A37005CB29B /* 3DBorder.3 */,
				F966BA1208F27A37005CB29B /* AddOption.3 */,
				F966BA1308F27A37005CB29B /* bell.n */,
				F966BA1408F27A37005CB29B /* bind.n */,
				F966BA1508F27A37005CB29B /* BindTable.3 */,
				F966BA1608F27A37005CB29B /* bindtags.n */,
				F966BA1708F27A37005CB29B /* bitmap.n */,
				F966BA1808F27A37005CB29B /* button.n */,
				F966BA1908F27A37005CB29B /* canvas.n */,
				F966BA1A08F27A37005CB29B /* CanvPsY.3 */,
				F966BA1B08F27A37005CB29B /* CanvTkwin.3 */,
				F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */,
				F966BA1D08F27A37005CB29B /* checkbutton.n */,
				F966BA1E08F27A37005CB29B /* chooseColor.n */,
				F966BA1F08F27A37005CB29B /* chooseDirectory.n */,
				F966BA2008F27A37005CB29B /* Clipboard.3 */,
				F966BA2108F27A37005CB29B /* clipboard.n */,
				F966BA2208F27A37005CB29B /* ClrSelect.3 */,
				F966BA2308F27A37005CB29B /* colors.n */,
				F966BA2408F27A37005CB29B /* ConfigWidg.3 */,
				F966BA2508F27A37005CB29B /* ConfigWind.3 */,
				F966BA2608F27A37005CB29B /* console.n */,
				F966BA2708F27A37005CB29B /* CoordToWin.3 */,
				F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */,
				F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */,
				F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */,
				F966BA2B08F27A37005CB29B /* CrtImgType.3 */,
				F966BA2C08F27A37005CB29B /* CrtItemType.3 */,
				F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */,
				F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */,
				F966BA2F08F27A37005CB29B /* CrtWindow.3 */,
				F966BA3008F27A37005CB29B /* cursors.n */,
				F966BA3108F27A37005CB29B /* DeleteImg.3 */,
				F966BA3208F27A37005CB29B /* destroy.n */,
				F966BA3308F27A37005CB29B /* dialog.n */,
				F966BA3408F27A37005CB29B /* DrawFocHlt.3 */,
				F966BA3508F27A37005CB29B /* entry.n */,
				F966BA3608F27A37005CB29B /* event.n */,
				F966BA3708F27A37005CB29B /* EventHndlr.3 */,
				F966BA3808F27A37005CB29B /* FindPhoto.3 */,
				F966BA3908F27A37005CB29B /* focus.n */,
				F966BA3A08F27A37005CB29B /* focusNext.n */,
				F966BA3B08F27A37005CB29B /* font.n */,
				F9C888C20EEF6571003F63AD /* fontchooser.n */,
				F966BA3C08F27A37005CB29B /* FontId.3 */,
				F966BA3D08F27A37005CB29B /* frame.n */,
				F966BA3E08F27A37005CB29B /* FreeXId.3 */,
				F966BA3F08F27A37005CB29B /* GeomReq.3 */,
				F966BA4008F27A37005CB29B /* GetAnchor.3 */,
				F966BA4108F27A37005CB29B /* GetBitmap.3 */,
				F966BA4208F27A37005CB29B /* GetCapStyl.3 */,
				F966BA4308F27A37005CB29B /* GetClrmap.3 */,
				F966BA4408F27A37005CB29B /* GetColor.3 */,
				F966BA4508F27A37005CB29B /* GetCursor.3 */,
				F966BA4608F27A37005CB29B /* GetDash.3 */,
				F966BA4708F27A37005CB29B /* GetFont.3 */,
				F966BA4808F27A37005CB29B /* GetGC.3 */,
				F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */,
				F966BA4A08F27A37005CB29B /* GetHWND.3 */,
				F966BA4B08F27A37005CB29B /* GetImage.3 */,
				F966BA4C08F27A37005CB29B /* GetJoinStl.3 */,
				F966BA4D08F27A37005CB29B /* GetJustify.3 */,
				F966BA4E08F27A37005CB29B /* getOpenFile.n */,
				F966BA4F08F27A37005CB29B /* GetOption.3 */,
				F966BA5008F27A38005CB29B /* GetPixels.3 */,
				F966BA5108F27A38005CB29B /* GetPixmap.3 */,
				F966BA5208F27A38005CB29B /* GetRelief.3 */,
				F966BA5308F27A38005CB29B /* GetRootCrd.3 */,
				F966BA5408F27A38005CB29B /* GetScroll.3 */,
				F966BA5508F27A38005CB29B /* GetSelect.3 */,
				F966BA5608F27A38005CB29B /* GetUid.3 */,
				F966BA5708F27A38005CB29B /* GetVisual.3 */,
				F966BA5808F27A38005CB29B /* GetVRoot.3 */,
				F966BA5908F27A38005CB29B /* Grab.3 */,
				F966BA5A08F27A38005CB29B /* grab.n */,
				F966BA5B08F27A38005CB29B /* grid.n */,
				F966BA5C08F27A38005CB29B /* HandleEvent.3 */,
				F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */,
				F966BA5E08F27A38005CB29B /* IdToWindow.3 */,
				F966BA5F08F27A38005CB29B /* image.n */,
				F966BA6008F27A38005CB29B /* ImgChanged.3 */,
				F966BA6108F27A38005CB29B /* Inactive.3 */,
				F966BA6208F27A38005CB29B /* InternAtom.3 */,
				F966BA6308F27A38005CB29B /* keysyms.n */,
				F966BA6408F27A38005CB29B /* label.n */,
				F966BA6508F27A38005CB29B /* labelframe.n */,
				F966BA6608F27A38005CB29B /* listbox.n */,
				F966BA6708F27A38005CB29B /* loadTk.n */,
				F966BA6808F27A38005CB29B /* lower.n */,
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
				F966BA8408F27A38005CB29B /* QWinEvent.3 */,
				F966BA8508F27A38005CB29B /* radiobutton.n */,
				F966BA8608F27A38005CB29B /* raise.n */,
				F966BA8708F27A38005CB29B /* Restack.3 */,
				F966BA8808F27A38005CB29B /* RestrictEv.3 */,
				F966BA8908F27A38005CB29B /* scale.n */,
				F966BA8A08F27A38005CB29B /* scrollbar.n */,
				F966BA8B08F27A38005CB29B /* selection.n */,
				F966BA8C08F27A38005CB29B /* send.n */,
				F966BA8D08F27A38005CB29B /* SetAppName.3 */,
				F966BA8E08F27A38005CB29B /* SetCaret.3 */,
				F966BA8F08F27A38005CB29B /* SetClass.3 */,
				F966BA9008F27A38005CB29B /* SetClassProcs.3 */,
				F966BA9108F27A38005CB29B /* SetGrid.3 */,
				F966BA9208F27A38005CB29B /* SetOptions.3 */,
				F966BA9308F27A38005CB29B /* SetVisual.3 */,
				F966BA9408F27A38005CB29B /* spinbox.n */,
				F966BA9508F27A38005CB29B /* StrictMotif.3 */,
				F966BA9608F27A38005CB29B /* text.n */,
				F966BA9708F27A38005CB29B /* TextLayout.3 */,
				F966BA9808F27A38005CB29B /* tk.n */,
				F966BA9A08F27A38005CB29B /* Tk_Init.3 */,
				F966BA9B08F27A38005CB29B /* Tk_Main.3 */,
				F966BA9C08F27A38005CB29B /* tkerror.n */,
				F966BA9D08F27A38005CB29B /* TkInitStubs.3 */,
				F966BA9E08F27A38005CB29B /* tkvars.n */,
				F966BA9F08F27A38005CB29B /* tkwait.n */,
				F966BAA008F27A38005CB29B /* toplevel.n */,
				F968886B0AF788F6000797B5 /* ttk_button.n */,
				F968886C0AF788F6000797B5 /* ttk_checkbutton.n */,
				F968886D0AF788F6000797B5 /* ttk_combobox.n */,
				F968886F0AF788F6000797B5 /* ttk_entry.n */,
				F96888700AF788F6000797B5 /* ttk_frame.n */,
				F96888710AF788F6000797B5 /* ttk_Geometry.3 */,
				F96888720AF788F6000797B5 /* ttk_image.n */,
				F96888730AF788F6000797B5 /* ttk_intro.n */,
				F96888740AF788F6000797B5 /* ttk_label.n */,
				F96888750AF788F6000797B5 /* ttk_labelframe.n */,
				F96888760AF788F6000797B5 /* ttk_menubutton.n */,
				F96888770AF788F6000797B5 /* ttk_notebook.n */,
				F96888780AF788F6000797B5 /* ttk_panedwindow.n */,
				F96888790AF788F6000797B5 /* ttk_progressbar.n */,
				F968887A0AF788F6000797B5 /* ttk_radiobutton.n */,
				F968887B0AF788F6000797B5 /* ttk_scrollbar.n */,
				F968887C0AF788F6000797B5 /* ttk_separator.n */,
				F968887D0AF788F6000797B5 /* ttk_sizegrip.n */,
				F968887E0AF788F6000797B5 /* ttk_style.n */,
				F968887F0AF788F6000797B5 /* ttk_Theme.3 */,
				F96888800AF788F6000797B5 /* ttk_treeview.n */,
				F96888810AF788F6000797B5 /* ttk_widget.n */,
				F966BAA108F27A38005CB29B /* WindowId.3 */,
				F966BAA208F27A38005CB29B /* winfo.n */,
				F966BAA308F27A38005CB29B /* wish.1 */,
				F966BAA408F27A38005CB29B /* wm.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F966BAA508F27A38005CB29B /* generic */ = {
			isa = PBXGroup;
			children = (
				F966BAA608F27A38005CB29B /* default.h */,
				F966BAA708F27A38005CB29B /* ks_names.h */,
				F966BAA908F27A39005CB29B /* README */,
				F966BAAA08F27A39005CB29B /* tk.decls */,
				F966BAAB08F27A39005CB29B /* tk.h */,
				F966BAAC08F27A39005CB29B /* tk3d.c */,
				F966BAAD08F27A39005CB29B /* tk3d.h */,
				F966BAAE08F27A39005CB29B /* tkArgv.c */,
				F966BAAF08F27A39005CB29B /* tkAtom.c */,
				F966BAB008F27A39005CB29B /* tkBind.c */,
				F966BAB108F27A39005CB29B /* tkBitmap.c */,
				F9152B080EAF8A5000CD5C7B /* tkBusy.c */,
				F966BAB208F27A39005CB29B /* tkButton.c */,
				F966BAB308F27A39005CB29B /* tkButton.h */,
				F966BAB408F27A39005CB29B /* tkCanvArc.c */,
				F966BAB508F27A39005CB29B /* tkCanvas.c */,
				F966BAB608F27A39005CB29B /* tkCanvas.h */,
				F966BAB708F27A39005CB29B /* tkCanvBmap.c */,
				F966BAB808F27A39005CB29B /* tkCanvImg.c */,
				F966BAB908F27A39005CB29B /* tkCanvLine.c */,
				F966BABA08F27A39005CB29B /* tkCanvPoly.c */,
				F966BABB08F27A39005CB29B /* tkCanvPs.c */,
				F966BABD08F27A39005CB29B /* tkCanvText.c */,
				F966BABE08F27A39005CB29B /* tkCanvUtil.c */,
				F966BABF08F27A39005CB29B /* tkCanvWind.c */,
				F966BAC008F27A39005CB29B /* tkClipboard.c */,
				F966BAC108F27A39005CB29B /* tkCmds.c */,
				F966BAC208F27A39005CB29B /* tkColor.c */,
				F966BAC308F27A39005CB29B /* tkColor.h */,
				F966BAC408F27A39005CB29B /* tkConfig.c */,
				F966BAC508F27A39005CB29B /* tkConsole.c */,
				F966BAC608F27A39005CB29B /* tkCursor.c */,
				F966BAC708F27A39005CB29B /* tkDecls.h */,
				F966BAC808F27A39005CB29B /* tkEntry.c */,
				F966BAC908F27A39005CB29B /* tkEntry.h */,
				F966BACA08F27A39005CB29B /* tkError.c */,
				F966BACB08F27A39005CB29B /* tkEvent.c */,
				F966BACC08F27A39005CB29B /* tkFileFilter.c */,
				F966BACD08F27A39005CB29B /* tkFileFilter.h */,
				F966BACE08F27A39005CB29B /* tkFocus.c */,
				F966BACF08F27A39005CB29B /* tkFont.c */,
				F966BAD008F27A39005CB29B /* tkFont.h */,
				F966BAD108F27A39005CB29B /* tkFrame.c */,
				F966BAD208F27A39005CB29B /* tkGC.c */,
				F966BAD308F27A39005CB29B /* tkGeometry.c */,
				F966BAD408F27A39005CB29B /* tkGet.c */,
				F966BAD508F27A39005CB29B /* tkGrab.c */,
				F966BAD608F27A39005CB29B /* tkGrid.c */,
				F966BAD708F27A39005CB29B /* tkImage.c */,
				F966BAD808F27A39005CB29B /* tkImgBmap.c */,
				F966BAD908F27A39005CB29B /* tkImgGIF.c */,
				F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */,
				F966BADA08F27A39005CB29B /* tkImgPhoto.c */,
				F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */,
				F966BADB08F27A39005CB29B /* tkImgPPM.c */,
				F966BADC08F27A39005CB29B /* tkImgUtil.c */,
				F966BADE08F27A39005CB29B /* tkInt.decls */,
				F966BADF08F27A39005CB29B /* tkInt.h */,
				F966BAE108F27A39005CB29B /* tkIntDecls.h */,
				F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */,
				F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */,
				F966BAE408F27A39005CB29B /* tkListbox.c */,
				F966BAE508F27A39005CB29B /* tkMacWinMenu.c */,
				F966BAE608F27A39005CB29B /* tkMain.c */,
				F966BAE708F27A39005CB29B /* tkMenu.c */,
				F966BAE808F27A39005CB29B /* tkMenu.h */,
				F966BAE908F27A39005CB29B /* tkMenubutton.c */,
				F966BAEA08F27A39005CB29B /* tkMenubutton.h */,
				F966BAEB08F27A39005CB29B /* tkMenuDraw.c */,
				F966BAEC08F27A39005CB29B /* tkMessage.c */,
				F966BAED08F27A39005CB29B /* tkObj.c */,
				F966BAEE08F27A39005CB29B /* tkOldConfig.c */,
				F966BAEF08F27A39005CB29B /* tkOption.c */,
				F966BAF008F27A39005CB29B /* tkPack.c */,
				F966BAF108F27A39005CB29B /* tkPanedWindow.c */,
				F966BAF208F27A39005CB29B /* tkPlace.c */,
				F966BAF308F27A39005CB29B /* tkPlatDecls.h */,
				F966BAF408F27A39005CB29B /* tkPointer.c */,
				F966BAF508F27A39005CB29B /* tkPort.h */,
				F966BAF608F27A39005CB29B /* tkRectOval.c */,
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
				F966BB0608F27A39005CB29B /* tkTextDisp.c */,
				F966BB0808F27A39005CB29B /* tkTextImage.c */,
				F966BB0908F27A39005CB29B /* tkTextIndex.c */,
				F966BB0A08F27A39005CB29B /* tkTextMark.c */,
				F966BB0B08F27A39005CB29B /* tkTextTag.c */,
				F966BB0C08F27A39005CB29B /* tkTextWind.c */,
				F966BB0D08F27A39005CB29B /* tkTrig.c */,
				F966BB0E08F27A39005CB29B /* tkUndo.c */,
				F966BB0F08F27A39005CB29B /* tkUndo.h */,
				F966BB1008F27A39005CB29B /* tkUtil.c */,
				F966BB1108F27A39005CB29B /* tkVisual.c */,
				F966BB1208F27A39005CB29B /* tkWindow.c */,
				F96887DF0AF786D5000797B5 /* ttk */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F966BB1308F27A39005CB29B /* library */ = {
			isa = PBXGroup;
			children = (
				F966BB1408F27A39005CB29B /* bgerror.tcl */,
				F966BB1508F27A39005CB29B /* button.tcl */,
				F966BB1608F27A39005CB29B /* choosedir.tcl */,
				F966BB1708F27A39005CB29B /* clrpick.tcl */,
				F966BB1808F27A39005CB29B /* comdlg.tcl */,
				F966BB1908F27A39005CB29B /* console.tcl */,
				F966BB1A08F27A39005CB29B /* demos */,
				F966BB6208F27A3A005CB29B /* dialog.tcl */,
				F966BB6308F27A3A005CB29B /* entry.tcl */,
				F966BB6408F27A3A005CB29B /* focus.tcl */,
				F99388380EE0114B0065FE6B /* fontchooser.tcl */,
				F974D57C0FBE7EFF00BF728B /* iconlist.tcl */,
				F974D57D0FBE7EFF00BF728B /* icons.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
			children = (
				F966BB1B08F27A39005CB29B /* anilabel.tcl */,
				F966BB1C08F27A39005CB29B /* aniwave.tcl */,
				F966BB1D08F27A39005CB29B /* arrow.tcl */,
				F966BB1E08F27A39005CB29B /* bind.tcl */,
				F966BB1F08F27A39005CB29B /* bitmap.tcl */,
				F966BB2008F27A39005CB29B /* browse */,
				F966BB2108F27A39005CB29B /* button.tcl */,
				F966BB2208F27A39005CB29B /* check.tcl */,
				F966BB2308F27A39005CB29B /* clrpick.tcl */,
				F966BB2408F27A39005CB29B /* colors.tcl */,
				F936FCDB0CCD984600716967 /* combo.tcl */,
				F966BB2508F27A39005CB29B /* cscroll.tcl */,
				F966BB2608F27A39005CB29B /* ctext.tcl */,
				F966BB2708F27A39005CB29B /* dialog1.tcl */,
				F966BB2808F27A39005CB29B /* dialog2.tcl */,
				F966BB2A08F27A39005CB29B /* entry1.tcl */,
				F966BB2B08F27A39005CB29B /* entry2.tcl */,
				F966BB2C08F27A39005CB29B /* entry3.tcl */,
				F966BB2D08F27A39005CB29B /* filebox.tcl */,
				F966BB2E08F27A39005CB29B /* floor.tcl */,
				F91543270EF201A90032D1E8 /* fontchoose.tcl */,
				F966BB2F08F27A39005CB29B /* form.tcl */,
				F966BB3008F27A39005CB29B /* goldberg.tcl */,
				F966BB3108F27A39005CB29B /* hello */,
				F966BB3208F27A39005CB29B /* hscale.tcl */,
				F966BB3308F27A39005CB29B /* icon.tcl */,
				F966BB3408F27A39005CB29B /* image1.tcl */,
				F966BB3508F27A39005CB29B /* image2.tcl */,
				F966BB4208F27A3A005CB29B /* items.tcl */,
				F966BB4308F27A3A005CB29B /* ixset */,
				F92240290D7C620F005EC715 /* knightstour.tcl */,
				F966BB4408F27A3A005CB29B /* label.tcl */,
				F966BB4508F27A3A005CB29B /* labelframe.tcl */,
				F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */,
				F966BB4608F27A3A005CB29B /* menu.tcl */,
				F966BB4708F27A3A005CB29B /* menubu.tcl */,
				F966BB4808F27A3A005CB29B /* msgbox.tcl */,
				F966BB4A08F27A3A005CB29B /* paned1.tcl */,
				F966BB4B08F27A3A005CB29B /* paned2.tcl */,
				F966BB4C08F27A3A005CB29B /* pendulum.tcl */,
				F966BB4D08F27A3A005CB29B /* plot.tcl */,
				F966BB4E08F27A3A005CB29B /* puzzle.tcl */,
				F966BB4F08F27A3A005CB29B /* radio.tcl */,
				F966BB5008F27A3A005CB29B /* README */,
				F966BB5108F27A3A005CB29B /* rmt */,
				F966BB5208F27A3A005CB29B /* rolodex */,
				F966BB5308F27A3A005CB29B /* ruler.tcl */,
				F966BB5408F27A3A005CB29B /* sayings.tcl */,
				F966BB5508F27A3A005CB29B /* search.tcl */,
				F966BB5608F27A3A005CB29B /* spin.tcl */,
				F966BB5708F27A3A005CB29B /* square */,
				F966BB5808F27A3A005CB29B /* states.tcl */,
				F966BB5908F27A3A005CB29B /* style.tcl */,
				F966BB5A08F27A3A005CB29B /* tclIndex */,
				F966BB5B08F27A3A005CB29B /* tcolor */,
				F966BB5C08F27A3A005CB29B /* text.tcl */,
				F9099B8A0CC67D30005A9580 /* textpeer.tcl */,
				F966BB5D08F27A3A005CB29B /* timer */,
				F936FCD90CCD984600716967 /* toolbar.tcl */,
				F936FCD80CCD984600716967 /* tree.tcl */,
				F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */,
				F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */,
				F936FCDA0CCD984600716967 /* ttknote.tcl */,
				F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */,
				F936FCD70CCD984500716967 /* ttkprogress.tcl */,
				F966BB5E08F27A3A005CB29B /* twind.tcl */,
				F966BB5F08F27A3A005CB29B /* unicodeout.tcl */,
				F966BB6008F27A3A005CB29B /* vscale.tcl */,
				F966BB6108F27A3A005CB29B /* widget */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		F966BB9708F27A3B005CB29B /* macosx */ = {
			isa = PBXGroup;
			children = (
				F966BBBA08F27A3B005CB29B /* configure.ac */,
				F966BBBB08F27A3B005CB29B /* GNUmakefile */,
				F966BBBE08F27A3B005CB29B /* README */,
				F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */,
				F966BBC208F27A3B005CB29B /* tkMacOSX.h */,
				F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */,
				F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */,
				F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */,
				F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */,
				F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */,
				F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */,
				F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */,
				F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */,
				F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */,
				F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */,
				F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */,
				F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */,
				F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */,
				F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */,
				F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */,
				F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */,
				F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */,
				F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */,
				F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */,
				F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */,
				F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */,
				F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */,
				F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */,
				F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */,
				F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */,
				F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */,
				F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */,
				F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */,
				F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */,
				F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */,
				F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */,
				F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */,
				F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */,
				F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */,
				F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */,
				F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */,
				F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */,
				F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */,
				F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */,
				F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */,
				F96888840AF78938000797B5 /* ttkMacOSXTheme.c */,
				F95D8D4B0F1715610006B020 /* Tk.icns */,
				F95D8D4C0F1715610006B020 /* Tk.tiff */,
				F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */,
				F97590AE1039A96200558A9A /* Wish.sdef */,
				F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F966BC0408F27A3C005CB29B /* tests */ = {
			isa = PBXGroup;
			children = (
				F966BC0508F27A3C005CB29B /* all.tcl */,
				F966BC0608F27A3C005CB29B /* arc.tcl */,
				F966BC0708F27A3C005CB29B /* bell.test */,
				F966BC0808F27A3C005CB29B /* bevel.tcl */,
				F966BC0908F27A3C005CB29B /* bgerror.test */,
				F966BC0A08F27A3C005CB29B /* bind.test */,
				F966BC0B08F27A3C005CB29B /* bitmap.test */,
				F966BC0C08F27A3C005CB29B /* border.test */,
				F966BC0D08F27A3C005CB29B /* bugs.tcl */,
				F966BC0E08F27A3C005CB29B /* butGeom.tcl */,
				F966BC0F08F27A3C005CB29B /* butGeom2.tcl */,
				F966BC1008F27A3C005CB29B /* button.test */,
				F966BC1108F27A3C005CB29B /* canvas.test */,
				F966BC1208F27A3C005CB29B /* canvImg.test */,
				F966BC1308F27A3C005CB29B /* canvPs.test */,
				F966BC1408F27A3C005CB29B /* canvPsArc.tcl */,
				F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */,
				F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */,
				F966BC1708F27A3C005CB29B /* canvPsImg.tcl */,
				F966BC1808F27A3C005CB29B /* canvPsText.tcl */,
				F966BC1908F27A3C005CB29B /* canvRect.test */,
				F966BC1A08F27A3C005CB29B /* canvText.test */,
				F966BC1B08F27A3C005CB29B /* canvWind.test */,
				F966BC1C08F27A3C005CB29B /* choosedir.test */,
				F966BC1D08F27A3C005CB29B /* clipboard.test */,
				F966BC1E08F27A3C005CB29B /* clrpick.test */,
				F966BC1F08F27A3C005CB29B /* cmap.tcl */,
				F966BC2008F27A3C005CB29B /* cmds.test */,
				F966BC2108F27A3C005CB29B /* color.test */,
				F966BC2208F27A3C005CB29B /* config.test */,
				F966BC2308F27A3C005CB29B /* constraints.tcl */,
				F966BC2408F27A3C005CB29B /* cursor.test */,
				F966BC2508F27A3C005CB29B /* dialog.test */,
				F966BC2608F27A3C005CB29B /* embed.test */,
				F966BC2708F27A3C005CB29B /* entry.test */,
				F966BC2808F27A3C005CB29B /* event.test */,
				F966BC2908F27A3C005CB29B /* filebox.test */,
				F966BC2A08F27A3C005CB29B /* focus.test */,
				F966BC2B08F27A3C005CB29B /* focusTcl.test */,
				F966BC2C08F27A3C005CB29B /* font.test */,
				F99388950EE02D980065FE6B /* fontchooser.test */,
				F966BC2D08F27A3C005CB29B /* frame.test */,
				F966BC2E08F27A3C005CB29B /* geometry.test */,
				F966BC2F08F27A3C005CB29B /* get.test */,
				F966BC3008F27A3C005CB29B /* grab.test */,
				F966BC3108F27A3C005CB29B /* grid.test */,
				F966BC3308F27A3C005CB29B /* image.test */,
				F966BC3408F27A3C005CB29B /* imgBmap.test */,
				F966BC3508F27A3C005CB29B /* imgPhoto.test */,
				F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */,
				F966BC3608F27A3C005CB29B /* imgPPM.test */,
				F966BC3708F27A3C005CB29B /* listbox.test */,
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
				F966BC4708F27A3D005CB29B /* README */,
				F966BC4808F27A3D005CB29B /* safe.test */,
				F966BC4908F27A3D005CB29B /* scale.test */,
				F966BC4A08F27A3D005CB29B /* scrollbar.test */,
				F966BC4B08F27A3D005CB29B /* select.test */,
				F966BC4C08F27A3D005CB29B /* send.test */,
				F966BC4D08F27A3D005CB29B /* spinbox.test */,
				F966BC4E08F27A3D005CB29B /* text.test */,
				F966BC4F08F27A3D005CB29B /* textBTree.test */,
				F966BC5008F27A3D005CB29B /* textDisp.test */,
				F966BC5108F27A3D005CB29B /* textImage.test */,
				F966BC5208F27A3D005CB29B /* textIndex.test */,
				F966BC5308F27A3D005CB29B /* textMark.test */,
				F966BC5408F27A3D005CB29B /* textTag.test */,
				F966BC5508F27A3D005CB29B /* textWind.test */,
				F966BC5608F27A3D005CB29B /* tk.test */,
				F96888530AF7880C000797B5 /* ttk */,
				F966BC5708F27A3D005CB29B /* unixButton.test */,
				F966BC5808F27A3D005CB29B /* unixEmbed.test */,
				F966BC5908F27A3D005CB29B /* unixFont.test */,
				F966BC5A08F27A3D005CB29B /* unixMenu.test */,
				F966BC5B08F27A3D005CB29B /* unixSelect.test */,
				F966BC5C08F27A3D005CB29B /* unixWm.test */,
				F966BC5D08F27A3D005CB29B /* util.test */,
				F966BC5E08F27A3D005CB29B /* visual.test */,
				F966BC5F08F27A3D005CB29B /* visual_bb.test */,
				F966BC6008F27A3D005CB29B /* winButton.test */,
				F966BC6108F27A3D005CB29B /* winClipboard.test */,
				F966BC6208F27A3D005CB29B /* winDialog.test */,
				F966BC6308F27A3D005CB29B /* window.test */,
				F966BC6408F27A3D005CB29B /* winfo.test */,
				F966BC6508F27A3D005CB29B /* winFont.test */,
				F966BC6608F27A3D005CB29B /* winMenu.test */,
				F966BC6708F27A3D005CB29B /* winSend.test */,
				F966BC6808F27A3D005CB29B /* winWm.test */,
				F966BC6908F27A3D005CB29B /* wm.test */,
				F966BC6A08F27A3D005CB29B /* xmfbox.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.ac */,
				F966BC6F08F27A3D005CB29B /* install-sh */,
				F966BC7008F27A3D005CB29B /* installManPage */,
				F966BC7108F27A3D005CB29B /* Makefile.in */,
				F966BC7208F27A3D005CB29B /* README */,
				F966BC7308F27A3D005CB29B /* tcl.m4 */,
				F974D57B0FBE7EC000BF728B /* tk.pc.in */,
				F966BC7408F27A3D005CB29B /* tk.spec */,
				F966BC7508F27A3D005CB29B /* tkAppInit.c */,
				F966BC7608F27A3D005CB29B /* tkConfig.h.in */,
				F966BC7708F27A3D005CB29B /* tkConfig.sh.in */,
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
				F966BC8708F27A3D005CB29B /* tkUnixKey.c */,
				F966BC8808F27A3D005CB29B /* tkUnixMenu.c */,
				F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */,
				F966BC8A08F27A3D005CB29B /* tkUnixPort.h */,
				F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */,
				F966BC8C08F27A3D005CB29B /* tkUnixScale.c */,
				F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */,
				F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */,
				F966BC8F08F27A3D005CB29B /* tkUnixSend.c */,
				F966BC9008F27A3D005CB29B /* tkUnixWm.c */,
				F966BC9108F27A3D005CB29B /* tkUnixXId.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.ac */,
				F966BC9908F27A3E005CB29B /* Makefile.in */,
				F966BC9A08F27A3E005CB29B /* makefile.vc */,
				F966BC9C08F27A3E005CB29B /* nmakehlp.c */,
				F966BC9D08F27A3E005CB29B /* rc */,
				F966BCF308F27A3E005CB29B /* README */,
				F966BCF408F27A3E005CB29B /* rmd.bat */,
				F966BCF508F27A3F005CB29B /* rules.vc */,
				F966BCF608F27A3F005CB29B /* stubs.c */,
				F966BCF708F27A3F005CB29B /* tcl.m4 */,
				F966BCF808F27A3F005CB29B /* tkConfig.sh.in */,
				F966BCF908F27A3F005CB29B /* tkWin.h */,
				F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */,
				F966BCFB08F27A3F005CB29B /* tkWin3d.c */,
				F966BCFC08F27A3F005CB29B /* tkWinButton.c */,
				F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */,
				F966BCFE08F27A3F005CB29B /* tkWinColor.c */,
				F966BCFF08F27A3F005CB29B /* tkWinConfig.c */,
				F966BD0008F27A3F005CB29B /* tkWinCursor.c */,
				F966BD0108F27A3F005CB29B /* tkWinDefault.h */,
				F966BD0208F27A3F005CB29B /* tkWinDialog.c */,
				F966BD0308F27A3F005CB29B /* tkWinDraw.c */,
				F966BD0408F27A3F005CB29B /* tkWinEmbed.c */,
				F966BD0508F27A3F005CB29B /* tkWinFont.c */,
				F966BD0708F27A3F005CB29B /* tkWinImage.c */,
				F966BD0808F27A3F005CB29B /* tkWinInit.c */,
				F966BD0908F27A3F005CB29B /* tkWinInt.h */,
				F966BD0A08F27A3F005CB29B /* tkWinKey.c */,
				F966BD0B08F27A3F005CB29B /* tkWinMenu.c */,
				F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */,
				F966BD0D08F27A3F005CB29B /* tkWinPointer.c */,
				F966BD0E08F27A3F005CB29B /* tkWinPort.h */,
				F966BD0F08F27A3F005CB29B /* tkWinRegion.c */,
				F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */,
				F966BD1108F27A3F005CB29B /* tkWinSend.c */,
				F966BD1208F27A3F005CB29B /* tkWinSendCom.c */,
				F966BD1308F27A3F005CB29B /* tkWinSendCom.h */,
				F966BD1408F27A3F005CB29B /* tkWinTest.c */,
				F966BD1508F27A3F005CB29B /* tkWinWindow.c */,
				F966BD1608F27A3F005CB29B /* tkWinWm.c */,
				F966BD1708F27A3F005CB29B /* tkWinX.c */,
				F96888860AF78953000797B5 /* ttkWinMonitor.c */,
				F96888870AF78953000797B5 /* ttkWinTheme.c */,
				F96888880AF78953000797B5 /* ttkWinXPTheme.c */,
				F966BD1808F27A3F005CB29B /* winMain.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F966BC9D08F27A3E005CB29B /* rc */ = {
			isa = PBXGroup;
			children = (
				F966BCEE08F27A3E005CB29B /* tk.rc */,
				F966BCEF08F27A3E005CB29B /* tk_base.rc */,
				F966BCF208F27A3E005CB29B /* wish.rc */,
			);
			path = rc;
			sourceTree = "<group>";
		};
		F966BD1908F27A3F005CB29B /* xlib */ = {
			isa = PBXGroup;
			children = (
				F966BD1A08F27A3F005CB29B /* X11 */,
				F966BD2308F27A3F005CB29B /* xbytes.h */,
				F966BD2408F27A3F005CB29B /* xcolors.c */,
				F966BD2508F27A3F005CB29B /* xdraw.c */,
				F966BD2608F27A3F005CB29B /* xgc.c */,
				F966BD2708F27A3F005CB29B /* ximage.c */,
				F966BD2808F27A3F005CB29B /* xutil.c */,
			);
			path = xlib;
			sourceTree = "<group>";
		};
		F966BD1A08F27A3F005CB29B /* X11 */ = {
			isa = PBXGroup;
			children = (
				F966BD1B08F27A3F005CB29B /* cursorfont.h */,
				F966BD1C08F27A3F005CB29B /* keysym.h */,
				F966BD1D08F27A3F005CB29B /* keysymdef.h */,
				F966BD1E08F27A3F005CB29B /* X.h */,
				F966BD1F08F27A3F005CB29B /* Xatom.h */,
				F966BD2008F27A3F005CB29B /* Xfuncproto.h */,
				F966BD2108F27A3F005CB29B /* Xlib.h */,
				F966BD2208F27A3F005CB29B /* Xutil.h */,
			);
			path = X11;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */,
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F96437E60EF0D652003F468E /* libz.dylib */,
				F966C07608F2821B005CB29B /* Carbon.framework */,
				F94523A10E6FC2AC00C1D987 /* Cocoa.framework */,
				F966C07808F28233005CB29B /* IOKit.framework */,
				F9FD32140CC1AF170073837D /* libX11.dylib */,
				F9FD32150CC1AF170073837D /* libXext.dylib */,
				F9FD32160CC1AF170073837D /* libXss.dylib */,
				F9FD349A0CC1BB0D0073837D /* libXft.dylib */,
				F9FD34990CC1BB0D0073837D /* libfreetype.dylib */,
				F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96887DF0AF786D5000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96887E00AF786D5000797B5 /* ttk.decls */,
				F96887E10AF786D5000797B5 /* ttkBlink.c */,
				F96887E20AF786D5000797B5 /* ttkButton.c */,
				F96887E30AF786D5000797B5 /* ttkCache.c */,
				F96887E40AF786D5000797B5 /* ttkClamTheme.c */,
				F96887E50AF786D5000797B5 /* ttkClassicTheme.c */,
				F96887E60AF786D5000797B5 /* ttkDecls.h */,
				F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */,
				F96887E80AF786D5000797B5 /* ttkElements.c */,
				F96887E90AF786D5000797B5 /* ttkEntry.c */,
				F96887EA0AF786D5000797B5 /* ttkFrame.c */,
				F96887EB0AF786D5000797B5 /* ttkImage.c */,
				F96887EC0AF786D5000797B5 /* ttkInit.c */,
				F96887ED0AF786D5000797B5 /* ttkLabel.c */,
				F96887EE0AF786D5000797B5 /* ttkLayout.c */,
				F96887EF0AF786D5000797B5 /* ttkManager.c */,
				F96887F00AF786D5000797B5 /* ttkManager.h */,
				F96887F10AF786D5000797B5 /* ttkNotebook.c */,
				F96887F20AF786D5000797B5 /* ttkPanedwindow.c */,
				F96887F30AF786D5000797B5 /* ttkProgress.c */,
				F96887F40AF786D5000797B5 /* ttkScale.c */,
				F96887F50AF786D5000797B5 /* ttkScroll.c */,
				F96887F60AF786D5000797B5 /* ttkScrollbar.c */,
				F96887F70AF786D5000797B5 /* ttkSeparator.c */,
				F96887F80AF786D5000797B5 /* ttkSquare.c */,
				F96887F90AF786D5000797B5 /* ttkState.c */,
				F96887FA0AF786D5000797B5 /* ttkStubInit.c */,
				F96887FB0AF786D5000797B5 /* ttkStubLib.c */,
				F96887FC0AF786D5000797B5 /* ttkTagSet.c */,
				F96887FD0AF786D5000797B5 /* ttkTheme.c */,
				F96887FE0AF786D5000797B5 /* ttkTheme.h */,
				F96887FF0AF786D5000797B5 /* ttkThemeInt.h */,
				F96888000AF786D5000797B5 /* ttkTrace.c */,
				F96888010AF786D5000797B5 /* ttkTrack.c */,
				F96888020AF786D5000797B5 /* ttkTreeview.c */,
				F96888030AF786D5000797B5 /* ttkWidget.c */,
				F96888040AF786D5000797B5 /* ttkWidget.h */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888360AF787B3000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888370AF787B3000797B5 /* altTheme.tcl */,
				F96888380AF787B3000797B5 /* aquaTheme.tcl */,
				F96888390AF787B3000797B5 /* button.tcl */,
				F968883A0AF787B3000797B5 /* clamTheme.tcl */,
				F968883B0AF787B3000797B5 /* classicTheme.tcl */,
				F968883C0AF787B3000797B5 /* combobox.tcl */,
				F968883D0AF787B3000797B5 /* cursors.tcl */,
				F968883E0AF787B3000797B5 /* defaults.tcl */,
				F96888400AF787B3000797B5 /* entry.tcl */,
				F96888410AF787B3000797B5 /* fonts.tcl */,
				F96888440AF787B3000797B5 /* menubutton.tcl */,
				F96888450AF787B3000797B5 /* notebook.tcl */,
				F96888460AF787B3000797B5 /* panedwindow.tcl */,
				F96888470AF787B3000797B5 /* progress.tcl */,
				F96888480AF787B3000797B5 /* scale.tcl */,
				F96888490AF787B3000797B5 /* scrollbar.tcl */,
				F968884A0AF787B3000797B5 /* sizegrip.tcl */,
				F968884B0AF787B3000797B5 /* treeview.tcl */,
				F968884C0AF787B3000797B5 /* ttk.tcl */,
				F968884D0AF787B3000797B5 /* utils.tcl */,
				F968884E0AF787B3000797B5 /* winTheme.tcl */,
				F973E5960EE99384001A648E /* vistaTheme.tcl */,
				F968884F0AF787B3000797B5 /* xpTheme.tcl */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888530AF7880C000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888540AF7880C000797B5 /* all.tcl */,
				F98383650F0FA43900171CA6 /* checkbutton.test */,
				F96888560AF7880C000797B5 /* combobox.test */,
				F96888570AF7880C000797B5 /* entry.test */,
				F96888580AF7880C000797B5 /* image.test */,
				F96888590AF7880C000797B5 /* labelframe.test */,
				F968885A0AF7880C000797B5 /* layout.test */,
				F968885C0AF7880C000797B5 /* notebook.test */,
				F968885D0AF7880C000797B5 /* panedwindow.test */,
				F968885E0AF7880C000797B5 /* progressbar.test */,
				F98383680F0FA44700171CA6 /* radiobutton.test */,
				F968885F0AF7880C000797B5 /* scrollbar.test */,
				F96888600AF7880C000797B5 /* treetags.test */,
				F96888610AF7880C000797B5 /* treeview.test */,
				F96888620AF7880C000797B5 /* ttk.test */,
				F96888630AF7880C000797B5 /* validate.test */,
				F962F7C60DADC26200648DB8 /* vsapi.test */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E0F08F272A5004A47F5 /* case.n */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F93599CF0DF1F87F00E04F67 /* Class.3 */,
				F93599D00DF1F89E00E04F67 /* class.n */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F93599D20DF1F8DF00E04F67 /* copy.n */,
				F974D5720FBE7DC600BF728B /* coroutine.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F93599D40DF1F91900E04F67 /* Method.3 */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F93599D50DF1F93700E04F67 /* my.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F93599D60DF1F95000E04F67 /* next.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F93599D70DF1F96800E04F67 /* object.n */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F93599D80DF1F98300E04F67 /* self.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F974D5760FBE7E1900BF728B /* tailcall.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F9183E640EFC80CD0030B814 /* throw.n */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F9183E650EFC80D70030B814 /* try.n */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
				F915432D0EF201EE0032D1E8 /* zlib.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F93599B20DF1F75400E04F67 /* tclOO.c */,
				F93599B40DF1F75900E04F67 /* tclOO.decls */,
				F93599B50DF1F75D00E04F67 /* tclOO.h */,
				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96437C90EF0D4B2003F468E /* tclZlib.c */,
				F96D3F3708F272A7004A47F5 /* tommath.h */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9008F272A8004A47F5 /* http1.0 */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
			isa = PBXGroup;
			children = (
				F96D3F9108F272A8004A47F5 /* http.tcl */,
				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http1.0;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D42D708F272B3004A47F5 /* bncore.c */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F974D5770FBE7E6100BF728B /* coroutine.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F974D56C0FBE7D6300BF728B /* http11.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F91DC23C0E44C51B002CB8D1 /* nre.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F93599C80DF1F81900E04F67 /* oo.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F974D5780FBE7E6100BF728B /* tailcall.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
				F915432A0EF201CF0032D1E8 /* zlib.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.ac */,
				F96D442208F272B8004A47F5 /* eolFix.tcl */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D442C08F272B8004A47F5 /* man2help.tcl */,
				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
				F96D442E08F272B8004A47F5 /* man2html.tcl */,
				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
				F96D443008F272B8004A47F5 /* man2html2.tcl */,
				F96D443108F272B8004A47F5 /* man2tcl.c */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
				F96D443608F272B8004A47F5 /* tcl.wse.in */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446A08F272B9004A47F5 /* tclUnixThrd.h */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tktest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
				F9A5C5F608F651AB008AE941 /* Configure Tk */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tktest;
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = 8DD76FB20486AB0100D96B5E /* tktest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tktest-X11 */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */;
			buildPhases = (
				F9FD30B40CC1AD070073837D /* Configure Tcl */,
				F9FD30B50CC1AD070073837D /* Configure Tk */,
				F9FD30BB0CC1AD070073837D /* Sources */,
				F9FD31E30CC1AD070073837D /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = "tktest-X11";
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = F9FD31F40CC1AD070073837D /* tktest-X11 */;
			productType = "com.apple.product-type.tool";
		};
		F9E61D16090A3E94002B3151 /* Tk */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* Build Tk */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tk;
			productName = Wish;
			productReference = F9A3084B08F2D4CE00BAE1AB /* Wish.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */;
			compatibilityVersion = "Xcode 3.1";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Tk */;
			projectDirPath = "";
			projectRoot = ..;
			targets = (
				F9E61D16090A3E94002B3151 /* Tk */,
				8DD76FA90486AB0100D96B5E /* tktest */,
				F97258A50A86873C00096C78 /* tktest-X11 */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F97AF02F0B665DA900310EA2 /* Build Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			name = "Build Tk";
			outputPaths = (
				"${TARGET_BUILD_DIR}/${WRAPPER_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "export CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TK_SRCROOT}/macosx\"  -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" APPLICATION_INSTALL_PATH=\"${APPLICATION_INSTALL_PATH}\" TCL_BUILD_DIR=\"${TCL_BUILD_DIR}\" TCL_FRAMEWORK_DIR=\"${TCL_FRAMEWORK_DIR}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${BUILT_PRODUCTS_DIR}/tktest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tktest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F608F651AB008AE941 /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B40CC1AD070073837D /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B50CC1AD070073837D /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
				F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */,
				F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */,
				F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */,
				F966BDD308F27A3F005CB29B /* tkBind.c in Sources */,
				F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */,
				F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */,
				F966BDD508F27A3F005CB29B /* tkButton.c in Sources */,
				F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */,
				F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */,
				F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */,
				F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */,
				F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */,
				F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */,
				F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */,
				F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */,
				F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */,
				F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */,
				F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */,
				F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */,
				F966BDE508F27A3F005CB29B /* tkColor.c in Sources */,
				F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */,
				F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */,
				F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */,
				F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */,
				F966BDED08F27A3F005CB29B /* tkError.c in Sources */,
				F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */,
				F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */,
				F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */,
				F966BDF208F27A3F005CB29B /* tkFont.c in Sources */,
				F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */,
				F966BDF508F27A3F005CB29B /* tkGC.c in Sources */,
				F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */,
				F966BDF708F27A3F005CB29B /* tkGet.c in Sources */,
				F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */,
				F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */,
				F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */,
				F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */,
				F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */,
				F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */,
				F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */,
				F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */,
				F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */,
				F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */,
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
				F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */,
				F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */,
				F966BE2008F27A40005CB29B /* tkSquare.c in Sources */,
				F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */,
				F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */,
				F966BE2408F27A40005CB29B /* tkStyle.c in Sources */,
				F966BE2508F27A40005CB29B /* tkTest.c in Sources */,
				F966BE2608F27A40005CB29B /* tkText.c in Sources */,
				F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */,
				F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */,
				F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */,
				F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */,
				F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */,
				F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */,
				F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */,
				F966BE3008F27A40005CB29B /* tkTrig.c in Sources */,
				F966BE3108F27A40005CB29B /* tkUndo.c in Sources */,
				F966BE3308F27A40005CB29B /* tkUtil.c in Sources */,
				F966BE3408F27A40005CB29B /* tkVisual.c in Sources */,
				F966BE3508F27A40005CB29B /* tkWindow.c in Sources */,
				F96888050AF786D5000797B5 /* ttkBlink.c in Sources */,
				F96888060AF786D5000797B5 /* ttkButton.c in Sources */,
				F96888070AF786D5000797B5 /* ttkCache.c in Sources */,
				F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */,
				F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */,
				F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */,
				F968880B0AF786D5000797B5 /* ttkElements.c in Sources */,
				F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */,
				F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */,
				F968880E0AF786D5000797B5 /* ttkImage.c in Sources */,
				F968880F0AF786D5000797B5 /* ttkInit.c in Sources */,
				F96888100AF786D5000797B5 /* ttkLabel.c in Sources */,
				F96888110AF786D5000797B5 /* ttkLayout.c in Sources */,
				F96888120AF786D5000797B5 /* ttkManager.c in Sources */,
				F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */,
				F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */,
				F96888150AF786D5000797B5 /* ttkProgress.c in Sources */,
				F96888160AF786D5000797B5 /* ttkScale.c in Sources */,
				F96888170AF786D5000797B5 /* ttkScroll.c in Sources */,
				F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */,
				F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */,
				F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */,
				F968881B0AF786D5000797B5 /* ttkState.c in Sources */,
				F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */,
				F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */,
				F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */,
				F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */,
				F96888200AF786D5000797B5 /* ttkTrace.c in Sources */,
				F96888210AF786D5000797B5 /* ttkTrack.c in Sources */,
				F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */,
				F96888230AF786D5000797B5 /* ttkWidget.c in Sources */,
				F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */,
				F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */,
				F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */,
				F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */,
				F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */,
				F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */,
				F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */,
				F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */,
				F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */,
				F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */,
				F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */,
				F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */,
				F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */,
				F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */,
				F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */,
				F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */,
				F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */,
				F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */,
				F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */,
				F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */,
				F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */,
				F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */,
				F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */,
				F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */,
				F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */,
				F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */,
				F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */,
				F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */,
				F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */,
				F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */,
				F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */,
				F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */,
				F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */,
				F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */,
				F966C02A08F27A42005CB29B /* xcolors.c in Sources */,
				F966C02B08F27A42005CB29B /* xdraw.c in Sources */,
				F966C02C08F27A42005CB29B /* xgc.c in Sources */,
				F966C02D08F27A42005CB29B /* ximage.c in Sources */,
				F966C02E08F27A42005CB29B /* xutil.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD30BB0CC1AD070073837D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */,
				F9FD30BD0CC1AD070073837D /* regerror.c in Sources */,
				F9FD30BE0CC1AD070073837D /* regexec.c in Sources */,
				F9FD30BF0CC1AD070073837D /* regfree.c in Sources */,
				F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */,
				F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */,
				F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */,
				F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */,
				F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */,
				F9FD30C50CC1AD070073837D /* tclClock.c in Sources */,
				F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */,
				F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */,
				F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */,
				F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */,
				F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */,
				F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */,
				F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */,
				F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */,
				F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */,
				F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */,
				F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */,
				F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */,
				F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */,
				F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */,
				F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */,
				F9FD30D50CC1AD070073837D /* tclGet.c in Sources */,
				F9FD30D60CC1AD070073837D /* tclHash.c in Sources */,
				F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */,
				F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */,
				F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */,
				F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */,
				F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */,
				F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */,
				F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */,
				F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */,
				F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */,
				F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */,
				F9FD30E00CC1AD070073837D /* tclLink.c in Sources */,
				F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */,
				F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */,
				F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */,
				F9FD30E40CC1AD070073837D /* tclMain.c in Sources */,
				F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */,
				F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */,
				F9FD30E70CC1AD070073837D /* tclObj.c in Sources */,
				F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */,
				F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */,
				F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */,
				F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */,
				F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */,
				F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */,
				F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */,
				F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */,
				F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */,
				F9FD30E90CC1AD070073837D /* tclParse.c in Sources */,
				F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */,
				F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */,
				F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */,
				F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */,
				F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */,
				F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */,
				F9FD30F00CC1AD070073837D /* tclProc.c in Sources */,
				F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */,
				F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */,
				F9FD30F30CC1AD070073837D /* tclResult.c in Sources */,
				F9FD30F40CC1AD070073837D /* tclScan.c in Sources */,
				F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */,
				F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */,
				F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */,
				F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */,
				F9FD30F90CC1AD070073837D /* tclThread.c in Sources */,
				F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */,
				F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */,
				F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */,
				F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */,
				F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */,
				F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */,
				F9FD31000CC1AD070073837D /* tclUtf.c in Sources */,
				F9FD31010CC1AD070073837D /* tclUtil.c in Sources */,
				F9FD31020CC1AD070073837D /* tclVar.c in Sources */,
				F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */,
				F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */,
				F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */,
				F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */,
				F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */,
				F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */,
				F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */,
				F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */,
				F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */,
				F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */,
				F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */,
				F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */,
				F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */,
				F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */,
				F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */,
				F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */,
				F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */,
				F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */,
				F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */,
				F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */,
				F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */,
				F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */,
				F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */,
				F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */,
				F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */,
				F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */,
				F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */,
				F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */,
				F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */,
				F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */,
				F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */,
				F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */,
				F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */,
				F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */,
				F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */,
				F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */,
				F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */,
				F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */,
				F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */,
				F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */,
				F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */,
				F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */,
				F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */,
				F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */,
				F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */,
				F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */,
				F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */,
				F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */,
				F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */,
				F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */,
				F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */,
				F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */,
				F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */,
				F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */,
				F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */,
				F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */,
				F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */,
				F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */,
				F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */,
				F9FD313F0CC1AD070073837D /* bncore.c in Sources */,
				F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */,
				F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */,
				F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */,
				F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */,
				F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */,
				F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */,
				F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */,
				F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */,
				F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */,
				F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */,
				F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */,
				F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */,
				F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */,
				F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */,
				F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */,
				F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */,
				F9FD314F0CC1AD070073837D /* tk3d.c in Sources */,
				F9FD31500CC1AD070073837D /* tkArgv.c in Sources */,
				F9FD31510CC1AD070073837D /* tkAtom.c in Sources */,
				F9FD31520CC1AD070073837D /* tkBind.c in Sources */,
				F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */,
				F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */,
				F9FD31540CC1AD070073837D /* tkButton.c in Sources */,
				F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */,
				F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */,
				F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */,
				F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */,
				F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */,
				F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */,
				F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */,
				F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */,
				F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */,
				F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */,
				F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */,
				F9FD31600CC1AD070073837D /* tkCmds.c in Sources */,
				F9FD31610CC1AD070073837D /* tkColor.c in Sources */,
				F9FD31620CC1AD070073837D /* tkConfig.c in Sources */,
				F9FD31630CC1AD070073837D /* tkConsole.c in Sources */,
				F9FD31640CC1AD070073837D /* tkCursor.c in Sources */,
				F9FD31650CC1AD070073837D /* tkEntry.c in Sources */,
				F9FD31660CC1AD070073837D /* tkError.c in Sources */,
				F9FD31670CC1AD070073837D /* tkEvent.c in Sources */,
				F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */,
				F9FD31690CC1AD070073837D /* tkFocus.c in Sources */,
				F9FD316A0CC1AD070073837D /* tkFont.c in Sources */,
				F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */,
				F9FD316C0CC1AD070073837D /* tkGC.c in Sources */,
				F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */,
				F9FD316E0CC1AD070073837D /* tkGet.c in Sources */,
				F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */,
				F9FD31700CC1AD070073837D /* tkGrid.c in Sources */,
				F9FD31710CC1AD070073837D /* tkImage.c in Sources */,
				F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */,
				F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */,
				F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */,
				F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */,
				F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */,
				F9FD31760CC1AD070073837D /* tkListbox.c in Sources */,
				F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */,
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
				F9FD31880CC1AD070073837D /* tkSelect.c in Sources */,
				F9FD31890CC1AD070073837D /* tkSquare.c in Sources */,
				F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */,
				F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */,
				F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */,
				F9FD318D0CC1AD070073837D /* tkTest.c in Sources */,
				F9FD318E0CC1AD070073837D /* tkText.c in Sources */,
				F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */,
				F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */,
				F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */,
				F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */,
				F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */,
				F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */,
				F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */,
				F9FD31960CC1AD070073837D /* tkTrig.c in Sources */,
				F9FD31970CC1AD070073837D /* tkUndo.c in Sources */,
				F9FD31980CC1AD070073837D /* tkUtil.c in Sources */,
				F9FD31990CC1AD070073837D /* tkVisual.c in Sources */,
				F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */,
				F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */,
				F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */,
				F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */,
				F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */,
				F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */,
				F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */,
				F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */,
				F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */,
				F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */,
				F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */,
				F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */,
				F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */,
				F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */,
				F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */,
				F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */,
				F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */,
				F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */,
				F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */,
				F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */,
				F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */,
				F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */,
				F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */,
				F9FD31B10CC1AD070073837D /* ttkState.c in Sources */,
				F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */,
				F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */,
				F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */,
				F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */,
				F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */,
				F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */,
				F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */,
				F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */,
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
				F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */,
				F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */,
				F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */,
				F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */,
				F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */,
				F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */,
				F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */,
				F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		F90E36D50F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoGC;
		};
		F90E36D60F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoGC;
		};
		F90E36D70F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoGC;
		};
		F90E36D80F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoGC;
		};
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc40";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc40";
		};
		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugLeaks;
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F90E36D60F3B5C8400810A10 /* DebugNoGC */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F90E36D70F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F90E36D50F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F90E36D80F3B5C8400810A10 /* DebugNoGC */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted macosx/Tk.xcodeproj/default.pbxuser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* Wish */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tk */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
			F944EB8F08F798100049FDD4 /* tktest */,
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a0b707265666572656e63657386928497960892849a9a0669734c6561668692848484084e534e756d626572008484074e5356616c7565009584012a849696008692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a09726563757273697665869284a29da496018692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a0763616e536176658692a892849a9a1250425850726f6a65637453636f70654b65798692849a9a035945538692849a9a0572656765788692849a9a065c2e286329248692849a9a07666e6d617463688692849a9a00868692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a08676c6f62616c49448692849a9a183143433045413430303433353045463930303434343130428692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f7570868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			SYMROOT = "${SRCROOT}/../../build/tk";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
			TK_SRCROOT = "${SRCROOT}/../../tk";
		};
	};
	8DD76FA90486AB0100D96B5E /* tktest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tktest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tktest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		dataTipCustomDataFormattersEnabled = 1;
		dataTipShowTypeColumn = 1;
		dataTipSortType = 0;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = TK_SRCROOT;
				value = "${TK_SRCROOT}";
			},
			{
				active = NO;
				name = TK_CONSOLE;
				value = 1;
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = NSTraceEvents;
				value = YES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
			{
				active = NO;
				name = NSZombieEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSDeallocateZombies;
				value = YES;
			},
			{
				active = NO;
				name = NSAutoreleaseFreedObjectCheckEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSEnableAutoreleasePool;
				value = NO;
			},
			{
				active = NO;
				name = AUTO_LOG_ALL;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_LOG_NOISY;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_REFERENCE_COUNT_LOGGING;
				value = YES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tktest;
		showTypeColumn = 0;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		repositoryNamesForRoots = {
			.. = "";
		};
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
			repositoryNamesForRoots = {
				.. = "";
			};
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F97258A50A86873C00096C78 /* tktest-X11 */ = {
		activeExec = 0;
		executables = (
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
	};
	F9E61D16090A3E94002B3151 /* Tk */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
		);
	};
	F9E61D1C090A4282002B3151 /* Wish */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		dataTipCustomDataFormattersEnabled = 1;
		dataTipShowTypeColumn = 1;
		dataTipSortType = 0;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = Wish;
		showTypeColumn = 0;
		sourceDirectories = (
		);
	};
	F9FD31F50CC1AD070073837D /* tktest-X11 */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		dataTipCustomDataFormattersEnabled = 1;
		dataTipShowTypeColumn = 1;
		dataTipSortType = 0;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = DISPLAY;
				value = ":0";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = "tktest-X11";
		showTypeColumn = 0;
		sourceDirectories = (
		);
	};
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































Deleted macosx/Tk.xcodeproj/project.pbxproj.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
		F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F94523A10E6FC2AC00C1D987 /* Cocoa.framework */; };
		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F96437E80EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F966BDD308F27A3F005CB29B /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F966BDD508F27A3F005CB29B /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F966BDE508F27A3F005CB29B /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F966BDED08F27A3F005CB29B /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F966BDF208F27A3F005CB29B /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F966BDF508F27A3F005CB29B /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F966BDF708F27A3F005CB29B /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F966BE0908F27A3F005CB29B /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F966BE1008F27A3F005CB29B /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F966BE1208F27A3F005CB29B /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F966BE1308F27A3F005CB29B /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF408F27A39005CB29B /* tkPointer.c */; };
		F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F966BE2008F27A40005CB29B /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F966BE2408F27A40005CB29B /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F966BE2508F27A40005CB29B /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F966BE2608F27A40005CB29B /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F966BE3008F27A40005CB29B /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F966BE3108F27A40005CB29B /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F966BE3308F27A40005CB29B /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F966BE3408F27A40005CB29B /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F966BE3508F27A40005CB29B /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */; };
		F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */; };
		F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */; };
		F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */; };
		F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */; };
		F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */; };
		F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */; };
		F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */; };
		F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */; };
		F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */; };
		F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */; };
		F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */; };
		F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */; };
		F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */; };
		F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */; settings = {COMPILER_FLAGS = "-DTK_LIBRARY=\\\"$(TK_LIBRARY)\\\""; }; };
		F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */; };
		F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */; };
		F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */; };
		F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */; };
		F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */; };
		F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */; };
		F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */; };
		F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */; };
		F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */; };
		F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */; };
		F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */; };
		F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */; };
		F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */; };
		F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */; };
		F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */; };
		F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F966C02A08F27A42005CB29B /* xcolors.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2408F27A3F005CB29B /* xcolors.c */; };
		F966C02B08F27A42005CB29B /* xdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2508F27A3F005CB29B /* xdraw.c */; };
		F966C02C08F27A42005CB29B /* xgc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2608F27A3F005CB29B /* xgc.c */; };
		F966C02D08F27A42005CB29B /* ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2708F27A3F005CB29B /* ximage.c */; };
		F966C02E08F27A42005CB29B /* xutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2808F27A3F005CB29B /* xutil.c */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07608F2821B005CB29B /* Carbon.framework */; };
		F966C07908F28233005CB29B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07808F28233005CB29B /* IOKit.framework */; };
		F96888050AF786D5000797B5 /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F96888060AF786D5000797B5 /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F96888070AF786D5000797B5 /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F968880B0AF786D5000797B5 /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F968880E0AF786D5000797B5 /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F968880F0AF786D5000797B5 /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F96888100AF786D5000797B5 /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F96888110AF786D5000797B5 /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F96888120AF786D5000797B5 /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F96888150AF786D5000797B5 /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F96888160AF786D5000797B5 /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F96888170AF786D5000797B5 /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F968881B0AF786D5000797B5 /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F96888200AF786D5000797B5 /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F96888210AF786D5000797B5 /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F96888230AF786D5000797B5 /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888840AF78938000797B5 /* ttkMacOSXTheme.c */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */; };
		F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F9FD30BD0CC1AD070073837D /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F9FD30BE0CC1AD070073837D /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F9FD30BF0CC1AD070073837D /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F9FD30C50CC1AD070073837D /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F9FD30D50CC1AD070073837D /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F9FD30D60CC1AD070073837D /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F9FD30E00CC1AD070073837D /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F9FD30E40CC1AD070073837D /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F9FD30E70CC1AD070073837D /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F9FD30E90CC1AD070073837D /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F9FD30F00CC1AD070073837D /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F9FD30F30CC1AD070073837D /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F9FD30F40CC1AD070073837D /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F9FD30F90CC1AD070073837D /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F9FD31000CC1AD070073837D /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F9FD31010CC1AD070073837D /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F9FD31020CC1AD070073837D /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F9FD313F0CC1AD070073837D /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9FD314F0CC1AD070073837D /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F9FD31500CC1AD070073837D /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F9FD31510CC1AD070073837D /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F9FD31520CC1AD070073837D /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F9FD31540CC1AD070073837D /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F9FD31600CC1AD070073837D /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F9FD31610CC1AD070073837D /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F9FD31620CC1AD070073837D /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F9FD31630CC1AD070073837D /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F9FD31640CC1AD070073837D /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F9FD31650CC1AD070073837D /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F9FD31660CC1AD070073837D /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F9FD31670CC1AD070073837D /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F9FD31690CC1AD070073837D /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F9FD316A0CC1AD070073837D /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F9FD316C0CC1AD070073837D /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F9FD316E0CC1AD070073837D /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F9FD31700CC1AD070073837D /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F9FD31710CC1AD070073837D /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F9FD31760CC1AD070073837D /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F9FD31880CC1AD070073837D /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F9FD31890CC1AD070073837D /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F9FD318D0CC1AD070073837D /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F9FD318E0CC1AD070073837D /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F9FD31960CC1AD070073837D /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F9FD31970CC1AD070073837D /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F9FD31980CC1AD070073837D /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F9FD31990CC1AD070073837D /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F9FD31B10CC1AD070073837D /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */; };
		F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8708F27A3D005CB29B /* tkUnixKey.c */; };
		F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9108F27A3D005CB29B /* tkUnixXId.c */; };
		F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8508F27A3D005CB29B /* tkUnixInit.c */; };
		F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */; };
		F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8F08F27A3D005CB29B /* tkUnixSend.c */; };
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
		F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32150CC1AF170073837D /* libXext.dylib */; };
		F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32160CC1AF170073837D /* libXss.dylib */; };
		F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34990CC1BB0D0073837D /* libfreetype.dylib */; };
		F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD349A0CC1BB0D0073837D /* libXft.dylib */; };
		F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */; };
		F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tktest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tktest; sourceTree = BUILT_PRODUCTS_DIR; };
		F9099B8A0CC67D30005A9580 /* textpeer.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textpeer.tcl; sourceTree = "<group>"; };
		F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkbut.tcl; sourceTree = "<group>"; };
		F9152B080EAF8A5000CD5C7B /* tkBusy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBusy.c; sourceTree = "<group>"; };
		F91543270EF201A90032D1E8 /* fontchoose.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchoose.tcl; sourceTree = "<group>"; };
		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92240290D7C620F005EC715 /* knightstour.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = knightstour.tcl; sourceTree = "<group>"; };
		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
		F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhInstance.c; sourceTree = "<group>"; };
		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
		F936FCD70CCD984500716967 /* ttkprogress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkprogress.tcl; sourceTree = "<group>"; };
		F936FCD80CCD984600716967 /* tree.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tree.tcl; sourceTree = "<group>"; };
		F936FCD90CCD984600716967 /* toolbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = toolbar.tcl; sourceTree = "<group>"; };
		F936FCDA0CCD984600716967 /* ttknote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttknote.tcl; sourceTree = "<group>"; };
		F936FCDB0CCD984600716967 /* combo.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combo.tcl; sourceTree = "<group>"; };
		F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXFont.h; sourceTree = "<group>"; };
		F94523A10E6FC2AC00C1D987 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
		F95D8D4B0F1715610006B020 /* Tk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Tk.icns; sourceTree = "<group>"; };
		F95D8D4C0F1715610006B020 /* Tk.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Tk.tiff; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F962F7C60DADC26200648DB8 /* vsapi.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vsapi.test; sourceTree = "<group>"; };
		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
		F966BA0408F27A37005CB29B /* error.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = error.xbm; sourceTree = "<group>"; };
		F966BA0508F27A37005CB29B /* gray12.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray12.xbm; sourceTree = "<group>"; };
		F966BA0608F27A37005CB29B /* gray25.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray25.xbm; sourceTree = "<group>"; };
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
		F966BA1808F27A37005CB29B /* button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = button.n; sourceTree = "<group>"; };
		F966BA1908F27A37005CB29B /* canvas.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = canvas.n; sourceTree = "<group>"; };
		F966BA1A08F27A37005CB29B /* CanvPsY.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvPsY.3; sourceTree = "<group>"; };
		F966BA1B08F27A37005CB29B /* CanvTkwin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTkwin.3; sourceTree = "<group>"; };
		F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTxtInfo.3; sourceTree = "<group>"; };
		F966BA1D08F27A37005CB29B /* checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = checkbutton.n; sourceTree = "<group>"; };
		F966BA1E08F27A37005CB29B /* chooseColor.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseColor.n; sourceTree = "<group>"; };
		F966BA1F08F27A37005CB29B /* chooseDirectory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseDirectory.n; sourceTree = "<group>"; };
		F966BA2008F27A37005CB29B /* Clipboard.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Clipboard.3; sourceTree = "<group>"; };
		F966BA2108F27A37005CB29B /* clipboard.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clipboard.n; sourceTree = "<group>"; };
		F966BA2208F27A37005CB29B /* ClrSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ClrSelect.3; sourceTree = "<group>"; };
		F966BA2308F27A37005CB29B /* colors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = colors.n; sourceTree = "<group>"; };
		F966BA2408F27A37005CB29B /* ConfigWidg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWidg.3; sourceTree = "<group>"; };
		F966BA2508F27A37005CB29B /* ConfigWind.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWind.3; sourceTree = "<group>"; };
		F966BA2608F27A37005CB29B /* console.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = console.n; sourceTree = "<group>"; };
		F966BA2708F27A37005CB29B /* CoordToWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CoordToWin.3; sourceTree = "<group>"; };
		F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCmHdlr.3; sourceTree = "<group>"; };
		F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtErrHdlr.3; sourceTree = "<group>"; };
		F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtGenHdlr.3; sourceTree = "<group>"; };
		F966BA2B08F27A37005CB29B /* CrtImgType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtImgType.3; sourceTree = "<group>"; };
		F966BA2C08F27A37005CB29B /* CrtItemType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtItemType.3; sourceTree = "<group>"; };
		F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtPhImgFmt.3; sourceTree = "<group>"; };
		F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSelHdlr.3; sourceTree = "<group>"; };
		F966BA2F08F27A37005CB29B /* CrtWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtWindow.3; sourceTree = "<group>"; };
		F966BA3008F27A37005CB29B /* cursors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cursors.n; sourceTree = "<group>"; };
		F966BA3108F27A37005CB29B /* DeleteImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DeleteImg.3; sourceTree = "<group>"; };
		F966BA3208F27A37005CB29B /* destroy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = destroy.n; sourceTree = "<group>"; };
		F966BA3308F27A37005CB29B /* dialog.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dialog.n; sourceTree = "<group>"; };
		F966BA3408F27A37005CB29B /* DrawFocHlt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DrawFocHlt.3; sourceTree = "<group>"; };
		F966BA3508F27A37005CB29B /* entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = entry.n; sourceTree = "<group>"; };
		F966BA3608F27A37005CB29B /* event.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = event.n; sourceTree = "<group>"; };
		F966BA3708F27A37005CB29B /* EventHndlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = EventHndlr.3; sourceTree = "<group>"; };
		F966BA3808F27A37005CB29B /* FindPhoto.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindPhoto.3; sourceTree = "<group>"; };
		F966BA3908F27A37005CB29B /* focus.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focus.n; sourceTree = "<group>"; };
		F966BA3A08F27A37005CB29B /* focusNext.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focusNext.n; sourceTree = "<group>"; };
		F966BA3B08F27A37005CB29B /* font.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = font.n; sourceTree = "<group>"; };
		F966BA3C08F27A37005CB29B /* FontId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FontId.3; sourceTree = "<group>"; };
		F966BA3D08F27A37005CB29B /* frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = frame.n; sourceTree = "<group>"; };
		F966BA3E08F27A37005CB29B /* FreeXId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FreeXId.3; sourceTree = "<group>"; };
		F966BA3F08F27A37005CB29B /* GeomReq.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GeomReq.3; sourceTree = "<group>"; };
		F966BA4008F27A37005CB29B /* GetAnchor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetAnchor.3; sourceTree = "<group>"; };
		F966BA4108F27A37005CB29B /* GetBitmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetBitmap.3; sourceTree = "<group>"; };
		F966BA4208F27A37005CB29B /* GetCapStyl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCapStyl.3; sourceTree = "<group>"; };
		F966BA4308F27A37005CB29B /* GetClrmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetClrmap.3; sourceTree = "<group>"; };
		F966BA4408F27A37005CB29B /* GetColor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetColor.3; sourceTree = "<group>"; };
		F966BA4508F27A37005CB29B /* GetCursor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCursor.3; sourceTree = "<group>"; };
		F966BA4608F27A37005CB29B /* GetDash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetDash.3; sourceTree = "<group>"; };
		F966BA4708F27A37005CB29B /* GetFont.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetFont.3; sourceTree = "<group>"; };
		F966BA4808F27A37005CB29B /* GetGC.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetGC.3; sourceTree = "<group>"; };
		F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHINSTANCE.3; sourceTree = "<group>"; };
		F966BA4A08F27A37005CB29B /* GetHWND.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHWND.3; sourceTree = "<group>"; };
		F966BA4B08F27A37005CB29B /* GetImage.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetImage.3; sourceTree = "<group>"; };
		F966BA4C08F27A37005CB29B /* GetJoinStl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJoinStl.3; sourceTree = "<group>"; };
		F966BA4D08F27A37005CB29B /* GetJustify.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJustify.3; sourceTree = "<group>"; };
		F966BA4E08F27A37005CB29B /* getOpenFile.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = getOpenFile.n; sourceTree = "<group>"; };
		F966BA4F08F27A37005CB29B /* GetOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOption.3; sourceTree = "<group>"; };
		F966BA5008F27A38005CB29B /* GetPixels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixels.3; sourceTree = "<group>"; };
		F966BA5108F27A38005CB29B /* GetPixmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixmap.3; sourceTree = "<group>"; };
		F966BA5208F27A38005CB29B /* GetRelief.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRelief.3; sourceTree = "<group>"; };
		F966BA5308F27A38005CB29B /* GetRootCrd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRootCrd.3; sourceTree = "<group>"; };
		F966BA5408F27A38005CB29B /* GetScroll.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetScroll.3; sourceTree = "<group>"; };
		F966BA5508F27A38005CB29B /* GetSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetSelect.3; sourceTree = "<group>"; };
		F966BA5608F27A38005CB29B /* GetUid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetUid.3; sourceTree = "<group>"; };
		F966BA5708F27A38005CB29B /* GetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVisual.3; sourceTree = "<group>"; };
		F966BA5808F27A38005CB29B /* GetVRoot.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVRoot.3; sourceTree = "<group>"; };
		F966BA5908F27A38005CB29B /* Grab.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Grab.3; sourceTree = "<group>"; };
		F966BA5A08F27A38005CB29B /* grab.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grab.n; sourceTree = "<group>"; };
		F966BA5B08F27A38005CB29B /* grid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grid.n; sourceTree = "<group>"; };
		F966BA5C08F27A38005CB29B /* HandleEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HandleEvent.3; sourceTree = "<group>"; };
		F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HWNDToWindow.3; sourceTree = "<group>"; };
		F966BA5E08F27A38005CB29B /* IdToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IdToWindow.3; sourceTree = "<group>"; };
		F966BA5F08F27A38005CB29B /* image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = image.n; sourceTree = "<group>"; };
		F966BA6008F27A38005CB29B /* ImgChanged.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ImgChanged.3; sourceTree = "<group>"; };
		F966BA6108F27A38005CB29B /* Inactive.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Inactive.3; sourceTree = "<group>"; };
		F966BA6208F27A38005CB29B /* InternAtom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InternAtom.3; sourceTree = "<group>"; };
		F966BA6308F27A38005CB29B /* keysyms.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = keysyms.n; sourceTree = "<group>"; };
		F966BA6408F27A38005CB29B /* label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = label.n; sourceTree = "<group>"; };
		F966BA6508F27A38005CB29B /* labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = labelframe.n; sourceTree = "<group>"; };
		F966BA6608F27A38005CB29B /* listbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = listbox.n; sourceTree = "<group>"; };
		F966BA6708F27A38005CB29B /* loadTk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = loadTk.n; sourceTree = "<group>"; };
		F966BA6808F27A38005CB29B /* lower.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lower.n; sourceTree = "<group>"; };
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
		F966BA8408F27A38005CB29B /* QWinEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = QWinEvent.3; sourceTree = "<group>"; };
		F966BA8508F27A38005CB29B /* radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = radiobutton.n; sourceTree = "<group>"; };
		F966BA8608F27A38005CB29B /* raise.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = raise.n; sourceTree = "<group>"; };
		F966BA8708F27A38005CB29B /* Restack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Restack.3; sourceTree = "<group>"; };
		F966BA8808F27A38005CB29B /* RestrictEv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RestrictEv.3; sourceTree = "<group>"; };
		F966BA8908F27A38005CB29B /* scale.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scale.n; sourceTree = "<group>"; };
		F966BA8A08F27A38005CB29B /* scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scrollbar.n; sourceTree = "<group>"; };
		F966BA8B08F27A38005CB29B /* selection.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = selection.n; sourceTree = "<group>"; };
		F966BA8C08F27A38005CB29B /* send.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = send.n; sourceTree = "<group>"; };
		F966BA8D08F27A38005CB29B /* SetAppName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetAppName.3; sourceTree = "<group>"; };
		F966BA8E08F27A38005CB29B /* SetCaret.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetCaret.3; sourceTree = "<group>"; };
		F966BA8F08F27A38005CB29B /* SetClass.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClass.3; sourceTree = "<group>"; };
		F966BA9008F27A38005CB29B /* SetClassProcs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClassProcs.3; sourceTree = "<group>"; };
		F966BA9108F27A38005CB29B /* SetGrid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetGrid.3; sourceTree = "<group>"; };
		F966BA9208F27A38005CB29B /* SetOptions.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetOptions.3; sourceTree = "<group>"; };
		F966BA9308F27A38005CB29B /* SetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVisual.3; sourceTree = "<group>"; };
		F966BA9408F27A38005CB29B /* spinbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = spinbox.n; sourceTree = "<group>"; };
		F966BA9508F27A38005CB29B /* StrictMotif.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrictMotif.3; sourceTree = "<group>"; };
		F966BA9608F27A38005CB29B /* text.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = text.n; sourceTree = "<group>"; };
		F966BA9708F27A38005CB29B /* TextLayout.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TextLayout.3; sourceTree = "<group>"; };
		F966BA9808F27A38005CB29B /* tk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tk.n; sourceTree = "<group>"; };
		F966BA9A08F27A38005CB29B /* Tk_Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Init.3; sourceTree = "<group>"; };
		F966BA9B08F27A38005CB29B /* Tk_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Main.3; sourceTree = "<group>"; };
		F966BA9C08F27A38005CB29B /* tkerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkerror.n; sourceTree = "<group>"; };
		F966BA9D08F27A38005CB29B /* TkInitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TkInitStubs.3; sourceTree = "<group>"; };
		F966BA9E08F27A38005CB29B /* tkvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkvars.n; sourceTree = "<group>"; };
		F966BA9F08F27A38005CB29B /* tkwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkwait.n; sourceTree = "<group>"; };
		F966BAA008F27A38005CB29B /* toplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = toplevel.n; sourceTree = "<group>"; };
		F966BAA108F27A38005CB29B /* WindowId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WindowId.3; sourceTree = "<group>"; };
		F966BAA208F27A38005CB29B /* winfo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = winfo.n; sourceTree = "<group>"; };
		F966BAA308F27A38005CB29B /* wish.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wish.1; sourceTree = "<group>"; };
		F966BAA408F27A38005CB29B /* wm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wm.n; sourceTree = "<group>"; };
		F966BAA608F27A38005CB29B /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = "<group>"; };
		F966BAA708F27A38005CB29B /* ks_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ks_names.h; sourceTree = "<group>"; };
		F966BAA908F27A39005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BAAA08F27A39005CB29B /* tk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.decls; sourceTree = "<group>"; };
		F966BAAB08F27A39005CB29B /* tk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk.h; sourceTree = "<group>"; };
		F966BAAC08F27A39005CB29B /* tk3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tk3d.c; sourceTree = "<group>"; };
		F966BAAD08F27A39005CB29B /* tk3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk3d.h; sourceTree = "<group>"; };
		F966BAAE08F27A39005CB29B /* tkArgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkArgv.c; sourceTree = "<group>"; };
		F966BAAF08F27A39005CB29B /* tkAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAtom.c; sourceTree = "<group>"; };
		F966BAB008F27A39005CB29B /* tkBind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBind.c; sourceTree = "<group>"; };
		F966BAB108F27A39005CB29B /* tkBitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBitmap.c; sourceTree = "<group>"; };
		F966BAB208F27A39005CB29B /* tkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkButton.c; sourceTree = "<group>"; };
		F966BAB308F27A39005CB29B /* tkButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkButton.h; sourceTree = "<group>"; };
		F966BAB408F27A39005CB29B /* tkCanvArc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvArc.c; sourceTree = "<group>"; };
		F966BAB508F27A39005CB29B /* tkCanvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvas.c; sourceTree = "<group>"; };
		F966BAB608F27A39005CB29B /* tkCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkCanvas.h; sourceTree = "<group>"; };
		F966BAB708F27A39005CB29B /* tkCanvBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvBmap.c; sourceTree = "<group>"; };
		F966BAB808F27A39005CB29B /* tkCanvImg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvImg.c; sourceTree = "<group>"; };
		F966BAB908F27A39005CB29B /* tkCanvLine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvLine.c; sourceTree = "<group>"; };
		F966BABA08F27A39005CB29B /* tkCanvPoly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPoly.c; sourceTree = "<group>"; };
		F966BABB08F27A39005CB29B /* tkCanvPs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPs.c; sourceTree = "<group>"; };
		F966BABD08F27A39005CB29B /* tkCanvText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvText.c; sourceTree = "<group>"; };
		F966BABE08F27A39005CB29B /* tkCanvUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvUtil.c; sourceTree = "<group>"; };
		F966BABF08F27A39005CB29B /* tkCanvWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvWind.c; sourceTree = "<group>"; };
		F966BAC008F27A39005CB29B /* tkClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkClipboard.c; sourceTree = "<group>"; };
		F966BAC108F27A39005CB29B /* tkCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCmds.c; sourceTree = "<group>"; };
		F966BAC208F27A39005CB29B /* tkColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkColor.c; sourceTree = "<group>"; };
		F966BAC308F27A39005CB29B /* tkColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkColor.h; sourceTree = "<group>"; };
		F966BAC408F27A39005CB29B /* tkConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConfig.c; sourceTree = "<group>"; };
		F966BAC508F27A39005CB29B /* tkConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConsole.c; sourceTree = "<group>"; };
		F966BAC608F27A39005CB29B /* tkCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCursor.c; sourceTree = "<group>"; };
		F966BAC708F27A39005CB29B /* tkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkDecls.h; sourceTree = "<group>"; };
		F966BAC808F27A39005CB29B /* tkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEntry.c; sourceTree = "<group>"; };
		F966BAC908F27A39005CB29B /* tkEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkEntry.h; sourceTree = "<group>"; };
		F966BACA08F27A39005CB29B /* tkError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkError.c; sourceTree = "<group>"; };
		F966BACB08F27A39005CB29B /* tkEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEvent.c; sourceTree = "<group>"; };
		F966BACC08F27A39005CB29B /* tkFileFilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFileFilter.c; sourceTree = "<group>"; };
		F966BACD08F27A39005CB29B /* tkFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFileFilter.h; sourceTree = "<group>"; };
		F966BACE08F27A39005CB29B /* tkFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFocus.c; sourceTree = "<group>"; };
		F966BACF08F27A39005CB29B /* tkFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFont.c; sourceTree = "<group>"; };
		F966BAD008F27A39005CB29B /* tkFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFont.h; sourceTree = "<group>"; };
		F966BAD108F27A39005CB29B /* tkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFrame.c; sourceTree = "<group>"; };
		F966BAD208F27A39005CB29B /* tkGC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGC.c; sourceTree = "<group>"; };
		F966BAD308F27A39005CB29B /* tkGeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGeometry.c; sourceTree = "<group>"; };
		F966BAD408F27A39005CB29B /* tkGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGet.c; sourceTree = "<group>"; };
		F966BAD508F27A39005CB29B /* tkGrab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrab.c; sourceTree = "<group>"; };
		F966BAD608F27A39005CB29B /* tkGrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrid.c; sourceTree = "<group>"; };
		F966BAD708F27A39005CB29B /* tkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImage.c; sourceTree = "<group>"; };
		F966BAD808F27A39005CB29B /* tkImgBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgBmap.c; sourceTree = "<group>"; };
		F966BAD908F27A39005CB29B /* tkImgGIF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgGIF.c; sourceTree = "<group>"; };
		F966BADA08F27A39005CB29B /* tkImgPhoto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhoto.c; sourceTree = "<group>"; };
		F966BADB08F27A39005CB29B /* tkImgPPM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPPM.c; sourceTree = "<group>"; };
		F966BADC08F27A39005CB29B /* tkImgUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgUtil.c; sourceTree = "<group>"; };
		F966BADE08F27A39005CB29B /* tkInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkInt.decls; sourceTree = "<group>"; };
		F966BADF08F27A39005CB29B /* tkInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkInt.h; sourceTree = "<group>"; };
		F966BAE108F27A39005CB29B /* tkIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntDecls.h; sourceTree = "<group>"; };
		F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntPlatDecls.h; sourceTree = "<group>"; };
		F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntXlibDecls.h; sourceTree = "<group>"; };
		F966BAE408F27A39005CB29B /* tkListbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkListbox.c; sourceTree = "<group>"; };
		F966BAE508F27A39005CB29B /* tkMacWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacWinMenu.c; sourceTree = "<group>"; };
		F966BAE608F27A39005CB29B /* tkMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMain.c; sourceTree = "<group>"; };
		F966BAE708F27A39005CB29B /* tkMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenu.c; sourceTree = "<group>"; };
		F966BAE808F27A39005CB29B /* tkMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenu.h; sourceTree = "<group>"; };
		F966BAE908F27A39005CB29B /* tkMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenubutton.c; sourceTree = "<group>"; };
		F966BAEA08F27A39005CB29B /* tkMenubutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenubutton.h; sourceTree = "<group>"; };
		F966BAEB08F27A39005CB29B /* tkMenuDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenuDraw.c; sourceTree = "<group>"; };
		F966BAEC08F27A39005CB29B /* tkMessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMessage.c; sourceTree = "<group>"; };
		F966BAED08F27A39005CB29B /* tkObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkObj.c; sourceTree = "<group>"; };
		F966BAEE08F27A39005CB29B /* tkOldConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldConfig.c; sourceTree = "<group>"; };
		F966BAEF08F27A39005CB29B /* tkOption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOption.c; sourceTree = "<group>"; };
		F966BAF008F27A39005CB29B /* tkPack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPack.c; sourceTree = "<group>"; };
		F966BAF108F27A39005CB29B /* tkPanedWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPanedWindow.c; sourceTree = "<group>"; };
		F966BAF208F27A39005CB29B /* tkPlace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPlace.c; sourceTree = "<group>"; };
		F966BAF308F27A39005CB29B /* tkPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPlatDecls.h; sourceTree = "<group>"; };
		F966BAF408F27A39005CB29B /* tkPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPointer.c; sourceTree = "<group>"; };
		F966BAF508F27A39005CB29B /* tkPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPort.h; sourceTree = "<group>"; };
		F966BAF608F27A39005CB29B /* tkRectOval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkRectOval.c; sourceTree = "<group>"; };
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
		F966BB0608F27A39005CB29B /* tkTextDisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextDisp.c; sourceTree = "<group>"; };
		F966BB0808F27A39005CB29B /* tkTextImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextImage.c; sourceTree = "<group>"; };
		F966BB0908F27A39005CB29B /* tkTextIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextIndex.c; sourceTree = "<group>"; };
		F966BB0A08F27A39005CB29B /* tkTextMark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextMark.c; sourceTree = "<group>"; };
		F966BB0B08F27A39005CB29B /* tkTextTag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextTag.c; sourceTree = "<group>"; };
		F966BB0C08F27A39005CB29B /* tkTextWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextWind.c; sourceTree = "<group>"; };
		F966BB0D08F27A39005CB29B /* tkTrig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTrig.c; sourceTree = "<group>"; };
		F966BB0E08F27A39005CB29B /* tkUndo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUndo.c; sourceTree = "<group>"; };
		F966BB0F08F27A39005CB29B /* tkUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUndo.h; sourceTree = "<group>"; };
		F966BB1008F27A39005CB29B /* tkUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUtil.c; sourceTree = "<group>"; };
		F966BB1108F27A39005CB29B /* tkVisual.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkVisual.c; sourceTree = "<group>"; };
		F966BB1208F27A39005CB29B /* tkWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWindow.c; sourceTree = "<group>"; };
		F966BB1408F27A39005CB29B /* bgerror.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.tcl; sourceTree = "<group>"; };
		F966BB1508F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB1608F27A39005CB29B /* choosedir.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.tcl; sourceTree = "<group>"; };
		F966BB1708F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB1808F27A39005CB29B /* comdlg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = comdlg.tcl; sourceTree = "<group>"; };
		F966BB1908F27A39005CB29B /* console.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = console.tcl; sourceTree = "<group>"; };
		F966BB1B08F27A39005CB29B /* anilabel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = anilabel.tcl; sourceTree = "<group>"; };
		F966BB1C08F27A39005CB29B /* aniwave.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aniwave.tcl; sourceTree = "<group>"; };
		F966BB1D08F27A39005CB29B /* arrow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arrow.tcl; sourceTree = "<group>"; };
		F966BB1E08F27A39005CB29B /* bind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.tcl; sourceTree = "<group>"; };
		F966BB1F08F27A39005CB29B /* bitmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.tcl; sourceTree = "<group>"; };
		F966BB2008F27A39005CB29B /* browse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = browse; sourceTree = "<group>"; };
		F966BB2108F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB2208F27A39005CB29B /* check.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = check.tcl; sourceTree = "<group>"; };
		F966BB2308F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB2408F27A39005CB29B /* colors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = colors.tcl; sourceTree = "<group>"; };
		F966BB2508F27A39005CB29B /* cscroll.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cscroll.tcl; sourceTree = "<group>"; };
		F966BB2608F27A39005CB29B /* ctext.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ctext.tcl; sourceTree = "<group>"; };
		F966BB2708F27A39005CB29B /* dialog1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog1.tcl; sourceTree = "<group>"; };
		F966BB2808F27A39005CB29B /* dialog2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog2.tcl; sourceTree = "<group>"; };
		F966BB2A08F27A39005CB29B /* entry1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry1.tcl; sourceTree = "<group>"; };
		F966BB2B08F27A39005CB29B /* entry2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry2.tcl; sourceTree = "<group>"; };
		F966BB2C08F27A39005CB29B /* entry3.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry3.tcl; sourceTree = "<group>"; };
		F966BB2D08F27A39005CB29B /* filebox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.tcl; sourceTree = "<group>"; };
		F966BB2E08F27A39005CB29B /* floor.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = floor.tcl; sourceTree = "<group>"; };
		F966BB2F08F27A39005CB29B /* form.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = form.tcl; sourceTree = "<group>"; };
		F966BB3008F27A39005CB29B /* goldberg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = goldberg.tcl; sourceTree = "<group>"; };
		F966BB3108F27A39005CB29B /* hello */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = hello; sourceTree = "<group>"; };
		F966BB3208F27A39005CB29B /* hscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = hscale.tcl; sourceTree = "<group>"; };
		F966BB3308F27A39005CB29B /* icon.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icon.tcl; sourceTree = "<group>"; };
		F966BB3408F27A39005CB29B /* image1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image1.tcl; sourceTree = "<group>"; };
		F966BB3508F27A39005CB29B /* image2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image2.tcl; sourceTree = "<group>"; };
		F966BB4208F27A3A005CB29B /* items.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = items.tcl; sourceTree = "<group>"; };
		F966BB4308F27A3A005CB29B /* ixset */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ixset; sourceTree = "<group>"; };
		F966BB4408F27A3A005CB29B /* label.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = label.tcl; sourceTree = "<group>"; };
		F966BB4508F27A3A005CB29B /* labelframe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.tcl; sourceTree = "<group>"; };
		F966BB4608F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB4708F27A3A005CB29B /* menubu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubu.tcl; sourceTree = "<group>"; };
		F966BB4808F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB4A08F27A3A005CB29B /* paned1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned1.tcl; sourceTree = "<group>"; };
		F966BB4B08F27A3A005CB29B /* paned2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned2.tcl; sourceTree = "<group>"; };
		F966BB4C08F27A3A005CB29B /* pendulum.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pendulum.tcl; sourceTree = "<group>"; };
		F966BB4D08F27A3A005CB29B /* plot.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = plot.tcl; sourceTree = "<group>"; };
		F966BB4E08F27A3A005CB29B /* puzzle.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = puzzle.tcl; sourceTree = "<group>"; };
		F966BB4F08F27A3A005CB29B /* radio.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radio.tcl; sourceTree = "<group>"; };
		F966BB5008F27A3A005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BB5108F27A3A005CB29B /* rmt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rmt; sourceTree = "<group>"; };
		F966BB5208F27A3A005CB29B /* rolodex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rolodex; sourceTree = "<group>"; };
		F966BB5308F27A3A005CB29B /* ruler.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ruler.tcl; sourceTree = "<group>"; };
		F966BB5408F27A3A005CB29B /* sayings.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sayings.tcl; sourceTree = "<group>"; };
		F966BB5508F27A3A005CB29B /* search.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = search.tcl; sourceTree = "<group>"; };
		F966BB5608F27A3A005CB29B /* spin.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spin.tcl; sourceTree = "<group>"; };
		F966BB5708F27A3A005CB29B /* square */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = square; sourceTree = "<group>"; };
		F966BB5808F27A3A005CB29B /* states.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = states.tcl; sourceTree = "<group>"; };
		F966BB5908F27A3A005CB29B /* style.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = style.tcl; sourceTree = "<group>"; };
		F966BB5A08F27A3A005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB5B08F27A3A005CB29B /* tcolor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tcolor; sourceTree = "<group>"; };
		F966BB5C08F27A3A005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB5D08F27A3A005CB29B /* timer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = timer; sourceTree = "<group>"; };
		F966BB5E08F27A3A005CB29B /* twind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = twind.tcl; sourceTree = "<group>"; };
		F966BB5F08F27A3A005CB29B /* unicodeout.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unicodeout.tcl; sourceTree = "<group>"; };
		F966BB6008F27A3A005CB29B /* vscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vscale.tcl; sourceTree = "<group>"; };
		F966BB6108F27A3A005CB29B /* widget */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = widget; sourceTree = "<group>"; };
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
		F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXBitmap.c; sourceTree = "<group>"; };
		F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXButton.c; sourceTree = "<group>"; };
		F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXClipboard.c; sourceTree = "<group>"; };
		F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXColor.c; sourceTree = "<group>"; };
		F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXConfig.c; sourceTree = "<group>"; };
		F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXCursor.c; sourceTree = "<group>"; };
		F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXCursors.h; sourceTree = "<group>"; };
		F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDebug.c; sourceTree = "<group>"; };
		F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDebug.h; sourceTree = "<group>"; };
		F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDefault.h; sourceTree = "<group>"; };
		F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDialog.c; sourceTree = "<group>"; };
		F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDraw.c; sourceTree = "<group>"; };
		F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEmbed.c; sourceTree = "<group>"; };
		F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEntry.c; sourceTree = "<group>"; };
		F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEvent.c; sourceTree = "<group>"; };
		F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXFont.c; sourceTree = "<group>"; };
		F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXHLEvents.c; sourceTree = "<group>"; };
		F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXInit.c; sourceTree = "<group>"; };
		F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXInt.h; sourceTree = "<group>"; };
		F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; };
		F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; };
		F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenu.c; sourceTree = "<group>"; };
		F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; };
		F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenus.c; sourceTree = "<group>"; };
		F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; };
		F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXNotify.c; sourceTree = "<group>"; };
		F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPort.h; sourceTree = "<group>"; };
		F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXRegion.c; sourceTree = "<group>"; };
		F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScale.c; sourceTree = "<group>"; };
		F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScrlbr.c; sourceTree = "<group>"; };
		F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSend.c; sourceTree = "<group>"; };
		F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSubwindows.c; sourceTree = "<group>"; };
		F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXTest.c; sourceTree = "<group>"; };
		F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWindowEvent.c; sourceTree = "<group>"; };
		F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWm.c; sourceTree = "<group>"; };
		F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXWm.h; sourceTree = "<group>"; };
		F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXXCursors.h; sourceTree = "<group>"; };
		F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXXStubs.c; sourceTree = "<group>"; };
		F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Wish-Info.plist.in"; sourceTree = "<group>"; };
		F966BC0308F27A3C005CB29B /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F966BC0508F27A3C005CB29B /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F966BC0608F27A3C005CB29B /* arc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arc.tcl; sourceTree = "<group>"; };
		F966BC0708F27A3C005CB29B /* bell.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bell.test; sourceTree = "<group>"; };
		F966BC0808F27A3C005CB29B /* bevel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bevel.tcl; sourceTree = "<group>"; };
		F966BC0908F27A3C005CB29B /* bgerror.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.test; sourceTree = "<group>"; };
		F966BC0A08F27A3C005CB29B /* bind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.test; sourceTree = "<group>"; };
		F966BC0B08F27A3C005CB29B /* bitmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.test; sourceTree = "<group>"; };
		F966BC0C08F27A3C005CB29B /* border.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = border.test; sourceTree = "<group>"; };
		F966BC0D08F27A3C005CB29B /* bugs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bugs.tcl; sourceTree = "<group>"; };
		F966BC0E08F27A3C005CB29B /* butGeom.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom.tcl; sourceTree = "<group>"; };
		F966BC0F08F27A3C005CB29B /* butGeom2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom2.tcl; sourceTree = "<group>"; };
		F966BC1008F27A3C005CB29B /* button.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.test; sourceTree = "<group>"; };
		F966BC1108F27A3C005CB29B /* canvas.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvas.test; sourceTree = "<group>"; };
		F966BC1208F27A3C005CB29B /* canvImg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvImg.test; sourceTree = "<group>"; };
		F966BC1308F27A3C005CB29B /* canvPs.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPs.test; sourceTree = "<group>"; };
		F966BC1408F27A3C005CB29B /* canvPsArc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsArc.tcl; sourceTree = "<group>"; };
		F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsBmap.tcl; sourceTree = "<group>"; };
		F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsGrph.tcl; sourceTree = "<group>"; };
		F966BC1708F27A3C005CB29B /* canvPsImg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsImg.tcl; sourceTree = "<group>"; };
		F966BC1808F27A3C005CB29B /* canvPsText.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsText.tcl; sourceTree = "<group>"; };
		F966BC1908F27A3C005CB29B /* canvRect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvRect.test; sourceTree = "<group>"; };
		F966BC1A08F27A3C005CB29B /* canvText.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvText.test; sourceTree = "<group>"; };
		F966BC1B08F27A3C005CB29B /* canvWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvWind.test; sourceTree = "<group>"; };
		F966BC1C08F27A3C005CB29B /* choosedir.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.test; sourceTree = "<group>"; };
		F966BC1D08F27A3C005CB29B /* clipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clipboard.test; sourceTree = "<group>"; };
		F966BC1E08F27A3C005CB29B /* clrpick.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.test; sourceTree = "<group>"; };
		F966BC1F08F27A3C005CB29B /* cmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmap.tcl; sourceTree = "<group>"; };
		F966BC2008F27A3C005CB29B /* cmds.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmds.test; sourceTree = "<group>"; };
		F966BC2108F27A3C005CB29B /* color.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = color.test; sourceTree = "<group>"; };
		F966BC2208F27A3C005CB29B /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F966BC2308F27A3C005CB29B /* constraints.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = constraints.tcl; sourceTree = "<group>"; };
		F966BC2408F27A3C005CB29B /* cursor.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursor.test; sourceTree = "<group>"; };
		F966BC2508F27A3C005CB29B /* dialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.test; sourceTree = "<group>"; };
		F966BC2608F27A3C005CB29B /* embed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = embed.test; sourceTree = "<group>"; };
		F966BC2708F27A3C005CB29B /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F966BC2808F27A3C005CB29B /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F966BC2908F27A3C005CB29B /* filebox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.test; sourceTree = "<group>"; };
		F966BC2A08F27A3C005CB29B /* focus.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.test; sourceTree = "<group>"; };
		F966BC2B08F27A3C005CB29B /* focusTcl.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focusTcl.test; sourceTree = "<group>"; };
		F966BC2C08F27A3C005CB29B /* font.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = font.test; sourceTree = "<group>"; };
		F966BC2D08F27A3C005CB29B /* frame.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = frame.test; sourceTree = "<group>"; };
		F966BC2E08F27A3C005CB29B /* geometry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = geometry.test; sourceTree = "<group>"; };
		F966BC2F08F27A3C005CB29B /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F966BC3008F27A3C005CB29B /* grab.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grab.test; sourceTree = "<group>"; };
		F966BC3108F27A3C005CB29B /* grid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grid.test; sourceTree = "<group>"; };
		F966BC3308F27A3C005CB29B /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F966BC3408F27A3C005CB29B /* imgBmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgBmap.test; sourceTree = "<group>"; };
		F966BC3508F27A3C005CB29B /* imgPhoto.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPhoto.test; sourceTree = "<group>"; };
		F966BC3608F27A3C005CB29B /* imgPPM.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPPM.test; sourceTree = "<group>"; };
		F966BC3708F27A3C005CB29B /* listbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.test; sourceTree = "<group>"; };
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
		F966BC4708F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC4808F27A3D005CB29B /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F966BC4908F27A3D005CB29B /* scale.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.test; sourceTree = "<group>"; };
		F966BC4A08F27A3D005CB29B /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F966BC4B08F27A3D005CB29B /* select.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = select.test; sourceTree = "<group>"; };
		F966BC4C08F27A3D005CB29B /* send.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = send.test; sourceTree = "<group>"; };
		F966BC4D08F27A3D005CB29B /* spinbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.test; sourceTree = "<group>"; };
		F966BC4E08F27A3D005CB29B /* text.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.test; sourceTree = "<group>"; };
		F966BC4F08F27A3D005CB29B /* textBTree.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textBTree.test; sourceTree = "<group>"; };
		F966BC5008F27A3D005CB29B /* textDisp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textDisp.test; sourceTree = "<group>"; };
		F966BC5108F27A3D005CB29B /* textImage.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textImage.test; sourceTree = "<group>"; };
		F966BC5208F27A3D005CB29B /* textIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textIndex.test; sourceTree = "<group>"; };
		F966BC5308F27A3D005CB29B /* textMark.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textMark.test; sourceTree = "<group>"; };
		F966BC5408F27A3D005CB29B /* textTag.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textTag.test; sourceTree = "<group>"; };
		F966BC5508F27A3D005CB29B /* textWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textWind.test; sourceTree = "<group>"; };
		F966BC5608F27A3D005CB29B /* tk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.test; sourceTree = "<group>"; };
		F966BC5708F27A3D005CB29B /* unixButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixButton.test; sourceTree = "<group>"; };
		F966BC5808F27A3D005CB29B /* unixEmbed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixEmbed.test; sourceTree = "<group>"; };
		F966BC5908F27A3D005CB29B /* unixFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFont.test; sourceTree = "<group>"; };
		F966BC5A08F27A3D005CB29B /* unixMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixMenu.test; sourceTree = "<group>"; };
		F966BC5B08F27A3D005CB29B /* unixSelect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixSelect.test; sourceTree = "<group>"; };
		F966BC5C08F27A3D005CB29B /* unixWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixWm.test; sourceTree = "<group>"; };
		F966BC5D08F27A3D005CB29B /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F966BC5E08F27A3D005CB29B /* visual.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual.test; sourceTree = "<group>"; };
		F966BC5F08F27A3D005CB29B /* visual_bb.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual_bb.test; sourceTree = "<group>"; };
		F966BC6008F27A3D005CB29B /* winButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winButton.test; sourceTree = "<group>"; };
		F966BC6108F27A3D005CB29B /* winClipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winClipboard.test; sourceTree = "<group>"; };
		F966BC6208F27A3D005CB29B /* winDialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDialog.test; sourceTree = "<group>"; };
		F966BC6308F27A3D005CB29B /* window.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = window.test; sourceTree = "<group>"; };
		F966BC6408F27A3D005CB29B /* winfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winfo.test; sourceTree = "<group>"; };
		F966BC6508F27A3D005CB29B /* winFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFont.test; sourceTree = "<group>"; };
		F966BC6608F27A3D005CB29B /* winMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winMenu.test; sourceTree = "<group>"; };
		F966BC6708F27A3D005CB29B /* winSend.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winSend.test; sourceTree = "<group>"; };
		F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = "<group>"; };
		F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = "<group>"; };
		F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
		F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BC7408F27A3D005CB29B /* tk.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.spec; sourceTree = "<group>"; };
		F966BC7508F27A3D005CB29B /* tkAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAppInit.c; sourceTree = "<group>"; };
		F966BC7608F27A3D005CB29B /* tkConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tkConfig.h.in; sourceTree = "<group>"; };
		F966BC7708F27A3D005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
		F966BC8708F27A3D005CB29B /* tkUnixKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixKey.c; sourceTree = "<group>"; };
		F966BC8808F27A3D005CB29B /* tkUnixMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenu.c; sourceTree = "<group>"; };
		F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenubu.c; sourceTree = "<group>"; };
		F966BC8A08F27A3D005CB29B /* tkUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixPort.h; sourceTree = "<group>"; };
		F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixRFont.c; sourceTree = "<group>"; };
		F966BC8C08F27A3D005CB29B /* tkUnixScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScale.c; sourceTree = "<group>"; };
		F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScrlbr.c; sourceTree = "<group>"; };
		F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSelect.c; sourceTree = "<group>"; };
		F966BC8F08F27A3D005CB29B /* tkUnixSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSend.c; sourceTree = "<group>"; };
		F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = "<group>"; };
		F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = "<group>"; };
		F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = "<group>"; };
		F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = "<group>"; };
		F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = "<group>"; };
		F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = "<group>"; };
		F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = "<group>"; };
		F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin32Dll.c; sourceTree = "<group>"; };
		F966BCFB08F27A3F005CB29B /* tkWin3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin3d.c; sourceTree = "<group>"; };
		F966BCFC08F27A3F005CB29B /* tkWinButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinButton.c; sourceTree = "<group>"; };
		F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinClipboard.c; sourceTree = "<group>"; };
		F966BCFE08F27A3F005CB29B /* tkWinColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinColor.c; sourceTree = "<group>"; };
		F966BCFF08F27A3F005CB29B /* tkWinConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinConfig.c; sourceTree = "<group>"; };
		F966BD0008F27A3F005CB29B /* tkWinCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinCursor.c; sourceTree = "<group>"; };
		F966BD0108F27A3F005CB29B /* tkWinDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinDefault.h; sourceTree = "<group>"; };
		F966BD0208F27A3F005CB29B /* tkWinDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDialog.c; sourceTree = "<group>"; };
		F966BD0308F27A3F005CB29B /* tkWinDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDraw.c; sourceTree = "<group>"; };
		F966BD0408F27A3F005CB29B /* tkWinEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinEmbed.c; sourceTree = "<group>"; };
		F966BD0508F27A3F005CB29B /* tkWinFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinFont.c; sourceTree = "<group>"; };
		F966BD0708F27A3F005CB29B /* tkWinImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinImage.c; sourceTree = "<group>"; };
		F966BD0808F27A3F005CB29B /* tkWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinInit.c; sourceTree = "<group>"; };
		F966BD0908F27A3F005CB29B /* tkWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinInt.h; sourceTree = "<group>"; };
		F966BD0A08F27A3F005CB29B /* tkWinKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinKey.c; sourceTree = "<group>"; };
		F966BD0B08F27A3F005CB29B /* tkWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinMenu.c; sourceTree = "<group>"; };
		F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPixmap.c; sourceTree = "<group>"; };
		F966BD0D08F27A3F005CB29B /* tkWinPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPointer.c; sourceTree = "<group>"; };
		F966BD0E08F27A3F005CB29B /* tkWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinPort.h; sourceTree = "<group>"; };
		F966BD0F08F27A3F005CB29B /* tkWinRegion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinRegion.c; sourceTree = "<group>"; };
		F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinScrlbr.c; sourceTree = "<group>"; };
		F966BD1108F27A3F005CB29B /* tkWinSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSend.c; sourceTree = "<group>"; };
		F966BD1208F27A3F005CB29B /* tkWinSendCom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSendCom.c; sourceTree = "<group>"; };
		F966BD1308F27A3F005CB29B /* tkWinSendCom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinSendCom.h; sourceTree = "<group>"; };
		F966BD1408F27A3F005CB29B /* tkWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinTest.c; sourceTree = "<group>"; };
		F966BD1508F27A3F005CB29B /* tkWinWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWindow.c; sourceTree = "<group>"; };
		F966BD1608F27A3F005CB29B /* tkWinWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWm.c; sourceTree = "<group>"; };
		F966BD1708F27A3F005CB29B /* tkWinX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinX.c; sourceTree = "<group>"; };
		F966BD1808F27A3F005CB29B /* winMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winMain.c; sourceTree = "<group>"; };
		F966BD1B08F27A3F005CB29B /* cursorfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorfont.h; sourceTree = "<group>"; };
		F966BD1C08F27A3F005CB29B /* keysym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysym.h; sourceTree = "<group>"; };
		F966BD1D08F27A3F005CB29B /* keysymdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysymdef.h; sourceTree = "<group>"; };
		F966BD1E08F27A3F005CB29B /* X.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X.h; sourceTree = "<group>"; };
		F966BD1F08F27A3F005CB29B /* Xatom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xatom.h; sourceTree = "<group>"; };
		F966BD2008F27A3F005CB29B /* Xfuncproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xfuncproto.h; sourceTree = "<group>"; };
		F966BD2108F27A3F005CB29B /* Xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xlib.h; sourceTree = "<group>"; };
		F966BD2208F27A3F005CB29B /* Xutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xutil.h; sourceTree = "<group>"; };
		F966BD2308F27A3F005CB29B /* xbytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbytes.h; sourceTree = "<group>"; };
		F966BD2408F27A3F005CB29B /* xcolors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xcolors.c; sourceTree = "<group>"; };
		F966BD2508F27A3F005CB29B /* xdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdraw.c; sourceTree = "<group>"; };
		F966BD2608F27A3F005CB29B /* xgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xgc.c; sourceTree = "<group>"; };
		F966BD2708F27A3F005CB29B /* ximage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ximage.c; sourceTree = "<group>"; };
		F966BD2808F27A3F005CB29B /* xutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xutil.c; sourceTree = "<group>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F966C07608F2821B005CB29B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
		F966C07808F28233005CB29B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
		F96887E00AF786D5000797B5 /* ttk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.decls; sourceTree = "<group>"; };
		F96887E10AF786D5000797B5 /* ttkBlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkBlink.c; sourceTree = "<group>"; };
		F96887E20AF786D5000797B5 /* ttkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkButton.c; sourceTree = "<group>"; };
		F96887E30AF786D5000797B5 /* ttkCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkCache.c; sourceTree = "<group>"; };
		F96887E40AF786D5000797B5 /* ttkClamTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClamTheme.c; sourceTree = "<group>"; };
		F96887E50AF786D5000797B5 /* ttkClassicTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClassicTheme.c; sourceTree = "<group>"; };
		F96887E60AF786D5000797B5 /* ttkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkDecls.h; sourceTree = "<group>"; };
		F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkDefaultTheme.c; sourceTree = "<group>"; };
		F96887E80AF786D5000797B5 /* ttkElements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkElements.c; sourceTree = "<group>"; };
		F96887E90AF786D5000797B5 /* ttkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkEntry.c; sourceTree = "<group>"; };
		F96887EA0AF786D5000797B5 /* ttkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkFrame.c; sourceTree = "<group>"; };
		F96887EB0AF786D5000797B5 /* ttkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkImage.c; sourceTree = "<group>"; };
		F96887EC0AF786D5000797B5 /* ttkInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkInit.c; sourceTree = "<group>"; };
		F96887ED0AF786D5000797B5 /* ttkLabel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLabel.c; sourceTree = "<group>"; };
		F96887EE0AF786D5000797B5 /* ttkLayout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLayout.c; sourceTree = "<group>"; };
		F96887EF0AF786D5000797B5 /* ttkManager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkManager.c; sourceTree = "<group>"; };
		F96887F00AF786D5000797B5 /* ttkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkManager.h; sourceTree = "<group>"; };
		F96887F10AF786D5000797B5 /* ttkNotebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkNotebook.c; sourceTree = "<group>"; };
		F96887F20AF786D5000797B5 /* ttkPanedwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkPanedwindow.c; sourceTree = "<group>"; };
		F96887F30AF786D5000797B5 /* ttkProgress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkProgress.c; sourceTree = "<group>"; };
		F96887F40AF786D5000797B5 /* ttkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScale.c; sourceTree = "<group>"; };
		F96887F50AF786D5000797B5 /* ttkScroll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScroll.c; sourceTree = "<group>"; };
		F96887F60AF786D5000797B5 /* ttkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScrollbar.c; sourceTree = "<group>"; };
		F96887F70AF786D5000797B5 /* ttkSeparator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSeparator.c; sourceTree = "<group>"; };
		F96887F80AF786D5000797B5 /* ttkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSquare.c; sourceTree = "<group>"; };
		F96887F90AF786D5000797B5 /* ttkState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkState.c; sourceTree = "<group>"; };
		F96887FA0AF786D5000797B5 /* ttkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubInit.c; sourceTree = "<group>"; };
		F96887FB0AF786D5000797B5 /* ttkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubLib.c; sourceTree = "<group>"; };
		F96887FC0AF786D5000797B5 /* ttkTagSet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTagSet.c; sourceTree = "<group>"; };
		F96887FD0AF786D5000797B5 /* ttkTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTheme.c; sourceTree = "<group>"; };
		F96887FE0AF786D5000797B5 /* ttkTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkTheme.h; sourceTree = "<group>"; };
		F96887FF0AF786D5000797B5 /* ttkThemeInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkThemeInt.h; sourceTree = "<group>"; };
		F96888000AF786D5000797B5 /* ttkTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrace.c; sourceTree = "<group>"; };
		F96888010AF786D5000797B5 /* ttkTrack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrack.c; sourceTree = "<group>"; };
		F96888020AF786D5000797B5 /* ttkTreeview.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTreeview.c; sourceTree = "<group>"; };
		F96888030AF786D5000797B5 /* ttkWidget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWidget.c; sourceTree = "<group>"; };
		F96888040AF786D5000797B5 /* ttkWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkWidget.h; sourceTree = "<group>"; };
		F96888370AF787B3000797B5 /* altTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = altTheme.tcl; sourceTree = "<group>"; };
		F96888380AF787B3000797B5 /* aquaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aquaTheme.tcl; sourceTree = "<group>"; };
		F96888390AF787B3000797B5 /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F968883A0AF787B3000797B5 /* clamTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clamTheme.tcl; sourceTree = "<group>"; };
		F968883B0AF787B3000797B5 /* classicTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = classicTheme.tcl; sourceTree = "<group>"; };
		F968883C0AF787B3000797B5 /* combobox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.tcl; sourceTree = "<group>"; };
		F968883D0AF787B3000797B5 /* cursors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursors.tcl; sourceTree = "<group>"; };
		F968883E0AF787B3000797B5 /* defaults.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = defaults.tcl; sourceTree = "<group>"; };
		F96888400AF787B3000797B5 /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F96888410AF787B3000797B5 /* fonts.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fonts.tcl; sourceTree = "<group>"; };
		F96888440AF787B3000797B5 /* menubutton.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubutton.tcl; sourceTree = "<group>"; };
		F96888450AF787B3000797B5 /* notebook.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.tcl; sourceTree = "<group>"; };
		F96888460AF787B3000797B5 /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F96888470AF787B3000797B5 /* progress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progress.tcl; sourceTree = "<group>"; };
		F96888480AF787B3000797B5 /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F96888490AF787B3000797B5 /* scrollbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.tcl; sourceTree = "<group>"; };
		F968884A0AF787B3000797B5 /* sizegrip.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sizegrip.tcl; sourceTree = "<group>"; };
		F968884B0AF787B3000797B5 /* treeview.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.tcl; sourceTree = "<group>"; };
		F968884C0AF787B3000797B5 /* ttk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.tcl; sourceTree = "<group>"; };
		F968884D0AF787B3000797B5 /* utils.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utils.tcl; sourceTree = "<group>"; };
		F968884E0AF787B3000797B5 /* winTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTheme.tcl; sourceTree = "<group>"; };
		F968884F0AF787B3000797B5 /* xpTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xpTheme.tcl; sourceTree = "<group>"; };
		F96888540AF7880C000797B5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96888560AF7880C000797B5 /* combobox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.test; sourceTree = "<group>"; };
		F96888570AF7880C000797B5 /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F96888580AF7880C000797B5 /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F96888590AF7880C000797B5 /* labelframe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.test; sourceTree = "<group>"; };
		F968885A0AF7880C000797B5 /* layout.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = layout.test; sourceTree = "<group>"; };
		F968885C0AF7880C000797B5 /* notebook.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.test; sourceTree = "<group>"; };
		F968885D0AF7880C000797B5 /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F968885E0AF7880C000797B5 /* progressbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progressbar.test; sourceTree = "<group>"; };
		F968885F0AF7880C000797B5 /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F96888600AF7880C000797B5 /* treetags.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treetags.test; sourceTree = "<group>"; };
		F96888610AF7880C000797B5 /* treeview.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.test; sourceTree = "<group>"; };
		F96888620AF7880C000797B5 /* ttk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.test; sourceTree = "<group>"; };
		F96888630AF7880C000797B5 /* validate.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = validate.test; sourceTree = "<group>"; };
		F968886B0AF788F6000797B5 /* ttk_button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_button.n; sourceTree = "<group>"; };
		F968886C0AF788F6000797B5 /* ttk_checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_checkbutton.n; sourceTree = "<group>"; };
		F968886D0AF788F6000797B5 /* ttk_combobox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_combobox.n; sourceTree = "<group>"; };
		F968886F0AF788F6000797B5 /* ttk_entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_entry.n; sourceTree = "<group>"; };
		F96888700AF788F6000797B5 /* ttk_frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_frame.n; sourceTree = "<group>"; };
		F96888710AF788F6000797B5 /* ttk_Geometry.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Geometry.3; sourceTree = "<group>"; };
		F96888720AF788F6000797B5 /* ttk_image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_image.n; sourceTree = "<group>"; };
		F96888730AF788F6000797B5 /* ttk_intro.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_intro.n; sourceTree = "<group>"; };
		F96888740AF788F6000797B5 /* ttk_label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_label.n; sourceTree = "<group>"; };
		F96888750AF788F6000797B5 /* ttk_labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_labelframe.n; sourceTree = "<group>"; };
		F96888760AF788F6000797B5 /* ttk_menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_menubutton.n; sourceTree = "<group>"; };
		F96888770AF788F6000797B5 /* ttk_notebook.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_notebook.n; sourceTree = "<group>"; };
		F96888780AF788F6000797B5 /* ttk_panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_panedwindow.n; sourceTree = "<group>"; };
		F96888790AF788F6000797B5 /* ttk_progressbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_progressbar.n; sourceTree = "<group>"; };
		F968887A0AF788F6000797B5 /* ttk_radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_radiobutton.n; sourceTree = "<group>"; };
		F968887B0AF788F6000797B5 /* ttk_scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_scrollbar.n; sourceTree = "<group>"; };
		F968887C0AF788F6000797B5 /* ttk_separator.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_separator.n; sourceTree = "<group>"; };
		F968887D0AF788F6000797B5 /* ttk_sizegrip.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_sizegrip.n; sourceTree = "<group>"; };
		F968887E0AF788F6000797B5 /* ttk_style.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_style.n; sourceTree = "<group>"; };
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = "<group>"; };
		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F973E5960EE99384001A648E /* vistaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vistaTheme.tcl; sourceTree = "<group>"; };
		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
		F974D57B0FBE7EC000BF728B /* tk.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.pc.in; sourceTree = "<group>"; };
		F974D57C0FBE7EFF00BF728B /* iconlist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iconlist.tcl; sourceTree = "<group>"; };
		F974D57D0FBE7EFF00BF728B /* icons.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icons.tcl; sourceTree = "<group>"; };
		F97590AE1039A96200558A9A /* Wish.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.sdef; path = Wish.sdef; sourceTree = "<group>"; };
		F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPrivate.h; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Debug.xcconfig"; sourceTree = "<group>"; };
		F98383650F0FA43900171CA6 /* checkbutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkbutton.test; sourceTree = "<group>"; };
		F98383680F0FA44700171CA6 /* radiobutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radiobutton.test; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F99388380EE0114B0065FE6B /* fontchooser.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.tcl; sourceTree = "<group>"; };
		F99388950EE02D980065FE6B /* fontchooser.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.test; sourceTree = "<group>"; };
		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
		F9A3082D08F2D4AB00BAE1AB /* Tk.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084B08F2D4CE00BAE1AB /* Wish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wish.app; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9C888C20EEF6571003F63AD /* fontchooser.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fontchooser.n; sourceTree = "<group>"; };
		F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
		F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mclist.tcl; sourceTree = "<group>"; };
		F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPNG.c; sourceTree = "<group>"; };
		F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPNG.test; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkpane.tcl; sourceTree = "<group>"; };
		F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkmenu.tcl; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
		F9FD31F40CC1AD070073837D /* tktest-X11 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "tktest-X11"; sourceTree = BUILT_PRODUCTS_DIR; };
		F9FD32140CC1AF170073837D /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = /usr/X11R6/lib/libX11.dylib; sourceTree = "<absolute>"; };
		F9FD32150CC1AF170073837D /* libXext.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXext.dylib; path = /usr/X11R6/lib/libXext.dylib; sourceTree = "<absolute>"; };
		F9FD32160CC1AF170073837D /* libXss.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXss.dylib; path = /usr/X11R6/lib/libXss.dylib; sourceTree = "<absolute>"; };
		F9FD34990CC1BB0D0073837D /* libfreetype.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreetype.dylib; path = /usr/X11R6/lib/libfreetype.dylib; sourceTree = "<absolute>"; };
		F9FD349A0CC1BB0D0073837D /* libXft.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXft.dylib; path = /usr/X11R6/lib/libXft.dylib; sourceTree = "<absolute>"; };
		F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfontconfig.dylib; path = /usr/X11R6/lib/libfontconfig.dylib; sourceTree = "<absolute>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
				F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */,
				F966C07908F28233005CB29B /* IOKit.framework in Frameworks */,
				F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */,
				F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD31E30CC1AD070073837D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */,
				F96437E80EF0D652003F468E /* libz.dylib in Frameworks */,
				F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */,
				F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */,
				F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */,
				F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */,
				F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */,
				F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Tk */ = {
			isa = PBXGroup;
			children = (
				F96D3DF708F271BE004A47F5 /* Tk Sources */,
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n";
			name = Tk;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* Wish.app */,
				F9A3082D08F2D4AB00BAE1AB /* Tk.framework */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
				8DD76FB20486AB0100D96B5E /* tktest */,
				F9FD31F40CC1AD070073837D /* tktest-X11 */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F9183E690EFC81560030B814 /* pkgs */ = {
			isa = PBXGroup;
			children = (
				F9183E6A0EFC81560030B814 /* README */,
				F946FB8B0FBE3AED00CD6495 /* itcl */,
				F9183E8F0EFC817B0030B814 /* tdbc */,
			);
			path = pkgs;
			sourceTree = "<group>";
		};
		F966BA0308F27A37005CB29B /* bitmaps */ = {
			isa = PBXGroup;
			children = (
				F966BA0408F27A37005CB29B /* error.xbm */,
				F966BA0508F27A37005CB29B /* gray12.xbm */,
				F966BA0608F27A37005CB29B /* gray25.xbm */,
				F966BA0708F27A37005CB29B /* gray50.xbm */,
				F966BA0808F27A37005CB29B /* gray75.xbm */,
				F966BA0908F27A37005CB29B /* hourglass.xbm */,
				F966BA0A08F27A37005CB29B /* info.xbm */,
				F966BA0B08F27A37005CB29B /* questhead.xbm */,
				F966BA0C08F27A37005CB29B /* question.xbm */,
				F966BA0D08F27A37005CB29B /* warning.xbm */,
			);
			path = bitmaps;
			sourceTree = "<group>";
		};
		F966BA1008F27A37005CB29B /* doc */ = {
			isa = PBXGroup;
			children = (
				F966BA1108F27A37005CB29B /* 3DBorder.3 */,
				F966BA1208F27A37005CB29B /* AddOption.3 */,
				F966BA1308F27A37005CB29B /* bell.n */,
				F966BA1408F27A37005CB29B /* bind.n */,
				F966BA1508F27A37005CB29B /* BindTable.3 */,
				F966BA1608F27A37005CB29B /* bindtags.n */,
				F966BA1708F27A37005CB29B /* bitmap.n */,
				F966BA1808F27A37005CB29B /* button.n */,
				F966BA1908F27A37005CB29B /* canvas.n */,
				F966BA1A08F27A37005CB29B /* CanvPsY.3 */,
				F966BA1B08F27A37005CB29B /* CanvTkwin.3 */,
				F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */,
				F966BA1D08F27A37005CB29B /* checkbutton.n */,
				F966BA1E08F27A37005CB29B /* chooseColor.n */,
				F966BA1F08F27A37005CB29B /* chooseDirectory.n */,
				F966BA2008F27A37005CB29B /* Clipboard.3 */,
				F966BA2108F27A37005CB29B /* clipboard.n */,
				F966BA2208F27A37005CB29B /* ClrSelect.3 */,
				F966BA2308F27A37005CB29B /* colors.n */,
				F966BA2408F27A37005CB29B /* ConfigWidg.3 */,
				F966BA2508F27A37005CB29B /* ConfigWind.3 */,
				F966BA2608F27A37005CB29B /* console.n */,
				F966BA2708F27A37005CB29B /* CoordToWin.3 */,
				F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */,
				F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */,
				F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */,
				F966BA2B08F27A37005CB29B /* CrtImgType.3 */,
				F966BA2C08F27A37005CB29B /* CrtItemType.3 */,
				F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */,
				F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */,
				F966BA2F08F27A37005CB29B /* CrtWindow.3 */,
				F966BA3008F27A37005CB29B /* cursors.n */,
				F966BA3108F27A37005CB29B /* DeleteImg.3 */,
				F966BA3208F27A37005CB29B /* destroy.n */,
				F966BA3308F27A37005CB29B /* dialog.n */,
				F966BA3408F27A37005CB29B /* DrawFocHlt.3 */,
				F966BA3508F27A37005CB29B /* entry.n */,
				F966BA3608F27A37005CB29B /* event.n */,
				F966BA3708F27A37005CB29B /* EventHndlr.3 */,
				F966BA3808F27A37005CB29B /* FindPhoto.3 */,
				F966BA3908F27A37005CB29B /* focus.n */,
				F966BA3A08F27A37005CB29B /* focusNext.n */,
				F966BA3B08F27A37005CB29B /* font.n */,
				F9C888C20EEF6571003F63AD /* fontchooser.n */,
				F966BA3C08F27A37005CB29B /* FontId.3 */,
				F966BA3D08F27A37005CB29B /* frame.n */,
				F966BA3E08F27A37005CB29B /* FreeXId.3 */,
				F966BA3F08F27A37005CB29B /* GeomReq.3 */,
				F966BA4008F27A37005CB29B /* GetAnchor.3 */,
				F966BA4108F27A37005CB29B /* GetBitmap.3 */,
				F966BA4208F27A37005CB29B /* GetCapStyl.3 */,
				F966BA4308F27A37005CB29B /* GetClrmap.3 */,
				F966BA4408F27A37005CB29B /* GetColor.3 */,
				F966BA4508F27A37005CB29B /* GetCursor.3 */,
				F966BA4608F27A37005CB29B /* GetDash.3 */,
				F966BA4708F27A37005CB29B /* GetFont.3 */,
				F966BA4808F27A37005CB29B /* GetGC.3 */,
				F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */,
				F966BA4A08F27A37005CB29B /* GetHWND.3 */,
				F966BA4B08F27A37005CB29B /* GetImage.3 */,
				F966BA4C08F27A37005CB29B /* GetJoinStl.3 */,
				F966BA4D08F27A37005CB29B /* GetJustify.3 */,
				F966BA4E08F27A37005CB29B /* getOpenFile.n */,
				F966BA4F08F27A37005CB29B /* GetOption.3 */,
				F966BA5008F27A38005CB29B /* GetPixels.3 */,
				F966BA5108F27A38005CB29B /* GetPixmap.3 */,
				F966BA5208F27A38005CB29B /* GetRelief.3 */,
				F966BA5308F27A38005CB29B /* GetRootCrd.3 */,
				F966BA5408F27A38005CB29B /* GetScroll.3 */,
				F966BA5508F27A38005CB29B /* GetSelect.3 */,
				F966BA5608F27A38005CB29B /* GetUid.3 */,
				F966BA5708F27A38005CB29B /* GetVisual.3 */,
				F966BA5808F27A38005CB29B /* GetVRoot.3 */,
				F966BA5908F27A38005CB29B /* Grab.3 */,
				F966BA5A08F27A38005CB29B /* grab.n */,
				F966BA5B08F27A38005CB29B /* grid.n */,
				F966BA5C08F27A38005CB29B /* HandleEvent.3 */,
				F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */,
				F966BA5E08F27A38005CB29B /* IdToWindow.3 */,
				F966BA5F08F27A38005CB29B /* image.n */,
				F966BA6008F27A38005CB29B /* ImgChanged.3 */,
				F966BA6108F27A38005CB29B /* Inactive.3 */,
				F966BA6208F27A38005CB29B /* InternAtom.3 */,
				F966BA6308F27A38005CB29B /* keysyms.n */,
				F966BA6408F27A38005CB29B /* label.n */,
				F966BA6508F27A38005CB29B /* labelframe.n */,
				F966BA6608F27A38005CB29B /* listbox.n */,
				F966BA6708F27A38005CB29B /* loadTk.n */,
				F966BA6808F27A38005CB29B /* lower.n */,
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
				F966BA8408F27A38005CB29B /* QWinEvent.3 */,
				F966BA8508F27A38005CB29B /* radiobutton.n */,
				F966BA8608F27A38005CB29B /* raise.n */,
				F966BA8708F27A38005CB29B /* Restack.3 */,
				F966BA8808F27A38005CB29B /* RestrictEv.3 */,
				F966BA8908F27A38005CB29B /* scale.n */,
				F966BA8A08F27A38005CB29B /* scrollbar.n */,
				F966BA8B08F27A38005CB29B /* selection.n */,
				F966BA8C08F27A38005CB29B /* send.n */,
				F966BA8D08F27A38005CB29B /* SetAppName.3 */,
				F966BA8E08F27A38005CB29B /* SetCaret.3 */,
				F966BA8F08F27A38005CB29B /* SetClass.3 */,
				F966BA9008F27A38005CB29B /* SetClassProcs.3 */,
				F966BA9108F27A38005CB29B /* SetGrid.3 */,
				F966BA9208F27A38005CB29B /* SetOptions.3 */,
				F966BA9308F27A38005CB29B /* SetVisual.3 */,
				F966BA9408F27A38005CB29B /* spinbox.n */,
				F966BA9508F27A38005CB29B /* StrictMotif.3 */,
				F966BA9608F27A38005CB29B /* text.n */,
				F966BA9708F27A38005CB29B /* TextLayout.3 */,
				F966BA9808F27A38005CB29B /* tk.n */,
				F966BA9A08F27A38005CB29B /* Tk_Init.3 */,
				F966BA9B08F27A38005CB29B /* Tk_Main.3 */,
				F966BA9C08F27A38005CB29B /* tkerror.n */,
				F966BA9D08F27A38005CB29B /* TkInitStubs.3 */,
				F966BA9E08F27A38005CB29B /* tkvars.n */,
				F966BA9F08F27A38005CB29B /* tkwait.n */,
				F966BAA008F27A38005CB29B /* toplevel.n */,
				F968886B0AF788F6000797B5 /* ttk_button.n */,
				F968886C0AF788F6000797B5 /* ttk_checkbutton.n */,
				F968886D0AF788F6000797B5 /* ttk_combobox.n */,
				F968886F0AF788F6000797B5 /* ttk_entry.n */,
				F96888700AF788F6000797B5 /* ttk_frame.n */,
				F96888710AF788F6000797B5 /* ttk_Geometry.3 */,
				F96888720AF788F6000797B5 /* ttk_image.n */,
				F96888730AF788F6000797B5 /* ttk_intro.n */,
				F96888740AF788F6000797B5 /* ttk_label.n */,
				F96888750AF788F6000797B5 /* ttk_labelframe.n */,
				F96888760AF788F6000797B5 /* ttk_menubutton.n */,
				F96888770AF788F6000797B5 /* ttk_notebook.n */,
				F96888780AF788F6000797B5 /* ttk_panedwindow.n */,
				F96888790AF788F6000797B5 /* ttk_progressbar.n */,
				F968887A0AF788F6000797B5 /* ttk_radiobutton.n */,
				F968887B0AF788F6000797B5 /* ttk_scrollbar.n */,
				F968887C0AF788F6000797B5 /* ttk_separator.n */,
				F968887D0AF788F6000797B5 /* ttk_sizegrip.n */,
				F968887E0AF788F6000797B5 /* ttk_style.n */,
				F968887F0AF788F6000797B5 /* ttk_Theme.3 */,
				F96888800AF788F6000797B5 /* ttk_treeview.n */,
				F96888810AF788F6000797B5 /* ttk_widget.n */,
				F966BAA108F27A38005CB29B /* WindowId.3 */,
				F966BAA208F27A38005CB29B /* winfo.n */,
				F966BAA308F27A38005CB29B /* wish.1 */,
				F966BAA408F27A38005CB29B /* wm.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F966BAA508F27A38005CB29B /* generic */ = {
			isa = PBXGroup;
			children = (
				F966BAA608F27A38005CB29B /* default.h */,
				F966BAA708F27A38005CB29B /* ks_names.h */,
				F966BAA908F27A39005CB29B /* README */,
				F966BAAA08F27A39005CB29B /* tk.decls */,
				F966BAAB08F27A39005CB29B /* tk.h */,
				F966BAAC08F27A39005CB29B /* tk3d.c */,
				F966BAAD08F27A39005CB29B /* tk3d.h */,
				F966BAAE08F27A39005CB29B /* tkArgv.c */,
				F966BAAF08F27A39005CB29B /* tkAtom.c */,
				F966BAB008F27A39005CB29B /* tkBind.c */,
				F966BAB108F27A39005CB29B /* tkBitmap.c */,
				F9152B080EAF8A5000CD5C7B /* tkBusy.c */,
				F966BAB208F27A39005CB29B /* tkButton.c */,
				F966BAB308F27A39005CB29B /* tkButton.h */,
				F966BAB408F27A39005CB29B /* tkCanvArc.c */,
				F966BAB508F27A39005CB29B /* tkCanvas.c */,
				F966BAB608F27A39005CB29B /* tkCanvas.h */,
				F966BAB708F27A39005CB29B /* tkCanvBmap.c */,
				F966BAB808F27A39005CB29B /* tkCanvImg.c */,
				F966BAB908F27A39005CB29B /* tkCanvLine.c */,
				F966BABA08F27A39005CB29B /* tkCanvPoly.c */,
				F966BABB08F27A39005CB29B /* tkCanvPs.c */,
				F966BABD08F27A39005CB29B /* tkCanvText.c */,
				F966BABE08F27A39005CB29B /* tkCanvUtil.c */,
				F966BABF08F27A39005CB29B /* tkCanvWind.c */,
				F966BAC008F27A39005CB29B /* tkClipboard.c */,
				F966BAC108F27A39005CB29B /* tkCmds.c */,
				F966BAC208F27A39005CB29B /* tkColor.c */,
				F966BAC308F27A39005CB29B /* tkColor.h */,
				F966BAC408F27A39005CB29B /* tkConfig.c */,
				F966BAC508F27A39005CB29B /* tkConsole.c */,
				F966BAC608F27A39005CB29B /* tkCursor.c */,
				F966BAC708F27A39005CB29B /* tkDecls.h */,
				F966BAC808F27A39005CB29B /* tkEntry.c */,
				F966BAC908F27A39005CB29B /* tkEntry.h */,
				F966BACA08F27A39005CB29B /* tkError.c */,
				F966BACB08F27A39005CB29B /* tkEvent.c */,
				F966BACC08F27A39005CB29B /* tkFileFilter.c */,
				F966BACD08F27A39005CB29B /* tkFileFilter.h */,
				F966BACE08F27A39005CB29B /* tkFocus.c */,
				F966BACF08F27A39005CB29B /* tkFont.c */,
				F966BAD008F27A39005CB29B /* tkFont.h */,
				F966BAD108F27A39005CB29B /* tkFrame.c */,
				F966BAD208F27A39005CB29B /* tkGC.c */,
				F966BAD308F27A39005CB29B /* tkGeometry.c */,
				F966BAD408F27A39005CB29B /* tkGet.c */,
				F966BAD508F27A39005CB29B /* tkGrab.c */,
				F966BAD608F27A39005CB29B /* tkGrid.c */,
				F966BAD708F27A39005CB29B /* tkImage.c */,
				F966BAD808F27A39005CB29B /* tkImgBmap.c */,
				F966BAD908F27A39005CB29B /* tkImgGIF.c */,
				F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */,
				F966BADA08F27A39005CB29B /* tkImgPhoto.c */,
				F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */,
				F966BADB08F27A39005CB29B /* tkImgPPM.c */,
				F966BADC08F27A39005CB29B /* tkImgUtil.c */,
				F966BADE08F27A39005CB29B /* tkInt.decls */,
				F966BADF08F27A39005CB29B /* tkInt.h */,
				F966BAE108F27A39005CB29B /* tkIntDecls.h */,
				F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */,
				F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */,
				F966BAE408F27A39005CB29B /* tkListbox.c */,
				F966BAE508F27A39005CB29B /* tkMacWinMenu.c */,
				F966BAE608F27A39005CB29B /* tkMain.c */,
				F966BAE708F27A39005CB29B /* tkMenu.c */,
				F966BAE808F27A39005CB29B /* tkMenu.h */,
				F966BAE908F27A39005CB29B /* tkMenubutton.c */,
				F966BAEA08F27A39005CB29B /* tkMenubutton.h */,
				F966BAEB08F27A39005CB29B /* tkMenuDraw.c */,
				F966BAEC08F27A39005CB29B /* tkMessage.c */,
				F966BAED08F27A39005CB29B /* tkObj.c */,
				F966BAEE08F27A39005CB29B /* tkOldConfig.c */,
				F966BAEF08F27A39005CB29B /* tkOption.c */,
				F966BAF008F27A39005CB29B /* tkPack.c */,
				F966BAF108F27A39005CB29B /* tkPanedWindow.c */,
				F966BAF208F27A39005CB29B /* tkPlace.c */,
				F966BAF308F27A39005CB29B /* tkPlatDecls.h */,
				F966BAF408F27A39005CB29B /* tkPointer.c */,
				F966BAF508F27A39005CB29B /* tkPort.h */,
				F966BAF608F27A39005CB29B /* tkRectOval.c */,
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
				F966BB0608F27A39005CB29B /* tkTextDisp.c */,
				F966BB0808F27A39005CB29B /* tkTextImage.c */,
				F966BB0908F27A39005CB29B /* tkTextIndex.c */,
				F966BB0A08F27A39005CB29B /* tkTextMark.c */,
				F966BB0B08F27A39005CB29B /* tkTextTag.c */,
				F966BB0C08F27A39005CB29B /* tkTextWind.c */,
				F966BB0D08F27A39005CB29B /* tkTrig.c */,
				F966BB0E08F27A39005CB29B /* tkUndo.c */,
				F966BB0F08F27A39005CB29B /* tkUndo.h */,
				F966BB1008F27A39005CB29B /* tkUtil.c */,
				F966BB1108F27A39005CB29B /* tkVisual.c */,
				F966BB1208F27A39005CB29B /* tkWindow.c */,
				F96887DF0AF786D5000797B5 /* ttk */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F966BB1308F27A39005CB29B /* library */ = {
			isa = PBXGroup;
			children = (
				F966BB1408F27A39005CB29B /* bgerror.tcl */,
				F966BB1508F27A39005CB29B /* button.tcl */,
				F966BB1608F27A39005CB29B /* choosedir.tcl */,
				F966BB1708F27A39005CB29B /* clrpick.tcl */,
				F966BB1808F27A39005CB29B /* comdlg.tcl */,
				F966BB1908F27A39005CB29B /* console.tcl */,
				F966BB1A08F27A39005CB29B /* demos */,
				F966BB6208F27A3A005CB29B /* dialog.tcl */,
				F966BB6308F27A3A005CB29B /* entry.tcl */,
				F966BB6408F27A3A005CB29B /* focus.tcl */,
				F99388380EE0114B0065FE6B /* fontchooser.tcl */,
				F974D57C0FBE7EFF00BF728B /* iconlist.tcl */,
				F974D57D0FBE7EFF00BF728B /* icons.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
			children = (
				F966BB1B08F27A39005CB29B /* anilabel.tcl */,
				F966BB1C08F27A39005CB29B /* aniwave.tcl */,
				F966BB1D08F27A39005CB29B /* arrow.tcl */,
				F966BB1E08F27A39005CB29B /* bind.tcl */,
				F966BB1F08F27A39005CB29B /* bitmap.tcl */,
				F966BB2008F27A39005CB29B /* browse */,
				F966BB2108F27A39005CB29B /* button.tcl */,
				F966BB2208F27A39005CB29B /* check.tcl */,
				F966BB2308F27A39005CB29B /* clrpick.tcl */,
				F966BB2408F27A39005CB29B /* colors.tcl */,
				F936FCDB0CCD984600716967 /* combo.tcl */,
				F966BB2508F27A39005CB29B /* cscroll.tcl */,
				F966BB2608F27A39005CB29B /* ctext.tcl */,
				F966BB2708F27A39005CB29B /* dialog1.tcl */,
				F966BB2808F27A39005CB29B /* dialog2.tcl */,
				F966BB2A08F27A39005CB29B /* entry1.tcl */,
				F966BB2B08F27A39005CB29B /* entry2.tcl */,
				F966BB2C08F27A39005CB29B /* entry3.tcl */,
				F966BB2D08F27A39005CB29B /* filebox.tcl */,
				F966BB2E08F27A39005CB29B /* floor.tcl */,
				F91543270EF201A90032D1E8 /* fontchoose.tcl */,
				F966BB2F08F27A39005CB29B /* form.tcl */,
				F966BB3008F27A39005CB29B /* goldberg.tcl */,
				F966BB3108F27A39005CB29B /* hello */,
				F966BB3208F27A39005CB29B /* hscale.tcl */,
				F966BB3308F27A39005CB29B /* icon.tcl */,
				F966BB3408F27A39005CB29B /* image1.tcl */,
				F966BB3508F27A39005CB29B /* image2.tcl */,
				F966BB4208F27A3A005CB29B /* items.tcl */,
				F966BB4308F27A3A005CB29B /* ixset */,
				F92240290D7C620F005EC715 /* knightstour.tcl */,
				F966BB4408F27A3A005CB29B /* label.tcl */,
				F966BB4508F27A3A005CB29B /* labelframe.tcl */,
				F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */,
				F966BB4608F27A3A005CB29B /* menu.tcl */,
				F966BB4708F27A3A005CB29B /* menubu.tcl */,
				F966BB4808F27A3A005CB29B /* msgbox.tcl */,
				F966BB4A08F27A3A005CB29B /* paned1.tcl */,
				F966BB4B08F27A3A005CB29B /* paned2.tcl */,
				F966BB4C08F27A3A005CB29B /* pendulum.tcl */,
				F966BB4D08F27A3A005CB29B /* plot.tcl */,
				F966BB4E08F27A3A005CB29B /* puzzle.tcl */,
				F966BB4F08F27A3A005CB29B /* radio.tcl */,
				F966BB5008F27A3A005CB29B /* README */,
				F966BB5108F27A3A005CB29B /* rmt */,
				F966BB5208F27A3A005CB29B /* rolodex */,
				F966BB5308F27A3A005CB29B /* ruler.tcl */,
				F966BB5408F27A3A005CB29B /* sayings.tcl */,
				F966BB5508F27A3A005CB29B /* search.tcl */,
				F966BB5608F27A3A005CB29B /* spin.tcl */,
				F966BB5708F27A3A005CB29B /* square */,
				F966BB5808F27A3A005CB29B /* states.tcl */,
				F966BB5908F27A3A005CB29B /* style.tcl */,
				F966BB5A08F27A3A005CB29B /* tclIndex */,
				F966BB5B08F27A3A005CB29B /* tcolor */,
				F966BB5C08F27A3A005CB29B /* text.tcl */,
				F9099B8A0CC67D30005A9580 /* textpeer.tcl */,
				F966BB5D08F27A3A005CB29B /* timer */,
				F936FCD90CCD984600716967 /* toolbar.tcl */,
				F936FCD80CCD984600716967 /* tree.tcl */,
				F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */,
				F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */,
				F936FCDA0CCD984600716967 /* ttknote.tcl */,
				F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */,
				F936FCD70CCD984500716967 /* ttkprogress.tcl */,
				F966BB5E08F27A3A005CB29B /* twind.tcl */,
				F966BB5F08F27A3A005CB29B /* unicodeout.tcl */,
				F966BB6008F27A3A005CB29B /* vscale.tcl */,
				F966BB6108F27A3A005CB29B /* widget */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		F966BB9708F27A3B005CB29B /* macosx */ = {
			isa = PBXGroup;
			children = (
				F966BBBA08F27A3B005CB29B /* configure.ac */,
				F966BBBB08F27A3B005CB29B /* GNUmakefile */,
				F966BBBE08F27A3B005CB29B /* README */,
				F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */,
				F966BBC208F27A3B005CB29B /* tkMacOSX.h */,
				F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */,
				F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */,
				F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */,
				F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */,
				F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */,
				F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */,
				F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */,
				F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */,
				F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */,
				F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */,
				F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */,
				F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */,
				F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */,
				F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */,
				F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */,
				F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */,
				F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */,
				F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */,
				F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */,
				F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */,
				F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */,
				F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */,
				F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */,
				F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */,
				F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */,
				F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */,
				F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */,
				F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */,
				F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */,
				F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */,
				F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */,
				F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */,
				F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */,
				F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */,
				F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */,
				F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */,
				F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */,
				F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */,
				F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */,
				F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */,
				F96888840AF78938000797B5 /* ttkMacOSXTheme.c */,
				F95D8D4B0F1715610006B020 /* Tk.icns */,
				F95D8D4C0F1715610006B020 /* Tk.tiff */,
				F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */,
				F97590AE1039A96200558A9A /* Wish.sdef */,
				F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F966BC0408F27A3C005CB29B /* tests */ = {
			isa = PBXGroup;
			children = (
				F966BC0508F27A3C005CB29B /* all.tcl */,
				F966BC0608F27A3C005CB29B /* arc.tcl */,
				F966BC0708F27A3C005CB29B /* bell.test */,
				F966BC0808F27A3C005CB29B /* bevel.tcl */,
				F966BC0908F27A3C005CB29B /* bgerror.test */,
				F966BC0A08F27A3C005CB29B /* bind.test */,
				F966BC0B08F27A3C005CB29B /* bitmap.test */,
				F966BC0C08F27A3C005CB29B /* border.test */,
				F966BC0D08F27A3C005CB29B /* bugs.tcl */,
				F966BC0E08F27A3C005CB29B /* butGeom.tcl */,
				F966BC0F08F27A3C005CB29B /* butGeom2.tcl */,
				F966BC1008F27A3C005CB29B /* button.test */,
				F966BC1108F27A3C005CB29B /* canvas.test */,
				F966BC1208F27A3C005CB29B /* canvImg.test */,
				F966BC1308F27A3C005CB29B /* canvPs.test */,
				F966BC1408F27A3C005CB29B /* canvPsArc.tcl */,
				F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */,
				F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */,
				F966BC1708F27A3C005CB29B /* canvPsImg.tcl */,
				F966BC1808F27A3C005CB29B /* canvPsText.tcl */,
				F966BC1908F27A3C005CB29B /* canvRect.test */,
				F966BC1A08F27A3C005CB29B /* canvText.test */,
				F966BC1B08F27A3C005CB29B /* canvWind.test */,
				F966BC1C08F27A3C005CB29B /* choosedir.test */,
				F966BC1D08F27A3C005CB29B /* clipboard.test */,
				F966BC1E08F27A3C005CB29B /* clrpick.test */,
				F966BC1F08F27A3C005CB29B /* cmap.tcl */,
				F966BC2008F27A3C005CB29B /* cmds.test */,
				F966BC2108F27A3C005CB29B /* color.test */,
				F966BC2208F27A3C005CB29B /* config.test */,
				F966BC2308F27A3C005CB29B /* constraints.tcl */,
				F966BC2408F27A3C005CB29B /* cursor.test */,
				F966BC2508F27A3C005CB29B /* dialog.test */,
				F966BC2608F27A3C005CB29B /* embed.test */,
				F966BC2708F27A3C005CB29B /* entry.test */,
				F966BC2808F27A3C005CB29B /* event.test */,
				F966BC2908F27A3C005CB29B /* filebox.test */,
				F966BC2A08F27A3C005CB29B /* focus.test */,
				F966BC2B08F27A3C005CB29B /* focusTcl.test */,
				F966BC2C08F27A3C005CB29B /* font.test */,
				F99388950EE02D980065FE6B /* fontchooser.test */,
				F966BC2D08F27A3C005CB29B /* frame.test */,
				F966BC2E08F27A3C005CB29B /* geometry.test */,
				F966BC2F08F27A3C005CB29B /* get.test */,
				F966BC3008F27A3C005CB29B /* grab.test */,
				F966BC3108F27A3C005CB29B /* grid.test */,
				F966BC3308F27A3C005CB29B /* image.test */,
				F966BC3408F27A3C005CB29B /* imgBmap.test */,
				F966BC3508F27A3C005CB29B /* imgPhoto.test */,
				F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */,
				F966BC3608F27A3C005CB29B /* imgPPM.test */,
				F966BC3708F27A3C005CB29B /* listbox.test */,
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
				F966BC4708F27A3D005CB29B /* README */,
				F966BC4808F27A3D005CB29B /* safe.test */,
				F966BC4908F27A3D005CB29B /* scale.test */,
				F966BC4A08F27A3D005CB29B /* scrollbar.test */,
				F966BC4B08F27A3D005CB29B /* select.test */,
				F966BC4C08F27A3D005CB29B /* send.test */,
				F966BC4D08F27A3D005CB29B /* spinbox.test */,
				F966BC4E08F27A3D005CB29B /* text.test */,
				F966BC4F08F27A3D005CB29B /* textBTree.test */,
				F966BC5008F27A3D005CB29B /* textDisp.test */,
				F966BC5108F27A3D005CB29B /* textImage.test */,
				F966BC5208F27A3D005CB29B /* textIndex.test */,
				F966BC5308F27A3D005CB29B /* textMark.test */,
				F966BC5408F27A3D005CB29B /* textTag.test */,
				F966BC5508F27A3D005CB29B /* textWind.test */,
				F966BC5608F27A3D005CB29B /* tk.test */,
				F96888530AF7880C000797B5 /* ttk */,
				F966BC5708F27A3D005CB29B /* unixButton.test */,
				F966BC5808F27A3D005CB29B /* unixEmbed.test */,
				F966BC5908F27A3D005CB29B /* unixFont.test */,
				F966BC5A08F27A3D005CB29B /* unixMenu.test */,
				F966BC5B08F27A3D005CB29B /* unixSelect.test */,
				F966BC5C08F27A3D005CB29B /* unixWm.test */,
				F966BC5D08F27A3D005CB29B /* util.test */,
				F966BC5E08F27A3D005CB29B /* visual.test */,
				F966BC5F08F27A3D005CB29B /* visual_bb.test */,
				F966BC6008F27A3D005CB29B /* winButton.test */,
				F966BC6108F27A3D005CB29B /* winClipboard.test */,
				F966BC6208F27A3D005CB29B /* winDialog.test */,
				F966BC6308F27A3D005CB29B /* window.test */,
				F966BC6408F27A3D005CB29B /* winfo.test */,
				F966BC6508F27A3D005CB29B /* winFont.test */,
				F966BC6608F27A3D005CB29B /* winMenu.test */,
				F966BC6708F27A3D005CB29B /* winSend.test */,
				F966BC6808F27A3D005CB29B /* winWm.test */,
				F966BC6908F27A3D005CB29B /* wm.test */,
				F966BC6A08F27A3D005CB29B /* xmfbox.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.ac */,
				F966BC6F08F27A3D005CB29B /* install-sh */,
				F966BC7008F27A3D005CB29B /* installManPage */,
				F966BC7108F27A3D005CB29B /* Makefile.in */,
				F966BC7208F27A3D005CB29B /* README */,
				F966BC7308F27A3D005CB29B /* tcl.m4 */,
				F974D57B0FBE7EC000BF728B /* tk.pc.in */,
				F966BC7408F27A3D005CB29B /* tk.spec */,
				F966BC7508F27A3D005CB29B /* tkAppInit.c */,
				F966BC7608F27A3D005CB29B /* tkConfig.h.in */,
				F966BC7708F27A3D005CB29B /* tkConfig.sh.in */,
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
				F966BC8708F27A3D005CB29B /* tkUnixKey.c */,
				F966BC8808F27A3D005CB29B /* tkUnixMenu.c */,
				F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */,
				F966BC8A08F27A3D005CB29B /* tkUnixPort.h */,
				F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */,
				F966BC8C08F27A3D005CB29B /* tkUnixScale.c */,
				F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */,
				F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */,
				F966BC8F08F27A3D005CB29B /* tkUnixSend.c */,
				F966BC9008F27A3D005CB29B /* tkUnixWm.c */,
				F966BC9108F27A3D005CB29B /* tkUnixXId.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.ac */,
				F966BC9908F27A3E005CB29B /* Makefile.in */,
				F966BC9A08F27A3E005CB29B /* makefile.vc */,
				F966BC9C08F27A3E005CB29B /* nmakehlp.c */,
				F966BC9D08F27A3E005CB29B /* rc */,
				F966BCF308F27A3E005CB29B /* README */,
				F966BCF508F27A3F005CB29B /* rules.vc */,
				F966BCF608F27A3F005CB29B /* stubs.c */,
				F966BCF708F27A3F005CB29B /* tcl.m4 */,
				F966BCF808F27A3F005CB29B /* tkConfig.sh.in */,
				F966BCF908F27A3F005CB29B /* tkWin.h */,
				F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */,
				F966BCFB08F27A3F005CB29B /* tkWin3d.c */,
				F966BCFC08F27A3F005CB29B /* tkWinButton.c */,
				F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */,
				F966BCFE08F27A3F005CB29B /* tkWinColor.c */,
				F966BCFF08F27A3F005CB29B /* tkWinConfig.c */,
				F966BD0008F27A3F005CB29B /* tkWinCursor.c */,
				F966BD0108F27A3F005CB29B /* tkWinDefault.h */,
				F966BD0208F27A3F005CB29B /* tkWinDialog.c */,
				F966BD0308F27A3F005CB29B /* tkWinDraw.c */,
				F966BD0408F27A3F005CB29B /* tkWinEmbed.c */,
				F966BD0508F27A3F005CB29B /* tkWinFont.c */,
				F966BD0708F27A3F005CB29B /* tkWinImage.c */,
				F966BD0808F27A3F005CB29B /* tkWinInit.c */,
				F966BD0908F27A3F005CB29B /* tkWinInt.h */,
				F966BD0A08F27A3F005CB29B /* tkWinKey.c */,
				F966BD0B08F27A3F005CB29B /* tkWinMenu.c */,
				F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */,
				F966BD0D08F27A3F005CB29B /* tkWinPointer.c */,
				F966BD0E08F27A3F005CB29B /* tkWinPort.h */,
				F966BD0F08F27A3F005CB29B /* tkWinRegion.c */,
				F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */,
				F966BD1108F27A3F005CB29B /* tkWinSend.c */,
				F966BD1208F27A3F005CB29B /* tkWinSendCom.c */,
				F966BD1308F27A3F005CB29B /* tkWinSendCom.h */,
				F966BD1408F27A3F005CB29B /* tkWinTest.c */,
				F966BD1508F27A3F005CB29B /* tkWinWindow.c */,
				F966BD1608F27A3F005CB29B /* tkWinWm.c */,
				F966BD1708F27A3F005CB29B /* tkWinX.c */,
				F96888860AF78953000797B5 /* ttkWinMonitor.c */,
				F96888870AF78953000797B5 /* ttkWinTheme.c */,
				F96888880AF78953000797B5 /* ttkWinXPTheme.c */,
				F966BD1808F27A3F005CB29B /* winMain.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F966BC9D08F27A3E005CB29B /* rc */ = {
			isa = PBXGroup;
			children = (
				F966BCEE08F27A3E005CB29B /* tk.rc */,
				F966BCEF08F27A3E005CB29B /* tk_base.rc */,
				F966BCF208F27A3E005CB29B /* wish.rc */,
			);
			path = rc;
			sourceTree = "<group>";
		};
		F966BD1908F27A3F005CB29B /* xlib */ = {
			isa = PBXGroup;
			children = (
				F966BD1A08F27A3F005CB29B /* X11 */,
				F966BD2308F27A3F005CB29B /* xbytes.h */,
				F966BD2408F27A3F005CB29B /* xcolors.c */,
				F966BD2508F27A3F005CB29B /* xdraw.c */,
				F966BD2608F27A3F005CB29B /* xgc.c */,
				F966BD2708F27A3F005CB29B /* ximage.c */,
				F966BD2808F27A3F005CB29B /* xutil.c */,
			);
			path = xlib;
			sourceTree = "<group>";
		};
		F966BD1A08F27A3F005CB29B /* X11 */ = {
			isa = PBXGroup;
			children = (
				F966BD1B08F27A3F005CB29B /* cursorfont.h */,
				F966BD1C08F27A3F005CB29B /* keysym.h */,
				F966BD1D08F27A3F005CB29B /* keysymdef.h */,
				F966BD1E08F27A3F005CB29B /* X.h */,
				F966BD1F08F27A3F005CB29B /* Xatom.h */,
				F966BD2008F27A3F005CB29B /* Xfuncproto.h */,
				F966BD2108F27A3F005CB29B /* Xlib.h */,
				F966BD2208F27A3F005CB29B /* Xutil.h */,
			);
			path = X11;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */,
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F96437E60EF0D652003F468E /* libz.dylib */,
				F966C07608F2821B005CB29B /* Carbon.framework */,
				F94523A10E6FC2AC00C1D987 /* Cocoa.framework */,
				F966C07808F28233005CB29B /* IOKit.framework */,
				F9FD32140CC1AF170073837D /* libX11.dylib */,
				F9FD32150CC1AF170073837D /* libXext.dylib */,
				F9FD32160CC1AF170073837D /* libXss.dylib */,
				F9FD349A0CC1BB0D0073837D /* libXft.dylib */,
				F9FD34990CC1BB0D0073837D /* libfreetype.dylib */,
				F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96887DF0AF786D5000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96887E00AF786D5000797B5 /* ttk.decls */,
				F96887E10AF786D5000797B5 /* ttkBlink.c */,
				F96887E20AF786D5000797B5 /* ttkButton.c */,
				F96887E30AF786D5000797B5 /* ttkCache.c */,
				F96887E40AF786D5000797B5 /* ttkClamTheme.c */,
				F96887E50AF786D5000797B5 /* ttkClassicTheme.c */,
				F96887E60AF786D5000797B5 /* ttkDecls.h */,
				F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */,
				F96887E80AF786D5000797B5 /* ttkElements.c */,
				F96887E90AF786D5000797B5 /* ttkEntry.c */,
				F96887EA0AF786D5000797B5 /* ttkFrame.c */,
				F96887EB0AF786D5000797B5 /* ttkImage.c */,
				F96887EC0AF786D5000797B5 /* ttkInit.c */,
				F96887ED0AF786D5000797B5 /* ttkLabel.c */,
				F96887EE0AF786D5000797B5 /* ttkLayout.c */,
				F96887EF0AF786D5000797B5 /* ttkManager.c */,
				F96887F00AF786D5000797B5 /* ttkManager.h */,
				F96887F10AF786D5000797B5 /* ttkNotebook.c */,
				F96887F20AF786D5000797B5 /* ttkPanedwindow.c */,
				F96887F30AF786D5000797B5 /* ttkProgress.c */,
				F96887F40AF786D5000797B5 /* ttkScale.c */,
				F96887F50AF786D5000797B5 /* ttkScroll.c */,
				F96887F60AF786D5000797B5 /* ttkScrollbar.c */,
				F96887F70AF786D5000797B5 /* ttkSeparator.c */,
				F96887F80AF786D5000797B5 /* ttkSquare.c */,
				F96887F90AF786D5000797B5 /* ttkState.c */,
				F96887FA0AF786D5000797B5 /* ttkStubInit.c */,
				F96887FB0AF786D5000797B5 /* ttkStubLib.c */,
				F96887FC0AF786D5000797B5 /* ttkTagSet.c */,
				F96887FD0AF786D5000797B5 /* ttkTheme.c */,
				F96887FE0AF786D5000797B5 /* ttkTheme.h */,
				F96887FF0AF786D5000797B5 /* ttkThemeInt.h */,
				F96888000AF786D5000797B5 /* ttkTrace.c */,
				F96888010AF786D5000797B5 /* ttkTrack.c */,
				F96888020AF786D5000797B5 /* ttkTreeview.c */,
				F96888030AF786D5000797B5 /* ttkWidget.c */,
				F96888040AF786D5000797B5 /* ttkWidget.h */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888360AF787B3000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888370AF787B3000797B5 /* altTheme.tcl */,
				F96888380AF787B3000797B5 /* aquaTheme.tcl */,
				F96888390AF787B3000797B5 /* button.tcl */,
				F968883A0AF787B3000797B5 /* clamTheme.tcl */,
				F968883B0AF787B3000797B5 /* classicTheme.tcl */,
				F968883C0AF787B3000797B5 /* combobox.tcl */,
				F968883D0AF787B3000797B5 /* cursors.tcl */,
				F968883E0AF787B3000797B5 /* defaults.tcl */,
				F96888400AF787B3000797B5 /* entry.tcl */,
				F96888410AF787B3000797B5 /* fonts.tcl */,
				F96888440AF787B3000797B5 /* menubutton.tcl */,
				F96888450AF787B3000797B5 /* notebook.tcl */,
				F96888460AF787B3000797B5 /* panedwindow.tcl */,
				F96888470AF787B3000797B5 /* progress.tcl */,
				F96888480AF787B3000797B5 /* scale.tcl */,
				F96888490AF787B3000797B5 /* scrollbar.tcl */,
				F968884A0AF787B3000797B5 /* sizegrip.tcl */,
				F968884B0AF787B3000797B5 /* treeview.tcl */,
				F968884C0AF787B3000797B5 /* ttk.tcl */,
				F968884D0AF787B3000797B5 /* utils.tcl */,
				F968884E0AF787B3000797B5 /* winTheme.tcl */,
				F973E5960EE99384001A648E /* vistaTheme.tcl */,
				F968884F0AF787B3000797B5 /* xpTheme.tcl */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888530AF7880C000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888540AF7880C000797B5 /* all.tcl */,
				F98383650F0FA43900171CA6 /* checkbutton.test */,
				F96888560AF7880C000797B5 /* combobox.test */,
				F96888570AF7880C000797B5 /* entry.test */,
				F96888580AF7880C000797B5 /* image.test */,
				F96888590AF7880C000797B5 /* labelframe.test */,
				F968885A0AF7880C000797B5 /* layout.test */,
				F968885C0AF7880C000797B5 /* notebook.test */,
				F968885D0AF7880C000797B5 /* panedwindow.test */,
				F968885E0AF7880C000797B5 /* progressbar.test */,
				F98383680F0FA44700171CA6 /* radiobutton.test */,
				F968885F0AF7880C000797B5 /* scrollbar.test */,
				F96888600AF7880C000797B5 /* treetags.test */,
				F96888610AF7880C000797B5 /* treeview.test */,
				F96888620AF7880C000797B5 /* ttk.test */,
				F96888630AF7880C000797B5 /* validate.test */,
				F962F7C60DADC26200648DB8 /* vsapi.test */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E0F08F272A5004A47F5 /* case.n */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F93599CF0DF1F87F00E04F67 /* Class.3 */,
				F93599D00DF1F89E00E04F67 /* class.n */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F93599D20DF1F8DF00E04F67 /* copy.n */,
				F974D5720FBE7DC600BF728B /* coroutine.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F93599D40DF1F91900E04F67 /* Method.3 */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F93599D50DF1F93700E04F67 /* my.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F93599D60DF1F95000E04F67 /* next.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F93599D70DF1F96800E04F67 /* object.n */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F93599D80DF1F98300E04F67 /* self.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F974D5760FBE7E1900BF728B /* tailcall.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F9183E640EFC80CD0030B814 /* throw.n */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F9183E650EFC80D70030B814 /* try.n */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
				F915432D0EF201EE0032D1E8 /* zlib.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F93599B20DF1F75400E04F67 /* tclOO.c */,
				F93599B40DF1F75900E04F67 /* tclOO.decls */,
				F93599B50DF1F75D00E04F67 /* tclOO.h */,
				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96437C90EF0D4B2003F468E /* tclZlib.c */,
				F96D3F3708F272A7004A47F5 /* tommath.h */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9008F272A8004A47F5 /* http1.0 */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
			isa = PBXGroup;
			children = (
				F96D3F9108F272A8004A47F5 /* http.tcl */,
				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http1.0;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D42D708F272B3004A47F5 /* bncore.c */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F974D5770FBE7E6100BF728B /* coroutine.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F974D56C0FBE7D6300BF728B /* http11.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F91DC23C0E44C51B002CB8D1 /* nre.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F93599C80DF1F81900E04F67 /* oo.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F974D5780FBE7E6100BF728B /* tailcall.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
				F915432A0EF201CF0032D1E8 /* zlib.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.ac */,
				F96D442208F272B8004A47F5 /* eolFix.tcl */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D442C08F272B8004A47F5 /* man2help.tcl */,
				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
				F96D442E08F272B8004A47F5 /* man2html.tcl */,
				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
				F96D443008F272B8004A47F5 /* man2html2.tcl */,
				F96D443108F272B8004A47F5 /* man2tcl.c */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
				F96D443608F272B8004A47F5 /* tcl.wse.in */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446A08F272B9004A47F5 /* tclUnixThrd.h */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tktest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
				F9A5C5F608F651AB008AE941 /* Configure Tk */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tktest;
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = 8DD76FB20486AB0100D96B5E /* tktest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tktest-X11 */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */;
			buildPhases = (
				F9FD30B40CC1AD070073837D /* Configure Tcl */,
				F9FD30B50CC1AD070073837D /* Configure Tk */,
				F9FD30BB0CC1AD070073837D /* Sources */,
				F9FD31E30CC1AD070073837D /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = "tktest-X11";
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = F9FD31F40CC1AD070073837D /* tktest-X11 */;
			productType = "com.apple.product-type.tool";
		};
		F9E61D16090A3E94002B3151 /* Tk */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* Build Tk */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tk;
			productName = Wish;
			productReference = F9A3084B08F2D4CE00BAE1AB /* Wish.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */;
			compatibilityVersion = "Xcode 3.2";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Tk */;
			projectDirPath = "";
			projectRoots = (
				..,
				../../tcl,
			);
			targets = (
				F9E61D16090A3E94002B3151 /* Tk */,
				8DD76FA90486AB0100D96B5E /* tktest */,
				F97258A50A86873C00096C78 /* tktest-X11 */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F97AF02F0B665DA900310EA2 /* Build Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			name = "Build Tk";
			outputPaths = (
				"${TARGET_BUILD_DIR}/${WRAPPER_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "export CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TK_SRCROOT}/macosx\"  -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" APPLICATION_INSTALL_PATH=\"${APPLICATION_INSTALL_PATH}\" TCL_BUILD_DIR=\"${TCL_BUILD_DIR}\" TCL_FRAMEWORK_DIR=\"${TCL_FRAMEWORK_DIR}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${BUILT_PRODUCTS_DIR}/tktest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tktest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F608F651AB008AE941 /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B40CC1AD070073837D /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B50CC1AD070073837D /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
				F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */,
				F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */,
				F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */,
				F966BDD308F27A3F005CB29B /* tkBind.c in Sources */,
				F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */,
				F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */,
				F966BDD508F27A3F005CB29B /* tkButton.c in Sources */,
				F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */,
				F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */,
				F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */,
				F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */,
				F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */,
				F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */,
				F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */,
				F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */,
				F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */,
				F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */,
				F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */,
				F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */,
				F966BDE508F27A3F005CB29B /* tkColor.c in Sources */,
				F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */,
				F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */,
				F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */,
				F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */,
				F966BDED08F27A3F005CB29B /* tkError.c in Sources */,
				F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */,
				F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */,
				F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */,
				F966BDF208F27A3F005CB29B /* tkFont.c in Sources */,
				F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */,
				F966BDF508F27A3F005CB29B /* tkGC.c in Sources */,
				F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */,
				F966BDF708F27A3F005CB29B /* tkGet.c in Sources */,
				F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */,
				F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */,
				F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */,
				F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */,
				F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */,
				F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */,
				F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */,
				F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */,
				F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */,
				F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */,
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
				F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */,
				F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */,
				F966BE2008F27A40005CB29B /* tkSquare.c in Sources */,
				F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */,
				F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */,
				F966BE2408F27A40005CB29B /* tkStyle.c in Sources */,
				F966BE2508F27A40005CB29B /* tkTest.c in Sources */,
				F966BE2608F27A40005CB29B /* tkText.c in Sources */,
				F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */,
				F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */,
				F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */,
				F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */,
				F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */,
				F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */,
				F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */,
				F966BE3008F27A40005CB29B /* tkTrig.c in Sources */,
				F966BE3108F27A40005CB29B /* tkUndo.c in Sources */,
				F966BE3308F27A40005CB29B /* tkUtil.c in Sources */,
				F966BE3408F27A40005CB29B /* tkVisual.c in Sources */,
				F966BE3508F27A40005CB29B /* tkWindow.c in Sources */,
				F96888050AF786D5000797B5 /* ttkBlink.c in Sources */,
				F96888060AF786D5000797B5 /* ttkButton.c in Sources */,
				F96888070AF786D5000797B5 /* ttkCache.c in Sources */,
				F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */,
				F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */,
				F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */,
				F968880B0AF786D5000797B5 /* ttkElements.c in Sources */,
				F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */,
				F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */,
				F968880E0AF786D5000797B5 /* ttkImage.c in Sources */,
				F968880F0AF786D5000797B5 /* ttkInit.c in Sources */,
				F96888100AF786D5000797B5 /* ttkLabel.c in Sources */,
				F96888110AF786D5000797B5 /* ttkLayout.c in Sources */,
				F96888120AF786D5000797B5 /* ttkManager.c in Sources */,
				F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */,
				F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */,
				F96888150AF786D5000797B5 /* ttkProgress.c in Sources */,
				F96888160AF786D5000797B5 /* ttkScale.c in Sources */,
				F96888170AF786D5000797B5 /* ttkScroll.c in Sources */,
				F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */,
				F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */,
				F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */,
				F968881B0AF786D5000797B5 /* ttkState.c in Sources */,
				F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */,
				F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */,
				F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */,
				F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */,
				F96888200AF786D5000797B5 /* ttkTrace.c in Sources */,
				F96888210AF786D5000797B5 /* ttkTrack.c in Sources */,
				F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */,
				F96888230AF786D5000797B5 /* ttkWidget.c in Sources */,
				F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */,
				F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */,
				F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */,
				F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */,
				F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */,
				F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */,
				F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */,
				F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */,
				F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */,
				F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */,
				F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */,
				F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */,
				F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */,
				F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */,
				F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */,
				F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */,
				F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */,
				F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */,
				F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */,
				F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */,
				F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */,
				F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */,
				F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */,
				F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */,
				F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */,
				F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */,
				F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */,
				F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */,
				F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */,
				F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */,
				F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */,
				F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */,
				F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */,
				F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */,
				F966C02A08F27A42005CB29B /* xcolors.c in Sources */,
				F966C02B08F27A42005CB29B /* xdraw.c in Sources */,
				F966C02C08F27A42005CB29B /* xgc.c in Sources */,
				F966C02D08F27A42005CB29B /* ximage.c in Sources */,
				F966C02E08F27A42005CB29B /* xutil.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD30BB0CC1AD070073837D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */,
				F9FD30BD0CC1AD070073837D /* regerror.c in Sources */,
				F9FD30BE0CC1AD070073837D /* regexec.c in Sources */,
				F9FD30BF0CC1AD070073837D /* regfree.c in Sources */,
				F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */,
				F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */,
				F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */,
				F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */,
				F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */,
				F9FD30C50CC1AD070073837D /* tclClock.c in Sources */,
				F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */,
				F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */,
				F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */,
				F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */,
				F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */,
				F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */,
				F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */,
				F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */,
				F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */,
				F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */,
				F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */,
				F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */,
				F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */,
				F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */,
				F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */,
				F9FD30D50CC1AD070073837D /* tclGet.c in Sources */,
				F9FD30D60CC1AD070073837D /* tclHash.c in Sources */,
				F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */,
				F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */,
				F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */,
				F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */,
				F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */,
				F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */,
				F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */,
				F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */,
				F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */,
				F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */,
				F9FD30E00CC1AD070073837D /* tclLink.c in Sources */,
				F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */,
				F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */,
				F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */,
				F9FD30E40CC1AD070073837D /* tclMain.c in Sources */,
				F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */,
				F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */,
				F9FD30E70CC1AD070073837D /* tclObj.c in Sources */,
				F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */,
				F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */,
				F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */,
				F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */,
				F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */,
				F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */,
				F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */,
				F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */,
				F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */,
				F9FD30E90CC1AD070073837D /* tclParse.c in Sources */,
				F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */,
				F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */,
				F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */,
				F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */,
				F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */,
				F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */,
				F9FD30F00CC1AD070073837D /* tclProc.c in Sources */,
				F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */,
				F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */,
				F9FD30F30CC1AD070073837D /* tclResult.c in Sources */,
				F9FD30F40CC1AD070073837D /* tclScan.c in Sources */,
				F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */,
				F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */,
				F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */,
				F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */,
				F9FD30F90CC1AD070073837D /* tclThread.c in Sources */,
				F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */,
				F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */,
				F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */,
				F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */,
				F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */,
				F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */,
				F9FD31000CC1AD070073837D /* tclUtf.c in Sources */,
				F9FD31010CC1AD070073837D /* tclUtil.c in Sources */,
				F9FD31020CC1AD070073837D /* tclVar.c in Sources */,
				F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */,
				F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */,
				F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */,
				F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */,
				F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */,
				F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */,
				F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */,
				F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */,
				F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */,
				F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */,
				F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */,
				F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */,
				F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */,
				F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */,
				F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */,
				F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */,
				F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */,
				F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */,
				F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */,
				F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */,
				F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */,
				F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */,
				F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */,
				F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */,
				F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */,
				F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */,
				F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */,
				F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */,
				F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */,
				F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */,
				F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */,
				F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */,
				F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */,
				F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */,
				F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */,
				F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */,
				F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */,
				F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */,
				F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */,
				F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */,
				F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */,
				F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */,
				F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */,
				F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */,
				F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */,
				F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */,
				F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */,
				F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */,
				F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */,
				F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */,
				F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */,
				F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */,
				F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */,
				F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */,
				F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */,
				F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */,
				F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */,
				F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */,
				F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */,
				F9FD313F0CC1AD070073837D /* bncore.c in Sources */,
				F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */,
				F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */,
				F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */,
				F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */,
				F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */,
				F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */,
				F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */,
				F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */,
				F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */,
				F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */,
				F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */,
				F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */,
				F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */,
				F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */,
				F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */,
				F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */,
				F9FD314F0CC1AD070073837D /* tk3d.c in Sources */,
				F9FD31500CC1AD070073837D /* tkArgv.c in Sources */,
				F9FD31510CC1AD070073837D /* tkAtom.c in Sources */,
				F9FD31520CC1AD070073837D /* tkBind.c in Sources */,
				F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */,
				F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */,
				F9FD31540CC1AD070073837D /* tkButton.c in Sources */,
				F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */,
				F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */,
				F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */,
				F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */,
				F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */,
				F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */,
				F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */,
				F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */,
				F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */,
				F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */,
				F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */,
				F9FD31600CC1AD070073837D /* tkCmds.c in Sources */,
				F9FD31610CC1AD070073837D /* tkColor.c in Sources */,
				F9FD31620CC1AD070073837D /* tkConfig.c in Sources */,
				F9FD31630CC1AD070073837D /* tkConsole.c in Sources */,
				F9FD31640CC1AD070073837D /* tkCursor.c in Sources */,
				F9FD31650CC1AD070073837D /* tkEntry.c in Sources */,
				F9FD31660CC1AD070073837D /* tkError.c in Sources */,
				F9FD31670CC1AD070073837D /* tkEvent.c in Sources */,
				F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */,
				F9FD31690CC1AD070073837D /* tkFocus.c in Sources */,
				F9FD316A0CC1AD070073837D /* tkFont.c in Sources */,
				F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */,
				F9FD316C0CC1AD070073837D /* tkGC.c in Sources */,
				F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */,
				F9FD316E0CC1AD070073837D /* tkGet.c in Sources */,
				F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */,
				F9FD31700CC1AD070073837D /* tkGrid.c in Sources */,
				F9FD31710CC1AD070073837D /* tkImage.c in Sources */,
				F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */,
				F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */,
				F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */,
				F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */,
				F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */,
				F9FD31760CC1AD070073837D /* tkListbox.c in Sources */,
				F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */,
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
				F9FD31880CC1AD070073837D /* tkSelect.c in Sources */,
				F9FD31890CC1AD070073837D /* tkSquare.c in Sources */,
				F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */,
				F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */,
				F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */,
				F9FD318D0CC1AD070073837D /* tkTest.c in Sources */,
				F9FD318E0CC1AD070073837D /* tkText.c in Sources */,
				F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */,
				F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */,
				F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */,
				F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */,
				F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */,
				F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */,
				F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */,
				F9FD31960CC1AD070073837D /* tkTrig.c in Sources */,
				F9FD31970CC1AD070073837D /* tkUndo.c in Sources */,
				F9FD31980CC1AD070073837D /* tkUtil.c in Sources */,
				F9FD31990CC1AD070073837D /* tkVisual.c in Sources */,
				F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */,
				F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */,
				F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */,
				F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */,
				F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */,
				F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */,
				F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */,
				F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */,
				F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */,
				F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */,
				F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */,
				F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */,
				F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */,
				F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */,
				F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */,
				F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */,
				F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */,
				F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */,
				F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */,
				F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */,
				F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */,
				F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */,
				F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */,
				F9FD31B10CC1AD070073837D /* ttkState.c in Sources */,
				F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */,
				F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */,
				F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */,
				F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */,
				F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */,
				F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */,
				F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */,
				F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */,
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
				F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */,
				F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */,
				F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */,
				F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */,
				F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */,
				F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */,
				F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */,
				F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		F90E36D50F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoGC;
		};
		F90E36D60F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoGC;
		};
		F90E36D70F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoGC;
		};
		F90E36D80F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoGC;
		};
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc40";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc40";
		};
		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				"GCC_OPTIMIZATION_LEVEL[arch=ppc]" = s;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
				RUN_CLANG_STATIC_ANALYZER = YES;
			};
			name = DebugLeaks;
		};
		F9A9D1EF0FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = clang;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug clang";
		};
		F9A9D1F00FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug clang";
		};
		F9A9D1F10FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug clang";
		};
		F9A9D1F20FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug clang";
		};
		F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CFLAGS = "-arch i386 -arch x86_64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = clang;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal clang";
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9A9D1F00FC77787002A2BE3 /* Debug clang */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F90E36D60F3B5C8400810A10 /* DebugNoGC */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9A9D1F10FC77787002A2BE3 /* Debug clang */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F90E36D70F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9A9D1EF0FC77787002A2BE3 /* Debug clang */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F90E36D50F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9A9D1F20FC77787002A2BE3 /* Debug clang */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F90E36D80F3B5C8400810A10 /* DebugNoGC */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added macosx/Wish-Common.xcconfig.





































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
// Wish-Common.xcconfig --
//
//	This file contains the Xcode build settings comon to all
//	project configurations in Wish.xcodeproj.
//
// Copyright (c) 2007-2009 Daniel A. Steffen <das@users.sourceforge.net>
// Copyright 2008-2009, Apple Inc.
//
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.
//

HEADER_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TK_SRCROOT)/xlib "$(DERIVED_FILE_DIR)/tcl" "$(DERIVED_FILE_DIR)/tk" $(HEADER_SEARCH_PATHS)
REZ_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TCL_SRCROOT)/generic $(REZ_SEARCH_PATHS)
OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __info_plist "$(DERIVED_FILE_DIR)/tk/Wish-Info.plist" $(OTHER_LDFLAGS)
OTHER_LDFLAGS_AQUA =
INSTALL_PATH = $(APPLICATION_INSTALL_PATH)
INSTALL_MODE_FLAG = go-w,a+rX
GCC_PREFIX_HEADER = $(DERIVED_FILE_DIR)/tk/tkConfig.h
OTHER_CFLAGS = -imacros "$(DERIVED_FILE_DIR)/tcl/tclConfig.h" $(OTHER_CFLAGS)
GCC_GENERATE_DEBUGGING_SYMBOLS = YES
GCC_NO_COMMON_BLOCKS = YES
GCC_DYNAMIC_NO_PIC = YES
GCC = $(DEVELOPER_DIR)/usr/bin/gcc
GCC_VERSION = 4.0
CC = $(GCC)-$(GCC_VERSION)
LD = $(CC)
WARNING_CFLAGS_GCC3 = -Wall -Wno-implicit-int -Wno-unused-parameter
WARNING_CFLAGS = -Wextra -Wno-missing-field-initializers -Winit-self -Wpointer-arith -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS_GCC3) $(WARNING_CFLAGS)
REZ_RESOURCE_MAP_READ_ONLY = YES
APPLICATION_INSTALL_PATH = /Applications/Utilities
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
MANDIR = $(PREFIX)/man
PER_ARCH_CFLAGS_ppc = -mcpu=G3 -mtune=G4 $(PER_ARCH_CFLAGS_ppc)
PREFIX = /usr/local
TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects
TCL_CONFIGURE_ARGS = --enable-threads --enable-dtrace
TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION)
TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED
VERSION = 8.5

Added macosx/Wish-Debug.xcconfig.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Wish-Debug.xcconfig --
//
//	This file contains the Xcode build settings for all Debug
//	project configurations in Wish.xcodeproj.
//
// 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.
//

#include "Wish-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf
DEPLOYMENT_POSTPROCESSING = NO
GCC_OPTIMIZATION_LEVEL = 0
GCC_PREPROCESSOR_DEFINITIONS = DEBUGLEVEL=4 $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --enable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = develop

Changes to macosx/Wish-Info.plist.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
	Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
	Copyright 2008-2009, Apple Inc.

	See the file "license.terms" for information on usage and redistribution of
	this file, and for a DISCLAIMER OF ALL WARRANTIES.
-->
<plist version="1.0">
  <dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDocumentTypes</key>
    <array>
      <dict>
	<key>CFBundleTypeExtensions</key>
	<array>
	  <string>tcl</string>
	  <string>TCL</string>
	  <string>*</string>
	</array>
	<key>CFBundleTypeMIMETypes</key>
	<array>
	  <string>application/x-tcl</string>
	  <string>text/plain</string>
	</array>
	<key>CFBundleTypeName</key>
	<string>NSStringPboardType</string>
	<key>CFBundleTypeOSTypes</key>
	<array>
	  <string>TEXT</string>
	  <string>****</string>
	</array>
	<key>CFBundleTypeRole</key>
	<string>Viewer</string>
      </dict>
    </array>
    <key>CFBundleURLTypes</key>
    <array>
      <dict>
	<key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>foo</string>
        </array>
        <key>CFBundleURLName</key>
        <string>Get Foo</string>
      </dict>
    </array>
    <key>CFBundleExecutable</key>
    <string>Wish</string>
    <key>CFBundleGetInfoString</key>
    <string>Wish Shell @TK_VERSION@@TK_PATCH_LEVEL@,
    Copyright © 1989-@TK_YEAR@ Tcl Core Team,

    Copyright © 1989-@TK_YEAR@ Contributors,
    Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech Communications LLC,
    Copyright © 2014-@TK_YEAR@ Marc Culler,
    Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,

    Copyright © 2001-2009 Apple Inc.,
    Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
    <key>CFBundleIconFile</key>
    <string>Wish.icns</string>
    <key>CFBundleIdentifier</key>
    <string>com.tcltk.wish</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleLocalizations</key>
    <array>
      @CFBUNDLELOCALIZATIONS@
    </array>
    <key>CFBundleName</key>
    <string>Wish</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>@TK_VERSION@@TK_PATCH_LEVEL@</string>
    <key>CFBundleSignature</key>
    <string>WiSH</string>
    <key>CFBundleVersion</key>
    <string>@TK_VERSION@@TK_PATCH_LEVEL@</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.6.0</string>
    <key>LSRequiresCarbon</key>
    <true/>
    <key>NSAppleScriptEnabled</key>
    <true/>
    <key>OSAScriptingDefinition</key>
    <string>Wish.sdef</string>
    <key>NSHighResolutionCapable</key>
    <string>True</string>
    <key>NSServices</key>
    <array>
      <dict>
	<key>NSMessage</key>
	<string>provideService</string>
	<key>NSPortName</key>
	<string>Wish</string>
	<key>NSSendTypes</key>
	<array>
          <string>NSStringPboardType</string>
          <string>NSPasteboardTypeString</string>
	</array>
      </dict>
    </array>
  </dict>
</plist>










|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
>
|
|
<
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38













39
40
41
42
43
44
45
46


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79












80


81
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
	Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
	Copyright 2008-2009, Apple Inc.

	See the file "license.terms" for information on usage and redistribution of
	this file, and for a DISCLAIMER OF ALL WARRANTIES.
-->
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeExtensions</key>
			<array>
				<string>tcl</string>
				<string>TCL</string>
				<string>*</string>
			</array>
			<key>CFBundleTypeMIMETypes</key>
			<array>
				<string>application/x-tcl</string>
				<string>text/plain</string>
			</array>
			<key>CFBundleTypeName</key>
			<string>NSStringPboardType</string>
			<key>CFBundleTypeOSTypes</key>
			<array>
				<string>TEXT</string>
				<string>****</string>
			</array>
			<key>CFBundleTypeRole</key>
			<string>Viewer</string>
		</dict>
	</array>













	<key>CFBundleExecutable</key>
	<string>Wish</string>
	<key>CFBundleGetInfoString</key>
	<string>Wish Shell @TK_VERSION@@TK_PATCH_LEVEL@,
Copyright © 1989-@TK_YEAR@ Tcl Core Team,
Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
	Copyright © 1989-@TK_YEAR@ Contributors,
	Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech


	Communications LLC,
Copyright © 2001-2009 Apple Inc.,
Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
	<key>CFBundleIconFile</key>
	<string>Wish.icns</string>
	<key>CFBundleIdentifier</key>
	<string>com.tcltk.wish</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleLocalizations</key>
	<array>
		@CFBUNDLELOCALIZATIONS@
	</array>
	<key>CFBundleName</key>
	<string>Wish</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>@TK_VERSION@@TK_PATCH_LEVEL@</string>
	<key>CFBundleSignature</key>
	<string>WiSH</string>
	<key>CFBundleVersion</key>
	<string>@TK_VERSION@@TK_PATCH_LEVEL@</string>
	<key>LSMinimumSystemVersion</key>
	<string>10.5.0</string>
	<key>LSRequiresCarbon</key>
	<true/>
	<key>NSAppleScriptEnabled</key>
	<true/>
	<key>OSAScriptingDefinition</key>
	<string>Wish.sdef</string>
	<key>NSHighResolutionCapable</key>
	<string>True</string>












</dict>


</plist>

Added macosx/Wish-Release.xcconfig.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Wish-Release.xcconfig --
//
//	This file contains the Xcode build settings for all Release
//	project configurations in Wish.xcodeproj.
//
// 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.
//

#include "Wish-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
// DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = s
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy

Added macosx/Wish.icns.

cannot compute difference between binary files

Changes to macosx/Wish.sdef.

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
		<command name="quit" code="aevtquit" description="Quit the application."/>
	</suite>
	<suite name="Wish Suite" code="WIsH" description="Commands for the Wish application.">
		<command name="do script" code="miscdosc" description="Execute a Tcl script.">
			<direct-parameter description="Script to execute" type="text">
				<type type="text"/>
			</direct-parameter>
			<result description="Result">
				<type type="text"/>
			</result>
		</command>
			<command name="open location" code="GURLGURL"
				 description="Open a URL.">
			<direct-parameter description="URL" type="text">
				<type type="text"/>
			</direct-parameter>
			<result description="Result">
				<type type="text"/>
			</result>
		</command>
	</suite>
</dictionary>







<
<
<
<
<
<
<
<
<






25
26
27
28
29
30
31









32
33
34
35
36
37
		<command name="quit" code="aevtquit" description="Quit the application."/>
	</suite>
	<suite name="Wish Suite" code="WIsH" description="Commands for the Wish application.">
		<command name="do script" code="miscdosc" description="Execute a Tcl script.">
			<direct-parameter description="Script to execute" type="text">
				<type type="text"/>
			</direct-parameter>









			<result description="Result">
				<type type="text"/>
			</result>
		</command>
	</suite>
</dictionary>

Added macosx/Wish.xcode/default.pbxuser.













































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* Wish */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tk */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
			F944EB8F08F798100049FDD4 /* tktest */,
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f75708692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a0b707265666572656e63657386928497960892849a9a07666e6d617463688692849a9a008692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a0572656765788692849a9a065c2e286329248692849a9a097265637572736976658692848484084e534e756d626572008484074e5356616c7565009584012a849696018692849a9a0669734c656166869284b09db296008692849a9a0763616e536176658692af92849a9a1250425850726f6a65637453636f70654b65798692849a9a03594553868692849a9a08676c6f62616c49448692849a9a18314343304541343030343335304546393030343434313042868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			CODE_SIGN_IDENTITY = "";
			SYMROOT = "${SRCROOT}/../../build/tk";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
			TK_SRCROOT = "${SRCROOT}/../../tk";
		};
	};
	8DD76FA90486AB0100D96B5E /* tktest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tktest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tktest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = TK_SRCROOT;
				value = "${TK_SRCROOT}";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = EventDebug;
				value = 1;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tktest;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F9E61D16090A3E94002B3151 /* Tk */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
		);
	};
	F9E61D1C090A4282002B3151 /* Wish */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = Wish;
		sourceDirectories = (
		);
	};
	F97258A50A86873C00096C78 /* tktest-X11 */ = {
		activeExec = 0;
		executables = (
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
	};
	F9FD31F50CC1AD070073837D /* tktest-X11 */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = DISPLAY;
				value = ":0";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = "tktest-X11";
		sourceDirectories = (
		);
	};
}

Added macosx/Wish.xcode/project.pbxproj.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 45;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F94523A10E6FC2AC00C1D987 /* Cocoa.framework */; };
		F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F966BDD308F27A3F005CB29B /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F966BDD508F27A3F005CB29B /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F966BDE508F27A3F005CB29B /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F966BDED08F27A3F005CB29B /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F966BDF208F27A3F005CB29B /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F966BDF508F27A3F005CB29B /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F966BDF708F27A3F005CB29B /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F966BE0908F27A3F005CB29B /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F966BE1008F27A3F005CB29B /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F966BE1208F27A3F005CB29B /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F966BE1308F27A3F005CB29B /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF408F27A39005CB29B /* tkPointer.c */; };
		F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F966BE2008F27A40005CB29B /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F966BE2408F27A40005CB29B /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F966BE2508F27A40005CB29B /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F966BE2608F27A40005CB29B /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F966BE3008F27A40005CB29B /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F966BE3108F27A40005CB29B /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F966BE3308F27A40005CB29B /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F966BE3408F27A40005CB29B /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F966BE3508F27A40005CB29B /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */; };
		F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */; };
		F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */; };
		F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */; };
		F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */; };
		F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */; };
		F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */; };
		F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */; };
		F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */; };
		F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */; };
		F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */; };
		F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */; };
		F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */; };
		F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */; };
		F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */; settings = {COMPILER_FLAGS = "-DTK_LIBRARY=\\\"$(TK_LIBRARY)\\\""; }; };
		F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */; };
		F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */; };
		F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */; };
		F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */; };
		F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */; };
		F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */; };
		F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */; };
		F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */; };
		F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */; };
		F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */; };
		F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */; };
		F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */; };
		F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */; };
		F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */; };
		F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */; };
		F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F966C02A08F27A42005CB29B /* xcolors.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2408F27A3F005CB29B /* xcolors.c */; };
		F966C02B08F27A42005CB29B /* xdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2508F27A3F005CB29B /* xdraw.c */; };
		F966C02C08F27A42005CB29B /* xgc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2608F27A3F005CB29B /* xgc.c */; };
		F966C02D08F27A42005CB29B /* ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2708F27A3F005CB29B /* ximage.c */; };
		F966C02E08F27A42005CB29B /* xutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2808F27A3F005CB29B /* xutil.c */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07608F2821B005CB29B /* Carbon.framework */; };
		F966C07908F28233005CB29B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07808F28233005CB29B /* IOKit.framework */; };
		F96888050AF786D5000797B5 /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F96888060AF786D5000797B5 /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F96888070AF786D5000797B5 /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F968880B0AF786D5000797B5 /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F968880E0AF786D5000797B5 /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F968880F0AF786D5000797B5 /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F96888100AF786D5000797B5 /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F96888110AF786D5000797B5 /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F96888120AF786D5000797B5 /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F96888150AF786D5000797B5 /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F96888160AF786D5000797B5 /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F96888170AF786D5000797B5 /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F968881B0AF786D5000797B5 /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F96888200AF786D5000797B5 /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F96888210AF786D5000797B5 /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F96888230AF786D5000797B5 /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888840AF78938000797B5 /* ttkMacOSXTheme.c */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F9FD30BD0CC1AD070073837D /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F9FD30BE0CC1AD070073837D /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F9FD30BF0CC1AD070073837D /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F9FD30C50CC1AD070073837D /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F9FD30D50CC1AD070073837D /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F9FD30D60CC1AD070073837D /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F9FD30E00CC1AD070073837D /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F9FD30E40CC1AD070073837D /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F9FD30E70CC1AD070073837D /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F9FD30E90CC1AD070073837D /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F9FD30F00CC1AD070073837D /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F9FD30F30CC1AD070073837D /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F9FD30F40CC1AD070073837D /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F9FD30F90CC1AD070073837D /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F9FD31000CC1AD070073837D /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F9FD31010CC1AD070073837D /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F9FD31020CC1AD070073837D /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F9FD313F0CC1AD070073837D /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9FD314F0CC1AD070073837D /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F9FD31500CC1AD070073837D /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F9FD31510CC1AD070073837D /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F9FD31520CC1AD070073837D /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F9FD31540CC1AD070073837D /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F9FD31600CC1AD070073837D /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F9FD31610CC1AD070073837D /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F9FD31620CC1AD070073837D /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F9FD31630CC1AD070073837D /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F9FD31640CC1AD070073837D /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F9FD31650CC1AD070073837D /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F9FD31660CC1AD070073837D /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F9FD31670CC1AD070073837D /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F9FD31690CC1AD070073837D /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F9FD316A0CC1AD070073837D /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F9FD316C0CC1AD070073837D /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F9FD316E0CC1AD070073837D /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F9FD31700CC1AD070073837D /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F9FD31710CC1AD070073837D /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F9FD31760CC1AD070073837D /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F9FD31880CC1AD070073837D /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F9FD31890CC1AD070073837D /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F9FD318D0CC1AD070073837D /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F9FD318E0CC1AD070073837D /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F9FD31960CC1AD070073837D /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F9FD31970CC1AD070073837D /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F9FD31980CC1AD070073837D /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F9FD31990CC1AD070073837D /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F9FD31B10CC1AD070073837D /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */; };
		F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8708F27A3D005CB29B /* tkUnixKey.c */; };
		F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9108F27A3D005CB29B /* tkUnixXId.c */; };
		F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8508F27A3D005CB29B /* tkUnixInit.c */; };
		F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */; };
		F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8F08F27A3D005CB29B /* tkUnixSend.c */; };
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
		F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32150CC1AF170073837D /* libXext.dylib */; };
		F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32160CC1AF170073837D /* libXss.dylib */; };
		F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34990CC1BB0D0073837D /* libfreetype.dylib */; };
		F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD349A0CC1BB0D0073837D /* libXft.dylib */; };
		F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tktest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tktest; sourceTree = BUILT_PRODUCTS_DIR; };
		F9099B8A0CC67D30005A9580 /* textpeer.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textpeer.tcl; sourceTree = "<group>"; };
		F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkbut.tcl; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92240290D7C620F005EC715 /* knightstour.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = knightstour.tcl; sourceTree = "<group>"; };
		F936FCD70CCD984500716967 /* ttkprogress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkprogress.tcl; sourceTree = "<group>"; };
		F936FCD80CCD984600716967 /* tree.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tree.tcl; sourceTree = "<group>"; };
		F936FCD90CCD984600716967 /* toolbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = toolbar.tcl; sourceTree = "<group>"; };
		F936FCDA0CCD984600716967 /* ttknote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttknote.tcl; sourceTree = "<group>"; };
		F936FCDB0CCD984600716967 /* combo.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combo.tcl; sourceTree = "<group>"; };
		F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXFont.h; sourceTree = "<group>"; };
		F94523A10E6FC2AC00C1D987 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
		F95D8D4B0F1715610006B020 /* Tk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Tk.icns; sourceTree = "<group>"; };
		F95D8D4C0F1715610006B020 /* Tk.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Tk.tiff; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F962F7C60DADC26200648DB8 /* vsapi.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vsapi.test; sourceTree = "<group>"; };
		F966BA0408F27A37005CB29B /* error.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = error.xbm; sourceTree = "<group>"; };
		F966BA0508F27A37005CB29B /* gray12.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray12.xbm; sourceTree = "<group>"; };
		F966BA0608F27A37005CB29B /* gray25.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray25.xbm; sourceTree = "<group>"; };
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
		F966BA1808F27A37005CB29B /* button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = button.n; sourceTree = "<group>"; };
		F966BA1908F27A37005CB29B /* canvas.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = canvas.n; sourceTree = "<group>"; };
		F966BA1A08F27A37005CB29B /* CanvPsY.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvPsY.3; sourceTree = "<group>"; };
		F966BA1B08F27A37005CB29B /* CanvTkwin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTkwin.3; sourceTree = "<group>"; };
		F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTxtInfo.3; sourceTree = "<group>"; };
		F966BA1D08F27A37005CB29B /* checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = checkbutton.n; sourceTree = "<group>"; };
		F966BA1E08F27A37005CB29B /* chooseColor.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseColor.n; sourceTree = "<group>"; };
		F966BA1F08F27A37005CB29B /* chooseDirectory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseDirectory.n; sourceTree = "<group>"; };
		F966BA2008F27A37005CB29B /* Clipboard.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Clipboard.3; sourceTree = "<group>"; };
		F966BA2108F27A37005CB29B /* clipboard.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clipboard.n; sourceTree = "<group>"; };
		F966BA2208F27A37005CB29B /* ClrSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ClrSelect.3; sourceTree = "<group>"; };
		F966BA2308F27A37005CB29B /* colors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = colors.n; sourceTree = "<group>"; };
		F966BA2408F27A37005CB29B /* ConfigWidg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWidg.3; sourceTree = "<group>"; };
		F966BA2508F27A37005CB29B /* ConfigWind.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWind.3; sourceTree = "<group>"; };
		F966BA2608F27A37005CB29B /* console.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = console.n; sourceTree = "<group>"; };
		F966BA2708F27A37005CB29B /* CoordToWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CoordToWin.3; sourceTree = "<group>"; };
		F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCmHdlr.3; sourceTree = "<group>"; };
		F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtErrHdlr.3; sourceTree = "<group>"; };
		F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtGenHdlr.3; sourceTree = "<group>"; };
		F966BA2B08F27A37005CB29B /* CrtImgType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtImgType.3; sourceTree = "<group>"; };
		F966BA2C08F27A37005CB29B /* CrtItemType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtItemType.3; sourceTree = "<group>"; };
		F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtPhImgFmt.3; sourceTree = "<group>"; };
		F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSelHdlr.3; sourceTree = "<group>"; };
		F966BA2F08F27A37005CB29B /* CrtWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtWindow.3; sourceTree = "<group>"; };
		F966BA3008F27A37005CB29B /* cursors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cursors.n; sourceTree = "<group>"; };
		F966BA3108F27A37005CB29B /* DeleteImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DeleteImg.3; sourceTree = "<group>"; };
		F966BA3208F27A37005CB29B /* destroy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = destroy.n; sourceTree = "<group>"; };
		F966BA3308F27A37005CB29B /* dialog.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dialog.n; sourceTree = "<group>"; };
		F966BA3408F27A37005CB29B /* DrawFocHlt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DrawFocHlt.3; sourceTree = "<group>"; };
		F966BA3508F27A37005CB29B /* entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = entry.n; sourceTree = "<group>"; };
		F966BA3608F27A37005CB29B /* event.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = event.n; sourceTree = "<group>"; };
		F966BA3708F27A37005CB29B /* EventHndlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = EventHndlr.3; sourceTree = "<group>"; };
		F966BA3808F27A37005CB29B /* FindPhoto.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindPhoto.3; sourceTree = "<group>"; };
		F966BA3908F27A37005CB29B /* focus.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focus.n; sourceTree = "<group>"; };
		F966BA3A08F27A37005CB29B /* focusNext.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focusNext.n; sourceTree = "<group>"; };
		F966BA3B08F27A37005CB29B /* font.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = font.n; sourceTree = "<group>"; };
		F966BA3C08F27A37005CB29B /* FontId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FontId.3; sourceTree = "<group>"; };
		F966BA3D08F27A37005CB29B /* frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = frame.n; sourceTree = "<group>"; };
		F966BA3E08F27A37005CB29B /* FreeXId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FreeXId.3; sourceTree = "<group>"; };
		F966BA3F08F27A37005CB29B /* GeomReq.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GeomReq.3; sourceTree = "<group>"; };
		F966BA4008F27A37005CB29B /* GetAnchor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetAnchor.3; sourceTree = "<group>"; };
		F966BA4108F27A37005CB29B /* GetBitmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetBitmap.3; sourceTree = "<group>"; };
		F966BA4208F27A37005CB29B /* GetCapStyl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCapStyl.3; sourceTree = "<group>"; };
		F966BA4308F27A37005CB29B /* GetClrmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetClrmap.3; sourceTree = "<group>"; };
		F966BA4408F27A37005CB29B /* GetColor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetColor.3; sourceTree = "<group>"; };
		F966BA4508F27A37005CB29B /* GetCursor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCursor.3; sourceTree = "<group>"; };
		F966BA4608F27A37005CB29B /* GetDash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetDash.3; sourceTree = "<group>"; };
		F966BA4708F27A37005CB29B /* GetFont.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetFont.3; sourceTree = "<group>"; };
		F966BA4808F27A37005CB29B /* GetGC.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetGC.3; sourceTree = "<group>"; };
		F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHINSTANCE.3; sourceTree = "<group>"; };
		F966BA4A08F27A37005CB29B /* GetHWND.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHWND.3; sourceTree = "<group>"; };
		F966BA4B08F27A37005CB29B /* GetImage.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetImage.3; sourceTree = "<group>"; };
		F966BA4C08F27A37005CB29B /* GetJoinStl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJoinStl.3; sourceTree = "<group>"; };
		F966BA4D08F27A37005CB29B /* GetJustify.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJustify.3; sourceTree = "<group>"; };
		F966BA4E08F27A37005CB29B /* getOpenFile.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = getOpenFile.n; sourceTree = "<group>"; };
		F966BA4F08F27A37005CB29B /* GetOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOption.3; sourceTree = "<group>"; };
		F966BA5008F27A38005CB29B /* GetPixels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixels.3; sourceTree = "<group>"; };
		F966BA5108F27A38005CB29B /* GetPixmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixmap.3; sourceTree = "<group>"; };
		F966BA5208F27A38005CB29B /* GetRelief.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRelief.3; sourceTree = "<group>"; };
		F966BA5308F27A38005CB29B /* GetRootCrd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRootCrd.3; sourceTree = "<group>"; };
		F966BA5408F27A38005CB29B /* GetScroll.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetScroll.3; sourceTree = "<group>"; };
		F966BA5508F27A38005CB29B /* GetSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetSelect.3; sourceTree = "<group>"; };
		F966BA5608F27A38005CB29B /* GetUid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetUid.3; sourceTree = "<group>"; };
		F966BA5708F27A38005CB29B /* GetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVisual.3; sourceTree = "<group>"; };
		F966BA5808F27A38005CB29B /* GetVRoot.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVRoot.3; sourceTree = "<group>"; };
		F966BA5908F27A38005CB29B /* Grab.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Grab.3; sourceTree = "<group>"; };
		F966BA5A08F27A38005CB29B /* grab.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grab.n; sourceTree = "<group>"; };
		F966BA5B08F27A38005CB29B /* grid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grid.n; sourceTree = "<group>"; };
		F966BA5C08F27A38005CB29B /* HandleEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HandleEvent.3; sourceTree = "<group>"; };
		F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HWNDToWindow.3; sourceTree = "<group>"; };
		F966BA5E08F27A38005CB29B /* IdToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IdToWindow.3; sourceTree = "<group>"; };
		F966BA5F08F27A38005CB29B /* image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = image.n; sourceTree = "<group>"; };
		F966BA6008F27A38005CB29B /* ImgChanged.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ImgChanged.3; sourceTree = "<group>"; };
		F966BA6108F27A38005CB29B /* Inactive.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Inactive.3; sourceTree = "<group>"; };
		F966BA6208F27A38005CB29B /* InternAtom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InternAtom.3; sourceTree = "<group>"; };
		F966BA6308F27A38005CB29B /* keysyms.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = keysyms.n; sourceTree = "<group>"; };
		F966BA6408F27A38005CB29B /* label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = label.n; sourceTree = "<group>"; };
		F966BA6508F27A38005CB29B /* labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = labelframe.n; sourceTree = "<group>"; };
		F966BA6608F27A38005CB29B /* listbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = listbox.n; sourceTree = "<group>"; };
		F966BA6708F27A38005CB29B /* loadTk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = loadTk.n; sourceTree = "<group>"; };
		F966BA6808F27A38005CB29B /* lower.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lower.n; sourceTree = "<group>"; };
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
		F966BA8408F27A38005CB29B /* QWinEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = QWinEvent.3; sourceTree = "<group>"; };
		F966BA8508F27A38005CB29B /* radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = radiobutton.n; sourceTree = "<group>"; };
		F966BA8608F27A38005CB29B /* raise.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = raise.n; sourceTree = "<group>"; };
		F966BA8708F27A38005CB29B /* Restack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Restack.3; sourceTree = "<group>"; };
		F966BA8808F27A38005CB29B /* RestrictEv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RestrictEv.3; sourceTree = "<group>"; };
		F966BA8908F27A38005CB29B /* scale.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scale.n; sourceTree = "<group>"; };
		F966BA8A08F27A38005CB29B /* scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scrollbar.n; sourceTree = "<group>"; };
		F966BA8B08F27A38005CB29B /* selection.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = selection.n; sourceTree = "<group>"; };
		F966BA8C08F27A38005CB29B /* send.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = send.n; sourceTree = "<group>"; };
		F966BA8D08F27A38005CB29B /* SetAppName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetAppName.3; sourceTree = "<group>"; };
		F966BA8E08F27A38005CB29B /* SetCaret.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetCaret.3; sourceTree = "<group>"; };
		F966BA8F08F27A38005CB29B /* SetClass.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClass.3; sourceTree = "<group>"; };
		F966BA9008F27A38005CB29B /* SetClassProcs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClassProcs.3; sourceTree = "<group>"; };
		F966BA9108F27A38005CB29B /* SetGrid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetGrid.3; sourceTree = "<group>"; };
		F966BA9208F27A38005CB29B /* SetOptions.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetOptions.3; sourceTree = "<group>"; };
		F966BA9308F27A38005CB29B /* SetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVisual.3; sourceTree = "<group>"; };
		F966BA9408F27A38005CB29B /* spinbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = spinbox.n; sourceTree = "<group>"; };
		F966BA9508F27A38005CB29B /* StrictMotif.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrictMotif.3; sourceTree = "<group>"; };
		F966BA9608F27A38005CB29B /* text.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = text.n; sourceTree = "<group>"; };
		F966BA9708F27A38005CB29B /* TextLayout.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TextLayout.3; sourceTree = "<group>"; };
		F966BA9808F27A38005CB29B /* tk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tk.n; sourceTree = "<group>"; };
		F966BA9908F27A38005CB29B /* tk4.0.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = tk4.0.ps; sourceTree = "<group>"; };
		F966BA9A08F27A38005CB29B /* Tk_Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Init.3; sourceTree = "<group>"; };
		F966BA9B08F27A38005CB29B /* Tk_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Main.3; sourceTree = "<group>"; };
		F966BA9C08F27A38005CB29B /* tkerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkerror.n; sourceTree = "<group>"; };
		F966BA9D08F27A38005CB29B /* TkInitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TkInitStubs.3; sourceTree = "<group>"; };
		F966BA9E08F27A38005CB29B /* tkvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkvars.n; sourceTree = "<group>"; };
		F966BA9F08F27A38005CB29B /* tkwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkwait.n; sourceTree = "<group>"; };
		F966BAA008F27A38005CB29B /* toplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = toplevel.n; sourceTree = "<group>"; };
		F966BAA108F27A38005CB29B /* WindowId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WindowId.3; sourceTree = "<group>"; };
		F966BAA208F27A38005CB29B /* winfo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = winfo.n; sourceTree = "<group>"; };
		F966BAA308F27A38005CB29B /* wish.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wish.1; sourceTree = "<group>"; };
		F966BAA408F27A38005CB29B /* wm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wm.n; sourceTree = "<group>"; };
		F966BAA608F27A38005CB29B /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = "<group>"; };
		F966BAA708F27A38005CB29B /* ks_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ks_names.h; sourceTree = "<group>"; };
		F966BAA808F27A38005CB29B /* prolog.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = prolog.ps; sourceTree = "<group>"; };
		F966BAA908F27A39005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BAAA08F27A39005CB29B /* tk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.decls; sourceTree = "<group>"; };
		F966BAAB08F27A39005CB29B /* tk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk.h; sourceTree = "<group>"; };
		F966BAAC08F27A39005CB29B /* tk3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tk3d.c; sourceTree = "<group>"; };
		F966BAAD08F27A39005CB29B /* tk3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk3d.h; sourceTree = "<group>"; };
		F966BAAE08F27A39005CB29B /* tkArgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkArgv.c; sourceTree = "<group>"; };
		F966BAAF08F27A39005CB29B /* tkAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAtom.c; sourceTree = "<group>"; };
		F966BAB008F27A39005CB29B /* tkBind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBind.c; sourceTree = "<group>"; };
		F966BAB108F27A39005CB29B /* tkBitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBitmap.c; sourceTree = "<group>"; };
		F966BAB208F27A39005CB29B /* tkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkButton.c; sourceTree = "<group>"; };
		F966BAB308F27A39005CB29B /* tkButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkButton.h; sourceTree = "<group>"; };
		F966BAB408F27A39005CB29B /* tkCanvArc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvArc.c; sourceTree = "<group>"; };
		F966BAB508F27A39005CB29B /* tkCanvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvas.c; sourceTree = "<group>"; };
		F966BAB608F27A39005CB29B /* tkCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkCanvas.h; sourceTree = "<group>"; };
		F966BAB708F27A39005CB29B /* tkCanvBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvBmap.c; sourceTree = "<group>"; };
		F966BAB808F27A39005CB29B /* tkCanvImg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvImg.c; sourceTree = "<group>"; };
		F966BAB908F27A39005CB29B /* tkCanvLine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvLine.c; sourceTree = "<group>"; };
		F966BABA08F27A39005CB29B /* tkCanvPoly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPoly.c; sourceTree = "<group>"; };
		F966BABB08F27A39005CB29B /* tkCanvPs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPs.c; sourceTree = "<group>"; };
		F966BABD08F27A39005CB29B /* tkCanvText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvText.c; sourceTree = "<group>"; };
		F966BABE08F27A39005CB29B /* tkCanvUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvUtil.c; sourceTree = "<group>"; };
		F966BABF08F27A39005CB29B /* tkCanvWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvWind.c; sourceTree = "<group>"; };
		F966BAC008F27A39005CB29B /* tkClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkClipboard.c; sourceTree = "<group>"; };
		F966BAC108F27A39005CB29B /* tkCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCmds.c; sourceTree = "<group>"; };
		F966BAC208F27A39005CB29B /* tkColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkColor.c; sourceTree = "<group>"; };
		F966BAC308F27A39005CB29B /* tkColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkColor.h; sourceTree = "<group>"; };
		F966BAC408F27A39005CB29B /* tkConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConfig.c; sourceTree = "<group>"; };
		F966BAC508F27A39005CB29B /* tkConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConsole.c; sourceTree = "<group>"; };
		F966BAC608F27A39005CB29B /* tkCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCursor.c; sourceTree = "<group>"; };
		F966BAC708F27A39005CB29B /* tkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkDecls.h; sourceTree = "<group>"; };
		F966BAC808F27A39005CB29B /* tkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEntry.c; sourceTree = "<group>"; };
		F966BAC908F27A39005CB29B /* tkEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkEntry.h; sourceTree = "<group>"; };
		F966BACA08F27A39005CB29B /* tkError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkError.c; sourceTree = "<group>"; };
		F966BACB08F27A39005CB29B /* tkEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEvent.c; sourceTree = "<group>"; };
		F966BACC08F27A39005CB29B /* tkFileFilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFileFilter.c; sourceTree = "<group>"; };
		F966BACD08F27A39005CB29B /* tkFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFileFilter.h; sourceTree = "<group>"; };
		F966BACE08F27A39005CB29B /* tkFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFocus.c; sourceTree = "<group>"; };
		F966BACF08F27A39005CB29B /* tkFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFont.c; sourceTree = "<group>"; };
		F966BAD008F27A39005CB29B /* tkFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFont.h; sourceTree = "<group>"; };
		F966BAD108F27A39005CB29B /* tkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFrame.c; sourceTree = "<group>"; };
		F966BAD208F27A39005CB29B /* tkGC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGC.c; sourceTree = "<group>"; };
		F966BAD308F27A39005CB29B /* tkGeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGeometry.c; sourceTree = "<group>"; };
		F966BAD408F27A39005CB29B /* tkGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGet.c; sourceTree = "<group>"; };
		F966BAD508F27A39005CB29B /* tkGrab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrab.c; sourceTree = "<group>"; };
		F966BAD608F27A39005CB29B /* tkGrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrid.c; sourceTree = "<group>"; };
		F966BAD708F27A39005CB29B /* tkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImage.c; sourceTree = "<group>"; };
		F966BAD808F27A39005CB29B /* tkImgBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgBmap.c; sourceTree = "<group>"; };
		F966BAD908F27A39005CB29B /* tkImgGIF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgGIF.c; sourceTree = "<group>"; };
		F966BADA08F27A39005CB29B /* tkImgPhoto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhoto.c; sourceTree = "<group>"; };
		F966BADB08F27A39005CB29B /* tkImgPPM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPPM.c; sourceTree = "<group>"; };
		F966BADC08F27A39005CB29B /* tkImgUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgUtil.c; sourceTree = "<group>"; };
		F966BADE08F27A39005CB29B /* tkInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkInt.decls; sourceTree = "<group>"; };
		F966BADF08F27A39005CB29B /* tkInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkInt.h; sourceTree = "<group>"; };
		F966BAE108F27A39005CB29B /* tkIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntDecls.h; sourceTree = "<group>"; };
		F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntPlatDecls.h; sourceTree = "<group>"; };
		F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntXlibDecls.h; sourceTree = "<group>"; };
		F966BAE408F27A39005CB29B /* tkListbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkListbox.c; sourceTree = "<group>"; };
		F966BAE508F27A39005CB29B /* tkMacWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacWinMenu.c; sourceTree = "<group>"; };
		F966BAE608F27A39005CB29B /* tkMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMain.c; sourceTree = "<group>"; };
		F966BAE708F27A39005CB29B /* tkMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenu.c; sourceTree = "<group>"; };
		F966BAE808F27A39005CB29B /* tkMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenu.h; sourceTree = "<group>"; };
		F966BAE908F27A39005CB29B /* tkMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenubutton.c; sourceTree = "<group>"; };
		F966BAEA08F27A39005CB29B /* tkMenubutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenubutton.h; sourceTree = "<group>"; };
		F966BAEB08F27A39005CB29B /* tkMenuDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenuDraw.c; sourceTree = "<group>"; };
		F966BAEC08F27A39005CB29B /* tkMessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMessage.c; sourceTree = "<group>"; };
		F966BAED08F27A39005CB29B /* tkObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkObj.c; sourceTree = "<group>"; };
		F966BAEE08F27A39005CB29B /* tkOldConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldConfig.c; sourceTree = "<group>"; };
		F966BAEF08F27A39005CB29B /* tkOption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOption.c; sourceTree = "<group>"; };
		F966BAF008F27A39005CB29B /* tkPack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPack.c; sourceTree = "<group>"; };
		F966BAF108F27A39005CB29B /* tkPanedWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPanedWindow.c; sourceTree = "<group>"; };
		F966BAF208F27A39005CB29B /* tkPlace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPlace.c; sourceTree = "<group>"; };
		F966BAF308F27A39005CB29B /* tkPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPlatDecls.h; sourceTree = "<group>"; };
		F966BAF408F27A39005CB29B /* tkPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPointer.c; sourceTree = "<group>"; };
		F966BAF508F27A39005CB29B /* tkPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPort.h; sourceTree = "<group>"; };
		F966BAF608F27A39005CB29B /* tkRectOval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkRectOval.c; sourceTree = "<group>"; };
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
		F966BB0608F27A39005CB29B /* tkTextDisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextDisp.c; sourceTree = "<group>"; };
		F966BB0808F27A39005CB29B /* tkTextImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextImage.c; sourceTree = "<group>"; };
		F966BB0908F27A39005CB29B /* tkTextIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextIndex.c; sourceTree = "<group>"; };
		F966BB0A08F27A39005CB29B /* tkTextMark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextMark.c; sourceTree = "<group>"; };
		F966BB0B08F27A39005CB29B /* tkTextTag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextTag.c; sourceTree = "<group>"; };
		F966BB0C08F27A39005CB29B /* tkTextWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextWind.c; sourceTree = "<group>"; };
		F966BB0D08F27A39005CB29B /* tkTrig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTrig.c; sourceTree = "<group>"; };
		F966BB0E08F27A39005CB29B /* tkUndo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUndo.c; sourceTree = "<group>"; };
		F966BB0F08F27A39005CB29B /* tkUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUndo.h; sourceTree = "<group>"; };
		F966BB1008F27A39005CB29B /* tkUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUtil.c; sourceTree = "<group>"; };
		F966BB1108F27A39005CB29B /* tkVisual.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkVisual.c; sourceTree = "<group>"; };
		F966BB1208F27A39005CB29B /* tkWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWindow.c; sourceTree = "<group>"; };
		F966BB1408F27A39005CB29B /* bgerror.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.tcl; sourceTree = "<group>"; };
		F966BB1508F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB1608F27A39005CB29B /* choosedir.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.tcl; sourceTree = "<group>"; };
		F966BB1708F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB1808F27A39005CB29B /* comdlg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = comdlg.tcl; sourceTree = "<group>"; };
		F966BB1908F27A39005CB29B /* console.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = console.tcl; sourceTree = "<group>"; };
		F966BB1B08F27A39005CB29B /* anilabel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = anilabel.tcl; sourceTree = "<group>"; };
		F966BB1C08F27A39005CB29B /* aniwave.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aniwave.tcl; sourceTree = "<group>"; };
		F966BB1D08F27A39005CB29B /* arrow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arrow.tcl; sourceTree = "<group>"; };
		F966BB1E08F27A39005CB29B /* bind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.tcl; sourceTree = "<group>"; };
		F966BB1F08F27A39005CB29B /* bitmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.tcl; sourceTree = "<group>"; };
		F966BB2008F27A39005CB29B /* browse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = browse; sourceTree = "<group>"; };
		F966BB2108F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB2208F27A39005CB29B /* check.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = check.tcl; sourceTree = "<group>"; };
		F966BB2308F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB2408F27A39005CB29B /* colors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = colors.tcl; sourceTree = "<group>"; };
		F966BB2508F27A39005CB29B /* cscroll.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cscroll.tcl; sourceTree = "<group>"; };
		F966BB2608F27A39005CB29B /* ctext.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ctext.tcl; sourceTree = "<group>"; };
		F966BB2708F27A39005CB29B /* dialog1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog1.tcl; sourceTree = "<group>"; };
		F966BB2808F27A39005CB29B /* dialog2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog2.tcl; sourceTree = "<group>"; };
		F966BB2A08F27A39005CB29B /* entry1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry1.tcl; sourceTree = "<group>"; };
		F966BB2B08F27A39005CB29B /* entry2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry2.tcl; sourceTree = "<group>"; };
		F966BB2C08F27A39005CB29B /* entry3.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry3.tcl; sourceTree = "<group>"; };
		F966BB2D08F27A39005CB29B /* filebox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.tcl; sourceTree = "<group>"; };
		F966BB2E08F27A39005CB29B /* floor.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = floor.tcl; sourceTree = "<group>"; };
		F966BB2F08F27A39005CB29B /* form.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = form.tcl; sourceTree = "<group>"; };
		F966BB3008F27A39005CB29B /* goldberg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = goldberg.tcl; sourceTree = "<group>"; };
		F966BB3108F27A39005CB29B /* hello */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = hello; sourceTree = "<group>"; };
		F966BB3208F27A39005CB29B /* hscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = hscale.tcl; sourceTree = "<group>"; };
		F966BB3308F27A39005CB29B /* icon.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icon.tcl; sourceTree = "<group>"; };
		F966BB3408F27A39005CB29B /* image1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image1.tcl; sourceTree = "<group>"; };
		F966BB3508F27A39005CB29B /* image2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image2.tcl; sourceTree = "<group>"; };
		F966BB4208F27A3A005CB29B /* items.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = items.tcl; sourceTree = "<group>"; };
		F966BB4308F27A3A005CB29B /* ixset */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ixset; sourceTree = "<group>"; };
		F966BB4408F27A3A005CB29B /* label.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = label.tcl; sourceTree = "<group>"; };
		F966BB4508F27A3A005CB29B /* labelframe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.tcl; sourceTree = "<group>"; };
		F966BB4608F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB4708F27A3A005CB29B /* menubu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubu.tcl; sourceTree = "<group>"; };
		F966BB4808F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB4A08F27A3A005CB29B /* paned1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned1.tcl; sourceTree = "<group>"; };
		F966BB4B08F27A3A005CB29B /* paned2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned2.tcl; sourceTree = "<group>"; };
		F966BB4C08F27A3A005CB29B /* pendulum.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pendulum.tcl; sourceTree = "<group>"; };
		F966BB4D08F27A3A005CB29B /* plot.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = plot.tcl; sourceTree = "<group>"; };
		F966BB4E08F27A3A005CB29B /* puzzle.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = puzzle.tcl; sourceTree = "<group>"; };
		F966BB4F08F27A3A005CB29B /* radio.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radio.tcl; sourceTree = "<group>"; };
		F966BB5008F27A3A005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BB5108F27A3A005CB29B /* rmt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rmt; sourceTree = "<group>"; };
		F966BB5208F27A3A005CB29B /* rolodex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rolodex; sourceTree = "<group>"; };
		F966BB5308F27A3A005CB29B /* ruler.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ruler.tcl; sourceTree = "<group>"; };
		F966BB5408F27A3A005CB29B /* sayings.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sayings.tcl; sourceTree = "<group>"; };
		F966BB5508F27A3A005CB29B /* search.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = search.tcl; sourceTree = "<group>"; };
		F966BB5608F27A3A005CB29B /* spin.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spin.tcl; sourceTree = "<group>"; };
		F966BB5708F27A3A005CB29B /* square */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = square; sourceTree = "<group>"; };
		F966BB5808F27A3A005CB29B /* states.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = states.tcl; sourceTree = "<group>"; };
		F966BB5908F27A3A005CB29B /* style.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = style.tcl; sourceTree = "<group>"; };
		F966BB5A08F27A3A005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB5B08F27A3A005CB29B /* tcolor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tcolor; sourceTree = "<group>"; };
		F966BB5C08F27A3A005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB5D08F27A3A005CB29B /* timer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = timer; sourceTree = "<group>"; };
		F966BB5E08F27A3A005CB29B /* twind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = twind.tcl; sourceTree = "<group>"; };
		F966BB5F08F27A3A005CB29B /* unicodeout.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unicodeout.tcl; sourceTree = "<group>"; };
		F966BB6008F27A3A005CB29B /* vscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vscale.tcl; sourceTree = "<group>"; };
		F966BB6108F27A3A005CB29B /* widget */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = widget; sourceTree = "<group>"; };
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8A08F27A3B005CB29B /* prolog.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = prolog.ps; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
		F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXBitmap.c; sourceTree = "<group>"; };
		F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXButton.c; sourceTree = "<group>"; };
		F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXClipboard.c; sourceTree = "<group>"; };
		F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXColor.c; sourceTree = "<group>"; };
		F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXConfig.c; sourceTree = "<group>"; };
		F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXCursor.c; sourceTree = "<group>"; };
		F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXCursors.h; sourceTree = "<group>"; };
		F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDebug.c; sourceTree = "<group>"; };
		F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDebug.h; sourceTree = "<group>"; };
		F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDefault.h; sourceTree = "<group>"; };
		F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDialog.c; sourceTree = "<group>"; };
		F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDraw.c; sourceTree = "<group>"; };
		F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEmbed.c; sourceTree = "<group>"; };
		F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEntry.c; sourceTree = "<group>"; };
		F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEvent.c; sourceTree = "<group>"; };
		F966BBD508F27A3B005CB29B /* tkMacOSXEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXEvent.h; sourceTree = "<group>"; };
		F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXFont.c; sourceTree = "<group>"; };
		F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXHLEvents.c; sourceTree = "<group>"; };
		F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXInit.c; sourceTree = "<group>"; };
		F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXInt.h; sourceTree = "<group>"; };
		F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; };
		F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; };
		F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenu.c; sourceTree = "<group>"; };
		F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; };
		F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenus.c; sourceTree = "<group>"; };
		F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; };
		F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXNotify.c; sourceTree = "<group>"; };
		F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPort.h; sourceTree = "<group>"; };
		F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXRegion.c; sourceTree = "<group>"; };
		F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScale.c; sourceTree = "<group>"; };
		F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScrlbr.c; sourceTree = "<group>"; };
		F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSend.c; sourceTree = "<group>"; };
		F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSubwindows.c; sourceTree = "<group>"; };
		F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXTest.c; sourceTree = "<group>"; };
		F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWindowEvent.c; sourceTree = "<group>"; };
		F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWm.c; sourceTree = "<group>"; };
		F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXWm.h; sourceTree = "<group>"; };
		F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXXCursors.h; sourceTree = "<group>"; };
		F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXXStubs.c; sourceTree = "<group>"; };
		F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Wish-Info.plist.in"; sourceTree = "<group>"; };
		F966BC0308F27A3C005CB29B /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F966BC0508F27A3C005CB29B /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F966BC0608F27A3C005CB29B /* arc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arc.tcl; sourceTree = "<group>"; };
		F966BC0708F27A3C005CB29B /* bell.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bell.test; sourceTree = "<group>"; };
		F966BC0808F27A3C005CB29B /* bevel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bevel.tcl; sourceTree = "<group>"; };
		F966BC0908F27A3C005CB29B /* bgerror.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.test; sourceTree = "<group>"; };
		F966BC0A08F27A3C005CB29B /* bind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.test; sourceTree = "<group>"; };
		F966BC0B08F27A3C005CB29B /* bitmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.test; sourceTree = "<group>"; };
		F966BC0C08F27A3C005CB29B /* border.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = border.test; sourceTree = "<group>"; };
		F966BC0D08F27A3C005CB29B /* bugs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bugs.tcl; sourceTree = "<group>"; };
		F966BC0E08F27A3C005CB29B /* butGeom.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom.tcl; sourceTree = "<group>"; };
		F966BC0F08F27A3C005CB29B /* butGeom2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom2.tcl; sourceTree = "<group>"; };
		F966BC1008F27A3C005CB29B /* button.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.test; sourceTree = "<group>"; };
		F966BC1108F27A3C005CB29B /* canvas.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvas.test; sourceTree = "<group>"; };
		F966BC1208F27A3C005CB29B /* canvImg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvImg.test; sourceTree = "<group>"; };
		F966BC1308F27A3C005CB29B /* canvPs.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPs.test; sourceTree = "<group>"; };
		F966BC1408F27A3C005CB29B /* canvPsArc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsArc.tcl; sourceTree = "<group>"; };
		F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsBmap.tcl; sourceTree = "<group>"; };
		F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsGrph.tcl; sourceTree = "<group>"; };
		F966BC1708F27A3C005CB29B /* canvPsImg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsImg.tcl; sourceTree = "<group>"; };
		F966BC1808F27A3C005CB29B /* canvPsText.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsText.tcl; sourceTree = "<group>"; };
		F966BC1908F27A3C005CB29B /* canvRect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvRect.test; sourceTree = "<group>"; };
		F966BC1A08F27A3C005CB29B /* canvText.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvText.test; sourceTree = "<group>"; };
		F966BC1B08F27A3C005CB29B /* canvWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvWind.test; sourceTree = "<group>"; };
		F966BC1C08F27A3C005CB29B /* choosedir.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.test; sourceTree = "<group>"; };
		F966BC1D08F27A3C005CB29B /* clipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clipboard.test; sourceTree = "<group>"; };
		F966BC1E08F27A3C005CB29B /* clrpick.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.test; sourceTree = "<group>"; };
		F966BC1F08F27A3C005CB29B /* cmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmap.tcl; sourceTree = "<group>"; };
		F966BC2008F27A3C005CB29B /* cmds.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmds.test; sourceTree = "<group>"; };
		F966BC2108F27A3C005CB29B /* color.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = color.test; sourceTree = "<group>"; };
		F966BC2208F27A3C005CB29B /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F966BC2308F27A3C005CB29B /* constraints.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = constraints.tcl; sourceTree = "<group>"; };
		F966BC2408F27A3C005CB29B /* cursor.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursor.test; sourceTree = "<group>"; };
		F966BC2508F27A3C005CB29B /* dialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.test; sourceTree = "<group>"; };
		F966BC2608F27A3C005CB29B /* embed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = embed.test; sourceTree = "<group>"; };
		F966BC2708F27A3C005CB29B /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F966BC2808F27A3C005CB29B /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F966BC2908F27A3C005CB29B /* filebox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.test; sourceTree = "<group>"; };
		F966BC2A08F27A3C005CB29B /* focus.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.test; sourceTree = "<group>"; };
		F966BC2B08F27A3C005CB29B /* focusTcl.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focusTcl.test; sourceTree = "<group>"; };
		F966BC2C08F27A3C005CB29B /* font.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = font.test; sourceTree = "<group>"; };
		F966BC2D08F27A3C005CB29B /* frame.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = frame.test; sourceTree = "<group>"; };
		F966BC2E08F27A3C005CB29B /* geometry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = geometry.test; sourceTree = "<group>"; };
		F966BC2F08F27A3C005CB29B /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F966BC3008F27A3C005CB29B /* grab.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grab.test; sourceTree = "<group>"; };
		F966BC3108F27A3C005CB29B /* grid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grid.test; sourceTree = "<group>"; };
		F966BC3208F27A3C005CB29B /* id.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = id.test; sourceTree = "<group>"; };
		F966BC3308F27A3C005CB29B /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F966BC3408F27A3C005CB29B /* imgBmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgBmap.test; sourceTree = "<group>"; };
		F966BC3508F27A3C005CB29B /* imgPhoto.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPhoto.test; sourceTree = "<group>"; };
		F966BC3608F27A3C005CB29B /* imgPPM.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPPM.test; sourceTree = "<group>"; };
		F966BC3708F27A3C005CB29B /* listbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.test; sourceTree = "<group>"; };
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
		F966BC4708F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC4808F27A3D005CB29B /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F966BC4908F27A3D005CB29B /* scale.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.test; sourceTree = "<group>"; };
		F966BC4A08F27A3D005CB29B /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F966BC4B08F27A3D005CB29B /* select.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = select.test; sourceTree = "<group>"; };
		F966BC4C08F27A3D005CB29B /* send.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = send.test; sourceTree = "<group>"; };
		F966BC4D08F27A3D005CB29B /* spinbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.test; sourceTree = "<group>"; };
		F966BC4E08F27A3D005CB29B /* text.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.test; sourceTree = "<group>"; };
		F966BC4F08F27A3D005CB29B /* textBTree.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textBTree.test; sourceTree = "<group>"; };
		F966BC5008F27A3D005CB29B /* textDisp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textDisp.test; sourceTree = "<group>"; };
		F966BC5108F27A3D005CB29B /* textImage.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textImage.test; sourceTree = "<group>"; };
		F966BC5208F27A3D005CB29B /* textIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textIndex.test; sourceTree = "<group>"; };
		F966BC5308F27A3D005CB29B /* textMark.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textMark.test; sourceTree = "<group>"; };
		F966BC5408F27A3D005CB29B /* textTag.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textTag.test; sourceTree = "<group>"; };
		F966BC5508F27A3D005CB29B /* textWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textWind.test; sourceTree = "<group>"; };
		F966BC5608F27A3D005CB29B /* tk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.test; sourceTree = "<group>"; };
		F966BC5708F27A3D005CB29B /* unixButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixButton.test; sourceTree = "<group>"; };
		F966BC5808F27A3D005CB29B /* unixEmbed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixEmbed.test; sourceTree = "<group>"; };
		F966BC5908F27A3D005CB29B /* unixFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFont.test; sourceTree = "<group>"; };
		F966BC5A08F27A3D005CB29B /* unixMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixMenu.test; sourceTree = "<group>"; };
		F966BC5B08F27A3D005CB29B /* unixSelect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixSelect.test; sourceTree = "<group>"; };
		F966BC5C08F27A3D005CB29B /* unixWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixWm.test; sourceTree = "<group>"; };
		F966BC5D08F27A3D005CB29B /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F966BC5E08F27A3D005CB29B /* visual.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual.test; sourceTree = "<group>"; };
		F966BC5F08F27A3D005CB29B /* visual_bb.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual_bb.test; sourceTree = "<group>"; };
		F966BC6008F27A3D005CB29B /* winButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winButton.test; sourceTree = "<group>"; };
		F966BC6108F27A3D005CB29B /* winClipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winClipboard.test; sourceTree = "<group>"; };
		F966BC6208F27A3D005CB29B /* winDialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDialog.test; sourceTree = "<group>"; };
		F966BC6308F27A3D005CB29B /* window.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = window.test; sourceTree = "<group>"; };
		F966BC6408F27A3D005CB29B /* winfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winfo.test; sourceTree = "<group>"; };
		F966BC6508F27A3D005CB29B /* winFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFont.test; sourceTree = "<group>"; };
		F966BC6608F27A3D005CB29B /* winMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winMenu.test; sourceTree = "<group>"; };
		F966BC6708F27A3D005CB29B /* winSend.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winSend.test; sourceTree = "<group>"; };
		F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = "<group>"; };
		F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = "<group>"; };
		F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
		F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BC7408F27A3D005CB29B /* tk.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.spec; sourceTree = "<group>"; };
		F966BC7508F27A3D005CB29B /* tkAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAppInit.c; sourceTree = "<group>"; };
		F966BC7608F27A3D005CB29B /* tkConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tkConfig.h.in; sourceTree = "<group>"; };
		F966BC7708F27A3D005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
		F966BC8708F27A3D005CB29B /* tkUnixKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixKey.c; sourceTree = "<group>"; };
		F966BC8808F27A3D005CB29B /* tkUnixMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenu.c; sourceTree = "<group>"; };
		F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenubu.c; sourceTree = "<group>"; };
		F966BC8A08F27A3D005CB29B /* tkUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixPort.h; sourceTree = "<group>"; };
		F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixRFont.c; sourceTree = "<group>"; };
		F966BC8C08F27A3D005CB29B /* tkUnixScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScale.c; sourceTree = "<group>"; };
		F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScrlbr.c; sourceTree = "<group>"; };
		F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSelect.c; sourceTree = "<group>"; };
		F966BC8F08F27A3D005CB29B /* tkUnixSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSend.c; sourceTree = "<group>"; };
		F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = "<group>"; };
		F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = "<group>"; };
		F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
		F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F966BC9B08F27A3E005CB29B /* mkd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mkd.bat; sourceTree = "<group>"; };
		F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = "<group>"; };
		F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = "<group>"; };
		F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = "<group>"; };
		F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BCF408F27A3E005CB29B /* rmd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rmd.bat; sourceTree = "<group>"; };
		F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = "<group>"; };
		F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = "<group>"; };
		F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin32Dll.c; sourceTree = "<group>"; };
		F966BCFB08F27A3F005CB29B /* tkWin3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin3d.c; sourceTree = "<group>"; };
		F966BCFC08F27A3F005CB29B /* tkWinButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinButton.c; sourceTree = "<group>"; };
		F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinClipboard.c; sourceTree = "<group>"; };
		F966BCFE08F27A3F005CB29B /* tkWinColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinColor.c; sourceTree = "<group>"; };
		F966BCFF08F27A3F005CB29B /* tkWinConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinConfig.c; sourceTree = "<group>"; };
		F966BD0008F27A3F005CB29B /* tkWinCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinCursor.c; sourceTree = "<group>"; };
		F966BD0108F27A3F005CB29B /* tkWinDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinDefault.h; sourceTree = "<group>"; };
		F966BD0208F27A3F005CB29B /* tkWinDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDialog.c; sourceTree = "<group>"; };
		F966BD0308F27A3F005CB29B /* tkWinDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDraw.c; sourceTree = "<group>"; };
		F966BD0408F27A3F005CB29B /* tkWinEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinEmbed.c; sourceTree = "<group>"; };
		F966BD0508F27A3F005CB29B /* tkWinFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinFont.c; sourceTree = "<group>"; };
		F966BD0708F27A3F005CB29B /* tkWinImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinImage.c; sourceTree = "<group>"; };
		F966BD0808F27A3F005CB29B /* tkWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinInit.c; sourceTree = "<group>"; };
		F966BD0908F27A3F005CB29B /* tkWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinInt.h; sourceTree = "<group>"; };
		F966BD0A08F27A3F005CB29B /* tkWinKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinKey.c; sourceTree = "<group>"; };
		F966BD0B08F27A3F005CB29B /* tkWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinMenu.c; sourceTree = "<group>"; };
		F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPixmap.c; sourceTree = "<group>"; };
		F966BD0D08F27A3F005CB29B /* tkWinPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPointer.c; sourceTree = "<group>"; };
		F966BD0E08F27A3F005CB29B /* tkWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinPort.h; sourceTree = "<group>"; };
		F966BD0F08F27A3F005CB29B /* tkWinRegion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinRegion.c; sourceTree = "<group>"; };
		F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinScrlbr.c; sourceTree = "<group>"; };
		F966BD1108F27A3F005CB29B /* tkWinSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSend.c; sourceTree = "<group>"; };
		F966BD1208F27A3F005CB29B /* tkWinSendCom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSendCom.c; sourceTree = "<group>"; };
		F966BD1308F27A3F005CB29B /* tkWinSendCom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinSendCom.h; sourceTree = "<group>"; };
		F966BD1408F27A3F005CB29B /* tkWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinTest.c; sourceTree = "<group>"; };
		F966BD1508F27A3F005CB29B /* tkWinWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWindow.c; sourceTree = "<group>"; };
		F966BD1608F27A3F005CB29B /* tkWinWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWm.c; sourceTree = "<group>"; };
		F966BD1708F27A3F005CB29B /* tkWinX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinX.c; sourceTree = "<group>"; };
		F966BD1808F27A3F005CB29B /* winMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winMain.c; sourceTree = "<group>"; };
		F966BD1B08F27A3F005CB29B /* cursorfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorfont.h; sourceTree = "<group>"; };
		F966BD1C08F27A3F005CB29B /* keysym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysym.h; sourceTree = "<group>"; };
		F966BD1D08F27A3F005CB29B /* keysymdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysymdef.h; sourceTree = "<group>"; };
		F966BD1E08F27A3F005CB29B /* X.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X.h; sourceTree = "<group>"; };
		F966BD1F08F27A3F005CB29B /* Xatom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xatom.h; sourceTree = "<group>"; };
		F966BD2008F27A3F005CB29B /* Xfuncproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xfuncproto.h; sourceTree = "<group>"; };
		F966BD2108F27A3F005CB29B /* Xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xlib.h; sourceTree = "<group>"; };
		F966BD2208F27A3F005CB29B /* Xutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xutil.h; sourceTree = "<group>"; };
		F966BD2308F27A3F005CB29B /* xbytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbytes.h; sourceTree = "<group>"; };
		F966BD2408F27A3F005CB29B /* xcolors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xcolors.c; sourceTree = "<group>"; };
		F966BD2508F27A3F005CB29B /* xdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdraw.c; sourceTree = "<group>"; };
		F966BD2608F27A3F005CB29B /* xgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xgc.c; sourceTree = "<group>"; };
		F966BD2708F27A3F005CB29B /* ximage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ximage.c; sourceTree = "<group>"; };
		F966BD2808F27A3F005CB29B /* xutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xutil.c; sourceTree = "<group>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F966C07608F2821B005CB29B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
		F966C07808F28233005CB29B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
		F96887E00AF786D5000797B5 /* ttk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.decls; sourceTree = "<group>"; };
		F96887E10AF786D5000797B5 /* ttkBlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkBlink.c; sourceTree = "<group>"; };
		F96887E20AF786D5000797B5 /* ttkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkButton.c; sourceTree = "<group>"; };
		F96887E30AF786D5000797B5 /* ttkCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkCache.c; sourceTree = "<group>"; };
		F96887E40AF786D5000797B5 /* ttkClamTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClamTheme.c; sourceTree = "<group>"; };
		F96887E50AF786D5000797B5 /* ttkClassicTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClassicTheme.c; sourceTree = "<group>"; };
		F96887E60AF786D5000797B5 /* ttkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkDecls.h; sourceTree = "<group>"; };
		F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkDefaultTheme.c; sourceTree = "<group>"; };
		F96887E80AF786D5000797B5 /* ttkElements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkElements.c; sourceTree = "<group>"; };
		F96887E90AF786D5000797B5 /* ttkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkEntry.c; sourceTree = "<group>"; };
		F96887EA0AF786D5000797B5 /* ttkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkFrame.c; sourceTree = "<group>"; };
		F96887EB0AF786D5000797B5 /* ttkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkImage.c; sourceTree = "<group>"; };
		F96887EC0AF786D5000797B5 /* ttkInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkInit.c; sourceTree = "<group>"; };
		F96887ED0AF786D5000797B5 /* ttkLabel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLabel.c; sourceTree = "<group>"; };
		F96887EE0AF786D5000797B5 /* ttkLayout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLayout.c; sourceTree = "<group>"; };
		F96887EF0AF786D5000797B5 /* ttkManager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkManager.c; sourceTree = "<group>"; };
		F96887F00AF786D5000797B5 /* ttkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkManager.h; sourceTree = "<group>"; };
		F96887F10AF786D5000797B5 /* ttkNotebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkNotebook.c; sourceTree = "<group>"; };
		F96887F20AF786D5000797B5 /* ttkPanedwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkPanedwindow.c; sourceTree = "<group>"; };
		F96887F30AF786D5000797B5 /* ttkProgress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkProgress.c; sourceTree = "<group>"; };
		F96887F40AF786D5000797B5 /* ttkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScale.c; sourceTree = "<group>"; };
		F96887F50AF786D5000797B5 /* ttkScroll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScroll.c; sourceTree = "<group>"; };
		F96887F60AF786D5000797B5 /* ttkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScrollbar.c; sourceTree = "<group>"; };
		F96887F70AF786D5000797B5 /* ttkSeparator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSeparator.c; sourceTree = "<group>"; };
		F96887F80AF786D5000797B5 /* ttkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSquare.c; sourceTree = "<group>"; };
		F96887F90AF786D5000797B5 /* ttkState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkState.c; sourceTree = "<group>"; };
		F96887FA0AF786D5000797B5 /* ttkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubInit.c; sourceTree = "<group>"; };
		F96887FB0AF786D5000797B5 /* ttkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubLib.c; sourceTree = "<group>"; };
		F96887FC0AF786D5000797B5 /* ttkTagSet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTagSet.c; sourceTree = "<group>"; };
		F96887FD0AF786D5000797B5 /* ttkTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTheme.c; sourceTree = "<group>"; };
		F96887FE0AF786D5000797B5 /* ttkTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkTheme.h; sourceTree = "<group>"; };
		F96887FF0AF786D5000797B5 /* ttkThemeInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkThemeInt.h; sourceTree = "<group>"; };
		F96888000AF786D5000797B5 /* ttkTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrace.c; sourceTree = "<group>"; };
		F96888010AF786D5000797B5 /* ttkTrack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrack.c; sourceTree = "<group>"; };
		F96888020AF786D5000797B5 /* ttkTreeview.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTreeview.c; sourceTree = "<group>"; };
		F96888030AF786D5000797B5 /* ttkWidget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWidget.c; sourceTree = "<group>"; };
		F96888040AF786D5000797B5 /* ttkWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkWidget.h; sourceTree = "<group>"; };
		F96888370AF787B3000797B5 /* altTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = altTheme.tcl; sourceTree = "<group>"; };
		F96888380AF787B3000797B5 /* aquaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aquaTheme.tcl; sourceTree = "<group>"; };
		F96888390AF787B3000797B5 /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F968883A0AF787B3000797B5 /* clamTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clamTheme.tcl; sourceTree = "<group>"; };
		F968883B0AF787B3000797B5 /* classicTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = classicTheme.tcl; sourceTree = "<group>"; };
		F968883C0AF787B3000797B5 /* combobox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.tcl; sourceTree = "<group>"; };
		F968883D0AF787B3000797B5 /* cursors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursors.tcl; sourceTree = "<group>"; };
		F968883E0AF787B3000797B5 /* defaults.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = defaults.tcl; sourceTree = "<group>"; };
		F96888400AF787B3000797B5 /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F96888410AF787B3000797B5 /* fonts.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fonts.tcl; sourceTree = "<group>"; };
		F96888440AF787B3000797B5 /* menubutton.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubutton.tcl; sourceTree = "<group>"; };
		F96888450AF787B3000797B5 /* notebook.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.tcl; sourceTree = "<group>"; };
		F96888460AF787B3000797B5 /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F96888470AF787B3000797B5 /* progress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progress.tcl; sourceTree = "<group>"; };
		F96888480AF787B3000797B5 /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F96888490AF787B3000797B5 /* scrollbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.tcl; sourceTree = "<group>"; };
		F968884A0AF787B3000797B5 /* sizegrip.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sizegrip.tcl; sourceTree = "<group>"; };
		F968884B0AF787B3000797B5 /* treeview.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.tcl; sourceTree = "<group>"; };
		F968884C0AF787B3000797B5 /* ttk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.tcl; sourceTree = "<group>"; };
		F968884D0AF787B3000797B5 /* utils.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utils.tcl; sourceTree = "<group>"; };
		F968884E0AF787B3000797B5 /* winTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTheme.tcl; sourceTree = "<group>"; };
		F968884F0AF787B3000797B5 /* xpTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xpTheme.tcl; sourceTree = "<group>"; };
		F96888540AF7880C000797B5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96888560AF7880C000797B5 /* combobox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.test; sourceTree = "<group>"; };
		F96888570AF7880C000797B5 /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F96888580AF7880C000797B5 /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F96888590AF7880C000797B5 /* labelframe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.test; sourceTree = "<group>"; };
		F968885A0AF7880C000797B5 /* layout.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = layout.test; sourceTree = "<group>"; };
		F968885C0AF7880C000797B5 /* notebook.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.test; sourceTree = "<group>"; };
		F968885D0AF7880C000797B5 /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F968885E0AF7880C000797B5 /* progressbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progressbar.test; sourceTree = "<group>"; };
		F968885F0AF7880C000797B5 /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F96888600AF7880C000797B5 /* treetags.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treetags.test; sourceTree = "<group>"; };
		F96888610AF7880C000797B5 /* treeview.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.test; sourceTree = "<group>"; };
		F96888620AF7880C000797B5 /* ttk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.test; sourceTree = "<group>"; };
		F96888630AF7880C000797B5 /* validate.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = validate.test; sourceTree = "<group>"; };
		F968886B0AF788F6000797B5 /* ttk_button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_button.n; sourceTree = "<group>"; };
		F968886C0AF788F6000797B5 /* ttk_checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_checkbutton.n; sourceTree = "<group>"; };
		F968886D0AF788F6000797B5 /* ttk_combobox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_combobox.n; sourceTree = "<group>"; };
		F968886F0AF788F6000797B5 /* ttk_entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_entry.n; sourceTree = "<group>"; };
		F96888700AF788F6000797B5 /* ttk_frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_frame.n; sourceTree = "<group>"; };
		F96888710AF788F6000797B5 /* ttk_Geometry.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Geometry.3; sourceTree = "<group>"; };
		F96888720AF788F6000797B5 /* ttk_image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_image.n; sourceTree = "<group>"; };
		F96888730AF788F6000797B5 /* ttk_intro.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_intro.n; sourceTree = "<group>"; };
		F96888740AF788F6000797B5 /* ttk_label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_label.n; sourceTree = "<group>"; };
		F96888750AF788F6000797B5 /* ttk_labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_labelframe.n; sourceTree = "<group>"; };
		F96888760AF788F6000797B5 /* ttk_menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_menubutton.n; sourceTree = "<group>"; };
		F96888770AF788F6000797B5 /* ttk_notebook.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_notebook.n; sourceTree = "<group>"; };
		F96888780AF788F6000797B5 /* ttk_panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_panedwindow.n; sourceTree = "<group>"; };
		F96888790AF788F6000797B5 /* ttk_progressbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_progressbar.n; sourceTree = "<group>"; };
		F968887A0AF788F6000797B5 /* ttk_radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_radiobutton.n; sourceTree = "<group>"; };
		F968887B0AF788F6000797B5 /* ttk_scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_scrollbar.n; sourceTree = "<group>"; };
		F968887C0AF788F6000797B5 /* ttk_separator.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_separator.n; sourceTree = "<group>"; };
		F968887D0AF788F6000797B5 /* ttk_sizegrip.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_sizegrip.n; sourceTree = "<group>"; };
		F968887E0AF788F6000797B5 /* ttk_style.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_style.n; sourceTree = "<group>"; };
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D425F08F272B3004A47F5 /* bn.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = bn.pdf; sourceTree = "<group>"; };
		F96D426108F272B3004A47F5 /* bn_error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_error.c; sourceTree = "<group>"; };
		F96D426208F272B3004A47F5 /* bn_fast_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_invmod.c; sourceTree = "<group>"; };
		F96D426308F272B3004A47F5 /* bn_fast_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_montgomery_reduce.c; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426508F272B3004A47F5 /* bn_fast_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426708F272B3004A47F5 /* bn_mp_2expt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_2expt.c; sourceTree = "<group>"; };
		F96D426808F272B3004A47F5 /* bn_mp_abs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_abs.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426B08F272B3004A47F5 /* bn_mp_addmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_addmod.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427308F272B3004A47F5 /* bn_mp_cnt_lsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cnt_lsb.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427B08F272B3004A47F5 /* bn_mp_dr_is_modulus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_is_modulus.c; sourceTree = "<group>"; };
		F96D427C08F272B3004A47F5 /* bn_mp_dr_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_reduce.c; sourceTree = "<group>"; };
		F96D427D08F272B3004A47F5 /* bn_mp_dr_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_setup.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
		F96D428008F272B3004A47F5 /* bn_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod.c; sourceTree = "<group>"; };
		F96D428108F272B3004A47F5 /* bn_mp_exptmod_fast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod_fast.c; sourceTree = "<group>"; };
		F96D428208F272B3004A47F5 /* bn_mp_exteuclid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exteuclid.c; sourceTree = "<group>"; };
		F96D428308F272B3004A47F5 /* bn_mp_fread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fread.c; sourceTree = "<group>"; };
		F96D428408F272B3004A47F5 /* bn_mp_fwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fwrite.c; sourceTree = "<group>"; };
		F96D428508F272B3004A47F5 /* bn_mp_gcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_gcd.c; sourceTree = "<group>"; };
		F96D428608F272B3004A47F5 /* bn_mp_get_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_get_int.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428C08F272B3004A47F5 /* bn_mp_init_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set_int.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D428E08F272B3004A47F5 /* bn_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod.c; sourceTree = "<group>"; };
		F96D428F08F272B3004A47F5 /* bn_mp_invmod_slow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod_slow.c; sourceTree = "<group>"; };
		F96D429008F272B3004A47F5 /* bn_mp_is_square.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_is_square.c; sourceTree = "<group>"; };
		F96D429108F272B3004A47F5 /* bn_mp_jacobi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_jacobi.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429408F272B3004A47F5 /* bn_mp_lcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lcm.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429808F272B3004A47F5 /* bn_mp_mod_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_d.c; sourceTree = "<group>"; };
		F96D429908F272B3004A47F5 /* bn_mp_montgomery_calc_normalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_calc_normalization.c; sourceTree = "<group>"; };
		F96D429A08F272B3004A47F5 /* bn_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_reduce.c; sourceTree = "<group>"; };
		F96D429B08F272B3004A47F5 /* bn_mp_montgomery_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_setup.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A008F272B3004A47F5 /* bn_mp_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mulmod.c; sourceTree = "<group>"; };
		F96D42A108F272B3004A47F5 /* bn_mp_n_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_n_root.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42A408F272B3004A47F5 /* bn_mp_prime_fermat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_fermat.c; sourceTree = "<group>"; };
		F96D42A508F272B3004A47F5 /* bn_mp_prime_is_divisible.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_divisible.c; sourceTree = "<group>"; };
		F96D42A608F272B3004A47F5 /* bn_mp_prime_is_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_prime.c; sourceTree = "<group>"; };
		F96D42A708F272B3004A47F5 /* bn_mp_prime_miller_rabin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_miller_rabin.c; sourceTree = "<group>"; };
		F96D42A808F272B3004A47F5 /* bn_mp_prime_next_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_next_prime.c; sourceTree = "<group>"; };
		F96D42A908F272B3004A47F5 /* bn_mp_prime_rabin_miller_trials.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_rabin_miller_trials.c; sourceTree = "<group>"; };
		F96D42AA08F272B3004A47F5 /* bn_mp_prime_random_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_random_ex.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AD08F272B3004A47F5 /* bn_mp_rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rand.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42AF08F272B3004A47F5 /* bn_mp_read_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_signed_bin.c; sourceTree = "<group>"; };
		F96D42B008F272B3004A47F5 /* bn_mp_read_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42B108F272B3004A47F5 /* bn_mp_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce.c; sourceTree = "<group>"; };
		F96D42B208F272B3004A47F5 /* bn_mp_reduce_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k.c; sourceTree = "<group>"; };
		F96D42B308F272B3004A47F5 /* bn_mp_reduce_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_l.c; sourceTree = "<group>"; };
		F96D42B408F272B3004A47F5 /* bn_mp_reduce_2k_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup.c; sourceTree = "<group>"; };
		F96D42B508F272B3004A47F5 /* bn_mp_reduce_2k_setup_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup_l.c; sourceTree = "<group>"; };
		F96D42B608F272B3004A47F5 /* bn_mp_reduce_is_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k.c; sourceTree = "<group>"; };
		F96D42B708F272B3004A47F5 /* bn_mp_reduce_is_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k_l.c; sourceTree = "<group>"; };
		F96D42B808F272B3004A47F5 /* bn_mp_reduce_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_setup.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BB08F272B3004A47F5 /* bn_mp_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set_int.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BD08F272B3004A47F5 /* bn_mp_signed_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_signed_bin_size.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42BF08F272B3004A47F5 /* bn_mp_sqrmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrmod.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C308F272B3004A47F5 /* bn_mp_submod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_submod.c; sourceTree = "<group>"; };
		F96D42C408F272B3004A47F5 /* bn_mp_to_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin.c; sourceTree = "<group>"; };
		F96D42C508F272B3004A47F5 /* bn_mp_to_signed_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin_n.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CA08F272B3004A47F5 /* bn_mp_toradix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42CF08F272B3004A47F5 /* bn_prime_tab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_prime_tab.c; sourceTree = "<group>"; };
		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D208F272B3004A47F5 /* bn_s_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_exptmod.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D408F272B3004A47F5 /* bn_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
		F96D42D908F272B3004A47F5 /* callgraph.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = callgraph.txt; sourceTree = "<group>"; };
		F96D42DA08F272B3004A47F5 /* changes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = changes.txt; sourceTree = "<group>"; };
		F96D42F008F272B3004A47F5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
		F96D431D08F272B4004A47F5 /* poster.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = poster.pdf; sourceTree = "<group>"; };
		F96D432608F272B4004A47F5 /* tommath.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = tommath.pdf; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437E08F272B6004A47F5 /* ioUtil.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioUtil.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443408F272B8004A47F5 /* str2c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = str2c; sourceTree = "<group>"; };
		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
		F96D443708F272B9004A47F5 /* tclmin.wse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclmin.wse; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPrivate.h; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Wish-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Debug.xcconfig"; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F9A3082D08F2D4AB00BAE1AB /* Tk.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084B08F2D4CE00BAE1AB /* Wish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wish.app; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
		F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mclist.tcl; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkpane.tcl; sourceTree = "<group>"; };
		F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkmenu.tcl; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
		F9FD31F40CC1AD070073837D /* tktest-X11 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "tktest-X11"; sourceTree = BUILT_PRODUCTS_DIR; };
		F9FD32140CC1AF170073837D /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = /usr/X11R6/lib/libX11.dylib; sourceTree = "<absolute>"; };
		F9FD32150CC1AF170073837D /* libXext.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXext.dylib; path = /usr/X11R6/lib/libXext.dylib; sourceTree = "<absolute>"; };
		F9FD32160CC1AF170073837D /* libXss.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXss.dylib; path = /usr/X11R6/lib/libXss.dylib; sourceTree = "<absolute>"; };
		F9FD34990CC1BB0D0073837D /* libfreetype.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreetype.dylib; path = /usr/X11R6/lib/libfreetype.dylib; sourceTree = "<absolute>"; };
		F9FD349A0CC1BB0D0073837D /* libXft.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXft.dylib; path = /usr/X11R6/lib/libXft.dylib; sourceTree = "<absolute>"; };
		F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfontconfig.dylib; path = /usr/X11R6/lib/libfontconfig.dylib; sourceTree = "<absolute>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */,
				F966C07908F28233005CB29B /* IOKit.framework in Frameworks */,
				F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */,
				F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD31E30CC1AD070073837D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */,
				F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */,
				F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */,
				F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */,
				F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */,
				F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */,
				F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Wish */ = {
			isa = PBXGroup;
			children = (
				F96D3DF708F271BE004A47F5 /* Tk Sources */,
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n";
			name = Wish;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* Wish.app */,
				F9A3082D08F2D4AB00BAE1AB /* Tk.framework */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
				8DD76FB20486AB0100D96B5E /* tktest */,
				F9FD31F40CC1AD070073837D /* tktest-X11 */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F966BA0308F27A37005CB29B /* bitmaps */ = {
			isa = PBXGroup;
			children = (
				F966BA0408F27A37005CB29B /* error.xbm */,
				F966BA0508F27A37005CB29B /* gray12.xbm */,
				F966BA0608F27A37005CB29B /* gray25.xbm */,
				F966BA0708F27A37005CB29B /* gray50.xbm */,
				F966BA0808F27A37005CB29B /* gray75.xbm */,
				F966BA0908F27A37005CB29B /* hourglass.xbm */,
				F966BA0A08F27A37005CB29B /* info.xbm */,
				F966BA0B08F27A37005CB29B /* questhead.xbm */,
				F966BA0C08F27A37005CB29B /* question.xbm */,
				F966BA0D08F27A37005CB29B /* warning.xbm */,
			);
			path = bitmaps;
			sourceTree = "<group>";
		};
		F966BA1008F27A37005CB29B /* doc */ = {
			isa = PBXGroup;
			children = (
				F966BA1108F27A37005CB29B /* 3DBorder.3 */,
				F966BA1208F27A37005CB29B /* AddOption.3 */,
				F966BA1308F27A37005CB29B /* bell.n */,
				F966BA1408F27A37005CB29B /* bind.n */,
				F966BA1508F27A37005CB29B /* BindTable.3 */,
				F966BA1608F27A37005CB29B /* bindtags.n */,
				F966BA1708F27A37005CB29B /* bitmap.n */,
				F966BA1808F27A37005CB29B /* button.n */,
				F966BA1908F27A37005CB29B /* canvas.n */,
				F966BA1A08F27A37005CB29B /* CanvPsY.3 */,
				F966BA1B08F27A37005CB29B /* CanvTkwin.3 */,
				F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */,
				F966BA1D08F27A37005CB29B /* checkbutton.n */,
				F966BA1E08F27A37005CB29B /* chooseColor.n */,
				F966BA1F08F27A37005CB29B /* chooseDirectory.n */,
				F966BA2008F27A37005CB29B /* Clipboard.3 */,
				F966BA2108F27A37005CB29B /* clipboard.n */,
				F966BA2208F27A37005CB29B /* ClrSelect.3 */,
				F966BA2308F27A37005CB29B /* colors.n */,
				F966BA2408F27A37005CB29B /* ConfigWidg.3 */,
				F966BA2508F27A37005CB29B /* ConfigWind.3 */,
				F966BA2608F27A37005CB29B /* console.n */,
				F966BA2708F27A37005CB29B /* CoordToWin.3 */,
				F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */,
				F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */,
				F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */,
				F966BA2B08F27A37005CB29B /* CrtImgType.3 */,
				F966BA2C08F27A37005CB29B /* CrtItemType.3 */,
				F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */,
				F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */,
				F966BA2F08F27A37005CB29B /* CrtWindow.3 */,
				F966BA3008F27A37005CB29B /* cursors.n */,
				F966BA3108F27A37005CB29B /* DeleteImg.3 */,
				F966BA3208F27A37005CB29B /* destroy.n */,
				F966BA3308F27A37005CB29B /* dialog.n */,
				F966BA3408F27A37005CB29B /* DrawFocHlt.3 */,
				F966BA3508F27A37005CB29B /* entry.n */,
				F966BA3608F27A37005CB29B /* event.n */,
				F966BA3708F27A37005CB29B /* EventHndlr.3 */,
				F966BA3808F27A37005CB29B /* FindPhoto.3 */,
				F966BA3908F27A37005CB29B /* focus.n */,
				F966BA3A08F27A37005CB29B /* focusNext.n */,
				F966BA3B08F27A37005CB29B /* font.n */,
				F966BA3C08F27A37005CB29B /* FontId.3 */,
				F966BA3D08F27A37005CB29B /* frame.n */,
				F966BA3E08F27A37005CB29B /* FreeXId.3 */,
				F966BA3F08F27A37005CB29B /* GeomReq.3 */,
				F966BA4008F27A37005CB29B /* GetAnchor.3 */,
				F966BA4108F27A37005CB29B /* GetBitmap.3 */,
				F966BA4208F27A37005CB29B /* GetCapStyl.3 */,
				F966BA4308F27A37005CB29B /* GetClrmap.3 */,
				F966BA4408F27A37005CB29B /* GetColor.3 */,
				F966BA4508F27A37005CB29B /* GetCursor.3 */,
				F966BA4608F27A37005CB29B /* GetDash.3 */,
				F966BA4708F27A37005CB29B /* GetFont.3 */,
				F966BA4808F27A37005CB29B /* GetGC.3 */,
				F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */,
				F966BA4A08F27A37005CB29B /* GetHWND.3 */,
				F966BA4B08F27A37005CB29B /* GetImage.3 */,
				F966BA4C08F27A37005CB29B /* GetJoinStl.3 */,
				F966BA4D08F27A37005CB29B /* GetJustify.3 */,
				F966BA4E08F27A37005CB29B /* getOpenFile.n */,
				F966BA4F08F27A37005CB29B /* GetOption.3 */,
				F966BA5008F27A38005CB29B /* GetPixels.3 */,
				F966BA5108F27A38005CB29B /* GetPixmap.3 */,
				F966BA5208F27A38005CB29B /* GetRelief.3 */,
				F966BA5308F27A38005CB29B /* GetRootCrd.3 */,
				F966BA5408F27A38005CB29B /* GetScroll.3 */,
				F966BA5508F27A38005CB29B /* GetSelect.3 */,
				F966BA5608F27A38005CB29B /* GetUid.3 */,
				F966BA5708F27A38005CB29B /* GetVisual.3 */,
				F966BA5808F27A38005CB29B /* GetVRoot.3 */,
				F966BA5908F27A38005CB29B /* Grab.3 */,
				F966BA5A08F27A38005CB29B /* grab.n */,
				F966BA5B08F27A38005CB29B /* grid.n */,
				F966BA5C08F27A38005CB29B /* HandleEvent.3 */,
				F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */,
				F966BA5E08F27A38005CB29B /* IdToWindow.3 */,
				F966BA5F08F27A38005CB29B /* image.n */,
				F966BA6008F27A38005CB29B /* ImgChanged.3 */,
				F966BA6108F27A38005CB29B /* Inactive.3 */,
				F966BA6208F27A38005CB29B /* InternAtom.3 */,
				F966BA6308F27A38005CB29B /* keysyms.n */,
				F966BA6408F27A38005CB29B /* label.n */,
				F966BA6508F27A38005CB29B /* labelframe.n */,
				F966BA6608F27A38005CB29B /* listbox.n */,
				F966BA6708F27A38005CB29B /* loadTk.n */,
				F966BA6808F27A38005CB29B /* lower.n */,
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
				F966BA8408F27A38005CB29B /* QWinEvent.3 */,
				F966BA8508F27A38005CB29B /* radiobutton.n */,
				F966BA8608F27A38005CB29B /* raise.n */,
				F966BA8708F27A38005CB29B /* Restack.3 */,
				F966BA8808F27A38005CB29B /* RestrictEv.3 */,
				F966BA8908F27A38005CB29B /* scale.n */,
				F966BA8A08F27A38005CB29B /* scrollbar.n */,
				F966BA8B08F27A38005CB29B /* selection.n */,
				F966BA8C08F27A38005CB29B /* send.n */,
				F966BA8D08F27A38005CB29B /* SetAppName.3 */,
				F966BA8E08F27A38005CB29B /* SetCaret.3 */,
				F966BA8F08F27A38005CB29B /* SetClass.3 */,
				F966BA9008F27A38005CB29B /* SetClassProcs.3 */,
				F966BA9108F27A38005CB29B /* SetGrid.3 */,
				F966BA9208F27A38005CB29B /* SetOptions.3 */,
				F966BA9308F27A38005CB29B /* SetVisual.3 */,
				F966BA9408F27A38005CB29B /* spinbox.n */,
				F966BA9508F27A38005CB29B /* StrictMotif.3 */,
				F966BA9608F27A38005CB29B /* text.n */,
				F966BA9708F27A38005CB29B /* TextLayout.3 */,
				F966BA9808F27A38005CB29B /* tk.n */,
				F966BA9908F27A38005CB29B /* tk4.0.ps */,
				F966BA9A08F27A38005CB29B /* Tk_Init.3 */,
				F966BA9B08F27A38005CB29B /* Tk_Main.3 */,
				F966BA9C08F27A38005CB29B /* tkerror.n */,
				F966BA9D08F27A38005CB29B /* TkInitStubs.3 */,
				F966BA9E08F27A38005CB29B /* tkvars.n */,
				F966BA9F08F27A38005CB29B /* tkwait.n */,
				F966BAA008F27A38005CB29B /* toplevel.n */,
				F968886B0AF788F6000797B5 /* ttk_button.n */,
				F968886C0AF788F6000797B5 /* ttk_checkbutton.n */,
				F968886D0AF788F6000797B5 /* ttk_combobox.n */,
				F968886F0AF788F6000797B5 /* ttk_entry.n */,
				F96888700AF788F6000797B5 /* ttk_frame.n */,
				F96888710AF788F6000797B5 /* ttk_Geometry.3 */,
				F96888720AF788F6000797B5 /* ttk_image.n */,
				F96888730AF788F6000797B5 /* ttk_intro.n */,
				F96888740AF788F6000797B5 /* ttk_label.n */,
				F96888750AF788F6000797B5 /* ttk_labelframe.n */,
				F96888760AF788F6000797B5 /* ttk_menubutton.n */,
				F96888770AF788F6000797B5 /* ttk_notebook.n */,
				F96888780AF788F6000797B5 /* ttk_panedwindow.n */,
				F96888790AF788F6000797B5 /* ttk_progressbar.n */,
				F968887A0AF788F6000797B5 /* ttk_radiobutton.n */,
				F968887B0AF788F6000797B5 /* ttk_scrollbar.n */,
				F968887C0AF788F6000797B5 /* ttk_separator.n */,
				F968887D0AF788F6000797B5 /* ttk_sizegrip.n */,
				F968887E0AF788F6000797B5 /* ttk_style.n */,
				F968887F0AF788F6000797B5 /* ttk_Theme.3 */,
				F96888800AF788F6000797B5 /* ttk_treeview.n */,
				F96888810AF788F6000797B5 /* ttk_widget.n */,
				F966BAA108F27A38005CB29B /* WindowId.3 */,
				F966BAA208F27A38005CB29B /* winfo.n */,
				F966BAA308F27A38005CB29B /* wish.1 */,
				F966BAA408F27A38005CB29B /* wm.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F966BAA508F27A38005CB29B /* generic */ = {
			isa = PBXGroup;
			children = (
				F966BAA608F27A38005CB29B /* default.h */,
				F966BAA708F27A38005CB29B /* ks_names.h */,
				F966BAA808F27A38005CB29B /* prolog.ps */,
				F966BAA908F27A39005CB29B /* README */,
				F966BAAA08F27A39005CB29B /* tk.decls */,
				F966BAAB08F27A39005CB29B /* tk.h */,
				F966BAAC08F27A39005CB29B /* tk3d.c */,
				F966BAAD08F27A39005CB29B /* tk3d.h */,
				F966BAAE08F27A39005CB29B /* tkArgv.c */,
				F966BAAF08F27A39005CB29B /* tkAtom.c */,
				F966BAB008F27A39005CB29B /* tkBind.c */,
				F966BAB108F27A39005CB29B /* tkBitmap.c */,
				F966BAB208F27A39005CB29B /* tkButton.c */,
				F966BAB308F27A39005CB29B /* tkButton.h */,
				F966BAB408F27A39005CB29B /* tkCanvArc.c */,
				F966BAB508F27A39005CB29B /* tkCanvas.c */,
				F966BAB608F27A39005CB29B /* tkCanvas.h */,
				F966BAB708F27A39005CB29B /* tkCanvBmap.c */,
				F966BAB808F27A39005CB29B /* tkCanvImg.c */,
				F966BAB908F27A39005CB29B /* tkCanvLine.c */,
				F966BABA08F27A39005CB29B /* tkCanvPoly.c */,
				F966BABB08F27A39005CB29B /* tkCanvPs.c */,
				F966BABD08F27A39005CB29B /* tkCanvText.c */,
				F966BABE08F27A39005CB29B /* tkCanvUtil.c */,
				F966BABF08F27A39005CB29B /* tkCanvWind.c */,
				F966BAC008F27A39005CB29B /* tkClipboard.c */,
				F966BAC108F27A39005CB29B /* tkCmds.c */,
				F966BAC208F27A39005CB29B /* tkColor.c */,
				F966BAC308F27A39005CB29B /* tkColor.h */,
				F966BAC408F27A39005CB29B /* tkConfig.c */,
				F966BAC508F27A39005CB29B /* tkConsole.c */,
				F966BAC608F27A39005CB29B /* tkCursor.c */,
				F966BAC708F27A39005CB29B /* tkDecls.h */,
				F966BAC808F27A39005CB29B /* tkEntry.c */,
				F966BAC908F27A39005CB29B /* tkEntry.h */,
				F966BACA08F27A39005CB29B /* tkError.c */,
				F966BACB08F27A39005CB29B /* tkEvent.c */,
				F966BACC08F27A39005CB29B /* tkFileFilter.c */,
				F966BACD08F27A39005CB29B /* tkFileFilter.h */,
				F966BACE08F27A39005CB29B /* tkFocus.c */,
				F966BACF08F27A39005CB29B /* tkFont.c */,
				F966BAD008F27A39005CB29B /* tkFont.h */,
				F966BAD108F27A39005CB29B /* tkFrame.c */,
				F966BAD208F27A39005CB29B /* tkGC.c */,
				F966BAD308F27A39005CB29B /* tkGeometry.c */,
				F966BAD408F27A39005CB29B /* tkGet.c */,
				F966BAD508F27A39005CB29B /* tkGrab.c */,
				F966BAD608F27A39005CB29B /* tkGrid.c */,
				F966BAD708F27A39005CB29B /* tkImage.c */,
				F966BAD808F27A39005CB29B /* tkImgBmap.c */,
				F966BAD908F27A39005CB29B /* tkImgGIF.c */,
				F966BADA08F27A39005CB29B /* tkImgPhoto.c */,
				F966BADB08F27A39005CB29B /* tkImgPPM.c */,
				F966BADC08F27A39005CB29B /* tkImgUtil.c */,
				F966BADE08F27A39005CB29B /* tkInt.decls */,
				F966BADF08F27A39005CB29B /* tkInt.h */,
				F966BAE108F27A39005CB29B /* tkIntDecls.h */,
				F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */,
				F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */,
				F966BAE408F27A39005CB29B /* tkListbox.c */,
				F966BAE508F27A39005CB29B /* tkMacWinMenu.c */,
				F966BAE608F27A39005CB29B /* tkMain.c */,
				F966BAE708F27A39005CB29B /* tkMenu.c */,
				F966BAE808F27A39005CB29B /* tkMenu.h */,
				F966BAE908F27A39005CB29B /* tkMenubutton.c */,
				F966BAEA08F27A39005CB29B /* tkMenubutton.h */,
				F966BAEB08F27A39005CB29B /* tkMenuDraw.c */,
				F966BAEC08F27A39005CB29B /* tkMessage.c */,
				F966BAED08F27A39005CB29B /* tkObj.c */,
				F966BAEE08F27A39005CB29B /* tkOldConfig.c */,
				F966BAEF08F27A39005CB29B /* tkOption.c */,
				F966BAF008F27A39005CB29B /* tkPack.c */,
				F966BAF108F27A39005CB29B /* tkPanedWindow.c */,
				F966BAF208F27A39005CB29B /* tkPlace.c */,
				F966BAF308F27A39005CB29B /* tkPlatDecls.h */,
				F966BAF408F27A39005CB29B /* tkPointer.c */,
				F966BAF508F27A39005CB29B /* tkPort.h */,
				F966BAF608F27A39005CB29B /* tkRectOval.c */,
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
				F966BB0608F27A39005CB29B /* tkTextDisp.c */,
				F966BB0808F27A39005CB29B /* tkTextImage.c */,
				F966BB0908F27A39005CB29B /* tkTextIndex.c */,
				F966BB0A08F27A39005CB29B /* tkTextMark.c */,
				F966BB0B08F27A39005CB29B /* tkTextTag.c */,
				F966BB0C08F27A39005CB29B /* tkTextWind.c */,
				F966BB0D08F27A39005CB29B /* tkTrig.c */,
				F966BB0E08F27A39005CB29B /* tkUndo.c */,
				F966BB0F08F27A39005CB29B /* tkUndo.h */,
				F966BB1008F27A39005CB29B /* tkUtil.c */,
				F966BB1108F27A39005CB29B /* tkVisual.c */,
				F966BB1208F27A39005CB29B /* tkWindow.c */,
				F96887DF0AF786D5000797B5 /* ttk */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F966BB1308F27A39005CB29B /* library */ = {
			isa = PBXGroup;
			children = (
				F966BB1408F27A39005CB29B /* bgerror.tcl */,
				F966BB1508F27A39005CB29B /* button.tcl */,
				F966BB1608F27A39005CB29B /* choosedir.tcl */,
				F966BB1708F27A39005CB29B /* clrpick.tcl */,
				F966BB1808F27A39005CB29B /* comdlg.tcl */,
				F966BB1908F27A39005CB29B /* console.tcl */,
				F966BB1A08F27A39005CB29B /* demos */,
				F966BB6208F27A3A005CB29B /* dialog.tcl */,
				F966BB6308F27A3A005CB29B /* entry.tcl */,
				F966BB6408F27A3A005CB29B /* focus.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8A08F27A3B005CB29B /* prolog.ps */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
			children = (
				F966BB1B08F27A39005CB29B /* anilabel.tcl */,
				F966BB1C08F27A39005CB29B /* aniwave.tcl */,
				F966BB1D08F27A39005CB29B /* arrow.tcl */,
				F966BB1E08F27A39005CB29B /* bind.tcl */,
				F966BB1F08F27A39005CB29B /* bitmap.tcl */,
				F966BB2008F27A39005CB29B /* browse */,
				F966BB2108F27A39005CB29B /* button.tcl */,
				F966BB2208F27A39005CB29B /* check.tcl */,
				F966BB2308F27A39005CB29B /* clrpick.tcl */,
				F966BB2408F27A39005CB29B /* colors.tcl */,
				F936FCDB0CCD984600716967 /* combo.tcl */,
				F966BB2508F27A39005CB29B /* cscroll.tcl */,
				F966BB2608F27A39005CB29B /* ctext.tcl */,
				F966BB2708F27A39005CB29B /* dialog1.tcl */,
				F966BB2808F27A39005CB29B /* dialog2.tcl */,
				F966BB2A08F27A39005CB29B /* entry1.tcl */,
				F966BB2B08F27A39005CB29B /* entry2.tcl */,
				F966BB2C08F27A39005CB29B /* entry3.tcl */,
				F966BB2D08F27A39005CB29B /* filebox.tcl */,
				F966BB2E08F27A39005CB29B /* floor.tcl */,
				F966BB2F08F27A39005CB29B /* form.tcl */,
				F966BB3008F27A39005CB29B /* goldberg.tcl */,
				F966BB3108F27A39005CB29B /* hello */,
				F966BB3208F27A39005CB29B /* hscale.tcl */,
				F966BB3308F27A39005CB29B /* icon.tcl */,
				F966BB3408F27A39005CB29B /* image1.tcl */,
				F966BB3508F27A39005CB29B /* image2.tcl */,
				F966BB4208F27A3A005CB29B /* items.tcl */,
				F966BB4308F27A3A005CB29B /* ixset */,
				F92240290D7C620F005EC715 /* knightstour.tcl */,
				F966BB4408F27A3A005CB29B /* label.tcl */,
				F966BB4508F27A3A005CB29B /* labelframe.tcl */,
				F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */,
				F966BB4608F27A3A005CB29B /* menu.tcl */,
				F966BB4708F27A3A005CB29B /* menubu.tcl */,
				F966BB4808F27A3A005CB29B /* msgbox.tcl */,
				F966BB4A08F27A3A005CB29B /* paned1.tcl */,
				F966BB4B08F27A3A005CB29B /* paned2.tcl */,
				F966BB4C08F27A3A005CB29B /* pendulum.tcl */,
				F966BB4D08F27A3A005CB29B /* plot.tcl */,
				F966BB4E08F27A3A005CB29B /* puzzle.tcl */,
				F966BB4F08F27A3A005CB29B /* radio.tcl */,
				F966BB5008F27A3A005CB29B /* README */,
				F966BB5108F27A3A005CB29B /* rmt */,
				F966BB5208F27A3A005CB29B /* rolodex */,
				F966BB5308F27A3A005CB29B /* ruler.tcl */,
				F966BB5408F27A3A005CB29B /* sayings.tcl */,
				F966BB5508F27A3A005CB29B /* search.tcl */,
				F966BB5608F27A3A005CB29B /* spin.tcl */,
				F966BB5708F27A3A005CB29B /* square */,
				F966BB5808F27A3A005CB29B /* states.tcl */,
				F966BB5908F27A3A005CB29B /* style.tcl */,
				F966BB5A08F27A3A005CB29B /* tclIndex */,
				F966BB5B08F27A3A005CB29B /* tcolor */,
				F966BB5C08F27A3A005CB29B /* text.tcl */,
				F9099B8A0CC67D30005A9580 /* textpeer.tcl */,
				F966BB5D08F27A3A005CB29B /* timer */,
				F936FCD90CCD984600716967 /* toolbar.tcl */,
				F936FCD80CCD984600716967 /* tree.tcl */,
				F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */,
				F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */,
				F936FCDA0CCD984600716967 /* ttknote.tcl */,
				F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */,
				F936FCD70CCD984500716967 /* ttkprogress.tcl */,
				F966BB5E08F27A3A005CB29B /* twind.tcl */,
				F966BB5F08F27A3A005CB29B /* unicodeout.tcl */,
				F966BB6008F27A3A005CB29B /* vscale.tcl */,
				F966BB6108F27A3A005CB29B /* widget */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		F966BB9708F27A3B005CB29B /* macosx */ = {
			isa = PBXGroup;
			children = (
				F966BBBA08F27A3B005CB29B /* configure.ac */,
				F966BBBB08F27A3B005CB29B /* GNUmakefile */,
				F966BBBE08F27A3B005CB29B /* README */,
				F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */,
				F966BBC208F27A3B005CB29B /* tkMacOSX.h */,
				F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */,
				F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */,
				F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */,
				F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */,
				F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */,
				F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */,
				F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */,
				F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */,
				F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */,
				F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */,
				F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */,
				F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */,
				F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */,
				F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */,
				F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */,
				F966BBD508F27A3B005CB29B /* tkMacOSXEvent.h */,
				F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */,
				F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */,
				F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */,
				F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */,
				F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */,
				F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */,
				F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */,
				F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */,
				F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */,
				F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */,
				F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */,
				F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */,
				F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */,
				F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */,
				F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */,
				F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */,
				F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */,
				F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */,
				F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */,
				F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */,
				F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */,
				F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */,
				F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */,
				F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */,
				F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */,
				F96888840AF78938000797B5 /* ttkMacOSXTheme.c */,
				F95D8D4B0F1715610006B020 /* Tk.icns */,
				F95D8D4C0F1715610006B020 /* Tk.tiff */,
				F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */,
				F97AE7F10B65C1E900310EA2 /* Wish-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F966BC0408F27A3C005CB29B /* tests */ = {
			isa = PBXGroup;
			children = (
				F966BC0508F27A3C005CB29B /* all.tcl */,
				F966BC0608F27A3C005CB29B /* arc.tcl */,
				F966BC0708F27A3C005CB29B /* bell.test */,
				F966BC0808F27A3C005CB29B /* bevel.tcl */,
				F966BC0908F27A3C005CB29B /* bgerror.test */,
				F966BC0A08F27A3C005CB29B /* bind.test */,
				F966BC0B08F27A3C005CB29B /* bitmap.test */,
				F966BC0C08F27A3C005CB29B /* border.test */,
				F966BC0D08F27A3C005CB29B /* bugs.tcl */,
				F966BC0E08F27A3C005CB29B /* butGeom.tcl */,
				F966BC0F08F27A3C005CB29B /* butGeom2.tcl */,
				F966BC1008F27A3C005CB29B /* button.test */,
				F966BC1108F27A3C005CB29B /* canvas.test */,
				F966BC1208F27A3C005CB29B /* canvImg.test */,
				F966BC1308F27A3C005CB29B /* canvPs.test */,
				F966BC1408F27A3C005CB29B /* canvPsArc.tcl */,
				F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */,
				F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */,
				F966BC1708F27A3C005CB29B /* canvPsImg.tcl */,
				F966BC1808F27A3C005CB29B /* canvPsText.tcl */,
				F966BC1908F27A3C005CB29B /* canvRect.test */,
				F966BC1A08F27A3C005CB29B /* canvText.test */,
				F966BC1B08F27A3C005CB29B /* canvWind.test */,
				F966BC1C08F27A3C005CB29B /* choosedir.test */,
				F966BC1D08F27A3C005CB29B /* clipboard.test */,
				F966BC1E08F27A3C005CB29B /* clrpick.test */,
				F966BC1F08F27A3C005CB29B /* cmap.tcl */,
				F966BC2008F27A3C005CB29B /* cmds.test */,
				F966BC2108F27A3C005CB29B /* color.test */,
				F966BC2208F27A3C005CB29B /* config.test */,
				F966BC2308F27A3C005CB29B /* constraints.tcl */,
				F966BC2408F27A3C005CB29B /* cursor.test */,
				F966BC2508F27A3C005CB29B /* dialog.test */,
				F966BC2608F27A3C005CB29B /* embed.test */,
				F966BC2708F27A3C005CB29B /* entry.test */,
				F966BC2808F27A3C005CB29B /* event.test */,
				F966BC2908F27A3C005CB29B /* filebox.test */,
				F966BC2A08F27A3C005CB29B /* focus.test */,
				F966BC2B08F27A3C005CB29B /* focusTcl.test */,
				F966BC2C08F27A3C005CB29B /* font.test */,
				F966BC2D08F27A3C005CB29B /* frame.test */,
				F966BC2E08F27A3C005CB29B /* geometry.test */,
				F966BC2F08F27A3C005CB29B /* get.test */,
				F966BC3008F27A3C005CB29B /* grab.test */,
				F966BC3108F27A3C005CB29B /* grid.test */,
				F966BC3208F27A3C005CB29B /* id.test */,
				F966BC3308F27A3C005CB29B /* image.test */,
				F966BC3408F27A3C005CB29B /* imgBmap.test */,
				F966BC3508F27A3C005CB29B /* imgPhoto.test */,
				F966BC3608F27A3C005CB29B /* imgPPM.test */,
				F966BC3708F27A3C005CB29B /* listbox.test */,
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
				F966BC4708F27A3D005CB29B /* README */,
				F966BC4808F27A3D005CB29B /* safe.test */,
				F966BC4908F27A3D005CB29B /* scale.test */,
				F966BC4A08F27A3D005CB29B /* scrollbar.test */,
				F966BC4B08F27A3D005CB29B /* select.test */,
				F966BC4C08F27A3D005CB29B /* send.test */,
				F966BC4D08F27A3D005CB29B /* spinbox.test */,
				F966BC4E08F27A3D005CB29B /* text.test */,
				F966BC4F08F27A3D005CB29B /* textBTree.test */,
				F966BC5008F27A3D005CB29B /* textDisp.test */,
				F966BC5108F27A3D005CB29B /* textImage.test */,
				F966BC5208F27A3D005CB29B /* textIndex.test */,
				F966BC5308F27A3D005CB29B /* textMark.test */,
				F966BC5408F27A3D005CB29B /* textTag.test */,
				F966BC5508F27A3D005CB29B /* textWind.test */,
				F966BC5608F27A3D005CB29B /* tk.test */,
				F96888530AF7880C000797B5 /* ttk */,
				F966BC5708F27A3D005CB29B /* unixButton.test */,
				F966BC5808F27A3D005CB29B /* unixEmbed.test */,
				F966BC5908F27A3D005CB29B /* unixFont.test */,
				F966BC5A08F27A3D005CB29B /* unixMenu.test */,
				F966BC5B08F27A3D005CB29B /* unixSelect.test */,
				F966BC5C08F27A3D005CB29B /* unixWm.test */,
				F966BC5D08F27A3D005CB29B /* util.test */,
				F966BC5E08F27A3D005CB29B /* visual.test */,
				F966BC5F08F27A3D005CB29B /* visual_bb.test */,
				F966BC6008F27A3D005CB29B /* winButton.test */,
				F966BC6108F27A3D005CB29B /* winClipboard.test */,
				F966BC6208F27A3D005CB29B /* winDialog.test */,
				F966BC6308F27A3D005CB29B /* window.test */,
				F966BC6408F27A3D005CB29B /* winfo.test */,
				F966BC6508F27A3D005CB29B /* winFont.test */,
				F966BC6608F27A3D005CB29B /* winMenu.test */,
				F966BC6708F27A3D005CB29B /* winSend.test */,
				F966BC6808F27A3D005CB29B /* winWm.test */,
				F966BC6908F27A3D005CB29B /* wm.test */,
				F966BC6A08F27A3D005CB29B /* xmfbox.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.in */,
				F966BC6F08F27A3D005CB29B /* install-sh */,
				F966BC7008F27A3D005CB29B /* installManPage */,
				F966BC7108F27A3D005CB29B /* Makefile.in */,
				F966BC7208F27A3D005CB29B /* README */,
				F966BC7308F27A3D005CB29B /* tcl.m4 */,
				F966BC7408F27A3D005CB29B /* tk.spec */,
				F966BC7508F27A3D005CB29B /* tkAppInit.c */,
				F966BC7608F27A3D005CB29B /* tkConfig.h.in */,
				F966BC7708F27A3D005CB29B /* tkConfig.sh.in */,
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
				F966BC8708F27A3D005CB29B /* tkUnixKey.c */,
				F966BC8808F27A3D005CB29B /* tkUnixMenu.c */,
				F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */,
				F966BC8A08F27A3D005CB29B /* tkUnixPort.h */,
				F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */,
				F966BC8C08F27A3D005CB29B /* tkUnixScale.c */,
				F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */,
				F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */,
				F966BC8F08F27A3D005CB29B /* tkUnixSend.c */,
				F966BC9008F27A3D005CB29B /* tkUnixWm.c */,
				F966BC9108F27A3D005CB29B /* tkUnixXId.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.in */,
				F966BC9808F27A3E005CB29B /* makefile.bc */,
				F966BC9908F27A3E005CB29B /* Makefile.in */,
				F966BC9A08F27A3E005CB29B /* makefile.vc */,
				F966BC9B08F27A3E005CB29B /* mkd.bat */,
				F966BC9C08F27A3E005CB29B /* nmakehlp.c */,
				F966BC9D08F27A3E005CB29B /* rc */,
				F966BCF308F27A3E005CB29B /* README */,
				F966BCF408F27A3E005CB29B /* rmd.bat */,
				F966BCF508F27A3F005CB29B /* rules.vc */,
				F966BCF608F27A3F005CB29B /* stubs.c */,
				F966BCF708F27A3F005CB29B /* tcl.m4 */,
				F966BCF808F27A3F005CB29B /* tkConfig.sh.in */,
				F966BCF908F27A3F005CB29B /* tkWin.h */,
				F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */,
				F966BCFB08F27A3F005CB29B /* tkWin3d.c */,
				F966BCFC08F27A3F005CB29B /* tkWinButton.c */,
				F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */,
				F966BCFE08F27A3F005CB29B /* tkWinColor.c */,
				F966BCFF08F27A3F005CB29B /* tkWinConfig.c */,
				F966BD0008F27A3F005CB29B /* tkWinCursor.c */,
				F966BD0108F27A3F005CB29B /* tkWinDefault.h */,
				F966BD0208F27A3F005CB29B /* tkWinDialog.c */,
				F966BD0308F27A3F005CB29B /* tkWinDraw.c */,
				F966BD0408F27A3F005CB29B /* tkWinEmbed.c */,
				F966BD0508F27A3F005CB29B /* tkWinFont.c */,
				F966BD0708F27A3F005CB29B /* tkWinImage.c */,
				F966BD0808F27A3F005CB29B /* tkWinInit.c */,
				F966BD0908F27A3F005CB29B /* tkWinInt.h */,
				F966BD0A08F27A3F005CB29B /* tkWinKey.c */,
				F966BD0B08F27A3F005CB29B /* tkWinMenu.c */,
				F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */,
				F966BD0D08F27A3F005CB29B /* tkWinPointer.c */,
				F966BD0E08F27A3F005CB29B /* tkWinPort.h */,
				F966BD0F08F27A3F005CB29B /* tkWinRegion.c */,
				F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */,
				F966BD1108F27A3F005CB29B /* tkWinSend.c */,
				F966BD1208F27A3F005CB29B /* tkWinSendCom.c */,
				F966BD1308F27A3F005CB29B /* tkWinSendCom.h */,
				F966BD1408F27A3F005CB29B /* tkWinTest.c */,
				F966BD1508F27A3F005CB29B /* tkWinWindow.c */,
				F966BD1608F27A3F005CB29B /* tkWinWm.c */,
				F966BD1708F27A3F005CB29B /* tkWinX.c */,
				F96888860AF78953000797B5 /* ttkWinMonitor.c */,
				F96888870AF78953000797B5 /* ttkWinTheme.c */,
				F96888880AF78953000797B5 /* ttkWinXPTheme.c */,
				F966BD1808F27A3F005CB29B /* winMain.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F966BC9D08F27A3E005CB29B /* rc */ = {
			isa = PBXGroup;
			children = (
				F966BCEE08F27A3E005CB29B /* tk.rc */,
				F966BCEF08F27A3E005CB29B /* tk_base.rc */,
				F966BCF208F27A3E005CB29B /* wish.rc */,
			);
			path = rc;
			sourceTree = "<group>";
		};
		F966BD1908F27A3F005CB29B /* xlib */ = {
			isa = PBXGroup;
			children = (
				F966BD1A08F27A3F005CB29B /* X11 */,
				F966BD2308F27A3F005CB29B /* xbytes.h */,
				F966BD2408F27A3F005CB29B /* xcolors.c */,
				F966BD2508F27A3F005CB29B /* xdraw.c */,
				F966BD2608F27A3F005CB29B /* xgc.c */,
				F966BD2708F27A3F005CB29B /* ximage.c */,
				F966BD2808F27A3F005CB29B /* xutil.c */,
			);
			path = xlib;
			sourceTree = "<group>";
		};
		F966BD1A08F27A3F005CB29B /* X11 */ = {
			isa = PBXGroup;
			children = (
				F966BD1B08F27A3F005CB29B /* cursorfont.h */,
				F966BD1C08F27A3F005CB29B /* keysym.h */,
				F966BD1D08F27A3F005CB29B /* keysymdef.h */,
				F966BD1E08F27A3F005CB29B /* X.h */,
				F966BD1F08F27A3F005CB29B /* Xatom.h */,
				F966BD2008F27A3F005CB29B /* Xfuncproto.h */,
				F966BD2108F27A3F005CB29B /* Xlib.h */,
				F966BD2208F27A3F005CB29B /* Xutil.h */,
			);
			path = X11;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */,
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F966C07608F2821B005CB29B /* Carbon.framework */,
				F94523A10E6FC2AC00C1D987 /* Cocoa.framework */,
				F966C07808F28233005CB29B /* IOKit.framework */,
				F9FD32140CC1AF170073837D /* libX11.dylib */,
				F9FD32150CC1AF170073837D /* libXext.dylib */,
				F9FD32160CC1AF170073837D /* libXss.dylib */,
				F9FD349A0CC1BB0D0073837D /* libXft.dylib */,
				F9FD34990CC1BB0D0073837D /* libfreetype.dylib */,
				F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96887DF0AF786D5000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96887E00AF786D5000797B5 /* ttk.decls */,
				F96887E10AF786D5000797B5 /* ttkBlink.c */,
				F96887E20AF786D5000797B5 /* ttkButton.c */,
				F96887E30AF786D5000797B5 /* ttkCache.c */,
				F96887E40AF786D5000797B5 /* ttkClamTheme.c */,
				F96887E50AF786D5000797B5 /* ttkClassicTheme.c */,
				F96887E60AF786D5000797B5 /* ttkDecls.h */,
				F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */,
				F96887E80AF786D5000797B5 /* ttkElements.c */,
				F96887E90AF786D5000797B5 /* ttkEntry.c */,
				F96887EA0AF786D5000797B5 /* ttkFrame.c */,
				F96887EB0AF786D5000797B5 /* ttkImage.c */,
				F96887EC0AF786D5000797B5 /* ttkInit.c */,
				F96887ED0AF786D5000797B5 /* ttkLabel.c */,
				F96887EE0AF786D5000797B5 /* ttkLayout.c */,
				F96887EF0AF786D5000797B5 /* ttkManager.c */,
				F96887F00AF786D5000797B5 /* ttkManager.h */,
				F96887F10AF786D5000797B5 /* ttkNotebook.c */,
				F96887F20AF786D5000797B5 /* ttkPanedwindow.c */,
				F96887F30AF786D5000797B5 /* ttkProgress.c */,
				F96887F40AF786D5000797B5 /* ttkScale.c */,
				F96887F50AF786D5000797B5 /* ttkScroll.c */,
				F96887F60AF786D5000797B5 /* ttkScrollbar.c */,
				F96887F70AF786D5000797B5 /* ttkSeparator.c */,
				F96887F80AF786D5000797B5 /* ttkSquare.c */,
				F96887F90AF786D5000797B5 /* ttkState.c */,
				F96887FA0AF786D5000797B5 /* ttkStubInit.c */,
				F96887FB0AF786D5000797B5 /* ttkStubLib.c */,
				F96887FC0AF786D5000797B5 /* ttkTagSet.c */,
				F96887FD0AF786D5000797B5 /* ttkTheme.c */,
				F96887FE0AF786D5000797B5 /* ttkTheme.h */,
				F96887FF0AF786D5000797B5 /* ttkThemeInt.h */,
				F96888000AF786D5000797B5 /* ttkTrace.c */,
				F96888010AF786D5000797B5 /* ttkTrack.c */,
				F96888020AF786D5000797B5 /* ttkTreeview.c */,
				F96888030AF786D5000797B5 /* ttkWidget.c */,
				F96888040AF786D5000797B5 /* ttkWidget.h */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888360AF787B3000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888370AF787B3000797B5 /* altTheme.tcl */,
				F96888380AF787B3000797B5 /* aquaTheme.tcl */,
				F96888390AF787B3000797B5 /* button.tcl */,
				F968883A0AF787B3000797B5 /* clamTheme.tcl */,
				F968883B0AF787B3000797B5 /* classicTheme.tcl */,
				F968883C0AF787B3000797B5 /* combobox.tcl */,
				F968883D0AF787B3000797B5 /* cursors.tcl */,
				F968883E0AF787B3000797B5 /* defaults.tcl */,
				F96888400AF787B3000797B5 /* entry.tcl */,
				F96888410AF787B3000797B5 /* fonts.tcl */,
				F96888440AF787B3000797B5 /* menubutton.tcl */,
				F96888450AF787B3000797B5 /* notebook.tcl */,
				F96888460AF787B3000797B5 /* panedwindow.tcl */,
				F96888470AF787B3000797B5 /* progress.tcl */,
				F96888480AF787B3000797B5 /* scale.tcl */,
				F96888490AF787B3000797B5 /* scrollbar.tcl */,
				F968884A0AF787B3000797B5 /* sizegrip.tcl */,
				F968884B0AF787B3000797B5 /* treeview.tcl */,
				F968884C0AF787B3000797B5 /* ttk.tcl */,
				F968884D0AF787B3000797B5 /* utils.tcl */,
				F968884E0AF787B3000797B5 /* winTheme.tcl */,
				F968884F0AF787B3000797B5 /* xpTheme.tcl */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888530AF7880C000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888540AF7880C000797B5 /* all.tcl */,
				F96888560AF7880C000797B5 /* combobox.test */,
				F96888570AF7880C000797B5 /* entry.test */,
				F96888580AF7880C000797B5 /* image.test */,
				F96888590AF7880C000797B5 /* labelframe.test */,
				F968885A0AF7880C000797B5 /* layout.test */,
				F968885C0AF7880C000797B5 /* notebook.test */,
				F968885D0AF7880C000797B5 /* panedwindow.test */,
				F968885E0AF7880C000797B5 /* progressbar.test */,
				F968885F0AF7880C000797B5 /* scrollbar.test */,
				F96888600AF7880C000797B5 /* treetags.test */,
				F96888610AF7880C000797B5 /* treeview.test */,
				F96888620AF7880C000797B5 /* ttk.test */,
				F96888630AF7880C000797B5 /* validate.test */,
				F962F7C60DADC26200648DB8 /* vsapi.test */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E0F08F272A5004A47F5 /* case.n */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96D3F3708F272A7004A47F5 /* tommath.h */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9008F272A8004A47F5 /* http1.0 */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
			isa = PBXGroup;
			children = (
				F96D3F9108F272A8004A47F5 /* http.tcl */,
				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http1.0;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D425F08F272B3004A47F5 /* bn.pdf */,
				F96D426108F272B3004A47F5 /* bn_error.c */,
				F96D426208F272B3004A47F5 /* bn_fast_mp_invmod.c */,
				F96D426308F272B3004A47F5 /* bn_fast_mp_montgomery_reduce.c */,
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426508F272B3004A47F5 /* bn_fast_s_mp_mul_high_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426708F272B3004A47F5 /* bn_mp_2expt.c */,
				F96D426808F272B3004A47F5 /* bn_mp_abs.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426B08F272B3004A47F5 /* bn_mp_addmod.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427308F272B3004A47F5 /* bn_mp_cnt_lsb.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427B08F272B3004A47F5 /* bn_mp_dr_is_modulus.c */,
				F96D427C08F272B3004A47F5 /* bn_mp_dr_reduce.c */,
				F96D427D08F272B3004A47F5 /* bn_mp_dr_setup.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
				F96D428008F272B3004A47F5 /* bn_mp_exptmod.c */,
				F96D428108F272B3004A47F5 /* bn_mp_exptmod_fast.c */,
				F96D428208F272B3004A47F5 /* bn_mp_exteuclid.c */,
				F96D428308F272B3004A47F5 /* bn_mp_fread.c */,
				F96D428408F272B3004A47F5 /* bn_mp_fwrite.c */,
				F96D428508F272B3004A47F5 /* bn_mp_gcd.c */,
				F96D428608F272B3004A47F5 /* bn_mp_get_int.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428C08F272B3004A47F5 /* bn_mp_init_set_int.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D428E08F272B3004A47F5 /* bn_mp_invmod.c */,
				F96D428F08F272B3004A47F5 /* bn_mp_invmod_slow.c */,
				F96D429008F272B3004A47F5 /* bn_mp_is_square.c */,
				F96D429108F272B3004A47F5 /* bn_mp_jacobi.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429408F272B3004A47F5 /* bn_mp_lcm.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429808F272B3004A47F5 /* bn_mp_mod_d.c */,
				F96D429908F272B3004A47F5 /* bn_mp_montgomery_calc_normalization.c */,
				F96D429A08F272B3004A47F5 /* bn_mp_montgomery_reduce.c */,
				F96D429B08F272B3004A47F5 /* bn_mp_montgomery_setup.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A008F272B3004A47F5 /* bn_mp_mulmod.c */,
				F96D42A108F272B3004A47F5 /* bn_mp_n_root.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42A408F272B3004A47F5 /* bn_mp_prime_fermat.c */,
				F96D42A508F272B3004A47F5 /* bn_mp_prime_is_divisible.c */,
				F96D42A608F272B3004A47F5 /* bn_mp_prime_is_prime.c */,
				F96D42A708F272B3004A47F5 /* bn_mp_prime_miller_rabin.c */,
				F96D42A808F272B3004A47F5 /* bn_mp_prime_next_prime.c */,
				F96D42A908F272B3004A47F5 /* bn_mp_prime_rabin_miller_trials.c */,
				F96D42AA08F272B3004A47F5 /* bn_mp_prime_random_ex.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AD08F272B3004A47F5 /* bn_mp_rand.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42AF08F272B3004A47F5 /* bn_mp_read_signed_bin.c */,
				F96D42B008F272B3004A47F5 /* bn_mp_read_unsigned_bin.c */,
				F96D42B108F272B3004A47F5 /* bn_mp_reduce.c */,
				F96D42B208F272B3004A47F5 /* bn_mp_reduce_2k.c */,
				F96D42B308F272B3004A47F5 /* bn_mp_reduce_2k_l.c */,
				F96D42B408F272B3004A47F5 /* bn_mp_reduce_2k_setup.c */,
				F96D42B508F272B3004A47F5 /* bn_mp_reduce_2k_setup_l.c */,
				F96D42B608F272B3004A47F5 /* bn_mp_reduce_is_2k.c */,
				F96D42B708F272B3004A47F5 /* bn_mp_reduce_is_2k_l.c */,
				F96D42B808F272B3004A47F5 /* bn_mp_reduce_setup.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BB08F272B3004A47F5 /* bn_mp_set_int.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BD08F272B3004A47F5 /* bn_mp_signed_bin_size.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42BF08F272B3004A47F5 /* bn_mp_sqrmod.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C308F272B3004A47F5 /* bn_mp_submod.c */,
				F96D42C408F272B3004A47F5 /* bn_mp_to_signed_bin.c */,
				F96D42C508F272B3004A47F5 /* bn_mp_to_signed_bin_n.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CA08F272B3004A47F5 /* bn_mp_toradix.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42CF08F272B3004A47F5 /* bn_prime_tab.c */,
				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D208F272B3004A47F5 /* bn_s_mp_exptmod.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D408F272B3004A47F5 /* bn_s_mp_mul_high_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D42D708F272B3004A47F5 /* bncore.c */,
				F96D42D908F272B3004A47F5 /* callgraph.txt */,
				F96D42DA08F272B3004A47F5 /* changes.txt */,
				F96D42F008F272B3004A47F5 /* LICENSE */,
				F96D431D08F272B4004A47F5 /* poster.pdf */,
				F96D432608F272B4004A47F5 /* tommath.pdf */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437E08F272B6004A47F5 /* ioUtil.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.in */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D442C08F272B8004A47F5 /* man2help.tcl */,
				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
				F96D442E08F272B8004A47F5 /* man2html.tcl */,
				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
				F96D443008F272B8004A47F5 /* man2html2.tcl */,
				F96D443108F272B8004A47F5 /* man2tcl.c */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443408F272B8004A47F5 /* str2c */,
				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
				F96D443608F272B8004A47F5 /* tcl.wse.in */,
				F96D443708F272B9004A47F5 /* tclmin.wse */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.in */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446A08F272B9004A47F5 /* tclUnixThrd.h */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447308F272BA004A47F5 /* coffbase.txt */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.in */,
				F96D447608F272BA004A47F5 /* makefile.bc */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tktest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* ShellScript */,
				F9A5C5F608F651AB008AE941 /* ShellScript */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tktest;
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = 8DD76FB20486AB0100D96B5E /* tktest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tktest-X11 */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */;
			buildPhases = (
				F9FD30B40CC1AD070073837D /* ShellScript */,
				F9FD30B50CC1AD070073837D /* ShellScript */,
				F9FD30BB0CC1AD070073837D /* Sources */,
				F9FD31E30CC1AD070073837D /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = "tktest-X11";
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = F9FD31F40CC1AD070073837D /* tktest-X11 */;
			productType = "com.apple.product-type.tool";
		};
		F9E61D16090A3E94002B3151 /* Tk */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* ShellScript */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tk;
			productName = Wish;
			productReference = F9A3084B08F2D4CE00BAE1AB /* Wish.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Wish" */;
			compatibilityVersion = "Xcode 3.1";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Wish */;
			projectDirPath = "";
			projectRoot = ..;
			targets = (
				F9E61D16090A3E94002B3151 /* Tk */,
				8DD76FA90486AB0100D96B5E /* tktest */,
				F97258A50A86873C00096C78 /* tktest-X11 */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F97AF02F0B665DA900310EA2 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			outputPaths = (
				"${TARGET_BUILD_DIR}/${WRAPPER_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "gnumake -C \"${TK_SRCROOT}/macosx\"  -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" APPLICATION_INSTALL_PATH=\"${APPLICATION_INSTALL_PATH}\" TCL_BUILD_DIR=\"${TCL_BUILD_DIR}\" TCL_FRAMEWORK_DIR=\"${TCL_FRAMEWORK_DIR}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${BUILT_PRODUCTS_DIR}/tktest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tktest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.in",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F608F651AB008AE941 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.in",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
		F9FD30B40CC1AD070073837D /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.in",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --disable-corefoundation ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B50CC1AD070073837D /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.in",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --disable-corefoundation --enable-xft --with-tcl=../tcl ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
				F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */,
				F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */,
				F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */,
				F966BDD308F27A3F005CB29B /* tkBind.c in Sources */,
				F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */,
				F966BDD508F27A3F005CB29B /* tkButton.c in Sources */,
				F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */,
				F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */,
				F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */,
				F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */,
				F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */,
				F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */,
				F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */,
				F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */,
				F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */,
				F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */,
				F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */,
				F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */,
				F966BDE508F27A3F005CB29B /* tkColor.c in Sources */,
				F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */,
				F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */,
				F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */,
				F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */,
				F966BDED08F27A3F005CB29B /* tkError.c in Sources */,
				F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */,
				F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */,
				F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */,
				F966BDF208F27A3F005CB29B /* tkFont.c in Sources */,
				F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */,
				F966BDF508F27A3F005CB29B /* tkGC.c in Sources */,
				F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */,
				F966BDF708F27A3F005CB29B /* tkGet.c in Sources */,
				F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */,
				F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */,
				F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */,
				F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */,
				F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */,
				F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */,
				F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */,
				F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */,
				F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */,
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
				F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */,
				F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */,
				F966BE2008F27A40005CB29B /* tkSquare.c in Sources */,
				F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */,
				F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */,
				F966BE2408F27A40005CB29B /* tkStyle.c in Sources */,
				F966BE2508F27A40005CB29B /* tkTest.c in Sources */,
				F966BE2608F27A40005CB29B /* tkText.c in Sources */,
				F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */,
				F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */,
				F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */,
				F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */,
				F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */,
				F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */,
				F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */,
				F966BE3008F27A40005CB29B /* tkTrig.c in Sources */,
				F966BE3108F27A40005CB29B /* tkUndo.c in Sources */,
				F966BE3308F27A40005CB29B /* tkUtil.c in Sources */,
				F966BE3408F27A40005CB29B /* tkVisual.c in Sources */,
				F966BE3508F27A40005CB29B /* tkWindow.c in Sources */,
				F96888050AF786D5000797B5 /* ttkBlink.c in Sources */,
				F96888060AF786D5000797B5 /* ttkButton.c in Sources */,
				F96888070AF786D5000797B5 /* ttkCache.c in Sources */,
				F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */,
				F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */,
				F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */,
				F968880B0AF786D5000797B5 /* ttkElements.c in Sources */,
				F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */,
				F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */,
				F968880E0AF786D5000797B5 /* ttkImage.c in Sources */,
				F968880F0AF786D5000797B5 /* ttkInit.c in Sources */,
				F96888100AF786D5000797B5 /* ttkLabel.c in Sources */,
				F96888110AF786D5000797B5 /* ttkLayout.c in Sources */,
				F96888120AF786D5000797B5 /* ttkManager.c in Sources */,
				F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */,
				F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */,
				F96888150AF786D5000797B5 /* ttkProgress.c in Sources */,
				F96888160AF786D5000797B5 /* ttkScale.c in Sources */,
				F96888170AF786D5000797B5 /* ttkScroll.c in Sources */,
				F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */,
				F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */,
				F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */,
				F968881B0AF786D5000797B5 /* ttkState.c in Sources */,
				F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */,
				F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */,
				F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */,
				F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */,
				F96888200AF786D5000797B5 /* ttkTrace.c in Sources */,
				F96888210AF786D5000797B5 /* ttkTrack.c in Sources */,
				F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */,
				F96888230AF786D5000797B5 /* ttkWidget.c in Sources */,
				F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */,
				F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */,
				F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */,
				F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */,
				F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */,
				F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */,
				F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */,
				F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */,
				F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */,
				F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */,
				F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */,
				F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */,
				F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */,
				F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */,
				F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */,
				F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */,
				F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */,
				F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */,
				F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */,
				F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */,
				F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */,
				F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */,
				F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */,
				F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */,
				F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */,
				F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */,
				F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */,
				F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */,
				F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */,
				F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */,
				F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */,
				F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */,
				F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */,
				F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */,
				F966C02A08F27A42005CB29B /* xcolors.c in Sources */,
				F966C02B08F27A42005CB29B /* xdraw.c in Sources */,
				F966C02C08F27A42005CB29B /* xgc.c in Sources */,
				F966C02D08F27A42005CB29B /* ximage.c in Sources */,
				F966C02E08F27A42005CB29B /* xutil.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD30BB0CC1AD070073837D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */,
				F9FD30BD0CC1AD070073837D /* regerror.c in Sources */,
				F9FD30BE0CC1AD070073837D /* regexec.c in Sources */,
				F9FD30BF0CC1AD070073837D /* regfree.c in Sources */,
				F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */,
				F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */,
				F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */,
				F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */,
				F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */,
				F9FD30C50CC1AD070073837D /* tclClock.c in Sources */,
				F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */,
				F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */,
				F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */,
				F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */,
				F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */,
				F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */,
				F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */,
				F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */,
				F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */,
				F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */,
				F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */,
				F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */,
				F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */,
				F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */,
				F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */,
				F9FD30D50CC1AD070073837D /* tclGet.c in Sources */,
				F9FD30D60CC1AD070073837D /* tclHash.c in Sources */,
				F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */,
				F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */,
				F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */,
				F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */,
				F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */,
				F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */,
				F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */,
				F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */,
				F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */,
				F9FD30E00CC1AD070073837D /* tclLink.c in Sources */,
				F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */,
				F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */,
				F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */,
				F9FD30E40CC1AD070073837D /* tclMain.c in Sources */,
				F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */,
				F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */,
				F9FD30E70CC1AD070073837D /* tclObj.c in Sources */,
				F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */,
				F9FD30E90CC1AD070073837D /* tclParse.c in Sources */,
				F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */,
				F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */,
				F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */,
				F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */,
				F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */,
				F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */,
				F9FD30F00CC1AD070073837D /* tclProc.c in Sources */,
				F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */,
				F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */,
				F9FD30F30CC1AD070073837D /* tclResult.c in Sources */,
				F9FD30F40CC1AD070073837D /* tclScan.c in Sources */,
				F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */,
				F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */,
				F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */,
				F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */,
				F9FD30F90CC1AD070073837D /* tclThread.c in Sources */,
				F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */,
				F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */,
				F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */,
				F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */,
				F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */,
				F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */,
				F9FD31000CC1AD070073837D /* tclUtf.c in Sources */,
				F9FD31010CC1AD070073837D /* tclUtil.c in Sources */,
				F9FD31020CC1AD070073837D /* tclVar.c in Sources */,
				F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */,
				F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */,
				F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */,
				F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */,
				F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */,
				F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */,
				F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */,
				F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */,
				F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */,
				F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */,
				F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */,
				F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */,
				F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */,
				F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */,
				F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */,
				F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */,
				F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */,
				F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */,
				F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */,
				F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */,
				F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */,
				F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */,
				F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */,
				F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */,
				F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */,
				F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */,
				F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */,
				F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */,
				F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */,
				F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */,
				F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */,
				F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */,
				F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */,
				F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */,
				F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */,
				F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */,
				F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */,
				F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */,
				F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */,
				F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */,
				F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */,
				F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */,
				F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */,
				F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */,
				F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */,
				F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */,
				F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */,
				F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */,
				F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */,
				F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */,
				F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */,
				F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */,
				F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */,
				F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */,
				F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */,
				F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */,
				F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */,
				F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */,
				F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */,
				F9FD313F0CC1AD070073837D /* bncore.c in Sources */,
				F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */,
				F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */,
				F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */,
				F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */,
				F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */,
				F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */,
				F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */,
				F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */,
				F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */,
				F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */,
				F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */,
				F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */,
				F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */,
				F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */,
				F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */,
				F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */,
				F9FD314F0CC1AD070073837D /* tk3d.c in Sources */,
				F9FD31500CC1AD070073837D /* tkArgv.c in Sources */,
				F9FD31510CC1AD070073837D /* tkAtom.c in Sources */,
				F9FD31520CC1AD070073837D /* tkBind.c in Sources */,
				F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */,
				F9FD31540CC1AD070073837D /* tkButton.c in Sources */,
				F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */,
				F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */,
				F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */,
				F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */,
				F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */,
				F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */,
				F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */,
				F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */,
				F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */,
				F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */,
				F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */,
				F9FD31600CC1AD070073837D /* tkCmds.c in Sources */,
				F9FD31610CC1AD070073837D /* tkColor.c in Sources */,
				F9FD31620CC1AD070073837D /* tkConfig.c in Sources */,
				F9FD31630CC1AD070073837D /* tkConsole.c in Sources */,
				F9FD31640CC1AD070073837D /* tkCursor.c in Sources */,
				F9FD31650CC1AD070073837D /* tkEntry.c in Sources */,
				F9FD31660CC1AD070073837D /* tkError.c in Sources */,
				F9FD31670CC1AD070073837D /* tkEvent.c in Sources */,
				F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */,
				F9FD31690CC1AD070073837D /* tkFocus.c in Sources */,
				F9FD316A0CC1AD070073837D /* tkFont.c in Sources */,
				F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */,
				F9FD316C0CC1AD070073837D /* tkGC.c in Sources */,
				F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */,
				F9FD316E0CC1AD070073837D /* tkGet.c in Sources */,
				F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */,
				F9FD31700CC1AD070073837D /* tkGrid.c in Sources */,
				F9FD31710CC1AD070073837D /* tkImage.c in Sources */,
				F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */,
				F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */,
				F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */,
				F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */,
				F9FD31760CC1AD070073837D /* tkListbox.c in Sources */,
				F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */,
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
				F9FD31880CC1AD070073837D /* tkSelect.c in Sources */,
				F9FD31890CC1AD070073837D /* tkSquare.c in Sources */,
				F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */,
				F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */,
				F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */,
				F9FD318D0CC1AD070073837D /* tkTest.c in Sources */,
				F9FD318E0CC1AD070073837D /* tkText.c in Sources */,
				F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */,
				F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */,
				F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */,
				F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */,
				F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */,
				F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */,
				F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */,
				F9FD31960CC1AD070073837D /* tkTrig.c in Sources */,
				F9FD31970CC1AD070073837D /* tkUndo.c in Sources */,
				F9FD31980CC1AD070073837D /* tkUtil.c in Sources */,
				F9FD31990CC1AD070073837D /* tkVisual.c in Sources */,
				F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */,
				F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */,
				F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */,
				F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */,
				F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */,
				F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */,
				F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */,
				F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */,
				F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */,
				F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */,
				F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */,
				F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */,
				F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */,
				F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */,
				F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */,
				F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */,
				F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */,
				F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */,
				F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */,
				F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */,
				F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */,
				F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */,
				F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */,
				F9FD31B10CC1AD070073837D /* ttkState.c in Sources */,
				F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */,
				F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */,
				F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */,
				F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */,
				F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */,
				F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */,
				F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */,
				F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */,
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
				F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */,
				F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */,
				F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */,
				F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */,
				F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */,
				F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */,
				F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */,
				F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		F90E36D50F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D60F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D70F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D80F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc42 nogc";
		};
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixZL;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoFixZL;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_32_BIT)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixZL;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixZL;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc42";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc42";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc42";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc42";
		};
		F9988AB50D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CC = "$(DEVELOPER_DIR)/usr/bin/llvm-gcc-4.2";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB60D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB70D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB80D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug llvmgcc42";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CC = "$(DEVELOPER_DIR)/usr/bin/llvm-gcc-4.2";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				TCL_CONFIGURE_ARGS = "$(TCL_CONFIGURE_ARGS) --disable-dtrace";
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugLeaks;
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9988AB20D814C6500B6B03B /* Debug gcc42 */,
				F90E36D60F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB60D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixZL */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9988AB30D814C6500B6B03B /* Debug gcc42 */,
				F90E36D70F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB70D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixZL */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Wish" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9988AB10D814C6500B6B03B /* Debug gcc42 */,
				F90E36D50F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB50D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixZL */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9988AB40D814C6500B6B03B /* Debug gcc42 */,
				F90E36D80F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB80D814C7500B6B03B /* Debug llvmgcc42 */,
				F97258AB0A86873D00096C78 /* DebugNoFixZL */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

Added macosx/Wish.xcodeproj/default.pbxuser.













































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* Wish */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tk */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
			F944EB8F08F798100049FDD4 /* tktest */,
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f75708692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a0b707265666572656e63657386928497960892849a9a07666e6d617463688692849a9a008692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a0572656765788692849a9a065c2e286329248692849a9a097265637572736976658692848484084e534e756d626572008484074e5356616c7565009584012a849696018692849a9a0669734c656166869284b09db296008692849a9a0763616e536176658692af92849a9a1250425850726f6a65637453636f70654b65798692849a9a03594553868692849a9a08676c6f62616c49448692849a9a18314343304541343030343335304546393030343434313042868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			CODE_SIGN_IDENTITY = "";
			SYMROOT = "${SRCROOT}/../../build/tk";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
			TK_SRCROOT = "${SRCROOT}/../../tk";
		};
	};
	8DD76FA90486AB0100D96B5E /* tktest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tktest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tktest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = TK_SRCROOT;
				value = "${TK_SRCROOT}";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = EventDebug;
				value = 1;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tktest;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F9E61D16090A3E94002B3151 /* Tk */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
		);
	};
	F9E61D1C090A4282002B3151 /* Wish */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = Wish;
		sourceDirectories = (
		);
	};
	F97258A50A86873C00096C78 /* tktest-X11 */ = {
		activeExec = 0;
		executables = (
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
	};
	F9FD31F50CC1AD070073837D /* tktest-X11 */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = DISPLAY;
				value = ":0";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = "tktest-X11";
		sourceDirectories = (
		);
	};
}

Added macosx/Wish.xcodeproj/project.pbxproj.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F94523A10E6FC2AC00C1D987 /* Cocoa.framework */; };
		F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F966BDD308F27A3F005CB29B /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F966BDD508F27A3F005CB29B /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F966BDE508F27A3F005CB29B /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F966BDED08F27A3F005CB29B /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F966BDF208F27A3F005CB29B /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F966BDF508F27A3F005CB29B /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F966BDF708F27A3F005CB29B /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F966BE0908F27A3F005CB29B /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F966BE1008F27A3F005CB29B /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F966BE1208F27A3F005CB29B /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F966BE1308F27A3F005CB29B /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF408F27A39005CB29B /* tkPointer.c */; };
		F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F966BE2008F27A40005CB29B /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F966BE2408F27A40005CB29B /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F966BE2508F27A40005CB29B /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F966BE2608F27A40005CB29B /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F966BE3008F27A40005CB29B /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F966BE3108F27A40005CB29B /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F966BE3308F27A40005CB29B /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F966BE3408F27A40005CB29B /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F966BE3508F27A40005CB29B /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */; };
		F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */; };
		F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */; };
		F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */; };
		F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */; };
		F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */; };
		F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */; };
		F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */; };
		F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */; };
		F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */; };
		F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */; };
		F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */; };
		F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */; };
		F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */; };
		F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */; settings = {COMPILER_FLAGS = "-DTK_LIBRARY=\\\"$(TK_LIBRARY)\\\""; }; };
		F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */; };
		F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */; };
		F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */; };
		F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */; };
		F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */; };
		F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */; };
		F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */; };
		F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */; };
		F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */; };
		F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */; };
		F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */; };
		F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */; };
		F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */; };
		F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */; };
		F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */; };
		F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F966C02A08F27A42005CB29B /* xcolors.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2408F27A3F005CB29B /* xcolors.c */; };
		F966C02B08F27A42005CB29B /* xdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2508F27A3F005CB29B /* xdraw.c */; };
		F966C02C08F27A42005CB29B /* xgc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2608F27A3F005CB29B /* xgc.c */; };
		F966C02D08F27A42005CB29B /* ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2708F27A3F005CB29B /* ximage.c */; };
		F966C02E08F27A42005CB29B /* xutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2808F27A3F005CB29B /* xutil.c */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07608F2821B005CB29B /* Carbon.framework */; };
		F966C07908F28233005CB29B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07808F28233005CB29B /* IOKit.framework */; };
		F96888050AF786D5000797B5 /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F96888060AF786D5000797B5 /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F96888070AF786D5000797B5 /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F968880B0AF786D5000797B5 /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F968880E0AF786D5000797B5 /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F968880F0AF786D5000797B5 /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F96888100AF786D5000797B5 /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F96888110AF786D5000797B5 /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F96888120AF786D5000797B5 /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F96888150AF786D5000797B5 /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F96888160AF786D5000797B5 /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F96888170AF786D5000797B5 /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F968881B0AF786D5000797B5 /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F96888200AF786D5000797B5 /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F96888210AF786D5000797B5 /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F96888230AF786D5000797B5 /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888840AF78938000797B5 /* ttkMacOSXTheme.c */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F9FD30BD0CC1AD070073837D /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F9FD30BE0CC1AD070073837D /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F9FD30BF0CC1AD070073837D /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F9FD30C50CC1AD070073837D /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F9FD30D50CC1AD070073837D /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F9FD30D60CC1AD070073837D /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F9FD30E00CC1AD070073837D /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F9FD30E40CC1AD070073837D /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F9FD30E70CC1AD070073837D /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F9FD30E90CC1AD070073837D /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F9FD30F00CC1AD070073837D /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F9FD30F30CC1AD070073837D /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F9FD30F40CC1AD070073837D /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F9FD30F90CC1AD070073837D /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F9FD31000CC1AD070073837D /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F9FD31010CC1AD070073837D /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F9FD31020CC1AD070073837D /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F9FD313F0CC1AD070073837D /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9FD314F0CC1AD070073837D /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F9FD31500CC1AD070073837D /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F9FD31510CC1AD070073837D /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F9FD31520CC1AD070073837D /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F9FD31540CC1AD070073837D /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F9FD31600CC1AD070073837D /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F9FD31610CC1AD070073837D /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F9FD31620CC1AD070073837D /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F9FD31630CC1AD070073837D /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F9FD31640CC1AD070073837D /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F9FD31650CC1AD070073837D /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F9FD31660CC1AD070073837D /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F9FD31670CC1AD070073837D /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F9FD31690CC1AD070073837D /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F9FD316A0CC1AD070073837D /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F9FD316C0CC1AD070073837D /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F9FD316E0CC1AD070073837D /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F9FD31700CC1AD070073837D /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F9FD31710CC1AD070073837D /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F9FD31760CC1AD070073837D /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F9FD31880CC1AD070073837D /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F9FD31890CC1AD070073837D /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F9FD318D0CC1AD070073837D /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F9FD318E0CC1AD070073837D /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F9FD31960CC1AD070073837D /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F9FD31970CC1AD070073837D /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F9FD31980CC1AD070073837D /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F9FD31990CC1AD070073837D /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F9FD31B10CC1AD070073837D /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */; };
		F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8708F27A3D005CB29B /* tkUnixKey.c */; };
		F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9108F27A3D005CB29B /* tkUnixXId.c */; };
		F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8508F27A3D005CB29B /* tkUnixInit.c */; };
		F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */; };
		F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8F08F27A3D005CB29B /* tkUnixSend.c */; };
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
		F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32150CC1AF170073837D /* libXext.dylib */; };
		F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32160CC1AF170073837D /* libXss.dylib */; };
		F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34990CC1BB0D0073837D /* libfreetype.dylib */; };
		F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD349A0CC1BB0D0073837D /* libXft.dylib */; };
		F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tktest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tktest; sourceTree = BUILT_PRODUCTS_DIR; };
		F9099B8A0CC67D30005A9580 /* textpeer.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textpeer.tcl; sourceTree = "<group>"; };
		F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkbut.tcl; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92240290D7C620F005EC715 /* knightstour.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = knightstour.tcl; sourceTree = "<group>"; };
		F936FCD70CCD984500716967 /* ttkprogress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkprogress.tcl; sourceTree = "<group>"; };
		F936FCD80CCD984600716967 /* tree.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tree.tcl; sourceTree = "<group>"; };
		F936FCD90CCD984600716967 /* toolbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = toolbar.tcl; sourceTree = "<group>"; };
		F936FCDA0CCD984600716967 /* ttknote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttknote.tcl; sourceTree = "<group>"; };
		F936FCDB0CCD984600716967 /* combo.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combo.tcl; sourceTree = "<group>"; };
		F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXFont.h; sourceTree = "<group>"; };
		F94523A10E6FC2AC00C1D987 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
		F95D8D4B0F1715610006B020 /* Tk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Tk.icns; sourceTree = "<group>"; };
		F95D8D4C0F1715610006B020 /* Tk.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Tk.tiff; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F962F7C60DADC26200648DB8 /* vsapi.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vsapi.test; sourceTree = "<group>"; };
		F966BA0408F27A37005CB29B /* error.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = error.xbm; sourceTree = "<group>"; };
		F966BA0508F27A37005CB29B /* gray12.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray12.xbm; sourceTree = "<group>"; };
		F966BA0608F27A37005CB29B /* gray25.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray25.xbm; sourceTree = "<group>"; };
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
		F966BA1808F27A37005CB29B /* button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = button.n; sourceTree = "<group>"; };
		F966BA1908F27A37005CB29B /* canvas.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = canvas.n; sourceTree = "<group>"; };
		F966BA1A08F27A37005CB29B /* CanvPsY.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvPsY.3; sourceTree = "<group>"; };
		F966BA1B08F27A37005CB29B /* CanvTkwin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTkwin.3; sourceTree = "<group>"; };
		F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTxtInfo.3; sourceTree = "<group>"; };
		F966BA1D08F27A37005CB29B /* checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = checkbutton.n; sourceTree = "<group>"; };
		F966BA1E08F27A37005CB29B /* chooseColor.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseColor.n; sourceTree = "<group>"; };
		F966BA1F08F27A37005CB29B /* chooseDirectory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseDirectory.n; sourceTree = "<group>"; };
		F966BA2008F27A37005CB29B /* Clipboard.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Clipboard.3; sourceTree = "<group>"; };
		F966BA2108F27A37005CB29B /* clipboard.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clipboard.n; sourceTree = "<group>"; };
		F966BA2208F27A37005CB29B /* ClrSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ClrSelect.3; sourceTree = "<group>"; };
		F966BA2308F27A37005CB29B /* colors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = colors.n; sourceTree = "<group>"; };
		F966BA2408F27A37005CB29B /* ConfigWidg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWidg.3; sourceTree = "<group>"; };
		F966BA2508F27A37005CB29B /* ConfigWind.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWind.3; sourceTree = "<group>"; };
		F966BA2608F27A37005CB29B /* console.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = console.n; sourceTree = "<group>"; };
		F966BA2708F27A37005CB29B /* CoordToWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CoordToWin.3; sourceTree = "<group>"; };
		F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCmHdlr.3; sourceTree = "<group>"; };
		F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtErrHdlr.3; sourceTree = "<group>"; };
		F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtGenHdlr.3; sourceTree = "<group>"; };
		F966BA2B08F27A37005CB29B /* CrtImgType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtImgType.3; sourceTree = "<group>"; };
		F966BA2C08F27A37005CB29B /* CrtItemType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtItemType.3; sourceTree = "<group>"; };
		F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtPhImgFmt.3; sourceTree = "<group>"; };
		F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSelHdlr.3; sourceTree = "<group>"; };
		F966BA2F08F27A37005CB29B /* CrtWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtWindow.3; sourceTree = "<group>"; };
		F966BA3008F27A37005CB29B /* cursors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cursors.n; sourceTree = "<group>"; };
		F966BA3108F27A37005CB29B /* DeleteImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DeleteImg.3; sourceTree = "<group>"; };
		F966BA3208F27A37005CB29B /* destroy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = destroy.n; sourceTree = "<group>"; };
		F966BA3308F27A37005CB29B /* dialog.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dialog.n; sourceTree = "<group>"; };
		F966BA3408F27A37005CB29B /* DrawFocHlt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DrawFocHlt.3; sourceTree = "<group>"; };
		F966BA3508F27A37005CB29B /* entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = entry.n; sourceTree = "<group>"; };
		F966BA3608F27A37005CB29B /* event.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = event.n; sourceTree = "<group>"; };
		F966BA3708F27A37005CB29B /* EventHndlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = EventHndlr.3; sourceTree = "<group>"; };
		F966BA3808F27A37005CB29B /* FindPhoto.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindPhoto.3; sourceTree = "<group>"; };
		F966BA3908F27A37005CB29B /* focus.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focus.n; sourceTree = "<group>"; };
		F966BA3A08F27A37005CB29B /* focusNext.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focusNext.n; sourceTree = "<group>"; };
		F966BA3B08F27A37005CB29B /* font.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = font.n; sourceTree = "<group>"; };
		F966BA3C08F27A37005CB29B /* FontId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FontId.3; sourceTree = "<group>"; };
		F966BA3D08F27A37005CB29B /* frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = frame.n; sourceTree = "<group>"; };
		F966BA3E08F27A37005CB29B /* FreeXId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FreeXId.3; sourceTree = "<group>"; };
		F966BA3F08F27A37005CB29B /* GeomReq.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GeomReq.3; sourceTree = "<group>"; };
		F966BA4008F27A37005CB29B /* GetAnchor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetAnchor.3; sourceTree = "<group>"; };
		F966BA4108F27A37005CB29B /* GetBitmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetBitmap.3; sourceTree = "<group>"; };
		F966BA4208F27A37005CB29B /* GetCapStyl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCapStyl.3; sourceTree = "<group>"; };
		F966BA4308F27A37005CB29B /* GetClrmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetClrmap.3; sourceTree = "<group>"; };
		F966BA4408F27A37005CB29B /* GetColor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetColor.3; sourceTree = "<group>"; };
		F966BA4508F27A37005CB29B /* GetCursor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCursor.3; sourceTree = "<group>"; };
		F966BA4608F27A37005CB29B /* GetDash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetDash.3; sourceTree = "<group>"; };
		F966BA4708F27A37005CB29B /* GetFont.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetFont.3; sourceTree = "<group>"; };
		F966BA4808F27A37005CB29B /* GetGC.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetGC.3; sourceTree = "<group>"; };
		F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHINSTANCE.3; sourceTree = "<group>"; };
		F966BA4A08F27A37005CB29B /* GetHWND.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHWND.3; sourceTree = "<group>"; };
		F966BA4B08F27A37005CB29B /* GetImage.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetImage.3; sourceTree = "<group>"; };
		F966BA4C08F27A37005CB29B /* GetJoinStl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJoinStl.3; sourceTree = "<group>"; };
		F966BA4D08F27A37005CB29B /* GetJustify.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJustify.3; sourceTree = "<group>"; };
		F966BA4E08F27A37005CB29B /* getOpenFile.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = getOpenFile.n; sourceTree = "<group>"; };
		F966BA4F08F27A37005CB29B /* GetOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOption.3; sourceTree = "<group>"; };
		F966BA5008F27A38005CB29B /* GetPixels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixels.3; sourceTree = "<group>"; };
		F966BA5108F27A38005CB29B /* GetPixmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixmap.3; sourceTree = "<group>"; };
		F966BA5208F27A38005CB29B /* GetRelief.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRelief.3; sourceTree = "<group>"; };
		F966BA5308F27A38005CB29B /* GetRootCrd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRootCrd.3; sourceTree = "<group>"; };
		F966BA5408F27A38005CB29B /* GetScroll.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetScroll.3; sourceTree = "<group>"; };
		F966BA5508F27A38005CB29B /* GetSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetSelect.3; sourceTree = "<group>"; };
		F966BA5608F27A38005CB29B /* GetUid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetUid.3; sourceTree = "<group>"; };
		F966BA5708F27A38005CB29B /* GetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVisual.3; sourceTree = "<group>"; };
		F966BA5808F27A38005CB29B /* GetVRoot.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVRoot.3; sourceTree = "<group>"; };
		F966BA5908F27A38005CB29B /* Grab.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Grab.3; sourceTree = "<group>"; };
		F966BA5A08F27A38005CB29B /* grab.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grab.n; sourceTree = "<group>"; };
		F966BA5B08F27A38005CB29B /* grid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grid.n; sourceTree = "<group>"; };
		F966BA5C08F27A38005CB29B /* HandleEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HandleEvent.3; sourceTree = "<group>"; };
		F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HWNDToWindow.3; sourceTree = "<group>"; };
		F966BA5E08F27A38005CB29B /* IdToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IdToWindow.3; sourceTree = "<group>"; };
		F966BA5F08F27A38005CB29B /* image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = image.n; sourceTree = "<group>"; };
		F966BA6008F27A38005CB29B /* ImgChanged.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ImgChanged.3; sourceTree = "<group>"; };
		F966BA6108F27A38005CB29B /* Inactive.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Inactive.3; sourceTree = "<group>"; };
		F966BA6208F27A38005CB29B /* InternAtom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InternAtom.3; sourceTree = "<group>"; };
		F966BA6308F27A38005CB29B /* keysyms.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = keysyms.n; sourceTree = "<group>"; };
		F966BA6408F27A38005CB29B /* label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = label.n; sourceTree = "<group>"; };
		F966BA6508F27A38005CB29B /* labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = labelframe.n; sourceTree = "<group>"; };
		F966BA6608F27A38005CB29B /* listbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = listbox.n; sourceTree = "<group>"; };
		F966BA6708F27A38005CB29B /* loadTk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = loadTk.n; sourceTree = "<group>"; };
		F966BA6808F27A38005CB29B /* lower.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lower.n; sourceTree = "<group>"; };
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
		F966BA8408F27A38005CB29B /* QWinEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = QWinEvent.3; sourceTree = "<group>"; };
		F966BA8508F27A38005CB29B /* radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = radiobutton.n; sourceTree = "<group>"; };
		F966BA8608F27A38005CB29B /* raise.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = raise.n; sourceTree = "<group>"; };
		F966BA8708F27A38005CB29B /* Restack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Restack.3; sourceTree = "<group>"; };
		F966BA8808F27A38005CB29B /* RestrictEv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RestrictEv.3; sourceTree = "<group>"; };
		F966BA8908F27A38005CB29B /* scale.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scale.n; sourceTree = "<group>"; };
		F966BA8A08F27A38005CB29B /* scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scrollbar.n; sourceTree = "<group>"; };
		F966BA8B08F27A38005CB29B /* selection.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = selection.n; sourceTree = "<group>"; };
		F966BA8C08F27A38005CB29B /* send.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = send.n; sourceTree = "<group>"; };
		F966BA8D08F27A38005CB29B /* SetAppName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetAppName.3; sourceTree = "<group>"; };
		F966BA8E08F27A38005CB29B /* SetCaret.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetCaret.3; sourceTree = "<group>"; };
		F966BA8F08F27A38005CB29B /* SetClass.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClass.3; sourceTree = "<group>"; };
		F966BA9008F27A38005CB29B /* SetClassProcs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClassProcs.3; sourceTree = "<group>"; };
		F966BA9108F27A38005CB29B /* SetGrid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetGrid.3; sourceTree = "<group>"; };
		F966BA9208F27A38005CB29B /* SetOptions.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetOptions.3; sourceTree = "<group>"; };
		F966BA9308F27A38005CB29B /* SetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVisual.3; sourceTree = "<group>"; };
		F966BA9408F27A38005CB29B /* spinbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = spinbox.n; sourceTree = "<group>"; };
		F966BA9508F27A38005CB29B /* StrictMotif.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrictMotif.3; sourceTree = "<group>"; };
		F966BA9608F27A38005CB29B /* text.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = text.n; sourceTree = "<group>"; };
		F966BA9708F27A38005CB29B /* TextLayout.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TextLayout.3; sourceTree = "<group>"; };
		F966BA9808F27A38005CB29B /* tk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tk.n; sourceTree = "<group>"; };
		F966BA9908F27A38005CB29B /* tk4.0.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = tk4.0.ps; sourceTree = "<group>"; };
		F966BA9A08F27A38005CB29B /* Tk_Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Init.3; sourceTree = "<group>"; };
		F966BA9B08F27A38005CB29B /* Tk_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Main.3; sourceTree = "<group>"; };
		F966BA9C08F27A38005CB29B /* tkerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkerror.n; sourceTree = "<group>"; };
		F966BA9D08F27A38005CB29B /* TkInitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TkInitStubs.3; sourceTree = "<group>"; };
		F966BA9E08F27A38005CB29B /* tkvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkvars.n; sourceTree = "<group>"; };
		F966BA9F08F27A38005CB29B /* tkwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkwait.n; sourceTree = "<group>"; };
		F966BAA008F27A38005CB29B /* toplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = toplevel.n; sourceTree = "<group>"; };
		F966BAA108F27A38005CB29B /* WindowId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WindowId.3; sourceTree = "<group>"; };
		F966BAA208F27A38005CB29B /* winfo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = winfo.n; sourceTree = "<group>"; };
		F966BAA308F27A38005CB29B /* wish.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wish.1; sourceTree = "<group>"; };
		F966BAA408F27A38005CB29B /* wm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wm.n; sourceTree = "<group>"; };
		F966BAA608F27A38005CB29B /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = "<group>"; };
		F966BAA708F27A38005CB29B /* ks_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ks_names.h; sourceTree = "<group>"; };
		F966BAA808F27A38005CB29B /* prolog.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = prolog.ps; sourceTree = "<group>"; };
		F966BAA908F27A39005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BAAA08F27A39005CB29B /* tk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.decls; sourceTree = "<group>"; };
		F966BAAB08F27A39005CB29B /* tk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk.h; sourceTree = "<group>"; };
		F966BAAC08F27A39005CB29B /* tk3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tk3d.c; sourceTree = "<group>"; };
		F966BAAD08F27A39005CB29B /* tk3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk3d.h; sourceTree = "<group>"; };
		F966BAAE08F27A39005CB29B /* tkArgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkArgv.c; sourceTree = "<group>"; };
		F966BAAF08F27A39005CB29B /* tkAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAtom.c; sourceTree = "<group>"; };
		F966BAB008F27A39005CB29B /* tkBind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBind.c; sourceTree = "<group>"; };
		F966BAB108F27A39005CB29B /* tkBitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBitmap.c; sourceTree = "<group>"; };
		F966BAB208F27A39005CB29B /* tkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkButton.c; sourceTree = "<group>"; };
		F966BAB308F27A39005CB29B /* tkButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkButton.h; sourceTree = "<group>"; };
		F966BAB408F27A39005CB29B /* tkCanvArc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvArc.c; sourceTree = "<group>"; };
		F966BAB508F27A39005CB29B /* tkCanvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvas.c; sourceTree = "<group>"; };
		F966BAB608F27A39005CB29B /* tkCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkCanvas.h; sourceTree = "<group>"; };
		F966BAB708F27A39005CB29B /* tkCanvBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvBmap.c; sourceTree = "<group>"; };
		F966BAB808F27A39005CB29B /* tkCanvImg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvImg.c; sourceTree = "<group>"; };
		F966BAB908F27A39005CB29B /* tkCanvLine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvLine.c; sourceTree = "<group>"; };
		F966BABA08F27A39005CB29B /* tkCanvPoly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPoly.c; sourceTree = "<group>"; };
		F966BABB08F27A39005CB29B /* tkCanvPs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPs.c; sourceTree = "<group>"; };
		F966BABD08F27A39005CB29B /* tkCanvText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvText.c; sourceTree = "<group>"; };
		F966BABE08F27A39005CB29B /* tkCanvUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvUtil.c; sourceTree = "<group>"; };
		F966BABF08F27A39005CB29B /* tkCanvWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvWind.c; sourceTree = "<group>"; };
		F966BAC008F27A39005CB29B /* tkClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkClipboard.c; sourceTree = "<group>"; };
		F966BAC108F27A39005CB29B /* tkCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCmds.c; sourceTree = "<group>"; };
		F966BAC208F27A39005CB29B /* tkColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkColor.c; sourceTree = "<group>"; };
		F966BAC308F27A39005CB29B /* tkColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkColor.h; sourceTree = "<group>"; };
		F966BAC408F27A39005CB29B /* tkConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConfig.c; sourceTree = "<group>"; };
		F966BAC508F27A39005CB29B /* tkConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConsole.c; sourceTree = "<group>"; };
		F966BAC608F27A39005CB29B /* tkCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCursor.c; sourceTree = "<group>"; };
		F966BAC708F27A39005CB29B /* tkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkDecls.h; sourceTree = "<group>"; };
		F966BAC808F27A39005CB29B /* tkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEntry.c; sourceTree = "<group>"; };
		F966BAC908F27A39005CB29B /* tkEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkEntry.h; sourceTree = "<group>"; };
		F966BACA08F27A39005CB29B /* tkError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkError.c; sourceTree = "<group>"; };
		F966BACB08F27A39005CB29B /* tkEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEvent.c; sourceTree = "<group>"; };
		F966BACC08F27A39005CB29B /* tkFileFilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFileFilter.c; sourceTree = "<group>"; };
		F966BACD08F27A39005CB29B /* tkFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFileFilter.h; sourceTree = "<group>"; };
		F966BACE08F27A39005CB29B /* tkFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFocus.c; sourceTree = "<group>"; };
		F966BACF08F27A39005CB29B /* tkFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFont.c; sourceTree = "<group>"; };
		F966BAD008F27A39005CB29B /* tkFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFont.h; sourceTree = "<group>"; };
		F966BAD108F27A39005CB29B /* tkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFrame.c; sourceTree = "<group>"; };
		F966BAD208F27A39005CB29B /* tkGC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGC.c; sourceTree = "<group>"; };
		F966BAD308F27A39005CB29B /* tkGeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGeometry.c; sourceTree = "<group>"; };
		F966BAD408F27A39005CB29B /* tkGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGet.c; sourceTree = "<group>"; };
		F966BAD508F27A39005CB29B /* tkGrab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrab.c; sourceTree = "<group>"; };
		F966BAD608F27A39005CB29B /* tkGrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrid.c; sourceTree = "<group>"; };
		F966BAD708F27A39005CB29B /* tkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImage.c; sourceTree = "<group>"; };
		F966BAD808F27A39005CB29B /* tkImgBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgBmap.c; sourceTree = "<group>"; };
		F966BAD908F27A39005CB29B /* tkImgGIF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgGIF.c; sourceTree = "<group>"; };
		F966BADA08F27A39005CB29B /* tkImgPhoto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhoto.c; sourceTree = "<group>"; };
		F966BADB08F27A39005CB29B /* tkImgPPM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPPM.c; sourceTree = "<group>"; };
		F966BADC08F27A39005CB29B /* tkImgUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgUtil.c; sourceTree = "<group>"; };
		F966BADE08F27A39005CB29B /* tkInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkInt.decls; sourceTree = "<group>"; };
		F966BADF08F27A39005CB29B /* tkInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkInt.h; sourceTree = "<group>"; };
		F966BAE108F27A39005CB29B /* tkIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntDecls.h; sourceTree = "<group>"; };
		F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntPlatDecls.h; sourceTree = "<group>"; };
		F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntXlibDecls.h; sourceTree = "<group>"; };
		F966BAE408F27A39005CB29B /* tkListbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkListbox.c; sourceTree = "<group>"; };
		F966BAE508F27A39005CB29B /* tkMacWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacWinMenu.c; sourceTree = "<group>"; };
		F966BAE608F27A39005CB29B /* tkMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMain.c; sourceTree = "<group>"; };
		F966BAE708F27A39005CB29B /* tkMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenu.c; sourceTree = "<group>"; };
		F966BAE808F27A39005CB29B /* tkMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenu.h; sourceTree = "<group>"; };
		F966BAE908F27A39005CB29B /* tkMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenubutton.c; sourceTree = "<group>"; };
		F966BAEA08F27A39005CB29B /* tkMenubutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenubutton.h; sourceTree = "<group>"; };
		F966BAEB08F27A39005CB29B /* tkMenuDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenuDraw.c; sourceTree = "<group>"; };
		F966BAEC08F27A39005CB29B /* tkMessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMessage.c; sourceTree = "<group>"; };
		F966BAED08F27A39005CB29B /* tkObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkObj.c; sourceTree = "<group>"; };
		F966BAEE08F27A39005CB29B /* tkOldConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldConfig.c; sourceTree = "<group>"; };
		F966BAEF08F27A39005CB29B /* tkOption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOption.c; sourceTree = "<group>"; };
		F966BAF008F27A39005CB29B /* tkPack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPack.c; sourceTree = "<group>"; };
		F966BAF108F27A39005CB29B /* tkPanedWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPanedWindow.c; sourceTree = "<group>"; };
		F966BAF208F27A39005CB29B /* tkPlace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPlace.c; sourceTree = "<group>"; };
		F966BAF308F27A39005CB29B /* tkPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPlatDecls.h; sourceTree = "<group>"; };
		F966BAF408F27A39005CB29B /* tkPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPointer.c; sourceTree = "<group>"; };
		F966BAF508F27A39005CB29B /* tkPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPort.h; sourceTree = "<group>"; };
		F966BAF608F27A39005CB29B /* tkRectOval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkRectOval.c; sourceTree = "<group>"; };
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
		F966BB0608F27A39005CB29B /* tkTextDisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextDisp.c; sourceTree = "<group>"; };
		F966BB0808F27A39005CB29B /* tkTextImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextImage.c; sourceTree = "<group>"; };
		F966BB0908F27A39005CB29B /* tkTextIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextIndex.c; sourceTree = "<group>"; };
		F966BB0A08F27A39005CB29B /* tkTextMark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextMark.c; sourceTree = "<group>"; };
		F966BB0B08F27A39005CB29B /* tkTextTag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextTag.c; sourceTree = "<group>"; };
		F966BB0C08F27A39005CB29B /* tkTextWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextWind.c; sourceTree = "<group>"; };
		F966BB0D08F27A39005CB29B /* tkTrig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTrig.c; sourceTree = "<group>"; };
		F966BB0E08F27A39005CB29B /* tkUndo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUndo.c; sourceTree = "<group>"; };
		F966BB0F08F27A39005CB29B /* tkUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUndo.h; sourceTree = "<group>"; };
		F966BB1008F27A39005CB29B /* tkUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUtil.c; sourceTree = "<group>"; };
		F966BB1108F27A39005CB29B /* tkVisual.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkVisual.c; sourceTree = "<group>"; };
		F966BB1208F27A39005CB29B /* tkWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWindow.c; sourceTree = "<group>"; };
		F966BB1408F27A39005CB29B /* bgerror.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.tcl; sourceTree = "<group>"; };
		F966BB1508F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB1608F27A39005CB29B /* choosedir.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.tcl; sourceTree = "<group>"; };
		F966BB1708F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB1808F27A39005CB29B /* comdlg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = comdlg.tcl; sourceTree = "<group>"; };
		F966BB1908F27A39005CB29B /* console.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = console.tcl; sourceTree = "<group>"; };
		F966BB1B08F27A39005CB29B /* anilabel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = anilabel.tcl; sourceTree = "<group>"; };
		F966BB1C08F27A39005CB29B /* aniwave.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aniwave.tcl; sourceTree = "<group>"; };
		F966BB1D08F27A39005CB29B /* arrow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arrow.tcl; sourceTree = "<group>"; };
		F966BB1E08F27A39005CB29B /* bind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.tcl; sourceTree = "<group>"; };
		F966BB1F08F27A39005CB29B /* bitmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.tcl; sourceTree = "<group>"; };
		F966BB2008F27A39005CB29B /* browse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = browse; sourceTree = "<group>"; };
		F966BB2108F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB2208F27A39005CB29B /* check.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = check.tcl; sourceTree = "<group>"; };
		F966BB2308F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB2408F27A39005CB29B /* colors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = colors.tcl; sourceTree = "<group>"; };
		F966BB2508F27A39005CB29B /* cscroll.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cscroll.tcl; sourceTree = "<group>"; };
		F966BB2608F27A39005CB29B /* ctext.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ctext.tcl; sourceTree = "<group>"; };
		F966BB2708F27A39005CB29B /* dialog1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog1.tcl; sourceTree = "<group>"; };
		F966BB2808F27A39005CB29B /* dialog2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog2.tcl; sourceTree = "<group>"; };
		F966BB2A08F27A39005CB29B /* entry1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry1.tcl; sourceTree = "<group>"; };
		F966BB2B08F27A39005CB29B /* entry2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry2.tcl; sourceTree = "<group>"; };
		F966BB2C08F27A39005CB29B /* entry3.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry3.tcl; sourceTree = "<group>"; };
		F966BB2D08F27A39005CB29B /* filebox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.tcl; sourceTree = "<group>"; };
		F966BB2E08F27A39005CB29B /* floor.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = floor.tcl; sourceTree = "<group>"; };
		F966BB2F08F27A39005CB29B /* form.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = form.tcl; sourceTree = "<group>"; };
		F966BB3008F27A39005CB29B /* goldberg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = goldberg.tcl; sourceTree = "<group>"; };
		F966BB3108F27A39005CB29B /* hello */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = hello; sourceTree = "<group>"; };
		F966BB3208F27A39005CB29B /* hscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = hscale.tcl; sourceTree = "<group>"; };
		F966BB3308F27A39005CB29B /* icon.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icon.tcl; sourceTree = "<group>"; };
		F966BB3408F27A39005CB29B /* image1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image1.tcl; sourceTree = "<group>"; };
		F966BB3508F27A39005CB29B /* image2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image2.tcl; sourceTree = "<group>"; };
		F966BB4208F27A3A005CB29B /* items.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = items.tcl; sourceTree = "<group>"; };
		F966BB4308F27A3A005CB29B /* ixset */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ixset; sourceTree = "<group>"; };
		F966BB4408F27A3A005CB29B /* label.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = label.tcl; sourceTree = "<group>"; };
		F966BB4508F27A3A005CB29B /* labelframe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.tcl; sourceTree = "<group>"; };
		F966BB4608F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB4708F27A3A005CB29B /* menubu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubu.tcl; sourceTree = "<group>"; };
		F966BB4808F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB4A08F27A3A005CB29B /* paned1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned1.tcl; sourceTree = "<group>"; };
		F966BB4B08F27A3A005CB29B /* paned2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned2.tcl; sourceTree = "<group>"; };
		F966BB4C08F27A3A005CB29B /* pendulum.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pendulum.tcl; sourceTree = "<group>"; };
		F966BB4D08F27A3A005CB29B /* plot.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = plot.tcl; sourceTree = "<group>"; };
		F966BB4E08F27A3A005CB29B /* puzzle.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = puzzle.tcl; sourceTree = "<group>"; };
		F966BB4F08F27A3A005CB29B /* radio.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radio.tcl; sourceTree = "<group>"; };
		F966BB5008F27A3A005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BB5108F27A3A005CB29B /* rmt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rmt; sourceTree = "<group>"; };
		F966BB5208F27A3A005CB29B /* rolodex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rolodex; sourceTree = "<group>"; };
		F966BB5308F27A3A005CB29B /* ruler.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ruler.tcl; sourceTree = "<group>"; };
		F966BB5408F27A3A005CB29B /* sayings.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sayings.tcl; sourceTree = "<group>"; };
		F966BB5508F27A3A005CB29B /* search.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = search.tcl; sourceTree = "<group>"; };
		F966BB5608F27A3A005CB29B /* spin.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spin.tcl; sourceTree = "<group>"; };
		F966BB5708F27A3A005CB29B /* square */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = square; sourceTree = "<group>"; };
		F966BB5808F27A3A005CB29B /* states.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = states.tcl; sourceTree = "<group>"; };
		F966BB5908F27A3A005CB29B /* style.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = style.tcl; sourceTree = "<group>"; };
		F966BB5A08F27A3A005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB5B08F27A3A005CB29B /* tcolor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tcolor; sourceTree = "<group>"; };
		F966BB5C08F27A3A005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB5D08F27A3A005CB29B /* timer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = timer; sourceTree = "<group>"; };
		F966BB5E08F27A3A005CB29B /* twind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = twind.tcl; sourceTree = "<group>"; };
		F966BB5F08F27A3A005CB29B /* unicodeout.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unicodeout.tcl; sourceTree = "<group>"; };
		F966BB6008F27A3A005CB29B /* vscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vscale.tcl; sourceTree = "<group>"; };
		F966BB6108F27A3A005CB29B /* widget */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = widget; sourceTree = "<group>"; };
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8A08F27A3B005CB29B /* prolog.ps */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = prolog.ps; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
		F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXBitmap.c; sourceTree = "<group>"; };
		F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXButton.c; sourceTree = "<group>"; };
		F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXClipboard.c; sourceTree = "<group>"; };
		F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXColor.c; sourceTree = "<group>"; };
		F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXConfig.c; sourceTree = "<group>"; };
		F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXCursor.c; sourceTree = "<group>"; };
		F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXCursors.h; sourceTree = "<group>"; };
		F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDebug.c; sourceTree = "<group>"; };
		F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDebug.h; sourceTree = "<group>"; };
		F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDefault.h; sourceTree = "<group>"; };
		F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDialog.c; sourceTree = "<group>"; };
		F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDraw.c; sourceTree = "<group>"; };
		F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEmbed.c; sourceTree = "<group>"; };
		F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEntry.c; sourceTree = "<group>"; };
		F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEvent.c; sourceTree = "<group>"; };
		F966BBD508F27A3B005CB29B /* tkMacOSXEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXEvent.h; sourceTree = "<group>"; };
		F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXFont.c; sourceTree = "<group>"; };
		F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXHLEvents.c; sourceTree = "<group>"; };
		F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXInit.c; sourceTree = "<group>"; };
		F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXInt.h; sourceTree = "<group>"; };
		F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; };
		F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; };
		F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenu.c; sourceTree = "<group>"; };
		F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; };
		F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenus.c; sourceTree = "<group>"; };
		F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; };
		F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXNotify.c; sourceTree = "<group>"; };
		F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPort.h; sourceTree = "<group>"; };
		F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXRegion.c; sourceTree = "<group>"; };
		F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScale.c; sourceTree = "<group>"; };
		F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScrlbr.c; sourceTree = "<group>"; };
		F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSend.c; sourceTree = "<group>"; };
		F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSubwindows.c; sourceTree = "<group>"; };
		F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXTest.c; sourceTree = "<group>"; };
		F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWindowEvent.c; sourceTree = "<group>"; };
		F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWm.c; sourceTree = "<group>"; };
		F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXWm.h; sourceTree = "<group>"; };
		F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXXCursors.h; sourceTree = "<group>"; };
		F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXXStubs.c; sourceTree = "<group>"; };
		F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Wish-Info.plist.in"; sourceTree = "<group>"; };
		F966BC0308F27A3C005CB29B /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F966BC0508F27A3C005CB29B /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F966BC0608F27A3C005CB29B /* arc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arc.tcl; sourceTree = "<group>"; };
		F966BC0708F27A3C005CB29B /* bell.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bell.test; sourceTree = "<group>"; };
		F966BC0808F27A3C005CB29B /* bevel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bevel.tcl; sourceTree = "<group>"; };
		F966BC0908F27A3C005CB29B /* bgerror.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.test; sourceTree = "<group>"; };
		F966BC0A08F27A3C005CB29B /* bind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.test; sourceTree = "<group>"; };
		F966BC0B08F27A3C005CB29B /* bitmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.test; sourceTree = "<group>"; };
		F966BC0C08F27A3C005CB29B /* border.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = border.test; sourceTree = "<group>"; };
		F966BC0D08F27A3C005CB29B /* bugs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bugs.tcl; sourceTree = "<group>"; };
		F966BC0E08F27A3C005CB29B /* butGeom.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom.tcl; sourceTree = "<group>"; };
		F966BC0F08F27A3C005CB29B /* butGeom2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom2.tcl; sourceTree = "<group>"; };
		F966BC1008F27A3C005CB29B /* button.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.test; sourceTree = "<group>"; };
		F966BC1108F27A3C005CB29B /* canvas.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvas.test; sourceTree = "<group>"; };
		F966BC1208F27A3C005CB29B /* canvImg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvImg.test; sourceTree = "<group>"; };
		F966BC1308F27A3C005CB29B /* canvPs.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPs.test; sourceTree = "<group>"; };
		F966BC1408F27A3C005CB29B /* canvPsArc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsArc.tcl; sourceTree = "<group>"; };
		F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsBmap.tcl; sourceTree = "<group>"; };
		F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsGrph.tcl; sourceTree = "<group>"; };
		F966BC1708F27A3C005CB29B /* canvPsImg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsImg.tcl; sourceTree = "<group>"; };
		F966BC1808F27A3C005CB29B /* canvPsText.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsText.tcl; sourceTree = "<group>"; };
		F966BC1908F27A3C005CB29B /* canvRect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvRect.test; sourceTree = "<group>"; };
		F966BC1A08F27A3C005CB29B /* canvText.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvText.test; sourceTree = "<group>"; };
		F966BC1B08F27A3C005CB29B /* canvWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvWind.test; sourceTree = "<group>"; };
		F966BC1C08F27A3C005CB29B /* choosedir.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.test; sourceTree = "<group>"; };
		F966BC1D08F27A3C005CB29B /* clipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clipboard.test; sourceTree = "<group>"; };
		F966BC1E08F27A3C005CB29B /* clrpick.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.test; sourceTree = "<group>"; };
		F966BC1F08F27A3C005CB29B /* cmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmap.tcl; sourceTree = "<group>"; };
		F966BC2008F27A3C005CB29B /* cmds.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmds.test; sourceTree = "<group>"; };
		F966BC2108F27A3C005CB29B /* color.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = color.test; sourceTree = "<group>"; };
		F966BC2208F27A3C005CB29B /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F966BC2308F27A3C005CB29B /* constraints.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = constraints.tcl; sourceTree = "<group>"; };
		F966BC2408F27A3C005CB29B /* cursor.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursor.test; sourceTree = "<group>"; };
		F966BC2508F27A3C005CB29B /* dialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.test; sourceTree = "<group>"; };
		F966BC2608F27A3C005CB29B /* embed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = embed.test; sourceTree = "<group>"; };
		F966BC2708F27A3C005CB29B /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F966BC2808F27A3C005CB29B /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F966BC2908F27A3C005CB29B /* filebox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.test; sourceTree = "<group>"; };
		F966BC2A08F27A3C005CB29B /* focus.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.test; sourceTree = "<group>"; };
		F966BC2B08F27A3C005CB29B /* focusTcl.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focusTcl.test; sourceTree = "<group>"; };
		F966BC2C08F27A3C005CB29B /* font.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = font.test; sourceTree = "<group>"; };
		F966BC2D08F27A3C005CB29B /* frame.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = frame.test; sourceTree = "<group>"; };
		F966BC2E08F27A3C005CB29B /* geometry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = geometry.test; sourceTree = "<group>"; };
		F966BC2F08F27A3C005CB29B /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F966BC3008F27A3C005CB29B /* grab.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grab.test; sourceTree = "<group>"; };
		F966BC3108F27A3C005CB29B /* grid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grid.test; sourceTree = "<group>"; };
		F966BC3208F27A3C005CB29B /* id.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = id.test; sourceTree = "<group>"; };
		F966BC3308F27A3C005CB29B /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F966BC3408F27A3C005CB29B /* imgBmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgBmap.test; sourceTree = "<group>"; };
		F966BC3508F27A3C005CB29B /* imgPhoto.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPhoto.test; sourceTree = "<group>"; };
		F966BC3608F27A3C005CB29B /* imgPPM.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPPM.test; sourceTree = "<group>"; };
		F966BC3708F27A3C005CB29B /* listbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.test; sourceTree = "<group>"; };
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
		F966BC4708F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC4808F27A3D005CB29B /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F966BC4908F27A3D005CB29B /* scale.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.test; sourceTree = "<group>"; };
		F966BC4A08F27A3D005CB29B /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F966BC4B08F27A3D005CB29B /* select.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = select.test; sourceTree = "<group>"; };
		F966BC4C08F27A3D005CB29B /* send.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = send.test; sourceTree = "<group>"; };
		F966BC4D08F27A3D005CB29B /* spinbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.test; sourceTree = "<group>"; };
		F966BC4E08F27A3D005CB29B /* text.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.test; sourceTree = "<group>"; };
		F966BC4F08F27A3D005CB29B /* textBTree.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textBTree.test; sourceTree = "<group>"; };
		F966BC5008F27A3D005CB29B /* textDisp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textDisp.test; sourceTree = "<group>"; };
		F966BC5108F27A3D005CB29B /* textImage.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textImage.test; sourceTree = "<group>"; };
		F966BC5208F27A3D005CB29B /* textIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textIndex.test; sourceTree = "<group>"; };
		F966BC5308F27A3D005CB29B /* textMark.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textMark.test; sourceTree = "<group>"; };
		F966BC5408F27A3D005CB29B /* textTag.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textTag.test; sourceTree = "<group>"; };
		F966BC5508F27A3D005CB29B /* textWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textWind.test; sourceTree = "<group>"; };
		F966BC5608F27A3D005CB29B /* tk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.test; sourceTree = "<group>"; };
		F966BC5708F27A3D005CB29B /* unixButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixButton.test; sourceTree = "<group>"; };
		F966BC5808F27A3D005CB29B /* unixEmbed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixEmbed.test; sourceTree = "<group>"; };
		F966BC5908F27A3D005CB29B /* unixFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFont.test; sourceTree = "<group>"; };
		F966BC5A08F27A3D005CB29B /* unixMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixMenu.test; sourceTree = "<group>"; };
		F966BC5B08F27A3D005CB29B /* unixSelect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixSelect.test; sourceTree = "<group>"; };
		F966BC5C08F27A3D005CB29B /* unixWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixWm.test; sourceTree = "<group>"; };
		F966BC5D08F27A3D005CB29B /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F966BC5E08F27A3D005CB29B /* visual.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual.test; sourceTree = "<group>"; };
		F966BC5F08F27A3D005CB29B /* visual_bb.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual_bb.test; sourceTree = "<group>"; };
		F966BC6008F27A3D005CB29B /* winButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winButton.test; sourceTree = "<group>"; };
		F966BC6108F27A3D005CB29B /* winClipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winClipboard.test; sourceTree = "<group>"; };
		F966BC6208F27A3D005CB29B /* winDialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDialog.test; sourceTree = "<group>"; };
		F966BC6308F27A3D005CB29B /* window.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = window.test; sourceTree = "<group>"; };
		F966BC6408F27A3D005CB29B /* winfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winfo.test; sourceTree = "<group>"; };
		F966BC6508F27A3D005CB29B /* winFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFont.test; sourceTree = "<group>"; };
		F966BC6608F27A3D005CB29B /* winMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winMenu.test; sourceTree = "<group>"; };
		F966BC6708F27A3D005CB29B /* winSend.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winSend.test; sourceTree = "<group>"; };
		F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = "<group>"; };
		F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = "<group>"; };
		F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
		F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BC7408F27A3D005CB29B /* tk.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.spec; sourceTree = "<group>"; };
		F966BC7508F27A3D005CB29B /* tkAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAppInit.c; sourceTree = "<group>"; };
		F966BC7608F27A3D005CB29B /* tkConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tkConfig.h.in; sourceTree = "<group>"; };
		F966BC7708F27A3D005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
		F966BC8708F27A3D005CB29B /* tkUnixKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixKey.c; sourceTree = "<group>"; };
		F966BC8808F27A3D005CB29B /* tkUnixMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenu.c; sourceTree = "<group>"; };
		F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenubu.c; sourceTree = "<group>"; };
		F966BC8A08F27A3D005CB29B /* tkUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixPort.h; sourceTree = "<group>"; };
		F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixRFont.c; sourceTree = "<group>"; };
		F966BC8C08F27A3D005CB29B /* tkUnixScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScale.c; sourceTree = "<group>"; };
		F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScrlbr.c; sourceTree = "<group>"; };
		F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSelect.c; sourceTree = "<group>"; };
		F966BC8F08F27A3D005CB29B /* tkUnixSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSend.c; sourceTree = "<group>"; };
		F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = "<group>"; };
		F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = "<group>"; };
		F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
		F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F966BC9B08F27A3E005CB29B /* mkd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mkd.bat; sourceTree = "<group>"; };
		F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = "<group>"; };
		F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = "<group>"; };
		F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = "<group>"; };
		F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BCF408F27A3E005CB29B /* rmd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rmd.bat; sourceTree = "<group>"; };
		F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = "<group>"; };
		F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = "<group>"; };
		F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin32Dll.c; sourceTree = "<group>"; };
		F966BCFB08F27A3F005CB29B /* tkWin3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin3d.c; sourceTree = "<group>"; };
		F966BCFC08F27A3F005CB29B /* tkWinButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinButton.c; sourceTree = "<group>"; };
		F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinClipboard.c; sourceTree = "<group>"; };
		F966BCFE08F27A3F005CB29B /* tkWinColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinColor.c; sourceTree = "<group>"; };
		F966BCFF08F27A3F005CB29B /* tkWinConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinConfig.c; sourceTree = "<group>"; };
		F966BD0008F27A3F005CB29B /* tkWinCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinCursor.c; sourceTree = "<group>"; };
		F966BD0108F27A3F005CB29B /* tkWinDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinDefault.h; sourceTree = "<group>"; };
		F966BD0208F27A3F005CB29B /* tkWinDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDialog.c; sourceTree = "<group>"; };
		F966BD0308F27A3F005CB29B /* tkWinDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDraw.c; sourceTree = "<group>"; };
		F966BD0408F27A3F005CB29B /* tkWinEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinEmbed.c; sourceTree = "<group>"; };
		F966BD0508F27A3F005CB29B /* tkWinFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinFont.c; sourceTree = "<group>"; };
		F966BD0708F27A3F005CB29B /* tkWinImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinImage.c; sourceTree = "<group>"; };
		F966BD0808F27A3F005CB29B /* tkWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinInit.c; sourceTree = "<group>"; };
		F966BD0908F27A3F005CB29B /* tkWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinInt.h; sourceTree = "<group>"; };
		F966BD0A08F27A3F005CB29B /* tkWinKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinKey.c; sourceTree = "<group>"; };
		F966BD0B08F27A3F005CB29B /* tkWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinMenu.c; sourceTree = "<group>"; };
		F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPixmap.c; sourceTree = "<group>"; };
		F966BD0D08F27A3F005CB29B /* tkWinPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPointer.c; sourceTree = "<group>"; };
		F966BD0E08F27A3F005CB29B /* tkWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinPort.h; sourceTree = "<group>"; };
		F966BD0F08F27A3F005CB29B /* tkWinRegion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinRegion.c; sourceTree = "<group>"; };
		F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinScrlbr.c; sourceTree = "<group>"; };
		F966BD1108F27A3F005CB29B /* tkWinSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSend.c; sourceTree = "<group>"; };
		F966BD1208F27A3F005CB29B /* tkWinSendCom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSendCom.c; sourceTree = "<group>"; };
		F966BD1308F27A3F005CB29B /* tkWinSendCom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinSendCom.h; sourceTree = "<group>"; };
		F966BD1408F27A3F005CB29B /* tkWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinTest.c; sourceTree = "<group>"; };
		F966BD1508F27A3F005CB29B /* tkWinWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWindow.c; sourceTree = "<group>"; };
		F966BD1608F27A3F005CB29B /* tkWinWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWm.c; sourceTree = "<group>"; };
		F966BD1708F27A3F005CB29B /* tkWinX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinX.c; sourceTree = "<group>"; };
		F966BD1808F27A3F005CB29B /* winMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winMain.c; sourceTree = "<group>"; };
		F966BD1B08F27A3F005CB29B /* cursorfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorfont.h; sourceTree = "<group>"; };
		F966BD1C08F27A3F005CB29B /* keysym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysym.h; sourceTree = "<group>"; };
		F966BD1D08F27A3F005CB29B /* keysymdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysymdef.h; sourceTree = "<group>"; };
		F966BD1E08F27A3F005CB29B /* X.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X.h; sourceTree = "<group>"; };
		F966BD1F08F27A3F005CB29B /* Xatom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xatom.h; sourceTree = "<group>"; };
		F966BD2008F27A3F005CB29B /* Xfuncproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xfuncproto.h; sourceTree = "<group>"; };
		F966BD2108F27A3F005CB29B /* Xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xlib.h; sourceTree = "<group>"; };
		F966BD2208F27A3F005CB29B /* Xutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xutil.h; sourceTree = "<group>"; };
		F966BD2308F27A3F005CB29B /* xbytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbytes.h; sourceTree = "<group>"; };
		F966BD2408F27A3F005CB29B /* xcolors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xcolors.c; sourceTree = "<group>"; };
		F966BD2508F27A3F005CB29B /* xdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdraw.c; sourceTree = "<group>"; };
		F966BD2608F27A3F005CB29B /* xgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xgc.c; sourceTree = "<group>"; };
		F966BD2708F27A3F005CB29B /* ximage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ximage.c; sourceTree = "<group>"; };
		F966BD2808F27A3F005CB29B /* xutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xutil.c; sourceTree = "<group>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F966C07608F2821B005CB29B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
		F966C07808F28233005CB29B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
		F96887E00AF786D5000797B5 /* ttk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.decls; sourceTree = "<group>"; };
		F96887E10AF786D5000797B5 /* ttkBlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkBlink.c; sourceTree = "<group>"; };
		F96887E20AF786D5000797B5 /* ttkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkButton.c; sourceTree = "<group>"; };
		F96887E30AF786D5000797B5 /* ttkCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkCache.c; sourceTree = "<group>"; };
		F96887E40AF786D5000797B5 /* ttkClamTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClamTheme.c; sourceTree = "<group>"; };
		F96887E50AF786D5000797B5 /* ttkClassicTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClassicTheme.c; sourceTree = "<group>"; };
		F96887E60AF786D5000797B5 /* ttkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkDecls.h; sourceTree = "<group>"; };
		F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkDefaultTheme.c; sourceTree = "<group>"; };
		F96887E80AF786D5000797B5 /* ttkElements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkElements.c; sourceTree = "<group>"; };
		F96887E90AF786D5000797B5 /* ttkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkEntry.c; sourceTree = "<group>"; };
		F96887EA0AF786D5000797B5 /* ttkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkFrame.c; sourceTree = "<group>"; };
		F96887EB0AF786D5000797B5 /* ttkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkImage.c; sourceTree = "<group>"; };
		F96887EC0AF786D5000797B5 /* ttkInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkInit.c; sourceTree = "<group>"; };
		F96887ED0AF786D5000797B5 /* ttkLabel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLabel.c; sourceTree = "<group>"; };
		F96887EE0AF786D5000797B5 /* ttkLayout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLayout.c; sourceTree = "<group>"; };
		F96887EF0AF786D5000797B5 /* ttkManager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkManager.c; sourceTree = "<group>"; };
		F96887F00AF786D5000797B5 /* ttkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkManager.h; sourceTree = "<group>"; };
		F96887F10AF786D5000797B5 /* ttkNotebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkNotebook.c; sourceTree = "<group>"; };
		F96887F20AF786D5000797B5 /* ttkPanedwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkPanedwindow.c; sourceTree = "<group>"; };
		F96887F30AF786D5000797B5 /* ttkProgress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkProgress.c; sourceTree = "<group>"; };
		F96887F40AF786D5000797B5 /* ttkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScale.c; sourceTree = "<group>"; };
		F96887F50AF786D5000797B5 /* ttkScroll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScroll.c; sourceTree = "<group>"; };
		F96887F60AF786D5000797B5 /* ttkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScrollbar.c; sourceTree = "<group>"; };
		F96887F70AF786D5000797B5 /* ttkSeparator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSeparator.c; sourceTree = "<group>"; };
		F96887F80AF786D5000797B5 /* ttkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSquare.c; sourceTree = "<group>"; };
		F96887F90AF786D5000797B5 /* ttkState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkState.c; sourceTree = "<group>"; };
		F96887FA0AF786D5000797B5 /* ttkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubInit.c; sourceTree = "<group>"; };
		F96887FB0AF786D5000797B5 /* ttkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubLib.c; sourceTree = "<group>"; };
		F96887FC0AF786D5000797B5 /* ttkTagSet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTagSet.c; sourceTree = "<group>"; };
		F96887FD0AF786D5000797B5 /* ttkTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTheme.c; sourceTree = "<group>"; };
		F96887FE0AF786D5000797B5 /* ttkTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkTheme.h; sourceTree = "<group>"; };
		F96887FF0AF786D5000797B5 /* ttkThemeInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkThemeInt.h; sourceTree = "<group>"; };
		F96888000AF786D5000797B5 /* ttkTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrace.c; sourceTree = "<group>"; };
		F96888010AF786D5000797B5 /* ttkTrack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrack.c; sourceTree = "<group>"; };
		F96888020AF786D5000797B5 /* ttkTreeview.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTreeview.c; sourceTree = "<group>"; };
		F96888030AF786D5000797B5 /* ttkWidget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWidget.c; sourceTree = "<group>"; };
		F96888040AF786D5000797B5 /* ttkWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkWidget.h; sourceTree = "<group>"; };
		F96888370AF787B3000797B5 /* altTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = altTheme.tcl; sourceTree = "<group>"; };
		F96888380AF787B3000797B5 /* aquaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aquaTheme.tcl; sourceTree = "<group>"; };
		F96888390AF787B3000797B5 /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F968883A0AF787B3000797B5 /* clamTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clamTheme.tcl; sourceTree = "<group>"; };
		F968883B0AF787B3000797B5 /* classicTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = classicTheme.tcl; sourceTree = "<group>"; };
		F968883C0AF787B3000797B5 /* combobox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.tcl; sourceTree = "<group>"; };
		F968883D0AF787B3000797B5 /* cursors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursors.tcl; sourceTree = "<group>"; };
		F968883E0AF787B3000797B5 /* defaults.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = defaults.tcl; sourceTree = "<group>"; };
		F96888400AF787B3000797B5 /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F96888410AF787B3000797B5 /* fonts.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fonts.tcl; sourceTree = "<group>"; };
		F96888440AF787B3000797B5 /* menubutton.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubutton.tcl; sourceTree = "<group>"; };
		F96888450AF787B3000797B5 /* notebook.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.tcl; sourceTree = "<group>"; };
		F96888460AF787B3000797B5 /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F96888470AF787B3000797B5 /* progress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progress.tcl; sourceTree = "<group>"; };
		F96888480AF787B3000797B5 /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F96888490AF787B3000797B5 /* scrollbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.tcl; sourceTree = "<group>"; };
		F968884A0AF787B3000797B5 /* sizegrip.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sizegrip.tcl; sourceTree = "<group>"; };
		F968884B0AF787B3000797B5 /* treeview.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.tcl; sourceTree = "<group>"; };
		F968884C0AF787B3000797B5 /* ttk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.tcl; sourceTree = "<group>"; };
		F968884D0AF787B3000797B5 /* utils.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utils.tcl; sourceTree = "<group>"; };
		F968884E0AF787B3000797B5 /* winTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTheme.tcl; sourceTree = "<group>"; };
		F968884F0AF787B3000797B5 /* xpTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xpTheme.tcl; sourceTree = "<group>"; };
		F96888540AF7880C000797B5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96888560AF7880C000797B5 /* combobox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.test; sourceTree = "<group>"; };
		F96888570AF7880C000797B5 /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F96888580AF7880C000797B5 /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F96888590AF7880C000797B5 /* labelframe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.test; sourceTree = "<group>"; };
		F968885A0AF7880C000797B5 /* layout.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = layout.test; sourceTree = "<group>"; };
		F968885C0AF7880C000797B5 /* notebook.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.test; sourceTree = "<group>"; };
		F968885D0AF7880C000797B5 /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F968885E0AF7880C000797B5 /* progressbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progressbar.test; sourceTree = "<group>"; };
		F968885F0AF7880C000797B5 /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F96888600AF7880C000797B5 /* treetags.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treetags.test; sourceTree = "<group>"; };
		F96888610AF7880C000797B5 /* treeview.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.test; sourceTree = "<group>"; };
		F96888620AF7880C000797B5 /* ttk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.test; sourceTree = "<group>"; };
		F96888630AF7880C000797B5 /* validate.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = validate.test; sourceTree = "<group>"; };
		F968886B0AF788F6000797B5 /* ttk_button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_button.n; sourceTree = "<group>"; };
		F968886C0AF788F6000797B5 /* ttk_checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_checkbutton.n; sourceTree = "<group>"; };
		F968886D0AF788F6000797B5 /* ttk_combobox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_combobox.n; sourceTree = "<group>"; };
		F968886F0AF788F6000797B5 /* ttk_entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_entry.n; sourceTree = "<group>"; };
		F96888700AF788F6000797B5 /* ttk_frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_frame.n; sourceTree = "<group>"; };
		F96888710AF788F6000797B5 /* ttk_Geometry.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Geometry.3; sourceTree = "<group>"; };
		F96888720AF788F6000797B5 /* ttk_image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_image.n; sourceTree = "<group>"; };
		F96888730AF788F6000797B5 /* ttk_intro.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_intro.n; sourceTree = "<group>"; };
		F96888740AF788F6000797B5 /* ttk_label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_label.n; sourceTree = "<group>"; };
		F96888750AF788F6000797B5 /* ttk_labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_labelframe.n; sourceTree = "<group>"; };
		F96888760AF788F6000797B5 /* ttk_menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_menubutton.n; sourceTree = "<group>"; };
		F96888770AF788F6000797B5 /* ttk_notebook.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_notebook.n; sourceTree = "<group>"; };
		F96888780AF788F6000797B5 /* ttk_panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_panedwindow.n; sourceTree = "<group>"; };
		F96888790AF788F6000797B5 /* ttk_progressbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_progressbar.n; sourceTree = "<group>"; };
		F968887A0AF788F6000797B5 /* ttk_radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_radiobutton.n; sourceTree = "<group>"; };
		F968887B0AF788F6000797B5 /* ttk_scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_scrollbar.n; sourceTree = "<group>"; };
		F968887C0AF788F6000797B5 /* ttk_separator.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_separator.n; sourceTree = "<group>"; };
		F968887D0AF788F6000797B5 /* ttk_sizegrip.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_sizegrip.n; sourceTree = "<group>"; };
		F968887E0AF788F6000797B5 /* ttk_style.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_style.n; sourceTree = "<group>"; };
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D425F08F272B3004A47F5 /* bn.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = bn.pdf; sourceTree = "<group>"; };
		F96D426108F272B3004A47F5 /* bn_error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_error.c; sourceTree = "<group>"; };
		F96D426208F272B3004A47F5 /* bn_fast_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_invmod.c; sourceTree = "<group>"; };
		F96D426308F272B3004A47F5 /* bn_fast_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_montgomery_reduce.c; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426508F272B3004A47F5 /* bn_fast_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426708F272B3004A47F5 /* bn_mp_2expt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_2expt.c; sourceTree = "<group>"; };
		F96D426808F272B3004A47F5 /* bn_mp_abs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_abs.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426B08F272B3004A47F5 /* bn_mp_addmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_addmod.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427308F272B3004A47F5 /* bn_mp_cnt_lsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cnt_lsb.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427B08F272B3004A47F5 /* bn_mp_dr_is_modulus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_is_modulus.c; sourceTree = "<group>"; };
		F96D427C08F272B3004A47F5 /* bn_mp_dr_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_reduce.c; sourceTree = "<group>"; };
		F96D427D08F272B3004A47F5 /* bn_mp_dr_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_setup.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
		F96D428008F272B3004A47F5 /* bn_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod.c; sourceTree = "<group>"; };
		F96D428108F272B3004A47F5 /* bn_mp_exptmod_fast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod_fast.c; sourceTree = "<group>"; };
		F96D428208F272B3004A47F5 /* bn_mp_exteuclid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exteuclid.c; sourceTree = "<group>"; };
		F96D428308F272B3004A47F5 /* bn_mp_fread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fread.c; sourceTree = "<group>"; };
		F96D428408F272B3004A47F5 /* bn_mp_fwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fwrite.c; sourceTree = "<group>"; };
		F96D428508F272B3004A47F5 /* bn_mp_gcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_gcd.c; sourceTree = "<group>"; };
		F96D428608F272B3004A47F5 /* bn_mp_get_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_get_int.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428C08F272B3004A47F5 /* bn_mp_init_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set_int.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D428E08F272B3004A47F5 /* bn_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod.c; sourceTree = "<group>"; };
		F96D428F08F272B3004A47F5 /* bn_mp_invmod_slow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod_slow.c; sourceTree = "<group>"; };
		F96D429008F272B3004A47F5 /* bn_mp_is_square.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_is_square.c; sourceTree = "<group>"; };
		F96D429108F272B3004A47F5 /* bn_mp_jacobi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_jacobi.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429408F272B3004A47F5 /* bn_mp_lcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lcm.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429808F272B3004A47F5 /* bn_mp_mod_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_d.c; sourceTree = "<group>"; };
		F96D429908F272B3004A47F5 /* bn_mp_montgomery_calc_normalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_calc_normalization.c; sourceTree = "<group>"; };
		F96D429A08F272B3004A47F5 /* bn_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_reduce.c; sourceTree = "<group>"; };
		F96D429B08F272B3004A47F5 /* bn_mp_montgomery_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_setup.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A008F272B3004A47F5 /* bn_mp_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mulmod.c; sourceTree = "<group>"; };
		F96D42A108F272B3004A47F5 /* bn_mp_n_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_n_root.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42A408F272B3004A47F5 /* bn_mp_prime_fermat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_fermat.c; sourceTree = "<group>"; };
		F96D42A508F272B3004A47F5 /* bn_mp_prime_is_divisible.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_divisible.c; sourceTree = "<group>"; };
		F96D42A608F272B3004A47F5 /* bn_mp_prime_is_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_prime.c; sourceTree = "<group>"; };
		F96D42A708F272B3004A47F5 /* bn_mp_prime_miller_rabin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_miller_rabin.c; sourceTree = "<group>"; };
		F96D42A808F272B3004A47F5 /* bn_mp_prime_next_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_next_prime.c; sourceTree = "<group>"; };
		F96D42A908F272B3004A47F5 /* bn_mp_prime_rabin_miller_trials.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_rabin_miller_trials.c; sourceTree = "<group>"; };
		F96D42AA08F272B3004A47F5 /* bn_mp_prime_random_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_random_ex.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AD08F272B3004A47F5 /* bn_mp_rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rand.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42AF08F272B3004A47F5 /* bn_mp_read_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_signed_bin.c; sourceTree = "<group>"; };
		F96D42B008F272B3004A47F5 /* bn_mp_read_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42B108F272B3004A47F5 /* bn_mp_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce.c; sourceTree = "<group>"; };
		F96D42B208F272B3004A47F5 /* bn_mp_reduce_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k.c; sourceTree = "<group>"; };
		F96D42B308F272B3004A47F5 /* bn_mp_reduce_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_l.c; sourceTree = "<group>"; };
		F96D42B408F272B3004A47F5 /* bn_mp_reduce_2k_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup.c; sourceTree = "<group>"; };
		F96D42B508F272B3004A47F5 /* bn_mp_reduce_2k_setup_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup_l.c; sourceTree = "<group>"; };
		F96D42B608F272B3004A47F5 /* bn_mp_reduce_is_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k.c; sourceTree = "<group>"; };
		F96D42B708F272B3004A47F5 /* bn_mp_reduce_is_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k_l.c; sourceTree = "<group>"; };
		F96D42B808F272B3004A47F5 /* bn_mp_reduce_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_setup.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BB08F272B3004A47F5 /* bn_mp_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set_int.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BD08F272B3004A47F5 /* bn_mp_signed_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_signed_bin_size.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42BF08F272B3004A47F5 /* bn_mp_sqrmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrmod.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C308F272B3004A47F5 /* bn_mp_submod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_submod.c; sourceTree = "<group>"; };
		F96D42C408F272B3004A47F5 /* bn_mp_to_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin.c; sourceTree = "<group>"; };
		F96D42C508F272B3004A47F5 /* bn_mp_to_signed_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin_n.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CA08F272B3004A47F5 /* bn_mp_toradix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42CF08F272B3004A47F5 /* bn_prime_tab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_prime_tab.c; sourceTree = "<group>"; };
		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D208F272B3004A47F5 /* bn_s_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_exptmod.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D408F272B3004A47F5 /* bn_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
		F96D42D908F272B3004A47F5 /* callgraph.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = callgraph.txt; sourceTree = "<group>"; };
		F96D42DA08F272B3004A47F5 /* changes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = changes.txt; sourceTree = "<group>"; };
		F96D42F008F272B3004A47F5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
		F96D431D08F272B4004A47F5 /* poster.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = poster.pdf; sourceTree = "<group>"; };
		F96D432608F272B4004A47F5 /* tommath.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = tommath.pdf; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437E08F272B6004A47F5 /* ioUtil.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioUtil.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443408F272B8004A47F5 /* str2c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = str2c; sourceTree = "<group>"; };
		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
		F96D443708F272B9004A47F5 /* tclmin.wse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclmin.wse; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
		F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPrivate.h; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Wish-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Wish-Debug.xcconfig"; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F9A3082D08F2D4AB00BAE1AB /* Tk.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084B08F2D4CE00BAE1AB /* Wish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wish.app; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
		F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mclist.tcl; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkpane.tcl; sourceTree = "<group>"; };
		F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkmenu.tcl; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
		F9FD31F40CC1AD070073837D /* tktest-X11 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "tktest-X11"; sourceTree = BUILT_PRODUCTS_DIR; };
		F9FD32140CC1AF170073837D /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = /usr/X11R6/lib/libX11.dylib; sourceTree = "<absolute>"; };
		F9FD32150CC1AF170073837D /* libXext.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXext.dylib; path = /usr/X11R6/lib/libXext.dylib; sourceTree = "<absolute>"; };
		F9FD32160CC1AF170073837D /* libXss.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXss.dylib; path = /usr/X11R6/lib/libXss.dylib; sourceTree = "<absolute>"; };
		F9FD34990CC1BB0D0073837D /* libfreetype.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreetype.dylib; path = /usr/X11R6/lib/libfreetype.dylib; sourceTree = "<absolute>"; };
		F9FD349A0CC1BB0D0073837D /* libXft.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXft.dylib; path = /usr/X11R6/lib/libXft.dylib; sourceTree = "<absolute>"; };
		F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfontconfig.dylib; path = /usr/X11R6/lib/libfontconfig.dylib; sourceTree = "<absolute>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */,
				F966C07908F28233005CB29B /* IOKit.framework in Frameworks */,
				F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */,
				F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD31E30CC1AD070073837D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */,
				F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */,
				F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */,
				F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */,
				F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */,
				F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */,
				F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Wish */ = {
			isa = PBXGroup;
			children = (
				F96D3DF708F271BE004A47F5 /* Tk Sources */,
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n";
			name = Wish;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* Wish.app */,
				F9A3082D08F2D4AB00BAE1AB /* Tk.framework */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
				8DD76FB20486AB0100D96B5E /* tktest */,
				F9FD31F40CC1AD070073837D /* tktest-X11 */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F966BA0308F27A37005CB29B /* bitmaps */ = {
			isa = PBXGroup;
			children = (
				F966BA0408F27A37005CB29B /* error.xbm */,
				F966BA0508F27A37005CB29B /* gray12.xbm */,
				F966BA0608F27A37005CB29B /* gray25.xbm */,
				F966BA0708F27A37005CB29B /* gray50.xbm */,
				F966BA0808F27A37005CB29B /* gray75.xbm */,
				F966BA0908F27A37005CB29B /* hourglass.xbm */,
				F966BA0A08F27A37005CB29B /* info.xbm */,
				F966BA0B08F27A37005CB29B /* questhead.xbm */,
				F966BA0C08F27A37005CB29B /* question.xbm */,
				F966BA0D08F27A37005CB29B /* warning.xbm */,
			);
			path = bitmaps;
			sourceTree = "<group>";
		};
		F966BA1008F27A37005CB29B /* doc */ = {
			isa = PBXGroup;
			children = (
				F966BA1108F27A37005CB29B /* 3DBorder.3 */,
				F966BA1208F27A37005CB29B /* AddOption.3 */,
				F966BA1308F27A37005CB29B /* bell.n */,
				F966BA1408F27A37005CB29B /* bind.n */,
				F966BA1508F27A37005CB29B /* BindTable.3 */,
				F966BA1608F27A37005CB29B /* bindtags.n */,
				F966BA1708F27A37005CB29B /* bitmap.n */,
				F966BA1808F27A37005CB29B /* button.n */,
				F966BA1908F27A37005CB29B /* canvas.n */,
				F966BA1A08F27A37005CB29B /* CanvPsY.3 */,
				F966BA1B08F27A37005CB29B /* CanvTkwin.3 */,
				F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */,
				F966BA1D08F27A37005CB29B /* checkbutton.n */,
				F966BA1E08F27A37005CB29B /* chooseColor.n */,
				F966BA1F08F27A37005CB29B /* chooseDirectory.n */,
				F966BA2008F27A37005CB29B /* Clipboard.3 */,
				F966BA2108F27A37005CB29B /* clipboard.n */,
				F966BA2208F27A37005CB29B /* ClrSelect.3 */,
				F966BA2308F27A37005CB29B /* colors.n */,
				F966BA2408F27A37005CB29B /* ConfigWidg.3 */,
				F966BA2508F27A37005CB29B /* ConfigWind.3 */,
				F966BA2608F27A37005CB29B /* console.n */,
				F966BA2708F27A37005CB29B /* CoordToWin.3 */,
				F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */,
				F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */,
				F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */,
				F966BA2B08F27A37005CB29B /* CrtImgType.3 */,
				F966BA2C08F27A37005CB29B /* CrtItemType.3 */,
				F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */,
				F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */,
				F966BA2F08F27A37005CB29B /* CrtWindow.3 */,
				F966BA3008F27A37005CB29B /* cursors.n */,
				F966BA3108F27A37005CB29B /* DeleteImg.3 */,
				F966BA3208F27A37005CB29B /* destroy.n */,
				F966BA3308F27A37005CB29B /* dialog.n */,
				F966BA3408F27A37005CB29B /* DrawFocHlt.3 */,
				F966BA3508F27A37005CB29B /* entry.n */,
				F966BA3608F27A37005CB29B /* event.n */,
				F966BA3708F27A37005CB29B /* EventHndlr.3 */,
				F966BA3808F27A37005CB29B /* FindPhoto.3 */,
				F966BA3908F27A37005CB29B /* focus.n */,
				F966BA3A08F27A37005CB29B /* focusNext.n */,
				F966BA3B08F27A37005CB29B /* font.n */,
				F966BA3C08F27A37005CB29B /* FontId.3 */,
				F966BA3D08F27A37005CB29B /* frame.n */,
				F966BA3E08F27A37005CB29B /* FreeXId.3 */,
				F966BA3F08F27A37005CB29B /* GeomReq.3 */,
				F966BA4008F27A37005CB29B /* GetAnchor.3 */,
				F966BA4108F27A37005CB29B /* GetBitmap.3 */,
				F966BA4208F27A37005CB29B /* GetCapStyl.3 */,
				F966BA4308F27A37005CB29B /* GetClrmap.3 */,
				F966BA4408F27A37005CB29B /* GetColor.3 */,
				F966BA4508F27A37005CB29B /* GetCursor.3 */,
				F966BA4608F27A37005CB29B /* GetDash.3 */,
				F966BA4708F27A37005CB29B /* GetFont.3 */,
				F966BA4808F27A37005CB29B /* GetGC.3 */,
				F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */,
				F966BA4A08F27A37005CB29B /* GetHWND.3 */,
				F966BA4B08F27A37005CB29B /* GetImage.3 */,
				F966BA4C08F27A37005CB29B /* GetJoinStl.3 */,
				F966BA4D08F27A37005CB29B /* GetJustify.3 */,
				F966BA4E08F27A37005CB29B /* getOpenFile.n */,
				F966BA4F08F27A37005CB29B /* GetOption.3 */,
				F966BA5008F27A38005CB29B /* GetPixels.3 */,
				F966BA5108F27A38005CB29B /* GetPixmap.3 */,
				F966BA5208F27A38005CB29B /* GetRelief.3 */,
				F966BA5308F27A38005CB29B /* GetRootCrd.3 */,
				F966BA5408F27A38005CB29B /* GetScroll.3 */,
				F966BA5508F27A38005CB29B /* GetSelect.3 */,
				F966BA5608F27A38005CB29B /* GetUid.3 */,
				F966BA5708F27A38005CB29B /* GetVisual.3 */,
				F966BA5808F27A38005CB29B /* GetVRoot.3 */,
				F966BA5908F27A38005CB29B /* Grab.3 */,
				F966BA5A08F27A38005CB29B /* grab.n */,
				F966BA5B08F27A38005CB29B /* grid.n */,
				F966BA5C08F27A38005CB29B /* HandleEvent.3 */,
				F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */,
				F966BA5E08F27A38005CB29B /* IdToWindow.3 */,
				F966BA5F08F27A38005CB29B /* image.n */,
				F966BA6008F27A38005CB29B /* ImgChanged.3 */,
				F966BA6108F27A38005CB29B /* Inactive.3 */,
				F966BA6208F27A38005CB29B /* InternAtom.3 */,
				F966BA6308F27A38005CB29B /* keysyms.n */,
				F966BA6408F27A38005CB29B /* label.n */,
				F966BA6508F27A38005CB29B /* labelframe.n */,
				F966BA6608F27A38005CB29B /* listbox.n */,
				F966BA6708F27A38005CB29B /* loadTk.n */,
				F966BA6808F27A38005CB29B /* lower.n */,
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
				F966BA8408F27A38005CB29B /* QWinEvent.3 */,
				F966BA8508F27A38005CB29B /* radiobutton.n */,
				F966BA8608F27A38005CB29B /* raise.n */,
				F966BA8708F27A38005CB29B /* Restack.3 */,
				F966BA8808F27A38005CB29B /* RestrictEv.3 */,
				F966BA8908F27A38005CB29B /* scale.n */,
				F966BA8A08F27A38005CB29B /* scrollbar.n */,
				F966BA8B08F27A38005CB29B /* selection.n */,
				F966BA8C08F27A38005CB29B /* send.n */,
				F966BA8D08F27A38005CB29B /* SetAppName.3 */,
				F966BA8E08F27A38005CB29B /* SetCaret.3 */,
				F966BA8F08F27A38005CB29B /* SetClass.3 */,
				F966BA9008F27A38005CB29B /* SetClassProcs.3 */,
				F966BA9108F27A38005CB29B /* SetGrid.3 */,
				F966BA9208F27A38005CB29B /* SetOptions.3 */,
				F966BA9308F27A38005CB29B /* SetVisual.3 */,
				F966BA9408F27A38005CB29B /* spinbox.n */,
				F966BA9508F27A38005CB29B /* StrictMotif.3 */,
				F966BA9608F27A38005CB29B /* text.n */,
				F966BA9708F27A38005CB29B /* TextLayout.3 */,
				F966BA9808F27A38005CB29B /* tk.n */,
				F966BA9908F27A38005CB29B /* tk4.0.ps */,
				F966BA9A08F27A38005CB29B /* Tk_Init.3 */,
				F966BA9B08F27A38005CB29B /* Tk_Main.3 */,
				F966BA9C08F27A38005CB29B /* tkerror.n */,
				F966BA9D08F27A38005CB29B /* TkInitStubs.3 */,
				F966BA9E08F27A38005CB29B /* tkvars.n */,
				F966BA9F08F27A38005CB29B /* tkwait.n */,
				F966BAA008F27A38005CB29B /* toplevel.n */,
				F968886B0AF788F6000797B5 /* ttk_button.n */,
				F968886C0AF788F6000797B5 /* ttk_checkbutton.n */,
				F968886D0AF788F6000797B5 /* ttk_combobox.n */,
				F968886F0AF788F6000797B5 /* ttk_entry.n */,
				F96888700AF788F6000797B5 /* ttk_frame.n */,
				F96888710AF788F6000797B5 /* ttk_Geometry.3 */,
				F96888720AF788F6000797B5 /* ttk_image.n */,
				F96888730AF788F6000797B5 /* ttk_intro.n */,
				F96888740AF788F6000797B5 /* ttk_label.n */,
				F96888750AF788F6000797B5 /* ttk_labelframe.n */,
				F96888760AF788F6000797B5 /* ttk_menubutton.n */,
				F96888770AF788F6000797B5 /* ttk_notebook.n */,
				F96888780AF788F6000797B5 /* ttk_panedwindow.n */,
				F96888790AF788F6000797B5 /* ttk_progressbar.n */,
				F968887A0AF788F6000797B5 /* ttk_radiobutton.n */,
				F968887B0AF788F6000797B5 /* ttk_scrollbar.n */,
				F968887C0AF788F6000797B5 /* ttk_separator.n */,
				F968887D0AF788F6000797B5 /* ttk_sizegrip.n */,
				F968887E0AF788F6000797B5 /* ttk_style.n */,
				F968887F0AF788F6000797B5 /* ttk_Theme.3 */,
				F96888800AF788F6000797B5 /* ttk_treeview.n */,
				F96888810AF788F6000797B5 /* ttk_widget.n */,
				F966BAA108F27A38005CB29B /* WindowId.3 */,
				F966BAA208F27A38005CB29B /* winfo.n */,
				F966BAA308F27A38005CB29B /* wish.1 */,
				F966BAA408F27A38005CB29B /* wm.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F966BAA508F27A38005CB29B /* generic */ = {
			isa = PBXGroup;
			children = (
				F966BAA608F27A38005CB29B /* default.h */,
				F966BAA708F27A38005CB29B /* ks_names.h */,
				F966BAA808F27A38005CB29B /* prolog.ps */,
				F966BAA908F27A39005CB29B /* README */,
				F966BAAA08F27A39005CB29B /* tk.decls */,
				F966BAAB08F27A39005CB29B /* tk.h */,
				F966BAAC08F27A39005CB29B /* tk3d.c */,
				F966BAAD08F27A39005CB29B /* tk3d.h */,
				F966BAAE08F27A39005CB29B /* tkArgv.c */,
				F966BAAF08F27A39005CB29B /* tkAtom.c */,
				F966BAB008F27A39005CB29B /* tkBind.c */,
				F966BAB108F27A39005CB29B /* tkBitmap.c */,
				F966BAB208F27A39005CB29B /* tkButton.c */,
				F966BAB308F27A39005CB29B /* tkButton.h */,
				F966BAB408F27A39005CB29B /* tkCanvArc.c */,
				F966BAB508F27A39005CB29B /* tkCanvas.c */,
				F966BAB608F27A39005CB29B /* tkCanvas.h */,
				F966BAB708F27A39005CB29B /* tkCanvBmap.c */,
				F966BAB808F27A39005CB29B /* tkCanvImg.c */,
				F966BAB908F27A39005CB29B /* tkCanvLine.c */,
				F966BABA08F27A39005CB29B /* tkCanvPoly.c */,
				F966BABB08F27A39005CB29B /* tkCanvPs.c */,
				F966BABD08F27A39005CB29B /* tkCanvText.c */,
				F966BABE08F27A39005CB29B /* tkCanvUtil.c */,
				F966BABF08F27A39005CB29B /* tkCanvWind.c */,
				F966BAC008F27A39005CB29B /* tkClipboard.c */,
				F966BAC108F27A39005CB29B /* tkCmds.c */,
				F966BAC208F27A39005CB29B /* tkColor.c */,
				F966BAC308F27A39005CB29B /* tkColor.h */,
				F966BAC408F27A39005CB29B /* tkConfig.c */,
				F966BAC508F27A39005CB29B /* tkConsole.c */,
				F966BAC608F27A39005CB29B /* tkCursor.c */,
				F966BAC708F27A39005CB29B /* tkDecls.h */,
				F966BAC808F27A39005CB29B /* tkEntry.c */,
				F966BAC908F27A39005CB29B /* tkEntry.h */,
				F966BACA08F27A39005CB29B /* tkError.c */,
				F966BACB08F27A39005CB29B /* tkEvent.c */,
				F966BACC08F27A39005CB29B /* tkFileFilter.c */,
				F966BACD08F27A39005CB29B /* tkFileFilter.h */,
				F966BACE08F27A39005CB29B /* tkFocus.c */,
				F966BACF08F27A39005CB29B /* tkFont.c */,
				F966BAD008F27A39005CB29B /* tkFont.h */,
				F966BAD108F27A39005CB29B /* tkFrame.c */,
				F966BAD208F27A39005CB29B /* tkGC.c */,
				F966BAD308F27A39005CB29B /* tkGeometry.c */,
				F966BAD408F27A39005CB29B /* tkGet.c */,
				F966BAD508F27A39005CB29B /* tkGrab.c */,
				F966BAD608F27A39005CB29B /* tkGrid.c */,
				F966BAD708F27A39005CB29B /* tkImage.c */,
				F966BAD808F27A39005CB29B /* tkImgBmap.c */,
				F966BAD908F27A39005CB29B /* tkImgGIF.c */,
				F966BADA08F27A39005CB29B /* tkImgPhoto.c */,
				F966BADB08F27A39005CB29B /* tkImgPPM.c */,
				F966BADC08F27A39005CB29B /* tkImgUtil.c */,
				F966BADE08F27A39005CB29B /* tkInt.decls */,
				F966BADF08F27A39005CB29B /* tkInt.h */,
				F966BAE108F27A39005CB29B /* tkIntDecls.h */,
				F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */,
				F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */,
				F966BAE408F27A39005CB29B /* tkListbox.c */,
				F966BAE508F27A39005CB29B /* tkMacWinMenu.c */,
				F966BAE608F27A39005CB29B /* tkMain.c */,
				F966BAE708F27A39005CB29B /* tkMenu.c */,
				F966BAE808F27A39005CB29B /* tkMenu.h */,
				F966BAE908F27A39005CB29B /* tkMenubutton.c */,
				F966BAEA08F27A39005CB29B /* tkMenubutton.h */,
				F966BAEB08F27A39005CB29B /* tkMenuDraw.c */,
				F966BAEC08F27A39005CB29B /* tkMessage.c */,
				F966BAED08F27A39005CB29B /* tkObj.c */,
				F966BAEE08F27A39005CB29B /* tkOldConfig.c */,
				F966BAEF08F27A39005CB29B /* tkOption.c */,
				F966BAF008F27A39005CB29B /* tkPack.c */,
				F966BAF108F27A39005CB29B /* tkPanedWindow.c */,
				F966BAF208F27A39005CB29B /* tkPlace.c */,
				F966BAF308F27A39005CB29B /* tkPlatDecls.h */,
				F966BAF408F27A39005CB29B /* tkPointer.c */,
				F966BAF508F27A39005CB29B /* tkPort.h */,
				F966BAF608F27A39005CB29B /* tkRectOval.c */,
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
				F966BB0608F27A39005CB29B /* tkTextDisp.c */,
				F966BB0808F27A39005CB29B /* tkTextImage.c */,
				F966BB0908F27A39005CB29B /* tkTextIndex.c */,
				F966BB0A08F27A39005CB29B /* tkTextMark.c */,
				F966BB0B08F27A39005CB29B /* tkTextTag.c */,
				F966BB0C08F27A39005CB29B /* tkTextWind.c */,
				F966BB0D08F27A39005CB29B /* tkTrig.c */,
				F966BB0E08F27A39005CB29B /* tkUndo.c */,
				F966BB0F08F27A39005CB29B /* tkUndo.h */,
				F966BB1008F27A39005CB29B /* tkUtil.c */,
				F966BB1108F27A39005CB29B /* tkVisual.c */,
				F966BB1208F27A39005CB29B /* tkWindow.c */,
				F96887DF0AF786D5000797B5 /* ttk */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F966BB1308F27A39005CB29B /* library */ = {
			isa = PBXGroup;
			children = (
				F966BB1408F27A39005CB29B /* bgerror.tcl */,
				F966BB1508F27A39005CB29B /* button.tcl */,
				F966BB1608F27A39005CB29B /* choosedir.tcl */,
				F966BB1708F27A39005CB29B /* clrpick.tcl */,
				F966BB1808F27A39005CB29B /* comdlg.tcl */,
				F966BB1908F27A39005CB29B /* console.tcl */,
				F966BB1A08F27A39005CB29B /* demos */,
				F966BB6208F27A3A005CB29B /* dialog.tcl */,
				F966BB6308F27A3A005CB29B /* entry.tcl */,
				F966BB6408F27A3A005CB29B /* focus.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8A08F27A3B005CB29B /* prolog.ps */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
			children = (
				F966BB1B08F27A39005CB29B /* anilabel.tcl */,
				F966BB1C08F27A39005CB29B /* aniwave.tcl */,
				F966BB1D08F27A39005CB29B /* arrow.tcl */,
				F966BB1E08F27A39005CB29B /* bind.tcl */,
				F966BB1F08F27A39005CB29B /* bitmap.tcl */,
				F966BB2008F27A39005CB29B /* browse */,
				F966BB2108F27A39005CB29B /* button.tcl */,
				F966BB2208F27A39005CB29B /* check.tcl */,
				F966BB2308F27A39005CB29B /* clrpick.tcl */,
				F966BB2408F27A39005CB29B /* colors.tcl */,
				F936FCDB0CCD984600716967 /* combo.tcl */,
				F966BB2508F27A39005CB29B /* cscroll.tcl */,
				F966BB2608F27A39005CB29B /* ctext.tcl */,
				F966BB2708F27A39005CB29B /* dialog1.tcl */,
				F966BB2808F27A39005CB29B /* dialog2.tcl */,
				F966BB2A08F27A39005CB29B /* entry1.tcl */,
				F966BB2B08F27A39005CB29B /* entry2.tcl */,
				F966BB2C08F27A39005CB29B /* entry3.tcl */,
				F966BB2D08F27A39005CB29B /* filebox.tcl */,
				F966BB2E08F27A39005CB29B /* floor.tcl */,
				F966BB2F08F27A39005CB29B /* form.tcl */,
				F966BB3008F27A39005CB29B /* goldberg.tcl */,
				F966BB3108F27A39005CB29B /* hello */,
				F966BB3208F27A39005CB29B /* hscale.tcl */,
				F966BB3308F27A39005CB29B /* icon.tcl */,
				F966BB3408F27A39005CB29B /* image1.tcl */,
				F966BB3508F27A39005CB29B /* image2.tcl */,
				F966BB4208F27A3A005CB29B /* items.tcl */,
				F966BB4308F27A3A005CB29B /* ixset */,
				F92240290D7C620F005EC715 /* knightstour.tcl */,
				F966BB4408F27A3A005CB29B /* label.tcl */,
				F966BB4508F27A3A005CB29B /* labelframe.tcl */,
				F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */,
				F966BB4608F27A3A005CB29B /* menu.tcl */,
				F966BB4708F27A3A005CB29B /* menubu.tcl */,
				F966BB4808F27A3A005CB29B /* msgbox.tcl */,
				F966BB4A08F27A3A005CB29B /* paned1.tcl */,
				F966BB4B08F27A3A005CB29B /* paned2.tcl */,
				F966BB4C08F27A3A005CB29B /* pendulum.tcl */,
				F966BB4D08F27A3A005CB29B /* plot.tcl */,
				F966BB4E08F27A3A005CB29B /* puzzle.tcl */,
				F966BB4F08F27A3A005CB29B /* radio.tcl */,
				F966BB5008F27A3A005CB29B /* README */,
				F966BB5108F27A3A005CB29B /* rmt */,
				F966BB5208F27A3A005CB29B /* rolodex */,
				F966BB5308F27A3A005CB29B /* ruler.tcl */,
				F966BB5408F27A3A005CB29B /* sayings.tcl */,
				F966BB5508F27A3A005CB29B /* search.tcl */,
				F966BB5608F27A3A005CB29B /* spin.tcl */,
				F966BB5708F27A3A005CB29B /* square */,
				F966BB5808F27A3A005CB29B /* states.tcl */,
				F966BB5908F27A3A005CB29B /* style.tcl */,
				F966BB5A08F27A3A005CB29B /* tclIndex */,
				F966BB5B08F27A3A005CB29B /* tcolor */,
				F966BB5C08F27A3A005CB29B /* text.tcl */,
				F9099B8A0CC67D30005A9580 /* textpeer.tcl */,
				F966BB5D08F27A3A005CB29B /* timer */,
				F936FCD90CCD984600716967 /* toolbar.tcl */,
				F936FCD80CCD984600716967 /* tree.tcl */,
				F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */,
				F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */,
				F936FCDA0CCD984600716967 /* ttknote.tcl */,
				F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */,
				F936FCD70CCD984500716967 /* ttkprogress.tcl */,
				F966BB5E08F27A3A005CB29B /* twind.tcl */,
				F966BB5F08F27A3A005CB29B /* unicodeout.tcl */,
				F966BB6008F27A3A005CB29B /* vscale.tcl */,
				F966BB6108F27A3A005CB29B /* widget */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		F966BB9708F27A3B005CB29B /* macosx */ = {
			isa = PBXGroup;
			children = (
				F966BBBA08F27A3B005CB29B /* configure.ac */,
				F966BBBB08F27A3B005CB29B /* GNUmakefile */,
				F966BBBE08F27A3B005CB29B /* README */,
				F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */,
				F966BBC208F27A3B005CB29B /* tkMacOSX.h */,
				F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */,
				F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */,
				F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */,
				F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */,
				F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */,
				F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */,
				F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */,
				F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */,
				F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */,
				F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */,
				F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */,
				F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */,
				F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */,
				F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */,
				F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */,
				F966BBD508F27A3B005CB29B /* tkMacOSXEvent.h */,
				F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */,
				F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */,
				F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */,
				F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */,
				F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */,
				F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */,
				F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */,
				F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */,
				F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */,
				F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */,
				F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */,
				F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */,
				F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */,
				F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */,
				F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */,
				F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */,
				F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */,
				F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */,
				F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */,
				F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */,
				F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */,
				F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */,
				F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */,
				F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */,
				F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */,
				F96888840AF78938000797B5 /* ttkMacOSXTheme.c */,
				F95D8D4B0F1715610006B020 /* Tk.icns */,
				F95D8D4C0F1715610006B020 /* Tk.tiff */,
				F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */,
				F97AE7F10B65C1E900310EA2 /* Wish-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F966BC0408F27A3C005CB29B /* tests */ = {
			isa = PBXGroup;
			children = (
				F966BC0508F27A3C005CB29B /* all.tcl */,
				F966BC0608F27A3C005CB29B /* arc.tcl */,
				F966BC0708F27A3C005CB29B /* bell.test */,
				F966BC0808F27A3C005CB29B /* bevel.tcl */,
				F966BC0908F27A3C005CB29B /* bgerror.test */,
				F966BC0A08F27A3C005CB29B /* bind.test */,
				F966BC0B08F27A3C005CB29B /* bitmap.test */,
				F966BC0C08F27A3C005CB29B /* border.test */,
				F966BC0D08F27A3C005CB29B /* bugs.tcl */,
				F966BC0E08F27A3C005CB29B /* butGeom.tcl */,
				F966BC0F08F27A3C005CB29B /* butGeom2.tcl */,
				F966BC1008F27A3C005CB29B /* button.test */,
				F966BC1108F27A3C005CB29B /* canvas.test */,
				F966BC1208F27A3C005CB29B /* canvImg.test */,
				F966BC1308F27A3C005CB29B /* canvPs.test */,
				F966BC1408F27A3C005CB29B /* canvPsArc.tcl */,
				F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */,
				F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */,
				F966BC1708F27A3C005CB29B /* canvPsImg.tcl */,
				F966BC1808F27A3C005CB29B /* canvPsText.tcl */,
				F966BC1908F27A3C005CB29B /* canvRect.test */,
				F966BC1A08F27A3C005CB29B /* canvText.test */,
				F966BC1B08F27A3C005CB29B /* canvWind.test */,
				F966BC1C08F27A3C005CB29B /* choosedir.test */,
				F966BC1D08F27A3C005CB29B /* clipboard.test */,
				F966BC1E08F27A3C005CB29B /* clrpick.test */,
				F966BC1F08F27A3C005CB29B /* cmap.tcl */,
				F966BC2008F27A3C005CB29B /* cmds.test */,
				F966BC2108F27A3C005CB29B /* color.test */,
				F966BC2208F27A3C005CB29B /* config.test */,
				F966BC2308F27A3C005CB29B /* constraints.tcl */,
				F966BC2408F27A3C005CB29B /* cursor.test */,
				F966BC2508F27A3C005CB29B /* dialog.test */,
				F966BC2608F27A3C005CB29B /* embed.test */,
				F966BC2708F27A3C005CB29B /* entry.test */,
				F966BC2808F27A3C005CB29B /* event.test */,
				F966BC2908F27A3C005CB29B /* filebox.test */,
				F966BC2A08F27A3C005CB29B /* focus.test */,
				F966BC2B08F27A3C005CB29B /* focusTcl.test */,
				F966BC2C08F27A3C005CB29B /* font.test */,
				F966BC2D08F27A3C005CB29B /* frame.test */,
				F966BC2E08F27A3C005CB29B /* geometry.test */,
				F966BC2F08F27A3C005CB29B /* get.test */,
				F966BC3008F27A3C005CB29B /* grab.test */,
				F966BC3108F27A3C005CB29B /* grid.test */,
				F966BC3208F27A3C005CB29B /* id.test */,
				F966BC3308F27A3C005CB29B /* image.test */,
				F966BC3408F27A3C005CB29B /* imgBmap.test */,
				F966BC3508F27A3C005CB29B /* imgPhoto.test */,
				F966BC3608F27A3C005CB29B /* imgPPM.test */,
				F966BC3708F27A3C005CB29B /* listbox.test */,
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
				F966BC4708F27A3D005CB29B /* README */,
				F966BC4808F27A3D005CB29B /* safe.test */,
				F966BC4908F27A3D005CB29B /* scale.test */,
				F966BC4A08F27A3D005CB29B /* scrollbar.test */,
				F966BC4B08F27A3D005CB29B /* select.test */,
				F966BC4C08F27A3D005CB29B /* send.test */,
				F966BC4D08F27A3D005CB29B /* spinbox.test */,
				F966BC4E08F27A3D005CB29B /* text.test */,
				F966BC4F08F27A3D005CB29B /* textBTree.test */,
				F966BC5008F27A3D005CB29B /* textDisp.test */,
				F966BC5108F27A3D005CB29B /* textImage.test */,
				F966BC5208F27A3D005CB29B /* textIndex.test */,
				F966BC5308F27A3D005CB29B /* textMark.test */,
				F966BC5408F27A3D005CB29B /* textTag.test */,
				F966BC5508F27A3D005CB29B /* textWind.test */,
				F966BC5608F27A3D005CB29B /* tk.test */,
				F96888530AF7880C000797B5 /* ttk */,
				F966BC5708F27A3D005CB29B /* unixButton.test */,
				F966BC5808F27A3D005CB29B /* unixEmbed.test */,
				F966BC5908F27A3D005CB29B /* unixFont.test */,
				F966BC5A08F27A3D005CB29B /* unixMenu.test */,
				F966BC5B08F27A3D005CB29B /* unixSelect.test */,
				F966BC5C08F27A3D005CB29B /* unixWm.test */,
				F966BC5D08F27A3D005CB29B /* util.test */,
				F966BC5E08F27A3D005CB29B /* visual.test */,
				F966BC5F08F27A3D005CB29B /* visual_bb.test */,
				F966BC6008F27A3D005CB29B /* winButton.test */,
				F966BC6108F27A3D005CB29B /* winClipboard.test */,
				F966BC6208F27A3D005CB29B /* winDialog.test */,
				F966BC6308F27A3D005CB29B /* window.test */,
				F966BC6408F27A3D005CB29B /* winfo.test */,
				F966BC6508F27A3D005CB29B /* winFont.test */,
				F966BC6608F27A3D005CB29B /* winMenu.test */,
				F966BC6708F27A3D005CB29B /* winSend.test */,
				F966BC6808F27A3D005CB29B /* winWm.test */,
				F966BC6908F27A3D005CB29B /* wm.test */,
				F966BC6A08F27A3D005CB29B /* xmfbox.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.in */,
				F966BC6F08F27A3D005CB29B /* install-sh */,
				F966BC7008F27A3D005CB29B /* installManPage */,
				F966BC7108F27A3D005CB29B /* Makefile.in */,
				F966BC7208F27A3D005CB29B /* README */,
				F966BC7308F27A3D005CB29B /* tcl.m4 */,
				F966BC7408F27A3D005CB29B /* tk.spec */,
				F966BC7508F27A3D005CB29B /* tkAppInit.c */,
				F966BC7608F27A3D005CB29B /* tkConfig.h.in */,
				F966BC7708F27A3D005CB29B /* tkConfig.sh.in */,
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
				F966BC8708F27A3D005CB29B /* tkUnixKey.c */,
				F966BC8808F27A3D005CB29B /* tkUnixMenu.c */,
				F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */,
				F966BC8A08F27A3D005CB29B /* tkUnixPort.h */,
				F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */,
				F966BC8C08F27A3D005CB29B /* tkUnixScale.c */,
				F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */,
				F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */,
				F966BC8F08F27A3D005CB29B /* tkUnixSend.c */,
				F966BC9008F27A3D005CB29B /* tkUnixWm.c */,
				F966BC9108F27A3D005CB29B /* tkUnixXId.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.in */,
				F966BC9808F27A3E005CB29B /* makefile.bc */,
				F966BC9908F27A3E005CB29B /* Makefile.in */,
				F966BC9A08F27A3E005CB29B /* makefile.vc */,
				F966BC9B08F27A3E005CB29B /* mkd.bat */,
				F966BC9C08F27A3E005CB29B /* nmakehlp.c */,
				F966BC9D08F27A3E005CB29B /* rc */,
				F966BCF308F27A3E005CB29B /* README */,
				F966BCF408F27A3E005CB29B /* rmd.bat */,
				F966BCF508F27A3F005CB29B /* rules.vc */,
				F966BCF608F27A3F005CB29B /* stubs.c */,
				F966BCF708F27A3F005CB29B /* tcl.m4 */,
				F966BCF808F27A3F005CB29B /* tkConfig.sh.in */,
				F966BCF908F27A3F005CB29B /* tkWin.h */,
				F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */,
				F966BCFB08F27A3F005CB29B /* tkWin3d.c */,
				F966BCFC08F27A3F005CB29B /* tkWinButton.c */,
				F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */,
				F966BCFE08F27A3F005CB29B /* tkWinColor.c */,
				F966BCFF08F27A3F005CB29B /* tkWinConfig.c */,
				F966BD0008F27A3F005CB29B /* tkWinCursor.c */,
				F966BD0108F27A3F005CB29B /* tkWinDefault.h */,
				F966BD0208F27A3F005CB29B /* tkWinDialog.c */,
				F966BD0308F27A3F005CB29B /* tkWinDraw.c */,
				F966BD0408F27A3F005CB29B /* tkWinEmbed.c */,
				F966BD0508F27A3F005CB29B /* tkWinFont.c */,
				F966BD0708F27A3F005CB29B /* tkWinImage.c */,
				F966BD0808F27A3F005CB29B /* tkWinInit.c */,
				F966BD0908F27A3F005CB29B /* tkWinInt.h */,
				F966BD0A08F27A3F005CB29B /* tkWinKey.c */,
				F966BD0B08F27A3F005CB29B /* tkWinMenu.c */,
				F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */,
				F966BD0D08F27A3F005CB29B /* tkWinPointer.c */,
				F966BD0E08F27A3F005CB29B /* tkWinPort.h */,
				F966BD0F08F27A3F005CB29B /* tkWinRegion.c */,
				F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */,
				F966BD1108F27A3F005CB29B /* tkWinSend.c */,
				F966BD1208F27A3F005CB29B /* tkWinSendCom.c */,
				F966BD1308F27A3F005CB29B /* tkWinSendCom.h */,
				F966BD1408F27A3F005CB29B /* tkWinTest.c */,
				F966BD1508F27A3F005CB29B /* tkWinWindow.c */,
				F966BD1608F27A3F005CB29B /* tkWinWm.c */,
				F966BD1708F27A3F005CB29B /* tkWinX.c */,
				F96888860AF78953000797B5 /* ttkWinMonitor.c */,
				F96888870AF78953000797B5 /* ttkWinTheme.c */,
				F96888880AF78953000797B5 /* ttkWinXPTheme.c */,
				F966BD1808F27A3F005CB29B /* winMain.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F966BC9D08F27A3E005CB29B /* rc */ = {
			isa = PBXGroup;
			children = (
				F966BCEE08F27A3E005CB29B /* tk.rc */,
				F966BCEF08F27A3E005CB29B /* tk_base.rc */,
				F966BCF208F27A3E005CB29B /* wish.rc */,
			);
			path = rc;
			sourceTree = "<group>";
		};
		F966BD1908F27A3F005CB29B /* xlib */ = {
			isa = PBXGroup;
			children = (
				F966BD1A08F27A3F005CB29B /* X11 */,
				F966BD2308F27A3F005CB29B /* xbytes.h */,
				F966BD2408F27A3F005CB29B /* xcolors.c */,
				F966BD2508F27A3F005CB29B /* xdraw.c */,
				F966BD2608F27A3F005CB29B /* xgc.c */,
				F966BD2708F27A3F005CB29B /* ximage.c */,
				F966BD2808F27A3F005CB29B /* xutil.c */,
			);
			path = xlib;
			sourceTree = "<group>";
		};
		F966BD1A08F27A3F005CB29B /* X11 */ = {
			isa = PBXGroup;
			children = (
				F966BD1B08F27A3F005CB29B /* cursorfont.h */,
				F966BD1C08F27A3F005CB29B /* keysym.h */,
				F966BD1D08F27A3F005CB29B /* keysymdef.h */,
				F966BD1E08F27A3F005CB29B /* X.h */,
				F966BD1F08F27A3F005CB29B /* Xatom.h */,
				F966BD2008F27A3F005CB29B /* Xfuncproto.h */,
				F966BD2108F27A3F005CB29B /* Xlib.h */,
				F966BD2208F27A3F005CB29B /* Xutil.h */,
			);
			path = X11;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */,
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F966C07608F2821B005CB29B /* Carbon.framework */,
				F94523A10E6FC2AC00C1D987 /* Cocoa.framework */,
				F966C07808F28233005CB29B /* IOKit.framework */,
				F9FD32140CC1AF170073837D /* libX11.dylib */,
				F9FD32150CC1AF170073837D /* libXext.dylib */,
				F9FD32160CC1AF170073837D /* libXss.dylib */,
				F9FD349A0CC1BB0D0073837D /* libXft.dylib */,
				F9FD34990CC1BB0D0073837D /* libfreetype.dylib */,
				F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96887DF0AF786D5000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96887E00AF786D5000797B5 /* ttk.decls */,
				F96887E10AF786D5000797B5 /* ttkBlink.c */,
				F96887E20AF786D5000797B5 /* ttkButton.c */,
				F96887E30AF786D5000797B5 /* ttkCache.c */,
				F96887E40AF786D5000797B5 /* ttkClamTheme.c */,
				F96887E50AF786D5000797B5 /* ttkClassicTheme.c */,
				F96887E60AF786D5000797B5 /* ttkDecls.h */,
				F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */,
				F96887E80AF786D5000797B5 /* ttkElements.c */,
				F96887E90AF786D5000797B5 /* ttkEntry.c */,
				F96887EA0AF786D5000797B5 /* ttkFrame.c */,
				F96887EB0AF786D5000797B5 /* ttkImage.c */,
				F96887EC0AF786D5000797B5 /* ttkInit.c */,
				F96887ED0AF786D5000797B5 /* ttkLabel.c */,
				F96887EE0AF786D5000797B5 /* ttkLayout.c */,
				F96887EF0AF786D5000797B5 /* ttkManager.c */,
				F96887F00AF786D5000797B5 /* ttkManager.h */,
				F96887F10AF786D5000797B5 /* ttkNotebook.c */,
				F96887F20AF786D5000797B5 /* ttkPanedwindow.c */,
				F96887F30AF786D5000797B5 /* ttkProgress.c */,
				F96887F40AF786D5000797B5 /* ttkScale.c */,
				F96887F50AF786D5000797B5 /* ttkScroll.c */,
				F96887F60AF786D5000797B5 /* ttkScrollbar.c */,
				F96887F70AF786D5000797B5 /* ttkSeparator.c */,
				F96887F80AF786D5000797B5 /* ttkSquare.c */,
				F96887F90AF786D5000797B5 /* ttkState.c */,
				F96887FA0AF786D5000797B5 /* ttkStubInit.c */,
				F96887FB0AF786D5000797B5 /* ttkStubLib.c */,
				F96887FC0AF786D5000797B5 /* ttkTagSet.c */,
				F96887FD0AF786D5000797B5 /* ttkTheme.c */,
				F96887FE0AF786D5000797B5 /* ttkTheme.h */,
				F96887FF0AF786D5000797B5 /* ttkThemeInt.h */,
				F96888000AF786D5000797B5 /* ttkTrace.c */,
				F96888010AF786D5000797B5 /* ttkTrack.c */,
				F96888020AF786D5000797B5 /* ttkTreeview.c */,
				F96888030AF786D5000797B5 /* ttkWidget.c */,
				F96888040AF786D5000797B5 /* ttkWidget.h */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888360AF787B3000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888370AF787B3000797B5 /* altTheme.tcl */,
				F96888380AF787B3000797B5 /* aquaTheme.tcl */,
				F96888390AF787B3000797B5 /* button.tcl */,
				F968883A0AF787B3000797B5 /* clamTheme.tcl */,
				F968883B0AF787B3000797B5 /* classicTheme.tcl */,
				F968883C0AF787B3000797B5 /* combobox.tcl */,
				F968883D0AF787B3000797B5 /* cursors.tcl */,
				F968883E0AF787B3000797B5 /* defaults.tcl */,
				F96888400AF787B3000797B5 /* entry.tcl */,
				F96888410AF787B3000797B5 /* fonts.tcl */,
				F96888440AF787B3000797B5 /* menubutton.tcl */,
				F96888450AF787B3000797B5 /* notebook.tcl */,
				F96888460AF787B3000797B5 /* panedwindow.tcl */,
				F96888470AF787B3000797B5 /* progress.tcl */,
				F96888480AF787B3000797B5 /* scale.tcl */,
				F96888490AF787B3000797B5 /* scrollbar.tcl */,
				F968884A0AF787B3000797B5 /* sizegrip.tcl */,
				F968884B0AF787B3000797B5 /* treeview.tcl */,
				F968884C0AF787B3000797B5 /* ttk.tcl */,
				F968884D0AF787B3000797B5 /* utils.tcl */,
				F968884E0AF787B3000797B5 /* winTheme.tcl */,
				F968884F0AF787B3000797B5 /* xpTheme.tcl */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888530AF7880C000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888540AF7880C000797B5 /* all.tcl */,
				F96888560AF7880C000797B5 /* combobox.test */,
				F96888570AF7880C000797B5 /* entry.test */,
				F96888580AF7880C000797B5 /* image.test */,
				F96888590AF7880C000797B5 /* labelframe.test */,
				F968885A0AF7880C000797B5 /* layout.test */,
				F968885C0AF7880C000797B5 /* notebook.test */,
				F968885D0AF7880C000797B5 /* panedwindow.test */,
				F968885E0AF7880C000797B5 /* progressbar.test */,
				F968885F0AF7880C000797B5 /* scrollbar.test */,
				F96888600AF7880C000797B5 /* treetags.test */,
				F96888610AF7880C000797B5 /* treeview.test */,
				F96888620AF7880C000797B5 /* ttk.test */,
				F96888630AF7880C000797B5 /* validate.test */,
				F962F7C60DADC26200648DB8 /* vsapi.test */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E0F08F272A5004A47F5 /* case.n */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96D3F3708F272A7004A47F5 /* tommath.h */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9008F272A8004A47F5 /* http1.0 */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
			isa = PBXGroup;
			children = (
				F96D3F9108F272A8004A47F5 /* http.tcl */,
				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http1.0;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D425F08F272B3004A47F5 /* bn.pdf */,
				F96D426108F272B3004A47F5 /* bn_error.c */,
				F96D426208F272B3004A47F5 /* bn_fast_mp_invmod.c */,
				F96D426308F272B3004A47F5 /* bn_fast_mp_montgomery_reduce.c */,
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426508F272B3004A47F5 /* bn_fast_s_mp_mul_high_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426708F272B3004A47F5 /* bn_mp_2expt.c */,
				F96D426808F272B3004A47F5 /* bn_mp_abs.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426B08F272B3004A47F5 /* bn_mp_addmod.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427308F272B3004A47F5 /* bn_mp_cnt_lsb.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427B08F272B3004A47F5 /* bn_mp_dr_is_modulus.c */,
				F96D427C08F272B3004A47F5 /* bn_mp_dr_reduce.c */,
				F96D427D08F272B3004A47F5 /* bn_mp_dr_setup.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
				F96D428008F272B3004A47F5 /* bn_mp_exptmod.c */,
				F96D428108F272B3004A47F5 /* bn_mp_exptmod_fast.c */,
				F96D428208F272B3004A47F5 /* bn_mp_exteuclid.c */,
				F96D428308F272B3004A47F5 /* bn_mp_fread.c */,
				F96D428408F272B3004A47F5 /* bn_mp_fwrite.c */,
				F96D428508F272B3004A47F5 /* bn_mp_gcd.c */,
				F96D428608F272B3004A47F5 /* bn_mp_get_int.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428C08F272B3004A47F5 /* bn_mp_init_set_int.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D428E08F272B3004A47F5 /* bn_mp_invmod.c */,
				F96D428F08F272B3004A47F5 /* bn_mp_invmod_slow.c */,
				F96D429008F272B3004A47F5 /* bn_mp_is_square.c */,
				F96D429108F272B3004A47F5 /* bn_mp_jacobi.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429408F272B3004A47F5 /* bn_mp_lcm.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429808F272B3004A47F5 /* bn_mp_mod_d.c */,
				F96D429908F272B3004A47F5 /* bn_mp_montgomery_calc_normalization.c */,
				F96D429A08F272B3004A47F5 /* bn_mp_montgomery_reduce.c */,
				F96D429B08F272B3004A47F5 /* bn_mp_montgomery_setup.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A008F272B3004A47F5 /* bn_mp_mulmod.c */,
				F96D42A108F272B3004A47F5 /* bn_mp_n_root.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42A408F272B3004A47F5 /* bn_mp_prime_fermat.c */,
				F96D42A508F272B3004A47F5 /* bn_mp_prime_is_divisible.c */,
				F96D42A608F272B3004A47F5 /* bn_mp_prime_is_prime.c */,
				F96D42A708F272B3004A47F5 /* bn_mp_prime_miller_rabin.c */,
				F96D42A808F272B3004A47F5 /* bn_mp_prime_next_prime.c */,
				F96D42A908F272B3004A47F5 /* bn_mp_prime_rabin_miller_trials.c */,
				F96D42AA08F272B3004A47F5 /* bn_mp_prime_random_ex.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AD08F272B3004A47F5 /* bn_mp_rand.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42AF08F272B3004A47F5 /* bn_mp_read_signed_bin.c */,
				F96D42B008F272B3004A47F5 /* bn_mp_read_unsigned_bin.c */,
				F96D42B108F272B3004A47F5 /* bn_mp_reduce.c */,
				F96D42B208F272B3004A47F5 /* bn_mp_reduce_2k.c */,
				F96D42B308F272B3004A47F5 /* bn_mp_reduce_2k_l.c */,
				F96D42B408F272B3004A47F5 /* bn_mp_reduce_2k_setup.c */,
				F96D42B508F272B3004A47F5 /* bn_mp_reduce_2k_setup_l.c */,
				F96D42B608F272B3004A47F5 /* bn_mp_reduce_is_2k.c */,
				F96D42B708F272B3004A47F5 /* bn_mp_reduce_is_2k_l.c */,
				F96D42B808F272B3004A47F5 /* bn_mp_reduce_setup.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BB08F272B3004A47F5 /* bn_mp_set_int.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BD08F272B3004A47F5 /* bn_mp_signed_bin_size.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42BF08F272B3004A47F5 /* bn_mp_sqrmod.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C308F272B3004A47F5 /* bn_mp_submod.c */,
				F96D42C408F272B3004A47F5 /* bn_mp_to_signed_bin.c */,
				F96D42C508F272B3004A47F5 /* bn_mp_to_signed_bin_n.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CA08F272B3004A47F5 /* bn_mp_toradix.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42CF08F272B3004A47F5 /* bn_prime_tab.c */,
				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D208F272B3004A47F5 /* bn_s_mp_exptmod.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D408F272B3004A47F5 /* bn_s_mp_mul_high_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D42D708F272B3004A47F5 /* bncore.c */,
				F96D42D908F272B3004A47F5 /* callgraph.txt */,
				F96D42DA08F272B3004A47F5 /* changes.txt */,
				F96D42F008F272B3004A47F5 /* LICENSE */,
				F96D431D08F272B4004A47F5 /* poster.pdf */,
				F96D432608F272B4004A47F5 /* tommath.pdf */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437E08F272B6004A47F5 /* ioUtil.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.in */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D442C08F272B8004A47F5 /* man2help.tcl */,
				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
				F96D442E08F272B8004A47F5 /* man2html.tcl */,
				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
				F96D443008F272B8004A47F5 /* man2html2.tcl */,
				F96D443108F272B8004A47F5 /* man2tcl.c */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443408F272B8004A47F5 /* str2c */,
				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
				F96D443608F272B8004A47F5 /* tcl.wse.in */,
				F96D443708F272B9004A47F5 /* tclmin.wse */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.in */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446A08F272B9004A47F5 /* tclUnixThrd.h */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447308F272BA004A47F5 /* coffbase.txt */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.in */,
				F96D447608F272BA004A47F5 /* makefile.bc */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tktest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* ShellScript */,
				F9A5C5F608F651AB008AE941 /* ShellScript */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tktest;
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = 8DD76FB20486AB0100D96B5E /* tktest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tktest-X11 */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */;
			buildPhases = (
				F9FD30B40CC1AD070073837D /* ShellScript */,
				F9FD30B50CC1AD070073837D /* ShellScript */,
				F9FD30BB0CC1AD070073837D /* Sources */,
				F9FD31E30CC1AD070073837D /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = "tktest-X11";
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = F9FD31F40CC1AD070073837D /* tktest-X11 */;
			productType = "com.apple.product-type.tool";
		};
		F9E61D16090A3E94002B3151 /* Tk */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* ShellScript */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tk;
			productName = Wish;
			productReference = F9A3084B08F2D4CE00BAE1AB /* Wish.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Wish" */;
			compatibilityVersion = "Xcode 3.2";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Wish */;
			projectDirPath = "";
			projectRoot = ..;
			targets = (
				F9E61D16090A3E94002B3151 /* Tk */,
				8DD76FA90486AB0100D96B5E /* tktest */,
				F97258A50A86873C00096C78 /* tktest-X11 */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F97AF02F0B665DA900310EA2 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			outputPaths = (
				"${TARGET_BUILD_DIR}/${WRAPPER_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "gnumake -C \"${TK_SRCROOT}/macosx\"  -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" APPLICATION_INSTALL_PATH=\"${APPLICATION_INSTALL_PATH}\" TCL_BUILD_DIR=\"${TCL_BUILD_DIR}\" TCL_FRAMEWORK_DIR=\"${TCL_FRAMEWORK_DIR}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${BUILT_PRODUCTS_DIR}/tktest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tktest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.in",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F608F651AB008AE941 /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.in",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
		F9FD30B40CC1AD070073837D /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.in",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --disable-corefoundation ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B50CC1AD070073837D /* ShellScript */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.in",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --disable-corefoundation --enable-xft --with-tcl=../tcl ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
				F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */,
				F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */,
				F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */,
				F966BDD308F27A3F005CB29B /* tkBind.c in Sources */,
				F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */,
				F966BDD508F27A3F005CB29B /* tkButton.c in Sources */,
				F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */,
				F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */,
				F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */,
				F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */,
				F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */,
				F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */,
				F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */,
				F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */,
				F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */,
				F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */,
				F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */,
				F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */,
				F966BDE508F27A3F005CB29B /* tkColor.c in Sources */,
				F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */,
				F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */,
				F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */,
				F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */,
				F966BDED08F27A3F005CB29B /* tkError.c in Sources */,
				F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */,
				F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */,
				F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */,
				F966BDF208F27A3F005CB29B /* tkFont.c in Sources */,
				F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */,
				F966BDF508F27A3F005CB29B /* tkGC.c in Sources */,
				F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */,
				F966BDF708F27A3F005CB29B /* tkGet.c in Sources */,
				F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */,
				F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */,
				F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */,
				F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */,
				F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */,
				F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */,
				F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */,
				F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */,
				F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */,
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
				F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */,
				F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */,
				F966BE2008F27A40005CB29B /* tkSquare.c in Sources */,
				F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */,
				F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */,
				F966BE2408F27A40005CB29B /* tkStyle.c in Sources */,
				F966BE2508F27A40005CB29B /* tkTest.c in Sources */,
				F966BE2608F27A40005CB29B /* tkText.c in Sources */,
				F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */,
				F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */,
				F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */,
				F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */,
				F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */,
				F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */,
				F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */,
				F966BE3008F27A40005CB29B /* tkTrig.c in Sources */,
				F966BE3108F27A40005CB29B /* tkUndo.c in Sources */,
				F966BE3308F27A40005CB29B /* tkUtil.c in Sources */,
				F966BE3408F27A40005CB29B /* tkVisual.c in Sources */,
				F966BE3508F27A40005CB29B /* tkWindow.c in Sources */,
				F96888050AF786D5000797B5 /* ttkBlink.c in Sources */,
				F96888060AF786D5000797B5 /* ttkButton.c in Sources */,
				F96888070AF786D5000797B5 /* ttkCache.c in Sources */,
				F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */,
				F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */,
				F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */,
				F968880B0AF786D5000797B5 /* ttkElements.c in Sources */,
				F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */,
				F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */,
				F968880E0AF786D5000797B5 /* ttkImage.c in Sources */,
				F968880F0AF786D5000797B5 /* ttkInit.c in Sources */,
				F96888100AF786D5000797B5 /* ttkLabel.c in Sources */,
				F96888110AF786D5000797B5 /* ttkLayout.c in Sources */,
				F96888120AF786D5000797B5 /* ttkManager.c in Sources */,
				F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */,
				F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */,
				F96888150AF786D5000797B5 /* ttkProgress.c in Sources */,
				F96888160AF786D5000797B5 /* ttkScale.c in Sources */,
				F96888170AF786D5000797B5 /* ttkScroll.c in Sources */,
				F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */,
				F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */,
				F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */,
				F968881B0AF786D5000797B5 /* ttkState.c in Sources */,
				F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */,
				F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */,
				F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */,
				F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */,
				F96888200AF786D5000797B5 /* ttkTrace.c in Sources */,
				F96888210AF786D5000797B5 /* ttkTrack.c in Sources */,
				F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */,
				F96888230AF786D5000797B5 /* ttkWidget.c in Sources */,
				F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */,
				F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */,
				F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */,
				F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */,
				F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */,
				F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */,
				F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */,
				F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */,
				F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */,
				F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */,
				F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */,
				F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */,
				F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */,
				F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */,
				F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */,
				F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */,
				F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */,
				F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */,
				F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */,
				F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */,
				F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */,
				F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */,
				F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */,
				F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */,
				F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */,
				F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */,
				F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */,
				F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */,
				F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */,
				F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */,
				F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */,
				F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */,
				F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */,
				F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */,
				F966C02A08F27A42005CB29B /* xcolors.c in Sources */,
				F966C02B08F27A42005CB29B /* xdraw.c in Sources */,
				F966C02C08F27A42005CB29B /* xgc.c in Sources */,
				F966C02D08F27A42005CB29B /* ximage.c in Sources */,
				F966C02E08F27A42005CB29B /* xutil.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD30BB0CC1AD070073837D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */,
				F9FD30BD0CC1AD070073837D /* regerror.c in Sources */,
				F9FD30BE0CC1AD070073837D /* regexec.c in Sources */,
				F9FD30BF0CC1AD070073837D /* regfree.c in Sources */,
				F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */,
				F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */,
				F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */,
				F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */,
				F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */,
				F9FD30C50CC1AD070073837D /* tclClock.c in Sources */,
				F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */,
				F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */,
				F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */,
				F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */,
				F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */,
				F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */,
				F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */,
				F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */,
				F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */,
				F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */,
				F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */,
				F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */,
				F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */,
				F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */,
				F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */,
				F9FD30D50CC1AD070073837D /* tclGet.c in Sources */,
				F9FD30D60CC1AD070073837D /* tclHash.c in Sources */,
				F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */,
				F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */,
				F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */,
				F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */,
				F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */,
				F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */,
				F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */,
				F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */,
				F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */,
				F9FD30E00CC1AD070073837D /* tclLink.c in Sources */,
				F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */,
				F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */,
				F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */,
				F9FD30E40CC1AD070073837D /* tclMain.c in Sources */,
				F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */,
				F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */,
				F9FD30E70CC1AD070073837D /* tclObj.c in Sources */,
				F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */,
				F9FD30E90CC1AD070073837D /* tclParse.c in Sources */,
				F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */,
				F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */,
				F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */,
				F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */,
				F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */,
				F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */,
				F9FD30F00CC1AD070073837D /* tclProc.c in Sources */,
				F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */,
				F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */,
				F9FD30F30CC1AD070073837D /* tclResult.c in Sources */,
				F9FD30F40CC1AD070073837D /* tclScan.c in Sources */,
				F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */,
				F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */,
				F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */,
				F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */,
				F9FD30F90CC1AD070073837D /* tclThread.c in Sources */,
				F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */,
				F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */,
				F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */,
				F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */,
				F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */,
				F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */,
				F9FD31000CC1AD070073837D /* tclUtf.c in Sources */,
				F9FD31010CC1AD070073837D /* tclUtil.c in Sources */,
				F9FD31020CC1AD070073837D /* tclVar.c in Sources */,
				F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */,
				F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */,
				F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */,
				F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */,
				F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */,
				F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */,
				F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */,
				F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */,
				F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */,
				F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */,
				F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */,
				F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */,
				F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */,
				F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */,
				F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */,
				F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */,
				F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */,
				F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */,
				F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */,
				F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */,
				F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */,
				F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */,
				F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */,
				F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */,
				F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */,
				F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */,
				F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */,
				F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */,
				F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */,
				F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */,
				F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */,
				F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */,
				F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */,
				F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */,
				F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */,
				F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */,
				F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */,
				F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */,
				F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */,
				F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */,
				F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */,
				F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */,
				F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */,
				F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */,
				F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */,
				F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */,
				F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */,
				F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */,
				F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */,
				F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */,
				F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */,
				F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */,
				F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */,
				F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */,
				F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */,
				F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */,
				F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */,
				F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */,
				F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */,
				F9FD313F0CC1AD070073837D /* bncore.c in Sources */,
				F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */,
				F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */,
				F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */,
				F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */,
				F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */,
				F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */,
				F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */,
				F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */,
				F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */,
				F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */,
				F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */,
				F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */,
				F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */,
				F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */,
				F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */,
				F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */,
				F9FD314F0CC1AD070073837D /* tk3d.c in Sources */,
				F9FD31500CC1AD070073837D /* tkArgv.c in Sources */,
				F9FD31510CC1AD070073837D /* tkAtom.c in Sources */,
				F9FD31520CC1AD070073837D /* tkBind.c in Sources */,
				F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */,
				F9FD31540CC1AD070073837D /* tkButton.c in Sources */,
				F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */,
				F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */,
				F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */,
				F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */,
				F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */,
				F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */,
				F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */,
				F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */,
				F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */,
				F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */,
				F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */,
				F9FD31600CC1AD070073837D /* tkCmds.c in Sources */,
				F9FD31610CC1AD070073837D /* tkColor.c in Sources */,
				F9FD31620CC1AD070073837D /* tkConfig.c in Sources */,
				F9FD31630CC1AD070073837D /* tkConsole.c in Sources */,
				F9FD31640CC1AD070073837D /* tkCursor.c in Sources */,
				F9FD31650CC1AD070073837D /* tkEntry.c in Sources */,
				F9FD31660CC1AD070073837D /* tkError.c in Sources */,
				F9FD31670CC1AD070073837D /* tkEvent.c in Sources */,
				F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */,
				F9FD31690CC1AD070073837D /* tkFocus.c in Sources */,
				F9FD316A0CC1AD070073837D /* tkFont.c in Sources */,
				F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */,
				F9FD316C0CC1AD070073837D /* tkGC.c in Sources */,
				F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */,
				F9FD316E0CC1AD070073837D /* tkGet.c in Sources */,
				F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */,
				F9FD31700CC1AD070073837D /* tkGrid.c in Sources */,
				F9FD31710CC1AD070073837D /* tkImage.c in Sources */,
				F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */,
				F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */,
				F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */,
				F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */,
				F9FD31760CC1AD070073837D /* tkListbox.c in Sources */,
				F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */,
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
				F9FD31880CC1AD070073837D /* tkSelect.c in Sources */,
				F9FD31890CC1AD070073837D /* tkSquare.c in Sources */,
				F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */,
				F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */,
				F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */,
				F9FD318D0CC1AD070073837D /* tkTest.c in Sources */,
				F9FD318E0CC1AD070073837D /* tkText.c in Sources */,
				F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */,
				F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */,
				F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */,
				F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */,
				F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */,
				F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */,
				F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */,
				F9FD31960CC1AD070073837D /* tkTrig.c in Sources */,
				F9FD31970CC1AD070073837D /* tkUndo.c in Sources */,
				F9FD31980CC1AD070073837D /* tkUtil.c in Sources */,
				F9FD31990CC1AD070073837D /* tkVisual.c in Sources */,
				F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */,
				F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */,
				F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */,
				F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */,
				F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */,
				F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */,
				F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */,
				F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */,
				F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */,
				F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */,
				F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */,
				F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */,
				F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */,
				F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */,
				F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */,
				F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */,
				F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */,
				F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */,
				F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */,
				F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */,
				F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */,
				F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */,
				F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */,
				F9FD31B10CC1AD070073837D /* ttkState.c in Sources */,
				F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */,
				F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */,
				F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */,
				F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */,
				F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */,
				F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */,
				F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */,
				F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */,
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
				F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */,
				F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */,
				F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */,
				F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */,
				F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */,
				F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */,
				F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */,
				F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		F90E36D50F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D60F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D70F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc42 nogc";
		};
		F90E36D80F3B5C8400810A10 /* Debug gcc42 nogc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc42 nogc";
		};
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixZL;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoFixZL;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_32_BIT)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixZL;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixZL */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixZL;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc42";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc42";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc42";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc42";
		};
		F9988AB50D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CC = "$(DEVELOPER_DIR)/usr/bin/llvm-gcc-4.2";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB60D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB70D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug llvmgcc42";
		};
		F9988AB80D814C7500B6B03B /* Debug llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug llvmgcc42";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.2;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc42";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CC = "$(DEVELOPER_DIR)/usr/bin/llvm-gcc-4.2";
				CFLAGS = "-arch i386 -arch x86_64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
				TCL_CONFIGURE_ARGS = "$(TCL_CONFIGURE_ARGS) --disable-dtrace";
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvmgcc42 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvmgcc42";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_32_BIT)",
					"$(NATIVE_ARCH_64_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugLeaks;
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Wish-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9988AB20D814C6500B6B03B /* Debug gcc42 */,
				F90E36D60F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB60D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixZL */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9988AB30D814C6500B6B03B /* Debug gcc42 */,
				F90E36D70F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB70D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixZL */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Wish" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9988AB10D814C6500B6B03B /* Debug gcc42 */,
				F90E36D50F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB50D814C7500B6B03B /* Debug llvmgcc42 */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixZL */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9988AB40D814C6500B6B03B /* Debug gcc42 */,
				F90E36D80F3B5C8400810A10 /* Debug gcc42 nogc */,
				F9988AB80D814C7500B6B03B /* Debug llvmgcc42 */,
				F97258AB0A86873D00096C78 /* DebugNoFixZL */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc42 */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvmgcc42 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

Changes to macosx/configure.ac.

1
2
3
4
5
6
7
8
9
10
11
#! /bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tk installation
dnl	to configure the system for the local environment.

dnl	Ensure that the config (auto)headers support is used, then just
dnl	include the configure sources from ../unix:

m4_include(../unix/aclocal.m4)
m4_define(SC_USE_CONFIG_HEADERS)
m4_include(../unix/configure.ac)










|
1
2
3
4
5
6
7
8
9
10
11
#! /bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tk installation
dnl	to configure the system for the local environment.

dnl	Ensure that the config (auto)headers support is used, then just
dnl	include the configure sources from ../unix:

m4_include(../unix/aclocal.m4)
m4_define(SC_USE_CONFIG_HEADERS)
m4_include(../unix/configure.in)

Changes to macosx/tkMacOSX.h.

22
23
24
25
26
27
28
29
30
31
32
33
34
 * Structures and function types for handling Netscape-type in process
 * embedding where Tk does not control the top-level
 */

typedef int (Tk_MacOSXEmbedRegisterWinProc) (long winID, Tk_Window window);
typedef void* (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window);
typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window);
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, void *rgn);
typedef void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, void *ulCorner);

#include "tkPlatDecls.h"

#endif /* _TKMAC */







|





22
23
24
25
26
27
28
29
30
31
32
33
34
 * Structures and function types for handling Netscape-type in process
 * embedding where Tk does not control the top-level
 */

typedef int (Tk_MacOSXEmbedRegisterWinProc) (long winID, Tk_Window window);
typedef void* (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window);
typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window);
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, TkRegion rgn);
typedef void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, void *ulCorner);

#include "tkPlatDecls.h"

#endif /* _TKMAC */

Changes to macosx/tkMacOSXBitmap.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
/*
 * This structure holds information about native bitmaps.
 */

typedef struct {
    const char *name;		/* Name of icon. */
    OSType iconType;		/* OSType of icon. */







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"

/*
 * This structure holds information about native bitmaps.
 */

typedef struct {
    const char *name;		/* Name of icon. */
    OSType iconType;		/* OSType of icon. */
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    {"ramdisk",		kGenericRAMDiskIcon},
    {"cdrom",		kGenericCDROMIcon},
    {"preferences",	kGenericPreferencesIcon},
    {"querydoc",	kGenericQueryDocumentIcon},
    {"stop",		kAlertStopIcon},
    {"note",		kAlertNoteIcon},
    {"caution",		kAlertCautionIcon},
    {NULL,			0}
};

#define builtInIconSize 32

#define OSTYPE_TO_UTI(x) (NSString *)UTTypeCreatePreferredIdentifierForTag( \
     kUTTagClassOSType, UTCreateStringForOSType(x), nil)

static Tcl_HashTable iconBitmapTable = {};
typedef struct {
    int kind, width, height;
    char *value;
} IconBitmap;

static const char *const iconBitmapOptionStrings[] = {
    "-file", "-fileType", "-osType", "-systemType", "-namedImage",
    "-imageFile", NULL
};
enum iconBitmapOptions {
    ICON_FILE, ICON_FILETYPE, ICON_OSTYPE, ICON_SYSTEMTYPE, ICON_NAMEDIMAGE,
    ICON_IMAGEFILE,
};







|




<
<
<






|







40
41
42
43
44
45
46
47
48
49
50
51



52
53
54
55
56
57
58
59
60
61
62
63
64
65
    {"ramdisk",		kGenericRAMDiskIcon},
    {"cdrom",		kGenericCDROMIcon},
    {"preferences",	kGenericPreferencesIcon},
    {"querydoc",	kGenericQueryDocumentIcon},
    {"stop",		kAlertStopIcon},
    {"note",		kAlertNoteIcon},
    {"caution",		kAlertCautionIcon},
    {NULL}
};

#define builtInIconSize 32




static Tcl_HashTable iconBitmapTable = {};
typedef struct {
    int kind, width, height;
    char *value;
} IconBitmap;

static const char *iconBitmapOptionStrings[] = {
    "-file", "-fileType", "-osType", "-systemType", "-namedImage",
    "-imageFile", NULL
};
enum iconBitmapOptions {
    ICON_FILE, ICON_FILETYPE, ICON_OSTYPE, ICON_SYSTEMTYPE, ICON_NAMEDIMAGE,
    ICON_IMAGEFILE,
};
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177

178

179

180
181



182

183

184
185
186
187
188
189
190
191
	Tcl_HashEntry *predefHashPtr;
	Tk_Uid name;
	int isNew;

	name = Tk_GetUid(builtInPtr->name);
	predefHashPtr = Tcl_CreateHashEntry(tablePtr, name, &isNew);
	if (isNew) {
	    TkPredefBitmap *predefPtr = (TkPredefBitmap *)ckalloc(sizeof(TkPredefBitmap));

	    predefPtr->source = UINT2PTR(builtInPtr->iconType);
	    predefPtr->width = builtInIconSize;
	    predefPtr->height = builtInIconSize;
	    predefPtr->native = 1;
	    Tcl_SetHashValue(predefHashPtr, predefPtr);
	}
    }
}


/*
 *----------------------------------------------------------------------
 *
 * PixmapFromImage --
 *
 * Results:
 *	Returns a Pixmap with an NSImage drawn into it.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Pixmap
PixmapFromImage(
    Display *display,
    NSImage* image,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
    if (TkMacOSXSetupDrawingContext(pixmap, NULL, &dc)) {
	if (dc.context) {
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
				    .tx = 0, .ty = size.height};


	    CGContextConcatCTM(dc.context, t);
	    [NSGraphicsContext saveGraphicsState];
	    [NSGraphicsContext setCurrentContext:GET_NSCONTEXT(dc.context, NO)];
	    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect
		operation:NSCompositeCopy fraction:1.0];
	    [NSGraphicsContext restoreGraphicsState];
	}
	TkMacOSXRestoreDrawingContext(&dc);
    }
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateNativeBitmap --
 *
 *	Create native bitmap.
 *
 * Results:
 *	Native bitmap.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Pixmap
TkpCreateNativeBitmap(
    Display *display,
    const void *source)		/* Info about the icon to build. */
{

    NSString *iconUTI = OSTYPE_TO_UTI(PTR2UINT(source));

    NSImage *iconImage = [[NSWorkspace sharedWorkspace]

			     iconForFileType: iconUTI];

    CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
    Pixmap pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));



    return pixmap;

}



/*
 *----------------------------------------------------------------------
 *
 * OSTypeFromString --
 *
 *	Helper to convert string to OSType.







|
|








<




|


|








|

|






|

|
|
>
>

<
|
<
|
<





<




















|

>
|
>
|
>
|
>
|
<
>
>
>
|
>
|
>
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142

143

144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
	Tcl_HashEntry *predefHashPtr;
	Tk_Uid name;
	int isNew;

	name = Tk_GetUid(builtInPtr->name);
	predefHashPtr = Tcl_CreateHashEntry(tablePtr, name, &isNew);
	if (isNew) {
	    TkPredefBitmap *predefPtr = (TkPredefBitmap *)
		    ckalloc(sizeof(TkPredefBitmap));
	    predefPtr->source = UINT2PTR(builtInPtr->iconType);
	    predefPtr->width = builtInIconSize;
	    predefPtr->height = builtInIconSize;
	    predefPtr->native = 1;
	    Tcl_SetHashValue(predefHashPtr, predefPtr);
	}
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetBitmapForIcon --
 *
 * Results:
 *	Bitmap for the given IconRef.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Pixmap
GetBitmapForIcon(
    Display *display,
    IconRef icon,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
    if (TkMacOSXSetupDrawingContext(pixmap, NULL, 1, &dc)) {
	if (dc.context) {
	    const CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
		    .tx = 0, .ty = size.height };
	    const CGRect r = { .origin = { .x = 0, .y = 0 }, .size = size };

	    CGContextConcatCTM(dc.context, t);

	    PlotIconRefInContext(dc.context, &r, kAlignAbsoluteCenter,

		    kTransformNone, NULL, kPlotIconRefNormalFlags, icon);

	}
	TkMacOSXRestoreDrawingContext(&dc);
    }
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateNativeBitmap --
 *
 *	Create native bitmap.
 *
 * Results:
 *	Native bitmap.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Pixmap
TkpCreateNativeBitmap(
    Display *display,
    const char *source)		/* Info about the icon to build. */
{
    Pixmap pixmap;
    IconRef icon;
    OSErr err;

    err = ChkErr(GetIconRef, kOnSystemDisk, kSystemIconsCreator,
	    PTR2UINT(source), &icon);
    if (err == noErr) {
	pixmap = GetBitmapForIcon(display, icon, CGSizeMake(builtInIconSize,

		builtInIconSize));
	ReleaseIconRef(icon);
    } else {
	pixmap = Tk_GetPixmap(display, None, builtInIconSize,
		builtInIconSize, 0);
    }
    return pixmap;
}

/*
 *----------------------------------------------------------------------
 *
 * OSTypeFromString --
 *
 *	Helper to convert string to OSType.
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    int result = TCL_ERROR;
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    Tcl_UtfToExternalDString(encoding, s, -1, &ds);
    if (Tcl_DStringLength(&ds) <= 4) {
	char string[4] = {};
	memcpy(string, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	*t = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
	     (OSType) string[2] <<  8 | (OSType) string[3];
	result = TCL_OK;
    }
    Tcl_DStringFree(&ds);
    Tcl_FreeEncoding(encoding);
    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * TkpGetNativeAppBitmap --
 *
 *	Get a named native bitmap.







|








<







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
    int result = TCL_ERROR;
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    Tcl_UtfToExternalDString(encoding, s, -1, &ds);
    if (Tcl_DStringLength(&ds) <= 4) {
	char string[4] = {};
	memcpy(string, Tcl_DStringValue(&ds), (size_t) Tcl_DStringLength(&ds));
	*t = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
	     (OSType) string[2] <<  8 | (OSType) string[3];
	result = TCL_OK;
    }
    Tcl_DStringFree(&ds);
    Tcl_FreeEncoding(encoding);
    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * TkpGetNativeAppBitmap --
 *
 *	Get a named native bitmap.
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310















311
312




313










314
315
316
317
318

319

320




321
322
323
324
325
326
327
	if (image) {
	    [image setSize:size];
	}
    } else {
	string = [NSString stringWithUTF8String:name];
	image = [NSImage imageNamed:string];
	if (!image) {
	    NSURL *url = [NSURL fileURLWithPath:string];
	    if (url) {
		image = [[[NSImage alloc] initWithContentsOfURL:url]
			autorelease];
	    }
	}
	if (image) {
	    size = [image size];
	}
    }
    if (image) {















	*width = size.width;
	*height = size.height;




	pixmap = PixmapFromImage(display, image, NSSizeToCGSize(size));










    } else if (name) {
	OSType iconType;
	if (OSTypeFromString(name, &iconType) == TCL_OK) {
	    NSString *iconUTI = OSTYPE_TO_UTI(iconType);
	    NSImage *iconImage = [[NSWorkspace sharedWorkspace]

				     iconForFileType: iconUTI];

	    pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));




	}
    }
    return pixmap;
}

/*
 *----------------------------------------------------------------------







|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
|
>
>
>
>
>
>
>
>
>
>



|
<
>
|
>
|
>
>
>
>







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	if (image) {
	    [image setSize:size];
	}
    } else {
	string = [NSString stringWithUTF8String:name];
	image = [NSImage imageNamed:string];
	if (!image) {
	    NSURL *url = [NSURL URLWithString:string];
	    if (url) {
		image = [[[NSImage alloc] initWithContentsOfURL:url]
			autorelease];
	    }
	}
	if (image) {
	    size = [image size];
	}
    }
    if (image) {
	TkMacOSXDrawingContext dc;
	int depth = 0;

#ifdef MAC_OSX_TK_TODO
	for (NSImageRep *r in [image representations]) {
	    NSInteger bitsPerSample = [r bitsPerSample];
	    if (bitsPerSample && bitsPerSample > depth) {
		depth = bitsPerSample;
	    };
	}
	if (depth == 1) {
	    /* TODO: convert BW NSImage to CGImageMask */
	}
#endif
	pixmap = Tk_GetPixmap(display, None, size.width, size.height, depth);
	*width = size.width;
	*height = size.height;
	if (TkMacOSXSetupDrawingContext(pixmap, NULL, 1, &dc)) {
	    if (dc.context) {
		CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
			.tx = 0, .ty = size.height};

		CGContextConcatCTM(dc.context, t);
		[NSGraphicsContext saveGraphicsState];
		[NSGraphicsContext setCurrentContext:[NSGraphicsContext
			graphicsContextWithGraphicsPort:dc.context flipped:NO]];
		[image drawAtPoint:NSZeroPoint fromRect:NSZeroRect
			operation:NSCompositeCopy fraction:1.0];
		[NSGraphicsContext restoreGraphicsState];
	    }
	    TkMacOSXRestoreDrawingContext(&dc);
	}
    } else if (name) {
	OSType iconType;
	if (OSTypeFromString(name, &iconType) == TCL_OK) {
	    IconRef icon;

	    OSErr err = ChkErr(GetIconRef, kOnSystemDisk, kSystemIconsCreator,
		    iconType, &icon);
	    if (err == noErr) {
		pixmap = GetBitmapForIcon(display, icon, NSSizeToCGSize(size));
		*width = size.width;
		*height = size.height;
		ReleaseIconRef(icon);
	    }
	}
    }
    return pixmap;
}

/*
 *----------------------------------------------------------------------
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXIconBitmapObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_HashEntry *hPtr;
    int i = 1, len, isNew, result = TCL_ERROR;
    const char *name, *value;
    IconBitmap ib, *iconBitmap;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 1, objv, "name width height "
		"-file|-fileType|-osType|-systemType|-namedImage|-imageFile "
		"value");
	goto end;
    }
    name = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap name", -1));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "BAD", NULL);
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.width) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.height) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[i++], iconBitmapOptionStrings,
	    sizeof(char *), "kind", TCL_EXACT, &ib.kind) != TCL_OK) {
	goto end;
    }
    value = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap value", -1));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "EMPTY", NULL);
	goto end;
    }
#if 0
    if ((kind == ICON_TYPE || kind == ICON_SYSTEM)) {
	Tcl_DString ds;
 	Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

	Tcl_UtfToExternalDString(encoding, value, -1, &ds);
	len = Tcl_DStringLength(&ds);
	Tcl_DStringFree(&ds);
	Tcl_FreeEncoding(encoding);
	if (len > 4) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid bitmap value", -1));
	    Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "INVALID", NULL);
	    goto end;
	}
    }
#endif
    ib.value = (char *)ckalloc(len + 1);
    strcpy(ib.value, value);
    if (!iconBitmapTable.buckets) {
	Tcl_InitHashTable(&iconBitmapTable, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(&iconBitmapTable, name, &isNew);
    if (!isNew) {
	iconBitmap = Tcl_GetHashValue(hPtr);
	ckfree(iconBitmap->value);
    } else {
	iconBitmap = (IconBitmap *)ckalloc(sizeof(IconBitmap));
	Tcl_SetHashValue(hPtr, iconBitmap);
    }
    *iconBitmap = ib;
    result = TCL_OK;
  end:
    return result;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

















|
<








|
|




|
<






<





<
|
<




|









|




|











372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418

419
420
421
422
423

424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXIconBitmapObjCmd(
    ClientData clientData,	/* Unused. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_HashEntry *hPtr;
    int i = 1, len, isNew, result = TCL_ERROR;
    const char *name, *value;
    IconBitmap ib, *iconBitmap;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 1, objv, "name width height "
		"-file|-fileType|-osType|-systemType|-namedImage|-imageFile "
		"value");
	goto end;
    }
    name = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_AppendResult(interp, "empty bitmap name", NULL);

	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.width) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.height) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIndexFromObj(interp, objv[i++], iconBitmapOptionStrings,
	    "kind", TCL_EXACT, &ib.kind) != TCL_OK) {
	goto end;
    }
    value = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_AppendResult(interp, "empty bitmap value", NULL);

	goto end;
    }
#if 0
    if ((kind == ICON_TYPE || kind == ICON_SYSTEM)) {
	Tcl_DString ds;
 	Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

	Tcl_UtfToExternalDString(encoding, value, -1, &ds);
	len = Tcl_DStringLength(&ds);
	Tcl_DStringFree(&ds);
	Tcl_FreeEncoding(encoding);
	if (len > 4) {

	    Tcl_AppendResult(interp, "invalid bitmap value", NULL);

	    goto end;
	}
    }
#endif
    ib.value = ckalloc(len + 1);
    strcpy(ib.value, value);
    if (!iconBitmapTable.buckets) {
	Tcl_InitHashTable(&iconBitmapTable, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(&iconBitmapTable, name, &isNew);
    if (!isNew) {
	iconBitmap = Tcl_GetHashValue(hPtr);
	ckfree(iconBitmap->value);
    } else {
	iconBitmap = (IconBitmap *) ckalloc(sizeof(IconBitmap));
	Tcl_SetHashValue(hPtr, iconBitmap);
    }
    *iconBitmap = ib;
    result = TCL_OK;
end:
    return result;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXButton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26

27


28




29


30
31
32


33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
/*
 * tkMacOSXButton.c --
 *
 *	This file implements the Macintosh specific portion of the button
 *	widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2007 Revar Desmera.
 * Copyright 2015 Kevin Walzer/WordTech Communications LLC.
 * Copyright 2015 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"
#include "tkButton.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXDebug.h"


#define FIRST_DRAW	    2
#define ACTIVE		    4


/*


 * Extra padding used for computing the content size that should




 * be allowed when drawing the HITheme button.


 */

#define HI_PADX 14


#define HI_PADY 1

/*
 * The delay in milliseconds between pulsing default button redraws.
 */
#define PULSE_TIMER_MSECS 62   /* Largest value that didn't look stuttery */

/*
 * Declaration of Mac specific button structure.
 */


typedef struct {

    Tk_3DBorder border;
    int relief;
    int offset;			/* 0 means this is a normal widget. 1 means
				 * it is an image button, so we offset the
				 * image to make the button appear to move
				 * up and down as the relief changes. */
    GC gc;



|
|

















>




>

>
>
|
>
>
>
>
|
>
>


|
>
>
|












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * tkMacOSXButton.c --
 *
 *	This file implements the Macintosh specific portion of the
 *	button widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2007 Revar Desmera.
 * Copyright 2015 Kevin Walzer/WordTech Communications LLC.
 * Copyright 2015 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"
#include "tkButton.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXDebug.h"


#define FIRST_DRAW	    2
#define ACTIVE		    4


/*
 * Default insets for controls
 */

#define DEF_INSET_LEFT 12
#define DEF_INSET_RIGHT 12
#define DEF_INSET_TOP 1
#define DEF_INSET_BOTTOM 1

/*
 * Some defines used to control what type of control is drawn.
 */

#define DRAW_LABEL	0	/* Labels are treated genericly. */
#define DRAW_CONTROL	1	/* Draw using the Native control. */
#define DRAW_CUSTOM	2	/* Make our own button drawing. */
#define DRAW_BEVEL	3

/*
 * The delay in milliseconds between pulsing default button redraws.
 */
#define PULSE_TIMER_MSECS 62   /* Largest value that didn't look stuttery */

/*
 * Declaration of Mac specific button structure.
 */


typedef struct {
    int drawType;
    Tk_3DBorder border;
    int relief;
    int offset;			/* 0 means this is a normal widget. 1 means
				 * it is an image button, so we offset the
				 * image to make the button appear to move
				 * up and down as the relief changes. */
    GC gc;
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
    Tcl_TimerToken defaultPulseHandler;
} MacButton;

/*
 * Forward declarations for procedures defined later in this file:
 */


static void	ButtonBackgroundDrawCB(const HIRect *btnbounds,
		    MacButton *ptr, SInt16 depth, Boolean isColorDev);
static void	ButtonContentDrawCB(const HIRect *bounds,
		    ThemeButtonKind kind,
		    const HIThemeButtonDrawInfo *info, MacButton *ptr,
		    SInt16 depth, Boolean isColorDev);
static void	ButtonEventProc(ClientData clientData,
		    XEvent *eventPtr);
static void	TkMacOSXComputeButtonParams(TkButton *butPtr,
		    ThemeButtonKind *btnkind,
		    HIThemeButtonDrawInfo *drawinfo);
static int	TkMacOSXComputeButtonDrawParams(TkButton *butPtr,
		    DrawParams * dpPtr);
static void	TkMacOSXDrawButton(MacButton *butPtr, GC gc,
		    Pixmap pixmap);
static void	DrawButtonImageAndText(TkButton *butPtr);
static void	PulseDefaultButtonProc(ClientData clientData);


/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    NULL,
	NULL
};

static int bCount;

/*
 *----------------------------------------------------------------------
 *
 * TkpButtonSetDefaults --
 *
 *	This procedure is invoked before option tables are created for buttons.
 *	It modifies some of the default values to match the current values
 *	defined for this platform.
 *
 * Results:
 *	Some of the default values in *specPtr are modified.
 *
 * Side effects:
 *	Updates some of.
 *
 *----------------------------------------------------------------------
 */

void
TkpButtonSetDefaults()
{
    /*No-op.*/
}


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *
 *	Allocate a new TkButton structure.







>
|
|
<
|
|
|
|
<
|
<
|
|
<
|
<
|
|
>





|


<
<



|





|
|
|













|

>







79
80
81
82
83
84
85
86
87
88

89
90
91
92

93

94
95

96

97
98
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    Tcl_TimerToken defaultPulseHandler;
} MacButton;

/*
 * Forward declarations for procedures defined later in this file:
 */


static void ButtonBackgroundDrawCB (const HIRect *btnbounds, MacButton *ptr,
        SInt16 depth, Boolean isColorDev);

static void ButtonContentDrawCB (const HIRect *bounds, ThemeButtonKind kind,
        const HIThemeButtonDrawInfo *info, MacButton *ptr, SInt16 depth,
	Boolean isColorDev);
static void ButtonEventProc(ClientData clientData, XEvent *eventPtr);

static void TkMacOSXComputeButtonParams (TkButton * butPtr, ThemeButtonKind* btnkind,

	HIThemeButtonDrawInfo* drawinfo);
static int TkMacOSXComputeButtonDrawParams (TkButton * butPtr, DrawParams * dpPtr);

static void TkMacOSXDrawButton (MacButton *butPtr, GC gc, Pixmap pixmap);

static void DrawButtonImageAndText(TkButton* butPtr);
static void PulseDefaultButtonProc(ClientData clientData);


/*
 * The class procedure table for the button widgets.
 */

Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */


};

static int bCount;

/*
 *----------------------------------------------------------------------
 *
 * TkpButtonSetDefaults --
 *
 *	This procedure is invoked before option tables are created for
 *	buttons. It modifies some of the default values to match the current
 *	values defined for this platform.
 *
 * Results:
 *	Some of the default values in *specPtr are modified.
 *
 * Side effects:
 *	Updates some of.
 *
 *----------------------------------------------------------------------
 */

void
TkpButtonSetDefaults()
{
/*No-op.*/
}


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *
 *	Allocate a new TkButton structure.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382




383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410

411
412
413


414
415
416











417



418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447


448

449

450

451

452

453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478





479
480
481
482
483
484
485
486
487
488
489
490

491
492
493

494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532
533
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    MacButton *macButtonPtr = (MacButton *)ckalloc(sizeof(MacButton));

    Tk_CreateEventHandler(tkwin, ActivateMask,
	    ButtonEventProc, macButtonPtr);
    macButtonPtr->id = bCount++;
    macButtonPtr->flags = FIRST_DRAW;
    macButtonPtr->btnkind = kThemePushButton;
    macButtonPtr->defaultPulseHandler = NULL;
    bzero(&macButtonPtr->drawinfo, sizeof(macButtonPtr->drawinfo));
    bzero(&macButtonPtr->lastdrawinfo, sizeof(macButtonPtr->lastdrawinfo));

    return (TkButton *) macButtonPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This procedure is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the button in its current mode. The
 *	REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    MacButton *macButtonPtr = clientData;
    TkButton *butPtr = clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams* dpPtr = &macButtonPtr->drawParams;
    int needhighlight = 0;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);


    if (TkMacOSXComputeButtonDrawParams(butPtr, dpPtr)) {
	macButtonPtr->useTkText = 0;
    } else {
	macButtonPtr->useTkText = 1;
    }







    if (macButtonPtr->useTkText) {
	if (butPtr->type == TYPE_BUTTON) {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	} else {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	}

        /*
	 * Display image or bitmap or text for labels or custom controls.
	 */

	DrawButtonImageAndText(butPtr);
        needhighlight = 1;
    } else {
        /*
	 * Draw the native portion of the buttons.
	 */

        TkMacOSXDrawButton(macButtonPtr, dpPtr->gc, pixmap);

        /*
	 * Ask for the highlight border, if needed.
	 */

        if (butPtr->highlightWidth < 3) {
            needhighlight = 1;
        }
    }

    /*
     * Draw highlight border, if needed.
     */

    if (needhighlight) {
	GC gc = NULL;
        if ((butPtr->flags & GOT_FOCUS) && butPtr->highlightColorPtr) {
	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
	} else if (butPtr->type == TYPE_LABEL) {
	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder), pixmap);
	}
	if (gc) {

	    TkMacOSXDrawSolidBorder(tkwin, gc, 0, butPtr->highlightWidth);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeButtonGeometry --
 *
 *	After changes in a button's text or bitmap, this procedure recomputes
 *	the button's geometry and passes this information along to the geometry
 *	manager for the window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    TkButton *butPtr)		/* Button whose geometry may have changed. */
{
    int width = 0, height = 0, charWidth = 1, haveImage = 0, haveText = 0;
    int txtWidth = 0, txtHeight = 0;
    MacButton *mbPtr = (MacButton *) butPtr;
    Tk_FontMetrics fm;

    char *text = Tcl_GetString(butPtr->textPtr);




    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    /*
     * If the indicator is on, get its size.
     */

    if (butPtr->indicatorOn) {
	switch (butPtr->type) {
	case TYPE_RADIO_BUTTON:
	    GetThemeMetric(kThemeMetricRadioButtonWidth,
		    (SInt32 *) &butPtr->indicatorDiameter);
	    break;
	case TYPE_CHECK_BUTTON:
	    GetThemeMetric(kThemeMetricCheckBoxWidth,
		    (SInt32 *) &butPtr->indicatorDiameter);
	    break;
	default:
	    break;
	}

	/*
	 * Allow 2px extra space next to the indicator.
	 */

	butPtr->indicatorSpace = butPtr->indicatorDiameter + 2;
    } else {
	butPtr->indicatorSpace = 0;
	butPtr->indicatorDiameter = 0;
    }

    if (butPtr->image != NULL) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
    } else if (butPtr->bitmap != None) {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		text, -1, butPtr->wrapLength, butPtr->justify, 0,
		&butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth + 2*butPtr->padX;
	txtHeight = butPtr->textHeight + 2*butPtr->padY;


	haveText = 1;
    }

    if (haveImage) {
	if (haveText) { /* Image and Text */
	    switch ((enum compound) butPtr->compound) {
	    case COMPOUND_TOP:
	    case COMPOUND_BOTTOM:
		/*
		* Image is above or below text.
		*/

		height += txtHeight + butPtr->padY;
		width = (width > txtWidth ? width : txtWidth);
		break;
	    case COMPOUND_LEFT:
	    case COMPOUND_RIGHT:
		/*
		* Image is left or right of text.
		*/

		width += txtWidth + 2*butPtr->padX;
		height = (height > txtHeight ? height : txtHeight);
		break;
	    case COMPOUND_CENTER:
		/*
		* Image and text are superimposed.
		*/

		width = (width > txtWidth ? width : txtWidth);
		height = (height > txtHeight ? height : txtHeight);
		break;
	    default:
		break;
	    }

	}
	/* Image with or without text */
	width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
	height = butPtr->height > 0 ? butPtr->height : height;
	if (butPtr->type == TYPE_BUTTON) {
	    /*
	     * Allow room to shift the image.
	     */
	    width += 2;
	    height += 2;
	}
    } else { /* Text only */
        width = txtWidth + butPtr->indicatorSpace;
	height = txtHeight;
	if (butPtr->width > 0) {
	    charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	    width = butPtr->width * charWidth + 2*butPtr->padX;
	}
	if (butPtr->height > 0) {
	    Tk_GetFontMetrics(butPtr->tkfont, &fm);
	    height = butPtr->height * fm.linespace + 2*butPtr->padY;
	}
    }





    /*
     * Now figure out the size of the border decorations for the button.
     */

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }

    butPtr->inset = butPtr->borderWidth + butPtr->highlightWidth;

    width += butPtr->inset*2;
    height += butPtr->inset*2;
    if ([NSApp macOSVersion] == 100600) {
	width += 12;
    }
    if (mbPtr->btnkind == kThemePushButton) {
        HIRect tmpRect;
    	HIRect contBounds;

	/*
	 * A PushButton has a minimum size.  We make sure that we are not
	 * underestimating the size by requesting the content size of a
	 * Pushbutton whose overall size is our content size expanded by the
	 * standard padding.
	 */

	tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY);

        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);

        if (height < contBounds.size.height) {
	    height = contBounds.size.height;
        }


        if (width < contBounds.size.width) {
	    width = contBounds.size.width;
        }











	height += 2*HI_PADY;



	width += 2*HI_PADX;

    }
    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawButtonImageAndText --
 *
 *	Draws the image and text associated with a button or label.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The image and text are drawn.
 *
 *----------------------------------------------------------------------
 */
static void
DrawButtonImageAndText(
    TkButton *butPtr)
{

    MacButton *mbPtr = (MacButton *) butPtr;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    int haveImage = 0, haveText = 0, pressed = 0;


    int imageWidth = 0, imageHeight = 0;

    int imageXOffset = 0, imageYOffset = 0;

    int textXOffset = 0, textYOffset = 0;

    int width = 0, height = 0;

    int fullWidth = 0, fullHeight = 0;

    DrawParams *dpPtr = &mbPtr->drawParams;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }


    pixmap = (Pixmap) Tk_WindowId(tkwin);

    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    imageWidth = width;
    imageHeight = height;

    if (mbPtr->drawinfo.state == kThemeStatePressed) {

        pressed = 1;
    }

    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { /* Image and Text */
        int x, y;






        switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /* Image is above or below text */
	    if (butPtr->compound == COMPOUND_TOP) {
		textYOffset = height + butPtr->padY;
	    } else {
		imageYOffset = butPtr->textHeight + butPtr->padY;
	    }
	    fullHeight = height + butPtr->textHeight + butPtr->padY;
	    fullWidth = (width > butPtr->textWidth ? width : butPtr->textWidth);

	    textXOffset = (fullWidth - butPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    break;

	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text
	     */

	    if (butPtr->compound == COMPOUND_LEFT) {
		textXOffset = width + butPtr->padX;
	    } else {
		imageXOffset = butPtr->textWidth + butPtr->padX;
	    }
	    fullWidth = butPtr->textWidth + butPtr->padX + width;
	    fullHeight = (height > butPtr->textHeight ? height :
		    butPtr->textHeight);
	    textYOffset = (fullHeight - butPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;

	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed
	     */

	    fullWidth = (width > butPtr->textWidth ? width :
		    butPtr->textWidth);
	    fullHeight = (height > butPtr->textHeight ? height :
		    butPtr->textHeight);
	    textXOffset = (fullWidth - butPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    textYOffset = (fullHeight - butPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;

	default:
	    break;
	}

        TkComputeAnchor(butPtr->anchor, tkwin,
                butPtr->padX + butPtr->borderWidth,
                butPtr->padY + butPtr->borderWidth,
                fullWidth + butPtr->indicatorSpace, fullHeight, &x, &y);
	x += butPtr->indicatorSpace;







|


|







|







|
|





|
|








|
|










>

|




>
>
>
>
>
>
>









<
|
<
<

|

<
|
<
<


<
|
<
<





<
|
<
<

<
|
<
|
<
<
<
>
|
|








|
|
|
















|

>
|
>
>
>







|
|
|
|
<
|
|
|
<
|
|
|
|
<
<
|
<
<
|

|
|













|
|

|
|
>
>
|


<
|
|



|
|







|
|

|




|
|






|
>
|
|
|
|
<
<
<
<
<
<
|




<
|


<
|



>
>
>
>








|
<
|
<
<
<
|
|


|
<
<
<
<
|
<

|
>

>

|

>
>

|

>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
|



|





|


|


|





|


|
|
|
|
>
>
|
>
|
>
|
>
|
>
|
>
|





>
|

|







|



>




|
|
>
>
>
>
>



|
|
|
|
|
|
|
|
|
>
|
|
|
>

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>

|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228


229
230
231

232


233
234

235


236
237
238
239
240

241


242

243

244



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295

296
297
298
299


300


301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363






364
365
366
367
368

369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389



390
391
392
393
394




395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    MacButton *macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));

    Tk_CreateEventHandler(tkwin, ActivateMask,
	    ButtonEventProc, (ClientData) macButtonPtr);
    macButtonPtr->id = bCount++;
    macButtonPtr->flags = FIRST_DRAW;
    macButtonPtr->btnkind = kThemePushButton;
    macButtonPtr->defaultPulseHandler = NULL;
    bzero(&macButtonPtr->drawinfo, sizeof(macButtonPtr->drawinfo));
    bzero(&macButtonPtr->lastdrawinfo, sizeof(macButtonPtr->lastdrawinfo));

    return (TkButton *)macButtonPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This procedure is invoked to display a button widget. It is
 *	normally invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the button in its
 *	current mode. The REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    MacButton *macButtonPtr = (MacButton *) clientData;
    TkButton *butPtr = (TkButton *) clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams* dpPtr = &macButtonPtr->drawParams;
    int needhighlight = 0;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));

    if (TkMacOSXComputeButtonDrawParams(butPtr, dpPtr) ) {
	macButtonPtr->useTkText = 0;
    } else {
	macButtonPtr->useTkText = 1;
    }


    /*
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    if (macButtonPtr->useTkText) {
	if (butPtr->type == TYPE_BUTTON) {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	} else {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	}


        /* Display image or bitmap or text for labels or custom controls.  */


	DrawButtonImageAndText(butPtr);
        needhighlight  = 1;
    } else {

        /* Draw the native portion of the buttons. */


        TkMacOSXDrawButton(macButtonPtr, dpPtr->gc, pixmap);


        /* Draw highlight border, if needed. */


        if (butPtr->highlightWidth < 3) {
            needhighlight = 1;
        }
    }


    /* Draw highlight border, if needed. */


    if (needhighlight) {

        if ((butPtr->flags & GOT_FOCUS)) {

            Tk_Draw3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,



                Tk_Width(tkwin), Tk_Height(tkwin),
                butPtr->highlightWidth, TK_RELIEF_SOLID);
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeButtonGeometry --
 *
 *	After changes in a button's text or bitmap, this procedure
 *	recomputes the button's geometry and passes this information
 *	along to the geometry manager for the window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    TkButton *butPtr)		/* Button whose geometry may have changed. */
{
    int width = 0, height = 0, charWidth = 1, haveImage = 0, haveText = 0;
    int txtWidth = 0, txtHeight = 0;
    MacButton *mbPtr = (MacButton*)butPtr;
    Tk_FontMetrics fm;
    DrawParams drawParams;

    /*
     * First figure out the size of the contents of the button.
     */

    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    /*
     * If the indicator is on, get its size.
     */

    if ( butPtr->indicatorOn ) {
      switch (butPtr->type) {
      case TYPE_RADIO_BUTTON:
	GetThemeMetric(kThemeMetricRadioButtonWidth, (SInt32 *)&butPtr->indicatorDiameter);

	  break;
      case TYPE_CHECK_BUTTON:
	GetThemeMetric(kThemeMetricCheckBoxWidth, (SInt32 *)&butPtr->indicatorDiameter);

	  break;
      default:
	break;
      }


      /* Allow 2px extra space next to the indicator. */


      butPtr->indicatorSpace = butPtr->indicatorDiameter + 2;
    } else {
      butPtr->indicatorSpace = 0;
      butPtr->indicatorDiameter = 0;
    }

    if (butPtr->image != NULL) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
    } else if (butPtr->bitmap != None) {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth + DEF_INSET_LEFT + DEF_INSET_RIGHT;
	txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP;
	charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }


    if (haveImage && haveText) { /* Image and Text */
	switch ((enum compound) butPtr->compound) {
	    case COMPOUND_TOP:
	    case COMPOUND_BOTTOM:
		/*
		 * Image is above or below text.
		 */

		height += txtHeight + butPtr->padY;
		width = (width > txtWidth ? width : txtWidth);
		break;
	    case COMPOUND_LEFT:
	    case COMPOUND_RIGHT:
		/*
		 * Image is left or right of text.
		 */

		width += txtWidth + butPtr->padX;
		height = (height > txtHeight ? height : txtHeight);
		break;
	    case COMPOUND_CENTER:
		/*
		 * Image and text are superimposed.
		 */

		width = (width > txtWidth ? width : txtWidth);
		height = (height > txtHeight ? height : txtHeight);
		break;
	    default:
		break;
	}
	width += butPtr->indicatorSpace;

    } else if (haveImage) { /* Image only */
      width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
      height = butPtr->height > 0 ? butPtr->height : height;







    } else { /* Text only */
        width = txtWidth + butPtr->indicatorSpace;
	height = txtHeight;
	if (butPtr->width > 0) {

	   width = butPtr->width * charWidth;
	}
	if (butPtr->height > 0) {

	  height = butPtr->height * fm.linespace;
	}
    }

    /* Add padding */
    width  += 2 * butPtr->padX;
    height += 2 * butPtr->padY;

    /*
     * Now figure out the size of the border decorations for the button.
     */

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }

    butPtr->inset = 0;

    butPtr->inset += butPtr->highlightWidth;



    
    if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
        HIRect tmpRect;
    	HIRect contBounds;
        int paddingx = 0;




        int paddingy = 0;


    	tmpRect = CGRectMake(0, 0, width, height);

        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        /* If the content region has a minimum height, match it. */
        if (height < contBounds.size.height) {
    	  height = contBounds.size.height;
        }

        /* If the content region has a minimum width, match it. */
        if (width < contBounds.size.width) {
    	  width = contBounds.size.width;
        }

        /* Pad to fill difference between content bounds and button bounds. */
    	paddingx = contBounds.origin.x;
    	paddingy = contBounds.origin.y;

        if (height < paddingx - 4) {
            /* can't have buttons much shorter than button side diameter. */
            height = paddingx - 4;
    	}

    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;

    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawButtonImageAndText --
 *
 *        Draws the image and text associated with a button or label.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The image and text are drawn.
 *
 *----------------------------------------------------------------------
 */
static void
DrawButtonImageAndText(
    TkButton* butPtr)
{

    MacButton *mbPtr = (MacButton*)butPtr;
    Tk_Window  tkwin  = butPtr->tkwin;
    Pixmap     pixmap;
    int        haveImage = 0;
    int        haveText = 0;
    int        imageWidth = 0;
    int        imageHeight = 0;
    int        imageXOffset = 0;
    int        imageYOffset = 0;
    int        textXOffset = 0;
    int        textYOffset = 0;
    int        width = 0;
    int        height = 0;
    int        fullWidth = 0;
    int        fullHeight = 0;
    int        pressed = 0;


    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawParams* dpPtr = &mbPtr->drawParams;
    pixmap = (Pixmap)Tk_WindowId(tkwin);

    if (butPtr->image != None) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    imageWidth  = width;
    imageHeight = height;

    if (mbPtr->drawinfo.state == kThemeStatePressed) {
        /* Offset bitmaps by a bit when the button is pressed. */
        pressed = 1;
    }

    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
    if (haveImage && haveText) { /* Image and Text */
        int x;
        int y;
        textXOffset = 0;
        textYOffset = 0;
        fullWidth = 0;
        fullHeight = 0;

        switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM: {
	  /* Image is above or below text */
	  if (butPtr->compound == COMPOUND_TOP) {
	    textYOffset = height + butPtr->padY;
	  } else {
	    imageYOffset = butPtr->textHeight + butPtr->padY;
	  }
	  fullHeight = height + butPtr->textHeight + butPtr->padY;
	  fullWidth = (width > butPtr->textWidth ? width :
		       butPtr->textWidth);
	  textXOffset = (fullWidth - butPtr->textWidth)/2;
	  imageXOffset = (fullWidth - width)/2;
	  break;
	}
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT: {
	  /*
	   * Image is left or right of text
	   */
	  
	  if (butPtr->compound == COMPOUND_LEFT) {
	    textXOffset = width + butPtr->padX;
	  } else {
	    imageXOffset = butPtr->textWidth + butPtr->padX;
	  }
	  fullWidth = butPtr->textWidth + butPtr->padX + width;
	  fullHeight = (height > butPtr->textHeight ? height :
                        butPtr->textHeight);
	  textYOffset = (fullHeight - butPtr->textHeight)/2;
	  imageYOffset = (fullHeight - height)/2;
	  break;
	}
	case COMPOUND_CENTER: {
	  /*
	   * Image and text are superimposed
	   */
	  
	  fullWidth = (width > butPtr->textWidth ? width :
		       butPtr->textWidth);
	  fullHeight = (height > butPtr->textHeight ? height :
                        butPtr->textHeight);
	  textXOffset = (fullWidth - butPtr->textWidth)/2;
	  imageXOffset = (fullWidth - width)/2;
	  textYOffset = (fullHeight - butPtr->textHeight)/2;
	  imageYOffset = (fullHeight - height)/2;
	  break;
	}
	default:
	  break;
	}

        TkComputeAnchor(butPtr->anchor, tkwin,
                butPtr->padX + butPtr->borderWidth,
                butPtr->padY + butPtr->borderWidth,
                fullWidth + butPtr->indicatorSpace, fullHeight, &x, &y);
	x += butPtr->indicatorSpace;
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579
580
581
582
583

584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

608

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
        }
        if (pressed) {
            x += dpPtr->offset;
            y += dpPtr->offset;
        }
        imageXOffset += x;
        imageYOffset += y;


        if (butPtr->image != NULL) {
	    if ((butPtr->selectImage != NULL) &&
		    (butPtr->flags & SELECTED)) {
		Tk_RedrawImage(butPtr->selectImage, 0, 0,
			width, height, pixmap, imageXOffset, imageYOffset);
	    } else if ((butPtr->tristateImage != NULL) &&
		    (butPtr->flags & TRISTATED)) {
		Tk_RedrawImage(butPtr->tristateImage, 0, 0,
			width, height, pixmap, imageXOffset, imageYOffset);
	    } else {
		Tk_RedrawImage(butPtr->image, 0, 0, width,
			height, pixmap, imageXOffset, imageYOffset);
	    }
        } else {
	    XSetClipOrigin(butPtr->display, dpPtr->gc,
		    imageXOffset, imageYOffset);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, (unsigned int) width, (unsigned int) height,
		    imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
        }
	y += 1; /* Tweak to match native buttons. */
        Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,

			  x + textXOffset, y + textYOffset, 0, -1);
        Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                butPtr->textLayout,
                x + textXOffset, y + textYOffset,
                butPtr->underline);
    } else if (haveImage) { /* Image only */
        int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin,
		butPtr->padX + butPtr->borderWidth,
		butPtr->padY + butPtr->borderWidth,
		width + butPtr->indicatorSpace, height, &x, &y);

        x += butPtr->indicatorSpace;
	if (pressed) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;

	if (butPtr->image != NULL) {

	    if ((butPtr->selectImage != NULL) &&
		    (butPtr->flags & SELECTED)) {
		Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
			height, pixmap, imageXOffset, imageYOffset);
	    } else if ((butPtr->tristateImage != NULL) &&
		    (butPtr->flags & TRISTATED)) {
		Tk_RedrawImage(butPtr->tristateImage, 0, 0, width,
			height, pixmap, imageXOffset, imageYOffset);
	    } else {
		Tk_RedrawImage(butPtr->image, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
	    }
	} else {
	    XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,

		    0, 0, (unsigned int) width, (unsigned int) height,

		    imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
    } else { /* Text only */
        int x, y;

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->textWidth + butPtr->indicatorSpace,
		butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	y += 1; /* Tweak to match native buttons */
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
			  x, y, 0, -1);
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect.  If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.
     */

    if (mbPtr->useTkText) {
        if ((butPtr->state == STATE_DISABLED)
                && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
                    && (butPtr->selectBorder != NULL)) {







>


|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|

|
|
>
|





|
|

|
|
|
>


|
|





>
|
|
|
|
|
|
|
|
|
|
|
|

|
|
>
|
>
|
|



<

|
|

<

|




|
|
|







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
        }
        if (pressed) {
            x += dpPtr->offset;
            y += dpPtr->offset;
        }
        imageXOffset += x;
        imageYOffset += y;
        textYOffset -= 1;

        if (butPtr->image != NULL) {
	  if ((butPtr->selectImage != NULL) &&
	      (butPtr->flags & SELECTED)) {
	    Tk_RedrawImage(butPtr->selectImage, 0, 0,
			   width, height, pixmap, imageXOffset, imageYOffset);
	  } else if ((butPtr->tristateImage != NULL) &&
		     (butPtr->flags & TRISTATED)) {
	    Tk_RedrawImage(butPtr->tristateImage, 0, 0,
			   width, height, pixmap, imageXOffset, imageYOffset);
	  } else {
	    Tk_RedrawImage(butPtr->image, 0, 0, width,
			   height, pixmap, imageXOffset, imageYOffset);
	  }
        } else {
	  XSetClipOrigin(butPtr->display, dpPtr->gc,
			 imageXOffset, imageYOffset);
	  XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		     0, 0, (unsigned int) width, (unsigned int) height,
		     imageXOffset, imageYOffset, 1);
	  XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
        }
	
        Tk_DrawTextLayout(butPtr->display, pixmap,
                dpPtr->gc, butPtr->textLayout,
                x + textXOffset, y + textYOffset, 0, -1);
        Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                butPtr->textLayout,
                x + textXOffset, y + textYOffset,
                butPtr->underline);
    } else if (haveImage) { /* Image only */
        int x = 0;
	int y;
	TkComputeAnchor(butPtr->anchor, tkwin,
			butPtr->padX + butPtr->borderWidth,
			butPtr->padY + butPtr->borderWidth,
			width + butPtr->indicatorSpace,
			height, &x, &y);
        x += butPtr->indicatorSpace;
	if (pressed) {
	  x += dpPtr->offset;
	  y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;

	if (butPtr->image != NULL) {
	  
	  if ((butPtr->selectImage != NULL) &&
	      (butPtr->flags & SELECTED)) {
	    Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
			   height, pixmap, imageXOffset, imageYOffset);
	  } else if ((butPtr->tristateImage != NULL) &&
		     (butPtr->flags & TRISTATED)) {
	    Tk_RedrawImage(butPtr->tristateImage, 0, 0, width,
			   height, pixmap, imageXOffset, imageYOffset);
	  } else {
	    Tk_RedrawImage(butPtr->image, 0, 0, width, height,
			   pixmap, imageXOffset, imageYOffset);
	  }
	} else {
	  XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
	  XCopyPlane(butPtr->display, butPtr->bitmap,
		     pixmap, dpPtr->gc,
		     0, 0, (unsigned int) width,
		     (unsigned int) height,
		     imageXOffset, imageYOffset, 1);
	  XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
    } else { /* Text only */
        int x, y;

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
			butPtr->textWidth + butPtr->indicatorSpace,
			  butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;

	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
			  x, y - DEF_INSET_BOTTOM, 0, -1);
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect.  If the widget
     * is selected and we use a different background color when selected,
     * must temporarily modify the GC so the stippling is the right color.
     */

    if (mbPtr->useTkText) {
        if ((butPtr->state == STATE_DISABLED)
                && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
                    && (butPtr->selectBorder != NULL)) {
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674




675
676
677
678
679
680
681

        /*
         * Draw the border and traversal highlight last.  This way, if the
         * button's contents overflow they'll be covered up by the border.
         */

        if (dpPtr->relief != TK_RELIEF_FLAT) {
	    int inset = butPtr->highlightWidth;

	    Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
		    Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		    butPtr->borderWidth, dpPtr->relief);
        }
    }
}





/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyButton --
 *
 *	Free data structures associated with the button control.
 *







|
<
|
|
|


|
|
>
>
>
>







688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

        /*
         * Draw the border and traversal highlight last.  This way, if the
         * button's contents overflow they'll be covered up by the border.
         */

        if (dpPtr->relief != TK_RELIEF_FLAT) {
            int inset = butPtr->highlightWidth;

            Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
                Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
                butPtr->borderWidth, dpPtr->relief);
        }
    }

   }




/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyButton --
 *
 *	Free data structures associated with the button control.
 *
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732


733
734
735
736

737

738
739
740
741
742
743
744
745
746
747
748
749
750













751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
 */

void
TkpDestroyButton(
    TkButton *butPtr)
{
    MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */

    if (mbPtr->defaultPulseHandler) {
        Tcl_DeleteTimerHandler(mbPtr->defaultPulseHandler);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawButton --
 *
 *        This function draws the tk button using Mac controls. In addition,
 *        this code may apply custom colors passed in the TkButton.

 *
 * Results:
 *        None.
 *
 * Side effects:
 *      The control is created, or reinitialised as needed
 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawButton(
    MacButton *mbPtr,    /* Mac button. */
    TCL_UNUSED(GC),      /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
{
    TkButton *butPtr = (TkButton *) mbPtr;
    TkWindow *winPtr = (TkWindow *) butPtr->tkwin;
    HIRect cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams *dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;



    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff,

	    Tk_Width(butPtr->tkwin), Tk_Height(butPtr->tkwin));


    cntrRect = CGRectInset(cntrRect, butPtr->inset, butPtr->inset);

    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}














        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
            hiinfo.animation.time.start = hiinfo.animation.time.current;
        }

	/*
	 * To avoid buttons with white text on a white background, we set the
	 * state to inactive in Dark Mode unless the button is pressed or is a
	 * -default active button.  This isn't perfect but it is mostly usable.
	 * Using a ttk::button would be a much better choice, however.
	 */

	if (TkMacOSXInDarkMode(butPtr->tkwin) &&
	    mbPtr->drawinfo.state != kThemeStatePressed &&
	    !(mbPtr->drawinfo.adornment & kThemeAdornmentDefault)) {
	    hiinfo.state = kThemeStateInactive;
	}
	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);

	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
		(MacButton *) mbPtr, 32, true);

    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}

	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonBackgroundDrawCB --
 *
 *        This function draws the background that lies under checkboxes and
 *        radiobuttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The background gets updated to the current color.
 *
 *--------------------------------------------------------------
 */

static void
ButtonBackgroundDrawCB(
    TCL_UNUSED(const HIRect *),
    MacButton *ptr,
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    MacButton *mbPtr = (MacButton *) ptr;
    TkButton *butPtr = (TkButton *) mbPtr;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    int usehlborder = 0;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    if (butPtr->type != TYPE_LABEL) {
        switch (mbPtr->btnkind) {
	case kThemeSmallBevelButton:
	case kThemeBevelButton:
	case kThemeRoundedBevelButton:
	case kThemePushButton:
	    usehlborder = 1;
	    break;
        }
    }
    if (usehlborder) {
        Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
            Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
    } else {
        Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,







<










|
|
>













|




|
|
|

|

>
>



|
>
|
>

|







|



>
>
>
>
>
>
>
>
>
>
>
>
>


|







<
<
<
<
<
<
<
<
<
<
<
<
|
|



|
>

|













|
|









<

|
|

|
|

|
|
|






|



|
|
|
|
|
|







721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809












810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
 */

void
TkpDestroyButton(
    TkButton *butPtr)
{
    MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */

    if (mbPtr->defaultPulseHandler) {
        Tcl_DeleteTimerHandler(mbPtr->defaultPulseHandler);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawButton --
 *
 *        This function draws the tk button using Mac controls
 *        In addition, this code may apply custom colors passed
 *        in the TkButton.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *      The control is created, or reinitialised as needed
 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawButton(
    MacButton *mbPtr,    /* Mac button. */
    GC gc,               /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
{
    TkButton * butPtr = ( TkButton *)mbPtr;
    TkWindow * winPtr;
    HIRect      cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams* dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;

    winPtr = (TkWindow *)butPtr->tkwin;

    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff,
			  winPtr->privatePtr->yOff,
			  Tk_Width(butPtr->tkwin),
			  Tk_Height(butPtr->tkwin));

     cntrRect = CGRectInset(cntrRect,  butPtr->inset, butPtr->inset);

    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}


	if (mbPtr->btnkind == kThemePushButton) {
	    /*
	     * For some reason, pushbuttons get drawn a bit
	     * too low, normally.  Correct for this.
	     */
	    if (cntrRect.size.height < 22) {
		cntrRect.origin.y -= 1;
	    } else if (cntrRect.size.height < 23) {
		cntrRect.origin.y -= 2;
	    }
	}

        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind  = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
            hiinfo.animation.time.start = hiinfo.animation.time.current;
        }













	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal,
			  &contHIRec);

	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
			    (MacButton *)mbPtr, 32, true);

    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}

	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonBackgroundDrawCB --
 *
 *        This function draws the background that
 *        lies under checkboxes and radiobuttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The background gets updated to the current color.
 *
 *--------------------------------------------------------------
 */

static void
ButtonBackgroundDrawCB (
    const HIRect * btnbounds,
    MacButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
{
    MacButton* mbPtr = (MacButton*)ptr;
    TkButton* butPtr = (TkButton*)mbPtr;
    Tk_Window  tkwin  = butPtr->tkwin;
    Pixmap pixmap;
    int usehlborder = 0;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = (Pixmap)Tk_WindowId(tkwin);

    if (butPtr->type != TYPE_LABEL) {
        switch (mbPtr->btnkind) {
            case kThemeSmallBevelButton:
            case kThemeBevelButton:
            case kThemeRoundedBevelButton:
            case kThemePushButton:
                usehlborder = 1;
                break;
        }
    }
    if (usehlborder) {
        Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
            Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
    } else {
        Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
 * Side effects:
 *        The content of the button gets updated.
 *
 *--------------------------------------------------------------
 */
static void
ButtonContentDrawCB (
    TCL_UNUSED(const HIRect *),
    TCL_UNUSED(ThemeButtonKind),
    TCL_UNUSED(const HIThemeButtonDrawInfo *),
    MacButton *ptr,
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    TkButton *butPtr = (TkButton *) ptr;
    Tk_Window tkwin = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    /*
     * Overlay Tk elements over button native region: drawing elements within
     * button boundaries/native region causes unpredictable metrics.
     */

    DrawButtonImageAndText( butPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for various events on
 *	buttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = clientData;
    MacButton *mbPtr = clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayButton, buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeButtonParams --
 *
 *      This procedure computes the various parameters used when creating a
 *      Carbon Appearance control.  These are determined by the various tk
 *      button parameters
 *
 * Results:
 *	None.
 *
 * Side effects:
 *        Sets the btnkind and drawinfo parameters
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeButtonParams(
    TkButton *butPtr,
    ThemeButtonKind *btnkind,
    HIThemeButtonDrawInfo *drawinfo)
{
    MacButton *mbPtr = (MacButton *) butPtr;

    if (butPtr->borderWidth <= 2) {
        *btnkind = kThemeSmallBevelButton;
    } else if (butPtr->borderWidth == 3) {
        *btnkind = kThemeBevelButton;
    } else if (butPtr->borderWidth == 4) {
        *btnkind = kThemeRoundedBevelButton;
    } else {
        *btnkind = kThemePushButton;
    }

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
        switch (butPtr->type) {
	case TYPE_BUTTON:
	    *btnkind = kThemePushButton;
	    break;
	case TYPE_RADIO_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallRadioButton;
	    } else {
		*btnkind = kThemeRadioButton;
	    }
	    break;
	case TYPE_CHECK_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallCheckBox;
	    } else {
		*btnkind = kThemeCheckBox;
	    }
	    break;
	}
    }

    if (butPtr->indicatorOn) {
        switch (butPtr->type) {
	case TYPE_RADIO_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallRadioButton;
	    } else {
		*btnkind = kThemeRadioButton;
	    }
	    break;
	case TYPE_CHECK_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallCheckBox;
	    } else {
		*btnkind = kThemeCheckBox;
	    }
	    break;
        }
    } else {
        if (butPtr->type == TYPE_RADIO_BUTTON ||
		butPtr->type == TYPE_CHECK_BUTTON) {

	    if (*btnkind == kThemePushButton) {
		*btnkind = kThemeBevelButton;
	    }
        }
    }

    if (butPtr->flags & SELECTED) {







|
|
|

|
|

|
|





<
|
<
<
<








|
|















|
|












|










|
|
|












|
|
|

|













|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
>







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911



912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
 * Side effects:
 *        The content of the button gets updated.
 *
 *--------------------------------------------------------------
 */
static void
ButtonContentDrawCB (
    const HIRect * btnbounds,
    ThemeButtonKind kind,
    const HIThemeButtonDrawInfo *drawinfo,
    MacButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
{
    TkButton  *butPtr = (TkButton *)ptr;
    Tk_Window  tkwin  = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }


    /*Overlay Tk elements over button native region: drawing elements within button boundaries/native region causes unpredictable metrics.*/



    DrawButtonImageAndText( butPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for various
 *	events on buttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = (TkButton *) clientData;
    MacButton *mbPtr = (MacButton *) clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeButtonParams --
 *
 *      This procedure computes the various parameters used
 *        when creating a Carbon Appearance control.
 *	These are determined by the various tk button parameters
 *
 * Results:
 *	None.
 *
 * Side effects:
 *        Sets the btnkind and drawinfo parameters
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeButtonParams(
        TkButton * butPtr,
        ThemeButtonKind* btnkind,
	HIThemeButtonDrawInfo *drawinfo)
{
    MacButton *mbPtr = (MacButton *)butPtr;

    if (butPtr->borderWidth <= 2) {
        *btnkind = kThemeSmallBevelButton;
    } else if (butPtr->borderWidth == 3) {
        *btnkind = kThemeBevelButton;
    } else if (butPtr->borderWidth == 4) {
        *btnkind = kThemeRoundedBevelButton;
    } else {
        *btnkind = kThemePushButton;
    }

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
        switch (butPtr->type) {
            case TYPE_BUTTON:
                *btnkind = kThemePushButton;
                break;
            case TYPE_RADIO_BUTTON:
                if (butPtr->borderWidth <= 1) {
                    *btnkind = kThemeSmallRadioButton;
		} else {
                    *btnkind = kThemeRadioButton;
		}
		break;
	    case TYPE_CHECK_BUTTON:
                if (butPtr->borderWidth <= 1) {
                    *btnkind = kThemeSmallCheckBox;
	        } else {
                    *btnkind = kThemeCheckBox;
		}
		break;
	}
    }

    if (butPtr->indicatorOn) {
        switch (butPtr->type) {
            case TYPE_RADIO_BUTTON:
                if (butPtr->borderWidth <= 1) {
                    *btnkind = kThemeSmallRadioButton;
                } else {
                    *btnkind = kThemeRadioButton;
                }
                break;
            case TYPE_CHECK_BUTTON:
                if (butPtr->borderWidth <= 1) {
                    *btnkind = kThemeSmallCheckBox;
                } else {
                    *btnkind = kThemeCheckBox;
                }
                break;
        }
    } else {
        if (butPtr->type == TYPE_RADIO_BUTTON ||
	    butPtr->type == TYPE_CHECK_BUTTON
	) {
	    if (*btnkind == kThemePushButton) {
		*btnkind = kThemeBevelButton;
	    }
        }
    }

    if (butPtr->flags & SELECTED) {
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146





1147






1148
1149
1150
1151

1152




1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
        drawinfo->state = kThemeStatePressed;
    } else {
        drawinfo->state = kThemeStateActive;
    }

    drawinfo->adornment = kThemeAdornmentNone;
    if (butPtr->defaultState == DEFAULT_ACTIVE) {
	if (drawinfo->state != kThemeStatePressed) {
	    drawinfo->adornment |= kThemeAdornmentDefault;
	}

	/*
	 * Older macOS systems (10.9 and earlier) use an animation to
	 * indicate the active button.  This is simulated by redrawing
	 * the button periodically.
	 */

        if (!mbPtr->defaultPulseHandler && ([NSApp macOSVersion] <= 100900)) {
            mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
                    PULSE_TIMER_MSECS, PulseDefaultButtonProc, butPtr);

        }
    } else if (mbPtr->defaultPulseHandler) {
        Tcl_DeleteTimerHandler(mbPtr->defaultPulseHandler);
    }
    if (butPtr->highlightWidth >= 3) {
        if ((butPtr->flags & GOT_FOCUS)) {
            drawinfo->adornment |= kThemeAdornmentFocus;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeButtonDrawParams --
 *
 *	This procedure computes the various parameters used when drawing a

 *	button. These are determined by the various tk button parameters
 *
 * Results:
 *	1 if control will be used, 0 otherwise.
 *
 * Side effects:
 *	Sets the button draw parameters
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXComputeButtonDrawParams(
    TkButton *butPtr,
    DrawParams *dpPtr)
{
    MacButton *mbPtr = (MacButton *) butPtr;

    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
	    || (butPtr->bitmap != None));

    if (butPtr->type != TYPE_LABEL) {
        dpPtr->offset = 0;
        if (dpPtr->hasImageOrBitmap) {
            switch (mbPtr->btnkind) {
	    case kThemeSmallBevelButton:
	    case kThemeBevelButton:
	    case kThemeRoundedBevelButton:
	    case kThemePushButton:
		dpPtr->offset = 1;
		break;
            }
        }
    }


    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->type == TYPE_BUTTON && butPtr->state == STATE_ACTIVE) {
	dpPtr->gc = butPtr->activeTextGC;
	dpPtr->border = butPtr->activeBorder;
    } else if ((mbPtr->drawinfo.adornment & kThemeAdornmentDefault) &&
	       mbPtr->drawinfo.state == kThemeStateActive) {
	/*
	 * This is a "-default active" button in the front window.
	 */

	dpPtr->gc = butPtr->activeTextGC;
    } else {
	dpPtr->gc = butPtr->normalTextGC;
    }

    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	dpPtr->border = butPtr->selectBorder;
    }

    /*
     * Override the relief specified for the button if this is a checkbutton or
     * radiobutton and there's no indicator.
     */

    dpPtr->relief = butPtr->relief;

    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
		    : TK_RELIEF_RAISED;
	}
    }

    if (butPtr->type != TYPE_LABEL && (butPtr->type == TYPE_BUTTON ||
	    butPtr->indicatorOn || dpPtr->hasImageOrBitmap)) {
	/*
	 * Draw this widget as a native control.
	 */






	return 1;






    } else {
	/*
	 * Draw this widget from scratch.
	 */






	return 0;
    }
}

/*
 *--------------------------------------------------------------
 *
 * PulseDefaultButtonProc --
 *
 *     This function redraws the button on a timer, to pulse
 *     default buttons.
 *
 * Results:
 *     None.
 *
 * Side effects:
 *     Sets a timer to run itself again.
 *
 *--------------------------------------------------------------
 */

static void
PulseDefaultButtonProc(ClientData clientData)
{
    MacButton *mbPtr = clientData;

    TkpDisplayButton(clientData);
    /*
     * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
     * in case the button is destroyed and has its data freed before the idle
     * event is handled (DestroyButton only cancels calls when REDRAW_PENDING
     * is set, which is not the case after calling TkpDisplayButton directly).
     */
    Tcl_CancelIdleCall(TkpDisplayButton, clientData);
    mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
            PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







<
|
<
<
<
<
<
<
<
<
|

|
>
















|
>
|















|








|
|
|
|
|
|



>







<
<
<
<
<
<
<










|
|











<
<
|
|
|

>
>
>
>
>
|
>
>
>
>
>
>

<
<
<
>
|
>
>
>
>




















<



|
<

<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
1067
1068
1069
1070
1071
1072
1073

1074








1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138







1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161


1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178



1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204

1205
1206
1207
1208

1209







1210
1211
1212









        drawinfo->state = kThemeStatePressed;
    } else {
        drawinfo->state = kThemeStateActive;
    }

    drawinfo->adornment = kThemeAdornmentNone;
    if (butPtr->defaultState == DEFAULT_ACTIVE) {

        drawinfo->adornment |= kThemeAdornmentDefault;








        if (!mbPtr->defaultPulseHandler) {
            mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
                    PULSE_TIMER_MSECS, PulseDefaultButtonProc,
                    (ClientData) butPtr);
        }
    } else if (mbPtr->defaultPulseHandler) {
        Tcl_DeleteTimerHandler(mbPtr->defaultPulseHandler);
    }
    if (butPtr->highlightWidth >= 3) {
        if ((butPtr->flags & GOT_FOCUS)) {
            drawinfo->adornment |= kThemeAdornmentFocus;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeButtonDrawParams --
 *
 *	This procedure computes the various parameters used
 *	when drawing a button
 *	These are determined by the various tk button parameters
 *
 * Results:
 *	1 if control will be used, 0 otherwise.
 *
 * Side effects:
 *	Sets the button draw parameters
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXComputeButtonDrawParams(
    TkButton *butPtr,
    DrawParams *dpPtr)
{
    MacButton *mbPtr = (MacButton *)butPtr;

    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
	    || (butPtr->bitmap != None));

    if (butPtr->type != TYPE_LABEL) {
        dpPtr->offset = 0;
        if (dpPtr->hasImageOrBitmap) {
            switch (mbPtr->btnkind) {
                case kThemeSmallBevelButton:
                case kThemeBevelButton:
                case kThemeRoundedBevelButton:
                case kThemePushButton:
                    dpPtr->offset = 1;
                    break;
            }
        }
    }


    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->type == TYPE_BUTTON && butPtr->state == STATE_ACTIVE) {
	dpPtr->gc = butPtr->activeTextGC;
	dpPtr->border = butPtr->activeBorder;







    } else {
	dpPtr->gc = butPtr->normalTextGC;
    }

    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	dpPtr->border = butPtr->selectBorder;
    }

    /*
     * Override the relief specified for the button if this is a
     * checkbutton or radiobutton and there's no indicator.
     */

    dpPtr->relief = butPtr->relief;

    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
		    : TK_RELIEF_RAISED;
	}
    }



    /*
     * Determine the draw type
     */

    if (butPtr->type == TYPE_LABEL) {
	dpPtr->drawType = DRAW_LABEL;
    } else if (butPtr->type == TYPE_BUTTON) {
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->drawType = DRAW_CONTROL;
	} else {
            dpPtr->drawType = DRAW_BEVEL;
	}
    } else if (butPtr->indicatorOn) {
      dpPtr->drawType = DRAW_CONTROL;
    } else if (dpPtr->hasImageOrBitmap) {
	dpPtr->drawType = DRAW_BEVEL;
    } else {



	dpPtr->drawType = DRAW_CUSTOM;
    }

    if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) {
	return 1;
    } else {
	return 0;
    }
}

/*
 *--------------------------------------------------------------
 *
 * PulseDefaultButtonProc --
 *
 *     This function redraws the button on a timer, to pulse
 *     default buttons.
 *
 * Results:
 *     None.
 *
 * Side effects:
 *     Sets a timer to run itself again.
 *
 *--------------------------------------------------------------
 */

static void
PulseDefaultButtonProc(ClientData clientData)
{
    MacButton *mbPtr = (MacButton *)clientData;

    TkpDisplayButton(clientData);







    mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
            PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}









Changes to macosx/tkMacOSXClipboard.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74

75
76
77
78
79
80
81
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)

@implementation TKApplication(TKClipboard)
- (void) tkProvidePasteboard: (TkDisplay *) dispPtr
	pasteboard: (NSPasteboard *) sender
	provideDataForType: (NSString *) type
{
    NSMutableString *string = [NSMutableString new];

    if (dispPtr && dispPtr->clipboardActive &&
	    [type isEqualToString:NSStringPboardType]) {
	for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr;
		targetPtr = targetPtr->nextPtr) {
	    if (targetPtr->type == XA_STRING ||
		    targetPtr->type == dispPtr->utf8Atom) {
		for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
			cbPtr; cbPtr = cbPtr->nextPtr) {
		    NSString *s = [[TKNSString alloc]
				      initWithTclUtfBytes:cbPtr->buffer
						   length:cbPtr->length];

		    [string appendString:s];
		    [s release];
		}
		break;
	    }
	}
    }
    [sender setString:string forType:type];
    [string release];
}

- (void) tkProvidePasteboard: (TkDisplay *) dispPtr
{
    if (dispPtr && dispPtr->clipboardActive) {
	[self tkProvidePasteboard:dispPtr
		pasteboard:[NSPasteboard generalPasteboard]
		provideDataForType:NSStringPboardType];
    }
}

- (void) pasteboard: (NSPasteboard *) sender
	provideDataForType: (NSString *) type
{
    [self tkProvidePasteboard:TkGetDisplayList() pasteboard:sender
	    provideDataForType:type];
}

- (void) tkCheckPasteboard
{
    if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] !=
	    changeCount) {
	TkDisplay *dispPtr = TkGetDisplayList();

	if (dispPtr) {
	    XEvent event;

	    event.xany.type = SelectionClear;
	    event.xany.serial = NextRequest(Tk_Display(clipboardOwner));
	    event.xany.send_event = False;
	    event.xany.window = Tk_WindowId(clipboardOwner);
	    event.xany.display = Tk_Display(clipboardOwner);
	    event.xselectionclear.selection = dispPtr->clipboardAtom;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);







<








|
<
|
<










|
<
|
>










<
|
<






|
<
<
<



<
|
<



>


>







8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23

24

25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47

48

49
50
51
52
53
54
55



56
57
58

59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"

#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)

@implementation TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr

	pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type {

    NSMutableString *string = [NSMutableString new];

    if (dispPtr && dispPtr->clipboardActive &&
	    [type isEqualToString:NSStringPboardType]) {
	for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr;
		targetPtr = targetPtr->nextPtr) {
	    if (targetPtr->type == XA_STRING ||
		    targetPtr->type == dispPtr->utf8Atom) {
		for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
			cbPtr; cbPtr = cbPtr->nextPtr) {
		    NSString *s = [[NSString alloc] initWithBytesNoCopy:

			    cbPtr->buffer length:cbPtr->length
			    encoding:NSUTF8StringEncoding freeWhenDone:NO];
		    [string appendString:s];
		    [s release];
		}
		break;
	    }
	}
    }
    [sender setString:string forType:type];
    [string release];
}

- (void)tkProvidePasteboard:(TkDisplay *)dispPtr {

    if (dispPtr && dispPtr->clipboardActive) {
	[self tkProvidePasteboard:dispPtr
		pasteboard:[NSPasteboard generalPasteboard]
		provideDataForType:NSStringPboardType];
    }
}
- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type {



    [self tkProvidePasteboard:TkGetDisplayList() pasteboard:sender
	    provideDataForType:type];
}

- (void)tkCheckPasteboard {

    if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] !=
	    changeCount) {
	TkDisplay *dispPtr = TkGetDisplayList();

	if (dispPtr) {
	    XEvent event;

	    event.xany.type = SelectionClear;
	    event.xany.serial = NextRequest(Tk_Display(clipboardOwner));
	    event.xany.send_event = False;
	    event.xany.window = Tk_WindowId(clipboardOwner);
	    event.xany.display = Tk_Display(clipboardOwner);
	    event.xselectionclear.selection = dispPtr->clipboardAtom;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158
159
160
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int haveExternalClip =
	    ([[NSPasteboard generalPasteboard] changeCount] != changeCount);

    if (dispPtr && (haveExternalClip || dispPtr->clipboardActive)
	        && selection == dispPtr->clipboardAtom
	        && (target == XA_STRING || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
	}
	if (string) {
	    if (target == dispPtr->utf8Atom) {
		result = proc(clientData, interp, string.UTF8String);
	    } else if (target == XA_STRING) {
		const char *latin1 = [string
		    cStringUsingEncoding:NSISOLatin1StringEncoding];
		result = proc(clientData, interp, latin1);
	    }
	}

    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	     "%s selection doesn't exist or form \"%s\" not defined",
	     Tk_GetAtomName(tkwin, selection),
	     Tk_GetAtomName(tkwin, target)));
	Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *







<
<

<
|
|








<
<
|
<
<
<
<
<
<
>

|
|
<
|
<







110
111
112
113
114
115
116


117

118
119
120
121
122
123
124
125
126
127


128






129
130
131
132

133

134
135
136
137
138
139
140
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;




    if (dispPtr && selection == dispPtr->clipboardAtom && (target == XA_STRING
	    || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
	}


	result = proc(clientData, interp, string ? (char*)[string UTF8String]






		: "");
    } else {
	Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
		" selection doesn't exist or form \"",

		Tk_GetAtomName(tkwin, target), "\" not defined", NULL);

    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 */

int
XSetSelectionOwner(
    Display *display,		/* X Display. */
    Atom selection,		/* What selection to own. */
    Window owner,		/* Window to be the owner. */
    TCL_UNUSED(Time))			/* The current time? */
{
    TkDisplay *dispPtr = TkGetDisplayList();
    (void)time;

    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];
	}
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSelDeadWindow --
 *
 *	This function is invoked just before a TkWindow is deleted. It performs
 *	selection-related cleanup.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	clipboardOwner is cleared.
 *







|


<





<











|
|







153
154
155
156
157
158
159
160
161
162

163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 */

int
XSetSelectionOwner(
    Display *display,		/* X Display. */
    Atom selection,		/* What selection to own. */
    Window owner,		/* Window to be the owner. */
    Time time)			/* The current time? */
{
    TkDisplay *dispPtr = TkGetDisplayList();


    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];
	}
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSelDeadWindow --
 *
 *	This function is invoked just before a TkWindow is deleted. It
 *	performs selection-related cleanup.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	clipboardOwner is cleared.
 *
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TCL_UNUSED(TkWindow *),		/* Window associated with clipboard. */
    TCL_UNUSED(TkClipboardTarget *))
				/* Info about the content. */
{
    NSPasteboard *pb = [NSPasteboard generalPasteboard];

    changeCount = [pb addTypes:[NSArray arrayWithObject:NSStringPboardType]
	    owner:NSApp];
}

/*
 *--------------------------------------------------------------
 *







|
|



<







212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TkWindow *winPtr,		/* Window associated with clipboard. */
    TkClipboardTarget *targetPtr)
				/* Info about the content. */
{
    NSPasteboard *pb = [NSPasteboard generalPasteboard];

    changeCount = [pb addTypes:[NSArray arrayWithObject:NSStringPboardType]
	    owner:NSApp];
}

/*
 *--------------------------------------------------------------
 *
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    if (eventPtr->type == SelectionClear) {
	clipboardOwner = NULL;
	TkSelClearSelection(tkwin, eventPtr);
    }
}







|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    register XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    if (eventPtr->type == SelectionClear) {
	clipboardOwner = NULL;
	TkSelClearSelection(tkwin, eventPtr);
    }
}
291
292
293
294
295
296
297
298
299






















300
301
302
303
304
305
306
307
308
309
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    TCL_UNUSED(XEvent *))	/* X PropertyChange event. */
{






















}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    register XEvent *eventPtr)	/* X PropertyChange event. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TkSuspendClipboard --
 *
 *	Handle clipboard conversion as required by the suppend event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The local scrap is moved to the global scrap.
 *
 *----------------------------------------------------------------------
 */

void
TkSuspendClipboard(void)
{
    changeCount = [[NSPasteboard generalPasteboard] changeCount];
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257


258


259
260
261
262

263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302



303


304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362



363
364
365
366
367
368
369
370
371
372
373
374
375


376

377
378




379
380





381
382



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448


449

450

451
452
453
454
455

456
457
458
459
460
461
462
/*
 * TkMacOSXColor.c --
 *
 *	This file maintains a database of color values for the Tk
 *	toolkit, in order to avoid round-trips to the server to
 *	map color names to pixel values.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkColor.h"
#include "tkMacOSXColor.h"

static Tcl_HashTable systemColors;
static int numSystemColors;
static int rgbColorIndex;
static int controlAccentIndex;
static int selectedTabTextIndex;
static Bool useFakeAccentColor = NO;
static SystemColorDatum **systemColorIndex;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
static NSAppearance *lightAqua = nil;
static NSAppearance *darkAqua = nil;
#endif
static NSColorSpace* sRGB = NULL;
static const CGFloat WINDOWBACKGROUND[4] =
    {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};

void initColorTable()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    Tcl_InitHashTable(&systemColors, TCL_STRING_KEYS);
    SystemColorDatum *entry, *oldEntry;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int newPtr, index = 0;
    NSColorList *systemColorList = [NSColorList colorListNamed:@"System"];
    NSString *key;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    if (@available(macOS 10.14, *)) {
	darkAqua = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
        lightAqua = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
    }
#endif

    /*
     * Build a hash table for looking up a color by its name.


     * First add all of the static entries from tkMacOSXColor.h
     */

    for (entry = systemColorData; entry->name != NULL; entry++) {
	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
	if (entry->type == semantic) {
	    NSString *colorName = [[NSString alloc]
				   initWithCString:entry->macName
					  encoding:NSUTF8StringEncoding];
	    SEL colorSelector = NSSelectorFromString(colorName);
	    if (![NSColor respondsToSelector:colorSelector]) {
		if ([colorName isEqualToString:@"controlAccentColor"]) {
		    useFakeAccentColor = YES;
		} else if (![colorName isEqualToString:@"selectedTabTextColor"]) {
		    /* Uncomment to print all unsupported colors:              */
		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
		    continue;
		}
	    }
	    entry->selector = [colorName retain];
	}
	if (newPtr == 0) {
	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	    entry->index = oldEntry->index;
	    [oldEntry->selector release];
	} else {
	    entry->index = index++;
	}
	Tcl_SetHashValue(hPtr, entry);
    }

    /*
     * Add all of the colors in the System ColorList.
     */

    for (key in [systemColorList allKeys]) {
	int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
	char *name;
	entry = (SystemColorDatum *)ckalloc(sizeof(SystemColorDatum));
	bzero(entry, sizeof(SystemColorDatum));
	name = (char *)ckalloc(length + 1);
	strcpy(name, key.UTF8String);
	name[0] = toupper(name[0]);


        if (!strcmp(name, "WindowBackgroundColor")) {

	    /*
	     * Avoid black windows on old systems.
	     */

	    continue;
	}
	entry->type=semantic;
	entry->name = name;
	entry->selector = [key retain];
	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
	if (newPtr == 0) {
	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	    entry->index = oldEntry->index;
	    [oldEntry->selector release];
	} else {
	    entry->index = index++;
	}
	Tcl_SetHashValue(hPtr, entry);
    }

    /*
     * Build an array for looking up a color by its index.
     */

    numSystemColors = index;
    systemColorIndex = (SystemColorDatum **)ckalloc(numSystemColors * sizeof(SystemColorDatum *));
    for (hPtr = Tcl_FirstHashEntry(&systemColors, &search); hPtr != NULL;
	 hPtr = Tcl_NextHashEntry(&search)) {
	entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	if (entry == NULL) {
	    Tcl_Panic("Unsupported semantic color with no supported backup!");
	}
	systemColorIndex[entry->index] = entry;
    }

    /*
     * Remember the indexes of some special entries.
     */

    hPtr = Tcl_FindHashEntry(&systemColors, "Pixel");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    rgbColorIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "ControlAccentColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAccentIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    selectedTabTextIndex = entry->index;
    [pool drain];
}

/*
 *----------------------------------------------------------------------
 *

 * TkMacOSXRGBPixel --
 *
 *	Return an unsigned long value suitable for use in the pixel
 *	field of an XColor with the specified red, green and blue
 *	intensities.  The inputs are cast as unsigned longs but are
 *      expected to have values representable by an unsigned char.
 *
 *      This is called in the TkpGetPixel macro, used in xcolor.c,
 *      and in ImageGetPixel.
 *
 * Results:
 *	An unsigned long that can be used as the pixel field of an XColor.
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long
TkMacOSXRGBPixel(
    unsigned long red,
    unsigned long green,
    unsigned long blue)
{
    MacPixel p;
    p.pixel.colortype = rgbColor;
    p.pixel.value = ((red & 0xff) << 16)  |
	            ((green & 0xff) << 8) |
	            (blue & 0xff);
    return p.ulong;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXClearPixel --
 *
 *	Return the unsigned long value that appears in the pixel
 *	field of the XColor for systemTransparentColor.
 *
 *      This is used in tkMacOSXImage.c.
 *
 * Results:
 *	The unsigned long that appears in the pixel field of the XColor
 *      for systemTransparentPixel.
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long TkMacOSXClearPixel(
    void)
{
    MacPixel p;
    p.pixel.value = 0;
    p.pixel.colortype = clearColor;
    return p.ulong;
}


/*
 *----------------------------------------------------------------------
 *
 * GetEntryFromPixel --
 *
 *	Look up a SystemColorDatum which describes the XColor with
 *      the specified value as its pixel field.
 *
 * Results:
 *	A pointer to a SystemColorDatum, or NULL if the pixel value is
 *	invalid.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

SystemColorDatum*
GetEntryFromPixel(
    unsigned long pixel)
{
    MacPixel p;
    int index = rgbColorIndex;

    p.ulong = pixel;
    if (p.pixel.colortype != rgbColor) {
	index = p.pixel.value;
    }
    if (index < numSystemColors) {
	return systemColorIndex[index];
    } else {
	return NULL;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetRGBA --


 *


 *	Given a SystemColorDatum and a pointer to an array of 4 CGFloats, store
 *      the associated RGBA color values in the array.  In the case of the
 *      RGBColor datum, the unsigned long pixel value containing the RGB values
 *      must also be provided as the pixel parameter.  Otherwise the pixel

 *      parameter is ignored.
 *
 * Results:
 *	None

 *
 * Side effects:
 *	The array rgba is filled in.
 *
 *----------------------------------------------------------------------
 */

static void
GetRGBA(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGFloat *rgba)
{
    NSColor *bgColor, *color = nil;

    if (!sRGB) {
	sRGB = [NSColorSpace sRGBColorSpace];
    }
    switch (entry->type) {
    case rgbColor:
	rgba[0] = ((pixel >> 16) & 0xff) / 255.0;
	rgba[1] = ((pixel >>  8) & 0xff) / 255.0;
	rgba[2] = ((pixel      ) & 0xff) / 255.0;
	break;
    case ttkBackground:

	/*
	 * Prior to OSX 10.14, getComponents returns black when applied to
	 * windowBackGroundColor.
	 */

	if ([NSApp macOSVersion] < 101400) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	} else {



	    bgColor = [[NSColor windowBackgroundColor] colorUsingColorSpace:sRGB];


	    [bgColor getComponents: rgba];
	}
	if (rgba[0] + rgba[1] + rgba[2] < 1.5) {
	    for (int i=0; i<3; i++) {
		rgba[i] += entry->value*8.0 / 255.0;
	    }
	} else {
	    for (int i=0; i<3; i++) {
		rgba[i] -= entry->value*8.0 / 255.0;
	    }
	}
	break;
    case semantic:
	if (entry->index == controlAccentIndex && useFakeAccentColor) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
	    color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
			      colorUsingColorSpace:sRGB];
#endif
	} else if (entry->index == selectedTabTextIndex) {
	    int OSVersion = [NSApp macOSVersion];
	    if (OSVersion > 100600 && OSVersion < 110000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    }



	} else {
	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
	}
	[color getComponents: rgba];
	break;
    case clearColor:
	rgba[3] = 0;
    default:
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SetCGColorComponents --
 *
 *	Set the components of a CGColorRef from an XColor pixel value and a
 *      SystemColorDatum.  The pixel value is only used in the case where
 *      the color is of type rgbColor.  In that case the normalized XColor RGB
 *      values are copied into the CGColorRef.  Otherwise the components are
 *      computed from the SystemColorDatum.
 *
 * Results:
 *	True if the function succeeds, false otherwise.

 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Bool
SetCGColorComponents(
    SystemColorDatum *entry,
    unsigned long pixel,



    CGColorRef *c)
{
    CGFloat rgba[4] = {0, 0, 0, 1};

    /*
     * This function is called before our autorelease pool is set up,
     * so it needs its own pool.
     */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (entry->type == HIBrush) {
     	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);


     	return err == noErr;

    }
    GetRGBA(entry, pixel, rgba);




    *c = CGColorCreate(sRGB.CGColorSpace, rgba);
    [pool drain];





    return true;
}




/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInDarkMode --
 *
 *      Tests whether the given window's NSView has a DarkAqua Appearance.
 *
 * Results:
 *      Returns true if the NSView is in DarkMode, false if not.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE Bool
TkMacOSXInDarkMode(Tk_Window tkwin)
{

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    if (@available(macOS 10.14, *)) {
        TkWindow *winPtr = (TkWindow*) tkwin;
	NSAppearanceName name;
	NSView *view = nil;
	if (winPtr && winPtr->privatePtr) {
	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
	}
	if (view) {
	    name = [[view effectiveAppearance] name];
	} else {
	    name = [[NSAppearance currentAppearance] name];

	}
	return (name == NSAppearanceNameDarkAqua);

    }
#endif
    return false;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetMacColor --
 *
 *	Sets the components of a CGColorRef from an XColor pixel value.  The
 *      pixel value is used to look up the color in the system color table, and
 *      then SetCGColorComponents is called with the table entry and the pixel
 *      value.
 *
 * Results:
 *      Returns false if the color is not found, true otherwise.
 *
 * Side effects:
 *	The variable macColor is set to a new CGColorRef, the caller is
 *	responsible for releasing it!
 *
 *----------------------------------------------------------------------
 */

int
TkSetMacColor(
    unsigned long pixel,		/* Pixel value to convert. */
    void *macColor)			/* CGColorRef to modify. */
{
    CGColorRef *color = (CGColorRef*)macColor;


    SystemColorDatum *entry = GetEntryFromPixel(pixel);



    if (entry) {
	return SetCGColorComponents(entry, pixel, color);
    } else {
	return false;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkpInitGCCache, TkpFreeGCCache, CopyCachedColor, SetCachedColor --
 *

|









<







<

<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
|
<
<
|
<
<
<
<
|
<
<
|
<
>
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
|
>
>
|
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
|
|
<
|
<
<
<
<
|
>
>

>
>
|
<
<
<
>
|


<
>


|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
|
<
<
|
>
>
>
|
>
>
|
<
<
|
|
<
|
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
|
>
>
>
|
<
<
<
|
<
<
<
<






|

|
<
<
<
<


<
>







|
|
<

>
>
>


<
|
<
<
<
<

<
<
|
|
>
>
|
>
|
|
>
>
>
>
|
|
>
>
>
>
>
|
|
>
>
>
|
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
>

<
>

<
|







|
<
<
<


|














>
>
|
>

>
|
|
|
<

>







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18

19

20










21

22
23






24


25




26


27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66



67
68
69
70
71


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88



89










90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115















116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142










143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170






171
172

173




174
175
176
177
178
179
180



181
182
183
184

185
186
187
188
189
190
























191
192

193


194
195
196
197
198
199
200
201


202
203

204




205




206
207




208
209
210
211
212



213




214
215
216
217
218
219
220
221
222




223
224

225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240

241




242


243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267









268
269
270
271


272



273








274



275
276

277
278

279
280
281
282
283
284
285
286
287



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
/*
 * tkMacOSXColor.c --
 *
 *	This file maintains a database of color values for the Tk
 *	toolkit, in order to avoid round-trips to the server to
 *	map color names to pixel values.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkColor.h"



struct SystemColorMapEntry {










    const char *name;

    ThemeBrush brush;
    ThemeTextColor textColor;






    ThemeBackgroundKind background;


};  /* unsigned char pixelCode; */







/*

 * Array of system color definitions: the array index is required to equal the
 * color's (pixelCode - MIN_PIXELCODE), i.e. the array order needs to be kept
 * in sync with the public pixel code values in tkMacOSXPort.h !
 */

#define MIN_PIXELCODE  30
static const struct SystemColorMapEntry systemColorMap[] = {
    { "Transparent",			    0, 0, 0 },							/*  30: TRANSPARENT_PIXEL */
    { "Highlight",			    kThemeBrushPrimaryHighlightColor, 0, 0 },			/*  31: HIGHLIGHT_PIXEL */
    { "HighlightSecondary",		    kThemeBrushSecondaryHighlightColor, 0, 0 },			/*  32: HIGHLIGHT_SECONDARY_PIXEL */
    { "HighlightText",			    kThemeBrushBlack, 0, 0 },					/*  33: HIGHLIGHT_TEXT_PIXEL */
    { "HighlightAlternate",		    kThemeBrushAlternatePrimaryHighlightColor, 0, 0 },		/*  34: HIGHLIGHT_ALTERNATE_PIXEL */
    { "ButtonText",			    0, kThemeTextColorPushButtonActive, 0 },			/*  35: CONTROL_TEXT_PIXEL */
    { "PrimaryHighlightColor",		    kThemeBrushPrimaryHighlightColor, 0, 0 },			/*  36 */
    { "ButtonFace",			    kThemeBrushButtonFaceActive, 0, 0 },			/*  37: CONTROL_BODY_PIXEL */
    { "SecondaryHighlightColor",	    kThemeBrushSecondaryHighlightColor, 0, 0 },			/*  38 */
    { "ButtonFrame",			    kThemeBrushButtonFrameActive, 0, 0 },			/*  39: CONTROL_FRAME_PIXEL */
    { "AlternatePrimaryHighlightColor",	    kThemeBrushAlternatePrimaryHighlightColor, 0, 0 },		/*  40 */
    { "WindowBody",			    kThemeBrushDocumentWindowBackground, 0, 0 },		/*  41: WINDOW_BODY_PIXEL */
    { "SheetBackground",		    kThemeBrushSheetBackground, 0, 0 },				/*  42 */
    { "MenuActive",			    kThemeBrushMenuBackgroundSelected, 0, 0 },			/*  43: MENU_ACTIVE_PIXEL */
    { "Black",				    kThemeBrushBlack, 0, 0 },					/*  44 */


    { "MenuActiveText",			    0, kThemeTextColorMenuItemSelected, 0 },			/*  45: MENU_ACTIVE_TEXT_PIXEL */
    { "White",				    kThemeBrushWhite, 0, 0 },					/*  46 */
    { "Menu",				    kThemeBrushMenuBackground, 0, 0 },				/*  47: MENU_BACKGROUND_PIXEL */
    { "DialogBackgroundActive",		    kThemeBrushDialogBackgroundActive, 0, 0 },			/*  48 */
    { "MenuDisabled",			    0, kThemeTextColorMenuItemDisabled, 0 },			/*  49: MENU_DISABLED_PIXEL */
    { "DialogBackgroundInactive",	    kThemeBrushDialogBackgroundInactive, 0, 0 },		/*  50 */
    { "MenuText",			    0, kThemeTextColorMenuItemActive, 0 },			/*  51: MENU_TEXT_PIXEL */
    { "AppearanceColor",		    0, 0, 0 },							/*  52: APPEARANCE_PIXEL */
    { "AlertBackgroundActive",		    kThemeBrushAlertBackgroundActive, 0, 0 },			/*  53 */
    { "AlertBackgroundInactive",	    kThemeBrushAlertBackgroundInactive, 0, 0 },			/*  54 */
    { "ModelessDialogBackgroundActive",	    kThemeBrushModelessDialogBackgroundActive, 0, 0 },		/*  55 */
    { "ModelessDialogBackgroundInactive",   kThemeBrushModelessDialogBackgroundInactive, 0, 0 },	/*  56 */
    { "UtilityWindowBackgroundActive",	    kThemeBrushUtilityWindowBackgroundActive, 0, 0 },		/*  57 */
    { "UtilityWindowBackgroundInactive",    kThemeBrushUtilityWindowBackgroundInactive, 0, 0 },		/*  58 */
    { "ListViewSortColumnBackground",	    kThemeBrushListViewSortColumnBackground, 0, 0 },		/*  59 */
    { "ListViewBackground",		    kThemeBrushListViewBackground, 0, 0 },			/*  60 */
    { "IconLabelBackground",		    kThemeBrushIconLabelBackground, 0, 0 },			/*  61 */



    { "ListViewSeparator",		    kThemeBrushListViewSeparator, 0, 0 },			/*  62 */
    { "ChasingArrows",			    kThemeBrushChasingArrows, 0, 0 },				/*  63 */
    { "DragHilite",			    kThemeBrushDragHilite, 0, 0 },				/*  64 */
    { "DocumentWindowBackground",	    kThemeBrushDocumentWindowBackground, 0, 0 },		/*  65 */
    { "FinderWindowBackground",		    kThemeBrushFinderWindowBackground, 0, 0 },			/*  66 */


    { "ScrollBarDelimiterActive",	    kThemeBrushScrollBarDelimiterActive, 0, 0 },		/*  67 */
    { "ScrollBarDelimiterInactive",	    kThemeBrushScrollBarDelimiterInactive, 0, 0 },		/*  68 */
    { "FocusHighlight",			    kThemeBrushFocusHighlight, 0, 0 },				/*  69 */
    { "PopupArrowActive",		    kThemeBrushPopupArrowActive, 0, 0 },			/*  70 */
    { "PopupArrowPressed",		    kThemeBrushPopupArrowPressed, 0, 0 },			/*  71 */
    { "PopupArrowInactive",		    kThemeBrushPopupArrowInactive, 0, 0 },			/*  72 */
    { "AppleGuideCoachmark",		    kThemeBrushAppleGuideCoachmark, 0, 0 },			/*  73 */
    { "IconLabelBackgroundSelected",	    kThemeBrushIconLabelBackgroundSelected, 0, 0 },		/*  74 */
    { "StaticAreaFill",			    kThemeBrushStaticAreaFill, 0, 0 },				/*  75 */
    { "ActiveAreaFill",			    kThemeBrushActiveAreaFill, 0, 0 },				/*  76 */
    { "ButtonFrameActive",		    kThemeBrushButtonFrameActive, 0, 0 },			/*  77 */
    { "ButtonFrameInactive",		    kThemeBrushButtonFrameInactive, 0, 0 },			/*  78 */
    { "ButtonFaceActive",		    kThemeBrushButtonFaceActive, 0, 0 },			/*  79 */
    { "ButtonFaceInactive",		    kThemeBrushButtonFaceInactive, 0, 0 },			/*  80 */
    { "ButtonFacePressed",		    kThemeBrushButtonFacePressed, 0, 0 },			/*  81 */
    { "ButtonActiveDarkShadow",		    kThemeBrushButtonActiveDarkShadow, 0, 0 },			/*  82 */

    { "ButtonActiveDarkHighlight",	    kThemeBrushButtonActiveDarkHighlight, 0, 0 },		/*  83 */



    { "ButtonActiveLightShadow",	    kThemeBrushButtonActiveLightShadow, 0, 0 },			/*  84 */










    { "ButtonActiveLightHighlight",	    kThemeBrushButtonActiveLightHighlight, 0, 0 },		/*  85 */

    { "ButtonInactiveDarkShadow",	    kThemeBrushButtonInactiveDarkShadow, 0, 0 },		/*  86 */
    { "ButtonInactiveDarkHighlight",	    kThemeBrushButtonInactiveDarkHighlight, 0, 0 },		/*  87 */
    { "ButtonInactiveLightShadow",	    kThemeBrushButtonInactiveLightShadow, 0, 0 },		/*  88 */
    { "ButtonInactiveLightHighlight",	    kThemeBrushButtonInactiveLightHighlight, 0, 0 },		/*  89 */
    { "ButtonPressedDarkShadow",	    kThemeBrushButtonPressedDarkShadow, 0, 0 },			/*  90 */
    { "ButtonPressedDarkHighlight",	    kThemeBrushButtonPressedDarkHighlight, 0, 0 },		/*  91 */
    { "ButtonPressedLightShadow",	    kThemeBrushButtonPressedLightShadow, 0, 0 },		/*  92 */
    { "ButtonPressedLightHighlight",	    kThemeBrushButtonPressedLightHighlight, 0, 0 },		/*  93 */
    { "BevelActiveLight",		    kThemeBrushBevelActiveLight, 0, 0 },			/*  94 */
    { "BevelActiveDark",		    kThemeBrushBevelActiveDark, 0, 0 },				/*  95 */
    { "BevelInactiveLight",		    kThemeBrushBevelInactiveLight, 0, 0 },			/*  96 */
    { "BevelInactiveDark",		    kThemeBrushBevelInactiveDark, 0, 0 },			/*  97 */
    { "NotificationWindowBackground",	    kThemeBrushNotificationWindowBackground, 0, 0 },		/*  98 */
    { "MovableModalBackground",		    kThemeBrushMovableModalBackground, 0, 0 },			/*  99 */
    { "SheetBackgroundOpaque",		    kThemeBrushSheetBackgroundOpaque, 0, 0 },			/* 100 */
    { "DrawerBackground",		    kThemeBrushDrawerBackground, 0, 0 },			/* 101 */
    { "ToolbarBackground",		    kThemeBrushToolbarBackground, 0, 0 },			/* 102 */
    { "SheetBackgroundTransparent",	    kThemeBrushSheetBackgroundTransparent, 0, 0 },		/* 103 */
    { "MenuBackground",			    kThemeBrushMenuBackground, 0, 0 },				/* 104 */
    { "Pixel",				    0, 0, 0 },							/* 105: PIXEL_MAGIC */

    { "MenuBackgroundSelected",		    kThemeBrushMenuBackgroundSelected, 0, 0 },			/* 106 */
    { "ListViewOddRowBackground",	    kThemeBrushListViewOddRowBackground, 0, 0 },		/* 107 */
    { "ListViewEvenRowBackground",	    kThemeBrushListViewEvenRowBackground, 0, 0 },		/* 108 */
    { "ListViewColumnDivider",		    kThemeBrushListViewColumnDivider, 0, 0 },			/* 109 */
    { "BlackText",			    0, kThemeTextColorBlack, 0 },				/* 110 */















    { "DialogActiveText",		    0, kThemeTextColorDialogActive, 0 },			/* 111 */
    { "DialogInactiveText",		    0, kThemeTextColorDialogInactive, 0 },			/* 112 */
    { "AlertActiveText",		    0, kThemeTextColorAlertActive, 0 },				/* 113 */
    { "AlertInactiveText",		    0, kThemeTextColorAlertInactive, 0 },			/* 114 */
    { "ModelessDialogActiveText",	    0, kThemeTextColorModelessDialogActive, 0 },		/* 115 */
    { "ModelessDialogInactiveText",	    0, kThemeTextColorModelessDialogInactive, 0 },		/* 116 */
    { "WindowHeaderActiveText",		    0, kThemeTextColorWindowHeaderActive, 0 },			/* 117 */
    { "WindowHeaderInactiveText",	    0, kThemeTextColorWindowHeaderInactive, 0 },		/* 118 */
    { "PlacardActiveText",		    0, kThemeTextColorPlacardActive, 0 },			/* 119 */
    { "PlacardInactiveText",		    0, kThemeTextColorPlacardInactive, 0 },			/* 120 */
    { "PlacardPressedText",		    0, kThemeTextColorPlacardPressed, 0 },			/* 121 */
    { "PushButtonActiveText",		    0, kThemeTextColorPushButtonActive, 0 },			/* 122 */
    { "PushButtonInactiveText",		    0, kThemeTextColorPushButtonInactive, 0 },			/* 123 */
    { "PushButtonPressedText",		    0, kThemeTextColorPushButtonPressed, 0 },			/* 124 */
    { "BevelButtonActiveText",		    0, kThemeTextColorBevelButtonActive, 0 },			/* 125 */
    { "BevelButtonInactiveText",	    0, kThemeTextColorBevelButtonInactive, 0 },			/* 126 */
    { "BevelButtonPressedText",		    0, kThemeTextColorBevelButtonPressed, 0 },			/* 127 */
    { "PopupButtonActiveText",		    0, kThemeTextColorPopupButtonActive, 0 },			/* 128 */
    { "PopupButtonInactiveText",	    0, kThemeTextColorPopupButtonInactive, 0 },			/* 129 */
    { "PopupButtonPressedText",		    0, kThemeTextColorPopupButtonPressed, 0 },			/* 130 */
    { "IconLabelText",			    0, kThemeTextColorIconLabel, 0 },				/* 131 */
    { "ListViewText",			    0, kThemeTextColorListView, 0 },				/* 132 */
    { "DocumentWindowTitleActiveText",	    0, kThemeTextColorDocumentWindowTitleActive, 0 },		/* 133 */
    { "DocumentWindowTitleInactiveText",    0, kThemeTextColorDocumentWindowTitleInactive, 0 },		/* 134 */
    { "MovableModalWindowTitleActiveText",  0, kThemeTextColorMovableModalWindowTitleActive, 0 },	/* 135 */
    { "MovableModalWindowTitleInactiveText",0, kThemeTextColorMovableModalWindowTitleInactive, 0 },	/* 136 */
    { "UtilityWindowTitleActiveText",	    0, kThemeTextColorUtilityWindowTitleActive, 0 },		/* 137 */










    { "UtilityWindowTitleInactiveText",	    0, kThemeTextColorUtilityWindowTitleInactive, 0 },		/* 138 */
    { "PopupWindowTitleActiveText",	    0, kThemeTextColorPopupWindowTitleActive, 0 },		/* 139 */
    { "PopupWindowTitleInactiveText",	    0, kThemeTextColorPopupWindowTitleInactive, 0 },		/* 140 */
    { "RootMenuActiveText",		    0, kThemeTextColorRootMenuActive, 0 },			/* 141 */
    { "RootMenuSelectedText",		    0, kThemeTextColorRootMenuSelected, 0 },			/* 142 */
    { "RootMenuDisabledText",		    0, kThemeTextColorRootMenuDisabled, 0 },			/* 143 */
    { "MenuItemActiveText",		    0, kThemeTextColorMenuItemActive, 0 },			/* 144 */
    { "MenuItemSelectedText",		    0, kThemeTextColorMenuItemSelected, 0 },			/* 145 */
    { "MenuItemDisabledText",		    0, kThemeTextColorMenuItemDisabled, 0 },			/* 146 */
    { "PopupLabelActiveText",		    0, kThemeTextColorPopupLabelActive, 0 },			/* 147 */
    { "PopupLabelInactiveText",		    0, kThemeTextColorPopupLabelInactive, 0 },			/* 148 */
    { "TabFrontActiveText",		    0, kThemeTextColorTabFrontActive, 0 },			/* 149 */
    { "TabNonFrontActiveText",		    0, kThemeTextColorTabNonFrontActive, 0 },			/* 150 */
    { "TabNonFrontPressedText",		    0, kThemeTextColorTabNonFrontPressed, 0 },			/* 151 */
    { "TabFrontInactiveText",		    0, kThemeTextColorTabFrontInactive, 0 },			/* 152 */
    { "TabNonFrontInactiveText",	    0, kThemeTextColorTabNonFrontInactive, 0 },			/* 153 */
    { "IconLabelSelectedText",		    0, kThemeTextColorIconLabelSelected, 0 },			/* 154 */
    { "BevelButtonStickyActiveText",	    0, kThemeTextColorBevelButtonStickyActive, 0 },		/* 155 */
    { "BevelButtonStickyInactiveText",	    0, kThemeTextColorBevelButtonStickyInactive, 0 },		/* 156 */
    { "NotificationText",		    0, kThemeTextColorNotification, 0 },			/* 157 */
    { "SystemDetailText",		    0, kThemeTextColorSystemDetail, 0 },			/* 158 */
    { "WhiteText",			    0, kThemeTextColorWhite, 0 },				/* 159 */
    { "TabPaneBackground",		    0, 0, kThemeBackgroundTabPane },				/* 160 */
    { "PlacardBackground",		    0, 0, kThemeBackgroundPlacard },				/* 161 */
    { "WindowHeaderBackground",		    0, 0, kThemeBackgroundWindowHeader },			/* 162 */
    { "ListViewWindowHeaderBackground",	    0, 0, kThemeBackgroundListViewWindowHeader },		/* 163 */
    { "SecondaryGroupBoxBackground",	    0, 0, kThemeBackgroundSecondaryGroupBox },			/* 164 */
    { "MetalBackground",		    0, 0, kThemeBackgroundMetal },				/* 165 */






    { NULL,				    0, 0, 0 }
};

#define MAX_PIXELCODE 165





/*
 *----------------------------------------------------------------------
 *
 * GetThemeFromPixelCode --
 *
 *	When given a pixel code corresponding to a theme system color,



 *	set one of brush, textColor or background to the corresponding
 *	Appearance Mgr theme constant.
 *
 * Results:

 *	Returns false if not a real pixel, true otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
























 */


static int


GetThemeFromPixelCode(
    unsigned char code,
    ThemeBrush *brush,
    ThemeTextColor *textColor,
    ThemeBackgroundKind *background)
{
    if (code >= MIN_PIXELCODE && code <= MAX_PIXELCODE) {
	*brush = systemColorMap[code - MIN_PIXELCODE].brush;


	*textColor = systemColorMap[code - MIN_PIXELCODE].textColor;
	*background = systemColorMap[code - MIN_PIXELCODE].background;

    } else {




	*brush = 0;




	*textColor = 0;
	*background = 0;




    }
    if (!*brush && !*textColor && !*background && code != PIXEL_MAGIC &&
	    code != TRANSPARENT_PIXEL) {
	return false;
    } else {



	return true;




    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetThemeColor --
 *
 *	Get RGB color for a given system color or pixel value.




 *
 * Results:

 *	OSStatus
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSStatus
GetThemeColor(

    unsigned long pixel,
    ThemeBrush brush,
    ThemeTextColor textColor,
    ThemeBackgroundKind background,
    CGColorRef *c)
{

    OSStatus err = noErr;







    if (brush) {
	err = ChkErr(HIThemeBrushCreateCGColor, brush, c);
    /*} else if (textColor) {
	err = ChkErr(GetThemeTextColor, textColor, 32, true, c);*/
    } else {
	CGFloat rgba[4] = {0, 0, 0, 1};

	switch ((pixel >> 24) & 0xff) {
	case PIXEL_MAGIC: {
	    unsigned short red, green, blue;
	    red		= (pixel >> 16) & 0xff;
	    green	= (pixel >>  8) & 0xff;
	    blue	= (pixel      ) & 0xff;
	    red		|= red   << 8;
	    green	|= green << 8;
	    blue	|= blue  << 8;
	    rgba[0]	= red	/ 65535.0;
	    rgba[1]	= green / 65535.0;
	    rgba[2]	= blue  / 65535.0;
	    break;
	    }
	case TRANSPARENT_PIXEL:
	    rgba[3]	= 0.0;
	    break;
	}










        // this attempts to find something roughly fitting for any display
//	*c = CGColorCreateGenericRGB(rgba[0], rgba[1], rgba[2], rgba[3]);



        // may be off for non-main display but in most cases better than prev



	static CGColorSpaceRef deviceRGBSpace = NULL;








	if (!deviceRGBSpace) {



	    deviceRGBSpace = CGDisplayCopyColorSpace(CGMainDisplayID());
	}

	*c = CGColorCreate(deviceRGBSpace, rgba );
    }

    return err;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetMacColor --
 *
 *	Creates a CGColorRef from a X style pixel value.



 *
 * Results:
 *	Returns false if not a real pixel, true otherwise.
 *
 * Side effects:
 *	The variable macColor is set to a new CGColorRef, the caller is
 *	responsible for releasing it!
 *
 *----------------------------------------------------------------------
 */

int
TkSetMacColor(
    unsigned long pixel,		/* Pixel value to convert. */
    void *macColor)			/* CGColorRef to modify. */
{
    CGColorRef *color = (CGColorRef*)macColor;
    OSStatus err = -1;
    ThemeBrush brush;
    ThemeTextColor textColor;
    ThemeBackgroundKind background;

    if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor,
	    &background)) {
	err = ChkErr(GetThemeColor, pixel, brush, textColor, background,
		color);

    }
    return (err == noErr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpInitGCCache, TkpFreeGCCache, CopyCachedColor, SetCachedColor --
 *
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

614
615

616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634

635
636
637
638
639
640
641
642
643
644
645
646
647






648


649

650
651







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

713
714
715
716
717

718
719
720



721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768




769
770
771

772
773

774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795

796
797
798



799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSColor --
 *
 *	Creates an autoreleased NSColor from a X style pixel value.
 *      The return value is nil if the pixel value is invalid.
 *
 * Results:
 *	A possibly nil pointer to an NSColor.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

NSColor*
TkMacOSXGetNSColor(
    GC gc,
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = TkMacOSXCreateCGColor(gc, pixel);
    NSColor *nsColor = nil;

    if (cgColor) {
	NSColorSpace *colorSpace = [[NSColorSpace alloc]
		initWithCGColorSpace:CGColorGetColorSpace(cgColor)];

	nsColor = [NSColor colorWithColorSpace:colorSpace
		components:CGColorGetComponents(cgColor)
		count:CGColorGetNumberOfComponents(cgColor)];
	[colorSpace release];
	CFRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetColorInContext --
 *
 *	Sets the fill and stroke colors in the given CGContext to the CGColor

 *	which corresponds to the XColor having the specified value for its pixel
 *	field.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    GC gc,
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = noErr;
    CGColorRef cgColor = nil;

    SystemColorDatum *entry = GetEntryFromPixel(pixel);


    if (entry) {
	switch (entry->type) {
	case HIBrush:
	    err = ChkErr(HIThemeSetFill, entry->value, NULL, context,
		    kHIThemeOrientationNormal);
	    if (err == noErr) {
		err = ChkErr(HIThemeSetStroke, entry->value, NULL, context,
			kHIThemeOrientationNormal);
	    }
	    break;
	default:
	    if (SetCGColorComponents(entry, pixel, &cgColor)){






		SetCachedColor(gc, pixel, cgColor);


	    }

	    break;
	}







    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);
    }
    if (err != noErr) {
	TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColor --
 *
 *	Create a new TkColor for the color with the given name, for use in the
 *      specified window. The colormap field is set to lightColormap if the
 *      window has a LightAqua appearance, or darkColormap if the window has a
 *      DarkAqua appearance.  TkColors with different colormaps are managed
 *      separately in the per-display table of TkColors maintained by Tk.
 *
 *      This function is called by Tk_GetColor.
 *
 * Results:
 *	Returns a newly allocated TkColor, or NULL on failure.
 *
 * Side effects:
 *

 *	Allocates memory for the TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColor(
    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). */
{
    Display *display = NULL;

    TkColor *tkColPtr;
    XColor color;
    Colormap colormap = tkwin ? Tk_Colormap(tkwin) : noColormap;
    NSView *view = nil;
    static Bool initialized = NO;
    static NSColorSpace* sRGB = NULL;

    if (!initialized) {
	initialized = YES;
	sRGB = [NSColorSpace sRGBColorSpace];
	initColorTable();
    }
    if (tkwin) {
	display = Tk_Display(tkwin);
	Drawable d = Tk_WindowId(tkwin);
	view = TkMacOSXGetNSViewForDrawable(d);
    }

    /*
     * Check to see if this is a system color. If not, just call XParseColor.

     */

    if (strncasecmp(name, "system", 6) == 0) {
	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&systemColors, name + 6);
	MacPixel p;


	if (hPtr != NULL) {
	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);



	    CGColorRef c;

	    p.pixel.colortype = entry->type;
	    p.pixel.value = entry->index;
	    color.pixel = p.ulong;
	    if (entry->type == semantic) {
		CGFloat rgba[4];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
		if (@available(macOS 10.14, *)) {
		    NSAppearance *savedAppearance = [NSAppearance currentAppearance];
		    NSAppearance *windowAppearance = savedAppearance;
		    if (view) {
			windowAppearance = [view effectiveAppearance];
		    }
		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
			colormap = darkColormap;
		    } else {
			colormap = lightColormap;
		    }
		    [NSAppearance setCurrentAppearance:windowAppearance];
		    GetRGBA(entry, p.ulong, rgba);
		    [NSAppearance setCurrentAppearance:savedAppearance];
		} else {
		    GetRGBA(entry, p.ulong, rgba);
		}
#else
		GetRGBA(entry, p.ulong, rgba);
#endif
		color.red   = rgba[0] * 65535.0;
		color.green = rgba[1] * 65535.0;
		color.blue  = rgba[2] * 65535.0;
		goto validXColor;
	    } else if (SetCGColorComponents(entry, 0, &c)) {
		const size_t n = CGColorGetNumberOfComponents(c);
		const CGFloat *rgba = CGColorGetComponents(c);

		switch (n) {
		case 4:
		    color.red   = rgba[0] * 65535.0;
		    color.green = rgba[1] * 65535.0;
		    color.blue  = rgba[2] * 65535.0;
		    break;
		case 2:
		    color.red = color.green = color.blue = rgba[0] * 65535.0;
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", (int) n);
		}




		CGColorRelease(c);
		goto validXColor;
	    }

	}
    }

    if (TkParseColor(display, colormap, name, &color) == 0) {
	return NULL;
    }

validXColor:
    tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
    tkColPtr->colormap = colormap;
    tkColPtr->color = color;
    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColorByValue --
 *
 *	Given an pointer to an XColor, construct a TkColor whose red, green and
 *	blue intensities match those of the XColor as closely as possible.  For
 *	the Macintosh, this means that the colortype bitfield of the pixel
 *	value will be RGBColor and that the color intensities stored in its
 *	24-bit value bitfield are computed from the 16-bit red green and blue
 *	values in the XColor by dividing by 256.

 *
 * Results:
 *	A pointer to a newly allocated TkColor structure.



 *
 * Side effects:
 *	May invalidate the colormap cache for the specified window.
 *	Allocates memory for a TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColorByValue(
    TCL_UNUSED(Tk_Window),		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    TkColor *tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));

    tkColPtr->color.red = colorPtr->red;
    tkColPtr->color.green = colorPtr->green;
    tkColPtr->color.blue = colorPtr->blue;
    tkColPtr->color.pixel = TkpGetPixel(colorPtr);
    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Stub functions --







<


|


















<














|
>
|
<
>
















|
|
>
|
>

|
|
|
|


|


<
<
|
>
>
>
>
>
>
|
>
>
|
>
|

>
>
>
>
>
>
>






<
<
<







|
<
<
<
<
<
<





|
>
|







|


|
>


<
<
<
<

<
<
<
<
<
<
<
<
<
<
<

|
>

<

|
<
>

|
|
>
>
>

|
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|













|

>
>
>
>



>


>

|



|
|
|








<
|
<
<
<
|
>


|
>
>
>



|






|



|




|







429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505


506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532



533
534
535
536
537
538
539
540






541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562




563











564
565
566
567

568
569

570
571
572
573
574
575
576
577
578


579










580

581
582












583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSColor --
 *
 *	Creates an autoreleased NSColor from a X style pixel value.

 *
 * Results:
 *	Returns nil if not a real pixel, NSColor* otherwise.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

NSColor*
TkMacOSXGetNSColor(
    GC gc,
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = TkMacOSXCreateCGColor(gc, pixel);
    NSColor *nsColor = nil;

    if (cgColor) {
	NSColorSpace *colorSpace = [[NSColorSpace alloc]
		initWithCGColorSpace:CGColorGetColorSpace(cgColor)];

	nsColor = [NSColor colorWithColorSpace:colorSpace
		components:CGColorGetComponents(cgColor)
		count:CGColorGetNumberOfComponents(cgColor)];
	[colorSpace release];
	CFRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetColorInContext --
 *
 *	Sets fill and stroke color in the given CG context from an X
 *	pixel value, or if the pixel code indicates a system color,
 *	sets the corresponding brush, textColor or background via

 *	HITheme APIs if available or Appearance mgr APIs.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    GC gc,
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = -1;
    CGColorRef cgColor = CopyCachedColor(gc, pixel);
    ThemeBrush brush;
    ThemeTextColor textColor;
    ThemeBackgroundKind background;

    if (!cgColor && GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush,
	    &textColor, &background)) {
	if (brush) {
	    err = ChkErr(HIThemeSetFill, brush, NULL, context,
		    kHIThemeOrientationNormal);
	    if (err == noErr) {
		err = ChkErr(HIThemeSetStroke, brush, NULL, context,
			kHIThemeOrientationNormal);
	    }


	} else if (textColor) {
	    err = ChkErr(HIThemeSetTextFill, textColor, NULL, context,
		    kHIThemeOrientationNormal);
	} else if (background) {
	    CGRect rect = CGContextGetClipBoundingBox(context);
	    HIThemeBackgroundDrawInfo info = { 0, kThemeStateActive,
		    background };

	    err = ChkErr(HIThemeApplyBackground, &rect, &info,
		    context, kHIThemeOrientationNormal);
	}
	if (err == noErr) {
	    return;
	}
	err = ChkErr(GetThemeColor, pixel, brush, textColor, background,
		&cgColor);
	if (err == noErr) {
	    SetCachedColor(gc, pixel, cgColor);
	}
    } else if (!cgColor) {
	TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);
    }



}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColor --
 *
 *	Allocate a new TkColor for the color with the given name.






 *
 * Results:
 *	Returns a newly allocated TkColor, or NULL on failure.
 *
 * Side effects:
 *	May invalidate the colormap cache associated with tkwin upon
 *	allocating a new colormap entry. Allocates a new TkColor
 *	structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColor(
    Tk_Window tkwin,		/* Window in which color will be used. */
    Tk_Uid name)		/* Name of color to allocated (in form
				 * suitable for passing to XParseColor). */
{
    Display *display = tkwin != None ? Tk_Display(tkwin) : NULL;
    Colormap colormap = tkwin!= None ? Tk_Colormap(tkwin) : None;
    TkColor *tkColPtr;
    XColor color;
















    /*
     * Check to see if this is a system color. Otherwise, XParseColor
     * will do all the work.
     */

    if (strncasecmp(name, "system", 6) == 0) {
	Tcl_Obj *strPtr = Tcl_NewStringObj(name+6, -1);

	int idx, result;

	result = Tcl_GetIndexFromObjStruct(NULL, strPtr, systemColorMap,
		    sizeof(struct SystemColorMapEntry), NULL, TCL_EXACT, &idx);
	Tcl_DecrRefCount(strPtr);
	if (result == TCL_OK) {
	    OSStatus err;
	    CGColorRef c;
	    unsigned char pixelCode = idx + MIN_PIXELCODE;


	    ThemeBrush brush = systemColorMap[idx].brush;










	    ThemeTextColor textColor = systemColorMap[idx].textColor;

	    ThemeBackgroundKind background = systemColorMap[idx].background;













	    err = ChkErr(GetThemeColor, 0, brush, textColor, background, &c);
	    if (err == noErr) {
		const size_t n = CGColorGetNumberOfComponents(c);
		const CGFloat *rgba = CGColorGetComponents(c);

		switch (n) {
		case 4:
		    color.red   = rgba[0] * 65535.0;
		    color.green = rgba[1] * 65535.0;
		    color.blue  = rgba[2] * 65535.0;
		    break;
		case 2:
		    color.red = color.green = color.blue = rgba[0] * 65535.0;
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", n);
		}
		color.pixel = ((((((pixelCode << 8)
		    | ((color.red   >> 8) & 0xff)) << 8)
		    | ((color.green >> 8) & 0xff)) << 8)
		    | ((color.blue  >> 8) & 0xff));
		CGColorRelease(c);
		goto validXColor;
	    }
	    CGColorRelease(c);
	}
    }

    if (TkParseColor(display, colormap, name, &color) == 0) {
	return (TkColor *) NULL;
    }

validXColor:
    tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
    tkColPtr->color = color;

    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColorByValue --
 *

 *	Given a desired set of red-green-blue intensities for a color,



 *	locate a pixel value to use to draw that color in a given
 *	window.
 *
 * Results:
 *	The return value is a pointer to an TkColor structure that
 *	indicates the closest red, blue, and green intensities available
 *	to those specified in colorPtr, and also specifies a pixel
 *	value to use to draw in that color.
 *
 * Side effects:
 *	May invalidate the colormap cache for the specified window.
 *	Allocates a new TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    TkColor *tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));

    tkColPtr->color.red = colorPtr->red;
    tkColPtr->color.green = colorPtr->green;
    tkColPtr->color.blue = colorPtr->blue;
    tkColPtr->color.pixel = TkpGetPixel(&tkColPtr->color);
    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Stub functions --
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
893
894
895
896
 *
 *----------------------------------------------------------------------
 */

Status
XAllocColor(
    Display *display,		/* Display. */
    TCL_UNUSED(Colormap),		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    display->request++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Window),		/* X window. */
    TCL_UNUSED(Visual *),		/* Not used. */
    TCL_UNUSED(int))			/* Not used. */
{
    static Colormap index = 16;

    /*
     * Just return a new value each time, large enough that it will not
     * conflict with any value of the macColormap enum.
     */
    return index++;
}

int
XFreeColormap(
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Colormap))		/* Colormap. */
{
    return Success;
}

int
XFreeColors(
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Colormap),		/* Colormap. */
    TCL_UNUSED(unsigned long *),	/* Array of pixels. */
    TCL_UNUSED(int),		/* Number of pixels. */
    TCL_UNUSED(unsigned long))	/* Number of pixel planes. */
{
    /*

     * Nothing needs to be done to release colors as there really is no
     * colormap in the Tk sense.
     */
    return Success;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|









|
|
|
|

|


|
<






|
|






|
|
|
|
|


>
|
|












672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
 *
 *----------------------------------------------------------------------
 */

Status
XAllocColor(
    Display *display,		/* Display. */
    Colormap map,		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    display->request++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    Display *display,		/* Display. */
    Window window,		/* X window. */
    Visual *visual,		/* Not used. */
    int alloc)			/* Not used. */
{
    static Colormap index = 1;

    /*
     * Just return a new value each time.

     */
    return index++;
}

int
XFreeColormap(
    Display* display,		/* Display. */
    Colormap colormap)		/* Colormap. */
{
    return Success;
}

int
XFreeColors(
    Display* display,		/* Display. */
    Colormap colormap,		/* Colormap. */
    unsigned long* pixels,	/* Array of pixels. */
    int npixels,		/* Number of pixels. */
    unsigned long planes)	/* Number of pixel planes. */
{
    /*
     * The Macintosh version of Tk uses TrueColor. Nothing
     * needs to be done to release colors as there really is
     * no colormap in the Tk sense.
     */
    return Success;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Deleted macosx/tkMacOSXColor.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#ifndef MACOSXCOLOR_H
#define MACOSXCOLOR_H
/*
 * The generic Tk code uses the X11 GC type to describe a graphics context.
 * (A GC is a pointer to a struct XGCValues).  The foreground and background
 * colors in a GC are unsigned longs.  These are meant to be used as indexes
 * into a table of XColors, where an XColor is declared in Xlib.h as:
 * typedef struct {
 *       unsigned long pixel;
 *       unsigned short red, green, blue;
 *       char flags;
 *       char pad;
 * } XColor;
 *
 * The xlib function XParseColor creates XColors from strings.  It recognizes
 * literal hexadecimal color specifications such as "#RRGGBB" as well as the
 * standard X11 color names.  When XParseColor creates an XColor it fills in
 * all of the fields except for the pixel field, and then passes the XColor
 * to TkpGetPixel to get a value to use for the pixel field. Since TkpGetPixel
 * is platform specific, each platform is free to choose a value which can
 * be used to set the foreground or background color in the platform's graphics
 * context.
 *
 * Tk represents a color by a struct TkColor, which extends the XColor struct.
 * Tk provides a mapping from color names to TkColors which extends the mapping
 * provided by XParseColor but also allows for platform specific color names.
 * By convention, these platform specific color names begin with the string
 * "system".  The mapping from names to TkColors is implemented by the function
 * TkpGetColor defined for the Macintosh in this file.  The pixel field in the
 * XColor contained in a TkColor will be stored in the X11 graphics context.
 * In X11 the pixel field is used as an index into a colormap.  On the Mac
 * the high order byte of the pixel is used to indicate a color type and
 * the low 24 bits are either used as an rgb value (if the type is rgbColor)
 * or as an index into a table of color descriptions.
 */

enum colorType {
    rgbColor,      /* The 24 bit value is an rgb color. */
    clearColor,    /* The unique rgba color with all channels 0. */
    HIBrush,       /* A HITheme brush color.*/
    ttkBackground, /* A background color which indicates nesting level.*/
    semantic,      /* A semantic NSColor.*/
};

typedef struct xpixel_t {
    unsigned value: 24;     /* Either RGB or an index into systemColorData. */
    unsigned colortype: 8;
} xpixel;

typedef union MacPixel_t {
    unsigned long ulong;
    xpixel pixel;
} MacPixel;

/*
 * We maintain two colormaps, one for the LightAqua appearance and one for the
 * DarkAqua appearance.
 */

enum macColormap {
    noColormap,
    lightColormap,
    darkColormap,
};

/*
 * In TkMacOSXColor.c a Tk hash table is constructed from the static data
 * below to map system color names to CGColors.
 */

typedef struct {
    const char *name;
    enum colorType type;
    int value;
    const char *macName;
    /* Fields below are filled in after or during construction of the hash table. */
    int index;
    NSString *selector;
} SystemColorDatum;

/*
 * WARNING: Semantic colors which are not supported on all systems must be
 * preceded by a backup color with the same name which *is* supported.  Systems
 * which do support the color will replace the backup value when the table is
 * constructed.  Failing to ensure this will result in a Tcl_Panic abort.
 */

static SystemColorDatum systemColorData[] = {
{"Pixel",				rgbColor, 0, NULL, 0, NULL },
{"Transparent",				clearColor,   0, NULL, 0, NULL },

{"Highlight",				HIBrush,  kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
{"HighlightSecondary",		    	HIBrush,  kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
{"HighlightText",			HIBrush,  kThemeBrushBlack, NULL, 0, NULL },
{"HighlightAlternate",			HIBrush,  kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
{"PrimaryHighlightColor",		HIBrush,  kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
{"ButtonFace",				HIBrush,  kThemeBrushButtonFaceActive, NULL, 0, NULL },
{"SecondaryHighlightColor",		HIBrush,  kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
{"ButtonFrame",				HIBrush,  kThemeBrushButtonFrameActive, NULL, 0, NULL },
{"AlternatePrimaryHighlightColor",      HIBrush,  kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
{"WindowBody",				HIBrush,  kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
{"SheetBackground",			HIBrush,  kThemeBrushSheetBackground, NULL, 0, NULL },
{"MenuActive",				HIBrush,  kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
{"Menu",				HIBrush,  kThemeBrushMenuBackground, NULL, 0, NULL },
{"DialogBackgroundInactive",		HIBrush,  kThemeBrushDialogBackgroundInactive, NULL, 0, NULL },
{"DialogBackgroundActive",		HIBrush,  kThemeBrushDialogBackgroundActive, NULL, 0, NULL },
{"AlertBackgroundActive",		HIBrush,  kThemeBrushAlertBackgroundActive, NULL, 0, NULL },
{"AlertBackgroundInactive",		HIBrush,  kThemeBrushAlertBackgroundInactive, NULL, 0, NULL },
{"ModelessDialogBackgroundActive",	HIBrush,  kThemeBrushModelessDialogBackgroundActive, NULL, 0, NULL },
{"ModelessDialogBackgroundInactive",	HIBrush,  kThemeBrushModelessDialogBackgroundInactive, NULL, 0, NULL },
{"UtilityWindowBackgroundActive",	HIBrush,  kThemeBrushUtilityWindowBackgroundActive, NULL, 0, NULL },
{"UtilityWindowBackgroundInactive",	HIBrush,  kThemeBrushUtilityWindowBackgroundInactive, NULL, 0, NULL },
{"ListViewSortColumnBackground",	HIBrush,  kThemeBrushListViewSortColumnBackground, NULL, 0, NULL },
{"ListViewBackground",			HIBrush,  kThemeBrushListViewBackground, NULL, 0, NULL },
{"IconLabelBackground",			HIBrush,  kThemeBrushIconLabelBackground, NULL, 0, NULL },
{"ListViewSeparator",			HIBrush,  kThemeBrushListViewSeparator, NULL, 0, NULL },
{"ChasingArrows",			HIBrush,  kThemeBrushChasingArrows, NULL, 0, NULL },
{"DragHilite",				HIBrush,  kThemeBrushDragHilite, NULL, 0, NULL },
{"DocumentWindowBackground",		HIBrush,  kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
{"FinderWindowBackground",		HIBrush,  kThemeBrushFinderWindowBackground, NULL, 0, NULL },
{"ScrollBarDelimiterActive",		HIBrush,  kThemeBrushScrollBarDelimiterActive, NULL, 0, NULL },
{"ScrollBarDelimiterInactive",		HIBrush,  kThemeBrushScrollBarDelimiterInactive, NULL, 0, NULL },
{"FocusHighlight",			HIBrush,  kThemeBrushFocusHighlight, NULL, 0, NULL },
{"PopupArrowActive",			HIBrush,  kThemeBrushPopupArrowActive, NULL, 0, NULL },
{"PopupArrowPressed",			HIBrush,  kThemeBrushPopupArrowPressed, NULL, 0, NULL },
{"PopupArrowInactive",			HIBrush,  kThemeBrushPopupArrowInactive, NULL, 0, NULL },
{"AppleGuideCoachmark",			HIBrush,  kThemeBrushAppleGuideCoachmark, NULL, 0, NULL },
{"IconLabelBackgroundSelected",		HIBrush,  kThemeBrushIconLabelBackgroundSelected, NULL, 0, NULL },
{"StaticAreaFill",			HIBrush,  kThemeBrushStaticAreaFill, NULL, 0, NULL },
{"ActiveAreaFill",			HIBrush,  kThemeBrushActiveAreaFill, NULL, 0, NULL },
{"ButtonFrameActive",			HIBrush,  kThemeBrushButtonFrameActive, NULL, 0, NULL },
{"ButtonFrameInactive",			HIBrush,  kThemeBrushButtonFrameInactive, NULL, 0, NULL },
{"ButtonFaceActive",			HIBrush,  kThemeBrushButtonFaceActive, NULL, 0, NULL },
{"ButtonFaceInactive",			HIBrush,  kThemeBrushButtonFaceInactive, NULL, 0, NULL },
{"ButtonFacePressed",			HIBrush,  kThemeBrushButtonFacePressed, NULL, 0, NULL },
{"ButtonActiveDarkShadow",		HIBrush,  kThemeBrushButtonActiveDarkShadow, NULL, 0, NULL },
{"ButtonActiveDarkHighlight",		HIBrush,  kThemeBrushButtonActiveDarkHighlight, NULL, 0, NULL },
{"ButtonActiveLightShadow",		HIBrush,  kThemeBrushButtonActiveLightShadow, NULL, 0, NULL },
{"ButtonActiveLightHighlight",		HIBrush,  kThemeBrushButtonActiveLightHighlight, NULL, 0, NULL },
{"ButtonInactiveDarkShadow",		HIBrush,  kThemeBrushButtonInactiveDarkShadow, NULL, 0, NULL },
{"ButtonInactiveDarkHighlight",		HIBrush,  kThemeBrushButtonInactiveDarkHighlight, NULL, 0, NULL },
{"ButtonInactiveLightShadow",		HIBrush,  kThemeBrushButtonInactiveLightShadow, NULL, 0, NULL },
{"ButtonInactiveLightHighlight",	HIBrush,  kThemeBrushButtonInactiveLightHighlight, NULL, 0, NULL },
{"ButtonPressedDarkShadow",		HIBrush,  kThemeBrushButtonPressedDarkShadow, NULL, 0, NULL },
{"ButtonPressedDarkHighlight",		HIBrush,  kThemeBrushButtonPressedDarkHighlight, NULL, 0, NULL },
{"ButtonPressedLightShadow",		HIBrush,  kThemeBrushButtonPressedLightShadow, NULL, 0, NULL },
{"ButtonPressedLightHighlight",		HIBrush,  kThemeBrushButtonPressedLightHighlight, NULL, 0, NULL },
{"BevelActiveLight",			HIBrush,  kThemeBrushBevelActiveLight, NULL, 0, NULL },
{"BevelActiveDark",			HIBrush,  kThemeBrushBevelActiveDark, NULL, 0, NULL },
{"BevelInactiveLight",			HIBrush,  kThemeBrushBevelInactiveLight, NULL, 0, NULL },
{"BevelInactiveDark",			HIBrush,  kThemeBrushBevelInactiveDark, NULL, 0, NULL },
{"NotificationWindowBackground",	HIBrush,  kThemeBrushNotificationWindowBackground, NULL, 0, NULL },
{"MovableModalBackground",		HIBrush,  kThemeBrushMovableModalBackground, NULL, 0, NULL },
{"SheetBackgroundOpaque",		HIBrush,  kThemeBrushSheetBackgroundOpaque, NULL, 0, NULL },
{"DrawerBackground",			HIBrush,  kThemeBrushDrawerBackground, NULL, 0, NULL },
{"ToolbarBackground",			HIBrush,  kThemeBrushToolbarBackground, NULL, 0, NULL },
{"SheetBackgroundTransparent",		HIBrush,  kThemeBrushSheetBackgroundTransparent, NULL, 0, NULL },
{"MenuBackground",			HIBrush,  kThemeBrushMenuBackground, NULL, 0, NULL },
{"MenuBackgroundSelected",		HIBrush,  kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
{"ListViewOddRowBackground",		HIBrush,  kThemeBrushListViewOddRowBackground, NULL, 0, NULL },
{"ListViewEvenRowBackground",		HIBrush,  kThemeBrushListViewEvenRowBackground, NULL, 0, NULL },
{"ListViewColumnDivider",		HIBrush,  kThemeBrushListViewColumnDivider, NULL, 0, NULL },

    /*
     * Dynamic Colors
     */

{"WindowBackgroundColor",	    ttkBackground, 0, NULL, 0, NULL },
{"WindowBackgroundColor1",	    ttkBackground, 1, NULL, 0, NULL },
{"WindowBackgroundColor2",	    ttkBackground, 2, NULL, 0, NULL },
{"WindowBackgroundColor3",	    ttkBackground, 3, NULL, 0, NULL },
{"WindowBackgroundColor4",	    ttkBackground, 4, NULL, 0, NULL },
{"WindowBackgroundColor5",	    ttkBackground, 5, NULL, 0, NULL },
{"WindowBackgroundColor6",	    ttkBackground, 6, NULL, 0, NULL },
{"WindowBackgroundColor7",	    ttkBackground, 7, NULL, 0, NULL },
/* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */
{"SecondaryLabelColor",		    ttkBackground, 14, NULL, 0, NULL },
/* Color to use for notebook tab labels -- depends on OS version. */
{"SelectedTabTextColor",	    semantic, 0, "textColor", 0, NULL },
/* Semantic colors that we simulate on older systems which don't supoort them. */
{"SelectedMenuItemTextColor",       semantic, 0, "selectedMenuItemTextColor", 0, NULL },
{"ControlAccentColor",		    semantic, 0, "controlAccentColor", 0, NULL },
{"LabelColor",                      semantic, 0, "blackColor", 0, NULL },
{"LinkColor",			    semantic, 0, "blueColor", 0, NULL },
{"PlaceholderTextColor",	    semantic, 0, "grayColor", 0, NULL },
{"SeparatorColor",		    semantic, 0, "grayColor", 0, NULL },
{NULL,				    0, 0, NULL, 0, NULL }
};

#endif
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































Changes to macosx/tkMacOSXConfig.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,			/* A window to use. */
    const char *dbName,			/* The option database name. */
    const char *className)		/* The name of the option class. */
{
    (void)tkwin;
    (void)dbName;
    (void)className;

    return NULL;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







<
<
<
<


<
<
<
<
<
<
<
<
<
35
36
37
38
39
40
41




42
43










Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,			/* A window to use. */
    const char *dbName,			/* The option database name. */
    const char *className)		/* The name of the option class. */
{




    return NULL;
}









Deleted macosx/tkMacOSXConstants.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * tkMacOSXConstants.h --
 *
 *	Macros which map the names of NS constants used in the Tk code to
 *      the new name that Apple came up with for subsequent versions of the
 *      operating system.  (Each new OS release seems to come with a new
 *      naming convention for the same old constants.)
 *
 * Copyright (c) 2017 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
#define NSFullScreenWindowMask (1 << 14)
#endif

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
typedef NSInteger NSModalResponse;
#endif

/*
 * Let's raise a glass for the project manager who improves our lives by
 * generating deprecation warnings about pointless changes of the names
 * of constants.
 */

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
#define kCTFontDefaultOrientation kCTFontOrientationDefault
#define kCTFontVerticalOrientation kCTFontOrientationVertical
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define NSOKButton NSModalResponseOK
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
#define kCTFontUserFixedPitchFontType kCTFontUIFontUserFixedPitch
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define NSAppKitDefined NSEventTypeAppKitDefined
#define NSApplicationDefined NSEventTypeApplicationDefined
#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
#define NSWindowExposedEventType NSEventSubtypeWindowExposed
#define NSScreenChangedEventType NSEventSubtypeScreenChanged
#define NSWindowMovedEventType NSEventSubtypeWindowMoved
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
#define NSFlagsChanged NSEventTypeFlagsChanged
#define NSLeftMouseDown NSEventTypeLeftMouseDown
#define NSLeftMouseUp NSEventTypeLeftMouseUp
#define NSRightMouseDown NSEventTypeRightMouseDown
#define NSRightMouseUp NSEventTypeRightMouseUp
#define NSLeftMouseDragged NSEventTypeLeftMouseDragged
#define NSRightMouseDragged NSEventTypeRightMouseDragged
#define NSMouseMoved NSEventTypeMouseMoved
#define NSMouseEntered NSEventTypeMouseEntered
#define NSMouseExited NSEventTypeMouseExited
#define NSScrollWheel NSEventTypeScrollWheel
#define NSOtherMouseDown NSEventTypeOtherMouseDown
#define NSOtherMouseUp NSEventTypeOtherMouseUp
#define NSOtherMouseDragged NSEventTypeOtherMouseDragged
#define NSTabletPoint NSEventTypeTabletPoint
#define NSTabletProximity NSEventTypeTabletProximity
#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask
#define NSCommandKeyMask NSEventModifierFlagCommand
#define NSShiftKeyMask NSEventModifierFlagShift
#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
#define NSAlternateKeyMask NSEventModifierFlagOption
#define NSControlKeyMask NSEventModifierFlagControl
#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSCursorUpdate NSEventTypeCursorUpdate
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSCompositeCopy NSCompositingOperationCopy
#define NSWarningAlertStyle NSAlertStyleWarning
#define NSInformationalAlertStyle NSAlertStyleInformational
#define NSCriticalAlertStyle NSAlertStyleCritical
#define NSCenterTextAlignment NSTextAlignmentCenter
#define NSAnyEventMask NSEventMaskAny
#define NSApplicationDefinedMask NSEventMaskApplicationDefined
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
#define NSWindowStyleMaskTexturedBackground 0
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext		\
	    graphicsContextWithGraphicsPort:context flipped:flip]
#else
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext		\
	    graphicsContextWithCGContext:context flipped:NO]
#endif

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































Changes to macosx/tkMacOSXCursor.c.

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189









190
191
192
193
194
195
196
    NSPoint hotspot;
};

#define MacCursorData(n)	((id)tkMacOSXCursors[TK_MAC_CURSOR_##n])
#define MacXCursorData(n)	((id)tkMacOSXXCursors[TK_MAC_XCURSOR_##n])

static const struct CursorName cursorNames[] = {
    {"none",			NONE,	    nil, nil, {0, 0}},
    {"arrow",			SELECTOR,    @"arrowCursor", nil, {0, 0}},
    {"top_left_arrow",		SELECTOR,    @"arrowCursor", nil, {0, 0}},
    {"left_ptr",		SELECTOR,    @"arrowCursor", nil, {0, 0}},
    {"copyarrow",		SELECTOR,    @"dragCopyCursor", @"_copyDragCursor", {0, 0}},
    {"aliasarrow",		SELECTOR,    @"dragLinkCursor", @"_linkDragCursor", {0, 0}},
    {"contextualmenuarrow",	SELECTOR,    @"contextualMenuCursor", nil, {0, 0}},
    {"movearrow",		SELECTOR,    @"_moveCursor", nil, {0, 0}},
    {"ibeam",			SELECTOR,    @"IBeamCursor", nil, {0, 0}},
    {"text",			SELECTOR,    @"IBeamCursor", nil, {0, 0}},
    {"xterm",			SELECTOR,    @"IBeamCursor", nil, {0, 0}},
    {"cross",			SELECTOR,    @"crosshairCursor", nil, {0, 0}},
    {"crosshair",		SELECTOR,    @"crosshairCursor", nil, {0, 0}},
    {"cross-hair",		SELECTOR,    @"crosshairCursor", nil, {0, 0}},
    {"tcross",			SELECTOR,    @"crosshairCursor", nil, {0, 0}},
    {"hand",			SELECTOR,    @"openHandCursor", nil, {0, 0}},
    {"openhand",		SELECTOR,    @"openHandCursor", nil, {0, 0}},
    {"closedhand",		SELECTOR,    @"closedHandCursor", nil, {0, 0}},
    {"fist",			SELECTOR,    @"closedHandCursor", nil, {0, 0}},
    {"pointinghand",		SELECTOR,    @"pointingHandCursor", nil, {0, 0}},
    {"resize",			SELECTOR,    @"arrowCursor", nil, {0, 0}},
    {"resizeleft",		SELECTOR,    @"resizeLeftCursor", nil, {0, 0}},
    {"resizeright",		SELECTOR,    @"resizeRightCursor", nil, {0, 0}},
    {"resizeleftright",		SELECTOR,    @"resizeLeftRightCursor", nil, {0, 0}},
    {"resizeup",		SELECTOR,    @"resizeUpCursor", nil, {0, 0}},
    {"resizedown",		SELECTOR,    @"resizeDownCursor", nil, {0, 0}},
    {"resizeupdown",		SELECTOR,    @"resizeUpDownCursor", nil, {0, 0}},
    {"resizebottomleft",	SELECTOR,    @"_bottomLeftResizeCursor", nil, {0, 0}},
    {"resizetopleft",		SELECTOR,    @"_topLeftResizeCursor", nil, {0, 0}},
    {"resizebottomright",	SELECTOR,    @"_bottomRightResizeCursor", nil, {0, 0}},
    {"resizetopright",		SELECTOR,    @"_topRightResizeCursor", nil, {0, 0}},
    {"notallowed",		SELECTOR,    @"operationNotAllowedCursor", nil, {0, 0}},
    {"poof",			SELECTOR,    @"disappearingItemCursor", nil, {0, 0}},
    {"wait",			SELECTOR,    @"busyButClickableCursor", nil, {0, 0}},
    {"spinning",		SELECTOR,    @"busyButClickableCursor", nil, {0, 0}},
    {"countinguphand",		SELECTOR,    @"busyButClickableCursor", nil, {0, 0}},
    {"countingdownhand",	SELECTOR,    @"busyButClickableCursor", nil, {0, 0}},
    {"countingupanddownhand",	SELECTOR,    @"busyButClickableCursor", nil, {0, 0}},
    {"help",			IMAGENAMED,  @"NSHelpCursor", nil, {8, 8}},
//  {"hand",			IMAGEBITMAP, MacCursorData(hand), nil, {0, 0}},
    {"bucket",			IMAGEBITMAP, MacCursorData(bucket), nil, {0, 0}},
    {"cancel",			IMAGEBITMAP, MacCursorData(cancel), nil, {0, 0}},
//  {"resize",			IMAGEBITMAP, MacCursorData(resize), nil, {0, 0}},
    {"eyedrop",			IMAGEBITMAP, MacCursorData(eyedrop), nil, {0, 0}},
    {"eyedrop-full",		IMAGEBITMAP, MacCursorData(eyedrop_full), nil, {0, 0}},
    {"zoom-in",			IMAGEBITMAP, MacCursorData(zoom_in), nil, {0, 0}},
    {"zoom-out",		IMAGEBITMAP, MacCursorData(zoom_out), nil, {0, 0}},
    {"X_cursor",		IMAGEBITMAP, MacXCursorData(X_cursor), nil, {0, 0}},
//  {"arrow",			IMAGEBITMAP, MacXCursorData(arrow), nil, {0, 0}},
    {"based_arrow_down",	IMAGEBITMAP, MacXCursorData(based_arrow_down), nil, {0, 0}},
    {"based_arrow_up",		IMAGEBITMAP, MacXCursorData(based_arrow_up), nil, {0, 0}},
    {"boat",			IMAGEBITMAP, MacXCursorData(boat), nil, {0, 0}},
    {"bogosity",		IMAGEBITMAP, MacXCursorData(bogosity), nil, {0, 0}},
    {"bottom_left_corner",	IMAGEBITMAP, MacXCursorData(bottom_left_corner), nil, {0, 0}},
    {"bottom_right_corner",	IMAGEBITMAP, MacXCursorData(bottom_right_corner), nil, {0, 0}},
    {"bottom_side",		IMAGEBITMAP, MacXCursorData(bottom_side), nil, {0, 0}},
    {"bottom_tee",		IMAGEBITMAP, MacXCursorData(bottom_tee), nil, {0, 0}},
    {"box_spiral",		IMAGEBITMAP, MacXCursorData(box_spiral), nil, {0, 0}},
    {"center_ptr",		IMAGEBITMAP, MacXCursorData(center_ptr), nil, {0, 0}},
    {"circle",			IMAGEBITMAP, MacXCursorData(circle), nil, {0, 0}},
    {"clock",			IMAGEBITMAP, MacXCursorData(clock), nil, {0, 0}},
    {"coffee_mug",		IMAGEBITMAP, MacXCursorData(coffee_mug), nil, {0, 0}},
//  {"cross",			IMAGEBITMAP, MacXCursorData(cross), nil, {0, 0}},
    {"cross_reverse",		IMAGEBITMAP, MacXCursorData(cross_reverse), nil, {0, 0}},
//  {"crosshair",		IMAGEBITMAP, MacXCursorData(crosshair), nil, {0, 0}},
    {"diamond_cross",		IMAGEBITMAP, MacXCursorData(diamond_cross), nil, {0, 0}},
    {"dot",			IMAGEBITMAP, MacXCursorData(dot), nil, {0, 0}},
    {"dotbox",			IMAGEBITMAP, MacXCursorData(dotbox), nil, {0, 0}},
    {"double_arrow",		IMAGEBITMAP, MacXCursorData(double_arrow), nil, {0, 0}},
    {"draft_large",		IMAGEBITMAP, MacXCursorData(draft_large), nil, {0, 0}},
    {"draft_small",		IMAGEBITMAP, MacXCursorData(draft_small), nil, {0, 0}},
    {"draped_box",		IMAGEBITMAP, MacXCursorData(draped_box), nil, {0, 0}},
    {"exchange",		IMAGEBITMAP, MacXCursorData(exchange), nil, {0, 0}},
    {"fleur",			IMAGEBITMAP, MacXCursorData(fleur), nil, {0, 0}},
    {"gobbler",			IMAGEBITMAP, MacXCursorData(gobbler), nil, {0, 0}},
    {"gumby",			IMAGEBITMAP, MacXCursorData(gumby), nil, {0, 0}},
    {"hand1",			IMAGEBITMAP, MacXCursorData(hand1), nil, {0, 0}},
    {"hand2",			IMAGEBITMAP, MacXCursorData(hand2), nil, {0, 0}},
    {"heart",			IMAGEBITMAP, MacXCursorData(heart), nil, {0, 0}},
    {"icon",			IMAGEBITMAP, MacXCursorData(icon), nil, {0, 0}},
    {"iron_cross",		IMAGEBITMAP, MacXCursorData(iron_cross), nil, {0, 0}},
//  {"left_ptr",		IMAGEBITMAP, MacXCursorData(left_ptr), nil, {0, 0}},
    {"left_side",		IMAGEBITMAP, MacXCursorData(left_side), nil, {0, 0}},
    {"left_tee",		IMAGEBITMAP, MacXCursorData(left_tee), nil, {0, 0}},
    {"leftbutton",		IMAGEBITMAP, MacXCursorData(leftbutton), nil, {0, 0}},
    {"ll_angle",		IMAGEBITMAP, MacXCursorData(ll_angle), nil, {0, 0}},
    {"lr_angle",		IMAGEBITMAP, MacXCursorData(lr_angle), nil, {0, 0}},
    {"man",			IMAGEBITMAP, MacXCursorData(man), nil, {0, 0}},
    {"middlebutton",		IMAGEBITMAP, MacXCursorData(middlebutton), nil, {0, 0}},
    {"mouse",			IMAGEBITMAP, MacXCursorData(mouse), nil, {0, 0}},
    {"pencil",			IMAGEBITMAP, MacXCursorData(pencil), nil, {0, 0}},
    {"pirate",			IMAGEBITMAP, MacXCursorData(pirate), nil, {0, 0}},
    {"plus",			IMAGEBITMAP, MacXCursorData(plus), nil, {0, 0}},
    {"question_arrow",		IMAGEBITMAP, MacXCursorData(question_arrow), nil, {0, 0}},
    {"right_ptr",		IMAGEBITMAP, MacXCursorData(right_ptr), nil, {0, 0}},
    {"right_side",		IMAGEBITMAP, MacXCursorData(right_side), nil, {0, 0}},
    {"right_tee",		IMAGEBITMAP, MacXCursorData(right_tee), nil, {0, 0}},
    {"rightbutton",		IMAGEBITMAP, MacXCursorData(rightbutton), nil, {0, 0}},
    {"rtl_logo",		IMAGEBITMAP, MacXCursorData(rtl_logo), nil, {0, 0}},
    {"sailboat",		IMAGEBITMAP, MacXCursorData(sailboat), nil, {0, 0}},
    {"sb_down_arrow",		IMAGEBITMAP, MacXCursorData(sb_down_arrow), nil, {0, 0}},
    {"sb_h_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_h_double_arrow), nil, {0, 0}},
    {"sb_left_arrow",		IMAGEBITMAP, MacXCursorData(sb_left_arrow), nil, {0, 0}},
    {"sb_right_arrow",		IMAGEBITMAP, MacXCursorData(sb_right_arrow), nil, {0, 0}},
    {"sb_up_arrow",		IMAGEBITMAP, MacXCursorData(sb_up_arrow), nil, {0, 0}},
    {"sb_v_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_v_double_arrow), nil, {0, 0}},
    {"shuttle",			IMAGEBITMAP, MacXCursorData(shuttle), nil, {0, 0}},
    {"sizing",			IMAGEBITMAP, MacXCursorData(sizing), nil, {0, 0}},
    {"spider",			IMAGEBITMAP, MacXCursorData(spider), nil, {0, 0}},
    {"spraycan",		IMAGEBITMAP, MacXCursorData(spraycan), nil, {0, 0}},
    {"star",			IMAGEBITMAP, MacXCursorData(star), nil, {0, 0}},
    {"target",			IMAGEBITMAP, MacXCursorData(target), nil, {0, 0}},
//  {"tcross",			IMAGEBITMAP, MacXCursorData(tcross), nil, {0, 0}},
//  {"top_left_arrow",		IMAGEBITMAP, MacXCursorData(top_left_arrow), nil, {0, 0}},
    {"top_left_corner",		IMAGEBITMAP, MacXCursorData(top_left_corner), nil, {0, 0}},
    {"top_right_corner",	IMAGEBITMAP, MacXCursorData(top_right_corner), nil, {0, 0}},
    {"top_side",		IMAGEBITMAP, MacXCursorData(top_side), nil, {0, 0}},
    {"top_tee",			IMAGEBITMAP, MacXCursorData(top_tee), nil, {0, 0}},
    {"trek",			IMAGEBITMAP, MacXCursorData(trek), nil, {0, 0}},
    {"ul_angle",		IMAGEBITMAP, MacXCursorData(ul_angle), nil, {0, 0}},
    {"umbrella",		IMAGEBITMAP, MacXCursorData(umbrella), nil, {0, 0}},
    {"ur_angle",		IMAGEBITMAP, MacXCursorData(ur_angle), nil, {0, 0}},
    {"watch",			IMAGEBITMAP, MacXCursorData(watch), nil, {0, 0}},
//  {"xterm",			IMAGEBITMAP, MacXCursorData(xterm), nil, {0, 0}},
    {NULL, 0, nil, nil, {0, 0}}
};

/*
 * Declarations of static variables used in this file.
 */

static TkMacOSXCursor *gCurrentCursor = NULL;
				/* A pointer to the current cursor. */










/*
 * Declarations of procedures local to this file
 */

static void FindCursorByName(TkMacOSXCursor *macCursorPtr, const char *string);








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|

>
>
>
>
>
>
>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    NSPoint hotspot;
};

#define MacCursorData(n)	((id)tkMacOSXCursors[TK_MAC_CURSOR_##n])
#define MacXCursorData(n)	((id)tkMacOSXXCursors[TK_MAC_XCURSOR_##n])

static const struct CursorName cursorNames[] = {
    {"none",			NONE,	    nil},
    {"arrow",			SELECTOR,    @"arrowCursor"},
    {"top_left_arrow",		SELECTOR,    @"arrowCursor"},
    {"left_ptr",		SELECTOR,    @"arrowCursor"},
    {"copyarrow",		SELECTOR,    @"dragCopyCursor", @"_copyDragCursor"},
    {"aliasarrow",		SELECTOR,    @"dragLinkCursor", @"_linkDragCursor"},
    {"contextualmenuarrow",	SELECTOR,    @"contextualMenuCursor"},
    {"movearrow",		SELECTOR,    @"_moveCursor"},
    {"ibeam",			SELECTOR,    @"IBeamCursor"},
    {"text",			SELECTOR,    @"IBeamCursor"},
    {"xterm",			SELECTOR,    @"IBeamCursor"},
    {"cross",			SELECTOR,    @"crosshairCursor"},
    {"crosshair",		SELECTOR,    @"crosshairCursor"},
    {"cross-hair",		SELECTOR,    @"crosshairCursor"},
    {"tcross",			SELECTOR,    @"crosshairCursor"},
    {"hand",			SELECTOR,    @"openHandCursor"},
    {"openhand",		SELECTOR,    @"openHandCursor"},
    {"closedhand",		SELECTOR,    @"closedHandCursor"},
    {"fist",			SELECTOR,    @"closedHandCursor"},
    {"pointinghand",		SELECTOR,    @"pointingHandCursor"},
    {"resize",			SELECTOR,    @"arrowCursor"},
    {"resizeleft",		SELECTOR,    @"resizeLeftCursor"},
    {"resizeright",		SELECTOR,    @"resizeRightCursor"},
    {"resizeleftright",		SELECTOR,    @"resizeLeftRightCursor"},
    {"resizeup",		SELECTOR,    @"resizeUpCursor"},
    {"resizedown",		SELECTOR,    @"resizeDownCursor"},
    {"resizeupdown",		SELECTOR,    @"resizeUpDownCursor"},
    {"resizebottomleft",	SELECTOR,    @"_bottomLeftResizeCursor"},
    {"resizetopleft",		SELECTOR,    @"_topLeftResizeCursor"},
    {"resizebottomright",	SELECTOR,    @"_bottomRightResizeCursor"},
    {"resizetopright",		SELECTOR,    @"_topRightResizeCursor"},
    {"notallowed",		SELECTOR,    @"operationNotAllowedCursor"},
    {"poof",			SELECTOR,    @"disappearingItemCursor"},
    {"wait",			SELECTOR,    @"busyButClickableCursor"},
    {"spinning",		SELECTOR,    @"busyButClickableCursor"},
    {"countinguphand",		SELECTOR,    @"busyButClickableCursor"},
    {"countingdownhand",	SELECTOR,    @"busyButClickableCursor"},
    {"countingupanddownhand",	SELECTOR,    @"busyButClickableCursor"},
    {"help",			IMAGENAMED,  @"NSHelpCursor", nil, {8, 8}},
//  {"hand",			IMAGEBITMAP, MacCursorData(hand)},
    {"bucket",			IMAGEBITMAP, MacCursorData(bucket)},
    {"cancel",			IMAGEBITMAP, MacCursorData(cancel)},
//  {"resize",			IMAGEBITMAP, MacCursorData(resize)},
    {"eyedrop",			IMAGEBITMAP, MacCursorData(eyedrop)},
    {"eyedrop-full",		IMAGEBITMAP, MacCursorData(eyedrop_full)},
    {"zoom-in",			IMAGEBITMAP, MacCursorData(zoom_in)},
    {"zoom-out",		IMAGEBITMAP, MacCursorData(zoom_out)},
    {"X_cursor",		IMAGEBITMAP, MacXCursorData(X_cursor)},
//  {"arrow",			IMAGEBITMAP, MacXCursorData(arrow)},
    {"based_arrow_down",	IMAGEBITMAP, MacXCursorData(based_arrow_down)},
    {"based_arrow_up",		IMAGEBITMAP, MacXCursorData(based_arrow_up)},
    {"boat",			IMAGEBITMAP, MacXCursorData(boat)},
    {"bogosity",		IMAGEBITMAP, MacXCursorData(bogosity)},
    {"bottom_left_corner",	IMAGEBITMAP, MacXCursorData(bottom_left_corner)},
    {"bottom_right_corner",	IMAGEBITMAP, MacXCursorData(bottom_right_corner)},
    {"bottom_side",		IMAGEBITMAP, MacXCursorData(bottom_side)},
    {"bottom_tee",		IMAGEBITMAP, MacXCursorData(bottom_tee)},
    {"box_spiral",		IMAGEBITMAP, MacXCursorData(box_spiral)},
    {"center_ptr",		IMAGEBITMAP, MacXCursorData(center_ptr)},
    {"circle",			IMAGEBITMAP, MacXCursorData(circle)},
    {"clock",			IMAGEBITMAP, MacXCursorData(clock)},
    {"coffee_mug",		IMAGEBITMAP, MacXCursorData(coffee_mug)},
//  {"cross",			IMAGEBITMAP, MacXCursorData(cross)},
    {"cross_reverse",		IMAGEBITMAP, MacXCursorData(cross_reverse)},
//  {"crosshair",		IMAGEBITMAP, MacXCursorData(crosshair)},
    {"diamond_cross",		IMAGEBITMAP, MacXCursorData(diamond_cross)},
    {"dot",			IMAGEBITMAP, MacXCursorData(dot)},
    {"dotbox",			IMAGEBITMAP, MacXCursorData(dotbox)},
    {"double_arrow",		IMAGEBITMAP, MacXCursorData(double_arrow)},
    {"draft_large",		IMAGEBITMAP, MacXCursorData(draft_large)},
    {"draft_small",		IMAGEBITMAP, MacXCursorData(draft_small)},
    {"draped_box",		IMAGEBITMAP, MacXCursorData(draped_box)},
    {"exchange",		IMAGEBITMAP, MacXCursorData(exchange)},
    {"fleur",			IMAGEBITMAP, MacXCursorData(fleur)},
    {"gobbler",			IMAGEBITMAP, MacXCursorData(gobbler)},
    {"gumby",			IMAGEBITMAP, MacXCursorData(gumby)},
    {"hand1",			IMAGEBITMAP, MacXCursorData(hand1)},
    {"hand2",			IMAGEBITMAP, MacXCursorData(hand2)},
    {"heart",			IMAGEBITMAP, MacXCursorData(heart)},
    {"icon",			IMAGEBITMAP, MacXCursorData(icon)},
    {"iron_cross",		IMAGEBITMAP, MacXCursorData(iron_cross)},
//  {"left_ptr",		IMAGEBITMAP, MacXCursorData(left_ptr)},
    {"left_side",		IMAGEBITMAP, MacXCursorData(left_side)},
    {"left_tee",		IMAGEBITMAP, MacXCursorData(left_tee)},
    {"leftbutton",		IMAGEBITMAP, MacXCursorData(leftbutton)},
    {"ll_angle",		IMAGEBITMAP, MacXCursorData(ll_angle)},
    {"lr_angle",		IMAGEBITMAP, MacXCursorData(lr_angle)},
    {"man",			IMAGEBITMAP, MacXCursorData(man)},
    {"middlebutton",		IMAGEBITMAP, MacXCursorData(middlebutton)},
    {"mouse",			IMAGEBITMAP, MacXCursorData(mouse)},
    {"pencil",			IMAGEBITMAP, MacXCursorData(pencil)},
    {"pirate",			IMAGEBITMAP, MacXCursorData(pirate)},
    {"plus",			IMAGEBITMAP, MacXCursorData(plus)},
    {"question_arrow",		IMAGEBITMAP, MacXCursorData(question_arrow)},
    {"right_ptr",		IMAGEBITMAP, MacXCursorData(right_ptr)},
    {"right_side",		IMAGEBITMAP, MacXCursorData(right_side)},
    {"right_tee",		IMAGEBITMAP, MacXCursorData(right_tee)},
    {"rightbutton",		IMAGEBITMAP, MacXCursorData(rightbutton)},
    {"rtl_logo",		IMAGEBITMAP, MacXCursorData(rtl_logo)},
    {"sailboat",		IMAGEBITMAP, MacXCursorData(sailboat)},
    {"sb_down_arrow",		IMAGEBITMAP, MacXCursorData(sb_down_arrow)},
    {"sb_h_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_h_double_arrow)},
    {"sb_left_arrow",		IMAGEBITMAP, MacXCursorData(sb_left_arrow)},
    {"sb_right_arrow",		IMAGEBITMAP, MacXCursorData(sb_right_arrow)},
    {"sb_up_arrow",		IMAGEBITMAP, MacXCursorData(sb_up_arrow)},
    {"sb_v_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_v_double_arrow)},
    {"shuttle",			IMAGEBITMAP, MacXCursorData(shuttle)},
    {"sizing",			IMAGEBITMAP, MacXCursorData(sizing)},
    {"spider",			IMAGEBITMAP, MacXCursorData(spider)},
    {"spraycan",		IMAGEBITMAP, MacXCursorData(spraycan)},
    {"star",			IMAGEBITMAP, MacXCursorData(star)},
    {"target",			IMAGEBITMAP, MacXCursorData(target)},
//  {"tcross",			IMAGEBITMAP, MacXCursorData(tcross)},
//  {"top_left_arrow",		IMAGEBITMAP, MacXCursorData(top_left_arrow)},
    {"top_left_corner",		IMAGEBITMAP, MacXCursorData(top_left_corner)},
    {"top_right_corner",	IMAGEBITMAP, MacXCursorData(top_right_corner)},
    {"top_side",		IMAGEBITMAP, MacXCursorData(top_side)},
    {"top_tee",			IMAGEBITMAP, MacXCursorData(top_tee)},
    {"trek",			IMAGEBITMAP, MacXCursorData(trek)},
    {"ul_angle",		IMAGEBITMAP, MacXCursorData(ul_angle)},
    {"umbrella",		IMAGEBITMAP, MacXCursorData(umbrella)},
    {"ur_angle",		IMAGEBITMAP, MacXCursorData(ur_angle)},
    {"watch",			IMAGEBITMAP, MacXCursorData(watch)},
//  {"xterm",			IMAGEBITMAP, MacXCursorData(xterm)},
    {NULL}
};

/*
 * Declarations of static variables used in this file.
 */

static TkMacOSXCursor * gCurrentCursor = NULL;
				/* A pointer to the current cursor. */
static int gResizeOverride = false;
				/* A boolean indicating whether we should use
				 * the resize cursor during installations. */
static int gTkOwnsCursor = true;/* A boolean indicating whether Tk owns the
				 * cursor. If not (for instance, in the case
				 * where a Tk window is embedded in another
				 * app's window, and the cursor is out of the
				 * tk window, we will not attempt to adjust
				 * the cursor. */

/*
 * Declarations of procedures local to this file
 */

static void FindCursorByName(TkMacOSXCursor *macCursorPtr, const char *string);

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
		NSBitmapImageRep *bitmapImageRep = NULL;
		CGImageRef img = NULL, mask = NULL, maskedImg = NULL;
		static const CGFloat decodeWB[] = {1, 0};
		CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(
			kCGColorSpaceGenericGray);
		CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
			bitmap, pix*pix/8, NULL);

		if (provider) {
		    img = CGImageCreate(pix, pix, 1, 1, pix/8, colorspace,
			    kCGBitmapByteOrderDefault, provider, decodeWB, 0,
			    kCGRenderingIntentDefault);
		    CFRelease(provider);
		}
		provider = CGDataProviderCreateWithData(NULL, bitmap +







<







274
275
276
277
278
279
280

281
282
283
284
285
286
287
		NSBitmapImageRep *bitmapImageRep = NULL;
		CGImageRef img = NULL, mask = NULL, maskedImg = NULL;
		static const CGFloat decodeWB[] = {1, 0};
		CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(
			kCGColorSpaceGenericGray);
		CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
			bitmap, pix*pix/8, NULL);

		if (provider) {
		    img = CGImageCreate(pix, pix, 1, 1, pix/8, colorspace,
			    kCGBitmapByteOrderDefault, provider, decodeWB, 0,
			    kCGRenderingIntentDefault);
		    CFRelease(provider);
		}
		provider = CGDataProviderCreateWithData(NULL, bitmap +
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
		    maskedImg = CGImageCreateWithMask(img, mask);
		}
		if (maskedImg) {
		    bitmapImageRep = [[NSBitmapImageRep alloc]
			    initWithCGImage:maskedImg];
		    CFRelease(maskedImg);
		}
		if (mask) {
		    CFRelease(mask);
		}
		if (img) {
		    CFRelease(img);
		}
		if (colorspace) {
		    CFRelease(colorspace);
		}
		if (bitmapImageRep) {
		    image = [[NSImage alloc] initWithSize:NSMakeSize(pix, pix)];
		    [image addRepresentation:bitmapImageRep];
		    [image setTemplate:YES];
		    [bitmapImageRep release];
		}

		uint16_t *hotSpotData = (uint16_t*)(bitmap + 2*pix*pix/8);
		hotSpot.y = CFSwapInt16BigToHost(*hotSpotData++);
		hotSpot.x = CFSwapInt16BigToHost(*hotSpotData);
		haveHotSpot = 1;
		break;
	    }
	    }







|
<
<
|
<
<
|
<
<



<


<







295
296
297
298
299
300
301
302


303


304


305
306
307

308
309

310
311
312
313
314
315
316
		    maskedImg = CGImageCreateWithMask(img, mask);
		}
		if (maskedImg) {
		    bitmapImageRep = [[NSBitmapImageRep alloc]
			    initWithCGImage:maskedImg];
		    CFRelease(maskedImg);
		}
		if (mask) { CFRelease(mask); }


		if (img)  { CFRelease(img); }


		if (colorspace) { CFRelease(colorspace); }


		if (bitmapImageRep) {
		    image = [[NSImage alloc] initWithSize:NSMakeSize(pix, pix)];
		    [image addRepresentation:bitmapImageRep];

		    [bitmapImageRep release];
		}

		uint16_t *hotSpotData = (uint16_t*)(bitmap + 2*pix*pix/8);
		hotSpot.y = CFSwapInt16BigToHost(*hotSpotData++);
		hotSpot.x = CFSwapInt16BigToHost(*hotSpotData);
		haveHotSpot = 1;
		break;
	    }
	    }
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkGetCursorByName(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry
				 * for details on legal syntax. */
{
    TkMacOSXCursor *macCursorPtr = NULL;
    const char **argv = NULL;
    int argc;

    /*
     * All cursor names are valid lists of one element (for
     * TkX11-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
	if (argc) {
	    macCursorPtr = (TkMacOSXCursor *)ckalloc(sizeof(TkMacOSXCursor));
	    macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr;
	    macCursorPtr->macCursor = nil;
	    macCursorPtr->type = 0;
	    FindCursorByName(macCursorPtr, argv[0]);
	}
	ckfree(argv);
    }
    if (!macCursorPtr || (!macCursorPtr->macCursor &&
	    macCursorPtr->type != NONE)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad cursor spec \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL);
	if (macCursorPtr) {
	    ckfree(macCursorPtr);
	    macCursorPtr = NULL;
	}
    }
    return (TkCursor *) macCursorPtr;
}

/*







|














|





|



<
|
<

|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393

394

395
396
397
398
399
400
401
402
403
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkGetCursorByName(
    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. */
{
    TkMacOSXCursor *macCursorPtr = NULL;
    const char **argv = NULL;
    int argc;

    /*
     * All cursor names are valid lists of one element (for
     * TkX11-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
	if (argc) {
	    macCursorPtr = (TkMacOSXCursor *) ckalloc(sizeof(TkMacOSXCursor));
	    macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr;
	    macCursorPtr->macCursor = nil;
	    macCursorPtr->type = 0;
	    FindCursorByName(macCursorPtr, argv[0]);
	}
	ckfree((char *) argv);
    }
    if (!macCursorPtr || (!macCursorPtr->macCursor &&
	    macCursorPtr->type != NONE)) {

	Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL);

	if (macCursorPtr) {
	    ckfree((char *)macCursorPtr);
	    macCursorPtr = NULL;
	}
    }
    return (TkCursor *) macCursorPtr;
}

/*
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
 *	Allocates a new cursor.
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    TCL_UNUSED(const char *),		/* Bitmap data for cursor shape. */
    TCL_UNUSED(const char *),		/* Bitmap data for cursor mask. */
    TCL_UNUSED(int),	/* Dimensions of cursor. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),		/* Location of hot-spot in cursor. */
    TCL_UNUSED(int),
    TCL_UNUSED(XColor),		/* Foreground color for cursor. */
    TCL_UNUSED(XColor))		/* Background color for cursor. */
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|
|
|
|
<
|
<
|
|







414
415
416
417
418
419
420
421
422
423
424

425

426
427
428
429
430
431
432
433
434
 *	Allocates a new cursor.
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    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. */

    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490


491
492
493
494
495
496
497
498
 *
 * Side effects:
 *	Changes the Macintosh mouse cursor.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXInstallCursor(
    void)
{
    TkMacOSXCursor *macCursorPtr = gCurrentCursor;
    static int cursorHidden = 0;
    int cursorNone = 0;



    if (!macCursorPtr) {
	[[NSCursor arrowCursor] set];
    } else {
	switch (macCursorPtr->type) {
	case NONE:
	    if (!cursorHidden) {
		cursorHidden = 1;
		[NSCursor hide];







|

|





>
>
|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 *
 * Side effects:
 *	Changes the Macintosh mouse cursor.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInstallCursor(
    int resizeOverride)
{
    TkMacOSXCursor *macCursorPtr = gCurrentCursor;
    static int cursorHidden = 0;
    int cursorNone = 0;

    gResizeOverride = resizeOverride;

    if (resizeOverride || !macCursorPtr) {
	[[NSCursor arrowCursor] set];
    } else {
	switch (macCursorPtr->type) {
	case NONE:
	    if (!cursorHidden) {
		cursorHidden = 1;
		[NSCursor hide];
531
532
533
534
535
536
537




538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559























560
561
562
563
564
565
566
567
568
 */

void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;





    if (cursor == None) {
	/*
	 * This is a little tricky. We can't really tell whether
	 * gCurrentCursor is NULL because it was NULL last time around or
	 * because we just freed the current cursor. So if the input cursor is
	 * NULL, we always need to reset it, we can't trust the cursorChanged
	 * logic.
	 */

	gCurrentCursor = NULL;
    } else {
	if (gCurrentCursor == (TkMacOSXCursor *) cursor) {
	    cursorChanged = 0;
	}
	gCurrentCursor = (TkMacOSXCursor *) cursor;
    }

    if (Tk_MacOSXIsAppInFront() && cursorChanged) {
	TkMacOSXInstallCursor();
    }
}
























/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>
>
>
>



















|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
 */

void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;

    if (!gTkOwnsCursor) {
	return;
    }

    if (cursor == None) {
	/*
	 * This is a little tricky. We can't really tell whether
	 * gCurrentCursor is NULL because it was NULL last time around or
	 * because we just freed the current cursor. So if the input cursor is
	 * NULL, we always need to reset it, we can't trust the cursorChanged
	 * logic.
	 */

	gCurrentCursor = NULL;
    } else {
	if (gCurrentCursor == (TkMacOSXCursor *) cursor) {
	    cursorChanged = 0;
	}
	gCurrentCursor = (TkMacOSXCursor *) cursor;
    }

    if (Tk_MacOSXIsAppInFront() && cursorChanged) {
	TkMacOSXInstallCursor(gResizeOverride);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXTkOwnsCursor --
 *
 *	Sets whether Tk has the right to adjust the cursor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May keep Tk from changing the cursor.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXTkOwnsCursor(
    int tkOwnsIt)
{
    gTkOwnsCursor = tkOwnsIt;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXDefault.h.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//#ifndef TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS 1
//#endif

/*
 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.
 * NORMAL_FG -		Normal foreground color.
 * ACTIVE_BG -		Background color when widget is active.
 * ACTIVE_FG -		Foreground color when widget is active.
 * SELECT_BG -		Background color for selected text.
 * SELECT_FG -		Foreground color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.
 */

#define BLACK			"Black"
#define WHITE			"White"
#define NORMAL_BG		"systemWindowBackgroundColor"
#define TEXT_BG                 "systemTextBackgroundColor"
#define NORMAL_FG		"systemTextColor"
#define ACTIVE_BG		"systemWindowBackgroundColor"
#define ACTIVE_FG		"systemTextColor"
#define SELECT_BG		"systemSelectedTextBackgroundColor"
#define SELECT_FG		"systemSelectedTextColor"
#define INACTIVE_SELECT_BG	"systemSelectedTextBackgroundColor"
#define TROUGH			"#c3c3c3"
#define INDICATOR		"#b03060"
#define DISABLED		"systemDisabledControlTextColor"

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_BUTTON_ACTIVE_BG_MONO	BLACK
#define DEF_BUTTON_ACTIVE_FG_COLOR	WHITE
#define DEF_CHKRAD_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_BUTTON_ACTIVE_FG_MONO	WHITE

#define DEF_BUTTON_BG_COLOR		NORMAL_BG
#define DEF_BUTTON_BG_MONO		WHITE
#define DEF_BUTTON_BITMAP		""
#define DEF_BUTTON_BORDER_WIDTH		"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_BUTTON_FG			NORMAL_FG
#define DEF_CHKRAD_FG			DEF_BUTTON_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		"systemButtonFrame"
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define DEF_BUTTON_HIGHLIGHT_WIDTH	"4"
//#define DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM	"1"
//#else
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
//#endif
#define DEF_BUTTON_IMAGE		NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS







<

<









|
<
<
|
|
|
|
|


|








|
|

>
|









|













|







19
20
21
22
23
24
25

26

27
28
29
30
31
32
33
34
35
36


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//#ifndef TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS 1
//#endif

/*
 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.

 * ACTIVE_BG -		Background color when widget is active.

 * SELECT_BG -		Background color for selected text.
 * SELECT_FG -		Foreground color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.
 */

#define BLACK			"Black"
#define WHITE			"White"
#define NORMAL_BG		"systemWindowBody"


#define ACTIVE_BG		"systemButtonFacePressed"
#define ACTIVE_FG		"systemPushButtonPressedText"
#define SELECT_BG		"systemHighlight"
#define SELECT_FG		NULL
#define INACTIVE_SELECT_BG	"systemHighlightSecondary"
#define TROUGH			"#c3c3c3"
#define INDICATOR		"#b03060"
#define DISABLED		"#a3a3a3"

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_BUTTON_ACTIVE_BG_MONO	BLACK
#define DEF_BUTTON_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_CHKRAD_ACTIVE_FG_COLOR	DEF_BUTTON_ACTIVE_FG_COLOR
#define DEF_BUTTON_ACTIVE_FG_MONO	WHITE
/* #define DEF_BUTTON_BG_COLOR	"systemButtonFace"*/
#define DEF_BUTTON_BG_COLOR		WHITE
#define DEF_BUTTON_BG_MONO		WHITE
#define DEF_BUTTON_BITMAP		""
#define DEF_BUTTON_BORDER_WIDTH		"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_BUTTON_FG			"systemButtonText"
#define DEF_CHKRAD_FG			DEF_BUTTON_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		"systemButtonFrame"
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define DEF_BUTTON_HIGHLIGHT_WIDTH	"4"
//#define DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM	"1"
//#else
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
//#endif
#define DEF_BUTTON_IMAGE		((char *) NULL)
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"flat"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"







|


|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"flat"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		((char *) NULL)
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		((char *) NULL)
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	SELECT_FG
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		NULL
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*







|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	SELECT_FG
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		((char *) NULL)
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
 */

#define MAC_OSX_FOCUS_WIDTH		3
#define MAC_OSX_ENTRY_BORDER		2
#define MAC_OSX_ENTRY_RELIEF		TK_RELIEF_SUNKEN
#define MAC_OSX_ENTRY_SELECT_RELIEF	TK_RELIEF_FLAT

#define DEF_ENTRY_BG_COLOR		TEXT_BG
#define DEF_ENTRY_BG_MONO		WHITE
#define DEF_ENTRY_BORDER_WIDTH		"2"
#define DEF_ENTRY_CURSOR		"xterm"
#define DEF_ENTRY_DISABLED_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_DISABLED_BG_MONO	WHITE
#define DEF_ENTRY_DISABLED_FG		DISABLED
#define DEF_ENTRY_EXPORT_SELECTION	"1"
#define DEF_ENTRY_FONT			"TkTextFont"
#define DEF_ENTRY_FG			NORMAL_FG
#define DEF_ENTRY_HIGHLIGHT_BG		NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT		BLACK

#define DEF_ENTRY_HIGHLIGHT_WIDTH	"3"
#define DEF_ENTRY_INSERT_BG		NORMAL_FG
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"1"
#define DEF_ENTRY_JUSTIFY		"left"
#define DEF_ENTRY_PLACEHOLDER		""
#define DEF_ENTRY_PLACEHOLDERFG		"systemPlaceholderTextColor"
#define DEF_ENTRY_READONLY_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"

#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"1"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	SELECT_FG
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			NULL
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		NULL
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG
#define DEF_FRAME_BG_IMAGE		NULL
#define DEF_FRAME_BG_MONO		WHITE
#define DEF_FRAME_BG_TILE		"0"
#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG







|








|


>

|




|
|
|
<



>







|

|








<

<







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

216

217
218
219
220
221
222
223
 */

#define MAC_OSX_FOCUS_WIDTH		3
#define MAC_OSX_ENTRY_BORDER		2
#define MAC_OSX_ENTRY_RELIEF		TK_RELIEF_SUNKEN
#define MAC_OSX_ENTRY_SELECT_RELIEF	TK_RELIEF_FLAT

#define DEF_ENTRY_BG_COLOR		NORMAL_BG
#define DEF_ENTRY_BG_MONO		WHITE
#define DEF_ENTRY_BORDER_WIDTH		"2"
#define DEF_ENTRY_CURSOR		"xterm"
#define DEF_ENTRY_DISABLED_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_DISABLED_BG_MONO	WHITE
#define DEF_ENTRY_DISABLED_FG		DISABLED
#define DEF_ENTRY_EXPORT_SELECTION	"1"
#define DEF_ENTRY_FONT			"TkTextFont"
#define DEF_ENTRY_FG			BLACK
#define DEF_ENTRY_HIGHLIGHT_BG		NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT		BLACK
/* #define DEF_ENTRY_HIGHLIGHT_WIDTH	"3" */
#define DEF_ENTRY_HIGHLIGHT_WIDTH	"3"
#define DEF_ENTRY_INSERT_BG		BLACK
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
/* #define DEF_ENTRY_INSERT_WIDTH		"2" */
#define DEF_ENTRY_INSERT_WIDTH		"1"
#define DEF_ENTRY_JUSTIFY		"left"

#define DEF_ENTRY_READONLY_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"
/* #define DEF_ENTRY_RELIEF		"solid" */
#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"1"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	SELECT_FG
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			((char *) NULL)
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		((char *) NULL)
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG

#define DEF_FRAME_BG_MONO		WHITE

#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332





333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
/*
 * Defaults for labelframes:
 */

#define DEF_LABELFRAME_BORDER_WIDTH	"2"
#define DEF_LABELFRAME_CLASS		"Labelframe"
#define DEF_LABELFRAME_RELIEF		"groove"
#define DEF_LABELFRAME_FG		NORMAL_FG
#define DEF_LABELFRAME_FONT		"TkDefaultFont"
#define DEF_LABELFRAME_TEXT		""
#define DEF_LABELFRAME_LABELANCHOR	"nw"

/*
 * Defaults for listboxes:
 */

#define DEF_LISTBOX_ACTIVE_STYLE	"dotbox"
#define DEF_LISTBOX_BG_COLOR		TEXT_BG
#define DEF_LISTBOX_BG_MONO		WHITE
#define DEF_LISTBOX_BORDER_WIDTH	"1"
#define DEF_LISTBOX_CURSOR		""
#define DEF_LISTBOX_DISABLED_FG		DISABLED
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkTextFont"
#define DEF_LISTBOX_FG			NORMAL_FG
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"0"
#define DEF_LISTBOX_JUSTIFY		"left"
#define DEF_LISTBOX_RELIEF		"solid"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		NULL
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	NULL
#define DEF_MENU_ENTRY_ACTIVE_FG	NULL
#define DEF_MENU_ENTRY_ACCELERATOR	NULL
#define DEF_MENU_ENTRY_BG		NULL
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		NULL
#define DEF_MENU_ENTRY_COMPOUND		"none"
#define DEF_MENU_ENTRY_FG		NULL
#define DEF_MENU_ENTRY_FONT		NULL
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		NULL
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		NULL
#define DEF_MENU_ENTRY_MENU		NULL
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	NORMAL_BG /*ignored*/
#define DEF_MENU_ACTIVE_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	NORMAL_FG
#define DEF_MENU_ACTIVE_FG_MONO		NORMAL_FG
#define DEF_MENU_ACTIVE_RELIEF		"flat"
#define DEF_MENU_BG_COLOR		NORMAL_BG /*ignored*/
#define DEF_MENU_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENU_BORDER_WIDTH		"0"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	DISABLED
#define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
#define DEF_MENU_FG			NORMAL_FG
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		"systemSelectedMenuItemTextColor"
#define DEF_MENU_SELECT_MONO		"systemSelectedMenuItemTextColor"
#define DEF_MENU_TAKE_FOCUS		"0"





#define DEF_MENU_TEAROFF		"0"
#define DEF_MENU_TEAROFF_CMD		NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */

#define DEF_MENUBUTTON_ANCHOR		"w"
#define DEF_MENUBUTTON_ACTIVE_BG_COLOR	NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_ACTIVE_BG_MONO	NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR	"systemTextColor"
#define DEF_MENUBUTTON_ACTIVE_FG_MONO	"systemTextColor"
#define DEF_MENUBUTTON_BG_COLOR		NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_BITMAP		""
#define DEF_MENUBUTTON_BORDER_WIDTH	"0"
#define DEF_MENUBUTTON_CURSOR		""
#define DEF_MENUBUTTON_DIRECTION	"below"
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO	""
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	NORMAL_BG
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"1"
#define DEF_MENUBUTTON_JUSTIFY		"left"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"0"
#define DEF_MENUBUTTON_PADY		"0"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""
#define DEF_MENUBUTTON_UNDERLINE	"-1"
#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			NORMAL_FG
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"







|









|






|




<











|






|
|
|
|


|

|
|

|

|
|


|

|
|

|






|
|

|
|
<
|
|


|
|

|


|
|

>
>
>
>
>

|







|
|
|
|
|
|
|

|





|



|

|



|
|



















|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
/*
 * Defaults for labelframes:
 */

#define DEF_LABELFRAME_BORDER_WIDTH	"2"
#define DEF_LABELFRAME_CLASS		"Labelframe"
#define DEF_LABELFRAME_RELIEF		"groove"
#define DEF_LABELFRAME_FG		"systemButtonText"
#define DEF_LABELFRAME_FONT		"TkDefaultFont"
#define DEF_LABELFRAME_TEXT		""
#define DEF_LABELFRAME_LABELANCHOR	"nw"

/*
 * Defaults for listboxes:
 */

#define DEF_LISTBOX_ACTIVE_STYLE	"dotbox"
#define DEF_LISTBOX_BG_COLOR		WHITE
#define DEF_LISTBOX_BG_MONO		WHITE
#define DEF_LISTBOX_BORDER_WIDTH	"1"
#define DEF_LISTBOX_CURSOR		""
#define DEF_LISTBOX_DISABLED_FG		DISABLED
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkTextFont"
#define DEF_LISTBOX_FG			BLACK
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"0"

#define DEF_LISTBOX_RELIEF		"solid"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		((char *) NULL)
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	((char *) NULL)
#define DEF_MENU_ENTRY_ACTIVE_FG	((char *) NULL)
#define DEF_MENU_ENTRY_ACCELERATOR	((char *) NULL)
#define DEF_MENU_ENTRY_BG		((char *) NULL)
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		((char *) NULL)
#define DEF_MENU_ENTRY_COMPOUND		"none"
#define DEF_MENU_ENTRY_FG		((char *) NULL)
#define DEF_MENU_ENTRY_FONT		((char *) NULL)
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		((char *) NULL)
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		((char *) NULL)
#define DEF_MENU_ENTRY_MENU		((char *) NULL)
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	((char *) NULL)
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		((char *) NULL)
#define DEF_MENU_ENTRY_CHECK_VARIABLE	((char *) NULL)
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		((char *) NULL)
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	"systemMenuActive"
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	"systemMenuActiveText"
#define DEF_MENU_ACTIVE_FG_MONO		WHITE

#define DEF_MENU_BG_COLOR		"systemMenu"
#define DEF_MENU_BG_MONO		WHITE
#define DEF_MENU_BORDER_WIDTH		"0"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	"systemMenuDisabled"
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
#define DEF_MENU_FG			"systemMenuText"
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		"systemMenuActive"
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_TAKE_FOCUS		"0"

/*
 * FIXME: Turn the default back to 1 when we make tearoff menus work again.
 */

#define DEF_MENU_TEAROFF		"0"
#define DEF_MENU_TEAROFF_CMD		((char *) NULL)
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */

#define DEF_MENUBUTTON_ANCHOR		"center"
#define DEF_MENUBUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENUBUTTON_ACTIVE_BG_MONO	BLACK
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_MENUBUTTON_ACTIVE_FG_MONO	WHITE
#define DEF_MENUBUTTON_BG_COLOR		NORMAL_BG
#define DEF_MENUBUTTON_BG_MONO		WHITE
#define DEF_MENUBUTTON_BITMAP		""
#define DEF_MENUBUTTON_BORDER_WIDTH	"2"
#define DEF_MENUBUTTON_CURSOR		""
#define DEF_MENUBUTTON_DIRECTION	"below"
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO	""
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		BLACK
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	BLACK
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		((char *) NULL)
#define DEF_MENUBUTTON_INDICATOR	"1"
#define DEF_MENUBUTTON_JUSTIFY		"left"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"4"
#define DEF_MENUBUTTON_PADY		"3"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""
#define DEF_MENUBUTTON_UNDERLINE	"-1"
#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			BLACK
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		NORMAL_FG
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"0"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:







|



















|







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		BLACK
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"0"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		((char *) NULL)
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"flat"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	NULL
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"15"

/*
 * Defaults for texts:
 */

#define DEF_TEXT_AUTO_SEPARATORS	"1"
#define DEF_TEXT_BG_COLOR		TEXT_BG
#define DEF_TEXT_BG_MONO		WHITE
#define DEF_TEXT_BLOCK_CURSOR		"0"
#define DEF_TEXT_BORDER_WIDTH		"0"
#define DEF_TEXT_CURSOR			"xterm"
#define DEF_TEXT_FG			NORMAL_FG
#define DEF_TEXT_EXPORT_SELECTION	"1"
#define DEF_TEXT_FONT			"TkFixedFont"
#define DEF_TEXT_HEIGHT			"24"
#define DEF_TEXT_HIGHLIGHT_BG		NORMAL_BG
#define DEF_TEXT_HIGHLIGHT		BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH	"3"
#define DEF_TEXT_INSERT_BG		NORMAL_FG
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"1"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"flat"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	INACTIVE_SELECT_BG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"1"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		NULL
#define DEF_TEXT_UNDO			"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"

/*
 * Defaults for canvas items
 * (arcs, bitmaps, lines, polygons, rectangles, and ovals):
 */

#define DEF_CANVBMAP_FG			NORMAL_FG
#define DEF_CANVITEM_OUTLINE		NORMAL_FG

/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""

/*
 * Defaults for busy windows (not really used yet):
 */

#define DEF_BUSY_CURSOR			"watch"

#endif /* _TKMACDEFAULT */







|









|




|






|




<




















|












<
<
<
<
<
<
<
<










<
<
<
<
<
<

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556








557
558
559
560
561
562
563
564
565
566






567
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"flat"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	((char *) NULL)
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"15"

/*
 * Defaults for texts:
 */

#define DEF_TEXT_AUTO_SEPARATORS	"1"
#define DEF_TEXT_BG_COLOR		NORMAL_BG
#define DEF_TEXT_BG_MONO		WHITE
#define DEF_TEXT_BLOCK_CURSOR		"0"
#define DEF_TEXT_BORDER_WIDTH		"0"
#define DEF_TEXT_CURSOR			"xterm"
#define DEF_TEXT_FG			BLACK
#define DEF_TEXT_EXPORT_SELECTION	"1"
#define DEF_TEXT_FONT			"TkFixedFont"
#define DEF_TEXT_HEIGHT			"24"
#define DEF_TEXT_HIGHLIGHT_BG		NORMAL_BG
#define DEF_TEXT_HIGHLIGHT		BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH	"3"
#define DEF_TEXT_INSERT_BG		BLACK
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"

#define DEF_TEXT_INSERT_WIDTH		"1"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"flat"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	INACTIVE_SELECT_BG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"1"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		((char *) NULL)
#define DEF_TEXT_UNDO			"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"









/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""







#endif /* _TKMACDEFAULT */

Changes to macosx/tkMacOSXDialog.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * tkMacOSXDialog.c --
 *
 *	Contains the Mac implementation of the common dialog boxes.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2017 Christian Gollwitzer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
#include "tkMacOSXConstants.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOther  -1 // indicates that the -command option was used. 
#define modalError  -2

/*
 * Vars for filtering in "open file" and "save file" dialogs.
 */

typedef struct {
    bool doFileTypes;			/* Show the accessory view which
					 * displays the filter menu */
    bool preselectFilter;		/* A filter was selected by the
					 * typevariable. */
    bool userHasSelectedFilter;		/* The user has changed the filter in
					 * the accessory view. */
    NSMutableArray *fileTypeNames;	/* Array of names, e.g. "Text
					 * document". */
    NSMutableArray *fileTypeExtensions;	/* Array of allowed extensions per
					 * name, e.g. "txt", "doc". */
    NSMutableArray *fileTypeLabels;	/* Displayed string, e.g. "Text
					 * document (.txt, .doc)". */
    NSMutableArray *fileTypeAllowsAll;	/* Boolean if the all pattern (*.*) is
					 * included. */
    NSMutableArray *allowedExtensions;	/* Set of all allowed extensions. */
    bool allowedExtensionsAllowAll;	/* Set of all allowed extensions
					 * includes *.* */
    NSUInteger fileTypeIndex;		/* Index of currently selected
					 * filter. */
} filepanelFilterInfo;

/*
 * Only one of these is needed for the application, so they can be static.
 */

static filepanelFilterInfo filterInfo;
static NSOpenPanel *openpanel;
static NSSavePanel *savepanel;

static const char *const colorOptionStrings[] = {
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};








<







<







|
|


<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8

9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26



27





















28







29
30
31
32
33
34
35
/*
 * tkMacOSXDialog.c --
 *
 *	Contains the Mac implementation of the common dialog boxes.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"


#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif
#define modalOther  -1
#define modalError  -2




static int TkBackgroundEvalObjv(Tcl_Interp *interp, int objc,





















    Tcl_Obj *const *objv, int flags);








static const char *const colorOptionStrings[] = {
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
static const char *const alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *const alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "no", "yes", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},







|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
static const char *const alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *const alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

199
200




201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},
    [TYPE_RETRYCANCEL] =	{0,    1,    0,    0,    2,    0,    0},
    [TYPE_YESNO] =		{0,    0,    0,    0,    0,    2,    1},
    [TYPE_YESNOCANCEL] =	{0,    0,    0,    0,    3,    2,    1},
};

/*
 * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the
 * descriptive button text string index.
 */

static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {0, 1, 2},
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{6, 5, 0},
    [TYPE_YESNOCANCEL] =	{6, 5, 4},
};

/*
 * Construct a file URL from directory and filename. Either may be nil. If both
 * are nil, returns nil.
 */

static NSURL *
getFileURL(
    NSString *directory,
    NSString *filename)
{
    NSURL *url = nil;
    if (directory) {
	url = [NSURL fileURLWithPath:directory isDirectory:YES];
    }
    if (filename) {
	url = [NSURL URLWithString:filename relativeToURL:url];
    }
    return url;
}


#pragma mark TKApplication(TKDialog)





@implementation TKApplication(TKDialog)

- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
	(void)sender;
	(void)url;
    return YES;
}

- (void)panel:(id)sender didChangeToDirectoryURL:(NSURL *)url {
    (void)sender; (void)url;
}

- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
    (void)sender; (void)url;
    *outError = nil;
    return YES;
}

- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
		returnCode: (NSModalResponse) returnCode
	       contextInfo: (void *) contextInfo
{
    FilePanelCallbackInfo *callbackInfo = contextInfo;

    if (returnCode == modalOK) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([[url path] UTF8String], -1));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    } else if (returnCode == modalCancel) {
	Tcl_ResetResult(callbackInfo->interp);



    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
    }
    if (callbackInfo) {
	ckfree(callbackInfo);
    }
    [NSApp stopModalWithCode:returnCode];
}

- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
	contextInfo: (void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = contextInfo;

    if (returnCode >= NSAlertFirstButtonReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);

	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree(callbackInfo);
    }
}

- (void)selectFormat:(id)sender  {
    NSPopUpButton *button      = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex   = [button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[openpanel setAllowsOtherFileTypes:YES];

	/*
	 * setAllowsOtherFileTypes might have no effect; it's inherited from
	 * the NSSavePanel, where it has the effect that it does not append an
	 * extension. Setting the allowed file types to nil allows selecting
	 * any file.
	 */

	[openpanel setAllowedFileTypes:nil];
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[openpanel setAllowedFileTypes:allowedtypes];
	[openpanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

- (void)saveFormat:(id)sender  {
    NSPopUpButton *button     = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex  = [button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[savepanel setAllowsOtherFileTypes:YES];
	[savepanel setAllowedFileTypes:nil];
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[savepanel setAllowedFileTypes:allowedtypes];
	[savepanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

@end

#pragma mark -

static NSInteger showOpenSavePanel(
    NSSavePanel *panel,
    NSWindow *parent,
    FilePanelCallbackInfo *callbackInfo)
{
    NSInteger modalReturnCode;

    if (parent && ![parent attachedSheet]) {
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ];
	    }];

	/*
	 * The sheet has been prepared, so now we have to run it as a modal
	 * window.  Using [NSApp runModalForWindow:] on macOS 10.15 or later
	 * generates warnings on stderr.  But using [NSOpenPanel runModal] or
	 * [NSSavePanel runModal] on 10.14 or earler does not cause the
	 * completion handler to run when the panel is closed.
	 */

	if ([NSApp macOSVersion] > 101400) {
	    modalReturnCode = [panel runModal];
	} else {
	    modalReturnCode = [NSApp runModalForWindow:panel];
	}
    } else {

	/* 
	 * For the standalone file dialog, completion handlers do not work
	 * at all on macOS 10.14 and earlier.
	 */

	if ([NSApp macOSVersion] > 101400) {
	    [panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
			          returnCode:returnCode
			         contextInfo:callbackInfo ];
	    }];
	    modalReturnCode = [panel runModal];
	} else {
	    modalReturnCode = [panel runModal];
	    [NSApp tkFilePanelDidEnd:panel
		   	  returnCode:modalReturnCode
		         contextInfo:callbackInfo ];
	    [panel close];
	}
    }
    return callbackInfo->cmdObj ? modalOther : modalReturnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
 *	This procedure implements the color dialog box for the Mac platform.







|
|












|
|



|
|

|
|
<
<
<
<


|






>


>
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|



|

















|




|




|

>
>
>



<
<
|

<


















|




|










|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152




153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
















172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212


213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251











































252
253
254





















































255
256
257
258
259
260
261

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},
    [TYPE_RETRYCANCEL] =	{0,    1,    0,    0,    2,    0,    0},
    [TYPE_YESNO] =		{0,    0,    0,    0,    0,    1,    2},
    [TYPE_YESNOCANCEL] =	{0,    0,    0,    0,    3,    1,    2},
};

/*
 * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the
 * descriptive button text string index.
 */

static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {0, 1, 2},
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{5, 6, 0},
    [TYPE_YESNOCANCEL] =	{5, 6, 4},
};

/*
 * Construct a file URL from directory and filename.  Either may
 * be nil.  If both are nil, returns nil.
 */
#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
static NSURL *getFileURL(NSString *directory, NSString *filename) {




    NSURL *url = nil;
    if (directory) {
	url = [NSURL fileURLWithPath:directory];
    }
    if (filename) {
	url = [NSURL URLWithString:filename relativeToURL:url];
    }
    return url;
}
#endif

#pragma mark TKApplication(TKDialog)

@interface NSColorPanel(TKDialog)
- (void) _setUseModalAppearance: (BOOL) flag;
@end

@implementation TKApplication(TKDialog)

















- (void) tkFilePanelDidEnd: (NSSavePanel *) panel

	returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
    FilePanelCallbackInfo *callbackInfo = contextInfo;

    if (returnCode == NSFileHandlingPanelOKButton) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([[url path] UTF8String], -1));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree((char *)tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    } else if (returnCode == NSFileHandlingPanelCancelButton) {
	Tcl_ResetResult(callbackInfo->interp);
    }
    if (panel == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);


	ckfree((char *)callbackInfo);
    }

}

- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
	contextInfo: (void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = contextInfo;

    if (returnCode >= NSAlertFirstButtonReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);

	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree((char *)tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree((char *) callbackInfo);
    }
}











































@end

#pragma mark -






















































/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
 *	This procedure implements the color dialog box for the Mac platform.
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];

	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
    returnCode = [NSApp runModalForWindow:colorPanel];
    if (returnCode == modalOK) {
	color = [[colorPanel color] colorUsingColorSpace:
		[NSColorSpace deviceRGBColorSpace]];
	numberOfComponents = [color numberOfComponents];
    }
    if (color && numberOfComponents >= 3 && numberOfComponents <= 4) {
	CGFloat components[4];
	char colorstr[8];

	[color getComponents:components];
	snprintf(colorstr, 8, "#%02x%02x%02x",
		(short)(components[0] * 255),
		(short)(components[1] * 255),
		(short)(components[2] * 255));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(colorstr, 7));
    } else {
	Tcl_ResetResult(interp);
    }
    result = TCL_OK;

end:
    return result;
}

/*
 * Dissect the -filetype nested lists and store the information in the
 * filterInfo structure.
 */

static int
parseFileFilters(
    Tcl_Interp *interp,
    Tcl_Obj *fileTypesPtr,
    Tcl_Obj *typeVariablePtr)
{

    if (!fileTypesPtr) {
	filterInfo.doFileTypes = false;
	return TCL_OK;
    }

    FileFilterList fl;

    TkInitFileFilters(&fl);
    if (TkGetFileFilters(interp, &fl, fileTypesPtr, 0) != TCL_OK) {
	TkFreeFileFilters(&fl);
	return TCL_ERROR;
    }

    filterInfo.doFileTypes = (fl.filters != NULL);

    filterInfo.fileTypeIndex = 0;
    filterInfo.fileTypeExtensions = [NSMutableArray array];
    filterInfo.fileTypeNames = [NSMutableArray array];
    filterInfo.fileTypeLabels = [NSMutableArray array];
    filterInfo.fileTypeAllowsAll = [NSMutableArray array];

    filterInfo.allowedExtensions = [NSMutableArray array];
    filterInfo.allowedExtensionsAllowAll = NO;

    if (filterInfo.doFileTypes) {
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    NSString *name = [[NSString alloc] initWithUTF8String: filterPtr->name];

	    [filterInfo.fileTypeNames addObject:name];
	    [name release];
	    NSMutableArray *clauseextensions = [NSMutableArray array];
	    NSMutableArray *displayextensions = [NSMutableArray array];
	    bool allowsAll = NO;

	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {

		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
			globPtr = globPtr->next) {
		    const char *str = globPtr->pattern;
		    while (*str && (*str == '*' || *str == '.')) {
		    	str++;
		    }
		    if (*str) {
			NSString *extension = [[NSString alloc] initWithUTF8String:str];
			if (![filterInfo.allowedExtensions containsObject:extension]) {
			    [filterInfo.allowedExtensions addObject:extension];
			}

			[clauseextensions addObject:extension];
			[displayextensions addObject:[@"." stringByAppendingString:extension]];

			[extension release];
		    } else {
			/*
			 * It is the all pattern (*, .* or *.*)
			 */

			allowsAll = YES;
			filterInfo.allowedExtensionsAllowAll = YES;
			[displayextensions addObject:@"*"];
		    }
		}
	    }
	    [filterInfo.fileTypeExtensions addObject:clauseextensions];
	    [filterInfo.fileTypeAllowsAll addObject:[NSNumber numberWithBool:allowsAll]];

	    NSMutableString *label = [[NSMutableString alloc] initWithString:name];
	    [label appendString:@" ("];
	    [label appendString:[displayextensions componentsJoinedByString:@", "]];
	    [label appendString:@")"];
	    [filterInfo.fileTypeLabels addObject:label];
	    [label release];
	}

	/*
	 * Check if the typevariable exists and matches one of the names.
	 */

	filterInfo.preselectFilter = false;
	filterInfo.userHasSelectedFilter = false;
	if (typeVariablePtr) {
	    /*
	     * Extract the variable content as a NSString.
	     */

	    Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp,
		    typeVariablePtr, NULL, TCL_GLOBAL_ONLY);

	    /*
	     * Check that the typevariable exists.
	     */

	    if (selectedFileTypeObj != NULL) {
		const char *selectedFileType =
			Tcl_GetString(selectedFileTypeObj);
		NSString *selectedFileTypeStr =
			[[NSString alloc] initWithUTF8String:selectedFileType];
		NSUInteger index =
			[filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr];

		if (index != NSNotFound) {
		    filterInfo.fileTypeIndex = index;
		    filterInfo.preselectFilter = true;
		}
	    }
	}

    }

    TkFreeFileFilters(&fl);
    return TCL_OK;
}

static bool
filterCompatible(
    NSString *extension,
    int filterIndex)
{
    NSMutableArray *allowedExtensions =
	    [filterInfo.fileTypeExtensions objectAtIndex: filterIndex];

    /*
     * If this contains the all pattern, accept any extension.
     */

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterIndex] boolValue]) {
	return true;
    }

    return [allowedExtensions containsObject: extension];
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileObjCmd --
 *
 *	This procedure implements the "open file" dialog box for the Mac







<









|




















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364


















































































































































365
366
367
368
369
370
371
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];

	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
    returnCode = [NSApp runModalForWindow:colorPanel];
    if (returnCode == modalOK) {
	color = [[colorPanel color] colorUsingColorSpace:
		[NSColorSpace genericRGBColorSpace]];
	numberOfComponents = [color numberOfComponents];
    }
    if (color && numberOfComponents >= 3 && numberOfComponents <= 4) {
	CGFloat components[4];
	char colorstr[8];

	[color getComponents:components];
	snprintf(colorstr, 8, "#%02x%02x%02x",
		(short)(components[0] * 255),
		(short)(components[1] * 255),
		(short)(components[2] * 255));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(colorstr, 7));
    } else {
	Tcl_ResetResult(interp);
    }
    result = TCL_OK;

end:
    return result;
}



















































































































































/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileObjCmd --
 *
 *	This procedure implements the "open file" dialog box for the Mac
678
679
680
681
682
683
684

685
686
687
688
689
690

691
692
693
694

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710


711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728


729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746


747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811





812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837

838
839
840
841
842
843
844
845
846





847








848
849

850
851


852
853
854
855


856
857





858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956

957
958
959
960
961
962

963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990


991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009


1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021


1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053

1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134





1135
1136
1137
1138



1139

1140
1141




1142
1143


1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, multiple = 0;

    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;

    openpanel =  [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;


    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case OPEN_DEFAULT:
	    break;
	case OPEN_FILETYPES:
	    fileTypesPtr = objv[i + 1];


	    break;
	case OPEN_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];


	    break;
	case OPEN_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &multiple) != TCL_OK) {
		goto end;
	    }
	    break;
	case OPEN_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case OPEN_TITLE:
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];


	    break;
	case OPEN_TYPEVARIABLE:
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }

    if (title) {
	[openpanel setTitle:title];

	/*
	 * From OSX 10.11, the title string is silently ignored in the open
	 * panel.  Prepend the title to the message in this case.
	 */

	if ([NSApp macOSVersion] > 101000) {
	    if (message) {
		NSString *fullmessage =
		    [[NSString alloc] initWithFormat:@"%@\n%@", title, message];
		[message release];
		[title release];

		message = fullmessage;
	    } else {
		message = title;
	    }
	}
    }

    if (message) {
	[openpanel setMessage:message];
	[message release];
    }

    [openpanel setAllowsMultipleSelection:multiple];

    if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
	goto end;
    }

    if (filterInfo.doFileTypes) {
	NSTextField *label = [[NSTextField alloc]
		initWithFrame:NSMakeRect(0, 0, 60, 22)];
	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO];
	NSView *accessoryView = [[NSView alloc]
		initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];

	[label setEditable:NO];
	[label setStringValue:@"Filter:"];
	[label setBordered:NO];
	[label setBezeled:NO];
	[label setDrawsBackground:NO];
	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
	[popupButton setAction:@selector(selectFormat:)];
	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];
	if (filterInfo.preselectFilter) {

	    /*
	     * A specific filter was selected from the typevariable. Select it
	     * and open the accessory view.
	     */






	    [popupButton selectItemAtIndex:filterInfo.fileTypeIndex];

	    /*
	     * On OSX > 10.11, the options are not visible by default. Ergo
	     * allow all file types
	    [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
	    */

	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
	} else {
	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
	}
	if (filterInfo.allowedExtensionsAllowAll) {
	    [openpanel setAllowsOtherFileTypes:YES];
	} else {
	    [openpanel setAllowsOtherFileTypes:NO];
	}
	[openpanel setAccessoryView:accessoryView];
    } else {
	/*
	 * No filters are given. Allow picking all files.
	 */

	[openpanel setAllowsOtherFileTypes:YES];
    }

    if (cmdObj) {

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = multiple;





    if (directory || filename) {








	NSURL *fileURL = getFileURL(directory, filename);


	[openpanel setDirectoryURL:fileURL];
    }


    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {


	parent = nil;
	parentIsKey = False;





    }
    modalReturnCode = showOpenSavePanel(openpanel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    if ((typeVariablePtr && (modalReturnCode == NSOKButton))
	    && filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the
	 * dialog was not cancelled.
	 */

	NSUInteger selectedFilterIndex = filterInfo.fileTypeIndex;
	NSString *selectedFilter = NULL;

	if (filterInfo.userHasSelectedFilter) {
	    selectedFilterIndex = filterInfo.fileTypeIndex;
	    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	} else {
	    /*
	     * Difficult case: the user has not touched the filter settings,
	     * but we must return something in the typevariable. First check if
	     * the preselected type is compatible with the selected file,
	     * otherwise choose the first compatible type from the list,
	     * finally fall back to the empty string.
	     */

	    NSURL *selectedFile;
	    NSString *extension;
	    if (multiple) {
		/*
		 * Use the first file in the case of multiple selection.
		 * Anyway it is not overly useful here.
		 */
		selectedFile = [[openpanel URLs] objectAtIndex:0];
	    } else {
		selectedFile = [openpanel URL];
	    }

	    extension = [selectedFile pathExtension];

	    if (filterInfo.preselectFilter &&
		    filterCompatible(extension, filterInfo.fileTypeIndex)) {
		selectedFilterIndex = filterInfo.fileTypeIndex;  // The preselection from the typevariable
		selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	    } else {
		NSUInteger j;

		for (j = 0; j < [filterInfo.fileTypeNames count]; j++) {
		    if (filterCompatible(extension, j)) {
			selectedFilterIndex = j;
			break;
		    }
		}
		if (j == selectedFilterIndex) {
		    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
		} else {
		    selectedFilter = @"";
		}
	    }
	}
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], -1),
		TCL_GLOBAL_ONLY);
    }
 end:

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileObjCmd --
 *
 *	This procedure implements the "save file" dialog box for the Mac
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    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 *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int confirmOverwrite = 1;
    int index, len;

    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;

    savepanel = [NSSavePanel savePanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;


    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	    case SAVE_DEFAULT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		while (*str && (*str == '*' || *str == '.')) {
		    str++;
		}
		if (*str) {
		    defaultType = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		}
		break;
	    case SAVE_FILETYPES:
		fileTypesPtr = objv[i + 1];


		break;
	    case SAVE_INITDIR:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    directory = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		}
		break;
	    case SAVE_INITFILE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    filename = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		    [savepanel setNameFieldStringValue:filename];
		}
		break;
	    case SAVE_MESSAGE:
		message = [[NSString alloc] initWithUTF8String:
			Tcl_GetString(objv[i + 1])];


		break;
	    case SAVE_PARENT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		tkwin = Tk_NameToWindow(interp, str, tkwin);
		if (!tkwin) {
		    goto end;
		}
		haveParentOption = 1;
		break;
	    case SAVE_TITLE:
		title = [[NSString alloc] initWithUTF8String:
			Tcl_GetString(objv[i + 1])];


		break;
	    case SAVE_TYPEVARIABLE:
		typeVariablePtr = objv[i + 1];
		break;
	    case SAVE_COMMAND:
		cmdObj = objv[i+1];
		break;
	    case SAVE_CONFIRMOW:
		if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
			&confirmOverwrite) != TCL_OK) {
		    goto end;
		}
		break;
	}
    }

    if (title) {
	[savepanel setTitle:title];

	/*
	 * From OSX 10.11, the title string is silently ignored, if the save
	 * panel is a sheet.  Prepend the title to the message in this case.
	 * NOTE: should be conditional on OSX version, but -mmacosx-version-min
	 * does not revert this behaviour.
	 */

	if (haveParentOption) {

	    if (message) {
		NSString *fullmessage =
		    [[NSString alloc] initWithFormat:@"%@\n%@",title,message];
		[message release];
		[title release];

		message = fullmessage;
	    } else {
		message = title;
	    }
	}
    }

    if (message) {
	[savepanel setMessage:message];
	[message release];
    }

    if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
	goto end;
    }


    if (filterInfo.doFileTypes) {
	NSView *accessoryView = [[NSView alloc]
		initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];
	NSTextField *label = [[NSTextField alloc]
		initWithFrame:NSMakeRect(0, 0, 60, 22)];

	[label setEditable:NO];
	[label setStringValue:NSLocalizedString(@"Format:", nil)];
	[label setBordered:NO];
	[label setBezeled:NO];
	[label setDrawsBackground:NO];

	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO];

	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
	[popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
	[popupButton setAction:@selector(saveFormat:)];

	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];

	[savepanel setAccessoryView:accessoryView];

	[savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
	[savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
    } else if (defaultType) {
	/*
	 * If no filetypes are given, defaultextension is an alternative way to
	 * specify the attached extension. Just propose this extension, but
	 * don't display an accessory view.
	 */

	NSMutableArray *AllowedFileTypes = [NSMutableArray array];

	[AllowedFileTypes addObject:defaultType];
	[savepanel setAllowedFileTypes:AllowedFileTypes];
	[savepanel setAllowsOtherFileTypes:YES];
    }

    [savepanel setCanSelectHiddenExtension:YES];
    [savepanel setExtensionHidden:NO];

    if (cmdObj) {

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;

    if (directory) {
	[savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    }

    /*
     * Check for file name and set to the empty string if nil. This prevents a crash
     * with an uncaught exception.
     */


    if (filename) {
	[savepanel setNameFieldStringValue:filename];





    } else {
	[savepanel setNameFieldStringValue:@""];
    }
    if (haveParentOption) {



	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);

	parentIsKey = parent && [parent isKeyWindow];
    } else {




	parent = nil;
	parentIsKey = False;


    }
    modalReturnCode = showOpenSavePanel(savepanel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }

    if (typeVariablePtr && (modalReturnCode == NSOKButton)
	    && filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the
	 * dialog was not cancelled.
	 */

	NSString *selectedFilter =
	    [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex];
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], -1),
		TCL_GLOBAL_ONLY);
    }

  end:

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseDirectoryObjCmd --







>
|



|

>
|



>















|
>
>


















>
>


















>
>









>
|
<
|
|
|
<
<
|
<
|
<
<
<
<
>
|
<
|
<
<
<
|
|
<
<
|
|
<
|
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
>
>
>
>
>
|
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<

>

>





<



>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
|
>
|
<
>
>
|
<
|

>
>
|
|
>
>
>
>
>

<




|
<

|
<


<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
















<










|




>
|



|

>
|



>












|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
<
|
|
|
|
|
|
|
|
|
|


|
|
<
|
<
<
<
<
<
<
|
|
>
|
<
<
<
<
>
|
<
|
<
<
<
|
|
<
<
|
|
<
<
<
|
>
|
<
<
<
<
|
<
<
<
<
<
|
<
<
|
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|

<
|
|
<

>





<



|
|
<
<
|
<
<
<
<
|
>
|
<
>
>
>
>
>
|
|
<
|
>
>
>
|
>
|

>
>
>
>
|
|
>
>

<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477


478

479




480
481

482



483
484


485
486

487



488
489






490



491






492




493
494
495
496
497
498
499
500





501



502




503





504

505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537

538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554

555
556

557
558


559











560










561
562


























563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684

685






686
687
688
689




690
691

692



693
694


695
696



697
698
699




700





701


702



703


704

705












706
707
708

709
710

711
712
713
714
715
716
717

718
719
720
721
722


723




724
725
726

727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750

751
752
753
754















755
756
757
758
759
760
761
762
763
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, multiple = 0;
    FileFilterList fl;
    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case OPEN_DEFAULT:
	    break;
	case OPEN_FILETYPES:
	    if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {
		goto end;
	    }
	    break;
	case OPEN_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [panel setMessage:message];
	    [message release];
	    break;
	case OPEN_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &multiple) != TCL_OK) {
		goto end;
	    }
	    break;
	case OPEN_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case OPEN_TITLE:
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [panel setTitle:title];
	    [title release];
	    break;
	case OPEN_TYPEVARIABLE:
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    [panel setAllowsMultipleSelection:multiple];
    if (fl.filters) {

	fileTypes = [NSMutableArray array];
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {


	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;

		    clausePtr = clausePtr->next) {




		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
			globPtr = globPtr->next) {

		    str = globPtr->pattern;



		    while (*str && (*str == '*' || *str == '.')) {
			str++;


		    }
		    if (*str) {

			type = [[NSString alloc] initWithUTF8String:str];



			if (![fileTypes containsObject:type]) {
			    [fileTypes addObject:type];






			}



			[type release];






		    }




		}
		for (MacFileType *mfPtr = clausePtr->macTypes; mfPtr;
			mfPtr = mfPtr->next) {
		    if (mfPtr->type) {
			type = NSFileTypeForHFSTypeCode(mfPtr->type);
			if (![fileTypes containsObject:type]) {
			    [fileTypes addObject:type];
			}





		    }



		}




	    }





	}

    }
    [panel setAllowedFileTypes:fileTypes];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }

    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = multiple;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
	    parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory
	       file:filename
	       types:fileTypes
	       modalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:
		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#else
	[panel setAllowedFileTypes:fileTypes];
	[panel setDirectoryURL:getFileURL(directory, filename)];
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel

		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif

	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory
				 file:filename];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }

    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    if (typeVariablePtr && result == TCL_OK) {

	/*
	 * The -typevariable option is not really supported.

	 */



	Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL,











		"", TCL_GLOBAL_ONLY);










    }



























  end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileObjCmd --
 *
 *	This procedure implements the "save file" dialog box for the Mac
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See user documentation.

 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    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 = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int confirmOverwrite = 1;
    int index, len;
    FileFilterList fl;
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSSavePanel *panel = [NSSavePanel savePanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case SAVE_DEFAULT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    while (*str && (*str == '*' || *str == '.')) {
		str++;
	    }
	    if (*str) {
		defaultType = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case SAVE_FILETYPES:
	    if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {
		goto end;
	    }
	    break;
	case SAVE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case SAVE_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[NSString alloc] initWithUTF8String:str]
			autorelease];

	    }
	    break;
	case SAVE_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [panel setMessage:message];
	    [message release];
	    break;
	case SAVE_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case SAVE_TITLE:
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [panel setTitle:title];
	    [title release];
	    break;
	case SAVE_TYPEVARIABLE:

	    break;
	case SAVE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	case SAVE_CONFIRMOW:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &confirmOverwrite) != TCL_OK) {
		goto end;
	    }
	    break;
	}
    }
    if (fl.filters || defaultType) {
	fileTypes = [NSMutableArray array];

	[fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent];






	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {




		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
			globPtr = globPtr->next) {

		    str = globPtr->pattern;



		    while (*str && (*str == '*' || *str == '.')) {
			str++;


		    }
		    if (*str) {



			type = [[NSString alloc] initWithUTF8String:str];
			if (![fileTypes containsObject:type]) {
			    [fileTypes addObject:type];




			}





			[type release];


		    }



		}


	    }

	}












	[panel setAllowedFileTypes:fileTypes];
	[panel setAllowsOtherFileTypes:YES];
    }

    [panel setCanSelectHiddenExtension:YES];
    [panel setExtensionHidden:NO];

    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }

    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {


       parentIsKey = [parent isKeyWindow];




#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory
	       file:filename

	       modalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:
		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];

	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif
	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory file:filename];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }

    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }















  end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseDirectoryObjCmd --
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
int
Tk_ChooseDirectoryObjCmd(
    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 *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, mustexist = 0;
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

    for (i = 1; i < objc; i += 2) {







|






|







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
int
Tk_ChooseDirectoryObjCmd(
    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 = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, mustexist = 0;
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

    for (i = 1; i < objc; i += 2) {
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281




1282
1283
1284




1285
1286




1287
1288


1289
1290
1291
1292
1293
1294
1295
1296
1297
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;

    /*
     * Check for directory value, set to root if not specified; otherwise
     * crashes with exception because of nil string parameter.
     */

    if (!directory) {
	directory = @"/";
    }

    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);




    [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);




	parentIsKey = parent && [parent isKeyWindow];
    } else {




	parent = nil;
	parentIsKey = False;


    }
    modalReturnCode = showOpenSavePanel(panel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
  end:
    return result;
}







>





<



|
<
<
|
<
|
|
|
<
>
|
>
>
>
>
|
|
|
>
>
>
>
|

>
>
>
>
|
|
>
>

<







847
848
849
850
851
852
853
854
855
856
857
858
859

860
861
862
863


864

865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891

892
893
894
895
896
897
898
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }

    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);


    if (haveParentOption && parent && ![parent attachedSheet]) {

      parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory

		file:filename
		modalForWindow:parent
		modalDelegate:NSApp
		didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif
	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory file:nil];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }

    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
  end:
    return result;
}
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
1347




1348
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];

    /*
     * This replaces the old about dialog with a standard alert that displays
     * correctly on 10.14.
     */


    NSString *version =  @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
    NSString *url = @"www.tcl-lang.org";
    NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
    NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
    NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font
					        forKey:NSFontAttributeName];





    [credits insertText: [[NSAttributedString alloc]
		 initWithString:[NSString stringWithFormat: @"\n"
		"Tcl and Tk are distributed under a modified BSD license: "
		"www.tcl.tk/software/tcltk/license.html\n\n"
		"%1$C 1987-%2$@ Tcl Core Team and Contributers.\n\n"

		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC.\n\n"
		"%1$C 2014-%2$@ Marc Culler.\n\n"
		"%1$C 2002-2012 Daniel A. Steffen.\n\n"
		"%1$C 2001-2009 Apple Inc.\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n"
		"%1$C 1998-2000 Scriptics Inc.\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year]
	    attributes:textAttributes]
            replacementRange:NSMakeRange(0,0)];
    [credits setDrawsBackground:NO];
    [credits setEditable:NO];

    NSAlert *about = [[NSAlert alloc] init];

    [[about window] setTitle:@"About Tcl & Tk"];
    [about setMessageText: version];
    [about setInformativeText:url];
    about.accessoryView = credits;
    [about runModal];
    [about release];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
 *	Implements the ::tk::mac::standardAboutPanel command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXStandardAboutPanelObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --







|
|
|
|
>

<
<
<
<
|
|
|
>
>
>
>
|
|
<
<
|
>
|
|
|
|
|
|
|
|
<
<
<
<
|
<
|
<
<
<
<
|
|




















|








|







930
931
932
933
934
935
936
937
938
939
940
941
942




943
944
945
946
947
948
949
950
951


952
953
954
955
956
957
958
959
960
961




962

963




964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];

    NSMutableParagraphStyle *style =
	    [[[NSParagraphStyle defaultParagraphStyle] mutableCopy]
	    autorelease];

    [style setAlignment:NSCenterTextAlignment];





    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
	    @"Tcl & Tk", @"ApplicationName",
	    @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion",
	    @TK_PATCH_LEVEL, @"Version",
	    image, @"ApplicationIcon",
	    [NSString stringWithFormat:@"Copyright %1$C 1987-%2$@.", 0xA9,
	    year], @"Copyright",
	    [[[NSAttributedString alloc] initWithString:
	    [NSString stringWithFormat:


	    @"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
		"%1$C 1989-%2$@ Contributors." "\n\n"
		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
		"%1$C 2014-%2$@ Marc Culler." "\n\n"
		"%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
		"%1$C 2001-2009 Apple Inc." "\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
		"%1$C 1998-2000 Scriptics Inc." "\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:




	    [NSDictionary dictionaryWithObject:style

	    forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits",




	    nil];
    [NSApp orderFrontStandardAboutPanelWithOptions:options];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
 *	Implements the ::tk::mac::standardAboutPanel command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXStandardAboutPanelObjCmd(
    ClientData clientData,	/* Unused. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
int
Tk_MessageBoxObjCmd(
    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 *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, typeIndex, iconIndex, indexDefaultOption = 0;
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;







|







1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
int
Tk_MessageBoxObjCmd(
    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 = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, typeIndex, iconIndex, indexDefaultOption = 0;
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];







|







1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is
	 * why we do this here.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, sizeof(char *), "-default value",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", -1));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*) alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: defaultNativeButtonIndex-1]
	    setKeyEquivalent: @"\r"];
    if (cmdObj) {

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
	parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 	[alert beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkAlertDidEnd:alert
		    returnCode:returnCode
		    contextInfo:callbackInfo];
	}];
#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [alert runModal];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
  end:
    [alert release];
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 */
#pragma mark [tk fontchooser] implementation (TIP 324)
/*
 *----------------------------------------------------------------------
 */

#include "tkMacOSXInt.h"
#include "tkMacOSXFont.h"

typedef struct FontchooserData {
    Tcl_Obj *titleObj;
    Tcl_Obj *cmdObj;
    Tk_Window parent;
} FontchooserData;

enum FontchooserEvent {
    FontchooserClosed,
    FontchooserSelection
};

static void		FontchooserEvent(int kind);
static Tcl_Obj *	FontchooserCget(FontchooserData *fcdPtr,
			    int optionIndex);
static int		FontchooserConfigureCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		FontchooserShowCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		FontchooserHideCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		FontchooserParentEventHandler(ClientData clientData,
			    XEvent *eventPtr);
static void		DeleteFontchooserData(ClientData clientData,
			    Tcl_Interp *interp);

MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
const TkEnsemble tkFontchooserEnsemble[] = {
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

static Tcl_Interp *fontchooserInterp = NULL;
static NSFont *fontPanelFont = nil;
static NSMutableDictionary *fontPanelFontAttributes = nil;

static const char *const fontchooserOptionStrings[] = {
    "-parent", "-title", "-font", "-command",
    "-visible", NULL
};
enum FontchooserOption {
    FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd,
    FontchooserVisible
};

@implementation TKApplication(TKFontPanel)

- (void) changeFont: (id) sender
{
    NSFontManager *fm = [NSFontManager sharedFontManager];
    (void)sender;

    if ([fm currentFontAction] == NSViaPanelFontAction) {
	NSFont *font = [fm convertFont:fontPanelFont];

	if (![fontPanelFont isEqual:font]) {
	    [fontPanelFont release];
	    fontPanelFont = [font retain];
	    FontchooserEvent(FontchooserSelection);
	}
    }
}

- (void) changeAttributes: (id) sender
{
    NSDictionary *attributes = [sender convertAttributes:
	    fontPanelFontAttributes];

    if (![fontPanelFontAttributes isEqual:attributes]) {
	[fontPanelFontAttributes setDictionary:attributes];
	FontchooserEvent(FontchooserSelection);
    }
}

- (NSUInteger) validModesForFontPanel: (NSFontPanel *)fontPanel
{
    (void)fontPanel;

    return (NSFontPanelStandardModesMask & ~NSFontPanelAllEffectsModeMask) |
	    NSFontPanelUnderlineEffectModeMask |
	    NSFontPanelStrikethroughEffectModeMask;
}

- (void) windowDidOrderOffScreen: (NSNotification *)notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if ([[notification object] isEqual:[[NSFontManager sharedFontManager]
	    fontPanel:NO]]) {
	FontchooserEvent(FontchooserClosed);
    }
}
@end

/*
 *----------------------------------------------------------------------
 *
 * FontchooserEvent --
 *
 *	This processes events generated by user interaction with the font
 *	panel.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static void
FontchooserEvent(
    int kind)
{
    FontchooserData *fcdPtr;
    Tcl_Obj *fontObj;

    if (!fontchooserInterp) {
	return;
    }
    fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    switch (kind) {
    case FontchooserClosed:
	if (fcdPtr->parent != None) {
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    fontchooserInterp = NULL;
	}
	break;
    case FontchooserSelection:
	fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (fontObj) {
	    if (fcdPtr->cmdObj) {
		int objc, result;
		Tcl_Obj **objv, **tmpv;

		result = Tcl_ListObjGetElements(fontchooserInterp,
			fcdPtr->cmdObj, &objc, &objv);
		if (result == TCL_OK) {
		    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		    tmpv[objc] = fontObj;
		    TkBackgroundEvalObjv(fontchooserInterp, objc + 1, tmpv,
			    TCL_EVAL_GLOBAL);
		    ckfree(tmpv);
		}
	    }
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
	}
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FontchooserCget --
 *
 *	Helper for the FontchooserConfigure command to return the current value
 *	of any of the options (which may be NULL in the structure).
 *
 * Results:
 *	Tcl object of option value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
FontchooserCget(
    FontchooserData *fcdPtr,
    int optionIndex)
{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (fcdPtr->parent != None) {
	    resObj = Tcl_NewStringObj(
		    ((TkWindow *)fcdPtr->parent)->pathName, -1);
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
	if (fcdPtr->titleObj) {
	    resObj = fcdPtr->titleObj;
	} else {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserFont:
	resObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (!resObj) {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserCmd:
	if (fcdPtr->cmdObj) {
	    resObj = fcdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewWideIntObj([[[NSFontManager sharedFontManager]
		fontPanel:NO] isVisible] != 0);
	break;
    default:
	resObj = Tcl_NewObj();
    }
    return resObj;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserConfigureCmd --
 *
 *	Implementation of the 'tk fontchooser configure' ensemble command.  See
 *	the user documentation for what it does.
 *
 * Results:
 *	See the user documentation.
 *
 * Side effects:
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);
    int i, r = TCL_OK;

    /*
     * With no arguments we return all the options in a dict
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && fontchooserOptionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(fontchooserOptionStrings[i], -1);
	    valueObj = FontchooserCget(fcdPtr, i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex, len;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], fontchooserOptionStrings,
		sizeof(char *), "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
	     * With one option and no arg, return the current value.
	     */

	    Tcl_SetObjResult(interp, FontchooserCget(fcdPtr, optionIndex));
	    return TCL_OK;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "VALUE", NULL);
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);

	    if (parent == None) {
		return TCL_ERROR;
	    }
	    if (fcdPtr->parent) {
		Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
			FontchooserParentEventHandler, fcdPtr);
	    }
	    fcdPtr->parent = parent;
	    Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
		    FontchooserParentEventHandler, fcdPtr);
	    break;
	}
	case FontchooserTitle:
	    if (fcdPtr->titleObj) {
		Tcl_DecrRefCount(fcdPtr->titleObj);
	    }
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		fcdPtr->titleObj = objv[i+1];
		if (Tcl_IsShared(fcdPtr->titleObj)) {
		    fcdPtr->titleObj = Tcl_DuplicateObj(fcdPtr->titleObj);
		}
		Tcl_IncrRefCount(fcdPtr->titleObj);
	    } else {
		fcdPtr->titleObj = NULL;
	    }
	    break;
	case FontchooserFont:
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]);

		if (!f) {
		    return TCL_ERROR;
		}
		[fontPanelFont autorelease];
		fontPanelFont = [TkMacOSXNSFontForFont(f) retain];
		[fontPanelFontAttributes setDictionary:
			TkMacOSXNSFontAttributesForFont(f)];
		[fontPanelFontAttributes removeObjectsForKeys:[NSArray
			arrayWithObjects:NSFontAttributeName,
			NSLigatureAttributeName, NSKernAttributeName, nil]];
		Tk_FreeFont(f);
	    } else {
		[fontPanelFont release];
		fontPanelFont = nil;
		[fontPanelFontAttributes removeAllObjects];
	    }

	    NSFontManager *fm = [NSFontManager sharedFontManager];
	    NSFontPanel *fp = [fm fontPanel:NO];

	    [fp setPanelFont:fontPanelFont isMultiple:NO];
	    [fm setSelectedFont:fontPanelFont isMultiple:NO];
	    [fm setSelectedAttributes:fontPanelFontAttributes
		    isMultiple:NO];
	    if ([fp isVisible]) {
		Tk_SendVirtualEvent(fcdPtr->parent,
			"TkFontchooserFontChanged", NULL);
	    }
	    break;
	case FontchooserCmd:
	    if (fcdPtr->cmdObj) {
		Tcl_DecrRefCount(fcdPtr->cmdObj);
	    }
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		fcdPtr->cmdObj = objv[i+1];
		if (Tcl_IsShared(fcdPtr->cmdObj)) {
		    fcdPtr->cmdObj = Tcl_DuplicateObj(fcdPtr->cmdObj);
		}
		Tcl_IncrRefCount(fcdPtr->cmdObj);
	    } else {
		fcdPtr->cmdObj = NULL;
	    }
	    break;
	}
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserShowCmd --
 *
 *	Implements the 'tk fontchooser show' ensemble command. The per-interp
 *	configuration data for the dialog is held in an interp associated
 *	structure.
 *
 * Results:
 *	See the user documentation.
 *
 * Side effects:
 *	Font Panel may be shown.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);

    if (fcdPtr->parent == None) {
	fcdPtr->parent = (Tk_Window)clientData;
	Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
    }

    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFontPanel *fp = [fm fontPanel:YES];

    if ([fp delegate] != NSApp) {
	[fp setDelegate:NSApp];
    }
    if (![fp isVisible]) {
	[fm orderFrontFontPanel:NSApp];
	Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
    }
    fontchooserInterp = interp;

    return TCL_OK;

}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserHideCmd --
 *
 *	Implementation of the 'tk fontchooser hide' ensemble. See the user
 *	documentation for details.
 *
 * Results:
 *	See the user documentation.
 *
 * Side effects:
 *	Font Panel may be hidden.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    TCL_UNUSED(void *),	/* Main window */
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO];

    if ([fp isVisible]) {
	[fp orderOut:NSApp];
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserParentEventHandler --
 *
 *	Event handler for StructureNotify events on the font chooser's parent
 *	window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Font chooser parent info is cleared and font panel is hidden.
 *
 * ----------------------------------------------------------------------
 */

static void
FontchooserParentEventHandler(
    ClientData clientData,
    XEvent *eventPtr)
{
    FontchooserData *fcdPtr = clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
	fcdPtr->parent = NULL;
	FontchooserHideCmd(NULL, NULL, 0, NULL);
    }
}

/*
 * ----------------------------------------------------------------------
 *
 * DeleteFontchooserData --
 *
 *	Clean up the font chooser configuration data when the interp is
 *	destroyed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	per-interp configuration data is destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteFontchooserData(
    ClientData clientData,
    Tcl_Interp *interp)
{
    FontchooserData *fcdPtr = clientData;

    if (fcdPtr->titleObj) {
	Tcl_DecrRefCount(fcdPtr->titleObj);
    }
    if (fcdPtr->cmdObj) {
	Tcl_DecrRefCount(fcdPtr->cmdObj);
    }
    ckfree(fcdPtr);

    if (fontchooserInterp == interp) {
	fontchooserInterp = NULL;
    }
}

/*
 * ----------------------------------------------------------------------
 *
 * TkInitFontchooser --
 *
 *	Associate the font chooser configuration data with the Tcl interpreter.
 *	There is one font chooser per interp.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	per-interp configuration data is destroyed.
 *
 * ----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkInitFontchooser(
    Tcl_Interp *interp,
    TCL_UNUSED(void *))
{
    FontchooserData *fcdPtr = (FontchooserData *)ckalloc(sizeof(FontchooserData));

    bzero(fcdPtr, sizeof(FontchooserData));
    Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteFontchooserData,
	    fcdPtr);
    if (!fontPanelFontAttributes) {
	fontPanelFontAttributes = [NSMutableDictionary new];
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|















|
<




















|














>





<



|


|

|
|
|
|
<







|















|
<
<
<
<
<
|
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<


|
<
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<

|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
|

|








1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191





1192


1193





1194




1195
















1196







1197



1198








1199

1200




1201










1202




1203





1204



1205


















1206













1207
































































































1208










1209
















1210



1211
1212
1213





1214



1215



1216





1217

1218











1219
1220
1221
1222













1223







1224















































1225

































1226









1227





1228






















1229





1230

1231
1232
1233
















1234








1235


1236


1237
















1238






1239





1240
1241

1242















1243






















1244

1245











1246






1247





1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is
	 * why we do this here.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) {

	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", -1));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*)alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: defaultNativeButtonIndex-1]
	    setKeyEquivalent: @"\r"];
    if (cmdObj) {
	callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }

    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
	parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090
 	[alert beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode)
	       { [NSApp tkAlertDidEnd:alert
			returnCode:returnCode
			contextInfo:callbackInfo ]; } ];

#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [NSApp runModalForWindow:[alert window]];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
  end:
    [alert release];
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    return result;
}

/*
 * ----------------------------------------------------------------------





 *


 * TkBackgroundEvalObjv --





 *




 *	Evaluate a command while ensuring that we do not affect the
















 *	interpreters state. This is important when evaluating script







 *	during background tasks.



 *








 * Results:

 *	A standard Tcl result code.




 *










 * Side Effects:




 *	The interpreters variables and code may be modified by the script





 *	but the result will not be modified.



 *


















 * ----------------------------------------------------------------------













 */











































































































int
















TkBackgroundEvalObjv(



    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const *objv,





    int flags)



{



    Tcl_InterpState state;





    int n, r = TCL_OK;













    /*
     * Record the state of the interpreter.
     */














    Tcl_Preserve(interp);







    state = Tcl_SaveInterpState(interp, TCL_OK);

















































































    /*









     * 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);





    }


    /*















     * Restore the state of the interpreter.






















     */













    (void) Tcl_RestoreInterpState(interp, state);






    Tcl_Release(interp);






    return r;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXDraw.c.

1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53




54
55
56
57
58
59
60
/*
 * tkMacOSXDraw.c --
 *
 *	This file contains functions that draw to windows. Many of thees

 *	functions emulate Xlib functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 2001-2009 Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2014-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext]
#else
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort]
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

#define radians(d)	((d) * (M_PI/180.0))

/*
 * Non-antialiased CG drawing looks better and more like X11 drawing when using
 * very fine lines, so decrease all linewidths by the following constant.
 */
#define NON_AA_CG_OFFSET .999

static int cgAntiAliasLimit = 0;
#define notAA(w)	((w) < cgAntiAliasLimit)

static int useThemedToplevel = 0;
static int useThemedFrame = 0;
static unsigned long transparentColor;

/*
 * Prototypes for functions used only in this file.
 */

static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
static NSImage *CreateNSImageFromPixmap(Pixmap pixmap, int width, int height);






/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitCGDrawing --
 *



|
>
|


|

|







|
|
<
<
<
<
<








|








|



<






|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20





21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * tkMacOSXDraw.c --
 *
 *	This file contains functions that perform drawing to
 *	Xlib windows. Most of the functions simple emulate
 *	Xlib functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2014 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "xbytes.h"
#include "tkButton.h"






/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

#define radians(d) ((d) * (M_PI/180.0))

/*
 * Non-antialiased CG drawing looks better and more like X11 drawing when using
 * very fine lines, so decrease all linewidths by the following constant.
 */
#define NON_AA_CG_OFFSET .999

static int cgAntiAliasLimit = 0;
#define notAA(w) ((w) < cgAntiAliasLimit)

static int useThemedToplevel = 0;
static int useThemedFrame = 0;


/*
 * Prototypes for functions used only in this file.
 */

static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
static CGImageRef CreateCGImageWithXImage(XImage *ximage);
static CGContextRef GetCGContextForDrawable(Drawable d);
static void DrawCGImage(Drawable d, GC gc, CGContextRef context, CGImageRef image,
	unsigned long imageForeground, unsigned long imageBackground,
	CGRect imageBounds, CGRect srcBounds, CGRect dstBounds);


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitCGDrawing --
 *
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112





















































113








114





115













































































































































































































































116
117
118
119
120
121
122
123
124
125




126
127
128
129
130
131
132








133


134

135


136
137
138


139



140
141





142



































143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228








































































229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXInitCGDrawing(
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    int limit)
{
    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}

	if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
		(char *)&cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	cgAntiAliasLimit = limit;

	/*
	 * Piggy-back the themed drawing var init here.
	 */

	if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel",
		(char *)&useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
		(char *)&useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	transparentColor = TkMacOSXClearPixel();
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *





















































 * TkMacOSXGetNSImageFromTkImage --








 *





 *	Get autoreleased NSImage for Tk_Image.













































































































































































































































 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */





NSImage *
TkMacOSXGetNSImageFromTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{








    Pixmap pixmap;


    NSImage *nsImage;

    if (width == 0 || height == 0) {


	return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
    }
    pixmap = Tk_GetPixmap(display, None, width, height, 0);


    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);



    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);









































    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSImageFromBitmap --
 *
 *	Get autoreleased NSImage for Bitmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSImage *
TkMacOSXGetNSImageFromBitmap(
    Display *display,
    Pixmap bitmap,
    GC gc,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    gc->background = transparentColor;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1);
    gc->background = origBackground;

    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * CreateNSImageFromPixmap --
 *
 *	Create NSImage for Pixmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static NSImage *
CreateNSImageFromPixmap(
    Pixmap pixmap,
    int width,
    int height)
{
    CGImageRef cgImage;
    NSImage *nsImage;
    NSBitmapImageRep *bitmapImageRep;
    CGContextRef context = TkMacOSXGetCGContextForDrawable(pixmap);

    if (context) {
	cgImage = CGBitmapContextCreateImage(context);
    } else {
	return NULL;
    }
    nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
    bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
    [nsImage addRepresentation:bitmapImageRep];
    [bitmapImageRep release];
    CFRelease(cgImage);

    return nsImage;
}

/*
 *----------------------------------------------------------------------
 *








































































 * Tk_MacOSXGetCGContextForDrawable --
 *
 *	Get CGContext for given Drawable, creating one if necessary.
 *
 * Results:
 *	CGContext.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
Tk_MacOSXGetCGContextForDrawable(
    Drawable drawable)
{
    MacDrawable *macDraw = (MacDrawable *)drawable;

    if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
	const size_t bitsPerComponent = 8;
	size_t bitsPerPixel, bytesPerRow, len;
	CGColorSpaceRef colorspace = NULL;
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
		kCGBitmapByteOrder32Host;
#else
		kCGBitmapByteOrderDefault;
#endif
	char *data;
	CGRect bounds = CGRectMake(0, 0,
		macDraw->size.width, macDraw->size.height);

	if (macDraw->flags & TK_IS_BW_PIXMAP) {
	    bitsPerPixel = 8;
	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateDeviceRGB();
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t)
		macDraw->size.width * bitsPerPixel + 127) >> 3 & ~15;
	len = macDraw->size.height * bytesPerRow;
	data = (char *)ckalloc(len);
	bzero(data, len);
	macDraw->context = CGBitmapContextCreate(data, macDraw->size.width,
		macDraw->size.height, bitsPerComponent, bytesPerRow,
		colorspace, bitmapInfo);
	if (macDraw->context) {
	    CGContextClearRect(macDraw->context, bounds);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    }

    return (macDraw ? macDraw->context : NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawCGImage --
 *
 *	Draw CG image into drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXDrawCGImage(
    Drawable d,
    GC gc,
    CGContextRef context,
    CGImageRef image,
    unsigned long imageForeground,
    unsigned long imageBackground,
    CGRect imageBounds,
    CGRect srcBounds,
    CGRect dstBounds)
{
    MacDrawable *macDraw = (MacDrawable *)d;

    if (macDraw && context && image) {
	CGImageRef subImage = NULL;

	if (!CGRectEqualToRect(imageBounds, srcBounds)) {
	    if (!CGRectContainsRect(imageBounds, srcBounds)) {
		TkMacOSXDbgMsg("Mismatch of sub CGImage bounds");
	    }
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);

	if (CGImageIsMask(image)) {

	    if (macDraw->flags & TK_IS_BW_PIXMAP) {

		/*
		 * Set fill color to black; background comes from the context,
		 * or is transparent.
		 */

		if (imageBackground != transparentColor) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != transparentColor) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
		    CGContextFillRect(context, dstBounds);
		}
		TkMacOSXSetColorInContext(gc, imageForeground, context);
	    }
	}

#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
	CGContextSaveGState(context);
	CGContextSetLineWidth(context, 1.0);
	CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.1);
	CGContextSetRGBFillColor(context, 0, 1, 0, 0.1);
	CGContextFillRect(context, dstBounds);
	CGContextStrokeRect(context, dstBounds);

	CGPoint p[4] = {dstBounds.origin,
	    CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMaxY(dstBounds)),
	    CGPointMake(CGRectGetMinX(dstBounds), CGRectGetMaxY(dstBounds)),
	    CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMinY(dstBounds))
	};

	CGContextStrokeLineSegments(context, p, 4);
	CGContextRestoreGState(context);
	TkMacOSXDbgMsg("Drawing CGImage at (x=%f, y=%f), (w=%f, h=%f)",
		dstBounds.origin.x, dstBounds.origin.y,
		dstBounds.size.width, dstBounds.size.height);
#else /* TK_MAC_DEBUG_IMAGE_DRAWING */
	CGContextSaveGState(context);







|












|









|



|


<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|







>
>
>
>
|
|
<
|
<
<

>
>
>
>
>
>
>
>
|
>
>
|
>
|
>
>
|
|
<
>
>
|
>
>
>
|
<
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|





|

|


|







|
|
|
<
<
<
<

<
|
|
<

<
<
<
<
>
|
<
|
|





|












|
|







<

<
|
<
<
<












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|












|
|
|

|







|

|


|
<





|



|
|

|


















|













|










|















>

>

<
<
|
<
<
<
|




|














<





<







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522




523

524
525

526




527
528

529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557

558

559



560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750


751



752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

772
773
774
775
776

777
778
779
780
781
782
783
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXInitCGDrawing(
    Tcl_Interp *interp,
    int enable,
    int limit)
{
    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}

	if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
		(char *) &cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	cgAntiAliasLimit = limit;

	/*
	 * Piggy-back the themed drawing var init here.
	 */

	if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel",
		(char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
		(char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * BitmapRepFromDrawableRect
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *
 * Results:
 *	Returns an autoreleased NSBitmapRep representing the image of the given
 *      rectangle of the given drawable.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system with
 *      origin at the top left, as used by XImage and CGImage, not bottom
 *      left as used by NSView.
 *
 * Side effects:
 *     None
 *
 *----------------------------------------------------------------------
 */
NSBitmapImageRep*
BitmapRepFromDrawableRect(
        Drawable drawable,
	int x,
	int y,
	unsigned int width,
	unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context=NULL;
    CGImageRef cg_image=NULL, sub_cg_image=NULL;
    NSBitmapImageRep *bitmap_rep=NULL;
    NSView *view=NULL;
    if ( mac_drawable->flags & TK_IS_PIXMAP ) {
	/*
	   This means that the MacDrawable is functioning as a Tk Pixmap, so its view
	   field is NULL.
	*/
	cg_context = GetCGContextForDrawable(drawable);
	CGRect image_rect = CGRectMake(x, y, width, height);
	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if ( sub_cg_image ) {
	    /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if ( cg_image ) {
	    CGImageRelease(cg_image);
	}
    } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {
	/* convert top-left coordinates to NSView coordinates */
	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
				      view_height - height - y - mac_drawable->yOff,
				      width,height);

	if ( [view lockFocusIfCanDraw] ) {
	    /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/
	    bitmap_rep = [NSBitmapImageRep alloc];
	    bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect];
	    [view unlockFocus];
	} else {
	    TkMacOSXDbgMsg("Could not lock focus on view.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyArea --
 *
 *	Copies data from one drawable to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Data is moved from a window or bitmap to a second window or
 *	bitmap.
 *
 *----------------------------------------------------------------------
 */

void
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;

    display->request++;

    if (!width || !height) {
	/* This happens all the time.
	TkMacOSXDbgMsg("Drawing of empty area requested");
	*/
	return;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	return;
	/*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
    }

    if ( dc.context ) {
	if (srcDraw->flags & TK_IS_PIXMAP) {
	    img = TkMacOSXCreateCGImageWithDrawable(src);
	}else if (TkMacOSXDrawableWindow(src)) {
	    bitmap_rep =  BitmapRepFromDrawableRect(src, src_x, src_y, width, height);
	    if ( bitmap_rep ) {
		img = [bitmap_rep CGImage];
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
	}

	if (img) {
	    DrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
			CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
			CGRectMake(src_x, src_y, width, height),
			CGRectMake(dest_x, dest_y, width, height));
	    CFRelease(img);


	} else {
	    TkMacOSXDbgMsg("Failed to construct CGImage.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return;
    }

    TkMacOSXRestoreDrawingContext(&dc);
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyPlane --
 *
 *	Copies a bitmap from a source drawable to a destination
 *	drawable. The plane argument specifies which bit plane of
 *	the source contains the bitmap. Note that this implementation
 *	ignores the gc->function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the destination drawable.
 *
 *----------------------------------------------------------------------
 */

void
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;

    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	    return;
	}
	CGContextRef context = dc.context;
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
			CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
			CGRect rect = CGRectMake(dest_x, dest_y, width, height);
			rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
			CGContextSaveGState(context);
			/* Move the origin of the destination to top left. */
			CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
			CGContextScaleCTM(context, 1, -1);
			/* Fill with the background color, clipping to the mask. */
			CGContextClipToMask(context, rect, mask);
			TkMacOSXSetColorInContext(gc, gc->background, dc.context);
			CGContextFillRect(dc.context, rect);
			/* Fill with the foreground color, clipping to the intersection of img and mask. */
			CGContextClipToMask(context, rect, img);
			TkMacOSXSetColorInContext(gc, gc->foreground, context);
			CGContextFillRect(context, rect);
			CGContextRestoreGState(context);
			CGImageRelease(mask);
			CGImageRelease(img);
		} else {
		    DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
				CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
			    CGRectMake(src_x, src_y, width, height),
			    CGRectMake(dest_x, dest_y, width, height));
		    CGImageRelease(img);
		}
	    } else { /* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
	}
	TkMacOSXRestoreDrawingContext(&dc);
    } else { /* source drawable is a window, not a Pixmap */
	XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of
 *	of the specified drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
TkPutImage(
    unsigned long *colors,	/* Unused on Macintosh. */
    int ncolors,			/* Unused on Macintosh. */
    Display* display,		/* Display. */
    Drawable d,			/* Drawable to place image on. */
    GC gc,				/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	/* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGImageRef img = CreateCGImageWithXImage(image);

	if (img) {
	    DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background,
		    CGRectMake(0, 0, image->width, image->height),
		    CGRectMake(src_x, src_y, width, height),
		    CGRectMake(dest_x, dest_y, width, height));
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(void *info, const void *data, size_t size) {
    ckfree(info);
}

CGImageRef
CreateCGImageWithXImage(

    XImage *image)


{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
    char *data = NULL;
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */

	/* Reverses the sense of the bits */
	static const CGFloat decodeWB[2] = {1, 0};
	decode = decodeWB;


	bitsPerComponent = 1;
	bitsPerPixel = 1;
	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = ckalloc(len));


	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	}
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
	}
    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) |
	    kCGImageAlphaNoneSkipFirst;
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CFRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithDrawable --
 *
 *	Create a CGImage from the given Drawable.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGImageRef
TkMacOSXCreateCGImageWithDrawable(
    Drawable drawable)




{

    CGImageRef img = NULL;
    CGContextRef context = GetCGContextForDrawable(drawable);






    if (context) {
	img = CGBitmapContextCreateImage(context);

    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateNSImageWithPixmap --
 *
 *	Create NSImage for Pixmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static NSImage*
CreateNSImageWithPixmap(
    Pixmap pixmap,
    int width,
    int height)
{
    CGImageRef cgImage;
    NSImage *nsImage;
    NSBitmapImageRep *bitmapImageRep;



    cgImage = TkMacOSXCreateCGImageWithDrawable(pixmap);



    nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
    bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
    [nsImage addRepresentation:bitmapImageRep];
    [bitmapImageRep release];
    CFRelease(cgImage);

    return nsImage;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSImageWithTkImage --
 *
 *	Get autoreleased NSImage for Tk_Image.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSImage*
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSImageWithBitmap --
 *
 *	Get autoreleased NSImage for Bitmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSImage*
TkMacOSXGetNSImageWithBitmap(
    Display *display,
    Pixmap bitmap,
    GC gc,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    gc->background = TRANSPARENT_PIXEL << 24;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * GetCGContextForDrawable --
 *
 *	Get CGContext for given Drawable, creating one if necessary.
 *
 * Results:
 *	CGContext.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGContextRef
GetCGContextForDrawable(
    Drawable d)
{
    MacDrawable *macDraw = (MacDrawable *) d;

    if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
	const size_t bitsPerComponent = 8;
	size_t bitsPerPixel, bytesPerRow, len;
	CGColorSpaceRef colorspace = NULL;
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
	kCGBitmapByteOrder32Host;
#else
	kCGBitmapByteOrderDefault;
#endif
	char *data;
	CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height);


	if (macDraw->flags & TK_IS_BW_PIXMAP) {
	    bitsPerPixel = 8;
	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3
		& ~15;
	len = macDraw->size.height * bytesPerRow;
	data = ckalloc(len);
	bzero(data, len);
	macDraw->context = CGBitmapContextCreate(data, macDraw->size.width,
		macDraw->size.height, bitsPerComponent, bytesPerRow,
		colorspace, bitmapInfo);
	if (macDraw->context) {
	    CGContextClearRect(macDraw->context, bounds);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    }

    return (macDraw ? macDraw->context : NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawCGImage --
 *
 *	Draw CG image into drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
DrawCGImage(
    Drawable d,
    GC gc,
    CGContextRef context,
    CGImageRef image,
    unsigned long imageForeground,
    unsigned long imageBackground,
    CGRect imageBounds,
    CGRect srcBounds,
    CGRect dstBounds)
{
    MacDrawable *macDraw = (MacDrawable *) d;

    if (macDraw && context && image) {
	CGImageRef subImage = NULL;

	if (!CGRectEqualToRect(imageBounds, srcBounds)) {
	    if (!CGRectContainsRect(imageBounds, srcBounds)) {
		TkMacOSXDbgMsg("Mismatch of sub CGImage bounds");
	    }
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);

	if (CGImageIsMask(image)) {
	    /*CGContextSaveGState(context);*/
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {


		/* Set fill color to black, background comes from the context, or is transparent. */



		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
		    CGContextFillRect(context, dstBounds);
		}
		TkMacOSXSetColorInContext(gc, imageForeground, context);
	    }
	}

#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
	CGContextSaveGState(context);
	CGContextSetLineWidth(context, 1.0);
	CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.1);
	CGContextSetRGBFillColor(context, 0, 1, 0, 0.1);
	CGContextFillRect(context, dstBounds);
	CGContextStrokeRect(context, dstBounds);

	CGPoint p[4] = {dstBounds.origin,
	    CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMaxY(dstBounds)),
	    CGPointMake(CGRectGetMinX(dstBounds), CGRectGetMaxY(dstBounds)),
	    CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMinY(dstBounds))
	};

	CGContextStrokeLineSegments(context, p, 4);
	CGContextRestoreGState(context);
	TkMacOSXDbgMsg("Drawing CGImage at (x=%f, y=%f), (w=%f, h=%f)",
		dstBounds.origin.x, dstBounds.origin.y,
		dstBounds.size.width, dstBounds.size.height);
#else /* TK_MAC_DEBUG_IMAGE_DRAWING */
	CGContextSaveGState(context);
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    int mode)			/* Line drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);







|








|







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    int mode)			/* Line drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
			macWin->yOff + points[i].y + o);
	    } else {
		prevx += points[i].x;
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}

        /*
         * In the case of closed polylines, the first and last points are the
         * same. We want miter or bevel join be rendered also at this point,
         * this needs telling CoreGraphics that the path is closed.
         */

        if ((points[0].x == points[npoints-1].x) &&
                (points[0].y == points[npoints-1].y)) {
            CGContextClosePath(dc.context);
        }
	CGContextStrokePath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*







<
<
<
<
<
<
<
<
<
<
<







846
847
848
849
850
851
852











853
854
855
856
857
858
859
			macWin->yOff + points[i].y + o);
	    } else {
		prevx += points[i].x;
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}











	CGContextStrokePath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {
	    CGContextBeginPath(dc.context);







|




|







876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {
	    CGContextBeginPath(dc.context);
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
 *
 * Side effects:
 *	Draws a filled polygon on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XFillPolygon(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    TCL_UNUSED(int),	/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);
	prevx = macWin->xOff + points[0].x + o;







|

|


|

|


|




|
|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
 *
 * Side effects:
 *	Draws a filled polygon on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XFillPolygon(
    Display* display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint* points,		/* Array of points. */
    int npoints,		/* Number of points. */
    int shape,			/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);
	prevx = macWin->xOff + points[0].x + o;
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619

620
621
622
623
624
625
626

627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}
	CGContextEOFillPath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangle --
 *
 *	Draws a rectangle.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a rectangle on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XDrawRectangle(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left corner. */
    unsigned int width,		/* Width & height of rect. */
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
		macWin->xOff + x + o, macWin->yOff + y + o,

		width, height);
	CGContextStrokeRect(dc.context, rect);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangles --
 *
 *	Draws the outlines of the specified rectangles as if a five-point
 *	PolyLine protocol request were specified for each rectangle:

 *
 *	    [x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y]
 *
 *	For the specified rectangles, these functions do not draw a pixel more
 *	than once. XDrawRectangles draws the rectangles in the order listed in
 *	the array. If rectangles intersect, the intersecting pixels are drawn
 *	multiple times. Draws a rectangle.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws rectangles on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XDrawRectangles(
    Display *display,
    Drawable d,
    GC gc,
    XRectangle *rectArr,
    int nRects)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) {
	    if (rectPtr->width == 0 || rectPtr->height == 0) {
		continue;
	    }
	    rect = CGRectMake(
		    macWin->xOff + rectPtr->x + o,
		    macWin->yOff + rectPtr->y + o,
		    rectPtr->width, rectPtr->height);
	    CGContextStrokeRect(dc.context, rect);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XFillRectangles --
 *
 *	Fill multiple rectangular areas in the given drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws onto the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XFillRectangles(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XRectangle *rectangles,	/* Rectangle array. */
    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
	    if (rectPtr->width == 0 || rectPtr->height == 0) {







<


















|








|




|



|
|






|
>




<


>





|
|
>



|
|
|
|
>










|


|




|





|
|

















<

>



















|





|





|







958
959
960
961
962
963
964

965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}
	CGContextEOFillPath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);

}

/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangle --
 *
 *	Draws a rectangle.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a rectangle on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XDrawRectangle(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left corner. */
    unsigned int width,		/* Width & height of rect. */
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
		macWin->xOff + x + o,
		macWin->yOff + y + o,
		width, height);
	CGContextStrokeRect(dc.context, rect);
    }
    TkMacOSXRestoreDrawingContext(&dc);

}

#ifdef TK_MACOSXDRAW_UNUSED
/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangles --
 *
 *	Draws the outlines of the specified rectangles as if a
 *	five-point PolyLine protocol request were specified for each
 *	rectangle:
 *
 *	    [x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y]
 *
 *	For the specified rectangles, these functions do not draw a
 *	pixel more than once. XDrawRectangles draws the rectangles in
 *	the order listed in the array. If rectangles intersect, the
 *	intersecting pixels are drawn multiple times. Draws a
 *	rectangle.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws rectangles on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XDrawRectangles(
    Display *display,
    Drawable drawable,
    GC gc,
    XRectangle *rectArr,
    int nRects)
{
    MacDrawable *macWin = (MacDrawable *) drawable;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) {
	    if (rectPtr->width == 0 || rectPtr->height == 0) {
		continue;
	    }
	    rect = CGRectMake(
		    macWin->xOff + rectPtr->x + o,
		    macWin->yOff + rectPtr->y + o,
		    rectPtr->width, rectPtr->height);
	    CGContextStrokeRect(dc.context, rect);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);

}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XFillRectangles --
 *
 *	Fill multiple rectangular areas in the given drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws onto the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XFillRectangles(
    Display* display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XRectangle *rectangles,	/* Rectangle array. */
    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
	    if (rectPtr->width == 0 || rectPtr->height == 0) {
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawSolidBorder --
 *
 *	Draws a border rectangle of specified thickness inside the bounding
 *      rectangle of a Tk Window.  The border rectangle can be inset within the
 *      bounding rectangle.  For a highlight border the inset should be 0, but
 *      for a solid border around the actual window the inset should equal the
 *      thickness of the highlight border.  The color of the border rectangle
 *      is the foreground color of the graphics context passed to the function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a rectangular border inside the bounding rectangle of a window.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkMacOSXDrawSolidBorder(
    Tk_Window tkwin,
    GC gc,
    int inset,
    int thickness)
{
    Drawable d = Tk_WindowId(tkwin);
    TkMacOSXDrawingContext dc;
    CGRect outerRect, innerRect;

    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return;
    }
    if (dc.context) {
	outerRect = CGRectMake(Tk_X(tkwin), Tk_Y(tkwin),
			       Tk_Width(tkwin), Tk_Height(tkwin));
	outerRect = CGRectInset(outerRect, inset, inset);
	innerRect = CGRectInset(outerRect, thickness, thickness);
	CGContextBeginPath(dc.context);
	CGContextAddRect(dc.context, outerRect);
	CGContextAddRect(dc.context, innerRect);
	CGContextEOFillPath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
}

/*
 *----------------------------------------------------------------------
 *
 * XDrawArc --
 *
 *	Draw an arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws an arc on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XDrawArc(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
		macWin->xOff + x + o,







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|

|








|




|



|
|







1127
1128
1129
1130
1131
1132
1133
















































1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
















































 * XDrawArc --
 *
 *	Draw an arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws an arc on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XDrawArc(
    Display* display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
		macWin->xOff + x + o,
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855

856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
		    radians(-(angle1 + angle2)/64.0), angle2 > 0);
	    CGContextAddPath(dc.context, p);
	    CGPathRelease(p);
	    CGContextStrokePath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XDrawArcs --
 *
 *	Draws multiple circular or elliptical arcs. Each arc is specified by a
 *	rectangle and two angles. The center of the circle or ellipse is the

 *	center of the rect- angle, and the major and minor axes are specified
 *	by the width and height.  Positive angles indicate counterclock- wise
 *	motion, and negative angles indicate clockwise motion. If the magnitude
 *	of angle2 is greater than 360 degrees, XDrawArcs truncates it to 360
 *	degrees.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws an arc for each array element on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{

    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
	    if (arcPtr->width == 0 || arcPtr->height == 0







<


>





|
|
>
|
|
|
|
|










|







>
|





|
|







1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
		    radians(-(angle1 + angle2)/64.0), angle2 > 0);
	    CGContextAddPath(dc.context, p);
	    CGPathRelease(p);
	    CGContextStrokePath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);

}

#ifdef TK_MACOSXDRAW_UNUSED
/*
 *----------------------------------------------------------------------
 *
 * XDrawArcs --
 *
 *	Draws multiple circular or elliptical arcs. Each arc is
 *	specified by a rectangle and two angles. The center of the
 *	circle or ellipse is the center of the rect- angle, and the
 *	major and minor axes are specified by the width and height.
 *	Positive angles indicate counterclock- wise motion, and
 *	negative angles indicate clockwise motion. If the magnitude
 *	of angle2 is greater than 360 degrees, XDrawArcs truncates it
 *	to 360 degrees.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws an arc for each array element on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{

    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
	    if (arcPtr->width == 0 || arcPtr->height == 0
920
921
922
923
924
925
926
927
928

929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
		CGContextAddPath(dc.context, p);
		CGPathRelease(p);
		CGContextStrokePath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XFillArc --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a filled arc on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XFillArc(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
	    o += NON_AA_CG_OFFSET/2;







<

>

















|

|








|




|



|
|







1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
		CGContextAddPath(dc.context, p);
		CGPathRelease(p);
		CGContextStrokePath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);

}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XFillArc --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a filled arc on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XFillArc(
    Display* display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
	    o += NON_AA_CG_OFFSET/2;
999
1000
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
	    CGPathCloseSubpath(p);
	    CGContextAddPath(dc.context, p);
	    CGPathRelease(p);
	    CGContextFillPath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XFillArcs --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a filled arc for each array element on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
	    o += NON_AA_CG_OFFSET/2;







<


>
















|







|





|
|







1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
	    CGPathCloseSubpath(p);
	    CGContextAddPath(dc.context, p);
	    CGPathRelease(p);
	    CGContextFillPath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);

}

#ifdef TK_MACOSXDRAW_UNUSED
/*
 *----------------------------------------------------------------------
 *
 * XFillArcs --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a filled arc for each array element on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

void
XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *) d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
	    o += NON_AA_CG_OFFSET/2;
1081
1082
1083
1084
1085
1086
1087
















1088
1089

1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153





1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

1175














1176



1177







1178
1179
1180
1181
1182
1183
1184
		CGContextAddPath(dc.context, p);
		CGPathRelease(p);
		CGContextFillPath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
















    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate a damage
 *	region.
 *
 * Results:
 *	Returns 0 if the scroll generated no additional damage. Otherwise, sets
 *	the region that needs to be repainted after scrolling and returns 1.

 *
 * Side effects:
 *	Scrolls the bits in the window.
 *
 *----------------------------------------------------------------------
 */

int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    TCL_UNUSED(GC),			/* GC for window to be scrolled. */
    int x, int y,		/* Position rectangle to be scrolled. */
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *)drawable;
    TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;

    if (view) {
  	/*
	 * Get the scroll area in NSView coordinates (origin at bottom left).
	 */

  	bounds = [view bounds];
 	scrollSrc = NSMakeRect(macDraw->xOff + x,

		bounds.size.height - height - (macDraw->yOff + y),
		width, height);
 	scrollDst = NSOffsetRect(scrollSrc, dx, -dy);

  	/*
	 * Limit scrolling to the window content area.
	 */

 	visRect = [view visibleRect];
 	scrollSrc = NSIntersectionRect(scrollSrc, visRect);
 	scrollDst = NSIntersectionRect(scrollDst, visRect);
 	if (!NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst)) {

  	    /*
  	     * Mark the difference between source and destination as damaged.
	     * This region is described in NSView coordinates (y=0 at the
	     * bottom) and converted to Tk coordinates later.
  	     */

	    srcRect = CGRectMake(x, y, width, height);
	    dstRect = CGRectOffset(srcRect, dx, dy);






	    /*
	     * Compute the damage.
	     */

  	    dmgRgn = HIShapeCreateMutableWithRect(&srcRect);
 	    extraRgn = HIShapeCreateWithRect(&dstRect);
 	    ChkErr(HIShapeDifference, dmgRgn, extraRgn,
		    (HIMutableShapeRef) dmgRgn);
	    result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;

	    /*
	     * Convert to Tk coordinates, offset by the window origin.
	     */

	    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
	    if (extraRgn) {
		CFRelease(extraRgn);
	    }

 	    /*
	     * Scroll the rectangle.

	     */


















 	    [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];







  	}
    } else {
	dmgRgn = HIShapeCreateEmpty();
	TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
    }

    if (dmgRgn) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>






|
|


|
|
>










|



|


|
|





|
<
|
<
<

|
>
|
|


<
|
<
<



|
>


|
|





>
>
>
>
>
|
|
<
<


|
<


<
|
<
<





<
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>







1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498

1499


1500
1501
1502
1503
1504
1505
1506

1507


1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528


1529
1530
1531

1532
1533

1534


1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
		CGContextAddPath(dc.context, p);
		CGPathRelease(p);
		CGContextFillPath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
}
#endif

#ifdef TK_MACOSXDRAW_UNUSED
/*
 *----------------------------------------------------------------------
 *
 * XMaxRequestSize --
 *
 *----------------------------------------------------------------------
 */

long
XMaxRequestSize(
    Display *display)
{
    return (SHRT_MAX / 4);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate
 *	a damage region.
 *
 * Results:
 *	Returns 0 if the scroll genereated no additional damage.
 *	Otherwise, sets the region that needs to be repainted after
 *	scrolling and returns 1.
 *
 * Side effects:
 *	Scrolls the bits in the window.
 *
 *----------------------------------------------------------------------
 */

int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y,		/* Position rectangle to be scrolled. */
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *) drawable;
    TKContentView *view = (TKContentView *)TkMacOSXDrawableView(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;

    if ( view ) {

  	/*  Get the scroll area in NSView coordinates (origin at bottom left). */


  	bounds = [view bounds];
 	scrollSrc = NSMakeRect(
			       macDraw->xOff + x,
			       bounds.size.height - height - (macDraw->yOff + y),
			       width, height);
 	scrollDst = NSOffsetRect(scrollSrc, dx, -dy);


  	/* Limit scrolling to the window content area. */


 	visRect = [view visibleRect];
 	scrollSrc = NSIntersectionRect(scrollSrc, visRect);
 	scrollDst = NSIntersectionRect(scrollDst, visRect);
 	if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) {

  	    /*
  	     * Mark the difference between source and destination as damaged.
	     * This region is described in NSView coordinates (y=0 at the bottom)
	     * and converted to Tk coordinates later.
  	     */

	    srcRect = CGRectMake(x, y, width, height);
	    dstRect = CGRectOffset(srcRect, dx, dy);

	    /* Expand the rectangles slightly to avoid degeneracies. */
	    srcRect.origin.y -= 1;
	    srcRect.size.height += 2;
	    dstRect.origin.y += 1;
	    dstRect.size.height -= 2;

	    /* Compute the damage. */


  	    dmgRgn = HIShapeCreateMutableWithRect(&srcRect);
 	    extraRgn = HIShapeCreateWithRect(&dstRect);
 	    ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn);

	    result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;


	    /* Convert to Tk coordinates. */


	    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
	    if (extraRgn) {
		CFRelease(extraRgn);
	    }


 	    /* Scroll the rectangle. */
 	    [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];

	    /* Shift the Tk children which meet the source rectangle. */
	    TkWindow *winPtr = (TkWindow *)tkwin;
	    TkWindow *childPtr;
	    CGRect childBounds;
	    for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) {
		if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) {
		    TkMacOSXWinCGBounds(childPtr, &childBounds);
		    if (CGRectIntersectsRect(srcRect, childBounds)) {
			MacDrawable *macChild = childPtr->privatePtr;
			if (macChild) {
			    macChild->yOff += dy;
			    macChild->xOff += dx;
			    childPtr->changes.y = macChild->yOff;
			    childPtr->changes.x = macChild->xOff;
			}
		    }
		}
	    }

	    /* Queue up Expose events for the damage region. */
	    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
	    [view generateExposeEvents:dmgRgn childrenOnly:1];
	    Tcl_SetServiceMode(oldMode);

	    /* Belt and suspenders: make the AppKit request a redraw
	       when it gets control again. */
  	}
    } else {
	dmgRgn = HIShapeCreateEmpty();
	TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
    }

    if (dmgRgn) {
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235

1236
1237
1238

1239
1240
1241
1242
1243
1244

1245
1246









1247
1248
1249
1250
1251





1252

















1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389


1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetUpGraphicsPort(
    TCL_UNUSED(GC),			/* GC to apply to current port. */
    TCL_UNUSED(void *))
{
    Tcl_Panic("TkMacOSXSetUpGraphicsPort: Obsolete, no more QD!");
}


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpDrawingContext --
 *
 *	Set up a drawing context for the given drawable from an X GC.
 *
 * Results:
 *	Boolean indicating whether it is ok to draw; if false, the drawing
 *	context was not setup, so do not attempt to draw and do not call
 *	TkMacOSXRestoreDrawingContext().
 *
 * Side effects:
 *	May modify or create the drawable's graphics context.  May expand the
 *      drawable's dirty rectangle.  When the result is true The dcPtr
 *      parameter is set to reference the new or updated drawing context.
 *
 *----------------------------------------------------------------------
 */

Bool

TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,

    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = (MacDrawable *)d;
    Bool canDraw = true;
    TKContentView *view = nil;
    TkMacOSXDrawingContext dc = {};


    /*









     * If the drawable is not a pixmap, get the associated NSView.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	view = (TKContentView *)TkMacOSXGetNSViewForDrawable(d);





	if (!view) {

















	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    }

    /*
     * Intersect the drawable's clipping region with the region stored in the
     * X GC.  If the resulting region is empty, don't do any drawing.
     */

    dc.clipRgn = TkMacOSXGetClipRgn(d);
    ClipToGC(d, gc, &dc.clipRgn);
    if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) {
	canDraw = false;
	goto end;
    }

    /*
     * If the drawable already has a CGContext, use it.  Otherwise, we must be
     * drawing to a window and we use the current context of its ContentView.
     */

    dc.context = TkMacOSXGetCGContextForDrawable(d);
    if (dc.context) {
	dc.portBounds = CGContextGetClipBoundingBox(dc.context);
    } else {
	NSRect drawingBounds, currentBounds;

	dc.view = view;
	dc.context = GET_CGCONTEXT;
	dc.portBounds = NSRectToCGRect([view bounds]);
	if (dc.clipRgn) {
	    CGRect clipBounds;
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
				    .ty = [view bounds].size.height};
	    HIShapeGetBounds(dc.clipRgn, &clipBounds);
	    clipBounds = CGRectApplyAffineTransform(clipBounds, t);
	    drawingBounds = NSRectFromCGRect(clipBounds);
	} else {
	    drawingBounds = [view bounds];
	}

	/*
	 * We can only draw into the NSView which is the current focusView.
	 * When the current [NSView focusView] is nil, the CGContext for
	 * [NSGraphicsContext currentContext] is nil.  Otherwise the current
	 * CGContext draws into the current focusView.  An NSView is guaranteed
	 * to be the focusView when its drawRect or setFrame methods are
	 * running.  Prior to OSX 10.14 it was also possible to call the
	 * lockFocus method to force an NSView to become the current focusView.
	 * But that method was deprecated in 10.14 and so is no longer used by
	 * Tk.  Instead, if the view is not the current focusView then we add
	 * the drawing bounds to its dirty rectangle and return false.  The
	 * part of the view inside the drawing bounds will get redrawn during
	 * the next call to its drawRect method.
	 */

	if (view != [NSView focusView]) {
	    [view addTkDirtyRect:drawingBounds];
	    canDraw = false;
	    goto end;
	}

	/*
	 * Drawing will also fail when the view is the current focusView but
	 * the clipping rectangle set by drawRect does not contain the clipping
	 * region of our drawing context.  (See bug [2a61eca3a8].)  If part of
	 * the drawing bounds will be clipped then we draw whatever we can, but
	 * we also add the drawing bounds to the view's dirty rectangle so it
	 * will get redrawn in the next call to its drawRect method.
	 */

	currentBounds = CGContextGetClipBoundingBox(dc.context);
	if (!NSContainsRect(currentBounds, drawingBounds)) {
	    [view addTkDirtyRect:drawingBounds];
	}
    }

    /*
     * Finish configuring the drawing context.
     */

    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0,
	.ty = dc.portBounds.size.height
    };

    dc.portBounds.origin.x += macDraw->xOff;
    dc.portBounds.origin.y += macDraw->yOff;
    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    CGContextConcatCTM(dc.context, t);
    if (dc.clipRgn) {

#ifdef TK_MAC_DEBUG_DRAWING
	CGContextSaveGState(dc.context);
	ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	CGContextEOFillPath(dc.context);
	CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */

	CGRect r;
	CGRect b = CGRectApplyAffineTransform(
	    CGContextGetClipBoundingBox(dc.context), t);
	if (!HIShapeIsRectangular(dc.clipRgn) ||
	    !CGRectContainsRect(*HIShapeGetBounds(dc.clipRgn, &r), b)) {

	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextEOClip(dc.context);
	}
    }
    if (gc) {
	static const CGLineCap cgCap[] = {
	    [CapNotLast] = kCGLineCapButt,
	    [CapButt] = kCGLineCapButt,
	    [CapRound] = kCGLineCapRound,
	    [CapProjecting] = kCGLineCapSquare,
	};
	static const CGLineJoin cgJoin[] = {
	    [JoinMiter] = kCGLineJoinMiter,
	    [JoinRound] = kCGLineJoinRound,
	    [JoinBevel] = kCGLineJoinBevel,
	};
	bool shouldAntialias = !notAA(gc->line_width);
	double w = gc->line_width;

	TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	if (view) {
	    CGContextSetPatternPhase(dc.context, CGSizeMake(
	        dc.portBounds.size.width, dc.portBounds.size.height));
	}
	if (gc->function != GXcopy) {
	    TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			   "not supported for CG drawing!");
	}


	if (!shouldAntialias) {

	    /*
	     * Make non-antialiased CG drawing look more like X11.
	     */

	    w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	}
	CGContextSetShouldAntialias(dc.context, shouldAntialias);
	CGContextSetLineWidth(dc.context, w);
	if (gc->line_style != LineSolid) {
	    int num = 0;
	    char *p = &gc->dashes;
	    CGFloat dashOffset = gc->dash_offset;
	    dashOffset -= (gc->line_width % 2) ? 0.5 : 0.0;
	    CGFloat lengths[10];

	    while (p[num] != '\0' && num < 10) {
		lengths[num] = p[num];
		num++;
	    }
	    CGContextSetLineDash(dc.context, dashOffset, lengths, num);
	}
	if ((unsigned) gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) {
	    CGContextSetLineCap(dc.context, cgCap[(unsigned) gc->cap_style]);

	}
	if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
	    CGContextSetLineJoin(dc.context, cgJoin[(unsigned) gc->join_style]);

	}
    }

end:

#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);

	if (winPtr) {
	    fprintf(stderr, "Cannot draw in %s - postponing.\n",
		    Tk_PathName(winPtr));
	}
    }
#endif

    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return canDraw;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *







|
|










|


|




|
<
<




<
>



>


|
|
<

>

<
>
>
>
>
>
>
>
>
>
|
<
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<

<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<

|
|
|
|
|

<
|
<
<
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
>
>
|
<
<
|
<
<
|
|
|
|
|
|
|
|
<
|

|
|
|
|
|
|
|
|
>
|
|
|
>
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
|




|







1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619


1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674

1675




1676






1677




1678

1679









1680
1681
1682





1683














1684





1685








1686




















1687
1688
1689

1690
1691
1692
1693
1694
1695
1696

1697


1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731


1732


1733
1734
1735
1736
1737
1738
1739
1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759












1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetUpGraphicsPort(
    GC gc,			/* GC to apply to current port. */
    void *destPort)
{
    Tcl_Panic("TkMacOSXSetUpGraphicsPort: Obsolete, no more QD!");
}


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpDrawingContext --
 *
 *	Set up a drawing context for the given drawable and GC.
 *
 * Results:
 *	Boolean indicating whether it is ok to draw; if false, drawing
 *	context was not setup, so do not attempt to draw and do not call
 *	TkMacOSXRestoreDrawingContext().
 *
 * Side effects:
 *	None.


 *
 *----------------------------------------------------------------------
 */


int
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG, /* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = ((MacDrawable*)d);
    int dontDraw = 0, isWin = 0;

    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;


    dc.clipRgn = TkMacOSXGetClipRgn(d);
    if (!dontDraw) {
	ClipToGC(d, gc, &dc.clipRgn);
	dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
    }
    if (dontDraw) {
	goto end;
    }
    if (useCG) {
	dc.context = GetCGContextForDrawable(d);

    }
    if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
	isWin = (TkMacOSXDrawableWindow(d) != nil);
    }
    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (isWin) {
	NSView *view = TkMacOSXDrawableView(macDraw);
	if (view) {
	    if (view != [NSView focusView]) {
		dc.focusLocked = [view lockFocusIfCanDraw];
		dontDraw = !dc.focusLocked;
	    } else {
		dontDraw = ![view canDraw];
	    }
	    if (dontDraw) {
		goto end;
	    }
	    [[view window] disableFlushWindow];
	    dc.view = view;
	    dc.context = [[NSGraphicsContext currentContext] graphicsPort];
	    dc.portBounds = NSRectToCGRect([view bounds]);
	    if (dc.clipRgn) {
		clipBounds = CGContextGetClipBoundingBox(dc.context);
	    }
	} else {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}

    } else {




	Tcl_Panic("TkMacOSXSetupDrawingContext(): "






		"no context to draw into !");




    }

    if (dc.context) {









	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
		.ty = dc.portBounds.size.height};
	dc.portBounds.origin.x += macDraw->xOff;





	dc.portBounds.origin.y += macDraw->yOff;














	if (!dc.focusLocked) {





	    CGContextSaveGState(dc.context);








	}




















	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {

#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	    CGContextEOFillPath(dc.context);
	    CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */

	    CGRect r;


	    if (!HIShapeIsRectangular(dc.clipRgn) || !CGRectContainsRect(
		    *HIShapeGetBounds(dc.clipRgn, &r),
		    CGRectApplyAffineTransform(clipBounds, t))) {
		ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
		CGContextEOClip(dc.context);
	    }
	}
	if (gc) {
	    static const CGLineCap cgCap[] = {
		[CapNotLast] = kCGLineCapButt,
		[CapButt] = kCGLineCapButt,
		[CapRound] = kCGLineCapRound,
		[CapProjecting] = kCGLineCapSquare,
	    };
	    static const CGLineJoin cgJoin[] = {
		[JoinMiter] = kCGLineJoinMiter,
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (isWin) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if(gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }
	    /* When should we antialias? */
	    shouldAntialias = !notAA(gc->line_width);
	    if (!shouldAntialias) {


		/* Make non-antialiased CG drawing look more like X11 */


		w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	    }
	    CGContextSetShouldAntialias(dc.context, shouldAntialias);
	    CGContextSetLineWidth(dc.context, w);
	    if (gc->line_style != LineSolid) {
		int num = 0;
		char *p = &(gc->dashes);
		CGFloat dashOffset = gc->dash_offset;

		CGFloat lengths[10];

		while (p[num] != '\0' && num < 10) {
		    lengths[num] = p[num];
		    num++;
		}
		CGContextSetLineDash(dc.context, dashOffset, lengths, num);
	    }
	    if ((unsigned)gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) {
		CGContextSetLineCap(dc.context,
			cgCap[(unsigned)gc->cap_style]);
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
			cgJoin[(unsigned)gc->join_style]);
	    }
	}
    }
end:












    if (dontDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return !dontDraw;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *
1457
1458
1459
1460
1461
1462
1463





1464

1465
1466
1467
1468
1469
1470
1471

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);





	CGContextRestoreGState(dcPtr->context);

    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */







>
>
>
>
>
|
>







1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	[[dcPtr->view window] setViewsNeedDisplay:YES];
	[[dcPtr->view window] enableFlushWindow];
	if (dcPtr->focusLocked) {
	    [dcPtr->view unlockFocus];
	} else {
	    CGContextRestoreGState(dcPtr->context);
	}
    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503

1504
1505
1506
1507
1508
1509
1510
1511
1512


1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526























1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548

1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567











1568
1569
1570
1571
1572
1573
1574
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetClipRgn(
    Drawable drawable)		/* Drawable. */
{
    MacDrawable *macDraw = (MacDrawable *)drawable;
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);

	NSView *view = TkMacOSXGetNSViewForDrawable(macDraw);

	CGContextRef context = GET_CGCONTEXT;

	CGContextSaveGState(context);
	CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
	      -1.0, 0.0, [view bounds].size.height));
	ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	CGContextEOFillPath(context);
	CGContextRestoreGState(context);


#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
    }
    return clipRgn;
}

/*
 *----------------------------------------------------------------------
 *























 * TkpClipDrawableToRect --
 *
 *	Clip all drawing into the drawable d to the given rectangle. If width
 *	or height are negative, reset to no clipping.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Subsequent drawing into d is offset and clipped as specified.
 *
 *----------------------------------------------------------------------
 */

void
TkpClipDrawableToRect(
    TCL_UNUSED(Display *),
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *)d;


    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
	}
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;











	}
    }
}

/*
 *----------------------------------------------------------------------
 *







|






<
|
>
|
<
|
|
|
|
|
|
|
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|












|




|
>





>














>
>
>
>
>
>
>
>
>
>
>







1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833

1834
1835
1836

1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetClipRgn(
    Drawable drawable)		/* Drawable. */
{
    MacDrawable *macDraw = (MacDrawable *) drawable;
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);

	NSView *view = TkMacOSXDrawableView(macDraw);
	if ([view lockFocusIfCanDraw]) {
	    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];

	    CGContextSaveGState(context);
	    CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
		    -1.0, 0.0, [view bounds].size.height));
	    ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	    CGContextEOFillPath(context);
	    CGContextRestoreGState(context);
	    [view unlockFocus];
	}
#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
    }
    return clipRgn;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpClippingRgn --
 *
 *	Set up the clipping region so that drawing only occurs on the
 *	specified X subwindow.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetUpClippingRgn(
    Drawable drawable)		/* Drawable to update. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClipDrawableToRect --
 *
 *	Clip all drawing into the drawable d to the given rectangle.
 *	If width or height are negative, reset to no clipping.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Subsequent drawing into d is offset and clipped as specified.
 *
 *----------------------------------------------------------------------
 */

void
TkpClipDrawableToRect(
    Display *display,
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    NSView *view = TkMacOSXDrawableView(macDraw);

    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
	}
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;
	}
	if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) {
	    clipRect.origin.y = [view bounds].size.height -
		    (clipRect.origin.y + clipRect.size.height);
	    NSRectClip(NSRectFromCGRect(clipRect));
	    macDraw->flags |= TK_FOCUSED_VIEW;
	}
    } else {
	if (view && (macDraw->flags & TK_FOCUSED_VIEW)) {
	    [view unlockFocus];
	    macDraw->flags &= ~TK_FOCUSED_VIEW;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621

1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
static void
ClipToGC(
    Drawable d,
    GC gc,
    HIShapeRef *clipRgnPtr) /* must point to initialized variable */
{
    if (gc && gc->clip_mask &&
	    ((TkpClipMask *)gc->clip_mask)->type == TKP_CLIP_REGION) {
	Region gcClip = ((TkpClipMask *)gc->clip_mask)->value.region;
	int xOffset = ((MacDrawable *)d)->xOff + gc->clip_x_origin;
	int yOffset = ((MacDrawable *)d)->yOff + gc->clip_y_origin;
	HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn;

	XOffsetRegion(gcClip, xOffset, yOffset);
	gcClipRgn = TkMacOSXGetNativeRegion(gcClip);
	if (clipRgn) {
	    *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn);
	    CFRelease(clipRgn);
	} else {
	    *clipRgnPtr = HIShapeCreateCopy(gcClipRgn);
	}
	CFRelease(gcClipRgn);
	XOffsetRegion(gcClip, -xOffset, -yOffset);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXMakeStippleMap --
 *
 *	Given a drawable and a stipple pattern this function draws the pattern
 *	repeatedly over the drawable. The drawable can then be used as a mask
 *	for bit-bliting a stipple pattern over an object.

 *
 * Results:
 *	A BitMap data structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXMakeStippleMap(
    TCL_UNUSED(Drawable),	/* Window to apply stipple. */
    TCL_UNUSED(Drawable))	/* The stipple pattern. */
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
 *
 *	This procedure draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *	On the Macintosh, this puts a 1 pixel border in the bgGC color between
 *	the widget and the focus ring, except in the case where highlightWidth
 *	is 1, in which case the border is left out.
 *
 *	For proper Mac L&F, use highlightWidth of 3.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawHighlightBorder (
    Tk_Window tkwin,







|
|
|
|


|








|








|
|
|
>












|
|









|
|

|
|
|







|
|







1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
static void
ClipToGC(
    Drawable d,
    GC gc,
    HIShapeRef *clipRgnPtr) /* must point to initialized variable */
{
    if (gc && gc->clip_mask &&
	    ((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
	TkRegion gcClip = ((TkpClipMask*)gc->clip_mask)->value.region;
	int xOffset = ((MacDrawable *) d)->xOff + gc->clip_x_origin;
	int yOffset = ((MacDrawable *) d)->yOff + gc->clip_y_origin;
	HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn;

	TkMacOSXOffsetRegion(gcClip, xOffset, yOffset);
	gcClipRgn = TkMacOSXGetNativeRegion(gcClip);
	if (clipRgn) {
	    *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn);
	    CFRelease(clipRgn);
	} else {
	    *clipRgnPtr = HIShapeCreateCopy(gcClipRgn);
	}
	CFRelease(gcClipRgn);
	TkMacOSXOffsetRegion(gcClip, -xOffset, -yOffset);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXMakeStippleMap --
 *
 *	Given a drawable and a stipple pattern this function draws the
 *	pattern repeatedly over the drawable. The drawable can then
 *	be used as a mask for bit-bliting a stipple pattern over an
 *	object.
 *
 * Results:
 *	A BitMap data structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXMakeStippleMap(
    Drawable drawable,		/* Window to apply stipple. */
    Drawable stipple)		/* The stipple pattern. */
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
 *
 *	This procedure draws a rectangular ring around the outside of
 *	a widget to indicate that it has received the input focus.
 *
 *	On the Macintosh, this puts a 1 pixel border in the bgGC color
 *	between the widget and the focus ring, except in the case where
 *	highlightWidth is 1, in which case the border is left out.
 *
 *	For proper Mac L&F, use highlightWidth of 3.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable",
 *	corresponding to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawHighlightBorder (
    Tk_Window tkwin,
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

1722
1723

1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 *
 *	This procedure draws the rectangular frame area. If the user has
 *	requested themeing, it draws with the background theme.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrameEx(
    Tk_Window tkwin,
    Drawable drawable,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    if (useThemedToplevel && Tk_IsTopLevel(tkwin)) {
	static Tk_3DBorder themedBorder = NULL;

	if (!themedBorder) {
	    themedBorder = Tk_Get3DBorder(NULL, tkwin,
		    "systemWindowHeaderBackground");
	}
	if (themedBorder) {
	    border = themedBorder;
	}
    }

    Tk_Fill3DRectangle(tkwin, drawable, border, highlightWidth,

	    highlightWidth, Tk_Width(tkwin) - 2 * highlightWidth,
	    Tk_Height(tkwin) - 2 * highlightWidth, borderWidth, relief);

}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

|
|











|

<

















|
>
|
|
>










2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072

2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrame --
 *
 *	This procedure draws the rectangular frame area. If the user
 *	has requested themeing, it draws with the background theme.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrame(
    Tk_Window tkwin,

    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    if (useThemedToplevel && Tk_IsTopLevel(tkwin)) {
	static Tk_3DBorder themedBorder = NULL;

	if (!themedBorder) {
	    themedBorder = Tk_Get3DBorder(NULL, tkwin,
		    "systemWindowHeaderBackground");
	}
	if (themedBorder) {
	    border = themedBorder;
	}
    }

    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
	    border, highlightWidth, highlightWidth,
	    Tk_Width(tkwin) - 2 * highlightWidth,
	    Tk_Height(tkwin) - 2 * highlightWidth,
	    borderWidth, relief);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXEmbed.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkBusy.h"

/*
 * One of the following structures exists for each container in this
 * application. It keeps track of the container window and its associated
 * embedded window.
 */








|


<







9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */ 

#include "tkMacOSXPrivate.h"


/*
 * One of the following structures exists for each container in this
 * application. It keeps track of the container window and its associated
 * embedded window.
 */

39
40
41
42
43
44
45





46
47
48
49
50
51
52
53
54
55
56
57
58
59





































60
61
62
63
64
65
66
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

static Container *firstContainerPtr = NULL;
				/* First in list of all containers managed by
				 * this process. */






/*
 * Prototypes for static procedures defined in this file:
 */

static void	ContainerEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbeddedEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedActivateProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedFocusProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedGeometryRequest(Container *containerPtr, int width,
		    int height);
static void	EmbedSendConfigure(Container *containerPtr);
static void	EmbedStructureProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedWindowDeleted(TkWindow *winPtr);






































/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Creates an X Window (Mac subwindow).







>
>
>
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

static Container *firstContainerPtr = NULL;
				/* First in list of all containers managed by
				 * this process. */
/*
 * Globals defined in this file:
 */

TkMacOSXEmbedHandler *tkMacOSXEmbedHandler = NULL;

/*
 * Prototypes for static procedures defined in this file:
 */

static void	ContainerEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbeddedEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedActivateProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedFocusProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedGeometryRequest(Container *containerPtr, int width,
		    int height);
static void	EmbedSendConfigure(Container *containerPtr);
static void	EmbedStructureProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedWindowDeleted(TkWindow *winPtr);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXSetEmbedHandler --
 *
 *	Registers a handler for an in process form of embedding, like Netscape
 *	plugins, where Tk is loaded into the process, but does not control the
 *	main window
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The embed handler is set.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXSetEmbedHandler(
    Tk_MacOSXEmbedRegisterWinProc *registerWinProc,
    Tk_MacOSXEmbedGetGrafPortProc *getPortProc,
    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc,
    Tk_MacOSXEmbedGetClipProc *getClipProc,
    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
{
    if (tkMacOSXEmbedHandler == NULL) {
	tkMacOSXEmbedHandler = (TkMacOSXEmbedHandler *)
		ckalloc(sizeof(TkMacOSXEmbedHandler));
    }
    tkMacOSXEmbedHandler->registerWinProc = registerWinProc;
    tkMacOSXEmbedHandler->getPortProc = getPortProc;
    tkMacOSXEmbedHandler->containerExistProc = containerExistProc;
    tkMacOSXEmbedHandler->getClipProc = getClipProc;
    tkMacOSXEmbedHandler->getOffsetProc = getOffsetProc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Creates an X Window (Mac subwindow).
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

Window
TkpMakeWindow(
    TkWindow *winPtr,
    Window parent)
{
    MacDrawable *macWin;
    (void)parent;

    /*
     * If this window is marked as embedded then the window structure should
     * have already been created in the TkpUseWindow function.
     */

    if (Tk_IsEmbedded(winPtr)) {
	macWin = winPtr->privatePtr;
    } else {
	/*
	 * Allocate sub window
	 */

	macWin = (MacDrawable *)ckalloc(sizeof(MacDrawable));
	if (macWin == NULL) {
	    winPtr->privatePtr = NULL;
	    return None;
	}
	macWin->winPtr = winPtr;
	winPtr->privatePtr = macWin;
	macWin->visRgn = NULL;







<













|







117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

Window
TkpMakeWindow(
    TkWindow *winPtr,
    Window parent)
{
    MacDrawable *macWin;


    /*
     * If this window is marked as embedded then the window structure should
     * have already been created in the TkpUseWindow function.
     */

    if (Tk_IsEmbedded(winPtr)) {
	macWin = winPtr->privatePtr;
    } else {
	/*
	 * Allocate sub window
	 */

	macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable));
	if (macWin == NULL) {
	    winPtr->privatePtr = NULL;
	    return None;
	}
	macWin->winPtr = winPtr;
	winPtr->privatePtr = macWin;
	macWin->visRgn = NULL;
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,
    const char * string,
    Window *idPtr)
{
    int code;
    Tcl_Obj obj;

    obj.refCount = 1;
    obj.bytes = (char *) string;	/* DANGER?! */







|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,
    CONST char * string,
    Window *idPtr)
{
    int code;
    Tcl_Obj obj;

    obj.refCount = 1;
    obj.bytes = (char *) string;	/* DANGER?! */
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250



251

252
253


254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275










276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

































296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    MacDrawable *parent, *macWin;
    Container *containerPtr;

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }

    /*
     * Decode the container window ID, and look for it among the list of
     * available containers.
     *
     * N.B. For now, we are limiting the containers to be in the same Tk
     * application as tkwin, since otherwise they would not be in our list of
     * containers.
     */

    if (TkpScanWindowId(interp, string, (Window *)&parent) != TCL_OK) {
	return TCL_ERROR;
    }

    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) parent);
    if (usePtr == NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't create child of window \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "NO_TARGET", NULL);
	}
	return TCL_ERROR;
    } else if (!(usePtr->flags & TK_CONTAINER)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" doesn't have -container option set",
		usePtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL);
	return TCL_ERROR;
    }


    /*



     * Since we do not allow embedding into windows belonging to a different

     * process, we know that a container will exist showing the parent window
     * as the parent.  This loop finds that container.


     */

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parent == (Window) parent) {
	    winPtr->flags |= TK_BOTH_HALVES;
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    break;
	}
    }

    /*
     * Make the embedded window.
     */

    macWin = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    if (macWin == NULL) {
	winPtr->privatePtr = NULL;
	return TCL_ERROR;
    }

    macWin->winPtr = winPtr;










    macWin->view = nil;
    macWin->context = NULL;
    macWin->size = CGSizeZero;
    macWin->visRgn = NULL;
    macWin->aboveVisRgn = NULL;
    macWin->drawRgn = NULL;
    macWin->referenceCount = 0;
    macWin->flags = TK_CLIP_INVALID;
    macWin->toplevel = macWin;
    macWin->toplevel->referenceCount++;

    winPtr->privatePtr = macWin;
    winPtr->flags |= TK_EMBEDDED;

    /*
     * Make a copy of the TK_EMBEDDED flag, since sometimes we need this to
     * get the port after the TkWindow structure has been freed.
     */

    macWin->flags |= TK_EMBEDDED;

































    macWin->xOff = parent->winPtr->privatePtr->xOff +
	    parent->winPtr->changes.border_width +
	    winPtr->changes.x;
    macWin->yOff = parent->winPtr->privatePtr->yOff +
	    parent->winPtr->changes.border_width +
	    winPtr->changes.y;

    /*
     * Finish filling up the container structure with the embedded window's
     * information.
     */

    containerPtr->embedded = (Window) macWin;
    containerPtr->embeddedPtr = macWin->winPtr;

    /*
     * Create an event handler to clean up the Container structure when
     * tkwin is eventually deleted.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    EmbeddedEventProc, winPtr);


    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<
|
|

















|
<
<
<
<
<
<
|
|
|
<
<
|
|
|
>

>
>
>
|
>
|
|
>
>















|






>
>
>
>
>
>
>
>
>
>











<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|

|
|
|
|

|
|

|
|
|
|

|
|
>







248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274






275
276
277


278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    MacDrawable *parent, *macWin;
    Container *containerPtr;

    if (winPtr->window != None) {

	Tcl_AppendResult(interp, "can't modify container after widget is "
		"created", NULL);
	return TCL_ERROR;
    }

    /*
     * Decode the container window ID, and look for it among the list of
     * available containers.
     *
     * N.B. For now, we are limiting the containers to be in the same Tk
     * application as tkwin, since otherwise they would not be in our list of
     * containers.
     */

    if (TkpScanWindowId(interp, string, (Window *)&parent) != TCL_OK) {
	return TCL_ERROR;
    }

    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) parent);
    if (usePtr != NULL) {






	if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
		    "\" doesn't have -container option set", NULL);


	    return TCL_ERROR;
	}
    }

    /*
     * The code below can probably be simplified given we have already
     * discovered 'usePtr' above.
     */

    /*
     * Save information about the container and the embedded window in a
     * Container structure. Currently, there must already be an existing
     * Container structure, since we only allow the case where both container
     * and embedded app. are in the same process.
     */

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parent == (Window) parent) {
	    winPtr->flags |= TK_BOTH_HALVES;
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    break;
	}
    }

    /*
     * Make the embedded window.
     */

    macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable));
    if (macWin == NULL) {
	winPtr->privatePtr = NULL;
	return TCL_ERROR;
    }

    macWin->winPtr = winPtr;
    winPtr->privatePtr = macWin;

    /*
     * The grafPtr will be NULL for a Tk in Tk embedded window. It is none of
     * our business what it is for a Tk not in Tk embedded window, but we will
     * initialize it to NULL, and let the registerWinProc set it. In any case,
     * you must always use TkMacOSXGetDrawablePort to get the portPtr. It will
     * correctly find the container's port.
     */

    macWin->view = nil;
    macWin->context = NULL;
    macWin->size = CGSizeZero;
    macWin->visRgn = NULL;
    macWin->aboveVisRgn = NULL;
    macWin->drawRgn = NULL;
    macWin->referenceCount = 0;
    macWin->flags = TK_CLIP_INVALID;
    macWin->toplevel = macWin;
    macWin->toplevel->referenceCount++;


    winPtr->flags |= TK_EMBEDDED;

    /*
     * Make a copy of the TK_EMBEDDED flag, since sometimes we need this to
     * get the port after the TkWindow structure has been freed.
     */

    macWin->flags |= TK_EMBEDDED;

    /*
     * Now check whether it is embedded in another Tk widget. If not (the
     * first case below) we see if there is an in-process embedding handler
     * registered, and if so, let that fill in the rest of the macWin.
     */

    if (containerPtr == NULL) {
	/*
	 * If someone has registered an in process embedding handler, then
	 * see if it can handle this window...
	 */

	if (tkMacOSXEmbedHandler == NULL ||
		tkMacOSXEmbedHandler->registerWinProc((long) parent,
		(Tk_Window) winPtr) != TCL_OK) {
	    Tcl_AppendResult(interp, "The window ID ", string,
		    " does not correspond to a valid Tk Window.", NULL);
	    return TCL_ERROR;
	} else {
	    containerPtr = (Container *) ckalloc(sizeof(Container));

	    containerPtr->parentPtr = NULL;
	    containerPtr->embedded = (Window) macWin;
	    containerPtr->embeddedPtr = macWin->winPtr;
	    containerPtr->nextPtr = firstContainerPtr;
	    firstContainerPtr = containerPtr;
	}
    } else {
	/*
	 * The window is embedded in another Tk window.
	 */

	macWin->xOff = parent->winPtr->privatePtr->xOff +
		parent->winPtr->changes.border_width +
		winPtr->changes.x;
	macWin->yOff = parent->winPtr->privatePtr->yOff +
		parent->winPtr->changes.border_width +
		winPtr->changes.y;

	/*
	 * Finish filling up the container structure with the embedded
	 * window's information.
	 */

	containerPtr->embedded = (Window) macWin;
	containerPtr->embeddedPtr = macWin->winPtr;

	/*
	 * Create an event handler to clean up the Container structure when
	 * tkwin is eventually deleted.
	 */

	Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
		winPtr);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

    /*
     * Register the window as a container so that, for example, we can make
     * sure the argument to -use is valid.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *)ckalloc(sizeof(Container));
    containerPtr->parent = Tk_WindowId(tkwin);
    containerPtr->parentPtr = winPtr;
    containerPtr->embedded = None;
    containerPtr->embeddedPtr = NULL;
    containerPtr->nextPtr = firstContainerPtr;
    firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;







|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

    /*
     * Register the window as a container so that, for example, we can make
     * sure the argument to -use is valid.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *) ckalloc(sizeof(Container));
    containerPtr->parent = Tk_WindowId(tkwin);
    containerPtr->parentPtr = winPtr;
    containerPtr->embedded = None;
    containerPtr->embeddedPtr = NULL;
    containerPtr->nextPtr = firstContainerPtr;
    firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
    TkWindow *winPtr)		/* Tk's structure for an embedded window. */
{
    Container *containerPtr;

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return (MacDrawable *)containerPtr->parent;
	}
    }
    Tcl_Panic("TkMacOSXContainerId couldn't find window");
    return NULL;
}

/*







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
    TkWindow *winPtr)		/* Tk's structure for an embedded window. */
{
    Container *containerPtr;

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return (MacDrawable *) containerPtr->parent;
	}
    }
    Tcl_Panic("TkMacOSXContainerId couldn't find window");
    return NULL;
}

/*
454
455
456
457
458
459
460
461


462
463
464
465
466
467
468

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --
 *
 *	This procedure is invoked when someone asks for the input focus to be
 *	put on a window in an embedded application.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The input focus may change.
 *







|
>
>







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --
 *
 *	This procedure is invoked when someone asks for the input focus to be
 *	put on a window in an embedded application, but the application
 *	doesn't currently have the focus. It requests the input focus from the
 *	container application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The input focus may change.
 *
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    event.xfocus.type = FocusIn;
    event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display);
    event.xfocus.send_event = 1;
    event.xfocus.display = topLevelPtr->display;
    event.xfocus.window = containerPtr->parent;
    event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS;
    event.xfocus.detail = force;
    Tk_HandleEvent(&event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTestembedCmd --
 *







|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
    event.xfocus.type = FocusIn;
    event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display);
    event.xfocus.send_event = 1;
    event.xfocus.display = topLevelPtr->display;
    event.xfocus.window = containerPtr->parent;
    event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS;
    event.xfocus.detail = force;
    Tk_QueueWindowEvent(&event,TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTestembedCmd --
 *
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
    (void)dummy;

    if ((objc > 1) && (strcmp(Tcl_GetString(objv[1]), "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);
    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr != NULL) {
	    embeddedInterp = containerPtr->embeddedPtr->mainPtr->interp;
	}
	if (containerPtr->parentPtr != NULL) {
	    parentInterp = containerPtr->parentPtr->mainPtr->interp;
	}
	if (embeddedInterp != interp && parentInterp != interp) {
	    continue;
	}
	Tcl_DStringStartSublist(&dString);

	/*
	 * Parent id
	 */

	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x",
		    (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	/*
	 * Parent pathName
	 */

	if (containerPtr->parentPtr == NULL ||
	    parentInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}

	/*

	 * On X11 embedded is a wrapper, which does not exist on macOS.
	 */

	Tcl_DStringAppendElement(&dString, "");

	/*
	 * Embedded window pathName
	 */


	if (containerPtr->embeddedPtr == NULL ||
	    embeddedInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->embeddedPtr->pathName);
	}
	Tcl_DStringEndSublist(&dString);
    }







|

|
|





<
<

|







<
<
<
<
<
<
<
<
<

<
<
<
<
<



<
|




<
<
<
<
<
|
<





|
<
>
|
<
|
|
|
<
<
<
>
|
|
<







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613


614
615
616
617
618
619
620
621
622









623





624
625
626

627
628
629
630
631





632

633
634
635
636
637
638

639
640

641
642
643



644
645
646

647
648
649
650
651
652
653
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char **argv)		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];



    if ((argc > 1) && (strcmp(argv[1], "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);
    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {









	Tcl_DStringStartSublist(&dString);





	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {

	    sprintf(buffer, "0x%x", (int) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}





	if (containerPtr->parentPtr == NULL) {

	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}
	if (containerPtr->embedded == None) {

	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {

	    sprintf(buffer, "0x%x", (int) containerPtr->embedded);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {



	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	if (containerPtr->embeddedPtr == NULL) {

	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->embeddedPtr->pathName);
	}
	Tcl_DStringEndSublist(&dString);
    }
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{
    (void)winPtr;
    (void)eventPtr;

    /* TODO: Implement this or decide it definitely needs no implementation */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --







<
<
<







680
681
682
683
684
685
686



687
688
689
690
691
692
693
void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{



    /* TODO: Implement this or decide it definitely needs no implementation */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */

	return;
    }

    /*
     * Ignore any X protocol errors that happen in this procedure (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,







<
<
<
<
<
<
<
<







792
793
794
795
796
797
798








799
800
801
802
803
804
805
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;









    /*
     * Ignore any X protocol errors that happen in this procedure (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
	 * the screen.
	 */

	XMapWindow(eventPtr->xmaprequest.display,
		eventPtr->xmaprequest.window);
    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * It is not clear whether the container should be destroyed
	 * when an embedded window is destroyed.  See ticket [67384bce7d].
	 * Here we are following unix, by destroying the container.
	 */

	Tk_DestroyWindow((Tk_Window)winPtr);
    }
    Tk_DeleteErrorHandler(errHandler);
}

/*
 *----------------------------------------------------------------------
 *







|
<
<


|







854
855
856
857
858
859
860
861


862
863
864
865
866
867
868
869
870
871
	 * the screen.
	 */

	XMapWindow(eventPtr->xmaprequest.display,
		eventPtr->xmaprequest.window);
    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * The embedded application is gone. Destroy the container window.


	 */

	Tk_DestroyWindow((Tk_Window) winPtr);
    }
    Tk_DeleteErrorHandler(errHandler);
}

/*
 *----------------------------------------------------------------------
 *
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {

	/*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != None) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->embedded != None) {
	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    Tk_MoveResizeWindow((Tk_Window)containerPtr->embeddedPtr, 0, 0,
		    (unsigned) Tk_Width((Tk_Window)containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window)containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}







<
<
<
<
<
<
<
<








|
|







890
891
892
893
894
895
896








897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {








	if (containerPtr->embedded != None) {
	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0,
		    (unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window)containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017


1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
    int width, int height)	/* Size that the child has requested. */
{
    TkWindow *winPtr = containerPtr->parentPtr;

    /*
     * Forward the requested size into our geometry management hierarchy via
     * the container window. We need to send a Configure event back to the
     * embedded application if we decide not to honor its request; to make this
     * happen, process all idle event handlers synchronously here (so that the
     * geometry managers have had a chance to do whatever they want to do), and
     * if the window's size didn't change then generate a configure event.

     */

    Tk_GeometryRequest((Tk_Window)winPtr, width, height);
    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)) {}


    if ((winPtr->changes.width != width)
	    || (winPtr->changes.height != height)) {
	EmbedSendConfigure(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedSendConfigure --
 *
 *	This is currently a stub. It is called to notify an embedded
 *	application of its current size and location. This procedure is called
 *	when the embedded application made a geometry request that we did not
 *	grant, so that the embedded application knows that its geometry didn't
 *	change after all. It is a response to ConfigureRequest events, which we
 *	do not currently synthesize on the Mac
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedSendConfigure(
    Container *containerPtr)	/* Information about the embedding. */
{
    (void)containerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *







|
|
|
|
>


|
|
>
>















|
|














<







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
    int width, int height)	/* Size that the child has requested. */
{
    TkWindow *winPtr = containerPtr->parentPtr;

    /*
     * Forward the requested size into our geometry management hierarchy via
     * the container window. We need to send a Configure event back to the
     * embedded application if we decide not to honor its request; to make
     * this happen, process all idle event handlers synchronously here (so
     * that the geometry managers have had a chance to do whatever they want
     * to do), and if the window's size didn't change then generate a
     * configure event.
     */

    Tk_GeometryRequest((Tk_Window) winPtr, width, height);
    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	/* Empty loop body. */
    }
    if ((winPtr->changes.width != width)
	    || (winPtr->changes.height != height)) {
	EmbedSendConfigure(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedSendConfigure --
 *
 *	This is currently a stub. It is called to notify an embedded
 *	application of its current size and location. This procedure is called
 *	when the embedded application made a geometry request that we did not
 *	grant, so that the embedded application knows that its geometry didn't
 *	change after all. It is a response to ConfigureRequest events, which
 *	we do not currently synthesize on the Mac
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedSendConfigure(
    Container *containerPtr)	/* Information about the embedding. */
{

}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
	     * Fabricate an event to do this.
	     */

	    if (containerPtr->parentPtr != NULL &&
		    containerPtr->parentPtr->flags & TK_BOTH_HALVES) {
		XEvent event;

		event.xany.serial = LastKnownRequestProcessed(
			Tk_Display(containerPtr->parentPtr));
		event.xany.send_event = False;
		event.xany.display = Tk_Display(containerPtr->parentPtr);

		event.xany.type = DestroyNotify;
		event.xany.window = containerPtr->parent;
		event.xdestroywindow.event = containerPtr->parent;
		Tk_QueueWindowEvent(&event, TCL_QUEUE_HEAD);







|
|







1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
	     * Fabricate an event to do this.
	     */

	    if (containerPtr->parentPtr != NULL &&
		    containerPtr->parentPtr->flags & TK_BOTH_HALVES) {
		XEvent event;

		event.xany.serial =
			LastKnownRequestProcessed(Tk_Display(containerPtr->parentPtr));
		event.xany.send_event = False;
		event.xany.display = Tk_Display(containerPtr->parentPtr);

		event.xany.type = DestroyNotify;
		event.xany.window = containerPtr->parent;
		event.xdestroywindow.event = containerPtr->parent;
		Tk_QueueWindowEvent(&event, TCL_QUEUE_HEAD);
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpShowBusyWindow, TkpHideBusyWindow, TkpMakeTransparentWindowExist,
 * TkpCreateBusy --
 *
 *	Portability layer for busy windows. Holds platform-specific gunk for
 *	the [tk busy] command, which is currently a dummy implementation for
 *	OSX/Aqua. The individual functions are supposed to do the following:
 *
 * TkpShowBusyWindow --
 *	Make the busy window appear.
 *
 * TkpHideBusyWindow --
 *	Make the busy window go away.
 *
 * TkpMakeTransparentWindowExist --
 *	Actually make a transparent window.
 *
 * TkpCreateBusy --
 *	Creates the platform-specific part of a busy window structure.
 *
 *----------------------------------------------------------------------
 */

void
TkpShowBusyWindow(
    TkBusy busy)
{
    (void)busy;
}

void
TkpHideBusyWindow(
    TkBusy busy)
{
    (void)busy;
}

void
TkpMakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent)		/* Parent window. */
{
    (void)tkwin;
    (void)parent;
}

void
TkpCreateBusy(
    Tk_FakeWin *winPtr,
    Tk_Window tkRef,
    Window* parentPtr,
    Tk_Window tkParent,
    TkBusy busy)
{
    (void)winPtr;
    (void)tkRef;
    (void)parentPtr;
    (void)tkParent;
    (void)busy;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










1154
1155
1156
1157
1158
1159
1160
1161
1162































































1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree((char *) containerPtr);
    }































































}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXEntry.c.

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    int isSpinbox)
{
    CGRect bounds;
    TkMacOSXDrawingContext dc;
    GC bgGC;
    Tk_Window tkwin = entryPtr->tkwin;
    int oldWidth = 0;
    MacDrawable *macDraw = (MacDrawable *)d;
    const HIThemeFrameDrawInfo info = {
	.version = 0,
	.kind = kHIThemeFrameTextFieldSquare,
	.state = (entryPtr->state == STATE_DISABLED ? kThemeStateInactive :
		kThemeStateActive),
	.isFocused = (entryPtr->flags & GOT_FOCUS ? 1 : 0),
    };







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    int isSpinbox)
{
    CGRect bounds;
    TkMacOSXDrawingContext dc;
    GC bgGC;
    Tk_Window tkwin = entryPtr->tkwin;
    int oldWidth = 0;
    MacDrawable *macDraw = (MacDrawable *) d;
    const HIThemeFrameDrawInfo info = {
	.version = 0,
	.kind = kHIThemeFrameTextFieldSquare,
	.state = (entryPtr->state == STATE_DISABLED ? kThemeStateInactive :
		kThemeStateActive),
	.isFocused = (entryPtr->flags & GOT_FOCUS ? 1 : 0),
    };
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
     * space for one pixel to the right, 'cause it makes the buttons look
     * nicer.
     */

    if (isSpinbox) {
	int incDecWidth;

	/*
	 * If native spinbox buttons are going to be drawn, then temporarily
	 * change the width of the widget so that the same code can be used
	 * for drawing the Entry portion of the Spinbox as is used to draw
	 * an ordinary Entry.  The width must be restored before returning.
	 */

	oldWidth = Tk_Width(tkwin);
	if (ComputeIncDecParameters(Tk_Height(tkwin) - 2 * MAC_OSX_FOCUS_WIDTH,
		&incDecWidth) != 0) {
	    Tk_Width(tkwin) -= incDecWidth + 1;
	}
    }

   /*
    * The focus ring is drawn with an Alpha at the outside part of the ring,
    * so we have to draw over the edges of the ring before drawing the focus
    * or the text will peep through.
    */

    bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d);
    TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0);

    /*
     * Inset the entry Frame by the maximum width of the focus rect, which is
     * 3 according to the Carbon docs.
     */

    bounds.origin.x = macDraw->xOff + MAC_OSX_FOCUS_WIDTH;
    bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
    bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {

	/*
	 * No graphics context is available.  If the widget is a Spinbox, we
	 * must restore its width before returning 0. (Ticket [273b6a4996].)
	 */

	if (isSpinbox) {
	    Tk_Width(tkwin) = oldWidth;
	}
	return 0;
    }
    ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
    TkMacOSXRestoreDrawingContext(&dc);
    if (isSpinbox) {
	Tk_Width(tkwin) = oldWidth;
    }







<
<
|
<
<
<

<
|
|
|
<




















|
<
<
<
<
<
<
<
<
<







119
120
121
122
123
124
125


126



127

128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151









152
153
154
155
156
157
158
     * space for one pixel to the right, 'cause it makes the buttons look
     * nicer.
     */

    if (isSpinbox) {
	int incDecWidth;



	oldWidth = Tk_Width(tkwin);





	ComputeIncDecParameters(Tk_Height(tkwin) - 2 * MAC_OSX_FOCUS_WIDTH,
		&incDecWidth);
	Tk_Width(tkwin) -= incDecWidth + 1;

    }

   /*
    * The focus ring is drawn with an Alpha at the outside part of the ring,
    * so we have to draw over the edges of the ring before drawing the focus
    * or the text will peep through.
    */

    bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d);
    TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0);

    /*
     * Inset the entry Frame by the maximum width of the focus rect, which is
     * 3 according to the Carbon docs.
     */

    bounds.origin.x = macDraw->xOff + MAC_OSX_FOCUS_WIDTH;
    bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
    bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {









	return 0;
    }
    ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
    TkMacOSXRestoreDrawingContext(&dc);
    if (isSpinbox) {
	Tk_Width(tkwin) = oldWidth;
    }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
 *	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.
 *
 * Results:
 *	1 if it has drawn the buttons, 0 if not.
 *
 * Side effects:
 *	May draw the buttons into pixmap.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Drawable d)
{
    CGRect bounds;
    Tk_Window tkwin = sbPtr->entry.tkwin;
    int height = Tk_Height(tkwin);
    int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH;
    int incDecWidth;
    TkMacOSXDrawingContext dc;
    XRectangle rects[1];
    GC bgGC;
    MacDrawable *macDraw = (MacDrawable *)d;
    HIThemeButtonDrawInfo info = {
	.version = 0,
	.adornment = kThemeAdornmentNone,
    };

    /*
     * FIXME: RAISED really makes more sense







|


|

















|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
 *	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.
 *
 * Results:
 *	1 if it has drawn the border, 0 if not.
 *
 * Side effects:
 *	May draw the entry border into pixmap.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Drawable d)
{
    CGRect bounds;
    Tk_Window tkwin = sbPtr->entry.tkwin;
    int height = Tk_Height(tkwin);
    int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH;
    int incDecWidth;
    TkMacOSXDrawingContext dc;
    XRectangle rects[1];
    GC bgGC;
    MacDrawable *macDraw = (MacDrawable *) d;
    HIThemeButtonDrawInfo info = {
	.version = 0,
	.adornment = kThemeAdornmentNone,
    };

    /*
     * FIXME: RAISED really makes more sense
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    /*
     * We had to make the entry part of the window smaller so that we wouldn't
     * overdraw the spin buttons with the focus highlight. So now we have to
     * draw the highlightbackground.
     */

    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = Tk_Width(tkwin) - incDecWidth - 1;
    rects[0].y = 0;
    rects[0].width = incDecWidth + 1;
    rects[0].height = Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);
    return 1;
}








|

|



|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    /*
     * We had to make the entry part of the window smaller so that we wouldn't
     * overdraw the spin buttons with the focus highlight. So now we have to
     * draw the highlightbackground.
     */

    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = bounds.origin.x;
    rects[0].y = 0;
    rects[0].width = Tk_Width(tkwin);
    rects[0].height = Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);
    return 1;
}


Changes to macosx/tkMacOSXEvent.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

#pragma mark TKApplication(TKEvent)

enum {
    NSWindowWillMoveEventType = 20
};

@implementation TKApplication(TKEvent)
/* TODO: replace by +[addLocalMonitorForEventsMatchingMask ? */
- (NSEvent *) tkProcessEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSEvent	    *processedEvent = theEvent;
    NSEventType	    type = [theEvent type];
    NSInteger	    subtype;








|

<









|
<







8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"


#pragma mark TKApplication(TKEvent)

enum {
    NSWindowWillMoveEventType = 20
};

@implementation TKApplication(TKEvent)
/* TODO: replace by +[addLocalMonitorForEventsMatchingMask ? */
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent {

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSEvent	    *processedEvent = theEvent;
    NSEventType	    type = [theEvent type];
    NSInteger	    subtype;

85
86
87
88
89
90
91

92
93
94
95
96
97
98

99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114




115
116
117

118
119
120

121



122


123

124
125

126



127
128
129
130
131
132
133
134
135
136
    case NSApplicationDefined: {
	id win;
	win = [theEvent window];
	break;
	}
    case NSCursorUpdate:
        break;

    case NSEventTypeGesture:
    case NSEventTypeMagnify:
    case NSEventTypeRotate:
    case NSEventTypeSwipe:
    case NSEventTypeBeginGesture:
    case NSEventTypeEndGesture:
        break;

#endif

    default:
	break; /* return theEvent */
    }
    return processedEvent;
}
@end

#pragma mark -
int
XSync(
    Display *display,
    TCL_UNUSED(Bool))
{
    /*
     *  The main use of XSync is by the update command, which alternates




     *  between running an event loop to process all events without waiting and
     *  calling XSync on all displays until no events are left.  There is
     *  nothing for the mac to do with respect to syncing its one display but

     *  it can (and, during regression testing, frequently does) happen that
     *  timer events fire during the event loop. Processing those here seems
     *  to make the update command work in a way that is more consistent with

     *  its behavior on other platforms.



     */




    while (Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT)){}
    display->request++;

    return 0;



}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>







>








>

<
<
<
<
|
|
<
>
>
>
>
|
|
<
>
|
|
<
>
|
>
>
>
|
>
>
|
>
|
<
>
|
>
>
>










83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108




109
110

111
112
113
114
115
116

117
118
119

120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    case NSApplicationDefined: {
	id win;
	win = [theEvent window];
	break;
	}
    case NSCursorUpdate:
        break;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
    case NSEventTypeGesture:
    case NSEventTypeMagnify:
    case NSEventTypeRotate:
    case NSEventTypeSwipe:
    case NSEventTypeBeginGesture:
    case NSEventTypeEndGesture:
        break;
#endif
#endif

    default:
	break; /* return theEvent */
    }
    return processedEvent;
}
@end

#pragma mark -





/*

 *----------------------------------------------------------------------
 *
 * TkMacOSXFlushWindows --
 *
 *	This routine flushes all the visible windows of the application. It is
 *	called by XSync().

 *
 * Results:
 *	None.

 *
 * Side effects:
 *	Flushes all visible Cocoa windows
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
    NSArray *macWindows = [NSApp orderedWindows];


    for (NSWindow *w in macWindows) {
	if (TkMacOSXGetXWindow(w)) {
	    [w flushWindow];
	}
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Added macosx/tkMacOSXEvent.h.















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkMacOSXEvent.h --
 *
 *	Declarations of Macintosh specific functions for implementing the
 *	Mac OS X Notifier.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 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.
 */

#ifndef _TKMACEVENT
#define _TKMACEVENT

#ifndef _TKMACINT
#include "tkMacOSXInt.h"
#endif

MODULE_SCOPE void TkMacOSXFlushWindows(void);

#endif

Changes to macosx/tkMacOSXFont.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20





21



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
/*
 * tkMacOSXFont.c --
 *
 *	Contains the Macintosh implementation of the platform-independent font
 *	package interface.
 *
 * Copyright 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXConstants.h"


#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation





#define fixedPitch kCTFontUserFixedPitchFontType




/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

/*
 * The following structure represents our Macintosh-specific implementation
 * of a font object.
 */

typedef struct {
    TkFont font;		/* Stuff used by generic font package. Must be
				 * first in structure. */

    NSFont *nsFont;
    NSDictionary *nsAttributes;
} MacFont;

/*
 * The names for our "native" fonts.
 */



|
|











<

>


>
>
>
>
>

>
>
>













|
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * tkMacOSXFont.c --
 *
 *	Contains the Macintosh implementation of the platform-independant
 *	font package interface.
 *
 * Copyright 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"


#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation
#else
#define defaultOrientation kCTFontOrientationDefault
#define verticalOrientation kCTFontOrientationVertical
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
#define fixedPitch kCTFontUserFixedPitchFontType
#else
#define fixedPitch kCTFontUIFontUserFixedPitch
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

/*
 * The following structure represents our Macintosh-specific implementation
 * of a font object.
 */

typedef struct {
    TkFont font;		/* Stuff used by generic font package. Must
				 * be first in structure. */

    NSFont *nsFont;
    NSDictionary *nsAttributes;
} MacFont;

/*
 * The names for our "native" fonts.
 */
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95









96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    const char *tkName;
    const char *tkName1;
};

#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
static const struct SystemFontMapEntry systemFontMap[] = {
    ThemeFont(System, 			"TkDefaultFont", "TkIconFont"),
    ThemeFont(EmphasizedSystem,		"TkCaptionFont", NULL),
    ThemeFont(SmallSystem,		"TkHeadingFont", "TkTooltipFont"),
    ThemeFont(SmallEmphasizedSystem, NULL, NULL),
    ThemeFont(Application,		"TkTextFont", NULL),
    ThemeFont(Label,			"TkSmallCaptionFont", NULL),
    ThemeFont(Views, NULL, NULL),
    ThemeFont(MenuTitle, NULL, NULL),
    ThemeFont(MenuItem,			"TkMenuFont", NULL),
    ThemeFont(MenuItemMark, NULL, NULL),
    ThemeFont(MenuItemCmdKey, NULL, NULL),
    ThemeFont(WindowTitle, NULL, NULL),
    ThemeFont(PushButton, NULL, NULL),
    ThemeFont(UtilityWindowTitle, NULL, NULL),
    ThemeFont(AlertHeader, NULL, NULL),
    ThemeFont(Toolbar, NULL, NULL),
    ThemeFont(MiniSystem, NULL, NULL),
    { kThemeSystemFontDetail,		"systemDetailSystemFont", NULL, NULL },
    { kThemeSystemFontDetailEmphasized,	"systemDetailEmphasizedSystemFont", NULL, NULL },
    { -1, NULL, NULL, NULL }
};
#undef ThemeFont

static int antialiasedTextEnabled = -1;
static NSCharacterSet *whitespaceCharacterSet = nil;
static NSCharacterSet *lineendingCharacterSet = nil;

static void		GetTkFontAttributesForNSFont(NSFont *nsFont,
			    TkFontAttributes *faPtr);
static NSFont *		FindNSFont(const char *familyName,
			    NSFontTraitMask traits, NSInteger weight,
			    CGFloat size, int fallbackToDefault);
static void		InitFont(NSFont *nsFont,
			    const TkFontAttributes *reqFaPtr,
			    MacFont *fontPtr);
static int		CreateNamedSystemFont(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name,
			    TkFontAttributes *faPtr);










#pragma mark -
#pragma mark Font Helpers:

/*
 * To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an
 * NSString that uses the DString's buffer as its character buffer.  It can be
 * constructed from a Tcl_DString and it has a DString property that handles
 * converting from an NSString to a Tcl_DString.
 */

@implementation TKNSString

- (instancetype)initWithTclUtfBytes:(const void *)bytes
		       length:(NSUInteger)len
{
    self = [self init];
    if (self) {
	Tcl_DStringInit(&_ds);
	Tcl_UtfToChar16DString(bytes, len, &_ds);
	_string = [[NSString alloc]
	     initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds)
			       length:Tcl_DStringLength(&_ds)>>1
			 freeWhenDone:NO];
	self.UTF8String = _string.UTF8String;
    }
    return self;
}

- (instancetype)initWithString:(NSString *)aString
{
    self = [self init];
    if (self) {
	_string = [[NSString alloc] initWithString:aString];
	self.UTF8String = _string.UTF8String;
    }
    return self;
}

- (void)dealloc
{
    Tcl_DStringFree(&_ds);
    [_string release];
    [super dealloc];
}

- (NSUInteger)length
{
    return _string.length;
}

- (unichar)characterAtIndex:(NSUInteger)index
{
    return [_string characterAtIndex:index];
}

# ifndef __clang__
@synthesize DString = _ds;
#endif

- (Tcl_DString)DString
{
    if ( _ds.string == NULL) {

	/*
	 * The DString has not been initialized. Construct it from
	 * our string's unicode characters.
	 */
	char *p;
	NSUInteger index;

	Tcl_DStringInit(&_ds);
	Tcl_DStringSetLength(&_ds, 3 * [_string length]);
	p = Tcl_DStringValue(&_ds);
	for (index = 0; index < [_string length]; index++) {
	    p += Tcl_UniCharToUtf([_string characterAtIndex: index], p);
	}
	Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
    }
    return _ds;
}

#ifndef __clang__
@synthesize UTF8String = _UTF8String;
#endif
@end

#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

/*
 *---------------------------------------------------------------------------
 *







|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







|
|
|
<
|
<
|
|
|
<
|
>
>
>
>
>
>
>
>
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97

98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114



















































































115
116
117
118
119
120
121
    const char *tkName;
    const char *tkName1;
};

#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
static const struct SystemFontMapEntry systemFontMap[] = {
    ThemeFont(System, 			"TkDefaultFont", "TkIconFont"),
    ThemeFont(EmphasizedSystem,		"TkCaptionFont"),
    ThemeFont(SmallSystem,		"TkHeadingFont", "TkTooltipFont"),
    ThemeFont(SmallEmphasizedSystem),
    ThemeFont(Application,		"TkTextFont"),
    ThemeFont(Label,			"TkSmallCaptionFont"),
    ThemeFont(Views),
    ThemeFont(MenuTitle),
    ThemeFont(MenuItem,			"TkMenuFont"),
    ThemeFont(MenuItemMark),
    ThemeFont(MenuItemCmdKey),
    ThemeFont(WindowTitle),
    ThemeFont(PushButton),
    ThemeFont(UtilityWindowTitle),
    ThemeFont(AlertHeader),
    ThemeFont(Toolbar),
    ThemeFont(MiniSystem),
    { kThemeSystemFontDetail,		"systemDetailSystemFont" },
    { kThemeSystemFontDetailEmphasized,	"systemDetailEmphasizedSystemFont" },
    { -1, NULL }
};
#undef ThemeFont

static int antialiasedTextEnabled = -1;
static NSCharacterSet *whitespaceCharacterSet = nil;
static NSCharacterSet *lineendingCharacterSet = nil;

static void GetTkFontAttributesForNSFont(NSFont *nsFont,
	TkFontAttributes *faPtr);
static NSFont *FindNSFont(const char *familyName, NSFontTraitMask traits,

	NSInteger weight, CGFloat size, int fallbackToDefault);

static void InitFont(NSFont *nsFont, const TkFontAttributes *reqFaPtr,
	MacFont * fontPtr);
static int CreateNamedSystemFont(Tcl_Interp *interp, Tk_Window tkwin,

	const char* name, TkFontAttributes *faPtr);
static void DrawCharsInContext(Display *display, Drawable drawable, GC gc,
	Tk_Font tkfont, const char *source, int numBytes, int rangeStart,
	int rangeLength, int x, int y, double angle);

@interface NSFont(TKFont)
- (NSFont *)bestMatchingFontForCharacters:(const UTF16Char *)characters
	length:(NSUInteger)length attributes:(NSDictionary *)attributes
	actualCoveredLength:(NSUInteger *)coveredLength;
@end

#pragma mark -
#pragma mark Font Helpers:




















































































#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

/*
 *---------------------------------------------------------------------------
 *
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
static void
GetTkFontAttributesForNSFont(
    NSFont *nsFont,
    TkFontAttributes *faPtr)
{
    NSFontTraitMask traits = [[NSFontManager sharedFontManager]
	    traitsOfFont:nsFont];

    faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);
    faPtr->size = [nsFont pointSize];
    faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
    faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);

}

/*
 *---------------------------------------------------------------------------
 *
 * FindNSFont --
 *







>




<







135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
static void
GetTkFontAttributesForNSFont(
    NSFont *nsFont,
    TkFontAttributes *faPtr)
{
    NSFontTraitMask traits = [[NSFontManager sharedFontManager]
	    traitsOfFont:nsFont];

    faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);
    faPtr->size = [nsFont pointSize];
    faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
    faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);

}

/*
 *---------------------------------------------------------------------------
 *
 * FindNSFont --
 *
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    } else {
	family = [defaultFont familyName];
    }
    if (size == 0.0) {
	size = [defaultFont pointSize];
    }
    nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];

    /*
     * A second bug in NSFontManager that Apple created for the Catalina OS
     * causes requests as above to sometimes return fonts with additional
     * traits that were not requested, even though fonts without those unwanted
     * traits exist on the system.  See bug [90d555e088].  As a workaround
     * we ask the font manager to remove any unrequested traits.
     */

    if (nsFont) {
	nsFont = [fm convertFont:nsFont toNotHaveTrait:~traits];
    }
    if (!nsFont) {
	NSArray *availableFamilies = [fm availableFontFamilies];
	NSString *caseFamily = nil;

	for (NSString *f in availableFamilies) {
	    if ([family caseInsensitiveCompare:f] == NSOrderedSame) {
		caseFamily = f;







<
<
<
<
<
<
<
<
<
<
<
<







183
184
185
186
187
188
189












190
191
192
193
194
195
196
    } else {
	family = [defaultFont familyName];
    }
    if (size == 0.0) {
	size = [defaultFont pointSize];
    }
    nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];












    if (!nsFont) {
	NSArray *availableFamilies = [fm availableFontFamilies];
	NSString *caseFamily = nil;

	for (NSString *f in availableFamilies) {
	    if ([family caseInsensitiveCompare:f] == NSOrderedSame) {
		caseFamily = f;
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
    NSDictionary *nsAttributes;
    NSRect bounds;
    CGFloat kern = 0.0;
    NSFontRenderingMode renderingMode = NSFontDefaultRenderingMode;
    int ascent, descent/*, dontAA*/;
    static const UniChar ch[] = {'.', 'W', ' ', 0xc4, 0xc1, 0xc2, 0xc3, 0xc7};
			/* ., W, Space, Auml, Aacute, Acirc, Atilde, Ccedilla */
#define nCh	(sizeof(ch) / sizeof(UniChar))
    CGGlyph glyphs[nCh];
    CGRect boundingRects[nCh];

    fontPtr->font.fid = (Font) fontPtr;
    faPtr = &fontPtr->font.fa;
    if (reqFaPtr) {
	*faPtr = *reqFaPtr;
    } else {
	TkInitFontAttributes(faPtr);
    }
    fontPtr->nsFont = nsFont;

    /*
     * Some don't like antialiasing on fixed-width even if bigger than limit
     */

    // dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10;
    if (antialiasedTextEnabled >= 0/* || dontAA*/) {
	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
		NSFontIntegerAdvancementsRenderingMode :
		NSFontAntialiasedRenderingMode;
    }
    nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
    GetTkFontAttributesForNSFont(nsFont, faPtr);







|











<
<
|
<
<
|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260


261


262
263
264
265
266
267
268
269
    NSDictionary *nsAttributes;
    NSRect bounds;
    CGFloat kern = 0.0;
    NSFontRenderingMode renderingMode = NSFontDefaultRenderingMode;
    int ascent, descent/*, dontAA*/;
    static const UniChar ch[] = {'.', 'W', ' ', 0xc4, 0xc1, 0xc2, 0xc3, 0xc7};
			/* ., W, Space, Auml, Aacute, Acirc, Atilde, Ccedilla */
    #define nCh (sizeof(ch) / sizeof(UniChar))
    CGGlyph glyphs[nCh];
    CGRect boundingRects[nCh];

    fontPtr->font.fid = (Font) fontPtr;
    faPtr = &fontPtr->font.fa;
    if (reqFaPtr) {
	*faPtr = *reqFaPtr;
    } else {
	TkInitFontAttributes(faPtr);
    }
    fontPtr->nsFont = nsFont;


    // some don't like antialiasing on fixed-width even if bigger than limit


//    dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10;
    if (antialiasedTextEnabled >= 0/* || dontAA*/) {
	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
		NSFontIntegerAdvancementsRenderingMode :
		NSFontAntialiasedRenderingMode;
    }
    nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
    GetTkFontAttributesForNSFont(nsFont, faPtr);
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
	    [NSNumber numberWithInt:faPtr->overstrike ?
		NSUnderlineStyleSingle|NSUnderlinePatternSolid :
		NSUnderlineStyleNone], NSStrikethroughStyleAttributeName,
	    [NSNumber numberWithInt:fmPtr->fixed ? 0 : 1],
		NSLigatureAttributeName,
	    [NSNumber numberWithDouble:kern], NSKernAttributeName, nil];
    fontPtr->nsAttributes = [nsAttributes retain];
#undef nCh
}

/*
 *-------------------------------------------------------------------------
 *
 * CreateNamedSystemFont --
 *







|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
	    [NSNumber numberWithInt:faPtr->overstrike ?
		NSUnderlineStyleSingle|NSUnderlinePatternSolid :
		NSUnderlineStyleNone], NSStrikethroughStyleAttributeName,
	    [NSNumber numberWithInt:fmPtr->fixed ? 0 : 1],
		NSLigatureAttributeName,
	    [NSNumber numberWithDouble:kern], NSKernAttributeName, nil];
    fontPtr->nsAttributes = [nsAttributes retain];
    #undef nCh
}

/*
 *-------------------------------------------------------------------------
 *
 * CreateNamedSystemFont --
 *
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
 *
 *	This procedure is called when an application is created. It
 *	initializes all the structures that are used by the
 *	platform-dependent code on a per application basis.
 *	Note that this is called before TkpInit() !
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initialize named system fonts.
 *
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    Tcl_Interp *interp = mainPtr->interp;
    Tk_Window tkwin = (Tk_Window)mainPtr->winPtr;
    const struct SystemFontMapEntry *systemFont = systemFontMap;
    NSFont *nsFont;
    TkFontAttributes fa;
    NSMutableCharacterSet *cs;
    /*
     * Since we called before TkpInit, we need our own autorelease pool.
     */
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    /*
     * Force this for now.
     */
    if (!mainPtr->winPtr->mainPtr) {
	mainPtr->winPtr->mainPtr = mainPtr;
    }
    while (systemFont->systemName) {
	nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
		HIThemeGetUIFontType(systemFont->id), 0, NULL);
	if (nsFont) {







|
















|




<
|
<


<
|
<







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375

376
377

378

379
380
381
382
383
384
385
/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
 *
 *	This procedure is called when an application is created. It
 *	initializes all the structures that are used by the
 *	platform-dependant code on a per application basis.
 *	Note that this is called before TkpInit() !
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initialize named system fonts.
 *
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    Tcl_Interp *interp = mainPtr->interp;
    Tk_Window tkwin = (Tk_Window) mainPtr->winPtr;
    const struct SystemFontMapEntry *systemFont = systemFontMap;
    NSFont *nsFont;
    TkFontAttributes fa;
    NSMutableCharacterSet *cs;

    /* Since we called before TkpInit, we need our own autorelease pool. */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];


    /* force this for now */

    if (!mainPtr->winPtr->mainPtr) {
	mainPtr->winPtr->mainPtr = mainPtr;
    }
    while (systemFont->systemName) {
	nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
		HIThemeGetUIFontType(systemFont->id), 0, NULL);
	if (nsFont) {
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
		CreateNamedSystemFont(interp, tkwin, systemFont->tkName1, &fa);
	    }
	    CFRelease(nsFont);
	}
	systemFont++;
    }
    TkInitFontAttributes(&fa);
#if 0

    /*
     * In macOS 10.15.1 Apple introduced a bug in NSFontManager which caused
     * it to not recognize the familyName ".SF NSMono" which is the familyName
     * of the default fixed pitch system fault on that system.  See bug [855049e799].
     * As a workaround we call [NSFont userFixedPitchFontOfSize:11] instead.
     * This returns a user font in the "Menlo" family.
     */

    nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);
#else
    nsFont = [NSFont userFixedPitchFontOfSize:11];
#endif
    if (nsFont) {
	GetTkFontAttributesForNSFont(nsFont, &fa);
#if 0
	CFRelease(nsFont);
#endif
    } else {
	fa.family = Tk_GetUid("Monaco");
	fa.size = 11;
	fa.weight = TK_FW_NORMAL;
	fa.slant = TK_FS_ROMAN;
    }
    CreateNamedSystemFont(interp, tkwin, "TkFixedFont", &fa);







<
<
<
<
<
<
<
<
<
<

<
<
<


<

<







393
394
395
396
397
398
399










400



401
402

403

404
405
406
407
408
409
410
		CreateNamedSystemFont(interp, tkwin, systemFont->tkName1, &fa);
	    }
	    CFRelease(nsFont);
	}
	systemFont++;
    }
    TkInitFontAttributes(&fa);










    nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);



    if (nsFont) {
	GetTkFontAttributesForNSFont(nsFont, &fa);

	CFRelease(nsFont);

    } else {
	fa.family = Tk_GetUid("Monaco");
	fa.size = 11;
	fa.weight = TK_FW_NORMAL;
	fa.slant = TK_FS_ROMAN;
    }
    CreateNamedSystemFont(interp, tkwin, "TkFixedFont", &fa);
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.
 *
 * Results:
 *	The return value is a pointer to a TkFont that represents the native
 *	font. If a native font by the given name could not be found, the return
 *	value is NULL.
 *
 *	Every call to this procedure returns a new TkFont structure, even if
 *	the name has already been seen before. The caller should call
 *	TkpDeleteFont() when the font is no longer needed.
 *
 *	The caller is responsible for initializing the memory associated with
 *	the generic TkFont when this function returns and releasing the
 *	contents of the generics TkFont before calling TkpDeleteFont().
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    TCL_UNUSED(Tk_Window),		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    MacFont *fontPtr = NULL;
    ThemeFontID themeFontId;
    CTFontRef ctFont;

    if (strcmp(name, SYSTEMFONT_NAME) == 0) {
	themeFontId = kThemeSystemFont;
    } else if (strcmp(name, APPLFONT_NAME) == 0) {
	themeFontId = kThemeApplicationFont;
    } else if (strcmp(name, MENUITEMFONT_NAME) == 0) {
	themeFontId = kThemeMenuItemFont;
    } else {
	return NULL;
    }
    ctFont = CTFontCreateUIFontForLanguage(
	    HIThemeGetUIFontType(themeFontId), 0, NULL);
    if (ctFont) {
	fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
	InitFont((NSFont*) ctFont, NULL, fontPtr);
    }

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFromAttributes --
 *
 *	Given a desired set of attributes for a font, find a font with the
 *	closest matching attributes.
 *
 * Results:
 *	The return value is a pointer to a TkFont that represents the font with
 *	the desired attributes. If a font with the desired attributes could not
 *	be constructed, some other font will be substituted automatically.

 *
 *	Every call to this procedure returns a new TkFont structure, even if
 *	the specified attributes have already been seen before. The caller
 *	should call TkpDeleteFont() to free the platform- specific data when
 *	the font is no longer needed.
 *
 *	The caller is responsible for initializing the memory associated with
 *	the generic TkFont when this function returns and releasing the
 *	contents of the generic TkFont before calling TkpDeleteFont().
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetFontFromAttributes(
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the font;
				 * the existing contents of the font will be
				 * released. If NULL, a new TkFont structure is
				 * allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    MacFont *fontPtr;
    int points = (int) (TkFontGetPoints(tkwin, faPtr->size) + 0.5);
    NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
    NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
    NSFont *nsFont;

    nsFont = FindNSFont(faPtr->family, traits, weight, points, 0);
    if (!nsFont) {
	const char *const *aliases = TkFontGetAliasList(faPtr->family);

	while (aliases && !nsFont) {
	    nsFont = FindNSFont(*aliases++, traits, weight, points, 0);
	}
    }
    if (!nsFont) {
	nsFont = FindNSFont(faPtr->family, traits, weight, points, 1);
    }
    if (!nsFont) {
	Tcl_Panic("Could not determine NSFont from TkFontAttributes");
    }
    if (tkFontPtr == NULL) {
	fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
    } else {
	fontPtr = (MacFont *) tkFontPtr;
	TkpDeleteFont(tkFontPtr);
    }
    CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
    InitFont(nsFont, faPtr, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDeleteFont --
 *
 *	Called to release a font allocated by TkpGetNativeFont() or
 *	TkpGetFontFromAttributes(). The caller should have already released the
 *	fields of the TkFont that are used exclusively by the generic TkFont
 *	code.
 *
 * Results:
 *	TkFont is deallocated.
 *
 * Side effects:
 *	None.
 *







|
|
|

|
|


|
|
|









|















|
|

|















|
|
|
>

|
|
|
|

|
|
|











|
|
|
|





|






|












|
















|
|
|







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.
 *
 * Results:
 *	The return value is a pointer to a TkFont that represents the
 *	native font. If a native font by the given name could not be
 *	found, the return value is NULL.
 *
 *	Every call to this procedure returns a new TkFont structure, even
 *	if the name has already been seen before. The caller should call
 *	TkpDeleteFont() when the font is no longer needed.
 *
 *	The caller is responsible for initializing the memory associated
 *	with the generic TkFont when this function returns and releasing
 *	the contents of the generics TkFont before calling TkpDeleteFont().
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    MacFont *fontPtr = NULL;
    ThemeFontID themeFontId;
    CTFontRef ctFont;

    if (strcmp(name, SYSTEMFONT_NAME) == 0) {
	themeFontId = kThemeSystemFont;
    } else if (strcmp(name, APPLFONT_NAME) == 0) {
	themeFontId = kThemeApplicationFont;
    } else if (strcmp(name, MENUITEMFONT_NAME) == 0) {
	themeFontId = kThemeMenuItemFont;
    } else {
	return NULL;
    }
    ctFont = CTFontCreateUIFontForLanguage(HIThemeGetUIFontType(
	    themeFontId), 0, NULL);
    if (ctFont) {
	fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
	InitFont((NSFont*) ctFont, NULL, fontPtr);
    }

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFromAttributes --
 *
 *	Given a desired set of attributes for a font, find a font with the
 *	closest matching attributes.
 *
 * Results:
 *	The return value is a pointer to a TkFont that represents the font
 *	with the desired attributes. If a font with the desired attributes
 *	could not be constructed, some other font will be substituted
 *	automatically.
 *
 *	Every call to this procedure returns a new TkFont structure, even
 *	if the specified attributes have already been seen before. The
 *	caller should call TkpDeleteFont() to free the platform- specific
 *	data when the font is no longer needed.
 *
 *	The caller is responsible for initializing the memory associated
 *	with the generic TkFont when this function returns and releasing
 *	the contents of the generic TkFont before calling TkpDeleteFont().
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetFontFromAttributes(
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    MacFont *fontPtr;
    int points = TkFontGetPoints(tkwin, faPtr->size);
    NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
    NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
    NSFont *nsFont;

    nsFont = FindNSFont(faPtr->family, traits, weight, points, 0);
    if (!nsFont) {
	char *const *aliases = TkFontGetAliasList(faPtr->family);

	while (aliases && !nsFont) {
	    nsFont = FindNSFont(*aliases++, traits, weight, points, 0);
	}
    }
    if (!nsFont) {
	nsFont = FindNSFont(faPtr->family, traits, weight, points, 1);
    }
    if (!nsFont) {
	Tcl_Panic("Could not determine NSFont from TkFontAttributes");
    }
    if (tkFontPtr == NULL) {
	fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
    } else {
	fontPtr = (MacFont *) tkFontPtr;
	TkpDeleteFont(tkFontPtr);
    }
    CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
    InitFont(nsFont, faPtr, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDeleteFont --
 *
 *	Called to release a font allocated by TkpGetNativeFont() or
 *	TkpGetFontFromAttributes(). The caller should have already
 *	released the fields of the TkFont that are used exclusively by the
 *	generic TkFont code.
 *
 * Results:
 *	TkFont is deallocated.
 *
 * Side effects:
 *	None.
 *
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFamilies --
 *
 *	Return information about the font families that are available on the
 *	display of the given window.
 *
 * Results:
 *	Modifies interp's result object to hold a list of all the available
 *	font families.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    TCL_UNUSED(Tk_Window))		/* For display to query. */
{
    Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
    NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];

    for (NSString *family in list) {
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj([family UTF8String], -1));
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * TkpGetSubFonts --
 *
 *	A function used by the testing package for querying the actual screen
 *	fonts that make up a font object.
 *
 * Results:
 *	Modifies interp's result object to hold a list containing the names of
 *	the screen fonts that make up the given font object.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */








|
|














|
















|
|


|
|







577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFamilies --
 *
 *	Return information about the font families that are available on
 *	the display of the given window.
 *
 * Results:
 *	Modifies interp's result object to hold a list of all the available
 *	font families.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
    NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];

    for (NSString *family in list) {
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj([family UTF8String], -1));
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * TkpGetSubFonts --
 *
 *	A function used by the testing package for querying the actual
 *	screen fonts that make up a font object.
 *
 * Results:
 *	Modifies interp's result object to hold a list containing the names
 *	of the screen fonts that make up the given font object.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
 *	Retrieve the font attributes of the actual font used to render a given
 *	character.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The font attributes are stored in *faPtr.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    MacFont *fontPtr = (MacFont *) tkfont;
    NSFont *nsFont = fontPtr->nsFont;
    *faPtr = fontPtr->font.fa;
    if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
	UTF16Char ch = (UTF16Char) c;

	nsFont = [nsFont bestMatchingFontForCharacters:&ch
		length:1 attributes:nil actualCoveredLength:NULL];
	if (nsFont) {
	    GetTkFontAttributesForNSFont(nsFont, faPtr);
	}
    }







|
|












|

|






|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
 *	Retrieve the font attributes of the actual font used to render a
 *	given character.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The font attributes are stored in *faPtr.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    Tcl_UniChar c,		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    MacFont *fontPtr = (MacFont *) tkfont;
    NSFont *nsFont = fontPtr->nsFont;
    *faPtr = fontPtr->font.fa;
    if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
	UTF16Char ch = c;

	nsFont = [nsFont bestMatchingFontForCharacters:&ch
		length:1 attributes:nil actualCoveredLength:NULL];
	if (nsFont) {
	    GetTkFontAttributesForNSFont(nsFont, faPtr);
	}
    }
857
858
859
860
861
862
863
864
865
866

867
868
869
870
871
872
873
 *	that TkpDrawCharsInContext() will be used to actually display the
 *	characters.
 *
 *	This one is almost the same as Tk_MeasureChars(), but with access to
 *	all the characters on the line for context.
 *
 * Results:
 *	The return value is the number of bytes from source that fit into the
 *	span that extends from 0 to maxLength. *lengthPtr is filled with the
 *	x-coordinate of the right edge of the last character that did fit.

 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */








|
|
|
>







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
 *	that TkpDrawCharsInContext() will be used to actually display the
 *	characters.
 *
 *	This one is almost the same as Tk_MeasureChars(), but with access to
 *	all the characters on the line for context.
 *
 * Results:
 *	The return value is the number of bytes from source that
 *	fit into the span that extends from 0 to maxLength. *lengthPtr is
 *	filled with the x-coordinate of the right edge of the last
 *	character that did fit.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
				 * which only partially fits on this line.
				 * TK_WHOLE_WORDS means stop on a word
				 * boundary, if possible. TK_AT_LEAST_ONE means
				 * return at least one character even if no
				 * characters fit.  If TK_WHOLE_WORDS and
				 * TK_AT_LEAST_ONE are set and the first word
				 * doesn't fit, we return at least one
				 * character or whatever characters fit into
				 * maxLength.  TK_ISOLATE_END means that the
				 * last character should not be considered in
				 * context with the rest of the string (used
				 * for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */







|
|
|
|
|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
				 * which only partially fits on this line.
				 * TK_WHOLE_WORDS means stop on a word
				 * boundary, if possible. TK_AT_LEAST_ONE
				 * means return at least one character even
				 * if no characters fit.  If TK_WHOLE_WORDS
				 * and TK_AT_LEAST_ONE are set and the first
				 * word doesn't fit, we return at least one
				 * character or whatever characters fit into
				 * maxLength.  TK_ISOLATE_END means that the
				 * last character should not be considered in
				 * context with the rest of the string (used
				 * for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
916
917
918
919
920
921
922









923
924
925
926

927
928
929
930
931
932
933

    if (rangeStart < 0 || rangeLength <= 0 ||
	    rangeStart + rangeLength > numBytes ||
	    (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) {
	*lengthPtr = 0;
	return 0;
    }









    if (maxLength > 32767) {
	maxLength = 32767;
    }
    string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];

    if (!string) {
	length = 0;
	fit = rangeLength;
	goto done;
    }
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:fontPtr->nsAttributes];







>
>
>
>
>
>
>
>
>



|
>







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

    if (rangeStart < 0 || rangeLength <= 0 ||
	    rangeStart + rangeLength > numBytes ||
	    (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) {
	*lengthPtr = 0;
	return 0;
    }
#if 0
    /* Back-compatibility with ATSUI renderer, appears not to be needed */
    if (rangeStart == 0 && maxLength == 1 && (flags & TK_ISOLATE_END) &&
	    !(flags & TK_AT_LEAST_ONE)) {
	length = 0;
	fit = 0;
	goto done;
    }
#endif
    if (maxLength > 32767) {
	maxLength = 32767;
    }
    string = [[NSString alloc] initWithBytesNoCopy:(void*)source
		length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
    if (!string) {
	length = 0;
	fit = rangeLength;
	goto done;
    }
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:fontPtr->nsAttributes];
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;

        /*
         * Get a line breakpoint in the source string.
         */

	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}

        /*
         * Trim right whitespace/lineending characters.
         */

	cs = (index <= len && (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}

        /*
         * If there is no line breakpoint in the source string between its
         * start and the index position that fits in maxWidth, then
         * CTTypesetterSuggestLineBreak() returns that very last index.
         * However if the TK_WHOLE_WORDS flag is set, we want to break at a
         * word boundary. In this situation, unless TK_AT_LEAST_ONE is set, we
         * must report that zero chars actually fit (in other words the
         * smallest word of the source string is still larger than maxWidth).
         */

        if ((index >= start) && (index < len) &&
                (flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) &&
                ![cs characterIsMember:[string characterAtIndex:index]]) {
            index = start;
        }

	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}

        /*
         * Now measure the string width in pixels.
         */

	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;
	}
	if (width < maxWidth && (flags & TK_PARTIAL_OK) && index < len) {
	    range.length = ++index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

        /*
	 * The call to CTTypesetterSuggestClusterBreak above will always return
	 * at least one character regardless of whether it exceeded it or not.
	 * Clean that up now.
	 */

	while (width > maxWidth && !(flags & TK_PARTIAL_OK)
		&& index > start+(flags & TK_AT_LEAST_ONE)) {
	    range.length = --index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

    }







<
<
<
<










<
<
<
<
<
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<















<
|
|
|
<
<
|
<







856
857
858
859
860
861
862




863
864
865
866
867
868
869
870
871
872





873
874
875
876
877
878

















879
880
881





882
883
884
885
886
887
888
889
890
891
892
893
894
895
896

897
898
899


900

901
902
903
904
905
906
907
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;





	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}





	cs = (index < len || (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}

















	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}





	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;
	}
	if (width < maxWidth && (flags & TK_PARTIAL_OK) && index < len) {
	    range.length = ++index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}


        /* The call to CTTypesetterSuggestClusterBreak above will always
           return at least one character regardless of whether it exceeded
           it or not.  Clean that up now. */


	  while (width > maxWidth && !(flags & TK_PARTIAL_OK) && index > start+(flags & TK_AT_LEAST_ONE)) {

	    range.length = --index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

    }
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
	    "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
	    source+rangeStart, maxLength,
	    flags & TK_PARTIAL_OK   ? "partialOk "  : "",
	    flags & TK_WHOLE_WORDS  ? "wholeWords " : "",
	    flags & TK_AT_LEAST_ONE ? "atLeastOne " : "",
	    flags & TK_ISOLATE_END  ? "isolateEnd " : "",
	    length, fit);

#endif
    *lengthPtr = length;
    return fit;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawChars --
 *
 *	Draw a string of characters on the screen.
 *
 *	With ATSUI we need the line context to do this right, so we have the
 *	actual implementation in TkpDrawAngledCharsInContext().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * string when drawing. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, 0.0);
}

void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, angle);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), with







>













|


|

















|
|






|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968























969
970
971
972
973
974
975
	    "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
	    source+rangeStart, maxLength,
	    flags & TK_PARTIAL_OK   ? "partialOk "  : "",
	    flags & TK_WHOLE_WORDS  ? "wholeWords " : "",
	    flags & TK_AT_LEAST_ONE ? "atLeastOne " : "",
	    flags & TK_ISOLATE_END  ? "isolateEnd " : "",
	    length, fit);
//if (!(rangeLength==1 && rangeStart == 0)) fprintf(stderr, "   measure len=%d (max=%d, w=%.0f) from %d (nb=%d): source=\"%s\": index=%d return %d\n",rangeLength,maxLength,width,rangeStart,numBytes, source+rangeStart, index, fit);
#endif
    *lengthPtr = length;
    return fit;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_DrawChars --
 *
 *	Draw a string of characters on the screen.
 *
 *	With ATSUI we need the line context to do this right, so we have the
 *	actual implementation in TkpDrawCharsInContext().
 *
 * Results:
  *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * string when drawing. */
{
    DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, 0.0);
}
























/*
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), with
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250


1251
1252

1253
1254
1255
1256
1257
1258
1259
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    (void)display;
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    rangeStart, rangeLength, x, y, 0.0);
}

void
TkpDrawAngledCharsInContext(
    TCL_UNUSED(Display *),		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const MacFont *fontPtr = (const MacFont *) tkfont;
    NSString *string;
    NSMutableDictionary *attributes;
    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, length;
    CTLineRef line, full=nil;
    MacDrawable *macWin = (MacDrawable *)drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg;
    NSFont *nsFont;
    CGAffineTransform t;
    CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y;

    if (rangeStart < 0 || rangeLength <= 0  ||
	rangeStart + rangeLength > numBytes ||
	!TkMacOSXSetupDrawingContext(drawable, gc, &drawingContext)) {
	return;
    }
    string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];

    if (!string) {
	return;
    }

    context = drawingContext.context;
    fg = TkMacOSXCreateCGColor(gc, gc->foreground);
    attributes = [fontPtr->nsAttributes mutableCopy];
    [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
    CFRelease(fg);
    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:GET_NSCONTEXT(context, NO)];

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    textX += (CGFloat) macWin->xOff;
    textY += (CGFloat) macWin->yOff;
    height = drawingContext.portBounds.size.height;
    textY = height - textY;
    t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
    if (angle != 0.0) {
	t = CGAffineTransformTranslate(
             CGAffineTransformRotate(
                 CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0),
             -textX, -textY);
    }
    CGContextConcatCTM(context, t);

    start = Tcl_NumUtfChars(source, rangeStart);
    length = Tcl_NumUtfChars(source, rangeStart + rangeLength) - start;
    line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length));
    if (start > 0) {

	/*
	 * We are only drawing part of the string.  To compute the x coordinate
	 * of the part we are drawing we subtract its typographical length from
	 * the typographical length of the full string.  This accounts for the
	 * kerning after the initial part of the string.
	 */

	full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length));
	width = CTLineGetTypographicBounds(full, NULL, NULL, NULL);
	CFRelease(full);
	textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL));


    }
    CGContextSetTextPosition(context, textX, textY);

    CTLineDraw(line, context);
    CFRelease(line);
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    [attributes release];
    TkMacOSXRestoreDrawingContext(&drawingContext);







|
|









<
|



|
|
|







|
|





|


|






|
|
|





|

|
|
|


|
>



<






|
>





|
|
|
|
|

|
|
<
<


>

|
<

|
<
<
<
<
<
<
<
|
|
|
<
>
>

<
>







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082


1083
1084
1085
1086
1087

1088
1089







1090
1091
1092

1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{

    DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    rangeStart, rangeLength, x, y, 0.0);
}

static void
DrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)
{
    const MacFont *fontPtr = (const MacFont *) tkfont;
    NSString *string;
    NSMutableDictionary *attributes;
    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, len;
    CTLineRef line;
    MacDrawable *macWin = (MacDrawable *) drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg;
    NSFont *nsFont;
    CGAffineTransform t;
    int h;

    if (rangeStart < 0 || rangeLength <= 0 ||
	    rangeStart + rangeLength > numBytes ||
	    !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) {
	return;
    }
    string = [[NSString alloc] initWithBytesNoCopy:(void*)source
		length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
    if (!string) {
	return;
    }

    context = drawingContext.context;
    fg = TkMacOSXCreateCGColor(gc, gc->foreground);
    attributes = [fontPtr->nsAttributes mutableCopy];
    [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
    CFRelease(fg);
    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:[NSGraphicsContext graphicsContextWithGraphicsPort:
	    context flipped:NO]];
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    x += macWin->xOff;
    y += macWin->yOff;
    h = drawingContext.portBounds.size.height;
    y = h - y;
    t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, h);
    if (angle != 0.0) {
	t = CGAffineTransformTranslate(CGAffineTransformRotate(
		CGAffineTransformTranslate(t, x, y), angle*M_PI/180.0), -x, -y);


    }
    CGContextConcatCTM(context, t);
    CGContextSetTextPosition(context, x, y);
    start = Tcl_NumUtfChars(source, rangeStart);
    len = Tcl_NumUtfChars(source, rangeStart + rangeLength);

    if (start > 0) {
	CGRect clipRect = CGRectInfinite, startBounds;







	line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start));
	startBounds = CTLineGetImageBounds(line, context);
	CFRelease(line);

	clipRect.origin.x = startBounds.origin.x + startBounds.size.width;
	CGContextClipToRect(context, clipRect);
    }

    line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, len));
    CTLineDraw(line, context);
    CFRelease(line);
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    [attributes release];
    TkMacOSXRestoreDrawingContext(&drawingContext);
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkMacOSXIsCharacterMissing(
    TCL_UNUSED(Tk_Font),		/* The font we are looking in. */
    TCL_UNUSED(unsigned int))	/* The character we are looking for. */
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFontDescriptionForNSFontAndNSFontAttributes --
 *
 *	Get text description of a font specified by NSFont and attributes.
 *
 * Results:
 *	List object or NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE Tcl_Obj *
TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
    NSFont *nsFont,
    NSDictionary *nsAttributes)
{
    Tcl_Obj *objv[6];
    int i = 0;
    const char *familyName = [[nsFont familyName] UTF8String];

    if (nsFont && familyName) {
	NSFontTraitMask traits = [[NSFontManager sharedFontManager]
		traitsOfFont:nsFont];
	id underline = [nsAttributes objectForKey:
		NSUnderlineStyleAttributeName];
	id strikethrough = [nsAttributes objectForKey:
		NSStrikethroughStyleAttributeName];

	objv[i++] = Tcl_NewStringObj(familyName, -1);
	objv[i++] = Tcl_NewWideIntObj([nsFont pointSize]);
#define S(s)    Tcl_NewStringObj(STRINGIFY(s), (sizeof(STRINGIFY(s))-1))
	objv[i++] = (traits & NSBoldFontMask)	? S(bold)   : S(normal);
	objv[i++] = (traits & NSItalicFontMask)	? S(italic) : S(roman);
	if ([underline respondsToSelector:@selector(intValue)] &&
		([underline intValue] & (NSUnderlineStyleSingle |
		NSUnderlineStyleThick | NSUnderlineStyleDouble))) {
	    objv[i++] = S(underline);
	}
	if ([strikethrough respondsToSelector:@selector(intValue)] &&
		([strikethrough intValue] & (NSUnderlineStyleSingle |
		NSUnderlineStyleThick | NSUnderlineStyleDouble))) {
	    objv[i++] = S(overstrike);
	}
#undef S
    }
    return i ? Tcl_NewListObj(i, objv) : NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXUseAntialiasedText --
 *
 *	Enables or disables application-wide use of antialiased text (where
 *	available). Sets up a linked Tcl global variable to allow disabling of
 *	antialiased text from Tcl.
 *
 *	The possible values for this variable are:
 *
 *	-1 - Use system default as configurable in "System Prefs" -> "General".
 *	 0 - Unconditionally disable antialiasing.
 *	 1 - Unconditionally enable antialiasing.
 *
 * Results:







|
|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|
<







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182





















































1183
1184
1185
1186
1187

1188
1189
1190
1191
1192
1193
1194
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkMacOSXIsCharacterMissing(
    Tk_Font tkfont,		/* The font we are looking in. */
    unsigned int searchChar)	/* The character we are looking for. */
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *





















































 * TkMacOSXUseAntialiasedText --
 *
 *	Enables or disables application-wide use of antialiased text (where
 *	available). Sets up a linked Tcl global variable to allow
 *	disabling of antialiased text from tcl.

 *	The possible values for this variable are:
 *
 *	-1 - Use system default as configurable in "System Prefs" -> "General".
 *	 0 - Unconditionally disable antialiasing.
 *	 1 - Unconditionally enable antialiasing.
 *
 * Results:

Changes to macosx/tkMacOSXFont.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * tkMacOSXFont.h --
 *
 *	Contains the Macintosh implementation of the platform-independent
 *	font package interface.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#ifndef TKMACOSXFONT_H
#define TKMACOSXFONT_H 1

#include "tkFont.h"

#ifndef _TKMACINT
#include "tkMacOSXInt.h"
#endif

/*
 * Function prototypes
 */

MODULE_SCOPE Tcl_Obj * TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
	NSFont *nsFont, NSDictionary *nsAttributes);

#endif /*TKMACOSXFONT_H*/



|




















<
<
<
<
<
<
<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24







25
/*
 * tkMacOSXFont.h --
 *
 *	Contains the Macintosh implementation of the platform-independant
 *	font package interface.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#ifndef TKMACOSXFONT_H
#define TKMACOSXFONT_H 1

#include "tkFont.h"

#ifndef _TKMACINT
#include "tkMacOSXInt.h"
#endif








#endif /*TKMACOSXFONT_H*/

Changes to macosx/tkMacOSXHLEvents.c.

1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * tkMacOSXHLEvents.c --
 *
 *	Implements high level event support for the Macintosh.

 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015-2019 Marc Culler
 * Copyright (c) 2019 Kevin Walzer/WordTech Communications LLC.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include <sys/param.h>



|
>


|

|
<







1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
/*
 * tkMacOSXHLEvents.c --
 *
 *	Implements high level event support for the Macintosh. Currently, the
 *	only event that really does anything is the Quit event.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Marc Culler

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include <sys/param.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48




49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330



331
332
333

334
335
336
337

338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362

363
364





365





366
367
368
369

370


371
372


373


374

375

376
377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416



417










418
419



420



421


422
423
424
425
426
427
428
429
430






431
432
433
434
435
436
437


438
439



440
441
442




443


444





445
446

447
448

449
450
451
452
453



454

455
456



457


458
459
460
461
462
463
464
465
466
467
468
469
470
typedef struct KillEvent {
    Tcl_Event header;		/* Information that is standard for all
				 * events. */
    Tcl_Interp *interp;		/* Interp that was passed to the Quit
				 * AppleEvent */
} KillEvent;

/*
 * When processing an AppleEvent as an idle task, a pointer to one
 * of these structs is passed as the clientData.
 */

typedef struct AppleEventInfo {
    Tcl_Interp *interp;
    const char *procedure;
    Tcl_DString command;
    NSAppleEventDescriptor *replyEvent; /* Only used for DoScriptText. */
    int retryCount;
} AppleEventInfo;

/*
 * Static functions used only in this file.
 */





static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);
static void ProcessAppleEvent(ClientData clientData);

/*
 * Names of the procedures which can be used to process AppleEvents.
 */

static const char openDocumentProc[] = "::tk::mac::OpenDocument";
static const char launchURLProc[] = "::tk::mac::LaunchURL";
static const char printDocProc[] = "::tk::mac::PrintDocument";
static const char scriptFileProc[] = "::tk::mac::DoScriptFile";
static const char scriptTextProc[] = "::tk::mac::DoScriptText";

#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
    (void)sender;
    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}

- (void) superTerminate: (id) sender
{
    [super terminate:nil];
}

- (void) preferences: (id) sender
{
    (void)sender;
    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}

- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    KillEvent *eventPtr;
    (void)event;
    (void)replyEvent;

    if (_eventInterp) {
	/*
	 * Call the exit command from the event loop, since you are not
	 * supposed to call ExitToShell in an Apple Event Handler. We put this
	 * at the head of Tcl's event queue because this message usually comes
	 * when the Mac is shutting down, and we want to kill the shell as
	 * quickly as possible.
	 */

	eventPtr = (KillEvent *)ckalloc(sizeof(KillEvent));
	eventPtr->header.proc = ReallyKillMe;
	eventPtr->interp = _eventInterp;

	Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
    }
}

- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{

    (void)event;
    (void)replyEvent;

    [NSApp activateIgnoringOtherApps: YES];

    if (_eventInterp && Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ReopenApplication", NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	    Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    Tcl_Encoding utf8;
    const AEDesc *fileSpecDesc = nil;
    AEDesc contents;
    char URLString[1 + URL_MAX_LENGTH];
    NSURL *fileURL;
    DescType type;
    Size actual;
    long count, index;
    AEKeyword keyword;
    Tcl_DString pathName;
    (void)replyEvent;

    /*
     * Do nothing if we don't have an interpreter.
     */

    if (!_eventInterp) {
	return;
    }

    fileSpecDesc = [event aeDesc];
    if (fileSpecDesc == nil ) {
    	return;
    }

    /*
     * The AppleEvent's descriptor should either contain a value of
     * typeObjectSpecifier or typeAEList.  In the first case, the descriptor
     * can be treated as a list of size 1 containing a value which can be
     * coerced into a fileURL. In the second case we want to work with the list
     * itself.  Values in the list will be coerced into fileURL's if possible;
     * otherwise they will be ignored.
     */

    /* Get a copy of the AppleEvent's descriptor. */
    AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
    if (contents.descriptorType == typeAEList) {
    	fileSpecDesc = &contents;
    }

    if (AECountItems(fileSpecDesc, &count) != noErr) {
	AEDisposeDesc(&contents);
    	return;
    }

    /*
     * Construct a Tcl expression which calls the ::tk::mac::OpenDocument
     * procedure, passing the paths contained in the AppleEvent as arguments.
     */

    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *openCommand = &AEInfo->command;
    Tcl_DStringInit(openCommand);
    Tcl_DStringAppend(openCommand, openDocumentProc, -1);
    utf8 = Tcl_GetEncoding(NULL, "utf-8");

    for (index = 1; index <= count; index++) {
	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
	    continue;
	}
	if (type != typeFileURL) {
	    continue;
	}
	URLString[actual] = '\0';
	fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]];
	if (fileURL == nil) {
	    continue;
	}
	Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
	Tcl_DStringAppendElement(openCommand, Tcl_DStringValue(&pathName));
	Tcl_DStringFree(&pathName);
    }

    Tcl_FreeEncoding(utf8);
    AEDisposeDesc(&contents);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = openDocumentProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;

    if (Tcl_FindCommand(_eventInterp, "::tk::mac::OpenDocuments", NULL, 0)){
	ProcessAppleEvent((ClientData)AEInfo);
    } else {
	Tcl_CreateTimerHandler(500, ProcessAppleEvent, (ClientData)AEInfo);
    }
}

- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
		    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    NSString* file = [[event paramDescriptorForKeyword:keyDirectObject]
			 stringValue];
    const char *printFile = [file UTF8String];
    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *printCommand = &AEInfo->command;
    (void)replyEvent;

    Tcl_DStringInit(printCommand);
    Tcl_DStringAppend(printCommand, printDocProc, -1);
    Tcl_DStringAppendElement(printCommand, printFile);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = printDocProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;
    ProcessAppleEvent((ClientData)AEInfo);
}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
	      withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;
    DescType type = 0, initialType = 0;
    Size actual;

    char URLBuffer[1 + URL_MAX_LENGTH];
    char errString[128];


    /*
     * The DoScript event receives one parameter that should be text data or a
     * fileURL.
     */

    theDesc = [event aeDesc];
    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar, errString, strlen(errString));
	return;
    }

    if (MissedAnyParameters((AppleEvent*)theDesc)) {
    	sprintf(errString, "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar,errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {

	/*
	 * This descriptor can be coerced to a file url.  Construct a Tcl
	 * expression which passes the file path as a string argument to
         * ::tk::mac::DoScriptFile.

	 */

	if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeFileURL, &type,
                                  (Ptr) URLBuffer, URL_MAX_LENGTH, &actual)) {
            if (actual > 0) {
                URLBuffer[actual] = '\0';
                NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
                NSURL *fileURL = [NSURL URLWithString:urlString];
                AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
                Tcl_DString *scriptFileCommand = &AEInfo->command;
                Tcl_DStringInit(scriptFileCommand);
                Tcl_DStringAppend(scriptFileCommand, scriptFileProc, -1);
                Tcl_DStringAppendElement(scriptFileCommand, [[fileURL path] UTF8String]);
                AEInfo->interp = _eventInterp;
                AEInfo->procedure = scriptFileProc;
                AEInfo->replyEvent = nil;
                Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
		AEInfo->retryCount = 0;
                ProcessAppleEvent((ClientData)AEInfo);
            }



        }
    } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			       NULL, 0, &actual)) {

        /*
         * The descriptor cannot be coerced to a file URL but can be coerced to
         * text.  Construct a Tcl expression which passes the text as a string
         * argument to ::tk::mac::DoScriptText.

         */

	if (actual > 0) {
	    char *data = (char *)ckalloc(actual + 1);
	    if (noErr == AEGetParamPtr(theDesc, keyDirectObject,
				       typeUTF8Text, &type,
				       data, actual, NULL)) {
		data[actual] = '\0';
		AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));

		Tcl_DString *scriptTextCommand = &AEInfo->command;
		Tcl_DStringInit(scriptTextCommand);
		Tcl_DStringAppend(scriptTextCommand, scriptTextProc, -1);
		Tcl_DStringAppendElement(scriptTextCommand, data);
		AEInfo->interp = _eventInterp;
		AEInfo->procedure = scriptTextProc;
		AEInfo->retryCount = 0;
                if (Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
                    AEInfo->replyEvent = replyEvent;
                    ProcessAppleEvent(AEInfo);
                } else {
                    AEInfo->replyEvent = nil;
                    Tcl_DoWhenIdle(ProcessAppleEvent, AEInfo);
                    ProcessAppleEvent(AEInfo);

                }
	    }

	}
    }





}






- (void)handleURLEvent:(NSAppleEventDescriptor*)event
        withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{

    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]


                        stringValue];
    const char *cURL=[url UTF8String];


    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));


    Tcl_DString *launchCommand = &AEInfo->command;

    (void)replyEvent;


    Tcl_DStringInit(launchCommand);
    Tcl_DStringAppend(launchCommand, launchURLProc, -1);
    Tcl_DStringAppendElement(launchCommand, cURL);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = launchURLProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;
    ProcessAppleEvent((ClientData)AEInfo);
}


@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * ProcessAppleEvent --
 *
 *      Usually used as an idle task which evaluates a Tcl expression generated
 *      from an AppleEvent.  If the AppleEventInfo passed as the client data
 *      has a non-null replyEvent, the result of evaluating the expression will
 *      be added to the reply.  This must not be done when this function is
 *      called as an idle task, but is done when handling DoScriptText events
 *      when this function is called directly.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The expression will be evaluated and the clientData will be freed.
 *      The replyEvent may be modified to contain the result of evaluating
 *      a Tcl expression.
 *
 *----------------------------------------------------------------------
 */

static void ProcessAppleEvent(

    ClientData clientData)



{










    int code;
    AppleEventInfo *AEInfo = (AppleEventInfo*) clientData;







    if (!AEInfo->interp) {


	return;
    }

    /*
     * Apple events that are delivered during the app startup can arrive
     * before the Tcl procedure for handling the events has been defined.
     * If the command is not found we create a timer handler to process
     * the event later, hopefully after the command has been created.
     * We retry up to 2 times before giving up.






     */

    if (!Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
	if (AEInfo->retryCount < 2) {
	    AEInfo->retryCount++;
	    Tcl_CreateTimerHandler(200, ProcessAppleEvent, clientData);
	} else {


	    ckfree(clientData);
	}



	return;
    }
    code = Tcl_EvalEx(AEInfo->interp, Tcl_DStringValue(&AEInfo->command),




	    Tcl_DStringLength(&AEInfo->command), TCL_EVAL_GLOBAL);








    if (AEInfo->replyEvent && code >= 0) {
        int reslen;

        const char *result = Tcl_GetStringFromObj(Tcl_GetObjResult(AEInfo->interp),
                                                  &reslen);

        if (code == TCL_OK) {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyDirectObject, typeChar, result, reslen);
        } else {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],



                          keyErrorString, typeChar, result, reslen);

            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyErrorNumber, typeSInt32, (Ptr) &code, sizeof(int));



        }


    } else if (code != TCL_OK) {
	Tcl_BackgroundException(AEInfo->interp, code);
    }

    Tcl_DStringFree(&AEInfo->command);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitAppleEvents --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<




>
>
>
>


<
<
<
<
<
<
<
<
<
<
<






<



<
<
<
<
<


<



|



<
<










|







|


|
<

|




|




|


>
|
|
|
|
>





|




|


<
<
<





|




|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<


|
|

<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<


|
|





>


>















|
|


|


|
|




<

|
<
|
>

<
|
|
|
|
|
|
<
|
|
|
|
<
|
<
|
<
<
|
>
>
>
|

|
>
|
|
<
|
>
|
<
<
|
|
<
|
<
<
>
|
|
|
|
|
<
<
|
<
<
|
<
<
<
>
|

>

|
>
>
>
>
>
|
>
>
>
>
>
|
<
<
<
>
|
>
>
|
|
>
>
|
>
>
|
>
|
>
|
<
<
<
<
<
<
<
<
<
|
>
|







|

<
|
<
<
<
|





|
<
<




|
>
|
>
>
>

>
>
>
>
>
>
>
>
>
>

|
>
>
>

>
>
>
|
>
>
|

|

<
<
<
<
<
>
>
>
>
>
>

|
<
<
<
|
<
>
>
|
|
>
>
>
|

|
>
>
>
>
|
>
>

>
>
>
>
>
|
|
>
|
<
>
|
<
<
|
<
>
>
>
|
>
|
|
>
>
>
|
>
>
|
|

<
|
|







25
26
27
28
29
30
31













32
33
34
35
36
37
38
39
40
41











42
43
44
45
46
47

48
49
50





51
52

53
54
55
56
57
58
59


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114



115
116
117
118
119
120
121
122
123
124
125
126
127


















































































128




129
130
131
132
133






134









135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177

178
179
180

181
182
183
184
185
186

187
188
189
190

191

192


193
194
195
196
197
198
199
200
201
202

203
204
205


206
207

208


209
210
211
212
213
214


215


216



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250









251
252
253
254
255
256
257
258
259
260
261
262

263



264
265
266
267
268
269
270


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307





308
309
310
311
312
313
314
315



316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345


346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
typedef struct KillEvent {
    Tcl_Event header;		/* Information that is standard for all
				 * events. */
    Tcl_Interp *interp;		/* Interp that was passed to the Quit
				 * AppleEvent */
} KillEvent;














/*
 * Static functions used only in this file.
 */

static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event, 
				 NSAppleEventDescriptor* replyEvent,
				 Tcl_Interp *interp,
				 char* procedure);
static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);












#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{

    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}






- (void) preferences: (id) sender
{

    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}

- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    KillEvent *eventPtr;



    if (_eventInterp) {
	/*
	 * Call the exit command from the event loop, since you are not
	 * supposed to call ExitToShell in an Apple Event Handler. We put this
	 * at the head of Tcl's event queue because this message usually comes
	 * when the Mac is shutting down, and we want to kill the shell as
	 * quickly as possible.
	 */

	eventPtr = (KillEvent*)ckalloc(sizeof(KillEvent));
	eventPtr->header.proc = ReallyKillMe;
	eventPtr->interp = _eventInterp;

	Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
    }
}

- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
   Tcl_Interp *interp = _eventInterp;


    if (interp &&
	Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
    ProcessSerialNumber thePSN = {0, kCurrentProcess};
    SetFrontProcess(&thePSN);
#else
    [[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
#endif
    if (_eventInterp && Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ReopenApplication", NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{



    if (_eventInterp &&
	    Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{


















































































    tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::OpenDocument");




}

- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{






    tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::PrintDocument");









}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;
    DescType type = 0, initialType = 0;
    Size actual;
    int tclErr = -1;
    char URLBuffer[1 + URL_MAX_LENGTH];
    char errString[128];
    char typeString[5];

    /*
     * The DoScript event receives one parameter that should be text data or a
     * fileURL.
     */

    theDesc = [event aeDesc];
    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
		      errString, strlen(errString));
	return;
    }
    
    if (MissedAnyParameters((AppleEvent*)theDesc)) {
    	sprintf(errString, "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
    		      errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {

	/*
	 * The descriptor can be coerced to a file url.  Source the file, or

	 * pass the path as a string argument to ::tk::mac::DoScriptFile if
	 * that procedure exists.
	 */

	err = AEGetParamPtr(theDesc, keyDirectObject, typeFileURL, &type,
			    (Ptr) URLBuffer, URL_MAX_LENGTH, &actual);
	if (err == noErr && actual > 0){
	    URLBuffer[actual] = '\0';
	    NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
	    NSURL *fileURL = [NSURL URLWithString:urlString];

	    Tcl_DString command;
	    Tcl_DStringInit(&command);
	    if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptFile", NULL, 0)){
		Tcl_DStringAppend(&command, "::tk::mac::DoScriptFile", -1);

	    } else {

		Tcl_DStringAppend(&command, "source", -1);


	    }
	    Tcl_DStringAppendElement(&command, [[fileURL path] UTF8String]);
	    tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
				 Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
	}
    } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			   NULL, 0, &actual)) {
	if (actual > 0) {
	    /*
	     * The descriptor can be coerced to UTF8 text.  Evaluate as Tcl, or

	     * or pass the text as a string argument to ::tk::mac::DoScriptText
	     * if that procedure exists.
	     */ 


	    char *data = ckalloc(actual + 1);
	    if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,

			    data, actual, NULL)) {


		if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptText", NULL, 0)){
		    Tcl_DString command;
		    Tcl_DStringInit(&command);
		    Tcl_DStringAppend(&command, "::tk::mac::DoScriptText", -1);
		    Tcl_DStringAppendElement(&command, data);
		    tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),


				 Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);


		} else {



		    tclErr = Tcl_EvalEx(_eventInterp, data, actual, TCL_EVAL_GLOBAL);
		}
	    }
	    ckfree(data);
	}
    } else {
	/*
	 * The descriptor can not be coerced to a fileURL or UTF8 text.
	 */
	for (int i = 0; i < 4; i++) {
	    typeString[i] = ((char*)&initialType)[3-i];
	}
	typeString[4] = '\0';
	sprintf(errString, "AEDoScriptHandler: invalid script type '%s', "
		"must be coercable to 'furl' or 'utf8'", typeString);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar, errString,
		      strlen(errString));
    }



    /*
     * If we ran some Tcl code, put the result in the reply.
     */
    if (tclErr >= 0) {
	int reslen;
	const char *result =
	    Tcl_GetStringFromObj(Tcl_GetObjResult(_eventInterp), &reslen);
	if (tclErr == TCL_OK) {
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyDirectObject, typeChar,
			  result, reslen);
	} else {
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
			  result, reslen);
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorNumber, typeSInt32,
			  (Ptr) &tclErr,sizeof(int));
	}









    }
    return;
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXProcessFiles --
 *

 *	Extract a list of fileURLs from an AppleEvent and call the specified



 *      procedure with the file paths as arguments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The event is handled by running the procedure.


 *
 *----------------------------------------------------------------------
 */

static void
tkMacOSXProcessFiles(
    NSAppleEventDescriptor* event, 
    NSAppleEventDescriptor* replyEvent,
    Tcl_Interp *interp,
    char* procedure)
{
    Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
    const AEDesc *fileSpecDesc = nil;
    AEDesc contents;
    char URLString[1 + URL_MAX_LENGTH];
    NSURL *fileURL;
    DescType type;
    Size actual;
    long count, index;
    AEKeyword keyword;
    Tcl_DString command, pathName;
    int code;

    /*
     * Do nothing if we don't have an interpreter or the procedure doesn't exist.
     */

    if (!interp || !Tcl_FindCommand(interp, procedure, NULL, 0)) {
	return;
    }
    
    fileSpecDesc = [event aeDesc];
    if (fileSpecDesc == nil ) {
    	return;
    }
    
    /*





     * The AppleEvent's descriptor should either contain a value of
     * typeObjectSpecifier or typeAEList.  In the first case, the descriptor
     * can be treated as a list of size 1 containing a value which can be
     * coerced into a fileURL. In the second case we want to work with the list
     * itself.  Values in the list will be coerced into fileURL's if possible;
     * otherwise they will be ignored.
     */
    



    /* Get a copy of the AppleEvent's descriptor. */

    AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
    if (contents.descriptorType == typeAEList) {
    	fileSpecDesc = &contents;
    }
    
    if (AECountItems(fileSpecDesc, &count) != noErr) {
	AEDisposeDesc(&contents);
    	return;
    }
    
    /*    
     * Construct a Tcl command which calls the procedure, passing the
     * paths contained in the AppleEvent as arguments.
     */
    
    Tcl_DStringInit(&command);
    Tcl_DStringAppend(&command, procedure, -1);

    for (index = 1; index <= count; index++) {
	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
	    continue;
	}
	if (type != typeFileURL) {
	    continue;
	}
	URLString[actual] = '\0';

	fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]]; 
	if (fileURL == nil) {


	    continue;

	}
	Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
	Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
	Tcl_DStringFree(&pathName);
    }
    AEDisposeDesc(&contents);

    /*
     * Handle the event by evaluating the Tcl expression we constructed.
     */

    code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
	    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundError(interp);
    }

    Tcl_DStringFree(&command);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitAppleEvents --
 *
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitAppleEvents(
    TCL_UNUSED(Tcl_Interp *))
{
    NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;








|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitAppleEvents(
    Tcl_Interp *interp)   /* not used */
{
    NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
	    forEventClass:kCoreEventClass andEventID:kAEShowPreferences];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handlePrintDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
	    forEventClass:kAEMiscStandards andEventID:kAEDoScript];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleURLEvent:withReplyEvent:)
	    forEventClass:kInternetEventClass andEventID:kAEGetURL];

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --







|





<
<
<
<
<







408
409
410
411
412
413
414
415
416
417
418
419
420





421
422
423
424
425
426
427
	    forEventClass:kCoreEventClass andEventID:kAEShowPreferences];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
	    forEventClass:kAEMiscStandards andEventID:kAEDoScript];





    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
}

/*
 *----------------------------------------------------------------------
 *
 * ReallyKillMe --
 *
 *	This procedure tries to kill the shell by running exit, called from
 *      an event scheduled by the "Quit" AppleEvent handler.
 *
 * Results:
 *	Runs the "exit" command which might kill the shell.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ReallyKillMe(
    Tcl_Event *eventPtr,
    TCL_UNUSED(int))
{
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;

    int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL;

    if (!quit) {
	Tcl_Exit(0);
    }

    int code = Tcl_EvalEx(interp, "::tk::mac::Quit", -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {

	/*
	 * Should be never reached...
	 */

	Tcl_BackgroundException(interp, code);
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
 *







|
|









<



|


>
|
|
<
<
|
<
<

<




|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495


496


497

498
499
500
501
502
503
504
505
506
507
508
509
}

/*
 *----------------------------------------------------------------------
 *
 * ReallyKillMe --
 *
 *	This proc tries to kill the shell by running exit, called from an
 *	event scheduled by the "Quit" AppleEvent handler.
 *
 * Results:
 *	Runs the "exit" command which might kill the shell.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ReallyKillMe(
    Tcl_Event *eventPtr,
    int flags)
{
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    Tcl_CmdInfo dummy;
    int quit = Tcl_GetCommandInfo(interp, "::tk::mac::Quit", &dummy);
    int code = Tcl_EvalEx(interp, quit ? "::tk::mac::Quit" : "exit", -1, TCL_EVAL_GLOBAL);





    if (code != TCL_OK) {

	/*
	 * Should be never reached...
	 */

	Tcl_BackgroundError(interp);
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
   Size actualSize;
   OSStatus err;

   err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr,
	    typeWildCard, &returnedType, NULL, 0, &actualSize);

   return (err != errAEDescNotFound);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|









528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
   Size actualSize;
   OSStatus err;

   err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr,
	    typeWildCard, &returnedType, NULL, 0, &actualSize);

   return (err != errAEDescNotFound);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Deleted macosx/tkMacOSXImage.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
/*
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages,
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2017-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"

static CGImageRef CreateCGImageFromPixmap(Drawable pixmap);
static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable,
	   int x, int y, unsigned int width, unsigned int height);

#pragma mark XImage handling

int
_XInitImageFuncPtrs(
    TCL_UNUSED(XImage *)) /* image */
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.  Called
 *      in Tk_PutImage and (currently) nowhere else.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(
    void *info,
    TCL_UNUSED(const void *), /* data */
    TCL_UNUSED(size_t))       /* size */
{
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)
{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
    char *data = NULL;
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */

	/* Reverses the sense of the bits */
	static const CGFloat decodeWB[2] = {1, 0};
	decode = decodeWB;

	bitsPerComponent = 1;
	bitsPerPixel = 1;
	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = (char *)ckalloc(len));

	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	}
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height,
		    bitsPerComponent, bitsPerPixel, image->bytes_per_line,
		    provider, decode, 0);
	}
    } else if ((image->format == ZPixmap) && (image->bits_per_pixel == 32)) {
	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	if (image->width == 0 && image->height == 0) {
	    /*
	     * CGCreateImage complains on early macOS releases.
	     */

	    return NULL;
	}
	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
	bitmapInfo |= kCGImageAlphaLast;
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CFRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyImage --
 *
 *	Destroys storage associated with an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deallocates the image.
 *
 *----------------------------------------------------------------------
 */

static int
DestroyImage(
    XImage *image)
{
    if (image) {
	if (image->data) {
	    ckfree(image->data);
	}
	ckfree(image);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageGetPixel --
 *
 *	Get a single pixel from an image.
 *
 * Results:
 *      The XColor structure contains an unsigned long field named pixel which
 *      identifies the color.  This function returns the unsigned long that
 *      would be used as the pixel value of an XColor that has the same red
 *      green and blue components as the XImage pixel at the specified
 *      location.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned long
ImageGetPixel(
    XImage *image,
    int x,
    int y)
{
    unsigned char r = 0, g = 0, b = 0;

    /*
     * Compute 8 bit red green and blue values, which are passed as inputs to
     * TkMacOSXRGBPixel to produce the pixel value.
     */

    if (image && image->data) {
	unsigned char *srcPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	case 32: /* 8 bits per channel */
	    r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
	    g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
	    b = (*((unsigned int*) srcPtr)      ) & 0xff;
	    /*if (image->byte_order == LSBFirst) {
		r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
	    } else {
		r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
	    }*/
	    break;
	case 16: /* 5 bits per channel */
	    r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
	    g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
	    b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
	    break;
	case 8: /* 2 bits per channel */
	    r = (*srcPtr << 2) & 0xc0;
	    g = (*srcPtr << 4) & 0xc0;
	    b = (*srcPtr << 6) & 0xc0;
	    r |= r >> 2 | r >> 4 | r >> 6;
	    g |= g >> 2 | g >> 4 | g >> 6;
	    b |= b >> 2 | b >> 4 | b >> 6;
	    break;
	case 4: { /* 1 bit per channel */
	    unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);

	    r = (c & 0x04) ? 0xff : 0;
	    g = (c & 0x02) ? 0xff : 0;
	    b = (c & 0x01) ? 0xff : 0;
	    break;
	}
	case 1: /* Black-white bitmap. */
	    r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
	    break;
	}
    }

    return TkMacOSXRGBPixel(r, g, b);
}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
 *	Set a single pixel in an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImagePutPixel(
    XImage *image,
    int x,
    int y,
    unsigned long pixel)
{
    if (image && image->data) {
	unsigned char *dstPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	if (image->bits_per_pixel == 32) {
	    *((unsigned int*) dstPtr) = pixel;
	} else {
	    unsigned char r = ((pixel & image->red_mask)   >> 16) & 0xff;
	    unsigned char g = ((pixel & image->green_mask) >>  8) & 0xff;
	    unsigned char b = ((pixel & image->blue_mask)       ) & 0xff;
	    switch (image->bits_per_pixel) {
	    case 16:
		*((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
		break;
	    case 8:
		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
			((b & 0xc0) >> 6);
		break;
	    case 4: {
		unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
			((b & 0x80) >> 7);
		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
			((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
		break;
		}
	    case 1:
		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
			(*dstPtr & ~(0x80 >> (x % 8)));
		break;
	    }
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * XCreateImage --
 *
 *	Allocates storage for a new XImage.
 *
 * Results:
 *	Returns a newly allocated XImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    TCL_UNUSED(Visual*),  /* visual */
    unsigned int depth,
    int format,
    int offset,
    char* data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage *ximage;

    display->request++;
    ximage = ckalloc(sizeof(XImage));

    ximage->height = height;
    ximage->width = width;
    ximage->depth = depth;
    ximage->xoffset = offset;
    ximage->format = format;
    ximage->data = data;
    ximage->obdata = NULL;

    if (format == ZPixmap) {
	ximage->bits_per_pixel = 32;
	ximage->bitmap_unit = 32;
    } else {
	ximage->bits_per_pixel = 1;
	ximage->bitmap_unit = 8;
    }
    if (bitmap_pad) {
	ximage->bitmap_pad = bitmap_pad;
    } else {
	/*
	 * Use 16 byte alignment for best Quartz perfomance.
	 */

	ximage->bitmap_pad = 128;
    }
    if (bytes_per_line) {
	ximage->bytes_per_line = bytes_per_line;
    } else {
	ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
		(ximage->bitmap_pad - 1)) >> 3) &
		~((ximage->bitmap_pad >> 3) - 1);
    }
#ifdef WORDS_BIGENDIAN
    ximage->byte_order = MSBFirst;
    ximage->bitmap_bit_order = MSBFirst;
#else
    ximage->byte_order = LSBFirst;
    ximage->bitmap_bit_order = LSBFirst;
#endif
    ximage->red_mask = 0x00FF0000;
    ximage->green_mask = 0x0000FF00;
    ximage->blue_mask = 0x000000FF;
    ximage->f.create_image = NULL;
    ximage->f.destroy_image = DestroyImage;
    ximage->f.get_pixel = ImageGetPixel;
    ximage->f.put_pixel = ImagePutPixel;
    ximage->f.sub_image = NULL;
    ximage->f.add_pixel = NULL;

    return ximage;
}

/*
 *----------------------------------------------------------------------
 *
 * XPutImage --
 *
 *	Copies a rectangular subimage of an XImage into a drawable.  Currently
 *      this is only called by TkImgPhotoDisplay, using a Window as the
 *      drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

int
XPutImage(
    Display* display,		/* Display. */
    Drawable drawable,		/* Drawable to place image on. */
    GC gc,			/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *)drawable;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);

	/*
	 * The CGContext for a pixmap is RGB only, with A = 0.
	 */

	if (!(macDraw->flags & TK_IS_PIXMAP)) {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromDrawableRect
 *
 *	Extract image data from a MacOSX drawable as a CGImage.
 *
 *      This is only called by XGetImage and XCopyArea.  The Tk core uses
 *      these functions on some platforms, but on macOS the core does not
 *      call them with a source drawable which is a window.  Such calls are
 *      used only for double-buffered drawing.  Since macOS defines the
 *      macro TK_NO_DOUBLE_BUFFERING, the generic code never calls XGetImage
 *      or XCopyArea on macOS.  Nonetheless, these function are in the stubs
 *      table and therefore could be used by extensions.
 *
 *      This implementation does not work correctly.  Originally it relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect]. To further complicate
 *      matters, cacheDisplayInRect calls [NSView drawRect]. Essentially it is
 *      asking the view to draw a subrectangle of itself using a special
 *      graphics context which is linked to the BitmapImageRep. But our
 *      implementation of [NSView drawRect] does not allow recursive calls. If
 *      called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image. To make it useful would require a significant amount
 *      of rewriting of the drawRect method. Perhaps the next release of OSX
 *      will include some more helpful ways of doing this.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given rectangle of
 *      the given drawable. This object is retained. The caller is responsible
 *      for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system
 *      with origin at the top left, as used by XImage and CGImage, not bottom
 *      left as used by NSView.
 *
 * Side effects:
 *     None
 *
 *----------------------------------------------------------------------
 */

static CGImageRef
CreateCGImageFromDrawableRect(
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *)drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image = NULL, result = NULL;
    NSBitmapImageRep *bitmapRep = NULL;
    NSView *view = NULL;
    if (mac_drawable->flags & TK_IS_PIXMAP) {
	/*
	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	CGRect image_rect = CGRectMake(x, y, width, height);

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
	if (cg_image) {
	    result = CGImageCreateWithImageInRect(cg_image, image_rect);
	    CGImageRelease(cg_image);
	}
    } else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != NULL) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
		view_height - height - y - mac_drawable->yOff,
		width, height);

	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	 * and make a big mess. So, in that case, we just return NULL.
	 */

	if (view == [NSView focusView]) {
	    bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
	    result = [bitmapRep CGImage];
	    CFRelease(bitmapRep);
	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    result = NULL;
	}
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromPixmap --
 *
 *	Create a CGImage from an X Pixmap.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static CGImageRef
CreateCGImageFromPixmap(
    Drawable pixmap)
{
    CGImageRef img = NULL;
    CGContextRef context = TkMacOSXGetCGContextForDrawable(pixmap);

    if (context) {
	img = CGBitmapContextCreateImage(context);
    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.  It
 *      is essentially never used. At one time it was called by
 *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
 *      called two places, one of which is requesting an XY image which we do
 *      not support.  It probably does not work correctly -- see the comments
 *      for CGImageFromDrawableRect.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
struct pixel_fmt {int r; int g; int b; int a;};
static struct pixel_fmt bgra = {2, 1, 0, 3};
static struct pixel_fmt abgr = {3, 2, 1, 0};

XImage *
XGetImage(
    Display *display,
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height,
    TCL_UNUSED(unsigned long), /* plane_mask */
    int format)
{
    NSBitmapImageRep* bitmapRep = NULL;
    NSUInteger bitmap_fmt = 0;
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;

    if (format == ZPixmap) {
	CGImageRef cgImage;
	if (width == 0 || height == 0) {
	    return NULL;
	}

	cgImage = CreateCGImageFromDrawableRect(drawable, x, y, width, height);
	if (cgImage) {
	    bitmapRep = [NSBitmapImageRep alloc];
	    [bitmapRep initWithCGImage:cgImage];
	    CFRelease(cgImage);
	} else {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct CGImage");
	    return NULL;
	}
	bitmap_fmt = [bitmapRep bitmapFormat];
	size = [bitmapRep bytesPerPlane];
	bytes_per_row = [bitmapRep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap
		|| (bitmap_fmt != 0 && bitmap_fmt != 1)
		|| [bitmapRep samplesPerPixel] != 4
		|| [bitmapRep isPlanar] != 0
		|| bytes_per_row < 4 * width
		|| size != bytes_per_row * height) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmapRep);
	    return NULL;
	}
	memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
	CFRelease(bitmapRep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in either
	 * BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

	for (row = 0, n = 0; row < height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*width; m += 4) {
		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
		*(bitmap + m + 2) = B;
		*(bitmap + m + 3) = A;
	    }
	}
	imagePtr = XCreateImage(display, NULL, depth, format, offset,
		(char*) bitmap, width, height,
		bitmap_pad, bytes_per_row);
    } else {
	/*
	 * There are some calls to XGetImage in the generic Tk code which pass
	 * an XYPixmap rather than a ZPixmap.  XYPixmaps should be handled
	 * here.
	 */
	TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
    }
    return imagePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyArea --
 *
 *	Copies image data from one drawable to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Image data is moved from a window or bitmap to a second window or bitmap.
 *
 *----------------------------------------------------------------------
 */

int
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,			/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,		/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;
    if (!width || !height) {
	return BadDrawable;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	TkMacOSXDbgMsg("Failed to setup drawing context.");
	return BadDrawable;
    }

    if (!dc.context) {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return BadDrawable;
    }

    if (srcDraw->flags & TK_IS_PIXMAP) {
	img = CreateCGImageFromPixmap(src);
    } else if (TkMacOSXGetNSWindowForDrawable(src)) {
	img = CreateCGImageFromDrawableRect(src, src_x, src_y, width, height);
    } else {
	TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
    }

    if (img) {
	bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
	srcRect = CGRectMake(src_x, src_y, width, height);
	dstRect = CGRectMake(dest_x, dest_y, width, height);
	TkMacOSXDrawCGImage(dst, gc, dc.context, img,
		gc->foreground, gc->background, bounds, srcRect, dstRect);
	CFRelease(img);
    } else {
	TkMacOSXDbgMsg("Failed to construct CGImage.");
    }

    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyPlane --
 *
 *	Copies a bitmap from a source drawable to a destination drawable. The
 *	plane argument specifies which bit plane of the source contains the
 *	bitmap. Note that this implementation ignores the gc->function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the destination drawable.
 *
 *----------------------------------------------------------------------
 */

int
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    MacDrawable *dstDraw = (MacDrawable *)dst;
    CGRect bounds, srcRect, dstRect;
    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return BadDrawable;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	    return BadDrawable;
	}

	CGContextRef context = dc.context;

	if (context) {
	    CGImageRef img = CreateCGImageFromPixmap(src);

	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;

                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP) {
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = CreateCGImageFromPixmap(
			    clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);

		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);

		    /*
		     * Move the origin of the destination to top left.
		     */

		    CGContextTranslateCTM(context,
			    0, rect.origin.y + CGRectGetMaxY(rect));
		    CGContextScaleCTM(context, 1, -1);

		    /*
		     * Fill with the background color, clipping to the mask.
		     */

		    CGContextClipToMask(context, rect, submask);
		    TkMacOSXSetColorInContext(gc, gc->background, dc.context);
		    CGContextFillRect(context, rect);

		    /*
		     * Fill with the foreground color, clipping to the
		     * intersection of img and mask.
		     */

		    CGImageRef subimage = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGContextClipToMask(context, rect, subimage);
		    TkMacOSXSetColorInContext(gc, gc->foreground, context);
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {
		    bounds = CGRectMake(0, 0,
			    srcDraw->size.width, srcDraw->size.height);
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    dstRect = CGRectMake(dest_x, dest_y, width, height);
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
			    gc->foreground, imageBackground, bounds,
			    srcRect, dstRect);
		    CGImageRelease(img);
		}
	    } else {
		/* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - "
		    "could not get a bitmap context.");
	}
	TkMacOSXRestoreDrawingContext(&dc);
	return Success;
    } else {
	/*
	 * Source drawable is a Window, not a Pixmap.
	 */

	return XCopyArea(display, src, dst, gc, src_x, src_y, width, height,
		dest_x, dest_y);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to macosx/tkMacOSXInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16





17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32




33

34



35








36
37


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90



91
92


93



94
95
96
97
98
99





100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * tkMacOSXInit.c --
 *
 *	This file contains Mac OS X -specific interpreter initialization
 *	functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2017 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"





#include <dlfcn.h>
#include <objc/objc-auto.h>
#include <sys/stat.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";


/*
 * Forward declarations...
 */






static int		TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip,



			    int objc, Tcl_Obj *const objv[]);









#pragma mark TKApplication(TKInit)



@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macOSVersion = _macOSVersion;
@synthesize isDrawing = _isDrawing;
@synthesize needsToDraw = _needsToDraw;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK

@implementation TKApplication(TKInit)
- (void) _resetAutoreleasePool
{
    if ([self poolLock] == 0) {
	[_mainPool drain];
	_mainPool = [NSAutoreleasePool new];
    } else {
#ifdef DEBUG_LOCK
	fprintf(stderr, "Pool is locked with count %d!!!!\n", [self poolLock]);
#endif
    }
}
- (void) _lockAutoreleasePool
{
    [self setPoolLock:[self poolLock] + 1];
}
- (void) _unlockAutoreleasePool
{
    [self setPoolLock:[self poolLock] - 1];
}
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void) _postedNotification: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
#endif

- (void) _setupApplicationNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]
    observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
    observe(NSApplicationWillResignActiveNotification, applicationDeactivate:);
    observe(NSApplicationDidUnhideNotification, applicationShowHide:);
    observe(NSApplicationDidHideNotification, applicationShowHide:);
    observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
    observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:);
#undef observe



}



-(void)applicationWillFinishLaunching:(NSNotification *)aNotification



{
    (void)aNotification;

    /*
     * Initialize notifications.
     */





#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    [[NSNotificationCenter defaultCenter] addObserver:self
	    selector:@selector(_postedNotification:) name:nil object:nil];
#endif
    [self _setupWindowNotifications];
    [self _setupApplicationNotifications];

    /*
     * Construct the menu bar.
     */
    _defaultMainMenu = nil;
    [self _setupMenus];

    /*
     * Initialize event processing.
     */

    TkMacOSXInitAppleEvents(_eventInterp);

    /*
     * Initialize the graphics context.
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
    (void)notification;

    /*
     * It is not safe to force activation of the NSApp until this method is
     * called. Activating too early can cause the menu bar to be unresponsive.
     * The call to activateIgnoringOtherApps was moved here to avoid this.
     * However, with the release of macOS 10.15 (Catalina) that was no longer
     * sufficient.  (See ticket bf93d098d7.)  The call to setActivationPolicy
     * needed to be moved into this function as well.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    [NSApp activateIgnoringOtherApps: YES];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
    [NSApp _unlockAutoreleasePool];
}

- (void) _setup: (Tcl_Interp *) interp
{
    /*
     * Remember our interpreter.
     */
    _eventInterp = interp;

    /*
     * Install the global autoreleasePool.
     */
    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolLock:0];

    /*
     * Record the OS version we are running on.
     */

    int minorVersion, majorVersion;
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
    Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
    majorVersion = 10;
#else
    NSOperatingSystemVersion systemVersion;
    systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    majorVersion = systemVersion.majorVersion;
    minorVersion = systemVersion.minorVersion;
#endif
    [NSApp setMacOSVersion: 10000*majorVersion + 100*minorVersion];

    /*
     * We are not drawing right now.
     */

    [NSApp setIsDrawing:NO];

    /*
     * Be our own delegate.
     */

    [self setDelegate:self];

    /*
     * If no icon has been set from an Info.plist file, use the Wish icon from
     * the Tk framework.
     */

    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
						    @"CFBundleIconFile"];
    if (!iconFile) {
	NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
	if (path) {
	    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
	    if (image) {
		[NSApp setApplicationIconImage:image];
		[image release];
	    }
	}
    }
}

- (NSString *) tkFrameworkImagePath: (NSString *) image
{
    NSString *path = nil;
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    if (tkLibPath[0] != '\0') {
	path = [[NSBundle bundleWithPath:[[NSString stringWithUTF8String:
		tkLibPath] stringByAppendingString:@"/../.."]]
		pathForImageResource:image];
    }
    if (!path) {
	const char *tk_library = Tcl_GetVar2(_eventInterp, "tk_library", NULL,
		TCL_GLOBAL_ONLY);

	if (tk_library) {
	    NSFileManager *fm = [NSFileManager defaultManager];

	    path = [[NSString stringWithUTF8String:tk_library]
		    stringByAppendingFormat:@"/%@", image];
	    if (![fm isReadableFileAtPath:path]) {
		path = [[NSString stringWithUTF8String:tk_library]
			stringByAppendingFormat:@"/../macosx/%@", image];
		if (![fm isReadableFileAtPath:path]) {
		    path = nil;









<






>
>
>
>
>


<










>
|
|
|
>
>
>
>
|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
|
|
>
>


|
<
<
<


<
<
<
<
<
<



|


<
<
<
<


<
|
<
<
<
<
<
<

|
<




|
<

<
|

|





>
>
>


>
>
|
>
>
>
|
|
|
<
<
<
>
>
>
>
>






|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<










<


<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64






65
66
67
68
69
70




71
72

73






74
75

76
77
78
79
80

81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103



104
105
106
107
108
109
110
111
112
113
114
115





116



































































































117

118
119
120
121
122
123
124
125
126
127

128
129

130
131
132
133
134
135
136
/*
 * tkMacOSXInit.c --
 *
 *	This file contains Mac OS X -specific interpreter initialization
 *	functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"

#include "tclInt.h" /* for Tcl_GetStartupScript() & Tcl_SetStartupScript() */

#include <sys/stat.h>
#include <sys/utsname.h>
#include <dlfcn.h>
#include <objc/objc-auto.h>


static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";

long tkMacOSXMacOSXVersion = 0;

#pragma mark TKApplication(TKInit) 

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#define NSTextInputContextKeyboardSelectionDidChangeNotification @"NSTextInputContextKeyboardSelectionDidChangeNotification"
static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    [[NSNotificationCenter defaultCenter] postNotificationName:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil userInfo:nil];
}
#endif

@interface TKApplication(TKKeyboard)
- (void)keyboardChanged:(NSNotification *)notification;
@end

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
#else
#define TKApplication_NSApplicationDelegate
#endif
@interface TKApplication(TKWindowEvent) TKApplication_NSApplicationDelegate
- (void)_setupWindowNotifications;
@end

@interface TKApplication(TKMenus)
- (void)_setupMenus;
@end

@implementation TKApplication
@synthesize poolProtected = _poolProtected;



@end







@implementation TKApplication(TKInit)
- (void) _resetAutoreleasePool
{
    if(![self poolProtected]) {
	[_mainPool drain];
	_mainPool = [NSAutoreleasePool new];




    }
}








#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void)_postedNotification:(NSNotification *)notification {

    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
#endif

- (void)_setupApplicationNotifications {

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) [nc addObserver:self selector:@selector(s) name:(n) object:nil]
    observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
    observe(NSApplicationDidResignActiveNotification, applicationDeactivate:);
    observe(NSApplicationDidUnhideNotification, applicationShowHide:);
    observe(NSApplicationDidHideNotification, applicationShowHide:);
    observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
    observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:);
#undef observe
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), NULL, &keyboardChanged, kTISNotifySelectedKeyboardInputSourceChanged, NULL, CFNotificationSuspensionBehaviorCoalesce);
#endif
}

- (void)_setupEventLoop {
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    [self finishLaunching];
    [self setWindowsNeedUpdate:YES];
    [pool drain];
}

- (void)_setup:(Tcl_Interp *)interp {
    _eventInterp = interp;



    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolProtected:NO];
    _defaultMainMenu = nil;
    [self _setupMenus];
    [self setDelegate:self];
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    [[NSNotificationCenter defaultCenter] addObserver:self
	    selector:@selector(_postedNotification:) name:nil object:nil];
#endif
    [self _setupWindowNotifications];
    [self _setupApplicationNotifications];
}









































































































- (NSString *)tkFrameworkImagePath:(NSString*)image {

    NSString *path = nil;
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    if (tkLibPath[0] != '\0') {
	path = [[NSBundle bundleWithPath:[[NSString stringWithUTF8String:
		tkLibPath] stringByAppendingString:@"/../.."]]
		pathForImageResource:image];
    }
    if (!path) {
	const char *tk_library = Tcl_GetVar2(_eventInterp, "tk_library", NULL,
		TCL_GLOBAL_ONLY);

	if (tk_library) {
	    NSFileManager *fm = [NSFileManager defaultManager];

	    path = [[NSString stringWithUTF8String:tk_library]
		    stringByAppendingFormat:@"/%@", image];
	    if (![fm isReadableFileAtPath:path]) {
		path = [[NSString stringWithUTF8String:tk_library]
			stringByAppendingFormat:@"/../macosx/%@", image];
		if (![fm isReadableFileAtPath:path]) {
		    path = nil;
252
253
254
255
256
257
258
































259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359




360
361
362
363
364
365
366
367
368
369
370
371
372
373

374









375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426


427

428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443


444



445
446

447
448

449
450





451
452
453

454
455
456
457
458
459

460


461
462
463
464
465
466
467


468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490




491
492
493
494
495
496
497
498
499
500
501
502
503
504

505
506
507
508



509



510
511
512
513
514
515


516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

531



532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
































 * TkpInit --
 *
 *	Performs Mac-specific interpreter initialization related to the
 *	tk_library variable.
 *
 * Results:
 *	Returns a standard Tcl result. Leaves an error message or result in
 *	the interp's result.
 *
 * Side effects:
 *	Sets "tk_library" Tcl variable, runs "tk.tcl" script.
 *
 *----------------------------------------------------------------------
 */

/*
 * Helper function which closes the shared NSFontPanel and NSColorPanel.
 */

static void closePanels(
    void)
{
    if ([NSFontPanel sharedFontPanelExists]) {
	[[NSFontPanel sharedFontPanel] orderOut:nil];
    }
    if ([NSColorPanel sharedColorPanelExists]) {
        [[NSColorPanel sharedColorPanel] orderOut:nil];
    }
}

/*
 * This custom exit procedure is called by Tcl_Exit in place of the exit
 * function from the C runtime.  It calls the terminate method of the
 * NSApplication class (superTerminate for a TKApplication).  The purpose of
 * doing this is to ensure that the NSFontPanel and the NSColorPanel are closed
 * before the process exits, and that the application state is recorded
 * correctly for all termination scenarios.
 *
 * TkpWantsExitProc tells Tcl_AppInit whether to install our custom exit proc,
 * which terminates the process by calling [NSApplication terminate].  This
 * does not work correctly if the process is part of an exec pipeline, so it is
 * only done if the process was launched by the launcher or if both stdin and
 * stdout are ttys.  To disable using the custom exit proc altogether, undefine
 * USE_CUSTOM_EXIT_PROC.
 */

#if defined(USE_CUSTOM_EXIT_PROC)
static Bool doCleanupFromExit = NO;

int TkpWantsExitProc(void) {
    return doCleanupFromExit == YES;
}

TCL_NORETURN void TkpExitProc(
    void *clientdata)
{
    Bool doCleanup = doCleanupFromExit;
    if (doCleanupFromExit) {
	doCleanupFromExit = NO; /* prevent possible recursive call. */
	closePanels();
    }

    /*
     * Tcl_Exit does not call Tcl_Finalize if there is an exit proc installed.
     */

    Tcl_Finalize();
    if (doCleanup == YES) {
	[(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */
    }
    exit((long)clientdata); /* Convince the compiler that we don't return. */
}
#endif

/*
 * This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals
 * so that normal finalization occurs when a Tk app is killed by one of these
 * signals (e.g when ^C is pressed while running Wish in the shell).  It calls
 * Tcl_Exit instead of the C runtime exit function called by the default handler.
 * This is consistent with the Tcl_Exit manual page, which says that Tcl_Exit
 * should always be called instead of exit.  When Tk is killed by a signal we
 * return exit status 1.
 */

static void TkMacOSXSignalHandler(TCL_UNUSED(int)) {

    Tcl_Exit(1);
}

int
TkpInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;

    /*
     * TkpInit can be called multiple times with different interpreters. But
     * The application initialization should only be done onece.

     */

    if (!initialized) {




	struct stat st;
	Bool shouldOpenConsole = NO;
        Bool stdinIsNullish = (!isatty(0) &&
	    (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif

	initialized = 1;











#ifdef TK_FRAMEWORK


	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */

	if (Tcl_MacOSXOpenVersionedBundleResources(interp,
		"com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
		tkLibPath) != TCL_OK) {
            # if 0 /* This is not really an error.  Wish still runs fine. */
	    TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed");
	    # endif
	}
#endif

	/*
	 * Instantiate our NSApplication object. This needs to be done before
	 * we check whether to open a console window.
	 */

	NSAutoreleasePool *pool = [NSAutoreleasePool new];
	[[NSUserDefaults standardUserDefaults] registerDefaults:
		[NSDictionary dictionaryWithObjectsAndKeys:
				  [NSNumber numberWithBool:YES],
			      @"_NSCanWrapButtonTitles",
				   [NSNumber numberWithInt:-1],
			      @"NSStringDrawingTypesetterBehavior",
			      nil]];
	[TKApplication sharedApplication];
	[pool drain];

        /*
         * WARNING: The finishLaunching method runs asynchronously. This
         * creates a race between the initialization of the NSApplication and
         * the initialization of Tk.  If Tk wins the race bad things happen
         * with the root window (see below).  If the NSApplication wins then an
         * AppleEvent created during launch, e.g. by dropping a file icon on
         * the application icon, will be delivered before the procedure meant
         * to to handle the AppleEvent has been defined.  This is handled in
         * tkMacOSXHLEvents.c by scheduling a timer event to handle the
         * ApplEvent later, after the required procedure has been defined.
         */

	[NSApp _setup:interp];
	[NSApp finishLaunching];

        /*
         * Create a Tk event source based on the Appkit event queue.
         */



	Tk_MacOSXSetupTkNotifier();



	/*
	 * If Tk initialization wins the race, the root window is mapped before
         * the NSApplication is initialized.  This can cause bad things to
         * happen.  The root window can open off screen with no way to make it
         * appear on screen until the app icon is clicked.  This will happen if
         * a Tk application opens a modal window in its startup script (see
         * ticket 56a1823c73).  In other cases, an empty root window can open
         * on screen and remain visible for a noticeable amount of time while
         * the Tk initialization finishes (see ticket d1989fb7cf).  The call
         * below forces Tk to block until the Appkit event queue has been
         * created.  This seems to be sufficient to ensure that the
         * NSApplication initialization wins the race, avoiding these bad
         * window behaviors.
	 */



	Tcl_DoOneEvent(TCL_WINDOW_EVENTS | TCL_DONT_WAIT);




	/*

	 * Decide whether to open a console window.  If the TK_CONSOLE
	 * environment variable is not defined we only show the console if

	 * stdin is not a tty and there is no startup script.
	 */






	if (getenv("TK_CONSOLE")) {
	    shouldOpenConsole = YES;

	} else if (stdinIsNullish && Tcl_GetStartupScript(NULL) == NULL) {
	    const char *intvar = Tcl_GetVar2(interp, "tcl_interactive",
					     NULL, TCL_GLOBAL_ONLY);
	    if (intvar == NULL) {
		Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
			    TCL_GLOBAL_ONLY);

	    }



#if defined(USE_CUSTOM_EXIT_PROC)
	    doCleanupFromExit = YES;
#endif

	    shouldOpenConsole = YES;
	}


	if (shouldOpenConsole) {
	    Tk_InitConsoleChannels(interp);
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));

	    if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
		return TCL_ERROR;
	    }
	} else if (stdinIsNullish) {

	    /*
	     * When launched as a macOS application with no console,
	     * redirect stderr and stdout to /dev/null. This avoids waiting
	     * forever for those files to become writable if the underlying
	     * Tcl program tries to write to them with a puts command.
	     */

	    FILE *null = fopen("/dev/null", "w");
	    dup2(fileno(null), STDOUT_FILENO);
	    dup2(fileno(null), STDERR_FILENO);
#if defined(USE_CUSTOM_EXIT_PROC)
	    doCleanupFromExit = YES;

#endif




	}

	/*
	 * FIXME: Close stdin & stdout for remote debugging if XCNOSTDIN is
	 * set.  Otherwise we will fight with gdb for stdin & stdout
	 */

	if (getenv("XCNOSTDIN") != NULL) {
	    close(0);
	    close(1);
	}

	/*
	 * Initialize the NSServices object here. Apple's docs say to do this

	 * in applicationDidFinishLaunching, but the Tcl interpreter is not
	 * initialized until this function call.
	 */




	TkMacOSXServices_Init(interp);




	/*
	 * The root window has been created and mapped, but XMapWindow deferred its
	 * call to makeKeyAndOrderFront because the first call to XMapWindow
	 * occurs too early in the initialization process for that.  Process idle
	 * tasks now, so the root window is configured, then order it front.


	 */

	while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
	for (NSWindow *window in [NSApp windows]) {
	    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
	    if (winPtr && Tk_IsMapped(winPtr)) {
		[window makeKeyAndOrderFront:NSApp];
		break;
	    }
	}

# if defined(USE_CUSTOM_EXIT_PROC)

	if ((isatty(0) && isatty(1))) {
	    doCleanupFromExit = YES;

	}




# endif

	/*
	 * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses
	 * Tcl_Exit instead of exit so that normal cleanup takes place if a TK
	 * application is killed with one of these signals.
	 */


	signal(SIGINT, TkMacOSXSignalHandler);
	signal(SIGHUP, TkMacOSXSignalHandler);
	signal(SIGTERM, TkMacOSXSignalHandler);
    }

    /*
     * Initialization steps that are needed for all interpreters.
     */


    if (tkLibPath[0] != '\0') {
	Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
    }

    if (scriptPath[0] != '\0') {
	Tcl_SetVar2(interp, "auto_path", NULL, scriptPath,
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
    }

    Tcl_CreateObjCommand(interp, "::tk::mac::standardAboutPanel",
	    TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
	    TkMacOSXIconBitmapObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",
	    TkMacOSXGetAppPathCmd, NULL, NULL);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|
>



>
>
>
>

|
|
<





|
|


|
>
|
>
>
>
>
>
>
>
>
>
|

>









<

<



<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<

>
>
|
>
|
>
|
|
|
|
|
|
|
<
<
<
<
<
|
|

>
>
|
>
>
>

<
>
|
<
>
|
<
>
>
>
>
>

|
<
>
|
|
|
|
<
<
>
|
>
>

<
|
<
|
<
|
>
>
|
<
<
<
<
>
|
|
|
<

<
<
<
<
<
<
|
<
<
<
<
<
>
|
>
>
>
>

|

|
|








|
>
|
<


>
>
>
|
>
>
>

|
<
<
<
<
>
>
|
<
<
<
<
<
<
<
<
<
<
<

|
|
>
|
>
>
>
|
<
|
<
<
<
|
<
>
|
<
<
<
|
|
|
<
<
>


|



|







<
<







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207










































































208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261

262
263
264




265
266
267
268
269
270
271
272
273
274
275













276

277



278
279
280
281
282
283
284
285
286
287
288
289
290
291





292
293
294
295
296
297
298
299
300
301

302
303

304
305

306
307
308
309
310
311
312

313
314
315
316
317


318
319
320
321
322

323

324

325
326
327
328




329
330
331
332

333






334





335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367




368
369
370











371
372
373
374
375
376
377
378
379

380



381

382
383



384
385
386


387
388
389
390
391
392
393
394
395
396
397
398
399
400
401


402
403
404
405
406
407
408
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * DoWindowActivate --
 *
 *	Idle handler that sets the application icon to the generic Tk icon.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SetApplicationIcon(
    ClientData clientData)
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
    if (path) {
	NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
	if (image) {
	    [NSApp setApplicationIconImage:image];
	    [image release];
	}
    }
    [pool drain];
}

/*
 *----------------------------------------------------------------------
 *
 * TkpInit --
 *
 *	Performs Mac-specific interpreter initialization related to the
 *	tk_library variable.
 *
 * Results:
 *	Returns a standard Tcl result. Leaves an error message or result in
 *	the interp's result.
 *
 * Side effects:
 *	Sets "tk_library" Tcl variable, runs "tk.tcl" script.
 *
 *----------------------------------------------------------------------
 */











































































int
TkpInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;

    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * against doing it more than once.
     */

    if (!initialized) {
	int bundledExecutable = 0;
	CFBundleRef bundleRef;
	CFURLRef bundleUrl = NULL;
	struct utsname name;
	struct stat st;

	initialized = 1;


	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
#   error Mac OS X 10.5 required
#endif

	if (!uname(&name)) {
	    tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10;
	}
        /*Check for new versioning scheme on Yosemite (10.10) and later.*/
	if (MAC_OS_X_VERSION_MIN_REQUIRED > 100000) {
		tkMacOSXMacOSXVersion = MAC_OS_X_VERSION_MIN_REQUIRED/100;
	    }
	if (tkMacOSXMacOSXVersion && MAC_OS_X_VERSION_MIN_REQUIRED < 100000 &&
		tkMacOSXMacOSXVersion/10 < MAC_OS_X_VERSION_MIN_REQUIRED/10) {
	    Tcl_Panic("Mac OS X 10.%d or later required !",
		    (MAC_OS_X_VERSION_MIN_REQUIRED/10)-100);
	}
		

#ifdef TK_FRAMEWORK
	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */

	if (Tcl_MacOSXOpenVersionedBundleResources(interp,
		"com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
		tkLibPath) != TCL_OK) {

	    TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed");

	}
#endif





	{
	    NSAutoreleasePool *pool = [NSAutoreleasePool new];
		[[NSUserDefaults standardUserDefaults] registerDefaults:
		     [NSDictionary dictionaryWithObjectsAndKeys:
		     [NSNumber numberWithBool:YES],
		     @"_NSCanWrapButtonTitles",
		     [NSNumber numberWithInt:-1],
		     @"NSStringDrawingTypesetterBehavior",
		     nil]];
	    [TKApplication sharedApplication];
	    [pool drain];













	    [NSApp _setup:interp];

	}




	/* Check whether we are a bundled executable: */
	bundleRef = CFBundleGetMainBundle();
	if (bundleRef) {
	    bundleUrl = CFBundleCopyBundleURL(bundleRef);
	}
	if (bundleUrl) {
	    /*
	     * A bundled executable is two levels down from its main bundle
	     * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas an
	     * unbundled executable's main bundle directory is just the
	     * directory containing the executable. So to check whether we are
	     * bundled, we delete the last three path components of the
	     * executable's url and compare the resulting url with the main





	     * bundle url.
	     */

	    int j = 3;
	    CFURLRef url = CFBundleCopyExecutableURL(bundleRef);

	    while (url && j--) {
		CFURLRef parent =
			CFURLCreateCopyDeletingLastPathComponent(NULL, url);


		CFRelease(url);
		url = parent;

	    }
	    if (url) {

		bundledExecutable = CFEqual(bundleUrl, url);
		CFRelease(url);
	    }
	    CFRelease(bundleUrl);
	}

	if (!bundledExecutable) {

	    /*
	     * If we are loaded into an executable that is not a bundled
	     * application, the window server does not let us come to the
	     * foreground. For such an executable, notify the window server
	     * that we are now a full GUI application.


	     */

	    OSStatus err = procNotFound;
	    ProcessSerialNumber psn = { 0, kCurrentProcess };


	    err = ChkErr(TransformProcessType, &psn,

		    kProcessTransformToForegroundApplication);


	    /*
	     * Set application icon to generic Tk icon, do it at idle time
	     * instead of now to ensure tk_library is setup.




	     */

	    Tcl_DoWhenIdle(SetApplicationIcon, NULL);
	}








	{





	    NSAutoreleasePool *pool = [NSAutoreleasePool new];
	    [NSApp _setupEventLoop];
	    TkMacOSXInitAppleEvents(interp);
	    TkMacOSXUseAntialiasedText(interp, -1);
	    TkMacOSXInitCGDrawing(interp, TRUE, 0);
	    [pool drain];
	}
	
	/*
	 * FIXME: Close stdin & stdout for remote debugging otherwise we will
	 * fight with gdb for stdin & stdout
	 */

	if (getenv("XCNOSTDIN") != NULL) {
	    close(0);
	    close(1);
	}

	/*
	 * If we don't have a TTY and stdin is a special character file of
	 * length 0, (e.g. /dev/null, which is what Finder sets when double
	 * clicking Wish) then use the Tk based console interpreter.

	 */

	if (getenv("TK_CONSOLE") ||
		(!isatty(0) && (fstat(0, &st) ||
		(S_ISCHR(st.st_mode) && st.st_blocks == 0)))) {
	    Tk_InitConsoleChannels(interp);
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));

	    /*




	     * Only show the console if we don't have a startup script
	     * and tcl_interactive hasn't been set already.
	     */












	    if (Tcl_GetStartupScript(NULL) == NULL) {
		const char *intvar = Tcl_GetVar(interp,
			"tcl_interactive", TCL_GLOBAL_ONLY);

		if (intvar == NULL) {
		    Tcl_SetVar(interp, "tcl_interactive", "1",
			    TCL_GLOBAL_ONLY);
		}

	    }



	    if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {

		return TCL_ERROR;
	    }



	}
    }



    Tk_MacOSXSetupTkNotifier();

    if (tkLibPath[0] != '\0') {
	Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
    }

    if (scriptPath[0] != '\0') {
	Tcl_SetVar(interp, "auto_path", scriptPath,
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
    }

    Tcl_CreateObjCommand(interp, "::tk::mac::standardAboutPanel",
	    TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
	    TkMacOSXIconBitmapObjCmd, NULL, NULL);



    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    const char *p, *name;

    name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetAppPathCmd --
 *
 *	Returns the path of the Wish application bundle.
 *
 * Results:
 *	Returns the application path.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXGetAppPathCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }

    /*
     * Get the application path URL and convert it to a string path reference.
     */

    CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef appPath =
	    CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);

    /*
     * Convert (and copy) the string reference into a Tcl result.
     */

    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    CFStringGetCStringPtr(appPath, CFStringGetSystemEncoding()), -1));

    CFRelease(mainBundleURL);
    CFRelease(appPath);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
 *
 *	This routines is called from Tk_Main to display warning messages that







|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
















































442
443
444
445
446
447
448
void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    const char *p, *name;

    name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, -1);
}

















































/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
 *
 *	This routines is called from Tk_Main to display warning messages that
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	CFURLRef appMainURL = CFBundleCopyResourceURL(bundleRef,
		CFSTR("AppMain"), CFSTR("tcl"), CFSTR("Scripts"));

	if (appMainURL != NULL) {
	    CFURLRef scriptFldrURL;
	    char startupScript[PATH_MAX + 1];

	    if (CFURLGetFileSystemRepresentation(appMainURL, true,
		    (unsigned char *) startupScript, PATH_MAX)) {
		Tcl_SetStartupScript(Tcl_NewStringObj(startupScript,-1), NULL);
		scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(NULL,
			appMainURL);
		if (scriptFldrURL != NULL) {
		    CFURLGetFileSystemRepresentation(scriptFldrURL, true,
			    (unsigned char *) scriptPath, PATH_MAX);







|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
	CFURLRef appMainURL = CFBundleCopyResourceURL(bundleRef,
		CFSTR("AppMain"), CFSTR("tcl"), CFSTR("Scripts"));

	if (appMainURL != NULL) {
	    CFURLRef scriptFldrURL;
	    char startupScript[PATH_MAX + 1];

	    if (CFURLGetFileSystemRepresentation (appMainURL, true,
		    (unsigned char *) startupScript, PATH_MAX)) {
		Tcl_SetStartupScript(Tcl_NewStringObj(startupScript,-1), NULL);
		scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(NULL,
			appMainURL);
		if (scriptFldrURL != NULL) {
		    CFURLGetFileSystemRepresentation(scriptFldrURL, true,
			    (unsigned char *) scriptPath, PATH_MAX);
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766








































767
768
769
770
771
772
773
774
775
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void*
TkMacOSXGetNamedSymbol(
    TCL_UNUSED(const char *),
    const char *symbol)
{
    void *addr = dlsym(RTLD_NEXT, symbol);

    if (!addr) {
	(void) dlerror(); /* Clear dlfcn error state */
    }
    return addr;
}









































/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|
|


<





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void*
TkMacOSXGetNamedSymbol(
    const char* module,
    const char* symbol)
{
    void *addr = dlsym(RTLD_NEXT, symbol);

    if (!addr) {
	(void) dlerror(); /* Clear dlfcn error state */
    }
    return addr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetStringObjFromCFString --
 *
 *	Get a string object from a CFString as efficiently as possible.
 *
 * Results:
 *	New string object or NULL if conversion failed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE Tcl_Obj*
TkMacOSXGetStringObjFromCFString(
    CFStringRef str)
{
    Tcl_Obj *obj = NULL;
    const char *c = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);

    if (c) {
	obj = Tcl_NewStringObj(c, -1);
    } else {
	CFRange all = CFRangeMake(0, CFStringGetLength(str));
	CFIndex len;

	if (CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false, NULL,
		0, &len) > 0 && len < INT_MAX) {
	    obj = Tcl_NewObj();
	    Tcl_SetObjLength(obj, len);
	    CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false,
		    (UInt8*) obj->bytes, len, NULL);
	}
    }
    return obj;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXInt.h.

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100


















101
102
103
104
105
106
107
    HIShapeRef visRgn;		/* Visible region of window */
    HIShapeRef aboveVisRgn;	/* Visible region of window & its children */
    HIShapeRef drawRgn;		/* Clipped drawing region */
    int referenceCount;		/* Don't delete toplevel until children are
				 * gone. */
    struct TkWindowPrivate *toplevel;
				/* Pointer to the toplevel datastruct. */
    CGFloat fillRGBA[4];        /* Background used by the ttk FillElement */
    int flags;			/* Various state see defines below. */
};
typedef struct TkWindowPrivate MacDrawable;

/*
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08

#define TK_IS_PIXMAP		0x10
#define TK_IS_BW_PIXMAP		0x20
#define TK_DO_NOT_DRAW          0x40
#define TTK_HAS_CONTRASTING_BG  0x80

/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
 */



















/*
 * GC CGColorRef cache for tkMacOSXColor.c
 */

typedef struct {
    unsigned long cachedForeground;
    CGColorRef cachedForegroundColor;







<












>
|
|
|
<
<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    HIShapeRef visRgn;		/* Visible region of window */
    HIShapeRef aboveVisRgn;	/* Visible region of window & its children */
    HIShapeRef drawRgn;		/* Clipped drawing region */
    int referenceCount;		/* Don't delete toplevel until children are
				 * gone. */
    struct TkWindowPrivate *toplevel;
				/* Pointer to the toplevel datastruct. */

    int flags;			/* Various state see defines below. */
};
typedef struct TkWindowPrivate MacDrawable;

/*
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08
#define TK_FOCUSED_VIEW		0x10
#define TK_IS_PIXMAP		0x20
#define TK_IS_BW_PIXMAP		0x40
#define TK_DO_NOT_DRAW          0x80


/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
 */

/*
 * This structure is for handling Netscape-type in process
 * embedding where Tk does not control the top-level. It contains
 * various functions that are needed by Mac specific routines, like
 * TkMacOSXGetDrawablePort. The definitions of the function types
 * are in tkMacOSX.h.
 */

typedef struct {
    Tk_MacOSXEmbedRegisterWinProc *registerWinProc;
    Tk_MacOSXEmbedGetGrafPortProc *getPortProc;
    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc;
    Tk_MacOSXEmbedGetClipProc *getClipProc;
    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc;
} TkMacOSXEmbedHandler;

MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler;

/*
 * GC CGColorRef cache for tkMacOSXColor.c
 */

typedef struct {
    unsigned long cachedForeground;
    CGColorRef cachedForegroundColor;
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175




176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

#define TK_LOCATION_CHANGED	1
#define TK_SIZE_CHANGED		2
#define TK_BOTH_CHANGED		3
#define TK_MACOSX_HANDLE_EVENT_IMMEDIATELY 1024

/*
 * Defines for tkTextDisp.c and tkFont.c
 */

#define TK_LAYOUT_WITH_BASE_CHUNKS	1
#define TK_DRAW_IN_CONTEXT		1

/*
 * Prototypes of internal procs not in the stubs table.
 */

MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);




MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(Region r);
MODULE_SCOPE void TkpReleaseRegion(Region r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
MODULE_SCOPE Bool TkTestLogDisplay(Drawable drawable);

/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|










>
>
>
>


|
|

<
<







<
<
<
<
<
<
<
<
<
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200


201
202
203
204
205
206
207










#define TK_LOCATION_CHANGED	1
#define TK_SIZE_CHANGED		2
#define TK_BOTH_CHANGED		3
#define TK_MACOSX_HANDLE_EVENT_IMMEDIATELY 1024

/*
 * Defines for tkTextDisp.c
 */

#define TK_LAYOUT_WITH_BASE_CHUNKS	1
#define TK_DRAW_IN_CONTEXT		1

/*
 * Prototypes of internal procs not in the stubs table.
 */

MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);
#if 0
MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin,
	int clip_y_origin, XRectangle* rectangles, int n, int ordering);
#endif
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);


/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */









Changes to macosx/tkMacOSXKeyEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32



33

34

35

36

37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249


250


251



















252



253


254













255




















256

257



258



259


























260
261

262

263


















264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297


298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

441

442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498

499
500
501
502
503
504
505
506




507
508
509





510
511

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
/*
 * tkMacOSXKeyEvent.c --
 *
 *	This file implements functions that decode & handle keyboard events on
 *	MacOS X.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2012 Adrian Robert.
 * Copyright 2015-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXWm.h"

/*
 * See tkMacOSXPrivate.h for macros related to key event processing.
 */

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_KEYBOARD
#endif
*/

#define NS_KEYLOG 0
#define XEVENT_MOD_MASK (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask)



static Tk_Window keyboardGrabWinPtr = NULL; /* Current keyboard grab window. */

static NSWindow *keyboardGrabNSWindow = nil; /* Its underlying NSWindow.*/

static NSModalSession modalSession = nil;

static BOOL processingCompose = NO;

static Tk_Window composeWin = NULL;
static int caret_x = 0, caret_y = 0, caret_height = 0;

static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers);
static void setXEventPoint(XEvent *xEvent, Tk_Window tkwin, NSWindow *w);
static NSUInteger textInputModifiers;

#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow *w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    NSEventType type = [theEvent type];
    NSUInteger virtual = [theEvent keyCode];
    NSUInteger modifiers = ([theEvent modifierFlags] &
			    NSDeviceIndependentModifierFlagsMask);
    XEvent xEvent;
    MacKeycode macKC;
    UniChar keychar = 0;
    Bool can_input_text, has_modifiers = NO, use_text_input = NO;
    static NSUInteger savedModifiers = 0;
    static NSMutableArray *nsEvArray = nil;

    if (nsEvArray == nil) {

        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
    }
    if (!winPtr) {
	return theEvent;
    }

    /*
     * If a local grab is in effect, key events for windows in the
     * grabber's application are redirected to the grabber.  Key events
     * for other applications are delivered normally.  If a global
     * grab is in effect all key events are redirected to the grabber.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr) {
	if (winPtr->dispPtr->grabFlags ||  /* global grab */
	    grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */
	    winPtr =winPtr->dispPtr->focusPtr;
	    tkwin = (Tk_Window)winPtr;
	}
    }

    /*
     * Extract the unicode character from KeyUp and KeyDown events.
     */

    if (type == NSKeyUp || type == NSKeyDown) {
	if ([[theEvent characters] length] > 0) {
	    keychar = [[theEvent characters] characterAtIndex:0];

	    /*
	     * Currently, real keys always send BMP characters, but who knows?
	     */

	    if (CFStringIsSurrogateHighCharacter(keychar)) {
		UniChar lowChar = [[theEvent characters] characterAtIndex:1];
		keychar = CFStringGetLongCharacterForSurrogatePair(
		    keychar, lowChar);
	    }
	} else {

	    /*
	     * This is a dead key, such as Option-e, so it should go to the
	     * TextInputClient.
	     */

	    use_text_input = YES;
	}

	/*
	 * Apple uses 0x10 for unrecognized keys.
	 */

	if (keychar == 0x10) {
	    keychar = UNKNOWN_KEYCHAR;
	}

#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d",
	      [self class], self, _cmd,
	      (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar,
	      virtual, w, type);
#endif

    }

    /*
     * Build a skeleton XEvent.  We need to build it here, even if we will not
     * send it, so we can pass it to TkFocusKeyEvent to determine whether the
     * target widget can input text.
     */

    setupXEvent(&xEvent, tkwin, modifiers);
    has_modifiers = xEvent.xkey.state & XEVENT_MOD_MASK;
    focusWinPtr = TkFocusKeyEvent(winPtr, &xEvent);
    if (focusWinPtr == NULL) {
	TKContentView *contentView = [w contentView];

	/*
	 * This NSEvent is being sent to a window which does not have focus.
	 * This could mean, for example, that the user deactivated the Tk app
	 * while the NSTextInputClient's popup character selection window was
	 * still open.  We attempt to abandon any ongoing composition operation
	 * and discard the event.
	 */

	[contentView cancelComposingText];
	return theEvent;
    }
    can_input_text = ((focusWinPtr->flags & TK_CAN_INPUT_TEXT) != 0);

#if (NS_KEYLOG)
    TKLog(@"keyDown: %s compose sequence.\n",
	  processingCompose == YES ? "Continue" : "Begin");
#endif

    /*
     * Decide whether this event should be processed with the NSTextInputClient
     * protocol.
     */

    if (processingCompose ||
	(type == NSKeyDown && can_input_text && !has_modifiers &&
	 IS_PRINTABLE(keychar))
	) {
	use_text_input = YES;
    }

    /*
     * If we are processing this KeyDown event as an NSTextInputClient we do
     * not queue an XEvent.  We pass the NSEvent to our interpretKeyEvents
     * method.  When the composition sequence is complete, the callback method
     * insertText: replacementRange will be called.  That method generates a
     * keyPress XEvent with the selected character.
     */

    if (use_text_input) {
	textInputModifiers = modifiers;

	/*
	 * In IME the Enter key is used to terminate a composition sequence.
	 * When there are multiple choices of input text available, and the
	 * user's selected choice is not the default, it may be necessary to
	 * hit the Enter key multiple times before the text is accepted and
	 * rendered (See ticket 39de9677aa]). So when sending an Enter key
	 * during composition, we continue sending Enter keys until the
	 * inputText method has cleared the processingCompose flag.
	 */

	if (processingCompose && [theEvent keyCode] == 36) {
	    [nsEvArray addObject: theEvent];
	    while(processingCompose) {
		[[w contentView] interpretKeyEvents: nsEvArray];
	    }
	    [nsEvArray removeObject: theEvent];
	} else {
	    [nsEvArray addObject: theEvent];
	    [[w contentView] interpretKeyEvents: nsEvArray];
	    [nsEvArray removeObject: theEvent];
	}
	return theEvent;
    }

    /*
     * We are not handling this event as an NSTextInputClient, so we need to
     * finish constructing the XEvent and queue it.
     */

    macKC.v.o_s =  ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) |
		    (modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0));
    macKC.v.virtual = virtual;
    switch (type) {
    case NSFlagsChanged:

	/*
	 * This XEvent is a simulated KeyPress or KeyRelease event for a
	 * modifier key.  To determine the type, note that the highest bit
	 * where the flags differ is 1 if and only if it is a KeyPress. The
	 * modifiers are saved so we can detect the next flag change.
	 */

	xEvent.xany.type = modifiers > savedModifiers ? KeyPress : KeyRelease;
	savedModifiers = modifiers;

	/*
	 * Set the keychar to MOD_KEYCHAR as a signal to TkpGetKeySym (see
	 * tkMacOSXKeyboard.c) that this is a modifier key event.
	 */

	keychar = MOD_KEYCHAR;
	break;
    case NSKeyUp:
	xEvent.xany.type = KeyRelease;
	break;
    case NSKeyDown:
	xEvent.xany.type = KeyPress;
	break;
    default:
	return theEvent; /* Unrecognized key event. */
    }
    macKC.v.keychar = keychar;
    xEvent.xkey.keycode = macKC.uint;


    setXEventPoint(&xEvent, tkwin, w);






















    /*



     * Finally we can queue the XEvent, inserting a KeyRelease before a


     * repeated KeyPress.













     */






















    if (type == NSKeyDown && [theEvent isARepeat]) {







	xEvent.xany.type = KeyRelease;


























	Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	xEvent.xany.type = KeyPress;

    }

    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);


















    return theEvent;
}
@end



@implementation TKContentView
@synthesize tkDirtyRect = _tkDirtyRect;
@synthesize tkNeedsDisplay = _tkNeedsDisplay;;

/*
 * Implementation of the NSTextInputClient protocol.
 */

/* [NSTextInputClient inputText: replacementRange:] is called by
 * interpretKeyEvents when a composition sequence is complete.  It is also
 * called when we delete working text.  In that case the call is followed
 * immediately by doCommandBySelector: deleteBackward:
 */
- (void)insertText: (id)aString
  replacementRange: (NSRange)repRange
{
    int i, len, state;
    XEvent xEvent;
    NSString *str, *keystr, *lower;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window)winPtr;
    Bool sendingIMEText = NO;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
    len = [str length];

    if (NS_KEYLOG) {
	TKLog(@"insertText '%@'\tlen = %d", aString, len);


    }

    /*
     * Clear any working text.
     */

    if (privateWorkingText != nil) {
	sendingIMEText = YES;
    	[self deleteWorkingText];
    }

    /*
     * Insert the string as a sequence of keystrokes.
     */

    setupXEvent(&xEvent, tkwin, textInputModifiers);
    setXEventPoint(&xEvent, tkwin, [self window]);
    xEvent.xany.type = KeyPress;

    /*
     * Apple evidently sets location to 0 to signal that an accented letter has
     * been selected from the accent menu.  An unaccented letter has already
     * been displayed and we need to erase it before displaying the accented
     * letter.
     */

    if (repRange.location == 0) {
	Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
	Tk_SendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
    }

    /*
     * Next we generate an XEvent for each unicode character in our string.
     * This string could contain non-BMP characters, for example if the
     * emoji palette was used.
     *
     * NSString uses UTF-16 internally, which means that a non-BMP character is
     * represented by a sequence of two 16-bit "surrogates".  We record this in
     * the XEvent by setting the low order 21-bits of the keycode to the UCS-32
     * value value of the character and the virtual keycode in the high order
     * byte to the special value NON_BMP.
     */

    state = xEvent.xkey.state;
    for (i = 0; i < len; i++) {
	UniChar keychar;
	MacKeycode macKC = {0};

	keychar = [str characterAtIndex:i];
	macKC.v.keychar = keychar;
	if (CFStringIsSurrogateHighCharacter(keychar)) {
	    UniChar lowChar = [str characterAtIndex:++i];
	    macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair(
				  (UniChar)keychar, lowChar);
	    macKC.v.virtual = NON_BMP_VIRTUAL;
	} else if (repRange.location == 0 || sendingIMEText) {
	    macKC.v.virtual = REPLACEMENT_VIRTUAL;
	} else {
	    macKC.uint = TkMacOSXAddVirtual(macKC.uint);
	    xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual);
	}
	keystr = [[NSString alloc] initWithCharacters:&keychar length:1];
	lower = [keystr lowercaseString];
	if (![keystr isEqual: lower]) {

	    macKC.v.o_s |= INDEX_SHIFT;
	    xEvent.xkey.state |= ShiftMask;
	}
	if (xEvent.xkey.state & Mod2Mask) {
	    macKC.v.o_s |= INDEX_OPTION;
	}
	xEvent.xkey.keycode = macKC.uint;
    	xEvent.xany.type = KeyPress;

    	Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	xEvent.xkey.state = state;
    }
}

/*
 * This required method is allowed to return nil.
 */

- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)theRange
      actualRange:(NSRangePointer)thePointer
{
    (void)theRange;
    (void)thePointer;

    return nil;
}

/*
 * This method is supposed to insert (or replace selected text with) the string
 * argument. If the argument is an NSString, it should be displayed with a
 * distinguishing appearance, e.g underlined.
 */

- (void)setMarkedText: (id)aString
	selectedRange: (NSRange)selRange
     replacementRange: (NSRange)repRange
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
    NSString *temp;
    NSString *str;



    (void)selRange;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
    if (focusWin) {

	/*
	 * Remember the widget where the composition is happening, in case it
	 * gets defocussed during the composition.
	 */

	composeWin = focusWin;
    } else {
	return;
    }
    if (NS_KEYLOG) {
	TKLog(@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	      (unsigned long) [str length], (unsigned long) selRange.length,
	      (unsigned long) selRange.location);
    }

    if (privateWorkingText != nil) {
	[self deleteWorkingText];
    }

    if ([str length] == 0) {
	return;
    }

    /*
     * Use our insertText method to display the marked text.
     */

    Tk_SendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
    processingCompose = YES;
    temp = [str copy];
    [self insertText: temp replacementRange:repRange];
    privateWorkingText = temp;
    Tk_SendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);

}


- (BOOL)hasMarkedText
{
    return privateWorkingText != nil;
}


- (NSRange)markedRange
{
    NSRange rng = privateWorkingText != nil
	? NSMakeRange(0, [privateWorkingText length])
	: NSMakeRange(NSNotFound, 0);

    if (NS_KEYLOG) {
	TKLog(@"markedRange request");
    }
    return rng;
}


- (void)unmarkText
{
    if (NS_KEYLOG) {
	TKLog(@"unmarkText");
    }
    [self deleteWorkingText];
    processingCompose = NO;
}

/*
 * Called by the system to get a position for popup character selection windows
 * such as a Character Palette, or a selection menu for IME.
 */


- (NSRect)firstRectForCharacterRange: (NSRange)theRange
			 actualRange: (NSRangePointer)thePointer
{
    NSRect rect;
    NSPoint pt;
    (void)theRange;
    (void)thePointer;

    pt.x = caret_x;
    pt.y = caret_y;

    pt = [self convertPoint: pt toView: nil];
    pt = [[self window] tkConvertPointToScreen: pt];
    pt.y -= caret_height;

    rect.origin = pt;
    rect.size.width = 0;
    rect.size.height = caret_height;
    return rect;
}


- (NSInteger)conversationIdentifier
{
    return (NSInteger) self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
    if (NS_KEYLOG) {
	TKLog(@"doCommandBySelector: %@", NSStringFromSelector(aSelector));
    }
    processingCompose = NO;
    if (aSelector == @selector (deleteBackward:)) {




	TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
	Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
	Tk_SendVirtualEvent(focusWin, "TkAccentBackspace", NULL);





    }
}


- (NSArray *)validAttributesForMarkedText
{
    static NSArray *arr = nil;
    if (arr == nil) {
	arr = [[NSArray alloc] initWithObjects:
	    NSUnderlineStyleAttributeName,
	    NSUnderlineColorAttributeName,
	    nil];
	[arr retain];
    }
    return arr;
}

- (NSRange)selectedRange
{
    if (NS_KEYLOG) {
	TKLog(@"selectedRange request");

    }
    return NSMakeRange(0, 0);
}

- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
    (void)thePoint;
    if (NS_KEYLOG) {
	TKLog(@"characterIndexForPoint request");

    }
    return NSNotFound;
}

- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
    static NSAttributedString *str = nil;
    (void)theRange;

    if (str == nil) {
	str = [NSAttributedString new];
    }
    if (NS_KEYLOG) {
	TKLog(@"attributedSubstringFromRange request");
    }
    return str;
}
/* End of NSTextInputClient implementation. */

@end


@implementation TKContentView(TKKeyEvent)

/*
 * Tell the widget to erase the displayed composing characters.  This
 * is not part of the NSTextInputClient protocol.
 */

- (void)deleteWorkingText
{
    if (privateWorkingText == nil) {
	return;
    } else {

	if (NS_KEYLOG) {
	    TKLog(@"deleteWorkingText len = %lu\n",
		  (unsigned long)[privateWorkingText length]);
	}

	[privateWorkingText release];
	privateWorkingText = nil;
	processingCompose = NO;
	if (composeWin) {
	    Tk_SendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL);
	}

    }
}

- (void)cancelComposingText
{
    if (NS_KEYLOG) {
	TKLog(@"cancelComposingText");
    }
    [self deleteWorkingText];
    processingCompose = NO;
}

@end

/*
 * Set up basic fields in xevent for keyboard input.
 */

static void
setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers)
{
    unsigned int state = 0;
    Display *display = Tk_Display(tkwin);

    if (tkwin == NULL) {
	return;
    }
    if (modifiers) {
	state = (modifiers & NSAlphaShiftKeyMask ? LockMask    : 0) |
	        (modifiers & NSShiftKeyMask      ? ShiftMask   : 0) |
	        (modifiers & NSControlKeyMask    ? ControlMask : 0) |
	        (modifiers & NSCommandKeyMask    ? Mod1Mask    : 0) |
	        (modifiers & NSAlternateKeyMask  ? Mod2Mask    : 0) |
	        (modifiers & NSNumericPadKeyMask ? Mod3Mask    : 0) |
	        (modifiers & NSFunctionKeyMask   ? Mod4Mask    : 0) ;
    }
    memset(xEvent, 0, sizeof(XEvent));
    xEvent->xany.serial = LastKnownRequestProcessed(display);

    xEvent->xany.display = Tk_Display(tkwin);
    xEvent->xany.window = Tk_WindowId(tkwin);

    xEvent->xkey.root = XRootWindow(display, 0);

    xEvent->xkey.time = TkpGetMS();
    xEvent->xkey.state = state;
    xEvent->xkey.same_screen = true;
    /* No need to initialize other fields implicitly here,
     * because of the memset() above. */
}

static void
setXEventPoint(
    XEvent *xEvent,
    Tk_Window tkwin,
    NSWindow *w)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    NSPoint local = [w  mouseLocationOutsideOfEventStream];
    NSPoint global = [w tkConvertPointToScreen: local];
    int win_x, win_y;

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	}
    } else if (winPtr->wmInfoPtr != NULL) {
	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;
    }
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    local.x = win_x;
    local.y = win_y;
    global.y = TkMacOSXZeroScreenHeight() - global.y;
    xEvent->xbutton.x = local.x;
    xEvent->xbutton.y = local.y;
    xEvent->xbutton.x_root = global.x;
    xEvent->xbutton.y_root = global.y;
}

#pragma mark -

/*
 *----------------------------------------------------------------------
 *









|






<
|
<
<
<
<
<






<

|
>
>
>
|
>
|
>

>

>
|

>
|
|
|










|
<
<
|
|
<
<
|
<
|
|

|

|
>


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
<
|
|
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<

|
<
|
<
<
<
<
|
<
|
|
<
<
<
<
|
<
|
<
<

|
<
<



|
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
|
>
>
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>



<
<
|
<
<
<

|
<
|
|
<

<

|
|
<
|
|
<

<
<
<
<
|
|
>
>
|
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<

<
|
<
<
|
|
<
|
<
|
|
<
<
<
<
<
|
<
<
|
<
>
<
<
|
<
<
<
<
|
>
|
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
|

<
<
<
<
<
|
|
<
<

<
<
|
|
>
>
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
|
|
|
<
<
<
<
<
<
|
<
<
|
|
>

>



|

>



|
|
<
<
|
|
<
|


>


|
|
<
|
|


<
<
<
<

>

<

|
|
<
<

|
|

|
|
|

|
|
|
|


>


|

>



|
|
<
|
|
>
>
>
>
|
<
|
>
>
>
>
>


>



|
|
<
|
<
<
|
|
<
|



|
|
>
|
<
|



<
|
|
>
|
<
|



|
<
<
<
|
<
|
|
<
|

<
|




|
<
<
<
<
<


|
|
<
<
|
|
|
<
<
|
|
|
<
<
|
>
|
<
|
<
|
<
<
|
<
<
|
<
<
<

|

<

|

<
<
|
|
<
|
<
<
<
<
<
<
<
<
<

|
>



|
>



<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17





18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


54
55


56

57
58
59
60
61
62
63
64
65
66
























































































67




68




69






70







71


72









73

74


75

76
77



78

79




80




81
82

83




84

85
86




87

88


89
90


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230


231



232
233

234
235

236

237
238
239

240
241

242




243
244
245
246
247


248


249

250
















251




252

253





254



255

256


257
258

259

260
261





262


263

264


265




266
267
268



269



270





271

272
273





274
275


276


277
278
279
280
281


















282
283

284
285


286
287
288






289


290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305


306
307

308
309
310
311
312
313
314
315

316
317
318
319




320
321
322

323
324
325


326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371

372


373
374

375
376
377
378
379
380
381
382

383
384
385
386

387
388
389
390

391
392
393
394
395



396

397
398

399
400

401
402
403
404
405
406





407
408
409
410


411
412
413


414
415
416


417
418
419

420

421


422


423



424
425
426

427
428
429


430
431

432









433
434
435
436
437
438
439
440
441
442
443



444





























445



446
447
448
449
450
451
452
/*
 * tkMacOSXKeyEvent.c --
 *
 *	This file implements functions that decode & handle keyboard events on
 *	MacOS X.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2012 Adrian Robert.
 * Copyright 2015 Marc Culler. 
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include "tkMacOSXEvent.h"






/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_KEYBOARD
#endif
*/

#define NS_KEYLOG 0


static Tk_Window grabWinPtr = NULL;
				/* Current grab window, NULL if no grab. */
static Tk_Window keyboardGrabWinPtr = NULL;
				/* Current keyboard grab window. */
static NSWindow *keyboardGrabNSWindow = nil;
                               /* NSWindow for the current keyboard grab window. */
static NSModalSession modalSession = nil;

static BOOL processingCompose = NO;
static BOOL finishedCompose = NO;

static int caret_x = 0, caret_y = 0, caret_height = 0;

static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state);
static unsigned isFunctionKey(unsigned int code);


#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow*	    w;


    NSEventType	    type = [theEvent type];
    NSUInteger	    modifiers, len = 0;


    BOOL	    repeat = NO;

    unsigned short  keyCode;
    NSString	    *characters = nil, *charactersIgnoringModifiers = nil;
    static NSUInteger savedModifiers = 0;
    static NSMutableArray *nsEvArray;

    if (nsEvArray == nil)
      {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
      }





























































































    switch (type) {




    case NSKeyUp:






      if (finishedCompose)







        {


          // if we were composing, swallow the last release since we already sent









          finishedCompose = NO;

          return theEvent;


        }

    case NSKeyDown:
	repeat = [theEvent isARepeat];



	characters = [theEvent characters];

	charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];




        len = [charactersIgnoringModifiers length];




    case NSFlagsChanged:
	modifiers = [theEvent modifierFlags];

	keyCode = [theEvent keyCode];




	//	w = [self windowWithWindowNumber:[theEvent windowNumber]];

	w = [theEvent window];
#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1




	NSLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);

#endif


	break;



    default:
	return theEvent; /* Unrecognized key event. */
    }

    /* Create an Xevent to add to the Tk queue. */
    if (!processingCompose) {
        unsigned int state = 0;

        if (modifiers & NSAlphaShiftKeyMask) {
          state |= LockMask;
        }
        if (modifiers & NSShiftKeyMask) {
          state |= ShiftMask;
        }
        if (modifiers & NSControlKeyMask) {
          state |= ControlMask;
        }
        if (modifiers & NSCommandKeyMask) {
          state |= Mod1Mask;		/* command key */
        }
        if (modifiers & NSAlternateKeyMask) {
          state |= Mod2Mask;		/* option key */
        }
        if (modifiers & NSNumericPadKeyMask) {
          state |= Mod3Mask;
        }
        if (modifiers & NSFunctionKeyMask) {
          state |= Mod4Mask;
        }

        /*
         * The focus must be in the FrontWindow on the Macintosh. We then query Tk
         * to determine the exact Tk window that owns the focus.
         */

        TkWindow *winPtr = TkMacOSXGetTkWindow(w);
        Tk_Window tkwin = (Tk_Window) winPtr;

        if (!tkwin) {
          TkMacOSXDbgMsg("tkwin == NULL");
          return theEvent;
        }
        tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
        if (!tkwin) {
          TkMacOSXDbgMsg("tkwin == NULL");
          return theEvent;  /* Give up. No window for this event. */
        }

        /*
         * If it's a function key, or we have modifiers other than Shift or Alt,
         * pass it straight to Tk.  Otherwise we'll send for input processing.
         */
        int code = (len == 0) ?
          0 : [charactersIgnoringModifiers characterAtIndex: 0];
        if (type != NSKeyDown || isFunctionKey(code)
            || (len > 0 && state & (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask))) {

            XEvent xEvent;
            setupXEvent(&xEvent, w, state);

            if (type == NSFlagsChanged) {
              if (savedModifiers > modifiers) {
                xEvent.xany.type = KeyRelease;
              } else {
                xEvent.xany.type = KeyPress;
              }

              /*
               * Use special '-1' to signify a special keycode to our platform
               * specific code in tkMacOSXKeyboard.c. This is rather like what
               * happens on Windows.
               */

              xEvent.xany.send_event = -1;

              /*
               * Set keycode (which was zero) to the changed modifier
               */

              xEvent.xkey.keycode = (modifiers ^ savedModifiers);
            } else {
              if (type == NSKeyUp || repeat) {
                xEvent.xany.type = KeyRelease;
              } else {
                xEvent.xany.type = KeyPress;
              }

              /* For command key, take input manager's word so things
                 like dvorak / qwerty layout work. */
              if ((modifiers & NSCommandKeyMask) == NSCommandKeyMask
                  && (modifiers & NSAlternateKeyMask) != NSAlternateKeyMask
                  && len > 0 && !isFunctionKey(code)) {
                // head off keycode-based translation in tkMacOSXKeyboard.c
                xEvent.xkey.nbytes = [characters length]; //len
              }

              if ([characters length] > 0) {
                xEvent.xkey.keycode =
                  (keyCode << 16) | (UInt16) [characters characterAtIndex:0];
                if (![characters getCString:xEvent.xkey.trans_chars
                                  maxLength:XMaxTransChars encoding:NSUTF8StringEncoding]) {
                  /* prevent SF bug 2907388 (crash on some composite chars) */
                  //PENDING: we might not need this anymore
                  TkMacOSXDbgMsg("characters too long");
                  return theEvent;
                }
              }

              if (repeat) {
                Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
                xEvent.xany.type = KeyPress;
                xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
              }
            }
            Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
            savedModifiers = modifiers;
            return theEvent;
          }  /* if send straight to TK */

      }  /* if not processing compose */

    if (type == NSKeyDown) {
        if (NS_KEYLOG)
          fprintf (stderr, "keyDown: %s compose sequence.\n",
                   processingCompose == YES ? "Continue" : "Begin");
        processingCompose = YES;
        [nsEvArray addObject: theEvent];
        [[w contentView] interpretKeyEvents: nsEvArray];
        [nsEvArray removeObject: theEvent];
      }

    savedModifiers = modifiers;

    return theEvent;
}
@end



@implementation TKContentView


/* <NSTextInput> implementation (called through interpretKeyEvents:]). */




/* <NSTextInput>: called when done composing;

   NOTE: also called when we delete over working text, followed immed.
         by doCommandBySelector: deleteBackward: */

- (void)insertText: (id)aString

{
  int i, len = [(NSString *)aString length];
  XEvent xEvent;

  TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
  Tk_Window tkwin = (Tk_Window) winPtr;






  if (NS_KEYLOG)
    NSLog (@"insertText '%@'\tlen = %d", aString, len);
  processingCompose = NO;
  finishedCompose = YES;



  /* first, clear any working text */


  if (privateWorkingText != nil)

    [self deleteWorkingText];





















  /* now insert the string as keystrokes */

  setupXEvent(&xEvent, [self window], 0);





  xEvent.xany.type = KeyPress;





  for (i =0; i<len; i++)


    {
      xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i];

      [[aString substringWithRange: NSMakeRange(i,1)]

        getCString: xEvent.xkey.trans_chars
         maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];





      xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);


      xEvent.xany.type = KeyPress;

      Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);







      xEvent.xany.type = KeyRelease;
      xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
      Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);



      xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));



    }





}








/* <NSTextInput>: inserts display of composing characters */
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange


{


  NSString *str = [aString respondsToSelector: @selector (string)] ?
    [aString string] : aString;
  if (NS_KEYLOG)
    NSLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	   (unsigned long) [str length], (unsigned long) selRange.length,


















	   (unsigned long) selRange.location);


  if (privateWorkingText != nil)
    [self deleteWorkingText];


  if ([str length] == 0)
    return;







  processingCompose = YES;


  privateWorkingText = [str copy];

  //PENDING: insert workingText underlined
}


- (BOOL)hasMarkedText
{
  return privateWorkingText != nil;
}


- (NSRange)markedRange
{
  NSRange rng = privateWorkingText != nil
    ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0);


  if (NS_KEYLOG)
    NSLog (@"markedRange request");

  return rng;
}


- (void)unmarkText
{
  if (NS_KEYLOG)
    NSLog (@"unmark (accept) text");

  [self deleteWorkingText];
  processingCompose = NO;
}






/* used to position char selection windows, etc. */
- (NSRect)firstRectForCharacterRange: (NSRange)theRange

{
  NSRect rect;
  NSPoint pt;



  pt.x = caret_x;
  pt.y = caret_y;

  pt = [self convertPoint: pt toView: nil];
  pt = [[self window] convertPointToScreen: pt];
  pt.y -= caret_height;

  rect.origin = pt;
  rect.size.width = caret_height;
  rect.size.height = caret_height;
  return rect;
}


- (NSInteger)conversationIdentifier
{
  return (NSInteger)self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
  if (NS_KEYLOG)
    NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));

  processingCompose = NO;
  if (aSelector == @selector (deleteBackward:))
    {
      /* happens when user backspaces over an ongoing composition:
         throw a 'delete' into the event queue */
      XEvent xEvent;
      setupXEvent(&xEvent, [self window], 0);

      xEvent.xany.type = KeyPress;
      xEvent.xkey.nbytes = 1;
      xEvent.xkey.keycode = (0x33 << 16) | 0x7F;
      xEvent.xkey.trans_chars[0] = 0x7F;
      xEvent.xkey.trans_chars[1] = 0x0;
      Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
    }
}


- (NSArray *)validAttributesForMarkedText
{
  static NSArray *arr = nil;
  if (arr == nil) arr = [NSArray new];

 /* [[NSArray arrayWithObject: NSUnderlineStyleAttributeName] retain]; */


  return arr;
}



- (NSRange)selectedRange
{
  if (NS_KEYLOG)
    NSLog (@"selectedRange request");
  return NSMakeRange (NSNotFound, 0);
}



- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{

  if (NS_KEYLOG)
    NSLog (@"characterIndexForPoint request");
  return 0;
}



- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
  static NSAttributedString *str = nil;



  if (str == nil) str = [NSAttributedString new];

  if (NS_KEYLOG)
    NSLog (@"attributedSubstringFromRange request");

  return str;
}

/* End <NSTextInput> impl. */
@end


@implementation TKContentView(TKKeyEvent)
/* delete display of composing characters [not in <NSTextInput>] */





- (void)deleteWorkingText
{
  if (privateWorkingText == nil)
    return;


  if (NS_KEYLOG)
    NSLog(@"deleteWorkingText len = %lu\n",
	    (unsigned long)[privateWorkingText length]);


  [privateWorkingText release];
  privateWorkingText = nil;
  processingCompose = NO;



  //PENDING: delete working text
}

@end











/*
 *  Set up basic fields in xevent for keyboard input.
 */

static void
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
{


    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;











    memset(xEvent, 0, sizeof(XEvent));
    xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    xEvent->xany.send_event = false;
    xEvent->xany.display = Tk_Display(tkwin);
    xEvent->xany.window = Tk_WindowId(tkwin);

    xEvent->xkey.root = XRootWindow(Tk_Display(tkwin), 0);
    xEvent->xkey.subwindow = None;
    xEvent->xkey.time = TkpGetMS();
    xEvent->xkey.state = state;
    xEvent->xkey.same_screen = true;



    xEvent->xkey.trans_chars[0] = 0;





























    xEvent->xkey.nbytes = 0;



}

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
    TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();
    (void)owner_events;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)time;

    if (keyboardGrabWinPtr && captureWinPtr) {
	NSWindow *w = TkMacOSXGetNSWindowForDrawable(grab_window);
	MacDrawable *macWin = (MacDrawable *)grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow *) captureWinPtr) {
	    if (modalSession) {
		Tcl_Panic("XGrabKeyboard: already grabbed");
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}







<
<
<
<
<
<
|
|
|

|







469
470
471
472
473
474
475






476
477
478
479
480
481
482
483
484
485
486
487
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);






    if (keyboardGrabWinPtr && grabWinPtr) {
	NSWindow *w = TkMacOSXDrawableWindow(grab_window);
	MacDrawable *macWin = (MacDrawable *) grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow*) grabWinPtr) {
	    if (modalSession) {
		Tcl_Panic("XGrabKeyboard: already grabbed");
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751



















752
753
754
755
756
757
758
759
 *
 * Side effects:
 *	Sets the keyboard focus back to the value before the grab.
 *
 *----------------------------------------------------------------------
 */

int
XUngrabKeyboard(
    Display* display,
    Time time)
{
    (void)display;
    (void)time;

    if (modalSession) {
	[NSApp endModalSession:modalSession];
	modalSession = nil;
    }
    if (keyboardGrabNSWindow) {
	[keyboardGrabNSWindow release];
	keyboardGrabNSWindow = nil;
    }
    keyboardGrabWinPtr = NULL;



















    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetModalSession --
 *







|




<
<
<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







501
502
503
504
505
506
507
508
509
510
511
512



513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
 *
 * Side effects:
 *	Sets the keyboard focus back to the value before the grab.
 *
 *----------------------------------------------------------------------
 */

void
XUngrabKeyboard(
    Display* display,
    Time time)
{



    if (modalSession) {
	[NSApp endModalSession:modalSession];
	modalSession = nil;
    }
    if (keyboardGrabNSWindow) {
	[keyboardGrabNSWindow release];
	keyboardGrabNSWindow = nil;
    }
    keyboardGrabWinPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetCapture --
 *
 * Results:
 *	Returns the current grab window
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkMacOSXGetCapture(void)
{
    return grabWinPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetModalSession --
 *
771
772
773
774
775
776
777




























778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
845
846
847
848




849
850

851
852









































































853
854
855
856
857
858
859
860
{
    return modalSession;
}

/*
 *----------------------------------------------------------------------
 *




























 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the popups used for character
 *      selection by the NSTextInputClient.  It gets called by text entry
 *      widgets whenever the cursor is drawn.  It does nothing if the widget's
 *      NSWindow is not the current KeyWindow.  Otherwise it updates the
 *      display's caret structure and records the caret geometry in static
 *      variables for use by the NSTextInputClient implementation.  Any
 *      widget passed to this function will be marked as being able to input
 *      text by setting the TK_CAN_INPUT_TEXT flag.
 *
 * Results:
 *	None
 *
 * Side effects:
 *      Sets the CAN_INPUT_TEXT flag on the widget passed as tkwin.  May update
 *      the display's caret structure as well as the static variables caret_x,
 *      caret_y and caret_height.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetCaretPos(
    Tk_Window tkwin,
    int x,
    int y,
    int height)
 {
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkCaret *caretPtr = &(winPtr->dispPtr->caret);
    NSWindow *w = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));

    /*

     * Register this widget as being capable of text input, so we know we
     * should process (appropriate) key events for this window with the
     * NSTextInputClient protocol.
     */

    winPtr->flags |= TK_CAN_INPUT_TEXT;
    if (w && ![w isKeyWindow]) {
	return;
    }
    if ((caretPtr->winPtr == winPtr
	 && caretPtr->x == x) && (caretPtr->y == y)) {
	return;
    }

    /*
     * Update the display's caret information.
     */

    caretPtr->winPtr = winPtr;
    caretPtr->x = x;
    caretPtr->y = y;
    caretPtr->height = height;

    /*
     * Record the caret geometry in static variables for use when processing
     * key events.  We use the TKContextView coordinate system for this.

     */

    caret_height = height;
    while (!Tk_IsTopLevel(tkwin)) {
	x += Tk_X(tkwin);
	y += Tk_Y(tkwin);
	tkwin = Tk_Parent(tkwin);
	if (tkwin == NULL) {
	    return;
	}
    }




    caret_x = x;
    caret_y = Tk_Height(tkwin) - y;

}










































































/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
|
<
<
<
<
|





|
<
<











<
|
<


>
|
<
<


<
<
<
<
|
|



<
<
<
<
|





<
<
>


<








>
>
>
>

|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598




599
600
601
602
603
604
605


606
607
608
609
610
611
612
613
614
615
616

617

618
619
620
621


622
623




624
625
626
627
628




629
630
631
632
633
634


635
636
637

638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
{
    return modalSession;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
 *	This function captures the mouse so that all future events will be
 *	reported to this window, even if the mouse is outside the window. If
 *	the specified window is NULL, then the mouse is released.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the capture flag and captures the mouse.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetCapture(
    TkWindow *winPtr)		/* Capture window, or NULL. */
{
    while (winPtr && !Tk_IsTopLevel(winPtr)) {
	winPtr = winPtr->parentPtr;
    }
    grabWinPtr = (Tk_Window) winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the XIM caret. This is called by

 *	widgets to indicate their cursor placement, and the caret location is




 *	used by TkpGetString to place the XIM caret.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	None


 *
 *----------------------------------------------------------------------
 */

void
Tk_SetCaretPos(
    Tk_Window tkwin,
    int x,
    int y,
    int height)
 {

    TkCaret *caretPtr = &(((TkWindow *) tkwin)->dispPtr->caret);


    /*
     * Prevent processing anything if the values haven't changed. Windows only
     * has one display, so we can do this with statics.


     */





    if ((caretPtr->winPtr == ((TkWindow *) tkwin))
	    && (caretPtr->x == x) && (caretPtr->y == y)) {
	return;
    }





    caretPtr->winPtr = ((TkWindow *) tkwin);
    caretPtr->x = x;
    caretPtr->y = y;
    caretPtr->height = height;

    /*


     * As in Windows, adjust to the toplevel to get the coords right.
     */


    while (!Tk_IsTopLevel(tkwin)) {
	x += Tk_X(tkwin);
	y += Tk_Y(tkwin);
	tkwin = Tk_Parent(tkwin);
	if (tkwin == NULL) {
	    return;
	}
    }

    /* But adjust for fact that NS uses flipped view. */
    y = Tk_Height(tkwin) - y;

    caret_x = x;
    caret_y = y;
    caret_height = height;
}


static unsigned convert_ns_to_X_keysym[] =
{
  NSHomeFunctionKey,            0x50,
  NSLeftArrowFunctionKey,       0x51,
  NSUpArrowFunctionKey,         0x52,
  NSRightArrowFunctionKey,      0x53,
  NSDownArrowFunctionKey,       0x54,
  NSPageUpFunctionKey,          0x55,
  NSPageDownFunctionKey,        0x56,
  NSEndFunctionKey,             0x57,
  NSBeginFunctionKey,           0x58,
  NSSelectFunctionKey,          0x60,
  NSPrintFunctionKey,           0x61,
  NSExecuteFunctionKey,         0x62,
  NSInsertFunctionKey,          0x63,
  NSUndoFunctionKey,            0x65,
  NSRedoFunctionKey,            0x66,
  NSMenuFunctionKey,            0x67,
  NSFindFunctionKey,            0x68,
  NSHelpFunctionKey,            0x6A,
  NSBreakFunctionKey,           0x6B,

  NSF1FunctionKey,              0xBE,
  NSF2FunctionKey,              0xBF,
  NSF3FunctionKey,              0xC0,
  NSF4FunctionKey,              0xC1,
  NSF5FunctionKey,              0xC2,
  NSF6FunctionKey,              0xC3,
  NSF7FunctionKey,              0xC4,
  NSF8FunctionKey,              0xC5,
  NSF9FunctionKey,              0xC6,
  NSF10FunctionKey,             0xC7,
  NSF11FunctionKey,             0xC8,
  NSF12FunctionKey,             0xC9,
  NSF13FunctionKey,             0xCA,
  NSF14FunctionKey,             0xCB,
  NSF15FunctionKey,             0xCC,
  NSF16FunctionKey,             0xCD,
  NSF17FunctionKey,             0xCE,
  NSF18FunctionKey,             0xCF,
  NSF19FunctionKey,             0xD0,
  NSF20FunctionKey,             0xD1,
  NSF21FunctionKey,             0xD2,
  NSF22FunctionKey,             0xD3,
  NSF23FunctionKey,             0xD4,
  NSF24FunctionKey,             0xD5,

  NSBackspaceCharacter,         0x08,  /* 8: Not on some KBs. */
  NSDeleteCharacter,            0xFF,  /* 127: Big 'delete' key upper right. */
  NSDeleteFunctionKey,          0x9F,  /* 63272: Del forw key off main array. */

  NSTabCharacter,		0x09,
  0x19,				0x09,  /* left tab->regular since pass shift */
  NSCarriageReturnCharacter,	0x0D,
  NSNewlineCharacter,		0x0D,
  NSEnterCharacter,		0x8D,

  0x1B,				0x1B   /* escape */
};


static unsigned isFunctionKey(unsigned code)
{
    const unsigned last_keysym = (sizeof (convert_ns_to_X_keysym)
                                / sizeof (convert_ns_to_X_keysym[0]));
  unsigned keysym;
  for (keysym = 0; keysym < last_keysym; keysym += 2)
    if (code == convert_ns_to_X_keysym[keysym])
      return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
  return 0;
 }

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXKeyboard.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36





37
38
39
40

41
42
43
44
45



46
47

48
49
50
51
52
53
54
55

56



57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76






77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92






93
94
95
96
97
98
99



100
101
102
103
104
105
106


107
108
109
110
111
112
113
114
115
116
117









118
119
120
121
122
123






124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170




171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238

239
240
241
242
243
244
245
246
247
248
249
250
251

252
253

254
255
256
257
258
259
260
261
262
263
264



265





266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282


283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364

365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415


416
417
418
419
420
421
422
423

424


425
426



427





428
429
430
431
432
433
434
435
436
437
438
439


440
441
442
443



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606












607






608





609






610

































611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634

635

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676

677

678
679
680




681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715

716

717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

733
734


735
736

737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796





797
798
799
800
801
802

803



804
805
806
807
808






809
810
811
812
813

814
815
816







817
818
819

820






821
822
823
824
825
826
827
828
829
830
831
832
833







834


835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889



890
891
892
893
894
895



896
897

898
899
900

901
902

903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
/*
 * tkMacOSXKeyboard.c --
 *
 *	Routines to support keyboard events on the Macintosh.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXKeysyms.h"

/*
 * About keyboards
 * ---------------
 * Keyboards are complicated.  This long comment is an attempt to provide
 * enough information about them to make it possible to read and understand
 * the code in this file.
 *
 * Every key on a keyboard is identified by a number between 0 and 127.  In
 * macOS, pressing or releasing a key on the keyboard generates an NSEvent of
 * type KeyDown, KeyUp or FlagsChanged.  The 8-bit identifier of the key that
 * was involved in this event is provided in the attribute [NSEvent keyCode].
 * Apple also refers to this number as a "Virtual KeyCode".  In this file, to
 * avoid confusion with other uses of the word keycode, we will refer to this
 * key identifier as a "virtual keycode", usually the value of a variable named

 * "virtual".
 *
 * Some of the keys on a keyboard, such as the Shift, Option, Command or





 * Control keys, are "modifier" keys.  The effect of pressing or releasing a
 * key depends on three quantities:
 *     - which key is being pressed or released
 *     - which modifier keys are being held down at the moment

 *     - the current keyboard layout
 * If the key is a modifier key then the effect of pressing or releasing it is
 * only to change the list of which modifier keys are being held down.  Apple
 * reports this by sending an NSEvent of type FlagsChanged.  X11 reports this
 * as a KeyPress or KeyRelease event for the modifier key.  Note that there may



 * be combinations of modifier key states and key presses which have no effect.
 *

 * In X11 every meaningful effect from a key action is identified by a 16 bit
 * value known as a keysym.  Every keysym has an associated string name, also
 * known as a keysym.  The Tk bind command uses the X11 keysym string to
 * specify a key event which should invoke a certain action and it provides the
 * numeric and symbolic keysyms to the bound proc as %N and %K respectively.
 * An X11 XEvent which reports a KeyPress or KeyRelease does not include the
 * keysym.  Instead it includes a platform-specific numerical value called a
 * keycode which is available to the bound procedure as %k.  A platform port of

 * Tk must provide functions which convert between keycodes and numerical



 * keysyms.  Conversion between numerical and symbolic keysyms is provided by
 * the generic Tk code, although platforms are allowed to provide their own by

 * defining the XKeysymToString and XStringToKeysym functions and undefining
 * the macro REDO_KEYSYM_LOOKUP.  This macOS port uses the conversion provided
 * by the generic code.
 *
 * When the keyboard focus is on a Tk widget which provides text input, there
 * are some X11 KeyPress events which cause text to be inserted.  We will call
 * these "printable" events. The UCS-32 character stored in the keycode field
 * of an XKeyEvent depends on more than the three items above.  It may also
 * depend on the sequence of keypresses that preceded the one being reported by
 * the XKeyEvent.  For example, on macOS an <Alt-e> event does not cause text
 * to be inserted but a following <a> event causes an accented 'a' to be
 * inserted.  The events in such a composition sequence, other than the final
 * one, are known as "dead-key" events.
 *
 * MacOS packages the information described above in a different way.  Every
 * meaningful effect from a key action *other than changing the state of
 * modifier keys* is identified by a unicode string which is provided as the
 * [NSEvent characters] attribute of a KeyDown or KeyUp event.  FlagsChanged






 * events do not have characters.  In principle, the characters attribute could
 * be an arbitrary unicode string but in practice it is always a single UTF-16
 * character which we usually store in a variable named keychar.  While the
 * keychar is a legal unicode code point, it does not necessarily represent a
 * glyph. MacOS uses unicode code points in the private-use range 0xF700-0xF8FF
 * for non-printable events which have no associated ASCII code point.  For
 * example, pressing the F2 key generates an NSEvent with the character 0xF705,
 * the Backspace key produces 0x7F (ASCII del) and the Delete key produces
 * 0xF728.
 *
 * With the exception of modifier keys, it is possible to translate between
 * numerical X11 keysyms and macOS keychars; this file constructs Tcl hash
 * tables to do this job, using data defined in the file tkMacOSXKeysyms.h.
 * The code here adopts the convention that the keychar of any modifier key
 * is MOD_KEYCHAR.  Keys which do not appear on any Macintosh keyboard, such
 * as the Menu key on PC keyboards, are assigned UNKNOWN_KEYCHAR.






 *
 * The macosx platform-specific scheme for generating a keycode when mapping an
 * NSEvent of type KeyUp, KeyDown or FlagsChanged to an XEvent of type KeyPress
 * or KeyRelease is as follows:
 *     keycode = (virtual << 24) | index << 22 | keychar
 * where index is a 2-bit quantity whose bits indicate the state of the Option
 * and Shift keys.



 *
 * A few remarks are in order.  First, we are using 32 bits for the keycode and
 * we are allowing room for up to 22 bits for the keychar.  This means that
 * there is enough room in the keycode to hold a UTF-32 character, which only
 * requires 21 bits.  Second, the KeyCode type for the keycode field in an
 * XEvent is currently defined as unsigned int, which was modified from the
 * unsigned short used in X11 in order to accomodate macOS. Finally, there is


 * no obstruction to generating KeyPress events for keys that represent letters
 * which do not exist on the current keyboard layout.  And different keyboard
 * layouts can assign a given letter to different keys.  So we need a
 * convention for what value to assign to "virtual" when computing the keycode
 * for a generated event.  The convention used here is as follows: If there is
 * a key on the current keyboard which produces the keychar, use the virtual
 * keycode of that key.  Otherwise set virtual = NO_VIRTUAL.
 */


/*









 * See tkMacOSXPrivate.h for macros and structures related to key event processing.
 */

/*
 * Hash tables and array used to translate between various key attributes.
 */







static Tcl_HashTable special2keysym;	/* Special virtual keycode to keysym */
static Tcl_HashTable keysym2keycode;	/* keysym to XEvent keycode */
static Tcl_HashTable keysym2unichar;	/* keysym to unichar */
static Tcl_HashTable unichar2keysym;	/* unichar to X11 keysym */
static Tcl_HashTable unichar2xvirtual;	/* unichar to virtual with index */
static UniChar xvirtual2unichar[512];	/* virtual with index to unichar */

/*
 * Flags.
 */

static BOOL initialized = NO;
static BOOL keyboardChanged = YES;

/*
 * Prototypes for static functions used in this file.
 */

static void	InitHashTables(void);
static void     UpdateKeymaps(void);

static int	KeyDataToUnicode(UniChar *uniChars, int maxChars,
			UInt16 keyaction, UInt32 virtual, UInt32 modifiers,
			UInt32 * deadKeyStatePtr);

#pragma mark TKApplication(TKKeyboard)

@implementation TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    keyboardChanged = YES;
    UpdateKeymaps();
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * InitHashTables --
 *
 *	Creates hash tables used by some of the functions in this file.




 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates memory & creates some hash tables.
 *
 *----------------------------------------------------------------------
 */

static void
InitHashTables(void)
{
    Tcl_HashEntry *hPtr;
    const KeyInfo *kPtr;
    const KeysymInfo *ksPtr;
    int dummy, index;

    Tcl_InitHashTable(&special2keysym, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&keysym2keycode, TCL_ONE_WORD_KEYS);
    for (kPtr = keyArray; kPtr->virtual != 0; kPtr++) {
	MacKeycode macKC;
	macKC.v.o_s = 0;
	hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virtual),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym));
	hPtr = Tcl_CreateHashEntry(&keysym2keycode, INT2PTR(kPtr->keysym),
				   &dummy);
	macKC.v.virtual = kPtr->virtual;
	macKC.v.keychar = kPtr->keychar;
	Tcl_SetHashValue(hPtr, INT2PTR(macKC.uint));

	/*
	 * The Carbon framework does not work for finding the unicode character
	 * of a special key.  But that does not depend on the keyboard layout,
	 * so we can record the information here.
	 */

	for (index = 3; index >= 0; index--) {
	    macKC.v.o_s = index;
	    xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar;
	}
    }
    Tcl_InitHashTable(&keysym2unichar, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&unichar2keysym, TCL_ONE_WORD_KEYS);
    for (ksPtr = keysymTable; ksPtr->keysym != 0; ksPtr++) {
	hPtr = Tcl_CreateHashEntry(&keysym2unichar, INT2PTR(ksPtr->keysym),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(ksPtr->keycode));
	hPtr = Tcl_CreateHashEntry(&unichar2keysym, INT2PTR(ksPtr->keycode),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(ksPtr->keysym));
    }
    UpdateKeymaps();
    initialized = YES;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateKeymaps --
 *
 *	Called when the keyboard changes to update the hash tables that provide
 *      maps between unicode characters and virtual keycodes with indexes.  In
 *      order for the map from characters to virtual keycodes to be
 *      well-defined we have to ignore virtual keycodes for keypad keys, since
 *      each keypad key has the same character as the corresponding key on the

 *      main keyboard.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initializes, if necessary, and updates the unichar2xvirtual hash table
 *      and the xvirtual2unichar array.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateKeymaps()

{
    static Bool keymapInitialized = false;

    Tcl_HashEntry *hPtr;
    int virtual, index, dummy;

    if (!keymapInitialized) {
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
	keymapInitialized = true;
    } else {
	Tcl_DeleteHashTable(&unichar2xvirtual);
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
    }
    /*



     * This loop goes backwards so that a lookup by keychar will provide the





     * minimal modifier mask.  Simpler combinations will overwrite more complex
     * ones when constructing the table.
     */

    for (index = 3; index >= 0; index--) {
        for (virtual = 0; virtual < 128; virtual++) {
	    MacKeycode macKC;
	    macKC.v = (keycode_v) {.virtual = virtual, .o_s = index, .keychar = 0};
	    int modifiers = INDEX2CARBON(index), result;
	    UniChar keychar = 0;
	    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virtual,
				      modifiers, NULL);
	    if (keychar == 0x10) {


		/*
		 * This is a special key, handled in InitHashTables.
		 */



		continue;
	    }
	    macKC.v.keychar = keychar;

	    if (! ON_KEYPAD(virtual)) {
		hPtr = Tcl_CreateHashEntry(&unichar2xvirtual,
					   INT2PTR(macKC.x.keychar), &dummy);
		Tcl_SetHashValue(hPtr, INT2PTR(macKC.x.xvirtual));
            }
	    xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * KeyDataToUnicode --
 *
 *	Given MacOS key event data this function generates the keychar.  It
 *	does this by using OS resources from the Carbon framework.  Note that
 *      the Carbon functions used here are not aware of the keychars in the
 *      private-use range which macOS now uses for special keys.  For those
 *      keys this function returns 0x10 (ASCII dle).
 *
 *	The parameter deadKeyStatePtr can be NULL, if no deadkey handling is
 *	needed (which is always the case here).
 *
 *	This function is called in XKeycodeToKeysym and UpdateKeymaps.
 *
 * Results:
 *	The number of characters generated if any, 0 if we are waiting for
 *	another byte of a dead-key sequence.

 *
 * Side Effects:
 *	 Fills in the uniChars array with a Unicode string.

 *
 *----------------------------------------------------------------------
 */


static int
KeyDataToUnicode(
    UniChar *uniChars,
    int maxChars,
    UInt16 keyaction,
    UInt32 virtual,
    UInt32 modifiers,
    UInt32 *deadKeyStatePtr)
{
    static const void *layoutData = NULL;
    static UInt32 keyboardType = 0;
    UniCharCount actuallength = 0;

    if (keyboardChanged) {
	TISInputSourceRef currentKeyboardLayout =
		TISCopyCurrentKeyboardLayoutInputSource();

	if (currentKeyboardLayout) {
	    CFDataRef keyLayoutData = (CFDataRef) TISGetInputSourceProperty(
		    currentKeyboardLayout, kTISPropertyUnicodeKeyLayoutData);

	    if (keyLayoutData) {
		layoutData = CFDataGetBytePtr(keyLayoutData);
		keyboardType = LMGetKbdType();
	    }
	    CFRelease(currentKeyboardLayout);
	}
	keyboardChanged = 0;
    }
    if (layoutData) {
	OptionBits options = 0;
	UInt32 dummyState;
	OSStatus err;

	virtual &= 0xFF;
	modifiers = (modifiers >> 8) & 0xFF;

	if (!deadKeyStatePtr) {
	    options = kUCKeyTranslateNoDeadKeysMask;
	    dummyState = 0;
	    deadKeyStatePtr = &dummyState;
	}

	err = ChkErr(UCKeyTranslate, layoutData, virtual, keyaction, modifiers,
		keyboardType, options, deadKeyStatePtr, maxChars,
		&actuallength, uniChars);
	if (!actuallength && *deadKeyStatePtr) {


	    /*
	     * We are waiting for another key.
	     */

	    return 0;
	}
	*deadKeyStatePtr = 0;
	if (err != noErr) {
	    actuallength = 0;
	}
    }
    return actuallength;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeycodeToKeysym --
 *
 *	This is a stub function which translates from the keycode used in an
 *      XEvent to a numerical keysym.  On macOS, the display parameter is
 *      ignored and only the the virtual keycode stored in the .virtual bitfield
 *      of a MacKeycode.v.
 *
 * Results:
 *      Returns the corresponding numerical keysym, or NoSymbol if the keysym
 *      cannot be found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XkbKeycodeToKeysym(
    TCL_UNUSED(Display *),
    unsigned int keycode,
    TCL_UNUSED(int),
    int index)
{
    Tcl_HashEntry *hPtr;
    MacKeycode macKC;
    int modifiers, result;
    UniChar keychar = 0;



    if (!initialized) {
	InitHashTables();
    }
    macKC.uint = keycode;
    macKC.v.o_s = index;

    /*
     * First check if the virtual keycode corresponds to a special key, such as

     * an Fn function key or Tab, Backspace, Home, End, etc.


     */




    hPtr = Tcl_FindHashEntry(&special2keysym, INT2PTR(macKC.v.virtual));





    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }

    /*
     * If the virtual value in this keycode does not correspond to an actual
     * key in the current keyboard layout, try using its keychar to look up a
     * keysym.
     */

    if (macKC.v.virtual > 127) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(macKC.v.keychar));


	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }




    /*
     * If the virtual keycode does belong to a key, use the virtual and the
     * Option-Shift from index to look up a keychar by using the Carbon
     * Framework; then translate the keychar to a keysym using the
     * unicode2keysym hash table.
     */

    modifiers = INDEX2CARBON(macKC.v.o_s);
    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, macKC.v.virtual,
			      modifiers, NULL);
    if (result) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(keychar));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }
    return NoSymbol;
}

KeySym
XKeycodeToKeysym(
    TCL_UNUSED(Display *),
    unsigned int keycode,
    int index)
{
    return XkbKeycodeToKeysym(NULL, keycode, 0, index);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetString --
 *
 *	This is a stub function which retrieves the string stored in the
 *      transchars field of an XEvent and converts it to a Tcl_DString.
 *
 * Results:
 *	Returns a pointer to the string value of the DString.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TCL_UNUSED(TkWindow *),	/* Window where event occurred: Needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{
    MacKeycode macKC;
    char utfChars[8];
    int length = 0;

    macKC.uint = eventPtr->xkey.keycode;
    if (IS_PRINTABLE(macKC.v.keychar)) {
	length = TkUniCharToUtf(macKC.v.keychar, utfChars);
    }
    utfChars[length] = 0;

    Tcl_DStringInit(dsPtr);
    return Tcl_DStringAppend(dsPtr, utfChars, length);
}

/*
 *----------------------------------------------------------------------
 *
 * XGetModifierMapping --
 *
 *	X11 stub function to get the keycodes used as modifiers.  This
 *      is never called by the macOS port.
 *
 * Results:
 *	Returns a newly allocated modifier map.
 *
 * Side effects:
 *	Allocates a new modifier map data structure.
 *
 *----------------------------------------------------------------------
 */

XModifierKeymap *
XGetModifierMapping(
    TCL_UNUSED(Display *))
{
    XModifierKeymap *modmap;








    modmap = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
    modmap->max_keypermod = 0;
    modmap->modifiermap = NULL;
    return modmap;
}

/*
 *----------------------------------------------------------------------
 *
 * XFreeModifiermap --
 *
 *	Deallocates a modifier map that was created by XGetModifierMapping.
 *      This is also never called by the macOS port.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the datastructure referenced by modmap.
 *
 *----------------------------------------------------------------------
 */

int
XFreeModifiermap(
    XModifierKeymap *modmap)
{
    if (modmap->modifiermap != NULL) {
	ckfree(modmap->modifiermap);
    }
    ckfree(modmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString, XStringToKeysym --
 *
 *	These X11 stub functions map keysyms to strings & strings to keysyms.
 *      A platform can do its own conversion by defining these and undefining
 *      REDO_KEYSYM_LOOKUP.  The macOS port defines REDO_KEYSYM_LOOKUP so these
 *      are never called and Tk does the conversion for us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    TCL_UNUSED(KeySym))
{
    return NULL;
}

KeySym
XStringToKeysym(
    TCL_UNUSED(const char *))
{
    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToKeycode --
 *












 *	This is a stub function which converts a numerical keysym to the






 *      platform-specific keycode used in a KeyPress or KeyRelease XEvent.





 *      For macOS the keycode is an unsigned int with bitfields described






 *      in the definition of the MacKeycode type.

































 *
 * Results:
 *
 *      A macOS KeyCode. See the description of keycodes at the top of this
 *	file and the definition of the MacKeycode type in tkMacOSXPrivate.h.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeyCode
XKeysymToKeycode(
    TCL_UNUSED(Display *),
    KeySym keysym)
{
    Tcl_HashEntry *hPtr;
    MacKeycode macKC;
    if (!initialized) {
	InitHashTables();
    }

    /*

     * First check for a special key.

     */

    hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym));
    if (hPtr != NULL) {
	return (KeyCode) Tcl_GetHashValue(hPtr);
    }

    /*
     * Initialize the keycode as if the keysym cannot be converted to anything
     * else.
     */

    macKC.v.virtual = NO_VIRTUAL;
    macKC.v.o_s = 0;
    macKC.v.keychar = 0;

    /*
     * If the keysym is recognized fill in the keychar.  Also fill in the
     * xvirtual field if the key exists on the current keyboard.
     */

    hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&keysym2unichar,
					       INT2PTR(keysym));
    if (hPtr != NULL) {
	unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	macKC.x.keychar = (unsigned int) data;
	hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar));
	if (hPtr != NULL) {
	    data = (unsigned long) Tcl_GetHashValue(hPtr);
	    macKC.x.xvirtual = (unsigned int) data;
	}
    }
    return (KeyCode) macKC.uint;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetKeycodeAndState --
 *
 *	This function accepts a keysym and an XEvent and sets some fields of

 *	the XEvent.  It is used by the event generate command.

 *
 * Results:
 *      None




 *
 * Side effects:
 *
 *	Modifies the XEvent. Sets the xkey.keycode to a keycode value formatted
 *	by XKeysymToKeycode and updates the shift and option flags in
 *	xkey.state if either of those modifiers is required to generate the
 *	keysym.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetKeycodeAndState(
    TCL_UNUSED(Tk_Window),
    KeySym keysym,
    XEvent *eventPtr)
{
    if (keysym == NoSymbol) {
	eventPtr->xkey.keycode = 0;
    } else {
	int eventIndex = STATE2INDEX(eventPtr->xkey.state);
	MacKeycode macKC;
	macKC.uint = XKeysymToKeycode(NULL, keysym);

	/*
	 * We have a virtual keycode and a minimal choice for Shift and Option
	 * modifiers which generates the keychar that corresponds to the
	 * specified keysym.  But we might not have the correct keychar yet,
	 * because the xEvent may have specified modifiers beyond our minimal
	 * set.  For example, the events described by <Oslash>, <Shift-oslash>,
	 * <Shift-Option-O> and <Shift-Option-o> should all produce the same
	 * uppercase Danish O.  So we may need to add the extra modifiers and
	 * do another lookup for the keychar.  We don't want to do this for
	 * special keys, however.

	 */


	if (macKC.v.o_s != eventIndex) {

	    macKC.v.o_s |= eventIndex;
	}
	if (macKC.v.keychar < 0xF700) {
	    UniChar keychar = macKC.v.keychar;
	    NSString *str, *lower, *upper;
	    if (macKC.v.virtual != NO_VIRTUAL) {
		macKC.x.keychar = xvirtual2unichar[macKC.x.xvirtual];
	    } else {
		str = [[NSString alloc] initWithCharacters:&keychar length:1];
		lower = [str lowercaseString];
		upper = [str uppercaseString];
		if (![str isEqual: lower]) {
		    macKC.v.o_s |= INDEX_SHIFT;
		}
		if (macKC.v.o_s & INDEX_SHIFT) {
		    macKC.v.keychar = [upper characterAtIndex:0];

		}
	    }


	}
	eventPtr->xkey.keycode = macKC.uint;

	eventPtr->xkey.state |= INDEX2STATE(macKC.v.o_s);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --
 *
 *	This is a stub function called in tkBind.c.  Given a KeyPress or
 *	KeyRelease XEvent, it maps the keycode in the event to a numerical
 *      keysym.
 *
 * Results:
 *	The return value is the keysym corresponding to eventPtr, or NoSymbol
 *	if no matching keysym could be found.
 *
 * Side effects:
 *	In the first call for a given display, calls TkpInitKeymapInfo.
 *
 *
 *----------------------------------------------------------------------
 */

KeySym
TkpGetKeySym(
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;
    MacKeycode macKC;
    macKC.uint = eventPtr->xkey.keycode;

    /*
     * Refresh the mapping information if it's stale.
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);
    }

    /*
     * Modifier key events have a special mac keycode (see tkProcessKeyEvent).

     */

    if (macKC.v.keychar == MOD_KEYCHAR) {
	switch (macKC.v.virtual) {
	case 54:
	    return XK_Meta_R;
	case 55:
	    return XK_Meta_L;
	case 56:
	    return XK_Shift_L;
	case 57:
	    return XK_Caps_Lock;
	case 58:
	    return XK_Alt_L;
	case 59:
	    return XK_Control_L;





	case 60:
	    return XK_Shift_R;
	case 61:
	    return XK_Alt_R;
	case 62:
	    return XK_Control_R;

	case 63:



	    return XK_Super_L;
	default:
	    return NoSymbol;
	}
    }







    /*
     * Figure out which of the four slots in the keymap vector to use for this
     * key. Refer to Xlib documentation for more info on how this computation
     * works.

     */

    index = STATE2INDEX(eventPtr->xkey.state);







    if (eventPtr->xkey.state & LockMask) {
	index |= INDEX_SHIFT;
    }








    /*
     * First do the straightforward lookup.
     */

    sym = XkbKeycodeToKeysym(dispPtr->display, macKC.uint, 0, index);

    /*
     * Special handling: If the key was shifted because of Lock, which is only
     * caps lock on macOS, not shift lock, and if the shifted keysym isn't
     * upper-case alphabetic, then switch back to the unshifted keysym.
     */

    if ((index & INDEX_SHIFT) && !(eventPtr->xkey.state & ShiftMask)) {







	if ((sym == NoSymbol) || !Tcl_UniCharIsUpper(sym)) {


	    sym = XkbKeycodeToKeysym(dispPtr->display, macKC.uint, 0,
				   index & ~INDEX_SHIFT);
	}
    }

    /*
     * Another bit of special handling: If this is a shifted key and there is
     * no keysym defined, then use the keysym for the unshifted key.
     */

    if ((index & INDEX_SHIFT) && (sym == NoSymbol)) {
	sym = XkbKeycodeToKeysym(dispPtr->display, macKC.uint, 0,
			       index & ~INDEX_SHIFT);
    }
    return sym;
}

/*
 *--------------------------------------------------------------
 *
 * TkpInitKeymapInfo --
 *
 *	This procedure initializes fields in the display that pertain
 *      to modifier keys.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Modifier key information in dispPtr is initialized.
 *
 *--------------------------------------------------------------
 */

void
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    dispPtr->bindInfoStale = 0;

    /*
     * On macOS the caps lock key is always interpreted to mean that alphabetic
     * keys become uppercase but other keys do not get shifted.  (X11 allows
     * a configuration option which makes the caps lock equivalent to holding
     * down the shift key.)
     * There is no offical "Mode_switch" key.
     */

    dispPtr->lockUsage = LU_CAPS;

    /* This field is no longer used by tkBind.c */

    dispPtr->modeModMask = 0;




    /* The Alt and Meta keys are interchanged on Macintosh keyboards compared
     * to PC keyboards.  These fields could be set to make the Alt key on a PC
     * keyboard behave likd an Alt key. That would also require interchanging
     * Mod1Mask and Mod2Mask in tkMacOSXKeyEvent.c.
     */




    dispPtr->altModMask = 0;
    dispPtr->metaModMask = 0;


    /*
     * The modKeyCodes table lists the keycodes that appear in KeyPress or

     * KeyRelease XEvents for modifier keys.  In tkBind.c this table is
     * searched to determine whether an XEvent corresponds to a modifier key.

     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree(dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = NUM_MOD_KEYCODES;
    dispPtr->modKeyCodes = (KeyCode *)ckalloc(NUM_MOD_KEYCODES * sizeof(KeyCode));
    for (int i = 0; i < NUM_MOD_KEYCODES; i++) {
	dispPtr->modKeyCodes[i] = XKeysymToKeycode(NULL, modKeyArray[i]);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXAddVirtual --
 *
 *	This procedure is an internal utility which accepts an unsigned int
 *      that has been partially filled as a MacKeycode, having the Option and
 *      Shift state set in the o_s field and the keychar field set but with the
 *      virtual keycode blank.  It looks up the virtual keycode for the keychar
 *      (possibly NO_VIRTUAL) and returns an unsigned int which is a complete
 *      MacKeycode with the looked up virtual keycode added.  This is used when
 *      creating XEvents for the unicode characters which are generated by the
 *      NSTextInputClient.
 *
 * Results:
 *      An unsigned int which is a complete MacKeycode, including a virtual
 *	keycode which matches the Option-Shift state and keychar.
 *
 * Side effects:
 *	None
 *
 *--------------------------------------------------------------
 */
unsigned
TkMacOSXAddVirtual(
    unsigned int keycode)
{
    MacKeycode macKC;
    Tcl_HashEntry *hPtr;
    macKC.uint = keycode;

    if (!initialized) {
	InitHashTables();
    }

    hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&unichar2xvirtual,
					       INT2PTR(macKC.v.keychar));
    if (hPtr != NULL) {
	unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	macKC.x.xvirtual = (unsigned int) data;
    } else {
	macKC.v.virtual = NO_VIRTUAL;
    }
    return macKC.uint;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */








<






<
|
<


<
<
<
<
|

<
<
<
<
<
<
<
>
|
|
|
>
>
>
>
>
|
|
<
<
>
|
<
<
<
<
>
>
>
<
|
>
|
<
|
<
<
|
|
<
>
|
>
>
>
|
<
>
|
|
<

<
<
|
<
<
<
<
<
<
|
|
<
<
<
>
>
>
>
>
>
|
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
>
>
>
>
>
>
|
<
<
<
<
<
|
>
>
>
|
<
<
<
<
<
<
>
>
<
<
<
<
<
<
<
<

|
<
>
>
>
>
>
>
>
>
>
|
<
|
<
<
<
>
>
>
>
>
>

|
|
|
|
<
<

|
|
<

<
|





|
|
>
|
|







<



|
<








|


>
>
>
>











|


|
<
|

<
|
|
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
|
|

<
|





|

<
<
<
|
<
>
|
>





<
|





|
>

|
>
|
|

<
<
<
<
|
<
|

>
>
>
|
>
>
>
>
>
|
<

<
<
<
|
<
<
|
<
|
|
>
|
<
<
<
>
>
|
<
|
|
>
|
<
|
<
|
<







|

|
|
<
<
<


|

|



|
>


<
>




<

|



|



|












|






|




|

>





>
|


<

>

|

















|
|
<
<


|
<








|
|
|
<


|
|
<
|

>
>

|

<
<


<
>
|
>
>


>
>
>
|
>
>
>
>
>





<
|
<


|
<
>
>
|
|
|
|
>
>
>


<
<
|
|


<
<
<
|
<
<
|
|
|

<
<
<
<
<
<
<
<
<







|
<


|







|

|





<
<
<
|
<
<
<
<
<
<

|







|
<


|









|



>
>
>
>
>
>
>
|










|
<















|

|








|
|
|
|












|






|







|

>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|









|


<
|
<
|
|
<

>
|
>


<
|
<
<
|
<
<
|
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|







|
>
|
>


<
>
>
>
>


|
<
<
<
<



>


|






|
|
<


<
<
<
<
<
<
<
<
<
>


>
|
>
|

|
|
<
<
<
<
<
<
<
|
|
|
|
<
>
|
|
>
>
|
|
>
|
>








<
|
|






|
|











<
<










|
>


|
<
|
|
|

|

|

|

|

>
>
>
>
>
|

|

|

>
|
>
>
>
|
<



>
>
>
>
>
>




|
>


|
>
>
>
>
>
>
>
|
|

>

>
>
>
>
>
>

|


|


|
|
|


|
>
>
>
>
>
>
>
|
>
>
|
|








|
|
|









|
|
>





|












|
|
<
<




<
<
<


>
>
>
|
|
|
|


>
>
>


>


|
>
|
|
>



|

|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1
2
3
4
5
6
7
8

9
10
11
12
13
14

15

16
17




18
19







20
21
22
23
24
25
26
27
28
29
30


31
32




33
34
35

36
37
38

39


40
41

42
43
44
45
46
47

48
49
50

51


52






53
54



55
56
57
58
59
60
61
62






63
64






65
66
67
68
69
70
71





72
73
74
75
76






77
78








79
80

81
82
83
84
85
86
87
88
89
90

91



92
93
94
95
96
97
98
99
100
101
102


103
104
105

106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160

161
162





163
164


165
166











167




168
169
170
171
172

173
174
175
176
177
178
179
180



181

182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203




204

205
206
207
208
209
210
211
212
213
214
215
216

217



218


219

220
221
222
223



224
225
226

227
228
229
230

231

232

233
234
235
236
237
238
239
240
241
242
243



244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332

333
334
335
336
337
338
339
340
341
342
343

344
345
346
347

348
349
350
351
352
353
354


355
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377

378
379
380

381
382
383
384
385
386
387
388
389
390
391


392
393
394
395



396


397
398
399
400









401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426



427






428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615

616
617

618
619
620
621
622
623

624


625


626

627



628




629









630

631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651




652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668









669
670
671
672
673
674
675
676
677
678







679
680
681
682

683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721


722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869


870
871
872
873



874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903


904
905
906














































907
908
909
910
911
912
913
914
/*
 * tkMacOSXKeyboard.c --
 *
 *	Routines to support keyboard events on the Macintosh.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"

#include "tkMacOSXEvent.h"


/*




 * A couple of simple definitions to make code a bit more self-explaining.
 *







 * For the assignments of Mod1==meta==command and Mod2==alt==option, see also
 * tkMacOSXMouseEvent.c.
 */

#define LATIN1_MAX	 255
#define MAC_KEYCODE_MAX	 0x7F
#define MAC_KEYCODE_MASK 0x7F
#define COMMAND_MASK	 Mod1Mask
#define OPTION_MASK	 Mod2Mask




/*
 * Tables enumerating the special keys defined on Mac keyboards. These are




 * necessary for correct keysym mappings for all keys where the keysyms are
 * not identical with their ASCII or Latin-1 code points.
 */


typedef struct {
    int keycode;		/* Macintosh keycode. */

    KeySym keysym;		/* X windows keysym. */


} KeyInfo;


/*
 * Notes on keyArray:
 *
 * 0x34, XK_Return - Powerbooks use this and some keymaps define it.
 *
 * 0x4C, XK_Return - XFree86 and Apple's X11 call this one XK_KP_Enter.

 *
 * 0x47, XK_Clear - This key is NumLock when used on PCs, but Mac
 * applications don't use it like that, nor does Apple's X11.

 *


 * All other keycodes are taken from the published ADB keyboard layouts.






 */




static KeyInfo keyArray[] = {
    {0x24,	XK_Return},
    {0x30,	XK_Tab},
    {0x33,	XK_BackSpace},
    {0x34,	XK_Return},
    {0x35,	XK_Escape},

    {0x47,	XK_Clear},






    {0x4C,	XK_KP_Enter},







    {0x72,	XK_Help},
    {0x73,	XK_Home},
    {0x74,	XK_Page_Up},
    {0x75,	XK_Delete},
    {0x77,	XK_End},
    {0x79,	XK_Page_Down},






    {0x7B,	XK_Left},
    {0x7C,	XK_Right},
    {0x7D,	XK_Down},
    {0x7E,	XK_Up},







    {0,		0}
};









static KeyInfo virtualkeyArray[] = {

    {122,	XK_F1},
    {120,	XK_F2},
    {99,	XK_F3},
    {118,	XK_F4},
    {96,	XK_F5},
    {97,	XK_F6},
    {98,	XK_F7},
    {100,	XK_F8},
    {101,	XK_F9},
    {109,	XK_F10},

    {103,	XK_F11},



    {111,	XK_F12},
    {105,	XK_F13},
    {107,	XK_F14},
    {113,	XK_F15},
    {0,		0}
};

static int initialized = 0;
static Tcl_HashTable keycodeTable;	/* keyArray hashed by keycode value. */
static Tcl_HashTable vkeyTable;		/* virtualkeyArray hashed by virtual
					 * keycode value. */



static int latin1Table[LATIN1_MAX+1];	/* Reverse mapping table for
					 * controls, ASCII and Latin-1. */



static int keyboardChanged = 1;

/*
 * Prototypes for static functions used in this file.
 */

static void	InitKeyMaps (void);
static void	InitLatin1Table(Display *display);
static int	XKeysymToMacKeycode(Display *display, KeySym keysym);
static int	KeycodeToUnicode(UniChar * uniChars, int maxChars,
			UInt16 keyaction, UInt32 keycode, UInt32 modifiers,
			UInt32 * deadKeyStatePtr);

#pragma mark TKApplication(TKKeyboard)

@implementation TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification
{

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    keyboardChanged = 1;

}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * InitKeyMaps --
 *
 *	Creates hash tables used by some of the functions in this file.
 *
 *	FIXME: As keycodes are defined to be in the limited range 0-127, it
 *	would be easier and more efficient to use directly initialized plain
 *	arrays and drop this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates memory & creates some hash tables.
 *
 *----------------------------------------------------------------------
 */

static void
InitKeyMaps(void)
{
    Tcl_HashEntry *hPtr;
    KeyInfo *kPtr;

    int dummy;


    Tcl_InitHashTable(&keycodeTable, TCL_ONE_WORD_KEYS);
    for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) {





	hPtr = Tcl_CreateHashEntry(&keycodeTable, INT2PTR(kPtr->keycode),
		&dummy);


	Tcl_SetHashValue(hPtr, kPtr->keysym);
    }











    Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS);




    for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) {
	hPtr = Tcl_CreateHashEntry(&vkeyTable, INT2PTR(kPtr->keycode),
		&dummy);
	Tcl_SetHashValue(hPtr, kPtr->keysym);
    }

    initialized = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * InitLatin1Table --
 *



 *	Creates a simple table to be used for mapping from keysyms to keycodes.

 *	Always needs to be called before using latin1Table, because the
 *	keyboard layout may have changed, and than the table must be
 *	re-computed.
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	Sets the global latin1Table.
 *
 *----------------------------------------------------------------------
 */

static void
InitLatin1Table(
    Display *display)
{
    int keycode;
    KeySym keysym;
    int state;
    int modifiers;





    memset(latin1Table, 0, sizeof(latin1Table));


    /*
     * In the common X11 implementations, a keymap has four columns
     * "plain", "Shift", "Mode_switch" and "Mode_switch + Shift". We don't
     * use "Mode_switch", but we use "Option" instead. (This is similar to
     * Apple's X11 implementation, where "Mode_switch" is used as an alias
     * for "Option".)
     *
     * So here we go through all 4 columns of the keymap and find all
     * Latin-1 compatible keycodes. We go through the columns back-to-front
     * from the more exotic columns to the more simple, so that simple
     * keycode-modifier combinations are preferred in the resulting table.

     */






    for (state = 3; state >= 0; state--) {

	modifiers = 0;
	if (state & 1) {
	    modifiers |= shiftKey;
	}



	if (state & 2) {
	    modifiers |= optionKey;
	}


	for (keycode = 0; keycode <= MAC_KEYCODE_MAX; keycode++) {
	    keysym = XKeycodeToKeysym(display,keycode<<16,state);
	    if (keysym <= LATIN1_MAX) {

		latin1Table[keysym] = keycode | modifiers;

	    }

	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * KeycodeToUnicode --
 *
 *	Given MacOS key event data this function generates the Unicode
 *	characters. It does this using OS resources and APIs.



 *
 *	The parameter deadKeyStatePtr can be NULL, if no deadkey handling is
 *	needed.
 *
 *	This function is called from XKeycodeToKeysym() in tkMacOSKeyboard.c.
 *
 * Results:
 *	The number of characters generated if any, 0 if we are waiting for
 *	another byte of a dead-key sequence. Fills in the uniChars array with a
 *	Unicode string.
 *
 * Side Effects:

 *	None
 *
 *----------------------------------------------------------------------
 */


static int
KeycodeToUnicode(
    UniChar *uniChars,
    int maxChars,
    UInt16 keyaction,
    UInt32 keycode,
    UInt32 modifiers,
    UInt32 *deadKeyStatePtr)
{
    static const void *uchr = NULL;
    static UInt32 keyboardType = 0;
    UniCharCount actuallength = 0;

    if (keyboardChanged) {
	TISInputSourceRef currentKeyboardLayout =
		TISCopyCurrentKeyboardLayoutInputSource();

	if (currentKeyboardLayout) {
	    CFDataRef keyLayoutData = (CFDataRef) TISGetInputSourceProperty(
		    currentKeyboardLayout, kTISPropertyUnicodeKeyLayoutData);

	    if (keyLayoutData) {
		uchr = CFDataGetBytePtr(keyLayoutData);
		keyboardType = LMGetKbdType();
	    }
	    CFRelease(currentKeyboardLayout);
	}
	keyboardChanged = 0;
    }
    if (uchr) {
	OptionBits options = 0;
	UInt32 dummyState;
	OSStatus err;

	keycode &= 0xFF;
	modifiers = (modifiers >> 8) & 0xFF;

	if (!deadKeyStatePtr) {
	    options = kUCKeyTranslateNoDeadKeysMask;
	    dummyState = 0;
	    deadKeyStatePtr = &dummyState;
	}

	err = ChkErr(UCKeyTranslate, uchr, keycode, keyaction, modifiers,
		keyboardType, options, deadKeyStatePtr, maxChars,
		&actuallength, uniChars);


	if (!actuallength && *deadKeyStatePtr) {
	    /*
	     * More data later
	     */

	    return 0;
	}
	*deadKeyStatePtr = 0;
	if (err != noErr) {
	    actuallength = 0;
	}
    }
    return actuallength;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeycodeToKeysym --
 *
 *	Translate from a system-dependent keycode to a system-independent
 *	keysym.


 *
 * Results:
 *	Returns the translated keysym, or NoSymbol on failure.

 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XKeycodeToKeysym(
    Display* display,
    KeyCode keycode,

    int index)
{
    register Tcl_HashEntry *hPtr;
    int newKeycode;

    UniChar newChar;

    (void) display; /*unused*/

    if (!initialized) {
	InitKeyMaps();
    }



    /*

     * When determining what keysym to produce we first check to see if the key
     * is a function key. We then check to see if the character is another
     * non-printing key. Finally, we return the key syms for all ASCII and
     * Latin-1 chars.
     */

    newKeycode = keycode >> 16;

    if ((keycode & 0xFFFF) >= 0xF700) { /* NSEvent.h function key unicodes */
	hPtr = Tcl_FindHashEntry(&vkeyTable, INT2PTR(newKeycode));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }
    hPtr = Tcl_FindHashEntry(&keycodeTable, INT2PTR(newKeycode));
    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }

    /*

     * Add in the Mac modifier flags for shift and option.

     */

    if (index & 1) {

	newKeycode |= shiftKey;
    }
    if (index & 2) {
	newKeycode |= optionKey;
    }

    newChar = 0;
    KeycodeToUnicode(&newChar, 1, kUCKeyActionDown, newKeycode & 0x00FF,
	    newKeycode & 0xFF00, NULL);

    /*


     * X11 keysyms are identical to Unicode for ASCII and Latin-1. Give up for
     * other characters for now.
     */




    if ((newChar >= XK_space) && (newChar <= LATIN1_MAX)) {


	return newChar;
    }

    return NoSymbol;









}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetString --
 *
 *	Retrieve the string equivalent for the given keyboard event.

 *
 * Results:
 *	Returns the UTF string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred: Needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{



    (void) winPtr; /*unused*/






    Tcl_DStringInit(dsPtr);
    return Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * XGetModifierMapping --
 *
 *	Fetch the current keycodes used as modifiers.

 *
 * Results:
 *	Returns a new modifier map.
 *
 * Side effects:
 *	Allocates a new modifier map data structure.
 *
 *----------------------------------------------------------------------
 */

XModifierKeymap *
XGetModifierMapping(
    Display *display)
{
    XModifierKeymap *modmap;

    (void) display; /*unused*/

    /*
     * MacOSX doesn't use the key codes for the modifiers for anything, and we
     * don't generate them either. So there is no modifier map.
     */

    modmap = (XModifierKeymap *) ckalloc(sizeof(XModifierKeymap));
    modmap->max_keypermod = 0;
    modmap->modifiermap = NULL;
    return modmap;
}

/*
 *----------------------------------------------------------------------
 *
 * XFreeModifiermap --
 *
 *	Deallocate a modifier map that was created by XGetModifierMapping.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the datastructure referenced by modmap.
 *
 *----------------------------------------------------------------------
 */

int
XFreeModifiermap(
    XModifierKeymap *modmap)
{
    if (modmap->modifiermap != NULL) {
	ckfree((char *) modmap->modifiermap);
    }
    ckfree((char *) modmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString, XStringToKeysym --
 *
 *	These X window functions map keysyms to strings & strings to keysyms.
 *	However, Tk already does this for the most common keysyms. Therefore,
 *	these functions only need to support keysyms that will be specific to
 *	the Macintosh. Currently, there are none.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
{
    return NULL;
}

KeySym
XStringToKeysym(
    const char* string)
{
    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToMacKeycode --
 *
 *	An internal function like XKeysymToKeycode but only generating the Mac
 *	specific keycode plus the modifiers Shift and Option.
 *
 * Results:
 *	A Mac keycode with the actual keycode in the low byte and Mac-style
 *	modifier bits in the high byte.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
XKeysymToMacKeycode(
    Display *display,
    KeySym keysym)
{
    KeyInfo *kPtr;

    if (keysym <= LATIN1_MAX) {
	/*
	 * Handle keysyms in the Latin-1 range where keysym and Unicode
	 * character code point are the same.
	 */

	if (keyboardChanged) {
	    InitLatin1Table(display);
	    keyboardChanged = 0;
	}
	return latin1Table[keysym];
    }

    /*
     * Handle special keys from our exception tables. Don't mind if this is
     * slow, neither the test suite nor [event generate] need to be optimized
     * (we hope).
     */

    for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) {
	if (kPtr->keysym == keysym) {
	    return kPtr->keycode;
	}
    }
    for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) {
	if (kPtr->keysym == keysym) {
	    return kPtr->keycode;
	}
    }

    /*
     * For other keysyms (not Latin-1 and not special keys), we'd need a
     * generic keysym-to-unicode table. We don't have that, so we give up here.
     */

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToKeycode --
 *
 *	The function XKeysymToKeycode takes an X11 keysym and converts it into
 *	a Mac keycode. It is in the stubs table for compatibility but not used
 *	anywhere in the core.
 *
 * Results:
 *	A 32 bit keycode with the the mac keycode (without modifiers) in the
 *	higher 16 bits of the keycode and the ASCII or Latin-1 code in the
 *	lower 8 bits of the keycode.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeyCode
XKeysymToKeycode(
    Display* display,
    KeySym keysym)
{

    int macKeycode = XKeysymToMacKeycode(display, keysym);

    KeyCode result;


    /*
     * See also TkpSetKeycodeAndState. The 0x0010 magic is used in
     * XKeycodeToKeysym. For special keys like XK_Return the lower 8 bits of
     * the keysym are usually a related ASCII control code.
     */


    if ((keysym >= XK_F1) && (keysym <= XK_F35)) {


	result = 0x0010;


    } else {

	result = 0x00FF & keysym;



    }




    result |= (macKeycode & MAC_KEYCODE_MASK) << 16;











    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetKeycodeAndState --
 *
 *	The function TkpSetKeycodeAndState takes a keysym and fills in the
 *	appropriate members of an XEvent. It is similar to XKeysymToKeycode,
 *	but it also sets the modifier mask in the XEvent. It is used by [event
 *	generate] and it is in the stubs table.
 *
 * Results:

 *	Fills an XEvent, sets the member xkey.keycode with a keycode
 *	formatted the same as XKeysymToKeycode and the member xkey.state with
 *	the modifiers implied by the keysym. Also fills in xkey.trans_chars,
 *	so that the actual characters can be retrieved later.
 *
 * Side effects:
 *	None.




 *
 *----------------------------------------------------------------------
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keysym,
    XEvent *eventPtr)
{
    if (keysym == NoSymbol) {
	eventPtr->xkey.keycode = 0;
    } else {
	Display *display = Tk_Display(tkwin);
	int macKeycode = XKeysymToMacKeycode(display, keysym);


	/*









	 * See also XKeysymToKeycode.
	 */

	if ((keysym >= XK_F1) && (keysym <= XK_F35)) {
	    eventPtr->xkey.keycode = 0x0010;
	} else {
	    eventPtr->xkey.keycode = 0x00FF & keysym;
	}
	eventPtr->xkey.keycode |= (macKeycode & MAC_KEYCODE_MASK) << 16;








	if (shiftKey & macKeycode) {
	    eventPtr->xkey.state |= ShiftMask;
	}
	if (optionKey & macKeycode) {

	    eventPtr->xkey.state |= OPTION_MASK;
	}

	if (keysym <= LATIN1_MAX) {
	    int done = Tcl_UniCharToUtf(keysym, eventPtr->xkey.trans_chars);

	    eventPtr->xkey.trans_chars[done] = 0;
	} else {
	    eventPtr->xkey.trans_chars[0] = 0;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --
 *

 *	Given an X KeyPress or KeyRelease event, map the keycode in the event
 *	into a keysym.
 *
 * Results:
 *	The return value is the keysym corresponding to eventPtr, or NoSymbol
 *	if no matching keysym could be found.
 *
 * Side effects:
 *	In the first call for a given display, keycode-to-keysym maps get
 *	loaded.
 *
 *----------------------------------------------------------------------
 */

KeySym
TkpGetKeySym(
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;



    /*
     * Refresh the mapping information if it's stale.
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);
    }

    /*
     * Handle pure modifier keys specially. We use -1 as a signal for
     * this.
     */

    if (eventPtr->xany.send_event == -1) {

	int modifier = eventPtr->xkey.keycode & NSDeviceIndependentModifierFlagsMask;

	if (modifier == NSCommandKeyMask) {
	    return XK_Meta_L;
	} else if (modifier == NSShiftKeyMask) {
	    return XK_Shift_L;
	} else if (modifier == NSAlphaShiftKeyMask) {
	    return XK_Caps_Lock;
	} else if (modifier == NSAlternateKeyMask) {
	    return XK_Alt_L;
	} else if (modifier == NSControlKeyMask) {
	    return XK_Control_L;
	} else if (modifier == NSNumericPadKeyMask) {
	    return XK_Num_Lock;
	} else if (modifier == NSFunctionKeyMask) {
	    return XK_Super_L;
/*
	} else if (modifier == rightShiftKey) {
	    return XK_Shift_R;
	} else if (modifier == rightOptionKey) {
	    return XK_Alt_R;
	} else if (modifier == rightControlKey) {
	    return XK_Control_R;
*/
	} else {
	    /*
	     * If we get here, we probably need to implement something new.
	     */


	    return NoSymbol;
	}
    }

    /* If nbytes has been set, it's not a function key, but a regular key that
       has been translated in tkMacOSXKeyEvent.c; just use that. */
    if (eventPtr->xkey.nbytes) {
      return eventPtr->xkey.keycode & 0xFFFF;
    }

    /*
     * Figure out which of the four slots in the keymap vector to use for this
     * key. Refer to Xlib documentation for more info on how this computation
     * works. (Note: We use "Option" in keymap columns 2 and 3 where other
     * implementations have "Mode_switch".)
     */

    index = 0;

    /*
     * We want Option key combinations to use their base chars as keysyms, so
     * we ignore the option modifier here.
     */

#if 0
    if (eventPtr->xkey.state & OPTION_MASK) {
	index |= 2;
    }
#endif

    if ((eventPtr->xkey.state & ShiftMask)
	    || (/* (dispPtr->lockUsage != LU_IGNORE)
	    && */ (eventPtr->xkey.state & LockMask))) {
	index |= 1;
    }

    /*
     * First try of the actual translation.
     */

    sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, index);

    /*
     * Special handling: If the key was shifted because of Lock, but lock is
     * only caps lock, not shift lock, and the shifted keysym isn't upper-case
     * alphabetic, then switch back to the unshifted keysym.
     */

    if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
	    /*&& (dispPtr->lockUsage == LU_CAPS)*/ ) {
	/*
	 * FIXME: Keysyms are only identical to Unicode for ASCII and Latin-1,
	 * so we can't use Tcl_UniCharIsUpper() for keysyms outside that range.
	 * This may be a serious problem here.
	 */

	if ((sym == NoSymbol) || (sym > LATIN1_MAX)
		|| !Tcl_UniCharIsUpper(sym)) {
	    index &= ~1;
	    sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
		    index);
	}
    }

    /*
     * Another bit of special handling: If this is a shifted key and there is
     * no keysym defined, then use the keysym for the unshifted key.
     */

    if ((index & 1) && (sym == NoSymbol)) {
	sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
		index & ~1);
    }
    return sym;
}

/*
 *--------------------------------------------------------------
 *
 * TkpInitKeymapInfo --
 *
 *	This procedure is invoked to scan keymap information to recompute stuff
 *	that's important for binding, such as the modifier key (if any) that
 *	corresponds to the "Mode_switch" keysym.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Keymap-related information in dispPtr is updated.
 *
 *--------------------------------------------------------------
 */

void
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    dispPtr->bindInfoStale = 0;

    /*
     * Behaviours that are variable on X11 are defined constant on MacOSX.
     * lockUsage is only used above in TkpGetKeySym(), nowhere else currently.


     * There is no offical "Mode_switch" key.
     */

    dispPtr->lockUsage = LU_CAPS;



    dispPtr->modeModMask = 0;

#if 0
    /*
     * With this, <Alt> and <Meta> become synonyms for <Command> and <Option>
     * in bindings like they are (and always have been) in the keysyms that
     * are reported by KeyPress events. But the init scripts like text.tcl
     * have some disabling bindings for <Meta>, so we don't want this without
     * some changes in those scripts. See also bug #700311.
     */

    dispPtr->altModMask = OPTION_MASK;
    dispPtr->metaModMask = COMMAND_MASK;
#else
    dispPtr->altModMask = 0;
    dispPtr->metaModMask = 0;
#endif

    /*
     * MacOSX doesn't use the keycodes for the modifiers for anything, and we
     * don't generate them either (the keycodes actually given in the simulated
     * modifier events are bogus). So there is no modifier map. If we ever want
     * to simulate real modifier keycodes, the list will be constant in the
     * Carbon implementation.
     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree((char *) dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = 0;


    dispPtr->modKeyCodes = NULL;
}















































/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Deleted macosx/tkMacOSXKeysyms.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
/*
 * tkMacOSXKeysyms.h --
 *
 *      Contains data used for processing key events, some of which was
 *      moved from tkMacOSXKeyboard.c.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef TKMACOSXKEYSYMS_H
#define TKMACOSXKEYSYMS_H 1

/*
 * This table enumerates the keys on Mac keyboards which do not represent
 * letters.  This is static data -- these keys do not change when the keyboard
 * layout changes.  The unicode representation of a special key which is not a
 * modifier and does not have an ASCII code point lies in the reserved range
 * 0xF700 - 0xF8FF.
 *
 * The table includes every key listed in Apple's documentation of Function-Key
 * Unicodes which is not marked as "Not on most Macintosh keyboards", as well
 * as F20, which is reported to be usable in scripts even though it does not
 * appear on any Macintosh keyboard.
 */

typedef struct {
    int virtual;	/* value of [NSEvent keyCode] */
    KeySym keysym;	/* X11 keysym */
    KeyCode keychar;	/* XEvent keycode & 0xFFFF */
} KeyInfo;

static const KeyInfo keyArray[] = {
    {36,	XK_Return,	NSNewlineCharacter},
    {48,	XK_Tab,		NSTabCharacter},
    {51,	XK_BackSpace,	NSDeleteCharacter},
    {52,	XK_Return,	NSNewlineCharacter},  /* Used on some Powerbooks */
    {53,	XK_Escape,	0x1B},
    {54,	XK_Meta_R,      MOD_KEYCHAR},
    {55,	XK_Meta_L,	MOD_KEYCHAR},
    {56,	XK_Shift_L,	MOD_KEYCHAR},
    {57,	XK_Caps_Lock,   MOD_KEYCHAR},
    {58,	XK_Alt_L,	MOD_KEYCHAR},
    {59,	XK_Control_L,	MOD_KEYCHAR},
    {60,	XK_Shift_R, 	MOD_KEYCHAR},
    {61,	XK_Alt_R,	MOD_KEYCHAR},
    {62,	XK_Control_R,	MOD_KEYCHAR},
    {63,	XK_Super_L,	MOD_KEYCHAR},
    {64,	XK_F17,		NSF17FunctionKey},
    {65,	XK_KP_Decimal,	'.'},
    {67,	XK_KP_Multiply, '*'},
    {69,	XK_KP_Add,	'+'},
    {71,	XK_Clear,       NSClearLineFunctionKey}, /* Numlock on PC */
    {75,	XK_KP_Divide,   '/'},
    {76,	XK_KP_Enter,	NSEnterCharacter},       /* Fn Return */
    {78,	XK_KP_Subtract, '-'},
    {79,	XK_F18,		NSF18FunctionKey},
    {80,	XK_F19,		NSF19FunctionKey},
    {81,	XK_KP_Equal,	'='},
    {82,	XK_KP_0,	'0'},
    {83,	XK_KP_1,	'1'},
    {84,	XK_KP_2,	'2'},
    {85,	XK_KP_3,	'3'},
    {86,	XK_KP_4,	'4'},
    {87,	XK_KP_5,	'5'},
    {88,	XK_KP_6,	'6'},
    {89,	XK_KP_7,	'7'},
    {90,	XK_F20,		NSF20FunctionKey}, /* For scripting only */
    {91,	XK_KP_8,	'8'},
    {92,	XK_KP_9,	'9'},
    {96,	XK_F5,		NSF5FunctionKey},
    {97,	XK_F6,		NSF6FunctionKey},
    {98,	XK_F7,		NSF7FunctionKey},
    {99,	XK_F3,		NSF3FunctionKey},
    {100,	XK_F8,		NSF8FunctionKey},
    {101,	XK_F9,		NSF9FunctionKey},
    {103,	XK_F11,		NSF11FunctionKey},
    {105,	XK_F13,		NSF13FunctionKey},
    {106,	XK_F16,		NSF16FunctionKey},
    {107,	XK_F14,		NSF14FunctionKey},
    {109,	XK_F10,		NSF10FunctionKey},
    {110,       XK_Menu,	UNKNOWN_KEYCHAR},
    {111,	XK_F12,		NSF12FunctionKey},
    {113,	XK_F15,		NSF15FunctionKey},
    {114,	XK_Help,	NSHelpFunctionKey},
    {115,	XK_Home,	NSHomeFunctionKey},     /* Fn Left */
    {116,	XK_Page_Up,	NSPageUpFunctionKey},   /* Fn Up */
    {117,	XK_Delete,	NSDeleteFunctionKey},   /* Fn Delete */
    {118,	XK_F4,		NSF4FunctionKey},
    {119,	XK_End,		NSEndFunctionKey},      /* Fn Right */
    {120,	XK_F2,		NSF2FunctionKey},
    {121,	XK_Page_Down,	NSPageDownFunctionKey}, /* Fn Down */
    {122,	XK_F1,		NSF1FunctionKey},
    {123,	XK_Left,	NSLeftArrowFunctionKey},
    {124,	XK_Right,	NSRightArrowFunctionKey},
    {125,	XK_Down,	NSDownArrowFunctionKey},
    {126,	XK_Up,		NSUpArrowFunctionKey},
    {0, 0, 0}
};

/*
 * X11 keysyms for modifier keys, in order.  This list includes keys
 * which do not appear on Apple keyboards, such as Shift_Lock and
 * Super_R.  While most systems don't provide events for the "fn"
 * function key, Apple does.  We map it to Super_L when processing a
 * FlagsChanged NSEvent.
 */

#define NUM_MOD_KEYCODES 14
static const KeyCode modKeyArray[NUM_MOD_KEYCODES] = {
    XK_Shift_L,
    XK_Shift_R,
    XK_Control_L,
    XK_Control_R,
    XK_Caps_Lock,
    XK_Shift_Lock,
    XK_Meta_L,
    XK_Meta_R,
    XK_Alt_L,
    XK_Alt_R,
    XK_Super_L,
    XK_Super_R,
    XK_Hyper_L,
    XK_Hyper_R,
};

/*
 * This table pairs X11 Keysyms for alphanumeric characters with the
 * unicode code point for that letter.
 * The data comes from http://www.cl.cam.ac.uk/~mgk25/ucs/keysyms.txt
 */

typedef struct KeysymInfo {
    KeySym keysym;
    KeyCode keycode;
} KeysymInfo;

const KeysymInfo keysymTable[] = {
    {0x0020, 0x0020}, /* space */
    {0x0021, 0x0021}, /* exclam */
    {0x0022, 0x0022}, /* quotedbl */
    {0x0023, 0x0023}, /* numbersign */
    {0x0024, 0x0024}, /* dollar */
    {0x0025, 0x0025}, /* percent */
    {0x0026, 0x0026}, /* ampersand */
    {0x0027, 0x0027}, /* apostrophe */
    {0x0028, 0x0028}, /* parenleft */
    {0x0029, 0x0029}, /* parenright */
    {0x002a, 0x002a}, /* asterisk */
    {0x002b, 0x002b}, /* plus */
    {0x002c, 0x002c}, /* comma */
    {0x002d, 0x002d}, /* minus */
    {0x002e, 0x002e}, /* period */
    {0x002f, 0x002f}, /* slash */
    {0x0030, 0x0030}, /* 0 */
    {0x0031, 0x0031}, /* 1 */
    {0x0032, 0x0032}, /* 2 */
    {0x0033, 0x0033}, /* 3 */
    {0x0034, 0x0034}, /* 4 */
    {0x0035, 0x0035}, /* 5 */
    {0x0036, 0x0036}, /* 6 */
    {0x0037, 0x0037}, /* 7 */
    {0x0038, 0x0038}, /* 8 */
    {0x0039, 0x0039}, /* 9 */
    {0x003a, 0x003a}, /* colon */
    {0x003b, 0x003b}, /* semicolon */
    {0x003c, 0x003c}, /* less */
    {0x003d, 0x003d}, /* equal */
    {0x003e, 0x003e}, /* greater */
    {0x003f, 0x003f}, /* question */
    {0x0040, 0x0040}, /* at */
    {0x0041, 0x0041}, /* A */
    {0x0042, 0x0042}, /* B */
    {0x0043, 0x0043}, /* C */
    {0x0044, 0x0044}, /* D */
    {0x0045, 0x0045}, /* E */
    {0x0046, 0x0046}, /* F */
    {0x0047, 0x0047}, /* G */
    {0x0048, 0x0048}, /* H */
    {0x0049, 0x0049}, /* I */
    {0x004a, 0x004a}, /* J */
    {0x004b, 0x004b}, /* K */
    {0x004c, 0x004c}, /* L */
    {0x004d, 0x004d}, /* M */
    {0x004e, 0x004e}, /* N */
    {0x004f, 0x004f}, /* O */
    {0x0050, 0x0050}, /* P */
    {0x0051, 0x0051}, /* Q */
    {0x0052, 0x0052}, /* R */
    {0x0053, 0x0053}, /* S */
    {0x0054, 0x0054}, /* T */
    {0x0055, 0x0055}, /* U */
    {0x0056, 0x0056}, /* V */
    {0x0057, 0x0057}, /* W */
    {0x0058, 0x0058}, /* X */
    {0x0059, 0x0059}, /* Y */
    {0x005a, 0x005a}, /* Z */
    {0x005b, 0x005b}, /* bracketleft */
    {0x005c, 0x005c}, /* backslash */
    {0x005d, 0x005d}, /* bracketright */
    {0x005e, 0x005e}, /* asciicircum */
    {0x005f, 0x005f}, /* underscore */
    {0x0060, 0x0060}, /* grave */
    {0x0061, 0x0061}, /* a */
    {0x0062, 0x0062}, /* b */
    {0x0063, 0x0063}, /* c */
    {0x0064, 0x0064}, /* d */
    {0x0065, 0x0065}, /* e */
    {0x0066, 0x0066}, /* f */
    {0x0067, 0x0067}, /* g */
    {0x0068, 0x0068}, /* h */
    {0x0069, 0x0069}, /* i */
    {0x006a, 0x006a}, /* j */
    {0x006b, 0x006b}, /* k */
    {0x006c, 0x006c}, /* l */
    {0x006d, 0x006d}, /* m */
    {0x006e, 0x006e}, /* n */
    {0x006f, 0x006f}, /* o */
    {0x0070, 0x0070}, /* p */
    {0x0071, 0x0071}, /* q */
    {0x0072, 0x0072}, /* r */
    {0x0073, 0x0073}, /* s */
    {0x0074, 0x0074}, /* t */
    {0x0075, 0x0075}, /* u */
    {0x0076, 0x0076}, /* v */
    {0x0077, 0x0077}, /* w */
    {0x0078, 0x0078}, /* x */
    {0x0079, 0x0079}, /* y */
    {0x007a, 0x007a}, /* z */
    {0x007b, 0x007b}, /* braceleft */
    {0x007c, 0x007c}, /* bar */
    {0x007d, 0x007d}, /* braceright */
    {0x007e, 0x007e}, /* asciitilde */
    {0x00a0, 0x00a0}, /* nobreakspace */
    {0x00a1, 0x00a1}, /* exclamdown */
    {0x00a2, 0x00a2}, /* cent */
    {0x00a3, 0x00a3}, /* sterling */
    {0x00a4, 0x00a4}, /* currency */
    {0x00a5, 0x00a5}, /* yen */
    {0x00a6, 0x00a6}, /* brokenbar */
    {0x00a7, 0x00a7}, /* section */
    {0x00a8, 0x00a8}, /* diaeresis */
    {0x00a9, 0x00a9}, /* copyright */
    {0x00aa, 0x00aa}, /* ordfeminine */
    {0x00ab, 0x00ab}, /* guillemotleft */
    {0x00ac, 0x00ac}, /* notsign */
    {0x00ad, 0x00ad}, /* hyphen */
    {0x00ae, 0x00ae}, /* registered */
    {0x00af, 0x00af}, /* macron */
    {0x00b0, 0x00b0}, /* degree */
    {0x00b1, 0x00b1}, /* plusminus */
    {0x00b2, 0x00b2}, /* twosuperior */
    {0x00b3, 0x00b3}, /* threesuperior */
    {0x00b4, 0x00b4}, /* acute */
    {0x00b5, 0x00b5}, /* mu */
    {0x00b6, 0x00b6}, /* paragraph */
    {0x00b7, 0x00b7}, /* periodcentered */
    {0x00b8, 0x00b8}, /* cedilla */
    {0x00b9, 0x00b9}, /* onesuperior */
    {0x00ba, 0x00ba}, /* masculine */
    {0x00bb, 0x00bb}, /* guillemotright */
    {0x00bc, 0x00bc}, /* onequarter */
    {0x00bd, 0x00bd}, /* onehalf */
    {0x00be, 0x00be}, /* threequarters */
    {0x00bf, 0x00bf}, /* questiondown */
    {0x00c0, 0x00c0}, /* Agrave */
    {0x00c1, 0x00c1}, /* Aacute */
    {0x00c2, 0x00c2}, /* Acircumflex */
    {0x00c3, 0x00c3}, /* Atilde */
    {0x00c4, 0x00c4}, /* Adiaeresis */
    {0x00c5, 0x00c5}, /* Aring */
    {0x00c6, 0x00c6}, /* AE */
    {0x00c7, 0x00c7}, /* Ccedilla */
    {0x00c8, 0x00c8}, /* Egrave */
    {0x00c9, 0x00c9}, /* Eacute */
    {0x00ca, 0x00ca}, /* Ecircumflex */
    {0x00cb, 0x00cb}, /* Ediaeresis */
    {0x00cc, 0x00cc}, /* Igrave */
    {0x00cd, 0x00cd}, /* Iacute */
    {0x00ce, 0x00ce}, /* Icircumflex */
    {0x00cf, 0x00cf}, /* Idiaeresis */
    {0x00d0, 0x00d0}, /* ETH */
    {0x00d1, 0x00d1}, /* Ntilde */
    {0x00d2, 0x00d2}, /* Ograve */
    {0x00d3, 0x00d3}, /* Oacute */
    {0x00d4, 0x00d4}, /* Ocircumflex */
    {0x00d5, 0x00d5}, /* Otilde */
    {0x00d6, 0x00d6}, /* Odiaeresis */
    {0x00d7, 0x00d7}, /* multiply */
    {0x00d8, 0x00d8}, /* Oslash */
    {0x00d9, 0x00d9}, /* Ugrave */
    {0x00da, 0x00da}, /* Uacute */
    {0x00db, 0x00db}, /* Ucircumflex */
    {0x00dc, 0x00dc}, /* Udiaeresis */
    {0x00dd, 0x00dd}, /* Yacute */
    {0x00de, 0x00de}, /* THORN */
    {0x00df, 0x00df}, /* ssharp */
    {0x00e0, 0x00e0}, /* agrave */
    {0x00e1, 0x00e1}, /* aacute */
    {0x00e2, 0x00e2}, /* acircumflex */
    {0x00e3, 0x00e3}, /* atilde */
    {0x00e4, 0x00e4}, /* adiaeresis */
    {0x00e5, 0x00e5}, /* aring */
    {0x00e6, 0x00e6}, /* ae */
    {0x00e7, 0x00e7}, /* ccedilla */
    {0x00e8, 0x00e8}, /* egrave */
    {0x00e9, 0x00e9}, /* eacute */
    {0x00ea, 0x00ea}, /* ecircumflex */
    {0x00eb, 0x00eb}, /* ediaeresis */
    {0x00ec, 0x00ec}, /* igrave */
    {0x00ed, 0x00ed}, /* iacute */
    {0x00ee, 0x00ee}, /* icircumflex */
    {0x00ef, 0x00ef}, /* idiaeresis */
    {0x00f0, 0x00f0}, /* eth */
    {0x00f1, 0x00f1}, /* ntilde */
    {0x00f2, 0x00f2}, /* ograve */
    {0x00f3, 0x00f3}, /* oacute */
    {0x00f4, 0x00f4}, /* ocircumflex */
    {0x00f5, 0x00f5}, /* otilde */
    {0x00f6, 0x00f6}, /* odiaeresis */
    {0x00f7, 0x00f7}, /* division */
    {0x00f8, 0x00f8}, /* oslash */
    {0x00f9, 0x00f9}, /* ugrave */
    {0x00fa, 0x00fa}, /* uacute */
    {0x00fb, 0x00fb}, /* ucircumflex */
    {0x00fc, 0x00fc}, /* udiaeresis */
    {0x00fd, 0x00fd}, /* yacute */
    {0x00fe, 0x00fe}, /* thorn */
    {0x00ff, 0x00ff}, /* ydiaeresis */
    {0x01a1, 0x0104}, /* Aogonek */
    {0x01a2, 0x02d8}, /* breve */
    {0x01a3, 0x0141}, /* Lstroke */
    {0x01a5, 0x013d}, /* Lcaron */
    {0x01a6, 0x015a}, /* Sacute */
    {0x01a9, 0x0160}, /* Scaron */
    {0x01aa, 0x015e}, /* Scedilla */
    {0x01ab, 0x0164}, /* Tcaron */
    {0x01ac, 0x0179}, /* Zacute */
    {0x01ae, 0x017d}, /* Zcaron */
    {0x01af, 0x017b}, /* Zabovedot */
    {0x01b1, 0x0105}, /* aogonek */
    {0x01b2, 0x02db}, /* ogonek */
    {0x01b3, 0x0142}, /* lstroke */
    {0x01b5, 0x013e}, /* lcaron */
    {0x01b6, 0x015b}, /* sacute */
    {0x01b7, 0x02c7}, /* caron */
    {0x01b9, 0x0161}, /* scaron */
    {0x01ba, 0x015f}, /* scedilla */
    {0x01bb, 0x0165}, /* tcaron */
    {0x01bc, 0x017a}, /* zacute */
    {0x01bd, 0x02dd}, /* doubleacute */
    {0x01be, 0x017e}, /* zcaron */
    {0x01bf, 0x017c}, /* zabovedot */
    {0x01c0, 0x0154}, /* Racute */
    {0x01c3, 0x0102}, /* Abreve */
    {0x01c5, 0x0139}, /* Lacute */
    {0x01c6, 0x0106}, /* Cacute */
    {0x01c8, 0x010c}, /* Ccaron */
    {0x01ca, 0x0118}, /* Eogonek */
    {0x01cc, 0x011a}, /* Ecaron */
    {0x01cf, 0x010e}, /* Dcaron */
    {0x01d0, 0x0110}, /* Dstroke */
    {0x01d1, 0x0143}, /* Nacute */
    {0x01d2, 0x0147}, /* Ncaron */
    {0x01d5, 0x0150}, /* Odoubleacute */
    {0x01d8, 0x0158}, /* Rcaron */
    {0x01d9, 0x016e}, /* Uring */
    {0x01db, 0x0170}, /* Udoubleacute */
    {0x01de, 0x0162}, /* Tcedilla */
    {0x01e0, 0x0155}, /* racute */
    {0x01e3, 0x0103}, /* abreve */
    {0x01e5, 0x013a}, /* lacute */
    {0x01e6, 0x0107}, /* cacute */
    {0x01e8, 0x010d}, /* ccaron */
    {0x01ea, 0x0119}, /* eogonek */
    {0x01ec, 0x011b}, /* ecaron */
    {0x01ef, 0x010f}, /* dcaron */
    {0x01f0, 0x0111}, /* dstroke */
    {0x01f1, 0x0144}, /* nacute */
    {0x01f2, 0x0148}, /* ncaron */
    {0x01f5, 0x0151}, /* odoubleacute */
    {0x01f8, 0x0159}, /* rcaron */
    {0x01f9, 0x016f}, /* uring */
    {0x01fb, 0x0171}, /* udoubleacute */
    {0x01fe, 0x0163}, /* tcedilla */
    {0x01ff, 0x02d9}, /* abovedot */
    {0x02a1, 0x0126}, /* Hstroke */
    {0x02a6, 0x0124}, /* Hcircumflex */
    {0x02a9, 0x0130}, /* Iabovedot */
    {0x02ab, 0x011e}, /* Gbreve */
    {0x02ac, 0x0134}, /* Jcircumflex */
    {0x02b1, 0x0127}, /* hstroke */
    {0x02b6, 0x0125}, /* hcircumflex */
    {0x02b9, 0x0131}, /* idotless */
    {0x02bb, 0x011f}, /* gbreve */
    {0x02bc, 0x0135}, /* jcircumflex */
    {0x02c5, 0x010a}, /* Cabovedot */
    {0x02c6, 0x0108}, /* Ccircumflex */
    {0x02d5, 0x0120}, /* Gabovedot */
    {0x02d8, 0x011c}, /* Gcircumflex */
    {0x02dd, 0x016c}, /* Ubreve */
    {0x02de, 0x015c}, /* Scircumflex */
    {0x02e5, 0x010b}, /* cabovedot */
    {0x02e6, 0x0109}, /* ccircumflex */
    {0x02f5, 0x0121}, /* gabovedot */
    {0x02f8, 0x011d}, /* gcircumflex */
    {0x02fd, 0x016d}, /* ubreve */
    {0x02fe, 0x015d}, /* scircumflex */
    {0x03a2, 0x0138}, /* kra */
    {0x03a3, 0x0156}, /* Rcedilla */
    {0x03a5, 0x0128}, /* Itilde */
    {0x03a6, 0x013b}, /* Lcedilla */
    {0x03aa, 0x0112}, /* Emacron */
    {0x03ab, 0x0122}, /* Gcedilla */
    {0x03ac, 0x0166}, /* Tslash */
    {0x03b3, 0x0157}, /* rcedilla */
    {0x03b5, 0x0129}, /* itilde */
    {0x03b6, 0x013c}, /* lcedilla */
    {0x03ba, 0x0113}, /* emacron */
    {0x03bb, 0x0123}, /* gcedilla */
    {0x03bc, 0x0167}, /* tslash */
    {0x03bd, 0x014a}, /* ENG */
    {0x03bf, 0x014b}, /* eng */
    {0x03c0, 0x0100}, /* Amacron */
    {0x03c7, 0x012e}, /* Iogonek */
    {0x03cc, 0x0116}, /* Eabovedot */
    {0x03cf, 0x012a}, /* Imacron */
    {0x03d1, 0x0145}, /* Ncedilla */
    {0x03d2, 0x014c}, /* Omacron */
    {0x03d3, 0x0136}, /* Kcedilla */
    {0x03d9, 0x0172}, /* Uogonek */
    {0x03dd, 0x0168}, /* Utilde */
    {0x03de, 0x016a}, /* Umacron */
    {0x03e0, 0x0101}, /* amacron */
    {0x03e7, 0x012f}, /* iogonek */
    {0x03ec, 0x0117}, /* eabovedot */
    {0x03ef, 0x012b}, /* imacron */
    {0x03f1, 0x0146}, /* ncedilla */
    {0x03f2, 0x014d}, /* omacron */
    {0x03f3, 0x0137}, /* kcedilla */
    {0x03f9, 0x0173}, /* uogonek */
    {0x03fd, 0x0169}, /* utilde */
    {0x03fe, 0x016b}, /* umacron */
    {0x047e, 0x203e}, /* overline */
    {0x04a1, 0x3002}, /* kana_fullstop */
    {0x04a2, 0x300c}, /* kana_openingbracket */
    {0x04a3, 0x300d}, /* kana_closingbracket */
    {0x04a4, 0x3001}, /* kana_comma */
    {0x04a5, 0x30fb}, /* kana_conjunctive */
    {0x04a6, 0x30f2}, /* kana_WO */
    {0x04a7, 0x30a1}, /* kana_a */
    {0x04a8, 0x30a3}, /* kana_i */
    {0x04a9, 0x30a5}, /* kana_u */
    {0x04aa, 0x30a7}, /* kana_e */
    {0x04ab, 0x30a9}, /* kana_o */
    {0x04ac, 0x30e3}, /* kana_ya */
    {0x04ad, 0x30e5}, /* kana_yu */
    {0x04ae, 0x30e7}, /* kana_yo */
    {0x04af, 0x30c3}, /* kana_tsu */
    {0x04b0, 0x30fc}, /* prolongedsound */
    {0x04b1, 0x30a2}, /* kana_A */
    {0x04b2, 0x30a4}, /* kana_I */
    {0x04b3, 0x30a6}, /* kana_U */
    {0x04b4, 0x30a8}, /* kana_E */
    {0x04b5, 0x30aa}, /* kana_O */
    {0x04b6, 0x30ab}, /* kana_KA */
    {0x04b7, 0x30ad}, /* kana_KI */
    {0x04b8, 0x30af}, /* kana_KU */
    {0x04b9, 0x30b1}, /* kana_KE */
    {0x04ba, 0x30b3}, /* kana_KO */
    {0x04bb, 0x30b5}, /* kana_SA */
    {0x04bc, 0x30b7}, /* kana_SHI */
    {0x04bd, 0x30b9}, /* kana_SU */
    {0x04be, 0x30bb}, /* kana_SE */
    {0x04bf, 0x30bd}, /* kana_SO */
    {0x04c0, 0x30bf}, /* kana_TA */
    {0x04c1, 0x30c1}, /* kana_CHI */
    {0x04c2, 0x30c4}, /* kana_TSU */
    {0x04c3, 0x30c6}, /* kana_TE */
    {0x04c4, 0x30c8}, /* kana_TO */
    {0x04c5, 0x30ca}, /* kana_NA */
    {0x04c6, 0x30cb}, /* kana_NI */
    {0x04c7, 0x30cc}, /* kana_NU */
    {0x04c8, 0x30cd}, /* kana_NE */
    {0x04c9, 0x30ce}, /* kana_NO */
    {0x04ca, 0x30cf}, /* kana_HA */
    {0x04cb, 0x30d2}, /* kana_HI */
    {0x04cc, 0x30d5}, /* kana_FU */
    {0x04cd, 0x30d8}, /* kana_HE */
    {0x04ce, 0x30db}, /* kana_HO */
    {0x04cf, 0x30de}, /* kana_MA */
    {0x04d0, 0x30df}, /* kana_MI */
    {0x04d1, 0x30e0}, /* kana_MU */
    {0x04d2, 0x30e1}, /* kana_ME */
    {0x04d3, 0x30e2}, /* kana_MO */
    {0x04d4, 0x30e4}, /* kana_YA */
    {0x04d5, 0x30e6}, /* kana_YU */
    {0x04d6, 0x30e8}, /* kana_YO */
    {0x04d7, 0x30e9}, /* kana_RA */
    {0x04d8, 0x30ea}, /* kana_RI */
    {0x04d9, 0x30eb}, /* kana_RU */
    {0x04da, 0x30ec}, /* kana_RE */
    {0x04db, 0x30ed}, /* kana_RO */
    {0x04dc, 0x30ef}, /* kana_WA */
    {0x04dd, 0x30f3}, /* kana_N */
    {0x04de, 0x309b}, /* voicedsound */
    {0x04df, 0x309c}, /* semivoicedsound */
    {0x05ac, 0x060c}, /* Arabic_comma */
    {0x05bb, 0x061b}, /* Arabic_semicolon */
    {0x05bf, 0x061f}, /* Arabic_question_mark */
    {0x05c1, 0x0621}, /* Arabic_hamza */
    {0x05c2, 0x0622}, /* Arabic_maddaonalef */
    {0x05c3, 0x0623}, /* Arabic_hamzaonalef */
    {0x05c4, 0x0624}, /* Arabic_hamzaonwaw */
    {0x05c5, 0x0625}, /* Arabic_hamzaunderalef */
    {0x05c6, 0x0626}, /* Arabic_hamzaonyeh */
    {0x05c7, 0x0627}, /* Arabic_alef */
    {0x05c8, 0x0628}, /* Arabic_beh */
    {0x05c9, 0x0629}, /* Arabic_tehmarbuta */
    {0x05ca, 0x062a}, /* Arabic_teh */
    {0x05cb, 0x062b}, /* Arabic_theh */
    {0x05cc, 0x062c}, /* Arabic_jeem */
    {0x05cd, 0x062d}, /* Arabic_hah */
    {0x05ce, 0x062e}, /* Arabic_khah */
    {0x05cf, 0x062f}, /* Arabic_dal */
    {0x05d0, 0x0630}, /* Arabic_thal */
    {0x05d1, 0x0631}, /* Arabic_ra */
    {0x05d2, 0x0632}, /* Arabic_zain */
    {0x05d3, 0x0633}, /* Arabic_seen */
    {0x05d4, 0x0634}, /* Arabic_sheen */
    {0x05d5, 0x0635}, /* Arabic_sad */
    {0x05d6, 0x0636}, /* Arabic_dad */
    {0x05d7, 0x0637}, /* Arabic_tah */
    {0x05d8, 0x0638}, /* Arabic_zah */
    {0x05d9, 0x0639}, /* Arabic_ain */
    {0x05da, 0x063a}, /* Arabic_ghain */
    {0x05e0, 0x0640}, /* Arabic_tatweel */
    {0x05e1, 0x0641}, /* Arabic_feh */
    {0x05e2, 0x0642}, /* Arabic_qaf */
    {0x05e3, 0x0643}, /* Arabic_kaf */
    {0x05e4, 0x0644}, /* Arabic_lam */
    {0x05e5, 0x0645}, /* Arabic_meem */
    {0x05e6, 0x0646}, /* Arabic_noon */
    {0x05e7, 0x0647}, /* Arabic_ha */
    {0x05e8, 0x0648}, /* Arabic_waw */
    {0x05e9, 0x0649}, /* Arabic_alefmaksura */
    {0x05ea, 0x064a}, /* Arabic_yeh */
    {0x05eb, 0x064b}, /* Arabic_fathatan */
    {0x05ec, 0x064c}, /* Arabic_dammatan */
    {0x05ed, 0x064d}, /* Arabic_kasratan */
    {0x05ee, 0x064e}, /* Arabic_fatha */
    {0x05ef, 0x064f}, /* Arabic_damma */
    {0x05f0, 0x0650}, /* Arabic_kasra */
    {0x05f1, 0x0651}, /* Arabic_shadda */
    {0x05f2, 0x0652}, /* Arabic_sukun */
    {0x06a1, 0x0452}, /* Serbian_dje */
    {0x06a2, 0x0453}, /* Macedonia_gje */
    {0x06a3, 0x0451}, /* Cyrillic_io */
    {0x06a4, 0x0454}, /* Ukrainian_ie */
    {0x06a5, 0x0455}, /* Macedonia_dse */
    {0x06a6, 0x0456}, /* Ukrainian_i */
    {0x06a7, 0x0457}, /* Ukrainian_yi */
    {0x06a8, 0x0458}, /* Cyrillic_je */
    {0x06a9, 0x0459}, /* Cyrillic_lje */
    {0x06aa, 0x045a}, /* Cyrillic_nje */
    {0x06ab, 0x045b}, /* Serbian_tshe */
    {0x06ac, 0x045c}, /* Macedonia_kje */
    {0x06ae, 0x045e}, /* Byelorussian_shortu */
    {0x06af, 0x045f}, /* Cyrillic_dzhe */
    {0x06b0, 0x2116}, /* numerosign */
    {0x06b1, 0x0402}, /* Serbian_DJE */
    {0x06b2, 0x0403}, /* Macedonia_GJE */
    {0x06b3, 0x0401}, /* Cyrillic_IO */
    {0x06b4, 0x0404}, /* Ukrainian_IE */
    {0x06b5, 0x0405}, /* Macedonia_DSE */
    {0x06b6, 0x0406}, /* Ukrainian_I */
    {0x06b7, 0x0407}, /* Ukrainian_YI */
    {0x06b8, 0x0408}, /* Cyrillic_JE */
    {0x06b9, 0x0409}, /* Cyrillic_LJE */
    {0x06ba, 0x040a}, /* Cyrillic_NJE */
    {0x06bb, 0x040b}, /* Serbian_TSHE */
    {0x06bc, 0x040c}, /* Macedonia_KJE */
    {0x06be, 0x040e}, /* Byelorussian_SHORTU */
    {0x06bf, 0x040f}, /* Cyrillic_DZHE */
    {0x06c0, 0x044e}, /* Cyrillic_yu */
    {0x06c1, 0x0430}, /* Cyrillic_a */
    {0x06c2, 0x0431}, /* Cyrillic_be */
    {0x06c3, 0x0446}, /* Cyrillic_tse */
    {0x06c4, 0x0434}, /* Cyrillic_de */
    {0x06c5, 0x0435}, /* Cyrillic_ie */
    {0x06c6, 0x0444}, /* Cyrillic_ef */
    {0x06c7, 0x0433}, /* Cyrillic_ghe */
    {0x06c8, 0x0445}, /* Cyrillic_ha */
    {0x06c9, 0x0438}, /* Cyrillic_i */
    {0x06ca, 0x0439}, /* Cyrillic_shorti */
    {0x06cb, 0x043a}, /* Cyrillic_ka */
    {0x06cc, 0x043b}, /* Cyrillic_el */
    {0x06cd, 0x043c}, /* Cyrillic_em */
    {0x06ce, 0x043d}, /* Cyrillic_en */
    {0x06cf, 0x043e}, /* Cyrillic_o */
    {0x06d0, 0x043f}, /* Cyrillic_pe */
    {0x06d1, 0x044f}, /* Cyrillic_ya */
    {0x06d2, 0x0440}, /* Cyrillic_er */
    {0x06d3, 0x0441}, /* Cyrillic_es */
    {0x06d4, 0x0442}, /* Cyrillic_te */
    {0x06d5, 0x0443}, /* Cyrillic_u */
    {0x06d6, 0x0436}, /* Cyrillic_zhe */
    {0x06d7, 0x0432}, /* Cyrillic_ve */
    {0x06d8, 0x044c}, /* Cyrillic_softsign */
    {0x06d9, 0x044b}, /* Cyrillic_yeru */
    {0x06da, 0x0437}, /* Cyrillic_ze */
    {0x06db, 0x0448}, /* Cyrillic_sha */
    {0x06dc, 0x044d}, /* Cyrillic_e */
    {0x06dd, 0x0449}, /* Cyrillic_shcha */
    {0x06de, 0x0447}, /* Cyrillic_che */
    {0x06df, 0x044a}, /* Cyrillic_hardsign */
    {0x06e0, 0x042e}, /* Cyrillic_YU */
    {0x06e1, 0x0410}, /* Cyrillic_A */
    {0x06e2, 0x0411}, /* Cyrillic_BE */
    {0x06e3, 0x0426}, /* Cyrillic_TSE */
    {0x06e4, 0x0414}, /* Cyrillic_DE */
    {0x06e5, 0x0415}, /* Cyrillic_IE */
    {0x06e6, 0x0424}, /* Cyrillic_EF */
    {0x06e7, 0x0413}, /* Cyrillic_GHE */
    {0x06e8, 0x0425}, /* Cyrillic_HA */
    {0x06e9, 0x0418}, /* Cyrillic_I */
    {0x06ea, 0x0419}, /* Cyrillic_SHORTI */
    {0x06eb, 0x041a}, /* Cyrillic_KA */
    {0x06ec, 0x041b}, /* Cyrillic_EL */
    {0x06ed, 0x041c}, /* Cyrillic_EM */
    {0x06ee, 0x041d}, /* Cyrillic_EN */
    {0x06ef, 0x041e}, /* Cyrillic_O */
    {0x06f0, 0x041f}, /* Cyrillic_PE */
    {0x06f1, 0x042f}, /* Cyrillic_YA */
    {0x06f2, 0x0420}, /* Cyrillic_ER */
    {0x06f3, 0x0421}, /* Cyrillic_ES */
    {0x06f4, 0x0422}, /* Cyrillic_TE */
    {0x06f5, 0x0423}, /* Cyrillic_U */
    {0x06f6, 0x0416}, /* Cyrillic_ZHE */
    {0x06f7, 0x0412}, /* Cyrillic_VE */
    {0x06f8, 0x042c}, /* Cyrillic_SOFTSIGN */
    {0x06f9, 0x042b}, /* Cyrillic_YERU */
    {0x06fa, 0x0417}, /* Cyrillic_ZE */
    {0x06fb, 0x0428}, /* Cyrillic_SHA */
    {0x06fc, 0x042d}, /* Cyrillic_E */
    {0x06fd, 0x0429}, /* Cyrillic_SHCHA */
    {0x06fe, 0x0427}, /* Cyrillic_CHE */
    {0x06ff, 0x042a}, /* Cyrillic_HARDSIGN */
    {0x07a1, 0x0386}, /* Greek_ALPHAaccent */
    {0x07a2, 0x0388}, /* Greek_EPSILONaccent */
    {0x07a3, 0x0389}, /* Greek_ETAaccent */
    {0x07a4, 0x038a}, /* Greek_IOTAaccent */
    {0x07a5, 0x03aa}, /* Greek_IOTAdiaeresis */
    {0x07a7, 0x038c}, /* Greek_OMICRONaccent */
    {0x07a8, 0x038e}, /* Greek_UPSILONaccent */
    {0x07a9, 0x03ab}, /* Greek_UPSILONdieresis */
    {0x07ab, 0x038f}, /* Greek_OMEGAaccent */
    {0x07ae, 0x0385}, /* Greek_accentdieresis */
    {0x07af, 0x2015}, /* Greek_horizbar */
    {0x07b1, 0x03ac}, /* Greek_alphaaccent */
    {0x07b2, 0x03ad}, /* Greek_epsilonaccent */
    {0x07b3, 0x03ae}, /* Greek_etaaccent */
    {0x07b4, 0x03af}, /* Greek_iotaaccent */
    {0x07b5, 0x03ca}, /* Greek_iotadieresis */
    {0x07b6, 0x0390}, /* Greek_iotaaccentdieresis */
    {0x07b7, 0x03cc}, /* Greek_omicronaccent */
    {0x07b8, 0x03cd}, /* Greek_upsilonaccent */
    {0x07b9, 0x03cb}, /* Greek_upsilondieresis */
    {0x07ba, 0x03b0}, /* Greek_upsilonaccentdieresis */
    {0x07bb, 0x03ce}, /* Greek_omegaaccent */
    {0x07c1, 0x0391}, /* Greek_ALPHA */
    {0x07c2, 0x0392}, /* Greek_BETA */
    {0x07c3, 0x0393}, /* Greek_GAMMA */
    {0x07c4, 0x0394}, /* Greek_DELTA */
    {0x07c5, 0x0395}, /* Greek_EPSILON */
    {0x07c6, 0x0396}, /* Greek_ZETA */
    {0x07c7, 0x0397}, /* Greek_ETA */
    {0x07c8, 0x0398}, /* Greek_THETA */
    {0x07c9, 0x0399}, /* Greek_IOTA */
    {0x07ca, 0x039a}, /* Greek_KAPPA */
    {0x07cb, 0x039b}, /* Greek_LAMDA */
    {0x07cc, 0x039c}, /* Greek_MU */
    {0x07cd, 0x039d}, /* Greek_NU */
    {0x07ce, 0x039e}, /* Greek_XI */
    {0x07cf, 0x039f}, /* Greek_OMICRON */
    {0x07d0, 0x03a0}, /* Greek_PI */
    {0x07d1, 0x03a1}, /* Greek_RHO */
    {0x07d2, 0x03a3}, /* Greek_SIGMA */
    {0x07d4, 0x03a4}, /* Greek_TAU */
    {0x07d5, 0x03a5}, /* Greek_UPSILON */
    {0x07d6, 0x03a6}, /* Greek_PHI */
    {0x07d7, 0x03a7}, /* Greek_CHI */
    {0x07d8, 0x03a8}, /* Greek_PSI */
    {0x07d9, 0x03a9}, /* Greek_OMEGA */
    {0x07e1, 0x03b1}, /* Greek_alpha */
    {0x07e2, 0x03b2}, /* Greek_beta */
    {0x07e3, 0x03b3}, /* Greek_gamma */
    {0x07e4, 0x03b4}, /* Greek_delta */
    {0x07e5, 0x03b5}, /* Greek_epsilon */
    {0x07e6, 0x03b6}, /* Greek_zeta */
    {0x07e7, 0x03b7}, /* Greek_eta */
    {0x07e8, 0x03b8}, /* Greek_theta */
    {0x07e9, 0x03b9}, /* Greek_iota */
    {0x07ea, 0x03ba}, /* Greek_kappa */
    {0x07eb, 0x03bb}, /* Greek_lambda */
    {0x07ec, 0x03bc}, /* Greek_mu */
    {0x07ed, 0x03bd}, /* Greek_nu */
    {0x07ee, 0x03be}, /* Greek_xi */
    {0x07ef, 0x03bf}, /* Greek_omicron */
    {0x07f0, 0x03c0}, /* Greek_pi */
    {0x07f1, 0x03c1}, /* Greek_rho */
    {0x07f2, 0x03c3}, /* Greek_sigma */
    {0x07f3, 0x03c2}, /* Greek_finalsmallsigma */
    {0x07f4, 0x03c4}, /* Greek_tau */
    {0x07f5, 0x03c5}, /* Greek_upsilon */
    {0x07f6, 0x03c6}, /* Greek_phi */
    {0x07f7, 0x03c7}, /* Greek_chi */
    {0x07f8, 0x03c8}, /* Greek_psi */
    {0x07f9, 0x03c9}, /* Greek_omega */
    {0x08a1, 0x23b7}, /* leftradical */
    {0x08a4, 0x2320}, /* topintegral */
    {0x08a5, 0x2321}, /* botintegral */
    {0x08a7, 0x23a1}, /* topleftsqbracket */
    {0x08a8, 0x23a3}, /* botleftsqbracket */
    {0x08a9, 0x23a4}, /* toprightsqbracket */
    {0x08aa, 0x23a6}, /* botrightsqbracket */
    {0x08ab, 0x239b}, /* topleftparens */
    {0x08ac, 0x239d}, /* botleftparens */
    {0x08ad, 0x239e}, /* toprightparens */
    {0x08ae, 0x23a0}, /* botrightparens */
    {0x08af, 0x23a8}, /* leftmiddlecurlybrace */
    {0x08b0, 0x23ac}, /* rightmiddlecurlybrace */
    {0x08bc, 0x2264}, /* lessthanequal */
    {0x08bd, 0x2260}, /* notequal */
    {0x08be, 0x2265}, /* greaterthanequal */
    {0x08bf, 0x222b}, /* integral */
    {0x08c0, 0x2234}, /* therefore */
    {0x08c1, 0x221d}, /* variation */
    {0x08c2, 0x221e}, /* infinity */
    {0x08c5, 0x2207}, /* nabla */
    {0x08c8, 0x223c}, /* approximate */
    {0x08c9, 0x2243}, /* similarequal */
    {0x08cd, 0x21d4}, /* ifonlyif */
    {0x08ce, 0x21d2}, /* implies */
    {0x08cf, 0x2261}, /* identical */
    {0x08d6, 0x221a}, /* radical */
    {0x08da, 0x2282}, /* includedin */
    {0x08db, 0x2283}, /* includes */
    {0x08dc, 0x2229}, /* intersection */
    {0x08dd, 0x222a}, /* union */
    {0x08de, 0x2227}, /* logicaland */
    {0x08df, 0x2228}, /* logicalor */
    {0x08ef, 0x2202}, /* partialderivative */
    {0x08f6, 0x0192}, /* function */
    {0x08fb, 0x2190}, /* leftarrow */
    {0x08fc, 0x2191}, /* uparrow */
    {0x08fd, 0x2192}, /* rightarrow */
    {0x08fe, 0x2193}, /* downarrow */
    {0x09e0, 0x25c6}, /* soliddiamond */
    {0x09e1, 0x2592}, /* checkerboard */
    {0x09e2, 0x2409}, /* ht */
    {0x09e3, 0x240c}, /* ff */
    {0x09e4, 0x240d}, /* cr */
    {0x09e5, 0x240a}, /* lf */
    {0x09e8, 0x2424}, /* nl */
    {0x09e9, 0x240b}, /* vt */
    {0x09ea, 0x2518}, /* lowrightcorner */
    {0x09eb, 0x2510}, /* uprightcorner */
    {0x09ec, 0x250c}, /* upleftcorner */
    {0x09ed, 0x2514}, /* lowleftcorner */
    {0x09ee, 0x253c}, /* crossinglines */
    {0x09ef, 0x23ba}, /* horizlinescan1 */
    {0x09f0, 0x23bb}, /* horizlinescan3 */
    {0x09f1, 0x2500}, /* horizlinescan5 */
    {0x09f2, 0x23bc}, /* horizlinescan7 */
    {0x09f3, 0x23bd}, /* horizlinescan9 */
    {0x09f4, 0x251c}, /* leftt */
    {0x09f5, 0x2524}, /* rightt */
    {0x09f6, 0x2534}, /* bott */
    {0x09f7, 0x252c}, /* topt */
    {0x09f8, 0x2502}, /* vertbar */
    {0x0aa1, 0x2003}, /* emspace */
    {0x0aa2, 0x2002}, /* enspace */
    {0x0aa3, 0x2004}, /* em3space */
    {0x0aa4, 0x2005}, /* em4space */
    {0x0aa5, 0x2007}, /* digitspace */
    {0x0aa6, 0x2008}, /* punctspace */
    {0x0aa7, 0x2009}, /* thinspace */
    {0x0aa8, 0x200a}, /* hairspace */
    {0x0aa9, 0x2014}, /* emdash */
    {0x0aaa, 0x2013}, /* endash */
    {0x0aae, 0x2026}, /* ellipsis */
    {0x0aaf, 0x2025}, /* doubbaselinedot */
    {0x0ab0, 0x2153}, /* onethird */
    {0x0ab1, 0x2154}, /* twothirds */
    {0x0ab2, 0x2155}, /* onefifth */
    {0x0ab3, 0x2156}, /* twofifths */
    {0x0ab4, 0x2157}, /* threefifths */
    {0x0ab5, 0x2158}, /* fourfifths */
    {0x0ab6, 0x2159}, /* onesixth */
    {0x0ab7, 0x215a}, /* fivesixths */
    {0x0ab8, 0x2105}, /* careof */
    {0x0abb, 0x2012}, /* figdash */
    {0x0ac3, 0x215b}, /* oneeighth */
    {0x0ac4, 0x215c}, /* threeeighths */
    {0x0ac5, 0x215d}, /* fiveeighths */
    {0x0ac6, 0x215e}, /* seveneighths */
    {0x0ac9, 0x2122}, /* trademark */
    {0x0ad0, 0x2018}, /* leftsinglequotemark */
    {0x0ad1, 0x2019}, /* rightsinglequotemark */
    {0x0ad2, 0x201c}, /* leftdoublequotemark */
    {0x0ad3, 0x201d}, /* rightdoublequotemark */
    {0x0ad4, 0x211e}, /* prescription */
    {0x0ad6, 0x2032}, /* minutes */
    {0x0ad7, 0x2033}, /* seconds */
    {0x0ad9, 0x271d}, /* latincross */
    {0x0aec, 0x2663}, /* club */
    {0x0aed, 0x2666}, /* diamond */
    {0x0aee, 0x2665}, /* heart */
    {0x0af0, 0x2720}, /* maltesecross */
    {0x0af1, 0x2020}, /* dagger */
    {0x0af2, 0x2021}, /* doubledagger */
    {0x0af3, 0x2713}, /* checkmark */
    {0x0af4, 0x2717}, /* ballotcross */
    {0x0af5, 0x266f}, /* musicalsharp */
    {0x0af6, 0x266d}, /* musicalflat */
    {0x0af7, 0x2642}, /* malesymbol */
    {0x0af8, 0x2640}, /* femalesymbol */
    {0x0af9, 0x260e}, /* telephone */
    {0x0afa, 0x2315}, /* telephonerecorder */
    {0x0afb, 0x2117}, /* phonographcopyright */
    {0x0afc, 0x2038}, /* caret */
    {0x0afd, 0x201a}, /* singlelowquotemark */
    {0x0afe, 0x201e}, /* doublelowquotemark */
    {0x0bc2, 0x22a5}, /* downtack */
    {0x0bc4, 0x230a}, /* downstile */
    {0x0bca, 0x2218}, /* jot */
    {0x0bcc, 0x2395}, /* quad */
    {0x0bce, 0x22a4}, /* uptack */
    {0x0bcf, 0x25cb}, /* circle */
    {0x0bd3, 0x2308}, /* upstile */
    {0x0bdc, 0x22a2}, /* lefttack */
    {0x0bfc, 0x22a3}, /* righttack */
    {0x0cdf, 0x2017}, /* hebrew_doublelowline */
    {0x0ce0, 0x05d0}, /* hebrew_aleph */
    {0x0ce1, 0x05d1}, /* hebrew_bet */
    {0x0ce2, 0x05d2}, /* hebrew_gimel */
    {0x0ce3, 0x05d3}, /* hebrew_dalet */
    {0x0ce4, 0x05d4}, /* hebrew_he */
    {0x0ce5, 0x05d5}, /* hebrew_waw */
    {0x0ce6, 0x05d6}, /* hebrew_zain */
    {0x0ce7, 0x05d7}, /* hebrew_chet */
    {0x0ce8, 0x05d8}, /* hebrew_tet */
    {0x0ce9, 0x05d9}, /* hebrew_yod */
    {0x0cea, 0x05da}, /* hebrew_finalkaph */
    {0x0ceb, 0x05db}, /* hebrew_kaph */
    {0x0cec, 0x05dc}, /* hebrew_lamed */
    {0x0ced, 0x05dd}, /* hebrew_finalmem */
    {0x0cee, 0x05de}, /* hebrew_mem */
    {0x0cef, 0x05df}, /* hebrew_finalnun */
    {0x0cf0, 0x05e0}, /* hebrew_nun */
    {0x0cf1, 0x05e1}, /* hebrew_samech */
    {0x0cf2, 0x05e2}, /* hebrew_ayin */
    {0x0cf3, 0x05e3}, /* hebrew_finalpe */
    {0x0cf4, 0x05e4}, /* hebrew_pe */
    {0x0cf5, 0x05e5}, /* hebrew_finalzade */
    {0x0cf6, 0x05e6}, /* hebrew_zade */
    {0x0cf7, 0x05e7}, /* hebrew_qoph */
    {0x0cf8, 0x05e8}, /* hebrew_resh */
    {0x0cf9, 0x05e9}, /* hebrew_shin */
    {0x0cfa, 0x05ea}, /* hebrew_taw */
    {0x0da1, 0x0e01}, /* Thai_kokai */
    {0x0da2, 0x0e02}, /* Thai_khokhai */
    {0x0da3, 0x0e03}, /* Thai_khokhuat */
    {0x0da4, 0x0e04}, /* Thai_khokhwai */
    {0x0da5, 0x0e05}, /* Thai_khokhon */
    {0x0da6, 0x0e06}, /* Thai_khorakhang */
    {0x0da7, 0x0e07}, /* Thai_ngongu */
    {0x0da8, 0x0e08}, /* Thai_chochan */
    {0x0da9, 0x0e09}, /* Thai_choching */
    {0x0daa, 0x0e0a}, /* Thai_chochang */
    {0x0dab, 0x0e0b}, /* Thai_soso */
    {0x0dac, 0x0e0c}, /* Thai_chochoe */
    {0x0dad, 0x0e0d}, /* Thai_yoying */
    {0x0dae, 0x0e0e}, /* Thai_dochada */
    {0x0daf, 0x0e0f}, /* Thai_topatak */
    {0x0db0, 0x0e10}, /* Thai_thothan */
    {0x0db1, 0x0e11}, /* Thai_thonangmontho */
    {0x0db2, 0x0e12}, /* Thai_thophuthao */
    {0x0db3, 0x0e13}, /* Thai_nonen */
    {0x0db4, 0x0e14}, /* Thai_dodek */
    {0x0db5, 0x0e15}, /* Thai_totao */
    {0x0db6, 0x0e16}, /* Thai_thothung */
    {0x0db7, 0x0e17}, /* Thai_thothahan */
    {0x0db8, 0x0e18}, /* Thai_thothong */
    {0x0db9, 0x0e19}, /* Thai_nonu */
    {0x0dba, 0x0e1a}, /* Thai_bobaimai */
    {0x0dbb, 0x0e1b}, /* Thai_popla */
    {0x0dbc, 0x0e1c}, /* Thai_phophung */
    {0x0dbd, 0x0e1d}, /* Thai_fofa */
    {0x0dbe, 0x0e1e}, /* Thai_phophan */
    {0x0dbf, 0x0e1f}, /* Thai_fofan */
    {0x0dc0, 0x0e20}, /* Thai_phosamphao */
    {0x0dc1, 0x0e21}, /* Thai_moma */
    {0x0dc2, 0x0e22}, /* Thai_yoyak */
    {0x0dc3, 0x0e23}, /* Thai_rorua */
    {0x0dc4, 0x0e24}, /* Thai_ru */
    {0x0dc5, 0x0e25}, /* Thai_loling */
    {0x0dc6, 0x0e26}, /* Thai_lu */
    {0x0dc7, 0x0e27}, /* Thai_wowaen */
    {0x0dc8, 0x0e28}, /* Thai_sosala */
    {0x0dc9, 0x0e29}, /* Thai_sorusi */
    {0x0dca, 0x0e2a}, /* Thai_sosua */
    {0x0dcb, 0x0e2b}, /* Thai_hohip */
    {0x0dcc, 0x0e2c}, /* Thai_lochula */
    {0x0dcd, 0x0e2d}, /* Thai_oang */
    {0x0dce, 0x0e2e}, /* Thai_honokhuk */
    {0x0dcf, 0x0e2f}, /* Thai_paiyannoi */
    {0x0dd0, 0x0e30}, /* Thai_saraa */
    {0x0dd1, 0x0e31}, /* Thai_maihanakat */
    {0x0dd2, 0x0e32}, /* Thai_saraaa */
    {0x0dd3, 0x0e33}, /* Thai_saraam */
    {0x0dd4, 0x0e34}, /* Thai_sarai */
    {0x0dd5, 0x0e35}, /* Thai_saraii */
    {0x0dd6, 0x0e36}, /* Thai_saraue */
    {0x0dd7, 0x0e37}, /* Thai_sarauee */
    {0x0dd8, 0x0e38}, /* Thai_sarau */
    {0x0dd9, 0x0e39}, /* Thai_sarauu */
    {0x0dda, 0x0e3a}, /* Thai_phinthu */
    {0x0ddf, 0x0e3f}, /* Thai_baht */
    {0x0de0, 0x0e40}, /* Thai_sarae */
    {0x0de1, 0x0e41}, /* Thai_saraae */
    {0x0de2, 0x0e42}, /* Thai_sarao */
    {0x0de3, 0x0e43}, /* Thai_saraaimaimuan */
    {0x0de4, 0x0e44}, /* Thai_saraaimaimalai */
    {0x0de5, 0x0e45}, /* Thai_lakkhangyao */
    {0x0de6, 0x0e46}, /* Thai_maiyamok */
    {0x0de7, 0x0e47}, /* Thai_maitaikhu */
    {0x0de8, 0x0e48}, /* Thai_maiek */
    {0x0de9, 0x0e49}, /* Thai_maitho */
    {0x0dea, 0x0e4a}, /* Thai_maitri */
    {0x0deb, 0x0e4b}, /* Thai_maichattawa */
    {0x0dec, 0x0e4c}, /* Thai_thanthakhat */
    {0x0ded, 0x0e4d}, /* Thai_nikhahit */
    {0x0df0, 0x0e50}, /* Thai_leksun */
    {0x0df1, 0x0e51}, /* Thai_leknung */
    {0x0df2, 0x0e52}, /* Thai_leksong */
    {0x0df3, 0x0e53}, /* Thai_leksam */
    {0x0df4, 0x0e54}, /* Thai_leksi */
    {0x0df5, 0x0e55}, /* Thai_lekha */
    {0x0df6, 0x0e56}, /* Thai_lekhok */
    {0x0df7, 0x0e57}, /* Thai_lekchet */
    {0x0df8, 0x0e58}, /* Thai_lekpaet */
    {0x0df9, 0x0e59}, /* Thai_lekkao */
    {0x13bc, 0x0152}, /* OE */
    {0x13bd, 0x0153}, /* oe */
    {0x13be, 0x0178}, /* Ydiaeresis */
    {0x20a0, 0x20a0}, /* EcuSign */
    {0x20a1, 0x20a1}, /* ColonSign */
    {0x20a2, 0x20a2}, /* CruzeiroSign */
    {0x20a3, 0x20a3}, /* FFrancSign */
    {0x20a4, 0x20a4}, /* LiraSign */
    {0x20a5, 0x20a5}, /* MillSign */
    {0x20a6, 0x20a6}, /* NairaSign */
    {0x20a7, 0x20a7}, /* PesetaSign */
    {0x20a8, 0x20a8}, /* RupeeSign */
    {0x20a9, 0x20a9}, /* WonSign */
    {0x20aa, 0x20aa}, /* NewSheqelSign */
    {0x20ab, 0x20ab}, /* DongSign */
    {0x20ac, 0x20ac}, /* EuroSign */
    {0x06ad, 0x0491}, /* Ukrainian_ghe_with_upturn */
    {0x06bd, 0x0490}, /* Ukrainian_GHE_WITH_UPTURN */
    {0x14a2, 0x0587}, /* Armenian_ligature_ew */
    {0x14a3, 0x0589}, /* Armenian_verjaket */
    {0x14aa, 0x055d}, /* Armenian_but */
    {0x14ad, 0x058a}, /* Armenian_yentamna */
    {0x14af, 0x055c}, /* Armenian_amanak */
    {0x14b0, 0x055b}, /* Armenian_shesht */
    {0x14b1, 0x055e}, /* Armenian_paruyk */
    {0x14b2, 0x0531}, /* Armenian_AYB */
    {0x14b3, 0x0561}, /* Armenian_ayb */
    {0x14b4, 0x0532}, /* Armenian_BEN */
    {0x14b5, 0x0562}, /* Armenian_ben */
    {0x14b6, 0x0533}, /* Armenian_GIM */
    {0x14b7, 0x0563}, /* Armenian_gim */
    {0x14b8, 0x0534}, /* Armenian_DA */
    {0x14b9, 0x0564}, /* Armenian_da */
    {0x14ba, 0x0535}, /* Armenian_YECH */
    {0x14bb, 0x0565}, /* Armenian_yech */
    {0x14bc, 0x0536}, /* Armenian_ZA */
    {0x14bd, 0x0566}, /* Armenian_za */
    {0x14be, 0x0537}, /* Armenian_E */
    {0x14bf, 0x0567}, /* Armenian_e */
    {0x14c0, 0x0538}, /* Armenian_AT */
    {0x14c1, 0x0568}, /* Armenian_at */
    {0x14c2, 0x0539}, /* Armenian_TO */
    {0x14c3, 0x0569}, /* Armenian_to */
    {0x14c4, 0x053a}, /* Armenian_ZHE */
    {0x14c5, 0x056a}, /* Armenian_zhe */
    {0x14c6, 0x053b}, /* Armenian_INI */
    {0x14c7, 0x056b}, /* Armenian_ini */
    {0x14c8, 0x053c}, /* Armenian_LYUN */
    {0x14c9, 0x056c}, /* Armenian_lyun */
    {0x14ca, 0x053d}, /* Armenian_KHE */
    {0x14cb, 0x056d}, /* Armenian_khe */
    {0x14cc, 0x053e}, /* Armenian_TSA */
    {0x14cd, 0x056e}, /* Armenian_tsa */
    {0x14ce, 0x053f}, /* Armenian_KEN */
    {0x14cf, 0x056f}, /* Armenian_ken */
    {0x14d0, 0x0540}, /* Armenian_HO */
    {0x14d1, 0x0570}, /* Armenian_ho */
    {0x14d2, 0x0541}, /* Armenian_DZA */
    {0x14d3, 0x0571}, /* Armenian_dza */
    {0x14d4, 0x0542}, /* Armenian_GHAT */
    {0x14d5, 0x0572}, /* Armenian_ghat */
    {0x14d6, 0x0543}, /* Armenian_TCHE */
    {0x14d7, 0x0573}, /* Armenian_tche */
    {0x14d8, 0x0544}, /* Armenian_MEN */
    {0x14d9, 0x0574}, /* Armenian_men */
    {0x14da, 0x0545}, /* Armenian_HI */
    {0x14db, 0x0575}, /* Armenian_hi */
    {0x14dc, 0x0546}, /* Armenian_NU */
    {0x14dd, 0x0576}, /* Armenian_nu */
    {0x14de, 0x0547}, /* Armenian_SHA */
    {0x14df, 0x0577}, /* Armenian_sha */
    {0x14e0, 0x0548}, /* Armenian_VO */
    {0x14e1, 0x0578}, /* Armenian_vo */
    {0x14e2, 0x0549}, /* Armenian_CHA */
    {0x14e3, 0x0579}, /* Armenian_cha */
    {0x14e4, 0x054a}, /* Armenian_PE */
    {0x14e5, 0x057a}, /* Armenian_pe */
    {0x14e6, 0x054b}, /* Armenian_JE */
    {0x14e7, 0x057b}, /* Armenian_je */
    {0x14e8, 0x054c}, /* Armenian_RA */
    {0x14e9, 0x057c}, /* Armenian_ra */
    {0x14ea, 0x054d}, /* Armenian_SE */
    {0x14eb, 0x057d}, /* Armenian_se */
    {0x14ec, 0x054e}, /* Armenian_VEV */
    {0x14ed, 0x057e}, /* Armenian_vev */
    {0x14ee, 0x054f}, /* Armenian_TYUN */
    {0x14ef, 0x057f}, /* Armenian_tyun */
    {0x14f0, 0x0550}, /* Armenian_RE */
    {0x14f1, 0x0580}, /* Armenian_re */
    {0x14f2, 0x0551}, /* Armenian_TSO */
    {0x14f3, 0x0581}, /* Armenian_tso */
    {0x14f4, 0x0552}, /* Armenian_VYUN */
    {0x14f5, 0x0582}, /* Armenian_vyun */
    {0x14f6, 0x0553}, /* Armenian_PYUR */
    {0x14f7, 0x0583}, /* Armenian_pyur */
    {0x14f8, 0x0554}, /* Armenian_KE */
    {0x14f9, 0x0584}, /* Armenian_ke */
    {0x14fa, 0x0555}, /* Armenian_O */
    {0x14fb, 0x0585}, /* Armenian_o */
    {0x14fc, 0x0556}, /* Armenian_FE */
    {0x14fd, 0x0586}, /* Armenian_fe */
    {0x14fe, 0x055a}, /* Armenian_apostrophe */
    {0x15d0, 0x10d0}, /* Georgian_an */
    {0x15d1, 0x10d1}, /* Georgian_ban */
    {0x15d2, 0x10d2}, /* Georgian_gan */
    {0x15d3, 0x10d3}, /* Georgian_don */
    {0x15d4, 0x10d4}, /* Georgian_en */
    {0x15d5, 0x10d5}, /* Georgian_vin */
    {0x15d6, 0x10d6}, /* Georgian_zen */
    {0x15d7, 0x10d7}, /* Georgian_tan */
    {0x15d8, 0x10d8}, /* Georgian_in */
    {0x15d9, 0x10d9}, /* Georgian_kan */
    {0x15da, 0x10da}, /* Georgian_las */
    {0x15db, 0x10db}, /* Georgian_man */
    {0x15dc, 0x10dc}, /* Georgian_nar */
    {0x15dd, 0x10dd}, /* Georgian_on */
    {0x15de, 0x10de}, /* Georgian_par */
    {0x15df, 0x10df}, /* Georgian_zhar */
    {0x15e0, 0x10e0}, /* Georgian_rae */
    {0x15e1, 0x10e1}, /* Georgian_san */
    {0x15e2, 0x10e2}, /* Georgian_tar */
    {0x15e3, 0x10e3}, /* Georgian_un */
    {0x15e4, 0x10e4}, /* Georgian_phar */
    {0x15e5, 0x10e5}, /* Georgian_khar */
    {0x15e6, 0x10e6}, /* Georgian_ghan */
    {0x15e7, 0x10e7}, /* Georgian_qar */
    {0x15e8, 0x10e8}, /* Georgian_shin */
    {0x15e9, 0x10e9}, /* Georgian_chin */
    {0x15ea, 0x10ea}, /* Georgian_can */
    {0x15eb, 0x10eb}, /* Georgian_jil */
    {0x15ec, 0x10ec}, /* Georgian_cil */
    {0x15ed, 0x10ed}, /* Georgian_char */
    {0x15ee, 0x10ee}, /* Georgian_xan */
    {0x15ef, 0x10ef}, /* Georgian_jhan */
    {0x15f0, 0x10f0}, /* Georgian_hae */
    {0x15f1, 0x10f1}, /* Georgian_he */
    {0x15f2, 0x10f2}, /* Georgian_hie */
    {0x15f3, 0x10f3}, /* Georgian_we */
    {0x15f4, 0x10f4}, /* Georgian_har */
    {0x15f5, 0x10f5}, /* Georgian_hoe */
    {0x15f6, 0x10f6}, /* Georgian_fi */
    {0x12a1, 0x1e02}, /* Babovedot */
    {0x12a2, 0x1e03}, /* babovedot */
    {0x12a6, 0x1e0a}, /* Dabovedot */
    {0x12a8, 0x1e80}, /* Wgrave */
    {0x12aa, 0x1e82}, /* Wacute */
    {0x12ab, 0x1e0b}, /* dabovedot */
    {0x12ac, 0x1ef2}, /* Ygrave */
    {0x12b0, 0x1e1e}, /* Fabovedot */
    {0x12b1, 0x1e1f}, /* fabovedot */
    {0x12b4, 0x1e40}, /* Mabovedot */
    {0x12b5, 0x1e41}, /* mabovedot */
    {0x12b7, 0x1e56}, /* Pabovedot */
    {0x12b8, 0x1e81}, /* wgrave */
    {0x12b9, 0x1e57}, /* pabovedot */
    {0x12ba, 0x1e83}, /* wacute */
    {0x12bb, 0x1e60}, /* Sabovedot */
    {0x12bc, 0x1ef3}, /* ygrave */
    {0x12bd, 0x1e84}, /* Wdiaeresis */
    {0x12be, 0x1e85}, /* wdiaeresis */
    {0x12bf, 0x1e61}, /* sabovedot */
    {0x12d0, 0x0174}, /* Wcircumflex */
    {0x12d7, 0x1e6a}, /* Tabovedot */
    {0x12de, 0x0176}, /* Ycircumflex */
    {0x12f0, 0x0175}, /* wcircumflex */
    {0x12f7, 0x1e6b}, /* tabovedot */
    {0x12fe, 0x0177}, /* ycircumflex */
    {0x0590, 0x06f0}, /* Farsi_0 */
    {0x0591, 0x06f1}, /* Farsi_1 */
    {0x0592, 0x06f2}, /* Farsi_2 */
    {0x0593, 0x06f3}, /* Farsi_3 */
    {0x0594, 0x06f4}, /* Farsi_4 */
    {0x0595, 0x06f5}, /* Farsi_5 */
    {0x0596, 0x06f6}, /* Farsi_6 */
    {0x0597, 0x06f7}, /* Farsi_7 */
    {0x0598, 0x06f8}, /* Farsi_8 */
    {0x0599, 0x06f9}, /* Farsi_9 */
    {0x05a5, 0x066a}, /* Arabic_percent */
    {0x05a6, 0x0670}, /* Arabic_superscript_alef */
    {0x05a7, 0x0679}, /* Arabic_tteh */
    {0x05a8, 0x067e}, /* Arabic_peh */
    {0x05a9, 0x0686}, /* Arabic_tcheh */
    {0x05aa, 0x0688}, /* Arabic_ddal */
    {0x05ab, 0x0691}, /* Arabic_rreh */
    {0x05ae, 0x06d4}, /* Arabic_fullstop */
    {0x05b0, 0x0660}, /* Arabic_0 */
    {0x05b1, 0x0661}, /* Arabic_1 */
    {0x05b2, 0x0662}, /* Arabic_2 */
    {0x05b3, 0x0663}, /* Arabic_3 */
    {0x05b4, 0x0664}, /* Arabic_4 */
    {0x05b5, 0x0665}, /* Arabic_5 */
    {0x05b6, 0x0666}, /* Arabic_6 */
    {0x05b7, 0x0667}, /* Arabic_7 */
    {0x05b8, 0x0668}, /* Arabic_8 */
    {0x05b9, 0x0669}, /* Arabic_9 */
    {0x05f3, 0x0653}, /* Arabic_madda_above */
    {0x05f4, 0x0654}, /* Arabic_hamza_above */
    {0x05f5, 0x0655}, /* Arabic_hamza_below */
    {0x05f6, 0x0698}, /* Arabic_jeh */
    {0x05f7, 0x06a4}, /* Arabic_veh */
    {0x05f8, 0x06a9}, /* Arabic_keheh */
    {0x05f9, 0x06af}, /* Arabic_gaf */
    {0x05fa, 0x06ba}, /* Arabic_noon_ghunna */
    {0x05fb, 0x06be}, /* Arabic_heh_doachashmee */
    {0x05fc, 0x06cc}, /* Farsi_yeh */
    {0x05fd, 0x06d2}, /* Arabic_yeh_baree */
    {0x05fe, 0x06c1}, /* Arabic_heh_goal */
    {0x0680, 0x0492}, /* Cyrillic_GHE_bar */
    {0x0681, 0x0496}, /* Cyrillic_ZHE_descender */
    {0x0682, 0x049a}, /* Cyrillic_KA_descender */
    {0x0683, 0x049c}, /* Cyrillic_KA_vertstroke */
    {0x0684, 0x04a2}, /* Cyrillic_EN_descender */
    {0x0685, 0x04ae}, /* Cyrillic_U_straight */
    {0x0686, 0x04b0}, /* Cyrillic_U_straight_bar */
    {0x0687, 0x04b2}, /* Cyrillic_HA_descender */
    {0x0688, 0x04b6}, /* Cyrillic_CHE_descender */
    {0x0689, 0x04b8}, /* Cyrillic_CHE_vertstroke */
    {0x068a, 0x04ba}, /* Cyrillic_SHHA */
    {0x068c, 0x04d8}, /* Cyrillic_SCHWA */
    {0x068d, 0x04e2}, /* Cyrillic_I_macron */
    {0x068e, 0x04e8}, /* Cyrillic_O_bar */
    {0x068f, 0x04ee}, /* Cyrillic_U_macron */
    {0x0690, 0x0493}, /* Cyrillic_ghe_bar */
    {0x0691, 0x0497}, /* Cyrillic_zhe_descender */
    {0x0692, 0x049b}, /* Cyrillic_ka_descender */
    {0x0693, 0x049d}, /* Cyrillic_ka_vertstroke */
    {0x0694, 0x04a3}, /* Cyrillic_en_descender */
    {0x0695, 0x04af}, /* Cyrillic_u_straight */
    {0x0696, 0x04b1}, /* Cyrillic_u_straight_bar */
    {0x0697, 0x04b3}, /* Cyrillic_ha_descender */
    {0x0698, 0x04b7}, /* Cyrillic_che_descender */
    {0x0699, 0x04b9}, /* Cyrillic_che_vertstroke */
    {0x069a, 0x04bb}, /* Cyrillic_shha */
    {0x069c, 0x04d9}, /* Cyrillic_schwa */
    {0x069d, 0x04e3}, /* Cyrillic_i_macron */
    {0x069e, 0x04e9}, /* Cyrillic_o_bar */
    {0x069f, 0x04ef}, /* Cyrillic_u_macron */
    {0x16a3, 0x1e8a}, /* Xabovedot */
    {0x16a6, 0x012c}, /* Ibreve */
    {0x16a9, 0x01b5}, /* Zstroke */
    {0x16aa, 0x01e6}, /* Gcaron */
    {0x16af, 0x019f}, /* Obarred */
    {0x16b3, 0x1e8b}, /* xabovedot */
    {0x16b6, 0x012d}, /* ibreve */
    {0x16b9, 0x01b6}, /* zstroke */
    {0x16ba, 0x01e7}, /* gcaron */
    {0x16bd, 0x01d2}, /* ocaron */
    {0x16bf, 0x0275}, /* obarred */
    {0x16c6, 0x018f}, /* SCHWA */
    {0x16f6, 0x0259}, /* schwa */
    {0x16d1, 0x1e36}, /* Lbelowdot */
    {0x16e1, 0x1e37}, /* lbelowdot */
    {0x1ea0, 0x1ea0}, /* Abelowdot */
    {0x1ea1, 0x1ea1}, /* abelowdot */
    {0x1ea2, 0x1ea2}, /* Ahook */
    {0x1ea3, 0x1ea3}, /* ahook */
    {0x1ea4, 0x1ea4}, /* Acircumflexacute */
    {0x1ea5, 0x1ea5}, /* acircumflexacute */
    {0x1ea6, 0x1ea6}, /* Acircumflexgrave */
    {0x1ea7, 0x1ea7}, /* acircumflexgrave */
    {0x1ea8, 0x1ea8}, /* Acircumflexhook */
    {0x1ea9, 0x1ea9}, /* acircumflexhook */
    {0x1eaa, 0x1eaa}, /* Acircumflextilde */
    {0x1eab, 0x1eab}, /* acircumflextilde */
    {0x1eac, 0x1eac}, /* Acircumflexbelowdot */
    {0x1ead, 0x1ead}, /* acircumflexbelowdot */
    {0x1eae, 0x1eae}, /* Abreveacute */
    {0x1eaf, 0x1eaf}, /* abreveacute */
    {0x1eb0, 0x1eb0}, /* Abrevegrave */
    {0x1eb1, 0x1eb1}, /* abrevegrave */
    {0x1eb2, 0x1eb2}, /* Abrevehook */
    {0x1eb3, 0x1eb3}, /* abrevehook */
    {0x1eb4, 0x1eb4}, /* Abrevetilde */
    {0x1eb5, 0x1eb5}, /* abrevetilde */
    {0x1eb6, 0x1eb6}, /* Abrevebelowdot */
    {0x1eb7, 0x1eb7}, /* abrevebelowdot */
    {0x1eb8, 0x1eb8}, /* Ebelowdot */
    {0x1eb9, 0x1eb9}, /* ebelowdot */
    {0x1eba, 0x1eba}, /* Ehook */
    {0x1ebb, 0x1ebb}, /* ehook */
    {0x1ebc, 0x1ebc}, /* Etilde */
    {0x1ebd, 0x1ebd}, /* etilde */
    {0x1ebe, 0x1ebe}, /* Ecircumflexacute */
    {0x1ebf, 0x1ebf}, /* ecircumflexacute */
    {0x1ec0, 0x1ec0}, /* Ecircumflexgrave */
    {0x1ec1, 0x1ec1}, /* ecircumflexgrave */
    {0x1ec2, 0x1ec2}, /* Ecircumflexhook */
    {0x1ec3, 0x1ec3}, /* ecircumflexhook */
    {0x1ec4, 0x1ec4}, /* Ecircumflextilde */
    {0x1ec5, 0x1ec5}, /* ecircumflextilde */
    {0x1ec6, 0x1ec6}, /* Ecircumflexbelowdot */
    {0x1ec7, 0x1ec7}, /* ecircumflexbelowdot */
    {0x1ec8, 0x1ec8}, /* Ihook */
    {0x1ec9, 0x1ec9}, /* ihook */
    {0x1eca, 0x1eca}, /* Ibelowdot */
    {0x1ecb, 0x1ecb}, /* ibelowdot */
    {0x1ecc, 0x1ecc}, /* Obelowdot */
    {0x1ecd, 0x1ecd}, /* obelowdot */
    {0x1ece, 0x1ece}, /* Ohook */
    {0x1ecf, 0x1ecf}, /* ohook */
    {0x1ed0, 0x1ed0}, /* Ocircumflexacute */
    {0x1ed1, 0x1ed1}, /* ocircumflexacute */
    {0x1ed2, 0x1ed2}, /* Ocircumflexgrave */
    {0x1ed3, 0x1ed3}, /* ocircumflexgrave */
    {0x1ed4, 0x1ed4}, /* Ocircumflexhook */
    {0x1ed5, 0x1ed5}, /* ocircumflexhook */
    {0x1ed6, 0x1ed6}, /* Ocircumflextilde */
    {0x1ed7, 0x1ed7}, /* ocircumflextilde */
    {0x1ed8, 0x1ed8}, /* Ocircumflexbelowdot */
    {0x1ed9, 0x1ed9}, /* ocircumflexbelowdot */
    {0x1eda, 0x1eda}, /* Ohornacute */
    {0x1edb, 0x1edb}, /* ohornacute */
    {0x1edc, 0x1edc}, /* Ohorngrave */
    {0x1edd, 0x1edd}, /* ohorngrave */
    {0x1ede, 0x1ede}, /* Ohornhook */
    {0x1edf, 0x1edf}, /* ohornhook */
    {0x1ee0, 0x1ee0}, /* Ohorntilde */
    {0x1ee1, 0x1ee1}, /* ohorntilde */
    {0x1ee2, 0x1ee2}, /* Ohornbelowdot */
    {0x1ee3, 0x1ee3}, /* ohornbelowdot */
    {0x1ee4, 0x1ee4}, /* Ubelowdot */
    {0x1ee5, 0x1ee5}, /* ubelowdot */
    {0x1ee6, 0x1ee6}, /* Uhook */
    {0x1ee7, 0x1ee7}, /* uhook */
    {0x1ee8, 0x1ee8}, /* Uhornacute */
    {0x1ee9, 0x1ee9}, /* uhornacute */
    {0x1eea, 0x1eea}, /* Uhorngrave */
    {0x1eeb, 0x1eeb}, /* uhorngrave */
    {0x1eec, 0x1eec}, /* Uhornhook */
    {0x1eed, 0x1eed}, /* uhornhook */
    {0x1eee, 0x1eee}, /* Uhorntilde */
    {0x1eef, 0x1eef}, /* uhorntilde */
    {0x1ef0, 0x1ef0}, /* Uhornbelowdot */
    {0x1ef1, 0x1ef1}, /* uhornbelowdot */
    {0x1ef4, 0x1ef4}, /* Ybelowdot */
    {0x1ef5, 0x1ef5}, /* ybelowdot */
    {0x1ef6, 0x1ef6}, /* Yhook */
    {0x1ef7, 0x1ef7}, /* yhook */
    {0x1ef8, 0x1ef8}, /* Ytilde */
    {0x1ef9, 0x1ef9}, /* ytilde */
    {0x1efa, 0x01a0}, /* Ohorn */
    {0x1efb, 0x01a1}, /* ohorn */
    {0x1efc, 0x01af}, /* Uhorn */
    {0x1efd, 0x01b0}, /* uhorn */
    {0, 0}
};

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to macosx/tkMacOSXMenu.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "tkMacOSXPrivate.h"
#include "tkMenubutton.h"
#include "tkMenu.h"
#include "tkColor.h"
#include "tkFont.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_MENUS
#endif
*/

#define ENTRY_HELP_MENU		ENTRY_PLATFORM_FLAG1
#define ENTRY_APPLE_MENU	ENTRY_PLATFORM_FLAG2
#define ENTRY_WINDOWS_MENU	ENTRY_PLATFORM_FLAG3

#define sl(s) ((int) (sizeof(s "") - 1))

#define SPECIALMENU(n, f) {.name = "." #n, .len = sl(#n) + 1, \
	.flag = ENTRY_##f##_MENU }
static const struct {
    const char *name; size_t len; int flag;
} specialMenus[] = {
    SPECIALMENU(help,	HELP),
    SPECIALMENU(apple,	APPLE),
    SPECIALMENU(window,	WINDOWS),
    {NULL, 0, 0}
};
#undef SPECIALMENU

#define MODIFIER(n, f) {.name = #n, .len = sl(#n), .mask = f }
static const struct {
    const char *name; size_t len; NSUInteger mask;
} allModifiers[] = {
    MODIFIER(Control,	NSControlKeyMask),
    MODIFIER(Ctrl,	NSControlKeyMask),
    MODIFIER(Option,	NSAlternateKeyMask),
    MODIFIER(Opt,	NSAlternateKeyMask),
    MODIFIER(Alt,	NSAlternateKeyMask),
    MODIFIER(Shift,	NSShiftKeyMask),
    MODIFIER(Command,	NSCommandKeyMask),
    MODIFIER(Cmd,	NSCommandKeyMask),
    MODIFIER(Meta,	NSCommandKeyMask),
    {NULL, 0, 0}
};
#undef MODIFIER

#define ACCEL(n, c) {.name = #n, .len = sl(#n), .ch = c }
static const struct {
    const char *name; size_t len; UniChar ch;
} specialAccelerators[] = {
    ACCEL(PageUp,	NSPageUpFunctionKey),
    ACCEL(PageDown,	NSPageDownFunctionKey),
    ACCEL(Left,		NSLeftArrowFunctionKey),
    ACCEL(Right,	NSRightArrowFunctionKey),
    ACCEL(Up,		NSUpArrowFunctionKey),
    ACCEL(Down,		NSDownArrowFunctionKey),







<
















|




|





|
|









|





|







15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "tkMacOSXPrivate.h"
#include "tkMenubutton.h"
#include "tkMenu.h"
#include "tkColor.h"
#include "tkFont.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXDebug.h"


/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_MENUS
#endif
*/

#define ENTRY_HELP_MENU		ENTRY_PLATFORM_FLAG1
#define ENTRY_APPLE_MENU	ENTRY_PLATFORM_FLAG2
#define ENTRY_WINDOWS_MENU	ENTRY_PLATFORM_FLAG3

#define sl(s) ((int) (sizeof(s "") - 1))

#define SPECIALMENU(n, f) {.name = "." #n, .len = sl(#n) + 1, \
	.flag = ENTRY_##f##_MENU }
static const struct {
    const char *name; const size_t len; const int flag;
} specialMenus[] = {
    SPECIALMENU(help,	HELP),
    SPECIALMENU(apple,	APPLE),
    SPECIALMENU(window,	WINDOWS),
    {NULL}
};
#undef SPECIALMENU

#define MODIFIER(n, f) {.name = #n, .len = sl(#n), .mask = f }
static const struct {
    const char *name; const size_t len; const NSUInteger mask;
} modifiers[] = {
    MODIFIER(Control,	NSControlKeyMask),
    MODIFIER(Ctrl,	NSControlKeyMask),
    MODIFIER(Option,	NSAlternateKeyMask),
    MODIFIER(Opt,	NSAlternateKeyMask),
    MODIFIER(Alt,	NSAlternateKeyMask),
    MODIFIER(Shift,	NSShiftKeyMask),
    MODIFIER(Command,	NSCommandKeyMask),
    MODIFIER(Cmd,	NSCommandKeyMask),
    MODIFIER(Meta,	NSCommandKeyMask),
    {NULL}
};
#undef MODIFIER

#define ACCEL(n, c) {.name = #n, .len = sl(#n), .ch = c }
static const struct {
    const char *name; const size_t len; const UniChar ch;
} specialAccelerators[] = {
    ACCEL(PageUp,	NSPageUpFunctionKey),
    ACCEL(PageDown,	NSPageDownFunctionKey),
    ACCEL(Left,		NSLeftArrowFunctionKey),
    ACCEL(Right,	NSRightArrowFunctionKey),
    ACCEL(Up,		NSUpArrowFunctionKey),
    ACCEL(Down,		NSDownArrowFunctionKey),
82
83
84
85
86
87
88
89
90
91
92
93



94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180








181
182
183
184
185
186
187
    ACCEL(Delete,	NSDeleteCharacter),
    ACCEL(Home,		NSHomeFunctionKey),
    ACCEL(End,		NSEndFunctionKey),
    ACCEL(Return,	NSCarriageReturnCharacter),
    ACCEL(Help,		NSHelpFunctionKey),
    ACCEL(Power,	0x233d),
    ACCEL(Eject,	0xf804),
    {NULL, 0, 0}
};
#undef ACCEL
#undef sl




static int inPostMenu = 0;

static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
static SInt16 menuSeparatorHeight = 0;

static void	CheckForSpecialMenu(TkMenu *menuPtr);
static NSString *ParseAccelerator(const char *accel, NSUInteger *maskPtr);
static int	GenerateMenuSelectEvent(TKMenu *menu, NSMenuItem *menuItem);
static void	MenuSelectEvent(TkMenu *menuPtr);
static void	RecursivelyClearActiveMenu(TkMenu *menuPtr);
static int	ModifierCharWidth(Tk_Font tkfont);

#pragma mark TkBackgroundLoop

/*
 * The function TkMacOSXEventsCheckProc (in tkMacOSXNotify.c) is the "check
 * proc" for the macOS event source.  Its job is to remove NSEvents from the
 * default event queue of the NSApplication.  It does this by calling the
 * method [NSApp nextEventMatchingMask: untilDate: inMode: dequeue:]. As a
 * rule, when the untilDate is set to the distant past this method returns
 * immediately.  An exception to that rule is when the next event is the button
 * press on a menu button.  In that case, the method starts running a nested
 * event loop in the mode NSEventTrackingRunLoopMode which does not return
 * until the menu has been dismissed.  In Tk 8.6.10 and earlier, this meant
 * that the Tk event loop would block in its call to the check proc as long as
 * the menu was posted.  For example, opening a menu during the Rube Goldberg
 * demo would cause the animation to stop.  This was also the case for
 * menubuttons.
 *
 * The TKBackground object below works around this problem, and allows a Tk
 * event loop to run while a menu is open.  It is a subclass of NSThread which
 * inserts requests to call [NSApp _runBackgroundLoop] onto the queue
 * associated with the NSEventTrackingRunLoopMode.  One of these threads gets
 * started in the callback [NSApp menuBeginTracking] and cancelled in [NSApp
 * menuEndTracking].
 */

@interface TKBackgroundLoop: NSThread
@end

@implementation TKBackgroundLoop
- (void) main
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    NSArray *modeArray = [NSArray arrayWithObjects: NSEventTrackingRunLoopMode,
				  nil];
    while(1) {

	/*
	 * Queue a request to process Tk events during event tracking.
	 */

	[NSApp performSelectorOnMainThread:@selector(_runBackgroundLoop)
				withObject:nil
			     waitUntilDone:true
				     modes:modeArray];
	if ([self isCancelled]) {
	    [NSThread exit];
	}

	/*
	 * Allow the tracked events to be processed too.
	 */

	[NSThread sleepForTimeInterval:0.001];
    }
    [pool drain];
}
@end

TKBackgroundLoop *backgroundLoop = nil;


#pragma mark TKMenu

/*
 * This interface is not declared in tkMacOSXPrivate.h because it requires
 * tkMenu.h.
 */

@interface TKMenu(TKMenuPrivate)
- (id) initWithTkMenu: (TkMenu *) tkMenu;
- (TkMenu *) tkMenu;
- (int) tkIndexOfItem: (NSMenuItem *) menuItem;
- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index;
@end









@implementation TKMenu
- (void) setSpecial: (NSUInteger) special
{
    NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
    _tkSpecial = special;
}







|




>
>
>

>












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<






>
>
>
>
>
>
>
>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109





























































110
111





112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    ACCEL(Delete,	NSDeleteCharacter),
    ACCEL(Home,		NSHomeFunctionKey),
    ACCEL(End,		NSEndFunctionKey),
    ACCEL(Return,	NSCarriageReturnCharacter),
    ACCEL(Help,		NSHelpFunctionKey),
    ACCEL(Power,	0x233d),
    ACCEL(Eject,	0xf804),
    {NULL}
};
#undef ACCEL
#undef sl

static int gNoTkMenus = 0;	/* This is used by Tk_MacOSXTurnOffMenus as
				 * the flag that Tk is not to draw any
				 * menus. */
static int inPostMenu = 0;
static unsigned long defaultBg = 0, defaultFg = 0;
static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
static SInt16 menuSeparatorHeight = 0;

static void	CheckForSpecialMenu(TkMenu *menuPtr);
static NSString *ParseAccelerator(const char *accel, NSUInteger *maskPtr);
static int	GenerateMenuSelectEvent(TKMenu *menu, NSMenuItem *menuItem);
static void	MenuSelectEvent(TkMenu *menuPtr);
static void	RecursivelyClearActiveMenu(TkMenu *menuPtr);
static int	ModifierCharWidth(Tk_Font tkfont);






























































#pragma mark TKMenu






@interface TKMenu(TKMenuPrivate)
- (id) initWithTkMenu: (TkMenu *) tkMenu;
- (TkMenu *) tkMenu;
- (int) tkIndexOfItem: (NSMenuItem *) menuItem;
- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index;
@end

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
#define TKMenu_NSMenuDelegate <NSMenuDelegate>
#else
#define TKMenu_NSMenuDelegate
#endif
@interface TKMenu(TKMenuDelegate) TKMenu_NSMenuDelegate
@end

@implementation TKMenu
- (void) setSpecial: (NSUInteger) special
{
    NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
    _tkSpecial = special;
}
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342






343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455




456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492




493
494
495
496
497
498
499
    [super insertItem:newItem atIndex:index + _tkOffset];
    _tkItemCount++;
}

- (void) insertItem: (NSMenuItem *) newItem atIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger) index <= _tkOffset) {
	    _tkOffset++;
	} else {
	    NSAssert((NSUInteger) index >= _tkItemCount + _tkOffset,
		    @"Cannot insert in the middle of Tk menu");
	}
    }
    [super insertItem:newItem atIndex:index];
}

- (void) removeItemAtIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger) index < _tkOffset) {
	    _tkOffset--;
	} else if ((NSUInteger) index < _tkItemCount + _tkOffset) {
	    _tkItemCount--;
	}
    }
    [super removeItemAtIndex:index];
}

- (NSMenuItem *) newTkMenuItem: (TkMenuEntry *) mePtr
{
    NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@""
	    action:@selector(tkMenuItemInvoke:) keyEquivalent:@""];

    [menuItem setTarget:self];
    [menuItem setTag:(NSInteger) mePtr];
    return menuItem;
}
@end

@implementation TKMenu(TKMenuActions)


- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
{
    return [menuItem isEnabled];
}

/*
 * Workaround for bug 3572016; leave menu items enabled during modal dialog.
 */

- (BOOL)worksWhenModal
{
    return YES;
}

- (void) tkMenuItemInvoke: (id) sender
{
    /*
     * With the delegate matching key equivalents, when a menu action is sent
     * in response to a key equivalent, the sender is the whole menu and not the
     * specific menu item.  We use this to ignore key equivalents for Tk
     * menus (as Tk handles them directly via bindings).
     */

    if ([sender isKindOfClass:[NSMenuItem class]]) {
	NSMenuItem *menuItem = (NSMenuItem *) sender;
	TkMenu *menuPtr = (TkMenu *) _tkMenu;
	TkMenuEntry *mePtr = (TkMenuEntry *) [menuItem tag];

	if (menuPtr && mePtr) {
	    Tcl_Interp *interp = menuPtr->interp;

	    /*
	     * Add time for errors to fire if necessary. This is sub-optimal
	     * but avoids issues with Tcl/Cocoa event loop integration.
	     */

	    //Tcl_Sleep(100);
	    Tcl_Preserve(interp);
	    Tcl_Preserve(menuPtr);

	    int result = TkInvokeMenu(interp, menuPtr, mePtr->index);

	    if (result != TCL_OK && result != TCL_CONTINUE &&
		    result != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(menuPtr);
	    Tcl_Release(interp);
	}
    }
}
@end

@implementation TKMenu(TKMenuDelegate)







- (BOOL) menuHasKeyEquivalent: (NSMenu *) menu forEvent: (NSEvent *) event
	target: (id *) target action: (SEL *) action
{
    (void)menu;

    /*
     * Use lowercaseString when comparing keyEquivalents since the notion of
     * a shifted upper case letter does not make much sense.
     */

    NSString *key = [[event charactersIgnoringModifiers] lowercaseString];
    NSUInteger modifiers = [event modifierFlags] &
	    NSDeviceIndependentModifierFlagsMask;

    if (modifiers == (NSCommandKeyMask | NSShiftKeyMask) &&
	    [key compare:@"?"] == NSOrderedSame) {
	/*
	 * Command-Shift-? has not been allowed as a keyboard equivalent since
	 * the first aqua port, for some mysterious reason.
	 */

	return NO;
    } else if (modifiers == (NSControlKeyMask | NSShiftKeyMask) &&
	    [event keyCode] == 48) {
	/*
	 * Starting with OSX 10.12 Control-Tab and Control-Shift-Tab are used
	 * to select window tabs.  But for some even more mysterious reason the
	 * Control-Shift-Tab event has character 0x19 = NSBackTabCharacter
	 * rather than 0x09 = NSTabCharacter.  At the same time, the
	 * keyEquivalent must be \0x09 in order for it to be displayed
	 * correctly in the menu. This makes it impossible for the standard
	 * "Select Previous Tab" to work correctly, unless we intervene.
	 */

	key = @"\t";
    } else if (([event modifierFlags] & NSCommandKeyMask) == NSCommandKeyMask) {
	/*
	 * If the command modifier is set, use the full character string so
	 * things like the dvorak / qwerty layout will work.
	 */

	key = [event characters];
    }

    NSArray *itemArray = [self itemArray];

    for (NSMenuItem *item in itemArray) {
	if ([item isEnabled] &&
	    [[item keyEquivalent] compare:key] == NSOrderedSame) {
	    NSUInteger keyEquivModifiers = [item keyEquivalentModifierMask];

	    if (keyEquivModifiers == modifiers) {
		*target = [item target];
		*action = [item action];
		return YES;
	    }
	}
    }
    return NO;
}

- (void) menuWillOpen: (NSMenu *) menu
{
    (void)menu;

    if (_tkMenu) {
	//RecursivelyClearActiveMenu(_tkMenu);
	GenerateMenuSelectEvent((TKMenu *)[self supermenu],
		[self itemInSupermenu]);
    }
}

- (void) menuDidClose: (NSMenu *) menu
{
    (void)menu;

    if (_tkMenu) {
	RecursivelyClearActiveMenu(_tkMenu);
    }
}

- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
{
    (void)menu;

    if (_tkMenu) {
	GenerateMenuSelectEvent(self, item);
    }
}

- (void) menuNeedsUpdate: (NSMenu *) menu
{
    TkMenu *menuPtr = (TkMenu *) _tkMenu;
    (void)menu;

    if (menuPtr) {
	Tcl_Interp *interp = menuPtr->interp;

	Tcl_Preserve(interp);
	Tcl_Preserve(menuPtr);

	int result = TkPostCommand(_tkMenu);

	if (result!=TCL_OK && result!=TCL_CONTINUE && result!=TCL_BREAK) {
	      Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
	      Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(menuPtr);
	Tcl_Release(interp);
    }
}
@end

#pragma mark TKApplication(TKMenu)





@implementation TKApplication(TKMenu)

- (void) menuBeginTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
    }
    backgroundLoop = [[TKBackgroundLoop alloc] init];
    [backgroundLoop start];
    //TkMacOSXClearMenubarActive();
    //TkMacOSXPreprocessMenu();
}

- (void) menuEndTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
	backgroundLoop = nil;
    }
    if (!inPostMenu) {
	TkMacOSXClearMenubarActive();
    }
}

- (void) tkSetMainMenu: (TKMenu *) menu
{




    TKMenu *applicationMenu = nil;

    if (menu) {
	NSMenuItem *applicationMenuItem = [menu numberOfItems] ?
		[menu itemAtIndex:0] : nil;

	if (![menu isSpecial:tkMainMenu]) {







|


|









|

|












|





>






<
|
<
<









|
|




|
|
|



<
<
|
|

<
|








|









>
>
>
>
>
>




<
|
<
<
<
<
<






<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
|
<
|
|



>

|
|

>
|











<
<









<
<







<
<








<











|








>
>
>
>





<



<
<
<
<
<
<






<



<
<
<
<
<







>
>
>
>







191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239


240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260


261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293





294
295
296
297
298
299





300











301
302


303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328
329
330
331
332
333
334
335
336


337
338
339
340
341
342
343


344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383






384
385
386
387
388
389

390
391
392





393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    [super insertItem:newItem atIndex:index + _tkOffset];
    _tkItemCount++;
}

- (void) insertItem: (NSMenuItem *) newItem atIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger)index <= _tkOffset) {
	    _tkOffset++;
	} else {
	    NSAssert((NSUInteger)index >= _tkItemCount + _tkOffset,
		    @"Cannot insert in the middle of Tk menu");
	}
    }
    [super insertItem:newItem atIndex:index];
}

- (void) removeItemAtIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger)index < _tkOffset) {
	    _tkOffset--;
	} else if ((NSUInteger)index < _tkItemCount + _tkOffset) {
	    _tkItemCount--;
	}
    }
    [super removeItemAtIndex:index];
}

- (NSMenuItem *) newTkMenuItem: (TkMenuEntry *) mePtr
{
    NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@""
	    action:@selector(tkMenuItemInvoke:) keyEquivalent:@""];

    [menuItem setTarget:self];
    [menuItem setTag:(NSInteger)mePtr];
    return menuItem;
}
@end

@implementation TKMenu(TKMenuActions)
// target methods

- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
{
    return [menuItem isEnabled];
}


// Workaround for bug 3572016; leaves menu items enabled during modal dialog.


- (BOOL)worksWhenModal
{
    return YES;
}

- (void) tkMenuItemInvoke: (id) sender
{
    /*
     * With the delegate matching key equivalents, when a menu action is sent
     * in response to a key equivalent, sender is the whole menu and not the
     * the specific menu item, use this to ignore key equivalents for our
     * menus (as Tk handles them directly via bindings).
     */

    if ([sender isKindOfClass:[NSMenuItem class]]) {
	NSMenuItem *menuItem = (NSMenuItem *)sender;
	TkMenu *menuPtr = (TkMenu *)_tkMenu;
	TkMenuEntry *mePtr = (TkMenuEntry *)[menuItem tag];

	if (menuPtr && mePtr) {
	    Tcl_Interp *interp = menuPtr->interp;


	    /*Add time for errors to fire if necessary. This is sub-optimal
	     *but avoids issues with Tcl/Cocoa event loop integration.
	     */

	    Tcl_Sleep(100);
	    Tcl_Preserve(interp);
	    Tcl_Preserve(menuPtr);

	    int result = TkInvokeMenu(interp, menuPtr, mePtr->index);

	    if (result != TCL_OK && result != TCL_CONTINUE &&
		    result != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundError(interp);
	    }
	    Tcl_Release(menuPtr);
	    Tcl_Release(interp);
	}
    }
}
@end

@implementation TKMenu(TKMenuDelegate)
#define keyEquivModifiersMatch(km, m) (( \
    ((km) & NSCommandKeyMask) != ((m) & NSCommandKeyMask) || \
    ((km) & NSAlternateKeyMask) != ((m) & NSAlternateKeyMask) || \
    ((km) & NSControlKeyMask) != ((m) & NSControlKeyMask) || \
    (((km) & NSShiftKeyMask) != ((m) & NSShiftKeyMask) && \
    ((m) & NSFunctionKeyMask))) ? NO : YES)

- (BOOL) menuHasKeyEquivalent: (NSMenu *) menu forEvent: (NSEvent *) event
	target: (id *) target action: (SEL *) action
{

    /*Use lowercaseString to keep "shift" from firing twice if bound to different procedure.*/





    NSString *key = [[event charactersIgnoringModifiers] lowercaseString];
    NSUInteger modifiers = [event modifierFlags] &
	    NSDeviceIndependentModifierFlagsMask;

    if (modifiers == (NSCommandKeyMask | NSShiftKeyMask) &&
	    [key compare:@"?"] == NSOrderedSame) {





	return NO;











    }



    // For command key, take input manager's word so things
    // like dvorak / qwerty layout work.

    if (([event modifierFlags] & NSCommandKeyMask) == NSCommandKeyMask) {
      key = [event characters];
    }

    NSArray *itemArray = [self itemArray];

    for (NSMenuItem *item in itemArray) {
	if ([item isEnabled] && [[item keyEquivalent] compare:key] ==
		NSOrderedSame) {
	    NSUInteger keyEquivModifiers = [item keyEquivalentModifierMask];

	    if (keyEquivModifiersMatch(keyEquivModifiers, modifiers)) {
		*target = [item target];
		*action = [item action];
		return YES;
	    }
	}
    }
    return NO;
}

- (void) menuWillOpen: (NSMenu *) menu
{


    if (_tkMenu) {
	//RecursivelyClearActiveMenu(_tkMenu);
	GenerateMenuSelectEvent((TKMenu *)[self supermenu],
		[self itemInSupermenu]);
    }
}

- (void) menuDidClose: (NSMenu *) menu
{


    if (_tkMenu) {
	RecursivelyClearActiveMenu(_tkMenu);
    }
}

- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
{


    if (_tkMenu) {
	GenerateMenuSelectEvent(self, item);
    }
}

- (void) menuNeedsUpdate: (NSMenu *) menu
{
    TkMenu *menuPtr = (TkMenu *) _tkMenu;


    if (menuPtr) {
	Tcl_Interp *interp = menuPtr->interp;

	Tcl_Preserve(interp);
	Tcl_Preserve(menuPtr);

	int result = TkPostCommand(_tkMenu);

	if (result!=TCL_OK && result!=TCL_CONTINUE && result!=TCL_BREAK) {
	      Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
	      Tcl_BackgroundError(interp);
	}
	Tcl_Release(menuPtr);
	Tcl_Release(interp);
    }
}
@end

#pragma mark TKApplication(TKMenu)

@interface NSApplication(TKMenu)
- (void) setAppleMenu: (NSMenu *) menu;
@end

@implementation TKApplication(TKMenu)

- (void) menuBeginTracking: (NSNotification *) notification
{

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif






    //TkMacOSXClearMenubarActive();
    //TkMacOSXPreprocessMenu();
}

- (void) menuEndTracking: (NSNotification *) notification
{

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif





    if (!inPostMenu) {
	TkMacOSXClearMenubarActive();
    }
}

- (void) tkSetMainMenu: (TKMenu *) menu
{
    if (gNoTkMenus) {
	return;
    }

    TKMenu *applicationMenu = nil;

    if (menu) {
	NSMenuItem *applicationMenuItem = [menu numberOfItems] ?
		[menu itemAtIndex:0] : nil;

	if (![menu isSpecial:tkMainMenu]) {
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
    NSImage *image = nil;
    NSString *keyEquivalent = @"";
    NSUInteger modifierMask = NSCommandKeyMask;
    NSMenu *submenu = nil;
    NSDictionary *attributes;
    int imageWidth, imageHeight;
    GC gc = (mePtr->textGC ? mePtr->textGC : mePtr->menuPtr->textGC);
    Tcl_Obj *fontPtr = (mePtr->fontPtr ?
			mePtr->fontPtr : mePtr->menuPtr->fontPtr);
    static unsigned long defaultBg, defaultFg;
    static int initialized = 0;

    if (!initialized) {
	TkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
	defaultBg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
	tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
	defaultFg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
    }

    if (mePtr->image) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	image = TkMacOSXGetNSImageFromTkImage(mePtr->menuPtr->display,
		mePtr->image, imageWidth, imageHeight);
    } else if (mePtr->bitmapPtr != None) {
	Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
		mePtr->bitmapPtr);

	Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
		&imageHeight);
	image = TkMacOSXGetNSImageFromBitmap(mePtr->menuPtr->display, bitmap,
		gc, imageWidth, imageHeight);
	if (gc->foreground == defaultFg) {
	    [image setTemplate:YES];
	}
    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {
	title = [[[NSString alloc] initWithBytes:Tcl_GetString(mePtr->labelPtr)
		length:mePtr->labelLength encoding:NSUTF8StringEncoding]
		autorelease];







|
|
<
<
<
<
<
<
<
<
<
<
<



|







|

<
<
<







595
596
597
598
599
600
601
602
603











604
605
606
607
608
609
610
611
612
613
614
615
616



617
618
619
620
621
622
623
    NSImage *image = nil;
    NSString *keyEquivalent = @"";
    NSUInteger modifierMask = NSCommandKeyMask;
    NSMenu *submenu = nil;
    NSDictionary *attributes;
    int imageWidth, imageHeight;
    GC gc = (mePtr->textGC ? mePtr->textGC : mePtr->menuPtr->textGC);
    Tcl_Obj *fontPtr = (mePtr->fontPtr ? mePtr->fontPtr :
	    mePtr->menuPtr->fontPtr);












    if (mePtr->image) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	image = TkMacOSXGetNSImageWithTkImage(mePtr->menuPtr->display,
		mePtr->image, imageWidth, imageHeight);
    } else if (mePtr->bitmapPtr != None) {
	Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
		mePtr->bitmapPtr);

	Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
		&imageHeight);
	image = TkMacOSXGetNSImageWithBitmap(mePtr->menuPtr->display, bitmap,
		gc, imageWidth, imageHeight);



    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {
	title = [[[NSString alloc] initWithBytes:Tcl_GetString(mePtr->labelPtr)
		length:mePtr->labelLength encoding:NSUTF8StringEncoding]
		autorelease];
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
	attributes = TkMacOSXNSFontAttributesForFont(Tk_GetFontFromObj(
		mePtr->menuPtr->tkwin, fontPtr));
	if (gc->foreground != defaultFg || gc->background != defaultBg) {
	    NSColor *color = TkMacOSXGetNSColor(gc,
		    gc->foreground!=defaultFg? gc->foreground:gc->background);

	    attributes = [[attributes mutableCopy] autorelease];
	    [(NSMutableDictionary *) attributes setObject:color
		    forKey:NSForegroundColorAttributeName];
	}
	if (attributes) {
	    attributedTitle = [[[NSAttributedString alloc]
		    initWithString:title attributes:attributes] autorelease];
	}
    }







|







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
	attributes = TkMacOSXNSFontAttributesForFont(Tk_GetFontFromObj(
		mePtr->menuPtr->tkwin, fontPtr));
	if (gc->foreground != defaultFg || gc->background != defaultBg) {
	    NSColor *color = TkMacOSXGetNSColor(gc,
		    gc->foreground!=defaultFg? gc->foreground:gc->background);

	    attributes = [[attributes mutableCopy] autorelease];
	    [(NSMutableDictionary *)attributes setObject:color
		    forKey:NSForegroundColorAttributeName];
	}
	if (attributes) {
	    attributedTitle = [[[NSAttributedString alloc]
		    initWithString:title attributes:attributes] autorelease];
	}
    }
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

810
811
812
813
814
815
816
		 */

		submenu = nil;
	    } else {
		[submenu setTitle:title];

    		if ([menuItem isEnabled]) {

		    /*
		     * This menuItem might have been previously disabled (XXX:
		     * track this), which would have disabled entries; we must
		     * re-enable the entries here.
		     */

		    int i = 0;
		    NSArray *itemArray = [submenu itemArray];

		    for (NSMenuItem *item in itemArray) {
			TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];

			/*
			 * Work around an apparent bug where itemArray can have
			 * more items than the menu's entries[] array.
			 */

			if (i >= (int) menuRefPtr->menuPtr->numEntries) {
			    break;
			}
			[item setEnabled: !(submePtr->state == ENTRY_DISABLED)];
			i++;
		    }
		}
	    }
	}
    }

    [menuItem setSubmenu:submenu];

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







<
<
|
|
|
<
<
|
|
<
|
|
<
<
|
|
<
<
|
<
<
|
|
|




>







672
673
674
675
676
677
678


679
680
681


682
683

684
685


686
687


688


689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
		 */

		submenu = nil;
	    } else {
		[submenu setTitle:title];

    		if ([menuItem isEnabled]) {


		  /* This menuItem might have been previously disabled (XXX:
		     track this), which would have disabled entries; we must
		     re-enable the entries here. */


		  int i = 0;
		  NSArray *itemArray = [submenu itemArray];

		  for (NSMenuItem *item in itemArray) {
		      TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];


		        /* Work around an apparent bug where itemArray can have
                      more items than the menu's entries[] array. */


                    if (i >= menuRefPtr->menuPtr->numEntries) break;


		      [item setEnabled: !(submePtr->state == ENTRY_DISABLED)];
		    i++;		      
		  }
		}
	    }
	}
    }
 
    [menuItem setSubmenu:submenu];

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903

904





905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen. If entry is < 0 then the menu is drawn so
 *      its top left corner is located at the point with screen coordinates
 *      (x,y).  Otherwise the top left corner of the specified entry is located
 *      at that point.
 *
 * Results:
 *	Returns a standard Tcl result.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y,		/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
    int index)
{
    int result;
    Tk_Window realWin = menuPtr->tkwin;

    TkWindow *realWinPtr;
    NSView *realWinView;

    while (1) {
	if (realWin == NULL) {
	    return TCL_ERROR;
	}
	/*
	 * Fix for bug 07cfc9f03e: use the view for the parent real (non-menu)
	 * toplevel window, rather than always using the root window.
	 * This allows menus to appear on a separate monitor than the root
	 * window, and to use the appearance of their parent real window
	 * rather than the appearance of the root window.
	 */
	realWinPtr = (TkWindow*) realWin;
	realWinView = TkMacOSXGetNSViewForDrawable(realWinPtr->privatePtr);
	if (realWinView != nil) {
	    break;
	}
	realWin = Tk_Parent(realWin);
    }
    NSWindow *win = [realWinView window];

    NSView *view = [win contentView];





    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSInteger itemIndex = index;
    NSInteger numItems = [menu numberOfItems];
    NSMenuItem *item = nil;
    NSPoint location = NSMakePoint(x, TkMacOSXZeroScreenHeight() - y);

    inPostMenu = 1;
    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = 0;
        return result;
    }
    if (itemIndex >= numItems) {
    	itemIndex = numItems - 1;
    }
    if (itemIndex >= 0) {
	item = [menu itemAtIndex:itemIndex];
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    [menu popUpMenuPositioningItem:item
			atLocation:[win tkConvertPointFromScreen:location]
			    inView:view];
    inPostMenu = 0;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --
 *
 *	Tearoff menus are not supported on the Mac.  This placeholder function,
 *      which is simply a copy of the unix function, posts a completely useless
 *      window with a black background on the screen. If entry is < 0 then the
 *      window is positioned so that its top left corner is located at the
 *      point with screen coordinates (x, y).  Otherwise the window position is
 *      offset so that top left corner of the specified entry would be located
 *      at that point, if there actually were a menu.
 *
 *      Mac menus steal all mouse or keyboard input from the application until
 *      the menu is dismissed, with or without a selection, by a mouse or key
 *      event.  Posting a Mac menu in a regression test will cause the test to
 *      halt waiting for user input.  This is why the TkpPostMenu function is
 *      not being used as the placeholder.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A useless window is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),	/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;

    if (index >= (int) menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * 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.
     */

    Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
	&vRootWidth, &vRootHeight);
    vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
    if (x > vRootX + vRootWidth) {
	x = vRootX + vRootWidth;
    }
    if (x < vRootX) {
	x = vRootX;
    }
    vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
    if (y > vRootY + vRootHeight) {
	y = vRootY + vRootHeight;
    }
    if (y < vRootY) {
	y = vRootY;
    }
    Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
    if (!Tk_IsMapped(menuPtr->tkwin)) {
	Tk_MapWindow(menuPtr->tkwin);
    }
    TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetWindowMenuBar --







|
<
<
<


|









|

|
|
|
|

|
|
>
|
<
|
<
|
|
|
|
<
<
<
<
<
<
|
|
|
<
|
|
|
<
>

>
>
>
>
>

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







737
738
739
740
741
742
743
744



745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767

768

769
770
771
772






773
774
775

776
777
778

779
780
781
782
783
784
785
786




787












788



















































789


790






791






792




793



794
















795







796













797
798
799
800
801
802
803
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen



 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,		/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x,			/* The global x-coordinate of the top, left-
				 * hand corner of where the menu is supposed
				 * to be posted. */
    int y)			/* The global y-coordinate */
{
 

    /* Get the object that holds this Tk Window.*/
    Tk_Window root;

    root = Tk_MainWindow(interp);

    if (root == NULL) {
	return TCL_ERROR;
    }
 






    Drawable d = Tk_WindowId(root);
    NSView *rootview = TkMacOSXGetRootControl(d);
    NSWindow *win = [rootview window];

 
    inPostMenu = 1;


    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    NSView *view = [win contentView];
    NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);

    frame.origin = [view convertPoint:
	    [win convertPointFromScreen:frame.origin] fromView:nil];

    NSMenu *menu = (NSMenu *) menuPtr->platformData;




    NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]












	    initTextCell:@"" pullsDown:NO];






















































    [popUpButtonCell setAltersStateOfSelectedItem:NO];






    [popUpButtonCell setMenu:menu];






    [popUpButtonCell selectItem:nil];




    [popUpButtonCell performClickWithFrame:frame inView:view];



    [popUpButtonCell release];
















    Tcl_SetServiceMode(oldMode);







    inPostMenu = 0;













    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetWindowMenuBar --
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only be
 *	called when the window is in front.
 *
 *      This is a no-op on all other platforms.  On OS X it is a no-op when
 *      passed a NULL menuName or a nonexistent menuName, with an exception for
 *      the first call in a new interpreter.  In that special case, passing a
 *      NULL menuName installs the default menu.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar may be changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. */
{
    static Tcl_Interp *currentInterp = NULL;
    TKMenu *menu = nil;
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * We will be called when an embedded window receives an ActivationNotify
     * event, but we should not change the menubar in that case.
     */

    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    if (menuName) {
	Tk_Window menubar = NULL;

	if (winPtr->wmInfoPtr &&
		winPtr->wmInfoPtr->menuPtr &&
		winPtr->wmInfoPtr->menuPtr->mainMenuPtr) {
	    menubar = winPtr->wmInfoPtr->menuPtr->mainMenuPtr->tkwin;
	}

	/*
	 * Attempt to find the NSMenu directly.  If that fails, ask Tk to find
	 * it.
	 */

	if (menubar != NULL && strcmp(menuName, Tk_PathName(menubar)) == 0) {
	    menu = (TKMenu *) winPtr->wmInfoPtr->menuPtr->platformData;
	} else {
	    TkMenuReferences *menuRefPtr = TkFindMenuReferences(interp,
		    menuName);

	    if (menuRefPtr && menuRefPtr->menuPtr &&
		    menuRefPtr->menuPtr->platformData) {
		menu = (TKMenu *) menuRefPtr->menuPtr->platformData;
	    }
	}
    }

    /*
     * If we couldn't find a menu, do nothing unless the window belongs to a
     * different application.  In that case, install the default menubar.
     */

    if (menu || interp != currentInterp) {
	[NSApp tkSetMainMenu:menu];
    }
    currentInterp = interp;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckForSpecialMenu --
 *
 *	Given a menu, check to see whether or not it is a cascade in a menubar
 *	with one of the special names ".apple", ".help" or ".window". If it is,
 *	the entry that points to this menu will be marked.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will set entryFlags appropriately.
 *
 *----------------------------------------------------------------------
 */

static void
CheckForSpecialMenu(
    TkMenu *menuPtr)		/* The menu we are checking */
{
    if (!menuPtr->mainMenuPtr->tkwin) {
	return;
    }
    for (TkMenuEntry *cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
		&& cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    int i = 0;
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, Tk_PathName(mainMenuPtr->tkwin), -1);
	    while (specialMenus[i].name) {
		Tcl_DStringAppend(&ds, specialMenus[i].name,
			specialMenus[i].len);
		if (strcmp(Tcl_DStringValue(&ds),
			Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		    cascadeEntryPtr->entryFlags |= specialMenus[i].flag;
		} else {
		    cascadeEntryPtr->entryFlags &= ~specialMenus[i].flag;
		}
		Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) -
			specialMenus[i].len);
		i++;







|
|


|
|










|




|



<

<
<
<
<
<
<
<
<
<

|

|
|
|
<
<
|
<
<
<
<
|
<











<
<
<
<
<
<












|
|














|






|
|




|




|







827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858

859









860
861
862
863
864
865


866




867

868
869
870
871
872
873
874
875
876
877
878






879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only
 *	be called when the window is in front.
 *
 *      This is a no-op on all other platforms.  On OS X it is a no-op when
 *      passed a NULL menuName or a nonexistent menuName, with an exception
 *      for the first call in a new interpreter.  In that special case, passing a
 *      NULL menuName installs the default menu.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar may be changed.
 *
 *----------------------------------------------------------------------
 */
 
void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    char *menuName)	/* The name of the menu to put in front.*/
{
    static Tcl_Interp *currentInterp = NULL;
    TKMenu *menu = nil;











    if (menuName) {
	TkWindow *winPtr = (TkWindow *) tkwin;

	if (winPtr->wmInfoPtr && winPtr->wmInfoPtr->menuPtr &&
		winPtr->wmInfoPtr->menuPtr->masterMenuPtr &&
		winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin &&


		!strcmp(menuName, Tk_PathName(




		winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin))) {

	    menu = (TKMenu *) winPtr->wmInfoPtr->menuPtr->platformData;
	} else {
	    TkMenuReferences *menuRefPtr = TkFindMenuReferences(interp,
		    menuName);

	    if (menuRefPtr && menuRefPtr->menuPtr &&
		    menuRefPtr->menuPtr->platformData) {
		menu = (TKMenu *) menuRefPtr->menuPtr->platformData;
	    }
	}
    }






    if (menu || interp != currentInterp) {
	[NSApp tkSetMainMenu:menu];
    }
    currentInterp = interp;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckForSpecialMenu --
 *
 *	Given a menu, check to see whether or not it is a cascade in a menubar
 *	with one of the special names .apple, .help or .window If it is, the
 *	entry that points to this menu will be marked.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will set entryFlags appropriately.
 *
 *----------------------------------------------------------------------
 */

static void
CheckForSpecialMenu(
    TkMenu *menuPtr)		/* The menu we are checking */
{
    if (!menuPtr->masterMenuPtr->tkwin) {
	return;
    }
    for (TkMenuEntry *cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
		&& cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin) {
	    TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
	    int i = 0;
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, Tk_PathName(masterMenuPtr->tkwin), -1);
	    while (specialMenus[i].name) {
		Tcl_DStringAppend(&ds, specialMenus[i].name,
			specialMenus[i].len);
		if (strcmp(Tcl_DStringValue(&ds),
			Tk_PathName(menuPtr->masterMenuPtr->tkwin)) == 0) {
		    cascadeEntryPtr->entryFlags |= specialMenus[i].flag;
		} else {
		    cascadeEntryPtr->entryFlags &= ~specialMenus[i].flag;
		}
		Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) -
			specialMenus[i].len);
		i++;
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
    unichar ch = 0;
    size_t len;
    int i;

    *maskPtr = 0;
    while (1) {
	i = 0;
	while (allModifiers[i].name) {
	    int l = allModifiers[i].len;

	    if (!strncasecmp(accel, allModifiers[i].name, l) &&
		    (accel[l] == '-' || accel[l] == '+')) {
		*maskPtr |= allModifiers[i].mask;
		accel += l+1;
		break;
	    }
	    i++;
	}
	if (!allModifiers[i].name || !*accel) {
	    break;
	}
    }
    len = strlen(accel);
    if (len > 1) {
	i = 0;
	if (accel[0] == 'F' && len < 4 && accel[1] > '0' && accel[1] <= '9') {







|
|

|

|





|







960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
    unichar ch = 0;
    size_t len;
    int i;

    *maskPtr = 0;
    while (1) {
	i = 0;
	while (modifiers[i].name) {
	    int l = modifiers[i].len;

	    if (!strncasecmp(accel, modifiers[i].name, l) &&
		    (accel[l] == '-' || accel[l] == '+')) {
		*maskPtr |= modifiers[i].mask;
		accel += l+1;
		break;
	    }
	    i++;
	}
	if (!modifiers[i].name || !*accel) {
	    break;
	}
    }
    len = strlen(accel);
    if (len > 1) {
	i = 0;
	if (accel[0] == 'F' && len < 4 && accel[1] > '0' && accel[1] <= '9') {
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399


















1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438


1439

1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495


1496










1497



1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
 *--------------------------------------------------------------
 */

void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    NSSize menuSize;
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int modifierCharWidth, menuModifierCharWidth;
    int x, y, modifierWidth, labelWidth, indicatorSpace;
    int windowWidth, windowHeight, accelWidth;
    int i, maxWidth;
    int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
    TkMenuEntry *mePtr;
    int haveAccel = 0;

    /*
     * Do nothing if this menu is a clone.
     */

    if (menuPtr->tkwin == NULL || menuPtr->mainMenuPtr != menuPtr) {
	return;
    }

    menuSize = [(NSMenu *) menuPtr->platformData size];
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    x = y = borderWidth;
    windowHeight = maxWidth = 0;
    maxIndicatorSpace = 0;

    /*
     * On the Mac especially, getting font metrics can be quite slow, so we
     * want to do it intelligently. We are going to precalculate them and pass
     * them down to all of the measuring and drawing routines. We will measure
     * the font metrics of the menu once. If an entry does not have its own
     * font set, then we give the geometry/drawing routines the menu's font and
     * metrics. If an entry has its own font, we will measure that font and
     * give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    menuModifierCharWidth = ModifierCharWidth(menuFont);

    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == CASCADE_ENTRY || mePtr->accelLength > 0) {
	    haveAccel = 1;
	    break;
	}
    }

    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == TEAROFF_ENTRY) {
	    continue;
	}
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	    modifierCharWidth = menuModifierCharWidth;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
	    fmPtr = &entryMetrics;
	    modifierCharWidth = ModifierCharWidth(tkfont);
	}


















	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
	} else {
	    /*
	     * For each entry, compute the height required by that particular
	     * entry, plus three widths: the width of the label, the width to
	     * allow for an indicator to be displayed to the left of the label
	     * (if any), and the width of the accelerator to be displayed to
	     * the right of the label (if any). These sizes depend, of course,
	     * on the type of the entry.
	     */

	    NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
	    int haveImage = 0, width = 0, height = 0;

	    if (mePtr->image) {
		Tk_SizeOfImage(mePtr->image, &width, &height);
		haveImage = 1;
		height += 2; /* tweak */
	    } else if (mePtr->bitmapPtr) {
		Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin,
			mePtr->bitmapPtr);

		Tk_SizeOfBitmap(menuPtr->display, bitmap, &width, &height);
		haveImage = 1;
		height += 2; /* tweak */
	    }
	    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
		NSAttributedString *attrTitle = [menuItem attributedTitle];
		NSSize size;

		if (attrTitle) {
		    size = [attrTitle size];
		} else {
		    size = [[menuItem title] sizeWithAttributes:
			TkMacOSXNSFontAttributesForFont(tkfont)];
		}
		size.width += menuTextLeadingEdgeMargin + menuTextTrailingEdgeMargin;


		size.height -= 1; /* tweak */

		if (haveImage && (mePtr->compound != COMPOUND_NONE)) {
		    int margin = width + menuIconTrailingEdgeMargin;

		    if (margin > menuTextLeadingEdgeMargin) {
			margin = menuTextLeadingEdgeMargin;
		    }
		    width += size.width + menuIconTrailingEdgeMargin - margin;
		    if (size.height > height) {
			height = size.height;
		    }
		} else {
		    width = size.width;
		    height = size.height;
		}
	    }
	    else {
		/* image only. */
	    }
	    labelWidth = width + menuItemExtraWidth;
	    mePtr->height = height + menuItemExtraHeight;

	    if (mePtr->type == CASCADE_ENTRY) {
		modifierWidth = modifierCharWidth;
	    } else if (mePtr->accelLength == 0) {
		if (haveAccel && !mePtr->hideMargin) {
		    modifierWidth = modifierCharWidth;
		}
	    } else {
		NSUInteger modifMask = [menuItem keyEquivalentModifierMask];
		int j = 0;

		while (allModifiers[j].name) {
		    if (modifMask & allModifiers[j].mask) {
			modifMask &= ~allModifiers[j].mask;
			modifierWidth += modifierCharWidth;
		    }
		    j++;
		}
		accelWidth = [[menuItem keyEquivalent] sizeWithAttributes:
			TkMacOSXNSFontAttributesForFont(tkfont)].width;
	    }
	    if (!mePtr->hideMargin) {
		indicatorSpace = menuMarkColumnWidth;
	    }
	    if (indicatorSpace > maxIndicatorSpace) {
		maxIndicatorSpace = indicatorSpace;
	    }
	    entryWidth = labelWidth + modifierWidth + accelWidth;
	    if (entryWidth > maxWidth) {
		maxWidth = entryWidth;
	    }
	    menuPtr->entries[i]->width = entryWidth;
	    mePtr->height += 2 * activeBorderWidth;
	}
	mePtr->x = x;
	mePtr->y = y;
	y += menuPtr->entries[i]->height + borderWidth;


    }










    windowWidth = menuSize.width;



    if (windowWidth <= 0) {
	windowWidth = 1;
    }
    windowHeight = menuSize.height;
    if (windowHeight <= 0) {
	windowHeight = 1;
    }
    menuPtr->totalWidth = windowWidth;
    menuPtr->totalHeight = windowHeight;
}








<





|

|


<
<
<
<
|



<





|







|
|
|






|







|

<
<
<










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|

















<






<











|
>
>
|
>















<
<
<


>








|

|
|
|


|














<


<


>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>



<







1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078




1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114



1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161

1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198



1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231

1232
1233

1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
 *--------------------------------------------------------------
 */

void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{

    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int modifierCharWidth, menuModifierCharWidth;
    int x, y, modifierWidth, labelWidth, indicatorSpace;
    int windowWidth, windowHeight, accelWidth;
    int i, j, lastColumnBreak, maxWidth;
    int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
    TkMenuEntry *mePtr, *columnEntryPtr;
    int haveAccel = 0;





    if (menuPtr->tkwin == NULL) {
	return;
    }


    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    x = y = borderWidth;
    windowHeight = maxWidth = lastColumnBreak = 0;
    maxIndicatorSpace = 0;

    /*
     * On the Mac especially, getting font metrics can be quite slow, so we
     * want to do it intelligently. We are going to precalculate them and pass
     * them down to all of the measuring and drawing routines. We will measure
     * the font metrics of the menu once. If an entry does not have its own
     * font set, then we give the geometry/drawing routines the menu's font
     * and metrics. If an entry has its own font, we will measure that font
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    menuModifierCharWidth = ModifierCharWidth(menuFont);

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == CASCADE_ENTRY || mePtr->accelLength > 0) {
	    haveAccel = 1;
	    break;
	}
    }

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];



	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	    modifierCharWidth = menuModifierCharWidth;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
	    fmPtr = &entryMetrics;
	    modifierCharWidth = ModifierCharWidth(tkfont);
	}

	if ((i > 0) && mePtr->columnBreak) {
	    if (maxIndicatorSpace != 0) {
		maxIndicatorSpace += 2;
	    }
	    for (j = lastColumnBreak; j < i; j++) {
		columnEntryPtr = menuPtr->entries[j];
		columnEntryPtr->indicatorSpace = maxIndicatorSpace;
		columnEntryPtr->width = maxIndicatorSpace + maxWidth
			+ 2 * activeBorderWidth;
		columnEntryPtr->x = x;
		columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += maxIndicatorSpace + maxWidth + 2 * borderWidth;
	    maxWidth = maxIndicatorSpace = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}
	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY || mePtr->type == TEAROFF_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
	} else {
	    /*
	     * For each entry, compute the height required by that particular
	     * entry, plus three widths: the width of the label, the width to
	     * allow for an indicator to be displayed to the left of the label
	     * (if any), and the width of the accelerator to be displayed to
	     * the right of the label (if any). These sizes depend, of course,
	     * on the type of the entry.
	     */

	    NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
	    int haveImage = 0, width = 0, height = 0;

	    if (mePtr->image) {
		Tk_SizeOfImage(mePtr->image, &width, &height);
		haveImage = 1;

	    } else if (mePtr->bitmapPtr) {
		Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin,
			mePtr->bitmapPtr);

		Tk_SizeOfBitmap(menuPtr->display, bitmap, &width, &height);
		haveImage = 1;

	    }
	    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
		NSAttributedString *attrTitle = [menuItem attributedTitle];
		NSSize size;

		if (attrTitle) {
		    size = [attrTitle size];
		} else {
		    size = [[menuItem title] sizeWithAttributes:
			TkMacOSXNSFontAttributesForFont(tkfont)];
		}
		size.width += menuTextLeadingEdgeMargin +
			menuTextTrailingEdgeMargin;
		if (size.height < fmPtr->linespace) {
		    size.height = fmPtr->linespace;
		}
		if (haveImage && (mePtr->compound != COMPOUND_NONE)) {
		    int margin = width + menuIconTrailingEdgeMargin;

		    if (margin > menuTextLeadingEdgeMargin) {
			margin = menuTextLeadingEdgeMargin;
		    }
		    width += size.width + menuIconTrailingEdgeMargin - margin;
		    if (size.height > height) {
			height = size.height;
		    }
		} else {
		    width = size.width;
		    height = size.height;
		}
	    }



	    labelWidth = width + menuItemExtraWidth;
	    mePtr->height = height + menuItemExtraHeight;

	    if (mePtr->type == CASCADE_ENTRY) {
		modifierWidth = modifierCharWidth;
	    } else if (mePtr->accelLength == 0) {
		if (haveAccel && !mePtr->hideMargin) {
		    modifierWidth = modifierCharWidth;
		}
	    } else {
		NSUInteger modifMask = [menuItem keyEquivalentModifierMask];
		int i = 0;

		while (modifiers[i].name) {
		    if (modifMask & modifiers[i].mask) {
			modifMask &= ~modifiers[i].mask;
			modifierWidth += modifierCharWidth;
		    }
		    i++;
		}
		accelWidth = [[menuItem keyEquivalent] sizeWithAttributes:
			TkMacOSXNSFontAttributesForFont(tkfont)].width;
	    }
	    if (!mePtr->hideMargin) {
		indicatorSpace = menuMarkColumnWidth;
	    }
	    if (indicatorSpace > maxIndicatorSpace) {
		maxIndicatorSpace = indicatorSpace;
	    }
	    entryWidth = labelWidth + modifierWidth + accelWidth;
	    if (entryWidth > maxWidth) {
		maxWidth = entryWidth;
	    }

	    mePtr->height += 2 * activeBorderWidth;
	}

	mePtr->y = y;
	y += menuPtr->entries[i]->height + borderWidth;
	if (y > windowHeight) {
	    windowHeight = y;
	}
    }

    for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
	columnEntryPtr = menuPtr->entries[j];
	columnEntryPtr->indicatorSpace = maxIndicatorSpace;
	columnEntryPtr->width = maxIndicatorSpace + maxWidth
		+ 2 * activeBorderWidth;
	columnEntryPtr->x = x;
	columnEntryPtr->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + maxIndicatorSpace + maxWidth
	    + 2 * activeBorderWidth + borderWidth;
    windowHeight += borderWidth;

    if (windowWidth <= 0) {
	windowWidth = 1;
    }

    if (windowHeight <= 0) {
	windowHeight = 1;
    }
    menuPtr->totalWidth = windowWidth;
    menuPtr->totalHeight = windowHeight;
}

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
    NSMenuItem *menuItem)
{
    TkMenu *menuPtr = [menu tkMenu];

    if (menuPtr) {
	int index = [menu tkIndexOfItem:menuItem];

	if (index < 0 || index >= (int) menuPtr->numEntries ||
		(menuPtr->entries[index])->state == ENTRY_DISABLED) {
	    TkActivateMenuEntry(menuPtr, -1);
	} else {
	    TkActivateMenuEntry(menuPtr, index);
	    MenuSelectEvent(menuPtr);
	    return true;
	}







|







1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
    NSMenuItem *menuItem)
{
    TkMenu *menuPtr = [menu tkMenu];

    if (menuPtr) {
	int index = [menu tkIndexOfItem:menuItem];

	if (index < 0 || index >= menuPtr->numEntries ||
		(menuPtr->entries[index])->state == ENTRY_DISABLED) {
	    TkActivateMenuEntry(menuPtr, -1);
	} else {
	    TkActivateMenuEntry(menuPtr, index);
	    MenuSelectEvent(menuPtr);
	    return true;
	}
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    int i;

    TkActivateMenuEntry(menuPtr, -1);
    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	TkMenuEntry *mePtr = menuPtr->entries[i];

	if (mePtr->type == CASCADE_ENTRY
		&& (mePtr->childMenuRefPtr != NULL)
		&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
	    RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
	}







|







1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    int i;

    TkActivateMenuEntry(menuPtr, -1);
    for (i = 0; i < menuPtr->numEntries; i++) {
	TkMenuEntry *mePtr = menuPtr->entries[i];

	if (mePtr->type == CASCADE_ENTRY
		&& (mePtr->childMenuRefPtr != NULL)
		&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
	    RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
	}
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
























1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687







1688
1689
1690
1691
1692
1693
1694
TkMacOSXClearMenubarActive(void)
{
    NSMenu *mainMenu = [NSApp mainMenu];

    if (mainMenu && [mainMenu isKindOfClass:[TKMenu class]]) {
	TkMenu *menuPtr = [(TKMenu *) mainMenu tkMenu];

	if (menuPtr &&
	    !(menuPtr->menuFlags & MENU_DELETION_PENDING) &&
	    menuPtr->numEntries > 0 &&
	    menuPtr->entries != NULL) {
	    RecursivelyClearActiveMenu(menuPtr);
	}
    }
}

























/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *
 *	Initializes Mac-specific menu data.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates a hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{
    //    TkColor *tkColPtr;

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:NSApp selector:@selector(s) name:(n) object:nil]
    observe(NSMenuDidBeginTrackingNotification, menuBeginTracking:);
    observe(NSMenuDidEndTrackingNotification, menuEndTracking:);
#undef observe

    [NSMenuItem setUsesUserKeyEquivalents:NO];







    ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth,
	    &menuMarkColumnWidth);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin,
	    &menuTextLeadingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextTrailingEdgeMargin,
	    &menuTextTrailingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuIconTrailingEdgeMargin,







|
<
<
<




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|










>
>
>
>
>
>
>







1396
1397
1398
1399
1400
1401
1402
1403



1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
TkMacOSXClearMenubarActive(void)
{
    NSMenu *mainMenu = [NSApp mainMenu];

    if (mainMenu && [mainMenu isKindOfClass:[TKMenu class]]) {
	TkMenu *menuPtr = [(TKMenu *) mainMenu tkMenu];

	if (menuPtr && menuPtr->numEntries && menuPtr->entries) {



	    RecursivelyClearActiveMenu(menuPtr);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXTurnOffMenus --
 *
 *	Turns off all the menu drawing code. This is more than just disabling
 *	the "menu" command, this means that Tk will NEVER touch the menubar.
 *	It is needed in the Plugin, where Tk does not own the menubar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A flag is set which will disable all menu drawing.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXTurnOffMenus(void)
{
    gNoTkMenus = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *
 *	Initializes Mac-specific menu data.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates a hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{
    TkColor *tkColPtr;

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:NSApp selector:@selector(s) name:(n) object:nil]
    observe(NSMenuDidBeginTrackingNotification, menuBeginTracking:);
    observe(NSMenuDidEndTrackingNotification, menuEndTracking:);
#undef observe

    [NSMenuItem setUsesUserKeyEquivalents:NO];
    tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
    defaultBg = tkColPtr->color.pixel;
    ckfree((char *) tkColPtr);
    tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
    defaultFg = tkColPtr->color.pixel;
    ckfree((char *) tkColPtr);

    ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth,
	    &menuMarkColumnWidth);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin,
	    &menuTextLeadingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextTrailingEdgeMargin,
	    &menuTextTrailingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuIconTrailingEdgeMargin,
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    TCL_UNUSED(Tcl_Interp *),	/* The interp the menu lives in. */
    TCL_UNUSED(const char *))	/* The name of the menu to reconfigure. */
{
    /*
     * Nothing to do.
     */
}

/*







|
|







1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    Tcl_Interp *interp,		/* The interp the menu lives in. */
    char *menuName)	/* The name of the menu to reconfigure. */
{
    /*
     * Nothing to do.
     */
}

/*
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
 *	Alt-key bindings.
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter to set. */
    TCL_UNUSED(Tk_BindingTable))
				/* The table to add to. */
{
    /*
     * Nothing to do.
     */
}








|
|







1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
 *	Alt-key bindings.
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    Tcl_Interp *interp,		/* The interpreter to set. */
    Tk_BindingTable bindingTable)
				/* The table to add to. */
{
    /*
     * Nothing to do.
     */
}

1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842

1843
1844
1845
1846
1847
1848
1849
 *	X Server commands are executed to display the menu entry.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TCL_UNUSED(TkMenuEntry *),		/* The entry to draw */
    TCL_UNUSED(Drawable),			/* What to draw into */
    TCL_UNUSED(Tk_Font),		/* Precalculated font for menu */
    TCL_UNUSED(const Tk_FontMetrics *),
				/* Precalculated metrics for menu */
    TCL_UNUSED(int),			/* X-coordinate of topleft of entry */
    TCL_UNUSED(int),			/* Y-coordinate of topleft of entry */
    TCL_UNUSED(int),			/* Width of the entry rectangle */
    TCL_UNUSED(int),			/* Height of the current rectangle */
    TCL_UNUSED(int),		/* Boolean flag */
    TCL_UNUSED(int))		/* Whether or not to draw the cascade arrow
				 * for cascade items. */

{
}

#pragma mark Obsolete

/*
 *----------------------------------------------------------------------







|
|
|
|

|
|
|
|
|
|
|
>







1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
 *	X Server commands are executed to display the menu entry.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TkMenuEntry *mePtr,		/* The entry to draw */
    Drawable d,			/* What to draw into */
    Tk_Font tkfont,		/* Precalculated font for menu */
    const Tk_FontMetrics *menuMetricsPtr,
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. Only applies to
				 * Windows. */
{
}

#pragma mark Obsolete

/*
 *----------------------------------------------------------------------
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXUseID --
 *
 *	Take the ID out of the available list for new menus. Used by the
 *	default menu bar's menus so that they do not get created at the Tk
 *	level. See TkMacOSXGetNewMenuID for more information.
 *
 * Results:
 *	Returns TCL_OK if the id was not in use. Returns TCL_ERROR if the id
 *	was in use.
 *
 * Side effects:
 *	A hash table entry in the command table is created with a NULL value.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXUseMenuID(
    TCL_UNUSED(short))		/* The id to take out of the table */
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDispatchMenuEvent --
 *
 *	Given a menu id and an item, dispatches the command associated with it.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands for the event are scheduled for execution at idle time.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXDispatchMenuEvent(
    TCL_UNUSED(int),			/* The menu id of the menu we are invoking */
    TCL_UNUSED(int))			/* The one-based index of the item that was
				 * selected. */
{
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------







|














|









|
>












|
|







1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXUseID --
 *
 *	Take the ID out of the available list for new menus. Used by the
 *	default menu bar's menus so that they do not get created at the tk
 *	level. See TkMacOSXGetNewMenuID for more information.
 *
 * Results:
 *	Returns TCL_OK if the id was not in use. Returns TCL_ERROR if the id
 *	was in use.
 *
 * Side effects:
 *	A hash table entry in the command table is created with a NULL value.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXUseMenuID(
    short macID)		/* The id to take out of the table */
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDispatchMenuEvent --
 *
 *	Given a menu id and an item, dispatches the command associated with
 *	it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands for the event are scheduled for execution at idle time.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXDispatchMenuEvent(
    int menuID,			/* The menu id of the menu we are invoking */
    int index)			/* The one-based index of the item that was
				 * selected. */
{
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetHelpMenuItemCount --
 *
 *	Has to be called after the first call to InsertMenu. Sets up the global
 *	variable for the number of items in the unmodified help menu.
 *
 *	NB: Nobody uses this any more, since you can get the number of system
 *	help items from HMGetHelpMenu trivially. But it is in the stubs
 *	table...
 *
 * Results:
 *	None.
 *
 * Side effects:







|
|
<
|







1727
1728
1729
1730
1731
1732
1733
1734
1735

1736
1737
1738
1739
1740
1741
1742
1743
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetHelpMenuItemCount --
 *
 *	Has to be called after the first call to InsertMenu. Sets up the
 *	global variable for the number of items in the unmodified help menu.

 *	NB. Nobody uses this any more, since you can get the number of system
 *	help items from HMGetHelpMenu trivially. But it is in the stubs
 *	table...
 *
 * Results:
 *	None.
 *
 * Side effects:

Changes to macosx/tkMacOSXMenubutton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkMacOSXMenubutton.c --
 *
 *	This file implements the Macintosh specific portion of the menubutton
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2007 Revar Desmera.
 * Copyright 2015 Kevin Walzer/WordTech Communications LLC.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"



|
|




|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkMacOSXMenubutton.c --
 *
 *	This file implements the Macintosh specific portion of the
 *	menubutton widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2007 Revar Desmera. 
 * Copyright 2015 Kevin Walzer/WordTech Communications LLC.  
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186



187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

typedef struct {
    Tk_3DBorder border;
    int relief;
    GC gc;
    int hasImageOrBitmap;
} DrawParams;


/*
 * Declaration of Mac specific button structure.
 */

typedef struct MacMenuButton {
    TkMenuButton info;		/* Generic button info. */
    int flags;
    ThemeButtonKind btnkind;
    HIThemeButtonDrawInfo drawinfo;
    HIThemeButtonDrawInfo lastdrawinfo;
    DrawParams drawParams;
} MacMenuButton;

/*
 * Forward declarations for static functions defined later in this file:
 */

static void		MenuButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		MenuButtonBackgroundDrawCB(MacMenuButton *ptr,
			    SInt16 depth, Boolean isColorDev);
static void		MenuButtonContentDrawCB(ThemeButtonKind kind,
			    const HIThemeButtonDrawInfo *info,
			    MacMenuButton *ptr, SInt16 depth,
			    Boolean isColorDev);
static void		MenuButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		TkMacOSXComputeMenuButtonParams(TkMenuButton *butPtr,
			    ThemeButtonKind *btnkind,
			    HIThemeButtonDrawInfo *drawinfo);
static void		TkMacOSXComputeMenuButtonDrawParams(
			    TkMenuButton *butPtr, DrawParams *dpPtr);
static void		TkMacOSXDrawMenuButton(MacMenuButton *butPtr, GC gc,
			    Pixmap pixmap);
static void		DrawMenuButtonImageAndText(TkMenuButton *butPtr);

/*
 * The structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

Tk_ClassProcs tkpMenubuttonClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TkMenuButtonWorldChanged,	/* worldChangedProc */
	NULL,
	NULL
};

/*
 * We use Apple's Pop-Up Button widget to represent the Tk Menubutton.
 * However, we do not use the NSPopUpButton class for this control.  Instead we
 * render the Pop-Up Button using the HITheme library.  This imposes some
 * constraints on what can be done.  The HITheme renderer allows only specific
 * dimensions for the button.
 *
 * The HITheme library allows drawing a Pop-Up Button with an arbitrary bounds
 * rectangle.  However the button is always drawn as a rounded box which is 22
 * pixels high.  If the bounds rectangle is less than 22 pixels high, the
 * button is drawn at the top of the rectangle and the bottom of the button is
 * clipped away.  So we set a minimum height of 22 pixels for a Menubutton.  If
 * the bounds rectangle is more than 22 pixels high, then the button is drawn
 * centered vertically in the bounds rectangle.
 *
 * The content rectangle of the button is inset by 14 pixels on the left and 28
 * pixels on the right.  The rightmost part of the button contains the blue
 * double-arrow symbol which is 28 pixels wide.
 *
 * To maintain compatibility with code that runs on multiple operating systems,
 * the width and height of the content rectangle includes the borderWidth, the
 * highlightWidth and the padX and padY dimensions of the Menubutton.  However,
 * to be consistent with the standard Apple appearance, the content is always
 * be drawn at the left side of the content rectangle.  All of the excess space
 * appears on the right side of the content, and the anchor property is
 * ignored.  The easiest way to comply with Apple's Human Interface Guidelines
 * would be to set bd = highlightthickness = padx = 0 and to specify an
 * explicit width for the button.  Apple also recommends using the same width
 * for all Pop-Up Buttons in a given window.
 */

#define LEFT_INSET 8
#define RIGHT_INSET 28
#define MIN_HEIGHT 22

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateMenuButton  --
 *
 *	Allocate a new TkMenuButton structure.
 *
 * Results:
 *	Returns a newly allocated TkMenuButton structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkMenuButton *
TkpCreateMenuButton(
    Tk_Window tkwin)
{
    MacMenuButton *mbPtr = (MacMenuButton *)ckalloc(sizeof(MacMenuButton));

    Tk_CreateEventHandler(tkwin, ActivateMask, MenuButtonEventProc, mbPtr);

    mbPtr->flags = FIRST_DRAW;
    mbPtr->btnkind = kThemePopupButton;
    bzero(&mbPtr->drawinfo, sizeof(mbPtr->drawinfo));
    bzero(&mbPtr->lastdrawinfo, sizeof(mbPtr->lastdrawinfo));

    return (TkMenuButton *) mbPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayMenuButton --
 *
 *	This procedure is invoked to display a menubutton widget.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the menubutton in its current mode.

 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    MacMenuButton *mbPtr = clientData;
    TkMenuButton *butPtr = clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams *dpPtr = &mbPtr->drawParams;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
    }

    pixmap = (Pixmap) Tk_WindowId(tkwin);

    TkMacOSXComputeMenuButtonDrawParams(butPtr, dpPtr);

    /*

     * Draw the native portion of the buttons.
     */




    TkMacOSXDrawMenuButton(mbPtr,  dpPtr->gc, pixmap);

    /*
     * Draw highlight border, if needed.
     */

    if (butPtr->highlightWidth < 3) {
        if (butPtr->flags & GOT_FOCUS) {
	    GC gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);

	    TkMacOSXDrawSolidBorder(tkwin, gc, 0, butPtr->highlightWidth);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyMenuButton --
 *
 *	Free data structures associated with the menubutton control. This is a
 *      no-op on the Mac.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TCL_UNUSED(TkMenuButton *))
{
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --







>















|


|
<
<
|
<
<
|
<
<
|
|
<
<
|
|
<
|
|









<
<


<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
















|

|
>




>














|
>








|
|
|

|









|
|
>
|

|
>
>
>


<
|
<
<

|
|
>
|
|








|
<





|






|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


54


55


56
57


58
59

60
61
62
63
64
65
66
67
68
69
70


71
72






73




























74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

typedef struct {
    Tk_3DBorder border;
    int relief;
    GC gc;
    int hasImageOrBitmap;
} DrawParams;


/*
 * Declaration of Mac specific button structure.
 */

typedef struct MacMenuButton {
    TkMenuButton info;		/* Generic button info. */
    int flags;
    ThemeButtonKind btnkind;
    HIThemeButtonDrawInfo drawinfo;
    HIThemeButtonDrawInfo lastdrawinfo;
    DrawParams drawParams;
} MacMenuButton;

/*
 * Forward declarations for procedures defined later in this file:
 */

static void MenuButtonEventProc(ClientData clientData, XEvent *eventPtr);


static void MenuButtonBackgroundDrawCB ( MacMenuButton *ptr, SInt16 depth, Boolean isColorDev);


static void MenuButtonContentDrawCB ( ThemeButtonKind kind, const HIThemeButtonDrawInfo * info, MacMenuButton *ptr, SInt16 depth, Boolean isColorDev);


static void MenuButtonEventProc ( ClientData clientData, XEvent *eventPtr);
static void TkMacOSXComputeMenuButtonParams (TkMenuButton * butPtr, ThemeButtonKind* btnkind, HIThemeButtonDrawInfo* drawinfo);


static int TkMacOSXComputeMenuButtonDrawParams (TkMenuButton * butPtr, DrawParams * dpPtr);
static void TkMacOSXDrawMenuButton (MacMenuButton *butPtr,

       GC gc, Pixmap pixmap);
static void DrawMenuButtonImageAndText(TkMenuButton* butPtr);

/*
 * The structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

Tk_ClassProcs tkpMenubuttonClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TkMenuButtonWorldChanged,	/* worldChangedProc */


};




































/*
 *----------------------------------------------------------------------
 *
 * TkpCreateMenuButton --
 *
 *	Allocate a new TkMenuButton structure.
 *
 * Results:
 *	Returns a newly allocated TkMenuButton structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkMenuButton *
TkpCreateMenuButton(
    Tk_Window tkwin)
{
    MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton));

    Tk_CreateEventHandler(tkwin, ActivateMask,
	    MenuButtonEventProc, (ClientData) mbPtr);
    mbPtr->flags = FIRST_DRAW;
    mbPtr->btnkind = kThemePopupButton;
    bzero(&mbPtr->drawinfo, sizeof(mbPtr->drawinfo));
    bzero(&mbPtr->lastdrawinfo, sizeof(mbPtr->lastdrawinfo));

    return (TkMenuButton *) mbPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayMenuButton --
 *
 *	This procedure is invoked to display a menubutton widget.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the menubutton in its
 *	current mode.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    MacMenuButton *mbPtr    = (MacMenuButton *)clientData;
    TkMenuButton  *butPtr   = (TkMenuButton *) clientData;
    Tk_Window tkwin         = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams* dpPtr = &mbPtr->drawParams;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
    }

    pixmap = (Pixmap) Tk_WindowId(tkwin);

    TkMacOSXComputeMenuButtonDrawParams(butPtr, dpPtr);
   
    /* 
     * set up clipping region.  Make sure the we are using the port
     * for this button, or we will set the wrong window's clip. 
     */
    
    TkMacOSXSetUpClippingRgn(pixmap);

    /* Draw the native portion of the buttons. */
    TkMacOSXDrawMenuButton(mbPtr,  dpPtr->gc, pixmap);


    /* Draw highlight border, if needed. */


    if (butPtr->highlightWidth < 3) {
        if ((butPtr->flags & GOT_FOCUS)) {
            Tk_Draw3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin),
                butPtr->highlightWidth, TK_RELIEF_SOLID);
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyMenuButton --
 *
 *	Free data structures associated with the menubutton control.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Restores the default control state.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TkMenuButton *mbPtr)
{
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
237
238
239
240
241
242
243
244
245
246

247
248
249



250
251
252
253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345


346










347

348





























349

350




351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377


378

379

380

381

382

383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401





402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451

452
453
454
455
456
457
458

459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491


492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510



511
512
513
514
515
516
517
518
519
520


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545

546
547
548
549
550
551
552


553
554
555
556


557
558
559
560
561
562

563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596


597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742



743
744
745
746
747
748
749
750
751
752
753
 *	The menu button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeMenuButtonGeometry(butPtr)
    TkMenuButton *butPtr;	/* Widget record for menu button. */
{
    int width, height, avgWidth, haveImage = 0, haveText = 0;

    int txtWidth, txtHeight;
    Tk_FontMetrics fm;
    int highlightWidth = butPtr->highlightWidth > 0 ? butPtr->highlightWidth : 0;




    /*
     * First compute the size of the contents of the button.
     */

    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;



    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    if (butPtr->text && strlen(butPtr->text) > 0) {
	haveText = 1;
        Tk_FreeTextLayout(butPtr->textLayout);
        butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
                butPtr->text, -1, butPtr->wrapLength,
                butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

        txtWidth = butPtr->textWidth;
        txtHeight = butPtr->textHeight;
        avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
        Tk_GetFontMetrics(butPtr->tkfont, &fm);

    }

    /*
     * If the button is compound (ie, it shows both an image and text), the new
     * geometry is a combination of the image and text geometry. We only honor
     * the compound bit if the button has both text and an image, because
     * otherwise it is not really a compound button.
     */

    if (haveImage && haveText) {
        switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text
	     */

	    height += txtHeight + butPtr->padY;
	    width = (width > txtWidth ? width : txtWidth);
	    break;

	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text
	     */

	    width += txtWidth + butPtr->padX;
	    height = (height > txtHeight ? height : txtHeight);
	    break;

	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed
	     */

	    width = (width > txtWidth ? width : txtWidth);
	    height = (height > txtHeight ? height : txtHeight);
	    break;

	case COMPOUND_NONE:
	    break;
        }

        if (butPtr->width > 0) {
            width = butPtr->width;
        }
        if (butPtr->height > 0) {
            height = butPtr->height;
        }

    } else {
        if (haveImage) { /* Image only */
            if (butPtr->width > 0) {
                width = butPtr->width;
            }
            if (butPtr->height > 0) {
                height = butPtr->height;
            }
        } else { /* Text only */
            width = txtWidth;
            height = txtHeight;
            if (butPtr->width > 0) {
                width = butPtr->width * avgWidth + 2*butPtr->padX;
            }
            if (butPtr->height > 0) {
                height = butPtr->height * fm.linespace + 2*butPtr->padY;
            }
        }
    }













    butPtr->inset = highlightWidth + butPtr->borderWidth;

    width += LEFT_INSET + RIGHT_INSET + 2*butPtr->inset;





























    height += 2*butPtr->inset;

    height = height < MIN_HEIGHT ? MIN_HEIGHT : height;




    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuButtonImageAndText --
 *
 *        Draws the image and text associated with a button or label.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The image and text are drawn.
 *
 *----------------------------------------------------------------------
 */
void
DrawMenuButtonImageAndText(
    TkMenuButton *butPtr)
{
    MacMenuButton *mbPtr = (MacMenuButton *) butPtr;
    Tk_Window tkwin  = butPtr->tkwin;
    Pixmap pixmap;
    int haveImage = 0, haveText = 0;


    int imageWidth = 0, imageHeight = 0;

    int imageXOffset = 0, imageYOffset = 0;

    int textXOffset = 0, textYOffset = 0;

    int width = 0, height = 0;

    int fullWidth = 0, fullHeight = 0;


    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawParams *dpPtr = &mbPtr->drawParams;
    pixmap = (Pixmap) Tk_WindowId(tkwin);


    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    imageWidth = width;
    imageHeight = height;






    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
        int x = 0, y = 0;

        textXOffset = 0;
        textYOffset = 0;
        fullWidth = 0;
        fullHeight = 0;

        switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text.
	     */

	    if (butPtr->compound == COMPOUND_TOP) {
		textYOffset = height + butPtr->padY;
	    } else {
		imageYOffset = butPtr->textHeight + butPtr->padY;
	    }
	    fullHeight = height + butPtr->textHeight + butPtr->padY;
	    fullWidth = (width > butPtr->textWidth ?
		     width : butPtr->textWidth);
	    textXOffset = (fullWidth - butPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    break;

	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text
	     */

	    if (butPtr->compound == COMPOUND_LEFT) {
		textXOffset = width + butPtr->padX - 2;
	    } else {
		imageXOffset = butPtr->textWidth + butPtr->padX;
	    }
	    fullWidth = butPtr->textWidth + butPtr->padX + width;
	    fullHeight = (height > butPtr->textHeight ? height :
                    butPtr->textHeight);
	    textYOffset = (fullHeight - butPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;

	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed
	     */

	    fullWidth = (width > butPtr->textWidth ? width : butPtr->textWidth);

	    fullHeight = (height > butPtr->textHeight ? height :
                    butPtr->textHeight);
	    textXOffset = (fullWidth - butPtr->textWidth) / 2;
	    imageXOffset = (fullWidth - width) / 2;
	    textYOffset = (fullHeight - butPtr->textHeight) / 2;
	    imageYOffset = (fullHeight - height) / 2;
	    break;

	case COMPOUND_NONE:
	    break;
	}

        TkComputeAnchor(butPtr->anchor, tkwin,
                butPtr->padX + butPtr->inset, butPtr->padY + butPtr->inset,

                fullWidth, fullHeight, &x, &y);
        imageXOffset = LEFT_INSET;
        imageYOffset += y;
        textYOffset -= 1;

        if (butPtr->image != NULL) {
	    Tk_RedrawImage(butPtr->image, 0, 0, width,
                    height, pixmap, imageXOffset, imageYOffset);
        } else {
            XSetClipOrigin(butPtr->display, dpPtr->gc,
                    imageXOffset, imageYOffset);
            XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
                    0, 0, (unsigned int) width, (unsigned int) height,
                    imageXOffset, imageYOffset, 1);
            XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
        }

        Tk_DrawTextLayout(butPtr->display, pixmap,
                dpPtr->gc, butPtr->textLayout,
                x + textXOffset, y + textYOffset, 0, -1);
        Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                butPtr->textLayout, x + textXOffset, y + textYOffset,

                butPtr->underline);
    } else {
	int x, y;

        if (haveImage) {


            TkComputeAnchor(butPtr->anchor, tkwin,
                    butPtr->padX + butPtr->borderWidth,
                    butPtr->padY + butPtr->borderWidth,
                    width, height, &x, &y);
	    imageXOffset = LEFT_INSET;
	    imageYOffset += y;

	    if (butPtr->image != NULL) {
		Tk_RedrawImage(butPtr->image, 0, 0, width, height,
			       pixmap, imageXOffset, imageYOffset);
            } else {
                XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
                XCopyPlane(butPtr->display, butPtr->bitmap,
			   pixmap, dpPtr->gc,
			   0, 0, (unsigned int) width,
			   (unsigned int) height,
			   imageXOffset, imageYOffset, 1);
                XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
            }
        } else {



	    textXOffset = LEFT_INSET;
	    TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		    butPtr->textWidth, butPtr->textHeight, &x, &y);
	    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, textXOffset, y, 0, -1);
	    y += butPtr->textHeight/2;
	}
   }
}



/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawMenuButton --
 *
 *        This function draws the tk menubutton using Mac controls. In
 *        addition, this code may apply custom colors passed in the
 *        TkMenubutton.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        None.
 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawMenuButton(
    MacMenuButton *mbPtr, /* Mac menubutton. */
    TCL_UNUSED(GC),       /* The GC we are drawing into - not used */

    Pixmap pixmap)        /* The pixmap we are drawing into - needed for the
                           * bevel button */
{

    TkMenuButton *butPtr = (TkMenuButton *) mbPtr;
    TkWindow *winPtr = (TkWindow *) butPtr->tkwin;
    HIRect cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams *dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;



    TkMacOSXComputeMenuButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff,
	    Tk_Width(butPtr->tkwin), Tk_Height(butPtr->tkwin));



    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        MenuButtonBackgroundDrawCB(mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}


        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
            hiinfo.animation.time.start = hiinfo.animation.time.current;
        }

	/*
	 * To avoid menubuttons with white text on a white background, we
	 * always set the state to inactive in Dark Mode.  It isn't perfect but
	 * it is usable.  Using a ttk::menubutton would be a better choice,
	 * however.
	 */

	if (TkMacOSXInDarkMode(butPtr->tkwin)) {
	    hiinfo.state = kThemeStateInactive;
	}

        HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);
	TkMacOSXRestoreDrawingContext(&dc);
        MenuButtonContentDrawCB(mbPtr->btnkind, &mbPtr->drawinfo,
		mbPtr, 32, true);
    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}


	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonBackgroundDrawCB --
 *
 *      This function draws the background that lies under checkboxes and
 *      radiobuttons.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The background gets updated to the current color.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonBackgroundDrawCB (
    MacMenuButton *ptr,
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    TkMenuButton* butPtr = (TkMenuButton *) ptr;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
            Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonContentDrawCB --
 *
 *      This function draws the label and image for the button.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The content of the button gets updated.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonContentDrawCB (
    TCL_UNUSED(ThemeButtonKind),
    TCL_UNUSED(const HIThemeButtonDrawInfo *),
    MacMenuButton *ptr,
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    TkMenuButton *butPtr = (TkMenuButton *) ptr;
    Tk_Window tkwin = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawMenuButtonImageAndText(butPtr);
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for various events on
 *	buttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *buttonPtr = clientData;
    MacMenuButton *mbPtr = clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeMenuButtonParams --
 *
 *      This procedure computes the various parameters used when creating a
 *      Carbon Appearance control. These are determined by the various Tk
 *      button parameters
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        Sets the btnkind and drawinfo parameters
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeMenuButtonParams(
    TkMenuButton *butPtr,
    ThemeButtonKind *btnkind,
    HIThemeButtonDrawInfo *drawinfo)
{
    MacMenuButton *mbPtr = (MacMenuButton *) butPtr;

    if (butPtr->image || butPtr->bitmap || butPtr->text) {
	/* TODO: allow for Small and Mini menubuttons. */
	*btnkind = kThemePopupButton;
    } else { /* This should never happen. */

	*btnkind = kThemeArrowButton;



    }

    drawinfo->value = kThemeButtonOff;

    if ((mbPtr->flags & FIRST_DRAW) != 0) {
	mbPtr->flags &= ~FIRST_DRAW;
	if (Tk_MacOSXIsAppInFront()) {
	    mbPtr->flags |= ACTIVE;
	}
    }








|


>


<
>
>
>


|

|





>
>









|
<




>




>



|
|
|
|


|

|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
>
|
<

|








|






|



|


|



>
>

>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>









|











|

|
|
|
|
>
>
|
>
|
>
|
>
|
>
|
>




|
|
|

>
|







|


>
>
>
>
>
|
|
|
|






|
|
<
|
<
<
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
>
|
<



|
>

|




|
|









|



|
>


<
<

>
>



|
|
|
>
|
|
|



|
|
|
|



>
>
>
|

|

|

|


|
>
>





|
|
|









<



|
>
|
|
|
>
|
|
|

|


>
>


|
|
>
>





|
>
|


>



|







<
<
<
<
<
<
|
<
<
|
<
<
<

|
|

|


>
>










|
|


|


|



<



|
|

|
|

<



|
>

|







|


|


|



<


|
|

|
|

|
|




>
|







|
|















|
|












|










|
|
|











|
<
<
<

|

|


|
>
|
>
>
>



|







197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442


443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518


519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619






620


621



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660

661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764



765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
 *	The menu button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeMenuButtonGeometry(butPtr)
    register TkMenuButton *butPtr;	/* Widget record for menu button. */
{
    int width, height, avgWidth, haveImage = 0, haveText = 0;
    MacMenuButton *mbPtr = (MacMenuButton*)butPtr;
    int txtWidth, txtHeight;
    Tk_FontMetrics fm;

    DrawParams drawParams;
    int paddingx = 0;
    int paddingy = 0;

    /*
     * First figure out the size of the contents of the button.
     */
     
    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    TkMacOSXComputeMenuButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {

        Tk_FreeTextLayout(butPtr->textLayout);
        butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
                butPtr->text, -1, butPtr->wrapLength,
                butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

        txtWidth = butPtr->textWidth;
        txtHeight = butPtr->textHeight;
        avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
        Tk_GetFontMetrics(butPtr->tkfont, &fm);
        haveText = (txtWidth != 0 && txtHeight != 0);
    }

    /*
     * If the button is compound (ie, it shows both an image and text),
     * the new geometry is a combination of the image and text geometry.
     * We only honor the compound bit if the button has both text and an
     * image, because otherwise it is not really a compound button.
     */

    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
        switch ((enum compound) butPtr->compound) {
            case COMPOUND_TOP:
            case COMPOUND_BOTTOM: {
                /* 
                 * Image is above or below text 
                 */
                 
                height += txtHeight + butPtr->padY;
                width = (width > txtWidth ? width : txtWidth);
                break;
            }
            case COMPOUND_LEFT:
            case COMPOUND_RIGHT: {
                /* 
                 * Image is left or right of text 
                 */
                  
                width += txtWidth + butPtr->padX;
                height = (height > txtHeight ? height : txtHeight);
                break;
            }
            case COMPOUND_CENTER: {
                /* 
                 * Image and text are superimposed 
                 */
                 
                width = (width > txtWidth ? width : txtWidth);
                height = (height > txtHeight ? height : txtHeight);
                break;
            }
            case COMPOUND_NONE: {break;}

        }
 
        if (butPtr->width > 0) {
            width = butPtr->width;
        }
        if (butPtr->height > 0) {
            height = butPtr->height;
        }

    } else {
        if (haveImage) {
            if (butPtr->width > 0) {
                width = butPtr->width;
            }
            if (butPtr->height > 0) {
                height = butPtr->height;
            }
        } else {
            width = txtWidth;
            height = txtHeight;
            if (butPtr->width > 0) {
                width = butPtr->width * avgWidth;
            }
            if (butPtr->height > 0) {
                height = butPtr->height * fm.linespace;
            }
        }
    }
    width  += 2 * butPtr->padX - 2;
    height += 2 * butPtr->padY - 2;

    /*Add padding for button arrows.*/
    width += 22;
    
    /*
     * Now figure out the size of the border decorations for the button.
     */
     
    if (butPtr->highlightWidth < 0) {
        butPtr->highlightWidth = 0;
    }
    butPtr->inset = 0;
    butPtr->inset += butPtr->highlightWidth;

    TkMacOSXComputeMenuButtonDrawParams(butPtr,&drawParams);

        HIRect tmpRect;
	HIRect contBounds;

	tmpRect = CGRectMake(0, 0, width, height);

	HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);



        /* If the content region has a minimum height, match it. */
        if (height < contBounds.size.height) {
	  height = contBounds.size.height;
        }

        /* If the content region has a minimum width, match it. */
        if (width < contBounds.size.width) {
	  width = contBounds.size.width;
        }

        /* Pad to fill difference between content bounds and button bounds. */
        paddingx = tmpRect.origin.x - contBounds.origin.x;
        paddingy = tmpRect.origin.y - contBounds.origin.y;
	
    if (paddingx > 0) {
        width += paddingx;
    }
    if (paddingy > 0) {
        height += paddingy;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;


    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuButtonImageAndText --
 *
 *        Draws the image and text associated witha button or label.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The image and text are drawn.
 *
 *----------------------------------------------------------------------
 */
void
DrawMenuButtonImageAndText(
    TkMenuButton* butPtr)
{
    MacMenuButton *mbPtr = (MacMenuButton*)butPtr;
    Tk_Window  tkwin  = butPtr->tkwin;
    Pixmap     pixmap;
    int        haveImage = 0;
    int        haveText = 0;
    int        imageWidth = 0;
    int        imageHeight = 0;
    int        imageXOffset = 0;
    int        imageYOffset = 0;
    int        textXOffset = 0;
    int        textYOffset = 0;
    int        width = 0;
    int        height = 0;
    int        fullWidth = 0;
    int        fullHeight = 0;
    int        pressed;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
 
    DrawParams* dpPtr = &mbPtr->drawParams;
    pixmap = (Pixmap)Tk_WindowId(tkwin);


    if (butPtr->image != None) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    imageWidth  = width;
    imageHeight = height;

    if (mbPtr->drawinfo.state == kThemeStatePressed) {
        /* Offset bitmaps by a bit when the button is pressed. */
        pressed = 1;
    }
    
  haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
   if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
        int x = 0;
        int y = 0;
        textXOffset = 0;
        textYOffset = 0;
        fullWidth = 0;
        fullHeight = 0;

        switch ((enum compound) butPtr->compound) {
            case COMPOUND_TOP: 
            case COMPOUND_BOTTOM: {

                /* Image is above or below text */


                if (butPtr->compound == COMPOUND_TOP) {
                    textYOffset = height + butPtr->padY;
                } else {
                    imageYOffset = butPtr->textHeight + butPtr->padY;
                }
                fullHeight = height + butPtr->textHeight + butPtr->padY;
                fullWidth = (width > butPtr->textWidth ? width :
                        butPtr->textWidth);
                textXOffset = (fullWidth - butPtr->textWidth)/2;
                imageXOffset = (fullWidth - width)/2;
                break;
            }
            case COMPOUND_LEFT:
            case COMPOUND_RIGHT: {
                /* 
                 * Image is left or right of text 
                 */
                 
                if (butPtr->compound == COMPOUND_LEFT) {
                    textXOffset = width + butPtr->padX - 2;
                } else {
                    imageXOffset = butPtr->textWidth + butPtr->padX;
                }
                fullWidth = butPtr->textWidth + butPtr->padX + width;
                fullHeight = (height > butPtr->textHeight ? height :
                        butPtr->textHeight);
                textYOffset = (fullHeight - butPtr->textHeight)/2;
                imageYOffset = (fullHeight - height)/2;
                break;
            }
            case COMPOUND_CENTER: {
                /* 
                 * Image and text are superimposed 
                 */
                 
                fullWidth = (width > butPtr->textWidth ? width :
                        butPtr->textWidth);
                fullHeight = (height > butPtr->textHeight ? height :
                        butPtr->textHeight);
                textXOffset = (fullWidth - butPtr->textWidth)/2;
                imageXOffset = (fullWidth - width)/2;
                textYOffset = (fullHeight - butPtr->textHeight)/2;
                imageYOffset = (fullHeight - height)/2;
                break;
            }
            case COMPOUND_NONE: {break;}

	}

        TkComputeAnchor(butPtr->anchor, tkwin,
                butPtr->padX + butPtr->borderWidth,
                butPtr->padY + butPtr->borderWidth,
                fullWidth, fullHeight, &x, &y);
        imageXOffset += x;
        imageYOffset += y;
        textYOffset -= 1;

        if (butPtr->image != NULL) {
                Tk_RedrawImage(butPtr->image, 0, 0, width,
                        height, pixmap, imageXOffset, imageYOffset);
        } else {
            XSetClipOrigin(butPtr->display, dpPtr->gc,
                    imageXOffset, imageYOffset);
            XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
                    0, 0, (unsigned int) width, (unsigned int) height,
                    imageXOffset, imageYOffset, 1);
            XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
        }

        Tk_DrawTextLayout(butPtr->display, pixmap, 
                dpPtr->gc, butPtr->textLayout,
                x + textXOffset, y + textYOffset, 0, -1);
        Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                butPtr->textLayout, 
                x + textXOffset, y + textYOffset,
                butPtr->underline);
    } else {


        if (haveImage) {
            int x = 0;
            int y;
            TkComputeAnchor(butPtr->anchor, tkwin,
                    butPtr->padX + butPtr->borderWidth,
                    butPtr->padY + butPtr->borderWidth,
                    width, height, &x, &y);      
	        imageXOffset += x;
	    	imageYOffset += y;
	 
               if (butPtr->image != NULL) {
		     Tk_RedrawImage(butPtr->image, 0, 0, width, height,
		         pixmap, imageXOffset, imageYOffset);
            } else {
                XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
                XCopyPlane(butPtr->display, butPtr->bitmap,
                        pixmap, dpPtr->gc,
                        0, 0, (unsigned int) width,
                        (unsigned int) height,
                        imageXOffset, imageYOffset, 1);
                XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
            }
        } else {
	  /*Move x back by eight pixels to give the menubutton arrows room.*/
	  int x = 0;
	  int y;
	  textXOffset = 8;
	    TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
			    butPtr->textWidth, butPtr->textHeight, &x, &y);
	    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
			      butPtr->textLayout, x - textXOffset, y, 0, -1);
	    y += butPtr->textHeight/2;
	  }
   }
}

    

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawMenuButton --
 *
 *        This function draws the tk menubutton using Mac controls
 *        In addition, this code may apply custom colors passed 
 *        in the TkMenubutton.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        None.
 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawMenuButton(
    MacMenuButton *mbPtr, /* Mac menubutton. */
    GC gc,                /* The GC we are drawing into - needed for
                           * the bevel button */
    Pixmap pixmap)        /* The pixmap we are drawing into - needed
                           * for the bevel button */
                
{
    TkMenuButton * butPtr = ( TkMenuButton *)mbPtr;
    TkWindow * winPtr;
    HIRect       cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams* dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;

    winPtr = (TkWindow *)butPtr->tkwin;
   
    TkMacOSXComputeMenuButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff, Tk_Width(butPtr->tkwin),Tk_Height(butPtr->tkwin));
  
     cntrRect = CGRectInset(cntrRect,  butPtr->inset, butPtr->inset);


    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        MenuButtonBackgroundDrawCB((MacMenuButton*) mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}


        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind  = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
            hiinfo.animation.time.start = hiinfo.animation.time.current;
        }







        HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal, &contHIRec);






	TkMacOSXRestoreDrawingContext(&dc);

        MenuButtonContentDrawCB( mbPtr->btnkind, &mbPtr->drawinfo, (MacMenuButton *)mbPtr, 32, true);
    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}
       

	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonBackgroundDrawCB --
 *
 *        This function draws the background that
 *        lies under checkboxes and radiobuttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The background gets updated to the current color.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonBackgroundDrawCB (
    MacMenuButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
{
    TkMenuButton* butPtr = (TkMenuButton*)ptr;
    Tk_Window tkwin  = butPtr->tkwin;
    Pixmap pixmap;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = (Pixmap)Tk_WindowId(tkwin);

    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
        Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonContentDrawCB --
 *
 *        This function draws the label and image for the button.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The content of the button gets updated.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonContentDrawCB (
    ThemeButtonKind kind,
    const HIThemeButtonDrawInfo *drawinfo,
    MacMenuButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
{
    TkMenuButton  *butPtr = (TkMenuButton *)ptr;
    Tk_Window  tkwin  = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawMenuButtonImageAndText( butPtr);
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for various
 *	events on buttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *buttonPtr = (TkMenuButton *) clientData;
    MacMenuButton *mbPtr = (MacMenuButton *) clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeMenuButtonParams --
 *
 *      This procedure computes the various parameters used
 *        when creating a Carbon Appearance control.
 *      These are determined by the various tk button parameters
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        Sets the btnkind and drawinfo parameters
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeMenuButtonParams(TkMenuButton * butPtr, ThemeButtonKind* btnkind, HIThemeButtonDrawInfo *drawinfo)



{
    MacMenuButton *mbPtr = (MacMenuButton *)butPtr;

    if (butPtr->image || butPtr->bitmap) {
	/* TODO: allow for Small and Mini menubuttons. */
	*btnkind = kThemePopupButton;
    } else {
        if (!butPtr->text || !*butPtr->text) {
            *btnkind = kThemeArrowButton;
        } else {
            *btnkind = kThemePopupButton;
        }
    }

    drawinfo->value = kThemeButtonOff;
    
    if ((mbPtr->flags & FIRST_DRAW) != 0) {
	mbPtr->flags &= ~FIRST_DRAW;
	if (Tk_MacOSXIsAppInFront()) {
	    mbPtr->flags |= ACTIVE;
	}
    }

774
775
776
777
778
779
780
781
782

783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

810
811
812
813
814
815
816
817
818
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeMenuButtonDrawParams --
 *
 *      This procedure selects an appropriate drawing context for drawing a
 *      menubutton.

 *
 * Results:
 *      None.
 *
 * Side effects:
 *      Sets the button draw parameters.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeMenuButtonDrawParams(
    TkMenuButton *butPtr,
    DrawParams *dpPtr)
{
    dpPtr->hasImageOrBitmap =
	    ((butPtr->image != NULL) || (butPtr->bitmap != None));
    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
        dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->state == STATE_ACTIVE) {
        dpPtr->gc = butPtr->activeTextGC;
        dpPtr->border = butPtr->activeBorder;
    } else {
        dpPtr->gc = butPtr->normalTextGC;
    }
}


/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|
|
>


|


|




|
|
<
<

|
|









|
>
|
|
<
<
<
<
<
<
<
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829


830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845







}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeMenuButtonDrawParams --
 *
 *        This procedure computes the various parameters used
 *        when drawing a button
 *      These are determined by the various tk button parameters
 *
 * Results:
 *        1 if control will be used, 0 otherwise.
 *
 * Side effects:
 *        Sets the button draw parameters
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXComputeMenuButtonDrawParams(TkMenuButton * butPtr, DrawParams * dpPtr)


{
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) 
            || (butPtr->bitmap != None));
    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
        dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->state == STATE_ACTIVE) {
        dpPtr->gc = butPtr->activeTextGC;
        dpPtr->border = butPtr->activeBorder;
    } else {
        dpPtr->gc = butPtr->normalTextGC;
    }

    return 1;
}








Changes to macosx/tkMacOSXMenus.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMenu.h"
#include "tkMacOSXConstants.h"

static void		GenerateEditEvent(const char *name);
static Tcl_Obj *	GetWidgetDemoPath(Tcl_Interp *interp);


#pragma mark TKApplication(TKMenus)

@implementation TKApplication(TKMenus)
- (void) _setupMenus
{
    if (_defaultMainMenu) {
	return;
    }
    TkMenuInit();

    NSString *applicationName = [[NSBundle mainBundle]
	    objectForInfoDictionaryKey:@"CFBundleName"];

    if (!applicationName) {
	applicationName = [[NSProcessInfo processInfo] processName];
    }

    NSString *aboutName = (applicationName &&
	    ![applicationName isEqualToString:@"Wish"] &&
	    ![applicationName hasPrefix:@"tclsh"]) ?
	    applicationName : @"Tcl & Tk";

    _servicesMenu = [NSMenu menuWithTitle:@"Services"];
    _defaultApplicationMenuItems = [[NSArray arrayWithObjects:
	    [NSMenuItem separatorItem],
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"Preferences%C", 0x2026]
		   action:@selector(preferences:) keyEquivalent:@","],
	    [NSMenuItem separatorItem],







<




<



|
<




<


<



<




<







9
10
11
12
13
14
15

16
17
18
19

20
21
22
23

24
25
26
27

28
29

30
31
32

33
34
35
36

37
38
39
40
41
42
43
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMenu.h"


static void		GenerateEditEvent(const char *name);
static Tcl_Obj *	GetWidgetDemoPath(Tcl_Interp *interp);


#pragma mark TKApplication(TKMenus)

@implementation TKApplication(TKMenus)
- (void)_setupMenus {

    if (_defaultMainMenu) {
	return;
    }
    TkMenuInit();

    NSString *applicationName = [[NSBundle mainBundle]
	    objectForInfoDictionaryKey:@"CFBundleName"];

    if (!applicationName) {
	applicationName = [[NSProcessInfo processInfo] processName];
    }

    NSString *aboutName = (applicationName &&
	    ![applicationName isEqualToString:@"Wish"] &&
	    ![applicationName hasPrefix:@"tclsh"]) ?
	    applicationName : @"Tcl & Tk";

    _servicesMenu = [NSMenu menuWithTitle:@"Services"];
    _defaultApplicationMenuItems = [[NSArray arrayWithObjects:
	    [NSMenuItem separatorItem],
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"Preferences%C", 0x2026]
		   action:@selector(preferences:) keyEquivalent:@","],
	    [NSMenuItem separatorItem],
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	    nil] retain];
    _defaultApplicationMenu = [TKMenu menuWithTitle:applicationName
	    menuItems:_defaultApplicationMenuItems];
    [_defaultApplicationMenu insertItem:
	    [NSMenuItem itemWithTitle:
		    [NSString stringWithFormat:@"About %@", aboutName]
		    action:@selector(orderFrontStandardAboutPanel:)] atIndex:0];
    _defaultFileMenuItems =
	    [[NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"Source%C", 0x2026]
		   action:@selector(tkSource:)],
	    [NSMenuItem itemWithTitle:@"Run Widget Demo"
		   action:@selector(tkDemo:)],
	    [NSMenuItem itemWithTitle:@"Close" action:@selector(performClose:)
		   target:nil keyEquivalent:@"w"],
	    nil] retain];
    _demoMenuItem = [_defaultFileMenuItems objectAtIndex:1];
    TKMenu *fileMenu = [TKMenu menuWithTitle:@"File"
	    menuItems: _defaultFileMenuItems];
    TKMenu *editMenu = [TKMenu menuWithTitle:@"Edit" menuItems:
	    [NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:@"Undo" action:@selector(undo:)
		   target:nil keyEquivalent:@"z"],
	    [NSMenuItem itemWithTitle:@"Redo" action:@selector(redo:)
		   target:nil keyEquivalent:@"y"],
	    [NSMenuItem separatorItem],
	    [NSMenuItem itemWithTitle:@"Cut" action:@selector(cut:)
		   target:nil keyEquivalent:@"x"],
	    [NSMenuItem itemWithTitle:@"Copy" action:@selector(copy:)
		   target:nil keyEquivalent:@"c"],
	    [NSMenuItem itemWithTitle:@"Paste" action:@selector(paste:)
		   target:nil keyEquivalent:@"v"],
	    [NSMenuItem itemWithTitle:@"Delete" action:@selector(delete:)
		   target:nil],
	    nil]];

    _defaultWindowsMenuItems = [NSArray arrayWithObjects:
    	    [NSMenuItem itemWithTitle:@"Minimize"
    	    	   action:@selector(performMiniaturize:) target:nil
    	    	   keyEquivalent:@"m"],
    	    [NSMenuItem itemWithTitle:@"Zoom" action:@selector(performZoom:)
    	    	   target:nil],
	    nil];

    /*
     * On OS X 10.12 we get duplicate tab control items if we create them here.
     */

    if ([NSApp macOSVersion] > 101200) {
	_defaultWindowsMenuItems = [_defaultWindowsMenuItems
	     arrayByAddingObjectsFromArray:
	     [NSArray arrayWithObjects:
        	    [NSMenuItem separatorItem],
    	            [NSMenuItem itemWithTitle:@"Show Previous Tab"
		           action:@selector(selectPreviousTab:)
		           target:nil
			   keyEquivalent:@"\t"
		           keyEquivalentModifierMask:
		    	       NSControlKeyMask|NSShiftKeyMask],
	            [NSMenuItem itemWithTitle:@"Show Next Tab"
		           action:@selector(selectNextTab:)
		           target:nil
			   keyEquivalent:@"\t"
		           keyEquivalentModifierMask:NSControlKeyMask],
    	            [NSMenuItem itemWithTitle:@"Move Tab To New Window"
    	    	           action:@selector(moveTabToNewWindow:)
    	    	           target:nil],
    	            [NSMenuItem itemWithTitle:@"Merge All Windows"
    	    	           action:@selector(mergeAllWindows:)
    	    	           target:nil],
    	            [NSMenuItem separatorItem],
	            nil]];
    }
    _defaultWindowsMenuItems = [_defaultWindowsMenuItems arrayByAddingObject:
	    [NSMenuItem itemWithTitle:@"Bring All to Front"
		   action:@selector(arrangeInFront:)]];
    [_defaultWindowsMenuItems retain];
    TKMenu *windowsMenu = [TKMenu menuWithTitle:@"Window" menuItems:
    				      _defaultWindowsMenuItems];
    _defaultHelpMenuItems = [[NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"%@ Help", applicationName]
		   action:@selector(showHelp:) keyEquivalent:@"?"],
	    nil] retain];
    TKMenu *helpMenu = [TKMenu menuWithTitle:@"Help" menuItems:
	    _defaultHelpMenuItems];
    [self setServicesMenu:_servicesMenu];
    [self setWindowsMenu:windowsMenu];
    _defaultMainMenu = [[TKMenu menuWithTitle:@"" submenus:[NSArray
	    arrayWithObjects:_defaultApplicationMenu, fileMenu, editMenu,
	    windowsMenu, helpMenu, nil]] retain];
    [_defaultMainMenu setSpecial:tkMainMenu];
    [_defaultApplicationMenu setSpecial:tkApplicationMenu];
    [windowsMenu setSpecial:tkWindowsMenu];
    [helpMenu setSpecial:tkHelpMenu];
    [self tkSetMainMenu:nil];
}

- (void) dealloc
{
    [_defaultMainMenu release];
    [_defaultHelpMenuItems release];
    [_defaultWindowsMenuItems release];
    [_defaultApplicationMenuItems release];
    [_defaultFileMenuItems release];
    [super dealloc];
}

- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem
{
    SEL action = [anItem action];

    if (sel_isEqual(action, @selector(preferences:))) {

	return (_eventInterp && Tcl_FindCommand(_eventInterp,
		"::tk::mac::ShowPreferences", NULL, 0));
    } else if (sel_isEqual(action, @selector(tkDemo:))) {
	BOOL haveDemo = NO;

	if (_eventInterp) {
	    Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);

	    if (path) {
		Tcl_IncrRefCount(path);
		haveDemo = (Tcl_FSAccess(path, R_OK) == 0);
		Tcl_DecrRefCount(path);
	    }
	}
	return haveDemo;
    } else {
        return [super validateUserInterfaceItem:anItem];
    }
}

- (void) orderFrontStandardAboutPanel: (id) sender
{
    (void)sender;

    if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
	    NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
	TkAboutDlg();
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) showHelp: (id) sender
{
    if (!_eventInterp || !Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ShowHelp", NULL, 0)) {
	[super showHelp:sender];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowHelp", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) tkSource: (id) sender
{
    (void)sender;

    if (_eventInterp) {
	if (Tcl_EvalEx(_eventInterp, "tk_getOpenFile -filetypes {"
		"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
		-1, TCL_EVAL_GLOBAL) == TCL_OK) {
	    Tcl_Obj *path = Tcl_GetObjResult(_eventInterp);
	    int len;

	    Tcl_GetStringFromObj(path, &len);
	    if (len) {
		Tcl_IncrRefCount(path);

		int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);

		if (code != TCL_OK) {
		    Tcl_BackgroundException(_eventInterp, code);
		}
		Tcl_DecrRefCount(path);
	    }
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) tkDemo: (id) sender
{
	(void)sender;

    if (_eventInterp) {
	Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);

	if (path) {
	    Tcl_IncrRefCount(path);

	    [_demoMenuItem setHidden:YES];
	    int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);

	    if (code != TCL_OK) {
		Tcl_BackgroundException(_eventInterp, code);
	    }
	    Tcl_DecrRefCount(path);
	    Tcl_ResetResult(_eventInterp);
	}
    }
}
@end

#pragma mark TKContentView(TKMenus)

@implementation TKContentView(TKMenus)

- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem
{
    (void)anItem;

    return YES;
}

#define EDIT_ACTION(a, e) \
    - (void) a: (id) sender \
    { \
	if ([sender isKindOfClass:[NSMenuItem class]]) { \
	    GenerateEditEvent(#e); \
	} \
    }
EDIT_ACTION(cut, Cut)
EDIT_ACTION(copy, Copy)
EDIT_ACTION(paste, Paste)







|
|







|
<
<
<
















<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|

|


















<
|
<




<


<
|
<



>
|
|


<














<
|
<
<
|
|
|




<

|




|
|
<
|
|




<

|




|
<
<
<
<






<



<
|
<

|







|
<
<
<
<


<


<
<
|
<

|







|



<
|
<
<
<


<

|
<







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97










98





















99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122

123
124
125
126

127
128

129

130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151

152


153
154
155
156
157
158
159

160
161
162
163
164
165
166
167

168
169
170
171
172
173

174
175
176
177
178
179
180




181
182
183
184
185
186

187
188
189

190

191
192
193
194
195
196
197
198
199
200




201
202

203
204


205

206
207
208
209
210
211
212
213
214
215
216
217
218

219



220
221

222
223

224
225
226
227
228
229
230
	    nil] retain];
    _defaultApplicationMenu = [TKMenu menuWithTitle:applicationName
	    menuItems:_defaultApplicationMenuItems];
    [_defaultApplicationMenu insertItem:
	    [NSMenuItem itemWithTitle:
		    [NSString stringWithFormat:@"About %@", aboutName]
		    action:@selector(orderFrontStandardAboutPanel:)] atIndex:0];
    TKMenu *fileMenu = [TKMenu menuWithTitle:@"File" menuItems:
	    [NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"Source%C", 0x2026]
		   action:@selector(tkSource:)],
	    [NSMenuItem itemWithTitle:@"Run Widget Demo"
		   action:@selector(tkDemo:)],
	    [NSMenuItem itemWithTitle:@"Close" action:@selector(performClose:)
		   target:nil keyEquivalent:@"w"],
	    nil]];



    TKMenu *editMenu = [TKMenu menuWithTitle:@"Edit" menuItems:
	    [NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:@"Undo" action:@selector(undo:)
		   target:nil keyEquivalent:@"z"],
	    [NSMenuItem itemWithTitle:@"Redo" action:@selector(redo:)
		   target:nil keyEquivalent:@"y"],
	    [NSMenuItem separatorItem],
	    [NSMenuItem itemWithTitle:@"Cut" action:@selector(cut:)
		   target:nil keyEquivalent:@"x"],
	    [NSMenuItem itemWithTitle:@"Copy" action:@selector(copy:)
		   target:nil keyEquivalent:@"c"],
	    [NSMenuItem itemWithTitle:@"Paste" action:@selector(paste:)
		   target:nil keyEquivalent:@"v"],
	    [NSMenuItem itemWithTitle:@"Delete" action:@selector(delete:)
		   target:nil],
	    nil]];

    _defaultWindowsMenuItems = [[NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:@"Minimize"
		   action:@selector(performMiniaturize:) target:nil
		   keyEquivalent:@"m"],
	    [NSMenuItem itemWithTitle:@"Zoom" action:@selector(performZoom:)
		   target:nil],










	    [NSMenuItem separatorItem],





















	    [NSMenuItem itemWithTitle:@"Bring All to Front"
		   action:@selector(arrangeInFront:)],
	    nil] retain];
    TKMenu *windowsMenu = [TKMenu menuWithTitle:@"Window" menuItems:
	    _defaultWindowsMenuItems];
    _defaultHelpMenuItems = [[NSArray arrayWithObjects:
	    [NSMenuItem itemWithTitle:
		   [NSString stringWithFormat:@"%@ Help", applicationName]
		   action:@selector(showHelp:) keyEquivalent:@"?"],
	    nil] retain];
    TKMenu *helpMenu = [TKMenu menuWithTitle:@"Help" menuItems:
	    _defaultHelpMenuItems];
    [self setServicesMenu:_servicesMenu];
    [self setWindowsMenu:windowsMenu];
    _defaultMainMenu = [[TKMenu menuWithTitle:@"" submenus:[NSArray
	    arrayWithObjects:_defaultApplicationMenu, fileMenu, editMenu,
	    windowsMenu, helpMenu, nil]] retain];
    [_defaultMainMenu setSpecial:tkMainMenu];
    [_defaultApplicationMenu setSpecial:tkApplicationMenu];
    [windowsMenu setSpecial:tkWindowsMenu];
    [helpMenu setSpecial:tkHelpMenu];
    [self tkSetMainMenu:nil];
}

- (void)dealloc {

    [_defaultMainMenu release];
    [_defaultHelpMenuItems release];
    [_defaultWindowsMenuItems release];
    [_defaultApplicationMenuItems release];

    [super dealloc];
}

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem {

    SEL action = [anItem action];

    if (sel_isEqual(action, @selector(preferences:))) {
	Tcl_CmdInfo dummy;
	return (_eventInterp && Tcl_GetCommandInfo(_eventInterp,
		"::tk::mac::ShowPreferences", &dummy));
    } else if (sel_isEqual(action, @selector(tkDemo:))) {
	BOOL haveDemo = NO;

	if (_eventInterp) {
	    Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);

	    if (path) {
		Tcl_IncrRefCount(path);
		haveDemo = (Tcl_FSAccess(path, R_OK) == 0);
		Tcl_DecrRefCount(path);
	    }
	}
	return haveDemo;
    } else {
        return [super validateUserInterfaceItem:anItem];
    }
}

- (void)orderFrontStandardAboutPanel:(id)sender {


    Tcl_CmdInfo dummy;
    if (!_eventInterp || !Tcl_GetCommandInfo(_eventInterp, "tkAboutDialog",
	    &dummy) || (GetCurrentEventKeyModifiers() & optionKey)) {
	TkAboutDlg();
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
	Tcl_ResetResult(_eventInterp);
    }
}
- (void)showHelp:(id)sender {
    Tcl_CmdInfo dummy;

    if (!_eventInterp || !Tcl_GetCommandInfo(_eventInterp,
	    "::tk::mac::ShowHelp", &dummy)) {
	[super showHelp:sender];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowHelp", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
	Tcl_ResetResult(_eventInterp);
    }
}
- (void)tkSource:(id)sender {




    if (_eventInterp) {
	if (Tcl_EvalEx(_eventInterp, "tk_getOpenFile -filetypes {"
		"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
		-1, TCL_EVAL_GLOBAL) == TCL_OK) {
	    Tcl_Obj *path = Tcl_GetObjResult(_eventInterp);
	    int len;

	    Tcl_GetStringFromObj(path, &len);
	    if (len) {
		Tcl_IncrRefCount(path);

		int code = Tcl_FSEvalFile(_eventInterp, path);

		if (code != TCL_OK) {
		    Tcl_BackgroundError(_eventInterp);
		}
		Tcl_DecrRefCount(path);
	    }
	}
	Tcl_ResetResult(_eventInterp);
    }
}
- (void)tkDemo:(id)sender {




    if (_eventInterp) {
	Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);

	if (path) {
	    Tcl_IncrRefCount(path);


	    int code = Tcl_FSEvalFile(_eventInterp, path);

	    if (code != TCL_OK) {
		Tcl_BackgroundError(_eventInterp);
	    }
	    Tcl_DecrRefCount(path);
	    Tcl_ResetResult(_eventInterp);
	}
    }
}
@end

#pragma mark TKContentView(TKMenus)

@implementation TKContentView(TKMenus)

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem {



    return YES;
}

#define EDIT_ACTION(a, e) \
    - (void) a:(id)sender { \

	if ([sender isKindOfClass:[NSMenuItem class]]) { \
	    GenerateEditEvent(#e); \
	} \
    }
EDIT_ACTION(cut, Cut)
EDIT_ACTION(copy, Copy)
EDIT_ACTION(paste, Paste)
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetWidgetDemoPath(
    Tcl_Interp *interp)
{
    Tcl_Obj *result = NULL;

    if (Tcl_EvalEx(interp, "::tk::pkgconfig get demodir,runtime",
		   -1, TCL_EVAL_GLOBAL) == TCL_OK) {

	Tcl_Obj *libpath, *demo[1] = { Tcl_NewStringObj("widget", 6) };

	libpath = Tcl_GetObjResult(interp);
	Tcl_IncrRefCount(libpath);
	result = Tcl_FSJoinToPath(libpath, 1, demo);
	Tcl_DecrRefCount(libpath);
    }
    Tcl_ResetResult(interp);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHandleMenuSelect --







|

|
|
>
|

<

|

|
|
>







252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetWidgetDemoPath(
    Tcl_Interp *interp)
{
    Tcl_Obj *libpath, *result = NULL;

    libpath = Tcl_GetVar2Ex(interp, "tk_library", NULL, TCL_GLOBAL_ONLY);
    if (libpath) {
	Tcl_Obj *demo[2] = {	Tcl_NewStringObj("demos", 5),
				Tcl_NewStringObj("widget", 6) };


	Tcl_IncrRefCount(libpath);
	result = Tcl_FSJoinToPath(libpath, 2, demo);
	Tcl_DecrRefCount(libpath);
    } else {
	Tcl_ResetResult(interp);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHandleMenuSelect --
359
360
361
362
363
364
365
366
367
368
369
370
371























372
373
374
375
376
377
378
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXHandleMenuSelect(
    TCL_UNUSED(short),
    TCL_UNUSED(unsigned short),
    TCL_UNUSED(int))
{
    Tcl_Panic("TkMacOSXHandleMenuSelect: Obsolete, no more Carbon!");
}
























/*
 *----------------------------------------------------------------------
 *
 * GenerateEditEvent --
 *
 *	Takes an edit menu item and posts the corasponding a virtual event to







|
|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXHandleMenuSelect(
    short theMenu,
    unsigned short theItem,
    int optionKeyPressed)
{
    Tcl_Panic("TkMacOSXHandleMenuSelect: Obsolete, no more Carbon!");
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitMenus --
 *
 *	This procedure initializes the Macintosh menu bar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitMenus(
    Tcl_Interp *interp)
{
    [NSApp _setupMenus];
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateEditEvent --
 *
 *	Takes an edit menu item and posts the corasponding a virtual event to
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
static void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin;

    if (!winPtr) {
	return;
    }
    tkwin = (Tk_Window)winPtr->dispPtr->focusPtr;
    if (!tkwin) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid(name);
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

#pragma mark -

#pragma mark NSMenu & NSMenuItem Utilities

@implementation NSMenu(TKUtils)

+ (id) menuWithTitle: (NSString *) title
{
    NSMenu *m = [[self alloc] initWithTitle:title];

    return [m autorelease];
}

+ (id) menuWithTitle: (NSString *) title menuItems: (NSArray *) items
{
    NSMenu *m = [[self alloc] initWithTitle:title];

    for (NSMenuItem *i in items) {
	[m addItem:i];
    }
    return [m autorelease];
}

+ (id) menuWithTitle: (NSString *) title submenus: (NSArray *) submenus
{
    NSMenu *m = [[self alloc] initWithTitle:title];

    for (NSMenu *i in submenus) {
	[m addItem:[NSMenuItem itemWithSubmenu:i]];
    }
    return [m autorelease];
}

- (NSMenuItem *) itemWithSubmenu: (NSMenu *) submenu
{
    return [self itemAtIndex:[self indexOfItemWithSubmenu:submenu]];
}

- (NSMenuItem *) itemInSupermenu
{
    NSMenu *supermenu = [self supermenu];

    return (supermenu ? [supermenu itemWithSubmenu:self] : nil);
}
@end

@implementation NSMenuItem(TKUtils)

+ (id) itemWithSubmenu: (NSMenu *) submenu
{
    NSMenuItem *i = [[self alloc] initWithTitle:[submenu title] action:NULL
	    keyEquivalent:@""];

    [i setSubmenu:submenu];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title submenu: (NSMenu *) submenu
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:NULL
	    keyEquivalent:@""];

    [i setSubmenu:submenu];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:@""];

    [i setTarget:NSApp];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
	target: (id) target
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:@""];

    [i setTarget:target];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
	keyEquivalent: (NSString *) keyEquivalent
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:NSApp];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
	target: (id) target keyEquivalent: (NSString *) keyEquivalent
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:target];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
	keyEquivalent: (NSString *) keyEquivalent
	keyEquivalentModifierMask: (NSUInteger) keyEquivalentModifierMask
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:NSApp];
    [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
    return [i autorelease];
}

+ (id) itemWithTitle: (NSString *) title action: (SEL) action
	target: (id) target keyEquivalent: (NSString *) keyEquivalent
	keyEquivalentModifierMask: (NSUInteger) keyEquivalentModifierMask
{
    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:target];
    [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
    return [i autorelease];
}
@end

/*







|

|


|
|




















<



<
|
<

<


|
<
<

<





|
<
<

<





|
<
<


<
|
<

<





<
|
<


<



|
<
<


<



|
<
<


<



|
<
|
<


<



|
<
|
<


<



|
<
|
<


<



|
<
|
|
<


<




|
<
|
|
<


<







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374
375
376

377

378

379
380
381


382

383
384
385
386
387
388


389

390
391
392
393
394
395


396
397

398

399

400
401
402
403
404

405

406
407

408
409
410
411


412
413

414
415
416
417


418
419

420
421
422
423

424

425
426

427
428
429
430

431

432
433

434
435
436
437

438

439
440

441
442
443
444

445
446

447
448

449
450
451
452
453

454
455

456
457

458
459
460
461
462
463
464
static void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin = (Tk_Window) winPtr;

    if (tkwin == NULL) {
	return;
    }
    tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
    if (tkwin == NULL) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid(name);
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

#pragma mark -

#pragma mark NSMenu & NSMenuItem Utilities

@implementation NSMenu(TKUtils)

+ (id)menuWithTitle:(NSString *)title {

    NSMenu *m = [[self alloc] initWithTitle:title];

    return [m autorelease];
}
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items {


    NSMenu *m = [[self alloc] initWithTitle:title];

    for (NSMenuItem *i in items) {
	[m addItem:i];
    }
    return [m autorelease];
}
+ (id)menuWithTitle:(NSString *)title submenus:(NSArray *)submenus {


    NSMenu *m = [[self alloc] initWithTitle:title];

    for (NSMenu *i in submenus) {
	[m addItem:[NSMenuItem itemWithSubmenu:i]];
    }
    return [m autorelease];
}
- (NSMenuItem *)itemWithSubmenu:(NSMenu *)submenu {


    return [self itemAtIndex:[self indexOfItemWithSubmenu:submenu]];
}

- (NSMenuItem *)itemInSupermenu {

    NSMenu *supermenu = [self supermenu];

    return (supermenu ? [supermenu itemWithSubmenu:self] : nil);
}
@end

@implementation NSMenuItem(TKUtils)

+ (id)itemWithSubmenu:(NSMenu *)submenu {

    NSMenuItem *i = [[self alloc] initWithTitle:[submenu title] action:NULL
	    keyEquivalent:@""];

    [i setSubmenu:submenu];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title submenu:(NSMenu *)submenu {


    NSMenuItem *i = [[self alloc] initWithTitle:title action:NULL
	    keyEquivalent:@""];

    [i setSubmenu:submenu];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action {


    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:@""];

    [i setTarget:NSApp];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action

	target:(id)target {

    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:@""];

    [i setTarget:target];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action

	keyEquivalent:(NSString *)keyEquivalent {

    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:NSApp];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action

	target:(id)target keyEquivalent:(NSString *)keyEquivalent {

    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:target];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action

	keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask {

    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:NSApp];
    [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
    return [i autorelease];
}
+ (id)itemWithTitle:(NSString *)title action:(SEL)action

	target:(id)target keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask {

    NSMenuItem *i = [[self alloc] initWithTitle:title action:action
	    keyEquivalent:keyEquivalent];

    [i setTarget:target];
    [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
    return [i autorelease];
}
@end

/*

Changes to macosx/tkMacOSXMouseEvent.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94

95




96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170


171
172
173
174
175

176
177

178
179
180




181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245



246
247
248
249
250

251
252
253
254
255
256
257


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

typedef struct {
    unsigned int state;
    long delta;
    Window window;
    Point global;
    Point local;
} MouseEventData;

static Tk_Window captureWinPtr = NULL;	/* Current capture window; may be
					 * NULL. */

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
			    UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};

/*
 * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
 * window attribute pointing to the active window.  As of 10.8 this behavior
 * had changed.  The new behavior was that if the mouse were ever moved outside
 * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute until the mouse returned to the window.  In 11.1 it changed again.

 * The window attribute can be non-nil, but referencing a window which does not
 * belong to the application.
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    NSRect viewFrame = [[eventWindow contentView] frame];
    NSPoint location = [theEvent locationInWindow];
    TkWindow *winPtr = NULL, *grabWinPtr;
    Tk_Window tkwin = NULL, capture, target;
    NSPoint local, global;
    NSInteger button;
    Bool inTitleBar = NO;
    int win_x, win_y;
    unsigned int buttonState = 0;
    static int validPresses = 0, ignoredPresses = 0;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif

    /*
     * If this event is not for a Tk toplevel, it should just be passed up the


     * responder chain.  However, there is an exception for synthesized events,

     * which are used in testing.  Those events are recognized by having their
     * both the windowNumber and the eventNumber set to -1.
     */

    if (eventWindow && ![eventWindow isMemberOfClass:[TKWindow class]]) {
	if ([theEvent windowNumber] != -1 || [theEvent eventNumber] != -1)
	    return theEvent;
    }

    /*
     * Check if the event is located in the titlebar.
     */

    if (eventWindow) {
	inTitleBar = viewFrame.size.height < location.y;
    }

    button = [theEvent buttonNumber] + Button1;
    if ((button & -2) == Button2) {
	button ^= 1; /* Swap buttons 2/3 */

    }

    switch (eventType) {




    case NSRightMouseUp:

    case NSOtherMouseUp:
	buttonState &= ~Tk_GetButtonMask(button);
	break;
    case NSLeftMouseDragged:
    case NSRightMouseDragged:
    case NSOtherMouseDragged:
    case NSRightMouseDown:
    case NSOtherMouseDown:
	buttonState |= Tk_GetButtonMask(button);
	break;
    case NSMouseEntered:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    !inTitleBar) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:YES];
	}
	break;
    case NSMouseExited:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)]) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:NO];
	    break;

	}
    case NSLeftMouseUp:
    case NSLeftMouseDown:
    case NSMouseMoved:
    case NSScrollWheel:
#if 0
    case NSCursorUpdate:
    case NSTabletPoint:
    case NSTabletProximity:
#endif

	break;
    default: /* This type of event is ignored. */
	return theEvent;
    }

    /*
     * Update the button state.  We ignore left button presses that start a
     * resize or occur in the title bar.  See tickets [d72abe6b54] and
     * [39cbacb9e8].
     */

    if (eventType == NSLeftMouseDown) {
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    [(TKWindow *) eventWindow mouseInResizeArea]) {

	    /*
	     * When the left button is pressed in the resize area, we receive
	     * NSMouseDown, but when it is released we do not receive
	     * NSMouseUp.  So ignore the event and clear the button state but
	     * do not change the ignoredPresses count.
	     */

	    buttonState &= ~Tk_GetButtonMask(Button1);
	    return theEvent;
	}
	if (inTitleBar) {
	    ignoredPresses++;
	    return theEvent;
	}
	validPresses++;
	buttonState |= Tk_GetButtonMask(Button1);
    }
    if (eventType == NSLeftMouseUp) {
	if (ignoredPresses > 0) {
	    ignoredPresses--;
	} else if (validPresses > 0) {
	    validPresses--;
	}
	if (validPresses == 0) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	}
    }

    /*


     * Find an appropriate NSWindow to attach to this event, and its
     * associated Tk window.
     */

    capture = TkpGetCapture();

    if (capture) {
	winPtr = (TkWindow *) capture;

	eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	if (!eventWindow) {
	    return theEvent;




	}
    } else {
	if (eventWindow) {
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
	if (!winPtr) {
	    eventWindow = [NSApp mainWindow];
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
    }
    if (!winPtr) {

	/*
	 * We couldn't find a Tk window for this event.  We have to ignore it.
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TkMacOSXDbgMsg("Event received with no Tk window.");
#endif
	return theEvent;
    }
    tkwin = (Tk_Window) winPtr;

    /*
     * Compute the mouse position in local (window) and global (screen)
     * coordinates.  These are Tk coordinates, meaning that the local origin is
     * at the top left corner of the containing toplevel and the global origin
     * is at top left corner of the primary screen.
     */

    global = [NSEvent mouseLocation];
    local = [eventWindow tkConvertPointFromScreen: global];
    global.x = floor(global.x);
    global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
    local.x = floor(local.x);
    local.y = floor([eventWindow frame].size.height - local.y);
    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	}
    } else {

	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;
    }

    /*
     * Use the local coordinates to find the Tk window which should receive
     * this event.  Also convert local into the coordinates of that window.
     * (The converted local coordinates are only needed for scrollwheel
     * events.)
     */

    target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);

    /*
     * Ignore the event if a local grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */




    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr && /* There is a grab in effect ... */
	!winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
	grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
	Tk_Window tkwin2;

	if (!target) {
	    return theEvent;
	}
	for (tkwin2 = target;
	     !Tk_IsTopLevel(tkwin2);
	     tkwin2 = Tk_Parent(tkwin2)) {
	    if (tkwin2 == (Tk_Window)grabWinPtr) {


		break;
	    }
	}
	if (tkwin2 != (Tk_Window)grabWinPtr) {
	    return theEvent;
	}
    }

    /*
     *  Generate an XEvent for this mouse event.
     */

    unsigned int state = buttonState;
    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;







|

<









<
<
<


|












|
>
|
<



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
<
|
>
>
|
>
<
<
<

|
<
|
<
|
<
<
<
|
|
<
|
|
<
|
<
>
|
>
|
>
>
>
>

>

<
<



<
<
<
<
|
<
|
|
<
|
<
<
|
<
>

<
<
<
<
|
<


<
>
|
|



<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<

<
<
|
<
|
<

<
<
<
<
<
|
<
<
<
<
|
<
>
>
|
|
<
|
<
>
|
|
>
|
|
<
>
>
>
>

<
<
<
|
<
<
<
|
<
|
|
<
|
<
|
<
|
<
<

|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>
|
|
|
|
<
<
<
<
<
<
<
|
|
<
<
<
<

>
>
>
|
|
|
|
|
>
|
|
<
|
|
|
|
>
>

<
<
|
|
|
|
|
<
<
<
<
<







9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48














49
50
51
52

53
54
55
56
57



58
59

60

61



62
63

64
65

66

67
68
69
70
71
72
73
74
75
76
77


78
79
80




81

82
83

84


85

86
87




88

89
90

91
92
93
94
95
96





97


98
99






100


101


102

103

104





105




106

107
108
109
110

111

112
113
114
115
116
117

118
119
120
121
122



123



124

125
126

127

128

129


130
131
132






133















134

135
136
137
138
139







140
141




142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160


161
162
163
164
165





166
167
168
169
170
171
172
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"


typedef struct {
    unsigned int state;
    long delta;
    Window window;
    Point global;
    Point local;
} MouseEventData;




static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
					      UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};

/*
 * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
 * window attribute pointing to the active window.  As of 10.8 this behavior
 * had changed.  The new behavior was that if the mouse were ever moved outside
 * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute.  To work around this the TKApplication remembers the last non-Nil
 * window that it received in a mouse event. If it receives an NSEvent with a
 * Nil window attribute then the saved window is used.

 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent {














#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow*    eventWindow = [theEvent window];

    NSEventType	 eventType = [theEvent type];
#if 0
    NSTrackingArea  *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif




    switch (eventType) {

    case NSMouseEntered:

	/* Remember which window has the mouse. */



	if (_windowWithMouse) {
	    [_windowWithMouse release];

	}
	_windowWithMouse = [theEvent window];

	if (_windowWithMouse) {

	    [_windowWithMouse retain];
	}
	break;
    case NSMouseExited:
    case NSCursorUpdate:
    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSRightMouseDown:
    case NSRightMouseUp:
    case NSOtherMouseDown:
    case NSOtherMouseUp:


    case NSLeftMouseDragged:
    case NSRightMouseDragged:
    case NSOtherMouseDragged:




    case NSMouseMoved:

#if 0
	eventNumber = [theEvent eventNumber];

	if (!trackingArea) {


	    clickCount = [theEvent clickCount];

	    buttonNumber = [theEvent buttonNumber];
	}




#endif

    case NSTabletPoint:
    case NSTabletProximity:

    case NSScrollWheel:
        break;
    default: /* Unrecognized mouse event. */
	return theEvent;
    }






    /* Remember the window in case we need it next time. */


    if (eventWindow && eventWindow != _windowWithMouse) {
	if (_windowWithMouse) {






	    [_windowWithMouse release];


	}


	_windowWithMouse = eventWindow;

	[_windowWithMouse retain];

    }










    /* Create an Xevent to add to the Tk queue. */

    NSPoint global, local = [theEvent locationInWindow];
    if (eventWindow) { /* local will be in window coordinates. */
	global = [eventWindow convertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;

	global.y = tkMacOSXZeroScreenHeight - global.y;

    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow convertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;

	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}



    }





    Window window = TkMacOSXGetXWindow(eventWindow);
    Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,

	    window) : NULL;

    if (!tkwin) {

	tkwin = TkMacOSXGetCapture();


    }
    if (!tkwin) {
	return theEvent; /* Give up.  No window for this event. */






    }

















    TkWindow  *winPtr = (TkWindow *) tkwin;
    local.x -= winPtr->wmInfoPtr->xInParent;
    local.y -= winPtr->wmInfoPtr->yInParent;

    int win_x, win_y;







    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y,
		&win_x, &win_y);





    unsigned int state = 0;
    NSInteger button = [theEvent buttonNumber];
    EventRef eventRef = (EventRef)[theEvent eventRef];
    UInt32 buttons;
    OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
	    typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
    if (err == noErr) {
	state |= (buttons & ((1<<5) - 1)) << 8;
    } else {
	if (button < 5) {
	    switch (eventType) {

	    case NSLeftMouseDown:
	    case NSRightMouseDown:
	    case NSLeftMouseDragged:
	    case NSRightMouseDragged:
	    case NSOtherMouseDown:
		state |= 1 << (button + 8);
		break;


	    default:
		break;
	    }
	}
    }





    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328
329
330
331
332
333
334


335
336
337
338
339
340
341
342
343
344
345




























346
347
348
349
350
351
352
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {

	/*
	 * For normal mouse events, Tk_UpdatePointer will send the appropriate
	 * XEvents using its cached state information.  Unfortunately, it will
	 * also recompute the local coordinates.
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
		target, global.x, global.y, state);
#endif

	Tk_UpdatePointer(target, global.x, global.y, state);
    } else {
	CGFloat delta;

	XEvent xEvent;

	/*
	 * For scroll wheel events we need to send the XEvent here.
	 */

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = win_x;
	xEvent.xbutton.y = win_y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(target);
	xEvent.xany.window = Tk_WindowId(target);

	delta = [theEvent deltaY] * 120;
	if (delta != 0.0) {


	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX] * 120;
	if (delta != 0.0) {


	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }
    return theEvent;
}
@end

#pragma mark -





























/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXButtonKeyState --
 *
 *	Returns the current state of the button & modifier keys.







<
<
<
<
<
<
<

|
<

<
|
|

>


<
<
<
<

|
|



|
|

|

>
>

|



|

>
>

|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







184
185
186
187
188
189
190







191
192

193

194
195
196
197
198
199




200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {







#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);

#endif

	Tk_UpdatePointer(tkwin, global.x, global.y, state);
    } else { /* handle scroll wheel event */
	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;





	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(tkwin);
	xEvent.xany.window = Tk_WindowId(tkwin);

	delta = [theEvent deltaY];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		(signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		(signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }
    return theEvent;
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXKeyModifiers --
 *
 *	Returns the current state of the modifier keys.
 *
 * Results:
 *	An OS Modifier state.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

EventModifiers
TkMacOSXModifierState(void)
{
    UInt32 keyModifiers;
    int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());

    keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
	    GetCurrentKeyModifiers();

    return (EventModifiers) (keyModifiers & USHRT_MAX);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXButtonKeyState --
 *
 *	Returns the current state of the button & modifier keys.
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
ButtonModifiers2State(
    UInt32 buttonState,
    UInt32 keyModifiers)
{
    unsigned int state;

    /*
     * Tk on OSX supports at most 9 buttons.
     */

    state = (buttonState & 0x079) * Button1Mask;
	/* Handle swapped buttons 2/3 */
	if (buttonState & 0x02) {
	    state |= Button3Mask;
	}
	if (buttonState & 0x04) {
	    state |= Button2Mask;
	}
	/* Handle buttons 8/9 */
    state |= (buttonState & 0x180) * (Button8Mask >> 7);

    if (keyModifiers & alphaLock) {
	state |= LockMask;
    }
    if (keyModifiers & shiftKey) {
	state |= ShiftMask;
    }







|


|
<
<
<
<
<
<
<
<
<







311
312
313
314
315
316
317
318
319
320
321









322
323
324
325
326
327
328
ButtonModifiers2State(
    UInt32 buttonState,
    UInt32 keyModifiers)
{
    unsigned int state;

    /*
     * Tk supports at most 5 buttons.
     */

    state = (buttonState & ((1<<5) - 1)) << 8;










    if (keyModifiers & alphaLock) {
	state |= LockMask;
    }
    if (keyModifiers & shiftKey) {
	state |= ShiftMask;
    }
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    int getGlobal = (root_x_return && root_y_return);
    int getLocal = (win_x_return && win_y_return && w != None);
    (void)display;
    (void)root_return;
    (void)child_return;

    if (getGlobal || getLocal) {
	NSPoint global = [NSEvent mouseLocation];

	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *)w;
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(w);

	    if (win) {
		NSPoint local;

		local = [win tkConvertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
	    }
	}
	if (getGlobal) {
	    *root_x_return = global.x;
	    *root_y_return = TkMacOSXZeroScreenHeight() - global.y;
	}
    }
    if (mask_return) {
	*mask_return = TkMacOSXButtonKeyState();
    }
    return True;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGenerateButtonEventForXPointer --
 *
 *	This procedure generates an X button event for the current pointer
 *	state as reported by XQueryPointer().
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkGenerateButtonEventForXPointer(







<
<
<





|
|




|











|




















|







374
375
376
377
378
379
380



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    int getGlobal = (root_x_return && root_y_return);
    int getLocal = (win_x_return && win_y_return && w != None);




    if (getGlobal || getLocal) {
	NSPoint global = [NSEvent mouseLocation];

	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win convertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
	    }
	}
	if (getGlobal) {
	    *root_x_return = global.x;
	    *root_y_return = tkMacOSXZeroScreenHeight - global.y;
	}
    }
    if (mask_return) {
	*mask_return = TkMacOSXButtonKeyState();
    }
    return True;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGenerateButtonEventForXPointer --
 *
 *	This procedure generates an X button event for the current pointer
 *	state as reported by XQueryPointer().
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkGenerateButtonEventForXPointer(
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

/*
 *----------------------------------------------------------------------
 *
 * TkGenerateButtonEvent --
 *
 *	Given a global x & y position and the button key status this procedure
 *	generates the appropriate X button event. It also handles the state
 *	changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated, false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

int
TkGenerateButtonEvent(
    int x,			/* X location of mouse, */
    int y,			/* Y location of mouse. */
    Window window,		/* X Window containing button event. */
    unsigned int state)		/* Button Key state suitable for X event. */
{
    MacDrawable *macWin = (MacDrawable *)window;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    MouseEventData med;

    bzero(&med, sizeof(MouseEventData));
    med.state = state;
    med.window = window;
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, TkMacOSXZeroScreenHeight() - y);

	local = [win tkConvertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = TkMacOSXZeroScreenHeight() - local.y;
    }

    return GenerateButtonEvent(&med);
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateButtonEvent --
 *
 *	Generate an X button event from a MouseEventData structure. Handles
 *	the state changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateButtonEvent(
    MouseEventData *medPtr)
{
    Tk_Window tkwin;
    int dummy;
    TkDisplay *dispPtr;

#ifdef UNUSED

    /*
     * ButtonDown events will always occur in the front window. ButtonUp
     * events, however, may occur anywhere on the screen. ButtonUp events
     * should only be sent to Tk if in the front window or during an implicit
     * grab.
     */

    if ((medPtr->activeNonFloating == NULL)
	    || ((!(TkpIsWindowFloating(medPtr->whichWin))
	    && (medPtr->activeNonFloating != medPtr->whichWin))
	    && TkpGetCapture() == NULL)) {
	return false;
    }
#endif

    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (tkwin != NULL) {
	tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v,
		&dummy, &dummy);
    }

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWarpPointer --
 *
 *	Move the mouse cursor to the screen location specified by the warpX and
 *	warpY fields of a TkDisplay.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The mouse cursor is moved.
 *
 *----------------------------------------------------------------------
 */

void
TkpWarpPointer(
    TkDisplay *dispPtr)
{
    CGPoint pt;

    if (dispPtr->warpWindow) {
	int x, y;
	Tk_GetRootCoords(dispPtr->warpWindow, &x, &y);
	pt.x = x + dispPtr->warpX;
	pt.y = y + dispPtr->warpY;
    } else {
	pt.x = dispPtr->warpX;
	pt.y = dispPtr->warpY;
    }

    CGWarpMouseCursorPosition(pt);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
 *	This function captures the mouse so that all future events will be
 *	reported to this window, even if the mouse is outside the window. If
 *	the specified window is NULL, then the mouse is released.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the capture flag and captures the mouse.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetCapture(
    TkWindow *winPtr)		/* Capture window, or NULL. */
{
    while (winPtr && !Tk_IsTopLevel(winPtr)) {
	winPtr = winPtr->parentPtr;
    }
    captureWinPtr = (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetCapture --
 *
 * Results:
 *	Returns the current grab window
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkpGetCapture(void)
{
    return captureWinPtr;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|






|












|
|










|

|






|

















|













|
<










|

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557




















































































558
559
560
561
562
563
564

/*
 *----------------------------------------------------------------------
 *
 * TkGenerateButtonEvent --
 *
 *	Given a global x & y position and the button key status this procedure
 *	generates the appropiate X button event. It also handles the state
 *	changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated, false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

int
TkGenerateButtonEvent(
    int x,			/* X location of mouse, */
    int y,			/* Y location of mouse. */
    Window window,		/* X Window containing button event. */
    unsigned int state)		/* Button Key state suitable for X event. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    NSWindow *win = TkMacOSXDrawableWindow(window);
    MouseEventData med;

    bzero(&med, sizeof(MouseEventData));
    med.state = state;
    med.window = window;
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);

	local = [win convertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = tkMacOSXZeroScreenHeight - local.y;
    }

    return GenerateButtonEvent(&med);
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateButtonEvent --
 *
 *	Generate an X button event from a MouseEventData structure. Handles
 *	the state changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateButtonEvent(
    MouseEventData *medPtr)
{
    Tk_Window tkwin;
    int dummy;
    TkDisplay *dispPtr;

#if UNUSED

    /*
     * ButtonDown events will always occur in the front window. ButtonUp
     * events, however, may occur anywhere on the screen. ButtonUp events
     * should only be sent to Tk if in the front window or during an implicit
     * grab.
     */

    if ((medPtr->activeNonFloating == NULL)
	    || ((!(TkpIsWindowFloating(medPtr->whichWin))
	    && (medPtr->activeNonFloating != medPtr->whichWin))
	    && TkMacOSXGetCapture() == NULL)) {
	return false;
    }
#endif

    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (tkwin != NULL) {
	tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v,
		&dummy, &dummy);
    }

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
    return true;
}

/*




















































































 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXNotify.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114














115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
 * tkMacOSXNotify.c --
 *
 *	This file contains the implementation of a tcl event source
 *	for the AppKit event loop.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2015 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tclInt.h>
#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"

#import <objc/objc-auto.h>

/* This is not used for anything at the moment. */
typedef struct ThreadSpecificData {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#ifdef TK_MAC_DEBUG_EVENTS
static const char *Tk_EventName[39] = {
    "",
    "",
    "KeyPress",		/*2*/
    "KeyRelease",      	/*3*/
    "ButtonPress",     	/*4*/
    "ButtonRelease",	/*5*/
    "MotionNotify",    	/*6*/
    "EnterNotify",     	/*7*/
    "LeaveNotify",     	/*8*/
    "FocusIn",		/*9*/
    "FocusOut",		/*10*/
    "KeymapNotify",    	/*11*/
    "Expose",		/*12*/
    "GraphicsExpose",	/*13*/
    "NoExpose",		/*14*/
    "VisibilityNotify",	/*15*/
    "CreateNotify",    	/*16*/
    "DestroyNotify",	/*17*/
    "UnmapNotify",     	/*18*/
    "MapNotify",       	/*19*/
    "MapRequest",      	/*20*/
    "ReparentNotify",	/*21*/
    "ConfigureNotify",	/*22*/
    "ConfigureRequest",	/*23*/
    "GravityNotify",	/*24*/
    "ResizeRequest",	/*25*/
    "CirculateNotify",	/*26*/
    "CirculateRequest",	/*27*/
    "PropertyNotify",	/*28*/
    "SelectionClear",	/*29*/
    "SelectionRequest",	/*30*/
    "SelectionNotify",	/*31*/
    "ColormapNotify",	/*32*/
    "ClientMessage",	/*33*/
    "MappingNotify",	/*34*/
    "VirtualEvent",    	/*35*/
    "ActivateNotify",	/*36*/
    "DeactivateNotify",	/*37*/
    "MouseWheelEvent"	/*38*/
};

static Tk_RestrictAction
InspectQueueRestrictProc(
     ClientData arg,
     XEvent *eventPtr)
{
    XVirtualEvent* ve = (XVirtualEvent*) eventPtr;
    const char *name;
    long serial = ve->serial;
    long time = eventPtr->xkey.time;

    if (eventPtr->type == VirtualEvent) {
	name = ve->name;
    } else {
	name = Tk_EventName[eventPtr->type];
    }
    fprintf(stderr, "    > %s;serial = %lu; time=%lu)\n",
	    name, serial, time);
    return TK_DEFER_EVENT;
}

/*
 * Debugging tool which prints the current Tcl queue.
 */

void DebugPrintQueue(void)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;

    oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg);
    fprintf(stderr, "Current queue:\n");
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {};
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}
# endif

#pragma mark TKApplication(TKNotify)















@implementation TKApplication(TKNotify)
/*
 * Earlier versions of Tk would override nextEventMatchingMask here, adding a
 * call to displayIfNeeded on all windows after calling super. This would cause
 * windows to be redisplayed (if necessary) each time that an event was
 * received.  This was intended to replace Apple's default autoDisplay
 * mechanism, which the earlier versions of Tk would disable.  When autoDisplay
 * is set to the default value of YES, the Apple event loop will call
 * displayIfNeeded on all windows at the beginning of each iteration of their
 * event loop.  Since Tk does not call the Apple event loop, it was thought
 * that the autoDisplay behavior needed to be replicated.
 *
 * However, as of OSX 10.14 (Mojave) the autoDisplay property became
 * deprecated.  Luckily it turns out that, even though we don't ever start the
 * Apple event loop, the Apple window manager still calls displayIfNeeded on
 * all windows on a regular basis, perhaps each time the queue is empty.  So we
 * no longer, and perhaps never did need to set autoDisplay to NO, nor call
 * displayIfNeeded on our windows.  We can just leave all of that to the window
 * manager.
 */


/*
 * Since the contentView is the first responder for a Tk Window, it is
 * responsible for sending events up the responder chain.  We also check the
 * pasteboard here.
 */
- (void) sendEvent: (NSEvent *) theEvent
{

    /*
     * Workaround for an Apple bug.  When an accented character is selected
     * from an NSTextInputClient popup character viewer with the mouse, Apple
     * sends an event of type NSAppKitDefined and subtype 21. If that event is
     * sent up the responder chain it causes Apple to print a warning to the
     * console log and, extremely obnoxiously, also to stderr, which says
     * "Window move completed without beginning."  Apparently they are sending
     * the "move completed" event without having sent the "move began" event of
     * subtype 20, and then announcing their error on our stderr.  Also, of
     * course, no movement is occurring.  The popup is not movable and is just
     * being closed.  The bug has been reported to Apple.  If they ever fix it,
     * this block should be removed.

     */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
    if ([theEvent type] == NSAppKitDefined) {
	static Bool aWindowIsMoving = NO;
	switch([theEvent subtype]) {
	case 20:
	    aWindowIsMoving = YES;
	    break;
	case 21:
	    if (aWindowIsMoving) {
		aWindowIsMoving = NO;
		break;
	    } else {
		// printf("Bug!!!!\n");
		return;
	    }
	default:
	    break;
	}
    }
#endif

    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];

#ifdef TK_MAC_DEBUG_EVENTS
    fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]);
    DebugPrintQueue();
#endif

}

- (void) _runBackgroundLoop
{
    while(Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)){
	TkMacOSXDrawAllViews(NULL);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------









|





<

|
|
>








|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|
|
|
|
|
|
|
<
<
<
<
|
<
<
|
<
<
>
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34















































































35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60




61


62


63
64






65

66











67
68
69





















70
71













72
73
74
75
76
77
78
/*
 * tkMacOSXNotify.c --
 *
 *	This file contains the implementation of a tcl event source
 *	for the AppKit event loop.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2015 Marc Culler. 
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */


#include "tkMacOSXPrivate.h"
#include "tkMacOSXEvent.h"
#include <tclInt.h>
#include <pthread.h>
#import <objc/objc-auto.h>

/* This is not used for anything at the moment. */
typedef struct ThreadSpecificData {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

#define TSD_INIT() ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, \
	    sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);
















































































#pragma mark TKApplication(TKNotify)

@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void)_modalSession:(NSModalSession)session sendEvent:(NSEvent *)event;
@end

@implementation NSWindow(TKNotify)
- (id)tkDisplayIfNeeded {
    if (![self isAutodisplay]) {
	[self displayIfNeeded];
    }
    return nil;
}
@end

@implementation TKApplication(TKNotify)
/* Display all windows each time an event is removed from the queue.*/
- (NSEvent *)nextEventMatchingMask:(NSUInteger)mask
	untilDate:(NSDate *)expiration inMode:(NSString *)mode
	dequeue:(BOOL)deqFlag {
    NSEvent *event = [super nextEventMatchingMask:mask
					untilDate:expiration
					   inMode:mode
					  dequeue:deqFlag];
    /* Retain this event for later use. Must be released.*/




    [event retain];


    [NSApp makeWindowsPerform:@selector(tkDisplayIfNeeded) inOrder:NO];


    return event;
}








 /*











 * Call super then check the pasteboard.
  */
- (void)sendEvent:(NSEvent *)theEvent {





















    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];













}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271

272
273
274
275
276
277
278
static NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;


    }
    if (!runLoopMode) {
	runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
    }
    if (!runLoopMode) {
	runLoopMode = NSDefaultRunLoopMode;
    }
    return runLoopMode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXSetupTkNotifier --
 *
 *	This procedure is called during Tk initialization to create the event
 *	source for TkAqua events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A new event source is created.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXSetupTkNotifier(void)
{
    TSD_INIT();

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;

	/*
	 * Install TkAqua event source in main event loop thread.
	 */

	if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
	    if (![NSThread isMainThread]) {
		/*
		 * Panic if main runloop is not on the main application thread.
		 */

		Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s",
		    "first [load] of TkAqua has to occur in the main thread!");
	    }
	    Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
		    TkMacOSXEventsCheckProc, NULL);

	    TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);

	    TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	}
    }
}

/*







>
>















|
|














<








|








|
>

>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
static NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkMacOSXGetCapture()) {
	runLoopMode = NSEventTrackingRunLoopMode;
    }
    if (!runLoopMode) {
	runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
    }
    if (!runLoopMode) {
	runLoopMode = NSDefaultRunLoopMode;
    }
    return runLoopMode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXSetupTkNotifier --
 *
 *	This procedure is called during Tk initialization to create
 *	the event source for TkAqua events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A new event source is created.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXSetupTkNotifier(void)
{
    TSD_INIT();

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;

	/*
	 * Install TkAqua event source in main event loop thread.
	 */

	if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
	    if (!pthread_main_np()) {
		/*
		 * Panic if main runloop is not on the main application thread.
		 */

		Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s",
		    "first [load] of TkAqua has to occur in the main thread!");
	    }
	    Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
				  TkMacOSXEventsCheckProc,
				  GetMainEventQueue());
	    TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
	    Tcl_SetServiceMode(TCL_SERVICE_ALL);
	    TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	}
    }
}

/*
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNotifyExitHandler(
    ClientData dummy)	/* Not used. */
{
    (void)dummy;
    TSD_INIT();

    Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
	    TkMacOSXEventsCheckProc, NULL);

    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawAllViews --
 *
 *       This static function is meant to be run as an idle task.  It attempts
 *       to redraw all views which have the tkNeedsDisplay property set to YES.
 *       This relies on a feature of [NSApp nextEventMatchingMask: ...] which
 *       is undocumented, namely that it sometimes blocks and calls drawRect
 *       for all views that need display before it returns.  We call it with
 *       deQueue=NO so that it will not change anything on the AppKit event
 *       queue, because we only want the side effect that it runs drawRect. The
 *       only time when any NSViews have the needsDisplay property set to YES
 *       is during execution of this function.
 *
 *       The reason for running this function as an idle task is to try to
 *       arrange that all widgets will be fully configured before they are
 *       drawn.  Any idle tasks that might reconfigure them should be higher on
 *       the idle queue, so they should be run before the display procs are run
 *       by drawRect.
 *
 *       If this function is called directly with non-NULL clientData parameter
 *       then the int which it references will be set to the number of windows
 *       that need display, but the needsDisplay property of those windows will
 *       not be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Parts of windows my get redrawn.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXDrawAllViews(
    ClientData clientData)
{
       int count = 0, *dirtyCount = (int *)clientData;

    for (NSWindow *window in [NSApp windows]) {
	if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
	    TKContentView *view = [window contentView];
	    if ([view tkNeedsDisplay]) {
		count++;
		if (dirtyCount) {
		   continue;
		}
		[view setNeedsDisplayInRect:[view tkDirtyRect]];
	    }
	} else {
	    [window displayIfNeeded];
	}
    }
    if (dirtyCount) {
    	*dirtyCount = count;
    }
    [NSApp nextEventMatchingMask:NSAnyEventMask
		       untilDate:[NSDate distantPast]
			  inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			 dequeue:NO];
    for (NSWindow *window in [NSApp windows]) {
	if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
	    TKContentView *view = [window contentView];

	    /*
	     * If we did not run drawRect, we set needsDisplay back to NO.
	     * Note that if drawRect did run it may have added to Tk's dirty
	     * rect, due to attempts to draw outside of drawRect's dirty rect.
	     */

	    if ([view needsDisplay]) {
		[view setNeedsDisplay: NO];
	    }
	}
    }
    [NSApp setNeedsToDraw:NO];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXEventsSetupProc --
 *
 *	This procedure implements the setup part of the MacOSX event source. It
 *	is invoked by Tcl_DoOneEvent before calling TkMacOSXEventsCheckProc to
 *	process all queued NSEvents.  In our case, all we need to do is to set
 *	the Tcl MaxBlockTime to 0 before starting the loop to process all
 *	queued NSEvents.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *
 *	If NSEvents are queued, or if there is any drawing that needs to be
 *      done, then the maximum block time will be set to 0 to ensure that
 *      Tcl_WaitForEvent returns immediately.
 *
 *----------------------------------------------------------------------
 */

#define TICK 200
static Tcl_TimerToken ticker = NULL;

static void
Heartbeat(
    TCL_UNUSED(ClientData))
{

    if (ticker) {
	ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
    }
}

static const Tcl_Time zeroBlockTime = { 0, 0 };

static void
TkMacOSXEventsSetupProc(
    ClientData dummy,
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
    (void)dummy;

    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {

	[NSApp _resetAutoreleasePool];

 	/*
	 * After calling this setup proc, Tcl_DoOneEvent will call
 	 * Tcl_WaitForEvent.  Then it will call check proc to collect the
 	 * events and translate them into XEvents.
	 *
 	 * If we have any events waiting or if there is any drawing to be done
	 * we want Tcl_WaitForEvent to return immediately.  So we set the block
	 * time to 0 and stop the heatbeat.
  	 */

	NSEvent *currentEvent =
	        [NSApp nextEventMatchingMask:NSAnyEventMask
			untilDate:[NSDate distantPast]
			inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			dequeue:NO];
	if ((currentEvent) || [NSApp needsToDraw] ) {

	    Tcl_SetMaxBlockTime(&zeroBlockTime);
	    Tcl_DeleteTimerHandler(ticker);
	    ticker = NULL;
	} else if (ticker == NULL) {

	    /*
	     * When the user is not generating events we schedule a "heartbeat"
	     * TimerHandler to fire every 200 milliseconds.  The handler does
	     * nothing, but when its timer fires it causes Tcl_WaitForEvent to
	     * return.  This helps avoid hangs when calling vwait during the
	     * non-regression tests.
	     */

	    ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXEventsCheckProc --
 *
 *	This procedure loops through all NSEvents waiting in the TKApplication
 *      event queue, generating X events from them.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	NSevents are used to generate X events, which are added to the Tcl
 *      event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    TCL_UNUSED(ClientData),
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
    int eventsFound = 0;

    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	NSEvent *currentEvent = nil;
	NSEvent *testEvent = nil;
	NSModalSession modalSession;

	/*
	 * It is possible for the SetupProc to be called before this function
	 * returns.  This happens, for example, when we process an event which
	 * opens a modal window.  To prevent premature release of our
	 * application-wide autorelease pool by a nested call to the SetupProc,
	 * we must lock it here.
	 */

	[NSApp _lockAutoreleasePool];
	do {

	    modalSession = TkMacOSXGetModalSession();
	    testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
		    untilDate:[NSDate distantPast]
		    inMode:GetRunLoopMode(modalSession)
		    dequeue:NO];

	    /*
	     * We must not steal any events during LiveResize.
	     */

	    if (testEvent && [[testEvent window] inLiveResize]) {
		break;
	    }

	    currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
		    untilDate:[NSDate distantPast]
		    inMode:GetRunLoopMode(modalSession)
		    dequeue:YES];
	    if (currentEvent) {

		/*
		 * Generate Xevents.
		 */

		NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];

		if (processedEvent) {
		    eventsFound++;

#ifdef TK_MAC_DEBUG_EVENTS
		    TKLog(@"   event: %@", currentEvent);
#endif

		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}

	    } else {
		break;
	    }
	} while (1);

	/*
	 * Now we can unlock the pool.
	 */

	[NSApp _unlockAutoreleasePool];

	/*
	 * Add an idle task to the end of the idle queue which will redisplay
	 * all of our dirty windows.  We want this to happen after all other
	 * idle tasks have run so that all widgets will be configured before
	 * they are displayed.  The drawRect method "borrows" the idle queue
	 * while drawing views. That is, it sends expose events which cause
	 * display procs to be posted as idle tasks and then runs an inner
	 * event loop to processes those idle tasks.  We are trying to arrange
	 * for the idle queue to be empty when it starts that process and empty
	 * when it finishes.
	 */

	int dirtyCount = 0;
	TkMacOSXDrawAllViews(&dirtyCount);
	if (dirtyCount > 0) {
	    Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	    Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
	}
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

<

<

|
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
|
|
|
|






<
|
|




<
<
<

<
<
<
<
<
<
<
<
<
<
<
<

|



<
<
<
|
<
<

|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
>
|
<
<
<
|
<
<
<
<
<
<
<
|
<









|
|





|
|





|



<
<
<
|
<
<





<
<
<
<
<
<
<
<
<

>


|
|
|
<
<
|
<
<



>

|
|
|

<
<
|
<
|

>
|
<
<



<






>




|
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









170
171
172
173
174
175
176
177
178

179

180
181
182
183
184
















































































185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207



208












209
210
211
212
213



214


215
216

217











218
219
220
221
222
223
224



225







226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253



254


255
256
257
258
259









260
261
262
263
264
265
266


267


268
269
270
271
272
273
274
275
276


277

278
279
280
281


282
283
284

285
286
287
288
289
290
291
292
293
294
295
296



297

298




















299
300
301
302
303
304
305
306
307
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNotifyExitHandler(
    ClientData clientData)	/* Not used. */
{

    TSD_INIT();

    Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
			  TkMacOSXEventsCheckProc,
			  GetMainEventQueue());
    tsdPtr->initialized = 0;
}

















































































/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXEventsSetupProc --
 *
 *	This procedure implements the setup part of the MacOSX event
 *	source. It is invoked by Tcl_DoOneEvent before calling
 *      TkMacOSXEventsProc to process all queued NSEvents.  In our
 *      case, all we need to do is to set the Tcl MaxBlockTime to
 *      0 before starting the loop to process all queued NSEvents.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *

 *	If NSEvents are queued, then the maximum block time will be set
 *	to 0 to ensure that control returns immediately to Tcl.
 *
 *----------------------------------------------------------------------
 */




static void












TkMacOSXEventsSetupProc(
    ClientData clientData,
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];



    /* runloopMode will be nil if we are in the Tcl event loop. */


    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	static Tcl_Time zeroBlockTime = { 0, 0 };

	/* Call this with dequeue=NO -- just checking if the queue is empty. */











	NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
				       untilDate:[NSDate distantPast]
				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
				       dequeue:NO];
	if (currentEvent) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);



	    }







	    [currentEvent release];

	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXEventsCheckProc --
 *
 *	This procedure loops through all NSEvents waiting in the
 *      TKApplication event queue, generating X events from them.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	NSevents are used to generate X events, which are added to the
 *      Tcl event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    ClientData clientData,
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];



    /* runloopMode will be nil if we are in the Tcl event loop. */


    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	NSEvent *currentEvent = nil;
	NSEvent *testEvent = nil;
	NSModalSession modalSession;










	do {
	    [NSApp _resetAutoreleasePool];
	    modalSession = TkMacOSXGetModalSession();
	    testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
					      untilDate:[NSDate distantPast]
						 inMode:GetRunLoopMode(modalSession)
						dequeue:NO];


	    /* We must not steal any events during LiveResize. */


	    if (testEvent && [[testEvent window] inLiveResize]) {
		break;
	    }

	    currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
					      untilDate:[NSDate distantPast]
						 inMode:GetRunLoopMode(modalSession)
						dequeue:YES];
	    if (currentEvent) {


		/* Generate Xevents. */

		int oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
		NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];
		Tcl_SetServiceMode(oldServiceMode);
		if (processedEvent) { /* Should always be non-NULL. */


#ifdef TK_MAC_DEBUG_EVENTS
		    TKLog(@"   event: %@", currentEvent);
#endif

		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}
		[currentEvent release];
	    } else {
		break;
	    }
	} while (1);
    }



}























/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXPort.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18






19







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
 * tkMacOSXPort.h --
 *
 *	This file is included by all of the Tk C files.  It contains
 *	information that may be configuration-dependent, such as
 *	#includes for system include files and a few other things.
 *
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 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.
 */

#ifndef _TKMACPORT
#define _TKMACPORT







#include <stdio.h>







#include <pwd.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL



|














>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
|

|

|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * tkMacOSXPort.h --
 *
 *	This file is included by all of the Tk C files. It contains
 *	information that may be configuration-dependent, such as
 *	#includes for system include files and a few other things.
 *
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 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.
 */

#ifndef _TKMACPORT
#define _TKMACPORT

/*
 * Macro to use instead of "void" for arguments that must have
 * type "void *" in ANSI C; maps them to type "char *" in
 * non-ANSI systems. This macro may be used in some of the include
 * files below, which is why it is defined here.
 */

#ifndef VOID
#   ifdef __STDC__
#	define VOID void
#   else
#	define VOID char
#   endif
#endif

#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xfuncproto.h>
#include <X11/Xutil.h>


/*
 * The following macro defines the type of the mask arguments to
 * select:
 */

#ifndef NO_FD_SET







<
<
<






>







58
59
60
61
62
63
64



65
66
67
68
69
70
71
72
73
74
75
76
77
78
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#include <unistd.h>



#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xfuncproto.h>
#include <X11/Xutil.h>
#include "tkIntXlibDecls.h"

/*
 * The following macro defines the type of the mask arguments to
 * select:
 */

#ifndef NO_FD_SET
106
107
108
109
110
111
112













113
114
115
116


117
118
119
120
121











122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164




165
166

167
168

/*
 * The following define causes Tk to use its internal keysym hash table
 */

#define REDO_KEYSYM_LOOKUP














/*
 * The following functions are not used on the Mac, so we stub them out.
 */



#define TkpCmapStressed(tkwin,colormap) (0)
#define TkpFreeColor(tkColPtr)
#define TkSetPixmapColormap(p,c) {}
#define TkpSync(display)












/*
 * This macro stores a representation of the window handle in a string.
 */

#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "0x%lx", (unsigned long) (w))

/*
 * Turn off Tk double-buffering as Aqua windows are already double-buffered.
 */

#define TK_NO_DOUBLE_BUFFERING 1
#define TK_HAS_DYNAMIC_COLORS 1
#define TK_DYNAMIC_COLORMAP 0x0fffffff

/*
 * Inform tkImgPhInstance.c that our tkPutImage can render an image with an
 * alpha channel directly into a window.
 */

#define TKPUTIMAGE_CAN_BLEND

/*

 * Used by xcolor.c
 */

MODULE_SCOPE unsigned long TkMacOSXRGBPixel(unsigned long red, unsigned long green,
					    unsigned long blue);
#define TkpGetPixel(p) (TkMacOSXRGBPixel(p->red >> 8, p->green >> 8, p->blue >> 8))

/*
 * Used by tkWindow.c
 */

MODULE_SCOPE void TkMacOSXHandleMapOrUnmap(Tk_Window tkwin, XEvent *event);

#define TkpHandleMapOrUnmap(tkwin, event)  TkMacOSXHandleMapOrUnmap(tkwin, event)

/*
 * Used by tkAppInit
 */


#define USE_CUSTOM_EXIT_PROC




EXTERN int TkpWantsExitProc(void);
EXTERN TCL_NORETURN void TkpExitProc(void *);


#endif /* _TKMACPORT */







>
>
>
>
>
>
>
>
>
>
>
>
>




>
>





>
>
>
>
>
>
>
>
>
>
>












<
<


<
<
<
|
<
|
<
>
|


<
<
|
|
<
<
<
|
<
|
|
|
<
<
<
|
>
|
>
>
>
>
|
<
>


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170


171
172



173

174

175
176
177
178


179
180



181

182
183
184



185
186
187
188
189
190
191
192

193
194
195

/*
 * The following define causes Tk to use its internal keysym hash table
 */

#define REDO_KEYSYM_LOOKUP

/*
 * Defines for X functions that are used by Tk but are treated as
 * no-op functions on the Macintosh.
 */

#define XFlush(display)
#define XFree(data) {if ((data) != NULL) ckfree((char *) (data));}
#define XGrabServer(display)
#define XNoOp(display) {display->request++;}
#define XUngrabServer(display)
#define XSynchronize(display, bool) {display->request++;}
#define XVisualIDFromVisual(visual) (visual->visualid)

/*
 * The following functions are not used on the Mac, so we stub them out.
 */

#define TkFreeWindowId(dispPtr,w)
#define TkInitXId(dispPtr)
#define TkpCmapStressed(tkwin,colormap) (0)
#define TkpFreeColor(tkColPtr)
#define TkSetPixmapColormap(p,c) {}
#define TkpSync(display)

/*
 * The following macro returns the pixel value that corresponds to the
 * RGB values in the given XColor structure.
 */

#define PIXEL_MAGIC ((unsigned char) 0x69)
#define TkpGetPixel(p) ((((((PIXEL_MAGIC << 8) \
	| (((p)->red >> 8) & 0xff)) << 8) \
	| (((p)->green >> 8) & 0xff)) << 8) \
	| (((p)->blue >> 8) & 0xff))

/*
 * This macro stores a representation of the window handle in a string.
 */

#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "0x%lx", (unsigned long) (w))

/*
 * Turn off Tk double-buffering as Aqua windows are already double-buffered.
 */

#define TK_NO_DOUBLE_BUFFERING 1



/*



 * Magic pixel code values for system colors.

 *

 * NOTE: values must be kept in sync with indices into the
 *	 systemColorMap array in tkMacOSXColor.c !
 */



#define TRANSPARENT_PIXEL		30
#define HIGHLIGHT_PIXEL			31



#define HIGHLIGHT_SECONDARY_PIXEL	32

#define HIGHLIGHT_TEXT_PIXEL		33
#define HIGHLIGHT_ALTERNATE_PIXEL	34
#define CONTROL_TEXT_PIXEL		35



#define CONTROL_BODY_PIXEL		37
#define CONTROL_FRAME_PIXEL		39
#define WINDOW_BODY_PIXEL		41
#define MENU_ACTIVE_PIXEL		43
#define MENU_ACTIVE_TEXT_PIXEL		45
#define MENU_BACKGROUND_PIXEL		47
#define MENU_DISABLED_PIXEL		49
#define MENU_TEXT_PIXEL			51

#define APPEARANCE_PIXEL		52

#endif /* _TKMACPORT */

Changes to macosx/tkMacOSXPrivate.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * tkMacOSXPrivate.h --
 *
 *	Macros and declarations that are purely internal & private to TkAqua.
 *
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2008-2009 Apple Inc.
 * Copyright (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id$
 */

#ifndef _TKMACPRIV
#define _TKMACPRIV

#if !__OBJC__
#error Objective-C compiler required
#endif

#ifndef __clang__
#define instancetype id
#endif

#define TextStyle MacTextStyle
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle






<
|



<
<

|







<
<
<
<







1
2
3
4
5
6

7
8
9
10


11
12
13
14
15
16
17
18
19




20
21
22
23
24
25
26
/*
 * tkMacOSXPrivate.h --
 *
 *	Macros and declarations that are purely internal & private to TkAqua.
 *
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>

 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.


 */
 
#ifndef _TKMACPRIV
#define _TKMACPRIV

#if !__OBJC__
#error Objective-C compiler required
#endif





#define TextStyle MacTextStyle
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle
60
61
62
63
64
65
66





















67
68
69
70
71
72
73
	if ((chk) && (cond)) { __VA_ARGS__
#define tk_else_mac_os_x_chk(...) \
	} else { __VA_ARGS__
#define tk_if_mac_os_x_no(chk, cond, ...) \
	if (0) {
#define tk_else_mac_os_x_no(...) \
	} else { __VA_ARGS__






















/*
 * Macros for DEBUG_ASSERT_MESSAGE et al from Debugging.h.
 */

#undef kComponentSignatureString
#undef COMPONENT_SIGNATURE







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	if ((chk) && (cond)) { __VA_ARGS__
#define tk_else_mac_os_x_chk(...) \
	} else { __VA_ARGS__
#define tk_if_mac_os_x_no(chk, cond, ...) \
	if (0) {
#define tk_else_mac_os_x_no(...) \
	} else { __VA_ARGS__
/* Private mapping macros defined according to Mac OS X version requirements */
/* 10.5 Leopard */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
#define tk_if_mac_os_x_min_10_5		tk_if_mac_os_x_yes
#define tk_else_mac_os_x_min_10_5	tk_else_mac_os_x_yes
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_yes
#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_yes
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
#else /* MAC_OS_X_VERSION_MIN_REQUIRED */
#define tk_if_mac_os_x_min_10_5		tk_if_mac_os_x_chk
#define tk_else_mac_os_x_min_10_5	tk_else_mac_os_x_chk
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_chk
#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_chk
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
#endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_no
#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_no
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */

/*
 * Macros for DEBUG_ASSERT_MESSAGE et al from Debugging.h.
 */

#undef kComponentSignatureString
#undef COMPONENT_SIGNATURE
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213


214
215
216
217
218
219




220
221
222

223
224
225
226
227
228




229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264



265
266
267
268

269
270
271
272
273
274


275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413





414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    } while (0)

/*
 * Macro to do very common check for noErr return from given API and output
 * debug message in case of failure.
 */
#define ChkErr(f, ...) ({ \
	OSStatus err_ = f(__VA_ARGS__); \
	if (err_ != noErr) { \
	    TkMacOSXDbgOSErr(f, err_); \
	} \
	err_;})

#else /* TK_MAC_DEBUG */
#define TKLog(f, ...)
#define TkMacOSXDbgMsg(m, ...)
#define TkMacOSXDbgOSErr(f, err)
#define ChkErr(f, ...) ({f(__VA_ARGS__);})
#endif /* TK_MAC_DEBUG */

/*
 * Macro abstracting use of TkMacOSXGetNamedSymbol to init named symbols.
 */

#define UNINITIALISED_SYMBOL	((void*)(-1L))
#define TkMacOSXInitNamedSymbol(module, ret, symbol, ...) \
    static ret (* symbol)(__VA_ARGS__) = UNINITIALISED_SYMBOL; \
    if (symbol == UNINITIALISED_SYMBOL) { \
	symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), \
		STRINGIFY(symbol)); \
    }

/*
 *  The structure of a 32-bit XEvent keycode on macOS. It may be viewed as
 *  an unsigned int or as having either two or three bitfields.
 */

typedef struct keycode_v_t {
    unsigned keychar: 22;    /* UCS-32 character */
    unsigned o_s: 2;         /* State of Option and Shift keys. */
    unsigned virtual: 8;     /* 8-bit virtual keycode - identifies a key. */
} keycode_v;

typedef struct keycode_x_t {
    unsigned keychar: 22;     /* UCS-32 character */
    unsigned xvirtual: 10;    /* Combines o_s and virtual. This 10-bit integer
			       * is used as a key for looking up the character
			       * produced when pressing a key with a particular
			       * Shift and Option modifier state. */
} keycode_x;

typedef union MacKeycode_t {
  unsigned int uint;
  keycode_v v;
  keycode_x x;
} MacKeycode;

/*
 * Macros used in tkMacOSXKeyboard.c and tkMacOSXKeyEvent.c.
 * Note that 0x7f is del and 0xF8FF is the Apple Logo character.
 */

#define ON_KEYPAD(virtual) ((virtual >= 0x41) && (virtual <= 0x5C))
#define IS_PRINTABLE(keychar) ((keychar >= 0x20) && (keychar != 0x7f) && \
                               ((keychar < 0xF700) || keychar >= 0xF8FF))

/*
 * An "index" is 2-bit bitfield showing the state of the Option and Shift
 * keys.  It is used as an index when building the keymaps and it
 * is the value of the o_s bitfield of a keycode_v.
 */

#define INDEX_SHIFT 1
#define INDEX_OPTION 2
#define INDEX2STATE(index) ((index & INDEX_SHIFT ? ShiftMask : 0) |	\
			    (index & INDEX_OPTION ? Mod2Mask : 0))
#define INDEX2CARBON(index) ((index & INDEX_SHIFT ? shiftKey : 0) |	\
			     (index & INDEX_OPTION ? optionKey : 0))
#define STATE2INDEX(state) ((state & ShiftMask ? INDEX_SHIFT : 0) |	\
			    (state & Mod2Mask ? INDEX_OPTION : 0))

/*
 * Special values for the virtual bitfield.  Actual virtual keycodes are < 128.
 */

#define NO_VIRTUAL 0xFF /* Not generated by a key or the NSText"InputClient. */
#define REPLACEMENT_VIRTUAL 0x80 /* A BMP char sent by the NSTextInputClient. */
#define NON_BMP_VIRTUAL 0x81 /* A non-BMP char sent by the NSTextInputClient. */

/*
 * A special character is used in the keycode for simulated modifier KeyPress
 * or KeyRelease XEvents.  It is near the end of the private-use range but
 * different from the UniChar 0xF8FF which Apple uses for their logo character.
 * A different special character is used for keys, like the Menu key, which do
 * not appear on Macintosh keyboards.
 */

#define MOD_KEYCHAR 0xF8FE
#define UNKNOWN_KEYCHAR 0xF8FD

/*
 * Structure encapsulating current drawing environment.
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;

} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */



MODULE_SCOPE long tkMacOSXMacOSXVersion;

/*
 * Prototypes for TkMacOSXRegion.c.
 */





MODULE_SCOPE HIShapeRef	TkMacOSXGetNativeRegion(Region r);
MODULE_SCOPE void	TkMacOSXSetWithNativeRegion(Region r,
			    HIShapeRef rgn);

MODULE_SCOPE HIShapeRef	TkMacOSXHIShapeCreateEmpty(void);
MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect(
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithShape(
			    HIMutableShapeRef inDestShape,
			    HIShapeRef inSrcShape);




MODULE_SCOPE OSStatus	TkMacOSHIShapeDifferenceWithRect(
			    HIMutableShapeRef inShape, const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnion(HIShapeRef inShape1,
			    HIShapeRef inShape2, HIMutableShapeRef outResult);

/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);
MODULE_SCOPE CGFloat	TkMacOSXZeroScreenHeight();
MODULE_SCOPE CGFloat	TkMacOSXZeroScreenTop();
MODULE_SCOPE int	TkMacOSXUseAntialiasedText(Tcl_Interp *interp,
			    int enable);
MODULE_SCOPE int	TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable,
			    int antiAlias);



MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
			    CGContextRef context);
#define TkMacOSXGetTkWindow(window) (TkWindow *)Tk_MacOSXGetTkWindow(window)
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)Tk_MacOSXGetNSWindowForDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
#define TkMacOSXGetCGContextForDrawable(drawable) ((CGContextRef)Tk_MacOSXGetCGContextForDrawable(drawable))



MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
			    HIShapeRef rgn);

MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromTkImage(Display *display,
			    Tk_Image image, int width, int height);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromBitmap(Display *display,
			    Pixmap bitmap, GC gc, int width, int height);
MODULE_SCOPE CGColorRef	TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSColor*	TkMacOSXGetNSColor(GC gc, unsigned long pixel);


MODULE_SCOPE NSFont*	TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
MODULE_SCOPE void	TkMacOSXSelDeadWindow(TkWindow *winPtr);
MODULE_SCOPE void	TkMacOSXApplyWindowAttributes(TkWindow *winPtr,
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE void       TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
			    int inset, int thickness);
MODULE_SCOPE int 	TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int	TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE unsigned   TkMacOSXAddVirtual(unsigned int keycode);
MODULE_SCOPE void       TkMacOSXWinNSBounds(TkWindow *winPtr, NSView *view,
					    NSRect *bounds);
MODULE_SCOPE Bool       TkMacOSXInDarkMode(Tk_Window tkwin);
MODULE_SCOPE void	TkMacOSXDrawAllViews(ClientData clientData);
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

VISIBILITY_HIDDEN
@interface TKMenu : NSMenu {
@private
    void *_tkMenu;
    NSUInteger _tkOffset, _tkItemCount, _tkSpecial;
}
- (void)setSpecial:(NSUInteger)special;
- (BOOL)isSpecial:(NSUInteger)special;
@end

@interface TKMenu(TKMenuDelegate) <NSMenuDelegate>
@end

VISIBILITY_HIDDEN
@interface TKApplication : NSApplication {
@private
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSMenuItem *_demoMenuItem;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems, *_defaultFileMenuItems;

    NSAutoreleasePool *_mainPool;
    NSThread *_backgoundLoop;

#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macOSVersion;  /* 10000 * major + 100*minor */
    Bool _isDrawing;
    Bool _needsToDraw;
#endif

}
@property int poolLock;
@property int macOSVersion;
@property Bool isDrawing;
@property Bool needsToDraw;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
@end
@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end
@interface TKApplication(TKWindowEvent) <NSApplicationDelegate>
- (void) _setupWindowNotifications;
@end
@interface TKApplication(TKDialog) <NSOpenSavePanelDelegate>
@end
@interface TKApplication(TKMenu)
- (void)tkSetMainMenu:(TKMenu *)menu;
@end
@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end
@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
- (void) _runBackgroundLoop;
@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKKeyEvent)
- (NSEvent *)tkProcessKeyEvent:(NSEvent *)theEvent;
@end



@interface TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
@interface TKApplication(TKHLEvents)
- (void) terminate: (id) sender;
- (void) superTerminate: (id) sender;
- (void) preferences: (id) sender;
- (void) handleQuitApplicationEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenApplicationEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
		       withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
- (void) handleShowPreferencesEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenDocumentsEvent:     (NSAppleEventDescriptor *)event
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handlePrintDocumentsEvent:    (NSAppleEventDescriptor *)event
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handleDoScriptEvent:          (NSAppleEventDescriptor *)event
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void)handleURLEvent:                (NSAppleEventDescriptor*)event
	           withReplyEvent:     (NSAppleEventDescriptor*)replyEvent;
@end

VISIBILITY_HIDDEN
/*
 * Subclass TKContentView from NSTextInputClient to enable composition and
 * input from the Character Palette.
 */

@interface TKContentView : NSView <NSTextInputClient>
{
@private





    NSString *privateWorkingText;
    Bool _tkNeedsDisplay;
    NSRect _tkDirtyRect;
}
@property Bool tkNeedsDisplay;
@property NSRect tkDirtyRect;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
- (void) cancelComposingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) addTkDirtyRect: (NSRect) rect;
- (void) clearTkDirtyRect;
- (void) generateExposeEvents: (NSRect) rect;

- (void) tkToolbarButton: (id) sender;
@end

@interface NSWindow(TKWm)
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Bool _mouseInResizeArea;
    Window _tkWindow;
#endif
}
@property Bool mouseInResizeArea;
@property Window tkWindow;
@end

@interface TKWindow(TKWm)
- (void)    tkLayoutChanged;
@end

@interface TKDrawerWindow : NSWindow
{
    id _i1, _i2;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end

@interface TKPanel : NSPanel
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;







|
|
|

|












<

|
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









>






>
>






>
>
>
>
|
|

>






>
>
>
>














<
<




>
>
>


|
|
|
<

|




|
|
|
|
>
>
>




>
|

|



>
>












<
<
<
<
<
<
<
<
<
<
<

















<
<
<






<

|
>

<
<

<
|
<
<
<

|
<
<
<
|
<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










>
>
>






<

|

|

|



|

|

|

<
<



<
<
<
<
<
|
<

>
>
>
>
>

<
<

<
<




<



|
|
|
>

<
|
|
|
|




<
<
<
<
<
<
<
<
<


|
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143




































































144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199


200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249











250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266



267
268
269
270
271
272

273
274
275
276


277

278



279
280



281


282
283
284
285





















286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319


320
321
322





323

324
325
326
327
328
329
330


331


332
333
334
335

336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351









352
353
354


355










356








357
358
359
360
361
362
363
    } while (0)

/*
 * Macro to do very common check for noErr return from given API and output
 * debug message in case of failure.
 */
#define ChkErr(f, ...) ({ \
	OSStatus err = f(__VA_ARGS__); \
	if (err != noErr) { \
	    TkMacOSXDbgOSErr(f, err); \
	} \
	err;})

#else /* TK_MAC_DEBUG */
#define TKLog(f, ...)
#define TkMacOSXDbgMsg(m, ...)
#define TkMacOSXDbgOSErr(f, err)
#define ChkErr(f, ...) ({f(__VA_ARGS__);})
#endif /* TK_MAC_DEBUG */

/*
 * Macro abstracting use of TkMacOSXGetNamedSymbol to init named symbols.
 */


#define TkMacOSXInitNamedSymbol(module, ret, symbol, ...) \
    static ret (* symbol)(__VA_ARGS__) = (void*)(-1L); \
    if (symbol == (void*)(-1L)) { \
	symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), \
		STRINGIFY(symbol)); \
    }





































































/*
 * Structure encapsulating current drawing environment.
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;
    int focusLocked;
} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
MODULE_SCOPE CGFloat tkMacOSXZeroScreenTop;
MODULE_SCOPE long tkMacOSXMacOSXVersion;

/*
 * Prototypes for TkMacOSXRegion.c.
 */

#if 0
MODULE_SCOPE void	TkMacOSXEmtpyRegion(TkRegion r);
MODULE_SCOPE int	TkMacOSXIsEmptyRegion(TkRegion r);
#endif
MODULE_SCOPE HIShapeRef	TkMacOSXGetNativeRegion(TkRegion r);
MODULE_SCOPE void	TkMacOSXSetWithNativeRegion(TkRegion r,
			    HIShapeRef rgn);
MODULE_SCOPE void	TkMacOSXOffsetRegion(TkRegion r, short dx, short dy);
MODULE_SCOPE HIShapeRef	TkMacOSXHIShapeCreateEmpty(void);
MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect(
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithShape(
			    HIMutableShapeRef inDestShape,
			    HIShapeRef inSrcShape);
#if 0
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
#endif
MODULE_SCOPE OSStatus	TkMacOSHIShapeDifferenceWithRect(
			    HIMutableShapeRef inShape, const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnion(HIShapeRef inShape1,
			    HIShapeRef inShape2, HIMutableShapeRef outResult);

/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);


MODULE_SCOPE int	TkMacOSXUseAntialiasedText(Tcl_Interp *interp,
			    int enable);
MODULE_SCOPE int	TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable,
			    int antiAlias);
MODULE_SCOPE int	TkMacOSXGenerateFocusEvent(TkWindow *winPtr,
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* BitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);

MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
			    CGContextRef context);
MODULE_SCOPE int	TkMacOSXMakeFullscreen(TkWindow *winPtr,
			    NSWindow *window, int fullscreen,
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkMacOSXEnterExitFullscreen(TkWindow *winPtr,
			    int active);
MODULE_SCOPE NSWindow*	TkMacOSXDrawableWindow(Drawable drawable);
MODULE_SCOPE NSView*	TkMacOSXDrawableView(MacDrawable *macWin);
MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
			    HIShapeRef rgn);
MODULE_SCOPE CGImageRef	TkMacOSXCreateCGImageWithDrawable(Drawable drawable);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithTkImage(Display *display,
			    Tk_Image image, int width, int height);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithBitmap(Display *display,
			    Pixmap bitmap, GC gc, int width, int height);
MODULE_SCOPE CGColorRef	TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSColor*	TkMacOSXGetNSColor(GC gc, unsigned long pixel);
MODULE_SCOPE Tcl_Obj *	TkMacOSXGetStringObjFromCFString(CFStringRef str);
MODULE_SCOPE TkWindow*	TkMacOSXGetTkWindow(NSWindow *w);
MODULE_SCOPE NSFont*	TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
MODULE_SCOPE void	TkMacOSXSelDeadWindow(TkWindow *winPtr);
MODULE_SCOPE void	TkMacOSXApplyWindowAttributes(TkWindow *winPtr,
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);












#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

VISIBILITY_HIDDEN
@interface TKMenu : NSMenu {
@private
    void *_tkMenu;
    NSUInteger _tkOffset, _tkItemCount, _tkSpecial;
}
- (void)setSpecial:(NSUInteger)special;
- (BOOL)isSpecial:(NSUInteger)special;
@end




VISIBILITY_HIDDEN
@interface TKApplication : NSApplication {
@private
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;

    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
    NSAutoreleasePool *_mainPool;


#ifdef __i386__

    BOOL _poolProtected;



#endif
}



@property BOOL poolProtected;


@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;





















@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKKeyEvent)
- (NSEvent *)tkProcessKeyEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKMenu)
- (void)tkSetMainMenu:(TKMenu *)menu;
@end
@interface TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
@interface TKApplication(TKHLEvents)
- (void) terminate: (id) sender;

- (void) preferences: (id) sender;
- (void) handleQuitApplicationEvent:   (NSAppleEventDescriptor *)event 
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenApplicationEvent:   (NSAppleEventDescriptor *)event 
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event 
		       withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
- (void) handleShowPreferencesEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenDocumentsEvent:     (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handlePrintDocumentsEvent:    (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handleDoScriptEvent:          (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;


@end

VISIBILITY_HIDDEN





@interface TKContentView : NSView <NSTextInput> {

@private
  /*Remove private API calls.*/
#if 0
    id _savedSubviews;
    BOOL _subviewsSetAside;
#endif
    NSString *privateWorkingText;


}


@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;

@end

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
- (void) viewDidEndLiveResize;
- (void) tkToolbarButton: (id) sender;

- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
- (BOOL) acceptsFirstResponder;
- (void) keyDown: (NSEvent *) theEvent;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow









@end

@interface NSWindow(TKWm)


- (NSPoint) convertPointToScreen:(NSPoint)point;










- (NSPoint) convertPointFromScreen:(NSPoint)point;








@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
	keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	target:(id)target keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end

@interface NSColorPanel(TKDialog)
- (void) _setUseModalAppearance: (BOOL) flag;
@end

@interface NSFont(TKFont)
- (NSFont *) bestMatchingFontForCharacters: (const UTF16Char *) characters
	length: (NSUInteger) length attributes: (NSDictionary *) attributes
	actualCoveredLength: (NSUInteger *) coveredLength;
@end

/*
 * This method of NSApplication is not declared in NSApplication.h so we
 * declare it here to be a method of the TKMenu category.
 */

@interface NSApplication(TKMenu)
- (void) setAppleMenu: (NSMenu *) menu;
@end

/*
 * These methods are exposed because they are needed to prevent zombie windows
 * on systems with a TouchBar.  The TouchBar Key-Value observer holds a
 * reference to the key window, which prevents deallocation of the key window
 * when it is closed.
 */

@interface NSApplication(TkWm)
- (id) _setKeyWindow: (NSWindow *) window;
- (id) _setMainWindow: (NSWindow *) window;
@end


/*
 *---------------------------------------------------------------------------
 *
 * TKNSString --
 *
 * When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
 * deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
 * encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk
 * uses the CESU-8 encoding internally.  This encoding is similar to UTF-8
 * except that it allows encoding surrogate characters as 3-byte sequences
 * using the same algorithm which UTF-8 uses for non-surrogates.  This means
 * that a non-BMP character is encoded as a string of length 6.  Apple's
 * NSString class does not provide a constructor which accepts a CESU-8 encoded
 * byte sequence as initial data.  So we add a new class which does provide
 * such a constructor.  It also has a DString property which is a DString whose
 * string pointer is a byte sequence encoding the NSString with the current Tk
 * encoding, namely UTF-8 if TCL_UTF_MAX >= 4 or CESU-8 if TCL_UTF_MAX = 3.
 *
 *---------------------------------------------------------------------------
 */

@interface TKNSString:NSString {
@private
    Tcl_DString _ds;
    NSString *_string;
}
@property const char *UTF8String;
@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
			     length:(NSUInteger)len;
@end

#endif /* _TKMACPRIV */

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
380
381
382
383
384
385
386
































































387









	keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	target:(id)target keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end

































































#endif /* _TKMACPRIV */









Changes to macosx/tkMacOSXRegion.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"
static void RetainRegion(TkRegion r);
static void ReleaseRegion(TkRegion r);

#ifdef DEBUG
static int totalRegions = 0;
static int totalRegionRetainCount = 0;
#define DebugLog(msg, ...) fprintf(stderr, (msg), ##__VA_ARGS__)
#else
#define DebugLog(msg, ...)
#endif


/*
 *----------------------------------------------------------------------
 *
 * XCreateRegion --
 *
 *	Implements the equivelent of the X window function XCreateRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns an allocated region handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
XCreateRegion(void)
{
    Region region = (Region) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d\n", ++totalRegions);
    RetainRegion(region);
    return region;
}

/*
 *----------------------------------------------------------------------
 *
 * XDestroyRegion --
 *
 *	Implements the equivelent of the X window function XDestroyRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

int
XDestroyRegion(
    Region r)
{
    if (r) {
	DebugLog("Destroyed region: total regions = %d\n", --totalRegions);
	ReleaseRegion(r);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XIntersectRegion --
 *
 *	Implements the equivalent of the X window function XIntersectRegion.
 *	See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XIntersectRegion(
    Region sra,
    Region srb,
    Region dr_return)
{
    ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XSubtractRegion --
 *
 *	Implements the equivalent of the X window function XSubtractRegion.
 *	See X window documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XSubtractRegion(
    Region sra,
    Region srb,
    Region dr_return)
{
    ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XUnionRectWithRegion --
 *
 *	Implements the equivelent of the X window function
 *	XUnionRectWithRegion. See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XUnionRectWithRegion(
    XRectangle* rectangle,
    Region src_region,
    Region dest_region_return)
{
    const CGRect r = CGRectMake(rectangle->x, rectangle->y,
	    rectangle->width, rectangle->height);

    if (src_region == dest_region_return) {
	ChkErr(TkMacOSHIShapeUnionWithRect,
		(HIMutableShapeRef) dest_region_return, &r);
    } else {
	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);

	ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
		(HIMutableShapeRef) dest_region_return);
	CFRelease(rectRgn);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsEmptyRegion --
 *
 *	Return native region for given tk region.
 *
 * Results:
 *	1 if empty, 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXIsEmptyRegion(
    Region r)
{
    return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
}

/*
 *----------------------------------------------------------------------
 *
 * XRectInRegion --
 *
 *	Implements the equivelent of the X window function XRectInRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns RectanglePart or RectangleOut. Note that this is not a complete
 *	implementation since it doesn't test for RectangleIn.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XRectInRegion(
    Region region,
    int x,
    int y,
    unsigned int width,
    unsigned int height)
{
    if (TkMacOSXIsEmptyRegion(region)) {
	return RectangleOut;

    } else {
	const CGRect r = CGRectMake(x, y, width, height);

	return HIShapeIntersectsRect((HIShapeRef) region, &r) ?
		RectanglePart : RectangleOut;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * XClipBox --
 *
 *	Implements the equivelent of the X window function XClipBox. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XClipBox(
    Region r,
    XRectangle *rect_return)
{
    CGRect rect;

    HIShapeGetBounds((HIShapeRef) r, &rect);
    rect_return->x = rect.origin.x;
    rect_return->y = rect.origin.y;
    rect_return->width = rect.size.width;
    rect_return->height = rect.size.height;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *







<
<
<
<
<
<
<
<
<
<





|













|
|

|
<
<
<





|













|
|
|


<
|

<





|













|
|
|
|
|



<





|













|
|
|
|
|



<





|













|
|

|
|














<


















|

|







|





|
|








|
|





|
|
>
|

<

|






|













|
|
|
|








<







8
9
10
11
12
13
14










15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
 * Copyright (c) 2006-2009 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.
 */

#include "tkMacOSXPrivate.h"












/*
 *----------------------------------------------------------------------
 *
 * TkCreateRegion --
 *
 *	Implements the equivelent of the X window function XCreateRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns an allocated region handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkRegion
TkCreateRegion(void)
{
    return (TkRegion) HIShapeCreateMutable();



}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyRegion --
 *
 *	Implements the equivelent of the X window function XDestroyRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

void
TkDestroyRegion(
    TkRegion r)
{
    if (r) {

	CFRelease(r);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkIntersectRegion --
 *
 *	Implements the equivalent of the X window function XIntersectRegion.
 *	See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkIntersectRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);

}

/*
 *----------------------------------------------------------------------
 *
 * TkSubtractRegion --
 *
 *	Implements the equivalent of the X window function XSubtractRegion.
 *	See X window documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSubtractRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);

}

/*
 *----------------------------------------------------------------------
 *
 * TkUnionRectWithRegion --
 *
 *	Implements the equivelent of the X window function
 *	XUnionRectWithRegion. See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkUnionRectWithRegion(
    XRectangle* rectangle,
    TkRegion src_region,
    TkRegion dest_region_return)
{
    const CGRect r = CGRectMake(rectangle->x, rectangle->y,
	    rectangle->width, rectangle->height);

    if (src_region == dest_region_return) {
	ChkErr(TkMacOSHIShapeUnionWithRect,
		(HIMutableShapeRef) dest_region_return, &r);
    } else {
	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);

	ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
		(HIMutableShapeRef) dest_region_return);
	CFRelease(rectRgn);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsEmptyRegion --
 *
 *	Return native region for given tk region.
 *
 * Results:
 *	1 if empty, 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXIsEmptyRegion(
    TkRegion r)
{
    return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkRectInRegion --
 *
 *	Implements the equivelent of the X window function XRectInRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns RectanglePart or RectangleOut. Note that this is not a
 *	complete implementation since it doesn't test for RectangleIn.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkRectInRegion(
    TkRegion region,
    int x,
    int y,
    unsigned int width,
    unsigned int height)
{
    if ( TkMacOSXIsEmptyRegion(region) ) {
	    return RectangleOut;
	}
    else {    
	const CGRect r = CGRectMake(x, y, width, height);

	return HIShapeIntersectsRect((HIShapeRef) region, &r) ?
	    RectanglePart : RectangleOut;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipBox --
 *
 *	Implements the equivelent of the X window function XClipBox. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkClipBox(
    TkRegion r,
    XRectangle* rect_return)
{
    CGRect rect;

    HIShapeGetBounds((HIShapeRef) r, &rect);
    rect_return->x = rect.origin.x;
    rect_return->y = rect.origin.y;
    rect_return->width = rect.size.width;
    rect_return->height = rect.size.height;

}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
 *	The region is updated, with extra pixels added to it.
 *
 *----------------------------------------------------------------------
 */

void
TkpBuildRegionFromAlphaData(
    Region region,			/* Region to update. */
    unsigned int x,			/* Where in region to update. */
    unsigned int y,			/* Where in region to update. */
    unsigned int width,			/* Size of rectangle to update. */
    unsigned int height,		/* Size of rectangle to update. */
    unsigned char *dataPtr,		/* Data to read from. */
    unsigned int pixelStride,		/* num bytes from one piece of alpha
					 * data to the next in the line. */







|







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
 *	The region is updated, with extra pixels added to it.
 *
 *----------------------------------------------------------------------
 */

void
TkpBuildRegionFromAlphaData(
    TkRegion region,			/* Region to update. */
    unsigned int x,			/* Where in region to update. */
    unsigned int y,			/* Where in region to update. */
    unsigned int width,			/* Size of rectangle to update. */
    unsigned int height,		/* Size of rectangle to update. */
    unsigned char *dataPtr,		/* Data to read from. */
    unsigned int pixelStride,		/* num bytes from one piece of alpha
					 * data to the next in the line. */
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
		lineDataPtr += pixelStride;
	    }
	    if (end > x1) {
		rect.x = x + x1;
		rect.y = y + y1;
		rect.width = end - x1;
		rect.height = 1;
		XUnionRectWithRegion(&rect, region, region);
	    }
	}
	dataPtr += lineStride;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RetainRegion --
 *
 *	Increases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
RetainRegion(
    Region r)
{
    CFRetain(r);
    DebugLog("Retained region: total count is %d\n", ++totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
 *
 * ReleaseRegion --
 *
 *	Decreases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May free memory.
 *
 *----------------------------------------------------------------------
 */

static void
ReleaseRegion(
    Region r)
{
    CFRelease(r);
    DebugLog("Released region: total count is %d\n", --totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetEmptyRegion --
 *
 *	Set region to emtpy.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetEmptyRegion(
    Region r)
{
    ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
}

/*
 *----------------------------------------------------------------------
 *







|









|












|
|
|


<





|












|
|
|


<




















|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
		lineDataPtr += pixelStride;
	    }
	    if (end > x1) {
		rect.x = x + x1;
		rect.y = y + y1;
		rect.width = end - x1;
		rect.height = 1;
		TkUnionRectWithRegion(&rect, region, region);
	    }
	}
	dataPtr += lineStride;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRetainRegion --
 *
 *	Increases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpRetainRegion(
    TkRegion r)
{
    CFRetain(r);

}

/*
 *----------------------------------------------------------------------
 *
 * TkpReleaseRegion --
 *
 *	Decreases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May free memory.
 *
 *----------------------------------------------------------------------
 */

void
TkpReleaseRegion(
    TkRegion r)
{
    CFRelease(r);

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetEmptyRegion --
 *
 *	Set region to emtpy.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetEmptyRegion(
    TkRegion r)
{
    ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
}

/*
 *----------------------------------------------------------------------
 *
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
 *	None.
 *
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetNativeRegion(
    Region r)
{
    return (HIShapeRef) CFRetain(r);
}

/*
 *----------------------------------------------------------------------
 *







|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
 *	None.
 *
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetNativeRegion(
    TkRegion r)
{
    return (HIShapeRef) CFRetain(r);
}

/*
 *----------------------------------------------------------------------
 *
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetWithNativeRegion(
    Region r,
    HIShapeRef rgn)
{
    ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
}

/*
 *----------------------------------------------------------------------
 *
 * XOffsetRegion --
 *
 *	Offsets region by given distances.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XOffsetRegion(
    Region r,
    int dx,
    int dy)
{
    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
 * TkMacOSXHIShapeSetWithShape,
 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
 * TkMacOSHIShapeUnion --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */







|








|












|
|
|
|
|


<






|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetWithNativeRegion(
    TkRegion r,
    HIShapeRef rgn)
{
    ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXOffsetRegion --
 *
 *	Offsets region by given distances.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXOffsetRegion(
    TkRegion r,
    short dx,
    short dy)
{
    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
 * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
 * TkMacOSHIShapeUnion --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */
514
515
516
517
518
519
520
















521
522
523
524
525
526
527
{
    OSStatus result;

    result = HIShapeSetWithShape(inDestShape, inSrcShape);
    return result;
}

















OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
{
    OSStatus result;

    result = HIShapeSetWithShape(inDestShape, inSrcShape);
    return result;
}

#if 0
OSStatus
TkMacOSXHIShapeSetWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

    result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
    CFRelease(rgn);

    return result;
}
#endif

OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

Changes to macosx/tkMacOSXScale.c.

47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
 */
static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		MacScaleEventProc(ClientData clientData,
			    XEvent *eventPtr);
static pascal void	ScaleActionProc(ControlRef theControl,
			    ControlPartCode partCode);


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScale --
 *
 *	Allocate a new TkScale structure.







|
<
|
|
>







47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
 */
static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */

/*
 * Forward declarations for procedures defined later in this file:
 */

static void MacScaleEventProc(ClientData clientData, XEvent *eventPtr);

static pascal void ScaleActionProc(ControlRef theControl,
	ControlPartCode partCode);


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScale --
 *
 *	Allocate a new TkScale structure.
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *----------------------------------------------------------------------
 */

TkScale *
TkpCreateScale(
    Tk_Window tkwin)
{
    MacScale *macScalePtr = (MacScale *)ckalloc(sizeof(MacScale));

    macScalePtr->scaleHandle = NULL;
    if (scaleActionProc == NULL) {
	scaleActionProc = NewControlActionUPP(ScaleActionProc);
    }

    Tk_CreateEventHandler(tkwin, ButtonPressMask,
	    MacScaleEventProc, macScalePtr);

    return (TkScale *) macScalePtr;
}

/*
 *----------------------------------------------------------------------
 *







|







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *----------------------------------------------------------------------
 */

TkScale *
TkpCreateScale(
    Tk_Window tkwin)
{
    MacScale *macScalePtr = (MacScale *) ckalloc(sizeof(MacScale));

    macScalePtr->scaleHandle = NULL;
    if (scaleActionProc == NULL) {
	scaleActionProc = NewControlActionUPP(ScaleActionProc);
    }

    Tk_CreateEventHandler(tkwin, ButtonPressMask,
	    MacScaleEventProc, (ClientData) macScalePtr);

    return (TkScale *) macScalePtr;
}

/*
 *----------------------------------------------------------------------
 *
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayScale --
 *
 *	This procedure is invoked as an idle handler to redisplay the contents
 *	of a scale widget.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    int result;
    char string[TCL_DOUBLE_SPACE];
    MacScale *macScalePtr = clientData;
    Rect r;
    WindowRef windowRef;


    MacDrawable *macDraw;
    SInt32 initialValue, minValue, maxValue;
    UInt16 numTicks;
    Tcl_DString buf;

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpDisplayScale");
#endif
    scalePtr->flags &= ~REDRAW_PENDING;
    if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
	goto done;
    }

    /*
     * Invoke the scale's command if needed.
     */

    Tcl_Preserve(scalePtr);
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, string, -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }
    scalePtr->flags &= ~INVOKE_COMMAND;
    if (scalePtr->flags & SCALE_DELETED) {
	Tcl_Release(scalePtr);
	return;
    }
    Tcl_Release(scalePtr);

    /*
     * Now handle the part of redisplay that is the same for horizontal and
     * vertical scales: border and traversal highlight.

     */

    if (scalePtr->highlightWidth != 0) {
	GC gc = Tk_GCForColor(scalePtr->highlightColorPtr, Tk_WindowId(tkwin));

	Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth,
		Tk_WindowId(tkwin));
    }
    Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scalePtr->bgBorder,
	    scalePtr->highlightWidth, scalePtr->highlightWidth,
	    Tk_Width(tkwin) - 2*scalePtr->highlightWidth,
	    Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
	    scalePtr->borderWidth, scalePtr->relief);

    /*
     * Set up port for drawing Macintosh control.
     */

    macDraw = (MacDrawable *)Tk_WindowId(tkwin);



    windowRef = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));

    /*
     * Create Macintosh control.
     */

#define MAC_OSX_SCROLL_WIDTH 10

    if (scalePtr->orient == ORIENT_HORIZONTAL) {
	int offset = (Tk_Height(tkwin) - MAC_OSX_SCROLL_WIDTH) / 2;

	if (offset < 0) {
	    offset = 0;
	}

	r.left = macDraw->xOff + scalePtr->inset;
	r.top = macDraw->yOff + offset;
	r.right = macDraw->xOff+Tk_Width(tkwin) - scalePtr->inset;
	r.bottom = macDraw->yOff + offset + MAC_OSX_SCROLL_WIDTH/2;
    } else {
	int offset = (Tk_Width(tkwin) - MAC_OSX_SCROLL_WIDTH) / 2;

	if (offset < 0) {
	    offset = 0;
	}

	r.left = macDraw->xOff + offset;
	r.top = macDraw->yOff + scalePtr->inset;
	r.right = macDraw->xOff + offset + MAC_OSX_SCROLL_WIDTH/2;
	r.bottom = macDraw->yOff + Tk_Height(tkwin) - scalePtr->inset;
    }

    if (macScalePtr->scaleHandle == NULL) {
#ifdef TK_MAC_DEBUG_SCALE
	TkMacOSXDbgMsg("Initialising scale");
#endif
	initialValue = scalePtr->value;







|
|














|




|


>
>



<













|

|
<
|
<
<
<
|
<
<
<
<


|

|



|


|


|
|
>


















|
>
>
>
|








|










|








|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173



174




175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayScale --
 *
 *	This procedure is invoked as an idle handler to redisplay
 *	the contents of a scale widget.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *) clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    int result;
    char string[TCL_DOUBLE_SPACE];
    MacScale *macScalePtr = (MacScale *) clientData;
    Rect r;
    WindowRef windowRef;
    CGrafPtr destPort, savePort;
    Boolean portChanged;
    MacDrawable *macDraw;
    SInt32 initialValue, minValue, maxValue;
    UInt16 numTicks;


#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpDisplayScale");
#endif
    scalePtr->flags &= ~REDRAW_PENDING;
    if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
	goto done;
    }

    /*
     * Invoke the scale's command if needed.
     */

    Tcl_Preserve((ClientData) scalePtr);
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve((ClientData) interp);

	sprintf(string, scalePtr->format, scalePtr->value);



	result = Tcl_VarEval(interp, scalePtr->command, " ", string, NULL);




	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundError(interp);
	}
	Tcl_Release((ClientData) interp);
    }
    scalePtr->flags &= ~INVOKE_COMMAND;
    if (scalePtr->flags & SCALE_DELETED) {
	Tcl_Release((ClientData) scalePtr);
	return;
    }
    Tcl_Release((ClientData) scalePtr);

    /*
     * Now handle the part of redisplay that is the same for
     * horizontal and vertical scales: border and traversal
     * highlight.
     */

    if (scalePtr->highlightWidth != 0) {
	GC gc = Tk_GCForColor(scalePtr->highlightColorPtr, Tk_WindowId(tkwin));

	Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth,
		Tk_WindowId(tkwin));
    }
    Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scalePtr->bgBorder,
	    scalePtr->highlightWidth, scalePtr->highlightWidth,
	    Tk_Width(tkwin) - 2*scalePtr->highlightWidth,
	    Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
	    scalePtr->borderWidth, scalePtr->relief);

    /*
     * Set up port for drawing Macintosh control.
     */

    macDraw = (MacDrawable *) Tk_WindowId(tkwin);
    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
    windowRef = TkMacOSXDrawableWindow(Tk_WindowId(tkwin));
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));

    /*
     * Create Macintosh control.
     */

#define MAC_OSX_SCROLL_WIDTH 10

    if (scalePtr->orient == ORIENT_HORIZONTAL) {
	int offset = (Tk_Height(tkwin) - MAC_OSX_SCROLL_WIDTH)/2;

	if (offset < 0) {
	    offset = 0;
	}

	r.left = macDraw->xOff + scalePtr->inset;
	r.top = macDraw->yOff + offset;
	r.right = macDraw->xOff+Tk_Width(tkwin) - scalePtr->inset;
	r.bottom = macDraw->yOff + offset + MAC_OSX_SCROLL_WIDTH/2;
    } else {
	int offset = (Tk_Width(tkwin) - MAC_OSX_SCROLL_WIDTH)/2;

	if (offset < 0) {
	    offset = 0;
	}

	r.left = macDraw->xOff + offset;
	r.top = macDraw->yOff + scalePtr->inset;
	r.right = macDraw->xOff + offset + MAC_OSX_SCROLL_WIDTH/2;
	r.bottom = macDraw->yOff+Tk_Height(tkwin) - scalePtr->inset;
    }

    if (macScalePtr->scaleHandle == NULL) {
#ifdef TK_MAC_DEBUG_SCALE
	TkMacOSXDbgMsg("Initialising scale");
#endif
	initialValue = scalePtr->value;
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290



291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321


322
323
324
325


326
327
328
329
330
331
332
333
334
335




336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396
397
398








399
400
401
402
403
404
405
	    numTicks = 0;
	} else {
	    numTicks = (maxValue - minValue)/scalePtr->tickInterval;
	}

	CreateSliderControl(windowRef, &r, initialValue, minValue, maxValue,
		kControlSliderPointsDownOrRight, numTicks, 1, scaleActionProc,
		&macScalePtr->scaleHandle);
	SetControlReference(macScalePtr->scaleHandle, (UInt32) scalePtr);

	if (IsWindowActive(windowRef)) {
	    macScalePtr->flags |= ACTIVE;
	}
    } else {
	SetControlBounds(macScalePtr->scaleHandle, &r);
	SetControl32BitValue(macScalePtr->scaleHandle, scalePtr->value);
	SetControl32BitMinimum(macScalePtr->scaleHandle, scalePtr->fromValue);
	SetControl32BitMaximum(macScalePtr->scaleHandle, scalePtr->toValue);
    }

    /*
     * Finally draw the control.
     */

    SetControlVisibility(macScalePtr->scaleHandle, true, true);
    HiliteControl(macScalePtr->scaleHandle, 0);
    Draw1Control(macScalePtr->scaleHandle);




done:
    scalePtr->flags &= ~REDRAW_ALL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScaleElement --
 *
 *	Determine which part of a scale widget lies under a given point.

 *
 * Results:
 *	The return value is either TROUGH1, SLIDER, TROUGH2, or OTHER,
 *	depending on which of the scale's active elements (if any) is under the
 *	point at (x,y).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpScaleElement(
    TkScale *scalePtr,		/* Widget record for scale. */
    int x, int y)		/* Coordinates within scalePtr's window. */
{
    MacScale *macScalePtr = (MacScale *) scalePtr;
    ControlPartCode part;
    Point where;
    Rect bounds;



#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpScaleElement");
#endif



    /*
     * All of the calculations in this procedure mirror those in
     * DisplayScrollbar. Be sure to keep the two consistent.
     */

    TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds);
    where.h = x + bounds.left;
    where.v = y + bounds.top;
    part = TestControl(macScalePtr->scaleHandle, where);





#ifdef TK_MAC_DEBUG_SCALE
    fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v );
#endif

    switch (part) {
    case inSlider:
	return SLIDER;
    case inInc:
	if (scalePtr->orient == ORIENT_VERTICAL) {
	    return TROUGH1;
	} else {
	    return TROUGH2;
	}
    case inDecr:
	if (scalePtr->orient == ORIENT_VERTICAL) {
	    return TROUGH2;
	} else {
	    return TROUGH1;
	}
    default:
	return OTHER;
    }
}

/*
 *--------------------------------------------------------------
 *
 * MacScaleEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for ButtonPress events
 *	on scales.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When the window gets deleted, internal structures get cleaned up. When
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MacScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    MacScale *macScalePtr = (MacScale *) clientData;
    Point where;
    Rect bounds;
    int part;



#ifdef TK_MAC_DEBUG_SCALE
    fprintf(stderr,"MacScaleEventProc\n" );
#endif

    /*
     * To call Macintosh control routines we must have the port set to the
     * window containing the control. We will then test which part of the
     * control was hit and act accordingly.
     */









    TkMacOSXDbgMsg("calling TestControl");
#endif
    part = TestControl(macScalePtr->scaleHandle, where);
    if (part == 0) {
	return;
    }








|
















|
|


>
>
>









|
>


|
|
|
















>
>




>
>










>
>
>
>






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|








|
|





|
|













>
>






|
|
|


>
>
>
>
>
>
>
>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
	    numTicks = 0;
	} else {
	    numTicks = (maxValue - minValue)/scalePtr->tickInterval;
	}

	CreateSliderControl(windowRef, &r, initialValue, minValue, maxValue,
		kControlSliderPointsDownOrRight, numTicks, 1, scaleActionProc,
		&(macScalePtr->scaleHandle));
	SetControlReference(macScalePtr->scaleHandle, (UInt32) scalePtr);

	if (IsWindowActive(windowRef)) {
	    macScalePtr->flags |= ACTIVE;
	}
    } else {
	SetControlBounds(macScalePtr->scaleHandle, &r);
	SetControl32BitValue(macScalePtr->scaleHandle, scalePtr->value);
	SetControl32BitMinimum(macScalePtr->scaleHandle, scalePtr->fromValue);
	SetControl32BitMaximum(macScalePtr->scaleHandle, scalePtr->toValue);
    }

    /*
     * Finally draw the control.
     */

    SetControlVisibility(macScalePtr->scaleHandle,true,true);
    HiliteControl(macScalePtr->scaleHandle,0);
    Draw1Control(macScalePtr->scaleHandle);

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
done:
    scalePtr->flags &= ~REDRAW_ALL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScaleElement --
 *
 *	Determine which part of a scale widget lies under a given
 *	point.
 *
 * Results:
 *	The return value is either TROUGH1, SLIDER, TROUGH2, or
 *	OTHER, depending on which of the scale's active elements
 *	(if any) is under the point at (x,y).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpScaleElement(
    TkScale *scalePtr,		/* Widget record for scale. */
    int x, int y)		/* Coordinates within scalePtr's window. */
{
    MacScale *macScalePtr = (MacScale *) scalePtr;
    ControlPartCode part;
    Point where;
    Rect bounds;
    CGrafPtr destPort, savePort;
    Boolean portChanged;

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpScaleElement");
#endif
    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scalePtr->tkwin));
    portChanged = QDSwapPort(destPort, &savePort);

    /*
     * All of the calculations in this procedure mirror those in
     * DisplayScrollbar. Be sure to keep the two consistent.
     */

    TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds);
    where.h = x + bounds.left;
    where.v = y + bounds.top;
    part = TestControl(macScalePtr->scaleHandle, where);

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }

#ifdef TK_MAC_DEBUG_SCALE
    fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v );
#endif

    switch (part) {
	case inSlider:
	    return SLIDER;
	case inInc:
	    if (scalePtr->orient == ORIENT_VERTICAL) {
		return TROUGH1;
	    } else {
		return TROUGH2;
	    }
	case inDecr:
	    if (scalePtr->orient == ORIENT_VERTICAL) {
		return TROUGH2;
	    } else {
		return TROUGH1;
	    }
	default:
	    return OTHER;
    }
}

/*
 *--------------------------------------------------------------
 *
 * MacScaleEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for
 *	ButtonPress events on scales.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When the window gets deleted, internal structures get
 *	cleaned up. When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MacScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    MacScale *macScalePtr = (MacScale *) clientData;
    Point where;
    Rect bounds;
    int part;
    CGrafPtr destPort, savePort;
    Boolean portChanged;

#ifdef TK_MAC_DEBUG_SCALE
    fprintf(stderr,"MacScaleEventProc\n" );
#endif

    /*
     * To call Macintosh control routines we must have the port
     * set to the window containing the control. We will then test
     * which part of the control was hit and act accordingly.
     */

    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(macScalePtr->info.tkwin));
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(macScalePtr->info.tkwin));

    TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds);
    where.h = eventPtr->xbutton.x + bounds.left;
    where.v = eventPtr->xbutton.y + bounds.top;
#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("calling TestControl");
#endif
    part = TestControl(macScalePtr->scaleHandle, where);
    if (part == 0) {
	return;
    }

417
418
419
420
421
422
423




424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

    /*
     * The HandleControlClick call will "eat" the ButtonUp event. We now
     * generate a ButtonUp event so Tk will unset implicit grabs etc.
     */

    TkGenerateButtonEventForXPointer(Tk_WindowId(macScalePtr->info.tkwin));




}

/*
 *--------------------------------------------------------------
 *
 * ScaleActionProc --
 *
 *	Callback procedure used by the Macintosh toolbox call
 *	HandleControlClick. This call will update the display while the
 *	scrollbar is being manipulated by the user.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May change the display.
 *







>
>
>
>








|
|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463

    /*
     * The HandleControlClick call will "eat" the ButtonUp event. We now
     * generate a ButtonUp event so Tk will unset implicit grabs etc.
     */

    TkGenerateButtonEventForXPointer(Tk_WindowId(macScalePtr->info.tkwin));

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ScaleActionProc --
 *
 *	Callback procedure used by the Macintosh toolbox call
 *	HandleControlClick. This call will update the display
 *	while the scrollbar is being manipulated by the user.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May change the display.
 *
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
    TkScale *scalePtr = (TkScale *) GetControlReference(theControl);

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("ScaleActionProc");
#endif
    value = GetControlValue(theControl);
    TkScaleSetValue(scalePtr, value, 1, 1);
    Tcl_Preserve(scalePtr);
    TkMacOSXRunTclEventLoop();
    Tcl_Release(scalePtr);
}
#endif

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

|











473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
    TkScale *scalePtr = (TkScale *) GetControlReference(theControl);

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("ScaleActionProc");
#endif
    value = GetControlValue(theControl);
    TkScaleSetValue(scalePtr, value, 1, 1);
    Tcl_Preserve((ClientData) scalePtr);
    TkMacOSXRunTclEventLoop();
    Tcl_Release((ClientData) scalePtr);
}
#endif

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXScrlbr.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


91






92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395

396
397



398
399
400
401
402
403

404
405
406
407
408
409
410
411
412

413

414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465

466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

517
518
519


520
521
522
523

524
525
526

527
528
529
530
531
532

533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612


613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634

635
636


637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
/*
 * tkMacOSXScrollbar.c --
 *
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright (c) 2018-2019 Marc Culler
 *
 * 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 "tkScrollbar.h"
#include "tkMacOSXPrivate.h"

/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	18
#define MIN_GAP			4

/*
 * Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.
 */

#ifdef __LP64__
#define RangeToFactor(maximum)	(((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum)	(((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */

/*
 * Apple reversed the scroll direction with the release of OSX 10.7 Lion.
 */

#define SNOW_LEOPARD_STYLE	(NSAppKitVersionNumber < 1138)

/*
 * Declaration of an extended scrollbar structure with Mac specific additions.
 */

typedef struct MacScrollbar {
    TkScrollbar information;	/* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */
    Bool buttonDown;            /* Is the mouse button down? */
    Bool mouseOver;             /* Is the pointer over the scrollbar. */
    HIThemeTrackDrawInfo info;	/* Controls how the scrollbar is drawn. */
} MacScrollbar;

/* Used to initialize a MacScrollbar's info field. */
HIThemeTrackDrawInfo defaultInfo = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
};

/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

const Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,			/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 * Information on scrollbar layout, metrics, and draw info.
 */

typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;

static ScrollbarMetrics metrics = {
    /* kThemeScrollBarMedium */


    15, MIN_SLIDER_LENGTH, 26, 14, 14, kControlSizeNormal






};


/*
 * Declarations of static functions defined later in this file:
 */

static void		ScrollbarEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ScrollbarEvent(TkScrollbar *scrollPtr,
			    XEvent *eventPtr);
static void		UpdateControlValues(TkScrollbar *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
 *	Allocate a new TkScrollbar structure.
 *
 * Results:
 *	Returns a newly allocated TkScrollbar structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkScrollbar *
TkpCreateScrollbar(
    Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = NULL;
    scrollPtr->copyGC = NULL;
    scrollPtr->info = defaultInfo;
    scrollPtr->buttonDown = false;

    Tk_CreateEventHandler(tkwin,
	    ExposureMask        |
	    StructureNotifyMask |
	    FocusChangeMask     |
	    ButtonPressMask     |
	    ButtonReleaseMask   |
	    EnterWindowMask     |
	    LeaveWindowMask     |
	    VisibilityChangeMask,
	    ScrollbarEventProc, scrollPtr);

    return (TkScrollbar *) scrollPtr;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDisplayScrollbar --
 *
 *	This procedure redraws the contents of a scrollbar 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.
 *
 * Side effects:
 *	Draws a scrollbar on the screen.
 *
 *--------------------------------------------------------------
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED > 1080

/*
 * This stand-alone drawing function is used on macOS 10.9 and newer because
 * the HIToolbox does not draw the scrollbar thumb at the expected size on
 * those systems.  The thumb is drawn too large, causing a mouse click on the
 * thumb to be interpreted as a mouse click in the trough.
 */

static void drawMacScrollbar(
    TkScrollbar *scrollPtr,
    MacScrollbar *msPtr,
    CGContextRef context)
{
    Drawable d = Tk_WindowId(scrollPtr->tkwin);
    NSView *view = TkMacOSXGetNSViewForDrawable(d);
    CGPathRef path;
    CGPoint inner[2], outer[2], thumbOrigin;
    CGSize thumbSize;
    CGRect troughBounds = msPtr->info.bounds;
    troughBounds.origin.y = [view bounds].size.height -
	(troughBounds.origin.y + troughBounds.size.height);
    if (scrollPtr->vertical) {
	thumbOrigin.x = troughBounds.origin.x + MIN_GAP;
	thumbOrigin.y = troughBounds.origin.y + scrollPtr->sliderFirst;
	thumbSize.width = troughBounds.size.width - 2*MIN_GAP + 1;
	thumbSize.height = scrollPtr->sliderLast - scrollPtr->sliderFirst;
	inner[0] = troughBounds.origin;
	inner[1] = CGPointMake(inner[0].x,
			       inner[0].y + troughBounds.size.height);
	outer[0] = CGPointMake(inner[0].x + troughBounds.size.width - 1,
			       inner[0].y);
	outer[1] = CGPointMake(outer[0].x, inner[1].y);
    } else {
	thumbOrigin.x = troughBounds.origin.x + scrollPtr->sliderFirst;
	thumbOrigin.y = troughBounds.origin.y + MIN_GAP;
	thumbSize.width = scrollPtr->sliderLast - scrollPtr->sliderFirst;
	thumbSize.height = troughBounds.size.height - 2*MIN_GAP + 1;
	inner[0] = troughBounds.origin;
	inner[1] = CGPointMake(inner[0].x + troughBounds.size.width,
			       inner[0].y + 1);
	outer[0] = CGPointMake(inner[0].x,
			       inner[0].y + troughBounds.size.height);
	outer[1] = CGPointMake(inner[1].x, outer[0].y);
    }
    CGContextSetShouldAntialias(context, false);
    CGContextSetGrayFillColor(context, 250.0 / 255, 1.0);
    CGContextFillRect(context, troughBounds);
    CGContextSetGrayStrokeColor(context, 232.0 / 255, 1.0);
    CGContextStrokeLineSegments(context, inner, 2);
    CGContextSetGrayStrokeColor(context, 238.0 / 255, 1.0);
    CGContextStrokeLineSegments(context, outer, 2);

    /*
     * Do not display the thumb unless scrolling is possible, in accordance
     * with macOS behavior.
     *
     * Native scrollbars and Ttk scrollbars are always 15 pixels wide, but we
     * allow Tk scrollbars to have any width, even if it looks bad. To prevent
     * sporadic assertion errors when drawing skinny thumbs we must make sure
     * the radius is at most half the width.
     */

    if (scrollPtr->firstFraction > 0.0 || scrollPtr->lastFraction < 1.0) {
	CGRect thumbBounds = {thumbOrigin, thumbSize};
	int width = scrollPtr->vertical ? thumbSize.width : thumbSize.height;
	int radius = width >= 8 ? 4 : width >> 1;
	path = CGPathCreateWithRoundedRect(thumbBounds, radius, radius, NULL);
	CGContextBeginPath(context);
	CGContextAddPath(context, path);
	if (msPtr->info.trackInfo.scrollbar.pressState != 0) {
	    CGContextSetGrayFillColor(context, 133.0 / 255, 1.0);
	} else {
	    CGContextSetGrayFillColor(context, 200.0 / 255, 1.0);
	}
	CGContextSetShouldAntialias(context, true);
	CGContextFillPath(context);
	CFRelease(path);
    }
}
#endif

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
	return;
    }

    MacDrawable *macWin = (MacDrawable *)winPtr->window;
    NSView *view = TkMacOSXGetNSViewForDrawable(macWin);

    if ((view == NULL)
	    || (macWin->flags & TK_DO_NOT_DRAW)
	    || !TkMacOSXSetupDrawingContext((Drawable)macWin, NULL, &dc)) {
	return;
    }

    /*
     * Transform NSView coordinates to CoreGraphics coordinates.
     */

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0, .ty = viewHeight
    };

    CGContextConcatCTM(dc.context, t);

    /*
     * Draw a 3D rectangle to provide a base for the native scrollbar.
     */

    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
    	    fgGC = bgGC;
    	}
    	TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
    		(Pixmap) macWin);
    }

    Tk_Draw3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
	    scrollPtr->highlightWidth, scrollPtr->highlightWidth,
	    Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
	    Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
	    scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
	    scrollPtr->inset, scrollPtr->inset,
	    Tk_Width(tkwin) - 2*scrollPtr->inset,
	    Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);

    /*
     * Update values and then draw the native scrollbar over the rectangle.
     */

    UpdateControlValues(scrollPtr);

    if (SNOW_LEOPARD_STYLE) {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
			 kHIThemeOrientationInverted);
    } else if ([NSApp macOSVersion] <= 100800) {
	HIThemeDrawTrack(&msPtr->info, 0, dc.context,
			 kHIThemeOrientationNormal);
    } else {
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1080

	/*
	 * Switch back to NSView coordinates and draw a modern scrollbar.
	 */

	CGContextConcatCTM(dc.context, t);
	drawMacScrollbar(scrollPtr, msPtr, dc.context);
#endif
    }
    TkMacOSXRestoreDrawingContext(&dc);
    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
 *
 *	After changes in a scrollbar's size or configuration, this procedure
 *	recomputes various geometry information used in displaying the
 *	scrollbar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

extern void
TkpComputeScrollbarGeometry(
    TkScrollbar *scrollPtr)
				/* Scrollbar whose geometry may have
				 * changed. */
{
    /*
     * The code below is borrowed from tkUnixScrlbr.c but has been adjusted to
     * account for some differences between macOS and X11. The Unix scrollbar
     * has an arrow button on each end.  On macOS 10.6 (Snow Leopard) the
     * scrollbars by default have both arrow buttons at the bottom or right.
     * (There is a preferences setting to use the Unix layout, but we are not
     * supporting that!)  On more recent versions of macOS there are no arrow
     * buttons at all. The case of no arrow buttons can be handled as a special
     * case of having both buttons at the end, but where scrollPtr->arrowLength
     * happens to be zero.  To adjust for having both arrows at the same end we
     * shift the scrollbar up by the arrowLength.
     */

    int fieldLength;

    if (scrollPtr->highlightWidth < 0) {
	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    if ([NSApp macOSVersion] == 100600) {
	scrollPtr->arrowLength = scrollPtr->width;
    } else {
	scrollPtr->arrowLength = 0;
    }

    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
	    : Tk_Width(scrollPtr->tkwin))
	    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*
     * Adjust the slider so that it has at least a minimal size and so there

     * is a small gap on either end which can be used to scroll by one page.
     */




    if (scrollPtr->sliderFirst < MIN_GAP) {
	scrollPtr->sliderFirst = MIN_GAP;
	scrollPtr->sliderLast += MIN_GAP;
    }
    if (scrollPtr->sliderLast > fieldLength - MIN_GAP) {

	scrollPtr->sliderLast = fieldLength - MIN_GAP;
	scrollPtr->sliderFirst -= MIN_GAP;
    }
    if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
	scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
	scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }

    scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset;

    scrollPtr->sliderLast += scrollPtr->inset;


    /*
     * Register the desired geometry for the window. Leave enough space for the
     * two arrows, if there are any arrows, plus a minimum-size slider, plus
     * border around the whole window, if any. Then arrange for the window to
     * be redisplayed.
     */

    if (scrollPtr->vertical) {
	Tk_GeometryRequest(scrollPtr->tkwin,
		scrollPtr->width + 2*scrollPtr->inset,
		2*(scrollPtr->arrowLength + scrollPtr->borderWidth
		+ scrollPtr->inset) + metrics.minThumbHeight);
    } else {
	Tk_GeometryRequest(scrollPtr->tkwin,
		2*(scrollPtr->arrowLength + scrollPtr->borderWidth
		+ scrollPtr->inset) + metrics.minThumbHeight,
		scrollPtr->width + 2*scrollPtr->inset);
    }
    Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
}


/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScrollbar --
 *
 *	Free data structures associated with the scrollbar control.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the GCs associated with the scrollbar.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }
}



/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished processing
 *	configuration options, in order to configure platform specific options.
 *	There are no such option on the Mac, however.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Currently, none.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)


{
    (void)scrollPtr;
    /* empty */
}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --
 *
 *	Determine the scrollbar element corresponding to a given position.
 *
 * Results:
 *	One of TOP_ARROW, TOP_GAP, etc., indicating which element of the
 *	scrollbar covers the position given by (x, y). If (x,y) is outside the
 *	scrollbar entirely, then OUTSIDE is returned.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

    /*
     * The code below is borrowed from tkUnixScrlbr.c and needs no adjustment
     * since it does not involve the arrow buttons.


     */

    int length, width, tmp;
    const int inset = scrollPtr->inset;


    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);

	width = Tk_Width(scrollPtr->tkwin);
    } else {
	tmp = x;
	x = y;
	y = tmp;
	length = Tk_Width(scrollPtr->tkwin);

	width = Tk_Height(scrollPtr->tkwin);
    }


    if (x < inset || x >= width - inset ||
	    y < inset || y >= length - inset) {
	return OUTSIDE;
    }

    /*
     * Here we assume that the scrollbar is layed out with both arrow buttons
     * at the bottom (or right).  Except on 10.6, however, the arrows do not
     * actually exist, i.e. the arrowLength is 0.  These are the same
     * assumptions which are being made in TkpComputeScrollbarGeometry.
     */

    if (y < scrollPtr->sliderFirst + scrollPtr->arrowLength) {
	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
	return SLIDER;
    }
    if (y < length - (2*scrollPtr->arrowLength + inset)) {
	return BOTTOM_GAP;
    }

    /*
     * On systems newer than 10.6 we have already returned.
     */

    if (y < length - (scrollPtr->arrowLength + inset)) {
	return TOP_ARROW;
    }
    return BOTTOM_ARROW;
}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
 *	This procedure updates the Macintosh scrollbar control to display the
 *	values defined by the Tk scrollbar. This is the key interface to the
 *	Mac-native scrollbar; the Unix bindings drive scrolling in the Tk
 *	window and all the Mac scrollbar has to do is redraw itself.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Macintosh control is updated.
 *
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *)Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect contrlRect;

    short width, height;

    NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;

    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
	    Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height - scrollPtr->arrowLength;



    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    msPtr->info.bounds = contrlRect;
    if (scrollPtr->vertical) {
	msPtr->info.attributes &= ~kThemeTrackHorizontal;
    } else {
	msPtr->info.attributes |= kThemeTrackHorizontal;
    }

    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
     * area in the content area being scrolled. The maximum value of the
     * control is therefore the dimension of the content area less the size of
     * the view area.
     */


    double factor = RangeToFactor(100.0);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) * factor;


    msPtr->info.max = factor - dViewSize;
    msPtr->info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
	if (SNOW_LEOPARD_STYLE) {
	    msPtr->info.value = factor * scrollPtr->firstFraction;
	} else {
	    msPtr->info.value = msPtr->info.max -
		    factor * scrollPtr->firstFraction;
	}
    } else {
	msPtr->info.value = factor * scrollPtr->firstFraction;
    }

    if ((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
	    || height <= metrics.minHeight) {
    	msPtr->info.enableState = kThemeTrackHideTrack;
    } else {
        msPtr->info.enableState = kThemeTrackActive;
    	msPtr->info.attributes =
		kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost;
    }
}


/*
 *--------------------------------------------------------------
 *
 * ScrollbarEvent --
 *
 *	This procedure is invoked in response to <Button>,
 *      <ButtonRelease>, <EnterNotify>, and <LeaveNotify> events.  The
 *      Scrollbar appearance is modified for each event.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarEvent(
    TkScrollbar *scrollPtr,
    XEvent *eventPtr)
{
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;

    /*
     * The pressState does not indicate whether the moused button was pressed
     * at some location in the Scrollbar.  Rather, it indicates that the
     * scrollbar should appear as if it were pressed in that location. The
     * standard Mac behavior is that once the button is pressed inside the
     * Scrollbar the appearance should not change until the button is released,
     * even if the mouse moves outside of the scrollbar.  However, if the mouse
     * lies over the scrollbar but the button is not pressed then the
     * appearance should be the same as if the button had been pressed on the
     * slider, i.e. kThemeThumbPressed.  See the file Appearance.r, or
     * HIToolbox.bridgesupport on 10.14.
     */

    if (eventPtr->type == ButtonPress) {
	msPtr->buttonDown = true;
	UpdateControlValues(scrollPtr);

	int where = TkpScrollbarPosition(scrollPtr,
		eventPtr->xbutton.x, eventPtr->xbutton.y);

	switch (where) {
	case OUTSIDE:
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	    break;
	case TOP_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeTopTrackPressed;
	    break;
	case SLIDER:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	    break;
	case BOTTOM_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeBottomTrackPressed;
	    break;
	case TOP_ARROW:

	    /*
	     * This looks wrong and the docs say it is wrong but it works.
	     */

	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeTopInsideArrowPressed;
	    break;
	case BOTTOM_ARROW:
	    msPtr->info.trackInfo.scrollbar.pressState =
		    kThemeBottomOutsideArrowPressed;
	    break;
	}
    }
    if (eventPtr->type == ButtonRelease) {
	msPtr->buttonDown = false;
	if (!msPtr->mouseOver) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    if (eventPtr->type == EnterNotify) {
	msPtr->mouseOver = true;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	}
    }
    if (eventPtr->type == LeaveNotify) {
	msPtr->mouseOver = false;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    TkScrollbarEventuallyRedraw(scrollPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEventProc --
 *
 *	This procedure 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.
 *
 *--------------------------------------------------------------
 */

static void
ScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = clientData;

    switch (eventPtr->type) {
    case UnmapNotify:
	TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
	break;
    case ActivateNotify:
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarEvent(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

|








<
<








<
<
<
<

<
|

<
|
<
<

|

|


<
<
<
<
|


|



|

|
<
<
<


<
<
<
<
<
<
<
<






|

|
|
|


|
|
<
<






|
|
>
>
|
>
>
>
>
>
>


>

|


|
|
<
<
|
|


















|

>




<
<

|
<
<
<
<
<
<
<
<
<
|









|
|





|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

|
<
|


|

|

|


|
|
|
<
|
|
|


<
<
<
<

|
<
<
|
<
<


<
<
<
|










|



|
|
|
|

|
|
|

<
<
<
|

|
<
<
|
<
<
<

<
|
<
<
<
|
|
<
<
|
<


|




















|
|
|

<
<
<
<
<
<
<
<
<
<
<
<

|


|


|
|
|
|
<
>

|
|

|

|
|


|
>
|

>
>
>
|
|
|
<

|
>
|
|

<
<
<
|
|

>
|
>
|
>
|

|
|
|
|



|
<
<
<

|
<
<
<


|
|
>


















|

|







|
>
|
>





|
|
|





|






|
>
>

|
<

|




















|



>
|
|
<
>
>
|

|
|
>



>






>


>

|
<




|
<
<
|


|





|


|
<
<
<
<
<




|





|
|
|
|
>












|

|

|

|
>


|


<

|




|
|

|

>
>



|

|

|

|

|










>
|
|
>
>
|
|

|
|
|
<
|
|

|

|
|
|
|

|
<
|

|
|
>



|

|
<
|





<
|
<

<

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<

<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|












<
<
<
|





|
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
18




19

20
21

22


23
24
25
26
27
28




29
30
31
32
33
34
35
36
37
38



39
40








41
42
43
44
45
46
47
48
49
50
51
52
53
54
55


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108


109
110









111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132


















































































133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155




156
157


158


159
160



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184



185
186
187


188



189

190



191
192


193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220












221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276



277
278



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397


398
399
400
401
402
403
404
405
406
407
408
409
410





411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524

525

526

527













528

529
530


531















532



533







534
535






















536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569



570
571
572
573
574
575
576








/*
 * tkMacOSXScrollbar.c -- 
 *
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.


 * 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 "tkScrollbar.h"
#include "tkMacOSXPrivate.h"







#define MIN_SCROLLBAR_VALUE		0


/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/


#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */





#define MOUNTAIN_LION_STYLE (NSAppKitVersionNumber < 1138)

/*
 * Declaration of Mac specific scrollbar structure.
 */

typedef struct MacScrollbar {
    TkScrollbar information;	 /* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */ 



} MacScrollbar;









/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/*Information on scrollbar layout, metrics, and draw info.*/


typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;

static ScrollbarMetrics metrics[2] = {
    {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */
    {11, 40, 20, 10, 10, NSSmallControlSize},  /* kThemeScrollBarSmall  */
};

HIThemeTrackDrawInfo info = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
    .kind = kThemeScrollBarMedium,
};


/*
 * Forward declarations for procedures defined later in this file:
 */

static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr);


static void UpdateControlValues(TkScrollbar  *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
 *	Allocate a new TkScrollbar structure.
 *
 * Results:
 *	Returns a newly allocated TkScrollbar structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkScrollbar *
TkpCreateScrollbar(
		   Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = NULL;
    scrollPtr->copyGC = NULL;



    Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr);









    
    return (TkScrollbar *) scrollPtr;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDisplayScrollbar --
 *
 *	This procedure redraws the contents of a scrollbar 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.
 *
 * Side effects:
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */



















































































void
TkpDisplayScrollbar(
		    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;

    register Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;
    
    scrollPtr->flags &= ~REDRAW_PENDING;
    
    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
  	return;
    }

    MacDrawable *macWin =  (MacDrawable *) winPtr->window;
    NSView *view = TkMacOSXDrawableView(macWin);
    if (!view ||

	macWin->flags & TK_DO_NOT_DRAW ||
	!TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
      return;
    }





    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,


			    .ty = viewHeight};


    CGContextConcatCTM(dc.context, t);




    /*Draw Unix-style scroll trough to provide rect for native scrollbar.*/
    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
    	    fgGC = bgGC;
    	}
    	TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
    			       (Pixmap) macWin);
    }

    Tk_Draw3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->highlightWidth, scrollPtr->highlightWidth,
    		       Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
    		       Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
    		       scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->inset, scrollPtr->inset,
    		       Tk_Width(tkwin) - 2*scrollPtr->inset,
    		       Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);




    /*Update values and draw in native rect.*/ 
    UpdateControlValues(scrollPtr);
    if (MOUNTAIN_LION_STYLE) {


      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted);



    } else {

      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);



    }
    TkMacOSXRestoreDrawingContext(&dc);


    

    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
 *
 *	After changes in a scrollbar's size or configuration, this procedure
 *	recomputes various geometry information used in displaying the
 *	scrollbar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

extern void
TkpComputeScrollbarGeometry(
			    register TkScrollbar *scrollPtr)
/* Scrollbar whose geometry may have
 * changed. */
{













    int variant, fieldLength;

    if (scrollPtr->highlightWidth < 0) {
    	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) :
		Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset
	       < metrics[0].width) ? 1 : 0;
    scrollPtr->arrowLength = (metrics[variant].topArrowHeight +

			      metrics[variant].bottomArrowHeight) / 2;
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
		   : Tk_Width(scrollPtr->tkwin))
	- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
    	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always
     * displayed in the scrollbar and so that it has at least
     * a minimal width (so it can be grabbed with the mouse).
     */

    if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) {
    	scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth;
    }
    if (scrollPtr->sliderFirst < 0) {
    	scrollPtr->sliderFirst = 0;

    }
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst +
				 metrics[variant].minThumbHeight)) {
    	scrollPtr->sliderLast = scrollPtr->sliderFirst +
	    metrics[variant].minThumbHeight;
    }



    if (scrollPtr->sliderLast > fieldLength) {
    	scrollPtr->sliderLast = fieldLength;
    }
    if (!(MOUNTAIN_LION_STYLE)) {
      scrollPtr->sliderFirst += scrollPtr->inset +
	metrics[variant].topArrowHeight;
      scrollPtr->sliderLast += scrollPtr->inset +
	metrics[variant].bottomArrowHeight;
    }
    /*
     * 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.
     */

    if (scrollPtr->vertical) {
    	Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) +  metrics[variant].minThumbHeight);



    } else {
    	Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight, scrollPtr->width + 2 * scrollPtr->inset);



    }
    Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
    
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScrollbar --
 *
 *	Free data structures associated with the scrollbar control.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the GCs associated with the scrollbar.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyScrollbar(
		    TkScrollbar *scrollPtr)
{
    MacScrollbar *macScrollPtr = (MacScrollbar *)scrollPtr;

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }

    macScrollPtr=NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished
 *	processing configuration options, in order to configure platform
 *	specific options.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Configuration info may get changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
		      register TkScrollbar *scrollPtr)
/* Information about widget; may or may not
 * already have values for some fields. */
{


}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --
 *
 *	Determine the scrollbar element corresponding to a given position.
 *
 * Results:
 *	One of TOP_ARROW, TOP_GAP, etc., indicating which element of the
 *	scrollbar covers the position given by (x, y). If (x,y) is outside the
 *	scrollbar entirely, then OUTSIDE is returned.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

  /*
   * Using code from tkUnixScrlbr.c because Unix scroll bindings are

   * driving the display at the script level. All the Mac scrollbar
   * has to do is re-draw itself.
   */

    int length, fieldlength, width, tmp;
    register const int inset = scrollPtr->inset;
    register const int arrowSize = scrollPtr->arrowLength + inset;

    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);
	fieldlength = length - 2 * arrowSize;
	width = Tk_Width(scrollPtr->tkwin);
    } else {
	tmp = x;
	x = y;
	y = tmp;
	length = Tk_Width(scrollPtr->tkwin);
	fieldlength = length - 2 * arrowSize; 
	width = Tk_Height(scrollPtr->tkwin);
    }
    fieldlength = fieldlength < 0 ? 0 : fieldlength;

    if (x<inset || x>=width-inset || y<inset || y>=length-inset) {

	return OUTSIDE;
    }

    /*
     * All of the calculations in this procedure mirror those in


     * TkpDisplayScrollbar. Be sure to keep the two consistent.
     */

    if (y < scrollPtr->sliderFirst) {
	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
	return SLIDER;
    }
    if (y < fieldlength){
	return BOTTOM_GAP;
    }
    if (y < fieldlength + arrowSize) {





	return TOP_ARROW;
    }
    return BOTTOM_ARROW;
}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
 *	This procedure updates the Macintosh scrollbar control to
 *	display the values defined by the Tk scrollbar. This is the
 *	key interface to the Mac-native * scrollbar; the Unix bindings
 *	drive scrolling in the Tk window and all the Mac scrollbar has
 *	to do is redraw itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Macintosh control is updated.
 *
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
		    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
 
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect  contrlRect;
    int variant; 
    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;

    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
		       Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    info.bounds = contrlRect;
    
    width = contrlRect.size.width;
    height = contrlRect.size.height;

    variant = contrlRect.size.width < metrics[0].width ? 1 : 0;
   
    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */ 

    info.bounds = contrlRect;
    if (scrollPtr->vertical) {
      info.attributes &= ~kThemeTrackHorizontal;
    } else {
      info.attributes |= kThemeTrackHorizontal;
    }
 
    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
     * area in the content area being scrolled. The maximum value of the
     * control is therefore the dimension of the content area less the size of
     * the view area.
     */

    double maximum = 100,  factor;
    factor = RangeToFactor(maximum);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
	* factor;
    info.max =  MIN_SCROLLBAR_VALUE +
	factor - dViewSize;
    info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
      if (MOUNTAIN_LION_STYLE) {
	info.value = factor * scrollPtr->firstFraction;
      } else {

	info.value = info.max - factor * scrollPtr->firstFraction;
      }
    } else {
	 info.value =  MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
    }
	
    if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
       || height <= metrics[variant].minHeight) {
    	info.enableState = kThemeTrackHideTrack;
    } else {
    	info.enableState = kThemeTrackActive;

    	info.attributes = kThemeTrackShowThumb |  kThemeTrackThumbRgnIsNotGhost;
    }

}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarPress --
 *
 *	This procedure is invoked in response to <ButtonPress> events.

 *	Enters a modal loop to handle scrollbar interactions.
 *
 *--------------------------------------------------------------
 */

static int

ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr)

{















  if (eventPtr->type == ButtonPress) {

    UpdateControlValues(scrollPtr); 
  }


  return TCL_OK;















}



































/*
 *--------------------------------------------------------------
 *
 * ScrollbarEventProc --
 *
 *	This procedure 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.
 *
 *--------------------------------------------------------------
 */

static void
ScrollbarEventProc(
		   ClientData clientData,	/* Information about window. */
		   XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = clientData;

    switch (eventPtr->type) {
    case UnmapNotify:
	TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
	break;
    case ActivateNotify:
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:



    	ScrollbarPress(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}
 








Changes to macosx/tkMacOSXSend.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkMacOSXSend.c --
 *
 *	This file provides procedures that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter. This
 *	current implementation for the Mac has most functionality stubbed out.
 *
 *	The current plan, which we have not had time to implement, is for the
 *	first Wish app to create a gestalt of type 'WIsH'. This gestalt will
 *	point to a table, in system memory, of Tk apps. Each Tk app, when it
 *	starts up, will register their name, and process ID, in this table.
 *	This will allow us to implement "tk appname".
 *





|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkMacOSXSend.c --
 *
 *	This file provides procedures that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter. This
 *	current implementation for the Mac has most functionality stubed out.
 *
 *	The current plan, which we have not had time to implement, is for the
 *	first Wish app to create a gestalt of type 'WIsH'. This gestalt will
 *	point to a table, in system memory, of Tk apps. Each Tk app, when it
 *	starts up, will register their name, and process ID, in this table.
 *	This will allow us to implement "tk appname".
 *
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
				 * list. */
} RegisteredInterp;

/*
 * A registry of all interpreters for a display is kept in a property
 * "InterpRegistry" on the root window of the display. It is organized as a
 * series of zero or more concatenated strings (in no particular order), each
 * of the form:
 *	window space name '\0'
 * where "window" is the hex id of the comm. window to use to talk to an
 * interpreter named "name".
 *
 * When the registry is being manipulated by an application (e.g. to add or
 * remove an entry), it is loaded into memory using a structure of the
 * following type:







|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
				 * list. */
} RegisteredInterp;

/*
 * A registry of all interpreters for a display is kept in a property
 * "InterpRegistry" on the root window of the display. It is organized as a
 * series of zero or more concatenated strings (in no particular order), each
 * of the form
 *	window space name '\0'
 * where "window" is the hex id of the comm. window to use to talk to an
 * interpreter named "name".
 *
 * When the registry is being manipulated by an application (e.g. to add or
 * remove an entry), it is loaded into memory using a structure of the
 * following type:
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
				 * none. See format description above; this is
				 * *not* terminated by the first null
				 * character. Dynamically allocated. */
    int allocedByX;		/* Non-zero means must free property with
				 * XFree; zero means use ckfree. */
} NameRegistry;

static int initialized = 0;	/* A flag to denote if we have initialized
				 * yet. */

static RegisteredInterp *interpListPtr = NULL;
				/* List of all interpreters registered by this
				 * process. */

/*







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
				 * none. See format description above; this is
				 * *not* terminated by the first null
				 * character. Dynamically allocated. */
    int allocedByX;		/* Non-zero means must free property with
				 * XFree; zero means use ckfree. */
} NameRegistry;

static int initialized = 0; /* A flag to denote if we have initialized
				 * yet. */

static RegisteredInterp *interpListPtr = NULL;
				/* List of all interpreters registered by this
				 * process. */

/*
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    Tcl_DecrRefCount(resultObjPtr);
    Tcl_ResetResult(interp);

    /*
     * We have found a unique name. Now add it to the registry.
     */

    riPtr = (RegisteredInterp *)ckalloc(sizeof(RegisteredInterp));
    riPtr->interp = interp;
    riPtr->name = (char *)ckalloc(strlen(actualName) + 1);
    riPtr->nextPtr = interpListPtr;
    interpListPtr = riPtr;
    strcpy(riPtr->name, actualName);

    /*
     * TODO: DeleteProc
     */







|

|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    Tcl_DecrRefCount(resultObjPtr);
    Tcl_ResetResult(interp);

    /*
     * We have found a unique name. Now add it to the registry.
     */

    riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
    riPtr->interp = interp;
    riPtr->name = ckalloc(strlen(actualName) + 1);
    riPtr->nextPtr = interpListPtr;
    interpListPtr = riPtr;
    strcpy(riPtr->name, actualName);

    /*
     * TODO: DeleteProc
     */
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData dummy,	/* Not used */
    Tcl_Interp *interp,		/* The interp we are sending from */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* The arguments */
{
    const char *const sendOptions[] = {"-async", "-displayof", "--", NULL};
    char *stringRep, *destName;
    /*int async = 0;*/
    int i, index, firstArg;
    RegisteredInterp *riPtr;
    Tcl_Obj *listObjPtr;
    int result = TCL_OK;
    (void)dummy;

    for (i = 1; i < (objc - 1); ) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index == 0) {
		/*async = 1;*/
		i++;
	    } else if (index == 1) {
		i += 2;







|




|






<




|
|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData clientData,	/* Used only for deletion */
    Tcl_Interp *interp,		/* The interp we are sending from */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* The arguments */
{
    const char *sendOptions[] = {"-async", "-displayof", "-", NULL};
    char *stringRep, *destName;
    /*int async = 0;*/
    int i, index, firstArg;
    RegisteredInterp *riPtr;
    Tcl_Obj *listObjPtr;
    int result = TCL_OK;


    for (i = 1; i < (objc - 1); ) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObj(interp, objv[i], sendOptions, "option", 0,
		    &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index == 0) {
		/*async = 1;*/
		i++;
	    } else if (index == 1) {
		i += 2;
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
    Tcl_Obj *listObjPtr;
    RegisteredInterp *riPtr;
    (void)tkwin;

    listObjPtr = Tcl_NewListObj(0, NULL);
    riPtr = interpListPtr;
    while (riPtr != NULL) {
	Tcl_ListObjAppendElement(interp, listObjPtr,
		Tcl_NewStringObj(riPtr->name, -1));
	riPtr = riPtr->nextPtr;







<







462
463
464
465
466
467
468

469
470
471
472
473
474
475
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
    Tcl_Obj *listObjPtr;
    RegisteredInterp *riPtr;


    listObjPtr = Tcl_NewListObj(0, NULL);
    riPtr = interpListPtr;
    while (riPtr != NULL) {
	Tcl_ListObjAppendElement(interp, listObjPtr,
		Tcl_NewStringObj(riPtr->name, -1));
	riPtr = riPtr->nextPtr;
496
497
498
499
500
501
502
503


504
505
506
507
508
509
510
511
512
513
514
515
516
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *dummy)		/* Not used */


{
    (void)dummy;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|
>
>

<











494
495
496
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *interp)		/* Interpreter to use for error reporting (no
				 * errors are ever returned, but the
				 * interpreter is needed anyway). */
{

    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Deleted macosx/tkMacOSXServices.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * tkMacOSXServices.c --
 *\
 *	This file allows the integration of Tk and the Cocoa NSServices API.
 *
 * Copyright (c) 2010-2019 Kevin Walzer/WordTech Communications LLC.
 * Copyright (c) 2019 Marc Culler.
 * Copyright (c) 2010 Adrian Robert.
 *
 * 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 <tkMacOSXInt.h>

/*
 * Event proc which calls the PerformService procedure.
 */

static int
ServicesEventProc(
    TCL_UNUSED(Tcl_Event *),
    TCL_UNUSED(int))
{
    TkMainInfo *info = TkGetMainInfoList();

    Tcl_GlobalEval(info->interp, "::tk::mac::PerformService");
    return 1;
}

/*
 * The Wish application can send the current selection in the Tk clipboard
 * to other applications which accept messages of type NSString.  The TkService
 * object provides this service via its provideService method.  (The method
 * must be specified in the application's Info.plist file for this to work.)
 */

@interface TkService : NSObject {

}

+ (void) initialize;
- (void) provideService:(NSPasteboard *)pboard
	       userData:(NSString *)data
		  error:(NSString **)error;
- (BOOL) writeSelectionToPasteboard:(NSPasteboard *)pboard
			      types:(NSArray *)types;

@end

/*
 * Class methods.
 */

@implementation TkService

+ (void) initialize {
    NSArray *sendTypes = [NSArray arrayWithObjects:@"NSStringPboardType",
				  @"NSPasteboardTypeString", nil];
    [NSApp registerServicesMenuSendTypes:sendTypes returnTypes:sendTypes];
    return;
}

/*
 * Get the current Tk selection and copy it to the system pasteboard.
 */

- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
			     types:(NSArray *)types
{
    NSArray *typesDeclared = nil;
    NSString *pboardType = nil;
    TkMainInfo *info = TkGetMainInfoList();

    for (NSString *typeString in types) {
	if ([typeString isEqualToString:@"NSStringPboardType"] ||
	    [typeString isEqualToString:@"NSPasteboardTypeString"]) {
	    typesDeclared = [NSArray arrayWithObject:typeString];
	    pboardType = typeString;
	    break;
	}
    }
    if (!typesDeclared) {
	return NO;
    }
    Tcl_Eval(info->interp, "selection get");

    char *copystring = Tcl_GetString(Tcl_GetObjResult(info->interp));
    NSString *writestring = [NSString stringWithUTF8String:copystring];

    [pboard declareTypes:typesDeclared owner:nil];
    return [pboard setString:writestring forType:pboardType];
}

/*
 * This is the method that actually calls the Tk service; it must be specified
 * in Info.plist.
 */

- (void)provideService:(NSPasteboard *)pboard
	      userData:(NSString *)data
		 error:(NSString **)error
{
    NSString *pboardString = nil, *pboardType = nil;
    NSArray *types = [pboard types];
    Tcl_Event *event;
    (void)data;
    (void)error;

    /*
     * Get a string from the private pasteboard and copy it to the general
     * pasteboard to make it available to other applications.
     */

    for (NSString *typeString in types) {
	if ([typeString isEqualToString:@"NSStringPboardType"] ||
	    [typeString isEqualToString:@"NSPasteboardTypeString"]) {
	    pboardString = [pboard stringForType:typeString];
	    pboardType = typeString;
	    break;
	}
    }
    if (pboardString) {
	NSPasteboard *generalpasteboard = [NSPasteboard generalPasteboard];
	[generalpasteboard declareTypes:[NSArray arrayWithObjects:pboardType, nil]
				  owner:nil];
	[generalpasteboard setString:pboardString forType:pboardType];
	event = (Tcl_Event *)ckalloc(sizeof(Tcl_Event));
	event->proc = ServicesEventProc;
	Tcl_QueueEvent((Tcl_Event *)event, TCL_QUEUE_TAIL);
    }
}
@end

/*

 * Instantiate a TkService object and register it with the NSApplication.
 * This is called exactly one time from TkpInit.
 */

int
TkMacOSXServices_Init(
    TCL_UNUSED(Tcl_Interp *))
{
    /*
     * Initialize an instance of TkService and register it with the NSApp.
     */

    TkService *service = [[TkService alloc] init];
    [NSApp setServicesProvider:service];
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































Changes to macosx/tkMacOSXSubwindows.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXConstants.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_CLIP_REGIONS
#endif
*/








<







10
11
12
13
14
15
16

17
18
19
20
21
22
23
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXWm.h"


/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_CLIP_REGIONS
#endif
*/

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186



187
188
189
190
191
192
193
194
195

196
197
198


199


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241


/*
 *----------------------------------------------------------------------
 *
 * XDestroyWindow --
 *
 *	Deallocates the given X Window.
 *
 * Results:
 *	The window id is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XDestroyWindow(
    TCL_UNUSED(Display *),		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    TkMacOSXSelDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window)macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);
            macWin->visRgn = NULL;
	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);
            macWin->aboveVisRgn = NULL;
	}
	if (macWin->drawRgn) {
	    CFRelease(macWin->drawRgn);
            macWin->drawRgn = NULL;
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree(macWin->toplevel);
	}
	ckfree(macWin);
	return Success;
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
        macWin->visRgn = NULL;
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
        macWin->aboveVisRgn = NULL;
    }
    if (macWin->drawRgn) {
	CFRelease(macWin->drawRgn);
        macWin->drawRgn = NULL;
    }
    macWin->view = nil;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree(macWin->toplevel);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	This X11 stub maps the given X11 Window but does not update any of
 *      the Tk structures describing the window.  Tk applications should
 *	never call this directly, but it is called by Tk_MapWindow and
 *      Tk_WmMapWindow.
 *
 * Results:
 *	Returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.  VisibilityNotify
 *      events are generated.
 *
 *
 *----------------------------------------------------------------------
 */

int
XMapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    if (!window) {
	return BadWindow;
    }
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    static Bool initialized = NO;


    /*
     * Under certain situations it's possible for this function to be called
     * before the toplevel window it's associated with has actually been
     * mapped. In that case we need to create the real Macintosh window now as
     * this function as well as other X functions assume that the portPtr is
     * valid.
     */

    if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
	TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
    }

    display->request++;

    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr)) {
	    TKContentView *view = [win contentView];

	    /*
	     * We want to activate Tk when a toplevel is mapped but we must not
	     * supply YES here.  This is because during Tk initialization the
	     * root window is mapped before applicationDidFinishLaunching
	     * returns. Forcing the app to activate too early can make the menu
	     * bar unresponsive.
	     */

	    TkMacOSXApplyWindowAttributes(winPtr, win);
	    [win setExcludedFromWindowsMenu:NO];
	    [NSApp activateIgnoringOtherApps:initialized];
	    [view addTkDirtyRect: [view bounds]];
	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		} else {
		    [win orderFrontRegardless];
		}



	    }
	} else {
	    TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	    /*
	     * Rebuild the container's clipping region and display
	     * the window.
	     */


	    TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
	    TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	}


	TkMacOSXInvalClipRgns((Tk_Window)winPtr);


    } else {

	/*
	 * For non-toplevel windows, rebuild the parent's clipping region
	 * and redisplay the window.
	 */

	TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
    }

    /*
     * Mark the toplevel as needing to be redrawn, unless the window is being
     * mapped while drawing is taking place.
     */

    TKContentView *view = [win contentView];
    if (view != [NSView focusView]) {
	[view addTkDirtyRect:[view bounds]];
    }

    /*
     * Generate VisibilityNotify events for window and all mapped children.
     */

    if (initialized) {
	XEvent event;
	event.xany.send_event = False;
	event.xany.display = display;
	event.xvisibility.type = VisibilityNotify;
	event.xvisibility.state = VisibilityUnobscured;
	NotifyVisibility(winPtr, &event);
    } else {
	initialized = YES;
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * NotifyVisibility --
 *







|










|

|


|













|



<



<



<



|

|
|



<



<



<









|

<







|
|
<
<


|


|
<
<




|




<
<
<
|
<
<
<
>














>
|
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
|
>
>
>
|
<
|

|
<
|
|

>
|
|
|
>
>
|
>
>

<

<
|


|
<
|
<
<
<
<
<
<
<
<






<
<
|
|
|
|
|
<
<
<
<







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77

78
79
80

81
82
83
84
85
86
87
88
89
90

91
92
93

94
95
96

97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116


117
118
119
120
121
122


123
124
125
126
127
128
129
130
131



132



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151










152


153
154


155
156
157
158
159

160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175

176

177
178
179
180

181








182
183
184
185
186
187


188
189
190
191
192




193
194
195
196
197
198
199


/*
 *----------------------------------------------------------------------
 *
 * XDestroyWindow --
 *
 *	Dealocates the given X Window.
 *
 * Results:
 *	The window id is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XDestroyWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    TkMacOSXSelDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);

	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);

	}
	if (macWin->drawRgn) {
	    CFRelease(macWin->drawRgn);

	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
	ckfree((char *) macWin);
	return;
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);

    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);

    }
    if (macWin->drawRgn) {
	CFRelease(macWin->drawRgn);

    }
    macWin->view = nil;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree((char *) macWin->toplevel);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	Map the given X Window to the screen. See X window documentation for
 *	more details.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.


 *
 *----------------------------------------------------------------------
 */

void
XMapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{



    MacDrawable *macWin = (MacDrawable *) window;



    XEvent event;

    /*
     * Under certain situations it's possible for this function to be called
     * before the toplevel window it's associated with has actually been
     * mapped. In that case we need to create the real Macintosh window now as
     * this function as well as other X functions assume that the portPtr is
     * valid.
     */

    if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
	TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
    }

    display->request++;
    macWin->winPtr->flags |= TK_MAPPED;
    if (Tk_IsTopLevel(macWin->winPtr)) {
	if (!Tk_IsEmbedded(macWin->winPtr)) {

	    NSWindow *win = TkMacOSXDrawableWindow(window);










	    [NSApp activateIgnoringOtherApps:YES];


	    if ( [win canBecomeKeyWindow] ) {
		[win makeKeyAndOrderFront:NSApp];


	    }
	    /* Why do we need this? (It is used by Carbon)*/
	    [win windowRef];
	    TkMacOSXApplyWindowAttributes(macWin->winPtr, win);
	}

	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);

	/*

	 * We only need to send the MapNotify event for toplevel windows.
	 */

	event.xany.serial = LastKnownRequestProcessed(display);
	event.xany.send_event = False;
	event.xany.display = display;

	event.xmap.window = window;
	event.xmap.type = MapNotify;
	event.xmap.event = window;
	event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {

	/*

	 * Generate damage for that area of the window.
	 */

	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);

	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);








    }

    /*
     * Generate VisibilityNotify events for window and all mapped children.
     */



    event.xany.send_event = False;
    event.xany.display = display;
    event.xvisibility.type = VisibilityNotify;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(macWin->winPtr, &event);




}

/*
 *----------------------------------------------------------------------
 *
 * NotifyVisibility --
 *
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306




307
308
309

310
311
312


313



314


315





316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
}

/*
 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	This X11 stub maps the given X11 Window but does not update any of
 *	The Tk structures describing the window.  Tk applications should
 *	never call this directly, but it is called by Tk_UnmapWindow and
 *      Tk_WmUnmapWindow.
 *
 * Results:
 *	Always returns Success or BadWindow.

 *
 * Side effects:
 *	The subwindow or toplevel may be removed from the screen.
 *
 *----------------------------------------------------------------------
 */

int
XUnmapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    TkWindow *parentPtr = winPtr->parentPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);

    if (!window) {
	return BadWindow;
    }
    display->request++;

    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr) &&
		winPtr->wmInfoPtr->hints.initial_state!=IconicState) {




	    [win orderOut:nil];
	    [win setExcludedFromWindowsMenu:YES];
	}

	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {
	/*


	 * Rebuild the visRgn clip region for the parent so it will be allowed



	 * to draw in the space from which this subwindow was removed and then


	 * redraw the window.





	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(
		    TkMacOSXGetNSViewForDrawable(parentPtr->privatePtr),
		    parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
    TKContentView *view = [win contentView];
    if (view != [NSView focusView]) {
	[view addTkDirtyRect:[view bounds]];
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XResizeWindow --
 *
 *	Resize a given X window. See X windows documentation for further
 *	details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TKWindow *w = (TKWindow *)macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    if ([w styleMask] & NSFullScreenWindowMask) {
		[w tkLayoutChanged];
	    } else {
		NSRect r = [w contentRectForFrameRect:[w frame]];

		r.origin.y += r.size.height - height;
		r.size.width = width;
		r.size.height = height;
		[w setFrame:[w frameRectForContentRect:r] display:NO];
	    }
	}
    } else {
	MoveResizeWindow(macWin);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XMoveResizeWindow --
 *
 *	Move or resize a given X window. See X windows documentation for
 *	further details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XMoveResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    /*
	     * We explicitly convert everything to doubles so we don't get
	     * surprised (again) by what happens when you do arithmetic with
	     * unsigned ints.
	     */

	    CGFloat X = (CGFloat) x;
	    CGFloat Y = (CGFloat) y;
	    CGFloat Width = (CGFloat) width;
	    CGFloat Height = (CGFloat) height;
	    CGFloat XOff = (CGFloat) macWin->winPtr->wmInfoPtr->xInParent;
	    CGFloat YOff = (CGFloat) macWin->winPtr->wmInfoPtr->yInParent;
	    NSRect r = NSMakeRect(
		    X + XOff, TkMacOSXZeroScreenHeight() - Y - YOff - Height,
	    	    Width, Height);

	    [w setFrame:[w frameRectForContentRect:r] display:NO];
	}
    } else {
	MoveResizeWindow(macWin);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XMoveWindow --
 *
 *	Move a given X window. See X windows documentation for further details.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint: NSMakePoint(
		    x, TkMacOSXZeroScreenHeight() - y)];
	}
    } else {
	MoveResizeWindow(macWin);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * MoveResizeWindow --
 *







|
|
<
<


<
>







|




|
<
<
<
|
<
<
|

>
|
|
|
>
>
>
>
|
<
|
>
|
|

>
>
|
>
>
>
|
>
>
|
>
>
>
>
>


<
|
<
<
<
|
<

<
<
<
<
<



















|






|
<


|


<
<
<
|
<
|
|
|
|
<




<







|
|










|







|




<

<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|




<







|
>










|





|




<

|
<




<







227
228
229
230
231
232
233
234
235


236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251



252


253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286



287

288





289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320



321

322
323
324
325

326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362












363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403

404
405
406
407

408
409
410
411
412
413
414
}

/*
 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	Unmap the given X Window to the screen. See X window documentation for
 *	more details.


 *
 * Results:

 *	None.
 *
 * Side effects:
 *	The subwindow or toplevel may be removed from the screen.
 *
 *----------------------------------------------------------------------
 */

void
XUnmapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;



    XEvent event;



    display->request++;
    macWin->winPtr->flags &= ~TK_MAPPED;
    if (Tk_IsTopLevel(macWin->winPtr)) {
	if (!Tk_IsEmbedded(macWin->winPtr) &&
		macWin->winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
	    NSWindow *win = TkMacOSXDrawableWindow(window);

	    if ([win isVisible]) {
		[[win parentWindow] removeChildWindow:win];
		[win orderOut:NSApp];

	    }
	}
	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);

	/*
	 * We only need to send the UnmapNotify event for toplevel windows.
	 */

	event.xany.serial = LastKnownRequestProcessed(display);
	event.xany.send_event = False;
	event.xany.display = display;

	event.xunmap.type = UnmapNotify;
	event.xunmap.window = window;
	event.xunmap.event = window;
	event.xunmap.from_configure = false;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {
	/*
	 * Generate damage for that area of the window.
	 */


	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);



	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);

    }





}

/*
 *----------------------------------------------------------------------
 *
 * XResizeWindow --
 *
 *	Resize a given X window. See X windows documentation for further
 *	details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {



	    NSRect r = [w contentRectForFrameRect:[w frame]];

	    r.origin.y += r.size.height - height;
	    r.size.width = width;
	    r.size.height = height;
	    [w setFrame:[w frameRectForContentRect:r] display:YES];

	}
    } else {
	MoveResizeWindow(macWin);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * XMoveResizeWindow --
 *
 *	Move or resize a given X window. See X windows documentation
 *	for further details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XMoveResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {












	    NSRect r = NSMakeRect(x + macWin->winPtr->wmInfoPtr->xInParent,
		    tkMacOSXZeroScreenHeight - (y +
		    macWin->winPtr->wmInfoPtr->yInParent + height),
		    width, height);
	    [w setFrame:[w frameRectForContentRect:r] display:YES];
	}
    } else {
	MoveResizeWindow(macWin);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * XMoveWindow --
 *
 *	Move a given X window. See X windows documentation for further
 *	details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint:NSMakePoint(x, tkMacOSXZeroScreenHeight - y)];

	}
    } else {
	MoveResizeWindow(macWin);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * MoveResizeWindow --
 *
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

static void
MoveResizeWindow(
    MacDrawable *macWin)
{
    int deltaX = 0, deltaY = 0, parentBorderwidth = 0;
    MacDrawable *macParent = NULL;
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable((Drawable)macWin);

    /*
     * Find the Parent window, for an embedded window it will be its container.
     */

    if (Tk_IsEmbedded(macWin->winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);







|







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

static void
MoveResizeWindow(
    MacDrawable *macWin)
{
    int deltaX = 0, deltaY = 0, parentBorderwidth = 0;
    MacDrawable *macParent = NULL;
    NSWindow *macWindow = TkMacOSXDrawableWindow((Drawable) macWin);

    /*
     * Find the Parent window, for an embedded window it will be its container.
     */

    if (Tk_IsEmbedded(macWin->winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
		macWin->winPtr->changes.x - macWin->xOff;
	deltaY = macParent->yOff + parentBorderwidth +
		macWin->winPtr->changes.y - macWin->yOff;
    }
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macParent) {
	    TkMacOSXInvalClipRgns((Tk_Window)macParent->winPtr);
	}
    }
    UpdateOffsets(macWin->winPtr, deltaX, deltaY);
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
    }
    GenerateConfigureNotify(macWin->winPtr, 0);







|







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
		macWin->winPtr->changes.x - macWin->xOff;
	deltaY = macParent->yOff + parentBorderwidth +
		macWin->winPtr->changes.y - macWin->yOff;
    }
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macParent) {
	    TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
	}
    }
    UpdateOffsets(macWin->winPtr, deltaX, deltaY);
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
    }
    GenerateConfigureNotify(macWin->winPtr, 0);
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
 *
 * Side effects:
 *	Changes the stacking order of the specified window.
 *
 *----------------------------------------------------------------------
 */

int
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XLowerWindow --
 *
 *	Change the stacking order of a window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the stacking order of the specified window.
 *
 *----------------------------------------------------------------------
 */

int
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
    return Success;
}


/*
 *----------------------------------------------------------------------
 *
 * XConfigureWindow --
 *
 *	Change the size, position, stacking, or border of the specified window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the attributes of the specified window. Note that we ignore the
 *	passed in values and use the values stored in the TkWindow data
 *	structure.
 *
 *----------------------------------------------------------------------
 */

int
XConfigureWindow(
    Display *display,		/* Display. */
    Window w,			/* Window. */
    unsigned int value_mask,
    TCL_UNUSED(XWindowChanges *))
{
    MacDrawable *macWin = (MacDrawable *)w;
    TkWindow *winPtr = macWin->winPtr;

    display->request++;

    /*
     * Change the shape and/or position of the window.
     */







|




|









<


>
















|




|









<

>



















|




|

|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
 *
 * Side effects:
 *	Changes the stacking order of the specified window.
 *
 *----------------------------------------------------------------------
 */

void
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }

}

#if 0
/*
 *----------------------------------------------------------------------
 *
 * XLowerWindow --
 *
 *	Change the stacking order of a window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the stacking order of the specified window.
 *
 *----------------------------------------------------------------------
 */

void
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }

}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XConfigureWindow --
 *
 *	Change the size, position, stacking, or border of the specified window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the attributes of the specified window. Note that we ignore the
 *	passed in values and use the values stored in the TkWindow data
 *	structure.
 *
 *----------------------------------------------------------------------
 */

void
XConfigureWindow(
    Display *display,		/* Display. */
    Window w,			/* Window. */
    unsigned int value_mask,
    XWindowChanges *values)
{
    MacDrawable *macWin = (MacDrawable *) w;
    TkWindow *winPtr = macWin->winPtr;

    display->request++;

    /*
     * Change the shape and/or position of the window.
     */
689
690
691
692
693
694
695
696


697
698
699
700




701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
     * Change the stacking order of the window. Tk actually keeps all the
     * information we need for stacking order. All we need to do is make sure
     * the clipping regions get updated and generate damage that will ensure
     * things get drawn correctly.
     */

    if (value_mask & CWStackMode) {
	NSView *view = TkMacOSXGetNSViewForDrawable(macWin);



	if (view) {
	    TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
	    TkpRedrawWidget((Tk_Window)winPtr);




	}
    }

#if 0
    TkGenWMMoveRequestEvent(macWin->winPtr,
	    macWin->winPtr->changes.x, macWin->winPtr->changes.y);
#endif
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetDrawingEnabled --
 *







|
>
>


|
|
>
>
>
>



<
|
|
<
<







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646


647
648
649
650
651
652
653
     * Change the stacking order of the window. Tk actually keeps all the
     * information we need for stacking order. All we need to do is make sure
     * the clipping regions get updated and generate damage that will ensure
     * things get drawn correctly.
     */

    if (value_mask & CWStackMode) {
	NSView *view = TkMacOSXDrawableView(macWin);
	Rect bounds;
	NSRect r;

	if (view) {
	    TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr);
	    TkMacOSXWinBounds(winPtr, &bounds);
	    r = NSMakeRect(bounds.left,
		[view bounds].size.height - bounds.bottom,
		bounds.right - bounds.left, bounds.bottom - bounds.top);
	    [view setNeedsDisplayInRect:r];
	}
    }


    /* TkGenWMMoveRequestEvent(macWin->winPtr,
	    macWin->winPtr->changes.x, macWin->winPtr->changes.y); */


}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetDrawingEnabled --
 *
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
 *	The clipping regions for the window and its children are cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetDrawingEnabled(
    TkWindow *winPtr,
    int flag)
{
    TkWindow *childPtr;
    MacDrawable *macWin = winPtr->privatePtr;

    if (macWin) {
	if (flag) {
	    macWin->flags &= ~TK_DO_NOT_DRAW;
	} else {
	    macWin->flags |= TK_DO_NOT_DRAW;
	}
    }

    /*
     * Set the flag for all children & their descendants, excluding Toplevels.
     * (??? Do we need to exclude Toplevels?)
     */

    childPtr = winPtr->childList;
    while (childPtr) {
	if (!Tk_IsTopLevel(childPtr)) {
	    TkMacOSXSetDrawingEnabled(childPtr, flag);
	}







|
|





|







|
|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
 *	The clipping regions for the window and its children are cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetDrawingEnabled(
	TkWindow *winPtr,
	int flag)
{
    TkWindow *childPtr;
    MacDrawable *macWin = winPtr->privatePtr;

    if (macWin) {
	if (flag ) {
	    macWin->flags &= ~TK_DO_NOT_DRAW;
	} else {
	    macWin->flags |= TK_DO_NOT_DRAW;
	}
    }

    /*
     * Set the flag for all children & their descendants, excluding
     * Toplevels. (??? Do we need to exclude Toplevels?)
     */

    childPtr = winPtr->childList;
    while (childPtr) {
	if (!Tk_IsTopLevel(childPtr)) {
	    TkMacOSXSetDrawingEnabled(childPtr, flag);
	}
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847









848
849
850
851
852
853
854
	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);

	    /*
	     * Clip away the area of any windows that may obscure this window.
	     * For a non-toplevel window, first, clip to the parent's visible
	     * clip region. Second, clip away any siblings that are higher in
	     * the stacking order. For an embedded toplevel, just clip to the
	     * container's visible clip region. Remember, we only allow one
	     * contained window in a frame, and don't support any other widgets
	     * in the frame either. This is not currently enforced, however.
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
		if (winPtr->parentPtr) {
		    TkMacOSXUpdateClipRgn(winPtr->parentPtr);
		    ChkErr(HIShapeIntersect,
			    winPtr->parentPtr->privatePtr->aboveVisRgn,
			    rgn, rgn);
		}
		win2Ptr = winPtr;
		while ((win2Ptr = win2Ptr->nextPtr)) {
		    if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
			continue;
		    }
		    TkMacOSXWinCGBounds(win2Ptr, &bounds);
		    ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		}
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		    ChkErr(HIShapeIntersect,
			    win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);









		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */
	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);







|








|
|


















>
>
>
>
>
>
>
>
>







750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);

	    /*
	     * Clip away the area of any windows that may obscure this window.
	     * For a non-toplevel window, first, clip to the parents visible
	     * clip region. Second, clip away any siblings that are higher in
	     * the stacking order. For an embedded toplevel, just clip to the
	     * container's visible clip region. Remember, we only allow one
	     * contained window in a frame, and don't support any other widgets
	     * in the frame either. This is not currently enforced, however.
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
		TkMacOSXUpdateClipRgn(winPtr->parentPtr);
		if (winPtr->parentPtr) {
		    ChkErr(HIShapeIntersect,
			    winPtr->parentPtr->privatePtr->aboveVisRgn,
			    rgn, rgn);
		}
		win2Ptr = winPtr;
		while ((win2Ptr = win2Ptr->nextPtr)) {
		    if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
			continue;
		    }
		    TkMacOSXWinCGBounds(win2Ptr, &bounds);
		    ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		}
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		    ChkErr(HIShapeIntersect,
			    win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);
		} else if (tkMacOSXEmbedHandler != NULL) {
		    TkRegion r = TkCreateRegion();
		    HIShapeRef visRgn;

		    tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr, r);
		    visRgn = TkMacOSXGetNativeRegion(r);
		    ChkErr(HIShapeIntersect, visRgn, rgn, rgn);
		    CFRelease(visRgn);
		    TkpReleaseRegion(r);
		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */
	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
995
996

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXVisableClipRgn --
 *
 *	This function returns the Macintosh clipping region for the given
 *	window. The caller is responsible for disposing of the returned region
 *	via XDestroyRegion().
 *
 * Results:
 *	The region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
TkMacOSXVisableClipRgn(
    TkWindow *winPtr)
{
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(winPtr);
    }
    return (Region) HIShapeCreateMutableCopy(winPtr->privatePtr->visRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalidateViewRegion --
 *
 *	This function invalidates the given region of a view.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Damage is created.
 *
 *----------------------------------------------------------------------
 */

static OSStatus
InvalViewRect(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    static CGAffineTransform t;
    TKContentView *view = ref;
    NSRect dirtyRect;

    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:
	t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0,
		NSHeight([view bounds]));
	break;
    case kHIShapeEnumerateRect:

	dirtyRect = NSRectFromCGRect(CGRectApplyAffineTransform(*rect, t));
	[view addTkDirtyRect:dirtyRect];
	break;
    }
    return noErr;
}

void
TkMacOSXInvalidateViewRegion(







|
|










|






|



















|
<
<
<
<
<

|
<










>
|
<







870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916





917
918

919
920
921
922
923
924
925
926
927
928
929
930

931
932
933
934
935
936
937

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXVisableClipRgn --
 *
 *	This function returns the Macintosh clipping region for the given
 *	window. The caller is responsible for disposing of the returned
 *	region via TkDestroyRegion().
 *
 * Results:
 *	The region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkRegion
TkMacOSXVisableClipRgn(
    TkWindow *winPtr)
{
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(winPtr);
    }
    return (TkRegion)HIShapeCreateMutableCopy(winPtr->privatePtr->visRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalidateViewRegion --
 *
 *	This function invalidates the given region of a view.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Damage is created.
 *
 *----------------------------------------------------------------------
 */

static OSStatus
InvalViewRect(int msg, HIShapeRef rgn, const CGRect *rect, void *ref) {





    static CGAffineTransform t;
    NSView *view = ref;


    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:
	t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0,
		NSHeight([view bounds]));
	break;
    case kHIShapeEnumerateRect:
	[view setNeedsDisplayInRect:NSRectFromCGRect(
		CGRectApplyAffineTransform(*rect, t))];

	break;
    }
    return noErr;
}

void
TkMacOSXInvalidateViewRegion(
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073


1074
































































1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122

1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
{
#ifdef TK_MAC_DEBUG_CLIP_REGIONS
    TkMacOSXDbgMsg("%s", macWin->winPtr->pathName);
#endif
    if (macWin->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macWin->winPtr);
    }
    TkMacOSXInvalidateViewRegion(TkMacOSXGetNSViewForDrawable(macWin),
	    (flag == TK_WINDOW_ONLY) ? macWin->visRgn : macWin->aboveVisRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSWindowForDrawable --
 *
 *	This function returns the NSWindow for a given X drawable, if the
 *      drawable is a window.  If the drawable is a pixmap it returns nil.
 *
 * Results:
 *	A NSWindow, or nil for off screen pixmaps.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
Tk_MacOSXGetNSWindowForDrawable(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *)drawable;
    NSWindow *result = nil;

    if (!macWin || macWin->flags & TK_IS_PIXMAP) {
	result = nil;
    } else if (macWin->toplevel && macWin->toplevel->winPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr->window) {
	result = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	    macWin->winPtr->wmInfoPtr->window) {
	result = macWin->winPtr->wmInfoPtr->window;
    } else if (macWin->toplevel && (macWin->toplevel->flags & TK_EMBEDDED)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);



































































	if (contWinPtr) {
	    result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSViewForDrawable/TkMacOSXGetRootControl --
 *
 *	The function name TkMacOSXGetRootControl is being preserved only
 *      because it exists in a stubs table.  Nobody knows what it means to
 *      get a "RootControl".  The macro TkMacOSXGetNSViewForDrawable calls
 *      this function and should always be used rather than directly using
 *      the obscure official name of this function.
 *
 *      It returns the NSView for a given X drawable in the case that the
 *      drawable is a window.  If the drawable is a pixmap it returns nil.
 *
 * Results:
 *	A NSView* or nil.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetRootControl(
    Drawable drawable)
{
    void *result = NULL;
    MacDrawable *macWin = (MacDrawable *)drawable;

    if (!macWin) {
	result = NULL;
    } else if (!macWin->toplevel) {
	result = macWin->view;
    } else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
	result = macWin->toplevel->view;
    } else {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXGetRootControl((Drawable)contWinPtr->privatePtr);

	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalClipRgns --
 *







|






|

|
<










|
|


|













>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|








|

<
<
<
<
<
<
|
<


|











<
<
|
<
<
<
<
<
<
<
<
|
<
<
>
|
<
|







969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985

986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092






1093

1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107


1108








1109


1110
1111

1112
1113
1114
1115
1116
1117
1118
1119
{
#ifdef TK_MAC_DEBUG_CLIP_REGIONS
    TkMacOSXDbgMsg("%s", macWin->winPtr->pathName);
#endif
    if (macWin->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macWin->winPtr);
    }
    TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(macWin),
	    (flag == TK_WINDOW_ONLY) ? macWin->visRgn : macWin->aboveVisRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawableWindow --
 *
 *	This function returns the NSWindow for a given X drawable.

 *
 * Results:
 *	A NSWindow, or nil for off screen pixmaps.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSWindow*
TkMacOSXDrawableWindow(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *) drawable;
    NSWindow *result = nil;

    if (!macWin || macWin->flags & TK_IS_PIXMAP) {
	result = nil;
    } else if (macWin->toplevel && macWin->toplevel->winPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr->window) {
	result = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	    macWin->winPtr->wmInfoPtr->window) {
	result = macWin->winPtr->wmInfoPtr->window;
    } else if (macWin->toplevel && (macWin->toplevel->flags & TK_EMBEDDED)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
	if (contWinPtr) {
	    result = TkMacOSXDrawableWindow((Drawable) contWinPtr->privatePtr);
	}
    }
    return result;
}

void *
TkMacOSXDrawable(
    Drawable drawable)
{
    return TkMacOSXDrawableWindow(drawable);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetDrawablePort --
 *
 *	This function returns the Graphics Port for a given X drawable.
 *
 * Results:
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetDrawablePort(
    Drawable drawable)
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawableView --
 *
 *	This function returns the NSView for a given X drawable.
 *
 * Results:
 *	A NSView* or nil.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSView*
TkMacOSXDrawableView(
    MacDrawable *macWin)
{
    NSView *result = nil;

    if (!macWin) {
	result = nil;
    } else if (!macWin->toplevel) {
	result = macWin->view;
    } else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
	result = macWin->toplevel->view;
    } else {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
	if (contWinPtr) {
	    result = TkMacOSXDrawableView(contWinPtr->privatePtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetRootControl --
 *






 *	This function returns the NSView for a given X drawable.

 *
 * Results:
 *	A NSView* .
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetRootControl(
    Drawable drawable)
{


    /*








     * will probably need to fix this up for embedding


     */


    return TkMacOSXDrawableView((MacDrawable *) drawable);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalClipRgns --
 *
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
     * Invalidate clip regions for all children & their descendants, unless the
     * child is a toplevel.
     */

    childPtr = winPtr->childList;
    while (childPtr) {
	if (!Tk_IsTopLevel(childPtr)) {
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}
	childPtr = childPtr->nextPtr;
    }

    /*
     * Also, if the window is a container, mark its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr) {
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinBounds --
 *
 *	Given a Tk window this function determines the window's bounds in
 *	relation to the Macintosh window's coordinate system. This is also the
 *	same coordinate system as the Tk toplevel window in which this window
 *	is contained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Fills in a Rect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinBounds(
    TkWindow *winPtr,
    void *bounds)
{
    Rect *b = (Rect *) bounds;

    b->left = winPtr->privatePtr->xOff;
    b->top = winPtr->privatePtr->yOff;
    b->right = b->left + winPtr->changes.width;
    b->bottom = b->top + winPtr->changes.height;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinCGBounds --
 *
 *	Given a Tk window this function determines the window's bounds in

 *	the coordinate system of the Tk toplevel window in which this window
 *	is contained.  This fills in a CGRect struct.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Fill in a CGRect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinCGBounds(
    TkWindow *winPtr,
    CGRect *bounds)
{
    bounds->origin.x = winPtr->privatePtr->xOff;
    bounds->origin.y = winPtr->privatePtr->yOff;
    bounds->size.width = winPtr->changes.width;
    bounds->size.height = winPtr->changes.height;
}
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinNSBounds --
 *
 *	Given a Tk window this function determines the window's bounds in
 *	the coordinate system of the TKContentView in which this Tk window
 *	is contained, which has the origin at the lower left corner.  This
 *      fills in an NSRect struct and requires the TKContentView as a
 *      parameter
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Fills in an NSRect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinNSBounds(
    TkWindow *winPtr,
    NSView *view,
    NSRect *bounds)
{
    bounds->size.width = winPtr->changes.width;
    bounds->size.height = winPtr->changes.height;
    bounds->origin.x = winPtr->privatePtr->xOff;
    bounds->origin.y = ([view bounds].size.height -
		       bounds->size.height -
		       winPtr->privatePtr->yOff);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateOffsets --
 *
 *	Updates the X & Y offsets of the given TkWindow from the TopLevel it is
 *	a descendant of.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The xOff & yOff fields for the Mac window datastructure is updated to
 *	the proper offset.







|












|













|








|









|
<











|
>
|
|





|














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|







1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259

































1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
     * Invalidate clip regions for all children & their descendants, unless the
     * child is a toplevel.
     */

    childPtr = winPtr->childList;
    while (childPtr) {
	if (!Tk_IsTopLevel(childPtr)) {
	    TkMacOSXInvalClipRgns((Tk_Window) childPtr);
	}
	childPtr = childPtr->nextPtr;
    }

    /*
     * Also, if the window is a container, mark its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr) {
	    TkMacOSXInvalClipRgns((Tk_Window) childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinBounds --
 *
 *	Given a Tk window this function determines the windows bounds in
 *	relation to the Macintosh window's coordinate system. This is also the
 *	same coordinate system as the Tk toplevel window in which this window
 *	is contained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinBounds(
    TkWindow *winPtr,
    void *bounds)
{
    Rect *b = (Rect *)bounds;

    b->left = winPtr->privatePtr->xOff;
    b->top = winPtr->privatePtr->yOff;
    b->right = b->left + winPtr->changes.width;
    b->bottom = b->top + winPtr->changes.height;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinCGBounds --
 *
 *	Given a Tk window this function determines the windows bounds in
 *	relation to the Macintosh window's coordinate system. This is also the
 *	same coordinate system as the Tk toplevel window in which this window
 *	is contained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinCGBounds(
    TkWindow *winPtr,
    CGRect *bounds)
{
    bounds->origin.x = winPtr->privatePtr->xOff;
    bounds->origin.y = winPtr->privatePtr->yOff;
    bounds->size.width = winPtr->changes.width;
    bounds->size.height = winPtr->changes.height;
}


































/*
 *----------------------------------------------------------------------
 *
 * UpdateOffsets --
 *
 *	Updates the X & Y offsets of the given TkWindow from the TopLevel it is
 *	a decendant of.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The xOff & yOff fields for the Mac window datastructure is updated to
 *	the proper offset.
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
 *
 *----------------------------------------------------------------------
 */

Pixmap
Tk_GetPixmap(
    Display *display,	/* Display for new pixmap (can be null). */
    TCL_UNUSED(Drawable),		/* Drawable where pixmap will be used (ignored). */
    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;

    if (display != NULL) {
	display->request++;
    }
    macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
    macPix->yOff = 0;
    macPix->visRgn = NULL;
    macPix->aboveVisRgn = NULL;
    macPix->drawRgn = NULL;
    macPix->referenceCount = 0;







|









|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
 *
 *----------------------------------------------------------------------
 */

Pixmap
Tk_GetPixmap(
    Display *display,	/* Display for new pixmap (can be null). */
    Drawable d,		/* Drawable where pixmap will be used (ignored). */
    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;

    if (display != NULL) {
	display->request++;
    }
    macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
    macPix->yOff = 0;
    macPix->visRgn = NULL;
    macPix->aboveVisRgn = NULL;
    macPix->drawRgn = NULL;
    macPix->referenceCount = 0;
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
 */

void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *)pixmap;

    display->request++;
    if (macPix->context) {
	char *data = CGBitmapContextGetData(macPix->context);

	if (data) {
	    ckfree(data);
	}
	CFRelease(macPix->context);
    }
    ckfree(macPix);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|










|










1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
 */

void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *) pixmap;

    display->request++;
    if (macPix->context) {
	char *data = CGBitmapContextGetData(macPix->context);

	if (data) {
	    ckfree(data);
	}
	CFRelease(macPix->context);
    }
    ckfree((char *) macPix);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXTest.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXWm.h"


/*
 * Forward declarations of procedures defined later in this file:
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int		DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
#endif
static int		PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);
static int		InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);
static int		MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);


/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --







<








|


|
<
<
<
<







9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27




28
29
30
31
32
33
34
 * Copyright (c) 2005-2009 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.
 */

#include "tkMacOSXPrivate.h"

#include "tkMacOSXWm.h"


/*
 * Forward declarations of procedures defined later in this file:
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int		DebuggerObjCmd(ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
#endif
static int		MenuBarHeightObjCmd(ClientData dummy, Tcl_Interp *interp,




					int objc, Tcl_Obj *const *objv);


/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    /*
     * Add commands for platform specific tests on MacOS here.
     */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
    Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif
    Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<
<







52
53
54
55
56
57
58


59
60
61
62
63
64
65
    /*
     * Add commands for platform specific tests on MacOS here.
     */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
    Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif


    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MenuBarHeightObjCmd(
    TCL_UNUSED(void *),		/* Not used. */
    Tcl_Interp *interp,			/* Not used. */
    TCL_UNUSED(int),				/* Not used. */
    TCL_UNUSED(Tcl_Obj *const *))		/* Not used. */
{
    static int height = 0;
    if (height == 0) {
	height = (int) [[NSApp mainMenu] menuBarHeight];
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(height));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTestLogDisplay --
 *
 *      The test image display procedure calls this to determine whether it
 *      should write a log message recording that it has being run.
 *
 * Results:
 *      Returns true if and only if the NSView of the drawable is the
 *      current focusView, which on 10.14 and newer systems can only be the
 *      case when within [NSView drawRect].
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE Bool
TkTestLogDisplay(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *)drawable;
    NSWindow *win = nil;
    if (macWin->toplevel && macWin->toplevel->winPtr &&
	macWin->toplevel->winPtr->wmInfoPtr &&
	macWin->toplevel->winPtr->wmInfoPtr->window) {
	win = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	       macWin->winPtr->wmInfoPtr->window) {
	win = macWin->winPtr->wmInfoPtr->window;
    }
    if (win) {
	return ([win contentView] == [NSView focusView]);
    } else {
	return True;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PressButtonObjCmd --
 *
 *	This Tcl command simulates a button press at a specific screen
 *      location.  It injects NSEvents into the NSApplication event queue, as
 *      opposed to adding events to the Tcl queue as event generate would do.
 *      One application is for testing the grab command. These events have
 *      their unused context property set to 1 as a signal indicating that they
 *      should not be ignored by [NSApp tkProcessMouseEvent].
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PressButtonObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value;
    NSInteger signal = -1;
    CGPoint pt;
    NSPoint loc;
    NSEvent *motion, *press, *release;
    NSArray *screens = [NSScreen screens];
    CGFloat ScreenHeight = 0;
    enum {X=1, Y};

    if (screens && [screens count]) {
	ScreenHeight = [[screens objectAtIndex:0] frame].size.height;
    }

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "x y");
        return TCL_ERROR;
    }
    for (i = 1; i < objc; i++) {
	if (Tcl_GetIntFromObj(interp,objv[i],&value) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch (i) {
	case X:
	    x = value;
	    break;
	case Y:
	    y = value;
	    break;
	default:
	    break;
	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;

    /*
     *  We set the window number and the eventNumber to -1 as a signal to
     *  processMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:motion atStart:NO];
    press = [NSEvent mouseEventWithType:NSLeftMouseDown
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:press atStart:NO];
    release = [NSEvent mouseEventWithType:NSLeftMouseUp
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:-1.0];
    [NSApp postEvent:release atStart:NO];
    return TCL_OK;
}

static int
InjectKeyEventObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] = {
	"press", "release", "flagschanged", NULL};
    NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged};
    static const char *const argStrings[] = {
	"-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL};
    enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND,
	       KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y};
    int i, index, keysym, mods = 0, x = 0, y = 0;
    NSString *chars = nil, *unmod = nil, *upper, *lower;
    NSEvent *keyEvent;
    NSUInteger type;
    MacKeycode macKC;

    if (objc < 3) {
    wrongArgs:
        Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
            &index) != TCL_OK) {
        return TCL_ERROR;
    }
    type = types[index];
    if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			 "keysym must be an integer"));
	Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL);
	return TCL_ERROR;
    }
    macKC.uint = XKeysymToKeycode(NULL, keysym);
    for (i = 3; i < objc; i++) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], argStrings,
                sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
            return TCL_ERROR;
        }
        switch ((enum args) index) {
	case KEYEVENT_SHIFT:
	    mods |= NSShiftKeyMask;
            break;
	case KEYEVENT_CONTROL:
	    mods |= NSControlKeyMask;
            break;
	case KEYEVENT_OPTION:
	    mods |= NSAlternateKeyMask;
            break;
	case KEYEVENT_COMMAND:
	    mods |= NSCommandKeyMask;
            break;
	case KEYEVENT_FUNCTION:
	    mods |= NSFunctionKeyMask;
            break;
	case KEYEVENT_X:
	    if (++i >= objc) {
                goto wrongArgs;
            }
	    if (Tcl_GetIntFromObj(interp,objv[i], &x) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case KEYEVENT_Y:
	    if (++i >= objc) {
                goto wrongArgs;
            }
	    if (Tcl_GetIntFromObj(interp,objv[i], &y) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	}
    }
    if (type != NSFlagsChanged) {
	UniChar keychar = macKC.v.keychar;
	chars = [[NSString alloc] initWithCharacters: &keychar length:1];
	upper = [chars uppercaseString];
	lower = [chars lowercaseString];
	if (![upper isEqual: lower] && [chars isEqual: upper]) {
	    mods |= NSShiftKeyMask;
	}
	if (mods & NSShiftKeyMask) {
	    chars = upper;
	    unmod = lower;
	    macKC.v.o_s |= INDEX_SHIFT;
	} else {
	    unmod = chars;
	}
	if (macKC.v.o_s & INDEX_OPTION) {
	    mods |= NSAlternateKeyMask;
	}
    }
    keyEvent = [NSEvent keyEventWithType:type
	location:NSMakePoint(x, y)
        modifierFlags:mods
	timestamp:GetCurrentEventTime()
	windowNumber:0
	context:nil
	characters:chars
	charactersIgnoringModifiers:unmod
	isARepeat:NO
	keyCode:macKC.v.virtual];
    [NSApp postEvent:keyEvent atStart:NO];
    return TCL_OK;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

|
|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


























































































































































































































































126
127
128
129
130
131
132
133
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MenuBarHeightObjCmd(
    ClientData clientData,		/* Not used. */
    Tcl_Interp *interp,			/* Not used. */
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    static int height = 0;
    if (height == 0) {
	height = (int) [[NSApp mainMenu] menuBarHeight];
    }
    Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
    return TCL_OK;
}



























































































































































































































































/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWindowEvent.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39


40
41
42
43

44
45

46

47
48
49
50
51
52
53
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_EVENTS
#define TK_MAC_DEBUG_DRAWING
#endif
*/

/*
 * Declaration of functions used only in this file
 */

static int		GenerateUpdates(
			    CGRect *updateBounds, TkWindow *winPtr);
static int		GenerateActivateEvents(TkWindow *winPtr,
			    int activeFlag);


#pragma mark TKApplication(TKWindowEvent)



extern NSString *NSWindowDidOrderOnScreenNotification;
extern NSString *NSWindowWillOrderOnScreenNotification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS

extern NSString *NSWindowDidOrderOffScreenNotification;
#endif




@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);







|

<












|



>



>
>

|

|
>
|

>
|
>







11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"


/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_EVENTS
#define TK_MAC_DEBUG_DRAWING
#endif
*/

/*
 * Declaration of functions used only in this file
 */

static int		GenerateUpdates(HIShapeRef updateRgn,
			    CGRect *updateBounds, TkWindow *winPtr);
static int		GenerateActivateEvents(TkWindow *winPtr,
			    int activeFlag);
static void		DoWindowActivate(ClientData clientData);

#pragma mark TKApplication(TKWindowEvent)

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
extern NSString *NSWindowWillOrderOnScreenNotification;
extern NSString *NSWindowDidOrderOnScreenNotification;
extern NSString *NSWindowDidOrderOffScreenNotification;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#define NSWindowWillStartLiveResizeNotification @"NSWindowWillStartLiveResizeNotification"
#define NSWindowDidEndLiveResizeNotification  @"NSWindowDidEndLiveResizeNotification"
#endif
#endif

extern BOOL opaqueTag;

@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
65
66
67
68
69
70
71





72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197




198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
















248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286


287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478

479
480
481
482
483


484

485
486
487
488








489



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535


















































536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];





    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	WmInfo *wmPtr = winPtr->wmInfoPtr;
	NSRect bounds = [w frame];
	int x, y, width = -1, height = -1, flags = 0;

	x = bounds.origin.x;
	y = TkMacOSXZeroScreenHeight() - (bounds.origin.y + bounds.size.height);
	if (winPtr->changes.x != x || winPtr->changes.y != y) {
	    flags |= TK_LOCATION_CHANGED;
	} else {
	    x = y = -1;
	}
	if (!movedOnly && (winPtr->changes.width != bounds.size.width ||
		winPtr->changes.height !=  bounds.size.height)) {
	    width = bounds.size.width - wmPtr->xInParent;
	    height = bounds.size.height - wmPtr->yInParent;
	    flags |= TK_SIZE_CHANGED;
	}

	/*
	 * Propagate geometry changes immediately.
	 */

	flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
	TkGenWMConfigureEvent((Tk_Window)winPtr, x, y, width, height, flags);
    }


}

- (void) windowExpanded: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	Tk_MapWindow((Tk_Window)winPtr);

	/*
	 * Process all Tk events generated by Tk_MapWindow().
	 */

	while (Tcl_ServiceEvent(0)) {}
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}

	/*
	 * NSWindowDidDeminiaturizeNotification is received after
	 * NSWindowDidBecomeKeyNotification, so activate manually
	 */

	GenerateActivateEvents(winPtr, 1);
    }
}

- (NSRect)windowWillUseStandardFrame:(NSWindow *)window
                        defaultFrame:(NSRect)newFrame
{
    (void)window;

    /*
     * This method needs to be implemented in order for [NSWindow isZoomed] to
     * give the correct answer. But it suffices to always validate every
     * request.
     */

    return newFrame;
}

- (NSSize)window:(NSWindow *)window
  willUseFullScreenContentSize:(NSSize)proposedSize
{
    (void)window;

    /*
     * We don't need to change the proposed size, but we do need to implement
     * this method.  Otherwise the full screen window will be sized to the
     * screen's visibleFrame, leaving black bands at the top and bottom.
     */

    return proposedSize;
}

- (void) windowEnteredFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowExitedFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowCollapsed: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window)winPtr);




    }

    /*
     * If necessary, TkGenWMDestroyEvent() handles [close]ing the window, so
     * can always return NO from -windowShouldClose: for a Tk window.
     */

    return (winPtr ? NO : YES);
}

- (void) windowBecameVisible: (NSNotification *) notification
{
    NSWindow *window = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    if (winPtr) {
	TKContentView *view = [window contentView];

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
	if (@available(macOS 10.15, *)) {
	    [view viewDidChangeEffectiveAppearance];
	}
#endif
	[view addTkDirtyRect:[view bounds]];
	Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    }
}

- (void) windowMapped: (NSNotification *) notification
{
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}

#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowLiveResize: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    //BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification];
}

















- (void) windowUnmapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

#endif /* TK_MAC_DEBUG_NOTIFICATIONS */

- (void) _setupWindowNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]

    observe(NSWindowDidBecomeKeyNotification, windowActivation:);
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
    observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
    observe(NSWindowDidExitFullScreenNotification, windowExitedFullScreen:);
#endif

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    observe(NSWindowWillMoveNotification, windowDragStart:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);


    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end

#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

- (void) applicationActivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    [NSApp tkCheckPasteboard];

    /*
     * When the application is activated with Command-Tab it will create a
     * zombie window for every Tk window which has been withdrawn.  So iterate
     * through the list of windows and order out any withdrawn window.
     */

    for (NSWindow *win in [NSApp windows]) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
	if (!winPtr || !winPtr->wmInfoPtr) {
	    continue;
	}
	if (winPtr->wmInfoPtr->hints.initial_state == WithdrawnState) {
	    [win orderOut:nil];
	}
    }
}

- (void) applicationDeactivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif

    /*
     * To prevent zombie windows on systems with a TouchBar, set the key window
     * to nil if the current key window is not visible.  This allows a closed
     * Help or About window to be deallocated so it will not reappear as a
     * zombie when the app is reactivated.
     */

    NSWindow *keywindow = [NSApp keyWindow];
    if (keywindow && ![keywindow isVisible]) {
	[NSApp _setKeyWindow:nil];
	[NSApp _setMainWindow:nil];
    }

}

- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender
                    hasVisibleWindows:(BOOL)flag
{
    (void)sender;
    (void)flag;

    /*
     * Allowing the default response means that withdrawn windows will get
     * displayed on the screen with unresponsive title buttons.  We don't
     * really want that.  Besides, we can write our own code to handle this
     * with ::tk::mac::ReopenApplication.  So we just say NO.
     */

    return NO;
}


- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    const char *cmd = ([[notification name] isEqualToString:
	    NSApplicationDidUnhideNotification] ?
	    "::tk::mac::OnShow" : "::tk::mac::OnHide");


    if (_eventInterp && Tcl_FindCommand(_eventInterp, cmd, NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, cmd, -1, TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) displayChanged: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr) {
	TkMacOSXDisplayChanged(dispPtr->display);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkpWillDrawWidget --
 *
 *      A widget display procedure can call this to determine whether it is
 *      being run inside of the drawRect method. If not, it may be desirable
 *      for the display procedure to simply clear the REDRAW_PENDING flag
 *      and return.  The widget can be recorded in order to schedule a
 *      redraw, via and Expose event, from within drawRect.
 *
 *      This is also needed for some tests, especially of the Text widget,
 *      which record data in a global Tcl variable and assume that display
 *      procedures will be run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *      True if called from the drawRect method of a TKContentView with
 *      tkwin NULL or pointing to a widget in the current focusView.
 *
 * Side effects:
 *	Currently none.  One day the tkwin parameter may be recorded to
 *      handle redrawing the widget later.
 *
 *----------------------------------------------------------------------
 */

int
TkpWillDrawWidget(Tk_Window tkwin) {
    int result;
    if (tkwin) {
	TkWindow *winPtr = (TkWindow *)tkwin;
	TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(
	    (Drawable)winPtr->privatePtr);
	result = ([NSApp isDrawing] && view == [NSView focusView]);
#if 0
	printf("TkpWillDrawWidget: %s %d  %d \n", Tk_PathName(tkwin),
	       [NSApp isDrawing], (view == [NSView focusView]));
	if (!result) {
	    NSRect dirtyRect;
	    TkMacOSXWinNSBounds(winPtr, view, &dirtyRect);
	    printf("TkpAppCanDraw: dirtyRect for %s is %s\n",
		   Tk_PathName(tkwin),
		   NSStringFromRect(dirtyRect).UTF8String);
	    [view addTkDirtyRect:dirtyRect];
	}
#endif
    } else {
	result = [NSApp isDrawing];
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateUpdates --
 *
 *	Given an update rectangle and a Tk window, this function generates
 *	an X Expose event for the window if it meets the update region. The
 *	function will then recursively have each damaged window generate Expose
 *	events for its child windows.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateUpdates(

    CGRect *updateBounds,
    TkWindow *winPtr)
{
    TkWindow *childPtr;
    XEvent event;
    CGRect bounds, damageBounds;


    TkMacOSXWinCGBounds(winPtr, &bounds);
    if (!CGRectIntersectsRect(bounds, *updateBounds)) {
	return 0;
    }




    /*
     * Compute the bounding box of the area that the damage occurred in.
     */









    damageBounds = CGRectIntersection(bounds, *updateBounds);



    event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    event.xany.send_event = false;
    event.xany.window = Tk_WindowId(winPtr);
    event.xany.display = Tk_Display(winPtr);
    event.type = Expose;
    event.xexpose.x = damageBounds.origin.x - bounds.origin.x;
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    TKLog(@"Exposed %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) {
	    continue;
	}
	GenerateUpdates(updateBounds, childPtr);
    }

    /*
     * Generate updates for any contained windows
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL && Tk_IsMapped(childPtr)) {
	    GenerateUpdates(updateBounds, childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }

    return 1;
}



















































/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGenerateFocusEvent --
 *
 *	Given a Macintosh window activate event this function generates all
 *	the X Focus events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXGenerateFocusEvent(
    TkWindow *winPtr,		/* Root X window for event. */
    int activeFlag)
{
    XEvent event;

    /*







>
>
>
>
>









|
|










>
|
|
|

|
<
|
>
|













|
|
|
|
|

|
|

|
|
|
|

|
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











|











|
>
>
>
>



|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|


<








<






<
<
<
<
<
<
<
<




>
>



<









<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
<



|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









>

|



|







<
<
















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|






|






>






>





>
>
|
>

|


>
>
>
>
>
>
>
>
|
>
>
>










|


|












|









|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|




|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139


140




141





142

143





























144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181




























182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228

229
230
231
232
233
234








235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252


253
254
255
256
















257
258
259
260


261
262
263
264






265
























266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288


289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304




















































305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];

    if (movedOnly) {
	/* constraining to screen after move not needed with AppKit */
    }

    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	WmInfo *wmPtr = winPtr->wmInfoPtr;
	NSRect bounds = [w frame];
	int x, y, width = -1, height = -1, flags = 0;

	x = bounds.origin.x;
	y = tkMacOSXZeroScreenHeight - (bounds.origin.y + bounds.size.height);
	if (winPtr->changes.x != x || winPtr->changes.y != y){
	    flags |= TK_LOCATION_CHANGED;
	} else {
	    x = y = -1;
	}
	if (!movedOnly && (winPtr->changes.width != bounds.size.width ||
		winPtr->changes.height !=  bounds.size.height)) {
	    width = bounds.size.width - wmPtr->xInParent;
	    height = bounds.size.height - wmPtr->yInParent;
	    flags |= TK_SIZE_CHANGED;
	}
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	    /*
	     * Propagate geometry changes immediately.
	     */

	    flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;

	}
	TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
    }
}

- (void) windowExpanded: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	Tk_MapWindow((Tk_Window) winPtr);
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	    /*
	     * Process all Tk events generated by Tk_MapWindow().
	     */

	    while (Tcl_ServiceEvent(0)) {}
	    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}

	    /*
	     * NSWindowDidDeminiaturizeNotification is received after
	     * NSWindowDidBecomeKeyNotification, so activate manually
	     */

	    GenerateActivateEvents(winPtr, 1);


	} else {




	    Tcl_DoWhenIdle(DoWindowActivate, winPtr);





	}

    }





























}

- (void) windowCollapsed: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	Tk_UnmapWindow((Tk_Window) winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window) winPtr);
	if (_windowWithMouse == w) {
	    _windowWithMouse = nil;
	    [w release];
	}
    }

    /*
     * If necessary, TkGenWMDestroyEvent() handles [close]ing the window,
     * so can always return NO from -windowShouldClose: for a Tk window.
     */

    return (winPtr ? NO : YES);
}





























#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowLiveResize: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    //BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification];
}

- (void) windowMapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_MapWindow((Tk_Window) winPtr);
    }
}

- (void) windowBecameVisible: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowUnmapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window) winPtr);
    }
}

#endif /* TK_MAC_DEBUG_NOTIFICATIONS */

- (void) _setupWindowNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]

    observe(NSWindowDidBecomeKeyNotification, windowActivation:);
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);








#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    observe(NSWindowWillMoveNotification, windowDragStart:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end

#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

- (void) applicationActivate: (NSNotification *) notification
{


#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    [NSApp tkCheckPasteboard];
















}

- (void) applicationDeactivate: (NSNotification *) notification
{


#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    TkSuspendClipboard();






}

























- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    const char *cmd = ([[notification name] isEqualToString:
	    NSApplicationDidUnhideNotification] ?
	    "::tk::mac::OnShow" : "::tk::mac::OnHide");
    Tcl_CmdInfo dummy;

    if (_eventInterp && Tcl_GetCommandInfo(_eventInterp, cmd, &dummy)) {
	int code = Tcl_EvalEx(_eventInterp, cmd, -1, TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) displayChanged: (NSNotification *) notification
{


#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr) {
	TkMacOSXDisplayChanged(dispPtr->display);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *




















































 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	a X Expose event for the window if it is within the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	events for its child windows.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateUpdates(
    HIShapeRef updateRgn,
    CGRect *updateBounds,
    TkWindow *winPtr)
{
    TkWindow *childPtr;
    XEvent event;
    CGRect bounds, damageBounds;
    HIShapeRef boundsRgn, damageRgn;

    TkMacOSXWinCGBounds(winPtr, &bounds);
    if (!CGRectIntersectsRect(bounds, *updateBounds)) {
	return 0;
    }
    if (!HIShapeIntersectsRect(updateRgn, &bounds)) {
	return 0;
    }

    /*
     * Compute the bounding box of the area that the damage occured in.
     */

    boundsRgn = HIShapeCreateWithRect(&bounds);
    damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn);
    if (HIShapeIsEmpty(damageRgn)) {
	CFRelease(damageRgn);
	CFRelease(boundsRgn);
	return 0;
    }
    HIShapeGetBounds(damageRgn, &damageBounds);

    CFRelease(damageRgn);
    CFRelease(boundsRgn);

    event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    event.xany.send_event = false;
    event.xany.window = Tk_WindowId(winPtr);
    event.xany.display = Tk_Display(winPtr);
    event.type = Expose;
    event.xexpose.x = damageBounds.origin.x - bounds.origin.x;
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_HandleEvent(&event);

#ifdef TK_MAC_DEBUG_DRAWING
    NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) {
	    continue;
	}
	GenerateUpdates(updateRgn, updateBounds, childPtr);
    }

    /*
     * Generate updates for any contained windows
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL && Tk_IsMapped(childPtr)) {
	    GenerateUpdates(updateRgn, updateBounds, childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateActivateEvents --
 *
 *	Given a Macintosh window activate event this function generates all the
 *	X Activate events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

int
GenerateActivateEvents(
    TkWindow *winPtr,
    int activeFlag)
{
    TkGenerateActivateEvents(winPtr, activeFlag);
    TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * DoWindowActivate --
 *
 *	Idle handler that calls GenerateActivateEvents().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

void
DoWindowActivate(
    ClientData clientData)
{
    GenerateActivateEvents(clientData, 1);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGenerateFocusEvent --
 *
 *	Given a Macintosh window activate event this function generates all
 *	the X Focus events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXGenerateFocusEvent(
    TkWindow *winPtr,		/* Root X window for event. */
    int activeFlag)
{
    XEvent event;

    /*
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
    event.xfocus.mode = NotifyNormal;
    event.xfocus.detail = NotifyDetailNone;

    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateActivateEvents --
 *
 *	Given a Macintosh window activate event this function generates all the
 *	X Activate events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

int
GenerateActivateEvents(
    TkWindow *winPtr,
    int activeFlag)
{
    TkGenerateActivateEvents(winPtr, activeFlag);
    if (activeFlag || ![NSApp isActive]) {
	TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
    }
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGenWMConfigureEvent --
 *
 *	Generate a ConfigureNotify event for Tk. Depending on the value of flag
 *	the values of width/height, x/y, or both may be changed.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







502
503
504
505
506
507
508





























509
510
511
512
513
514
515
    event.xfocus.mode = NotifyNormal;
    event.xfocus.detail = NotifyDetailNone;

    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    return true;
}






























/*
 *----------------------------------------------------------------------
 *
 * TkGenWMConfigureEvent --
 *
 *	Generate a ConfigureNotify event for Tk. Depending on the value of flag
 *	the values of width/height, x/y, or both may be changed.
689
690
691
692
693
694
695

696
697
698
699
700
701
702
     */

    if (Tk_IsTopLevel(winPtr)) {
	wmPtr = winPtr->wmInfoPtr;
	if (flags & TK_LOCATION_CHANGED) {
	    wmPtr->x = x;
	    wmPtr->y = y;

	}
	if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.







>







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
     */

    if (Tk_IsTopLevel(winPtr)) {
	wmPtr = winPtr->wmInfoPtr;
	if (flags & TK_LOCATION_CHANGED) {
	    wmPtr->x = x;
	    wmPtr->y = y;
	    wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
	}
	if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
	    wmPtr->configWidth = width;
	    wmPtr->configHeight = height;
	}
    }

    /*
     * Now set up the changes structure. Under X we wait for the
     * ConfigureNotify to set these values. On the Mac we know immediately that
     * this is what we want - so we just set them. However, we need to make
     * sure the windows clipping region is marked invalid so the change is
     * visible to the subwindow.
     */

    winPtr->changes.x = x;
    winPtr->changes.y = y;







|







617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
	    wmPtr->configWidth = width;
	    wmPtr->configHeight = height;
	}
    }

    /*
     * Now set up the changes structure. Under X we wait for the
     * ConfigureNotify to set these values. On the Mac we know imediatly that
     * this is what we want - so we just set them. However, we need to make
     * sure the windows clipping region is marked invalid so the change is
     * visible to the subwindow.
     */

    winPtr->changes.x = x;
    winPtr->changes.y = y;
818
819
820
821
822
823
824

825
826
827

828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {

		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			Tk_GetAtomName((Tk_Window)winPtr, protocol)));

		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
	    Tcl_Release(protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.
     */

    if (protocol == Tk_InternAtom((Tk_Window)winPtr, "WM_DELETE_WINDOW")) {
	Tk_DestroyWindow((Tk_Window)winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXIsAppInFront --







>
|
<
|
>
|












|
|







706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(interp, "\n    (command for \"");
		Tcl_AddErrorInfo(interp,

			Tk_GetAtomName((Tk_Window) winPtr, protocol));
		Tcl_AddErrorInfo(interp, "\" window manager protocol)");
		Tcl_BackgroundError(interp);
	    }
	    Tcl_Release(interp);
	    Tcl_Release(protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.
     */

    if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
	Tk_DestroyWindow((Tk_Window) winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXIsAppInFront --
858
859
860
861
862
863
864








865


866
867
868
869
870
871
872
 *
 *----------------------------------------------------------------------
 */

int
Tk_MacOSXIsAppInFront(void)
{








    return ([NSRunningApplication currentApplication].active == true);


}

#pragma mark TKContentView

#import <ApplicationServices/ApplicationServices.h>

/*







>
>
>
>
>
>
>
>
|
>
>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
 *
 *----------------------------------------------------------------------
 */

int
Tk_MacOSXIsAppInFront(void)
{
    Boolean isFrontProcess = true;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};

    if (noErr == GetFrontProcess(&frontPsn)){
	SameProcess(&frontPsn, &ourPsn, &isFrontProcess);
    }
#else
    isFrontProcess = [NSRunningApplication currentApplication].active;
#endif
    return (isFrontProcess == true);
}

#pragma mark TKContentView

#import <ApplicationServices/ApplicationServices.h>

/*
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926


927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944

945
946
947
948
949


950
951

952

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993

994


995

996
997
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059


1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093



1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113







1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134

1135
1136



1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159




1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172


1173
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216



1217
1218


1219
1220




1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
 * Widgets it was necessary to use Apple private API calls.  In order to avoid
 * using private API calls, the NSView-based widgets have been replaced with
 * normal Tk widgets which draw themselves as native widgets by using the
 * HITheme API.
 *
 */

/*
 * Restrict event processing to Expose events.
 */

static Tk_RestrictAction
ExposeRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)
	    ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

/*
 * Restrict event processing to ConfigureNotify events.
 */

static Tk_RestrictAction
ConfigureRestrictProc(
    TCL_UNUSED(void *),

    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

@implementation TKContentView(TKWindowEvent)

- (void) addTkDirtyRect: (NSRect) rect
{
    _tkNeedsDisplay = YES;
    _tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
    [NSApp setNeedsToDraw:YES];
}

- (void) clearTkDirtyRect
{


    _tkNeedsDisplay = NO;
    _tkDirtyRect = NSZeroRect;
    [NSApp setNeedsToDraw:NO];
}

- (void) drawRect: (NSRect) rect
{
    (void)rect;

#ifdef TK_MAC_DEBUG_DRAWING
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (winPtr) {
	fprintf(stderr, "drawRect: drawing %s in %s\n",
	    Tk_PathName(winPtr), NSStringFromRect(rect).UTF8String);
    }
#endif

    /*

     * We do not allow recursive calls to drawRect, but we only log them on OSX
     * > 10.13, where they should never happen.
     */

    if ([NSApp isDrawing]) {


	if ([NSApp macOSVersion] > 101300) {
	    TKLog(@"WARNING: a recursive call to drawRect was aborted.");

	}

	return;
    }

    [NSApp setIsDrawing: YES];
    [self clearTkDirtyRect];
    [self generateExposeEvents:rect];
    [NSApp setIsDrawing:NO];

#ifdef TK_MAC_DEBUG_DRAWING
    fprintf(stderr, "drawRect: done.\n");
#endif
}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];

    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window)winPtr;

    if (![self inLiveResize] &&
	[w respondsToSelector: @selector (tkLayoutChanged)]) {
	[(TKWindow *)w tkLayoutChanged];
    }

    if (winPtr) {
	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.  Since it calls
	 * Tcl_DoOneEvent, we need to make sure we don't clobber the
	 * AutoreleasePool set up by the caller.
	 */

	[NSApp _lockAutoreleasePool];

	/*
	 * Disable Tk drawing until the window has been completely configured.

	 */




	TkMacOSXSetDrawingEnabled(winPtr, 0);

	 /*
	  * Generate and handle a ConfigureNotify event for the new size.
	  */

	TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
		TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
    	oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);

    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Now that Tk has configured all subwindows, create the clip regions.
	 */

	TkMacOSXSetDrawingEnabled(winPtr, 1);
	TkMacOSXInvalClipRgns(tkwin);
	TkMacOSXUpdateClipRgn(winPtr);

	 /*
	  * Generate and process expose events to redraw the window.  To avoid
	  * crashes, only do this if we are being called from drawRect.  See
	  * ticket [1fa8c3ed8d].
	  */

	if([NSApp isDrawing] || [self inLiveResize]) {
	    [self generateExposeEvents: [self bounds]];
	}

	/*
	 * Finally, unlock the main autoreleasePool.
	 */

	[NSApp _unlockAutoreleasePool];
    }
}

/*
 * Core method of this class: generates expose events for redrawing.  The
 * expose events are immediately removed from the Tcl event loop and processed.
 * This causes drawing procedures to be scheduled as idle events.  Then all
 * pending idle events are processed so the drawing will actually take place.
 */

- (void) generateExposeEvents: (NSRect) rect
{
    unsigned long serial;
    int updatesNeeded;
    CGRect updateBounds;

    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.  All of these events will share the same
     * serial number.
     */

    updateBounds = NSRectToCGRect(rect);
    updateBounds.origin.y = ([self bounds].size.height - updateBounds.origin.y
			     - updateBounds.size.height);


    updatesNeeded = GenerateUpdates(&updateBounds, winPtr);
    if (updatesNeeded) {

	serial = LastKnownRequestProcessed(Tk_Display(winPtr));

	/*
	 * Use the ExposeRestrictProc to process only the expose events.  This
	 * will create idle drawing tasks, which we handle before we return.
	 */

    	oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg);
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {};
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Starting with OSX 10.14, which uses Core Animation to draw windows,
	 * all drawing must be done within the drawRect method.  (The CGContext
	 * which draws to the backing CALayer is created by the NSView before
	 * calling drawRect, and destroyed when drawRect returns.  Drawing done
	 * with the current CGContext outside of the drawRect method has no


	 * effect.)
	 *
	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
	 * So to run any display procs which were scheduled by the expose
	 * events we process all idle events before returning.
	 */

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}

/*
 * In macOS 10.14 and later this method is called when a user changes between
 * light and dark mode or changes the accent color. The implementation



 * generates two virtual events.  The first is either <<LightAqua>> or
 * <<DarkAqua>>, depending on the view's current effective appearance.  The
 * second is <<AppearnceChanged>> and has a data string describing the
 * effective appearance of the view and the current accent and highlight
 * colors.
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400

static const char *const accentNames[] = {
    "Graphite",
    "Red",
    "Orange",
    "Yellow",
    "Green",
    "Blue",
    "Purple",
    "Pink"
};








- (void) viewDidChangeEffectiveAppearance
{
    Tk_Window tkwin = (Tk_Window)TkMacOSXGetTkWindow([self window]);
    if (!tkwin) {
	return;
    }
    NSAppearanceName effectiveAppearanceName = [[self effectiveAppearance] name];
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    static const char *defaultColor = NULL;

    if (effectiveAppearanceName == NSAppearanceNameAqua) {
	Tk_SendVirtualEvent(tkwin, "LightAqua", NULL);
    } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
	Tk_SendVirtualEvent(tkwin, "DarkAqua", NULL);
    }
    if ([NSApp macOSVersion] < 101500) {

	/*
	 * Mojave cannot handle the KVO shenanigans that we need for the
	 * highlight and accent color notifications.
	 */


	return;



    }
    if (!defaultColor) {
	defaultColor = [NSApp macOSVersion] < 110000 ? "Blue" : "Multicolor";
	preferences = [[NSUserDefaults standardUserDefaults] retain];

	/*
	 * AppKit calls this method when the user changes the Accent Color
	 * but not when the user changes the Highlight Color.  So we register
	 * to receive KVO notifications for Highlight Color as well.
	 */

	[preferences addObserver:self
		      forKeyPath:@"AppleHighlightColor"
			 options:NSKeyValueObservingOptionNew
			 context:NULL];
    }
    NSString *accent = [preferences stringForKey:@"AppleAccentColor"];
    NSArray *words = [[preferences stringForKey:@"AppleHighlightColor"]
			        componentsSeparatedByString: @" "];
    NSString *highlight = [words count] > 3 ? [words objectAtIndex:3] : nil;
    const char *accentName = accent ? accentNames[1 + accent.intValue] : defaultColor;
    const char *highlightName = highlight ? highlight.UTF8String: defaultColor;
    char data[256];




    snprintf(data, 256, "Appearance %s Accent %s Highlight %s",
	     effectiveAppearanceName.UTF8String, accentName,
	     highlightName);
    Tk_SendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, -1));
}

- (void)observeValueForKeyPath:(NSString *)keyPath
		      ofObject:(id)object
			change:(NSDictionary *)change

		       context:(void *)context
{
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    if (object == preferences && [keyPath isEqualToString:@"AppleHighlightColor"]) {


	if (@available(macOS 10.14, *)) {
	    [self viewDidChangeEffectiveAppearance];

	}
    }
}

#endif

/*
 * This is no-op on 10.7 and up because Apple has removed this widget, but we
 * are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window)winPtr;
    (void)sender;

    if (!winPtr){
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}




/*
 * On Catalina this is never called and drawRect clips to the rect that


 * is passed to it by AppKit.
 */





- (BOOL) wantsDefaultClipping
{
    return NO;
}

- (BOOL) acceptsFirstResponder
{
    return YES;
}

/*
 * This keyDown method does nothing, which is a huge improvement over the
 * default keyDown method which beeps every time a key is pressed.
 */

- (void) keyDown: (NSEvent *) theEvent
{
    (void)theEvent;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
}

/*
 * When the services menu is opened this is called for each Responder in
 * the Responder chain until a service provider is found.  The TKContentView
 * should be the first (and generally only) Responder in the chain.  We
 * return the TkServices object that was created in TkpInit.
 */

- (id)validRequestorForSendType:(NSString *)sendType
		     returnType:(NSString *)returnType
{
    if ([sendType isEqualToString:@"NSStringPboardType"] ||
	[sendType isEqualToString:@"NSPasteboardTypeString"]) {
	return [NSApp servicesProvider];
    }
    return [super validRequestorForSendType:sendType returnType:returnType];
}

@end

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







<
|
<
<









<
|
<
<


<
>







|

<
|
|
|
|
<
|
>
>
|
|
|
<
|
<
|
<

<
|
<
|
<
|
|
|
<
>
|
<
<
|
|
>
>
|
|
>
|
>
|


|
<
<
<

<
<
<





>
|
|
|
<
<
<
<
<
<
<





<
|
|
|

|
<


<
>

>
>

>


<
|
<
<

|

>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
>
|
|
<
|
<
|
|
<
<
<
<
<
|
|
|
>
>
|
|
|
<
|
<
<
<
<
|
<
<
<

|
<
<
<
<
<
>
>
|
<
<
<
<
|

|
<
<
|
<
<
<
>
>
>
|
<
<
<
<
<

<
|
<
<
<
<
<
<
<
<
<
<

>
>
>
>
>
>
>
|

|
<
<
|
<
<
<

<
<
<
<
<
<
|
<
<
<
<
>
|
|
>
>
>
|
|
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
>
>
>
>
<
<
<
<
|
|
<
<
<
>
|
<
<
<
>
>
|
<
>
|
|
|
<
<
<

|
|

<








|
<
<
<
<
<

















>
>
>
|
<
>
>
|
|
>
>
>
>











<
<
<
<
<


<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










783
784
785
786
787
788
789

790


791
792
793
794
795
796
797
798
799

800


801
802

803
804
805
806
807
808
809
810
811
812

813
814
815
816

817
818
819
820
821
822

823

824

825

826

827

828
829
830

831
832


833
834
835
836
837
838
839
840
841
842
843
844
845



846



847
848
849
850
851
852
853
854
855







856
857
858
859
860

861
862
863
864
865

866
867

868
869
870
871
872
873
874
875

876


877
878
879
880
881

































882





883
884
885

886

887
888





889
890
891
892
893
894
895
896

897




898



899
900





901
902
903




904
905
906


907



908
909
910
911





912

913










914
915
916
917
918
919
920
921
922
923
924


925



926






927




928
929
930
931
932
933
934
935


936





937




938


939




940
941
942
943




944
945



946
947



948
949
950

951
952
953
954



955
956
957
958

959
960
961
962
963
964
965
966
967





968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988

989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007





1008
1009


1010
1011
1012
1013
1014

















1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
 * Widgets it was necessary to use Apple private API calls.  In order to avoid
 * using private API calls, the NSView-based widgets have been replaced with
 * normal Tk widgets which draw themselves as native widgets by using the
 * HITheme API.
 *
 */


/*Restrict event processing to Expose events.*/


static Tk_RestrictAction
ExposeRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)
	    ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}


/*Restrict event processing to ConfigureNotify events.*/


static Tk_RestrictAction
ConfigureRestrictProc(

    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

@implementation TKContentView(TKWindowEvent)

- (void) drawRect: (NSRect) rect
{

    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;

    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];


#ifdef TK_MAC_DEBUG_DRAWING
    TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect));
    [[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill];
    NSRectFillListUsingOperation(rectsBeingDrawn, rectsBeingDrawnCount,
	    NSCompositeSourceOver);

#endif





    CGFloat height = [self bounds].size.height;

    HIMutableShapeRef drawShape = HIShapeCreateMutable();


    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);

	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);


    }
    if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
	[self generateExposeEvents:(HIShapeRef)drawShape];
    } else {
	[self performSelectorOnMainThread:@selector(generateExposeEvents:)
		withObject:(id)drawShape waitUntilDone:NO
		modes:[NSArray arrayWithObjects:NSRunLoopCommonModes,

			NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode,
			nil]];
    }

    CFRelease(drawShape);







}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];
    if ([self inLiveResize]) {
	NSWindow *w = [self window];
	TkWindow *winPtr = TkMacOSXGetTkWindow(w);
	Tk_Window tkwin = (Tk_Window) winPtr;







	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;


	/* This can be called from outside the Tk event loop.
	 * Since it calls Tcl_DoOneEvent, we need to make sure we
	 * don't clobber the AutoreleasePool set up by the caller.
	 */
	[NSApp setPoolProtected:YES];


	/*

	 * Try to prevent flickers and flashes.
	 */
	[w disableFlushWindow];
	NSDisableScreenUpdates();

	/* Disable Tk drawing until the window has been completely configured.*/
	TkMacOSXSetDrawingEnabled(winPtr, 0);


	 /* Generate and handle a ConfigureNotify event for the new size.*/


	TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
			      TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
    	oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);
	while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);







































	/* Now that Tk has configured all subwindows we can create the clip regions. */
	TkMacOSXSetDrawingEnabled(winPtr, 1);
	TkMacOSXInvalClipRgns(tkwin);

	TkMacOSXUpdateClipRgn(winPtr);


	 /* Finally, generate and process expose events to redraw the window. */





	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {}
	[w enableFlushWindow];
	[w flushWindowIfNeeded];
	NSEnableScreenUpdates();
	[NSApp setPoolProtected:NO];

    }




}




/*





 * As insurance against bugs that might cause layout glitches during a live
 * resize, we redraw the window one more time at the end of the resize
 * operation.




 */

- (void)viewDidEndLiveResize


{



    HIRect bounds = NSRectToCGRect([self bounds]);
    HIShapeRef shape = HIShapeCreateWithRect(&bounds);
    [super viewDidEndLiveResize];
    [self generateExposeEvents: shape];







}











/* Core method of this class: generates expose events for redrawing.
 * Whereas drawRect is intended to be called only from the Appkit event
 * loop, this can be called from Tk.  If the Tcl_ServiceMode is set to
 * TCL_SERVICE_ALL then the expose events will be immediately removed
 * from the Tcl event loop and processed.  Typically, they should be queued,
 * however.
 */
- (void) generateExposeEvents: (HIShapeRef) shape
{
    [self generateExposeEvents:shape childrenOnly:0];


}










- (void) generateExposeEvents: (HIShapeRef) shape




		 childrenOnly: (int) childrenOnly
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;

    if (!winPtr) {


		return;





    }







    /* Generate Tk Expose events. */




    HIShapeGetBounds(shape, &updateBounds);
    /* All of these events will share the same serial number. */
    serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);





    /* Process the Expose events if the service mode is TCL_SERVICE_ALL */



    if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) {
	ClientData oldArg;



    	Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc,
						     UINT2PTR(serial), &oldArg);
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}

    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);
    }
}




/*
 * This is no-op on 10.7 and up because Apple has removed this widget,
 * but we are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window) winPtr;





    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

- (BOOL) isOpaque
{
    NSWindow *w = [self window];


    if (opaqueTag) {
      return YES;
	} else {

     return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
    	    ![w isOpaque]) ? NO : YES);
    }
}

- (BOOL) wantsDefaultClipping
{
    return NO;
}

- (BOOL) acceptsFirstResponder
{
    return YES;
}






- (void) keyDown: (NSEvent *) theEvent
{


#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
}


















@end

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWm.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
 * tkMacOSXWm.c --
 *
 *	This module takes care of the interactions between a Tk-based
 *	application and the window manager. Among other things, it implements
 *	the "wm" command and passes geometry information to the window manager.

 *
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2010 Kevin Walzer/WordTech Communications LLC.
 * Copyright (c) 2017-2019 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkScrollbar.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

/*
 * Setting this to 1 prints when each window is freed, setting it to 2 adds
 * dumps of the autorelease pools, and setting it to 3 also shows each retain
 * and release.
 */

#define DEBUG_ZOMBIES 0

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_WINDOWS
#endif





|
>





<








|

<
|
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22

23





24
25
26
27
28
29
30
/*
 * tkMacOSXWm.c --
 *
 *	This module takes care of the interactions between a Tk-based
 *	application and the window manager. Among other things, it implements
 *	the "wm" command and passes geometry information to the window
 *	manager.
 *
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2010 Kevin Walzer/WordTech Communications LLC.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkScrollbar.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"

#include <Carbon/Carbon.h>






#define DEBUG_ZOMBIES 0

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_WINDOWS
#endif
56
57
58
59
60
61
62





63
64
65
66
67
68
69
	| kWindowHideOnFullScreenAttribute  | kWindowNoConstrainAttribute \
	| kWindowNoShadowAttribute	    | kWindowLiveResizeAttribute \
	| kWindowOpaqueForEventsAttribute   | kWindowIgnoreClicksAttribute \
	| kWindowDoesNotCycleAttribute	    | tkWindowDoesNotHideAttribute \
	| tkCanJoinAllSpacesAttribute	    | tkMoveToActiveSpaceAttribute \
	| tkNonactivatingPanelAttribute	    | tkHUDWindowAttribute)






static const struct {
    const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs;
    int flags; NSUInteger styleMask;
} macClassAttrs[] = {
    [kAlertWindowClass] = {
	.defaultAttrs = kWindowDoesNotCycleAttribute, },
    [kMovableAlertWindowClass] = {







>
>
>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	| kWindowHideOnFullScreenAttribute  | kWindowNoConstrainAttribute \
	| kWindowNoShadowAttribute	    | kWindowLiveResizeAttribute \
	| kWindowOpaqueForEventsAttribute   | kWindowIgnoreClicksAttribute \
	| kWindowDoesNotCycleAttribute	    | tkWindowDoesNotHideAttribute \
	| tkCanJoinAllSpacesAttribute	    | tkMoveToActiveSpaceAttribute \
	| tkNonactivatingPanelAttribute	    | tkHUDWindowAttribute)


/*Objects for use in setting background color and opacity of window.*/
NSColor *colorName = NULL;
BOOL opaqueTag = FALSE;

static const struct {
    const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs;
    int flags; NSUInteger styleMask;
} macClassAttrs[] = {
    [kAlertWindowClass] = {
	.defaultAttrs = kWindowDoesNotCycleAttribute, },
    [kMovableAlertWindowClass] = {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

















































194
195
196
197
198
199
200
/*
 * Data for [wm attributes] command:
 */

typedef enum {
    WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY,
    WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,
    WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-fullscreen", "-modified", "-notify",
    "-titlepath", "-topmost", "-transparent",
    "-type", NULL
};

/*
 * The variable below is used to enable or disable tracing in this module. If
 * tracing is enabled, then information is printed on standard output about
 * interesting interactions with the window manager.
 */

static int wmTracing = 0;

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;


















































/*
 * Forward declarations for procedures defined in this file:
 */

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);







|





|




















|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
 * Data for [wm attributes] command:
 */

typedef enum {
    WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY,
    WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,
    _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-fullscreen", "-modified", "-notify",
    "-titlepath", "-topmost", "-transparent",
    NULL
};

/*
 * The variable below is used to enable or disable tracing in this module. If
 * tracing is enabled, then information is printed on standard output about
 * interesting interactions with the window manager.
 */

static int wmTracing = 0;

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostSlaveProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;

/*
 * Hash table for Mac Window -> TkWindow mapping.
 */

static Tcl_HashTable windowTable;
static int windowHashInit = false;



#pragma mark NSWindow(TKWm)

/*
 * Conversion of coordinates between window and screen.
 */

@implementation NSWindow(TKWm)
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
@end
#else
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectFromScreen:pointrect].origin;
}
@end
#endif

#pragma mark -


/*
 * Forward declarations for procedures defined in this file:
 */

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

430
431
432

433
434
435

436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
static int		WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		WmWinTabbingId(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
			    NSWindow *macWindow, UInt64 oldAttributes,
			    int oldFlags, int create, int initial);
static void		ApplyContainerOverrideChanges(TkWindow *winPtr,
			    NSWindow *macWindow);
static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
			    int *minHeightPtr);
static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		RemapWindows(TkWindow *winPtr,
			    MacDrawable *parentWin);
static void             RemoveTransient(TkWindow *winPtr);

#pragma mark NSWindow(TKWm)

@implementation NSWindow(TKWm)

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectFromScreen:pointrect].origin;
}

#endif

@end

#pragma mark -

@implementation TKPanel: NSPanel
@synthesize tkWindow = _tkWindow;
@end

@implementation TKDrawerWindow: NSWindow
@synthesize tkWindow = _tkWindow;
@end

@implementation TKWindow: NSWindow
@synthesize mouseInResizeArea = _mouseInResizeArea;
@synthesize tkWindow = _tkWindow;
@end

#pragma mark TKWindow(TKWm)

@implementation TKWindow(TKWm)

/*
 * This method synchronizes Tk's understanding of the bounds of a contentView
 * with the window's.  It is needed because there are situations when the
 * window manager can change the layout of an NSWindow without having been
 * requested to do so by Tk.  Examples are when a window goes FullScreen or
 * shows a tab bar.  NSWindow methods which involve such layout changes should
 * be overridden or protected by methods which call this.
 */

- (void) tkLayoutChanged
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);

    if (winPtr) {
	NSRect frameRect;

	/*
	 * This avoids including the title bar for full screen windows
	 * but does include it for normal windows.
	 */

	if ([self styleMask] & NSFullScreenWindowMask) {
 	    frameRect = [NSWindow frameRectForContentRect:NSZeroRect
		    styleMask:[self styleMask]];
	} else {
	    frameRect = [self frameRectForContentRect:NSZeroRect];
	}

	WmInfo *wmPtr = winPtr->wmInfoPtr;

	wmPtr->xInParent = -frameRect.origin.x;
	wmPtr->yInParent = frameRect.origin.y + frameRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + frameRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + frameRect.size.height;
    }
}

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
- (void)toggleTabBar:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    if (!winPtr) {
	return;
    }
    [super toggleTabBar:sender];
    [self tkLayoutChanged];
}
#endif

- (NSSize)windowWillResize:(NSWindow *)sender
                    toSize:(NSSize)frameSize
{
    NSRect currentFrame = [sender frame];
    TkWindow *winPtr = TkMacOSXGetTkWindow(sender);
    if (winPtr) {
	if (winPtr->wmInfoPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	    frameSize.width = currentFrame.size.width;

	}
	if (winPtr->wmInfoPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	    frameSize.height = currentFrame.size.height;

	}
    }
    return frameSize;

}


- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);

    if (!winPtr || !winPtr->wmInfoPtr) {
	return NO;
    }
    return (winPtr->wmInfoPtr &&
	    (winPtr->wmInfoPtr->macClass == kHelpWindowClass ||
	     winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute)
	    ) ? NO : YES;
}

#if DEBUG_ZOMBIES
- (id) retain
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 2) {
	fprintf(stderr, "Retained <%s>. Count is: %lu\n",
		title, [self retainCount]);
    }
    return result;
}

- (id) autorelease
{

    id result = [super autorelease];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 2) {
	fprintf(stderr, "Autoreleased <%s>. Count is %lu\n",
		title, [self retainCount]);
    }
    return result;
}

- (oneway void) release {
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 2) {
	fprintf(stderr, "Releasing <%s>. Count is %lu\n",
		title, [self retainCount]);
    }
    [super release];
}

- (void) dealloc {
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 0) {
	fprintf(stderr, ">>>> Freeing <%s>. Count is %lu\n",
		title, [self retainCount]);
    }
    [super dealloc];
}


#endif
@end

#pragma mark -

/*







<
<
<
<



|







<

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>


<
<
|

<
<
<
|
|
<
<
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<

<
<
<
<
<
>
|
<
<
>
|
<
|
>
|
>





<
<
<
<
|
|
|










|
|
<






>





|
|
<









|
|
<









|
|
<



>







350
351
352
353
354
355
356




357
358
359
360
361
362
363
364
365
366
367

368




369



















370
371
372


373
374



375
376


377



378




















































379
380
381

382





383
384


385
386

387
388
389
390
391
392
393
394
395




396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
static int		WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);




static void		ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
			    NSWindow *macWindow, UInt64 oldAttributes,
			    int oldFlags, int create, int initial);
static void		ApplyMasterOverrideChanges(TkWindow *winPtr,
			    NSWindow *macWindow);
static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
			    int *minHeightPtr);
static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		RemapWindows(TkWindow *winPtr,
			    MacDrawable *parentWin);






#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060



















#define TK_GOT_AT_LEAST_SNOW_LEOPARD 1
#endif



#pragma mark TKWindow(TKWm)




#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
@interface NSWindow(TkWm)


- (void) setCanCycle: (BOOL) canCycleFlag;



@end




















































#endif

@interface NSDrawerWindow : NSWindow

{





    id _i1, _i2;
}


@end


@implementation TKWindow
@end

@implementation TKWindow(TKWm)

- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);





    return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass ==
	    kHelpWindowClass || winPtr->wmInfoPtr->attributes &
	    kWindowNoActivatesAttribute)) ? NO : YES;
}

#if DEBUG_ZOMBIES
- (id) retain
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){
	printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]);

    }
    return result;
}

- (id) autorelease
{
    static int xcount = 0;
    id result = [super autorelease];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){
	printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]);

    }
    return result;
}

- (oneway void) release {
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){
	printf("Releasing <%s>. Count is %lu\n", title, [self retainCount]);

    }
    [super release];
}

- (void) dealloc {
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 0){
	printf(">>>> Freeing <%s>. Count is %lu\n", title, [self retainCount]);

    }
    [super dealloc];
}


#endif
@end

#pragma mark -

/*
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
 *----------------------------------------------------------------------
 */

static void
SetWindowSizeLimits(
    TkWindow *winPtr)
{
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int minWidth, minHeight, maxWidth, maxHeight, base;

    if (!macWindow) {
	return;
    }
    GetMinSize(winPtr, &minWidth, &minHeight);







|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
 *----------------------------------------------------------------------
 */

static void
SetWindowSizeLimits(
    TkWindow *winPtr)
{
    NSWindow *macWindow = TkMacOSXDrawableWindow(winPtr->window);
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int minWidth, minHeight, maxWidth, maxHeight, base;

    if (!macWindow) {
	return;
    }
    GetMinSize(winPtr, &minWidth, &minHeight);
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    if (wmPtr->gridWin) {
	[macWindow setResizeIncrements:NSMakeSize(wmPtr->widthInc,
		wmPtr->heightInc)];
    } else if (wmPtr->sizeHintsFlags & PAspect && wmPtr->minAspect.x ==
	    wmPtr->maxAspect.x && wmPtr->minAspect.y == wmPtr->maxAspect.y) {
	NSSize aspect = NSMakeSize(wmPtr->minAspect.x, wmPtr->minAspect.y);
	CGFloat ratio = aspect.width/aspect.height;

	[macWindow setContentAspectRatio:aspect];
	if ((CGFloat)minWidth/(CGFloat)minHeight > ratio) {
	    minHeight = lround(minWidth / ratio);
	} else {
	    minWidth = lround(minHeight * ratio);
	}
	if ((CGFloat)maxWidth/(CGFloat)maxHeight > ratio) {







<







506
507
508
509
510
511
512

513
514
515
516
517
518
519
    if (wmPtr->gridWin) {
	[macWindow setResizeIncrements:NSMakeSize(wmPtr->widthInc,
		wmPtr->heightInc)];
    } else if (wmPtr->sizeHintsFlags & PAspect && wmPtr->minAspect.x ==
	    wmPtr->maxAspect.x && wmPtr->minAspect.y == wmPtr->maxAspect.y) {
	NSSize aspect = NSMakeSize(wmPtr->minAspect.x, wmPtr->minAspect.y);
	CGFloat ratio = aspect.width/aspect.height;

	[macWindow setContentAspectRatio:aspect];
	if ((CGFloat)minWidth/(CGFloat)minHeight > ratio) {
	    minHeight = lround(minWidth / ratio);
	} else {
	    minWidth = lround(minHeight * ratio);
	}
	if ((CGFloat)maxWidth/(CGFloat)maxHeight > ratio) {
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
}

/*
 *----------------------------------------------------------------------
 *
 * FrontWindowAtPoint --
 *
 *	Find frontmost toplevel window at a given screen location which has the
 *      specified mainPtr.  If the location is in the title bar, return NULL.
 *
 * Results:
 *	TkWindow*.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkWindow*
FrontWindowAtPoint(
    int x,
    int y)
{
    NSPoint p = NSMakePoint(x, TkMacOSXZeroScreenHeight() - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *winPtr = NULL;

    for (NSWindow *w in windows) {

	winPtr = TkMacOSXGetTkWindow(w);
	if (winPtr) {
	    WmInfo *wmPtr = winPtr->wmInfoPtr;
	    NSRect windowFrame = [w frame];
	    NSRect contentFrame = [w frame];

	    contentFrame.size.height = [[w contentView] frame].size.height;
	    /*
	     * For consistency with other platforms, points in the
	     * title bar are not considered to be contained in the
	     * window.
	     */

	    if ((wmPtr->hints.initial_state == NormalState ||
		    wmPtr->hints.initial_state == ZoomState)) {
		if (NSMouseInRect(p, contentFrame, NO)) {
		    return winPtr;
		} else if (NSMouseInRect(p, windowFrame, NO)) {
		    return NULL;
		}
	    }
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *







|
<












|
<

|

|


>
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
|







542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570




571






572






573



574
575
576
577
578
579
580
581
}

/*
 *----------------------------------------------------------------------
 *
 * FrontWindowAtPoint --
 *
 *	Find frontmost toplevel window at a given screen location.

 *
 * Results:
 *	TkWindow*.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkWindow*
FrontWindowAtPoint(
    int x, int y)

{
    NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *front = NULL;

    for (NSWindow *w in windows) {
	    if (w && NSMouseInRect(p, [w frame], NO)) {
		front = TkMacOSXGetTkWindow(w);




		break;






	    }






	}



    return front;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695
696
 *----------------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->titleUid = NULL;
    wmPtr->iconName = NULL;
    wmPtr->container = NULL;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
    wmPtr->hints.icon_mask = None;
    wmPtr->hints.window_group = None;
    wmPtr->leaderName = NULL;

    wmPtr->icon = NULL;
    wmPtr->iconFor = NULL;
    wmPtr->transientPtr = NULL;
    wmPtr->sizeHintsFlags = 0;
    wmPtr->minWidth = wmPtr->minHeight = 1;
    wmPtr->maxWidth = 0;
    wmPtr->maxHeight = 0;
    wmPtr->gridWin = NULL;
    wmPtr->widthInc = wmPtr->heightInc = 1;
    wmPtr->minAspect.x = wmPtr->minAspect.y = 1;







|





|









>


<







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
 *----------------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    WmInfo *wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));

    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->titleUid = NULL;
    wmPtr->iconName = NULL;
    wmPtr->master = None;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
    wmPtr->hints.icon_mask = None;
    wmPtr->hints.window_group = None;
    wmPtr->leaderName = NULL;
    wmPtr->masterWindowName = NULL;
    wmPtr->icon = NULL;
    wmPtr->iconFor = NULL;

    wmPtr->sizeHintsFlags = 0;
    wmPtr->minWidth = wmPtr->minHeight = 1;
    wmPtr->maxWidth = 0;
    wmPtr->maxHeight = 0;
    wmPtr->gridWin = NULL;
    wmPtr->widthInc = wmPtr->heightInc = 1;
    wmPtr->minAspect.x = wmPtr->minAspect.y = 1;
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
    wmPtr->cmapCount = 0;
    wmPtr->configX = 0;
    wmPtr->configY = 0;
    wmPtr->configWidth = -1;
    wmPtr->configHeight = -1;
    wmPtr->vRoot = None;
    wmPtr->protPtr = NULL;
    wmPtr->commandObj = NULL;
    wmPtr->clientMachine = NULL;
    wmPtr->flags = WM_NEVER_MAPPED;
    wmPtr->macClass = kDocumentWindowClass;
    wmPtr->attributes = macClassAttrs[kDocumentWindowClass].defaultAttrs;
    wmPtr->scrollWinPtr = NULL;
    wmPtr->menuPtr = NULL;
    wmPtr->window = nil;
    winPtr->wmInfoPtr = wmPtr;

    UpdateVRootGeometry(wmPtr);


    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window)winPtr, &wmMgrType, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHandleMapOrUnmap --
 *
 *      The mechanism used by a geometry manager to propogate the information
 *      about which of its content widgets are mapped is to call Tk_MapWindow
 *      or Tk_UnmapNotify.  Those functions generate MapNotify or UnmapNotify
 *      events and then handle them immediately.  Other platforms use
 *      Tk_HandleEvent to do this.  But that does not work correctly on macOS
 *      due to the fact that the calls to Tk_MapNotify or Tk_UnmapNotify can
 *      occur in display procedures which are being run in the drawRect method
 *      of a TKContentView. The events will be processed after drawRect
 *      returns, but they need to be processed immediately in some cases.

 *      This function operates as a macOS alternative to Tk_HandleEvent, for
 *      processing MapNotify or UnmapNotify events only.  It is called by
 *      Tk_MapWindow, Tk_UnmapWindow, TkWmMapWindow and TkWmUnmapWindow.
 *      Rather than using Tk_HandleEvent it installs a filter which restricts
 *      to the MapNotify or UnmapNotify events, it queues the event and then
 *      processes window events with the filter installed.  This allows the
 *      event to be handled immediately even from within the drawRect method.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Handles a MapNotify or UnMapNotify event.
 *
 *----------------------------------------------------------------------
 */
static Tk_RestrictAction
MapUnmapRestrictProc(
    TCL_UNUSED(void*),
    XEvent *eventPtr)
{
    return (eventPtr->type==MapNotify || eventPtr->type==UnmapNotify ?
	    TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

MODULE_SCOPE
void TkMacOSXHandleMapOrUnmap(
    Tk_Window tkwin,
    XEvent *event)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    TkWindow *winPtr = (TkWindow *) tkwin;
    const Tk_GeomMgr *geomMgrPtr = winPtr->geomMgrPtr;

    /*
     * Sadly, this approach does not work with the "text" geometry manager.
     * The mysterious unexplained crash elicited by textDisp-5.2 occurs.  So we
     * have to check for the "text" manager and revert to using Tk_HandleEvent
     * in that case.  Hopefully this can be removed when the revised text
     * widget is in place.
     */

    if (geomMgrPtr && strcmp(geomMgrPtr->name, "text") == 0) {
	Tk_HandleEvent(event);
	return;
    }
    oldProc = Tk_RestrictEvents(MapUnmapRestrictProc, NULL, &oldArg);
    Tk_QueueWindowEvent(event, TCL_QUEUE_TAIL);
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmMapWindow --
 *







|










>






|







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671




































































672
673
674
675
676
677
678
    wmPtr->cmapCount = 0;
    wmPtr->configX = 0;
    wmPtr->configY = 0;
    wmPtr->configWidth = -1;
    wmPtr->configHeight = -1;
    wmPtr->vRoot = None;
    wmPtr->protPtr = NULL;
    wmPtr->cmdArgv = NULL;
    wmPtr->clientMachine = NULL;
    wmPtr->flags = WM_NEVER_MAPPED;
    wmPtr->macClass = kDocumentWindowClass;
    wmPtr->attributes = macClassAttrs[kDocumentWindowClass].defaultAttrs;
    wmPtr->scrollWinPtr = NULL;
    wmPtr->menuPtr = NULL;
    wmPtr->window = nil;
    winPtr->wmInfoPtr = wmPtr;

    UpdateVRootGeometry(wmPtr);


    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);




































































}

/*
 *----------------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    XEvent event;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
	}

	wmPtr->flags &= ~WM_NEVER_MAPPED;

	/*
	 * Generate configure event when we first map the window.
	 */

	TkGenWMConfigureEvent((Tk_Window)winPtr, wmPtr->x, wmPtr->y, -1, -1,
		TK_LOCATION_CHANGED);

	/*
	 * This is the first time this window has ever been mapped. Store all
	 * the window-manager-related information for the window.
	 */








<
















|







696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
	}

	wmPtr->flags &= ~WM_NEVER_MAPPED;

	/*
	 * Generate configure event when we first map the window.
	 */

	TkGenWMConfigureEvent((Tk_Window) winPtr, wmPtr->x, wmPtr->y, -1, -1,
		TK_LOCATION_CHANGED);

	/*
	 * This is the first time this window has ever been mapped. Store all
	 * the window-manager-related information for the window.
	 */

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    UpdateGeometryInfo(winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Map the window and process a MapNotify event for it.
     */

    winPtr->flags |= TK_MAPPED;
    XMapWindow(winPtr->display, winPtr->window);
    event.xany.serial = LastKnownRequestProcessed(winPtr->display);
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xmap.window = winPtr->window;
    event.xmap.type = MapNotify;
    event.xmap.event = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *







|


<

|
<
<
<
<
<
<
<







760
761
762
763
764
765
766
767
768
769

770
771







772
773
774
775
776
777
778
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    UpdateGeometryInfo(winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Map the window.
     */


    XMapWindow(winPtr->display, winPtr->window);








}

/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
 */

void
TkWmUnmapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * unmapped. */
{
    XEvent event;

    event.xany.serial = LastKnownRequestProcessed(winPtr->display);
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xunmap.type = UnmapNotify;
    event.xunmap.window = winPtr->window;
    event.xunmap.event = winPtr->window;
    event.xunmap.from_configure = false;
    winPtr->flags &= ~TK_MAPPED;
    XUnmapWindow(winPtr->display, winPtr->window);
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmDeadWindow --
 *







<
<
<
<
<
<
<
<
<
<

<







789
790
791
792
793
794
795










796

797
798
799
800
801
802
803
 */

void
TkWmUnmapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * unmapped. */
{










    XUnmapWindow(winPtr->display, winPtr->window);

}

/*
 *----------------------------------------------------------------------
 *
 * TkWmDeadWindow --
 *
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006



1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017


1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071




1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
    TKWindow *deadNSWindow;

    if (wmPtr == NULL) {
	return;
    }

    /*
     *If the dead window is a transient, remove it from the container's list.
     */

    RemoveTransient(winPtr);
    Tk_ManageGeometry((Tk_Window)winPtr, NULL, NULL);
    Tk_DeleteEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);
    if (wmPtr->hints.flags & IconPixmapHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    if (wmPtr->leaderName != NULL) {
	ckfree(wmPtr->leaderName);
    }



    if (wmPtr->icon != NULL) {
	wmPtr2 = ((TkWindow *)wmPtr->icon)->wmInfoPtr;
	wmPtr2->iconFor = NULL;
    }
    if (wmPtr->iconFor != NULL) {
	wmPtr2 = ((TkWindow *)wmPtr->iconFor)->wmInfoPtr;
	wmPtr2->icon = NULL;
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr = wmPtr->protPtr;


	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->commandObj != NULL) {
	Tcl_DecrRefCount(wmPtr->commandObj);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }

    /*
     * If the dead window has a transient, remove references to it from
     * the transient.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
    	TkWindow *winPtr2 = transientPtr->winPtr;
    	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (containerPtr == winPtr) {
    	    wmPtr2 = winPtr2->wmInfoPtr;
    	    wmPtr2->container = NULL;
    	}
    }

    while (wmPtr->transientPtr != NULL) {
	Transient *transientPtr = wmPtr->transientPtr;

	wmPtr->transientPtr = transientPtr->nextPtr;
	ckfree(transientPtr);
    }

    /*
     * Unregister the NSWindow and remove all references to it from the Tk
     * data structures.  If the NSWindow is a child, disassociate it from
     * the parent.  Then close and release the NSWindow.
     */

    deadNSWindow = (TKWindow *)wmPtr->window;
    if (deadNSWindow && !Tk_IsEmbedded(winPtr)) {
	NSWindow *parent = [deadNSWindow parentWindow];
	[deadNSWindow setTkWindow:None];
        if (winPtr->window) {
            ((MacDrawable *)winPtr->window)->view = nil;
        }
	wmPtr->window = NULL;

	if (parent) {
	    [parent removeChildWindow:deadNSWindow];
	}





#if DEBUG_ZOMBIES > 1
	{
	    const char *title = [[deadNSWindow title] UTF8String];
	    if (title == nil) {
		title = "unnamed window";
	    }
	    fprintf(stderr, ">>>> Closing <%s>. Count is: %lu\n", title,
		    [deadNSWindow retainCount]);
	}
#endif

	/*
	 * When a window is closed we want to move the focus to the next
	 * highest window.  Apple's documentation says that calling the
	 * orderOut method of the key window will accomplish this.  But
	 * experiment shows that this is not the case.  So we have to reset the
	 * key window ourselves.  When the window is the last one on the screen
	 * there is no choice for a new key window.  Moreover, if the host
	 * computer has a TouchBar then the TouchBar holds a reference to the
	 * key window which prevents it from being deallocated until it stops
	 * being the key window.  On these systems the only option for
	 * preventing zombies is to set the key window to nil.
	 */


	for (NSWindow *w in [NSApp orderedWindows]) {
	    TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
	    BOOL isOnScreen;

	    if (!winPtr2 || !winPtr2->wmInfoPtr) {
		continue;
	    }
	    wmPtr2 = winPtr2->wmInfoPtr;
	    isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
			  wmPtr2->hints.initial_state != WithdrawnState);
	    if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
		[w makeKeyAndOrderFront:NSApp];
		break;
	    }
	}

	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
	    [NSApp _setMainWindow:nil];
	}
	[deadNSWindow close];
	[deadNSWindow release];
	[NSApp _resetAutoreleasePool];

#if DEBUG_ZOMBIES > 1
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif

    }

    /*
     * Deallocate the wmInfo and clear the wmInfoPtr.
     */

    ckfree(wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmSetClass --







<




<
<
<
<
<
<
|
|













>
>
>

|



|




|
>
>



|
|









<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<


<
<
<
<
|
<
|
|
|

|

>
>
>
>
|
|

|



|
<


|
<
<
<
|
<
<
<
<
<
<
<
<

>
|
|
<
|
<
<
<
<
<
<
|
|
<


<
<
<
<
<
<
<
<
<
<
<


|



|
<
<
<
<
<
<
|







814
815
816
817
818
819
820

821
822
823
824






825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869



870




871





872


873








874
875




876

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894

895
896
897



898








899
900
901
902

903






904
905

906
907











908
909
910
911
912
913
914






915
916
917
918
919
920
921
922
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;


    if (wmPtr == NULL) {
	return;
    }






     Tk_ManageGeometry((Tk_Window) winPtr, NULL, NULL);
    Tk_DeleteEventHandler((Tk_Window) winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);
    if (wmPtr->hints.flags & IconPixmapHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    if (wmPtr->leaderName != NULL) {
	ckfree(wmPtr->leaderName);
    }
    if (wmPtr->masterWindowName != NULL) {
	ckfree(wmPtr->masterWindowName);
    }
    if (wmPtr->icon != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	wmPtr2->iconFor = NULL;
    }
    if (wmPtr->iconFor != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr;
	wmPtr2->icon = NULL;
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr;

	protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }

    /*



     * Delete the Mac window and remove it from the windowTable. The window




     * could be nil if the window was never mapped. However, we don't do this





     * for embedded windows, they don't go in the window list, and they do not


     * own their portPtr's.








     */





    NSWindow *window = wmPtr->window;


    if (window && !Tk_IsEmbedded(winPtr) ) {
	NSWindow *parent = [window parentWindow];
	if (parent) {
	    [parent removeChildWindow:window];
	}
	[window close];
	TkMacOSXUnregisterMacWindow(window);
        if (winPtr->window) {
            ((MacDrawable *) winPtr->window)->view = nil;
        }
#if DEBUG_ZOMBIES > 0
	{
	    const char *title = [[window title] UTF8String];
	    if (title == nil) {
		title = "unnamed window";
	    }
	    printf(">>>> Closing <%s>. Count is: %lu\n", title, [window retainCount]);

	}
#endif
        [window release];



	wmPtr->window = NULL;









	/* Activate the highest window left on the screen. */
	NSArray *windows = [NSApp orderedWindows];
	if ( [windows count] > 0 ) {

	    NSWindow *front = [windows objectAtIndex:0];






	    if ( front && [front canBecomeKeyWindow] ) {
		[front makeKeyAndOrderFront:NSApp];

	    }
	}











	[NSApp _resetAutoreleasePool];

#if DEBUG_ZOMBIES > 0
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif
    }






    ckfree((char *)wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmSetClass --
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
 *	A window property may get updated.
 *
 *----------------------------------------------------------------------
 */

void
TkWmSetClass(
    TCL_UNUSED(TkWindow *))		/* Newly-created top-level window. */
{
    return;
}

/*
 *----------------------------------------------------------------------
 *







|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
 *	A window property may get updated.
 *
 *----------------------------------------------------------------------
 */

void
TkWmSetClass(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    return;
}

/*
 *----------------------------------------------------------------------
 *
1176
1177
1178
1179
1180
1181
1182

1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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 = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group",
	"iconbitmap", "iconify", "iconmask", "iconname",
	"iconphoto", "iconposition", "iconwindow",
	"manage", "maxsize", "minsize", "overrideredirect",







>







|







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
int
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 = (Tk_Window) clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group",
	"iconbitmap", "iconify", "iconmask", "iconname",
	"iconphoto", "iconposition", "iconwindow",
	"manage", "maxsize", "minsize", "overrideredirect",
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
	    && (length >= 3)) {
	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wmTracing != 0));
	    return TCL_OK;
	}
	return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
	!= TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr)
	    && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:







|





|





|
|













|
|
<
<







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031


1032
1033
1034
1035
1036
1037
1038
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
	&& (length >= 3)) {
	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
	    return TCL_OK;
	}
	return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
	!= TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr)
	    && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", NULL);


	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewWideIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewWideIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;







|





|









|

|
|
<
|
|














<
|
<







1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160

1161

1162
1163
1164
1165
1166
1167
1168
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
		    wmPtr->minAspect.y, wmPtr->maxAspect.x,

		    wmPtr->maxAspect.y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {

	    Tcl_SetResult(interp, "aspect number can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456

1457
1458
1459
1460
1461
1462
1463
	[macWindow setAlphaValue:dval];
	break;
    }
    case WMATT_FULLSCREEN:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != (([macWindow styleMask] & NSFullScreenWindowMask) != 0)) {
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
	    [macWindow toggleFullScreen:macWindow];

#else
	    TKLog(@"The fullscreen attribute is ignored on this system.");
#endif

	}
	break;
    case WMATT_MODIFIED:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != [macWindow isDocumentEdited]) {







|
<
|
>
|
<
<
>







1219
1220
1221
1222
1223
1224
1225
1226

1227
1228
1229


1230
1231
1232
1233
1234
1235
1236
1237
	[macWindow setAlphaValue:dval];
	break;
    }
    case WMATT_FULLSCREEN:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != ((wmPtr->flags & WM_FULLSCREEN) != 0)) {

	    if (TkMacOSXMakeFullscreen(winPtr, macWindow, boolean, interp)
		    != TCL_OK) {
		return TCL_ERROR;


	    }
	}
	break;
    case WMATT_MODIFIED:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != [macWindow isDocumentEdited]) {
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
		wmPtr->flags &= ~WM_TRANSPARENT;
		wmPtr->attributes &= ~kWindowNoShadowAttribute;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		    oldFlags, 1, 0);
	    [macWindow setBackgroundColor:boolean ? [NSColor clearColor] : nil];
	    [macWindow setOpaque:!boolean];
	    TkMacOSXInvalidateWindow((MacDrawable *)winPtr->window,
		    TK_PARENT_WINDOW);
	    }
	break;
    case WMATT_TYPE:
	TKLog(@"The type attribute is ignored on macOS.");
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	return TCL_ERROR;
    }
    return TCL_OK;
}








|



<
<
<







1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306



1307
1308
1309
1310
1311
1312
1313
		wmPtr->flags &= ~WM_TRANSPARENT;
		wmPtr->attributes &= ~kWindowNoShadowAttribute;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		    oldFlags, 1, 0);
	    [macWindow setBackgroundColor:boolean ? [NSColor clearColor] : nil];
	    [macWindow setOpaque:!boolean];
	    TkMacOSXInvalidateWindow((MacDrawable *) winPtr->window,
		    TK_PARENT_WINDOW);
	    }
	break;



    case _WMATT_LAST_ATTRIBUTE:
    default:
	return TCL_ERROR;
    }
    return TCL_OK;
}

1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	result = Tcl_NewDoubleObj([macWindow alphaValue]);
	break;
    case WMATT_FULLSCREEN:
	result = Tcl_NewBooleanObj([macWindow styleMask] & NSFullScreenWindowMask);
	break;
    case WMATT_MODIFIED:
	result = Tcl_NewWideIntObj([macWindow isDocumentEdited] != 0);
	break;
    case WMATT_NOTIFY:
	result = Tcl_NewWideIntObj(tkMacOSXWmAttrNotifyVal != 0);
	break;
    case WMATT_TITLEPATH:
	result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
		-1);
	break;
    case WMATT_TOPMOST:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TOPMOST) != 0);
	break;
    case WMATT_TRANSPARENT:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TRANSPARENT) != 0);
	break;
    case WMATT_TYPE:
	result = Tcl_NewStringObj("unsupported", -1);
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	break;
    }
    return result;
}







|


|


|






|


|
<
<
<







1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355



1356
1357
1358
1359
1360
1361
1362
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	result = Tcl_NewDoubleObj([macWindow alphaValue]);
	break;
    case WMATT_FULLSCREEN:
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_FULLSCREEN);
	break;
    case WMATT_MODIFIED:
	result = Tcl_NewBooleanObj([macWindow isDocumentEdited]);
	break;
    case WMATT_NOTIFY:
	result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal);
	break;
    case WMATT_TITLEPATH:
	result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
		-1);
	break;
    case WMATT_TOPMOST:
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST);
	break;
    case WMATT_TRANSPARENT:
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);



	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	break;
    }
    return result;
}
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;
    NSWindow *macWindow;

    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewObj();

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(NULL, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(NULL, result,
		    WmGetAttribute(winPtr, macWindow, attribute));
	}
	Tcl_SetObjResult(interp, result);
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute));
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1])
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}







|









|




|


|


|

|



|
|
|







|
|







1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;
    NSWindow *macWindow;

    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    macWindow = TkMacOSXDrawableWindow(winPtr->window);

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(interp, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(interp, result,
		    WmGetAttribute(winPtr, macWindow, attribute));
	}
	Tcl_SetObjResult(interp, result);
    } else if (objc == 4)  {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames,
		    "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute));
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames,
			"attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1])
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)ckalloc(length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|





|









<
|














|







1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470

1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {

	    Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    wmPtr->clientMachine = ckalloc(length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2;

    int i, windowObjc, gotToplevel = 0;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window)winPtr);
	resultObj = Tcl_NewObj();
	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj((Tk_Window)wmPtr->cmapList[i]));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **)ckalloc((windowObjc+1) * sizeof(TkWindow*));
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) &winPtr2) != TCL_OK) {
	    ckfree(cmapList);
	    return TCL_ERROR;
	}
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
	    Tk_MakeWindowExist((Tk_Window)winPtr2);
	}
	cmapList[i] = winPtr2;
    }
    if (!gotToplevel) {
	wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
	cmapList[windowObjc] = winPtr;
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    if (wmPtr->cmapList != NULL) {
	ckfree(wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * we don't support colormaps. If we did they would be installed here.
     */

    return TCL_OK;
}

/*







|
|
>

|






|
<


|


<
|

<



|


|



|






|












|





|







1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532

1533
1534

1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList;
    TkWindow *winPtr2;
    int i, windowObjc, gotToplevel = 0;
    Tcl_Obj **windowObjv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window) winPtr);

	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		&& (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }

	    Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
	}

	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	!= TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **) ckalloc((windowObjc+1) * sizeof(TkWindow*));
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) &winPtr2) != TCL_OK) {
	    ckfree((char *) cmapList);
	    return TCL_ERROR;
	}
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
	    Tk_MakeWindowExist((Tk_Window) winPtr2);
	}
	cmapList[i] = winPtr2;
    }
    if (!gotToplevel) {
	wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
	cmapList[windowObjc] = winPtr;
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    if (wmPtr->cmapList != NULL) {
	ckfree((char *) wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * On the Macintosh all of this is just an excercise in compatibility as
     * we don't support colormaps. If we did they would be installed here.
     */

    return TCL_OK;
}

/*
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838

1839

1840
1841
1842
1843
1844
1845
1846

1847

1848
1849
1850
1851

1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    int len;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->commandObj != NULL) {

	    Tcl_SetObjResult(interp, wmPtr->commandObj);

	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {

	if (wmPtr->commandObj != NULL) {
	    Tcl_DecrRefCount(wmPtr->commandObj);
	    wmPtr->commandObj = NULL;
	}
	return TCL_OK;
    }
    if (Tcl_ListObjLength(interp, objv[3], &len) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->commandObj != NULL) {
	Tcl_DecrRefCount(wmPtr->commandObj);
    }
    wmPtr->commandObj = Tcl_DuplicateObj(objv[3]);
    Tcl_IncrRefCount(wmPtr->commandObj);
    Tcl_InvalidateStringRep(wmPtr->commandObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmDeiconifyCmd --







|





|
>
|
>






|
>
|
>



|
>
|
|
|



|


|
|

<
|
|







1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641
1642
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int cmdArgc;
    const char **cmdArgv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
		argv3 = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);
	    Tcl_SetResult(interp, argv3, TCL_VOLATILE);
	    ckfree(argv3);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree((char *) wmPtr->cmdArgv);
	    wmPtr->cmdArgv = NULL;
	}
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }

    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = cmdArgv;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmDeiconifyCmd --
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907

1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;

    } else if (winPtr->flags & TK_EMBEDDED) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ?
	    ZoomState : NormalState);
    [win setExcludedFromWindowsMenu:NO];
    TkMacOSXApplyWindowAttributes(winPtr, win);
    [win orderFront:NSApp];
    if (wmPtr->icon) {
	Tk_UnmapWindow((Tk_Window)wmPtr->icon);
    }

    /*
     * If this window has a transient, the transient must also be deiconified if
     * it was withdrawn by the container.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	WmInfo *wmPtr2 = winPtr2->wmInfoPtr;
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (containerPtr == winPtr) {
	    if ((wmPtr2->hints.initial_state == WithdrawnState) &&
		    ((transientPtr->flags & WITHDRAWN_BY_CONTAINER) != 0)) {
		TkpWmSetState(winPtr2, NormalState);
		transientPtr->flags &= ~WITHDRAWN_BY_CONTAINER;
	    }
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --







|





|
<






<
|
|
<

>
|
|
|
<
<


<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670

1671
1672

1673
1674
1675
1676
1677


1678
1679

1680
1681



























1682
1683
1684
1685
1686
1687
1688
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		": it is an embedded window", NULL);


	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ?
	    ZoomState : NormalState);



























    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));

	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }







|





|











<
|
>



|
|







1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {

	Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		TCL_STATIC);
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026

2027
2028
2029

2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),	/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{

    Tk_Window frameWin = (Tk_Window)winPtr;

    if (Tk_IsTopLevel(frameWin)) {

	MacDrawable *macWin;

	Tk_MakeWindowExist(frameWin);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);

	macWin = (MacDrawable *)winPtr->window;

    	TkFocusJoin(winPtr);
    	Tk_UnmapWindow(frameWin);

	macWin->toplevel->referenceCount--;
	macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel;
	macWin->toplevel->referenceCount++;
	macWin->flags &= ~TK_HOST_EXISTS;

	TkWmDeadWindow(winPtr);
	RemapWindows(winPtr, (MacDrawable *)winPtr->parentPtr->window);

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);

	/*
         * Flags (above) must be cleared before calling TkMapTopFrame (below).
         */

	TkMapTopFrame(frameWin);
    } else {
    	/*
	 * Already not managed by wm - ignore it.
	 */
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

|
|
|

>
|


>





|

|
|







|

<
<
<
<
<
|


|
|



<
|
<







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786





1787
1788
1789
1790
1791
1792
1793
1794

1795

1796
1797
1798
1799
1800
1801
1802
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    register Tk_Window frameWin = (Tk_Window)winPtr;

    if (Tk_IsTopLevel(frameWin)) {

	MacDrawable *macWin;

	Tk_MakeWindowExist(frameWin);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);

	macWin = (MacDrawable *) winPtr->window;

	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);

	macWin->toplevel->referenceCount--;
	macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel;
	macWin->toplevel->referenceCount++;
	macWin->flags &= ~TK_HOST_EXISTS;

	TkWmDeadWindow(winPtr);
	RemapWindows(winPtr, (MacDrawable *) winPtr->parentPtr->window);






	winPtr->flags &=~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);

	/*
	 * Flags (above) must be cleared before calling TkMapTopFrame (below).
	 */

	TkMapTopFrame(frameWin);
    } else {

    	/* Already not managed by wm - ignore it */

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window)winPtr);
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|





|









|

|
|







1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%x", (unsigned) window);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145




2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168

2169
2170
2171
2172
2173
2174
2175
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    char xSign = '+', ySign = '+';
    int width, height, x = wmPtr->x, y= wmPtr->y;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }
    if (objc == 3) {




	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	if (win) {
	    if (wmPtr->flags & WM_NEGATIVE_X) {
		xSign = '-';
		x = wmPtr->vRootWidth - wmPtr->x
		    - (width + (wmPtr->parentWidth - winPtr->changes.width));
	    }
	    if (wmPtr->flags & WM_NEGATIVE_Y) {
		ySign = '-';
		y = wmPtr->vRootHeight - wmPtr->y
		    - (height + (wmPtr->parentHeight - winPtr->changes.height));
	    }
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d",
		width, height, xSign, x, ySign, y));

	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);







|





|
<
|
|







>
>
>
>









<
<
<
<
<
<
<
<
<
<
<
<
|
|
>







1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889












1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    char xSign, ySign;
    int width, height;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[16 + TCL_INTEGER_SPACE * 4];

	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
	ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}












	sprintf(buf, "%dx%d%c%d%c%d",
		width, height, xSign, wmPtr->x, ySign, wmPtr->y);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;
    const char *errorMsg;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewWideIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewWideIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewWideIntObj(wmPtr->heightInc);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.







|





|

<








|

|
|
<
|
|







1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931

1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943

1944
1945
1946
1947
1948
1949
1950
1951
1952
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;


    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
		    wmPtr->reqGridHeight, wmPtr->widthInc,

		    wmPtr->heightInc);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
2243
2244
2245
2246
2247
2248
2249
2250
2251

2252
2253
2254


2255
2256
2257


2258
2259
2260

2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc)!=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    errorMsg = "baseWidth can't be < 0";
	    goto error;

	} else if (reqHeight < 0) {
	    errorMsg = "baseHeight can't be < 0";
	    goto error;


	} else if (widthInc <= 0) {
	    errorMsg = "widthInc can't be <= 0";
	    goto error;


	} else if (heightInc <= 0) {
	    errorMsg = "heightInc can't be <= 0";
	    goto error;

	}
	Tk_SetGrid((Tk_Window)winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, -1));
    Tcl_SetErrorCode(interp, "TK", "WM", "GRID", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGroupCmd --
 *







|
|
>
|
|
<
>
>
|
|
<
>
>
|
|
<
>

|





<
<
<
<
<







1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980

1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992





1993
1994
1995
1996
1997
1998
1999
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc)!=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;





}

/*
 *----------------------------------------------------------------------
 *
 * WmGroupCmd --
 *
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin2);
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = (char *)ckalloc(length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|










|



<

















|







2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
	}
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin2);
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = ckalloc(length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *str;
    int len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display,wmPtr->hints.icon_pixmap),
		    -1));
	}
	return TCL_OK;
    }
    str = Tcl_GetStringFromObj(objv[3], &len);
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    if (WmSetAttribute(winPtr, TkMacOSXGetNSWindowForDrawable(winPtr->window), interp,
	    WMATT_TITLEPATH, objv[3]) == TCL_OK) {
	if (!len) {
	    if (wmPtr->hints.icon_pixmap != None) {
		Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
		wmPtr->hints.icon_pixmap = None;
	    }
	    wmPtr->hints.flags &= ~IconPixmapHint;
	}
    } else {
	pixmap = Tk_GetBitmap(interp, (Tk_Window)winPtr, Tk_GetUid(str));
	if (pixmap == None) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_pixmap = pixmap;
	wmPtr->hints.flags |= IconPixmapHint;
    }
    return TCL_OK;







|





|










|
|
<





|




|









|







2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *str;
    int len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetResult(interp, (char*)Tk_NameOfBitmap(winPtr->display,
		    wmPtr->hints.icon_pixmap), TCL_STATIC);

	}
	return TCL_OK;
    }
    str = Tcl_GetStringFromObj(objv[3], &len);
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    if (WmSetAttribute(winPtr, TkMacOSXDrawableWindow(winPtr->window), interp,
	    WMATT_TITLEPATH, objv[3]) == TCL_OK) {
	if (!len) {
	    if (wmPtr->hints.icon_pixmap != None) {
		Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
		wmPtr->hints.icon_pixmap = None;
	    }
	    wmPtr->hints.flags &= ~IconPixmapHint;
	}
    } else {
	pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, Tk_GetUid(str));
	if (pixmap == None) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_pixmap = pixmap;
	wmPtr->hints.flags |= IconPixmapHint;
    }
    return TCL_OK;
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445

2446
2447
2448
2449
2450

2451
2452
2453
2454
2455
2456

2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (Tk_Attributes((Tk_Window)winPtr)->override_redirect) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;

    } else if (wmPtr->container != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is a transient", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
	return TCL_ERROR;

    } else if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is an icon for \"%s\"",
		winPtr->pathName, Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL);
	return TCL_ERROR;

    } else if (winPtr->flags & TK_EMBEDDED) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, IconicState);
    if (wmPtr->icon) {
	Tk_MapWindow((Tk_Window)wmPtr->icon);
    }

    /*
     * If this window has a transient the transient must be withdrawn when
     * the container is iconified.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);
    	if (containerPtr == winPtr &&
		winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr2, WithdrawnState);
	    transientPtr->flags |= WITHDRAWN_BY_CONTAINER;
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconmaskCmd --







|





|




<
|
|
|
<
<
<

>
|
|
|
<

>
|
|
<
|
<

>
|
|
|
<
<


<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158



2159
2160
2161
2162
2163

2164
2165
2166
2167

2168

2169
2170
2171
2172
2173


2174
2175

2176




















2177
2178
2179
2180
2181
2182
2183
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", NULL);



	return TCL_ERROR;
    }
    if (wmPtr->master != None) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", NULL);

	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,

		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an embedded window", NULL);


	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, IconicState);




















    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconmaskCmd --
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    -1));
	}
	return TCL_OK;
    }

    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
	}
	wmPtr->hints.flags &= ~IconMaskHint;
    } else {







|







<


|
|
<



<







2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212

2213
2214
2215
2216

2217
2218
2219

2220
2221
2222
2223
2224
2225
2226
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetResult(interp, (char *) Tk_NameOfBitmap(winPtr->display,
		    wmPtr->hints.icon_mask), TCL_STATIC);

	}
	return TCL_OK;
    }

    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
	}
	wmPtr->hints.flags &= ~IconMaskHint;
    } else {
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607

2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658

2659




2660
2661
2662
2663

2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
	}
	return TCL_OK;
    }

    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->iconName = (char *)ckalloc(length + 1);
    strcpy(wmPtr->iconName, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconphotoCmd --
 *
 *	This procedure is invoked to process the "wm iconphoto" 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
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Image tk_icon;
    int width, height, isDefault = 0;
    NSImage *newIcon = NULL;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
			 "window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }

    /*
     * Parse args.
     */

    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
	isDefault = 1;
	if (objc == 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }

    /*
     * Get icon name. We only use the first icon name because macOS does not
     * support multiple images in Tk photos.
     */

    char *icon;
    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
	icon = Tcl_GetString(objv[4]);
    } else {

	icon = Tcl_GetString(objv[3]);




    }

    /*
     * Get image and convert to NSImage that can be displayed as icon.

     */

    tk_icon = Tk_GetImage(interp, tkwin, icon, NULL, NULL);
    if (tk_icon == NULL) {
    	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	      "can't use \"%s\" as iconphoto: not a photo image",
	      icon));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
	return TCL_ERROR;
    }

    Tk_SizeOfImage(tk_icon, &width, &height);
    if (width != 0 && height != 0) {
	newIcon = TkMacOSXGetNSImageFromTkImage(winPtr->display, tk_icon,
						width, height);
    }
    Tk_FreeImage(tk_icon);
    if (newIcon == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "failed to create an iconphoto with image \"%s\"", icon));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	return TCL_ERROR;
    }
    [NSApp setApplicationIconImage: newIcon];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconpositionCmd --







|





|


















|













|
>






<












|
|
<



|


<
<
<
<
<










|
|


<
|
|
<
>
|
>
>
>
>



|
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302

2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316

2317
2318
2319
2320
2321
2322





2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336

2337
2338

2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351






















2352
2353
2354
2355
2356
2357
2358
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
	}
	return TCL_OK;
    }

    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->iconName = ckalloc(length + 1);
    strcpy(wmPtr->iconName, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconphotoCmd --
 *
 *	This procedure is invoked to process the "wm iconphoto" Tcl command.
 *	See the user documentation for details on what it does. Not yet
 *	implemented for OS X.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.

 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_PhotoHandle photo;
    int i, width, height, isDefault = 0;


    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }





    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
	isDefault = 1;
	if (objc == 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }

    /*
     * Iterate over all images to retrieve their sizes, in order to allocate a
     * buffer large enough to hold all images.
     */


    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));

	if (photo == NULL) {
	    Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]),
		    "\" as iconphoto: not a photo image", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);
    }

    /*
     * TODO: This requires implementation for OS X, but we silently return for
     * now.
     */























    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconpositionCmd --
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726

2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
	    Tcl_Obj *results[2];


	    results[0] = Tcl_NewWideIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->hints.icon_y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    return TCL_OK;







|





|






<


<
>

|
|
|



<




|







2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386

2387
2388

2389
2390
2391
2392
2393
2394
2395
2396

2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {

	    char buf[TCL_INTEGER_SPACE * 2];

	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
		    wmPtr->hints.icon_y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    return TCL_OK;
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    wmPtr2 = ((TkWindow *)wmPtr->icon)->wmInfoPtr;
	    wmPtr2->iconFor = NULL;
	    wmPtr2->hints.initial_state = WithdrawnState;
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use %s as icon window: not at top level",
		    Tk_PathName(tkwin2)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "TOPLEVEL",
		    NULL);
	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *)tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is already an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    TkWindow *oldIcon = (TkWindow *)wmPtr->icon;
	    WmInfo *wmPtr3 = oldIcon->wmInfoPtr;
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(oldIcon->window);

	    /*
	     * The old icon should be withdrawn.
	     */

	    TkpWmSetState(oldIcon, WithdrawnState);
	    [win orderOut:nil];
    	    [win setExcludedFromWindowsMenu:YES];
	    wmPtr3->iconFor = NULL;
	}
	Tk_MakeWindowExist(tkwin2);
	wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= IconWindowHint;
	wmPtr->icon = tkwin2;
	wmPtr2->iconFor = (Tk_Window)winPtr;
	if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
	    /*
	     * If the window is in normal or zoomed state, the icon should be
	     * unmapped.
	     */

	    if (wmPtr->hints.initial_state == NormalState ||
		    wmPtr->hints.initial_state == ZoomState) {
		Tk_UnmapWindow(tkwin2);
	    }
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|







<


|



<



|









|
|
<
<
<


|

|
|
|
<



<
|
<
<
<
<
<
<
<
<
<






|


|
<


<
<
|
<







2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443

2444
2445
2446
2447
2448
2449

2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464



2465
2466
2467
2468
2469
2470
2471

2472
2473
2474

2475









2476
2477
2478
2479
2480
2481
2482
2483
2484
2485

2486
2487


2488

2489
2490
2491
2492
2493
2494
2495
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	    wmPtr2->iconFor = NULL;
	    wmPtr2->hints.initial_state = WithdrawnState;
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
		    " as icon window: not at top level", NULL);



	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
		    " is already an icon for ",
		    Tk_PathName(wmPtr2->iconFor), NULL);

	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {

	    WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;









	    wmPtr3->iconFor = NULL;
	}
	Tk_MakeWindowExist(tkwin2);
	wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= IconWindowHint;
	wmPtr->icon = tkwin2;
	wmPtr2->iconFor = (Tk_Window) winPtr;
	if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
	    /*
	     * Don't have iconwindows on the Mac. We just withdraw.

	     */



	    Tk_UnmapWindow(tkwin2);

	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876

2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898


2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,           /* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{

    Tk_Window frameWin = (Tk_Window)winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin = (MacDrawable *)winPtr->window;

	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a"
		    " frame, labelframe or toplevel",
		    Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    if (winPtr->window == None) {
		Tk_MakeWindowExist((Tk_Window)winPtr);
		macWin = (MacDrawable *)winPtr->window;
	    }


	}
	wmPtr = winPtr->wmInfoPtr;
	winPtr->flags &= ~TK_MAPPED;
	macWin->toplevel->referenceCount--;
	macWin->toplevel = macWin;
	macWin->toplevel->referenceCount++;
	RemapWindows(winPtr, macWin);
	winPtr->flags |=
		(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	TkMapTopFrame(frameWin);
	TkWmMapWindow(winPtr);
    } else if (Tk_IsTopLevel(frameWin)) {
	/* Already managed by wm - ignore it */
    }
    return TCL_OK;
}

/*







|


|
|

>
|
|


|


|
|
|
<
<







|
|

>
>










<







2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529


2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551

2552
2553
2554
2555
2556
2557
2558
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,           /* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    register Tk_Window frameWin = (Tk_Window)winPtr;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin = (MacDrawable *) winPtr->window;

	if (!Tk_IsManageable(frameWin)) {
	    Tcl_AppendResult(interp, "window \"",
		Tk_PathName(frameWin), "\" is not manageable: must be "
		"a frame, labelframe or toplevel", NULL);


	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    if (winPtr->window == None) {
		Tk_MakeWindowExist((Tk_Window) winPtr);
		macWin = (MacDrawable *) winPtr->window;
	    }
	    TkWmMapWindow(winPtr);
	    Tk_UnmapWindow(frameWin);
	}
	wmPtr = winPtr->wmInfoPtr;
	winPtr->flags &= ~TK_MAPPED;
	macWin->toplevel->referenceCount--;
	macWin->toplevel = macWin;
	macWin->toplevel->referenceCount++;
	RemapWindows(winPtr, macWin);
	winPtr->flags |=
		(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	TkMapTopFrame(frameWin);

    } else if (Tk_IsTopLevel(frameWin)) {
	/* Already managed by wm - ignore it */
    }
    return TCL_OK;
}

/*
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950

2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];


	GetMaxSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;







|





|






<

<
>


<
|
|


<

|







2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589

2590

2591
2592
2593

2594
2595
2596
2597

2598
2599
2600
2601
2602
2603
2604
2605
2606
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {

	char buf[TCL_INTEGER_SPACE * 2];

	GetMaxSize(winPtr, &width, &height);

	sprintf(buf, "%d %d", width, height);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	|| (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004

3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];


	GetMinSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;







|





|






<

<
>


<
|
|


<







2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640

2641

2642
2643
2644

2645
2646
2647
2648

2649
2650
2651
2652
2653
2654
2655
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {

	char buf[TCL_INTEGER_SPACE * 2];

	GetMinSize(winPtr, &width, &height);

	sprintf(buf, "%d %d", width, height);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int flag;
    XSetWindowAttributes atts;
    TKWindow *win = (TKWindow *)TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		Tk_Attributes((Tk_Window) winPtr)->override_redirect));
	return TCL_OK;
    }

    if (Tcl_GetBooleanFromObj(interp, objv[3], &flag) != TCL_OK) {
	return TCL_ERROR;
    }
    atts.override_redirect = flag ? True : False;
    Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
    ApplyContainerOverrideChanges(winPtr, win);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --







|





|

<





<





<
|


|
|
|







2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686

2687
2688
2689
2690
2691

2692
2693
2694
2695
2696

2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int boolean;
    XSetWindowAttributes atts;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		Tk_Attributes((Tk_Window) winPtr)->override_redirect));
	return TCL_OK;
    }

    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    atts.override_redirect = (boolean) ? True : False;
    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts);
    ApplyMasterOverrideChanges(winPtr, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;







|





|










<


|

|



<



|
|







2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741

2742
2743
2744
2745
2746
2747
2748
2749

2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    int cmdLength;
    Tcl_Obj *resultObj;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */

	resultObj = Tcl_NewObj();
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol),-1));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }

    protocol = Tk_InternAtom((Tk_Window)winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    if (protPtr->command)
		ckfree(protPtr->command);
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(sizeof(ProtocolHandler));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	protPtr->command = (char *)ckalloc(cmdLength+1);
	strcpy(protPtr->command, cmd);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|





|
|



<





<





<


|
|

<


<
|








|
<












|






<
<






|




<







2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802
2803
2804

2805
2806
2807
2808
2809

2810
2811
2812
2813
2814

2815
2816

2817
2818
2819
2820
2821
2822
2823
2824
2825
2826

2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845


2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    register ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    int cmdLength;


    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */


	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_AppendElement(interp,
		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	}

	return TCL_OK;
    }

    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetResult(interp, protPtr->command, TCL_STATIC);

		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }


	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;

	strcpy(protPtr->command, cmd);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276

3277
3278

3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];


	results[0] = Tcl_NewWideIntObj(

		(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) == 0);
	results[1] = Tcl_NewWideIntObj(
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) == 0);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {
	wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
	wmPtr->attributes |= kWindowHorizontalZoomAttribute;
    } else {
	wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;







|





|








<

<
>

<
>
|
<
|
|


<

|







2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895

2896

2897
2898

2899
2900

2901
2902
2903
2904

2905
2906
2907
2908
2909
2910
2911
2912
2913
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {

	char buf[TCL_INTEGER_SPACE * 2];


	sprintf(buf, "%d %d",
		(wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,

		(wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }

    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	|| (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {
	wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
	wmPtr->attributes |= kWindowHorizontalZoomAttribute;
    } else {
	wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;







|





|










<


|

|







|
|







2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973

2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427


3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460


3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490

3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508

3509
3510
3511
3512
3513
3514
3515
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW
    };
    Tcl_Obj *resultObj;
    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {


	    resultObj = Tcl_NewObj();
	    for (windowPtr = windows; *windowPtr ; windowPtr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tk_NewWindowObj((Tk_Window)*windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
    } else {
	TkWindow *winPtr2;
	int index1 = -1, index2 = -1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't a top-level window",
		    winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;


	} else if (!Tk_IsMapped(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "FAIL", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = windowPtr - windows;
	    }
	    if (*windowPtr == winPtr2) {
		index2 = windowPtr - windows;
	    }
	}
	if (index1 == -1) {
	    Tcl_Panic("winPtr window not found");

	} else if (index2 == -1) {
	    Tcl_Panic("winPtr2 window not found");
	}

	ckfree(windows);

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result != 0));
	return TCL_OK;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * WmStateCmd --
 *







|

|
<

|
<
<









|
>
>
|
|
|
<
|
<
|
|
|
<
<
<

|


|




|
|
<
<




|
|
<

>
>
|
|
|
<










<
|
<



|
|
|

|
|




>
|



|

|
|







|


>







3021
3022
3023
3024
3025
3026
3027
3028
3029
3030

3031
3032


3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047

3048

3049
3050
3051



3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062


3063
3064
3065
3066
3067
3068

3069
3070
3071
3072
3073
3074

3075
3076
3077
3078
3079
3080
3081
3082
3083
3084

3085

3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL };

    enum options {
	OPT_ISABOVE, OPT_ISBELOW };


    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows == NULL) {
	    Tcl_Panic("TkWmStackorderToplevel failed");
	}

	for (window_ptr = windows; *window_ptr ; window_ptr++) {
	    Tcl_AppendElement(interp, (*window_ptr)->pathName);

	}

	ckfree((char *) windows);
	return TCL_OK;
    } else {



	TkWindow *winPtr2;
	int index1=-1, index2=-1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
	    != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", NULL);


	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {

	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);

	    return TCL_ERROR;
	}

	for (window_ptr = windows; *window_ptr ; window_ptr++) {
	    if (*window_ptr == winPtr) {
		index1 = (window_ptr - windows);
	    }
	    if (*window_ptr == winPtr2) {
		index2 = (window_ptr - windows);
	    }
	}
	if (index1 == -1) {
	    Tcl_Panic("winPtr window not found");
	}
	if (index2 == -1) {
	    Tcl_Panic("winPtr2 window not found");
	}

	ckfree((char *) windows);

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmStateCmd --
 *
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }

    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of \"%s\": it is an icon for \"%s\"",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of \"%s\": it is an embedded window",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "EMBEDDED", NULL);
	    return TCL_ERROR;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch (index) {
	case OPT_NORMAL:
	    TkpWmSetState(winPtr, NormalState);

	    /*
	     * This varies from 'wm deiconify' because it does not force the
	     * window to be raised and receive focus
	     */

	    break;
	case OPT_ICONIC:
	    if (Tk_Attributes((Tk_Window)winPtr)->override_redirect) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->container != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);
	    break;
	case OPT_WITHDRAWN:
	    TkpWmSetState(winPtr, WithdrawnState);
	    break;
	default: /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);
	    break;
	}
    } else if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", -1));
    } else {
	if (wmPtr->hints.initial_state == NormalState ||
		wmPtr->hints.initial_state == ZoomState) {
	    wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ?
		    ZoomState : NormalState);
	}
	switch (wmPtr->hints.initial_state) {
	case NormalState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", -1));
	    break;
	case IconicState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", -1));
	    break;
	case WithdrawnState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", -1));
	    break;
	case ZoomState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", -1));
	    break;
	}
    }
    return TCL_OK;
}

/*







|





|










<


|
|
|
<



<
|
|
<



|
|



<
|






<
<
|
|
|
|
<
<
<


|
|
|
<
<
<



<
|

<
|

<


|








|


|


|


|







3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156

3157
3158
3159
3160
3161

3162
3163
3164

3165
3166

3167
3168
3169
3170
3171
3172
3173
3174

3175
3176
3177
3178
3179
3180
3181


3182
3183
3184
3185



3186
3187
3188
3189
3190



3191
3192
3193

3194
3195

3196
3197

3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }

    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]), ": it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);

	    return TCL_ERROR;
	}
	if (winPtr->flags & TK_EMBEDDED) {

	    Tcl_AppendResult(interp, "can't change state of ",
		    winPtr->pathName, ": it is an embedded window", NULL);

	    return TCL_ERROR;
	}

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
				&index) != TCL_OK) {
	    return TCL_ERROR;
	}


	if (index == OPT_NORMAL) {
	    TkpWmSetState(winPtr, NormalState);

	    /*
	     * This varies from 'wm deiconify' because it does not force the
	     * window to be raised and receive focus
	     */


	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
			"\": override-redirect flag is set", NULL);



		return TCL_ERROR;
	    }
	    if (wmPtr->master != None) {
		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
			"\": it is a transient", NULL);



		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);

	} else if (index == OPT_WITHDRAWN) {
	    TkpWmSetState(winPtr, WithdrawnState);

	} else { /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);

	}
    } else if (wmPtr->iconFor != NULL) {
	Tcl_SetResult(interp, "icon", TCL_STATIC);
    } else {
	if (wmPtr->hints.initial_state == NormalState ||
		wmPtr->hints.initial_state == ZoomState) {
	    wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ?
		    ZoomState : NormalState);
	}
	switch (wmPtr->hints.initial_state) {
	case NormalState:
	    Tcl_SetResult(interp, "normal", TCL_STATIC);
	    break;
	case IconicState:
	    Tcl_SetResult(interp, "iconic", TCL_STATIC);
	    break;
	case WithdrawnState:
	    Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
	    break;
	case ZoomState:
	    Tcl_SetResult(interp, "zoomed", TCL_STATIC);
	    break;
	}
    }
    return TCL_OK;
}

/*
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, -1));
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->titleUid = Tk_GetUid(argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	TkSetWMName(winPtr, wmPtr->titleUid);
    }
    return TCL_OK;
}







|





|







<

|
|


<







3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257

3258
3259
3260
3261
3262

3263
3264
3265
3266
3267
3268
3269
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetResult(interp, (char *)((wmPtr->titleUid != NULL) ?
		wmPtr->titleUid : winPtr->nameUid), TCL_STATIC);
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->titleUid = Tk_GetUid(argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	TkSetWMName(winPtr, wmPtr->titleUid);
    }
    return TCL_OK;
}
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707

3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757




3758
3759

3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779

3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797


3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838

3839
3840
3841
3842
3843
3844
3845

3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window container;
    TkWindow *containerPtr, *w;
    WmInfo *wmPtr2;

    Transient *transient;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->container != NULL) {
	    Tcl_SetObjResult(interp,
		Tcl_NewStringObj(Tk_PathName(wmPtr->container), -1));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	RemoveTransient(winPtr);
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = (TkWindow*) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
            /*
             * Ensure that the container window is actually a Tk toplevel.
             */

            containerPtr = containerPtr->parentPtr;
        }
	Tk_MakeWindowExist((Tk_Window)containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = containerPtr->wmInfoPtr;

	/*
	 * Under some circumstances, wmPtr2 is NULL here.
	 */

	if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}





	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;

		w = (TkWindow *)w->wmInfoPtr->container) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Add the transient to the container's list, if it not already there.
	 */

	for (transient = wmPtr2->transientPtr;
	     transient != NULL && transient->winPtr != winPtr;
	     transient = transient->nextPtr) {}
	if (transient == NULL) {
	    transient = (Transient *)ckalloc(sizeof(Transient));
	    transient->winPtr = winPtr;

	    transient->flags = 0;
	    transient->nextPtr = wmPtr2->transientPtr;
	    wmPtr2->transientPtr = transient;
	}

	/*
	 * If the container is withdrawn or iconic then withdraw the transient.
	 */

	if ((wmPtr2->hints.initial_state == WithdrawnState ||
		wmPtr2->hints.initial_state == IconicState) &&
		wmPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr, WithdrawnState);
	    transient->flags |= WITHDRAWN_BY_CONTAINER;
	}

	wmPtr->container = (Tk_Window)containerPtr;
    }


    ApplyContainerOverrideChanges(winPtr, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * RemoveTransient --
 *
 *      Clears the transient's container record and removes the transient from the
 *      container's list.
 *
 * Results:
 *	None
 *
 * Side effects:
 *      References to a container are removed from the transient's wmInfo
 *	structure and references to the transient are removed from its container's
 *	wmInfo.
 *
 *----------------------------------------------------------------------
 */

static void
RemoveTransient(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
    TkWindow *containerPtr;
    Transient *transPtr, *temp;

    if (wmPtr == NULL || wmPtr->container == NULL) {
	return;
    }
    containerPtr = (TkWindow *)wmPtr->container;
    wmPtr2 = containerPtr->wmInfoPtr;
    if (wmPtr2 == NULL) {
	return;
    }
    wmPtr->container= NULL;
    transPtr = wmPtr2->transientPtr;

    while (transPtr != NULL) {
	if (transPtr->winPtr != winPtr) {
	    break;
	}
	temp = transPtr->nextPtr;
	ckfree(transPtr);
	transPtr = temp;

    }
    wmPtr2->transientPtr = transPtr;
    while (transPtr != NULL) {
	if (transPtr->nextPtr && transPtr->nextPtr->winPtr == winPtr) {
	    temp = transPtr->nextPtr;
	    transPtr->nextPtr = temp->nextPtr;
	    ckfree(temp);
	} else {
	    transPtr = transPtr->nextPtr;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * WmWithdrawCmd --
 *







|
|
<

>
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
|
<
<
<
<
<
|
|
>
>
>
>
|
|
>
|
<
<
<
<
<
|
|
<
|
<
<
<

<
<
<
|
<
<
>
|
|
|


<
<
<
|
<
<
<
<
<
|
|
|
<
>
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
|
|
|
|
<
<
<
<
|
|
<
>
|
|
<

|
<
<
>

<
|
<
<
<
|
<
<
<
<







3289
3290
3291
3292
3293
3294
3295
3296
3297

3298
3299
3300
3301
3302
3303






























3304
3305
3306
3307
3308



3309





3310
3311
3312
3313
3314
3315
3316
3317
3318
3319





3320
3321

3322



3323



3324


3325
3326
3327
3328
3329
3330



3331





3332
3333
3334

3335
3336
3337
3338
3339



















3340


3341




3342
3343
3344
3345




3346
3347

3348
3349
3350

3351
3352


3353
3354

3355



3356




3357
3358
3359
3360
3361
3362
3363
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window master;

    WmInfo *wmPtr2;
    char *masterWindowName;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");






























	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->master != None) {
	    Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);



	}





	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	wmPtr->master = None;
	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {





	    return TCL_ERROR;
	}

	Tk_MakeWindowExist(master);







	if (wmPtr->iconFor != NULL) {


	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);
	    return TCL_ERROR;
	}




	wmPtr2 = ((TkWindow *) master)->wmInfoPtr;






	/* Under some circumstances, wmPtr2 is NULL here */
	if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {

	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor), NULL);
	    return TCL_ERROR;
	}






















	if ((TkWindow *) master == winPtr) {




	    Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),
		    "\" its own master", NULL);
	    return TCL_ERROR;
	}





	wmPtr->master = Tk_WindowId(master);

	masterWindowName = Tcl_GetStringFromObj(objv[3], &length);
	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);

	}
	wmPtr->masterWindowName = ckalloc(length+1);


	strcpy(wmPtr->masterWindowName, masterWindowName);
    }

    ApplyMasterOverrideChanges(winPtr, NULL);



    return TCL_OK;




}

/*
 *----------------------------------------------------------------------
 *
 * WmWithdrawCmd --
 *
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, WithdrawnState);

    /*
     * If this window has a transient, the transient must also be withdrawn.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (containerPtr == winPtr &&
		winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr2, WithdrawnState);
	    transientPtr->flags |= WITHDRAWN_BY_CONTAINER;
	}
    }

    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry.  Schedules a geometry
 * update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{







|





|





<

<
|
|
<


<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

|
|







3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389

3390

3391
3392

3393
3394

3395

















3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, WithdrawnState);

















    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry.
 * Schedules a geometry update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
    int reqWidth,		/* Width (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {







|







3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
    int reqWidth,		/* Width (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015

4016
4017
4018
4019
4020
4021
4022
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
		    == (PBaseSize|PResizeInc))) {
	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel units
     * and there's no easy way to translate them to grid units since the new
     * requested size of the top-level window in pixels may not yet have been
     * registered yet (it may filter up the hierarchy in DoWhenIdle handlers).
     * However, if the window has never been mapped yet then just leave the
     * window size alone: assume that it is intended to be in grid units but
     * just happened to have been specified before this procedure was called.

     */

    if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) {
	wmPtr->width = -1;
	wmPtr->height = -1;
    }








|
|
|
|
|
|
|
>







3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
		    == (PBaseSize|PResizeInc))) {
	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel
     * units and there's no easy way to translate them to grid units since the
     * new requested size of the top-level window in pixels may not yet have
     * been registered yet (it may filter up the hierarchy in DoWhenIdle
     * handlers). However, if the window has never been mapped yet then just
     * leave the window size alone: assume that it is intended to be in grid
     * units but just happened to have been specified before this procedure
     * was called.
     */

    if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) {
	wmPtr->width = -1;
	wmPtr->height = -1;
    }

4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
 */

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */








|







3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
 */

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display,
		    -1, -1, -1, NULL, NULL);

	    Tk_DestroyWindow((Tk_Window)winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
	if (wmTracing) {
	    TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName);
	}
    } else if (eventPtr->type == ReparentNotify) {
	Tcl_Panic("received unwanted reparent event");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TopLevelReqProc --







|






|







3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display,
		    -1, -1, -1, NULL, NULL);

	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
	if (wmTracing) {
	    TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName);
	}
    } else if (eventPtr->type == ReparentNotify) {
	Tcl_Panic("recieved unwanted reparent event");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TopLevelReqProc --
4159
4160
4161
4162
4163
4164
4165

4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */


static void
TopLevelReqProc(
    TCL_UNUSED(void *),		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;







>


|


|







3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
4288
4289
4290
4291
4292
4293
4294










4295





4296




4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
	max = wmPtr->maxHeight;
    }
    if (height < min) {
	height = min;
    } else if ((max > 0) && (height > max)) {
	height = max;
    }










    x = wmPtr->x;





    y = wmPtr->y;





    /*
     * If the window's size is going to change and the window is supposed to
     * not be resizable by the user, then we have to update the size hints.
     * There may also be a size-hint-update request pending from somewhere
     * else, too.
     */

    if (((width != winPtr->changes.width)
	    || (height != winPtr->changes.height))
	    && (wmPtr->gridWin == NULL)
	    && !(wmPtr->sizeHintsFlags & (PMinSize|PMaxSize))) {
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }
    if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
	UpdateSizeHints(winPtr);
    }

    /*







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>











|







3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
	max = wmPtr->maxHeight;
    }
    if (height < min) {
	height = min;
    } else if ((max > 0) && (height > max)) {
	height = max;
    }

    /*
     * Compute the new position for the upper-left pixel of the window's
     * decorative frame. This is tricky, because we need to include the border
     * widths supplied by a reparented parent in this calculation, but can't
     * use the parent's current overall size since that may change as a result
     * of this code.
     */

    if (wmPtr->flags & WM_NEGATIVE_X) {
	x = wmPtr->vRootWidth - wmPtr->x
	    - (width + (wmPtr->parentWidth - winPtr->changes.width));
    } else {
	x =  wmPtr->x;
    }
    if (wmPtr->flags & WM_NEGATIVE_Y) {
	y = wmPtr->vRootHeight - wmPtr->y
	    - (height + (wmPtr->parentHeight - winPtr->changes.height));
    } else {
	y =  wmPtr->y;
    }

    /*
     * If the window's size is going to change and the window is supposed to
     * not be resizable by the user, then we have to update the size hints.
     * There may also be a size-hint-update request pending from somewhere
     * else, too.
     */

    if (((width != winPtr->changes.width)
	    || (height != winPtr->changes.height))
	    && (wmPtr->gridWin == NULL)
	    && ((wmPtr->sizeHintsFlags & (PMinSize|PMaxSize)) == 0)) {
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }
    if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
	UpdateSizeHints(winPtr);
    }

    /*
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
	     * geometry, except to make sure that the desired size is known by
	     * the container. Also, zero out any position information, since
	     * embedded windows are not allowed to move.
	     */

	    wmPtr->x = wmPtr->y = 0;
	    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
	    Tk_GeometryRequest((Tk_Window)contWinPtr, width, height);
	}
	return;
    }
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {







|







3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
	     * geometry, except to make sure that the desired size is known by
	     * the container. Also, zero out any position information, since
	     * embedded windows are not allowed to move.
	     */

	    wmPtr->x = wmPtr->y = 0;
	    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
	    Tk_GeometryRequest((Tk_Window) contWinPtr, width, height);
	}
	return;
    }
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
     * Parse the width and height, if they are present. Don't actually update
     * any of the fields of wmPtr until we've successfully parsed the entire
     * geometry string.
     */

    width = wmPtr->width;
    height = wmPtr->height;
    x = -1;
    y = -1;
    flags = wmPtr->flags;
    if (isdigit(UCHAR(*p))) {
	width = strtoul(p, &end, 10);
	p = end;
	if (*p != 'x') {
	    goto error;
	}







|
|







3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
     * Parse the width and height, if they are present. Don't actually update
     * any of the fields of wmPtr until we've successfully parsed the entire
     * geometry string.
     */

    width = wmPtr->width;
    height = wmPtr->height;
    x = wmPtr->x;
    y = wmPtr->y;
    flags = wmPtr->flags;
    if (isdigit(UCHAR(*p))) {
	width = strtoul(p, &end, 10);
	p = end;
	if (*p != 'x') {
	    goto error;
	}
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561

4562

4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	    wmPtr->sizeHintsFlags |= USPosition;
	    flags |= WM_UPDATE_SIZE_HINTS;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.
     *
     * Computing the new position for the upper-left pixel of the window's
     * decorative frame is tricky because we need to include the border
     * widths supplied by a reparented parent in the calculation, but we can't
     * use the parent's current overall size since that may change as a result
     * of this code.
     */

    wmPtr->width = width;
    wmPtr->height = height;
    if (flags & WM_NEGATIVE_X) {
	int borderwidth = wmPtr->parentWidth - winPtr->changes.width;
	int newWidth = width == -1 ? winPtr->changes.width : width;

	x = (x == -1) ?
		wmPtr->x + winPtr->changes.width - newWidth :
		wmPtr->vRootWidth - x - newWidth - borderwidth;
    }
    if (x == -1) {
	x = wmPtr->x;
    }
    if (flags & WM_NEGATIVE_Y) {
	int borderheight = wmPtr->parentHeight - winPtr->changes.height;
	int newHeight = height == -1 ? winPtr->changes.height : height;

	y = (y == -1) ?
		wmPtr->y + winPtr->changes.height - newHeight :
		wmPtr->vRootHeight - y - newHeight - borderheight;
    }
    if (y == -1) {
	y = wmPtr->y;
    }
    if (wmPtr->flags & WM_FULLSCREEN) {
	wmPtr->configX = x;
	wmPtr->configY = y;
    } else {
	wmPtr->x = x;
	wmPtr->y = y;
    }
    flags |= WM_MOVE_PENDING;

    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad geometry specifier \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "GEOMETRY", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --







|









<
<
<
<
<
<




<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
>

>







<
|
<







4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021






4022
4023
4024
4025









4026

4027


4028







4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046

4047

4048
4049
4050
4051
4052
4053
4054
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	    wmPtr->sizeHintsFlags |= USPosition;
	    flags |= WM_UPDATE_SIZE_HINTS;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.






     */

    wmPtr->width = width;
    wmPtr->height = height;









    if ((x != wmPtr->x) || (y != wmPtr->y)

	    || ((flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y))


		    != (wmPtr->flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)))) {







	if (wmPtr->flags & WM_FULLSCREEN) {
	    wmPtr->configX = x;
	    wmPtr->configY = y;
	} else {
	    wmPtr->x = x;
	    wmPtr->y = y;
	}
	flags |= WM_MOVE_PENDING;
    }
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:

    Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    int x, y;
    TkWindow *winPtr = (TkWindow *)tkwin;

    /*
     * Search back through this window's parents all the way to a top-level
     * window, combining the offsets of each window within its parent.
     */

    x = y = 0;







|







4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    int x, y;
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * Search back through this window's parents all the way to a top-level
     * window, combining the offsets of each window within its parent.
     */

    x = y = 0;
4619
4620
4621
4622
4623
4624
4625





















4626
4627
4628
4629
4630
4631
4632
4633
4634
4635








4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655

4656
4657
4658
4659
4660
4661
4662
		x += winPtr->wmInfoPtr->xInParent;
		y += winPtr->wmInfoPtr->yInParent;
		break;
	    }

	    otherPtr = TkpGetOtherWindow(winPtr);
	    if (otherPtr == NULL) {





















		break;
	    }

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
	     */

	    winPtr = otherPtr;
            continue;








	}
	winPtr = winPtr->parentPtr;
    }
    *xPtr = x;
    *yPtr = y;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CoordsToWindow --
 *
 *	This is a Macintosh specific implementation of this function. Given
 *	the root coordinates of a point, this procedure returns the token for
 *	the top-most window covering that point, if there exists such a window
 *	in this application.
 *
 * Results:
 *	The return result is either a token for the window corresponding to
 *	rootX and rootY, or else NULL to indicate that there is no such window.

 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
>
>
>
>
>
>
>
>



















|
>







4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
		x += winPtr->wmInfoPtr->xInParent;
		y += winPtr->wmInfoPtr->yInParent;
		break;
	    }

	    otherPtr = TkpGetOtherWindow(winPtr);
	    if (otherPtr == NULL) {
		if (tkMacOSXEmbedHandler->getOffsetProc != NULL) {
		    Point theOffset;

		    /*
		     * We do not require that the changes.x & changes.y for a
		     * non-Tk master window be kept up to date. So we first
		     * subtract off the possibly bogus values that have been
		     * added on at the top of this pass through the loop, and
		     * then call out to the getOffsetProc to give us the
		     * correct offset.
		     */

		    x -= winPtr->changes.x + winPtr->changes.border_width;
		    y -= winPtr->changes.y + winPtr->changes.border_width;

		    tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr,
			    &theOffset);

		    x += theOffset.h;
		    y += theOffset.v;
		}
		break;
	    }

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
	     */

	    winPtr = otherPtr;

	    /*
	     * Remember to offset by the container window here, since at the
	     * end of this if branch, we will pop out to the container's
	     * parent...
	     */

	    x += winPtr->changes.x + winPtr->changes.border_width;
	    y += winPtr->changes.y + winPtr->changes.border_width;
	}
	winPtr = winPtr->parentPtr;
    }
    *xPtr = x;
    *yPtr = y;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CoordsToWindow --
 *
 *	This is a Macintosh specific implementation of this function. Given
 *	the root coordinates of a point, this procedure returns the token for
 *	the top-most window covering that point, if there exists such a window
 *	in this application.
 *
 * Results:
 *	The return result is either a token for the window corresponding to
 *	rootX and rootY, or else NULL to indicate that there is no such
 *	window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
	    }
	}
	if (nextPtr == NULL) {
	    break;
	}
	winPtr = nextPtr;
    }
    if (winPtr->mainPtr != ((TkWindow *)tkwin)->mainPtr) {
	return NULL;
    }
    return (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_TopCoordsToWindow --
 *







<
<
<
|







4245
4246
4247
4248
4249
4250
4251



4252
4253
4254
4255
4256
4257
4258
4259
	    }
	}
	if (nextPtr == NULL) {
	    break;
	}
	winPtr = nextPtr;
    }



    return (Tk_Window) winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_TopCoordsToWindow --
 *
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
{
    TkWindow *winPtr, *childPtr;
    TkWindow *nextPtr;		/* Coordinates of highest child found so far
				 * that contains point. */
    int x, y;			/* Coordinates in winPtr. */
    Window *children;		/* Children of winPtr, or NULL. */

    winPtr = (TkWindow *)tkwin;
    x = rootX;
    y = rootY;
    while (1) {
	nextPtr = NULL;
	children = NULL;

	/*







|







4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
{
    TkWindow *winPtr, *childPtr;
    TkWindow *nextPtr;		/* Coordinates of highest child found so far
				 * that contains point. */
    int x, y;			/* Coordinates in winPtr. */
    Window *children;		/* Children of winPtr, or NULL. */

    winPtr = (TkWindow *) tkwin;
    x = rootX;
    y = rootY;
    while (1) {
	nextPtr = NULL;
	children = NULL;

	/*
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
	}
	winPtr = nextPtr;
	x -= winPtr->changes.x;
	y -= winPtr->changes.y;
    }
    *newX = x;
    *newY = y;
    return (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateVRootGeometry --
 *







|







4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
	}
	winPtr = nextPtr;
	x -= winPtr->changes.x;
	y -= winPtr->changes.y;
    }
    *newX = x;
    *newY = y;
    return (Tk_Window) winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateVRootGeometry --
 *
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
    /*
     * If this isn't a virtual-root window manager, just return information
     * about the screen.
     */

    wmPtr->flags &= ~WM_VROOT_OFFSET_STALE;
    if (wmPtr->vRoot == None) {
    noVRoot:
	wmPtr->vRootX = wmPtr->vRootY = 0;
	wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum);
	wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum);
	return;
    }

    /*







|







4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
    /*
     * If this isn't a virtual-root window manager, just return information
     * about the screen.
     */

    wmPtr->flags &= ~WM_VROOT_OFFSET_STALE;
    if (wmPtr->vRoot == None) {
	noVRoot:
	wmPtr->vRootX = wmPtr->vRootY = 0;
	wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum);
	wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum);
	return;
    }

    /*
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr,		/* Store dimensions of virtual root here. */
    int *heightPtr)
{
    WmInfo *wmPtr;
    TkWindow *winPtr = (TkWindow *)tkwin;

    /*
     * Find the top-level window for tkwin, and locate the window manager
     * information for that window.
     */

    while (!(winPtr->flags & TK_TOP_LEVEL)) {







|







4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr,		/* Store dimensions of virtual root here. */
    int *heightPtr)
{
    WmInfo *wmPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * Find the top-level window for tkwin, and locate the window manager
     * information for that window.
     */

    while (!(winPtr->flags & TK_TOP_LEVEL)) {
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003

5004
5005
5006
5007
5008
5009
5010
5011
 */

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;

    if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	wmPtr->sizeHintsFlags |= USPosition;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server







|








>
|







4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
 */

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;
    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
    if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	wmPtr->sizeHintsFlags |= USPosition;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071

5072
5073
5074



5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089

5090

5091


5092
5093

5094

5095
5096
5097
5098

5099
5100
5101
5102
5103
5104
5105
    int aboveBelow,		/* Gives relative position for restacking;
				 * must be Above or Below. */
    TkWindow *otherPtr)		/* Window relative to which to restack; if
				 * NULL, then winPtr gets restacked above or
				 * below *all* siblings. */
{
    NSWindow *macWindow;
    NSWindow *otherMacWindow;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int macAboveBelow = (aboveBelow == Above ? NSWindowAbove : NSWindowBelow);
    int otherNumber = 0; /* 0 will be used when otherPtr is NULL. */

    /*
     * If the Tk windows has no drawable, or is withdrawn do nothing.
     */

    if (winPtr->window == None ||
	    wmPtr == NULL      ||
	    wmPtr->hints.initial_state == WithdrawnState) {
	return;
    }
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (macWindow == nil) {
	return;
    }
    if (otherPtr) {
	/*
	 * When otherPtr is non-NULL, if the other window has no drawable or is

	 * withdrawn, do nothing.
	 */




	WmInfo *otherWmPtr = otherPtr->wmInfoPtr;
	if (winPtr->window == None ||
		otherWmPtr == NULL ||
		otherWmPtr->hints.initial_state == WithdrawnState) {
	    return;
	}
	otherMacWindow = TkMacOSXGetNSWindowForDrawable(otherPtr->window);
	if (otherMacWindow == nil) {
	    return;
	}

	/*
	 * If the other window is OK, get its number.
	 */


	otherNumber = [otherMacWindow windowNumber];

    }



    /*

     * Just let the Mac window manager deal with all the subtleties of keeping

     * track of off-screen windows, etc.
     */

    [macWindow orderWindow:macAboveBelow relativeTo:otherNumber];

}

/*
 *----------------------------------------------------------------------
 *
 * TkWmAddToColormapWindows --
 *







|
<
<
<


|


|
<
<
<
<
<
|
<

|

|
>
|


>
>
>
<
<
<
<
<
|
<
<
<
<
<
|
|
|

>
|
>
|
>
>
|
<
>
|
>
|
<
|
|
>







4547
4548
4549
4550
4551
4552
4553
4554



4555
4556
4557
4558
4559
4560





4561

4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572





4573





4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584

4585
4586
4587
4588

4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
    int aboveBelow,		/* Gives relative position for restacking;
				 * must be Above or Below. */
    TkWindow *otherPtr)		/* Window relative to which to restack; if
				 * NULL, then winPtr gets restacked above or
				 * below *all* siblings. */
{
    NSWindow *macWindow;
    NSInteger otherMacWindowNumber;




    /*
     * Get the mac window. Make sure it exists & is mapped.
     */

    if (winPtr->window == None) {





	Tk_MakeWindowExist((Tk_Window) winPtr);

    }
    if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Can't set stacking order properly until the window is on the screen
	 * (mapping it may give it a reparent window), so make sure it's on
	 * the screen.
	 */

	TkWmMapWindow(winPtr);
    }
    macWindow = TkMacOSXDrawableWindow(winPtr->window);











    /*
     * Get the window in which a raise or lower is in relation to.
     */

    if (otherPtr != NULL) {
	if (otherPtr->window == None) {
	    Tk_MakeWindowExist((Tk_Window) otherPtr);
	}
	if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
	    TkWmMapWindow(otherPtr);
	}

	otherMacWindowNumber = [TkMacOSXDrawableWindow(otherPtr->window)
		windowNumber];
    } else {
	otherMacWindowNumber = 0;

    }
    [macWindow orderWindow:(aboveBelow == Above ? NSWindowAbove : NSWindowBelow)
	    relativeTo:otherMacWindowNumber];
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmAddToColormapWindows --
 *
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
    }

    /*
     * Make a new bigger array and use it to reset the property. Automatically
     * add the toplevel itself as the last element of the list.
     */

    newPtr = (TkWindow **)ckalloc((count+2) * sizeof(TkWindow *));
    if (count > 0) {
	memcpy(newPtr, oldPtr, count * sizeof(TkWindow *));
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr;
    newPtr[count] = topPtr;
    if (oldPtr != NULL) {
	ckfree(oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * we don't support colormaps. If we did they would be installed here.
     */
}

/*
 *----------------------------------------------------------------------
 *







|









|






|







4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
    }

    /*
     * Make a new bigger array and use it to reset the property. Automatically
     * add the toplevel itself as the last element of the list.
     */

    newPtr = (TkWindow**)ckalloc((count+2) * sizeof(TkWindow *));
    if (count > 0) {
	memcpy(newPtr, oldPtr, count * sizeof(TkWindow *));
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr;
    newPtr[count] = topPtr;
    if (oldPtr != NULL) {
	ckfree((char *) oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * On the Macintosh all of this is just an excercise in compatibility as
     * we don't support colormaps. If we did they would be installed here.
     */
}

/*
 *----------------------------------------------------------------------
 *
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkGetPointerCoords(
    TCL_UNUSED(Tk_Window),	/* Toplevel window that identifies screen on
				 * which lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    XQueryPointer(NULL, None, NULL, NULL, xPtr, yPtr, NULL, NULL, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * InitialWindowBounds --
 *
 *	This function calculates the initial bounds for a new Mac toplevel
 *	window. Unless the geometry is specified by the user this code will
 *	auto place the windows in a cascade diagonially across the main monitor
 *	of the Mac.
 *
 * Results:
 *	Window bounds.
 *
 * Side effects:
 *	None.
 *







|













|
|







4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkGetPointerCoords(
    Tk_Window tkwin,		/* Toplevel window that identifies screen on
				 * which lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    XQueryPointer(NULL, None, NULL, NULL, xPtr, yPtr, NULL, NULL, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * InitialWindowBounds --
 *
 *	This function calculates the initial bounds for a new Mac toplevel
 *	window. Unless the geometry is specified by the user this code will
 *	auto place the windows in a cascade diagonially across the main
 *	monitor of the Mac.
 *
 * Results:
 *	Window bounds.
 *
 * Side effects:
 *	None.
 *
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
    if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))) {
	static NSPoint cascadePoint = { .x = 0, .y = 0 };
	NSRect frame;

	cascadePoint = [macWindow cascadeTopLeftFromPoint:cascadePoint];
	frame = [macWindow frame];
	wmPtr->x = frame.origin.x;
	wmPtr->y = TkMacOSXZeroScreenHeight() - (frame.origin.y +
		frame.size.height);
    }
    return NSMakeRect(wmPtr->x, wmPtr->y, winPtr->changes.width,
	    winPtr->changes.height);
}

/*







|







4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
    if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))) {
	static NSPoint cascadePoint = { .x = 0, .y = 0 };
	NSRect frame;

	cascadePoint = [macWindow cascadeTopLeftFromPoint:cascadePoint];
	frame = [macWindow frame];
	wmPtr->x = frame.origin.x;
	wmPtr->y = tkMacOSXZeroScreenHeight - (frame.origin.y +
		frame.size.height);
    }
    return NSMakeRect(wmPtr->x, wmPtr->y, winPtr->changes.width,
	    winPtr->changes.height);
}

/*
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXGrowToplevel(
    TCL_UNUSED(void *),
    TCL_UNUSED(XPoint))
{
    return false;
}

/*
 *----------------------------------------------------------------------
 *







|
|







4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXGrowToplevel(
    void *whichWindow,
    XPoint start)
{
    return false;
}

/*
 *----------------------------------------------------------------------
 *
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478

5479


5480


5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[NSString alloc] initWithUTF8String:titleUid];
    [TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetContainer --
 *
 *	If the passed window has the TRANSIENT_FOR property set this will
 *	return the container window. Otherwise it will return None.
 *
 * Results:
 *	The container window or None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkMacOSXGetContainer(
    TkWindow *winPtr)
{
    if (winPtr->wmInfoPtr != NULL) {
	return (Tk_Window)winPtr->wmInfoPtr->container;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetXWindow --
 *
 *	Stub function that returns the X window Id associated with the
 *      given NSWindow*.
 *
 * Results:
 *	The window id is returned. None is returned if not a Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
TkMacOSXGetXWindow(
    void *macWinPtr)
{
    Window window = None;
    TKWindow *w = (TKWindow *)macWinPtr;
    if ([w respondsToSelector: @selector (tkWindow)]) {
	window = [w tkWindow];

    }


    return window ? window : None;


}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXGetTkWindow --
 *
 *	Returns the Tk_Window associated with the given NSWindow*.  This
 *      function is a stub, so the NSWindow* parameter must be declared as
 *      void*.
 *
 * Results:
 *	A Tk_Window, or NULL if the NSWindow is not associated with
 *      any Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_MacOSXGetTkWindow(
    void *w)
{
    Window window = None;
    TkDisplay *dispPtr = TkGetDisplayList();
    if ([(NSWindow *)w respondsToSelector: @selector (tkWindow)]) {
	window = [(TKWindow *)w tkWindow];
    }
    return (window != None ?
	    Tk_IdToWindow(dispPtr->display, window) : NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *
 *	Ask Cocoa if the given window is in the zoomed out state. Because
 *	dragging & growing a window can change the Cocoa zoom state, we
 *	cannot rely on wmInfoPtr->hints.initial_state for this information.
 *
 * Results:
 *	True if window is zoomed out, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXIsWindowZoomed(
    TkWindow *winPtr)
{
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    return [macWindow isZoomed];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXZoomToplevel --
 *







|






|


|


|







|
|



|

|







|
<














<
|
|
|
>

>
>
|
>
>





|

|
<
<


<
|







|
|
|

|

<
<
|

|







|
|















|
<







4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952

4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966

4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984


4985
4986

4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000


5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028

5029
5030
5031
5032
5033
5034
5035
    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[NSString alloc] initWithUTF8String:titleUid];
    [TkMacOSXDrawableWindow(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetTransientMaster --
 *
 *	If the passed window has the TRANSIENT_FOR property set this will
 *	return the master window. Otherwise it will return None.
 *
 * Results:
 *	The master window or None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
TkGetTransientMaster(
    TkWindow *winPtr)
{
    if (winPtr->wmInfoPtr != NULL) {
	return winPtr->wmInfoPtr->master;
    }
    return None;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetXWindow --
 *
 *	Returns the X window Id associated with the given NSWindow*.

 *
 * Results:
 *	The window id is returned. None is returned if not a Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
TkMacOSXGetXWindow(
    void *macWinPtr)
{

    Tcl_HashEntry *hPtr;

    if (!macWinPtr || !windowHashInit) {
	return None;
    }
    hPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
    if (hPtr == NULL) {
	return None;
    }
    return (Window) Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetTkWindow --
 *
 *	Returns the TkWindow* associated with the given NSWindow*.


 *
 * Results:

 *	The TkWindow* returned. NULL is returned if not a Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow*
TkMacOSXGetTkWindow(
    NSWindow *w)
{
    Window window = TkMacOSXGetXWindow(w);
    TkDisplay *dispPtr = TkGetDisplayList();



    return (window != None ?
	    (TkWindow *)Tk_IdToWindow(dispPtr->display, window) : NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *
 *	Ask Carbon if the given window is in the zoomed out state. Because
 *	dragging & growing a window can change the Carbon zoom state, we
 *	cannot rely on wmInfoPtr->hints.initial_state for this information.
 *
 * Results:
 *	True if window is zoomed out, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXIsWindowZoomed(
    TkWindow *winPtr)
{
    return [TkMacOSXDrawableWindow(winPtr->window) isZoomed];

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXZoomToplevel --
 *
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609

5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630








































5631
5632
5633
5634
5635
5636
5637
5638

5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
	return false;
    }

    /*
     * Do nothing if already in desired zoom state.
     */

    if (([window isZoomed] == (zoomPart == inZoomOut))) {
	return false;
    }
    [window zoom:NSApp];

    wmPtr->hints.initial_state =
	(zoomPart == inZoomIn ? NormalState : ZoomState);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUnsupported1ObjCmd --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle" Tcl command. This command allows
 *	you to set the style of decoration for a Macintosh window.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Changes the style of a new Mac window.
 *
 *----------------------------------------------------------------------
 */


int
TkUnsupported1ObjCmd(
    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 *const subcmds[] = {
	"style", "tabbingid", "appearance", "isdark", NULL
    };
    enum SubCmds {
	TKMWS_STYLE, TKMWS_TABID, TKMWS_APPEARANCE, TKMWS_ISDARK
    };
    Tk_Window tkwin = clientData;
    TkWindow *winPtr;
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }









































    winPtr = (TkWindow *)
	    Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(

		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], subcmds,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch((enum SubCmds) index) {
    case TKMWS_STYLE:
	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
	    return TCL_ERROR;
	}
	return WmWinStyle(interp, winPtr, objc, objv);
    case TKMWS_TABID:
	if ([NSApp macOSVersion] < 101200) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
                "Tabbing identifiers did not exist until OSX 10.12.", -1));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "TABBINGID", NULL);
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?newid?");
	    return TCL_ERROR;
	}
	return WmWinTabbingId(interp, winPtr, objc, objv);
    case TKMWS_APPEARANCE:
	if ([NSApp macOSVersion] < 100900) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
                "Window appearances did not exist until OSX 10.9.", -1));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "APPEARANCE", NULL);
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?appearancename?");
	    return TCL_ERROR;
	}
	if (objc == 4 && [NSApp macOSVersion] < 101400) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Window appearances cannot be changed before OSX 10.14.",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "APPEARANCE", NULL);
	    return TCL_ERROR;
	}
	return WmWinAppearance(interp, winPtr, objc, objv);
    case TKMWS_ISDARK:
	if ((objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		TkMacOSXInDarkMode((Tk_Window)winPtr)));
	return TCL_OK;
    default:
	return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * WmWinStyle --
 *







|



<

|






|














>








|


|



|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
>
|
<



|
|


|
<





<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075

5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170

5171
5172
5173
5174
5175
5176
5177
5178

5179
5180
5181
5182
5183






5184


















5185


5186













5187
5188
5189
5190
5191
5192
5193
	return false;
    }

    /*
     * Do nothing if already in desired zoom state.
     */

    if (![window isZoomed] == (zoomPart == inZoomIn)) {
	return false;
    }
    [window zoom:NSApp];

    wmPtr->hints.initial_state =
	    (zoomPart == inZoomIn ? NormalState : ZoomState);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUnsupported1Cmd --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle" Tcl command. This command allows
 *	you to set the style of decoration for a Macintosh window.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Changes the style of a new Mac window.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
int
TkUnsupported1ObjCmd(
    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 *const subcmds[] = {
	"style", NULL
    };
    enum SubCmds {
	TKMWS_STYLE
    };
    Tk_Window tkwin = clientData;
    TkWindow *winPtr;
    int index, i;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }


    /* Iterate through objc/objv to set correct background color and toggle opacity of window. */
    for (i= 0; i < objc; i++) {
    	if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*black*")) {
    	    colorName = [NSColor blackColor];	// use #000000 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*dark*")) {
    	    colorName = [NSColor darkGrayColor]; //use #545454 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*light*")) {
    	    colorName = [NSColor lightGrayColor]; //use #ababab in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*white*")) {
    	    colorName = [NSColor whiteColor];	//use #ffffff in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "gray*")) {
    	    colorName = [NSColor grayColor];	//use #7f7f7f in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*red*")) {
    	    colorName = [NSColor redColor];	//use #ff0000 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*green*")) {
    	    colorName = [NSColor greenColor];	//use #00ff00 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*blue*")) {
    	    colorName = [NSColor blueColor];	//use #0000ff in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*cyan*")) {
    	    colorName = [NSColor cyanColor];	//use #00ffff in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*yellow*")) {
    	    colorName = [NSColor yellowColor];	//use #ffff00 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*magenta*")) {
    	    colorName = [NSColor magentaColor];	//use #ff00ff in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*orange*")) {
    	    colorName = [NSColor orangeColor];	//use #ff8000 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*purple*")) {
    	    colorName = [NSColor purpleColor];	//use #800080 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*brown*")){
    	    colorName = [NSColor brownColor];	//use #996633 in Tk scripts to match
    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*clear*")) {
    	    colorName = [NSColor clearColor];	//use systemTransparent in Tk scripts to match
    	}
    	if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*opacity*")) {
    	    opaqueTag = YES;
    	}
    }


    winPtr = (TkWindow *)
	    Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", NULL);

	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (((enum SubCmds) index) == TKMWS_STYLE) {

	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
	    return TCL_ERROR;
	}
	return WmWinStyle(interp, winPtr, objc, objv);






    }


















    /* won't be reached */


    return TCL_ERROR;













}

/*
 *----------------------------------------------------------------------
 *
 * WmWinStyle --
 *
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
	{ "toolbar",		kToolbarWindowClass			     },
	{ "plain",		kPlainWindowClass			     },
	{ "overlay",		kOverlayWindowClass			     },
	{ "sheetAlert",		kSheetAlertWindowClass			     },
	{ "altPlain",		kAltPlainWindowClass			     },
	{ "simple",		kSimpleWindowClass			     },
	{ "drawer",		kDrawerWindowClass			     },
	{ NULL, 0 }
    };
    static const struct StrIntMap compositeAttrMap[] = {
	{ "none",		kWindowNoAttributes			     },
	{ "standardDocument",	kWindowStandardDocumentAttributes	     },
	{ "standardFloating",	kWindowStandardFloatingAttributes	     },
	{ "fullZoom",		kWindowFullZoomAttribute		     },
	{ NULL, 0 }
    };

    /*
     * Map window attributes. Color and opacity are mapped to NULL; these are
     * parsed from the objv in TkUnsupported1ObjCmd.
     */

    static const struct StrIntMap attrMap[] = {
	{ "closeBox",		kWindowCloseBoxAttribute		     },
	{ "horizontalZoom",	kWindowHorizontalZoomAttribute		     },
	{ "verticalZoom",	kWindowVerticalZoomAttribute		     },
	{ "collapseBox",	kWindowCollapseBoxAttribute		     },
	{ "resizable",		kWindowResizableAttribute		     },







|






|


<
|
<
<







5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244

5245


5246
5247
5248
5249
5250
5251
5252
	{ "toolbar",		kToolbarWindowClass			     },
	{ "plain",		kPlainWindowClass			     },
	{ "overlay",		kOverlayWindowClass			     },
	{ "sheetAlert",		kSheetAlertWindowClass			     },
	{ "altPlain",		kAltPlainWindowClass			     },
	{ "simple",		kSimpleWindowClass			     },
	{ "drawer",		kDrawerWindowClass			     },
	{ NULL }
    };
    static const struct StrIntMap compositeAttrMap[] = {
	{ "none",		kWindowNoAttributes			     },
	{ "standardDocument",	kWindowStandardDocumentAttributes	     },
	{ "standardFloating",	kWindowStandardFloatingAttributes	     },
	{ "fullZoom",		kWindowFullZoomAttribute		     },
	{ NULL }
    };


    /* Map window attributes. Color and opacity are mapped to NULL; these are parsed from the objv in TkUnsupported1ObjCmd.*/



    static const struct StrIntMap attrMap[] = {
	{ "closeBox",		kWindowCloseBoxAttribute		     },
	{ "horizontalZoom",	kWindowHorizontalZoomAttribute		     },
	{ "verticalZoom",	kWindowVerticalZoomAttribute		     },
	{ "collapseBox",	kWindowCollapseBoxAttribute		     },
	{ "resizable",		kWindowResizableAttribute		     },
5782
5783
5784
5785
5786
5787
5788
















5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807

5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
	{ "ignoreClicks",	kWindowIgnoreClicksAttribute		     },
	{ "noConstrain",	kWindowNoConstrainAttribute		     },
	{ "doesNotHide",	tkWindowDoesNotHideAttribute		     },
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
















	{ NULL, 0 }
    };

    int index, i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {
	Tcl_Obj *attributeList, *newResult = NULL;
	UInt64 attributes;

	for (i = 0; classMap[i].strValue != NULL; i++) {
	    if (wmPtr->macClass == classMap[i].intValue) {
		newResult = Tcl_NewStringObj(classMap[i].strValue, -1);
		break;
	    }
	}
	if (newResult == NULL) {
	    Tcl_Panic("invalid class");
	}


	attributeList = Tcl_NewListObj(0, NULL);
	attributes = wmPtr->attributes;

	for (i = 0; compositeAttrMap[i].strValue != NULL; i++) {
	    UInt64 intValue = compositeAttrMap[i].intValue;

	    if (intValue && (attributes & intValue) == intValue) {
		Tcl_ListObjAppendElement(NULL, attributeList,
			Tcl_NewStringObj(compositeAttrMap[i].strValue,
			-1));
		attributes &= ~intValue;
		break;
	    }
	}
	for (i = 0; attrMap[i].strValue != NULL; i++) {
	    if (attributes & attrMap[i].intValue) {
		Tcl_ListObjAppendElement(NULL, attributeList,
			Tcl_NewStringObj(attrMap[i].strValue, -1));
	    }
	}
	Tcl_ListObjAppendElement(NULL, newResult, attributeList);
	Tcl_SetObjResult(interp, newResult);
    } else {
	int attrObjc;
	Tcl_Obj **attrObjv = NULL;
	WindowClass macClass;
	UInt64 oldAttributes = wmPtr->attributes;
	int oldFlags = wmPtr->flags;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


















>








|








|



|







5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
	{ "ignoreClicks",	kWindowIgnoreClicksAttribute		     },
	{ "noConstrain",	kWindowNoConstrainAttribute		     },
	{ "doesNotHide",	tkWindowDoesNotHideAttribute		     },
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ "black",		0			                     },
	{ "dark",		0			                     },
	{ "light",		0			                     },
	{ "gray",		0			                     },
	{ "red",		0 			                     },
	{ "green",		0                			     },
	{ "blue",		0           			             },
	{ "cyan",		0			                     },
	{ "yellow",		0			                     },
	{ "magenta",		0  			                     },
	{ "orange",		0 			                     },
	{ "purple",		0			                     },
	{ "brown",		0			                     },
	{ "clear",		0			                     },
	{ "opacity",		0			                     },
	{ "fullscreen",         0			                     },
	{ NULL }
    };

    int index, i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {
	Tcl_Obj *attributeList, *newResult = NULL;
	UInt64 attributes;

	for (i = 0; classMap[i].strValue != NULL; i++) {
	    if (wmPtr->macClass == classMap[i].intValue) {
		newResult = Tcl_NewStringObj(classMap[i].strValue, -1);
		break;
	    }
	}
	if (newResult == NULL) {
	    Tcl_Panic("invalid class");
	}


	attributeList = Tcl_NewListObj(0, NULL);
	attributes = wmPtr->attributes;

	for (i = 0; compositeAttrMap[i].strValue != NULL; i++) {
	    UInt64 intValue = compositeAttrMap[i].intValue;

	    if (intValue && (attributes & intValue) == intValue) {
		Tcl_ListObjAppendElement(interp, attributeList,
			Tcl_NewStringObj(compositeAttrMap[i].strValue,
			-1));
		attributes &= ~intValue;
		break;
	    }
	}
	for (i = 0; attrMap[i].strValue != NULL; i++) {
	    if (attributes & attrMap[i].intValue) {
		Tcl_ListObjAppendElement(interp, attributeList,
			Tcl_NewStringObj(attrMap[i].strValue, -1));
	    }
	}
	Tcl_ListObjAppendElement(interp, newResult, attributeList);
	Tcl_SetObjResult(interp, newResult);
    } else {
	int attrObjc;
	Tcl_Obj **attrObjv = NULL;
	WindowClass macClass;
	UInt64 oldAttributes = wmPtr->attributes;
	int oldFlags = wmPtr->flags;
5863
5864
5865
5866
5867
5868
5869

5870
5871

5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
	} else {
	    wmPtr->attributes = macClassAttrs[macClass].defaultAttrs;
	}
	wmPtr->attributes &= (tkAlwaysValidAttributes |
		macClassAttrs[macClass].validAttrs);
	wmPtr->flags |= macClassAttrs[macClass].flags;
	wmPtr->macClass = macClass;

	ApplyWindowAttributeFlagChanges(winPtr, NULL, oldAttributes, oldFlags,
		0, 1);

	return TCL_OK;

    badClassAttrs:
	wmPtr->attributes = oldAttributes;
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmWinTabbingId --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle tabbingid" subcommand. The command
 *	allows you to get or set the tabbingIdentifier for the NSWindow
 *	associated with a Tk Window.  The syntax is:
 *
 *	    tk::unsupported::MacWindowStyle tabbingid window ?newId?
 *
 * Results:
 *	Returns the tabbingIdentifier of the window prior to calling this
 *      function.  If the optional newId argument is omitted, the window's
 *      tabbingIdentifier is not changed.
 *
 * Side effects:
 *	Windows may only be grouped together as tabs if they all have the same
 *      tabbingIdentifier.  In particular, by giving a window a unique
 *      tabbingIdentifier one can prevent it from becoming a tab in any other
 *      window.  Changing the tabbingIdentifier of a window which is already
 *      a tab causes it to become a separate window.
 *
 *----------------------------------------------------------------------
 */

static int
WmWinTabbingId(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
    Tcl_Obj *result = NULL;
    NSString *idString;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	idString = win.tabbingIdentifier;
	result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
    }
    if (result == NULL) {
	NSLog(@"Failed to read tabbing identifier; try calling update idletasks"
	      " before getting/setting the tabbing identifier of the window.");
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, result);
    if (objc == 3) {
	return TCL_OK;
    } else if (objc == 4) {
	int len;
	char *newId = Tcl_GetStringFromObj(objv[3], &len);
	NSString *newIdString = [NSString stringWithUTF8String:newId];
	[win setTabbingIdentifier: newIdString];

	/*
	 * If the tabbingIdentifier of a tab is changed we also turn it into a
	 * separate window so we don't violate the rule that all tabs in the
	 * same frame must have the same tabbingIdentifier.
	 */

	if ([idString compare:newIdString] != NSOrderedSame
#if MAC_OS_X_VERSION_MIN_REQUIRED > 101200
		&& [win tab]
#endif
		) {
	    [win moveTabToNewWindow:nil];
	}
	return TCL_OK;
    }
#endif
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * WmWinAppearance --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle appearance" subcommand. The command
 *	allows you to get or set the appearance for the NSWindow associated
 *	with a Tk Window.  The syntax is:
 *
 *	    tk::unsupported::MacWindowStyle tabbingid window ?newAppearance?
 *
 *      Allowed appearance names are "aqua", "darkaqua", and "auto".
 *
 * Results:
 *      Returns the appearance setting of the window prior to calling this
 *	function.
 *
 * Side effects:
 *      The underlying NSWindow's appearance property is set to the specified
 *      value if the optional newAppearance argument is supplied. Otherwise the
 *      window's appearance property is not changed.  If the appearance is set
 *      to aqua or darkaqua then the window will use the associated
 *      NSAppearance even if the user has selected a different appearance with
 *      the system preferences.  If it is set to auto then the appearance
 *      property is set to nil, meaning that the preferences will determine the
 *      appearance.
 *
 *----------------------------------------------------------------------
 */

static int
WmWinAppearance(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
    static const char *const appearanceStrings[] = {
	"aqua", "darkaqua", "auto", NULL
    };
    enum appearances {
	APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
    };
    Tcl_Obj *result = NULL;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
    NSAppearanceName appearance;
#else
    NSString *appearance;
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101300

    const char *resultString = "unrecognized";
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	appearance = win.appearance.name;
	if (appearance == nil) {
	    resultString = appearanceStrings[APPEARANCE_AUTO];
	} else if (appearance == NSAppearanceNameAqua) {
	    resultString = appearanceStrings[APPEARANCE_AQUA];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	} else if (@available(macOS 10.14, *)) {
	    if (appearance == NSAppearanceNameDarkAqua) {
		resultString = appearanceStrings[APPEARANCE_DARKAQUA];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	}
	result = Tcl_NewStringObj(resultString, strlen(resultString));
    }
    if (result == NULL) {
	NSLog(@"Failed to read appearance name; try calling update idletasks before getting/setting the appearance of the window.");
	return TCL_OK;
    }
    if (objc == 4) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], appearanceStrings,
                sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
            return TCL_ERROR;
        }
	switch ((enum appearances) index) {
	case APPEARANCE_AQUA:
	    win.appearance = [NSAppearance appearanceNamed:
		NSAppearanceNameAqua];
	    break;
	case APPEARANCE_DARKAQUA:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    if (@available(macOS 10.14, *)) {
		win.appearance = [NSAppearance appearanceNamed:
		    NSAppearanceNameDarkAqua];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    break;
	default:
	    win.appearance = nil;
	}
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
#else // MAC_OS_X_VERSION_MAX_ALLOWED > 1090
    return TCL_ERROR;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --
 *







>


>







<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384

5385














































5386


































































































































5387
5388
5389
5390
5391
5392
5393
	} else {
	    wmPtr->attributes = macClassAttrs[macClass].defaultAttrs;
	}
	wmPtr->attributes &= (tkAlwaysValidAttributes |
		macClassAttrs[macClass].validAttrs);
	wmPtr->flags |= macClassAttrs[macClass].flags;
	wmPtr->macClass = macClass;

	ApplyWindowAttributeFlagChanges(winPtr, NULL, oldAttributes, oldFlags,
		0, 1);

	return TCL_OK;

    badClassAttrs:
	wmPtr->attributes = oldAttributes;
	return TCL_ERROR;
    }

















































    return TCL_OK;


































































































































}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --
 *
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
TkpMakeMenuWindow(
    Tk_Window tkwin,		/* New window. */
    int transient)		/* 1 means menu is only posted briefly as a
				 * popup or pulldown or cascade. 0 means menu
				 * is always visible, e.g. as a floating
				 * menu. */
{
    TkWindow *winPtr = (TkWindow *)tkwin;

    if (transient) {
	winPtr->wmInfoPtr->macClass = kSimpleWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute;
    } else {
	winPtr->wmInfoPtr->macClass = kFloatingWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes;







|







5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
TkpMakeMenuWindow(
    Tk_Window tkwin,		/* New window. */
    int transient)		/* 1 means menu is only posted briefly as a
				 * popup or pulldown or cascade. 0 means menu
				 * is always visible, e.g. as a floating
				 * menu. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (transient) {
	winPtr->wmInfoPtr->macClass = kSimpleWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute;
    } else {
	winPtr->wmInfoPtr->macClass = kFloatingWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes;
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144

6145






6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204

6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215















6216
6217
6218
6219

6220
6221
6222
6223
6224
6225
6226

6227
6228











6229
6230
6231


6232

6233





6234



6235





6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251

6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264

6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276





6277
6278
6279
6280
6281
6282
6283
6284
6285

void
TkMacOSXMakeRealWindowExist(
    TkWindow *winPtr)		/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    MacDrawable *macWin;
    WindowClass macClass;
    Bool overrideRedirect = Tk_Attributes((Tk_Window)winPtr)->override_redirect;

    if (TkMacOSXHostToplevelExists(winPtr)) {
	return;
    }

    macWin = (MacDrawable *)winPtr->window;

    /*
     * If this is embedded, make sure its container's toplevel exists, then
     * return...
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}


	Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");






	return;

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }

    /*
     * If this is an override-redirect window, the NSWindow is created first as
     * a document window then converted to a simple window.
     */

    if (overrideRedirect) {
	wmPtr->macClass = kDocumentWindowClass;
    }
    macClass = wmPtr->macClass;
    wmPtr->attributes &= (tkAlwaysValidAttributes |
	    macClassAttrs[macClass].validAttrs);
    wmPtr->flags |= macClassAttrs[macClass].flags |
	    ((wmPtr->attributes & kWindowResizableAttribute) ? 0 :
	    WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
    UInt64 attributes = (wmPtr->attributes &
	    ~macClassAttrs[macClass].forceOffAttrs) |
	    macClassAttrs[macClass].forceOnAttrs;
    NSUInteger styleMask = macClassAttrs[macClass].styleMask |
	((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
	((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
	((attributes & kWindowCollapseBoxAttribute) ?
		NSMiniaturizableWindowMask : 0) |
	((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
	((attributes & kWindowMetalAttribute) ?
		NSTexturedBackgroundWindowMask : 0) |
	((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
		NSUnifiedTitleAndToolbarWindowMask : 0) |
	((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
	(attributes >> WM_NSMASK_SHIFT);
    Class winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
	    (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
	    NSNonactivatingPanelMask|NSHUDWindowMask)) ? [TKPanel class] :
	    [TKWindow class]);
    NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
	    styleMask:styleMask];
    NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
	    TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
	    structureRect.origin.y + structureRect.size.height + 200), 200, 200);
    if (wmPtr->hints.initial_state == WithdrawnState) {
    }
    TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];

    if (styleMask & NSUtilityWindowMask) {
	[(TKPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Textured windows are draggable from
	 *                               opaque content.
	 */
	[window setMovableByWindowBackground:NO];
    }















    [window setDocumentEdited:NO];
    wmPtr->window = window;
    macWin->view = window.contentView;
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width += structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = TkMacOSXZeroScreenHeight() - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:YES];
    [window setTkWindow: (Window) macWin];


    macWin->flags |= TK_HOST_EXISTS;











    if (overrideRedirect) {
    	XSetWindowAttributes atts;



    	atts.override_redirect = True;

    	Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);





    	ApplyContainerOverrideChanges(winPtr, NULL);



    }





}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedrawWidget --
 *
 *      Mark the bounding rectangle of this widget as needing display so the
 *      widget will be drawn by [NSView drawRect:].  If this is called within
 *      the drawRect method, do nothing.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The widget's bounding rectangle is marked as dirty.

 *
 *----------------------------------------------------------------------
 */

void
TkpRedrawWidget(Tk_Window tkwin) {
    TkWindow *winPtr = (TkWindow *)tkwin;
    NSWindow *w;
    Rect tkBounds;
    NSRect bounds;

    if ([NSApp isDrawing]) {
	return;

    }
    w = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (w) {
	TKContentView *view = [w contentView];
	TkMacOSXWinBounds(winPtr, &tkBounds);
	bounds = NSMakeRect(tkBounds.left,
			    [view bounds].size.height - tkBounds.bottom,
			    tkBounds.right - tkBounds.left,
			    tkBounds.bottom - tkBounds.top);
	[view setTkNeedsDisplay:YES];
	[view setTkDirtyRect:bounds];
    }





}


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetScrollbarGrow --
 *
 *	Sets a flag for a toplevel window indicating that the passed Tk







<
<





|


|
|












>
|
>
>
>
>
>
>






<
<
<
<
<
<
<
<
<
|




















|

|




|

<
<
|











>

|




|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>

|

|

|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
|
>
|
>
>
>
>
>
|
>
>
>

>
>
>
>
>





|

|
|
<


|


<
>





|
<
|
<
<
|
<
<
>
|
<
|
<
|
<
<
<
<
<
<

>
>
>
>
>
|
|







5443
5444
5445
5446
5447
5448
5449


5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485









5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515


5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612

5613
5614
5615
5616
5617

5618
5619
5620
5621
5622
5623
5624

5625


5626


5627
5628

5629

5630






5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645

void
TkMacOSXMakeRealWindowExist(
    TkWindow *winPtr)		/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    MacDrawable *macWin;



    if (TkMacOSXHostToplevelExists(winPtr)) {
	return;
    }

    macWin = (MacDrawable *) winPtr->window;

    /*
     * If this is embedded, make sure its container's toplevel exists,
     * then return...
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}

	if (tkMacOSXEmbedHandler == NULL) {
	    Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
	}
	if (tkMacOSXEmbedHandler->containerExistProc &&
		tkMacOSXEmbedHandler->containerExistProc((Tk_Window) winPtr)
		!= TCL_OK) {
	    Tcl_Panic("ContainerExistProc could not make container");
	}
	return;

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }









    WindowClass macClass = wmPtr->macClass;
    wmPtr->attributes &= (tkAlwaysValidAttributes |
	    macClassAttrs[macClass].validAttrs);
    wmPtr->flags |= macClassAttrs[macClass].flags |
	    ((wmPtr->attributes & kWindowResizableAttribute) ? 0 :
	    WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
    UInt64 attributes = (wmPtr->attributes &
	    ~macClassAttrs[macClass].forceOffAttrs) |
	    macClassAttrs[macClass].forceOnAttrs;
    NSUInteger styleMask = macClassAttrs[macClass].styleMask |
	((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
	((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
	((attributes & kWindowCollapseBoxAttribute) ?
		NSMiniaturizableWindowMask : 0) |
	((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
	((attributes & kWindowMetalAttribute) ?
		NSTexturedBackgroundWindowMask : 0) |
	((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
		NSUnifiedTitleAndToolbarWindowMask : 0) |
	((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
	(attributes >> WM_NSMASK_SHIFT);
    Class winClass = (macClass == kDrawerWindowClass ? [NSDrawerWindow class] :
	    (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
	    NSNonactivatingPanelMask|NSHUDWindowMask)) ? [NSPanel class] :
	    [TKWindow class]);
    NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
	    styleMask:styleMask];
    NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
	    tkMacOSXZeroScreenHeight - (tkMacOSXZeroScreenTop + 5 +
	    structureRect.origin.y + structureRect.size.height + 200), 200, 200);


    NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];
    [window setAutodisplay:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Texured windows are draggable
	 *                               from opaque content.
	 */
	[window setMovableByWindowBackground:NO];
    }


    /* Set background color and opacity of window if those flags are set.  */
    if (colorName != NULL) {
    	[window setBackgroundColor: colorName];
    }

    if (opaqueTag) {
#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
    	[window setOpaque: opaqueTag];
#else
	[window setOpaque: YES];
#endif
    }

    [window setDocumentEdited:NO];
    wmPtr->window = window;
    macWin->view = window.contentView;
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width +=  structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:NO];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    macWin->flags |= TK_HOST_EXISTS;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table
 *	that maps Mac windows to root X windows.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An entry is added to the windowTable hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXRegisterOffScreenWindow(
    Window window,		/* Window structure. */
    void *portPtr)		/* Pointer to a Mac Window. */
{
    Tcl_HashEntry *valueHashPtr;
    int isNew;

    if (!windowHashInit) {
	Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
	windowHashInit = true;
    }
    valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew);
    if (!isNew) {
	Tcl_Panic("Same macintosh window allocated twice!");
    }
    Tcl_SetHashValue(valueHashPtr, window);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXUnregisterMacWindow --
 *
 *	Given a macintosh port window, this function removes the association
 *	between this window and the root X window that Tk cares about.

 *
 * Results:
 *	None.
 *
 * Side effects:

 *	An entry is removed from the windowTable hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXUnregisterMacWindow(

    void *macWinPtr)	/* Reference to a Mac Window */


{


    Tcl_HashEntry *entryPtr;


    if (!windowHashInit) {

	Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited");






    }
    entryPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
    if (!entryPtr) {
	TkMacOSXDbgMsg("Failed to find window %p", macWinPtr);
    } else {
	Tcl_DeleteHashEntry(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetScrollbarGrow --
 *
 *	Sets a flag for a toplevel window indicating that the passed Tk
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423


6424
6425
6426
6427
6428
6429
6430

6431
6432
6433
6434
6435
6436
6437
6438
6439
    NSWindow *macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == IconicState) {

	/*
	 * The window always gets unmapped. If we can show the icon version of
	 * the window we also collapse it.
	 */

	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		![macWin isMiniaturized]) {
	    [macWin miniaturize:NSApp];
	}
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == NormalState || state == ZoomState) {
	Tk_MapWindow((Tk_Window)winPtr);


	[macWin deminiaturize:NSApp];
	[macWin orderFront:NSApp];
	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut);
    }
    /*
     * Make sure windows are updated after the state change.
     */


    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpIsWindowFloating --
 *







|


|

<









|

|
>
>
|
<
<
|
<
|
<
>
|
<







5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770

5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785


5786

5787

5788
5789

5790
5791
5792
5793
5794
5795
5796
    NSWindow *macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacOSXDrawableWindow(winPtr->window);

    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window) winPtr);
    } else if (state == IconicState) {

	/*
	 * The window always gets unmapped. If we can show the icon version of
	 * the window we also collapse it.
	 */

	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		![macWin isMiniaturized]) {
	    [macWin miniaturize:NSApp];
	}
	Tk_UnmapWindow((Tk_Window) winPtr);
    } else if (state == NormalState || state == ZoomState) {
	Tk_MapWindow((Tk_Window) winPtr);
	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		[macWin isMiniaturized]) {
	    [macWin deminiaturize:NSApp];


	}

	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn :

		inZoomOut);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkpIsWindowFloating --
 *
6450
6451
6452
6453
6454
6455
6456























6457
6458
6459
6460
6461
6462
6463

int
TkpIsWindowFloating(
    void *wRef)
{
    return [(NSWindow *)wRef level] == kCGFloatingWindowLevel;
}
























/*
 *--------------------------------------------------------------
 *
 * TkMacOSXWindowOffset --
 *
 *	Determines the x and y offset from the orgin of the toplevel window







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843

int
TkpIsWindowFloating(
    void *wRef)
{
    return [(NSWindow *)wRef level] == kCGFloatingWindowLevel;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWindowClass --
 *
 *	Returns OS X window class of window
 *
 * Results:
 *	1 or 0 depending on window's floating attribute.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE WindowClass
TkMacOSXWindowClass(
    TkWindow *winPtr)
{
    return winPtr->wmInfoPtr->macClass;
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXWindowOffset --
 *
 *	Determines the x and y offset from the orgin of the toplevel window
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XSetInputFocus(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(Time))
{
    /*
     * Don't need to do a thing. Tk manages the focus for us.
     */
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpChangeFocus --
 *
 *	This function is called when Tk moves focus from one window to another.
 *      It should be passed a non-embedded TopLevel. That toplevel gets raised
 *      to the top of the Tk stacking order and the associated NSWindow is
 *      ordered Front.
 *
 * Results:
 *	The return value is the serial number of the command that changed the
 *	focus. It may be needed by the caller to filter out focus change
 *	events that were queued before the command. If the procedure doesn't
 *	actually change the focus then it returns 0.
 *







|

|
|
|
|




<







|
<
<
|







5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924

5925
5926
5927
5928
5929
5930
5931
5932


5933
5934
5935
5936
5937
5938
5939
5940
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XSetInputFocus(
    Display* display,
    Window focus,
    int revert_to,
    Time time)
{
    /*
     * Don't need to do a thing. Tk manages the focus for us.
     */

}

/*
 *----------------------------------------------------------------------
 *
 * TkpChangeFocus --
 *
 *	This procedure is a stub on the Mac because we always own the focus if


 *	we are a front most application.
 *
 * Results:
 *	The return value is the serial number of the command that changed the
 *	focus. It may be needed by the caller to filter out focus change
 *	events that were queued before the command. If the procedure doesn't
 *	actually change the focus then it returns 0.
 *
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
				 * didn't originally belong to topLevelPtr's
				 * application. */
{
    if (winPtr->atts.override_redirect) {
	return 0;
    }

    if (Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)) {
    	NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if (win && [win canBecomeKeyWindow]) {
	    [win makeKeyAndOrderFront:NSApp];
	}
    }

    /*
     * Remember the current serial number for the X server and issue a dummy
     * server request. This marks the position at which we changed the focus,







|
|
<

|


|







5951
5952
5953
5954
5955
5956
5957
5958
5959

5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
				 * didn't originally belong to topLevelPtr's
				 * application. */
{
    if (winPtr->atts.override_redirect) {
	return 0;
    }

    if (Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr) ){
    	NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);

    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force ) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if ( win && [win canBecomeKeyWindow] ) {
	    [win makeKeyAndOrderFront:NSApp];
	}
    }

    /*
     * Remember the current serial number for the X server and issue a dummy
     * server request. This marks the position at which we changed the focus,
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670



























6671
6672
6673
6674
6675

6676

6677
6678

6679
6680
6681
6682
6683
6684
6685
6686
6687

6688




6689
6690
6691
6692
6693
6694
6695
    Display *display,		/* X display of parent window */
    Tcl_HashTable *table)	/* Maps mac window to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)
	    && (winPtr->display == display)) {
	hPtr = Tcl_CreateHashEntry(table,
		(void *)TkMacOSXGetNSWindowForDrawable(winPtr->window), &newEntry);
	Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	WmStackorderToplevelWrapperMap(childPtr, display, table);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmStackorderToplevel --
 *
 *	This procedure returns the stack order of toplevel windows.
 *
 * Results:
 *	A NULL terminated array of pointers to tk window objects in stacking
 *	order or else NULL if there was an error.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow **
TkWmStackorderToplevel(
    TkWindow *parentPtr)	/* Parent toplevel window. */
{
    TkWindow *childWinPtr, **windows, **windowPtr;
    Tcl_HashTable table;
    Tcl_HashEntry *hPtr;



























    NSArray *macWindows = [NSApp orderedWindows];
    NSArray* backToFront = [[macWindows reverseObjectEnumerator] allObjects];
    NSInteger windowCount = [macWindows count];

    windows = windowPtr = (TkWindow **)ckalloc((windowCount + 1) * sizeof(TkWindow *));

    if (windows != NULL) {

	Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
	WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);

	for (NSWindow *w in backToFront) {
	    hPtr = Tcl_FindHashEntry(&table, (char*) w);
	    if (hPtr != NULL) {
		childWinPtr = Tcl_GetHashValue(hPtr);
		*windowPtr++ = childWinPtr;
	    }
	}
	*windowPtr = NULL;
	Tcl_DeleteHashTable(&table);

    }




    return windows;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXApplyWindowAttributes --







|


|

















|
|














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<


|
>
|
>
|
<
>
|



|


|
|
>
|
>
>
>
>







6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074

6075
6076
6077
6078
6079
6080
6081

6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
    Display *display,		/* X display of parent window */
    Tcl_HashTable *table)	/* Maps mac window to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)
	    && (winPtr->display == display)) {
	hPtr = Tcl_CreateHashEntry(table,
		(char*) TkMacOSXDrawableWindow(winPtr->window), &newEntry);
	Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	WmStackorderToplevelWrapperMap(childPtr, display, table);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmStackorderToplevel --
 *
 *	This procedure returns the stack order of toplevel windows.
 *
 * Results:
 *	An array of pointers to tk window objects in stacking order or else
 *	NULL if there was an error.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow **
TkWmStackorderToplevel(
    TkWindow *parentPtr)	/* Parent toplevel window. */
{
    TkWindow *childWinPtr, **windows, **windowPtr;
    Tcl_HashTable table;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    /*
     * Map mac windows to a TkWindow of the wrapped toplevel.
     */

    Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
    WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);

    windows = (TkWindow**)ckalloc((table.numEntries+1) * sizeof(TkWindow *));

    /*
     * Special cases: If zero or one toplevels were mapped there is no need to
     * enumerate Windows.
     */

    switch (table.numEntries) {
    case 0:
	windows[0] = NULL;
	goto done;
    case 1:
	hPtr = Tcl_FirstHashEntry(&table, &search);
	windows[0] = Tcl_GetHashValue(hPtr);
	windows[1] = NULL;
	goto done;
    }

    NSArray *macWindows = [NSApp orderedWindows];

    NSInteger windowCount = [macWindows count];

    if (!windowCount) {
	ckfree((char *)windows);
	windows = NULL;
    } else {
	windowPtr = windows + table.numEntries;

	*windowPtr-- = NULL;
	for (NSWindow *w in macWindows) {
	    hPtr = Tcl_FindHashEntry(&table, (char*) w);
	    if (hPtr != NULL) {
		childWinPtr = Tcl_GetHashValue(hPtr);
		*windowPtr-- = childWinPtr;
	    }
	}
	if (windowPtr != windows-1) {
	    Tcl_Panic("num matched toplevel windows does not equal num "
		      "children");
	}
    }

  done:
    Tcl_DeleteHashTable(&table);
    return windows;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXApplyWindowAttributes --
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724

void
TkMacOSXApplyWindowAttributes(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    ApplyWindowAttributeFlagChanges(winPtr, macWindow, 0, 0, 0, 1);
    if (wmPtr->container != NULL || winPtr->atts.override_redirect) {
	ApplyContainerOverrideChanges(winPtr, macWindow);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyWindowAttributeFlagChanges --







<

|
|







6116
6117
6118
6119
6120
6121
6122

6123
6124
6125
6126
6127
6128
6129
6130
6131
6132

void
TkMacOSXApplyWindowAttributes(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    ApplyWindowAttributeFlagChanges(winPtr, macWindow, 0, 0, 0, 1);
    if (wmPtr->master != None || winPtr->atts.override_redirect) {
	ApplyMasterOverrideChanges(winPtr, macWindow);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyWindowAttributeFlagChanges --
6747
6748
6749
6750
6751
6752
6753
6754


6755
6756
6757
6758
6759
6760


6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783

6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
    UInt64 newAttributes = ForceAttributes(wmPtr->attributes, wmPtr->macClass);
    UInt64 changedAttributes = newAttributes ^ ForceAttributes(oldAttributes,
	    wmPtr->macClass);

    if (changedAttributes || wmPtr->flags != oldFlags || initial) {
	if (!macWindow) {
	    if (winPtr->window == None) {
		if (!create) {


		    return;
		}
		Tk_MakeWindowExist((Tk_Window)winPtr);
	    }
	    if (!TkMacOSXHostToplevelExists(winPtr)) {
		if (!create) {


		    return;
		}
		TkMacOSXMakeRealWindowExist(winPtr);
	    }
	    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	}
	if ((changedAttributes & kWindowCloseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowCloseButton]
		    setEnabled:!!(newAttributes & kWindowCloseBoxAttribute)];
	}
	if ((changedAttributes & kWindowCollapseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowMiniaturizeButton]
		    setEnabled:!!(newAttributes & kWindowCollapseBoxAttribute)];
	}
	if ((changedAttributes & (kWindowResizableAttribute |
		kWindowFullZoomAttribute)) || initial) {
	    [macWindow setShowsResizeIndicator:
		    !!(newAttributes & kWindowResizableAttribute)];
	    [[macWindow standardWindowButton:NSWindowZoomButton]
		    setEnabled:(newAttributes & kWindowResizableAttribute) &&
		    (newAttributes & kWindowFullZoomAttribute)];
	    if (newAttributes & kWindowHorizontalZoomAttribute) {
		wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE);

	    } else {
		wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE);
	    }
	    if (newAttributes & kWindowVerticalZoomAttribute) {
		wmPtr->flags &= ~(WM_HEIGHT_NOT_RESIZABLE);
	    } else {
		wmPtr->flags |= (WM_HEIGHT_NOT_RESIZABLE);
	    }
	    WmUpdateGeom(wmPtr, winPtr);
	}
	if ((changedAttributes & kWindowToolbarButtonAttribute) || initial) {
	    [macWindow setShowsToolbarButton:
		    !!(newAttributes & kWindowToolbarButtonAttribute)];
	    if ((newAttributes & kWindowToolbarButtonAttribute) &&
		    ![macWindow toolbar]) {
		NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@""];

		[toolbar setVisible:NO];
		[macWindow setToolbar:toolbar];
		[toolbar release];
		NSCell *toolbarButtonCell = [[macWindow standardWindowButton:
			NSWindowToolbarButton] cell];
		[toolbarButtonCell setTarget:[macWindow contentView]];
		[toolbarButtonCell setAction:@selector(tkToolbarButton:)];







|
>
>


<


|
>
>


<

|
















|
|
>

|
<
<
<
<
|









<







6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166

6167
6168
6169
6170
6171
6172
6173

6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196




6197
6198
6199
6200
6201
6202
6203
6204
6205
6206

6207
6208
6209
6210
6211
6212
6213
    UInt64 newAttributes = ForceAttributes(wmPtr->attributes, wmPtr->macClass);
    UInt64 changedAttributes = newAttributes ^ ForceAttributes(oldAttributes,
	    wmPtr->macClass);

    if (changedAttributes || wmPtr->flags != oldFlags || initial) {
	if (!macWindow) {
	    if (winPtr->window == None) {
		if (create) {
		    Tk_MakeWindowExist((Tk_Window) winPtr);
		} else {
		    return;
		}

	    }
	    if (!TkMacOSXHostToplevelExists(winPtr)) {
		if (create) {
		    TkMacOSXMakeRealWindowExist(winPtr);
		} else {
		    return;
		}

	    }
	    macWindow = TkMacOSXDrawableWindow(winPtr->window);
	}
	if ((changedAttributes & kWindowCloseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowCloseButton]
		    setEnabled:!!(newAttributes & kWindowCloseBoxAttribute)];
	}
	if ((changedAttributes & kWindowCollapseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowMiniaturizeButton]
		    setEnabled:!!(newAttributes & kWindowCollapseBoxAttribute)];
	}
	if ((changedAttributes & (kWindowResizableAttribute |
		kWindowFullZoomAttribute)) || initial) {
	    [macWindow setShowsResizeIndicator:
		    !!(newAttributes & kWindowResizableAttribute)];
	    [[macWindow standardWindowButton:NSWindowZoomButton]
		    setEnabled:(newAttributes & kWindowResizableAttribute) &&
		    (newAttributes & kWindowFullZoomAttribute)];
	    if (newAttributes & kWindowResizableAttribute) {
		wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE |
			WM_HEIGHT_NOT_RESIZABLE);
	    } else {
		wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE |




			WM_HEIGHT_NOT_RESIZABLE);
	    }
	    WmUpdateGeom(wmPtr, winPtr);
	}
	if ((changedAttributes & kWindowToolbarButtonAttribute) || initial) {
	    [macWindow setShowsToolbarButton:
		    !!(newAttributes & kWindowToolbarButtonAttribute)];
	    if ((newAttributes & kWindowToolbarButtonAttribute) &&
		    ![macWindow toolbar]) {
		NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@""];

		[toolbar setVisible:NO];
		[macWindow setToolbar:toolbar];
		[toolbar release];
		NSCell *toolbarButtonCell = [[macWindow standardWindowButton:
			NSWindowToolbarButton] cell];
		[toolbarButtonCell setTarget:[macWindow contentView]];
		[toolbarButtonCell setAction:@selector(tkToolbarButton:)];
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877

6878
6879
6880
6881
6882

6883










6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970



6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006

7007

7008

7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037


7038
7039
7040
7041

7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052















































































































7053
7054
7055
7056
7057
7058
7059
	    [macWindow setCanHide:
		    !(newAttributes & tkWindowDoesNotHideAttribute)];
	}
	if ((changedAttributes & (kWindowDoesNotCycleAttribute |
		tkCanJoinAllSpacesAttribute | tkMoveToActiveSpaceAttribute)) ||
		initial) {
	    NSWindowCollectionBehavior b = NSWindowCollectionBehaviorDefault;

	    /*
	     * This behavior, which makes the green button expand a window to
	     * full screen, was included in the default as of OSX 10.13.  For
	     * uniformity we use the new default in all versions of the OS
	     * after 10.10.
	     */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
	    if (!(macWindow.styleMask & NSUtilityWindowMask)) {
		/*
		 * Exclude overrideredirect, transient, and "help"-styled
		 * windows from moving into their own fullscreen space.
		 */

		if ((winPtr->atts.override_redirect) ||
			(wmPtr->container != NULL) ||
			(winPtr->wmInfoPtr->macClass == kHelpWindowClass)) {
		    b |= (NSWindowCollectionBehaviorCanJoinAllSpaces |
			    NSWindowCollectionBehaviorFullScreenAuxiliary);
		} else {
		    b |= NSWindowCollectionBehaviorFullScreenPrimary;

		    /*
		     * The default max size has height less than the screen
		     * height. This causes the window manager to refuse to
		     * allow the window to be resized when it is a split
		     * window. To work around this we make the max size equal
		     * to the screen size.  (For 10.11 and up, only)
		     */

		    if (@available(macOS 10.11, *)) {
			NSSize screenSize = [[macWindow screen] frame].size;
			[macWindow setMaxFullScreenContentSize:screenSize];
		    }
		}
	    }
#endif

	    if (newAttributes & tkCanJoinAllSpacesAttribute) {
		b |= NSWindowCollectionBehaviorCanJoinAllSpaces;
	    } else if (newAttributes & tkMoveToActiveSpaceAttribute) {
		b |= NSWindowCollectionBehaviorMoveToActiveSpace;
	    }

	    if (newAttributes & kWindowDoesNotCycleAttribute) {
		b |= NSWindowCollectionBehaviorIgnoresCycle;
	    } else {
		b |= NSWindowCollectionBehaviorParticipatesInCycle;
	    }

	    [macWindow setCollectionBehavior:b];










	}
	if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) {
	    [macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ?
		    kCGUtilityWindowLevel : ([macWindow isKindOfClass:
		    [TKPanel class]] && [macWindow isFloatingPanel] ?
		    kCGFloatingWindowLevel : kCGNormalWindowLevel)];
	}

	/*
	 * The change of window class/attributes might have changed the window
	 * frame geometry:
	 */

	NSRect structureRect = [macWindow frameRectForContentRect:NSZeroRect];

	wmPtr->xInParent = -structureRect.origin.x;
	wmPtr->yInParent = structureRect.origin.y + structureRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + structureRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + structureRect.size.height;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyContainerOverrideChanges --
 *
 *	This procedure applies changes to override_redirect or container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ApplyContainerOverrideChanges(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;
    unsigned long styleMask;
    NSRect structureRect;
    NSWindow *parentWindow;

    if (!macWindow && winPtr->window != None &&
	    TkMacOSXHostToplevelExists(winPtr)) {
	macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    }
    styleMask = [macWindow styleMask];

    /*
     * FIX: We need an UpdateWrapper equivalent to make this 100% correct
     */

    if (winPtr->atts.override_redirect) {
	if (wmPtr->macClass == kDocumentWindowClass) {
	    wmPtr->macClass = kSimpleWindowClass;
	    wmPtr->attributes = macClassAttrs[kSimpleWindowClass].defaultAttrs;
	}
	wmPtr->attributes |= kWindowNoActivatesAttribute;
	if ([NSApp macOSVersion] == 100600) {
	    styleMask = 0;
	} else {
	    styleMask &= ~NSTitledWindowMask;
	}
    } else {
	if (wmPtr->macClass == kSimpleWindowClass &&
	    (oldAttributes & kWindowNoActivatesAttribute)) {
	    wmPtr->macClass = kDocumentWindowClass;
	    wmPtr->attributes =
		    macClassAttrs[kDocumentWindowClass].defaultAttrs;
	}
	wmPtr->attributes &= ~kWindowNoActivatesAttribute;
	if ([NSApp macOSVersion] == 100600) {
	    styleMask = NSTitledWindowMask         |
		        NSClosableWindowMask       |
		        NSMiniaturizableWindowMask |
		        NSResizableWindowMask;
	} else {
	    styleMask |= NSTitledWindowMask;
	}



    }
    if (macWindow) {
	structureRect = [NSWindow frameRectForContentRect:NSZeroRect
		styleMask:styleMask];

	/*
	 * Synchronize the wmInfoPtr to match the new window configuration
	 * so windowBoundsChanged won't corrupt the window manager info.
	 */

	wmPtr->xInParent = -structureRect.origin.x;
	wmPtr->yInParent = structureRect.origin.y + structureRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + structureRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + structureRect.size.height;
	if (winPtr->atts.override_redirect) {
	    [macWindow setExcludedFromWindowsMenu:YES];
	    [macWindow setStyleMask:styleMask];
	    if (wmPtr->hints.initial_state == NormalState) {
		[macWindow orderFront:NSApp];
	    }
	    if (wmPtr->container != NULL) {
		wmPtr->flags |= WM_TOPMOST;
	    } else {
		wmPtr->flags &= ~WM_TOPMOST;
	    }
	} else {
	    const char *title = winPtr->wmInfoPtr->titleUid;

	    if (!title) {
		title = winPtr->nameUid;
	    }
	    [macWindow setStyleMask:styleMask];
	    [macWindow setTitle:[NSString stringWithUTF8String:title]];
	    [macWindow setExcludedFromWindowsMenu:NO];
	    wmPtr->flags &= ~WM_TOPMOST;
	}

	if (wmPtr->container != None) {

	    TkWindow *containerWinPtr = (TkWindow *)wmPtr->container;


	    if (containerWinPtr && (containerWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(containerWinPtr)) {
		NSWindow *containerMacWin = TkMacOSXGetNSWindowForDrawable(
			containerWinPtr->window);

		/*
		 * Try to add the transient window as a child window of the
		 * container. A child NSWindow retains its relative position
		 * with respect to the parent when the parent is moved.  This
		 * is pointless if the parent is offscreen, and adding a child
		 * to an offscreen window causes the parent to be displayed as
		 * a zombie.  So we only do this if the parent is visible.
		 */

		if (containerMacWin && [containerMacWin isVisible]
			&& (winPtr->flags & TK_MAPPED)) {
		    /*
		     * If the transient is already a child of some other window,
		     * remove it.
		     */

		    parentWindow = [macWindow parentWindow];
		    if (parentWindow && parentWindow != containerMacWin) {
			[parentWindow removeChildWindow:macWindow];
		    }
		    [macWindow orderFront:NSApp];
		    [containerMacWin addChildWindow:macWindow
					    ordered:NSWindowAbove];


		}
	    }
	} else {
	    parentWindow = [macWindow parentWindow];

	    if (parentWindow) {
		[parentWindow removeChildWindow:macWindow];
	    }
	}
	if (wmPtr->flags & WM_TOPMOST) {
	    [macWindow setLevel:kCGUtilityWindowLevel];
	}
	ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		oldFlags, 0, 0);
    }
}
















































































































/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *
 *	This function computes the current minWidth and minHeight values for a







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





>





>

>
>
>
>
>
>
>
>
>
>




|





|



<










|

|











|






<
<
<
<
<
<
<
<
<











<
<
|
<
<
<

|





<
<
<
<
<
<
<
|
>
>
>


<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<


>
|
>
|
>

|
|
|
|

<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|


<
|
|
>
>
|
|
<
<
>
|
|
<
<
<
<





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







6233
6234
6235
6236
6237
6238
6239







































6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276

6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307









6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318


6319



6320
6321
6322
6323
6324
6325
6326







6327
6328
6329
6330
6331
6332












6333






6334
6335











6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348








6349

6350






6351
6352
6353

6354
6355
6356
6357
6358
6359


6360
6361
6362




6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
	    [macWindow setCanHide:
		    !(newAttributes & tkWindowDoesNotHideAttribute)];
	}
	if ((changedAttributes & (kWindowDoesNotCycleAttribute |
		tkCanJoinAllSpacesAttribute | tkMoveToActiveSpaceAttribute)) ||
		initial) {
	    NSWindowCollectionBehavior b = NSWindowCollectionBehaviorDefault;







































	    if (newAttributes & tkCanJoinAllSpacesAttribute) {
		b |= NSWindowCollectionBehaviorCanJoinAllSpaces;
	    } else if (newAttributes & tkMoveToActiveSpaceAttribute) {
		b |= NSWindowCollectionBehaviorMoveToActiveSpace;
	    }
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	    if (newAttributes & kWindowDoesNotCycleAttribute) {
		b |= NSWindowCollectionBehaviorIgnoresCycle;
	    } else {
		b |= NSWindowCollectionBehaviorParticipatesInCycle;
	    }
#endif
	    [macWindow setCollectionBehavior:b];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	    if (((changedAttributes & kWindowDoesNotCycleAttribute) || initial)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
		    && tkMacOSXMacOSXVersion < 1060
#endif
	    ) {
		[macWindow setCanCycle:
			!(newAttributes & kWindowDoesNotCycleAttribute)];
	    }
#endif
	}
	if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) {
	    [macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ?
		    kCGUtilityWindowLevel : ([macWindow isKindOfClass:
		    [NSPanel class]] && [macWindow isFloatingPanel] ?
		    kCGFloatingWindowLevel : kCGNormalWindowLevel)];
	}

	/*
	 * The change of window class/attributes might have changed the window
	 * structure widths:
	 */

	NSRect structureRect = [macWindow frameRectForContentRect:NSZeroRect];

	wmPtr->xInParent = -structureRect.origin.x;
	wmPtr->yInParent = structureRect.origin.y + structureRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + structureRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + structureRect.size.height;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyMasterOverrideChanges --
 *
 *	This procedure applies changes to override_redirect or master.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ApplyMasterOverrideChanges(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;










    /*
     * FIX: We need an UpdateWrapper equivalent to make this 100% correct
     */

    if (winPtr->atts.override_redirect) {
	if (wmPtr->macClass == kDocumentWindowClass) {
	    wmPtr->macClass = kSimpleWindowClass;
	    wmPtr->attributes = macClassAttrs[kSimpleWindowClass].defaultAttrs;
	}
	wmPtr->attributes |= kWindowNoActivatesAttribute;


    } else {



	if (wmPtr->macClass == kSimpleWindowClass &&
		oldAttributes == kWindowNoActivatesAttribute) {
	    wmPtr->macClass = kDocumentWindowClass;
	    wmPtr->attributes =
		    macClassAttrs[kDocumentWindowClass].defaultAttrs;
	}
	wmPtr->attributes &= ~kWindowNoActivatesAttribute;







    }
    if (!macWindow && winPtr->window != None &&
	    TkMacOSXHostToplevelExists(winPtr)) {
	macWindow = TkMacOSXDrawableWindow(winPtr->window);
    }
    if (macWindow) {












	if (winPtr->atts.override_redirect && wmPtr->master != None) {






	    wmPtr->flags |= WM_TOPMOST;
	} else {











	    wmPtr->flags &= ~WM_TOPMOST;
	}
	NSWindow *parentWindow = [macWindow parentWindow];
	if (wmPtr->master != None) {
	    TkDisplay *dispPtr = TkGetDisplayList();
	    TkWindow *masterWinPtr = (TkWindow *)
		    Tk_IdToWindow(dispPtr->display, wmPtr->master);

	    if (masterWinPtr && masterWinPtr->window != None &&
		    TkMacOSXHostToplevelExists(masterWinPtr)) {
		NSWindow *masterMacWin =
			TkMacOSXDrawableWindow(masterWinPtr->window);









		if (masterMacWin && masterMacWin != parentWindow &&

			(winPtr->flags & TK_MAPPED)) {






		    if (parentWindow) {
			[parentWindow removeChildWindow:macWindow];
		    }

		    [masterMacWin addChildWindow:macWindow
			    ordered:NSWindowAbove];
		    if (wmPtr->flags & WM_TOPMOST) {
			[macWindow setLevel:kCGUtilityWindowLevel];
		    }
		}


	    }
	} else if (parentWindow) {
	    [parentWindow removeChildWindow:macWindow];




	}
	ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		oldFlags, 0, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXMakeFullscreen --
 *
 *	This procedure sets a fullscreen window to the size of the screen.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXMakeFullscreen(
    TkWindow *winPtr,
    NSWindow *window,
    int fullscreen,
    Tcl_Interp *interp)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN);

#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
    static unsigned long prevMask = 0, prevPres = 0;
#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/

    if (fullscreen) {
	int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
	int screenHeight = HeightOfScreen(Tk_Screen(winPtr));

	/*
	 * Check max width and height if set by the user.
	 */

	if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
		|| (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
	    if (interp) {
		Tcl_AppendResult(interp,
			"can't set fullscreen attribute for \"",
			winPtr->pathName,
			"\": max width/height is too small", NULL);
	    }
	    result = TCL_ERROR;
	    wmPtr->flags &= ~WM_FULLSCREEN;
	} else {
	    NSRect bounds = [window contentRectForFrameRect:[window frame]];
	    NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);

    	    if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) {
		wmPtr->configX = wmPtr->x;
		wmPtr->configY = wmPtr->y;
		wmPtr->configAttributes = wmPtr->attributes;
		wmPtr->attributes &= ~kWindowResizableAttribute;
		ApplyWindowAttributeFlagChanges(winPtr, window,
			wmPtr->configAttributes, wmPtr->flags, 1, 0);
		wmPtr->flags |= WM_SYNC_PENDING;
		[window setFrame:[window frameRectForContentRect:
					   screenBounds] display:YES];

		wmPtr->flags &= ~WM_SYNC_PENDING;
	    }
	    wmPtr->flags |= WM_FULLSCREEN;
	}

#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
	/*
	 * We can't set these features on Leopard or earlier, as they don't
	 * exist (neither options nor API that uses them). This formally means
	 * that there's a bug with full-screen windows with Tk on old OSX, but
	 * it isn't worth blocking a build just for this.
	 */

	prevMask = [window styleMask];
	prevPres = [NSApp presentationOptions];
	[window setStyleMask: NSBorderlessWindowMask];
	[NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock
	     | NSApplicationPresentationAutoHideMenuBar];

#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/
    } else {
	wmPtr->flags &= ~WM_FULLSCREEN;
#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
	[NSApp setPresentationOptions: prevPres];
	[window setStyleMask: prevMask];
#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/
    }

    if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) {
	UInt64 oldAttributes = wmPtr->attributes;
	NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight -
		(wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight),
		wmPtr->xInParent + wmPtr->configWidth,
		wmPtr->yInParent + wmPtr->configHeight);

	wmPtr->attributes |= wmPtr->configAttributes &
		kWindowResizableAttribute;
	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
		wmPtr->flags, 1, 0);
	wmPtr->flags |= WM_SYNC_PENDING;
	[window setFrame:[window frameRectForContentRect:bounds] display:YES];
	wmPtr->flags &= ~WM_SYNC_PENDING;
    }
    return result;
}



/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *
 *	This function computes the current minWidth and minHeight values for a
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255


7256
7257
7258
7259
7260
7261
7262
7263
7264

static void
RemapWindows(
    TkWindow *winPtr,
    MacDrawable *parentWin)
{
    TkWindow *childPtr;

    /*
     * Remove the OS specific window. It will get rebuilt when the window gets
     * Mapped.
     */

    if (winPtr->window != None) {
	MacDrawable *macWin = (MacDrawable *)winPtr->window;

	macWin->toplevel->referenceCount--;
	macWin->toplevel = parentWin->toplevel;
	macWin->toplevel->referenceCount++;
	winPtr->flags &= ~TK_MAPPED;
#ifdef TK_REBUILD_TOPLEVEL
	winPtr->flags |= TK_REBUILD_TOPLEVEL;
#endif
    }

    /*
     * Repeat for all the children.
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr, (MacDrawable *)winPtr->window);
    }
}



/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







<






|










<
|
<
<


|


>
>









6648
6649
6650
6651
6652
6653
6654

6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671

6672


6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688

static void
RemapWindows(
    TkWindow *winPtr,
    MacDrawable *parentWin)
{
    TkWindow *childPtr;

    /*
     * Remove the OS specific window. It will get rebuilt when the window gets
     * Mapped.
     */

    if (winPtr->window != None) {
	MacDrawable *macWin = (MacDrawable *) winPtr->window;

	macWin->toplevel->referenceCount--;
	macWin->toplevel = parentWin->toplevel;
	macWin->toplevel->referenceCount++;
	winPtr->flags &= ~TK_MAPPED;
#ifdef TK_REBUILD_TOPLEVEL
	winPtr->flags |= TK_REBUILD_TOPLEVEL;
#endif
    }


    /* Repeat for all the children */


    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr, (MacDrawable *) winPtr->window);
    }
}



/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWm.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75





76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245

246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 * tkMacOSXWm.h --
 *
 *	Declarations of Macintosh specific window manager structures.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#ifndef _TKMACWM
#define _TKMACWM

#include "tkMacOSXInt.h"
#include "tkMenu.h"

/*
 * A data structure of the following type holds information for each window
 * manager protocol (such as WM_DELETE_WINDOW) for which a handler (i.e. a Tcl

 * command) has been defined for a particular top-level window.
 */

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char* command;		/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the

				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

/* The following data structure is used in the TkWmInfo to maintain a list of all of the
 * transient windows belonging to a given container.
 */

typedef struct Transient {
    TkWindow *winPtr;
    int flags;
    struct Transient *nextPtr;
} Transient;

#define WITHDRAWN_BY_CONTAINER 0x1

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

typedef struct TkWmInfo {
    TkWindow *winPtr;		/* Pointer to main Tk information for this
				 * window. */
    Window reparent;		/* If the window has been reparented, this
				 * gives the ID of the ancestor of the window
				 * that is a child of the root window (may not
				 * be window's immediate parent). If the window
				 * isn't reparented, this has the value
				 * None. */
    Tk_Uid titleUid;		/* Title to display in window caption. If NULL,
				 * use name of widget. */
    char *iconName;		/* Name to display in icon. */
    Tk_Window container;		/* Container window for TRANSIENT_FOR property,
				 * or None. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */





    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */
    Transient *transientPtr;    /* First item in a list of all transient windows
				 * belonging to this window, or NULL if there
				 * are no transients. */

    /*
     * Information used to construct an XSizeHints structure for the window
     * manager:
     */

    int sizeHintsFlags;		/* Flags word for XSizeHints structure. If the
				 * PBaseSize flag is set then the window is
				 * gridded; otherwise it isn't gridded. */

    int minWidth, minHeight;	/* Minimum dimensions of window, in grid units,
				 * not pixels. */
    int maxWidth, maxHeight;	/* Maximum dimensions of window, in grid units,
				 * not pixels. */
    Tk_Window gridWin;		/* Identifies the window that controls gridding
				 * for this top-level, or NULL if the top-level
				 * isn't currently gridded. */
    int widthInc, heightInc;	/* Increments for size changes (# pixels per
				 * step). */
    struct {
	int x;			/* numerator */
	int y;			/* denominator */
    } minAspect, maxAspect;	/* Min/max aspect ratios for window. */
    int reqGridWidth, reqGridHeight;
				/* The dimensions of the window (in grid units)

				 * requested through the geometry manager. */
    int gravity;		/* Desired window gravity. */

    /*
     * Information used to manage the size and location of a window.
     */

    int width, height;		/* Desired dimensions of window, specified in
				 * grid units. These values are set by the "wm
				 * geometry" command and by ConfigureNotify

				 * events (for when wm resizes window). -1
				 * means user hasn't requested dimensions. */
    int x, y;			/* Desired X and Y coordinates for window.
				 * These values are set by "wm geometry", plus
				 * by ConfigureNotify events (when wm moves
				 * window). These numbers are different than
				 * the numbers stored in winPtr->changes
				 * because (a) they could be measured from the

				 * right or bottom edge of the screen (see
				 * WM_NEGATIVE_X and WM_NEGATIVE_Y flags) and
				 * (b) if the window has been reparented then
				 * they refer to the parent rather than the
				 * window itself. */
    int parentWidth, parentHeight;
				/* Width and height of reparent, in pixels
				 * *including border*. If window hasn't been
				 * reparented then these will be the outer
				 * dimensions of the window, including
				 * border. */
    int xInParent, yInParent;	/* Offset of window within reparent, measured
				 * from upper-left outer corner of parent's
				 * border to upper-left outer corner of child's
				 * border. If not reparented then these are
				 * zero. */
    int configX, configY;	/* x,y position of toplevel when window is
				 * switched into fullscreen state, */
    int configWidth, configHeight;
				/* Dimensions passed to last request that we
				 * issued to change geometry of window. Used to
				 * eliminate redundant resize operations. */

    /*
     * Information about the virtual root window for this top-level, if there
     * is one.
     */

    Window vRoot;		/* Virtual root window for this top-level, or
				 * None if there is no virtual root window
				 * (i.e. just use the screen's root). */
    int vRootX, vRootY;		/* Position of the virtual root inside the root
				 * window. If the WM_VROOT_OFFSET_STALE flag is
				 * set then this information may be incorrect
				 * and needs to be refreshed from the OS. If
				 * vRoot is None then these values are both
				 * 0. */
    unsigned int vRootWidth, vRootHeight;
				/* Dimensions of the virtual root window. If
				 * vRoot is None, gives the dimensions of the
				 * containing screen. This information is never
				 * stale, even though vRootX and vRootY can
				 * be. */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    int cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    Tcl_Obj *commandObj;	/* The command (guaranteed to be a list) for

				 * the WM_COMMAND property. NULL means nothing
				 * available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */

    /*
     * Macintosh information.
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;

    /*
     * Space to cache current window state when window becomes Fullscreen.
     */

    unsigned long cachedStyle;
    unsigned long cachedPresentation;
    NSRect cachedBounds;

} WmInfo;

/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
 *				need to update all info when window is first
 *				mapped.
 * WM_UPDATE_PENDING -		non-zero means a call to UpdateGeometryInfo
 *				has already been scheduled for this window; no
 *				need to schedule another one.
 * WM_NEGATIVE_X -		non-zero means x-coordinate is measured in
 *				pixels from right edge of screen, rather than
 *				from left edge.
 * WM_NEGATIVE_Y -		non-zero means y-coordinate is measured in
 *				pixels up from bottom of screen, rather than
 *				down from top.
 * WM_UPDATE_SIZE_HINTS -	non-zero means that new size hints need to be
 *				propagated to window manager.
 * WM_SYNC_PENDING -		set to non-zero while waiting for the window
 *				manager to respond to some state change.
 * WM_VROOT_OFFSET_STALE -	non-zero means that (x,y) offset information
 *				about the virtual root window is stale and
 *				needs to be fetched fresh from the X server.
 * WM_ABOUT_TO_MAP -		non-zero means that the window is about to be
 *				mapped by TkWmMapWindow. This is used by
 *				UpdateGeometryInfo to modify its behavior.
 * WM_MOVE_PENDING -		non-zero means the application has requested a
 *				new position for the window, but it hasn't
 *				been reflected through the window manager yet.

 * WM_COLORMAPS_EXPLICIT -	non-zero means the colormap windows were set
 *				explicitly via "wm colormapwindows".
 * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows"
 *				was called the top-level itself wasn't
 *				specified, so we added it implicitly at the
 *				end of the list.
 * WM_WIDTH_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).

 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).

 */

#define WM_NEVER_MAPPED			0x0001
#define WM_UPDATE_PENDING		0x0002
#define WM_NEGATIVE_X			0x0004
#define WM_NEGATIVE_Y			0x0008
#define WM_UPDATE_SIZE_HINTS		0x0010
#define WM_SYNC_PENDING			0x0020
#define WM_VROOT_OFFSET_STALE		0x0040
#define WM_ABOUT_TO_MAP			0x0080
#define WM_MOVE_PENDING			0x0100
#define WM_COLORMAPS_EXPLICIT		0x0200
#define WM_ADDED_TOPLEVEL_COLORMAP	0x0400
#define WM_WIDTH_NOT_RESIZABLE		0x0800
#define WM_HEIGHT_NOT_RESIZABLE		0x1000
#define WM_TOPMOST			0x2000
#define WM_FULLSCREEN			0x4000
#define WM_TRANSPARENT			0x8000

#endif /* _TKMACWM */

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */








|
|









|
|
>
|





|
|
|

|
|
|
>
|
|


<
<
<
|
<
<
<
<
<
|
<







|
|


|
|
|
|
|
|

|

|
|


|
|
>
>
>
>
>
|
|


<
<
<


|
|


|
|
|
>
|
|
|
|
|
|
|
|
|





|
>
|






|
|
|
>
|
|

|
|
|
|
|
>
|
|
|
<
|















|
|


|
|


|
|
|
|
|
|
|
|
|

|
|
|
|
|












|
|
|
>
|








<





|
<
<
<

<
<
<
<
<




|
|
|

|
|

|
|










|
|
|
|
|
|
>
|
|


|
|


|
>


|
>



















|
|
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



41





42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196



197





198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262








/*
 * tkMacOSXWm.h --
 *
 *	Declarations of Macintosh specific window manager structures.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 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.
 */

#ifndef _TKMACWM
#define _TKMACWM

#include "tkMacOSXInt.h"
#include "tkMenu.h"

/*
 * A data structure of the following type holds information for
 * each window manager protocol (such as WM_DELETE_WINDOW) for
 * which a handler (i.e. a Tcl command) has been defined for a
 * particular top-level window.
 */

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for
				 * the same top-level window, or NULL for
				 * end of list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[4];		/* Tcl command to invoke when a client
				 * message for this protocol arrives.
				 * The actual size of the structure varies
				 * to accommodate the needs of the actual
				 * command. THIS MUST BE THE LAST FIELD OF
				 * THE STRUCTURE. */
} ProtocolHandler;




#define HANDLER_SIZE(cmdLength) \





((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))


/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

typedef struct TkWmInfo {
    TkWindow *winPtr;		/* Pointer to main Tk information for
				 * this window. */
    Window reparent;		/* If the window has been reparented, this
				 * gives the ID of the ancestor of the window
				 * that is a child of the root window (may
				 * not be window's immediate parent). If
				 * the window isn't reparented, this has the
				 * value None. */
    Tk_Uid titleUid;		/* Title to display in window caption. If
				 * NULL, use name of widget. */
    char *iconName;		/* Name to display in icon. */
    Window master;		/* Master window for TRANSIENT_FOR property,
				 * or None. */
    XWMHints hints;		/* Various pieces of information for
				 * window manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note:  this field doesn't
				 * get updated if leader is destroyed. */
    char *masterWindowName;	/* Path name of window specified as master
				 * in "wm transient" command, or NULL.
				 * Malloc-ed. Note:  this field doesn't
				 * get updated if masterWindowName is
				 * destroyed. */
    Tk_Window icon;		/* Window to use as icon for this window,
				 * or NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */




    /*
     * Information used to construct an XSizeHints structure for
     * the window manager:
     */

    int sizeHintsFlags;		/* Flags word for XSizeHints structure.
				 * If the PBaseSize flag is set then the
				 * window is gridded; otherwise it isn't
				 * gridded. */
    int minWidth, minHeight;	/* Minimum dimensions of window, in
				 * grid units, not pixels. */
    int maxWidth, maxHeight;	/* Maximum dimensions of window, in
				 * grid units, not pixels. */
    Tk_Window gridWin;		/* Identifies the window that controls
				 * gridding for this top-level, or NULL if
				 * the top-level isn't currently gridded. */
    int widthInc, heightInc;	/* Increments for size changes (# pixels
				 * per step). */
    struct {
	int x;			/* numerator */
	int y;			/* denominator */
    } minAspect, maxAspect;	/* Min/max aspect ratios for window. */
    int reqGridWidth, reqGridHeight;
				/* The dimensions of the window (in
				 * grid units) requested through
				 * the geometry manager. */
    int gravity;		/* Desired window gravity. */

    /*
     * Information used to manage the size and location of a window.
     */

    int width, height;		/* Desired dimensions of window, specified
				 * in grid units. These values are
				 * set by the "wm geometry" command and by
				 * ConfigureNotify events (for when wm
				 * resizes window). -1 means user hasn't
				 * requested dimensions. */
    int x, y;			/* Desired X and Y coordinates for window.
				 * These values are set by "wm geometry",
				 * plus by ConfigureNotify events (when wm
				 * moves window). These numbers are
				 * different than the numbers stored in
				 * winPtr->changes because (a) they could be
				 * measured from the right or bottom edge
				 * of the screen (see WM_NEGATIVE_X and
				 * WM_NEGATIVE_Y flags) and (b) if the window
				 * has been reparented then they refer to the

				 * parent rather than the window itself. */
    int parentWidth, parentHeight;
				/* Width and height of reparent, in pixels
				 * *including border*. If window hasn't been
				 * reparented then these will be the outer
				 * dimensions of the window, including
				 * border. */
    int xInParent, yInParent;	/* Offset of window within reparent, measured
				 * from upper-left outer corner of parent's
				 * border to upper-left outer corner of child's
				 * border. If not reparented then these are
				 * zero. */
    int configX, configY;	/* x,y position of toplevel when window is
				 * switched into fullscreen state, */
    int configWidth, configHeight;
				/* Dimensions passed to last request that we
				 * issued to change geometry of window. Used
				 * to eliminate redundant resize operations. */

    /*
     * Information about the virtual root window for this top-level,
     * if there is one.
     */

    Window vRoot;		/* Virtual root window for this top-level,
				 * or None if there is no virtual root
				 * window (i.e. just use the screen's root). */
    int vRootX, vRootY;		/* Position of the virtual root inside the
				 * root window. If the WM_VROOT_OFFSET_STALE
				 * flag is set then this information may be
				 * incorrect and needs to be refreshed from
				 * the X server. If vRoot is None then these
				 * values are both 0. */
    unsigned int vRootWidth, vRootHeight;
				/* Dimensions of the virtual root window.
				 * If vRoot is None, gives the dimensions
				 * of the containing screen. This information
				 * is never stale, even though vRootX and
				 * vRootY can be. */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    int cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for
				 * this window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;		/* Array of strings to store in the
				 * WM_COMMAND property. NULL means nothing
				 * available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */

    /*
     * Macintosh information.
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;
} WmInfo;










/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been
 *				mapped; need to update all info when
 *				window is first mapped.
 * WM_UPDATE_PENDING -		non-zero means a call to UpdateGeometryInfo
 *				has already been scheduled for this
 *				window; no need to schedule another one.
 * WM_NEGATIVE_X -		non-zero means x-coordinate is measured in
 *				pixels from right edge of screen, rather
 *				than from left edge.
 * WM_NEGATIVE_Y -		non-zero means y-coordinate is measured in
 *				pixels up from bottom of screen, rather than
 *				down from top.
 * WM_UPDATE_SIZE_HINTS -	non-zero means that new size hints need to be
 *				propagated to window manager.
 * WM_SYNC_PENDING -		set to non-zero while waiting for the window
 *				manager to respond to some state change.
 * WM_VROOT_OFFSET_STALE -	non-zero means that (x,y) offset information
 *				about the virtual root window is stale and
 *				needs to be fetched fresh from the X server.
 * WM_ABOUT_TO_MAP -		non-zero means that the window is about to
 *				be mapped by TkWmMapWindow. This is used
 *				by UpdateGeometryInfo to modify its behavior.
 * WM_MOVE_PENDING -		non-zero means the application has requested
 *				a new position for the window, but it hasn't
 *				been reflected through the window manager
 *				yet.
 * WM_COLORMAPS_EXPLICIT -	non-zero means the colormap windows were
 *				set explicitly via "wm colormapwindows".
 * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows"
 *				was called the top-level itself wasn't
 *				specified, so we added it implicitly at
 *				the end of the list.
 * WM_WIDTH_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable"
 *				command).
 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable"
 *				command).
 */

#define WM_NEVER_MAPPED			0x0001
#define WM_UPDATE_PENDING		0x0002
#define WM_NEGATIVE_X			0x0004
#define WM_NEGATIVE_Y			0x0008
#define WM_UPDATE_SIZE_HINTS		0x0010
#define WM_SYNC_PENDING			0x0020
#define WM_VROOT_OFFSET_STALE		0x0040
#define WM_ABOUT_TO_MAP			0x0080
#define WM_MOVE_PENDING			0x0100
#define WM_COLORMAPS_EXPLICIT		0x0200
#define WM_ADDED_TOPLEVEL_COLORMAP	0x0400
#define WM_WIDTH_NOT_RESIZABLE		0x0800
#define WM_HEIGHT_NOT_RESIZABLE		0x1000
#define WM_TOPMOST			0x2000
#define WM_FULLSCREEN			0x4000
#define WM_TRANSPARENT			0x8000

#endif









Changes to macosx/tkMacOSXXStubs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55








56
57
58
59
60
61
62
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implementation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2014 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"

#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>

/*
 * Because this file is still under major development Debugger statements are
 * used through out this file. The define TCL_DEBUG will decide whether the
 * debugger statements actually call the debugger or not.
 */

#ifndef TCL_DEBUG
#   define Debugger()
#endif

#define ROOT_ID 10




/*
 * Declarations of static variables used in this file.
 */

/* The unique Macintosh display. */
static TkDisplay *gMacDisplay = NULL;
/* The default name of the Macintosh display. */
static const char *macScreenName = ":0";
/* Timestamp showing the last reset of the inactivity timer. */
static Time lastInactivityReset = 0;


/*
 * Forward declarations of procedures used in this file.
 */

static XID		MacXIdAlloc(Display *display);
static int		DefaultErrorHandler(Display *display,
			    XErrorEvent *err_evt);










/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDisplayChanged --
 *
 *	Called to set up initial screen info or when an event indicated





|












|
















>
>
>




<

|

<
<
|









>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implamentation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2014 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXEvent.h"

#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>

/*
 * Because this file is still under major development Debugger statements are
 * used through out this file. The define TCL_DEBUG will decide whether the
 * debugger statements actually call the debugger or not.
 */

#ifndef TCL_DEBUG
#   define Debugger()
#endif

#define ROOT_ID 10

CGFloat tkMacOSXZeroScreenHeight = 0;
CGFloat tkMacOSXZeroScreenTop = 0;

/*
 * Declarations of static variables used in this file.
 */


static TkDisplay *gMacDisplay = NULL;
				/* Macintosh display. */
static const char *macScreenName = ":0";


				/* Default name of macintosh display. */

/*
 * Forward declarations of procedures used in this file.
 */

static XID		MacXIdAlloc(Display *display);
static int		DefaultErrorHandler(Display *display,
			    XErrorEvent *err_evt);

/*
 * Other declarations
 */

static int		DestroyImage(XImage *image);
static unsigned long	ImageGetPixel(XImage *image, int x, int y);
static int		ImagePutPixel(XImage *image, int x, int y,
			    unsigned long pixel);

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDisplayChanged --
 *
 *	Called to set up initial screen info or when an event indicated
83
84
85
86
87
88
89
90
91




92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188





189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301








302

303






304



305

306

307




308



309
310
311
312
313
314
315
316
	return;
    }
    screen = display->screens;

    nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame];
	NSRect maxBounds = NSZeroRect;





	screen->root_depth = NSBitsPerPixelFromDepth([s depth]);
	screen->width = bounds.size.width;
	screen->height = bounds.size.height;
	screen->mwidth = (bounds.size.width * 254 + 360) / 720;
	screen->mheight = (bounds.size.height * 254 + 360) / 720;

	for (s in nsScreens) {
	    maxBounds = NSUnionRect(maxBounds, [s visibleFrame]);
	}
	*((NSRect *)screen->ext_data) = maxBounds;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXZeroScreenHeight --
 *
 *	Replacement for the tkMacOSXZeroScreenHeight variable to avoid
 *	caching values from NSScreen (fixes bug aea00be199).
 *
 * Results:
 *	Returns the height of screen 0 (the screen assigned the menu bar
 *	in System Preferences), or 0.0 if getting [NSScreen screens] fails.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGFloat
TkMacOSXZeroScreenHeight()
{
    NSArray *nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame];
	return bounds.size.height;
    }
    return 0.0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXZeroScreenTop --
 *
 *	Replacement for the tkMacOSXZeroScreenTop variable to avoid
 *	caching values from visibleFrame.
 *
 * Results:
 *	Returns how far below the top of screen 0 to draw
 *	(i.e. the height of the menu bar if it is always shown),
 *	or 0.0 if getting [NSScreen screens] fails.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGFloat
TkMacOSXZeroScreenTop()
{
    NSArray *nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame], visible = [s visibleFrame];
	return bounds.size.height - (visible.origin.y + visible.size.height);
    }
    return 0.0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --
 *
 *	Create the Display structure and fill it with device specific
 *	information.
 *
 * Results:
 *	Returns a Display structure on success or NULL on failure.
 *
 * Side effects:
 *	Allocates a new Display structure.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;





    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (gMacDisplay != NULL) {
	if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
	    return gMacDisplay;
	} else {
	    return NULL;
	}
    }

    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);

    /*
     * Initialize screen bits that may change
     */

    TkMacOSXDisplayChanged(display);

    gMacDisplay = (TkDisplay *)ckalloc(sizeof(TkDisplay));

    /*
     * This is the quickest way to make sure that all the *Init flags get
     * properly initialized
     */

    bzero(gMacDisplay, sizeof(TkDisplay));
    gMacDisplay->display = display;
    [pool drain];

    /*
     * Key map info must be available immediately, because of "send event".
     */
    TkpInitKeymapInfo(gMacDisplay);

    return gMacDisplay;
}

Display *
XkbOpenDisplay(
    TCL_UNUSED(const char *),
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    Display *display = (Display *)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    int fd = 0;
    NSArray *cgVers;
    static char vendor[25] = "";
    static NSRect maxBounds = {{0, 0}, {0, 0}};

    bzero(display, sizeof(Display));
    bzero(screen, sizeof(Screen));

    display->resource_alloc = MacXIdAlloc;
    display->request	    = 0;
    display->qlen	    = 0;
    display->fd		    = fd;
    display->screens	    = screen;
    display->nscreens	    = 1;
    display->default_screen = 0;
    display->display_name   = (char *) macScreenName;

    /*
     * These screen bits never change
     */
    screen->root	= ROOT_ID;
    screen->display	= display;
    screen->black_pixel = 0x00000000;
    screen->white_pixel = 0x00FFFFFF;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->c_class      = TrueColor;
    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    cgVers = [[[NSBundle bundleWithIdentifier:@"com.apple.CoreGraphics"]
	    objectForInfoDictionaryKey:@"CFBundleShortVersionString"]
	    componentsSeparatedByString:@"."];
    if ([cgVers count] >= 2) {
	display->proto_major_version = [[cgVers objectAtIndex:1] integerValue];
    }
    if ([cgVers count] >= 3) {
	display->proto_minor_version = [[cgVers objectAtIndex:2] integerValue];
    }
    if (!vendor[0]) {
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
	patch = systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }











    if (ev_rtrn) *ev_rtrn = 0;






    if (err_rtrn) *err_rtrn = 0;



    if (major_rtrn) *major_rtrn = 0;

    if (minor_rtrn) *minor_rtrn = 0;

    if (reason) *reason = 0;








    return display;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *







|

>
>
>
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


















>
>
>
>
>










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















|












>
>
>
>
>
>
>
>

>
|
>
>
>
>
>
>
|
>
>
>
|
>
|
>
|
>
>
>
>

>
>
>
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120





























































121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154




































155
156





157
158
159
160
161
162
163
164
165
166
167
168


















169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
	return;
    }
    screen = display->screens;

    nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame], visible = [s visibleFrame];
	NSRect maxBounds = NSZeroRect;

	tkMacOSXZeroScreenHeight = bounds.size.height;
	tkMacOSXZeroScreenTop = tkMacOSXZeroScreenHeight -
		(visible.origin.y + visible.size.height);

	screen->root_depth = NSBitsPerPixelFromDepth([s depth]);
	screen->width = bounds.size.width;
	screen->height = bounds.size.height;
	screen->mwidth = (bounds.size.width * 254 + 360) / 720;
	screen->mheight = (bounds.size.height * 254 + 360) / 720;

	for (s in nsScreens) {
	    maxBounds = NSUnionRect(maxBounds, [s visibleFrame]);
	}
	*((NSRect *)screen->ext_data) = maxBounds;
    }
}

/*
 *----------------------------------------------------------------------
 *





























































 * TkpOpenDisplay --
 *
 *	Create the Display structure and fill it with device specific
 *	information.
 *
 * Results:
 *	Returns a Display structure on success or NULL on failure.
 *
 * Side effects:
 *	Allocates a new Display structure.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;
    Screen *screen;
    int fd = 0;
    static NSRect maxBounds = {{0, 0}, {0, 0}};
    static char vendor[25] = "";
    NSArray *cgVers;
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (gMacDisplay != NULL) {
	if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
	    return gMacDisplay;
	} else {
	    return NULL;
	}
    }





































    display = (Display *) ckalloc(sizeof(Display));
    screen  = (Screen *) ckalloc(sizeof(Screen));





    bzero(display, sizeof(Display));
    bzero(screen, sizeof(Screen));

    display->resource_alloc = MacXIdAlloc;
    display->request	    = 0;
    display->qlen	    = 0;
    display->fd		    = fd;
    display->screens	    = screen;
    display->nscreens	    = 1;
    display->default_screen = 0;
    display->display_name   = (char *) macScreenName;



















    cgVers = [[[NSBundle bundleWithIdentifier:@"com.apple.CoreGraphics"]
	    objectForInfoDictionaryKey:@"CFBundleShortVersionString"]
	    componentsSeparatedByString:@"."];
    if ([cgVers count] >= 2) {
	display->proto_major_version = [[cgVers objectAtIndex:1] integerValue];
    }
    if ([cgVers count] >= 3) {
	display->proto_minor_version = [[cgVers objectAtIndex:2] integerValue];
    }
    if (!vendor[0]) {
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 10100
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
	patch = systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }

    /*
     * These screen bits never change
     */
    screen->root	= ROOT_ID;
    screen->display	= display;
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = (Visual *) ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->class	      = TrueColor;
    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    /*
     * Initialize screen bits that may change
     */

    TkMacOSXDisplayChanged(display);

    gMacDisplay = (TkDisplay *) ckalloc(sizeof(TkDisplay));

    /*
     * This is the quickest way to make sure that all the *Init flags get
     * properly initialized
     */

    bzero(gMacDisplay, sizeof(TkDisplay));
    gMacDisplay->display = display;
    [pool drain];
    return gMacDisplay;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    if (gMacDisplay != displayPtr) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display");
    }

    gMacDisplay = NULL;
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree(display->screens->root_visual);
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipCleanup --
 *







|

|

|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    if (gMacDisplay != displayPtr) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display");
    }

    gMacDisplay = NULL;
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree((char *) display->screens->root_visual);
	}
	ckfree((char *) display->screens);
    }
    ckfree((char *) display);
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipCleanup --
 *
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420



























421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877

















878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904


905
906
907
908
909
910
911
 *	was previously on the stack.
 *
 *----------------------------------------------------------------------
 */

static XID
MacXIdAlloc(
    TCL_UNUSED(Display *))		/* Display for which to allocate. */
{
    static long int cur_id = 100;
    /*
     * Some special XIds are reserved
     *   - this is why we start at 100
     */

    return ++cur_id;
}




























/*
 *----------------------------------------------------------------------
 *
 * DefaultErrorHandler --
 *
 *	This procedure is the default X error handler. Tk uses it's own error
 *	handler so this call should never be called.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This function will call panic and exit.
 *
 *----------------------------------------------------------------------
 */

static int
DefaultErrorHandler(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XErrorEvent *))
{
    /*
     * This call should never be called. Tk replaces it with its own error
     * handler.
     */

    Tcl_Panic("Warning hit bogus error handler!");
    return 0;
}

char *
XGetAtomName(
    Display *display,
    TCL_UNUSED(Atom))
{
    display->request++;
    return NULL;
}








XErrorHandler
XSetErrorHandler(
    TCL_UNUSED(XErrorHandler))
{
    return DefaultErrorHandler;
}

Window
XRootWindow(
    Display *display,
    TCL_UNUSED(int))
{
    display->request++;
    return ROOT_ID;
}

int
XGetGeometry(
    Display *display,
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWindow *winPtr = ((MacDrawable *)d)->winPtr;

    display->request++;
    *root_return = ROOT_ID;
    if (winPtr) {
	*x_return = Tk_X(winPtr);
	*y_return = Tk_Y(winPtr);
	*width_return = Tk_Width(winPtr);
	*height_return = Tk_Height(winPtr);
	*border_width_return = winPtr->changes.border_width;
	*depth_return = Tk_Depth(winPtr);
    } else {
	CGSize size = ((MacDrawable *)d)->size;
	*x_return = 0;
	*y_return =  0;
	*width_return = size.width;
	*height_return = size.height;
	*border_width_return = 0;
	*depth_return = 32;
    }
    return 1;
}

int
XChangeProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom),
    TCL_UNUSED(Atom),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(_Xconst unsigned char *),
    TCL_UNUSED(int))
{
    Debugger();
    return Success;
}

int
XSelectInput(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(long))
{
    Debugger();
    return Success;
}

int
XBell(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int))
{
    NSBeep();
    return Success;
}

#if 0
void
XSetWMNormalHints(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(XSizeHints *))
{
    /*
     * Do nothing. Shouldn't even be called.
     */
}

XSizeHints *
XAllocSizeHints(void)
{
    /*
     * Always return NULL. Tk code checks to see if NULL is returned & does
     * nothing if it is.
     */

    return NULL;
}
#endif

GContext
XGContextFromGC(
    TCL_UNUSED(GC))
{
    /*
     * TODO: currently a no-op
     */

    return 0;
}

Status
XSendEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Bool),
    TCL_UNUSED(long),
    TCL_UNUSED(XEvent *))
{
    Debugger();
    return 0;
}

int
XClearWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window))
{
    return Success;
}

/*
int
XDrawPoint(
    Display* display,
    Drawable d,
    GC gc,
    int x,
    int y)
{
    return Success;
}

int
XDrawPoints(
    Display* display,
    Drawable d,
    GC gc,
    XPoint* points,
    int npoints,
    int mode)
{
    return Success;
}
*/

int
XWarpPointer(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    return Success;
}

int
XQueryColor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    XColor* def_in_out)
{
    unsigned long p;
    unsigned char r, g, b;
    XColor *d = def_in_out;

    p		= d->pixel;
    r		= (p & 0x00FF0000) >> 16;
    g		= (p & 0x0000FF00) >> 8;
    b		= (p & 0x000000FF);
    d->red	= (r << 8) | r;
    d->green	= (g << 8) | g;
    d->blue	= (b << 8) | b;
    d->flags	= DoRed|DoGreen|DoBlue;
    d->pad	= 0;
    return Success;
}

Bool
XTranslateCoordinates(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    TCL_UNUSED(Window *))
{
    return 0;
}

int
XSetCommand(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(char **),
    TCL_UNUSED(int))
{
    return Success;
}

int
XGetWindowAttributes(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(XWindowAttributes *))
{
    return Success;
}

Status
XGetWMColormapWindows(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window **),
    TCL_UNUSED(int *))
{
    return Success;
}

int
XIconifyWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int))
{
    return Success;
}

XHostAddress *
XListHosts(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int *),
    TCL_UNUSED(Bool *))
{
    return NULL;
}

int
XLookupColor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    TCL_UNUSED(_Xconst char *),
    TCL_UNUSED(XColor *),
    TCL_UNUSED(XColor *))
{
    return Success;
}

int
XNextEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XEvent *))
{
    return Success;
}

int
XPutBackEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XEvent *))
{
    return Success;
}

int
XQueryColors(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    XColor* defs_in_out,
    int ncolors)
{
    int i;
    unsigned long p;
    unsigned char r, g, b;
    XColor *d = defs_in_out;

    for (i = 0; i < ncolors; i++, d++) {
	p		= d->pixel;
	r		= (p & 0x00FF0000) >> 16;
	g		= (p & 0x0000FF00) >> 8;
	b		= (p & 0x000000FF);
	d->red		= (r << 8) | r;
	d->green	= (g << 8) | g;
	d->blue		= (b << 8) | b;
	d->flags	= DoRed|DoGreen|DoBlue;
	d->pad		= 0;
    }
    return Success;
}

int
XQueryTree(

    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window **),
    TCL_UNUSED(unsigned int *))
{
    return 0;
}


int
XGetWindowProperty(
    Display *display,
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom),
    TCL_UNUSED(long),
    TCL_UNUSED(long),
    TCL_UNUSED(Bool),
    TCL_UNUSED(Atom),
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    TCL_UNUSED(unsigned char **))
{
    display->request++;
    *actual_type_return = None;
    *actual_format_return = *bytes_after_return = 0;
    *nitems_return = 0;
    return 0;
}

int
XWindowEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(long),
    TCL_UNUSED(XEvent *))
{
    return Success;
}

int
XWithdrawWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int))
{
    return Success;
}

int
XmbLookupString(
    TCL_UNUSED(XIC),
    TCL_UNUSED(XKeyPressedEvent *),
    TCL_UNUSED(char *),
    TCL_UNUSED(int),
    TCL_UNUSED(KeySym *),
    TCL_UNUSED(Status *))
{
    return Success;
}

int
XRefreshKeyboardMapping(
    TCL_UNUSED(XMappingEvent *))
{
    /* used by tkXEvent.c */
    Debugger();
    return Success;
}

int
XSetIconName(
    Display* display,
    TCL_UNUSED(Window),
    TCL_UNUSED(const char *))
{
    /*
     * This is a no-op, no icon name for Macs.
     */
    display->request++;
    return Success;
}

int
XForceScreenSaver(
    Display* display,
    TCL_UNUSED(int))
{
    /*
     * This function is just a no-op. It is defined to reset the screen saver.
     * However, there is no real way to do this on a Mac. Let me know if there
     * is!
     */

    display->request++;

















    return Success;
}


int
XSetClipRectangles(
    Display *d,
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    TCL_UNUSED(int))
{
    TkRegion clipRgn = TkCreateRegion();

    while (n--) {
    	XRectangle rect = *rectangles;

    	rect.x += clip_x_origin;
    	rect.y += clip_y_origin;
    	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
    	rectangles++;
    }
    TkSetRegion(d, gc, clipRgn);
    TkDestroyRegion(clipRgn);
    return 1;
}


/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo







|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|
|












|
|





>
>
>
>
>
>
>


|







|

















|











|










|

|
|
|
|
|
|
|
|


<


|

|
|
|


<




|
|








|
|
|




















|










|
|
|
|
|





|

|
|

<











<











<





|
|
|
|
|
|
|
|
|




|

|
|















<


<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|



















<



|
>
|
|
|
|
|
|








|
|
|
|
|
|




|








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|



<


|


|
|





<


|


|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
>








|




|

|
|
|
|





>
>







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

614
615













616











































































617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677































678
679
680
681
682

683
684
685
686
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
 *	was previously on the stack.
 *
 *----------------------------------------------------------------------
 */

static XID
MacXIdAlloc(
    Display *display)		/* Display for which to allocate. */
{
    static long int cur_id = 100;
    /*
     * Some special XIds are reserved
     *   - this is why we start at 100
     */

    return ++cur_id;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWindowWasRecentlyDeleted --
 *
 *	Tries to determine whether the given window was recently deleted.
 *	Called from the generic code error handler to attempt to deal with
 *	async BadWindow errors under some circumstances.
 *
 * Results:
 *	Always 0, we do not keep this information on the Mac, so we do not
 *	know whether the window was destroyed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpWindowWasRecentlyDeleted(
    Window win,
    TkDisplay *dispPtr)
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * DefaultErrorHandler --
 *
 *	This procedure is the default X error handler. Tk uses it's own error
 *	handler so this call should never be called.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This function will call panic and exit.
 *
 *----------------------------------------------------------------------
 */

static int
DefaultErrorHandler(
    Display* display,
    XErrorEvent* err_evt)
{
    /*
     * This call should never be called. Tk replaces it with its own error
     * handler.
     */

    Tcl_Panic("Warning hit bogus error handler!");
    return 0;
}

char *
XGetAtomName(
    Display * display,
    Atom atom)
{
    display->request++;
    return NULL;
}

int
_XInitImageFuncPtrs(
    XImage *image)
{
    return 0;
}

XErrorHandler
XSetErrorHandler(
    XErrorHandler handler)
{
    return DefaultErrorHandler;
}

Window
XRootWindow(
    Display *display,
    int screen_number)
{
    display->request++;
    return ROOT_ID;
}

int
XGetGeometry(
    Display *display,
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWindow *winPtr = ((MacDrawable *) d)->winPtr;

    display->request++;
    *root_return = ROOT_ID;
    if (winPtr) {
	*x_return = Tk_X(winPtr);
	*y_return = Tk_Y(winPtr);
	*width_return = Tk_Width(winPtr);
	*height_return = Tk_Height(winPtr);
	*border_width_return = winPtr->changes.border_width;
	*depth_return = Tk_Depth(winPtr);
    } else {
	CGSize size = ((MacDrawable *) d)->size;
	*x_return = 0;
	*y_return =  0;
	*width_return = size.width;
	*height_return = size.height;
	*border_width_return = 0;
	*depth_return = 32;
    }
    return 1;
}

void
XChangeProperty(
    Display* display,
    Window w,
    Atom property,
    Atom type,
    int format,
    int mode,
    _Xconst unsigned char* data,
    int nelements)
{
    Debugger();

}

void
XSelectInput(
    Display* display,
    Window w,
    long event_mask)
{
    Debugger();

}

int
XBell(
    Display* display,
    int percent)
{
    NSBeep();
    return Success;
}

#if 0
void
XSetWMNormalHints(
    Display* display,
    Window w,
    XSizeHints* hints)
{
    /*
     * Do nothing. Shouldn't even be called.
     */
}

XSizeHints *
XAllocSizeHints(void)
{
    /*
     * Always return NULL. Tk code checks to see if NULL is returned & does
     * nothing if it is.
     */

    return NULL;
}
#endif

GContext
XGContextFromGC(
    GC gc)
{
    /*
     * TODO: currently a no-op
     */

    return 0;
}

Status
XSendEvent(
    Display* display,
    Window w,
    Bool propagate,
    long event_mask,
    XEvent* event_send)
{
    Debugger();
    return 0;
}

void
XClearWindow(
    Display* display,
    Window w)
{

}

/*
int
XDrawPoint(
    Display* display,
    Drawable d,
    GC gc,
    int x,
    int y)
{

}

int
XDrawPoints(
    Display* display,
    Drawable d,
    GC gc,
    XPoint* points,
    int npoints,
    int mode)
{

}
*/

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)
{
    return Success;
}

void
XQueryColor(
    Display* display,
    Colormap colormap,
    XColor* def_in_out)
{
    unsigned long p;
    unsigned char r, g, b;
    XColor *d = def_in_out;

    p		= d->pixel;
    r		= (p & 0x00FF0000) >> 16;
    g		= (p & 0x0000FF00) >> 8;
    b		= (p & 0x000000FF);
    d->red	= (r << 8) | r;
    d->green	= (g << 8) | g;
    d->blue	= (b << 8) | b;
    d->flags	= DoRed|DoGreen|DoBlue;
    d->pad	= 0;

}














void











































































XQueryColors(
    Display* display,
    Colormap colormap,
    XColor* defs_in_out,
    int ncolors)
{
    int i;
    unsigned long p;
    unsigned char r, g, b;
    XColor *d = defs_in_out;

    for (i = 0; i < ncolors; i++, d++) {
	p		= d->pixel;
	r		= (p & 0x00FF0000) >> 16;
	g		= (p & 0x0000FF00) >> 8;
	b		= (p & 0x000000FF);
	d->red		= (r << 8) | r;
	d->green	= (g << 8) | g;
	d->blue		= (b << 8) | b;
	d->flags	= DoRed|DoGreen|DoBlue;
	d->pad		= 0;
    }

}

int
XQueryTree(display, w, root_return, parent_return, children_return,
	nchildren_return)
    Display* display;
    Window w;
    Window* root_return;
    Window* parent_return;
    Window** children_return;
    unsigned int* nchildren_return;
{
    return 0;
}


int
XGetWindowProperty(
    Display *display,
    Window w,
    Atom property,
    long long_offset,
    long long_length,
    Bool delete,
    Atom req_type,
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    unsigned char ** prop_return)
{
    display->request++;
    *actual_type_return = None;
    *actual_format_return = *bytes_after_return = 0;
    *nitems_return = 0;
    return 0;
}

void































XRefreshKeyboardMapping(
    XMappingEvent *x)
{
    /* used by tkXEvent.c */
    Debugger();

}

void
XSetIconName(
    Display* display,
    Window w,
    const char *icon_name)
{
    /*
     * This is a no-op, no icon name for Macs.
     */
    display->request++;

}

void
XForceScreenSaver(
    Display* display,
    int mode)
{
    /*
     * This function is just a no-op. It is defined to reset the screen saver.
     * However, there is no real way to do this on a Mac. Let me know if there
     * is!
     */

    display->request++;
}

void
Tk_FreeXId(
    Display *display,
    XID xid)
{
    /* no-op function needed for stubs implementation. */
}

int
XSync(
    Display *display,
    Bool discard)
{
    TkMacOSXFlushWindows();
    display->request++;
    return 0;
}

#if 0
int
XSetClipRectangles(
    Display *d,
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    int ordering)
{
    TkRegion clipRgn = TkCreateRegion();

    while (n--) {
	XRectangle rect = *rectangles;

	rect.x += clip_x_origin;
	rect.y += clip_y_origin;
	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
	rectangles++;
    }
    TkSetRegion(d, gc, clipRgn);
    TkDestroyRegion(clipRgn);
    return 1;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo
934
935
936
937
938
939
940





































































































































































































































































































































































941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159


1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206









1207
1208
1209

1210



1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
	    ProtocolVersion(Tk_Display(tkwin)),
	    ProtocolRevision(Tk_Display(tkwin)));
    snprintf(buffer2, sizeof(buffer2), " Mac OS X %x",
	    VendorRelease(Tk_Display(tkwin)));
    Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
	    buffer2, NULL);
}






































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * XChangeWindowAttributes, XSetWindowBackground,
 * XSetWindowBackgroundPixmap, XSetWindowBorder, XSetWindowBorderPixmap,
 * XSetWindowBorderWidth, XSetWindowColormap
 *
 *	These functions are all no-ops. They all have equivalent Tk calls that
 *	should always be used instead.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XChangeWindowAttributes(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned long),
    TCL_UNUSED(XSetWindowAttributes *))
{
    return Success;
}

int
XSetWindowBackground(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned long))
{
    return Success;
}

int
XSetWindowBackgroundPixmap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Pixmap))
{
    return Success;
}

int
XSetWindowBorder(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned long))
{
    return Success;
}

int
XSetWindowBorderPixmap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Pixmap))
{
    return Success;
}

int
XSetWindowBorderWidth(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned int))
{
    return Success;
}

int
XSetWindowColormap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Colormap))
{
    Debugger();
    return Success;
}

Status
XStringListToTextProperty(
    TCL_UNUSED(char **),
    TCL_UNUSED(int),
    TCL_UNUSED(XTextProperty *))
{
    Debugger();
    return Success;
}

void
XSetWMClientMachine(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(XTextProperty *))
{
    Debugger();
}

XIC
XCreateIC(TCL_UNUSED(XIM), ...)
{
    Debugger();
    return (XIC) 0;
}

int
XDeleteProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom))
{
    return Success;
}

int
XGetInputFocus(
    Display *display,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *))
{
    display->request++;
    return Success;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{
    display->request++;
    return NULL;
}

int
XUngrabServer(
    TCL_UNUSED(Display *))
{
    return 0;
}

int
XFreeCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Cursor))
{
    return Success;
}

int
XNoOp(
    Display *display)
{
	display->request++;
    return 0;
}

int
XGrabServer(
    TCL_UNUSED(Display *))
{
    return 0;
}

int
XFree(
    void *data)
{
	if ((data) != NULL) {
		ckfree(data);
	}
    return 0;
}

int
XFlush(
    TCL_UNUSED(Display *))
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetDefaultScreenName --
 *
 *	Returns the name of the screen that Tk should use during
 *	initialization.
 *
 * Results:
 *	Returns a statically allocated string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    TCL_UNUSED(Tcl_Interp *),
    const char *screenName)		/* If NULL, use default string. */
{

    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = macScreenName;
    }
    return screenName;


}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
 *	Return the number of milliseconds the user was inactive.
 *
 * Results:
 *	The number of milliseconds the user has been inactive, or -1 if
 *	querying the inactive time is not supported.
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
    TCL_UNUSED(Display *))
{
    io_registry_entry_t regEntry;
    CFMutableDictionaryRef props = NULL;
    CFTypeRef timeObj;
    long ret = -1l;
    uint64_t time;
    IOReturn result;

    regEntry = IOServiceGetMatchingService(0,
	    IOServiceMatching("IOHIDSystem"));

    if (regEntry == 0) {
	return -1l;
    }

    result = IORegistryEntryCreateCFProperties(regEntry, &props,
	    kCFAllocatorDefault, 0);
    IOObjectRelease(regEntry);

    if (result != KERN_SUCCESS || props == NULL) {
	return -1l;
    }

    timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime"));

    if (timeObj) {









	    CFNumberGetValue((CFNumberRef)timeObj,
		    kCFNumberSInt64Type, &time);
	    /* Convert nanoseconds to milliseconds. */

	    ret = (long) (time/kMillisecondScale);



    }
    /* Cleanup */
    CFRelease(props);

    /*
     * If the idle time reported by the system is larger than the elapsed
     * time since the last reset, return the elapsed time.
     */
    long elapsed = (long)(TkpGetMS() - lastInactivityReset);
    if (ret > elapsed) {
    	ret = elapsed;
    }

    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ResetUserInactiveTime --







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|

|
|
|
|

<


|

|
|
|

<


|

|
|
|

<


|

|
|
|

<


|

|
|
|

<


|

|
|
|

<


|

|
|
|


<




|
|
|


|




|
|
|





|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















|


>




>
>




















|








|

















>
>
>
>
>
>
>
>
>



>

>
>
>




<
<
<
<
<
<
<
<
<







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215

1216
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252


















































































1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349









1350
1351
1352
1353
1354
1355
1356
	    ProtocolVersion(Tk_Display(tkwin)),
	    ProtocolRevision(Tk_Display(tkwin)));
    snprintf(buffer2, sizeof(buffer2), " Mac OS X %x",
	    VendorRelease(Tk_Display(tkwin)));
    Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
	    buffer2, NULL);
}

#pragma mark XImage handling

/*
 *----------------------------------------------------------------------
 *
 * XCreateImage --
 *
 *	Allocates storage for a new XImage.
 *
 * Results:
 *	Returns a newly allocated XImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    Visual* visual,
    unsigned int depth,
    int format,
    int offset,
    char* data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage *ximage;
    display->request++;
    ximage = (XImage *) ckalloc(sizeof(XImage));

    ximage->height = height;
    ximage->width = width;
    ximage->depth = depth;
    ximage->xoffset = offset;
    ximage->format = format;
    ximage->data = data;
    ximage->obdata = NULL;

    if (format == ZPixmap) {
	ximage->bits_per_pixel = 32;
	ximage->bitmap_unit = 32;
    } else {
	ximage->bits_per_pixel = 1;
	ximage->bitmap_unit = 8;
    }
    if (bitmap_pad) {
	ximage->bitmap_pad = bitmap_pad;
    } else {
	/* Use 16 byte alignment for best Quartz perfomance */
	ximage->bitmap_pad = 128;
    }
    if (bytes_per_line) {
	ximage->bytes_per_line = bytes_per_line;
    } else {
	ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
		(ximage->bitmap_pad - 1)) >> 3) &
		~((ximage->bitmap_pad >> 3) - 1);
    }
#ifdef WORDS_BIGENDIAN
    ximage->byte_order = MSBFirst;
    ximage->bitmap_bit_order = MSBFirst;
#else
    ximage->byte_order = LSBFirst;
    ximage->bitmap_bit_order = LSBFirst;
#endif
    ximage->red_mask = 0x00FF0000;
    ximage->green_mask = 0x0000FF00;
    ximage->blue_mask = 0x000000FF;
    ximage->f.create_image = NULL;
    ximage->f.destroy_image = DestroyImage;
    ximage->f.get_pixel = ImageGetPixel;
    ximage->f.put_pixel = ImagePutPixel;
    ximage->f.sub_image = NULL;
    ximage->f.add_pixel = NULL;

    return ximage;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *     constructed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

XImage *
XGetImage(
    Display *display,
    Drawable d,
    int x,
    int y,
    unsigned int width,
    unsigned int height,
    unsigned long plane_mask,
    int format)
{
    NSBitmapImageRep *bitmap_rep;
    NSUInteger         bitmap_fmt;
    XImage *       imagePtr = NULL;
    char *           bitmap = NULL;
    char *           image_data=NULL;
    int	        depth = 32;
    int	        offset = 0;
    int	        bitmap_pad = 0;
    int	        bytes_per_row = 4*width;
    int                size;
    TkMacOSXDbgMsg("XGetImage");
    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    /* This happens all the time.
	    TkMacOSXDbgMsg("XGetImage: empty image requested");
	    */
	    return NULL;
	}

	bitmap_rep =  BitmapRepFromDrawableRect(d, x, y,width, height);
	bitmap_fmt = [bitmap_rep bitmapFormat];

	if ( bitmap_rep == Nil                     ||
	     (bitmap_fmt != 0 && bitmap_fmt != 1)  ||
	     [bitmap_rep samplesPerPixel] != 4     ||
	     [bitmap_rep isPlanar] != 0               ) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}

	NSSize image_size = NSMakeSize(width, height);
	NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
	[ns_image addRepresentation:bitmap_rep];

	/* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
	if ( [bitmap_rep isPlanar ] == 0 &&
	     [bitmap_rep samplesPerPixel] == 4 ) {
	    bytes_per_row = [bitmap_rep bytesPerRow];
	    size = bytes_per_row*height;
	    image_data = (char*)[bitmap_rep bitmapData];
	    if ( image_data ) {
		int row, n, m;
		bitmap = ckalloc(size);
		/*
		  Oddly enough, the bitmap has the top row at the beginning,
		  and the pixels are in BGRA or ABGR format.
		*/
		if (bitmap_fmt == 0) {
		    /* BGRA */
		    for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
			for (m=n; m<n+bytes_per_row; m+=4) {
			    *(bitmap+m)   = *(image_data+m+2);
			    *(bitmap+m+1) = *(image_data+m+1);
			    *(bitmap+m+2) = *(image_data+m);
			    *(bitmap+m+3) = *(image_data+m+3);
			}
		    }
		} else {
		    /* ABGR */
		    for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
			for (m=n; m<n+bytes_per_row; m+=4) {
			    *(bitmap+m)   = *(image_data+m+3);
			    *(bitmap+m+1) = *(image_data+m+2);
			    *(bitmap+m+2) = *(image_data+m+1);
			    *(bitmap+m+3) = *(image_data+m);
			}
		    }
		}
	    }
	}
	if (bitmap) {
	    imagePtr = XCreateImage(display, NULL, depth, format, offset,
				    (char*)bitmap, width, height, bitmap_pad, bytes_per_row);
	    [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/
	    [ns_image release];
	}
    } else {
	TkMacOSXDbgMsg("Could not extract image from drawable.");
    }
    return imagePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyImage --
 *
 *	Destroys storage associated with an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deallocates the image.
 *
 *----------------------------------------------------------------------
 */

static int
DestroyImage(
    XImage *image)
{
    if (image) {
	if (image->data) {
	    ckfree(image->data);
	}
	ckfree((char*) image);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageGetPixel --
 *
 *	Get a single pixel from an image.
 *
 * Results:
 *	Returns the 32 bit pixel value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned long
ImageGetPixel(
    XImage *image,
    int x,
    int y)
{
    unsigned char r = 0, g = 0, b = 0;

    if (image && image->data) {
	unsigned char *srcPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	    case 32: {
		r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
		g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
		b = (*((unsigned int*) srcPtr)      ) & 0xff;
		/*if (image->byte_order == LSBFirst) {
		    r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
		} else {
		    r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
		}*/
		break;
	    }
	    case 16:
		r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
		g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
		b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
		break;
	    case 8:
		r = (*srcPtr << 2) & 0xc0;
		g = (*srcPtr << 4) & 0xc0;
		b = (*srcPtr << 6) & 0xc0;
		r |= r >> 2 | r >> 4 | r >> 6;
		g |= g >> 2 | g >> 4 | g >> 6;
		b |= b >> 2 | b >> 4 | b >> 6;
		break;
	    case 4: {
		unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
		r = (c & 0x04) ? 0xff : 0;
		g = (c & 0x02) ? 0xff : 0;
		b = (c & 0x01) ? 0xff : 0;
		break;
		}
	    case 1:
		r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
		break;
	}
    }
    return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
 *	Set a single pixel in an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImagePutPixel(
    XImage *image,
    int x,
    int y,
    unsigned long pixel)
{
    if (image && image->data) {
	unsigned char r = ((pixel & image->red_mask)   >> 16) & 0xff;
	unsigned char g = ((pixel & image->green_mask) >>  8) & 0xff;
	unsigned char b = ((pixel & image->blue_mask)       ) & 0xff;
	unsigned char *dstPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	    case 32:
		*((unsigned int*) dstPtr) = (0xff << 24) | (r << 16) |
			(g << 8) | b;
		/*if (image->byte_order == LSBFirst) {
		    dstPtr[3] = 0xff; dstPtr[2] = r; dstPtr[1] = g; dstPtr[0] = b;
		} else {
		    dstPtr[0] = 0xff; dstPtr[1] = r; dstPtr[2] = g; dstPtr[3] = b;
		}*/
		break;
	    case 16:
		*((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
		break;
	    case 8:
		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
			((b & 0xc0) >> 6);
		break;
	    case 4: {
		unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
			((b & 0x80) >> 7);
		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
			((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
		break;
		}
	    case 1:
		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
			(*dstPtr & ~(0x80 >> (x % 8)));
		break;
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * XChangeWindowAttributes, XSetWindowBackground,
 * XSetWindowBackgroundPixmap, XSetWindowBorder, XSetWindowBorderPixmap,
 * XSetWindowBorderWidth, XSetWindowColormap
 *
 *	These functions are all no-ops. They all have equivalent Tk calls that
 *	should always be used instead.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
XChangeWindowAttributes(
    Display *display,
    Window w,
    unsigned long value_mask,
    XSetWindowAttributes *attributes)
{

}

void
XSetWindowBackground(
    Display *display,
    Window window,
    unsigned long value)
{

}

void
XSetWindowBackgroundPixmap(
    Display *display,
    Window w,
    Pixmap background_pixmap)
{

}

void
XSetWindowBorder(
    Display *display,
    Window w,
    unsigned long border_pixel)
{

}

void
XSetWindowBorderPixmap(
    Display *display,
    Window w,
    Pixmap border_pixmap)
{

}

void
XSetWindowBorderWidth(
    Display *display,
    Window w,
    unsigned int width)
{

}

void
XSetWindowColormap(
    Display *display,
    Window w,
    Colormap colormap)
{
    Debugger();

}

Status
XStringListToTextProperty(
    char **list,
    int count,
    XTextProperty *text_prop_return)
{
    Debugger();
    return (Status) 0;
}

void
XSetWMClientMachine(
    Display *display,
    Window w,
    XTextProperty *text_prop)
{
    Debugger();
}

XIC
XCreateIC(void)
{
    Debugger();
    return (XIC) 0;
}



















































































/*
 *----------------------------------------------------------------------
 *
 * TkGetDefaultScreenName --
 *
 *	Returns the name of the screen that Tk should use during
 *	initialization.
 *
 * Results:
 *	Returns a statically allocated string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Not used. */
    const char *screenName)		/* If NULL, use default string. */
{
#if 0
    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = macScreenName;
    }
    return screenName;
#endif
    return macScreenName;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
 *	Return the number of milliseconds the user was inactive.
 *
 * Results:
 *	The number of milliseconds the user has been inactive, or -1 if
 *	querying the inactive time is not supported.
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
    Display *dpy)
{
    io_registry_entry_t regEntry;
    CFMutableDictionaryRef props = NULL;
    CFTypeRef timeObj;
    long ret = -1l;
    uint64_t time;
    IOReturn result;

    regEntry = IOServiceGetMatchingService(kIOMasterPortDefault,
	    IOServiceMatching("IOHIDSystem"));

    if (regEntry == 0) {
	return -1l;
    }

    result = IORegistryEntryCreateCFProperties(regEntry, &props,
	    kCFAllocatorDefault, 0);
    IOObjectRelease(regEntry);

    if (result != KERN_SUCCESS || props == NULL) {
	return -1l;
    }

    timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime"));

    if (timeObj) {
	CFTypeID type = CFGetTypeID(timeObj);

	if (type == CFDataGetTypeID()) { /* Jaguar */
	    CFDataGetBytes((CFDataRef) timeObj,
		    CFRangeMake(0, sizeof(time)), (UInt8 *) &time);
	    /* Convert nanoseconds to milliseconds. */
	    /* ret /= kMillisecondScale; */
	    ret = (long) (time/kMillisecondScale);
	} else if (type == CFNumberGetTypeID()) { /* Panther+ */
	    CFNumberGetValue((CFNumberRef)timeObj,
		    kCFNumberSInt64Type, &time);
	    /* Convert nanoseconds to milliseconds. */
	    /* ret /= kMillisecondScale; */
	    ret = (long) (time/kMillisecondScale);
	} else {
	    ret = -1l;
	}
    }
    /* Cleanup */
    CFRelease(props);










    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ResetUserInactiveTime --
1239
1240
1241
1242
1243
1244
1245
1246
1247





1248
















1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    TCL_UNUSED(Display *))
{





    lastInactivityReset = TkpGetMS();
















}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    IOGPoint loc = {0};
    kern_return_t kr;
    NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0};
    enum { kNULLEventPostThrottle = 10 };
    static io_connect_t io_connection = MACH_PORT_NULL;

    if (io_connection == MACH_PORT_NULL) {
	io_service_t service = IOServiceGetMatchingService(
		kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass));

	if (service == MACH_PORT_NULL) {
	    return;
	}
	kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType,
		&io_connection);
	IOObjectRelease(service);
	if (kr != KERN_SUCCESS) {
	    return;
	}
    }
    kr = IOHIDPostEvent(io_connection, NX_NULLEVENT, loc, &nullEvent.data,
	    FALSE, 0, FALSE);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/ttkMacOSXTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262



1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296

1297
1298
1299
1300

1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403


1404
1405
1406


1407



1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510

1511



1512
1513
1514
1515
1516
1517
1518
1519
1520

1521
1522

1523
1524
1525
1526

1527
1528

1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573

1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647








1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682

1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720


1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751

1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773

1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842



1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872

1873
1874
1875

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045


2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070

2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209



2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783

2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810

2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908

2909
2910
2911
2912
2913
2914
2915
2916


2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024

3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298

/*
 * ttkMacOSXTheme.c --
 *
 *      Tk theme engine for Mac OSX, using the Appearance Manager API.
 *
 * Copyright (c) 2004 Joe English
 * Copyright (c) 2005 Neil Madden
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 * Copyright 2009 Kevin Walzer/WordTech Communications LLC.
 * Copyright 2019 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * See also:
 *
 * <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *      Appearance_Manager/appearance_manager/APIIndex.html >
 *
 * Notes:
 *      "Active" means different things in Mac and Tk terminology --
 *      On Aqua, widgets are "Active" if they belong to the foreground window,
 *      "Inactive" if they are in a background window.  Tk uses the term
 *      "active" to mean that the mouse cursor is over a widget; aka "hover",

 *      "prelight", or "hot-tracked".  Aqua doesn't use this kind of feedback.
 *
 *      The QuickDraw/Carbon coordinate system is relative to the top-level
 *      window, not to the Tk_Window.  BoxToRect() accounts for this.

 */

#include "tkMacOSXPrivate.h"
#include "ttk/ttkTheme.h"
#include <math.h>

/*
 * Macros for handling drawing contexts.

 */

#define BEGIN_DRAWING(d) {	   \
	TkMacOSXDrawingContext dc; \
	if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {return;}
#define END_DRAWING \
    TkMacOSXRestoreDrawingContext(&dc);}

#define HIOrientation kHIThemeOrientationNormal
#define NoThemeMetric 0xFFFFFFFF

#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */

#define TTK_STATE_FIRST_TAB     TTK_STATE_USER1
#define TTK_STATE_LAST_TAB      TTK_STATE_USER2
#define TTK_TREEVIEW_STATE_SORTARROW    TTK_STATE_USER1

/*
 * Colors and gradients used in Dark Mode.
 */

static CGFloat darkButtonFace[4] = {
    112.0 / 255, 113.0 / 255, 115.0 / 255, 1.0
};
static CGFloat darkPressedBevelFace[4] = {
    135.0 / 255, 136.0 / 255, 138.0 / 255, 1.0
};
static CGFloat darkSelectedBevelFace[4] = {
    162.0 / 255, 163.0 / 255, 165.0 / 255, 1.0
};
static CGFloat darkDisabledButtonFace[4] = {
    86.0 / 255, 87.0 / 255, 89.0 / 255, 1.0
};
static CGFloat darkInactiveSelectedTab[4] = {
    159.0 / 255, 160.0 / 255, 161.0 / 255, 1.0
};
static CGFloat darkFocusRing[4] = {
    38.0 / 255, 113.0 / 255, 159.0 / 255, 1.0
};
static CGFloat darkFocusRingTop[4] = {
    50.0 / 255, 124.0 / 255, 171.0 / 255, 1.0
};
static CGFloat darkFocusRingBottom[4] = {
    57.0 / 255, 130.0 / 255, 176.0 / 255, 1.0
};
static CGFloat darkTabSeparator[4] = {0.0, 0.0, 0.0, 0.25};
static CGFloat darkTrack[4] = {1.0, 1.0, 1.0, 0.25};
static CGFloat darkFrameTop[4] = {1.0, 1.0, 1.0, 0.0625};
static CGFloat darkFrameBottom[4] = {1.0, 1.0, 1.0, 0.125};
static CGFloat darkFrameAccent[4] = {0.0, 0.0, 0.0, 0.0625};
static CGFloat darkTopGradient[8] = {
    1.0, 1.0, 1.0, 0.3,
    1.0, 1.0, 1.0, 0.0
};
static CGFloat darkBackgroundGradient[8] = {
    0.0, 0.0, 0.0, 0.1,
    0.0, 0.0, 0.0, 0.25
};
static CGFloat darkInactiveGradient[8] = {
    89.0 / 255, 90.0 / 255, 93.0 / 255, 1.0,
    119.0 / 255, 120.0 / 255, 122.0 / 255, 1.0
};
static CGFloat darkSelectedGradient[8] = {
    23.0 / 255, 111.0 / 255, 232.0 / 255, 1.0,
    20.0 / 255, 94.0 / 255,  206.0 / 255, 1.0
};
static CGFloat pressedPushButtonGradient[8] = {
    35.0 / 255, 123.0 / 255, 244.0 / 255, 1.0,
    30.0 / 255, 114.0 / 255, 235.0 / 255, 1.0
};

/*
 * When building on systems earlier than 10.8 there is no reasonable way to
 * convert an NSColor to a CGColor.  We do run-time checking of the OS version,
 * and never need the CGColor property on older systems, so we can use this
 * CGCOLOR macro, which evaluates to NULL without raising compiler warnings.
 * Similarly, we never draw rounded rectangles on older systems which did not
 * have CGPathCreateWithRoundedRect, so we just redefine it to return NULL.
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
#define CGCOLOR(nscolor) nscolor.CGColor
#else
#define CGCOLOR(nscolor) (0 ? (CGColorRef) nscolor : NULL)
#define CGPathCreateWithRoundedRect(w, x, y, z) NULL
#endif

/*
 * If we try to draw a rounded rectangle with too large of a radius
 * CoreGraphics will raise a fatal exception.  This macro returns if
 * the width or height is less than twice the radius.  Presumably this
 * only happens when a widget has not yet been configured and has size
 * 1x1.
 */

#define CHECK_RADIUS(radius, bounds)                                         \
    if (radius > bounds.size.width / 2 || radius > bounds.size.height / 2) { \
        return;                                                              \
    }

/*----------------------------------------------------------------------
 * +++ Utilities.
 */

/*
 * BoxToRect --
 *    Convert a Ttk_Box in Tk coordinates relative to the given Drawable
 *    to a native Rect relative to the containing port.
 */

static inline CGRect BoxToRect(
    Drawable d,
    Ttk_Box b)
{
    MacDrawable *md = (MacDrawable *)d;
    CGRect rect;

    rect.origin.y       = b.y + md->yOff;
    rect.origin.x       = b.x + md->xOff;
    rect.size.height    = b.height;
    rect.size.width     = b.width;

    return rect;
}

/*
 * Table mapping Tk states to Appearance manager ThemeStates
 */

static Ttk_StateTable ThemeStateTable[] = {
    {kThemeStateActive, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeStateUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeStatePressed, TTK_STATE_PRESSED, 0},
    {kThemeStateInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeStateActive, 0, 0}

    /* Others: Not sure what these are supposed to mean.  Up/Down have
     * something to do with "little arrow" increment controls...  Dunno what
     * a "Rollover" is.
     * NEM: Rollover is TTK_STATE_ACTIVE... but we don't handle that yet, by
     * the looks of things
     *
     * {kThemeStateRollover, 0, 0},
     * {kThemeStateUnavailableInactive, 0, 0}
     * {kThemeStatePressedUp, 0, 0},
     * {kThemeStatePressedDown, 0, 0}
     */
};

/*----------------------------------------------------------------------
 * NormalizeButtonBounds --
 *
 *      Apple's Human Interface Guidelines only allow three specific heights
 *      for most buttons: Regular, small and mini. We always use the regular
 *      size.  However, Ttk may provide an arbitrary bounding rectangle.  We
 *      always draw the button centered vertically on the rectangle, and
 *      having the same width as the rectangle.  This function returns the
 *      actual bounding rectangle that will be used in drawing the button.
 *
 *      The BevelButton is allowed to have arbitrary size, and also has
 *      external padding.  This is handled separately here.
 */

static CGRect NormalizeButtonBounds(
    SInt32 heightMetric,
    CGRect bounds)
{
    SInt32 height;

    if (heightMetric != (SInt32) NoThemeMetric) {
	ChkErr(GetThemeMetric, heightMetric, &height);
	bounds.origin.y += (bounds.size.height - height) / 2;
	bounds.size.height = height;
    }
    return bounds;
}

/*----------------------------------------------------------------------
 * +++ Backgrounds
 *
 * Support for contrasting background colors when GroupBoxes or Tabbed
 * panes are nested inside each other.  Early versions of macOS used ridged
 * borders, so do not need contrasting backgrounds.
 */

/*
 * For systems older than 10.14, [NSColor windowBackGroundColor] generates
 * garbage when called from this function.  In 10.14 it works correctly, and
 * must be used in order to have a background color which responds to Dark
 * Mode.  So we use this hard-wired RGBA color on the older systems which don't
 * support Dark Mode anyway.
 */

static const CGFloat WINDOWBACKGROUND[4] = {
    235.0 / 255, 235.0 / 255, 235.0 / 255, 1.0
};
static const CGFloat WHITERGBA[4] = {1.0, 1.0, 1.0, 1.0};
static const CGFloat BLACKRGBA[4] = {0.0, 0.0, 0.0, 1.0};

/*----------------------------------------------------------------------
 * GetBackgroundColor --
 *
 *      Fills the array rgba with the color coordinates for a background color.
 *      Start with the background color of a window's geometry container, or
 *      the standard ttk window background if there is no container. If the
 *      contrast parameter is nonzero, modify this color to be darker, for the
 *      aqua appearance, or lighter for the DarkAqua appearance.  This is
 *      primarily used by the Fill and Background elements.
 */

static void GetBackgroundColor(
    TCL_UNUSED(CGContextRef),
    Tk_Window tkwin,
    int contrast,
    CGFloat *rgba)
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *containerPtr = (TkWindow *)TkGetContainer(tkwin);

    while (containerPtr && containerPtr->privatePtr) {
	if (containerPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) {
	    break;
	}
	containerPtr = (TkWindow *)TkGetContainer(containerPtr);
    }
    if (containerPtr && containerPtr->privatePtr) {
	for (int i = 0; i < 4; i++) {
	    rgba[i] = containerPtr->privatePtr->fillRGBA[i];
	}
    } else {
	if ([NSApp macOSVersion] > 101300) {
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *windowColor = [[NSColor windowBackgroundColor]
		colorUsingColorSpace: deviceRGB];
	    [windowColor getComponents: rgba];
	} else {
	    for (int i = 0; i < 4; i++) {
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	}
    }
    if (contrast) {
	int isDark = (rgba[0] + rgba[1] + rgba[2] < 1.5);

	if (isDark) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] += 8.0 / 255.0;
	    }
	} else {
	    for (int i = 0; i < 3; i++) {
		rgba[i] -= 8.0 / 255.0;
	    }
	}
        if (winPtr->privatePtr) {
            winPtr->privatePtr->flags |= TTK_HAS_CONTRASTING_BG;
            for (int i = 0; i < 4; i++) {
                winPtr->privatePtr->fillRGBA[i] = rgba[i];
            }
        }
    }
}


/*----------------------------------------------------------------------
 * +++ Single Arrow Images --
 *
 * Used in ListHeaders and Comboboxes as well as disclosure triangles in
 * macOS 11.
 */

static void DrawDownArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4}, {x + size / 2, y + size / 4},
	{x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

static void DrawUpArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y + size / 4}, {x + size / 2, y - size / 4},
	{x + size, y + size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

static void DrawClosedDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4 - 1}, {x + size / 2, y}, {x, y + size / 4 + 1}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

static void DrawOpenDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4}, {x + size / 2, y + size / 2}, {x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------
 * +++ Double Arrow Buttons --
 *
 * Used in MenuButtons and SpinButtons.
 */

static void DrawUpDownArrows(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint bottomArrow[3] =
    {{x, y + 2}, {x + size / 2, y + 2 + size / 2}, {x + size, y + 2}};
    CGContextAddLines(context, bottomArrow, 3);
    CGPoint topArrow[3] =
    {{x, y - 2}, {x + size / 2, y - 2 - size / 2}, {x + size, y - 2}};
    CGContextAddLines(context, topArrow, 3);
    CGContextStrokePath(context);
}


/*----------------------------------------------------------------------
 * +++ FillButtonBackground --
 *
 *      Fills a rounded rectangle with a transparent black gradient.
 *      This is a no-op if building on 10.8 or older.
 */

static void FillButtonBackground(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius)
{
    CHECK_RADIUS(radius, bounds)

    CGPathRef path;
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    CGGradientRef backgroundGradient = CGGradientCreateWithColorComponents(
	deviceRGB.CGColorSpace, darkBackgroundGradient, NULL, 2);
    CGPoint backgroundEnd = {
	bounds.origin.x,
	bounds.origin.y + bounds.size.height
    };
    CGContextBeginPath(context);
    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGContextAddPath(context, path);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, backgroundGradient,
	bounds.origin, backgroundEnd, 0);
    CFRelease(path);
    CFRelease(backgroundGradient);
}

/*----------------------------------------------------------------------
 * +++ HighlightButtonBorder --
 *
 * Accent the top border of a rounded rectangle with a transparent
 * white gradient.
 */

static void HighlightButtonBorder(
    CGContextRef context,
    CGRect bounds)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    CGPoint topEnd = {bounds.origin.x, bounds.origin.y + 3};
    CGGradientRef topGradient = CGGradientCreateWithColorComponents(
	deviceRGB.CGColorSpace, darkTopGradient, NULL, 2);

    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextAddArc(context, bounds.origin.x + 4, bounds.origin.y + 4,
	4, PI, 3 * PI / 2, 0);
    CGContextAddArc(context, bounds.origin.x + bounds.size.width - 4,
	bounds.origin.y + 4, 4, 3 * PI / 2, 0, 0);
    CGContextReplacePathWithStrokedPath(context);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, topGradient, bounds.origin, topEnd,
	0.0);
    CGContextRestoreGState(context);
    CFRelease(topGradient);
}

/*----------------------------------------------------------------------
 * DrawGroupBox --
 *
 *      This is a standalone drawing procedure which draws the contrasting
 *      rounded rectangular box for LabelFrames and Notebook panes used in
 *      more recent versions of macOS.
 */

static void DrawGroupBox(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin)
{
    CHECK_RADIUS(4, bounds)

    CGPathRef path;
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *borderColor, *bgColor;
    static CGFloat border[4] = {1.0, 1.0, 1.0, 0.25};
    CGFloat fill[4];

    GetBackgroundColor(context, tkwin, 1, fill);
    bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
	count: 4];
    CGContextSetFillColorSpace(context, deviceRGB.CGColorSpace);
    CGContextSetFillColorWithColor(context, CGCOLOR(bgColor));
    path = CGPathCreateWithRoundedRect(bounds, 4, 4, NULL);
    CGContextClipToRect(context, bounds);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    borderColor = [NSColor colorWithColorSpace: deviceRGB components: border
	count: 4];
    CGContextSetFillColorWithColor(context, CGCOLOR(borderColor));
    [borderColor getComponents: fill];
    CGContextSetRGBFillColor(context, fill[0], fill[1], fill[2], fill[3]);

    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextReplacePathWithStrokedPath(context);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
 * SolidFillRoundedRectangle --
 *
 *      Fill a rounded rectangle with a specified solid color.
 */

static void SolidFillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    NSColor *color)
{
    CGPathRef path;

    CHECK_RADIUS(radius, bounds)
    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    if (!path) {
	return;
    }
    CGContextSetFillColorWithColor(context, CGCOLOR(color));
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
 * +++ DrawListHeader --
 *
 *      This is a standalone drawing procedure which draws column headers for
 *      a Treeview in the Aqua appearance.  The HITheme headers have not
 *      matched the native ones since OSX 10.8.  Note that the header image is
 *      ignored, but we draw arrows according to the state.
 */

static void DrawListHeader(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin,
    int state)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *strokeColor, *bgColor;
    static CGFloat borderRGBA[4] = {
	200.0 / 255, 200.0 / 255, 200.0 / 255, 1.0
    };
    static CGFloat separatorRGBA[4] = {
	220.0 / 255, 220.0 / 255, 220.0 / 255, 1.0
    };
    static CGFloat activeBgRGBA[4] = {
	238.0 / 255, 238.0 / 255, 238.0 / 255, 1.0
    };
    static CGFloat inactiveBgRGBA[4] = {
	246.0 / 255, 246.0 / 255, 246.0 / 255, 1.0
    };

    /*
     * Apple changes the background of a list header when the window is not
     * active.  But Ttk does not indicate that in the state of a TreeHeader.
     * So we have to query the Apple window manager.
     */

    NSWindow *win = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
    CGFloat *bgRGBA = [win isKeyWindow] ? activeBgRGBA : inactiveBgRGBA;
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};

    bgColor = [NSColor colorWithColorSpace: deviceRGB
	components: bgRGBA
	count: 4];
    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextSetFillColorSpace(context, deviceRGB.CGColorSpace);
    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGContextBeginPath(context);
    CGContextSetFillColorWithColor(context, CGCOLOR(bgColor));
    CGContextAddRect(context, bounds);
    CGContextFillPath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
	components: separatorRGBA
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
	components: borderRGBA
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, top, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;
	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Drawing procedures for widgets in Apple's "Dark Mode" (10.14 and up).
 *
 *      The HIToolbox does not support Dark Mode, and apparently never will,
 *      so to make widgets look "native" we have to provide analogues of the
 *      HITheme drawing functions to be used in DarkAqua.  We continue to use
 *      HITheme in Aqua, since it understands earlier versions of the OS.
 *
 *      Drawing the dark widgets requires NSColors that were introduced in OSX
 *      10.14, so we make some of these functions be no-ops when building on
 *      systems older than 10.14.
 */

/*----------------------------------------------------------------------
 * GradientFillRoundedRectangle --
 *
 *      Fill a rounded rectangle with a specified gradient.
 */

static void GradientFillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    CGFloat *colors,
    int numColors)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    CGPathRef path;
    CHECK_RADIUS(radius, bounds)

    CGPoint end = {
	bounds.origin.x,
	bounds.origin.y + bounds.size.height
    };
    CGGradientRef gradient = CGGradientCreateWithColorComponents(
	deviceRGB.CGColorSpace, colors, NULL, numColors);

    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, bounds.origin, end, 0);
    CFRelease(path);
    CFRelease(gradient);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkButton --
 *
 *      This is a standalone drawing procedure which draws PushButtons and
 *      PopupButtons in the Dark Mode style.
 */

static void DrawDarkButton(
    CGRect bounds,
    ThemeButtonKind kind,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    /*
     * To match the appearance of Apple's buttons we need to increase the
     * height by 1 pixel.
     */

    bounds.size.height += 1;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 5);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (kind == kThemePushButton && (state & TTK_STATE_PRESSED)) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    pressedPushButtonGradient, 2);
    } else if (kind == kThemePushButton &&
	       (state & TTK_STATE_ALTERNATE) &&
	       !(state & TTK_STATE_BACKGROUND)) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    darkSelectedGradient, 2);
    } else {
	if (state & TTK_STATE_DISABLED) {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkDisabledButtonFace
		count: 4];
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkButtonFace
		count: 4];
	}
	SolidFillRoundedRectangle(context, bounds, 4, faceColor);
    }

    /*
     * If this is a popup, draw the arrow button.
     */

    if ((kind == kThemePopupButton) | (kind == kThemeComboBox)) {
	CGRect arrowBounds = bounds;
	arrowBounds.size.width = 16;
	arrowBounds.origin.x += bounds.size.width - 16;

        /*
         * If the toplevel is front, paint the button blue.
         */

	if (!(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    GradientFillRoundedRectangle(context, arrowBounds, 4,
		darkSelectedGradient, 2);
	}
	if (kind == kThemePopupButton) {
	    DrawUpDownArrows(context, arrowBounds, 3, 7, WHITERGBA);
	} else {
	    DrawDownArrow(context, arrowBounds, 4, 8, WHITERGBA);
	}
    }

    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkIncDecButton --
 *
 *      This is a standalone drawing procedure which draws an IncDecButton
 *      (as used in a Spinbox) in the Dark Mode style.
 */

static void DrawDarkIncDecButton(
    CGRect bounds,
    ThemeDrawState drawState,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    bounds = CGRectInset(bounds, 0, -1);
    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 6);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (state & TTK_STATE_DISABLED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkDisabledButtonFace
	    count: 4];
    } else {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkButtonFace
	    count: 4];
    }
    SolidFillRoundedRectangle(context, bounds, 4, faceColor);

    /*
     * If pressed, paint the appropriate half blue.
     */

    if (state & TTK_STATE_PRESSED) {
	CGRect clip = bounds;
	clip.size.height /= 2;
	CGContextSaveGState(context);
	if (drawState == kThemeStatePressedDown) {
	    clip.origin.y += clip.size.height;
	}
	CGContextClipToRect(context, clip);
	GradientFillRoundedRectangle(context, bounds, 5,
	    darkSelectedGradient, 2);
	CGContextRestoreGState(context);
    }
    DrawUpDownArrows(context, bounds, 3, 5, WHITERGBA);
    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkBevelButton --
 *
 *      This is a standalone drawing procedure which draws RoundedBevelButtons
 *      in the Dark Mode style.
 */

static void DrawDarkBevelButton(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 5);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (state & TTK_STATE_PRESSED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkPressedBevelFace
	    count: 4];
    } else if ((state & TTK_STATE_DISABLED) ||
	(state & TTK_STATE_ALTERNATE)) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkDisabledButtonFace
	    count: 4];
    } else if (state & TTK_STATE_SELECTED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkSelectedBevelFace
	    count: 4];
    } else {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkButtonFace
	    count: 4];
    }
    SolidFillRoundedRectangle(context, bounds, 4, faceColor);
    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkCheckBox --
 *
 *      This is a standalone drawing procedure which draws Checkboxes in the
 *      Dark Mode style.
 */

static void DrawDarkCheckBox(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    CGRect checkbounds = {{0, bounds.size.height / 2 - 8}, {16, 16}};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;
    CGFloat x, y;

    bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
    x = bounds.origin.x;
    y = bounds.origin.y;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 4);
    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_BACKGROUND) &&
	!(state & TTK_STATE_DISABLED) &&
	((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
	GradientFillRoundedRectangle(context, bounds, 3,
	    darkSelectedGradient, 2);
    } else {
	GradientFillRoundedRectangle(context, bounds, 3,
	    darkInactiveGradient, 2);
    }
    HighlightButtonBorder(context, bounds);
    if ((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
	if (state & TTK_STATE_DISABLED) {
	    stroke = [NSColor disabledControlTextColor];
	} else {
	    stroke = [NSColor controlTextColor];
	}
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
    }
    if (state & TTK_STATE_SELECTED) {
	CGContextSetLineWidth(context, 1.5);
	CGContextBeginPath(context);
	CGPoint check[3] = {{x + 4, y + 8}, {x + 7, y + 11}, {x + 11, y + 4}};
	CGContextAddLines(context, check, 3);
	CGContextStrokePath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGContextSetLineWidth(context, 2.0);
	CGContextBeginPath(context);
	CGPoint bar[2] = {{x + 4, y + 8}, {x + 12, y + 8}};
	CGContextAddLines(context, bar, 2);
	CGContextStrokePath(context);
    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkRadioButton --
 *
 *    This is a standalone drawing procedure which draws RadioButtons
 *    in the Dark Mode style.
 */

static void DrawDarkRadioButton(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    CGRect checkbounds = {{0, bounds.size.height / 2 - 9}, {18, 18}};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *fill;
    CGFloat x, y;

    bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
    x = bounds.origin.x;
    y = bounds.origin.y;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 9);
    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_BACKGROUND) &&
	!(state & TTK_STATE_DISABLED) &&
	((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
	GradientFillRoundedRectangle(context, bounds, 8,
	    darkSelectedGradient, 2);
    } else {
	GradientFillRoundedRectangle(context, bounds, 8,
	    darkInactiveGradient, 2);
    }
    HighlightButtonBorder(context, bounds);
    if ((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
	if (state & TTK_STATE_DISABLED) {
	    fill = [NSColor disabledControlTextColor];
	} else {
	    fill = [NSColor controlTextColor];
	}
	CGContextSetFillColorWithColor(context, CGCOLOR(fill));
    }
    if (state & TTK_STATE_SELECTED) {
	CGContextBeginPath(context);
	CGRect dot = {{x + 6, y + 6}, {6, 6}};
	CGContextAddEllipseInRect(context, dot);
	CGContextFillPath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGRect bar = {{x + 5, y + 8}, {8, 2}};
	CGContextFillRect(context, bar);
    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkTab --
 *
 *      This is a standalone drawing procedure which draws Tabbed Pane
 *      Tabs in the Dark Mode style.
 */

static void DrawDarkTab(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor, *stroke;
    CGRect originalBounds = bounds;

    CGContextSetLineWidth(context, 1.0);
    CGContextClipToRect(context, bounds);

    /*
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off.
     */

    if (!(state & TTK_STATE_FIRST_TAB)) {
	bounds.origin.x -= 10;
	bounds.size.width += 10;
    }

    if (!(state & TTK_STATE_LAST_TAB)) {
	bounds.size.width += 10;
    }

    /*
     * Fill the tab face with the appropriate color or gradient.  Use a solid
     * color if the tab is not selected, otherwise use a blue or gray
     * gradient.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_SELECTED)) {
	if (state & TTK_STATE_DISABLED) {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkDisabledButtonFace
		count: 4];
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkButtonFace
		count: 4];
	}
	SolidFillRoundedRectangle(context, bounds, 4, faceColor);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    CGContextSaveGState(context);
	    CGContextSetShouldAntialias(context, false);
	    stroke = [NSColor colorWithColorSpace: deviceRGB
		components: darkTabSeparator
		count: 4];
	    CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	    CGContextBeginPath(context);
	    CGContextMoveToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + 1);
	    CGContextAddLineToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + originalBounds.size.height - 1);
	    CGContextStrokePath(context);
	    CGContextRestoreGState(context);
	}
    } else {

        /*
         * This is the selected tab; paint it blue.  If it is first, cover up
         * the separator line drawn by the second one.  (The selected tab is
         * always drawn last.)
         */

	if ((state & TTK_STATE_FIRST_TAB) && !(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 1;
	}
	if (!(state & TTK_STATE_BACKGROUND)) {
	    GradientFillRoundedRectangle(context, bounds, 4,
		darkSelectedGradient, 2);
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkInactiveSelectedTab
		count: 4];
	    SolidFillRoundedRectangle(context, bounds, 4, faceColor);
	}
	HighlightButtonBorder(context, bounds);
    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkSeparator --
 *
 *      This is a standalone drawing procedure which draws a separator widget
 *      in Dark Mode.
 */

static void DrawDarkSeparator(
    CGRect bounds,
    CGContextRef context,
    TCL_UNUSED(Tk_Window))
{
    static CGFloat fill[4] = {1.0, 1.0, 1.0, 0.3};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *fillColor = [NSColor colorWithColorSpace: deviceRGB
	components: fill
	count:4];

    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGContextFillRect(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkFocusRing --
 *
 *      This is a standalone drawing procedure which draws a focus ring around
 *      an Entry widget in Dark Mode.
 */

static void DrawDarkFocusRing(
    CGRect bounds,
    CGContextRef context)
{
    CGRect insetBounds = CGRectInset(bounds, -3, -3);
    CHECK_RADIUS(4, insetBounds)

    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *strokeColor;
    NSColor *fillColor = [NSColor colorWithColorSpace:deviceRGB
					   components:darkFocusRing
						count:4];
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h}, {x, y + 1}, {x + w - 1, y + 1}, {x + w - 1, y + h}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};

    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextBeginPath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingTop
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, topPart, 4);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingBottom
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGPathRef path = CGPathCreateWithRoundedRect(insetBounds, 4, 4, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextAddRect(context, bounds);
    CGContextEOFillPath(context);
    CGContextRestoreGState(context);
}
/*----------------------------------------------------------------------
 * +++ DrawDarkFrame --
 *
 *      This is a standalone drawing procedure which draws various
 *      types of borders in Dark Mode.
 */

static void DrawDarkFrame(
    CGRect bounds,
    CGContextRef context,
    HIThemeFrameKind kind)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;

    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h - 1}, {x, y + 1}, {x + w, y + 1}, {x + w, y + h - 1}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint accent[2] = {{x, y + 1}, {x + w, y + 1}};

    switch (kind) {
    case kHIThemeFrameTextFieldSquare:
	CGContextSaveGState(context);
	CGContextSetShouldAntialias(context, false);
	CGContextBeginPath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameTop
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, topPart, 4);
	CGContextStrokePath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameBottom
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, bottom, 2);
	CGContextStrokePath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameAccent
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, accent, 2);
	CGContextStrokePath(context);
	CGContextRestoreGState(context);
	break;
    default:
	break;
    }
}

/*----------------------------------------------------------------------
 * +++ DrawListHeader --
 *
 *      This is a standalone drawing procedure which draws column
 *      headers for a Treeview in the Dark Mode.
 */

static void DrawDarkListHeader(
    CGRect bounds,
    CGContextRef context,
    TCL_UNUSED(Tk_Window),
    int state)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;

    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;

    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};
    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    stroke = [NSColor colorWithColorSpace: deviceRGB
	components: darkFrameBottom
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
    CGContextBeginPath(context);
    CGContextAddLines(context, top, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;

	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, WHITERGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, WHITERGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Button element: Used for elements drawn with DrawThemeButton.
 */

/*
 * When Ttk draws the various types of buttons, a pointer to one of these
 * is passed as the clientData.
 */




typedef struct {
    ThemeButtonKind kind;
    ThemeMetric heightMetric;
} ThemeButtonParams;

static ThemeButtonParams
    PushButtonParams =  {kThemePushButton, kThemeMetricPushButtonHeight},
    CheckBoxParams =    {kThemeCheckBox, kThemeMetricCheckBoxHeight},
    RadioButtonParams = {kThemeRadioButton, kThemeMetricRadioButtonHeight},
    BevelButtonParams = {kThemeRoundedBevelButton, NoThemeMetric},
    PopupButtonParams = {kThemePopupButton, kThemeMetricPopupButtonHeight},
    DisclosureParams =  {
    kThemeDisclosureButton, kThemeMetricDisclosureTriangleHeight
},
    ListHeaderParams =
{kThemeListHeaderButton, kThemeMetricListHeaderHeight};
static Ttk_StateTable ButtonValueTable[] = {
    {kThemeButtonOff, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeButtonMixed, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}

    /*
     * Others: kThemeDisclosureRight, kThemeDisclosureDown,
     * kThemeDisclosureLeft
     */

};

static Ttk_StateTable ButtonAdornmentTable[] = {
    {kThemeAdornmentNone, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeAdornmentDefault | kThemeAdornmentFocus,
     TTK_STATE_ALTERNATE | TTK_STATE_FOCUS, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentDefault, TTK_STATE_ALTERNATE, 0},

    {kThemeAdornmentNone, 0, 0}
};

/*----------------------------------------------------------------------

 * +++ computeButtonDrawInfo --
 *
 *      Fill in an appearance manager HIThemeButtonDrawInfo record.
 */

static inline HIThemeButtonDrawInfo computeButtonDrawInfo(
    ThemeButtonParams *params,
    Ttk_State state,
    TCL_UNUSED(Tk_Window))
{

    /*
     * See ButtonElementDraw for the explanation of why we always draw
     * PushButtons in the active state.
     */

    SInt32 HIThemeState;

    HIThemeState = Ttk_StateTableLookup(ThemeStateTable, state);
    switch (params->kind) {
    case kThemePushButton:
	HIThemeState &= ~kThemeStateInactive;
	HIThemeState |= kThemeStateActive;
	break;
    default:
	break;
    }

    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = HIThemeState,
	.kind = params ? params->kind : 0,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };
    return info;
}

/*----------------------------------------------------------------------
 * +++ Button elements.
 */

static void ButtonElementMinSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;

    if (params->heightMetric != NoThemeMetric) {
	ChkErr(GetThemeMetric, params->heightMetric, minHeight);

        /*
         * The theme height does not include the 1-pixel border around
         * the button, although it does include the 1-pixel shadow at
         * the bottom.
         */

	*minHeight += 2;

        /*
         * The minwidth must be 0 to force the generic ttk code to compute the
         * correct text layout.  For example, a non-zero value will cause the
         * text to be left justified, no matter what -anchor setting is used in
         * the style.
         */

	*minWidth = 0;
    }
}

static void ButtonElementSize(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;
    const HIThemeButtonDrawInfo info =
	computeButtonDrawInfo(params, 0, tkwin);
    static const CGRect scratchBounds = {{0, 0}, {100, 100}};
    CGRect contentBounds, backgroundBounds;
    int verticalPad;


    ButtonElementMinSize(clientData, elementRecord, tkwin,
	minWidth, minHeight, paddingPtr);

    /*
     * Given a hypothetical bounding rectangle for a button, HIToolbox will
     * compute a bounding rectangle for the button contents and a bounding
     * rectangle for the button background.  The background bounds are large
     * enough to contain the image of the button in any state, which might
     * include highlight borders, shadows, etc.  The content rectangle is not
     * centered vertically within the background rectangle, presumably because
     * shadows only appear on the bottom.  Nonetheless, when HITools is asked
     * to draw a button with a certain bounding rectangle it draws the button
     * centered within the rectangle.
     *


     * To compute the effective padding around a button we request the
     * content and bounding rectangles for a 100x100 button and use the
     * padding between those.  However, we symmetrize the padding on the


     * top and bottom, because that is how the button will be drawn.



     */

    ChkErr(HIThemeGetButtonContentBounds,
	&scratchBounds, &info, &contentBounds);
    ChkErr(HIThemeGetButtonBackgroundBounds,
	&scratchBounds, &info, &backgroundBounds);
    paddingPtr->left = contentBounds.origin.x - backgroundBounds.origin.x;
    paddingPtr->right =
	CGRectGetMaxX(backgroundBounds) - CGRectGetMaxX(contentBounds);
    verticalPad = backgroundBounds.size.height - contentBounds.size.height;
    paddingPtr->top = paddingPtr->bottom = verticalPad / 2;
}

static void ButtonElementDraw(
    void *clientData,
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, b);
    HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, state, tkwin);

    bounds = NormalizeButtonBounds(params->heightMetric, bounds);

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	switch (info.kind) {
	case kThemePushButton:
	case kThemePopupButton:
	    DrawDarkButton(bounds, info.kind, state, dc.context);
	    break;
	case kThemeCheckBox:
	    DrawDarkCheckBox(bounds, state, dc.context);
	    break;
	case kThemeRadioButton:
	    DrawDarkRadioButton(bounds, state, dc.context);
	    break;
	case kThemeRoundedBevelButton:
	    DrawDarkBevelButton(bounds, state, dc.context);
	    break;
	default:
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context,
		HIOrientation, NULL);
	}
    } else if (info.kind == kThemePushButton &&
	       (state & TTK_STATE_PRESSED)) {
	bounds.size.height += 2;
	if ([NSApp macOSVersion] > 100800) {
	    GradientFillRoundedRectangle(dc.context, bounds, 4,
					 pressedPushButtonGradient, 2);
	}
    } else {

        /*
         * Apple's PushButton and PopupButton do not change their fill color
         * when the window is inactive.  However, except in 10.7 (Lion), the
         * color of the arrow button on a PopupButton does change.  For some
         * reason HITheme fills inactive buttons with a transparent color that
         * allows the window background to show through, leading to
         * inconsistent behavior.  We work around this by filling behind an
         * inactive PopupButton with a text background color before asking
         * HIToolbox to draw it. For PushButtons, we simply draw them in the
         * active state.
         */

	if (info.kind == kThemePopupButton &&
	    (state & TTK_STATE_BACKGROUND)) {
	    CGRect innerBounds = CGRectInset(bounds, 1, 1);
	    NSColor *whiteRGBA = [NSColor whiteColor];
	    SolidFillRoundedRectangle(dc.context, innerBounds, 4, whiteRGBA);
	}

        /*
         * A BevelButton with mixed value is drawn borderless, which does make
         * much sense for us.
         */

	if (info.kind == kThemeRoundedBevelButton &&
	    info.value == kThemeButtonMixed) {
	    info.value = kThemeButtonOff;
	    info.state = kThemeStateInactive;
	}
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec ButtonElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ButtonElementSize,
    ButtonElementDraw
};

/*----------------------------------------------------------------------
 * +++ Notebook elements.
 */


/* Tab position logic, c.f. ttkNotebook.c TabState() */



static Ttk_StateTable TabStyleTable[] = {
    {kThemeTabFrontInactive, TTK_STATE_SELECTED | TTK_STATE_BACKGROUND, 0},
    {kThemeTabNonFrontInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeTabFrontUnavailable, TTK_STATE_DISABLED | TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeTabFront, TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0},
    {kThemeTabNonFront, 0, 0}
};

static Ttk_StateTable TabAdornmentTable[] = {
    {kHIThemeTabAdornmentNone, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},

    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabAdornmentNone, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, 0, 0},
};

static Ttk_StateTable TabPositionTable[] = {
    {kHIThemeTabPositionOnly, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},

    {kHIThemeTabPositionFirst, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabPositionLast, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionMiddle, 0, 0},
};

/*
 * Apple XHIG Tab View Specifications:
 *
 * Control sizes: Tab views are available in regular, small, and mini sizes.
 * The tab height is fixed for each size, but you control the size of the pane
 * area. The tab heights for each size are listed below:
 *  - Regular size: 20 pixels.
 *  - Small: 17 pixels.
 *  - Mini: 15 pixels.
 *
 * Label spacing and fonts: The tab labels should be in a font that’s
 * proportional to the size of the tab view control. In addition, the label
 * should be placed so that there are equal margins of space before and after
 * it. The guidelines below provide the specifications you should use for tab
 * labels:
 *  - Regular size: System font. Center in tab, leaving 12 pixels on each
 *side.
 *  - Small: Small system font. Center in tab, leaving 10 pixels on each side.
 *  - Mini: Mini system font. Center in tab, leaving 8 pixels on each side.
 *
 * Control spacing: Whether you decide to inset a tab view in a window or
 * extend its edges to the window sides and bottom, you should place the top
 * edge of the tab view 12 or 14 pixels below the bottom edge of the title bar
 * (or toolbar, if there is one). If you choose to inset a tab view in a
 * window, you should leave a margin of 20 pixels between the sides and bottom
 * of the tab view and the sides and bottom of the window (although 16 pixels
 * is also an acceptable margin-width). If you need to provide controls below
 * the tab view, leave enough space below the tab view so the controls are 20
 * pixels above the bottom edge of the window and 12 pixels between the tab
 * view and the controls.
 *
 * If you choose to extend the tab view sides and bottom so that they meet the
 * window sides and bottom, you should leave a margin of at least 20 pixels
 * between the content in the tab view and the tab-view edges.
 *
 * <URL: http://developer.apple.com/documentation/userexperience/Conceptual/
 *       AppleHIGuidelines/XHIGControls/XHIGControls.html#//apple_ref/doc/uid/
 *       TP30000359-TPXREF116>
 */


static void TabElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    GetThemeMetric(kThemeMetricLargeTabHeight, (SInt32 *) minHeight);
    *paddingPtr = Ttk_MakePadding(0, 0, 0, 2);

}

static void TabElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeTabDrawInfo info = {
	.version = 1,
	.style = Ttk_StateTableLookup(TabStyleTable, state),
	.direction = kThemeTabNorth,
	.size = kHIThemeTabSizeNormal,
	.adornment = Ttk_StateTableLookup(TabAdornmentTable, state),
	.kind = kHIThemeTabKindNormal,
	.position = Ttk_StateTableLookup(TabPositionTable, state),
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkTab(bounds, state, dc.context);
    } else {
	ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Notebook panes:
 */

static void PaneElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(9, 5, 9, 9);
}

static void PaneElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);









    bounds.origin.y -= kThemeMetricTabFrameOverlap;
    bounds.size.height += kThemeMetricTabFrameOverlap;
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin);
    } else {
	HIThemeTabPaneDrawInfo info = {
	    .version = 1,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .direction = kThemeTabNorth,
	    .size = kHIThemeTabSizeNormal,
	    .kind = kHIThemeTabKindNormal,
	    .adornment = kHIThemeTabPaneAdornmentNormal,
	    };
	bounds.origin.y -= kThemeMetricTabFrameOverlap;
	bounds.size.height += kThemeMetricTabFrameOverlap;
	ChkErr(HIThemeDrawTabPane, &bounds, &info, dc.context, HIOrientation);
    }
    END_DRAWING
}

static Ttk_ElementSpec PaneElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    PaneElementSize,
    PaneElementDraw
};

/*----------------------------------------------------------------------
 * +++ Labelframe elements --
 *
 * Labelframe borders: Use "primary group box ..."  Quoth
 * DrawThemePrimaryGroup reference: "The primary group box frame is drawn

 * inside the specified rectangle and is a maximum of 2 pixels thick."
 *
 * "Maximum of 2 pixels thick" is apparently a lie; looks more like 4 to me
 * with shading.
 */

static void GroupElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(4);
}

static void GroupElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin);
    } else {
	const HIThemeGroupBoxDrawInfo info = {
	    .version = 0,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .kind = kHIThemeGroupBoxKindPrimaryOpaque,
	    };
	ChkErr(HIThemeDrawGroupBox, &bounds, &info, dc.context, HIOrientation);
    }


    END_DRAWING
}

static Ttk_ElementSpec GroupElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GroupElementSize,
    GroupElementDraw
};

/*----------------------------------------------------------------------
 * +++ Entry elements --
 *
 *    3 pixels padding for focus rectangle
 *    2 pixels padding for EditTextFrame
 */

typedef struct {
    Tcl_Obj     *backgroundObj;
    Tcl_Obj     *fieldbackgroundObj;
} EntryElement;

#define ENTRY_DEFAULT_BACKGROUND "systemTextBackgroundColor"

static Ttk_ElementOptionSpec EntryElementOptions[] = {
    {"-background", TK_OPTION_BORDER,
     offsetof(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(EntryElement, fieldbackgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}

};

static void EntryElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(7, 5, 7, 6);
}

static void EntryElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    EntryElement *e = elementRecord;

    Ttk_Box inner = Ttk_PadBox(b, Ttk_UniformPadding(3));
    CGRect bounds = BoxToRect(d, inner);
    NSColor *background;
    Tk_3DBorder backgroundPtr = NULL;
    static const char *defaultBG = ENTRY_DEFAULT_BACKGROUND;

    if (TkMacOSXInDarkMode(tkwin)) {
	BEGIN_DRAWING(d)
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	CGFloat fill[4];
	GetBackgroundColor(dc.context, tkwin, 1, fill);

	/*
	 * Lighten the background to provide contrast.
	 */

	for (int i = 0; i < 3; i++) {
		fill[i] += 9.0 / 255.0;
	    }
	background = [NSColor colorWithColorSpace: deviceRGB
	    components: fill
	    count: 4];
	CGContextSetFillColorWithColor(dc.context, CGCOLOR(background));
	CGContextFillRect(dc.context, bounds);
	if (state & TTK_STATE_FOCUS) {
	    DrawDarkFocusRing(bounds, dc.context);
	} else {
	    DrawDarkFrame(bounds, dc.context, kHIThemeFrameTextFieldSquare);
	}
	END_DRAWING
    } else {
	const HIThemeFrameDrawInfo info = {
	    .version = 0,
	    .kind = kHIThemeFrameTextFieldSquare,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .isFocused = state & TTK_STATE_FOCUS,
	};

        /*
         * Earlier versions of the Aqua theme ignored the -fieldbackground
         * option and used the -background as if it were -fieldbackground.
         * Here we are enabling -fieldbackground.  For backwards
         * compatibility, if -fieldbackground is set to the default color and
         * -background is set to a different color then we use -background as
         * -fieldbackground.
         */

	if (0 != strcmp(Tcl_GetString(e->fieldbackgroundObj), defaultBG)) {
	    backgroundPtr =
		Tk_Get3DBorderFromObj(tkwin, e->fieldbackgroundObj);
	} else if (0 != strcmp(Tcl_GetString(e->backgroundObj), defaultBG)) {
	    backgroundPtr = Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);
	}
	if (backgroundPtr != NULL) {
	    XFillRectangle(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
		inner.x, inner.y, inner.width, inner.height);
	}
	BEGIN_DRAWING(d)
	if (backgroundPtr == NULL) {
	    if ([NSApp macOSVersion] > 100800) {
		background = [NSColor textBackgroundColor];
		CGContextSetFillColorWithColor(dc.context, CGCOLOR(background));
	    } else {
		CGContextSetRGBFillColor(dc.context, 1.0, 1.0, 1.0, 1.0);
	    }
	    CGContextFillRect(dc.context, bounds);
	}
	ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);



	END_DRAWING
    }
}

static Ttk_ElementSpec EntryElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(EntryElement),
    EntryElementOptions,
    EntryElementSize,
    EntryElementDraw
};

/*----------------------------------------------------------------------
 * +++ Combobox elements --
 *
 * NOTES:
 *      The HIToolbox has incomplete and inconsistent support for ComboBoxes.
 *      There is no constant available to get the height of a ComboBox with
 *      GetThemeMetric. In fact, ComboBoxes are the same (fixed) height as
 *      PopupButtons and PushButtons, but they have no shadow at the bottom.
 *      As a result, they are drawn 1 pixel above the center of the bounds
 *      rectangle rather than being centered like the other buttons.  One can
 *      request background bounds for a ComboBox, and it is reported with
 *      height 23, while the actual button face, including its 1-pixel border
 *      has height 21. Attempting to request the content bounds returns a 0x0
 *      rectangle.  Measurement indicates that the arrow button has width 18.
 *
 *      With no help available from HIToolbox, we have to use hard-wired
 *      constants for the padding. We shift the bounding rectangle downward by
 *      1 pixel to account for the fact that the button is not centered.

 */

static Ttk_Padding ComboboxPadding = {4, 2, 20, 2};


static void ComboboxElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    *minWidth = 24;
    *minHeight = 23;
    *paddingPtr = ComboboxPadding;
}

static void ComboboxElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = kThemeComboBox,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };

    BEGIN_DRAWING(d)
    bounds.origin.y += 1;
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds.size.height += 1;
	DrawDarkButton(bounds, info.kind, state, dc.context);
    } else if ([NSApp macOSVersion] > 100800) {
	if ((state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    NSColor *background = [NSColor textBackgroundColor];
	    CGRect innerBounds = CGRectInset(bounds, 1, 2);
	    SolidFillRoundedRectangle(dc.context, innerBounds, 4, background);
	}
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    END_DRAWING
}

static Ttk_ElementSpec ComboboxElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ComboboxElementSize,
    ComboboxElementDraw
};

/*----------------------------------------------------------------------
 * +++ Spinbutton elements --
 *
 *      From Apple HIG, part III, section "Controls", "The Stepper Control":
 *      there should be 2 pixels of space between the stepper control (AKA
 *      IncDecButton, AKA "little arrows") and the text field it modifies.
 *
 *      Ttk expects the up and down arrows to be distinct elements but
 *      HIToolbox draws them as one widget with two different pressed states.
 *      We work around this by defining them as separate elements in the
 *      layout, but making each one have a drawing method which also draws the
 *      other one.  The down button does no drawing when not pressed, and when
 *      pressed draws the entire IncDecButton in its "pressed down" state.
 *      The up button draws the entire IncDecButton when not pressed and when
 *      pressed draws the IncDecButton in its "pressed up" state.  NOTE: This
 *      means that when the down button is pressed the IncDecButton will be
 *      drawn twice, first in unpressed state by the up arrow and then in
 *      "pressed down" state by the down button.  The drawing must be done in
 *      that order.  So the up button must be listed first in the layout.
 */

static Ttk_Padding SpinbuttonMargins = {0, 0, 2, 0};

static void SpinButtonUpElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *minWidth = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *minHeight = (s + Ttk_PaddingHeight(SpinbuttonMargins)) / 2;
}

static void SpinButtonUpElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState;

    bounds.size.height *= 2;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedUp;
    } else {
	infoState = Ttk_StateTableLookup(ThemeStateTable, state);
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };
    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkIncDecButton(bounds, infoState, state, dc.context);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonUpElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonUpElementSize,
    SpinButtonUpElementDraw
};
static void SpinButtonDownElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *minWidth = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *minHeight = (s + Ttk_PaddingHeight(SpinbuttonMargins)) / 2;
}

static void SpinButtonDownElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState = 0;

    bounds.origin.y -= bounds.size.height;
    bounds.size.height *= 2;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedDown;
    } else {
	return;
    }


    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkIncDecButton(bounds, infoState, state, dc.context);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonDownElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonDownElementSize,
    SpinButtonDownElementDraw
};


/*----------------------------------------------------------------------
 * +++ DrawThemeTrack-based elements --
 *
 *    Progress bars and scales. (See also: <<NOTE-TRACKS>>)
 */

/*
 * Apple does not change the appearance of a slider when the window becomes
 * inactive.  So we shouldn't either.
 */

static Ttk_StateTable ThemeTrackEnableTable[] = {
    {kThemeTrackDisabled, TTK_STATE_DISABLED, 0},
    {kThemeTrackActive, TTK_STATE_BACKGROUND, 0},
    {kThemeTrackActive, 0, 0}
    /* { kThemeTrackNothingToScroll, ?, ? }, */
};

typedef struct {        /* TrackElement client data */
    ThemeTrackKind kind;
    SInt32 thicknessMetric;
} TrackElementData;

static TrackElementData ScaleData = {
    kThemeSlider, kThemeMetricHSliderHeight
};

typedef struct {
    Tcl_Obj *fromObj;           /* minimum value */
    Tcl_Obj *toObj;             /* maximum value */
    Tcl_Obj *valueObj;          /* current value */
    Tcl_Obj *orientObj;         /* horizontal / vertical */
} TrackElement;

static Ttk_ElementOptionSpec TrackElementOptions[] = {
    {"-from", TK_OPTION_DOUBLE, offsetof(TrackElement, fromObj), NULL},
    {"-to", TK_OPTION_DOUBLE, offsetof(TrackElement, toObj), NULL},
    {"-value", TK_OPTION_DOUBLE, offsetof(TrackElement, valueObj), NULL},
    {"-orient", TK_OPTION_STRING, offsetof(TrackElement, orientObj), NULL},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void TrackElementSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    TrackElementData *data = (TrackElementData *)clientData;
    SInt32 size = 24;   /* reasonable default ... */

    ChkErr(GetThemeMetric, data->thicknessMetric, &size);
    *minWidth = *minHeight = size;
}

static void TrackElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    TrackElementData *data = clientData;
    TrackElement *elem = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, factor;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, elem->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, elem->fromObj, &from);
    Tcl_GetDoubleFromObj(NULL, elem->toObj, &to);
    Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value);
    factor = RangeToFactor(to);

    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.
     */

    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind = data->kind,
	.bounds = bounds,
	.min = from * factor,
	.max = to * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = 0,
    };

    if (info.kind == kThemeSlider) {
	info.trackInfo.slider.pressState = state & TTK_STATE_PRESSED ?
	    kThemeThumbPressed : 0;
	if (state & TTK_STATE_ALTERNATE) {
	    info.trackInfo.slider.thumbDir = kThemeThumbDownward;
	} else {
	    info.trackInfo.slider.thumbDir = kThemeThumbPlain;
	}
    }
    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 2);
	} else {
	    bounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 2);
	}
	SolidFillRoundedRectangle(dc.context, bounds, 2, trackColor);
    }
    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec TrackElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TrackElement),
    TrackElementOptions,
    TrackElementSize,
    TrackElementDraw
};

/*----------------------------------------------------------------------
 * Slider elements -- <<NOTE-TRACKS>>
 *
 * Has geometry only. The Scale widget adjusts the position of this element,
 * and uses it for hit detection. In the Aqua theme, the slider is actually
 * drawn as part of the trough element.
 *



 */

static void SliderElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    *minWidth = *minHeight = 24;
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SliderElementSize,
    TtkNullElementDraw
};

/*----------------------------------------------------------------------
 * +++ Progress bar elements --
 *
 * @@@ NOTE: According to an older revision of the Aqua reference docs,
 * @@@ the 'phase' field is between 0 and 4. Newer revisions say
 * @@@ that it can be any UInt8 value.
 */

typedef struct {
    Tcl_Obj *orientObj;         /* horizontal / vertical */
    Tcl_Obj *valueObj;          /* current value */
    Tcl_Obj *maximumObj;        /* maximum value */
    Tcl_Obj *phaseObj;          /* animation phase */
    Tcl_Obj *modeObj;           /* progress bar mode */
} PbarElement;

static Ttk_ElementOptionSpec PbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(PbarElement, orientObj), "horizontal"},
    {"-value", TK_OPTION_DOUBLE,
     offsetof(PbarElement, valueObj), "0"},
    {"-maximum", TK_OPTION_DOUBLE,
     offsetof(PbarElement, maximumObj), "100"},
    {"-phase", TK_OPTION_INT,
     offsetof(PbarElement, phaseObj), "0"},
    {"-mode", TK_OPTION_STRING,
     offsetof(PbarElement, modeObj), "determinate"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void PbarElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 size = 24;           /* @@@ Check HIG for correct default */

    ChkErr(GetThemeMetric, kThemeMetricLargeProgressBarThickness, &size);
    *minWidth = *minHeight = size;
}

static void PbarElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    PbarElement *pbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    int phase = 0;
    double value = 0, maximum = 100, factor;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, pbar->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);
    factor = RangeToFactor(maximum);

    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.
     */

    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind =
	    (!strcmp("indeterminate",
	    Tcl_GetString(pbar->modeObj)) && value) ?
	    kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = bounds,
	.min = 0,
	.max = maximum * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = phase,
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 3);
	} else {
	    bounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 1);
	}
	SolidFillRoundedRectangle(dc.context, bounds, 3, trackColor);
    }
    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PbarElement),
    PbarElementOptions,
    PbarElementSize,
    PbarElementDraw
};

/*----------------------------------------------------------------------
 * +++ Scrollbar elements
 */

typedef struct
{
    Tcl_Obj *orientObj;
} ScrollbarElement;

static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(ScrollbarElement, orientObj), "horizontal"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TroughElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    SInt32 thickness = 15;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    ChkErr(GetThemeMetric, kThemeMetricScrollBarWidth, &thickness);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	*minHeight = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 4, 3);
	}
    } else {
	*minWidth = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 3, 4);
	}
    }
}

static CGFloat lightTrough[4] = {250.0 / 255, 250.0 / 255, 250.0 / 255, 1.0};
static CGFloat darkTrough[4] = {45.0 / 255, 46.0 / 255, 49.0 / 255, 1.0};
static CGFloat lightInactiveThumb[4] = {
    200.0 / 255, 200.0 / 255, 200.0 / 255, 1.0
};
static CGFloat lightActiveThumb[4] = {
    133.0 / 255, 133.0 / 255, 133.0 / 255, 1.0
};
static CGFloat darkInactiveThumb[4] = {
    116.0 / 255, 117.0 / 255, 118.0 / 255, 1.0
};
static CGFloat darkActiveThumb[4] = {
    158.0 / 255, 158.0 / 255, 159.0 / 255, 1.0
};
static void TroughElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    CGRect bounds = BoxToRect(d, b);
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *troughColor;
    CGFloat *rgba = TkMacOSXInDarkMode(tkwin) ? darkTrough : lightTrough;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	bounds = CGRectInset(bounds, 0, 1);
    } else {
	bounds = CGRectInset(bounds, 1, 0);
    }
    troughColor = [NSColor colorWithColorSpace: deviceRGB
	components: rgba
	count: 4];
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	CGContextSetFillColorWithColor(dc.context, CGCOLOR(troughColor));
    } else {
	ChkErr(HIThemeSetFill, kThemeBrushDocumentWindowBackground, NULL,
	    dc.context, HIOrientation);
    }
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}

static Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TroughElementSize,
    TroughElementDraw
};
static void ThumbElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_VERTICAL) {
	*minHeight = 18;
	*minWidth = 8;
    } else {
	*minHeight = 8;
	*minWidth = 18;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    /*
     * In order to make ttk scrollbars work correctly it is necessary to be
     * able to display the thumb element at the size and location which the ttk
     * scrollbar widget requests.  The algorithm that HIToolbox uses to
     * determine the thumb geometry from the input values of min, max, value
     * and viewSize is undocumented.  A seemingly natural algorithm is
     * implemented below.  This code uses that algorithm for older OS versions,
     * because using HITools also handles drawing the buttons and 3D thumb used
     * on those systems.  For newer systems the cleanest approach is to just
     * draw the thumb directly.
     */

    if ([NSApp macOSVersion] > 100800) {
	CGRect thumbBounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *thumbColor;
	CGFloat *rgba;
	if ((orientation == TTK_ORIENT_HORIZONTAL &&
	    thumbBounds.size.width >= Tk_Width(tkwin) - 8) ||
	    (orientation == TTK_ORIENT_VERTICAL &&
	    thumbBounds.size.height >= Tk_Height(tkwin) - 8)) {
	    return;
	}
	int isDark = TkMacOSXInDarkMode(tkwin);
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    rgba = isDark ? darkActiveThumb : lightActiveThumb;
	} else {
	    rgba = isDark ? darkInactiveThumb : lightInactiveThumb;
	}
	thumbColor = [NSColor colorWithColorSpace: deviceRGB
	    components: rgba
	    count: 4];
	BEGIN_DRAWING(d)
	SolidFillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, factor, fraction;
	MacDrawable *macWin = (MacDrawable *)Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};

        /*
         * The info struct has integer fields, which will be converted to
         * floats in the drawing routine.  All of values provided in the info
         * struct, namely min, max, value, and viewSize are only defined up to
         * an arbitrary scale factor.  To avoid roundoff error we scale so
         * that the viewSize is a large float which is smaller than the
         * largest int.
         */

	HIThemeTrackDrawInfo info = {
	    .version = 0,
	    .bounds = troughBounds,
	    .min = 0,
	    .attributes = kThemeTrackShowThumb |
		kThemeTrackThumbRgnIsNotGhost,
	    .enableState = kThemeTrackActive
	};
	factor = RangeToFactor(100.0);
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    trackSize = troughBounds.size.width;
	    thumbSize = b.width;
	    fraction = b.x / trackSize;
	} else {
	    trackSize = troughBounds.size.height;
	    thumbSize = b.height;
	    fraction = b.y / trackSize;
	}
	visibleSize = (thumbSize / trackSize) * factor;
	info.max = factor - visibleSize;
	info.trackInfo.scrollbar.viewsize = visibleSize;
	if ([NSApp macOSVersion] < 100800 ||
	    orientation == TTK_ORIENT_HORIZONTAL) {
	    info.value = factor * fraction;
	} else {
	    info.value = info.max - factor * fraction;
	}
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	} else {
	    info.trackInfo.scrollbar.pressState = 0;
	}
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    info.attributes |= kThemeTrackHorizontal;
	} else {
	    info.attributes &= ~kThemeTrackHorizontal;
	}
	BEGIN_DRAWING(d)
	HIThemeDrawTrack(&info, 0, dc.context, kHIThemeOrientationNormal);
	END_DRAWING
    }
}

static Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};
static void ArrowElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    if ([NSApp macOSVersion] < 100800) {
	*minHeight = *minWidth = 14;
    } else {
	*minHeight = *minWidth = -1;
    }
}

static Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ArrowElementSize,
    TtkNullElementDraw
};

/*----------------------------------------------------------------------
 * +++ Separator element.
 *
 *    DrawThemeSeparator() guesses the orientation of the line from the width
 *    and height of the rectangle, so the same element can can be used for
 *    horizontal, vertical, and general separators.
 */

static void SeparatorElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    *minWidth = *minHeight = 1;
}

static void SeparatorElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeSeparatorDrawInfo info = {
	.version = 0,
        /* Separator only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkSeparator(bounds, dc.context, tkwin);
    } else {
	ChkErr(HIThemeDrawSeparator, &bounds, &info, dc.context,
	    HIOrientation);
    }
    END_DRAWING
}

static Ttk_ElementSpec SeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SeparatorElementSize,
    SeparatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Size grip elements -- (obsolete)
 */

static const ThemeGrowDirection sizegripGrowDirection
    = kThemeGrowRight | kThemeGrowDown;

static void SizegripElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
	.state = kThemeStateActive,
	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };
    CGRect bounds = CGRectZero;

    ChkErr(HIThemeGetGrowBoxBounds, &bounds.origin, &info, &bounds);
    *minWidth = bounds.size.width;
    *minHeight = bounds.size.height;
}

static void SizegripElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
        /* Grow box only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),
	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };

    BEGIN_DRAWING(d)
    ChkErr(HIThemeDrawGrowBox, &bounds.origin, &info, dc.context,
	HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec SizegripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SizegripElementSize,
    SizegripElementDraw
};

/*----------------------------------------------------------------------
 * +++ Background and fill elements --
 *
 *      Before drawing any ttk widget, its bounding rectangle is filled with a
 *      background color.  This color must match the background color of the
 *      containing widget to avoid looking ugly. The need for care when doing
 *      this is exacerbated by the fact that ttk enforces its "native look" by
 *      not allowing user control of the background or highlight colors of ttk
 *      widgets.
 *
 *      This job is made more complicated in recent versions of macOS by the
 *      fact that the Appkit GroupBox (used for ttk LabelFrames) and
 *      TabbedPane (used for the Notebook widget) both place their content
 *      inside a rectangle with rounded corners that has a color which
 *      contrasts with the dialog background color.  Moreover, although the
 *      Apple human interface guidelines recommend against doing so, there are
 *      times when one wants to nest these widgets, for example placing a
 *      GroupBox inside of a TabbedPane.  To have the right contrast, each
 *      level of nesting requires a different color.
 *
 *      Previous Tk releases used the HIThemeDrawGroupBox routine to draw
 *      GroupBoxes and TabbedPanes. This meant that the best that could be
 *      done was to set the GroupBox to be of kind
 *      kHIThemeGroupBoxKindPrimaryOpaque, and set its fill color to be the
 *      system background color.  If widgets inside the box were drawn with
 *      the system background color the backgrounds would match.  But this
 *      produces a GroupBox with no contrast, the only visual clue being a
 *      faint highlighting around the top of the GroupBox.  Moreover, the
 *      TabbedPane does not have an Opaque version, so while it is drawn
 *      inside a contrasting rounded rectangle, the widgets inside the pane
 *      needed to be enclosed in a frame with the system background
 *      color. This added a visual artifact since the frame's background color
 *      does not match the Pane's background color.  That code has now been
 *      replaced with the standalone drawing procedure macOSXDrawGroupBox,
 *      which draws a rounded rectangle with an appropriate contrasting
 *      background color.
 *
 *      Patterned backgrounds, which are now obsolete, should be aligned with
 *      the coordinate system of the top-level window.  Apparently failing to
 *      do this used to cause graphics anomalies when drawing into an
 *      off-screen graphics port.  The code for handling this is currently
 *      commented out.
 */

static void FillElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    if ([NSApp macOSVersion] > 100800) {
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *bgColor;
	CGFloat fill[4];
	BEGIN_DRAWING(d)
	GetBackgroundColor(dc.context, tkwin, 0, fill);
	bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
					 count: 4];
	CGContextSetFillColorSpace(dc.context, deviceRGB.CGColorSpace);
	CGContextSetFillColorWithColor(dc.context, CGCOLOR(bgColor));
	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    } else {
	ThemeBrush brush = (state & TTK_STATE_BACKGROUND)
	    ? kThemeBrushModelessDialogBackgroundInactive
	    : kThemeBrushModelessDialogBackgroundActive;

	BEGIN_DRAWING(d)
	ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);
	//QDSetPatternOrigin(PatternOrigin(tkwin, d));
	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    }
}

static void BackgroundElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    unsigned int state)
{

    FillElementDraw(clientData, elementRecord, tkwin, d, Ttk_WinBox(tkwin),
	state);
}

static Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    FillElementDraw
};

static Ttk_ElementSpec BackgroundElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    BackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ ToolbarBackground element -- toolbar style for frames.
 *
 *    This is very similar to the normal background element, but uses a
 *    different ThemeBrush in order to get the lighter pinstripe effect
 *    used in toolbars. We use SetThemeBackground() rather than
 *    ApplyThemeBackground() in order to get the right style.
 *
 *    <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *    Appearance_Manager/appearance_manager/constant_7.html#/
 *    /apple_ref/doc/uid/TP30000243/C005321>
 *
 */

static void ToolbarBackgroundElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    ThemeBrush brush = kThemeBrushToolbarBackground;
    CGRect bounds = BoxToRect(d, Ttk_WinBox(tkwin));

    BEGIN_DRAWING(d)
    ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);
    //QDSetPatternOrigin(PatternOrigin(tkwin, d));
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}

static Ttk_ElementSpec ToolbarBackgroundElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    ToolbarBackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field elements --
 *
 *      Used for the Treeview widget. This is like the BackgroundElement
 *      except that the fieldbackground color is configureable.
 */

typedef struct {
    Tcl_Obj     *backgroundObj;
} FieldElement;

static Ttk_ElementOptionSpec FieldElementOptions[] = {
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(FieldElement, backgroundObj), "white"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void FieldElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *e = elementRecord;
    Tk_3DBorder backgroundPtr =
	Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);

    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	b.x, b.y, b.width, b.height);
}

static Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    TtkNullElementSize,
    FieldElementDraw
};

/*----------------------------------------------------------------------
 * +++ Treeview headers --
 *
 *    On systems older than 10.9 The header is a kThemeListHeaderButton drawn
 *    by HIToolbox.  On newer systems those buttons do not match the Apple
 *    buttons, so we draw them from scratch.
 */


static Ttk_StateTable TreeHeaderValueTable[] = {
    {kThemeButtonOn, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}
};

static Ttk_StateTable TreeHeaderAdornmentTable[] = {
    {kThemeAdornmentHeaderButtonSortUp,


     TTK_STATE_ALTERNATE | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentDefault,
     TTK_STATE_SELECTED | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_ALTERNATE, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_SELECTED, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentNone, 0, 0}
};

static void TreeAreaElementSize (
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{

    /*
     * Padding is needed to get the heading text to align correctly, since the
     * widget expects the heading to be the same height as a row.
     */

    if ([NSApp macOSVersion] > 100800) {
	paddingPtr->top = 4;
    }
}

static Ttk_ElementSpec TreeAreaElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TreeAreaElementSize,
    TtkNullElementDraw
};
static void TreeHeaderElementSize(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    if ([NSApp macOSVersion] > 100800) {
	*minHeight = 24;
    } else {
	ButtonElementSize(clientData, elementRecord, tkwin, minWidth,
	    minHeight, paddingPtr);
    }
}

static void TreeHeaderElementDraw(
    void *clientData,
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = params->kind,
	.value = Ttk_StateTableLookup(TreeHeaderValueTable, state),
	.adornment = Ttk_StateTableLookup(TreeHeaderAdornmentTable, state),
    };

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {

        /*
         * Compensate for the padding added in TreeHeaderElementSize, so
         * the larger heading will be drawn at the top of the widget.
         */

	bounds.origin.y -= 4;
	if (TkMacOSXInDarkMode(tkwin)) {
	    DrawDarkListHeader(bounds, dc.context, tkwin, state);
	} else {
	    DrawListHeader(bounds, dc.context, tkwin, state);
	}
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec TreeHeaderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TreeHeaderElementSize,
    TreeHeaderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Disclosure triangles --
 */

#define TTK_TREEVIEW_STATE_OPEN         TTK_STATE_USER1
#define TTK_TREEVIEW_STATE_LEAF         TTK_STATE_USER2
static Ttk_StateTable DisclosureValueTable[] = {
    {kThemeDisclosureDown, TTK_TREEVIEW_STATE_OPEN, 0},
    {kThemeDisclosureRight, 0, 0},
};

static void DisclosureElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s);
    *minWidth = s;
    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s);
    *minHeight = s;
}

static void DisclosureElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?
	    kThemeStateInactive : kThemeStateActive;
	CGRect bounds = BoxToRect(d, b);
	const HIThemeButtonDrawInfo info = {
	    .version = 0,
	    .state = triangleState,
	    .kind = kThemeDisclosureTriangle,
	    .value = Ttk_StateTableLookup(DisclosureValueTable, state),
	    .adornment = kThemeAdornmentDrawIndicatorOnly,
	};

	BEGIN_DRAWING(d)
	if ([NSApp macOSVersion] >= 110000) {
	    CGFloat rgba[4];
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *stroke = [[NSColor textColor]
		colorUsingColorSpace: deviceRGB];
	    [stroke getComponents: rgba];
	    if (state & TTK_TREEVIEW_STATE_OPEN) {
		DrawOpenDisclosure(dc.context, bounds, 2, 8, rgba);
	    } else {
		DrawClosedDisclosure(dc.context, bounds, 2, 12, rgba);
	    }
	} else {
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
	}
	END_DRAWING
    }
}

static Ttk_ElementSpec DisclosureElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    DisclosureElementSize,
    DisclosureElementDraw
};

/*----------------------------------------------------------------------
 * +++ Widget layouts --
 */

TTK_BEGIN_LAYOUT_TABLE(LayoutTable)

TTK_LAYOUT("Toolbar",
    TTK_NODE("Toolbar.background", TTK_FILL_BOTH))

TTK_LAYOUT("TButton",
    TTK_GROUP("Button.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

TTK_LAYOUT("TRadiobutton",
    TTK_GROUP("Radiobutton.button", TTK_FILL_BOTH,
    TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
    TTK_NODE("Radiobutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCheckbutton",
    TTK_GROUP("Checkbutton.button", TTK_FILL_BOTH,
    TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
    TTK_NODE("Checkbutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TMenubutton",
    TTK_GROUP("Menubutton.button", TTK_FILL_BOTH,
    TTK_GROUP("Menubutton.padding", TTK_FILL_BOTH,
    TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.button", TTK_FILL_BOTH,
    TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))

/* Notebook tabs -- no 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))))

/* Spinbox -- buttons 2px to the right of the field. */
TTK_LAYOUT("TSpinbox",
    TTK_GROUP("Spinbox.buttons", 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.field", TTK_FILL_X,
    TTK_NODE("Spinbox.textarea", TTK_FILL_X)))

/* Progress bars -- track only */
TTK_LAYOUT("TProgressbar",
    TTK_NODE("Progressbar.track", TTK_FILL_BOTH))

/* Treeview -- no border. */
TTK_LAYOUT("Treeview",
    TTK_GROUP("Treeview.field", TTK_FILL_BOTH,
    TTK_GROUP("Treeview.padding", TTK_FILL_BOTH,
    TTK_NODE("Treeview.treearea", TTK_FILL_BOTH))))

/* Tree heading -- no border, fixed height */
TTK_LAYOUT("Heading",
    TTK_NODE("Treeheading.cell", TTK_FILL_BOTH)
    TTK_NODE("Treeheading.image", TTK_PACK_RIGHT)
    TTK_NODE("Treeheading.text", TTK_PACK_TOP))

/* Tree items -- omit focus ring */
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_NODE("Treeitem.text", TTK_PACK_LEFT)))

/* Scrollbar Layout -- Buttons at the bottom (Snow Leopard and Lion only) */

TTK_LAYOUT("Vertical.TScrollbar",
    TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
    TTK_NODE("Vertical.Scrollbar.thumb", TTK_FILL_BOTH)
    TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
    TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_BOTTOM)))

TTK_LAYOUT("Horizontal.TScrollbar",
    TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
    TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH)
    TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
    TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_RIGHT)))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ Initialization --
 */

static int AquaTheme_Init(
    Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_CreateTheme(interp, "aqua", NULL);

    if (!themePtr) {
	return TCL_ERROR;
    }

    /*
     * Elements:
     */

    Ttk_RegisterElementSpec(themePtr, "background", &BackgroundElementSpec,
	0);
    Ttk_RegisterElementSpec(themePtr, "fill", &FillElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Toolbar.background",
	&ToolbarBackgroundElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Button.button",
	&ButtonElementSpec, &PushButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Checkbutton.button",
	&ButtonElementSpec, &CheckBoxParams);
    Ttk_RegisterElementSpec(themePtr, "Radiobutton.button",
	&ButtonElementSpec, &RadioButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Toolbutton.border",
	&ButtonElementSpec, &BevelButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Menubutton.button",
	&ButtonElementSpec, &PopupButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.uparrow",
	&SpinButtonUpElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.downarrow",
	&SpinButtonDownElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Combobox.button",
	&ComboboxElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator",
	&DisclosureElementSpec, &DisclosureParams);
    Ttk_RegisterElementSpec(themePtr, "Treeheading.cell",
	&TreeHeaderElementSpec, &ListHeaderParams);

    Ttk_RegisterElementSpec(themePtr, "Treeview.treearea",
	&TreeAreaElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.tab", &TabElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.client", &PaneElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Labelframe.border", &GroupElementSpec,
	0);
    Ttk_RegisterElementSpec(themePtr, "Entry.field", &EntryElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.field", &EntryElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "separator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "hseparator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "vseparator", &SeparatorElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "sizegrip", &SizegripElementSpec, 0);

    /*
     * <<NOTE-TRACKS>>
     * In some themes the Layouts for a progress bar has a trough element and a
     * pbar element.  But in our case the appearance manager draws both parts
     * of the progress bar, so we just have a single element called ".track".
     */

    Ttk_RegisterElementSpec(themePtr, "Progressbar.track", &PbarElementSpec,
	0);

    Ttk_RegisterElementSpec(themePtr, "Scale.trough", &TrackElementSpec,
	&ScaleData);
    Ttk_RegisterElementSpec(themePtr, "Scale.slider", &SliderElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Vertical.Scrollbar.trough",
	&TroughElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Vertical.Scrollbar.thumb",
	&ThumbElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Horizontal.Scrollbar.trough",
	&TroughElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Horizontal.Scrollbar.thumb",
	&ThumbElementSpec, 0);

    /*
     * If we are not in Snow Leopard or Lion the arrows won't actually be
     * displayed.
     */

    Ttk_RegisterElementSpec(themePtr, "Vertical.Scrollbar.uparrow",
	&ArrowElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Vertical.Scrollbar.downarrow",
	&ArrowElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Horizontal.Scrollbar.leftarrow",
	&ArrowElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Horizontal.Scrollbar.rightarrow",
	&ArrowElementSpec, 0);

    /*
     * Layouts:
     */

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::aqua", TTK_VERSION);
    return TCL_OK;
}

MODULE_SCOPE
int Ttk_MacOSXPlatformInit(
    Tcl_Interp *interp)
{
    return AquaTheme_Init(interp);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */




|






<







|


|
|
|
|
>
|

|
|
>




<


<
>

<
|

|

|


<







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
|

<
|
<
<

|


|
|
|
|









<




<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
<

>
>
>





>

|
|
|
|
|
<
|
<
|
|

<
|
|
|
<
<
|
<
<
<

>

<
|
|
<
|
>
|


<
>
|
<
|

<

|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|







<
<
<
<
|
|
<
<
<
<
|

|


<
|
<
<
<
<
<

<
|
<
<
<
<
<
<
|
<




|
<
<
<
<
|


|
<

|
<

>
|
|


<
|
<
<
|
<
<
<
|
|
>
>
|
|
|
>
>
|
>
>
>


<
<
<
<
|
|
<
<
|



|
<
<
|
<
<


|
|

<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















>

>
>
>

|
|
|
|
|
|
|

>

|
>
|
|
|

>

|
>
|
|
|

















|
<













<









>

<
<
|
<
<
|

|
|




<
<
|
|
<
<













<
<
<
|
<
<














<

<
<
|
<
<
|





<
<
|
|
<
<


>
>
>
>
>
>
>
>




<
<
<
<
<
<
<
<
<
<
<
<
<
|
<











|
|
<
|
|
>
|

|
|

<

<
<
|
<
<
|





<
<
|
|
<
<


<
<
<
<
<
|
|
|
|
|
<
|
>
>












|
<
|
|



|
<


<
<

|
|
<
<
<
>



<
<
|
<
<
|

|



<
|
<
|
<
<


>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|

|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
>
>
>
|
<











|


<
<
|
<
<
<
<
<
<
<
<
<
<
<
>


|
>


<
<
|
<
<
|

|
|
|



<
<
|
|
<
<

|









<
<
<
<
<
<
<
<
<
<
<
<













|

|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<
|
<
<
|
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|

|


|
<
<
|
|
<
<


<
|
<
<
<
<
<
<
<
>
>


|






<
<
<
|
<
<



|



|
|

>



<
|
<
<
<
<
<



|
|
|



|
|
|







|
|
|
|



|
|
|
|
|

>

|
<
<
<
<
|

|
|


|



|
<
<
|
<
<



|

<

|



|

<
<
<
<
<
<



|




|
|






|
<
<
<
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<












|
|
<




>
>
>

<

<
<
|
<
<
|

|











|







|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|

>

<
<
|
<
<
|

|


|



<
|
<
|
<
<


|
<

<

|





<
<
<
<
<
<


<
<
|
|
|




|
|





<
<
<
<
<
<
<
<
<
<
<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|
|



<
<
|
<
<
|

|



<
<
|
<
<
|




|
|
<



<
<
<
|
<
<












|

<

|


<
<
|
<
<
|











|
|



<
<
|
<
<
|




|
|
<






|
<












|

<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<

|
|
<
|
<



<
<
|
|
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


>
|
|
|
|
|
|
|
<

|
<
<
<
<
|

>
|
|









>











|
|
|
|

|
|
|


<

<
<
|
|
<
<




















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<


>

|
|
|

<

|
>
>
|
<
<
|
|
|
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<







|



|
|

<
|
|

|
|

>

<
<
|
<
<
|




|

|



<
<
|
|
<
<


<
<



|






<
<
<
<
<
<
<
<
<
<
<
<
|
<
<













|









|
|



|
|



|
|



|
|


|
|
|




|
|

|

<
|
<
|
|

<

|
<
<
<
<
<
<



|

|




|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|


|
<










<
|
<

<













|
|
<
<







<
<



|
<
|
|

|
|
|

|



<
<
<
<
|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|
|
<
|
<
<
<




<







|
<



|








>
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36

37
38

39
40
41
42
43
44
45

46
47
48
49
50
51
52























































































53
54
55
56
57
58
59
60
61

62


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83

84
85
86
87





















































































































































































































































































88

































































































































89





90







91


























92






















































































93





















































































































































































































































































































































































































94


































































































































95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118

119
120
121

122
123
124


125



126
127
128

129
130

131
132
133
134
135

136
137

138
139

140
141


142


















143
144
145
146
147
148
149
150
151
152




153
154




155
156
157
158
159

160





161

162






163

164
165
166
167
168




169
170
171
172

173
174

175
176
177
178
179
180

181


182



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197




198
199


200
201
202
203
204


205


206
207
208
209
210


211
















212











































213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298


299


300
301
302
303
304
305
306
307


308
309


310
311
312
313
314
315
316
317
318
319
320
321
322



323


324
325
326
327
328
329
330
331
332
333
334
335
336
337

338


339


340
341
342
343
344
345


346
347


348
349
350
351
352
353
354
355
356
357
358
359
360
361













362

363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383

384


385


386
387
388
389
390
391


392
393


394
395





396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422

423
424


425
426
427



428
429
430
431


432


433
434
435
436
437
438

439

440


441
442
443
444
445





























446
447
448
449
450
451
452
453





454
455








456
457
458
459
460









461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479


480











481
482
483
484
485
486
487


488


489
490
491
492
493
494
495
496


497
498


499
500
501
502
503
504
505
506
507
508
509












510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527













528
529
530

531


532


533
534
535





































536




















537
538
539
540
541
542
543


544
545


546
547

548







549
550
551
552
553
554
555
556
557
558
559



560


561
562
563
564
565
566
567
568
569
570
571
572
573
574

575





576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610




611
612
613
614
615
616
617
618
619
620
621


622


623
624
625
626
627

628
629
630
631
632
633
634






635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651



652
653
654
655













656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677

678


679


680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723


724


725
726
727
728
729
730
731
732
733

734

735


736
737
738

739

740
741
742
743
744
745
746






747
748


749
750
751
752
753
754
755
756
757
758
759
760
761
762













763
764
765
766
767
768
769
770
771
772
773
774
































































































































































































































































775
776
777
778
779
780
781
782
783


784


785
786
787
788
789
790


791


792
793
794
795
796
797
798

799
800
801



802


803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820


821


822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838


839


840
841
842
843
844
845
846

847
848
849
850
851
852
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867

868


869



















870








871
872
873

874

875
876
877


878
879


880
881














882
883
884
885
886
887
888
889
890
891
892

893
894




895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

931


932
933


934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953










































954

955


956
957
958
959
960
961
962
963

964
965
966
967
968


969
970
971
972
973
974










































975
976


977


978
979
980
981
982
983
984
985
986
987
988
989














990


991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1012


1013


1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024


1025
1026


1027
1028


1029
1030
1031
1032
1033
1034
1035
1036
1037
1038












1039


1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093

1094

1095
1096
1097

1098
1099






1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112














1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130

1131

1132

1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147


1148
1149
1150
1151
1152
1153
1154


1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169




1170


1171



1172












1173

1174
1175
1176

1177



1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
/*
 * ttkMacOSXTheme.c --
 *
 *	Tk theme engine for Mac OSX, using the Appearance Manager API.
 *
 * Copyright (c) 2004 Joe English
 * Copyright (c) 2005 Neil Madden
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 * Copyright 2009 Kevin Walzer/WordTech Communications LLC.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * See also:
 *
 * <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *	Appearance_Manager/appearance_manager/APIIndex.html >
 *
 * Notes:
 *	"Active" means different things in Mac and Tk terminology --
 *	On Aqua, widgets are "Active" if they belong to the foreground window,
 *	"Inactive" if they are in a background window.
 *	Tk uses the term "active" to mean that the mouse cursor
 *	is over a widget; aka "hover", "prelight", or "hot-tracked".
 *	Aqua doesn't use this kind of feedback.
 *
 *	The QuickDraw/Carbon coordinate system is relative to the
 *	top-level window, not to the Tk_Window.  BoxToRect()
 *	accounts for this.
 */

#include "tkMacOSXPrivate.h"
#include "ttk/ttkTheme.h"


/*

 * Use this version in the core:
 */

#define BEGIN_DRAWING(d) { \
	TkMacOSXDrawingContext dc; \
	if (!TkMacOSXSetupDrawingContext((d), NULL, 1, &dc)) {return;}
#define END_DRAWING \
	TkMacOSXRestoreDrawingContext(&dc); }

#define HIOrientation kHIThemeOrientationNormal


#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */
























































































/*----------------------------------------------------------------------
 * +++ Utilities.
 */

/*
 * BoxToRect --
 *	Convert a Ttk_Box in Tk coordinates relative to the given Drawable
 *	to a native Rect relative to the containing port.
 */

static inline CGRect BoxToRect(Drawable d, Ttk_Box b)


{
    MacDrawable *md = (MacDrawable*)d;
    CGRect rect;

    rect.origin.y	= b.y + md->yOff;
    rect.origin.x	= b.x + md->xOff;
    rect.size.height	= b.height;
    rect.size.width	= b.width;

    return rect;
}

/*
 * Table mapping Tk states to Appearance manager ThemeStates
 */

static Ttk_StateTable ThemeStateTable[] = {

    {kThemeStateUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeStatePressed, TTK_STATE_PRESSED, 0},
    {kThemeStateInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeStateActive, 0, 0}

/* Others: Not sure what these are supposed to mean.
   Up/Down have something to do with "little arrow" increment controls...
   Dunno what a "Rollover" is.
   NEM: Rollover is TTK_STATE_ACTIVE... but we don't handle that yet, by the





















































































































































































































































































   looks of things

































































































































    {kThemeStateRollover, 0, 0},





    {kThemeStateUnavailableInactive, 0, 0}







    {kThemeStatePressedUp, 0, 0},


























    {kThemeStatePressedDown, 0, 0}






















































































*/





















































































































































































































































































































































































































};



































































































































/*----------------------------------------------------------------------
 * +++ Button element: Used for elements drawn with DrawThemeButton.
 */

/*
 * Extra margins to account for drop shadow.

 */
static Ttk_Padding ButtonMargins = {2,2,2,2};

#define NoThemeMetric 0xFFFFFFFF

typedef struct {
    ThemeButtonKind kind;
    ThemeMetric heightMetric;
} ThemeButtonParams;

static ThemeButtonParams
    PushButtonParams = { kThemePushButton, kThemeMetricPushButtonHeight },
    CheckBoxParams = { kThemeCheckBox, kThemeMetricCheckBoxHeight },
    RadioButtonParams = { kThemeRadioButton, kThemeMetricRadioButtonHeight },
    BevelButtonParams = { kThemeBevelButton, NoThemeMetric },
    PopupButtonParams = { kThemePopupButton, kThemeMetricPopupButtonHeight },

    DisclosureParams = { kThemeDisclosureButton, kThemeMetricDisclosureTriangleHeight },

    ListHeaderParams = { kThemeListHeaderButton, kThemeMetricListHeaderHeight };

static Ttk_StateTable ButtonValueTable[] = {

    { kThemeButtonMixed, TTK_STATE_ALTERNATE, 0 },
    { kThemeButtonOn, TTK_STATE_SELECTED, 0 },
    { kThemeButtonOff, 0, 0 }


/* Others: kThemeDisclosureRight, kThemeDisclosureDown, kThemeDisclosureLeft */



};

static Ttk_StateTable ButtonAdornmentTable[] = {

    { kThemeAdornmentDefault| kThemeAdornmentFocus,
	TTK_STATE_ALTERNATE| TTK_STATE_FOCUS, 0 },

    { kThemeAdornmentDefault, TTK_STATE_ALTERNATE, 0 },
    { kThemeAdornmentFocus, TTK_STATE_FOCUS, 0 },
    { kThemeAdornmentNone, 0, 0 }
};


/*
 * computeButtonDrawInfo --

 *	Fill in an appearance manager HIThemeButtonDrawInfo record.
 */

static inline HIThemeButtonDrawInfo computeButtonDrawInfo(
	ThemeButtonParams *params, Ttk_State state)


{


















    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = params ? params->kind : 0,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };
    return info;
}





static void ButtonElementSizeNoPadding(
    void *clientData, void *elementRecord, Tk_Window tkwin,




    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;

    if (params->heightMetric != NoThemeMetric) {

	SInt32 height;







	ChkErr(GetThemeMetric, params->heightMetric, &height);






	*heightPtr = height;

    }
}

static void ButtonElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,




    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;
    const HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, 0);

    static const CGRect scratchBounds = {{0, 0}, {100, 100}};
    CGRect contentBounds;


    ButtonElementSizeNoPadding(
	clientData, elementRecord, tkwin,
	widthPtr, heightPtr, paddingPtr);

    /*

     * To compute internal padding, query the appearance manager


     * for the content bounds of a dummy rectangle, then use



     * the difference as the padding.
     */
    ChkErr(HIThemeGetButtonContentBounds,
	&scratchBounds, &info, &contentBounds);

    paddingPtr->left = CGRectGetMinX(contentBounds);
    paddingPtr->top = CGRectGetMinY(contentBounds);
    paddingPtr->right = CGRectGetMaxX(scratchBounds) - CGRectGetMaxX(contentBounds) + 1;
    paddingPtr->bottom = CGRectGetMaxY(scratchBounds) - CGRectGetMaxY(contentBounds);

    /*
     * Now add a little extra padding to account for drop shadows.
     * @@@ SHOULD: call GetThemeButtonBackgroundBounds() instead.
     */





    *paddingPtr = Ttk_AddPadding(*paddingPtr, ButtonMargins);
    *widthPtr += Ttk_PaddingWidth(ButtonMargins);


    *heightPtr += Ttk_PaddingHeight(ButtonMargins);
}

static void ButtonElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, Ttk_State state)


{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, ButtonMargins));
    const HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, state);



    BEGIN_DRAWING(d)
















    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);











































    END_DRAWING
}

static Ttk_ElementSpec ButtonElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ButtonElementSize,
    ButtonElementDraw
};

/*----------------------------------------------------------------------
 * +++ Notebook elements.
 */


/* Tab position logic, c.f. ttkNotebook.c TabState() */

#define TTK_STATE_NOTEBOOK_FIRST	TTK_STATE_USER1
#define TTK_STATE_NOTEBOOK_LAST 	TTK_STATE_USER2
static Ttk_StateTable TabStyleTable[] = {
    { kThemeTabFrontInactive, TTK_STATE_SELECTED|TTK_STATE_BACKGROUND},
    { kThemeTabNonFrontInactive, TTK_STATE_BACKGROUND},
    { kThemeTabFrontUnavailable, TTK_STATE_DISABLED|TTK_STATE_SELECTED},
    { kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED},
    { kThemeTabFront, TTK_STATE_SELECTED},
    { kThemeTabNonFrontPressed, TTK_STATE_PRESSED},
    { kThemeTabNonFront, 0}
};

static Ttk_StateTable TabAdornmentTable[] = {
    { kHIThemeTabAdornmentNone,
	    TTK_STATE_NOTEBOOK_FIRST|TTK_STATE_NOTEBOOK_LAST},
    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_NOTEBOOK_FIRST},
    {kHIThemeTabAdornmentNone, TTK_STATE_NOTEBOOK_LAST},
    {kHIThemeTabAdornmentTrailingSeparator, 0 },
};

static Ttk_StateTable TabPositionTable[] = {
    { kHIThemeTabPositionOnly,
	    TTK_STATE_NOTEBOOK_FIRST|TTK_STATE_NOTEBOOK_LAST},
    { kHIThemeTabPositionFirst, TTK_STATE_NOTEBOOK_FIRST},
    { kHIThemeTabPositionLast, TTK_STATE_NOTEBOOK_LAST},
    { kHIThemeTabPositionMiddle, 0 },
};

/*
 * Apple XHIG Tab View Specifications:
 *
 * Control sizes: Tab views are available in regular, small, and mini sizes.
 * The tab height is fixed for each size, but you control the size of the pane
 * area. The tab heights for each size are listed below:
 *  - Regular size: 20 pixels.
 *  - Small: 17 pixels.
 *  - Mini: 15 pixels.
 *
 * Label spacing and fonts: The tab labels should be in a font that’s
 * proportional to the size of the tab view control. In addition, the label
 * should be placed so that there are equal margins of space before and after
 * it. The guidelines below provide the specifications you should use for tab
 * labels:
 *  - Regular size: System font. Center in tab, leaving 12 pixels on each side.

 *  - Small: Small system font. Center in tab, leaving 10 pixels on each side.
 *  - Mini: Mini system font. Center in tab, leaving 8 pixels on each side.
 *
 * Control spacing: Whether you decide to inset a tab view in a window or
 * extend its edges to the window sides and bottom, you should place the top
 * edge of the tab view 12 or 14 pixels below the bottom edge of the title bar
 * (or toolbar, if there is one). If you choose to inset a tab view in a
 * window, you should leave a margin of 20 pixels between the sides and bottom
 * of the tab view and the sides and bottom of the window (although 16 pixels
 * is also an acceptable margin-width). If you need to provide controls below
 * the tab view, leave enough space below the tab view so the controls are 20
 * pixels above the bottom edge of the window and 12 pixels between the tab
 * view and the controls.

 * If you choose to extend the tab view sides and bottom so that they meet the
 * window sides and bottom, you should leave a margin of at least 20 pixels
 * between the content in the tab view and the tab-view edges.
 *
 * <URL: http://developer.apple.com/documentation/userexperience/Conceptual/
 *       AppleHIGuidelines/XHIGControls/XHIGControls.html#//apple_ref/doc/uid/
 *       TP30000359-TPXREF116>
 */


static void TabElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    GetThemeMetric(kThemeMetricLargeTabHeight, (SInt32 *)heightPtr);
     *paddingPtr = Ttk_MakePadding(0, 0, 0, 2);

}

static void TabElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, b);
    HIThemeTabDrawInfo info = {
	.version = 1,
	.style = Ttk_StateTableLookup(TabStyleTable, state),
	.direction = kThemeTabNorth,
	.size = kHIThemeTabSizeNormal,
	.adornment = Ttk_StateTableLookup(TabAdornmentTable, state),
	.kind = kHIThemeTabKindNormal,
	.position = Ttk_StateTableLookup(TabPositionTable, state),
    };

    BEGIN_DRAWING(d)



    ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation, NULL);


    END_DRAWING
}

static Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Notebook panes:
 */

static void PaneElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(9, 5, 9, 9);
}

static void PaneElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, b);
    HIThemeTabPaneDrawInfo info = {
	.version = 1,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.direction = kThemeTabNorth,
	.size = kHIThemeTabSizeNormal,
	.kind = kHIThemeTabKindNormal,
	.adornment = kHIThemeTabPaneAdornmentNormal,
    };

    bounds.origin.y -= kThemeMetricTabFrameOverlap;
    bounds.size.height += kThemeMetricTabFrameOverlap;
    BEGIN_DRAWING(d)













    ChkErr(HIThemeDrawTabPane, &bounds, &info, dc.context, HIOrientation);

    END_DRAWING
}

static Ttk_ElementSpec PaneElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    PaneElementSize,
    PaneElementDraw
};

/*
 * Labelframe borders:

 * Use "primary group box ..."
 * Quoth DrawThemePrimaryGroup reference:
 * "The primary group box frame is drawn inside the specified
 * rectangle and is a maximum of 2 pixels thick."
 *
 * "Maximum of 2 pixels thick" is apparently a lie;
 * looks more like 4 to me with shading.
 */

static void GroupElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(4);
}

static void GroupElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, b);





    const HIThemeGroupBoxDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = kHIThemeGroupBoxKindPrimaryOpaque,
    };


    BEGIN_DRAWING(d)
    ChkErr(HIThemeDrawGroupBox, &bounds, &info, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec GroupElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GroupElementSize,
    GroupElementDraw
};

/*----------------------------------------------------------------------
 * +++ Entry element --

 *	3 pixels padding for focus rectangle
 *	2 pixels padding for EditTextFrame
 */

typedef struct {
    Tcl_Obj	*backgroundObj;

} EntryElement;



static Ttk_ElementOptionSpec EntryElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	    Tk_Offset(EntryElement,backgroundObj), "white" },



    {0}
};

static void EntryElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(5);
}

static void EntryElementDraw(

    void *clientData, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    EntryElement *e = elementRecord;
    Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,e->backgroundObj);
    Ttk_Box inner = Ttk_PadBox(b, Ttk_UniformPadding(3));
    CGRect bounds = BoxToRect(d, inner);





























    const HIThemeFrameDrawInfo info = {
	.version = 0,
	.kind = kHIThemeFrameTextFieldSquare,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.isFocused = state & TTK_STATE_FOCUS,
    };

    /*





     * Erase w/background color:
     */








    XFillRectangle(Tk_Display(tkwin), d,
	    Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	    inner.x,inner.y, inner.width, inner.height);

    BEGIN_DRAWING(d)









    ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
    /*if (state & TTK_STATE_FOCUS) {
	ChkErr(DrawThemeFocusRect, &bounds, 1);
    }*/
    END_DRAWING

}

static Ttk_ElementSpec EntryElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(EntryElement),
    EntryElementOptions,
    EntryElementSize,
    EntryElementDraw
};

/*----------------------------------------------------------------------
 * +++ Combobox:
 *
 * NOTES:


 *	kThemeMetricComboBoxLargeDisclosureWidth -> 17











 *	Padding and margins guesstimated by trial-and-error.
 */

static Ttk_Padding ComboboxPadding = { 2, 3, 17, 1 };
static Ttk_Padding ComboboxMargins = { 3, 3, 4, 4 };

static void ComboboxElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *widthPtr = 0;
    *heightPtr = 0;
    *paddingPtr = Ttk_AddPadding(ComboboxMargins, ComboboxPadding);
}

static void ComboboxElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, ComboboxMargins));
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = kThemeComboBox,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };

    BEGIN_DRAWING(d)












    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    END_DRAWING
}

static Ttk_ElementSpec ComboboxElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ComboboxElementSize,
    ComboboxElementDraw
};

/*----------------------------------------------------------------------
 * +++ Spinbuttons.
 *
 * From Apple HIG, part III, section "Controls", "The Stepper Control":
 * there should be 2 pixels of space between the stepper control
 * (AKA IncDecButton, AKA "little arrows") and the text field it modifies.













 */

static Ttk_Padding SpinbuttonMargins = {2,0,2,0};

static void SpinButtonElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SInt32 s;


























































    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *widthPtr = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *heightPtr = s + Ttk_PaddingHeight(SpinbuttonMargins);
}

static void SpinButtonElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));

    /* @@@ can't currently distinguish PressedUp (== Pressed) from PressedDown;







     * ignore this bit for now [see #2219588]
     */
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state & ~TTK_STATE_PRESSED),
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };

    BEGIN_DRAWING(d)



    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);


    END_DRAWING
}

static Ttk_ElementSpec SpinButtonElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonElementSize,
    SpinButtonElementDraw
};


/*----------------------------------------------------------------------
 * +++ DrawThemeTrack-based elements --

 * Progress bars and scales. (See also: <<NOTE-TRACKS>>)





 */

static Ttk_StateTable ThemeTrackEnableTable[] = {
    { kThemeTrackDisabled, TTK_STATE_DISABLED, 0 },
    { kThemeTrackInactive, TTK_STATE_BACKGROUND, 0 },
    { kThemeTrackActive, 0, 0 }
    /* { kThemeTrackNothingToScroll, ?, ? }, */
};

typedef struct {	/* TrackElement client data */
    ThemeTrackKind	kind;
    SInt32		thicknessMetric;
} TrackElementData;

static TrackElementData ScaleData = {
    kThemeSlider, kThemeMetricHSliderHeight
};

typedef struct {
    Tcl_Obj *fromObj;		/* minimum value */
    Tcl_Obj *toObj;		/* maximum value */
    Tcl_Obj *valueObj;		/* current value */
    Tcl_Obj *orientObj;		/* horizontal / vertical */
} TrackElement;

static Ttk_ElementOptionSpec TrackElementOptions[] = {
    { "-from", TK_OPTION_DOUBLE, Tk_Offset(TrackElement,fromObj) },
    { "-to", TK_OPTION_DOUBLE, Tk_Offset(TrackElement,toObj) },
    { "-value", TK_OPTION_DOUBLE, Tk_Offset(TrackElement,valueObj) },
    { "-orient", TK_OPTION_STRING, Tk_Offset(TrackElement,orientObj) },
    {0,0,0}
};

static void TrackElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,




    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TrackElementData *data = clientData;
    SInt32 size = 24;	/* reasonable default ... */

    ChkErr(GetThemeMetric, data->thicknessMetric, &size);
    *widthPtr = *heightPtr = size;
}

static void TrackElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, Ttk_State state)


{
    TrackElementData *data = clientData;
    TrackElement *elem = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, factor;


    Ttk_GetOrientFromObj(NULL, elem->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, elem->fromObj, &from);
    Tcl_GetDoubleFromObj(NULL, elem->toObj, &to);
    Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value);
    factor = RangeToFactor(to - from);







    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind = data->kind,
	.bounds = BoxToRect(d, b),
	.min = from * factor,
	.max = to * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
		(orientation == TTK_ORIENT_HORIZONTAL ?
		kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = 0,
    };

    if (info.kind == kThemeSlider) {
	info.trackInfo.slider.pressState = state & TTK_STATE_PRESSED ?
		kThemeThumbPressed : 0;



	info.trackInfo.slider.thumbDir = kThemeThumbPlain;
    }

    BEGIN_DRAWING(d)













    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec TrackElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TrackElement),
    TrackElementOptions,
    TrackElementSize,
    TrackElementDraw
};

/*
 * Slider element -- <<NOTE-TRACKS>>

 * Has geometry only. The Scale widget adjusts the position of this element,
 * and uses it for hit detection. In the Aqua theme, the slider is actually
 * drawn as part of the trough element.
 *
 * Also buggy: The geometry here is a Wild-Assed-Guess; I can't
 * figure out how to get the Appearance Manager to tell me the
 * slider size.
 */

static void SliderElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *widthPtr = *heightPtr = 24;
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SliderElementSize,
    TtkNullElementDraw
};

/*----------------------------------------------------------------------
 * +++ Progress bar element (new):
 *
 * @@@ NOTE: According to an older revision of the Aqua reference docs,
 * @@@ the 'phase' field is between 0 and 4. Newer revisions say
 * @@@ that it can be any UInt8 value.
 */

typedef struct {
    Tcl_Obj *orientObj;		/* horizontal / vertical */
    Tcl_Obj *valueObj;		/* current value */
    Tcl_Obj *maximumObj;	/* maximum value */
    Tcl_Obj *phaseObj;		/* animation phase */
    Tcl_Obj *modeObj;		/* progress bar mode */
} PbarElement;

static Ttk_ElementOptionSpec PbarElementOptions[] = {
    { "-orient", TK_OPTION_STRING,
	Tk_Offset(PbarElement,orientObj), "horizontal" },
    { "-value", TK_OPTION_DOUBLE,
	Tk_Offset(PbarElement,valueObj), "0" },
    { "-maximum", TK_OPTION_DOUBLE,
	Tk_Offset(PbarElement,maximumObj), "100" },
    { "-phase", TK_OPTION_INT,
	Tk_Offset(PbarElement,phaseObj), "0" },
    { "-mode", TK_OPTION_STRING,
	Tk_Offset(PbarElement,modeObj), "determinate" },
    {0,0,0,0}
};

static void PbarElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SInt32 size = 24;	/* @@@ Check HIG for correct default */

    ChkErr(GetThemeMetric, kThemeMetricLargeProgressBarThickness, &size);
    *widthPtr = *heightPtr = size;
}

static void PbarElementDraw(

    void *clientData, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    PbarElement *pbar = elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL, phase = 0;

    double value = 0, maximum = 100, factor;


    Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);
    factor = RangeToFactor(maximum);







    HIThemeTrackDrawInfo info = {
	.version = 0,


	.kind = (!strcmp("indeterminate", Tcl_GetString(pbar->modeObj)) && value) ?
		kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = BoxToRect(d, b),
	.min = 0,
	.max = maximum * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
		(orientation == TTK_ORIENT_HORIZONTAL ?
		kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = phase,
    };

    BEGIN_DRAWING(d)













    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PbarElement),
    PbarElementOptions,
    PbarElementSize,
    PbarElementDraw
};

































































































































































































































































/*----------------------------------------------------------------------
 * +++ Separator element.
 *
 * DrawThemeSeparator() guesses the orientation of the line from
 * the width and height of the rectangle, so the same element can
 * can be used for horizontal, vertical, and general separators.
 */

static void SeparatorElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    *widthPtr = *heightPtr = 1;
}

static void SeparatorElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeSeparatorDrawInfo info = {
	.version = 0,
	/* Separator only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable, state & TTK_STATE_BACKGROUND),

    };

    BEGIN_DRAWING(d)



    ChkErr(HIThemeDrawSeparator, &bounds, &info, dc.context, HIOrientation);


    END_DRAWING
}

static Ttk_ElementSpec SeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SeparatorElementSize,
    SeparatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Size grip element.
 */

static const ThemeGrowDirection sizegripGrowDirection
	= kThemeGrowRight|kThemeGrowDown;

static void SizegripElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
	.state = kThemeStateActive,
	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };
    CGRect bounds = CGRectZero;

    ChkErr(HIThemeGetGrowBoxBounds, &bounds.origin, &info, &bounds);
    *widthPtr = bounds.size.width;
    *heightPtr = bounds.size.height;
}

static void SizegripElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
	/* Grow box only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable, state & TTK_STATE_BACKGROUND),

	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };

    BEGIN_DRAWING(d)
    ChkErr(HIThemeDrawGrowBox, &bounds.origin, &info, dc.context, HIOrientation);

    END_DRAWING
}

static Ttk_ElementSpec SizegripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SizegripElementSize,
    SizegripElementDraw
};

/*----------------------------------------------------------------------
 * +++ Background and fill elements.
 *

 *	This isn't quite right: In Aqua, the correct background for


 *	a control depends on what kind of container it belongs to,



















 *	and the type of the top-level window.








 *
 *	Also: patterned backgrounds should be aligned with the coordinate
 *	system of the top-level window.  If we're drawing into an

 *	off-screen graphics port this leads to alignment glitches.

 */

static void FillElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    CGRect bounds = BoxToRect(d, b);














    ThemeBrush brush = (state & TTK_STATE_BACKGROUND)
	    ? kThemeBrushModelessDialogBackgroundInactive
	    : kThemeBrushModelessDialogBackgroundActive;

    BEGIN_DRAWING(d)
    ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);
    //QDSetPatternOrigin(PatternOrigin(tkwin, d));
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}


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(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    FillElementDraw
};

static Ttk_ElementSpec BackgroundElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    BackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ ToolbarBackground element -- toolbar style for frames.
 *
 *	This is very similar to the normal background element, but uses a
 *	different ThemeBrush in order to get the lighter pinstripe effect
 *	used in toolbars. We use SetThemeBackground() rather than
 *	ApplyThemeBackground() in order to get the right style.
 *
 * <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *	Appearance_Manager/appearance_manager/constant_7.html#/
 *	/apple_ref/doc/uid/TP30000243/C005321>
 *
 */

static void ToolbarBackgroundElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    ThemeBrush brush = kThemeBrushToolbarBackground;
    CGRect bounds = BoxToRect(d, Ttk_WinBox(tkwin));

    BEGIN_DRAWING(d)
    ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);
    //QDSetPatternOrigin(PatternOrigin(tkwin, d));
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}

static Ttk_ElementSpec ToolbarBackgroundElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    ToolbarBackgroundElementDraw
};

/*----------------------------------------------------------------------










































 * +++ Treeview header

 *	Redefine the header to use a kThemeListHeaderButton.


 */

#define TTK_TREEVIEW_STATE_SORTARROW	TTK_STATE_USER1
static Ttk_StateTable TreeHeaderValueTable[] = {
    { kThemeButtonOn, TTK_STATE_ALTERNATE},
    { kThemeButtonOn, TTK_STATE_SELECTED},
    { kThemeButtonOff, 0}
};

static Ttk_StateTable TreeHeaderAdornmentTable[] = {
    { kThemeAdornmentHeaderButtonSortUp,
	    TTK_STATE_ALTERNATE|TTK_TREEVIEW_STATE_SORTARROW},
    { kThemeAdornmentDefault,
	    TTK_STATE_SELECTED|TTK_TREEVIEW_STATE_SORTARROW},


    { kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_ALTERNATE},
    { kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_SELECTED},
    { kThemeAdornmentFocus, TTK_STATE_FOCUS},
    { kThemeAdornmentNone, 0}
};











































static void TreeHeaderElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, Ttk_State state)


{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = params->kind,
	.value = Ttk_StateTableLookup(TreeHeaderValueTable, state),
	.adornment = Ttk_StateTableLookup(TreeHeaderAdornmentTable, state),
    };

    BEGIN_DRAWING(d)














    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);


    END_DRAWING
}

static Ttk_ElementSpec TreeHeaderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ButtonElementSizeNoPadding,
    TreeHeaderElementDraw
};

/*
 * Disclosure triangle:
 */

#define TTK_TREEVIEW_STATE_OPEN 	TTK_STATE_USER1
#define TTK_TREEVIEW_STATE_LEAF 	TTK_STATE_USER2
static Ttk_StateTable DisclosureValueTable[] = {
    { kThemeDisclosureDown, TTK_TREEVIEW_STATE_OPEN, 0 },
    { kThemeDisclosureRight, 0, 0 },
};

static void DisclosureElementSize(


    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s);
    *widthPtr = s;
    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s);
    *heightPtr = s;
}

static void DisclosureElementDraw(


    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)


{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {


	CGRect bounds = BoxToRect(d, b);
	const HIThemeButtonDrawInfo info = {
	    .version = 0,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .kind = kThemeDisclosureTriangle,
	    .value = Ttk_StateTableLookup(DisclosureValueTable, state),
	    .adornment = kThemeAdornmentDrawIndicatorOnly,
	};

	BEGIN_DRAWING(d)












	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);


	END_DRAWING
    }
}

static Ttk_ElementSpec DisclosureElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    DisclosureElementSize,
    DisclosureElementDraw
};

/*----------------------------------------------------------------------
 * +++ Widget layouts.
 */

TTK_BEGIN_LAYOUT_TABLE(LayoutTable)

TTK_LAYOUT("Toolbar",
    TTK_NODE("Toolbar.background", TTK_FILL_BOTH))

TTK_LAYOUT("TButton",
    TTK_GROUP("Button.button", TTK_FILL_BOTH,
	TTK_GROUP("Button.padding", TTK_FILL_BOTH,
	    TTK_NODE("Button.label", TTK_FILL_BOTH))))

TTK_LAYOUT("TRadiobutton",
    TTK_GROUP("Radiobutton.button", TTK_FILL_BOTH,
	TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
	    TTK_NODE("Radiobutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCheckbutton",
    TTK_GROUP("Checkbutton.button", TTK_FILL_BOTH,
	TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
	    TTK_NODE("Checkbutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TMenubutton",
    TTK_GROUP("Menubutton.button", TTK_FILL_BOTH,
	TTK_GROUP("Menubutton.padding", TTK_FILL_BOTH,
	    TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.button", TTK_PACK_TOP|TTK_FILL_X,
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Combobox.textarea", TTK_FILL_X))))

/* Notebook tabs -- no focus ring */
TTK_LAYOUT("Tab",
    TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
	TTK_GROUP("Notebook.padding", TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_NODE("Notebook.label", TTK_EXPAND|TTK_FILL_BOTH))))

/* Progress bars -- track only */
TTK_LAYOUT("TSpinbox",

    TTK_NODE("Spinbox.spinbutton", TTK_PACK_RIGHT|TTK_STICK_E)

    TTK_GROUP("Spinbox.field", TTK_EXPAND|TTK_FILL_X,
	TTK_NODE("Spinbox.textarea", TTK_EXPAND|TTK_FILL_X)))


TTK_LAYOUT("TProgressbar",
    TTK_NODE("Progressbar.track", TTK_EXPAND|TTK_FILL_BOTH))







/* Tree heading -- no border, fixed height */
TTK_LAYOUT("Heading",
    TTK_NODE("Treeheading.cell", TTK_FILL_X)
    TTK_NODE("Treeheading.image", TTK_PACK_RIGHT)
    TTK_NODE("Treeheading.text", 0))

/* Tree items -- omit focus ring */
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_NODE("Treeitem.text", TTK_PACK_LEFT)))















TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ Initialization.
 */

static int AquaTheme_Init(Tcl_Interp *interp)

{
    Ttk_Theme themePtr = Ttk_CreateTheme(interp, "aqua", NULL);

    if (!themePtr) {
	return TCL_ERROR;
    }

    /*
     * Elements:
     */

    Ttk_RegisterElementSpec(themePtr, "background", &BackgroundElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "fill", &FillElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Toolbar.background",
	&ToolbarBackgroundElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Button.button",
	&ButtonElementSpec, &PushButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Checkbutton.button",
	&ButtonElementSpec, &CheckBoxParams);
    Ttk_RegisterElementSpec(themePtr, "Radiobutton.button",
	&ButtonElementSpec, &RadioButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Toolbutton.border",
	&ButtonElementSpec, &BevelButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Menubutton.button",
	&ButtonElementSpec, &PopupButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.spinbutton",
    	&SpinButtonElementSpec, 0);


    Ttk_RegisterElementSpec(themePtr, "Combobox.button",
	&ComboboxElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator",
	&DisclosureElementSpec, &DisclosureParams);
    Ttk_RegisterElementSpec(themePtr, "Treeheading.cell",
	&TreeHeaderElementSpec, &ListHeaderParams);



    Ttk_RegisterElementSpec(themePtr, "Notebook.tab", &TabElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.client", &PaneElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Labelframe.border",&GroupElementSpec,0);

    Ttk_RegisterElementSpec(themePtr, "Entry.field",&EntryElementSpec,0);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.field",&EntryElementSpec,0);

    Ttk_RegisterElementSpec(themePtr, "separator",&SeparatorElementSpec,0);
    Ttk_RegisterElementSpec(themePtr, "hseparator",&SeparatorElementSpec,0);
    Ttk_RegisterElementSpec(themePtr, "vseparator",&SeparatorElementSpec,0);

    Ttk_RegisterElementSpec(themePtr, "sizegrip",&SizegripElementSpec,0);

    /*
     * <<NOTE-TRACKS>>




     * The Progressbar widget adjusts the size of the pbar element.


     * In the Aqua theme, the appearance manager computes the bar geometry;



     * we do all the drawing in the ".track" element and leave the .pbar out.












     */

    Ttk_RegisterElementSpec(themePtr,"Scale.trough",
	&TrackElementSpec, &ScaleData);
    Ttk_RegisterElementSpec(themePtr,"Scale.slider",&SliderElementSpec,0);

    Ttk_RegisterElementSpec(themePtr,"Progressbar.track", &PbarElementSpec, 0);




    /*
     * Layouts:
     */

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::aqua", TTK_VERSION);
    return TCL_OK;
}

MODULE_SCOPE
int Ttk_MacOSXPlatformInit(Tcl_Interp *interp)

{
    return AquaTheme_Init(interp);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to tests/all.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# all.tcl --
#
# This file contains a top-level script to run all of the Tk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 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.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [tcltest::testsDirectory] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]
encoding system utf-8
if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}






|












<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
# all.tcl --
#
# This file contains a top-level script to run all of the Tk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# 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.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [tcltest::testsDirectory] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]

if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}

Changes to tests/arc.tcl.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
.t.c create arc 340 450 460 570 -start 320 -extent 270 -fill $fill1 -width 14 \
	-style chord -outline {}
.t.c create arc 500 450 620 570 -start 350 -extent -110 -fill $fill1 -width 14 \
	-style chord -outline {}
.t.c addtag arc withtag all
.t.c addtag circle withtag [.t.c create oval 320 200 340 220 -fill MistyRose3]

.t.c bind arc <Enter> {
    set prevFill [lindex [.t.c itemconf current -fill] 4]
    set prevOutline [lindex [.t.c itemconf current -outline] 4]
    if {($prevFill != "") || ($prevOutline == "")} {
	.t.c itemconf current -fill $fill3
    }
    if {$prevOutline != ""} {
	.t.c itemconf current -outline $outline2
    }
}
.t.c bind arc <Leave> {.t.c itemconf current -fill $prevFill -outline $prevOutline}

bind .t.c <Button-1> {markarea %x %y}
bind .t.c <B1-Motion> {strokearea %x %y}

proc markarea {x y} {
    global areaX1 areaY1
    set areaX1 $x
    set areaY1 $y
}







|









|

|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
.t.c create arc 340 450 460 570 -start 320 -extent 270 -fill $fill1 -width 14 \
	-style chord -outline {}
.t.c create arc 500 450 620 570 -start 350 -extent -110 -fill $fill1 -width 14 \
	-style chord -outline {}
.t.c addtag arc withtag all
.t.c addtag circle withtag [.t.c create oval 320 200 340 220 -fill MistyRose3]

.t.c bind arc <Any-Enter> {
    set prevFill [lindex [.t.c itemconf current -fill] 4]
    set prevOutline [lindex [.t.c itemconf current -outline] 4]
    if {($prevFill != "") || ($prevOutline == "")} {
	.t.c itemconf current -fill $fill3
    }
    if {$prevOutline != ""} {
	.t.c itemconf current -outline $outline2
    }
}
.t.c bind arc <Any-Leave> {.t.c itemconf current -fill $prevFill -outline $prevOutline}

bind .t.c <1> {markarea %x %y}
bind .t.c <B1-Motion> {strokearea %x %y}

proc markarea {x y} {
    global areaX1 areaY1
    set areaX1 $x
    set areaY1 $y
}
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
}

bind .t.c <Control-f> {
    puts stdout "Enclosed: [.t.c find enclosed $areaX1 $areaY1 $areaX2 $areaY2]"
    puts stdout "Overlapping: [.t.c find overl $areaX1 $areaY1 $areaX2 $areaY2]"
}

bind .t.c <Button-3> {puts stdout "%x %y"}

# The code below allows the circle to be move by shift-dragging.

bind .t.c <Shift-Button-1> {
    set curx %x
    set cury %y
}

bind .t.c <Shift-B1-Motion> {
    .t.c move circle [expr {%x-$curx}] [expr {%y-$cury}]
    set curx %x
    set cury %y
}

# The binding below flashes the closest item to the mouse.

bind .t.c <Control-c> {







|



|





|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
}

bind .t.c <Control-f> {
    puts stdout "Enclosed: [.t.c find enclosed $areaX1 $areaY1 $areaX2 $areaY2]"
    puts stdout "Overlapping: [.t.c find overl $areaX1 $areaY1 $areaX2 $areaY2]"
}

bind .t.c <3> {puts stdout "%x %y"}

# The code below allows the circle to be move by shift-dragging.

bind .t.c <Shift-1> {
    set curx %x
    set cury %y
}

bind .t.c <Shift-B1-Motion> {
    .t.c move circle [expr %x-$curx] [expr %y-$cury]
    set curx %x
    set cury %y
}

# The binding below flashes the closest item to the mouse.

bind .t.c <Control-c> {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	    set delta -5
	}
	if {$i <= 5} {
	    set delta 5
	}
	incr i $delta
	c -start $i
	c -extent [expr {360-2*$i}]
	after 20
	update
    }
}

bind .t.c b {set go 0}








|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	    set delta -5
	}
	if {$i <= 5} {
	    set delta 5
	}
	incr i $delta
	c -start $i
	c -extent [expr 360-2*$i]
	after 20
	update
    }
}

bind .t.c b {set go 0}

Changes to tests/bell.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
# This file is a Tcl script to test out Tk's "bell" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test bell-1.1 {bell command} -body {
    bell a
} -returnCodes {error} -result {bad option "a": must be -displayof or -nice}

test bell-1.2 {bell command} -body {
    bell a b
} -returnCodes {error} -result {bad option "a": must be -displayof or -nice}

test bell-1.3 {bell command} -body {
    bell -displayof gorp
} -returnCodes {error} -result {bad window path name "gorp"}

test bell-1.4 {bell command} -body {
    bell -nice -displayof
} -returnCodes {error} -result {wrong # args: should be "bell ?-displayof window? ?-nice?"}

test bell-1.5 {bell command} -body {
    bell -nice -nice -nice
} -returnCodes {ok} -result {}  ;#keep -result {} and -retutnCodes {ok} for clarity?

test bell-1.6 {bell command} -body {
    bell -displayof . -nice
} -returnCodes {ok} -result {}

test bell-1.7 {bell command} -body {
    bell -nice -displayof . -nice
} -returnCodes {error} -result {wrong # args: should be "bell ?-displayof window? ?-nice?"}

test bell-1.8 {bell command} -body {
    puts "Bell should ring now ..."
    flush stdout
    after 200
    bell -displayof .
    after 200
    bell -nice
    after 200
    bell
} -result {}


cleanupTests
return



|
|



<



|
|
|
<
|
|
|
<
|
|
|
<
|
|
|
<
|
|
<
|
|
|
<
|
|
|
|
<
|








|

>


1
2
3
4
5
6
7
8

9
10
11
12
13
14

15
16
17

18
19
20

21
22
23

24
25

26
27
28

29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
# This file is a Tcl script to test out Tk's "bell" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test bell-1.1 {bell command} {
    list [catch {bell a} msg] $msg
} {1 {bad option "a": must be -displayof or -nice}}

test bell-1.2 {bell command} {
    list [catch {bell a b} msg] $msg
} {1 {bad option "a": must be -displayof or -nice}}

test bell-1.3 {bell command} {
    list [catch {bell -displayof gorp} msg] $msg
} {1 {bad window path name "gorp"}}

test bell-1.4 {bell command} {
    list [catch {bell -nice -displayof} msg] $msg
} {1 {wrong # args: should be "bell ?-displayof window? ?-nice?"}}

test bell-1.5 {bell command} {
    list [catch {bell -nice -nice -nice} msg] $msg

} {0 {}}
test bell-1.6 {bell command} {
    list [catch {bell -displayof . -nice} msg] $msg

} {0 {}}
test bell-1.7 {bell command} {
    list [catch {bell -nice -displayof . -nice} msg] $msg
} {1 {wrong # args: should be "bell ?-displayof window? ?-nice?"}}

test bell-1.8 {bell command} {
    puts "Bell should ring now ..."
    flush stdout
    after 200
    bell -displayof .
    after 200
    bell -nice
    after 200
    bell
} {}

# cleanup
cleanupTests
return

Changes to tests/bgerror.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
# This file is a Tcl script to test the bgerror command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test bgerror-1.1 {bgerror / tkerror compat} -setup {
    set errRes {}
    proc tkerror {err} {
        global errRes;
        set errRes $err;
    }
} -body {
    after 0 {error err1}
    vwait errRes;
    return $errRes;
} -cleanup {
    catch {rename tkerror {}}
} -result {err1}

test bgerror-1.2 {bgerror / tkerror compat / accumulation} -setup {
    set errRes {}
    proc tkerror {err} {
        global errRes;
        lappend errRes $err;
    }
} -body {
    after 0 {error err1}
    after 0 {error err2}
    after 0 {error err3}
    update
    return $errRes;
} -cleanup {
    catch {rename tkerror {}}
} -result {err1 err2 err3}

test bgerror-1.3 {bgerror / tkerror compat / accumulation / break} -setup {
    set errRes {}
    proc tkerror {err} {
        global errRes;
        lappend errRes $err;
        return -code break "skip!";
    }
} -body {
    after 0 {error err1}
    after 0 {error err2}
    after 0 {error err3}
    update
    return $errRes;
} -cleanup {
    catch {rename tkerror {}}
} -result {err1}



# some testing of the default error dialog
# would be needed too, but that's not easy at all
# to emulate.

# cleanup
cleanupTests



|
|



<



|


|
|

<


|
<
<
|

|


|
|

<




|
<
<
|

|


|
|
|

<




|
<
<
|

>







1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17

18
19
20


21
22
23
24
25
26
27
28

29
30
31
32
33


34
35
36
37
38
39
40
41
42

43
44
45
46
47


48
49
50
51
52
53
54
55
56
57
# This file is a Tcl script to test the bgerror command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test bgerror-1.1 {bgerror / tkerror compat} {
    set errRes {}
    proc tkerror {err} {
	global errRes;
	set errRes $err;
    }

    after 0 {error err1}
    vwait errRes;
    set errRes;


} err1

test bgerror-1.2 {bgerror / tkerror compat / accumulation} {
    set errRes {}
    proc tkerror {err} {
	global errRes;
	lappend errRes $err;
    }

    after 0 {error err1}
    after 0 {error err2}
    after 0 {error err3}
    update
    set errRes;


} {err1 err2 err3}

test bgerror-1.3 {bgerror / tkerror compat / accumulation / break} {
    set errRes {}
    proc tkerror {err} {
	global errRes;
	lappend errRes $err;
	return -code break "skip!";
    }

    after 0 {error err1}
    after 0 {error err2}
    after 0 {error err3}
    update
    set errRes;


} err1

catch {rename tkerror {}}

# some testing of the default error dialog
# would be needed too, but that's not easy at all
# to emulate.

# cleanup
cleanupTests

Changes to tests/bind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































23





















































































































































































































































































































































































































































































































































24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650


1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396

2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367

4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143

6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
# This file is a Tcl script to test out Tk's "bind" and "bindtags"
# commands plus the procedures in tkBind.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
tk useinputmethods 0

testConstraint nodeprecated [expr {"nodeprecated" ni [tk::pkgconfig list]}]


toplevel .t -width 100 -height 50
wm geom .t +0+0
update idletasks









































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































foreach p [event info] {event delete $p}





















































































































































































































































































































































































































































































































































foreach event [bind Test] {
    bind Test $event {}
}
foreach event [bind all] {
    bind all $event {}
}

proc unsetBindings {} {
    bind all <Enter> {}
    bind Test <Enter> {}
    bind Toplevel <Enter> {}
    bind xyz <Enter> {}
    bind {a b} <Enter> {}
    bind .t <Enter> {}
}

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top
wm geometry .top 50x50-50-50
update
event generate .top <Button-1> -warp 1
update
destroy .top

test bind-1.1 {bind command} -body {
    bind
} -returnCodes error -result {wrong # args: should be "bind window ?pattern? ?command?"}
test bind-1.2 {bind command} -body {
    bind a b c d
} -returnCodes error -result {wrong # args: should be "bind window ?pattern? ?command?"}
test bind-1.3 {bind command} -body {
    bind .gorp
} -returnCodes error -result {bad window path name ".gorp"}
test bind-1.4 {bind command} -body {
    bind foo
} -returnCodes ok -result {}
test bind-1.5 {bind command} -body {
    bind .t <gorp-> {}
} -returnCodes ok -result {}
test bind-1.6 {bind command} -body {
    frame .t.f
    bind .t.f <Enter> {test script}
    set result [bind .t.f <Enter>]
    bind .t.f <Enter> {}
    list $result [bind .t.f <Enter>]
} -cleanup {
    destroy .t.f
} -result {{test script} {}}
test bind-1.7 {bind command} -body {
    frame .t.f
    bind .t.f <Enter> {test script}
    bind .t.f <Enter> {+more text}
    bind .t.f <Enter>
} -cleanup {
    destroy .t.f
} -result {test script
more text}
test bind-1.8 {bind command} -body {
    bind .t <gorp-> {test script}
} -returnCodes error -result {bad event type or keysym "gorp"}
test bind-1.9 {bind command} -body {
    catch {bind .t <gorp-> {test script}}
    bind .t
} -result {}
test bind-1.10 {bind command} -body {
    bind .t <gorp->
} -returnCodes ok -result {}
test bind-1.11 {bind command} -body {
    frame .t.f
    bind .t.f <Enter> {script 1}
    bind .t.f <Leave> {script 2}
    bind .t.f a {script for a}
    bind .t.f b {script for b}
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {<Enter> <Leave> a b}

test bind-2.1 {bindtags command} -body {
    bindtags
} -returnCodes error -result {wrong # args: should be "bindtags window ?taglist?"}
test bind-2.2 {bindtags command} -body {
    bindtags a b c
} -returnCodes error -result {wrong # args: should be "bindtags window ?taglist?"}
test bind-2.3 {bindtags command} -body {
    bindtags .foo
} -returnCodes error -result {bad window path name ".foo"}
test bind-2.4 {bindtags command} -body {
    bindtags .t
} -result {.t Toplevel all}
test bind-2.5 {bindtags command} -body {
    frame .t.f
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {.t.f Frame .t all}
test bind-2.6 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {{x y z} b c d}
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {{x y z} b c d}
test bind-2.7 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {x y z}
    bindtags .t.f {}
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {.t.f Frame .t all}
test bind-2.8 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {x y z}
    bindtags .t.f {a b c d}
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {a b c d}
test bind-2.9 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {a b c}
    bindtags .t.f "\{"
} -cleanup {
    destroy .t.f
} -returnCodes error -result {unmatched open brace in list}
test bind-2.10 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {a b c}
    catch {bindtags .t.f "\{"}
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {.t.f Frame .t all}
test bind-2.11 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {a b c}
    bindtags .t.f "a .gorp b"
} -cleanup {
    destroy .t.f
} -returnCodes ok
test bind-2.12 {bindtags command} -body {
    frame .t.f
    bindtags .t.f {a b c}
    catch {bindtags .t.f "a .gorp b"}
    bindtags .t.f
} -cleanup {
    destroy .t.f
} -result {a .gorp b}


test bind-3.1 {TkFreeBindingTags procedure} -body {
    frame .t.f
    bindtags .t.f "a b c d"
    destroy .t.f
} -cleanup {
    destroy .t.f
} -result {}
test bind-3.2 {TkFreeBindingTags procedure} -body {
    frame .t.f
    catch {bindtags .t.f "a .gorp b .t.f"}
    destroy .t.f
} -cleanup {
    destroy .t.f
} -result {}


test bind-4.1 {TkBindEventProc procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update
    set x {}
} -body {
    bind all <Enter> {lappend x "%W enter all"}
    bind Test <Enter> {lappend x "%W enter frame"}
    bind Toplevel <Enter> {lappend x "%W enter toplevel"}
    bind xyz <Enter> {lappend x "%W enter xyz"}
    bind {a b} <Enter> {lappend x "%W enter {a b}"}
    bind .t <Enter>  {lappend x "%W enter .t"}
    bind .t.f <Enter> {lappend x "%W enter .t.f"}

    event generate .t.f <Enter>
    return $x
} -cleanup {
    destroy .t.f
    unsetBindings
} -result {{.t.f enter .t.f} {.t.f enter frame} {.t.f enter .t} {.t.f enter all}}
test bind-4.2 {TkBindEventProc procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update
    set x {}
} -body {
    bind all <Enter> {lappend x "%W enter all"}
    bind Test <Enter> {lappend x "%W enter frame"}
    bind Toplevel <Enter> {lappend x "%W enter toplevel"}
    bind xyz <Enter> {lappend x "%W enter xyz"}
    bind {a b} <Enter> {lappend x "%W enter {a b}"}
    bind .t <Enter>  {lappend x "%W enter .t"}
    bind .t.f <Enter> {lappend x "%W enter .t.f"}

    bindtags .t.f {.t.f {a b} xyz}
    event generate .t.f <Enter>
    return $x
} -cleanup {
    destroy .t.f
    unsetBindings
} -result {{.t.f enter .t.f} {.t.f enter {a b}} {.t.f enter xyz}}
test bind-4.3 {TkBindEventProc procedure} -body {
    set x {}
    bind all <Enter> {lappend x "%W enter all"}
    bind Test <Enter> {lappend x "%W enter frame"}
    bind Toplevel <Enter> {lappend x "%W enter toplevel"}
    bind xyz <Enter> {lappend x "%W enter xyz"}
    bind {a b} <Enter> {lappend x "%W enter {a b}"}
    bind .t <Enter>  {lappend x "%W enter .t"}

    event generate .t <Enter>
    return $x
} -cleanup {
    unsetBindings
}  -result {{.t enter .t} {.t enter toplevel} {.t enter all}}
test bind-4.4 {TkBindEventProc procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    frame .t.f3 -width 50 -height 50
    pack .t.f3
    update
    set x {}
} -body {
    bind all <Enter> {lappend x "%W enter all"}
    bind Test <Enter> {lappend x "%W enter frame"}
    bind Toplevel <Enter> {lappend x "%W enter toplevel"}
    bind xyz <Enter> {lappend x "%W enter xyz"}
    bind {a b} <Enter> {lappend x "%W enter {a b}"}
    bind .t <Enter>  {lappend x "%W enter .t"}

    bindtags .t.f {.t.f .t.f2 .t.f3}
    bind .t.f <Enter> {lappend x "%W enter .t.f"}
    bind .t.f3 <Enter> {lappend x "%W enter .t.f3"}
    event generate .t.f <Enter>
    return $x
} -cleanup {
    destroy .t.f .t.f3
    unsetBindings
} -result {{.t.f enter .t.f} {.t.f enter .t.f3}}
test bind-4.5 {TkBindEventProc procedure} -setup {
    # This tests memory allocation for objPtr;  it won't serve any useful
    # purpose unless run with some sort of allocation checker turned on.
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update
} -body {
    bind all <Enter> {lappend x "%W enter all"}
    bind Test <Enter> {lappend x "%W enter frame"}
    bind Toplevel <Enter> {lappend x "%W enter toplevel"}
    bind xyz <Enter> {lappend x "%W enter xyz"}
    bind {a b} <Enter> {lappend x "%W enter {a b}"}
    bind .t <Enter>  {lappend x "%W enter .t"}
    bindtags .t.f {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}

    event generate .t.f <Enter>
} -cleanup {
    destroy .t.f
    unsetBindings
} -result {}


test bind-5.1 {Tk_CreateBindingTable procedure} -body {
    canvas .t.c
    .t.c bind foo
} -cleanup {
    destroy .t.c
} -result {}


test bind-6.1 {Tk_DeleteBindTable procedure} -body {
    canvas .t.c
    .t.c bind foo <Button-1> {string 1}
    .t.c create rectangle 0 0 100 100
    .t.c bind 1 <Button-2> {string 2}
    destroy .t.c
} -cleanup {
    destroy .t.c
} -result {}
test bind-7.1 {Tk_CreateBinding procedure: bad binding} -body {
    canvas .t.c
    .t.c bind foo <
} -cleanup {
    destroy .t.c
} -returnCodes error -result {no event type or button # or keysym}
test bind-7.3 {Tk_CreateBinding procedure: append} -body {
    canvas .t.c
    .t.c bind foo <Button-1> "button 1"
    .t.c bind foo <Button-1> "+more button 1"
    .t.c bind foo <Button-1>
} -cleanup {
    destroy .t.c
} -result {button 1
more button 1}
test bind-7.4 {Tk_CreateBinding procedure: append to non-existing} -body {
    canvas .t.c
    .t.c bind foo <Button-1> "+button 1"
    .t.c bind foo <Button-1>
} -cleanup {
    destroy .t.c
} -result {button 1}

test bind-8.1 {Tk_CreateBinding: error} -body {
    bind . <xyz> "xyz"
} -returnCodes error -result {bad event type or keysym "xyz"}

test bind-9.1 {Tk_DeleteBinding procedure} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <
} -cleanup {
    destroy .t.f
} -returnCodes ok
test bind-9.2 {Tk_DeleteBinding procedure} -setup {
    set result {}
} -body {
    frame .t.f -class Test -width 150 -height 100
    foreach i {a b c d} {
        bind .t.f $i "binding for $i"
    }
    foreach i {b d a c} {
        bind .t.f $i {}
        lappend result [lsort [bind .t.f]]
    }
    return $result
} -cleanup {
    destroy .t.f
} -result {{a c d} {a c} c {}}
test bind-9.3 {Tk_DeleteBinding procedure} -setup {
    set result {}
} -body {
    frame .t.f -class Test -width 150 -height 100
    foreach i {<Button-1> <Meta-Button-1> <Control-Button-1> <Double-Alt-Button-1>} {
        bind .t.f $i "binding for $i"
    }
    foreach i {<Control-Button-1> <Double-Alt-Button-1> <Button-1> <Meta-Button-1>} {
        bind .t.f $i {}
        lappend result [lsort [bind .t.f]]
    }
    return $result
} -cleanup {
    destroy .t.f
} -result {{<Button-1> <Double-Alt-Button-1> <Meta-Button-1>} {<Button-1> <Meta-Button-1>} <Meta-Button-1> {}}

test bind-10.1 {Tk_GetBinding procedure} -body {
    canvas .t.c
    .t.c bind foo <
} -cleanup {
    destroy .t.c
} -returnCodes error -result {no event type or button # or keysym}
test bind-10.2 {Tk_GetBinding procedure} -body {
    canvas .t.c
    .t.c bind foo a Test
    .t.c bind foo a
} -cleanup {
    destroy .t.c
} -result {Test}

test bind-11.1 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "! a \\\{ ~ <Delete> <space> <<Paste>> <Tab> <Linefeed> <less> <Meta-a> <Acircumflex>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {! <<Paste>> <Key-Acircumflex> <Key-Delete> <Key-Linefeed> <Key-Tab> <Key-less> <Key-space> <Meta-Key-a> a \{ ~}
test bind-11.2 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "<Double-Button-1> <Triple-Button-1> <Meta-Control-a> <Double-Alt-Enter> <Button-1>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {<Button-1> <Control-Meta-Key-a> <Double-Alt-Enter> <Double-Button-1> <Triple-Button-1>}
test bind-11.3 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "<Double-Triple-Button-1> abcd a<Leave>b" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {<Triple-Button-1> a<Leave>b abcd}


test bind-12.1 {Tk_DeleteAllBindings procedure} -body {
    frame .t.f -class Test -width 150 -height 100
    destroy .t.f
} -result {}
test bind-12.2 {Tk_DeleteAllBindings procedure} -body {
    frame .t.f -class Test -width 150 -height 100
    foreach i "a b c <Meta-Button-1> <Alt-a> <Control-a>" {
        bind .t.f $i x
    }
    destroy .t.f
} -result {}

test bind-13.1 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Key> {lappend x "%W %K Test Key"}
    bind all <Key> {lappend x "%W %K all Key"}
    bind Test : {lappend x "%W %K Test :"}
    bind all  _ {lappend x "%W %K all _"}
    bind .t.f : {lappend x "%W %K .t.f :"}

    event generate .t.f <colon>
    event generate .t.f <plus>
    event generate .t.f <underscore>
    return $x
} -cleanup {
    destroy .t.f
    bind all <Key> {}
    bind Test <Key> {}
    bind all _ {}
    bind Test : {}
} -result {{.t.f colon .t.f :} {.t.f colon Test :} {.t.f colon all Key} {.t.f plus Test Key} {.t.f plus all Key} {.t.f underscore Test Key} {.t.f underscore all _}}

test bind-13.2 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Key> {lappend x "%W %K Test press any"; break}
    bind all <Key> {continue; lappend x "%W %K all press any"}
    bind .t.f : {lappend x "%W %K .t.f pressed colon"}

    event generate .t.f <colon>
    return $x
} -cleanup {
    destroy .t.f
    bind all <Key> {}
    bind Test <Key> {}
} -result {{.t.f colon .t.f pressed colon} {.t.f colon Test press any}}

test bind-13.3 {Tk_BindEvent procedure} -setup {
    proc bgerror args {}
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Key> {lappend x "%W %K Test press any"; error Test}
    bind .t.f : {lappend x "%W %K .t.f pressed colon"}
    event generate .t.f <colon>
    update
    list $x $errorInfo
} -cleanup {
    destroy .t.f
    bind Test <Key> {}
    rename bgerror {}
}  -result {{{.t.f colon .t.f pressed colon} {.t.f colon Test press any}} {Test
    while executing
"error Test"
    (command bound to event)}}
test bind-13.4 {Tk_BindEvent procedure} -setup {
    proc foo {} {
        set x 44
        event generate .t.f <colon>
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test : {lappend x "%W %K Test"}
    bind .t.f : {lappend x "%W %K .t.f"}
    foo
    return $x
} -cleanup {
    destroy .t.f
    bind Test : {}
} -result {{.t.f colon .t.f} {.t.f colon Test}}

test bind-13.5 {Tk_BindEvent procedure} -body {
    bind all <Destroy> {lappend x "%W destroyed"}
    set x {}
    frame .t.g -gorp foo
} -cleanup {
    bind all <Destroy> {}
} -returnCodes error -result {unknown option "-gorp"}
test bind-13.6 {Tk_BindEvent procedure} -body {
    bind all <Destroy> {lappend x "%W destroyed"}
    set x {}
    catch {frame .t.g -gorp foo}
    return $x
} -cleanup {
    bind all <Destroy> {}
} -result {{.t.g destroyed}}

test bind-13.7 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f : {lappend x "%W (.t.f binding)"}
    bind Test : {lappend x "%W (Test binding)"}
    bind all : {bind .t.f : {}; lappend x "%W (all binding)"}
    event generate .t.f <colon>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}
test bind-13.8 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f : {lappend x "%W (.t.f binding)"}
    bind Test : {lappend x "%W (Test binding)"}
    bind all : {destroy .t.f; lappend x "%W (all binding)"}
    event generate .t.f <colon>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}

test bind-13.9 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1> {lappend x "%W z (.t.f <Button-1> binding)"}
    bind .t.f <Button> {lappend x "%W z (.t.f <Button> binding)"}
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {{.t.f z (.t.f <Button-1> binding)} {.t.f z (.t.f <Button> binding)}}
test bind-13.10 {Tk_BindEvent procedure: ignore NotifyInferior} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x Enter%#"
    bind .t.f <Leave> "lappend x Leave%#"
    event generate .t.f <Enter> -serial 100 -detail NotifyAncestor
    event generate .t.f <Enter> -serial 101 -detail NotifyInferior
    event generate .t.f <Leave> -serial 102 -detail NotifyAncestor
    event generate .t.f <Leave> -serial 103 -detail NotifyInferior
    return $x
} -cleanup {
    destroy .t.f
} -result {Enter100 Leave102}
test bind-13.11 {Tk_BindEvent procedure: collapse Motions} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x Motion%#(%x,%y)"
    event generate .t.f <Motion> -serial 100 -x 100 -y 200 -when tail
    update
    event generate .t.f <Motion> -serial 101 -x 200 -y 300 -when tail
    event generate .t.f <Motion> -serial 102 -x 300 -y 400 -when tail
    update
    return $x
} -cleanup {
    destroy .t.f
} -result {Motion100(100,200) Motion102(300,400)}
test bind-13.12 {Tk_BindEvent procedure: collapse repeating modifiers} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> "lappend x %K%#"
    bind .t.f <KeyRelease> "lappend x %K%#"
    event generate .t.f <Shift_L> -serial 100 -when tail
    event generate .t.f <KeyRelease-Shift_L> -serial 101 -when tail
    event generate .t.f <Shift_L> -serial 102 -when tail
    event generate .t.f <KeyRelease-Shift_L> -serial 103 -when tail
    update
} -cleanup {
    destroy .t.f
} -result {}
test bind-13.13 {Tk_BindEvent procedure: valid key detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x Key%K"
    bind .t.f <KeyRelease> "lappend x Release%K"
    event generate .t.f <Key> -keysym colon
    event generate .t.f <KeyRelease> -keysym colon
    return $x
} -cleanup {
    destroy .t.f
} -result {Keycolon Releasecolon}
test bind-13.14 {Tk_BindEvent procedure: invalid key detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x Key%K"
    bind .t.f <KeyRelease> "lappend x Release%K"
    event generate .t.f <Key> -keycode -1
    event generate .t.f <KeyRelease> -keycode -1
    return $x
} -cleanup {
    destroy .t.f
} -result {Key?? Release??}
test bind-13.15 {Tk_BindEvent procedure: button detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x Button%b"
    bind .t.f <ButtonRelease> "lappend x Release%b"
    event generate .t.f <Button> -button 1
    event generate .t.f <ButtonRelease> -button 3
    set x
} -cleanup {
    destroy .t.f
} -result {Button1 Release3}
test bind-13.16 {Tk_BindEvent procedure: virtual detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <<Paste>>
    return $x
} -cleanup {
    destroy .t.f
} -result {Paste}
test bind-13.17 {Tk_BindEvent procedure: virtual event in event stream} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <<Paste>>
    return $x
} -cleanup {
    destroy .t.f
} -result {Paste}
test bind-13.18 {Tk_BindEvent procedure: match detail physical} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {set x Button-2}
    event add <<Paste>> <Button-2>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
} -result {Button-2}

test bind-13.19 {Tk_BindEvent procedure: no match detail physical} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-2>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
} -result {Paste}
test bind-13.20 {Tk_BindEvent procedure: match detail virtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-2>
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
} -result {Paste}
test bind-13.21 {Tk_BindEvent procedure: no match detail virtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-2>
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <Button>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
} -result {}
test bind-13.22 {Tk_BindEvent procedure: match no-detail physical} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {set x Button}
    event add <<Paste>> <Button>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button>
} -result {Button}
test bind-13.23 {Tk_BindEvent procedure: no match no-detail physical} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button>
} -result {Paste}
test bind-13.24 {Tk_BindEvent procedure: match no-detail virtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button>
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button>
} -result {Paste}
test bind-13.25 {Tk_BindEvent procedure: no match no-detail virtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Key>
    bind .t.f <<Paste>> "lappend x Paste"
    event generate .t.f <Button>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Key>
} -result {}
test bind-13.26 {Tk_BindEvent procedure: precedence} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-2>
    event add <<Copy>> <Button>
    bind .t.f <Button-2> "lappend x Button-2"
    bind .t.f <<Paste>> "lappend x Paste"
    bind .t.f <Button> "lappend x Button"
    bind .t.f <<Copy>> "lappend x Copy"

    event generate .t.f <Button-2>
    bind .t.f <Button-2> {}
    event generate .t.f <Button-2>
    bind .t.f <<Paste>> {}
    event generate .t.f <Button-2>
    bind .t.f <Button> {}
    event generate .t.f <Button-2>
    bind .t.f <<Copy>> {}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
    event delete <<Copy>> <Button>
} -result {Button-2 Paste Button Copy}
test bind-13.27 {Tk_BindEvent procedure: no detail virtual pattern list} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {set x Button-2}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {Button-2}
test bind-13.28 {Tk_BindEvent procedure: detail virtual pattern list} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-2>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-2>
} -result {Paste}
test bind-13.29 {Tk_BindEvent procedure: no no-detail virtual pattern list} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {set x Button}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {Button}
test bind-13.30 {Tk_BindEvent procedure: no-detail virtual pattern list} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button>
    bind .t.f <<Paste>> {set x Paste}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button>
} -result {Paste}
test bind-13.31 {Tk_BindEvent procedure: no match} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    event generate .t.f <Button-2>
} -cleanup {
    destroy .t.f
} -result {}
test bind-13.32 {Tk_BindEvent procedure: match} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {set x Button-2}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {Button-2}
test bind-13.33 {Tk_BindEvent procedure: many C bindings cause realloc} -setup {
    # this test might not be useful anymore [#3009998]
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bindtags .t.f {a b c d e f g h i j k l m n o p}
    foreach p [bindtags .t.f] {
        bind $p <Button-1> "lappend x $p"
    }
    event generate .t.f <Button-1>
    return $x
} -cleanup {
    foreach p [bindtags .t.f] {bind $p <Button-1> {}}
    destroy .t.f
} -result {a b c d e f g h i j k l m n o p}
test bind-13.34 {Tk_BindEvent procedure: multiple tags} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {lappend x .t.f}
    bind Test <Button-2> {lappend x Button}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    bind Test <Button-2> {}
} -result {.t.f Button}
test bind-13.35 {Tk_BindEvent procedure: execute binding} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1> {lappend x 1}
    event generate .t.f <Button-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-13.38 {Tk_BindEvent procedure: binding gets to run} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Button-1> {lappend x Test}
    bind .t.f <Button-1> {lappend x .t.f}
    event generate .t.f <Button-1>
    return $x
} -cleanup {
    destroy .t.f
    bind Test <Button-1> {}
} -result {.t.f Test}
test bind-13.41 {Tk_BindEvent procedure: continue in script} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {lappend x b1; continue; lappend x b2}
    bind Test <Button-2> {lappend x B1; continue; lappend x B2}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    bind Test <Button-2> {}
} -result {b1 B1}
test bind-13.43 {Tk_BindEvent procedure: break in script} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {lappend x b1; break; lappend x b2}
    bind Test <Button-2> {lappend x B1; break; lappend x B2}
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
    bind Test <Button-2> {}
} -result  {b1}
test bind-13.45 {Tk_BindEvent procedure: error in script} -setup {
    proc bgerror msg {
        global x
        lappend x $msg
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2> {lappend x b1; blap}
    bind Test <Button-2> {lappend x B1}
    event generate .t.f <Button-2>
    update
    return $x
} -cleanup {
    destroy .t.f
    bind Test <Button-2> {}
    proc bgerror args {}
} -result {b1 {invalid command name "blap"}}

test bind-15.1 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.2 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <Enter>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Leave>
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.3 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <Button-1>
    event generate .t.f <Key-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.4 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.5 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-ButtonRelease> {set x 1}
    set x 0
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.6 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-1>
    event generate .t.f <a>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.7 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-1>
    event generate .t.f <Shift_L>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.8 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f ab {set x 1}
    set x 0
    event generate .t.f <a>
    event generate .t.f <c>
    event generate .t.f <b>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.9 {MatchPatterns procedure, modifier checks} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <M1-M2-Key> {set x 1}
    set x 0
    event generate .t.f <a> -state 0x18
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.10 {MatchPatterns procedure, modifier checks} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <M1-M2-Key> {set x 1}
    set x 0
    event generate .t.f <a> -state 0xfc
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.11 {MatchPatterns procedure, modifier checks} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <M1-M2-Key> {set x 1}
    set x 0
    event generate .t.f <a> -state 0x8
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.12 {MatchPatterns procedure, ignore modifier presses and releases} -constraints {
    nonPortable
} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    # This test is non-portable because the Shift_L keysym may behave
    # differently on some platforms.
    bind .t.f aB {set x 1}
    set x 0
    event generate .t.f <a>
    event generate .t.f <Shift_L>
    event generate .t.f <b> -state 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.13 {MatchPatterns procedure, checking detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f ab {set x 1}
    set x 0
    event generate .t.f <a>
    event generate .t.f <c>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.14 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 31 -y 39
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.15 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 29 -y 41
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.16 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 40 -y 40
    event generate .t.f <ButtonRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.17 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 20 -y 40
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.18 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 30 -y 30
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.19 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -x 30 -y 40
    event generate .t.f <Button-1> -x 30 -y 50
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.20 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -time 300
    event generate .t.f <Button-1> -time 700
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.21 {MatchPatterns procedure, checking "nearby"} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1> -time 300
    event generate .t.f <Button-1> -time 900
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.22 {MatchPatterns procedure, time wrap-around} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-1> -time -100
    event generate .t.f <Button-1> -time 200
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.23 {MatchPatterns procedure, time wrap-around} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Double-Button-1> {set x 1}
    set x 0
    event generate .t.f <Button-1> -time -100
    event generate .t.f <Button-1> -time 500
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.24 {MatchPatterns procedure, virtual event} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Button-1>
    bind .t.f <<Paste>> {lappend x paste}
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Button-1>
} -result {paste}
test bind-15.25 {MatchPatterns procedure, reject a  virtual event} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<Paste>> <Shift-Button-1>
    bind .t.f <<Paste>> {lappend x paste}
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
    event delete <<Paste>> <Shift-Button-1>
} -result {}
test bind-15.26 {MatchPatterns procedure, reject a virtual event} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<V1>> <Button>
    event add <<V2>> <Button-1>
    event add <<V3>> <Shift-Button-1>
    bind .t.f <<V2>> "lappend x V2%#"
    event generate .t.f <Button> -serial 101
    event generate .t.f <Button-1> -serial 102
    event generate .t.f <Shift-Button-1> -serial 103
    event generate .t.f <ButtonRelease-1>
    bind .t.f <Shift-Button-1> "lappend x Shift-Button-1"
    event generate .t.f <Button> -serial 104
    event generate .t.f <Button-1> -serial 105
    event generate .t.f <Shift-Button-1> -serial 106
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
    event delete <<V1>> <Button>
    event delete <<V2>> <Button-1>
    event delete <<V3>> <Shift-Button-1>
} -result {V2102 V2103 V2105 Shift-Button-1}
test bind-15.27 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.28 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.29 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {lappend x 0}
    bind .t.f 1 {lappend x 1}
    bind .t.f 21 {lappend x 2}
    set x none
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    event generate .t.f <Key-1>
    set x
} -cleanup {
    destroy .t.f
} -result {none 0 2}
test bind-15.30 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {set x 0}
    bind .t.f <Button-1> {set x 1}
    set x none
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.31 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <M1-Key> {set x 0}
    bind .t.f <M2-Key> {set x 1}
    event generate .t.f <a> -state 0x18
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.32 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <M2-Key> {set x 0}
    bind .t.f <M1-Key> {set x 1}
    set x none
    event generate .t.f <a> -state 0x18
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.33 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1> {lappend x single}
    bind Test <Button-1> {lappend x single(Test)}
    bind Test <Double-Button-1> {lappend x double(Test)}
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
    bind Test <Button-1> {}
    bind Test <Double-Button-1> {}
} -result {single single(Test) single double(Test) single double(Test)}


test bind-16.1 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x abcd}
    set x none
    event generate .t.f <Enter>
    set x
} -cleanup {
    destroy .t.f
} -result {abcd}
test bind-16.2 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %#}
    set x none
    event generate .t.f <Enter> -serial 1234
    set x
} -cleanup {
    destroy .t.f
} -result 1234
test bind-16.3 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> {set x %a}
    set x none
    event generate .t.f <Configure> -above .t -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result [winfo id .t]
test bind-16.4 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {set x %b}
    set x none
    event generate .t.f <Button-3>
    event generate .t.f <ButtonRelease-3>
    set x
} -cleanup {
    destroy .t.f
} -result 3
test bind-16.5 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Expose> {set x %c}
    set x none
    event generate .t.f <Expose> -count 47
    set x
} -cleanup {
    destroy .t.f
} -result 47
test bind-16.6 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f


    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyAncestor
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyAncestor}
test bind-16.7 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyVirtual
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyVirtual}
test bind-16.8 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyNonlinear
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyNonlinear}
test bind-16.9 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyNonlinearVirtual
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyNonlinearVirtual}
test bind-16.10 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyPointer
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyPointer}
test bind-16.11 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyPointerRoot
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyPointerRoot}
test bind-16.12 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %d}
    set x none
    event generate .t.f <Enter> -detail NotifyDetailNone
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyDetailNone}
test bind-16.13 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x %f}
    set x none
    event generate .t.f <Enter> -focus 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-16.14 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Expose> {set x "%x %y %w %h"}
    set x none
    event generate .t.f <Expose> -x 24 -y 18 -width 147 -height 61
    set x
} -cleanup {
    destroy .t.f
} -result {24 18 147 61}
test bind-16.15 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> {set x "%x %y %w %h"}
    set x none
    event generate .t.f <Configure> -x 24 -y 18 -width 147 -height 61 -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result {24 18 147 61}
test bind-16.16 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x "%k"}
    set x none
    event generate .t.f <Key> -keycode 146
    set x
} -cleanup {
    destroy .t.f
} -result 146
test bind-16.17 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%m"}
    set x none
    event generate .t.f <Enter> -mode NotifyNormal
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyNormal}
test bind-16.18 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%m"}
    set x none
    event generate .t.f <Enter> -mode NotifyGrab
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyGrab}
test bind-16.19 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%m"}
    set x none
    event generate .t.f <Enter> -mode NotifyUngrab
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyUngrab}
test bind-16.20 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> {set x "%m"}
    set x none
    event generate .t.f <Enter> -mode NotifyWhileGrabbed
    set x
} -cleanup {
    destroy .t.f
} -result {NotifyWhileGrabbed}
test bind-16.21 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Map> {set x "%o"}
    set x none
    event generate .t.f <Map> -override 1 -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-16.22 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Reparent> {set x "%o"}
    set x none
    event generate .t.f <Reparent> -override true -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-16.23 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> {set x "%o"}
    set x none
    event generate .t.f <Configure> -override 1 -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-16.24 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Circulate> {set x "%p"}
    set x none
    event generate .t.f <Circulate> -place PlaceOnTop -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result {PlaceOnTop}
test bind-16.25 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Circulate> {set x "%p"}
    set x none
    event generate .t.f <Circulate> -place PlaceOnBottom -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result {PlaceOnBottom}
test bind-16.26 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-1> {set x "%s"}
    set x none
    event generate .t.f <Button-1> -state 1402
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
} -result 1402
test bind-16.27 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%s"}
    set x none
    event generate .t.f <Enter> -state 0x3ff
    set x
} -cleanup {
    destroy .t.f
} -result 1023
test bind-16.28 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Visibility> {set x "%s"}
    set x none
    event generate .t.f <Visibility> -state VisibilityPartiallyObscured
    set x
} -cleanup {
    destroy .t.f
} -result {VisibilityPartiallyObscured}
test bind-16.29 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Visibility> {set x "%s"}
    set x none
    event generate .t.f <Visibility> -state VisibilityUnobscured
    set x
} -cleanup {
    destroy .t.f
} -result {VisibilityUnobscured}
test bind-16.30 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Visibility> {set x "%s"}
    set x none
    event generate .t.f <Visibility> -state VisibilityFullyObscured
    set x
} -cleanup {
    destroy .t.f
} -result {VisibilityFullyObscured}
test bind-16.31 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {set x "%t"}
    set x none
    event generate .t.f <Button> -time 4294
    event generate .t.f <ButtonRelease>
    set x
} -cleanup {
    destroy .t.f
} -result 4294
test bind-16.32 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {set x "%x %y"}
    set x none
    event generate .t.f <Button> -x 881 -y 432
    event generate .t.f <ButtonRelease>
    set x
} -cleanup {
    destroy .t.f
} -result {881 432}
test bind-16.33 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Reparent> {set x "%x %y"}
    set x none
    event generate .t.f <Reparent> -x 882 -y 431 -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result {882 431}
test bind-16.34 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%x %y"}
    set x none
    event generate .t.f <Enter> -x 781 -y 632
    set x
} -cleanup {
    destroy .t.f
} -result {781 632}
test bind-16.35 {ExpandPercents procedure} -constraints {
    nonPortable
} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> {lappend x "%A"}
    event generate .t.f <a>
    event generate .t.f <A> -state 1
    event generate .t.f <Tab>
    event generate .t.f <Return>
    event generate .t.f <F1>
    event generate .t.f <Shift_L>
    event generate .t.f <space>
    event generate .t.f <dollar> -state 1
    event generate .t.f <braceleft> -state 1
    event generate .t.f <Multi_key>
    event generate .t.f <e>
    event generate .t.f <apostrophe>
    set x
} -cleanup {
    destroy .t.f
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \xE9}
test bind-16.36 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> {set x "%B"}
    set x none
    event generate .t.f <Configure> -borderwidth 24 -window .t.f
    set x
} -cleanup {
    destroy .t.f
} -result 24
test bind-16.37 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> {set x "%E"}
    set x none
    event generate .t.f <Enter> -sendevent 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-16.38 {ExpandPercents procedure} -constraints {
    nonPortable
} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> {lappend x %K}
    event generate .t.f <a>
    event generate .t.f <A> -state 1
    event generate .t.f <Tab>
    event generate .t.f <F1>
    event generate .t.f <Shift_L>
    event generate .t.f <space>
    event generate .t.f <dollar> -state 1
    event generate .t.f <braceleft> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result {a A Tab F1 Shift_L space dollar braceleft}
test bind-16.39 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x "%N"}
    set x none
    event generate .t.f <space>
    set x
} -cleanup {
    destroy .t.f
} -result 32
test bind-16.40 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x "%S"}
    set x none
    event generate .t.f <space> -subwindow .t
    set x
} -cleanup {
    destroy .t.f
} -result [winfo id .t]
test bind-16.41 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x "%T"}
    set x none
    event generate .t.f <Key>
    set x
} -cleanup {
    destroy .t.f
} -result 2
test bind-16.42 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> {set x "%W"}
    set x none
    event generate .t.f <Key>
    set x
} -cleanup {
    destroy .t.f
} -result {.t.f}
test bind-16.43 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {set x "%X %Y"}
    set x none
    event generate .t.f <Button> -rootx 422 -rooty 13
    event generate .t.f <ButtonRelease>
    set x
} -cleanup {
    destroy .t.f
} -result {422 13}
test bind-16.44 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Gravity> {set x "%R %S"}
    set x none
    event generate .t.f <Gravity>
    set x
} -cleanup {
    destroy .t.f
} -result {?? ??}

test bind-16.45 {ExpandPercents procedure} -setup {
    set savedBind(Entry) [bind Entry <Key>]
    set savedBind(All) [bind all <Key>]
    entry .t.e
    pack .t.e
    focus -force .t.e
    foreach p [event info] {event delete $p}
    update
} -body {
    bind .t.e <Key> {set x "%M"}
    bind Entry <Key> {set y "%M"}
    bind all <Key> {set z "%M"}
    set x none; set y none; set z none
    event gen .t.e <a>
    list $x $y $z
} -cleanup {
    destroy .t.e
    bind all <Key> $savedBind(All)
    bind Entry <Key> $savedBind(Entry)
    unset savedBind
} -result {0 1 2}
test bind-16.46 {ExpandPercents procedure} -setup {
    set savedBind(All) [bind all <Key>]
    set savedBind(Entry) [bind Entry <Key>]
    entry .t.e
    pack .t.e
    focus -force .t.e
    foreach p [event info] {event delete $p}
    update
} -body {
    bind all <Key> {set z "%M"}
    bind Entry <Key> {set y "%M"}
    bind .t.e <Key> {set x "%M"}
    set x none; set y none; set z none
    event gen .t.e <a>
    list $x $y $z
} -cleanup {
    destroy .t.e
    bind Entry <Key> $savedBind(Entry)
    bind all <Key> $savedBind(All)
    unset savedBind
} -result {0 1 2}

test bind-17.1 {event command} -body {
    event
} -returnCodes error -result {wrong # args: should be "event option ?arg?"}
test bind-17.2 {event command} -body {
    event xyz
} -returnCodes error -result {bad option "xyz": must be add, delete, generate, or info}
test bind-17.3 {event command: add} -body {
    event add
} -returnCodes error -result {wrong # args: should be "event add virtual sequence ?sequence ...?"}
test bind-17.4 {event command: add 1} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v>
    event info <<Paste>>
} -cleanup {
    event delete <<Paste>> <Control-v>
} -result {<Control-Key-v>}
test bind-17.5 {event command: add 2} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v> <Button-2>
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>> <Control-v> <Button-2>
} -result {<Button-2> <Control-Key-v>}

test bind-17.6 {event command: add with error} -body {
    event add <<Paste>> <Control-v> <Button-2> abc <xyz> <Button-1>
} -cleanup {
    event delete <<Paste>>
} -returnCodes error -result {bad event type or keysym "xyz"}
test bind-17.7 {event command: add with error} -body {
    event delete <<Paste>>
    catch {event add <<Paste>> <Control-v> <Button-2> abc <xyz> <Button-1>}
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>>
} -result {<Button-2> <Control-Key-v> abc}

test bind-17.8 {event command: delete} -body {
    event delete
} -returnCodes error -result {wrong # args: should be "event delete virtual ?sequence ...?"}
test bind-17.9 {event command: delete many} -body {
    event delete <<Paste>>
    event add <<Paste>> <Button-3> <Button-1> <Button-2> t
    event delete <<Paste>> <Button-1> <Button-2>
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>>
    event delete <<Paste>> <Button-3> t
} -result {<Button-3> t}
test bind-17.10 {event command: delete all} -body {
    event add <<Paste>> a b
    event delete <<Paste>>
    event info <<Paste>>
} -cleanup {
    event delete <<Paste>> a b
} -result {}
test bind-17.11 {event command: delete 1} -body {
    event delete <<Paste>>
    event add <<Paste>> a b c
    event delete <<Paste>> b
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>>
} -result {a c}
test bind-17.12 {event command: info name} -body {
    event delete <<Paste>>
    event add <<Paste>> a b c
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>>
} -result {a b c}
test bind-17.13 {event command: info all} -body {
    foreach p [event info] {event delete $p}
    event add <<Paste>> a
    event add <<Alive>> b
    lsort [event info]
} -cleanup {
    event delete <<Paste>>
    event delete <<Alive>>
} -result {<<Alive>> <<Paste>>}

test bind-17.14 {event command: info error} -body {
    event info <<Paste>> <Control-v>
} -returnCodes error -result {wrong # args: should be "event info ?virtual?"}
test bind-17.15 {event command: generate} -body {
    event generate
} -returnCodes error -result {wrong # args: should be "event generate window event ?-option value ...?"}

test bind-17.16 {event command: generate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1> "lappend x 1"
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result 1
test bind-17.17 {event command: generate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    event generate .t.f <xyz>
} -cleanup {
    destroy .t.f
}  -returnCodes error -result {bad event type or keysym "xyz"}
test bind-17.18 {event command} -body {
    event foo
} -returnCodes error -result {bad option "foo": must be add, delete, generate, or info}


test bind-18.1 {CreateVirtualEvent procedure: GetVirtualEventUid} -body {
    event add asd <Ctrl-v>
} -returnCodes error -result {virtual event "asd" is badly formed}
test bind-18.2 {CreateVirtualEvent procedure: FindSequence} -body {
    event add <<asd>> <Ctrl-v>
} -returnCodes error -result {bad event type or keysym "Ctrl"}
test bind-18.3 {CreateVirtualEvent procedure: new physical} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-18.4 {CreateVirtualEvent procedure: duplicate physical} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-18.5 {CreateVirtualEvent procedure: existing physical} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<abc>> <Control-v>
    list [lsort [event info]] [event info <<xyz>>] [event info <<abc>>]
} -cleanup {
    event delete <<xyz>>
    event delete <<abc>>
} -result {{<<abc>> <<xyz>>} <Control-Key-v> <Control-Key-v>}
test bind-18.6 {CreateVirtualEvent procedure: new virtual} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    list [event info] [event info <<xyz>>]
} -cleanup {
    event delete <<abc>>
} -result {<<xyz>> <Control-Key-v>}
test bind-18.7 {CreateVirtualEvent procedure: existing virtual} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    list [event info] [lsort [event info <<xyz>>]]
} -cleanup {
    event delete <<xyz>>
} -result {<<xyz>> {<Button-2> <Control-Key-v>}}


test bind-19.1 {DeleteVirtualEvent procedure: GetVirtualEventUid} -body {
    event add xyz {}
} -returnCodes error -result {virtual event "xyz" is badly formed}
test bind-19.2 {DeleteVirtualEvent procedure: non-existent virtual} -setup {
    foreach p [event info] {event delete $p}
} -body {
    event delete <<xyz>>

    event info
} -result {}
test bind-19.3 {DeleteVirtualEvent procedure: delete 1} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Control-v>
    event info <<xyz>>
} -result {}
test bind-19.4 {DeleteVirtualEvent procedure: delete 1, not owned} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Button-1>
    event info <<xyz>>
} -result {<Control-Key-v>}
test bind-19.5 {DeleteVirtualEvent procedure: delete 1, badly formed} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <xyz>
} -cleanup {
    event delete <<xyz>>
} -returnCodes error -result {bad event type or keysym "xyz"}
test bind-19.6 {DeleteVirtualEvent procedure: delete 1, badly formed} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <<Paste>>
} -cleanup {
    event delete <<xyz>>
} -returnCodes error -result {virtual event not allowed in definition of another virtual event}
test bind-19.7 {DeleteVirtualEvent procedure: owns 1, delete all} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event delete <<xyz>>
    event info
} -result {}
test bind-19.8 {DeleteVirtualEvent procedure: owns 1, delete 1} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Control-v>
    event info
} -result {}
test bind-19.9 {DeleteVirtualEvent procedure: owns many, delete all} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v> <Control-w> <Control-x>
    event delete <<xyz>>
    event info
} -result {}
test bind-19.10 {DeleteVirtualEvent procedure: owns many, delete 1} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v> <Control-w> <Control-x>
    event delete <<xyz>> <Control-w>
    lsort [event info <<xyz>>]
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v> <Control-Key-x>}
test bind-19.11 {DeleteVirtualEvent procedure: owned by 1, only} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Button-2>
    bind .t.f <<xyz>> {lappend x %#}
    event generate .t.f <Button-2> -serial 101
    event generate .t.f <ButtonRelease-2>
    event delete <<xyz>>
    event generate .t.f <Button-2> -serial 102
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result 101
test bind-19.12 {DeleteVirtualEvent procedure: owned by 1, first in chain} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<abc>> <Control-Button-2>
    event add <<xyz>> <Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.f <<abc>> {lappend x abc}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Control-ButtonRelease-2>
    event delete <<xyz>>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Control-ButtonRelease-2>
    list $x [event info <<abc>>]
} -cleanup {
    destroy .t.f
    event delete <<abc>>
} -result {{xyz abc abc} <Control-Button-2>}
test bind-19.13 {DeleteVirtualEvent procedure: owned by 1, second in chain} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
    event delete <<def>>
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<def>> <Shift-Button-2>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.f <<abc>> {lappend x abc}
    bind .t.f <<def>> {lappend x def}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Control-ButtonRelease-2>
    event generate .t.f <Shift-Button-2>
    event generate .t.f <Shift-ButtonRelease-2>
    event delete <<xyz>>
    event generate .t.f <Button-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Shift-Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-ButtonRelease-2>
    event generate .t.f <Shift-ButtonRelease-2>
    list $x [event info <<def>>] [event info <<xyz>>] [event info <<abc>>]
} -cleanup {
    destroy .t.f
    event delete <<abc>>
    event delete <<def>>
} -result {{xyz abc def abc def} <Shift-Button-2> {} <Control-Button-2>}
test bind-19.14 {DeleteVirtualEvent procedure: owned by 1, last in chain} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
    event delete <<def>>
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-Button-2>
    event add <<def>> <Shift-Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.f <<abc>> {lappend x abc}
    bind .t.f <<def>> {lappend x def}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Control-ButtonRelease-2>
    event generate .t.f <Shift-Button-2>
    event generate .t.f <Shift-ButtonRelease-2>
    event delete <<xyz>>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Control-Button-2>
    event generate .t.f <Control-ButtonRelease-2>
    event generate .t.f <Shift-Button-2>
    event generate .t.f <Shift-ButtonRelease-2>
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} -cleanup {
    destroy .t.f
    event delete <<def>>
    event delete <<abc>>
} -result {{xyz abc def abc def} {} <Control-Button-2> <Shift-Button-2>}
test bind-19.15 {DeleteVirtualEvent procedure: owned by many, first} -setup {
    pack [frame .t.f -class Test -width 150 -height 100]
    pack [frame .t.g -class Test -width 150 -height 100]
    pack [frame .t.h -class Test -width 150 -height 100]
    after 250 ;# we need a bit time to ensure that .t.h is mapped (<TODO>: fix this race condition)
    focus -force .t.f
    update
    set x {}
    event delete <<def>>
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.g <<abc>> {lappend x abc}
    bind .t.h <<def>> {lappend x def}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    event delete <<xyz>>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} -cleanup {
    destroy .t.f .t.g .t.h
    event delete <<def>>
    event delete <<abc>>
} -result {{xyz abc def abc def} {} <Button-2> <Button-2>}
test bind-19.16 {DeleteVirtualEvent procedure: owned by many, middle} -setup {
    pack [frame .t.f -class Test -width 150 -height 100]
    pack [frame .t.g -class Test -width 150 -height 100]
    pack [frame .t.h -class Test -width 150 -height 100]
    after 250 ;# we need a bit time to ensure that .t.h is mapped (<TODO>: fix this race condition)
    focus -force .t.f
    update
    set x {}
    event delete <<def>>
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.g <<abc>> {lappend x abc}
    bind .t.h <<def>> {lappend x def}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    event delete <<abc>>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} -cleanup {
    destroy .t.f .t.g .t.h
    event delete <<def>>
    event delete <<xyz>>
} -result {{xyz abc def xyz def} <Button-2> {} <Button-2>}
test bind-19.17 {DeleteVirtualEvent procedure: owned by many, last} -setup {
    pack [frame .t.f -class Test -width 150 -height 100]
    pack [frame .t.g -class Test -width 150 -height 100]
    pack [frame .t.h -class Test -width 150 -height 100]
    after 250 ;# we need a bit time to ensure that .t.h is mapped (<TODO>: fix this race condition)
    focus -force .t.f
    update
    set x {}
    event delete <<def>>
    event delete <<xyz>>
    event delete <<abc>>
} -body {
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .t.f <<xyz>> {lappend x xyz}
    bind .t.g <<abc>> {lappend x abc}
    bind .t.h <<def>> {lappend x def}
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    event delete <<def>>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.g <Button-2>
    event generate .t.g <ButtonRelease-2>
    event generate .t.h <Button-2>
    event generate .t.h <ButtonRelease-2>
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} -cleanup {
    destroy .t.f .t.g .t.h
    event delete <<xyz>>
    event delete <<abc>>
} -result {{xyz abc def xyz abc} <Button-2> <Button-2> {}}


test bind-20.1 {GetVirtualEvent procedure: GetVirtualEventUid} -body {
    event info asd
} -returnCodes error -result {virtual event "asd" is badly formed}
test bind-20.2 {GetVirtualEvent procedure: non-existent event} -body {
    event delete <<asd>>
    event info <<asd>>
} -result {}
test bind-20.3 {GetVirtualEvent procedure: owns 1} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-20.4 {GetVirtualEvent procedure: owns many} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v> <Button-2> spack
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v> <Button-2> spack}


test bind-21.1 {GetAllVirtualEvents procedure: no events} -body {
    foreach p [event info] {event delete $p}
    event info
} -result {}
test bind-21.2 {GetAllVirtualEvents procedure: 1 event} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event info
} -cleanup {
    event delete <<xyz>>
} -result {<<xyz>>}
test bind-21.3 {GetAllVirtualEvents procedure: many events} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-v>
    event add <<def>> <F6>
    lsort [event info]
} -cleanup {
    event delete <<xyz>>
    event delete <<abc>>
    event delete <<def>>
} -result {<<abc>> <<def>> <<xyz>>}

test bind-22.1 {HandleEventGenerate} -setup {
    destroy .xyz
} -body {
    event generate .xyz <Control-v>
} -returnCodes error -result {bad window path name ".xyz"}
test bind-22.2 {HandleEventGenerate} -body {
    event generate zzz <Control-v>
} -returnCodes error -result {bad window name/identifier "zzz"}
test bind-22.3 {HandleEventGenerate} -body {
    event generate 47 <Control-v>
} -returnCodes error -result {bad window name/identifier "47"}
test bind-22.4 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {set x "%s %b"}
    event generate [winfo id .t.f] <Control-Button-1> -state 260
    set x
} -cleanup {
    destroy .t.f
} -result {260 1}
test bind-22.5 {HandleEventGenerate} -body {
    event generate . <xyz>
} -returnCodes error -result {bad event type or keysym "xyz"}
test bind-22.6 {HandleEventGenerate} -body {
    event generate . <Double-Button-1>
} -returnCodes error -result {Double, Triple, or Quadruple modifier not allowed}
test bind-22.7 {HandleEventGenerate} -body {
    event generate . xyz
} -returnCodes error -result {only one event specification allowed}
test bind-22.8 {HandleEventGenerate} -body {
    event generate . <Button> -button
} -returnCodes error -result {value for "-button" missing}
test bind-22.9 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {set x "%s %b"}
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <ButtonRelease-3>
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
} -result {4 1}
test bind-22.10 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> {set x "%s %K"}
    event generate .t.f <Control-space>
    set x
} -cleanup {
    destroy .t.f
} -result {4 space}
test bind-22.11 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> {set x "%s"}
    event generate .t.f <<Paste>> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result 1
test bind-22.12 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> {set x "%s"}
    event generate .t.f <Control-Motion>
    set x
} -cleanup {
    destroy .t.f
} -result 4
test bind-22.13 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {lappend x %#}
    event generate .t.f <Button> -when now -serial 100
    event generate .t.f <ButtonRelease> -when now
    set x
} -cleanup {
    destroy .t.f
} -result 100
test bind-22.14 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {lappend x %#}
    event generate .t.f <Button> -when head -serial 100
    event generate .t.f <Button> -when head -serial 101
    event generate .t.f <Button> -when head -serial 102
    event generate .t.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} -cleanup {
    destroy .t.f
} -result {foo 102 101 100}
test bind-22.15 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {lappend x %#}
    event generate .t.f <Button> -when head -serial 99
    event generate .t.f <Button> -when mark -serial 100
    event generate .t.f <Button> -when mark -serial 101
    event generate .t.f <Button> -when mark -serial 102
    event generate .t.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} -cleanup {
    destroy .t.f
} -result {foo 100 101 102 99}
test bind-22.16 {HandleEventGenerate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> {lappend x %#}
    event generate .t.f <Button> -when head -serial 99
    event generate .t.f <Button> -when tail -serial 100
    event generate .t.f <Button> -when tail -serial 101
    event generate .t.f <Button> -when tail -serial 102
    event generate .t.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} -cleanup {
    destroy .t.f
} -result {foo 99 100 101 102}
test bind-22.17 {HandleEventGenerate} -body {
    event generate . <Button> -when xyz
} -returnCodes error -result {bad -when value "xyz": must be now, head, mark, or tail}
test bind-22.18 {HandleEventGenerate} -body {
    # Bug 411307
    event generate . <a> -root 98765
} -returnCodes error -result {bad window name/identifier "98765"}

test bind-22.19 {HandleEventGenerate: options <Configure> -above .xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %a"
    event generate .t.f <Configure> -above .xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window path name ".xyz"}
test bind-22.20 {HandleEventGenerate: options <Configure> -above .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %a"
    event generate .t.f <Configure> -above .t
    return $x
} -cleanup {
    destroy .t.f
} -result [winfo id .t]
test bind-22.21 {HandleEventGenerate: options <Configure> -above xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %a"
    event generate .t.f <Configure> -above xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window name/identifier "xyz"}
test bind-22.22 {HandleEventGenerate: options <Configure> -above [winfo id .t]} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %a"
    event generate .t.f <Configure> -above [winfo id .t]
    return $x
} -cleanup {
    destroy .t.f
} -result [winfo id .t]

test bind-22.23 {HandleEventGenerate: options <Key> -above .} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %b"
    event generate .t.f <Key> -above .
    return $x
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-above" option}

test bind-22.24 {HandleEventGenerate: options <Configure> -borderwidth xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %B"
    event generate .t.f <Configure> -borderwidth xyz
    return $x
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.25 {HandleEventGenerate: options <Configure> -borderwidth 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %B"
    event generate .t.f <Configure> -borderwidth 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.26 {HandleEventGenerate: options <Key> -borderwidth 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -borderwidth 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-borderwidth" option}

test bind-22.27 {HandleEventGenerate: options <Button> -button xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %b"
    event generate .t.f <Button> -button xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.28 {HandleEventGenerate: options <Button> -button 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %b"
    event generate .t.f <Button> -button 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.29 {HandleEventGenerate: options <ButtonRelease> -button 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %b"
    event generate .t.f <ButtonRelease> -button 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.30 {HandleEventGenerate: options <Key> -button 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -button 1
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-button" option}

test bind-22.31 {HandleEventGenerate: options <Expose> -count xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %c"
    event generate .t.f <Expose> -count xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.32 {HandleEventGenerate: options <Expose> -count 20} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %c"
    event generate .t.f <Expose> -count 20
    return $x
} -cleanup {
    destroy .t.f
} -result 20

test bind-22.33 {HandleEventGenerate: options <Key> -count 20} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %b"
    event generate .t.f <Key> -count 20
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-count" option}

test bind-22.34 {HandleEventGenerate: options <Enter> -detail xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %d"
    event generate .t.f <Enter> -detail xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad -detail value "xyz": must be NotifyAncestor, NotifyVirtual, NotifyInferior, NotifyNonlinear, NotifyNonlinearVirtual, NotifyPointer, NotifyPointerRoot, or NotifyDetailNone}

test bind-22.35 {HandleEventGenerate: options <FocusIn> -detail NotifyVirtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <FocusIn> "lappend x FocusIn %d"
    event generate .t.f <FocusIn> -detail NotifyVirtual
    return $x
} -cleanup {
    destroy .t.f
} -result {FocusIn NotifyVirtual}

test bind-22.35.1 {HandleEventGenerate: options <FocusOut> -detail NotifyVirtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <FocusOut> "lappend x FocusOut %d"
    event generate .t.f <FocusOut> -detail NotifyVirtual
    return $x
} -cleanup {
    destroy .t.f
} -result {FocusOut NotifyVirtual}

test bind-22.36 {HandleEventGenerate: options <Enter> -detail NotifyVirtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %d"
    event generate .t.f <Enter> -detail NotifyVirtual
    return $x
} -cleanup {
    destroy .t.f
} -result {NotifyVirtual}

test bind-22.37 {HandleEventGenerate: options <Key> -detail NotifyVirtual} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -detail NotifyVirtual
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-detail" option}

test bind-22.38 {HandleEventGenerate: options <Enter> -focus xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %f"
    event generate .t.f <Enter> -focus xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected boolean value but got "xyz"}

test bind-22.39 {HandleEventGenerate: options <Enter> -focus 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %f"
    event generate .t.f <Enter> -focus 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.40 {HandleEventGenerate: options <Key> -focus 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -focus 1
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-focus" option}

test bind-22.41 {HandleEventGenerate: options <Expose> -height xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %h"
    event generate .t.f <Expose> -height xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.42 {HandleEventGenerate: options <Expose> -height 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %h"
    event generate .t.f <Expose> -height 2i
    expr {$x eq [winfo pixels .t.f 2i]}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.43 {HandleEventGenerate: options <Configure> -height 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %h"
    event generate .t.f <Configure> -height 2i
    expr {$x eq [winfo pixels .t.f 2i]}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.44 {HandleEventGenerate: options <Key> -height 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -height 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-height" option}

test bind-22.45 {HandleEventGenerate: options <Key> -keycode xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -keycode xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.46 {HandleEventGenerate: options <Key> -keycode 20} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -keycode 20
    return $x
} -cleanup {
    destroy .t.f
} -result 20

test bind-22.47 {HandleEventGenerate: options <Button> -keycode 20} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %b"
    event generate .t.f <Button> -keycode 20
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Button> event doesn't accept "-keycode" option}

test bind-22.48 {HandleEventGenerate: options <Key> -keysym xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %K"
    event generate .t.f <Key> -keysym xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {unknown keysym "xyz"}

test bind-22.49 {HandleEventGenerate: options <Key> -keysym space} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %K"
    event generate .t.f <Key> -keysym space
    return $x
} -cleanup {
    destroy .t.f
} -result {space}

test bind-22.50 {HandleEventGenerate: options <Button> -keysym space} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %b"
    event generate .t.f <Button> -keysym space
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Button> event doesn't accept "-keysym" option}

test bind-22.51 {HandleEventGenerate: options <Enter> -mode xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %m"
    event generate .t.f <Enter> -mode xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad -mode value "xyz": must be NotifyNormal, NotifyGrab, NotifyUngrab, or NotifyWhileGrabbed}

test bind-22.52 {HandleEventGenerate: options <Enter> -mode NotifyNormal} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %m"
    event generate .t.f <Enter> -mode NotifyNormal
    return $x
} -cleanup {
    destroy .t.f
} -result {NotifyNormal}

test bind-22.53 {HandleEventGenerate: options <FocusIn> -mode NotifyNormal} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <FocusIn> "lappend x %m"
    event generate .t.f <FocusIn> -mode NotifyNormal
    return $x
} -cleanup {
    destroy .t.f
} -result {NotifyNormal}

test bind-22.54 {HandleEventGenerate: options <Key> -mode NotifyNormal} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -mode NotifyNormal
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-mode" option}
test bind-22.55 {HandleEventGenerate: options <Map> -override xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Map> "lappend x %o"
    event generate .t.f <Map> -override xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected boolean value but got "xyz"}

test bind-22.56 {HandleEventGenerate: options <Map> -override 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Map> "lappend x %o"
    event generate .t.f <Map> -override 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.57 {HandleEventGenerate: options <Reparent> -override 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Reparent> "lappend x %o"
    event generate .t.f <Reparent> -override 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.58 {HandleEventGenerate: options <Configure> -override 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %o"
    event generate .t.f <Configure> -override 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.59 {HandleEventGenerate: options <Key> -override 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -override 1
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-override" option}

test bind-22.60 {HandleEventGenerate: options <Circulate> -place xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Circulate> "lappend x %p"
    event generate .t.f <Circulate> -place xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad -place value "xyz": must be PlaceOnTop, or PlaceOnBottom}

test bind-22.61 {HandleEventGenerate: options <Circulate> -place PlaceOnTop} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Circulate> "lappend x %p"
    event generate .t.f <Circulate> -place PlaceOnTop
    return $x
} -cleanup {
    destroy .t.f
} -result {PlaceOnTop}

test bind-22.62 {HandleEventGenerate: options <Key> -place PlaceOnTop} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -place PlaceOnTop
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-place" option}

test bind-22.63 {HandleEventGenerate: options <Key> -root .xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %R"
    event generate .t.f <Key> -root .xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window path name ".xyz"}

test bind-22.64 {HandleEventGenerate: options <Key> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %R"
    event generate .t.f <Key> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.65 {HandleEventGenerate: options <Key> -root xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %R"
    event generate .t.f <Key> -root xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window name/identifier "xyz"}

test bind-22.66 {HandleEventGenerate: options <Key> -root [winfo id .t]} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %R"
    event generate .t.f <Key> -root [winfo id .t]
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.67 {HandleEventGenerate: options <Button> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %R"
    event generate .t.f <Button> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.68 {HandleEventGenerate: options <ButtonRelease> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %R"
    event generate .t.f <ButtonRelease> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.69 {HandleEventGenerate: options <Motion> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %R"
    event generate .t.f <Motion> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.70 {HandleEventGenerate: options <<Paste>> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %R"
    event generate .t.f <<Paste>> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.71 {HandleEventGenerate: options <Enter> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %R"
    event generate .t.f <Enter> -root .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.72 {HandleEventGenerate: options <Configure> -root .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %R"
    event generate .t.f <Configure> -root .t
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-root" option}

test bind-22.73 {HandleEventGenerate: options <Key> -rootx xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %X"
    event generate .t.f <Key> -rootx xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.74 {HandleEventGenerate: options <Key> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %X"
    event generate .t.f <Key> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.75 {HandleEventGenerate: options <Button> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %X"
    event generate .t.f <Button> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.76 {HandleEventGenerate: options <ButtonRelease> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %X"
    event generate .t.f <ButtonRelease> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.77 {HandleEventGenerate: options <Motion> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %X"
    event generate .t.f <Motion> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.78 {HandleEventGenerate: options <<Paste>> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %X"
    event generate .t.f <<Paste>> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.79 {HandleEventGenerate: options <Enter> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %X"
    event generate .t.f <Enter> -rootx 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.80 {HandleEventGenerate: options <Configure> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %X"
    event generate .t.f <Configure> -rootx 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-rootx" option}

test bind-22.81 {HandleEventGenerate: options <Key> -rooty xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %Y"
    event generate .t.f <Key> -rooty xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.82 {HandleEventGenerate: options <Key> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %Y"
    event generate .t.f <Key> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.83 {HandleEventGenerate: options <Button> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %Y"
    event generate .t.f <Button> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.84 {HandleEventGenerate: options <ButtonRelease> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %Y"
    event generate .t.f <ButtonRelease> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.85 {HandleEventGenerate: options <Motion> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %Y"
    event generate .t.f <Motion> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.86 {HandleEventGenerate: options <<Paste>> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %Y"
    event generate .t.f <<Paste>> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.87 {HandleEventGenerate: options <Enter> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %Y"
    event generate .t.f <Enter> -rooty 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.88 {HandleEventGenerate: options <Configure> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %Y"
    event generate .t.f <Configure> -rooty 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-rooty" option}

test bind-22.89 {HandleEventGenerate: options <Key> -sendevent xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %E"
    event generate .t.f <Key> -sendevent xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected boolean value but got "xyz"}

test bind-22.90 {HandleEventGenerate: options <Key> -sendevent 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %E"
    event generate .t.f <Key> -sendevent 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.91 {HandleEventGenerate: options <Key> -sendevent yes} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %E"
    event generate .t.f <Key> -sendevent yes
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.92 {HandleEventGenerate: options <Key> -sendevent 43} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %E"
    event generate .t.f <Key> -sendevent 43
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.93 {HandleEventGenerate: options <Key> -serial xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %#"
    event generate .t.f <Key> -serial xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.94 {HandleEventGenerate: options <Key> -serial 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %#"
    event generate .t.f <Key> -serial 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.95 {HandleEventGenerate: options <Key> -state xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %s"
    event generate .t.f <Key> -state xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.96 {HandleEventGenerate: options <Key> -state 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %s"
    event generate .t.f <Key> -state 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.97 {HandleEventGenerate: options <Button> -state 1025} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %s"
    event generate .t.f <Button> -state 1025
    return $x
} -cleanup {
    destroy .t.f
} -result 1025

test bind-22.98 {HandleEventGenerate: options <ButtonRelease> -state 1025} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %s"
    event generate .t.f <ButtonRelease> -state 1025
    return $x
} -cleanup {
    destroy .t.f
} -result 1025

test bind-22.99 {HandleEventGenerate: options <Motion> -state 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %s"
    event generate .t.f <Motion> -state 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.100 {HandleEventGenerate: options <<Paste>> -state 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %s"
    event generate .t.f <<Paste>> -state 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.101 {HandleEventGenerate: options <Enter> -state 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %s"
    event generate .t.f <Enter> -state 1
    return $x
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.102 {HandleEventGenerate: options <Visibility> -state xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Visibility> "lappend x %s"
    event generate .t.f <Visibility> -state xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad -state value "xyz": must be VisibilityUnobscured, VisibilityPartiallyObscured, or VisibilityFullyObscured}

test bind-22.103 {HandleEventGenerate: options <Visibility> -state VisibilityUnobscured} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Visibility> "lappend x %s"
    event generate .t.f <Visibility> -state VisibilityUnobscured
    return $x
} -cleanup {
    destroy .t.f
} -result {VisibilityUnobscured}

test bind-22.104 {HandleEventGenerate: options <Configure> -state xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %s"
    event generate .t.f <Configure> -state xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-state" option}

test bind-22.105 {HandleEventGenerate: options <Key> -subwindow .xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %S"
    event generate .t.f <Key> -subwindow .xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window path name ".xyz"}

test bind-22.106 {HandleEventGenerate: options <Key> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %S"
    event generate .t.f <Key> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.107 {HandleEventGenerate: options <Key> -subwindow xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %S"
    event generate .t.f <Key> -subwindow xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window name/identifier "xyz"}

test bind-22.108 {HandleEventGenerate: options <Key> -subwindow [winfo id .t]} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %S"
    event generate .t.f <Key> -subwindow [winfo id .t]
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.109 {HandleEventGenerate: options <Button> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %S"
    event generate .t.f <Button> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.110 {HandleEventGenerate: options <ButtonRelease> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %S"
    event generate .t.f <ButtonRelease> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.111 {HandleEventGenerate: options <Motion> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %S"
    event generate .t.f <Motion> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.112 {HandleEventGenerate: options <<Paste>> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %S"
    event generate .t.f <<Paste>> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.113 {HandleEventGenerate: options <Enter> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %S"
    event generate .t.f <Enter> -subwindow .t
    expr {[winfo id .t] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.114 {HandleEventGenerate: options <Configure> -subwindow .t} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %S"
    event generate .t.f <Configure> -subwindow .t
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-subwindow" option}

test bind-22.115 {HandleEventGenerate: options <Key> -time xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %t"
    event generate .t.f <Key> -time xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected integer but got "xyz"}

test bind-22.116 {HandleEventGenerate: options <Key> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %t"
    event generate .t.f <Key> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.117 {HandleEventGenerate: options <Button> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %t"
    event generate .t.f <Button> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.118 {HandleEventGenerate: options <ButtonRelease> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %t"
    event generate .t.f <ButtonRelease> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.119 {HandleEventGenerate: options <Motion> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %t"
    event generate .t.f <Motion> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.120 {HandleEventGenerate: options <<Paste>> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %t"
    event generate .t.f <<Paste>> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.121 {HandleEventGenerate: options <Enter> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %t"
    event generate .t.f <Enter> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.122 {HandleEventGenerate: options <Property> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Property> "lappend x %t"
    event generate .t.f <Property> -time 100
    return $x
} -cleanup {
    destroy .t.f
} -result 100

test bind-22.123 {HandleEventGenerate: options <Configure> -time 100} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %t"
    event generate .t.f <Configure> -time 100
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Configure> event doesn't accept "-time" option}

test bind-22.124 {HandleEventGenerate: options <Expose> -width xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %w"
    event generate .t.f <Expose> -width xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.125 {HandleEventGenerate: options <Expose> -width 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %w"
    event generate .t.f <Expose> -width 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.126 {HandleEventGenerate: options <Configure> -width 2i} -setup {
    frame .t.f -class Test -width 150 -height 100

    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %w"
    event generate .t.f <Configure> -width 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.127 {HandleEventGenerate: options <Key> -width 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -width 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-width" option}

test bind-22.128 {HandleEventGenerate: options <Unmap> -window .xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Unmap> "lappend x %W"
    event generate .t.f <Unmap> -window .xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window path name ".xyz"}

test bind-22.129 {HandleEventGenerate: options <Unmap> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Unmap> "lappend x %W"
    event generate .t.f <Unmap> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.130 {HandleEventGenerate: options <Unmap> -window xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Unmap> "lappend x %W"
    event generate .t.f <Unmap> -window xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad window name/identifier "xyz"}

test bind-22.131 {HandleEventGenerate: options <Unmap> -window [winfo id .t.f]} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Unmap> "lappend x %W"
    event generate .t.f <Unmap> -window [winfo id .t.f]
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.132 {HandleEventGenerate: options <Unmap> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Unmap> "lappend x %W"
    event generate .t.f <Unmap> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.133 {HandleEventGenerate: options <Map> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Map> "lappend x %W"
    event generate .t.f <Map> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.134 {HandleEventGenerate: options <Reparent> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Reparent> "lappend x %W"
    event generate .t.f <Reparent> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.135 {HandleEventGenerate: options <Configure> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %W"
    event generate .t.f <Configure> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.136 {HandleEventGenerate: options <Gravity> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Gravity> "lappend x %W"
    event generate .t.f <Gravity> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.137 {HandleEventGenerate: options <Circulate> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Circulate> "lappend x %W"
    event generate .t.f <Circulate> -window .t.f
    return $x
} -cleanup {
    destroy .t.f
} -result {.t.f}

test bind-22.138 {HandleEventGenerate: options <Key> -window .t.f} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %W"
    event generate .t.f <Key> -window .t.f
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Key> event doesn't accept "-window" option}

test bind-22.139 {HandleEventGenerate: options <Key> -x xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %x"
    event generate .t.f <Key> -x xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.140 {HandleEventGenerate: options <Key> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %x"
    event generate .t.f <Key> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.141 {HandleEventGenerate: options <Button> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %x"
    event generate .t.f <Button> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.142 {HandleEventGenerate: options <ButtonRelease> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %x"
    event generate .t.f <ButtonRelease> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.143 {HandleEventGenerate: options <Motion> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %x"
    event generate .t.f <Motion> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.144 {HandleEventGenerate: options <<Paste>> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %x"
    event generate .t.f <<Paste>> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.145 {HandleEventGenerate: options <Enter> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %x"
    event generate .t.f <Enter> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.146 {HandleEventGenerate: options <Expose> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %x"
    event generate .t.f <Expose> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.147 {HandleEventGenerate: options <Configure> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %x"
    event generate .t.f <Configure> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.148 {HandleEventGenerate: options <Gravity> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Gravity> "lappend x %x"
    event generate .t.f <Gravity> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.149 {HandleEventGenerate: options <Reparent> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Reparent> "lappend x %x"
    event generate .t.f <Reparent> -x 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.150 {HandleEventGenerate: options <Map> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Map> "lappend x %x"
    event generate .t.f <Map> -x 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Map> event doesn't accept "-x" option}

test bind-22.151 {HandleEventGenerate: options <Key> -y xyz} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %y"
    event generate .t.f <Key> -y xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.152 {HandleEventGenerate: options <Key> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %y"
    event generate .t.f <Key> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.153 {HandleEventGenerate: options <Button> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button> "lappend x %y"
    event generate .t.f <Button> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.154 {HandleEventGenerate: options <ButtonRelease> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <ButtonRelease> "lappend x %y"
    event generate .t.f <ButtonRelease> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.155 {HandleEventGenerate: options <Motion> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Motion> "lappend x %y"
    event generate .t.f <Motion> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.156 {HandleEventGenerate: options <<Paste>> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> "lappend x %y"
    event generate .t.f <<Paste>> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.157 {HandleEventGenerate: options <Enter> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x %y"
    event generate .t.f <Enter> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.158 {HandleEventGenerate: options <Expose> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %y"
    event generate .t.f <Expose> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.159 {HandleEventGenerate: options <Configure> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %y"
    event generate .t.f <Configure> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.160 {HandleEventGenerate: options <Gravity> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Gravity> "lappend x %y"
    event generate .t.f <Gravity> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.161 {HandleEventGenerate: options <Reparent> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Reparent> "lappend x %y"
    event generate .t.f <Reparent> -y 2i
    expr {[winfo pixels .t.f 2i] eq $x}
} -cleanup {
    destroy .t.f
} -result 1

test bind-22.162 {HandleEventGenerate: options <Map> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Map> "lappend x %y"
    event generate .t.f <Map> -y 2i
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<Map> event doesn't accept "-y" option}

test bind-22.163 {HandleEventGenerate: options <Key> -xyz 1} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %k"
    event generate .t.f <Key> -xyz 1
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad option "-xyz": must be -when, -above, -borderwidth, -button, -count, -data, -delta, -detail, -focus, -height, -keycode, -keysym, -mode, -override, -place, -root, -rootx, -rooty, -sendevent, -serial, -state, -subwindow, -time, -warp, -width, -window, -x, or -y}
# Note that the -data option is tested in bind-32.* because it has
# more demanding requirements in memory handling


test bind-23.1 {GetVirtualEventUid procedure} -body {
    event info <<asd
} -returnCodes error -result {virtual event "<<asd" is badly formed}
test bind-23.2 {GetVirtualEventUid procedure} -body {
    event info <<>>
} -returnCodes error -result {virtual event "<<>>" is badly formed}
test bind-23.3 {GetVirtualEventUid procedure} -body {
    event info <<asd>
} -returnCodes error -result {virtual event "<<asd>" is badly formed}
test bind-23.4 {GetVirtualEventUid procedure} -setup {
    event delete <<asd>>
} -body {
    event info <<asd>>
} -result {}


test bind-24.1 {FindSequence procedure: no event} -body {
    bind .t {} test
} -returnCodes error -result {no events specified in binding}
test bind-24.2 {FindSequence procedure: bad event} -body {
    bind .t <xyz> test
} -returnCodes error -result {bad event type or keysym "xyz"}
test bind-24.3 {FindSequence procedure: virtual allowed} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<Paste>> test
} -cleanup {
    destroy .t.f
} -result  {}
test bind-24.4 {FindSequence procedure: virtual not allowed} -body {
    event add <<Paste>> <<Alive>>
} -returnCodes error -result {virtual event not allowed in definition of another virtual event}
test bind-24.5 {FindSequence procedure, multiple bindings} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-1> {lappend x single}
    bind .t.f <Double-Button-1> {lappend x double}
    bind .t.f <Triple-Button-1> {lappend x triple}
    bind .t.f <Quadruple-Button-1> {lappend x quadruple}
    set x press
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    lappend x press
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    lappend x press
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    lappend x press
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    lappend x press
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
} -result {press single press double press triple press quadruple press quadruple}
test bind-24.6 {FindSequence procedure: virtual composed} -body {
    bind .t <Control-b><<Paste>> "puts hi"
} -returnCodes error -result {virtual events may not be composed}
test bind-24.7 {FindSequence procedure: new pattern sequence} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-2> {lappend x 1-2}
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {1-2}
test bind-24.8 {FindSequence procedure: similar pattern sequence} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-2> {lappend x 1-2}
    bind .t.f <Button-2> {lappend x 2}
    event generate .t.f <Button-3>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {2 1-2}
test bind-24.9 {FindSequence procedure: similar pattern sequence} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-2> {lappend x 1-2}
    bind .t.f <Button-2><Button-2> {lappend x 2-2}
    event generate .t.f <Button-3>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {2-2 1-2}
test bind-24.10 {FindSequence procedure: similar pattern sequence} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2><Button-2> {lappend x 2-2}
    bind .t.f <Double-Button-2> {lappend x d-2}
    event generate .t.f <Button-3>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    event generate .t.f <Button-2> -x 100
    event generate .t.f <ButtonRelease-2>
    event generate .t.f <Button-2> -x 200
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {d-2 2-2}
test bind-24.11 {FindSequence procedure: new sequence, don't create} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-2>
} -cleanup {
    destroy .t.f
} -result {}
test bind-24.12 {FindSequence procedure: not new sequence, don't create} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Control-Button-2> "foo"
    bind .t.f <Button-2>
} -cleanup {
    destroy .t.f
} -result {}
test bind-24.13 {FindSequence procedure: no binding} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <a>
} -cleanup {
    destroy .t.f
} -returnCodes ok
test bind-24.14 {FindSequence procedure: no binding} -body {
    canvas .t.c
    set i [.t.c create rect 10 10 100 100]
    .t.c bind $i <a>
} -cleanup {
    destroy .t.c
} -returnCodes ok

test bind-25.1 {ParseEventDescription procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f a test
    bind .t.f a
} -cleanup {
    destroy .t.f
} -result test
test bind-25.2 {ParseEventDescription procedure: misinterpreted modifier} -setup {
    button .b
} -body {
    bind .b <Control-M> a
    bind .b <M-M> b
    lsort [bind .b]
} -cleanup {
    destroy .b
} -result {<Control-Key-M> <Meta-Key-M>}
test bind-25.3 {ParseEventDescription procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <a---> {nothing}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result a
test bind-25.4 {ParseEventDescription} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <<Shift-Paste>> {puts hi}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<<Shift-Paste>>}

# Assorted error cases in event sequence parsing
test bind-25.5 {ParseEventDescription procedure error cases} -body {
    bind .t \x7 {puts hi}
} -returnCodes error -result {bad ASCII character 0x7}
test bind-25.6 {ParseEventDescription procedure error cases} -body {
    bind .t \x7f {puts hi}
} -returnCodes error -result {bad ASCII character 0x7f}
test bind-25.7 {ParseEventDescription procedure error cases} -body {
    bind .t \x4 {puts hi}
} -returnCodes error -result {bad ASCII character 0x4}
test bind-25.8 {ParseEventDescription procedure error cases} -body {
    bind .t <<>>  {puts hi}
} -returnCodes error -result {virtual event "<<>>" is badly formed}
test bind-25.9 {ParseEventDescription procedure error cases} -body {
    bind .t <<Paste  {puts hi}
} -returnCodes error -result {missing ">" in virtual binding}
test bind-25.10 {ParseEventDescription procedure error cases} -body {
    bind .t <<Paste>  {puts hi}
} -returnCodes error -result {missing ">" in virtual binding}
test bind-25.11 {ParseEventDescription procedure error cases} -body {
    bind .t <<Paste>>h  {puts hi}
} -returnCodes error -result {virtual events may not be composed}
test bind-25.12 {ParseEventDescription procedure error cases} -body {
    bind .t <>  {puts hi}
} -returnCodes error -result {no event type or button # or keysym}
test bind-25.13 {ParseEventDescription procedure error cases} -body {
    bind .t <a--  {puts hi}
} -returnCodes error -result {missing ">" in binding}
test bind-25.14 {ParseEventDescription procedure error cases} -body {
    bind .t <a-b> {puts hi}
} -returnCodes error -result {extra characters after detail in binding}
test bind-25.15 {ParseEventDescription procedure error cases} -body {
    bind .t <<abc   {puts hi}
} -returnCodes error -result {missing ">" in virtual binding}
test bind-25.16 {ParseEventDescription procedure error cases} -body {
    bind .t <<abc>  {puts hi}
} -returnCodes error -result {missing ">" in virtual binding}
test bind-25.17 {ParseEventDescription} -body {
    event add <<xyz>> <<abc>>
} -returnCodes error -result {virtual event not allowed in definition of another virtual event}

# Modifier canonicalization tests

test bind-25.18 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f {<Control- a>} foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Control-Key-a>

test bind-25.19 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Shift-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Shift-Key-a>

test bind-25.20 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Lock-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Lock-Key-a>

test bind-25.21 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Meta---a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Meta-Key-a>

test bind-25.22 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Meta-Key-a>

test bind-25.23 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Alt-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Alt-Key-a>

test bind-25.24 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <B1-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B1-Key-a>

test bind-25.25 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <B2-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B2-Key-a>

test bind-25.26 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <B3-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B3-Key-a>

test bind-25.27 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <B4-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B4-Key-a>

test bind-25.28 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <B5-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B5-Key-a>

test bind-25.29 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button1-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B1-Key-a>

test bind-25.30 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button2-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B2-Key-a>

test bind-25.31 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button3-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B3-Key-a>

test bind-25.32 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button4-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B4-Key-a>

test bind-25.33 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button5-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B5-Key-a>

test bind-25.34 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M1-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod1-Key-a>

test bind-25.35 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M2-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod2-Key-a>

test bind-25.36 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M3-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod3-Key-a>

test bind-25.37 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M4-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod4-Key-a>

test bind-25.38 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M5-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod5-Key-a>

test bind-25.39 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Mod1-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod1-Key-a>

test bind-25.40 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Mod2-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod2-Key-a>

test bind-25.41 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Mod3-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod3-Key-a>

test bind-25.42 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Mod4-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod4-Key-a>

test bind-25.43 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Mod5-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod5-Key-a>

test bind-25.44 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Double-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Double-Key-a>

test bind-25.45 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Triple-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Triple-Key-a>

test bind-25.46 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f {<Double 1>} foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Double-Button-1>

test bind-25.47 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Triple-1> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Triple-Button-1>

test bind-25.48 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f {<M1-M2 M3-M4 B1-Control-a>} foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Control-B1-Mod1-Mod2-Mod3-Mod4-Key-a>

test bind-25.49 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Extended-Return> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Extended-Key-Return>

test bind-25.50 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button6-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B6-Key-a>

test bind-25.51 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button7-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B7-Key-a>

test bind-25.52 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button8-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B8-Key-a>

test bind-25.53 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Button9-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B9-Key-a>



test bind-26.1 {event names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <FocusIn> {nothing}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <FocusIn>
test bind-26.2 {event names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <FocusOut> {nothing}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <FocusOut>
test bind-26.3 {event names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Destroy> {lappend x "destroyed"}
    set x [bind .t.f]
    destroy .t.f
    set x
} -cleanup {
    destroy .t.f
} -result {<Destroy> destroyed}

test bind-26.4 {event names: Motion} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Motion> "set x {event Motion}"
    set x xyzzy
    event generate .t.f <Motion>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Motion} <Motion>}

test bind-26.5 {event names: Button} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> "set x {event Button}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Button} <Button>}

test bind-26.6 {event names: ButtonPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> "set x {event Button}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Button} <Button>}

test bind-26.7 {event names: ButtonRelease} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <ButtonRelease> "set x {event ButtonRelease}"
    set x xyzzy
    event generate .t.f <ButtonRelease>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event ButtonRelease} <ButtonRelease>}

test bind-26.8 {event names: Colormap} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Colormap> "set x {event Colormap}"
    set x xyzzy
    event generate .t.f <Colormap>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Colormap} <Colormap>}

test bind-26.9 {event names: Enter} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Enter> "set x {event Enter}"
    set x xyzzy
    event generate .t.f <Enter>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Enter} <Enter>}

test bind-26.10 {event names: Leave} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Leave> "set x {event Leave}"
    set x xyzzy
    event generate .t.f <Leave>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Leave} <Leave>}

test bind-26.11 {event names: Expose} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Expose> "set x {event Expose}"
    set x xyzzy
    event generate .t.f <Expose>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Expose} <Expose>}

test bind-26.12 {event names: Key} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> "set x {event Key}"
    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Key} <Key>}

test bind-26.13 {event names: KeyPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> "set x {event KeyPress}"
    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event KeyPress} <Key>}

test bind-26.14 {event names: KeyRelease} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <KeyRelease> "set x {event KeyRelease}"
    set x xyzzy
    event generate .t.f <KeyRelease>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event KeyRelease} <KeyRelease>}

test bind-26.15 {event names: Property} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Property> "set x {event Property}"
    set x xyzzy
    event generate .t.f <Property>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Property} <Property>}

test bind-26.16 {event names: Visibility} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Visibility> "set x {event Visibility}"
    set x xyzzy
    event generate .t.f <Visibility>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Visibility} <Visibility>}

test bind-26.17 {event names: Activate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Activate> "set x {event Activate}"
    set x xyzzy
    event generate .t.f <Activate>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Activate} <Activate>}

test bind-26.18 {event names: Deactivate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Deactivate> "set x {event Deactivate}"
    set x xyzzy
    event generate .t.f <Deactivate>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Deactivate} <Deactivate>}


# These events require an extra argument to [event generate]
test bind-26.19 {event names: Circulate} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Circulate> "set x {event Circulate}"
    set x xyzzy
    event generate .t.f <Circulate>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Circulate} <Circulate>}

test bind-26.20 {event names: Configure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> "set x {event Configure}"
    set x xyzzy
    event generate .t.f <Configure>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Configure} <Configure>}

test bind-26.21 {event names: Gravity} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Gravity> "set x {event Gravity}"
    set x xyzzy
    event generate .t.f <Gravity>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Gravity} <Gravity>}

test bind-26.22 {event names: Map} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Map> "set x {event Map}"
    set x xyzzy
    event generate .t.f <Map>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Map} <Map>}

test bind-26.23 {event names: Reparent} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Reparent> "set x {event Reparent}"
    set x xyzzy
    event generate .t.f <Reparent>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Reparent} <Reparent>}

test bind-26.24 {event names: Unmap} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Unmap> "set x {event Unmap}"
    set x xyzzy
    event generate .t.f <Unmap>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Unmap} <Unmap>}


test bind-27.1 {button names} -body {
    bind .t <Expose-1> foo
} -returnCodes error -result {specified button "1" for non-button event}
test bind-27.2 {button names} -body {
    bind .t <Button-10> foo
} -returnCodes error -result {bad button number "10"}
test bind-27.3 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-1> {lappend x "button 1"}
    set x [bind .t.f]
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-1> {button 1}}
test bind-27.4 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-2> {lappend x "button 2"}
    set x [bind .t.f]
    event generate .t.f <Button-2>
    event generate .t.f <ButtonRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-2> {button 2}}
test bind-27.5 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-3> {lappend x "button 3"}
    set x [bind .t.f]
    event generate .t.f <Button-3>
    event generate .t.f <ButtonRelease-3>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-3> {button 3}}
test bind-27.6 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-4> {lappend x "button 4"}
    set x [bind .t.f]
    event generate .t.f <Button-4>
    event generate .t.f <ButtonRelease-4>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-4> {button 4}}
test bind-27.7 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-5> {lappend x "button 5"}
    set x [bind .t.f]
    event generate .t.f <Button-5>
    event generate .t.f <ButtonRelease-5>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-5> {button 5}}
test bind-27.8 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-6> {lappend x "button 6"}
    set x [bind .t.f]
    event generate .t.f <Button-6>
    event generate .t.f <ButtonRelease-6>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-6> {button 6}}
test bind-27.9 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-7> {lappend x "button 7"}
    set x [bind .t.f]
    event generate .t.f <Button-7>
    event generate .t.f <ButtonRelease-7>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-7> {button 7}}
test bind-27.10 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-8> {lappend x "button 8"}
    set x [bind .t.f]
    event generate .t.f <Button-8>
    event generate .t.f <ButtonRelease-8>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-8> {button 8}}
test bind-27.11 {button names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button-9> {lappend x "button 9"}
    set x [bind .t.f]
    event generate .t.f <Button-9>
    event generate .t.f <ButtonRelease-9>
    set x
} -cleanup {
    destroy .t.f
} -result {<Button-9> {button 9}}

test bind-28.1 {keysym names} -body {
    bind .t <Expose-a> foo
} -returnCodes error -result {specified keysym "a" for non-key event}
test bind-28.2 {keysym names} -body {
    bind .t <Gorp> foo
} -returnCodes error -result {bad event type or keysym "Gorp"}
test bind-28.3 {keysym names} -body {
    bind .t <Stupid> foo
} -returnCodes error -result {bad event type or keysym "Stupid"}
test bind-28.4 {keysym names} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {a}

test bind-28.5 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <colon> "lappend x \"keysym received\""
    bind .t.f <underscore> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <colon> ;# -state 0
    set x
} -cleanup {
    destroy .t.f
} -result {: _ {keysym received}}
test bind-28.6 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Return> "lappend x \"keysym Return\""
    bind .t.f <x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <Return> -state 0
    set x
} -cleanup {
    destroy .t.f
} -result {<Key-Return> x {keysym Return}}
test bind-28.7 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <X> "lappend x \"keysym X\""
    bind .t.f <x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result {X x {keysym X}}
test bind-28.8 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <X> "lappend x \"keysym X\""
    bind .t.f <x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result {X x {keysym X}}
test bind-28.9 {keysym names, Eth -> ETH} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Eth> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-ETH>}
test bind-28.10 {keysym names, Ooblique -> Oslash} -constraints nodeprecated -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Ooblique> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-Oslash>}
test bind-28.11 {keysym names, gcedilla} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <gcedilla> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-gcedilla>}
test bind-28.12 {keysym names, Greek_IOTAdiaeresis -> Greek_IOTAdieresis} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Greek_IOTAdiaeresis> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-Greek_IOTAdieresis>}


test bind-29.1 {Tcl_BackgroundError procedure} -setup {
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {error "This is a test"}
    set x none
    event generate .t.f <Button>
    event generate .t.f <ButtonRelease>
    update
    set x
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{This is a test} {This is a test
    while executing
"error "This is a test""
    (command bound to event)}}

test bind-29.2 {Tcl_BackgroundError procedure} -setup {
    proc do {} {
        event generate .t.f <Button>
        event generate .t.f <ButtonRelease>
    }
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> {error Message2}
    set x none
    do
    update
    set x
} -cleanup {
    destroy .t.f
    rename bgerror {}
    rename do {}
} -result {Message2 {Message2
    while executing
"error Message2"
    (command bound to event)}}


test bind-30.1 {MouseWheel events} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <MouseWheel> {set x Wheel}
    event generate .t.f <MouseWheel>
    set x
} -cleanup {
    destroy .t.f
} -result {Wheel}
test bind-30.2 {MouseWheel events} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <MouseWheel> {set x %D}
    event generate .t.f <MouseWheel> -delta 120
    set x
} -cleanup {
    destroy .t.f
} -result 120
test bind-30.3 {MouseWheel events} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <MouseWheel> {set x "%D %x %y"}
    event generate .t.f <MouseWheel> -delta 240 -x 10 -y 30
    set x
} -cleanup {
    destroy .t.f
} -result {240 10 30}


test bind-31.1 {virtual event user_data field - bad generation} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f

    update
} -body {
# Check no confusion, since Focus events use %d for something else
    event generate .t.f <FocusIn> -data foo
} -cleanup {
    destroy .t.f
} -returnCodes error -result {<FocusIn> event doesn't accept "-data" option}
test bind-31.2 {virtual event user_data field - NULL, synch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>>
    set x
} -cleanup {
    destroy .t.f
} -result {TestUserData >{}<}
test bind-31.3 {virtual event user_data field - shared, synch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>> -data "foo bar"
    set x
} -cleanup {
    destroy .t.f
} -result {TestUserData >foo bar<}
test bind-31.4 {virtual event user_data field - unshared, synch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>> -data [string index abc 1]
    set x
} -cleanup {
    destroy .t.f
} -result {TestUserData >b<}
# Note that asynch event handling can only really catch any potential
# extra errors when used in combination with a tool like Purify or
# Valgrind. Such testing is rarely done, but at least any problem with
# reference handling will eventually show up with these tests...
test bind-31.5 {virtual event user_data field - NULL, asynch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>> -when head
    list $x [update] $x
} -cleanup {
    destroy .t.f
} -result {{} {} {TestUserData >{}<}}
test bind-31.6 {virtual event user_data field - shared, asynch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>> -data "foo bar" -when head
    list $x [update] $x
} -cleanup {
    destroy .t.f
} -result {{} {} {TestUserData >foo bar<}}
test bind-31.7 {virtual event user_data field - unshared, asynch} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <<TestUserData>> {set x "TestUserData >%d<"}
    event generate .t.f <<TestUserData>> -data [string index abc 1] -when head
    list $x [update] $x
} -cleanup {
    destroy .t.f
} -result {{} {} {TestUserData >b<}}

test bind-32.1 {-warp, window was destroyed before the idle callback DoWarp} -setup {
    # note: this test is now essentially useless
    #       since DoWarp no longer exist, not even as an idle callback
    frame .t.f
    pack .t.f
    focus -force .t.f
    update
} -body {
    event generate .t.f <Button-1> -warp 1
    event generate .t.f <ButtonRelease-1>
    destroy .t.f
    update  ;  # shall simply not crash
} -cleanup {
} -result {}
test bind-32.2 {detection of double click should not fail} -setup {
    pack [frame .t.f]
    focus -force .t.f
    bind .t.f <Double-Button-1> { set x "Double" }
    update
    set x {}
} -body {
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    # Simulate a lot of intervening exposure events. The old implementation
    # that used an event ring overflowed, and the double click was not detected.
    # But new implementation should work properly.
    for {set i 0} {$i < 1000} {incr i} {
        event generate .t.f <Expose>
    }
    event generate .t.f <Button-1>
    event generate .t.f <ButtonRelease-1>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-32.3 {should trigger best match of modifier states} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Alt-Control-A> { lappend x "Alt-Control" }
    bind .t.f <Shift-Control-A> { lappend x "Shift-Control" }
    bind .t.f <Shift-A> { lappend x "Shift" }
    event generate .t.f <Alt-Control-A>
    set x
} -cleanup {
    destroy .t.f
} -result {Shift-Control}
test bind-32.4 {should not trigger Double-1} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Double-Button-1> { set x "Double" }
    event generate .t.f <Button-1> -time current
    after 1000
    event generate .t.f <Button-1> -time current
    set x
} -cleanup {
    destroy .t.f
} -result {}
test bind-32.5 {should trigger Quadruple-1} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Quadruple-Button-1> { set x "Quadruple" }
    bind .t.f <Triple-Button-1> { set x "Triple" }
    bind .t.f <Double-Button-1> { set x "Double" }
    bind .t.f <Button-1> { set x "Single" }
    # Old implementation triggered "Double", but new implementation
    # triggers "Quadruple", the latter behavior conforms to other toolkits.
    event generate .t.f <Button-1> -time 0
    event generate .t.f <Button-1> -time 400
    event generate .t.f <Button-1> -time 800
    event generate .t.f <Button-1> -time 1200
    set x
} -cleanup {
    destroy .t.f
} -result {Quadruple}
test bind-32.6 {problem with sendevent} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    # Old implementation was losing sendevent value
    bind .t.f <FocusIn> { set x "sendevent=%E" }
    event generate .t.f <FocusIn> -sendevent 1
    set x
} -cleanup {
    destroy .t.f
} -result {sendevent=1}
test bind-32.7 {test sequences} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Double-Button-1> { lappend x "Double" }
    bind .t.f <Button-1><Button-1><a> { lappend x "11" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result {Double 11}
test bind-32.8 {test sequences} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Button-1><Double-Button-1><Button-1><a> { lappend x "Double" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-32.9 {trigger events for modifier keys} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> { set x "Key" }
    event generate .t.f <Key> -keysym Caps_Lock
    set x
} -cleanup {
    destroy .t.f
} -result {Key}
test bind-32.10 {reset key state when destroying window} -setup {
    set x {}
} -body {
    pack [frame .t.f]; update; focus -force .t.f
    bind .t.f <A> { set x "A" }
    event generate .t.f <A>
    event generate .t.f <A>
    destroy .t.f; update
    pack [frame .t.f]; update; focus -force .t.f
    bind .t.f <A> { set x "A" }
    bind .t.f <Double-A> { set x "AA" }
    event generate .t.f <A>
    destroy .t.f
    set x
} -result {A}
test bind-32.11 {match detailed virtual} -setup {
    pack [frame .t.f -class Test]
    focus -force .t.f
    update
    set x {}
} -body {
    event add <<TestControlButton1>> <Control-Button-1>
    bind Test <<TestControlButton1>> { set x "Control-Button-1" }
    bind Test <Button-1> { set x "Button-1" }
    bind .t.f <Button-1> { set x "Button-1" }
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
    event delete <<TestControlButton1>>
    bind Test <Button-1> {#}
} -result {Control-Button-1}
test bind-32.12 {don't detect repetition when window has changed} -setup {
    pack [frame .t.f]
    pack [frame .t.g]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1> { set x "1" }
    bind .t.f <Double-Button-1> { set x "11" }
    event generate .t.f <Button-1>
    event generate .t.g <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
    destroy .t.g
} -result 1
test bind-32.13 {don't detect repetition when window has changed} -setup {
    pack [frame .t.f]
    pack [frame .t.g]
    update
    set x {}
} -body {
    bind .t.f <A> { set x "A" }
    bind .t.f <Double-A> { set x "AA" }
    focus -force .t.f; event generate .t.f <A>
    focus -force .t.g; event generate .t.g <A>
    focus -force .t.f; event generate .t.f <A>
    set x
} -cleanup {
    destroy .t.f
    destroy .t.g
} -result {A}
test bind-32.14 {don't detect repetition when window has changed} -setup {
    pack [frame .t.f]
    pack [frame .t.g]
    update
    set x {}
} -body {
    bind .t.f <Button-1> { set x "1" }
    bind .t.f <Double-Button-1> { set x "11" }
    focus -force .t.f; event generate .t.f <Button-1>
    focus -force .t.g; event generate .t.g <Button-1>
    focus -force .t.f; event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
    destroy .t.g
} -result 1
test bind-32.15 {reset button state when destroying window} -setup {
    set x {}
} -body {
    pack [frame .t.f]; update; focus -force .t.f
    bind .t.f <Button-1> { set x "1" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    destroy .t.f; update
    pack [frame .t.f]; update; focus -force .t.f
    bind .t.f <Button-1> { set x "1" }
    bind .t.f <Double-Button-1> { set x "11" }
    event generate .t.f <Button-1>
    destroy .t.f
    set x
} -result 1

test bind-33.1 {prefer longest match} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Button-1><Button-1> { lappend x "a11" }
    bind .t.f <Double-Button-1> { lappend x "Double" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {a11}
test bind-33.2 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Double-Button-1> { lappend x "Double" }
    bind .t.f <Button-1><Button-1> { lappend x "11" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-33.3 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Double-Button-1><a> { lappend x "Double" }
    bind .t.f <a><Button-1><Button-1><a> { lappend x "11" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-33.4 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-1> { lappend x "11" }
    bind .t.f <Double-Button-1> { lappend x "Double" }
    event generate .t.f <Button-1> -time 0
    event generate .t.f <Button-1> -time 1000
    set x
} -cleanup {
    destroy .t.f
} -result 11
test bind-33.5 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-1> { lappend x "11" }
    bind .t.f <Double-Button> { lappend x "Double" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result 11
test bind-33.6 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Button-1><Button-1><Button-1><Button-1><a> { lappend x "1111" }
    bind .t.f <a><Button><Double-Button><Button><a> { lappend x "Any-Double-Any" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result 1111
test bind-33.7 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><a> { lappend x "1" }
    bind .t.f <Button><a> { lappend x "Any" }
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result 1
test bind-33.8 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Double-Button-1><a> { lappend x "1" }
    bind .t.f <Button><Button><a> { lappend x "Any" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result 1
test bind-33.9 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-2><Button-2><Double-Button-1> { lappend x "first" }
    bind .t.f <Button-1><Double-Button-2><Button-1><Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.10 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Double-Button-2><Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button-2><Button-2><Double-Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.11 {should prefer most specific} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2><Double-Button-1><Double-Button-2><Double-Button-1><Button-2><Button-2> { lappend x "first" }
    bind .t.f <Button-2><Button-1><Button-1><Button-2><Button-2><Double-Button-1><Double-Button-2> { lappend x "last" }
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    set x
} -cleanup {
    destroy .t.f
} -result {first}
test bind-33.12 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Control-Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Control-Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.13 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Control-1> { lappend x "first" }
    bind .t.f <Control-1><Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result {last}
test bind-33.14 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "first" }
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.15 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result {last}
test bind-33.16 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
    event generate .t.f <Escape>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control-c>
    set x
} -cleanup {
    destroy .t.f
} -result {Esc_Control-c}
test bind-33.17 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
    bind .t.f <Escape><Control_L><Control-c> { lappend x "Esc_Ctrl_L_Control-c" }
    event generate .t.f <Escape>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control-c>
    set x
} -cleanup {
    destroy .t.f
} -result {Esc_Ctrl_L_Control-c}
test bind-33.18 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
    bind .t.f <Escape><Control_L><Control-c> { lappend x "Esc_Ctrl_L_Control-c" }
    bind .t.f <Escape><Control_L><Control_L><Control-c> { lappend x "Esc_Ctrl_L(2)_Control-c" }
    event generate .t.f <Escape>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control-c>
    set x
} -cleanup {
    destroy .t.f
} -result {Esc_Ctrl_L(2)_Control-c}
test bind-33.19 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
    bind .t.f <Escape><Key><Key><Control-c> { lappend x "Esc_Key(2)_Control-c" }
    event generate .t.f <Escape>
    event generate .t.f <Alt_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control-c>
    set x
} -cleanup {
    destroy .t.f
} -result {Esc_Key(2)_Control-c}
test bind-33.20 {simulate use of the keyboard to trigger a pattern sequence with mixed Key and Button types - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key-1><Button-1> { lappend x "1_Button1" }
    event generate .t.f <Key-1>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {1_Button1}
test bind-33.21 {simulate use of the keyboard to trigger a pattern sequence with mixed Key and Button types - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key-1><Button-1> { lappend x "1_Button1" }
    bind .t.f <Key-1><Button-1><Key-2> { lappend x "1_Button1_2" }
    event generate .t.f <Key-1>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Button-1>
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    set x
} -cleanup {
    destroy .t.f
} -result {1_Button1 1_Button1_2}

test bind-34.1 {-warp works relatively to a window} -setup {
    toplevel .top
    wm geometry .top +100+100
    update
} -body {
    # In order to avoid platform-dependent coordinate results due to
    # decorations and borders, this test warps the pointer twice
    # relatively to a window that moved in the meantime, and checks
    # how much the pointer moved
    wm geometry .top +200+200
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    set pointerPos1 [winfo pointerxy .top]
    wm geometry .top +600+600
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    set pointerPos2 [winfo pointerxy .top]
    # from the first warped position to the second one, the mouse
    # pointer should have moved the same amount as the window moved
    set res 1
    foreach pos1 $pointerPos1 pos2 $pointerPos2 {
        if {$pos1 != [expr {$pos2 - 400}]} {
            set res [list $pointerPos1 $pointerPos2]
        }
    }
    set res
} -cleanup {
    destroy .top
} -result 1
test bind-34.2 {-warp works relatively to the screen} -setup {
} -body {
    # Contrary to bind-34.1, we're directly checking screen coordinates
    event generate {} <Motion> -x 20 -y 20 -warp 1
    set res [winfo pointerxy .]
    event generate {} <Motion> -x 200 -y 200 -warp 1
    lappend res {*}[winfo pointerxy .]
} -cleanup {
} -result {20 20 200 200}
test bind-34.3 {-warp works with null or negative coordinates} -setup {
    # On some OS/WM, at least Linux with KDE, the "Screen edges" feature
    # provides hot spots that can be associated with some action.
    # When activated, the WM will not allow warping to happen on top of
    # a hot spot (which would trigger the corresponding action as an
    # unwanted effect) but will warp the pointer to the hot spot limit only.
    if {[tk windowingsystem] eq "x11"} {
        set halo 1
    } else {
        set halo 0
    }
    set res {}
} -body {
    event generate {} <Motion> -x 0 -y 0 -warp 1
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    event generate {} <Motion> -x 100 -y 100 -warp 1
    event generate {} <Motion> -x -1 -y -1 -warp 1
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    set res
} -cleanup {
} -result {ok ok ok ok}

set keyInfo {}
set numericKeysym {}
proc testKey {window event type mods} {
    global keyInfo numericKeysym
    set keyInfo {}
    set numericKeysym {}
    bind $window <Key> {
	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
	set numericKeysym %N
    }
    focus -force $window
    update
    event generate $window $event
    if {$keyInfo == {}} {
        vwait keyInfo
    }
    set save $keyInfo
    set keyInfo {}
    set injectcmd [list injectkeyevent $type $numericKeysym]
    foreach {option} $mods {
	lappend injectcmd $option
    }
    eval $injectcmd
    if {$keyInfo == {}} {
        vwait keyInfo
    }
    if {$save != $keyInfo} {
	return "[format "0x%x" $numericKeysym] ($mods): $save != $keyInfo"
    }
    return pass
}
proc testKeyWithMods {window keysym type} {
    set result [testKey $window "<$keysym>" $type {}]
    if {$result != {pass}} {
	return $result
    }
    set result [testKey $window "<Shift-$keysym>" $type {-shift}]
    if {$result != {pass}} {
	return $result
    }
    set result [testKey $window "<Option-$keysym>" $type {-option}]
    if {$result != {pass}} {
	return $result
    }
    set result [testKey $window "<Shift-Option-$keysym>" $type {-shift -option}]
    if {$result != {pass}} {
	return $result
    }
    return pass
}
test bind-35.0 {Generated and real key events agree} -constraints {aqua} -body {
    foreach k {o O F2 Home Right Greek_sigma Greek_ALPHA} {
	set result [testKeyWithMods . $k press]
	if {$result != "pass"} {
	    return $result
	}
    }
    return pass
} -cleanup {
} -result pass

test bind-35.1 {Key events agree for entry widgets} -constraints {aqua} -setup {
    toplevel .new
    entry .new.e
    pack .new.e
} -body {
    foreach k {o O F2 Home Right Greek_sigma Greek_ALPHA Menu} {
	set result [testKeyWithMods .new.e $k press]
	if {$result != "pass"} {
	    return $result
	}
    }
    return pass
} -cleanup {
    destroy .new.e
    destroy .new
} -result pass

test bind-35.2 {Can bind to function keys} -constraints {aqua} -body {
    global keyInfo numericKeysym
    bind . <Key> {}
    bind . <Key> {
	lappend keyInfo %K
	set numericKeysym %N
    }
    set keyInfo {}
    set numericKeysym {}
    focus -force .
    event generate . <F2>
    injectkeyevent press $numericKeysym -function
    vwait keyInfo
    return $keyInfo
} -cleanup {
} -result {F2 F2}

test bind-35.3 {Events agree for modifier keys} -constraints {aqua} -setup {
} -body {
    global keyInfo numericalKeysym
    set result {}
    bind . <Key> {
    	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
    	set numericalKeysym [format "0x%x" %N]
    }
    foreach event {
	{<Control_L> -control}
	{<Control_R> -control}
	{<Alt_L> -option}
	{<Alt_R> -option}
	{<Meta_L> -command}
	{<Meta_R> -command}
	{<Shift_L> -shift}
	{<Shift_R> -shift}
    } {
	set keyInfo {}
	event generate . [lindex $event 0]
	if {$keyInfo == {}} {
	    vwait keyInfo
	}
	set save $keyInfo
	injectkeyevent flagschanged $numericKeysym [lindex $event 1]
	if {$keyInfo == {}} {
	    vwait keyInfo
	}
	if {$save != $keyInfo} {
	    return "$save != $keyInfo"
	}
    }
    return pass
} -cleanup {
} -result pass

test bind-36.1 {pointer warp with grab on toplevel, bug [e3888d5820]} -setup {
    event generate {} <Motion> -warp 1 -x 50 -y 50
    toplevel .top
    grab release .top
    wm geometry .top 200x200+300+300
    label .top.l -height 5 -width 20 -highlightthickness 2 \
            -highlightbackground black -bg yellow -text "My label"
    pack .top.l -side bottom
    update
    # On KDE/Plasma _with_the_Aurorae_theme_ (at least), setting up the toplevel
    # and the label will not be finished after the above 'update'. The WM still
    # needs some time before the window is fully ready. For me 50 ms is enough,
    # but let's wait more (it depends on computer performance).
    after 100 ; update
} -body {
    grab .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    foreach {x1 y1} [winfo pointerxy .top.l] {}
    event generate {} <Motion> -warp 1 -x 50 -y 50
    grab release .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    foreach {x2 y2} [winfo pointerxy .top.l] {}
    # success if the coords are the same with or without the grab, and if they
    # are at (10,10) inside the label widget as requested by the warping
    expr {$x1==$x2 && $y1==$y2 && $x1==[winfo rootx .top.l]+10 \
                               && $y1==[winfo rooty .top.l]+10}
} -cleanup {
    destroy .top
    unset x1 y1 x2 y2
} -result 1

# cleanup
cleanupTests
return

# vi:set ts=4 sw=4 et:
# Local Variables:
# mode: tcl
# End:




|
|
|



<




<
|
<
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
>
>
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
<
>
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
|
|
<
|
|
<
<
<
|
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



<
|

|
|

<
<
<
<
<
<
<
|
<
|




<
<
<
<
|



|

|
<
<
<
|

<
|
|

<
<
|
|
<
<
<
|

<
|
|

<
<
|
|
<
<
<
|

<
|
|

<
<
|
<
<
<
<
<
|
>
|
<
|
|
<
<
|
|
<
<
<
|

<
|
|

<
<
|
|
<
<
<
|

<
|
|

<
<
|
|
<
<
<
|

<
|
|

<
<
|




|
<
<
<
|

<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<



1
2
3
4
5
6
7
8
9
10

11
12
13
14

15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
















2521

















































































































































2522











2523





































































































































2524

































2525













2526







2527






















2528
2529




2530












































































2531











2532


2533





2534
2535







































































2536




























































































































































































2537






2538





















































































































































2539





















2540
2541


























2542














2543





































2544

























2545

2546












2547














2548

































































2549





2550



















































2551














2552




























2553
















2554
2555






































































2556






























































































2557












2558







































































2559
















2560



































2561


















































2562

2563







2564
2565
2566
2567

2568













































































2569












2570






































2571






2572




2573


2574












2575













2576








2577
















































































2578


























































































































2579






























































































































































2580



























2581























2582









































































































































2583
2584







2585
2586

2587










2588


















2589

2590


































2591














2592




















2593












































































































































































































2594

































































2595




2596

















































2597






2598













2599
















2600
























































































2601







2602













2603





2604







2605












2606














































2607






2608





2609






2610













2611

























































































































































2612







2613












2614



































































































































































































































































2615







2616





2617






2618



































2619











2620







2621



























2622





2623






2624





2625






























































2626













2627





2628







2629













































































































































































































































































































































































































































































































































































































2630
2631






2632




2633
2634






2635




2636
2637






2638
2639

2640
2641



2642
2643



















2644




2645












2646













2647












2648













2649



























































































































2650



















































































2651













2652













2653





2654







2655







2656










2657


































2658





2659







2660













2661









































































































































































































































































































2662
2663



2664


2665
2666






2667








2668







2669



2670








































2671
































































2672








2673








2674








2675








2676








2677







2678
2679


































































































































































































































































































































2680













2681













2682







2683





2684













2685




2686








2687





















2688






















































































2689

















































2690
































































2691





2692








































































































































































2693
2694
2695
2696

2697
2698
2699
2700
2701







2702

2703
2704
2705
2706
2707




2708
2709
2710
2711
2712
2713
2714



2715
2716

2717
2718
2719


2720
2721



2722
2723

2724
2725
2726


2727
2728



2729
2730

2731
2732
2733


2734





2735
2736
2737

2738
2739


2740
2741



2742
2743

2744
2745
2746


2747
2748



2749
2750

2751
2752
2753


2754
2755



2756
2757

2758
2759
2760


2761
2762
2763
2764
2765
2766



2767
2768

2769
2770

































































































2771
2772








































































































































































2773











2774







2775













2776


















































































































2777








2778
2779
















2780









2781











































































2782
















2783




2784











2785











































2786























2787


























































































































2788






















































































2789
2790
2791
2792
2793

2794
2795
2796
# This file is a Tcl script to test out Tk's "bind" and "bindtags"
# commands plus the procedures in tkBind.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands
tk useinputmethods 0


catch {destroy .b}

toplevel .b -width 100 -height 50
wm geom .b +0+0
update idletasks

proc setup {} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    pack .b.f
    focus -force .b.f
    foreach p [event info] {event delete $p}
    update
}
proc setup2 {} {
    catch {destroy .b.e}
    entry .b.e
    pack .b.e
    focus -force .b.e
    foreach p [event info] {event delete $p}
    update
}
setup

foreach i [bind Test] {
    bind Test $i {}
}
foreach i [bind all] {
    bind all $i {}
}

test bind-1.1 {bind command} {
    list [catch {bind} msg] $msg
} {1 {wrong # args: should be "bind window ?pattern? ?command?"}}
test bind-1.2 {bind command} {
    list [catch {bind a b c d} msg] $msg
} {1 {wrong # args: should be "bind window ?pattern? ?command?"}}
test bind-1.3 {bind command} {
    list [catch {bind .gorp} msg] $msg
} {1 {bad window path name ".gorp"}}
test bind-1.4 {bind command} {
    list [catch {bind foo} msg] $msg
} {0 {}}
test bind-1.5 {bind command} {
    list [catch {bind .b <gorp-> {}} msg] $msg
} {0 {}}
test bind-1.6 {bind command} {
    catch {destroy .b.f}
    frame .b.f
    bind .b.f <Enter> {test script}
    set result [bind .b.f <Enter>]
    bind .b.f <Enter> {}
    list $result [bind .b.f <Enter>]
} {{test script} {}}
test bind-1.7 {bind command} {
    catch {destroy .b.f}
    frame .b.f
    bind .b.f <Enter> {test script}
    bind .b.f <Enter> {+more text}
    bind .b.f <Enter>
} {test script
more text}
test bind-1.8 {bind command} {
    list [catch {bind .b <gorp-> {test script}} msg] $msg [bind .b]
} {1 {bad event type or keysym "gorp"} {}}
test bind-1.9 {bind command} {
    list [catch {bind .b <gorp->} msg] $msg
} {0 {}}
test bind-1.10 {bind command} {
    catch {destroy .b.f}
    frame .b.f
    bind .b.f <Enter> {script 1}
    bind .b.f <Leave> {script 2}
    bind .b.f a {script for a}
    bind .b.f b {script for b}
    lsort [bind .b.f]
} {<Enter> <Leave> a b}

test bind-2.1 {bindtags command} {
    list [catch {bindtags} msg] $msg
} {1 {wrong # args: should be "bindtags window ?taglist?"}}
test bind-2.2 {bindtags command} {
    list [catch {bindtags a b c} msg] $msg
} {1 {wrong # args: should be "bindtags window ?taglist?"}}
test bind-2.3 {bindtags command} {
    list [catch {bindtags .foo} msg] $msg
} {1 {bad window path name ".foo"}}
test bind-2.4 {bindtags command} {
    bindtags .b
} {.b Toplevel all}
test bind-2.5 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f
} {.b.f Frame .b all}
test bind-2.6 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f {{x y z} b c d}
    bindtags .b.f
} {{x y z} b c d}
test bind-2.7 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f {x y z}
    bindtags .b.f {}
    bindtags .b.f
} {.b.f Frame .b all}
test bind-2.8 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f {x y z}
    bindtags .b.f {a b c d}
    bindtags .b.f
} {a b c d}
test bind-2.9 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f {a b c}
    list [catch {bindtags .b.f "\{"} msg] $msg [bindtags .b.f]
} {1 {unmatched open brace in list} {.b.f Frame .b all}}
test bind-2.10 {bindtags command} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f {a b c}
    list [catch {bindtags .b.f "a .gorp b"} msg] $msg [bindtags .b.f]
} {0 {} {a .gorp b}}
test bind-3.1 {TkFreeBindingTags procedure} {
    catch {destroy .b.f}
    frame .b.f
    bindtags .b.f "a b c d"
    destroy .b.f
} {}
test bind-3.2 {TkFreeBindingTags procedure} {
    catch {destroy .b.f}
    frame .b.f
    catch {bindtags .b.f "a .gorp b .b.f"}
    destroy .b.f
} {}

bind all <Enter> {lappend x "%W enter all"}
bind Test <Enter> {lappend x "%W enter frame"}
bind Toplevel <Enter> {lappend x "%W enter toplevel"}
bind xyz <Enter> {lappend x "%W enter xyz"}
bind {a b} <Enter> {lappend x "%W enter {a b}"}
bind .b <Enter>  {lappend x "%W enter .b"}
test bind-4.1 {TkBindEventProc procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    pack .b.f
    update
    bind .b.f <Enter> {lappend x "%W enter .b.f"}
    set x {}
    event gen .b.f <Enter>
    set x
} {{.b.f enter .b.f} {.b.f enter frame} {.b.f enter .b} {.b.f enter all}}
test bind-4.2 {TkBindEventProc procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    pack .b.f
    update
    bind .b.f <Enter> {lappend x "%W enter .b.f"}
    bindtags .b.f {.b.f {a b} xyz}
    set x {}
    event gen .b.f <Enter>
    set x
} {{.b.f enter .b.f} {.b.f enter {a b}} {.b.f enter xyz}}
test bind-4.3 {TkBindEventProc procedure} {
    set x {}
    event gen .b <Enter>
    set x
} {{.b enter .b} {.b enter toplevel} {.b enter all}}
test bind-4.4 {TkBindEventProc procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    pack .b.f
    update
    bindtags .b.f {.b.f .b.f2 .b.f3}
    frame .b.f3 -width 50 -height 50
    pack .b.f3
    bind .b.f <Enter> {lappend x "%W enter .b.f"}
    bind .b.f3 <Enter> {lappend x "%W enter .b.f3"}
    set x {}
    event gen .b.f <Enter>
    destroy .b.f3
    set x
} {{.b.f enter .b.f} {.b.f enter .b.f3}}
test bind-4.5 {TkBindEventProc procedure} {
    # This tests memory allocation for objPtr;  it won't serve any useful
    # purpose unless run with some sort of allocation checker turned on.
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    pack .b.f
    update
    bindtags .b.f {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}
    event gen .b.f <Enter>
} {}
bind all <Enter> {}
bind Test <Enter> {}
bind Toplevel <Enter> {}
bind xyz <Enter> {}
bind {a b} <Enter> {}
bind .b <Enter> {}

test bind-5.1 {Tk_CreateBindingTable procedure} {
    catch {destroy .b.c}
    canvas .b.c
    .b.c bind foo
} {}

test bind-6.1 {Tk_DeleteBindTable procedure} {
    catch {destroy .b.c}
    canvas .b.c
    .b.c bind foo <1> {string 1}
    .b.c create rectangle 0 0 100 100
    .b.c bind 1 <2> {string 2}
    destroy .b.c
} {}
test bind-6.2 {Tk_DeleteBindTable procedure: pending bindings deleted later} testcbind {
    catch {interp delete foo}
    interp create foo
    foo eval {
	load {} Tk
	tk useinputmethods 0
	load {} Tktest
	wm geometry . +0+0
	frame .t -width 50 -height 50
	bindtags .t {a b c d}
	pack .t
	update
	set x {}
	testcbind a <1> "lappend x a1; destroy ." "lappend x bye.a1"
	bind b <1> "lappend x b1"
	testcbind c <1> "lappend x c1" "lappend x bye.c1"
	testcbind c <2> "lappend x all2" "lappend x bye.all2"
	event gen .t <1>
    }
    set x [foo eval set x]
    interp delete foo
    set x
} {a1 bye.all2 bye.a1 b1 bye.c1}

test bind-7.1 {Tk_CreateBinding procedure: bad binding} {
    catch {destroy .b.c}
    canvas .b.c
    list [catch {.b.c bind foo <} msg] $msg
} {1 {no event type or button # or keysym}}
test bind-7.2 {Tk_CreateBinding procedure: replace existing C binding} testcbind {
    catch {destroy .b.f}
    frame .b.f
    testcbind .b.f <1> "xyz" "lappend x bye.1"
    set x {}
    bind .b.f <1> "abc"
    destroy .b.f
    set x
} {bye.1}
test bind-7.3 {Tk_CreateBinding procedure: append} {
    catch {destroy .b.c}
    canvas .b.c
    .b.c bind foo <1> "button 1"
    .b.c bind foo <1> "+more button 1"
    .b.c bind foo <1>
} {button 1
more button 1}
test bind-7.4 {Tk_CreateBinding procedure: append to non-existing} {
    catch {destroy .b.c}
    canvas .b.c
    .b.c bind foo <1> "+button 1"
    .b.c bind foo <1>
} {button 1}

test bind-8.1 {TkCreateBindingProcedure: error} testcbind {
    list [catch {testcbind . <xyz> "xyz"} msg] $msg
} {1 {bad event type or keysym "xyz"}}
test bind-8.2 {TkCreateBindingProcedure: new binding} testcbind {
    catch {destroy .b.f}
    frame .b.f
    testcbind .b.f <1> "lappend x 1" "lappend x bye.1"
    set x {}
    event gen .b.f <1>
    destroy .b.f
    set x
} {bye.1}
test bind-8.3 {TkCreateBindingProcedure: replace existing} testcbind {
    catch {destroy .b.f}
    frame .b.f
    pack .b.f
    set x {}
    testcbind .b.f <1> "lappend x old1" "lappend x bye.old1"
    testcbind .b.f <1> "lappend x new1" "lappend x bye.new1"
    set x
} {bye.old1}
test bind-8.4 {TkCreateBindingProcedure: replace existing while pending} testcbind {
    catch {destroy .b.f}
    frame .b.f
    pack .b.f
    update
    testcbind .b.f <1> "lappend x .b.f; testcbind Frame <1> {lappend x Frame}"
    testcbind Frame <1> "lappend x never"
    set x {}
    event gen .b.f <1>
    bind .b.f <1> {}
    set x
} {.b.f Frame}

test bind-9.1 {Tk_DeleteBinding procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    list [catch {bind .b.f <} msg] $msg
} {0 {}}
test bind-9.2 {Tk_DeleteBinding procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i {a b c d} {
	bind .b.f $i "binding for $i"
    }
    set result {}
    foreach i {b d a c} {
	bind .b.f $i {}
	lappend result [lsort [bind .b.f]]
    }
    set result
} {{a c d} {a c} c {}}
test bind-9.3 {Tk_DeleteBinding procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i {<1> <Meta-1> <Control-1> <Double-Alt-1>} {
	bind .b.f $i "binding for $i"
    }
    set result {}
    foreach i {<Control-1> <Double-Alt-1> <1> <Meta-1>} {
	bind .b.f $i {}
	lappend result [lsort [bind .b.f]]
    }
    set result
} {{<Button-1> <Double-Alt-Button-1> <Meta-Button-1>} {<Button-1> <Meta-Button-1>} <Meta-Button-1> {}}
test bind-9.4 {Tk_DeleteBinding procedure: pending bindings delete later} testcbind {
    catch {destroy .b.f}
    frame .b.f
    pack .b.f
    update
    bindtags .b.f {a b c}
    testcbind a <1> {lappend x a1; bind c <1> {}; bind c <2> {}} {lappend x bye.a1}
    bind b <1> {lappend x b1}
    testcbind c <1> {lappend x c1} {lappend x bye.c1}
    testcbind c <2> {lappend x c2} {lappend x bye.c2}
    set x {}
    event gen .b.f <1>
    bind a <1> {}
    bind b <1> {}
    set x
} {a1 bye.c2 b1 bye.c1 bye.a1}

test bind-10.1 {Tk_GetBinding procedure} {
    catch {destroy .b.c}
    canvas .b.c
    list [catch {.b.c bind foo <} msg] $msg
} {1 {no event type or button # or keysym}}
test bind-10.2 {Tk_GetBinding procedure} {
    catch {destroy .b.c}
    canvas .b.c
    .b.c bind foo a Test
    .b.c bind foo a
} {Test}
test bind-10.3 {Tk_GetBinding procedure: C binding} testcbind {
    catch {destroy .b.f}
    frame .b.f
    testcbind .b.f <1> "foo"
    list [bind .b.f] [bind .b.f <1>]
} {<Button-1> {}}

test bind-11.1 {Tk_GetAllBindings procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i "! a \\\{ ~ <Delete> <space> <<Paste>> <Tab> <Linefeed> <less> <Meta-a> <Acircumflex>" {
	bind .b.f $i Test
    }
    lsort [bind .b.f]
} {! <<Paste>> <Key-Acircumflex> <Key-Delete> <Key-Linefeed> <Key-Tab> <Key-less> <Key-space> <Meta-Key-a> a \{ ~}
test bind-11.2 {Tk_GetAllBindings procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i "<Double-1> <Triple-1> <Meta-Control-a> <Double-Alt-Enter> <1>" {
	bind .b.f $i Test
    }
    lsort [bind .b.f]
} {<Button-1> <Control-Meta-Key-a> <Double-Alt-Enter> <Double-Button-1> <Triple-Button-1>}
test bind-11.3 {Tk_GetAllBindings procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i "<Double-Triple-1> abcd a<Leave>b" {
	bind .b.f $i Test
    }
    lsort [bind .b.f]
} {<Triple-Button-1> a<Leave>b abcd}


test bind-12.1 {Tk_DeleteAllBindings procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    destroy .b.f
} {}
test bind-12.2 {Tk_DeleteAllBindings procedure} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    foreach i "a b c <Meta-1> <Alt-a> <Control-a>" {
	bind .b.f $i x
    }
    destroy .b.f
} {}
test bind-12.3 {Tk_DeleteAllBindings procedure: pending bindings deleted later} testcbind {
    catch {destroy .b.f}
    frame .b.f
    pack .b.f
    update
    testcbind .b.f <1> {lappend x before; event gen .b.f <2>; lappend x after} {lappend x bye.f1}
    testcbind .b.f <2> {destroy .b.f} {lappend x bye.f2}
    bind .b.f <Destroy> {lappend x fDestroy}
    testcbind .b.f <3> {foo} {lappend x bye.f3}
    set x {}
    event gen .b.f <1>
    set x
} {before fDestroy bye.f3 bye.f2 after bye.f1}

bind Test <KeyPress> {lappend x "%W %K Test press any"}
bind all <KeyPress> {lappend x "%W %K all press any"}
bind Test a {lappend x "%W %K Test press a"}
bind all x {lappend x "%W %K all press x"}

test bind-13.1 {Tk_BindEvent procedure} {
    setup
    bind .b.f a {lappend x "%W %K .b.f press a"}
    set x {}
    event gen .b.f <Key-a>
    event gen .b.f <Key-b>
    event gen .b.f <Key-x>
    set x
} {{.b.f a .b.f press a} {.b.f a Test press a} {.b.f a all press any} {.b.f b Test press any} {.b.f b all press any} {.b.f x Test press any} {.b.f x all press x}}

bind Test <KeyPress> {lappend x "%W %K Test press any"; break}
bind all <KeyPress> {continue; lappend x "%W %K all press any"}

test bind-13.2 {Tk_BindEvent procedure} {
    setup
    bind .b.f b {lappend x "%W %K .b.f press a"}
    set x {}
    event gen .b.f <Key-b>
    set x
} {{.b.f b .b.f press a} {.b.f b Test press any}}
if {[info procs bgerror] == "bgerror"} {
    rename bgerror {}
}
proc bgerror args {}
bind Test <KeyPress> {lappend x "%W %K Test press any"; error Test}
test bind-13.3 {Tk_BindEvent procedure} {
    setup
    bind .b.f b {lappend x "%W %K .b.f press a"}
    set x {}
    event gen .b.f <Key-b>
    update
    list $x $errorInfo
} {{{.b.f b .b.f press a} {.b.f b Test press any}} {Test
    while executing
"error Test"
    (command bound to event)}}
rename bgerror {}
test bind-13.4 {Tk_BindEvent procedure} {
    proc foo {} {
	set x 44
	event gen .b.f <Key-a>
    }
    setup
    bind .b.f a {lappend x "%W %K .b.f press a"}
    set x {}
    foo
    set x
} {{.b.f a .b.f press a} {.b.f a Test press a}}
test bind-13.5 {Tk_BindEvent procedure} {
    bind all <Destroy> {lappend x "%W destroyed"}
    set x {}
    list [catch {frame .b.g -gorp foo} msg] $msg $x
} {1 {unknown option "-gorp"} {{.b.g destroyed}}}
foreach i [bind all] {
    bind all $i {}
}
foreach i [bind Test] {
    bind Test $i {}
}
test bind-13.6 {Tk_BindEvent procedure} {
    setup
    bind .b.f z {lappend x "%W z (.b.f binding)"}
    bind Test z {lappend x "%W z (.b.f binding)"}
    bind all z {bind .b.f z {}; lappend x "%W z (.b.f binding)"}
    set x {}
    event gen .b.f <Key-z>
    bind Test z {}
    bind all z {}
    set x
} {{.b.f z (.b.f binding)} {.b.f z (.b.f binding)} {.b.f z (.b.f binding)}}
test bind-13.7 {Tk_BindEvent procedure} {
    setup
    bind .b.f z {lappend x "%W z (.b.f binding)"}
    bind Test z {lappend x "%W z (.b.f binding)"}
    bind all z {destroy .b.f; lappend x "%W z (.b.f binding)"}
    set x {}
    event gen .b.f <Key-z>
    bind Test z {}
    bind all z {}
    set x
} {{.b.f z (.b.f binding)} {.b.f z (.b.f binding)} {.b.f z (.b.f binding)}}
test bind-13.8 {Tk_BindEvent procedure} {
    setup
    bind .b.f <1> {lappend x "%W z (.b.f <1> binding)"}
    bind .b.f <ButtonPress> {lappend x "%W z (.b.f <ButtonPress> binding)"}
    set x {}
    event gen .b.f <Button-1>
    event gen .b.f <Button-2>
    set x
} {{.b.f z (.b.f <1> binding)} {.b.f z (.b.f <ButtonPress> binding)}}
test bind-13.9 {Tk_BindEvent procedure: ignore NotifyInferior} {
    setup
    bind .b.f <Enter> "lappend x Enter%#"
    bind .b.f <Leave> "lappend x Leave%#"
    set x {}
    event gen .b.f <Enter> -serial 100 -detail NotifyAncestor
    event gen .b.f <Enter> -serial 101 -detail NotifyInferior
    event gen .b.f <Leave> -serial 102 -detail NotifyAncestor
    event gen .b.f <Leave> -serial 103 -detail NotifyInferior
    set x
} {Enter100 Leave102}
test bind-13.10 {Tk_BindEvent procedure: collapse Motions} {
    setup
    bind .b.f <Motion> "lappend x Motion%#(%x,%y)"
    set x {}
    event gen .b.f <Motion> -serial 100 -x 100 -y 200 -when tail
    update
    event gen .b.f <Motion> -serial 101 -x 200 -y 300 -when tail
    event gen .b.f <Motion> -serial 102 -x 300 -y 400 -when tail
    update
    set x
} {Motion100(100,200) Motion102(300,400)}
test bind-13.11 {Tk_BindEvent procedure: collapse repeating modifiers} {
    setup
    bind .b.f <Key> "lappend x %K%#"
    bind .b.f <KeyRelease> "lappend x %K%#"
    event gen .b.f <Key-Shift_L> -serial 100 -when tail
    event gen .b.f <KeyRelease-Shift_L> -serial 101 -when tail
    event gen .b.f <Key-Shift_L> -serial 102 -when tail
    event gen .b.f <KeyRelease-Shift_L> -serial 103 -when tail
    update
} {}
test bind-13.12 {Tk_BindEvent procedure: valid key detail} {
    setup
    bind .b.f <Key> "lappend x Key%K"
    bind .b.f <KeyRelease> "lappend x Release%K"
    set x {}
    event gen .b.f <Key> -keysym a
    event gen .b.f <KeyRelease> -keysym a
    set x
} {Keya Releasea}
test bind-13.13 {Tk_BindEvent procedure: invalid key detail} {
    setup
    bind .b.f <Key> "lappend x Key%K"
    bind .b.f <KeyRelease> "lappend x Release%K"
    set x {}
    event gen .b.f <Key> -keycode 0
    event gen .b.f <KeyRelease> -keycode 0
    set x
} {Key?? Release??}
test bind-13.14 {Tk_BindEvent procedure: button detail} {
    setup
    bind .b.f <Button> "lappend x Button%b"
    bind .b.f <ButtonRelease> "lappend x Release%b"
    set x {}
    event gen .b.f <Button> -button 1
    event gen .b.f <ButtonRelease> -button 3
    set x
} {Button1 Release3}
test bind-13.15 {Tk_BindEvent procedure: virtual detail} {
    setup
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <<Paste>>
    set x
} {Paste}
test bind-13.16 {Tk_BindEvent procedure: virtual event in event stream} {
    setup
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <<Paste>>
    set x
} {Paste}
test bind-13.17 {Tk_BindEvent procedure: match detail physical} {
    setup
    bind .b.f <Button-2> {set x Button-2}
    event add <<Paste>> <Button-2>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Button-2}
test bind-13.18 {Tk_BindEvent procedure: no match detail physical} {
    setup
    event add <<Paste>> <Button-2>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.19 {Tk_BindEvent procedure: match detail virtual} {
    setup
    event add <<Paste>> <Button-2>
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.20 {Tk_BindEvent procedure: no match detail virtual} {
    setup
    event add <<Paste>> <Button-2>
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <Button>
    set x
} {}
test bind-13.21 {Tk_BindEvent procedure: match no-detail physical} {
    setup
    bind .b.f <Button> {set x Button}
    event add <<Paste>> <Button>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Button}
test bind-13.22 {Tk_BindEvent procedure: no match no-detail physical} {
    setup
    event add <<Paste>> <Button>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.23 {Tk_BindEvent procedure: match no-detail virtual} {
    setup
    event add <<Paste>> <Button>
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.24 {Tk_BindEvent procedure: no match no-detail virtual} {
    setup
    event add <<Paste>> <Key>
    bind .b.f <<Paste>> "lappend x Paste"
    set x {}
    event gen .b.f <Button>
    set x
} {}
test bind-13.25 {Tk_BindEvent procedure: precedence} {
    setup
    event add <<Paste>> <Button-2>
    event add <<Copy>> <Button>
    bind .b.f <Button-2> "lappend x Button-2"
    bind .b.f <<Paste>> "lappend x Paste"
    bind .b.f <Button> "lappend x Button"
    bind .b.f <<Copy>> "lappend x Copy"

    set x {}
    event gen .b.f <Button-2>
    bind .b.f <Button-2> {}
    event gen .b.f <Button-2>
    bind .b.f <<Paste>> {}
    event gen .b.f <Button-2>
    bind .b.f <Button> {}
    event gen .b.f <Button-2>
    bind .b.f <<Copy>> {}
    event gen .b.f <Button-2>
    set x
} {Button-2 Paste Button Copy}
test bind-13.26 {Tk_BindEvent procedure: no detail virtual pattern list} {
    setup
    bind .b.f <Button-2> {set x Button-2}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Button-2}
test bind-13.27 {Tk_BindEvent procedure: detail virtual pattern list} {
    setup
    event add <<Paste>> <Button-2>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.28 {Tk_BindEvent procedure: no no-detail virtual pattern list} {
    setup
    bind .b.f <Button> {set x Button}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Button}
test bind-13.29 {Tk_BindEvent procedure: no-detail virtual pattern list} {
    setup
    event add <<Paste>> <Button>
    bind .b.f <<Paste>> {set x Paste}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Paste}
test bind-13.30 {Tk_BindEvent procedure: no match} {
    setup
    event gen .b.f <Button-2>
} {}
test bind-13.31 {Tk_BindEvent procedure: match} {
    setup
    bind .b.f <Button-2> {set x Button-2}
    set x {}
    event gen .b.f <Button-2>
    set x
} {Button-2}
test bind-13.32 {Tk_BindEvent procedure: many C bindings cause realloc} testcbind {
    setup
    bindtags .b.f {a b c d e f g h i j k l m n o p}
    foreach p [bindtags .b.f] {
	testcbind $p <1> "lappend x $p"
    }
    set x {}
    event gen .b.f <1>
    foreach p [bindtags .b.f] {
	bind $p <1> {}
    }
    set x
} {a b c d e f g h i j k l m n o p}
test bind-13.33 {Tk_BindEvent procedure: multiple tags} {
    setup
    bind .b.f <Button-2> {lappend x .b.f}
    bind Test <Button-2> {lappend x Button}
    set x {}
    event gen .b.f <Button-2>
    bind Test <Button-2> {}
    set x
} {.b.f Button}
test bind-13.34 {Tk_BindEvent procedure: execute C binding} testcbind {
    setup
    testcbind .b.f <1> {lappend x 1}
    set x {}
    event gen .b.f <1>
    set x
} {1}
test bind-13.35 {Tk_BindEvent procedure: pending list marked deleted} testcbind {
    setup
    testcbind Test <1> {lappend x Test} {lappend x Deleted}
    bind .b.f <1> {lappend x .b.f; destroy .b.f}
    set x {}
    event gen .b.f <1>
    set y [list $x [bind Test]]
    bind Test <1> {}
    set y
} {.b.f <Button-1>}
test bind-13.36 {Tk_BindEvent procedure: C binding marked deleted} testcbind {
    setup
    testcbind Test <1> {lappend x Test} {lappend x Deleted}
    bind .b.f <1> {lappend x .b.f; bind Test <1> {}; lappend x after}
    set x {}
    event gen .b.f <1>
    set x
} {.b.f after Deleted}
test bind-13.37 {Tk_BindEvent procedure: C binding gets to run} testcbind {
    setup
    testcbind Test <1> {lappend x Test}
    bind .b.f <1> {lappend x .b.f}
    set x {}
    event gen .b.f <1>
    bind Test <1> {}
    set x
} {.b.f Test}
test bind-13.38 {Tk_BindEvent procedure: C binding deleted, refcount == 0} testcbind {
    setup
    testcbind .b.f <1> {lappend x hi; bind .b.f <1> {}} {lappend x bye}
    set x {}
    event gen .b.f <1>
    set x
} {hi bye}
test bind-13.39 {Tk_BindEvent procedure: C binding deleted, refcount != 0} testcbind {
    setup
    testcbind .b.f <1> {
	lappend x before$n
	if {$n==0} {
	    bind .b.f <1> {}
	} else {
	    set n [expr $n-1]
	    event gen .b.f <1>
	}
	lappend x after$n
    } {lappend x Deleted}
    set n 3
    set x {}
    event gen .b.f <1>
    set x
} {before3 before2 before1 before0 after0 after0 after0 after0 Deleted}
test bind-13.40 {Tk_BindEvent procedure: continue in script} {
    setup
    bind .b.f <Button-2> {lappend x b1; continue; lappend x b2}
    bind Test <Button-2> {lappend x B1; continue; lappend x B2}
    set x {}
    event gen .b.f <Button-2>
    bind Test <Button-2> {}
    set x
} {b1 B1}
test bind-13.41 {Tk_BindEvent procedure: continue in script} testcbind {
    setup
    testcbind .b.f <Button-2> {lappend x b1; continue; lappend x b2}
    testcbind Test <Button-2> {lappend x B1; continue; lappend x B2}
    set x {}
    event gen .b.f <Button-2>
    bind Test <Button-2> {}
    set x
} {b1 B1}
test bind-13.42 {Tk_BindEvent procedure: break in script} {
    setup
    bind .b.f <Button-2> {lappend x b1; break; lappend x b2}
    bind Test <Button-2> {lappend x B1; break; lappend x B2}
    set x {}
    event gen .b.f <Button-2>
    bind Test <Button-2> {}
    set x
} {b1}
test bind-13.43 {Tk_BindEvent procedure: break in script} testcbind {
    setup
    testcbind .b.f <Button-2> {lappend x b1; break; lappend x b2}
    testcbind Test <Button-2> {lappend x B1; break; lappend x B2}
    set x {}
    event gen .b.f <Button-2>
    bind Test <Button-2> {}
    set x
} {b1}

proc bgerror msg {
    global x
    lappend x $msg
}
test bind-13.44 {Tk_BindEvent procedure: error in script} {
    setup
    bind .b.f <Button-2> {lappend x b1; blap}
    bind Test <Button-2> {lappend x B1}
    set x {}
    event gen .b.f <Button-2>
    update
    bind Test <Button-2> {}
    set x
} {b1 {invalid command name "blap"}}
test bind-13.45 {Tk_BindEvent procedure: error in script} testcbind {
    setup
    testcbind .b.f <Button-2> {lappend x b1; blap}
    testcbind Test <Button-2> {lappend x B1}
    set x {}
    event gen .b.f <Button-2>
    update
    bind Test <Button-2> {}
    set x
} {b1 {invalid command name "blap"}}

test bind-14.1 {TkBindDeadWindow: no C bindings pending} testcbind {
    setup
    bind .b.f <1> x
    testcbind .b.f <2> y
    destroy .b.f
} {}
test bind-14.2 {TkBindDeadWindow: is called after <Destroy>} testcbind {
    setup
    testcbind .b.f <Destroy> "lappend x .b.f"
    testcbind Test <Destroy> "lappend x Test"
    set x {}
    destroy .b.f
    bind Test <Destroy> {}
    set x
} {.b.f Test}
test bind-14.3 {TkBindDeadWindow: pending C bindings} testcbind {
    setup
    bindtags .b.f {a b c d}
    testcbind a <1> "lappend x a1" "lappend x bye.a1"
    testcbind b <1> "destroy .b.f; lappend x b1" "lappend x bye.b1"
    testcbind c <1> "lappend x c1" "lappend x bye.c1"
    testcbind d <1> "lappend x d1" "lappend x bye.d1"
    bind a <2> "event gen .b.f <1>"
    testcbind b <2> "lappend x b2" "lappend x bye.b2"
    testcbind c <2> "lappend x c2" "lappend x bye.d2"
    bind d <2> "lappend x d2"
    testcbind a <3> "event gen .b.f <2>"
    set x {}
    event gen .b.f <3>
    set y $x
    foreach tag {a b c d} {
	foreach event {<1> <2> <3>} {
	    bind $tag $event {}
	}
    }
    set y
} {a1 b1 d2}

test bind-15.1 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f ab {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <KeyRelease-a>
    event gen .b.f <Key-b>
    event gen .b.f <KeyRelease-b>
    set x
} 1
test bind-15.2 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f ab {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <Enter>
    event gen .b.f <KeyRelease-a>
    event gen .b.f <Leave>
    event gen .b.f <Key-b>
    event gen .b.f <KeyRelease-b>
    set x
} 1
test bind-15.3 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f ab {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <Button-1>
    event gen .b.f <Key-b>
    set x
} 0
test bind-15.4 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.5 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f <Double-ButtonRelease> {set x 1}
    set x 0
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    set x
} 1
test bind-15.6 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-1>
    event gen .b.f <Key-a>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.7 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-1>
    event gen .b.f <Key-Shift_L>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.8 {MatchPatterns procedure, ignoring type mismatches} {
    setup
    bind .b.f ab {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <Key-c>
    event gen .b.f <Key-b>
    set x
} 0
test bind-15.9 {MatchPatterns procedure, modifier checks} {
    setup
    bind .b.f <M1-M2-Key> {set x 1}
    set x 0
    event gen .b.f <Key-a> -state 0x18
    set x
} 1
test bind-15.10 {MatchPatterns procedure, modifier checks} {
    setup
    bind .b.f <M1-M2-Key> {set x 1}
    set x 0
    event gen .b.f <Key-a> -state 0xfc
    set x
} 1
test bind-15.11 {MatchPatterns procedure, modifier checks} {
    setup
    bind .b.f <M1-M2-Key> {set x 1}
    set x 0
    event gen .b.f <Key-a> -state 0x8
    set x
} 0
test bind-15.12 {MatchPatterns procedure, ignore modifier presses and releases} {nonPortable} {
    # This test is non-portable because the Shift_L keysym may behave
    # differently on some platforms.
    setup
    bind .b.f aB {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <Key-Shift_L>
    event gen .b.f <Key-b> -state 1
    set x
} 1
test bind-15.13 {MatchPatterns procedure, checking detail} {
    setup
    bind .b.f ab {set x 1}
    set x 0
    event gen .b.f <Key-a>
    event gen .b.f <Key-c>
    set x
} 0
test bind-15.14 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 31 -y 39
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.15 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 29 -y 41
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.16 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 40 -y 40
    event gen .b.f <ButtonRelease-2>
    set x
} 0
test bind-15.17 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 20 -y 40
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.18 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 30 -y 30
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.19 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -x 30 -y 40
    event gen .b.f <Button-1> -x 30 -y 50
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.20 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -time 300
    event gen .b.f <Button-1> -time 700
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.21 {MatchPatterns procedure, checking "nearby"} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1> -time 300
    event gen .b.f <Button-1> -time 900
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.22 {MatchPatterns procedure, time wrap-around} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-1> -time [expr -100]
    event gen .b.f <Button-1> -time 200
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.23 {MatchPatterns procedure, time wrap-around} {
    setup
    bind .b.f <Double-1> {set x 1}
    set x 0
    event gen .b.f <Button-1> -time -100
    event gen .b.f <Button-1> -time 500
    event gen .b.f <ButtonRelease-1>
    set x
} 0
test bind-15.24 {MatchPatterns procedure, virtual event} {
    setup
    event add <<Paste>> <Button-1>
    bind .b.f <<Paste>> {lappend x paste}
    set x {}
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} {paste}
test bind-15.25 {MatchPatterns procedure, reject a  virtual event} {
    setup
    event add <<Paste>> <Shift-Button-1>
    bind .b.f <<Paste>> {lappend x paste}
    set x {}
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} {}
test bind-15.26 {MatchPatterns procedure, reject a virtual event} {
    setup
    event add <<V1>> <Button>
    event add <<V2>> <Button-1>
    event add <<V3>> <Shift-Button-1>
    bind .b.f <<V2>> "lappend x V2%#"
    set x {}
    event gen .b.f <Button> -serial 101
    event gen .b.f <Button-1> -serial 102
    event gen .b.f <Shift-Button-1> -serial 103
    event gen .b.f <ButtonRelease-1>
    bind .b.f <Shift-Button-1> "lappend x Shift-Button-1"
    event gen .b.f <Button> -serial 104
    event gen .b.f <Button-1> -serial 105
    event gen .b.f <Shift-Button-1> -serial 106
    event gen .b.f <ButtonRelease-1>
    set x
} {V2102 V2103 V2105 Shift-Button-1}
test bind-15.27 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <KeyPress> {set x 0}
    bind .b.f a {set x 1}
    set x none
    event gen .b.f <Key-a>
    set x
} 1
test bind-15.28 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <KeyPress> {set x 0}
    bind .b.f a {set x 1}
    set x none
    event gen .b.f <Key-b>
    set x
} 0
test bind-15.29 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <KeyPress> {lappend x 0}
    bind .b.f a {lappend x 1}
    bind .b.f ba {lappend x 2}
    set x none
    event gen .b.f <Key-b>
    event gen .b.f <KeyRelease-b>
    event gen .b.f <Key-a>
    set x
} {none 0 2}
test bind-15.30 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <ButtonPress> {set x 0}
    bind .b.f <1> {set x 1}
    set x none
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} 1
test bind-15.31 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <M1-Key> {set x 0}
    bind .b.f <M2-Key> {set x 1}
    set x none
    event gen .b.f <Key-a> -state 0x18
    set x
} 1
test bind-15.32 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <M2-Key> {set x 0}
    bind .b.f <M1-Key> {set x 1}
    set x none
    event gen .b.f <Key-a> -state 0x18
    set x
} 1
test bind-15.33 {MatchPatterns procedure, conflict resolution} {
    setup
    bind .b.f <1> {lappend x single}
    bind Test <1> {lappend x single(Test)}
    bind Test <Double-1> {lappend x double(Test)}
    set x {}
    event gen .b.f <Button-1>
    event gen .b.f <Button-1>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} {single single(Test) single double(Test) single double(Test)}
foreach i [bind Test] {
    bind Test $i {}
}
test bind-16.1 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x abcd}
    set x none
    event gen .b.f <Enter>
    set x
} abcd
test bind-16.2 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %#}
    set x none
    event gen .b.f <Enter> -serial 1234
    set x
} 1234
test bind-16.3 {ExpandPercents procedure} {
    setup
    bind .b.f <Configure> {set x %a}
    set x none
    event gen .b.f <Configure> -above .b -window .b.f
    set x
} [winfo id .b]
test bind-16.4 {ExpandPercents procedure} {
    setup
    bind .b.f <Button> {set x %b}
    set x none
    event gen .b.f <Button-3>
    event gen .b.f <ButtonRelease-3>
    set x
} 3
test bind-16.5 {ExpandPercents procedure} {
    setup
    bind .b.f <Expose> {set x %c}
    set x none
    event gen .b.f <Expose> -count 47
    set x
} 47
test bind-16.6 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyAncestor
    set x
} NotifyAncestor
test bind-16.7 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyVirtual
    set x
} NotifyVirtual
test bind-16.8 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyNonlinear
    set x
} NotifyNonlinear
test bind-16.9 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyNonlinearVirtual
    set x
} NotifyNonlinearVirtual
test bind-16.10 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyPointer
    set x
} NotifyPointer
test bind-16.11 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyPointerRoot
    set x
} NotifyPointerRoot
test bind-16.12 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %d}
    set x none
    event gen .b.f <Enter> -detail NotifyDetailNone
    set x
} NotifyDetailNone
test bind-16.13 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x %f}
    set x none
    event gen .b.f <Enter> -focus 1
    set x
} 1
test bind-16.14 {ExpandPercents procedure} {
    setup
    bind .b.f <Expose> {set x "%x %y %w %h"}
    set x none
    event gen .b.f <Expose> -x 24 -y 18 -width 147 -height 61
    set x
} {24 18 147 61}
test bind-16.15 {ExpandPercents procedure} {
    setup
    bind .b.f <Configure> {set x "%x %y %w %h"}
    set x none
    event gen .b.f <Configure> -x 24 -y 18 -width 147 -height 61 -window .b.f
    set x
} {24 18 147 61}
test bind-16.16 {ExpandPercents procedure} {
    setup
    bind .b.f <Key> {set x "%k"}
    set x none
    event gen .b.f <Key> -keycode 146
    set x
} 146
test bind-16.17 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%m"}
    set x none
    event gen .b.f <Enter> -mode NotifyNormal
    set x
} NotifyNormal
test bind-16.18 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%m"}
    set x none
    event gen .b.f <Enter> -mode NotifyGrab
    set x
} NotifyGrab
test bind-16.19 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%m"}
    set x none
    event gen .b.f <Enter> -mode NotifyUngrab
    set x
} NotifyUngrab
test bind-16.20 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%m"}
    set x none
    event gen .b.f <Enter> -mode NotifyWhileGrabbed
    set x
} NotifyWhileGrabbed
test bind-16.21 {ExpandPercents procedure} {
    setup
    bind .b.f <Map> {set x "%o"}
    set x none
    event gen .b.f <Map> -override 1 -window .b.f
    set x
} 1
test bind-16.22 {ExpandPercents procedure} {
    setup
    bind .b.f <Reparent> {set x "%o"}
    set x none
    event gen .b.f <Reparent> -override true -window .b.f
    set x
} 1
test bind-16.23 {ExpandPercents procedure} {
    setup
    bind .b.f <Configure> {set x "%o"}
    set x none
    event gen .b.f <Configure> -override 1 -window .b.f
    set x
} 1
test bind-16.24 {ExpandPercents procedure} {
    setup
    bind .b.f <Circulate> {set x "%p"}
    set x none
    event gen .b.f <Circulate> -place PlaceOnTop -window .b.f
    set x
} PlaceOnTop
test bind-16.25 {ExpandPercents procedure} {
    setup
    bind .b.f <Circulate> {set x "%p"}
    set x none
    event gen .b.f <Circulate> -place PlaceOnBottom -window .b.f
    set x
} PlaceOnBottom
test bind-16.26 {ExpandPercents procedure} {
    setup
    bind .b.f <1> {set x "%s"}
    set x none
    event gen .b.f <Button-1> -state 1402
    event gen .b.f <ButtonRelease-1>
    set x
} 1402
test bind-16.27 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%s"}
    set x none
    event gen .b.f <Enter> -state 0x3ff
    set x
} 1023
test bind-16.28 {ExpandPercents procedure} {
    setup
    bind .b.f <Visibility> {set x "%s"}
    set x none
    event gen .b.f <Visibility> -state VisibilityPartiallyObscured
    set x
} VisibilityPartiallyObscured
test bind-16.29 {ExpandPercents procedure} {
    setup
    bind .b.f <Visibility> {set x "%s"}
    set x none
    event gen .b.f <Visibility> -state VisibilityUnobscured
    set x
} VisibilityUnobscured
test bind-16.30 {ExpandPercents procedure} {
    setup
    bind .b.f <Visibility> {set x "%s"}
    set x none
    event gen .b.f <Visibility> -state VisibilityFullyObscured
    set x
} VisibilityFullyObscured
test bind-16.31 {ExpandPercents procedure} {
    setup
    bind .b.f <Button> {set x "%t"}
    set x none
    event gen .b.f <Button> -time 4294
    event gen .b.f <ButtonRelease>
    set x
} 4294
test bind-16.32 {ExpandPercents procedure} {
    setup
    bind .b.f <Button> {set x "%x %y"}
    set x none
    event gen .b.f <Button> -x 881 -y 432
    event gen .b.f <ButtonRelease>
    set x
} {881 432}
test bind-16.33 {ExpandPercents procedure} {
    setup
    bind .b.f <Reparent> {set x "%x %y"}
    set x none
    event gen .b.f <Reparent> -x 882 -y 431 -window .b.f
    set x
} {882 431}
test bind-16.34 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%x %y"}
    set x none
    event gen .b.f <Enter> -x 781 -y 632
    set x
} {781 632}
test bind-16.35 {ExpandPercents procedure} {nonPortable} {
    setup
    bind .b.f <Key> {lappend x "%A"}
    set x {}
    event gen .b.f <Key-a>
    event gen .b.f <Key-A> -state 1
    event gen .b.f <Key-Tab>
    event gen .b.f <Key-Return>
    event gen .b.f <Key-F1>
    event gen .b.f <Key-Shift_L>
    event gen .b.f <Key-space>
    event gen .b.f <Key-dollar> -state 1
    event gen .b.f <Key-braceleft> -state 1
    event gen .b.f <Key-Multi_key>
    event gen .b.f <Key-e>
    event gen .b.f <Key-apostrophe>
    set x
} "a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \u00e9"
test bind-16.36 {ExpandPercents procedure} {
    setup
    bind .b.f <Configure> {set x "%B"}
    set x none
    event gen .b.f <Configure> -borderwidth 24 -window .b.f
    set x
} 24
test bind-16.37 {ExpandPercents procedure} {
    setup
    bind .b.f <Enter> {set x "%E"}
    set x none
    event gen .b.f <Enter> -sendevent 1
    set x
} 1
test bind-16.38 {ExpandPercents procedure} {nonPortable} {
    setup
    bind .b.f <Key> {lappend x %K}
    set x {}
    event gen .b.f <Key-a>
    event gen .b.f <Key-A> -state 1
    event gen .b.f <Key-Tab>
    event gen .b.f <Key-F1>
    event gen .b.f <Key-Shift_L>
    event gen .b.f <Key-space>
    event gen .b.f <Key-dollar> -state 1
    event gen .b.f <Key-braceleft> -state 1
    set x
} {a A Tab F1 Shift_L space dollar braceleft}
test bind-16.39 {ExpandPercents procedure} {
    setup
    bind .b.f <Key> {set x "%N"}
    set x none
    event gen .b.f <Key-a>
    set x
} 97
test bind-16.40 {ExpandPercents procedure} {
    setup
    bind .b.f <Key> {set x "%S"}
    set x none
    event gen .b.f <Key-a> -subwindow .b
    set x
} [winfo id .b]
test bind-16.41 {ExpandPercents procedure} {
    setup
    bind .b.f <Key> {set x "%T"}
    set x none
    event gen .b.f <Key>
    set x
} 2
test bind-16.42 {ExpandPercents procedure} {
    setup
    bind .b.f <Key> {set x "%W"}
    set x none
    event gen .b.f <Key>
    set x
} .b.f
test bind-16.43 {ExpandPercents procedure} {
    setup
    bind .b.f <Button> {set x "%X %Y"}
    set x none
    event gen .b.f <Button> -rootx 422 -rooty 13
    event gen .b.f <ButtonRelease>
    set x
} {422 13}
test bind-16.44 {ExpandPercents procedure} {
    setup
    bind .b.f <Gravity> {set x "%R %S"}
    set x none
    event gen .b.f <Gravity>
    set x
} {?? ??}
test bind-16.45 {ExpandPercents procedure} -setup {
    set savedBind(Entry) [bind Entry <Key>]
    set savedBind(All) [bind all <Key>]

    setup2

    bind .b.e <Key> {set x "%M"}
    bind Entry <Key> {set y "%M"}
    bind all <Key> {set z "%M"}
} -body {
    set x none; set y none; set z none
    event gen .b.e <Key-a>
    list $x $y $z
} -cleanup {
    bind all <Key> $savedBind(All)
    bind Entry <Key> $savedBind(Entry)
    unset savedBind
} -result {0 1 2}
test bind-16.46 {ExpandPercents procedure} -setup {
    set savedBind(Entry) [bind Entry <Key>]
    set savedBind(All) [bind all <Key>]

    setup2

    bind all <Key> {set z "%M"}
    bind Entry <Key> {set y "%M"}
    bind .b.e <Key> {set x "%M"}
} -body {
    set x none; set y none; set z none
    event gen .b.e <Key-a>
    list $x $y $z
} -cleanup {
    bind Entry <Key> $savedBind(Entry)
    bind all <Key> $savedBind(All)
    unset savedBind
} -result {0 1 2}


test bind-17.1 {event command} {
    list [catch {event} msg] $msg
} {1 {wrong # args: should be "event option ?arg?"}}
test bind-17.2 {event command} {
    list [catch {event xyz} msg] $msg
} {1 {bad option "xyz": must be add, delete, generate, or info}}
test bind-17.3 {event command: add} {
    list [catch {event add} msg] $msg
} {1 {wrong # args: should be "event add virtual sequence ?sequence ...?"}}
test bind-17.4 {event command: add 1} {
    setup
    event add <<Paste>> <Control-v>
    event info <<Paste>>
} {<Control-Key-v>}
test bind-17.5 {event command: add 2} {
    setup
    event add <<Paste>> <Control-v> <Button-2>
    lsort [event info <<Paste>>]
} {<Button-2> <Control-Key-v>}
test bind-17.6 {event command: add with error} {
    setup
    list [catch {event add <<Paste>> <Control-v> <Button-2> abc <xyz> <1>} \
	    msg] $msg [lsort [event info <<Paste>>]]
} {1 {bad event type or keysym "xyz"} {<Button-2> <Control-Key-v> abc}}
test bind-17.7 {event command: delete} {
    list [catch {event delete} msg] $msg
} {1 {wrong # args: should be "event delete virtual ?sequence sequence ...?"}}
test bind-17.8 {event command: delete many} {
    setup
    event add <<Paste>> <3> <1> <2> t
    event delete <<Paste>> <1> <2>
    lsort [event info <<Paste>>]
} {<Button-3> t}
test bind-17.9 {event command: delete all} {
    setup
    event add <<Paste>> a b
    event delete <<Paste>>
    event info <<Paste>>
} {}
test bind-17.10 {event command: delete 1} {
    setup
    event add <<Paste>> a b c
    event delete <<Paste>> b
    lsort [event info <<Paste>>]
} {a c}
test bind-17.11 {event command: info name} {
    setup
    event add <<Paste>> a b c
    lsort [event info <<Paste>>]
} {a b c}
test bind-17.12 {event command: info all} {
    setup
    event add <<Paste>> a
    event add <<Alive>> b
    lsort [event info]
} {<<Alive>> <<Paste>>}
test bind-17.13 {event command: info error} {
    list [catch {event info <<Paste>> <Control-v>} msg] $msg
} {1 {wrong # args: should be "event info ?virtual?"}}
test bind-17.14 {event command: generate} {
    list [catch {event generate} msg] $msg
} {1 {wrong # args: should be "event generate window event ?options?"}}
test bind-17.15 {event command: generate} {
    setup
    bind .b.f <1> "lappend x 1"
    set x {}
    event generate .b.f <1>
    set x
} {1}
test bind-17.16 {event command: generate} {
    list [catch {event generate .b.f <xyz>} msg] $msg
} {1 {bad event type or keysym "xyz"}}
test bind-17.17 {event command} {
    list [catch {event foo} msg] $msg
} {1 {bad option "foo": must be add, delete, generate, or info}}

test bind-18.1 {CreateVirtualEvent procedure: GetVirtualEventUid} {
    list [catch {event add asd <Ctrl-v>} msg] $msg
} {1 {virtual event "asd" is badly formed}}
test bind-18.2 {CreateVirtualEvent procedure: FindSequence} {
    list [catch {event add <<asd>> <Ctrl-v>} msg] $msg
} {1 {bad event type or keysym "Ctrl"}}
test bind-18.3 {CreateVirtualEvent procedure: new physical} {
    setup
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} {<Control-Key-v>}
test bind-18.4 {CreateVirtualEvent procedure: duplicate physical} {
    setup
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} {<Control-Key-v>}
test bind-18.5 {CreateVirtualEvent procedure: existing physical} {
    setup
    event add <<xyz>> <Control-v>
    event add <<abc>> <Control-v>
    list [lsort [event info]] [event info <<xyz>>] [event info <<abc>>]
} {{<<abc>> <<xyz>>} <Control-Key-v> <Control-Key-v>}
test bind-18.6 {CreateVirtualEvent procedure: new virtual} {
    setup
    event add <<xyz>> <Control-v>
    list [event info] [event info <<xyz>>]
} {<<xyz>> <Control-Key-v>}
test bind-18.7 {CreateVirtualEvent procedure: existing virtual} {
    setup
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    list [event info] [lsort [event info <<xyz>>]]
} {<<xyz>> {<Button-2> <Control-Key-v>}}


test bind-19.1 {DeleteVirtualEvent procedure: GetVirtualEventUid} {
    list [catch {event add xyz {}} msg] $msg
} {1 {virtual event "xyz" is badly formed}}
test bind-19.2 {DeleteVirtualEvent procedure: non-existent virtual} {
    setup
    event delete <<xyz>>
    event info
} {}
test bind-19.3 {DeleteVirtualEvent procedure: delete 1} {
    setup
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Control-v>
    event info <<xyz>>
} {}
test bind-19.4 {DeleteVirtualEvent procedure: delete 1, not owned} {
    setup
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Button-1>
    event info <<xyz>>
} {<Control-Key-v>}
test bind-19.5 {DeleteVirtualEvent procedure: delete 1, badly formed} {
    setup
    event add <<xyz>> <Control-v>
    list [catch {event delete <<xyz>> <xyz>} msg] $msg
} {1 {bad event type or keysym "xyz"}}
test bind-19.6 {DeleteVirtualEvent procedure: delete 1, badly formed} {
    setup
    event add <<xyz>> <Control-v>
    list [catch {event delete <<xyz>> <<Paste>>} msg] $msg
} {1 {virtual event not allowed in definition of another virtual event}}
test bind-19.7 {DeleteVirtualEvent procedure: owns 1, delete all} {
    setup
    event add <<xyz>> <Control-v>
    event delete <<xyz>>
    event info
} {}
test bind-19.8 {DeleteVirtualEvent procedure: owns 1, delete 1} {
    setup
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Control-v>
    event info
} {}
test bind-19.9 {DeleteVirtualEvent procedure: owns many, delete all} {
    setup
    event add <<xyz>> <Control-v> <Control-w> <Control-x>
    event delete <<xyz>>
    event info
} {}
test bind-19.10 {DeleteVirtualEvent procedure: owns many, delete 1} {
    setup
    event add <<xyz>> <Control-v> <Control-w> <Control-x>
    event delete <<xyz>> <Control-w>
    lsort [event info <<xyz>>]
} {<Control-Key-v> <Control-Key-x>}
test bind-19.11 {DeleteVirtualEvent procedure: owned by 1, only} {
    setup
    event add <<xyz>> <Button-2>
    bind .b.f <<xyz>> {lappend x %#}
    set x {}
    event gen .b.f <Button-2> -serial 101
    event gen .b.f <ButtonRelease-2>
    event delete <<xyz>>
    event gen .b.f <Button-2> -serial 102
    event gen .b.f <ButtonRelease-2>
    set x
} {101}
test bind-19.12 {DeleteVirtualEvent procedure: owned by 1, first in chain} {
    setup
    event add <<abc>> <Control-Button-2>
    event add <<xyz>> <Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.f <<abc>> {lappend x abc}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Control-ButtonRelease-2>
    event delete <<xyz>>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Control-ButtonRelease-2>
    list $x [event info <<abc>>]
} {{xyz abc abc} <Control-Button-2>}
test bind-19.13 {DeleteVirtualEvent procedure: owned by 1, second in chain} {
    setup
    event add <<def>> <Shift-Button-2>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.f <<abc>> {lappend x abc}
    bind .b.f <<def>> {lappend x def}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Control-ButtonRelease-2>
    event gen .b.f <Shift-Button-2>
    event gen .b.f <Shift-ButtonRelease-2>
    event delete <<xyz>>
    event gen .b.f <Button-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Shift-Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-ButtonRelease-2>
    event gen .b.f <Shift-ButtonRelease-2>
    list $x [event info <<def>>] [event info <<xyz>>] [event info <<abc>>]
} {{xyz abc def abc def} <Shift-Button-2> {} <Control-Button-2>}
test bind-19.14 {DeleteVirtualEvent procedure: owned by 1, last in chain} {
    setup
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-Button-2>
    event add <<def>> <Shift-Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.f <<abc>> {lappend x abc}
    bind .b.f <<def>> {lappend x def}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Control-ButtonRelease-2>
    event gen .b.f <Shift-Button-2>
    event gen .b.f <Shift-ButtonRelease-2>
    event delete <<xyz>>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Control-Button-2>
    event gen .b.f <Control-ButtonRelease-2>
    event gen .b.f <Shift-Button-2>
    event gen .b.f <Shift-ButtonRelease-2>
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} {{xyz abc def abc def} {} <Control-Button-2> <Shift-Button-2>}
test bind-19.15 {DeleteVirtualEvent procedure: owned by many, first} {
    setup
    pack [frame .b.g -class Test -width 150 -height 100]
    pack [frame .b.h -class Test -width 150 -height 100]
    update
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.g <<abc>> {lappend x abc}
    bind .b.h <<def>> {lappend x def}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    event delete <<xyz>>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    destroy .b.g
    destroy .b.h
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} {{xyz abc def abc def} {} <Button-2> <Button-2>}
test bind-19.16 {DeleteVirtualEvent procedure: owned by many, middle} {
    setup
    pack [frame .b.g -class Test -width 150 -height 100]
    pack [frame .b.h -class Test -width 150 -height 100]
    update
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.g <<abc>> {lappend x abc}
    bind .b.h <<def>> {lappend x def}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    event delete <<abc>>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    destroy .b.g
    destroy .b.h
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} {{xyz abc def xyz def} <Button-2> {} <Button-2>}
test bind-19.17 {DeleteVirtualEvent procedure: owned by many, last} {
    setup
    pack [frame .b.g -class Test -width 150 -height 100]
    pack [frame .b.h -class Test -width 150 -height 100]
    update
    event add <<xyz>> <Button-2>
    event add <<abc>> <Button-2>
    event add <<def>> <Button-2>
    bind .b.f <<xyz>> {lappend x xyz}
    bind .b.g <<abc>> {lappend x abc}
    bind .b.h <<def>> {lappend x def}
    set x {}
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    event delete <<def>>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.g <Button-2>
    event gen .b.g <ButtonRelease-2>
    event gen .b.h <Button-2>
    event gen .b.h <ButtonRelease-2>
    destroy .b.g
    destroy .b.h
    list $x [event info <<xyz>>] [event info <<abc>>] [event info <<def>>]
} {{xyz abc def xyz abc} <Button-2> <Button-2> {}}


test bind-20.1 {GetVirtualEvent procedure: GetVirtualEventUid} {
    list [catch {event info asd} msg] $msg
} {1 {virtual event "asd" is badly formed}}
test bind-20.2 {GetVirtualEvent procedure: non-existent event} {
    event info <<asd>>
} {}
test bind-20.3 {GetVirtualEvent procedure: owns 1} {
    setup
    event add <<xyz>> <Control-Key-v>
    event info <<xyz>>
} {<Control-Key-v>}
test bind-20.4 {GetVirtualEvent procedure: owns many} {
    setup
    event add <<xyz>> <Control-v> <Button-2> spack
    event info <<xyz>>
} {<Control-Key-v> <Button-2> spack}


test bind-21.1 {GetAllVirtualEvents procedure: no events} {
    setup
    event info
} {}
test bind-21.2 {GetAllVirtualEvents procedure: 1 event} {
    setup
    event add <<xyz>> <Control-v>
    event info
} {<<xyz>>}
test bind-21.3 {GetAllVirtualEvents procedure: many events} {
    setup
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-v>
    event add <<def>> <Key-F6>
    lsort [event info]
} {<<abc>> <<def>> <<xyz>>}

test bind-22.1 {HandleEventGenerate} {
    list [catch {event gen .xyz <Control-v>} msg] $msg
} {1 {bad window path name ".xyz"}}
test bind-22.2 {HandleEventGenerate} {
    list [catch {event gen zzz <Control-v>} msg] $msg
} {1 {bad window name/identifier "zzz"}}
test bind-22.3 {HandleEventGenerate} {
    list [catch {event gen 47 <Control-v>} msg] $msg
} {1 {bad window name/identifier "47"}}
test bind-22.4 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {set x "%s %b"}
    set x {}
    event gen [winfo id .b.f] <Control-Button-1> -state 260
    set x
} {260 1}
test bind-22.5 {HandleEventGenerate} {
    list [catch {event gen . <xyz>} msg] $msg
} {1 {bad event type or keysym "xyz"}}
test bind-22.6 {HandleEventGenerate} {
    list [catch {event gen . <Double-Button-1>} msg] $msg
} {1 {Double or Triple modifier not allowed}}
test bind-22.7 {HandleEventGenerate} {
    list [catch {event gen . xyz} msg] $msg
} {1 {only one event specification allowed}}
test bind-22.8 {HandleEventGenerate} {
    list [catch {event gen . <Button> -button} msg] $msg
} {1 {value for "-button" missing}}
test bind-22.9 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {set x "%s %b"}
    set x {}
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <ButtonRelease-3>
    event gen .b.f <Control-Button-1>
    event gen .b.f <Control-ButtonRelease-1>
    set x
} {4 1}
test bind-22.10 {HandleEventGenerate} {
    setup
    bind .b.f <Key> {set x "%s %K"}
    set x {}
    event gen .b.f <Control-Key-space>
    set x
} {4 space}
test bind-22.11 {HandleEventGenerate} {
    setup
    bind .b.f <<Paste>> {set x "%s"}
    set x {}
    event gen .b.f <<Paste>> -state 1
    set x
} {1}
test bind-22.12 {HandleEventGenerate} {
    setup
    bind .b.f <Motion> {set x "%s"}
    set x {}
    event gen .b.f <Control-Motion>
    set x
} {4}
test bind-22.13 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {lappend x %#}
    set x {}
    event gen .b.f <Button> -when now -serial 100
    event gen .b.f <ButtonRelease> -when now
    set x
} {100}
test bind-22.14 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {lappend x %#}
    set x {}
    event gen .b.f <Button> -when head -serial 100
    event gen .b.f <Button> -when head -serial 101
    event gen .b.f <Button> -when head -serial 102
    event gen .b.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} {foo 102 101 100}
test bind-22.15 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {lappend x %#}
    set x {}
    event gen .b.f <Button> -when head -serial 99
    event gen .b.f <Button> -when mark -serial 100
    event gen .b.f <Button> -when mark -serial 101
    event gen .b.f <Button> -when mark -serial 102
    event gen .b.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} {foo 100 101 102 99}
test bind-22.16 {HandleEventGenerate} {
    setup
    bind .b.f <Button> {lappend x %#}
    set x {}
    event gen .b.f <Button> -when head -serial 99
    event gen .b.f <Button> -when tail -serial 100
    event gen .b.f <Button> -when tail -serial 101
    event gen .b.f <Button> -when tail -serial 102
    event gen .b.f <ButtonRelease> -when tail
    lappend x foo
    update
    set x
} {foo 99 100 101 102}
test bind-22.17 {HandleEventGenerate} {
    list [catch {event gen . <Button> -when xyz} msg] $msg
} {1 {bad -when value "xyz": must be now, head, mark, or tail}}
test bind-22.18 {HandleEventGenerate} {
    # Bug 411307
    list [catch {event gen . <a> -root 98765} msg] $msg
} {1 {bad window name/identifier "98765"}}
foreach check {
    {bind-22.19 <Configure> %a {-above .xyz} {{1 {bad window path name ".xyz"}}}}
    {bind-22.20 <Configure> %a {-above .b} {[winfo id .b]}}
    {bind-22.21 <Configure> %a {-above xyz} {{1 {bad window name/identifier "xyz"}}}}
    {bind-22.22 <Configure> %a {-above [winfo id .b]} {[winfo id .b]}}
    {bind-22.23 <Key> %b       {-above .} {{1 {<Key> event doesn't accept "-above" option}}}}

    {bind-22.24 <Configure> %B {-borderwidth xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.25 <Configure> %B {-borderwidth 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.26 <Key> %k       {-borderwidth 2i} {{1 {<Key> event doesn't accept "-borderwidth" option}}}}

    {bind-22.27 <Button> %b    {-button xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.28 <Button> %b    {-button 1} 1}
    {bind-22.29 <ButtonRelease> %b {-button 1} 1}
    {bind-22.30 <Key> %k       {-button 1} {{1 {<Key> event doesn't accept "-button" option}}}}

    {bind-22.31 <Expose> %c    {-count xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.32 <Expose> %c    {-count 20} 20}
    {bind-22.33 <Key> %b       {-count 20} {{1 {<Key> event doesn't accept "-count" option}}}}

    {bind-22.34 <Enter> %d     {-detail xyz} {{1 {bad -detail value "xyz": must be NotifyAncestor, NotifyVirtual, NotifyInferior, NotifyNonlinear, NotifyNonlinearVirtual, NotifyPointer, NotifyPointerRoot, or NotifyDetailNone}}}}
    {bind-22.35 <FocusIn> %d   {-detail NotifyVirtual} {{}}}
    {bind-22.36 <Enter> %d     {-detail NotifyVirtual} NotifyVirtual}
    {bind-22.37 <Key> %k       {-detail NotifyVirtual} {{1 {<Key> event doesn't accept "-detail" option}}}}

    {bind-22.38 <Enter> %f     {-focus xyz} {{1 {expected boolean value but got "xyz"}}}}
    {bind-22.39 <Enter> %f     {-focus 1} 1}
    {bind-22.40 <Key> %k       {-focus 1} {{1 {<Key> event doesn't accept "-focus" option}}}}

    {bind-22.41 <Expose> %h    {-height xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.42 <Expose> %h    {-height 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.43 <Configure> %h {-height 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.44 <Key> %k       {-height 2i} {{1 {<Key> event doesn't accept "-height" option}}}}

    {bind-22.45 <Key> %k       {-keycode xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.46 <Key> %k       {-keycode 20} 20}
    {bind-22.47 <Button> %b    {-keycode 20} {{1 {<Button> event doesn't accept "-keycode" option}}}}

    {bind-22.48 <Key> %K       {-keysym xyz} {{1 {unknown keysym "xyz"}}}}
    {bind-22.49 <Key> %K       {-keysym a} a}
    {bind-22.50 <Button> %b    {-keysym a} {{1 {<Button> event doesn't accept "-keysym" option}}}}

    {bind-22.51 <Enter> %m     {-mode xyz} {{1 {bad -mode value "xyz": must be NotifyNormal, NotifyGrab, NotifyUngrab, or NotifyWhileGrabbed}}}}
    {bind-22.52 <Enter> %m     {-mode NotifyNormal} NotifyNormal}
    {bind-22.53 <FocusIn> %m   {-mode NotifyNormal} {{}}}
    {bind-22.54 <Key> %k       {-mode NotifyNormal} {{1 {<Key> event doesn't accept "-mode" option}}}}

    {bind-22.55 <Map> %o       {-override xyz} {{1 {expected boolean value but got "xyz"}}}}
    {bind-22.56 <Map> %o       {-override 1} 1}
    {bind-22.57 <Reparent> %o  {-override 1} 1}
    {bind-22.58 <Configure> %o {-override 1} 1}
    {bind-22.59 <Key> %k       {-override 1} {{1 {<Key> event doesn't accept "-override" option}}}}

    {bind-22.60 <Circulate> %p {-place xyz} {{1 {bad -place value "xyz": must be PlaceOnTop, or PlaceOnBottom}}}}
    {bind-22.61 <Circulate> %p {-place PlaceOnTop} PlaceOnTop}
    {bind-22.62 <Key> %k       {-place PlaceOnTop} {{1 {<Key> event doesn't accept "-place" option}}}}

    {bind-22.63 <Key> %R       {-root .xyz} {{1 {bad window path name ".xyz"}}}}
    {bind-22.64 <Key> %R       {-root .b} {[winfo id .b]}}
    {bind-22.65 <Key> %R       {-root xyz} {{1 {bad window name/identifier "xyz"}}}}
    {bind-22.66 <Key> %R       {-root [winfo id .b]} {[winfo id .b]}}
    {bind-22.67 <Button> %R    {-root .b} {[winfo id .b]}}
    {bind-22.68 <ButtonRelease> %R {-root .b} {[winfo id .b]}}
    {bind-22.69 <Motion> %R    {-root .b} {[winfo id .b]}}
    {bind-22.70 <<Paste>> %R   {-root .b} {[winfo id .b]}}
    {bind-22.71 <Enter> %R     {-root .b} {[winfo id .b]}}
    {bind-22.72 <Configure> %R {-root .b} {{1 {<Configure> event doesn't accept "-root" option}}}}

    {bind-22.73 <Key> %X       {-rootx xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.74 <Key> %X       {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.75 <Button> %X    {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.76 <ButtonRelease> %X {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.77 <Motion> %X    {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.78 <<Paste>> %X   {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.79 <Enter> %X     {-rootx 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.80 <Configure> %X {-rootx 2i} {{1 {<Configure> event doesn't accept "-rootx" option}}}}

    {bind-22.81 <Key> %Y       {-rooty xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.82 <Key> %Y       {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.83 <Button> %Y    {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.84 <ButtonRelease> %Y {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.85 <Motion> %Y    {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.86 <<Paste>> %Y   {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.87 <Enter> %Y     {-rooty 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.88 <Configure> %Y {-rooty 2i} {{1 {<Configure> event doesn't accept "-rooty" option}}}}

    {bind-22.89 <Key> %E       {-sendevent xyz} {{1 {expected boolean value but got "xyz"}}}}
    {bind-22.90 <Key> %E       {-sendevent 1} 1}
    {bind-22.91 <Key> %E       {-sendevent yes} 1}
    {bind-22.92 <Key> %E       {-sendevent 43} 43}

    {bind-22.93 <Key> %#       {-serial xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.94 <Key> %#       {-serial 100} 100}

    {bind-22.95 <Key> %s       {-state xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.96 <Key> %s       {-state 1} 1}
    {bind-22.97 <Button> %s    {-state 1025} 1025}
    {bind-22.98 <ButtonRelease> %s {-state 1025} 1025}
    {bind-22.99 <Motion> %s    {-state 1} 1}
    {bind-22.100 <<Paste>> %s  {-state 1} 1}
    {bind-22.101 <Enter> %s    {-state 1} 1}
    {bind-22.102 <Visibility> %s {-state xyz} {{1 {bad -state value "xyz": must be VisibilityUnobscured, VisibilityPartiallyObscured, or VisibilityFullyObscured}}}}
    {bind-22.103 <Visibility> %s {-state VisibilityUnobscured} VisibilityUnobscured}
    {bind-22.104 <Configure> %s {-state xyz} {{1 {<Configure> event doesn't accept "-state" option}}}}

    {bind-22.105 <Key> %S      {-subwindow .xyz} {{1 {bad window path name ".xyz"}}}}
    {bind-22.106 <Key> %S      {-subwindow .b} {[winfo id .b]}}
    {bind-22.107 <Key> %S      {-subwindow xyz} {{1 {bad window name/identifier "xyz"}}}}
    {bind-22.108 <Key> %S      {-subwindow [winfo id .b]} {[winfo id .b]}}
    {bind-22.109 <Button> %S   {-subwindow .b} {[winfo id .b]}}
    {bind-22.110 <ButtonRelease> %S {-subwindow .b} {[winfo id .b]}}
    {bind-22.111 <Motion> %S   {-subwindow .b} {[winfo id .b]}}
    {bind-22.112 <<Paste>> %S  {-subwindow .b} {[winfo id .b]}}
    {bind-22.113 <Enter> %S    {-subwindow .b} {[winfo id .b]}}
    {bind-22.114 <Configure> %S {-subwindow .b} {{1 {<Configure> event doesn't accept "-subwindow" option}}}}

    {bind-22.115 <Key> %t      {-time xyz} {{1 {expected integer but got "xyz"}}}}
    {bind-22.116 <Key> %t      {-time 100} 100}
    {bind-22.117 <Button> %t   {-time 100} 100}
    {bind-22.118 <ButtonRelease> %t {-time 100} 100}
    {bind-22.119 <Motion> %t   {-time 100} 100}
    {bind-22.120 <<Paste>> %t  {-time 100} 100}
    {bind-22.121 <Enter> %t    {-time 100} 100}
    {bind-22.122 <Property> %t {-time 100} 100}
    {bind-22.123 <Configure> %t {-time 100} {{1 {<Configure> event doesn't accept "-time" option}}}}

    {bind-22.124 <Expose> %w   {-width xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.125 <Expose> %w   {-width 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.126 <Configure> %w {-width 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.127 <Key> %k      {-width 2i} {{1 {<Key> event doesn't accept "-width" option}}}}

    {bind-22.128 <Unmap> %W    {-window .xyz} {{1 {bad window path name ".xyz"}}}}
    {bind-22.129 <Unmap> %W    {-window .b.f} .b.f}
    {bind-22.130 <Unmap> %W    {-window xyz} {{1 {bad window name/identifier "xyz"}}}}
    {bind-22.131 <Unmap> %W    {-window [winfo id .b.f]} .b.f}
    {bind-22.132 <Unmap> %W    {-window .b.f} .b.f}
    {bind-22.133 <Map> %W      {-window .b.f} .b.f}
    {bind-22.134 <Reparent> %W {-window .b.f} .b.f}
    {bind-22.135 <Configure> %W {-window .b.f} .b.f}
    {bind-22.136 <Gravity> %W  {-window .b.f} .b.f}
    {bind-22.137 <Circulate> %W {-window .b.f} .b.f}
    {bind-22.138 <Key> %W      {-window .b.f} {{1 {<Key> event doesn't accept "-window" option}}}}

    {bind-22.139 <Key> %x      {-x xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.140 <Key> %x      {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.141 <Button> %x   {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.142 <ButtonRelease> %x {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.143 <Motion> %x   {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.144 <<Paste>> %x  {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.145 <Enter> %x    {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.146 <Expose> %x   {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.147 <Configure> %x {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.148 <Gravity> %x  {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.149 <Reparent> %x {-x 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.150 <Map> %x      {-x 2i} {{1 {<Map> event doesn't accept "-x" option}}}}

    {bind-22.151 <Key> %y      {-y xyz} {{1 {bad screen distance "xyz"}}}}
    {bind-22.152 <Key> %y      {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.153 <Button> %y   {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.154 <ButtonRelease> %y {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.155 <Motion> %y   {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.156 <<Paste>> %y  {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.157 <Enter> %y    {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.158 <Expose> %y   {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.159 <Configure> %y {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.160 <Gravity> %y  {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.161 <Reparent> %y {-y 2i} {[winfo pixels .b.f 2i]}}
    {bind-22.162 <Map> %y      {-y 2i} {{1 {<Map> event doesn't accept "-y" option}}}}

    {bind-22.163 <Key> %k      {-xyz 1} {{1 {bad option "-xyz": must be -when, -above, -borderwidth, -button, -count, -data, -delta, -detail, -focus, -height, -keycode, -keysym, -mode, -override, -place, -root, -rootx, -rooty, -sendevent, -serial, -state, -subwindow, -time, -warp, -width, -window, -x, or -y}}}}
} {
    lassign $check name event substitution generator result
    test $name "HandleEventGenerate: options $event $generator" {
	setup
	bind .b.f $event "lappend x $substitution"
	set x {}
	if [catch {eval event gen .b.f $event $generator} msg] {
	    set x [list 1 $msg]
	}
	set x
    } [eval set x $result]
}
# Note that the -data option is tested in bind-32.* because it has
# more demanding requirements in memory handling

test bind-23.1 {GetVirtualEventUid procedure} {
    list [catch {event info <<asd} msg] $msg
} {1 {virtual event "<<asd" is badly formed}}
test bind-23.2 {GetVirtualEventUid procedure} {
    list [catch {event info <<>>} msg] $msg
} {1 {virtual event "<<>>" is badly formed}}
test bind-23.3 {GetVirtualEventUid procedure} {
    list [catch {event info <<asd>} msg] $msg
} {1 {virtual event "<<asd>" is badly formed}}
test bind-23.4 {GetVirtualEventUid procedure} {
    event info <<asd>>
} {}


test bind-24.1 {FindSequence procedure: no event} {
    list [catch {bind .b {} test} msg] $msg
} {1 {no events specified in binding}}
test bind-24.2 {FindSequence procedure: bad event} {
    list [catch {bind .b <xyz> test} msg] $msg
} {1 {bad event type or keysym "xyz"}}
test bind-24.3 {FindSequence procedure: virtual allowed} {
    bind .b.f <<Paste>> test
} {}
test bind-24.4 {FindSequence procedure: virtual not allowed} {
   list [catch {event add <<Paste>> <<Alive>>} msg] $msg
} {1 {virtual event not allowed in definition of another virtual event}}
test bind-24.5 {FindSequence procedure, multiple bindings} {
    setup
    bind .b.f <1> {lappend x single}
    bind .b.f <Double-1> {lappend x double}
    bind .b.f <Triple-1> {lappend x triple}
    bind .b.f <Quadruple-1> {lappend x quadruple}
    set x press
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    lappend x press
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    lappend x press
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    lappend x press
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    lappend x press
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    set x
} {press single press double press triple press quadruple press quadruple}
test bind-24.6 {FindSequence procedure: virtual composed} {
    list [catch {bind .b <Control-b><<Paste>> "puts hi"} msg] $msg
} {1 {virtual events may not be composed}}
test bind-24.7 {FindSequence procedure: new pattern sequence} {
    setup
    bind .b.f <Button-1><Button-2> {lappend x 1-2}
    set x {}
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    set x
} {1-2}
test bind-24.8 {FindSequence procedure: similar pattern sequence} {
    setup
    bind .b.f <Button-1><Button-2> {lappend x 1-2}
    bind .b.f <Button-2> {lappend x 2}
    set x {}
    event gen .b.f <Button-3>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    set x
} {2 1-2}
test bind-24.9 {FindSequence procedure: similar pattern sequence} {
    setup
    bind .b.f <Button-1><Button-2> {lappend x 1-2}
    bind .b.f <Button-2><Button-2> {lappend x 2-2}
    set x {}
    event gen .b.f <Button-3>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    set x
} {2-2 1-2}
test bind-24.10 {FindSequence procedure: similar pattern sequence} {
    setup
    bind .b.f <Button-2><Button-2> {lappend x 2-2}
    bind .b.f <Double-Button-2> {lappend x d-2}
    set x {}
    event gen .b.f <Button-3>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-2>
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-1>
    event gen .b.f <ButtonRelease-1>
    event gen .b.f <Button-2> -x 100
    event gen .b.f <ButtonRelease-2>
    event gen .b.f <Button-2> -x 200
    event gen .b.f <ButtonRelease-2>
    set x
} {d-2 2-2}
test bind-24.11 {FindSequence procedure: new sequence, don't create} {
    setup
    bind .b.f <Button-2>
} {}
test bind-24.12 {FindSequence procedure: not new sequence, don't create} {
    setup
    bind .b.f <Control-Button-2> "foo"
    bind .b.f <Button-2>
} {}
test bind-24.13 {FindSequence procedure: no binding} {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
    list [catch {bind .b.f <a>} msg] $msg
} {0 {}}
test bind-24.14 {FindSequence procedure: no binding} {
    catch {destroy .b.f}
    canvas .b.f
    set i [.b.f create rect 10 10 100 100]
    list [catch {.b.f bind $i <a>} msg] $msg
} {0 {}}

test bind-25.1 {ParseEventDescription procedure} -setup {
    setup
} -body {
    bind .b.f a test
    bind .b.f a
} -result test
test bind-25.2 {ParseEventDescription procedure: misinterpreted modifier} -setup {
    button .x
} -body {
    bind .x <Control-M> a
    bind .x <M-M> b
    lsort [bind .x]
} -cleanup {
    destroy .x
} -result {<Control-Key-M> <Meta-Key-M>}
test bind-25.3 {ParseEventDescription procedure} -setup {
    catch {destroy .b.f}
    frame .b.f -class Test -width 150 -height 100
} -body {
    bind .b.f <a---> {nothing}
    bind .b.f
} -result a
test bind-25.4 {ParseEventDescription} -setup {
    setup
} -body {
    bind .b <<Shift-Paste>> {puts hi}
    bind .b
} -result {<<Shift-Paste>>}
# Assorted error cases in event sequence parsing
foreach {testname testinfo} {
    bind-25.5  {\x7        {bad ASCII character 0x7}}
    bind-25.6  {\x7f       {bad ASCII character 0x7f}}
    bind-25.7  {\x4        {bad ASCII character 0x4}}
    bind-25.8  {<<>>       {virtual event "<<>>" is badly formed}}
    bind-25.9  {<<Paste    {missing ">" in virtual binding}}
    bind-25.10 {<<Paste>   {missing ">" in virtual binding}}
    bind-25.11 {<<Paste>>h {virtual events may not be composed}}
    bind-25.12 {<>         "no event type or button # or keysym"}
    bind-25.13 {<a--       {missing ">" in binding}}
    bind-25.14 {<a-b>      {extra characters after detail in binding}}
    bind-25.15 {<<abc      {missing ">" in virtual binding}}
    bind-25.16 {<<abc>     {missing ">" in virtual binding}}
} {
    lassign $testinfo sequence errorMessage
    test $testname {ParseEventDescription procedure error cases} \
	-setup { setup } \
	-body [list bind .b $sequence {puts hi}] \
	-returnCodes error -result $errorMessage
}
test bind-25.17 {ParseEventDescription} -setup {
    setup
} -returnCodes error -body {
    event add <<xyz>> <<abc>>
} -result {virtual event not allowed in definition of another virtual event}
# Modifier canonicalization tests
foreach {name check} {
    bind-25.18 {{<Control- a>} <Control-Key-a>}
    bind-25.19 {<Shift-a>   <Shift-Key-a>}
    bind-25.20 {<Lock-a>    <Lock-Key-a>}
    bind-25.21 {<Meta---a>  <Meta-Key-a>}
    bind-25.22 {<M-a>       <Meta-Key-a>}
    bind-25.23 {<Alt-a>     <Alt-Key-a>}
    bind-25.24 {<B1-a>      <B1-Key-a>}
    bind-25.25 {<B2-a>      <B2-Key-a>}
    bind-25.26 {<B3-a>      <B3-Key-a>}
    bind-25.27 {<B4-a>      <B4-Key-a>}
    bind-25.28 {<B5-a>      <B5-Key-a>}
    bind-25.29 {<Button1-a> <B1-Key-a>}
    bind-25.30 {<Button2-a> <B2-Key-a>}
    bind-25.31 {<Button3-a> <B3-Key-a>}
    bind-25.32 {<Button4-a> <B4-Key-a>}
    bind-25.33 {<Button5-a> <B5-Key-a>}
    bind-25.34 {<M1-a>      <Mod1-Key-a>}
    bind-25.35 {<M2-a>      <Mod2-Key-a>}
    bind-25.36 {<M3-a>      <Mod3-Key-a>}
    bind-25.37 {<M4-a>      <Mod4-Key-a>}
    bind-25.38 {<M5-a>      <Mod5-Key-a>}
    bind-25.39 {<Mod1-a>    <Mod1-Key-a>}
    bind-25.40 {<Mod2-a>    <Mod2-Key-a>}
    bind-25.41 {<Mod3-a>    <Mod3-Key-a>}
    bind-25.42 {<Mod4-a>    <Mod4-Key-a>}
    bind-25.43 {<Mod5-a>    <Mod5-Key-a>}
    bind-25.44 {<Double-a>  <Double-Key-a>}
    bind-25.45 {<Triple-a>  <Triple-Key-a>}
    bind-25.46 {{<Double 1>} <Double-Button-1>}
    bind-25.47 {<Triple-1>  <Triple-Button-1>}
    bind-25.48 {{<M1-M2 M3-M4 B1-Control-a>}
	<Control-B1-Mod1-Mod2-Mod3-Mod4-Key-a>}
    bind-25.49 {<Extended-Return> <Extended-Key-Return>}
} {
    lassign $check shortBind longBind
    test $name {modifier names} -setup {
	catch {destroy .b.f}
	frame .b.f -class Test -width 150 -height 100
    } -body {
	bind .b.f $shortBind foo
	bind .b.f
    } -result $longBind -cleanup {
	bind .b.f [lindex $check 1] {}
    }
}

foreach event [bind Test] {
    bind Test $event {}
}
foreach event [bind all] {
    bind all $event {}
}
test bind-26.1 {event names} {
















    catch {destroy .b.f}

















































































































































    frame .b.f -class Test -width 150 -height 100











    bind .b.f <FocusIn> {nothing}





































































































































    bind .b.f

































} <FocusIn>













test bind-26.2 {event names} {







    catch {destroy .b.f}






















    frame .b.f -class Test -width 150 -height 100
    bind .b.f <FocusOut> {nothing}




    bind .b.f












































































} <FocusOut>











test bind-26.3 {event names} {


    setup





    bind .b.f <Destroy> {lappend x "destroyed"}
    set x [bind .b.f]







































































    destroy .b.f




























































































































































































    set x






} {<Destroy> destroyed}





















































































































































foreach check {





















    {bind-26.4  Motion     Motion}
    {bind-26.5  Button     Button}


























    {bind-26.6  ButtonPress   Button}














    {bind-26.7  ButtonRelease ButtonRelease}





































    {bind-26.8  Colormap   Colormap}

























    {bind-26.9  Enter      Enter}

    {bind-26.10 Leave      Leave}












    {bind-26.11 Expose     Expose}














    {bind-26.12 Key        Key}

































































    {bind-26.13 KeyPress   Key}





    {bind-26.14 KeyRelease KeyRelease}



















































    {bind-26.15 Property   Property}














    {bind-26.16 Visibility Visibility}




























    {bind-26.17 Activate   Activate}
















    {bind-26.18 Deactivate Deactivate}
} {






































































    lassign $check name event canonicalEvent






























































































    test $name "event names: $event" {












	setup







































































	bind .b.f <$event> "set x {event $event}"
















	set x xyzzy



































	event gen .b.f <$event>


















































	list $x [bind .b.f]

    } [list "event $event" <$canonicalEvent>]







}
# These events require an extra argument to [event generate]
foreach check {
    {bind-26.19 Circulate Circulate}

    {bind-26.20 Configure Configure}













































































    {bind-26.21 Gravity   Gravity}












    {bind-26.22 Map       Map}






































    {bind-26.23 Reparent  Reparent}






    {bind-26.24 Unmap     Unmap}




} {


    lassign $check name event canonicalEvent












    test $name "event names: $event" {













	setup








	bind .b.f <$event> "set x {event $event}"
















































































	set x xyzzy


























































































































	event gen .b.f <$event> -window .b.f






























































































































































	list $x [bind .b.f]



























    } [list "event $event" <$canonicalEvent>]























}










































































































































test bind-27.1 {button names} {







    list [catch {bind .b <Expose-1> foo} msg] $msg
} {1 {specified button "1" for non-button event}}

test bind-27.2 {button names} {










    list [catch {bind .b <Button-6> foo} msg] $msg


















} {1 {specified keysym "6" for non-key event}}

test bind-27.3 {button names} {


































    setup














    bind .b.f <Button-1> {lappend x "button 1"}




















    set x [bind .b.f]












































































































































































































    event gen .b.f <Button-1>

































































    event gen .b.f <ButtonRelease-1>




    set x

















































} {<Button-1> {button 1}}






test bind-27.4 {button names} {













    setup
















    bind .b.f <Button-2> {lappend x "button 2"}
























































































    set x [bind .b.f]







    event gen .b.f <Button-2>













    event gen .b.f <ButtonRelease-2>





    set x







} {<Button-2> {button 2}}












test bind-27.5 {button names} {














































    setup






    bind .b.f <Button-3> {lappend x "button 3"}





    set x [bind .b.f]






    event gen .b.f <Button-3>













    event gen .b.f <ButtonRelease-3>

























































































































































    set x







} {<Button-3> {button 3}}












test bind-27.6 {button names} {



































































































































































































































































    setup







    bind .b.f <Button-4> {lappend x "button 4"}





    set x [bind .b.f]






    event gen .b.f <Button-4>



































    event gen .b.f <ButtonRelease-4>











    set x







} {<Button-4> {button 4}}



























test bind-27.7 {button names} {





    setup






    bind .b.f <Button-5> {lappend x "button 5"}





    set x [bind .b.f]






























































    event gen .b.f <Button-5>













    event gen .b.f <ButtonRelease-5>





    set x







} {<Button-5> {button 5}}














































































































































































































































































































































































































































































































































































































test bind-28.1 {keysym names} {






    list [catch {bind .b <Expose-a> foo} msg] $msg




} {1 {specified keysym "a" for non-key event}}
test bind-28.2 {keysym names} {






    list [catch {bind .b <Gorp> foo} msg] $msg




} {1 {bad event type or keysym "Gorp"}}
test bind-28.3 {keysym names} {






    list [catch {bind .b <Key-Stupid> foo} msg] $msg
} {1 {bad event type or keysym "Stupid"}}

test bind-28.4 {keysym names} {
    catch {destroy .b.f}



    frame .b.f -class Test -width 150 -height 100
    bind .b.f <a> foo



















    bind .b.f




} a












foreach check {













    {bind-28.5 a      0 a}












    {bind-28.6 space  0 <Key-space>}













    {bind-28.7 Return 0 <Key-Return>}



























































































































    {bind-28.8 X      1 X}



















































































} {













    lassign $check name keysym state result













    test $name {keysym names} {





	setup







	bind .b.f <Key-$keysym> "lappend x \"keysym $keysym\""







	bind .b.f <Key-x> "lappend x {bad binding match}"










	set x [lsort [bind .b.f]]


































	event gen .b.f <Key-$keysym> -state $state





	set x







    } [concat [lsort "x $result"] "{keysym $keysym}"]













}










































































































































































































































































































test bind-29.1 {dummy test to help ensure proper numbering} {} {}



setup


bind .b.f <KeyPress> {set x %K}
foreach check {






    {bind-29.2 a     0 a}








    {bind-29.3 x     1 X}







    {bind-29.4 x     2 X}



    {bind-29.5 space 0 space}








































    {bind-29.6 F1    1 F1}
































































} {








    lassign $check name keysym state result








    test $name {GetKeySym procedure} nonPortable {








	set x nothing








	event gen .b.f <KeyPress> -keysym $keysym -state $state








	set x







    } $result
}
















































































































































































































































































































































proc bgerror msg {













    global x errorInfo







    set x [list $msg $errorInfo]





}













test bind-30.1 {Tcl_BackgroundError procedure} {




    setup








    bind .b.f <Button> {error "This is a test"}





















    set x none






















































































    event gen .b.f <Button>

















































    event gen .b.f <ButtonRelease>
































































    update





    set x








































































































































































} {{This is a test} {This is a test
    while executing
"error "This is a test""
    (command bound to event)}}

test bind-30.2 {Tcl_BackgroundError procedure} {
    proc do {} {
	event gen .b.f <Button>
	event gen .b.f <ButtonRelease>
    }







    setup

    bind .b.f <Button> {error Message2}
    set x none
    do
    update
    set x




} {Message2 {Message2
    while executing
"error Message2"
    (command bound to event)}}
rename bgerror {}

test bind-31.1 {MouseWheel events} {



    setup
    set x {}

    bind .b.f <MouseWheel> {set x Wheel}
    event gen .b.f <MouseWheel>
    set x


} {Wheel}
test bind-31.2 {MouseWheel events} {



    setup
    set x {}

    bind .b.f <MouseWheel> {set x %D}
    event gen .b.f <MouseWheel> -delta 120
    set x


} {120}
test bind-31.3 {MouseWheel events} {



    setup
    set x {}

    bind .b.f <MouseWheel> {set x "%D %x %y"}
    event gen .b.f <MouseWheel> -delta 240 -x 10 -y 30
    set x


} {240 10 30}






test bind-32.1 {virtual event user_data field - bad generation} {
    setup

    # Check no confusion, since Focus events use %d for something else
    list [catch {event gen .b.f <FocusIn> -data foo} msg] $msg


} {1 {<FocusIn> event doesn't accept "-data" option}}
test bind-32.2 {virtual event user_data field - NULL, synch} {



    setup
    set x {}

    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}
    event gen .b.f <<TestUserData>>
    set x


} {TestUserData >{}<}
test bind-32.3 {virtual event user_data field - shared, synch} {



    setup
    set x {}

    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}
    event gen .b.f <<TestUserData>> -data "foo bar"
    set x


} {TestUserData >foo bar<}
test bind-32.4 {virtual event user_data field - unshared, synch} {



    setup
    set x {}

    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}
    event gen .b.f <<TestUserData>> -data [string index abc 1]
    set x


} {TestUserData >b<}
# Note that asynch event handling can only really catch any potential
# extra errors when used in combination with a tool like Purify or
# Valgrind. Such testing is rarely done, but at least any problem with
# reference handling will eventually show up with these tests...
test bind-32.5 {virtual event user_data field - NULL, asynch} {



    setup
    set x {}

    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}
    event gen .b.f <<TestUserData>> -when head

































































































    list $x [update] $x
} {{} {} {TestUserData >{}<}}








































































































































































test bind-32.6 {virtual event user_data field - shared, asynch} {











    setup







    set x {}













    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}


















































































































    event gen .b.f <<TestUserData>> -data "foo bar" -when head








    list $x [update] $x
} {{} {} {TestUserData >foo bar<}}
















test bind-32.7 {virtual event user_data field - unshared, asynch} {









    setup











































































    set x {}
















    bind .b.f <<TestUserData>> {set x "TestUserData >%d<"}




    event gen .b.f <<TestUserData>> -data [string index abc 1] -when head











    list $x [update] $x











































} {{} {} {TestUserData >b<}}


















































































































































destroy .b























































































# cleanup
cleanupTests
return


# Local Variables:
# mode: tcl
# End:

Changes to tests/bitmap.test.

1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30

31
32

33
34
35
36
37
38
39
40
41
42
43
44

45

46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62

63
64
65
66
67
68
69
70

71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
# This file is a Tcl script to test out the procedures in the file
# tkBitmap.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands



test bitmap-1.1 {Tk_AllocBitmapFromObj - converting internal reps} -constraints {
    testbitmap
} -body {
    set x gray25
    lindex $x 0

    button .b -bitmap $x
    lindex $x 0
    testbitmap gray25
} -cleanup {
    destroy .b
} -result {{1 0}}
test bitmap-1.2 {Tk_AllocBitmapFromObj - discard stale bitmap} -constraints {
    testbitmap
} -setup {
    set result {}
} -body {
    set x gray25

    button .b1 -bitmap $x
    destroy .b1

    lappend result [testbitmap gray25]
    button .b2 -bitmap $x
    lappend result [testbitmap gray25]
} -cleanup {
    destroy .b1 .b2
} -result {{} {{1 1}}}
test bitmap-1.3 {Tk_AllocBitmapFromObj - reuse existing bitmap} -constraints {
    testbitmap
} -setup {
    set result {}
} -body {
    set x gray25

    button .b1 -bitmap $x

    lappend result [testbitmap gray25]
    button .b2 -bitmap $x
    pack .b1 .b2 -side top
    lappend result [testbitmap gray25]
} -cleanup {
    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}

test bitmap-2.1 {Tk_GetBitmap procedure} -body {
    button .b1 -bitmap bad_name
} -cleanup {
    destroy .b1

} -returnCodes error -result {bitmap "bad_name" not defined}
test bitmap-2.2 {Tk_GetBitmap procedure} -body {
    button .b1 -bitmap @xyzzy
} -cleanup {
    destroy .b1

} -returnCodes error -result {error reading bitmap file "xyzzy"}

test bitmap-3.1 {Tk_FreeBitmapFromObj - reference counts} -constraints {
    testbitmap
} -setup {
    set result {}
} -body {
    set x questhead

    button .b1 -bitmap $x
    button .b3 -bitmap $x
    button .b2 -bitmap $x

    lappend result [testbitmap questhead]
    destroy .b1
    lappend result [testbitmap questhead]
    destroy .b2
    lappend result [testbitmap questhead]
    destroy .b3
    lappend result [testbitmap questhead]
} -cleanup {
    destroy .b1 .b2 .b3     ;# destroying just in case
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test bitmap-4.1 {FreeBitmapObjProc} -constraints {
    testbitmap
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy questhead]
    button .b -bitmap $x
    set y [copy questhead]
    .b configure -bitmap $y
    set z [copy questhead]
    .b configure -bitmap $z
    set result {}
    lappend result [testbitmap questhead]
    set x red
    lappend result [testbitmap questhead]
    set z 32
    lappend result [testbitmap questhead]
    destroy .b
    lappend result [testbitmap questhead]
    set y bogus
    return $result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}



# cleanup
cleanupTests
return




|
|



<



>
>
|
<
<


>
|


<
<
|
|
<
<
<
<

>


>



<
<
|
|
<
<
<
<

>

>




<
<
|

|
<
<

>
|
|
<
<

>
|

|
<
<
<
<

>



>







<
<
|

|
|
<
<
<
|

|

|










|
<
<
<
|

>




1
2
3
4
5
6
7
8
9

10
11
12
13
14
15


16
17
18
19
20
21


22
23




24
25
26
27
28
29
30
31


32
33




34
35
36
37
38
39
40
41


42
43
44


45
46
47
48


49
50
51
52
53




54
55
56
57
58
59
60
61
62
63
64
65
66


67
68
69
70



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86



87
88
89
90
91
92
93
# This file is a Tcl script to test out the procedures in the file
# tkBitmap.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

test bitmap-1.1 {Tk_AllocBitmapFromObj - converting internal reps} testbitmap {


    set x gray25
    lindex $x 0
    destroy .b1
    button .b1 -bitmap $x
    lindex $x 0
    testbitmap gray25


} {{1 0}}
test bitmap-1.2 {Tk_AllocBitmapFromObj - discard stale bitmap} testbitmap {




    set x gray25
    destroy .b1 .b2
    button .b1 -bitmap $x
    destroy .b1
    set result {}
    lappend result [testbitmap gray25]
    button .b2 -bitmap $x
    lappend result [testbitmap gray25]


} {{} {{1 1}}}
test bitmap-1.3 {Tk_AllocBitmapFromObj - reuse existing bitmap} testbitmap {




    set x gray25
    destroy .b1 .b2
    button .b1 -bitmap $x
    set result {}
    lappend result [testbitmap gray25]
    button .b2 -bitmap $x
    pack .b1 .b2 -side top
    lappend result [testbitmap gray25]


} {{{1 1}} {{2 1}}}

test bitmap-2.1 {Tk_GetBitmap procedure} {


    destroy .b1
    list [catch {button .b1 -bitmap bad_name} msg] $msg
} {1 {bitmap "bad_name" not defined}}
test bitmap-2.2 {Tk_GetBitmap procedure} {


    destroy .b1
    list [catch {button .b1 -bitmap @xyzzy} msg] $msg
} {1 {error reading bitmap file "xyzzy"}}

test bitmap-3.1 {Tk_FreeBitmapFromObj - reference counts} testbitmap {




    set x questhead
    destroy .b1 .b2 .b3
    button .b1 -bitmap $x
    button .b3 -bitmap $x
    button .b2 -bitmap $x
    set result {}
    lappend result [testbitmap questhead]
    destroy .b1
    lappend result [testbitmap questhead]
    destroy .b2
    lappend result [testbitmap questhead]
    destroy .b3
    lappend result [testbitmap questhead]


} {{{3 1}} {{2 1}} {{1 1}} {}}

test bitmap-4.1 {FreeBitmapObjProc} {testbitmap failsOnUbuntu failsOnQuarz} {
    destroy .b



    set x [format questhead]
    button .b -bitmap $x
    set y [format questhead]
    .b configure -bitmap $y
    set z [format questhead]
    .b configure -bitmap $z
    set result {}
    lappend result [testbitmap questhead]
    set x red
    lappend result [testbitmap questhead]
    set z 32
    lappend result [testbitmap questhead]
    destroy .b
    lappend result [testbitmap questhead]
    set y bogus
    set result



} {{{1 3}} {{1 2}} {{1 1}} {}}

destroy .t

# cleanup
cleanupTests
return

Changes to tests/border.test.

1
2
3
4
5
6
7
8
9
10
11
12








13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29

30
31

32
33
34
35
36
37
38
39
40
41
42
43

44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195

196
197
198
199
200
201
202
# This file is a Tcl script to test out the procedures in the file
# tkBorder.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands









test border-1.1 {Tk_AllocBorderFromObj - converting internal reps} -constraints {
    testborder
} -body {
    set x orange
    lindex $x 0

    button .b1 -bg $x -text .b1
    lindex $x 0
    testborder orange
} -cleanup {
    destroy .b1
} -result {{1 0}}
test border-1.2 {Tk_AllocBorderFromObj - discard stale border} -constraints {
    testborder
} -setup {
    set result {}
} -body {
    set x orange

    button .b1 -bg $x -text First
    destroy .b1

    lappend result [testborder orange]
    button .b2 -bg $x -text Second
    lappend result [testborder orange]
} -cleanup {
    destroy .b1 .b2
} -result {{} {{1 1}}}
test border-1.3 {Tk_AllocBorderFromObj - reuse existing border} -constraints {
    testborder
} -setup {
    set result {}
} -body {
    set x orange

    button .b1 -bg $x -text First

    lappend result [testborder orange]
    button .b2 -bg $x -text Second
    pack .b1 .b2 -side top
    lappend result [testborder orange]
} -cleanup {
    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}
test border-1.4 {Tk_AllocBorderFromObj - try other borders in list} -constraints {
    testborder pseudocolor8
} -setup {
    toplevel .t -visual {pseudocolor 8} -colormap new
    wm geom .t +0+0
    set result {}
} -body {
    set x purple

    button .b1 -bg $x -text First
    pack .b1 -side top

    lappend result [testborder purple]
    button .t.b -bg $x -text Second
    pack .t.b -side top
    lappend result [testborder purple]
    button .b2 -bg $x -text Third
    pack .b2 -side top
    lappend result [testborder purple]
} -cleanup {
    destroy .b1 .b2 .t
} -result {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}

test border-2.1 {Tk_Free3DBorder - reference counts} -constraints {
    testborder pseudocolor8
} -setup {
    toplevel .t -visual {pseudocolor 8} -colormap new
    wm geom .t +0+0
    set result {}
} -body {
    set x purple

    button .b1 -bg $x -text First
    pack .b1 -side top
    button .t.b -bg $x -text Second
    pack .t.b -side top
    button .b2 -bg $x -text Third
    pack .b2 -side top

    lappend result [testborder purple]
    destroy .b1
    lappend result [testborder purple]
    destroy .b2
    lappend result [testborder purple]
    destroy .t.b
    lappend result [testborder purple]
} -cleanup {
    destroy .b1 .b2 .t
} -result {{{1 0} {2 1}} {{1 0} {1 1}} {{1 0}} {}}
test border-2.2 {Tk_Free3DBorder - unlinking from list} -constraints {
    testborder pseudocolor8
} -setup {
    toplevel .t -visual {pseudocolor 8} -colormap new
    wm geom .t +0+0
    toplevel .t2 -visual {pseudocolor 8} -colormap new
    toplevel .t3 -visual {pseudocolor 8} -colormap new
    set result {}
} -body {
    set x purple
    button .b -bg $x -text .b1
    button .t.b1 -bg $x -text .t.b1
    button .t.b2 -bg $x -text .t.b2
    button .t2.b1 -bg $x -text .t2.b1
    button .t2.b2 -bg $x -text .t2.b2
    button .t2.b3 -bg $x -text .t2.b3
    button .t3.b1 -bg $x -text .t3.b1
    button .t3.b2 -bg $x -text .t3.b2
    button .t3.b3 -bg $x -text .t3.b3
    button .t3.b4 -bg $x -text .t3.b4

    lappend result [testborder purple]
    destroy .t2
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    destroy .t3
    lappend result [testborder purple]
    destroy .t
    lappend result [testborder purple]
} -cleanup {
    destroy .b .t2 .t3 .t
} -result {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}


test border-3.1 {FreeBorderObjProc} -constraints {
    testborder
} -setup {
    set result {}
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy purple]
    button .b -bg $x -text .b1
    set y [copy purple]
    .b configure -bg $y
    set z [copy purple]
    .b configure -bg $z

    lappend result [testborder purple]
    set x red
    lappend result [testborder purple]
    set z 32
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    set y bogus
    return $result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}



test border-4.1 {Tk_GetReliefFromObj} -body {
    button .b -relief flat
    .b cget -relief
} -cleanup {
    destroy .b
} -result {flat}
test border-4.2 {Tk_GetReliefFromObj} -body {
    button .b -relief groove
    .b cget -relief
} -cleanup {
    destroy .b
} -result {groove}
test border-4.3 {Tk_GetReliefFromObj} -body {
    button .b -relief raised
    .b cget -relief
} -cleanup {
    destroy .b
} -result {raised}
test border-4.4 {Tk_GetReliefFromObj} -body {
    button .b -relief ridge
    .b cget -relief
} -cleanup {
    destroy .b
} -result {ridge}
test border-4.5 {Tk_GetReliefFromObj} -body {
    button .b -relief solid
    .b cget -relief
} -cleanup {
    destroy .b
} -result {solid}
test border-4.6 {Tk_GetReliefFromObj} -body {
    button .b -relief sunken
    .b cget -relief
} -cleanup {
    destroy .b
} -result {sunken}
test border-4.7 {Tk_GetReliefFromObj - error} -body {
    button .b -relief upanddown

} -cleanup {

    destroy .b
} -returnCodes error -result {bad relief "upanddown": must be flat, groove, raised, ridge, solid, or sunken}


# cleanup
cleanupTests
return



|
|



<



>
>
>
>
>
>
>
>
|
<
<


>



<
<
|
|
<
<
<
<

>


>



<
<
|
|
<
<
<
<

>

>




<
<
|
|
<
<
<
<
<
<

>


>







<
<
|

|
<
<
<
<
<
<

>






>







<
<
|
|
<
<
<
|


<
<











>









<
<
|

<
|
|
<
<
<
<
|

|

|

>








|
<
<
<
|

>
>
|
|

<
<
|
|
|

<
<
|
|
|

<
<
|
|
|

<
<
|
|
|

<
<
|
|
|

<
<
|
|
|
>
|
>
|
<
|




1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26


27
28




29
30
31
32
33
34
35
36


37
38




39
40
41
42
43
44
45
46


47
48






49
50
51
52
53
54
55
56
57
58
59
60


61
62
63






64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81



82
83
84


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107

108
109




110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125



126
127
128
129
130
131
132


133
134
135
136


137
138
139
140


141
142
143
144


145
146
147
148


149
150
151
152


153
154
155
156
157
158
159

160
161
162
163
164
# This file is a Tcl script to test out the procedures in the file
# tkBorder.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

if {[testConstraint pseudocolor8]} {
    toplevel .t -visual {pseudocolor 8} -colormap new
    wm geom .t +0+0
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

test border-1.1 {Tk_AllocBorderFromObj - converting internal reps} testborder {


    set x orange
    lindex $x 0
    destroy .b1
    button .b1 -bg $x -text .b1
    lindex $x 0
    testborder orange


} {{1 0}}
test border-1.3 {Tk_AllocBorderFromObj - discard stale border} testborder {




    set x orange
    destroy .b1 .b2
    button .b1 -bg $x -text First
    destroy .b1
    set result {}
    lappend result [testborder orange]
    button .b2 -bg $x -text Second
    lappend result [testborder orange]


} {{} {{1 1}}}
test border-1.2 {Tk_AllocBorderFromObj - reuse existing border} testborder {




    set x orange
    destroy .b1 .b2
    button .b1 -bg $x -text First
    set result {}
    lappend result [testborder orange]
    button .b2 -bg $x -text Second
    pack .b1 .b2 -side top
    lappend result [testborder orange]


} {{{1 1}} {{2 1}}}
test border-1.4 {Tk_AllocBorderFromObj - try other borders in list} {pseudocolor8 testborder} {






    set x purple
    destroy .b1 .b2 .t.b
    button .b1 -bg $x -text First
    pack .b1 -side top
    set result {}
    lappend result [testborder purple]
    button .t.b -bg $x -text Second
    pack .t.b -side top
    lappend result [testborder purple]
    button .b2 -bg $x -text Third
    pack .b2 -side top
    lappend result [testborder purple]


} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}

test border-3.1 {Tk_Free3DBorder - reference counts} {pseudocolor8 testborder} {






    set x purple
    destroy .b1 .b2 .t.b
    button .b1 -bg $x -text First
    pack .b1 -side top
    button .t.b -bg $x -text Second
    pack .t.b -side top
    button .b2 -bg $x -text Third
    pack .b2 -side top
    set result {}
    lappend result [testborder purple]
    destroy .b1
    lappend result [testborder purple]
    destroy .b2
    lappend result [testborder purple]
    destroy .t.b
    lappend result [testborder purple]


} {{{1 0} {2 1}} {{1 0} {1 1}} {{1 0}} {}}
test border-3.4 {Tk_Free3DBorder - unlinking from list} {pseudocolor8 testborder} {



    destroy .b .t.b .t2 .t3
    toplevel .t2 -visual {pseudocolor 8} -colormap new
    toplevel .t3 -visual {pseudocolor 8} -colormap new


    set x purple
    button .b -bg $x -text .b1
    button .t.b1 -bg $x -text .t.b1
    button .t.b2 -bg $x -text .t.b2
    button .t2.b1 -bg $x -text .t2.b1
    button .t2.b2 -bg $x -text .t2.b2
    button .t2.b3 -bg $x -text .t2.b3
    button .t3.b1 -bg $x -text .t3.b1
    button .t3.b2 -bg $x -text .t3.b2
    button .t3.b3 -bg $x -text .t3.b3
    button .t3.b4 -bg $x -text .t3.b4
    set result {}
    lappend result [testborder purple]
    destroy .t2
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    destroy .t3
    lappend result [testborder purple]
    destroy .t
    lappend result [testborder purple]


} {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}


test border-4.1 {FreeBorderObjProc} {testborder failsOnUbuntu failsOnQuarz} {
    destroy .b




    set x [format purple]
    button .b -bg $x -text .b1
    set y [format purple]
    .b configure -bg $y
    set z [format purple]
    .b configure -bg $z
    set result {}
    lappend result [testborder purple]
    set x red
    lappend result [testborder purple]
    set z 32
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    set y bogus
    set result



} {{{1 3}} {{1 2}} {{1 1}} {}}

catch {destroy .b}
button .b
test border-5.1 {Tk_GetReliefFromObj} {
    .b configure -relief flat
    .b cget -relief


} {flat}
test border-5.2 {Tk_GetReliefFromObj} {
    .b configure -relief groove
    .b cget -relief


} {groove}
test border-5.3 {Tk_GetReliefFromObj} {
    .b configure -relief raised
    .b cget -relief


} {raised}
test border-5.4 {Tk_GetReliefFromObj} {
    .b configure -relief ridge
    .b cget -relief


} {ridge}
test border-5.5 {Tk_GetReliefFromObj} {
    .b configure -relief solid
    .b cget -relief


} {solid}
test border-5.6 {Tk_GetReliefFromObj} {
    .b configure -relief sunken
    .b cget -relief


} {sunken}
test border-5.7 {Tk_GetReliefFromObj - error} {
    list [catch {.b configure -relief upanddown} msg] $msg
} {1 {bad relief "upanddown": must be flat, groove, raised, ridge, solid, or sunken}}

if {[testConstraint pseudocolor8]} {
    destroy .t

}

# cleanup
cleanupTests
return

Added tests/bugs.tcl.



















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# This file is a Tcl script to test out various known bugs that will
# cause Tk to crash.  This file ends with .tcl instead of .test to make
# sure it isn't run when you type "source all".  We currently are not
# shipping this file with the rest of the source release.
#
# 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.

if {[info procs test] != "test"} {
    source defs
}

test crash-1.0 {imgPhoto} {
    image create photo p1
    image create photo p2
    catch {image create photo p2 -file bogus}
    p1 copy p2
    label .l -image p1
    destroy .l
    set foo ""
} {}

test crash-1.1 {color} {
    . configure -bg rgb:345
    set foo ""
} {}













Deleted tests/busy.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# Tests for the tk busy command.
#
# This file contains a collection of tests for one or more of the Tk built-in
# commands. Sourcing this file runs the tests and generates output for errors.
# No output means no errors were found.
#
# Copyright © 1998-2000 by Jos Decoster. All rights reserved.

package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# There's currently no way to test the actual grab effect, per se, in an
# automated test. Therefore, this test suite only covers the interface to the
# grab command (ie, error messages, etc.)

test busy-1.1 {Tk_BusyObjCmd} -returnCodes error -body {
    tk busy
} -result {wrong # args: should be "tk busy options ?arg ...?"}

test busy-2.1 {tk busy hold} -returnCodes error -body {
    tk busy hold
} -result {wrong # args: should be "tk busy hold window ?-option value ...?"}
test busy-2.2 {tk busy hold root window} -body {
    set res [tk busy hold .]
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
test busy-2.3 {tk busy hold root window with shortcut} -body {
    set res [tk busy .]
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
test busy-2.4 {tk busy hold nested window} -setup {
    pack [frame .f]
} -body {
    set res [tk busy hold .f]
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f_Busy}
test busy-2.5 {tk busy hold nested window with shortcut} -setup {
    pack [frame .f]
} -body {
    set res [tk busy .f]
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f_Busy}
test busy-2.6 {tk busy hold toplevel window} -setup {
    toplevel .f
} -body {
    set res [tk busy hold .f]
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f._Busy}
test busy-2.7 {tk busy hold toplevel window with shortcut} -setup {
    toplevel .f
} -body {
    set res [tk busy .f]
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f._Busy}
test busy-2.8 {tk busy hold non existing window} -body {
    tk busy hold .f
    update
} -returnCodes error -result {bad window path name ".f"}
test busy-2.9 {tk busy hold (shortcut) non existing window} -body {
    tk busy .f
    update
} -returnCodes {error} -result {bad window path name ".f"}
test busy-2.10 {tk busy hold root window with cursor} -body {
    set res [tk busy hold . -cursor arrow]
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
test busy-2.11 {tk busy hold (shortcut) root window, cursor} -body {
    set res [tk busy . -cursor arrow]
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
test busy-2.12 {tk busy hold root window, invalid cursor} -body {
    tk busy hold . -cursor nonExistingCursor
    update
} -returnCodes error -cleanup {
    tk busy forget .
} -result {bad cursor spec "nonExistingCursor"}
test busy-2.13 {tk busy hold (shortcut) root window, invalid cursor} -body {
    tk busy . -cursor nonExistingCursor
    update
} -returnCodes error -cleanup {
    tk busy forget .
} -result {bad cursor spec "nonExistingCursor"}
test busy-2.14 {tk busy hold root window, invalid option} -body {
    tk busy hold . -invalidOption 1
    update
} -returnCodes error -cleanup {
    tk busy forget .
} -result {unknown option "-invalidOption"}
test busy-2.15 {tk busy hold (shortcut) root window, invalid option} -body {
    tk busy . -invalidOption 1
    update
} -returnCodes error -cleanup {
    tk busy forget .
} -result {unknown option "-invalidOption"}

test busy-3.1 {tk busy cget no window} -returnCodes error -body {
    tk busy cget
} -result {wrong # args: should be "tk busy cget window option"}
test busy-3.2 {tk busy cget no option} -returnCodes error -body {
    tk busy cget
} -result {wrong # args: should be "tk busy cget window option"}
test busy-3.3 {tk busy cget invalid window} -returnCodes error -body {
    tk busy cget .f -cursor
} -result {bad window path name ".f"}
test busy-3.4 {tk busy cget non-busy window} -setup {
    pack [frame .f]
} -body {
    tk busy cget .f -cursor
} -cleanup {
    destroy .f
} -returnCodes error -result {can't find busy window ".f"}
test busy-3.5 {tk busy cget invalid option} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy cget .f -invalidOption
} -cleanup {
    tk busy forget .f
    destroy .f
} -returnCodes error -result {unknown option "-invalidOption"}
test busy-3.6unix {tk busy cget unix} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy cget .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {watch} -constraints unix
test busy-3.6win {tk busy cget win} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy cget .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {wait} -constraints win
test busy-3.7 {tk busy cget unix} -setup {
    pack [frame .f]
    tk busy hold .f -cursor hand1
    update
} -body {
    tk busy cget .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {hand1}

test busy-4.1 {tk busy configure no window} -returnCodes error -body {
    tk busy configure
} -result {wrong # args: should be "tk busy configure window ?-option value ...?"}

test busy-4.2 {tk busy configure invalid window} -body {
    tk busy configure .f
} -returnCodes error -result {bad window path name ".f"}

test busy-4.3 {tk busy configure non-busy window} -setup {
    pack [frame .f]
} -body {
    tk busy configure .f
} -cleanup {
    destroy .f
} -returnCodes error -result {can't find busy window ".f"}

test busy-4.4 {tk busy configure} -constraints {nonwin} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {{-cursor cursor Cursor watch watch}}

test busy-4.4-win {tk busy configure} -constraints {win} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {{-cursor cursor Cursor wait wait}}

test busy-4.5 {tk busy configure} -constraints {nonwin} -setup {
    pack [frame .f]
    tk busy hold .f -cursor hand2
    update
} -body {
    tk busy configure .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {{-cursor cursor Cursor watch hand2}}

test busy-4.5-win {tk busy configure} -constraints win -setup {
    pack [frame .f]
    tk busy hold .f -cursor hand2
    update
} -body {
    tk busy configure .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {{-cursor cursor Cursor wait hand2}}

test busy-4.6 {tk busy configure invalid option} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f -invalidOption
} -cleanup {
    tk busy forget .f
    destroy .f
} -returnCodes error -result {unknown option "-invalidOption"}

test busy-4.7 {tk busy configure valid option} -constraints {nonwin} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {-cursor cursor Cursor watch watch}

test busy-4.7-win {tk busy configure valid option} -constraints {win} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {-cursor cursor Cursor wait wait}

test busy-4.8 {tk busy configure valid option} -constraints {
    nonwin
} -setup {
    pack [frame .f]
    tk busy hold .f -cursor circle
    update
} -body {
    tk busy configure .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {-cursor cursor Cursor watch circle}

test busy-4.8-win {tk busy configure valid option} -constraints win -setup {
    pack [frame .f]
    tk busy hold .f -cursor circle
    update
} -body {
    tk busy configure .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {-cursor cursor Cursor wait circle}

test busy-4.9 {tk busy configure valid option with value} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f -cursor pencil
    tk busy cget .f -cursor
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {pencil}

test busy-4.10 {tk busy configure valid option with invalid value} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy configure .f -cursor nonExistingCursor
} -returnCodes error -cleanup {
    tk busy forget .f
    destroy .f
} -result {bad cursor spec "nonExistingCursor"}

test busy-5.1 {tk busy forget} -returnCodes error -body {
    tk busy forget
} -result {wrong # args: should be "tk busy forget window"}
test busy-5.2 {tk busy forget non existing window} -body {
    tk busy forget .f
} -returnCodes error -result {bad window path name ".f"}
test busy-5.3 {tk busy forget non busy window} -setup {
    pack [frame .f]
} -body {
    tk busy forget .f
} -cleanup {
    destroy .f
} -returnCodes error -result {can't find busy window ".f"}
test busy-5.4 {tk busy forget window} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    set r [tk busy status .f]
    tk busy forget .f
    lappend r [tk busy status .f]
} -cleanup {
    destroy .f
} -result {1 0}

test busy-6.1 {tk busy status} -returnCodes error -body {
    tk busy status
} -result {wrong # args: should be "tk busy status window"}
test busy-6.2 {tk busy status non existing window} -body {
    tk busy status .f
} -result 0
test busy-6.3 {tk busy status non busy window} -setup {
    pack [frame .f]
} -body {
    tk busy status .f
} -cleanup {
    destroy .f
} -result 0
test busy-6.4 {tk busy status busy window} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy status .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result 1
test busy-6.5 {tk busy status forgotten busy window} -setup {
    pack [frame .f]
    tk busy hold .f
    update
    tk busy forget .f
} -body {
    tk busy status .f
} -cleanup {
    destroy .f
} -result 0

test busy-7.1 {tk busy current no busy} -body {
    tk busy current
} -result {}
test busy-7.2 {tk busy current 1 busy} -setup {
    pack [frame .f]
    tk busy hold .f
    update
} -body {
    tk busy current
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f}
test busy-7.3 {tk busy current 2 busy} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
} -body {
    lsort [tk busy current]
} -cleanup {
    tk busy forget .f1
    tk busy forget .f2
    destroy .f1 .f2
} -result {.f1 .f2}
test busy-7.4 {tk busy current 2 busy with matching filter} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
} -body {
    lsort [tk busy current *2*]
} -cleanup {
    tk busy forget .f1
    tk busy forget .f2
    destroy .f1 .f2
} -result {.f2}
test busy-7.5 {tk busy current 2 busy with non matching filter} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
} -body {
    lsort [tk busy current *3*]
} -cleanup {
    tk busy forget .f1
    tk busy forget .f2
    destroy .f1 .f2
} -result {}
test busy-7.6 {tk busy current 1 busy after forget} -setup {
    pack [frame .f]
    tk busy hold .f
    update
    tk busy forget .f
} -body {
    tk busy current
} -cleanup {
    destroy .f
} -result {}
test busy-7.7 {tk busy current 2 busy after forget} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
    tk busy forget .f1
} -body {
    lsort [tk busy current]
} -cleanup {
    tk busy forget .f2
    destroy .f1 .f2
} -result {.f2}
test busy-7.8 {tk busy current 2 busy with matching filter after forget} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
    tk busy forget .f1
} -body {
    lsort [tk busy current *2*]
} -cleanup {
    tk busy forget .f2
    destroy .f1 .f2
} -result {.f2}
test busy-7.9 {tk busy current 2 busy with non matching filter after forget} -setup {
    pack [frame .f1]
    pack [frame .f2]
    tk busy hold .f1
    tk busy hold .f2
    update
    tk busy forget .f1
} -body {
    lsort [tk busy current *3*]
} -cleanup {
    tk busy forget .f2
    destroy .f1 .f2
} -result {}

test busy-8.1 {tk busy busywindow with a busy toplevel} -body {
    toplevel .top
    tk busy .top
    tk busy busywindow .top
} -cleanup {
    tk busy forget .top
    destroy .top
} -result {.top._Busy}
test busy-8.2 {tk busy busywindow with a busy widget} -body {
    pack [frame .f]
    tk busy .f
    tk busy busywindow .f
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f_Busy}
test busy-8.3 {tk busy busywindow with a nonexisting widget} -body {
    tk busy .
    tk busy busywindow .nonExistingWidget
} -cleanup {
    tk busy forget .
} -result {}


::tcltest::cleanupTests
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to tests/button.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310

2311
2312

2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676

2677
2678
2679
2680
2681
2682

2683
2684
2685
2686
2687
2688

2689
2690
2691
2692
2693
2694

2695
2696
2697
2698
2699
2700
2701


2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737

2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750

2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787

2788
2789
2790
2791
2792
2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865


2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983

2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026

3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056

3057
3058
3059
3060
3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226

3227
3228
3229
3230
3231
3232
3233
3234
3235

3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250


3251



3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304


3305
3306
3307
3308
3309
3310
3311

3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396

3397

3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417

3418
3419
3420
3421
3422
3423
3424

3425
3426
3427

3428
3429


3430
3431
3432
3433
3434
3435
3436
3437


3438
3439


3440



3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469

3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492

3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507

3508
3509
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
3524

3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537

3538
3539
3540
3541
3542
3543
3544
3545

3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566

3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610

3611
3612
3613
3614
3615
3616
3617

3618
3619
3620
3621
3622
3623
3624
3625
3626

3627
3628
3629
3630
3631
3632
3633
3634
3635
3636

3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647

3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660

3661
3662
3663
3664
3665
3666
3667
3668
3669

3670
3671
3672
3673
3674
3675
3676
3677
3678
3679

3680
3681
3682
3683
3684
3685
3686
3687
3688
3689

3690
3691
3692
3693
3694
3695
3696
3697
3698
3699

3700
3701
3702
3703
3704
3705
3706
3707
3708
3709

3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720

3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731

3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743

3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770

3771
3772

3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
# This file is a Tcl script to test labels, buttons, checkbuttons, and
# radiobuttons in Tk (i.e., all the widgets defined in tkButton.c).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

proc bogusTrace args {
    error "trace aborted"
}

test button-1.1 {configuration option: "activebackground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -activebackground #012345
    .l cget -activebackground
} -cleanup {
    destroy .l
} -result {#012345}
test button-1.2 {configuration option: "activebackground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -activebackground non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.3 {configuration option: "activebackground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -activebackground #012345
    .b cget -activebackground
} -cleanup {
    destroy .b
} -result {#012345}
test button-1.4 {configuration option: "activebackground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -activebackground non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.5 {configuration option: "activebackground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -activebackground #012345
    .c cget -activebackground
} -cleanup {
    destroy .c
} -result {#012345}
test button-1.6 {configuration option: "activebackground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -activebackground non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.7 {configuration option: "activebackground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -activebackground #012345
    .r cget -activebackground
} -cleanup {
    destroy .r
} -result {#012345}
test button-1.8 {configuration option: "activebackground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -activebackground non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.9 {configuration option: "activeforeground" for label} -setup {

    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -activeforeground #ff0000
    .l cget -activeforeground
} -cleanup {
    destroy .l
} -result {#ff0000}
test button-1.10 {configuration option: "activeforeground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -activeforeground non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.11 {configuration option: "activeforeground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -activeforeground #ff0000
    .b cget -activeforeground
} -cleanup {
    destroy .b
} -result {#ff0000}
test button-1.12 {configuration option: "activeforeground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -activeforeground non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.13 {configuration option: "activeforeground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -activeforeground #ff0000
    .c cget -activeforeground
} -cleanup {
    destroy .c
} -result {#ff0000}
test button-1.14 {configuration option: "activeforeground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -activeforeground non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.15 {configuration option: "activeforeground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -activeforeground #ff0000
    .r cget -activeforeground
} -cleanup {
    destroy .r
} -result {#ff0000}
test button-1.16 {configuration option: "activeforeground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -activeforeground non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.17 {configuration option: "anchor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -anchor nw
    .l cget -anchor
} -cleanup {
    destroy .l
} -result {nw}
test button-1.18 {configuration option: "anchor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -anchor bogus
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}
test button-1.19 {configuration option: "anchor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -anchor nw
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {nw}
test button-1.20 {configuration option: "anchor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -anchor bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}
test button-1.21 {configuration option: "anchor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -anchor nw
    .c cget -anchor
} -cleanup {
    destroy .c
} -result {nw}
test button-1.22 {configuration option: "anchor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -anchor bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}
test button-1.23 {configuration option: "anchor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -anchor nw
    .r cget -anchor
} -cleanup {
    destroy .r
} -result {nw}
test button-1.24 {configuration option: "anchor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -anchor bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}

test button-1.25 {configuration option: "background" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -background #ff0000
    .l cget -background
} -cleanup {
    destroy .l
} -result {#ff0000}
test button-1.26 {configuration option: "background" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -background non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.27 {configuration option: "background" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -background #ff0000
    .b cget -background
} -cleanup {
    destroy .b
} -result {#ff0000}
test button-1.28 {configuration option: "background" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -background non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.29 {configuration option: "background" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -background #ff0000
    .c cget -background
} -cleanup {
    destroy .c
} -result {#ff0000}
test button-1.30 {configuration option: "background" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -background non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.31 {configuration option: "background" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -background #ff0000
    .r cget -background
} -cleanup {
    destroy .r
} -result {#ff0000}
test button-1.32 {configuration option: "background" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -background non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.33 {configuration option: "bd" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bd 4
    .l cget -bd
} -cleanup {
    destroy .l
} -result 4
test button-1.34 {configuration option: "bd" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bd badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.35 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd 4
    .b cget -bd
} -cleanup {
    destroy .b
} -result 4
test button-1.36 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.37 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd 4
    .c cget -bd
} -cleanup {
    destroy .c
} -result 4
test button-1.38 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.39 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd 4
    .r cget -bd
} -cleanup {
    destroy .r
} -result 4
test button-1.40 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.41 {configuration option: "bg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bg #ff0000
    .l cget -bg
} -cleanup {
    destroy .l
} -result {#ff0000}
test button-1.42 {configuration option: "bg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bg non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.43 {configuration option: "bg" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bg #ff0000
    .b cget -bg
} -cleanup {
    destroy .b
} -result {#ff0000}
test button-1.44 {configuration option: "bg" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bg non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.45 {configuration option: "bg" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bg #ff0000
    .c cget -bg
} -cleanup {
    destroy .c
} -result {#ff0000}
test button-1.46 {configuration option: "bg" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bg non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.47 {configuration option: "bg" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bg #ff0000
    .r cget -bg
} -cleanup {
    destroy .r
} -result {#ff0000}
test button-1.48 {configuration option: "bg" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bg non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.49 {configuration option: "bitmap" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bitmap questhead
    .l cget -bitmap
} -cleanup {
    destroy .l
} -result {questhead}
test button-1.50 {configuration option: "bitmap" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bitmap badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bitmap "badValue" not defined}
test button-1.51 {configuration option: "bitmap" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bitmap questhead
    .b cget -bitmap
} -cleanup {
    destroy .b
} -result {questhead}
test button-1.52 {configuration option: "bitmap" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bitmap badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bitmap "badValue" not defined}
test button-1.53 {configuration option: "bitmap" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bitmap questhead
    .c cget -bitmap
} -cleanup {
    destroy .c
} -result {questhead}
test button-1.54 {configuration option: "bitmap" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bitmap badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bitmap "badValue" not defined}
test button-1.55 {configuration option: "bitmap" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bitmap questhead
    .r cget -bitmap
} -cleanup {
    destroy .r
} -result {questhead}
test button-1.56 {configuration option: "bitmap" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bitmap badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bitmap "badValue" not defined}

test button-1.57 {configuration option: "borderwidth" for label} -setup {
    label .l -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -borderwidth 1.3
    .l cget -borderwidth
} -cleanup {
    destroy .l
} -result {1.3}
test button-1.58 {configuration option: "borderwidth" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -borderwidth badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.59 {configuration option: "borderwidth" for button} -setup {
    button .b -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth 1.3
    .b cget -borderwidth
} -cleanup {
    destroy .b
} -result {1.3}
test button-1.60 {configuration option: "borderwidth" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.61 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -cleanup {
    destroy .c
} -result {1.3}
test button-1.62 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.63 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth 1.3
    .r cget -borderwidth
} -cleanup {
    destroy .r
} -result {1.3}
test button-1.64 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.65 {configuration option: "command" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -command {set x}
    .b cget -command
} -cleanup {
    destroy .b
} -result {set x}
test button-1.66 {configuration option: "command" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -command {set x}
    .b cget -command
} -cleanup {
    destroy .b
} -result {set x}
test button-1.67 {configuration option: "command" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -command {set x}
    .c cget -command
} -cleanup {
    destroy .c
} -result {set x}
test button-1.68 {configuration option: "command" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -command {set x}
    .r cget -command
} -cleanup {
    destroy .r
} -result {set x}

test button-1.69 {configuration option: "compound" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -compound left
    .l cget -compound
} -cleanup {
    destroy .l
} -result {left}
test button-1.70 {configuration option: "compound" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -compound bogus
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad compound "bogus": must be bottom, center, left, none, right, or top}
test button-1.71 {configuration option: "compound" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -compound left
    .b cget -compound
} -cleanup {
    destroy .b
} -result {left}
test button-1.72 {configuration option: "compound" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -compound bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad compound "bogus": must be bottom, center, left, none, right, or top}
test button-1.73 {configuration option: "compound" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -compound left
    .c cget -compound
} -cleanup {
    destroy .c
} -result {left}
test button-1.74 {configuration option: "compound" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -compound bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad compound "bogus": must be bottom, center, left, none, right, or top}
test button-1.75 {configuration option: "compound" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -compound left
    .r cget -compound
} -cleanup {
    destroy .r
} -result {left}
test button-1.76 {configuration option: "compound" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -compound bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad compound "bogus": must be bottom, center, left, none, right, or top}

test button-1.77 {configuration option: "cursor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -cursor arrow
    .l cget -cursor
} -cleanup {
    destroy .l
} -result {arrow}
test button-1.78 {configuration option: "cursor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -cursor badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad cursor spec "badValue"}
test button-1.79 {configuration option: "cursor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -cursor arrow
    .b cget -cursor
} -cleanup {
    destroy .b
} -result {arrow}
test button-1.80 {configuration option: "cursor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -cursor badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad cursor spec "badValue"}
test button-1.81 {configuration option: "cursor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -cursor arrow
    .c cget -cursor
} -cleanup {
    destroy .c
} -result {arrow}
test button-1.82 {configuration option: "cursor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -cursor badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad cursor spec "badValue"}
test button-1.83 {configuration option: "cursor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -cursor arrow
    .r cget -cursor
} -cleanup {
    destroy .r
} -result {arrow}
test button-1.84 {configuration option: "cursor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -cursor badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad cursor spec "badValue"}

test button-1.85 {configuration option: "default" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -default active
    .b cget -default
} -cleanup {
    destroy .b
} -result {active}
test button-1.86 {configuration option: "default" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -default huh?
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad default "huh?": must be active, disabled, or normal}

test button-1.87 {configuration option: "disabledforeground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -disabledforeground #00ff00
    .l cget -disabledforeground
} -cleanup {
    destroy .l
} -result {#00ff00}
test button-1.88 {configuration option: "disabledforeground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -disabledforeground non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.89 {configuration option: "disabledforeground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -disabledforeground #00ff00
    .b cget -disabledforeground
} -cleanup {
    destroy .b
} -result {#00ff00}
test button-1.90 {configuration option: "disabledforeground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -disabledforeground non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.91 {configuration option: "disabledforeground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -disabledforeground #00ff00
    .c cget -disabledforeground
} -cleanup {
    destroy .c
} -result {#00ff00}
test button-1.92 {configuration option: "disabledforeground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -disabledforeground non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.93 {configuration option: "disabledforeground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -disabledforeground #00ff00
    .r cget -disabledforeground
} -cleanup {
    destroy .r
} -result {#00ff00}
test button-1.94 {configuration option: "disabledforeground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -disabledforeground non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.95 {configuration option: "fg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -fg #110022
    .l cget -fg
} -cleanup {
    destroy .l
} -result {#110022}
test button-1.96 {configuration option: "fg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -fg non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.97 {configuration option: "fg" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -fg #110022
    .b cget -fg
} -cleanup {
    destroy .b
} -result {#110022}
test button-1.98 {configuration option: "fg" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -fg non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.99 {configuration option: "fg" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -fg #110022
    .c cget -fg
} -cleanup {
    destroy .c
} -result {#110022}
test button-1.100 {configuration option: "fg" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -fg non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.101 {configuration option: "fg" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -fg #110022
    .r cget -fg
} -cleanup {
    destroy .r
} -result {#110022}
test button-1.102 {configuration option: "fg" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -fg non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.103 {configuration option: "font" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2
    pack .l
    update
} -body {
    .l configure -font {Helvetica -12}
    .l cget -font
} -cleanup {
    destroy .l
} -result {Helvetica -12}
test button-1.104 {configuration option: "activebackground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2
    pack .l
    update
} -body {
    .l configure -font {}
} -cleanup {
    destroy .l
} -returnCodes {error} -result {font "" doesn't exist}
test button-1.105 {configuration option: "font" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2
    pack .b
    update
} -body {
    .b configure -font {Helvetica -12}
    .b cget -font
} -cleanup {
    destroy .b
} -result {Helvetica -12}
test button-1.106 {configuration option: "activebackground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2
    pack .b
    update
} -body {
    .b configure -font {}
} -cleanup {
    destroy .b
} -returnCodes {error} -result {font "" doesn't exist}
test button-1.107 {configuration option: "font" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2
    pack .c
    update
} -body {
    .c configure -font {Helvetica -12}
    .c cget -font
} -cleanup {
    destroy .c
} -result {Helvetica -12}
test button-1.108 {configuration option: "activebackground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2
    pack .c
    update
} -body {
    .c configure -font {}
} -cleanup {
    destroy .c
} -returnCodes {error} -result {font "" doesn't exist}
test button-1.109 {configuration option: "font" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2
    pack .r
    update
} -body {
    .r configure -font {Helvetica -12}
    .r cget -font
} -cleanup {
    destroy .r
} -result {Helvetica -12}
test button-1.110 {configuration option: "activebackground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2
    pack .r
    update
} -body {
    .r configure -font {}
} -cleanup {
    destroy .r
} -returnCodes {error} -result {font "" doesn't exist}

test button-1.111 {configuration option: "foreground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -foreground #110022
    .l cget -foreground
} -cleanup {
    destroy .l
} -result {#110022}
test button-1.112 {configuration option: "foreground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -foreground non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.113 {configuration option: "foreground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -foreground #110022
    .b cget -foreground
} -cleanup {
    destroy .b
} -result {#110022}
test button-1.114 {configuration option: "foreground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -foreground non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.115 {configuration option: "foreground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -foreground #110022
    .c cget -foreground
} -cleanup {
    destroy .c
} -result {#110022}
test button-1.116 {configuration option: "foreground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -foreground non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.117 {configuration option: "foreground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -foreground #110022
    .r cget -foreground
} -cleanup {
    destroy .r
} -result {#110022}
test button-1.118 {configuration option: "foreground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -foreground non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.119 {configuration option: "height" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -height 18
    .l cget -height
} -cleanup {
    destroy .l
} -result 18
test button-1.120 {configuration option: "height" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -height 20.0
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected integer but got "20.0"}
test button-1.121 {configuration option: "height" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -height 18
    .b cget -height
} -cleanup {
    destroy .b
} -result 18
test button-1.122 {configuration option: "height" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -height 20.0
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "20.0"}
test button-1.123 {configuration option: "height" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -height 18
    .c cget -height
} -cleanup {
    destroy .c
} -result 18
test button-1.124 {configuration option: "height" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -height 20.0
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected integer but got "20.0"}
test button-1.125 {configuration option: "height" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -height 18
    .r cget -height
} -cleanup {
    destroy .r
} -result 18
test button-1.126 {configuration option: "height" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -height 20.0
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected integer but got "20.0"}

test button-1.127 {configuration option: "highlightbackground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightbackground #110022
    .l cget -highlightbackground
} -cleanup {
    destroy .l
} -result {#110022}
test button-1.128 {configuration option: "highlightbackground" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightbackground non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.129 {configuration option: "highlightbackground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightbackground #110022
    .b cget -highlightbackground
} -cleanup {
    destroy .b
} -result {#110022}
test button-1.130 {configuration option: "highlightbackground" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightbackground non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.131 {configuration option: "highlightbackground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightbackground #110022
    .c cget -highlightbackground
} -cleanup {
    destroy .c
} -result {#110022}
test button-1.132 {configuration option: "highlightbackground" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightbackground non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.133 {configuration option: "highlightbackground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightbackground #110022
    .r cget -highlightbackground
} -cleanup {
    destroy .r
} -result {#110022}
test button-1.134 {configuration option: "highlightbackground" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightbackground non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.135 {configuration option: "highlightcolor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightcolor #110022
    .l cget -highlightcolor
} -cleanup {
    destroy .l
} -result {#110022}
test button-1.136 {configuration option: "highlightcolor" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightcolor non-existent
} -cleanup {
    destroy .l
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.137 {configuration option: "highlightcolor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightcolor #110022
    .b cget -highlightcolor
} -cleanup {
    destroy .b
} -result {#110022}
test button-1.138 {configuration option: "highlightcolor" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightcolor non-existent
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.139 {configuration option: "highlightcolor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightcolor #110022
    .c cget -highlightcolor
} -cleanup {
    destroy .c
} -result {#110022}
test button-1.140 {configuration option: "highlightcolor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightcolor non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.141 {configuration option: "highlightcolor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightcolor #110022
    .r cget -highlightcolor
} -cleanup {
    destroy .r
} -result {#110022}
test button-1.142 {configuration option: "highlightcolor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightcolor non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.143 {configuration option: "highlightthickness" for label} -setup {
    label .l -borderwidth 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightthickness 6m
    .l cget -highlightthickness
} -cleanup {
    destroy .l
} -result {6m}
test button-1.144 {configuration option: "highlightthickness" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightthickness badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.145 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness 6m
    .b cget -highlightthickness
} -cleanup {
    destroy .b
} -result {6m}
test button-1.146 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.147 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightthickness 6m
    .c cget -highlightthickness
} -cleanup {
    destroy .c
} -result {6m}
test button-1.148 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}

    pack .c
    update
} -body {
    .c configure -highlightthickness badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.149 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness 6m
    .r cget -highlightthickness
} -cleanup {
    destroy .r
} -result {6m}
test button-1.150 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.151 {configuration option: "image" for label} -constraints {
    testImageType
} -setup {
    image create test image1
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -image image1
    .l cget -image
} -cleanup {
    destroy .l
    image delete image1
} -result {image1}
test button-1.152 {configuration option: "image" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -image bogus
} -cleanup {
    destroy .l
} -returnCodes {error} -result {image "bogus" doesn't exist}
test button-1.153 {configuration option: "image" for button} -constraints {
    testImageType
} -setup {
    image create test image1
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -image image1
    .b cget -image
} -cleanup {
    destroy .b
    image delete image1
} -result {image1}
test button-1.154 {configuration option: "image" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -image bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {image "bogus" doesn't exist}
test button-1.155 {configuration option: "image" for checkbutton} -constraints {
    testImageType
} -setup {
    image create test image1
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -image image1
    .c cget -image
} -cleanup {
    destroy .c
    image delete image1
} -result {image1}
test button-1.156 {configuration option: "image" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -image bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {image "bogus" doesn't exist}
test button-1.157 {configuration option: "image" for radiobutton} -constraints {
    testImageType
} -setup {
    image create test image1
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -image image1
    .r cget -image
} -cleanup {
    destroy .r
    image delete image1
} -result {image1}
test button-1.158 {configuration option: "image" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -image bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {image "bogus" doesn't exist}

test button-1.159 {configuration option: "indicatoron" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -indicatoron yes
    .c cget -indicatoron
} -cleanup {
    destroy .c
} -result 1
test button-1.160 {configuration option: "indicatoron" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -indicatoron no_way
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected boolean value but got "no_way"}
test button-1.161 {configuration option: "indicatoron" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -indicatoron yes
    .r cget -indicatoron
} -cleanup {
    destroy .r
} -result 1
test button-1.162 {configuration option: "indicatoron" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -indicatoron no_way
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected boolean value but got "no_way"}

test button-1.163 {configuration option: "justify" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -justify right
    .l cget -justify
} -cleanup {
    destroy .l
} -result {right}
test button-1.164 {configuration option: "justify" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -justify bogus
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}
test button-1.165 {configuration option: "justify" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -justify right
    .b cget -justify
} -cleanup {
    destroy .b
} -result {right}
test button-1.166 {configuration option: "justify" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -justify bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}
test button-1.167 {configuration option: "justify" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -justify right
    .c cget -justify
} -cleanup {
    destroy .c
} -result {right}
test button-1.168 {configuration option: "justify" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -justify bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}
test button-1.169 {configuration option: "justify" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -justify right
    .r cget -justify
} -cleanup {
    destroy .r
} -result {right}
test button-1.170 {configuration option: "justify" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -justify bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test button-1.171 {configuration option: "offrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -offrelief flat
    .c cget -offrelief
} -cleanup {
    destroy .c
} -result {flat}
test button-1.172 {configuration option: "offrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -offrelief 1.5
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.173 {configuration option: "offrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -offrelief flat
    .r cget -offrelief
} -cleanup {
    destroy .r
} -result {flat}
test button-1.174 {configuration option: "offrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -offrelief 1.5
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test button-1.175 {configuration option: "offvalue" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -offvalue lousy
    .c cget -offvalue
} -cleanup {
    destroy .c
} -result {lousy}

test button-1.176 {configuration option: "onvalue" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -onvalue fantastic
    .c cget -onvalue
} -cleanup {
    destroy .c
} -result {fantastic}

test button-1.177 {configuration option: "overrelief" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -overrelief ""
    .b cget -overrelief
} -cleanup {
    destroy .b
} -result {}
test button-1.178 {configuration option: "overrelief" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -overrelief 1.5
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.179 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief ""
    .c cget -overrelief
} -cleanup {
    destroy .c
} -result {}
test button-1.180 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief 1.5
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.181 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief ""
    .r cget -overrelief
} -cleanup {
    destroy .r
} -result {}
test button-1.182 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief 1.5
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test button-1.183 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 12m
    .l cget -padx
} -cleanup {
    destroy .l
} -result {12m}
test button-1.184 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.185 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 12m
    .b cget -padx
} -cleanup {
    destroy .b
} -result {12m}
test button-1.186 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.187 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 12m
    .c cget -padx
} -cleanup {
    destroy .c
} -result {12m}
test button-1.188 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.189 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 12m
    .r cget -padx
} -cleanup {
    destroy .r
} -result {12m}
test button-1.190 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "420x"}

test button-1.191 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 12m
    .l cget -pady
} -cleanup {
    destroy .l
} -result {12m}
test button-1.192 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.193 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 12m
    .b cget -pady
} -cleanup {
    destroy .b
} -result {12m}
test button-1.194 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.195 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 12m
    .c cget -pady
} -cleanup {
    destroy .c
} -result {12m}
test button-1.196 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.197 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 12m
    .r cget -pady
} -cleanup {
    destroy .r
} -result {12m}
test button-1.198 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "420x"}

test button-1.199 {configuration option: "repeatdelay" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatdelay 100
    .b cget -repeatdelay
} -cleanup {
    destroy .b
} -result 100
test button-1.200 {configuration option: "repeatdelay" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatdelay foo
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "foo"}

test button-1.201 {configuration option: "repeatinterval" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatinterval 100
    .b cget -repeatinterval
} -cleanup {
    destroy .b
} -result 100
test button-1.202 {configuration option: "repeatinterval" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatinterval foo
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "foo"}

test button-1.203 {configuration option: "relief" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -relief flat
    .l cget -relief
} -cleanup {
    destroy .l
} -result {flat}
test button-1.204 {configuration option: "relief" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -relief 1.5
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.205 {configuration option: "relief" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -relief flat
    .b cget -relief
} -cleanup {
    destroy .b
} -result {flat}
test button-1.206 {configuration option: "relief" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -relief 1.5
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.207 {configuration option: "relief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -relief flat
    .c cget -relief
} -cleanup {
    destroy .c
} -result {flat}
test button-1.208 {configuration option: "relief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -relief 1.5
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.209 {configuration option: "relief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -relief flat
    .r cget -relief
} -cleanup {
    destroy .r
} -result {flat}
test button-1.210 {configuration option: "relief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -relief 1.5
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test button-1.211 {configuration option: "selectcolor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -selectcolor #110022
    .c cget -selectcolor
} -cleanup {
    destroy .c
} -result {#110022}
test button-1.212 {configuration option: "selectcolor" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -selectcolor non-existent
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown color name "non-existent"}
test button-1.213 {configuration option: "selectcolor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -selectcolor #110022
    .r cget -selectcolor
} -cleanup {
    destroy .r
} -result {#110022}
test button-1.214 {configuration option: "selectcolor" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -selectcolor non-existent
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown color name "non-existent"}

test button-1.215 {configuration option: "selectimage" for checkbutton} -constraints {
    testImageType
} -setup {
    image create test image1
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -selectimage image1
    .c cget -selectimage
} -cleanup {
    destroy .c
    image delete image1
} -result {image1}
test button-1.216 {configuration option: "selectimage" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -selectimage bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {image "bogus" doesn't exist}
test button-1.217 {configuration option: "selectimage" for radiobutton} -constraints {
    testImageType
} -setup {
    image create test image1
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -selectimage image1
    .r cget -selectimage
} -cleanup {
    destroy .r
    image delete image1
} -result {image1}
test button-1.218 {configuration option: "selectimage" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -selectimage bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {image "bogus" doesn't exist}

test button-1.219 {configuration option: "state" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -state normal
    .l cget -state
} -cleanup {
    destroy .l
} -result {normal}
test button-1.220 {configuration option: "state" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -state bogus
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad state "bogus": must be active, disabled, or normal}
test button-1.221 {configuration option: "state" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -state normal
    .b cget -state
} -cleanup {
    destroy .b
} -result {normal}
test button-1.222 {configuration option: "state" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -state bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad state "bogus": must be active, disabled, or normal}
test button-1.223 {configuration option: "state" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -state normal
    .c cget -state
} -cleanup {
    destroy .c
} -result {normal}
test button-1.224 {configuration option: "state" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -state bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad state "bogus": must be active, disabled, or normal}
test button-1.225 {configuration option: "state" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -state normal
    .r cget -state
} -cleanup {
    destroy .r
} -result {normal}
test button-1.226 {configuration option: "state" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -state bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad state "bogus": must be active, disabled, or normal}

test button-1.227 {configuration option: "takefocus" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -takefocus "any string"
    .l cget -takefocus
} -cleanup {
    destroy .l
} -result {any string}
test button-1.228 {configuration option: "takefocus" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -takefocus "any string"
    .b cget -takefocus
} -cleanup {
    destroy .b
} -result {any string}
test button-1.229 {configuration option: "takefocus" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -takefocus "any string"
    .c cget -takefocus
} -cleanup {
    destroy .c
} -result {any string}
test button-1.230 {configuration option: "takefocus" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -takefocus "any string"
    .r cget -takefocus
} -cleanup {
    destroy .r
} -result {any string}

test button-1.231 {configuration option: "text" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -text "Sample text"
    .l cget -text
} -cleanup {
    destroy .l
} -result {Sample text}
test button-1.232 {configuration option: "text" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -text "Sample text"
    .b cget -text
} -cleanup {
    destroy .b
} -result {Sample text}
test button-1.233 {configuration option: "text" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -text "Sample text"
    .c cget -text
} -cleanup {
    destroy .c
} -result {Sample text}
test button-1.234 {configuration option: "text" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -text "Sample text"
    .r cget -text
} -cleanup {
    destroy .r
} -result {Sample text}


test button-1.235 {configuration option: "textvariable" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}

    pack .l
    update
} -body {
    .l configure -textvariable i
    .l cget -textvariable
} -cleanup {
    destroy .l
} -result {i}
test button-1.236 {configuration option: "textvariable" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -textvariable i
    .b cget -textvariable
} -cleanup {
    destroy .b
} -result {i}
test button-1.237 {configuration option: "textvariable" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -textvariable i
    .c cget -textvariable
} -cleanup {
    destroy .c
} -result {i}
test button-1.238 {configuration option: "textvariable" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -textvariable i
    .r cget -textvariable
} -cleanup {
    destroy .r
} -result {i}

test button-1.239 {configuration option: "tristateimage" for checkbutton} -constraints {
    testImageType
} -setup {
    image create test image1
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -tristateimage image1
    .c cget -tristateimage
} -cleanup {
    destroy .c
    image delete image1
} -result {image1}
test button-1.240 {configuration option: "tristateimage" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -tristateimage bogus
} -cleanup {
    destroy .c
} -returnCodes {error} -result {image "bogus" doesn't exist}
test button-1.241 {configuration option: "tristateimage" for radiobutton} -constraints {
    testImageType
} -setup {
    image create test image1
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -tristateimage image1
    .r cget -tristateimage
} -cleanup {
    destroy .r
    image delete image1
} -result {image1}
test button-1.242 {configuration option: "tristateimage" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -tristateimage bogus
} -cleanup {
    destroy .r
} -returnCodes {error} -result {image "bogus" doesn't exist}

test button-1.243 {configuration option: "underline" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -underline 5
    .l cget -underline
} -cleanup {
    destroy .l
} -result 5
test button-1.244 {configuration option: "underline" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -underline 3p
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.245 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 5
    .b cget -underline
} -cleanup {
    destroy .b
} -result 5
test button-1.246 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 3p
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.247 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 5
    .c cget -underline
} -cleanup {
    destroy .c
} -result 5
test button-1.248 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 3p
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.249 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 5
    .r cget -underline
} -cleanup {
    destroy .r
} -result 5
test button-1.250 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 3p
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected integer but got "3p"}

test button-1.251 {configuration option: "tristatevalue" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -tristatevalue unknowable
    .c cget -tristatevalue
} -cleanup {
    destroy .c
} -result {unknowable}
test button-1.252 {configuration option: "tristatevalue" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -tristatevalue unknowable
    .r cget -tristatevalue
} -cleanup {
    destroy .r
} -result {unknowable}

test button-1.253 {configuration option: "value" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -value anyString
    .r cget -value
} -cleanup {
    destroy .r
} -result {anyString}

test button-1.254 {configuration option: "width" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -width 402
    .l cget -width
} -cleanup {
    destroy .l
} -result 402
test button-1.255 {configuration option: "width" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -width 3p
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.256 {configuration option: "width" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -width 402
    .b cget -width
} -cleanup {
    destroy .b
} -result 402
test button-1.257 {configuration option: "width" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -width 3p
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.258 {configuration option: "width" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -width 402
    .c cget -width
} -cleanup {
    destroy .c
} -result 402
test button-1.259 {configuration option: "width" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -width 3p
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.260 {configuration option: "width" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -width 402
    .r cget -width
} -cleanup {
    destroy .r
} -result 402
test button-1.261 {configuration option: "width" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -width 3p
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected integer but got "3p"}

test button-1.262 {configuration option: "wraplength" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -wraplength 100
    .l cget -wraplength
} -cleanup {
    destroy .l
} -result 100
test button-1.263 {configuration option: "wraplength" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -wraplength 6x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.264 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 100
    .b cget -wraplength
} -cleanup {
    destroy .b
} -result 100
test button-1.265 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 6x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.266 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 100
    .c cget -wraplength
} -cleanup {
    destroy .c
} -result 100
test button-1.267 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 6x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.268 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 100
    .r cget -wraplength
} -cleanup {
    destroy .r
} -result 100
test button-1.269 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 6x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "6x"}

test button-1.270 {configuration options} -body {
# Additional check to make sure that -selectcolor may be empty in
# checkbox widgets
    checkbutton .c
    .c configure -selectcolor {}
} -cleanup {
    destroy .c
} -result {}

# ex-tests 3.*
test button-2.1 {ButtonCreate - not enough arguments} -body {
    button
} -returnCodes {error} -result {wrong # args: should be "button pathName ?-option value ...?"}

test button-2.2 {ButtonCreate procedure - setting label class} -body {

    label .x
    winfo class .x
} -cleanup {
    destroy .x
} -result {Label}
test button-2.3 {ButtonCreate - setting button class} -body {

    button .x
    winfo class .x
} -cleanup {
    destroy .x
} -result {Button}
test button-2.4 {ButtonCreate - setting checkbutton class} -body {

    checkbutton .x
    winfo class .x
} -cleanup {
    destroy .x
} -result {Checkbutton}
test button-2.5 {ButtonCreate - setting radiobutton class} -body {

    radiobutton .x
    winfo class .x
} -cleanup {
    destroy .x
} -result {Radiobutton}
test button-2.6 {ButtonCreate - setting class} -body {
    rename button gorp


    gorp .x
    winfo class .x
} -cleanup {
    destroy .x
    rename gorp button
} -result {Button}

test button-2.7 {ButtonCreate - bad window name} -body {
    button foo
} -cleanup {
    destroy foo
} -returnCodes {error} -result {bad window path name "foo"}
######### test ex 3.8
test button-2.8 {ButtonCreate procedure - error in default option value} -body {
    option add *funny.background bogus
    button .funny
} -cleanup {
    option clear
    destroy .funny
} -returnCodes {error} -result {unknown color name "bogus"}
test button-2.9 {ButtonCreate procedure - error in default option value} -body {
   option add *funny.background bogus
    catch {button .funny}
    return $errorInfo
} -cleanup {
    option clear
    destroy .funny
} -result {unknown color name "bogus"
    (database entry for "-background" in widget ".funny")
    invoked from within
"button .funny"}

test button-2.10 {ButtonCreate procedure - option error} -body {
    button .x -gorp foo
}  -cleanup {
    destroy .x

} -returnCodes {error} -result {unknown option "-gorp"}
test button-2.11 {ButtonCreate procedure - option error} -body {
    catch {button .x -gorp foo}
    winfo exists .x
}  -cleanup {
    destroy .x
} -result 0
######### ex 3.10
test button-2.12 {ButtonCreate procedure - return value} -body {
    set x [button .abcd]
    return $x
} -cleanup {
    destroy .abcd

} -result {.abcd}

######### ex 4.*
test button-3.1 {ButtonWidgetCmd - too few arguments} -body {
    button .b
    .b
} -cleanup {
    destroy .b
} -returnCodes {error} -result {wrong # args: should be ".b option ?arg ...?"}
test button-3.2 {ButtonWidgetCmd - bad option name} -body {
    button .b
    .b c
} -cleanup {
    destroy .b
} -returnCodes {error} -result {ambiguous option "c": must be cget, configure, flash, or invoke}
test button-3.3 {ButtonWidgetCmd - bad option name} -body {
    button .b
    .b bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad option "bogus": must be cget, configure, flash, or invoke}
test button-3.4 {ButtonWidgetCmd procedure, "cget" option} -body {
    button .b
    .b cget a b
} -cleanup {
    destroy .b
} -returnCodes {error} -result {wrong # args: should be ".b cget option"}
test button-3.5 {ButtonWidgetCmd procedure, "cget" option} -body {
    button .b
    .b cget -gorp
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown option "-gorp"}

#ex 4.7
test button-3.6 {ButtonWidgetCmd procedure, "cget" option} -body {
    label .l

    .l cget -disabledforeground
} -cleanup {
    destroy .l
} -returnCodes {ok} -match {glob} -result {*}
test button-3.7 {ButtonWidgetCmd procedure, "cget" option} -body {
    button .b
    .b cget -disabledforeground
} -cleanup {
    destroy .b
} -returnCodes {ok} -match {glob} -result {*}

test button-3.8 {ButtonWidgetCmd procedure, "cget" option} -body {
    button .b
    .b cget -variable
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown option "-variable"}

test button-3.9 {ButtonWidgetCmd procedure, "cget" option} -body {
    checkbutton .c
    .c cget -variable
} -cleanup {
    destroy .c
} -returnCodes {ok} -match {glob} -result {*}
test button-3.10 {ButtonWidgetCmd procedure, "cget" option} -body {
    checkbutton .c
    .c cget -value
} -cleanup {
    destroy .c
} -returnCodes {error} -result {unknown option "-value"}

test button-3.11 {ButtonWidgetCmd procedure, "cget" option} -body {
    radiobutton .r
    .r cget -value
} -cleanup {
    destroy .r
} -returnCodes {ok} -match {glob} -result {*}
test button-3.12 {ButtonWidgetCmd procedure, "cget" option} -body {
    radiobutton .r
    .r cget -onvalue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {unknown option "-onvalue"}

# ex 4.6
test button-3.13 {ButtonWidgetCmd procedure, "configure" option} -body {
    button .b -highlightthickness 3
    lindex [.b configure -highlightthickness] 4
} -cleanup {
    destroy .b
}  -result 3
test button-3.14 {ButtonWidgetCmd procedure, "configure" option} -body {
    checkbutton .c
    llength [.c configure]
} -cleanup {
    destroy .c
} -result 41
test button-3.15 {ButtonWidgetCmd procedure, "configure" option} -body {
    button .b
    .b configure -gorp
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown option "-gorp"}
test button-3.16 {ButtonWidgetCmd procedure, "configure" option} -setup {
    button .b
} -body {
    .b co -bg #ffffff -fg
} -cleanup {
    destroy .b
} -returnCodes {error} -result {value for "-fg" missing}
test button-3.17 {ButtonWidgetCmd procedure, "configure" option} -setup {
    button .b
} -body {
    .b configure -fg #123456
    .b configure -bg #654321
    lindex [.b configure -fg] 4
} -cleanup {
    destroy .b
} -result {#123456}


test button-3.18 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c
    .c deselect foo
} -cleanup {
    destroy .c
} -returnCodes {error} -result {wrong # args: should be ".c deselect"}
test button-3.19 {ButtonWidgetCmd procedure, "deselect" option} -body {
    label .l
    .l deselect
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad option "deselect": must be cget or configure}
test button-3.20 {ButtonWidgetCmd procedure, "deselect" option} -body {
    button .b
    .b deselect
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad option "deselect": must be cget, configure, flash, or invoke}

test button-3.21 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    .c d
    return $checkvar
} -cleanup {
    destroy .c
} -result 0
test button-3.22 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar green
    .r deselect
    return $radiovar
} -cleanup {
    destroy .r
} -result {green}
test button-3.23 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    .r deselect
    return $radiovar
} -cleanup {
    destroy .r
} -result {}

test button-3.24 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace variable checkvar w bogusTrace
    .c deselect
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.25 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace variable checkvar w bogusTrace
    catch {.c deselect}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c deselect"} 0}
test button-3.26 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace variable radiovar w bogusTrace
    .r deselect
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.27 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace variable radiovar w bogusTrace
    catch {.r deselect}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match glob -result {{*trace aborted
    while executing
*
".r deselect"} {}}

test button-3.28 {ButtonWidgetCmd procedure, "flash" option} -body {
    button .b
    .b flash foo
} -cleanup {
    destroy .b
} -returnCodes {error} -result {wrong # args: should be ".b flash"}
test button-3.29 {ButtonWidgetCmd procedure, "flash" option} -body {
    label .l
    .l flash
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad option "flash": must be cget or configure}
test button-3.30 {ButtonWidgetCmd procedure, "flash" option} -body {
    button .b
    catch {.b flash}
} -cleanup {
    destroy .b
} -returnCodes {ok} -match {glob} -result {*}
test button-3.31 {ButtonWidgetCmd procedure, "flash" option} -body {
    checkbutton .c
    catch {.c flash}
} -cleanup {
    destroy .c
} -returnCodes {ok} -match {glob} -result {*}
test button-3.32 {ButtonWidgetCmd procedure, "flash" option} -body {
    radiobutton .r
    catch {.r f}
} -cleanup {
    destroy .r

} -returnCodes {ok} -match {glob} -result {*}

test button-3.33 {ButtonWidgetCmd procedure, "invoke" option} -body {
    label .l
    .l invoke
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad option "invoke": must be cget or configure}
test button-3.34 {ButtonWidgetCmd procedure, "invoke" option} -body {
    button .b
    .b invoke foo
} -cleanup {
    destroy .b
} -returnCodes {error} -result {wrong # args: should be ".b invoke"}
test button-3.35 {ButtonWidgetCmd procedure, "invoke" option} -body {
    button .b
    .b configure -command {set x invoked}
    set x "not invoked"
    .b invoke
    return $x
} -cleanup {
    destroy .b
} -result {invoked}
test button-3.36 {ButtonWidgetCmd procedure, "invoke" option} -body {
    button .b
    .b configure -command {set x invoked} -state disabled
    set x "not invoked"
    .b invoke
    return $x
} -cleanup {
    destroy .b
} -result {not invoked}
test button-3.37 {ButtonWidgetCmd procedure, "invoke" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0 \
        -command {set x invoked}
    set checkvar bogus
    set x "not invoked"
    .c invoke
    list $x $checkvar
} -cleanup {
    destroy .c
} -result  {invoked 1}
test button-3.38 {ButtonWidgetCmd procedure, "invoke" option} -body {

    radiobutton .r -command {set x invoked} -variable radiovar -value red
    set radiovar green
    set x "not invoked"
    .r i
    list $x $radiovar
} -cleanup {
    destroy .r
} -result {invoked red}

test button-3.39 {ButtonWidgetCmd procedure, "select" option} -body {
    label .l
    .l select
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad option "select": must be cget or configure}
test button-3.40 {ButtonWidgetCmd procedure, "select" option} -body {
    button .b
    .b select
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad option "select": must be cget, configure, flash, or invoke}
test button-3.41 {ButtonWidgetCmd procedure, "select" option} -body {
    checkbutton .c
    .c select foo
} -cleanup {
    destroy .c
} -returnCodes {error} -result {wrong # args: should be ".c select"}
test button-3.42 {ButtonWidgetCmd procedure, "select" option} -body {
    checkbutton .c -variable checkvar -onvalue lovely -offvalue 0
    set checkvar bogus

    .c s
    return $checkvar
} -cleanup {
    destroy .c
} -result  {lovely}
test button-3.43 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar green

    .r select
    return $radiovar
} -cleanup {
    destroy .r
} -result  {red}
test button-3.44 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace variable radiovar w bogusTrace
    .r select
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.45 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace variable radiovar w bogusTrace
    catch {.r select}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -result {{*trace aborted
    while executing
*
".r select"} red}

# ex 4.43
test button-3.46 {ButtonWidgetCmd procedure, "toggle" option} -body {
    label .l
    .l toggle
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad option "toggle": must be cget or configure}
test button-3.47 {ButtonWidgetCmd procedure, "toggle" option} -body {
    button .b
    .b toggle
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad option "toggle": must be cget, configure, flash, or invoke}
test button-3.48 {ButtonWidgetCmd procedure, "toggle" option} -body {
    radiobutton .r
    .r toggle
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad option "toggle": must be cget, configure, deselect, flash, invoke, or select}
test button-3.49 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c
    .c toggle foo
} -cleanup {
    destroy .c
} -returnCodes {error} -result {wrong # args: should be ".c toggle"}
test button-3.50 {ButtonWidgetCmd procedure, "toggle" option} -body {
    set checkvar bogus
    checkbutton .c -variable checkvar -onvalue sunshine -offvalue rain
    .c toggle
    set result $checkvar
    .c toggle
    lappend result $checkvar
    .c toggle
    lappend result $checkvar
    return $result
} -cleanup {
    destroy .c
} -result {sunshine rain sunshine}
test button-3.51 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace variable checkvar w bogusTrace
    .c toggle
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.52 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace variable checkvar w bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} abc}
test button-3.53 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace variable checkvar w bogusTrace
    .c toggle
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.54 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace variable checkvar w bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} xyz}
test button-3.55 {ButtonWidgetCmd procedure, "toggle" option} -setup {
    unset -nocomplain checkvar
} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    unset checkvar
    set checkvar(1) 1
    .c toggle
} -cleanup {
    destroy .c
} -returnCodes {error} -result {can't set "checkvar": variable is array}
test button-3.56 {ButtonWidgetCmd procedure, "toggle" option} -setup {
    unset -nocomplain checkvar
} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    unset checkvar
    set checkvar(1) 1
    catch {.c toggle}
    return $errorInfo
} -cleanup {
    destroy .c
} -match {glob} -result {can't set "checkvar": variable is array
    while executing
".c toggle"}

test button-4.1 {DestroyButton procedure} -constraints {
    testImageType
} -setup {
    image create test image1
    unset -nocomplain x
} -body {
    button .b1 -image image1
    button .b2 -fg #ff0000 -text "Button 2"
    button .b3 -state active -text "Button 3"
    button .b4 -disabledforeground #0000ff -state disabled -text "Button 4"
    checkbutton .b5 -variable x -text "Checkbutton 5"
    set x 1
    pack .b1 .b2 .b3 .b4 .b5
    update
    deleteWindows
} -cleanup {
    destroy .b1 .b2 .b3 .b4 .b5
    image delete image1
} -result {}

test button-5.1 {ConfigureButton - textvariable trace} -body {
    button .b -bd 4 -bg green
    .b configure -bd 7 -bg red -fg bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {unknown color name "bogus"}
test button-5.2 {ConfigureButton - textvariable trace} -body {
    button .b -bd 4 -bg green

    catch {.b configure -bd 7 -bg red -fg bogus}
    list [.b cget -bd] [.b cget -bg]
} -cleanup {
    destroy .b
} -result {4 green}
test button-5.3 {ConfigureButton - textvariable trace} -body {
    button .b -textvariable x
    set x From-x
    set y From-y

    .b configure -textvariable y
    set x New
    lindex [.b configure -text] 4
} -cleanup {
    destroy .b
} -result {From-y}
test button-5.4 {ConfigureButton - variable trace} -body {  ;# ex 6.2a
    checkbutton .c -variable x
    set x 1
    set y 1
    .c configure -textvariable y
    set x 0
    .c toggle
    return $y
} -cleanup {


    destroy .c



} -result 1

test button-5.5 {ConfigureButton - image handling} -constraints {
    testImageType
} -setup {
    imageCleanup
    image create test image1
    image create test image2
} -body {
    button .b -image image1
    image delete image1
    .b configure -image image2
    imageNames
} -cleanup {
    destroy .b
    imageCleanup
} -result {image2}

test button-5.6 {ConfigureButton - default value for variable} -body {
    checkbutton .c
    .c cget -variable
} -cleanup {
    destroy .c
} -result {c}
test button-5.7 {ConfigureButton - setting selected state from variable} -body {
    set x 0
    set y Shiny
    checkbutton .c -variable x
    .c configure -variable y -onvalue Shiny
    .c toggle
    return $y
} -cleanup {
    destroy .c
} -result 0
test button-5.8 {ConfigureButton - setting selected state from variable} -setup {
    unset -nocomplain x
} -body {
    checkbutton .c -variable x -offvalue Bogus
    return $x
} -cleanup {
    destroy .c
} -result {Bogus}

test button-5.9 {ConfigureButton - setting selected state from variable} -setup {
    unset -nocomplain x
} -body {
    radiobutton .r -variable x
    return $x
} -cleanup {
    destroy .r
} -result {}

test button-5.10 {ConfigureButton - error in setting variable} -setup {


    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    radiobutton .r -variable x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace

} -returnCodes {error} -result {can't set "x": trace aborted}

test button-5.11 {ConfigureButton - bad image name} -body {
    button .b -image bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {image "bogus" doesn't exist}

test button-5.12 {ConfigureButton - setting variable from current text value} -setup {
    unset -nocomplain x
} -body {
    button .b -textvariable x -text "Button 1"
    return $x
} -cleanup {
    destroy .b
} -result {Button 1}

test button-5.13 {ConfigureButton - using current value of variable} -body {
    set x Override
    button .b -textvariable x -text "Button 1"
    return $x
} -cleanup {
    destroy .b
} -result {Override}

test button-5.14 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    radiobutton .r -text foo -textvariable x
} -cleanup {
    trace vdelete x w bogusTrace
    destroy .r
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-5.15 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    catch {radiobutton .r -text foo -textvariable x}
	return $x
} -cleanup {
    trace vdelete x w bogusTrace

    destroy .r
} -result {foo}

#ex 6.14
test button-5.16 {ConfigureButton - -width option} -body {
    button .b -text "Button 1"
    .b configure -width 1i
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "1i"}
test button-5.17 {ConfigureButton - -width option} -body {
    button .b -text "Button 1"
    catch {.b configure -width 1i}
    return $errorInfo
} -cleanup {
    destroy .b
} -result  {expected integer but got "1i"
    (processing -width option)
    invoked from within
".b configure -width 1i"}
test button-5.18 {ConfigureButton - -height option} -body {
    button .b -text "Button 1"
    .b configure -height 0.5c
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "0.5c"}
test button-5.19 {ConfigureButton - -height option} -body {
    button .b -text "Button 1"
    catch {.b configure -height 0.5c}
    return $errorInfo
} -cleanup {
    destroy .b
} -result {expected integer but got "0.5c"
    (processing -height option)
    invoked from within
".b configure -height 0.5c"}
#ex 6.16
test button-5.20 {ConfigureButton - -width option} -body {
    button .b -bitmap questhead
    .b configure -width abc
} -cleanup {
    destroy .b
} -returnCodes {error} -result  {bad screen distance "abc"}

test button-5.21 {ConfigureButton - -width option} -body {

    button .b -bitmap questhead
    catch {.b configure -width abc}
    return $errorInfo
} -cleanup {
    destroy .b
} -result {bad screen distance "abc"
    (processing -width option)
    invoked from within
".b configure -width abc"}
test button-5.22 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
    button .b -image image1
    .b configure -height 0.5x
} -cleanup {
    destroy .b
    image delete image1
} -returnCodes {error} -result {bad screen distance "0.5x"}

test button-5.23 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
#ztestImageType
    button .b -image image1

    catch {.b configure -height 0.5x}
    return $errorInfo
} -cleanup {

    destroy .b
    image delete image1


} -result  {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".b configure -height 0.5x"}
#ex 6.18
test button-5.24 {ConfigureButton - computing geometry} -constraints {
    fonts
} -body {


    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
                -padx 30 -pady 20


    # 1. button with text



    .b configure -text "Sample text"
    pack .b
    set textwidth [font measure [.b cget -font] -displayof .b [.b cget -text]]
    set expectedwidth [expr {$textwidth + 2*[.b cget -borderwidth] \
            + 2*[.b cget -highlightthickness] + 2*[.b cget -padx]}]
    incr expectedwidth 2   ; # added (hardcoded) in tkUnixButton.c
    set result [expr {$expectedwidth == [winfo reqwidth .b]}]
    set linespace [lindex [font metrics [.b cget -font] -displayof .b] 5]
    set expectedheight [expr {$linespace + 2*[.b cget -borderwidth] \
            + 2*[.b cget -highlightthickness] + 2*[.b cget -pady]}]
    incr expectedheight 2   ; # added (hardcoded) in tkUnixButton.c
    lappend result [expr {$expectedheight == [winfo reqheight .b]}]
    # 2. button with a bitmap image
    # there is no access to characteristics the predefined bitmaps,
    # so define one as an image (copied from questhead.xbm)
    set myquesthead [image create bitmap -data {
        #define myquesthead_width 20
        #define myquesthead_height 22
        static unsigned char myquesthead_bits[] = {
           0xf8, 0x1f, 0x00, 0xac, 0x2a, 0x00, 0x56, 0x55, 0x00, 0xeb, 0xaf, 0x00,
           0xf5, 0x5f, 0x01, 0xfb, 0xbf, 0x00, 0x75, 0x5d, 0x01, 0xfb, 0xbe, 0x02,
           0x75, 0x5d, 0x05, 0xab, 0xbe, 0x0a, 0x55, 0x5f, 0x07, 0xab, 0xaf, 0x00,
           0xd6, 0x57, 0x01, 0xac, 0xab, 0x00, 0xd8, 0x57, 0x00, 0xb0, 0xaa, 0x00,
           0x50, 0x55, 0x00, 0xb0, 0x0b, 0x00, 0xd0, 0x17, 0x00, 0xb0, 0x0b, 0x00,
           0x58, 0x15, 0x00, 0xa8, 0x2a, 0x00};
    }]
    .b configure -image $myquesthead
    set expectedwidth [expr {[image width $myquesthead] + 2*[.b cget -borderwidth] \
            + 2*[.b cget -highlightthickness]}]

    incr expectedwidth 2   ; # added (hardcoded) in tkUnixButton.c
    lappend result [expr {$expectedwidth == [winfo reqwidth .b]}]
    set expectedheight [expr {[image height $myquesthead] + 2*[.b cget -borderwidth] \
            + 2*[.b cget -highlightthickness]}]
    incr expectedheight 2   ; # added (hardcoded) in tkUnixButton.c
    lappend result [expr {$expectedheight == [winfo reqheight .b]}]
} -cleanup {
    destroy .b
} -result {1 1 1 1}

test button-5.25 {ConfigureButton - computing geometry} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
} -body {
    .b configure -text "Button 1"
    set old [winfo reqwidth .b]
    .b configure -text "Much longer text"
    set new [winfo reqwidth .b]
    expr {$old == $new}
} -cleanup {
    destroy .b
} -result 0

test button-6.1 {ButtonEventProc procedure} -body {

    button .b -text "Test Button" -command {
	   destroy .b
	   set x [list [winfo exists .b] [info commands .b]]
}
    .b invoke
    return $x
} -cleanup {
    destroy .b
} -result {0 {}}

test button-6.2 {ButtonEventProc procedure} -setup {
    set x {}
} -body {
    button .b1 -bg #543210
    rename .b1 .b2

    lappend x [winfo children .]
    lappend x [.b2 cget -bg]
    destroy .b1
    lappend x [info command .b*] [winfo children .]
} -cleanup {
    destroy .b1
} -result {.b1 #543210 {} {}}

test button-7.1 {ButtonCmdDeletedProc procedure} -body {

    button .b
    rename .b {}
    list [info command .b*] [winfo children .]
} -cleanup {
    destroy .b
} -result {{} {}}

test button-8.1 {TkInvokeButton procedure} -setup {

    set x 0
} -body {
    checkbutton .c -variable x
    set result $x
    .c invoke
    lappend result $x
    .c invoke
    lappend result $x
} -cleanup {
    destroy .c
} -result {0 1 0}

test button-8.2 {TkInvokeButton procedure} -setup {

    set x 0
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace

} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.3 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -result 1
test button-8.4 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace

} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.5 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -result 0

test button-8.6 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    radiobutton .r -variable x -value red
    set result $x
    .r invoke
    lappend result $x
    .r invoke
    lappend result $x
} -cleanup {
    destroy .r
} -result {0 red red}

test button-8.7 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace variable x w bogusTrace
    .r invoke
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.8 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace variable x w bogusTrace
    catch {.r invoke}
    list $errorInfo $x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace

} -match {glob} -result {{*trace aborted
    while executing
*
".r invoke"} red}

#ex 9.6
test button-8.9 {TkInvokeButton procedure} -setup {

    set result untouched
} -body {
    button .b -command {set result invoked}
    set msg [.b invoke]
    list $msg $result
} -cleanup {
    destroy .b
} -result {invoked invoked}
test button-8.10 {TkInvokeButton procedure} -setup {

    set result untouched
    set x 0
} -body {
    checkbutton .c -variable x -command {set result "invoked $x"}
    set msg [.c invoke]
    list $msg $result
} -cleanup {
    destroy .c
} -result {{invoked 1} {invoked 1}}
test button-8.11 {TkInvokeButton procedure} -setup {

    set result untouched
    set x 0
} -body {
    radiobutton .r -variable x -value red -command {set result "invoked $x"}
    set msg [.r invoke]
    list $msg $result
} -cleanup {
    destroy .r
} -result {{invoked red} {invoked red}}

test button-9.1 {ButtonVarProc procedure} -body {

    set x 1
    checkbutton .c -variable x
    unset x
    set result [info exists x]
    .c toggle
    lappend result $x
    set x 0
    .c toggle
    lappend result $x
} -cleanup {
    destroy .c
} -result {0 1 1}
test button-9.2 {ButtonVarProc procedure} -body {

    set x 0
    checkbutton .c -variable x
    set x 44
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 1
test button-9.3 {ButtonVarProc procedure} -setup {

    set x 1
} -body {
    checkbutton .c -variable x
    set x 44
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 1
test button-9.4 {ButtonVarProc procedure} -setup {

    set x 0
} -body {
    checkbutton .c -variable x
    set x 1
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 0
test button-9.5 {ButtonVarProc procedure} -setup {

    set x 1
} -body {
    checkbutton .c -variable x
    set x 1
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 0
test button-9.6 {ButtonVarProc procedure} -setup {

    set x 0
} -body {
    checkbutton .c -variable x
    set x 0
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 1
test button-9.7 {ButtonVarProc procedure} -setup {

    set x 1
} -body {
    checkbutton .c -variable x
    set x 0
    .c toggle
    return $x
} -cleanup {
    destroy .c
} -result 1
test button-9.8 {ButtonVarProc procedure, can't read variable} -setup {
# This test does nothing but produce a core dump if there's a prbblem.

    unset -nocomplain a
} -body {
    checkbutton .c -variable a
    unset a
    set a(32) 0
    unset a
} -cleanup {
    destroy .c
} -result {}

test button-10.1 {ButtonTextVarProc procedure} -body {

    set x Label
    button .b -textvariable x
    unset x
    set result [list $x [.b cget -text]]
    set x New
    lappend result [.b cget -text]
} -cleanup {
    destroy .b
} -result {Label Label New}
test button-10.2 {ButtonTextVarProc procedure} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
} -body {

# Windows buttons have a default min width, so we have to
# set this to be longer to force the wider button.
    set x ExtraLongLabel
    .b configure -textvariable x
    set old [winfo reqwidth .b]
    set x New
    set new [winfo reqwidth .b]
    expr {$old == $new}
} -cleanup {
    destroy .b
} -result 0

test button-11.1 {ButtonImageProc procedure} -constraints {
    testImageType
} -setup {
    label .l -highlightthickness 0 -font {Helvetica -12 bold}
    image create test image1
} -body {
    .l configure -image image1 -padx 0 -pady 0 -bd 0
    pack .l
    set result "[winfo reqwidth .l] [winfo reqheight .l]"
    image1 changed 0 0 0 0 80 100
    lappend result [winfo reqwidth .l] [winfo reqheight .l]
} -cleanup {
    destroy .l
    image delete image1
} -result {30 15 80 100}


test button-12.1 {button widget vs hidden commands} -body {

    button .b -text hello
    set l [interp hidden]
    interp hide {} .b
    destroy .b

    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 == $res2}
} -cleanup {
    destroy .b
} -result 1

test button-13.1 {size behavior: label} -setup {
    label .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    label .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    label .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}
test button-13.2 {size behavior: label} -setup {
    label .a -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    label .b -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    label .c -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-13.3 {size behavior: button} -setup {
    button .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    button .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}
test button-13.4 {size behavior: button} -setup {
    button .a -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    button .b -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    button .c -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-13.5 {size behavior: radiobutton} -setup {
    radiobutton .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    radiobutton .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    radiobutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-13.6 {size behavior: radiobutton} -setup {
    radiobutton .a -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    radiobutton .b -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    radiobutton .c -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-13.7 {size behavior: checkbutton} -setup {
    checkbutton .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    checkbutton .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-13.8 {size behavior: checkbutton} -setup {
    checkbutton .a -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    checkbutton .b -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Arial 20}
    set result {}
} -body {
	.a configure -text Hej
	.b configure -text Hej -width 10 -height 1
	.c configure -text "" -width 10 -height 1

# With -width, width should not be affected by text change
	lappend result [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
# With -height, height should not be affected by text change
	lappend result [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
# A one line text should be as high as -height 1
	lappend result [expr {[winfo reqheight .a] == [winfo reqheight .b]}]
} -cleanup {
    destroy .a .b .c
} -result {1 1 1}

test button-14.1 {bug fix: [011706ec42] tk::ButtonInvoke unsafe wrt widget destruction} -body {
    proc destroy_button {} {
        if {[winfo exists .top.b]} {
            destroy .top.b
        }
    }
    toplevel .top
    button .top.b -text Foo -command destroy_button
    bind .top.b <space> destroy_button
    pack .top.b
    focus -force .top.b
    update
    event generate .top.b <space>
    update  ; # shall not trigger error  invalid command name ".top.b"
} -cleanup {
    destroy .top.b .top
} -result {}

test button-15.1 {Bug [5d991b822e]} {
    # Want this not to segfault
    set var INIT
    button .b -textvariable var
    trace add variable var unset {apply {args {
	.b configure -textvariable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
} {}
test button-15.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    button .b -textvariable var
    trace add variable var unset {apply {args {
	.b configure -textvariable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}
test button-15.3 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    checkbutton .b -variable var
    trace add variable var unset {apply {args {
	.b configure -variable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
} {}


imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:




|
|
|



<


<




|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
>
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
<
>
|
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
|
<
|
>


<
<
|
|
>


<
<
|
|
>


<
<
|
|
>


<
<
|
<
|
>
>


|
<
|
<
<
|
|
<
<
|
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|


|
<
|
<
<
|
>
|
|
<
<
<
|
<
<
<

<
<
|
>
|

<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
<
<
|
<
>
|
|
<
<
|
<
|
|
|
|
>
|
<
|
<
<
|
<
|
<
|
|
<
<
|
<
|
<
<
|
<
|
<
|
|
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
<
|
<

|
<
<
|
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<



<
<
|
>
>
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
<
|
<
|

|
|
<
<
|
<
|

|
<
<
|
|
<
|

<
<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
|
|
|
<
<
|
|
|



|
<
|
|
|
<
<
|
<
<
<
|
<
<
<
<
<
<
|



<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
>
|
|
|
<
|
<
<
|
|
<
<
<
<
<
<
<



|
<
<
|
|
<



|
<
<
|
|
|
|
|


|
<
<
|
|
>
|
<


|
<
<
|
<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
>

|
<
<
|
|
<
|
>

|
<
<
|
|
<
|
|
|
<
<
|
<
<
<
|
<
<
<
<
<
<
|



<
<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
|
|

|

|

|
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|



|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|



|
<
<
<
|
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
|

|

|
<
<

<
<









|
<
<
<

|
<
<
<
|
<
<
|
>
|
|
<
<
|
|
|


>
|

|
<
<
|
|
<
<
|
<
<
<
<
|
>
>
|
>
>
>
|
|
|
|
<
|


<
|

|
|
<
<
<
|
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
|
|
|
|
>
>
|
|
<
|
<
|
|
>
|
|
|
<
<
|
<
<
<
|
<
|
|
<
<
<
|
|
<
<
<
<
|
<
<
<
|
<

|
<

|
|
|
<
|
<
|
<
<
|
>
|
|
|
|
<
<
<
<
<
<
<
|
|
<
<
|
<
|
<
<
<
|
|
<
|
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
|
|
>
|
>
|
|
<
|
<
<


|
|
|
<
<
<
|
|
<
<
<
<
>
|
<
<
<
<
<
<
>
|
<
<
>
|
<
>
>
|
|

|
<
|
<
|
>
>
|
|
>
>
|
>
>
>
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
|
|
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<

|
>
|
|
|
|
|
|
<
<
|
<
|
|
<


>




<
<
|

|
>
|
|

<
<
|

|
>

<
|

|

|

<
<
|
<
|
>

<
|

|
<
<

>
|
|
<
<
<
<
<
<
<
|
<
<
<

<
|

|
<
<

>
|
|
<
<
<
<
<
<
<
|
<
<
<
<

<
|

|

|

<
<
|
<
|
<
<
<
<
<
|
<
<
<
|


|
<
<
<

>
|


|
<
<
|
>

<
|
<
|
<
<
|
|
>


<
|
<
|
<
<
|
|
>


<
|
<
|
<
<
|

|
>

|


|


|

<
<
|
|
>

|

|
|
|
<
<
|
>

<
|

|
|
|
<
<
|
>

<
|

|
|
<
<
|
|
>

<
|

|
|
|
<
<
|
>

<
|

|
|
|
<
<
|
>

<
|

|
|
|
<
<
|
|
>
|
<
|



|
<
<

|
>

|

|

|
<
<
|
|
<
<
>
|
|

|
|

|
|
|
<
<

|
|
|
<

<
|
|
|

|
|
|
|
<
>

|
>

<


<
|
|
<
<
<
<

<
<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<

<
<
<
<
<
<
|
|
|

|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
|
|
|
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<

<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<


<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12

13
14
15
16
17



18








































































19

20
21










































































22
23
24









25


















































































26




27




28




29











































30


31
32






33









34
35










36











37































































38


39


40





41












42




43














44








































45









46

























47


















48






















49





50








51









52








53
54

































































55












56






































57


















58































































59












60
61





62



















































































63





64

65
















66






































67











68
































































69


















70


71








72
73












































74





































75









76














77













78































79
80











































81


82







































83

































84















































85


86
87





88


















89
90



































































































































91









92








93


94












95


















96






97















98












99

























100










101










102

























































103


104
















































105
106
107
108

109




110














111






112


















113







114










































115































































116
117









118












119















120












121






































122

123






124




125


126





























127















128

















129




130





































131





132



133






















134







135








































136
137
138

139
140


141








142


































































































































































































































































143












































































144








145


146
147

148
149
150
151


152
153
154
155
156


157
158
159
160
161


162
163
164
165
166


167

168
169
170
171
172
173

174


175
176


177

178




179


180
181




182
183
184
185

186


187
188
189
190



191



192


193
194
195
196

197

198


199
200

201


202
203

204


205
206

207


208
209

210


211


212

213
214
215


216

217
218
219
220
221
222

223


224

225

226
227


228

229


230

231

232
233


234

235


236








237

238
239


240

241


242
243


244


245
246


247
248
249


250
251
252
253

254


255
256

257


258
259

260


261

262

263
264
265
266


267

268
269
270


271
272

273
274




275





276



277

278
279
280


281
282
283
284
285
286
287

288
289
290


291



292






293
294
295
296

297

298


299
300

301


302
303

304
305


306

307
308


309

310
311

312
313
314
315

316


317
318







319
320
321
322


323
324

325
326
327
328


329
330
331
332
333
334
335
336


337
338
339
340

341
342
343


344

345

346


347
348

349


350
351

352


353
354

355
356
357
358


359
360

361
362
363
364


365
366

367
368
369


370



371






372
373
374
375


376

377


378
379

380


381
382

383


384
385

386


387
388
389
390
391
392
393
394
395
396



397
398
399
400
401









402


403
404
405
406
407
408
409
410
411
412









413


414
415
416
417
418
419
420



421

422







423
424




425
426
427
428
429


430


431
432
433
434
435
436
437
438
439
440



441
442



443


444
445
446
447


448
449
450
451
452
453
454
455
456


457
458


459




460
461
462
463
464
465
466
467
468
469
470

471
472
473

474
475
476
477



478

479



480




481









482




483
484





485
486
487
488
489
490
491
492

493

494
495
496
497
498
499


500



501

502
503



504
505




506



507

508
509

510
511
512
513

514

515


516
517
518
519
520
521







522
523


524

525



526
527

528

529




530

531


532

533

534
535
536
537
538
539
540
541

542


543
544
545
546
547



548
549




550
551






552
553


554
555

556
557
558
559
560
561

562

563
564
565
566
567
568
569
570
571
572
573
574
575




576








577
578








579
580


581
582













583
584
585
586
587


588
589
590
591
592
593
594
595
596


597

598
599

600
601
602
603
604
605
606


607
608
609
610
611
612
613


614
615
616
617
618

619
620
621
622
623
624


625

626
627
628

629
630
631


632
633
634
635







636



637

638
639
640


641
642
643
644







645




646

647
648
649
650
651
652


653

654





655



656
657
658
659



660
661
662
663
664
665


666
667
668

669

670


671
672
673
674
675

676

677


678
679
680
681
682

683

684


685
686
687
688
689
690
691
692
693
694
695
696
697


698
699
700
701
702
703
704
705
706


707
708
709

710
711
712
713
714


715
716
717

718
719
720
721


722
723
724
725

726
727
728
729
730


731
732
733

734
735
736
737
738


739
740
741

742
743
744
745
746


747
748
749
750

751
752
753
754
755


756
757
758
759
760
761
762
763
764


765
766


767
768
769
770
771
772
773
774
775
776


777
778
779
780

781

782
783
784
785
786
787
788
789

790
791
792
793
794

795
796

797
798




799




800




801









802



803




804







805

806






807
808
809
810
811












812





813
814
815
816
817
818



819









820









821






822
823


















824


825









826




827




828














829






830





831



832

































833
834

835
836




# This file is a Tcl script to test labels, buttons, checkbuttons, and
# radiobuttons in Tk (i.e., all the widgets defined in tkButton.c).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


proc bogusTrace args {
    error "trace aborted"
}
catch {unset value}



catch {unset value2}










































































# Create entries in the option database to be sure that geometry options
# like border width have predictable values.











































































option add *Button.borderWidth 2
option add *Button.highlightThickness 2









option add *Button.font {Helvetica -12 bold}























































































eval image delete [image names]




if {[testConstraint testImageType]} {




    image create test image1











































}


label .l -text Label
button .b -text Button






checkbutton .c -text Checkbutton









radiobutton .r -text Radiobutton
pack .l .b .c .r










update











set i 1































































foreach test {


    {-activebackground #012345 #012345 non-existent


	    {unknown color name "non-existent"} {1 1 1 1}}





    {-activeforeground #ff0000 #ff0000 non-existent












	    {unknown color name "non-existent"} {1 1 1 1}}




    {-anchor nw nw bogus














	    {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}








































	    {1 1 1 1}}









    {-background #ff0000 #ff0000 non-existent

























	    {unknown color name "non-existent"} {1 1 1 1}}


















    {-bd 4 4 badValue {bad screen distance "badValue"} {1 1 1 1}}






















    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}





	    {1 1 1 1}}








    {-bitmap questhead questhead badValue {bitmap "badValue" not defined}









	    {1 1 1 1}}








    {-borderwidth 1.3 1.3 badValue {bad screen distance "badValue"} {1 1 1 1}}
    {-command "set x" {set x} {} {} {0 1 1 1}}

































































    {-compound left left bogus












	    {bad compound "bogus": must be bottom, center, left, none, right, or top}






































	    {1 1 1 1}}


















    {-cursor arrow arrow badValue {bad cursor spec "badValue"} {1 1 1 1}}































































    {-default active active huh?












	    {bad default "huh?": must be active, disabled, or normal}
	    {0 1 0 0}}





    {-disabledforeground #00ff00 #00ff00 xyzzy {unknown color name "xyzzy"}



















































































	    {1 1 1 1}}





    {-fg #110022 #110022 bogus {unknown color name "bogus"} {1 1 1 1}}

    {-font {Helvetica 12} {Helvetica 12} {} {font "" doesn't exist} {1 1 1 1}}
















    {-foreground #110022 #110022 bogus {unknown color name "bogus"} {1 1 1 1}}






































    {-height 18 18 20.0 {expected integer but got "20.0"} {1 1 1 1}}











    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}
































































	    {1 1 1 1}}


















    {-highlightcolor #110022 #110022 bogus {unknown color name "bogus"}


	    {1 1 1 1}}








    {-highlightthickness 6m 6m badValue {bad screen distance "badValue"}
	    {1 1 1 1}}












































    {-image image1 image1 bogus {image "bogus" doesn't exist} {1 1 1 1}}





































    {-indicatoron yes 1 no_way {expected boolean value but got "no_way"}









	    {0 0 1 1}}














    {-justify right right bogus













	    {bad justification "bogus": must be left, right, or center}































	    {1 1 1 1}}
    {-offrelief flat flat 1.5











































	    {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}


	    {0 0 1 1}}







































    {-offvalue lousy lousy {} {} {0 0 1 0}}

































    {-onvalue fantastic fantastic {} {} {0 0 1 0}}















































    {-overrelief "" "" 1.5


	    {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
	    {0 1 1 1}}





    {-padx 12m 12m 420x {bad screen distance "420x"} {1 1 1 1}}


















    {-pady 12m 12m 420x {bad screen distance "420x"} {1 1 1 1}}
    {-repeatdelay 100 100 foo {expected integer but got "foo"} {0 1 0 0}}



































































































































    {-repeatinterval 100 100 foo {expected integer but got "foo"} {0 1 0 0}}









    {-relief flat flat 1.5








	    {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}


	    {1 1 1 1}}












    {-selectcolor #110022 #110022 bogus {unknown color name "bogus"} {0 0 1 1}}


















    {-selectimage image1 image1 bogus {image "bogus" doesn't exist} {0 0 1 1}}






    {-state normal normal bogus















	    {bad state "bogus": must be active, disabled, or normal}












	    {1 1 1 1}}

























    {-takefocus "any string" "any string" {} {} {1 1 1 1}}










    {-text "Sample text" {Sample text} {} {} {1 1 1 1}}










    {-textvariable i i {} {} {1 1 1 1}}

























































    {-tristateimage image1 image1 bogus {image "bogus" doesn't exist}


	    {0 0 1 1}}
















































    {-tristatevalue unknowable unknowable {} {} {0 0 1 1}}
    {-underline 5 5 3p {expected integer but got "3p"} {1 1 1 1}}
    {-value anyString anyString {} {} {0 0 0 1}}
    {-width 402 402 3p {expected integer but got "3p"} {1 1 1 1}}

    {-wraplength 100 100 6x {bad screen distance "6x"} {1 1 1 1}}




} {














    lassign $test name value okResult badValue badResult classes






    foreach w {.l .b .c .r} hasOption $classes {


















	set classname [winfo class $w]







	if {$hasOption} {










































	    test button-1.$i "configuration option $name for $classname" \































































		-constraints testImageType -body "
		    $w configure $name [list $value]









		    lindex \[$w configure $name] 4












		" -result $okResult















	    incr i












	    if {$badValue ne ""} {






































		test button-1.$i "configuration option $name for $classname" \

		    -constraints testImageType \






		    -body [list $w configure $name $badValue] \




		    -returnCodes error -result $badResult


		incr i





























	    }















	    $w configure $name [lindex [$w configure $name] 3]

















	} else {




	    test button-1.$i "configuration option $name for $classname" \





































		-constraints testImageType \





		-body [list $w configure $name $value] \



		-returnCodes error -result "unknown option \"$name\""






















	    incr i







	}








































    }
}
test button-1.$i {configuration options} {

    # Additional check to make sure that -selectcolor may be empty in
    # checkbox widgets


    .c configure -selectcolor {}








} {}















































































































































































































































































































































test button-3.1 {ButtonCreate - not enough cd ../unix








} {


    list [catch {button} msg] $msg
} {1 {wrong # args: should be "button pathName ?options?"}}

test button-3.2 {ButtonCreate procedure - setting label class} {
    catch {destroy .x}
    label .x
    winfo class .x


} {Label}
test button-3.3 {ButtonCreate - setting button class} {
    catch {destroy .x}
    button .x
    winfo class .x


} {Button}
test button-3.4 {ButtonCreate - setting checkbutton class} {
    catch {destroy .x}
    checkbutton .x
    winfo class .x


} {Checkbutton}
test button-3.5 {ButtonCreate - setting radiobutton class} {
    catch {destroy .x}
    radiobutton .x
    winfo class .x


} {Radiobutton}

rename button gorp
test button-3.6 {ButtonCreate - setting class} {
    catch {destroy .x}
    gorp .x
    winfo class .x
} {Button}

rename gorp button


test button-3.7 {ButtonCreate - bad window name} {
    list [catch {button foo} msg] $msg


} {1 {bad window path name "foo"}}

test button-3.8 {ButtonCreate procedure - error in default option value} {




    catch {destroy .funny}


    option add *funny.background bogus
    list [catch {button .funny} msg] $msg $errorInfo




} {1 {unknown color name "bogus"} {unknown color name "bogus"
    (database entry for "-background" in widget ".funny")
    invoked from within
"button .funny"}}

test button-3.9 {ButtonCreate procedure - option error} {


    catch {destroy .x}
    list [catch {button .x -gorp foo} msg] $msg [winfo exists .x]
} {1 {unknown option "-gorp"} 0}
test button-3.10 {ButtonCreate procedure - return value} {



    catch {destroy .abcd}



    set x [button .abcd]


    destroy .abc
    set x
} {.abcd}


test button-4.1 {ButtonWidgetCmd - too few arguments} {

    list [catch {.b} msg] $msg


} {1 {wrong # args: should be ".b option ?arg arg ...?"}}
test button-4.2 {ButtonWidgetCmd - bad option name} {

    list [catch {.b c} msg] $msg


} {1 {ambiguous option "c": must be cget, configure, flash, or invoke}}
test button-4.3 {ButtonWidgetCmd - bad option name} {

    list [catch {.b bogus} msg] $msg


} {1 {bad option "bogus": must be cget, configure, flash, or invoke}}
test button-4.4 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.b cget a b} msg] $msg


} {1 {wrong # args: should be ".b cget option"}}
test button-4.5 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.b cget -gorp} msg] $msg


} {1 {unknown option "-gorp"}}


test button-4.6 {ButtonWidgetCmd procedure, "cget" option} {

    .b configure -highlightthickness 3
    .b cget -highlightthickness
} {3}


test button-4.7 {ButtonWidgetCmd procedure, "cget" option} {

    catch {.l cget -disabledforeground}
} {0}
test button-4.8 {ButtonWidgetCmd procedure, "cget" option} {
    catch {.b cget -disabledforeground}
} {0}
test button-4.9 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.b cget -variable} msg] $msg


} {1 {unknown option "-variable"}}

test button-4.10 {ButtonWidgetCmd procedure, "cget" option} {

    catch {.c cget -variable}
} {0}


test button-4.11 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.c cget -value} msg] $msg


} {1 {unknown option "-value"}}

test button-4.12 {ButtonWidgetCmd procedure, "cget" option} {

    catch {.r cget -value}
} {0}


test button-4.13 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.r cget -onvalue} msg] $msg


} {1 {unknown option "-onvalue"}}








test button-4.14 {ButtonWidgetCmd procedure, "configure" option} {

    llength [.c configure]
} {41}


test button-4.15 {ButtonWidgetCmd procedure, "configure" option} {

    list [catch {.b configure -gorp} msg] $msg


} {1 {unknown option "-gorp"}}
test button-4.16 {ButtonWidgetCmd procedure, "configure" option} {


    list [catch {.b co -bg #ffffff -fg} msg] $msg


} {1 {value for "-fg" missing}}
test button-4.17 {ButtonWidgetCmd procedure, "configure" option} {


    .b configure -fg #123456
    .b configure -bg #654321
    lindex [.b configure -fg] 4


} {#123456}
.c configure -variable value -onvalue 1 -offvalue 0
.r configure -variable value2 -value red
test button-4.18 {ButtonWidgetCmd procedure, "deselect" option} {

    list [catch {.c deselect foo} msg] $msg


} {1 {wrong # args: should be ".c deselect"}}
test button-4.19 {ButtonWidgetCmd procedure, "deselect" option} {

    list [catch {.l deselect} msg] $msg


} {1 {bad option "deselect": must be cget or configure}}
test button-4.20 {ButtonWidgetCmd procedure, "deselect" option} {

    list [catch {.b deselect} msg] $msg


} {1 {bad option "deselect": must be cget, configure, flash, or invoke}}

test button-4.21 {ButtonWidgetCmd procedure, "deselect" option} {

    set value 1
    .c d
    set value
} {0}


test button-4.22 {ButtonWidgetCmd procedure, "deselect" option} {

    set value2 green
    .r deselect
    set value2


} {green}
test button-4.23 {ButtonWidgetCmd procedure, "deselect" option} {

    set value2 red
    .r deselect




    set value2





} {}



test button-4.24 {ButtonWidgetCmd procedure, "deselect" option} -body {

    set value 1
    trace variable value w bogusTrace
    set result [list [catch {.c deselect} msg] $msg $errorInfo $value]


    trace vdelete value w bogusTrace
    set result
} -match glob -result {1 {can't set "value": trace aborted} {*trace aborted
    while executing
*
".c deselect"} 0}
test button-4.25 {ButtonWidgetCmd procedure, "deselect" option} -body {

    set value2 red
    trace variable value2 w bogusTrace
    set result [list [catch {.r deselect} msg] $msg $errorInfo $value2]


    trace vdelete value2 w bogusTrace



    set result






} -match glob -result {1 {can't set "value2": trace aborted} {*trace aborted
    while executing
*
".r deselect"} {}}

test button-4.26 {ButtonWidgetCmd procedure, "flash" option} {

    list [catch {.b flash foo} msg] $msg


} {1 {wrong # args: should be ".b flash"}}
test button-4.27 {ButtonWidgetCmd procedure, "flash" option} {

    list [catch {.l flash} msg] $msg


} {1 {bad option "flash": must be cget or configure}}
test button-4.28 {ButtonWidgetCmd procedure, "flash" option} {

    list [catch {.b flash} msg] $msg
} {0 {}}


test button-4.29 {ButtonWidgetCmd procedure, "flash" option} {

    list [catch {.c flash} msg] $msg
} {0 {}}


test button-4.30 {ButtonWidgetCmd procedure, "flash" option} {

    list [catch {.r f} msg] $msg
} {0 {}}

test button-4.31 {ButtonWidgetCmd procedure, "invoke" option} {
    list [catch {.b invoke foo} msg] $msg
} {1 {wrong # args: should be ".b invoke"}}
test button-4.32 {ButtonWidgetCmd procedure, "invoke" option} {

    list [catch {.l invoke} msg] $msg


} {1 {bad option "invoke": must be cget or configure}}
test button-4.33 {ButtonWidgetCmd procedure, "invoke" option} {







    .b configure -command {set x invoked}
    set x "not invoked"
    .b invoke
    set x


} {invoked}
test button-4.34 {ButtonWidgetCmd procedure, "invoke" option} {

    .b configure -command {set x invoked} -state disabled
    set x "not invoked"
    .b invoke
    set x


} {not invoked}
test button-4.35 {ButtonWidgetCmd procedure, "invoke" option} {
    set value bogus
    .c configure -command {set x invoked} -variable value -onvalue 1 \
	    -offvalue 0
    set x "not invoked"
    .c invoke
    list $x $value


} {invoked 1}
test button-4.36 {ButtonWidgetCmd procedure, "invoke" option} {
    set value2 green
    .r configure -command {set x invoked} -variable value2 -value red

    set x "not invoked"
    .r i
    list $x $value2


} {invoked red}

test button-4.37 {ButtonWidgetCmd procedure, "select" option} {

    list [catch {.l select} msg] $msg


} {1 {bad option "select": must be cget or configure}}
test button-4.38 {ButtonWidgetCmd procedure, "select" option} {

    list [catch {.b select} msg] $msg


} {1 {bad option "select": must be cget, configure, flash, or invoke}}
test button-4.39 {ButtonWidgetCmd procedure, "select" option} {

    list [catch {.c select foo} msg] $msg


} {1 {wrong # args: should be ".c select"}}
test button-4.40 {ButtonWidgetCmd procedure, "select" option} {

    set value bogus
    .c configure -command {} -variable value -onvalue lovely -offvalue 0
    .c s
    set value


} {lovely}
test button-4.41 {ButtonWidgetCmd procedure, "select" option} {

    set value2 green
    .r configure -command {} -variable value2 -value red
    .r select
    set value2


} {red}
test button-4.42 {ButtonWidgetCmd procedure, "select" option} -body {

    set value2 yellow
    trace variable value2 w bogusTrace
    set result [list [catch {.r select} msg] $msg $errorInfo $value2]


    trace vdelete value2 w bogusTrace



    set result






} -match glob -result {1 {can't set "value2": trace aborted} {*trace aborted
    while executing
*
".r select"} red}


test button-4.43 {ButtonWidgetCmd procedure, "toggle" option} {

    list [catch {.l toggle} msg] $msg


} {1 {bad option "toggle": must be cget or configure}}
test button-4.44 {ButtonWidgetCmd procedure, "toggle" option} {

    list [catch {.b toggle} msg] $msg


} {1 {bad option "toggle": must be cget, configure, flash, or invoke}}
test button-4.45 {ButtonWidgetCmd procedure, "toggle" option} {

    list [catch {.r toggle} msg] $msg


} {1 {bad option "toggle": must be cget, configure, deselect, flash, invoke, or select}}
test button-4.46 {ButtonWidgetCmd procedure, "toggle" option} {

    list [catch {.c toggle foo} msg] $msg


} {1 {wrong # args: should be ".c toggle"}}
test button-4.47 {ButtonWidgetCmd procedure, "toggle" option} {
    set value bogus
    .c configure -command {} -variable value -onvalue sunshine -offvalue rain
    .c toggle
    set result $value
    .c toggle
    lappend result $value
    .c toggle
    lappend result $value



} {sunshine rain sunshine}
test button-4.48 {ButtonWidgetCmd procedure, "toggle" option} -body {
    .c configure -onvalue xyz -offvalue abc
    set value xyz
    trace variable value w bogusTrace









    set result [list [catch {.c toggle} msg] $msg $errorInfo $value]


    trace vdelete value w bogusTrace
    set result
} -match glob -result {1 {can't set "value": trace aborted} {*trace aborted
    while executing
*
".c toggle"} abc}
test button-4.49 {ButtonWidgetCmd procedure, "toggle" option} -body {
    .c configure -onvalue xyz -offvalue abc
    set value abc
    trace variable value w bogusTrace









    set result [list [catch {.c toggle} msg] $msg $errorInfo $value]


    trace vdelete value w bogusTrace
    set result
} -match glob -result {1 {can't set "value": trace aborted} {*trace aborted
    while executing
*
".c toggle"} xyz}
test button-4.50 {ButtonWidgetCmd procedure, "toggle" option} {



    catch {unset value}; set value(1) 1;

    set result [list [catch {.c toggle} msg] $msg $errorInfo]







    unset value;
    set result




} {1 {can't set "value": variable is array} {can't set "value": variable is array
    while executing
".c toggle"}}

test button-5.1 {DestroyButton procedure} testImageType {


    image create test image1


    button .b1 -image image1
    button .b2 -fg #ff0000 -text "Button 2"
    button .b3 -state active -text "Button 3"
    button .b4 -disabledforeground #0000ff -state disabled -text "Button 4"
    checkbutton .b5 -variable x -text "Checkbutton 5"
    set x 1
    pack .b1 .b2 .b3 .b4 .b5
    update
    deleteWindows
} {}




test button-6.1 {ConfigureButton - textvariable trace} {



    catch {destroy .b1}


    button .b1 -bd 4 -bg green
    catch {.b1 configure -bd 7 -bg green -fg bogus}
    list [catch {.b1 configure -bd 7 -bg red -fg bogus} msg] \
	    $msg [.b1 cget -bd] [.b1 cget -bg]


} {1 {unknown color name "bogus"} 4 green}
test button-6.2 {ConfigureButton - textvariable trace} {
    catch {destroy .b1}
    set x From-x
    set y From-y
    button .b1 -textvariable x
    .b1 configure -textvariable y
    set x New
    lindex [.b1 configure -text] 4


} {From-y}
test button-6.2a {ConfigureButton - variable traces} {


    catch {destroy .b1}




    catch {unset x}
    checkbutton .b1 -variable x
    set x 1
    set y 1
    .b1 configure -textvariable y
    set x 0
    .b1 toggle
    set y
} {1}
test button-6.3 {ConfigureButton - image handling} testImageType {
    catch {destroy .b1}

    eval image delete [image names]
    image create test image1
    image create test image2

    button .b1 -image image1
    image delete image1
    .b1 configure -image image2
    image names



} {image2}

test button-6.5 {ConfigureButton - default value for variable} {



    catch {destroy .b1}




    checkbutton .b1









    .b1 cget -variable




} {b1}
test button-6.6 {ConfigureButton - setting selected state from variable} {





    catch {destroy .b1}
    set x 0
    set y Shiny
    checkbutton .b1 -variable x
    .b1 configure -variable y -onvalue Shiny
    .b1 toggle
    set y
} 0

test button-6.7 {ConfigureButton - setting selected state from variable} {

    catch {destroy .b1}
    catch {unset x}
    checkbutton .b1 -variable x -offvalue Bogus
    set x
} Bogus
test button-6.8 {ConfigureButton - setting selected state from variable} {


    catch {destroy .b1}



    catch {unset x}

    radiobutton .b1 -variable x
    set x



} {}
test button-6.9 {ConfigureButton - error in setting variable} {




    catch {destroy .b1}



    catch {unset x}

    trace variable x w bogusTrace
    set result [list [catch {radiobutton .b1 -variable x} msg] $msg]

    trace vdelete x w bogusTrace
    set result
} {1 {can't set "x": trace aborted}}
test button-6.10 {ConfigureButton - bad image name} {

    catch {destroy .b1}

    list [catch {button .b1 -image bogus} msg] $msg


} {1 {image "bogus" doesn't exist}}
test button-6.11 {ConfigureButton - setting variable from current text value} {
    catch {destroy .b1}
    catch {unset x}
    button .b1 -textvariable x -text "Button 1"
    set x







} {Button 1}
test button-6.12 {ConfigureButton - using current value of variable} {


    catch {destroy .b1}

    set x Override



    button .b1 -textvariable x -text "Button 1"
    set x

} {Override}

test button-6.13 {ConfigureButton - variable handling} {




    catch {destroy .b1}

    catch {unset x}


    trace variable x w bogusTrace

    set result [list [catch {radiobutton .b1 -text foo -textvariable x} msg] \

	    $msg $x]
    trace vdelete x w bogusTrace
    set result
} {1 {can't set "x": trace aborted} foo}
test button-6.14 {ConfigureButton - -width option} {
    catch {destroy .b1}
    button .b1 -text "Button 1"
    list [catch {.b1 configure -width 1i} msg] $msg $errorInfo

} {1 {expected integer but got "1i"} {expected integer but got "1i"


    (processing -width option)
    invoked from within
".b1 configure -width 1i"}}
test button-6.15 {ConfigureButton - -height option} {
    catch {destroy .b1}



    button .b1 -text "Button 1"
    list [catch {.b1 configure -height 0.5c} msg] $msg $errorInfo




} {1 {expected integer but got "0.5c"} {expected integer but got "0.5c"
    (processing -height option)






    invoked from within
".b1 configure -height 0.5c"}}


test button-6.16 {ConfigureButton - -width option} {
    catch {destroy .b1}

    button .b1 -bitmap questhead
    list [catch {.b1 configure -width abc} msg] $msg $errorInfo
} {1 {bad screen distance "abc"} {bad screen distance "abc"
    (processing -width option)
    invoked from within
".b1 configure -width abc"}}

test button-6.17 {ConfigureButton - -height option} testImageType {

    catch {destroy .b1}
    eval image delete [image names]
    image create test image1
    button .b1 -image image1
    list [catch {.b1 configure -height 0.5x} msg] $msg $errorInfo
} {1 {bad screen distance "0.5x"} {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".b1 configure -height 0.5x"}}
test button-6.18 {ConfigureButton - computing geometry} {nonPortable fonts} {
    catch {destroy .b1}
    button .b1 -text "Sample text" -width 10 -height 2
    pack .b1




    set result "[winfo reqwidth .b1] [winfo reqheight .b1]"








    .b1 configure -bitmap questhead
    lappend result [winfo reqwidth .b1] [winfo reqheight .b1]








} {102 46 20 12}
test button-6.19 {ConfigureButton - computing geometry} {


    catch {destroy .b1}
    button .b1 -text "Button 1"













    set old [winfo reqwidth .b1]
    .b1 configure -text "Much longer text"
    set new [winfo reqwidth .b1]
    expr $old == $new
} {0}



test button-7.1 {ButtonEventProc procedure} {
    catch {destroy .b1}
    button .b1 -text "Test Button" -command {
	destroy .b1
	set x [list [winfo exists .b1] [info commands .b1]]
    }
    .b1 invoke
    set x


} {0 {}}

test button-7.2 {ButtonEventProc procedure} {
    deleteWindows

    button .b1 -bg #543210
    rename .b1 .b2
    set x {}
    lappend x [winfo children .]
    lappend x [.b2 cget -bg]
    destroy .b1
    lappend x [info command .b*] [winfo children .]


} {.b1 #543210 {} {}}

test button-8.1 {ButtonCmdDeletedProc procedure} {
    deleteWindows
    button .b1
    rename .b1 {}
    list [info command .b*] [winfo children .]


} {{} {}}

test button-9.1 {TkInvokeButton procedure} {
    catch {destroy .b1}
    set x 0

    checkbutton .b1 -variable x
    set result $x
    .b1 invoke
    lappend result $x
    .b1 invoke
    lappend result $x


} {0 1 0}

test button-9.2 {TkInvokeButton procedure} {
    catch {destroy .b1}
    set x 0

    checkbutton .b1 -variable x
    trace variable x w bogusTrace
    set result [list [catch {.b1 invoke} msg] $msg $x]


    trace vdelete x w bogusTrace
    set result
} {1 {can't set "x": trace aborted} 1}
test button-9.3 {TkInvokeButton procedure} {







    catch {destroy .b1}



    set x 1

    checkbutton .b1 -variable x
    trace variable x w bogusTrace
    set result [list [catch {.b1 invoke} msg] $msg $x]


    trace vdelete x w bogusTrace
    set result
} {1 {can't set "x": trace aborted} 0}
test button-9.4 {TkInvokeButton procedure} {







    catch {destroy .b1}




    set x 0

    radiobutton .b1 -variable x -value red
    set result $x
    .b1 invoke
    lappend result $x
    .b1 invoke
    lappend result $x


} {0 red red}

test button-9.5 {TkInvokeButton procedure} -body {





    catch {destroy .b1}



    radiobutton .b1 -variable x -value red
    set x green
    trace variable x w bogusTrace
    set result [list [catch {.b1 invoke} msg] $msg $errorInfo $x]



    trace vdelete x w bogusTrace
    set result
} -match glob -result {1 {can't set "x": trace aborted} {*trace aborted
    while executing
*
".b1 invoke"} red}


test button-9.6 {TkInvokeButton procedure} {
    deleteWindows
    set result untouched

    button .b1 -command {set result invoked}

    list [catch {.b1 invoke} msg] $msg $result


} {0 invoked invoked}
test button-9.7 {TkInvokeButton procedure} {
    deleteWindows
    set result untouched
    set x 0

    checkbutton .b1 -variable x -command {set result "invoked $x"}

    list [catch {.b1 invoke} msg] $msg $result


} {0 {invoked 1} {invoked 1}}
test button-9.8 {TkInvokeButton procedure} {
    deleteWindows
    set result untouched
    set x 0

    radiobutton .b1 -variable x -value red -command {set result "invoked $x"}

    list [catch {.b1 invoke} msg] $msg $result


} {0 {invoked red} {invoked red}}

test button-10.1 {ButtonVarProc procedure} {
    deleteWindows
    set x 1
    checkbutton .b1 -variable x
    unset x
    set result [info exists x]
    .b1 toggle
    lappend result $x
    set x 0
    .b1 toggle
    lappend result $x


} {0 1 1}
test button-10.2 {ButtonVarProc procedure} {
    deleteWindows
    set x 0
    checkbutton .b1 -variable x
    set x 44
    .b1 toggle
    set x
} {1}


test button-10.3 {ButtonVarProc procedure} {
    deleteWindows
    set x 1

    checkbutton .b1 -variable x
    set x 44
    .b1 toggle
    set x
} {1}


test button-10.4 {ButtonVarProc procedure} {
    deleteWindows
    set x 0

    checkbutton .b1 -variable x
    set x 1
    .b1 toggle
    set x


} {0}
test button-10.5 {ButtonVarProc procedure} {
    deleteWindows
    set x 1

    checkbutton .b1 -variable x
    set x 1
    .b1 toggle
    set x
} {0}


test button-10.6 {ButtonVarProc procedure} {
    deleteWindows
    set x 0

    checkbutton .b1 -variable x
    set x 0
    .b1 toggle
    set x
} {1}


test button-10.7 {ButtonVarProc procedure} {
    deleteWindows
    set x 1

    checkbutton .b1 -variable x
    set x 0
    .b1 toggle
    set x
} {1}


test button-10.8 {ButtonVarProc procedure, can't read variable} {
    # This test does nothing but produce a core dump if there's a prbblem.
    deleteWindows
    catch {unset a}

    checkbutton .b1 -variable a
    unset a
    set a(32) 0
    unset a
} {}



test button-11.1 {ButtonTextVarProc procedure} {
    deleteWindows
    set x Label
    button .b1 -textvariable x
    unset x
    set result [list $x [lindex [.b1 configure -text] 4]]
    set x New
    lappend result [lindex [.b1 configure -text] 4]


} {Label Label New}
test button-11.2 {ButtonTextVarProc procedure} {


    deleteWindows
    # Windows buttons have a default min width, so we have to
    # set this to be longer to force the wider button.
    set x ExtraLongLabel
    button .b1 -textvariable x
    set old [winfo reqwidth .b1]
    set x New
    set new [winfo reqwidth .b1]
    list [lindex [.b1 configure -text] 4] [expr $old == $new]
} {New 0}



test button-12.1 {ButtonImageProc procedure} testImageType {
    deleteWindows
    eval image delete [image names]

    image create test image1

    label .b1 -image image1 -padx 0 -pady 0 -bd 0
    pack .b1
    set result "[winfo reqwidth .b1] [winfo reqheight .b1]"
    image1 changed 0 0 0 0 80 100
    lappend result [winfo reqwidth .b1] [winfo reqheight .b1]
} {30 15 80 100}

deleteWindows

set l [interp hidden]

test button-13.1 {button widget vs hidden commands} {
    catch {destroy .b}
    button .b -text hello

    interp hide {} .b
    destroy .b

    list [winfo children .] [interp hidden]
} [list {} $l]









deleteWindows














test button-14.1 {size behaviouor} {



    set res {}




    foreach class {label button radiobutton checkbutton} {







	eval destroy [winfo children .]








	$class .a -text Hej
	$class .b -text Hej -width 10 -height 1
	$class .c -text "" -width 10 -height 1

	for {set t 0} {$t < 2} {incr t} {












	    set res2 {}





	    # With -width, width should not be affected by text change
	    lappend res2 [expr {[winfo reqwidth .b] == [winfo reqwidth .c]}]
	    # With -height, height should not be affected by text change
	    lappend res2 [expr {[winfo reqheight .b] == [winfo reqheight .c]}]
	    # A one line text should be as high as -height 1
	    lappend res2 [expr {[winfo reqheight .a] == [winfo reqheight .b]}]



	    lappend res $res2



















	    # Do the second round with another font






	    .a configure -font "Arial 20"
	    .b configure -font "Arial 20"


















	    .c configure -font "Arial 20"


	}









    }




    set res




} {{1 1 1} {1 1 1} {1 1 1} {1 1 1} {1 1 1} {1 1 1} {1 1 1} {1 1 1}}





















deleteWindows









option clear


































# cleanup

cleanupTests
return




Changes to tests/canvImg.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20



21
22

23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185



186


187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
519
520
521
522
523


524
525
526
527
528
529
530

531
532

533
534
535
536
537
538
539

540
541

542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679



680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
# This file is a Tcl script to test out the procedures in tkCanvImg.c,
# which implement canvas "image" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# Canvas used in every test case of the whole file

canvas .c
pack .c
update





test canvImg-1.1 {options for image items} -body {

    .c create image 50 50 -anchor nw -tags i1
    .c itemconfigure i1 -anchor
} -cleanup {
    .c delete all
} -result {-anchor {} {} center nw}
test canvImg-1.2 {options for image items} -body {
    .c create image 50 50 -anchor gorp -tags i1
} -cleanup {
    .c delete all

} -returnCodes {error} -result {bad anchor position "gorp": must be n, ne, e, se, s, sw, w, nw, or center}
test canvImg-1.3 {options for image items} -constraints testImageType -setup {
    image create test foo
	.c delete all
} -body {
    .c create image 50 50 -image foo -tags i1
    .c itemconfigure i1 -image
} -cleanup {
    .c delete all
	image delete foo
} -result {-image {} {} {} foo}
test canvImg-1.4 {options for image items} -body {
    .c create image 50 50 -image unknown -tags i1
} -cleanup {
    .c delete all

} -returnCodes {error} -result {image "unknown" doesn't exist}
test canvImg-1.5 {options for image items} -constraints testImageType -setup {
    image create test foo
	.c delete all
} -body {
    .c create image 50 50 -image foo -tags {i1 foo}
    .c itemconfigure i1 -tags
} -cleanup {
    .c delete all
	image delete foo
} -result {-tags {} {} {} {i1 foo}}

test canvImg-2.1 {CreateImage procedure} -body {
    .c create image 40
} -cleanup {
    .c delete all
} -returnCodes {error} -result {wrong # coordinates: expected 2, got 1}
test canvImg-2.2 {CreateImage procedure} -body {
    .c create image 40 50 60
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "60"}
test canvImg-2.3 {CreateImage procedure} -body {
    .c delete all
    set i [.c create image 50 50]
    list [lindex [.c itemconf $i -anchor] 4] \
	    [lindex [.c itemconf $i -image] 4] \
	    [lindex [.c itemconf $i -tags] 4]
} -cleanup {
    .c delete all
} -result {center {} {}}
test canvImg-2.4 {CreateImage procedure} -body {
    .c create image xyz 40
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvImg-2.5 {CreateImage procedure} -body {
    .c create image 50 qrs
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "qrs"}
test canvImg-2.6 {CreateImage procedure} -constraints testImageType -body {
    .c create image 50 50 -gorp foo
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-gorp"}


test canvImg-3.1 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c create image 50 100 -image foo -tags i1
    format {%.6g %.6g} {*}[.c coords i1]
} -cleanup {
	.c delete all
	image delete foo
} -result {50 100}
test canvImg-3.2 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c create image 50 100 -image foo -tags i1
    .c coords i1 dumb 100
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {bad screen distance "dumb"}
test canvImg-3.3 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250 dumb0
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {bad screen distance "dumb0"}
test canvImg-3.4 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {wrong # coordinates: expected 2, got 1}
test canvImg-3.5 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250 300 400
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {wrong # coordinates: expected 0 or 2, got 3}


test canvImg-4.1 {ConfiugreImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags i1
    update
    set x {}
    .c itemconfigure i1 -image {}
    update
    list $x [.c bbox i1]
} -cleanup {
	.c delete all
	image delete foo
} -result {{{foo free}} {}}
test canvImg-4.2 {ConfigureImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
    image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    set timer [after 300 {lappend y "timed out"}]
    .c itemconfigure i1 -image foo2
    update idletasks
    update
    # On MacOS we need to wait for the test image display procedure to run.
    while {"timed out" ni $y && [lindex $y end 1] ne "display"} {
        vwait y
    }
    after cancel $timer
    list $x $y [.c bbox i1]
} -cleanup {
    .c delete all
    image delete foo
    image delete foo2
} -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60}} {50 100 130 160}}
test canvImg-4.3 {ConfiugreImage procedure} -constraints testImageType -setup {
    .c delete all



} -body {


	image create test foo -variable x

    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    .c itemconfigure i1 -image lousy
} -cleanup {
	.c delete all
	image delete foo foo2
} -returnCodes {error} -result {image "lousy" doesn't exist}


test canvImg-5.1 {DeleteImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    image create test foo2 -variable y
    image create test xyzzy -variable z
    .c create image 50 100 -image xyzzy -tags i1
    update
    set names [lsort [imageNames]]
    image delete xyzzy
    set z {}
    set names2 [lsort [imageNames]]
    .c delete i1
    update
    list $names $names2 $z [lsort [imageNames]]
} -cleanup {
    imageCleanup
    .c delete all
} -result {{foo foo2 xyzzy} {foo foo2} {} {foo foo2}}
test canvImg-5.2 {DeleteImage procedure (don't delete non-existent image)} -body {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c delete i1
    update
} -result {}


test canvImg-6.1 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c create image 15.51 17.51 -image foo -tags i1 -anchor nw
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {16 18 46 33}
test canvImg-6.2 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c create image 15.49 17.49 -image foo -tags i1 -anchor nw
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {15 17 45 32}
test canvImg-6.3 {ComputeImageBbox procedure} -setup {
    .c delete all
} -body {
    .c create image 20 30 -tags i1 -anchor nw
    .c bbox i1
} -cleanup {
    .c delete all
} -result {}
test canvImg-6.4 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor nw
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {20 30 50 45}
test canvImg-6.5 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor n
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {5 30 35 45}
test canvImg-6.6 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor ne
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {-10 30 20 45}
test canvImg-6.7 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor e
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {-10 23 20 38}
test canvImg-6.8 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor se
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {-10 15 20 30}
test canvImg-6.9 {ComputeImageBbox procedure} -constraints testImageType -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor s
    .c bbox i1
} -cleanup {
    .c delete all
    imageCleanup
} -result {5 15 35 30}
test canvImg-6.10 {ComputeImageBbox procedure} -constraints {
    testImageType
} -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor sw
    .c bbox i1
} -cleanup {
    .c delete all
    image delete foo
} -result {20 15 50 30}
test canvImg-6.11 {ComputeImageBbox procedure} -constraints {
    testImageType
} -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor w
    .c bbox i1
} -cleanup {
    .c delete all
    image delete foo
} -result {20 23 50 38}
test canvImg-6.12 {ComputeImageBbox procedure} -constraints {
	testImageType
} -setup {
    image create test foo
    .c delete all
} -body {
    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor center
    .c bbox i1
} -cleanup {
    .c delete all
    image delete foo
} -result {5 23 35 38}

# The following test is non-portable because of differences in
# coordinate rounding on some machines (does 0.5 round  up?).

test canvImg-7.1 {DisplayImage procedure} -constraints {
	nonPortable testImageType
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
    set x
} -result {{foo display 4 9 12 6 30 30}}
test canvImg-7.2 {DisplayImage procedure, no image} -body {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
} -result {}


# image used in 8.* test cases
if {[testConstraint testImageType]} {
    image create test foo
}
test canvImg-8.1 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect 50 70 80 81
	.c gettags [.c find closest 70 90]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.2 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{50 70 80 79}
	.c gettags [.c find closest {*}{70 90}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.3 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{99 70 110 81}
	.c gettags [.c find closest {*}{90 90}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.4 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{101 70 110 79}
	.c gettags [.c find closest {*}{90 90}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.5 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{99 100 110 115}
	.c gettags [.c find closest {*}{90 110}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.6 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{101 100 110 115}
	.c gettags [.c find closest {*}{90 110}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.7 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{99 134 110 145}
	.c gettags [.c find closest {*}{90 125}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.8 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{101 136 110 145}
	.c gettags [.c find closest {*}{90 125}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.9 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{50 134 80 145}
	.c gettags [.c find closest {*}{70 125}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.10 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{50 136 80 145}
	.c gettags [.c find closest {*}{70 125}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.11 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{20 134 31 145}
	.c gettags [.c find closest {*}{40 125}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.12 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{20 136 29 145}
	.c gettags [.c find closest {*}{40 125}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.13 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{20 100 31 115}
	.c gettags [.c find closest {*}{40 110}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.14 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw

	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{20 100 29 115}
	.c gettags [.c find closest {*}{40 110}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.15 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{20 70 31 80}


	.c gettags [.c find closest {*}{40 90}]
} -cleanup {
	.c delete all
} -result {rect}
test canvImg-8.16 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}

} -body {
	.c coords rect {*}{20 70 29 79}

	.c gettags [.c find closest {*}{40 90}]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.17 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}

} -body {
	.c coords rect {*}{60 70 69 109}

	.c gettags [.c find closest {*}{70 110}]
} -cleanup {

	.c delete all
} -result {image}
test canvImg-8.18 {ImageToArea procedure} -constraints testImageType -setup {
	.c create image 50 100 -image foo -tags image -anchor nw
	.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}
} -body {
	.c coords rect {*}{60 70 71 111}
	.c gettags [.c find closest {*}{70 110}]
} -cleanup {
	.c delete all
} -result {rect}
.c delete all

test canvImg-8.19 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 0 70 99]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.20 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 0 70 99.999]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.21 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 0 70 101]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.22 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 81 105 120 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.23 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 80.001 105 120 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.24 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 79 105 120 115]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.25 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 116 70 150]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.26 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 115.001 70 150]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.27 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 60 114 70 150]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.28 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 105 49 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.29 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 105 50 114.999]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.30 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 105 51 115]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.31 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 0 49.999 99.999]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.32 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 0 51 101]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.33 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 80 0 150 100]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.34 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 79 0 150 101]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.35 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 80.001 115.001 150 180]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.36 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 79 114 150 180]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.37 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 115 50 180]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.38 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find overlapping 0 114 51 180]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.39 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 0 0 200 200]



} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.40 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 49.999 99.999 80.001 115.001]
} -cleanup {
	.c delete all
} -result {image}
test canvImg-8.41 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 51 100 80 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.42 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 50 101 80 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.43 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 50 100 79 115]
} -cleanup {
	.c delete all
} -result {}
test canvImg-8.44 {ImageToArea procedure} -constraints testImageType -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c gettags [.c find enclosed 50 100 80 114]
} -cleanup {
	.c delete all
} -result {}
if {[testConstraint testImageType]} {
	image delete foo
}


test canvImg-9.1 {DisplayImage procedure} -constraints testImageType -setup {
    .c delete all
	image create test foo
} -body {
    .c create image 50 100 -image foo -tags image -anchor nw
    .c scale image 25 0 2.0 1.5
    .c bbox image
} -cleanup {
	.c delete all
	image delete foo
} -result {75 150 105 165}

test canvImg-10.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    foo changed 2 4 6 8 30 15

    vwait x
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    image delete foo
} -result {{foo display 2 4 6 8}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    foo changed 2 4 6 8 40 50
    vwait x
    after cancel $timer
    update
    return $x
} -cleanup {
    .c delete all
    image delete foo
} -result {{foo display 0 0 40 50}}
test canvImg-11.2 {ImageChangedProc procedure} -constraints {
	testImageType
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor center
    update
    set x {}
    foo changed 0 0 0 0 40 50
    .c bbox image
} -cleanup {
	.c delete all
	image delete foo
} -result {30 75 70 125}

test canvImg-11.3 {ImageChangedProc procedure} -constraints {
	testImageType
} -setup {
    .c delete all
    update idletasks
} -body {
    image create test foo -variable x
    image create test foo2 -variable z
    foo changed 0 0 0 0 40 50
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags image -anchor nw
    .c create image 70 110 -image foo2 -anchor nw

    set z {}
    set timer [after 500 {lappend z "timed out"}]
    image delete foo
    vwait z
    after cancel $timer
    return $z
} -cleanup {
    .c delete all
    image delete foo2
} -result {{foo2 display 0 0 80 60}}

# cleanup
imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:




|
|
|



<


<

<
>



|
>
>
>
|
|
>


<
<
|
|
<
<

>
|
|
<
|
<


<
<
<
|
|
<
<

>
|
|
<
|
<


<
<
<
|

|
|
<
<
|
|
|
<
<
|
|





<
<
|
|
|
<
<
|
|
|
<
<
|
|
|
<
<
|

<
|
|
<

|
<
<
<
|
|
|
<

|
<
<
<
|
|
<
<


|
<
<
<
|
|
<
<


|
<
<
<
|
|
<
<


|
<
<
<
|

<
|

<
<






<
<
<
|
|

<
<
<
<




<

<

<
<
<
<
<

<
<
<
<
|
|

>
>
>
|
>
>
|
>
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<


|


|


|
<
<
<
|
|





<
|

|
<

<


<
<
<
|
|
<

<


<
<
<
|
|

<


|
<
<
|
<
<
<



<
<
<
|
|
<
<
<



<
<
<
|
|
<
<
<



<
<
<
|
|
<
<
<



<
<
<
|
|
<
<
<



<
<
<
|
|
<
<
<



<
<
<
|
|
<
<
<

<
<


<
<
<
|
|
<
<
<

<
<


<
<
<
|
|
<
<
<
<
<



<
<
<
|




|
<
<

<
<






|
|





|

|
<

|

<
<
|
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
|
|
<
<
<
|
<
<
<
|
|
|
|
|
<
<
<
<
|
|
<
<
<
|
<
<
<
|
|
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
|
<
<
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
|
|
<
|
<
<
<
>
>
|
|
<
<
|
<
<
>
|
<
>
|
<
<
|
|
<
<
>
|
<
>
|
|
>
|
|
|
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
|
<
|
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
<
<
|
|
<
|
|
<
<
|
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<

<
<
|
|
<

|
<
<
|
<

<
<
|
|
<

>
>
>
<
<
|
<
<
<
<
<
<
|
<

|
<
<
|
<

|
<
<
|
<

|
<
<
|
<

<
<
<
<
<
|

<
|

<
<



<
<
<
|

|

<
<
<



<

>
|
<
<
<
<
<
|

|

<
<
<



<

<
<

|
<
<
<
|
|
<
<

<






<
<
<
|
<
|
<
<

<
<

<

<


>
|
<
|
|
<
|
<
<
<
|


<


<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12

13

14
15
16
17
18
19
20
21
22
23
24
25
26


27
28


29
30
31
32

33

34
35



36
37


38
39
40
41

42

43
44



45
46
47
48


49
50
51


52
53
54
55
56
57
58


59
60
61


62
63
64


65
66
67


68
69

70
71

72
73



74
75
76

77
78



79
80


81
82
83



84
85


86
87
88



89
90


91
92
93



94
95

96
97


98
99
100
101
102
103



104
105
106




107
108
109
110

111

112





113




114
115
116
117
118
119
120
121
122
123
124
125







126











127
128
129
130
131
132
133
134
135



136
137
138
139
140
141
142

143
144
145

146

147
148



149
150

151

152
153



154
155
156

157
158
159


160



161
162
163



164
165



166
167
168



169
170



171
172
173



174
175



176
177
178



179
180



181
182
183



184
185



186
187
188



189
190



191


192
193



194
195



196


197
198



199
200





201
202
203



204
205
206
207
208
209


210


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

227
228
229


230



231

232




233




234



235



236
237



238



239
240
241
242
243




244
245



246



247
248







249



250
251




252



253
254


255






































256
257




258
259

260



261
262
263
264


265


266
267

268
269


270
271


272
273

274
275
276
277
278
279
280




281




282
283







284
285


286

287


288
289







290
291


292

293
294


295

296
297


298

299
300


301

302


303
304

305
306


307

308








309
310







311
312




















313

314


315
316

317
318


319

320


321
322

323
324
325
326


327






328

329
330


331

332
333


334

335
336


337

338





339
340

341
342


343
344
345



346
347
348
349



350
351
352

353
354
355





356
357
358
359



360
361
362

363


364
365



366
367


368

369
370
371
372
373
374



375

376


377


378

379

380
381
382
383

384
385

386



387
388
389

390
391




# This file is a Tcl script to test out the procedures in tkCanvImg.c,
# which implement canvas "image" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands



eval image delete [image names]
canvas .c
pack .c
update
if {[testConstraint testImageType]} {
    image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
}
test canvImg-1.1 {options for image items} {
    .c delete all
    .c create image 50 50 -anchor nw -tags i1
    .c itemconfigure i1 -anchor


} {-anchor {} {} center nw}
test canvImg-1.2 {options for image items} {


    .c delete all
    list [catch {.c create image 50 50 -anchor gorp -tags i1} msg] $msg
} {1 {bad anchor position "gorp": must be n, ne, e, se, s, sw, w, nw, or center}}
test canvImg-1.3 {options for image items} testImageType {

    .c delete all

    .c create image 50 50 -image foo -tags i1
    .c itemconfigure i1 -image



} {-image {} {} {} foo}
test canvImg-1.4 {options for image items} {


    .c delete all
    list [catch {.c create image 50 50 -image unknown -tags i1} msg] $msg
} {1 {image "unknown" doesn't exist}}
test canvImg-1.5 {options for image items} testImageType {

    .c delete all

    .c create image 50 50 -image foo -tags {i1 foo}
    .c itemconfigure i1 -tags



} {-tags {} {} {} {i1 foo}}

test canvImg-2.1 {CreateImage procedure} {
    list [catch {.c create image 40} msg] $msg


} {1 {wrong # coordinates: expected 2, got 1}}
test canvImg-2.2 {CreateImage procedure} {
    list [catch {.c create image 40 50 60} msg] $msg


} {1 {unknown option "60"}}
test canvImg-2.3 {CreateImage procedure} {
    .c delete all
    set i [.c create image 50 50]
    list [lindex [.c itemconf $i -anchor] 4] \
	    [lindex [.c itemconf $i -image] 4] \
	    [lindex [.c itemconf $i -tags] 4]


} {center {} {}}
test canvImg-2.4 {CreateImage procedure} {
    list [catch {.c create image xyz 40} msg] $msg


} {1 {bad screen distance "xyz"}}
test canvImg-2.5 {CreateImage procedure} {
    list [catch {.c create image 50 qrs} msg] $msg


} {1 {bad screen distance "qrs"}}
test canvImg-2.6 {CreateImage procedure} testImageType {
    list [catch {.c create image 50 50 -gorp foo} msg] $msg


} {1 {unknown option "-gorp"}}


test canvImg-3.1 {ImageCoords procedure} testImageType {
    .c delete all

    .c create image 50 100 -image foo -tags i1
    .c coords i1



} {50.0 100.0}
test canvImg-3.2 {ImageCoords procedure} testImageType {
    .c delete all

    .c create image 50 100 -image foo -tags i1
    list [catch {.c coords i1 dumb 100} msg] $msg



} {1 {bad screen distance "dumb"}}
test canvImg-3.3 {ImageCoords procedure} testImageType {


    .c delete all
    .c create image 50 100 -image foo -tags i1
    list [catch {.c coords i1 250 dumb0} msg] $msg



} {1 {bad screen distance "dumb0"}}
test canvImg-3.4 {ImageCoords procedure} testImageType {


    .c delete all
    .c create image 50 100 -image foo -tags i1
    list [catch {.c coords i1 250} msg] $msg



} {1 {wrong # coordinates: expected 2, got 1}}
test canvImg-3.5 {ImageCoords procedure} testImageType {


    .c delete all
    .c create image 50 100 -image foo -tags i1
    list [catch {.c coords i1 250 300 400} msg] $msg



} {1 {wrong # coordinates: expected 0 or 2, got 3}}


test canvImg-4.1 {ConfiugreImage procedure} testImageType {
    .c delete all


    .c create image 50 100 -image foo -tags i1
    update
    set x {}
    .c itemconfigure i1 -image {}
    update
    list $x [.c bbox i1]



} {{{foo free}} {}}
test canvImg-4.2 {ConfiugreImage procedure} testImageType {
    .c delete all




    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}

    .c itemconfigure i1 -image foo2

    update





    list $x $y [.c bbox i1]




} {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60 30 30}} {50 100 130 160}}
test canvImg-4.3 {ConfiugreImage procedure} testImageType {
    .c delete all
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    list [catch {.c itemconfigure i1 -image lousy} msg] $msg
} {1 {image "lousy" doesn't exist}}

test canvImg-5.1 {DeleteImage procedure} testImageType {
    image create test xyzzy -variable z







    .c delete all











    .c create image 50 100 -image xyzzy -tags i1
    update
    set names [lsort [image names]]
    image delete xyzzy
    set z {}
    set names2 [lsort [image names]]
    .c delete i1
    update
    list $names $names2 $z [lsort [image names]]



} {{foo foo2 xyzzy} {foo foo2} {} {foo foo2}}
test canvImg-5.2 {DeleteImage procedure (don't delete non-existent image)} {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c delete i1
    update

} {}

test canvImg-6.1 {ComputeImageBbox procedure} testImageType {

    .c delete all

    .c create image 15.51 17.51 -image foo -tags i1 -anchor nw
    .c bbox i1



} {16 18 46 33}
test canvImg-6.2 {ComputeImageBbox procedure} testImageType {

    .c delete all

    .c create image 15.49 17.49 -image foo -tags i1 -anchor nw
    .c bbox i1



} {15 17 45 32}
test canvImg-6.3 {ComputeImageBbox procedure} {
    .c delete all

    .c create image 20 30 -tags i1 -anchor nw
    .c bbox i1
} {}


test canvImg-6.4 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor nw
    .c bbox i1



} {20 30 50 45}
test canvImg-6.5 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor n
    .c bbox i1



} {5 30 35 45}
test canvImg-6.6 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor ne
    .c bbox i1



} {-10 30 20 45}
test canvImg-6.7 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor e
    .c bbox i1



} {-10 23 20 38}
test canvImg-6.8 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor se
    .c bbox i1



} {-10 15 20 30}
test canvImg-6.9 {ComputeImageBbox procedure} testImageType {



    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor s
    .c bbox i1



} {5 15 35 30}
test canvImg-6.10 {ComputeImageBbox procedure} testImageType {



    .c delete all


    .c create image 20 30 -image foo -tags i1 -anchor sw
    .c bbox i1



} {20 15 50 30}
test canvImg-6.11 {ComputeImageBbox procedure} testImageType {



    .c delete all


    .c create image 20 30 -image foo -tags i1 -anchor w
    .c bbox i1



} {20 23 50 38}
test canvImg-6.12 {ComputeImageBbox procedure} testImageType {





    .c delete all
    .c create image 20 30 -image foo -tags i1 -anchor center
    .c bbox i1



} {5 23 35 38}

# The following test is non-portable because of differences in
# coordinate rounding on some machines (does 0.5 round  up?).

test canvImg-7.1 {DisplayImage procedure} {nonPortable testImageType} {


    .c delete all


    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
    set x
} {{foo display 4 9 12 6 30 30}}
test canvImg-7.2 {DisplayImage procedure, no image} {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
} {}

.c delete all

if {[testConstraint testImageType]} {
    .c create image 50 100 -image foo -tags image -anchor nw
}


.c create rect 10 10 20 20 -tags rect -fill black -width 0 -outline {}



foreach check {

    {canvImg-8.1   {50 70 80 81}     {70 90}  rect}




    {canvImg-8.2   {50 70 80 79}     {70 90}  image}




    {canvImg-8.3   {99 70 110 81}    {90 90}  rect}



    {canvImg-8.4   {101 70 110 79}   {90 90}  image}



    {canvImg-8.5   {99 100 110 115}  {90 110} rect}
    {canvImg-8.6   {101 100 110 115} {90 110} image}



    {canvImg-8.7   {99 134 110 145}  {90 125} rect}



    {canvImg-8.8   {101 136 110 145} {90 125} image}
    {canvImg-8.9   {50 134 80 145}   {70 125} rect}
    {canvImg-8.10  {50 136 80 145}   {70 125} image}
    {canvImg-8.11  {20 134 31 145}   {40 125} rect}
    {canvImg-8.12  {20 136 29 145}   {40 125} image}




    {canvImg-8.13  {20 100 31 115}   {40 110} rect}
    {canvImg-8.14  {20 100 29 115}   {40 110} image}



    {canvImg-8.15  {20 70 31 80}     {40 90}  rect}



    {canvImg-8.16  {20 70 29 79}     {40 90}  image}
    {canvImg-8.17  {60 70 69 109}    {70 110} image}







    {canvImg-8.18  {60 70 71 111}    {70 110} rect}



} {
    lassign $check name rectCoords testPoint result




    test $name {ImageToPoint procedure} testImageType {



	.c coords rect {*}$rectCoords
	.c gettags [.c find closest {*}$testPoint]


    } $result






































}





.c delete all
if {[testConstraint testImageType]} {

    .c create image 50 100 -image foo -tags image -anchor nw



}
test canvImg-8.19 {ImageToArea procedure} testImageType {
    .c gettags [.c find overlapping 60 0 70 99]
} {}


test canvImg-8.20 {ImageToArea procedure} testImageType {


    .c gettags [.c find overlapping 60 0 70 99.999]
} {}

test canvImg-8.21 {ImageToArea procedure} testImageType {
    .c gettags [.c find overlapping 60 0 70 101]


} {image}
test canvImg-8.22 {ImageToArea procedure} testImageType {


    .c gettags [.c find overlapping 81 105 120 115]
} {}

test canvImg-8.23 {ImageToArea procedure} testImageType {
    .c gettags [.c find overlapping 80.001 105 120 115]
} {}
test canvImg-8.24 {ImageToArea procedure} testImageType {
    .c gettags [.c find overlapping 79 105 120 115]
} {image}
test canvImg-8.25 {ImageToArea procedure} testImageType {




    .c gettags [.c find overlapping 60 116 70 150]




} {}
test canvImg-8.26 {ImageToArea procedure} testImageType {







    .c gettags [.c find overlapping 60 115.001 70 150]
} {}


test canvImg-8.27 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 60 114 70 150]


} {image}
test canvImg-8.28 {ImageToArea procedure} testImageType {







    .c gettags [.c find overlapping 0 105 49 115]
} {}


test canvImg-8.29 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 105 50 114.999]
} {}


test canvImg-8.30 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 105 51 115]
} {image}


test canvImg-8.31 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 0 49.999 99.999]
} {}


test canvImg-8.32 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 0 51 101]


} {image}
test canvImg-8.33 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 80 0 150 100]
} {}


test canvImg-8.34 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 79 0 150 101]








} {image}
test canvImg-8.35 {ImageToArea procedure} testImageType {







    .c gettags [.c find overlapping 80.001 115.001 150 180]
} {}




















test canvImg-8.36 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 79 114 150 180]


} {image}
test canvImg-8.37 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 115 50 180]
} {}


test canvImg-8.38 {ImageToArea procedure} testImageType {

    .c gettags [.c find overlapping 0 114 51 180]


} {image}
test canvImg-8.39 {ImageToArea procedure} testImageType {

    .c gettags [.c find enclosed 0 0 200 200]
} {image}
test canvImg-8.40 {ImageToArea procedure} testImageType {
    .c gettags [.c find enclosed 49.999 99.999 80.001 115.001]


} {image}






test canvImg-8.41 {ImageToArea procedure} testImageType {

    .c gettags [.c find enclosed 51 100 80 115]
} {}


test canvImg-8.42 {ImageToArea procedure} testImageType {

    .c gettags [.c find enclosed 50 101 80 115]
} {}


test canvImg-8.43 {ImageToArea procedure} testImageType {

    .c gettags [.c find enclosed 50 100 79 115]
} {}


test canvImg-8.44 {ImageToArea procedure} testImageType {

    .c gettags [.c find enclosed 50 100 80 114]





} {}


test canvImg-9.1 {DisplayImage procedure} testImageType {
    .c delete all


    .c create image 50 100 -image foo -tags image -anchor nw
    .c scale image 25 0 2.0 1.5
    .c bbox image



} {75 150 105 165}

test canvImg-10.1 {TranslateImage procedure} testImageType {
    .c delete all



    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}

    foo changed 2 4 6 8 30 15
    update
    set x





} {{foo display 2 4 6 8 30 30}}

test canvImg-11.1 {TranslateImage procedure} testImageType {
    .c delete all



    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}

    foo changed 2 4 6 8 40 50


    update
    set x



} {{foo display 0 0 40 50 30 30}}
test canvImg-11.2 {ImageChangedProc procedure} testImageType {


    .c delete all

    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor center
    update
    set x {}
    foo changed 0 0 0 0 40 50
    .c bbox image



} {30 75 70 125}

test canvImg-11.3 {ImageChangedProc procedure} testImageType {


    .c delete all


    image create test foo -variable x

    foo changed 0 0 0 0 40 50

    .c create image 50 100 -image foo -tags image -anchor nw
    .c create image 70 110 -image foo2 -anchor nw
    update
    set y {}

    image create test foo -variable x
    update

    set y



} {{foo2 display 0 0 20 40 50 40}}

# cleanup

cleanupTests
return




Deleted tests/canvMoveto.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# This file is a Tcl script to test out the canvas "moveto" command. It is
# derived from canvRect.test.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2004 Neil McKay.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

canvas .c -width 400 -height 300 -bd 2 -relief sunken
.c create rectangle 20 20 80 80 -tag {test rect1}
.c create rectangle 40 40 90 100 -tag {test rect2}

test canvMoveto-1.1 {Bad args handling for "moveto" command} -body {
    .c moveto test
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.2 {Bad args handling for "moveto" command} -body {
    .c moveto rect
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.3 {Bad args handling for "moveto" command} -body {
    .c moveto test 12
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.4 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 y
} -returnCodes error -result {bad screen distance "y"}
test canvMoveto-1.5 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 20 -anchor
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}

test canvMoveto-2.1 {Canvas "moveto" command coordinates} {
    .c moveto test 200 150
    .c bbox test
} {200 150 272 232}
test canvMoveto-2.2 {Canvas "moveto" command, blank y coordinate} {
    .c moveto test 200 150
    .c moveto test 150 {}
    .c bbox test
} {150 150 222 232}
test canvMoveto-2.3 {Canvas "moveto" command, blank x coordinate} {
    .c moveto test 200 150
    .c moveto test {} 200
    .c bbox test
} {200 200 272 282}

.c delete withtag all

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































Changes to tests/canvPs.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# This file is a Tcl script to test out procedures to write postscript
# for canvases to files and channels. It exercises the procedure
# TkCanvPostscriptCmd in generic/tkCanvPs.c
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# canvas used in 1.* and 2.* test cases
canvas .c -width 400 -height 300 -bd 2 -relief sunken
.c create rectangle 20 20 80 80 -fill red
pack .c
update

test canvPs-1.1 {test writing to a file} -constraints {
    unixOrWin
} -setup {
    set foo [makeFile {} foo.ps]
} -body {
    set res [.c postscript -file $foo]
    lappend res [file exists $foo]
} -cleanup {
    removeFile foo.ps
} -result 1
test canvPs-1.2 {test writing to a file, idempotency} -constraints {
    unixOrWin
} -setup {
    set foo [makeFile {} foo.ps]
    set bar [makeFile {} bar.ps]
} -body {
    .c postscript -file $foo
    .c postscript -file $bar
    set status ok
    if {[file size $bar] != [file size $foo]} {
	set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok


test canvPs-2.1 {test writing to a channel} -constraints {
    unixOrWin
} -setup {
    set foo [makeFile {} foo.ps]
    file delete $foo
} -body {
    set chan [open $foo w]
    fconfigure $chan -translation lf
    set res [.c postscript -channel $chan]
    close $chan
    lappend res [file exists $foo]
} -cleanup {
    removeFile foo.ps
} -result 1
test canvPs-2.2 {test writing to channel, idempotency} -constraints {
    unixOrWin
} -setup {
    set foo [makeFile {} foo.ps]
    set bar [makeFile {} bar.ps]
    file delete $foo
    file delete $bar
} -body {
    set c1 [open $foo w]
    set c2 [open $bar w]
    fconfigure $c1 -translation lf
    fconfigure $c2 -translation lf
    .c postscript -channel $c1
    .c postscript -channel $c2
    close $c1
    close $c2
    set status ok
    if {[file size $bar] != [file size $foo]} {
	    set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
test canvPs-2.3 {test writing to channel and file, same output} -constraints {




|
|



<


<

<






|



|
|




|
















<

|






|

|




|
















|







1
2
3
4
5
6
7
8
9

10
11

12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# This file is a Tcl script to test out procedures to write postscript
# for canvases to files and channels. It exercises the procedure
# TkCanvPostscriptCmd in generic/tkCanvPs.c
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands



canvas .c -width 400 -height 300 -bd 2 -relief sunken
.c create rectangle 20 20 80 80 -fill red
pack .c
update

test canvPs-1.1 {test writing to a file} -constraints {
    unixOrPc
} -setup {
    set foo [makeFile {} foo.ps]
} -body {
    .c postscript -file $foo
    file exists $foo
} -cleanup {
    removeFile foo.ps
} -result 1
test canvPs-1.2 {test writing to a file, idempotency} -constraints {
    unixOrPc
} -setup {
    set foo [makeFile {} foo.ps]
    set bar [makeFile {} bar.ps]
} -body {
    .c postscript -file $foo
    .c postscript -file $bar
    set status ok
    if {[file size $bar] != [file size $foo]} {
	set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok


test canvPs-2.1 {test writing to a channel} -constraints {
    unixOrPc
} -setup {
    set foo [makeFile {} foo.ps]
    file delete $foo
} -body {
    set chan [open $foo w]
    fconfigure $chan -translation lf
    .c postscript -channel $chan
    close $chan
    file exists $foo
} -cleanup {
    removeFile foo.ps
} -result 1
test canvPs-2.2 {test writing to channel, idempotency} -constraints {
    unixOrPc
} -setup {
    set foo [makeFile {} foo.ps]
    set bar [makeFile {} bar.ps]
    file delete $foo
    file delete $bar
} -body {
    set c1 [open $foo w]
    set c2 [open $bar w]
    fconfigure $c1 -translation lf
    fconfigure $c2 -translation lf
    .c postscript -channel $c1
    .c postscript -channel $c2
    close $c1
    close $c2
    set status ok
    if {[file size $bar] != [file size $foo]} {
	set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
test canvPs-2.3 {test writing to channel and file, same output} -constraints {
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    set c1 [open $foo w]
    fconfigure $c1 -translation lf
    .c postscript -channel $c1
    close $c1
    .c postscript -file $bar
    set status ok
    if {[file size $foo] != [file size $bar]} {
	    set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
test canvPs-2.4 {test writing to channel and file, same output} -constraints {







|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    set c1 [open $foo w]
    fconfigure $c1 -translation lf
    .c postscript -channel $c1
    close $c1
    .c postscript -file $bar
    set status ok
    if {[file size $foo] != [file size $bar]} {
	set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
test canvPs-2.4 {test writing to channel and file, same output} -constraints {
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140


141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    set c1 [open $foo w]
    fconfigure $c1 -translation crlf
    .c postscript -channel $c1
    close $c1
    .c postscript -file $bar
    set status ok
    if {[file size $foo] != [file size $bar]} {
	    set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
destroy .c


test canvPs-3.1 {test ps generation with an embedded window} -constraints {
    notAqua
} -setup {
    set bar [makeFile {} bar.ps]
    file delete $bar


} -body {

    pack [canvas .c -width 200 -height 200 -background white]
    .c create rect 20 20 150 150 -tags rect0 -dash . -width 2
    .c create arc 0 50 200 200 -tags arc0 \
	    -dash {4 4} -stipple question -outline red -fill green

    image create photo logo \
	-file [file join [file dirname [info script]] pwrdLogo150.gif]
    .c create image 200 50 -image logo -anchor nw

    entry .c.e -background pink -foreground blue -width 14
    .c.e insert 0 "we gonna be postscripted"
    .c create window 50 180 -anchor nw -window .c.e
    update
    .c postscript -file $bar
    file exists $bar
} -cleanup {
    destroy .c
    imageCleanup
    removeFile bar.ps
} -result 1
test canvPs-3.2 {test ps generation with an embedded window not mapped} -setup {
    set bar [makeFile {} bar.ps]
    file delete $bar
} -body {

    pack [canvas .c -width 200 -height 200 -background white]
    entry .c.e -background pink -foreground blue -width 14
    .c.e insert 0 "we gonna be postscripted"
    .c create window 50 180 -anchor nw -window .c.e
    .c postscript -file $bar
    file exists $bar
} -cleanup {
    destroy .c
    removeFile bar.ps
} -result 1


test canvPs-4.1 {test ps generation with single-point uncolored poly, bug 734498} -body {

    pack [canvas .c]
    .c create poly 10 20 10 20
    .c postscript
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *


# cleanup
unset -nocomplain foo bar
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:







|






<

<
|
<
<


>
>

>
















<
<






>







<



<
|
>


|
<
<
<
|



<



<
<
<
<
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129

130


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169

170
171
172
173
174



175
176
177
178

179
180
181




    set c1 [open $foo w]
    fconfigure $c1 -translation crlf
    .c postscript -channel $c1
    close $c1
    .c postscript -file $bar
    set status ok
    if {[file size $foo] != [file size $bar]} {
	set status broken
    }
    set status
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok



test canvPs-3.1 {test ps generation with an embedded window} -setup {


    set bar [makeFile {} bar.ps]
    file delete $bar
} -constraints {
    notAqua
} -body {
    destroy .c
    pack [canvas .c -width 200 -height 200 -background white]
    .c create rect 20 20 150 150 -tags rect0 -dash . -width 2
    .c create arc 0 50 200 200 -tags arc0 \
	    -dash {4 4} -stipple question -outline red -fill green

    image create photo logo \
	-file [file join [file dirname [info script]] pwrdLogo150.gif]
    .c create image 200 50 -image logo -anchor nw

    entry .c.e -background pink -foreground blue -width 14
    .c.e insert 0 "we gonna be postscripted"
    .c create window 50 180 -anchor nw -window .c.e
    update
    .c postscript -file $bar
    file exists $bar
} -cleanup {


    removeFile bar.ps
} -result 1
test canvPs-3.2 {test ps generation with an embedded window not mapped} -setup {
    set bar [makeFile {} bar.ps]
    file delete $bar
} -body {
    destroy .c
    pack [canvas .c -width 200 -height 200 -background white]
    entry .c.e -background pink -foreground blue -width 14
    .c.e insert 0 "we gonna be postscripted"
    .c create window 50 180 -anchor nw -window .c.e
    .c postscript -file $bar
    file exists $bar
} -cleanup {

    removeFile bar.ps
} -result 1


test canvPs-4.1 {test ps generation with single-point uncolored poly, bug 734498} {} {
    destroy .c
    pack [canvas .c]
    .c create poly 10 20 10 20
    catch {.c postscript}



} 0

# cleanup
unset -nocomplain foo bar

deleteWindows
cleanupTests
return




Changes to tests/canvRect.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34








35
36
37
38


39
40
41
42
43
44
45



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240



241
242
243

244


245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429


430
431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452
453
# This file is a Tcl script to test out the procedures in tkRectOval.c,
# which implement canvas "rectangle" and "oval" items.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Canvas used in every test case of the whole file
canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c



update

# Rectangle used in canvRect-1.* tests

.c create rectangle 20 20 80 80 -tag test
test canvRect-1.1 {configuration options: good value for -fill} -body {
    .c itemconfigure test -fill #ff0000
    list [.c itemcget test -fill] [lindex [.c itemconfigure test -fill] 4]
} -result {{#ff0000} #ff0000}
test canvRect-1.2 {configuration options: bad value for -fill} -body {
    .c itemconfigure test -fill non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test canvRect-1.3 {configuration options: good value for -outline} -body {
    .c itemconfigure test -outline #123456
    list [.c itemcget test -outline] [lindex [.c itemconfigure test -outline] 4]
} -result {{#123456} #123456}
test canvRect-1.4 {configuration options: bad value for -outline} -body {
    .c itemconfigure test -outline non-existent
} -returnCodes error -result {unknown color name "non-existent"}








test canvRect-1.5 {configuration options: good value for -stipple } -body {
    .c itemconfigure test -stipple  gray50
    list [.c itemcget test -stipple ] [lindex [.c itemconfigure test -stipple ] 4]
} -result {gray50 gray50}


test canvRect-1.6 {configuration options: bad value for -stipple } -body {
    .c itemconfigure test -stipple  bogus
} -returnCodes error -result {bitmap "bogus" not defined}
test canvRect-1.7 {configuration options: good value for -tags} -body {
    .c itemconfigure test -tags {test a b c}
    list [.c itemcget test -tags] [lindex [.c itemconfigure test -tags] 4]
} -result {{test a b c} {test a b c}}



test canvRect-1.8 {configuration options} -body {
    .c itemconfigure test -tags {test xyz}
    .c itemcget xyz -tags
} -result {test xyz}
test canvRect-1.9 {configuration options: good value for -width} -body {
    .c itemconfigure test -width 6.0
    list [.c itemcget test -width] [lindex [.c itemconfigure test -width] 4]
} -result {6.0 6.0}
test canvRect-1.10 {configuration options: bad value for -width} -body {
    .c itemconfigure test -width abc
} -returnCodes error -result {bad screen distance "abc"}
.c delete withtag all


test canvRect-2.1 {CreateRectOval procedure} -body {
    .c create rect
} -returnCodes error -result {wrong # args: should be ".c create rect coords ?arg ...?"}
test canvRect-2.2 {CreateRectOval procedure} -body {
    .c create oval x y z
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 3}
test canvRect-2.3 {CreateRectOval procedure} -body {
    .c create rectangle x 2 3 4
} -returnCodes error -result {bad screen distance "x"}
test canvRect-2.4 {CreateRectOval procedure} -body {
    .c create rectangle 1 y 3 4
} -returnCodes error -result {bad screen distance "y"}
test canvRect-2.5 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 z 4
} -returnCodes error -result {bad screen distance "z"}
test canvRect-2.6 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 q
} -returnCodes error -result {bad screen distance "q"}
test canvRect-2.7 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 4 -tags x
    set result {}
    foreach element [.c coords x] {
	    lappend result [format %.1f $element]
    }
    set result
} -result {1.0 2.0 3.0 4.0}
test canvRect-2.8 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 4 -gorp foo
} -returnCodes error -result {unknown option "-gorp"}
.c delete withtag all


test canvRect-3.1 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x

    set result {}
    foreach element [.c coords x] {
	    lappend result [format %.1f $element]
    }
    return $result
} -cleanup {
    .c delete withtag all
} -result {10.0 20.0 30.0 40.0}
test canvRect-3.2 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x a 2 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "a"}
test canvRect-3.3 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 b 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "b"}
test canvRect-3.4 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 c 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "c"}
test canvRect-3.5 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 d
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "d"}
test canvRect-3.6 {RectOvalCoords procedure} -constraints {
    nonPortable
} -body {
    .c create rectangle 10 20 30 40 -tags x
    # Non-portable due to rounding differences.
    .c coords x 10 25 15 40
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 24 16 41}
test canvRect-3.7 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 4 5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 5}


test canvRect-4.1 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width abc
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "abc"}
test canvRect-4.2 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1

    catch {.c itemconfigure x -width abc}
	.c itemcget x -width
} -cleanup {
    .c delete withtag all
} -result {1.0}
test canvRect-4.3 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width -5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "-5"}
test canvRect-4.4 {ConfigureRectOval procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width 10
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {5 15 35 45}

# I can't come up with any good tests for DeleteRectOval.



test canvRect-5.1 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 20 15 10 5
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {10 5 20 15}
test canvRect-5.2 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 1 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.3 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 2 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.4 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 3 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {8 8 32 22}

# I can't come up with any good tests for DisplayRectOval.

test canvRect-6.1 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]
    .c itemconfigure y -outline {}
    list [expr {[.c find closest 14.9 28] eq $xId}] \
		[expr {[.c find closest 15.1 28] eq $yId}] \
		[expr {[.c find closest 24.9 28] eq $yId}] \
		[expr {[.c find closest 25.1 28] eq $xId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1}
test canvRect-6.2 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]
    .c itemconfigure y -outline {}
    list [expr {[.c find closest 20 24.9] eq $xId}] \
		 [expr {[.c find closest 20 25.1] eq $yId}] \
	    [expr {[.c find closest 20 29.9] eq $yId}] \
		 [expr {[.c find closest 20 30.1] eq $xId}]

} -cleanup {
	.c delete all
} -result {1 1 1 1}
test canvRect-6.3 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]

    .c itemconfigure y -width 1 -outline black
    list [expr {[.c find closest 14.4 28] eq $xId}] \
		 [expr {[.c find closest 14.6 28] eq $yId}] \



	    [expr {[.c find closest 25.4 28] eq $yId}] \
		 [expr {[.c find closest 25.6 28] eq $xId}]
} -cleanup {

	.c delete all


} -result {1 1 1 1}
test canvRect-6.4 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]
    .c itemconfigure  y -width 1 -outline black
    list [expr {[.c find closest 20 24.4] eq $xId}] \
		 [expr {[.c find closest 20 24.6] eq $yId}] \
	    [expr {[.c find closest 20 30.4] eq $yId}] \
		 [expr {[.c find closest 20 30.6] eq $xId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1}

test canvRect-6.5 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]
	.c itemconfigure x -fill {} -outline black -width 3
	.c itemconfigure y -outline {}

    list [expr {[.c find closest 13.2 28] eq $xId}] \
		 [expr {[.c find closest 13.3 28] eq $yId}] \
	    [expr {[.c find closest 26.7 28] eq $yId}] \
		 [expr {[.c find closest 26.8 28] eq $xId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1}
test canvRect-6.6 {RectToPoint procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -tags x -fill green]
	set yId [.c create rectangle 15 25 25 30  -tags y -fill red]
	.c itemconfigure x -fill {} -outline black -width 3
	.c itemconfigure y -outline {}
    list [expr {[.c find closest 20 23.2] eq $xId}] \
		 [expr {[.c find closest 20 23.3] eq $yId}] \
	    [expr {[.c find closest 20 31.7] eq $yId}] \
		 [expr {[.c find closest 20 31.8] eq $xId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1}

test canvRect-6.7 {RectToPoint procedure} -body {
	set xId [.c create rectangle 10 20 30 40 -outline {} -fill black]
	set yId [.c create rectangle 40 40 50 50 -outline {} -fill black]
    list [expr {[.c find closest 35 35] eq $xId}] \

		 [expr {[.c find closest 36 36] eq $yId}] \
	    [expr {[.c find closest 37 37] eq $yId}] \
		 [expr {[.c find closest 38 38] eq $yId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1}


test canvRect-7.1 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]

    list [expr {[.c find overlapping 20 50 38 60] eq {}}] \
	    [expr {[.c find overlapping 20 50 39 60] eq $yId}] \
	    [expr {[.c find overlapping 20 50 70 60] eq $yId}] \
	    [expr {[.c find overlapping 61 50 70 60] eq $yId}] \
	    [expr {[.c find overlapping 62 50 70 60] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1}
test canvRect-7.2 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
    list [expr {[.c find overlapping 45 20 55 43] eq {}}] \
	    [expr {[.c find overlapping 45 20 55 44] eq $yId}] \
	    [expr {[.c find overlapping 45 20 55 80] eq $yId}] \
	    [expr {[.c find overlapping 45 71 55 80] eq $yId}] \
	    [expr {[.c find overlapping 45 72 55 80] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1}
test canvRect-7.3 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
    list [expr {[.c find overlapping 5 25 9.9 30] eq {}}] \
		[expr {[.c find overlapping 5 25 10.1 30] eq $xId}]
} -cleanup {
	.c delete all
} -result {1 1}
test canvRect-7.4 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
    list [expr {[.c find overlapping 102 152 118 168]  eq {}}]\
	    [expr {[.c find overlapping 101 152 118 168] eq $zId}] \
	    [expr {[.c find overlapping 102 151 118 168] eq $zId}] \
	    [expr {[.c find overlapping 102 152 119 168] eq $zId}] \
	    [expr {[.c find overlapping 102 152 118 169] eq $zId}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1}
test canvRect-7.5 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
    list [expr {[.c find enclosed 20 40 38 80] eq {}}] \
	    [expr {[.c find enclosed 20 40 39 80] eq {}}] \
	    [expr {[.c find enclosed 20 40 70 80] eq $yId}] \
	    [expr {[.c find enclosed 61 40 70 80] eq {}}] \
	    [expr {[.c find enclosed 62 40 70 80] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1}
test canvRect-7.6 {RectToArea procedure} -body {
	set xId  [.c create rectangle 10 20 30 35 -fill green -outline {}]
	set yId [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
	set zId [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
    list [expr {[.c find enclosed 20 20 65 43] eq {}}] \
	    [expr {[.c find enclosed 20 20 65 44] eq {}}] \
	    [expr {[.c find enclosed 20 20 65 80] eq $yId}] \
	    [expr {[.c find enclosed 20 71 65 80] eq {}}] \
	    [expr {[.c find enclosed 20 72 65 80] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1}


test canvRect-8.1 {OvalToArea procedure} -body {
	set xId  [.c create oval 50 100 200 150 -fill green -outline {}]
	set yId [.c create oval 50 100 200 150 -fill red -outline black -width 3]
	set zId [.c create oval 50 100 200 150 -fill {} -outline black -width 3]

    list [expr {[.c find overlapping 20 120 48 130] eq {}}] \
	    [expr {[.c find overlapping 20 120 49 130] eq "$yId $zId"}] \
	    [expr {[.c find overlapping 20 120 50.2 130] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 20 120 300 130] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 60 120 190 130] eq "$xId $yId"}] \
	    [expr {[.c find overlapping 199.9 120 300 130] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 201 120 300 130] eq "$yId $zId"}] \
	    [expr {[.c find overlapping 202 120 300 130] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1 1 1 1}
test canvRect-8.2 {OvalToArea procedure} -body {
	set xId  [.c create oval 50 100 200 150 -fill green -outline {}]
	set yId [.c create oval 50 100 200 150 -fill red -outline black -width 3]
	set zId [.c create oval 50 100 200 150 -fill {} -outline black -width 3]
    list [expr {[.c find overlapping 100 50 150 98] eq {}}] \
	    [expr {[.c find overlapping 100 50 150 99] eq "$yId $zId"}] \
	    [expr {[.c find overlapping 100 50 150 100.1] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 100 50 150 200] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 100 110 150 140] eq "$xId $yId"}] \
	    [expr {[.c find overlapping 100 149.9 150 200] eq "$xId $yId $zId"}] \
	    [expr {[.c find overlapping 100 151 150 200] eq "$yId $zId"}] \
	    [expr {[.c find overlapping 100 152 150 200] eq {}}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1 1 1 1}
test canvRect-8.3 {OvalToArea procedure} -body {
	set xId  [.c create oval 50 100 200 150 -fill green -outline {}]
	set yId [.c create oval 50 100 200 150 -fill red -outline black -width 3]
	set zId [.c create oval 50 100 200 150 -fill {} -outline black -width 3]
    list [expr {[.c find overlapping 176 104 177 105] eq {}}] \
	    [expr {[.c find overlapping 187 116 188 117] eq "$xId $yId"}] \
	    [expr {[.c find overlapping 192 142 193 143] eq {}}] \
	    [expr {[.c find overlapping 180 138 181 139] eq "$xId $yId"}] \
	    [expr {[.c find overlapping 61 142 62 143] eq {}}] \
	    [expr {[.c find overlapping 65 137 66 136] eq "$xId $yId"}] \
	    [expr {[.c find overlapping 62 108 63 109] eq {}}] \
	    [expr {[.c find overlapping 68 115 69 116] eq "$xId $yId"}]
} -cleanup {
	.c delete all
} -result {1 1 1 1 1 1 1 1}


test canvRect-9.1 {ScaleRectOval procedure} -setup {
    .c delete withtag all
} -body {
    .c create rect 100 300 200 350 -tags x
    .c scale x 50 100 2 4
    format {%.6g %.6g %.6g %.6g} {*}[.c coords x]
} -result {150 900 350 1100}

test canvRect-10.1 {TranslateRectOval procedure} -setup {
    .c delete withtag all
} -body {
    .c create rect 100 300 200 350 -tags x
    .c move x 100 -10
    format {%.6g %.6g %.6g %.6g} {*}[.c coords x]
} -result {200 290 300 340}




test canvRect-11.1 {RectOvalToPostscript procedure} -constraints {
     nonPortable macCrash
} -setup {
    .c delete withtag all
} -body {
    # Crashes on Mac because the XGetImage() call isn't implemented, causing a
    # dereference of NULL.
    # This test is non-portable because different color information
	# will get generated on different displays (e.g. mono displays
	# vs. color).
    .c configure -bd 0 -highlightthickness 0

    .c create rect 50 60 90 80 -fill black -stipple gray50 -outline {}
    .c create oval 100 150 200 200 -fill {} -outline #ff0000 -width 5
    update
    set x [.c postscript]
    string range $x [string first "-200 -150 translate" $x] end
} -result {-200 -150 translate
0 300 moveto 400 300 lineto 400 0 lineto 0 0 lineto closepath clip newpath
gsave
50 240 moveto 40 0 rlineto 0 -20 rlineto -40 0 rlineto closepath
0.000 0.000 0.000 setrgbcolor AdjustColor
clip 16 16 <5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555
aaaa> StippleFill
grestore




|
|



<



<


>
>
>


<
>

|
|
<
<
<
<
|
<
|
<
<
<
<
|
>
>
>
>
>
>
>
>
|
|
|
|
>
>
|
|
|
<
<
<
<
>
>
>
|


|
<
<
<
<
<
<
<
<

<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|
|
|
|
<

|
<
|
>


|

|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
<
<



<
<
|
|
<
|
<
<
|

<
<
<
<
<
|
<
<
|
>
|
|
<
<
|
|
<
|
<
<
|
|
|
<


<
<
|
<


>
>
|

<


<
<
|
|

<



<
<
|
|

<



<
<
|
|

<



<
<
|



<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
|
|
>
>
>
|
|
|
>
|
>
>
|
|
<
<

<
|
|
<
<
<
<
|
<
<
<
|
|
>
<
|
|
<
|
<
<
|
<
<
<
<
<
|
|
<
|
|
<
<
<
|
|
<
>
|
|
<
|
<
<

|
<
|
|
|
>
|
|
|
|
|
|
<
<
|
<
<
<
|
|
|
|
|
|
<
<
|
<
<
<
<
|
|
<
<
|
<
<
<
|
|
|
|
|
<
<
|
|
<
<
<
|
|
|
|
|
|
<
<
|
<
<
<
|
|
|
|
|
<
<
<
|

|
|
|
|
>
|
|
|
|
|
|
|
|
<
|
<
|
<
<
<
|
|
|
|
|
|
|
|
|
<
<
|
<
<
<
|
|
|
|
|
|
|
|
<
<
<
|

|

<


|
|

|

<


|
|

|
>
>
|
<
<
<
<


|
<
<

>





|







1
2
3
4
5
6
7
8
9

10
11
12

13
14
15
16
17
18
19

20
21
22
23




24

25




26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43




44
45
46
47
48
49
50








51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82

83
84
85
86
87
88
89


90
91

92


93
94

95


96
97

98


99
100

101


102
103



104
105
106


107
108

109


110
111





112


113
114
115
116


117
118

119


120
121
122

123
124


125

126
127
128
129
130
131

132
133


134
135
136

137
138
139


140
141
142

143
144
145


146
147
148

149
150
151


152
153
154
155









156


157












158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174


175

176
177




178



179
180
181

182
183

184


185





186
187

188
189



190
191

192
193
194

195


196
197

198
199
200
201
202
203
204
205
206
207


208



209
210
211
212
213
214


215




216
217


218



219
220
221
222
223


224
225



226
227
228
229
230
231


232



233
234
235
236
237



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253

254



255
256
257
258
259
260
261
262
263


264



265
266
267
268
269
270
271
272



273
274
275
276

277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292




293
294
295


296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# This file is a Tcl script to test out the procedures in tkRectOval.c,
# which implement canvas "rectangle" and "oval" items.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c
bind .c <1> {
    puts "button down at (%x,%y)"
}
update


set i 1
.c create rectangle 20 20 80 80 -tag test
foreach test {
    {-fill #ff0000 #ff0000




	    non-existent {unknown color name "non-existent"}}

    {-outline #123456 #123456




	    bad_color {unknown color name "bad_color"}}
    {-stipple gray50 gray50
	    bogus {bitmap "bogus" not defined}}
    {-tags {test a b c} {test a b c}
	    {} {}}
    {-width 6.0 6.0
	    abc {bad screen distance "abc"}}
} {
    lassign $test name goodValue goodResult badValue badResult
    test canvRect-1.$i "configuration options: good value for $name" {
	.c itemconfigure test $name $goodValue
	list [lindex [.c itemconfigure test $name] 4] [.c itemcget test $name]
    } [list $goodResult $goodResult]
    incr i
    if {$badValue ne ""} {
	test canvRect-1.$i "configuration options: bad value for $name" -body {
	    .c itemconfigure test $name $badValue
	} -returnCodes error -result $badResult




    }
    incr i
}
test canvRect-1.$i {configuration options} {
    .c itemconfigure test -tags {test xyz}
    .c itemcget xyz -tags
} {test xyz}










test canvRect-2.1 {CreateRectOval procedure} {
    list [catch {.c create rect} msg] $msg
} {1 {wrong # args: should be ".c create rect coords ?arg arg ...?"}}
test canvRect-2.2 {CreateRectOval procedure} {
    list [catch {.c create oval x y z} msg] $msg
} {1 {wrong # coordinates: expected 0 or 4, got 3}}
test canvRect-2.3 {CreateRectOval procedure} {
    list [catch {.c create rectangle x 2 3 4} msg] $msg
} {1 {bad screen distance "x"}}
test canvRect-2.4 {CreateRectOval procedure} {
    list [catch {.c create rectangle 1 y 3 4} msg] $msg
} {1 {bad screen distance "y"}}
test canvRect-2.5 {CreateRectOval procedure} {
    list [catch {.c create rectangle 1 2 z 4} msg] $msg
} {1 {bad screen distance "z"}}
test canvRect-2.6 {CreateRectOval procedure} {
    list [catch {.c create rectangle 1 2 3 q} msg] $msg
} {1 {bad screen distance "q"}}
test canvRect-2.7 {CreateRectOval procedure} {
    .c create rectangle 1 2 3 4 -tags x
    set result {}
    foreach element [.c coords x] {
	lappend result [format %.1f $element]
    }
    set result
} {1.0 2.0 3.0 4.0}
test canvRect-2.8 {CreateRectOval procedure} {
    list [catch {.c create rectangle 1 2 3 4 -gorp foo} msg] $msg
} {1 {unknown option "-gorp"}}


.c delete withtag all

.c create rectangle 10 20 30 40 -tags x
test canvRect-3.1 {RectOvalCoords procedure} {
    set result {}
    foreach element [.c coords x] {
	lappend result [format %.1f $element]
    }
    set result


} {10.0 20.0 30.0 40.0}
test canvRect-3.2 {RectOvalCoords procedure} {

    list [catch {.c coords x a 2 3 4} msg] $msg


} {1 {bad screen distance "a"}}
test canvRect-3.3 {RectOvalCoords procedure} {

    list [catch {.c coords x 1 b 3 4} msg] $msg


} {1 {bad screen distance "b"}}
test canvRect-3.4 {RectOvalCoords procedure} {

    list [catch {.c coords x 1 2 c 4} msg] $msg


} {1 {bad screen distance "c"}}
test canvRect-3.5 {RectOvalCoords procedure} {

    list [catch {.c coords x 1 2 3 d} msg] $msg


} {1 {bad screen distance "d"}}
test canvRect-3.6 {RectOvalCoords procedure} {nonPortable} {



    # Non-portable due to rounding differences.
    .c coords x 10 25 15 40
    .c bbox x


} {9 24 16 41}
test canvRect-3.7 {RectOvalCoords procedure} {

    list [catch {.c coords x 1 2 3 4 5} msg] $msg


} {1 {wrong # coordinates: expected 0 or 4, got 5}}






.c delete withtag all


.c create rectangle 10 20 30 40 -tags x -width 1
test canvRect-4.1 {ConfigureRectOval procedure} {
    list [catch {.c itemconfigure x -width abc} msg] $msg \
	    [.c itemcget x -width]


} {1 {bad screen distance "abc"} 1.0}
test canvRect-4.2 {ConfigureRectOval procedure} {

    list [catch {.c itemconfigure x -width -5} msg] $msg


} {1 {bad screen distance "-5"}}
test canvRect-4.3 {ConfigureRectOval procedure} {nonPortable} {
    # Non-portable due to rounding differences.

    .c itemconfigure x -width 10
    .c bbox x


} {5 15 35 45}

# I can't come up with any good tests for DeleteRectOval.

.c delete withtag all
.c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
test canvRect-5.1 {ComputeRectOvalBbox procedure} {nonPortable} {
    # Non-portable due to rounding differences:

    .c coords x 20 15 10 5
    .c bbox x


} {10 5 20 15}
test canvRect-5.2 {ComputeRectOvalBbox procedure} {nonPortable} {
    # Non-portable due to rounding differences:

    .c coords x 10 20 30 10
    .c itemconfigure x -width 1 -outline red
    .c bbox x


} {9 9 31 21}
test canvRect-5.3 {ComputeRectOvalBbox procedure} {nonPortable} {
    # Non-portable due to rounding differences:

    .c coords x 10 20 30 10
    .c itemconfigure x -width 2 -outline red
    .c bbox x


} {9 9 31 21}
test canvRect-5.4 {ComputeRectOvalBbox procedure} {nonPortable} {
    # Non-portable due to rounding differences:

    .c coords x 10 20 30 10
    .c itemconfigure x -width 3 -outline red
    .c bbox x


} {8 8 32 22}

# I can't come up with any good tests for DisplayRectOval.










.c delete withtag all


set x  [.c create rectangle 10 20 30 35 -tags x -fill green]












set y [.c create rectangle 15 25 25 30  -tags y -fill red]
test canvRect-6.1 {RectToPoint procedure} {
    .c itemconfigure y -outline {}
    list [.c find closest 14.9 28] [.c find closest 15.1 28] \
	    [.c find closest 24.9 28] [.c find closest 25.1 28]
} "$x $y $y $x"
test canvRect-6.2 {RectToPoint procedure} {
    .c itemconfigure y -outline {}
    list [.c find closest 20 24.9] [.c find closest 20 25.1] \
	    [.c find closest 20 29.9]  [.c find closest 20 30.1]
} "$x $y $y $x"
test canvRect-6.3 {RectToPoint procedure} {
    .c itemconfigure y -width 1 -outline black
    list [.c find closest 14.4 28] [.c find closest 14.6 28] \
	    [.c find closest 25.4 28] [.c find closest 25.6 28]
} "$x $y $y $x"
test canvRect-6.4 {RectToPoint procedure} {


    .c itemconfigure  y -width 1 -outline black

    list [.c find closest 20 24.4] [.c find closest 20 24.6] \
	    [.c find closest 20 30.4] [.c find closest 20 30.6]




} "$x $y $y $x"



.c itemconfigure x -fill {} -outline black -width 3
.c itemconfigure y -outline {}
test canvRect-6.5 {RectToPoint procedure} {

    list [.c find closest 13.2 28] [.c find closest 13.3 28] \
	    [.c find closest 26.7 28] [.c find closest 26.8 28]

} "$x $y $y $x"


test canvRect-6.6 {RectToPoint procedure} {





    list [.c find closest 20 23.2] [.c find closest 20 23.3] \
	    [.c find closest 20 31.7] [.c find closest 20 31.8]

} "$x $y $y $x"
.c delete withtag all



set x [.c create rectangle 10 20 30 40 -outline {} -fill black]
set y [.c create rectangle 40 40 50 50 -outline {} -fill black]

test canvRect-6.7 {RectToPoint procedure} {
    list [.c find closest 35 35] [.c find closest 36 36] \
	    [.c find closest 37 37] [.c find closest 38 38]

} "$x $y $y $y"



.c delete withtag all

set x  [.c create rectangle 10 20 30 35 -fill green -outline {}]
set y [.c create rectangle 40 45 60 70 -fill red -outline black -width 3]
set z [.c create rectangle 100 150 120 170 -fill {} -outline black -width 3]
test canvRect-7.1 {RectToArea procedure} {
    list [.c find overlapping 20 50 38 60] \
	    [.c find overlapping 20 50 39 60] \
	    [.c find overlapping 20 50 70 60] \
	    [.c find overlapping 61 50 70 60] \
	    [.c find overlapping 62 50 70 60]
} "{} $y $y $y {}"


test canvRect-7.2 {RectToArea procedure} {



    list [.c find overlapping 45 20 55 43] \
	    [.c find overlapping 45 20 55 44] \
	    [.c find overlapping 45 20 55 80] \
	    [.c find overlapping 45 71 55 80] \
	    [.c find overlapping 45 72 55 80]
} "{} $y $y $y {}"


test canvRect-7.3 {RectToArea procedure} {




    list [.c find overlapping 5 25 9.9 30] [.c find overlapping 5 25 10.1 30]
} "{} $x"


test canvRect-7.4 {RectToArea procedure} {



    list [.c find overlapping 102 152 118 168] \
	    [.c find overlapping 101 152 118 168] \
	    [.c find overlapping 102 151 118 168] \
	    [.c find overlapping 102 152 119 168] \
	    [.c find overlapping 102 152 118 169]


} "{} $z $z $z $z"
test canvRect-7.5 {RectToArea procedure} {



    list [.c find enclosed 20 40 38 80] \
	    [.c find enclosed 20 40 39 80] \
	    [.c find enclosed 20 40 70 80] \
	    [.c find enclosed 61 40 70 80] \
	    [.c find enclosed 62 40 70 80]
} "{} {} $y {} {}"


test canvRect-7.6 {RectToArea procedure} {



    list [.c find enclosed 20 20 65 43] \
	    [.c find enclosed 20 20 65 44] \
	    [.c find enclosed 20 20 65 80] \
	    [.c find enclosed 20 71 65 80] \
	    [.c find enclosed 20 72 65 80]



} "{} {} $y {} {}"

.c delete withtag all
set x  [.c create oval 50 100 200 150 -fill green -outline {}]
set y [.c create oval 50 100 200 150 -fill red -outline black -width 3]
set z [.c create oval 50 100 200 150 -fill {} -outline black -width 3]
test canvRect-8.1 {OvalToArea procedure} {
    list [.c find overlapping 20 120 48 130] \
	    [.c find overlapping 20 120 49 130] \
	    [.c find overlapping 20 120 50.2 130] \
	    [.c find overlapping 20 120 300 130] \
	    [.c find overlapping 60 120 190 130] \
	    [.c find overlapping 199.9 120 300 130] \
	    [.c find overlapping 201 120 300 130] \
	    [.c find overlapping 202 120 300 130]

} "{} {$y $z} {$x $y $z} {$x $y $z} {$x $y} {$x $y $z} {$y $z} {}"

test canvRect-8.2 {OvalToArea procedure} {



    list [.c find overlapping 100 50 150 98] \
	    [.c find overlapping 100 50 150 99] \
	    [.c find overlapping 100 50 150 100.1] \
	    [.c find overlapping 100 50 150 200] \
	    [.c find overlapping 100 110 150 140] \
	    [.c find overlapping 100 149.9 150 200] \
	    [.c find overlapping 100 151 150 200] \
	    [.c find overlapping 100 152 150 200]
} "{} {$y $z} {$x $y $z} {$x $y $z} {$x $y} {$x $y $z} {$y $z} {}"


test canvRect-8.3 {OvalToArea procedure} {



    list [.c find overlapping 176 104 177 105] \
	    [.c find overlapping 187 116 188 117] \
	    [.c find overlapping 192 142 193 143] \
	    [.c find overlapping 180 138 181 139] \
	    [.c find overlapping 61 142 62 143] \
	    [.c find overlapping 65 137 66 136] \
	    [.c find overlapping 62 108 63 109] \
	    [.c find overlapping 68 115 69 116]



} "{} {$x $y} {} {$x $y} {} {$x $y} {} {$x $y}"

test canvRect-9.1 {ScaleRectOval procedure} {
    .c delete withtag all

    .c create rect 100 300 200 350 -tags x
    .c scale x 50 100 2 4
    .c coords x
} {150.0 900.0 350.0 1100.0}

test canvRect-10.1 {TranslateRectOval procedure} {
    .c delete withtag all

    .c create rect 100 300 200 350 -tags x
    .c move x 100 -10
    .c coords x
} {200.0 290.0 300.0 340.0}

# This test is non-portable because different color information
# will get generated on different displays (e.g. mono displays
# vs. color).
test canvRect-11.1 {RectOvalToPostscript procedure} {nonPortable macCrash} {




    # Crashes on Mac because the XGetImage() call isn't implemented, causing a
    # dereference of NULL.



    .c configure -bd 0 -highlightthickness 0
    .c delete withtag all
    .c create rect 50 60 90 80 -fill black -stipple gray50 -outline {}
    .c create oval 100 150 200 200 -fill {} -outline #ff0000 -width 5
    update
    set x [.c postscript]
    string range $x [string first "-200 -150 translate" $x] end
} {-200 -150 translate
0 300 moveto 400 300 lineto 400 0 lineto 0 0 lineto closepath clip newpath
gsave
50 240 moveto 40 0 rlineto 0 -20 rlineto -40 0 rlineto closepath
0.000 0.000 0.000 setrgbcolor AdjustColor
clip 16 16 <5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555aaaa5555
aaaa> StippleFill
grestore
465
466
467
468
469
470
471
472
473
474
475
end
%%EOF
}

# cleanup
cleanupTests
return











<
<
<
<
322
323
324
325
326
327
328




end
%%EOF
}

# cleanup
cleanupTests
return




Changes to tests/canvText.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


25
26


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51





52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89




90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325


326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352






353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874



875
876
877
878
879
880
881









882

883

884

885
886
887
888


889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

909
910

911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926

927

928

929
930
931

932
933
934

935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
# This file is a Tcl script to test out the procedures in tkCanvText.c,
# which implement canvas "text" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Canvas used in 1.* - 17.* tests
canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c
update

# Item used in 1.*  tests
.c create text 20 20 -tag test
test canvText-1.1 {configuration options: good value for "anchor"} -body {


    .c itemconfigure test -anchor nw
    list [lindex [.c itemconfigure test -anchor] 4] [.c itemcget test -anchor]


} -result {nw nw}
test canvasText-1.2 {configuration options: bad value for "anchor"} -body {
    .c itemconfigure test -anchor xyz
} -returnCodes error -result {bad anchor position "xyz": must be n, ne, e, se, s, sw, w, nw, or center}
test canvText-1.3 {configuration options: good value for "fill"} -body {
    .c itemconfigure test -fill #ff0000
    list [lindex [.c itemconfigure test -fill] 4] [.c itemcget test -fill]
} -result {{#ff0000} #ff0000}
test canvasText-1.4 {configuration options: bad value for "fill"} -body {
    .c itemconfigure test -fill xyz
} -returnCodes error -result {unknown color name "xyz"}
test canvText-1.5 {configuration options: good value for "fill"} -body {
    .c itemconfigure test -fill {}
    list [lindex [.c itemconfigure test -fill] 4] [.c itemcget test -fill]
} -result {{} {}}
test canvText-1.6 {configuration options: good value for "font"} -body {
    .c itemconfigure test -font {Times 40}
    list [lindex [.c itemconfigure test -font] 4] [.c itemcget test -font]
} -result {{Times 40} {Times 40}}
test canvasText-1.7 {configuration options: bad value for "font"} -body {
    .c itemconfigure test -font {}
} -returnCodes error -result {font "" doesn't exist}
test canvText-1.8 {configuration options: good value for "justify"} -body {
    .c itemconfigure test -justify left
    list [lindex [.c itemconfigure test -justify] 4] [.c itemcget test -justify]





} -result {left left}

test canvasText-1.9 {configuration options: bad value for "justify"} -body {
    .c itemconfigure test -justify xyz
} -returnCodes error -result {bad justification "xyz": must be left, right, or center}
test canvText-1.10 {configuration options: good value for "stipple"} -body {
    .c itemconfigure test -stipple gray50
    list [lindex [.c itemconfigure test -stipple] 4] [.c itemcget test -stipple]
} -result {gray50 gray50}
test canvasText-1.11 {configuration options: bad value for "stipple"} -body {
    .c itemconfigure test -stipple abcxyz
} -returnCodes error -result {bitmap "abcxyz" not defined}
test canvText-1.12 {configuration options: good value for "underline"} -body {
    .c itemconfigure test -underline 0
    list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline]
} -result {0 0}
test canvasText-1.13 {configuration options: bad value for "underline"} -body {
    .c itemconfigure test -underline xyz
} -returnCodes error -result {expected integer but got "xyz"}
test canvText-1.14 {configuration options: good value for "width"} -body {
    .c itemconfigure test -width 6
    list [lindex [.c itemconfigure test -width] 4] [.c itemcget test -width]
} -result {6 6}
test canvasText-1.15 {configuration options: bad value for "width"} -body {
    .c itemconfigure test -width xyz
} -returnCodes error -result {bad screen distance "xyz"}
test canvText-1.16 {configuration options: good value for "tags"} -body {
    .c itemconfigure test -tags {test a b c}
    list [lindex [.c itemconfigure test -tags] 4] [.c itemcget test -tags]
} -result {{test a b c} {test a b c}}
test canvasText-1.17 {configuration options: bad value for "angle"} -body {
    .c itemconfigure test -angle xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test canvasText-1.18 {configuration options: good value for "angle"} -body {
    .c itemconfigure test -angle 32.5
    list [lindex [.c itemconfigure test -angle] 4] [.c itemcget test -angle]
} -result {32.5 32.5}


test canvasText-1.19 {configuration options: bounding of "angle"} -body {
    .c itemconfigure test -angle 390




    set result [.c itemcget test -angle]
    .c itemconfigure test -angle -30
    lappend result [.c itemcget test -angle]
    .c itemconfigure test -angle -360
    lappend result [.c itemcget test -angle]
} -result {30.0 330.0 0.0}
.c delete test


test canvText-2.1 {CreateText procedure: args} -body {
    .c create text
} -returnCodes {error} -result {wrong # args: should be ".c create text coords ?arg ...?"}
test canvText-2.2 {CreateText procedure: args} -body {
    .c create text xyz 0
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-2.3 {CreateText procedure: args} -body {
    .c create text 0 xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-2.4 {CreateText procedure: args} -body {
    .c create text 0 0 -xyz xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-xyz"}
test canvText-2.5 {CreateText procedure} -body {
    .c create text 0 0 -tags x
    .c coords x
} -cleanup {
    .c delete x

} -result {0.0 0.0}


test canvText-3.1 {TextCoords procedure} -body {
    .c create text 20 20 -tag test
    .c coords test 0 0
    update


    .c coords test
} -cleanup {
    .c delete test
} -result {0.0 0.0}
test canvText-3.2 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test xyz 0
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-3.3 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 0 xyz
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-3.4 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 10 10
    set result {}
    foreach element [.c coords test] {
	lappend result [format %.1f $element]
    }
    return $result
} -cleanup {
    .c delete test
} -result {10.0 10.0}
test canvText-3.5 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 10
} -cleanup {
    .c delete test
} -returnCodes {error} -result {wrong # coordinates: expected 2, got 1}
test canvText-3.6 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 10 10 10
} -cleanup {
    .c delete test
} -returnCodes {error} -result {wrong # coordinates: expected 0 or 2, got 3}


test canvText-4.1 {ConfigureText procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c itemconfig test -fill xyz
} -cleanup {
    .c delete test
} -returnCodes {error} -result {unknown color name "xyz"}
test canvText-4.2 {ConfigureText procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c itemconfig test -fill blue
    .c itemcget test -fill
} -cleanup {
    .c delete test
} -result {blue}
test canvText-4.3 {ConfigureText procedure: construct font gcs} -setup {
    .c create text 20 20 -tag test
} -body {
    .c itemconfig test -font "times 20" -fill black -stipple gray50
    list [.c itemcget test -font] [.c itemcget test -fill] [.c itemcget test -stipple]
} -cleanup {
    .c delete test
} -result {{times 20} black gray50}
test canvText-4.4 {ConfigureText procedure: construct cursor gc} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c icursor test 3

    # Both black -> cursor becomes white.
    .c config -insertbackground black
    .c config -selectbackground black
    .c itemconfig test -just left
    update

    # Both same color (and not black) -> cursor becomes black.
    .c config -insertbackground red
    .c config -selectbackground red
    .c itemconfig test -just left
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-4.5 {ConfigureText procedure: adjust selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
    set x {}
} -body {
    .c itemconfig test -text "abcdefghi"
    .c select from test 2
    .c select to test 6
    lappend x [selection get]
    .c dchars test 1 end
    lappend x [catch {selection get}]
    .c insert test end "bcdefghi"
    .c select from test 2
    .c select to test 6
    lappend x [selection get]
    .c dchars test 4 end
    lappend x [selection get]
    .c insert test end "efghi"
    .c select from test 6
    .c select to test 2
    lappend x [selection get]
    .c dchars test 4 end
    lappend x [selection get]
} -cleanup {
    .c delete test
} -result {cdefg 1 cdefg cd cdef cd}
test canvText-4.6 {ConfigureText procedure: adjust cursor} -setup {
    .c create text 20 20 -tag test
} -body {
    .c itemconfig test -text "abcdefghi"

    .c icursor test 6
    .c dchars test 4 end
    .c index test insert
} -cleanup {
	.c delete test
} -result 4


test canvText-5.1 {ConfigureText procedure: adjust cursor} -body {
    .c create text 10 10 -tag x -fill blue -font "times 40" -stipple gray50 \
	-text "xyz"
    .c delete x
} -result {}


test canvText-6.1 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor n; .c bbox test] \
	      eq "[expr {-$ax/2-1}] 0 [expr {$ax/2+1}] $ay"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.2 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor nw; .c bbox test] \
	      eq "-1 0 [expr {$ax+1}] $ay"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.3 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor w; .c bbox test] \
	      eq "-1 [expr -$ay/2] [expr $ax+1] [expr $ay/2]"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.4 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor sw; .c bbox test] \
	      eq "-1 -$ay [expr $ax+1] 0"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.5 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0


    expr {[.c itemconfig test -anchor s; .c bbox test] \
	      eq "[expr -$ax/2-1] -$ay [expr $ax/2+1] 0"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.6 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor se; .c bbox test] \
	      eq "[expr -$ax-1] -$ay 1 0"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.7 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor e; .c bbox test]\






	      eq "[expr -$ax-1] [expr -$ay/2] 1 [expr $ay/2]"}
} -cleanup {

    .c delete test
} -result 1
test canvText-6.8 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor ne; .c bbox test] \
	      eq "[expr -$ax-1] 0 1 $ay"}
} -cleanup {
    .c delete test
} -result 1
test canvText-6.9 {ComputeTextBbox procedure} -constraints fonts -setup {
    .c delete test
} -body {
    set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
    set ay [font metrics $font -linespace]
    set ax [font measure $font 0]
    .c create text 0 0 -tag test
    .c itemconfig test -font $font -text 0
    expr {[.c itemconfig test -anchor center; .c bbox test] \
	      eq "[expr -$ax/2-1] [expr -$ay/2] [expr $ax/2+1] [expr $ay/2]"}
} -cleanup {
    .c delete test
} -result 1


#.c delete test
#.c create text 20 20 -tag test
#focus -force .c
#.c focus test
focus .c
.c focus test
.c itemconfig test -text "abcd\nefghi\njklmnopq"
test canvText-7.1 {DisplayText procedure: stippling} -body {
    .c create text 20 20 -tag test
    .c itemconfig test -stipple gray50
    update
    .c itemconfig test -stipple {}
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.2 {DisplayText procedure: draw selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    .c select from test 0
    .c select to test end
    update
    selection get
} -cleanup {
    .c delete test
} -result "abcd\nefghi\njklmnopq"
test canvText-7.3 {DisplayText procedure: selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    .c select from test 0
    .c select to test end
    update
    selection get
} -cleanup {
    .c delete test
} -result "abcd\nefghi\njklmnopq"
test canvText-7.4 {DisplayText procedure: one line selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    .c select from test 2
    .c select to test 3
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.5 {DisplayText procedure: multi-line selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    .c select from test 2
    .c select to test 12
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.6 {DisplayText procedure: draw cursor} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    .c icursor test 3
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.7 {DisplayText procedure: selected text different color} -setup {
    .c create text 20 20 -tag test
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    focus .c
    .c focus test
} -body {
    .c config -selectforeground blue
    .c itemconfig test -anchor n
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.8 {DisplayText procedure: not selected} -setup {
    .c create text 20 20 -tag test
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    focus .c
    .c focus test
} -body {
    .c select clear
    update
} -cleanup {
    .c delete test
} -result {}
test canvText-7.9 {DisplayText procedure: select end} -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t +0+0
    canvas .t.c
    pack .t.c
    set id [.t.c create text 0 0 -text Dummy -anchor nw]
    update
    .t.c select from $id 0
    .t.c select to $id end
    update
    #catch {destroy .t}
    update
} -cleanup {
    destroy .t
} -result {}

test canvText-8.1 {TextInsert procedure: 0 length insert} -setup {
    .c create text 20 20 -tag test
    .c itemconfig test -text "abcd\nefghi\njklmnopq"
    focus .c
    .c focus test
} -body {
    .c insert test end {}
} -cleanup {
    .c delete test
} -result {}
test canvText-8.2 {TextInsert procedure: before beginning/after end} -body {
    # Can't test this because GetTextIndex filters out those numbers.
} -result {}
test canvText-8.3 {TextInsert procedure: inserting in a selected item} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 1 "xyz"
    .c itemcget test -text
} -result {axyzbcdefg}
test canvText-8.4 {TextInsert procedure: inserting before selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 1 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} -result {5 7}
test canvText-8.5 {TextInsert procedure: inserting in selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 3 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} -result {2 7}
test canvText-8.6 {TextInsert procedure: inserting after selection} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 5 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} -result {2 4}
test canvText-8.7 {TextInsert procedure: inserting in unselected item} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c select clear
    .c insert test 5 "xyz"
    .c itemcget test -text
} -result {abcdexyzfg}
test canvText-8.8 {TextInsert procedure: inserting before cursor} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c icursor test 3
    .c insert test 2 "xyz"
    .c index test insert
} -result 6
test canvText-8.9 {TextInsert procedure: inserting after cursor} -setup {
    .c create text 20 20 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefg"
    .c icursor test 3
    .c insert test 4 "xyz"
    .c index test insert
} -result 3

# Item used in 9.* tests
.c create text 20 20 -tag test
test canvText-9.1 {TextInsert procedure: before beginning/after end} -body {
    # Can't test this because GetTextIndex filters out those numbers.
} -result {}
test canvText-9.2 {TextInsert procedure: start > end} -body {
    .c itemconfig test -text "abcdefg"
    .c dchars test 4 2
    .c itemcget test -text
} -result {abcdefg}
test canvText-9.3 {TextInsert procedure: deleting from a selected item} -body {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c dchars test 3 5
    .c itemcget test -text
} -result {abcg}
test canvText-9.4 {TextInsert procedure: deleting before start} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 1 1
    list [.c index test sel.first] [.c index test sel.last]
} -result {3 7}
test canvText-9.5 {TextInsert procedure: keep start > first char deleted} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 2 6
    list [.c index test sel.first] [.c index test sel.last]
} -result {2 3}
test canvText-9.6 {TextInsert procedure: deleting inside selection} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 6 6
    list [.c index test sel.first] [.c index test sel.last]
} -result {4 7}
test canvText-9.7 {TextInsert procedure: keep end > first char deleted} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 6 10
    list [.c index test sel.first] [.c index test sel.last]
} -result {4 5}
test canvText-9.8 {TextInsert procedure: selectFirst > selectLast: deselect} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 3 10
    .c index test sel.first
} -returnCodes {error} -result {selection isn't in item}
test canvText-9.9 {TextInsert procedure: selectFirst <= selectLast} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 4 7
    list [.c index test sel.first] [.c index test sel.last]
} -result {4 4}
test canvText-9.10 {TextInsert procedure: move anchor} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 6
    .c select to test 8
    .c dchars test 2 4
    .c select to test 1
    list [.c index test sel.first] [.c index test sel.last]
} -result {1 2}
test canvText-9.11 {TextInsert procedure: keep anchor >= first} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 6
    .c select to test 8
    .c dchars test 5 7
    .c select to test 1
    list [.c index test sel.first] [.c index test sel.last]
} -result {1 4}
test canvText-9.12 {TextInsert procedure: anchor doesn't move} -body {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 2
    .c select to test 5
    .c dchars test 6 8
    .c select to test 8
    list [.c index test sel.first] [.c index test sel.last]
} -result {2 8}
test canvText-9.13 {TextInsert procedure: move cursor} -body {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 6
    .c dchars test 2 4
    .c index test insert
} -result 3
test canvText-9.14 {TextInsert procedure: keep cursor >= first} -body {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 6
    .c dchars test 2 10
    .c index test insert
} -result 2
test canvText-9.15 {TextInsert procedure: cursor doesn't move} -body {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 5
    .c dchars test 7 9
    .c index test insert
} -result 5
.c delete test


test canvText-10.1 {TextToPoint procedure} -body {
    .c create text 0 0 -tag test
    .c itemconfig test -text 0 -anchor center
    .c index test @0,0
} -cleanup {
	.c delete test
} -result 0


test canvText-11.1 {TextToArea procedure} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text 0 -anchor center
    set res1 [.c find overlapping 0 0 1 1]
    set res2 [.c find withtag test]
    expr {$res1 eq $res2}
} -cleanup {
    .c delete test
} -result 1
test canvText-11.2 {TextToArea procedure} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text 0 -anchor center
    .c find overlapping 1000 1000 1001 1001
} -cleanup {
	.c delete test
} -result {}


test canvText-12.1 {ScaleText procedure} -body {
    .c create text 100 100 -tag test
    .c scale all 50 50 2 2
    format {%.6g %.6g} {*}[.c coords test]
} -cleanup {
	.c delete test
} -result {150 150}


test canvText-13.1 {TranslateText procedure} -body {
	.c create text 100 100 -tag test
    .c move all 10 10
    format {%.6g %.6g} {*}[.c coords test]
} -cleanup {
	.c delete test
} -result {110 110}


test canvText-14.1 {GetTextIndex procedure} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefghijklmno" -anchor nw
    .c select from test 5
    .c select to test 8
    .c icursor test 12
    .c coords test 0 0

    list [.c index test end] [.c index test insert] \
	[.c index test sel.first] [.c index test sel.last] \
	[.c index test @0,0] \
	[.c index test -1] [.c index test 10] [.c index test 100]
} -cleanup {
    .c delete test
} -result {15 12 5 8 0 0 10 15}
test canvText-14.2 {GetTextIndex procedure: select error} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c select clear
    .c index test sel.first
} -cleanup {
    .c delete test
} -returnCodes {error} -result {selection isn't in item}
test canvText-14.3 {GetTextIndex procedure: select error} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c select clear
    .c index test sel.last
} -cleanup {
    .c delete test
} -returnCodes {error} -result {selection isn't in item}
test canvText-14.4 {GetTextIndex procedure: select error} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c select clear
    .c index test sel.
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad index "sel."}
test canvText-14.5 {GetTextIndex procedure: bad int or unknown index} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test

} -body {
    .c index test xyz
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad index "xyz"}
test canvText-14.6 {select clear errors} -setup {
    .c create text 0 0 -tag test
} -body {
    .c select clear test
} -cleanup {
    .c delete test
} -returnCodes error -result "wrong \# args: should be \".c select clear\""
test canvText-14.7 {GetTextIndex procedure: pixel index with non-default scrollregion} -setup {
    canvas .cc
    .cc create text 50 80 -tag test -text Hello -anchor nw -font "Arial 30"
    foreach {xmin ymin xmax ymax} [.cc bbox test] {}
} -body {
    # default -scrollregion
    set res [.cc index test @$xmin,$ymin]
    lappend res [.cc index test @$xmax,$ymax]
    # -scrollregion with positive upper left corner
    .cc configure -scrollregion {50 50 700 900}
    lappend res [.cc index test @$xmin,$ymin]
    lappend res [.cc index test @$xmax,$ymax]
    # -scrollregion with negative upper left corner
    .cc configure -scrollregion {-100 -100 700 900}
    lappend res [.cc index test @$xmin,$ymin]
    lappend res [.cc index test @$xmax,$ymax]
} -cleanup {
    destroy .cc
} -result {0 5 0 5 0 5}

test canvText-15.1 {SetTextCursor procedure} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefghijklmno" -anchor nw
    .c itemconfig -text "abcdefg"
    .c icursor test 3
    .c index test insert
} -cleanup {
    .c delete test
} -result 3

test canvText-16.1 {GetSelText procedure} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
} -body {
    .c itemconfig test -text "abcdefghijklmno" -anchor nw
    .c select from test 5
    .c select to test 8
    selection get
} -cleanup {
    .c delete test
} -result {fghi}

test canvText-17.1 {TextToPostscript procedure} -setup {
    .c delete all
    set result {findfont [font actual $font -size] scalefont ISOEncode setfont
0.000 0.000 0.000 setrgbcolor AdjustColor
0 100 200 \[
\[(000)\]
\[(000)\]
\[(00)\]
\] $ay -0.5 0 0 false DrawText
grestore
restore showpage

%%Trailer
end
%%EOF
}
} -body {
    set font {Courier 12 italic}
    set ax [font measure $font 0]
    set ay [font metrics $font -linespace]



    .c config -height 300 -highlightthickness 0 -bd 0
    update
    .c create text 100 100 -tags test
    .c itemconfig test -font $font -text "00000000" -width [expr 3*$ax]
    .c itemconfig test -anchor n -fill black
    set x [.c postscript]
    set x [string range $x [string first "findfont " $x] end]









    expr {$x eq [subst $result] ? "ok" : $x}

} -result ok



test canvText-18.1 {bug fix 2525, find enclosed on text with newlines} -setup {
    destroy .c
} -body {
    pack [canvas .c]


    .c create text 100 100 -text Hello\n -anchor nw
    set bbox [.c bbox 1]
    set x2 [lindex $bbox 2]
    set y2 [lindex $bbox 3]
    incr y2
    update
    .c find enclosed 99 99 [expr $x2 + 1] [expr $y2 + 1]
} -cleanup {
    destroy .c
    unset -nocomplain bbox x2 y2
} -result 1

test canvText-19.1 {patch 1006286, leading space caused wrap under Win32} -setup {
    destroy .c
    set c [canvas .c -bg black -width 964]
    pack $c
    $c delete all
    after 100 "set done 1"; vwait done
} -body {
    set f {Arial 28 bold}

    set s1 {    Yeah-ah-ah-ah-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-Yow}
    set s2 {    Yeah ah ah ah oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh Yow}

    $c create text 21 18 \
        -font $f \
        -text $s1 \
        -fill white \
        -width 922 \
        -anchor nw \
        -tags tbox1
    $c create rect {*}[$c bbox tbox1] -outline red

    $c create text 21 160 \
        -font $f \
        -text $s2 \
        -fill white \
        -width 922 \
        -anchor nw \
        -tags tbox2
    $c create rect {*}[$c bbox tbox2] -outline red

    after 500 "set done 1" ; vwait done

    set results [list]

    $c select from tbox2 4
    $c select to tbox2 8
    lappend results [selection get]

    $c select from tbox1 4
    $c select to tbox1 8
    lappend results [selection get]

    array set metrics [font metrics $f]
    set x [expr {21 + [font measure $f "    "] \
        + ([font measure {Arial 28 bold} "Y"] / 2)}]
    set y1 [expr {18 + ($metrics(-linespace) / 2)}]
    set y2 [expr {160 + ($metrics(-linespace) / 2)}]

    lappend results [$c index tbox1 @$x,$y1]
    lappend results [$c index tbox2 @$x,$y2]
} -cleanup {
    destroy .c
} -result {{Yeah } Yeah- 4 4}

test canvText-20.1 {angled text bounding box} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    destroy .c
    canvas .c
    proc transpose {bbox} {
	lassign $bbox a b c d
	list $b $a $d $c
    }
} -body {
    .c create text 2 2 -tag t -anchor center -text 0 -font {Helvetica 24}
    set bb0 [.c bbox t]
    .c itemconf t -angle 90
    set bb1 [.c bbox t]
    .c itemconf t -angle 180
    set bb2 [.c bbox t]
    .c itemconf t -angle 270
    set bb3 [.c bbox t]
    list [expr {$bb0 eq $bb2 ? "ok" : "$bb0,$bb2"}] \
	[expr {$bb1 eq $bb3 ? "ok" : "$bb1,$bb3"}] \
	[expr {$bb0 eq [transpose $bb1] ? "ok" : "$bb0,$bb1"}] \
} -cleanup {
    destroy .c
    rename transpose {}
} -result {ok ok ok}


test canvText-20.2 {crash on angled text selection (X11, without xft) - bug 2712f43f6e} -setup {
    destroy .c
    canvas .c -background bisque -selectforeground green2
    grid .c
    set id [.c create text 50 150 -anchor w -text "Angled text" \
	    -angle 30 -font {Helvetica 32} -fill darkblue]
} -body {
    .c select clear
    .c select from $id 0
    .c select to $id 8 ; update    ;  # used to crash on X11 (--disable-xft build only)
} -cleanup {
    destroy .c
} -result {}

# cleanup
cleanupTests
return




|
|



<



<
<
<
<




|

|
>
>
|
|
>
>
|
<
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
|
<
>
>
>
>
>
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
>
>
|
|
>
>
>
>
|
|
|
|
|
<

|

|
|
|
|
|
<
<
|
|
|
<
<
|
|
|
<
<
|
|

|
<

>
|

|
<
|
|
|
>
>

<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<





|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|

<
|
<
<
|
<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<
<
<




>





>





|
<
<
|
<
<
<

<


















<
<
|
|
<
<

>



<
<
<
|

|
|
<

<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<

>
>
|
|
|
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
>
>
>
>
>
>
|
|
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<



|
<




|
<
<
|
<
<
<
<
<




<
<
|
|
<
<
<
<
<




<
<
|
|
<
<
<
<
<



<
<
<
<
<
<
<
|
|



|
<
<
|
<
<
<
<
<


|
<
<
|
<
<
<
<
<



|
<
<
|
<
<
<
<
<


|
<
<
|
|
<











|
<
<

|
<
<
<
<
<

|
<
<
|

|
|
<
<
<
<





|
|
<
<
<
<





|
|
<
<
<
<





|
|
<
<
<
<





|
|
<
<
<
<




|
|
<
<
<
<




|
|
<
<
<
<




|

<
<
|

|
|



|
|





|
|





|
|





|
|





|
|





|
|




|
|
|





|
|






|
|






|
|






|
|




|
|




|
|




<
<
|

|
|


<
<
<
|

|
<
<
|
<

|
|
<
<
<
<
|
<
<
|
<


<
<
<
|

|
|


<
<
|

<
|
|


<
<
|

<
<
<
<
<
<
|
|
|
|
|
>




<
<
|
|
<
<
<
<

|
<
<
|
|
<
<
<
<

|
<
<
|
|
<
<
<
<

|
<
<
|
|
<
<
|
>
<
<
<
<
<
|
<
<

<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<



|
<
<

|
<
<
<
<




<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
>
>
>







>
>
>
>
>
>
>
>
>
|
>
|
>
|
>
|
|
<
|
>
>






|

<



|
|



|
|

>


>







|
>







|
>
|
>

>



>



>





>


<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>

<
<
<
<
<
<
<
<
<
<
<
<
<




1
2
3
4
5
6
7
8
9

10
11
12




13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28






29

30





31




32

33
34
35
36
37
38
39
40

















41














42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64


65
66
67


68
69
70


71
72
73
74

75
76
77
78
79

80
81
82
83
84
85


86
87


88


89
90


91


92
93


94
95
96
97
98
99


100
101


102


103
104


105


106
107

108


109


110
111


112
113


114
115


116
117


118
119




120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136


137



138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156


157
158


159
160
161
162
163



164
165
166
167

168

169
























































170
171


172
173
174
175
176
177








178
179
180










181
182
183
184
185
186
187
188
189
190
191
192




























193





194
195
196
197

198
199
200
201
202


203





204
205
206
207


208
209





210
211
212
213


214
215





216
217
218







219
220
221
222
223
224


225





226
227
228


229





230
231
232
233


234





235
236
237


238
239

240
241
242
243
244
245
246
247
248
249
250
251


252
253





254
255


256
257
258
259




260
261
262
263
264
265
266




267
268
269
270
271
272
273




274
275
276
277
278
279
280




281
282
283
284
285
286
287




288
289
290
291
292
293




294
295
296
297
298
299




300
301
302
303
304
305


306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403


404
405
406
407
408
409



410
411
412


413

414
415
416




417


418

419
420



421
422
423
424
425
426


427
428

429
430
431
432


433
434






435
436
437
438
439
440
441
442
443
444


445
446




447
448


449
450




451
452


453
454




455
456


457
458


459
460





461


462


463



















464
465





466
467
468
469


470
471




472
473
474
475


476
477

















478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571



572






















573
574
575













576
577
578
579
# This file is a Tcl script to test out the procedures in tkCanvText.c,
# which implement canvas "text" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands





canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c
update

set i 1
.c create text 20 20 -tag test

set font "-adobe-times-medium-r-normal--*-200-*-*-*-*-*-*"
set ay [font metrics $font -linespace]
set ax [font measure $font 0]

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]


foreach test {
    {-anchor nw nw xyz {bad anchor position "xyz": must be n, ne, e, se, s, sw, w, nw, or center}}






    {-fill #ff0000 #ff0000 xyz {unknown color name "xyz"}}

    {-fill {} {} {} {}}





    {-font {Times 40} {Times 40} {} {font "" doesn't exist}}




    {-justify left left xyz {bad justification "xyz": must be left, right, or center}}

    {-stipple gray50 gray50 xyz {bitmap "xyz" not defined}}
    {-tags {test a b c} {test a b c} {} {}}
    {-text xyz xyz {} {}}
    {-underline 0 0 xyz {expected integer but got "xyz"}}
    {-width 6 6 xyz {bad screen distance "xyz"}}
} {
    lassign $test name goodValue goodResult badValue badResult
    test canvText-1.$i "configuration options: good value for $name" {

















	.c itemconfigure test $name $goodValue














	list [lindex [.c itemconfigure test $name] 4] [.c itemcget test $name]
    } [list $goodResult $goodResult]
    incr i
    if {$badValue ne ""} {
	test canvText-1.$i "configuration options: bad value for $name" -body {
	    .c itemconfigure test $name $badValue
	} -returnCodes error -result $badResult
    }
    incr i
}
test canvText-1.$i {configuration options} {
    .c itemconfigure test -tags {test xyz}
    .c itemcget xyz -tags
} {test xyz}


.c delete test
.c create text 20 20 -tag test

test canvText-2.1 {CreateText procedure: args} {
    list [catch {.c create text} msg] $msg
} {1 {wrong # args: should be ".c create text coords ?arg arg ...?"}}
test canvText-2.2 {CreateText procedure: args} {
    list [catch {.c create text xyz 0} msg] $msg


} {1 {bad screen distance "xyz"}}
test canvText-2.3 {CreateText procedure: args} {
    list [catch {.c create text 0 xyz} msg] $msg


} {1 {bad screen distance "xyz"}}
test canvText-2.4 {CreateText procedure: args} {
    list [catch {.c create text 0 0 -xyz xyz} msg] $msg


} {1 {unknown option "-xyz"}}
test canvText-2.5 {CreateText procedure} {
    .c create text 0 0 -tags x
    set x [.c coords x]

    .c delete x
    set x
} {0.0 0.0}

focus -force .c

.c focus test
.c coords test 0 0
update

test canvText-3.1 {TextCoords procedure} {
    .c coords test


} {0.0 0.0}
test canvText-3.2 {TextCoords procedure} {


    list [catch {.c coords test xyz 0} msg] $msg


} {1 {bad screen distance "xyz"}}
test canvText-3.3 {TextCoords procedure} {


    list [catch {.c coords test 0 xyz} msg] $msg


} {1 {bad screen distance "xyz"}}
test canvText-3.4 {TextCoords procedure} {


    .c coords test 10 10
    set result {}
    foreach element [.c coords test] {
	lappend result [format %.1f $element]
    }
    set result


} {10.0 10.0}
test canvText-3.5 {TextCoords procedure} {


    list [catch {.c coords test 10} msg] $msg


} {1 {wrong # coordinates: expected 2, got 1}}
test canvText-3.6 {TextCoords procedure} {


    list [catch {.c coords test 10 10 10} msg] $msg


} {1 {wrong # coordinates: expected 0 or 2, got 3}}


test canvText-4.1 {ConfigureText procedure} {


    list [catch {.c itemconfig test -fill xyz} msg] $msg


} {1 {unknown color name "xyz"}}
test canvText-4.2 {ConfigureText procedure} {


    .c itemconfig test -fill blue
    .c itemcget test -fill


} {blue}
test canvText-4.3 {ConfigureText procedure: construct font gcs} {


    .c itemconfig test -font "times 20" -fill black -stipple gray50
    list [.c itemcget test -font] [.c itemcget test -fill] [.c itemcget test -stipple]


} {{times 20} black gray50}
test canvText-4.4 {ConfigureText procedure: construct cursor gc} {




    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c icursor test 3

    # Both black -> cursor becomes white.
    .c config -insertbackground black
    .c config -selectbackground black
    .c itemconfig test -just left
    update

    # Both same color (and not black) -> cursor becomes black.
    .c config -insertbackground red
    .c config -selectbackground red
    .c itemconfig test -just left
    update
} {}


test canvText-4.5 {ConfigureText procedure: adjust selection} {



    set x {}

    .c itemconfig test -text "abcdefghi"
    .c select from test 2
    .c select to test 6
    lappend x [selection get]
    .c dchars test 1 end
    lappend x [catch {selection get}]
    .c insert test end "bcdefghi"
    .c select from test 2
    .c select to test 6
    lappend x [selection get]
    .c dchars test 4 end
    lappend x [selection get]
    .c insert test end "efghi"
    .c select from test 6
    .c select to test 2
    lappend x [selection get]
    .c dchars test 4 end
    lappend x [selection get]


} {cdefg 1 cdefg cd cdef cd}
test canvText-4.6 {ConfigureText procedure: adjust cursor} {


    .c itemconfig test -text "abcdefghi"
    set x {}
    .c icursor test 6
    .c dchars test 4 end
    .c index test insert



} {4}

test canvText-5.1 {ConfigureText procedure: adjust cursor} {
    .c create text 10 10 -tag x -fill blue -font "times 40" -stipple gray50 -text "xyz"

    .c delete x

} {}

























































test canvText-6.1 {ComputeTextBbox procedure} {fonts nonPortable} {


    .c itemconfig test -font $font -text 0
    .c coords test 0 0
    set x {}
    lappend x [.c itemconfig test -anchor n; .c bbox test]
    lappend x [.c itemconfig test -anchor nw; .c bbox test]
    lappend x [.c itemconfig test -anchor w; .c bbox test]








    lappend x [.c itemconfig test -anchor sw; .c bbox test]
    lappend x [.c itemconfig test -anchor s; .c bbox test]
    lappend x [.c itemconfig test -anchor se; .c bbox test]










    lappend x [.c itemconfig test -anchor e; .c bbox test]
    lappend x [.c itemconfig test -anchor ne; .c bbox test]
    lappend x [.c itemconfig test -anchor center; .c bbox test]
} "{[expr -$ax/2-1] 0 [expr $ax/2+1] $ay}\
{-1 0 [expr $ax+1] $ay}\
{-1 [expr -$ay/2] [expr $ax+1] [expr $ay/2]}\
{-1 -$ay [expr $ax+1] 0}\
{[expr -$ax/2-1] -$ay [expr $ax/2+1] 0}\
{[expr -$ax-1] -$ay 1 0}\
{[expr -$ax-1] [expr -$ay/2] 1 [expr $ay/2]}\
{[expr -$ax-1] 0 1 $ay}\
{[expr -$ax/2-1] [expr -$ay/2] [expr $ax/2+1] [expr $ay/2]}"


































focus .c
.c focus test
.c itemconfig test -text "abcd\nefghi\njklmnopq"
test canvText-7.0 {DisplayText procedure: stippling} {

    .c itemconfig test -stipple gray50
    update
    .c itemconfig test -stipple {}
    update
} {}


test canvText-7.2 {DisplayText procedure: draw selection} {





    .c select from test 0
    .c select to test end
    update
    selection get


} "abcd\nefghi\njklmnopq"
test canvText-7.3 {DisplayText procedure: selection} {





    .c select from test 0
    .c select to test end
    update
    selection get


} "abcd\nefghi\njklmnopq"
test canvText-7.4 {DisplayText procedure: one line selection} {





    .c select from test 2
    .c select to test 3
    update







} {}
test canvText-7.5 {DisplayText procedure: multi-line selection} {
    .c select from test 2
    .c select to test 12
    update
} {}


test canvText-7.6 {DisplayText procedure: draw cursor} {





    .c icursor test 3
    update
} {}


test canvText-7.7 {DisplayText procedure: selected text different color} {





    .c config -selectforeground blue
    .c itemconfig test -anchor n
    update
} {}


test canvText-7.8 {DisplayText procedure: not selected} {





    .c select clear
    update
} {}


test canvText-7.9 {DisplayText procedure: select end} {
    catch {destroy .t}

    toplevel .t
    wm geometry .t +0+0
    canvas .t.c
    pack .t.c
    set id [.t.c create text 0 0 -text Dummy -anchor nw]
    update
    .t.c select from $id 0
    .t.c select to $id end
    update
    #catch {destroy .t}
    update
} {}



test canvText-8.1 {TextInsert procedure: 0 length insert} {





    .c insert test end {}
} {}


test canvText-8.2 {TextInsert procedure: before beginning/after end} {
    # Can't test this because GetTextIndex filters out those numbers.
} {}
test canvText-8.3 {TextInsert procedure: inserting in a selected item} {




    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 1 "xyz"
    .c itemcget test -text
} {axyzbcdefg}
test canvText-8.4 {TextInsert procedure: inserting before selection} {




    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 1 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} {5 7}
test canvText-8.5 {TextInsert procedure: inserting in selection} {




    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 3 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} {2 7}
test canvText-8.6 {TextInsert procedure: inserting after selection} {




    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c insert test 5 "xyz"
    list [.c index test sel.first] [.c index test sel.last]
} {2 4}
test canvText-8.7 {TextInsert procedure: inserting in unselected item} {




    .c itemconfig test -text "abcdefg"
    .c select clear
    .c insert test 5 "xyz"
    .c itemcget test -text
} {abcdexyzfg}
test canvText-8.8 {TextInsert procedure: inserting before cursor} {




    .c itemconfig test -text "abcdefg"
    .c icursor test 3
    .c insert test 2 "xyz"
    .c index test insert
} {6}
test canvText-8.9 {TextInsert procedure: inserting after cursor} {




    .c itemconfig test -text "abcdefg"
    .c icursor test 3
    .c insert test 4 "xyz"
    .c index test insert
} {3}



test canvText-9.1 {TextInsert procedure: before beginning/after end} {
    # Can't test this because GetTextIndex filters out those numbers.
} {}
test canvText-9.2 {TextInsert procedure: start > end} {
    .c itemconfig test -text "abcdefg"
    .c dchars test 4 2
    .c itemcget test -text
} {abcdefg}
test canvText-9.3 {TextInsert procedure: deleting from a selected item} {
    .c itemconfig test -text "abcdefg"
    .c select from test 2
    .c select to test 4
    .c dchars test 3 5
    .c itemcget test -text
} {abcg}
test canvText-9.4 {TextInsert procedure: deleting before start} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 1 1
    list [.c index test sel.first] [.c index test sel.last]
} {3 7}
test canvText-9.5 {TextInsert procedure: keep start > first char deleted} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 2 6
    list [.c index test sel.first] [.c index test sel.last]
} {2 3}
test canvText-9.6 {TextInsert procedure: deleting inside selection} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 6 6
    list [.c index test sel.first] [.c index test sel.last]
} {4 7}
test canvText-9.7 {TextInsert procedure: keep end > first char deleted} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 6 10
    list [.c index test sel.first] [.c index test sel.last]
} {4 5}
test canvText-9.8 {TextInsert procedure: selectFirst > selectLast: deselect} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 3 10
    list [catch {.c index test sel.first} msg] $msg
} {1 {selection isn't in item}}
test canvText-9.9 {TextInsert procedure: selectFirst <= selectLast} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 4
    .c select to test 8
    .c dchars test 4 7
    list [.c index test sel.first] [.c index test sel.last]
} {4 4}
test canvText-9.10 {TextInsert procedure: move anchor} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 6
    .c select to test 8
    .c dchars test 2 4
    .c select to test 1
    list [.c index test sel.first] [.c index test sel.last]
} {1 2}
test canvText-9.11 {TextInsert procedure: keep anchor >= first} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 6
    .c select to test 8
    .c dchars test 5 7
    .c select to test 1
    list [.c index test sel.first] [.c index test sel.last]
} {1 4}
test canvText-9.12 {TextInsert procedure: anchor doesn't move} {
    .c itemconfig test -text "abcdefghijk"
    .c select from test 2
    .c select to test 5
    .c dchars test 6 8
    .c select to test 8
    list [.c index test sel.first] [.c index test sel.last]
} {2 8}
test canvText-9.13 {TextInsert procedure: move cursor} {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 6
    .c dchars test 2 4
    .c index test insert
} {3}
test canvText-9.14 {TextInsert procedure: keep cursor >= first} {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 6
    .c dchars test 2 10
    .c index test insert
} {2}
test canvText-9.15 {TextInsert procedure: cursor doesn't move} {
    .c itemconfig test -text "abcdefghijk"
    .c icursor test 5
    .c dchars test 7 9
    .c index test insert


} {5}

test canvText-10.1 {TextToPoint procedure} {
    .c coords test 0 0
    .c itemconfig test -text 0 -anchor center
    .c index test @0,0



} {0}

test canvText-11.1 {TextToArea procedure} {


    .c coords test 0 0

    .c itemconfig test -text 0 -anchor center
    .c find overlapping 0 0 1 1
} [.c find withtag test]




test canvText-11.2 {TextToArea procedure} {


    .c coords test 0 0

    .c itemconfig test -text 0 -anchor center
    .c find overlapping 1000 1000 1001 1001



} {}

test canvText-12.1 {ScaleText procedure} {
    .c coords test 100 100
    .c scale all 50 50 2 2
    format {%.6g %.6g} {*}[.c coords test]


} {150 150}


test canvText-13.1 {TranslateText procedure} {
    .c coords test 100 100
    .c move all 10 10
    format {%.6g %.6g} {*}[.c coords test]


} {110 110}







.c itemconfig test -text "abcdefghijklmno" -anchor nw
.c select from test 5
.c select to test 8
.c icursor test 12
.c coords test 0 0
test canvText-14.1 {GetTextIndex procedure} {
    list [.c index test end] [.c index test insert] \
	[.c index test sel.first] [.c index test sel.last] \
	[.c index test @0,0] \
	[.c index test -1] [.c index test 10] [.c index test 100]


} {15 12 5 8 0 0 10 15}
test canvText-14.2 {GetTextIndex procedure: select error} {




    .c select clear
    list [catch {.c index test sel.first} msg] $msg


} {1 {selection isn't in item}}
test canvText-14.3 {GetTextIndex procedure: select error} {




    .c select clear
    list [catch {.c index test sel.last} msg] $msg


} {1 {selection isn't in item}}
test canvText-14.4 {GetTextIndex procedure: select error} {




    .c select clear
    list [catch {.c index test sel.} msg] $msg


} {1 {bad index "sel."}}
test canvText-14.5 {GetTextIndex procedure: bad int or unknown index} {


    list [catch {.c index test xyz} msg] $msg
} {1 {bad index "xyz"}}





test canvText-14.6 {select clear errors} -body {


    .c select clear test


} -returnCodes error -result "wrong \# args: should be \".c select clear\""




















test canvText-15.1 {SetTextCursor procedure} {





    .c itemconfig -text "abcdefg"
    .c icursor test 3
    .c index test insert
} {3}



test canvText-16.1 {GetSelText procedure} {




    .c itemconfig test -text "abcdefghijklmno" -anchor nw
    .c select from test 5
    .c select to test 8
    selection get


} {fghi}


















set font {Courier 12 italic}
set ax [font measure $font 0]
set ay [font metrics $font -linespace]

test canvText-17.1 {TextToPostscript procedure} {failsOnUbuntu failsOnQuarz} {
    .c delete all
    .c config -height 300 -highlightthickness 0 -bd 0
    update
    .c create text 100 100 -tags test
    .c itemconfig test -font $font -text "00000000" -width [expr 3*$ax]
    .c itemconfig test -anchor n -fill black
    set x [.c postscript]
    set x [string range $x [string first "findfont " $x] end]
} "findfont [font actual $font -size] scalefont ISOEncode setfont
0.000 0.000 0.000 setrgbcolor AdjustColor
100 200 \[
\[(000)\]
\[(000)\]
\[(00)\]
] $ay -0.5 0.0 0 false DrawText
grestore
restore showpage

%%Trailer
end
%%EOF
"

test canvText-18.1 {bug fix 2525, find enclosed on text with newlines} -body {
    catch {destroy .c}

    canvas .c
    pack .c
    .c delete all
    .c create text 100 100 -text Hello\n -anchor nw
    set bbox [.c bbox 1]
    set x2 [lindex $bbox 2]
    set y2 [lindex $bbox 3]
    incr y2
    update
    .c find enclosed 99 99 [expr $x2 + $i] [expr $y2 + 1]
} -cleanup {

    unset -nocomplain bbox x2 y2
} -result 1

test canvText-19.1 {patch 1006286, leading space caused wrap under Win32} {
    catch {destroy .c}
    set c [canvas .c -bg black -width 964]
    pack $c
    $c delete all
    after 1000 "set done 1" ; vwait done

    set f {Arial 28 bold}

    set s1 {    Yeah-ah-ah-ah-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-oh-Yow}
    set s2 {    Yeah ah ah ah oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh Yow}

    $c create text 21 18 \
        -font $f \
        -text $s1 \
        -fill white \
        -width 922 \
        -anchor nw \
        -tags tbox1
    eval {$c create rect} [$c bbox tbox1] -outline red

    $c create text 21 160 \
        -font $f \
        -text $s2 \
        -fill white \
        -width 922 \
        -anchor nw \
        -tags tbox2
    eval {$c create rect} [$c bbox tbox2] -outline red

    after 1000 "set done 1" ; vwait done

    set results [list]

    $c select from tbox2 4
    $c select to tbox2 8
    lappend results [selection get]

    $c select from tbox1 4
    $c select to tbox1 8
    lappend results [selection get]

    array set metrics [font metrics $f]
    set x [expr {21 + [font measure $f "    "] \
        + ([font measure {Arial 28 bold} "Y"] / 2)}]
    set y1 [expr {18 + ($metrics(-linespace) / 2)}]
    set y2 [expr {160 + ($metrics(-linespace) / 2)}]

    lappend results [$c index tbox1 @$x,$y1]
    lappend results [$c index tbox2 @$x,$y2]


























    set results
} {{Yeah } Yeah- 4 4}















# cleanup
cleanupTests
return

Changes to tests/canvWind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# This file is a Tcl script to test out the procedures in tkCanvWind.c,
# which implement canvas "window" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test canvWind-1.1 {DisplayWinItem, windows off-screen vertically} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.f




|
|



<



|
|
<







1
2
3
4
5
6
7
8
9

10
11
12
13
14

15
16
17
18
19
20
21
# This file is a Tcl script to test out the procedures in tkCanvWind.c,
# which implement canvas "window" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test canvWind-1.1 {DisplayWinItem, windows off-screen vertically} {
    catch {destroy .t}

    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.f
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -255 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
} -cleanup {
    destroy .t
} -result {{1 23} {1 -29} {0 -29} {1 225} {0 225}}

test canvWind-1.2 {DisplayWinItem, windows off-screen vertically} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.c.f







<
<
|
<
|
|
<







33
34
35
36
37
38
39


40

41
42

43
44
45
46
47
48
49
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -255 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]


} {{1 23} {1 -29} {0 -29} {1 225} {0 225}}

test canvWind-1.2 {DisplayWinItem, windows off-screen vertically} {
    catch {destroy .t}

    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.c.f
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -255 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
} -cleanup {
    destroy .t
} -result {{1 3} {1 -49} {0 -49} {1 205} {0 205}}

test canvWind-1.3 {DisplayWinItem, windows off-screen horizontally} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.f







<
<
|
<
|
|
<







61
62
63
64
65
66
67


68

69
70

71
72
73
74
75
76
77
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -255 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]
    .t.c yview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo y $f]]


} {{1 3} {1 -49} {0 -49} {1 205} {0 205}}

test canvWind-1.3 {DisplayWinItem, windows off-screen horizontally} {
    catch {destroy .t}

    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.f
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -335 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
} -cleanup {
    destroy .t
} -result {{1 23} {1 -59} {0 -59} {1 275} {0 275}}

test canvWind-1.4 {DisplayWinItem, windows off-screen horizontally} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.c.f







<
<
|
<
|
|
<







89
90
91
92
93
94
95


96

97
98

99
100
101
102
103
104
105
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -335 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]


} {{1 23} {1 -59} {0 -59} {1 275} {0 275}}

test canvWind-1.4 {DisplayWinItem, windows off-screen horizontally} {
    catch {destroy .t}

    toplevel .t
    canvas .t.c -scrollregion {0 0 1000 800} -width 250 -height 200 -bd 2 \
	    -relief sunken -xscrollincrement 1 -yscrollincrement 1 \
	    -highlightthickness 1
    pack .t.c -fill both -expand 1 -padx 20 -pady 20
    wm geometry .t +0+0
    set f .t.c.f
131
132
133
134
135
136
137
138
139
140

141
142
143
144
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -335 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
} -cleanup {
    destroy .t
} -result {{1 3} {1 -79} {0 -79} {1 255} {0 255}}


# cleanup
cleanupTests
return







<
<
|
>




117
118
119
120
121
122
123


124
125
126
127
128
129
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -335 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]


} {{1 3} {1 -79} {0 -79} {1 255} {0 255}}
catch {destroy .t}

# cleanup
cleanupTests
return

Changes to tests/canvas.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102



103

104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184


185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332

333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389
390

391
392

393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# This file is a Tcl script to test out the procedures in tkCanvas.c, which
# implements generic code for canvases. It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# XXX - This test file is woefully incomplete. At present, only a few of the
# features are tested.

# Canvas used in 1.* test cases
canvas .c
pack .c
update

test canvas-1.1 {configuration options: good value for "background"} -body {
    .c configure -background #ff0000
    .c cget -background
} -result {#ff0000}
test canvas-1.2 {configuration options: bad value for "background"} -body {
    .c configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test canvas-1.3 {configuration options: good value for "bg"} -body {
    .c configure -bg #ff0000
    .c cget -bg
} -result {#ff0000}
test canvas-1.4 {configuration options: bad value for "bg"} -body {
    .c configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test canvas-1.5 {configuration options: good value for "bd"} -body {
    .c configure -bd 4
    .c cget -bd
} -result 4
test canvas-1.6 {configuration options: bad value for "bd"} -body {
    .c configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.7 {configuration options: good value for "borderwidth"} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -result 1
test canvas-1.8 {configuration options: bad value for "borderwidth"} -body {
    .c configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.9 {configuration options: good value for "closeenough"} -body {
    .c configure -closeenough 24
    .c cget -closeenough
} -result {24.0}
test canvas-1.10 {configuration options: bad value for "closeenough"} -body {
    .c configure -closeenough bogus
} -returnCodes error -result {expected floating-point number but got "bogus"}
test canvas-1.11 {configuration options: good value for "confine"} -body {
    .c configure -confine true
    .c cget -confine
} -result 1
test canvas-1.12 {configuration options: bad value for "confine"} -body {
    .c configure -confine silly
} -returnCodes error -result {expected boolean value but got "silly"}
test canvas-1.13 {configuration options: good value for "cursor"} -body {
    .c configure -cursor arrow
    .c cget -cursor
} -result {arrow}
test canvas-1.14 {configuration options: bad value for "cursor"} -body {
    .c configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test canvas-1.15 {configuration options: good value for "height"} -body {
    .c configure -height 2.1
    .c cget -height
} -result 2
test canvas-1.16 {configuration options: bad value for "height"} -body {
    .c configure -height x42
} -returnCodes error -result {bad screen distance "x42"}
test canvas-1.17 {configuration options: good value for "highlightbackground"} -body {
    .c configure -highlightbackground #112233
    .c cget -highlightbackground
} -result {#112233}
test canvas-1.18 {configuration options: bad value for "highlightbackground"} -body {
    .c configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test canvas-1.19 {configuration options: good value for "highlightcolor"} -body {
    .c configure -highlightcolor #110022
    .c cget -highlightcolor
} -result {#110022}
test canvas-1.20 {configuration options: bad value for "highlightcolor"} -body {
    .c configure -highlightcolor bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.21 {configuration options: good value for "highlightthickness"} -body {
    .c configure -highlightthickness 18
    .c cget -highlightthickness
} -result 18
test canvas-1.22 {configuration options: bad value for "highlightthickness"} -body {
    .c configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.23 {configuration options: good value for "insertbackground"} -body {
    .c configure -insertbackground #110022

    .c cget -insertbackground



} -result {#110022}

test canvas-1.24 {configuration options: bad value for "insertbackground"} -body {
    .c configure -insertbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.25 {configuration options: good value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 1.3
    .c cget -insertborderwidth
} -result 1
test canvas-1.26 {configuration options: bad value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 2.6x
} -returnCodes error -result {bad screen distance "2.6x"}
test canvas-1.27 {configuration options: good value for "insertofftime"} -body {
    .c configure -insertofftime 100
    .c cget -insertofftime
} -result 100

test canvas-1.28 {configuration options: bad value for "insertofftime"} -body {
    .c configure -insertofftime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.29 {configuration options: good value for "insertontime"} -body {
    .c configure -insertontime 100
    .c cget -insertontime
} -result 100
test canvas-1.30 {configuration options: bad value for "insertontime"} -body {
    .c configure -insertontime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.31 {configuration options: good value for "insertwidth"} -body {
    .c configure -insertwidth 1.3
    .c cget -insertwidth
} -result 1
test canvas-1.32 {configuration options: bad value for "insertwidth"} -body {
    .c configure -insertwidth 6x
} -returnCodes error -result {bad screen distance "6x"}

test canvas-1.33 {configuration options: good value for "relief"} -body {
    .c configure -relief groove
    .c cget -relief
} -result {groove}
test canvas-1.34 {configuration options: bad value for "relief"} -body {
    .c configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test canvas-1.35 {configuration options: good value for "selectbackground"} -body {
    .c configure -selectbackground #110022
    .c cget -selectbackground
} -result {#110022}
test canvas-1.36 {configuration options: bad value for "selectbackground"} -body {
    .c configure -selectbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.37 {configuration options: good value for "selectborderwidth"} -body {
    .c configure -selectborderwidth 1.3
    .c cget -selectborderwidth
} -result 1
test canvas-1.38 {configuration options: bad value for "selectborderwidth"} -body {
    .c configure -selectborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.39 {configuration options: good value for "selectforeground"} -body {
    .c configure -selectforeground #654321
    .c cget -selectforeground
} -result {#654321}
test canvas-1.40 {configuration options: bad value for "selectforeground"} -body {
    .c configure -selectforeground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.41 {configuration options: good value for "takefocus"} -body {
    .c configure -takefocus "any string"
    .c cget -takefocus
} -result {any string}
test canvas-1.42 {configuration options: good value for "width"} -body {
    .c configure -width 402
    .c cget -width
} -result 402
test canvas-1.43 {configuration options: bad value for "width"} -body {
    .c configure -width xyz
} -returnCodes error -result {bad screen distance "xyz"}
test canvas-1.44 {configuration options: good value for "xscrollcommand"} -body {
    .c configure -xscrollcommand {Some command}
    .c cget -xscrollcommand
} -result {Some command}
test canvas-1.45 {configuration options: good value for "yscrollcommand"} -body {
    .c configure -yscrollcommand {Another command}
    .c cget -yscrollcommand
} -result {Another command}
test canvas-1.46 {configure throws error on bad option} -body {

    .c configure -gorp foo
} -returnCodes error -match glob -result {*}


test canvas-1.47 {configure throws error on bad option} -body {
    catch {.c configure -gorp foo}
    .c create rect 10 10 100 100
    .c configure -gorp foo
} -returnCodes error -match glob -result {*}
catch {destroy .c}

# Canvas used in 2.* test cases
canvas .c -width 60 -height 40 -scrollregion {0 0 200 150} -bd 0 \
	-highlightthickness 0
pack .c
update

test canvas-2.1 {CanvasWidgetCmd, bind option} -body {
    set i [.c create rect 10 10 100 100]
    .c bind $i <a>
} -cleanup {
    .c delete $i
} -returnCodes ok
test canvas-2.2 {CanvasWidgetCmd, bind option} -body {
    set i [.c create rect 10 10 100 100]
    .c bind $i <
} -cleanup {
    .c delete $i
} -returnCodes error -result {no event type or button # or keysym}
test canvas-2.3 {CanvasWidgetCmd, xview option} -body {
    .c configure -xscrollincrement 40 -yscrollincrement 5
    .c xview moveto 0
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} -result {{0.0 0.3} {0.4 0.7}}
test canvas-2.4 {CanvasWidgetCmd, xview option} -constraints nonPortable -body {
    # This test gives slightly different results on platforms such as NetBSD.
    # I don't know why...
    .c configure -xscrollincrement 0 -yscrollincrement 5
    .c xview moveto 0.6
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} -result {{0.6 0.9} {0.66 0.96}}
test canvas-2.5 {CanvasWidgetCmd, raise/lower option, no error on non-existing tags} -setup {
    .c create line 0 0 10 10 -tags aline
} -body {
    .c raise aline noline
    .c raise bline aline
    .c lower aline noline
    .c lower bline aline
} -cleanup {
    .c delete aline
} -result {}
catch {destroy .c}

# Canvas used in 3.* test cases
canvas .c -width 60 -height 40 -scrollregion {0 0 200 80} \
	-borderwidth 0 -highlightthickness 0
pack .c
update

test canvas-3.1 {CanvasWidgetCmd, yview option} -body {
    .c configure -xscrollincrement 40 -yscrollincrement 5
    .c yview moveto 0
    update
    set x [list [.c yview]]
    .c yview scroll 3 units
    update
    lappend x [.c yview]
} -result {{0.0 0.5} {0.1875 0.6875}}
test canvas-3.2 {CanvasWidgetCmd, yview option} -body {
    .c configure -xscrollincrement 40 -yscrollincrement 0
    .c yview moveto 0
    update
    set x [list [.c yview]]
    .c yview scroll 2 units
    update
    lappend x [.c yview]
} -result {{0.0 0.5} {0.1 0.6}}
destroy .c

test canvas-4.1 {ButtonEventProc procedure} -setup {
    deleteWindows
    set x {}
} -body {
    canvas .c1 -bg #543210
    rename .c1 .c2

    lappend x [winfo children .]
    lappend x [.c2 cget -bg]
    destroy .c1
    lappend x [info command .c*] [winfo children .]
} -result {.c1 #543210 {} {}}

test canvas-5.1 {ButtonCmdDeletedProc procedure} -body {

    canvas .c1
    rename .c1 {}
    list [info command .c*] [winfo children .]
} -cleanup {
    destroy .c1
} -result {{} {}}

# Canvas used in 6.* test cases
canvas .c -width 100 -height 50 -scrollregion {-200 -100 305 102} \
	-borderwidth 2 -highlightthickness 3
pack .c
update

test canvas-6.1 {CanvasSetOrigin procedure} -body {
    .c configure -xscrollincrement 0 -yscrollincrement 0
    .c xview moveto 0
    .c yview moveto 0
    update
    list [.c canvasx 0] [.c canvasy 0]
} -result {-205.0 -105.0}
test canvas-6.2 {CanvasSetOrigin procedure} -body {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    set x ""
    foreach i {.08 .10 .48 .50} {
	.c xview moveto $i
	update
	lappend x [.c canvasx 0]
    }
    return $x
} -result {-165.0 -145.0 35.0 55.0}
test canvas-6.3 {CanvasSetOrigin procedure} -body {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    set x ""
    foreach i {.06 .08 .70 .72} {
	.c yview moveto $i
	update
	lappend x [.c canvasy 0]
    }
    return $x
} -result {-95.0 -85.0 35.0 45.0}
test canvas-6.4 {CanvasSetOrigin procedure} -body {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    .c xview moveto 1.0
    .c canvasx 0
} -result {215.0}
test canvas-6.5 {CanvasSetOrigin procedure} -body {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    .c yview moveto 1.0
    .c canvasy 0
} -result {55.0}

deleteWindows


test canvas-7.1 {canvas widget vs hidden commands} -setup {
    canvas .c
} -body {

    interp hide {} .c
    destroy .c
    list [winfo children .] [lsort [interp hidden]]
} -cleanup {
    destroy .c
} -result [list {} [lsort [interp hidden]]]

test canvas-8.1 {canvas arc bbox} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    .c create arc -100 10 100 210 -start 10 -extent 50 -style arc -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 100 10 300 210 -start 10 -extent 50 -style chord -tags arc2
    set coordBox [.c bbox arc2]
    .c create arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3
    set pieBox [.c bbox arc3]
    .c create arc 100 200 300 200 -height [expr {(1-0.5*sqrt(3))*200}] -style arc -tags arc4
    set arcSegBox [.c bbox arc4]
    list $arcBox $coordBox $pieBox $arcSegBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112} {98 171 302 202}}
test canvas-8.2 {canvas very small arc} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # no Inf or NaN must be generated even for very small arcs
    .c create arc 0 100 0 100 -height 100 -style arc -outline "" -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 0 100 0 100 -height 100 -style arc -outline blue -tags arc2
    set outlinedArcBox [.c bbox arc2]
    set coords [.c coords arc1]
    set start [.c itemcget arc1 -start]
    set extent [.c itemcget arc1 -extent]
    set width [.c itemcget arc1 -width]
    set height [.c itemcget arc1 -height]
    list $arcBox $outlinedArcBox $coords $start $extent $width $height
} -result {{-1 99 1 101} {-2 98 2 102} {0.0 100.0 0.0 100.0} 0.0 0.0 1.0 0.0}

test canvas-9.1 {canvas id creation and deletion} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # With Tk 8.0.4 the ids are now stored in a hash table. You can use this
    # test as a performance test with older versions by changing the value of
    # size.
    set size 15

    for {set i 0} {$i < $size} {incr i} {
	set x [expr {-10 + 3*$i}]
	for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} {
	    .c create rect ${x}c ${y}c [expr {$x+2}]c [expr {$y+2}]c \
		    -outline black -fill blue -tags rect
	    .c create text [expr {$x+1}]c [expr {$y+1}]c -text "$i,$j" \
		    -anchor center -tags text
	}
    }

    # The actual bench mark - this code also exercises all the hash table
    # changes.

    set time [lindex [time {
	foreach id [.c find withtag all] {
	    .c lower $id
	    .c raise $id
	    .c find withtag $id
	    .c bind <Return> $id {}
	    .c delete $id
	}
    }] 0]

    set x ""
} -result {}

test canvas-10.1 {find items using tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    set res {}
} -body {
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 60 40 80 -fill yellow -tag [list b a]
    .c create oval 20 100 40 120 -fill green -tag [list c b]
    .c create oval 20 140 40 160 -fill blue -tag [list b]
    .c create oval 20 180 40 200 -fill bisque -tag [list a d e]
    .c create oval 20 220 40 240 -fill bisque -tag b
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]

    lappend res [.c find withtag {!a}]
    lappend res [.c find withtag {b&&c}]
    lappend res [.c find withtag {b||c}]
    lappend res [.c find withtag {a&&!b}]
    lappend res [.c find withtag {!b&&!c}]
    lappend res [.c find withtag {d&&a&&c&&b}]
    lappend res [.c find withtag {b^a}]
    lappend res [.c find withtag {(a&&!b)||(!a&&b)}]
    lappend res [.c find withtag { ( a && ! b ) || ( ! a && b ) }]
    lappend res [.c find withtag {a&&!(c||d)}]
    lappend res [.c find withtag {d&&"tag with spaces"}]
    lappend res [.c find withtag "tag with spaces"]
} -result {{3 4 6 7} {1 3} {1 2 3 4 6} 5 {5 7} 1 {3 4 5 6} {3 4 5 6} {3 4 5 6} 2 7 7}
test canvas-10.2 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {&&c}
} -returnCodes error -result {unexpected operator in tag search expression}
test canvas-10.3 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {!!c}
} -returnCodes error -result {too many '!' in tag search expression}
test canvas-10.4 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {b||}
} -returnCodes error -result {missing tag in tag search expression}
test canvas-10.5 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {b&&(c||)}
} -returnCodes error -result {unexpected operator in tag search expression}
test canvas-10.6 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {d&&""}
} -returnCodes error -result {null quoted tag string in tag search expression}
test canvas-10.7 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag "d&&\"tag with spaces"
} -returnCodes error -result {missing endquote in tag search expression}
test canvas-10.8 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -returnCodes error -body {
    .c find withtag {a&&"tag with spaces"z}
} -result {invalid boolean operator in tag search expression}
test canvas-10.9 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {a&&b&c}
} -returnCodes error -result {singleton '&' in tag search expression}
test canvas-10.10 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {a||b|c}
} -returnCodes error -result {singleton '|' in tag search expression}
test canvas-10.11 {backward compatility - strange tags that are not expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red \
	-tag [list { strange tag(xxx&yyy|zzz) " && \" || ! ^ " }]
} -body {
    .c find withtag { strange tag(xxx&yyy|zzz) " && \" || ! ^ " }
} -result 1
test canvas-10.12 {multple events bound to same tag expr} -setup {
    catch {destroy .c}
    canvas .c
} -body {
|
|
|

|
|
<





<

|
|

<



|
|
|
<
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
|
<
<
<
<
|
<
<
|
<
<
<
|
<
|
>
|
>
>
>
|
>
<
|
|
<
|
<
<
<
<
|
|
<
<
<
>
|
<
<
|
<
<
<
|
<
<
|
<
<
|
<
<
<
>
|
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
>
|
<
>
>
|
|

|
|
|

|





|

|
|
<
<
|

|
<
<
|
|







|
|
|
|







|
|
<
<
<
<
<
<
<
<
<

<
<




<
|







|
|







|
<

|

<
<


>




|

|
>



<
<
|

|




<
|





|
|







|
|
|







|
|
|



|
|



|
>


>

|

>



<
<
|











<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
|
|

>



|

|



>
|
|
>









>


<



<








>




















|







|







|







|







|







|





|

|







|







|



|
<







1
2
3
4
5
6

7
8
9
10
11

12
13
14
15

16
17
18
19
20
21




22

23




24






25

26






27




28






29






30






31

32




33

34




35


36



37

38
39
40
41
42
43
44
45

46
47

48




49
50



51
52


53



54


55


56



57
58




59


60

61






62

63
















64
65
66









67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112









113


114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138


139
140
141
142
143
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215
216
217
218
219


220
221
















222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
# This file is a Tcl script to test out the procedures in tkCanvas.c,
# which implements generic code for canvases.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.

# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


# XXX - This test file is woefully incomplete.  At present, only a
# few of the features are tested.


canvas .c
pack .c
update
set i 1
foreach {testname testinfo} {
    canvas-1.1 {-background #ff0000 #ff0000




	non-existent {unknown color name "non-existent"}}

    canvas-1.2 {-bg #ff0000 #ff0000




	non-existent {unknown color name "non-existent"}}






    canvas-1.3 {-bd 4 4 badValue {bad screen distance "badValue"}}

    canvas-1.4 {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}






    canvas-1.5 {-closeenough 24 24.0




	bogus {expected floating-point number but got "bogus"}}






    canvas-1.6 {-confine true 1 silly {expected boolean value but got "silly"}}






    canvas-1.7 {-cursor arrow arrow badValue {bad cursor spec "badValue"}}






    canvas-1.8 {-height 2.1 2 x42 {bad screen distance "x42"}}

    canvas-1.9 {-highlightbackground #112233 #112233




	ugly {unknown color name "ugly"}}

    canvas-1.10 {-highlightcolor #110022 #110022




	bogus {unknown color name "bogus"}}


    canvas-1.11 {-highlightthickness 18 18



	badValue {bad screen distance "badValue"}}

    canvas-1.12 {-insertbackground #110022 #110022
	bogus {unknown color name "bogus"}}
    canvas-1.13 {-insertborderwidth 1.3 1 2.6x {bad screen distance "2.6x"}}
    canvas-1.14 {-insertofftime 100 100 3.2 {expected integer but got "3.2"}}
    canvas-1.15 {-insertontime 100 100 3.2 {expected integer but got "3.2"}}
    canvas-1.16 {-insertwidth 1.3 1 6x {bad screen distance "6x"}}
    canvas-1.17 {-relief groove groove
	1.5 {bad relief type "1.5": must be flat, groove, raised, ridge, solid, or sunken}}

    canvas-1.18 {-selectbackground #110022 #110022
	bogus {unknown color name "bogus"}}

    canvas-1.19 {-selectborderwidth 1.3 1




	badValue {bad screen distance "badValue"}}
    canvas-1.20 {-selectforeground #654321 #654321



	bogus {unknown color name "bogus"}}
    canvas-1.21 {-takefocus "any string" "any string" {} {}}


    canvas-1.22 {-width 402 402 xyz {bad screen distance "xyz"}}



    canvas-1.23 {-xscrollcommand {Some command} {Some command} {} {}}


    canvas-1.24 {-yscrollcommand {Another command} {Another command} {} {}}


} {



    lassign $testinfo name goodValue goodResult badValue badResult
    test $testname-good "configuration options: good value for $name" {




	.c configure $name $goodValue


	lindex [.c configure $name] 4

    } $goodResult






    incr i

    if {$badValue ne ""} {
















	test $testname-bad "configuration options: bad value for $name" -body {
	    .c configure $name $badValue
	} -returnCodes error -result $badResult









    }
    .c configure $name [lindex [.c configure $name] 3]

    incr i
}
test canvas-1.25 {configure throws error on bad option} {
    set res [list [catch {.c configure -gorp foo}]]
    .c create rect 10 10 100 100
    lappend res [catch {.c configure -gorp foo}]
    set res
} [list 1 1]

catch {destroy .c}
canvas .c -width 60 -height 40 -scrollregion {0 0 200 150} -bd 0 \
	-highlightthickness 0
pack .c
update

test canvas-2.1 {CanvasWidgetCmd, bind option} {
    set i [.c create rect 10 10 100 100]
    list [catch {.c bind $i <a>} msg] $msg
} {0 {}}


test canvas-2.2 {CanvasWidgetCmd, bind option} {
    set i [.c create rect 10 10 100 100]
    list [catch {.c bind $i <} msg] $msg


} {1 {no event type or button # or keysym}}
test canvas-2.3 {CanvasWidgetCmd, xview option} {
    .c configure -xscrollincrement 40 -yscrollincrement 5
    .c xview moveto 0
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} {{0.0 0.3} {0.4 0.7}}
test canvas-2.4 {CanvasWidgetCmd, xview option} {nonPortable} {
    # This test gives slightly different results on platforms such
    # as NetBSD.  I don't know why...
    .c configure -xscrollincrement 0 -yscrollincrement 5
    .c xview moveto 0.6
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} {{0.6 0.9} {0.66 0.96}}










catch {destroy .c}


canvas .c -width 60 -height 40 -scrollregion {0 0 200 80} \
	-borderwidth 0 -highlightthickness 0
pack .c
update

test canvas-3.1 {CanvasWidgetCmd, yview option} {
    .c configure -xscrollincrement 40 -yscrollincrement 5
    .c yview moveto 0
    update
    set x [list [.c yview]]
    .c yview scroll 3 units
    update
    lappend x [.c yview]
} {{0.0 0.5} {0.1875 0.6875}}
test canvas-3.2 {CanvasWidgetCmd, yview option} {
    .c configure -xscrollincrement 40 -yscrollincrement 0
    .c yview moveto 0
    update
    set x [list [.c yview]]
    .c yview scroll 2 units
    update
    lappend x [.c yview]
} {{0.0 0.5} {0.1 0.6}}


test canvas-4.1 {ButtonEventProc procedure} {
    deleteWindows


    canvas .c1 -bg #543210
    rename .c1 .c2
    set x {}
    lappend x [winfo children .]
    lappend x [.c2 cget -bg]
    destroy .c1
    lappend x [info command .c*] [winfo children .]
} {.c1 #543210 {} {}}

test canvas-5.1 {ButtonCmdDeletedProc procedure} {
    deleteWindows
    canvas .c1
    rename .c1 {}
    list [info command .c*] [winfo children .]


} {{} {}}

catch {destroy .c}
canvas .c -width 100 -height 50 -scrollregion {-200 -100 305 102} \
	-borderwidth 2 -highlightthickness 3
pack .c
update

test canvas-6.1 {CanvasSetOrigin procedure} {
    .c configure -xscrollincrement 0 -yscrollincrement 0
    .c xview moveto 0
    .c yview moveto 0
    update
    list [.c canvasx 0] [.c canvasy 0]
} {-205.0 -105.0}
test canvas-6.2 {CanvasSetOrigin procedure} {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    set x ""
    foreach i {.08 .10 .48 .50} {
	.c xview moveto $i
	update
	lappend x [.c canvasx 0]
    }
    set x
} {-165.0 -145.0 35.0 55.0}
test canvas-6.3 {CanvasSetOrigin procedure} {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    set x ""
    foreach i {.06 .08 .70 .72} {
	.c yview moveto $i
	update
	lappend x [.c canvasy 0]
    }
    set x
} {-95.0 -85.0 35.0 45.0}
test canvas-6.4 {CanvasSetOrigin procedure} {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    .c xview moveto 1.0
    .c canvasx 0
} {215.0}
test canvas-6.5 {CanvasSetOrigin procedure} {
    .c configure -xscrollincrement 20 -yscrollincrement 10
    .c yview moveto 1.0
    .c canvasy 0
} {55.0}

deleteWindows

set l [lsort [interp hidden]]
test canvas-7.1 {canvas widget vs hidden commands} -setup {
    catch {destroy .c}
} -body {
    canvas .c
    interp hide {} .c
    destroy .c
    list [winfo children .] [lsort [interp hidden]]


} -result [list {} $l]

test canvas-8.1 {canvas arc bbox} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    .c create arc -100 10 100 210 -start 10 -extent 50 -style arc -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 100 10 300 210 -start 10 -extent 50 -style chord -tags arc2
    set coordBox [.c bbox arc2]
    .c create arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3
    set pieBox [.c bbox arc3]


    list $arcBox $coordBox $pieBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112}}

















test canvas-9.1 {canvas id creation and deletion} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # With Tk 8.0.4 the ids are now stored in a hash table.  You
    # can use this test as a performance test with older versions
    # by changing the value of size.
    set size 15

    for {set i 0} {$i < $size} {incr i} {
	set x [expr {-10 + 3*$i}]
	for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} {
	    .c create rect ${x}c ${y}c [expr $x+2]c [expr $y+2]c \
		    -outline black -fill blue -tags rect
	    .c create text [expr $x+1]c [expr $y+1]c -text "$i,$j" \
		    -anchor center -tags text
	}
    }

    # The actual bench mark - this code also exercises all the hash
    # table changes.

    set time [lindex [time {
	foreach id [.c find withtag all] {
	    .c lower $id
	    .c raise $id
	    .c find withtag $id
	    .c bind <Return> $id {}
	    .c delete $id
	}
    }] 0]

    set x ""
} -result {}

test canvas-10.1 {find items using tag expressions} -setup {
    catch {destroy .c}
    canvas .c

} -body {
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 60 40 80 -fill yellow -tag [list b a]
    .c create oval 20 100 40 120 -fill green -tag [list c b]
    .c create oval 20 140 40 160 -fill blue -tag [list b]
    .c create oval 20 180 40 200 -fill bisque -tag [list a d e]
    .c create oval 20 220 40 240 -fill bisque -tag b
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
    set res {}
    lappend res [.c find withtag {!a}]
    lappend res [.c find withtag {b&&c}]
    lappend res [.c find withtag {b||c}]
    lappend res [.c find withtag {a&&!b}]
    lappend res [.c find withtag {!b&&!c}]
    lappend res [.c find withtag {d&&a&&c&&b}]
    lappend res [.c find withtag {b^a}]
    lappend res [.c find withtag {(a&&!b)||(!a&&b)}]
    lappend res [.c find withtag { ( a && ! b ) || ( ! a && b ) }]
    lappend res [.c find withtag {a&&!(c||d)}]
    lappend res [.c find withtag {d&&"tag with spaces"}]
    lappend res [.c find withtag "tag with spaces"]
} -result {{3 4 6 7} {1 3} {1 2 3 4 6} 5 {5 7} 1 {3 4 5 6} {3 4 5 6} {3 4 5 6} 2 7 7}
test canvas-10.2 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {&&c}
} -returnCodes error -result {Unexpected operator in tag search expression}
test canvas-10.3 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {!!c}
} -returnCodes error -result {Too many '!' in tag search expression}
test canvas-10.4 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {b||}
} -returnCodes error -result {Missing tag in tag search expression}
test canvas-10.5 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {b&&(c||)}
} -returnCodes error -result {Unexpected operator in tag search expression}
test canvas-10.6 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {d&&""}
} -returnCodes error -result {Null quoted tag string in tag search expression}
test canvas-10.7 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag "d&&\"tag with spaces"
} -returnCodes error -result {Missing endquote in tag search expression}
test canvas-10.8 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {a&&"tag with spaces"z}
} -returnCodes error -result {Invalid boolean operator in tag search expression}
test canvas-10.9 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {a&&b&c}
} -returnCodes error -result {Singleton '&' in tag search expression}
test canvas-10.10 {check errors from tag expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list a b c d]
    .c create oval 20 260 40 280 -fill bisque -tag [list d "tag with spaces"]
} -body {
    .c find withtag {a||b|c}
} -returnCodes error -result {Singleton '|' in tag search expression}
test canvas-10.11 {backward compatility - strange tags that are not expressions} -setup {
    catch {destroy .c}
    canvas .c
    .c create oval 20 20 40 40 -fill red -tag [list { strange tag(xxx&yyy|zzz) " && \" || ! ^ " }]

} -body {
    .c find withtag { strange tag(xxx&yyy|zzz) " && \" || ! ^ " }
} -result 1
test canvas-10.12 {multple events bound to same tag expr} -setup {
    catch {destroy .c}
    canvas .c
} -body {
531
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
    # This would crash in 8.3.0 and 8.3.1
    .c create polygon 0 0 100 100 200 50 \
	    -fill {} -stipple gray50 -outline black
} -result 1
test canvas-11.2 {canvas poly overlap fill check, bug 226357} -setup {
    destroy .c
    pack [canvas .c]
    set result {}
} -body {

    .c create poly 30 30 90 90 30 90 90 30
    lappend result [.c find over 40 40 45 45];	# rect region inc. edge
    lappend result [.c find over 60 40 60 40];	# top-center point
    lappend result [.c find over 0 0 0 0];	# not on poly
    lappend result [.c find over 60 60 60 60];	# center-point
    lappend result [.c find over 45 50 45 50];	# outside poly
    .c itemconfig 1 -fill "" -outline black
    lappend result [.c find over 40 40 45 45];	# rect region inc. edge
    lappend result [.c find over 60 40 60 40];	# top-center point
    lappend result [.c find over 0 0 0 0];	# not on poly
    lappend result [.c find over 60 60 60 60];	# center-point
    lappend result [.c find over 45 50 45 50];	# outside poly
    .c itemconfig 1 -width 8
    lappend result [.c find over 45 50 45 50];	# outside poly
} -result {1 1 {} 1 {} 1 1 {} 1 {} 1}
test canvas-11.3 {canvas poly dchars, bug 3291543} {
    # This would crash
    destroy .c
    pack [canvas .c]
    .c create polygon 0 0 0 10 10 0
    .c dchars 1 2 end







<

>

|
|
|
|
|

|
|
|
|
|

|







382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    # This would crash in 8.3.0 and 8.3.1
    .c create polygon 0 0 100 100 200 50 \
	    -fill {} -stipple gray50 -outline black
} -result 1
test canvas-11.2 {canvas poly overlap fill check, bug 226357} -setup {
    destroy .c
    pack [canvas .c]

} -body {
    set result {}
    .c create poly 30 30 90 90 30 90 90 30
    lappend result [.c find over 40 40 45 45]; # rect region inc. edge
    lappend result [.c find over 60 40 60 40]; # top-center point
    lappend result [.c find over 0 0 0 0]; # not on poly
    lappend result [.c find over 60 60 60 60]; # center-point
    lappend result [.c find over 45 50 45 50]; # outside poly
    .c itemconfig 1 -fill "" -outline black
    lappend result [.c find over 40 40 45 45]; # rect region inc. edge
    lappend result [.c find over 60 40 60 40]; # top-center point
    lappend result [.c find over 0 0 0 0]; # not on poly
    lappend result [.c find over 60 60 60 60]; # center-point
    lappend result [.c find over 45 50 45 50]; # outside poly
    .c itemconfig 1 -width 8
    lappend result [.c find over 45 50 45 50]; # outside poly
} -result {1 1 {} 1 {} 1 1 {} 1 {} 1}
test canvas-11.3 {canvas poly dchars, bug 3291543} {
    # This would crash
    destroy .c
    pack [canvas .c]
    .c create polygon 0 0 0 10 10 0
    .c dchars 1 2 end
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597



598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763

764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
    incr val
    # qx has type double and no string representation
    .c scale all $val 0 1 1
    # qx has now type MMRep and no string representation
    incr val
} -result 12

# procedure used in 13.1 test case
proc kill_canvas {w} {
    destroy $w
    pack [canvas $w -height 200 -width 200] -fill both -expand yes
    update idle
    $w create rectangle 80 80 120 120 -fill blue -tags blue
    # bind a button press to re-build the canvas
    $w bind blue <ButtonRelease-1> [subst {
	[lindex [info level 0] 0] $w
	append ::x ok
    }]
}



test canvas-13.1 {canvas delete during event, SF bug-228024} -body {
    kill_canvas .c
    set ::x {}
    # do this many times to improve chances of triggering the crash
    for {set i 0} {$i < 30} {incr i} {
	event generate .c <Button-1> -x 100 -y 100
	event generate .c <ButtonRelease-1> -x 100 -y 100
    }
    return $::x
} -result {okokokokokokokokokokokokokokokokokokokokokokokokokokokokokok}

test canvas-14.1 {canvas scan SF bug 581560} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c scan
} -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.2 {canvas scan} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c scan bogus
} -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.3 {canvas scan} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c scan mark
} -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.4 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan mark 10 10
} -result {}
test canvas-14.5 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan mark 10 10 5
} -returnCodes error -result {wrong # args: should be ".c scan mark x y"}
test canvas-14.6 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan dragto 10 10 5
} -result {}

test canvas-15.1 {basic types check: arc requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create arc
} -result {wrong # args: should be ".c create arc coords ?arg ...?"}
test canvas-15.2 "basic coords check: arc coords are paired" -setup {
    destroy .c
    canvas .c
} -body {
    .c create arc 0
} -returnCodes error -result {wrong # coordinates: expected 4, got 1}

test canvas-15.3 {basic types check: bitmap requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create bitmap
} -result {wrong # args: should be ".c create bitmap coords ?arg ...?"}
test canvas-15.4 "basic coords check: bitmap coords are paired" -setup {
    destroy .c
    canvas .c
} -body {
    .c create bitmap 0
} -returnCodes error -result {wrong # coordinates: expected 2, got 1}
test canvas-15.5 {basic types check: image requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create image
} -result {wrong # args: should be ".c create image coords ?arg ...?"}
test canvas-15.6 "basic coords check: image coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create image 0
} -result {wrong # coordinates: expected 2, got 1}
test canvas-15.7 {basic types check: line requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create line
} -result {wrong # args: should be ".c create line coords ?arg ...?"}
test canvas-15.8 "basic coords check: line coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create line 0
} -result {wrong # coordinates: expected an even number, got 1}
test canvas-15.9 {basic types check: oval requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create oval
} -result {wrong # args: should be ".c create oval coords ?arg ...?"}
test canvas-15.10 "basic coords check: oval coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create oval 0
} -result {wrong # coordinates: expected 0 or 4, got 1}
test canvas-15.11 {basic types check: polygon requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create polygon
} -result {wrong # args: should be ".c create polygon coords ?arg ...?"}
test canvas-15.12 "basic coords check: polygon coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create polygon 0
} -result {wrong # coordinates: expected an even number, got 1}
test canvas-15.13 {basic types check: rect requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create rect
} -result {wrong # args: should be ".c create rect coords ?arg ...?"}
test canvas-15.14 "basic coords check: rect coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create rect 0
} -result {wrong # coordinates: expected 0 or 4, got 1}
test canvas-15.15 {basic types check: text requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create text
} -result {wrong # args: should be ".c create text coords ?arg ...?"}
test canvas-15.16 "basic coords check: text coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create text 0
} -result {wrong # coordinates: expected 2, got 1}
test canvas-15.17 {basic types check: window requires coords} -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create window
} -result {wrong # args: should be ".c create window coords ?arg ...?"}
test canvas-15.18 "basic coords check: window coords are paired" -setup {
    destroy .c
    canvas .c
} -returnCodes error -body {
    .c create window 0
} -result {wrong # coordinates: expected 2, got 1}
test canvas-15.19 "basic coords check: centimeters are larger than pixels" -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create rect 0 0 1cm 1cm]
    expr {[lindex [.c coords $id] 2]>1}
} -result 1
destroy .c


test canvas-16.1 {arc coords check} -setup {

    canvas .c
} -body {
    set id [.c create arc {0 10 20 30} -start 33]
    .c itemcget $id -start
} -cleanup {
    destroy .c
} -result {33.0}

test canvas-17.1 {default smooth method handling} -setup {

    canvas .c
} -body {
    set id [.c create line {0 0 1 1 2 2 3 3 4 4 5 5 6 6}]
    set result [.c itemcget $id -smooth]
    foreach smoother {yes 1 bezier raw r b} {
	.c itemconfigure $id -smooth $smoother
	lappend result [.c itemcget $id -smooth]
    }
    return $result
} -cleanup {
    destroy .c
} -result {0 true true true raw raw true}

test canvas-18.1 {imove method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {4.0 4.0 1.0 1.0 2.0 2.0 3.0 3.0}
test canvas-18.2 {imove method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1]
    .c imove $id 0 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {4.0 4.0 1.0 1.0}
test canvas-18.3 {imove method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id @1,1 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 4.0 4.0 2.0 2.0 3.0 3.0}
test canvas-18.4 {imove method - lines} -constraints knownBug -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id end 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 1.0 1.0 2.0 2.0 4.0 4.0}
test canvas-18.5 {imove method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c imove $id 0 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {4.0 4.0 1.0 1.0 2.0 2.0 3.0 3.0}
test canvas-18.6 {imove method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1]
    .c imove $id 0 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {4.0 4.0 1.0 1.0}
test canvas-18.7 {imove method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c imove $id @1,1 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 4.0 4.0 2.0 2.0 3.0 3.0}
test canvas-18.8 {imove method - polygon} -constraints knownBug -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c imove $id end 4 4
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 1.0 1.0 2.0 2.0 4.0 4.0}
test canvas-18.9 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id foobar 4 4
} -cleanup {
    destroy .c
} -returnCodes error -result {bad index "foobar"}
test canvas-18.10 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 foobar 4
} -cleanup {
    destroy .c
} -returnCodes error -result {bad screen distance "foobar"}
test canvas-18.11 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 4 foobar
} -cleanup {
    destroy .c
} -returnCodes error -result {bad screen distance "foobar"}

test canvas-19.1 {rchars method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {4 4}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 4.0 4.0 3.0 3.0}
test canvas-19.2 {rchars method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 3.0 3.0}
test canvas-19.3 {rchars method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {10 11 12 13 14 15}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 10.0 11.0 12.0 13.0 14.0 15.0 3.0 3.0}
test canvas-19.4 {rchars method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {4 4}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 4.0 4.0 3.0 3.0}
test canvas-19.5 {rchars method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 3.0 3.0}
test canvas-19.6 {rchars method - polygon} -setup {
    canvas .c
} -body {
    set id [.c create polygon 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {10 11 12 13 14 15}
    .c coords $id
} -cleanup {
    destroy .c
} -result {0.0 0.0 10.0 11.0 12.0 13.0 14.0 15.0 3.0 3.0}
test canvas-19.7 {rchars method - text} -setup {
    canvas .c
} -body {
    set id [.c create text 0 0 -text abcde]
    .c rchars $id 1 3 XYZ
    .c itemcget $id -text
} -cleanup {
    destroy .c
} -result aXYZe
test canvas-19.8 {rchars method - text} -setup {
    canvas .c
} -body {
    set id [.c create text 0 0 -text abcde]
    .c rchars $id 1 3 {}
    .c itemcget $id -text
} -cleanup {
    destroy .c
} -result ae
test canvas-19.9 {rchars method - text} -setup {
    canvas .c
} -body {
    set id [.c create text 0 0 -text abcde]
    .c rchars $id 1 3 FOOBAR
    .c itemcget $id -text
} -cleanup {
    destroy .c
} -result aFOOBARe
test canvas-19.10 {rchars method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1]
    .c rchars $id foo 1 {2 2}
} -cleanup {
    destroy .c
} -returnCodes error -result {bad index "foo"}
test canvas-19.11 {rchars method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1]
    .c rchars $id 1 foo {2 2}
} -cleanup {
    destroy .c
} -returnCodes error -result {bad index "foo"}

test canvas-20.1 {addtag/dtag - no shuffling of tag sequence} -setup {
    canvas .c
    .c create text 100 100 -text Hello
} -body {
    for {set i 1} {$i < 5} {incr i} {
        .c addtag tag$i all
    }
    # [.c addtags] only adds tags that are not already present
    .c addtag tag1 all   ; # no effect
    set res [list [.c gettags 1]]
    .c dtag 1 tag2
    lappend res [.c gettags 1]
} -cleanup {
    destroy .c
} -result {{tag1 tag2 tag3 tag4} {tag1 tag3 tag4}}
test canvas-20.2 {tag deletion - multiple tags with same name, no shuffling} -setup {
    canvas .c
    .c create text 100 100 -text Hello
} -body {
    # [.c itemconfigure -tags] lets the user add duplicate tags
    # this is not a problem although inconsistent with [.c addtags]
    .c itemconfigure 1 -tags {tagA tagB tagA tagA tagC tagA}
    set res [list [.c gettags 1]]
    .c dtag 1 tagA
    lappend res [.c gettags 1]
} -cleanup {
    destroy .c
} -result {{tagA tagB tagA tagA tagC tagA} {tagB tagC}}
test canvas-20.3 {tag deletion - all tags match} -setup {
    canvas .c
    .c create text 100 100 -text Hello
} -body {
    # [.c itemconfigure -tags] lets the user add duplicate tags
    # this is not a problem although inconsistent with [.c addtags]
    .c itemconfigure 1 -tags {tagA tagA tagA tagA tagA tagA}
    set res [list [.c gettags 1]]
    .c dtag 1 tagA
    lappend res [.c gettags 1]
} -cleanup {
    destroy .c
} -result {{tagA tagA tagA tagA tagA tagA} {}}

destroy .c
test canvas-21.1 {canvas rotate} -setup {
    pack [canvas .c]
} -body {
    .c create line 50 50 50 100 100 100
    .c rotate all 75 75 90
    lmap c [.c coords all] {format %.2f $c}
} -cleanup {
    destroy .c
} -result {50.00 100.00 100.00 100.00 100.00 50.00}
test canvas-21.2 {canvas rotate} -setup {
    pack [canvas .c]
} -body {
    .c create line 50 50 50 100 100 100
    .c rotate all 75 75 -10
    lmap c [.c coords all] {format %.2f $c}
} -cleanup {
    destroy .c
} -result {54.72 46.04 46.04 95.28 95.28 103.96}
test canvas-21.3 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 75 75
} -returnCodes error -cleanup {
    destroy .c
} -result {wrong # args: should be ".c rotate tagOrId x y angle"}
test canvas-21.4 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 75 75 123 123
} -returnCodes error -cleanup {
    destroy .c
} -result {wrong # args: should be ".c rotate tagOrId x y angle"}
test canvas-21.5 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate {!} 1 1 1
} -returnCodes error -cleanup {
    destroy .c
} -result {missing tag in tag search expression}
test canvas-21.6 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all x 1 1
} -returnCodes error -cleanup {
    destroy .c
} -result {bad screen distance "x"}
test canvas-21.7 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 x 1
} -returnCodes error -cleanup {
    destroy .c
} -result {bad screen distance "x"}
test canvas-21.8 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 1 x
} -returnCodes error -cleanup {
    destroy .c
} -result {expected floating-point number but got "x"}
test canvas-21.9 {canvas rotate: nothing to rotate} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 75 75 10
} -cleanup {
    destroy .c
} -result {}
test canvas-21.10 {canvas rotate: multiple things to rotate} -setup {
    pack [canvas .c]
} -body {
    .c create line 50 50 50 100 -tag a
    .c create line 50 50 100 50 -tag b
    .c rotate all 75 75 45
    list [lmap c [.c coords a] {format %.2f $c}] [lmap c [.c coords b] {format %.2f $c}]
} -cleanup {
    destroy .c
} -result {{39.64 75.00 75.00 110.36} {39.64 75.00 75.00 39.64}}

test canvas-22.1 {canvas rotate: arc item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create arc 50 50 75 75 -start 45 -extent 90
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {-start -extent} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 125.00 75.00 150.00} {45.0 90.0} {52 123 73 140}}
test canvas-22.2 {canvas rotate: bitmap item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create bitmap 50 50 -bitmap info -anchor se
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {-bitmap -anchor} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 150.00} {info se} {42 129 50 150}}
test canvas-22.3 {canvas rotate: image item rotation behaviour} -setup {
    pack [canvas .c]
    image create photo dummy -width 50 -height 50
} -body {
    .c create image 50 50 -image dummy -anchor se
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {-image -anchor} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
    image delete dummy
} -result {{50.00 150.00} {dummy se} {0 100 50 150}}
test canvas-22.4 {canvas rotate: line item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create line 50 50 75 50 50 75 75 75
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 150.00 50.00 125.00 75.00 150.00 75.00 125.00} {} {48 123 77 152}}
test canvas-22.5 {canvas rotate: oval item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create oval 50 50 65 85
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{60.00 125.00 75.00 160.00} {} {59 124 76 161}}
test canvas-22.6 {canvas rotate: polygon item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create polygon 50 50 75 50 50 75 75 75
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 150.00 50.00 125.00 75.00 150.00 75.00 125.00} {} {48 123 77 152}}
test canvas-22.7 {canvas rotate: rectangle item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create rectangle 50 50 75 75
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 125.00 75.00 150.00} {} {49 124 76 151}}
test canvas-22.8 {canvas rotate: text item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create text 50 50 -text foo -angle 45
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {-text -angle} {.c itemcget all $o}]
    # [.c bbox all]
    # No testing of text bounding box; fonts too variable!
} -cleanup {
    destroy .c
} -result {{50.00 150.00} {foo 45.0}}
test canvas-22.9 {canvas rotate: window item rotation behaviour} -setup {
    pack [canvas .c]
} -body {
    .c create window 50 50 -window [frame .c.f -width 25 -height 25] \
	-anchor se
    .c rotate all 100 100 90
    list [lmap c [.c coords all] {format %.2f $c}] \
	[lmap o {} {.c itemcget all $o}] \
	[.c bbox all]
} -cleanup {
    destroy .c
} -result {{50.00 150.00} {} {25 125 50 150}}

# Procedure used in test cases 23.1 23.2 23.3
proc matchPixels {pixels expected} {
    set matched 1
    foreach pline $pixels eline $expected {
        foreach ppixel $pline epixel $eline {
            if {$ppixel != $epixel} {
                set matched 0
                break
            }
        }
    }
    return $matched
}

test canvas-23.1 {canvas image} -setup {
    canvas .c
    image create photo testimage
} -body  {
    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
    .c create rectangle 0 0 0 9 -fill #000080 -outline #000080
    .c image testimage
    matchPixels [testimage data] { \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
} -cleanup {
    destroy .c
    image delete testimage
} -result 1

test canvas-23.2 {canvas image with subsample} -setup {
    canvas .c
    image create photo testimage
} -body  {
    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
    .c create rectangle 0 0 1 9 -fill #008000 -outline #008000
    .c image testimage 2
    matchPixels [testimage data] { \
        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
} -cleanup {
    destroy .c
    image delete testimage
} -result 1

test canvas-23.3 {canvas image with subsample and zoom} -setup {
    canvas .c
    image create photo testimage
} -body  {
    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
    .c create rectangle 0 0 9 0 -fill #800000 -outline #800000
    .c image testimage 1 2
    matchPixels [testimage data] { \
        {#800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000} \
        {#800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
} -cleanup {
    destroy .c
    image delete testimage
} -result 1

# cleanup
imageCleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







<









<
|
>
>
>
|




|


|
|




|

|



|

|



|

|



















<
|
<
<
|
<
<
<
<
<
|
<
>
|
<
<
<
|
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
|
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>


>




<
<



>








|
<
<


<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<


<
<
<
<
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498


499





500

501
502



503

504
505
506
507










































508




509






510

511
512
513




514








515




516
















517
518
519
520
521
522
523
524


525
526
527
528
529
530
531
532
533
534
535
536
537


538
539







540



















































































































































































































































































































541
































































































































































































542

543
544




    incr val
    # qx has type double and no string representation
    .c scale all $val 0 1 1
    # qx has now type MMRep and no string representation
    incr val
} -result 12


proc kill_canvas {w} {
    destroy $w
    pack [canvas $w -height 200 -width 200] -fill both -expand yes
    update idle
    $w create rectangle 80 80 120 120 -fill blue -tags blue
    # bind a button press to re-build the canvas
    $w bind blue <ButtonRelease-1> [subst {
	[lindex [info level 0] 0] $w
	append ::x ok

    }
    ]
}

test canvas-13.1 {canvas delete during event, SF bug-228024} {
    kill_canvas .c
    set ::x {}
    # do this many times to improve chances of triggering the crash
    for {set i 0} {$i < 30} {incr i} {
	event generate .c <1> -x 100 -y 100
	event generate .c <ButtonRelease-1> -x 100 -y 100
    }
    set ::x
} okokokokokokokokokokokokokokokokokokokokokokokokokokokokokok

test canvas-14.1 {canvas scan SF bug 581560} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan
} -returnCodes error -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.2 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan bogus
} -returnCodes error -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.3 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan mark
} -returnCodes error -result {wrong # args: should be ".c scan mark|dragto x y ?dragGain?"}
test canvas-14.4 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan mark 10 10
} -result {}
test canvas-14.5 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan mark 10 10 5
} -returnCodes error -result {wrong # args: should be ".c scan mark x y"}
test canvas-14.6 {canvas scan} -setup {
    destroy .c
    canvas .c
} -body {
    .c scan dragto 10 10 5
} -result {}


set i 0


proc create {w type args} {





    eval [list $w create $type] $args

}
foreach type {arc bitmap image line oval polygon rect text window} {



    incr i

    test canvas-15.$i "basic types check: $type requires coords" -setup {
	destroy .c
	canvas .c
    } -body {










































	.c create $type




    } -returnCodes error -result [format {wrong # args: should be ".c create %s coords ?arg arg ...?"} $type]






    incr i

    test canvas-15.$i "basic coords check: $type coords are paired" -setup {
	destroy .c
	canvas .c




    } -match glob -body {








	.c create $type 0




    } -returnCodes error -result "wrong # coordinates: expected*"
















}

test canvas-16.1 {arc coords check} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create arc {0 10 20 30} -start 33]
    .c itemcget $id -start


} -result {33.0}

test canvas-17.1 {default smooth method handling} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create line {0 0 1 1 2 2 3 3 4 4 5 5 6 6}]
    set result [.c itemcget $id -smooth]
    foreach smoother {yes 1 bezier raw r b} {
	.c itemconfigure $id -smooth $smoother
	lappend result [.c itemcget $id -smooth]
    }
    set result


} -result {0 true true true raw raw true}








destroy .c




















































































































































































































































































































































































































































































































# cleanup

cleanupTests
return




Changes to tests/choosedir.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# This file is a Tcl script to test out Tk's "tk_chooseDir" and
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

#----------------------------------------------------------------------
#
# Procedures needed by this test file
#
#----------------------------------------------------------------------

proc ToPressButton {parent btn} {
    after 100 SendButtonPress $parent $btn mouse
}

proc ToEnterDirsByKey {parent dirs} {
    after 100 [list EnterDirsByKey $parent $dirs]
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <Button-1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc EnterDirsByKey {parent dirs} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_choosedir



|
|



<



















|







1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# This file is a Tcl script to test out Tk's "tk_chooseDir" and
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

#----------------------------------------------------------------------
#
# Procedures needed by this test file
#
#----------------------------------------------------------------------

proc ToPressButton {parent btn} {
    after 100 SendButtonPress $parent $btn mouse
}

proc ToEnterDirsByKey {parent dirs} {
    after 100 [list EnterDirsByKey $parent $dirs]
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc EnterDirsByKey {parent dirs} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_choosedir
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
#
#----------------------------------------------------------------------
# Make a dir for us to rely on for tests
set real [makeDirectory choosedirTest]
set dir [file dirname $real]
set fake [file join $dir non-existant]

set parent .

test choosedir-1.1 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -initialdir
} -returnCodes error -result {value for "-initialdir" missing}
test choosedir-1.2 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -mustexist
} -returnCodes error -result {value for "-mustexist" missing}
test choosedir-1.3 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent
} -returnCodes error -result {value for "-parent" missing}
test choosedir-1.4 {tk_chooseDirectory command} -body {

    tk_chooseDirectory -title
} -returnCodes error -result {value for "-title" missing}
test choosedir-1.5.1 {tk_chooseDirectory command} -constraints notAqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test choosedir-1.5.2 {tk_chooseDirectory command} -constraints aqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -message, -mustexist, -parent, -title, or -command}
test choosedir-1.6 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


test choosedir-2.1 {tk_chooseDirectory command, cancel gives null} -constraints {
	unix notAqua
} -body {
    ToPressButton $parent cancel
    tk_chooseDirectory -title "Press Cancel" -parent $parent
} -result {}


test choosedir-3.1 {tk_chooseDirectory -mustexist 1} -constraints {
	unix notAqua
} -body {
    # first enter a bogus dirname, then enter a real one.
    ToEnterDirsByKey $parent [list $fake $real $real]
    set result [tk_chooseDirectory \
	    -title "Enter \"$fake\", press OK, enter \"$real\", press OK" \
	    -parent $parent -mustexist 1]
    set result
} -result $real
test choosedir-3.2 {tk_chooseDirectory -mustexist 0} -constraints {
	unix notAqua
} -body {
    ToEnterDirsByKey $parent [list $fake $fake]
    tk_chooseDirectory -title "Enter \"$fake\", press OK" \
	    -parent $parent -mustexist 0
} -result $fake


test choosedir-4.1 {tk_chooseDirectory command, initialdir} -constraints {
	unix notAqua
} -body {
    ToPressButton $parent ok
    tk_chooseDirectory -title "Press Ok" -parent $parent -initialdir $real
} -result $real
test choosedir-4.2 {tk_chooseDirectory command, initialdir} -constraints {
	unix notAqua
} -body {
    ToEnterDirsByKey $parent [list $fake $fake]
    tk_chooseDirectory \
	    -title "Enter \"$fake\" and press Ok" \
	    -parent $parent -initialdir $real
} -result $fake
test choosedir-4.3 {tk_chooseDirectory command, {} initialdir} -constraints {
	unix notAqua
} -body {
    catch {unset ::tk::dialog::file::__tk_choosedir}
    ToPressButton $parent ok
    tk_chooseDirectory \
	    -title "Press OK" \
	    -parent $parent -initialdir ""
} -result [pwd]


test choosedir-5.1 {tk_chooseDirectory, handles {} entry text} -constraints {
	unix notAqua
} -body {
    ToEnterDirsByKey $parent [list "" $real $real]
    tk_chooseDirectory -title "Clear entry, Press OK; Enter $real, press OK" \
	    -parent $parent
} -result $real

# cleanup
removeDirectory choosedirTest
cleanupTests
return







|
















<
|
<
|
<
<
<
|
|
<
>
|
<
<
|
|
<
|
<
<
|
|


|
<
<


<
|

|
<
<






|
|
<
<



|

<
|
<
<


|
|
<
<




|
<
|
<





|

<
|
<
<



|





63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87

88



89
90

91
92


93
94

95


96
97
98
99
100


101
102

103
104
105


106
107
108
109
110
111
112
113


114
115
116
117
118

119


120
121
122
123


124
125
126
127
128

129

130
131
132
133
134
135
136

137


138
139
140
141
142
143
144
145
146

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <KeyPress> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
#
#----------------------------------------------------------------------
# Make a dir for us to rely on for tests
set real [makeDirectory choosedirTest]
set dir [file dirname $real]
set fake [file join $dir non-existant]

set parent .


foreach opt {-initialdir -mustexist -parent -title} {

    test choosedir-1.1$opt "tk_chooseDirectory command" unix {



	list [catch {tk_chooseDirectory $opt} msg] $msg
    } [list 1 "value for \"$opt\" missing"]

}
test choosedir-1.2 "tk_chooseDirectory command" unix {


    list [catch {tk_chooseDirectory -foo bar} msg] $msg
} [list 1 "bad option \"-foo\": must be -initialdir, -mustexist, -parent, or -title"]

test choosedir-1.3 "tk_chooseDirectory command" unix {


    list [catch {tk_chooseDirectory -parent foo.bar} msg] $msg
} {1 {bad window path name "foo.bar"}}


test choosedir-2.1 "tk_chooseDirectory command, cancel gives null" {unix notAqua} {


    ToPressButton $parent cancel
    tk_chooseDirectory -title "Press Cancel" -parent $parent

} ""

test choosedir-3.1 "tk_chooseDirectory -mustexist 1" {unix notAqua} {


    # first enter a bogus dirname, then enter a real one.
    ToEnterDirsByKey $parent [list $fake $real $real]
    set result [tk_chooseDirectory \
	    -title "Enter \"$fake\", press OK, enter \"$real\", press OK" \
	    -parent $parent -mustexist 1]
    set result
} $real
test choosedir-3.2 "tk_chooseDirectory -mustexist 0" {unix notAqua} {


    ToEnterDirsByKey $parent [list $fake $fake]
    tk_chooseDirectory -title "Enter \"$fake\", press OK" \
	    -parent $parent -mustexist 0
} $fake


test choosedir-4.1 "tk_chooseDirectory command, initialdir" {unix notAqua} {


    ToPressButton $parent ok
    tk_chooseDirectory -title "Press Ok" -parent $parent -initialdir $real
} $real
test choosedir-4.2 "tk_chooseDirectory command, initialdir" {unix notAqua} {


    ToEnterDirsByKey $parent [list $fake $fake]
    tk_chooseDirectory \
	    -title "Enter \"$fake\" and press Ok" \
	    -parent $parent -initialdir $real
} $fake

test choosedir-4.3 "tk_chooseDirectory, -initialdir {}" {unix notAqua} {

    catch {unset ::tk::dialog::file::__tk_choosedir}
    ToPressButton $parent ok
    tk_chooseDirectory \
	    -title "Press OK" \
	    -parent $parent -initialdir ""
} [pwd]


test choosedir-5.1 "tk_chooseDirectory, handles {} entry text" {unix notAqua} {


    ToEnterDirsByKey $parent [list "" $real $real]
    tk_chooseDirectory -title "Clear entry, Press OK; Enter $real, press OK" \
	    -parent $parent
} $real

# cleanup
removeDirectory choosedirTest
cleanupTests
return

Changes to tests/clipboard.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146


147
148
149
150

151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241

242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293


294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325

326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# This file is a Tcl script to test out Tk's clipboard management code,
# especially the "clipboard" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display clipboard handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#

#################################################################
# Note that some of these tests may fail if another application #
# is grabbing the clipboard (e.g. an X server, or a VNC viewer) #
#################################################################

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# Now we start the main body of the test code

test clipboard-1.1 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append "test"
    clipboard get
} -cleanup {
    clipboard clear
} -result {test}
test clipboard-1.2 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append "test"
    clipboard append "ing"
    clipboard get
} -cleanup {
    clipboard clear
} -result {testing}
test clipboard-1.3 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append "t"
    clipboard append "e"
    clipboard append "s"
    clipboard append "t"
    clipboard get
} -cleanup {
    clipboard clear
} -result {test}
test clipboard-1.4 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append $longValue
    clipboard get
} -cleanup {
    clipboard clear
} -result "$longValue"
test clipboard-1.5 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append $longValue
    clipboard append "test"
    clipboard get
} -cleanup {
    clipboard clear
} -result "${longValue}test"
test clipboard-1.6 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append -t TEST $longValue
    clipboard append -t STRING "test"
    list [clipboard get -t STRING] [clipboard get -t TEST]
} -cleanup {
    clipboard clear
} -result [list test $longValue]
test clipboard-1.7 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append -t TEST [string range $longValue 1 4000]
    clipboard append -t STRING "test"
    list [clipboard get -t STRING] [clipboard get -t TEST]
} -cleanup {
    clipboard clear
} -result [list test [string range $longValue 1 4000]]
test clipboard-1.8 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append ""
    clipboard get
} -cleanup {
    clipboard clear
} -result {}
test clipboard-1.9 {ClipboardHandler procedure} -setup {
    clipboard clear
} -body {
    clipboard append ""
    clipboard append "Test"
    clipboard get
} -cleanup {
    clipboard clear
} -result {Test}

##############################################################################

test clipboard-2.1 {ClipboardAppHandler procedure} -setup {
    set oldAppName [tk appname]
    clipboard clear
} -body {
    tk appname UnexpectedName
    clipboard append -type NEW_TYPE Data
    selection get -selection CLIPBOARD -type TK_APPLICATION
} -cleanup {
    tk appname $oldAppName
    clipboard clear
} -result {UnexpectedName}

##############################################################################

test clipboard-3.1 {ClipboardWindowHandler procedure} -setup {
    set oldAppName [tk appname]
    clipboard clear
} -body {
    tk appname UnexpectedName
    clipboard append -type NEW_TYPE Data
    selection get -selection CLIPBOARD -type TK_WINDOW
} -cleanup {
    tk appname $oldAppName
    clipboard clear
} -result {.}


##############################################################################

test clipboard-4.1 {ClipboardLostSel procedure} -setup {


    clipboard clear
} -body {
    clipboard append "Test"
    selection clear -s CLIPBOARD

    clipboard get
} -cleanup {
    clipboard clear

}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}
test clipboard-4.2 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    selection clear -s CLIPBOARD
    clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}
test clipboard-4.3 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    selection clear -s CLIPBOARD
    clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}
test clipboard-4.4 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    clipboard append "Test3"
    selection clear -s CLIPBOARD
    clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}
test clipboard-4.5 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    clipboard append "Test3"
    selection clear -s CLIPBOARD
    clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}



##############################################################################

test clipboard-5.1 {Tk_ClipboardClear procedure} -setup {
    clipboard clear
} -body {
    clipboard append -t TEST "test"
    set result [lsort [clipboard get TARGETS]]
    clipboard clear
    list $result [lsort [clipboard get TARGETS]]
} -cleanup {
    clipboard clear
}  -result {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test clipboard-5.2 {Tk_ClipboardClear procedure} -setup {
    clipboard clear
} -body {
    clipboard append -t TEST "test"
    set result [lsort [clipboard get TARGETS]]
    selection own -s CLIPBOARD .
    lappend result [lsort [clipboard get TARGETS]]
    clipboard clear
    clipboard append -t TEST "test"
    lappend result [lsort [clipboard get TARGETS]]
} -cleanup {
    clipboard clear
}  -result {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}

##############################################################################

test clipboard-6.1 {Tk_ClipboardAppend procedure} -setup {
    clipboard clear
} -body {
    clipboard append "first chunk"
    selection own -s CLIPBOARD .

	clipboard append " second chunk"
	clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes ok -result {first chunk second chunk}
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints {x11 failsOnXQuarz} -setup {
    clipboard clear
} -body {
    setupbg

    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {
    clipboard clear
    cleanupbg

}  -result {0x10 }
test clipboard-6.3 {Tk_ClipboardAppend procedure} -setup {
    clipboard clear
} -body {
    clipboard append -f INTEGER -t TEST "16"
    clipboard append -t TEST "test"
} -cleanup {
    clipboard clear
}  -returnCodes error -result {format "STRING" does not match current format "INTEGER" for TEST}

##############################################################################

test clipboard-7.1 {Tk_ClipboardCmd procedure} -body {
    clipboard
} -returnCodes error -result {wrong # args: should be "clipboard option ?arg ...?"}
test clipboard-7.2 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append --
} -cleanup {
    clipboard clear
} -returnCodes ok -result {}
test clipboard-7.3 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append --
	selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -result {--}
test clipboard-7.4 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -- information
	selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -result {information}
test clipboard-7.5 {Tk_ClipboardCmd procedure} -body {
    clipboard append --x a b
} -returnCodes error -result {bad option "--x": must be -displayof, -format, or -type}
test clipboard-7.6 {Tk_ClipboardCmd procedure} -body {
    clipboard append -- a b
} -returnCodes error -result {wrong # args: should be "clipboard append ?-option value ...? data"}
test clipboard-7.7 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear


} -body {
    clipboard append -format
} -returnCodes ok -result {}
test clipboard-7.8 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -format
	selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -result {-format}
test clipboard-7.9 {Tk_ClipboardCmd procedure} -body {
    clipboard append -displayofoo f
} -returnCodes error -result {bad option "-displayofoo": must be -displayof, -format, or -type}
test clipboard-7.10 {Tk_ClipboardCmd procedure} -body {
    clipboard append -type TEST
} -returnCodes error -result {wrong # args: should be "clipboard append ?-option value ...? data"}
test clipboard-7.11 {Tk_ClipboardCmd procedure} -body {
    clipboard append -displayof foo "test"
} -returnCodes error -result {bad window path name "foo"}

test clipboard-7.12 {Tk_ClipboardCmd procedure} -body {
    clipboard clear -displayof
} -returnCodes error -result {wrong # args: should be "clipboard clear ?-displayof window?"}
test clipboard-7.13 {Tk_ClipboardCmd procedure} -body {
    clipboard clear -displayofoo f
} -returnCodes error -result {bad option "-displayofoo": must be -displayof}
test clipboard-7.14 {Tk_ClipboardCmd procedure} -body {
    clipboard clear foo
} -returnCodes error -result {wrong # args: should be "clipboard clear ?-displayof window?"}
test clipboard-7.15 {Tk_ClipboardCmd procedure} -body {
    clipboard clear -displayof foo
} -returnCodes error -result {bad window path name "foo"}

test clipboard-7.16 {Tk_ClipboardCmd procedure} -body {
    clipboard error
} -returnCodes error -result {bad option "error": must be append, clear, or get}

test clipboard-7.17 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -displayof
} -cleanup {
    clipboard clear
} -returnCodes ok -result {}
test clipboard-7.18 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -displayof
	selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -result {-displayof}
test clipboard-7.19 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -type
} -cleanup {
    clipboard clear
} -returnCodes ok -result {}
test clipboard-7.20 {Tk_ClipboardCmd procedure} -setup {
    clipboard clear
} -body {
    clipboard append -type
	selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -result {-type}

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:




|
|







<
<
<
<
<

<



<
<








|
|

<


<
<
|
|

<



<
<
|
|

<





<
<
|
|

<


<
<
|
|

<



<
<
|
|

<


|
<
|
|
|

<


|
<
|
|
|

<


|
<
<
|

<



<
<
|



|

<
<

<
<
<
<

<
<
<
<
<
<
<
<
<

|
<

<
|
>



|
>
>

<
|
|
>
|
|
|
>
|
|

<

<

|
<
<
|
|
<
<
<
<
<
<
<
<
<
<

<


<

|
<
|
|
|

<




|
<
|
|

<
<


|

<




<
<
|
|

<







<
<
|



|

<


>


|
<
|
|
<
<

>


<
<
<

>
|
|

<

|
<
<
|



|
|
|
|

<
|
<
<
<
<
<
<
<
|
|
<
<
|

<
|
|
<
<
|
|
|
|
|
|
|
|

>
>
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
>
|

<
|
<
<
<
<
<
<
<
|
<
<
|
|

<
|
<
<
<
<
<
<
<
|
<
<
|
|



<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13





14

15
16
17


18
19
20
21
22
23
24
25
26
27
28

29
30


31
32
33

34
35
36


37
38
39

40
41
42
43
44


45
46
47

48
49


50
51
52

53
54
55


56
57
58

59
60
61

62
63
64
65

66
67
68

69
70
71
72

73
74
75


76
77

78
79
80


81
82
83
84
85
86


87




88









89
90

91

92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110

111

112
113


114
115










116

117
118

119
120

121
122
123
124

125
126
127
128
129

130
131
132


133
134
135
136

137
138
139
140


141
142
143

144
145
146
147
148
149
150


151
152
153
154
155
156

157
158
159
160
161
162

163
164


165
166
167
168



169
170
171
172
173

174
175


176
177
178
179
180
181
182
183
184

185







186
187


188
189

190
191


192
193
194
195
196
197
198
199
200
201
202










203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233







234


235
236
237

238







239


240
241
242
243
244




# This file is a Tcl script to test out Tk's clipboard management code,
# especially the "clipboard" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display clipboard handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#






package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands



# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# Now we start the main body of the test code

test clipboard-1.1 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append "test"
    clipboard get


} {test}
test clipboard-1.2 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append "test"
    clipboard append "ing"
    clipboard get


} {testing}
test clipboard-1.3 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append "t"
    clipboard append "e"
    clipboard append "s"
    clipboard append "t"
    clipboard get


} {test}
test clipboard-1.4 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append $longValue
    clipboard get


} "$longValue"
test clipboard-1.5 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append $longValue
    clipboard append "test"
    clipboard get


} "${longValue}test"
test clipboard-1.6 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append -t TEST $longValue
    clipboard append -t STRING "test"
    list [clipboard get -t STRING] \

	[clipboard get -t TEST]
} [list test $longValue]
test clipboard-1.7 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append -t TEST [string range $longValue 1 4000]
    clipboard append -t STRING "test"
    list [clipboard get -t STRING] \

	[clipboard get -t TEST]
} [list test [string range $longValue 1 4000]]
test clipboard-1.8 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append ""
    clipboard get
} {}


test clipboard-1.9 {ClipboardHandler procedure} {
    clipboard clear

    clipboard append ""
    clipboard append "Test"
    clipboard get


} {Test}

##############################################################################

test clipboard-2.1 {ClipboardAppHandler procedure} {
    set oldAppName [tk appname]


    tk appname UnexpectedName




    clipboard clear









    clipboard append -type NEW_TYPE Data
    set result [selection get -selection CLIPBOARD -type TK_APPLICATION]

    tk appname $oldAppName

    set result
} {UnexpectedName}

##############################################################################

test clipboard-3.1 {ClipboardWindowHandler procedure} {
    set oldAppName [tk appname]
    tk appname UnexpectedName
    clipboard clear

    clipboard append -type NEW_TYPE Data
    set result [selection get -selection CLIPBOARD -type TK_WINDOW]
    tk appname $oldAppName
    set result
} {.}

##############################################################################

test clipboard-4.1 {ClipboardLostSel procedure} {
    clipboard clear

    clipboard append "Test"

    selection clear -s CLIPBOARD
    list [catch {clipboard get} msg] $msg


} {1 {CLIPBOARD selection doesn't exist or form "STRING" not defined}}
test clipboard-4.2 {ClipboardLostSel procedure} {










    clipboard clear

    clipboard append "Test"
    clipboard append -t TEST "Test2"

    selection clear -s CLIPBOARD
    list [catch {clipboard get} msg] $msg \

	[catch {clipboard get -t TEST} msg] $msg
} {1 {CLIPBOARD selection doesn't exist or form "STRING" not defined} 1 {CLIPBOARD selection doesn't exist or form "TEST" not defined}}
test clipboard-4.3 {ClipboardLostSel procedure} {
    clipboard clear

    clipboard append "Test"
    clipboard append -t TEST "Test2"
    clipboard append "Test3"
    selection clear -s CLIPBOARD
    list [catch {clipboard get} msg] $msg \

	[catch {clipboard get -t TEST} msg] $msg
} {1 {CLIPBOARD selection doesn't exist or form "STRING" not defined} 1 {CLIPBOARD selection doesn't exist or form "TEST" not defined}}



##############################################################################

test clipboard-5.1 {Tk_ClipboardClear procedure} {
    clipboard clear

    clipboard append -t TEST "test"
    set result [lsort [clipboard get TARGETS]]
    clipboard clear
    list $result [lsort [clipboard get TARGETS]]


} {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test clipboard-5.2 {Tk_ClipboardClear procedure} {
    clipboard clear

    clipboard append -t TEST "test"
    set result [lsort [clipboard get TARGETS]]
    selection own -s CLIPBOARD .
    lappend result [lsort [clipboard get TARGETS]]
    clipboard clear
    clipboard append -t TEST "test"
    lappend result [lsort [clipboard get TARGETS]]


} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}

##############################################################################

test clipboard-6.1 {Tk_ClipboardAppend procedure} {
    clipboard clear

    clipboard append "first chunk"
    selection own -s CLIPBOARD .
    list [catch {
	clipboard append " second chunk"
	clipboard get
    } msg] $msg

} {0 {first chunk second chunk}}
test clipboard-6.2 {Tk_ClipboardAppend procedure} unix {


    setupbg
    clipboard clear
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]



    cleanupbg
    set result
} {0x10 }
test clipboard-6.3 {Tk_ClipboardAppend procedure} {
    clipboard clear

    clipboard append -f INTEGER -t TEST "16"
    list [catch {clipboard append -t TEST "test"} msg] $msg


} {1 {format "STRING" does not match current format "INTEGER" for TEST}}

##############################################################################

test clipboard-7.1 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard} msg] $msg
} {1 {wrong # args: should be "clipboard option ?arg arg ...?"}}
test clipboard-7.2 {Tk_ClipboardCmd procedure} {
    clipboard clear

    list [catch {clipboard append --} msg] $msg \







	    [selection get -selection CLIPBOARD]
} {0 {} --}


test clipboard-7.3 {Tk_ClipboardCmd procedure} {
    clipboard clear

    list [catch {clipboard append -- information} msg] $msg \
	    [selection get -selection CLIPBOARD]


} {0 {} information}
test clipboard-7.4 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard append --x a b} msg] $msg
} {1 {bad option "--x": must be -displayof, -format, or -type}}
test clipboard-7.5 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard append -- a b} msg] $msg
} {1 {wrong # args: should be "clipboard append ?options? data"}}
test clipboard-7.6 {Tk_ClipboardCmd procedure} {
    clipboard clear
    list [catch {clipboard append -format} msg] $msg \
	    [selection get -selection CLIPBOARD]










} {0 {} -format}
test clipboard-7.7 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard append -displayofoo f} msg] $msg
} {1 {bad option "-displayofoo": must be -displayof, -format, or -type}}
test clipboard-7.8 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard append -type TEST} msg] $msg
} {1 {wrong # args: should be "clipboard append ?options? data"}}
test clipboard-7.9 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard append -displayof foo "test"} msg] $msg
} {1 {bad window path name "foo"}}

test clipboard-7.10 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard clear -displayof} msg] $msg
} {1 {wrong # args: should be "clipboard clear ?-displayof window?"}}
test clipboard-7.11 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard clear -displayofoo f} msg] $msg
} {1 {bad option "-displayofoo": must be -displayof}}
test clipboard-7.12 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard clear foo} msg] $msg
} {1 {wrong # args: should be "clipboard clear ?-displayof window?"}}
test clipboard-7.13 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard clear -displayof foo} msg] $msg
} {1 {bad window path name "foo"}}

test clipboard-7.14 {Tk_ClipboardCmd procedure} {
    list [catch {clipboard error} msg] $msg
} {1 {bad option "error": must be append, clear, or get}}

test clipboard-7.15 {Tk_ClipboardCmd procedure} {
    clipboard clear

    list [catch {clipboard append -displayof} msg] $msg \







	    [selection get -selection CLIPBOARD]


} {0 {} -displayof}
test clipboard-7.16 {Tk_ClipboardCmd procedure} {
    clipboard clear

    list [catch {clipboard append -type} msg] $msg \







	    [selection get -selection CLIPBOARD]


} {0 {} -type}

# cleanup
cleanupTests
return




Changes to tests/clrpick.test.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
# This file is a Tcl script to test out Tk's "tk_chooseColor" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


if {[testConstraint defaultPseudocolor8]} {
    # let's soak up a bunch of colors...so that
    # machines with small color palettes still fail.
    # some tests will be skipped if there are no more colors
    set numcolors 32
    testConstraint colorsLeftover 1



|
|





|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# This file is a Tcl script to test out Tk's "tk_chooseColor" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

if {[testConstraint defaultPseudocolor8]} {
    # let's soak up a bunch of colors...so that
    # machines with small color palettes still fail.
    # some tests will be skipped if there are no more colors
    set numcolors 32
    testConstraint colorsLeftover 1
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	incr i
    }
    destroy .c
} else {
    testConstraint colorsLeftover 0
}

test clrpick-1.1 {tk_chooseColor command} -body {
    tk_chooseColor -foo
} -returnCodes error -result {bad option "-foo": must be -initialcolor, -parent, or -title}

test clrpick-1.2 {tk_chooseColor command } -body {
    tk_chooseColor -initialcolor

} -returnCodes error -result {value for "-initialcolor" missing}
test clrpick-1.2.1 {tk_chooseColor command } -body {
    tk_chooseColor -parent
} -returnCodes error -result {value for "-parent" missing}
test clrpick-1.2.2 {tk_chooseColor command } -body {
    tk_chooseColor -title
} -returnCodes error -result {value for "-title" missing}



test clrpick-1.3 {tk_chooseColor command} -body {
    tk_chooseColor -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialcolor, -parent, or -title}
test clrpick-1.4 {tk_chooseColor command} -body {
    tk_chooseColor -initialcolor
} -returnCodes error -result {value for "-initialcolor" missing}
test clrpick-1.5 {tk_chooseColor command} -body {
    tk_chooseColor -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}
test clrpick-1.6 {tk_chooseColor command} -body {
    tk_chooseColor -initialcolor badbadbaadcolor
} -returnCodes error -result {unknown color name "badbadbaadcolor"}
test clrpick-1.7 {tk_chooseColor command} -body {
    tk_chooseColor -initialcolor ##badbadbaadcolor
} -returnCodes error -result {invalid color name "##badbadbaadcolor"}


# tests 3.1 and 3.2 fail when individually run
# if there is no catch {tk_chooseColor -foo 1} msg
# before settin isNative
catch {tk_chooseColor -foo 1} msg
set isNative [expr {[info commands tk::dialog::color::] eq ""}]

proc ToPressButton {parent btn} {
    global isNative
    if {!$isNative} {
	after 200 "SendButtonPress . $btn mouse"
    }
}

proc ToChooseColorByKey {parent r g b} {
    global isNative
    if {!$isNative} {
	after 200 ChooseColorByKey . $r $g $b
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <Button-1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc ChooseColorByKey {parent r g b} {
    set w .__tk__color
    upvar ::tk::dialog::color::[winfo name $w] data








|
|
|

<
|
>
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
<
<
<
<





|






|





|







41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79





80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	incr i
    }
    destroy .c
} else {
    testConstraint colorsLeftover 0
}

test clrpick-1.1 {tk_chooseColor command} {
    list [catch {tk_chooseColor -foo} msg] $msg
} {1 {bad option "-foo": must be -initialcolor, -parent, or -title}}


catch {tk_chooseColor -foo 1} msg
regsub -all ,      $msg "" options
regsub \"-foo\" $options "" options

foreach option $options {
    if {[string index $option 0] eq "-"} {
	test clrpick-1.2$option {tk_chooseColor command} -body {
	    tk_chooseColor $option
	} -returnCodes error -result "value for \"$option\" missing"
    }
}

test clrpick-1.3 {tk_chooseColor command} {
    list [catch {tk_chooseColor -foo bar} msg] $msg
} {1 {bad option "-foo": must be -initialcolor, -parent, or -title}}
test clrpick-1.4 {tk_chooseColor command} {
    list [catch {tk_chooseColor -initialcolor} msg] $msg
} {1 {value for "-initialcolor" missing}}
test clrpick-1.5 {tk_chooseColor command} {
    list [catch {tk_chooseColor -parent foo.bar} msg] $msg
} {1 {bad window path name "foo.bar"}}
test clrpick-1.6 {tk_chooseColor command} {
    list [catch {tk_chooseColor -initialcolor badbadbaadcolor} msg] $msg
} {1 {unknown color name "badbadbaadcolor"}}
test clrpick-1.7 {tk_chooseColor command} {
    list [catch {tk_chooseColor -initialcolor ##badbadbaadcolor} msg] $msg
} {1 {invalid color name "##badbadbaadcolor"}}






set isNative [expr {[info commands tk::dialog::color::] eq ""}]

proc ToPressButton {parent btn} {
    global isNative
    if {!$isNative} {
	after 200 "SendButtonPress $parent $btn mouse"
    }
}

proc ToChooseColorByKey {parent r g b} {
    global isNative
    if {!$isNative} {
	after 200 ChooseColorByKey $parent $r $g $b
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc ChooseColorByKey {parent r g b} {
    set w .__tk__color
    upvar ::tk::dialog::color::[winfo name $w] data

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162



163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    $data(blue,entry)  insert 0 $b

    # Manually force the refresh of the color values instead
    # of counting on the timing of the event stream to change
    # the values for us.
    tk::dialog::color::HandleRGBEntry $w

    SendButtonPress . ok mouse
}

proc SendButtonPress {parent btn type} {
    set w .__tk__color
    upvar ::tk::dialog::color::[winfo name $w] data

    set button $data($btn\Btn)
    if ![winfo ismapped $button] {
	update
    }

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
    }
}



test clrpick-2.1 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -setup {
    set verylongstring longstring:
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    # Interesting thing...when this is too long, the
    # delay caused in processing it kills the automated testing,
    # and makes a lot of the test cases fail.
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
} -body {



    ToPressButton . ok
    tk_chooseColor -title "Press Ok $verylongstring" -initialcolor #404040 \
        -parent .
} -result {#404040}

test clrpick-2.2 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -body {
    set colors "128 128 64"
    ToChooseColorByKey . 128 128 64
    tk_chooseColor -parent . -title "choose #808040"
} -result {#808040}
test clrpick-2.3 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -body {
    ToPressButton . ok
    tk_chooseColor -parent . -title "Press OK"
} -result {#808040}
test clrpick-2.4 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -body {
    ToPressButton . cancel
    tk_chooseColor -parent . -title "Press Cancel"
} -result {}



test clrpick-3.1 {tk_chooseColor: background events} -constraints {
	nonUnixUserInteraction
} -body {
    after 1 {set x 53}
    ToPressButton . ok
    tk_chooseColor -parent . -title "Press OK" -initialcolor #000000
} -result {#000000}
test clrpick-3.2 {tk_chooseColor: background events} -constraints {
	nonUnixUserInteraction
} -body {
    after 1 {set x 53}
    ToPressButton . cancel
    tk_chooseColor -parent . -title "Press Cancel"
} -result {}


test clrpick-4.1 {tk_chooseColor: screen is inherited from parent} -constraints {
	unix notAqua
} -body {
    after 50 {set ::scr [winfo screen .__tk__color]}
    ToPressButton . cancel
    tk_chooseColor -parent .
    set ::scr
} -result [winfo screen .]

# cleanup
cleanupTests
return








|

















|



|

<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
|
|
|
|
>
|
|
<

|
|
|
|
|
<
|
|
|
|
<
<
|
|
<
|

>
|
<
<

|
|
|
|
<
<

|
|
<
|

|
<
<

|
|

|




<
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173

174
175
176
177


178
179

180
181
182
183


184
185
186
187
188


189
190
191

192
193
194


195
196
197
198
199
200
201
202
203

    $data(blue,entry)  insert 0 $b

    # Manually force the refresh of the color values instead
    # of counting on the timing of the event stream to change
    # the values for us.
    tk::dialog::color::HandleRGBEntry $w

    SendButtonPress $parent ok mouse
}

proc SendButtonPress {parent btn type} {
    set w .__tk__color
    upvar ::tk::dialog::color::[winfo name $w] data

    set button $data($btn\Btn)
    if ![winfo ismapped $button] {
	update
    }

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <KeyPress> -keysym Return
    }
}

set parent .




set verylongstring longstring:
set verylongstring $verylongstring$verylongstring
set verylongstring $verylongstring$verylongstring
set verylongstring $verylongstring$verylongstring
set verylongstring $verylongstring$verylongstring
#set verylongstring $verylongstring$verylongstring
# Interesting thing...when this is too long, the
# delay caused in processing it kills the automated testing,
# and makes a lot of the test cases fail.
#set verylongstring $verylongstring$verylongstring
#set verylongstring $verylongstring$verylongstring
#set verylongstring $verylongstring$verylongstring
#set verylongstring $verylongstring$verylongstring

set color #404040
test clrpick-2.1 {tk_chooseColor command} \
	{nonUnixUserInteraction colorsLeftover} {
    ToPressButton $parent ok
    tk_chooseColor -title "Press Ok $verylongstring" -initialcolor $color \
	    -parent $parent
} "$color"
set color #808040
test clrpick-2.2 {tk_chooseColor command} \
	{nonUnixUserInteraction colorsLeftover} {

    set colors "128 128 64"
    ToChooseColorByKey $parent 128 128 64
    tk_chooseColor -parent $parent -title "choose $colors"
} "$color"
test clrpick-2.3 {tk_chooseColor command} \
	{nonUnixUserInteraction colorsLeftover failsOnQuarz} {

    ToPressButton $parent ok
    tk_chooseColor -parent $parent -title "Press OK"
} "$color"
test clrpick-2.4 {tk_chooseColor command} {nonUnixUserInteraction} {


    ToPressButton $parent cancel
    tk_chooseColor -parent $parent -title "Press Cancel"

} ""

set color "#000000"
test clrpick-3.1 {tk_chooseColor: background events} {nonUnixUserInteraction} {


    after 1 {set x 53}
    ToPressButton $parent ok
    tk_chooseColor -parent $parent -title "Press OK" -initialcolor $color
} "#000000"
test clrpick-3.2 {tk_chooseColor: background events} {nonUnixUserInteraction} {


    after 1 {set x 53}
    ToPressButton $parent cancel
    tk_chooseColor -parent $parent -title "Press Cancel"

} ""

test clrpick-4.1 {tk_chooseColor: screen is inherited from parent} {unix notAqua} {


    after 50 {set ::scr [winfo screen .__tk__color]}
    ToPressButton $parent cancel
    tk_chooseColor -parent $parent
    set ::scr
} [winfo screen $parent]

# cleanup
cleanupTests
return

Changes to tests/cmap.tcl.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    set red 0
    set green 0
    set blue 0
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 8} {incr x} {
	    frame $w.f$x,$y -width 40 -height 40 -bd 2 -relief raised \
		    -bg [format #%02x%02x%02x $red $green $blue]
	    place $w.f$x,$y -x [expr {40*$x}] -y [expr {40*$y}]
	    incr red $redInc
	    incr green $greenInc
	    incr blue $blueInc
	}
    }
}








|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    set red 0
    set green 0
    set blue 0
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 8} {incr x} {
	    frame $w.f$x,$y -width 40 -height 40 -bd 2 -relief raised \
		    -bg [format #%02x%02x%02x $red $green $blue]
	    place $w.f$x,$y -x [expr 40*$x] -y [expr 40*$y]
	    incr red $redInc
	    incr green $greenInc
	    incr blue $blueInc
	}
    }
}

Changes to tests/cmds.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# This file is a Tcl script to test the procedures in the file
# tkCmds.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

update

test cmds-1.1 {tkwait visibility, argument errors} -body {
    tkwait visibility
} -returnCodes {error} -result {wrong # args: should be "tkwait variable|visibility|window name"}
test cmds-1.2 {tkwait visibility, argument errors} -body {
    tkwait visibility foo bar
} -returnCodes {error} -result {wrong # args: should be "tkwait variable|visibility|window name"}
test cmds-1.3 {tkwait visibility, argument errors} -body {
    tkwait visibility bad_window
} -returnCodes {error} -result {bad window path name "bad_window"}
test cmds-1.4 {tkwait visibility, waiting for window to be mapped} -setup {
    button .b -text "Test"
    set x init
} -body {
    after 100 {set x delay; place .b -x 0 -y 0}
    tkwait visibility .b
    return $x
} -cleanup {
    destroy .b

} -result {delay}
test cmds-1.5 {tkwait visibility, window gets deleted} -setup {
    frame .f
    button .f.b -text "Test"
    pack .f.b
    set x init
} -body {
    after 100 {set x deleted; destroy .f}
    tkwait visibility .f.b
} -returnCodes {error} -result {window ".f.b" was deleted before its visibility changed}
test cmds-1.6 {tkwait visibility, window gets deleted} -setup {
    frame .f
    button .f.b -text "Test"
    pack .f.b
    set x init
} -body {
    after 100 {set x deleted; destroy .f}
    catch {tkwait visibility .f.b}
    return $x
} -cleanup {
    destroy .f
} -result {deleted}


# cleanup
cleanupTests
return




|
|





<



|
|
|
|
|
|
|
|
|
|


<


<
<

>
|
|




<

|
|
<
<
<
<
<
<
<
<
<
<
<
<

<



<
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27


28
29
30
31
32
33
34
35

36
37
38












39

40
41
42

# This file is a Tcl script to test the procedures in the file
# tkCmds.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


update

test cmds-1.1 {tkwait visibility, argument errors} {
    list [catch {tkwait visibility} msg] $msg
} {1 {wrong # args: should be "tkwait variable|visibility|window name"}}
test cmds-1.2 {tkwait visibility, argument errors} {
    list [catch {tkwait visibility foo bar} msg] $msg
} {1 {wrong # args: should be "tkwait variable|visibility|window name"}}
test cmds-1.3 {tkwait visibility, argument errors} {
    list [catch {tkwait visibility bad_window} msg] $msg
} {1 {bad window path name "bad_window"}}
test cmds-1.4 {tkwait visibility, waiting for window to be mapped} {
    button .b -text "Test"
    set x init

    after 100 {set x delay; place .b -x 0 -y 0}
    tkwait visibility .b


    destroy .b
    set x
} {delay}
test cmds-1.5 {tkwait visibility, window gets deleted} {
    frame .f
    button .f.b -text "Test"
    pack .f.b
    set x init

    after 100 {set x deleted; destroy .f}
    list [catch {tkwait visibility .f.b} msg] $msg $x
} {1 {window ".f.b" was deleted before its visibility changed} deleted}














# cleanup
cleanupTests
return

Changes to tests/color.test.

1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
# This file is a Tcl script to test out the procedures in the file
# tkColor.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



# cname --
# Returns a proper name for a color, given its intensities.
#
# Arguments:
# r, g, b -	Intensities on a 0-255 scale.




|
|





>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# This file is a Tcl script to test out the procedures in the file
# tkColor.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# cname --
# Returns a proper name for a color, given its intensities.
#
# Arguments:
# r, g, b -	Intensities on a 0-255 scale.

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    button .b2 -foreground $x -text Third
    pack .b2 -side top
    lappend result [testcolor purple]
} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}
test color-1.5 {Color table} nonPortable {
    set fd [open ../xlib/rgb.txt]
    set result {}
    while {[gets $fd line] >= 0} {
    	if {[string index $line 0] == "!"} continue
	set rgb [c255 [winfo rgb . [lrange $line 3 end]]]
	if {$rgb != [lrange $line 0 2] } {
		append result $line\n
	}

    }







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    button .b2 -foreground $x -text Third
    pack .b2 -side top
    lappend result [testcolor purple]
} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}
test color-1.5 {Color table} nonPortable {
    set fd [open ../xlib/rgb.txt]
    set result {}
    while {[gets $fd line] != -1} {
    	if {[string index $line 0] == "!"} continue
	set rgb [c255 [winfo rgb . [lrange $line 3 end]]]
	if {$rgb != [lrange $line 0 2] } {
		append result $line\n
	}

    }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    lappend result [testcolor purple]
    destroy .t3
    lappend result [testcolor purple]
    destroy .t
    lappend result [testcolor purple]
} {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test color-4.1 {FreeColorObjProc} -constraints {
    colorsFree
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    destroy .b
    set x [copy purple]
    button .b -foreground $x -text .b1
    set y [copy purple]
    .b configure -foreground $y
    set z [copy purple]
    .b configure -foreground $z
    set result {}
    lappend result [testcolor purple]
    set x red
    lappend result [testcolor purple]
    set z 32
    lappend result [testcolor purple]
    destroy .b
    lappend result [testcolor purple]
    set y bogus
    set result
} -cleanup {
    rename copy {}
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

destroy .t

# cleanup
cleanupTests
return







|
<
<
<
<

|

|

|











<
<
|






275
276
277
278
279
280
281
282




283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303
304
305
306
    lappend result [testcolor purple]
    destroy .t3
    lappend result [testcolor purple]
    destroy .t
    lappend result [testcolor purple]
} {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test color-4.1 {FreeColorObjProc} {colorsFree failsOnQuarz} {




    destroy .b
    set x [format purple]
    button .b -foreground $x -text .b1
    set y [format purple]
    .b configure -foreground $y
    set z [format purple]
    .b configure -foreground $z
    set result {}
    lappend result [testcolor purple]
    set x red
    lappend result [testcolor purple]
    set z 32
    lappend result [testcolor purple]
    destroy .b
    lappend result [testcolor purple]
    set y bogus
    set result


} {{{1 3}} {{1 2}} {{1 1}} {}}

destroy .t

# cleanup
cleanupTests
return

Changes to tests/config.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221








222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

507
508
509
510
511

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

601
602


603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644

645
646

647

648


649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883

884
885
886
887
888
889
890

891

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977

978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096

1097
1098

1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360

1361


1362


1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410


1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561

1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585

1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748

1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
# This file is a Tcl script to test the procedures in tkConfig.c,
# which comprise the new new option configuration system.  It is
# organized in the standard "white-box" fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

proc killTables {} {
    # Note: it's important to delete chain2 before chain1, because
    # chain2 depends on chain1.  If chain1 is deleted first, the
    # delete of chain2 will crash.
    deleteWindows
    foreach t {alltypes chain3 chain2 chain1 configerror internal
	    new notenoughparams twowindows} {
	    while {[testobjconfig info $t] != ""} {
	        testobjconfig delete $t
	    }
    }
}


option clear
deleteWindows
if {[testConstraint testobjconfig]} {
    killTables
}

test config-1.1 {Tk_CreateOptionTable - reference counts} -constraints {
	testobjconfig
} -body {
    set x {}
    testobjconfig alltypes .a
    lappend x [testobjconfig info alltypes]
    testobjconfig alltypes .b
    lappend x [testobjconfig info alltypes]

    set x
} -cleanup {
    killTables
} -result {{1 16 -boolean} {2 16 -boolean}}
test config-1.2 {Tk_CreateOptionTable - synonym initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a -synonym green
    .a cget -color
} -cleanup {
    killTables
} -result {green}
test config-1.3 {Tk_CreateOptionTable - option database initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    option add *b.string different
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]
} -cleanup {
    killTables
    option clear
} -result {foo different}
test config-1.4 {Tk_CreateOptionTable - option database initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    option add *b.String bar
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]
} -cleanup {
    killTables
    option clear
} -result {foo bar}
test config-1.5 {Tk_CreateOptionTable - default initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -relief
} -cleanup {
    killTables
} -result {raised}
test config-1.6 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig info chain2
} -cleanup {
    killTables
} -result {1 4 -three 2 2 -one}
test config-1.7 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .b
    testobjconfig chain1 .a
    testobjconfig info chain2
} -cleanup {
    killTables
} -result {1 4 -three 2 2 -one}
test config-1.8 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    .a cget -four
} -cleanup {
    killTables
} -returnCodes error -result {unknown option "-four"}
test config-1.9 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    catch {.a cget -four}
    list [.a cget -one] [.b cget -four] [.b cget -one]
} -cleanup {
    killTables
} -result {one four one}


test config-2.1 {Tk_DeleteOptionTable - reference counts} -constraints {
    testobjconfig
} -body {
    set x {}
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig chain3 .c
    deleteWindows

    testobjconfig delete chain3
    lappend x [testobjconfig info chain2] [testobjconfig info chain1]
    testobjconfig delete chain2
    lappend x [testobjconfig info chain2] [testobjconfig info chain1]
} -cleanup {
    killTables
} -result {{3 4 -three 2 2 -one} {2 2 -one} {} {2 2 -one}}

# No tests for DestroyOptionHashTable; couldn't figure out how to test.



test config-3.1 {Tk_InitOptions - priority of chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    list [.a cget -two] [.b cget -two]
} -cleanup {
    killTables
} -result {two {two and a half}}
test config-3.2 {Tk_InitOptions - initialize from database} -constraints {
    testobjconfig
} -body {
    option add *a.color blue
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
    option clear
} -result {blue}
test config-3.3 {Tk_InitOptions - initialize from database} -constraints {
    testobjconfig
} -body {
    option add *a.justify bogus
    testobjconfig alltypes .a
    list [.a cget -justify]
} -cleanup {
    killTables
    option clear
} -result {left}
test config-3.4 {Tk_InitOptions - initialize from widget class} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
} -result {red}
test config-3.5 {Tk_InitOptions - no initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -anchor
} -cleanup {
    killTables
} -result {}
test config-3.6 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    option add *a.color non-existent
    testobjconfig alltypes .a
} -cleanup {
    killTables
    option clear
} -returnCodes error -result {unknown color name "non-existent"}
test config-3.7 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    option add *a.color non-existent
    catch {testobjconfig alltypes .a}
    return $errorInfo
} -cleanup {
    killTables
    option clear
} -result {unknown color name "non-existent"
    (database entry for "-color" in widget ".a")
    invoked from within
"testobjconfig alltypes .a"}

test config-3.8 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig configerror
} -returnCodes error -result {expected integer but got "bogus"}
test config-3.9 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    catch {testobjconfig configerror}
    return $errorInfo
} -result {expected integer but got "bogus"
    (default value for "-int")
    invoked from within








"testobjconfig configerror"}


test config-4.1 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.2 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables
} -returnCodes ok -result 0
test config-4.3 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
    .foo cget -boolean
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.4 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.5 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
    .foo cget -boolean
} -cleanup {
    killTables
} -returnCodes ok -result 1
test config-4.6 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
    .foo cget -boolean
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.7 {DoObjConfig - invalid boolean} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean {}
} -cleanup {
    killTables
} -returnCodes error -result {expected boolean value but got ""}
test config-4.8 {DoObjConfig - boolean internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables
} -result 0

test config-4.9 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.10 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
    .foo cget -integer
} -cleanup {
    killTables
} -returnCodes ok -result 3
test config-4.11 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
    .foo cget -integer
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.12 {DoObjConfig - invalid integer} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer bar
} -cleanup {
    killTables
} -cleanup {
    killTables
} -returnCodes error -result {expected integer but got "bar"}
test config-4.13 {DoObjConfig - integer internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -integer 421
    .foo cget -integer
} -cleanup {
    killTables
} -result 421

test config-4.14 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.15 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
} -cleanup {
    killTables
} -returnCodes ok -result {3.14}
test config-4.16 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.17 {DoObjConfig - invalid double} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double bar
} -cleanup {
    killTables
} -returnCodes error -result {expected floating-point number but got "bar"}
test config-4.18 {DoObjConfig - double internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -double 62.75
    .foo cget -double
} -cleanup {
    killTables
} -result {62.75}

test config-4.19 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.20 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
} -cleanup {
    killTables
} -returnCodes ok -result {test}
test config-4.21 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.22 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.23 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
    .foo cget -string
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.24 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
    .foo cget -string
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok

test config-4.25 {DoObjConfig - string internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -string "this is a test"
    .foo cget -string
} -cleanup {
    killTables
} -result {this is a test}

test config-4.26 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two

} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.27 {DoObjConfig - string table} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result {two}
test config-4.28 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.29 {DoObjConfig - invalid string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable foo
} -cleanup {
    killTables
} -returnCodes error -result {bad stringtable "foo": must be one, two, three, or four}

test config-4.30 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
} -cleanup {
    killTables
} -returnCodes ok -result 16
test config-4.31 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result {three}
test config-4.32 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.33 {DoObjConfig - stringtable internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -stringtable "four"
    .foo cget -stringtable
} -cleanup {
    killTables
} -result {four}

test config-4.34 {DoObjConfig - color} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -color blue
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.35 {DoObjConfig - color} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -color blue
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {blue}
test config-4.36 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
    .foo cget -color
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.37 {DoObjConfig - invalid color} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color xxx
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name "xxx"}
test config-4.38 {DoObjConfig - color internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -color purple
    .foo cget -color
} -cleanup {
    killTables
} -result {purple}

test config-4.39 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.40 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.41 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
    .foo cget -color
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.42 {DoObjConfig - getting rid of old color} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color #333333
    .foo configure -color #444444
} -cleanup {
    killTables
} -returnCodes ok -result 32
test config-4.43 {DoObjConfig - getting rid of old color} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color #333333
    .foo configure -color #444444
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {#444444}
test config-4.44 {DoObjConfig - getting rid of old color} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color #333333
    .foo configure -color #444444
    .foo cget -color
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok

test config-4.45 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.46 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
    .foo cget -font
} -cleanup {

    killTables
} -returnCodes ok -result {Helvetica 72}


test config-4.47 {DoObjConfig - new font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Courier 12}
    .foo configure -font {Helvetica 72}
} -cleanup {
    killTables
} -returnCodes ok -result 64
test config-4.48 {DoObjConfig - new font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Courier 12}
    .foo configure -font {Helvetica 72}
    .foo cget -font
} -cleanup {
    killTables
} -returnCodes ok -result {Helvetica 72}
test config-4.49 {DoObjConfig - invalid font} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 12 foo}
} -cleanup {
    killTables
} -returnCodes error -result {unknown font style "foo"}
test config-4.50 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}

} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.51 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}
    .foo cget -font
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.52 {DoObjConfig - font internal value} -constraints {

    testobjconfig
} -setup {

    catch {rename .foo {}}

} -body {


    testobjconfig internal .foo -font {Times 16}
    .foo cget -font
} -cleanup {
    killTables
} -result {Times 16}

test config-4.53 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.54 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray75}
test config-4.55 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
} -cleanup {
    killTables
} -returnCodes ok -result 128
test config-4.56 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray50}
test config-4.57 {DoObjConfig - invalid bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -bitmap foobar
} -cleanup {
    killTables
} -returnCodes error -result {bitmap "foobar" not defined}
test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.59 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.60 {DoObjConfig - bitmap internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -bitmap gray25
    .foo cget -bitmap
} -cleanup {
    killTables
} -result {gray25}

test config-4.61 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.62 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {green}
test config-4.63 {DoObjConfig - invalid border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -border xxx
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name "xxx"}

test config-4.64 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.65 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.66 {DoObjConfig - border internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -border #123456
    .foo cget -border
} -cleanup {
    killTables
} -result {#123456}
test config-4.67 {DoObjConfig - getting rid of old border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -border #333333
    .foo configure -border #444444
} -cleanup {
    killTables
} -returnCodes ok -result 256
test config-4.68 {DoObjConfig - getting rid of old border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -border #333333
    .foo configure -border #444444
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {#444444}

test config-4.69 {DoObjConfig - relief} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.70 {DoObjConfig - relief} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result {flat}
test config-4.71 {DoObjConfig - invalid relief} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -relief foo
} -cleanup {
    killTables
} -returnCodes error -result {bad relief "foo": must be flat, groove, raised, ridge, solid, or sunken}
test config-4.72 {DoObjConfig - relief internal value} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -relief ridge
    .foo cget -relief
} -cleanup {
    killTables
} -result {ridge}
test config-4.73 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result 512
test config-4.74 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result {flat}

test config-4.75 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.76 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {arrow}
test config-4.77 {DoObjConfig - invalid cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad cursor spec "foo"}
test config-4.78 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.79 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {}

test config-4.80 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result 1024
test config-4.81 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {arrow}
test config-4.82 {DoObjConfig - cursor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -cursor watch
    .foo cget -cursor
} -cleanup {
    killTables
} -result {watch}

test config-4.83 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.84 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result {center}
test config-4.85 {DoObjConfig - invalid justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify foo
} -cleanup {
    killTables
} -returnCodes error -result {bad justification "foo": must be left, right, or center}
test config-4.86 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left
    .foo configure -justify right
} -cleanup {
    killTables
} -returnCodes ok -result 2048
test config-4.87 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left

    .foo configure -justify right
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result {right}
test config-4.88 {DoObjConfig - justify internal value} -constraints {
    testobjconfig

} -setup {

    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -result {center}

test config-4.89 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.90 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result {center}
test config-4.91 {DoObjConfig - invalid anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad anchor "foo": must be n, ne, e, se, s, sw, w, nw, or center}
test config-4.92 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
} -cleanup {
    killTables
} -returnCodes ok -result 4096
test config-4.93 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result {n}
test config-4.94 {DoObjConfig - anchor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -anchor sw
    .foo cget -anchor
} -cleanup {
    killTables
} -result {sw}
test config-4.95 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.96 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result 42
test config-4.97 {DoObjConfig - invalid pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel foo
} -cleanup {
    killTables
} -returnCodes error -result {bad screen distance "foo"}
test config-4.98 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
} -cleanup {
    killTables
} -returnCodes ok -result 8192
test config-4.99 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result {3c}
test config-4.100 {DoObjConfig - pixel internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -pixel [winfo screenmmwidth .]m
    set screenW [winfo screenwidth .]
    set result [.foo cget -pixel]
    expr {$screenW eq $result}
} -cleanup {

    killTables
} -result 1

test config-4.101 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.102 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {.bar}
test config-4.103 {DoObjConfig - invalid window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window foo
} -cleanup {
    killTables
} -returnCodes error -result {bad window path name "foo"}
test config-4.104 {DoObjConfig - null window} -constraints testobjconfig -body {

    toplevel .bar
    testobjconfig twowindows .foo -window {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.105 {DoObjConfig - null window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window {}
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.106 {DoObjConfig - new window} -constraints testobjconfig -body {

    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    .foo configure -window .blamph
} -cleanup {
    killTables
} -returnCodes ok -result 0
test config-4.107 {DoObjConfig - new window} -constraints testobjconfig -body {
    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    .foo configure -window .blamph
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {.blamph}
test config-4.108 {DoObjConfig - window internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -window .
    .foo cget -window
} -cleanup {
    killTables
} -result {.}

test config-4.109 {DoObjConfig - releasing old values} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    # This test doesn't generate a useful value to check; if an
    # error occurs, it will be detected only by memory checking software
    # such as Purify or Tcl's built-in checker.


    testobjconfig alltypes .foo -string {Test string} -color yellow \
	    -font {Courier 18} -bitmap questhead -border green -cursor cross \
	    -custom foobar
    .foo configure -string {new string} -color brown \
	    -font {Times 8} -bitmap gray75 -border pink -cursor watch \
	    -custom barbaz
    concat {}
} -cleanup {
    killTables
} -result {}
test config-4.110 {DoObjConfig - releasing old values} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    # This test doesn't generate a useful value to check; if an
    # error occurs, it will be detected only by memory checking software
    # such as Purify or Tcl's built-in checker.


    testobjconfig internal .foo -string {Test string} -color yellow \
	    -font {Courier 18} -bitmap questhead -border green -cursor cross \
	    -custom foobar
    .foo configure -string {new string} -color brown \
	    -font {Times 8} -bitmap gray75 -border pink -cursor watch \
	    -custom barbaz
    concat {}
} -cleanup {
    killTables
} -result {}

test config-4.111 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.112 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
    .foo cget -custom
} -cleanup {
    killTables
} -returnCodes ok -result {TEST}
test config-4.113 {DoObjConfig - null custom} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -custom {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.114 {DoObjConfig - null custom} -constraints testobjconfig -body {

    testobjconfig alltypes .foo -custom {}
    .foo cget -custom

} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.115 {DoObjConfig - custom internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -custom "this is a test"
    .foo cget -custom
} -cleanup {

    killTables
}  -result {THIS IS A TEST}


test config-5.1 {ObjectIsEmpty - object is already string} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color [format ""]
    .foo cget -color
} -cleanup {
    killTables
}  -result {}

test config-5.2 {ObjectIsEmpty - object is already string} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color [format " "]
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name " "}
test config-5.3 {ObjectIsEmpty - must convert back to string} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -color [list]
    .foo cget -color
} -cleanup {
    killTables
} -result {}


test config-6.1 {GetOptionFromObj - cached answer} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    list [.a cget -three] [.a cget -three]
} -cleanup {
    killTables
} -result {three three}
test config-6.2 {GetOptionFromObj - exact match} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -one
} -cleanup {
    killTables
} -result {one}
test config-6.3 {GetOptionFromObj - abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -fo
} -cleanup {
    killTables
} -result {four}
test config-6.4 {GetOptionFromObj - ambiguous abbreviation} -constraints {
    testobjconfig

} -body {
    testobjconfig chain2 .a
    .a cget -on


} -cleanup {
    killTables
} -cleanup {
    killTables
} -returnCodes error -result {unknown option "-on"}
test config-6.5 {GetOptionFromObj - duplicate options in different tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -tw
} -cleanup {
    killTables
} -result {two and a half}
test config-6.6 {GetOptionFromObj - synonym} -constraints testobjconfig -body {
    testobjconfig alltypes .b
    .b cget -synonym
} -cleanup {
    killTables
} -result {red}


if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-7.1 {Tk_SetOptions - basics} -constraints testobjconfig -body {
    .a configure -color green -rel sunken
     list [.a cget -color] [.a cget -relief]
} -result {green sunken}
test config-7.2 {Tk_SetOptions - bogus option name} -constraints {
    testobjconfig
} -body {
    .a configure -bogus
} -returnCodes error -result {unknown option "-bogus"}
test config-7.3 {Tk_SetOptions - synonym} -constraints testobjconfig -body {
    .a configure -synonym blue
    .a cget -color
} -result {blue}
test config-7.4 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    .a configure -color green -relief
} -returnCodes error -result {value for "-relief" missing}
test config-7.5 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    catch {.a configure -color green -relief}
    .a cget -color
} -result {green}
test config-7.6 {Tk_SetOptions - saving old values} -constraints {
    testobjconfig
} -body {
    .a configure -color red -int 7 -relief raised -double 3.14159
    .a csave -color green -int 432 -relief sunken -double 2.0 -color bogus
} -returnCodes error -result {unknown color name "bogus"}
test config-7.7 {Tk_SetOptions - saving old values} -constraints {
    testobjconfig
} -body {
    .a configure -color red -int 7 -relief raised -double 3.14159
    catch {.a csave -color green -int 432 -relief sunken -double 2.0 -color bogus}
    list [.a cget -color] [.a cget -int] [.a cget -relief] [.a cget -double]
} -result {red 7 raised 3.14159}

test config-7.8 {Tk_SetOptions - error in DoObjConfig call} -constraints {
    testobjconfig
} -body {
    .a configure -color bogus
} -returnCodes error -result {unknown color name "bogus"}
test config-7.9 {Tk_SetOptions - error in DoObjConfig call} -constraints {
    testobjconfig
} -body {
    catch {.a configure -color bogus}
    return $errorInfo
} -result {unknown color name "bogus"
    (processing "-color" option)
    invoked from within
".a configure -color bogus"}

test config-7.10 {Tk_SetOptions - synonym name in error message} -constraints {
    testobjconfig
} -body {
    .a configure -synonym bogus
} -returnCodes error -result {unknown color name "bogus"}
test config-7.11 {Tk_SetOptions - synonym name in error message} -constraints {
    testobjconfig
} -body {
    catch {.a configure -synonym bogus}
    return $errorInfo
} -result {unknown color name "bogus"
    (processing "-synonym" option)
    invoked from within
".a configure -synonym bogus"}
test config-7.12 {Tk_SetOptions - returning mask} -constraints testobjconfig -body {
    format %x [.a configure -color red -int 7 -relief raised -double 3.14159]
} -result 226
test config-7.13 {Tk_SetOptions - error in DoObjConfig with custom option} -constraints {
    testobjconfig
} -body {
    .a configure -custom bad
} -returnCodes error -result {expected good value, got "BAD"}
test config-7.14 {Tk_SetOptions - error in DoObjConfig with custom option} -constraints {
    testobjconfig
} -body {
    catch {.a configure -custom bad}
    return $errorInfo
} -result {expected good value, got "BAD"
    (processing "-custom" option)
    invoked from within
".a configure -custom bad"}
if {[testConstraint testobjconfig]} {
    killTables
}


test config-8.1 {Tk_RestoreSavedOptions - restore in proper order} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a csave -color green -color black -color blue \
        -color #ffff00 -color #ff00ff -color bogus \
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name "bogus"}
test config-8.2 {Tk_RestoreSavedOptions - restore in proper order} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    catch {.a csave -color green -color black -color blue \
	    -color #ffff00 -color #ff00ff -color bogus}
	.a cget -color
} -cleanup {
    killTables
} -result {red}
test config-8.3 {Tk_RestoreSavedOptions - freeing object memory} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a csave -color green -color black -color blue -color #ffff00 -color #ff00ff
} -cleanup {
    killTables
} -result 32
test config-8.4 {Tk_RestoreSavedOptions - boolean internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    .a csave -boolean 0 -color bogus
} -cleanup {
    killTables
} -returnCodes error -match glob -result *
test config-8.5 {Tk_RestoreSavedOptions - boolean internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -boolean 0 -color bogus}
    .a cget -boolean
} -cleanup {
    killTables
} -result 1
test config-8.6 {Tk_RestoreSavedOptions - integer internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    .a csave -integer 24 -color bogus
} -cleanup {
    killTables
} -returnCodes error -match glob -result *
test config-8.7 {Tk_RestoreSavedOptions - integer internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -integer 24 -color bogus}
    .a cget -integer
} -cleanup {
    killTables
} -result 148962237
test config-8.8 {Tk_RestoreSavedOptions - double internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -double 62.4 -color bogus}
    .a cget -double
} -cleanup {
    killTables
} -result {3.14159}
test config-8.9 {Tk_RestoreSavedOptions - string internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -string "A long string" -color bogus}
	.a cget -string
} -cleanup {
    killTables
} -result {foo}
test config-8.10 {Tk_RestoreSavedOptions - string table internal form} -constraints {

    testobjconfig


} -body {


    testobjconfig internal .a
    catch {.a csave -stringtable three -color bogus}
	.a cget -stringtable
} -cleanup {
    killTables
} -result {one}
test config-8.11 {Tk_RestoreSavedOptions - color internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -color green -color bogus}
    .a cget -color
} -cleanup {
    killTables
} -result {red}
test config-8.12 {Tk_RestoreSavedOptions - font internal form} -constraints {
    testobjconfig nonPortable
} -body {
    testobjconfig internal .a
    catch {.a csave -font {Times 12} -color bogus}
    .a cget -font
} -cleanup {
    killTables
} -result {Helvetica 12}
test config-8.13 {Tk_RestoreSavedOptions - bitmap internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -bitmap questhead -color bogus}
    .a cget -bitmap
} -cleanup {
    killTables
} -result {gray50}
test config-8.14 {Tk_RestoreSavedOptions - border internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -border brown -color bogus}
    .a cget -border
} -cleanup {
    killTables
} -result {blue}
test config-8.15 {Tk_RestoreSavedOptions - relief internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -relief sunken -color bogus}
    .a cget -relief


} -cleanup {
    killTables
} -result {raised}
test config-8.16 {Tk_RestoreSavedOptions - cursor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -cursor watch -color bogus}
    .a cget -cursor
} -cleanup {
    killTables
} -result {xterm}
test config-8.17 {Tk_RestoreSavedOptions - justify internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -justify right -color bogus}
    .a cget -justify
} -cleanup {
    killTables
} -result {left}
test config-8.18 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -anchor center -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result {n}
test config-8.19 {Tk_RestoreSavedOptions - window internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -window .a
    catch {.a csave -window .a -color bogus}
    .a cget -window
} -cleanup {
    killTables
} -result {.a}
test config-8.20 {Tk_RestoreSavedOptions - custom internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -custom "foobar"
    catch {.a csave -custom "barbaz" -color bogus}
    .a cget -custom
} -cleanup {
    killTables
} -result {FOOBAR}

# Most of the tests below will cause memory leakage if there is a
# problem.  This may not be evident unless the tests are run in
# conjunction with a memory usage analyzer such as Purify.

test config-9.1 {Tk_FreeConfigOptions/FreeResources - string internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -string "two words"
    destroy .foo
} -result {}
test config-9.2 {Tk_FreeConfigOptions/FreeResources - color internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -color yellow
    destroy .foo
} -result {}
test config-9.3 {Tk_FreeConfigOptions/FreeResources - color} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -color [format blue]
    destroy .foo
} -result {}
test config-9.4 {Tk_FreeConfigOptions/FreeResources - font internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -font {Courier 20}
    destroy .foo
} -result {}
test config-9.5 {Tk_FreeConfigOptions/FreeResources - font} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -font [format {Courier 24}]
    destroy .foo
} -result {}
test config-9.6 {Tk_FreeConfigOptions/FreeResources - bitmap internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -bitmap gray75
    destroy .foo
} -result {}
test config-9.7 {Tk_FreeConfigOptions/FreeResources - bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -bitmap [format gray75]
    destroy .foo
} -result {}
test config-9.8 {Tk_FreeConfigOptions/FreeResources - border internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -border orange
    destroy .foo
} -result {}
test config-9.9 {Tk_FreeConfigOptions/FreeResources - border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -border [format blue]
    destroy .foo
} -result {}
test config-9.10 {Tk_FreeConfigOptions/FreeResources - cursor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .foo
    .foo configure -cursor cross
    destroy .foo
} -result {}
test config-9.11 {Tk_FreeConfigOptions/FreeResources - cursor} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -cursor [format watch]
    destroy .foo
} -result {}
test config-9.12 {Tk_FreeConfigOptions/FreeResources - not special} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -integer [format 27]
    destroy .foo
} -result {}
test config-9.13 {Tk_FreeConfigOptions/FreeResources - custom internal form} -constraints {
    testobjconfig
} -body {
    catch {destroy .fpp}
    testobjconfig internal .foo
    .foo configure -custom "foobar"
    destroy .foo
} -result {}
if {[testConstraint testobjconfig]} {
    killTables
}


test config-10.1 {Tk_GetOptionInfo - one item} -constraints testobjconfig -body {

    testobjconfig alltypes .foo
    .foo configure -relief groove
    .foo configure -relief
} -cleanup {
    destroy .foo
} -result {-relief relief Relief raised groove}
test config-10.2 {Tk_GetOptionInfo - one item, synonym} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -color black
    .foo configure -synonym
} -cleanup {
    destroy .foo
} -result {-color color Color red black}
test config-10.3 {Tk_GetOptionInfo - all items} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -font {Helvetica 18} -integer 13563
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-boolean boolean Boolean 1 1} {-integer integer Integer 7 13563} {-double double Double 3.14159 3.14159} {-string string String foo foo} {-stringtable StringTable stringTable one one} {-color color Color red red} {-font font Font {Helvetica 12} {Helvetica 18}} {-bitmap bitmap Bitmap gray50 gray50} {-border border Border blue blue} {-relief relief Relief raised raised} {-cursor cursor Cursor xterm xterm} {-justify {} {} left left} {-anchor anchor Anchor {} {}} {-pixel pixel Pixel 1 1} {-custom {} {} {} {}} {-synonym -color}}
test config-10.4 {Tk_GetOptionInfo - chaining through tables} -constraints testobjconfig -body {

    testobjconfig chain2 .foo -one asdf -three xyzzy
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-three three Three three xyzzy} {-four four Four four four} {-two two Two {two and a half} {two and a half}} {-oneAgain oneAgain OneAgain {one again} {one again}} {-one one One one asdf} {-two two Two two {two and a half}}}
if {[testConstraint testobjconfig]} {
    killTables
}


if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-11.1 {GetConfigList - synonym} -constraints testobjconfig -body {
    lindex [.a configure] end
} -result {-synonym -color}
test config-11.2 {GetConfigList - null database names} -constraints {
    testobjconfig
} -body {
    .a configure -justify
} -result {-justify {} {} left left}
test config-11.3 {GetConfigList - null default and current value} -constraints {
    testobjconfig
} -body {
    .a configure -anchor
} -result {-anchor anchor Anchor {} {}}
if {[testConstraint testobjconfig]} {
    killTables
}


if {[testConstraint testobjconfig]} {
    testobjconfig internal .a
}
test config-12.1 {GetObjectForOption - boolean} -constraints testobjconfig -body {
    .a configure -boolean 0
    .a cget -boolean
} -result 0
test config-12.2 {GetObjectForOption - integer} -constraints testobjconfig -body {
    .a configure -integer 1247
    .a cget -integer
} -result 1247
test config-12.3 {GetObjectForOption - double} -constraints testobjconfig -body {
    .a configure -double -88.82
    .a cget -double
} -result {-88.82}
test config-12.4 {GetObjectForOption - string} -constraints testobjconfig -body {
    .a configure -string "test value"
    .a cget -string
} -result {test value}
test config-12.5 {GetObjectForOption - stringTable} -constraints {
    testobjconfig
} -body {
    .a configure -stringtable "two"
    .a cget -stringtable
} -result {two}
test config-12.6 {GetObjectForOption - color} -constraints testobjconfig -body {
    .a configure -color "green"
    .a cget -color
} -result {green}
test config-12.7 {GetObjectForOption - font} -constraints testobjconfig -body {
    .a configure -font {Times 36}
    .a cget -font
} -result {Times 36}
test config-12.8 {GetObjectForOption - bitmap} -constraints testobjconfig -body {
    .a configure -bitmap "questhead"
    .a cget -bitmap
} -result {questhead}
test config-12.9 {GetObjectForOption - border} -constraints testobjconfig -body {
    .a configure -border #33217c
    .a cget -border
} -result {#33217c}
test config-12.10 {GetObjectForOption - relief} -constraints {
    testobjconfig
} -body {
    .a configure -relief groove
    .a cget -relief
} -result {groove}
test config-12.11 {GetObjectForOption - cursor} -constraints {
    testobjconfig
} -body {
    .a configure -cursor watch
    .a cget -cursor
} -result {watch}
test config-12.12 {GetObjectForOption - justify} -constraints {
    testobjconfig
} -body {
    .a configure -justify right
    .a cget -justify
} -result {right}
test config-12.13 {GetObjectForOption - anchor} -constraints testobjconfig -body {
    .a configure -anchor e
    .a cget -anchor
} -result {e}
test config-12.14 {GetObjectForOption - pixels} -constraints testobjconfig -body {
    .a configure -pixel 193.2
    .a cget -pixel
} -result 193
test config-12.15 {GetObjectForOption - window} -constraints testobjconfig -body {
    .a configure -window .a
    .a cget -window
} -result {.a}
test config-12.16 {GetObjectForOption -custom} -constraints testobjconfig -body {
    .a configure -custom foobar
    .a cget -custom
} -result {FOOBAR}
test config-12.17 {GetObjectForOption - null values} -constraints {
    testobjconfig
} -body {
    .a configure -string {} -color {} -font {} -bitmap {} -border {} \
	    -cursor {} -window {} -custom {}
    list [.a cget -string] [.a cget -color] [.a cget -font] \
	    [.a cget -bitmap] [.a cget -border] [.a cget -cursor] \
	    [.a cget -window] [.a cget -custom]
} -result {{} {} {} {} {} {} {} {}}
if {[testConstraint testobjconfig]} {
    killTables
}


test config-13.1 {proper cleanup of options with widget destroy} -body {
    button .w -cursor crosshair
    destroy .w
} -result {}
test config-13.2 {proper cleanup of options with widget destroy} -body {
    canvas .w -cursor crosshair
    destroy .w
} -result {}
test config-13.3 {proper cleanup of options with widget destroy} -body {
    entry .w -cursor crosshair
    destroy .w
} -result {}
test config-13.4 {proper cleanup of options with widget destroy} -body {
    frame .w -cursor crosshair
    destroy .w
} -result {}
test config-13.5 {proper cleanup of options with widget destroy} -body {
    listbox .w -cursor crosshair
    destroy .w
} -result {}
test config-13.6 {proper cleanup of options with widget destroy} -body {
    menu .w -cursor crosshair
    destroy .w
} -result {}
test config-13.7 {proper cleanup of options with widget destroy} -body {
    menubutton .w -cursor crosshair
    destroy .w
} -result {}
test config-13.8 {proper cleanup of options with widget destroy} -body {
    message .w -cursor crosshair
    destroy .w
} -result {}
test config-13.9 {proper cleanup of options with widget destroy} -body {
    scale .w -cursor crosshair
    destroy .w
} -result {}
test config-13.10 {proper cleanup of options with widget destroy} -body {
    scrollbar .w -cursor crosshair
    destroy .w
} -result {}
test config-13.11 {proper cleanup of options with widget destroy} -body {
    text .w -cursor crosshair
    destroy .w

} -result {}
test config-13.12 {proper cleanup of options with widget destroy} -body {
    radiobutton .w -cursor crosshair
    destroy .w
} -result {}
test config-13.13 {proper cleanup of options with widget destroy} -body {
    checkbutton .w -cursor crosshair
    destroy .w
} -result {}

test config-14.1 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::button
        ::foo::button .a
        ::foo::button .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.2 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::canvas
        ::foo::canvas .a
        ::foo::canvas .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.3 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::entry
        ::foo::entry .a
        ::foo::entry .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.4 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::frame
        ::foo::frame .a
        ::foo::frame .b

        }
    ]
    destroy .a .b
} -result {}
test config-14.5 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::listbox
        ::foo::listbox .a
        ::foo::listbox .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.6 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::menu
        ::foo::menu .a
        ::foo::menu .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.7 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::menubutton
        ::foo::menubutton .a
        ::foo::menubutton .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.8 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::message
        ::foo::message .a
        ::foo::message .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.9 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::scale
        ::foo::scale .a
        ::foo::scale .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.10 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::scrollbar
        ::foo::scrollbar .a
        ::foo::scrollbar .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.11 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::spinbox
        ::foo::spinbox .a
        ::foo::spinbox .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.12 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::text
        ::foo::text .a
        ::foo::text .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.13 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::radiobutton
        ::foo::radiobutton .a
        ::foo::radiobutton .b
        }
    ]
    destroy .a .b
} -result {}
test config-14.14 {Tk_CreateOptionTable - use with namespace import} -setup {
    namespace export -clear *
} -body {
    namespace eval ::foo [subst {
        namespace import -force ::checkbutton
        ::foo::checkbutton .a
        ::foo::checkbutton .b
        }
    ]
    destroy .a .b
} -result {}


# cleanup
deleteWindows
if {[testConstraint testobjconfig]} {
    killTables
}
cleanupTests
return












|
|



<







|
|
|
|
|
|



<
<
<




|
|
|





>

<
<
|
|
|
<


<
<
|
|
|
|




<
<
<
|
|
|
|




<
<
<
|
|
|
<


<
<
|
|
|
|



<
<
|
|
|
|



<
<
|
|
<
<
<
<
<
<
|
<
<
<
<


|
|
<
<
|

<
|
|
|
<


|

>
|



<
<
|
<
<

>
>
|
|
<



<
<
|
|
|
|



<
<
<
|
|
|
|



<
<
<
|
|
|
<


<
<
|
|
|
<


|
<
<
|
<
<
<
<
<
|

<
<
<
<

|
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>
>
>
>
>
>
>
>
|
>

|

<
|
<
<
|
|

<
|
|
<
<
<
|

<
|
|
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
|
|

<
|
<
<
|
|

<
|
|
<
<
<
|

<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<

<
|
<
<
|
|
<
<

<


<
<
|
<
|
|
<
|
<
<
|
|
|
<
|
|
<
<
<
|

<
|

<
<
<
<
<
<
|
<
<
<
<
|
|
<
|
|
<
<
<
|
|
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<

>
|
<
<
|
>
|

|
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
|
|
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
|
|
>
|
<
<
|
|
>
|
|
|
<
<
|
<
<
|
<
<
<
<
<
<
|
|
<
<
|
<
<

<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

<
|
<
<
|
|

<
|

|
>
|
<
>
>
|
|
<
|
|
|
<
<
|
|
<
|
<
|
<
<
<
|
<
<
|
<
|
|
<
<
|

<
|
>
|
<
<
|

<
|
|
<
<
<
|
>
|
|
>

>
|
>
>
|
|
<
<
<
|
|
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|
<
|
<
|
<
<
|
|
<
|
<
<
<
>
|
<
<
<
|
<
|
|
<
<
|
|
<
<

<
|
|
|
<
<
|
|
<
|
|
<
<
<
|
|
<
|
<
<
<
<
<
|
|
>
|
<
<
|
|
>
|
|
|
<
<
|
<
<
<
<
<
<
<

<
|
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
>
|
<
|
<
<
<
<
|
|
<
|
<
<
|
<
<

<
|
|
<
<
<
|
|
<
<
<
|
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
>
|
|
<
<
<
<
|
>
|
>

<
|
|
<
<
<
|
|
<
<
<
|
<
|
|
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<

|
<
<
|
<
<
<
<
<
<
<
|
<
<

<

<
|
|
<
>
|
<
|
<

|
<
<
|
|
<
<
|
<
<
<
<

|
<
<
|
|
>
|
<
<
<
<
<

|
|
<
<
<
|
>
|
|
<
<
<
<
<
<



|
<
<
<
|
|
<
<

<


<
<
|
<
|
<
<
<
<




>







|
<
<
|
<
<
<
<




>







<
<
<
|
|
<
<
<
|
<
|
|
<
<
<
|
>
|
<
<
|
|
>
|

>
|
|
|
<
|
<
<
<
<
|
|
>
|
<
|
|
|
|
<
|

|
|
<
>
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<

<
<
|
|
<
<
<

<
<
|
|
<
<
<

<
<
|
|
<
>
|
|
|
>
>
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|



|


|
|
<
<
|
|
|


|
|
<
<
|
|
|
<
<
<
<
<
<
<
<

|
<
<
<
<
<
|
|
<
<
<
<
<
<
|
|
<
<
|
<
|


|
<
|
<
<
<
<
<
<
<
|
<
|


|
|

|
<
<
<
<
<
|
<
<
|
<
|


|
<
<
|
<
<
|
|
<

|
|
|
<
|
|
|
<

|
|
<
|
<
<
|
<
<
<
<
<
|
<
<
<
<

|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<

|
<
<
<
|
|
|
<

|
<
<
<
|
|
|
<

|
|
<
<
|
|
>
|
>
>
|
>
>

<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
|
<

|
<
<
<
|
|
|
<

|
<
<
<
|
|
|
<

|
<
<
<
|
|
|
<

|
<
>
>
<
|
<
<
<
<

|
<
<
<
|
|
|
<

|
<
<
<
|
|
|
<

|
<
|
<
<
|
|
<

|
<
|
<
<
|
|
<

|
<
<
<
|





|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
|
<



|
|
<
<




<
<
<
|

<
|
>



<
<
|
|
|
<



<
<
|
|
|
<


<
<
|
|
>


<
<
|
<
<
|
|
<



|

|
|
<
<

|
|
<
<

|
<
<
|
|
<



|


|
|


|
|


|
|


|
|
<
<


|
|


|
|


|
|


|
|


|
|
<
<


|
|
<
<


|
|
<
<


|
|


|
|


|
|


|
|


|
|
<
<





|
<
<
|
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
|
|
>
|
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
|

<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
>
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35
36
37
38
39


40
41
42

43
44


45
46
47
48
49
50
51
52



53
54
55
56
57
58
59
60



61
62
63

64
65


66
67
68
69
70
71
72


73
74
75
76
77
78
79


80
81






82




83
84
85
86


87
88

89
90
91

92
93
94
95
96
97
98
99
100


101


102
103
104
105
106

107
108
109


110
111
112
113
114
115
116



117
118
119
120
121
122
123



124
125
126

127
128


129
130
131

132
133
134


135





136
137




138
139




140
141















142
143
144
145
146
147
148
149
150
151
152
153
154
155

156


157
158
159

160
161



162
163

164
165




166
167























168













169



170
171
172

173


174
175
176

177
178



179
180

181
182

























183
184
185

186
















187



188


189

190


191
192


193

194
195


196

197
198

199


200
201
202

203
204



205
206

207
208






209




210
211

212
213



214
215

216





217
218









219

220
221
222


223
224
225
226
227


228


229






230



231
232
233

234






235






236





237








238
239



240
241
242
243


244
245
246
247
248
249


250


251






252
253


254


255








256





257

258

259


260






261























262
263
264

265


266
267
268

269
270
271
272
273

274
275
276
277

278
279
280


281
282

283

284



285


286

287
288


289
290

291
292
293


294
295

296
297



298
299
300
301
302
303
304
305
306
307
308
309



310
311



312

313






314






































315
316



317

318

319


320
321

322



323
324



325

326
327


328
329


330

331
332
333


334
335

336
337



338
339

340





341
342
343
344


345
346
347
348
349
350


351







352

353
354
355


356












357

358





359



360












361

362




363
364

365




366
367

368


369


370

371
372



373
374



375

376
377



378









379

380
381
382
383




384
385
386
387
388

389
390



391
392



393

394
395



396






397




398

399



400
















401









402
403


404







405


406

407

408
409

410
411

412

413
414


415
416


417




418
419


420
421
422
423





424
425
426



427
428
429
430






431
432
433
434



435
436


437

438
439


440

441




442
443
444
445
446
447
448
449
450
451
452
453
454


455




456
457
458
459
460
461
462
463
464
465
466
467



468
469



470

471
472



473
474
475


476
477
478
479
480
481
482
483
484

485




486
487
488
489

490
491
492
493

494
495
496
497

498
499
500

501











502

503



504


505
506



507


508
509



510


511
512

513
514
515
516
517
518
519

520
















521
522
523
524
525
526
527
528
529
530


531
532
533
534
535
536
537


538
539
540








541
542





543
544






545
546


547

548
549
550
551

552







553

554
555
556
557
558
559
560





561


562

563
564
565
566


567


568
569

570
571
572
573

574
575
576

577
578
579

580


581





582




583
584





585






586





587




588
589



590
591
592

593
594



595
596
597

598
599
600


601
602
603
604
605
606
607
608
609
610









611



612
613
614

615
616



617
618
619

620
621



622
623
624

625
626



627
628
629

630
631

632
633

634




635
636



637
638
639

640
641



642
643
644

645
646

647


648
649

650
651

652


653
654

655
656



657
658
659
660
661
662
663
664

665
666
667
668
669
670

671
672
673
674
675
676

677
678
679
680
681
682

683
684
685
686
687
688

689
690
691
692
693
694

695
696
697
698
699
700

701
702
703
704
705
706

707
708
709
710
711
712

713
714
715
716
717
718

719
720
721
722
723
724

725
726
727
728
729
730

731
732
733
734
735


736
737
738
739



740
741

742
743
744
745
746


747
748
749

750
751
752


753
754
755

756
757


758
759
760
761
762


763


764
765

766
767
768
769
770
771
772


773
774
775


776
777


778
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799


800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819


820
821
822
823


824
825
826
827


828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847


848
849
850
851
852
853


854


855


856





















857







858

859


860


861
862
863
864








865









866








867



868
869








870





871

872
873






874
875











876
877
878
879
880








881










882






































































883
884
885
886
887
888
889
890








# This file is a Tcl script to test the procedures in tkConfig.c,
# which comprise the new new option configuration system.  It is
# organized in the standard "white-box" fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

proc killTables {} {
    # Note: it's important to delete chain2 before chain1, because
    # chain2 depends on chain1.  If chain1 is deleted first, the
    # delete of chain2 will crash.

    foreach t {alltypes chain2 chain1 configerror internal new notenoughparams
	    twowindows} {
	while {[testobjconfig info $t] != ""} {
	    testobjconfig delete $t
	}
    }
}




if {[testConstraint testobjconfig]} {
    killTables
}

test config-1.1 {Tk_CreateOptionTable - reference counts} testobjconfig {
    deleteWindows
    killTables
    set x {}
    testobjconfig alltypes .a
    lappend x [testobjconfig info alltypes]
    testobjconfig alltypes .b
    lappend x [testobjconfig info alltypes]
    deleteWindows
    set x


} {{1 16 -boolean} {2 16 -boolean}}
test config-1.2 {Tk_CreateOptionTable - synonym initialization} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a -synonym green
    .a cget -color


} {green}
test config-1.3 {Tk_CreateOptionTable - option database initialization} testobjconfig {
    deleteWindows
    option clear
    testobjconfig alltypes .a
    option add *b.string different
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]



} {foo different}
test config-1.4 {Tk_CreateOptionTable - option database initialization} testobjconfig {
    deleteWindows
    option clear
    testobjconfig alltypes .a
    option add *b.String bar
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]



} {foo bar}
test config-1.5 {Tk_CreateOptionTable - default initialization} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a
    .a cget -relief


} {raised}
test config-1.6 {Tk_CreateOptionTable - chained tables} testobjconfig {
    deleteWindows
    killTables
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig info chain2


} {1 4 -three 2 2 -one}
test config-1.7 {Tk_CreateOptionTable - chained tables} testobjconfig {
    deleteWindows
    killTables
    testobjconfig chain2 .b
    testobjconfig chain1 .a
    testobjconfig info chain2


} {1 4 -three 2 2 -one}
test config-1.8 {Tk_CreateOptionTable - chained tables} testobjconfig {






    deleteWindows




    testobjconfig chain1 .a
    testobjconfig chain2 .b
    list [catch {.a cget -four} msg] $msg [.a cget -one] \
	    [.b cget -four] [.b cget -one]


} {1 {unknown option "-four"} one four one}


test config-2.1 {Tk_DeleteOptionTable - reference counts} testobjconfig {
    deleteWindows
    killTables

    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig chain2 .c
    deleteWindows
    set x {}
    testobjconfig delete chain2
    lappend x [testobjconfig info chain2] [testobjconfig info chain1]
    testobjconfig delete chain2
    lappend x [testobjconfig info chain2] [testobjconfig info chain1]


} {{1 4 -three 2 2 -one} {2 2 -one} {} {1 2 -one}}



# No tests for DestroyOptionHashTable; couldn't figure out how to test.

test config-3.1 {Tk_InitOptions - priority of chained tables} testobjconfig {
    deleteWindows

    testobjconfig chain1 .a
    testobjconfig chain2 .b
    list [.a cget -two] [.b cget -two]


} {two {two and a half}}
test config-3.2 {Tk_InitOptions - initialize from database} testobjconfig {
    deleteWindows
    option clear
    option add *a.color blue
    testobjconfig alltypes .a
    list [.a cget -color]



} {blue}
test config-3.3 {Tk_InitOptions - initialize from database} testobjconfig {
    deleteWindows
    option clear
    option add *a.justify bogus
    testobjconfig alltypes .a
    list [.a cget -justify]



} {left}
test config-3.4 {Tk_InitOptions - initialize from widget class} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a
    list [.a cget -color]


} {red}
test config-3.5 {Tk_InitOptions - no initial value} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a
    .a cget -anchor
} {}


test config-3.6 {Tk_InitOptions - bad initial value} testobjconfig {





    deleteWindows
    option clear




    option add *a.color non-existent
    list [catch {testobjconfig alltypes .a} msg] $msg $errorInfo




} {1 {unknown color name "non-existent"} {unknown color name "non-existent"
    (database entry for "-color" in widget ".a")















    invoked from within
"testobjconfig alltypes .a"}}
option clear
test config-3.7 {Tk_InitOptions - bad initial value} testobjconfig {
    deleteWindows
    list [catch {testobjconfig configerror} msg] $msg $errorInfo
} {1 {expected integer but got "bogus"} {expected integer but got "bogus"
    (default value for "-int")
    invoked from within
"testobjconfig configerror"}}
option clear

test config-4.1 {DoObjConfig - boolean} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -boolean 0} msg] $msg [catch {.foo cget -boolean} result] $result [catch {rename .foo {}}]


} {0 .foo 0 0 0}
test config-4.2 {DoObjConfig - boolean} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -boolean 1} msg] $msg [catch {.foo cget -boolean} result] $result [catch {rename .foo {}}]
} {0 .foo 0 1 0}



test config-4.3 {DoObjConfig - invalid boolean} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -boolean {}} msg] $msg
} {1 {expected boolean value but got ""}}




test config-4.4 {DoObjConfig - boolean internal value} testobjconfig {
    catch {rename .foo {}}























    testobjconfig internal .foo -boolean 0













    .foo cget -boolean



} {0}
test config-4.5 {DoObjConfig - integer} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -integer 3} msg] $msg [catch {.foo cget -integer} result] $result [catch {rename .foo {}}]


} {0 .foo 0 3 0}
test config-4.6 {DoObjConfig - invalid integer} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -integer bar} msg] $msg
} {1 {expected integer but got "bar"}}



test config-4.7 {DoObjConfig - integer internal value} testobjconfig {
    catch {rename .foo {}}

    testobjconfig internal .foo -integer 421
    .foo cget -integer

























} {421}
test config-4.8 {DoObjConfig - double} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -double 3.14} msg] $msg [catch {.foo cget -double} result] $result [catch {rename .foo {}}]
















} {0 .foo 0 3.14 0}



test config-4.9 {DoObjConfig - invalid double} testobjconfig {


    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -double bar} msg] $msg


} {1 {expected floating-point number but got "bar"}}
test config-4.10 {DoObjConfig - double internal value} testobjconfig {


    catch {rename .foo {}}

    testobjconfig internal .foo -double 62.75
    .foo cget -double


} {62.75}

test config-4.11 {DoObjConfig - string} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -string test} msg] $msg [catch {.foo cget -string} result] $result [destroy .foo]


} {0 .foo 0 test {}}
test config-4.12 {DoObjConfig - null string} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -string {}} msg] $msg [catch {.foo cget -string} result] $result [destroy .foo]
} {0 .foo 0 {} {}}



test config-4.13 {DoObjConfig - string internal value} testobjconfig {
    catch {rename .foo {}}

    testobjconfig internal .foo -string "this is a test"
    .foo cget -string






} {this is a test}




test config-4.14 {DoObjConfig - string table} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -stringtable two} msg] $msg [catch {.foo cget -stringtable} result] $result [destroy .foo]
} {0 .foo 0 two {}}



test config-4.15 {DoObjConfig - invalid string table} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -stringtable foo} msg] $msg





} {1 {bad stringtable "foo": must be one, two, three, or four}}
test config-4.16 {DoObjConfig - new string table} testobjconfig {









    catch {destroy .foo}

    testobjconfig alltypes .foo -stringtable two
    list [catch {.foo configure -stringtable three} msg] $msg [catch {.foo cget -stringtable} result] $result [destroy .foo]
} {0 16 0 three {}}


test config-4.17 {DoObjConfig - stringtable internal value} testobjconfig {
    catch {rename .foo {}}
    testobjconfig internal .foo -stringtable "four"
    .foo cget -stringtable
} {four}


test config-4.18 {DoObjConfig - color} testobjconfig {


    catch {rename .foo {}}






    list [catch {testobjconfig alltypes .foo -color blue} msg] $msg [catch {.foo cget -color} result] $result [destroy .foo]



} {0 .foo 0 blue {}}
test config-4.19 {DoObjConfig - invalid color} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -color xxx} msg] $msg






} {1 {unknown color name "xxx"}}






test config-4.20 {DoObjConfig - color internal value} testobjconfig {





    catch {rename .foo {}}








    testobjconfig internal .foo -color purple
    .foo cget -color



} {purple}
test config-4.21 {DoObjConfig - null color} testobjconfig {
    catch {rename .foo {}}
    list [catch {testobjconfig alltypes .foo -color {}} msg] $msg [catch {.foo cget -color} result] $result [destroy .foo]


} {0 .foo 0 {} {}}
test config-4.22 {DoObjConfig - getting rid of old color} testobjconfig {
    catch {destroy .foo}
    testobjconfig alltypes .foo -color #333333
    list [catch {.foo configure -color #444444} msg] $msg [catch {.foo cget -color} result] $result [destroy .foo]
} {0 32 0 #444444 {}}


test config-4.23 {DoObjConfig - font} testobjconfig {


    catch {rename .foo {}}






    list [catch {testobjconfig alltypes .foo -font {Helvetica 72}} msg] $msg [catch {.foo cget -font} result] $result [destroy .foo]
} {0 .foo 0 {Helvetica 72} {}}


test config-4.24 {DoObjConfig - new font} testobjconfig {


    catch {rename .foo {}}








    testobjconfig alltypes .foo -font {Courier 12}





    list [catch {.foo configure -font {Helvetica 72}} msg] $msg [catch {.foo cget -font} result] $result [destroy .foo]

} {0 64 0 {Helvetica 72} {}}

test config-4.25 {DoObjConfig - invalid font} testobjconfig {


    catch {rename .foo {}}






    list [catch {testobjconfig alltypes .foo -font {Helvetica 12 foo}} msg] $msg























} {1 {unknown font style "foo"}}
test config-4.26 {DoObjConfig - null font} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -font {}} msg] $msg [catch {.foo cget -font} result] $result [destroy .foo]


} {0 .foo 0 {} {}}
test config-4.27 {DoObjConfig - font internal value} testobjconfig {
    catch {rename .foo {}}

    testobjconfig internal .foo -font {Times 16}
    .foo cget -font
} {Times 16}
test config-4.28 {DoObjConfig - bitmap} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -bitmap gray75} msg] $msg [catch {.foo cget -bitmap} result] $result [destroy .foo]
} {0 .foo 0 gray75 {}}
test config-4.29 {DoObjConfig - new bitmap} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo -bitmap gray75
    list [catch {.foo configure -bitmap gray50} msg] $msg [catch {.foo cget -bitmap} result] $result [destroy .foo]
} {0 128 0 gray50 {}}


test config-4.30 {DoObjConfig - invalid bitmap} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -bitmap foo} msg] $msg

} {1 {bitmap "foo" not defined}}



test config-4.31 {DoObjConfig - null bitmap} testobjconfig {


    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -bitmap {}} msg] $msg [catch {.foo cget -bitmap} result] $result [destroy .foo]
} {0 .foo 0 {} {}}


test config-4.32 {DoObjConfig - bitmap internal value} testobjconfig {
    catch {rename .foo {}}

    testobjconfig internal .foo -bitmap gray25
    .foo cget -bitmap
} {gray25}


test config-4.33 {DoObjConfig - border} testobjconfig {
    catch {rename .foo {}}

    list [catch {testobjconfig alltypes .foo -border green} msg] $msg [catch {.foo cget -border} result] $result [destroy .foo]
} {0 .foo 0 green {}}



test config-4.34 {DoObjConfig - invalid border} testobjconfig {
    catch {destroy .foo}
    list [catch {testobjconfig alltypes .foo -border xxx} msg] $msg
} {1 {unknown color name "xxx"}}
test config-4.35 {DoObjConfig - null border} testobjconfig {
    catch {rename .foo {}}
    list [catch {testobjconfig alltypes .foo -border {}} msg] $msg [catch {.foo cget -border} result] $result [destroy .foo]
} {0 .foo 0 {} {}}
test config-4.36 {DoObjConfig - border internal value} testobjconfig {
    catch {rename .foo {}}
    testobjconfig internal .foo -border #123456
    .foo cget -border



} {#123456}
test config-4.37 {DoObjConfig - getting rid of old border} testobjconfig {



    catch {destroy .foo}

    testobjconfig alltypes .foo -border #333333






    list [catch {.foo configure -border #444444} msg] $msg [catch {.foo cget -border} result] $result [destroy .foo]






































} {0 256 0 #444444 {}}
test config-4.38 {DoObjConfig - relief} testobjconfig {



    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -relief flat} msg] $msg [catch {.foo cget -relief} result] $result [destroy .foo]

} {0 .foo 0 flat {}}


test config-4.39 {DoObjConfig - invalid relief} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -relief foo} msg] $msg



} {1 {bad relief "foo": must be flat, groove, raised, ridge, solid, or sunken}}
test config-4.40 {DoObjConfig - new relief} testobjconfig {



    catch {destroy .foo}

    testobjconfig alltypes .foo -relief raised
    list [catch {.foo configure -relief flat} msg] $msg [catch {.foo cget -relief} result] $result [destroy .foo]


} {0 512 0 flat {}}
test config-4.41 {DoObjConfig - relief internal value} testobjconfig {


    catch {rename .foo {}}

    testobjconfig internal .foo -relief ridge
    .foo cget -relief
} {ridge}


test config-4.42 {DoObjConfig - cursor} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -cursor arrow} msg] $msg [catch {.foo cget -cursor} result] $result [destroy .foo]
} {0 .foo 0 arrow {}}



test config-4.43 {DoObjConfig - invalid cursor} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -cursor foo} msg] $msg





} {1 {bad cursor spec "foo"}}
test config-4.44 {DoObjConfig - null cursor} testobjconfig {
    catch {destroy .foo}
    list [catch {testobjconfig alltypes .foo -cursor {}} msg] $msg [catch {.foo cget -cursor} result] $result [destroy .foo]


} {0 .foo 0 {} {}}
test config-4.45 {DoObjConfig - new cursor} testobjconfig {
    catch {destroy .foo}
    testobjconfig alltypes .foo -cursor xterm
    list [catch {.foo configure -cursor arrow} msg] $msg [catch {.foo cget -cursor} result] $result [destroy .foo]
} {0 1024 0 arrow {}}


test config-4.46 {DoObjConfig - cursor internal value} testobjconfig {







    catch {rename .foo {}}

    testobjconfig internal .foo -cursor watch
    .foo cget -cursor
} {watch}


test config-4.47 {DoObjConfig - justify} testobjconfig {












    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -justify center} msg] $msg [catch {.foo cget -justify} result] $result [destroy .foo]





} {0 .foo 0 center {}}



test config-4.48 {DoObjConfig - invalid justify} testobjconfig {












    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -justify foo} msg] $msg




} {1 {bad justification "foo": must be left, right, or center}}
test config-4.49 {DoObjConfig - new justify} testobjconfig {

    catch {destroy .foo}




    testobjconfig alltypes .foo -justify left
    list [catch {.foo configure -justify right} msg] $msg [catch {.foo cget -justify} result] $result [destroy .foo]

} {0 2048 0 right {}}


test config-4.50 {DoObjConfig - justify internal value} testobjconfig {


    catch {rename .foo {}}

    testobjconfig internal .foo -justify center
    .foo cget -justify



} {center}
test config-4.51 {DoObjConfig - anchor} testobjconfig {



    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -anchor center} msg] $msg [catch {.foo cget -anchor} result] $result [destroy .foo]
} {0 .foo 0 center {}}



test config-4.52 {DoObjConfig - invalid anchor} testobjconfig {









    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -anchor foo} msg] $msg
} {1 {bad anchor "foo": must be n, ne, e, se, s, sw, w, nw, or center}}
test config-4.53 {DoObjConfig - new anchor} testobjconfig {
    catch {destroy .foo}




    testobjconfig alltypes .foo -anchor e
    list [catch {.foo configure -anchor n} msg] $msg [catch {.foo cget -anchor} result] $result [destroy .foo]
} {0 4096 0 n {}}
test config-4.54 {DoObjConfig - anchor internal value} testobjconfig {
    catch {rename .foo {}}

    testobjconfig internal .foo -anchor sw
    .foo cget -anchor



} {sw}
test config-4.55 {DoObjConfig - pixel} testobjconfig {



    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -pixel 42} msg] $msg [catch {.foo cget -pixel} result] $result [destroy .foo]
} {0 .foo 0 42 {}}



test config-4.56 {DoObjConfig - invalid pixel} testobjconfig {






    catch {destroy .foo}




    list [catch {testobjconfig alltypes .foo -pixel foo} msg] $msg

} {1 {bad screen distance "foo"}}



test config-4.57 {DoObjConfig - new pixel} testobjconfig {
















    catch {destroy .foo}









    testobjconfig alltypes .foo -pixel 42m
    list [catch {.foo configure -pixel 3c} msg] $msg [catch {.foo cget -pixel} result] $result [destroy .foo]


} {0 8192 0 3c {}}







test config-4.58 {DoObjConfig - pixel internal value} testobjconfig {


    catch {rename .foo {}}

    testobjconfig internal .foo -pixel [winfo screenmmwidth .]m

    .foo cget -pixel
} [winfo screenwidth .]

test config-4.59 {DoObjConfig - window} testobjconfig {
    catch {destroy .foo}

    catch {destroy .bar}

    toplevel .bar
    list [catch {testobjconfig twowindows .foo -window .bar} msg] $msg [catch {.foo cget -window} result] $result [destroy .foo] [destroy .bar]


} {0 .foo 0 .bar {} {}}
test config-4.60 {DoObjConfig - invalid window} testobjconfig {


    catch {destroy .foo}




    toplevel .bar
    list [catch {testobjconfig twowindows .foo -window foo} msg] $msg [destroy .bar]


} {1 {bad window path name "foo"} {}}
test config-4.61 {DoObjConfig - null window} testobjconfig {
    catch {destroy .foo}
    catch {destroy .bar}





    toplevel .bar
    list [catch {testobjconfig twowindows .foo -window {}} msg] $msg [catch {.foo cget -window} result] $result [destroy .foo]
} {0 .foo 0 {} {}}



test config-4.62 {DoObjConfig - new window} testobjconfig {
    catch {destroy .foo}
    catch {destroy .bar}
    catch {destroy .blamph}






    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    list [catch {.foo configure -window .blamph} msg] $msg [catch {.foo cget -window} result] $result [destroy .foo] [destroy .bar] [destroy .blamph]



} {0 0 0 .blamph {} {} {}}
test config-4.63 {DoObjConfig - window internal value} testobjconfig {


    catch {rename .foo {}}

    testobjconfig internal .foo -window .
    .foo cget -window


} {.}

test config-4.64 {DoObjConfig - releasing old values} testobjconfig {




    # This test doesn't generate a useful value to check; if an
    # error occurs, it will be detected only by memory checking software
    # such as Purify or Tcl's built-in checker.

    catch {rename .foo {}}
    testobjconfig alltypes .foo -string {Test string} -color yellow \
	    -font {Courier 18} -bitmap questhead -border green -cursor cross \
	    -custom foobar
    .foo configure -string {new string} -color brown \
	    -font {Times 8} -bitmap gray75 -border pink -cursor watch \
	    -custom barbaz
    concat {}
} {}


test config-4.65 {DoObjConfig - releasing old values} testobjconfig {




    # This test doesn't generate a useful value to check; if an
    # error occurs, it will be detected only by memory checking software
    # such as Purify or Tcl's built-in checker.

    catch {rename .foo {}}
    testobjconfig internal .foo -string {Test string} -color yellow \
	    -font {Courier 18} -bitmap questhead -border green -cursor cross \
	    -custom foobar
    .foo configure -string {new string} -color brown \
	    -font {Times 8} -bitmap gray75 -border pink -cursor watch \
	    -custom barbaz
    concat {}



} {}
test config-4.66 {DoObjConfig - custom} testobjconfig {



    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -custom test} msg] $msg [catch {.foo cget -custom} result] $result [destroy .foo]
} {0 .foo 0 TEST {}}



test config-4.67 {DoObjConfig - null custom} testobjconfig {
    catch {destroy .foo}
    list [catch {testobjconfig alltypes .foo -custom {}} msg] $msg [catch {.foo cget -custom} result] $result [destroy .foo]


} {0 .foo 0 {} {}}
test config-4.68 {DoObjConfig - custom internal value} testobjconfig {
    catch {rename .foo {}}
    testobjconfig internal .foo -custom "this is a test"
    .foo cget -custom
} {THIS IS A TEST}

test config-5.1 {ObjectIsEmpty - object is already string} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo -color [format ""]




    .foo cget -color
} {}
test config-5.2 {ObjectIsEmpty - object is already string} testobjconfig {
    catch {destroy .foo}

    list [catch {testobjconfig alltypes .foo -color [format " "]} msg] $msg
} {1 {unknown color name " "}}
test config-5.3 {ObjectIsEmpty - must convert back to string} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo -color [list]
    .foo cget -color
} {}


deleteWindows
if {[testConstraint testobjconfig]} {
    testobjconfig chain2 .a

    testobjconfig alltypes .b











}

test config-6.1 {GetOptionFromObj - cached answer} testobjconfig {



    list [.a cget -three] [.a cget -three]


} {three three}
test config-6.2 {GetOptionFromObj - exact match} testobjconfig {



    .a cget -one


} {one}
test config-6.3 {GetOptionFromObj - abbreviation} testobjconfig {



    .a cget -fo


} {four}
test config-6.4 {GetOptionFromObj - ambiguous abbreviation} testobjconfig {

    list [catch {.a cget -on} msg] $msg
} {1 {unknown option "-on"}}
test config-6.5 {GetOptionFromObj - duplicate options in different tables} testobjconfig {
    .a cget -tw
} {two and a half}
test config-6.6 {GetOptionFromObj - synonym} testobjconfig {
    .b cget -synonym

} {red}

















deleteWindows
if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-7.1 {Tk_SetOptions - basics} testobjconfig {
    .a configure -color green -rel sunken
     list [.a cget -color] [.a cget -relief]
} {green sunken}
test config-7.2 {Tk_SetOptions - bogus option name} testobjconfig {


    list [catch {.a configure -bogus} msg] $msg
} {1 {unknown option "-bogus"}}
test config-7.3 {Tk_SetOptions - synonym} testobjconfig {
    .a configure -synonym blue
    .a cget -color
} {blue}
test config-7.4 {Tk_SetOptions - missing value} testobjconfig {


    list [catch {.a configure -color green -relief} msg] $msg [.a cget -color]
} {1 {value for "-relief" missing} green}
test config-7.5 {Tk_SetOptions - saving old values} testobjconfig {








    .a configure -color red -int 7 -relief raised -double 3.14159
    list [catch {.a csave -color green -int 432 -relief sunken \





	    -double 2.0 -color bogus} msg] $msg [.a cget -color] \
	    [.a cget -int] [.a cget -relief] [.a cget -double]






} {1 {unknown color name "bogus"} red 7 raised 3.14159}
test config-7.6 {Tk_SetOptions - error in DoObjConfig call} testobjconfig {


    list [catch {.a configure -color bogus} msg] $msg $errorInfo

} {1 {unknown color name "bogus"} {unknown color name "bogus"
    (processing "-color" option)
    invoked from within
".a configure -color bogus"}}

test config-7.7 {Tk_SetOptions - synonym name in error message} testobjconfig {







    list [catch {.a configure -synonym bogus} msg] $msg $errorInfo

} {1 {unknown color name "bogus"} {unknown color name "bogus"
    (processing "-synonym" option)
    invoked from within
".a configure -synonym bogus"}}
test config-7.8 {Tk_SetOptions - returning mask} testobjconfig {
    format %x [.a configure -color red -int 7 -relief raised -double 3.14159]
} {226}





test config-7.9 {Tk_SetOptions - error in DoObjConfig with custom option} testobjconfig {


    list [catch {.a configure -custom bad} msg] $msg $errorInfo

} {1 {expected good value, got "BAD"} {expected good value, got "BAD"
    (processing "-custom" option)
    invoked from within
".a configure -custom bad"}}





test config-8.1 {Tk_RestoreSavedOptions - restore in proper order} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a
    list [catch {.a csave -color green -color black -color blue \
	    -color #ffff00 -color #ff00ff -color bogus} msg] $msg \
	    [.a cget -color]

} {1 {unknown color name "bogus"} red}
test config-8.2 {Tk_RestoreSavedOptions - freeing object memory} testobjconfig {
    deleteWindows

    testobjconfig alltypes .a
    .a csave -color green -color black -color blue -color #ffff00 \
	    -color #ff00ff

} {32}


test config-8.3 {Tk_RestoreSavedOptions - boolean internal form} testobjconfig {





    deleteWindows




    testobjconfig internal .a
    list [catch {.a csave -boolean 0 -color bogus}] [.a cget -boolean]





} {1 1}






test config-8.4 {Tk_RestoreSavedOptions - integer internal form} testobjconfig {





    deleteWindows




    testobjconfig internal .a
    list [catch {.a csave -integer 24 -color bogus}] [.a cget -integer]



} {1 148962237}
test config-8.5 {Tk_RestoreSavedOptions - double internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -double 62.4 -color bogus}] [.a cget -double]



} {1 3.14159}
test config-8.6 {Tk_RestoreSavedOptions - string internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -string "A long string" -color bogus}] \
	    [.a cget -string]


} {1 foo}
test config-8.7 {Tk_RestoreSavedOptions - string table internal form} testobjconfig {
    deleteWindows
    testobjconfig internal .a
    list [catch {.a csave -stringtable three -color bogus}] \
	    [.a cget -stringtable]
} {1 one}
test config-8.8 {Tk_RestoreSavedOptions - color internal form} testobjconfig {
    deleteWindows
    testobjconfig internal .a









    list [catch {.a csave -color green -color bogus}] [.a cget -color]



} {1 red}
test config-8.9 {Tk_RestoreSavedOptions - font internal form} {testobjconfig nonPortable} {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -font {Times 12} -color bogus}] [.a cget -font]



} {1 {Helvetica 12}}
test config-8.10 {Tk_RestoreSavedOptions - bitmap internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -bitmap questhead -color bogus}] [.a cget -bitmap]



} {1 gray50}
test config-8.11 {Tk_RestoreSavedOptions - border internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -border brown -color bogus}] [.a cget -border]



} {1 blue}
test config-8.12 {Tk_RestoreSavedOptions - relief internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -relief sunken -color bogus}] [.a cget -relief]

} {1 raised}
test config-8.13 {Tk_RestoreSavedOptions - cursor internal form} testobjconfig {

    deleteWindows




    testobjconfig internal .a
    list [catch {.a csave -cursor watch -color bogus}] [.a cget -cursor]



} {1 xterm}
test config-8.14 {Tk_RestoreSavedOptions - justify internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -justify right -color bogus}] [.a cget -justify]



} {1 left}
test config-8.15 {Tk_RestoreSavedOptions - anchor internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a
    list [catch {.a csave -anchor center -color bogus}] [.a cget -anchor]

} {1 n}


test config-8.16 {Tk_RestoreSavedOptions - window internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a -window .a
    list [catch {.a csave -window .a -color bogus}] [.a cget -window]

} {1 .a}


test config-8.17 {Tk_RestoreSavedOptions - custom internal form} testobjconfig {
    deleteWindows

    testobjconfig internal .a -custom "foobar"
    list [catch {.a csave -custom "barbaz" -color bogus}] [.a cget -custom]



} {1 FOOBAR}

# Most of the tests below will cause memory leakage if there is a
# problem.  This may not be evident unless the tests are run in
# conjunction with a memory usage analyzer such as Purify.

test config-9.1 {Tk_FreeConfigOptions/FreeResources - string internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -string "two words"
    destroy .foo
} {}
test config-9.2 {Tk_FreeConfigOptions/FreeResources - color internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -color yellow
    destroy .foo
} {}
test config-9.3 {Tk_FreeConfigOptions/FreeResources - color} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -color [format blue]
    destroy .foo
} {}
test config-9.4 {Tk_FreeConfigOptions/FreeResources - font internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -font {Courier 20}
    destroy .foo
} {}
test config-9.5 {Tk_FreeConfigOptions/FreeResources - font} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -font [format {Courier 24}]
    destroy .foo
} {}
test config-9.6 {Tk_FreeConfigOptions/FreeResources - bitmap internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -bitmap gray75
    destroy .foo
} {}
test config-9.7 {Tk_FreeConfigOptions/FreeResources - bitmap} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -bitmap [format gray75]
    destroy .foo
} {}
test config-9.8 {Tk_FreeConfigOptions/FreeResources - border internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -border orange
    destroy .foo
} {}
test config-9.9 {Tk_FreeConfigOptions/FreeResources - border} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -border [format blue]
    destroy .foo
} {}
test config-9.10 {Tk_FreeConfigOptions/FreeResources - cursor internal form} testobjconfig {
    catch {destroy .foo}

    testobjconfig internal .foo
    .foo configure -cursor cross
    destroy .foo
} {}
test config-9.11 {Tk_FreeConfigOptions/FreeResources - cursor} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -cursor [format watch]
    destroy .foo
} {}
test config-9.12 {Tk_FreeConfigOptions/FreeResources - not special} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -integer [format 27]
    destroy .foo
} {}
test config-9.13 {Tk_FreeConfigOptions/FreeResources - custom internal form} testobjconfig {


    catch {destroy .fpp}
    testobjconfig internal .foo
    .foo configure -custom "foobar"
    destroy .foo



} {}


test config-10.1 {Tk_GetOptionInfo - one item} testobjconfig {
    catch {destroy .foo}
    testobjconfig alltypes .foo
    .foo configure -relief groove
    .foo configure -relief


} {-relief relief Relief raised groove}
test config-10.2 {Tk_GetOptionInfo - one item, synonym} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo
    .foo configure -color black
    .foo configure -synonym


} {-color color Color red black}
test config-10.3 {Tk_GetOptionInfo - all items} testobjconfig {
    catch {destroy .foo}

    testobjconfig alltypes .foo -font {Helvetica 18} -integer 13563
    .foo configure


} {{-boolean boolean Boolean 1 1} {-integer integer Integer 7 13563} {-double double Double 3.14159 3.14159} {-string string String foo foo} {-stringtable StringTable stringTable one one} {-color color Color red red} {-font font Font {Helvetica 12} {Helvetica 18}} {-bitmap bitmap Bitmap gray50 gray50} {-border border Border blue blue} {-relief relief Relief raised raised} {-cursor cursor Cursor xterm xterm} {-justify {} {} left left} {-anchor anchor Anchor {} {}} {-pixel pixel Pixel 1 1} {-custom {} {} {} {}} {-synonym -color}}
test config-10.4 {Tk_GetOptionInfo - chaining through tables} testobjconfig {
    catch {destroy .foo}
    testobjconfig chain2 .foo -one asdf -three xyzzy
    .foo configure


} {{-three three Three three xyzzy} {-four four Four four four} {-two two Two {two and a half} {two and a half}} {-oneAgain oneAgain OneAgain {one again} {one again}} {-one one One one asdf} {-two two Two two {two and a half}}}



deleteWindows

if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-11.1 {GetConfigList - synonym} testobjconfig {
    lindex [.a configure] end
} {-synonym -color}
test config-11.2 {GetConfigList - null database names} testobjconfig {


    .a configure -justify
} {-justify {} {} left left}
test config-11.3 {GetConfigList - null default and current value} testobjconfig {


    .a configure -anchor
} {-anchor anchor Anchor {} {}}



deleteWindows

if {[testConstraint testobjconfig]} {
    testobjconfig internal .a
}
test config-12.1 {GetObjectForOption - boolean} testobjconfig {
    .a configure -boolean 0
    .a cget -boolean
} {0}
test config-12.2 {GetObjectForOption - integer} testobjconfig {
    .a configure -integer 1247
    .a cget -integer
} {1247}
test config-12.3 {GetObjectForOption - double} testobjconfig {
    .a configure -double -88.82
    .a cget -double
} {-88.82}
test config-12.4 {GetObjectForOption - string} testobjconfig {
    .a configure -string "test value"
    .a cget -string
} {test value}
test config-12.5 {GetObjectForOption - stringTable} testobjconfig {


    .a configure -stringtable "two"
    .a cget -stringtable
} {two}
test config-12.6 {GetObjectForOption - color} testobjconfig {
    .a configure -color "green"
    .a cget -color
} {green}
test config-12.7 {GetObjectForOption - font} testobjconfig {
    .a configure -font {Times 36}
    .a cget -font
} {Times 36}
test config-12.8 {GetObjectForOption - bitmap} testobjconfig {
    .a configure -bitmap "questhead"
    .a cget -bitmap
} {questhead}
test config-12.9 {GetObjectForOption - border} testobjconfig {
    .a configure -border #33217c
    .a cget -border
} {#33217c}
test config-12.10 {GetObjectForOption - relief} testobjconfig {


    .a configure -relief groove
    .a cget -relief
} {groove}
test config-12.11 {GetObjectForOption - cursor} testobjconfig {


    .a configure -cursor watch
    .a cget -cursor
} {watch}
test config-12.12 {GetObjectForOption - justify} testobjconfig {


    .a configure -justify right
    .a cget -justify
} {right}
test config-12.13 {GetObjectForOption - anchor} testobjconfig {
    .a configure -anchor e
    .a cget -anchor
} {e}
test config-12.14 {GetObjectForOption - pixels} testobjconfig {
    .a configure -pixel 193.2
    .a cget -pixel
} {193}
test config-12.15 {GetObjectForOption - window} testobjconfig {
    .a configure -window .a
    .a cget -window
} {.a}
test config-12.16 {GetObjectForOption -custom} testobjconfig {
    .a configure -custom foobar
    .a cget -custom
} {FOOBAR}
test config-12.17 {GetObjectForOption - null values} testobjconfig {


    .a configure -string {} -color {} -font {} -bitmap {} -border {} \
	    -cursor {} -window {} -custom {}
    list [.a cget -string] [.a cget -color] [.a cget -font] \
	    [.a cget -bitmap] [.a cget -border] [.a cget -cursor] \
	    [.a cget -window] [.a cget -custom]
} {{} {} {} {} {} {} {} {}}





test config-13.1 {proper cleanup of options with widget destroy} {


    foreach type {





















	button canvas entry frame listbox menu menubutton message







	scale scrollbar text radiobutton checkbutton

    } {


	destroy .w


	$type .w -cursor crosshair
	destroy .w
    }
} {}


















deleteWindows












test config-14.1 {Tk_CreateOptionTable - use with namespace import} {
    namespace export -clear *








    foreach type {





	button canvas entry frame listbox menu menubutton message

	scale scrollbar spinbox text radiobutton checkbutton
    } {






	namespace eval ::foo [subst {
	    namespace import -force ::$type











	    ::foo::$type .a
	    ::foo::$type .b
	}
	]
	destroy .a .b








    }










} {}







































































# cleanup
deleteWindows
if {[testConstraint testobjconfig]} {
    killTables
}
cleanupTests
return








Changes to tests/constraints.tcl.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
		}
	    }
	    return [list load $tklib Tk]
	}

	namespace eval bg {
	    # Manage a background process.
	    # Replace with child interp or thread?
	    namespace import ::tcltest::interpreter
	    namespace import ::tk::test::loadTkCommand
	    namespace export setup cleanup do

	    proc cleanup {} {
		variable fd
		# catch in case the background process has closed $fd







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
		}
	    }
	    return [list load $tklib Tk]
	}

	namespace eval bg {
	    # Manage a background process.
	    # Replace with slave interp or thread?
	    namespace import ::tcltest::interpreter
	    namespace import ::tk::test::loadTkCommand
	    namespace export setup cleanup do

	    proc cleanup {} {
		variable fd
		# catch in case the background process has closed $fd
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
            entry .focus.e
            .focus.e insert 0 "fixfocus"
            pack .focus.e
            update
            focus -force .focus.e
            destroy .focus
	}


        namespace export imageInit imageFinish imageCleanup imageNames
        variable ImageNames
        proc imageInit {} {
            variable ImageNames
            if {![info exists ImageNames]} {
                set ImageNames [lsort [image names]]
            }
            imageCleanup
            if {[lsort [image names]] ne $ImageNames} {
                return -code error "IMAGE NAMES mismatch: [image names] != $ImageNames"
            }
        }
        proc imageFinish {} {
            variable ImageNames
            if {[lsort [image names]] ne $ImageNames} {
                return -code error "images remaining: [image names] != $ImageNames"
            }
            imageCleanup
        }
        proc imageCleanup {} {
            variable ImageNames
            foreach img [image names] {
                if {$img ni $ImageNames} {image delete $img}
            }
        }
        proc imageNames {} {
            variable ImageNames
            set r {}
            foreach img [image names] {
                if {$img ni $ImageNames} {lappend r $img}
            }
            return $r
        }

    }
}

namespace import -force tk::test::*

namespace import -force tcltest::testConstraint
testConstraint notAqua [expr {[tk windowingsystem] ne "aqua"}]
testConstraint aqua [expr {[tk windowingsystem] eq "aqua"}]
testConstraint x11 [expr {[tk windowingsystem] eq "x11"}]
testConstraint nonwin [expr {[tk windowingsystem] ne "win32"}]
testConstraint aquaOrWin32 [expr {
    ([tk windowingsystem] eq "win32") || [testConstraint aqua]
}]
testConstraint userInteraction 0
testConstraint nonUnixUserInteraction [expr {
    [testConstraint userInteraction] ||
    ([testConstraint unix] && [testConstraint notAqua])
}]
testConstraint haveDISPLAY [expr {[info exists env(DISPLAY)] && [testConstraint x11]}]
testConstraint altDisplay  [info exists env(TK_ALT_DISPLAY)]
testConstraint noExceed [expr {
    ![testConstraint unix] || [catch {font actual "\{xyz"}]
}]

# constraints for testing facilities defined in the tktest executable...
testConstraint testImageType [expr {"test" in [image types]}]
testConstraint testOldImageType [expr {"oldtest" in [image types]}]
testConstraint testbitmap    [llength [info commands testbitmap]]
testConstraint testborder    [llength [info commands testborder]]
testConstraint testcbind     [llength [info commands testcbind]]
testConstraint testclipboard [llength [info commands testclipboard]]
testConstraint testcolor     [llength [info commands testcolor]]
testConstraint testcursor    [llength [info commands testcursor]]
testConstraint testembed     [llength [info commands testembed]]
testConstraint testfont      [llength [info commands testfont]]
testConstraint testmakeexist [llength [info commands testmakeexist]]
testConstraint testmenubar   [llength [info commands testmenubar]]
testConstraint testmetrics   [llength [info commands testmetrics]]
testConstraint testobjconfig [llength [info commands testobjconfig]]
testConstraint testsend      [llength [info commands testsend]]
testConstraint testtext      [llength [info commands testtext]]
testConstraint testwinevent  [llength [info commands testwinevent]]
testConstraint testwrapper   [llength [info commands testwrapper]]

# constraint to see what sort of fonts are available
testConstraint fonts 1
destroy .e
entry .e -width 0 -font {Helvetica -12} -bd 1 -highlightthickness 1
.e insert end a.bcd
if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
    testConstraint fonts 0
}
destroy .e
destroy .t
text .t -width 80 -height 20 -font {Times -14} -bd 1







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










<
<
<












|
|




















|







132
133
134
135
136
137
138




































139
140
141
142
143
144
145
146
147
148



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
            entry .focus.e
            .focus.e insert 0 "fixfocus"
            pack .focus.e
            update
            focus -force .focus.e
            destroy .focus
	}




































    }
}

namespace import -force tk::test::*

namespace import -force tcltest::testConstraint
testConstraint notAqua [expr {[tk windowingsystem] ne "aqua"}]
testConstraint aqua [expr {[tk windowingsystem] eq "aqua"}]
testConstraint x11 [expr {[tk windowingsystem] eq "x11"}]
testConstraint nonwin [expr {[tk windowingsystem] ne "win32"}]



testConstraint userInteraction 0
testConstraint nonUnixUserInteraction [expr {
    [testConstraint userInteraction] ||
    ([testConstraint unix] && [testConstraint notAqua])
}]
testConstraint haveDISPLAY [expr {[info exists env(DISPLAY)] && [testConstraint x11]}]
testConstraint altDisplay  [info exists env(TK_ALT_DISPLAY)]
testConstraint noExceed [expr {
    ![testConstraint unix] || [catch {font actual "\{xyz"}]
}]

# constraints for testing facilities defined in the tktest executable...
testConstraint testImageType [expr {[lsearch [image types] test] >= 0}]
testConstraint testOldImageType [expr {[lsearch [image types] oldtest] >= 0}]
testConstraint testbitmap    [llength [info commands testbitmap]]
testConstraint testborder    [llength [info commands testborder]]
testConstraint testcbind     [llength [info commands testcbind]]
testConstraint testclipboard [llength [info commands testclipboard]]
testConstraint testcolor     [llength [info commands testcolor]]
testConstraint testcursor    [llength [info commands testcursor]]
testConstraint testembed     [llength [info commands testembed]]
testConstraint testfont      [llength [info commands testfont]]
testConstraint testmakeexist [llength [info commands testmakeexist]]
testConstraint testmenubar   [llength [info commands testmenubar]]
testConstraint testmetrics   [llength [info commands testmetrics]]
testConstraint testobjconfig [llength [info commands testobjconfig]]
testConstraint testsend      [llength [info commands testsend]]
testConstraint testtext      [llength [info commands testtext]]
testConstraint testwinevent  [llength [info commands testwinevent]]
testConstraint testwrapper   [llength [info commands testwrapper]]

# constraint to see what sort of fonts are available
testConstraint fonts 1
destroy .e
entry .e -width 0 -font {Helvetica -12} -bd 1
.e insert end a.bcd
if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
    testConstraint fonts 0
}
destroy .e
destroy .t
text .t -width 80 -height 20 -font {Times -14} -bd 1
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {
    {truecolor 24} in [winfo visualsavailable .]
}]
testConstraint haveGrayscale8 [expr {
    {grayscale 8} in [winfo visualsavailable .]
}]
testConstraint defaultPseudocolor8 [expr {
    ([winfo visual .] eq "pseudocolor") && ([winfo depth .] == 8)
}]

# constraint based on whether our display is secure
setupbg







|


|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {
    [lsearch -exact [winfo visualsavailable .] {truecolor 24}] >= 0
}]
testConstraint haveGrayscale8 [expr {
    [lsearch -exact [winfo visualsavailable .] {grayscale 8}] >= 0
}]
testConstraint defaultPseudocolor8 [expr {
    ([winfo visual .] eq "pseudocolor") && ([winfo depth .] == 8)
}]

# constraint based on whether our display is secure
setupbg
275
276
277
278
279
280
281

282
283
284
285
286
namespace import -force tcltest::makeFile
namespace import -force tcltest::removeFile
namespace import -force tcltest::makeDirectory
namespace import -force tcltest::removeDirectory
namespace import -force tcltest::interpreter
namespace import -force tcltest::testsDirectory
namespace import -force tcltest::cleanupTests


deleteWindows
wm geometry . {}
raise .








>





236
237
238
239
240
241
242
243
244
245
246
247
248
namespace import -force tcltest::makeFile
namespace import -force tcltest::removeFile
namespace import -force tcltest::makeDirectory
namespace import -force tcltest::removeDirectory
namespace import -force tcltest::interpreter
namespace import -force tcltest::testsDirectory
namespace import -force tcltest::cleanupTests
namespace import -force tcltest::bytestring

deleteWindows
wm geometry . {}
raise .

Changes to tests/cursor.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97

98
























99
100
101
102
103
104
105
106



107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720

721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
# This file is a Tcl script to test out the procedures in the file
# tkCursor.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands


# Tests 2.3 and 2.4 need a helper file with a very specific name and
# controlled format.
proc setWincur {wincurName} {
	upvar $wincurName wincur
	set wincur(data_octal) {
	    000 000 002 000 001 000 040 040 000 000 007 000 007 000 060 001
	    000 000 026 000 000 000 050 000 000 000 040 000 000 000 100 000
	    000 000 001 000 001 000 000 000 000 000 000 000 000 000 000 000
	    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
	    000 000 377 377 377 000 000 000 000 000 000 000 000 000 000 000
	    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
	    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
	    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
	    000 000 000 000 000 000 000 000 000 000 160 016 000 000 170 036
	    000 000 174 076 000 000 076 174 000 000 037 370 000 000 017 360
	    000 000 007 340 000 000 007 340 000 000 017 360 000 000 037 370
	    000 000 076 174 000 000 174 076 000 000 170 036 000 000 160 016
	    000 000 000 000 000 000 377 377 377 377 377 377 377 377 377 377
	    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
	    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
	    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
	    377 377 377 377 377 377 017 360 377 377 007 340 377 377 003 300
	    377 377 001 200 377 377 200 001 377 377 300 003 377 377 340 007
	    377 377 360 017 377 377 360 017 377 377 340 007 377 377 300 003
	    377 377 200 001 377 377 001 200 377 377 003 300 377 377 007 340
	    377 377 017 360 377 377
	}
	set wincur(data_binary) {}
	foreach wincur(num) $wincur(data_octal) {
	    append wincur(data_binary) [binary format c [scan $wincur(num) %o]]
	}
	set wincur(dir) [makeDirectory {dir with spaces}]
	set wincur(file) [makeFile $wincur(data_binary) "test file.cur" $wincur(dir)]
}


test cursor-1.1 {Tk_AllocCursorFromObj - converting internal reps} -constraints {
    testcursor
} -body {
    set x watch
    lindex $x 0

    button .b -cursor $x
    lindex $x 0
    testcursor watch
} -cleanup {
    destroy .b
} -result {{1 0}}
test cursor-1.2 {Tk_AllocCursorFromObj - discard stale cursor} -constraints {
    testcursor
} -body {
    set x watch
    set result {}
    button .b1 -cursor $x
    destroy .b1

    lappend result [testcursor watch]
    button .b2 -cursor $x
    lappend result [testcursor watch]
} -cleanup {
    destroy .b2
} -result {{} {{1 1}}}
test cursor-1.3 {Tk_AllocCursorFromObj - reuse existing cursor} -constraints {
    testcursor
} -body {
    set x watch
    set result {}
    button .b1 -cursor $x

    lappend result [testcursor watch]
    button .b2 -cursor $x
    pack .b1 .b2 -side top
    lappend result [testcursor watch]
} -cleanup {
    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}

test cursor-2.1 {Tk_GetCursor procedure} -body {
    button .b -cursor bad_name
} -cleanup {
    destroy .b

} -returnCodes error -result {bad cursor spec "bad_name"}
test cursor-2.2 {Tk_GetCursor procedure} -body {
    button .b -cursor @xyzzy
} -cleanup {
    destroy .b

} -returnCodes error -result {bad cursor spec "@xyzzy"}

























test cursor-2.3 {Tk_GetCursor procedure: cursor specs are lists} -constraints {
    win
} -setup {
	unset -nocomplain wincur
	set wincur(file) ""
} -body {
	setWincur wincur



    button .b -cursor [list @$wincur(file)]
} -cleanup {

    destroy .b
	removeDirectory $wincur(dir)
	unset wincur
} -result {.b}
test cursor-2.4 {Tk_GetCursor procedure: cursor specs are lists} -constraints {
    win
} -setup {
	unset -nocomplain wincur
	set wincur(file) ""
} -body {
	setWincur wincur
    button .b -cursor @[regsub -all {[][ \\{}""$#]} $wincur(file) {\\&}]
} -cleanup {
    destroy .b
	removeDirectory $wincur(dir)
	unset wincur
} -result {.b}

test cursor-3.1 {Tk_FreeCursorFromObj - reference counts} -constraints {
    testcursor
} -setup {
    set x heart
    set result {}
} -body {
    button .b1 -cursor $x
    button .b3 -cursor $x
    button .b2 -cursor $x

    lappend result [testcursor heart]
    destroy .b1
    lappend result [testcursor heart]
    destroy .b2
    lappend result [testcursor heart]
    destroy .b3
    lappend result [testcursor heart]
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test cursor-4.1 {FreeCursorObjProc} -constraints {
    testcursor
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy heart]
    button .b -cursor $x
    set y [copy heart]
    .b configure -cursor $y
    set z [copy heart]
    .b configure -cursor $z
    set result {}
    lappend result [testcursor heart]
    set x red
    lappend result [testcursor heart]
    set z 32
    lappend result [testcursor heart]
    destroy .b
    lappend result [testcursor heart]
    set y bogus
    set result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

# -------------------------------------------------------------------------

test cursor-5.1 {assert consistent cursor configuration command} -setup {
    button .b
} -body {
    .b configure -cursor {watch red black}
} -cleanup {
    destroy .b
} -result {}

# -------------------------------------------------------------------------
# Check for the standard set of cursors.
test cursor-6.1 {check cursor-font cursor X_cursor} -setup {
	button .b -text X_cursor
} -body {
	.b configure -cursor X_cursor
} -cleanup {
	destroy .b
} -result {}
test cursor-6.2 {check cursor-font cursor arrow} -setup {
	button .b -text arrow
} -body {
	.b configure -cursor arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.3 {check cursor-font cursor based_arrow_down} -setup {
	button .b -text based_arrow_down
} -body {
	.b configure -cursor based_arrow_down
} -cleanup {
	destroy .b
} -result {}
test cursor-6.4 {check cursor-font cursor based_arrow_up} -setup {
	button .b -text based_arrow_up
} -body {
	.b configure -cursor based_arrow_up
} -cleanup {
	destroy .b
} -result {}
test cursor-6.5 {check cursor-font cursor boat} -setup {
	button .b -text boat
} -body {
	.b configure -cursor boat
} -cleanup {
	destroy .b
} -result {}
test cursor-6.6 {check cursor-font cursor bogosity} -setup {
	button .b -text bogosity
} -body {
	.b configure -cursor bogosity
} -cleanup {
	destroy .b
} -result {}
test cursor-6.7 {check cursor-font cursor bottom_left_corner} -setup {
	button .b -text bottom_left_corner
} -body {
	.b configure -cursor bottom_left_corner
} -cleanup {
	destroy .b
} -result {}
test cursor-6.8 {check cursor-font cursor bottom_right_corner} -setup {
	button .b -text bottom_right_corner
} -body {
	.b configure -cursor bottom_right_corner
} -cleanup {
	destroy .b
} -result {}
test cursor-6.9 {check cursor-font cursor bottom_side} -setup {
	button .b -text bottom_side
} -body {
	.b configure -cursor bottom_side
} -cleanup {
	destroy .b
} -result {}
test cursor-6.10 {check cursor-font cursor bottom_tee} -setup {
	button .b -text bottom_tee
} -body {
	.b configure -cursor bottom_tee
} -cleanup {
	destroy .b
} -result {}
test cursor-6.11 {check cursor-font cursor box_spiral} -setup {
	button .b -text box_spiral
} -body {
	.b configure -cursor box_spiral
} -cleanup {
	destroy .b
} -result {}
test cursor-6.12 {check cursor-font cursor center_ptr} -setup {
	button .b -text center_ptr
} -body {
	.b configure -cursor center_ptr
} -cleanup {
	destroy .b
} -result {}
test cursor-6.13 {check cursor-font cursor circle} -setup {
	button .b -text circle
} -body {
	.b configure -cursor circle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.14 {check cursor-font cursor clock} -setup {
	button .b -text clock
} -body {
	.b configure -cursor clock
} -cleanup {
	destroy .b
} -result {}
test cursor-6.15 {check cursor-font cursor coffee_mug} -setup {
	button .b -text coffee_mug
} -body {

	.b configure -cursor coffee_mug
} -cleanup {
	destroy .b
} -result {}
test cursor-6.16 {check cursor-font cursor cross} -setup {
	button .b -text cross
} -body {
	.b configure -cursor cross
} -cleanup {

	destroy .b
} -result {}
test cursor-6.17 {check cursor-font cursor cross_reverse} -setup {
	button .b -text cross_reverse
} -body {
	.b configure -cursor cross_reverse
} -cleanup {
	destroy .b
} -result {}
test cursor-6.18 {check cursor-font cursor crosshair} -setup {
	button .b -text crosshair
} -body {
	.b configure -cursor crosshair
} -cleanup {
	destroy .b
} -result {}
test cursor-6.19 {check cursor-font cursor diamond_cross} -setup {
	button .b -text diamond_cross
} -body {
	.b configure -cursor diamond_cross
} -cleanup {
	destroy .b
} -result {}
test cursor-6.20 {check cursor-font cursor dot} -setup {
	button .b -text dot
} -body {
	.b configure -cursor dot
} -cleanup {
	destroy .b
} -result {}
test cursor-6.21 {check cursor-font cursor dotbox} -setup {
	button .b -text dotbox
} -body {
	.b configure -cursor dotbox
} -cleanup {
	destroy .b
} -result {}
test cursor-6.22 {check cursor-font cursor double_arrow} -setup {
	button .b -text double_arrow
} -body {
	.b configure -cursor double_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.23 {check cursor-font cursor draft_large} -setup {
	button .b -text draft_large
} -body {
	.b configure -cursor draft_large
} -cleanup {
	destroy .b
} -result {}
test cursor-6.24 {check cursor-font cursor draft_small} -setup {
	button .b -text draft_small
} -body {
	.b configure -cursor draft_small
} -cleanup {
	destroy .b
} -result {}
test cursor-6.25 {check cursor-font cursor draped_box} -setup {
	button .b -text draped_box
} -body {
	.b configure -cursor draped_box
} -cleanup {
	destroy .b
} -result {}
test cursor-6.26 {check cursor-font cursor exchange} -setup {
	button .b -text exchange
} -body {
	.b configure -cursor exchange
} -cleanup {
	destroy .b
} -result {}
test cursor-6.27 {check cursor-font cursor fleur} -setup {
	button .b -text fleur
} -body {
	.b configure -cursor fleur
} -cleanup {
	destroy .b
} -result {}
test cursor-6.28 {check cursor-font cursor gobbler} -setup {
	button .b -text gobbler
} -body {
	.b configure -cursor gobbler
} -cleanup {
	destroy .b
} -result {}
test cursor-6.29 {check cursor-font cursor gumby} -setup {
	button .b -text gumby
} -body {
	.b configure -cursor gumby
} -cleanup {
	destroy .b
} -result {}
test cursor-6.30 {check cursor-font cursor hand1} -setup {
	button .b -text hand1
} -body {
	.b configure -cursor hand1
} -cleanup {
	destroy .b
} -result {}
test cursor-6.31 {check cursor-font cursor hand2} -setup {
	button .b -text hand2
} -body {
	.b configure -cursor hand2
} -cleanup {
	destroy .b
} -result {}
test cursor-6.32 {check cursor-font cursor heart} -setup {
	button .b -text heart
} -body {
	.b configure -cursor heart
} -cleanup {
	destroy .b
} -result {}
test cursor-6.33 {check cursor-font cursor icon} -setup {
	button .b -text icon
} -body {
	.b configure -cursor icon
} -cleanup {
	destroy .b
} -result {}
test cursor-6.34 {check cursor-font cursor iron_cross} -setup {
	button .b -text iron_cross
} -body {
	.b configure -cursor iron_cross
} -cleanup {
	destroy .b
} -result {}
test cursor-6.35 {check cursor-font cursor left_ptr} -setup {
	button .b -text left_ptr
} -body {
	.b configure -cursor left_ptr
} -cleanup {
	destroy .b
} -result {}
test cursor-6.36 {check cursor-font cursor left_side} -setup {
	button .b -text left_side
} -body {
	.b configure -cursor left_side
} -cleanup {
	destroy .b
} -result {}
test cursor-6.37 {check cursor-font cursor left_tee} -setup {
	button .b -text left_tee
} -body {
	.b configure -cursor left_tee
} -cleanup {
	destroy .b
} -result {}
test cursor-6.38 {check cursor-font cursor leftbutton} -setup {
	button .b -text leftbutton
} -body {
	.b configure -cursor leftbutton
} -cleanup {
	destroy .b
} -result {}
test cursor-6.39 {check cursor-font cursor ll_angle} -setup {
	button .b -text ll_angle
} -body {
	.b configure -cursor ll_angle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.40 {check cursor-font cursor lr_angle} -setup {
	button .b -text lr_angle
} -body {
	.b configure -cursor lr_angle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.41 {check cursor-font cursor man} -setup {
	button .b -text man
} -body {
	.b configure -cursor man
} -cleanup {
	destroy .b
} -result {}
test cursor-6.42 {check cursor-font cursor middlebutton} -setup {
	button .b -text middlebutton
} -body {
	.b configure -cursor middlebutton
} -cleanup {
	destroy .b
} -result {}
test cursor-6.43 {check cursor-font cursor mouse} -setup {
	button .b -text mouse
} -body {
	.b configure -cursor mouse
} -cleanup {
	destroy .b
} -result {}
test cursor-6.44 {check cursor-font cursor pencil} -setup {
	button .b -text pencil
} -body {
	.b configure -cursor pencil
} -cleanup {
	destroy .b
} -result {}
test cursor-6.45 {check cursor-font cursor pirate} -setup {
	button .b -text pirate
} -body {
	.b configure -cursor pirate
} -cleanup {
	destroy .b
} -result {}
test cursor-6.46 {check cursor-font cursor plus} -setup {
	button .b -text plus
} -body {
	.b configure -cursor plus
} -cleanup {
	destroy .b
} -result {}
test cursor-6.47 {check cursor-font cursor question_arrow} -setup {
	button .b -text question_arrow
} -body {
	.b configure -cursor question_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.48 {check cursor-font cursor right_ptr} -setup {
	button .b -text right_ptr
} -body {
	.b configure -cursor right_ptr
} -cleanup {
	destroy .b
} -result {}
test cursor-6.49 {check cursor-font cursor right_side} -setup {
	button .b -text right_side
} -body {
	.b configure -cursor right_side
} -cleanup {
	destroy .b
} -result {}
test cursor-6.50 {check cursor-font cursor right_tee} -setup {
	button .b -text right_tee
} -body {
	.b configure -cursor right_tee
} -cleanup {
	destroy .b
} -result {}
test cursor-6.51 {check cursor-font cursor rightbutton} -setup {
	button .b -text rightbutton
} -body {
	.b configure -cursor rightbutton
} -cleanup {
	destroy .b
} -result {}
test cursor-6.52 {check cursor-font cursor rtl_logo} -setup {
	button .b -text rtl_logo
} -body {
	.b configure -cursor rtl_logo
} -cleanup {
	destroy .b
} -result {}
test cursor-6.53 {check cursor-font cursor sailboat} -setup {
	button .b -text sailboat
} -body {
	.b configure -cursor sailboat
} -cleanup {
	destroy .b
} -result {}
test cursor-6.54 {check cursor-font cursor sb_down_arrow} -setup {
	button .b -text sb_down_arrow
} -body {
	.b configure -cursor sb_down_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.55 {check cursor-font cursor sb_h_double_arrow} -setup {
	button .b -text sb_h_double_arrow
} -body {
	.b configure -cursor sb_h_double_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.56 {check cursor-font cursor sb_left_arrow} -setup {
	button .b -text sb_left_arrow
} -body {
	.b configure -cursor sb_left_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.57 {check cursor-font cursor sb_right_arrow} -setup {
	button .b -text sb_right_arrow
} -body {
	.b configure -cursor sb_right_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.58 {check cursor-font cursor sb_up_arrow} -setup {
	button .b -text sb_up_arrow
} -body {
	.b configure -cursor sb_up_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.59 {check cursor-font cursor sb_v_double_arrow} -setup {
	button .b -text sb_v_double_arrow
} -body {
	.b configure -cursor sb_v_double_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.60 {check cursor-font cursor shuttle} -setup {
	button .b -text shuttle
} -body {
	.b configure -cursor shuttle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.61 {check cursor-font cursor sizing} -setup {
	button .b -text sizing
} -body {
	.b configure -cursor sizing
} -cleanup {
	destroy .b
} -result {}
test cursor-6.62 {check cursor-font cursor spider} -setup {
	button .b -text spider
} -body {
	.b configure -cursor spider
} -cleanup {
	destroy .b
} -result {}
test cursor-6.63 {check cursor-font cursor spraycan} -setup {
	button .b -text spraycan
} -body {
	.b configure -cursor spraycan
} -cleanup {
	destroy .b
} -result {}
test cursor-6.64 {check cursor-font cursor star} -setup {
	button .b -text star
} -body {
	.b configure -cursor star
} -cleanup {
	destroy .b
} -result {}
test cursor-6.65 {check cursor-font cursor target} -setup {
	button .b -text target
} -body {
	.b configure -cursor target
} -cleanup {
	destroy .b
} -result {}
test cursor-6.66 {check cursor-font cursor tcross} -setup {
	button .b -text tcross
} -body {
	.b configure -cursor tcross
} -cleanup {
	destroy .b
} -result {}
test cursor-6.67 {check cursor-font cursor top_left_arrow} -setup {
	button .b -text top_left_arrow
} -body {
	.b configure -cursor top_left_arrow
} -cleanup {
	destroy .b
} -result {}
test cursor-6.68 {check cursor-font cursor top_left_corner} -setup {
	button .b -text top_left_corner
} -body {
	.b configure -cursor top_left_corner
} -cleanup {
	destroy .b
} -result {}
test cursor-6.69 {check cursor-font cursor top_right_corner} -setup {
	button .b -text top_right_corner
} -body {
	.b configure -cursor top_right_corner
} -cleanup {
	destroy .b
} -result {}
test cursor-6.70 {check cursor-font cursor top_side} -setup {
	button .b -text top_side
} -body {
	.b configure -cursor top_side
} -cleanup {
	destroy .b
} -result {}
test cursor-6.71 {check cursor-font cursor top_tee} -setup {
	button .b -text top_tee
} -body {
	.b configure -cursor top_tee
} -cleanup {
	destroy .b
} -result {}
test cursor-6.72 {check cursor-font cursor trek} -setup {
	button .b -text trek
} -body {
	.b configure -cursor trek
} -cleanup {
	destroy .b
} -result {}
test cursor-6.73 {check cursor-font cursor ul_angle} -setup {
	button .b -text ul_angle
} -body {
	.b configure -cursor ul_angle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.74 {check cursor-font cursor umbrella} -setup {
	button .b -text umbrella
} -body {
	.b configure -cursor umbrella
} -cleanup {
	destroy .b
} -result {}
test cursor-6.75 {check cursor-font cursor ur_angle} -setup {
	button .b -text ur_angle
} -body {
	.b configure -cursor ur_angle
} -cleanup {
	destroy .b
} -result {}
test cursor-6.76 {check cursor-font cursor watch} -setup {
	button .b -text watch
} -body {
	.b configure -cursor watch
} -cleanup {
	destroy .b
} -result {}
test cursor-6.77 {check cursor-font cursor xterm} -setup {
	button .b -text xterm
} -body {
	.b configure -cursor xterm
} -cleanup {
	destroy .b
} -result {}


# Test cursor named "none", it is not defined in
# the X cursor table. It is defined in a Tk specific
# table of named cursors and should be available on
# all platforms.

test cursor-6.78 {test cursor named "none"} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b cget -cursor
} -cleanup {
    destroy .b
} -result none

test cursor-6.79 {test cursor named "none"} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b configure -cursor {}
    .b cget -cursor
} -cleanup {
    destroy .b
} -result {}

test cursor-6.80 {test cursor named "none"} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b configure -cursor {}
    .b configure -cursor none
    .b cget -cursor
} -cleanup {
    destroy .b
} -result none

test cursor-6.81 {test cursor named "none"} -setup {
    button .b -text CButton
} -body {
    # Setting fg and bg does nothing for the none cursor
    # because it displays no fg or bg pixels.
    set results [list]
    .b configure -cursor none
    lappend results [.b cget -cursor]




|
|



<



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
<


>
|


<
<
|
|
<
<

|


>



<
<
|
|
<
<

|

>




<
<
|

|
<
<
|
>
|
|
<
<
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
|
<
|
>
>
>
|
<
>
|
|
<
|
|
<
<
<
<
|
<
|
<
|
|
|
<

|
<
<

<
|



>







|

|
|
<
<
<
|

|

|











<
<
<
|


>










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
<
|
|
|
<
|
|
|
>
|
<
|
<
|
|
|
<
<
|
<
<
|
<
|
<
|
|
<
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
|
<
<
|
<
<
|
<
<
<
|
<
<
|
<
|
<
|
<
<
|
<
<
<
|
|
<
|
<
<
<
|
<
<
|
<
<
<
|
<
<
|
<
<
<
|
|
<
<
<
<
<
|
<
<
|
<
<
<
|
|
<
|
<
|
<
|
<
<
|
<
|
<
|
|
<
|
<
<
<
|
<
<
|
|
<
|
|
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>





>
|








|









|










|







1
2
3
4
5
6
7
8
9

10
11
12
13


































14
15
16


17
18
19
20
21
22


23
24


25
26
27
28
29
30
31
32


33
34


35
36
37
38
39
40
41
42


43
44
45


46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77




78

79
80
81
82
83

84
85
86

87
88




89

90

91
92
93

94
95


96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136
137
138
139
140
141
142




































































































143
144
145

146
147
148

149
150
151
152
153

154

155
156
157


158


159

160

161
162

163






164




165






166






167






168






169






170





171







172












173
174





175






176






177







178






179






180






181






182








183




184

185
186


187


188



189


190

191

192


193



194
195

196



197


198



199


200



201
202





203


204



205
206

207

208

209


210

211

212
213

214



215


216
217

218
219
220

221





222











223
224
225
226
227














228
229





































































































































230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# This file is a Tcl script to test out the procedures in the file
# tkCursor.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]


































testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

test cursor-1.1 {Tk_AllocCursorFromObj - converting internal reps} {testcursor} {


    set x watch
    lindex $x 0
    destroy .b1
    button .b1 -cursor $x
    lindex $x 0
    testcursor watch


} {{1 0}}
test cursor-1.2 {Tk_AllocCursorFromObj - discard stale cursor} {testcursor} {


    set x watch
    destroy .b1 .b2
    button .b1 -cursor $x
    destroy .b1
    set result {}
    lappend result [testcursor watch]
    button .b2 -cursor $x
    lappend result [testcursor watch]


} {{} {{1 1}}}
test cursor-1.3 {Tk_AllocCursorFromObj - reuse existing cursor} {testcursor} {


    set x watch
    destroy .b1 .b2
    button .b1 -cursor $x
    set result {}
    lappend result [testcursor watch]
    button .b2 -cursor $x
    pack .b1 .b2 -side top
    lappend result [testcursor watch]


} {{{1 1}} {{2 1}}}

test cursor-2.1 {Tk_GetCursor procedure} {


    destroy .b1
    list [catch {button .b1 -cursor bad_name} msg] $msg
} {1 {bad cursor spec "bad_name"}}
test cursor-2.2 {Tk_GetCursor procedure} {


    destroy .b1
    list [catch {button .b1 -cursor @xyzzy} msg] $msg
} {1 {bad cursor spec "@xyzzy"}}
# Next two tests need a helper file with a very specific name and
# controlled format.
set wincur(data_octal) {
    000 000 002 000 001 000 040 040 000 000 007 000 007 000 060 001
    000 000 026 000 000 000 050 000 000 000 040 000 000 000 100 000
    000 000 001 000 001 000 000 000 000 000 000 000 000 000 000 000
    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
    000 000 377 377 377 000 000 000 000 000 000 000 000 000 000 000
    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
    000 000 000 000 000 000 000 000 000 000 160 016 000 000 170 036
    000 000 174 076 000 000 076 174 000 000 037 370 000 000 017 360
    000 000 007 340 000 000 007 340 000 000 017 360 000 000 037 370
    000 000 076 174 000 000 174 076 000 000 170 036 000 000 160 016
    000 000 000 000 000 000 377 377 377 377 377 377 377 377 377 377
    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
    377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
    377 377 377 377 377 377 017 360 377 377 007 340 377 377 003 300
    377 377 001 200 377 377 200 001 377 377 300 003 377 377 340 007
    377 377 360 017 377 377 360 017 377 377 340 007 377 377 300 003
    377 377 200 001 377 377 001 200 377 377 003 300 377 377 007 340
    377 377 017 360 377 377
}




set wincur(data_binary) {}

foreach wincur(num) $wincur(data_octal) {
    append wincur(data_binary) [binary format c [scan $wincur(num) %o]]
}
set wincur(dir) [makeDirectory {dir with spaces}]
set wincur(file) [makeFile $wincur(data_binary) "test file.cur" $wincur(dir)]

test cursor-2.3 {Tk_GetCursor procedure: cursor specs are lists} win {
    destroy .b1
    button .b1 -cursor [list @$wincur(file)]

} {.b1}
test cursor-2.4 {Tk_GetCursor procedure: cursor specs are lists} win {




    destroy .b1

    button .b1 -cursor @[regsub -all {[][ \\{}""$#]} $wincur(file) {\\&}]

} {.b1}
removeDirectory $wincur(dir)
unset wincur


test cursor-3.1 {Tk_FreeCursorFromObj - reference counts} {testcursor} {


    set x heart

    destroy .b1 .b2 .b3
    button .b1 -cursor $x
    button .b3 -cursor $x
    button .b2 -cursor $x
    set result {}
    lappend result [testcursor heart]
    destroy .b1
    lappend result [testcursor heart]
    destroy .b2
    lappend result [testcursor heart]
    destroy .b3
    lappend result [testcursor heart]
} {{{3 1}} {{2 1}} {{1 1}} {}}

test cursor-4.1 {FreeCursorObjProc} {testcursor failsOnUbuntu failsOnQuarz} {
    destroy .b



    set x [format heart]
    button .b -cursor $x
    set y [format heart]
    .b configure -cursor $y
    set z [format heart]
    .b configure -cursor $z
    set result {}
    lappend result [testcursor heart]
    set x red
    lappend result [testcursor heart]
    set z 32
    lappend result [testcursor heart]
    destroy .b
    lappend result [testcursor heart]
    set y bogus
    set result



} {{{1 3}} {{1 2}} {{1 1}} {}}

# -------------------------------------------------------------------------

test cursor-5.1 {assert consistent cursor configuration command} -setup {
    button .b
} -body {
    .b configure -cursor {watch red black}
} -cleanup {
    destroy .b
} -result {}

# -------------------------------------------------------------------------
# Check for the standard set of cursors.





































































































foreach {testName cursor} {
    cursor-6.1  X_cursor

    cursor-6.2  arrow
    cursor-6.3  based_arrow_down
    cursor-6.4  based_arrow_up

    cursor-6.5  boat
    cursor-6.6  bogosity
    cursor-6.7  bottom_left_corner
    cursor-6.8  bottom_right_corner
    cursor-6.9  bottom_side

    cursor-6.10 bottom_tee

    cursor-6.11 box_spiral
    cursor-6.12 center_ptr
    cursor-6.13 circle


    cursor-6.14 clock


    cursor-6.15 coffee_mug

    cursor-6.16 cross

    cursor-6.17 cross_reverse
    cursor-6.18 crosshair

    cursor-6.19 diamond_cross






    cursor-6.20 dot




    cursor-6.21 dotbox






    cursor-6.22 double_arrow






    cursor-6.23 draft_large






    cursor-6.24 draft_small






    cursor-6.25 draped_box






    cursor-6.26 exchange





    cursor-6.27 fleur







    cursor-6.28 gobbler












    cursor-6.29 gumby
    cursor-6.30 hand1





    cursor-6.31 hand2






    cursor-6.32 heart






    cursor-6.33 icon







    cursor-6.34 iron_cross






    cursor-6.35 left_ptr






    cursor-6.36 left_side






    cursor-6.37 left_tee






    cursor-6.38 leftbutton








    cursor-6.39 ll_angle




    cursor-6.40 lr_angle

    cursor-6.41 man
    cursor-6.42 middlebutton


    cursor-6.43 mouse


    cursor-6.44 pencil



    cursor-6.45 pirate


    cursor-6.46 plus

    cursor-6.47 question_arrow

    cursor-6.48 right_ptr


    cursor-6.49 right_side



    cursor-6.50 right_tee
    cursor-6.51 rightbutton

    cursor-6.52 rtl_logo



    cursor-6.53 sailboat


    cursor-6.54 sb_down_arrow



    cursor-6.55 sb_h_double_arrow


    cursor-6.56 sb_left_arrow



    cursor-6.57 sb_right_arrow
    cursor-6.58 sb_up_arrow





    cursor-6.59 sb_v_double_arrow


    cursor-6.60 shuttle



    cursor-6.61 sizing
    cursor-6.62 spider

    cursor-6.63 spraycan

    cursor-6.64 star

    cursor-6.65 target


    cursor-6.66 tcross

    cursor-6.67 top_left_arrow

    cursor-6.68 top_left_corner
    cursor-6.69 top_right_corner

    cursor-6.70 top_side



    cursor-6.71 top_tee


    cursor-6.72 trek
    cursor-6.73 ul_angle

    cursor-6.74 umbrella
    cursor-6.75 ur_angle
    cursor-6.76 watch

    cursor-6.77 xterm





} {











    test $testName "check cursor-font cursor $cursor" -setup {
	button .b -text $cursor
    } -body {
	.b configure -cursor $cursor
    } -cleanup {














	destroy .b
    } -result {}





































































































































}

# Test cursor named "none", it is not defined in
# the X cursor table. It is defined in a Tk specific
# table of named cursors and should be available on
# all platforms.

test cursor-6.80 {} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b cget -cursor
} -cleanup {
    destroy .b
} -result none

test cursor-6.81 {} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b configure -cursor {}
    .b cget -cursor
} -cleanup {
    destroy .b
} -result {}

test cursor-6.82 {} -setup {
    button .b -text CButton
} -body {
    .b configure -cursor none
    .b configure -cursor {}
    .b configure -cursor none
    .b cget -cursor
} -cleanup {
    destroy .b
} -result none

test cursor-6.83 {} -setup {
    button .b -text CButton
} -body {
    # Setting fg and bg does nothing for the none cursor
    # because it displays no fg or bg pixels.
    set results [list]
    .b configure -cursor none
    lappend results [.b cget -cursor]
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840

841
842


843
844
845
846
} -cleanup {
    destroy .b
    unset results
} -result {none {none blue} {none blue green} {}}

# -------------------------------------------------------------------------
# Check the Windows specific cursors
test cursor-7.1 {check Windows cursor no} -constraints win -setup {
	button .b -text no
} -body {
	.b configure -cursor no
} -cleanup {
	destroy .b
} -result {}
test cursor-7.2 {check Windows cursor starting} -constraints win -setup {
	button .b -text starting
} -body {
	.b configure -cursor starting
} -cleanup {
	destroy .b
} -result {}
test cursor-7.3 {check Windows cursor size} -constraints win -setup {
	button .b -text size
} -body {
	.b configure -cursor size
} -cleanup {
	destroy .b
} -result {}
test cursor-7.4 {check Windows cursor size_ne_sw} -constraints win -setup {
	button .b -text size_ne_sw
} -body {

	.b configure -cursor size_ne_sw
} -cleanup {
	destroy .b
} -result {}
test cursor-7.5 {check Windows cursor size_ns} -constraints win -setup {
	button .b -text size_ns
} -body {
	.b configure -cursor size_ns
} -cleanup {
	destroy .b
} -result {}
test cursor-7.6 {check Windows cursor size_nw_se} -constraints win -setup {
	button .b -text size_nw_se
} -body {
	.b configure -cursor size_nw_se
} -cleanup {
	destroy .b
} -result {}
test cursor-7.7 {check Windows cursor size_we} -constraints win -setup {
	button .b -text size_we
} -body {
	.b configure -cursor size_we
} -cleanup {
	destroy .b
} -result {}
test cursor-7.8 {check Windows cursor uparrow} -constraints win -setup {
	button .b -text uparrow
} -body {
	.b configure -cursor uparrow
} -cleanup {
	destroy .b
} -result {}
test cursor-7.9 {check Windows cursor wait} -constraints win -setup {
	button .b -text wait
} -body {
	.b configure -cursor wait
} -cleanup {
	destroy .b
} -result {}


# -------------------------------------------------------------------------



# cleanup
cleanupTests
return







|
<
|
|
<
<
<
<
|
<
|
<
<
<
<
|
<
|
<
<
<
|
|
<
>
|
|
<
<
|
|
|
|
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>


>
>




282
283
284
285
286
287
288
289

290
291




292

293




294

295



296
297

298
299
300


301
302
303
304
305
306
307




























308
309
310
311
312
313
314
315
316
} -cleanup {
    destroy .b
    unset results
} -result {none {none blue} {none blue green} {}}

# -------------------------------------------------------------------------
# Check the Windows specific cursors


foreach {testName cursor} {
    cursor-7.1 no




    cursor-7.2 starting

    cursor-7.3 size




    cursor-7.4 size_ne_sw

    cursor-7.5 size_ns



    cursor-7.6 size_nw_se
    cursor-7.7 size_we

    cursor-7.8 uparrow
    cursor-7.9 wait
} {


    test $testName "check Windows cursor $cursor" -constraints win -setup {
	button .b -text $cursor
    } -body {
	.b configure -cursor $cursor
    } -cleanup {
	destroy .b
    } -result {}




























}

# -------------------------------------------------------------------------

destroy .t

# cleanup
cleanupTests
return

Changes to tests/dialog.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# This file is a Tcl script to test out Tk's "tk_dialog" command.
# It is organized in the standard fashion for Tcl tests.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

test dialog-1.1 {tk_dialog command} -body {
    tk_dialog
} -match glob -returnCodes error -result {wrong # args: should be "tk_dialog w title text bitmap default *"}
test dialog-1.2 {tk_dialog command} -body {
    tk_dialog foo foo foo foo foo
} -returnCodes error -result {bad window path name "foo"}
test dialog-1.3 {tk_dialog command} -body {
    tk_dialog .d foo foo fooBitmap foo
} -cleanup {
    destroy .d

} -returnCodes error -result {bitmap "fooBitmap" not defined}


test dialog-2.1 {tk_dialog operation} -setup {
    proc PressButton {btn} {
        if {![winfo ismapped $btn]} {
            update
        }
        event generate $btn <Enter>
        event generate $btn <Button-1> -x 5 -y 5
        event generate $btn <ButtonRelease-1> -x 5 -y 5
    }
} -body {







    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 PressButton .d.button0
    set res [tk_dialog .d foo foo info 0 click]
    after cancel $x
    return $res
} -cleanup {
    destroy .d
} -result 0
test dialog-2.2 {tk_dialog operation} -setup {
    proc HitReturn {w} {
        event generate $w <Enter>
        focus -force $w
        event generate $w <Key> -keysym Return
    }
} -body {
    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 HitReturn .d
    set res [tk_dialog .d foo foo info 1 click default]
    after cancel $x
    return $res
} -cleanup {
    destroy .d
} -result 1
test dialog-2.3 {tk_dialog operation} -body {
    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 destroy .d
    set res [tk_dialog .d foo foo info 0 click]
    after cancel $x
    return $res
} -cleanup {
    destroy .b
} -result -1

cleanupTests
return







<


|
|
|
|
|
|
|
<

>
|

<
<
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>




|
|
<
<
|
<
<
<
<
<
<




|
|
<
<
|




|
|
<
<



<
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15

16
17
18
19


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


42






43
44
45
46
47
48


49
50
51
52
53
54
55


56
57
58

# This file is a Tcl script to test out Tk's "tk_dialog" command.
# It is organized in the standard fashion for Tcl tests.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


test dialog-1.1 {tk_dialog command} -body {
    list [catch {tk_dialog} msg] $msg
} -match glob -result {1 {wrong # args: should be "tk_dialog w title text bitmap default *"}}
test dialog-1.2 {tk_dialog command} {
    list [catch {tk_dialog foo foo foo foo foo} msg] $msg
} {1 {bad window path name "foo"}}
test dialog-1.3 {tk_dialog command} {
    set res [list [catch {tk_dialog .d foo foo fooBitmap foo} msg] $msg]

    destroy .d
    set res
} {1 {bitmap "fooBitmap" not defined}}



proc PressButton {btn} {
    if {![winfo ismapped $btn]} {
	update
    }
    event generate $btn <Enter>
    event generate $btn <1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc HitReturn {w} {
    event generate $w <Enter>
    focus -force $w
    event generate $w <KeyPress> -keysym Return
}

test dialog-2.0 {tk_dialog operation} {
    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 PressButton .d.button0
    set res [tk_dialog .d foo foo info 0 click]
    after cancel $x
    set res
} {0}


test dialog-2.1 {tk_dialog operation} {






    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 HitReturn .d
    set res [tk_dialog .d foo foo info 1 click default]
    after cancel $x
    set res
} {1}


test dialog-2.2 {tk_dialog operation} {
    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 destroy .d
    set res [tk_dialog .d foo foo info 0 click]
    after cancel $x
    set res
} {-1}



cleanupTests
return

Changes to tests/embed.test.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37


38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60


61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83




84
85
86
87
88
# This file is a Tcl script to test out embedded Windows.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands



test embed-1.1 {TkpUseWindow procedure, bad window identifier} -setup {
    deleteWindows
} -body {
    toplevel .t -use xyz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "xyz"}

test embed-1.2 {CreateFrame procedure, bad window identifier} -setup {
    deleteWindows
} -body {
    toplevel .t -container xyz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected boolean value but got "xyz"}

test embed-1.3 {CreateFrame procedure, both -use and -container is invalid} -setup {

    deleteWindows
} -body {
    toplevel .container -container 1
    toplevel .t -use [winfo id .container] -container 1
} -cleanup {
    deleteWindows
} -returnCodes error -result {windows cannot have both the -use and the -container option set}



# testing window embedding for win platforms

test embed-1.4.win {TkpUseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}
# testing window embedding for win platforms
test embed-1.5.win {TkpUseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}



# testing window embedding for other than win platforms

test embed-1.4.nonwin {TkpUseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".container" doesn't have -container option set}
# testing window embedding for other than win platforms
test embed-1.5.nonwin {TkpUseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".container" doesn't have -container option set}






cleanupTests
return




|
|



<



>

|

<
|
<
<
|

|

<
|
<
<
|

|
>

<

|
|
<
|

>
>
|
>
|
<
<

<

|
<
<
|
|
|
<
<

<

|
<
<
|

>
>
|
>
|
<
<

<

|
<
<
|
|
|
<
<

<

|
<
<
|

>
>
>
>



<

1
2
3
4
5
6
7

8
9
10
11
12
13
14

15


16
17
18
19

20


21
22
23
24
25

26
27
28

29
30
31
32
33
34
35


36

37
38


39
40
41


42

43
44


45
46
47
48
49
50
51


52

53
54


55
56
57


58

59
60


61
62
63
64
65
66
67
68
69

70
# This file is a Tcl script to test out embedded Windows.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

global tcl_platform

test embed-1.1 {TkpUseWindow procedure, bad window identifier} {
    deleteWindows

    list [catch {toplevel .t -use xyz} msg] $msg


} {1 {expected integer but got "xyz"}}

test embed-1.2 {CreateFrame procedure, bad window identifier} {
    deleteWindows

    list [catch {toplevel .t -container xyz} msg] $msg


} {1 {expected boolean value but got "xyz"}}

test embed-1.3 {CreateFrame procedure, both -use and
        -container is invalid } {
    deleteWindows

    toplevel .container -container 1
    list [catch {toplevel .t -use [winfo id .container] \
        -container 1} msg] $msg

} {1 {A window cannot have both the -use and the -container option set.}}

if {$tcl_platform(platform) == "windows"} {

# testing window embedding for Windows platform

test embed-1.4.win {TkpUseWindow procedure, -container must be set} {


    deleteWindows

    toplevel .container
    list [catch {toplevel .embd -use [winfo id .container]} err] $err


} {1 {the window to use is not a Tk container}}

test embed-1.5.win {TkpUseWindow procedure, -container must be set} {


    deleteWindows

    frame .container
    list [catch {toplevel .embd -use [winfo id .container]} err] $err


} {1 {the window to use is not a Tk container}}

} else {

# testing window embedding for other platforms

test embed-1.4.nonwin {TkpUseWindow procedure, -container must be set} {


    deleteWindows

    toplevel .container
    list [catch {toplevel .embd -use [winfo id .container]} err] $err


} {1 {window ".container" doesn't have -container option set}}

test embed-1.5.nonwin {TkpUseWindow procedure, -container must be set} {


    deleteWindows

    frame .container
    list [catch {toplevel .embd -use [winfo id .container]} err] $err


} {1 {window ".container" doesn't have -container option set}}

}

# FIXME: test cases common to unixEmbed.test and macEmbed.test should
# be moved here.

cleanupTests
return


Changes to tests/entry.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235




236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281


282
283


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361


362
363
364
365


366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

654
655

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863

864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036




1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565

1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

1595
1596
1597
1598
1599
1600
1601


1602

1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629


1630

1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686

1687




1688
1689



1690

1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752


1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804

1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820

1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883

1884






1885


1886
1887

1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942


1943
1944
1945

1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128

2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352

2353

2354


2355
2356
2357
2358
2359
2360
2361
2362
2363
2364



2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377

2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424

2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
2506
2507

2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522

2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725


2726
2727
2728
2729
2730


2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759


2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780

2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796


2797
2798
2799

2800
2801
2802

2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881



2882
2883

2884
2885
2886
2887
2888
2889
2890
2891
2892

2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916

2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929

2930
2931

2932
2933
2934
2935



2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961

2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974

2975
2976
2977

2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989

2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001

3002
3003
3004
3005
3006
3007

3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021

3022
3023
3024
3025
3026


3027
3028

3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057









3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155

3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336



3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358



3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377






3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441

3442
3443
3444
3445
3446
3447

3448
3449
3450
3451
3452
3453
3454

3455
3456
3457
3458
3459
3460
3461
3462
3463
3464

3465
3466
3467
3468
3469
3470
3471
3472
3473

3474
3475
3476
3477
3478
3479
3480
3481
3482
3483

3484
3485
3486
3487
3488
3489
3490
3491

3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506

3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518

3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614

3615
3616
3617
3618
3619
3620
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        return 1
}
proc doval2 {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        set ::e mydata
        return 1
}
proc doval3 {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        return 0
}

set cy [font metrics {Courier -12} -linespace]


test entry-1.1 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -background #ff0000
    .e cget -background
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.2 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}


test entry-1.3 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-1.4 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}


test entry-1.5 {configuration option: "bg" for entry} -setup {

    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bg #ff0000
    .e cget -bg
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.6 {configuration option: "bg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.7 {configuration option: "borderwidth" for entry} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -borderwidth 1.3
    .e cget -borderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.8 {configuration option: "borderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.9 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -cursor arrow
    .e cget -cursor
} -cleanup {
    destroy .e
} -result {arrow}
test entry-1.10 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}

test entry-1.11 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {

    .e configure -disabledbackground green
    .e cget -disabledbackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.12 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.13 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledforeground blue
    .e cget -disabledforeground
} -cleanup {
    destroy .e
} -result {blue}
test entry-1.14 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.15 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -exportselection yes
    .e cget -exportselection
} -cleanup {
    destroy .e
} -result 1
test entry-1.16 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}

test entry-1.17 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -fg #110022

    .e cget -fg
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.18 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -fg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.19 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e configure -font {Helvetica -12}
    .e cget -font
} -cleanup {




    destroy .e
} -result {Helvetica -12}
test entry-1.20 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}

test entry-1.21 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -foreground #110022
    .e cget -foreground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.22 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -foreground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.23 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightbackground #110022
    .e cget -highlightbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.24 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update


} -body {
    .e configure -highlightbackground non-existent


} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.25 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightcolor #110022
    .e cget -highlightcolor
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.26 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update

} -body {
    .e configure -highlightcolor non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.27 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness 6
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 6
test entry-1.28 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness -2
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 0
test entry-1.29 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.30 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertbackground #110022
    .e cget -insertbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.31 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.32 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -insertwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update


} -body {
    .e configure -insertborderwidth 1.3
    .e cget -insertborderwidth
} -cleanup {


    destroy .e
} -result 1
test entry-1.33 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {

    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}

test entry-1.34 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertofftime 100
    .e cget -insertofftime
} -cleanup {
    destroy .e
} -result 100
test entry-1.35 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.36 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertontime 100
    .e cget -insertontime
} -cleanup {
    destroy .e
} -result 100
test entry-1.37 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.38 {configuration option: "invalidcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -invalidcommand "any string"
    .e cget -invalidcommand
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.39 {configuration option: "invcmd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -invcmd "any string"
    .e cget -invcmd
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.40 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -justify right
    .e cget -justify
} -cleanup {
    destroy .e
} -result {right}
test entry-1.41 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -justify bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test entry-1.42 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -readonlybackground green
    .e cget -readonlybackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.43 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.44 {configuration option: "relief" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -relief flat
    .e cget -relief
} -cleanup {
    destroy .e
} -result {flat}

test entry-1.45 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectbackground #110022
    .e cget -selectbackground
} -cleanup {
    destroy .e
} -result {#110022}

test entry-1.46 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.47 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectborderwidth 1.3
    .e cget -selectborderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.48 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue

} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.49 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectforeground #110022
    .e cget -selectforeground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.50 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.51 {configuration option: "show" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -show *
    .e cget -show
} -cleanup {
    destroy .e
} -result {*}

test entry-1.52 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -state n
    .e cget -state
} -cleanup {
    destroy .e
} -result {normal}
test entry-1.53 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -state bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad state "bogus": must be disabled, normal, or readonly}

test entry-1.54 {configuration option: "takefocus" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -takefocus "any string"
    .e cget -takefocus
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.55 {configuration option: "textvariable" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -textvariable i
    .e cget -textvariable
} -cleanup {
    destroy .e
} -result {i}

test entry-1.56 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -width 402
    .e cget -width
} -cleanup {
    destroy .e
} -result 402
test entry-1.57 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test entry-1.58 {configuration option: "xscrollcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -xscrollcommand {Some command}
    .e cget -xscrollcommand
} -cleanup {
    destroy .e
} -result {Some command}

test entry-1.59 {configuration option: "-placeholder"} -setup {
    pack [entry .e]
} -body {
    .e configure -placeholder {Some text}
    .e cget -placeholder
} -cleanup {
    destroy .e
} -result {Some text}

test entry-1.60 {configuration option: "-placeholderforeground"} -setup {
    pack [entry .e]
} -body {
    .e configure -placeholder {Some text} -placeholderforeground red
    .e cget -placeholderforeground
} -cleanup {
    destroy .e
} -result {red}



test entry-2.1 {Tk_EntryCmd procedure} -body {
    entry

} -returnCodes error -result {wrong # args: should be "entry pathName ?-option value ...?"}
test entry-2.2 {Tk_EntryCmd procedure} -body {
    entry gorp
} -returnCodes error -result {bad window path name "gorp"}
test entry-2.3 {Tk_EntryCmd procedure} -body {
    entry .e
    pack .e
    update
    list [winfo exists .e] [winfo class .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {1 Entry .e}
test entry-2.4 {Tk_EntryCmd procedure} -body {
    entry .e -gorp foo
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-gorp"}
test entry-2.4.1 {Tk_EntryCmd procedure} -body {
    catch {entry .e -gorp foo}
    list [winfo exists .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {0 {}}
test entry-2.5 {Tk_EntryCmd procedure} -body {
    entry .e
} -cleanup {
    destroy .e
} -result {.e}


test entry-3.1 {EntryWidgetCmd procedure} -setup {
    entry .e
    pack .e
    update
} -body {
    .e
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e option ?arg ...?"}
test entry-3.2 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.3 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.4 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e bbox bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}
test entry-3.5 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
   .e bbox 0
} -cleanup {
    destroy .e
} -result [list 5 5 0 $cy]

# Previously the result was count using previousli counted font measurements
# and metrics. It was changed to less verbose solution - the result is the one
# that passes fonts constraint (this concerns tests 3.6, 3.7, 3.8, 3.10)
test entry-3.6 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no utf chars
    .e insert 0 "abc"
    list [.e bbox 3] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{19 5 7 13} {19 5 7 13}}
test entry-3.7 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab乎"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab乎c"
    .e bbox 3
} -cleanup {
    destroy .e
} -result {31 5 7 13}
test entry-3.9 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no chars
    .e bbox end
} -cleanup {
    destroy .e
} -result "5 5 0 $cy"

test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert 0 "abcdefghij乎klmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{5 5 7 13} {12 5 7 13} {75 5 12 13} {122 5 7 13}}
test entry-3.11 {EntryWidgetCmd procedure, "cget" widget command} -setup {
    entry .e
} -body {
    .e cget
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e cget option"}
test entry-3.12 {EntryWidgetCmd procedure, "cget" widget command} -setup {

    entry .e
} -body {
    .e cget a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e cget option"}
test entry-3.13 {EntryWidgetCmd procedure, "cget" widget command} -setup {
    entry .e
} -body {
    .e cget -gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-gorp"}
test entry-3.14 {EntryWidgetCmd procedure, "cget" widget command} -setup {
    entry .e
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-3.15 {EntryWidgetCmd procedure, "configure" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 38
test entry-3.16 {EntryWidgetCmd procedure, "configure" widget command} -setup {
    entry .e
} -body {
    .e configure -foo
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-foo"}
test entry-3.17 {EntryWidgetCmd procedure, "configure" widget command} -setup {
    entry .e
} -body {
    .e configure -bd 4
    .e configure -bg #ffffff
    lindex [.e configure -bd] 4
} -cleanup {
    destroy .e
} -result 4
test entry-3.18 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e delete
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e delete firstIndex ?lastIndex?"}
test entry-3.19 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e delete a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e delete firstIndex ?lastIndex?"}

test entry-3.20 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e delete foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.21 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e delete 0 bar
} -cleanup {

    destroy .e
} -returnCodes error -result {bad entry index "bar"}
test entry-3.22 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 2 4
    .e get
} -cleanup {
    destroy .e
} -result 014567890
test entry-3.23 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e insert end "01234567890"
    .e delete 6
    .e get
} -cleanup {
    destroy .e
} -result 0123457890
test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "01234乎67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345乎7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456乎890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "012347890" "0123457890" "012345890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26a {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.27 {EntryWidgetCmd procedure, "get" widget command} -setup {
    entry .e
} -body {
    .e get foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e get"}
test entry-3.28 {EntryWidgetCmd procedure, "icursor" widget command} -setup {
    entry .e
} -body {
    .e icursor
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e icursor pos"}
test entry-3.29 {EntryWidgetCmd procedure, "icursor" widget command} -setup {
    entry .e
} -body {
    .e icursor foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.30 {EntryWidgetCmd procedure, "icursor" widget command} -setup {
    entry .e
} -body {
    .e insert end "01234567890"
    .e icursor 4
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-3.31 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
} -body {
    .e in
} -cleanup {
    destroy .e
} -returnCodes error -result {ambiguous option "in": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}
test entry-3.32 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
} -body {
    .e index
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e index string"}
test entry-3.33 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
} -body {
    .e index foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.34 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e index 0
} -cleanup {
    destroy .e
} -returnCodes {ok} -match glob -result {*}
test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
# UTF

    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e
} -result {3 4 8}
test entry-3.36 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
    .e insert a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test entry-3.37 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {




    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test entry-3.38 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
    .e insert foo Text
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.39 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e insert 3 xxx
    .e get
} -cleanup {
    destroy .e
} -result {012xxx34567890}
test entry-3.40 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.40a {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.41 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test entry-3.42 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.43 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.44 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be mark or dragto}
test entry-3.45 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan mark 20.1
} -cleanup {
    destroy .e
} -returnCodes error -result {expected integer but got "20.1"}

# This test is non-portable because character sizes vary.

test entry-3.46 {EntryWidgetCmd procedure, "scan" widget command} -constraints {
    fonts
} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0
} -cleanup {
    destroy .e
} -result 2
test entry-3.47 {EntryWidgetCmd procedure, "select" widget command} -setup {
    entry .e
} -body {
    .e select
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection option ?index?"}
test entry-3.48 {EntryWidgetCmd procedure, "select" widget command} -setup {
    entry .e
} -body {
    .e select foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad selection option "foo": must be adjust, clear, from, present, range, or to}

test entry-3.49 {EntryWidgetCmd procedure, "select clear" widget command} -setup {
    entry .e
} -body {
    .e select clear gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection clear"}
test entry-3.50 {EntryWidgetCmd procedure, "select clear" widget command} -setup {
    entry .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-3.50.1 {EntryWidgetCmd procedure, "select clear" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    catch {selection get}
    selection own
} -cleanup {
    destroy .e
} -result {.e}

test entry-3.51 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
} -body {
    .e selection present foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection present"}
test entry-3.52 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.53 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.54 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
} -cleanup {
    destroy .e
} -result 0
test entry-3.55 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
} -body {
    .e select adjust x
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "x"}
test entry-3.56 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
} -body {
    .e select adjust 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection adjust index"}
test entry-3.57 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get
} -cleanup {
    destroy .e
} -result 123
test entry-3.58 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
    selection get
} -cleanup {
    destroy .e
} -result 234
test entry-3.59 {EntryWidgetCmd procedure, "selection from" widget command} -setup {
    entry .e
} -body {
    .e select from 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection from index"}

test entry-3.60 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
} -body {
    .e select range 2
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection range start end"}
test entry-3.61 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
} -body {
    .e selection range 2 3 4
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection range start end"}
test entry-3.62 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
} -body {
    .e insert end 0123456789
    .e select from 1
    .e select to 5
    .e select range 4 4
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-3.63 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]
} -cleanup {
    destroy .e
} -result {2 9 3}
test entry-3.64 {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state disabled
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {0 10}
test entry-3.64a {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state readonly
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 4}
test entry-3.64b {EntryWidgetCmd procedure, "selection to" widget command} -setup {
    entry .e
    pack .e
    update
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
} -body {

    .e select to 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection to index"}

test entry-3.65 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 5
    format {%.7f %.7f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.0537634 0.2688172}
test entry-3.66 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "gorp"}
test entry-3.67 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.107527 0.322581}
test entry-3.68 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo bar
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview moveto fraction"}
test entry-3.69 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "foo"}
test entry-3.70 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.505376 0.720430}
test entry-3.71 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview scroll 24
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview scroll number pages|units"}
test entry-3.72 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll gorp units
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "gorp"}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.193548 0.408602}
test entry-3.74 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.397849 0.612903}
test entry-3.75 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} -cleanup {
    destroy .e
} -result 32
test entry-3.76 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} -cleanup {
    destroy .e
} -result 29
test entry-3.77 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll 23 foobars
} -cleanup {
    destroy .e
} -returnCodes error -result {bad argument "foobars": must be pages or units}
test entry-3.78 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview eat 23 hamburgers
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "eat": must be moveto or scroll}
test entry-3.79 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview -1
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test entry-3.80 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 300
    .e index @0
} -cleanup {
    destroy .e
} -result 73
test entry-3.86 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e insert 10 
    update

# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:
# 0.106383 0.117021 0.117021

    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .11
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .12
    lappend x [format {%.6f} [lindex [.e xview] 0]]
} -cleanup {
    destroy .e
} -result {0.095745 0.106383 0.117021}

test entry-3.82 {EntryWidgetCmd procedure} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}

# The test below doesn't actually check anything directly, but if run
# with Purify or some other memory-allocation-checking program it will
# ensure that resources get properly freed.

test entry-4.1 {DestroyEntry procedure} -body {

    entry .e -textvariable x -show *
    pack .e
    .e insert end "Sample text"
    update
    destroy .e
} -result {}



test entry-5.1 {ConfigureEntry procedure, -textvariable} -body {

    set x 12345
    entry .e -textvariable x
    .e get
} -cleanup {
    destroy .e
} -result 12345
test entry-5.2 {ConfigureEntry procedure, -textvariable} -body {

    set x 12345
    entry .e -textvariable x
    set y abcde
    .e configure -textvariable y
    set x 54321
    .e get
} -cleanup {
    destroy .e
} -result {abcde}
test entry-5.3 {ConfigureEntry procedure, -textvariable} -setup {

    unset -nocomplain x
    entry .e
} -body {
    .e insert 0 "Some text"
    .e configure -textvariable x
    set x
} -cleanup {
    destroy .e
} -result {Some text}
test entry-5.4 {ConfigureEntry procedure, -textvariable} -setup {


    unset -nocomplain x

    entry .e
} -body {
    trace variable x w override

    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    unset x;
} -result {12345 12345}

test entry-5.5 {ConfigureEntry procedure} -setup {
    set x {}
    entry .e1
    entry .e2
} -body {
    .e2 insert end "This is some sample text"
    .e1 configure -exportselection false
    .e1 insert end "0123456789"
    pack .e1 .e2
    .e2 select from 0
    .e2 select to 10
    lappend x [selection get]
    .e1 select from 1
    .e1 select to 5
    lappend x [selection get]
    .e1 configure -exportselection 1
    lappend x [selection get]
    set x
} -cleanup {
    destroy .e1 .e2
} -result {{This is so} {This is so} 1234}
test entry-5.6 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-5.6.1 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    catch {selection get}
    list [.e index sel.first] [.e index sel.last]
} -cleanup {

    destroy .e




} -result {1 5}




test entry-5.7 {ConfigureEntry procedure} -setup {

    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}


test entry-5.8 {ConfigureEntry procedure} -constraints {
    fonts failsOnXQuarz
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -width 0 -font {Helvetica -12}
    .e insert end "0123"
    update
    .e configure -font {Helvetica -24}
    update
    winfo geom .e
} -cleanup {
    destroy .e
} -result {62x37+0+0}
test entry-5.9 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.10 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief flat
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.11 {ConfigureEntry procedure} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
# If "0" in selected font had 0 width, caused divide-by-zero error.


    .e configure -font {{open look glyph}}
    .e scan dragto 30
    update
} -cleanup {
    destroy .e
} -result {}

# No tests for DisplayEntry.

test entry-6.1 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.2 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e

    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify center -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.3 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify right -highlightthickness 3

    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.4 {EntryComputeGeometry procedure} -setup {

    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.5 {EntryComputeGeometry procedure} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5

    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.6 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 10
    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]
} -cleanup {
    destroy .e
} -result {5 6}
test entry-6.7 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 5
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {77 39}
test entry-6.8 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {116 39}
test entry-6.9 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {25 39}
test entry-6.10 {EntryComputeGeometry procedure} -constraints {
    unix fonts
} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12}

    pack .e






} -body {


    .e configure -bd 1 -relief raised -width 0 -show .
    .e insert 0 12345

    update
    set x [winfo reqwidth .e]
    .e configure -show X
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {23 53 43}
test entry-6.11 {EntryComputeGeometry procedure} -constraints {
    win
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -bd 1 -relief raised -width 0 -show . -font {helvetica 12}
    .e insert 0 12345
    update
    set x1 [winfo reqwidth .e]
	set x2 [expr {8+5*[font measure {helvetica 12} .]}]
	set x [expr {$x1 eq $x2}]
    .e configure -show X
	set x1 [winfo reqwidth .e]
	set x2 [expr {8+5*[font measure {helvetica 12} X]}]
    lappend x [expr {$x1 eq $x2}]
    .e configure -show ""
	set x1 [winfo reqwidth .e]
	set x2 [expr {8+[font measure {helvetica 12} 12345]}]
    lappend x [expr {$x1 eq $x2}]
} -cleanup {
    destroy .e
} -result {1 1 1}
test entry-6.12 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    catch {destroy .e}
    entry .e -font {Courier -12} -bd 2 -relief raised -width 20
    pack .e
} -body {
    .e insert end "012\t456\t"
    update
    list [.e index @80] [.e index @81] [.e index @115] [.e index @116]
} -cleanup {
    destroy .e
} -result {6 7 7 8}


test entry-7.1 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]


    .e insert 0 abcde
    .e insert 2 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test entry-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e insert 500 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test entry-7.3 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {5 9 5 8}
test entry-7.4 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.5 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.6 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 6 2 5}
test entry-7.7 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -xscrollcommand scroll
    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 7
test entry-7.8 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-7.9 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 7
test entry-7.10 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 4

test entry-7.11 {InsertChars procedure} -constraints {
    fonts
} -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e
} -cleanup {
    destroy .e
} -result 59


test entry-8.1 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 2 4
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test entry-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete -1 2
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test entry-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 3 1000
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test entry-8.4 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6 1 5}
test entry-8.5 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5 1 4}
test entry-8.6 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 2 1 5}
test entry-8.7 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.8 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 4 3 8}
test entry-8.9 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.10 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 5 5 8}
test entry-8.11 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 8 4 8}
test entry-8.12 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.13 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.14 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 4 6
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-8.15 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.16 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.17 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test entry-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
    # To check that deletion actually happened we measure the new width
    # of the widget, based on the measuring width of the remaining text ("xyy")
    # in the widget. For that purpose we have to mirror the code in tkEntry.c
    # for computation of the reqwidth
    # note: XPAD corresponds to the hardcoded    #define XPAD 1
    set XPAD 1
    set expected [expr { [font measure [.e cget -font] "xyy"] \
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) } ]
    expr {[winfo reqwidth .e] == $expected}

} -cleanup {

    destroy .e


    unset XPAD expected
} -result 1

test entry-9.1 {EntryValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    entry .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]



} -cleanup {
    destroy .e
    trace vdelete x w override
    unset x
} -result {12345 12345}


test entry-10.1 {EntrySetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    entry .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0
    pack .e
    .e configure -textvariable x

    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {ab 24}
test entry-10.2 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-10.3 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 7}
test entry-10.4 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 10}
test entry-10.5 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x

    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test entry-10.6 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 10
test entry-10.7 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
    update
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} -cleanup {
    destroy .e
} -result 3
test entry-10.8 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} -cleanup {
    destroy .e
} -result 5

test entry-11.1 {EntryEventProc procedure} -setup {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    pack .e
} -body {
    .e insert 0 abcdefg
    destroy .e
    update
} -cleanup {
    destroy .e
} -result {}
test entry-11.2 {EntryEventProc procedure} -setup {
    set x {}
} -body {
    entry .e1 -fg #112233
    rename .e1 .e2

    lappend x [winfo children .]
    lappend x [.e2 cget -fg]
    destroy .e1
    lappend x [info command .e*] [winfo children .]
} -cleanup {
    destroy .e1
} -result {.e1 #112233 {} {}}

test entry-12.1 {EntryCmdDeletedProc procedure} -body {

    button .b -text "xyz_123"
    rename .b {}
    list [info command .b*] [winfo children .]
} -cleanup {
    destroy .b
} -result {{} {}}


test entry-13.1 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update

    .e index end
} -cleanup {
    destroy .e
} -result 21
test entry-13.2 {GetEntryIndex procedure} -body {
    entry .e
    .e index abogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "abogus"}
test entry-13.3 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    .e index anchor
} -cleanup {
    destroy .e
} -result 1
test entry-13.4 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 4
    .e select to 1
    .e index anchor
} -cleanup {
    destroy .e
} -result 4
test entry-13.5 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} -cleanup {
    destroy .e
} -result 15
test entry-13.6 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ebogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ebogus"}
test entry-13.7 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e icursor 2
    .e index insert
} -cleanup {
    destroy .e
} -result 2
test entry-13.8 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ibogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ibogus"}
test entry-13.9 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6}






test entry-13.10 {GetEntryIndex procedure} -constraints x11 -body {
# On unix, when selection is cleared, entry widget's internal
# selection range is reset.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

test entry-13.11 {GetEntryIndex procedure} -constraints aquaOrWin32 -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    catch {selection get}
    .e index sel.first
} -cleanup {
    destroy .e
} -result 1

test entry-13.12 {GetEntryIndex procedure} -constraints x11 -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

# why when string in .e index changed to not beginning with s,
# it behaves differently?
test entry-13.12.1 {GetEntryIndex procedure} -constraints unix -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}

test entry-13.13 {GetEntryIndex procedure} -constraints win -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "sbogus"}

test entry-13.14 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e


    selection get
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}



test entry-13.14.1 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    catch {selection get}
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}

test entry-13.15 {GetEntryIndex procedure} -body {
    entry .e
    selection clear .e
    .e index @xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "@xyz"}



test entry-13.16 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @4
} -cleanup {
    destroy .e
} -result 4
test entry-13.17 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @11
} -cleanup {
    destroy .e

} -result 4
test entry-13.18 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @12
} -cleanup {
    destroy .e
} -result 5
test entry-13.19 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e


    .e insert 0 012345678901234567890
    .e xview 4
    update

    .e index @[expr {[winfo width .e] - 6}]
} -cleanup {
    destroy .e

} -result 8
test entry-13.20 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 5}]
} -cleanup {
    destroy .e
} -result 9
test entry-13.21 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @1000
} -cleanup {
    destroy .e
} -result 9
test entry-13.22 {GetEntryIndex procedure} -setup {
    entry .e
    pack .e
    update
} -body {
    .e index 1xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "1xyz"}
test entry-13.23 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index -1
} -cleanup {
    destroy .e
} -result 0
test entry-13.24 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 12
} -cleanup {
    destroy .e
} -result 12
test entry-13.25 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 49
} -cleanup {
    destroy .e
} -result 21
test entry-13.26 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    selection clear .e
    .e configure -show .
    .e insert 0 XXXYZZY
    pack .e
    update
    list [.e index @7] [.e index @8]
} -cleanup {
    destroy .e
} -result {0 1}

# XXX Still need to write tests for EntryScanTo and EntrySelectTo.





test entry-14.1 {EntryFetchSelection procedure} -body {

    entry .e
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get
} -cleanup {
    destroy .e
} -result {his is a test str}
test entry-14.2 {EntryFetchSelection procedure} -body {

    entry .e -show *
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get
} -cleanup {
    destroy .e
} -result {*****************}
test entry-14.3 {EntryFetchSelection procedure} -setup {
    set x {}
    for {set i 1} {$i <= 500} {incr i} {
        append x "This is line $i, out of 500\n"
}
} -body {
    entry .e
    .e insert end $x
    .e select from 0
    .e select to end
    string compare [selection get] $x
} -cleanup {
    destroy .e
} -result 0

test entry-15.1 {EntryLostSelection} -body {

    entry .e
    .e insert 0 "Text"
    .e select from 0
    .e select to 4
    set result [selection get]
    selection clear
    .e select from 0
    .e select to 4
    lappend result [selection get]
} -cleanup {
    destroy .e
} -result {Text Text}


# is scrollcommand needed here??
test entry-16.1 {EntryVisibleRange procedure} -constraints fonts  -body {

    entry .e -width 10 -font {Helvetica -12}
    pack .e
    update
    .e insert 0 "............................."



    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test entry-16.2 {EntryVisibleRange procedure} -constraints {
    unix fonts
} -body {
    entry .e -show X -width 10  -font {Helvetica -12}
    pack .e
    update
    .e insert 0 "............................."
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.275862}
test entry-16.3 {EntryVisibleRange procedure} -constraints {
    win
} -body {
    entry .e -show . -width 10  -font {Helvetica -12}
	pack .e
    update
    .e insert 0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}

test entry-16.4 {EntryVisibleRange procedure} -body {
    entry .e -show ""
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 1.000000}


test entry-17.1 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]

    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test entry-17.2 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 0123456789abcdef
    .e xview 3
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test entry-17.3 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.315789 0.842105}
test entry-17.4 {EntryUpdateScrollbar procedure} -setup {

    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    entry .e -width 5
    pack .e
    update idletasks
    .e configure -xscrollcommand thisisnotacommand
    vwait x
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}

} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
    (horizontal scrolling command executed by .e)}}




test entry-18.1 {Entry widget vs hiding} -setup {

    entry .e
} -body {
    set l [interp hidden]
    interp hide {} .e
    destroy .e
    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 == $res2}
} -result 1

##
## Entry widget VALIDATION tests
##
# The validation tests build each one upon the previous, so cascading
# failures aren't good
#

# 19.* test cases in previous version highly depended on the previous
# test cases. This was replaced by inserting recently set configurations
# that matters for the test case
test entry-19.1 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e









    .e insert 0 a
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 0 a {} a all key}

test entry-19.2 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a   ;# previous settings
    .e insert 1 b
    return $::vVals
} -cleanup {
    destroy .e
} -result {.e 1 1 ab a b all key}

test entry-19.3 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 ab   ;# previous settings
    .e insert end c
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 2 abc ab c all key}

test entry-19.4 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abc   ;# previous settings
    .e insert 1 123
    list $::vVals $::e
} -cleanup {
    destroy .e
} -result {{.e 1 1 a123bc abc 123 all key} a123bc}

test entry-19.5 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a123bc   ;# previous settings
    .e delete 2
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 2 a13bc a123bc 2 all key}

test entry-19.6 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a13bc   ;# previous settings
    .e configure -validate key
    .e delete 1 3
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 1 abc a13bc 13 key key}

test entry-19.7 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abc                 ;# previous settings
    set ::vVals {}

    .e insert end d
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.8 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e configure -validate focus    ;# previous settings
    .e insert end abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusin}

test entry-19.9 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd      ;# previous settings
    focus -force .e         ;# previous settings
    update                  ;# previous settings
# update necessary to process FocusIn event
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusout}

test entry-19.10 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusin}

test entry-19.11 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e             ;# previous settings
# update necessary to process FocusIn event
    update                      ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusout}

test entry-19.12 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test entry-19.13 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.14 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.15 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusout focusout}

# the same as 19.16 but added [.e validate] to returned list
test entry-19.16 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update



    list [.e validate] $::vVals
} -cleanup {
    destroy .e
} -result {1 {.e -1 -1 abcd abcd {} all forced}}


test entry-19.17 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::e newdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {focusout {.e -1 -1 newdata abcd {} focusout forced}}





# proc doval changed - returns 0
test entry-19.18 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e newdata                 ;# previous settings
    .e configure -validate all
    set ::e nextdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {none {.e -1 -1 nextdata newdata {} all forced}}







## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the entry textvar is also set
# proc doval2 used
test entry-19.19 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e
} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test entry-19.20 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings
    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] ;# prev
    .e validate                     ;# previous settings

    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test entry-19.21 {entry widget validation - bug 40e4bf6198} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate key \
        -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \
        -textvariable ::e
    pack .e
    set ::e origdata
    .e insert 0 A
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}}


##
## End validation tests
##

test entry-20.1 {widget deletion while active} -body {

    entry .e -validate all \
	    -validatecommand { destroy %W ; return 1 } \
	    -invalidcommand bell
    update
    .e insert 0 abc
    winfo exists .e
} -cleanup {

    destroy .e
} -result 0

test entry-20.2 {widget deletion while active} -body {
    entry .e -validate all \
	    -validatecommand { return 0 } \
	    -invalidcommand { destroy %W }
    .e insert 0 abc
    winfo exists .e
} -cleanup {

    destroy .e
} -result 0

test entry-20.3 {widget deletion while active} -body {
    entry .e -validate all \
	    -validatecommand { rename .e {} ; return 1 }
    .e insert 0 abc
    winfo exists .e
} -cleanup {

    destroy .e
} -result 0

test entry-20.4 {widget deletion while active} -body {
    entry .e -validate all \
	    -validatecommand { return 0 } \
	    -invalidcommand { rename .e {} }
    .e insert 0 abc
    winfo exists .e
} -cleanup {

    destroy .e
} -result 0

test entry-20.5 {widget deletion while active} -body {
    entry .e -validatecommand { destroy .e ; return 0 }
    .e validate
    winfo exists .e
} -cleanup {

    destroy .e
} -result 0

test entry-20.6 {widget deletion while active} -body {
    pack [entry .e]
    update
    .e config -xscrollcommand { destroy .e }
    update idle
    winfo exists .e
} -cleanup {
    destroy .e
} -result 0

test entry-20.7 {widget deletion with textvariable active} -body {
# SF bugs 607390 and 617446

    set FOO init
    entry .e -textvariable FOO -validate all \
	    -vcmd {%W configure -bg white; format 1}
    bind .e <Destroy> { set FOO hello }
    destroy .e
    winfo exists .e
} -cleanup {
    destroy .e
} -result 0


test entry-21.1 {selection present while disabled, bug 637828} -body {

    entry .e
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    set out [.e selection present]
    .e configure -state disabled
# still return 1 when disabled, because 'selection get' will work,
# but selection cannot be changed (new behavior since 8.4)
    .e select to 9
    lappend out [.e selection present] [selection get]
} -cleanup {
    destroy .e
} -result {1 1 345}

test entry-22.1 {lost namespaced textvar} -body {
    namespace eval test { variable foo {a b} }
    entry .e -textvariable ::test::foo
    namespace delete test
    set ::test::foo
} -cleanup {
    destroy .e
} -returnCodes error -result {can't read "::test::foo": no such variable}
test entry-22.2 {lost namespaced textvar} -body {
    namespace eval test { variable foo {a b} }
    entry .e -textvariable ::test::foo
    namespace delete test
    catch {.e insert end "more stuff"} result1
    catch {.e delete 5 end } result2
    catch {set ::test::foo} result3
    list [.e get] [.e cget -textvar] $result1 $result2 $result3
} -cleanup {
    destroy .e
} -result [list "a bmo" ::test::foo \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't read "::test::foo": no such variable}]

test entry-23.1 {error in trace proc attached to the textvariable} -setup {
    destroy .e
} -body {
    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    entry .e -textvariable myvar
    catch {.e insert end mystring} result1
    catch {.e delete 0} result2
    list $result1 $result2
} -cleanup {
    destroy .e
} -result [list {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!}]

test entry-24.1 {textvariable lives in a non-existing namespace} -setup {
    destroy .e
} -body {
    catch {entry .e -textvariable thisnsdoesntexist::myvar} result1
    set result1
} -cleanup {
  destroy .e
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}

test entry-25.1 {Bug [5d991b822e]} {
    # Want this not to segfault, or write to variable with empty name
    set var INIT
    entry .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
    info exists {}
} 0
test entry-25.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    entry .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}


# Gathered comments about lacks
# XXX Still need to write tests for EntryBlinkProc, EntryFocusProc,
# and EntryTextVarProc.
# No tests for DisplayEntry.
# XXX Still need to write tests for EntryScanTo and EntrySelectTo.
# No tests for EventuallyRedraw

# option clear

# cleanup
cleanupTests
return






|
|
|



<



<
<
<
<
<
<

|
|

<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
>

<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
<
<
>

<
>
|
|
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<

<
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<

<
<
<
<
<
<
|
<
|
<
<
<
|
|
<
<
<
<
|
|
<
|
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
<
>
|
<
<
|
<
|
<
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
>
>
>
>
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
|
<
|
<
<
<
<
<
|
>
>
|
<
>
>
|
<
<
|
|
<
<
<
<
|
|
<
<
|
<
<
|
<
>
|
|
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
>
>
|
<
<
<
>
>
|
<
<
<
|
<
<
<
<
>
|
<
|
<
<
<
|
|
|
|
|
|
<
<
<
|
<
|
<
<
<
<

<
<
<
<
<
<
<
<
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
<
<
|
|
|
>
|
<
|
|
|
|
|
|
|
|
|
<
<
|
|
<
<
<
|
<
|
<
<
<
<
<
>
<
<
<

<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
<
|
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
|
<
<
|
<
<
<
<
<
<
|
<
|
|
>
|
<
>
|
|
<
<
<
<
<
<
|
<
<
|
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
|
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
>
|
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
>
|
<
<
<
<
<
|
|
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
|
<
|
<
|
<
>
|
|
|
|
<
|
<
|
|
<
|
<
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<


|


<
<
<
<
<
<
|
|
<
<
|
<



<
<
|
|
<
<
|
<





<
<
|
|
<
<
|
<





<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
|
<



|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
<
<
|
|
<
<
|
|
<
<
|
<
<
<
<
|
>
|

<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<



<
<
|
|
<
<
|
<





<
<
|
|
<
<
|
<





<
<
|
|
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
<

>
|
<
<
<
|

<





|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
<
|
<
<
|
<
<
|
|
|
<





|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
|
<




|
<
<
|
<
<
|
<





|
|
<
|
<
<
|
<





|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<






<
<
|
|
<
<
|
<






<
<
|
|
<
<
|
<
<
|
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
|
<




|
<
<
|
|
<
<
|
<





<
<
|
|
<
<
|
<






<
<
|
|
<
<
|
<






<
<
|
<
<
<
|
|
|
<
>
|
<
<
|
<
|
<
<
<
<
<
<


<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<




<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<


<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<



<
<
|
|
<
<
<
<
<
<




<
<
|
|
<
<
<
<
<
<




|
<
<
|
<
<
<
<
<
<




|
<
<
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<


|

|
<
<
|
<
<
<
<
<
<


<
<
<
<
<
<
|
<
<
|
<
>
|
|
|
>







<
<
|
<
|
<
<
<
<
|
<
<
|





|
>





|

>
>
|
>



<
<
|
|
>






<
<
|
|
>
|

<



<
<
|
|
>
>
|
>
|
|

>


|
<
<
|
|
|
<
|
|
|
|
<
<
<
|
<
|
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<


<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
>
|
>
>
>
>
|
|
>
>
>
|
>
|

<
<

|
<

<

<
<
<
|
<
<
|
<
|
|

<
<


|


<
<
|
|
<
|
|

<
<



<
<
|
|
<
|
|

<
<



<
<
|
|
<
<
<
|
>
>
|


|
<
<



|
<
|
|

<
<
<



<
<
|
|
<
|
|
>

<
<
<



<
<
|
|
<
<
|
<
<
|
|
>



<
<
|
|
>
|

<
<




|
<
<
|
<
|
<
|
>




|
<
<
|
<
|
|

<
<




<
<
|
|
<
|
|

<
<



<
<
|
|
<
|
|

<
<



<
<
|
|
<
|
|

<
<


<
<
|
|
<
|
|
>

>
>
>
>
>
>
|
>
>
|

>






<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<

|

<


|
<
<
|

|
<
<
|
|
|
<
<
<
>
>


<
>

<
<
<
|
<
|
<
<
|
<
<
<
<


<
>

<
<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<
<




|
<
<
|
<
|
<




|
<
<
|
<
|
<





|
<
<
|
<
|
<





|
<
<
|
|
<
<
<
|
<




|
<
<

>
|
<
<
|
<
<
<
<


<
<
|
<
<
<
<
|
|
|
|
<
<
<

|
<
>

<
<
<
|
|
<
<
|
<
<
<
<


<
>

<
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<




<
|
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<




<
|
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<


<
|

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
|
<
|
<
|
<
<



<
<
<
<
<
<
<
<
<
|
>
|
>
|
>
>
|
<
|
<
|
<

|

|
>
>
>
|
|
<
|
<
|
|
|


<
<

>



<
<
|
|
<
<
|
<
|



|
<
<
|
|
<
<
|
<
|




<
<
|
|
<
<
|
<
|




<
<
|
|
<
>
|

<
<






|
<
<
|
<
<
|
<
|







|
<
<
|
<
<
|
<
<
|





|
<
<
|
<
<
|
<
|





|
<
<

|
|
|
<



|
<
<
|
|
<


>




<
<
|

|
>
|
|
|
<
<
|

|
<
|
|
<
|
|
|
>

|
<
<
|
<
|
<
<
|
|
<
<
<
<
<
<



|
<
<
|
<
<
<
<
<
<



|
<
<
|
<
<
<
<
<
<




|
<
<
|
<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|
>
>
|
<
<
<

>
>
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>
>
|
<
<
<
<
<
<
|
<
|
<
|
<
<
<
|
<
<
|
<
|
>
|
|
<
<
<
<
<
<
|
|
<
<
|
<
<
|
>
>
|
|
<
>
|
|
|
>
|
|
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<

|
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<

|
<
<
|
<
<
<
<
<
<

|
<
<
|
<
|
|




<
<
|



>
>
>
|
|
>





<
<
|
|
>





<
<
|
|
|
<
<
<
<





|
<
<

|
>









<
<
|

>
|
<
>
|
|
|
|
>
>
>

<
<
|
|
<
<
|
<
|
|

<
<
|
|
<
<
|
<
|


<
<
|
>
|
|

<
<
|

|
<
|
|
|
<
>


<
>

<
<
<
|
|
<
|
<


<
>

<
<
<
|
|
<
|
<


<
>

<
<
<
|
|
>



|
<
|

|
<
<
<
<
<

>
|




>
>

|
>

<
<


|
|
<
<




<
<
|
|
<
<
<
<
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>


<
<
|
<
|
<
<
<
<
<
<
<
<
<

|
<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<



<
<
|
<
|
<
<
<
<
<
<
<
<
<

>


<
<
<
|
|
<
<
<
<
<
<
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<

|


<
<
|
<
<
<
<
|
<
|
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<


|


|
<
<
|
|
<
<
<
<
<
<
<
<
<
<

|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<

|

>
>
>

<
<
|
<
<
|
<
<
<
<
<
<
<
<
<


<
<
|

>
>
>
|
|
|
<
<
<
<
<
<
<
<
<



<
<
|

>
>
>
>
>
>


<
|
<
<
<
<
<
<
<
<
<
<
|


<
<
|






|
<
<
<
<
<
<
<
<
<
<
<
<



<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>





|
>






|
>

<
<
<





|
>

<
<
<




|
>

<
<
<





|
>

<
<
<



|
>

<
<
<





<
<
<
|
|
|
>






<
<
<
|

|
>






|
|


<
<
|

|
<
<
<
<
<

<
<




|


<
<
|




|

<






<
<
|


|

<


<
<
|

<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<


<
<
<

|
>



<
<
<
1
2
3
4
5
6
7
8
9

10
11
12






13
14
15
16




17
18
































19


20

21
22






23
24



25







26
27

28
29
30

31





32
33







34

35










36
37





38






39

40



41
42




43
44

45



46
47












48
















49


50



















51
52

53




54
55


56

57






58
59

60






61
62
63
64
65








66

67





68












69
70
71
72



73

74





75
76
77
78

79
80
81


82
83




84
85


86


87

88
89
90


91
92





93






94
















95



















96
97


98
99
100
101



102
103
104



105




106
107

108



109
110
111
112
113
114



115

116




117








118


119
120
121



































































122





123
124



125







126
127
128
129
130

131
132
133
134
135
136
137
138
139


140
141



142

143





144



145



146








147






148










149
150


















151



152


153

154

155
156









157



158


159





160






161
162









163

164
165


166


167






168

169
170
171
172

173
174
175






176


177
178
179


180













181













182







183

184


185

186

187




188







189
190



191





192












193


194


195
196

197




198





199





200



201
202







203




204





205
206
207





208
209

210

211





212







213




















214


215




216

217

218

219
220
221
222
223

224

225
226

227

228

















229













230
231
232
233
234






235
236


237

238
239
240


241
242


243

244
245
246
247
248


249
250


251

252
253
254
255
256


257
258


259


260
261


262


263
264


265


266
267
268

269
270
271
272


273


274


275
276


277


278
279


280




281
282


283
284


285




286
287
288
289












290
291
292
293
294
295


296
297


298


299
300


301

302
303
304


305
306


307

308
309
310
311
312


313
314


315

316
317
318
319
320


321
322


323


324
325




326


327
328




329


330
331




332


333
334




335


336

337
338
339



340
341

342
343
344
345
346
347


348


349


350
351


352


353

354


355


356
357
358

359
360
361
362
363
364


365
















366


367


368
369


370

371
372
373
374
375


376


377

378
379
380
381
382
383
384

385


386

387
388
389
390
391
392


393


394


395
396


397


398
399


400

401
402
403
404
405
406


407
408


409

410
411
412
413
414
415


416
417


418


419

420


421


422
423


424


425
426
427

428
429
430
431
432


433
434


435

436
437
438
439
440


441
442


443

444
445
446
447
448
449


450
451


452

453
454
455
456
457
458


459



460
461
462

463
464


465

466






467
468


469
470




471


472
473






474
475
476
477


478
479




480


481
482




483


484
485






486
487


488
489






490


491
492






493


494
495






496
497
498


499
500






501
502
503
504


505
506






507
508
509
510
511


512






513
514
515
516
517


518






519


520
521






522


523
524






525
526
527
528
529


530






531
532






533


534

535
536
537
538
539
540
541
542
543
544
545
546


547

548




549


550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571


572
573
574
575
576
577
578
579
580


581
582
583
584
585

586
587
588


589
590
591
592
593
594
595
596
597
598
599
600
601


602
603
604

605
606
607
608



609

610
611
612


613











614
615

616










617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635


636
637

638

639



640


641

642
643
644


645
646
647
648
649


650
651

652
653
654


655
656
657


658
659

660
661
662


663
664
665


666
667



668
669
670
671
672
673
674


675
676
677
678

679
680
681



682
683
684


685
686

687
688
689
690



691
692
693


694
695


696


697
698
699
700
701
702


703
704
705
706
707


708
709
710
711
712


713

714

715
716
717
718
719
720
721


722

723
724
725


726
727
728
729


730
731

732
733
734


735
736
737


738
739

740
741
742


743
744
745


746
747

748
749
750


751
752


753
754

755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776

777











778



779



780




781


782
783
784

785
786
787


788
789
790


791
792
793



794
795
796
797

798
799



800

801


802




803
804

805
806



807
808

809

810
811
812
813
814
815
816


817
818

819

820
821
822
823
824
825
826


827
828

829

830
831
832
833
834
835
836


837
838

839

840
841
842
843
844
845
846


847
848

849


850
851
852
853
854


855

856

857
858
859
860
861


862

863

864
865
866
867
868
869


870

871

872
873
874
875
876
877


878
879



880

881
882
883
884
885


886
887
888


889




890
891


892




893
894
895
896



897
898

899
900



901
902


903




904
905

906
907



908
909

910


911
912
913
914
915
916
917
918


919
920

921


922
923
924
925
926
927
928
929


930
931

932


933
934
935
936
937
938
939
940


941
942

943


944
945
946
947

948


949
950

951


952
953
954
955
956
957
958
959


960
961

962

963
964
965
966

967


968
969

970


971
972
973
974
975
976
977
978


979
980

981


982
983
984
985
986
987
988
989


990
991

992


993
994
995

996
997


998

999


1000
1001
1002

1003
1004


1005

1006


1007
1008

1009
1010
1011


1012

1013


1014
1015
1016

1017
1018


1019

1020


1021
1022
1023

1024
1025


1026

1027


1028
1029
1030

1031
1032
1033

1034

1035


1036
1037
1038









1039
1040
1041
1042
1043
1044
1045
1046

1047

1048

1049
1050
1051
1052
1053
1054
1055
1056
1057

1058

1059
1060
1061
1062
1063


1064
1065
1066
1067
1068


1069
1070


1071

1072
1073
1074
1075
1076


1077
1078


1079

1080
1081
1082
1083
1084


1085
1086


1087

1088
1089
1090
1091
1092


1093
1094

1095
1096
1097


1098
1099
1100
1101
1102
1103
1104


1105


1106

1107
1108
1109
1110
1111
1112
1113
1114
1115


1116


1117


1118
1119
1120
1121
1122
1123
1124


1125


1126

1127
1128
1129
1130
1131
1132
1133


1134
1135
1136
1137

1138
1139
1140
1141


1142
1143

1144
1145
1146
1147
1148
1149
1150


1151
1152
1153
1154
1155
1156
1157


1158
1159
1160

1161
1162

1163
1164
1165
1166
1167
1168


1169

1170


1171
1172






1173
1174
1175
1176


1177






1178
1179
1180
1181


1182






1183
1184
1185
1186
1187


1188


1189


1190
1191












































































1192












1193



1194


1195











1196


1197

1198


























1199
1200
1201
1202
1203
1204
1205
1206



1207
1208
1209
1210
1211
1212
1213
























1214
1215
1216
1217






1218

1219

1220



1221


1222

1223
1224
1225
1226






1227
1228


1229


1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241






1242
1243


1244






1245
1246


1247




1248


1249
1250






1251
1252


1253






1254
1255


1256






1257
1258


1259

1260
1261
1262
1263
1264
1265


1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280


1281
1282
1283
1284
1285
1286
1287
1288


1289
1290
1291




1292
1293
1294
1295
1296
1297


1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309


1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321
1322


1323
1324


1325

1326
1327
1328


1329
1330


1331

1332
1333
1334


1335
1336
1337
1338
1339


1340
1341
1342

1343
1344
1345

1346
1347
1348

1349
1350



1351
1352

1353

1354
1355

1356
1357



1358
1359

1360

1361
1362

1363
1364



1365
1366
1367
1368
1369
1370
1371

1372
1373
1374





1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387


1388
1389
1390
1391


1392
1393
1394
1395


1396
1397




1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416


1417

1418









1419
1420


1421

1422









1423
1424


1425

1426









1427
1428


1429

1430









1431
1432


1433

1434









1435
1436
1437


1438

1439









1440
1441
1442
1443



1444
1445










1446
1447
1448
1449


1450

1451












1452
1453
1454
1455


1456




1457

1458




1459
1460
1461
1462


1463

1464












1465
1466


1467
1468
1469
1470
1471









1472
1473
1474
1475


1476

1477









1478
1479
1480
1481
1482
1483


1484
1485










1486
1487
1488
1489





























1490
1491










1492
1493
1494
1495
1496
1497
1498


1499


1500









1501
1502


1503
1504
1505
1506
1507
1508
1509
1510









1511
1512
1513


1514
1515
1516
1517
1518
1519
1520
1521
1522
1523

1524










1525
1526
1527


1528
1529
1530
1531
1532
1533
1534
1535












1536
1537
1538


1539
1540
















1541

1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558



1559
1560
1561
1562
1563
1564
1565
1566



1567
1568
1569
1570
1571
1572
1573



1574
1575
1576
1577
1578
1579
1580
1581



1582
1583
1584
1585
1586
1587



1588
1589
1590
1591
1592



1593
1594
1595
1596
1597
1598
1599
1600
1601
1602



1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616


1617
1618
1619





1620


1621
1622
1623
1624
1625
1626
1627


1628
1629
1630
1631
1632
1633
1634

1635
1636
1637
1638
1639
1640


1641
1642
1643
1644
1645

1646
1647


1648
1649










1650















1651


1652
1653



1654
1655
1656
1657
1658
1659



# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands







proc scroll args {
    global scrollInfo
    set scrollInfo $args
}





# Create additional widget that's used to hold the selection at times.



































entry .sel

.sel insert end "This is some sample text"







# Font names




set big -adobe-helvetica-medium-r-normal--24-240-75-75-p-*-iso8859-1







set fixed -adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1


# Create entries in the option database to be sure that geometry options
# like border width have predictable values.


option add *Entry.borderWidth 2





option add *Entry.highlightThickness 2
option add *Entry.font {Helvetica -12}









entry .e -bd 2 -relief sunken










pack .e
update












set i 1

foreach test {



    {-background #ff0000 #ff0000 non-existent
	{unknown color name "non-existent"}}




    {-bd 4 4 badValue {bad screen distance "badValue"}}
    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}

    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}



    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-disabledbackground green green non-existent












	{unknown color name "non-existent"}}
















    {-disabledforeground blue blue non-existent


	{unknown color name "non-existent"}}



















    {-exportselection yes 1 xyzzy {expected boolean value but got "xyzzy"}}
    {-fg #110022 #110022 bogus {unknown color name "bogus"}}

    {-font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*




	-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* {}
	{font "" doesn't exist}}


    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}

    {-highlightbackground #123456 #123456 ugly {unknown color name "ugly"}}






    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}

    {-highlightthickness -2 0 {} {}}






    {-insertbackground #110022 #110022 bogus {unknown color name "bogus"}}
    {-insertborderwidth 1.3 1 2.6x {bad screen distance "2.6x"}}
    {-insertofftime 100 100 3.2 {expected integer but got "3.2"}}
    {-insertontime 100 100 3.2 {expected integer but got "3.2"}}
    {-invalidcommand "any string" "any string" {} {}}








    {-invcmd "any string" "any string" {} {}}

    {-justify right right bogus {bad justification "bogus": must be left, right, or center}}





    {-readonlybackground green green non-existent












	{unknown color name "non-existent"}}
    {-relief groove groove 1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    {-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
    {-selectborderwidth 1.3 1 badValue {bad screen distance "badValue"}}



    {-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}

    {-show * * {} {}}





    {-state n normal bogus
	{bad state "bogus": must be disabled, normal, or readonly}}
    {-takefocus "any string" "any string" {} {}}
    {-textvariable i i {} {}}

    {-width 402 402 3p {expected integer but got "3p"}}
    {-xscrollcommand {Some command} {Some command} {} {}}
} {


    lassign $test name goodValue goodResult badValue badResult
    test entry-1.$i {configuration options} {




	.e configure $name $goodValue
	list [lindex [.e configure $name] 4] [.e cget $name]


    } [list $goodResult $goodResult]


    incr i

    if {$badValue ne ""} {
	test entry-1.$i {configuration options} -body {
	    .e configure $name $badValue


	} -returnCodes error -result $badResult
    }





    .e configure $name [lindex [.e configure $name] 3]






    incr i
















}




















test entry-2.1 {Tk_EntryCmd procedure} {


    list [catch {entry} msg] $msg
} {1 {wrong # args: should be "entry pathName ?options?"}}
test entry-2.2 {Tk_EntryCmd procedure} {
    list [catch {entry gorp} msg] $msg



} {1 {bad window path name "gorp"}}
test entry-2.3 {Tk_EntryCmd procedure} {
    catch {destroy .e}



    entry .e




    list [winfo exists .e] [winfo class .e] [info commands .e]
} {1 Entry .e}

test entry-2.4 {Tk_EntryCmd procedure} {



    catch {destroy .e}
    list [catch {entry .e -gorp foo} msg] $msg [winfo exists .e] \
	    [info commands .e]
} {1 {unknown option "-gorp"} 0 {}}
test entry-2.5 {Tk_EntryCmd procedure} {
    catch {destroy .e}



    entry .e

} {.e}













catch {destroy .e}


entry .e -font $fixed
pack .e
update









































































set cx [font measure $fixed a]
set cy [font metrics $fixed -linespace]



set ux [font measure $fixed \u4e4e]








test entry-3.1 {EntryWidgetCmd procedure} {
    list [catch {.e} msg] $msg
} {1 {wrong # args: should be ".e option ?arg arg ...?"}}
test entry-3.2 {EntryWidgetCmd procedure, "bbox" widget command} {

    list [catch {.e bbox} msg] $msg
} {1 {wrong # args: should be ".e bbox index"}}
test entry-3.3 {EntryWidgetCmd procedure, "bbox" widget command} {
    list [catch {.e bbox a b} msg] $msg
} {1 {wrong # args: should be ".e bbox index"}}
test entry-3.4 {EntryWidgetCmd procedure, "bbox" widget command} {
    list [catch {.e bbox bogus} msg] $msg
} {1 {bad entry index "bogus"}}
test entry-3.5 {EntryWidgetCmd procedure, "bbox" widget command} {


    .e delete 0 end
    .e bbox 0



} [list 5 5 0 $cy]

test entry-3.6 {EntryWidgetCmd procedure, "bbox" widget command} {





    # Tcl_UtfAtIndex(): no utf chars







    .e delete 0 end








    .e insert 0 "abc"






    list [.e bbox 3] [.e bbox end]










} [list "[expr 5+2*$cx] 5 $cx $cy" "[expr 5+2*$cx] 5 $cx $cy"]
test entry-3.7 {EntryWidgetCmd procedure, "bbox" widget command} {


















    # Tcl_UtfAtIndex(): utf at end



    .e delete 0 end


    .e insert 0 "ab\u4e4e"

    .e bbox end

} "[expr 5+2*$cx] 5 $ux $cy"
test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} {









    # Tcl_UtfAtIndex(): utf before index



    .e delete 0 end


    .e insert 0 "ab\u4e4ec"





    .e bbox 3






} "[expr 5+2*$cx+$ux] 5 $cx $cy"
test entry-3.9 {EntryWidgetCmd procedure, "bbox" widget command} {









    # Tcl_UtfAtIndex(): no chars

    .e delete 0 end
    .e bbox end


} "5 5 0 $cy"


test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} {






    .e delete 0 end

    .e insert 0 "abcdefghij\u4e4eklmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
} [list "5 5 $cx $cy" "[expr 5+$cx] 5 $cx $cy" "[expr 5+10*$cx] 5 $ux $cy" "[expr 5+$ux+15*$cx] 5 $cx $cy"]
test entry-3.11 {EntryWidgetCmd procedure, "cget" widget command} {

    list [catch {.e cget} msg] $msg
} {1 {wrong # args: should be ".e cget option"}}
test entry-3.12 {EntryWidgetCmd procedure, "cget" widget command} {






    list [catch {.e cget a b} msg] $msg


} {1 {wrong # args: should be ".e cget option"}}
test entry-3.13 {EntryWidgetCmd procedure, "cget" widget command} {
    list [catch {.e cget -gorp} msg] $msg


} {1 {unknown option "-gorp"}}













test entry-3.14 {EntryWidgetCmd procedure, "cget" widget command} {













    .e configure -bd 4







    .e cget -bd

} {4}


test entry-3.15 {EntryWidgetCmd procedure, "configure" widget command} {

    llength [.e configure]

} {36}




test entry-3.16 {EntryWidgetCmd procedure, "configure" widget command} {







    list [catch {.e configure -foo} msg] $msg
} {1 {unknown option "-foo"}}



test entry-3.17 {EntryWidgetCmd procedure, "configure" widget command} {





    .e configure -bd 4












    .e configure -bg #ffffff


    lindex [.e configure -bd] 4


} {4}
test entry-3.18 {EntryWidgetCmd procedure, "delete" widget command} {

    list [catch {.e delete} msg] $msg




} {1 {wrong # args: should be ".e delete firstIndex ?lastIndex?"}}





test entry-3.19 {EntryWidgetCmd procedure, "delete" widget command} {





    list [catch {.e delete a b c} msg] $msg



} {1 {wrong # args: should be ".e delete firstIndex ?lastIndex?"}}
test entry-3.20 {EntryWidgetCmd procedure, "delete" widget command} {







    list [catch {.e delete foo} msg] $msg




} {1 {bad entry index "foo"}}





test entry-3.21 {EntryWidgetCmd procedure, "delete" widget command} {
    list [catch {.e delete 0 bar} msg] $msg
} {1 {bad entry index "bar"}}





test entry-3.22 {EntryWidgetCmd procedure, "delete" widget command} {
    .e delete 0 end

    .e insert end "01234567890"

    .e delete 2 4





    .e get







} {014567890}




















test entry-3.23 {EntryWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end




    .e insert end "01234567890"

    .e delete 6

    .e get

} {0123457890}
test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} {
    # UTF
    set x {}
    .e delete 0 end

    .e insert end "01234\u4e4e67890"

    .e delete 6
    lappend x [.e get]

    .e delete 0 end

    .e insert end "012345\u4e4e7890"

















    .e delete 6













    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456\u4e4e890"
    .e delete 6
    lappend x [.e get]






} [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e delete 6 5
    .e get


} {01234567890}
test entry-3.26 {EntryWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get


} {01234567890}
test entry-3.26a {EntryWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get


} {01234567890}
test entry-3.27 {EntryWidgetCmd procedure, "get" widget command} {


    list [catch {.e get foo} msg] $msg


} {1 {wrong # args: should be ".e get"}}
test entry-3.28 {EntryWidgetCmd procedure, "icursor" widget command} {


    list [catch {.e icursor} msg] $msg


} {1 {wrong # args: should be ".e icursor pos"}}
test entry-3.29 {EntryWidgetCmd procedure, "icursor" widget command} {


    list [catch {.e icursor foo} msg] $msg


} {1 {bad entry index "foo"}}
test entry-3.30 {EntryWidgetCmd procedure, "icursor" widget command} {
    .e delete 0 end

    .e insert end "01234567890"
    .e icursor 4
    .e index insert
} {4}


test entry-3.31 {EntryWidgetCmd procedure, "index" widget command} {


    list [catch {.e in} msg] $msg


} {1 {ambiguous option "in": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}}
test entry-3.32 {EntryWidgetCmd procedure, "index" widget command} {


    list [catch {.e index} msg] $msg


} {1 {wrong # args: should be ".e index string"}}
test entry-3.33 {EntryWidgetCmd procedure, "index" widget command} {


    list [catch {.e index foo} msg] $msg




} {1 {bad entry index "foo"}}
test entry-3.34 {EntryWidgetCmd procedure, "index" widget command} {


    list [catch {.e index 0} msg] $msg
} {0 0}


test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} {




    # UTF
    .e delete 0 end
    .e insert 0 abc\u4e4e\u0153def
    list [.e index 3] [.e index 4] [.e index end]












} {3 4 8}
test entry-3.36 {EntryWidgetCmd procedure, "insert" widget command} {
    list [catch {.e insert a} msg] $msg
} {1 {wrong # args: should be ".e insert index text"}}
test entry-3.37 {EntryWidgetCmd procedure, "insert" widget command} {
    list [catch {.e insert a b c} msg] $msg


} {1 {wrong # args: should be ".e insert index text"}}
test entry-3.38 {EntryWidgetCmd procedure, "insert" widget command} {


    list [catch {.e insert foo Text} msg] $msg


} {1 {bad entry index "foo"}}
test entry-3.39 {EntryWidgetCmd procedure, "insert" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e insert 3 xxx
    .e get


} {012xxx34567890}
test entry-3.40 {EntryWidgetCmd procedure, "insert" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get


} {01234567890}
test entry-3.40a {EntryWidgetCmd procedure, "insert" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state readonly
    .e insert 3 xxx
    .e configure -state normal
    .e get


} {01234567890}
test entry-3.41 {EntryWidgetCmd procedure, "insert" widget command} {


    list [catch {.e insert a b c} msg] $msg


} {1 {wrong # args: should be ".e insert index text"}}
test entry-3.42 {EntryWidgetCmd procedure, "scan" widget command} {




    list [catch {.e scan a} msg] $msg


} {1 {wrong # args: should be ".e scan mark|dragto x"}}
test entry-3.43 {EntryWidgetCmd procedure, "scan" widget command} {




    list [catch {.e scan a b c} msg] $msg


} {1 {wrong # args: should be ".e scan mark|dragto x"}}
test entry-3.44 {EntryWidgetCmd procedure, "scan" widget command} {




    list [catch {.e scan foobar 20} msg] $msg


} {1 {bad scan option "foobar": must be mark or dragto}}
test entry-3.45 {EntryWidgetCmd procedure, "scan" widget command} {




    list [catch {.e scan mark 20.1} msg] $msg


} {1 {expected integer but got "20.1"}}

# This test is non-portable because character sizes vary.

test entry-3.46 {EntryWidgetCmd procedure, "scan" widget command} {fonts} {



    .e delete 0 end
    update

    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0
} {2}


test entry-3.47 {EntryWidgetCmd procedure, "select" widget command} {


    list [catch {.e select} msg] $msg


} {1 {wrong # args: should be ".e selection option ?index?"}}
test entry-3.48 {EntryWidgetCmd procedure, "select" widget command} {


    list [catch {.e select foo} msg] $msg


} {1 {bad selection option "foo": must be adjust, clear, from, present, range, or to}}

test entry-3.49 {EntryWidgetCmd procedure, "select clear" widget command} {


    list [catch {.e select clear gorp} msg] $msg


} {1 {wrong # args: should be ".e selection clear"}}
test entry-3.50 {EntryWidgetCmd procedure, "select clear" widget command} {
    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    list [catch {selection get} msg] $msg [selection own]


} {1 {PRIMARY selection doesn't exist or form "STRING" not defined} .e}
















test entry-3.51 {EntryWidgetCmd procedure, "selection present" widget command} {


    list [catch {.e selection present foo} msg] $msg


} {1 {wrong # args: should be ".e selection present"}}
test entry-3.52 {EntryWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} {1}


test entry-3.53 {EntryWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} {1}
.e configure -exportselection true

test entry-3.54 {EntryWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
} {0}


test entry-3.55 {EntryWidgetCmd procedure, "selection adjust" widget command} {


    list [catch {.e select adjust x} msg] $msg


} {1 {bad entry index "x"}}
test entry-3.56 {EntryWidgetCmd procedure, "selection adjust" widget command} {


    list [catch {.e select adjust 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection adjust index"}}
test entry-3.57 {EntryWidgetCmd procedure, "selection adjust" widget command} {


    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get


} {123}
test entry-3.58 {EntryWidgetCmd procedure, "selection adjust" widget command} {


    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
    selection get


} {234}
test entry-3.59 {EntryWidgetCmd procedure, "selection from" widget command} {


    list [catch {.e select from 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection from index"}}

test entry-3.60 {EntryWidgetCmd procedure, "selection range" widget command} {


    list [catch {.e select range 2} msg] $msg


} {1 {wrong # args: should be ".e selection range start end"}}
test entry-3.61 {EntryWidgetCmd procedure, "selection range" widget command} {


    list [catch {.e selection range 2 3 4} msg] $msg


} {1 {wrong # args: should be ".e selection range start end"}}
test entry-3.62 {EntryWidgetCmd procedure, "selection range" widget command} {
    .e delete 0 end

    .e insert end 0123456789
    .e select from 1
    .e select to 5
    .e select range 4 4
    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test entry-3.63 {EntryWidgetCmd procedure, "selection range" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]


} {2 9 3}
test entry-3.64 {EntryWidgetCmd procedure, "selection" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state disabled
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]


} {0 10}
test entry-3.64a {EntryWidgetCmd procedure, "selection" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state readonly
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]


} {2 4}



.e delete 0 end
.e insert end "This is quite a long text string, so long that it "
.e insert end "runs off the end of the window quite a bit."

test entry-3.64b {EntryWidgetCmd procedure, "selection to" widget command} {
    list [catch {.e select to 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection to index"}}

test entry-3.65 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 5
    format {%.7f %.7f} {*}[.e xview]


} {0.0537634 0.2688172}
test entry-3.66 {EntryWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview gorp} msg] $msg


} {1 {bad entry index "gorp"}}
test entry-3.67 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]


} {0.107527 0.322581}
test entry-3.68 {EntryWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview moveto foo bar} msg] $msg


} {1 {wrong # args: should be ".e xview moveto fraction"}}
test entry-3.69 {EntryWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview moveto foo} msg] $msg


} {1 {expected floating-point number but got "foo"}}
test entry-3.70 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]


} {0.505376 0.720430}
test entry-3.71 {EntryWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll 24} msg] $msg


} {1 {wrong # args: should be ".e xview scroll number units|pages"}}
test entry-3.72 {EntryWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll gorp units} msg] $msg


} {1 {expected integer but got "gorp"}}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]


} {0.193548 0.408602}
test entry-3.74 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]


} {0.397849 0.612903}
test entry-3.75 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} {32}


test entry-3.76 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} {29}


test entry-3.77 {EntryWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll 23 foobars} msg] $msg


} {1 {bad argument "foobars": must be units or pages}}
test entry-3.78 {EntryWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview eat 23 hamburgers} msg] $msg


} {1 {unknown option "eat": must be moveto or scroll}}
test entry-3.79 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 0
    update
    .e xview -4
    .e index @0
} {0}


test entry-3.80 {EntryWidgetCmd procedure, "xview" widget command} {






    .e xview 300
    .e index @0






} {73}


.e insert 10 \u4e4e

test entry-3.81 {EntryWidgetCmd procedure, "xview" widget command} {
    # UTF
    # If Tcl_NumUtfChars wasn't used, wrong answer would be:
    # 0.106383 0.117021 0.117021

    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .11
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .12
    lappend x [format {%.6f} [lindex [.e xview] 0]]


} {0.095745 0.106383 0.117021}

test entry-3.82 {EntryWidgetCmd procedure} {




    list [catch {.e gorp} msg] $msg


} {1 {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}}

# The test below doesn't actually check anything directly, but if run
# with Purify or some other memory-allocation-checking program it will
# ensure that resources get properly freed.

test entry-4.1 {DestroyEntry procedure} {
    catch {destroy .e}
    entry .e -textvariable x -show *
    pack .e
    .e insert end "Sample text"
    update
    destroy .e
} {}

frame .f -width 200 -height 50 -relief raised -bd 2
pack .f -side right
test entry-5.1 {ConfigureEntry procedure, -textvariable} {
    catch {destroy .e}
    set x 12345
    entry .e -textvariable x
    .e get


} {12345}
test entry-5.2 {ConfigureEntry procedure, -textvariable} {
    catch {destroy .e}
    set x 12345
    entry .e -textvariable x
    set y abcde
    .e configure -textvariable y
    set x 54321
    .e get


} {abcde}
test entry-5.3 {ConfigureEntry procedure, -textvariable} {
    catch {destroy .e}
    catch {unset x}
    entry .e

    .e insert 0 "Some text"
    .e configure -textvariable x
    set x


} {Some text}
test entry-5.4 {ConfigureEntry procedure, -textvariable} {
    proc override args {
	global x
	set x 12345
    }
    catch {destroy .e}
    catch {unset x}
    trace variable x w override
    entry .e
    .e insert 0 "Some text"
    .e configure -textvariable x
    set result [list $x [.e get]]


    unset x;  rename override {}
    set result
} {12345 12345}

test entry-5.5 {ConfigureEntry procedure} {
    catch {destroy .e}
    entry .e -exportselection false
    pack .e



    .e insert end "0123456789"

    .sel select from 0
    .sel select to 10
    set x {}


    lappend x [selection get]











    .e select from 1
    .e select to 5

    lappend x [selection get]










    .e configure -exportselection 1
    lappend x [selection get]
    set x
} {{This is so} {This is so} 1234}
test entry-5.6 {ConfigureEntry procedure} {
    catch {destroy .e}
    entry .e
    pack .e
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    list [catch {selection get} msg] $msg [.e index sel.first] \
	    [.e index sel.last]
} {1 {PRIMARY selection doesn't exist or form "STRING" not defined} 1 5}
test entry-5.7 {ConfigureEntry procedure} {
    catch {destroy .e}
    entry .e -font $fixed -width 4 -xscrollcommand scroll
    pack .e


    .e insert end "01234567890"
    update

    .e configure -width 5

    format {%.6f %.6f} {*}$scrollInfo



} {0.000000 0.363636}


test entry-5.8 {ConfigureEntry procedure} {fonts} {

    catch {destroy .e}
    entry .e -width 0
    pack .e


    .e insert end "0123"
    update
    .e configure -font $big
    update
    winfo geom .e


} {62x37+0+0}
test entry-5.9 {ConfigureEntry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised
    pack .e


    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]


} {0 0 1 1}
test entry-5.10 {ConfigureEntry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief flat
    pack .e


    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]


} {0 0 1 1}
test entry-5.11 {ConfigureEntry procedure} {



    # If "0" in selected font had 0 width, caused divide-by-zero error.

    catch {destroy .e}
    pack [entry .e -font {{open look glyph}}]
    .e scan dragto 30
    update
} {}



# No tests for DisplayEntry.

test entry-6.1 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 20 -highlightthickness 3
    pack .e



    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]


} {3 4}
test entry-6.2 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 20 -justify center \
	    -highlightthickness 3
    pack .e



    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]


} {3 4}
test entry-6.3 {EntryComputeGeometry procedure} {fonts} {


    catch {destroy .e}


    entry .e -font $fixed -bd 2 -relief raised -width 20 -justify right \
	    -highlightthickness 3
    pack .e
    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]


} {3 4}
test entry-6.4 {EntryComputeGeometry procedure} {
    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 5
    pack .e


    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} {6}


test entry-6.5 {EntryComputeGeometry procedure} {

    catch {destroy .e}

    entry .e -font $fixed -bd 2 -relief raised -width 5
    pack .e
    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} {6}


test entry-6.6 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 10
    pack .e


    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]


} {5 6}
test entry-6.7 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $big -bd 3 -relief raised -width 5
    pack .e


    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {77 39}
test entry-6.8 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $big -bd 3 -relief raised -width 0
    pack .e


    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {116 39}
test entry-6.9 {EntryComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    entry .e -font $big -bd 3 -relief raised -width 0 -highlightthickness 2
    pack .e


    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {25 39}
test entry-6.10 {EntryComputeGeometry procedure} {unix fonts} {

    catch {destroy .e}
    entry .e -bd 1 -relief raised -width 0 -show .
    .e insert 0 12345
    pack .e
    update
    set x [winfo reqwidth .e]
    .e configure -show X
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} {23 53 43}
test entry-6.11 {EntryComputeGeometry procedure} win {
    catch {destroy .e}
    entry .e -bd 1 -relief raised -width 0 -show . -font {helvetica 12}
    .e insert 0 12345
    pack .e
    update
    set x [winfo reqwidth .e]
    .e configure -show X
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]

} [list \











    [expr 8+5*[font measure {helvetica 12} .]] \



    [expr 8+5*[font measure {helvetica 12} X]] \



    [expr 8+[font measure {helvetica 12} 12345]]]




test entry-6.12 {EntryComputeGeometry procedure} {fonts} {


    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 20
    pack .e

    .e insert end "012\t456\t"
    update
    list [.e index @81] [.e index @82] [.e index @116] [.e index @117]


} {6 7 7 8}

catch {destroy .e}


entry .e -width 10 -font $fixed -textvariable contents -xscrollcommand scroll
pack .e
focus .e



test entry-7.1 {InsertChars procedure} {
    .e delete 0 end
    .e insert 0 abcde
    .e insert 2 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abXXXcde abXXXcde {0.000000 1.000000}}

test entry-7.2 {InsertChars procedure} {


    .e delete 0 end




    .e insert 0 abcde
    .e insert 500 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abcdeXXX abcdeXXX {0.000000 1.000000}}
test entry-7.3 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {5 9 5 8}
test entry-7.4 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {2 9 2 8}
test entry-7.5 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {2 9 2 8}
test entry-7.6 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {2 6 2 5}
test entry-7.7 {InsertChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} {7}


test entry-7.8 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} {4}


test entry-7.9 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} {7}


test entry-7.10 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} {4}


.e configure -width 0
test entry-7.11 {InsertChars procedure} {fonts} {



    .e delete 0 end

    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e
} {59}



.e configure -width 10
test entry-8.1 {DeleteChars procedure} {


    .e delete 0 end




    .e insert 0 abcde
    .e delete 2 4


    update




    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} {abe abe {0.000000 1.000000}}
test entry-8.2 {DeleteChars procedure} {
    .e delete 0 end



    .e insert 0 abcde
    .e delete -2 2

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {cde cde {0.000000 1.000000}}
test entry-8.3 {DeleteChars procedure} {


    .e delete 0 end




    .e insert 0 abcde
    .e delete 3 1000

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abc abc {0.000000 1.000000}}
test entry-8.4 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {1 6 1 5}
test entry-8.5 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]


} {1 5 1 4}
test entry-8.6 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {1 2 1 5}
test entry-8.7 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8

    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test entry-8.8 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {3 4 3 8}
test entry-8.9 {DeleteChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8

    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test entry-8.10 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {3 5 5 8}
test entry-8.11 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]


} {3 8 4 8}
test entry-8.12 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4

    .e index insert
} {1}


test entry-8.13 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5

    .e index insert
} {1}


test entry-8.14 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4

    .e delete 4 6
    .e index insert
} {4}


test entry-8.15 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4

    .e index @0
} {1}


test entry-8.16 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5

    .e index @0
} {1}


test entry-8.17 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6

    .e index @0
} {4}
.e configure -width 0

test entry-8.18 {DeleteChars procedure} {fonts} {

    .e delete 0 end


    .e insert 0 "xyzzy"
    update
    .e delete 2 4









    winfo reqwidth .e
} {31}

test entry-9.1 {EntryValueChanged procedure} {
    catch {destroy .e}
    proc override args {
	global x
	set x 12345

    }

    catch {unset x}

    trace variable x w override
    entry .e -textvariable x
    .e insert 0 foo
    set result [list $x [.e get]]
    unset x; rename override {}
    set result
} {12345 12345}

catch {destroy .e}

entry .e

pack .e
.e configure -width 0
test entry-10.1 {EntrySetValue procedure} {fonts} {
    set x abcde
    set y ab


    .e configure -textvariable x
    update
    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]


} {ab 24}
test entry-10.2 {EntrySetValue procedure, updating selection} {


    catch {destroy .e}

    entry .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test entry-10.3 {EntrySetValue procedure, updating selection} {


    catch {destroy .e}

    entry .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]


} {4 7}
test entry-10.4 {EntrySetValue procedure, updating selection} {


    catch {destroy .e}

    entry .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]


} {4 10}
test entry-10.5 {EntrySetValue procedure, updating display position} {

    catch {destroy .e}
    entry .e -width 10 -font $fixed -textvariable x
    pack .e


    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} {0}


test entry-10.6 {EntrySetValue procedure, updating display position} {


    catch {destroy .e}

    entry .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} {10}


test entry-10.7 {EntrySetValue procedure, updating insertion cursor} {


    catch {destroy .e}


    entry .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} {3}


test entry-10.8 {EntrySetValue procedure, updating insertion cursor} {


    catch {destroy .e}

    entry .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} {5}



test entry-11.1 {EntryEventProc procedure} {
    catch {destroy .e}
    entry .e

    .e insert 0 abcdefg
    destroy .e
    update
} {}


test entry-11.2 {EntryEventProc procedure} {
    deleteWindows

    entry .e1 -fg #112233
    rename .e1 .e2
    set x {}
    lappend x [winfo children .]
    lappend x [.e2 cget -fg]
    destroy .e1
    lappend x [info command .e*] [winfo children .]


} {.e1 #112233 {} {}}

test entry-12.1 {EntryCmdDeletedProc procedure} {
    deleteWindows
    button .e1 -text "xyz_123"
    rename .e1 {}
    list [info command .e*] [winfo children .]


} {{} {}}

catch {destroy .e}

entry .e -font $fixed -width 5 -bd 2 -relief sunken
pack .e

.e insert 0 012345678901234567890
.e xview 4
update
test entry-13.1 {GetEntryIndex procedure} {
    .e index end
} {21}


test entry-13.2 {GetEntryIndex procedure} {

    list [catch {.e index abogus} msg] $msg


} {1 {bad entry index "abogus"}}
test entry-13.3 {GetEntryIndex procedure} {






    .e select from 1
    .e select to 6
    .e index anchor
} {1}


test entry-13.4 {GetEntryIndex procedure} {






    .e select from 4
    .e select to 1
    .e index anchor
} {4}


test entry-13.5 {GetEntryIndex procedure} {






    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} {15}


test entry-13.6 {GetEntryIndex procedure} {


    list [catch {.e index ebogus} msg] $msg


} {1 {bad entry index "ebogus"}}
test entry-13.7 {GetEntryIndex procedure} {












































































    .e icursor 2












    .e index insert



} {2}


test entry-13.8 {GetEntryIndex procedure} {











    list [catch {.e index ibogus} msg] $msg


} {1 {bad entry index "ibogus"}}

test entry-13.9 {GetEntryIndex procedure} {


























    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
} {1 6}
selection clear .e
test entry-13.10 {GetEntryIndex procedure} unix {
    # On unix, when selection is cleared, entry widget's internal
    # selection range is reset.




    list [catch {.e index sel.first} msg] $msg
} {1 {selection isn't in widget .e}}
test entry-13.11 {GetEntryIndex procedure} win {
    # On mac and pc, when selection is cleared, entry widget remembers
    # last selected range.  When selection ownership is restored to
    # entry, the old range will be rehighlighted.

























    list [catch {selection get}] [.e index sel.first]
} {1 1}
test entry-13.12 {GetEntryIndex procedure} unix {






    list [catch {.e index sbogus} msg] $msg

} {1 {selection isn't in widget .e}}

test entry-13.13 {GetEntryIndex procedure} win {



    list [catch {.e index sbogus} msg] $msg


} {1 {bad entry index "sbogus"}}

test entry-13.14 {GetEntryIndex procedure} win {
    list [catch {selection get}] [catch {.e index sbogus}]
} {1 1}
test entry-13.15 {GetEntryIndex procedure} {






    list [catch {.e index @xyz} msg] $msg
} {1 {bad entry index "@xyz"}}


test entry-13.16 {GetEntryIndex procedure} {fonts} {


    .e index @4
} {4}
test entry-13.17 {GetEntryIndex procedure} {fonts} {
    .e index @11
} {4}

test entry-13.18 {GetEntryIndex procedure} {fonts} {
    .e index @12
} {5}
test entry-13.19 {GetEntryIndex procedure} {fonts} {
    .e index @[expr [winfo width .e] - 6]
} {8}
test entry-13.20 {GetEntryIndex procedure} {fonts} {






    .e index @[expr [winfo width .e] - 5]
} {9}


test entry-13.21 {GetEntryIndex procedure} {






    .e index @1000
} {9}


test entry-13.22 {GetEntryIndex procedure} {




    list [catch {.e index 1xyz} msg] $msg


} {1 {bad entry index "1xyz"}}
test entry-13.23 {GetEntryIndex procedure} {






    .e index -10
} {0}


test entry-13.24 {GetEntryIndex procedure} {






    .e index 12
} {12}


test entry-13.25 {GetEntryIndex procedure} {






    .e index 49
} {21}


test entry-13.26 {GetEntryIndex procedure} {fonts} {

    catch {destroy .e}
    entry .e -show .
    .e insert 0 XXXYZZY
    pack .e
    update
    list [.e index @7] [.e index @8]


} {0 1}

# XXX Still need to write tests for EntryScanTo and EntrySelectTo.

set x {}
for {set i 1} {$i <= 500} {incr i} {
    append x "This is line $i, out of 500\n"
}
test entry-14.1 {EntryFetchSelection procedure} {
    catch {destroy .e}
    entry .e
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get


} {his is a test str}
test entry-14.2 {EntryFetchSelection procedure} {
    catch {destroy .e}
    entry .e -show *
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get


} {*****************}
test entry-14.3 {EntryFetchSelection procedure} {
    catch {destroy .e}




    entry .e
    .e insert end $x
    .e select from 0
    .e select to end
    string compare [selection get] $x
} 0



test entry-15.1 {EntryLostSelection} {
    catch {destroy .e}
    entry .e
    .e insert 0 "Text"
    .e select from 0
    .e select to 4
    set result [selection get]
    selection clear
    .e select from 0
    .e select to 4
    lappend result [selection get]


} {Text Text}

# No tests for EventuallyRedraw.


catch {destroy .e}
entry .e -width 10 -xscrollcommand scroll
pack .e
update

test entry-16.1 {EntryVisibleRange procedure} {fonts} {
    .e delete 0 end
    .e insert 0 .............................
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 0.827586}
test entry-16.2 {EntryVisibleRange procedure} {unix fonts} {


    .e configure -show X

    .e delete 0 end
    .e insert 0 .............................
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 0.275862}
test entry-16.3 {EntryVisibleRange procedure} win {


    .e configure -show .

    .e delete 0 end
    .e insert 0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 0.827586}
.e configure -show ""
test entry-16.4 {EntryVisibleRange procedure} {
    .e delete 0 end
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 1.000000}

catch {destroy .e}

entry .e -width 10 -xscrollcommand scroll -font $fixed
pack .e
update

test entry-17.1 {EntryUpdateScrollbar procedure} {
    .e delete 0 end
    .e insert 0 123

    update
    format {%.6f %.6f} {*}$scrollInfo



} {0.000000 1.000000}
test entry-17.2 {EntryUpdateScrollbar procedure} {

    .e delete 0 end

    .e insert 0 0123456789abcdef
    .e xview 3

    update
    format {%.6f %.6f} {*}$scrollInfo



} {0.187500 0.812500}
test entry-17.3 {EntryUpdateScrollbar procedure} {

    .e delete 0 end

    .e insert 0 abcdefghijklmnopqrs
    .e xview 6

    update
    format {%.6f %.6f} {*}$scrollInfo



} {0.315789 0.842105}
test entry-17.4 {EntryUpdateScrollbar procedure} {
    destroy .e
    proc bgerror msg {
	global x
	set x $msg
    }

    entry .e -width 5 -xscrollcommand thisisnotacommand
    pack .e
    update





    rename bgerror {}
    list $x $errorInfo
} {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
    (horizontal scrolling command executed by .e)}}

set l [interp hidden]
deleteWindows

test entry-18.1 {Entry widget vs hiding} {
    destroy .e
    entry .e


    interp hide {} .e
    destroy .e
    list [winfo children .] [interp hidden]
} [list {} $l]



##
## Entry widget VALIDATION tests
##



destroy .e




catch {unset ::e}
catch {unset ::vVals}
entry .e -validate all \
	-validatecommand [list doval %W %d %i %P %s %S %v %V] \
	-invalidcommand bell \
	-textvariable ::e \
	-background red -foreground white
pack .e
proc doval {W d i P s S v V} {
    set ::vVals [list $W $d $i $P $s $S $v $V]
    return 1
}

# The validation tests build each one upon the previous, so cascading
# failures aren't good
#
test entry-19.1 {entry widget validation} {
    .e insert 0 a
    set ::vVals


} {.e 1 0 a {} a all key}

test entry-19.2 {entry widget validation} {









    .e insert 1 b
    set ::vVals


} {.e 1 1 ab a b all key}

test entry-19.3 {entry widget validation} {









    .e insert end c
    set ::vVals


} {.e 1 2 abc ab c all key}

test entry-19.4 {entry widget validation} {









    .e insert 1 123
    list $::vVals $::e


} {{.e 1 1 a123bc abc 123 all key} a123bc}

test entry-19.5 {entry widget validation} {









    .e delete 2
    set ::vVals


} {.e 0 2 a13bc a123bc 2 all key}

test entry-19.6 {entry widget validation} {









    .e configure -validate key
    .e delete 1 3
    set ::vVals


} {.e 0 1 abc a13bc 13 key key}

test entry-19.7 {entry widget validation} {









    set ::vVals {}
    .e configure -validate focus
    .e insert end d
    set ::vVals



} {}
test entry-19.8 {entry widget validation} {










    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focus focusin}

test entry-19.9 {entry widget validation} {












    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focus focusout}




.e configure -validate all

test entry-19.10 {entry widget validation} {




    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} all focusin}

test entry-19.11 {entry widget validation} {












    focus -force .
    # update necessary to process FocusOut event


    update
    set ::vVals
} {.e -1 -1 abcd abcd {} all focusout}
.e configure -validate focusin
test entry-19.12 {entry widget validation} {









    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focusin focusin}

test entry-19.13 {entry widget validation} {









    set ::vVals {}
    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals
} {}


.e configure -validate focuso
test entry-19.14 {entry widget validation} {










    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals





























} {}
test entry-19.15 {entry widget validation} {










    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals
} {.e -1 -1 abcd abcd {} focusout focusout}
test entry-19.16 {entry widget validation} {
    list [.e validate] $::vVals


} {1 {.e -1 -1 abcd abcd {} all forced}}


test entry-19.17 {entry widget validation} {









    set ::e newdata
    list [.e cget -validate] $::vVals


} {focusout {.e -1 -1 newdata abcd {} focusout forced}}

proc doval {W d i P s S v V} {
    set ::vVals [list $W $d $i $P $s $S $v $V]
    return 0
}

test entry-19.18 {entry widget validation} {









    .e configure -validate all
    set ::e nextdata
    list [.e cget -validate] $::vVals


} {none {.e -1 -1 nextdata newdata {} all forced}}

proc doval {W d i P s S v V} {
    set ::vVals [list $W $d $i $P $s $S $v $V]
    set ::e mydata
    return 1
}

## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the entry textvar is also set

test entry-19.19 {entry widget validation} {










    .e configure -validate all
    .e validate
    list [.e cget -validate] [.e get] $::vVals


} {none mydata {.e -1 -1 nextdata nextdata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test entry-19.20 {entry widget validation} {












    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals


} {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}

















destroy .e

catch {unset ::e ::vVals}

##
## End validation tests
##

test entry-20.1 {widget deletion while active} {
    destroy .e
    entry .e -validate all \
	    -validatecommand { destroy %W ; return 1 } \
	    -invalidcommand bell
    update
    .e insert 0 abc
    winfo exists .e
} 0
test entry-20.2 {widget deletion while active} {
    destroy .e



    entry .e -validate all \
	    -validatecommand { return 0 } \
	    -invalidcommand { destroy %W }
    .e insert 0 abc
    winfo exists .e
} 0
test entry-20.3 {widget deletion while active} {
    destroy .e



    entry .e -validate all \
	    -validatecommand { rename .e {} ; return 1 }
    .e insert 0 abc
    winfo exists .e
} 0
test entry-20.4 {widget deletion while active} {
    destroy .e



    entry .e -validate all \
	    -validatecommand { return 0 } \
	    -invalidcommand { rename .e {} }
    .e insert 0 abc
    winfo exists .e
} 0
test entry-20.5 {widget deletion while active} {
    destroy .e



    entry .e -validatecommand { destroy .e ; return 0 }
    .e validate
    winfo exists .e
} 0
test entry-20.6 {widget deletion while active} {
    destroy .e



    pack [entry .e]
    update
    .e config -xscrollcommand { destroy .e }
    update idle
    winfo exists .e



} 0
test entry-20.7 {widget deletion with textvariable active} {
    # SF bugs 607390 and 617446
    destroy .e
    set FOO init
    entry .e -textvariable FOO -validate all \
	    -vcmd {%W configure -bg white; format 1}
    bind .e <Destroy> { set FOO hello }
    destroy .e
    winfo exists .e



} 0

test entry-21.1 {selection present while disabled, bug 637828} {
    destroy .e
    entry .e
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    set out [.e selection present]
    .e configure -state disabled
    # still return 1 when disabled, because 'selection get' will work,
    # but selection cannot be changed (new behavior since 8.4)
    .e select to 9
    lappend out [.e selection present] [selection get]


} {1 1 345}

test entry-22.1 {lost namespaced textvar} {





    destroy .e


    namespace eval test { variable foo {a b} }
    entry .e -textvariable ::test::foo
    namespace delete test
    catch {.e insert end "more stuff"} result1
    catch {.e delete 5 end} result2
    catch {set ::test::foo} result3
    list [.e get] [.e cget -textvar] $result1 $result2 $result3


} [list "a bmo" ::test::foo \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't read "::test::foo": no such variable}]

test entry-23.1 {error in trace proc attached to the textvariable} {
    destroy .e

    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    entry .e -textvariable myvar
    catch {.e insert end mystring} result1
    catch {.e delete 0} result2
    list $result1 $result2


} [list {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!}]

test entry-24.1 {textvariable lives in a non-existing namespace} {
    destroy .e

    catch {entry .e -textvariable thisnsdoesntexist::myvar} result1
    set result1


} {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}











destroy .e


















# XXX Still need to write tests for EntryBlinkProc, EntryFocusProc,
# and EntryTextVarProc.




option clear

# cleanup
cleanupTests
return



Changes to tests/event.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# This file is a Tcl script to test the code in tkEvent.c.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# XXX This test file is woefully incomplete.  Right now it only tests
# a few of the procedures in tkEvent.c.  Please add more tests whenever
# possible.

# Setup table used to query key events.




|
|
|





<







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
# This file is a Tcl script to test the code in tkEvent.c.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


# XXX This test file is woefully incomplete.  Right now it only tests
# a few of the procedures in tkEvent.c.  Please add more tests whenever
# possible.

# Setup table used to query key events.

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    if {[info exists keypress_lookup($char)]} {
        return $keypress_lookup($char)
    } else {
        return $char
    }
}

# Lookup and generate a pair of Key and KeyRelease events

proc _keypress {win key} {
    set keysym [_keypress_lookup $key]

    # Force focus to the window before delivering
    # each event so that a window manager using
    # a focus follows mouse will not steal away
    # the focus if the mouse is moved around.

    if {[focus] != $win} {
        focus -force $win
    }
    event generate $win <Key-$keysym>
    _pause 50
    if {[focus] != $win} {
        focus -force $win
    }
    event generate $win <KeyRelease-$keysym>
    _pause 50
}







|












|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    if {[info exists keypress_lookup($char)]} {
        return $keypress_lookup($char)
    } else {
        return $char
    }
}

# Lookup and generate a pair of KeyPress and KeyRelease events

proc _keypress {win key} {
    set keysym [_keypress_lookup $key]

    # Force focus to the window before delivering
    # each event so that a window manager using
    # a focus follows mouse will not steal away
    # the focus if the mouse is moved around.

    if {[focus] != $win} {
        focus -force $win
    }
    event generate $win <KeyPress-$keysym>
    _pause 50
    if {[focus] != $win} {
        focus -force $win
    }
    event generate $win <KeyRelease-$keysym>
    _pause 50
}
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
        return ""
    }
    return $sel
}

# Begining of the actual tests

test event-1.1 {Tk_HandleEvent procedure, filter events for dead windows} -setup {
	deleteWindows
    set x {}
} -body {
    button .b -text Test
    pack .b
    bindtags .b .b
    update
    bind .b <Destroy> {
	    lappend x destroy
	    event generate .b <Button-1>
	    event generate .b <ButtonRelease-1>
    }
    bind .b <Button-1> {
	    lappend x button
    }

    destroy .b
    return $x
} -cleanup {
    deleteWindows
} -result {destroy}
test event-1.2 {event generate <Alt-z>} -setup {
	deleteWindows
    catch {unset ::event12result}
} -body {
	set ::event12result 0
	pack [entry .e]
	update
	bind .e <Alt-z> {set ::event12result "1"}

	focus -force .e
     event generate .e <Alt-z>
	destroy .e
	set ::event12result
} -cleanup {
    deleteWindows
} -result 1


test event-2.1(keypress) {type into entry widget and hit Return} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    set return_binding 0
    bind $e <Return> {set return_binding 1}
    tkwait visibility $e
    _keypress_string $e HELLO\n
    list [$e get] $return_binding
} -cleanup {
    deleteWindows
} -result {HELLO 1}
test event-2.2(keypress) {type into entry widget and then delete some text} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    # Avoid a hang when macOS puts the mouse pointer on the green button
    wm geometry .t +200+100
    _keypress_string $e MELLO
    _keypress $e BackSpace
    _keypress $e BackSpace
    $e get
} -cleanup {
    deleteWindows
} -result {MEL}
test event-2.3(keypress) {type into entry widget, triple click, hit Delete key,
        and then type some more} -setup {
    deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e JUMP

    set result [$e get]

    event generate $e <Enter>
    for {set i 0} {$i < 3} {incr i} {
        _pause 100
        event generate $e <Button-1>
        _pause 100
        event generate $e <ButtonRelease-1>
    }

    _keypress $e Delete
    _keypress_string $e UP
    lappend result [$e get]
} -cleanup {
    deleteWindows
} -result {JUMP UP}
test event-2.4(keypress) {type into text widget and hit Return} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    set return_binding 0
    bind $e <Return> {set return_binding 1}
    tkwait visibility $e
    _keypress_string $e HELLO\n
    list [$e get 1.0 end] $return_binding
} -cleanup {
    deleteWindows
} -result [list "HELLO\n\n" 1]
test event-2.5(keypress) {type into text widget and then delete some text} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e MELLO
    _keypress $e BackSpace
    _keypress $e BackSpace
    $e get 1.0 1.end
} -cleanup {
    deleteWindows
} -result {MEL}
test event-2.6(keypress) {type into text widget, triple click,
    hit Delete key, and then type some more} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e JUMP

    set result [$e get 1.0 1.end]

    event generate $e <Enter>
    for {set i 0} {$i < 3} {incr i} {
        _pause 100
        event generate $e <Button-1>
        _pause 100
        event generate $e <ButtonRelease-1>
    }

    _keypress $e Delete
    _keypress_string $e UP
    lappend result [$e get 1.0 1.end]
} -cleanup {
    deleteWindows
} -result {JUMP UP}

test event-3.1(click-drag) {click and drag in a text widget, this tests
    tkTextSelectTo in text.tcl} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "A Tcl/Tk selection test!"
    set anchor 1.6
    set selend 1.18

    set result [list]
    lappend result [$e get 1.0 1.end]

    # Get the x,y coords of the second T in "Tcl/Tk"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down to set the insert cursor position
    event generate $e <Enter>
    event generate $e <Button-1> -x $anchor_x -y $anchor_y

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor







|
<
<
<





|
|
|

|
|

|

|
<
<
|
|
|
|
<




<
|
<


<
<
<
|

|
<
|








<
<
|
|
<
|




<
<




|
<
<
|
|
<
|











|







<
<
|
|
<
|








<
<
|
|
<
|








|
<
<
|
|
<
|











|







<
<
|

|
|
<
|
















|







179
180
181
182
183
184
185
186



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201


202
203
204
205

206
207
208
209

210

211
212



213
214
215

216
217
218
219
220
221
222
223
224


225
226

227
228
229
230
231


232
233
234
235
236


237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260

261
262
263
264
265
266
267
268
269


270
271

272
273
274
275
276
277
278
279
280
281


282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303


304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
        return ""
    }
    return $sel
}

# Begining of the actual tests

test event-1.1 {Tk_HandleEvent procedure, filter events for dead windows} {



    button .b -text Test
    pack .b
    bindtags .b .b
    update
    bind .b <Destroy> {
	lappend x destroy
	event generate .b <1>
	event generate .b <ButtonRelease-1>
    }
    bind .b <1> {
	lappend x button
    }
    set x {}
    destroy .b
    set x


} {destroy}
test event-1.2 {event generate <Alt-z>} {
	catch {destroy .e}
	catch {unset ::event12result}

	set ::event12result 0
	pack [entry .e]
	update
	bind .e <Alt-z> {set ::event12result "1"}

	focus -force .e ; event generate .e <Alt-z>

	destroy .e
	set ::event12result



} 1

test event-2.1(keypress) {type into entry widget and hit Return} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    set return_binding 0
    bind $e <Return> {set return_binding 1}
    tkwait visibility $e
    _keypress_string $e HELLO\n
    list [$e get] $return_binding


} {HELLO 1}
test event-2.2(keypress) {type into entry widget and then delete some text} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e


    _keypress_string $e MELLO
    _keypress $e BackSpace
    _keypress $e BackSpace
    $e get
} MEL


test event-2.3(keypress) {type into entry widget, triple click,\
	hit Delete key, and then type some more} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e JUMP

    set result [$e get]

    event generate $e <Enter>
    for {set i 0} {$i < 3} {incr i} {
        _pause 100
        event generate $e <ButtonPress-1>
        _pause 100
        event generate $e <ButtonRelease-1>
    }

    _keypress $e Delete
    _keypress_string $e UP
    lappend result [$e get]


} {JUMP UP}
test event-1.4(keypress) {type into text widget and hit Return} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    set return_binding 0
    bind $e <Return> {set return_binding 1}
    tkwait visibility $e
    _keypress_string $e HELLO\n
    list [$e get 1.0 end] $return_binding


} [list "HELLO\n\n" 1]
test event-2.5(keypress) {type into text widget and then delete some text} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e MELLO
    _keypress $e BackSpace
    _keypress $e BackSpace
    $e get 1.0 1.end
} MEL


test event-2.6(keypress) {type into text widget, triple click,\
	hit Delete key, and then type some more} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e JUMP

    set result [$e get 1.0 1.end]

    event generate $e <Enter>
    for {set i 0} {$i < 3} {incr i} {
        _pause 100
        event generate $e <ButtonPress-1>
        _pause 100
        event generate $e <ButtonRelease-1>
    }

    _keypress $e Delete
    _keypress_string $e UP
    lappend result [$e get 1.0 1.end]


} {JUMP UP}

test event-3.1(click-drag) {click and drag in a text widget, this tests\
	tkTextSelectTo in text.tcl} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "A Tcl/Tk selection test!"
    set anchor 1.6
    set selend 1.18

    set result [list]
    lappend result [$e get 1.0 1.end]

    # Get the x,y coords of the second T in "Tcl/Tk"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down to set the insert cursor position
    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

    # Now click and click and drag to the left, over "Tcl/Tk selection"

    event generate $e <Button-1> -x $current_x -y $current_y

    while {[$e compare $current >= [list $anchor - 4 char]]} {
        foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
        event generate $e <B1-Motion> -x $current_x -y $current_y
        set current [$e index [list $current - 1 char]]
        _pause 50
    }

    event generate $e <ButtonRelease-1> -x $current_x -y $current_y
    _pause 200

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

} -cleanup {
    deleteWindows
} -result {{A Tcl/Tk selection test!} 1.6 1.18 {Tk selection} 1.2 {Tcl/Tk selection}}
 test event-3.2(click-drag) {click and drag in an entry widget, this
    tests tkEntryMouseSelect in entry.tcl} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "A Tcl/Tk selection!"
    set anchor 6
    set selend 18

    set result [list]
    lappend result [$e get]

    # Get the x,y coords of the second T in "Tcl/Tk"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down to set the insert cursor position
    event generate $e <Enter>
    event generate $e <Button-1> -x $anchor_x -y $anchor_y

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor







|

















<
<
|
|
|
<
|
















|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368


369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

    # Now click and click and drag to the left, over "Tcl/Tk selection"

    event generate $e <ButtonPress-1> -x $current_x -y $current_y

    while {[$e compare $current >= [list $anchor - 4 char]]} {
        foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
        event generate $e <B1-Motion> -x $current_x -y $current_y
        set current [$e index [list $current - 1 char]]
        _pause 50
    }

    event generate $e <ButtonRelease-1> -x $current_x -y $current_y
    _pause 200

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]



} {{A Tcl/Tk selection test!} 1.6 1.18 {Tk selection} 1.2 {Tcl/Tk selection}}
test event-3.2(click-drag) {click and drag in an entry widget, this\
	tests tkEntryMouseSelect in entry.tcl} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "A Tcl/Tk selection!"
    set anchor 6
    set selend 18

    set result [list]
    lappend result [$e get]

    # Get the x,y coords of the second T in "Tcl/Tk"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down to set the insert cursor position
    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

    # Now click and click and drag to the left, over "Tcl/Tk selection"

    event generate $e <Button-1> -x $current_x -y $current_y

    while {$current >= ($anchor - 4)} {
        foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
        event generate $e <B1-Motion> -x $current_x -y $current_y
        incr current -1
        _pause 50
    }

    event generate $e <ButtonRelease-1> -x $current_x -y $current_y
    _pause 200

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

} -cleanup {
    deleteWindows
} -result {{A Tcl/Tk selection!} 6 18 {Tk selection} 2 {Tcl/Tk selection}}


test event-4.1(double-click-drag) {click down, click up, click down again,
    then drag in a text widget} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "Word select test"
    set anchor 1.8

    # Get the x,y coords of the second e in "select"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down, release, then click down again
    event generate $e <Enter>
    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50

    # Save the highlighted text
    set result [list]
    lappend result [_get_selection $e]

    # Insert cursor should be at beginning of "select"







|

















<
<
|

<
|
|
<
|












|



|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432


433
434

435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]

    # Now click and click and drag to the left, over "Tcl/Tk selection"

    event generate $e <ButtonPress-1> -x $current_x -y $current_y

    while {$current >= ($anchor - 4)} {
        foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
        event generate $e <B1-Motion> -x $current_x -y $current_y
        incr current -1
        _pause 50
    }

    event generate $e <ButtonRelease-1> -x $current_x -y $current_y
    _pause 200

    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Save the highlighted text
    lappend result [_get_selection $e]



} {{A Tcl/Tk selection!} 6 18 {Tk selection} 2 {Tcl/Tk selection}}


test event-4.1(double-click-drag) {click down, click up, click down again,\
	then drag in a text widget} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "Word select test"
    set anchor 1.8

    # Get the x,y coords of the second e in "select"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down, release, then click down again
    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50

    # Save the highlighted text
    set result [list]
    lappend result [_get_selection $e]

    # Insert cursor should be at beginning of "select"
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572

    # Selection should now be "Word select"
    lappend result [_get_selection $e]

    # Insert cursor should be before the r in "Word"
    lappend result [$e index insert]

    return $result
} -cleanup {
    deleteWindows
} -result {select 1.5 1.7 select 1.4 { select} {Word select} 1.2}
test event-4.2(double-click-drag) {click down, click up, click down again,
    then drag in an entry widget} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "Word select test"

    set anchor 8

    # Get the x,y coords of the second e in "select"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down, release, then click down again
    event generate $e <Enter>
    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50

    set result [list]
    lappend result [_get_selection $e]

    # Insert cursor should be at the end of "select"
    lappend result [$e index insert]







|
<
<
|
|
|
<
|













|



|







493
494
495
496
497
498
499
500


501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529

    # Selection should now be "Word select"
    lappend result [_get_selection $e]

    # Insert cursor should be before the r in "Word"
    lappend result [$e index insert]

    set result


} {select 1.5 1.7 select 1.4 { select} {Word select} 1.2}
test event-4.2(double-click-drag) {click down, click up, click down again,\
	then drag in an entry widget} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "Word select test"

    set anchor 8

    # Get the x,y coords of the second e in "select"
    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    # Click down, release, then click down again
    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50

    set result [list]
    lappend result [_get_selection $e]

    # Insert cursor should be at the end of "select"
    lappend result [$e index insert]
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

    # Selection should now be "Word select"
    lappend result [_get_selection $e]

    # Insert cursor should be before the r in "Word"
    lappend result [$e index insert]

    return $result
} -cleanup {
    deleteWindows
} -result {select 11 7 select 4 { select} {Word select} 2}

test event-5.1(triple-click-drag) {Triple click and drag across lines in a
        text widget, this should extend the selection to the new line} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "LINE ONE\nLINE TWO\nLINE THREE"

    set anchor 3.2

    # Triple click one third line leaving mouse down

    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    event generate $e <Enter>

    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50

    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50

    event generate $e <Button-1> -x $anchor_x -y $anchor_y
    _pause 50

    set result [list]
    lappend result [_get_selection $e]

    # Drag up to second line








|
<
<
|

|
|
<
|














|




|




|







560
561
562
563
564
565
566
567


568
569
570
571

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

    # Selection should now be "Word select"
    lappend result [_get_selection $e]

    # Insert cursor should be before the r in "Word"
    lappend result [$e index insert]

    set result


} {select 11 7 select 4 { select} {Word select} 2}

test event-5.1(triple-click-drag) {Triple click and drag across lines in\
        a text widget, this should extend the selection to the new line} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    _keypress_string $e "LINE ONE\nLINE TWO\nLINE THREE"

    set anchor 3.2

    # Triple click one third line leaving mouse down

    foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break

    event generate $e <Enter>

    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50

    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
    _pause 50

    event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
    _pause 50

    set result [list]
    lappend result [_get_selection $e]

    # Drag up to second line

662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
    foreach {current_x current_y} [_text_ind_to_x_y $e $current] break

    event generate $e <B1-Motion> -x $current_x -y $current_y
    _pause 50

    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
} -result [list "LINE THREE\n" "LINE TWO\nLINE THREE\n" \
        "LINE ONE\nLINE TWO\nLINE THREE\n"]

test event-6.1(button-state) {button press in a window that is then
        destroyed, when the mouse is moved into another window it
        should not generate a <B1-motion> event since the mouse
        was not pressed down in that window} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]

    event generate $t <Button-1>
    destroy $t
    set t [toplevel .t]
    set motion nomotion
    bind $t <B1-Motion> {set motion inmotion}
    event generate $t <Motion>
    return $motion
} -cleanup {
    deleteWindows
} -result {nomotion}

test event-7.1(double-click) {A double click on a lone character
    in a text widget should select that character} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"








|
|
<
|


|
|
|
|
<
|


|





|
<
<
|


|
<
|







616
617
618
619
620
621
622
623
624

625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641


642
643
644
645

646
647
648
649
650
651
652
653
    foreach {current_x current_y} [_text_ind_to_x_y $e $current] break

    event generate $e <B1-Motion> -x $current_x -y $current_y
    _pause 50

    lappend result [_get_selection $e]

    set result


} [list "LINE THREE\n" "LINE TWO\nLINE THREE\n" \
        "LINE ONE\nLINE TWO\nLINE THREE\n"]

test event-6.1(button-state) {button press in a window that is then\
        destroyed, when the mouse is moved into another window it\
        should not generate a <B1-motion> event since the mouse\
        was not pressed down in that window} {

    destroy .t
    set t [toplevel .t]

    event generate $t <ButtonPress-1>
    destroy $t
    set t [toplevel .t]
    set motion nomotion
    bind $t <B1-Motion> {set motion inmotion}
    event generate $t <Motion>
    set motion


} nomotion

test event-7.1(double-click) {A double click on a lone character
	in a text widget should select that character} {

    destroy .t
    set t [toplevel .t]
    set e [text $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770

    set right_x [expr {($x1 + $width) - 2}]
    set right_y $middle_y

    # Double click near left hand egde of the letter A

    event generate $e <Enter>
    event generate $e <Button-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <Button-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50

    set result [list]
    lappend result [$e index insert]
    lappend result [_get_selection $e]

    # Clear selection by clicking at 0,0

    event generate $e <Button-1> -x 0 -y 0
    _pause 50
    event generate $e <ButtonRelease-1> -x 0 -y 0
    _pause 50

    # Double click near right hand edge of the letter A

    event generate $e <Button-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <Button-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
} -result {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character
    in an entry widget should select that character} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"








|



|










|






|



|







|
<
<
|
|
|
<
|







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705


706
707
708

709
710
711
712
713
714
715
716

    set right_x [expr {($x1 + $width) - 2}]
    set right_y $middle_y

    # Double click near left hand egde of the letter A

    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonPress-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50

    set result [list]
    lappend result [$e index insert]
    lappend result [_get_selection $e]

    # Clear selection by clicking at 0,0

    event generate $e <ButtonPress-1> -x 0 -y 0
    _pause 50
    event generate $e <ButtonRelease-1> -x 0 -y 0
    _pause 50

    # Double click near right hand edge of the letter A

    event generate $e <ButtonPress-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonPress-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result


} {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character\
	in an entry widget should select that character} {

    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

    set right_x [expr {($x1 + $width) - 2}]
    set right_y $middle_y

    # Double click near left hand egde of the letter A

    event generate $e <Enter>
    event generate $e <Button-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <Button-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50

    set result [list]
    lappend result [$e index insert]
    lappend result [_get_selection $e]

    # Clear selection by clicking at 0,0

    event generate $e <Button-1> -x 0 -y 0
    _pause 50
    event generate $e <ButtonRelease-1> -x 0 -y 0
    _pause 50

    # Double click near right hand edge of the letter A

    event generate $e <Button-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <Button-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
} -result {4 A 4 A}

test event-8 {event generate with keysyms corresponding to
              multi-byte virtual keycodes - bug
              e36963bfe8df9f5e528134707a91b9c0051de723} -constraints nonPortable -setup {
    deleteWindows
    set res [list ]
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    bind $e <Key> {lappend res keycode: %k keysym: %K}
    focus -force $e
    update
    event generate $e <diaeresis>
    # The value now contained in $res depends on the actual
    # physical keyboard layout and keycode generated, from
    # the hardware on which the test suite happens to run.
    # We don't need (and we can't really) check correctness
    # of the (system-dependent) keycode received, however
    # Tk should be able to associate this keycode to a
    # (system-independent) known keysym, unless the system
    # running the test does not have a keyboard with a
    # diaeresis key.
    if {[expr {[lindex $res 3] ne "??"}]} {
        # keyboard has a physical diaeresis key and bug is fixed
        return "OK"
    } else  {
        return "Test failed, unless the keyboard tied to the system \
                on which this test is run does NOT have a diaeresis \
                physical key - in this case, test is actually void."
    }
} -cleanup {
    deleteWindows
} -result {OK}

# cleanup
update
unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}
rename _keypress_lookup {}
rename _keypress {}
rename _pause {}
rename _text_ind_to_x_y {}
rename _get_selection {}

cleanupTests
return









|



|










|






|



|







|
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<

<
<










<
<
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768


769
770












771

















772

773

774


775
776
777
778
779
780
781
782
783
784



    set right_x [expr {($x1 + $width) - 2}]
    set right_y $middle_y

    # Double click near left hand egde of the letter A

    event generate $e <Enter>
    event generate $e <ButtonPress-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonPress-1> -x $left_x -y $left_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $left_x -y $left_y
    _pause 50

    set result [list]
    lappend result [$e index insert]
    lappend result [_get_selection $e]

    # Clear selection by clicking at 0,0

    event generate $e <ButtonPress-1> -x 0 -y 0
    _pause 50
    event generate $e <ButtonRelease-1> -x 0 -y 0
    _pause 50

    # Double click near right hand edge of the letter A

    event generate $e <ButtonPress-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonPress-1> -x $right_x -y $right_y
    _pause 50
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result


} {4 A 4 A}













# cleanup



















destroy .t




unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}
rename _keypress_lookup {}
rename _keypress {}
rename _pause {}
rename _text_ind_to_x_y {}
rename _get_selection {}

cleanupTests
return


Changes to tests/filebox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out Tk's "tk_getOpenFile" and
# "tk_getSaveFile" commands. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test fileDialog-0.1 {GetFileName: file types: MakeFilter() fails} {




|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out Tk's "tk_getOpenFile" and
# "tk_getSaveFile" commands. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test fileDialog-0.1 {GetFileName: file types: MakeFilter() fails} {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    if {!$isNative} {
	after 100 EnterFileByKey $parent [list $fileName] [list $fileDir]
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <Button-1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc EnterFileByKey {parent fileName fileDir} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_filedialog







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    if {!$isNative} {
	after 100 EnterFileByKey $parent [list $fileName] [list $fileDir]
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc EnterFileByKey {parent fileName fileDir} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_filedialog
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
#
#----------------------------------------------------------------------

if {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile,notAqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getOpenFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -multiple, -parent, -title, -typevariable, or -command}
set unknownOptionsMsg(tk_getSaveFile,notAqua) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getSaveFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -parent, -title, -typevariable, -command, or -confirmoverwrite}

set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {







|
















|
<
|
<







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114

115
116
117
118
119
120
121

    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <KeyPress> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
#
#----------------------------------------------------------------------

if {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}

set unknownOptionsMsg(tk_getSaveFile) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}


set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
	# Extension adding is only done when using the non-motif file
	# box with an extension-less filename
	if {!$mode} {
	    set addedExtensions {NONE {} .txt .txt}
	}
    }

    test filebox-1.1.1-$mode "tk_getOpenFile command" -constraints notAqua -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua)
    test filebox-1.1.2-$mode "tk_getOpenFile command" -constraints aqua -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua)

    catch {tk_getOpenFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
        if {[string index $option 0] eq "-"} {
	    test filebox-1.2-$mode$option "tk_getOpenFile command" -body {
		tk_getOpenFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
        }
    }

    test filebox-1.3.1-$mode "tk_getOpenFile command" -constraints notAqua -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua)
    test filebox-1.3.2-$mode "tk_getOpenFile command" -constraints aqua -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua)
    test filebox-1.4-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-1.5-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-1.6-$mode "tk_getOpenFile command" -body {







|

|
<
<
<













|

|
<
<
<







151
152
153
154
155
156
157
158
159
160



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176



177
178
179
180
181
182
183
	# Extension adding is only done when using the non-motif file
	# box with an extension-less filename
	if {!$mode} {
	    set addedExtensions {NONE {} .txt .txt}
	}
    }

    test filebox-1.1-$mode "tk_getOpenFile command" -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile)




    catch {tk_getOpenFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
        if {[string index $option 0] eq "-"} {
	    test filebox-1.2-$mode$option "tk_getOpenFile command" -body {
		tk_getOpenFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
        }
    }

    test filebox-1.3-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile)



    test filebox-1.4-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-1.5-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-1.6-$mode "tk_getOpenFile command" -body {
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
	    } else {
	    }
	    set choice [tk_getOpenFile -title "Press Ok" \
		    -filetypes $filters($x) -parent $parent \
		    -initialfile $fileName -initialdir $fileDir \
		    -typevariable tv]
	    if {[info exists tv]} {
		set typeName $tv
	    } else {
		set typeName "-unset-"
	    }
	    set typeName
        } $res
    }

    test filebox-4.1.1-$mode "tk_getSaveFile command" -constraints notAqua -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua)
    test filebox-4.1.2-$mode "tk_getSaveFile command" -constraints aqua -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua)

    catch {tk_getSaveFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
	if {[string index $option 0] eq "-"} {
	    test filebox-4.2-$mode$option "tk_getSaveFile command" -body {
		tk_getSaveFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
	}
    }

    test filebox-4.3.1-$mode "tk_getSaveFile command" -constraints notAqua -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua)
    test filebox-4.3.2-$mode "tk_getSaveFile command" -constraints aqua -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua)
    test filebox-4.4-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-4.5-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-4.6-$mode "tk_getSaveFile command" -body {







|







|

|
<
<
<













|

|
<
<
<







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310



311
312
313
314
315
316
317
	    } else {
	    }
	    set choice [tk_getOpenFile -title "Press Ok" \
		    -filetypes $filters($x) -parent $parent \
		    -initialfile $fileName -initialdir $fileDir \
		    -typevariable tv]
	    if {[info exists tv]} {
		regexp {^(.*) \(.*\)$} $tv dummy typeName
	    } else {
		set typeName "-unset-"
	    }
	    set typeName
        } $res
    }

    test filebox-4.1-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile)




    catch {tk_getSaveFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
	if {[string index $option 0] eq "-"} {
	    test filebox-4.2-$mode$option "tk_getSaveFile command" -body {
		tk_getSaveFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
	}
    }

    test filebox-4.3-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile)



    test filebox-4.4-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-4.5-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-4.6-$mode "tk_getSaveFile command" -body {
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
		set gotmessage
	    } \
	    -match glob \
	    -result "*RUBBISH*"
    }

    # The rest of the tests need to be executed on Unix only.
    # They test whether the dialog box widgets were implemented correctly.
    # These tests are not
    # needed on the other platforms because they use native file dialogs.
}

set tk_strictMotif $tk_strictMotif_old

# cleanup
removeFile filebox.tmp
cleanupTests
return







|










459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
		set gotmessage
	    } \
	    -match glob \
	    -result "*RUBBISH*"
    }

    # The rest of the tests need to be executed on Unix only.
    # The test whether the dialog box widgets were implemented correctly.
    # These tests are not
    # needed on the other platforms because they use native file dialogs.
}

set tk_strictMotif $tk_strictMotif_old

# cleanup
removeFile filebox.tmp
cleanupTests
return

Changes to tests/focus.test.

1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test



testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

proc focusSetup {} {
    destroy .t
    toplevel .t
    wm geom .t +0+0
    foreach i {b1 b2 b3 b4} {
	    button .t.$i -text .t.$i -relief raised -bd 2
	    pack .t.$i
    }
    tkwait visibility .t.b4
}
proc focusSetupAlt {} {
    global env
    destroy .alt
    toplevel .alt -screen $env(TK_ALT_DISPLAY)
    foreach i {a b c d} {
	button .alt.$i -text .alt.$i -relief raised -bd 2
	pack .alt.$i
    }
    tkwait visibility .alt.d
}




# The following procedure ensures that there is no input focus
# in this application.  It does it by arranging for another
# application to grab the focus.  The "after" and "update" stuff
# is needed to wait long enough for pending actions to get through
# the X server and possibly also the window manager.


proc focusClear {} {
    global x;
    after 200 {set x 1}
    tkwait variable x
    dobg {focus -force .; update}
    update
}


# Button used in some tests in the whole test file
button .b -text .b -relief raised -bd 2
pack .b

# Make sure the window manager knows who has focus
catch {fixfocus}

# cleanupbg will be after 4.3 test
setupbg
update

bind all <FocusIn> {
    append focusInfo "in %W %d\n"
}
bind all <FocusOut> {
    append focusInfo "out %W %d\n"
}
bind all <Key> {
    append focusInfo "press %W %K"
}
focusSetup
if {[testConstraint altDisplay]} {
    focusSetupAlt
}


test focus-1.1 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear
    focus
} -result {}
test focus-1.2 {Tk_FocusCmd procedure} -constraints {
	unix altDisplay
} -body {
    focus .alt.b
    focus
} -result {}
test focus-1.3 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear
    focus .t.b3
    focus
} -result {}
test focus-1.4 {Tk_FocusCmd procedure} -constraints unix -body {
    focus ""
} -returnCodes ok -result {}
test focus-1.5 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear
    focus -force .t
    focus .t.b3
    focus
}  -result {.t.b3}
test focus-1.6 {Tk_FocusCmd procedure} -constraints unix -body {
    focus .gorp
} -returnCodes error -result {bad window path name ".gorp"}
test focus-1.7 {Tk_FocusCmd procedure} -constraints unix -body {
    focus .gorp a
} -returnCodes error -result {bad option ".gorp": must be -displayof, -force, or -lastfor}
test focus-1.8 {Tk_FocusCmd procedure, focussing on dead window} -constraints {
	unix
} -setup {
    destroy .t2
} -body {
    focusClear
    toplevel .t2
    wm geom .t2 +10+10
    frame .t2.f -width 200 -height 100 -bd 2 -relief raised
    frame .t2.f2 -width 200 -height 100 -bd 2 -relief raised
    pack .t2.f .t2.f2
    bind .t2.f <Destroy> {focus .t2.f}
    bind .t2.f2 <Destroy> {focus .t2}
    focus -force .t2.f2
    tkwait visibility .t2.f2
    update
    set x [focus]
    destroy .t2.f2
    lappend x [focus]
    destroy .t2.f
    lappend x [focus]
    destroy .t2
    return $x
} -cleanup {
    destroy .t2
} -result {.t2.f2 .t2 .t2}
test focus-1.9 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix
} -body {
    focus -displayof
} -returnCodes error -result {wrong # args: should be "focus -displayof window"}
test focus-1.10 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix
} -body {
    focus -displayof a b
} -returnCodes error -result {wrong # args: should be "focus -displayof window"}
test focus-1.11 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix
} -body {
    focus -displayof .lousy
} -returnCodes error -result {bad window path name ".lousy"}
test focus-1.12 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix
} -body {
    focusClear
    focus .t
    focus -displayof .t.b3
}  -result {}
test focus-1.13 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix
} -body {
    focusClear
    focus -force .t
    focus -displayof .t.b3
} -result {.t}
test focus-1.14 {Tk_FocusCmd procedure, -displayof option} -constraints {
	unix altDisplay
} -body {
    focusClear
    focus -force .alt.c
    focus -displayof .alt
} -result {.alt.c}
test focus-1.15 {Tk_FocusCmd procedure, -force option} -constraints unix -body {
    focus -force
} -returnCodes error -result {wrong # args: should be "focus -force window"}
test focus-1.16 {Tk_FocusCmd procedure, -force option} -constraints unix -body {
    focus -force a b
} -returnCodes error -result {wrong # args: should be "focus -force window"}
test focus-1.17 {Tk_FocusCmd procedure, -force option} -constraints unix -body {
    focus -force foo
} -returnCodes error -result {bad window path name "foo"}
test focus-1.18 {Tk_FocusCmd procedure, -force option} -constraints unix -body {
    focus -force ""
} -returnCodes ok -result {}
test focus-1.19 {Tk_FocusCmd procedure, -force option} -constraints unix -body {
    focusClear
    focus .t.b1
    set x  [list [focus]]
    focus -force .t.b1
    lappend x [focus]
} -result {{} .t.b1}
test focus-1.20 {Tk_FocusCmd procedure, -lastfor option} -constraints {
    unix
} -body {
    focus -lastfor
} -returnCodes error -result {wrong # args: should be "focus -lastfor window"}
test focus-1.21 {Tk_FocusCmd procedure, -lastfor option} -constraints {
    unix
} -body {
    focus -lastfor 1 2
} -returnCodes error -result {wrong # args: should be "focus -lastfor window"}
test focus-1.22 {Tk_FocusCmd procedure, -lastfor option} -constraints {
    unix
} -body {
    focus -lastfor who_knows?
} -returnCodes error -result {bad window path name "who_knows?"}
test focus-1.23 {Tk_FocusCmd procedure, -lastfor option} -constraints {
    unix
} -body {
    focusClear
    focusSetup
    focus .b
    focus .t.b1
    list [focus -lastfor .] [focus -lastfor .t.b3]
} -result {.b .t.b1}
test focus-1.24 {Tk_FocusCmd procedure, -lastfor option} -constraints {
    unix
} -body {
    focusClear
    focusSetup
    update
    focus -lastfor .t.b2
} -result {.t}
test focus-1.25 {Tk_FocusCmd procedure} -constraints unix -body {
    focus -unknown
} -returnCodes error -result {bad option "-unknown": must be -displayof, -force, or -lastfor}


focusSetup
test focus-2.1 {TkFocusFilterEvent procedure} -constraints {
	unix nonPortable testwrapper
} -body {
    focusClear
    focus -force .b

    focusSetup
    update
    set focusInfo {}
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor \
	    -sendevent 0x54217567
    return $focusInfo
} -result {}
test focus-2.2 {TkFocusFilterEvent procedure} -constraints {
	unix nonPortable testwrapper
} -body {
    focusClear
    focus -force .b

    focusSetup
    update
    set focusInfo {}
    event gen .t <FocusIn> -detail NotifyAncestor -sendevent 0x547321ac
    list $focusInfo [focus]
} -result {{in .t NotifyAncestor
} .b}
test focus-2.3 {TkFocusFilterEvent procedure} -constraints {
	unix nonPortable testwrapper
} -body {
    focusClear
    focus -force .b

    focusSetup
    update
    set focusInfo {}
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    update
    list $focusInfo [focus -lastfor .t]
} -result {{out .b NotifyNonlinear
out . NotifyNonlinearVirtual
in .t NotifyNonlinear
} .t}
test focus-2.4 {TkFocusFilterEvent procedure, FocusIn events} -constraints {
    unix nonPortable testwrapper
} -body {
    focusClear
    set result {}
    focus .t.b1
    # Important to end with NotifyAncestor, which is an
    # event that is processed normally. This has a side
    # effect on text 2.5
    foreach detail {NotifyAncestor NotifyNonlinear
	    NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
	    NotifyVirtual NotifyAncestor} {
	focus -force .
	update
	event gen [testwrapper .t] <FocusIn> -detail $detail
	set focusInfo {}
	update
	lappend result $focusInfo
    }
    return $result
} -result {{out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {} {} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
}}
test focus-2.5 {TkFocusFilterEvent procedure, creating FocusInfo struct} -constraints {
    unix nonPortable testwrapper
} -body {
    focusSetup
    focus .t.b1
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    list $focusInfo [focus]
} -result {{out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} .t.b1}

test focus-2.6 {TkFocusFilterEvent procedure, FocusIn events} -constraints {
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    focus .t.b1
    focus .
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    set focusInfo {}
    set x [focus]
    event gen . <x>
    list $x $focusInfo
} -result {.t.b1 {press .t.b1 x}}
test focus-2.7 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    set result {}
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
	    NotifyVirtual} {
	    focus -force .t.b1
	    event gen [testwrapper .t] <FocusOut> -detail $detail
	    update
	    lappend result [focus]
    }
    return $result
} -result {{} .t.b1 {} {} .t.b1 .t.b1 {}}
test focus-2.8 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper
} -body {
    focus -force .t.b1
    event gen .t.b1 <FocusOut> -detail NotifyAncestor
    focus
} -result {.t.b1}
test focus-2.9 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    focus .t.b1
    event gen [testwrapper .] <FocusOut> -detail NotifyAncestor
    focus
} -result {}
test focus-2.10 {TkFocusFilterEvent procedure, Enter events} -constraints {
    unix  testwrapper
} -body {
    set result {}
    focus .t.b1
    focusClear
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	        NotifyNonlinearVirtual NotifyVirtual} {
	    event gen [testwrapper .t] <Enter> -detail $detail -focus 1
	    update
	    lappend result [focus]
	    event gen [testwrapper .t] <Leave> -detail NotifyAncestor
	    update
    }
    return $result
} -result {.t.b1 {} .t.b1 .t.b1 .t.b1}
test focus-2.11 {TkFocusFilterEvent procedure, Enter events} -constraints {
    unix  testwrapper
} -body {
    focusClear
    set focusInfo {}
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor
    update
    return $focusInfo
} -result {}
test focus-2.12 {TkFocusFilterEvent procedure, Enter events} -constraints {
    unix  testwrapper
} -body {
    focus -force .b
    update
    set focusInfo {}
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    return $focusInfo
} -result {}
test focus-2.13 {TkFocusFilterEvent procedure, Enter events} -constraints {
    unix  testwrapper
} -body {
    focus .t.b1
    focusClear
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    set focusInfo {}
    update
    return $focusInfo
} -result {in .t NotifyVirtual
in .t.b1 NotifyAncestor
}
test focus-2.14 {TkFocusFilterEvent procedure, Enter events, ignore errors when setting focus due to implicit focus} -constraints {
	unix testwrapper
} -setup {
    destroy .t2
    set focusInfo {}
} -body {
    focusClear

    toplevel .t2
    wm withdraw .t2
    update

    event gen [testwrapper .t2] <Enter> -detail NotifyAncestor -focus 1
    update
} -cleanup {
    destroy .t2
} -result {}
test focus-2.15 {TkFocusFilterEvent procedure, Leave events} -constraints {
    unix  testwrapper
} -body {
    set result {}
    focus .t.b1
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyVirtual} {
	    focusClear
	    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
	    update
	    event gen [testwrapper .t] <Leave> -detail $detail
	    update
	    lappend result [focus]
    }
    return $result
} -result {{} .t.b1 {} {} {}}
test focus-2.16 {TkFocusFilterEvent procedure, Leave events} -constraints {
    unix  testwrapper
} -body {
    focusClear
    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen [testwrapper .t] <Leave> -detail NotifyAncestor
    update
    return $focusInfo
} -result {out .t.b1 NotifyAncestor
out .t NotifyVirtual
}
test focus-2.17 {TkFocusFilterEvent procedure, Leave events} -constraints {
    unix  testwrapper
} -body {
    focusClear
    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen .t.b1 <Leave> -detail NotifyAncestor
    event gen [testwrapper .] <Leave> -detail NotifyAncestor
    update
    list $focusInfo [focus]
} -result {{out .t.b1 NotifyAncestor
out .t NotifyVirtual
} {}}


test focus-3.1 {SetFocus procedure, create record on focus} -constraints {
    unix  testwrapper
} -body {
    toplevel .t2 -width 250 -height 100
    wm geometry .t2 +0+0
    update
    focus -force .t2
    update
    focus
} -cleanup {
    destroy .t2
} -result {.t2}
# This test produces no result, but it will generate a protocol
# error if Tk forgets to make the window exist before focussing
# on it.
test focus-3.2 {SetFocus procedure, making window exist} -constraints {
	unix testwrapper
} -body {
    update
    button .b2 -text "Another button"
    focus .b2
    update
} -cleanup {
    destroy .b2
    update
} -result {}
# The following test doesn't produce a check-able result, but if
# there are bugs it may generate an X protocol error.
test focus-3.3 {SetFocus procedure, delaying claim of X focus} -constraints {
    unix  testwrapper
} -body {
    focusSetup
    focus -force .t.b2
    update
} -result {}
test focus-3.4 {SetFocus procedure, delaying claim of X focus} -constraints {
    unix  testwrapper
} -body {
    focusSetup
    wm withdraw .t
    focus -force .t.b2
    toplevel .t2 -width 250 -height 100
    wm geometry .t2 +10+10
    focus -force .t2
    wm withdraw .t2
    update
    wm deiconify .t2
    wm deiconify .t
} -cleanup {
    destroy .t2
} -result {}
test focus-3.5 {SetFocus procedure, generating events} -constraints {
	unix testwrapper
} -body {
    focusSetup
    focusClear
    set focusInfo {}
    focus -force .t.b2
    update
    return $focusInfo
} -result {in .t NotifyVirtual
in .t.b2 NotifyAncestor
}
test focus-3.6 {SetFocus procedure, generating events} -constraints {
	unix testwrapper
} -body {
    focusSetup
    focus -force .b
    update
    set focusInfo {}
    focus .t.b2
    update
    return $focusInfo
} -result {out .b NotifyNonlinear
out . NotifyNonlinearVirtual
in .t NotifyNonlinearVirtual
in .t.b2 NotifyNonlinear
}
test focus-3.7 {SetFocus procedure, generating events} -constraints {
unix nonPortable testwrapper
} -body {
    # Non-portable because some platforms generate extra events.

    focusSetup
    focusClear
    set focusInfo {}
    focus .t.b2
    update
    return $focusInfo
} -result {}


test focus-4.1 {TkFocusDeadWindow procedure} -constraints {
	unix testwrapper
} -body {
    focusSetup
    update
    focus -force .b
    update
    destroy .t
    focus
} -result {.b}
test focus-4.2 {TkFocusDeadWindow procedure} -constraints {
	unix testwrapper
} -body {
    focusSetup
    update
    focus -force .t.b2
    focus .b
    update
    destroy .t.b2
    update
    focus
} -result {.b}

# Non-portable due to wm-specific redirection of input focus when
# windows are deleted:

test focus-4.3 {TkFocusDeadWindow procedure} -constraints {
	unix nonPortable testwrapper
} -body {
    focusSetup
    update
    focus .t
    update
    destroy .t
    update
    focus
} -result {}
test focus-4.4 {TkFocusDeadWindow procedure} -constraints {
	unix testwrapper
} -body {
    focusSetup
    focus -force .t.b2
    update
    destroy .t.b2
    focus
} -result {.t}
cleanupbg


# I don't know how to test most of the remaining procedures of this file
# explicitly;  they've already been exercised by the preceding tests.

# Test 5.1 fails (before and after update)
test focus-5.1 {ChangeXFocus procedure, don't take focus unless have it} -constraints {
    unix testwrapper secureserver failsOnUbuntu failsOnXQuarz
} -body {
    setupbg
    focusSetup
    focus -force .t
    update
    set result [focus]
    send [dobg {tk appname}] {focus -force .; update}
    lappend result [focus]
    focus .t.b2
    update
    lappend result [focus]
} -cleanup {
    cleanupbg
} -result {.t {} {}}

destroy .t
bind all <FocusIn> {}
bind all <FocusOut> {}
bind all <Key> {}


fixfocus

test focus-6.1 {miscellaneous - embedded application in same process} -constraints {
    unix  testwrapper
} -setup {
    eval interp delete [interp slaves]
} -body {
    toplevel .t
    wm geometry .t +0+0
    frame .t.f1 -container 1
    frame .t.f2
    pack .t.f1 .t.f2
    entry .t.f2.e1 -bg red
    pack .t.f2.e1
    bind all <FocusIn> {lappend x "focus in %W %d"}
    bind all <FocusOut> {lappend x "focus out %W %d"}
    interp create child
    child eval "set argv {-use [winfo id .t.f1]}"
    load {} Tk child
    child eval {
	    entry .e1 -bg lightBlue
	    pack .e1
	    bind all <FocusIn> {lappend x "focus in %W %d"}
	    bind all <FocusOut> {lappend x "focus out %W %d"}
	    set x {}
    }

    # Claim the focus and wait long enough for it to really arrive.

    focus -force .t.f2.e1
    after 300 {set timer 1}
    vwait timer




|
|





|
>
>

|
|


|



|
|





|








>
>







>








|
<
<
<
|
<
|
|
<
<

>






|


<
<
<
|
<
<
|


|
|
<
<


|
|



|
|
|
|
|




|
|
|
|
|
|
|
|
<
<
<
<
<
















|
<
<
|
|
<
<
|
|
|
<
<
|
|
|
<
<
|
|
|
<
<



|
|
<
<



|
|
<
<
<


|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
<
<
|
|
|
<
<
|
|
|
<
<
|
|
|
<
<
<
<



|
|
<
|
<



|
|
|
|

<
<
|
<
<
<

>





|
|
|
<
<
<

>





|

|
<
<
<

>






|



|
|
<
<















|
|












|
|
<





|



<
|
|
<






|

|
|
|
<




|
|
|
|

|
|
|
|
<



|
|
|
<



|
|
|
<




|
|
|
|
|
|

|
|
|
|
<




|
|
|
|
<





|
|
|
|
<





|
|


|
<
<
<
<
<

>



>


<

|
|
|
<




|
|
|
|
|
|

|
|
|
|
|
<






|
|


|
|
|
<








|



<
|
|
<






|
|
<



|
<
<




|
|
|
<


|
|
<



|
|
|
<










|
|
<
|
<
<





|
|


|
<
<






|
|




|
|
<

>





|
<
|

|
<
<






|
|
<
<








|
>


>
|
<
<







|
|
<
<





|
<
<




|
|
|
<
<









<
<
|
>
|


|
|
<

>
|
|
<

|













|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58



59

60
61


62
63
64
65
66
67
68
69
70
71
72



73


74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102





103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119


120
121


122
123
124


125
126
127


128
129
130


131
132
133
134
135


136
137
138
139
140



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163


164
165
166


167
168
169


170
171
172




173
174
175
176
177

178

179
180
181
182
183
184
185
186


187



188
189
190
191
192
193
194
195
196
197



198
199
200
201
202
203
204
205
206
207



208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261

262
263

264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293

294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341





342
343
344
345
346
347
348
349

350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392
393
394

395
396

397
398
399
400
401
402
403
404

405
406
407
408


409
410
411
412
413
414
415

416
417
418
419

420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437

438


439
440
441
442
443
444
445
446
447
448


449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470

471
472
473


474
475
476
477
478
479
480
481


482
483
484
485
486
487
488
489
490
491
492
493
494
495


496
497
498
499
500
501
502
503
504


505
506
507
508
509
510


511
512
513
514
515
516
517


518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533

534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

button .b -text .b -relief raised -bd 2
pack .b

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

proc focusSetup {} {
    catch {destroy .t}
    toplevel .t
    wm geom .t +0+0
    foreach i {b1 b2 b3 b4} {
	button .t.$i -text .t.$i -relief raised -bd 2
	pack .t.$i
    }
    tkwait visibility .t.b4
}
proc focusSetupAlt {} {
    global env
    catch {destroy .alt}
    toplevel .alt -screen $env(TK_ALT_DISPLAY)
    foreach i {a b c d} {
	button .alt.$i -text .alt.$i -relief raised -bd 2
	pack .alt.$i
    }
    tkwait visibility .alt.d
}

# Make sure the window manager knows who has focus
catch {fixfocus}

# The following procedure ensures that there is no input focus
# in this application.  It does it by arranging for another
# application to grab the focus.  The "after" and "update" stuff
# is needed to wait long enough for pending actions to get through
# the X server and possibly also the window manager.

setupbg
proc focusClear {} {
    global x;
    after 200 {set x 1}
    tkwait variable x
    dobg {focus -force .; update}
    update
}

focusSetup



if {[testConstraint altDisplay]} {

    focusSetupAlt
}


update

bind all <FocusIn> {
    append focusInfo "in %W %d\n"
}
bind all <FocusOut> {
    append focusInfo "out %W %d\n"
}
bind all <KeyPress> {
    append focusInfo "press %W %K"
}






test focus-1.1 {Tk_FocusCmd procedure} unix {
    focusClear
    focus
} {}
test focus-1.2 {Tk_FocusCmd procedure} {unix altDisplay} {


    focus .alt.b
    focus
} {}
test focus-1.3 {Tk_FocusCmd procedure} unix {
    focusClear
    focus .t.b3
    focus
} {}
test focus-1.4 {Tk_FocusCmd procedure} unix {
    list [catch {focus ""} msg] $msg
} {0 {}}
test focus-1.5 {Tk_FocusCmd procedure} unix {
    focusClear
    focus -force .t
    focus .t.b3
    focus
} {.t.b3}
test focus-1.6 {Tk_FocusCmd procedure} unix {
    list [catch {focus .gorp} msg] $msg
} {1 {bad window path name ".gorp"}}
test focus-1.7 {Tk_FocusCmd procedure} unix {
    list [catch {focus .gorp a} msg] $msg
} {1 {bad option ".gorp": must be -displayof, -force, or -lastfor}}
test focus-1.8 {Tk_FocusCmd procedure, focussing on dead window} unix {





    toplevel .t2
    wm geom .t2 +10+10
    frame .t2.f -width 200 -height 100 -bd 2 -relief raised
    frame .t2.f2 -width 200 -height 100 -bd 2 -relief raised
    pack .t2.f .t2.f2
    bind .t2.f <Destroy> {focus .t2.f}
    bind .t2.f2 <Destroy> {focus .t2}
    focus -force .t2.f2
    tkwait visibility .t2.f2
    update
    set x [focus]
    destroy .t2.f2
    lappend x [focus]
    destroy .t2.f
    lappend x [focus]
    destroy .t2
    set x


} {.t2.f2 .t2 .t2}
test focus-1.9 {Tk_FocusCmd procedure, -displayof option} unix {


    list [catch {focus -displayof} msg] $msg
} {1 {wrong # args: should be "focus -displayof window"}}
test focus-1.10 {Tk_FocusCmd procedure, -displayof option} unix {


    list [catch {focus -displayof a b} msg] $msg
} {1 {wrong # args: should be "focus -displayof window"}}
test focus-1.11 {Tk_FocusCmd procedure, -displayof option} unix {


    list [catch {focus -displayof .lousy} msg] $msg
} {1 {bad window path name ".lousy"}}
test focus-1.12 {Tk_FocusCmd procedure, -displayof option} unix {


    focusClear
    focus .t
    focus -displayof .t.b3
} {}
test focus-1.13 {Tk_FocusCmd procedure, -displayof option} unix {


    focusClear
    focus -force .t
    focus -displayof .t.b3
} {.t}
test focus-1.14 {Tk_FocusCmd procedure, -displayof option} {unix altDisplay} {



    focus -force .alt.c
    focus -displayof .alt
} {.alt.c}
test focus-1.15 {Tk_FocusCmd procedure, -force option} unix {
    list [catch {focus -force} msg] $msg
} {1 {wrong # args: should be "focus -force window"}}
test focus-1.16 {Tk_FocusCmd procedure, -force option} unix {
    list [catch {focus -force a b} msg] $msg
} {1 {wrong # args: should be "focus -force window"}}
test focus-1.17 {Tk_FocusCmd procedure, -force option} unix {
    list [catch {focus -force foo} msg] $msg
} {1 {bad window path name "foo"}}
test focus-1.18 {Tk_FocusCmd procedure, -force option} unix {
    list [catch {focus -force ""} msg] $msg
} {0 {}}
test focus-1.19 {Tk_FocusCmd procedure, -force option} unix {
    focusClear
    focus .t.b1
    set x  [list [focus]]
    focus -force .t.b1
    lappend x [focus]
} {{} .t.b1}
test focus-1.20 {Tk_FocusCmd procedure, -lastfor option} unix {


    list [catch {focus -lastfor} msg] $msg
} {1 {wrong # args: should be "focus -lastfor window"}}
test focus-1.21 {Tk_FocusCmd procedure, -lastfor option} unix {


    list [catch {focus -lastfor 1 2} msg] $msg
} {1 {wrong # args: should be "focus -lastfor window"}}
test focus-1.22 {Tk_FocusCmd procedure, -lastfor option} unix {


    list [catch {focus -lastfor who_knows?} msg] $msg
} {1 {bad window path name "who_knows?"}}
test focus-1.23 {Tk_FocusCmd procedure, -lastfor option} unix {




    focus .b
    focus .t.b1
    list [focus -lastfor .] [focus -lastfor .t.b3]
} {.b .t.b1}
test focus-1.24 {Tk_FocusCmd procedure, -lastfor option} unix {

    destroy .t

    focusSetup
    update
    focus -lastfor .t.b2
} {.t}
test focus-1.25 {Tk_FocusCmd procedure} unix {
    list [catch {focus -unknown} msg] $msg
} {1 {bad option "-unknown": must be -displayof, -force, or -lastfor}}



test focus-2.1 {TkFocusFilterEvent procedure} {unix nonPortable testwrapper} {



    focus -force .b
    destroy .t
    focusSetup
    update
    set focusInfo {}
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor \
	    -sendevent 0x54217567
    list $focusInfo
} {{}}
test focus-2.2 {TkFocusFilterEvent procedure} {unix nonPortable testwrapper} {



    focus -force .b
    destroy .t
    focusSetup
    update
    set focusInfo {}
    event gen .t <FocusIn> -detail NotifyAncestor -sendevent 0x547321ac
    list $focusInfo [focus]
} {{in .t NotifyAncestor
} .b}
test focus-2.3 {TkFocusFilterEvent procedure} {unix nonPortable testwrapper} {



    focus -force .b
    destroy .t
    focusSetup
    update
    set focusInfo {}
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    update
    list $focusInfo [focus -lastfor .t]
} {{out .b NotifyNonlinear
out . NotifyNonlinearVirtual
in .t NotifyNonlinear
} .t}
test focus-2.4 {TkFocusFilterEvent procedure, FocusIn events} \
	{unix nonPortable testwrapper} {


    set result {}
    focus .t.b1
    # Important to end with NotifyAncestor, which is an
    # event that is processed normally. This has a side
    # effect on text 2.5
    foreach detail {NotifyAncestor NotifyNonlinear
	    NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
	    NotifyVirtual NotifyAncestor} {
	focus -force .
	update
	event gen [testwrapper .t] <FocusIn> -detail $detail
	set focusInfo {}
	update
	lappend result $focusInfo
    }
    set result
} {{out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} {} {} {out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
}}
test focus-2.5 {TkFocusFilterEvent procedure, creating FocusInfo struct} \
	{unix nonPortable testwrapper} {

    focusSetup
    focus .t.b1
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    list $focusInfo [focus]
} {{out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} .t.b1}

test focus-2.6 {TkFocusFilterEvent procedure, FocusIn events} \
	{unix testwrapper} {

    focus .t.b1
    focus .
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    set focusInfo {}
    set x [focus]
    event gen . <KeyPress-x>
    list $x $focusInfo
} {.t.b1 {press .t.b1 x}}
test focus-2.7 {TkFocusFilterEvent procedure, FocusOut events} \
	{unix testwrapper} {

    set result {}
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
	    NotifyVirtual} {
	focus -force .t.b1
	event gen [testwrapper .t] <FocusOut> -detail $detail
	update
	lappend result [focus]
    }
    set result
} {{} .t.b1 {} {} .t.b1 .t.b1 {}}
test focus-2.8 {TkFocusFilterEvent procedure, FocusOut events} \
	{unix testwrapper} {

    focus -force .t.b1
    event gen .t.b1 <FocusOut> -detail NotifyAncestor
    focus
} {.t.b1}
test focus-2.9 {TkFocusFilterEvent procedure, FocusOut events} \
	{unix testwrapper} {

    focus .t.b1
    event gen [testwrapper .] <FocusOut> -detail NotifyAncestor
    focus
} {}
test focus-2.10 {TkFocusFilterEvent procedure, Enter events} \
	{unix testwrapper} {

    set result {}
    focus .t.b1
    focusClear
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyVirtual} {
	event gen [testwrapper .t] <Enter> -detail $detail -focus 1
	update
	lappend result [focus]
	event gen [testwrapper .t] <Leave> -detail NotifyAncestor
	update
    }
    set result
} {.t.b1 {} .t.b1 .t.b1 .t.b1}
test focus-2.11 {TkFocusFilterEvent procedure, Enter events} \
	{unix testwrapper} {

    focusClear
    set focusInfo {}
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor
    update
    set focusInfo
} {}
test focus-2.12 {TkFocusFilterEvent procedure, Enter events} \
	{unix testwrapper} {

    focus -force .b
    update
    set focusInfo {}
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo
} {}
test focus-2.13 {TkFocusFilterEvent procedure, Enter events} \
	{unix testwrapper} {

    focus .t.b1
    focusClear
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    set focusInfo {}
    update
    set focusInfo
} {in .t NotifyVirtual
in .t.b1 NotifyAncestor
}
test focus-2.14 {TkFocusFilterEvent procedure, Enter events, ignore errors when setting focus due to implicit focus} {unix testwrapper} {





    focusClear
    catch {destroy .t2}
    toplevel .t2
    wm withdraw .t2
    update
    set focusInfo {}
    event gen [testwrapper .t2] <Enter> -detail NotifyAncestor -focus 1
    update

    destroy .t2
} {}
test focus-2.15 {TkFocusFilterEvent procedure, Leave events} \
	{unix testwrapper} {

    set result {}
    focus .t.b1
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyVirtual} {
	focusClear
	event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
	update
	event gen [testwrapper .t] <Leave> -detail $detail
	update
	lappend result [focus]
    }
    set result
} {{} .t.b1 {} {} {}}
test focus-2.16 {TkFocusFilterEvent procedure, Leave events} \
	{unix testwrapper} {
    set result {}

    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen [testwrapper .t] <Leave> -detail NotifyAncestor
    update
    set focusInfo
} {out .t.b1 NotifyAncestor
out .t NotifyVirtual
}
test focus-2.17 {TkFocusFilterEvent procedure, Leave events} \
	{unix testwrapper} {
    set result {}

    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen .t.b1 <Leave> -detail NotifyAncestor
    event gen [testwrapper .] <Leave> -detail NotifyAncestor
    update
    list $focusInfo [focus]
} {{out .t.b1 NotifyAncestor
out .t NotifyVirtual
} {}}


test focus-3.1 {SetFocus procedure, create record on focus} \
	{unix testwrapper} {

    toplevel .t2 -width 250 -height 100
    wm geometry .t2 +0+0
    update
    focus -force .t2
    update
    focus
} {.t2}
catch {destroy .t2}

# This test produces no result, but it will generate a protocol
# error if Tk forgets to make the window exist before focussing
# on it.
test focus-3.2 {SetFocus procedure, making window exist} {unix testwrapper} {


    update
    button .b2 -text "Another button"
    focus .b2
    update
} {}
catch {destroy .b2}
update

# The following test doesn't produce a check-able result, but if
# there are bugs it may generate an X protocol error.
test focus-3.3 {SetFocus procedure, delaying claim of X focus} \
	{unix testwrapper} {

    focusSetup
    focus -force .t.b2
    update
} {}
test focus-3.4 {SetFocus procedure, delaying claim of X focus} \
	{unix testwrapper} {

    focusSetup
    wm withdraw .t
    focus -force .t.b2
    toplevel .t2 -width 250 -height 100
    wm geometry .t2 +10+10
    focus -force .t2
    wm withdraw .t2
    update
    wm deiconify .t2
    wm deiconify .t
} {}
catch {destroy .t2}

test focus-3.5 {SetFocus procedure, generating events} {unix testwrapper} {


    focusSetup
    focusClear
    set focusInfo {}
    focus -force .t.b2
    update
    set focusInfo
} {in .t NotifyVirtual
in .t.b2 NotifyAncestor
}
test focus-3.6 {SetFocus procedure, generating events} {unix testwrapper} {


    focusSetup
    focus -force .b
    update
    set focusInfo {}
    focus .t.b2
    update
    set focusInfo
} {out .b NotifyNonlinear
out . NotifyNonlinearVirtual
in .t NotifyNonlinearVirtual
in .t.b2 NotifyNonlinear
}
test focus-3.7 {SetFocus procedure, generating events} \
	{unix nonPortable testwrapper} {

    # Non-portable because some platforms generate extra events.

    focusSetup
    focusClear
    set focusInfo {}
    focus .t.b2
    update
    set focusInfo

} {}

test focus-4.1 {TkFocusDeadWindow procedure} {unix testwrapper} {


    focusSetup
    update
    focus -force .b
    update
    destroy .t
    focus
} {.b}
test focus-4.2 {TkFocusDeadWindow procedure} {unix testwrapper} {


    focusSetup
    update
    focus -force .t.b2
    focus .b
    update
    destroy .t.b2
    update
    focus
} {.b}

# Non-portable due to wm-specific redirection of input focus when
# windows are deleted:

test focus-4.3 {TkFocusDeadWindow procedure} {unix nonPortable testwrapper} {


    focusSetup
    update
    focus .t
    update
    destroy .t
    update
    focus
} {}
test focus-4.4 {TkFocusDeadWindow procedure} {unix testwrapper} {


    focusSetup
    focus -force .t.b2
    update
    destroy .t.b2
    focus
} {.t}



# I don't know how to test most of the remaining procedures of this file
# explicitly;  they've already been exercised by the preceding tests.

setupbg
test focus-5.1 {ChangeXFocus procedure, don't take focus unless have it} \
	{unix testwrapper secureserver failsOnUbuntu failsOnQuarz} {


    focusSetup
    focus -force .t
    update
    set result [focus]
    send [dobg {tk appname}] {focus -force .; update}
    lappend result [focus]
    focus .t.b2
    update
    lappend result [focus]


} {.t {} {}}

catch {destroy .t}
bind all <FocusIn> {}
bind all <FocusOut> {}
bind all <KeyPress> {}
cleanupbg

fixfocus

test focus-6.1 {miscellaneous - embedded application in same process} \
	{unix testwrapper} {

    eval interp delete [interp slaves]
    catch {destroy .t}
    toplevel .t
    wm geometry .t +0+0
    frame .t.f1 -container 1
    frame .t.f2
    pack .t.f1 .t.f2
    entry .t.f2.e1 -bg red
    pack .t.f2.e1
    bind all <FocusIn> {lappend x "focus in %W %d"}
    bind all <FocusOut> {lappend x "focus out %W %d"}
    interp create child
    child eval "set argv {-use [winfo id .t.f1]}"
    load {} Tk child
    child eval {
	entry .e1 -bg lightBlue
	pack .e1
	bind all <FocusIn> {lappend x "focus in %W %d"}
	bind all <FocusOut> {lappend x "focus out %W %d"}
	set x {}
    }

    # Claim the focus and wait long enough for it to really arrive.

    focus -force .t.f2.e1
    after 300 {set timer 1}
    vwait timer
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709

    # Bring the focus back to the main application.

    focus .t.f2.e1
    after 300 {set timer 1}
    vwait timer
    set result [list $x [child eval {set x}]]
    return $result
} -cleanup {
    interp delete child
    destroy .t
    bind all <FocusIn> {}
    bind all <FocusOut> {}
} -result {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}

test focus-6.2 {miscellaneous - embedded application in different process} -constraints {
    unix  testwrapper

} -body {
    setupbg
    toplevel .t
    wm geometry .t +0+0
    frame .t.f1 -container 1
    frame .t.f2
    pack .t.f1 .t.f2
    entry .t.f2.e1 -bg red
    pack .t.f2.e1
    bind all <FocusIn> {lappend x "focus in %W %d"}
    bind all <FocusOut> {lappend x "focus out %W %d"}
    setupbg -use [winfo id .t.f1]
    dobg {
	    entry .e1 -bg lightBlue
	    pack .e1
	    bind all <FocusIn> {lappend x "focus in %W %d"}
	    bind all <FocusOut> {lappend x "focus out %W %d"}
	    set x {}
    }

    # Claim the focus and wait long enough for it to really arrive.

    focus -force .t.f2.e1
    after 300 {set timer 1}
    vwait timer







<
<

|
<
<
|
<
|
|
>
|












|
|
|
|
|







576
577
578
579
580
581
582


583
584


585

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

    # Bring the focus back to the main application.

    focus .t.f2.e1
    after 300 {set timer 1}
    vwait timer
    set result [list $x [child eval {set x}]]


    interp delete child
    set result


} {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}

test focus-6.2 {miscellaneous - embedded application in different process} \
	{unix testwrapper} {
    eval interp delete [interp slaves]
    catch {destroy .t}
    setupbg
    toplevel .t
    wm geometry .t +0+0
    frame .t.f1 -container 1
    frame .t.f2
    pack .t.f1 .t.f2
    entry .t.f2.e1 -bg red
    pack .t.f2.e1
    bind all <FocusIn> {lappend x "focus in %W %d"}
    bind all <FocusOut> {lappend x "focus out %W %d"}
    setupbg -use [winfo id .t.f1]
    dobg {
	entry .e1 -bg lightBlue
	pack .e1
	bind all <FocusIn> {lappend x "focus in %W %d"}
	bind all <FocusOut> {lappend x "focus out %W %d"}
	set x {}
    }

    # Claim the focus and wait long enough for it to really arrive.

    focus -force .t.f2.e1
    after 300 {set timer 1}
    vwait timer
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758


759
760
761
762

    # Bring the focus back to the main application.

    focus .t.f2.e1
    after 300 {set timer 1}
    vwait timer
    set result [list $x [dobg {set x}]]
    return $result
} -cleanup {
    destroy .t
    cleanupbg
    bind all <FocusIn> {}
    bind all <FocusOut> {}

} -result {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}

test focus-7.1 {TkSetFocusWin procedure, unmapped windows} -setup {
    # TkSetFocusWin handles the case of not yet mapped windows
    # by not setting the focus on them right at the time it is
    # requested, but by scheduling an event handler that will
    # set the focus later once it gets mapped. The purpose of
    # this test is to check that event scheduling and deletion
    # work as expected (bug [08e2f8e6f0]).
    toplevel .top
    spinbox .top.s1
    spinbox .top.s2
    spinbox .top.s3
    grid .top.s1 .top.s2 .top.s3
} -body {
    focus -force .top.s2
    focus -force .top.s3
    update
    focus
} -cleanup {
    destroy .top
} -result {.top.s3}


deleteWindows



# cleanup
cleanupTests
return







<
<
<

<
<
>
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>
>




625
626
627
628
629
630
631



632


633
634
635






















636
637
638
639
640
641
642

    # Bring the focus back to the main application.

    focus .t.f2.e1
    after 300 {set timer 1}
    vwait timer
    set result [list $x [dobg {set x}]]



    cleanupbg


    set result
} {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}























deleteWindows
bind all <FocusIn> {}
bind all <FocusOut> {}

# cleanup
cleanupTests
return

Changes to tests/focusTcl.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

















14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101

102
103
104


105
106
107

108
109

110
111

112
113
114
115

116
117
118

119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236




237
238

239



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# This file is a Tcl script to test out the features of the script
# file focus.tcl, which includes the procedures tk_focusNext and
# tk_focusPrev, among other things.  This file is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


















option add *takeFocus 1
option add *highlightThickness 2
. configure -takefocus 1 -highlightthickness 2

proc setup1 w {
    if {$w == "."} {
        set w ""
    }
    foreach i {a b c d} {
        destroy $w.$i
        frame  $w.$i -width 200 -height 50 -bd 2 -relief raised
        pack $w.$i
    }
    .b configure -width 0 -height 0
    foreach i {x y z} {
        destroy $w.b.$i
        button $w.b.$i -text "Button $w.b.$i"
        pack $w.b.$i -side left
    }
    if {![winfo ismapped $w.b.z]} {
        tkwait visibility $w.b.z
    }
}

proc cleanup1 w {
    if {$w == "."} {
        set w ""
    }
    foreach i {a b c d} {
        destroy $w.$i
    }
    foreach i {x y z} {
        destroy $w.b.$i
    }
}


test focusTcl-1.1 {tk_focusNext procedure, no children} -body {
    tk_focusNext .
} -result {.}

test focusTcl-1.2 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .
} -cleanup {
    cleanup1 .
} -result {.a}
test focusTcl-1.3 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .a
} -cleanup {
    cleanup1 .
} -result {.b}
test focusTcl-1.4 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.b.x}
test focusTcl-1.5 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .b.x
} -cleanup {
    cleanup1 .
} -result {.b.y}
test focusTcl-1.6 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .b.y
} -cleanup {
    cleanup1 .
} -result {.b.z}
test focusTcl-1.7 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .b.z
} -cleanup {
    cleanup1 .
} -result {.c}
test focusTcl-1.8 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    tk_focusNext .c
} -cleanup {
    cleanup1 .
} -result {.d}
test focusTcl-1.9 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .

    tk_focusNext .d
} -cleanup {

    cleanup1 .
} -result {.}



test focusTcl-1.10 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    foreach w {.b .b.x .b.y .c .d} {

        $w configure -takefocus 0
    }

    tk_focusNext .a
} -cleanup {

    cleanup1 .
} -result {.b.z}
test focusTcl-1.11 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .

    foreach w {.b .b.x .b.y .c .d} {
        $w configure -takefocus 0
    }

    tk_focusNext .b.z
} -cleanup {

    cleanup1 .
} -result {.}

test focusTcl-1.12 {tk_focusNext procedure, basic tree traversal} -body {
    setup1 .
    deleteWindows
    setup1 .
    update
    . configure -takefocus 0
    tk_focusNext .d
} -cleanup {
    . configure -takefocus 1
    cleanup1 .
} -result {.a}


test focusTcl-2.1 {tk_focusNext procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusNext .a
} -cleanup {
    deleteWindows
} -result {.b}
test focusTcl-2.2 {tk_focusNext procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusNext .d
} -cleanup {
    deleteWindows
} -result {.}
test focusTcl-2.3 {tk_focusNext procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusNext .t
} -cleanup {
    deleteWindows
} -result {.t}
test focusTcl-2.4 {tk_focusNext procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a
    setup1 .t
    raise .t.b

    tk_focusNext .t
} -cleanup {
    deleteWindows
} -result {.t.a}
test focusTcl-2.5 {tk_focusNext procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a
    setup1 .t
    raise .t.b

    tk_focusNext .t.b.z
} -cleanup {
    deleteWindows
} -result {.t}


test focusTcl-3.1 {tk_focusPrev procedure, no children} -body {
    tk_focusPrev .
} -result {.}

test focusTcl-3.2 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .
} -cleanup {
    cleanup1 .
} -result {.d}
test focusTcl-3.3 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .d
} -cleanup {
    cleanup1 .
} -result {.c}
test focusTcl-3.4 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .c
} -cleanup {
    cleanup1 .
} -result {.b.z}
test focusTcl-3.5 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .




    tk_focusPrev .b.z
} -cleanup {

    cleanup1 .



} -result {.b.y}
test focusTcl-3.6 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .b.y
} -cleanup {
    cleanup1 .
} -result {.b.x}
test focusTcl-3.7 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .b.x
} -cleanup {
    cleanup1 .
} -result {.b}
test focusTcl-3.8 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .b
} -cleanup {
    cleanup1 .
} -result {.a}
test focusTcl-3.9 {tk_focusPrev procedure, basic tree traversal} -body {
    setup1 .
    tk_focusPrev .a
} -cleanup {
    cleanup1 .
} -result {.}


deleteWindows
setup1 .
toplevel .t
wm geom .t +0+0
toplevel .t2
wm geom .t2 -0+0
raise .t .a
test focusTcl-4.1 {tk_focusPrev procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusPrev .
} -cleanup {
    deleteWindows
} -result {.d}
test focusTcl-4.2 {tk_focusPrev procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusPrev .b
} -cleanup {
    deleteWindows
} -result {.a}
test focusTcl-4.3 {tk_focusPrev procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a

    tk_focusPrev .t
} -cleanup {
    deleteWindows
} -result {.t}

test focusTcl-4.4 {tk_focusPrev procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a
    setup1 .t
    update
    .t configure -takefocus 0
    raise .t.b

    tk_focusPrev .t
} -cleanup {
    deleteWindows
} -result {.t.b.z}
test focusTcl-4.5 {tk_focusPrev procedure, toplevels} -setup {
    deleteWindows
} -body {
    setup1 .
    toplevel .t
    wm geom .t +0+0
    toplevel .t2
    wm geom .t2 -0+0
    raise .t .a
    setup1 .t
    update
    .t configure -takefocus 0
    raise .t.b

    tk_focusPrev .t.a
} -cleanup {
    deleteWindows
} -result {.t.b.z}


test focusTcl-5.1 {tkFocusOK procedure, -takefocus 0} -body {

    setup1 .
    .b.x configure -takefocus 0
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.b.y}
test focusTcl-5.2 {tkFocusOK procedure, -takefocus 1} -body {

    setup1 .
    pack forget .b
    update
    .b configure -takefocus ""
    .b.y configure -takefocus ""
    .b.z configure -takefocus ""
    list [tk_focusNext .a] [tk_focusNext .b.x]
} -cleanup {
    cleanup1 .
} -result {.c .c}
test focusTcl-5.3 {tkFocusOK procedure, -takefocus procedure} -body {
    proc t w {
    if {$w == ".b.x"} {
        return 1
    } elseif {$w == ".b.y"} {
        return ""
    }
    return 0
    }

    setup1 .
    pack forget .b.y
    update
    .b configure -takefocus ""
    foreach w {.b.x .b.y .b.z .c} {
        $w configure -takefocus t
    }
    list [tk_focusNext .a] [tk_focusNext .b.x]
} -cleanup {
    cleanup1 .
} -result {.b.x .d}
test focusTcl-5.4 {tkFocusOK procedure, -takefocus ""} -body {

    setup1 .
    .b.x configure -takefocus ""
    update
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.b.x}
test focusTcl-5.5 {tkFocusOK procedure, -takefocus "", not mapped} -body {

    setup1 .
    .b.x configure -takefocus ""
    pack forget .b.x
    update
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.b.y}
test focusTcl-5.6 {tkFocusOK procedure, -takefocus "", not mapped} -body {

    setup1 .
    foreach w {.b.x .b.y .b.z} {
        $w configure -takefocus ""
    }
    pack forget .b
    update
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.c}
test focusTcl-5.7 {tkFocusOK procedure, -takefocus "", not mapped} -body {

    setup1 .
    .b.y configure -takefocus 1
    pack forget .b.y
    update
    tk_focusNext .b.x
} -cleanup {
    cleanup1 .
} -result {.b.z}
test focusTcl-5.8 {tkFocusOK procedure, -takefocus "", not mapped} -body {
    proc always args {return 1}

    setup1 .
    .b.y configure -takefocus always
    pack forget .b.y
    update
    tk_focusNext .b.x
} -cleanup {
    cleanup1 .
} -result {.b.y}
test focusTcl-5.9 {tkFocusOK procedure, -takefocus "", window disabled} -body {

    setup1 .
    foreach w {.b.x .b.y .b.z} {
        $w configure -takefocus ""
    }
    update
    .b.x configure -state disabled
    tk_focusNext .b
} -cleanup {
    cleanup1 .
} -result {.b.y}
test focusTcl-5.10 {tkFocusOK procedure, -takefocus "", check for bindings} -body {

    setup1 .
    foreach w {.a .b .c .d} {
        $w configure -takefocus ""
    }
    update
    bind .a <Key> {foo}
    list [tk_focusNext .] [tk_focusNext .a]
} -cleanup {
    cleanup1 .
} -result {.a .b.x}
test focusTcl-5.11 {tkFocusOK procedure, -takefocus "", check for bindings} -body {

    setup1 .
    foreach w {.a .b .c .d} {
        $w configure -takefocus ""
    }
    update
    bind Frame <Key> {foo}
    list [tk_focusNext .] [tk_focusNext .a]
} -cleanup {
    cleanup1 .
    bind Frame <Key> {}
} -result {.a .b}


. configure -takefocus 0 -highlightthickness 0
option clear

# cleanup
cleanupTests
return








|
|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
|
>
|
|
|
>
>
|
|
|
>
|
|
>
|
|
>
|
|
|
|
>
|
|
|
>
|
|
>
|
|
<
|
<





|
|
<
<

<
<
|
<
|
|
|
|
|
|
|

<
<
|
|
<
<
<
<
<
<
<
<
<

<
<
|
|
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
|
|
|

<
<
|
|
<
<
<
|
<
<
<
<
|
<

<
<
|
<
<
<
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
|
|
>
|
>
>
>
|
|
<

<
<
|
|
<

<
<
|
|
<

<
<
|
|
<

<
<
|
<








|
<
<
<
<
<
<
<
<
<

<
<
|
|
<
<
<
<
<
<
<
<
<

<
<
|
|
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|

<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|

|
|
>



<
<
|
|
>







<
<
|
|

|
|
|
|
|
|

|





|


<
<
|
|
>




<
<
|
|
>


|


<
<
|
|
>


|

|


<
<
|
|
>


|


<
<
|
|

>


|


<
<
|
|
>


|




<
<
|
|
>


|




<
<
|
|
>


|




<
<
<
|

|






<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34


































35
36
37












































38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72

73
74
75
76
77
78
79


80


81

82
83
84
85
86
87
88
89


90
91









92


93
94









95


96









97
98
99
100


101
102



103




104

105


106



107
108
109




















110
111
112
113
114
115
116
117
118
119
120
121
122
123

124


125
126

127


128
129

130


131
132

133


134

135
136
137
138
139
140
141
142
143









144


145
146









147


148
149









150


151










152
153
154
155
156
157


158
159













160


161
162
163
164
165
166
167
168


169
170
171
172
173
174
175
176
177
178


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197


198
199
200
201
202
203
204


205
206
207
208
209
210
211
212


213
214
215
216
217
218
219
220
221
222


223
224
225
226
227
228
229
230


231
232
233
234
235
236
237
238
239


240
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268
269



270
271
272
273
274
275
276
277
278



# This file is a Tcl script to test out the features of the script
# file focus.tcl, which includes the procedures tk_focusNext and
# tk_focusPrev, among other things.  This file is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

proc setup1 w {
    if {$w == "."} {
	set w ""
    }
    foreach i {a b c d} {
	frame  $w.$i -width 200 -height 50 -bd 2 -relief raised
	pack $w.$i
    }
    .b configure -width 0 -height 0
    foreach i {x y z} {
	button $w.b.$i -text "Button $w.b.$i"
	pack $w.b.$i -side left
    }
    if {![winfo ismapped $w.b.z]} {
	tkwait visibility $w.b.z
    }
}

option add *takeFocus 1
option add *highlightThickness 2
. configure -takefocus 1 -highlightthickness 2


































test focusTcl-1.1 {tk_focusNext procedure, no children} {
    tk_focusNext .
} {.}












































setup1 .
test focusTcl-1.2 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .
} {.a}
test focusTcl-1.3 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .a
} {.b}
test focusTcl-1.4 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .b
} {.b.x}
test focusTcl-1.5 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .b.x
} {.b.y}
test focusTcl-1.6 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .b.y
} {.b.z}
test focusTcl-1.7 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .b.z
} {.c}
test focusTcl-1.8 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .c
} {.d}
test focusTcl-1.9 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .d
} {.}
foreach w {.b .b.x .b.y .c .d} {
    $w configure -takefocus 0
}
test focusTcl-1.10 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .a
} {.b.z}
test focusTcl-1.11 {tk_focusNext procedure, basic tree traversal} {
    tk_focusNext .b.z
} {.}

test focusTcl-1.12 {tk_focusNext procedure, basic tree traversal} {

    deleteWindows
    setup1 .
    update
    . configure -takefocus 0
    tk_focusNext .d
} {.a}
. configure -takefocus 1





deleteWindows

setup1 .
toplevel .t
wm geom .t +0+0
toplevel .t2
wm geom .t2 -0+0
raise .t .a
test focusTcl-2.1 {tk_focusNext procedure, toplevels} {
    tk_focusNext .a


} {.b}
test focusTcl-2.2 {tk_focusNext procedure, toplevels} {









    tk_focusNext .d


} {.}
test focusTcl-2.3 {tk_focusNext procedure, toplevels} {









    tk_focusNext .t


} {.t}









setup1 .t
raise .t.b
test focusTcl-2.4 {tk_focusNext procedure, toplevels} {
    tk_focusNext .t


} {.t.a}
test focusTcl-2.5 {tk_focusNext procedure, toplevels} {



    tk_focusNext .t.b.z




} {.t}




deleteWindows



test focusTcl-3.1 {tk_focusPrev procedure, no children} {
    tk_focusPrev .
} {.}




















setup1 .
test focusTcl-3.2 {tk_focusPrev procedure, basic tree traversal} {
    tk_focusPrev .
} {.d}
test focusTcl-3.3 {tk_focusPrev procedure, basic tree traversal} {
    tk_focusPrev .d
} {.c}
test focusTcl-3.4 {tk_focusPrev procedure, basic tree traversal} {
    tk_focusPrev .c
} {.b.z}
test focusTcl-3.5 {tk_focusPrev procedure, basic tree traversal} {
    tk_focusPrev .b.z
} {.b.y}
test focusTcl-3.6 {tk_focusPrev procedure, basic tree traversal} {

    tk_focusPrev .b.y


} {.b.x}
test focusTcl-3.7 {tk_focusPrev procedure, basic tree traversal} {

    tk_focusPrev .b.x


} {.b}
test focusTcl-3.8 {tk_focusPrev procedure, basic tree traversal} {

    tk_focusPrev .b


} {.a}
test focusTcl-3.9 {tk_focusPrev procedure, basic tree traversal} {

    tk_focusPrev .a


} {.}


deleteWindows
setup1 .
toplevel .t
wm geom .t +0+0
toplevel .t2
wm geom .t2 -0+0
raise .t .a
test focusTcl-4.1 {tk_focusPrev procedure, toplevels} {









    tk_focusPrev .


} {.d}
test focusTcl-4.2 {tk_focusPrev procedure, toplevels} {









    tk_focusPrev .b


} {.a}
test focusTcl-4.3 {tk_focusPrev procedure, toplevels} {









    tk_focusPrev .t


} {.t}










setup1 .t
update
.t configure -takefocus 0
raise .t.b
test focusTcl-4.4 {tk_focusPrev procedure, toplevels} {
    tk_focusPrev .t


} {.t.b.z}
test focusTcl-4.5 {tk_focusPrev procedure, toplevels} {













    tk_focusPrev .t.a


} {.t.b.z}

deleteWindows
test focusTcl-5.1 {tkFocusOK procedure, -takefocus 0} {
    deleteWindows
    setup1 .
    .b.x configure -takefocus 0
    tk_focusNext .b


} {.b.y}
test focusTcl-5.2 {tkFocusOK procedure, -takefocus 1} {
    deleteWindows
    setup1 .
    pack forget .b
    update
    .b configure -takefocus ""
    .b.y configure -takefocus ""
    .b.z configure -takefocus ""
    list [tk_focusNext .a] [tk_focusNext .b.x]


} {.c .c}
test focusTcl-5.3 {tkFocusOK procedure, -takefocus procedure} {
    proc t w {
	if {$w == ".b.x"} {
	    return 1
	} elseif {$w == ".b.y"} {
	    return ""
	}
	return 0
    }
    deleteWindows
    setup1 .
    pack forget .b.y
    update
    .b configure -takefocus ""
    foreach w {.b.x .b.y .b.z .c} {
	$w configure -takefocus t
    }
    list [tk_focusNext .a] [tk_focusNext .b.x]


} {.b.x .d}
test focusTcl-5.4 {tkFocusOK procedure, -takefocus ""} {
    deleteWindows
    setup1 .
    .b.x configure -takefocus ""
    update
    tk_focusNext .b


} {.b.x}
test focusTcl-5.5 {tkFocusOK procedure, -takefocus "", not mapped} {
    deleteWindows
    setup1 .
    .b.x configure -takefocus ""
    pack unpack .b.x
    update
    tk_focusNext .b


} {.b.y}
test focusTcl-5.6 {tkFocusOK procedure, -takefocus "", not mapped} {
    deleteWindows
    setup1 .
    foreach w {.b.x .b.y .b.z} {
	$w configure -takefocus ""
    }
    pack unpack .b
    update
    tk_focusNext .b


} {.c}
test focusTcl-5.7 {tkFocusOK procedure, -takefocus "", not mapped} {
    deleteWindows
    setup1 .
    .b.y configure -takefocus 1
    pack unpack .b.y
    update
    tk_focusNext .b.x


} {.b.z}
test focusTcl-5.8 {tkFocusOK procedure, -takefocus "", not mapped} {
    proc always args {return 1}
    deleteWindows
    setup1 .
    .b.y configure -takefocus always
    pack unpack .b.y
    update
    tk_focusNext .b.x


} {.b.y}
test focusTcl-5.9 {tkFocusOK procedure, -takefocus "", window disabled} {
    deleteWindows
    setup1 .
    foreach w {.b.x .b.y .b.z} {
	$w configure -takefocus ""
    }
    update
    .b.x configure -state disabled
    tk_focusNext .b


} {.b.y}
test focusTcl-5.10 {tkFocusOK procedure, -takefocus "", check for bindings} {
    deleteWindows
    setup1 .
    foreach w {.a .b .c .d} {
	$w configure -takefocus ""
    }
    update
    bind .a <Key> {foo}
    list [tk_focusNext .] [tk_focusNext .a]


} {.a .b.x}
test focusTcl-5.11 {tkFocusOK procedure, -takefocus "", check for bindings} {
    deleteWindows
    setup1 .
    foreach w {.a .b .c .d} {
	$w configure -takefocus ""
    }
    update
    bind Frame <Key> {foo}
    list [tk_focusNext .] [tk_focusNext .a]



} {.a .b}

bind Frame <Key> {}
. configure -takefocus 0 -highlightthickness 0
option clear

# cleanup
cleanupTests
return



Changes to tests/font.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38



39



40

41




42



43

44










45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80

81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280

281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301


302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317


318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480

481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

517
518
519
520
521
522
523


524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595





596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663
664
665
666
667

668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781
782

783
784
785
786
787
788

789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
804
805
806
807
808

809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971

972
973
974
975
976
977

978
979
980
981
982
983
984
985
986
987
988
989

990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041


1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306

1307
1308
1309
1310


1311
1312

1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598

1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751









1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819



1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852






1853
1854
1855
1856
1857
1858
1859
1860
1861
1862

1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887




1888

1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988

1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
# This file is a Tcl script to test out Tk's "font" command
# plus the procedures in tkFont.c.  It is organized in the
# standard white-box fashion for Tcl tests.
#
# Copyright © 1996-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Some tests require support for 4-byte UTF-8 sequences
testConstraint fullutf [expr {[format %c 0x010000] != "\uFFFD"}]
testConstraint utfcompat [expr {([string length "\U10000"] == 2) && [package vsatisfies [package provide Tcl] 8]}]
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

set defaultfontlist [font names]




proc getnondefaultfonts {} {
    global defaultfontlist
    set nondeffonts [list ]
    foreach afont [font names] {
        if {$afont ni $defaultfontlist} {
            lappend nondeffonts $afont
        }
    }
    set nondeffonts
}

proc clearnondefaultfonts {} {
    foreach afont [getnondefaultfonts] {
        font delete $afont
    }
}




deleteWindows



# Toplevel used (in some tests) of the whole file

toplevel .t




wm geom .t +0+0



update idletasks












switch [tk windowingsystem] {
    x11	 	{set fixed "TkFixedFont"}
    win32	{set fixed "courier 12"}
    aqua	{set fixed "monaco 9"}
}


# Procedure used in tests: 24.15, 26.*, 28.*, 30.*, 31.*, 32.1
proc csetup {{str ""}} {
    focus -force .t.c
    .t.c dchars text 0 end
    .t.c insert text 0 $str
    .t.c focus text
}


test font-1.1 {TkFontPkgInit} -setup {
    catch {interp delete foo}
} -body {
    interp create foo
    foo eval {
	load {} Tk
	wm geometry . +0+0
	update
    }
    interp delete foo
} -result {}


test font-2.1 {TkFontPkgFree} -setup {
    catch {interp delete foo}
    set x {}
} -body {
    interp create foo


    # Makes sure that named font was visible only to child interp.

    foo eval {
	load {} Tk
	wm geometry . +0+0
	button .b -font {times 16} -text "hi"
	pack .b
	font create wiggles -family courier -underline 1
	update
    }
    lappend x [catch {font configure wiggles} msg; set msg]

    # Tests cancelling the idle handler for TheWorldHasChanged,
    # because app goes away before idle serviced.

    foo eval {
	.b config -font wiggles
	font config wiggles -size 24
	destroy .
    }
    lappend x [foo eval {catch {font families} msg; set msg}]
} -cleanup {
    interp delete foo

} -result {{named font "wiggles" doesn't exist} {can't invoke "font" command: application has been destroyed}}


test font-3.1 {font command: general} -body {
    font
} -returnCodes error -result {wrong # args: should be "font option ?arg?"}
test font-3.2 {font command: general} -body {
    font xyz
} -returnCodes error -result {bad option "xyz": must be actual, configure, create, delete, families, measure, metrics, or names}


test font-4.1 {font command: actual: arguments} -body {
    # (skip < 0)
    font actual xyz -displayof
} -returnCodes error -result {value for "-displayof" missing}
test font-4.2 {font command: actual: arguments} -body {
    # (objc < 3)
    font actual
} -returnCodes error -result {wrong # args: should be "font actual font ?-displayof window? ?-option? ?--? ?char?"}
test font-4.3 {font command: actual: arguments} -body {
    # (objc - skip > 4) when skip == 0
    font actual xyz abc def
} -returnCodes error -result {wrong # args: should be "font actual font ?-displayof window? ?-option? ?--? ?char?"}
test font-4.4 {font command: actual: displayof specified, so skip to next} -body {
    catch {font actual xyz -displayof . -size}
} -result 0
test font-4.5 {font command: actual: displayof specified, so skip to next} -body {
    lindex [font actual xyz -displayof .] 0
} -result {-family}
test font-4.6 {font command: actual: arguments} -body {
    # (objc - skip > 4) when skip == 2
    font actual xyz -displayof . abc def
} -returnCodes error -result {wrong # args: should be "font actual font ?-displayof window? ?-option? ?--? ?char?"}
test font-4.7 {font command: actual: arguments} -constraints noExceed -body {
    # (tkfont == NULL)
    font actual "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-4.8 {font command: actual: all attributes} -body {
    # not (objc > 3) so objPtr = NULL
    lindex [font actual {-family times}] 0
} -result {-family}
test font-4.9 {font command: actual} -constraints {unix noExceed failsOnUbuntu} -body {
    # (objc > 3) so objPtr = objv[3 + skip]
    string tolower [font actual {-family times} -family]
} -result {times}
test font-4.10 {font command: actual} -constraints win -body {
    # (objc > 3) so objPtr = objv[3 + skip]
    font actual {-family times} -family
} -result {times}
test font-4.11 {font command: bad option} -body {
    font actual xyz -style
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-4.12 {font command: actual} -body {
    font actual {-family times} -- \uD800
} -match glob -result {*}
test font-4.13 {font command: actual} -body {
    font actual {-family times} -- \uDC00
} -match glob -result {*}
test font-4.14 {font command: actual} -constraints {utfcompat win} -body {
    font actual {-family times} -family -- \uD800\uDC00
} -result {times}
test font-4.15 {font command: actual} -body {
    font actual {-family times} -- \uDC00\uD800
} -returnCodes 1 -match glob -result {expected a single character but got "*"}
test font-4.16 {font command: actual} -constraints {fullutf win} -body {
    font actual {-family times} -family -- \U10000
} -result {times}


test font-5.1 {font command: configure} -body {
    # (objc < 3)
    font configure
} -returnCodes error -result {wrong # args: should be "font configure fontname ?-option value ...?"}
test font-5.2 {font command: configure: non-existent font} -body {
    # (namedHashPtr == NULL)
    font configure xyz
} -returnCodes error -result {named font "xyz" doesn't exist}
test font-5.3 {font command: configure: "deleted" font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (nfPtr->deletePending != 0)

    font create xyz
    .t.f configure -font xyz
    font delete xyz
    font configure xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {named font "xyz" doesn't exist}
test font-5.4 {font command: configure: get all options} -setup {
    catch {font delete xyz}
} -body {
    # (objc == 3) so objPtr = NULL

    font create xyz -family xyz
    lindex [font configure xyz] 1
} -cleanup {
    font delete xyz
} -result xyz
test font-5.5 {font command: configure: get one option} -setup {
    clearnondefaultfonts
} -body {
    # (objc == 4) so objPtr = objv[3]

    font create xyz -family xyz
    font configure xyz -family
    getnondefaultfonts
} -cleanup {
    font delete xyz
} -result xyz
test font-5.6 {font command: configure: update existing font} -setup {
    catch {font delete xyz}
} -body {
    # else result = ConfigAttributesObj()

    font create xyz
    font configure xyz -family xyz
    update
    font configure xyz -family
} -cleanup {
    font delete xyz
} -result xyz
test font-5.7 {font command: configure: bad option} -setup {
    catch {font delete xyz}
} -body {
    font create xyz
    font configure xyz -style
} -cleanup {
    font delete xyz
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}


test font-6.1 {font command: create: make up name} -setup {
    clearnondefaultfonts
} -body {
    # (objc < 3) so name = NULL

    font create
    getnondefaultfonts
} -cleanup {
    font delete font1
} -result {font1}
test font-6.2 {font command: create: name specified} -setup {
    clearnondefaultfonts
} -body {
    # not (objc < 3)

    font create xyz
    getnondefaultfonts
} -cleanup {
    font delete xyz
} -result {xyz}
test font-6.3 {font command: create: name not really specified} -setup {
    clearnondefaultfonts
} -body {
    # (name[0] == '-') so name = NULL

    font create -family xyz
    getnondefaultfonts
} -cleanup {
    font delete font1
} -result {font1}
test font-6.4 {font command: create: generate name} -setup {
} -body {
    # (name == NULL)

    font create -family one
    font create -family two
    font create -family three
    font delete font2
    font create -family four
    font configure font2 -family
} -cleanup {
    font delete font1 font2 font3
} -result {four}
test font-6.5 {font command: create: bad option creating new font} -setup {
    catch {font delete xyz}
} -body {
    # name was specified so skip = 3

    font create xyz -xyz times
} -returnCodes error -result {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-6.6 {font command: create: bad option creating new font} -setup {
    clearnondefaultfonts
} -body {
    # name was not specified so skip = 2

    font create -xyz times
} -returnCodes error -result {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-6.7 {font command: create: already exists} -setup {
    catch {font delete xyz}
} -body {
    # (CreateNamedFont() != TCL_OK)

    font create xyz
    font create xyz
} -cleanup {
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}

test font-7.1 {font command: delete: arguments} -body {
    # (objc < 3)
    font delete
} -returnCodes error -result {wrong # args: should be "font delete fontname ?fontname ...?"}
test font-7.2 {font command: delete: loop test} -setup {
    clearnondefaultfonts
    set x {}
} -body {
    # for (i = 2; i < objc; i++)


    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
    lappend x [lsort [getnondefaultfonts]]
    font delete a e c b
    lappend x [lsort [getnondefaultfonts]]
} -cleanup {
    getnondefaultfonts
} -result {{a b c d e} d}
test font-7.3 {font command: delete: loop test} -setup {
    clearnondefaultfonts
    set x {}
} -body {
    # (namedHashPtr == NULL) in middle of loop


    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
    lappend x [lsort [getnondefaultfonts]]
    catch {font delete a d q c e b}
    lappend x [lsort [getnondefaultfonts]]
} -cleanup {
    clearnondefaultfonts
} -result {{a b c d e} {b c e}}
test font-7.4 {font command: delete: non-existent} -setup {
    catch {font delete xyz}
} -body {
    # (namedHashPtr == NULL)

    font delete xyz
} -returnCodes error -result {named font "xyz" doesn't exist}
test font-7.5 {font command: delete: mark for later deletion} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (nfPtr->refCount != 0)

    font create xyz
    .t.f configure -font xyz
    font delete xyz
    font actual xyz
    font configure xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {named font "xyz" doesn't exist}
test font-7.6 {font command: delete: mark for later deletion} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (nfPtr->refCount != 0)

    font create xyz
    .t.f configure -font xyz
    font delete xyz
    font actual xyz
    catch {font configure xyz}
    .t.f cget -font
} -cleanup {
	destroy .t.f
} -result xyz
test font-7.7 {font command: delete: actually delete} -setup {
    catch {font delete xyz}
} -body {
    # not (nfPtr->refCount != 0)
    font create xyz -underline 1
    font delete xyz
    font config xyz
} -returnCodes error -match glob -result {*}


test font-8.1 {font command: families: arguments} -body {
    # (skip < 0)
    font families -displayof
} -returnCodes error -result {value for "-displayof" missing}
test font-8.2 {font command: families: arguments} -body {
    # (objc - skip != 2) when skip == 0
    font families xyz
} -returnCodes error -result {wrong # args: should be "font families ?-displayof window?"}
test font-8.3 {font command: families: arguments} -body {
    # (objc - skip != 2) when skip == 2
    font families -displayof . xyz
} -returnCodes error -result {wrong # args: should be "font families ?-displayof window?"}
test font-8.4 {font command: families} -constraints failsOnUbuntu -body {
    # TkpGetFontFamilies()
    regexp -nocase times [font families]
} -result 1


test font-9.1 {font command: measure: arguments} -body {
    # (skip < 0)
    expr {[font measure xyz -displayof] > 0}
} -returnCodes ok -result 1
test font-9.2 {font command: measure: arguments} -body {
    # (objc - skip != 4)
    font measure
} -returnCodes error -result {wrong # args: should be "font measure font ?-displayof window? text"}
test font-9.3 {font command: measure: arguments} -body {
    # (objc - skip != 4)
    font measure xyz abc def
} -returnCodes error -result {wrong # args: should be "font measure font ?-displayof window? text"}
test font-9.4 {font command: measure: arguments} -constraints noExceed -body {
    # (tkfont == NULL)
    font measure "\{xyz" abc
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-9.5 {font command: measure} -body {
    # Tk_TextWidth()
    expr {[font measure $fixed "abcdefg"] == [font measure $fixed "a"]*7 }
} -result 1
test font-9.6 {font command: measure -d} -body {
     expr {[font measure $fixed -d] > 0}
} -returnCodes ok -result 1
test font-9.7 {font command: measure -d with -displayof} -body {
     expr {[font measure $fixed -displayof . -d] > 0}
} -returnCodes ok -result 1
test font-9.8 {font command: measure: arguments} -body {
    font measure $fixed -displayof .
} -returnCodes error -result {wrong # args: should be "font measure font ?-displayof window? text"}


test font-10.1 {font command: metrics: arguments} -body {
    font metrics xyz -displayof
} -returnCodes error -result {value for "-displayof" missing}
test font-10.2 {font command: metrics: arguments} -body {
    # (skip < 0)
    font metrics xyz -displayof
} -returnCodes error -result {value for "-displayof" missing}
test font-10.3 {font command: metrics: arguments} -body {
    # (objc < 3)
    font metrics
} -returnCodes error -result {wrong # args: should be "font metrics font ?-displayof window? ?-option?"}
test font-10.4 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 0
    font metrics xyz abc def
} -returnCodes error -result {wrong # args: should be "font metrics font ?-displayof window? ?-option?"}
test font-10.5 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 2
    font metrics xyz -displayof . abc
} -returnCodes error -result {bad metric "abc": must be -ascent, -descent, -linespace, or -fixed}
test font-10.6 {font command: metrics: bad font} -constraints noExceed -body {
    # (tkfont == NULL)
    font metrics "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-10.7 {font command: metrics: get all metrics} -setup {
    catch {unset a}
} -body {
    # (objc == 3)

    array set a [font metrics {-family xyz}]
    lsort [array names a]
} -cleanup {
    unset a

} -result {-ascent -descent -fixed -linespace}
test font-10.8 {font command: metrics: bad metric} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)
    font metrics $fixed -xyz
} -returnCodes error -result {bad metric "-xyz": must be -ascent, -descent, -linespace, or -fixed}
test font-10.9 {font command: metrics: get individual metrics} -body {
    font metrics $fixed -ascent
    font metrics $fixed -descent
    font metrics $fixed -linespace
    font metrics $fixed -fixed
} -result 1


test font-11.1 {font command: names: arguments} -body {
    # (objc != 2)
    font names xyz
} -returnCodes error -result {wrong # args: should be "font names"}
test font-11.2 {font command: names: loop test: no passes} -setup {
    clearnondefaultfonts
} -body {

    getnondefaultfonts
} -result {}
test font-11.3 {font command: names: loop test: one pass} -setup {
    clearnondefaultfonts
} -body {

    font create
    getnondefaultfonts
} -result {font1}
test font-11.4 {font command: names: loop test: multiple passes} -setup {
    clearnondefaultfonts
} -body {

    font create xyz
    font create abc
    font create def
    lsort [getnondefaultfonts]
} -cleanup {
    clearnondefaultfonts
} -result {abc def xyz}
test font-11.5 {font command: names: skip deletePending fonts} -setup {
    destroy .t.f
    clearnondefaultfonts
    pack [label .t.f]
    update
    set x {}
} -body {
    # (nfPtr->deletePending == 0)
    font create xyz
    font create abc
    lappend x [lsort [getnondefaultfonts]]
    .t.f config -font xyz
    font delete xyz
    lappend x [getnondefaultfonts]
} -cleanup {
    clearnondefaultfonts
} -result {{abc xyz} abc}


test font-12.1 {UpdateDependantFonts procedure: no users} -setup {
    catch {font delete xyz}
} -body {
    # (nfPtr->refCount == 0)

    font create xyz
    font configure xyz -family times
} -cleanup {
    font delete xyz
} -result {}
test font-12.2 {UpdateDependantFonts procedure: pings the widgets} -setup {
    destroy .t.f


    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    font create xyz -family times -size 20
    .t.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
    set a1 [font measure xyz "abcd"]
    update
    set b1 [winfo reqwidth .t.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update
    set b2 [winfo reqwidth .t.f]
    expr {$a1==$b1 && $a2==$b2}
} -cleanup {
    destroy .t.f
    font delete xyz
} -result 1


test font-13.1 {CreateNamedFont: new named font} -setup {

    catch {font delete xyz}
    set x {}
} -body {
    # not (new == 0)
    lappend x [getnondefaultfonts]
    font create xyz
    lappend x [getnondefaultfonts]
} -cleanup {
    font delete xyz
} -result {{} xyz}
test font-13.2 {CreateNamedFont: named font already exists} -setup {
    catch {font delete xyz}
} -body {
    # (new == 0)
    font create xyz
    font create xyz
} -cleanup {
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}
test font-13.3 {CreateNamedFont: named font already exists} -setup {
    catch {font delete xyz}
} -body {
    # (nfPtr->deletePending == 0)

    font create xyz
    font create xyz
} -cleanup {
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}
test font-13.4 {CreateNamedFont: recreate "deleted" font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # not (nfPtr->deletePending == 0)

    font create xyz -family times
    .t.f configure -font xyz
    font delete xyz
    font create xyz -family courier
    font configure xyz -family
} -cleanup {
    font delete xyz
    destroy .t.f
} -result {courier}


test font-14.1 {Tk_GetFont procedure} -body {
} -result {}


test font-15.1 {Tk_AllocFontFromObj - converting internal reps} -constraints {





    testfont
} -setup {
    destroy .b1 .b2
} -body {
    set x {Times 16}
    lindex $x 0
    button .b1 -font $x
    lindex $x 0
    testfont counts {Times 16}
} -cleanup {
    destroy .b1 .b2
} -result {{1 0}}
test font-15.2 {Tk_AllocFontFromObj - discard stale font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x
    destroy .b1

    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    lappend result [testfont counts {Times 16}]
} -cleanup {
    destroy .b2
} -result {{} {{1 1}}}
test font-15.3 {Tk_AllocFontFromObj - reuse existing font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x

    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    pack .b1 .b2 -side top
    lappend result [testfont counts {Times 16}]
} -cleanup {
    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}
test font-15.4 {Tk_AllocFontFromObj procedure: bump ref count} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (new == 0)

    .t.f config -font {-family fixed}
    lindex [font actual {-family fixed}] 0
} -cleanup {
    destroy .t.f
} -result {-family}
test font-15.5 {Tk_AllocFontFromObj procedure: get named font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (namedHashPtr != NULL)

    font create xyz
    .t.f config -font xyz
} -cleanup {
    destroy .t.f
    font delete xyz
} -result {}
test font-15.6 {Tk_AllocFontFromObj procedure: not a named font} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # not (namedHashPtr != NULL)

    .t.f config -font {times 20}
} -cleanup {
    destroy .t.f
} -result {-family} -result {}
test font-15.7 {Tk_AllocFontFromObj procedure: get native font} -constraints {
	unix
} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # not (fontPtr == NULL)

    .t.f config -font fixed
} -result {}
test font-15.8 {Tk_AllocFontFromObj procedure: get native font} -constraints {
	win
} -setup {
    destroy .t.f
    clearnondefaultfonts
    pack [label .t.f]
    update
} -body {
    # not (fontPtr == NULL)

    .t.f config -font oemfixed
} -cleanup {
	destroy .t.f
} -result {}
test font-15.9 {Tk_AllocFontFromObj procedure: get attribute font} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr == NULL)
    .t.f config -font {xxx yyy zzz}
} -cleanup {
	destroy .t.f
} -returnCodes error -result {expected integer but got "yyy"}
test font-15.10 {Tk_AllocFontFromObj procedure: no match} -constraints noExceed -body {
    # (ParseFontNameObj() != TCL_OK)
    font actual "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-15.11 {Tk_AllocFontFromObj procedure: get attribute font} -body {
    # not (ParseFontNameObj() != TCL_OK)
    lindex [font actual {plan 9}] 0
} -result {-family}
test font-15.12 {Tk_AllocFontFromObj procedure: setup tab width} -setup {
    destroy .l
} -body {
    # Tk_MeasureChars(fontPtr, "0", ...)
    label .l -bd 0 -padx 0  -highlightthickness 0 -font $fixed -text "a\tb"
    update
    set res1 [winfo reqwidth .l]
	set res2 [expr [font measure $fixed "0"]*9]
	expr {$res1 eq $res2}
} -cleanup {
    destroy .l
} -result 1

test font-15.13 {Tk_AllocFontFromObj procedure: underline position} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr->underlineHeight == 0) because size was < 10

    .t.f config -text "underline" -font "times -8 underline"
    update
} -cleanup {
    destroy .t.f
} -result {}


test font-16.1 {Tk_NameOfFont procedure} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -font -family\ fixed
    .t.f cget -font
} -cleanup {
    destroy .t.f
} -result {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} -constraints {
	testfont
} -setup {
    destroy .b1 .b2 .b3
    set result {}
} -body {
    set x {Courier 12}
    button .b1 -font $x
    button .b3 -font $x
    button .b2 -font $x

    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    destroy .b2
    lappend result [testfont counts {Courier 12}]
    destroy .b3
    lappend result [testfont counts {Courier 12}]
} -result {{{3 1}} {{2 1}} {{1 1}} {}}
test font-17.2 {Tk_FreeFont procedure: one ref} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr->refCount == 0)

    .t.f config -font {-family fixed}
    destroy .t.f
} -result {}
test font-17.3 {Tk_FreeFont procedure: multiple ref} -setup {
    destroy .t.f .t.b
    pack [label .t.f]
    update
} -body {
    # not (fontPtr->refCount == 0)

    .t.f config -font {-family fixed}
    button .t.b -font {-family fixed}
    destroy .t.f
    .t.b cget -font
} -cleanup {
    destroy .t.b

} -result {-family fixed}
test font-17.4 {Tk_FreeFont procedure: named font} -setup {
    destroy .t.f
    clearnondefaultfonts
    pack [label .t.f]
    update
} -body {
    # (fontPtr->namedHashPtr != NULL)

    font create xyz
    .t.f config -font xyz
    destroy .t.f
    getnondefaultfonts
} -result {xyz}
test font-17.5 {Tk_FreeFont procedure: named font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # not (fontPtr->refCount == 0)

    font create xyz -underline 1
    .t.f config -font xyz
    font delete xyz
    set x [font actual xyz -underline]
    destroy .t.f
    list [font actual xyz -underline] $x
} -result {0 1}
test font-17.6 {Tk_FreeFont procedure: named font not deleted yet} -setup {
    destroy .t.f .t.b
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    font create xyz
    .t.f config -font xyz
    button .t.b -font xyz
    font delete xyz
    set x [font actual xyz]
    destroy .t.b
    list [lindex [font actual xyz] 0] [lindex $x 0]
} -cleanup {
    destroy .t.f
} -result {-family -family}


test font-18.1 {FreeFontObjProc} -constraints testfont -setup {
    destroy .b1
    set result {}
} -body {
    set x [join {Courier 12} { }]
    button .b1 -font $x
    set y [join {Courier 12} { }]
    .b1 configure -font $y
    set z [join {Courier 12} { }]
    .b1 configure -font $z

    lappend result [testfont counts {Courier 12}]
    set x red
    lappend result [testfont counts {Courier 12}]
    set z 32
    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    set y bogus
    return $result
} -result {{{1 3}} {{1 2}} {{1 1}} {}}


test font-19.1 {Tk_FontId} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -font "times 20"
    update
} -cleanup {
	destroy .t.f
} -result {}


test font-20.1 {Tk_GetFontMetrics procedure} -setup {
	destroy .t.w1 .t.w2
} -body {
    button .t.w1 -text abc
    entry .t.w2 -text abcd
    update
    destroy .t.w1 .t.w2
} -result {}


# Procedure used in 21.* tests
proc psfontname {name} {
	destroy .t.c
	canvas .t.c -closeenough 0
	.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
	pack .t.c
	update
    set a [.t.c itemcget text -font]
    .t.c itemconfig text -text "We need text" -font $name
    set post [.t.c postscript]
    .t.c itemconfig text -font $a
    set end [string first "findfont" $post]
    incr end -2
    set post [string range $post [expr $end-70] $end]
    set start [string first "gsave" $post]
	destroy .t.c
    return [string range $post [expr $start+7] end]
}
test font-21.1 {Tk_PostscriptFontName procedure: native} -constraints {
	unix
} -body {
    set x [font actual {{itc avant garde} 10} -family]
    if {[string match *avant*garde $x]} {
		psfontname "{itc avant garde} 10"
    } else {
		set x {AvantGarde-Book}
    }
} -result {AvantGarde-Book}
test font-21.2 {Tk_PostscriptFontName procedure: native} -constraints {
	win
} -body {
    psfontname "arial 10"
} -result {Helvetica}
test font-21.3 {Tk_PostscriptFontName procedure: native} -constraints {
	win
} -body {
    psfontname "{times new roman} 10"
} -result {Times-Roman}
test font-21.4 {Tk_PostscriptFontName procedure: native} -constraints {
	win
} -body {
    psfontname "{courier new} 10"
} -result {Courier}
test font-21.5 {Tk_PostscriptFontName procedure: spaces} -constraints {
	unix
} -body {
    set x [font actual {{lucida bright} 10} -family]
    if {[string match lucida*bright $x]} {
		psfontname "{lucida bright} 10"
    } else {
		set x {LucidaBright}
    }
} -result {LucidaBright}
test font-21.6 {Tk_PostscriptFontName procedure: spaces} -constraints {
	x11 failsOnUbuntu
} -body {
    psfontname "{new century schoolbook} 10"
} -result {NewCenturySchlbk-Roman}

test font-21.7 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {avantgarde 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "avantgarde"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-Book
    }
} -result {AvantGarde-Book}
test font-21.8 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {avantgarde 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "avantgarde"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-Demi
    }
} -result {AvantGarde-Demi}
test font-21.9 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {avantgarde 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "avantgarde"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-BookOblique
    }
} -result {AvantGarde-BookOblique}
test font-21.10 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {avantgarde 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "avantgarde"} {

        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-DemiOblique
    }
} -result {AvantGarde-DemiOblique}


test font-21.11 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {bookman 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "bookman"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-Light
    }
} -result {Bookman-Light}
test font-21.12 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix

} -body {
    set name {bookman 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "bookman"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-Demi
    }
} -result {Bookman-Demi}
test font-21.13 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {bookman 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "bookman"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-LightItalic
    }
} -result {Bookman-LightItalic}
test font-21.14 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {bookman 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "bookman"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-DemiItalic
    }
} -result {Bookman-DemiItalic}

test font-21.15 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {courier 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "courier"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier
    }
} -result {Courier}
test font-21.16 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {courier 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "courier"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-Bold
    }
} -result {Courier-Bold}
test font-21.17 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {


    set name {courier 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "courier"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-Oblique
    }
} -result {Courier-Oblique}
test font-21.18 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {courier 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "courier"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-BoldOblique
    }
} -result {Courier-BoldOblique}

test font-21.19 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {helvetica 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "helvetica"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica

    }
} -result {Helvetica}
test font-21.20 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {helvetica 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "helvetica"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-Bold
    }
} -result {Helvetica-Bold}
test font-21.21 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {helvetica 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "helvetica"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-Oblique
    }
} -result {Helvetica-Oblique}
test font-21.22 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {helvetica 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "helvetica"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-BoldOblique
    }
} -result {Helvetica-BoldOblique}

test font-21.23 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {{new century schoolbook} 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "new century schoolbook"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Roman
    }
} -result {NewCenturySchlbk-Roman}
test font-21.24 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {{new century schoolbook} 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "new century schoolbook"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Bold
    }
} -result {NewCenturySchlbk-Bold}
test font-21.25 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {{new century schoolbook} 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "new century schoolbook"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Italic
    }
} -result {NewCenturySchlbk-Italic}
test font-21.26 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {{new century schoolbook} 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "new century schoolbook"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-BoldItalic
    }
} -result {NewCenturySchlbk-BoldItalic}

test font-21.27 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {palatino 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "palatino"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Roman
    }
} -result {Palatino-Roman}
test font-21.28 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {palatino 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "palatino"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Bold
    }
} -result {Palatino-Bold}
test font-21.29 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {palatino 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "palatino"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Italic
    }
} -result {Palatino-Italic}
test font-21.30 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {palatino 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "palatino"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-BoldItalic
    }
} -result {Palatino-BoldItalic}

test font-21.31 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {symbol 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "symbol"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
    }
} -result {Symbol}
test font-21.32 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {symbol 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "symbol"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
    }
} -result {Symbol}
test font-21.33 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {symbol 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "symbol"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
    }
} -result {Symbol}
test font-21.34 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {symbol 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "symbol"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
    }
} -result {Symbol}

test font-21.35 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {times 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "times"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Roman
    }
} -result {Times-Roman}
test font-21.36 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {times 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "times"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Bold
    }
} -result {Times-Bold}
test font-21.37 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {times 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "times"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Italic
    }
} -result {Times-Italic}
test font-21.38 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {times 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "times"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-BoldItalic
    }
} -result {Times-BoldItalic}

test font-21.39 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfchancery 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfchancery"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
    }
} -result {ZapfChancery-MediumItalic}
test font-21.40 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix

} -body {
    set name {zapfchancery 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfchancery"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
    }
} -result {ZapfChancery-MediumItalic}
test font-21.41 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfchancery 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfchancery"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
    }
} -result {ZapfChancery-MediumItalic}
test font-21.42 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfchancery 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfchancery"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
    }
} -result {ZapfChancery-MediumItalic}

test font-21.43 {Tk_PostscriptFontName procedure: exhaustive} -constraints {

    unix
} -body {
    set name {zapfdingbats 12 roman normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfdingbats"} {


        set x [psfontname avantgarde 12 roman normal]
    } else {

        set x ZapfDingbats
    }
} -result {ZapfDingbats}

test font-21.44 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfdingbats 12 roman bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfdingbats"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
    }
} -result {ZapfDingbats}
test font-21.45 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfdingbats 12 italic normal}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfdingbats"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
    }
} -result {ZapfDingbats}
test font-21.46 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
    set name {zapfdingbats 12 italic bold}
    if {[font actual {avantgarde 12 roman normal} -family] == "zapfdingbats"} {
        set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
    }
} -result {ZapfDingbats}

test font-21.47 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {arial 12 roman normal}]
} -result {Helvetica}
test font-21.48 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {arial 12 roman bold}]
} -result {Helvetica-Bold}
test font-21.49 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {arial 12 italic normal}]
} -result {Helvetica-Oblique}
test font-21.50 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {arial 12 italic bold}]
} -result {Helvetica-BoldOblique}

test font-21.51 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{courier new} 12 roman normal}]
} -result {Courier}
test font-21.52 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{courier new} 12 roman bold}]
} -result {Courier-Bold}
test font-21.53 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{courier new} 12 italic normal}]
} -result {Courier-Oblique}
test font-21.54 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{courier new} 12 italic bold}]
} -result {Courier-BoldOblique}

test font-21.55 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {helvetica 12 roman normal}]
} -result {Helvetica}
test font-21.56 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {helvetica 12 roman bold}]
} -result {Helvetica-Bold}

test font-21.57 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {helvetica 12 italic normal}]
} -result {Helvetica-Oblique}
test font-21.58 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {helvetica 12 italic bold}]
} -result {Helvetica-BoldOblique}

test font-21.59 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {symbol 12 roman normal}]
} -result {Symbol}
test font-21.60 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {symbol 12 roman bold}]
} -result {Symbol-Bold}
test font-21.61 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {symbol 12 italic normal}]
} -result {Symbol-Italic}
test font-21.62 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {symbol 12 italic bold}]
} -result {Symbol-BoldItalic}

test font-21.63 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{times new roman} 12 roman normal}]
} -result {Times-Roman}
test font-21.64 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{times new roman} 12 roman bold}]
} -result {Times-Bold}
test font-21.65 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{times new roman} 12 italic normal}]
} -result {Times-Italic}
test font-21.66 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {{times new roman} 12 italic bold}]
} -result {Times-BoldItalic}


test font-22.1 {Tk_TextWidth procedure} -setup {
    destroy .t.l
} -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
	    -text "0" -font "Courier -12"
    pack .t.l
    set ax [winfo reqwidth .t.l]
    expr {[font measure [.t.l cget -font] "000"] eq $ax*3}
} -cleanup {
    destroy .t.l
} -result 1


test font-23.1 {Tk_UnderlineChars procedure} -setup {
    destroy .t.t
} -body {
    text .t.t
    .t.t insert 1.0 abc\tdefg
    .t.t tag config sel -underline 1
    .t.t tag add sel 1.0 end
    update
} -cleanup {
    destroy .t.t
} -result {}


# Data used in 24.* tests
destroy .t.l
label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
	-text "0" -font "Courier -12"
pack .t.l
update
set ax [winfo reqwidth .t.l]
set ay [winfo reqheight .t.l]
test font-24.1 {Tk_ComputeTextLayout: empty string} -body {
    .t.l config -text ""
} -result {}
test font-24.2 {Tk_ComputeTextLayout: simple string} -body {
    .t.l config -text "000"
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq $ay}]
} -result {1 1}
test font-24.3 {Tk_ComputeTextLayout: find special chars} -body {
    .t.l config -text "000\n000"
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.4 {Tk_ComputeTextLayout: calls Tk_MeasureChars} -body {
    .t.l config -text "000\n000"
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.5 {Tk_ComputeTextLayout: break line} -body {
    .t.l config -text "000\t00000" -wrap [expr 9 * $ax]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -cleanup {
    .t.l config -wrap 0
} -result {1 1}
test font-24.6 {Tk_ComputeTextLayout: normal ended on special char} -body {
    .t.l config -text "000\n000"
} -result {}
test font-24.7 {Tk_ComputeTextLayout: special char was \n} -body {
    .t.l config -text "000\n0000"
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.8 {Tk_ComputeTextLayout: special char was \t} -body {
    .t.l config -text "000\t00"
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}] \
	    [expr {[winfo reqheight .t.l] eq $ay}]
} -result {1 1}
test font-24.9 {Tk_ComputeTextLayout: tab didn't cause break} -body {
    set x {}
    .t.l config -text "000\t000"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 11}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    .t.l config -text "000\t000" -wrap [expr 100 * $ax]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 11}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.10 {Tk_ComputeTextLayout: tab caused break} -body {
    set x {}
    .t.l config -text "000\t"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    .t.l config -text "000\t00" -wrap [expr $ax * 6]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.11 {Tk_ComputeTextLayout: absorb spaces at eol} -body {
    set x {}
    .t.l config -text "000            000" -wrap [expr {$ax * 5}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]

    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    .t.l config -text "000            "
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.12 {Tk_ComputeTextLayout: append non-printing spaces to chunk} -body {
    set x {}
    .t.l config -text "000            0000" -wrap [expr {$ax * 5}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    .t.l config -text "000\t00            0000" -wrap [expr {$ax * 12}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.13 {Tk_ComputeTextLayout: many lines -> realloc line array} -body {
    .t.l config -text "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
    update
    list [expr {[winfo reqwidth .t.l] eq 1}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 129}]}]
} -result {1 1}
test font-24.14 {Tk_ComputeTextLayout: text ended with \n} -body {
    set x {}
    .t.l config -text "0000"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]

    .t.l config -text "0000\n"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    set x
} -result {1 1 1 1}
destroy .t.l

test font-24.15 {Tk_ComputeTextLayout: justification} -setup {
    set x {}
    destroy .t.c

    canvas .t.c -closeenough 0
    .t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
    pack .t.c
    update
} -body {
    csetup "000\n00000"
    .t.c itemconfig text -just left
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just center
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just right
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just left
    return $x
} -cleanup {
    destroy .t.c
} -result {2 1 0}


test font-25.1 {Tk_FreeTextLayout procedure} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -text foo
    .t.f config -text boo
} -cleanup {
    destroy .t.f
} -result {}


# Canvas created for tests: 26.*
destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-26.1 {Tk_DrawTextLayout procedure: auto-detect last char} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -text foo
} -cleanup {
    destroy .t.f
} -result {}
test font-26.2 {Tk_DrawTextLayout procedure: multiple chunks} -body {
    csetup "000\t00\n000"
} -result {}
test font-26.3 {Tk_DrawTextLayout: draw subset of chunk: numDisplay <= 0} -body {
    csetup "000\t00"
    .t.c select from text 3
    .t.c select to text 5
} -result {}
test font-26.4 {Tk_DrawTextLayout: draw subset of chunk: firstChar <= 0} -body {
    csetup "000\t00"
    .t.c select from text 3
    .t.c select to text 5
} -result {}
test font-26.5 {Tk_DrawTextLayout: draw subset of chunk: firstChar > 0} -body {
    csetup "000\t00"
    .t.c select from text 2
    .t.c select to text 2
} -result {}
test font-26.6 {Tk_DrawTextLayout: draw subset of chunk: lastChar < numChars} -body {
    csetup "000\t00"
    .t.c select from text 4
    .t.c select to text 4
} -result {}
destroy .t.c

#  Label used in 27.* tests
destroy .t.f
pack [label .t.f]
update
test font-27.1 {Tk_UnderlineTextLayout procedure: no underline chosen} -body {
    .t.f config -text "foo" -underline -1
} -result {}
test font-27.2 {Tk_UnderlineTextLayout procedure: underline not visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 10
} -result {}
test font-27.3 {Tk_UnderlineTextLayout procedure: underline is visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 5
    .t.f config -wrap -1 -underline -1
} -result {}
destroy .t.f



# Canvas created for tests: 28.*
destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-28.1 {Tk_PointToChar procedure: above all lines} -body {
    csetup "000"
    .t.c index text @-1,0
} -result 0
test font-28.2 {Tk_PointToChar procedure: no chars} -body {
    # After fixing the following bug:
    #
    # In canvas text item, it was impossible to click to position the
    # insertion point just after the last character.
    #
    # introduced another bug that Tk_PointToChar() would return a character
    # index of 1 if TextLayout contained 0 characters.

    csetup ""
    .t.c index text @100,100
} -result 0
test font-28.3 {Tk_PointToChar procedure: loop test} -body {
    csetup "000\n000\n000\n000"
    .t.c index text @10000,0
} -result 3
test font-28.4 {Tk_PointToChar procedure: intersect line} -body {
    csetup "000\n000\n000"
    .t.c index text @0,$ay
} -result 4
test font-28.5 {Tk_PointToChar procedure: to the left of all chunks} -body {
    csetup "000\n000\n000"
    .t.c index text @-100,$ay
} -result 4
test font-28.6 {Tk_PointToChar procedure: past any possible chunk} -body {
    csetup "000\n000\n000"
    .t.c index text @100000,$ay
} -result 7
test font-28.7 {Tk_PointToChar procedure: which chunk on this line} -body {
    csetup "000\n000\t000\t000\n000"
    .t.c index text @[expr $ax*2],$ay
} -result 6
test font-28.8 {Tk_PointToChar procedure: which chunk on this line} -body {
    csetup "000\n000\t000\t000\n000"
    .t.c index text @[expr $ax*10],$ay
} -result 10
test font-28.9 {Tk_PointToChar procedure: in special chunk} -body {
    csetup "000\n000\t000\t000\n000"
    .t.c index text @[expr $ax*6],$ay
} -result 7
test font-28.10 {Tk_PointToChar procedure: past all chars in chunk} -body {
    csetup "000 0000000"
    .t.c itemconfig text -width [expr $ax*5]









    set x [.t.c index text @[expr $ax*5],0]
    .t.c itemconfig text -width 0
    return $x
} -result 3
test font-28.11 {Tk_PointToChar procedure: below all chunks} -body {
    csetup "000 0000000"
    .t.c index text @0,1000000
} -result 11
destroy .t.c


#  Label used in 29.* tests
destroy .t.f
pack [label .t.f]
update
test font-29.1 {Tk_CharBBox procedure: index < 0} -body {
    .t.f config -text "000" -underline -1
} -result {}
test font-29.2 {Tk_CharBBox procedure: loop} -body {
    .t.f config -text "000\t000\t000\t000" -underline 9
} -result {}
test font-29.3 {Tk_CharBBox procedure: special char} -body {
    .t.f config -text "000\t000\t000" -underline 7
} -result {}
test font-29.4 {Tk_CharBBox procedure: normal char} -body {
    .t.f config -text "000" -underline 1
} -result {}
test font-29.5 {Tk_CharBBox procedure: right edge of bbox truncated} -body {
    .t.f config -text "0    0000" -wrap [expr $ax*4] -under 2
    .t.f config -wrap 0
} -result {}
test font-29.6 {Tk_CharBBox procedure: bbox pegged to right edge} -body {
    .t.f config -text "0    0000" -wrap [expr $ax*4] -under 3
    .t.f config -wrap 0
} -result {}
destroy .t.f



# Canvas created for tests: 30.*
destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-30.1 {Tk_DistanceToTextLayout procedure: loop once} -body {

    csetup "000\n000\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result 0
test font-30.2 {Tk_DistanceToTextLayout procedure: loop multiple} -body {

    csetup "000\n000\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y $ay
    return $x
} -cleanup {
    bind all <Enter> {}
} -result 5
test font-30.3 {Tk_DistanceToTextLayout procedure: loop to end} -body {
    csetup "000\n0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}



    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y $ay
    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
test font-30.4 {Tk_DistanceToTextLayout procedure: hit a special char (tab)} -body {
    csetup "000\t000\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*6] -y 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result 3
test font-30.5 {Tk_DistanceToTextLayout procedure: ignore newline} -body {
    csetup "000\n0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y $ay
    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
test font-30.6 {Tk_DistanceToTextLayout procedure: ignore spaces at eol} -body {
    csetup "000\n000      000000000"
    .t.c itemconfig text -width [expr $ax*10]
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>






    event generate .t.c <Enter> -x [expr $ax*5] -y $ay
    .t.c itemconfig text -width 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
.t.c itemconfig text -justify center
test font-30.7 {Tk_DistanceToTextLayout procedure: on left side} -body {
    csetup "0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}

    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0

    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
test font-30.8 {Tk_DistanceToTextLayout procedure: on right side} -body {
    csetup "0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
test font-30.9 {Tk_DistanceToTextLayout procedure: inside line} -body {
    csetup "0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y 0
    return $x
} -cleanup {




    bind all <Enter> {}

} -result 0
test font-30.10 {Tk_DistanceToTextLayout procedure: above line} -body {
    csetup "0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result {}
test font-30.11 {Tk_DistanceToTextLayout procedure: below line} -body {
    csetup "000\n0"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
} -result {}
test font-30.12 {Tk_DistanceToTextLayout procedure: in line} -body {
    csetup "0\n000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
} -result 3
.t.c itemconfig text -justify left
test font-30.13 {Tk_DistanceToTextLayout procedure: exact hit} -body {
    csetup "000"
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y 0
    return $x
} -cleanup {
    bind all <Enter> {}
} -result 1
destroy .t.c


# Canvas created for tests 31.*
destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-31.1 {Tk_IntersectTextLayout procedure: loop once} -body {
    csetup "000\n000\n000"
    .t.c find overlapping 0 0 0 0
} -result [.t.c find withtag text]
test font-31.2 {Tk_IntersectTextLayout procedure: loop multiple} -body {
    csetup "000\t000\t000"
    .t.c find overlapping [expr $ax*10] 0 [expr $ax*10] 0
} -result [.t.c find withtag text]
test font-31.3 {Tk_IntersectTextLayout procedure: loop to end} -body {
    csetup "0\n000"
    .t.c find overlapping [expr $ax*2] 0 [expr $ax*2] 0
} -result {}
test font-31.4 {Tk_IntersectTextLayout procedure: hit a special char (tab)} -body {
    csetup "000\t000"
    .t.c find overlapping [expr $ax*6] 0 [expr $ax*6] 0
} -result [.t.c find withtag text]
test font-31.5 {Tk_IntersectTextLayout procedure: ignore newlines} -body {
    csetup "000\n0\n000"
    .t.c find overlapping $ax $ay $ax $ay
} -result {}
test font-31.6 {Tk_IntersectTextLayout procedure: ignore spaces at eol} -body {
    csetup "000\n000      000000000"
    .t.c itemconfig text -width [expr $ax*10]
    set x [.t.c find overlapping [expr $ax*5] $ay [expr $ax*5] $ay]
    .t.c itemconfig text -width 0
    return $x
} -result {}
test font-31.7 {TkIntersectAngledTextLayout procedure: bug [514ff64dd0]} -body {
    csetup "This is line one\nand line two\nand line three here"
    .t.c itemconfigure text -angle 90
    # Coordinates of the rectangle to check can be hardcoded:
    # The goal of this test is to check whether the overlap detection algorithm
    # works when the rectangle is entirely included in a chunk of the text layout.
    # The text has been rotated 90 degrees around it's upper left corner,
    # so it's enough to check with a small rectangle with small negative y coords.
    .t.c find overlapping 5 -7 7 -5
} -result 1
destroy .t.c


test font-32.1 {Tk_TextLayoutToPostscript: ensure buffer doesn't overflow} -setup {
    destroy .t.c
    canvas .t.c -closeenough 0
    .t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
    pack .t.c
    update
} -body {
    # If there were a whole bunch of returns or tabs in a row, then the
    # temporary buffer could overflow and write on the stack.

    csetup "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .t.c itemconfig text -width 800
    .t.c insert text end "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .t.c insert text end "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
    .t.c insert text end "end"
    set x [.t.c postscript]
    set i [string first "(qwerty" $x]
    string range $x $i [expr {$i + 278}]
} -cleanup {
    destroy .t.c
} -result {(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[()]
[()]
[()]
[()]
[()]
[()]




|
|



<



|
|
|
|
<


>
>
>


















>
>
>
|
>
>
>
|
>
|
>
>
>
>
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>

|





<
<
<
<
<
<
<
|

|

<







<
|

|

<
<

>


>












>






|

>
|


|
|
|
|
|
|

<
|

|
|
|

|
|
|

|
|
|

|
|

|
|

|
|
|

|
|
|


|
|


|
|


|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|

|
|
|

|
|
|
<
<
<
<
<

>

|

|
<
<
|
|
<
<

>


<
<
|
|
<
<

>


<
<
<
|
|
<
<

>




<
<
|
|
|
<

|
<
<
|

<
|
<
<

>

|
|
<
<
|
<
<

>

|
|
<
<
|
<
<

>

|
|
<
<
|
<

>






<
<
|
|
<
<

>
|
|
|
<
<

>
|
|
|
<
<

>

|
<
<
|

|

|
|
|
<
<
<

>
>








<
<
|
|
<
<
<

>
>








<
<
|
|
<
<

>
|
|
|
<
<
<
<
<

>

|


|
<
<
|
|
<
<
<
<
<
|
>
|
<

<
|
<
<
<
<
<
<
|
<
<
<
<
<
|

|

|
|
|

|
|
|

|
|
|


<
|

|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|

<
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|
<
<

>

|
<

>
|
|

|
|
|




<
|

|

|
|
|
<
<
>

|
|
<
<
>


|
|
<
<
>




<
<
|
|
|
<
<
|

<
<



|


<
<
|

<
|
<
<

>


|
<
<
|
|
>
>
|
<

<
<
<
<
<
|



|

<
<
<
<
|

|
>
|

<
<



<
<
|
|
<
<

|
<
|
|
|
|
<
<

>

|
<
<
|
|
<
<
<
<
<

>

|



<
<
<
|

<
|
<
|

|
>
>
>
>
>
<
<
<
<
<
<
<
<

<
<
|
|
<
|

<
<
<


>



<
<
|
|
<
|

<
<
<

>




<
<
|
|
<
<
<
<

>
|

<
<
|
|
<
<
<
<
<

>

|
|
<
<
<
|
<
<
<
<

>
|
|
<
<
|
<
<
<
<
<
<

>
|
|
|
<
<
<
<
<
<
<

>
|
|
<
<
|
<
<
<
<

|
<
<
|
|

|
|
|


|
|
<
<



|
<
<
<

|
>
|
<
<
<
<

>
|

<
<
<
|

|
<
<
|
<
|
|
<
<
|

<
|
<
|

<
<
<



>







|
|
<
<
<
<

>
|
|
|
|
<
<
<
<

>
|
|
|
|
<
|
>
|
|
<
<
<
<
<

>

|
|
|
|
|
<
<
<
<
<

>

|


|

|
|
<
<
<
|
<

|
|


|

<
<
|

<
|

<
<
|

|

|

>








|
|

<
|
<
<
<
<
|

<
<
<
|

|
<
<
|
|

|
<
|

<

<
<
<
<
<
|
|
|
|




<


|
<
<


|

|

|
|
<
<

|
|
<
<

|
|
<
<

|
|
<
<


|

|

|
|
<
<

|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
>
|
<
|
<
<
|
>
|
<
<
<
<
|
|
<
<
<
|
<
>
|
|
<
<
<
<
<
<
|
<
<
|
<
|
<
|
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
|
|
>
>
|
|
|
|
|
|
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
|
>
|
|
|
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
|
<
|
<
|
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
>
|
<
<
<
<
<
|
<
|
<
|
<
<
<
|
<
|
<
|
<
|
<
<
<
|
<
<
<
|
|
>
|
|
<
<
>
>
|
<
>
|
<
<
>
|
<
|
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
|
<
<
<
|
|
<
>
|
<
<
|
<
<
<
|
|
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
<
|
<
|
<
|
|
|
<
<
|
<
<
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
|
|
|
|
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
|
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
|
<
<
<
>
|
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
>
|
<
<
<
|
<
<
|
|
|
<
>
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|
|
<
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<

<
<
<
<
|
|
|
|
|
|
|
|
|
<
<
|

<
<
<
<
<
<
<
|

|
|
|









|
|
|

|
|
|

|
|
|
<
|
|
|
<
|
|
|

|
|
|

<
<
<
<
<
<
<
<
<
>
>
>
>
>
>
>
>
>
|
|
|
|
|

|
<
<
|

<
<
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
<
<
<
<
<
<
|
>
|
<
|
<
<
<
<
<
<
|
>
|
<
|
|
<
<
<
<
<
<
<
|
>
>
>

|
|
|
|
<
<
|
|
<

|
|
|
|
<
<
|

<

|
|
|
<
|
<
|
|
<
<

|
>
>
>
>
>
>
|
|
|
<
|
<
<
|
|
<
>

|
|
>
|
|
|
<
|

<

|
|
|
<
|
<
|

<

|
|
|
|
>
>
>
>
|
>
|
|

<

|
|
|
<
|
<
|

<

|
|
|
<
|
<
|

<

|
|
|
|
<
<
|
|

<

|
|
|
<
<
<
<
|

<
<
<
<
<
<
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
<
<
<
<
<


>

|
|
|
|
|


<
<
|







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77







78
79
80
81

82
83
84
85
86
87
88

89
90
91
92


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170















171

172
173
174
175
176
177
178
179
180





181
182
183
184
185
186


187
188


189
190
191
192


193
194


195
196
197
198



199
200


201
202
203
204
205
206


207
208
209

210
211


212
213

214


215
216
217
218
219


220


221
222
223
224
225


226


227
228
229
230
231


232

233
234
235
236
237
238
239
240


241
242


243
244
245
246
247


248
249
250
251
252


253
254
255
256


257
258
259
260
261
262
263



264
265
266
267
268
269
270
271
272
273
274


275
276



277
278
279
280
281
282
283
284
285
286
287


288
289


290
291
292
293
294





295
296
297
298
299
300
301


302
303





304
305
306

307

308






309





310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382


383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405


406
407
408
409


410
411
412
413
414


415
416
417
418
419


420
421
422


423
424


425
426
427
428
429
430


431
432

433


434
435
436
437
438


439
440
441
442
443

444





445
446
447
448
449
450




451
452
453
454
455
456


457
458
459


460
461


462
463

464
465
466
467


468
469
470
471


472
473





474
475
476
477
478
479
480



481
482

483

484
485
486
487
488
489
490
491








492


493
494

495
496



497
498
499
500
501
502


503
504

505
506



507
508
509
510
511
512


513
514




515
516
517
518


519
520





521
522
523
524
525



526




527
528
529
530


531






532
533
534
535
536







537
538
539
540


541




542
543


544
545
546
547
548
549
550
551
552
553


554
555
556
557



558
559
560
561




562
563
564
565



566
567
568


569

570
571


572
573

574

575
576



577
578
579
580
581
582
583
584
585
586
587
588
589




590
591
592
593
594
595




596
597
598
599
600
601

602
603
604
605





606
607
608
609
610
611
612
613





614
615
616
617
618
619
620
621
622
623



624

625
626
627
628
629
630
631


632
633

634
635


636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

654




655
656



657
658
659


660
661
662
663

664
665

666





667
668
669
670
671
672
673
674

675
676
677


678
679
680
681
682
683
684
685


686
687
688


689
690
691


692
693
694


695
696
697
698
699
700
701
702


703
704
705






706






707



708









709


710




711
712

713


714
715
716




717
718



719

720
721
722






723


724

725

726

727
728









729
















730
731


732
733
734
735
736
737
738
739
740
741
742


743






744

745







746
747
748
749
750








751
752
753





754

755
756









757
758






759
760








761


762






763












764



765

766


767









768







769
770
771









772

773




774

775

776

777






778

779

780




781




782






783



















































784


785
786
787





788

789

790



791

792

793

794



795



796
797
798
799
800


801
802
803

804
805


806
807

808





809

810

811








812








813
814

815



816













817
818







819



820





821

822



823



824
825

826
827


828



829
830

831



832



833










834

835
836







837











838
839




840

841

842

843
844
845


846


847
848




849
850









851
852



853


854
855
856
857


858
859

860













861
862











863
864


865
866


867


868






869






870


871



872
873








874
875
876









877








878
879



880
881



882


883
884
885

886
887

888
889
890












891
892



893
894





895
896





897




898







899
















900
901
902

903




904
905
906
907
908
909
910
911
912


913
914







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939

940
941
942

943
944
945
946
947
948
949
950









951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966


967
968




969
970
971
972
973
974
975
976











977

978
979
980






981
982
983

984






985
986
987

988
989







990
991
992
993
994
995
996
997
998


999
1000

1001
1002
1003
1004
1005


1006
1007

1008
1009
1010
1011

1012

1013
1014


1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

1026


1027
1028

1029
1030
1031
1032
1033
1034
1035
1036

1037
1038

1039
1040
1041
1042

1043

1044
1045

1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059

1060
1061
1062
1063

1064

1065
1066

1067
1068
1069
1070

1071

1072
1073

1074
1075
1076
1077
1078


1079
1080
1081

1082
1083
1084
1085




1086
1087






1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113












1114
1115
1116






1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127


1128
1129
1130
1131
1132
1133
1134
1135
# This file is a Tcl script to test out Tk's "font" command
# plus the procedures in tkFont.c.  It is organized in the
# standard white-box fashion for Tcl tests.
#
# Copyright (c) 1996-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

catch {destroy .b}
toplevel .b
wm geom .b +0+0
update idletasks


set defaultfontlist [font names]

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

proc getnondefaultfonts {} {
    global defaultfontlist
    set nondeffonts [list ]
    foreach afont [font names] {
        if {$afont ni $defaultfontlist} {
            lappend nondeffonts $afont
        }
    }
    set nondeffonts
}

proc clearnondefaultfonts {} {
    foreach afont [getnondefaultfonts] {
        font delete $afont
    }
}

proc setup {} {
    catch {destroy .b.f}
    clearnondefaultfonts
    label .b.f
    pack .b.f
    update
}

label .b.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left -text "0" -font "Courier -12"
pack .b.l
canvas .b.c -closeenough 0
.b.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .b.c
update

set ax [winfo reqwidth .b.l]
set ay [winfo reqheight .b.l]
proc getsize {} {
    update
    return "[winfo reqwidth .b.l] [winfo reqheight .b.l]"
}

proc csetup {{str ""}} {
    focus -force .b.c
    .b.c dchars text 0 end
    .b.c insert text 0 $str
    .b.c focus text
}

setup

switch [tk windowingsystem] {
    x11	 	{set fixed "fixed"}
    win32	{set fixed "courier 12"}
    aqua	{set fixed "monaco 9"}
}









set times [font actual {times 0} -family]

test font-1.1 {TkFontPkgInit} {
    catch {interp delete foo}

    interp create foo
    foo eval {
	load {} Tk
	wm geometry . +0+0
	update
    }
    interp delete foo

} {}

test font-2.1 {TkFontPkgFree} {
    catch {interp delete foo}


    interp create foo
    set x {}

    # Makes sure that named font was visible only to child interp.

    foo eval {
	load {} Tk
	wm geometry . +0+0
	button .b -font {times 16} -text "hi"
	pack .b
	font create wiggles -family courier -underline 1
	update
    }
    lappend x [catch {font configure wiggles} msg; set msg]

    # Tests cancelling the idle handler for TheWorldHasChanged,
    # because app goes away before idle serviced.

    foo eval {
	.b config -font wiggles
	font config wiggles -size 24
	destroy .
    }
    lappend x [foo eval {catch {font families} msg; set msg}]

    interp delete foo
    set x
} {{named font "wiggles" doesn't exist} {can't invoke "font" command:  application has been destroyed}}


test font-3.1 {font command: general} {
    list [catch {font} msg] $msg
} {1 {wrong # args: should be "font option ?arg?"}}
test font-3.2 {font command: general} {
    list [catch {font xyz} msg] $msg
} {1 {bad option "xyz": must be actual, configure, create, delete, families, measure, metrics, or names}}


test font-4.1 {font command: actual: arguments} {
    # (skip < 0)
    list [catch {font actual xyz -displayof} msg] $msg
} {1 {value for "-displayof" missing}}
test font-4.2 {font command: actual: arguments} {
    # (objc < 3)
    list [catch {font actual} msg] $msg
} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
test font-4.3 {font command: actual: arguments} {
    # (objc - skip > 4) when skip == 0
    list [catch {font actual xyz abc def} msg] $msg
} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
test font-4.4 {font command: actual: displayof specified, so skip to next} {
    catch {font actual xyz -displayof . -size}
} 0
test font-4.5 {font command: actual: displayof specified, so skip to next} {
    lindex [font actual xyz -displayof .] 0
} {-family}
test font-4.6 {font command: actual: arguments} {
    # (objc - skip > 4) when skip == 2
    list [catch {font actual xyz -displayof . abc def} msg] $msg
} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
test font-4.7 {font command: actual: arguments} noExceed {
    # (tkfont == NULL)
    list [catch {font actual "\{xyz"} msg] $msg
} [list 1 "font \"{xyz\" doesn't exist"]
test font-4.8 {font command: actual: all attributes} {
    # not (objc > 3) so objPtr = NULL
    lindex [font actual {-family times}] 0
} {-family}
test font-4.9 {font command: actual} {unix noExceed failsOnUbuntu} {
    # (objc > 3) so objPtr = objv[3 + skip]
    string tolower [font actual {-family times} -family]
} times
test font-4.10 {font command: actual} win {
    # (objc > 3) so objPtr = objv[3 + skip]
    font actual {-family times} -family
} {Times New Roman}
test font-4.11 {font command: bad option} {
    list [catch {font actual xyz -style} msg] $msg
} {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}}

















test font-5.1 {font command: configure} {
    # (objc < 3)
    list [catch {font configure} msg] $msg
} {1 {wrong # args: should be "font configure fontname ?options?"}}
test font-5.2 {font command: configure: non-existent font} {
    # (namedHashPtr == NULL)
    list [catch {font configure xyz} msg] $msg
} {1 {named font "xyz" doesn't exist}}
test font-5.3 {font command: configure: "deleted" font} {





    # (nfPtr->deletePending != 0)
    setup
    font create xyz
    .b.f configure -font xyz
    font delete xyz
    list [catch {font configure xyz} msg] $msg


} {1 {named font "xyz" doesn't exist}}
test font-5.4 {font command: configure: get all options} {


    # (objc == 3) so objPtr = NULL
    setup
    font create xyz -family xyz
    lindex [font configure xyz] 1


} xyz
test font-5.5 {font command: configure: get one option} {


    # (objc == 4) so objPtr = objv[3]
    setup
    font create xyz -family xyz
    font configure xyz -family



} xyz
test font-5.6 {font command: configure: update existing font} {


    # else result = ConfigAttributesObj()
    setup
    font create xyz
    font configure xyz -family xyz
    update
    font configure xyz -family


} xyz
test font-5.7 {font command: configure: bad option} {
    setup

    font create xyz
    list [catch {font configure xyz -style} msg] $msg


} {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}}


test font-6.1 {font command: create: make up name} {


    # (objc < 3) so name = NULL
    setup
    font create
    expr {"font1" in [font names]}
} 1


test font-6.2 {font command: create: name specified} {


    # not (objc < 3)
    setup
    font create xyz
    expr {"xyz" in [font names]}
} 1


test font-6.3 {font command: create: name not really specified} {


    # (name[0] == '-') so name = NULL
    setup
    font create -family xyz
    expr {"font1" in [font names]}
} 1


test font-6.4 {font command: create: generate name} {

    # (name == NULL)
    setup
    font create -family one
    font create -family two
    font create -family three
    font delete font2
    font create -family four
    font configure font2 -family


} four
test font-6.5 {font command: create: bad option creating new font} {


    # name was specified so skip = 3
    setup
    list [catch {font create xyz -xyz times} msg] $msg
} {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}}
test font-6.6 {font command: create: bad option creating new font} {


    # name was not specified so skip = 2
    setup
    list [catch {font create -xyz times} msg] $msg
} {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}}
test font-6.7 {font command: create: already exists} {


    # (CreateNamedFont() != TCL_OK)
    setup
    font create xyz
    list [catch {font create xyz} msg] $msg


} {1 {named font "xyz" already exists}}

test font-7.1 {font command: delete: arguments} {
    # (objc < 3)
    list [catch {font delete} msg] $msg
} {1 {wrong # args: should be "font delete fontname ?fontname ...?"}}
test font-7.2 {font command: delete: loop test} {



    # for (i = 2; i < objc; i++)
    setup
    set x {}
    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
    lappend x [lsort [getnondefaultfonts]]
    font delete a e c b
    lappend x [lsort [getnondefaultfonts]]


} {{a b c d e} d}
test font-7.3 {font command: delete: loop test} {



    # (namedHashPtr == NULL) in middle of loop
    setup
    set x {}
    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
    lappend x [lsort [getnondefaultfonts]]
    catch {font delete a d q c e b}
    lappend x [lsort [getnondefaultfonts]]


} {{a b c d e} {b c e}}
test font-7.4 {font command: delete: non-existent} {


    # (namedHashPtr == NULL)
    setup
    list [catch {font delete xyz} msg] $msg
} {1 {named font "xyz" doesn't exist}}
test font-7.5 {font command: delete: mark for later deletion} {





    # (nfPtr->refCount != 0)
    setup
    font create xyz
    .b.f configure -font xyz
    font delete xyz
    font actual xyz
    list [catch {font configure xyz} msg] $msg [.b.f cget -font]


} {1 {named font "xyz" doesn't exist} xyz}
test font-7.6 {font command: delete: actually delete} {





    # not (nfPtr->refCount != 0)
    setup
    font create xyz -underline 1

    font delete xyz

    catch {font config xyz}






} 1





setup

test font-8.1 {font command: families: arguments} {
    # (skip < 0)
    list [catch {font families -displayof} msg] $msg
} {1 {value for "-displayof" missing}}
test font-8.2 {font command: families: arguments} {
    # (objc - skip != 2) when skip == 0
    list [catch {font families xyz} msg] $msg
} {1 {wrong # args: should be "font families ?-displayof window?"}}
test font-8.3 {font command: families: arguments} {
    # (objc - skip != 2) when skip == 2
    list [catch {font families -displayof . xyz} msg] $msg
} {1 {wrong # args: should be "font families ?-displayof window?"}}
test font-8.4 {font command: families} failsOnUbuntu {
    # TkpGetFontFamilies()
    regexp -nocase times [font families]

} 1

test font-9.1 {font command: measure: arguments} {
    # (skip < 0)
    list [catch {expr {[font measure xyz -displayof]>0}} msg] $msg
} {0 1}
test font-9.2 {font command: measure: arguments} {
    # (objc - skip != 4)
    list [catch {font measure} msg] $msg
} {1 {wrong # args: should be "font measure font ?-displayof window? text"}}
test font-9.3 {font command: measure: arguments} {
    # (objc - skip != 4)
    list [catch {font measure xyz abc def} msg] $msg
} {1 {wrong # args: should be "font measure font ?-displayof window? text"}}
test font-9.4 {font command: measure: arguments} noExceed {
    # (tkfont == NULL)
    list [catch {font measure "\{xyz" abc} msg] $msg
} [list 1 "font \"{xyz\" doesn't exist"]
test font-9.5 {font command: measure} failsOnUbuntu {
    # Tk_TextWidth()
    expr [font measure $fixed "abcdefg"]==[font measure $fixed "a"]*7
} 1
test font-9.6 {font command: measure -d} {
     list [catch {expr {[font measure $fixed -d] > 0}} msg] $msg
} {0 1}
test font-9.7 {font command: measure -d with -displayof} {
     list [catch {expr {[font measure $fixed -displayof . -d] > 0}} msg] $msg
} {0 1}
test font-9.8 {font command: measure: arguments} {
    list [catch {font measure $fixed -displayof .} msg] $msg
} {1 {wrong # args: should be "font measure font ?-displayof window? text"}}


test font-10.1 {font command: metrics: arguments} {
    list [catch {font metrics xyz -displayof} msg] $msg
} {1 {value for "-displayof" missing}}
test font-10.2 {font command: metrics: arguments} {
    # (skip < 0)
    list [catch {font metrics xyz -displayof} msg] $msg
} {1 {value for "-displayof" missing}}
test font-10.3 {font command: metrics: arguments} {
    # (objc < 3)
    list [catch {font metrics} msg] $msg
} {1 {wrong # args: should be "font metrics font ?-displayof window? ?option?"}}
test font-10.4 {font command: metrics: arguments} {
    # (objc - skip) > 4) when skip == 0
    list [catch {font metrics xyz abc def} msg] $msg
} {1 {wrong # args: should be "font metrics font ?-displayof window? ?option?"}}
test font-10.5 {font command: metrics: arguments} {
    # (objc - skip) > 4) when skip == 2
    list [catch {font metrics xyz -displayof . abc} msg] $msg
} {1 {bad metric "abc": must be -ascent, -descent, -linespace, or -fixed}}
test font-10.6 {font command: metrics: bad font} noExceed {
    # (tkfont == NULL)
    list [catch {font metrics "\{xyz"} msg] $msg
} [list 1 "font \"{xyz\" doesn't exist"]
test font-10.7 {font command: metrics: get all metrics} {


    # (objc == 3)
    catch {unset a}
    array set a [font metrics {-family xyz}]
    set x [lsort [array names a]]

    unset a
    set x
} {-ascent -descent -fixed -linespace}
test font-10.8 {font command: metrics: bad metric} {
    # (Tcl_GetIndexFromObj() != TCL_OK)
    list [catch {font metrics $fixed -xyz} msg] $msg
} {1 {bad metric "-xyz": must be -ascent, -descent, -linespace, or -fixed}}
test font-10.9 {font command: metrics: get individual metrics} failsOnUbuntu {
    font metrics $fixed -ascent
    font metrics $fixed -descent
    font metrics $fixed -linespace
    font metrics $fixed -fixed

} 1

test font-11.1 {font command: names: arguments} {
    # (objc != 2)
    list [catch {font names xyz} msg] $msg
} {1 {wrong # args: should be "font names"}}
test font-11.2 {font command: names: loop test: no passes} {


    setup
    getnondefaultfonts
} {}
test font-11.3 {font command: names: loop test: one pass} {


    setup
    font create
    getnondefaultfonts
} font1
test font-11.4 {font command: names: loop test: multiple passes} {


    setup
    font create xyz
    font create abc
    font create def
    lsort [getnondefaultfonts]


} {abc def xyz}
test font-11.5 {font command: names: skip deletePending fonts} {
    # (nfPtr->deletePending == 0)


    setup
    set x {}


    font create xyz
    font create abc
    lappend x [lsort [getnondefaultfonts]]
    .b.f config -font xyz
    font delete xyz
    lappend x [getnondefaultfonts]


} {{abc xyz} abc}


test font-12.1 {UpdateDependantFonts procedure: no users} {


    # (nfPtr->refCount == 0)
    setup
    font create xyz
    font configure xyz -family times
} {}


test font-12.2 {UpdateDependantFonts procedure: pings the widgets} {
    setup
    font create xyz -family times -size 20
    .b.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
    set a1 [font measure xyz "abcd"]

    update





    set b1 [winfo reqwidth .b.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update
    set b2 [winfo reqwidth .b.f]
    expr {$a1==$b1 && $a2==$b2}




} 1

test font-13.1 {CreateNamedFont: new named font} {
    # not (new == 0)
    setup
    set x {}


    lappend x [getnondefaultfonts]
    font create xyz
    lappend x [getnondefaultfonts]


} {{} xyz}
test font-13.2 {CreateNamedFont: named font already exists} {


    # (new == 0)
    setup

    font create xyz
    list [catch {font create xyz} msg] $msg
} {1 {named font "xyz" already exists}}
test font-13.3 {CreateNamedFont: named font already exists} {


    # (nfPtr->deletePending == 0)
    setup
    font create xyz
    list [catch {font create xyz} msg] $msg


} {1 {named font "xyz" already exists}}
test font-13.4 {CreateNamedFont: recreate "deleted" font} {





    # not (nfPtr->deletePending == 0)
    setup
    font create xyz -family times
    .b.f configure -font xyz
    font delete xyz
    font create xyz -family courier
    font configure xyz -family



} courier


test font-14.1 {Tk_GetFont procedure} {

} {}

test font-15.1 {Tk_AllocFontFromObj - converting internal reps} testfont {
    set x {Times 16}
    lindex $x 0
    destroy .b1 .b2
    button .b1 -font $x
    lindex $x 0








    testfont counts {Times 16}


} {{1 0}}
test font-15.2 {Tk_AllocFontFromObj - discard stale font} testfont {

    set x {Times 16}
    destroy .b1 .b2



    button .b1 -font $x
    destroy .b1
    set result {}
    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    lappend result [testfont counts {Times 16}]


} {{} {{1 1}}}
test font-15.3 {Tk_AllocFontFromObj - reuse existing font} testfont {

    set x {Times 16}
    destroy .b1 .b2



    button .b1 -font $x
    set result {}
    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    pack .b1 .b2 -side top
    lappend result [testfont counts {Times 16}]


} {{{1 1}} {{2 1}}}
test font-15.4 {Tk_AllocFontFromObj procedure: bump ref count} {




    # (new == 0)
    setup
    .b.f config -font {-family fixed}
    lindex [font actual {-family fixed}] 0


} {-family}
test font-15.5 {Tk_AllocFontFromObj procedure: get named font} {





    # (namedHashPtr != NULL)
    setup
    font create xyz
    .b.f config -font xyz
} {}



test font-15.6 {Tk_AllocFontFromObj procedure: not a named font} {




    # not (namedHashPtr != NULL)
    setup
    .b.f config -font {times 20}
} {}


test font-15.7 {Tk_AllocFontFromObj procedure: get native font} unix {






    # not (fontPtr == NULL)
    setup
    .b.f config -font fixed
} {}
test font-15.8 {Tk_AllocFontFromObj procedure: get native font} win {







    # not (fontPtr == NULL)
    setup
    .b.f config -font oemfixed
} {}


test font-15.10 {Tk_AllocFontFromObj procedure: get attribute font} {




    # (fontPtr == NULL)
    list [catch {.b.f config -font {xxx yyy zzz}} msg] $msg


} {1 {expected integer but got "yyy"}}
test font-15.11 {Tk_AllocFontFromObj procedure: no match} noExceed {
    # (ParseFontNameObj() != TCL_OK)
    list [catch {font actual "\{xyz"} msg] $msg
} [list 1 "font \"{xyz\" doesn't exist"]
test font-15.12 {Tk_AllocFontFromObj procedure: get attribute font} {
    # not (ParseFontNameObj() != TCL_OK)
    lindex [font actual {plan 9}] 0
} {-family}
test font-15.13 {Tk_AllocFontFromObj procedure: setup tab width} {


    # Tk_MeasureChars(fontPtr, "0", ...)
    label .l -bd 0 -padx 0  -highlightthickness 0 -font $fixed -text "a\tb"
    update
    set x [winfo reqwidth .l]



    destroy .l
    set x
} [expr [font measure $fixed "0"]*9]
test font-15.14 {Tk_AllocFontFromObj procedure: underline position} {




    # (fontPtr->underlineHeight == 0) because size was < 10
    setup
    .b.f config -text "underline" -font "times -8 underline"
    update



} {}

test font-16.1 {Tk_NameOfFont procedure} {


    setup

    .b.f config -font -family\ fixed
    .b.f cget -font


} {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} testfont {

    set x {Courier 12}
    destroy .b1 .b2 .b3



    button .b1 -font $x
    button .b3 -font $x
    button .b2 -font $x
    set result {}
    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    destroy .b2
    lappend result [testfont counts {Courier 12}]
    destroy .b3
    lappend result [testfont counts {Courier 12}]
} {{{3 1}} {{2 1}} {{1 1}} {}}
test font-17.2 {Tk_FreeFont procedure: one ref} {




    # (fontPtr->refCount == 0)
    setup
    .b.f config -font {-family fixed}
    destroy .b.f
} {}
test font-17.3 {Tk_FreeFont procedure: multiple ref} {




    # not (fontPtr->refCount == 0)
    setup
    .b.f config -font {-family fixed}
    button .b.b -font {-family fixed}
    destroy .b.f
    set x [.b.b cget -font]

    destroy .b.b
    set x
} {-family fixed}
test font-17.4 {Tk_FreeFont procedure: named font} {





    # (fontPtr->namedHashPtr != NULL)
    setup
    font create xyz
    .b.f config -font xyz
    destroy .b.f
    expr {"xyz" in [font names]}
} 1
test font-17.5 {Tk_FreeFont procedure: named font} {





    # not (fontPtr->refCount == 0)
    setup
    font create xyz -underline 1
    .b.f config -font xyz
    font delete xyz
    set x [font actual xyz -underline]
    destroy .b.f
    list [font actual xyz -underline] $x
} {0 1}
test font-17.6 {Tk_FreeFont procedure: named font not deleted yet} {



    setup

    font create xyz
    .b.f config -font xyz
    button .b.b -font xyz
    font delete xyz
    set x [font actual xyz]
    destroy .b.b
    list [lindex [font actual xyz] 0] [lindex $x 0]


} {-family -family}


test font-18.1 {FreeFontObjProc} {testfont failsOnUbuntu failsOnQuarz} {
    destroy .b1


    set x [format {Courier 12}]
    button .b1 -font $x
    set y [format {Courier 12}]
    .b1 configure -font $y
    set z [format {Courier 12}]
    .b1 configure -font $z
    set result {}
    lappend result [testfont counts {Courier 12}]
    set x red
    lappend result [testfont counts {Courier 12}]
    set z 32
    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    set y bogus
    set result
} {{{1 3}} {{1 2}} {{1 1}} {}}


test font-19.1 {Tk_FontId} {




    .b.f config -font "times 20"
    update



} {}

test font-20.1 {Tk_GetFontMetrics procedure} {


    button .b.w1 -text abc
    entry .b.w2 -text abcd
    update
    destroy .b.w1 .b.w2

} {}


proc psfontname {name} {





    set a [.b.c itemcget text -font]
    .b.c itemconfig text -text "We need text" -font $name
    set post [.b.c postscript]
    .b.c itemconfig text -font $a
    set end [string first "findfont" $post]
    incr end -2
    set post [string range $post [expr $end-70] $end]
    set start [string first "gsave" $post]

    return [string range $post [expr $start+7] end]
}
test font-21.1 {Tk_PostscriptFontName procedure: native} unix {


    set x [font actual {{itc avant garde} 10} -family]
    if {[string match *avant*garde $x]} {
	psfontname "{itc avant garde} 10"
    } else {
	set x {AvantGarde-Book}
    }
} {AvantGarde-Book}
test font-21.2 {Tk_PostscriptFontName procedure: native} win {


    psfontname "arial 10"
} Helvetica
test font-21.3 {Tk_PostscriptFontName procedure: native} win {


    psfontname "{times new roman} 10"
} Times-Roman
test font-21.4 {Tk_PostscriptFontName procedure: native} win {


    psfontname "{courier new} 10"
} Courier
test font-21.8 {Tk_PostscriptFontName procedure: spaces} unix {


    set x [font actual {{lucida bright} 10} -family]
    if {[string match lucida*bright $x]} {
	psfontname "{lucida bright} 10"
    } else {
	set x LucidaBright
    }
} LucidaBright
test font-21.9 {Tk_PostscriptFontName procedure: spaces} {unix failsOnUbuntu} {


    psfontname "{new century schoolbook} 10"
} {NewCenturySchlbk-Roman}
set i 10






foreach p {






    {font-21.10 "avantgarde"



	    AvantGarde-Book AvantGarde-Demi









	    AvantGarde-BookOblique AvantGarde-DemiOblique}


    {font-21.11 "bookman"




	    Bookman-Light Bookman-Demi Bookman-LightItalic Bookman-DemiItalic}
    {font-21.12 "courier"

	    Courier Courier-Bold Courier-Oblique Courier-BoldOblique}


    {font-21.13 "helvetica"
	    Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique}
    {font-21.14 "new century schoolbook"




	    NewCenturySchlbk-Roman NewCenturySchlbk-Bold
	    NewCenturySchlbk-Italic NewCenturySchlbk-BoldItalic}



    {font-21.15 "palatino"

	    Palatino-Roman Palatino-Bold Palatino-Italic Palatino-BoldItalic}
    {font-21.16 "symbol"
	    Symbol Symbol Symbol Symbol}






    {font-21.17 "times"


	    Times-Roman Times-Bold Times-Italic Times-BoldItalic}

    {font-21.18 "zapfchancery"

	    ZapfChancery-MediumItalic ZapfChancery-MediumItalic

	    ZapfChancery-MediumItalic ZapfChancery-MediumItalic}
    {font-21.19 "zapfdingbats"









	    ZapfDingbats ZapfDingbats ZapfDingbats ZapfDingbats}
















} {
    set values [lassign $p testName family]


    test $testName {Tk_PostscriptFontName procedure: exhaustive} {unix failsOnQuarz} {
	set x {}
	set j 0
	foreach slant {roman italic} {
	    foreach weight {normal bold} {
		set name [list $family 12 $slant $weight]
		if {[font actual $name -family] == $family} {
		    lappend x [psfontname $name]
		} else {
		    lappend x [lindex $values $j]
		}


		incr j






	    }

	}







	set x
    } $values
}
foreach p {
    {font-21.20 "arial"








	    Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique}
    {font-21.21 "courier new"
	    Courier Courier-Bold Courier-Oblique Courier-BoldOblique}





    {font-21.22 "helvetica"

	    Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique}
    {font-21.23 "symbol"









	    Symbol Symbol-Bold Symbol-Italic Symbol-BoldItalic}
    {font-21.24 "times new roman"






	    Times-Roman Times-Bold Times-Italic Times-BoldItalic}
} {








    set values [lassign $p testName family]


    test $testName {Tk_PostscriptFontName procedure: exhaustive} win {






	set x {}












	foreach slant {roman italic} {



	    foreach weight {normal bold} {

		lappend x [psfontname [list $family 12 "$slant $weight"]]


	    }









	}







	set x
    } $values
}











test font-22.1 {Tk_TextWidth procedure} {




    font measure [.b.l cget -font] "000"

} [expr $ax*3]



test font-23.1 {Tk_UnderlineChars procedure} {






    text .b.t

    .b.t insert 1.0 abc\tdefg

    .b.t tag config sel -underline 1




    .b.t tag add sel 1.0 end




    update






} {}






















































setup
test font-24.1 {Tk_ComputeTextLayout: empty string} {
    .b.l config -text ""





} {}

test font-24.2 {Tk_ComputeTextLayout: simple string} {

    .b.l config -text "000"



    getsize

} "[expr $ax*3] $ay"

test font-24.3 {Tk_ComputeTextLayout: find special chars} {

    .b.l config -text "000\n000"



    getsize



} "[expr $ax*3] [expr $ay*2]"
test font-24.4 {Tk_ComputeTextLayout: calls Tk_MeasureChars} {
    .b.l config -text "000\n000"
    getsize
} "[expr $ax*3] [expr $ay*2]"


test font-24.5 {Tk_ComputeTextLayout: break line} failsOnUbuntu {
    .b.l config -text "000\t00000" -wrap [expr 9*$ax]
    set x [getsize]

    .b.l config -wrap 0
    set x


} "[expr 8*$ax] [expr 2*$ay]"
test font-24.6 {Tk_ComputeTextLayout: normal ended on special char} {

    .b.l config -text "000\n000"





} {}

test font-24.7 {Tk_ComputeTextLayout: special char was \n} {

    .b.l config -text "000\n0000"








    getsize








} "[expr $ax*4] [expr $ay*2]"
test font-24.8 {Tk_ComputeTextLayout: special char was \t} {

    .b.l config -text "000\t00"



    getsize













} "[expr $ax*10] $ay"
test font-24.9 {Tk_ComputeTextLayout: tab didn't cause break} {







    set x {}



    .b.l config -text "000\t000"





    lappend x [getsize]

    .b.l config -text "000\t000" -wrap [expr 100*$ax]



    lappend x [getsize]



    .b.l config -wrap 0
    set x

} "{[expr $ax*11] $ay} {[expr $ax*11] $ay}"
test font-24.10 {Tk_ComputeTextLayout: tab caused break} {


    set x {}



    .b.l config -text "000\t"
    lappend x [getsize]

    .b.l config -text "000\t00" -wrap [expr $ax*6]



    lappend x [getsize]



    .b.l config -wrap 0










    set x

} "{[expr $ax*8] $ay} {[expr $ax*8] [expr $ay*2]}"
test font-24.11 {Tk_ComputeTextLayout: absorb spaces at eol} {







    set x {}











    .b.l config -text "000            000" -wrap [expr $ax*5]
    lappend x [getsize]




    .b.l config -text "000            "

    lappend x [getsize]

    .b.l config -wrap 0

    set x
} "{[expr $ax*3] [expr $ay*2]} {[expr $ax*3] $ay}"
test font-24.12 {Tk_ComputeTextLayout: append non-printing spaces to chunk} {


    set x {}


    .b.l config -text "000            0000" -wrap [expr $ax*5]
    lappend x [getsize]




    .b.l config -text "000\t00            0000" -wrap [expr $ax*12]
    lappend x [getsize]









    .b.l config -wrap 0
    set x



} "{[expr $ax*4] [expr $ay*2]} {[expr $ax*10] [expr $ay*2]}"


test font-24.13 {Tk_ComputeTextLayout: many lines -> realloc line array} {
    .b.l config -text "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
    getsize
} "1 [expr $ay*129]"


test font-24.14 {Tk_ComputeTextLayout: text ended with \n} {
    list [.b.l config -text "0000"; getsize] [.b.l config -text "0000\n"; getsize]

} "{[expr $ax*4] $ay} {[expr $ax*4] [expr $ay*2]}"













test font-24.15 {Tk_ComputeTextLayout: justification} {
    csetup "000\n00000"











    set x {}
    .b.c itemconfig text -just left


    lappend x [.b.c index text @[expr $ax*2],0]
    .b.c itemconfig text -just center


    lappend x [.b.c index text @[expr $ax*2],0]


    .b.c itemconfig text -just right






    lappend x [.b.c index text @[expr $ax*2],0]






    .b.c itemconfig text -just left


    set x



} {2 1 0}









test font-25.1 {Tk_FreeTextLayout procedure} {
    setup
    .b.f config -text foo









    .b.f config -text boo








} {}




test font-26.1 {Tk_DrawTextLayout procedure: auto-detect last char} {
    .b.f config -text foo



} {}


test font-26.2 {Tk_DrawTextLayout procedure: multiple chunks} {
    csetup "000\t00\n000"
} {}

test font-26.3 {Tk_DrawTextLayout: draw subset of chunk: numDisplay <= 0} {
    csetup "000\t00"

    .b.c select from text 3
    .b.c select to text 5
} {}












test font-26.4 {Tk_DrawTextLayout: draw subset of chunk: firstChar <= 0} {
    .b.c select from text 3



    .b.c select to text 5
} {}





test font-26.5 {Tk_DrawTextLayout: draw subset of chunk: firstChar > 0} {
    .b.c select from text 2





    .b.c select to text 2




} {}







test font-26.6 {Tk_DrawTextLayout: draw subset of chunk: lastChar < numChars} {
















    .b.c select from text 4
    .b.c select to text 4
} {}






test font-27.1 {Tk_UnderlineTextLayout procedure: no underline chosen} {
    .b.f config -text "foo" -under -1
} {}
test font-27.2 {Tk_UnderlineTextLayout procedure: underline not visible} {
    .b.f config -text "000          00000" -wrap [expr $ax*7] -under 10
} {}
test font-27.3 {Tk_UnderlineTextLayout procedure: underline is visible} {
    .b.f config -text "000          00000" -wrap [expr $ax*7] -under 5
    .b.f config -wrap -1 -under -1


} {}








test font-28.1 {Tk_PointToChar procedure: above all lines} {
    csetup "000"
    .b.c index text @-1,0
} 0
test font-28.2 {Tk_PointToChar procedure: no chars} {
    # After fixing the following bug:
    #
    # In canvas text item, it was impossible to click to position the
    # insertion point just after the last character.
    #
    # introduced another bug that Tk_PointToChar() would return a character
    # index of 1 if TextLayout contained 0 characters.

    csetup ""
    .b.c index text @100,100
} 0
test font-28.3 {Tk_PointToChar procedure: loop test} {
    csetup "000\n000\n000\n000"
    .b.c index text @10000,0
} 3
test font-28.4 {Tk_PointToChar procedure: intersect line} {
    csetup "000\n000\n000"
    .b.c index text @0,$ay
} 4
test font-28.5 {Tk_PointToChar procedure: to the left of all chunks} {

    .b.c index text @-100,$ay
} 4
test font-28.6 {Tk_PointToChar procedure: past any possible chunk} {

    .b.c index text @100000,$ay
} 7
test font-28.7 {Tk_PointToChar procedure: which chunk on this line} {
    csetup "000\n000\t000\t000\n000"
    .b.c index text @[expr $ax*2],$ay
} 6
test font-28.8 {Tk_PointToChar procedure: which chunk on this line} {
    csetup "000\n000\t000\t000\n000"









    .b.c index text @[expr $ax*10],$ay
} 10
test font-28.9 {Tk_PointToChar procedure: in special chunk} {
    csetup "000\n000\t000\t000\n000"
    .b.c index text @[expr $ax*6],$ay
} 7
test font-28.10 {Tk_PointToChar procedure: past all chars in chunk} {
    csetup "000 0000000"
    .b.c itemconfig text -width [expr $ax*5]
    set x [.b.c index text @[expr $ax*5],0]
    .b.c itemconfig text -width 0
    set x
} 3
test font-28.11 {Tk_PointToChar procedure: below all chunks} {
    csetup "000 0000000"
    .b.c index text @0,1000000


} 11





test font-29.1 {Tk_CharBBox procedure: index < 0} {
    .b.f config -text "000" -underline -1
} {}
test font-29.2 {Tk_CharBBox procedure: loop} {
    .b.f config -text "000\t000\t000\t000" -underline 9
} {}
test font-29.3 {Tk_CharBBox procedure: special char} {
    .b.f config -text "000\t000\t000" -underline 7











} {}

test font-29.4 {Tk_CharBBox procedure: normal char} {
    .b.f config -text "000" -underline 1
} {}






test font-29.5 {Tk_CharBBox procedure: right edge of bbox truncated} {
    .b.f config -text "0    0000" -wrap [expr $ax*4] -under 2
    .b.f config -wrap 0

} {}






test font-29.6 {Tk_CharBBox procedure: bbox pegged to right edge} {
    .b.f config -text "0    0000" -wrap [expr $ax*4] -under 3
    .b.f config -wrap 0

} {}








.b.c bind all <Enter> {lappend x [.b.c index current @%x,%y]}

test font-30.1 {Tk_DistanceToTextLayout procedure: loop once} {
    csetup "000\n000\n000"
    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x 0 -y 0
    set x
} 0


test font-30.2 {Tk_DistanceToTextLayout procedure: loop multiple} {
    csetup "000\n000\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x $ax -y $ay
    set x
} 5


test font-30.3 {Tk_DistanceToTextLayout procedure: loop to end} {
    csetup "000\n0\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x [expr $ax*2] -y $ay
    set x

} {}

test font-30.4 {Tk_DistanceToTextLayout procedure: hit a special char (tab)} {
    csetup "000\t000\n000"


    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x [expr $ax*6] -y 0
    set x
} 3
test font-30.5 {Tk_DistanceToTextLayout procedure: ignore newline} {
    csetup "000\n0\n000"
    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x [expr $ax*2] -y $ay
    set x

} {}


test font-30.6 {Tk_DistanceToTextLayout procedure: ignore spaces at eol} {
    csetup "000\n000      000000000"

    .b.c itemconfig text -width [expr $ax*10]
    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x [expr $ax*5] -y $ay
    .b.c itemconfig text -width 0
    set x
} {}
.b.c itemconfig text -justify center

test font-30.7 {Tk_DistanceToTextLayout procedure: on left side} {
    csetup "0\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x 0 -y 0
    set x

} {}

test font-30.8 {Tk_DistanceToTextLayout procedure: on right side} {
    csetup "0\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x [expr $ax*2] -y 0
    set x
} {}
test font-30.9 {Tk_DistanceToTextLayout procedure: inside line} {
    csetup "0\n000"
    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x $ax -y 0
    set x
} 0
test font-30.10 {Tk_DistanceToTextLayout procedure: above line} {
    csetup "0\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x 0 -y 0
    set x

} {}

test font-30.11 {Tk_DistanceToTextLayout procedure: below line} {
    csetup "000\n0"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x 0 -y $ay
    set x

} {}

test font-30.12 {Tk_DistanceToTextLayout procedure: in line} {
    csetup "0\n000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x $ax -y $ay
    set x
} 3


.b.c itemconfig text -justify left
test font-30.13 {Tk_DistanceToTextLayout procedure: exact hit} {
    csetup "000"

    set x {}
    event generate .b.c <Leave>
    event generate .b.c <Enter> -x $ax -y 0
    set x




} 1







test font-31.1 {Tk_IntersectTextLayout procedure: loop once} {
    csetup "000\n000\n000"
    .b.c find overlapping 0 0 0 0
} [.b.c find withtag text]
test font-31.2 {Tk_IntersectTextLayout procedure: loop multiple} {
    csetup "000\t000\t000"
    .b.c find overlapping [expr $ax*10] 0 [expr $ax*10] 0
} [.b.c find withtag text]
test font-31.3 {Tk_IntersectTextLayout procedure: loop to end} {
    csetup "0\n000"
    .b.c find overlapping [expr $ax*2] 0 [expr $ax*2] 0
} {}
test font-31.4 {Tk_IntersectTextLayout procedure: hit a special char (tab)} {
    csetup "000\t000"
    .b.c find overlapping [expr $ax*6] 0 [expr $ax*6] 0
} [.b.c find withtag text]
test font-31.5 {Tk_IntersectTextLayout procedure: ignore newlines} {
    csetup "000\n0\n000"
    .b.c find overlapping $ax $ay $ax $ay
} {}
test font-31.6 {Tk_IntersectTextLayout procedure: ignore spaces at eol} {
    csetup "000\n000      000000000"
    .b.c itemconfig text -width [expr $ax*10]
    set x [.b.c find overlapping [expr $ax*5] $ay [expr $ax*5] $ay]
    .b.c itemconfig text -width 0
    set x












} {}

test font-32.1 {Tk_TextLayoutToPostscript: ensure buffer doesn't overflow} {failsOnUbuntu failsOnQuarz} {






    # If there were a whole bunch of returns or tabs in a row, then the
    # temporary buffer could overflow and write on the stack.

    csetup "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .b.c itemconfig text -width 800
    .b.c insert text end "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .b.c insert text end "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
    .b.c insert text end "end"
    set x [.b.c postscript]
    set i [string first "(qwerty" $x]
    string range $x $i [expr {$i + 278}]


} {(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[()]
[()]
[()]
[()]
[()]
[()]
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042


2043
2044
2045
2046
2047
2048
2049
2050

2051
2052
2053
2054
2055
2056



2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084

2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141

2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229


2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346

2347
2348
2349
2350
2351
2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378

2379


2380
2381
2382
2383

2384


2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396

2397

2398




2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
[()]
[()]
[()]
[()]
[(end)]
}


test font-33.1 {Tk_TextWidth procedure} -body {
} -result {}


test font-34.1 {ConfigAttributesObj procedure: arguments} -setup {
    catch {font delete xyz}
} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)


    font create xyz -xyz
} -returnCodes {
    error
} -result {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-34.2 {ConfigAttributesObj procedure: arguments} -setup {
    catch {font delete xyz}
} -body {
    # (objc & 1)

    font create xyz -family
} -returnCodes error -result {value for "-family" option missing}

test font-34.3 {ConfigAttributesObj procedure: family} -setup {
    catch {font delete xyz}
    set x {}



} -body {
    font create xyz -family xyz
    lappend x [font config xyz -family]
    font config xyz -family times
    lappend x [font config xyz -family]
} -cleanup {
	font delete xyz
} -result {xyz times}
test font-34.4 {ConfigAttributesObj procedure: size} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -size 20
    lappend x [font config xyz -size]
    font config xyz -size 40
    lappend x [font config xyz -size]
} -cleanup {
    font delete xyz
} -result {20 40}
test font-34.5 {ConfigAttributesObj procedure: weight} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -weight normal
    lappend x [font config xyz -weight]
    font config xyz -weight bold
    lappend x [font config xyz -weight]
} -cleanup {

    font delete xyz
} -result {normal bold}
test font-34.6 {ConfigAttributesObj procedure: slant} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -slant roman
    lappend x [font config xyz -slant]
    font config xyz -slant italic
    lappend x [font config xyz -slant]
} -cleanup {
    font delete xyz
} -result {roman italic}
test font-34.7 {ConfigAttributesObj procedure: underline} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -underline 0
    lappend x [font config xyz -underline]
    font config xyz -underline 1
    lappend x [font config xyz -underline]
} -cleanup {
    font delete xyz
} -result {0 1}
test font-34.8 {ConfigAttributesObj procedure: overstrike} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -overstrike 0
    lappend x [font config xyz -overstrike]
    font config xyz -overstrike 1
    lappend x [font config xyz -overstrike]
} -cleanup {
    font delete xyz
} -result {0 1}

test font-34.9 {ConfigAttributesObj procedure: size} -body {
    font create xyz -size xyz
} -returnCodes error -result {expected integer but got "xyz"}
test font-34.10 {ConfigAttributesObj procedure: weight} -body {
    font create xyz -weight xyz
} -returnCodes error -result {bad -weight value "xyz": must be normal, or bold}
test font-34.11 {ConfigAttributesObj procedure: slant} -body {
    font create xyz -slant xyz
} -returnCodes error -result {bad -slant value "xyz": must be roman, or italic}
test font-34.12 {ConfigAttributesObj procedure: underline} -body {
    font create xyz -underline xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test font-34.13 {ConfigAttributesObj procedure: overstrike} -body {
    font create xyz -overstrike xyz
} -returnCodes error -result {expected boolean value but got "xyz"}


test font-35.1 {GetAttributeInfoObj procedure: one attribute} -setup {
    catch {font delete xyz}
} -body {
    # (objPtr != NULL)

    font create xyz -family xyz
    font config xyz -family
} -cleanup {
    font delete xyz
} -result {xyz}


test font-36.1 {GetAttributeInfoObj procedure: unknown attribute} -setup {
    catch {font delete xyz}
} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)

    font create xyz
    font config xyz -xyz
} -cleanup {
    font delete xyz
} -returnCodes {
    error
} -result {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}


test font-37.1 {GetAttributeInfoObj procedure: all attributes} -setup {
    catch {font delete xyz}
} -body {
    # not (objPtr != NULL)
    font create xyz -family xyz
    font config xyz
} -cleanup {
    font delete xyz
} -result {-family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0}
test font-37.2 {GetAttributeInfo procedure: family} -setup {
    catch {font delete xyz}
} -body {
    font create xyz -family xyz
    font config xyz -family
} -cleanup {
    font delete xyz
} -result {xyz}
test font-37.3 {GetAttributeInfo procedure: size} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -size 20
    font config xyz -size
} -cleanup {
    font delete xyz
} -result 20
test font-37.4 {GetAttributeInfo procedure: weight} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -weight normal
    font config xyz -weight
} -cleanup {
    font delete xyz
} -result {normal}
test font-37.5 {GetAttributeInfo procedure: slant} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -slant italic
    font config xyz -slant
} -cleanup {
    font delete xyz
} -result {italic}
test font-37.6 {GetAttributeInfo procedure: underline} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -underline yes
    font config xyz -underline
} -cleanup {
    font delete xyz
} -result 1

test font-37.7 {GetAttributeInfo procedure: overstrike} -setup {
    catch {font delete xyz}
    set x {}
} -body {
    font create xyz -overstrike no
    font config xyz -overstrike
} -cleanup {
    font delete xyz
} -result 0


# In tests below, one field is set to "xyz" so that font name doesn't
# look like a native X font, so that ParseFontNameObj or TkParseXLFD will
# be called.



test font-38.1 {ParseFontNameObj procedure: begins with -} -body {
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]
test font-38.2 {ParseFontNameObj procedure: begins with -*} -body {
    lindex [font actual -*-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]
test font-38.3 {ParseFontNameObj procedure: begins with -, doesn't look like list} -body {
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]
test font-38.4 {ParseFontNameObj procedure: begins with -, looks like list} -body {
    lindex [font actual {-family times}] 1
} -result [font actual {times 0} -family]
test font-38.5 {ParseFontNameObj procedure: begins with *} -body {
    lindex [font actual *-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]
test font-38.6 {ParseFontNameObj procedure: begins with *} -body {
    font actual *-times-xyz -family
} -result [font actual {times 0} -family]
test font-38.7 {ParseFontNameObj procedure: arguments} -constraints noExceed -body {
    font actual "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-38.8 {ParseFontNameObj procedure: arguments} -constraints noExceed -body {
    font actual ""
} -returnCodes error -result {font "" doesn't exist}
test font-38.9 {ParseFontNameObj procedure: arguments} -body {
    font actual {times 20 xyz xyz}
} -returnCodes error -result {unknown font style "xyz"}
test font-38.10 {ParseFontNameObj procedure: arguments} -body {
    font actual {times xyz xyz}
} -returnCodes error -result {expected integer but got "xyz"}
test font-38.11 {ParseFontNameObj procedure: stylelist loop} -constraints {
	unixOrWin failsOnUbuntuNoXft
} -body {
    lrange [font actual {times 12 bold italic overstrike underline}] 4 end
} -result {-weight bold -slant italic -underline 1 -overstrike 1}
test font-38.12 {ParseFontNameObj procedure: stylelist error} -body {
    font actual {times 12 bold xyz}
} -returnCodes error -result {unknown font style "xyz"}
test font-38.13 "ParseFontNameObj: options with hyphenated family: bug #2791352" -body {
    font actual {-family sans-serif -size 12 -weight bold -slant roman -underline 0 -overstrike 0}
} -returnCodes ok -result [font actual {sans-serif 12 bold}]
test font-38.14 "ParseFontNameObj: bug #2791352" -body {
    font actual {-invalidfont 8 bold}
} -returnCodes error -match glob -result {bad option "-invalidfont": *}


test font-39.1 {NewChunk procedure: test realloc} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -text "xxx\nxxx\txxx\nxxx\t\t\t"
} -cleanup {
	destroy .t.f
} -result {}


test font-40.1 {TkFontParseXLFD procedure: initial dash} -body {
    font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-* -family
} -result [font actual {times 0} -family]
test font-40.2 {TkFontParseXLFD procedure: no initial dash} -body {
    font actual *-times-*-*-*-*-*-*-*-*-*-*-*-xyz -family
} -result [font actual {times 0} -family]
test font-40.3 {TkFontParseXLFD procedure: not enough fields} -body {
    font actual -xyz-times-*-*-* -family
} -result [font actual {times 0} -family]
test font-40.4 {TkFontParseXLFD procedure: all fields unspecified} -body {
    lindex [font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*] 0
} -result {-family}
test font-40.5 {TkFontParseXLFD procedure: all fields specified} -body {
    lindex [font actual \
        -foundry-times-weight-slant-setwidth-addstyle-10-10-10-10-spacing-avgwidth-registry-encoding] 1
} -result [font actual {times 0} -family]


test font-41.1 {TkParseXLFD procedure: arguments} -body {
    # XLFD with bad pointsize: fallback to some system font.
    font actual -*-*-*-*-*-*-xyz-*-*-*-*-*-*-*
    set x {}
} -result {}


test font-42.1 {TkFontParseXLFD procedure: arguments} -body {
    # XLFD with bad pixelsize: fallback to some system font.
    font actual -*-*-*-*-*-*-*-xyz-*-*-*-*-*-*
    set x {}
} -result {}
test font-42.2 {TkFontParseXLFD procedure: pixelsize specified} -body {
    font metrics -xyz-times-*-*-*-*-12-*-*-*-*-*-*-* -linespace
    set x {}
} -result {}
test font-42.3 {TkFontParseXLFD procedure: weird pixelsize specified} -body {
    font metrics {-xyz-times-*-*-*-*-[ 12.0 0 12.0 0]-*-*-*-*-*-*-*} -linespace
    set x {}
} -result {}
test font-42.4 {TkFontParseXLFD procedure: pointsize specified} -body {
    font metrics -xyz-times-*-*-*-*-*-120-*-*-*-*-*-* -linespace
    set x {}
} -result {}
test font-42.5 {TkFontParseXLFD procedure: weird pointsize specified} -body {
    font metrics {-xyz-times-*-*-*-*-*-[ 12.0 0 12.0 0]-*-*-*-*-*-*} -linespace
    set x {}
} -result {}


test font-43.1 {FieldSpecified procedure: specified vs. non-specified} -body {
    font actual -xyz--*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-?-*-*-*-*-*-*-*-*-*-*-*-*
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]


test font-44.1 {TkFontGetPixels: size < 0} -constraints failsOnUbuntuNoXft -setup {
    set oldscale [tk scaling]
} -body {
    tk scaling 0.5

    font actual {times -12} -size
} -cleanup {
    tk scaling $oldscale
} -result 24
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed failsOnUbuntuNoXft} -setup {
    set oldscale [tk scaling]
} -body {
    tk scaling 0.5
    font actual {times 12} -size

} -cleanup {
    tk scaling $oldscale
} -result 12


test font-45.1 {TkFontGetAliasList: no match} -body {
    font actual {snarky 10} -family
} -result [font actual {-size 10} -family]
test font-45.2 {TkFontGetAliasList: match} -constraints win -body {
    font actual {times 10} -family
} -result {times}
test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed} -body {
    if {[font actual {{times new roman} 10} -family] eq "Times New Roman"} {
        # avoid test failure on systems that have a real "times new roman" font
        set res 1
    } else {
        set res [expr {[font actual {{times new roman} 10} -family] eq \
                       [font actual {times 10} -family]} ]
    }
} -result 1


test font-46.1 {font actual, with character, no option, no --} -body {

    font actual {times 10} a


} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.2 {font actual, with character introduced by --} -body {

    font actual {times 10} -- -


} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.3 {font actual, with character and option} -body {
    font actual {times 10} -family a
} -result [font actual {times 10} -family]

test font-46.4 {font actual, with character, option and --} -body {
    font actual {times 10} -family -- -
} -result [font actual {times 10} -family]

test font-46.5 {font actual, too many chars} -body {

    font actual {times 10} 123456789012345678901234567890123456789012345678901

} -returnCodes error -result {expected a single character but got "1234567890123456789012345678901234567..."}





test font-47.1 {Bug f214b8ad5b} -body {
    interp create one
    interp create two
    load {} Tk one
    load {} Tk two
    one eval menu .menubar
    two eval menu .menubar
    interp delete one
    interp delete two
} -result {}

# cleanup
cleanupTests
return











<
|
<
|

|
<
<

>
>
|
<
<
|
|
<
<

>
|
|
|
|
|
|
>
>
>
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
>
|
<
|
|
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
<
<
<
|
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|

|
<
<

>


<
|
<

<
|
<
<

>

|
<
<
<
<
|

<
|
<
<

<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
|
<
|
<
|
|
<
<
|
<
<
|
|
>
|
<
|
|
|
|
<
<
|
|





>
>
|

|
|

|
|

|
|

|
|

|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<

|
|
|
|
|

|
|



<
|
<
<
<
<
|
<
<
<
|

|

|
|

|
|

|
|

|
|
<
|
<
|
<
|



<
|
<
|



|
|


|
|


|
|


|
|


<
|

|




<
|

<
|
<
|
>

|
<
<
|
<
<
<

>
|
|
<

<
|

|
|

|
|
<
|
<
<
|
|
|
<
<
<
|
>
|
>
>
|


|
>
|
>
>
|


|

|

|

|

|
>
|
>
|
>
>
>
>















<
<
<
<
1156
1157
1158
1159
1160
1161
1162

1163

1164
1165
1166


1167
1168
1169
1170


1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185






1186

1187










1188

1189
1190
1191
1192
1193
1194
1195

1196
1197








1198
1199
1200

1201






1202
1203

1204
1205
1206


















1207



1208
1209
1210


1211
1212
1213
1214

1215

1216

1217


1218
1219
1220
1221




1222
1223

1224


1225



1226




1227









1228







1229






1230

1231
1232

1233

1234
1235


1236


1237
1238
1239
1240

1241
1242
1243
1244


1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284


1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

1297




1298



1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313

1314

1315

1316
1317
1318
1319

1320

1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345
1346
1347

1348
1349

1350

1351
1352
1353
1354


1355



1356
1357
1358
1359

1360

1361
1362
1363
1364
1365
1366
1367

1368


1369
1370
1371



1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419




[()]
[()]
[()]
[()]
[(end)]
}


test font-33.1 {Tk_TextWidth procedure} {

} {}

test font-34.1 {ConfigAttributesObj procedure: arguments} {


    # (Tcl_GetIndexFromObj() != TCL_OK)
    set x {}
    setup
    list [catch {font create xyz -xyz} msg] $msg


} {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}}
test font-34.2 {ConfigAttributesObj procedure: arguments} {


    # (objc & 1)
    setup
    list [catch {font create xyz -family} msg] $msg
} {1 {value for "-family" option missing}}
foreach p {
    {font-34.3 family xyz times}
    {font-34.4 size 20 40}
    {font-34.5 weight normal bold}
    {font-34.6 slant roman italic}
    {font-34.7 underline 0 1}
    {font-34.8 overstrike 0 1}
} {
    lassign $p testName opt val1 val2






    test $testName "ConfigAttributesObj procedure: $opt" {

	setup










	set x {}

	font create xyz -$opt $val1
	lappend x [font config xyz -$opt]
	font config xyz -$opt $val2
	lappend x [font config xyz -$opt]
    } [list $val1 $val2]
}
foreach p {

    {font-34.9  size   xyz {expected integer but got "xyz"}}
    {font-34.10 weight xyz {bad -weight value "xyz": must be normal, or bold}}








    {font-34.11 slant  xyz {bad -slant value "xyz": must be roman, or italic}}
    {font-34.12 underline  xyz {expected boolean value but got "xyz"}}
    {font-34.13 overstrike xyz {expected boolean value but got "xyz"}}

} {






    lassign $p testName opt val result
    test $testName "ConfigAttributesObj procedure: $opt" -setup {

	setup
    } -body {
	font create xyz -$opt $val


















    } -returnCodes error -result $result



}

test font-35.1 {GetAttributeInfoObj procedure: one attribute} {


    # (objPtr != NULL)
    setup
    font create xyz -family xyz
    font config xyz -family

} xyz



test font-36.1 {GetAttributeInfoObj procedure: unknown attribute} {


    # (Tcl_GetIndexFromObj() != TCL_OK)
    setup
    font create xyz
    list [catch {font config xyz -xyz} msg] $msg




} {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}}


test font-37.1 {GetAttributeInfoObj procedure: all attributes} {


    # not (objPtr != NULL)



    setup




    font create xyz -family xyz









    font config xyz







} {-family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0}






set i 4

foreach p {
    {font-37.2 family     xyz    xyz}

    {font-37.3 size       20     20}

    {font-37.4 weight     normal normal}
    {font-37.5 slant      italic italic}


    {font-37.6 underline  yes    1}


    {font-37.7 overstrike false  0}
} {
    lassign $p testName opt val expected
    test $testName "GetAttributeInfo procedure: $opt" -setup {

	setup
    } -body {
	font create xyz -$opt $val
	font config xyz -$opt


    } -result $expected
}

# In tests below, one field is set to "xyz" so that font name doesn't
# look like a native X font, so that ParseFontNameObj or TkParseXLFD will
# be called.

setup

test font-38.1 {ParseFontNameObj procedure: begins with -} {
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} $times
test font-38.2 {ParseFontNameObj procedure: begins with -*} {
    lindex [font actual -*-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1
} $times
test font-38.3 {ParseFontNameObj procedure: begins with -, doesn't look like list} {
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} $times
test font-38.4 {ParseFontNameObj procedure: begins with -, looks like list} {
    lindex [font actual {-family times}] 1
} $times
test font-38.5 {ParseFontNameObj procedure: begins with *} {
    lindex [font actual *-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1
} $times
test font-38.6 {ParseFontNameObj procedure: begins with *} {
    font actual *-times-xyz -family
} $times
test font-38.7 {ParseFontNameObj procedure: arguments} noExceed {
    list [catch {font actual "\{xyz"} msg] $msg
} [list 1 "font \"{xyz\" doesn't exist"]
test font-38.8 {ParseFontNameObj procedure: arguments} noExceed {
    list [catch {font actual ""} msg] $msg
} {1 {font "" doesn't exist}}
test font-38.9 {ParseFontNameObj procedure: arguments} {
    list [catch {font actual {times 20 xyz xyz}} msg] $msg
} {1 {unknown font style "xyz"}}
test font-38.10 {ParseFontNameObj procedure: arguments} {
    list [catch {font actual {times xyz xyz}} msg] $msg
} {1 {expected integer but got "xyz"}}
test font-38.12 {ParseFontNameObj procedure: stylelist loop} {unixOrPc failsOnUbuntu} {


    lrange [font actual {times 12 bold italic overstrike underline}] 4 end
} {-weight bold -slant italic -underline 1 -overstrike 1}
test font-38.13 {ParseFontNameObj procedure: stylelist error} {
    list [catch {font actual {times 12 bold xyz}} msg] $msg
} {1 {unknown font style "xyz"}}
test font-38.14 "ParseFontNameObj: options with hyphenated family: bug #2791352" -body {
    font actual {-family sans-serif -size 12 -weight bold -slant roman -underline 0 -overstrike 0}
} -result [font actual {sans-serif 12 bold}]
test font-38.15 "ParseFontNameObj: bug #2791352" -body {
    font actual {-invalidfont 8 bold}
} -returnCodes error -match glob -result {bad option "-invalidfont": *}


test font-39.1 {NewChunk procedure: test realloc} {




    .b.f config -text "xxx\nxxx\txxx\nxxx\t\t\t"



} {}

test font-40.1 {TkFontParseXLFD procedure: initial dash} {
    font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-* -family
} $times
test font-40.2 {TkFontParseXLFD procedure: no initial dash} {
    font actual *-times-*-*-*-*-*-*-*-*-*-*-*-xyz -family
} $times
test font-40.3 {TkFontParseXLFD procedure: not enough fields} {
    font actual -xyz-times-*-*-* -family
} $times
test font-40.4 {TkFontParseXLFD procedure: all fields unspecified} {
    lindex [font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*] 0
} {-family}
test font-40.5 {TkFontParseXLFD procedure: all fields specified} {

    lindex [font actual -foundry-times-weight-slant-setwidth-addstyle-10-10-10-10-spacing-avgwidth-registry-encoding] 1

} $times

test font-41.1 {TkParseXLFD procedure: arguments} {
    # XLFD with bad pointsize: fallback to some system font.
    font actual -*-*-*-*-*-*-xyz-*-*-*-*-*-*-*
    set x {}

} {}

test font-42.1 {TkFontParseXLFD procedure: arguments} {
    # XLFD with bad pixelsize: fallback to some system font.
    font actual -*-*-*-*-*-*-*-xyz-*-*-*-*-*-*
    set x {}
} {}
test font-42.2 {TkFontParseXLFD procedure: pixelsize specified} {
    font metrics -xyz-times-*-*-*-*-12-*-*-*-*-*-*-* -linespace
    set x {}
} {}
test font-42.3 {TkFontParseXLFD procedure: weird pixelsize specified} {
    font metrics {-xyz-times-*-*-*-*-[ 12.0 0 12.0 0]-*-*-*-*-*-*-*} -linespace
    set x {}
} {}
test font-42.4 {TkFontParseXLFD procedure: pointsize specified} {
    font metrics -xyz-times-*-*-*-*-*-120-*-*-*-*-*-* -linespace
    set x {}
} {}
test font-42.5 {TkFontParseXLFD procedure: weird pointsize specified} {
    font metrics {-xyz-times-*-*-*-*-*-[ 12.0 0 12.0 0]-*-*-*-*-*-*} -linespace
    set x {}

} {}

test font-43.1 {FieldSpecified procedure: specified vs. non-specified} {
    font actual -xyz--*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-?-*-*-*-*-*-*-*-*-*-*-*-*
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1

} $times


set oldscale [tk scaling]

tk scaling 0.5
test font-44.1 {TkFontGetPixels: size < 0} failsOnUbuntu {
    font actual {times -12} -size
} 24


test font-44.2 {TkFontGetPoints: size >= 0} {noExceed failsOnUbuntu} {



    font actual {times 12} -size
} 12

tk scaling $oldscale



test font-45.1 {TkFontGetAliasList: no match} {
    font actual {snarky 10} -family
} [font actual {-size 10} -family]
test font-45.3 {TkFontGetAliasList: match} win {
    font actual {times 10} -family
} {Times New Roman}
test font-45.4 {TkFontGetAliasList: match} {unix noExceed} {

    # can fail on Unix systems that have a real "times new roman" font


    font actual {{times new roman} 10} -family
} [font actual {times 10} -family]




test font-46.1 {font actual, with character, no option, no --} \
    -body {
	font actual {times 10} a
    } \
    -match glob \
    -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.2 {font actual, with character introduced by --} \
    -body {
	font actual {times 10} -- -
    } \
    -match glob \
    -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.3 {font actual, with character and option} {
    font actual {times 10} -family a
} [font actual {times 10} -family]

test font-46.4 {font actual, with character, option and --} {
    font actual {times 10} -family -- -
} [font actual {times 10} -family]

test font-46.5 {font actual, too many chars} {
    list [catch {
	font actual {times 10} 123456789012345678901234567890123456789012345678901
    } result] $result
} {1 {expected a single character but got "1234567890123456789012345678901234567..."}}

setup

destroy .b

test font-47.1 {Bug f214b8ad5b} -body {
    interp create one
    interp create two
    load {} Tk one
    load {} Tk two
    one eval menu .menubar
    two eval menu .menubar
    interp delete one
    interp delete two
} -result {}

# cleanup
cleanupTests
return




Deleted tests/fontchooser.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# Test the "tk::fontchooser" command
#
# Copyright © 2008 Pat Thoyts

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

# the following helper functions are related to the functions used
# in winDialog.test where they are used to send messages to the win32
# dialog (hence the wierdness).

proc start {cmd} {
    set ::tk_dialog {}
    set ::iter_after 0
    after 1 $cmd
}
proc then {cmd} {
    set ::command $cmd
    set ::dialogresult {}
    set ::testfont {}
    afterbody
    vwait ::dialogresult
    return $::dialogresult
}
proc afterbody {} {
    if {$::tk_dialog == {}} {
        if {[incr ::iter_after] > 30} {
            set ::dialogresult ">30 iterations waiting for tk_dialog"
            return
        }
        after 150 {afterbody}
        return
    }
    uplevel #0 {set dialogresult [eval $command]}
}
proc Click {button} {
    switch -exact -- $button {
        ok { $::tk_dialog.ok invoke }
        cancel { $::tk_dialog.cancel invoke }
        apply { $::tk_dialog.apply invoke }
        default { return -code error "invalid button name \"$button\"" }
    }
}
proc ApplyFont {font} {
#    puts stderr "apply: $font"
    set ::testfont $font
}

# -------------------------------------------------------------------------

test fontchooser-1.1 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser -z
} -result {unknown or ambiguous subcommand "-z": must be configure, hide, or show}

test fontchooser-1.2 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -z
} -match glob -result {bad option "-z":*}

test fontchooser-1.3 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -parent . -font
} -result {value for "-font" missing}

test fontchooser-1.4 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -parent . -title
} -result {value for "-title" missing}

test fontchooser-1.5 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -parent . -command
} -result {value for "-command" missing}

test fontchooser-1.6 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -title . -parent
} -result {value for "-parent" missing}

test fontchooser-1.7 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -parent abc
} -result {bad window path name "abc"}

test fontchooser-1.8 {tk fontchooser: usage} -returnCodes ok -body {
    tk fontchooser configure -visible
} -result 0

test fontchooser-1.9 {tk fontchooser: usage} -returnCodes error -body {
    tk fontchooser configure -visible 1
} -match glob -result {*}

# -------------------------------------------------------------------------
#
# The remaining tests in this file are only relevant for the script
# implementation. They can be tested by sourcing the script file but
# the Tk tests are run with -singleproc 1 and doing this affects the
# result of later attempts to test the native implementations.
#
testConstraint scriptImpl [llength [info proc ::tk::fontchooser::Configure]]

test fontchooser-2.0 {fontchooser -title} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -title "Hello"
        tk::fontchooser::Show
    }
    then {
        set x [wm title $::tk_dialog]
        Click cancel
    }
    set x
} -result {Hello}

test fontchooser-2.1 {fontchooser -title (cyrillic)} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure \
            -title "Привет"
        tk::fontchooser::Show
    }
    then {
        set x [wm title $::tk_dialog]
        Click cancel
    }
    set x
} -result "Привет"

test fontchooser-3.0 {fontchooser -parent} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -parent .
        tk::fontchooser::Show
    }
    then {
        set x [winfo parent $::tk_dialog]
        Click cancel
    }
    set x
} -result {.}

test fontchooser-3.1 {fontchooser -parent (invalid)} -constraints scriptImpl -body {
    tk::fontchooser::Configure -parent junk
} -returnCodes error -match glob -result {bad window path *}

test fontchooser-4.0 {fontchooser -font} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font courier
        tk::fontchooser::Show
    }
    then {
        Click cancel
    }
    set ::testfont
} -result {}

test fontchooser-4.1 {fontchooser -font} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font courier
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.2 {fontchooser -font} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font TkDefaultFont
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.3 {fontchooser -font} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl failsOnUbuntuNoXft} -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    lrange $::testfont 1 end
} -result {14 bold}

# -------------------------------------------------------------------------

cleanupTests
return

# Local Variables:
# mode: tcl
# indent-tabs-mode: nil
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































Changes to tests/frame.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

























































































































170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555


556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576


577
578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612

613
614
615
616
617

618
619

620


621

622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692

693
694
695


696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887

888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057

1058

1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099

1100
1101
1102
1103

1104
1105
1106

1107
1108
1109
1110
1111

1112
1113
1114
1115
1116


1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137

1138
1139
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196


1197

1198


1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217

1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264

1265


1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311

1312









1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423

1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442

1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461

1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
# This file is a Tcl script to test out the "frame", "labelframe" and
# "toplevel" commands of Tk.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

tcltest::testConstraint x11 [expr {[tk windowingsystem] eq "x11"}]


# eatColors --
# Creates a toplevel window and allocates enough colors in it to use up all
# the slots in an 8-bit colormap.
#
# Arguments:
# w -		Name of toplevel window to create.

proc eatColors {w} {
    catch {destroy $w}
    toplevel $w
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 40} {incr x} {
	    set color [format #%02x%02x%02x [expr {$x*6}] [expr {$y*30}] 0]
	    $w.c create rectangle [expr {10*$x}] [expr {20*$y}] \
		[expr {10*$x + 10}] [expr {20*$y + 20}] -outline {} \
		-fill $color
	}
    }
    update
}

# colorsFree --
#
# Returns 1 if there appear to be free colormap entries in a window, 0
# otherwise.
#
# Arguments:
# w -			Name of window in which to check.
# red, green, blue -	Intensities to use in a trial color allocation
#			to see if there are colormap entries free.

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    lassign [winfo rgb $w [format "#%02x%02x%02x" $red $green $blue]] r g b
    expr {($r/256 == $red) && ($g/256 == $green) && ($b/256 == $blue)}
}

# uniq --
#
# Returns the unique items of a list in the order they first appear.
#
# Arguments:
# list -		The list to uniq-ify.
proc uniq {list} {
    set d {}
    foreach item $list {
	dict set d $item {}
    }
    return [dict keys $d]
}

# optnames --
#
# Returns the option names out of a list of option details.
#
# Arguments:
# options -		The option detail list.
proc optnames {options} {
    lsort [lmap desc $options {lindex $desc 0}]
}

test frame-1.1 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -class NewFrame
    .f configure -class
} -cleanup {
    deleteWindows
} -result {-class class Class Frame NewFrame}

test frame-1.2 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -class NewFrame
    .f configure -class Different
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -class option after widget is created}
test frame-1.3 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -colormap new
    .f configure -colormap
} -cleanup {
    deleteWindows
} -result {-colormap colormap Colormap {} new}

test frame-1.4 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -colormap new
    .f configure -colormap .
} -returnCodes error -cleanup {

    deleteWindows
} -result {can't modify -colormap option after widget is created}
test frame-1.5 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -visual default
    .f configure -visual
} -cleanup {
    deleteWindows
} -result {-visual visual Visual {} default}
test frame-1.6 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -visual default
    .f configure -visual best
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -visual option after widget is created}
test frame-1.7 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -screen bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-screen"}
test frame-1.8 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -container true
} -cleanup {
    deleteWindows
} -result {.f}
test frame-1.9 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -container true
    .f configure -container
} -cleanup {
    deleteWindows

} -result {-container container Container 0 1}
test frame-1.10 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -container bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected boolean value but got "bogus"}
test frame-1.11 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f
    .f configure -container 1
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -container option after widget is created}
test frame-1.12 {frame configuration options} -setup {
    deleteWindows
} -body {
    # Make sure all options can be set to the default value
    frame .f

























































































































    set opts {}
    foreach opt [.f configure] {
        if {[llength $opt] == 5} {
            lappend opts [lindex $opt 0] [lindex $opt 4]
        }
    }
    frame .g {*}$opts
} -cleanup {
    destroy .f .g
    deleteWindows
} -result .g

destroy .f
frame .f
test frame-1.13 {frame configuration options} -body {
    .f configure -background #ff0000
    lindex [.f configure -background] 4
} -cleanup {
    .f configure -background [lindex [.f configure -background] 3]
} -result "#ff0000"
test frame-1.14 {frame configuration options} -body {
    .f configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-1.15 {frame configuration options} -body {
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-1.16 {frame configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.17 {frame configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"
test frame-1.18 {frame configuration options} -body {
    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-1.19 {frame configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-1.20 {frame configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.21 {frame configuration options} -body {
    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-1.22 {frame configuration options} -body {
    .f configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-1.23 {frame configuration options} -body {
    .f configure -height 100
    lindex [.f configure -height] 4
} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100
test frame-1.24 {frame configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-1.25 {frame configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-1.26 {frame configuration options} -body {
    .f configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test frame-1.27 {frame configuration options} -body {
    .f configure -highlightcolor #123456
    lindex [.f configure -highlightcolor] 4
} -cleanup {
    .f configure -highlightcolor [lindex [.f configure -highlightcolor] 3]
} -result "#123456"
test frame-1.28 {frame configuration options} -body {
    .f configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-1.29 {frame configuration options} -body {
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-1.30 {frame configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.31 {frame configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-1.32 {frame configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.33 {frame configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-1.34 {frame configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.35 {frame configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-1.36 {frame configuration options} -returnCodes error -body {
    .f configure -relief badValue
} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test frame-1.37 {frame configuration options} -body {
    .f configure -takefocus {any string}
    lindex [.f configure -takefocus] 4
} -cleanup {
    .f configure -takefocus [lindex [.f configure -takefocus] 3]
} -result {any string}
test frame-1.38 {frame configuration options} -body {
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-1.39 {frame configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .f

test frame-2.1 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -class NewClass
    wm geometry .t +0+0
    .t configure -class
} -cleanup {
    deleteWindows
} -result {-class class Class Toplevel NewClass}
test frame-2.2 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -class NewClass
    wm geometry .t +0+0
    .t configure -class Another
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -class option after widget is created}
test frame-2.3 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -colormap new
    wm geometry .t +0+0
    .t configure -colormap
} -cleanup {
    deleteWindows
} -result {-colormap colormap Colormap {} new}
test frame-2.4 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -colormap new
    wm geometry .t +0+0
    .t configure -colormap .
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -colormap option after widget is created}
test frame-2.5 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    .t configure -container 1
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -container option after widget is created}
test frame-2.6 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    catch {.t configure -container 1}
    .t configure -container
} -cleanup {
    deleteWindows
} -result {-container container Container 0 0}
test frame-2.7 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -colormap bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad window path name "bogus"}
test frame-2.8 {toplevel configuration options} -constraints win -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    .t configure -use 0x44022
} -cleanup {
    deleteWindows
} -returnCodes error -result {window "0x44022" doesn't exist}
test frame-2.9 {toplevel configuration options} -constraints win -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    catch {.t configure -use 0x44022}
    .t configure -use
} -cleanup {
    deleteWindows
} -result {-use use Use {} {}}
test frame-2.10 {toplevel configuration options} -constraints nonwin -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    .t configure -use 0x44022
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't modify -use option after widget is created}
test frame-2.11 {toplevel configuration options} -constraints nonwin -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    catch {.t configure -use 0x44022}
    .t configure -use
} -cleanup {
    deleteWindows
} -result {-use use Use {} {}}
test frame-2.12 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -visual default
    wm geometry .t +0+0
    .t configure -visual
} -cleanup {
    deleteWindows
} -result {-visual visual Visual {} default}
test frame-2.13 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -visual default
    wm geometry .t +0+0
    .t configure -visual best
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -visual option after widget is created}
test frame-2.14 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -visual who_knows?
} -returnCodes error -cleanup {
    deleteWindows
} -result {unknown or ambiguous visual name "who_knows?": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}
set expectedScreen ""
if {[tcltest::testConstraint haveDISPLAY]} {
    set expectedScreen [list -screen screen Screen {} $env(DISPLAY)]
}
test frame-2.15 {toplevel configuration options} -constraints {x11 haveDISPLAY} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -screen $env(DISPLAY)
    wm geometry .t +0+0
    .t configure -screen
} -cleanup {
    deleteWindows
} -result $expectedScreen
test frame-2.16 {toplevel configuration options} -constraints {x11 haveDISPLAY} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -screen $env(DISPLAY)
    wm geometry .t +0+0
    .t configure -screen another
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -screen option after widget is created}
test frame-2.17 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -screen bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {couldn't connect to display "bogus"}
test frame-2.18 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    toplevel .x -container 1 -use [winfo id .t]
} -returnCodes error -cleanup {
    deleteWindows
} -result {windows cannot have both the -use and the -container option set}
test frame-2.19 {toplevel configuration options} -setup {
    deleteWindows
    set opts {}
} -body {
    # Make sure all options can be set to the default value
    toplevel .f
    foreach opt [.f configure] {
        if {[llength $opt] == 5} {
            lappend opts [lindex $opt 0] [lindex $opt 4]
        }
    }
    toplevel .g {*}$opts
} -cleanup {
    destroy .f .g
    deleteWindows
} -result .g

destroy .t
toplevel .t -width 300 -height 150
wm geometry .t +0+0
update

test frame-2.20 {toplevel configuration options} -body {
    .t configure -background #ff0000
    lindex [.t configure -background] 4
} -result "#ff0000"
test frame-2.21 {toplevel configuration options} -body {
    .t configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.22 {toplevel configuration options} -body {
    .t configure -bd 4
    lindex [.t configure -bd] 4
} -result 4
test frame-2.23 {toplevel configuration options} -body {
    .t configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.24 {toplevel configuration options} -body {
    .t configure -bg #00ff00
    lindex [.t configure -bg] 4
} -result "#00ff00"
test frame-2.25 {toplevel configuration options} -body {
    .t configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.26 {toplevel configuration options} -body {
    .t configure -borderwidth 1.3
    lindex [.t configure -borderwidth] 4
} -result 1
test frame-2.27 {toplevel configuration options} -body {
    .t configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.28 {toplevel configuration options} -body {
    .t configure -cursor arrow
    lindex [.t configure -cursor] 4
} -result {arrow}
test frame-2.29 {toplevel configuration options} -body {
    .t configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-2.30 {toplevel configuration options} -body {
    .t configure -height 100
    lindex [.t configure -height] 4
} -result 100
test frame-2.31 {toplevel configuration options} -body {
    .t configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-2.32 {toplevel configuration options} -body {
    .t configure -highlightcolor #123456
    lindex [.t configure -highlightcolor] 4
} -result "#123456"
test frame-2.33 {toplevel configuration options} -body {
    .t configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.34 {toplevel configuration options} -body {
    .t configure -highlightthickness 3
    lindex [.t configure -highlightthickness] 4
} -result 3
test frame-2.35 {toplevel configuration options} -body {
    .t configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.36 {toplevel configuration options} -body {
    .t configure -padx 3
    lindex [.t configure -padx] 4
} -result 3
test frame-2.37 {toplevel configuration options} -body {
    .t configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}


test frame-2.38 {toplevel configuration options} -body {
    .t configure -pady 4
    lindex [.t configure -pady] 4
} -result 4
test frame-2.39 {toplevel configuration options} -body {
    .t configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.40 {toplevel configuration options} -body {
    .t configure -relief ridge
    lindex [.t configure -relief] 4
} -result {ridge}
test frame-2.41 {toplevel configuration options} -returnCodes error -body {
    .t configure -relief badValue
} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test frame-2.42 {toplevel configuration options} -body {
    .t configure -width 32
    lindex [.t configure -width] 4
} -result 32
test frame-2.43 {toplevel configuration options} -body {
    .t configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}


destroy .t


test frame-3.1 {TkCreateFrame procedure} -returnCodes error -body {
    frame
} -result {wrong # args: should be "frame pathName ?-option value ...?"}
test frame-3.2 {TkCreateFrame procedure} -setup {
    deleteWindows
    frame .f
} -body {
    .f configure -class
} -cleanup {
    deleteWindows
} -result {-class class Class Frame Frame}
test frame-3.3 {TkCreateFrame procedure} -setup {
    deleteWindows
    toplevel .t
    wm geometry .t +0+0
} -body {
    .t configure -class
} -cleanup {
    deleteWindows
} -result {-class class Class Toplevel Toplevel}
test frame-3.4 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 350 -class NewClass -bg black -visual default -height 90
    wm geometry .t +0+0
    update
    list [lindex [.t configure -width] 4] \
	    [lindex [.t configure -background] 4] \
	    [lindex [.t configure -height] 4]
} -cleanup {
    deleteWindows
} -result {350 black 90}

# Be sure that the -class, -colormap, and -visual options are processed
# before configuring the widget.

test frame-3.5 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    option add *NewFrame.background #123456
    frame .f -class NewFrame

    lindex [.f configure -background] 4
} -cleanup {

    deleteWindows


    option clear

} -result {#123456}
test frame-3.7 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    option add *NewFrame.background #332211
    option add *f.class NewFrame
    frame .f
    list [lindex [.f configure -class] 4] [lindex [.f configure -background] 4]
} -cleanup {
    deleteWindows
    option clear

} -result {NewFrame #332211}
test frame-3.8 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    option add *Silly.background #122334
    option add *f.Class Silly
    frame .f
    list [lindex [.f configure -class] 4] [lindex [.f configure -background] 4]
} -cleanup {
    deleteWindows
    option clear

} -result {Silly #122334}
test frame-3.9 {TkCreateFrame procedure, -use option} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green
    tkwait visibility .x
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    # This call to update idletasks was added to prevent a crash that was
    # observed on OSX 10.12 (Sierra) only.  Any change, such as using the
    # Development version to make debugging symbols available, adding a print
    # statement, or calling update idletasks here, would make the test pass
    # with no segfault.
    update idletasks
    deleteWindows
} -result {0 0 140 300}
test frame-3.10 {TkCreateFrame procedure, -use option} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    option add *x.use [winfo id .t]
    toplevel .x -width 140 -height 300 -bg green
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	tkwait visibility .x
	update
    }
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    destroy .t
    option clear
} -result {0 0 140 300}

# The tests below require specific display characteristics (i.e. that they are
# run on a pseudocolor display of depth 8).  Even so, they are non-portable:
# some machines don't seem to ever run out of colors.


if {[testConstraint defaultPseudocolor8]} {
    eatColors .t1
}
test frame-3.11 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200 -bg #475601
    wm geometry .t +0+0
    update
    colorsFree .t
} -cleanup {
    destroy .t
} -result 0
test frame-3.12 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200 -bg #475601 -colormap new
    wm geometry .t +0+0
    update
    colorsFree .t
} -cleanup {
    destroy .t
} -result 1
test frame-3.13 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    option add *t.class Toplevel2
    option add *Toplevel2.colormap new
    toplevel .t -width 300 -height 200 -bg #475601
    wm geometry .t +0+0
    update
    option clear
    colorsFree .t
} -cleanup {
    destroy .t
} -result 1
test frame-3.14 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    option add *t.class Toplevel3
    option add *Toplevel3.Colormap new
    toplevel .t -width 300 -height 200 -bg #475601 -colormap new
    wm geometry .t +0+0
    update
    option clear
    colorsFree .t
} -cleanup {
    destroy .t
} -result 1
test frame-3.15 {TkCreateFrame procedure, -use and -colormap} -constraints {
    defaultPseudocolor8 unix nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green -colormap new
    tkwait visibility .x
    list [colorsFree .t] [colorsFree .x]
} -cleanup {
    destroy .t
} -result {0 1}
test frame-3.16 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200 -bg #475601 -visual default
    wm geometry .t +0+0
    update
    colorsFree .t
} -cleanup {
    destroy .t
} -result 0
test frame-3.17 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200 -bg #475601 -visual default \
	    -colormap new
    wm geometry .t +0+0
    update
    colorsFree .t
} -cleanup {
    destroy .t
} -result 1
test frame-3.18 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 haveGrayscale8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -visual {grayscale 8} -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    colorsFree .t 131 131 131
} -cleanup {
    destroy .t
} -result 1
test frame-3.19 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 haveGrayscale8 nonPortable
} -setup {
    destroy .t
} -body {
    option add *t.class T4
    option add *T4.visual {grayscale 8}
    toplevel .t -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    option clear
    list [colorsFree .t 131 131 131] [lindex [.t configure -visual] 4]
} -cleanup {
    destroy .t
} -result {1 {grayscale 8}}
test frame-3.20 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 haveGrayscale8 nonPortable
} -setup {
    destroy .t
} -body {
    option add *t.class T5
    option add *T5.Visual {grayscale 8}
    toplevel .t -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    option clear
    list [colorsFree .t 131 131 131] [lindex [.t configure -visual] 4]
} -cleanup {
    destroy .t
} -result {1 {grayscale 8}}
test frame-3.21 {TkCreateFrame procedure} -constraints {
    defaultPseudocolor8 haveGrayscale8 nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -visual {grayscale 8} -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    colorsFree .t 131 131 131
} -cleanup {
    destroy .t
} -result 1
if {[testConstraint defaultPseudocolor8]} {
    destroy .t1
}
test frame-3.22 {TkCreateFrame procedure, default dimensions} -setup {
    deleteWindows
} -body {
    toplevel .t
    wm geometry .t +0+0
    update
    set result "[winfo reqwidth .t] [winfo reqheight .t]"
    frame .t.f -bg red
    pack .t.f
    update
    lappend result [winfo reqwidth .t.f] [winfo reqheight .t.f]
} -cleanup {
    deleteWindows
} -result {200 200 1 1}
test frame-3.23 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    frame .f -gorp glob
} -returnCodes error -result {unknown option "-gorp"}
test frame-3.24 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 300 -height 200 -colormap new -bogus option
    wm geometry .t +0+0
} -returnCodes error -result {unknown option "-bogus"}

test frame-4.1 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    catch {frame .f -gorp glob}
    winfo exists .f
} -result 0
test frame-4.2 {TkCreateFrame procedure} -setup {
    deleteWindows
} -body {
    list [frame .f -width 200 -height 100] [winfo exists .f]
} -cleanup {
    deleteWindows
} -result {.f 1}


frame .f -highlightcolor black
test frame-5.1 {FrameWidgetCommand procedure} -body {
    .f
} -returnCodes error -result {wrong # args: should be ".f option ?arg ...?"}
test frame-5.2 {FrameWidgetCommand procedure, cget option} -body {
    .f cget
} -returnCodes error -result {wrong # args: should be ".f cget option"}
test frame-5.3 {FrameWidgetCommand procedure, cget option} -body {
    .f cget a b
} -returnCodes error -result {wrong # args: should be ".f cget option"}
test frame-5.4 {FrameWidgetCommand procedure, cget option} -body {
    .f cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test frame-5.5 {FrameWidgetCommand procedure, cget option} -body {
    .f cget -highlightcolor
} -result {black}
test frame-5.6 {FrameWidgetCommand procedure, cget option} -body {
    .f cget -screen
} -returnCodes error -result {unknown option "-screen"}
test frame-5.7 {FrameWidgetCommand procedure, cget option} -setup {
    destroy .t
} -body {
    toplevel .t
    .t cget -screen
} -cleanup {
    destroy .t
} -returnCodes ok -match glob -result *
test frame-5.8 {FrameWidgetCommand procedure, configure option} -body {
    optnames [.f configure]
} -result {-background -backgroundimage -bd -bg -bgimg -borderwidth -class -colormap -container -cursor -height -highlightbackground -highlightcolor -highlightthickness -padx -pady -relief -takefocus -tile -visual -width}

test frame-5.9 {FrameWidgetCommand procedure, configure option} -body {
    .f configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test frame-5.10 {FrameWidgetCommand procedure, configure option} -body {
    .f configure -gorp bogus
} -returnCodes error -result {unknown option "-gorp"}
test frame-5.11 {FrameWidgetCommand procedure, configure option} -body {
    .f configure -width 200 -height
} -returnCodes error -result {value for "-height" missing}
test frame-5.12 {FrameWidgetCommand procedure} -body {
    .f swizzle
} -returnCodes error -result {bad option "swizzle": must be cget or configure}
test frame-5.13 {FrameWidgetCommand procedure, configure option} -body {
    optnames [. configure]
} -result {-background -backgroundimage -bd -bg -bgimg -borderwidth -class -colormap -container -cursor -height -highlightbackground -highlightcolor -highlightthickness -menu -padx -pady -relief -screen -takefocus -tile -use -visual -width}
destroy .f

test frame-6.1 {ConfigureFrame procedure} -setup {
    deleteWindows
} -body {
    frame .f -width 150
    list [winfo reqwidth .f] [winfo reqheight .f]
} -cleanup {
    deleteWindows
} -result {150 1}
test frame-6.2 {ConfigureFrame procedure} -setup {
    deleteWindows
} -body {
    frame .f -height 97
    list [winfo reqwidth .f] [winfo reqheight .f]
} -cleanup {
    deleteWindows
} -result {1 97}
test frame-6.3 {ConfigureFrame procedure} -setup {
    deleteWindows
} -body {
    frame .f
    set result {}
    lappend result [winfo reqwidth .f] [winfo reqheight .f]
    .f configure -width 100 -height 180
    lappend result [winfo reqwidth .f] [winfo reqheight .f]
    .f configure -width 0 -height 0
    lappend result [winfo reqwidth .f] [winfo reqheight .f]
} -cleanup {
    deleteWindows
} -result {1 1 100 180 100 180}

test frame-7.1 {FrameEventProc procedure} -setup {
    deleteWindows
} -body {
    frame .frame2
    set result [info commands .frame2]
    destroy .frame2
    lappend result [info commands .frame2]
} -result {.frame2 {}}
test frame-7.2 {FrameEventProc procedure} -setup {
    deleteWindows
    set x {}
} -body {
    frame .f1 -bg #543210
    rename .f1 .f2

    lappend x [winfo children .]
    lappend x [.f2 cget -bg]
    destroy .f1
    lappend x [info command .f*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {.f1 #543210 {} {}}

test frame-8.1 {FrameCmdDeletedProc procedure} -setup {
    deleteWindows
} -body {
    frame .f1
    rename .f1 {}
    list [info command .f*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}
test frame-8.2 {FrameCmdDeletedProc procedure} -setup {
    deleteWindows
} -body {
    toplevel .f1 -menu .m
    wm geometry .f1 +0+0
    update
    rename .f1 {}
    update
    list [info command .f*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}
#
# This one fails with the dash-patch!!!! Still don't know why  :-(
#
#test frame-8.3 {FrameCmdDeletedProc procedure} -setup {
#    deleteWindows
#} -body {
#    toplevel .f1 -menu .m
#    wm geometry .f1 +0+0
#    menu .m
#    update
#    rename .f1 {}
#    update
#    list [info command .f*] [winfo children .]
#} -cleanup {
#    deleteWindows
#} -result {{} .m}

test frame-9.1 {MapFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    set result [winfo ismapped .t]
    update idletasks
    lappend result [winfo ismapped .t]
} -cleanup {
    deleteWindows
} -result {0 1}
test frame-9.2 {MapFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    destroy .t
    update
    winfo exists .t
} -result 0
test frame-9.3 {MapFrame procedure, window deleted while mapping} -setup {
    deleteWindows
} -body {
    toplevel .t2 -width 200 -height 200
    wm geometry .t2 +0+0
    tkwait visibility .t2

    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    frame .t2.f -width 50 -height 50
    bind .t2.f <Configure> {destroy .t}
    pack .t2.f -side top
    update idletasks
    winfo exists .t

} -cleanup {

    deleteWindows
} -result 0

test frame-10.1 {frame widget vs hidden commands} -setup {
    deleteWindows
} -body {
    frame .t
    interp hide {} .t
    destroy .t
    list [winfo children .] [lsort [interp hidden]]
} -result [list {} [lsort [interp hidden]]]

test frame-11.1 {TkInstallFrameMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label foo
    toplevel .t -menu .m1
} -cleanup {
    deleteWindows
} -result {.t}
test frame-11.2 {TkInstallFrameMenu - frame renamed} -setup {
    deleteWindows
    catch {rename foo {}}
} -body {
    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label foo
    toplevel .t
    rename .t foo
} -cleanup {
    deleteWindows
} -result {}

test frame-12.1 {FrameWorldChanged procedure} -setup {
    deleteWindows
} -body {
    # Test -bd -padx and -pady

    frame .f -borderwidth 2 -padx 3 -pady 4
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1
    update

    list [winfo x .f.f] [winfo y .f.f] [winfo width .f.f] [winfo height .f.f]
} -cleanup {
    deleteWindows

} -result {5 6 30 28}
test frame-12.2 {FrameWorldChanged procedure} -setup {
    deleteWindows
} -body {
    # Test all -labelanchor positions

    set font {helvetica 12}
    labelframe .f -highlightthickness 1 -bd 3 -padx 1 -pady 2 -font $font \
            -text "Mupp"
    set fh [expr {max([font metrics $font -linespace] + 2 - 3, 0)}]
    set fw [expr {max([font measure $font "Mupp"] + 2 - 3, 0)}]


    place .f -x 0 -y 0 -width 100 -height 100
    pack [frame .f.f] -fill both -expand 1

    set result {}
    foreach lp {nw n ne en e es se s sw ws w wn} {
        .f configure -labelanchor $lp
        update
        set expx 5
        set expy 6
        set expw 90
        set exph 88
        switch -glob $lp {
            n* {incr expy $fh ; incr exph -$fh}
            s* {incr exph -$fh}
            w* {incr expx $fw ; incr expw -$fw}
            e* {incr expw -$fw}
        }
        lappend result [expr {
	    [winfo x .f.f] == $expx && [winfo y .f.f] == $expy &&
	    [winfo width .f.f] == $expw && [winfo height .f.f] == $exph
	}]
    }

    return $result
} -cleanup {
    deleteWindows
} -result {1 1 1 1 1 1 1 1 1 1 1 1}
test frame-12.3 {FrameWorldChanged procedure} -setup {
    deleteWindows
	update idletasks
} -body {
    # Check reaction on font change

    font create myfont -family courier -size 10
    labelframe .f -font myfont -text Mupp
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    set h1 [font metrics myfont -linespace]
    set y1 [winfo y .f.f]
    font configure myfont -size 20
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    set h2 [font metrics myfont -linespace]
    set y2 [winfo y .f.f]
    expr {($h2 - $h1) - ($y2 - $y1)}
} -cleanup {
    deleteWindows
    font delete myfont
} -result 0

test frame-13.1 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f -class NewFrame
    .f configure -class
} -cleanup {
    deleteWindows
} -result {-class class Class Labelframe NewFrame}
test frame-13.2 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f -class NewFrame
    .f configure -class Different
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -class option after widget is created}
test frame-13.3 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f -colormap new
} -cleanup {
    deleteWindows
} -result {.f}
test frame-13.4 {labelframe configuration options} -setup {
    deleteWindows


} -body {

    labelframe .f -visual default


} -cleanup {
    deleteWindows
} -result {.f}
test frame-13.5 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f -screen bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-screen"}
test frame-13.6 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f -container true
} -cleanup {
    deleteWindows
} -result {.f}
test frame-13.7 {labelframe configuration options} -setup {
    deleteWindows

} -body {

    labelframe .f -container true
    .f configure -container
} -cleanup {
    deleteWindows
} -result {-container container Container 0 1}
test frame-13.8 {labelframe configuration options} -setup {
    deleteWindows
} -body {
     labelframe .f -container bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected boolean value but got "bogus"}
test frame-13.9 {labelframe configuration options} -setup {
    deleteWindows
} -body {
    labelframe .f
    .f configure -container 1
} -returnCodes error -cleanup {
    deleteWindows
} -result {can't modify -container option after widget is created}
destroy .f
labelframe .f
test frame-13.10 {labelframe configuration options} -body {
    .f configure -background #ff0000
    lindex [.f configure -background] 4
} -cleanup {
    .f configure -background [lindex [.f configure -background] 3]
} -result "#ff0000"

test frame-13.11 {labelframe configuration options} -body {
    .f configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.12 {labelframe configuration options} -body {
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-13.13 {labelframe configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.14 {labelframe configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"

test frame-13.15 {labelframe configuration options} -body {


    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.16 {labelframe configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-13.17 {labelframe configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.18 {labelframe configuration options} -body {

    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-13.19 {labelframe configuration options} -body {
    .f configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-13.20 {labelframe configuration options} -body {
    .f configure -fg #0000ff
    lindex [.f configure -fg] 4
} -cleanup {
    .f configure -fg [lindex [.f configure -fg] 3]
} -result "#0000ff"
test frame-13.21 {labelframe configuration options} -body {
    .f configure -fg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.22 {labelframe configuration options} -body {
    .f configure -font {courier 8}
    lindex [.f configure -font] 4
} -cleanup {
    .f configure -font [lindex [.f configure -font] 3]
} -result {courier 8}
test frame-13.23 {labelframe configuration options} -body {
    .f configure -foreground #ff0000
    lindex [.f configure -foreground] 4
} -cleanup {
    .f configure -foreground [lindex [.f configure -foreground] 3]
} -result "#ff0000"
test frame-13.24 {labelframe configuration options} -body {
    .f configure -foreground non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.25 {labelframe configuration options} -body {
    .f configure -height 100

    lindex [.f configure -height] 4









} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100

test frame-13.26 {labelframe configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-13.27 {labelframe configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-13.28 {labelframe configuration options} -body {
    .f configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test frame-13.29 {labelframe configuration options} -body {
    .f configure -highlightcolor #123456
    lindex [.f configure -highlightcolor] 4
} -cleanup {
    .f configure -highlightcolor [lindex [.f configure -highlightcolor] 3]
} -result "#123456"
test frame-13.30 {labelframe configuration options} -body {
    .f configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.31 {labelframe configuration options} -body {
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-13.32 {labelframe configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.33 {labelframe configuration options} -body {
    .f configure -labelanchor se
    lindex [.f configure -labelanchor] 4
} -cleanup {
    .f configure -labelanchor [lindex [.f configure -labelanchor] 3]
} -result {se}
test frame-13.34 {labelframe configuration options} -returnCodes error -body {
    .f configure -labelanchor badValue
} -result {bad labelanchor "badValue": must be e, en, es, n, ne, nw, s, se, sw, w, wn, or ws}
test frame-13.35 {labelframe configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-13.36 {labelframe configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.37 {labelframe configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-13.38 {labelframe configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.39 {labelframe configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-13.40 {labelframe configuration options} -returnCodes error -body {
    .f configure -relief badValue
} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test frame-13.41 {labelframe configuration options} -body {
    .f configure -takefocus {any string}
    lindex [.f configure -takefocus] 4
} -cleanup {
    .f configure -takefocus [lindex [.f configure -takefocus] 3]
} -result {any string}
test frame-13.42 {labelframe configuration options} -body {
    .f configure -text {any string}

    lindex [.f configure -text] 4
} -cleanup {
    .f configure -text [lindex [.f configure -text] 3]
} -result {any string}
test frame-13.43 {labelframe configuration options} -body {
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-13.44 {labelframe configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}

destroy .f

test frame-14.1 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test that label is moved in stacking order

    label .l -text Mupp -font {helvetica 8}
    labelframe .f -labelwidget .l
    pack .f
    frame .f.f -width 50 -height 50
    pack .f.f
    update
    list [winfo children .] [winfo width .f] \
        [expr {[winfo height .f] - [winfo height .l]}]
} -cleanup {
    deleteWindows
} -result {{.f .l} 54 52}
test frame-14.2 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test the labelframe's reaction if the label is destroyed

    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set res [list [.f cget -labelwidget]]
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    destroy .l
    lappend res [.f cget -labelwidget]
    update
    lappend res [expr {[winfo width .f] - [winfo width .f.l]}]
} -cleanup {
    deleteWindows
} -result {.l 12 {} 4}
test frame-14.3 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test the labelframe's reaction if the label is stolen

    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set res [list [.f cget -labelwidget]]
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    pack .l
    lappend res [.f cget -labelwidget]
    update
    lappend res [expr {[winfo width .f] - [winfo width .f.l]}]
} -cleanup {
    deleteWindows
} -result {.l 12 {} 4}
test frame-14.4 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test the label's reaction if the labelframe is destroyed

    label .l -text Mupp
    labelframe .f -labelwidget .l
    pack .f
    update
    set res [list [winfo manager .l]]
    destroy .f
    lappend res [winfo manager .l]
} -cleanup {
    deleteWindows
} -result {labelframe {}}
test frame-14.5 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test that the labelframe reacts on changes in label

    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set first [winfo width .f]
    set res [expr {[winfo width .f] - [winfo width .l]}]
    .l configure -text Shorter
    update
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    lappend res [expr {[winfo width .f] < $first}]
    .l configure -text Alotlongerthananytimebefore
    update
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    lappend res [expr {[winfo width .f] > $first}]
} -cleanup {
    deleteWindows
} -result {12 12 1 12 1}
test frame-14.6 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Destroying a labelframe with a child label caused a crash when not
    # handling mapping of the label correctly.
    # This test does not test anything directly, it's just ment to catch if
    # the same mistake is made again.

    labelframe .f
    pack .f
    label .f.l -text Mupp
    .f configure -labelwidget .f.l
    update
} -cleanup {
    deleteWindows
} -result {}

test frame-15.1 {TIP 262: frame background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    frame .f -width 100 -height 100
    pack .f
    list [image inuse gorp] [.f configure -backgroundimage gorp;update] \
	[image inuse gorp] [winfo width .f] [winfo height .f]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {0 {} 1 100 100}
test frame-15.2 {TIP 262: frame background images} -setup {
    deleteWindows
    catch {rename gorp ""}
} -body {
    frame .f -width 100 -height 100
    pack .f
    update
    .f configure -backgroundimage gorp
} -returnCodes error -cleanup {
    deleteWindows
} -result {image "gorp" doesn't exist}
test frame-15.3 {TIP 262: frame background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    frame .f -width 100 -height 100 -backgroundimage gorp
    pack .f
    .f configure -tile yes
    update
    list [.f cget -bgimg] [.f cget -tile]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {gorp 1}
test frame-15.4 {TIP 262: frame background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    frame .f -width 100 -height 100 -backgroundimage gorp
    pack .f
    .f configure -tile yes
    update
    gorp put red -to 15 15 20 20
    update
    list [.f cget -bgimg] [.f cget -tile]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {gorp 1}
test frame-15.5 {TIP 262: frame background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
    set result {}
} -body {
    frame .f -width 100 -height 100 -backgroundimage gorp
    pack .f
    .f configure -tile yes
    update
    image delete gorp
    update
    set result [list [.f cget -bgimg] [.f cget -tile]]
    image create photo gorp -width 250 -height 250
    update
    lappend result [.f cget -backgroundimage]
} -cleanup {
    catch {image delete gorp}
    deleteWindows
} -result {gorp 1 gorp}
test frame-15.6 {TIP 262: frame background images} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 100 -height 100 -bgimg gorp]
    update idletasks; update
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15}}
test frame-15.6a {TIP 262: frame background images (offsets)} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 10 -height 10 -bgimg gorp]
    update idletasks; update
    # On MacOS must wait for the test image display procedure to run.
    set timer [after 300 {lappend result "timedout"}]
    while {"timedout" ni $result &&
	   "gorp display 10 2 10 10" ni $result} {
       vwait result
    }
    after cancel $timer
    update idletasks; update
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 10 2 10 10}}
test frame-15.7 {TIP 262: frame background images} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 50 -height 25 -bgimg gorp -tile 1]
    update idletasks; update
    # On MacOS must wait for the test image display procedure to run.
    set timer [after 300 {lappend result "timedout"}]
    while {"timedout" ni $result &&
	   "gorp display 0 0 20 10" ni $result} {
	vwait result
    }
    after cancel $timer
    if {[lindex $result end] eq "timedout"} {
	return [lreplace $result end end]
    }
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15} {gorp display 0 0 30 10} {gorp display 0 0 20 15} {gorp display 0 0 20 10}}
test frame-15.7a {TIP 262: frame background images (offsets)} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 50 -height 25 -bgimg gorp -tile 1 -highlightthick 1]
    update idletasks; update
    # On MacOS must wait for the test image display procedure to run.
    set timer [after 300 {lappend result "timedout"}]
    while {"timedout" ni $result &&
	   "gorp display 0 0 18 8" ni $result} {
	vwait result
   }
    after cancel $timer
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15} {gorp display 0 0 30 8} {gorp display 0 0 18 15} {gorp display 0 0 18 8}}
test frame-15.7b {TIP 262: frame background images (offsets)} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 50 -height 25 -bgimg gorp -tile 1 -bd 2]
    update idletasks; update
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15} {gorp display 0 0 30 6} {gorp display 0 0 16 15} {gorp display 0 0 16 6}}
test frame-15.7c {TIP 262: frame background images (offsets)} -setup {
    deleteWindows
    set result {}
    . configure -width 200 -height 200
} -constraints testImageType -body {
    image create test gorp -variable result
    pack [frame .f -width 50 -height 25 -bgimg gorp -tile 1 -bd 2 -highlightthick 1]
    update idletasks; update
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15} {gorp display 0 0 30 4} {gorp display 0 0 14 15} {gorp display 0 0 14 4}}
test frame-15.8 {TIP 262: toplevel background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    toplevel .t -width 100 -height 100
    update
    # Used to verify that setting a background image doesn't change the widget size
    set w [winfo width .t]
    set h [winfo height .t]
    list [image inuse gorp] [.t configure -backgroundimage gorp;update] \
	[image inuse gorp] \
	[expr {$w-[winfo width .t]}] [expr {$h-[winfo height .t]}]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {0 {} 1 0 0}
test frame-15.9 {TIP 262: toplevel background images} -setup {
    deleteWindows
    catch {rename gorp ""}
} -body {
    toplevel .t -width 100 -height 100
    update
    .t configure -backgroundimage gorp
} -returnCodes error -cleanup {
    deleteWindows
} -result {image "gorp" doesn't exist}
test frame-15.10 {TIP 262: toplevel background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    toplevel .t -width 100 -height 100 -backgroundimage gorp -tile yes
    update
    list [.t cget -bgimg] [.t cget -tile]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {gorp 1}
test frame-15.11 {TIP 262: toplevel background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
} -body {
    toplevel .t -width 100 -height 100 -backgroundimage gorp -tile yes
    update
    gorp put red -to 15 15 20 20
    update
    list [.t cget -bgimg] [.t cget -tile]
} -cleanup {
    image delete gorp
    deleteWindows
} -result {gorp 1}
test frame-15.12 {TIP 262: toplevel background images} -setup {
    deleteWindows
    image create photo gorp -width 10 -height 10
    gorp put black -to 2 2 7 7
    set result {}
} -body {
    toplevel .t -width 100 -height 100 -backgroundimage gorp -tile yes
    update
    image delete gorp
    update
    set result [list [.t cget -bgimg] [.t cget -tile]]
    image create photo gorp -width 250 -height 250
    update
    lappend result [.t cget -backgroundimage]
} -cleanup {
    catch {image delete gorp}
    deleteWindows
} -result {gorp 1 gorp}
test frame-15.13 {TIP 262: toplevel background images} -setup {
    deleteWindows
    set result {}
} -constraints testImageType -body {
    image create test gorp -variable result
    toplevel .t -width 100 -height 100 -bgimg gorp
    wm overrideredirect .t 1;	# Reduce trouble from window managers
    update idletasks; update
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15}}
test frame-15.14 {TIP 262: toplevel background images} -setup {
    deleteWindows
    set result {}
} -constraints testImageType -body {
    image create test gorp -variable result
    toplevel .t -width 50 -height 25 -bgimg gorp -tile 1
    wm overrideredirect .t 1;	# Reduce trouble from window managers
    update idletasks; update
    # On MacOS must wait for the test image display procedure to run.
    set timer [after 300 {lappend result "timedout"}]
    while {"timedout" ni $result &&
	   "gorp display 0 0 20 10" ni $result} {
	vwait result
   }
    after cancel $timer
    return [uniq $result]
} -cleanup {
    deleteWindows
    catch {image delete gorp}
} -result {{gorp get} {gorp display 0 0 30 15} {gorp display 0 0 30 10} {gorp display 0 0 20 15} {gorp display 0 0 20 10}}

# cleanup
deleteWindows
apply {cmds {foreach cmd $cmds {rename $cmd {}}}} {
    eatColors colorsFree uniq optnames
}

cleanupTests
return

# Local Variables:
# mode: tcl
# End:
|
|


|
|
|



<
|


|
>


|
|












|
|
|
|







|
|







|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<

|
|
<
<

|
<
<
|
>
|
<
<
<
<
<
<
<
<
<
<

|
<
<
|
>
|
<
<
|
|
<
>
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
|
<
<
<
<
<
<
<
|
<
|
>
|
|
<
<
|
<
<
|
|
<
<

|
|
|
|
|
<
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



>
|
|
<
<
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
|
<
<
<
|
|
<
<
<
<
<
|
|
>
>
|
|
|
|
<
<
<
<
<
|
<
<
|
<
|
|
<
<
<
<
|
>
>
|
|
>
|

|

|




|


|





|

|
<
|






<
<
|
>


>
|
<
|


>

|
>
|
>
>

>
|
|
<
|



<
<
<

>
|
|
<
|



<
<
<

>
|
|
<
|
|
|








<
<
<
<
<
<
|

|
<
|
|
|


<
<
<
<
<


<
<
<
|
<
<







>
|
|
|
>
>



|
<
<
|
<




|
<
<
|
<
<
|
<




|
<
<
|
<
<
|
<







|
<
<
|
<
<
|
<







|
<
<
|
<
|
|
|








|
<
<
|
<




|
<
<
|
<
<
|
<





|
<
<
|
<
<
|
<




|
<
<
|
<
<
|
<







<
<
|
|
<
<
|
|







<
<
|
|
<
<
|
|




|
<
<




|










|


|




|





|
<
|


|
|
<
|

<
<
|

>

|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
<

|
|
|
<
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|

|
<
|


<
<
|
|
<
|


<
<
|
|
<
|







<
<
|

|
<
<




|
|

<
<


>




<
<
|

|

<



<
<
|
|

<






<
<
|



|
|
<






|
|
|
|

|
<
|





<
<
|
|
<
|





|
|
<
<



>







>
|
>
|
<

|
<
|



|
|

|
<
|




|
<
<
|
|
|

<





|
<
<
|

|
<
<

>




>
|
<
|
>
|
|
<
<

>



|
|
>
>


>














|
|
|
<

>
|
<
<
|
|
<
<
<

>




<
<
<
|
<



<
<
<
|
<


<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
|
>
|
>
>
|
<
<
|
<
<
|
|
|
<
|
<
<
|
|
|
<
|
<
>
|
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
>
|
<
<
|
<
<
|
<
<
|
<
<
|
|
|
<
<
|
>
|
>
>
|
|
<
<
<
<
<
<
<
<
|
<
>
|
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
>
|
>
>
>
>
>
>
>
>
>
|
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
|
<
<
<
<
<
<
<
<
<
>


|
<
<

>






|
|
|
|
|
|
<
<

>












|
|
|
|
<
<

>












|
|
|
|
<
<

>







|
|
|
|
<
<

>
















|
|
|
|
<
<
|
|
|
|
>





<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<

<
<
<
<
<



<
<
<
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


53













54








55
56
57


58
59


60
61
62










63
64


65
66
67


68
69

70




71





72










73


74
75


76







77

78
79
80
81


82


83
84


85
86
87
88
89
90


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221


222































































































































































































































































223



















































224
225
226
227
228
229
230




231






232

233




234






235






236






237

238




239

240



241
242





243
244
245
246
247
248
249
250





251


252

253
254




255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288


289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312



313
314
315
316

317
318
319
320



321
322
323
324

325
326
327
328
329
330
331
332
333
334
335






336
337
338

339
340
341
342
343





344
345



346


347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363


364

365
366
367
368
369


370


371

372
373
374
375
376


377


378

379
380
381
382
383
384
385
386


387


388

389
390
391
392
393
394
395
396


397

398
399
400
401
402
403
404
405
406
407
408
409


410

411
412
413
414
415


416


417

418
419
420
421
422
423


424


425

426
427
428
429
430


431


432

433
434
435
436
437
438
439


440
441


442
443
444
445
446
447
448
449
450


451
452


453
454
455
456
457
458
459


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494

495
496


497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524

525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

542
543
544

545
546
547


548
549

550
551
552


553
554

555
556
557
558
559
560
561
562


563
564
565


566
567
568
569
570
571
572


573
574
575
576
577
578
579


580
581
582
583

584
585
586


587
588
589

590
591
592
593
594
595


596
597
598
599
600
601

602
603
604
605
606
607
608
609
610
611
612
613

614
615
616
617
618
619


620
621

622
623
624
625
626
627
628
629


630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646

647
648
649
650
651
652
653
654

655
656
657
658
659
660


661
662
663
664

665
666
667
668
669
670


671
672
673


674
675
676
677
678
679
680
681

682
683
684
685


686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

715
716
717


718
719



720
721
722
723
724
725



726

727
728
729



730

731
732





733
























734
735
736
737
738
739
740
741
742


743


744
745
746

747


748
749
750

751

752
753
754
755
756


















757






758
759
760


761


762


763


764
765
766


767
768
769
770
771
772
773








774

775
776





777
778

779






780

781





782






783

784
785
786
787
788
789
790
791
792
793
794
795
796


797
798






























799
800


801





802




803

804
805






806

















807
808


809









810
811
812
813


814
815
816
817
818
819
820
821
822
823
824
825
826
827


828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845


846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863


864
865
866
867
868
869
870
871
872
873
874
875
876


877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898


899
900
901
902
903
904
905
906
907
908










909





























































































910











































911




912

































913












914













































































915







916





917
918
919



# This file is a Tcl script to test out the "frame" and "toplevel"
# commands of Tk.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint notWinCI [expr {
    ($::tcl_platform(platform) ne "windows") || ![info exists ::env(CI)]}]

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:
# w -		Name of toplevel window to create.

proc eatColors {w} {
    catch {destroy $w}
    toplevel $w
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 40} {incr x} {
	    set color [format #%02x%02x%02x [expr $x*6] [expr $y*30] 0]
	    $w.c create rectangle [expr 10*$x] [expr 20*$y] \
		    [expr 10*$x + 10] [expr 20*$y + 20] -outline {} \
		    -fill $color
	}
    }
    update
}

# colorsFree --
#
# Returns 1 if there appear to be free colormap entries in a window,
# 0 otherwise.
#
# Arguments:
# w -			Name of window in which to check.
# red, green, blue -	Intensities to use in a trial color allocation
#			to see if there are colormap entries free.

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]


    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \













	    && ([lindex $vals 2]/256 == $blue)








}

test frame-1.1 {frame configuration options} {


    frame .f -class NewFrame
    list [.f configure -class] [catch {.f configure -class Different} msg] $msg


} {{-class class Class Frame NewFrame} 1 {can't modify -class option after widget is created}}
catch {destroy .f}
test frame-1.2 {frame configuration options} {










    frame .f -colormap new
    list [.f configure -colormap] [catch {.f configure -colormap .} msg] $msg


} {{-colormap colormap Colormap {} new} 1 {can't modify -colormap option after widget is created}}
catch {destroy .f}
test frame-1.3 {frame configuration options} {


    frame .f -visual default
    list [.f configure -visual] [catch {.f configure -visual best} msg] $msg

} {{-visual visual Visual {} default} 1 {can't modify -visual option after widget is created}}




catch {destroy .f}





test frame-1.4 {frame configuration options} {










    list [catch {frame .f -screen bogus} msg] $msg


} {1 {unknown option "-screen"}}
test frame-1.5 {frame configuration options} {


    set result [list [catch {frame .f -container true} msg] $msg \







	    [.f configure -container]]

    destroy .f
    set result
} {0 .f {-container container Container 0 1}}
test frame-1.6 {frame configuration options} {


    list [catch {frame .f -container bogus} msg] $msg


} {1 {expected boolean value but got "bogus"}}
test frame-1.7 {frame configuration options} {


    frame .f
    set result [list [catch {.f configure -container 1} msg] $msg]
    destroy .f
    set result
} {1 {can't modify -container option after widget is created}}
test frame-1.8 {frame configuration options} {


    # Make sure all options can be set to the default value
    frame .f
    set opts {}
    foreach opt [.f configure] {
        if {[llength $opt] == 5} {
            lappend opts [lindex $opt 0] [lindex $opt 4]
        }
    }
    eval frame .g $opts
    destroy .f .g
} {}

frame .f
set i 9
foreach test {
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {bad screen distance "badValue"}}
    {-bg #00ff00 #00ff00 non-existent
	    {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-height 100 100 not_a_number {bad screen distance "not_a_number"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 non-existent
	    {unknown color name "non-existent"}}
    {-highlightthickness 6 6 badValue {bad screen distance "badValue"}}
    {-padx 3 3 badValue {bad screen distance "badValue"}}
    {-pady 4 4 badValue {bad screen distance "badValue"}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-takefocus "any string" "any string" {} {}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {
    lassign $test opt goodValue goodResult badValue badResult
    test frame-1.$i {frame configuration options} {
	.f configure $opt $goodValue
	lindex [.f configure $opt] 4
    } $goodResult
    incr i
    if {$badValue ne ""} {
	test frame-1.$i {frame configuration options} -body {
	    .f configure $opt $badValue
	} -returnCodes error -result $badResult
    }
    .f configure $opt [lindex [.f configure $opt] 3]
    incr i
}
destroy .f

test frame-2.1 {toplevel configuration options} {
    catch {destroy .t}
    toplevel .t -width 200 -height 100 -class NewClass
    wm geometry .t +0+0
    list [.t configure -class] [catch {.t configure -class Another} msg] $msg
} {{-class class Class Toplevel NewClass} 1 {can't modify -class option after widget is created}}
test frame-2.2 {toplevel configuration options} {
    catch {destroy .t}
    toplevel .t -width 200 -height 100 -colormap new
    wm geometry .t +0+0
    list [.t configure -colormap] [catch {.t configure -colormap .} msg] $msg
} {{-colormap colormap Colormap {} new} 1 {can't modify -colormap option after widget is created}}
test frame-2.3 {toplevel configuration options} {
    catch {destroy .t}
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    list [catch {.t configure -container 1} msg] $msg [.t configure -container]
} {1 {can't modify -container option after widget is created} {-container container Container 0 0}}
test frame-2.4 {toplevel configuration options} {
    catch {destroy .t}
    list [catch {toplevel .t -width 200 -height 100 -colormap bogus} msg] $msg
} {1 {bad window path name "bogus"}}
set default "[winfo visual .] [winfo depth .]"
if {$tcl_platform(platform) == "windows"} {
test frame-2.5 {toplevel configuration options} notWinCI {
    catch {destroy .t}
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    list [catch {.t configure -use 0x44022} msg] $msg [.t configure -use]
} {1 {window "0x44022" doesn't exist} {-use use Use {} {}}}
} else {
test frame-2.5 {toplevel configuration options} {
    catch {destroy .t}
    toplevel .t -width 200 -height 100
    wm geometry .t +0+0
    list [catch {.t configure -use 0x44022} msg] $msg [.t configure -use]
} {1 {can't modify -use option after widget is created} {-use use Use {} {}}}
}

test frame-2.6 {toplevel configuration options} {
    catch {destroy .t}
    toplevel .t -width 200 -height 100 -visual default
    wm geometry .t +0+0
    list [.t configure -visual] [catch {.t configure -visual best} msg] $msg
} {{-visual visual Visual {} default} 1 {can't modify -visual option after widget is created}}
test frame-2.7 {toplevel configuration options} {
    catch {destroy .t}
    list [catch {toplevel .t -width 200 -height 100 -visual who_knows?} msg] $msg
} {1 {unknown or ambiguous visual name "who_knows?": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}}
test frame-2.8 {toplevel configuration options} haveDISPLAY {
    catch {destroy .t}
    toplevel .t -width 200 -height 100 -screen $env(DISPLAY)
    wm geometry .t +0+0
    set cfg [string compare [.t configure -screen] \
        "-screen screen Screen {} $env(DISPLAY)"]
    list $cfg [catch {.t configure -screen another} msg] $msg
} {0 1 {can't modify -screen option after widget is created}}
test frame-2.9 {toplevel configuration options} {
    catch {destroy .t}
    list [catch {toplevel .t -width 200 -height 100 -screen bogus} msg] $msg
} {1 {couldn't connect to display "bogus"}}
test frame-2.10 {toplevel configuration options} {
    catch {destroy .t}
    catch {destroy .x}
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    set result [list \
            [catch {toplevel .x -container 1 -use [winfo id .t]} msg] $msg]
    destroy .t .x
    set result
} {1 {A window cannot have both the -use and the -container option set.}}
test frame-2.11 {toplevel configuration options} {
    # Make sure all options can be set to the default value
    toplevel .f
    set opts {}
    foreach opt [.f configure] {
        if {[llength $opt] == 5} {
            lappend opts [lindex $opt 0] [lindex $opt 4]
        }
    }
    eval toplevel .g $opts

    destroy .f .g


} {}



















































































































































































































































































































catch {destroy .t}
toplevel .t -width 300 -height 150
wm geometry .t +0+0
update
set i 12
foreach test {
    {-background #ff0000 #ff0000 non-existent




	    {unknown color name "non-existent"}}






    {-bd 4 4 badValue {bad screen distance "badValue"}}

    {-bg #00ff00 #00ff00 non-existent




	    {unknown color name "non-existent"}}






    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}






    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}






    {-height 100 100 not_a_number {bad screen distance "not_a_number"}}

    {-highlightcolor #123456 #123456 non-existent




	    {unknown color name "non-existent"}}

    {-highlightthickness 3 3 badValue {bad screen distance "badValue"}}



    {-padx 3 3 badValue {bad screen distance "badValue"}}
    {-pady 4 4 badValue {bad screen distance "badValue"}}





    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {
    lassign $test opt goodValue goodResult badValue badResult
    test frame-2.$i {toplevel configuration options} {
	.t configure $opt $goodValue
	lindex [.t configure $opt] 4
    } $goodResult





    incr i


    if {$badValue ne ""} {

	test frame-2.$i {toplevel configuration options} -body {
	    .t configure $opt $badValue




	} -returnCodes error -result $badResult
    }
    .t configure $opt [lindex [.t configure $opt] 3]
    incr i
}

test frame-3.1 {TkCreateFrame procedure} -body {
    frame
} -returnCodes error -result {wrong # args: should be "frame pathName ?options?"}
test frame-3.2 {TkCreateFrame procedure} -setup {
    catch {destroy .f}
    frame .f
} -body {
    .f configure -class
} -cleanup {
    destroy .f
} -result {-class class Class Frame Frame}
test frame-3.3 {TkCreateFrame procedure} -setup {
    catch {destroy .t}
    toplevel .t
    wm geometry .t +0+0
} -body {
    .t configure -class
} -cleanup {
    destroy .t
} -result {-class class Class Toplevel Toplevel}
test frame-3.4 {TkCreateFrame procedure} {

    catch {destroy .t}
    toplevel .t -width 350 -class NewClass -bg black -visual default -height 90
    wm geometry .t +0+0
    update
    list [lindex [.t configure -width] 4] \
	    [lindex [.t configure -background] 4] \
	    [lindex [.t configure -height] 4]


} {350 black 90}

# Be sure that the -class, -colormap, and -visual options are processed
# before configuring the widget.

test frame-3.5 {TkCreateFrame procedure} {

    catch {destroy .f}
    option add *NewFrame.background #123456
    frame .f -class NewFrame
    option clear
    lindex [.f configure -background] 4
} {#123456}
test frame-3.6 {TkCreateFrame procedure} {
    catch {destroy .f}
    option add *NewFrame.background #123456
    frame .f -class NewFrame
    option clear
    lindex [.f configure -background] 4
} {#123456}
test frame-3.7 {TkCreateFrame procedure} {

    catch {destroy .f}
    option add *NewFrame.background #332211
    option add *f.class NewFrame
    frame .f



    option clear
    list [lindex [.f configure -class] 4] [lindex [.f configure -background] 4]
} {NewFrame #332211}
test frame-3.8 {TkCreateFrame procedure} {

    catch {destroy .f}
    option add *Silly.background #122334
    option add *f.Class Silly
    frame .f



    option clear
    list [lindex [.f configure -class] 4] [lindex [.f configure -background] 4]
} {Silly #122334}
test frame-3.9 {TkCreateFrame procedure, -use option} -setup {

    catch {destroy .t}
    catch {destroy .x}
} -constraints unix -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green
    tkwait visibility .x
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {






    destroy .t
} -result {0 0 140 300}
test frame-3.10 {TkCreateFrame procedure, -use option} -setup {

    catch {destroy .t}
    catch {destroy .x}
} -constraints unix -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0





    option add *x.use [winfo id .t]
    toplevel .x -width 140 -height 300 -bg green



    tkwait visibility .x


    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    destroy .t
    option clear
} -result {0 0 140 300}

# The tests below require specific display characteristics (i.e. that
# they are run on a pseudocolor display of depth 8).  Even so, they
# are non-portable: some machines don't seem to ever run out of
# colors.

if {[testConstraint defaultPseudocolor8]} {
    eatColors .t1
}
test frame-3.11 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    toplevel .t -width 300 -height 200 -bg #475601
    wm geometry .t +0+0
    update
    colorsFree .t
} {0}


test frame-3.12 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    toplevel .t -width 300 -height 200 -bg #475601 -colormap new
    wm geometry .t +0+0
    update
    colorsFree .t
} {1}


test frame-3.13 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    option add *t.class Toplevel2
    option add *Toplevel2.colormap new
    toplevel .t -width 300 -height 200 -bg #475601
    wm geometry .t +0+0
    update
    option clear
    colorsFree .t
} {1}


test frame-3.14 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    option add *t.class Toplevel3
    option add *Toplevel3.Colormap new
    toplevel .t -width 300 -height 200 -bg #475601 -colormap new
    wm geometry .t +0+0
    update
    option clear
    colorsFree .t
} {1}


test frame-3.15 {TkCreateFrame procedure, -use and -colormap} -setup {

    catch {destroy .t}
    catch {destroy .x}
} -constraints {defaultPseudocolor8 unix nonPortable} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green -colormap new
    tkwait visibility .x
    list [colorsFree .t] [colorsFree .x]
} -cleanup {
    destroy .t
} -result {0 1}
test frame-3.16 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    toplevel .t -width 300 -height 200 -bg #475601 -visual default
    wm geometry .t +0+0
    update
    colorsFree .t
} {0}


test frame-3.17 {TkCreateFrame procedure} {defaultPseudocolor8 nonPortable} {


    catch {destroy .t}

    toplevel .t -width 300 -height 200 -bg #475601 -visual default \
	    -colormap new
    wm geometry .t +0+0
    update
    colorsFree .t
} {1}


test frame-3.18 {TkCreateFrame procedure} {defaultPseudocolor8 haveGrayscale8 nonPortable} {


    catch {destroy .t}

    toplevel .t -visual {grayscale 8} -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    colorsFree .t 131 131 131
} {1}


test frame-3.19 {TkCreateFrame procedure} {defaultPseudocolor8 haveGrayscale8 nonPortable} {


    catch {destroy .t}

    option add *t.class T4
    option add *T4.visual {grayscale 8}
    toplevel .t -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    option clear
    list [colorsFree .t 131 131 131] [lindex [.t configure -visual] 4]


} {1 {grayscale 8}}
test frame-3.20 {TkCreateFrame procedure} {defaultPseudocolor8 haveGrayscale8 nonPortable} {


    catch {destroy .t}
    set x ok
    option add *t.class T5
    option add *T5.Visual {grayscale 8}
    toplevel .t -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    option clear
    list [colorsFree .t 131 131 131] [lindex [.t configure -visual] 4]


} {1 {grayscale 8}}
test frame-3.21 {TkCreateFrame procedure} {defaultPseudocolor8 haveGrayscale8 nonPortable} {


    catch {destroy .t}
    set x ok
    toplevel .t -visual {grayscale 8} -width 300 -height 200 -bg #434343
    wm geometry .t +0+0
    update
    colorsFree .t 131 131 131
} {1}


if {[testConstraint defaultPseudocolor8]} {
    destroy .t1
}
test frame-3.22 {TkCreateFrame procedure, default dimensions} -setup {
    catch {destroy .t}
} -body {
    toplevel .t
    wm geometry .t +0+0
    update
    set result "[winfo reqwidth .t] [winfo reqheight .t]"
    frame .t.f -bg red
    pack .t.f
    update
    lappend result [winfo reqwidth .t.f] [winfo reqheight .t.f]
} -cleanup {
    destroy .t
} -result {200 200 1 1}
test frame-3.23 {TkCreateFrame procedure} -setup {
    catch {destroy .f}
} -body {
    frame .f -gorp glob
} -returnCodes error -result {unknown option "-gorp"}
test frame-3.24 {TkCreateFrame procedure} -setup {
    catch {destroy .t}
} -body {
    toplevel .t -width 300 -height 200 -colormap new -bogus option
    wm geometry .t +0+0
} -returnCodes error -result {unknown option "-bogus"}

test frame-4.1 {TkCreateFrame procedure} {

    catch {destroy .f}
    catch {frame .f -gorp glob}
    winfo exists .f
} 0
test frame-4.2 {TkCreateFrame procedure} {

    catch {destroy .f}
    list [frame .f -width 200 -height 100] [winfo exists .f]


} {.f 1}

catch {destroy .f}
frame .f -highlightcolor black
test frame-5.1 {FrameWidgetCommand procedure} {
    list [catch .f msg] $msg
} {1 {wrong # args: should be ".f option ?arg arg ...?"}}
test frame-5.2 {FrameWidgetCommand procedure, cget option} {
    list [catch {.f cget} msg] $msg
} {1 {wrong # args: should be ".f cget option"}}
test frame-5.3 {FrameWidgetCommand procedure, cget option} {
    list [catch {.f cget a b} msg] $msg
} {1 {wrong # args: should be ".f cget option"}}
test frame-5.4 {FrameWidgetCommand procedure, cget option} {
    list [catch {.f cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test frame-5.5 {FrameWidgetCommand procedure, cget option} {
    .f cget -highlightcolor
} {black}
test frame-5.6 {FrameWidgetCommand procedure, cget option} {
    list [catch {.f cget -screen} msg] $msg
} {1 {unknown option "-screen"}}
test frame-5.7 {FrameWidgetCommand procedure, cget option} {
    catch {destroy .t}

    toplevel .t
    catch {.t cget -screen}
} {0}
catch {destroy .t}

test frame-5.8 {FrameWidgetCommand procedure, configure option} {
    llength [.f configure]

} {18}
test frame-5.9 {FrameWidgetCommand procedure, configure option} {
    list [catch {.f configure -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test frame-5.10 {FrameWidgetCommand procedure, configure option} {
    list [catch {.f configure -gorp bogus} msg] $msg
} {1 {unknown option "-gorp"}}
test frame-5.11 {FrameWidgetCommand procedure, configure option} {
    list [catch {.f configure -width 200 -height} msg] $msg
} {1 {value for "-height" missing}}
test frame-5.12 {FrameWidgetCommand procedure} {
    list [catch {.f swizzle} msg] $msg
} {1 {bad option "swizzle": must be cget or configure}}
test frame-5.13 {FrameWidgetCommand procedure, configure option} {
    llength [. configure]

} {21}

test frame-6.1 {ConfigureFrame procedure} {

    catch {destroy .f}
    frame .f -width 150
    list [winfo reqwidth .f] [winfo reqheight .f]


} {150 1}
test frame-6.2 {ConfigureFrame procedure} {

    catch {destroy .f}
    frame .f -height 97
    list [winfo reqwidth .f] [winfo reqheight .f]


} {1 97}
test frame-6.3 {ConfigureFrame procedure} {

    catch {destroy .f}
    frame .f
    set result {}
    lappend result [winfo reqwidth .f] [winfo reqheight .f]
    .f configure -width 100 -height 180
    lappend result [winfo reqwidth .f] [winfo reqheight .f]
    .f configure -width 0 -height 0
    lappend result [winfo reqwidth .f] [winfo reqheight .f]


} {1 1 100 180 100 180}

test frame-7.1 {FrameEventProc procedure} {


    frame .frame2
    set result [info commands .frame2]
    destroy .frame2
    lappend result [info commands .frame2]
} {.frame2 {}}
test frame-7.2 {FrameEventProc procedure} {
    deleteWindows


    frame .f1 -bg #543210
    rename .f1 .f2
    set x {}
    lappend x [winfo children .]
    lappend x [.f2 cget -bg]
    destroy .f1
    lappend x [info command .f*] [winfo children .]


} {.f1 #543210 {} {}}

test frame-8.1 {FrameCmdDeletedProc procedure} {
    deleteWindows

    frame .f1
    rename .f1 {}
    list [info command .f*] [winfo children .]


} {{} {}}
test frame-8.2 {FrameCmdDeletedProc procedure} {
    deleteWindows

    toplevel .f1 -menu .m
    wm geometry .f1 +0+0
    update
    rename .f1 {}
    update
    list [info command .f*] [winfo children .]


} {{} {}}
#
# This one fails with the dash-patch!!!! Still don't know why  :-(
#
#test frame-8.3 {FrameCmdDeletedProc procedure} {
#    eval destroy [winfo children .]

#    toplevel .f1 -menu .m
#    wm geometry .f1 +0+0
#    menu .m
#    update
#    rename .f1 {}
#    update
#    set result [list [info command .f*] [winfo children .]]
#    eval destroy [winfo children .]
#    set result
#} {{} .m}

test frame-9.1 {MapFrame procedure} {

    catch {destroy .t}
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    set result [winfo ismapped .t]
    update idletasks
    lappend result [winfo ismapped .t]


} {0 1}
test frame-9.2 {MapFrame procedure} {

    catch {destroy .t}
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    destroy .t
    update
    winfo exists .t
} {0}
test frame-9.3 {MapFrame procedure, window deleted while mapping} {


    toplevel .t2 -width 200 -height 200
    wm geometry .t2 +0+0
    tkwait visibility .t2
    catch {destroy .t}
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    frame .t2.f -width 50 -height 50
    bind .t2.f <Configure> {destroy .t}
    pack .t2.f -side top
    update idletasks
    winfo exists .t
} {0}

set l [interp hidden]
deleteWindows


test frame-10.1 {frame widget vs hidden commands} {

    catch {destroy .t}
    frame .t
    interp hide {} .t
    destroy .t
    list [winfo children .] [interp hidden]
} [list {} $l]

test frame-11.1 {TkInstallFrameMenu} {

    catch {destroy .t}
    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label foo
    list [toplevel .t -menu .m1] [destroy .m1] [destroy .t]


} {.t {} {}}
test frame-11.2 {TkInstallFrameMenu - frame renamed} {
    catch {destroy .t}
    catch {rename foo {}}

    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label foo
    toplevel .t
    list [rename .t foo] [destroy .t] [destroy foo] [destroy .m1]


} {{} {} {} {}}

test frame-12.1 {FrameWorldChanged procedure} {


    # Test -bd -padx and -pady
    destroy .f
    frame .f -borderwidth 2 -padx 3 -pady 4
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1
    update
    set result [list [winfo x .f.f] [winfo y .f.f] \
            [winfo width .f.f] [winfo height .f.f]]

    destroy .f
    set result
} {5 6 30 28}
test frame-12.2 {FrameWorldChanged procedure} {


    # Test all -labelanchor positions
    destroy .f
    set font {helvetica 12}
    labelframe .f -highlightthickness 1 -bd 3 -padx 1 -pady 2 -font $font \
            -text "Mupp"
    set fh [expr {[font metrics $font -linespace] + 2 - 3}]
    set fw [expr {[font measure $font "Mupp"] + 2 - 3}]
    if {$fw < 0} {set fw 0}
    if {$fh < 0} {set fh 0}
    place .f -x 0 -y 0 -width 100 -height 100
    pack [frame .f.f] -fill both -expand 1

    set result {}
    foreach lp {nw n ne en e es se s sw ws w wn} {
        .f configure -labelanchor $lp
        update
        set expx 5
        set expy 6
        set expw 90
        set exph 88
        switch -glob $lp {
            n* {incr expy $fh ; incr exph -$fh}
            s* {incr exph -$fh}
            w* {incr expx $fw ; incr expw -$fw}
            e* {incr expw -$fw}
        }
        lappend result [expr {\
                [winfo x .f.f] == $expx && [winfo y .f.f] == $expy &&\
                [winfo width .f.f] == $expw && [winfo height .f.f] == $exph}]

    }
    destroy .f
    set result


} {1 1 1 1 1 1 1 1 1 1 1 1}
test frame-12.3 {FrameWorldChanged procedure} {



    # Check reaction on font change
    destroy .f
    font create myfont -family courier -size 10
    labelframe .f -font myfont -text Mupp
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1



    update

    set h1 [font metrics myfont -linespace]
    set y1 [winfo y .f.f]
    font configure myfont -size 20



    update

    set h2 [font metrics myfont -linespace]
    set y2 [winfo y .f.f]





    destroy .f
























    font delete myfont
    expr {($h2 - $h1) - ($y2 - $y1)}
} {0}

test frame-13.1 {labelframe configuration options} {
    labelframe .f -class NewFrame
    list [.f configure -class] [catch {.f configure -class Different} msg] $msg
} {{-class class Class Labelframe NewFrame} 1 {can't modify -class option after widget is created}}
catch {destroy .f}


test frame-13.2 {labelframe configuration options} {


    list [catch {labelframe .f -colormap new} msg] $msg
} {0 .f}
catch {destroy .f}

test frame-13.3 {labelframe configuration options} {


    list [catch {labelframe .f -visual default} msg] $msg
} {0 .f}
catch {destroy .f}

test frame-13.4 {labelframe configuration options} {

    list [catch {labelframe .f -screen bogus} msg] $msg
} {1 {unknown option "-screen"}}
test frame-13.5 {labelframe configuration options} {
    set result [list [catch {labelframe .f -container true} msg] $msg \
	    [.f configure -container]]


















    destroy .f






    set result
} {0 .f {-container container Container 0 1}}
test frame-13.6 {labelframe configuration options} {


    list [catch {labelframe .f -container bogus} msg] $msg


} {1 {expected boolean value but got "bogus"}}


test frame-13.7 {labelframe configuration options} {


    labelframe .f
    set result [list [catch {.f configure -container 1} msg] $msg]
    destroy .f


    set result
} {1 {can't modify -container option after widget is created}}
labelframe .f
set i 8
foreach test {
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}








    {-bd 4 4 badValue {bad screen distance "badValue"}}

    {-bg #00ff00 #00ff00 non-existent
	    {unknown color name "non-existent"}}





    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}

    {-fg #0000ff #0000ff non-existent






	    {unknown color name "non-existent"}}

    {-font {courier 8} {courier 8} {} {}}





    {-foreground #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}

    {-height 100 100 not_a_number {bad screen distance "not_a_number"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 non-existent
	    {unknown color name "non-existent"}}
    {-highlightthickness 6 6 badValue {bad screen distance "badValue"}}
    {-labelanchor se se badValue {bad labelanchor "badValue": must be e, en, es, n, ne, nw, s, se, sw, w, wn, or ws}}
    {-padx 3 3 badValue {bad screen distance "badValue"}}
    {-pady 4 4 badValue {bad screen distance "badValue"}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-takefocus "any string" "any string" {} {}}
    {-text "any string" "any string" {} {}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {


    lassign $test name goodValue goodResult badValue badResult
    test frame-13.$i {labelframe configuration options} {






























	.f configure $name $goodValue
	lindex [.f configure $name] 4


    } $goodResult





    incr i




    if {$badValue ne ""} {

	test frame-13.$i {labelframe configuration options} -body {
	    .f configure $name $badValue






	} -returnCodes error -result $badResult

















    }
    .f configure $name [lindex [.f configure $name] 3]


    incr i









}
destroy .f

test frame-14.1 {labelframe labelwidget option} {


    # Test that label is moved in stacking order
    destroy .f .l
    label .l -text Mupp -font {helvetica 8}
    labelframe .f -labelwidget .l
    pack .f
    frame .f.f -width 50 -height 50
    pack .f.f
    update
    set res [list [winfo children .] [winfo width .f] \
            [expr {[winfo height .f] - [winfo height .l]}]]
    destroy .f .l
    set res
} {{.f .l} 54 52}
test frame-14.2 {labelframe labelwidget option} {


    # Test the labelframe's reaction if the label is destroyed
    destroy .f .l
    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set res [list [.f cget -labelwidget]]
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    destroy .l
    lappend res [.f cget -labelwidget]
    update
    lappend res [expr {[winfo width .f] - [winfo width .f.l]}]
    destroy .f
    set res
} {.l 12 {} 4}
test frame-14.3 {labelframe labelwidget option} {


    # Test the labelframe's reaction if the label is stolen
    destroy .f .l
    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set res [list [.f cget -labelwidget]]
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    pack .l
    lappend res [.f cget -labelwidget]
    update
    lappend res [expr {[winfo width .f] - [winfo width .f.l]}]
    destroy .f .l
    set res
} {.l 12 {} 4}
test frame-14.4 {labelframe labelwidget option} {


    # Test the label's reaction if the labelframe is destroyed
    destroy .f .l
    label .l -text Mupp
    labelframe .f -labelwidget .l
    pack .f
    update
    set res [list [winfo manager .l]]
    destroy .f
    lappend res [winfo manager .l]
    destroy .l
    set res
} {labelframe {}}
test frame-14.5 {labelframe labelwidget option} {


    # Test that the labelframe reacts on changes in label
    destroy .f .l
    label .l -text Aratherlonglabel
    labelframe .f -labelwidget .l
    pack .f
    label .f.l -text Mupp
    pack .f.l
    update
    set first [winfo width .f]
    set res [expr {[winfo width .f] - [winfo width .l]}]
    .l configure -text Shorter
    update
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    lappend res [expr {[winfo width .f] < $first}]
    .l configure -text Alotlongerthananytimebefore
    update
    lappend res [expr {[winfo width .f] - [winfo width .l]}]
    lappend res [expr {[winfo width .f] > $first}]
    destroy .f .l
    set res
} {12 12 1 12 1}
test frame-14.6 {labelframe labelwidget option} {


    # Destroying a labelframe with a child label caused a crash
    # when not handling mapping of the label correctly.
    # This test does not test anything directly, it's just ment
    # to catch if the same mistake is made again.
    destroy .f
    labelframe .f
    pack .f
    label .f.l -text Mupp
    .f configure -labelwidget .f.l
    update










    destroy .f





























































































} {}
















































catch {destroy .f}

































rename eatColors {}












rename colorsFree {}





















































































# cleanup





cleanupTests
return




Changes to tests/geometry.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
# This file is a Tcl script to test the procedures in the file
# tkGeometry.c (generic support for geometry managers).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

proc getsize w {
    regexp {(^[^+-]*)} [wm geometry $w] foo x
    return $x
}

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


wm geometry . 300x300
raise .
update

frame .f -bd 2 -relief raised
frame .f.f -bd 2 -relief sunken
frame .f.f.f -bd 2 -relief raised
button .b1 -text .b1
button .b2 -text .b2
button .b3 -text .b3
button .f.f.b4 -text .b4

test geometry-1.1 {Tk_ManageGeometry procedure} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .b1 -x 120 -y 80
    update
    list [winfo x .b1] [winfo y .b1]
} -result {120 80}
test geometry-1.2 {Tk_ManageGeometry procedure} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .b1 -in .f -x 40 -y 30
    update
    pack .b1 -side top -anchor w
    place .f -x 30 -y 40
    update
    list [winfo x .b1] [winfo y .b1]
} -result {0 0}


test geometry-2.1 {Tk_GeometryRequest procedure} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
    destroy .f2
} -body {
    frame .f2
    set result [list [winfo reqwidth .f2] [winfo reqheight .f2]]
    .f2 configure -width 150 -height 300
    update
    lappend result [winfo reqwidth .f2] [winfo reqheight .f2] \
        [winfo geom .f2]
    place .f2 -x 10 -y 20
    update
    lappend result [winfo geom .f2]
    .f2 configure -width 100 -height 80
    update
    lappend result [winfo geom .f2]
} -cleanup {
    destroy .f2
} -result {1 1 150 300 1x1+0+0 150x300+10+20 100x80+10+20}


test geometry-3.1 {Tk_SetInternalBorder procedure} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .b1 -in .f -x 50 -y 5
    update
    set x [list [winfo x .b1] [winfo y .b1]]
    .f configure -bd 5
    update
    lappend x [winfo x .b1] [winfo y .b1]
} -cleanup {
    .f configure -bd 2
} -result {72 37 75 40}


test geometry-4.1 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    update
    list [winfo x .b1] [winfo y .b1]
} -result {91 46}
test geometry-4.2 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    place .f -x 30 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
        [winfo x .b3] [winfo y .b3]
} -result {101 41 61 61 101 61}
test geometry-4.3 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b1
    button .b1 -text .b1
    place .f.f -x 10 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
        [winfo x .b3] [winfo y .b3]
} -result {0 0 46 86 86 86}
test geometry-4.4 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b2
    button .b2 -text .b2
    place .f.f.f -x 2 -y 3
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
        [winfo x .b3] [winfo y .b3]
} -result {93 49 0 0 93 69}
test geometry-4.5 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b3
    button .b3 -text .b3
    place .f.f.f -x 2 -y 3
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
        [winfo x .b3] [winfo y .b3]
} -result {93 49 53 69 0 0}
test geometry-4.6 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3 .f.f.b4} {
    place forget $w
    }
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .f.f.b4 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    update
    place .f -x 25 -y 35
    update
    list [winfo x .f.f.b4] [winfo y .f.f.b4] [winfo x .b2] [winfo y .b2]
} -result {54 9 56 71}
test geometry-4.7 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    bind .b1 <Configure> {lappend x configure}
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .f.f.b4 -in .f.f.f -x 50 -y 5
    place .b1 -in .f.f.f -x 10 -y 25
    update
    set x init
    place .f -x 25 -y 35
    update
    lappend x |
    place .f -x 30 -y 40
    place .f.f -x 10 -y 0
    update
    return $x
} -cleanup {
    bind .b1 <Configure> {}

} -result {init configure |}
test geometry-4.8 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .f.f
    frame .f.f -bd 2 -relief raised
    frame .f.f.f -bd 2 -relief raised
    place .f -x 30 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo ismapped .b1] \
        [winfo x .b2] [winfo y .b2] [winfo ismapped .b2] \
        [winfo x .b3] [winfo y .b3] [winfo ismapped .b3]
} -result {91 46 0 51 66 0 91 66 0}
test geometry-4.9 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
} -body {
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    update
    set result [winfo ismapped .b1]
    place forget .f.f
    update
    lappend result [winfo ismapped .b1]
    place .f.f -x 15 -y 5 -width 150 -height 120
    update
    lappend result [winfo ismapped .b1]
} -result {1 0 1}
test geometry-4.10 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} -setup {
	foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
        place forget $w
    }
    destroy .t
} -body {
    toplevel .t
    wm geometry .t +0+0
    tkwait visibility .t
    update
    pack [frame .t.f]

    button .t.quit -text Quit -command exit
    pack .t.quit -in .t.f
    wm iconify .t
    set x 0
    after 500 {set x 1}
    tkwait variable x
    wm deiconify .t
    update
    winfo ismapped .t.quit
} -cleanup {
    destroy .t
} -result 1



# cleanup
cleanupTests
return





|
|
|


<
<
<
<
<



<
<













|
<
<
<
<



|
|
|
|

<







|

<
|
<
<
<
<
<





|






<
<
|
|

|
|
|

<







|
|
<

<
|
|
|

<






|
|
|
|

<










|
|
|
|
|

<












|
|
|
|
|

<












|
|
|
|
|

<












|
|
|
<
<
<
<

|










|
|
|
|

<














<
<

>
|
|
|
|

<













|
|
|
|
|
|

<












|
|
<
<
<
<
<




|
>









|
<
<

>




<
1
2
3
4
5
6
7
8
9





10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26




27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43

44





45
46
47
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72

73

74
75
76
77

78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155




156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186


187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227





228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247
248
249

# This file is a Tcl script to test the procedures in the file
# tkGeometry.c (generic support for geometry managers).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.






package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



wm geometry . 300x300
raise .
update

frame .f -bd 2 -relief raised
frame .f.f -bd 2 -relief sunken
frame .f.f.f -bd 2 -relief raised
button .b1 -text .b1
button .b2 -text .b2
button .b3 -text .b3
button .f.f.b4 -text .b4

test geometry-1.1 {Tk_ManageGeometry procedure} {




    place .b1 -x 120 -y 80
    update
    list [winfo x .b1] [winfo y .b1]
} {120 80}
test geometry-1.2 {Tk_ManageGeometry procedure} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .b1 -in .f -x 40 -y 30
    update
    pack .b1 -side top -anchor w
    place .f -x 30 -y 40
    update
    list [winfo x .b1] [winfo y .b1]
} {0 0}


test geometry-2.1 {Tk_GeometryRequest procedure} {





    frame .f2
    set result [list [winfo reqwidth .f2] [winfo reqheight .f2]]
    .f2 configure -width 150 -height 300
    update
    lappend result [winfo reqwidth .f2] [winfo reqheight .f2] \
	    [winfo geom .f2]
    place .f2 -x 10 -y 20
    update
    lappend result [winfo geom .f2]
    .f2 configure -width 100 -height 80
    update
    lappend result [winfo geom .f2]


} {1 1 150 300 1x1+0+0 150x300+10+20 100x80+10+20}
catch {destroy .f2}

test geometry-3.1 {Tk_SetInternalBorder procedure} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .b1 -in .f -x 50 -y 5
    update
    set x [list [winfo x .b1] [winfo y .b1]]
    .f configure -bd 5
    update
    lappend x [winfo x .b1] [winfo y .b1]
} {72 37 75 40}
.f configure -bd 2



test geometry-4.1 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    update
    list [winfo x .b1] [winfo y .b1]
} {91 46}
test geometry-4.2 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    place .f -x 30 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
	    [winfo x .b3] [winfo y .b3]
} {101 41 61 61 101 61}
test geometry-4.3 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b1
    button .b1 -text .b1
    place .f.f -x 10 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
	    [winfo x .b3] [winfo y .b3]
} {0 0 46 86 86 86}
test geometry-4.4 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b2
    button .b2 -text .b2
    place .f.f.f -x 2 -y 3
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
	    [winfo x .b3] [winfo y .b3]
} {93 49 0 0 93 69}
test geometry-4.5 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .b3
    button .b3 -text .b3
    place .f.f.f -x 2 -y 3
    update
    list [winfo x .b1] [winfo y .b1] [winfo x .b2] [winfo y .b2] \
	    [winfo x .b3] [winfo y .b3]
} {93 49 53 69 0 0}
test geometry-4.6 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {




    foreach w {.f .f.f .f.f.f .b1 .b2 .b3 .f.f.b4} {
	place forget $w
    }
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .f.f.b4 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    update
    place .f -x 25 -y 35
    update
    list [winfo x .f.f.b4] [winfo y .f.f.b4] [winfo x .b2] [winfo y .b2]
} {54 9 56 71}
test geometry-4.7 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3 .f.f.b4} {
	place forget $w
    }

    bind .b1 <Configure> {lappend x configure}
    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .f.f.b4 -in .f.f.f -x 50 -y 5
    place .b1 -in .f.f.f -x 10 -y 25
    update
    set x init
    place .f -x 25 -y 35
    update
    lappend x |
    place .f -x 30 -y 40
    place .f.f -x 10 -y 0
    update


    bind .b1 <Configure> {}
    set x
} {init configure |}
test geometry-4.8 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    place .b2 -in .f.f.f -x 10 -y 25
    place .b3 -in .f.f.f -x 50 -y 25
    update
    destroy .f.f
    frame .f.f -bd 2 -relief raised
    frame .f.f.f -bd 2 -relief raised
    place .f -x 30 -y 25
    update
    list [winfo x .b1] [winfo y .b1] [winfo ismapped .b1] \
	    [winfo x .b2] [winfo y .b2] [winfo ismapped .b2] \
	    [winfo x .b3] [winfo y .b3] [winfo ismapped .b3]
} {91 46 0 51 66 0 91 66 0}
test geometry-4.9 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {
    foreach w {.f .f.f .f.f.f .b1 .b2 .b3} {
	place forget $w
    }

    place .f -x 20 -y 30 -width 200 -height 200
    place .f.f -x 15 -y 5 -width 150 -height 120
    place .f.f.f -width 100 -height 80
    place .b1 -in .f.f.f -x 50 -y 5
    update
    set result [winfo ismapped .b1]
    place forget .f.f
    update
    lappend result [winfo ismapped .b1]
    place .f.f -x 15 -y 5 -width 150 -height 120
    update
    lappend result [winfo ismapped .b1]
} {1 0 1}
test geometry-4.10 {Tk_MaintainGeometry and Tk_UnmaintainGeometry} {





    toplevel .t
    wm geometry .t +0+0
    tkwait visibility .t
    update
    frame .t.f
    pack .t.f
    button .t.quit -text Quit -command exit
    pack .t.quit -in .t.f
    wm iconify .t
    set x 0
    after 500 {set x 1}
    tkwait variable x
    wm deiconify .t
    update
    winfo ismapped .t.quit
} {1}



catch {destroy .t}

# cleanup
cleanupTests
return

Changes to tests/get.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# This file is a Tcl script to test out the procedures in the file
# tkGet.c.  It is organized in the standard fashion for Tcl
# white-box tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

test get-1.1 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {

    .b configure -anchor n
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {n}
test get-1.2 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor ne
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {ne}
test get-1.3 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor e
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {e}
test get-1.4 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor se
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {se}
test get-1.5 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor s
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {s}
test get-1.6 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor sw
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {sw}
test get-1.7 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor w
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {w}
test get-1.8 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor nw
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {nw}
test get-1.9 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor n
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {n}
test get-1.10 {Tk_GetAnchorFromObj} -setup {
    button .b
} -body {
    .b configure -anchor center
    .b cget -anchor
} -cleanup {
    destroy .b
} -result {center}
test get-1.11 {Tk_GetAnchorFromObj - error} -setup {
    button .b
} -body {
    .b configure -anchor unknown
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad anchor "unknown": must be n, ne, e, se, s, sw, w, nw, or center}


test get-2.1 {Tk_GetJustifyFromObj} -setup {
    button .b
} -body {

    .b configure -justify left
    .b cget -justify
} -cleanup {
    destroy .b
} -result {left}
test get-2.2 {Tk_GetJustifyFromObj} -setup {
    button .b
} -body {
    .b configure -justify right
    .b cget -justify
} -cleanup {
    destroy .b
} -result {right}
test get-2.3 {Tk_GetJustifyFromObj} -setup {
    button .b
} -body {
    .b configure -justify center
    .b cget -justify
} -cleanup {
    destroy .b
} -result {center}
test get-2.4 {Tk_GetJustifyFromObj - error} -setup {
    button .b
} -body {
    .b configure -justify stupid
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad justification "stupid": must be left, right, or center}

# cleanup
cleanupTests
return





|
|





<

<
|
<
>


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<
|
<
<
|

|
<
|
<
>


<
<
|
|
<
<


<
<
|
|
<
<


<
<
|
|
<
<
|
<
<
|




<
1
2
3
4
5
6
7
8
9
10
11

12

13

14
15
16


17
18


19
20


21
22


23
24


25
26


27
28


29
30


31
32


33
34


35
36


37
38


39
40


41
42


43
44


45
46


47
48


49
50


51
52


53
54


55


56
57
58

59

60
61
62


63
64


65
66


67
68


69
70


71
72


73


74
75
76
77
78

# This file is a Tcl script to test out the procedures in the file
# tkGet.c.  It is organized in the standard fashion for Tcl
# white-box tests.
#
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



button .b

test get-1.1 {Tk_GetAnchorFromObj} {
    .b configure -anchor n
    .b cget -anchor


} {n}
test get-1.2 {Tk_GetAnchorFromObj} {


    .b configure -anchor ne
    .b cget -anchor


} {ne}
test get-1.3 {Tk_GetAnchorFromObj} {


    .b configure -anchor e
    .b cget -anchor


} {e}
test get-1.4 {Tk_GetAnchorFromObj} {


    .b configure -anchor se
    .b cget -anchor


} {se}
test get-1.5 {Tk_GetAnchorFromObj} {


    .b configure -anchor s
    .b cget -anchor


} {s}
test get-1.6 {Tk_GetAnchorFromObj} {


    .b configure -anchor sw
    .b cget -anchor


} {sw}
test get-1.7 {Tk_GetAnchorFromObj} {


    .b configure -anchor w
    .b cget -anchor


} {w}
test get-1.8 {Tk_GetAnchorFromObj} {


    .b configure -anchor nw
    .b cget -anchor


} {nw}
test get-1.9 {Tk_GetAnchorFromObj} {


    .b configure -anchor n
    .b cget -anchor


} {n}
test get-1.10 {Tk_GetAnchorFromObj} {


    .b configure -anchor center
    .b cget -anchor


} {center}
test get-1.11 {Tk_GetAnchorFromObj - error} {


    list [catch {.b configure -anchor unknown} msg] $msg


} {1 {bad anchor "unknown": must be n, ne, e, se, s, sw, w, nw, or center}}

catch {destroy .b}

button .b

test get-2.1 {Tk_GetJustifyFromObj} {
    .b configure -justify left
    .b cget -justify


} {left}
test get-2.2 {Tk_GetJustifyFromObj} {


    .b configure -justify right
    .b cget -justify


} {right}
test get-2.3 {Tk_GetJustifyFromObj} {


    .b configure -justify center
    .b cget -justify


} {center}
test get-2.4 {Tk_GetJustifyFromObj - error} {


    list [catch {.b configure -justify stupid} msg] $msg


} {1 {bad justification "stupid": must be left, right, or center}}

# cleanup
cleanupTests
return

Changes to tests/grab.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# Tests for the grab command.
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# The macOS test module includes the pressbutton command to simulate a
# mouse button press event by injecting events into the NSApplication
# event queue.  On other platforms there is currently no way to test
# the actual grab effect, per se, in an automated test.  Therefore,
# this test suite only covers the interface to the grab command (ie,
# error messages, etc.) on platforms other than macOS.

testConstraint pressbutton [llength [info commands pressbutton]]

test grab-1.1 {Tk_GrabObjCmd} -body {
    grab
} -returnCodes error -result {wrong # args: should be "grab ?-global? window" or "grab option ?arg ...?"}
test grab-1.2 {Tk_GrabObjCmd} -body {
    rename grab grabTest1.2
    grabTest1.2
} -cleanup {
    rename grabTest1.2 grab

} -returnCodes error -result {wrong # args: should be "grabTest1.2 ?-global? window" or "grabTest1.2 option ?arg ...?"}

test grab-1.3 {Tk_GrabObjCmd, "grab ?-global? window"} -body {
    grab .foo bar baz
} -returnCodes error -result {wrong # args: should be "grab ?-global? window"}
test grab-1.4 {Tk_GrabObjCmd, "grab ?-global? window"} -body {
    destroy .foo
    grab .foo
} -returnCodes error -result {bad window path name ".foo"}
test grab-1.5 {Tk_GrabObjCmd, "grab ?-global? window"} -body {
    grab -foo bar
} -returnCodes error -result {bad option "-foo": must be -global}
test grab-1.6 {Tk_GrabObjCmd, "grab ?-global? window"} -body {
    destroy .foo
    grab -global .foo
} -returnCodes error -result {bad window path name ".foo"}

test grab-1.7 {Tk_GrabObjCmd} -body {
    grab foo
} -returnCodes error -result {bad option "foo": must be current, release, set, or status}

test grab-1.8 {Tk_GrabObjCmd, "grab current ?window?"} -body {
    grab current foo bar
} -returnCodes error -result {wrong # args: should be "grab current ?window?"}
test grab-1.9 {Tk_GrabObjCmd, "grab current ?window?"} -body {
    destroy .foo
    grab current .foo
} -returnCodes error -result {bad window path name ".foo"}

test grab-1.10 {Tk_GrabObjCmd, "grab release window"} -body {
    grab release
} -returnCodes error -result {wrong # args: should be "grab release window"}
test grab-1.11 {Tk_GrabObjCmd, "grab release window"} -body {
    destroy .foo
    grab release .foo
} -returnCodes ok -result {}
test grab-1.12 {Tk_GrabObjCmd, "grab release window"} -body {
    grab release foo
} -returnCodes ok -result {}

test grab-1.13 {Tk_GrabObjCmd, "grab set ?-global? window"} -body {
    grab set
} -returnCodes error -result {wrong # args: should be "grab set ?-global? window"}
test grab-1.14 {Tk_GrabObjCmd, "grab set ?-global? window"} -body {
    grab set foo bar baz
} -returnCodes error -result {wrong # args: should be "grab set ?-global? window"}
test grab-1.15 {Tk_GrabObjCmd, "grab set ?-global? window"} -body {
    destroy .foo
    grab set .foo
} -returnCodes error -result {bad window path name ".foo"}
test grab-1.16 {Tk_GrabObjCmd, "grab set ?-global? window"} -body {
    grab set -foo bar
} -returnCodes error -result {bad option "-foo": must be -global}
test grab-1.17 {Tk_GrabObjCmd, "grab set ?-global? window"} -body {
    destroy .foo
    grab set -global .foo
} -returnCodes error -result {bad window path name ".foo"}

test grab-1.18 {Tk_GrabObjCmd, "grab status window"} -body {
    grab status
} -returnCodes error -result {wrong # args: should be "grab status window"}
test grab-1.19 {Tk_GrabObjCmd, "grab status window"} -body {
    grab status foo bar
} -returnCodes error -result {wrong # args: should be "grab status window"}
test grab-1.20 {Tk_GrabObjCmd, "grab status window"} -body {
    destroy .foo
    grab status .foo
} -returnCodes error -result {bad window path name ".foo"}


test grab-2.1 {Tk_GrabObjCmd, grab status gives correct status} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab status .
} -cleanup {
    grab release .
} -result none

test grab-2.2 {Tk_GrabObjCmd, grab status gives correct status} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    grab status .
} -cleanup {
    grab release .
} -result {local}

test grab-2.3 {Tk_GrabObjCmd, grab status gives correct status} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab -global .
    grab status .
} -cleanup {
    grab release .
} -result {global}


test grab-3.1 {Tk_GrabObjCmd, grab current gives correct information} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    return $curr
} -result {}
test grab-3.2 {Tk_GrabObjCmd, grab current gives correct information} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    grab current
} -cleanup {
    grab release .
} -result {.}


test grab-4.1 {Tk_GrabObjCmd, grab release releases grab} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    set result [grab status .]
    grab release .
    lappend result [grab status .]
    grab -global .
    lappend result [grab status .]
    grab release .
    lappend result [grab status .]
} -result {local none global none}


test grab-5.1 {Tk_GrabObjCmd, grab set} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab set .
    list [grab current .] [grab status .]
} -cleanup {
    grab release .
} -result {. local}

test grab-5.2 {Tk_GrabObjCmd, grab set} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab set -global .
    list [grab current .] [grab status .]
} -cleanup {
    grab release .
} -result {. global}

test grab-6.1 {local grab on child window} -constraints {
    pressbutton
} -body {
    wm geometry . 100x200+200+100
    set result {}
    frame .f -background red -padx 10 -pady 10 -height 100 -width 80
    bind . <Button-1> {lappend result "outside"}
    bind .f <Button-1> {lappend result "inside"}
    pack .f
    update idletasks
    pressbutton 250 150
    update
    lappend result ":"
    pressbutton 250 250
    update
    lappend result ":"
    grab set .f
    pressbutton 250 150
    update
    lappend result ":"
    pressbutton 250 250
    update
    return $result
} -cleanup {
    grab release .f
} -result {inside outside : outside : inside outside :}

cleanupTests
return







|





<

<
<
|
|
|
<

<
<
|
|
|
|

|
<

>
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

<
|




|
<

|
>
|





|
<

|
>
|





|
<

|
|

|




|
|
|





|
<

|
|

|












<
|

|





|
<

|
>
|





|
<

<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<



<
1
2
3
4
5
6
7
8
9
10
11
12

13


14
15
16

17


18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174

175






176







177













178
179
180

# Tests for the grab command.
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands




# There's currently no way to test the actual grab effect, per se,
# in an automated test.  Therefore, this test suite only covers the
# interface to the grab command (ie, error messages, etc.)




test grab-1.1 {Tk_GrabObjCmd} {
    list [catch {grab} msg] $msg
} [list 1 "wrong # args: should be \"grab ?-global? window\" or \"grab option ?arg arg ...?\""]
test grab-1.2 {Tk_GrabObjCmd} {
    rename grab grabTest1.2
    set res [list [catch {grabTest1.2} msg] $msg]

    rename grabTest1.2 grab
    set res
} [list 1 "wrong # args: should be \"grabTest1.2 ?-global? window\" or \"grabTest1.2 option ?arg arg ...?\""]

test grab-1.3 {Tk_GrabObjCmd, "grab ?-global? window"} {
    list [catch {grab .foo bar baz} msg] $msg
} [list 1 "wrong # args: should be \"grab ?-global? window\""]
test grab-1.4 {Tk_GrabObjCmd, "grab ?-global? window"} {
    catch {destroy .foo}
    list [catch {grab .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]
test grab-1.5 {Tk_GrabObjCmd, "grab ?-global? window"} {
    list [catch {grab -foo bar} msg] $msg
} [list 1 "bad option \"-foo\": must be -global"]
test grab-1.6 {Tk_GrabObjCmd, "grab ?-global? window"} {
    catch {destroy .foo}
    list [catch {grab -global .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]

test grab-1.7 {Tk_GrabObjCmd} {
    list [catch {grab foo} msg] $msg
} [list 1 "bad option \"foo\": must be current, release, set, or status"]

test grab-1.8 {Tk_GrabObjCmd, "grab current ?window?"} {
    list [catch {grab current foo bar} msg] $msg
} [list 1 "wrong # args: should be \"grab current ?window?\""]
test grab-1.9 {Tk_GrabObjCmd, "grab current ?window?"} {
    catch {destroy .foo}
    list [catch {grab current .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]

test grab-1.10 {Tk_GrabObjCmd, "grab release window"} {
    list [catch {grab release} msg] $msg
} [list 1 "wrong # args: should be \"grab release window\""]
test grab-1.11 {Tk_GrabObjCmd, "grab release window"} {
    catch {destroy .foo}
    list [catch {grab release .foo} msg] $msg
} [list 0 ""]
test grab-1.12 {Tk_GrabObjCmd, "grab release window"} {
    list [catch {grab release foo} msg] $msg
} [list 0 ""]

test grab-1.13 {Tk_GrabObjCmd, "grab set ?-global? window"} {
    list [catch {grab set} msg] $msg
} [list 1 "wrong # args: should be \"grab set ?-global? window\""]
test grab-1.14 {Tk_GrabObjCmd, "grab set ?-global? window"} {
    list [catch {grab set foo bar baz} msg] $msg
} [list 1 "wrong # args: should be \"grab set ?-global? window\""]
test grab-1.15 {Tk_GrabObjCmd, "grab set ?-global? window"} {
    catch {destroy .foo}
    list [catch {grab set .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]
test grab-1.16 {Tk_GrabObjCmd, "grab set ?-global? window"} {
    list [catch {grab set -foo bar} msg] $msg
} [list 1 "bad option \"-foo\": must be -global"]
test grab-1.17 {Tk_GrabObjCmd, "grab set ?-global? window"} {
    catch {destroy .foo}
    list [catch {grab set -global .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]

test grab-1.18 {Tk_GrabObjCmd, "grab status window"} {
    list [catch {grab status} msg] $msg
} [list 1 "wrong # args: should be \"grab status window\""]
test grab-1.19 {Tk_GrabObjCmd, "grab status window"} {
    list [catch {grab status foo bar} msg] $msg
} [list 1 "wrong # args: should be \"grab status window\""]
test grab-1.20 {Tk_GrabObjCmd, "grab status window"} {
    catch {destroy .foo}
    list [catch {grab status .foo} msg] $msg
} [list 1 "bad window path name \".foo\""]


test grab-2.1 {Tk_GrabObjCmd, grab status gives correct status} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    set result [grab status .]

    grab release .
    set result
} "none"
test grab-2.2 {Tk_GrabObjCmd, grab status gives correct status} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    set result [grab status .]

    grab release .
    set result
} "local"
test grab-2.3 {Tk_GrabObjCmd, grab status gives correct status} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab -global .
    set result [grab status .]

    grab release .
    set result
} "global"

test grab-3.1 {Tk_GrabObjCmd, grab current gives correct information} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    set curr
} ""
test grab-3.2 {Tk_GrabObjCmd, grab current gives correct information} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    set curr [grab current]

    grab release .
    set curr
} "."

test grab-4.1 {Tk_GrabObjCmd, grab release releases grab} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    set result [grab status .]
    grab release .
    lappend result [grab status .]
    grab -global .
    lappend result [grab status .]
    grab release .
    lappend result [grab status .]

} [list "local" "none" "global" "none"]

test grab-5.1 {Tk_GrabObjCmd, grab set} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab set .
    set result [list [grab current .] [grab status .]]

    grab release .
    set result
} [list "." "local"]
test grab-5.2 {Tk_GrabObjCmd, grab set} {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab set -global .
    set result [list [grab current .] [grab status .]]

    grab release .






    set result







} [list "." "global"]














cleanupTests
return

Changes to tests/grid.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41




















42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66

67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93

94
95
96

97
98
99

100
101
102

103
104
105

106
107
108

109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299

300
301
302

303
304
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# This file is a Tcl script to test out the *NEW* "grid" command of Tk. It is
# (almost) organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# helper routine to return "." to a sane state after a test.
# The variable GRID_VERBOSE can be used to "look" at the result of one or all
# of the tests

proc grid_reset {{test ?} {top .}} {
    global GRID_VERBOSE
    if {[info exists GRID_VERBOSE]} {
	if {$GRID_VERBOSE eq "" || $GRID_VERBOSE eq $test} {
	    puts -nonewline "grid test $test: "
	    flush stdout
	    gets stdin
	}
    }
    eval destroy [winfo children $top]
    update
    foreach {cols rows} [grid size .] {}
    for {set i 0} {$i <= $cols} {incr i} {
	grid columnconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    for {set i 0} {$i <= $rows} {incr i} {
	grid rowconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    grid propagate . 1
    grid anchor . nw
    update
}

grid_reset 0.0
wm geometry . {}





















test grid-1.1 {basic argument checking} -body {
    grid
} -returnCodes error -result {wrong # args: should be "grid option arg ?arg ...?"}
test grid-1.2 {basic argument checking} -body {
    grid foo bar
} -returnCodes error -result {bad option "foo": must be anchor, bbox, columnconfigure, configure, content, forget, info, location, propagate, remove, rowconfigure, or size}
test grid-1.3 {basic argument checking} -body {
    button .b
    grid .b -row 0 -column
} -cleanup {
    grid_reset 1.3
} -returnCodes error -result {extra option or option with no value}
test grid-1.4 {basic argument checking} -body {
    button .b
    grid configure .b - foo
} -cleanup {
    grid_reset 1.4
} -returnCodes error -result {unexpected parameter "foo" in configure list: should be window name or option}
test grid-1.5 {basic argument checking} -body {
    grid .
} -returnCodes error -result {can't manage ".": it's a top-level window}

test grid-1.6 {basic argument checking} -body {
    grid x
} -returnCodes error -result {can't determine container window}

test grid-1.7 {basic argument checking} -body {
    grid configure x
} -returnCodes error -result {can't determine container window}

test grid-1.8 {basic argument checking} -body {
    button .b
    grid x .b
} -cleanup {
    grid_reset 1.8
} -returnCodes ok -result {}
test grid-1.9 {basic argument checking} -body {
    button .b
    grid configure x .b
} -cleanup {
    grid_reset 1.9
} -returnCodes ok -result {}


test grid-2.1 {bbox} -body {
    grid bbox .
} -result {0 0 0 0}

test grid-2.2 {bbox} -body {
    button .b
    grid .b
    destroy .b
    update
    grid bbox .
} -result {0 0 0 0}

test grid-2.3 {bbox: argument checking} -body {
    grid bbox . 0 0 5
} -returnCodes error -result {wrong # args: should be "grid bbox window ?column row ?column row??"}

test grid-2.4 {bbox} -body {
    grid bbox .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}

test grid-2.5 {bbox} -body {
    grid bbox . x 0
} -returnCodes error -result {expected integer but got "x"}

test grid-2.6 {bbox} -body {
    grid bbox . 0 x
} -returnCodes error -result {expected integer but got "x"}

test grid-2.7 {bbox} -body {
    grid bbox . 0 0 x 0
} -returnCodes error -result {expected integer but got "x"}

test grid-2.8 {bbox} -body {
    grid bbox . 0 0 0 x
} -returnCodes error -result {expected integer but got "x"}

test grid-2.9 {bbox} -body {
    frame .1 -width 75 -height 75 -bg red
    frame .2 -width 90 -height 90 -bg red
    grid .1 -row 0 -column 0
    grid .2 -row 1 -column 1
    update
    set a ""
    lappend a [grid bbox .]
    lappend a [grid bbox . 0 0]
    lappend a [grid bbox . 0 0 1 1]
    lappend a [grid bbox . 1 1]
    return $a
} -cleanup {
    grid_reset 2.9
} -result {{0 0 165 165} {0 0 75 75} {0 0 165 165} {75 75 90 90}}
test grid-2.10 {bbox} -body {
    frame .1 -width 75 -height 75 -bg red
    frame .2 -width 90 -height 90 -bg red
    grid .1 -row 0 -column 0
    grid .2 -row 1 -column 1
    update
    set a ""
    lappend a [grid bbox . 10 10 0 0]
    lappend a [grid bbox . -2 -2 -1 -1]
    lappend a [grid bbox . 10 10 12 12]
    return $a
} -cleanup {
    grid_reset 2.10
} -result {{0 0 165 165} {0 0 0 0} {165 165 0 0}}

test grid-3.1 {configure: basic argument checking} -body {
    grid configure foo
} -returnCodes error -result {bad argument "foo": must be name of window}

test grid-3.2 {configure: basic argument checking} -body {
    button .b
    grid configure .b
    grid content .
} -cleanup {
    grid_reset 3.2
} -result {.b}
test grid-3.3 {configure: basic argument checking} -body {
    button .b
    grid .b -row -1
} -cleanup {
    grid_reset 3.3
} -returnCodes error -result {bad row value "-1": must be a non-negative integer}
test grid-3.4 {configure: basic argument checking} -body {
    button .b
    grid .b -column -1
} -cleanup {
    grid_reset 3.4
} -returnCodes error -result {bad column value "-1": must be a non-negative integer}
test grid-3.5 {configure: basic argument checking} -body {
    button .b
    grid .b -rowspan 0
} -cleanup {
    grid_reset 3.5
} -returnCodes error -result {bad rowspan value "0": must be a positive integer}
test grid-3.6 {configure: basic argument checking} -body {
    button .b
    grid .b -columnspan 0
} -cleanup {
    grid_reset 3.6
} -returnCodes error -result {bad columnspan value "0": must be a positive integer}
test grid-3.7 {configure: basic argument checking} -body {
    frame .f
    button .f.b
    grid .f .f.b
} -cleanup {
    grid_reset 3.7
} -returnCodes error -result {can't put ".f.b" inside "."}
test grid-3.8 {configure: basic argument checking} -body {
    button .b
    grid configure x .b
    grid content .
} -cleanup {
    grid_reset 3.8
} -result {.b}
test grid-3.9 {configure: basic argument checking} -body {
    button .b
    grid configure y .b
} -cleanup {
    grid_reset 3.9
} -returnCodes error -result {invalid window shortcut, "y" should be '-', 'x', or '^'}
test grid-3.10 {ConfigureContent procedure, bad -in option} -body {
    frame .f
    grid .f -in .f
} -cleanup {
    grid_reset 3.10
} -returnCodes error -result {window can't be managed in itself}
test grid-3.11 {prevent management loops} -body {
    frame .f1
    frame .f2
    grid .f1 -in .f2
    grid .f2 -in .f1
} -cleanup {
    grid_reset 3.11
} -returnCodes error -result {can't put ".f2" inside ".f1": would cause management loop}
test grid-3.12 {prevent management loops} -body {
    frame .f1
    frame .f2
    frame .f3
    grid .f1 -in .f2
    grid .f2 -in .f3
    grid .f3 -in .f1
} -cleanup {
    grid_reset 3.12
} -returnCodes error -result {can't put ".f3" inside ".f1": would cause management loop}

test grid-4.1 {forget: basic argument checking} -body {
    grid forget foo
} -returnCodes error -result {bad window path name "foo"}

test grid-4.2 {forget} -body {
    button .c
    grid [button .b]
    set a [grid content .]
    grid forget .b .c
    lappend a [grid content .]
    return $a
} -cleanup {
    grid_reset 4.2
} -result {.b {}}
test grid-4.3 {forget} -body {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
    grid forget .c
    grid .c -row 0 -column 0
    grid info .c
} -cleanup {
    grid_reset 4.3
} -result {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}
test grid-4.4 {forget} -body {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid forget .c
    grid .c -row 0 -column 0
    grid info .c
} -cleanup {
    grid_reset 4.3.1
} -result {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}
test grid-4.5 {forget, calling Tk_UnmaintainGeometry} -body {
    frame .f -bd 2 -relief raised
    place .f -x 10 -y 20 -width 200 -height 100
    frame .f2 -width 50 -height 30 -bg red
    grid .f2 -in .f
    update
    set x [winfo ismapped .f2]
    grid forget .f2
    place .f -x 30
    update
    lappend x [winfo ismapped .f2]
} -cleanup {
    grid_reset 4.4
} -result {1 0}

test grid-5.1 {info: basic argument checking} -body {
    grid info a b
} -returnCodes error -result {wrong # args: should be "grid info window"}

test grid-5.2 {info} -body {
    frame .1 -width 75 -height 75 -bg red
    grid .1 -row 0 -column 0
    update
    grid info .x
} -cleanup {
    grid_reset 5.2
} -returnCodes error -result {bad window path name ".x"}
test grid-5.3 {info} -body {
    frame .1 -width 75 -height 75 -bg red
    grid .1 -row 0 -column 0
    update
    grid info .1
} -cleanup {
    grid_reset 5.3
} -result {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}
test grid-5.4 {info} -body {
    frame .1 -width 75 -height 75 -bg red
    update
    grid info .1
} -cleanup {
    grid_reset 5.4
} -returnCodes ok -result {}

test grid-6.1 {location: basic argument checking} -body {
    grid location .
} -returnCodes error -result {wrong # args: should be "grid location window x y"}

test grid-6.2 {location: basic argument checking} -body {
    grid location .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}

test grid-6.3 {location: basic argument checking} -body {
    grid location . x y
} -returnCodes error -result {bad screen distance "x"}

test grid-6.4 {location: basic argument checking} -body {
    grid location . 1c y
} -returnCodes error -result {bad screen distance "y"}

test grid-6.5 {location: basic argument checking} -body {
    frame .f
    grid location .f 10 10
} -cleanup {
    grid_reset 6.5
} -result {-1 -1}
test grid-6.6 {location (x)} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set got ""
    set result ""
    for {set x -10} { $x < 220} { incr x} {
	set a [grid location . $x 0]
	if {$a != $got} {
	    lappend result $x->$a
	    set got $a
	}
    }
    return $result
} -cleanup {
    grid_reset 6.6
} -result {{-10->-1 0} {0->0 0} {201->1 0}}
test grid-6.7 {location (y)} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set got ""
    set result ""
    for {set y -10} { $y < 110} { incr y} {
	set a [grid location . 0 $y]
	if {$a != $got} {
	    lappend result $y->$a
	    set got $a
	}
    }
    return $result
} -cleanup {
    grid_reset 6.7
} -result {{-10->0 -1} {0->0 0} {101->0 1}}
test grid-6.8 {location (weights)} -body {
    frame .f -width 300 -height 100 -highlightthickness 0 -bg red
    frame .a
    grid .a
    grid .f -in .a
    grid rowconfigure .f 0 -weight 1
    grid columnconfigure .f 0 -weight 1
    grid propagate .a 0
    .a configure -width 200 -height 15
    update
    set got ""
    set result ""
    for {set y -10} { $y < 210} { incr y} {
	set a [grid location . $y $y]
	if {$a != $got} {
	    lappend result $y->$a
	    set got $a
	}
    }
    return $result
} -cleanup {
    grid_reset 6.8
} -result {{-10->-1 -1} {0->0 0} {16->0 1} {201->1 1}}
test grid-6.9 {location: check updates pending} -constraints {
    nonPortable
} -body {
    set a ""
    foreach i {0 1 2} {
	frame .$i -width 120 -height 75 -bg red
	lappend a [grid location . 150 90]
	grid .$i -row $i -column $i
    }
    return $a
} -cleanup {
    grid_reset 6.9
} -result {{0 0} {1 1} {1 1}}

test grid-7.1 {propagate} -body {
    grid propagate . 1 xxx
} -cleanup {

    grid_reset 7.1
} -returnCodes error -result {wrong # args: should be "grid propagate window ?boolean?"}
test grid-7.2 {propagate} -body {
    grid propagate .
} -cleanup {
    grid_reset 7.2
} -result 1
test grid-7.3 {propagate} -body {
    grid propagate . 0;grid propagate .
} -cleanup {
    grid_reset 7.3
} -result 0
test grid-7.4 {propagate} -body {
    grid propagate .x
} -cleanup {

    grid_reset 7.4
} -returnCodes error -result {bad window path name ".x"}
test grid-7.5 {propagate} -body {
    grid propagate . x
} -cleanup {
    grid_reset 7.5
} -returnCodes error -result {expected boolean value but got "x"}
test grid-7.6 {propagate} -body {
    frame .f -width 100 -height 100 -bg red
    grid .f -row 0 -column 0
    update
    set a [winfo width .f]x[winfo height .f]
    grid propagate .f 0
    frame .g -width 75 -height 85 -bg green
    grid .g -in .f -row 0 -column 0
    update
    lappend a [winfo width .f]x[winfo height .f]
    grid propagate .f 1
    update
    lappend a [winfo width .f]x[winfo height .f]
    return $a
} -cleanup {
    grid_reset 7.6
} -result {100x100 100x100 75x85}
test grid-7.7 {propagate} -body {
    grid propagate . 1
    set res [list [grid propagate .]]
    grid propagate . 0
    lappend res [grid propagate .]
    grid propagate . 0
    lappend res [grid propagate .]
    return $res
} -cleanup {
    grid_reset 7.7
} -result [list 1 0 0]

test grid-8.1 {size} -body {
    grid size . foo
} -cleanup {

    grid_reset 8.1
} -returnCodes error -result {wrong # args: should be "grid size window"}
test grid-8.2 {size} -body {
    grid size .x
} -cleanup {

    grid_reset 8.2
} -returnCodes error -result {bad window path name ".x"}
test grid-8.3 {size} -body {
    frame .f
    grid size .f
} -cleanup {
    grid_reset 8.3
} -result {0 0}
test grid-8.4 {size} -body {
    catch {unset a}
    scale .f
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid .f -row 4 -column 5
    update
    lappend a [grid size .]
    grid .f -row 947 -column 663
    update
    lappend a [grid size .]
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    return $a
} -cleanup {
    grid_reset 8.4
} -result {{1 1} {6 5} {664 948} {1 1}}
test grid-8.5 {size} -body {
    catch {unset a}
    scale .f
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid rowconfigure . 17 -weight 1
    update
    lappend a [grid size .]
    grid columnconfigure . 63 -weight 1
    update
    lappend a [grid size .]
    grid columnconfigure . 63 -weight 0
    grid rowconfigure . 17 -weight 0
    update
    lappend a [grid size .]
    return $a
} -cleanup {
    grid_reset 8.5
} -result {{1 1} {1 18} {64 18} {1 1}}
test grid-8.6 {size} -body {
    catch {unset a}
    scale .f
    grid .f -row 10 -column 50
    update
    lappend a [grid size .]
    grid columnconfigure . 15 -weight 1
    grid columnconfigure . 30 -weight 1
|
|

|
|





<

|
|
|




|









|


|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
<

<
|
|
|
>
|
|
|
|
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|










|
|
|
|
|









|
|
|
<

|
|
|
>
|


|
|
|
|
|

|
|
|
|
|

|
|
|
|
|

|
|
|
|
|

|
|
|
|
|


|
|
|
|
|


|
|
|
|
|

|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
|
>
|


|

|
|
|
|
|
|





|
|
|
|





|
|
|
|










|
|
<

|
|
|
>
|



|
|
|
|
|



|
|
|
|
|


|
|
|
<

|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
|
|
|
|












|
|
|
|
|












|
|
|
|
|


















|
|
|
|
|
<
<
|
|
|
|
|
|
|
|
|
<

|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|












|
|
|
<
|






|
|
|
<

|
|
<
>
|
|
|
|
<
>
|
|
|

|
|
|
|
|














|
|
|
|
|















|
|
|
|
|







1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61


















62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202


203




204



















205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358


359
360
361
362
363
364
365
366
367

368
369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419

420
421
422

423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# This file is a Tcl script to test out the *NEW* "grid" command
# of Tk.  It is (almost) organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


# helper routine to return "." to a sane state after a test
# The variable GRID_VERBOSE can be used to "look" at the result
# of one or all of the tests

proc grid_reset {{test ?} {top .}} {
    global GRID_VERBOSE
    if {[info exists GRID_VERBOSE]} {
	if {$GRID_VERBOSE=="" || $GRID_VERBOSE==$test} {
	    puts -nonewline "grid test $test: "
	    flush stdout
	    gets stdin
	}
    }
    eval destroy [winfo children $top]
    update
    foreach {cols rows} [grid size .] {}
    for {set i 0} {$i <= $cols} {incr i} {
    	grid columnconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    for {set i 0} {$i <= $rows} {incr i} {
    	grid rowconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    grid propagate . 1
    grid anchor . nw
    update
}

grid_reset 0.0
wm geometry . {}

test grid-1.1 {basic argument checking} {
	list [catch grid msg] $msg
} {1 {wrong # args: should be "grid option arg ?arg ...?"}}

test grid-1.2 {basic argument checking} {
	list [catch {grid foo bar} msg] $msg
} {1 {bad option "foo": must be anchor, bbox, columnconfigure, configure, forget, info, location, propagate, remove, rowconfigure, size, or slaves}}

test grid-1.3 {basic argument checking} {
	button .b
	list [catch {grid .b -row 0 -column} msg] $msg
} {1 {extra option or option with no value}}
grid_reset 1.3

test grid-1.4 {basic argument checking} {
	button .b
	list [catch {grid configure .b - foo} msg] $msg
} {1 {unexpected parameter, "foo", in configure list. Should be window name or option}}
grid_reset 1.4



















test grid-1.5 {basic argument checking} {
	list [catch {grid .} msg] $msg
} {1 {can't manage ".": it's a top-level window}}

test grid-1.6 {basic argument checking} {
	list [catch {grid x} msg] $msg
} {1 {can't determine master window}}

test grid-1.7 {basic argument checking} {
	list [catch {grid configure x} msg] $msg
} {1 {can't determine master window}}

test grid-1.8 {basic argument checking} {
	button .b
	list [catch {grid x .b} msg] $msg
} {0 {}}
grid_reset 1.8

test grid-1.9 {basic argument checking} {
	button .b
	list [catch {grid configure x .b} msg] $msg
} {0 {}}
grid_reset 1.9



test grid-2.1 {bbox} {
	list [catch {grid bbox .} msg] $msg
} {0 {0 0 0 0}}

test grid-2.2 {bbox} {
	button .b
	grid .b
	destroy .b
	update
	list [catch {grid bbox .} msg] $msg
} {0 {0 0 0 0}}

test grid-2.3 {bbox: argument checking} {
	list [catch {grid bbox . 0 0 5} msg] $msg
} {1 {wrong # args: should be "grid bbox master ?column row ?column row??"}}

test grid-2.4 {bbox} {
	list [catch {grid bbox .bad 0 0} msg] $msg
} {1 {bad window path name ".bad"}}

test grid-2.5 {bbox} {
	list [catch {grid bbox . x 0} msg] $msg
} {1 {expected integer but got "x"}}

test grid-2.6 {bbox} {
	list [catch {grid bbox . 0 x} msg] $msg
} {1 {expected integer but got "x"}}

test grid-2.7 {bbox} {
	list [catch {grid bbox . 0 0 x 0} msg] $msg
} {1 {expected integer but got "x"}}

test grid-2.8 {bbox} {
	list [catch {grid bbox . 0 0 0 x} msg] $msg
} {1 {expected integer but got "x"}}

test grid-2.9 {bbox} {
    frame .1 -width 75 -height 75 -bg red
    frame .2 -width 90 -height 90 -bg red
    grid .1 -row 0 -column 0
    grid .2 -row 1 -column 1
    update
    set a ""
    lappend a [grid bbox .]
    lappend a [grid bbox . 0 0]
    lappend a [grid bbox . 0 0 1 1]
    lappend a [grid bbox . 1 1]
    set a
} {{0 0 165 165} {0 0 75 75} {0 0 165 165} {75 75 90 90}}
grid_reset 2.9

test grid-2.10 {bbox} {
    frame .1 -width 75 -height 75 -bg red
    frame .2 -width 90 -height 90 -bg red
    grid .1 -row 0 -column 0
    grid .2 -row 1 -column 1
    update
    set a ""
    lappend a [grid bbox . 10 10 0 0]
    lappend a [grid bbox . -2 -2 -1 -1]
    lappend a [grid bbox . 10 10 12 12]
    set a
} {{0 0 165 165} {0 0 0 0} {165 165 0 0}}
grid_reset 2.10


test grid-3.1 {configure: basic argument checking} {
    list [catch {grid configure foo} msg] $msg
} {1 {bad argument "foo": must be name of window}}

test grid-3.2 {configure: basic argument checking} {
    button .b
    grid configure .b
    grid slaves .
} {.b}
grid_reset 3.2

test grid-3.3 {configure: basic argument checking} {
    button .b
    list [catch {grid .b -row -1} msg] $msg
} {1 {bad row value "-1": must be a non-negative integer}}
grid_reset 3.3

test grid-3.4 {configure: basic argument checking} {
    button .b
    list [catch {grid .b -column -1} msg] $msg
} {1 {bad column value "-1": must be a non-negative integer}}
grid_reset 3.4

test grid-3.5 {configure: basic argument checking} {
    button .b
    list [catch {grid .b -rowspan 0} msg] $msg
} {1 {bad rowspan value "0": must be a positive integer}}
grid_reset 3.5

test grid-3.6 {configure: basic argument checking} {
    button .b
    list [catch {grid .b -columnspan 0} msg] $msg
} {1 {bad columnspan value "0": must be a positive integer}}
grid_reset 3.6

test grid-3.7 {configure: basic argument checking} {
    frame .f
    button .f.b
    list [catch {grid .f .f.b} msg] $msg
} {1 {can't put .f.b inside .}}
grid_reset 3.7

test grid-3.8 {configure: basic argument checking} {
    button .b
    grid configure x .b
    grid slaves .
} {.b}
grid_reset 3.8

test grid-3.9 {configure: basic argument checking} {
    button .b
    list [catch {grid configure y .b} msg] $msg


} {1 {invalid window shortcut, "y" should be '-', 'x', or '^'}}




grid_reset 3.9




















test grid-4.1 {forget: basic argument checking} {
    list [catch {grid forget foo} msg] $msg
} {1 {bad window path name "foo"}}

test grid-4.2 {forget} {
    button .c
    grid [button .b]
    set a [grid slaves .]
    grid forget .b .c
    lappend a [grid slaves .]
    set a
} {.b {}}
grid_reset 4.2

test grid-4.3 {forget} {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
    grid forget .c
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}
grid_reset 4.3

test grid-4.3.1 {forget} {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid forget .c
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}
grid_reset 4.3.1

test grid-4.4 {forget, calling Tk_UnmaintainGeometry} {
    frame .f -bd 2 -relief raised
    place .f -x 10 -y 20 -width 200 -height 100
    frame .f2 -width 50 -height 30 -bg red
    grid .f2 -in .f
    update
    set x [winfo ismapped .f2]
    grid forget .f2
    place .f -x 30
    update
    lappend x [winfo ismapped .f2]
} {1 0}
grid_reset 4.4


test grid-5.1 {info: basic argument checking} {
	list [catch {grid info a b} msg] $msg
} {1 {wrong # args: should be "grid info window"}}

test grid-5.2 {info} {
    frame .1 -width 75 -height 75 -bg red
    grid .1 -row 0 -column 0
    update
    list [catch {grid info .x} msg] $msg
} {1 {bad window path name ".x"}}
grid_reset 5.2

test grid-5.3 {info} {
    frame .1 -width 75 -height 75 -bg red
    grid .1 -row 0 -column 0
    update
    list [catch {grid info .1} msg] $msg
} {0 {-in . -column 0 -row 0 -columnspan 1 -rowspan 1 -ipadx 0 -ipady 0 -padx 0 -pady 0 -sticky {}}}
grid_reset 5.3

test grid-5.4 {info} {
    frame .1 -width 75 -height 75 -bg red
    update
    list [catch {grid info .1} msg] $msg
} {0 {}}
grid_reset 5.4


test grid-6.1 {location: basic argument checking} {
	list [catch "grid location ." msg] $msg
} {1 {wrong # args: should be "grid location master x y"}}

test grid-6.2 {location: basic argument checking} {
	list [catch "grid location .bad 0 0" msg] $msg
} {1 {bad window path name ".bad"}}

test grid-6.3 {location: basic argument checking} {
	list [catch "grid location . x y" msg] $msg
} {1 {bad screen distance "x"}}

test grid-6.4 {location: basic argument checking} {
	list [catch "grid location . 1c y" msg] $msg
} {1 {bad screen distance "y"}}

test grid-6.5 {location: basic argument checking} {
	frame .f
	grid location .f 10 10
} {-1 -1}
grid_reset 6.5

test grid-6.6 {location (x)} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set got ""
    set result ""
    for {set x -10} { $x < 220} { incr x} {
	set a [grid location . $x 0]
	if {$a != $got} {
	    lappend result $x->$a
	    set got $a
	}
    }
    set result
} {{-10->-1 0} {0->0 0} {201->1 0}}
grid_reset 6.6

test grid-6.7 {location (y)} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set got ""
    set result ""
    for {set y -10} { $y < 110} { incr y} {
	set a [grid location . 0 $y]
	if {$a != $got} {
	    lappend result $y->$a
	    set got $a
	}
    }
    set result
} {{-10->0 -1} {0->0 0} {101->0 1}}
grid_reset 6.7

test grid-6.8 {location (weights)} {
    frame .f -width 300 -height 100 -highlightthickness 0 -bg red
    frame .a
    grid .a
    grid .f -in .a
    grid rowconfigure .f 0 -weight 1
    grid columnconfigure .f 0 -weight 1
    grid propagate .a 0
    .a configure -width 200 -height 15
    update
    set got ""
    set result ""
    for {set y -10} { $y < 210} { incr y} {
	set a [grid location . $y $y]
	if {$a != $got} {
	    lappend result $y->$a
	    set got $a
	}
    }
    set result
} {{-10->-1 -1} {0->0 0} {16->0 1} {201->1 1}}
grid_reset 6.8

test grid-6.9 {location: check updates pending} {nonPortable} {


	set a ""
	foreach i {0 1 2} {
	    frame .$i -width 120 -height 75 -bg red
	    lappend a [grid location . 150 90]
	    grid .$i -row $i -column $i
	}
	set a
} {{0 0} {1 1} {1 1}}
grid_reset 6.9


test grid-7.1 {propagate} {
    list [catch {grid propagate . 1 xxx} msg] $msg

} {1 {wrong # args: should be "grid propagate window ?boolean?"}}
grid_reset 7.1

test grid-7.2 {propagate} {
    list [catch {grid propagate .} msg] $msg
} {0 1}
grid_reset 7.2

test grid-7.3 {propagate} {
    list [catch {grid propagate . 0;grid propagate .} msg] $msg
} {0 0}
grid_reset 7.3

test grid-7.4 {propagate} {
    list [catch {grid propagate .x} msg] $msg

} {1 {bad window path name ".x"}}
grid_reset 7.4

test grid-7.5 {propagate} {
    list [catch {grid propagate . x} msg] $msg
} {1 {expected boolean value but got "x"}}
grid_reset 7.5

test grid-7.6 {propagate} {
    frame .f -width 100 -height 100 -bg red
    grid .f -row 0 -column 0
    update
    set a [winfo width .f]x[winfo height .f]
    grid propagate .f 0
    frame .g -width 75 -height 85 -bg green
    grid .g -in .f -row 0 -column 0
    update
    lappend a [winfo width .f]x[winfo height .f]
    grid propagate .f 1
    update
    lappend a [winfo width .f]x[winfo height .f]
    set a
} {100x100 100x100 75x85}
grid_reset 7.6

test grid-7.7 {propagate} {
    grid propagate . 1
    set res [list [grid propagate .]]
    grid propagate . 0
    lappend res [grid propagate .]
    grid propagate . 0
    lappend res [grid propagate .]
    set res
} [list 1 0 0]
grid_reset 7.7


test grid-8.1 {size} {
    list [catch {grid size . foo} msg] $msg

} {1 {wrong # args: should be "grid size window"}}
grid_reset 8.1

test grid-8.2 {size} {
    list [catch {grid size .x} msg] $msg

} {1 {bad window path name ".x"}}
grid_reset 8.2

test grid-8.3 {size} {
    frame .f
    list [catch {grid size .f} msg] $msg
} {0 {0 0}}
grid_reset 8.3

test grid-8.4 {size} {
    catch {unset a}
    scale .f
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid .f -row 4 -column 5
    update
    lappend a [grid size .]
    grid .f -row 947 -column 663
    update
    lappend a [grid size .]
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    set a
} {{1 1} {6 5} {664 948} {1 1}}
grid_reset 8.4

test grid-8.5 {size} {
    catch {unset a}
    scale .f
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid rowconfigure . 17 -weight 1
    update
    lappend a [grid size .]
    grid columnconfigure . 63 -weight 1
    update
    lappend a [grid size .]
    grid columnconfigure . 63 -weight 0
    grid rowconfigure . 17 -weight 0
    update
    lappend a [grid size .]
    set a
} {{1 1} {1 18} {64 18} {1 1}}
grid_reset 8.5

test grid-8.6 {size} {
    catch {unset a}
    scale .f
    grid .f -row 10 -column 50
    update
    lappend a [grid size .]
    grid columnconfigure . 15 -weight 1
    grid columnconfigure . 30 -weight 1
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524

525
526
527

528
529
530

531
532
533

534
535
536

537
538
539

540
541
542

543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577

578
579
580
581
582

583
584
585
586
587

588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766

767
768
769
770
771

772

773
774
775

776
777
778

779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831

832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854

855
856
857

858
859
860
861
862
863

864
865
866
867
868
869

870
871
872
873
874
875

876
877
878
879
880
881

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123


1124
1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163

1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585

1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
1638
1639


1640
1641
1642
1643

1644
1645

1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664


1665
1666
1667
1668

1669
1670

1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687


1688
1689
1690
1691

1692
1693

1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710


1711
1712
1713
1714
1715
1716
1717

1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737


1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765

1766
1767
1768

1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815
1816
1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926
1927
1928
1929

1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941


1942
1943
1944
1945
1946
1947
1948
1949

1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973

1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990

1991
1992
1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
    lappend a [grid size .]
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid columnconfigure . 15 -weight 0
    update
    lappend a [grid size .]
    return $a
} -cleanup {
    grid_reset 8.6
} -result {{51 11} {51 11} {31 11} {21 11} {16 1} {1 1}}

test grid-9.1 {content} -body {
    grid content .

} -returnCodes ok -result {}
test grid-9.2 {content} -body {
    grid content .foo
} -returnCodes error -result {bad window path name ".foo"}

test grid-9.3 {content} -body {
    grid content a b
} -returnCodes error -result {wrong # args: should be "grid content window ?-option value ...?"}

test grid-9.4 {content} -body {
    grid content . a b
} -returnCodes error -result {bad option "a": must be -column or -row}

test grid-9.5 {content} -body {
    grid content . -column x
} -returnCodes error -result {expected integer but got "x"}

test grid-9.6 {content} -body {
    grid content . -row -3
} -returnCodes error -result {-3 is an invalid value: should NOT be < 0}

test grid-9.7 {content} -body {
    grid content . -foo 3
} -returnCodes error -result {bad option "-foo": must be -column or -row}

test grid-9.8 {content} -body {
    grid content .x -row 3
} -returnCodes error -result {bad window path name ".x"}

test grid-9.9 {content} -body {
    grid content . -row 3

} -returnCodes ok -result {}
test grid-9.10 {content} -body {
    foreach i {0 1 2} {
	label .$i -text $i
	grid .$i -row $i -column $i
    }
    grid content .
} -cleanup {
    grid_reset 9.10
} -result {.2 .1 .0}
test grid-9.11 {content} -body {
    catch {unset a}
    foreach i {0 1 2} {
	label .$i -text $i
	label .$i-x -text $i-x
	grid .$i -row $i -column $i
	grid .$i-x -row $i -column [incr i]
    }
    foreach row {0 1 2 3} {
	lappend a $row{[grid content . -row $row]}
    }
    foreach col {0 1 2 3} {
	lappend a $col{[grid content . -column $col]}
    }
    return $a
} -cleanup {
    grid_reset 9.11
} -result {{0{.0-x .0}} {1{.1-x .1}} {2{.2-x .2}} 3{} 0{.0} {1{.1 .0-x}} {2{.2 .1-x}} 3{.2-x}}

# column/row configure

test grid-10.1 {column/row configure} -body {
    grid columnconfigure .
} -cleanup {

    grid_reset 10.1
} -returnCodes error -result {wrong # args: should be "grid columnconfigure window index ?-option value ...?"}
test grid-10.2 {column/row configure} -body {
    grid columnconfigure . 0 -weight 0 -pad
} -cleanup {

    grid_reset 10.2
} -returnCodes error -result {wrong # args: should be "grid columnconfigure window index ?-option value ...?"}
test grid-10.3 {column/row configure} -body {
    grid columnconfigure .f 0 -weight
} -cleanup {

    grid_reset 10.3
} -returnCodes error -result {bad window path name ".f"}
test grid-10.4 {column/row configure} -body {
    grid columnconfigure . nine -weight
} -cleanup {

    grid_reset 10.4
} -returnCodes error -result {expected integer but got "nine" (when retrieving options only integer indices are allowed)}
test grid-10.5 {column/row configure} -body {
    grid columnconfigure . 265 -weight
} -cleanup {
    grid_reset 10.5
} -result 0
test grid-10.6 {column/row configure} -body {
    grid columnconfigure . 0
} -cleanup {
    grid_reset 10.6
} -result {-minsize 0 -pad 0 -uniform {} -weight 0}
test grid-10.7 {column/row configure} -body {
    grid columnconfigure . 0 -foo
} -cleanup {
    grid_reset 10.7
} -returnCodes error -result {bad option "-foo": must be -minsize, -pad, -uniform, or -weight}
test grid-10.8 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.8
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.9 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.9
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.10 {column/row configure} -body {
    grid columnconfigure . 0 -minsize 10
    grid columnconfigure . 0 -minsize
} -cleanup {
    grid_reset 10.10
} -result 10
test grid-10.11 {column/row configure} -body {
    grid columnconfigure . 0 -weight bad
} -cleanup {
    grid_reset 10.11
} -returnCodes error -result {expected integer but got "bad"}
test grid-10.12 {column/row configure} -body {
    grid columnconfigure . 0 -weight -3
} -cleanup {
    grid_reset 10.12
} -returnCodes error -result {invalid arg "-weight": should be non-negative}
test grid-10.13 {column/row configure} -body {
    grid columnconfigure . 0 -weight 3
    grid columnconfigure . 0 -weight
} -cleanup {
    grid_reset 10.13
} -result 3
test grid-10.14 {column/row configure} -body {
    grid columnconfigure . 0 -pad foo
} -cleanup {
    grid_reset 10.14
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.15 {column/row configure} -body {
    grid columnconfigure . 0 -pad -3
} -cleanup {
    grid_reset 10.15
} -returnCodes error -result {invalid arg "-pad": should be non-negative}
test grid-10.16 {column/row configure} -body {
    grid columnconfigure . 0 -pad 3
    grid columnconfigure . 0 -pad
} -cleanup {
    grid_reset 10.16
} -result 3
test grid-10.17 {column/row configure} -body {
    frame .f
    set a ""
    grid columnconfigure .f 0 -weight 0
    lappend a [grid columnconfigure .f 0 -weight]
    grid columnconfigure .f 0 -weight 1
    lappend a [grid columnconfigure .f 0 -weight]
    grid rowconfigure .f 0 -weight 0
    lappend a [grid rowconfigure .f 0 -weight]
    grid rowconfigure .f 0 -weight 1
    lappend a [grid columnconfigure .f 0 -weight]
    grid columnconfigure .f 0 -weight 0
    return $a
} -cleanup {
    grid_reset 10.17
} -result {0 1 0 1}
test grid-10.18 {column/row configure} -body {
    frame .f
    grid columnconfigure .f {0 2} -minsize 10 -weight 1
    list [grid columnconfigure .f 0 -minsize] \
	[grid columnconfigure .f 1 -minsize] \
	[grid columnconfigure .f 2 -minsize] \
	[grid columnconfigure .f 0 -weight] \
	[grid columnconfigure .f 1 -weight] \
	[grid columnconfigure .f 2 -weight]
} -cleanup {
    grid_reset 10.18
} -result {10 0 10 1 0 1}
test grid-10.19 {column/row configure} -body {
    grid columnconfigure . {0 -1 2} -weight 1
} -cleanup {
    grid_reset 10.19
} -returnCodes error -result {"-1" is out of range}
test grid-10.20 {column/row configure} -body {
    grid columnconfigure . 0 -uniform foo
    grid columnconfigure . 0 -uniform
} -cleanup {
    grid_reset 10.20
} -result {foo}
test grid-10.21 {column/row configure} -body {
    grid columnconfigure . .b -weight 1
} -cleanup {
    grid_reset 10.21
} -returnCodes error -result {illegal index ".b"}
test grid-10.22 {column/row configure} -body {
    button .b
    grid columnconfigure . .b -weight 1
} -cleanup {
    grid_reset 10.22
} -returnCodes error -result {the window ".b" is not managed by "."}
test grid-10.23 {column/row configure} -body {
    button .b
    grid .b -column 1 -columnspan 2
    grid columnconfigure . .b -weight 1
    set res {}
    foreach i {0 1 2 3} {
        lappend res [grid columnconfigure . $i -weight]
    }
    return $res
} -cleanup {
    grid_reset 10.23
} -result {0 1 1 0}
test grid-10.24 {column/row configure} -body {
    button .b
    button .c
    button .d
    grid .b -column 1 -columnspan 2
    grid .c -column 2 -columnspan 3
    grid .d -column 4 -columnspan 2
    grid columnconfigure . {.b .d} -weight 1
    grid columnconfigure . .c -weight 2
    set res {}
    foreach i {0 1 2 3 4 5 6} {
        lappend res [grid columnconfigure . $i -weight]
    }
    return $res
} -cleanup {
    grid_reset 10.24
} -result {0 1 2 2 2 1 0}
test grid-10.25 {column/row configure} -body {
    button .b
    button .c
    button .d
    grid .b -row 1 -rowspan 2
    grid .c -row 2 -rowspan 3
    grid .d -row 4 -rowspan 2
    grid rowconfigure . {7 all} -weight 1
    grid rowconfigure . {1 .d} -weight 2
    set res {}
    foreach i {0 1 2 3 4 5 6 7} {
        lappend res [grid rowconfigure . $i -weight]
    }
    return $res
} -cleanup {
    grid_reset 10.25
} -result {0 2 1 1 2 2 0 1}
test grid-10.26 {column/row configure} -body {
    button .b
    grid columnconfigure .b 0
} -cleanup {
    grid_reset 10.26
} -result {-minsize 0 -pad 0 -uniform {} -weight 0}
test grid-10.27 {column/row configure - no indices} -body {
    # Bug 1422430
    set t [toplevel .test]
    grid columnconfigure $t "" -weight 1
} -cleanup {
    destroy $t

} -returnCodes error -result {no column indices specified}

test grid-10.28 {column/row configure - no indices} -body {
    set t [toplevel .test]
    grid rowconfigure $t "" -weight 1
} -cleanup {
    destroy $t

} -returnCodes error -result {no row indices specified}

test grid-10.29 {column/row configure - invalid indices} -body {
    grid columnconfigure . {0 1 2} -weight
} -returnCodes error -result {must specify a single element on retrieval}

test grid-10.30 {column/row configure - invalid indices} -body {
    grid rowconfigure . {0 1 2} -weight
} -returnCodes error -result {must specify a single element on retrieval}

test grid-10.31 {column/row configure - empty 'all' configure} -body {
    # Bug 1422430
    set t [toplevel .test]
    grid rowconfigure $t all -weight 1
    destroy $t

} -result {}
test grid-10.32 {column/row configure} -body {
    # Test that no lingering message is there
    frame .f
    set res    [grid columnconfigure .f all -weight 1]
    append res [grid columnconfigure .f {0 all} -weight 1]
    frame .f.f
    grid .f.f
    append res [grid columnconfigure .f {.f.f} -weight 1]
    append res [grid columnconfigure .f {.f.f 1} -weight 1]
    append res [grid columnconfigure .f {2 .f.f} -weight 1]
    destroy .f
    return $res
} -cleanup {
    grid_reset 10.35
} -result {}
test grid-10.33 {column/row configure} -body {
    grid columnconfigure . all
} -cleanup {
    grid_reset 10.36
} -returnCodes error -result {expected integer but got "all" (when retrieving options only integer indices are allowed)}
test grid-10.34 {column/row configure} -body {
    grid columnconfigure . 100000
} -cleanup {
    grid_reset 10.37
} -result {-minsize 0 -pad 0 -uniform {} -weight 0}
test grid-10.35 {column/row configure} -body {
    # This is a test for bug 1423666 where a column >= 10000 caused
    # a crash in layout.  The update is needed to reach the layout stage.
    # Test different combinations of row/column overflow
    frame .f
    set res {}
    lappend res [catch {grid .f -row 10 -column 9999} msg] $msg ; update
    lappend res [catch {grid .f -row 9999 -column 10} msg] $msg ; update
    lappend res [catch {grid .f -columnspan 2 -column 9998} msg] $msg ; update
    lappend res [catch {grid .f -rowspan 2 -row 9998} msg] $msg ; update
    lappend res [catch {grid .f -column 9998 -columnspan 2} msg] $msg ; update
    lappend res [catch {grid .f -row 9998 -rowspan 2} msg] $msg ; update
    return $res
} -cleanup {destroy .f} -result [lrange {
    1 {column out of bounds}
    1 {row out of bounds}
    1 {column out of bounds}
    1 {row out of bounds}
    1 {column out of bounds}
    1 {row out of bounds}
} 0 end]
grid_reset 10.38

test grid-10.36 {column/row configure} -body {
    # Additional tests for row/column overflow
    frame .f
    frame .g
    set res {}
    grid .f -row 9998 -column 0
    lappend res [catch {grid ^ -in .} msg] $msg  ; update
    lappend res [catch {grid .g} msg] $msg  ; update
    grid forget .f .g
    lappend res [catch {grid .f - -column 9998} msg] $msg ; update
    grid forget .f .g
    lappend res [catch {eval grid [string repeat " x " 9999] .f} msg] $msg
    update
    return $res
} -cleanup {destroy .f .g} -result [lrange {
    1 {row out of bounds}
    1 {row out of bounds}
    1 {column out of bounds}
    1 {column out of bounds}
} 0 end]
grid_reset 10.39

# auto-placement tests

test grid-11.1 {default widget placement} -body {
    grid ^
} -cleanup {

    grid_reset 11.1
} -returnCodes error -result {can't use '^', can't find container window}
test grid-11.2 {default widget placement} -body {
    button .b
    grid .b ^
} -cleanup {

    grid_reset 11.2
} -returnCodes error -result {can't find content to extend with "^"}
test grid-11.3 {default widget placement} -body {
    button .b
    grid .b - - .c
} -cleanup {

    grid_reset 11.3
} -returnCodes error -result {bad window path name ".c"}
test grid-11.4 {default widget placement} -body {
    button .b
    grid .b - - = -
} -cleanup {

    grid_reset 11.4
} -returnCodes error -result {invalid window shortcut, "=" should be '-', 'x', or '^'}
test grid-11.5 {default widget placement} -body {
    button .b
    grid .b - x -
} -cleanup {

    grid_reset 11.5
} -returnCodes error -result {must specify window before shortcut '-'}
test grid-11.6 {default widget placement} -body {
    foreach i {1 2 3 4 5 6} {
	frame .f$i -width 50 -height 50 -highlightthickness 0 -bg red
    }
    grid .f1 .f2 .f3 .f4
    grid .f5   -  x  .f6 -sticky nsew
    update
    set a ""
    foreach i {5 6} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.6
} -result {{0,50  100,50} {150,50  50,50}}
test grid-11.7 {default widget placement} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    grid .f x -
} -cleanup {
    grid_reset 11.7
} -returnCodes error -result {must specify window before shortcut '-'}
test grid-11.8 {default widget placement} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    grid .f ^ -
} -cleanup {
    grid_reset 11.8
} -returnCodes error -result {must specify window before shortcut '-'}
test grid-11.9 {default widget placement} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    grid .f x ^
} -cleanup {
    grid_reset 11.9
} -returnCodes error -result {can't find content to extend with "^"}
test grid-11.10 {default widget placement} -body {
    foreach i {1 2 3} {
	frame .f$i -width 100 -height 50 -highlightthickness 0 -bg red
    }
    grid .f1 .f2  -sticky nsew
    grid .f3   ^  -sticky nsew
    update
    set a ""
    foreach i {1 2 3} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.10
} -result {{0,0  100,50} {100,0  100,100} {0,50  100,50}}
test grid-11.11 {default widget placement} -body {
    foreach i {1 2 3 4 5 6 7 8 9 10 11 12} {
	frame .f$i -width 50 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2  .f3 .f4  -sticky nsew
    grid .f5  .f6   -  .f7  -sticky nsew
    grid .f8    ^   ^  .f9  -sticky nsew
    grid .f10   ^   ^  .f11 -sticky nsew
    grid .f12   -   -   -   -sticky nsew
    update
    set a ""
    foreach i {5 6 7 8 9 10 11 12 } {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.11
} -result {{0,50  50,50} {50,50  100,150} {150,50  50,50} {0,100  50,50} {150,100  50,50} {0,150  50,50} {150,150  50,50} {0,200  200,50}}
test grid-11.12 {default widget placement} -body {
    foreach i {1 2 3 4} {
	frame .f$i -width 75 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2   .f3     -sticky nsew
    grid .f4    ^           -sticky nsew
    update
    set a ""
    foreach i {1 2 3 4} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    grid .f4    ^   -column 1
    update
    foreach i {1 2 3 4} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.12
} -result {{0,0  75,50} {75,0  75,100} {150,0  75,50} {0,50  75,50} {0,0  75,50} {75,0  75,100} {150,0  75,100} {75,50  75,50}}
test grid-11.13 {default widget placement} -body {
    foreach i {1 2 3 4 5 6 7} {
	frame .f$i -width 40 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2  .f3 .f4 .f5 -sticky nsew
    grid .f6    -  .f7         -sticky nsew -columnspan 2
    update
    set a ""
    foreach i {6 7} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.13
} -result {{0,50  120,50} {120,50  80,50}}
test grid-11.14 {default widget placement} -body {
    foreach i {1 2 3} {
	frame .f$i -width 60 -height 60 -highlightthickness 0 -bg red
    }
    grid .f1 .f2
    grid  ^  .f3
    update
    set a ""
    foreach i {1 2 3} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.14
} -result {{0,30  60,60} {60,0  60,60} {60,60  60,60}}
test grid-11.15 {^ ^ test with multiple windows} -body {
    foreach i {1 2 3 4} {
	frame .f$i -width 50 -height 50 -bd 1 -relief solid
    }
    grid .f1 .f2 .f3 -sticky ns
    grid .f4 ^ ^
    update
    set a ""
    foreach i {1 2 3 4} {
	lappend a "[winfo x .f$i],[winfo y .f$i]\
		[winfo width .f$i],[winfo height .f$i]"
    }
    return $a
} -cleanup {
    grid_reset 11.15
} -result {{0,0 50,50} {50,0 50,100} {100,0 50,100} {0,50 50,50}}
test grid-11.16 {default widget placement} -body {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  x  ^  x .e -sticky news
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
} -cleanup {
    grid_reset 11.16
} -result {50 100 50}
test grid-11.17 {default widget placement} -body {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  ^  x  ^ .e -sticky news
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
} -cleanup {
    grid_reset 11.17
} -result {100 50 100}
test grid-11.18 {default widget placement} -body {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  ^  ^  ^  x -in .           ;# ^ and no child should work with -in.
    grid rowconfigure . {0 1} -uniform a
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
    lappend res [winfo height .d]
} -cleanup {
    grid_reset 11.18
} -result {100 100 100 50}
test grid-11.19 {default widget placement} -body {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b -sticky news
    grid .c .d -sticky news
    grid ^     -in . -row 2
    grid x  ^  -in . -row 1

    grid rowconfigure . {0 1 2} -uniform a
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
    lappend res [winfo height .d]
} -cleanup {
    grid_reset 11.19
} -result {50 100 100 50}

test grid-12.1 {-sticky} -body {
    catch {unset data}
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    set a ""
    grid .f
    grid rowconfigure . 0 -weight 1
    grid columnconfigure . 0 -weight 1
    grid propagate . 0
    . configure -width 250 -height 150
    foreach i { {} n s e w ns ew nw ne se sw nse nsw sew new nsew} {
	grid .f -sticky $i
	update
	array set data [grid info .f]
	append a "($data(-sticky)) [winfo x .f] [winfo y .f] [winfo width .f] [winfo height .f]\n"
    }
    return $a
} -cleanup {
    grid_reset 12.1
} -result {() 25 25 200 100
(n) 25 0 200 100
(s) 25 50 200 100
(e) 50 25 200 100
(w) 0 25 200 100
(ns) 25 0 200 150
(ew) 0 25 250 100
(nw) 0 0 200 100
(ne) 50 0 200 100
(es) 50 50 200 100
(sw) 0 50 200 100
(nes) 50 0 200 150
(nsw) 0 0 200 150
(esw) 0 50 250 100
(new) 0 0 250 100
(nesw) 0 0 250 150
}


test grid-12.2 {-sticky} -body {
    frame .f -bg red
    grid .f -sticky glue
} -cleanup {

    grid_reset 12.2
} -returnCodes error -result {bad stickyness value "glue": must be a string containing n, e, s, and/or w}
test grid-12.3 {-sticky} -body {
    frame .f -bg red
    grid .f -sticky {n,s,e,w}
    array set A [grid info .f]
    set A(-sticky)
} -cleanup {
    grid_reset 12.3
} -result {nesw}

test grid-13.1 {-in} -body {
    frame .f -bg red
    grid .f -in .f
} -cleanup {

    grid_reset 13.1
} -returnCodes error -result {window can't be managed in itself}
test grid-13.2 {-in} -body {
    frame .f -bg red
    list [winfo manager .f] \
         [catch {grid .f -in .f} err] $err \
         [winfo manager .f]
} -cleanup {
    grid_reset 13.1.1
} -result {{} 1 {window can't be managed in itself} {}}
test grid-13.3 {-in} -body {
    frame .f -bg red
    grid .f -in .bad
} -cleanup {
    grid_reset 13.2
} -returnCodes error -result {bad window path name ".bad"}
test grid-13.4 {-in} -body {
    frame .f -bg red
    toplevel .top
    grid .f -in .top
} -cleanup {

    grid_reset 13.3
} -returnCodes error -result {can't put ".f" inside ".top"}
destroy .top
test grid-13.5 {-ipadx} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -ipadx x
} -cleanup {
    grid_reset 13.4
} -returnCodes error -result {bad ipadx value "x": must be positive screen distance}
test grid-13.6 {-ipadx} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -ipadx {5 5}
} -cleanup {
    grid_reset 13.4.1
} -returnCodes error -result {bad ipadx value "5 5": must be positive screen distance}
test grid-13.7 {-ipadx} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a [winfo width .f]
    grid .f -ipadx 1
    update
    list $a [winfo width .f]
} -cleanup {
    grid_reset 13.5
} -result {200 202}
test grid-13.8 {-ipady} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -ipady x
} -cleanup {
    grid_reset 13.6
} -returnCodes error -result {bad ipady value "x": must be positive screen distance}
test grid-13.9 {-ipady} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -ipady {5 5}
} -cleanup {
    grid_reset 13.6.1
} -returnCodes error -result {bad ipady value "5 5": must be positive screen distance}
test grid-13.10 {-ipady} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a [winfo height .f]
    grid .f -ipady 1
    update
    list $a [winfo height .f]
} -cleanup {
    grid_reset 13.7
} -result {100 102}
test grid-13.11 {-padx} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -padx x
} -cleanup {
    grid_reset 13.8
} -returnCodes error -result {bad pad value "x": must be positive screen distance}
test grid-13.12 {-padx} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -padx {10 x}
} -cleanup {
    grid_reset 13.8.1
} -returnCodes error -result {bad 2nd pad value "x": must be positive screen distance}
test grid-13.13 {-padx} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo width .f] [winfo width .]"
    grid .f -padx 1
    update
    list $a "[winfo width .f] [winfo width .] [winfo x .f]"
} -cleanup {
    grid_reset 13.9
} -result {{200 200} {200 202 1}}
test grid-13.14 {-padx} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo width .f] [winfo width .]"
    grid .f -padx {10 5}
    update
    list $a "[winfo width .f] [winfo width .] [winfo x .f]"
} -cleanup {
    grid_reset 13.9.1
} -result {{200 200} {200 215 10}}
test grid-13.15 {-pady} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -pady x
} -cleanup {
    grid_reset 13.10
} -returnCodes error -result {bad pad value "x": must be positive screen distance}
test grid-13.16 {-pady} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -pady {10 x}
} -cleanup {
    grid_reset 13.10.1
} -returnCodes error -result {bad 2nd pad value "x": must be positive screen distance}
test grid-13.17 {-pady} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo height .f] [winfo height .]"
    grid .f -pady 1
    update
    list $a "[winfo height .f] [winfo height .] [winfo y .f]"
} -cleanup {
    grid_reset 13.11
} -result {{100 100} {100 102 1}}
test grid-13.18 {-pady} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo height .f] [winfo height .]"
    grid .f -pady {4 16}
    update
    list $a "[winfo height .f] [winfo height .] [winfo y .f]"
} -cleanup {
    grid_reset 13.11.1
} -result {{100 100} {100 120 4}}
test grid-13.19 {-ipad x and y} -body {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid columnconfigure . 0 -minsize 150
    grid rowconfigure . 0 -minsize 100
    set a ""
    foreach x {0 5} {
	foreach y {0 5} {
	    grid .f -ipadx $x -ipady $y
	    update
	    append a " $x,$y:"
	    foreach prop {x y width height} {
		append a ,[winfo $prop .f]
	    }
	}
    }
    return $a
} -cleanup {
    grid_reset 13.12
} -result { 0,0:,65,40,20,20 0,5:,65,35,20,30 5,0:,60,40,30,20 5,5:,60,35,30,30}
test grid-13.20 {reparenting} -body {
    frame .1
    frame .2
    button .b
    grid .1 .2
    grid .b -in .1
    set a ""
    catch {unset info}; array set info [grid info .b]
    lappend a [grid content .1],[grid content .2],$info(-in)
    grid .b -in .2
    catch {unset info}; array set info [grid info .b]
    lappend a [grid content .1],[grid content .2],$info(-in)
    unset info
    return $a
} -cleanup {
    grid_reset 13.13
} -result {.b,,.1 ,.b,.2}

test grid-14.1 {structure notify} -body {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    frame .g -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    grid .g -in .f
    update
    set a ""
    lappend a "[winfo x .g],[winfo y .g] \
        [winfo width .g],[winfo height .g]"
    .f configure -bd 5 -relief raised
    update
    lappend a "[winfo x .g],[winfo y .g] \
        [winfo width .g],[winfo height .g]"
    return $a
} -cleanup {
    grid_reset 14.1
} -result {{0,0  200,100} {5,5  200,100}}
test grid-14.2 {structure notify} -body {
    frame .f -width 200 -height 100
    frame .f.g -width 200 -height 100
    grid .f
    grid .f.g
    update
    set a ""
    lappend a [grid bbox .],[grid bbox .f]
    .f config -bd 20
    update
    lappend a [grid bbox .],[grid bbox .f]
} -cleanup {
    grid_reset 14.2
} -result {{0 0 200 100,0 0 200 100} {0 0 240 140,20 20 200 100}}
test grid-14.3 {map notify: bug 1648} -constraints {nonPortable} -body {
    # This test is nonPortable because the number of times
    # A(.) will be incremented is unspecified--the behavior
    # is different accross window managers.
    global A
    catch {unset A}
    bind . <Configure> {incr A(%W)}
    set A(.) 0
    foreach i {0 1 2} {
	frame .$i -width 100 -height 75
	set A(.$i) 0
    }
    grid .0 .1 .2
    update
    bind <Configure> .1 {destroy .0}
    .2 configure -bd 10
    update
    bind . <Configure> {}
    array get A
} -cleanup {
    grid_reset 14.3
} -result {.2 2 .0 1 . 2 .1 1}

test grid-15.1 {lost content} -body {
    button .b
    grid .b
    set a [grid content .]
    pack .b
    lappend a [grid content .]
    grid .b
    lappend a [grid content .]
} -cleanup {
    grid_reset 15.1
} -result {.b {} .b}
test grid-15.2 {lost content} -body {
    frame .f
    grid .f
    button .b
    grid .b -in .f
    set a [grid content .f]
    pack .b -in .f
    lappend a [grid content .f]
    grid .b -in .f
    lappend a [grid content .f]
} -cleanup {
    grid_reset 15.2
} -result {.b {} .b}

test grid-16.1 {layout centering} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid anchor . center
    . configure -width 300 -height 250
    update
    grid bbox .
} -cleanup {
    grid_reset 16.1
} -result {37 50 225 150}
test grid-16.2 {layout weights (expanding)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
	grid rowconfigure . $i -weight [expr $i + 1]
	grid columnconfigure . $i -weight [expr $i + 1]
    }
    grid propagate . 0
    . configure -width 500 -height 300
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.2
} -result {120-75 167-100 213-125}
test grid-16.3 {layout weights (shrinking)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
	grid rowconfigure . $i -weight [expr $i + 1]
	grid columnconfigure . $i -weight [expr $i + 1]
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.3
} -result {84-63 66-50 50-37}
test grid-16.4 {layout weights (shrinking with minsize)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
	grid rowconfigure . $i -weight [expr $i + 1] -minsize 45
	grid columnconfigure . $i -weight [expr $i + 1] -minsize 65
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.4
} -result {70-60 65-45 65-45}
test grid-16.5 {layout weights (shrinking at minsize)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
	grid rowconfigure . $i -weight 0 -minsize 70
	grid columnconfigure . $i -weight 0 -minsize 90
    }
    grid propagate . 0
    . configure -width 100 -height 75
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.5
} -result {100-75 100-75 100-75}

test grid-16.6 {layout weights (shrinking at minsize)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
	grid rowconfigure . $i -weight [expr $i + 1] -minsize 52
	grid columnconfigure . $i -weight [expr $i + 1] -minsize 69
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.6
} -result {69-52 69-52 69-52}
# test fails when run alone
# reason (I think): -minsize 0 causes both:
# [winfo ismapped .$i] => 0 and
# not responding for width ang height settings, so that
# [winfo width .$i] [winfo height .$i] take different values
# That doesn't happen if previous tests run
test grid-16.7 {layout weights (shrinking at minsize)} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid columnconfigure . 1 -weight 1 -minsize 0
    grid rowconfigure . 1 -weight 1 -minsize 0
    . configure -width 100 -height 1
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.7
} -result {100-75-1 1-1-0 100-75-1}
test grid-16.8 {layout internal constraints} -body {
    foreach i {0 1 2 3 4} {
	frame .$i -bg gray  -width 30 -height 25 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
    }
    frame .f -bg red -width 250 -height 200
    frame .g -bg green -width 200 -height 180
    lower .f
    raise .g .f
    grid .f -row 1 -column 1 -rowspan 3 -columnspan 3 -sticky nswe
    grid .g -row 1 -column 1 -rowspan 2 -columnspan 2 -sticky nswe
    update
    set a ""
    foreach i {0 1 2 3 4} {
	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .f
    update
    foreach i {0 1 2 3 4} {
	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .g
    grid .f
    update
    foreach i {0 1 2 3 4} {
	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .f
    update
    foreach i {0 1 2 3 4} {
	append a "[winfo x .$i] "
    }
    return $a
} -cleanup {
    grid_reset 16.8
} -result {0 30 130 230 280 , 0 30 130 230 260 , 0 30 113 196 280 , 0 30 60 90 120 }
test grid-16.9 {layout uniform} -body {
    frame .f1 -width 75 -height 50
    frame .f2 -width 60 -height 25
    frame .f3 -width 95 -height 75
    frame .f4 -width 135 -height 100
    frame .f5 -width 80 -height 40
    for {set t 1} {$t <= 5} {incr t} {
        grid .f$t
    }
    grid rowconfigure . {0 2} -uniform a
    grid rowconfigure . {1 3} -uniform b
    update
    list [grid bbox . 0 0] [grid bbox . 0 1] [grid bbox . 0 2] \
            [grid bbox . 0 3] [grid bbox . 0 4]
} -cleanup {
    grid_reset 16.9
} -result {{0 0 135 75} {0 75 135 100} {0 175 135 75} {0 250 135 100} {0 350 135 40}}
test grid-16.10 {layout uniform} -body {
    grid [frame .f1 -width  75 -height  50] -row 0 -column 0
    grid [frame .f2 -width  60 -height  30] -row 1 -column 2
    grid [frame .f3 -width  95 -height  90] -row 2 -column 1
    grid [frame .f4 -width  60 -height 100] -row 3 -column 4
    grid [frame .f5 -width  60 -height  40] -row 4 -column 3

    grid rowconfigure . {0 1} -uniform a
    grid rowconfigure . {2 4} -uniform b
    grid rowconfigure . {0 2} -weight 2
    grid columnconfigure . {0 2} -uniform a
    grid columnconfigure . {3 4} -uniform b
    grid columnconfigure . {2 4} -weight 2
    grid columnconfigure . 3 -minsize 70
    grid columnconfigure . 4 -minsize 130
    update
    list [grid bbox . 0 0] [grid bbox . 2 1] [grid bbox . 1 2] \
            [grid bbox . 4 3] [grid bbox . 3 4]
} -cleanup {
    grid_reset 16.10
} -result {{0 0 75 60} {170 60 150 30} {75 90 95 90} {390 180 140 100} {320 280 70 45}}
test grid-16.11 {layout uniform (shrink)} -body {
    frame .f1 -width 75 -height 50
    frame .f2 -width 100 -height 95
    grid .f1 .f2 -sticky news
    grid columnconfigure . {0 1} -uniform a
    grid columnconfigure . 0 -weight 1
    update
    set res {}
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    grid propagate . 0
    . configure -width 150 -height 95
    update
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
} -cleanup {
    grid_reset 16.11
} -result {{0 0 100 95} {100 0 100 95} {0 0 50 95} {50 0 100 95}}
test grid-16.12 {layout uniform (grow)} -body {
    frame .f1 -width 40 -height 50
    frame .f2 -width 50 -height 95
    frame .f3 -width 60 -height 50
    frame .f4 -width 70 -height 95
    grid .f1 .f2 .f3 .f4 -sticky news
    grid columnconfigure . {0 1 2} -uniform a
    # Put weight 2 on the biggest in the group to see that the groups
    # adapt to one of the smaller.
    grid columnconfigure . 2 -weight 2
    grid columnconfigure . {0 3} -weight 1
    update
    set res {}
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    lappend res [grid bbox . 2 0] [grid bbox . 3 0]

    grid propagate . 0
    . configure -width 350 -height 95
    update
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    lappend res [grid bbox . 2 0] [grid bbox . 3 0]
} -cleanup {
    grid_reset 16.12
} -result [list {0 0 50 95} {50 0 50 95} {100 0 100 95} {200 0 70 95} \
        {0 0 70 95} {70 0 50 95} {120 0 140 95} {260 0 90 95}]


test grid-16.13 {layout span} -body {
    frame .f1 -width 24 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid .f3 - - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 3 4 0} {1 2 1 2} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    return $res
    # The last result below should ideally be 8 8 8 126 but the current
    # implementation is not exact enough.
} -cleanup {
    grid_reset 16.13
} -result [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 14 42 56 38 0] \
           [list 18 38 18 76 0] [list 7 8 9 126 0]]


test grid-16.14 {layout span} -body {
    frame .f1 -width 110 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid .f3 - - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 3 4 0} {1 2 1 3} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    return $res
} -cleanup {
    grid_reset 16.14
} -result [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 14 42 56 38 0] \
           [list 27 55 28 40 0] [list 36 37 37 40 0]]


test grid-16.15 {layout span} -body {
    frame .f1 -width 24 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid x .f3 - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 0 1 0} {0 0 0 0} {1 0 0 6}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    return $res
} -cleanup {
    grid_reset 16.15
} -result [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 0 0 112 38 0] \
           [list 0 37 37 76 0] [list 0 12 12 126 0]]


test grid-16.16 {layout span} -body {
    frame .f1 -width 64 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20
    frame .f4 -width 15 -height 20
    frame .f5 -width 18 -height 20
    frame .f6 -width 20 -height 20

    grid .f1 - x .f2
    grid .f3 - - -
    grid .f4 .f5 .f6

    set res {}
    foreach w {{1 1 5 1} {0 0 1 0} {1 3 4 0} {1 2 1 2} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    return $res
} -cleanup {
    grid_reset 16.16
} -result [list [list 30 34 43 43 0] [list 30 34 48 38 0] [list 22 42 48 38 0] \
           [list 25 39 29 57 0] [list 30 34 22 64 0]]


test grid-16.17 {layout weights (shrinking at minsize)} -body {
    foreach i {0 1 2 3} {
	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid columnconfigure . {0 1} -weight 1 -minsize 0
    grid rowconfigure . {0 1} -weight 1 -minsize 0
    set a ""
    . configure -width 250 -height 200
    update
    foreach i {0 1 2 3} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    . configure -width 150 -height 100
    update
    foreach i {0 1 2 3} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    return $a
} -cleanup {
    grid_reset 16.17
} -result {25-25-1 25-25-1 100-75-1 100-75-1 25-25-0 25-25-0 100-75-1 100-75-1}
test grid-16.18 {layout span} -body {
    frame .f1 -width 30  -height 20
    frame .f2 -width 166 -height 20
    frame .f3 -width 39  -height 20
    frame .f4 -width 10  -height 20

    grid .f1 .f3 -
    grid .f2 -   .f4
    grid columnconfigure . 0 -weight 1

    set res {}
    foreach w {{1 0 0} {0 1 0} {0 0 1}} {
        for {set c 0} {$c < 3} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 2} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    return $res
} -cleanup {
    grid_reset 16.18
} -result [list [list 137 29 10] [list 30 136 10] [list 98 68 10]]
test grid-16.19 {layout span} -constraints { knownBug } -body {
    # This test shows the problem in Bug 2075285
    # Several overlapping multi-span widgets is a weak spot
    # in the current implementation.
    # Test present as a reminder in case a future algorithm update is made.
    frame .f1 -width 100 -height 20
    frame .f2 -width 20  -height 20
    frame .f3 -width 10  -height 20
    frame .f4 -width 20  -height 20
    grid .f1 - -   - -   - -sticky we
    grid .f2 - .f3 - .f4 - -sticky we
    grid columnconfigure . {1 5} -weight 1
    set res {}
    update
    for {set c 0} {$c <= 5} {incr c} {
        lappend res [lindex [grid bbox . $c 0] 2]
    }
    return $res
} -cleanup {
    grid_reset 16.19
} -result [list 0 45 5 5 0 45]

test grid-17.1 {forget and pending idle handlers} -body {
    # This test is intended to detect a crash caused by a failure to remove
    # pending idle handlers when grid forget is invoked.

    toplevel .t
    wm geometry .t +0+0
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    grid .t.f
    update
    grid forget .t.f.l
    grid forget .t.f
    destroy .t

    toplevel .t
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    destroy .t
    set result ok
} -result ok

test grid-18.1 {test respect for internalborder} -body {
    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    grid .pack.lf.f -sticky news
    grid columnconfigure .pack.lf 0 -weight 1
    grid rowconfigure .pack.lf 0 -weight 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
    destroy .pack
    return $res
} -result {196x188+2+10 177x186+5+7}
test grid-18.2 {test support for minreqsize} -body {
    toplevel .pack
    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25
    grid .pack.lf.f
    update
    set res [list [winfo geometry .pack.lf]]
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]
    destroy .pack
    return $res
} -result {162x127+0+0 172x112+0+0}

test grid-19.1 {uniform realloc} -body {
    # Use a lot of uniform groups to test the reallocation mechanism
    for {set t 0} {$t < 100} {incr t 2} {
        frame .fa$t -width 5 -height 20
        frame .fb$t -width 6 -height 20
        grid .fa$t .fb$t -row 0 -column $t -sticky news
        grid columnconfigure . [list $t [expr {$t + 1}]] -uniform a$t
    }
    update
    grid bbox .
} -cleanup {
    grid_reset 19.1
} -result {0 0 600 20}

test grid-20.1 {recalculate size after removal (destroy)} -body {
    label .l1 -text l1
    grid .l1 -row 2 -column 2
    destroy .l1
    label .l2 -text l2
    grid .l2
    grid size .
} -cleanup {
    grid_reset 20.1
} -result {1 1}
test grid-20.2 {recalculate size after removal (forget)} -body {
    label .l1 -text l1
    grid .l1 -row 2 -column 2
    grid forget .l1
    label .l2 -text l2
    grid .l2
    grid size .
} -cleanup {
    grid_reset 20.2
} -result {1 1}

test grid-21.1 {anchor} -body {
    grid anchor . 1 xxx
} -cleanup {

    grid_reset 21.1
} -returnCodes error -result {wrong # args: should be "grid anchor window ?anchor?"}
test grid-21.2 {anchor} -body {
    grid anchor .
} -cleanup {
    grid_reset 21.2
} -result {nw}
test grid-21.3 {anchor} -body {
    grid anchor . se;grid anchor .
} -cleanup {
    grid_reset 21.3
} -result {se}
test grid-21.4 {anchor} -body {
    grid anchor .x
} -cleanup {

    grid_reset 21.4
} -returnCodes error -result {bad window path name ".x"}
test grid-21.5 {anchor} -body {
    grid anchor . x
} -cleanup {

    grid_reset 21.5
} -returnCodes error -result {bad anchor "x": must be n, ne, e, se, s, sw, w, nw, or center}
test grid-21.6 {anchor} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    . configure -width 300 -height 250

    set res {}
    foreach a {n ne e se s sw w nw center} {
        grid anchor . $a
        update
        lappend res [grid bbox .]
    }
    return $res
} -cleanup {
    grid_reset 21.6
} -result [list {37 0 225 150} {75 0 225 150} {75 50 225 150} {75 100 225 150} \
           {37 100 225 150} {0 100 225 150} {0 50 225 150} {0 0 225 150} \
           {37 50 225 150}]


test grid-21.7 {anchor} -body {
    # Test with a non-symmetric internal border.
    # This only tests vertically, there is currently no way to get
    # it assymetric horizontally.
    labelframe .f -bd 0
    frame .f.x -width 20 -height 20
    .f configure -labelwidget .f.x
    pack .f -fill both -expand 1

    foreach i {0 1 2} {
	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
	grid .$i -in .f -row $i -column $i -sticky nswe
    }
    pack propagate . 0
    grid propagate .f 0
    . configure -width 300 -height 250

    set res {}
    foreach a {n ne e se s sw w nw center} {
        grid anchor .f $a
        update
        lappend res [grid bbox .f]
    }
    pack propagate . 1 ; wm geometry . {}
    return $res
} -cleanup {
    grid_reset 21.7
} -result [list {37 20 225 150} {75 20 225 150} {75 60 225 150} {75 100 225 150} \
           {37 100 225 150} {0 100 225 150} {0 60 225 150} {0 20 225 150} \
           {37 60 225 150}]


test grid-22.1 {remove: basic argument checking} {
    list [catch {grid remove foo} msg] $msg
} {1 {bad window path name "foo"}}

test grid-22.2 {remove} {
    button .c
    grid [button .b]
    set a [grid content .]
    grid remove .b .c
    lappend a [grid content .]
    return $a
} {.b {}}
grid_reset 22.2

test grid-22.3 {remove} {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
    grid remove .c
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx 3 -pady 4 -sticky ns}
grid_reset 22.3

test grid-22.3.1 {remove} {
    frame .a
    button .c
    grid .c -in .a -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid remove .c
    grid .c -row 0 -column 0
    grid info .c
} {-in .a -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx {3 5} -pady {4 7} -sticky ns}
grid_reset 22.3.1

test grid-22.4 {remove, calling Tk_UnmaintainGeometry} {
    frame .f -bd 2 -relief raised
    place .f -x 10 -y 20 -width 200 -height 100
    frame .f2 -width 50 -height 30 -bg red
    grid .f2 -in .f
    update
    set x [winfo ismapped .f2]
    grid remove .f2
    place .f -x 30
    update
    lappend x [winfo ismapped .f2]
} {1 0}
grid_reset 22.4

test grid-22.5 {remove} {
    frame .a
    button .c
    grid .c -in .a -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid remove .c
    # If .a was destroyed while remembered by the removed .c, make sure it
    # is ignored.
    destroy .a
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx {3 5} -pady {4 7} -sticky ns}
grid_reset 22.5

test grid-23 {grid configure -in leaked from previous container window - bug
              6aea69fccbb266b7f0437686379fbe5b55442958} {
    frame .f
    frame .g
    pack .f .g
    text .t
    grid .t -in .f
    pack forget .f
    update
    grid .t -in .g
    # .t is now managed by .g; following lines must have no effect on .t
    pack .f
    update
    pack forget .f
    update
    winfo ismapped .t ; # must return 1
} 1
grid_reset 23

test grid-24.1 {<<NoManagedChild>> fires on last grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.1
} -result 1
test grid-24.2 {<<NoManagedChild>> fires on last grid remove} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid remove .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.2
} -result 1
test grid-24.3 {<<NoManagedChild>> fires on last gridded child destruction} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {incr A}
    destroy .1
    update
    set A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.3
} -result 1
test grid-24.4 {<Configure> does not fire on last grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <Configure> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    grid_reset 24.4
} -result 0
test grid-24.5 {<Configure> fires on forelast grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid [frame .2]
    update
    bind . <Configure> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    grid_reset 24.5
} -result 1
test grid-24.6 {<<NoManagedChild>> does not fire on forelast grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid [frame .2]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.6
} -result 0
test grid-24.7 {<<NoManagedChild>> does not fire on grid anchor} -setup {
    global A
    unset -nocomplain A
} -body {
    bind . <<NoManagedChild>> {set A 1}
    grid anchor . w
    update
    info exists A
} -cleanup {
    grid anchor . nw
    bind . <<NoManagedChild>> {}
    grid_reset 24.7
} -result 0
test grid-24.8 {<<NoManagedChild>> does not fire on last grid forget if propagation is off} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid propagate . 0
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.8
} -result 0

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|
|
|
<

|
|
>
|
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
>
|
|
|
|
|
|
|
|
|
|
|








|


|

|
|
|
<


>
|
|
<
>
|
|
|
|
<
>
|
|
|
|
<
>
|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|







|
|
|
|
|












|
|
|
|
|












|
|
|
|
|


|
|
|
|


|
<

>
|
>
|

|
<

>
|
>
|
|
|
>
|
|
|
>
|




>
|
|










|
|
|
|
|
|
|
|
|
|
|
|
|
|
|











|

|
|
|
|
|
|


>
|












|

|
|
|
|




>
|
|
<
>
|
|
|
|
|
<
>
|
|
|
|
|
<
>
|
|
|
|
|
<
>
|
|
|
|
|
<
>
|
|
|











|
|
|
|
|


|
|
|
|
|


|
|
|
|
|


|
|
|
|
|

|









|
|
|
|
|

|

|


|
|






|
|
|
|
|

|






|
|




|
|
|
|
|
|
|
|

|









|
|
|
|
|











|
|
|
|
|











|
|
|
|
|










|
|
|
|










|
|
|
|












|
|
|
|







>







|
|
<

|














<
<
|
|
















>
>
|

|
<
>
|
|
|




|
|
<

|

|
<
>
|
|
|




|
|
|
|

|
|
|
|
|


|
|
>
|
|
<
|

|
|
|
|
|

|
|
|
|
|







|
|
|
|

|
|
|
|
|

|
|
|
|
|







|
|
|
|

|
|
|
|
|

|
|
|
|
|







|
|
|
|







|
|
|
|

|
|
|
|
|

|
|
|
|
|







|
|
|
|







|
|
|
|





|




|



|
|
|
|
|







|


|

|
|
|
<

|












|
|
|
|
|










|
|
|
|


















|
|
<

|


|

|

|
|
|
|
|




|
|
|

|
|
|
<

|

|
|






|
|
|
|

|
|
|
|








|
|
|
|
|

|
|
|
|








|
|
|
|
|

|
|
|
|








|
|
|
|
|

|
|
|
|








|
|
|
|
>
|

|
|
|
|








|
|
|
|
<
<
<
<
<
<
|

|
|




|





|
|
|
|
|

|
|










|





|






|





|

|
|
|
|
|













|
|
|
|





>











|
|
|
|












|
|
|
|














>





<
<
|

>
>
|



>


>












|


<
<
|

>
>
|



>


>












<
<
|
|

>
>
|



>


>












<
<
|
|

>
>
|






>



>












<
<
|
|

>
>
|

|
|















|
|
|
|
|




>



>












<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<

|


>










>






|

|















|
|
|













|
|

|









|
|
<

|






|
|
|
|






|
|
<

|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|
|
|
<
>
|
|
|

|
|



>






<
<
|
|


>
>
|







>

|
|




>







<
<
|
|


>




>



|

|
|


>








>









>













>













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

564
565
566
567
568

569
570
571
572
573

574
575
576
577
578

579
580
581
582
583

584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861

862
863
864
865
866
867

868
869
870
871
872
873

874
875
876
877
878
879

880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102


1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390

1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495






1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627


1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654


1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678


1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703


1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732


1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782


1783
1784



















1785

1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876

1877
1878
1879

1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894

1895
1896
1897
1898
1899

1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916


1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946


1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012






































































































































2013
2014
2015




    lappend a [grid size .]
    grid .f -row 0 -column 0
    update
    lappend a [grid size .]
    grid columnconfigure . 15 -weight 0
    update
    lappend a [grid size .]
    set a
} {{51 11} {51 11} {31 11} {21 11} {16 1} {1 1}}
grid_reset 8.6


test grid-9.1 {slaves} {
	list [catch {grid slaves .} msg] $msg
} {0 {}}

test grid-9.2 {slaves} {
	list [catch {grid slaves .foo} msg] $msg
} {1 {bad window path name ".foo"}}

test grid-9.3 {slaves} {
	list [catch {grid slaves a b} msg] $msg
} {1 {wrong # args: should be "grid slaves window ?-option value...?"}}

test grid-9.4 {slaves} {
	list [catch {grid slaves . a b} msg] $msg
} {1 {bad option "a": must be -column or -row}}

test grid-9.5 {slaves} {
	list [catch {grid slaves . -column x} msg] $msg
} {1 {expected integer but got "x"}}

test grid-9.6 {slaves} {
	list [catch {grid slaves . -row -3} msg] $msg
} {1 {-row is an invalid value: should NOT be < 0}}

test grid-9.7 {slaves} {
	list [catch {grid slaves . -foo 3} msg] $msg
} {1 {bad option "-foo": must be -column or -row}}

test grid-9.8 {slaves} {
	list [catch {grid slaves .x -row 3} msg] $msg
} {1 {bad window path name ".x"}}

test grid-9.9 {slaves} {
	list [catch {grid slaves . -row 3} msg] $msg
} {0 {}}

test grid-9.10 {slaves} {
	foreach i {0 1 2} {
	    label .$i -text $i
	    grid .$i -row $i -column $i
	}
	list [catch {grid slaves .} msg] $msg
} {0 {.2 .1 .0}}
grid_reset 9.10

test grid-9.11 {slaves} {
    catch {unset a}
    foreach i {0 1 2} {
	label .$i -text $i
	label .$i-x -text $i-x
	grid .$i -row $i -column $i
	grid .$i-x -row $i -column [incr i]
    }
    foreach row {0 1 2 3} {
	lappend a $row{[grid slaves . -row $row]}
    }
    foreach col {0 1 2 3} {
	lappend a $col{[grid slaves . -column $col]}
    }
    set a
} {{0{.0-x .0}} {1{.1-x .1}} {2{.2-x .2}} 3{} 0{.0} {1{.1 .0-x}} {2{.2 .1-x}} 3{.2-x}}
grid_reset 9.11


# column/row configure

test grid-10.1 {column/row configure} {
	list [catch {grid columnconfigure .} msg] $msg

} {1 {wrong # args: should be "grid columnconfigure master index ?-option value...?"}}
grid_reset 10.1

test grid-10.2 {column/row configure} {
	list [catch {grid columnconfigure . 0 -weight 0 -pad} msg] $msg

} {1 {wrong # args: should be "grid columnconfigure master index ?-option value...?"}}
grid_reset 10.2

test grid-10.3 {column/row configure} {
	list [catch {grid columnconfigure .f 0 -weight} msg] $msg

} {1 {bad window path name ".f"}}
grid_reset 10.3

test grid-10.4 {column/row configure} {
	list [catch {grid columnconfigure . nine -weight} msg] $msg

} {1 {expected integer but got "nine" (when retreiving options only integer indices are allowed)}}
grid_reset 10.4

test grid-10.5 {column/row configure} {
	list [catch {grid columnconfigure . 265 -weight} msg] $msg
} {0 0}
grid_reset 10.5

test grid-10.6 {column/row configure} {
	list [catch {grid columnconfigure . 0} msg] $msg
} {0 {-minsize 0 -pad 0 -uniform {} -weight 0}}
grid_reset 10.6

test grid-10.7 {column/row configure} {
	list [catch {grid columnconfigure . 0 -foo} msg] $msg
} {1 {bad option "-foo": must be -minsize, -pad, -uniform, or -weight}}
grid_reset 10.7

test grid-10.8 {column/row configure} {
	list [catch {grid columnconfigure . 0 -minsize foo} msg] $msg
} {1 {bad screen distance "foo"}}
grid_reset 10.8

test grid-10.9 {column/row configure} {
	list [catch {grid columnconfigure . 0 -minsize foo} msg] $msg
} {1 {bad screen distance "foo"}}
grid_reset 10.9

test grid-10.10 {column/row configure} {
	grid columnconfigure . 0 -minsize 10
	grid columnconfigure . 0 -minsize
} {10}
grid_reset 10.10

test grid-10.11 {column/row configure} {
	list [catch {grid columnconfigure . 0 -weight bad} msg] $msg
} {1 {expected integer but got "bad"}}
grid_reset 10.11

test grid-10.12 {column/row configure} {
	list [catch {grid columnconfigure . 0 -weight -3} msg] $msg
} {1 {invalid arg "-weight": should be non-negative}}
grid_reset 10.12

test grid-10.13 {column/row configure} {
	grid columnconfigure . 0 -weight 3
	grid columnconfigure . 0 -weight
} {3}
grid_reset 10.13

test grid-10.14 {column/row configure} {
	list [catch {grid columnconfigure . 0 -pad foo} msg] $msg
} {1 {bad screen distance "foo"}}
grid_reset 10.14

test grid-10.15 {column/row configure} {
	list [catch {grid columnconfigure . 0 -pad -3} msg] $msg
} {1 {invalid arg "-pad": should be non-negative}}
grid_reset 10.15

test grid-10.16 {column/row configure} {
	grid columnconfigure . 0 -pad 3
	grid columnconfigure . 0 -pad
} {3}
grid_reset 10.16

test grid-10.17 {column/row configure} {
	frame .f
	set a ""
	grid columnconfigure .f 0 -weight 0
	lappend a [grid columnconfigure .f 0 -weight]
	grid columnconfigure .f 0 -weight 1
	lappend a [grid columnconfigure .f 0 -weight]
	grid rowconfigure .f 0 -weight 0
	lappend a [grid rowconfigure .f 0 -weight]
	grid rowconfigure .f 0 -weight 1
	lappend a [grid columnconfigure .f 0 -weight]
	grid columnconfigure .f 0 -weight 0
	set a
} {0 1 0 1}
grid_reset 10.17

test grid-10.18 {column/row configure} {
	frame .f
	grid columnconfigure .f {0 2} -minsize 10 -weight 1
	list [grid columnconfigure .f 0 -minsize] \
		[grid columnconfigure .f 1 -minsize] \
		[grid columnconfigure .f 2 -minsize] \
		[grid columnconfigure .f 0 -weight] \
		[grid columnconfigure .f 1 -weight] \
		[grid columnconfigure .f 2 -weight]
}  {10 0 10 1 0 1}
grid_reset 10.18

test grid-10.19 {column/row configure} {
	list [catch {grid columnconfigure . {0 -1 2} -weight 1} msg] $msg
} {1 {grid columnconfigure: "-1" is out of range}}
grid_reset 10.19

test grid-10.20 {column/row configure} {
	grid columnconfigure . 0 -uniform foo
	grid columnconfigure . 0 -uniform
} {foo}
grid_reset 10.20

test grid-10.21 {column/row configure} {
    list [catch {grid columnconfigure . .b -weight 1} msg] $msg
} {1 {grid columnconfigure: illegal index ".b"}}
grid_reset 10.21

test grid-10.22 {column/row configure} {
    button .b
    list [catch {grid columnconfigure . .b -weight 1} msg] $msg
} {1 {grid columnconfigure: the window ".b" is not managed by "."}}
grid_reset 10.22

test grid-10.23 {column/row configure} {
    button .b
    grid .b -column 1 -columnspan 2
    grid columnconfigure . .b -weight 1
    set res {}
    foreach i {0 1 2 3} {
        lappend res [grid columnconfigure . $i -weight]
    }
    set res
} {0 1 1 0}
grid_reset 10.23

test grid-10.24 {column/row configure} {
    button .b
    button .c
    button .d
    grid .b -column 1 -columnspan 2
    grid .c -column 2 -columnspan 3
    grid .d -column 4 -columnspan 2
    grid columnconfigure . {.b .d} -weight 1
    grid columnconfigure . .c -weight 2
    set res {}
    foreach i {0 1 2 3 4 5 6} {
        lappend res [grid columnconfigure . $i -weight]
    }
    set res
} {0 1 2 2 2 1 0}
grid_reset 10.24

test grid-10.25 {column/row configure} {
    button .b
    button .c
    button .d
    grid .b -row 1 -rowspan 2
    grid .c -row 2 -rowspan 3
    grid .d -row 4 -rowspan 2
    grid rowconfigure . {7 all} -weight 1
    grid rowconfigure . {1 .d} -weight 2
    set res {}
    foreach i {0 1 2 3 4 5 6 7} {
        lappend res [grid rowconfigure . $i -weight]
    }
    set res
} {0 2 1 1 2 2 0 1}
grid_reset 10.25

test grid-10.26 {column/row configure} {
    button .b
    grid columnconfigure .b 0
} {-minsize 0 -pad 0 -uniform {} -weight 0}
grid_reset 10.26

test grid-10.30 {column/row configure - no indices} {
    # Bug 1422430
    set t [toplevel .test]
    set res [list [catch {grid columnconfigure $t "" -weight 1} msg] $msg]

    destroy $t
    set res
} {1 {no column indices specified}}

test grid-10.31 {column/row configure - no indices} {
    set t [toplevel .test]
    set res [list [catch {grid rowconfigure $t "" -weight 1} msg] $msg]

    destroy $t
    set res
} {1 {no row indices specified}}

test grid-10.32 {column/row configure - invalid indices} {
    list [catch {grid columnconfigure . {0 1 2} -weight} msg] $msg
} {1 {grid columnconfigure: must specify a single element on retrieval}}

test grid-10.33 {column/row configure - invalid indices} {
    list [catch {grid rowconfigure . {0 1 2} -weight} msg] $msg
} {1 {grid rowconfigure: must specify a single element on retrieval}}

test grid-10.34 {column/row configure - empty 'all' configure} {
    # Bug 1422430
    set t [toplevel .test]
    grid rowconfigure $t all -weight 1
    destroy $t
} {}

test grid-10.35 {column/row configure} {
    # Test that no lingering message is there
    frame .f
    set res    [grid columnconfigure .f all -weight 1]
    append res [grid columnconfigure .f {0 all} -weight 1]
    frame .f.f
    grid .f.f
    append res [grid columnconfigure .f {.f.f} -weight 1]
    append res [grid columnconfigure .f {.f.f 1} -weight 1]
    append res [grid columnconfigure .f {2 .f.f} -weight 1]
    destroy .f
    set res
} {}
grid_reset 10.35

test grid-10.36 {column/row configure} {
    list [catch {grid columnconfigure . all} msg] $msg
} {1 {expected integer but got "all" (when retreiving options only integer indices are allowed)}}
grid_reset 10.36

test grid-10.37 {column/row configure} {
    list [catch {grid columnconfigure . 100000} msg] $msg
} {0 {-minsize 0 -pad 0 -uniform {} -weight 0}}
grid_reset 10.37

test grid-10.38 {column/row configure} -body {
    # This is a test for bug 1423666 where a column >= 10000 caused
    # a crash in layout.  The update is needed to reach the layout stage.
    # Test different combinations of row/column overflow
    frame .f
    set res {}
    lappend res [catch {grid .f -row 10 -column 9999} msg] $msg ; update
    lappend res [catch {grid .f -row 9999 -column 10} msg] $msg ; update
    lappend res [catch {grid .f -columnspan 2 -column 9998} msg] $msg ; update
    lappend res [catch {grid .f -rowspan 2 -row 9998} msg] $msg ; update
    lappend res [catch {grid .f -column 9998 -columnspan 2} msg] $msg ; update
    lappend res [catch {grid .f -row 9998 -rowspan 2} msg] $msg ; update
    set res
} -cleanup {destroy .f} -result [lrange {
    1 {Column out of bounds}
    1 {Row out of bounds}
    1 {Column out of bounds}
    1 {Row out of bounds}
    1 {Column out of bounds}
    1 {Row out of bounds}
} 0 end]
grid_reset 10.38

test grid-10.39 {column/row configure} -body {
    # Additional tests for row/column overflow
    frame .f
    frame .g
    set res {}
    grid .f -row 9998 -column 0
    lappend res [catch {grid ^ -in .} msg] $msg  ; update
    lappend res [catch {grid .g} msg] $msg  ; update
    grid forget .f .g
    lappend res [catch {grid .f - -column 9998} msg] $msg ; update
    grid forget .f .g
    lappend res [catch {eval grid [string repeat " x " 9999] .f} msg] $msg
    update
    set res
} -cleanup {destroy .f .g} -result [lrange {
    1 {Row out of bounds}
    1 {Row out of bounds}
    1 {Column out of bounds}
    1 {Column out of bounds}
} 0 end]
grid_reset 10.39

# auto-placement tests

test grid-11.1 {default widget placement} {
	list [catch {grid ^} msg] $msg

} {1 {can't use '^', cant find master}}
grid_reset 11.1

test grid-11.2 {default widget placement} {
	button .b
	list [catch {grid .b ^} msg] $msg

} {1 {can't find slave to extend with "^".}}
grid_reset 11.2

test grid-11.3 {default widget placement} {
	button .b
	list [catch {grid .b - - .c} msg] $msg

} {1 {bad window path name ".c"}}
grid_reset 11.3

test grid-11.4 {default widget placement} {
	button .b
	list [catch {grid .b - - = -} msg] $msg

} {1 {invalid window shortcut, "=" should be '-', 'x', or '^'}}
grid_reset 11.4

test grid-11.5 {default widget placement} {
	button .b
	list [catch {grid .b - x -} msg] $msg

} {1 {Must specify window before shortcut '-'.}}
grid_reset 11.5

test grid-11.6 {default widget placement} {
    foreach i {1 2 3 4 5 6} {
	frame .f$i -width 50 -height 50 -highlightthickness 0 -bg red
    }
    grid .f1 .f2 .f3 .f4
    grid .f5   -  x  .f6 -sticky nsew
    update
    set a ""
    foreach i {5 6} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,50  100,50} {150,50  50,50}}
grid_reset 11.6

test grid-11.7 {default widget placement} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    list [catch "grid .f x -" msg] $msg
} {1 {Must specify window before shortcut '-'.}}
grid_reset 11.7

test grid-11.8 {default widget placement} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    list [catch "grid .f ^ -" msg] $msg
} {1 {Must specify window before shortcut '-'.}}
grid_reset 11.8

test grid-11.9 {default widget placement} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid .f -row 5 -column 5
    list [catch "grid .f x ^" msg] $msg
} {1 {can't find slave to extend with "^".}}
grid_reset 11.9

test grid-11.10 {default widget placement} {
    foreach i {1 2 3} {
		frame .f$i -width 100 -height 50 -highlightthickness 0 -bg red
    }
    grid .f1 .f2  -sticky nsew
    grid .f3   ^  -sticky nsew
    update
    set a ""
    foreach i {1 2 3} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,0  100,50} {100,0  100,100} {0,50  100,50}}
grid_reset 11.10

test grid-11.11 {default widget placement} {
    foreach i {1 2 3 4 5 6 7 8 9 10 11 12} {
		frame .f$i -width 50 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2  .f3 .f4 -sticky nsew
    grid .f5  .f6   -  .f7  -sticky nsew
    grid .f8    ^   ^  .f9  -sticky nsew
    grid .f10   ^   ^  .f11  -sticky nsew
	grid .f12   -   -   - -sticky nsew
    update
    set a ""
    foreach i {5 6 7 8 9 10 11 12 } {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,50  50,50} {50,50  100,150} {150,50  50,50} {0,100  50,50} {150,100  50,50} {0,150  50,50} {150,150  50,50} {0,200  200,50}}
grid_reset 11.11

test grid-11.12 {default widget placement} {
    foreach i {1 2 3 4} {
		frame .f$i -width 75 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2   .f3     -sticky nsew
    grid .f4    ^           -sticky nsew
    update
    set a ""
    foreach i {1 2 3 4} {
		lappend a "[winfo x .f$i],[winfo y .f$i] \
			[winfo width .f$i],[winfo height .f$i]"
    }
    grid .f4    ^   -column 1
    update
    foreach i {1 2 3 4} {
		lappend a "[winfo x .f$i],[winfo y .f$i] \
			[winfo width .f$i],[winfo height .f$i]"
	}
	set a
} {{0,0  75,50} {75,0  75,100} {150,0  75,50} {0,50  75,50} {0,0  75,50} {75,0  75,100} {150,0  75,100} {75,50  75,50}}
grid_reset 11.12

test grid-11.13 {default widget placement} {
    foreach i {1 2 3 4 5 6 7} {
		frame .f$i -width 40 -height 50 -highlightthickness 1 -highlightbackground black
    }
    grid .f1  .f2  .f3 .f4 .f5 -sticky nsew
    grid .f6    -  .f7         -sticky nsew -columnspan 2
    update
    set a ""
    foreach i {6 7} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,50  120,50} {120,50  80,50}}
grid_reset 11.13

test grid-11.14 {default widget placement} {
    foreach i {1 2 3} {
	frame .f$i -width 60 -height 60 -highlightthickness 0 -bg red
    }
    grid .f1 .f2
    grid  ^  .f3
    update
    set a ""
    foreach i {1 2 3} {
	lappend a "[winfo x .f$i],[winfo y .f$i] \
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,30  60,60} {60,0  60,60} {60,60  60,60}}
grid_reset 11.14

test grid-11.15 {^ ^ test with multiple windows} {
    foreach i {1 2 3 4} {
	frame .f$i -width 50 -height 50 -bd 1 -relief solid
    }
    grid .f1 .f2 .f3 -sticky ns
    grid .f4 ^ ^
    update
    set a ""
    foreach i {1 2 3 4} {
	lappend a "[winfo x .f$i],[winfo y .f$i]\
		[winfo width .f$i],[winfo height .f$i]"
    }
    set a
} {{0,0 50,50} {50,0 50,100} {100,0 50,100} {0,50 50,50}}
grid_reset 11.15

test grid-11.16 {default widget placement} {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  x  ^  x .e -sticky news
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
} {50 100 50}
grid_reset 11.16

test grid-11.17 {default widget placement} {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  ^  x  ^ .e -sticky news
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
} {100 50 100}
grid_reset 11.17

test grid-11.18 {default widget placement} {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b .c .d -sticky news
    grid  ^  ^  ^  x -in .           ;# ^ and no child should work with -in.
    grid rowconfigure . {0 1} -uniform a
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
    lappend res [winfo height .d]
} {100 100 100 50}
grid_reset 11.18

test grid-11.19 {default widget placement} {
    foreach l {a b c d e} {
        frame .$l -width 50 -height 50
    }
    grid .a .b -sticky news
    grid .c .d -sticky news
    grid ^     -in . -row 2
    grid x  ^  -in . -row 1

    grid rowconfigure . {0 1 2} -uniform a
    update
    set res ""
    lappend res [winfo height .a]
    lappend res [winfo height .b]
    lappend res [winfo height .c]
    lappend res [winfo height .d]
} {50 100 100 50}
grid_reset 11.19


test grid-12.1 {-sticky} {
    catch {unset data}
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    set a ""
    grid .f
    grid rowconfigure . 0 -weight 1
    grid columnconfigure . 0 -weight 1
    grid propagate . 0
    . configure -width 250 -height 150
    foreach i { {} n s e w ns ew nw ne se sw nse nsw sew new nsew} {
	grid .f -sticky $i
	update
	array set data [grid info .f]
	append a "($data(-sticky)) [winfo x .f] [winfo y .f] [winfo width .f] [winfo height .f]\n"
    }


    set a
} {() 25 25 200 100
(n) 25 0 200 100
(s) 25 50 200 100
(e) 50 25 200 100
(w) 0 25 200 100
(ns) 25 0 200 150
(ew) 0 25 250 100
(nw) 0 0 200 100
(ne) 50 0 200 100
(es) 50 50 200 100
(sw) 0 50 200 100
(nes) 50 0 200 150
(nsw) 0 0 200 150
(esw) 0 50 250 100
(new) 0 0 250 100
(nesw) 0 0 250 150
}
grid_reset 12.1

test grid-12.2 {-sticky} {
    frame .f -bg red
    list [catch "grid .f -sticky glue" msg] $msg

} {1 {bad stickyness value "glue": must be a string containing n, e, s, and/or w}}
grid_reset 12.2

test grid-12.3 {-sticky} {
    frame .f -bg red
    grid .f -sticky {n,s,e,w}
    array set A [grid info .f]
    set A(-sticky)
} {nesw}
grid_reset 12.3


test grid-13.1 {-in} {
    frame .f -bg red
    list [catch "grid .f -in .f" msg] $msg

} {1 {Window can't be managed in itself}}
grid_reset 13.1

test grid-13.1.1 {-in} {
    frame .f -bg red
    list [winfo manager .f] \
         [catch {grid .f -in .f} err] $err \
         [winfo manager .f]
} {{} 1 {Window can't be managed in itself} {}}
grid_reset 13.1.1

test grid-13.2 {-in} {
    frame .f -bg red
    list [catch "grid .f -in .bad" msg] $msg
} {1 {bad window path name ".bad"}}
grid_reset 13.2

test grid-13.3 {-in} {
    frame .f -bg red
    toplevel .top
    list [catch "grid .f -in .top" msg] $msg
} {1 {can't put .f inside .top}}
destroy .top
grid_reset 13.3


test grid-13.4 {-ipadx} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -ipadx x" msg] $msg
} {1 {bad ipadx value "x": must be positive screen distance}}
grid_reset 13.4

test grid-13.4.1 {-ipadx} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -ipadx {5 5}" msg] $msg
} {1 {bad ipadx value "5 5": must be positive screen distance}}
grid_reset 13.4.1

test grid-13.5 {-ipadx} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a [winfo width .f]
    grid .f -ipadx 1
    update
    list $a [winfo width .f]
} {200 202}
grid_reset 13.5

test grid-13.6 {-ipady} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -ipady x" msg] $msg
} {1 {bad ipady value "x": must be positive screen distance}}
grid_reset 13.6

test grid-13.6.1 {-ipady} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -ipady {5 5}" msg] $msg
} {1 {bad ipady value "5 5": must be positive screen distance}}
grid_reset 13.6.1

test grid-13.7 {-ipady} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a [winfo height .f]
    grid .f -ipady 1
    update
    list $a [winfo height .f]
} {100 102}
grid_reset 13.7

test grid-13.8 {-padx} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -padx x" msg] $msg
} {1 {bad pad value "x": must be positive screen distance}}
grid_reset 13.8

test grid-13.8.1 {-padx} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -padx {10 x}" msg] $msg
} {1 {bad 2nd pad value "x": must be positive screen distance}}
grid_reset 13.8.1

test grid-13.9 {-padx} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo width .f] [winfo width .]"
    grid .f -padx 1
    update
    list $a "[winfo width .f] [winfo width .] [winfo x .f]"
} {{200 200} {200 202 1}}
grid_reset 13.9

test grid-13.9.1 {-padx} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo width .f] [winfo width .]"
    grid .f -padx {10 5}
    update
    list $a "[winfo width .f] [winfo width .] [winfo x .f]"
} {{200 200} {200 215 10}}
grid_reset 13.9.1

test grid-13.10 {-pady} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -pady x" msg] $msg
} {1 {bad pad value "x": must be positive screen distance}}
grid_reset 13.10

test grid-13.10.1 {-pady} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    list [catch "grid .f -pady {10 x}" msg] $msg
} {1 {bad 2nd pad value "x": must be positive screen distance}}
grid_reset 13.10.1

test grid-13.11 {-pady} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo height .f] [winfo height .]"
    grid .f -pady 1
    update
    list $a "[winfo height .f] [winfo height .] [winfo y .f]"
} {{100 100} {100 102 1}}
grid_reset 13.11

test grid-13.11.1 {-pady} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    update
    set a "[winfo height .f] [winfo height .]"
    grid .f -pady {4 16}
    update
    list $a "[winfo height .f] [winfo height .] [winfo y .f]"
} {{100 100} {100 120 4}}
grid_reset 13.11.1

test grid-13.12 {-ipad x and y} {
    frame .f -width 20 -height 20 -highlightthickness 0 -bg red
    grid columnconfigure . 0 -minsize 150
    grid rowconfigure . 0 -minsize 100
    set a ""
    foreach x {0 5} {
    	foreach y {0 5} {
	    grid .f -ipadx $x -ipady $y
	    update
	    append a " $x,$y:"
	    foreach prop {x y width height} {
	    	append a ,[winfo $prop .f]
	    }
	}
    }
    set a
} { 0,0:,65,40,20,20 0,5:,65,35,20,30 5,0:,60,40,30,20 5,5:,60,35,30,30}
grid_reset 13.12

test grid-13.13 {reparenting} {
    frame .1
    frame .2
    button .b
    grid .1 .2
    grid .b -in .1
    set a ""
    catch {unset info}; array set info [grid info .b]
    lappend a [grid slaves .1],[grid slaves .2],$info(-in)
    grid .b -in .2
    catch {unset info}; array set info [grid info .b]
    lappend a [grid slaves .1],[grid slaves .2],$info(-in)
    unset info
    set a
} {.b,,.1 ,.b,.2}
grid_reset 13.13


test grid-14.1 {structure notify} {
    frame .f -width 200 -height 100 -highlightthickness 0 -bg red
    frame .g -width 200 -height 100 -highlightthickness 0 -bg red
    grid .f
    grid .g -in .f
    update
    set a ""
    lappend a "[winfo x .g],[winfo y .g] \
        [winfo width .g],[winfo height .g]"
    .f configure -bd 5 -relief raised
    update
    lappend a "[winfo x .g],[winfo y .g] \
        [winfo width .g],[winfo height .g]"
    set a
} {{0,0  200,100} {5,5  200,100}}
grid_reset 14.1

test grid-14.2 {structure notify} {
    frame .f -width 200 -height 100
    frame .f.g -width 200 -height 100
    grid .f
    grid .f.g
    update
    set a ""
    lappend a [grid bbox .],[grid bbox .f]
    .f config -bd 20
    update
    lappend a [grid bbox .],[grid bbox .f]
} {{0 0 200 100,0 0 200 100} {0 0 240 140,20 20 200 100}}
grid_reset 14.2

test grid-14.3 {map notify: bug 1648} {nonPortable} {
    # This test is nonPortable because the number of times
    # A(.) will be incremented is unspecified--the behavior
    # is different accross window managers.
    global A
    catch {unset A}
    bind . <Configure> {incr A(%W)}
    set A(.) 0
    foreach i {0 1 2} {
	frame .$i -width 100 -height 75
	set A(.$i) 0
    }
    grid .0 .1 .2
    update
    bind <Configure> .1 {destroy .0}
    .2 configure -bd 10
    update
    bind . <Configure> {}
    array get A
} {.2 2 .0 1 . 2 .1 1}
grid_reset 14.3


test grid-15.1 {lost slave} {
    button .b
    grid .b
    set a [grid slaves .]
    pack .b
    lappend a [grid slaves .]
    grid .b
    lappend a [grid slaves .]
} {.b {} .b}
grid_reset 15.1

test grid-15.2 {lost slave} {
    frame .f
    grid .f
    button .b
    grid .b -in .f
    set a [grid slaves .f]
    pack .b
    lappend a [grid slaves .f]
    grid .b -in .f
    lappend a [grid slaves .f]
} {.b {} .b}
grid_reset 15.2


test grid-16.1 {layout centering} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid anchor . center
    . configure -width 300 -height 250
    update
    grid bbox .
} {37 50 225 150}
grid_reset 16.1

test grid-16.2 {layout weights (expanding)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    	grid rowconfigure . $i -weight [expr $i + 1]
    	grid columnconfigure . $i -weight [expr $i + 1]
    }
    grid propagate . 0
    . configure -width 500 -height 300
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    set a
} {120-75 167-100 213-125}
grid_reset 16.2

test grid-16.3 {layout weights (shrinking)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    	grid rowconfigure . $i -weight [expr $i + 1]
    	grid columnconfigure . $i -weight [expr $i + 1]
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    set a
} {84-63 66-50 50-37}
grid_reset 16.3

test grid-16.4 {layout weights (shrinking with minsize)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    	grid rowconfigure . $i -weight [expr $i + 1] -minsize 45
    	grid columnconfigure . $i -weight [expr $i + 1] -minsize 65
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    set a
} {70-60 65-45 65-45}
grid_reset 16.4

test grid-16.5 {layout weights (shrinking at minsize)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    	grid rowconfigure . $i -weight 0 -minsize 70
    	grid columnconfigure . $i -weight 0 -minsize 90
    }
    grid propagate . 0
    . configure -width 100 -height 75
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    set a
} {100-75 100-75 100-75}
grid_reset 16.5


test grid-16.6 {layout weights (shrinking at minsize)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    	grid rowconfigure . $i -weight [expr $i + 1] -minsize 52
    	grid columnconfigure . $i -weight [expr $i + 1] -minsize 69
    }
    grid propagate . 0
    . configure -width 200 -height 150
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]
    }
    set a
} {69-52 69-52 69-52}
grid_reset 16.6







test grid-16.7 {layout weights (shrinking at minsize)} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid columnconfigure . 1 -weight 1 -minsize 0
    grid rowconfigure . 1 -weight 1 -minsize 0
    . configure -width 100 -height 75
    set a ""
    update
    foreach i {0 1 2} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    set a
} {100-75-1 1-1-0 100-75-1}
grid_reset 16.7

test grid-16.8 {layout internal constraints} {
    foreach i {0 1 2 3 4} {
    	frame .$i -bg gray  -width 30 -height 25 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    }
    frame .f -bg red -width 250 -height 200
    frame .g -bg green -width 200 -height 180
    lower .f
    raise .g .f
    grid .f -row 1 -column 1 -rowspan 3 -columnspan 3 -sticky nswe
    grid .g -row 1 -column 1 -rowspan 2 -columnspan 2 -sticky nswe
    update
    set a ""
    foreach i {0 1 2 3 4} {
    	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .f
    update
    foreach i {0 1 2 3 4} {
    	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .g
    grid .f
    update
    foreach i {0 1 2 3 4} {
    	append a "[winfo x .$i] "
    }
    append a ", "
    grid remove .f
    update
    foreach i {0 1 2 3 4} {
    	append a "[winfo x .$i] "
    }
    set a
} {0 30 130 230 280 , 0 30 130 230 260 , 0 30 113 196 280 , 0 30 60 90 120 }
grid_reset 16.8

test grid-16.9 {layout uniform} {
    frame .f1 -width 75 -height 50
    frame .f2 -width 60 -height 25
    frame .f3 -width 95 -height 75
    frame .f4 -width 135 -height 100
    frame .f5 -width 80 -height 40
    for {set t 1} {$t <= 5} {incr t} {
        grid .f$t
    }
    grid rowconfigure . {0 2} -uniform a
    grid rowconfigure . {1 3} -uniform b
    update
    list [grid bbox . 0 0] [grid bbox . 0 1] [grid bbox . 0 2] \
            [grid bbox . 0 3] [grid bbox . 0 4]
} {{0 0 135 75} {0 75 135 100} {0 175 135 75} {0 250 135 100} {0 350 135 40}}
grid_reset 16.9

test grid-16.10 {layout uniform} {
    grid [frame .f1 -width  75 -height  50] -row 0 -column 0
    grid [frame .f2 -width  60 -height  30] -row 1 -column 2
    grid [frame .f3 -width  95 -height  90] -row 2 -column 1
    grid [frame .f4 -width  60 -height 100] -row 3 -column 4
    grid [frame .f5 -width  60 -height  40] -row 4 -column 3

    grid rowconfigure . {0 1} -uniform a
    grid rowconfigure . {2 4} -uniform b
    grid rowconfigure . {0 2} -weight 2
    grid columnconfigure . {0 2} -uniform a
    grid columnconfigure . {3 4} -uniform b
    grid columnconfigure . {2 4} -weight 2
    grid columnconfigure . 3 -minsize 70
    grid columnconfigure . 4 -minsize 130
    update
    list [grid bbox . 0 0] [grid bbox . 2 1] [grid bbox . 1 2] \
            [grid bbox . 4 3] [grid bbox . 3 4]
} {{0 0 75 60} {170 60 150 30} {75 90 95 90} {390 180 140 100} {320 280 70 45}}
grid_reset 16.10

test grid-16.11 {layout uniform (shrink)} {
    frame .f1 -width 75 -height 50
    frame .f2 -width 100 -height 95
    grid .f1 .f2 -sticky news
    grid columnconfigure . {0 1} -uniform a
    grid columnconfigure . 0 -weight 1
    update
    set res {}
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    grid propagate . 0
    . configure -width 150 -height 95
    update
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
} {{0 0 100 95} {100 0 100 95} {0 0 50 95} {50 0 100 95}}
grid_reset 16.11

test grid-16.12 {layout uniform (grow)} {
    frame .f1 -width 40 -height 50
    frame .f2 -width 50 -height 95
    frame .f3 -width 60 -height 50
    frame .f4 -width 70 -height 95
    grid .f1 .f2 .f3 .f4 -sticky news
    grid columnconfigure . {0 1 2} -uniform a
    # Put weight 2 on the biggest in the group to see that the groups
    # adapt to one of the smaller.
    grid columnconfigure . 2 -weight 2
    grid columnconfigure . {0 3} -weight 1
    update
    set res {}
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    lappend res [grid bbox . 2 0] [grid bbox . 3 0]

    grid propagate . 0
    . configure -width 350 -height 95
    update
    lappend res [grid bbox . 0 0] [grid bbox . 1 0]
    lappend res [grid bbox . 2 0] [grid bbox . 3 0]


} [list {0 0 50 95} {50 0 50 95} {100 0 100 95} {200 0 70 95} \
        {0 0 70 95} {70 0 50 95} {120 0 140 95} {260 0 90 95}]
grid_reset 16.12

test grid-16.13 {layout span} {
    frame .f1 -width 24 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid .f3 - - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 3 4 0} {1 2 1 2} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }
    set res
    # The last result below should ideally be 8 8 8 126 but the current
    # implementation is not exact enough.


} [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 14 42 56 38 0] \
           [list 18 38 18 76 0] [list 7 8 9 126 0]]
grid_reset 16.13

test grid-16.14 {layout span} {
    frame .f1 -width 110 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid .f3 - - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 3 4 0} {1 2 1 3} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }


    set res
} [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 14 42 56 38 0] \
           [list 27 55 28 40 0] [list 36 37 37 40 0]]
grid_reset 16.14

test grid-16.15 {layout span} {
    frame .f1 -width 24 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20

    grid .f1 - - .f2
    grid x .f3 - -

    set res {}
    foreach w {{0 1 0 0} {0 0 1 0} {1 0 1 0} {0 0 0 0} {1 0 0 6}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }


    set res
} [list [list 0 112 0 38 0] [list 0 0 112 38 0] [list 0 0 112 38 0] \
           [list 0 37 37 76 0] [list 0 12 12 126 0]]
grid_reset 16.15

test grid-16.16 {layout span} {
    frame .f1 -width 64 -height 20
    frame .f2 -width 38 -height 20
    frame .f3 -width 150 -height 20
    frame .f4 -width 15 -height 20
    frame .f5 -width 18 -height 20
    frame .f6 -width 20 -height 20

    grid .f1 - x .f2
    grid .f3 - - -
    grid .f4 .f5 .f6

    set res {}
    foreach w {{1 1 5 1} {0 0 1 0} {1 3 4 0} {1 2 1 2} {1 1 1 12}} {
        for {set c 0} {$c < 4} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 4} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }


    set res
} [list [list 30 34 43 43 0] [list 30 34 48 38 0] [list 22 42 48 38 0] \
           [list 25 39 29 57 0] [list 30 34 22 64 0]]
grid_reset 16.16

test grid-16.17 {layout weights (shrinking at minsize)} {
    foreach i {0 1 2 3} {
    	frame .$i -bg gray  -width 100 -height 75 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    grid columnconfigure . {0 1} -weight 1 -minsize 0
    grid rowconfigure . {0 1} -weight 1 -minsize 0
    set a ""
    . configure -width 250 -height 200
    update
    foreach i {0 1 2 3} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    . configure -width 150 -height 100
    update
    foreach i {0 1 2 3} {
	lappend a [winfo width .$i]-[winfo height .$i]-[winfo ismapped .$i]
    }
    set a
} {25-25-1 25-25-1 100-75-1 100-75-1 25-25-0 25-25-0 100-75-1 100-75-1}
grid_reset 16.17

test grid-16.18 {layout span} {
    frame .f1 -width 30  -height 20
    frame .f2 -width 166 -height 20
    frame .f3 -width 39  -height 20
    frame .f4 -width 10  -height 20

    grid .f1 .f3 -
    grid .f2 -   .f4
    grid columnconfigure . 0 -weight 1

    set res {}
    foreach w {{1 0 0} {0 1 0} {0 0 1}} {
        for {set c 0} {$c < 3} {incr c} {
            grid columnconfigure . $c -weight [lindex $w $c]
        }
        update
        set res2 {}
        for {set c 0} {$c <= 2} {incr c} {
            lappend res2 [lindex [grid bbox . $c 0] 2]
        }
        lappend res $res2
    }


    set res
} [list [list 137 29 10] [list 30 136 10] [list 98 68 10]]



















grid_reset 16.18


test grid-17.1 {forget and pending idle handlers} {
    # This test is intended to detect a crash caused by a failure to remove
    # pending idle handlers when grid forget is invoked.

    toplevel .t
    wm geometry .t +0+0
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    grid .t.f
    update
    grid forget .t.f.l
    grid forget .t.f
    destroy .t

    toplevel .t
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    destroy .t
    set result ok
} ok

test grid-18.1 {test respect for internalborder} {
    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    grid .pack.lf.f -sticky news
    grid columnconfigure .pack.lf 0 -weight 1
    grid rowconfigure .pack.lf 0 -weight 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
    destroy .pack
    set res
} {196x188+2+10 177x186+5+7}
test grid-18.2 {test support for minreqsize} {
    toplevel .pack
    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25
    grid .pack.lf.f
    update
    set res [list [winfo geometry .pack.lf]]
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]
    destroy .pack
    set res
} {162x127+0+0 172x112+0+0}

test grid-19.1 {uniform realloc} {
    # Use a lot of uniform groups to test the reallocation mechanism
    for {set t 0} {$t < 100} {incr t 2} {
        frame .fa$t -width 5 -height 20
        frame .fb$t -width 6 -height 20
        grid .fa$t .fb$t -row 0 -column $t -sticky news
        grid columnconfigure . [list $t [expr {$t + 1}]] -uniform a$t
    }
    update
    grid bbox .
} {0 0 600 20}
grid_reset 19.1


test grid-20.1 {recalculate size after removal (destroy)} {
    label .l1 -text l1
    grid .l1 -row 2 -column 2
    destroy .l1
    label .l2 -text l2
    grid .l2
    grid size .
} {1 1}
grid_reset 20.1

test grid-20.2 {recalculate size after removal (forget)} {
    label .l1 -text l1
    grid .l1 -row 2 -column 2
    grid forget .l1
    label .l2 -text l2
    grid .l2
    grid size .
} {1 1}
grid_reset 20.2


test grid-21.1 {anchor} {
    list [catch {grid anchor . 1 xxx} msg] $msg

} {1 {wrong # args: should be "grid anchor window ?anchor?"}}
grid_reset 21.1

test grid-21.2 {anchor} {
    list [catch {grid anchor .} msg] $msg
} {0 nw}
grid_reset 21.2

test grid-21.3 {anchor} {
    list [catch {grid anchor . se;grid anchor .} msg] $msg
} {0 se}
grid_reset 21.3

test grid-21.4 {anchor} {
    list [catch {grid anchor .x} msg] $msg

} {1 {bad window path name ".x"}}
grid_reset 21.4

test grid-21.5 {anchor} {
    list [catch {grid anchor . x} msg] $msg

} {1 {bad anchor "x": must be n, ne, e, se, s, sw, w, nw, or center}}
grid_reset 21.5

test grid-21.6 {anchor} {
    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
    	grid .$i -row $i -column $i -sticky nswe
    }
    grid propagate . 0
    . configure -width 300 -height 250

    set res {}
    foreach a {n ne e se s sw w nw center} {
        grid anchor . $a
        update
        lappend res [grid bbox .]
    }


    set res
} [list {37 0 225 150} {75 0 225 150} {75 50 225 150} {75 100 225 150} \
           {37 100 225 150} {0 100 225 150} {0 50 225 150} {0 0 225 150} \
           {37 50 225 150}]
grid_reset 21.6

test grid-21.7 {anchor} {
    # Test with a non-symmetric internal border.
    # This only tests vertically, there is currently no way to get
    # it assymetric horizontally.
    labelframe .f -bd 0
    frame .f.x -width 20 -height 20
    .f configure -labelwidget .f.x
    pack .f -fill both -expand 1

    foreach i {0 1 2} {
    	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
    	grid .$i -in .f -row $i -column $i -sticky nswe
    }
    pack propagate . 0
    grid propagate .f 0
    . configure -width 300 -height 250

    set res {}
    foreach a {n ne e se s sw w nw center} {
        grid anchor .f $a
        update
        lappend res [grid bbox .f]
    }
    pack propagate . 1 ; wm geometry . {}


    set res
} [list {37 20 225 150} {75 20 225 150} {75 60 225 150} {75 100 225 150} \
           {37 100 225 150} {0 100 225 150} {0 60 225 150} {0 20 225 150} \
           {37 60 225 150}]
grid_reset 21.7

test grid-22.1 {remove: basic argument checking} {
    list [catch {grid remove foo} msg] $msg
} {1 {bad window path name "foo"}}

test grid-22.2 {remove} {
    button .c
    grid [button .b]
    set a [grid slaves .]
    grid remove .b .c
    lappend a [grid slaves .]
    set a
} {.b {}}
grid_reset 22.2

test grid-22.3 {remove} {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
    grid remove .c
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx 3 -pady 4 -sticky ns}
grid_reset 22.3

test grid-22.3.1 {remove} {
    frame .a
    button .c
    grid .c -in .a -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid remove .c
    grid .c -row 0 -column 0
    grid info .c
} {-in .a -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx {3 5} -pady {4 7} -sticky ns}
grid_reset 22.3.1

test grid-22.4 {remove, calling Tk_UnmaintainGeometry} {
    frame .f -bd 2 -relief raised
    place .f -x 10 -y 20 -width 200 -height 100
    frame .f2 -width 50 -height 30 -bg red
    grid .f2 -in .f
    update
    set x [winfo ismapped .f2]
    grid remove .f2
    place .f -x 30
    update
    lappend x [winfo ismapped .f2]
} {1 0}
grid_reset 22.4

test grid-22.5 {remove} {
    frame .a
    button .c
    grid .c -in .a -row 2 -column 2 -rowspan 2 -columnspan 2 -padx {3 5} -pady {4 7} -sticky ns
    grid remove .c
    # If .a was destroyed while remembered by the removed .c, make sure it
    # is ignored.
    destroy .a
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx {3 5} -pady {4 7} -sticky ns}
grid_reset 22.5







































































































































# cleanup
cleanupTests
return




Deleted tests/iDOT.png.

cannot compute difference between binary files

Added tests/id.test.























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# This file is a Tcl script to test out the procedures in the file
# tkId.c, which recycle X resource identifiers.  It is organized in
# the standard fashion for Tcl tests.
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test id-1.1 {WindowIdCleanup, delaying window release} {unix testwrapper} {
    bind all <Destroy> {lappend x %W}
    catch {unset map}
    frame .f
    set j 0
    foreach i {a b c d e f g h i j k l m n o p q} {
	toplevel .f.$i -height 50 -width 100
	wm geometry .f.$i +$j+$j
	incr j 10
	update
	set map([winfo id .f.$i]) .f.$i
	set map([testwrapper .f.$i]) wrapper.f.$i
    }
    set x {}
    destroy .f

    # Destroy events should have occurred for all windows.
    set result [list [lsort $x]]

    set x {}
    update idletasks
    set reused {}
    foreach i {a b c d e} {
	set w .${i}2
	frame $w -height 20 -width 100 -bd 2 -relief raised
	pack $w
	if [info exists map([winfo id $w])] {
	    lappend reused $map([winfo id $w])
	}
	set map([winfo id $w]) $w
    }

    # No window ids should have been reused: stale Destroy events still
    # pending in queue.
    lappend result [lsort $reused]

    # Wait a few seconds, then try again;  ids should still not have
    # been re-used.

    set y 0
    after 2000 {set y 1}
    tkwait variable y
    foreach i {a b c} {
	set w .${i}3
	frame $w -height 20 -width 100 -bd 2 -relief raised
	pack $w
	if [info exists map([winfo id $w])] {
	    lappend reused $map([winfo id $w])
	}
	set map([winfo id $w])] $w
    }

    # Ids should not yet have been reused.
    lappend result [lsort $reused]


    # Wait a few more seconds, to give ids enough time to be recycled.
    set y 0
    after 6000 {set y 1}
    tkwait variable y
    foreach i {a b c d e f} {
	set w .${i}4
	frame $w -height 20 -width 100 -bd 2 -relief raised
	pack $w
	if [info exists map([winfo id $w])] {
	    lappend reused $map([winfo id $w])
	}
	set map([winfo id $w])] $w
    }

    # Ids should be reused now, due to time delay.  Destroy events should
    # have been discarded.
    lappend result [lsort $reused] [lsort $x]
} {{.f .f.a .f.b .f.c .f.d .f.e .f.f .f.g .f.h .f.i .f.j .f.k .f.l .f.m .f.n .f.o .f.p .f.q} {} {} {.f.o .f.p .f.q wrapper.f.p wrapper.f.q} {}}
bind all <Destroy> {}

# cleanup
cleanupTests
return

Changes to tests/image.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357


358
359

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615



616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# This file is a Tcl script to test out the "image" command and the
# other procedures in the file tkImage.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

imageInit

# Canvas used in some tests in the whole file

canvas .c -highlightthickness 2
pack .c
update


test image-1.1 {Tk_ImageCmd procedure, "create" option} -body {
    image
} -returnCodes error -result {wrong # args: should be "image option ?args?"}
test image-1.2 {Tk_ImageCmd procedure, "create" option} -body {
    image gorp
} -returnCodes error -result {bad option "gorp": must be create, delete, height, inuse, names, type, types, or width}
test image-1.3 {Tk_ImageCmd procedure, "create" option} -body {
    image create
} -returnCodes error -result {wrong # args: should be "image create type ?name? ?-option value ...?"}
test image-1.4 {Tk_ImageCmd procedure, "create" option} -body {
    image c bad_type
} -returnCodes error -result {image type "bad_type" doesn't exist}
test image-1.5 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType
} -body {
    list [image create test myimage] [imageNames]
} -cleanup {
    imageCleanup
} -result {myimage myimage}
test image-1.6 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    scan [image create test] image%d first
    image create test myimage
    scan [image create test -variable x] image%d second
    expr {$second-$first}
} -cleanup {
    imageCleanup
} -result 1

test image-1.7 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    image create test myimage -variable x
    update idletasks
    update
    # On MacOS we need to wait for the test image display procedure to run.
    while {"timed out" ni $x && [lindex $x end 1] ne "display"} {
        vwait x
    }
    after cancel timer
    if {[lindex $x end] eq "timed out"} {
       return [lreplace $x end end]
    }
    return $x
} -cleanup {
    imageCleanup
} -result {{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}}
test image-1.8 {Tk_ImageCmd procedure, "create" option} -constraints {
	testImageType
} -setup {
    .c delete all
    imageCleanup
} -body {
    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    image delete myimage
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    image create test myimage -variable x

    vwait x
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}}
test image-1.9 {Tk_ImageCmd procedure, "create" option} -constraints {

	testImageType
} -body {
    image create test -badName foo
} -returnCodes error -result {bad option name "-badName"}
test image-1.10 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType
} -body {
    catch {image create test -badName foo}
    imageNames
} -result {}
test image-1.11 {Tk_ImageCmd procedure, "create" option with same name as main window} -body {
    set code [loadTkCommand]
    append code {
	    update
	    puts [list [catch {image create photo .} msg] $msg]
	    exit
    }
    set script [makeFile $code script]
    exec [interpreter] <$script
} -cleanup {
    removeFile script

} -result {1 {images may not be named the same as the main window}}
test image-1.12 {Tk_ImageCmd procedure, "create" option with same name as main window after renaming} -body {
    set code [loadTkCommand]
    append code {
	    update
	    puts [list [catch {rename . foo;image create photo foo} msg] $msg]
	    exit
    }
    set script [makeFile $code script]
    exec [interpreter] <$script
} -cleanup {
    removeFile script

} -result {1 {images may not be named the same as the main window}}
test image-1.13 {Tk_ImageCmd, "create" option: do not generated command name in use} -setup {
    .c delete all
    imageCleanup
} -body {
    set i [image create bitmap]
    regexp {^image(\d+)$} $i -> serial
    incr serial
    proc image$serial {} {return works}
    set j [image create bitmap]

    image$serial
} -cleanup {
    rename image$serial {}
    image delete $i $j
} -result works

test image-2.1 {Tk_ImageCmd procedure, "delete" option} -body {
    image delete
} -result {}
test image-2.2 {Tk_ImageCmd procedure, "delete" option} -constraints {
    testImageType
} -setup {
    imageCleanup
    set result {}
} -body {
    image create test myimage
    image create test img2

    lappend result [lsort [imageNames]]
    image d myimage img2
    lappend result [imageNames]
} -cleanup {
    imageCleanup
} -result {{img2 myimage} {}}
test image-2.3 {Tk_ImageCmd procedure, "delete" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    image create test img2
    image delete myimage gorp img2
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "gorp" doesn't exist}
test image-2.4 {Tk_ImageCmd procedure, "delete" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    image create test img2
    catch {image delete myimage gorp img2}
    imageNames
} -cleanup {
    imageCleanup
} -result {img2}


test image-3.1 {Tk_ImageCmd procedure, "height" option} -body {
    image height
} -returnCodes error -result {wrong # args: should be "image height name"}
test image-3.2 {Tk_ImageCmd procedure, "height" option} -body {
    image height a b
} -returnCodes error -result {wrong # args: should be "image height name"}
test image-3.3 {Tk_ImageCmd procedure, "height" option} -body {
    image height foo
} -returnCodes error -result {image "foo" doesn't exist}
test image-3.4 {Tk_ImageCmd procedure, "height" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    set x [image h myimage]
    myimage changed 0 0 0 0 60 50
    list $x [image height myimage]
} -cleanup {
    imageCleanup
} -result {15 50}


test image-4.1 {Tk_ImageCmd procedure, "names" option} -body {
    image names x
} -returnCodes error -result {wrong # args: should be "image names"}
test image-4.2 {Tk_ImageCmd procedure, "names" option} -constraints {
    testImageType
} -setup {
    catch {interp delete testinterp}
} -body {
    interp create testinterp
    load {} Tk testinterp
    interp eval testinterp {
        image delete {*}[image names]
        image create test myimage
        image create test img2
        image create test 24613
        lsort [image names]
    }
} -cleanup {
    interp delete testinterp
} -result {24613 img2 myimage}
test image-4.3 {Tk_ImageCmd procedure, "names" option} -setup {
    catch {interp delete testinterp}
} -body {
    interp create testinterp

    load {} Tk testinterp
    interp eval testinterp {
        image delete {*}[image names]
        eval image delete [image names] [image names]
        lsort [image names]
    }
} -cleanup {
    interp delete testinterp
} -result {}


test image-5.1 {Tk_ImageCmd procedure, "type" option} -body {
    image type
} -returnCodes error -result {wrong # args: should be "image type name"}
test image-5.2 {Tk_ImageCmd procedure, "type" option} -body {
    image type a b
} -returnCodes error -result {wrong # args: should be "image type name"}
test image-5.3 {Tk_ImageCmd procedure, "type" option} -body {
    image type foo
} -returnCodes error -result {image "foo" doesn't exist}

test image-5.4 {Tk_ImageCmd procedure, "type" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    image type myimage
} -cleanup {
    imageCleanup
} -result {test}
test image-5.5 {Tk_ImageCmd procedure, "type" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    .c create image 50 50 -image myimage
    image delete myimage
    image type myimage
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "myimage" doesn't exist}
test image-5.6 {Tk_ImageCmd procedure, "type" option} -constraints {
    testOldImageType
} -setup {
    imageCleanup
} -body {
    image create oldtest myimage
    image type myimage
} -cleanup {
    imageCleanup
} -result {oldtest}
test image-5.7 {Tk_ImageCmd procedure, "type" option} -constraints {
    testOldImageType
} -setup {
    .c delete all
    imageCleanup
} -body {
    image create oldtest myimage
    .c create image 50 50 -image myimage
    image delete myimage
    image type myimage
} -cleanup {



    .c delete all
    imageCleanup
} -returnCodes error -result {image "myimage" doesn't exist}


test image-6.1 {Tk_ImageCmd procedure, "types" option} -constraints {
    testImageType
} -body {
    image types x
} -returnCodes error -result {wrong # args: should be "image types"}
test image-6.2 {Tk_ImageCmd procedure, "types" option} -body {
    lsort [image types]
} -match glob -result {bitmap*photo test}


test image-7.1 {Tk_ImageCmd procedure, "width" option} -body {
    image width
} -returnCodes error -result {wrong # args: should be "image width name"}
test image-7.2 {Tk_ImageCmd procedure, "width" option} -body {
    image width a b
} -returnCodes error -result {wrong # args: should be "image width name"}
test image-7.3 {Tk_ImageCmd procedure, "width" option} -body {
    image width foo
} -returnCodes error -result {image "foo" doesn't exist}
test image-7.4 {Tk_ImageCmd procedure, "width" option} -constraints {
    testImageType
} -setup {
    imageCleanup
} -body {
    image create test myimage
    set x [image w myimage]
    myimage changed 0 0 0 0 60 50
    list $x [image width myimage]
} -cleanup {
    imageCleanup
} -result {30 60}


test image-8.1 {Tk_ImageCmd procedure, "inuse" option} -constraints {
    testImageType
} -setup {
    imageCleanup
    set res {}
    destroy .b
} -body {
    image create test myimage2
    lappend res [image inuse myimage2]

    button .b -image myimage2
    lappend res [image inuse myimage2]
} -cleanup {
    imageCleanup
    catch {destroy .b}


} -result [list 0 1]


test image-9.1 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    foo changed 5 6 7 8 30 15
    update idletasks
    update
    # On MacOS we need to wait for the test image display procedure to run.
    while {"timed out" ni $x && [lindex $x end 1] ne "display"} {
        vwait x
    }
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 7 8}}

test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    set timer [after 500 {lappend x "timed out"}]
    image create test myimage -variable x
    vwait x
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 25 9} {foo display 0 0 12 14}}

test image-10.1 {Tk_GetImage procedure} -setup {
    imageCleanup
} -body {
    .c create image 100 10 -image bad_name
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "bad_name" doesn't exist}
test image-10.2 {Tk_GetImage procedure} -constraints testImageType -setup {
    destroy .l
    imageCleanup
} -body {
    image create test mytest

    label .l -image mytest
    image delete  mytest
    label .l2 -image mytest
} -cleanup {
    destroy .l
    imageCleanup

} -returnCodes error -result {image "mytest" doesn't exist}


test image-11.1 {Tk_FreeImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    pack forget .c
    update
    set x {}
    .c delete i1
    set timer [after 500 {lappend x "timed out"}]
    pack .c
    vwait x
    after cancel $timer
    list [imageNames] $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {foo {{foo free} {foo display 0 0 30 15}}}
test image-11.2 {Tk_FreeImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    set names [imageNames]
    image delete foo
    update
    set names2 [imageNames]
    set x {}
    .c delete i1
    pack forget .c
    pack .c
    update
    list $names $names2 [imageNames] $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {foo {} {} {}}


# Non-portable, apparently due to differences in rounding:

test image-12.1 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 30 40 55 65 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 0 0 5 5 50 50}}
test image-12.2 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 60 40 100 65 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 10 0 20 5 30 50}}
test image-12.3 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 60 70 100 200 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 10 10 20 5 30 30}}
test image-12.4 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 30 70 55 200 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 0 10 5 5 50 30}}
test image-12.5 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 10 20 120 130 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 0 0 30 15 70 70}}
test image-12.6 {Tk_RedrawImage procedure, redisplay area clipping} -constraints {
    testImageType nonPortable
} -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 55 65 75 70 -width 0 -fill black -outline {}
    set x {}
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{foo display 5 5 20 5 30 30}}


test image-13.1 {Tk_SizeOfImage procedure} -constraints testImageType -setup {
    imageCleanup
} -body {
    image create test foo -variable x
    set result [list [image width foo] [image height foo]]
    foo changed 0 0 0 0 85 60
    lappend result [image width foo] [image height foo]
} -cleanup {
    imageCleanup
} -result {30 15 85 60}

test image-13.2 {DeleteImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    set x {}
    image delete foo
    lappend x | [imageNames] | [catch {image delete foo} msg] | $msg | [imageNames] |
} -cleanup {
    imageCleanup
} -result {{foo free} {foo free} {foo delete} | {} | 1 | {image "foo" doesn't exist} | {} |}

test image-13.3 {Tk_SizeOfImage procedure} -constraints testOldImageType -setup {
    imageCleanup
} -body {
    image create oldtest foo -variable x
    set result [list [image width foo] [image height foo]]
    foo changed 0 0 0 0 85 60
    lappend result [image width foo] [image height foo]
} -cleanup {
    imageCleanup
} -result {30 15 85 60}

test image-13.4 {DeleteImage procedure} -constraints testOldImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create oldtest foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    set x {}
    image delete foo
    lappend x | [imageNames] | [catch {image delete foo} msg] | $msg | [imageNames] |
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo free} {foo free} {foo delete} | {} | 1 | {image "foo" doesn't exist} | {} |}

test image-14.1 {image command vs hidden commands} -body {
    catch {image delete hidden}
    set l [imageNames]
    set h [interp hidden]



    image create photo hidden
    interp hide {} hidden
    image delete hidden
    set res1 [list [imageNames] [interp hidden]]
    set res2 [list $l $h]
    expr {$res1 eq $res2}
} -result 1


test image-15.1 {deleting image does not make widgets forget about it} -setup {
    .c delete all
    imageCleanup
} -body {
    image create photo foo -width 10 -height 10
    .c create image 10 10 -image foo -tags i1 -anchor nw
    update
    set x [.c bbox i1]
    lappend x [imageNames]
    image delete foo
    lappend x [imageNames]
    image create photo foo -width 20 -height 20
    lappend x [.c bbox i1] [imageNames]
} -cleanup {
    .c delete all
    imageCleanup
} -result {10 10 20 20 foo {} {10 10 30 30} foo}

destroy .c
imageFinish

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:




|
|
|



<


|
<

<
>



<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
<
|
|
<
<
<
<



|
<
<
<
|
|
<
<
|
<





<

<

<
<
|
<
<
<
<
<
<
<
<
|
|
<
<

<
<






<

>
|
<
<
<
<
<
|
|
>
|
<
|
|
|
<
<
<
<
<
<


|
|
|


|
<

>
|
|


|
|
|


|
<

>
|
|
<
<
<





|






|
|
|
|
<
|
|
<
<


>
|

|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<


|
<
<
<
<
|

|
|
|
|
|
|
|
|
|
|
<
<
<
<




<
<
|

<
|
|
|
|
<
<
|
<
<
<
<
|
|
|
|
|
<
<
<
|
|
|
<
|
>
|
<
<
<
<
|
<
<
<
<
<
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<


<
<
<
<
|
<
|
<



|
<
<
|
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<

|
>
>
>
|
|
|

<
|
<
<
|
|
|

<
|

|
|
|
|
|
|
|
|
|
|
<
<
<
<




<
<
|

<
|
|
<
|

<
<
<

>


<
<

>
>
|

>
|

|
<
<




<

<

<
<
|
<
<
<
<
<
<
|
<
|

|
<
<






<
|
|
<
<
<
<
<
|

|
<
<
|
<
<
|
|
<
<
<

>


|
<

<
>
|

<
|

|
<







<

|
<
|
<
<
<
|
|

|
<


|


|





|
<
<
<
|

<

>
|
|
|
|
<






|
<
<
|
|
|
|
|
<






|
<
<
|
|
|
|
|
<






|
<
<
|
|
|
|
|
<






|
<
<
|
|
|
|
|
<






|
<
<
|
|
|
|
|
<






|
<
<
|

<
|
|
<




<
<
|

|

|
<





|
<
<
|

|
|
<




<
<
|

|

|
<





|
<
<
<
|

|
|
|
|
>
>
>



|
|
<
<

>
|

<
<




|

|

|
<
<
<
|


|




<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12
13

14

15
16
17
18


19
20
21
22
23
24
25
26
27
28
29
30
31


32


33
34




35
36
37
38



39
40


41

42
43
44
45
46

47

48


49








50
51


52


53
54
55
56
57
58

59
60
61





62
63
64
65

66
67
68






69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110


111
112
113
114
115
116


117











118

119
120

121
122
123




124
125
126
127
128
129
130
131
132
133
134
135




136
137
138
139


140
141

142
143
144
145


146




147
148
149
150
151



152
153
154

155
156
157




158





159
160
161
162
163
164
165
166
167

168




169
170




171

172

173
174
175
176


177
178




179













180
181
182
183
184
185
186
187
188

189


190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205




206
207
208
209


210
211

212
213

214
215



216
217
218
219


220
221
222
223
224
225
226
227
228


229
230
231
232

233

234


235






236

237
238
239


240
241
242
243
244
245

246
247





248
249
250


251


252
253



254
255
256
257
258

259

260
261
262

263
264
265

266
267
268
269
270
271
272

273
274

275



276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291



292
293

294
295
296
297
298
299

300
301
302
303
304
305
306


307
308
309
310
311

312
313
314
315
316
317
318


319
320
321
322
323

324
325
326
327
328
329
330


331
332
333
334
335

336
337
338
339
340
341
342


343
344
345
346
347

348
349
350
351
352
353
354


355
356
357
358
359

360
361
362
363
364
365
366


367
368

369
370

371
372
373
374


375
376
377
378
379

380
381
382
383
384
385


386
387
388
389

390
391
392
393


394
395
396
397
398

399
400
401
402
403
404



405
406
407
408
409
410
411
412
413
414
415
416
417
418


419
420
421
422


423
424
425
426
427
428
429
430
431



432
433
434
435
436
437
438
439




# This file is a Tcl script to test out the "image" command and the
# other procedures in the file tkImage.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force ::tk::test::loadTkCommand



eval image delete [image names]
canvas .c -highlightthickness 2
pack .c
update


test image-1.1 {Tk_ImageCmd procedure, "create" option} {
    list [catch image msg] $msg
} {1 {wrong # args: should be "image option ?args?"}}
test image-1.2 {Tk_ImageCmd procedure, "create" option} {
    list [catch {image gorp} msg] $msg
} {1 {bad option "gorp": must be create, delete, height, inuse, names, type, types, or width}}
test image-1.3 {Tk_ImageCmd procedure, "create" option} {
    list [catch {image create} msg] $msg
} {1 {wrong # args: should be "image create type ?name? ?options?"}}
test image-1.4 {Tk_ImageCmd procedure, "create" option} {
    list [catch {image c bad_type} msg] $msg
} {1 {image type "bad_type" doesn't exist}}
test image-1.5 {Tk_ImageCmd procedure, "create" option} testImageType {


    list [image create test myimage] [image names]


} {myimage myimage}
test image-1.6 {Tk_ImageCmd procedure, "create" option} testImageType {




    scan [image create test] image%d first
    image create test myimage
    scan [image create test -variable x] image%d second
    expr $second-$first



} {1}
test image-1.7 {Tk_ImageCmd procedure, "create" option} testImageType {


    image delete myimage

    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    update
    set x {}

    image create test myimage -variable x

    update


    set x








} {{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}}
test image-1.8 {Tk_ImageCmd procedure, "create" option} testImageType {


    .c delete all


    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    image delete myimage
    update
    set x {}

    image create test myimage -variable x
    update
    set x





} {{myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}}
test image-1.9 {Tk_ImageCmd procedure, "create" option} testImageType {
    .c delete all
    eval image delete [image names]

    list [catch {image create test -badName foo} msg] $msg [image names]
} {1 {bad option name "-badName"} {}}
test image-1.10 {Tk_ImageCmd procedure, "create" option with same name as main window} {






    set code [loadTkCommand]
    append code {
	update
	puts [list [catch {image create photo .} msg] $msg]
	exit
    }
    set script [makeFile $code script]
    set x [list [catch {exec [interpreter] <$script} msg] $msg]

    removeFile script
    set x
} {0 {1 {images may not be named the same as the main window}}}
test image-1.11 {Tk_ImageCmd procedure, "create" option with same name as main window after renaming} {
    set code [loadTkCommand]
    append code {
	update
	puts [list [catch {rename . foo;image create photo foo} msg] $msg]
	exit
    }
    set script [makeFile $code script]
    set x [list [catch {exec [interpreter] <$script} msg] $msg]

    removeFile script
    set x
} {0 {1 {images may not be named the same as the main window}}}
test image-1.12 {Tk_ImageCmd, "create" option: do not generated command name in use} -setup {



    set i [image create bitmap]
    regexp {^image(\d+)$} $i -> serial
    incr serial
    proc image$serial {} {return works}
    set j [image create bitmap]
} -body {
    image$serial
} -cleanup {
    rename image$serial {}
    image delete $i $j
} -result works

test image-2.1 {Tk_ImageCmd procedure, "delete" option} {
    list [catch {image delete} msg] $msg
} {0 {}}
test image-2.2 {Tk_ImageCmd procedure, "delete" option} testImageType {

    .c delete all
    eval image delete [image names]


    image create test myimage
    image create test img2
    set result {}
    lappend result [lsort [image names]]
    image d myimage img2
    lappend result [image names]


} {{img2 myimage} {}}











test image-2.3 {Tk_ImageCmd procedure, "delete" option} testImageType {

    .c delete all
    eval image delete [image names]

    image create test myimage
    image create test img2
    list [catch {image delete myimage gorp img2} msg] $msg [image names]




} {1 {image "gorp" doesn't exist} img2}

test image-3.1 {Tk_ImageCmd procedure, "height" option} {
    list [catch {image height} msg] $msg
} {1 {wrong # args: should be "image height name"}}
test image-3.2 {Tk_ImageCmd procedure, "height" option} {
    list [catch {image height a b} msg] $msg
} {1 {wrong # args: should be "image height name"}}
test image-3.3 {Tk_ImageCmd procedure, "height" option} {
    list [catch {image height foo} msg] $msg
} {1 {image "foo" doesn't exist}}
test image-3.4 {Tk_ImageCmd procedure, "height" option} testImageType {




    image create test myimage
    set x [image h myimage]
    myimage changed 0 0 0 0 60 50
    list $x [image height myimage]


} {15 50}


test image-4.1 {Tk_ImageCmd procedure, "names" option} {
    list [catch {image names x} msg] $msg
} {1 {wrong # args: should be "image names"}}
test image-4.2 {Tk_ImageCmd procedure, "names" option} testImageType {


    .c delete all




    eval image delete [image names]
    image create test myimage
    image create test img2
    image create test 24613
    lsort [image names]



} {24613 img2 myimage}
test image-4.3 {Tk_ImageCmd procedure, "names" option} {
    .c delete all

    eval image delete [image names]
    lsort [image names]
} {}










test image-5.1 {Tk_ImageCmd procedure, "type" option} {
    list [catch {image type} msg] $msg
} {1 {wrong # args: should be "image type name"}}
test image-5.2 {Tk_ImageCmd procedure, "type" option} {
    list [catch {image type a b} msg] $msg
} {1 {wrong # args: should be "image type name"}}
test image-5.3 {Tk_ImageCmd procedure, "type" option} {
    list [catch {image type foo} msg] $msg
} {1 {image "foo" doesn't exist}}

test image-5.4 {Tk_ImageCmd procedure, "type" option} testImageType {




    image create test myimage
    image type myimage




} {test}

test image-5.5 {Tk_ImageCmd procedure, "type" option} testImageType {

    image create test myimage
    .c create image 50 50 -image myimage
    image delete myimage
    list [catch {image type myimage} msg] $msg


} {1 {image "myimage" doesn't exist}}
test image-5.6 {Tk_ImageCmd procedure, "type" option} testOldImageType {




    image create oldtest myimage













    image type myimage
} {oldtest}
test image-5.7 {Tk_ImageCmd procedure, "type" option} testOldImageType {
    image create oldtest myimage
    .c create image 50 50 -image myimage
    image delete myimage
    list [catch {image type myimage} msg] $msg
} {1 {image "myimage" doesn't exist}}


test image-6.1 {Tk_ImageCmd procedure, "types" option} {


    list [catch {image types x} msg] $msg
} {1 {wrong # args: should be "image types"}}
test image-6.2 {Tk_ImageCmd procedure, "types" option} testImageType {
    lsort [image types]

} {bitmap oldtest photo test}

test image-7.1 {Tk_ImageCmd procedure, "width" option} {
    list [catch {image width} msg] $msg
} {1 {wrong # args: should be "image width name"}}
test image-7.2 {Tk_ImageCmd procedure, "width" option} {
    list [catch {image width a b} msg] $msg
} {1 {wrong # args: should be "image width name"}}
test image-7.3 {Tk_ImageCmd procedure, "width" option} {
    list [catch {image width foo} msg] $msg
} {1 {image "foo" doesn't exist}}
test image-7.4 {Tk_ImageCmd procedure, "width" option} testImageType {




    image create test myimage
    set x [image w myimage]
    myimage changed 0 0 0 0 60 50
    list $x [image width myimage]


} {30 60}


test image-8.1 {Tk_ImageCmd procedure, "inuse" option} testImageType {
    catch {image delete myimage2}

    image create test myimage2
    set res {}



    lappend res [image inuse myimage2]
    catch {destroy .b}
    button .b -image myimage2
    lappend res [image inuse myimage2]


    catch {destroy .b}
    image delete myimage2
    set res
} [list 0 1]


test image-9.1 {Tk_ImageChanged procedure} testImageType {
    .c delete all
    eval image delete [image names]


    image create test foo -variable x
    .c create image 50 50 -image foo
    update
    set x {}

    foo changed 5 6 7 8 30 15

    update


    set x






} {{foo display 5 6 7 8 30 30}}

test image-9.2 {Tk_ImageChanged procedure} testImageType {
    .c delete all
    eval image delete [image names]


    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15

    update
    set x





} {{foo display 5 6 25 9 30 30} {foo display 0 0 12 14 65 74}}

test image-10.1 {Tk_GetImage procedure} {


    list [catch {.c create image 100 10 -image bad_name} msg] $msg


} {1 {image "bad_name" doesn't exist}}
test image-10.2 {Tk_GetImage procedure} testImageType {



    image create test mytest
    catch {destroy .l}
    label .l -image mytest
    image delete  mytest
    set result [list [catch {label .l2 -image mytest} msg] $msg]

    destroy .l

    set result
} {1 {image "mytest" doesn't exist}}


test image-11.1 {Tk_FreeImage procedure} testImageType {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    pack forget .c
    update
    set x {}
    .c delete i1

    pack .c
    update

    list [image names] $x



} {foo {{foo free} {foo display 0 0 30 15 103 121}}}
test image-11.2 {Tk_FreeImage procedure} testImageType {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    set names [image names]
    image delete foo
    update
    set names2 [image names]
    set x {}
    .c delete i1
    pack forget .c
    pack .c
    update
    list $names $names2 [image names] $x



} {foo {} {} {}}


# Non-portable, apparently due to differences in rounding:

test image-12.1 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 30 40 55 65 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 0 0 5 5 50 50}}
test image-12.2 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 60 40 100 65 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 10 0 20 5 30 50}}
test image-12.3 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 60 70 100 200 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 10 10 20 5 30 30}}
test image-12.4 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 30 70 55 200 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 0 10 5 5 50 30}}
test image-12.5 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 10 20 120 130 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 0 0 30 15 70 70}}
test image-12.6 {Tk_RedrawImage procedure, redisplay area clipping} \
	{testImageType nonPortable} {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 60 -image foo -tags i1 -anchor nw
    update
    .c create rectangle 55 65 75 70 -width 0 -fill black -outline {}
    set x {}
    update
    set x


} {{foo display 5 5 20 5 30 30}}


test image-13.1 {Tk_SizeOfImage procedure} testImageType {
    eval image delete [image names]

    image create test foo -variable x
    set result [list [image width foo] [image height foo]]
    foo changed 0 0 0 0 85 60
    lappend result [image width foo] [image height foo]


} {30 15 85 60}

test image-13.2 {DeleteImage procedure} testImageType {
    .c delete all
    eval image delete [image names]

    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    set x {}
    image delete foo
    lappend x | [image names] | [catch {image delete foo} msg] | $msg | [image names] |


} {{foo free} {foo free} {foo delete} | {} | 1 | {image "foo" doesn't exist} | {} |}

test image-13.3 {Tk_SizeOfImage procedure} testOldImageType {
    eval image delete [image names]

    image create oldtest foo -variable x
    set result [list [image width foo] [image height foo]]
    foo changed 0 0 0 0 85 60
    lappend result [image width foo] [image height foo]


} {30 15 85 60}

test image-13.4 {DeleteImage procedure} testOldImageType {
    .c delete all
    eval image delete [image names]

    image create oldtest foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    set x {}
    image delete foo
    lappend x | [image names] | [catch {image delete foo} msg] | $msg | [image names] |



} {{foo free} {foo free} {foo delete} | {} | 1 | {image "foo" doesn't exist} | {} |}


catch {image delete hidden}
set l [image names]
set h [interp hidden]

test image-14.1 {image command vs hidden commands} {
    catch {image delete hidden}
    image create photo hidden
    interp hide {} hidden
    image delete hidden
    list [image names] [interp hidden]
} [list $l $h]



eval image delete [image names]
test image-15.1 {deleting image does not make widgets forget about it} {
    .c delete all


    image create photo foo -width 10 -height 10
    .c create image 10 10 -image foo -tags i1 -anchor nw
    update
    set x [.c bbox i1]
    lappend x [image names]
    image delete foo
    lappend x [image names]
    image create photo foo -width 20 -height 20
    lappend x [.c bbox i1] [image names]



} {10 10 20 20 foo {} {10 10 30 30} foo}

destroy .c
eval image delete [image names]

# cleanup
cleanupTests
return




Changes to tests/imgBmap.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out images of type "bitmap" (i.e.,
# the procedures in the file tkImgBmap.c).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

set data1 {#define foo_width 16
#define foo_height 16
#define foo_x_hot 3
#define foo_y_hot 3
static unsigned char foo_bits[] = {
   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,




|
|
|



<


<







1
2
3
4
5
6
7
8
9
10

11
12

13
14
15
16
17
18
19
# This file is a Tcl script to test out images of type "bitmap" (i.e.,
# the procedures in the file tkImgBmap.c).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


set data1 {#define foo_width 16
#define foo_height 16
#define foo_x_hot 3
#define foo_y_hot 3
static unsigned char foo_bits[] = {
   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228


229
230
231


232
233
234


235
236
237


238
239
240


241
242
243


244
245
246


247
248
249


250
251
252
253
254
255
256
257
258
259
260
261
262
263


264
265
266
267
268
269
270
271
272
273
274
275
276


277
278
279
280
281
282
283
284
285
286
287


288
289
290
291
292
293
294
295
296
297
298


299
300
301
302
303
304


305
306
307
308
309
310


311
312
313
314
315
316
317
318
319
320
321


322
323
324
325
326
327
328
329
330
331
332
333
334


335
336
337


338
339
340
341


342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
       0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
       0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
       0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0xff};
}
makeFile $data1 foo.bm
makeFile $data2 foo2.bm

imageCleanup
#canvas .c
#pack .c
#update
#image create bitmap i1
#.c create image 200 100 -image i1
update
proc bgerror msg {
    global errMsg
    set errMsg $msg
}

test imageBmap-1.1 {options for bitmap images} -body {
    image create bitmap i1 -background #123456
    lindex [i1 configure -background] 4
} -cleanup {
	image delete i1
} -result {#123456}
test imageBmap-1.2 {options for bitmap images} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    set errMsg {}
    image create bitmap i1 -background lousy
    .c create image 200 100 -image i1
    update
    list $errMsg $errorInfo
} -cleanup {
	image delete i1
    destroy .c
} -result {{unknown color name "lousy"} {unknown color name "lousy"
    (while configuring image "i1")}}
test imageBmap-1.3 {options for bitmap images} -body {
    image create bitmap i1 -data $data1
    lindex [i1 configure -data] 4
} -result $data1
test imageBmap-1.4 {options for bitmap images} -body {
    image create bitmap i1 -data bogus
} -returnCodes error -result {format error in bitmap data}
test imageBmap-1.5 {options for bitmap images} -body {
    image create bitmap i1 -file foo.bm
    lindex [i1 configure -file] 4
} -result foo.bm
test imageBmap-1.6 {options for bitmap images} -body {
    list [catch {image create bitmap i1 -file bogus} msg] [string tolower $msg]
} -result {1 {couldn't read bitmap file "bogus": no such file or directory}}
test imageBmap-1.7 {options for bitmap images} -body {
    image create bitmap i1 -foreground #00ff00
    lindex [i1 configure -foreground] 4
} -cleanup {
	image delete i1
} -result {#00ff00}
test imageBmap-1.8 {options for bitmap images} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    set errMsg {}
    image create bitmap i1 -foreground bad_color
    .c create image 200 100 -image i1
    update
    list $errMsg $errorInfo
} -cleanup {
    destroy .c
	image delete i1
} -result {{unknown color name "bad_color"} {unknown color name "bad_color"
    (while configuring image "i1")}}
test imageBmap-1.9 {options for bitmap images} -body {
    image create bitmap i1 -data $data1 -maskdata $data2
    lindex [i1 configure -maskdata] 4
} -result $data2
test imageBmap-1.10 {options for bitmap images} -body {
    image create bitmap i1 -data $data1 -maskdata bogus
} -returnCodes error -result {format error in bitmap data}
test imageBmap-1.11 {options for bitmap images} -body {
    image create bitmap i1 -file foo.bm -maskfile foo2.bm
    lindex [i1 configure -maskfile] 4
} -result foo2.bm
test imageBmap-1.12 {options for bitmap images} -body {
    list [catch {image create bitmap i1 -data $data1 -maskfile bogus} msg] \
	    [string tolower $msg]
} -result {1 {couldn't read bitmap file "bogus": no such file or directory}}
rename bgerror {}


test imageBmap-2.1 {ImgBmapCreate procedure} -setup {
    imageCleanup
} -body {

    list [catch {image create bitmap -gorp dum} msg] $msg [imageNames]
} -result {1 {unknown option "-gorp"} {}}
test imageBmap-2.2 {ImgBmapCreate procedure} -setup {
    imageCleanup
} -body {

    image create bitmap image1
    list [info commands image1] [imageNames] \
	    [image width image1] [image height image1] \
	    [lindex [image1 configure -foreground] 4] \
	    [lindex [image1 configure -background] 4]
} -cleanup {
    image delete image1
} -result {image1 image1 0 0 #000000 {}}


test imageBmap-3.1 {ImgBmapConfigureModel procedure, memory de-allocation} -body {
    image create bitmap i1 -data $data1
    i1 configure -data $data1
} -cleanup {
	image delete i1
} -result {}
test imageBmap-3.2 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1
    list [catch {i1 configure -data bogus} msg] $msg [image width i1] \
	    [image height i1]
} -result {1 {format error in bitmap data} 16 16}
test imageBmap-3.3 {ImgBmapConfigureModel procedure, memory de-allocation} -body {
    image create bitmap i1 -data $data1 -maskdata $data2
    i1 configure -maskdata $data2
} -cleanup {
	image delete i1
} -result {}
test imageBmap-3.4 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1
    i1 configure -maskdata $data2
} -returnCodes error -result {can't have mask without bitmap}
test imageBmap-3.5 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 8
	#define foo_height 16
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}

} -returnCodes error -result {bitmap and mask have different sizes}
test imageBmap-3.6 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 16
	#define foo_height 8
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}

} -returnCodes error -result {bitmap and mask have different sizes}
test imageBmap-3.7 {ImgBmapConfigureModel procedure} -setup {
    destroy .c
    pack [canvas .c]
} -body {
    image create bitmap i1 -data $data1
    .c create image 100 100 -image i1 -tags i1.1 -anchor nw
    .c create image 200 100 -image i1 -tags i1.2 -anchor nw
    update
    i1 configure -data {
	#define foo2_height 14
	#define foo2_width 15
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }
    update
    list [image width i1] [image height i1] [.c bbox i1.1] [.c bbox i1.2]
} -cleanup {
	image delete i1
    destroy .c
} -result {15 14 {100 100 115 114} {200 100 215 114}}


test imageBmap-4.1 {ImgBmapConfigureInstance procedure: check error handling} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    proc bgerror args {}

    image create bitmap i1 -file foo.bm
    .c create image 100 100 -image i1
    update
    i1 configure -foreground bogus
    update
} -cleanup {
	image delete i1
    destroy .c
} -result {}


test imageBmap-5.1 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file ~bad_user/a/b} msg] \
	    [string tolower $msg]
} -result {1 {user "bad_user" doesn't exist}}
test imageBmap-5.2 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file bad_name} msg] [string tolower $msg]
} -result {1 {couldn't read bitmap file "bad_name": no such file or directory}}
test imageBmap-5.3 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data { }
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.4 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_width"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.5 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_width gorp"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.6 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_width 1.4"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.7 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_height"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.8 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_height gorp"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.9 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap -data "#define foo2_height 1.4"
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.10 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_height 14
	#define foo2_width 15 xx _widtg 18 xwidth 18 _heighz 18 xheight 18
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }
    list [image width i1] [image height i1]
} -cleanup {
    image delete i1
} -result {15 14}
test imageBmap-5.11 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	_height 14 _width 15
	char {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff}
    }
    list [image width i1] [image height i1]
} -cleanup {
    image delete i1
} -result {15 14}
test imageBmap-5.12 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_height 14
	#define foo2_width 15
	static short foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }
} -returnCodes error -result {format error in bitmap data; looks like it's an obsolete X10 bitmap file}
test imageBmap-5.13 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] =
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff;
    }
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.14 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_width 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, }}
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.15 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_height 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, }}
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.16 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, foo};
    }
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.17 {GetBitmapData procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data "
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] = \{
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff
    "
} -returnCodes error -result {format error in bitmap data}


test imageBmap-6.1 {NextBitmapWord procedure} -setup {imageCleanup} -body {


    image create bitmap i1 -data {1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890}
} -returnCodes error -result {format error in bitmap data}
test imageBmap-6.2 {NextBitmapWord procedure} -setup {imageCleanup} -body {


    makeFile {1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890} foo3.bm
    image create bitmap i1 -file foo3.bm
} -returnCodes error -result {format error in bitmap data}
test imageBmap-6.3 {NextBitmapWord procedure} -setup {imageCleanup} -body {


    makeFile {   } foo3.bm
    image create bitmap i1 -file foo3.bm
} -returnCodes error -result {format error in bitmap data}
removeFile foo3.bm


imageCleanup
# Image used in 7.* tests
image create bitmap i1
test imageBmap-7.1 {ImgBmapCmd procedure} -body {
    i1
} -returnCodes error -result {wrong # args: should be "i1 option ?arg ...?"}
test imageBmap-7.2 {ImgBmapCmd procedure, "cget" option} -body {
    i1 cget
} -returnCodes error -result {wrong # args: should be "i1 cget option"}
test imageBmap-7.3 {ImgBmapCmd procedure, "cget" option} -body {
    i1 cget a b
} -returnCodes error -result {wrong # args: should be "i1 cget option"}
test imageBmap-7.4 {ImgBmapCmd procedure, "cget" option} -body {
    i1 co -foreground #123456
    i1 cget -foreground
} -result {#123456}
test imageBmap-7.5 {ImgBmapCmd procedure, "cget" option} -body {
    i1 cget -stupid
} -returnCodes error -result {unknown option "-stupid"}
test imageBmap-7.6 {ImgBmapCmd procedure} -body {
    llength [i1 configure]
} -result 6
test imageBmap-7.7 {ImgBmapCmd procedure} -body {
    i1 co -foreground #001122
    i1 configure -foreground
} -result {-foreground {} {} #000000 #001122}
test imageBmap-7.8 {ImgBmapCmd procedure} -body {
    i1 configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test imageBmap-7.9 {ImgBmapCmd procedure} -body {
    i1 configure -foreground #221100 -background
} -returnCodes error -result {value for "-background" missing}
test imageBmap-7.10 {ImgBmapCmd procedure} -body {
    i1 gorp
} -returnCodes error -result {bad option "gorp": must be cget or configure}
# Clean it up after use!!
imageCleanup

test imageBmap-8.1 {ImgBmapGet/Free procedures, shared instances} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    .c create image 150 100 -image i1 -tags i1.2
    .c create image 250 100 -image i1 -tags i1.3
    update
    .c delete i1.1
    i1 configure -background black
    update
    .c delete i1.2
    i1 configure -background white
    update
    .c delete i1.3
    i1 configure -background black
    update
    image delete i1
} -cleanup {
    destroy .c
} -result {}


test imageBmap-9.1 {ImgBmapDisplay procedure, nothing to display} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    proc bgerror args {}
    imageCleanup

    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    i1 configure -data {}
    update
} -cleanup {
    image delete i1
    destroy .c
} -result {}
test imageBmap-9.2 {ImgBmapDisplay procedure, nothing to display} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    proc bgerror args {}
    imageCleanup
    .c delete all
    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    i1 configure -foreground bogus
    update
} -cleanup {
    image delete i1
    destroy .c
} -result {}
if {[info exists bgerror]} {
    rename bgerror {}
}


test imageBmap-10.1 {ImgBmapFree procedure, resource freeing} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    imageCleanup
    image create bitmap i1 -data $data1 -maskdata $data2 -foreground #112233 \
	    -background #445566
    .c create image 100 100 -image i1
    update
    .c delete all
    image delete i1
} -cleanup {
    destroy .c
} -result {}
test imageBmap-10.2 {ImgBmapFree procedures, unlinking} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    imageCleanup
    image create bitmap i1 -data $data1 -maskdata $data2 -foreground #112233 \
	    -background #445566
    .c create image 100 100 -image i1
    button .b1 -image i1
    button .b2 -image i1
    button .b3 -image i1
    pack .b1 .b2 .b3
    update
    destroy .b2
    update
    destroy .b3
    update
    destroy .b1
    update
    .c delete all
} -cleanup {
	image delete i1
    deleteWindows
} -result {}


test imageBmap-11.1 {ImgBmapDelete procedure} -body {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    image delete i2
    info command i2
} -result {}
test imageBmap-11.2 {ImgBmapDelete procedure} -body {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    rename i2 newi2
    set x [list [info command i2] [info command new*] [newi2 cget -file]]
    image delete i2
    lappend x [info command new*]
} -result {{} newi2 foo.bm {}}


test imageBmap-12.1 {ImgBmapCmdDeletedProc procedure} -body {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    rename i2 {}
    list [expr {"i2" in [imageNames]}] [catch {i2 foo} msg] $msg
} -result {0 1 {invalid command name "i2"}}

removeFile foo.bm
removeFile foo2.bm

imageFinish

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|
|
|
|
|
|





<
|


<
<
|
|
<
<
<
<


<


<
<
<
|

|


|
|
|
|
|


|
|

|
|


<
<
|
|
<
<
<
<


<


<
<
<
|

|


|
|
|
|
|


|
|


|


<
|
|
<
>
|
|
|
|
<
>

|



<
<
|

<
|


|
<
<
|



|
|


|
<
<
|

|
|
|
|






>
|
|
|






>
|
|
<
<
<















<
<
<
|

<
|
<
<
<
<

>





<
<
<
<
|

|


|
|

|
|
>
>
|
|
|
>
>
|
|
|
>
>
|
|
|
>
>
|
|
|
>
>
|
|
|
>
>
|
|
|
>
>
|
|
|
>
>










<
<
|
|
>
>









<
<
|
|
>
>
|







|
|
|
>
>
|







|
|
|
>
>
|


|
|
|
>
>
|


|
|
|
>
>
|







|
|
|
>
>
|







|
|

<
|
>
>
|
|
|
>
>

|
|
|
>
>

|
|


|
|
<

|
|
|
|
|
|
|
|
|
|


|
|
|
|
|

|
|


|
|
|
|
|
|
|
|
|
|
<
<

|
|
<
|
<















<
<
<
|

|
<
<
<
<

|
>




|
<
<
<
|
<
<
<
<

|





|
<
<
<




<
|
|
<
|
<
<






|
<
<
|
|
<
|
<
<















<
<
<
<
|

|



|
|





|

<
|


|
|



>
|




<
<
<
<
<
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47


48
49




50
51

52
53



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74




75
76

77
78



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99

100
101
102
103
104

105
106
107
108
109
110


111
112

113
114
115
116


117
118
119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165



166
167

168




169
170
171
172
173
174
175




176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239
240
241
242
243
244
245


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369


370
371
372

373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388



389
390
391




392
393
394
395
396
397
398
399



400




401
402
403
404
405
406
407
408



409
410
411
412

413
414

415


416
417
418
419
420
421
422


423
424

425


426
427
428
429
430
431
432
433
434
435
436
437
438
439
440




441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469





       0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
       0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
       0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0xff};
}
makeFile $data1 foo.bm
makeFile $data2 foo2.bm

eval image delete [image names]
canvas .c
pack .c
update
image create bitmap i1
.c create image 200 100 -image i1
update
proc bgerror msg {
    global errMsg
    set errMsg $msg
}

test imageBmap-1.1 {options for bitmap images} {
    image create bitmap i1 -background #123456
    lindex [i1 configure -background] 4


} {#123456}
test imageBmap-1.2 {options for bitmap images} {




    set errMsg {}
    image create bitmap i1 -background lousy

    update
    list $errMsg $errorInfo



} {{unknown color name "lousy"} {unknown color name "lousy"
    (while configuring image "i1")}}
test imageBmap-1.3 {options for bitmap images} {
    image create bitmap i1 -data $data1
    lindex [i1 configure -data] 4
} $data1
test imageBmap-1.4 {options for bitmap images} {
    list [catch {image create bitmap i1 -data bogus} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-1.5 {options for bitmap images} {
    image create bitmap i1 -file foo.bm
    lindex [i1 configure -file] 4
} foo.bm
test imageBmap-1.6 {options for bitmap images} {
    list [catch {image create bitmap i1 -file bogus} msg] [string tolower $msg]
} {1 {couldn't read bitmap file "bogus": no such file or directory}}
test imageBmap-1.7 {options for bitmap images} {
    image create bitmap i1 -foreground #00ff00
    lindex [i1 configure -foreground] 4


} {#00ff00}
test imageBmap-1.8 {options for bitmap images} {




    set errMsg {}
    image create bitmap i1 -foreground bad_color

    update
    list $errMsg $errorInfo



} {{unknown color name "bad_color"} {unknown color name "bad_color"
    (while configuring image "i1")}}
test imageBmap-1.9 {options for bitmap images} {
    image create bitmap i1 -data $data1 -maskdata $data2
    lindex [i1 configure -maskdata] 4
} $data2
test imageBmap-1.10 {options for bitmap images} {
    list [catch {image create bitmap i1 -data $data1 -maskdata bogus} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-1.11 {options for bitmap images} {
    image create bitmap i1 -file foo.bm -maskfile foo2.bm
    lindex [i1 configure -maskfile] 4
} foo2.bm
test imageBmap-1.12 {options for bitmap images} {
    list [catch {image create bitmap i1 -data $data1 -maskfile bogus} msg] \
	    [string tolower $msg]
} {1 {couldn't read bitmap file "bogus": no such file or directory}}
rename bgerror {}


test imageBmap-2.1 {ImgBmapCreate procedure} {
    eval image delete [image names]

    .c delete all
    list [catch {image create bitmap -gorp dum} msg] $msg [image names]
} {1 {unknown option "-gorp"} {}}
test imageBmap-2.2 {ImgBmapCreate procedure} {
    eval image delete [image names]

    .c delete all
    image create bitmap image1
    list [info commands image1] [image names] \
	    [image width image1] [image height image1] \
	    [lindex [image1 configure -foreground] 4] \
	    [lindex [image1 configure -background] 4]


} {image1 image1 0 0 #000000 {}}


test imageBmap-3.1 {ImgBmapConfigureMaster procedure, memory de-allocation} {
    image create bitmap i1 -data $data1
    i1 configure -data $data1
} {}


test imageBmap-3.2 {ImgBmapConfigureMaster procedure} {
    image create bitmap i1 -data $data1
    list [catch {i1 configure -data bogus} msg] $msg [image width i1] \
	    [image height i1]
} {1 {format error in bitmap data} 16 16}
test imageBmap-3.3 {ImgBmapConfigureMaster procedure, memory de-allocation} {
    image create bitmap i1 -data $data1 -maskdata $data2
    i1 configure -maskdata $data2
} {}


test imageBmap-3.4 {ImgBmapConfigureMaster procedure} {
    image create bitmap i1
    list [catch {i1 configure -maskdata $data2} msg] $msg
} {1 {can't have mask without bitmap}}
test imageBmap-3.5 {ImgBmapConfigureMaster procedure} {
    list [catch {image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 8
	#define foo_height 16
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}
    } msg] $msg
} {1 {bitmap and mask have different sizes}}
test imageBmap-3.6 {ImgBmapConfigureMaster procedure} {
    list [catch {image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 16
	#define foo_height 8
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}
    } msg] $msg
} {1 {bitmap and mask have different sizes}}
test imageBmap-3.7 {ImgBmapConfigureMaster procedure} {



    image create bitmap i1 -data $data1
    .c create image 100 100 -image i1 -tags i1.1 -anchor nw
    .c create image 200 100 -image i1 -tags i1.2 -anchor nw
    update
    i1 configure -data {
	#define foo2_height 14
	#define foo2_width 15
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }
    update
    list [image width i1] [image height i1] [.c bbox i1.1] [.c bbox i1.2]



} {15 14 {100 100 115 114} {200 100 215 114}}


test imageBmap-4.1 {ImgBmapConfigureInstance procedure: check error handling} {




    proc bgerror args {}
    .c delete all
    image create bitmap i1 -file foo.bm
    .c create image 100 100 -image i1
    update
    i1 configure -foreground bogus
    update




} {}

test imageBmap-5.1 {GetBitmapData procedure} {
    list [catch {image create bitmap -file ~bad_user/a/b} msg] \
	    [string tolower $msg]
} {1 {user "bad_user" doesn't exist}}
test imageBmap-5.2 {GetBitmapData procedure} {
    list [catch {image create bitmap -file bad_name} msg] [string tolower $msg]
} {1 {couldn't read bitmap file "bad_name": no such file or directory}}
test imageBmap-5.3 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data { }} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.4 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_width}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.5 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_width gorp}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.6 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_width 1.4}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.7 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_height}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.8 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_height gorp}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.9 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap -data {#define foo2_height 1.4}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.10 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    image create bitmap i1 -data {
	#define foo2_height 14
	#define foo2_width 15 xx _widtg 18 xwidth 18 _heighz 18 xheight 18
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }
    list [image width i1] [image height i1]


} {15 14}
test imageBmap-5.11 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    image create bitmap i1 -data {
	_height 14 _width 15
	char {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff}
    }
    list [image width i1] [image height i1]


} {15 14}
test imageBmap-5.12 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {
	#define foo2_height 14
	#define foo2_width 15
	static short foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff};
    }} msg] $msg
} {1 {format error in bitmap data; looks like it's an obsolete X10 bitmap file}}
test imageBmap-5.13 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] =
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0xff;
    }} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.14 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {
	#define foo2_width 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, }}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.15 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {
	#define foo2_height 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, }}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.16 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] = {
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, foo};
    }} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-5.17 {GetBitmapData procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data "
	#define foo2_height 16
	#define foo2_width 16
	static char foo2_bits[] = \{
	   0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
	   0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81, 0xff, 0x81,
	   0xff
    "} msg] $msg
} {1 {format error in bitmap data}}


test imageBmap-6.1 {NextBitmapWord procedure} {
    eval image delete [image names]
    .c delete all
    list [catch {image create bitmap i1 -data {1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890}} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-6.2 {NextBitmapWord procedure} {
    eval image delete [image names]
    .c delete all
    makeFile {1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890} foo3.bm
    list [catch {image create bitmap i1 -file foo3.bm} msg] $msg
} {1 {format error in bitmap data}}
test imageBmap-6.3 {NextBitmapWord procedure} {
    eval image delete [image names]
    .c delete all
    makeFile {   } foo3.bm
    list [catch {image create bitmap i1 -file foo3.bm} msg] $msg
} {1 {format error in bitmap data}}
removeFile foo3.bm

eval image delete [image names]
.c delete all

image create bitmap i1
test imageBmap-7.1 {ImgBmapCmd procedure} {
    list [catch {i1} msg] $msg
} {1 {wrong # args: should be "i1 option ?arg arg ...?"}}
test imageBmap-7.2 {ImgBmapCmd procedure, "cget" option} {
    list [catch {i1 cget} msg] $msg
} {1 {wrong # args: should be "i1 cget option"}}
test imageBmap-7.3 {ImgBmapCmd procedure, "cget" option} {
    list [catch {i1 cget a b} msg] $msg
} {1 {wrong # args: should be "i1 cget option"}}
test imageBmap-7.4 {ImgBmapCmd procedure, "cget" option} {
    i1 co -foreground #123456
    i1 cget -foreground
} {#123456}
test imageBmap-7.5 {ImgBmapCmd procedure, "cget" option} {
    list [catch {i1 cget -stupid} msg] $msg
} {1 {unknown option "-stupid"}}
test imageBmap-7.6 {ImgBmapCmd procedure} {
    llength [i1 configure]
} {6}
test imageBmap-7.7 {ImgBmapCmd procedure} {
    i1 co -foreground #001122
    i1 configure -foreground
} {-foreground {} {} #000000 #001122}
test imageBmap-7.8 {ImgBmapCmd procedure} {
    list [catch {i1 configure -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test imageBmap-7.9 {ImgBmapCmd procedure} {
    list [catch {i1 configure -foreground #221100 -background} msg] $msg
} {1 {value for "-background" missing}}
test imageBmap-7.10 {ImgBmapCmd procedure} {
    list [catch {i1 gorp} msg] $msg
} {1 {bad option "gorp": must be cget or configure}}



test imageBmap-8.1 {ImgBmapGet/Free procedures, shared instances} {
    eval image delete [image names]

    .c delete all

    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    .c create image 150 100 -image i1 -tags i1.2
    .c create image 250 100 -image i1 -tags i1.3
    update
    .c delete i1.1
    i1 configure -background black
    update
    .c delete i1.2
    i1 configure -background white
    update
    .c delete i1.3
    i1 configure -background black
    update
    image delete i1



} {}

test imageBmap-9.1 {ImgBmapDisplay procedure, nothing to display} {




    proc bgerror args {}
    eval image delete [image names]
    .c delete all
    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    i1 configure -data {}
    update
} {}



test imageBmap-9.2 {ImgBmapDisplay procedure, nothing to display} {




    proc bgerror args {}
    eval image delete [image names]
    .c delete all
    image create bitmap i1 -data $data1
    .c create image 50 100 -image i1 -tags i1.1
    i1 configure -foreground bogus
    update
} {}



if {[info exists bgerror]} {
    rename bgerror {}
}


test imageBmap-10.1 {ImgBmapFree procedure, resource freeing} {
    eval image delete [image names]

    .c delete all


    image create bitmap i1 -data $data1 -maskdata $data2 -foreground #112233 \
	    -background #445566
    .c create image 100 100 -image i1
    update
    .c delete all
    image delete i1
} {}


test imageBmap-10.2 {ImgBmapFree procedures, unlinking} {
    eval image delete [image names]

    .c delete all


    image create bitmap i1 -data $data1 -maskdata $data2 -foreground #112233 \
	    -background #445566
    .c create image 100 100 -image i1
    button .b1 -image i1
    button .b2 -image i1
    button .b3 -image i1
    pack .b1 .b2 .b3
    update
    destroy .b2
    update
    destroy .b3
    update
    destroy .b1
    update
    .c delete all




} {}

test imageBmap-11.1 {ImgBmapDelete procedure} {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    image delete i2
    info command i2
} {}
test imageBmap-11.2 {ImgBmapDelete procedure} {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    rename i2 newi2
    set x [list [info command i2] [info command new*] [newi2 cget -file]]
    image delete i2
    lappend x [info command new*]
} {{} newi2 foo.bm {}}


test imageBmap-12.1 {ImgBmapCmdDeletedProc procedure} {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    rename i2 {}
    list [lsearch -exact [image names] i2] [catch {i2 foo} msg] $msg
} {-1 1 {invalid command name "i2"}}

removeFile foo.bm
removeFile foo2.bm
destroy .c
eval image delete [image names]

# cleanup
cleanupTests
return





Deleted tests/imgListFormat.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
# This file is a Tcl script to test out the default image data format
# ("list format") implementend in the file tkImgListFormat.c.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 2017 Simon Bachmann
# All rights reserved.
#
# Author: Simon Bachmann (simonbachmann@bluewin.ch)

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

imageInit

# find the teapot.ppm file for use in these tests
set teapotPhotoFile [file join [file dirname [info script]] teapot.ppm]
testConstraint hasTeapotPhoto [file exists $teapotPhotoFile]
# let's see if we have the semi-transparent one as well
set transpTeapotPhotoFile [file join [file dirname [info script]] teapotTransparent.png]
testConstraint hasTranspTeapotPhoto [file exists $transpTeapotPhotoFile]

# ---------------------------------------------------------------------


test imgListFormat-1.1 {ParseFormatOptions: default values} -setup {
    image create photo photo1
} -body {
    photo1 put {{red green} {blue black}}
    lindex [photo1 data] 1 1
} -cleanup {
    imageCleanup
} -result {#000000}
test imgListFormat-1.2 {ParseFormatOptions: format name as first arg} -setup {
    image create photo photo1
} -body {
    photo1 put #1256ef -format {default} -to 0 0 10 10
} -cleanup {
    imageCleanup
} -result {}
test imgListFormat-1.3 {ParseFormatOptions: unknown option} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -bogus}
} -cleanup {
    imageCleanup
} -returnCodes error -result {bad format option "-bogus": must be -colorformat}
test imgListFormat-1.4 {ParseFormatOptions: option not allowed} -setup {
    image create photo photo1
} -body {
    photo1 put yellow -format {default -colorformat rgb}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {bad format option "-colorformat": no options allowed}
test imgListFormat-1.5 {ParseFormatOptions: no -colorformat value} -setup {
    image create photo photo1 -data black
} -body {
    photo1 data -format {default -colorformat}
} -returnCodes error -result {the "-colorformat" option requires a value}
test imgListFormat-1.6 {ParseFormatOptions: bad -colorformat val #1} -setup {
    image create photo photo1
} -body {
    photo1 put yellow
    photo1 data -format {default -colorformat bogus}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {bad color format "bogus": must be rgb, rgba, or list}
test imgListFormat-1.7 {ParseFormatOptions: bad -colorformat val #2} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat tkcolor}
} -returnCodes error -result \
    {bad color format "tkcolor": must be rgb, rgba, or list}
test imgListFormat-1.8 {ParseFormatOptions: bad -colorformat #3} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat emptystring}
} -returnCodes error -result \
    {bad color format "emptystring": must be rgb, rgba, or list}
test imgListFormat-1.9 {ParseFormatOptions: bad -colorformat #4} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat rgb-short}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {bad color format "rgb-short": must be rgb, rgba, or list}
test imgListFormat-1.10 {ParseFormatOptions: bad -colorformat #5} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat rgba-short}
} -returnCodes error -result \
    {bad color format "rgba-short": must be rgb, rgba, or list}
test imgListFormat-1.11 {valid colorformats} -setup {
    image create photo photo1
} -body {
    photo1 put white#78
    set result {}
    lappend result [photo1 data -format {default -colorformat rgb}]
    lappend result [photo1 data -format {default -colorformat rgba}]
    lappend result [photo1 data -format {default -colorformat list}]
    set result
} -cleanup {
    imageCleanup
    unset result
} -result {{{#ffffff}} {{#ffffff78}} {{{255 255 255 120}}}}

# GetBadOptMsg: only use case already tested with imgListFormat-1.4

test imgListFormat-3.1 {StringMatchDef: data is not a list} -body {
    testphotostringmatch {not a " proper list}
    # " (this comment is here only for editor highlighting)
} -returnCodes error -result {unmatched open quote in list}
# empty data case tested with imgPhoto-4.95 (imgPhoto.test)
test imgListFormat-3.2 {StringMatchDef: \
        list element not a proper list} -body {
    testphotostringmatch {{red white} {not "} {blue green}}
    # "
} -returnCodes error -result {unmatched open quote in list}
test imgListFormat-3.3 {StringMatchDef: \
        sublists with differen lengths} -body {
    testphotostringmatch {{#001122 #334455 #667788}
		{#99AABB #CCDDEE}
		{#FF0011 #223344 #556677}}
} -returnCodes error -result \
    {invalid row # 1: all rows must have the same number of elements}
test imgListFormat-3.4 {StringMatchDef: base64 data is not parsed as valid \
} -setup {
    image create photo photo1
} -body {
    photo1 put {
	iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCA
	YAAAEFsT2yAAAABGdBTUEAAYagMeiWXwAA
	ABdJREFUCJkFwQEBAAAAgiD6P9pACRoqDk
	fUBvt1wUFKAAAAAElFTkSuQmCC
    } -format default
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCA"}
test imgListFormat-3.5 {StringMatchDef: valid data} -setup {
    image create photo photo1
} -body {
    photo1 put {{blue green}
		{yellow magenta}
	        {#000000 #FFFFFFFF}}
    list [image width photo1] [image height photo1] \
	[photo1 get 0 2 -withalpha]
} -cleanup {
    imageCleanup
} -result {2 3 {0 0 0 255}}

# ImgStringRead: most of the error cases cannot be tested with current code,
# as the errors are detected by StringMatchDef
test imgListFormat-4.1 {StringReadDef: use with -format opt} -setup {
    image create photo photo1
} -body {
    photo1 put white -format "default"
    photo1 get 0 0
} -cleanup {
    imageCleanup
} -result {255 255 255}
test imgListFormat-4.2 {StringReadDef: suboptions to format} -setup {
    image create photo photo1
} -body {
    photo1 put white -format {default -bogus}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {bad format option "-bogus": no options allowed}
test imgListFormat-4.3 {StringReadDef: erroneous non-option argument} -setup {
    image create photo photo1
} -body {
    photo1 put orange -format {default bogus}
} -returnCodes error -result {bad format option "bogus": no options allowed}
test imgListFormat-4.4 {StringReadDef: normal use case} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    set imgData [photo1 data]
    photo2 put $imgData
    string equal [photo1 data] [photo2 data]
} -cleanup {
    imageCleanup
    unset imgData
} -result 1
test imgListFormat-4.5 {StringReadDef: correct compositing rule} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
    image create photo photo2
} -body {
    photo2 put #FF0000 -to 0 0 50 50
    photo2 put [photo1 data -format {default -colorformat rgba}] -to 10 10 40 40
    list [photo2 get 0 0 -withalpha] [photo2 get 20 25 -withalpha] \
	[photo2 get 49 49 -withalpha]
} -cleanup {
    imageCleanup
} -result {{255 0 0 255} {0 78 185 225} {255 0 0 255}}

test imgListFormat-5.1 {StringWriteDef: format options not a list} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default " bogus}
    # "
} -cleanup {
    imageCleanup
} -returnCodes error -result {unmatched open quote in list}
test imgListFormat-5.2 {StringWriteDef: invalid format option} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -bogus}
} -cleanup {
    imageCleanup
} -returnCodes error -result {bad format option "-bogus": must be -colorformat}
test imgListFormat-5.3 {StringWriteDef: non-option arg in format} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat list bogus}
} -cleanup {
    imageCleanup
} -returnCodes error -result {bad format option "bogus": must be -colorformat}
test imgListFormat-5.4 {StringWriteDef: empty image} -setup {
    image create photo photo1
} -body {
    photo1 data -format {default -colorformat rgba}
} -cleanup {
    imageCleanup
} -result {}
test imgListFormat-5.5 {StirngWriteDef: size of data} -setup {
    image create photo photo1
} -body {
    photo1 put blue -to 0 0 35 64
    set imgData [photo1 data]
    list [llength [lindex $imgData 0]] [llength $imgData]
} -cleanup {
    unset imgData
    imageCleanup
} -result {35 64}
test imgListFormat-5.6 {StringWriteDef: test some pixels #1} -constraints {
    hasTeapotPhoto
} -setup {
    set result {}
    image create photo photo1 -file $teapotPhotoFile
} -body {
    set imgData [photo1 data]
    # note: with [lindex], the coords are inverted (y x)
    lappend result [lindex $imgData 0 0]
    lappend result [lindex $imgData 3 2]
    lappend result [lindex $imgData 107 53]
    lappend result [lindex $imgData 203 157]
    lappend result [lindex $imgData 255 255]
    set result
} -cleanup {
    unset result
    unset imgData
    imageCleanup
} -result {{#135cc0} #135cc0 #a06d52 #e1c8ba #135cc0}
test imgListFormat-5.7 {StringWriteDef: test some pixels #2} -constraints {
    hasTeapotPhoto
} -setup {
    set result {}
    image create photo photo1 -file $teapotPhotoFile
} -body {
    set imgData [photo1 data -format {default -colorformat rgba}]
    # note: with [lindex], the coords are inverted (y x)
    lappend result [lindex $imgData 0 0]
    lappend result [lindex $imgData 3 2]
    lappend result [lindex $imgData 107 53]
    lappend result [lindex $imgData 203 157]
    lappend result [lindex $imgData 255 255]
    set result
} -cleanup {
    unset result
    unset imgData
    imageCleanup
} -result {{#135cc0ff} #135cc0ff #a06d52ff #e1c8baff #135cc0ff}
test imgListFormat-5.8 {StringWriteDef: test some pixels #3} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
} -body {
    set imgData [photo1 data -format {default -colorformat rgb}]
    set result {}
    lappend result [lindex $imgData 3 2]
    lappend result [lindex $imgData 107 53]
    lappend result [lindex $imgData 203 157]
    set result
} -cleanup {
    unset result
    unset imgData
    imageCleanup
} -result {{#004eb9} #a14100 #ffca9f}
test imgListFormat-5.9 {StringWriteDef: test some pixels #4} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
} -body {
    set imgData [photo1 data -format {default -colorformat rgba}]
    set result [lindex $imgData 3 2]
    lappend result [lindex $imgData 107 53]
    lappend result [lindex $imgData 203 157]
    set result
} -cleanup {
    unset result
    unset imgData
    imageCleanup
} -result {{#004eb9e1} #a14100aa #ffca9faf}
test imgListFormat-5.10 {StringWriteDef: test some pixels #5} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
} -body {
    set imgData [photo1 data -format {default -colorformat list}]
    set result {}
    lappend result [lindex $imgData 3 2]
    lappend result [lindex $imgData 107 53]
    lappend result [lindex $imgData 203 157]
    set result
} -cleanup {
    unset imgData
    unset result
    imageCleanup
} -result {{0 78 185 225} {161 65 0 170} {255 202 159 175}}

test imgListFormat-6.1 {ParseColor: empty string} -setup {
    image create photo photo1
    set result {}
} -body {
    photo1 put {{"" ""} {"" ""}}
    lappend result [image width photo1]
    lappend result [image height photo1]
    lappend result [photo1 get 1 1 -withalpha]
    set result
} -cleanup {
    unset result
    imageCleanup
} -result {2 2 {0 0 0 0}}
test imgListFormat-6.2 {ParseColor: empty string, mixed} -setup {
    image create photo photo1
} -body {
    photo1 put {{black white} {{} white}}
    list [photo1 get 0 0 -withalpha] [photo1 get 0 1 -withalpha]
} -cleanup {
    imageCleanup
} -result {{0 0 0 255} {0 0 0 0}}
test imgListFormat-6.3 {ParseColor: color name too long} -setup {
    image create photo photo1
    set longstr {}
    for {set i 1} {$i <= 100} {incr i} {
        append longstr "z"
    }
} -body {
    photo1 put [list [list blue] [list $longstr]]
} -cleanup {
    imageCleanup
    unset longstr
} -returnCodes error -result {invalid color}
test imgListFormat-6.4 {ParseColor: #XXX color, different forms} -setup {
    image create photo photo1
} -body {
    photo1 put {{#A123 #334455} {#012 #fffefd#00}}
    photo1 data -format {default -colorformat rgba}
} -cleanup {
    imageCleanup
} -result {{#aa112233 #334455ff} {#001122ff #fffefd00}}
test imgListFormat-6.5 {ParseColor: list format} -setup {
    image create photo photo1
} -body {
    photo1 put [list [list [list 255 255 255]]]
    photo1 get 0 0 -withalpha
} -cleanup {
    imageCleanup
} -result {255 255 255 255}
test imgListFormat-6.6 {ParseColor: string format} -setup {
    image create photo photo1
} -body {
    photo1 put [list [list [list white]]]
    photo1 get 0 0 -withalpha
} -cleanup {
    imageCleanup
} -result {255 255 255 255}
test imgListFormat-6.7 {ParseColor: invalid color} -setup {
    image create photo photo1
} -body {
    photo1 put {{blue red} {green bogus}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "bogus"}
test imgListFormat-6.8 {ParseColor: overall test} -setup {
    image create photo photo1
    set result {}
} -body {
    photo1 put {
		{snow@0.5 snow#80 snow#8 #fffffafafafa@0.5 #fffffabbfacc#8}
		{#fffffafffaff#80 #ffffaafaa@.5 #ffffaafaa#8 #ffffaafaa#80 #fee#8}
		{#fee#80 #fee@0.5 #fffafa@0.5 #fffafa#8 #fffafa#80}
		{{0xff 250 0xfa 128} {255 250 250} #fee8 #fffafa80 snow}}
    for {set y 0} {$y < 4} {incr y} {
		for {set x 0} {$x < 5} {incr x} {
			lappend result [photo1 get $x $y -withalpha]
		}
    }
    set result
} -cleanup {
    imageCleanup
    unset result
} -result \
{{255 250 250 128} {255 250 250 128} {255 250 250 136} {255 250 250 128}\
{255 250 250 136} {255 250 250 128} {255 250 250 128} {255 250 250 136}\
{255 250 250 128} {255 238 238 136} {255 238 238 128} {255 238 238 128}\
{255 250 250 128} {255 250 250 136} {255 250 250 128} {255 250 250 128}\
{255 250 250 255} {255 238 238 136} {255 250 250 128} {255 250 250 255}}

# Note: these tests were written for an earlier implementation of
# ParseColorAsList. For this reason, their order and layout do not follow the
# current code very well. Test coverage is pretty good, nevertheless.
test imgListFormat-7.1 {ParseColorAsList: invalid list} -setup {
    image create photo photo1
} -body {
    photo1 put {{{123 45 67 89} {123 45 " 67}}}
	#"
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "123 45 " 67"}
#"
test imgListFormat-7.2 {ParseColorAsList: too few elements in list} -setup {
    image create photo photo1
} -body {
    photo1 put {{{0 255 0 255} {0 255}}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "0 255"}
test imgListFormat-7.3 {ParseColorAsList: too many elements in list} -setup {
    image create photo photo1
} -body {
    photo1 put {{{0 100 200 255} {0 100 200 255 0}}}
} -returnCodes error -result {invalid color name "0 100 200 255 0"}
test imgListFormat-7.4 {ParseColorAsList: not an integer value} -setup {
    image create photo photo1
} -body {
    photo1 put {{{9 0xf3 87 65} {43 21 10 1.0}}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "43 21 10 1.0"}
test imgListFormat-7.5 {ParseColorAsList: negative value in list} -setup {
    image create photo photo1
} -body {
    photo1 put {{{121 121 121} {121 121 -1}}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "121 121 -1"}
test imgListFormat-7.6 {ParseColorAsList: value in list too large} -setup {
    image create photo photo1
} -body {
    photo1 put {{{0 1 2 3} {254 255 256}}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "254 255 256"}
test imgListFormat-7.7 {ParseColorAsList: suffix not allowed} -setup {
    image create photo photo1
} -body {
    photo1 put {{{100 100 100} {100 100 100#FE}}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "100 100 100#FE"}
test imgListFormat-7.8 {ParseColorAsList: valid list form} -setup {
    image create photo photo1
} -body {
    photo1 put {{{0x0 0x10 0xfe 0xff} {0 100 254}}
		{{30 30 30 0} {1 1 254 1}}}
    list [photo1 get 0 0 -withalpha] [photo1 get 1 0 -withalpha] \
	[photo1 get 0 1 -withalpha] [photo1 get 1 1 -withalpha]
} -cleanup {
    imageCleanup
} -result {{0 16 254 255} {0 100 254 255} {30 30 30 0} {1 1 254 1}}
test imgListFormat-7.9 {ParseColorAsList: additional spaces in list} -setup {
    image create photo photo1
} -body {
    photo1 put { { { 1 2 3} {1  2	 3} } { {1 2 3  } {  1  2  3   4  }  } }
    photo1 data -format {default -colorformat rgba}
} -cleanup {
    imageCleanup
} -result {{#010203ff #010203ff} {#010203ff #01020304}}
test imgListFormat-7.10 {ParseColorAsList: list format, string rep} -setup {
	image create photo photo1
} -body {
	photo1 put {{"111 222 33 44"}}
	photo1 get 0 0 -withalpha
} -cleanup {
	imageCleanup
} -result {111 222 33 44}

test imgListFormat-8.1 {ParseColorAsHex: RGB format} -setup {
    image create photo photo1
} -body {
    photo1 put {{#010 #001100}}
    photo1 data
} -cleanup {
    imageCleanup
} -result {{#001100 #001100}}
test imgListFormat-8.2 {ParseColorAsHex: invalid hex digit} -setup {
    image create photo photo1
} -body {
    photo1 put {#ABCD #ABCZ}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "#ABCZ"}
test imgListFormat-8.3 {ParseColorAsHex: RGB with suffix, 8 chars} -setup {
    image create photo photo1
} -body {
    photo1 put {{#FFfFFf #AbCdef#0}}
    photo1 data
} -cleanup {
    imageCleanup
} -result {{#ffffff #abcdef}}
test imgListFormat-8.4 {ParseColor: valid #RGBA color} -setup {
    image create photo photo1
} -body {
    photo1 put {{#9bd5020d #7acF}}
    list [photo1 get 0 0 -withalpha] [photo1 get 1 0 -withalpha]
} -cleanup {
    imageCleanup
} -result {{155 213 2 13} {119 170 204 255}}

test imgListFormat-9.1 {ParseColorAsStandard:
        Tk color, valid suffixes} -setup {
    image create photo photo1
    set result {}
} -body {
    photo1 put {{blue@0.711 #114433#C} {#8D4#1A magenta}}
    lappend result [photo1 get 0 0 -withalpha]
    lappend result [photo1 get 1 0 -withalpha]
    lappend result [photo1 get 0 1 -withalpha]
    lappend result [photo1 get 1 1 -withalpha]
    set result
} -cleanup {
    unset result
    imageCleanup
} -result {{0 0 255 181} {17 68 51 204} {136 221 68 26} {255 0 255 255}}
test imgListFormat-9.2 {ParseColorAsStandard:
        Tk color with and w/o suffixes} -setup {
    image create photo photo1
    set result {}
} -body {
    photo1 put {{#52D8a0 #2B5} {#E47@0.01 maroon#4}}
    lappend result [photo1 get 0 0 -withalpha]
    lappend result [photo1 get 1 0 -withalpha]
    lappend result [photo1 get 0 1 -withalpha]
    lappend result [photo1 get 1 1 -withalpha]
    set result
} -cleanup {
    unset result
    imageCleanup
} -result {{82 216 160 255} {34 187 85 255} {238 68 119 3} {128 0 0 68}}
test imgListFormat-9.3 {ParseColorAsStandard: wrong digit count} -setup {
    image create photo photo1
} -body {
    photo1 put {{#000 #00}}
} -returnCodes error -result {invalid color name "#00"}
test imgListFormat-9.4 {ParseColorAsStandard: @A suffix, not a float} -setup {
    image create photo photo1
} -body {
    photo1 put {{blue@0.5 blue@bogus}}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {invalid alpha suffix "@bogus": expected floating-point value}
test imgListFormat-9.5 {ParseColorAsStandard: @A, value too low} -setup {
    image create photo photo1
} -body {
    photo1 put {green@.1 green@-0.1}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {invalid alpha suffix "@-0.1": value must be in the range from 0 to 1}
test imgListFormat-9.6 {ParseColorAsStandard: @A, value too high} -setup {
    image create photo photo1
} -body {
    photo1 put {#000000@0 #000000@1.0001}
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {invalid alpha suffix "@1.0001": value must be in the range from 0 to 1}
test imgListFormat-9.7 {ParseColorAsStandard: @A suffix, edge values} -setup {
    imageCleanup
    image create photo photo1
} -body {
    photo1 put {{yellow@1e-22 yellow@0.12352941 yellow@0.12352942 \
		 yellow@0.9999999}}
    list [photo1 get 0 0 -withalpha] [photo1 get 1 0 -withalpha] \
	[photo1 get 2 0 -withalpha] [photo1 get 3 0 -withalpha]
} -cleanup {
    imageCleanup
} -result {{255 255 0 0} {255 255 0 31} {255 255 0 32} {255 255 0 255}}
test imgListFormat-9.8 {ParseColorAsStandard: # suffix, no hex digits} -setup {
    image create photo photo1
} -body {
    photo1 put {{black#f} {black#}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid alpha suffix "#"}
test imgListFormat-9.9 {ParseColorAsStandard:
        '#' suffix, too many digits} -setup {
    image create photo photo1
} -body {
    photo1 put {{#ABC#12 #ABC#123}}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid alpha suffix "#123"}
test imgListFormat-9.10 {ParseColorAsStandard:
        invalid digit in #X suffix} -setup {
    image create photo photo1
} -body {
    photo1 put {#000#a #000#g}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid alpha suffix "#g": expected hex digit}
test imgListFormat-9.11 {ParseColorAsStandard:
        invalid digit in #XX suffix} -setup {
    image create photo photo1
} -body {
    photo1 put {green#2 green#2W}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid alpha suffix "#2W": expected hex digit}
test imgListFormat-9.12 {ParseColorAsStandard:
        invalid color: not a hex digit} -setup {
    image create photo photo1
} -body {
    photo1 put {#ABCDEF@.99 #ABCDEG@.99}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "#ABCDEG@.99"}
test imgListFormat-9.13 {ParseColorAsStandard: suffix not allowed #1} -setup {
    image create photo photo1
} -body {
    photo1 put {#ABC@.5 #ABCD@0.5}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "#ABCD@0.5"}
test imgListFormat-9.14 {ParseColorAsStandard: suffix not allowed #2} -setup {
    image create photo photo1
} -body {
    photo1 put {#1111 #1111#1}
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "#1111#1"}


# ---------------------------------------------------------------------

imageFinish

# cleanup
cleanupTests
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted tests/imgPNG.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
# This file is a Tcl script to test out the code in tkImgFmtPNG.c, which reads
# and write PNG-format image files for photo widgets. The files is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Willem van Schaik (images only)
# Copyright © 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

namespace eval png {
    variable encoded
    # Key names are from the names of the source images, which come from
    #    http://www.schaik.com/pngsuite/pngsuite.html
    # The exception is "BadX", which is used to test handling badly compressed
    # images.
    array set encoded {
	basn0g08 "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAAABGdBTUEAAYag
MeiWXwAAAEFJREFUeJxjZGAkABQIyLMMBQWMDwgp+PcfP2B5MBwUMMoRkGdkonlcDAYFjI/wyv7/z/
iH5nExGBQwyuCVZWQEAFDl/nE14thZAAAAAElFTkSuQmCC"
	basn2c08 "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAABGdBTUEAAYag
MeiWXwAAAEhJREFUeJzt1cEJADAMAkCF7JH9t3ITO0Qr9KH4zuErtA0EO4AKFPgcoO3kfUx4QIECD0
qHH8KEBxQo8KB0OCOpQIG7cHejwAGCsfleD0DPSwAAAABJRU5ErkJggg=="
	basn3p08 "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAAYag
MeiWXwAAAwBQTFRFIkQA9f/td/93y///EQoAOncAIiL//xH/EQAAIiIA/6xVZv9m/2Zm/wH/IhIA3P
//zP+ZRET/AFVVIgAAy8v/REQAVf9Vy8sAMxoA/+zc7f//5P/L/9zcRP9EZmb/MwAARCIA7e3/ZmYA
/6RE//+q7e0AAMvL/v///f/+//8BM/8zVSoAAQH/iIj/AKqqAQEARAAAiIgA/+TLulsAIv8iZjIA//
+Zqqr/VQAAqqoAy2MAEf8R1P+qdzoA/0RE3GsAZgAAAf8BiEIA7P/ca9wA/9y6ADMzAO0A7XMA//+I
mUoAEf//dwAA/4MB/7q6/nsA//7/AMsA/5mZIv//iAAA//93AIiI/9z/GjMAAACqM///AJkAmQAAAA
ABMmYA/7r/RP///6r/AHcAAP7+qgAASpkA//9m/yIiAACZi/8RVf///wEB/4j/AFUAABER///+//3+
pP9EZv///2b/ADMA//9V/3d3AACI/0T/ABEAd///AGZm///tAAEA//XtERH///9E/yL//+3tEREAiP
//AAB3k/8iANzcMzP//gD+urr/mf//MzMAY8sAuroArP9V///c//8ze/4A7QDtVVX/qv//3Nz/VVUA
AABm3NwA3ADcg/8Bd3f//v7////L/1VVd3cA/v4AywDLAAD+AQIAAQAAEiIA//8iAEREm/8z/9SqAA
BVmZn/mZkAugC6KlUA/8vLtP9m/5sz//+6qgCqQogAU6oA/6qqAADtALq6//8RAP4AAABEAJmZmQCZ
/8yZugAAiACIANwA/5MiAADc/v/+qlMAdwB3AgEAywAAAAAz/+3/ALoA/zMz7f/t/8SIvP93AKoAZg
BmACIi3AAA/8v/3P/c/4sRAADLAAEBVQBVAIgAAAAiAf//y//L7QAA/4iIRABEW7oA/7x3/5n/AGYA
uv+6AHd3c+0A/gAAMwAzAAC6/3f/AEQAqv+q//7+AAARIgAixP+IAO3tmf+Z/1X/ACIA/7RmEQARCh
EA/xER3P+6uv//iP+IAQAB/zP/uY7TYgAAAbFJREFUeJwNwQcACAQQAMBHqIxIZCs7Mwlla1hlZ+8V
itCw9yoqNGiYDatsyt6jjIadlVkysve+u5jC9xTmV/qyl6bcJR7kAQZzg568xXmuE2lIyUNM5So7OM
AFIhvp+YgGvEtFNnOKeJonSEvwP9NZzhHiOfLzBXPoxKP8yD6iPMXITjP+oTdfsp14lTJMJjGtOMFQ
fiFe4wWK8BP7qUd31hBNqMos2tKYFbRnJdGGjTzPz2yjEA1ZSKymKCM5ylaWcJrZxCZK8jgfU4vc/M
W3xE7K8RUvsZb3Wc/XxCEqk4v/qMQlFvMZcZIafMOnLKM13zGceJNqPMU4KnCQAqQgbrKHpXSgFK/Q
n6REO9YxjWE8Sx2SMJD4jfl8wgzy0YgPuEeUJQcD6EoWWpCaHsQkHuY9RpGON/icK0RyrvE680jG22
TlHaIbx6jLnySkF+M5QxzmD6pwkTsMoSAdidqsojipuMyHzOQ4sYgfyElpzjKGErQkqvMyC7jFv9xm
BM2JuTzDRDLxN4l4jF1EZjIwmhfZzSOMpT4xiH70IQG/k5En2UKcowudycsG8jCBmtwHgRv+EIeWyO
AAAAAASUVORK5CYII="
	basn6a08 "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAYag
MeiWXwAAAG9JREFUeJzt1jEKgDAMRuEnZGhPofc/VQSPIcTdxUV4HVLoUCj8H00o2YoBMF57fpz/uj
ODHXUFRwPKBqj5DVigB041HiJ9gFyCVOMbsEIPXNwuAHkgiJL/4qABNqB7QAeUPBAE2QAZUDZAfwEb
8ABSIBqcFg+4TAAAAABJRU5ErkJggg=="

	BadX "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABHNCSVQICAgIfAhk
iAAAABN0RVh0U29mdHdhcmUAVGsgOC42YjEuMcrtT1oAAAAcSURBVHicYmBgYPjPgAr+ozP+o0uj68
BUiWEmAAAA//8SozfjAAAAAElFTkSuQmCC"
	MultiIDAT "iVBORw0KGgoAAAANSUhEUgAAAN8AAADUCAYAAAAcPvbvAAAAAXNSR0IArs4
c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEGQQKMpLRO
uoAACAASURBVHja7L158GbZWd/3ec45977bb+2e7p7pnu7ZNzFaRhJCwggjsHqUCgUhiWMSJymwUoV
UlkumJChCHFWBywQQNqhYpFDB2Ljs2EWqiAmphMQVO2ATQMJCQsuMZrp7lt5++7ve9957lid/3Ptbu
tWjGRAgZvo9XW//3vXe973nfM/zPN9nE1VlMf58RwHkgFMgJhDAQg0EAJQ+FuYekgVrCBope5YK6F3
8Vw9UCdbvOnuBwbH2aDnBKy7rtkcA357PYHC0B0/t2xfjaz7M4hJ8jS+6fPnriqKqxLqG1IDTGINpP
9vtds8bY85j5ABoYBAxX3ly5dbnW4wF+G7PoTcDpvnnYyDEeACYJOlgsozN3xMS71Fx7RQaFIOIbY6
n5iaMpQX4/gIOt7gEf/7jyzFgQMFIAxODQSShmYXcgICmRr5F9dlwPH3XaFJw3LgMjFcsgiDtcZAG1
HIEsArIAnwLybcA30urnQcPjSHr5GBNK7kSgpLq6h0XLz63fP36xjKYd4AlYUgYdF/t1MPJlVtJv8V
YgO92vujmFmJQblAUFbWmfXPCZQaH4mezJ5/+wtM8//yLBJ+ePFQ7pQGdtjhTGkl49LiSFuBbgG8h+
V5OJU0CAQVJJBQxIBqY7uw8+fyFS2xcvkooqycPxBzSqJU3MjcHE5yOAnAxFjbf7bzjyVG06Y07YWy
ghEps3AUaMJpB7U8Ue8MnptvbpKSkyj9BTCewbMm+TccR6WdvBLoutM6F5FtIvpvuHFE7DaAaMRiCJ
hKxnSUlFMW7r1+8ZIrNberhmPHWhsHIu20r16K2yE2HgL55khd+3QX4FuMWNh8KouDUoijG2saWA9B
EPR6f37t8Fb+zTbW1wdVnn0GHu+eJFYaAMa0uc8MxzWKiF2rnYtys/+nNkjA1Dw4kIAaIiCYAmW3vv
Pv6xUuc7uY4Z5ltXENC9W6siKKaNEEAK6ZVZxVEDjRbARC7uP4LybcY6WYNsbXVGuDpwStiFIJ//Wh
r+/Tw6nXcdEI2m7B96Vn8aPc0qX49VIjEBls36pmAaX2A5gZ1dDEW4LvtheCNd1ppqPsATc39afHke
GsLijlrKXDMKDoZUY92INZPQiASUEmo6OEBAJI2t1ucZzEW4Lttgbcv/W54UsEeqIsREWE2Gp7fvbZ
BR4S7Bl1ODnosWaXY2wZfnBcCSiRoA8B9cuWQYJEF8BbgW4yviMZDbbMJsEYRUm+8s/fOzWtX6RmHK
Ut0NiVMp1x5/iJpMn4n0LMI1jQ2nR7x56nqIfAWbr4F+BbjKxuDgrR2HwDvms7GnclwhBXDXXcc5/j
qEsu9LnVRoMF3IL1LSXitSC3CVF5Kx12MBfhu0xGlSa2LBKDCUIH4AxdBSFABdcrpsgTT4jxXL3C3v
8bXZZsMj09YX4k8sLfLGy9sYj//AuxMzqc4oxTLmEQtYKRJMxIR1OjNwZ6LsQDf7TteCge29QZYAxC
Z7e6cH+/tYpLSzRyDwQDnGi9RWZawuwfz+Xln7a1z+F7JSRdjAb7b5aLv+/LM/hTI4ZNiGxUxA/D1u
d3rVx/b29zAxJqBc2TWISJ0Oh2cs1DMoJw/ZpKegxpzk355g/q5AN8CfLe7xDMcDURpH7VPqECMYAH
q8vxo8zrz4R5dha4xTQRM5ED61eMRTKcQ03nRwIGr70gcm+4ffzEW4Luth+4D0HBDzvlB1nozMY5Em
k+fjJMxnbqmbw0dlH7Ww4khxkgxn7K7s0Xc3QEfnlyRDHcTpalH/y4AuADf7Q6+fQA2twaKKg0Zo4C
zQArWj4bfJtMZfWDZGnoiZGJxJsN1crLMYjWRiikUs2+DZDNNByFl+ypnkhuBuBgL8C2YliM1WBJNU
kIEnCSopm8rtjfXw2iPzNd0ETpJMcmRuR5Z3qXb79HJLTIvYTRap6ze5lLCHg1wOfJ34eZbgG8x4KD
Y0X7mwWEiekSIUM7P+71dwniErSqcD1iUvhuQGUeISlGW1MWMajyC8QSinicq0sIs3ax7LsYCfLf3a
GWQ3giK/SBrQUE9Ops+GcZj0nRGR5WOs0iM+DJRFDVBlYQS64o4HsHuLoTwZBNMLU1qX2qSbJsSobr
A4AJ8t7vamb7M/jsqnCwKKa2HWfE2PxqSh0DXGHKxZFlGbvt08iUkyxFrsMYQZwVxcwf2Rm+j9uu0M
Z37Np+9UQ4uxgJ8ty/f8mUA5KbEdu+/rdjdttPtHZxP9GyGMYYsy8ntgKwzQIxDrSOzllTMKba3YDS
yhPBtaGyO1TKn5sDODIsJWIDv9h3xqPK3z3weAaABKOsnp7tDyuEIGyNWDClBQDBqMZIRsCQBay3UN
Wk8g2IOSZ9EBYNytGqEFV0Yfwvw3e7gS4dB00cyGQ4iXxRiMTtfjsdQB3JjceIa+w4BzYjJUadETBB
jRLwnFQVMphDj+abOpxwCW0FIB0TMYizAd9uqnfHmJ/SGx4/NJ9Nz1bRo7Lw2nAzjSEZAHT4mklpqj
YS6JtWeOJ/D1jaU1TlCfOzgcAnQ2E72AnwL8N3Wki+2ki/emMPXOt6T9+dHe0PqYk4mBougqhjnMFm
OkYwUmyBQwRBCgBShDky3d2E6AV+dv6FIRVKU2HoTF2MBvttY8qVbsjDN8N6fn02mVPOySQdKiZRS0
6nIZs3bVZvHzrb2nGBIzGeTxu6r6/OKNhKzJXgWZQP/Yo1F9bI/T9C1iz/Spw9NQz4FejAlUlOzCp1
sd/td/UtXcFtzenPBxBx1UKSaEC1djWQmI9VgnWsKdkahmxx6bQR/+Hm489S7TLXbKaypCrcK5Aw0x
4XFrC8k3+180aWtLn1TcmvTaUjfWRVFz1c1GiOookkQNc0tQUqJGCMpNLcYAr6uqeYlVTEnDIcwnvS
I+k5n7H7vzS8vJ78YC/DdbkP21U5p9M0YIwI4BI3x/GS3sfdSiKR0o7qoKRFCQFOCmNCgaB1IPhCqm
nI+Z+vaBmzvQEznu8YtBN0CfIuxPxKHlfxAG3uulU5pXj052xsR5h4TFQJoBFFBkqBBCSkRQ0JTQkL
CREGiIjGhdWCyNyRt7UDpn2wmObah24uxAN9C8jXgsxyEnhgEB6fDdP76+d4YrTwOi2jjXNckEA2xB
u89IQRSSGhImKRYFSQKEiCVNeONbZjOX0/ktNOI1bb+52LGF+C77S/6fkiLE0S0aXEZw7vr4Uj8aIq
UHptAVIkxIckiScAnfB3RoCSfSJUn1REJNFLRe0IZ2L56Hba2BR/f7ZKQyyKTfQG+xbhRBLZ/LKDz6
vx8e0iazJEqYqOgEVLQJjtBHRrb/D9tX/OJWEeiT3gfqavAbDrl6vMvMrx6HWbz88S238OiR9hfqLG
wxb9GmFONIK5pfpkClszovH63H02xRY2tIyYKISopAmohKkYdYiwiilElJYtGJSbFR8XHyHQ2Z4Qy2
tpjbVa+m17f4DQhsWFOv+peKYs9eyH5/oKOl3Jmi0jr9G4c5sH7ZhIUqMMTroontp+/Qr03oRMgzit
iHRFxzOcVVeUbuy8m6ipSzCrms5JyXlNUNUVVMatqyhjx3vO5T3+GsL17gpSeIDVBnokvZ1CPfu/91
24sNX8TYXTkPTd/fuHIX0i+vzDgk1s41ywGS8LmFjRhswxierIajTCzCqkjztOQJ6ntdxkVrRMEJXR
NWwLekKIwrz0xRqqYmMbAqC7Y8yXF5hbj3T2ORX0STX+AGoy1reRtgHZ0U9i/LQC0kHyvOsAd3fmP/
r35BhFNjQM91XWDsKp6cu/aJmkypxPABcUkwbSFADUJMYKvE7WPhAAhQFlFJvOaYVGyPZuyM59RG2F
rOOTChQtcfPYCeP8kIpRlgVd/ADhjDMaYryitF0BcSL5XpYr50he9bWiibYSnmGVieke5N6YTIasTJ
iQ0RKIoUSAmg8QGp943sZ6+qqnnJfO6Yh49Y18zToFpmdiaTCh9xYULl3jrpHgHa6vLeZ5PklhU9Yb
vt39/X53cB+TR3yiL8JiF5HtVECrtQr1ZnTskXJSjmeaQ3uWHw2y0tUU1miCVR+cBX3qqsmZeeXxM+
AAxKAlH8IlyXjOrAkVITENi5Gt25gWX93YpgqesPBcuXOC5S5cy6vpdMTbnjDEeqJxHpbOINIm5Cwm
4AN+rSeodVStvBtuXfS4F9jl/cRnU/j17W9vMRmPK0QSqQKw9ofZ4HwkpNfl7SQkRYoI6wLyqmc5Lp
mXFuCzZLefszAtmGilCYFRMufDsRa5duwZJ35PlOYmm0vVR6bYfK3qzyvxSqvViLMD3qrL/jt72e+g
RA8TIfDw+v7O13YSKKahP0AZNp5RIsZFWPgbqumY2K5jNCiazOZNpwd5kyt5sxrAoGFZzJlXF3mzGX
jHl0vPP8cUvfpFrl198/7ycU6Wasizx3h+omfsbxa1s1sVY2HyvKgl4VPW81YKeT6agynhv7wlV/Ya
969f/zQvPPTfU0fj1/WKe+yph6pqQwoHNl2IilR5becblDF/VFMWcopgz9XOmEijUU2lgHEpCo9zyw
niHX//1X+daXXDPGx+v1s/c9Uf3nzr7h4PB4FMrKyu/NxgMPu2cwzl3S9fBwtb7MzRPbscdzlPSRFO
aI38P1QCNbRl3A02nythkipvGZhqSYxBsW+jdtoX5AjAPje/cojjGOPbohhKmNWyPHg07o/Ofuv573
7o3nn7zZ75waf36iyNOd0/zsDvDyT3D8V3F7pXEqqSQinIgTLPIuJ4xns+oqhK7u0WZAsN6zrYv2CO
wZwK7WrMdPMMI0UEQRx2UGJU867O+ssbS0hIPn+rz0GOPcuaBezlx7vTeg48/9ltn7z/3/ywtLf1fn
az7FFHJbQeNhgiI7Ta/jcbtkamSidzQ7OWw6xJH7NkbukQcGenI1ZYjStjLKWLpNaWw3Zbgq6jbhXM
IQMNhuOWhbdZEoohpc89Nk3M3ItEhawsSgfcRUUfHWaxAVU2QuEcoNvCTjbcVm1e/a+u5y99++UuXH
r/+4iYvzq+zNRrzhWcuU0yFJ+59gneefTPn/CprY5CdKZoC01QwEc/c1BSpYjgaMRmPSeWYOkUmqWY
nzNlNnqEJ7BLYS0oBeAvBCDEJITaL3ZGRGYtJBYOOpb/SY+3EKg8/+iCPPPoADz14P/efPfu5+++5/
zeOrR3/Nddf+X1sBlmHGou3FiHD4m6AzAHAUkA14lrSRm6IZTsKmHgL4L0cqNJrzlq6TcHnj8i8tk+
QHpnQtp7KfqMRNTe2NDcpYo0AHsE3z6YAsznMZ8StF+4bbVz861svPvXXtq9deny4vcHu9h67uyOKW
c0w9bi6tculywUuc7zjsb/EW8+9kfWxhetTBkGwBiZhxrCcUlASY2Syt8vuzg4TG6lJzJJnV0tGePb
wTEiMUGY0SfLxoAeZgaStImpY7TqCr0kR+haODWCtC2dO9Xjg7N08cP+9PPzIYzz2xjd97tT9D/4LT
p75p7jOJRBULOgpVJu+7yL7x20u3H5VNmk3twOJdnSZSbgFkF6p1HvtgO82tfluVnnayT2KMGsQOSx
BFI/clpNAqoESZAr1FN3dZHb58neEjSt/Y/vZz3+n33qR6d5lUjFC5gXMSsxc6aqBaYbfKuiUcO7Yn
Zxbu4s128ekmipFJnUAo5QamMaaedWoodW0REjsGcUnmAFjDEOUCcIMocYQ24bT+z9HJGEyg2gTvbJ
X1ViFdQd3rcCprjBQZX06x12/wAubz+CvfJ7RC59+/OzDjz1+92Ov+7vH7773X9r1E/9Qlld+nbSMq
B5tMAjGHdm72n6AB1scN25scjOAbk/ez92e0DMI6aVblB9ZC0nbGs/7QFTAz0Dn4PeIwxcZXr34vtE
LF95fXn3hDW64Q9q6gp2PWKkndDVA9IwrD7PGRTAZlexsNsdblyVWgiXtzWAcyZNlWhZ4qSnwFMkzr
ucUkwmhKhCUXQNVikzVM6RmTGRKokLwCMFkHJZpSqhCjG0omQHpOGyK9HJhJXesW+VkFjnWSwxSYm0
1o6NTphvPcLHeZDp6jjvP3fudJ+8+951rJ05+llP242SdT5D3GgMXA9GRxCKmAxgS9gB+B3gT/hj23
QJ8r02W6dDK+/IXbnYZxIATwVjXqqEK0yvocIPR1qXvn2xc+v5y44WzYesyDHeQ2YQVEwlaMI0zijI
yKyF4MGLIxDH2iQgcy7ucXT/NcVlC9mrCzpxU1oToKaiYSs1Ua4ahZuQLEjUWx9B6ilgzoaYgMkWpM
FTtlhL2u6NYB/ijafONHZsCSZuKZxmGnhGOLy9xetWRuznS9ayudxkc72P74OIOxcacYbmB7Ky/QWL
28cHy2g/btVM/TW/tp2EA0sPQBTVoS0Dtb1iHXXJTWyb/FstO+YpzcWuyZgG+V92wuh9QbA/L+N2kg
RpRNNU49U2ty5iI8wnFeEJ1+ffft7dx5YcmVy/eY4Zb9OsJy7MZqS4Ifs60mlJrzRSYOYPv9pDkSHN
lOvW8MJxQAnf2V1npr9IjR7ynqiLldM48VhQ2sMuMnThjr55RSMCTSMzZTCVlrCgIrdUp1AgRQY1tf
1DznTGmTZtoMtnFgBihK8rqYIn15S494zHGoM4QMsfa8SX6x3p0VnJsR+h3PaudwHo+Z9V1uT7890h
YP7vM3f+AcOcH6Zz4cczxT+COgeSI2ltgK+z3TfryZfeytEO6hd23AN+rlGVKLdjsQUNKPaIeGQOWi
EgNWkAsYLrH9Nrz37Fx5fJH0uan36LFBDcZ0asn5NMZZlpAVWI1kfX6zNVQzBOjOlImQ6kZ89ozmwa
qXh8NJaY/oPbKbFzSKZt4zTIFtmdjZnlgK824Vo8Yqyc4YZ4ikzhjO84plZbqab51gAZ8GhBnm7DRl
A515f3OtAoaFTHQdZa15WVWTc3yQFm/Y0BvOTK4w+JWLLan5B1YXepyrJuz5BLEGb1sE9KUqpjjdHy
Pqacfl+78v4Hwo7j06yI9mgbW2WsSNAvwfTUjNRJBUZLIAQD3BWAiYuIMW4+h3Ibh1fuKjed/bHbtu
e/WvW1s8RzG13RTSV8rnHiSDXgjRHGUoaJMileDOiEGZV6VVHVNSoGRF3LJGKwdww6W2B3P6UWBHK7
MR2zHgpRnjHxkbGGKMEmBUgIlllFqgCcCLoOyVoxNaFSyrI+v64boNwZSQjGINmqvoOSZspxZus7Qz
ZTVnqWbFVhJrK320Kyg03EsrfUYDPr084yutdi8C3kXK2NyF8nzHIwlxkis5m+xMvuXRsb/XNz6Dwv
LlwyDFoCNA1/bPhN64Ae0yH4ZRb1xeg6y/EURMUfUzbQA36tb9DWz29DkcgMJZ1BsKrA6g2obf/2pD
46e//xPVpvP5VIOOUbAxjEpVKR6TvB1E6isieQcRjIk1oSipJ6XWGdY63aRgbC7MWW4B0Nfs2oyKjX
43DHLEluTMbP5jE07Z8fOSNFyfb7HOFbQ7zGtE8NQNYm1rcljLYS2sW2336GqPDE0Va7RdGDrNUlJr
i1HL9RVhSeBRnKTWOrC8Z5yYiVyx3LN8vGM0A3YvMJZQ+YsttODTg42I3OGzAIyBzGIqREzJ8kUTXv
fLXr8P0bWf1BY/5hhHRgg0kWTQxRS62o4dMLfWF9GzCthqhfge5WCzzZkgAZUTLs0E4aIY474PardF
x6eXnnqY9X1Z99jhpfpVtvkYYyJFbaqqOuKOpTU0RNRojT0ukk16gPLWYbVxMx7dveG7OzCuICQQd9
06Ls+UWCzmOKLis3xFrNQE9YMS3ece6q/tvTUkvpn8l7/uc7S8uU/evrpjd/77L//3Vrrg3CSKBAjd
JY6fPO3fMuJc2fuXo0+3THaG5+ajEZ3b23u3Luzs/fQbDZ7tKrqR0MIxBhxNgOBmBI2h7X1LneuCHc
szRnIlCUyEgmkQ6fTpbvSxXT6YHLAkuUDxLomKkHmiKkwpkB1SEo7aNjJxdzxM87e+R4IHwT5EmRNf
bZWrVf0IKVK1dyU4vSKmJcF+F6dvgaDpoSmiDEBZxJCDWEGfkSx+dx7Z9ee/bnx5ae7rthg3VYsDyJ
pVlHNh2SlI0aPpAhWiQplnYihRjxIEqRWxCsSG4d5tMokwmYJ8+Dp9hMboxEu2904duyO3zr3yFt+5
/RD937y9EP3ffrYqfXi+PHjdJ2lm/eoysg//p//GV+4fIW92QzyDnjfBGarcseps3zHd/4n2+e/9V3
bBrkgQDGZsru9x+bmNpevXOPixUv9C89eemJjY+Prr2xe+cZquPHNV7bGpy5kJWeWTnLfqRWOHV9ib
bkGU2CyRNYdQLcPuYPctO1tFekstd6CACYh1mNsRZI56BzROaqepOY9Iu4zQvYBcL/UuCVsa52apn/
EgU1oX0aqvbZUztsWfIojSUBMwJg2arHcJY2u4UdXPjG6/PT32XKXVbYxZoKppsx9Ab5ADaTUVBNTb
cu4ix7s1knbiM9sQDIdirJmo665XldMctDj8ODxR/+/1z382P/+5te98TcffvCxT9197330T6xjVwf
kq31cblnpdluvvqEeTukeW8esLLF+Yp2uXaGazyhGOzAe0ukf5/S5+7nn3gcwGknRI0mRRwUxOSkoe
+NJsbmx9e92h6N/90dPf+5nXrzwFNe++Om3msnVJ6cu/YdX5913dAtLbTJO33kS20vQyyBzIBaVCHl
AugZxDjWpkX42gDGISVgCQoVSoalAdEiQvCti/ycj+vXG1O9D+kB2xIbTWwDLvOZVztsWfHPAiWlqW
VJBtQd7zz1aXnv6l8vtS2/PptfpMselOeiUyk/xddXszXkHnxlCisRQQ1JcVLrR4MURbM64ipTGsVV
HLk2Va2VOOvXIH77hG5/453edffh/eewvv/PCmROnOLZ8nMzmuF4fBpZKGrwFLfExkAXAC5Um8rVV7
nrsIY7dcxab7mVvZ4MvffGP2KmewWTLiPRIgPeBbu7Q1BRRIkXE5Kyur7C8tsq5mPj6b3or0/GI7Su
XPrV3+eKnys0X/l7Yu/rAeLr1nxbl9nfX4+xNK0lZ7hq6YsAl6CSkGyBXou01G45regY2RWEExGI0A
+2ACEkr0DFJLMmF77OM3yh0vxfufWq/M4U0RRPZDwpQFUQSt4MT/jUJvpeLV40iCIaUPKYcwfDFb68
2nv0Vv/XsOpMXWLMVUo9JZUEIjVoaOzlRwUdIVommsfFcFKQ22EqoS6FMQpUN2IqWra4je+TRf/ime
9/8j85+3Tf/9j0Pv50Tp45R5nss5V26ptfEkDZNhvCAp6YvOU4S2MYeTbZElvpkp44zOHsX9698E9e
vPM/m9RE717fodI/h8iUUyPIOPswRgayTN61XmpK8GCBzlmExpjvocu9jb+Khx95ELArKve0L843LP
1EPr/3E6NqX3jk1o++Jcfw3+n5GT2qyvIasBOMJrkNmsobxwYI6iFlbCrELKQOTY6xBxZNkiEpFJH8
7uN+RdOa/NuJ+A5Ebgq8PokTV3kB/vlbTmm5Lybcfr+m9J4333ldtXft42r2GLXcZaImLM0hzjFYkj
fgEPik+WRKCTwmDkIklw2A1EatELAJTn9A7jg3veuihn/26173548cee+u1/pk3YPp3NKU3gdwsE1E
CYAViVDxNFGSHHEtTidq6DggY5+gsD+jfsU7v5B1kaRmbL4Prg+nT7awgJqMO4AQ6rnPg0E5AUI/Sq
I8isNJfImGoGrlP3u/T651j6fg5mIw48+Djv11vf+m397Y/83cm1XPvD8Xsbw365VreqxDjUeNJhiY
bXg0kBykH6YDpgGaNamkMxiTU1CQ8ikGRdav6vyXC+61kn3jpzVNf08B79YJvvwqD9e3yAchQ7SAJJ
ArYCLZsJzEj0iGmhqdYtQEtrzLa/cxH6tFnf8RMn6ZXX6cfZ0gSfJ0obZ9pp0dpA9YnlufC2qhGxhU
lV1HXpzJ9rqaMzbpDOThJ/4GHx71TD/3kfW96x0/nayeLwYk7sUsDkgMvTZKgQ8lxbZ/0ANpMglODi
rRqZ02n1yrIyeJiYnloeHh4kjPXTrF5WgkZdPo5xIKODUg9o2MgaSK0PWj3SQyR5p7d5w6DHDpXjq7
tDDi2SvI9smOnOH7u8WvzyfWPlNPNH9+bTr4/K/wPZo6V3ul/g8O0Lc48SAVmBq4HdkCswMgAMdrcp
ImmbTx9guN3ENP9OKyfhGM/CisoPSIdVBwqTXaEIbZpW9I0isEiWJLsZ078yYApC/B9te6C/f/slxv
j+2GbakEjSZp+JAo4Azq9wGx67aeqyZUP6XwHG0qESJSEswnNlTpUpKT0nMUqkDxBlV43Y7V3jp3xn
J1xzYQeq2fu4aGH3vrROx/9hh+zZx4eki9DtgydHvsmTRZBTERECAJW0k0exsNhxZJISPIYDMEp3kQ
K8RR4MitkxmBMw8tHX0NsAsWN2T9iOrg2+6CT/dOZfXLDHqRN7Wt5AuAskvdxA8Pyas7yfLmoJtt/b
z7d+fl5Wfywq9Z+IDlwRKyNDetJajYTX2Ftv81yaG8KaERN2w5bPRoFMdMfQbIVcB9uokw7RBXMfgG
q1haUtsOuIK8gFG0h+f5sh6V1lBug0+oqDXOmZr9ymG1CqVTa8KoKp03C53Dvkz/rp1sfCNMX6NSbd
MIEazyaRbxJBOtxNtANHkJC50qswbgOMe+wOYRa+3ROrnLs9P3/6/GH3vjfZw++/nOcvB/cEtAjkLX
2C809kWaVByXkiUQi22dJ9cbNoyEhEl4jmc0JTihsZCaeWRbpSEKMtv3VI1U9b8kfMPaw6bS0f00b4
bKPdTWpfbW5hnqTOBDTgN9gIetBZuj0u8jy8tCWxQ/aNPsVpfi73k/+o8gYxwxjQTUQqXFm0Pye1Ep
eEsZEwKMSkDRHqUjJIzZ9SIx0IP9bhlZl1X1Hu6EtGdyUtDiQ1LIA39eMUJF547DVjJuFh0pE2x0ds
RhjMeIhjonVNn4+J3sJbgAAIABJREFU/NlUfOYDzIfk5R7dMKUrFUYitVWCicTocSZh1aNlRNWQXId
5EPZmJTtylpN3n9u4/9HHf0Duf/SfcOpuyFaBjEnlMZ0ugYjRSKd16DdxlglEiSQEPSKb2kWv+w5m0
6Y9WRQhWqU2kXmm1B2l20qPFGvQSDkbU/s5KQasNBn3rtmBjli5h6RiPKD19QCeHKE4BAiqaFSMCJn
t4lxOvrKCWwmYSfY50vi76nj9vwrp6keTyCljSqwJGDJiDIh4DB6MYIySSFiNDfDjtJG2Mm/iZ0U/A
A6kBWBsxbc1bXpuBGl8s41/cAG+ryFh0qhjIhxGRQtgpM1gO3zKCkANYZs4e+an5uPLH3DheVwqcDq
lpw1IkiYSihdFxaC+Iq+bWibRdBipY6w5dZ5z7Bu+/Z8eP3P2b8vZe7dZPtYSDTlITt/mBG1URyMGQ
0JpJFUjftJB5rfZ93UdyaK3R1RqJ225Bm0kurTEIqmGUKOxAgJlNaepyZluTS+puQXlZI58hxslbyO
Vs0b9pAsonsi+NdntPAQ6Jo8r/4TY+z986v5MiLt/3eoca1oVX6vGpEw1ooLR/VqlCU1jjLUtW1pBi
IB8ANOpMJ0Po71Gapo2/pNmbjD7W9YipehrNmK7Z7tDjvpAcqiYg8zzxtyKiB+ixYsf8ZMvfShNnqe
fxmgscVpiUmx6HqREVEXFNZ2AEjgMErvsjj1b04yVux/jode9+f2Tx5/8RKe/3BAMCKlOmJSD67R9G
A4MLwJKTSTRqJj7nq3GDjOHdSqO/pbUSC2TBJzgIvRsRs/aRnUOnhjqJspGhBBC6+iX/RZINyauSqu
WS2Pv2S9LZk1HFDnTxp3LQV5e0ERKbeNq0za1dl3IeuSpv23Cyn9Zh+v/Noatj4c4otcFk+qmxIaax
vYODqKgSUhujN23CdVCjCQVjMs+hMgYWf1RzKBlgATIDtzxr6Vws1en2vlSmdCt8RKOTJEPu6TJc+9
jfPFHtHge569hIxAFm1rbMQWSCjZZjOSot5jYJ3rLtHSUrsvKubOfPfvGd75Xvu6tn6q7ZxDyFkSCZ
IlcHfhIrCtsp7VDTaNm7meTpta+6rYK5Q3kkd78O2zj/EuJgeQcz/usZl160RKDPyiqiyg+xTYKxbS
M4iGQ9i1D3Y/AwbTf/Oj5jtRY0YTRhtiQNpLHqGCMO/CnRwtGOohkYLs4WQGz/gnPyqdSuvpLyvANa
iqgQJI2dnnqQuo0THQ+B8kgGdCMpAG0CfcTnf8I9uQm3PEJdBW0ByYjteqnvobaW79K2c7OgdUkN/U
VkNausQYsM2J9/dt98cLHmT6HrTfpM8FUHVJSotQEqcFEUhKcZOTapyoFX+UMx0rJEicefOJXV5/4l
u/hjvsKasF0+wcY8YBR25wvd1h3ZGGL4MQcQC0QGtuHnMOaMY1E0v2sb23ivg90Z4XMZKznfdZsn34
URi3wQghoagKkkzSbUkwRZ83BJpUOKIvDQ+b70360sp+mG8GvjQFqjuLUt691laAGSQ5DjrErOFlG6
HwqRvuOmMI/Smb2V50qIv5Q8pomtlNMTdKExPyAmVWzAzIlMsTK9ONodRmV34CcGDKikYbDIZG/1sB
3tLDrrRybL9f26o/jEH25CJSXjVAxDqsJlYi0/jNSE6lvAavg8IhuPTqdXviVevw0Hb9BHqeIn4NfJ
USP63ZJpmY+HZNj6CRHmM4JswHDMcSl05x93dv+fufhN3+YpbtAl6HfZ0X3yZ1WmphmXdZteUHVgJN
G/TSAbdVKpzn4gHZa8kAEpKmNWbU5bM6AltB1NDaRb36fVpHZ7hBnB9SDQdNUM0aoSmK0iHUETZgYM
GIx4g7jTTks/qRAaIkd00pc2S9Sqgl8aM7bBLG2z9/o4gkkjEgjuBKkYBBdRWwgz1JRFJP/zMTqp3y
qPiQpkhEwWjUbjQkELTHSO5BgST2aiqaqmdlkVmzR78VfEbvyjcSVp6CLNU1MbqBC94k2ubWvT1/OH
6GvbH3eqpnMV7O+bz6GO/rCX5QKxS/3HSQJxtiWSq9bQ1zaSAvIUkLDFuX04i+H0TPrprqG9buYUKK
1hyAkLFNfoXlJNrD0Uo5MHTY5ikli9eR9LD/wlh/iwdf/BMfOkOwSUfqoQB4OzSkVmqrSbU55Aqy4w
2jFqNgUW58jkFwjicy+2zkREWJLFhmg26XJWKjnzTMB6nJO9IGUEpkzDLo9+v1uQzKlRF2XWIROp9t
8NsXGxhJFbNt3r2mNSSA/IPGlrYZtDDhjkI5raf023We/h98NpE2jQps2takJSHGIDIBj9HoPkEL3w
7HubqFbP56kwEhoik6RwDbBAJKkFbgBbIExU8SCsVO8H6xnaf2Xxa6+w2oPHzKS9dibuiztO+5fMfD
+hOvvZuHzUs1Fb/X5l1rP7uY3vZI6ni91kldaA/Tl3vdy4LOpZTFl/2InEgHBYlSwcUQ5fv4Txe4X3
h6nF+nGLWycoqEE39gW2IBPJZo8Wcfii0Q9KYhTh1s+zfI9r/ubPPaGX2DtLtT0KVu/nblpBxVpiB9
7YJHs49K2722/6JEAfm0dx1E9QSMYiyUjxzblKzSBLyDMweYwnzOa7jGtZlCMkXyV2XREVZUQPcZ28
VWJL+d0yKGqGollLc4KzjTpO40rXKlCxDmLaVVdrNnfxg4k+kFFQLtPc8QDTtSQHS73NhNdm8A5lFV
EcqzrIaH/E1H6E5Gdn4ddMGPQEpXG79g0+GxYUCMek0rU1DjxBH8FwvG3590Tn8D03mdjF0mCtY2mc
HQN3gy4l11fXyVpc6v2AEcfH+1S9cey+f44nUn/pJLyZSXby33pVhtCLJGGZDBGMaaCWMP88nvj+NL
3yeh5OmGbrpnhYgU+NiUK4ghjPZkoSS2pFHb2avykS69zgpNf943fx+lHf5GlY2Ac03bh2YazBBdvs
o9AVHF6hI61rSonN15lVZAUcAYy0UNLLHn8tKAeTxDvcbEexNnsLWUVX//czviR55979r4gHula+ks
ZOzs1KZTgIDeJK5cuvPj7//Zfby0hV06vrV9a6fafXhks/RHdzh/QdTP6GS6zoIG8dxxIhNRE/9AWk
lKagsLuyBc2R5z1+56drC2QpHJoUR4GrPWBHmgXMX2s7f4C2gkq+j8iHpGIamgiXlqXkW0rCxAbkid
Tj4YRKV0hsf59puM+aczJXzLSBbIb1sefhbZ2Kwy8Ekwc7U71Sr7TV0243OrH/1mrrkY4Qih0G3cCC
Sgg7T48Hz3zc2lygbzaoisVOYEUEj427B1phI1CRyHFLlUtlJMe3eX7OXnfN/5NHnvHL5Ktg+lRqCB
isEdyA8qWUbStH1H22Yx4pPx5MgcZ59q+FFoZ3Q+xKfHgmwrXlCVhOGTvyvUnh1evvHu6ufmXs1S/d
Xt7m0sbm3zu2i6f3Z4RTtxD7+RJlk2grqfU9RSKERvPX+VX/9k/vvu3fi2/u1f5J+4/eSf3nDjJfWf
Ocufpuzh5+tSn7rr37v83O3Pq/2Z58JvIDKzBSeuwbsPUQsuGtl3jOdobQY644yW2Es82AFL2k2JzI
jkSwNJBshyxFoL+Yki1A//zog7STlPZU2qMaTYEUgahf3DBslBR+WuUlaU/kJ9jIL+NnPwSVUI63a9
q836lNt8fR7rdvCG8kk3B/XFVwj9NCfgn35oOJU5DrxsSFXUcYYvnPlbsPdXNi8t0w5CcAgioT8QQC
Ah9U0MEVxl8mROrHl13huN3v/2HePibfoHeGdTk1NZisY2/jyYoWtQQJR7MYcQ0sfpiGpZyH22tmpm
SIpaDpiqIgaKCvR2Kay8yvX71yXo0/Gv17u53za5vrs23tqEsMAaK7Q02r1zhwuVNNjTn1PG7yHOwL
tEfZJw8tcbOtSXqnRFXLj7DKFQci5Bdu4ZdP4k+/yKbS0ssrQzeevyuE289fueJD/VW+sO1Bx75tWM
nT/2L7Mzp32RlDYwF63DG4Iw9KPLHkQYy0jrkD2NEE6i2Vb1N6wDIGvZVW/85A8juAJ0hqfgFH+Ny0
v6PO7fX2HmprasdXbMz+W5zXwIiAak3CbGkVNPtuqWPkS//B8T8K649Qf5U7L6vBg+vlKR0f5onOto
W66vZmV7281oB3QM1LkkTMjWfbnwwbT/7nlC8QF5vYutJo4a2XiJVIRIQmWNqgxQd/NjQc6dYvvdtf
597/tJP0HuAQrt4m2GBjERGQmJqYxWhk9mWRVQSBm8EPbKhxnbBWtXGPk2KpECal1RlSe+ZC4ONF59
//+aFp98737j6qJsWZPM5bjpjuZiT+Rok0h9uszyZ0pmUKCVaFxSzEWa0RVVPIFWkOMeIkpnIshVWj
GBnE2zWxboMZjPme5a94TbF1Rewzq25Zy587513n/3eex58+KnVc/f8EsdPfJyllRm9JXAGZ8CKaWy
/g4Brc0TNrg9tWFw7n47U0r/Slg5tNJQMslWsnqIO+hPR908489SHNNaEUGJjxHiL+D7UDfhSmhFkQ
qljqrhLVUbUr7ynt3L8g3TXPnYrhv6l7L8/TcB9JSLmK61ZERE9fENPmgMVr9jV8Oe1W7yikWqQHFV
DbON3vff3TabDn6z3rrAUx0icIqGEOrZrRA4CSUJdYKocKTNc1aEzOP2rnH3zh1l/CFgi5IelBM1Bn
ficI+Kuec3YFvjtxn1EUcuATJqQMMqaajRmtLGxMtkd/kD1yT/44Gjj6nKxcY1+PWcZGJQVrvBk85o
uiUkxwQ3HdMuKbmqOlwOZgLWCMeB9RZgMkQRdJ3TEYuaBPIMlY1jPM1Z6A/KOJe900JiIoaS4fp1r4
zGTzZ1Hj794+aMnH3jkI8fuf/BjnHAfpefGGHNY0u9A05BDt4Np07hkP5nWNoqpHrg3CandfCwgPch
Wcd7ja/fhFPRcivVfTfUEao+pM1xtMFUO0VCUFTUTStnCG4iaKKcnOBUe/Mn8xH2/Dlz6arrkyks3C
UhH1m9HRPbz1dZEZNZO8TERWQMuA7mqPqSqQVU3gHuBu4wxW+3xHgeSqu4A94vIOeAZ4F8BTzXcfDB
9iaIk5tLk3giaFCeNgh9KxMQmUxPYMeGgO52haRuV7cdNaLsDxcP5kXaBHmiLDcF3JLjpkF1LNz2+l
bY5dT2WrCEHuuUYW41h5+kf8xc/mevms6juMPVzbL/LbDRkdWUZrSMSPC4lOuEBtvdKtuou6w9+w2f
v/Pr3fA8n7yfhCVlFB0enVaYEiEZucHd5tP3VYFKiiyG0wcwekKgsKZi6hs3r8NyzuMvPfdhcufTfh
Ssvrg2KbU7UEHYnyLiiqxmxKvGxxvU6bO/uIcYy3J1TxUYF7HYGhAxkxeHSEK3HGFUGa2cotrcYT3M
GuaUT5tRqCHUkD4HV6OnOazq1xznX9Fxfyumh2Osj4m5BcfH6sr3/0t9ZfeSRD3Dv6b/HXad+in6Xm
TFEDF3pNo5t38xKMA3pYWj7zRMRIN/v856aKAfV1IRtsgRmmdQ9g5qa8rnf+p6Ujj8ymY3fsLm9waD
XJTeGrRcvMBCHqQJhpiR/Apd3yQZLXJt+hs215/O3nH/+x6aD7/7PnTEYYzoGU7VOmxzVgaruNQSuv
SdBGVLYxshZhzsJbHpiqsget41M34B4nyBnLGwJ0aZUvz4zRGLcc3C/GLmLFDeoqi4hfh1QlfnWrkl
6j/PhjPH+ReY+ow4PoBIxnU0/nJ6oxA0KsbO57SRZXV9eO3MWZOkLFenasShBRHBN3TbuxfJXCOmhe
lK8kCRdNJbjucNA/Bz4RMedoI7XmIyfO35icAqs06TPpCC1VXc3JgzB7aImQ+yAyLDhoLUDVC7UjY5
oxGCzdFCcsa15KSJou9Ua85Uj153N0JiQELC2C+Od77hy4ep3b17axPmKoIlMG1KyLjsMQ6AsC7Lco
GJIwTMsEv0Td3HnPQ+/l8FagVpM1m0Dec0BvX60n9GhVLOkFKk1YK29octcjtK1ApMZYeM64y899eT
u5z/7P8Rrl5/ozEbEYooNNeoTqYqkOpJiatVnS/IROl08Qr6ySpzMmAOTqqCbIikFOp2MTsciLhHFo
5LwyVPWkb4Gsu4ynW63KSPhGqlknSXLWqYwyxCbgRFCiISiwF/bZmazNR2OPnpHFf+L/K6T/+1gde0
3yZoolBgb+87YW/Wbb6+SafuqmUZsitjW4dIGutqmH3zgdPH5L372vdvb258cj4eUxRT1gfloSCoq4
rTCNoQoSQXJOkyqimMnT5Fl93z3I39lXnT6/UhmniPEjKRvwNqalPaoyvuAu3HuslFyF/zjpDTHmG1
SOi11fVdP9Wq79k7XdUUK9V4KfjWG2sTgVVVDDHUmMYCGqD5YXzZpW6rKXrhOMZ3h56WapMdS5ZmOZ
0wmU3zg3sIntouSwuSDux5+HW/8xm8ql1ZO/EZ/dfmjFvf7+6qTCz7hjA0YlqpUfevGePN1v//7v0t
ZTCYrvdycOrYyyJOfGV9tHVvqn7xjbd3ygr9gjPFG3FkVc0Vs53nT6R0jH3Sw7vMELcGcwtprOHcRY
9ZRtaj+ESIRl5/AmCtgLqHplAHBuc+Jyw1GTjIbb2Lci1hzByJdMM+3qFzHmFnecTVFaBLs5tPq4qe
++JHf/de/zXTzixwbVOQyoyORfidnHxp1rDl2bA0xifFsgnTXeOz0o+/n3td/iv7xJv7QdJA2/lKOE
A2N3RMPOtCikLB4E4kHCZ+JTBM2CTocM3rxMnuXLv703jNP/e3Js1+iu7vNegwMFOaxRH0T+WJtjg8
BtRlJEsO6IACzsmQkym5o+ujWAqbTZHGrlKjU+FDgfYlYxWWCNYY86xCtEl3TOdCnSMdYTJaTd7qIQ
rSdRiUxGc5ajOsgAdJuga+Umek/Yefyf7q77c+wsvL90usgInjTBGwfePn0JjNlP33qSHaFtBRNg8n
/n7k3DbYsLet8f++whj2decw5a8ya54GiKCiGy9iIeJ3AFrBDxBuBjY3YHd1BBNGhtqKCVyIE2w4pR
em4tnJF7QtGKyiFRQ1Q85BT5XTy5Dl55n32tNZ6p/thrX3yZIFfbDvo+lJVmZVZO9dez/s+z//5D4p
IBhozr6L/7c1vP/rYsZ89eeLYZ7vbbYIpML1A5EtuQVTtc60tDdSsg5HxjKz7LMI98lOjo6M00hrOF
igPSRQHEZzI+wNsnoVYRzcqITCmwBlLCOGg9x7rClpZb48QAZzH2BxnzLjzecnxtVZ4m0WuyEtjZGe
UNwVFUewUHyLHGUev1xVb3R6Z92Qe1rt9lre7FHHKzOGr2XfkCq49fM3Rq/dd+btj6dgfEcQagK+el
w5BeCfCcSnFr5iIv3Gp/Nhm1n7Hdx5/uLVw7CVaEiYT3WgF0ZhIE8YbDeZ1uD5NU5K0HmSkJ5SObkr
qDRrNEeKkdkdpAy6dkpGK45hIxUYIpaWUQkrpXXOiLaUcr76iC0Jp4ijdoyK9JIS6gFRTUquaUPHzC
FUg2AfqPEqdRspxW1OxQj0rVN30Fxd/+cRjL7H4/CL9rS3W2Mb0V1EyoIQkjlOEVOhYMz4lsd7QTR2
33HnrH4/uv+VzNOdBjoBPL6PsDmPExM4iePi2lTsDGZdyl4KCgCfBorICujnrz710++rpU7+7dX7hT
tobNK2hiaRlPEme47XG5AZvJcZKusbjRSAjsNrLaI6NsrzdZ90Flo0hB0KiQQaMzUvwxQ/Iiw4u2wQ
PA2vZdgHhAgfmZhG1BNFMkTouS0BHFD7graMWSlqAlBod19H1BrLWRKkU52LUagfHKmrgPiJm8/vZM
/MzshU/GYSgAJLqEBqCGyUN9PIkJMTuG7JESX0IZVczdgOHr8swf/vS55567rH77aB4r3BQBKhzyfJ
iSJ9vRnV0UOQXJC88sQorf8xIs0WjlqKlItWKZpwKFTy+yBlrNEWqVZmQaw3B2WpPWyJIPlsr52YR8
N4SfKmDFMKhgkW6HOEtwReltX1wRK40HPbekm4VZM5AYbBFRmYsfR8wSpEkCQeuvY4H3/mDxc33Pfj
fmZz+JLXRRxEaslDupnQ5muko0riKmyhT/fjo7MTPvvEdb/qHgwenf+bbf//1I8ce/Rar58+i4xpFr
cb68hL1rI1vtQjNhpC63ABlSYxptEjqtdLXMihFkEgZoYSOyn9WKBVJ35gcF1WYYgjsCUIhVQTIeR/
EvPG+5CYq/XqPJARCQN4ohEBKGfKJpnCFfzdW011rs/jyacIGuC3F+nqXZnMECBTGImSMFQERSc4ub
ZKZnMl7r7w4de29H5EHbgBXA1GHSFO4EiIXQ3uTcGmlcRmI5i79u8WW2y1vsReX6J84+xObzx/7/GB
xUdPeoOYtaZ6T5gW6nyH7A/JIk2cOKSKciihSTRFFdDCsqR5nN7dYaW/TMZaztmANGODoFQOCy8t5W
wyItNsR8jdHWjQD0O5ybnOdVDgSKSjqDaaSOjJOGEnqJErRiJt4qRAiBhUjiBBOIgpB7ANprFBtgwv
bBC/u1JF+DDX+AVHXf6SE+se2r5ev0XaSoAShCuUU1crGOMWBa2/njle/iaeePfGR488//0YT8lkP9
BDEOi5vcRWhnYS4UTF3HFknsH5umbZcpZ7GjNabjKQ1CiVJpCAm0FFtrJLESiC9QwZf3fCqnHllmyB
FSQn0BQSLV6VjOcGQ5Z2y6ERFIJCOEALO5BhnmcwU/U4Hgiet1ZAqkDlDfW6ewzfczL1vffvTh2+/9
z8zOfeHWNHbATiUqDSK5cGkh7YYttJXp1FtTc9M/tb0/a969PqDe3/xxcMH3/7M178ed86dI/WBuk6
p56vUQ04jSKQD7y2R0NRUThISIh1jfSB4RRAaQlxaqcsYJSP6WwOElAhRra2FREiN9RLrPEJEOCHxT
uACWI+wLuB9IIQgtluaYhDAxQiriLswJiap1SStmREGRRfjyodWBEXfFJjc0+5vMT41w76bH/jYnhv
uW6M1j80kUuoStQwVMUVUKGfYDfVcGl3QQ1JvICIQY2Frg/bJY/9+7Ylnf9ktrZBsbJEUBZG3+O42R
a9P6ktl+GDgsSjQMSaKWA+WC9ttzm6us7i5wUp/q1Qf1Jv0k5ioFtMaqaG1pNlImRyt0WsnjDajSnY
OQQaS5gjWONCKdec5enGJJRkxGafsG5/k4Px+picmGScpleEyAZXiZYStDhgZFErFEJVkNz8wmI22R
okvqMnWgbhV/5VhV7mDGsrvxRCRVcBJRT8rY5OQUtLXnlpS574HH+Dc2dNri+fOfuziRv6HzTSlk2U
MQo4WEc0oKm+ioo8WnoZQ1KVkc6MDwVFPUtyIxSR9YgENJWhEGpWm5Q2HRxGIZCjzFSMNkSSvuTIqM
Bh8MCjp0TgEFu8zorreIS2GapfssFgFRW5YMV36iWfLedZsh2xsgsNHjnDo3vv8/I23f3nP7Xd+kqj
5eGa99zoi0RWKUIVjiZ22cxch1VftQUyKSMKje/bu/5fzb3nLT16/7+AHTzzx+K3nXzjG5vIyjZkx4
jghisseXgtNLZLUIkkiA/3+JsILPBohI7xISmsHYUBHNAa2/IKkqiDsCCk11guMBYSlsJA7CM6DlwQ
fsMZgrGN7JUfJFFdEmEJS5I5+v0fhCmScsr3ZpT3IcTomE9DJAoVw5D7mrlvv//M7HnzbFxpzh0HW8
VEJBLwyoy9Q5thdgl7lkMS4o/FUeOI8I1tdYvvYS7+x+fSzHzWnz9Bs99HdjMg5grPkvT7O5uRa4YU
k0zUGzrHZ67JuLBezgjOdLdbyHJOm7D1yN5PTU4xOTy7oVv3RIo2evlh0jy52239W1xJfdAi2TxpBs
yYIkeZNb3nzHW978I2H6qgj3cWlW+3m5r356tr+fGWVfL3NxSzHdtps6YjECXRaI1UpkYiRKiFEETK
pIdMaQSlEpCFKStex3BM6GUrrXxYqniDSv7CL6LlzKA278/LlEpdZQ4UQSo1HKMkIBsPcgTne+JY38
OzTT3zhq1/563fnPnuXoVxTBGtAeyIHkbUEGYhI0DbDGEUaJ8Q6KWdY5xFSILRESolUIIJDCI+S1d5
SuYqSKPBBE4IjeIFElmEwFXBmiSgGHZywWG+w3uBF6bmTmYIsy7gQOXwck8cJjE9w4IabueaBB5/Yd
8sdnxNTc1+0spkNkLgoIqZW6ksDeOOJlKRSfJVLdgUkaCy2rHBvSaVG1kZ6RPXf3Xfn2FN7Zvf94qk
Dz/7A0Wefl/n5fyh9J4MnDo7WUOLvLN4UNKMIHASh8SrCCYVBlR9CBlpxWXTOhfKGDKakJTuBM5X63
AaC8eAFIiiEC4TC4KwhjQ1xlLDZ6dJez0DEOAKdXkbP9vCJpp05Qk2QIdiyYLSkMT7FHQ++/uNX3XQ
bVicQJHJXhJz6Hq1UEENx6qXK7HiIBSTBItvbrL700m8vPvrYh83p00z0C2r9gribo205RQovGKiIL
RzbRYctH7Pe73FqbZWVIseNjhIfPsid1x7h2ltufvi6W27+8+nZ2a/Wm/UX09E6XTPgO0ef5Utf+Qt
st0NzrlHKdFxB0S/9XGZnZ5981WsffHJ+fIoUgW1vUWy2r+8sr7xl8cTJd507euI13fUt+kJy5uVNa
i3DRJrScqArNb0TEqEjBiIQi4ASAa80SqqSydC3EHofZWY0RvBzO7jK7uy/nZtuF/F6SLnaxQ91BJI
o5qZbb+Ud73gnR1889vGjZ868S2jQGrIccuOIiEijmKaskRZAL0fZhGYSM5Y0SQTEzpNqTUPHpBKiA
FEoV0WR8MRaVvYWrvxgeUzwgeBceSPHlO+B92ALalGK9wWFFxgv8KqMW5PaoKKE9cMNNvoDRuf2cc+
b3uyveNVr/oqpuU8SNx51suUMcUVEjMpLLQhSASKSVcb4TvGVT0xVaJSvAPbSc8OXfg210Uflodp7r
mpNvmf6yE0fWnwqvuvCmTNsLS8zJkEnMSFclcyBAAAgAElEQVTLsL0+0gZM3qdZaxAlKbkXFMZhRAC
VlL22KZBSo2QJa1hX0rAioYgSTadr0FJTjyIy68kLj7UWUxQUucGYrDQosim1KKaXOTJbYELACMHFr
XVcFBO0ZBA8F/0WI40Jbnngnl+/6f67nk/qjYoU5odr9J3TCMA6uyNIdVTzZygTgbQqldwaT1jZYOm
xp39j8fFHP+wvnGckK9D9Ab3VDUaiJqGXM8hy9GiTrrCc7G3S1YEzFxZZbm/QlZLpI1dz0wMPdG589
X2fO3Dt9Q+Nzcy8mDSaCCUr4qgh8QkTUxOM1uvEiUb7jEYsqxcFigzStE69OUrcGsEai05T9NTsi/X
DV744e/Mtn7pldeP6pbML71+/uPKhTfdY69zSRZYvXmB/HDEmFKmIUPWy+SJK6HqHDh4pBdp54qKag
YKhaHc/HCdJQRL9wk7xKS6pJLh0Iw6LUEu98wNWSFLKApDUec39b+Q7jz/3/KmHfv/XpdIfa2d9lNB
oH1OTCZFPCIUiISEmpk5M2veksWeknqJxJLmgJgOJD0R4arEm1WXBae/RIpRWi9ZTeEG9lmC9RcvAe
KOOsz16nQFRBKY3KLkDwWOtY+B9+d4KSQgxq/UJrr/nJnfLPa9+bOzKI7/D2NQfE9eBhKIIECuScgt
caktDxf99hSxGD+OCGQYoBlWuz+UwRSZCqABRPSOp/0FzbOrYdRNv+8XaiePvOP/iC9KtrjHIcoTto
5IYKS2pLpEll5fCTSUjUp1gpMQNeUcyVK0u2ODYmenKFMeKKlQJVqUoX0atEM4TnMd7S5Zn9AeBTmY
ZeEPH9en6LlEzpe8K2v1NehI26XBw39Xb9735Nb8yd/Veimo1IIYeyhVdYJiYIxW74qKjHacFKirbw
HeJs4L+saP/fvU7T39UnlqikXXR+QDyjGa9xvb6Nk2RktZHOLvd4RR9ToQBR5dXaK+nXHPzDbz29a/
tXH//q351/w03/Nb4/n19kTbKT1Be+JW7Q0A4i9aaWEMqBc2aJlGgnEFVB0KsYhCKzCt0VHYZKqpSe
NM6amz8xX1zc7840+l+ws7v/8j5k6f/3eLL51rrW336W1tMeolIGihlGBlPCHGMiyK8kGUQSoCosJB
bQipBqI8SRRvAr+y0nvry9WwQl9Y1lxGaK2ArVgJRi9k7fwWvuvd1PPf8sV958fixnwkuHXHWoq1Ai
5iEGk2Z0hApTRXTKhyicCR9y0gtRgqHNAVaOVIRkXhB7MqbO9YSrQRxJAjBYYVHxR6hS82jMTndgUE
Fg0wEUZqgRESn36FvHCaKsUAePGmzxfjEOG94948yv2fvX7b2H/oUrfFHEUnJPxIJtUgRnLwkLduxC
AmXuHpVBZZYZZCXhh5BOShXg6YVpf+WlgJU5Ega/yDGrv+Bw+N73zsxc/j/Wj1+9J7OyVOqXywhVEQ
kIA5lgQgf0D6UPpBClR6a3uOjMo65TPvxGFdasgt0RU0yeCkonMdYT+HBBI/Fl6RmKTAOCmPoG0dmD
T1XMGDAIOTkHtqmz4Yt8HGM1hFH7rz+k69+06u3ZCuqhuuww2AZvhFDAEEisZVbyHC5LocKoQCxGTB
YvPATq8+98MvF8ZcZ2dqm5gryojwxe6aMZu52MgwFy8Hz3OYqz9otsskmDzzwDu5+8LWfufuNr/1E4
9D+DZIYh8IBxcCSpro8lHxVfKJ0ftaA8oY4glhZlLQlCQmIVUmKhhKy95XaQgZBrASRkjA+Rjw21o8
nx3/lmmsOf6750sufWHz22Ic3Tl+gv7aKCZJ9I1dgjcdpXybOWtBG4rWqZjGHGOR4IZFS/TJJdA4p/
qiyGi0d1v4xMnz1fOtyV0F6UKnmjjvu4DUvPbC1cPb8J8n5JYGn5iUTKmUkJNRDTCOuMZo2GJEGYww
1nVKPEmSwWGfBC5SQKCkJwVZc3kp1HwTOB4x1GJmjQ4SKSx1oVhSlhSGObOBRaUxPeXpBkEkwKqI+O
cGBI9ebuWuPPMLdD36GevPPiNLKHEpWORWVT6m8dPiEnUWx37WOkbuI1eEVJ1P1tg2Nd1xlShQA7z1
NX0eON/5ktDZ1brQ18282GnPv2mqeIDt/ns2NDQpnGU01dR2TBo8xhtxYNIFIKbyUeAc2WGwozWFLj
01QWmMHBdYV5CaQm0BmPcYHcmvJTY7XksJb+tYxcJ5BMGTSkGMx0tHOe3R8To7DC8HeK/Zv3XbvHZ+
ePTDPoOgRx+muE9nvMqy87Ecr0VKl7fKgREA4T7yxdvu5p57+fOelo0xkBeNFwPZ6ZH6ASWNWum1at
Ql6ec7KZo9zZsDLuSW96mrueevrn/uJd/yrj8wd2v81OTeBVYGezdE6IUJSS0rGX6hWil6UWsWyQzE
IFzDBIGTJ4dSq7AZV8ERCElVroyFGVCUPwrC1doGiIUnSqY35RuPnJmZm//z8M8d/6+UnX7hpNeszZ
sqViNIS6SKcDdjc4JQijkvGjM4KnChRarz9PLX4RSL95BB0eSU3MFQD4fDdU0LgnccF0EJAJLjimkO
85jWv4qknHv30M99+8hdSGY2NpTXGRY16EVC5QQZLFElCocsxKYkujVBKIOME4qgiwEqc9DtKe+Md3
nu8EMTelI4GMiBDgfWDkoMqAwNTYHNLoSOyWDHQmtbefVx9y+3M3H7HV9i3/zdpzT2KrjaRjtImvAo
cDVXtuF2+POEVUpx0p+3cbQ8gLqFWvvryA1wW4iSlwPo6cZCGuPYwe656eGJ05ocm9h/68Mpzz9538
djRqNfZIgSPEYLUlbptCUhX0sh6Rcn7FxXxWHqFcyWB1psCpUTZngaH8wYfwHmHcxbvCzo5dAcF2wN
HpwgMgicXhlwYCixWOTwO6z3G5Ry58chnbr3j1r4Qcif55zIj2WFfOUQLRDXzivJze2dLNXjw2H6X9
lPP/u7y49/WyZkF6gMHm1vYvAuxYLXYpi0lq2bAQAleLnqc2t5m9u7beN37fvT3rnvg3g/tmbnekyq
8khg8Wqc7i+UhP3Z403qhEGiiSBGpsrgKv4mMLGlNksSQZUCRI60lGn53cpe6YvjHLOcKnIzJVSCdi
EibI1+7amru1nR0/HOnXzrx0+fbm4zIQCPWNBp1IhlhAtjcErxAxxGJc5Dn5cEgUk2sfxe4i8qx0Iv
wXQqPIRpTjoeGgEUqXa48coeoaw4d3suRa6/qXzh+4jNy4D5ed566dCS+XIYZk5ObjCIzJEmEEYHtr
I93BbVU04g1XitCVD5bpQJBeIpQgHMopVBRTNPn5PkAby2I8rvVWuJLoxiKADaqU5uYYHb/oezALbd
8s3HT7Z9hcuovEIJyviv/TEHLnRHJDf1x5OWrYf/dLQBDPchug/+y7dTDX+SrGVGidnk7ep1UDzUgE
glx9Jek6epUEn1Uz068c+3kSQbrF+lurJMUBU0FKaXnii0yrBXlg5AKrUuU1BmPMRneFyRpnWA9prJ
EF2HYJjokju2BKYsv92ROYISgCI6cghzDwGYYAkJJWqOj3HXXPZ+94vA1BASxqjGM4RBhF0S3CzuXF
YtfVYZMerg07ndZO3f605uPP3WnWrhA2uliO33c5lZF/VJs9npsNxssZT1eOr/CSi/nyL2v5p0/9VM
fvfOtb/hUfXYajMKJco4IojSgsN6g8gJFBDJCiPJWs0N9mhRILdBSIBOPrgmiNBApyAVIb5DOgC1n2
FAFyVo8zjtE5Q0hdqhzGqtduejdO+73xbd90I42j144cfY3V7e7DLoKF2laYhQda6zz+OBA6PImDhY
bAkoIVKTvJIk/jeTnv+vWC+VkP+w6Q/XeREpirUXqmCIYkiCZ37uH++66h1Pffv6z3cW1j7utLkJ4E
hUTSY1UEVYIamlCVIsRkabwFm8NkRdVEI5ByUCkS/K7FKG8jV35AZRSYCTClN6sURwhYkXhDZ1+Tl8
qXKNOc89B9t12O5O33/kVDh7+NPXWY2UvL3Gu7IZKFUcJxiBFNaeHXQYiofIdF99TKqB34Jfhzwu/Q
+AIuMrc1SJDQFYWc0bWKuMgURJ0nStULf6GPLD3GxNzY++Mplof3j5z6v7Nl0+lZn2VojBl22AcPli
ULjmXIZSkYudc6RcpBFIFgrcI5/G2wJoM5xzBBbyxOFvQyx29PGdgAhaFkYo8WAahoOf69MkpkFgvO
TS/9/evufrIktYxphgGOsqSElWZ+Ow8mF1tJ/7SjFdadDnaS4tvfv7bT3xk/OQZJnJHnBe47S6xD7j
CsJF36eE4s7nBmcJyMu9z+PbbeOfPfvC9973pLV9U9WY5I8iKSSOGiKsnFpIo1mDkzm5ReHDK4LF4X
4as6DiiPpqwvd0F4fABIgX1pARhcIY4jncZB5cvRrTL8kIZj44CQSr60oIP1OZazEZHPhWNjy6fee7
4H2edPpsbW4ggaDabJejlAKGxwZQng1dY4VDKk+jwERq1r5LovxY7raffMQpmt++JVwgpKUwfqSTIF
GOAEDE9MUci60uW2u8bb3+qplISUUNpiJKUen2M0bT8vSOp0FLiCKV8y/kK8fEEawlWoqPSXMuZQLA
WZ6AXwAuNI+CERuuY7QIGkSKZnmLq6qsHk9de+3D9jrs+zd4DXyVOGSDpywiJZrxCAkP16vjd7bW4t
JiSiFewpORlKlp9mUF/lZFty3sDWUZIVhbml2aj4a55KP9RKsYjiLVEJOKrrRuObDYb8c8nmh/Mzml
YWydstQkGIjTaxWUmXV5QFAZrLCpExHFEpFO2tvsUhSUfZBRZjnEe4z3WOIwpyEwgN5aCgKXcFRYYM
nIysp2Tp4+lXm9+IU1rdLa2GZ+eKjV41aPyQZWOmsN2c7cL1hCccq5k95qMtQsX/tNLzz3Nvett6kp
hsgxX5CRpwtLWOgtbK/SmRljudTi+bZm/7Tp++EM//UN3v/ENX9Kt0UtpQOHybCKNJBaU7GF3yftly
C0NovTlFFoRx5q4FiNUILcDnC/3YrUkRkVx5e1XHjKqaj3V8H/sPThPolKwDqcVSmuGQWvxbJ1xsfe
Lzvhs7eTCn/UurjPo9kikRkW63I0pRW4zdBpXyU4KIwIukiSR+k8qkn8t1NB24pK4tZQeVc/WCIgkU
qQYK9nu9Dl/6hwLR0/x2Fe+Nr292fs//cD/VEKdWNXASaxzyDQhrY8SD3rkgz4+BKJ6Sk3rcp8nNQ2
tkMGhnCSSksiXgiMTFCE3YApMM8F5QzfLwDkSrTA6pjU3w6HbbqTxqvu/wp49n2Zs8nFURBtJLmsMg
AwYt0NEvjrMhC9HJkLl0you8cu9vDT4+Uuo8PB7v2ypLIBkSBj8R+h7tpLaaGS5wwiyMrJN8LJZWGE
f5oqZh5uzN75FLV38+Y1jJ1+zeezlmlvZQFnLjc+9TKgn9Gopg7SgW7Nli+kFsTF4Z1CFoDaIKPrQR
9KNIja0YxtHMThJYQu8gjxWbHjDVihoY2hbT88DkSLoJt88efJvLvzHT37lvte+5aH7X/PGvzp0+Kp
8vtVlz8wkcSoIhUV4Vy5dhMLLCEO1yxMgXcn9C+dO/cLZR/72ttb6ecZWF2jUWyxsroGucS5zbMcTL
DTrHF/vcizXTF5zAz/y0z/33vvf8q4vqZExXCX2UwGyaGvHvzoiQdIsB/WozJgsDXAtEo0mRRpPLUh
qaZ+QrNLoDEh7OSNyjCLvEEdj9PQMfRGTJgEhsqExYKW6jKpTNxqGV5QAVxWmOYTDPZBMpMzcePWXO
iq8d00Uf2ysw8cFdRlKoKJf0GKblhwtV0kOokaDYiNHNPPbOHzgF5D8hiJAQ4Hw9Is+cT3FESjI6Xe
atDsZy+sXWVg8x8mTJ/Y8//RTP3r06ed+cv302VvrxnPt9F4iI8m2+sQqoqU0jWCo5X0W4i5JBKMom
jhaARpB0rSCNJLk3hBisMrhKBDOoPBEKhBLyfb2RWwcYeoRvVYTuX+e5jVX9mq33Pz3+vqbPuXHx/7
WqKhSbSpqQtCoDhGFKPMy2C06lyXK+r3qRf4vMFDa6VLFrnt3F7qjdETUbH0t3au641H68716892Lz
x9j6cwZzMwoubAYEZAioHND0R1grCcScRkSqSV5bOnnnn5e0CsyBtaSFzmFMRgcJihyZxmYnH7IyHA
4IIkkPevwto/JnHrumWfesd3z71i+uMGhw1f9j/Hx+KGD++a+fOXB/b0D81PMTo6iRelPGyqvWudKe
RpIWNsYefnFF//D+sJ5+hubbNqCXtZjzfTxhSFHs4Vkqb3Kqhuga01e++YHP3rXfXd+sTGSoqLyFho
iH4KkojL4Sox8qW+RogJMqmyHshFO0aqGVnW0Aik3gT4+DEpARTmCLzA2J/aq8k8Rl+CWoC/np6piV
2P03byeNIWrrrrqiyNxMrf88unf3G63CTpCpTUIhl6vQKkC4wP9Isd3+6XaIW+xZ6z5Hxhp/Gdq8fa
QvSDjBlvdAaub6ywuLXHieMHyysWD5y8svGd9a/0nep3t6zeWl1lv9+j0DY2ojgoRtaRGXIuoW0Ejx
DRkgio0iS/1mlJ6nHRkyNLzpdreogQhlLxMjUTrGOkNWEtuDIyM0LcFPQSN6Wmuvvte5m6/9a+Yn/t
tRka/7aXaSdQQQlUd4P+85eA/S/Hp6mOo4QS9y/lYiHLnEfB4pQtZq32TvfPfbDQbbzicpv9GjzZfe
/7JbzUGnQF+UFCTklrQKKvKwBEV2BoMMGi60tKWBd1gyK2HrJwdCxlwXhC0xIlAESwZbgd2zm354IW
U6KRGXKvTrNeQItDe2HjT8RX1piePr1DXz39j79TIQ1cfPvClwwfm2wcO7GPPngamKjypyiX70umzH
3vsG98cW3jpGHZ7i0VnYFDQVeC8xUURG3nBBdel0Jrr7rrx9970L/6PTx268RqsKOU2oZp7yvarhqx
sisSQWLor7EUKv0OGEL7S/YUU6RsoL4hTQ5wURFFGnEJaEyhtCcEipdgxtRVVyAjD2WPn5MyGE8nO6
R6ErhJgS5g8GZHM7pn+lOm1j6yY/k9ngwzXGyB8YIYWg1xQGMtmv8fWoMfmYJuQRiy018bueu39H5M
y+fjK6hZbvYyVrU1OnllgYWn56jPnzr63Z/a+N7f5VYiI2vh+0pEcHxLWVzp4sYV1EYVVJHGd0Vqdt
O9peEVLJtSKiHEUUkoSytnRKUmmAjJSeFmyFIQrXQucKhOelCj3N0EIVqRk7MBBZg7u783fcN3fNW6
/7dfZv/fv0XGJhleO38Ojr5Ix7hAIwvez+Ia2eWJ3XJO4JMUJDHeDpd1eIj2Mth6OrrtmcMWe2c7Ku
P/RlTMLbJ04i11t0xhYdAaiACMKullOHjm2hWdbFPQpysAOa4itwWqBEVCIQIEnrzxUdtmrVCOcwAw
GeBIatYTZiQlGxiZoNG8g67Zpry0/cGqh88D62qnfP3ps6bHx8RN/MDU9/t8OHZhbG2ulzI/UaYZB4
4knX/jX33z8SczqBZQ15L5yP9MxwQvyvMfi5hbLwJ6r9j/31h/7oQ9dcdMRgixDtSQO43IiNEpopCj
DkeXueLBdaLMSnhBM1S4ObQk1wkUEG5PGhiQ2aF2QJFCvS5IIlHAVxStUFILSRPiyutu13S7/G7cjB
g4IvBDoWIGFuBWz79DeDwlv7l04fuamTq9PGicsbbYRGx16eY/17gar3XWWtlbp+Iz0+Cgn2yv/ujU
986tnL6z22n17w3Zm/+X6eu/HVVI/UJgR6hP7acjS38X5jPXVRVa3umxs9xg4S4ak188IqaKW1onzD
JV7oqDRSjMWRdX2WiGjCBJJUIJcljtQiox6JEmiMhOjbzJcsIhIoiKNP7CHvXfewewdd36Z/Xs/Q6v
xHYQEF7BSlmLNIeGimv3F7iFdfB+Lb+hfuds0dvcH8jtlGRG0xOOQRVFQTx4hnXlk5g33f7Z2auFjS
XP0dZtPH20Mzq2QVC+OwxOkJJeBgXP0Q0HXZaXhrTHYYMgU9KyhXxT0RCDDVlkJ5YLZhdLuQMcxuSm
t17c3N9jaWKeWJAzyjEbSojVVQ9oBSgac7d+ztNS559z51d959PGnnhodrf3heE3/Pw1RvPelxx9tP
XdqCd3v4vMes2mEzQtGR0fBCzpZn5XMMLVnmrvf9taPvPrtb/PJ1Dg9a9C6thPWqVS0wzIqCfbye/T
yHsiro6sA4urULW/NcoYboJRBi6LM5o1A6aFr9CvM/sTlXqdlJTZ3LZJ8dXQNvU9D5b8dEFFEPFb3j
dGxj3gd/e1WzyB7jni9YHvQYWVzhdXeKhuDLdYGm3RdhktiXri42Jrad7C72S2WonR8fmRkDp1OMju
zD9Bs2IQ8H9DpbLK5scy5c8c5f+YUnc4WUsB2aLM90BRhCpHUEap0IsidIE4EDSJcGHrrSNAR6IBxh
pAbkgBaxeg4wYaCbihwUUx9coT65Hj30Nvf8HezV13xa+w/8E3SuFy1VWwuVBXeMgyX8t+DhKK+j8W
3U/yvFJuKS21pDpgqe7VAIGOBkIZISKxoPdI4fMUv7Ze1drM2+p6t5gn6Z5cYrKzR6/UYCInxUBSGL
DfkpsA7h8XgsPSFpBMK+nj6oQwo2Z3EQ+U5Yge9yrouZmnxHNZ4Zmb2MDmT4MfGaTVToliSpglWxRi
ZYAK0B93b2oPt207b/qdD1qHbCfjpq+i2N+isr9KxA7quoNUuVzCZtwShefX9D37mwR/8sa+N7jlAo
cvtaJlcDtFw82ov6QEvfWK96/AqsccgKsRZlsigji1RYlGJQyJIdFQaIklLEmuSeOguuptZcinJ1Q+
PAOHB65KzuSNZlEBR2dh7HA6PR3uHiGvM7N/7tX7PfGZpZfPDLzz7EubiKpvtTTb7m+TC4FIQTU1ja
hLVbFAfn6Q2MY5qRfON5gyNxgzOxOSZZ21thbX2NlvtDdbWl9jcWmZtbQGzdgGybXyw1HTM+HyT+nR
CcI4iLlCRwQoFqSh9aaTYSRKVPiBdifIGF0jjlBAEnTxnIC22VWfk4BwHbr6G+cMH/zS+587foTXyF
FqXaySlsKoE2iSXi6hF+F+XCPhPKr5hVK8YBi76sLN/kG4YKlruV4oqxDIiQmpVtYdNI0cbj6ZXjz4
6Pzb72dG5/f924cnnX7f6zPPNjYXzmFDuzYrc43JbriUEmEgw8NDH0cfRw5GhyAjlMlqU/J7Z+Wmmp
ma+luXm9ReX1xlkjvbmKu2NDc6efpnxkQ5jI03Gx8eZnZ1lZn6OWrNBiGNarRbpSJPcW/J8QNZtMzq
1h/1X3sz6hUV67S3WF49iLq6w5gy2yHFopqenOodvv+8TM1deR89FeClLVkxF89A7ySRcXmhi11ch2
GmgQ3XzhaEZr+4TdB90j0jFNGp10jhBS0sUlfYFWqvv8V0NjW5LHqPE4UPzslM0EHHJe82WDasOl1y
jmoL6RPSJQnXff271ROv0C89TeEfaqtGaHqMxOUJrZoKxuRnikRGCroFISVyMtbC+tkKv41ld2uT8+
UWK7jprG6usbyxBvlUC+DXB7IEx5qcmeM2tt27ftO+K/3cklw8tPXPi79r99rJ2zA7jybJQtsZKCax
z+J5BKkEsA4oIGSS5s7hEE81NM3vtoe78bdd+ffbGa36N+Zl/IB2BuHzeXmg8ijx4nCvpj1oMxyouy
6T436L4dkaUncK7/Ea0hSOOy+bUIHDBVQi3onCGhqpRmAKlJGrf3kfrU1P/cWZsdK072nx/fOocRx9
7EhEGBDK8E1gvKKSgB/S1p+ctfSwZkOPISk/qHSLrvgP7/9t7fuzHf+Tw4StrR186+S+OHT/9/nNnl
968cH5ZdvsZ7c4ZNhdzTp+D1tg4k1Oz1OojpCPjjE5PMTY9h0wSarUacdKildRIhMDbGlNTMHNoP4s
LZ9lYW6O3vYG1GeP7Z3916vDVGzZOMdUtF1fPKSkRd0zXEzVk1eyZCnSRpXJiZzCLKwv24T7SIvFYB
tjQQdJDSkkUxWitKUUHsiS+7xC69I7RbbjMkLFSk1f/qRue7jvDYIwkJs8z4qj0R+22l1i6cI7jx17
ceHnp8V/rydO/NH/jDHEtZXJ2htHpKYyUFEJAHJMHgR0UbHc7FLlgdWmT5cU18oFje6PL+vomorOMk
I6JkRozh+bZe2CaK686sH7zLdf92ZGrDj90xdz8tw7vu4LNl07z1e1ttpeWvyGK8MMiSKy0ZMZQRxA
FhcsNIc9K4XMSQSzpmRw/EtPYO83+O2+0h+679b9G1x3+HKO1p0vLCE0QEuMcQVc5vUIi9K6iC7u44
GL3QfXPh7jof2rTGYZxwzJclmwqBNQjtQN+yF18NUnZi3vjUaqBkx6LtKKePDF2+60fODI7/18G55b
+7WbhH1x8+oVmZ6tLxwuM1Kxsr+EixcBZOi6jR2VgFMr1glQRloAQnkMHr3jkne/6ASbGJgevfeDBP
+l2sz85dux0dPr0ubedOHnq/U8ce+btx4+fiBbPLrHR6bDRuQjGQ22E1vgUoxMztFqjjI9PMDM1C3G
d7cJS03UipQlxwTWTY1xcvoB3BUoYrMkOfv2Rb9x2eunUUzfeeB1HrrmKvXvmqKsEbwzBOKJmCs4Tc
JgwQAWPFgkylETzAMgoYmAlKI0SUVkMpoOQEuMKmmkEQmHMAKUkWkOcSGr1qPRWHapFUHgPWpdB1LJ
KRaJ66XYsDytrA1kRkK0JBOdpdzdZWDzOiy8+rk+eePat65vn3+9s/917r4EknmNkbIxac4yB8XQ6A
wqnybqWzfYaKxc3ubC4ysZam/Zmu7QkGBSopIbLB0zXNVdecxW33HLD8m133vQnt9554x8evmr/d5o
jdSIt0dUYOj45xp5985xLjj4SJ+6H6yHFDzxWBApnsXlGZD31OCGSgqCgiBWmmbLntmt7+++8/m/nb
7vuVzly+FtEYIUlyARdcUu0luyW2Yldxk2XuSMKf8lWAtBCfz+LT0OZsBwAACAASURBVO4C6OR3X8k
Vy0eLS9KKy0pXVU7TSPLq98tljJyb+VYtTj/xwI//yPIL84984JmH/0Ff+PZ36Pc6yKRGUJCZHoUKZ
Uiq8NhwSQ3lQ+nVUavVnoiiiFotIY5rjI6NMT42YW699dYvb21tf/l1qyfEyydPv/npp154/wsvHH3
nyRPnaqvLq9Bfp2N7dJZPQdqg0RhhrDVGo9ZgtD7C9OQMzVqTYiynNdJgZn6MRiPFu5yLFxc+uLm98
sH8+MbaqZef+dMn5qb/4ODeuUdvue56rjl8iInREZAZOEvh4lICJFRJYneXoGxvIdEjFH6AcwKtU6Q
MxFGLOB1FiII0rSNVjoo0JbuvVHsMD0Yty1iXIcteCHBWY51ExhBH2U6RImUVVhLobm+y3d7g1Omj6
cLiyXecWzj2gazYeHNaD+rA5BhC1ksdpWtQmIIts06/71la22Zpqc3S8hbrGz02ltfRSQOfG+j10El
C1AwcuXqe+bm5hfvvvvu/XnPN1V+45rorn5+fn2Z0cgQdicpzRV6SBkQNmvVxmvHIE9guFBKdg0sCk
VQI4bG2oGMLRCTQtQQ50eSmN93P3juv+0Lj0PxnmRp5lnjIolQ77BO5SyrmX7ETF2E3HdrvYMPhu0j
S36dVw3fZSO/OFReXO36JV0C0QVyea7BjixIlPp6dfrIxOf3B21utz4/tm/93anz0nc889i3a5xdLG
7gKXDGVM/LQor1UYghirZnfu+epVqtFHMc7XLE4UdSbMSOjNSbm6uGuG2/56psfeP1XT718nmeff+n
BZ5958f3PPPfsu86cOTOy3RlAb5teb4neWrn3iZMmzeYIWseM7m0wOTnJ2HiLOJqjXo+ZnEgBSz2RU
4TiQ93txQ+9uH6qvXr++S+9MD350L75mW9cd/XVzMzMYNIDpPX6DkkhVEz44QtgHChZYyj+Fq5OsC0
a0Tyx6BPEFkJb0toE9foqOkqRsgyNNDsuARWNbXgQStCilL04u47SCikdLu+ytrXC8vK55vnFUz+wt
r70gU5n6w29bItaU7N/dpLmSIPBYMDqxjqD7ja9osfLp86yeH6N7e2C9dWM9Y2MPJMEp6BnsEWAIie
txdx5+w0vH7n6ii/ed++df3TjTTccn5o7zOzMVBnuWSVeWG8qdU5StpBCQZQwPbqXqdbsU73gifqO2
GhMVAJDSil8GmGFIY8CphbwNcc9Nx2mcfdNn2a0dtxgCaJE5/WuOOxKo11BguzkMu20mrtjsnc17+H
7XXy73S3DK6/of6QAd/9V+HKBLQQkHpy85MNTAF4GWlfs/9at81Mfj0brt6/3t/adv7hE3s/QaBxmJ
+bYV6o77yAIQZrUj05MTPWVkJVdXUnKds6XangEYyKFNGJyb4srpvdy1/W3fX3xgaWvv/jSS5w8ffy
+xx9/5H3PvPD0BxeXzmNMBh4Ku83G5jIIRS+vsbVcZ2SsxfbqNKNjLWq1mPGJBs36CM36CIn2mKw76
oreB86eu/CBhQXbu7D0/F/MTE19ft+1b/ofY2MjjLeaxLpGpMZRjO1wu6X3BEcVTVbmkrh+naLXoL2
+jXAdlhZ7LC4atrZAKEGeS3xQpFGCD+Hy5z/EzN2AYDJULZB1lllcOjW2sPDSD62tnXp/P1u93/suQ
lqmZmtMyZg4aaCUZqvdZXFxk6XlLfqDghdefpGzZ5dYXytv6iIHBiXpWuk6KkkYa7U4dPB6Xv/gA2u
ve/C+qw7u38P8/DSjo02sGi3hpgB5btBaInVSuh8gLr2UacTY2Axjo9N9o7eOCt87EoVSHeO9x0ooE
uhJWHV9VrbX6YQVbgldZurymiA5bquSqg13qu5SjyleEYR2ufHoP3bdhO/zzRfkZWyl3Q57Qrxi9fA
9UCJZ/fIYiHfxTi1gfcmxyhWkrfTZycP7fj2ZGvm/iygwoKBGhA/msotWUjLbhZDU6/WjY2Nj5e0aP
EKVLIgkKsvbq5I9P0w3kQHGR2PGxw9y7aGD9Af3PnL3rdc883v/5Xc++HebC2wYhxXVHR2AOCZb79B
fg/5GnfbKMkktpjnaYHZ6nK2pcQ7sn2ZyrEE9UaSNFm5E0h+0G2tbF378/PLJH3/66GI+PTP+36++8
tDnrzx09Vdnpw5aFfcp7QgCWmsICmvqmFxRdGFrpWD9fM75hSWeV4ssnF3h9Ol1Tp2FsdU2Dz/83Pv
m5q//g9vvugPnHPVGRc4OWVV8A5xbY9Dbmt5eXfvhxYVT7zt16vm7tzrnSZOc0TFNrS6QKqI/6OGCo
b9tWN/YZPFCxulTm7x8ZoWVi1t0Bz0626Wdu1YQm7KbSVSCkopmrcnYSJMH7r2Hn/5X75u64urDDXz
RQ4nyMCuFHThf2l8oLXa+/1C9R7p6O3WrTjrSgISjVtojTnu8lmTK03OG9aLNUrbF6d4qS7ZLv6l5V
96lr/wVEo+uIt7kUB1+WZHJaq96qcFUwxMwfPeF879F23k5ZeLy61hcsur/7gV89fdoqKOrwiSrC6k
0862gOOMNuXf0XX5gc7DNZtEruZvSs5u5WAbUKowrJTfNZvPE3Mxs+QIPBY/Bl0bTrtzkxPjSrirVl
z6jgyiF0doYN191xR2TiSYtchpF1Rqb8uVI8AgfkWOwnQFbnRyLI04jVhcuMjZWZ3VxhumpJiMjmun
JJhNTNUbHRhmbaJQyKhuSbLD87hPHTr373KlH3MTI7Ffn5654aP+Bq/5ydn5PHpxCqEl0JBlsxZw7u
f6+Yy+8+InzL69z8WKPMxcdFy4Etjuj+HyEtYuCL/3pNx5aXOp+4i1vPfWJt7ztwT+opSCUJ7BJ0W3
vLfLVH93YPPuT2+2Lt1y4eA5vc0bHDXv2TVNLFcFl9Lpdup0+vU5gfX2b4ycv8sKLy5xbyNnahn4Gh
amCeT3UY0FCSpABrWLiuNRopxq6G+t0NjcIzmOy4o4gwzdiFaMjTSgMMopKBLwM5qms7cMO8dsIqEV
gmwI/IrBNfyKvDcBAB4P1sFJsc3Z7hVOdiyzQZgDEssF6dxN8OCC8Q8uojKCuXjkpL38fPfKy1zl8r
/ui2qSpf+aNwz+t+Pylt19cdiL4S9zd6id38+GGp4by5pJLkKgwJlFZaAuB84ZUlgLefNDbu97eoJA
Op6BT6XEqDyakkAQpwXmEkNRqjTPNZhMlSoUxIlSaMkmky3jHPvmO7AjKYEYtS8UB3rG6sHDT4OI6z
aK0LweQKiV3noYcxU02Wd/cQKYpmTVsFz18rtjM+mytdVk4tcT4WDkH7t0/xtyeUabnxzh81X4mJkd
I9AqtCVcJiQfKmrNvP39h6e0Xlr4DSv3Nddff9tDE+OEvx/qK7qmj+W8//a1zH37hmaOcO32WfrfN4
oVxCFOMt2qMjyiMz1nfXOSr/9/Dh86eO/VQWnd33HTT4U/t2TPynnyw8hPd7YXrev8/e28eZFl213d
+zna3t+XLvaqylt6rW71Uq1d1awGEBwxjjywghmHMIDuMgcByGBs8eBx2yGMTMTM2HhxjkOzANjMsM
RgBZgsQGgNSIwn13tXd1VXVtee+v/fyrffec878ce/LzKpuCUd4PN0KkREvKpeot9x7fuf8lu8yWKL
bXWTQ32VqtpSKFwEuy2ltt1hd3GJ9tUOv63j55cv0hpJW27K5k7HdglEOKjBMNCocCef+OE3T9wdGE
5mALB0yGgwZjQaMRiPae216bsTlSxdZW17h6InjD0Rx5fPjMsHIHGx+SD2ghCOoAmMzAtCOWEhs3eG
aYCfsteFOn7yfsdTrs5cPWOu3WU53WKdLD8g1BFqxurQMg/SYiRQm8IxGGSqMsLqENLiDscHbnWbqM
IjkluRTinfLyecPg+VvPr4p0RWHc+rxB1V5IYJUtENLJUc7jqjCghmpIE3Za7fmBqM+1WaNkRG0W32
w5aknCx0RJwrOthCCIAiWwjBESllAj3A4Z0u2uEdqTZe05FJ5BJ5QF0aYWPC7exgv7mlGFU5OzpLuD
Rn2U4QvEBAVl7CRS7Q3NKqTv6LC8H8cefs9Toq/vNtpnR72O0hl6e7t0dpJ2d7pcOkaRBU4crxOc6r
BfSeGLCxMc+zoJNVKiJYBAkGajuin+TdfvvLcN19XN8gHF7l6znLp9T1uXFpjdWmJne01dtNTzM0cp
RrXccozOVNlPj3O5evPcf3aDf7X/+1/+fif+3OPfvz9T72HxoRDqxZJPGB6VhKGEwzyFbrtAZubfTZ
X+yxe3uXSG1tcuQQ7m5Bn0NqDYQZBBWanZ5icnfuPR46f+Ln5o0f+wx3Jfd2rVy//++Wlxe/a3d6i3
RthhynSe2Kj6Q9HVGSITUfs7e1hrb/HAcMyTd0PPJsVR5E0Bal2DJaAEhdbKPlTBVdjKYtysnzE6uo
2W3mbFbbZJScTGieL589bHXa3ttGOuUiWGFDn9/VUUqB2iAT7pzZRbmkminca24l565Por0JcuhV3M
QhLzRLvUGMjEqVASJwQ5ELhbYFXbLf3pqYDhYwcw05BXbniCkJ4Xzr6mcPbLg0KNbOqyNddGLBrYoL
CewiZF7o6Vhe7amwDjBKFjK/N8dLhhGIoc3zg2N1Zv23OpcwkhnDQxgQZg1GfAZJBugdpyAX6zB+7/
eX7v+cjVzdC9RO91P7E6sVrxzbPX/3u/vrm965vrD60trfJVs+BNYgduL6UEqs2F051OHHMc9eddU4
en2J2JmKmCRNVmG5W6bfg9bNXWFpc5Nqi4/zlHa5vbrLSWgfbh6CBVnWkrDNXn6GuYDKZZP7Ox9ncW
eXcyy/xu5tfpOL2+IvfcTuzM22E7ZD3HNuX21zdqXJ9cYerVzdYXGlzY7HP4ir0BmCMIXOG6YVj9vT
xE585fnzh3915x22/ffr03cOTp47RbNQRnYw/+n3xssr4rqgXY7KQCd8kiCzejNgx2+QRjPp7LC/dQ
OX5bcpBRQBZjg+H44ofV64cAcTOEXtLb9CnUp0oHKNVHTVznFbl3PpVUtY3r/J74TJeAVagbIzwAmE
1FZmBcOSjIRutralKs1kIZgRh4RBcME6h9AlRXw2mKfgvhyv7z0W4/Jf8kqJUf7IZWTZq2jxFSAhDi
KpwNC8pJLlHSchGB7iOahRsBao4PeW+QdXhwtnhyjRHlSh+xFjavGjOxHF8LI5jdLVGDU9NaJwvZpF
D59lZ7rGXRzx05sHz3/YX/iL5/DRDB7tLG8ujle2fXH7z0k8u3bg2e+76he+6tr32fVt7rcd2d3fp7
XQYDoe8eQHWl7a4cWWL4wvTHJmvcmQu4MTRCeanpxB5he3tISsrPa5dGbC81KY9SBE+xlRrNJLbmGr
OUw/qxIkhCD2GiDCcxVrDyaOW9uASb15a49q1GsNhl531RVavbLJ6o8XrK0O2tmBzq7CH9wLmZivMz
N2ZTs+e/J0773rg380fOf67p06dyo8cOcL0VJPGRIUg0IUO6F7GiRM3zu8ud8jbHruXkfY1Uo8YCk8
tqjKSRbMryzKstccO0ypECTR/W6apEERRVBiT5IIgKBoyu7vbW6urS+x0NshVCcn0viQdKxwZ1lncC
IbDIaPRqOkK0We8EwcqUuLds87fkeC7iYh7uC1++O+iFN+xeRWbE0iBiTVS5xjdoO8yonzA0FqGXRj
0YOSgEYh2oosdTpSOemNFMC0sFouUJVMAhRB2H4blhS/k8Kyb0UJidOEJUNUhQmkyGTD04NqSyiCnF
iXXZiencI0ZUiRHGzNU7xb4xx5je3tz4/rm4k8v7Wz+9Hprq7m6vPodS1evf9/26ub7r1z9Mq1Wi5X
ljNXlLaJgi4k6LByBhSMzVKMpdtYkmxsxi4tDNlspQyRBOMVko0mzcpJGtU4sFFoWAsJOCjRVjA6p1
yTrO2u8dnaNuN6iVt1me7XD5jK0N2AYFUSA6emIqdnj/WPH7/7NE6fu/3cnTp7+7NTMgp87cpx6Y4p
ms0kYjMm++T5KRmQB1Wr1mkDhnCP1tpDmS0f0bI8hPfbsCD/ssbi4yNbuzkxSqyKDoEAU7LfLvkKmp
DXWOryXBKEmy4esbyy31zaW8GRUwyJzFbYAxAkh8V6TYbES8mxEno2qztqbrMtK3fp3TQC+K08+50G
4IiMXzsZ4i5aeJNAEypJoqEpNQkiGI69Z0m7Ods9T07ZXlQ5TMun0GB3si7mOOkS88RSuQXCzB7tWq
hFHAZVanQmhqMqCIJypEO0gPtKg09ZMJNU17Rx9NySXIYFUBRXMx8wmC0ydmOdeMoY22+22Oz+7sbz
+s1sra9XV1T//keXl5b9y9erVb1peucH29iK9vRXevJJz9compJuQV9BygV43AKoYAiJVoxbNUw2bR
CpAuCHWZmQ+I88dLhe0O46dHY+zk+zs7PLFL95ASks1grn6BCdOzTBzx5H23Nz8rx+/7c6fO3Hizs/
NHb2N5vQxKtVJtEkwYbzfKMvzDOsytCzk1kubNpKkumbxpM4zSlMyl+N8TppldO2AvWwAuWZzc5PRa
NQQquzOGQ0+Rwh1kx/iPhrDg3dF098EApdBng4Y9Ns9QUoFqGpIbSFhIRghUUhVQOl8AMpbJC4uOuk
HXvE36df/WfB9hZOxBB3afEQ2Ghg7GqCcxUhPJBXOD4gDRSg8TkJQiRANw+pOj4nAp5HICEgLFAxmn
04gfCFbsd8A8qWr7FjcxxX/uiyPA22oV6rUECSZxXmJMSFGSAZ9x0Slxky10ZImIpGmWAAcKBQLrVB
SFKYdQcRE0uDo1FHS2/vd0YBf6PeHv7C1sx2tr6/+hc3tpb+ysvbmt1y99LpcWrzGm69fZXsrx7k9Y
JaECXTSIKomJGqSSmSItMDnpYU2MEhH9PYGbG0N2On0cDJmonqS6ckppudy7r3rju37Tz/66bmpkz8
3vTD9J41Gg8bENFG1igkSZBABhsz5cfe/uHraoPCF0psohG+F0CSVWguhyF2hJGfTEdYPGdi0ICS5o
tHVardJ0zQ+cK+9qZ94SxOvtChwbv9zCeGJEkVzKkk7kyF6NKIZF6OIXIIvx1VeOLwez3EzvHVGlCO
C/fGC//+4Xfk1nXaOZxH+rQ0ai8NmKaNhT9pRH+1yYiWIPQhbOBNpmeEE1KOAOIiQ1jKZKBeSgstQt
wJgvS3HDmX24YoxhBcl87vEYgkhVKACwiBA9wdQWn0hLFIWEnXGC5T1Q/ojbGSQiS4oVN4ThuqQXY/
EOYdRGm0UQSOgWoEpBcdPzg/7w/f8Sub6v9If7OqVlWvftnzj+sf++A+/8Jd+97c+z5Vr24QIavUqj
eYcYaVKGCdEwQCtDHme461gaHP2eh3ae3tsd9qMrMd7S6N5nA9+8CGeeOruR267febFo3OzNBuTiKC
+Lw6MAGc9zolCeFkKsnLxj2FXGlkqr/nSqVUQBNEwy3L6o5R2v0uWDnB2jx5tEClDn0FqabVaDNORy
qxHK4/NHVp/FWUhIZFS7KujC5EzMVHlxPFZN1iu0VkfMV0R+FDhrMbnisw6BvmQkacAROQp3qbS2xz
MAbZYiP8fuihfC8H31nDztzRdCtGhUEoXBkbFpjBc0i4nMuBkhpQeHUqaMWjl6RpHM1JSZanFu0ODf
nnAxBjvu4eEcguq3QEQdao5aZuNCV3Pc+JhirICm4MzEVZqajM1er1dEl1IjRlbbCR5eYNH1hXS8hQ
2yNJLcMVJJXJ3MGKRECYQqYTqRJLPzE3/5ul73/ObSdxMX33tqlld3aOWxDRqMfVaQlSto1WEFKsIn
2BTT5p5+r09dtsb9Ifb9OwODk1gakxOz/PQg9+Yvu+pR16caAKqg9AO0gLQ7csY8FIU7lilvfOYh+i
xBZy4hFspoUrfdUUQhIVIrfeFdLzR5EIXU4Ryqi100XARQlhT8ueULtJODgHy3a1dx3JDdi5HkhMGj
lpDy0bDwBBy5fHCgpQ4KRiMUpwvMhohi9peFrnrLeNpf8tI/es47RRv94PwJfzOEQQBSSXKGpVE6Sz
ADPv4HMIIrPAYA9XEUEs0djQicBmR8oH0+WAfn7evfFtKoXAg8SZ8aYBZOhX5EvVtgnCgg7AmS/dcJ
TU6NIggJpUa1/fY1EKaR1j6lIZjY0NItY9qtkUjXch97wSMBF22GIVCCkXmLLm1COmI4oTmdHM5jM2
pSlUzORkTKAkiQ3pXdGj9XuE/kEuGfUervUer0yL1O+Rsk+NoVCJmZhs0J2dX4rhgdWXCIRgVkhPuQ
CO4PKCLsYsYa74ckspDgvM4Uaa5qSfPXNQbjhilOTkCYwKE0Phc7s/UpPeMRiPSNB1kuUUbhfPuEMD
hoATz4mBDtNYihCqV8SxZ3sfZXhAmOdNTAm8F3ilsLsjSgiAsFEQKbChLIxmZqbdTzxbvnrNPviOv6
r9CoScL9rtzrqjHrCXQauBdTiUMMEpST1Thg+EhCQXKpTRCzWQlYrZZZbZRqwibg1TkWRmA5UnjRKH
FaG0ZeGIs++1w3iGEAiXxUrTjSo3cK4TUmDCiWmugg4ikUsO6Yh6mvZqgnxap5bDQUyn454VXRKG/6
Q+5Ro5Bghn4FOdHeDKkLNgYRhZ2zWEcvrBwfBbr+vT7WzQahuZETCVJUELjc0E6yun19mh1dukN+gz
SId2sS8aQZjPg+Kk6tYZAB/aFKC5eV8kAhy9ItJKbFJcFoJVEF0rB+9A959x+MEipca6QpVhdXptIR
zn9NGOYpfSyEb10yJCUgS2A74M0p1avoLVuj2u+fIxsGm9+4hbWi/cHgectUnlq1Yjp6WplomEwxpM
YT6QzarEj0hnVGOamJBM1qFc0jVqMkG5QKKEfBLgUEv8uOvnekeAT4qvnoUoqhJLk3uGc6zqXY7O8u
BkelBKEBiItCRWE0hIrT6QELssaNktvfmI/dlySeGThOckBYxlf/L7gBSp0EG4KrZEmIEhqqCBBhTG
mUiv+jWOQimFvME+vD6lHe3lI23Gs1ywOlK+4BeNa8ujEWOChtEpz1nH82MJvve99j3Dq1CzIPrnbw
+YDbJrS2W2TD0N63ZxWe5et1jrbvQ32GGBRGJmwsHCM6ZmYkycjji8Ev4UowCSisI3cP/GKE2osoJT
DIaMAX/oXCiEK3Ut54P6Rjzzd7mA+yyzWwcg6Bnla2qod2EEbCXEYoaXaPLj3f4r+ni/YKO6QlqLSj
iD0jSSBWg2qMVQDSEJHNYZaFep1zUTD0GzEVBJDGOiuKY++cfA53l1f8p16UfW2AG2/D/cRJTYzDMP
dMAyRCoxUKAmqtKsKjcEoMMITKQiFJe3vTbs0KyDzohjmukMXP983Az1UCYiCjmRlaQRpgmVfmANgk
mrhU65DVJQgggpBtYpUIb3e4BS7e+Vr6QMW9L7dZqnjViLn3RhLno/tV1RZcxaSgqE0GKWpJcH/ee/
dJzdPnprC21263XWs7xIYTxgG5KMq3U5Gp9ein25jGaAJiMUkE/UjTDdnmJk0LCxI5uaHn1a6j6eHw
CCo4USGF7cGXAHBE5Spsh+feGJfmGlcRWWDjN3N3VODQeGjMXIZgzzDygJDK8vucagVlUoFpdTy+Jo
L+dWXnBfjgU+JzZWFGUwSi+l6TVFvQC1RVCqCJIZKpQi+Rl1Tr2uqNUO9GpGEwS5S3hTo/yWEb7/ma
j75dk0XX8jcHZ63KW2o1+vbExMTyLRFYAO0A2MkJlZEgUD5jFB6QiGpGEVn1J8bDfrgCgHew3g8dQg
Tvs9WFjdnw1ZIZBhfVXEFGUUYHRU6MmhMWMU5j6poVNJilNnTg96AOBf7SF0v3Fvhup6SWSHJAenDf
VrW2BNCjmXbsUg/JFDDmePHEs4GHW4svki7NWSyYVFimtZOznZnk/ZgkwEtCvnYKlLH1KoRlcQwN6u
Jky36o3O/VPXZfxMGM0AFn0uUtrfsfGOe9sGpJYXCy4PAs9bjfdFAGg1Strd3Tw/6I1Jryy1mHLqFC
JHNc5RS1Ks1IhNcVWpcFY8Vlt9uEbj9X+43wZ1FSEtg/FycSORIk0rDaMg+CdkpUJEjt4VLUBQbtJH
bX7nB92cNl6+Yerr9FghESWU9jivk0qB1EXxRpIliQxBZAm+JjSIS0EhC+riFbNgDm6O0vAkbWwR9X
uIK2S84itpMlsEHYaV6oT45SbaxjcwsKgebK4hibOrQCVQbEzgdnEmHGXG5Y4jcj12kkftLeXy6Kmz
J5RSl37uzkDtbaIcIifcjhN2j01784V73Oo8+ukCrfTv/z2fPs9u6QKeTUq0cZ9CpszfcwIkO3u/hh
CUOKkw2a9x9ep57Toc8+LChUt1kdfmLfzGJ/Q9X6+ankRW0CN8m4yvO6XF+JoS6CUDsfclHkID09Dt
ddrZ2zwwGRcNFK03qJNZ7LA4jZUGUDgImJyYIw/DCzXxU9zaoSsdbUlPAW4u1GUK6hTAQiAgSYVDag
RdI47ACZCTJRoU6tQkEQrA+Fsa5yar6Jjfir9dRg//KfZiiVyhL8Vu1LJXC+nL2JFTR7NASLSyhURj
h0DhiExBJfyrr7UE+hKBseZdiHbJEuAh/06xhv9O5byITRq82ZmZoL63A3gAVV3ApOB2Q+2JxRY0GA
62fHHQHNEYpuAqoAmCe75/fHJLS8GV9JQ/SYO8Q5GglEMKSDzqMeivvWbzx4r+0bpWHH54jTB5mY2u
RZ7/co9O6xGDUJc+n6bOOEF10YDEG4kgRVTOakzkPnJnjsccrpOkNdttX2N1q/kujJv4oTOLXURM33
XaBKsEGB8FXSLvIg8ATrrB7do4sT1ldWWdna/vJ4XDIcDhEmgDlMvK8tx+xWkOtVmN+fp5qUnl17Mx
0kx/0ftXjbi4DxaHupLd4lyOlO6WNgFAgrcUgC689U5zbBIqRKHC7URSitVweP2nJLHtXdTrfseArU
i3PLcXXWy6Ml4IwjG/EcYVMBwQ+LAwy1Njt1JWdT1v40qmAQKq7RoMejEYQpQU73BYkTbGv+RCpogA
AIABJREFU/hK+5UX3hfUEiEC/0JiaZhAn5L0RYRiRCY9TpkB6KEUQJ3T6g+M7Ozv3zXd655hrFt1ac
3PDYjzu8OVRMtab8SWKR2kQwuLzPq2dRbbXz//aXmeRRn3EKN/C+WV00MPEcM/CJLXkGJ5prq/sEVY
TGtOTTE+eJB8GrCxe5Prys7T27sIyT3MqLwSG2ssI3vy12SPVe4KKw7s5xs7AeHGoDzROMQ+QEM45l
CpSRetS2u1drl+7dt/29u7x4TBlMBghRPG5rHcYrXEuIwoDZianOHbkKNVq9YXieR1Cy1tOO/n262O
M7XUO7x1KiruiUOHSAG0NJvDoIECnKZn3OK0JpcUTUK0mhJG5wf4Gwj64gq/3Od9N2Na3QZqPZTaMC
qhUKleq1SppFKFlisodWhYSgUIUkgtKgHSeQCtCqU7naVrkdM4f+Ao6QLmipym+yuRDgNRhL6rXnw+
TyqNCddHaEErIlEFLCp86IRmMhrR2O9867HbPRbkFLYq/SV92zcvk2XNw/OKRWpT1ngORF/qYnW1WV
678qxtXz949N2epVjwvvPIlXnn1DVp7cPwkfN//8N/z4P0f/kJ/aI699Orzp5zM0mMn71g5ceL+F1Y
Xt5779P/9s5+4ce13o2dfuMLxk6d575nbqdciNtZ2SNOlu6v1o/8qCNUPeDFfSNU73gJq520RWMUFT
NMh7c4ua2tr39rf65JlGWmaQiD3RzZKKWzmMCakXq8zOTn5fBRFPcqxhWYs3aBuOvXcIQsC5zjolZT
mMkqp08YYfKiJCREl+yFNDakrRJVH5HgfkFQiVBheKe2a3irJ8vUcfKmEEIHIS2076UDZ8g0plJcYw
Mkqo2T6YrBwEn/tZaqjPpNpiwSL0Ak2jOk5zcgIKgkEPqeRbZ+WS+cSrl3o89BxkJJeVNzqyIXoVJI
GpVmjUCgUykOMA+eRzuJ9yiBUn8vvvv3RvSCm1e5SywRhmhMNU/biGdAJQS8jbw8/Mrix/s+j40dgr
o7MLanyBCpkLP0yppBpVfyYihYBFYYDB5kkSTTLN85+54U3f/Ov1yfbRJMxV9Y2WVp3PP88rC/Ct//
5v8wHHv/vvvO2k6d/tc0WJ2d2aeo+jfn3kMk72V44TRwOL/3Sp65/evH5F3lhokYQTnDi9pijJx071
5/jytk/+OsPnTn9Wdn8xKeFq+NJCjsyDY52KT9skNSQGLJ8SKwt3o4QvkKNGV54eYXnFrsf2RIJ7Wy
dIMgZDrdIyKkJR3fURaEZpJ6w2WTmtuOfs5FEkBMYRZ5l5Kbg8GknitvuKOaruksuhgyVIaSB0TGZ6
5LLi0kwsXTa9S2IBayyRMZhzAjLHmGWY1QNX2nSiG9n5ugDZLJ20UvPINujYirlri7Ah++aTod8R1/
9K7i+jAtkqSCO44tJkqSBidBBSBAnJElCHFcITIRSCi1VaREsMEqj8A+TDcCm+8+/70ki8v3BrvSH+
y5iv9gXUUJSq362UqsT1yqEcYWwkhAkFUyc4AVESUJjahpp9Ad2O+376PZBCLQxhaTdeLrrfIkNdfv
i3hLFKBuRJAFR4nn5xT8+8ual135+cqrB1NQM7c6Iy5fXef7ZC7R34cyZB3niqff965m56V81kSSKE
oIgwhgDQYCJQyYmAm677bZffeyxx/51pVrn1Vff4E++9CJr67vgAyq1CWwOZ18/9/OrK+ePONoInY1
RbuRekDmNJN6vWMc6OEIZEJLdrS6rq6v39fv9D0hZYFaF89TCGpGJEEJRD+pUq1WOHDnGfQ/cz9Tsz
GeVUiVOU2CMKQcxvrgnkkNqYqqUOlL7521u+1g3elhIhwkNcRLSbNap1RIqlZg4DjGRIUkSqtUqQRy
RJElqguCiQh1o+Yxr2ndR0feOBZ/jLXPwA4/NQ2lCEIVUqrVXTRjhhUIYgw6KoBOiMLwX3hagaTxae
mzafcx2d2DUBj/c/5CeFFRhcy39W4f9Qgi8KNOhKP5MUq+2giRBVyJ0kmAqFVQU44xBVRLiRg2nNOu
t3Y+12i2wviB5HkbtKwFGFWMUMYZshXib41yX5ZVzvHnl2U9nbjtqTlZxVvDa2at88ZlzPPvl4mmef
vrDFx5/4skfaE7VIQSlo2KGOV5MqtCDWji5wJPve/oHzjz02IX19TbPPPM6L750nrX1PaK4Sa0xQ6c
zjG6sPvfpwfAysE2WtwslOVFH+zoQo7wpEC9l17nQuRHcuHGDxcXrHxsNh8Um5cRYtIogCBBCUKvVm
Zqa4vjx4zz00EOtWq32GUqWw1tXQH4YZV8uR40UukTXFGBt5wePKe2JYk1cjWlMVAoScawxYWFZHcY
RSbWCMYYkSV6lvI/ysBOUeFeVfO9M8N0ceG9VvPbe77cegyCgVmu8bOK4sPnwpoRIFfWcQqBK5TMlP
Eo6+r3WU53tVRhsAz0UQwrPpBy0f1uUjUCUQ93SGlZJdBT/uqlUEHGCqMSISgyVCFOt4sMQmSTIJKa
f5z+42+kkfjjEubHmalnMloiCYi0U8zSbeeIoZHn5As8997v/aGSXn5qaMXT6O1y6tMTzz17m7MtF2
frwmQ/x8KNPf3Rmdr5QeZJ5oaGBwjqKBexSnC/QJHfeeTcf+sZv/eip2+5nawv+5EvneOXlK/R7gnp
9nonJOTZ3XnlqY+eVf+TcDYKgC+RID4E05MMD52gAlwtwmvZOl4sXriQrKys/2Nvr0u928d4ThiFKG
YwJqVarVKtVpqdnOXZ8gRMnTvy6EALrCnn6/Xu7P4axRckhDy9Hg9536+1j/R6IwVPaeII4IIwNYQQ
q8CgDKpSoQKEDgwkiTBChTfgy3iORCHeIuCvkn518b2lyeFl66ZTpjjroCUsTUWtOPp/UpsDEZMJgy
+6hlJIwMEShIdKa2BQP8vSDw84WpB2QA7QYIkixpAdpJrdsuuUfhBB4KcAE6Erll4N6nbBeR1Sq5FG
MjRNUNUHEAUGzQW1uFhGEtZ1252+1W3vFmWdBOFHIse/DyYoOqMcirKPf3eHNN1/4wOLyy/9QBy1U0
GNp6Qavnr3E66/32NmG0/few3/1rf/t37jzngfPCRPgpMOKHHyAkmGxoFVhDZX7YkzeaE7zwAOPnXv
6qW/5G82JSV5/zfLl5y5y5foO3b6nUptFBzssLj/3D7d2X/uAEB1gSDYqHKZiU7x/l5fluAjJB5LrV
ze4dOnq39rYWq912x12t3cQOOIwwmY5xhimp6ep1Ko0mhOcPHWKI0eP/vL4RCyCz92y6HJgdJDqeIM
kLIW3MqANooNUow8GgSQIFTpQxXglcJgAwlgT1xJ0FKLCgEq9ThTFz+M91tt9rua7iEP7zgbfPp31r
av/pmGrLzg6VOuNL9eaU4i4RiZD8nIZSykwRhEbXULNCumHJFRz2ajzKKM2uAGSERJHZn3hYeD9/g7
8dpvCPus6jD4TNOrng2YDl0TkUUAWB+QSRBQS1+tUpyZRccz2TufH11bWJ7NuVliiydIkJs/BFZpcu
lQv8S7jueeeSc6ff/bTQdwnqmQMRi02N7d5440lrl8FEygeevCDv3H/g0/+9ERzFq80QhgKGSANsrB
GLi0A8SIvvA6ihOn5Uzz88Ad++s47HvmNzh68/tomr7x8haXVLlo3WVios7NzmVdf/6NPt/YuJLCHG
kvLl5msliCFRiDZ3cp58+LS5OrK5o93u12ydIjEkUQxUVRIvhtjqNSqxHFMc2qKe++99/zMzNxntCl
QB7mzZd13q0qmLaJ9vAK8RHpVBKVrg2s/qtVoLggVJtQIDVKN0JFHBA4dG6JqBWE0XhkmpqaJK7UvI
03RUBPyJnzn133a+Xap55hrJzgAY1pbcLaS2sRLjekju2FtChdWEabAiokyzSx8yMtdVUISB+SjvW+
huwODNti0kJPwGntoxufLhkgxEjiMrhmXH5qgVvs3wUQDWa2QxyGuEiNCg4wCbKBQcUhUrZJntra5s
vGJ9cVV6HPgxVeqtY7TrOFoj6tXXuONc8//Yq+3OTs9WwGRce3aNS5evMHFiyOUgofPfGjz8ce/4Xs
mp+bxSkPpI2cxxYkkA2wxiKOQTSzx+kJD0uT2Ox/iqff/199zzz13bW5uwzN//BovvXiRlfU9tNREs
WJx+cLsl5/9zC9urJ9D6UHB6csOBtM2g34bLl1c49xr1z/RaQ9qaZqSjQbUKgnVOMYoQRzHRElIFEU
0mk3uu+8+Hjjz8L8xUVgO7YtxwbjuEzd12Q7VfmPLMgfCD7D5Ls63v0UqSxBoTBCgAomOHHFFokKJD
DVhNcHpAK80UzNHdnUUv8T+ehIH91r82cnHzR6yb9cFLY02ZdEKM9UGyeTM58PGNCJpIEODCCTSlLo
issAcClU8jFHkw+632+4O9DowZjl4c0id/wBgLTw3nYSWwkfAKtBJ9ElTq+7JaoKoJahGlbhWxSQRO
YJcSiq1Okkck/WGH99d2vimvNWHgTsUyQ68Jx3s0dnZ5oWXPv9Dw3T3IzOzdRqNGp12j5devsBzz2+
wtAS33XYX3/hNf/67Hnn8ff1qfaJkXGhSK7EEKHWAQMHbW8FZ4AOmpk/w1NPf3H//+7/1u5QMeOlsh
z959jyvnL3G8mKHuenjJJHm3Lkvf+SNi1/4oe7wGkL00QE4nwMw7Fk2VoZcPr/yTdcurX2830uxmaO
7t0tgJFp5nLNUa0lhKprEzMzNct/979m7/c47PmmdY5QVxFkp5KG6j30FMz+OOH+wLIQHXA/vWnjX/
XZBgROVRiINhJEkSgwmlOhQEyQJ6BBhYmoTU58vLOkk3vp9ZgnvQqDnO0MpOvzC/nCna7/KL3oVRpB
lKeiA6WMLf2CDCn1ZqES7EuSL8OR5yjAbknkHWhHGAaGR7+vsrN5B3gPlwHqiMCoZE2IfMT+eOxzGE
7r9YTv4QPaIzL8QSYiqxqhaQrVeK+pCDSYJCMOQSlQhRpHu7v3UztKqREjIIB/2S3MKz/rKMl/8/Of
ufePCCz8TRpDUYhZvrPPqq1d5/rk2F87D9DQ8+eQ3/JMPfeM3f26i2SB3GbKkOykV4q0iyyDP80Ntd
I8qxRIRAUiwTrKwcBdPvf/Pfe7+B5/6J87C+Yu7nDu3xPK1nL2OZmZqgUo14MrVl37mued/+17LKsg
Web4L5HR2u3zhj5+XL714/qc67QFbGzsMBiNmmg2UsHibEoWKOA6IooBGo8bc3Bx3n77nX3T7/Z5Si
sAEN3WTnbVFiedFybIo9eUOS5/LDG9b2HzrDmz3fbIo/pFaIQOBI8X6DBMaknoDKw1htc7CiTuJk8Y
foCvgBEoeCMwqJf4s+N6263KLpEPhY1VeKKVBKWRS//1gYhIbVBAmAG0QsgBDS63QUYCMIrxRqEgSV
iTCD7+TwW6B8xS+8PF0tyJa3P57uHXsaAFXQG3+qYyClkxCZBygAo2OA3QcoLRGh5o4jEh0RGDFA6O
d7qdYb0N/hNYG8pyl61d57ewrvPHqq79WaWh0JOgPc65e3eDF56/z5oVC2Pf++x//0mNPPP0Pji4cJ
apEqNLk0LuS/+1LnIy3SO9KnNqYpHUw4tABRLHh9jvv4f0f/PA/uOPOO7/UasHZ167z+tltttYE2kw
yPTtL7tpcX37p164uPotnkzB27O3ucOHCm1y6cOVTm2ubDzgHRsfkuaNRj1HeEgaSiWYVoyXWpcwem
eV973+qNTM/908r1fgQUcnvk1jlTbo64/csbzbWsT2gA77znUKMSsU0jdAKYWyBYAkUXhU247nXoBJ
0Uiepzfz+fiGMRPh3K6fhHePz/SnIcun30ymhdLGz1Zvna3MLr/mkjgwiVBQhTFCkmkajkwqqGkOs0
RVFpaaQYu+7/d4qpK2igD9kqeS/ygU5LHbliu5DR8fBT+g4QEQGHQiCikHFBh9IlNbEcUxiQoyF1ur
G9y++eflvd9c3QSm6ey1efuVFXn311U922runZ+Ynsc5z7doGL7x0lddfg0EfTp48Mnr0sQ98x4NnH
qZar+83J6z3+6lTAQworKIPZmf6kAit3BdFcQLmjy7wwQ99M08++Q3fYQI9unChxzOfv8jLL6+ytWG
pV2eQWrKxdeX0y6/+wSevL72C911efP5P+OIzf/y311dXvr/X77KztclgMKCeNAi0Q4gUE0AlCanWI
hYWjnLmzIM89sSjP1Ft1jtSqQPTSSkPLCmFKIx0PHg/DpJb2s++hXdbCL/73YIRSsgi+JRHBUX9V3R
6NUIF5GicCgmixmsyqZ+HALzaDzzBuzPtfMf4fPJPAb0c7g1nAoKkxsT8wm+b+uX7ZRZjjEGZUiZAC
YgMMg6KeVokiBLBQHXPDPpLH0hGG89QP47wk6W68a2v7/Z3X/E2aBupwXn5z8jU9/hMPGyVRUqFQjN
yOVaUilxKYr2g096jPWz/5MZgd22O7i9d2bjGl5977qOt9vYPHpmfQZic1s6AS1fWuXhhh70unDjV5
Mmnv/l7n3j6g6szc3NF3WVBaUNui8G92Mc95nhXdka8Lh7i0NUt5N+K/6cEx0+c4IPf8OHVa9evfu/
nv/Af//2Fiy2a05cR2vHex26jWm/S6fW4eOmVHxwO/GePza3/2u//zsvfc/7szk9qMcug7+n2d4gCS
Rw16HevUatG1OtVlPYEQch977mbBx564KXaRP2fjSea42iSZeA55woVcSnK2ytKROchfp8c4fMtvF/
/AOye0SItwO5SgnI4leJQCKUJdIC3MQxDEBVUUPttZAzW7F+Tgs3gDwLcf90HnzvYCQ/ZiN1cB/r97
NMKDWFEdXb+16szR35ctCvFridTvHPksjBK1IFChEULWiYjlMhwdvNjjJafwd4GagLBxAHO+u0CkJu
tgsfq2VICyv69nPT3clkYbQohsSOPlQ4lix3e+eJ02lhbZ+X6+V9Mz4nhSnvtC0sbN35hfnaS2kSNl
fWrLC1tc+3qDsvLYLTg/vuf+Nmnn/7GX3nve99LY6IGvrRrLv3UnbcF+MoP8aR4nxUB6kUxHxuTT8d
plixqJ0dGGIa899En2Frf/pWlleWfffHl83/tjfNLCO2ZnJnixG1NZmccmxtv8MrZF3/hmY3X/87rr
+z8zMZSTmymiaMmlaROEifYzBJHiulmjVq9wmg0oN6scccdt3P02OzfQwq8z3He4w+deAV9aoxuyIr
T2hUzVS98ybP04NpYv4n3Gx9DtNAqwypTsBtUjpBDRFZHSYEyMcNhSOYVQVAljCd+vWCsqFv6CYeyn
a93ASXBf8LMRcp93SGLxCpDZWLq2cmjx18L4yZSRXhvEDpEGEOuFM4IZKSQiUVGGWEyQunWX/Xp+hH
SNRAdlBx+hUH/oS5soXhcEoCKh5QSpdRnlFI/JQLwRuCMKCSzAl0Ag73H5ZZBv8/a2hpfevbL/Mbv/
PavvvDaK2smjuLmzDTdQZ8r19c4+8plzr5+jdEA5o/c/uYjj7zv++99z/3UGtUy6Iqgwkmw43nViCj
KQWSF6rPzZVEqbybll4tOiXKIo+DI/DEeefR9PPDg49/fmKq8ub414I0Lq7z6yhKbGylRNMH0zDxRF
MXtdvtnOp0W2zsr7LYXcW4bE6YERhBFCadOHCWKNVk2YGp6gvc+8hAPnLnvp6qTE58Bh5ASIcUBRQl
3wBmEcrCe3fSGiw2lB+zg/fYRz+5fFbKLNjkmKDCaQlukHqCUwUtF7iTD1JJmAh1WX4uixrNj256b7
AfehQP2d0/D5dZUvBSv9YfYlQ6BrtaZXVj45Xp9FmUqeGHQQUgUVwiSCEKFiCUyBEyKruTESY7NNn+
I4SbQRtD9yrZQb2dj7UuJBekJAk0chz8iQ/W8U55cOVSgMUmA1II0T+mXgXf1+jWuL96gN+hTnWgwe
3QeGRqW1ld5881lzl24wd421KameOKJb/joo48/xbFjx0owcY7NC61Qm5VBpASFwdUAIR2erKz5xP4
xvX+9nAPlcQwRWKTWIDVHjhzjQx/8Jt772JmPBqFme6vPSy9f5uyr19jc6DLRmOXY0ROcOnU78/OzR
LECOcCLHsPhDtZlNJtT1KoxlSRkemqCM2ce5EMf+sDzx+6640fQemxyeGiCVwSeFKrIHjzF5xjX9GW
e4clx9HC2g/OtH/K+hZJDjPFEJsAYhTYCFTqkVGXjRuK9wgQJjebML1eqjXK8I99md3V/Fnz7L/q2i
IPy7Vi7/6fxWNYKCWFAY2LyF2vVCQITI5TGmJAwqRBEETowyFAVKhHaQiggBuv7H8+yTgIpvrBe/E8
6mcddxfEJKLQkigOklj/gsLnDg1GYMEBoRZ7n9Ed9NjY3WV1dZZRlHDtxnDvuup24UmG31WJlbY2rV
xdp7WYkzRoPn3n8bz7yyKOvnbztFLWJGqExCFnyFFWZQI0vSz7A00f68UlyCA10eOPQ5QjGF3WhFgp
vLbVqg8cff5InnnjstZmZmb+ZpnDt2hoX3rjO1Wsr5JknjitEUcSxo0eZmm4wGLbYba2R2wFaKwIT0
e12mJyc4MyZMzz5xGP5kbvu+AGUgnRQvE9nb5LoU0Lt19JZNhZtyt8y+3UuxbpBYl3/454hQuZIJRB
aFcoFZtz8Vihl0CYkiGJqjQmmpqZ/ERUVPixfI1/qE5/4xDuQduoC5CoPuuPyUMXlpS5nb4XTQuA90
oH1El9rtLZH6cMrvn+6l+wQz3YIKm0ikyN1FVwdTANbNaSVjGGlRx7lkVJyoG34jMCg9GzZeJGkXpB
7gSu9rCUjsCOEzRAOpC9kY610DEXOUFl80lzt7PWupp32R6elRLRbdLdX6Yz2eG31Gp+/dI4L3T1qd
9zO9Kk7IaySecHiyhoXr13jxpUbuB4cq8a/9ReefupHvvPDH+au+QUCpxEmJs0FmOKiCJ3jRQoix0t
FZg2hW6fd2qNPjXpzChFmBPQKx1eZk7kBSkuMC9DESKsQowxlJBWl2DbrrG6tPLu4eP2R9ra/Z9AVB
O4YWh0jrEwhKgqf9GgPltnY6uJHQ+aqUxxJJqjkOcGs476HTnPmqYeZvfv49+m6+kyqLGkg8TIAYVB
eoZ1AO4l0IJwtJPyVpS/fRIoIKWr4AchUI6REuXOMss/9XSfOfptUu8W19xLPEKfaePZw3tExQ4gT+
nmT1c0a1fojvzF37MlPWVtD6hCUR0hbnsLyJnFQ946ne++WtPMrAlzEWx5Syv3H5MyxfzsxPUcQVwr
Le60h1BAqqBgINcqE6CBG6QStQqSUfxc/mMB3y/QtO9DUPFyUe1EQCUU5fxKy+N6LciAMLrdMTEz8w
sTExN/PnCN3FhMVttHLa+vsDQYktTozs/M0mlMArK2s8vqrr3Pu7OtkHYgjmGpO/3AtblANq8ioCio
Gq9AEaK8LZWerkFYjvEEREagqvp/hcomRIUJHjI0mfQb5yGF0AtbQ7aQwUoABk7C33eP8+Wu88OzrY
KPJk8fv3IwjydraLq+ff50bS4t0ukOcVTQnj3LqztPMHq2jQkOGQ8aa6lSFhRPHufPuuzh1x51/v9J
o/ELRryxgem8RpZVvxfAq6ngMzrGvbk2+TZ7vTuR28HeldwXGE4UUAVKZQk1NGBwKoysIDN4rJhpTN
Kdm/q2RIYEOb6YQvTuX9zt78v3nBqMR8oJm8NE03ZzTskMlFqhIgTLFqo4kVBQyUUijQcUoUQ2lTBR
CfhZ9tAQQKpwvRg/7IwZfCsp7WcwYhCpP6bHaceFHVAkDDOKZYbdba+/uPbW10+Liles8/+p51vf6J
JNTzJ08gYlDOu1dFm9c5eqlC4xaXZAw15ylYap/TaUIMRIvuH6WiVxQSaoIr/alHIQXYBXeSlzuyXM
QvR3a7T54TTWZQOoaiBghE6SICi09IRAuJEsFO+tdXn3pDZ555sv84R9+IXnu7Cs/trXa/rTI1ZN5m
jPo9un1e2QuJfOWI8ePU7AeY/AR/Z6j2xkw0ZzkPQ/czwc//BR3v+fen4wnm/8A4XDC7WuPeu9Ronj
/N/mSiLINLMFhEFQQXpeSiW2su0JuL//PgpVv8r6FwqK9QYgAUHjvcCWk3ooGo1FIrxdTb9x5dnb23
h9RqsnhTqfYZ1DfjGzx76KQ1HwNfe3DwsIJqs1jnxz0Fj7p+tuIpA1iVHQnTApRDMaAUgXx1Osy4Wj
/GM7/X7jd1xBJ2RGsFqcGY1V3PRauvAl5IUqiiwfCkh6jtSZM6j+aq1ZweWX94y9fvMz6Xp/a7BHmb
jtFc2aenc4Gq6trXLt8lc5aIdwchwmJqiBSVdtd3v2JN8+++eNpK//U4tG1n5u/vn7u2G0niWt16hN
VVFLcJSEEikKvBlUnlD2814g0hjwqNh4LaR9GGYxGltWVTa5cucaVNy+zdGPxvs3N7Y+1d1s/uL2b1
ZYXt9DKksRVJpsjttsdLl++gTWS6YWTBGGM1k3mF+6hvSPYFpvUjk1zxyN3c/qhB/6PaKLxo2BJh0N
UGCDL2b4U/q2LWx40zYpB02SR0guHND3IlshGV+53buXHtOrhshzhBF4U4xyEQhAgVYQS4PM6o1STp
wGN2vwnA9Mgtx6txjYo4mtiPb/rg2+ffHl4+q0TRHX2U3Fz4X8aitXjqbJIYZHGISoCtCsq81JEUwi
P9znQBj/6x7iNv4SsI0QB+C1GvxonwIlCAkK+jXWZRJUSCK50ZlRUGhNMHsn/pqhcS9u5+DtUatTmj
lCbmQcTsrXTYWV5g531bcigUokIZUx/tw/ZgMnpGLuX1Vqr2z+2ubz7YxfPXXmmeXT+P1QnGr83N3/
03Mz8DPWJBiaJkIFGakWc5vQ7HqSjZVJUp0V/aNnZ7bG2vsva+g6t3S5raxv3ra5sfGu/O/iItfYDo
/6QdCRQgwq+a+i7AcoqlNAIB8M+7HWGfP7zz3Pv/Q9x2x13E9QSmscGzBw5zqMffD/3v/+xn5RR8qO
FOJEniCtFs6QMd7CqAAAgAElEQVT0u9CH8JRe3Nxn3G8PZeWGpgfAOrm7zCi7+I+lWyIQe0hhSxn/g
yGrUBpJBWSAyCdRKKJodrFanfkUhDhfKoB/FTiZe5dVffprIfBu/V4YAbJO1Fz43zO3+s/T0RCpIY4
sVIKCkqSLG+d8wU4vArCPEIOP2HztexWjn8cUO6uiqCVUKS447m8qcauf+7g+yYqftEIoxeTRY8zfd
vePNo4u/p1+PMHUseP4MGJ1c5tLl6+ydGOZdJgRmJiZyWm6OwMG3S7Ga/J+ytbKGoOtPVLg/2XvzYM
sO8/zvt+3nO3uvffsCzBYBhgsFCASkLGQEjeTFBHGiu3EkURWYkk2VYq1REuKTiKpXLTlhFoiS1YiW
+WyltiyRFKiJHCTCHMndhDAYJkZzNbTMz293P2c823545zuGVByySXHBinNnbrV042pRve95z3f973
v8/weF8X3TZ95/j6VZv9HZ6Z3dmZu9ovNbufJuJkdj7P0FZmo1eWW27q0vj5xNsg066SlpTeZ2uWtr
enBi2sbN507t3pHWbg3gNxX5AYtNFprBlsDptMpURQxm87Sn1jGgy2SDLrtBluTCSvn15AbE5Jsns7
MXmZ68yzsqkBX7aVlOruWflhuGza8QEiPFLLaKPgrssFw1QV/BaZYX3Rqu8E2AVZx/vR/L7j4kKSP8
EUdRSbrrX+lqQv1GdyHiCJvAykzvf0f0tFcvT2OK+XL1WUe5NdMtfy14vtPXf2CAiETos6uD2X2uh+
YDooDIk6hOQU5BeEIqkqt3RbXCukRopo8uXLlZ6Qo/1Co+DIyQ5IhRIwjqofC1cnB1rvPP/MILytOe
WFgamDoecg1mix05+nML7K2scbZlQucOnWa8aW1ykyrNG5cko/6NEXMnrklds3OYCcTNjYGmCAoBBi
lMcFz/rTcp5N4n4j0d6AlPlIIrZhpSfpbA0IQSBEzzQ0hVFuz8WgKKLyDWCcMBiNcaWikGd57GkmCx
JPOzZConPPDdaTTzPYWyM0lJtMpTnhefvkkcaPLHXfeRdbusbm5yUtnVnny+dMPfdP1Bz4cAc5W/Jx
GGgESuS0sCY6A2g4jqoFMcieQWwXwGIpiFWdPzXu3+jNajomEqYxG23lhMlRUOwHeawoH1mnGw4Qon
T09M3PoQ9DBWomSMcFXvk4h/qNGy9eK7887421zG69+FHi0AJ3NELcPfDA3o1/yOiFEmxTlCmlTVTz
MbV2fkFdScBEEf3lJePWz+O7fIXRBtBCigZJRxVgh4HZSCq5u2lUYCGQEQWI8DKaWC2uDxRdOr/z6W
n/MwZsOcfbSKufPn+XUmdOMt7YAaDdbRD6nmOZEGpT3aGVxJmc8yMF40Amj6RSnFWNjKI3DSwVSUOB
rcK8gEpWlKEubaB2Rj0sEEbGOsaWrAE5Bolst4nKCFIJunAKBNAXSQJY1SPUMG8Nz2NLhSkEr66Cyj
OFoxHj9MmdOnWRufoHdew8jVINzF4d86jOP/fpc1ji0b8/CpUaiUehKsxlsdWiWsgZRXcl+qGmcr7r
wbbHKZHIGY87/rJYbS42oQAtZAY6pi06Fyg6GxlhBWWqKUpOXTZJ07oNRuhto4J0mSqLqfy/kFV7rn
yEx+3oqv6/Lbmf4c4AbRpZ18EmE1OmjaZK+y+F2lz5HJ2BFUTUplKgCSepmCaGCEikC+bi4zU3ERa1
7jxKaVbdQRBWhWSqMLypVxrYaNzicKVBSQtCsbw7IWglnV4d87ON/8gfnLm1e3+jNMzGWV06fYXNzn
ZdefJawtorINDONBF/kuKIktzlHDu5ld28OP5lUX3cGhKc922a9vw44bDBM7IjcjfHeErBYlzPOc7z
b1t55nLEU5ZRQGlIliUWgGUlS5YiFYbYV02vFaEoSLO2ZQJYpApY4iplOCzbHA5IkIWs2MKHEllPG0
yFSRczP72J+bi/exaxeHEb5ZOP1+w8d+bVWo3pNtRA7xlXqcE3na4Mz4JwlOEusJBqJMGucPPFlTp7
83Pe68vyPtzJLIivDsVRRta2PAFnibI4NEqE7GNNiNIJO65sfW1q6/u+qaL4qvpAglaop15W5+lWzj
Z0cm6qw5Z/KibhWfP/RDyfyajtJjBQx3olV5/3f9qIkqBIV+4rytb1qCV2lpgaJM6AxiKA598rGO9c
v5B+bbe9dIZ0Fux1b7BDyivBabHfxts+AUqOShAtrOZ/74pMfeOHUue9WSRsRJWwNBpw9d5pnn3kce
+Yk2fIc33TbUdtOI9nfWGcyHTE/n9HOUqLgiQOkUYSOFIUv2Bz3afRa5C6nKKdsB1XmTMj9GOdLkqi
B1hIlBTIE8JZYSBqRohEpEulItKedSNIIOg1Nu6HIYs9MNyHuGZqtGB1r4jSj2emxuGs3Nx69ietvO
Ex/sG63xluSvGBaGoKP6XV30WwuMR0HJsXmgUbW8nt3Lz4SKXAF6EhW81E8Qmp88FgfUEgiJdFSIox
lstnnpec/xdNPfuau0yce/4iSQ+a6GY0kRoc6FDMClIHIIWOFlwl5nlGaLkrN02nf9X1pY/4FZLc67
4loZ6tZZQp+jVbpWvH9pw3Zr34GDJXaP0ZUw9cXvAg3BWFuFcqitEfWtDDhq+G4EJVI2TtJsGO21ic
88aWXeeIrJ97gpum/2t3ba0TcrIp621ERLNZbvLeIUHVARQgMC804hy89/vS9X3r8q/96aqDZnmVSl
pw6eYKXXniO0Ssvg4b77nv9//Tud7z1HbfdcuO4mSXfLIJPk5ai02wy0+yQKMV0PGaSjzHCY5Vnfdx
naqdYTIXFl67GJAaUqpQ+Eg++xJkC6Q1ppGjEmkQHOs2UZqrptBMamaLR0MSJR2lPp9tAtRxRlpC1O
xy64Sbe8Nfu58E3fxv3v/GBrdtfd9sHSjd5+3S0tbU53HqbMR7nI+Zm97Br6RBx1GaYb1JMyzcePHj
9J+ba8iwVQOCqpJtKFKGlxDuLrPscfqvPKy+8zMN/9KuNrz7xxY9evnRqababsHd5gWYjQ2mFiBRog
w85QTpElFCWGYN+incLNLN9v9Xu3fGPEC0QGT7E1d6kHtaHYOsZ6X9o5bti2b525vsLyXIqUuw2Nkm
qFBV3fyKI+fcQJrHzplav1RSsUP2qQkiUCkhpuLxyjrMnz/Lo5y/fduY4v9ZSB/+bW9+0F+JK76bwe
BxKVYRlXEBIBd6RO3j+5dPJ408d/+3cwszcEkFKRlt9Lq2cZ/2VExAJjt127GPvfPubf+6d3/YAzST
6p3fedvRXXjx+/Eeee/GJH1h75Vx7cuEyRV7ghEc2EqSWmGLK+tYWnd4MqUyZDIYUZVHhGAIUdoqSA
i0jtIyQIhCrmHYW0UpjYqVpJDFCBJKGJo4laTOrViY8ndku01jSm1mks7CPIze/joM3HRv2FhZ/Lmr
onxnn/UHhBpTl9OcGg8mbz13aesfWxTVeeO5Z0nSR/ftvoNVa4OzKOo899uxvzzdvP7TQoSCAMwEVS
4wx6KgC72LrzIyi5OWnnuWPH/44f/LHn/g164e37dqb4aaKcipxVkMSqrx6ESomqVA4FzMtUkrbJos
Wy2Z64CdQHfAK79VOvLX31Cd1f1VfWn7Nue9qs9i1le8vtjIikFXYV71SgpB+S2CHAfc2ZwtUrUQRo
U7iqVqkVe76tODZJ0/x9KNnefaxDS6c7t+CbbTnm72Pzy0uV99QB7xzaFXh87yv1Ca2tKyMNI898dX
feunUudfPzC7SaHTZ2NjizOnTvPT8V5leXmHPgeWNd7/9Tfc99M63lTceOUirmTE7P1McveXoH1935
Iafn59b3Gynrf1JnM4TJE5KchxDU2IiiU4TvLcYW6KVJGtkJEmMEoJOK6bTSul1mvQ6LWY6LeZmOsz
MdOl1OzTbDeI0Jm6lxM2UxmyP9uwMrbkec3t2ceOtxzj2uru4/a7XH7/u1lv+cWt+5m/5KDwsElXIS
NCd6SCC5MLKpd9bObf2PfmwyDaGEzyC2blZ4laP6WjC2oUL7WbauGl5cf7fxqpi7jgPKlIUhSE4R6R
jmOacf/Y4n/jwR3n4dz/yT0+eOPc/SA+znSZzcx3mF7p0ZxrEDY9jjNAWYomQKca1MMU8kTpAu3njD
8XNw3+EnK1VPDF10FI1NxShHg/5GsKlrr5oroqgE9eK7y9cfF7twFB97firXvDwJUJ4g7f+ei1kxUe
q5f47CDnvGaxu8exTZ3j2sbNcPOMRZZP1C5N7NzfG+fWHDn+uPdeBJAZnCVIS0AQnUFoyHOT8yWMv/
I8vvHz6R41TdGcWGY7GvPD8cZ7/6jNcfOEZFvct8+1vf9M7/+uH/voLNx05iFQBFwxxEpM1Wswu7jb
79x38/NEjR3/xhsM3fXH3nr2mMz97KJuZSRuzPbxWjPKc4XCIVppGo0kkI6RUxHGCllNUcCgZSGNNF
kfEUYXWi2JN0qhy41szM7QXF9h16BCHbr6R/TffxI233bZ1y7G7fnPfkaM/3ty96x/IVvZ5EmFKYdG
xRmhBGmV0O3OMx2W5cn7t0fXB6Lt8XlBiSVsR3ZnraDWb9Dc2sNPp0dlOb2V2pv14hasJKF0Bg+M4g
iBYefY4n/zwR/nCw5/80ZUTr/zD3OWkKqKRxbTbCfMLDRZ2tUg6npIBIrYEpTAhw5gekj000hv+KEu
PfD9yHnyCJ6pOeK/yYzsk9kqP9c8svvB1U3zfkNvOba9RtbW0eCrrjJQRUrZ/QEbmKRVkiqvORUI6I
MeZkqKYMuyXDDZzcDGzrSbCzDHZnPL0V57+4L//5CPDBzL5z5aOXYeKr6S4Si0opoETJ07f8NjTz/6
KKT3d3jxFYTh75jwvPPcC506cJGq1efMD933wPe/665++55vuJFBgyylp1qjGym6KoEmWdWktN9i9s
P/hY6+/9+Giv/m+l8+cfOvZyxfe/PzLxx84f/b0XZdXVis3gvWMB0OKyRiAVKxTFAYhFN1Wh05nhjR
pk6VtskabKGvR7PaY372bzuwMy/v3Prr7wL7PNDrtTyS95sMMgAjKvCAIi0gEKha42ubjPCwu7eVb7
n0jq6uDT5fuTz74/MmXfmwwuMjLLz1Bb/Eu9u9aYKY3z4WVSzz62FO/MtPJPnPocO9FpMCG6tyej8e
ce/5lPv3hj/L5P3z47108dfqDDaGxYonEB9xUMt6y9LdGDEd9MqMgNRgc1gS8VcjQIUl25ane9QPIO
fAdvKjyZUO4oneoqIRVAKl6tZ7mz9K6XSu+v/DjStRdNVCnCkmRaFDJizK034/J/x/vYvBxlbKDwTl
DXkxYX+tz/txqDTXTjLYmQMxwY8inPv6pX/QN7IMN9SvzB5YQjQxEpZU8dfI0n/j4p36nYI5ms03Wb
HBxdYPV1UusrKyAdbzh3ru/8sYH7//xG66/niSW+KCI45SAoMAQqRjrIUoqPguj6ndJZma4qXPs4Rv
S2x++c+tuRqNBc7y+8U3Tzf6xyVb/xvFm/9B0NN5jjFmQ5enu1tYgCxY1N7vk5ueWpllzpt9sdNbSV
u981uye6iwsvdBdXnoGpR8ji8ckUJZVYam0eudjmeA0WAwWg0Lhg0AnCTFw7NY7GQxKVi9v/vjFzbV
v3ZwO7u4PLnH+/AVSpTiw3GNtbYXjx1/g+kPLv9Pp3njrzHxGaT0mzzn5wnE+9ZGP8bnf+4O/u3Hy9
C/qSQEURCyjvEf6QLCKySRnc3OdxkJMM6vSi0zhCQ6ypEWazL4f2XsRm4KrzdL1TaJC2m/3VARfX6a
hv4zFJ0bVNkLIeqOR1JniIEMKpL8aVHK3S7LvkaKLzc8TucvErsRcXOHlF5usXZhhOikwE0/iI5Zb8
1Bq5DNDzpon//nZUUfPPfC6f6aP7IL5FpMLF/jov/k3v/DyK6dvKW+9hyiTXMo3OXHhZV448RQmv8x
dd99sHnrr/e9554P3MtOJoazU/iDxEjQRpQOlxgQdY4QjtASxjiAofFlFac3Oz9Ob6405eOARoXjEe
EthSnywBCEo8xGXXvwEXbPKof134GdvZ121CZGj6R0ZTbxImUYOKUs0AeUTdARWGMp4vLMB2+4Iylq
LEomKFk2ISBPLHcf2c/ny/WxtbL7nsSefP7l2fjN6KvwuStxOt3eMqBd46ZUT/Pbv9W9RvOsX3nDbs
e/X0zGnnnycL37sY3z1Tz7196YnT/xi25cktcjMxCfZ1ztIK8yRXkxxl2bIxwm5yZnBIwcSVRzCJm/
ANe//51ty/69qoCk8Qk3xIdk566fR1czVqH7+6UWuDnO6Vnz/f/Q7r3yUyLoBI+p5uJARQqXfi0tvl
7LxBmwDSQM73mI0sozWJ/jcEYqA8pJIJyQ6whlBpCRnT53kjz9R/uI4jNoPdL/1H/vJkM9+5o+//dH
Pfun9QUnSvSMKr1lf2+DFp5/m0tlX6M51ef29d3/Xt77tW8/F7aSyOGl21BZSSKLtzreOqlVGCoLzO
BcIrto/JVFc/3oxzlUgolgpoiitxyyeqUrIG7O0TYlo9FBZl4Zsg7JkOFQZoUQMosJNyKB3On4BUGT
sRFTvkFJ9/WoGnDEQKZJGytLuDnfeeTtrG8NzIoq+6/Nf+Mpv9C+scKbVJA2eTMesnjvN+ePHyYx9f
+hvfSIui49+/pMf50uf+tSPDi6ufDDTEcoEQjBodJ0EBT4vmQ4dww3NsO+ZjGA4gaZuEiVddNr9otH
x95Y7IyjJTpz1X4LHN+jKF+3YfMTVbs0aQ159KUHSfC/Sfl5GvRlnpvTHigsXc0aXxqhSk3gIWtOKu
rSSjNJ5GklK2omY9vs8+9gTH7TCLAxE8cEvPv3Ub5z76suoJKHVeJlps8XJs6c5/eyzdLtt3vaWB3/
tzW97428evGkJHWp5FGabXQciQYTqvuy8IkhR+d9UHaCJwgePs5YQqlQfESofm0ShZKXOMaUh012ya
JaUAnQXaBELTUBXYMQ6CksLWXnnRI1FrM9ikUuuOA7E10roQEVxzaUQKA37D+zlgQfvpQzmN8+tnHn
Ls8+Nvnv99Gm+cu4MmY5x+ZTpeJPpygrTc+d/Iwv+4MvPPPljq2dO/VALiVQagiAmodfuUGpDR7dIZ
ULw4EeeyaZnMs7IywbNZAGd7tkkW3zvdljnzqolrhXfa92kfdXsZpvTXNlQxI4RNsjsuCB8J6r4vdK
N2dySnD43ZXpxSlREZE6hgqalYxJAK0UrTVAV0ZXBpTVOPPPcDxWKH2rbmEPtBS5cvszpR75M3My4s
HGZFMf933bnyb/x7ne879gdN1OGgFIei6nmTsLXQ34JIULUANyrcyIAgvD0tza4cOEi7XabLK2CHoM
QqCih2UxRCiIZ4S3gEqRPwMYVp7L+1V8FDwrU7oCvmZK6qzg1r0qJuvLF4KocBqEVOpbs27/Esdtu4
Olnrnvf5NLW/aurq4eLcoLF0yBmVqTYwYBnvvTlpsyna9pZZuMusbco70hURitNyOKUTtaiFzVpxU1
E6hFFYHw5MB61COyBdA+kB74TZo9LYpQHvQPUlfxleXyDrnxy5/r62rs2VIGOMo7wZCjk7yPt9wUx/
aXxtM36uqLlW4g0Im8HjNQkokumWuiGot1uU9qcsSkxhSMpPbGOSOM2Ytf17Ern+czzLzHsXyai4Na
bb+ftf+1b3nPn0RvDbLcy4loqSJDHVnFhQtacegNOoCK90zlyziK8wzvHhdWzfOGLX0CrmE6nQ7vdJ
Y4atDodFheWmZmZQydxNXP0dcu8XsLUTvHVPQexXX+vWjcq09TXXsDh1WqsKtG6ztRTgiTWCN3ghiM
HuP++u8Pqky+9Z+PMqScTAomMEd4x32jTUAqz2SdyjkgrkiDQVpDphJlmk1QrvHXMp7M0UHRlglaCQ
T6h7GtCuYyKb0Rle74Pln8fOgQv0dsKmlf9kNeK77WctO98CFff6eutlUfVsyCJlPyy0uWiihb/d8Q
CXZWTxJY886BipE9IZEYjaRDHMT4ouiJha9yHYcm0HJN2uhxsL7A7mydTXY6fOsFYGL719ff84Dvuv
fepvQtNxgZkHHA4rgAL6qP+dgC5EoRtbJ64kk+nooDUHmMnDEcbKO1pdxo0WpJWOyFOBEp7Yg2TwoE
oa/ZlCcHipa6htG5nZ1A56AxBOISMaqW/qVwZf87rWsWu1ZOx4Ei14sCeZe6755tZf+LEU2unT/zg5
tbW/9lSEutLVDFBCIW0JR3dQJgSgSMloqVTmjKhnTRIOhFLrR6xDbRUhYDXskXa2suu2WP0Zm79X6H
3y5YGmgbCS6KrwMqvis29VnyvzZwvAG4HzhxePUmtJUc2VJKyBEGSLPxkp7n79m5733ui/BTTcYnMK
6ye8IJYC9JEYcsxG/1N5udnaSmNDBJJRDMkxCEmNyWvO3iYxUaDsTR/eMvu3R9ajBOkhcQanA/oVNU
6iiqa2AeB8PXXZKU/tNZWmQNa4pxFKsmufcvcfuctXLp0iV5vlsXFRXrdWZKkiVACE6Z4U+JlIOgcX
F75F+WEIDv1lKtEygiEJghHwBBQtc3H4TEEPb6y5d3Zpm7fKGqynAJjApSOEDyCgHKOXpZx683Xs2/
3wofsePTmRIW3K2IyKQhFTlckNGoXSUZEJ0lpRzGZjOkmDWa7PTpJRKI9LSkJ2jM7O8Oe6+5iz4G7f
0cke34yJ8LVISq6ErOC8wQpEDWc+FX3i2/QM+A3ZPEFcTUtwFWev+Drs15FHAtU71nFAtEI1RLtZO5
f9hqL72kkW1glsDqQZS2CV7SyKk+837fMdJtEKuBLQyNtEmuBH+fkY0PwgtKVHF5cxGbqY/RHnH3qW
Q6Lo8TLXdARFGFHyOsFuCBqvkmVXamErnDqtdbCuoBQ0OvOcOOtRzlUXo+UVRc2jpNKEhckcZwQ6Yh
BvglRgVAlaAPaEESoBOfCsY14qP6I6qMItY87YITZwdTInSK8khZkCk+UVt1VLXSF5Chyhpc3WD1zl
ueee5rxpI/S7mPCh7drBJQez4RW3CYLklglZAjaMmY2bdJptGjoGDEpkcGTKEVa13u32WXv7uugd/h
fYmJhIxHc9tAgVO8xwRIQVQMpfOMX3jds8W3T4bab5UpsJ5xUhx3rDEFERLIWljkBpQvjtdF9o7URc
piTyJgkk0Rao6Um+JxBf4qSEik8ZZHTzFKEs0QiRiqFdxJPIDjLeLCJ9sn/Nb44/bZnPjv+wOba2lc
PH7uR3vICemm+0iZGgjpMh6CrwBdb7wyTONqZtUVxmxAMFk+vt4y1ZRUGKarsh8pQrBBIXAjotCJDu
+BrIphgW1Zs8CQIgqiARdXaK/FB44WtBwox4NAEfI2d10rWoSugoqiiZVtPaQxmPOLC2Vf4yhc/xxO
PPcpnPvGpW6ej6U+5snio+u4RGsGs7NKQkqj0zGUtmlLRkBEdFdMUikxKmlkDbQsaqSSRgSiOcJMJ0
7MXyUb+PmLx+9ujuh3mSrAgPEJUcncp1Dd84X3jrnxXSV3kqyJN62y6SGO2GzEehHG49a3rB6tr7wt
bY9IoxkkHSLSWFRHC1Yk6UkKIdy54WW8XvQuVodU5nHdgJGZsKHMesoP+Q3Yy/ZnR2uY/StrtrSPHb
mHx4AHY16pWwClMhIeGpAafVabPegWvBOLxVSL8KgY6IPChXtmvijcugsUEgduGPHmJU3WAJhkhVNH
RQUe1jSZCBoEXMRJwxDsCoUhYnC/xtqJIl8ZjvUZJjbWei+fP8/gXv8BnP/0Jnnr0i72L58/9hED9S
JHnSOdRIiVSglQqUimJgYaSNISgFcV0opi5dptGHKGEJMYTR5JECaR0SFXtWszWiGxt8300s/9bxbz
s1JVgk+09chAe93Xjxvur3HB5FRPr6r9fsZN4AgkCjBXDldV3bL5yRoitMVmkCVrVYKUauSPrTHexH
aioELV41ztwweOExdeQCWs9zkFuDZMyZ7i++SPr5y59T9DRP1k7c+lDh4/eOLnujqM0980jZmKaXYm
ThpySlGZdSPUY8KqObZAgRXTVKEDtQLy2bzzexRBiJA0QKXiNldRhKhLh69m+Ay8rUbivx3/oajIa3
DbIWVdzSVmxPtMQGE1Lnnn2eZ588mmee/opnnv8scbLzz71D6bjwf+cSTrBKwSeGE0qNZmKaHhFS0U
0hGK+3aCrU5pS0U5juo2YRpSAt4gAWaxJYk3AoyKJloJicwPOrwj27H5H4vj5oHZSxF41D/Ffh5kLf
7W2nfV2Tb5Kx+d3znq2fpOEr+VdRZ5MVi8dzVcvzjXKnFhHV2BMoQqZ9FTbGikCvj4/BukrQhcgpEN
XzVPiSID1eGvxJsdOppSTknJcdpyQP315de2HL54/9wunz7z4S/NHli4s3bjM0k2LpPMpUhYgFisWp
VTgVXUnD7U/zV81+5NXwk/U1f0kkSCICV6D11VE2HbM2tUJRRK8kCh5BWQSqDSTwdSNqpBDKMGVbKx
f5vS5C3zuK4/z5S8/xZcfe3zX5qXL3xem0+/35bCXAJGsUjcTUlpRSlvFZF7SEJqGUnRUxHK3R0trY
g+JEMQyEElLEB4pBFF9RPBSEJREKUE56JOfOz2X3nLkqGx3kxhyBzUfpj4s/+VpdH5jr3zbBXhltZM
7e7lqmxYqu633MBzvyS9ffC/9LbrOEym/U3zOORSeIEQNSAoVk0RUhelCteohAjKqCq8IlaNdElAhE
EyVCe8nE4yHcZH3htOND5xefe4D/jHzL3oHm7929J4b/v3tf+0W9hxeBj0EkVRPFVORliNkqLDvOJB
U2IsrAKkq09o7V3M2RW1UrVYCvTPkNGBrXikGIad1vrUGaYlCDqEHlOBGUPTxeZ+Lqys88vkv8IlHP
sfnvvzMfZc2p989GJj3SXQ1La1faWsDs8S0dZNO0iAJksh5WlIzGzeYSVI6cUwnTolw6BCq11tWabp
KKZSXlQFWK7yO8ALMaMBk5SzppfPvZfVX5S0AACAASURBVD79J5rohKcSpm+Ha1a3QXut+L4uDn3bs
7N6K1J196qEHomsLsjphMml1b8/vnhZJnlBSnUnrjieAYUlyFDL1KphuNQRPkisr7EE3mNDdecOQlC
OC6zJcQRwDucsRTGltFB6S+Es07UNpusD8qj/vt4wel/aPf/k0u6t3+o0Dv52b37hhFApRA3QTRAdK
hZJC0hROgF0JZUL/qo9p0Xi0DTRuDpQ0lVFJRICFilzoGLcICZIOa32mEFCKMBPYHqeUAwxky3K8Tr
DrTXOnDt93cvPf+5vPPf0U39r/TJ3GF9BsIO1FMESI4lJaTUa9CaBjmrQlQ0iD7H29OKUhaxFL0nRP
pAoyOKYWAh0tN0cE2gNDdmgjAQiq3I1pIqQZU6xcQnOn5YcmP37JO0flFETJwTCKZTabqdpvr4AgH8
Vi09ckU1eLV/3XOVUDuBG40OXzq0cmmxcVqmHjhB44eviq3LhJKCkrs93onZMCEQQeCGxwhCCw3tbU
a2LHFeWWOkw1lGaCYU1dTRcQATLJN+iVH26PTiwO2PPLHckdvWO8aXJB2Xc/IJSyce0bj0sVPdRrWc
QqodQMwjZAtWugjG3CcxCbOeVIbCEoIEcRQF+CmZYEfdUDnZcubxxYIe4coswzTHTkrwckTMkv3SKf
NzHTvt3+aL/1vGo/4619fV7YnmB66+DzSms9WFaVq9xJGNSH6NkhHGKGRLaMqMlEiIZaOqI+VaTuax
BpgQ6OGIpiIVAKo/Scmf11rEgFilWemSaISKNlBBLiZsMyVdOq3Sw/xANechHyakg9I5hlr80ZfcN3
3DhyqD4yj70VYEYhEAxmswMNta/vRhPmBGCTCsmZVHTAB34ahsXCQg+YEPAW0+okxyFEFWR1zh0hyO
SgpJtZF9OnueUxiB0hNAKpav7s04li4sN9u+aYdd8g3bmScSU8Xj1HimSe1Ctn5aic1HquUe0mvm8i
kZfEar3hNbjSSAl7HBnFLrWVzlvMDatVl5bQD6EsMFA5IgoJ7Mjys0xzhsmfoNxvkq+tcVoa9jYGq/
fOXabd6v+iXvLyfD+RNqlRuSZjIas90cEH9i9nHBwVGDPwKSoFsxEJ8QhQRMTxwkdH9PUGamISJWgE
yf0Gm2acYz2hkxFaFnZo4K3SKXQuiKNy0jhS4/1vsL1I7CuMsD6PGe0uUY6Hny7K9o/RSucEuJKNPd
2k+pa8b2WD2MhhlxAiSRBkriKk6sFFDEYB9p6wvrgR5PVTblsPc0ENtYuEssmWmucUlgnyEuPk55UR
TSFrhiYoUCEymbqlKWILQOfM7QFZXtEbidELsKNHfHQ0kTTV5Zhq+RyvIndPWXXkZT2zU26Bxxzu9Z
ZSjZoTQ39eBcwwoUBQqwsRVH0HVEUfUd1BvXoqHHcWY5L3XhJiuQV79S5INKLSiWXcaHvB+fHifXl0
AY/GH1J+qDivAzNydR0TennN/qjJVO6vcPh6GC/3z9SFMVNwYubiqJgmo/Joo3qeAzEcYVfdLaN8Io
ZmbBPXCSJA3MKhjlIMySLNFmakkQtjgymRJHEZBLbUESdmBCD9o45H9EKAu0VIY4pYgiRIsQRSipcg
LxxHh81KLUHnyBKyYzz9LKI0eo67sQpqeaXflSF6G8aD6qeiygzpKEMQcxcK77XtNvCq+Bwr/pvzlX
HQZfndxeDwUEzyVGlwTpLrOrcu51/X1mhvajOdYSAweFDRafWWqJCwBcG70oiAsPcMp1YnI8QcUzUi
7DBYooBuR/S7Dhm9qUcuq7H4f0ddi/HtNsgoup7OlvNGEIAX+stfbB477HGMw7jm6zhJoGGEFOWjuC
r2V1ZWkajAQ5BPrVMpiXWVVrWae4Zj3JWL22wtTmkMJY0TQHJeDzGW0eSJIzqOWMcQ9Z0RFFlYxJUO
InDN+xjbsHS7m5x4sSEyxvgzSaNVoP2TBc/SBCNhFYzQzdisigmEwKpJGQJ1lXAXKkFiZIgBUorZL1
6i5rPKWsBgQ+WMjiEFZTGs7W2Rm9r66BaMHdLGX0l1PmWqKhq54ZrK9/XQfFJoquHrpIqn0FV/UMzG
e8era/f7qdTlDV4Z4iTiNhHBARlcHhV6S1FqMYT1nmCtjjrcd7jrcfZkmI6xJqCoATFBMpc4ZViag0
jM2HoBozEJqprmNsVceONPY7c2GJpOWJ5JiNVAes8LkqQchvs6ncQGN56rDUYY3AuYMqqILyT5FNDW
XrKwjKZTOn3DVJqxtOCrf6I0ggCMaNxyfrmiNGwaoQ6BwRTZaFTfe5cTltXwTFxQxFEio4CzhXo2NG
KI8ZmSNJusetgB6dBvTJhPIRCXGZrWjBs7SdppzSaTVpRRCoVWgaiSCFaGYUtEUJUNi0CWqmK4amp9
JkuqmRrQlb6XAU2VDkapZNML14kvXz59uae6W7VjCq7owAhNdvJD9eK77V6SMnVbZbt4gsCrNzWK3r
Ga2vvH11YTcR0irKWYC1KS2IUxjmUr9DikoAXlb3HBl9hA4PHuJK8NBRFgTAObT2+CBRT8CLFxgljY
DM4xqEgNAzz+yUHDkfcfH3MgWXIspxWFCFFggkxZdxGUNQz7QpDDwEfSgiO4F1lgK8s+bh6oBKswZc
Wm+dMxwVSakzpqsDM0lGWnn5/ytZmrYuWCuccZbkdoSBxzpPngGojhKclIqJEIWyOcY4YRxSmBG1wj
NDtlKX9TYglK+dG9DcLxqOCc/EScUMz18wq8bSUxInGKY8RDhFJSjzaByIX0Hhk3Sl2ArRUFXYfWcn
5tMNLsKq6IRX9LdzaesJo8H6yzkeErAYMob5ko2vF91oWXz1Irgkp29sQLyungwSKwdZbBmfP3TK5e
JFWnhN7hzMlLoC3Ed5XWQhBhtoB4XGumptZ65BCYrAVOdp5lKhyH2w+wQuNShOKNKYfpgy0gqzJzFL
MwZuaXHdQcGBPi4UOCGmJtcNLQSk0RZRAUSJE7XBAgHdVBzPESF8NlqsbvAYX8IXDFxG28LhSoVSEt
R7vQcoq3dWUpsL2SXBOsN535CWkicB5wXBY/ftmU7I5lOhI4aQgRCCUxQCZAl1OSJoZ1njiSNOamSF
qesqwihF9ihzU3mWypT0ksgFbOcIJsjjCYZmUOTpRKAJBVnoUrxxSGVCKEBzGVTcUhScoj1cOpz1BB
YT2MBliL12Ctcu30J17i4iyj1tZye5CrTu6Vnyv1aRBVFtOEXgVIc7tGEhtOllfv3WyeqEnhgNSZ0m
EYFpN5gjegncIb1GiTo5zFu9KvAfrHUIoSu8oXMnIGArrGRclk7xk0jQcOXojSzfeyKqZcrp/ga18l
UZzzNLhBnv2CbodTxoVKFmidEKpIpxUjDE0VMWl9EIQgq9XvmpvJYQmeA9BE7zEm4ApDDb3uFwRygQ
tHCY4TOkoC8d0ahlPLc4qojhi0i8wFoyB0gacDeR5LcQTgThUWQrSQBgZgi4Rqlp5/DgQ+5LgFRkSF
ac0eg2uu3mJG25t0m7NcfD6N7EUZYiVTTaffpH+2haRV7SkJpEVLkNIUUXZK4+PFD4WICwieGyo9sA
imGq1jwKFMkhliBBEpac4fw7OnO6xuHgrWfQISufVHkFdm/O9ps1OKruJuMpAi9zmkVjsdGDGF1beV
Vy6mMXjEYmzRK6swA6hEuiGYBCyyj8IziBsXkMgQSrJJC8YWcM4OPrOMDIGkaRksz0OHJnhW97xxsk
db/q278yj+HOvbF566OS5F7/v8qWXblvulizMlmi9hVADhJrgJXilKo+csChtkdIjQhX15Zyt/RkOL
yobUjXeU/hgcU5Q2kDwleazdKN6wCmZ5lNGY0NegHGK0kBpBSqJUXjGI0Npqu/lPAzHjpmWw0mYWMN
0nCMiT5JVxyk3EcwkPdKsTaO9RNZeZKa7l11L13Po0M3sWt77dJku/ZK24cNbJ05/i86ifzV9/nTDr
o+QhaMrU7A5XkjKSOAij0tBaon0DmUcQcfEVV5R1eiSDhdZgvJELhA5z3T1PMPTJ7L2dYfexVzn54h
afM299lrxvRaPbSm1ugqZcKUX4zGDzXdN1y48aC9fJJ0OEYXHljnOF7gAxutKoBscwllwJaLIq3OVB
BGnjMsJW4WhUBGjVDDUETNLiywfPOhe99++8SuHj97yAXbPfVIZx/7lI7+864YDv9zfuPXb26p433T
txLspL2DDBugRjhFOGnTi8cEQ3CZeiKq7KSpIbPCh0piGgPMB7yUEh/GO0o4xzuKEx0vHNDfEUYpQC
usm5CVYLymtYDg1GK/Y2CrIS4h0jBewNSgJARpZwsiMUV4QyhInAkkKMslIRAOIcWGG5d1HufnoHRz
YfxOLi/uZm939ER01/4WzfHRU096iRvzvombW35yb/anp0y/dXZ5dV8F6lFdIGXBK4aJAiCTIil0jh
SdKmkTeowk4GbDaU+pQB9EGdDBM+jl27SIM1h+kXH6XSOIPOxlfK77/7MXl/Z/yal39udv+wbczh23
FENIK8umgM127+NbJ+TMlW+txIxhi4Sl8jjMFhfGUItDMGrjSMO5vIQXV3Cp4ptOS8WTM0AXGArZ8o
C8FjX3L4egD94l7H3zwl9qvO/BvUfoRpEM1YiBCRglLy9lHpTUfbSZzh0Sx+d+Z6crfzPOVW0t3Cee
28GWO0A4nN6rsOi2Q0gIFNpSE4BBS4pxBSMl0lNMfjzAYVKYwefWzTUswLlCUgdJLSge5CYwLz7QUD
IYGJyRBCoa5pcirZoeOIoSOOb82ZHYWOp123cJXJI1FDh26gT37DnDkhps5fPgGDhy87qtJ1v5/Bfr
XpUpPVYm3ZdXtl4K402bh6HWfnJ+fLYu9e75j89Hn3r/51RdDpr3oNloEkTOcrIN3NLpNhHcMR2NCL
NFxghSC3E4oMZBUZ2CbF6iyYCZJmVw8y8zKqZIbD75Vm/jTOokHAXb0rl8bnPq1CcbXiu8vMkm46sX
7s15I97V7fr3dALWosmiXq6u3i/WNWE2GaGdrf41B14JqG0kmZogtSlQsEc4zHo6Y2BLZyOgPpqxbw
0peUrRbHLrrbr7lrW+/fMvd3/yb6cLCj+WZnlb709rxgK0HHhFCxUSd5ins4k/r9u6fju3lb7blxf/
KuovvdHbjVhcmmNIRXKi9gdX80IWC0hUE6yjtlOA8uXFMnaAMIIJj6g3TYEE1MUimzpIbzdQqcgOlU
1VSQaRwhaCwlkkRKG31OqooRWVtFnfB0tIudu/bz8L8IosLuzl4+DqOXH8TS7t2fzVOG7/f6XR/N0r
TLztjKL0jkqC0IErjClAYAiZU57l4ef4RncRf8Yn2arH9t7eef3khH/TRBXQ7c2hpCEWOd45Ob4ZBE
XDBUtbjBaVcpTgyHm8sOIsUloQcu7Ea67WV23XWaqdJGJTXAEr/5YrvP7Tx9Nt8zu0ZkKja8W5z64H
R2bP3hI3LJOUE6as32ocqzVZLjUsCRZlTmAmp0EgpmDpDfzrFhkCZJAwJpHtmueWee7jrLW99/PDtd
/zrZHb2Q15IjEpqnb1DBoMMtqZXVF4KG4A4RsRzaGa+rMPClzG7fhy7eRNu/Ja83P+msizvN/l0xro
cR4FngrADSj/ChkphU4YRRmQ4keOFxzCmRGNCRlFaBhPHuFAUJmFqAqXXBBVTmDGGCJU16LZikrhJs
91hbnaeTqfD/v372bVrD9ddd4R9ew9uzs8tP9Jo9T4dR8nHkRwX+so8VWpFJKqcQE+ODx5NE+XrAbm
WeB3Bwuw0a2U/oPctvJLPZH9n8sKJ15VnV2g4T+ShsAU2SFSqifEEW2IpEJFHa4mzFudKpK0FByEnQ
tNfOcns6b33iKXdD0Rp5zeCSq4V32s7Y6+REWGHJ1HZf6bTrt3YfK9ZuRBUf1MkZoqUUDrD1JYEL5B
SMTUeGwwGgzUlUZRgIs1QwMZ4wpZWqKVFbn/g/vL+h959eu7WY9/thTw59o4ky7gSOqyQ+OoZLEJIA
oqpZ8cAK4UkYRYRZaDnjhPM8TSLfj4tS0w2udPZ/PXel3dZM76jyIfHymIYb/XX8G6KFwOCGGBtXmk
kozFejTBmgKEgzkpmdKA1oymdJIgUqRtMCk+StunNLDC/uMzi4i4WFhdZXFwue73eM1naezKJs0ezr
PklrdUT28YQ52uHUllvFlQgikVt0rVVkIpwkBvQGi0jcIGJspRC4rIGan/yK91UfjLpZP9uqMSB0em
V2E4CUZIi0Iy9JYlDZd4KHhUJNI6yLBHWIp3Ay4DHosgZXTpLdPZE6By9/b005j6m0H2uQXP/M44S/
hz1rKzV1J4qLRZVZeeRT47ZjY0lsdkXyXhMUuecG0oKnyO8QlrJ0E8AsKLK5ekXlo1pzrq3jLOEeHk
Xtz744Pib3vqWj8xdf+Qn0dELQick242eq54aXSMAq+6PoJKwuat6QdZDFDIIWW0RkhBBpHgigicQt
bvV5YRQ3LAHe0Pw+eGiGO83xWRPwC3h3VxR5jOTyag13VrN+qNhVBovG62ez7KuCSqdKpWNdNrcTNL
2ulDxxTjJzsdp64zW+qRQ6kWl1Itaa7RIdzbuvg4bCaFizWyT+XwA5331XoiaXk1U0cLVtsui9lK6q
mliqsnrOF5cfKYR1Lua6H84TpJ3mwurzbKYYF1OYXJ0UeCFwUmLEJ5gHaK0RF4QaQW+pJQGrKeclBQ
XVwRba0v0lo8pGX/W6/ha8b1WRRiEZ8chtsOr9NjJ9Nbi0tqxeDIls5YYg5DVaEHEAll6hAsYW2K9x
3tBieLyeMK5rQF0Z5m74fpwz7veLQ7dfdf/0rvxpj9A6pdyG0h0VWy28MSJrIfE9bKLfBV4Vl1lbJJ
chZp0QJB4VceX7+ji6k+iFAEvgnlReE+aGFJntznv4BxlWSCWVlhfX6c0gdm5RVqzC4AiyASRNCgmO
UHUPjmtqpHFdhNLSiZTi1KKKBJXDOLbXBl5lY5BVr9QCBCCQso6pTdy9TIZQEbEWte58WAJKDTp7Ow
L7dtv+d+6s70vb7z0ws9eevnFMNkohUPTnBY4THV6dwZlHdo6tIjRIqKQghJHMFOkMZSXV+Hs2WMsH
rqVrPPZa9vO/8Jnv6sL0WOri03Usz0BFKY92uz/8PrZ8zSKksj8f+2deYxd1X3HP2e5975t/Gb1jMf
GO/bYYBswBgMBgp0GXBkqIG2DQqqoahU1SEGqUrXqH5XaP6q2qVSlCKqqTdp/0gZFbYIapS1UJUogU
kRD2Yyx8Ybt8Xj29S13O6d/nPvevJkxhQQCM9Yc6cqekWd83znnt/9+32+MTGJSz84PwgImTklkndh
YapGhZgSJ79G1dRO9u/ey5cAtr+07dPffic7OJ/F9Ujw8PV9TzCkJhNlLqayZVC+IR62JkVI4DvcmY
G72zyxYlSzoUBTY+c9nRJYJVWAD0C1zUp5rhsZKgqogIcTPd0LQ4cQlAWxAUMjPW7amwnLT4xII8u5
9LWBMTGpcptXzPCwQRTFaa5T0nRIxztLYJKMY81OHxy1sw4ijwHFfpILUZvRnnWve9kr6a+1tKgkL8
rft6bP76hOT+PUJIhJiU8fGMaQpOTQa6cotys2HRVGITRLmRi8z+tYxejbv+grl7m+igtlV4fsIhW5
BBrTBrdMAP7IQ1asPzExOBBMjo+TDkDSsY6IakTDURUoUG2RdYKshdS/CCkW1HjOXWDo2bmH7gdsZu
OuefyvdcMM36Oz6Ll6+OStO6p55sORaNhnugfUXwq1LiZQqQ45OsTbJujL8ZqiSMtNA03Q8Dg0uBwR
WuQkFgUQK6XA3WzCirAVlNWEkqdddQd3HA6EyRGpJmmRVmAzHxS4a/4jTEGtTlJIZv7uLow11LBLfl
xm7qyWNXWyttNtuN1GegM4m7RHExuLHGUW3BWkERkIoDcLXBFvWP7mxlBssFwu/OXLi9P2FmWGkgSS
qYxLXbKCFRBhBkiSInHQOfBohjaEyOUH4zjk6J8YD1V95gKDtm6vC9zHFfIIqxiT4op0kAc8z0s4Mb
UtffX7D9qkTeLODzMkKM4FApAG52EfUq4zXp5iws4xX11CVkqjcSXnnLq755Kemtn7i0E9yG7Z8oWb
9GV/7CJM5gxJQCVbFJKSkJAS0z88zyXfbVk1DP4iFL49P5/v7/FkW12Hm2qb0TSd5/MIMXbWTlAIP0
k5Cr43UM+i0ii8KrglLgSFGk1lo6XgkAtkSM1lwOJ4tDerWzusT1cgutwiwyTewrZu/xHhLUaQ94/j
yrChgutq+J29a+8O2nTf+0+Dz6taRc+fak0vQqTyCoIZOK/jxKH5SpTZdJwk8ZizUdY6a9fCGh1Gv/
M8GOjq2xR1dErRJjCEQHtpCGjokNGwK2pJgSRzKJxqBb7XzDBIgvzzu+YqkfHFWwfUnWgG1arU0Nnj
5sdr0LPVqhSiqY5IQEYdYE1ELq0xVK1TSBOvnifwcaZCjf9sODh05OnT7PYef6OhZ+6hBTPg5fyFCj
23dKpFhiHzMhyZla0dCE0RJNHBHPwTP44M81s670Y0/lVJJEAQTxWLx0YFbDj5xzcDAUKFvHUmxjbo
fEHoBsQyIYoGnAmQsCKx0j4QorDJ86RwMX3jM1GslZWOkSR2AgQDlzHdDW2S6US694GLV8n2gFeAhh
EeMa96tTc598fLp8+3x+BRerYaKaigiZAqVeoQ1PmngMx3GDE1OEXetY+CmG5NbPv3p6rqDt32Btf0
/RQfjAq/ZKqpFa8CkmxZMLoMGJyll85Jn2ZCs/CGQQr4v4fpFhw3N92tZvu+jlBpTW7Z9bYPnvVDqK
H979u2ThcqpN3U4WmeN9WkL1hDOzhDVq2jPR4kITynCNGb48hl6x8+167D+RR0EX5VCZDGBahj2pqK
UGV43GTTW/++prArfksvxbu6nNpBKSSwEnqG3Mjq2Y+r0ed+bmCap10jSCGvqCCMRVlJJYMJqZoMct
tDHtbffw8HDh/+j97bb/oZi8dkkjLG6gEETpZacEu5MRUvWQmoH374MhG9JHCzEPFvTMjm/xVaw0Qo
mpSQWwXhu/aZn17d3PDLb3f07Fz19dFoopseGSecU2sbYNCGnPMKw5mYfpWVq5B3Mhbd8Oz2xg2KhV
0o1bI0AqZro1q4yIskqUFhMJn6mOQe6Knzv8xCvKICRhJxwEVi1LiuDg/dHg4MEk9OYKKQe1wmjKsY
oIlFiNIwYlYKe3ddx860HuO7wI38ddHb9I6X2/8XTGN8B8hlALaagaiQbLRngj1w2wpeZwWbiyeKGg
OVH+f+/h3JoIoIb0yx3xCrASMi1dX2/uNUf2uDlzhS7er48/uorXDp2jK5iBzmr3VlUa5i4jhIxszM
Vzrz+El0HL9zvl9f8EcUSQlhSFFa62qpqfHgrUYKFkxCrlu9D0PjksjpaQmVy+PHqhbO9ufExctU5S
GNmowiLZC5MmQgrRJ39XHvzAa47/KlTG/fs+T7X7H7cUfBIUqFIgSjLSTZZbiVLEQvs8ooZhGhkZJZ
Xx4fJYlApZdNFbgihEC5HaqxPJA1+oeOV0rbc46q4hkh6v1yzcvvEmTN4oaEeVYmNwCQGKRL8esLYq
bcRZ071dmza8Dj5/B841kxL3CJbooXPT0iZEQeAEGa+7LMqfD9v0OOBNQjCHZVLZ/fXzr1JYXoEXZk
iVhEzRpJIn1Brgu51XHvbXey5/+gbwXW7/xIveLoeC3KlwKYCIqCWuKJzE6buXYJzK+Y7XJZNzLc44
fIRXK73ihmVUk0BXPwzUkpUAkJlfbBgY51H9m74/e4b9culrt6vXPjJj6+ffPMNpi6eI+fn8UyIjiN
yQhGNRpw79jrbdu/aT3f3Dqw+CZDYFIxECYHXCvJpnABaTKZLzUIArVXh+xldTwtxGAnSuZ760Ok90
cUTFGaHiecmmckZ5vw8w3Mp5a713HToaGX3ffedYWDnQ5QK5xFEAUFz6l0CBa3nU78mRUm1VPjE/AT
Tsst2tuyPWAamWQhHKf2uMXt2hm6YClKh8b1SvdS/+Z/b2jtfzLWX//WY1lsvRNViPCVR4zGqWiOXK
irTKZffeoupSxf2tG/a2EObfBuVs1JohMqSKylLqK6Xy9ktOMeV4mouiCEM5PzAzgy+87lLb7zUy9Q
lVDzNXHWKyPcZsz7d19/KgQd/I9195OGvs3Pv5ymWT1nhRQjXFS9tk7C5WZVTGHzZ4ANwnHDuaSXj/
OgSFo3Pv3gPkiSZF0AhIFMey43BZ/Fo2Pw7O/g/bSGXPa6fW0dJvu2U6lv/+X33/8rXdx05mkbrrmG
yWGaqUGYoEkwJOHP6NC+//HIvlcrn0J6N0ihrS1hZa0W6nWkMyk/3MjV+pHb5ohUz4yKVMWkhYDQRd
F9/k73urqN25x33fpn+Dc8QyMFQOrg8kaR4mWFTC7SjWagfRUOFZow6SOyyKDRcBUulWYlEo6xAGde
iZiSkeBTKPa+qtra/2HHnPSeKa8pPHP/Bf4sTP/qBmJyN0RGcPHuR7teP213nLx5Zt37z3kAHr0WZE
xBHDt7zSmGDWBW+D8EaarSZntk/cup0KRyfFCKOGDEp+S3buHbnXrYfeuCF7t23Pk3/5qfwJLMYlHB
IZ0lcw5OLTqS1f2vJKdmMvNK0JMs+Xh0rRFbBWqGjNREpSkiUSDPUJgfJr1KXrTRKE1s1mF/b/9TWg
0Xht5V/XZTa73zthR9x/q0TyHrIifPnxevHT5a6du/b73cV3tQ40g0dLHI5pSs3yOa3VhMuH8xX9kk
qg6N3D588212drCBybei+NWy865fYfNd9/86Om/8UEbyQ2pSahVTLZiIl7+Xnhcs2BI+MlTIbArpCV
lM2I4flcXgrmRK50UKkGi5oY8+zM5GAEAFWJMi2zievueHAq6We/j9Myj1HzsbfQQ5e5NTQCC+/ebx
74M7xu9eXu//BWOnQBNRSwTPNLKhcViZwRbaXhcns/qnR4UdmHKb3TAAAAyxJREFUhsZJ04Dyjr1sP
/qZoc1HP/MMu29+GL/0IkqDD1obRwNm4/lTb8Zyi6ydzWjCMuoxmz1iwbMqeB/80mVN5I0bqLJG2gy
PlTh1uKbCB+ljc20vdm4deHjPoXuf+cSvPTpU3riJmvQ5fXGIS8Njj2D1fl8pTBS30PwaUtyzINGyj
OKGlWj5vJnK2IOnjx+L49nQ37nrAAOH75xuv/XmP6Nv078YE9RkaEGnSBUCKRqBFj5e1o1ksxMQjYK
elQuEsLUwK2m1kpmlVB+/8K1kAQxaNtBmjeMOl8LtcRzV8WQuG6FQGIQVWtbW79zz2L19Gx/uL5f+J
P+fz5YHR8Z56aevxNt37n2wu7fnNd/TsfNaXBiRZiGDwKDRLbB3q8L3867y+MTlXdMTo8WBbbvi/Qf
vGOLAvt+qrl37w3EIcxLag4x11laIRAWPAI8Ot/ExpH6jWC8yF2devkyLrInFgmeWh7OwRPBWGG+Wi
F0jppWWRJBNHxikcD21XjFwUpk6AkatJEkC1orBclf73x564IHjhb7+v3/uv55fNz45VRy+fHlXd09
PmSgZc0hPNhvYAruYN27V8n2gtXV8fOShnq5O9t+492kG9n2LQv65KWAaWAMUDPhEaG0oIFyOMgkhy
YOaz2HKRVHc4lqQbf3LMisUrWjrl9XhhBCkwnWnNLiFDVCParR5BeeRJE47aungOASE1gueu+OTh76
0dt3Gzx47dvzRUnHNQ8Cf2yQZE7mg+XtslqVWi5XocjlDu7K0pgS+dfbs2V8tFotPlUqlr+ZyuXNO+
duFtaSrZF3pfCpiGjN2imToJJ39m6BjG1XZRwrkAI8YUKSZWlEZQDAIrNArHnyvpXtmM/B7wJeAbwO
fBcxKuQMrzfLdBoz29fX9led5v6u1XnBJW7vnr/YlrXEoNo22LRYOYlxZ1S6rkOfDcLvPAY/hGmWC7
H68uFI+x0oSPg2MAN/L5/M/vtqSED/T5cMu9J4Wf7HMGsB/4TEv/DFwe3Y/NPN57VXh+5BWApwFLlh
r661tV1eju/ne8YJrkWtES0tmRe2VOviv2j2aBp5nHihiRaz/A4oCnsAsje/+AAAAAElFTkSuQmCC"
    }

# $encoded(basn0g08), $encoded(basn2c08), $encoded(basn3p08), $encoded(basn6a08)
test imgPNG-1.1 {reading basic images; grayscale} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn0g08)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {32 32}
test imgPNG-1.2 {reading basic images; color} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn2c08)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {32 32}
test imgPNG-1.3 {reading basic images; color with palette} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn3p08)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {32 32}
test imgPNG-1.4 {reading basic images; alpha} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn6a08)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {32 32}

test imgPNG-2.1 {reading a bad image} -body {
    image create photo -data $encoded(BadX)
} -returnCodes error -result {unfinalized data stream in PNG data}
test imgPNG-2.2 {reading a good image with multiple IDATs} -setup {
    set i [image create photo]
} -body {
    $i put $encoded(MultiIDAT)
    return [image width $i]x[image height $i]
} -cleanup {
    image delete $i
} -result 223x212

test imgPNG-3.1 {reading image with unknown ancillary chunk - bug [1c659ef0f1]} -setup {
    set fileName [file join [file dirname [info script]] iDOT.png]
} -body {
    # the image contains an unknown chunk iDOT
    # since the name of this chunk starts with a lowercase letter,
    # it's an ancillary chunk that shall not trigger an error
    catch {set i [image create photo -file $fileName]}
} -cleanup {
    image delete $i
} -result 0

}
namespace delete png
imageFinish
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to tests/imgPPM.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100

101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118

119
120
121
122
123
124

125
126
127
128

129
130
131
132

133
134
135
136

137
138
139
140

141
142
143
144

145
146
147
148

149
150
151
152

153
154
155
156
157
158

159
160

161
162





163
164
165
166
167
168
169
170
# This file is a Tcl script to test out the code in tkImgFmtPPM.c,
# which reads and write PPM-format image files for photo widgets.
# The files is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

imageInit

# Note that we do not use [tcltest::makeFile] because it is
# only suitable for text files
proc put {file data} {
    set f [open $file w]
    fconfigure $f -translation lf
    puts -nonewline $f $data
    close $f
}

test imgPPM-1.1 {FileReadPPM procedure} -body {
    put test.ppm "P6\n0 256\n255\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has dimension(s) <= 0}
test imgPPM-1.2 {FileReadPPM procedure} -body {
    put test.ppm "P6\n-2 256\n255\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has dimension(s) <= 0}
test imgPPM-1.3 {FileReadPPM procedure} -body {
    put test.ppm "P6\n10 0\n255\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has dimension(s) <= 0}
test imgPPM-1.4 {FileReadPPM procedure} -body {
    put test.ppm "P6\n10 -2\n255\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has dimension(s) <= 0}
test imgPPM-1.5 {FileReadPPM procedure} -body {
    put test.ppm "P6\n10 20\n100000\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has bad maximum intensity value 100000}
test imgPPM-1.6 {FileReadPPM procedure} -body {
    put test.ppm "P6\n10 20\n0\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has bad maximum intensity value 0}
test imgPPM-1.7 {FileReadPPM procedure} -body {
    put test.ppm "P6\n10 10\n255\nabcdef"
    image create photo p1 -file test.ppm
} -returnCodes error -result {error reading PPM image file "test.ppm": not enough data}
test imgPPM-1.8 {FileReadPPM procedure} -body {
    put test.ppm "P6\n5 4\n255\n01234567890123456789012345678901234567890123456789012345678"
    image create photo p1 -file test.ppm
} -returnCodes error -result {error reading PPM image file "test.ppm": not enough data}
test imgPPM-1.9 {FileReadPPM procedure} -body {
    put test.ppm "P6\n5 4\n150\n012345678901234567890123456789012345678901234567890123456789"
    list [image create photo p1 -file test.ppm] \
        [image width p1] [image height p1]
} -returnCodes ok -result {p1 5 4}


test imgPPM-2.1 {FileWritePPM procedure} -setup {
    catch {image delete p1}
} -body {
    put test.ppm "P6\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm

    list [catch {p1 write not_a_dir/bar/baz/gorp} msg] [string tolower $msg] \
        [string tolower $errorCode]
} -cleanup {
    image delete p1
} -result {1 {couldn't open "not_a_dir/bar/baz/gorp": no such file or directory} {posix enoent {no such file or directory}}}

test imgPPM-2.2 {FileWritePPM procedure} -setup {
    catch {image delete p1}
    catch {unset data}
} -body {
    put test.ppm "P6\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
    p1 write -format ppm test.ppm
    set fd [open test.ppm]
    set data [read $fd]
    close $fd
    set data
} -cleanup {
    image delete p1
} -result {P6
5 4
255
012345678901234567890123456789012345678901234567890123456789}


test imgPPM-3.1 {ReadPPMFileHeader procedure} -body {

    put test.ppm "#   \n#\n#\nP6\n#\n##\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -cleanup {
    image delete p1
} -returnCodes ok -result p1
test imgPPM-3.2 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6\n5\n 4   	                                                                 255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -cleanup {
    image delete p1
} -returnCodes ok -result p1
test imgPPM-3.3 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6\n#                                                                      asdfasdf\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -cleanup {
    image delete p1
} -returnCodes ok -result p1
test imgPPM-3.4 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6 \n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -cleanup {
    image delete p1
} -returnCodes ok -result p1
test imgPPM-3.5 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P5\n5 4\n255\n01234567890123456789"
    image create photo p1 -file test.ppm
} -cleanup {
    image delete p1
} -returnCodes ok -result p1
test imgPPM-3.6 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P3\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.7 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6x\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.8 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6\nxy5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.9 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6\n5\n255\n!012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.10 {ReadPPMFileHeader procedure} -body {

    put test.ppm "P6\n5 4\nzz255\n012345678901234567890123456789012345678901234567890123456789"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.11 {ReadPPMFileHeader procedure, empty file} -body {

    put test.ppm "     "
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.12 {ReadPPMFileHeader procedure, file ends too soon} -body {

    put test.ppm "P6\n566"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}
test imgPPM-3.13 {ReadPPMFileHeader procedure, file ends too soon} -body {

    put test.ppm "P6\n566\n#asdf"
    image create photo p1 -file test.ppm
} -returnCodes error -result {couldn't recognize data in image file "test.ppm"}


test imgPPM-4.1 {StringReadPPM procedure, data too short [Bug 1822391]} -body {

    image create photo I -width 1103 -height 997
    I put "P5\n1103 997\n255\n"

} -cleanup {
    image delete I





} -returnCodes error -result {truncated PPM data}

test imgPPM-5.1 {StringReadPPM procedure} -setup {
    image create photo ppm
} -body {
    ppm put "P6\n0 256\n255\nabcdef"
} -returnCodes error -cleanup {
    image delete ppm




|
|



<



|










|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
<
|

<
|
<
|
|
>

|
<
<
|
<
|
<

<
<
<





<
<
|




<
|
>

|
<
|
<
|
>

|
<
|
<
|
>

|
<
|
<
|
>

|
<
|
<
|
>

|
<
|
<
|
>

|
|
|
>

|
|
|
>

|
|
|
>

|
|
|
>

|
|
|
>

|
|
|
>

|
|
|
>

|
|

<
|
>
|
<
>
|
|
>
>
>
>
>
|







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61

62

63
64
65
66
67


68

69

70



71
72
73
74
75


76
77
78
79
80

81
82
83
84

85

86
87
88
89

90

91
92
93
94

95

96
97
98
99

100

101
102
103
104

105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# This file is a Tcl script to test out the code in tkImgFmtPPM.c,
# which reads and write PPM-format image files for photo widgets.
# The files is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

eval image delete [image names]

# Note that we do not use [tcltest::makeFile] because it is
# only suitable for text files
proc put {file data} {
    set f [open $file w]
    fconfigure $f -translation lf
    puts -nonewline $f $data
    close $f
}

test imgPPM-1.1 {FileReadPPM procedure} {
    put test.ppm "P6\n0 256\n255\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has dimension(s) <= 0}}
test imgPPM-1.2 {FileReadPPM procedure} {
    put test.ppm "P6\n-2 256\n255\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has dimension(s) <= 0}}
test imgPPM-1.3 {FileReadPPM procedure} {
    put test.ppm "P6\n10 0\n255\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has dimension(s) <= 0}}
test imgPPM-1.4 {FileReadPPM procedure} {
    put test.ppm "P6\n10 -2\n255\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has dimension(s) <= 0}}
test imgPPM-1.5 {FileReadPPM procedure} {
    put test.ppm "P6\n10 20\n100000\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has bad maximum intensity value 100000}}
test imgPPM-1.6 {FileReadPPM procedure} {
    put test.ppm "P6\n10 20\n0\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {PPM image file "test.ppm" has bad maximum intensity value 0}}
test imgPPM-1.7 {FileReadPPM procedure} {
    put test.ppm "P6\n10 10\n255\nabcdef"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {error reading PPM image file "test.ppm": not enough data}}
test imgPPM-1.8 {FileReadPPM procedure} {
    put test.ppm "P6\n5 4\n255\n01234567890123456789012345678901234567890123456789012345678"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {error reading PPM image file "test.ppm": not enough data}}
test imgPPM-1.9 {FileReadPPM procedure} {
    put test.ppm "P6\n5 4\n150\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg \
	    [image width p1] [image height p1]

} {0 p1 5 4}


catch {image delete p1}

put test.ppm "P6\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
image create photo p1 -file test.ppm
test imgPPM-2.1 {FileWritePPM procedure} {
    list [catch {p1 write not_a_dir/bar/baz/gorp} msg] [string tolower $msg] \
	    [string tolower $errorCode]


} {1 {couldn't open "not_a_dir/bar/baz/gorp": no such file or directory} {posix enoent {no such file or directory}}}

test imgPPM-2.2 {FileWritePPM procedure} {

    catch {unset data}



    p1 write -format ppm test.ppm
    set fd [open test.ppm]
    set data [read $fd]
    close $fd
    set data


} {P6
5 4
255
012345678901234567890123456789012345678901234567890123456789}


test imgPPM-3.1 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "#   \n#\n#\nP6\n#\n##\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg

} {0 p1}

test imgPPM-3.2 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6\n5\n 4   	                                                                 255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg

} {0 p1}

test imgPPM-3.3 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6\n#                                                                      asdfasdf\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg

} {0 p1}

test imgPPM-3.4 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6 \n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg

} {0 p1}

test imgPPM-3.5 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P5\n5 4\n255\n01234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg

} {0 p1}

test imgPPM-3.6 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P3\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.7 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6x\n5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.8 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6\nxy5 4\n255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.9 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6\n5\n255\n!012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.10 {ReadPPMFileHeader procedure} {
    catch {image delete p1}
    put test.ppm "P6\n5 4\nzz255\n012345678901234567890123456789012345678901234567890123456789"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.11 {ReadPPMFileHeader procedure, empty file} {
    catch {image delete p1}
    put test.ppm "     "
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.12 {ReadPPMFileHeader procedure, file ends too soon} {
    catch {image delete p1}
    put test.ppm "P6\n566"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}
test imgPPM-3.13 {ReadPPMFileHeader procedure, file ends too soon} {
    catch {image delete p1}
    put test.ppm "P6\n566\n#asdf"
    list [catch {image create photo p1 -file test.ppm} msg] $msg
} {1 {couldn't recognize data in image file "test.ppm"}}


test imgPPM-4.1 {StringReadPPM procedure, data too short [Bug 1822391]} \
    -setup {
	image create photo I -width 1103 -height 997

    } \
    -cleanup {
	image delete I
    } \
    -body {
	I put "P5\n1103 997\n255\n"
    } \
    -returnCodes error \
    -result {truncated PPM data}

test imgPPM-5.1 {StringReadPPM procedure} -setup {
    image create photo ppm
} -body {
    ppm put "P6\n0 256\n255\nabcdef"
} -returnCodes error -cleanup {
    image delete ppm
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
} -body {
    ppm put "P6\n5 4\n150\n012345678901234567890123456789012345678901234567890123456789"
    list [image width ppm] [image height ppm]
} -cleanup {
    image delete ppm
} -result {5 4}

imageFinish

# cleanup
catch {file delete test.ppm}
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|









218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
} -body {
    ppm put "P6\n5 4\n150\n012345678901234567890123456789012345678901234567890123456789"
    list [image width ppm] [image height ppm]
} -cleanup {
    image delete ppm
} -result {5 4}

eval image delete [image names]

# cleanup
catch {file delete test.ppm}
cleanupTests
return

# Local Variables:
# mode: tcl
# End:

Changes to tests/imgPhoto.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134



135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348

349




350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391


392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517



518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706






707
708
709
710
711
712

713
714
715
716
717

718
719
720
721
722

723
724

725
726
727
728

729
730
731

732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774

775



776



777





778
779
780
781
782
783
784
785
786
787
788
789
790


791



792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810


811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841


842
843
844
845
846


847
848
849
850
851
852
853
854
855

856
857
858
859
860

861
862

863
864
865
866
867
868

869
870
871
872
873
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
# This file is a Tcl script to test out the "photo" image type and the other
# procedures in the file tkImgPhoto.c. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 The Australian National University
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2002-2008 Donal K. Fellows
# All rights reserved.
#
# Author: Paul Mackerras (paulus@cs.anu.edu.au)

#
# This file is somewhat caothic: the order of the tests does not
# really follow the order of the corresponding functions in
# tkImgPhoto.c. Probably, because early versions had only a few tests
# and over time test cases were added in bits and pieces.
# To be noted, also, that this file is not complete: large portions of
# code in tkImgPhoto.c have no test coverage.
#
# To help keeping the overview, the table below lists where to find
# tests for each of the functions in tkImgPhoto.c. The function are
# listed in the order as they appear in the source file.
#

#
# Function name                         Tests for function
#--------------------------------------------------------------------------
# PhotoFormatThreadExitProc             no tests
# Tk_Create*PhotoImageFormat            no tests
# ImgPhotoCreate                        imgPhoto-2.*
# ImgPhotoCmd                           imgPhoto-4.*, imgPhoto-17.*
# GetExtension:                         no tests
# ParseSubcommandOptions:               imgPhoto-1.*
# ImgPhotoConfigureModel:              imgPhoto-3.*, imgPhoto-15.*
# toggleComplexAlphaIfNeeded:           no tests
# ImgPhotoDelete:                       imgPhoto-8.*
# ImgPhotoCmdDeleteProc:                imgPhoto-9.*
# ImgPhotoSetSize:                      no tests
# MatchFileFormat:                      imgPhoto-18.*
# MatchSringFormat:                     imgPhoto-19.*
# Tk_FindPhoto:                         imgPhoto-11.*
# Tk_PhotoPutBlock:                     imgPhoto-10.*, imgPhoto-16.*
# Tk_PhotoPutZoomedBlock:               imgPhoto-12.*
# Tk_DitherPhoto:                       no tets
# Tk_PhotoBlank:                        no tests
# Tk_PhotoExpand:                       no tests
# Tk_PhotoGetSize:                      no tests
# Tk_PhotoSetSize:                      no tests
# TkGetPhotoValidRegion:                no tests
# ImgGetPhoto:                          no tests
# Tk_PhotoGetImage                      no tests
# ImgPostscriptPhoto                    no tests
# Tk_PhotoPutBlock_NoComposite          no tests, probably none needed
# Tk_PhotoPutZoomedBlock_NoComposite    no tests, probably none needed
# Tk_PhotoExpand_Panic                  no tests, probably none needed
# Tk_PhotoPutBlock_Panic                no tests, probably none needed
# Tk_PhotoPutZoomedBlock_Panic          no tests, probably none needed
# Tk_PhotoSetSize_Panic                 no tests, probably none needed
#--------------------------------------------------------------------------
#

#
# Some tests are not specific to a function in tkImgPhoto.c. They are:
#

#
# Test name(s)          Description
#--------------------------------------------------------------------------
# imgPhoto-5.*          Do not really belong to this file. ImgPhotoGet and
#                       ImgPhotoFree are defined in tkImgPhInstance.c.
# imgPhoto-6.*          Do not really belong to this file. ImgPhotoDisplay
#                       is defined in tkImgPhInstance.c.
# imgPhoto-7.*          Do not really belong to this file. ImgPhotoFree is
#                       defined in tkImgPhInstance.c.
# imgPhoto-13.*         Tests for separation in different interpreters
# imgPhoto-14.*         Test GIF format. Would belong to imgGIF.test
#                       - which does not exist.
#

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

#
# Used for imgPhoto-4.65 - imgPhoto-4.73
#
proc foreachPixel {img xVar yVar script} {
    upvar 1 $xVar x $yVar y
    set width [image width $img]
    set height [image height $img]
    for {set x 0} {$x<$width} {incr x} {
	for {set y 0} {$y<$height} {incr y} {
	    uplevel 1 $script
	}
    }
}
proc checkImgTrans {img} {
    set result {}
    foreachPixel $img x y {
	if {[$img transparency get $x $y]} {
	    lappend result $x,$y
	}
    }
    return $result
}
proc checkImgTransLoop {img script1 script2} {
    set result {}
    foreachPixel $img x y {
	eval $script1
	lappend result {*}[checkImgTrans $img]
	append result :
	eval $script2
	lappend result {*}[checkImgTrans $img]
	append result .
    }
    return $result
}

imageInit
set README [makeFile {
    README -- Tk test suite design document.
} README-imgPhoto]

# find the teapot.ppm file for use in these tests
set teapotPhotoFile [file join [file dirname [info script]] teapot.ppm]
testConstraint hasTeapotPhoto [file exists $teapotPhotoFile]
# let's see if we have the semi-transparent one as well
set transpTeapotPhotoFile [file join [file dirname [info script]] teapotTransparent.png]
testConstraint hasTranspTeapotPhoto [file exists $transpTeapotPhotoFile]
testConstraint needsTcl867 [package vsatisfies [package provide Tcl] 8.6.7-]





test imgPhoto-1.1 {options for photo images} -body {
    image create photo photo1 -width 79 -height 83
    list [photo1 cget -width] [photo1 cget -height] \
	[image width photo1] [image height photo1]
} -cleanup {
    image delete photo1
} -result {79 83 79 83}
test imgPhoto-1.2 {options for photo images} -body {
    list [catch {image create photo photo1 -file no.such.file} err] \
	[string tolower $err]
} -result {1 {couldn't open "no.such.file": no such file or directory}}
test imgPhoto-1.3 {options for photo images} -constraints hasTeapotPhoto -body {

    image create photo photo1 -file $teapotPhotoFile -format no.such.format
} -returnCodes error -result {image file format "no.such.format" is not supported}
test imgPhoto-1.4 {options for photo images} -constraints hasTeapotPhoto -body {
    image create photo photo1 -file $teapotPhotoFile
    list [image width photo1] [image height photo1]
} -cleanup {
    image delete photo1
} -result {256 256}
test imgPhoto-1.5 {options for photo images} -constraints hasTeapotPhoto -body {
    image create photo photo1 -file $teapotPhotoFile \
	-format ppm -width 79 -height 83
    list [image width photo1] [image height photo1] [photo1 cget -file] [photo1 cget -format]
} -cleanup {
    image delete photo1

} -result [list 79 83 $teapotPhotoFile ppm]
test imgPhoto-1.6 {options for photo images} -body {
    image create photo photo1 -palette 2/2/2 -gamma 2.2
    list [format %.1f [photo1 cget -gamma]] [photo1 cget -palette]
} -cleanup {
    image delete photo1

} -result {2.2 2/2/2}
test imgPhoto-1.7 {options for photo images} -returnCodes error -body {
    image create photo photo1 -file $README
} -result [subst {couldn't recognize data in image file "$README"}]
test imgPhoto-1.8 {options for photo images} -body {
    image create photo -blah blah
} -returnCodes error -result {unknown option "-blah"}
test imgPhoto-1.9 {options for photo images - error case} -body {
    image create photo -format
} -returnCodes error -result {value for "-format" missing}
test imgPhoto-1.10 {options for photo images - error case} -body {
    image create photo -data
} -returnCodes error -result {value for "-data" missing}
test imgPhoto-1.11 {options for photo images - error case} -body {
    image create photo photo1 -format
} -returnCodes error -result {value for "-format" missing}
test imgPhoto-1.12 {option -alpha, normal use} -setup {
    image create photo photo1
} -body {
    photo1 put "white" -to 0 0
    photo1 transparency get 0 0 -alpha
} -cleanup {
    imageCleanup
} -result 255
test imgPhoto-1.13 {option -withalpha, normal use} -setup {
    image create photo photo1
} -body {
    photo1 put {{blue green}}
    photo1 get 1 0 -withalpha
} -cleanup {
    imageCleanup
} -result {0 128 0 255}

test imgPhoto-2.1 {ImgPhotoCreate procedure} -setup {
    imageCleanup
} -body {
    catch {image create photo -blah blah}
    imageNames
} -result {}
test imgPhoto-2.2 {ImgPhotoCreate procedure} -setup {
    imageCleanup
} -body {
    image create photo image1
    list [info commands image1] [imageNames] \
	[image width image1] [image height image1]
} -cleanup {
    image delete image1
} -result {image1 image1 0 0}
# test imgPhoto-2.3 {ImgPhotoCreate procedure: creation failure} {
#     image create photo photo1
#     image create photo photo2 -width 10 -height 10
#     catch {image create photo photo2 -file bogus.img} msg
#     photo1 copy photo2
#     set msg
# } {couldn't open "bogus.img": no such file or directory}

test imgPhoto-3.1 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    photo1 configure -file $teapotPhotoFile
} -cleanup {
    image delete photo1
} -result {}
test imgPhoto-3.2 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    list [catch {photo1 configure -file bogus} err] [string tolower $err] \
	[image width photo1] [image height photo1]
} -cleanup {
    image delete photo1
} -result {1 {couldn't open "bogus": no such file or directory} 256 256}
test imgPhoto-3.3 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    image create photo photo1
    .c create image 10 10 -image photo1 -tags photo1.1 -anchor nw
    .c create image 300 10 -image photo1 -tags photo1.2 -anchor nw
    update
    photo1 configure -file $teapotPhotoFile
    update
    list [image width photo1] [image height photo1] [.c bbox photo1.1] [.c bbox photo1.2]
} -cleanup {
    destroy .c
    image delete photo1
} -result {256 256 {10 10 266 266} {300 10 556 266}}
test imgPhoto-3.4 {ImgPhotoConfigureModel: -data <ppm>} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    photo2 configure -data [photo1 data -format ppm -from 100 100 120 120]
    list [image width photo2] [image height photo2]
} -cleanup {
    imageCleanup
} -result {20 20}
# This testcase fails with Tcl < 8.6.7, due to [25842c]
test imgPhoto-3.5 {ImgPhotoConfigureModel: -data <png>} -constraints {
    hasTeapotPhoto needsTcl867
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    photo2 configure -data [photo1 data -format png -from 120 120 140 140]
    list [image width photo2] [image height photo2]
} -cleanup {
    imageCleanup
} -result {20 20}
test imgPhoto-3.6 {ImgPhotoConfigureModel: -data <default>} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    photo2 configure -data [photo1 data -from 80 90 100 110]
    list [image width photo2] [image height photo2]
} -cleanup {
    imageCleanup
} -result {20 20}

test imgPhoto-4.1 {ImgPhotoCmd procedure} -setup {
    image create photo photo1
} -body {
    photo1
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 option ?arg ...?"}
test imgPhoto-4.2 {ImgPhotoCmd procedure} -setup {
    image create photo photo1
} -body {
    photo1 blah
} -returnCodes error -cleanup {
    image delete photo1
} -match glob -result {bad option "blah": must be *}
test imgPhoto-4.3 {ImgPhotoCmd procedure: blank option} -setup {
    image create photo photo1
} -body {
    photo1 blank
    photo1 blank x
} -cleanup {
    image delete photo1
} -returnCodes error -result {wrong # args: should be "photo1 blank"}
test imgPhoto-4.4 {ImgPhotoCmd procedure: cget option} -setup {
    image create photo photo1
} -body {
    photo1 cget
} -cleanup {
    image delete photo1
} -returnCodes error -result {wrong # args: should be "photo1 cget option"}
test imgPhoto-4.5 {ImgPhotoCmd procedure: cget option} -setup {
    image create photo photo2 -width 25 -height 30
} -body {
    list [photo2 cget -width] [photo2 cget -height]
} -cleanup {
    image delete photo2
} -result {25 30}
test imgPhoto-4.6 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    llength [photo1 configure]
} -cleanup {
    image delete photo1
} -result 7
test imgPhoto-4.7 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    photo1 conf -palette 3/4/2
    photo1 configure -palette
} -cleanup {
    image delete photo1
} -result {-palette {} {} {} 3/4/2}
test imgPhoto-4.8 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    photo1 configure -blah
} -cleanup {

    image delete photo1




} -returnCodes error -result {unknown option "-blah"}
test imgPhoto-4.9 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    photo1 configure -palette {} -gamma
} -cleanup {
    image delete photo1
} -returnCodes error -result {value for "-gamma" missing}
test imgPhoto-4.10 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -width 25 -height 30
} -body {
    image create photo photo2 -file $teapotPhotoFile
    photo1 configure -width 0 -height 0 -palette {} -gamma 1
    photo1 copy photo2
    list [image width photo1] [image height photo1] [photo1 get 100 100]
} -cleanup {
    image delete photo1 photo2
} -result {256 256 {169 117 90}}
test imgPhoto-4.11 {ImgPhotoCmd procedure: copy option} -setup {
    image create photo photo1
} -body {
    photo1 copy
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 copy source-image ?-compositingrule rule? ?-from x1 y1 x2 y2? ?-to x1 y1 x2 y2? ?-zoom x y? ?-subsample x y?"}
test imgPhoto-4.12 {ImgPhotoCmd procedure: copy option} -setup {
    image create photo photo1
} -body {
    photo1 copy blah
} -returnCodes error -cleanup {
    image delete photo1
} -result {image "blah" doesn't exist or is not a photo image}
test imgPhoto-4.13 {ImgPhotoCmd procedure: copy option} -setup {
    image create photo photo1
    image create photo photo2
} -body {
    photo1 copy photo2 -blah
} -returnCodes error -cleanup {
    image delete photo1 photo2


} -result {unrecognized option "-blah": must be -compositingrule, -from, -shrink, -subsample, -to, or -zoom}
test imgPhoto-4.14 {ImgPhotoCmd procedure: copy option} -setup {
    image create photo photo1
    image create photo photo2
} -body {
    photo1 copy photo2 -from -to
} -returnCodes error -cleanup {
    image delete photo1 photo2
} -result {the "-from" option requires one to four integer values}
test imgPhoto-4.15 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2
    photo1 copy photo2 -from 0 70 60 120 -shrink
    list [image width photo1] [image height photo1] [photo1 get 20 10]
} -cleanup {
    image delete photo1 photo2
} -result {60 50 {215 154 120}}
test imgPhoto-4.16 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2 -from 60 120 0 70 -to 20 50
    list [image width photo1] [image height photo1] [photo1 get 40 80]
} -cleanup {
    image delete photo1 photo2
} -result {80 100 {19 92 192}}
test imgPhoto-4.17 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2 -from 0 120 60 70 -to 0 0 100 100
    list [image width photo1] [image height photo1] [photo1 get 80 60]
} -cleanup {
    image delete photo1 photo2
} -result {100 100 {215 154 120}}
test imgPhoto-4.18 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2 -from 60 70 0 120 -zoom 2
    list [image width photo1] [image height photo1] [photo1 get 100 50]
} -cleanup {
    image delete photo1 photo2
} -result {120 100 {169 99 47}}
test imgPhoto-4.19 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2 -from 0 70 60 120 -zoom 2
    list [image width photo1] [image height photo1] [photo1 get 100 50]
} -cleanup {
    image delete photo1 photo2
} -result {120 100 {169 99 47}}
test imgPhoto-4.20 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2 -from 20 20 200 180 -subsample 2 -shrink
    list [image width photo1] [image height photo1] [photo1 get 50 30]
} -cleanup {
    image delete photo1 photo2
} -result {90 80 {207 146 112}}
test imgPhoto-4.21 {ImgPhotoCmd procedure: copy option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
    image create photo photo2 -file $teapotPhotoFile
} -body {
    photo1 copy photo2
    set result [list [image width photo1] [image height photo1]]
    photo1 conf -width 49 -height 51
    lappend result [image width photo1] [image height photo1]
    photo1 copy photo2
    lappend result [image width photo1] [image height photo1]
    photo1 copy photo2 -from 0 0 10 10 -shrink
    lappend result [image width photo1] [image height photo1]
    photo1 conf -width 0
    photo1 copy photo2 -from 0 0 10 10 -shrink
    lappend result [image width photo1] [image height photo1]
    photo1 conf -height 0
    photo1 copy photo2 -from 0 0 10 10 -shrink
    lappend result [image width photo1] [image height photo1]
} -cleanup {
    image delete photo1 photo2
} -result {256 256 49 51 49 51 49 51 10 51 10 10}
# tests for <imageName> data: imgPhoto-4.
test imgPhoto-4.22 {ImgPhotoCmd procedure: get option} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $transpTeapotPhotoFile
    list [photo1 get 100 100 -withalpha] \
	[photo1 get 150 100 -withalpha] \
	[photo1 get 100 150] [photo1 get 150 150]
} -cleanup {
    image delete photo1
} -result {{175 71 0 162} {179 73 0 168} {14 8 0} {0 0 0}}

test imgPhoto-4.23 {ImgPhotoCmd procedure: get option} -setup {
    image create photo photo1
} -body {
    photo1 get 256 0
} -cleanup {
    image delete photo1
} -returnCodes error -result {photo1 get: coordinates out of range}
test imgPhoto-4.24 {ImgPhotoCmd procedure: get option} -setup {
    image create photo photo1
} -body {
    photo1 get 0 -1
} -cleanup {
    image delete photo1
} -returnCodes error -result {photo1 get: coordinates out of range}



test imgPhoto-4.25 {ImgPhotoCmd procedure: get option} -setup {
    image create photo photo1
} -body {
    photo1 get 0
} -cleanup {
    image delete photo1
} -returnCodes error -result \
    {wrong # args: should be "photo1 get x y ?-withalpha?"}
# more test for image get: 4.101-4.102
test imgPhoto-4.26 {ImgPhotoCmd procedure: put option} -setup {
    image create photo photo1
} -body {
    photo1 put
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 put data ?-option value ...?"}
test imgPhoto-4.27 {ImgPhotoCmd procedure: put option} -setup {
    image create photo photo1
} -body {
    photo1 put {{white} {white white}}
} -returnCodes error -cleanup {
    image delete photo1
} -result {invalid row # 1: all rows must have the same number of elements}
test imgPhoto-4.28 {ImgPhotoCmd procedure: put option} -setup {
    image create photo photo1
} -body {
    photo1 put {{blahgle}}
} -cleanup {
    image delete photo1
} -returnCodes error -result {invalid color name "blahgle"}
test imgPhoto-4.29 {ImgPhotoCmd procedure: put option} -setup {
    image create photo photo1
} -body {
    # SB: odd thing - this test passed with tk 8.6.6, even if the data
    # is in the wrong position:
    #photo1 put -to 10 10 20 20 {{white}}

    # this is how it's supposed to be:
    photo1 put {{white}} -to 10 10 20 20
    photo1 get 19 19
} -cleanup {
    image delete photo1
} -result {255 255 255}
# more tests for image put: 4.90-4.100
test imgPhoto-4.30 {ImgPhotoCmd procedure: read option} -setup {
    image create photo photo1
} -body {
    photo1 read
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 read fileName ?-option value ...?"}
test imgPhoto-4.31 {ImgPhotoCmd procedure: read option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile -zoom 2
} -returnCodes error -cleanup {
    image delete photo1
} -result {unrecognized option "-zoom": must be -format, -from, -shrink, or -to}
test imgPhoto-4.32 {ImgPhotoCmd procedure: read option} -setup {
    image create photo photo1
} -body {
    list [catch {photo1 read bogus} err] [string tolower $err]
} -cleanup {
    image delete photo1
} -result {1 {couldn't open "bogus": no such file or directory}}
test imgPhoto-4.33 {ImgPhotoCmd procedure: read option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile -format bogus
} -cleanup {
    image delete photo1
} -returnCodes error -result {image file format "bogus" is not supported}
test imgPhoto-4.34 {ImgPhotoCmd procedure: read option} -setup {
    image create photo photo1
} -body {
    photo1 read $README
} -returnCodes error -cleanup {
    image delete photo1
} -result [subst {couldn't recognize data in image file "$README"}]
test imgPhoto-4.35 {ImgPhotoCmd procedure: read option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile
    list [image width photo1] [image height photo1] [photo1 get 120 120]
} -cleanup {
    image delete photo1
} -result {256 256 {161 109 82}}
test imgPhoto-4.36 {ImgPhotoCmd procedure: read option} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile -from 0 70 60 120 -to 10 10 -shrink
    list [image width photo1] [image height photo1] [photo1 get 29 19]
} -cleanup {
    image delete photo1
} -result {70 60 {244 180 144}}
test imgPhoto-4.37 {ImgPhotoCmd procedure: redither option} -setup {
    image create photo photo1
} -body {
    photo1 redither
    photo1 redither x
} -cleanup {
    image delete photo1
} -returnCodes error -result {wrong # args: should be "photo1 redither"}
test imgPhoto-4.38 {ImgPhotoCmd procedure: write option} -setup {
    image create photo photo1
} -body {
    photo1 write
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 write fileName ?-option value ...?"}
test imgPhoto-4.39 {ImgPhotoCmd procedure: write option} -setup {
    image create photo photo1
} -body {
    photo1 write teapot.tmp -format bogus
} -cleanup {
    image delete photo1
} -returnCodes error -result {image file format "bogus" is unknown}

# more tests on "imageName write": imgPhoto-17.*
test imgPhoto-4.40 {ImgPhotoCmd procedure: transparency option} -setup {
    image create photo photo1
} -body {
    photo1 transparency
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 transparency option ?arg ...?"}
test imgPhoto-4.41 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 transparency get x y ?-option?"}
test imgPhoto-4.42 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 0
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 transparency get x y ?-option?"}
test imgPhoto-4.43 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 0 0 0 -alpha
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 transparency get x y ?-option?"}
test imgPhoto-4.44 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get bogus 0
} -cleanup {
    image delete photo1
} -returnCodes error -result {expected integer but got "bogus"}
test imgPhoto-4.45 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 0 bogus
} -cleanup {
    image delete photo1
} -returnCodes error -result {expected integer but got "bogus"}
test imgPhoto-4.46 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 put white
    photo1 transparency get 0 0
} -cleanup {
    image delete photo1
} -result 0
test imgPhoto-4.47 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 1 0
} -returnCodes error -cleanup {
    image delete photo1
} -result {photo1 transparency get: coordinates out of range}
test imgPhoto-4.48 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get -1 0
} -returnCodes error -cleanup {
    image delete photo1






} -result {photo1 transparency get: coordinates out of range}
test imgPhoto-4.49 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 0 1
} -returnCodes error -cleanup {

    image delete photo1
} -result {photo1 transparency get: coordinates out of range}
test imgPhoto-4.50 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {

    photo1 transparency get 0 -1
} -returnCodes error -cleanup {
    image delete photo1
} -result {photo1 transparency get: coordinates out of range}
test imgPhoto-4.51 {ImgPhotoCmd procedure: transparency get option} -setup {

    image create photo photo1
} -body {

    photo1 put white
    photo1 blank
    photo1 transparency get 0 0
} -cleanup {

    image delete photo1
} -result 1
# more tests for transparency get: 4.65, 4.66, 4.76-4.81

test imgPhoto-4.52 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set
} -returnCodes error -cleanup {
    image delete photo1
} -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
test imgPhoto-4.53 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0
} -returnCodes error -cleanup {
    image delete photo1
} -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
test imgPhoto-4.54 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 0
} -returnCodes error -cleanup {
    image delete photo1
} -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
test imgPhoto-4.55 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 0 0 0 -alpha
} -returnCodes error -cleanup {
    image delete photo1
} -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
test imgPhoto-4.56 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set bogus 0 0
} -cleanup {
    image delete photo1
} -returnCodes error -result {expected integer but got "bogus"}
test imgPhoto-4.57 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 bogus 0

} -cleanup {



    image delete photo1



} -returnCodes error -result {expected integer but got "bogus"}





test imgPhoto-4.58 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
    photo1 put blue
} -body {
    photo1 transparency set 0 0 bogus
} -cleanup {
    image delete photo1
} -returnCodes error -result {expected boolean value but got "bogus"}
test imgPhoto-4.59 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 1 0 0
} -returnCodes error -cleanup {


    image delete photo1



} -result {photo1 transparency set: coordinates out of range}
test imgPhoto-4.60 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set -1 0 0
} -returnCodes error -cleanup {
    image delete photo1
} -result {photo1 transparency set: coordinates out of range}
test imgPhoto-4.61 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 1 0
} -returnCodes error -cleanup {
    image delete photo1
} -result {photo1 transparency set: coordinates out of range}
test imgPhoto-4.62 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 -1 0


} -returnCodes error -cleanup {
    image delete photo1
} -result {photo1 transparency set: coordinates out of range}

test imgPhoto-4.63 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 put white
    photo1 transparency set 0 0 false
    photo1 transparency get 0 0
} -cleanup {
    image delete photo1
} -result 0
test imgPhoto-4.64 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 put white
    photo1 transparency set 0 0 true
    photo1 transparency get 0 0
} -cleanup {
    image delete photo1
} -result 1
# more tests for transparency set: 4.67, 4.68, 4.82-4.89
# Now for some heftier testing, checking that setting and resetting of pixels'
# transparency status doesn't "leak" with any one-off errors.
test imgPhoto-4.65 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 3 3
    checkImgTrans photo1
} -cleanup {
    image delete photo1


} -result {}
test imgPhoto-4.66 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 3 3


    photo1 blank
    checkImgTrans photo1
} -result {0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2}
test imgPhoto-4.67 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 3 3
    checkImgTransLoop photo1 {
	photo1 put white -to 0 0 3 3

	photo1 transparency set $x $y 1
    } {
	photo1 transparency set $x $y 0
    }
} -cleanup {

    image delete photo1
} -result {0,0:. 0,1:. 0,2:. 1,0:. 1,1:. 1,2:. 2,0:. 2,1:. 2,2:.}

test imgPhoto-4.68 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 3 3
    checkImgTransLoop photo1 {
	photo1 blank

	photo1 transparency set $x $y 0
    } {
	photo1 transparency set $x $y 1
    }
} -cleanup {
    image delete photo1
} -result {0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,2 1,0 1,1 1,2 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 1,0 1,1 1,2 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,1 1,2 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,0 1,2 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,0 1,1 2,0 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,0 1,1 1,2 2,1 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,2: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2. 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1: 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2.}
test imgPhoto-4.69 {ImgPhotoCmd procedure: copy with -compositingrule} -setup {
    # Test the compositing rules for copying images
    image create photo photo1 -width 3 -height 3
    image create photo photo2 -width 2 -height 2
} -body {

    photo1 copy photo2 -to 1 1 -compositingrule
} -cleanup {
    image delete photo1 photo2
} -returnCodes error -result {the "-compositingrule" option requires a value}
test imgPhoto-4.70 {ImgPhotoCmd procedure: copy with -compositingrule} -setup {
    # Test the compositing rules for copying images
    image create photo photo1 -width 3 -height 3
    image create photo photo2 -width 2 -height 2
} -body {
    photo1 copy photo2 -to 1 1 -compositingrule BAD
} -returnCodes error -cleanup {
    image delete photo1 photo2
} -result {bad compositing rule "BAD": must be overlay or set}
test imgPhoto-4.71 {ImgPhotoCmd procedure: copy with -compositingrule} -setup {
    # Test the compositing rules for copying images
    image create photo photo1 -width 3 -height 3
    image create photo photo2 -width 2 -height 2
} -body {
    # Tests default compositing rule
    photo1 blank
    photo2 blank
    photo1 put white -to 0 0 2 2
    photo2 put white -to 0 0 2 2
    photo2 transparency set 0 0 true
    photo1 copy photo2 -to 1 1
    checkImgTrans photo1
} -cleanup {
    image delete photo1 photo2
} -result {0,2 2,0}
test imgPhoto-4.72 {ImgPhotoCmd procedure: copy with -compositingrule} -setup {
    # Test the compositing rules for copying images
    image create photo photo1 -width 3 -height 3
    image create photo photo2 -width 2 -height 2
} -body {
    photo1 blank
    photo2 blank
    photo1 put white -to 0 0 2 2
    photo2 put white -to 0 0 2 2
    photo2 transparency set 0 0 true
    photo1 copy photo2 -to 1 1 -compositingrule overlay
    checkImgTrans photo1
} -cleanup {
    image delete photo1 photo2
} -result {0,2 2,0}
test imgPhoto-4.73 {ImgPhotoCmd procedure: copy with -compositingrule} -setup {
    # Test the compositing rules for copying images
    image create photo photo1 -width 3 -height 3
    image create photo photo2 -width 2 -height 2
} -body {
    photo1 blank
    photo2 blank
    photo1 put white -to 0 0 2 2
    photo2 put white -to 0 0 2 2
    photo2 transparency set 0 0 true
    photo1 copy photo2 -to 1 1 -compositingrule set
    checkImgTrans photo1
} -cleanup {
    image delete photo1 photo2
} -result {0,2 1,1 2,0}

test imgPhoto-4.74 {ImgPhotoCmd procedure: put option error handling} -setup {
    image create photo photo1
} -body {
    photo1 put {{white}} -to 10 10 20 20 {{white}}
} -cleanup {
    image delete photo1
} -returnCodes 1 -result {wrong # args: should be "photo1 put data ?-option value ...?"}
test imgPhoto-4.75 {<photo> read command: filename starting with '-'} -constraints {
    hasTeapotPhoto
} -body {
    file copy -force $teapotPhotoFile -teapotPhotoFile
    image create photo photo1
    photo1 read -teapotPhotoFile
} -cleanup {
    image delete photo1
    file delete ./-teapotPhotoFile
} -result {}
test imgPhoto-4.75.1 {ImgPhotoCmd procedure: copy to same image} -constraints {
    hasTeapotPhoto
} -setup {
    imageCleanup
    image create photo photo1 -file $teapotPhotoFile
} -body {
    # non-regression test for bug [5239fd749b] - shall just not crash
    photo1 copy photo1 -to 0 0 2000 1000
    photo1 copy photo1 -subsample 2 2 -shrink
} -cleanup {
    imageCleanup
} -result {}
test imgPhoto-4.76 {ImgPhotoCmd, transparency get: too many options} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 1 1
    photo1 transparency get 0 0 -alpha -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {wrong # args: should be "photo1 transparency get x y ?-option?"}
test imgPhoto-4.77 {ImgPhotoCmd, transparency get: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 1 1
    photo1 transparency get 0 0 -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -alpha}
test imgPhoto-4.78 {ImgPhotoCmd, transparency get: normal use} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 1 1
    set result [photo1 transparency get 0 0]
    lappend result [photo1 transparency get 0 0 -alpha]
} -cleanup {
    imageCleanup
} -result {0 255}
test imgPhoto-4.79 {ImgPhotoCmd, transparency get: no option} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
    set result {}
} -body {
    set pixelCoords {{156 239} {76 207} {153 213} {139 43} {75 112}}
    foreach coord $pixelCoords {
	lappend result [photo1 transparency get {*}$coord]
    }
    set result
} -cleanup {
    imageCleanup
} -result {0 1 0 0 0}
# test imgPhoto-4.80: deleted (was transparency get: -boolean)
test imgPhoto-4.81 {ImgPhotoCmd, transparency get: -alpha} -constraints {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1 -file $transpTeapotPhotoFile
    set result {}
} -body {
    set pixelCoords {{156 239} {76 207} {153 213} {139 43} {75 112}}
    foreach coord $pixelCoords {
	lappend result [photo1 transparency get {*}$coord -alpha]
    }
    set result
} -cleanup {
    imageCleanup
} -result {255 0 1 254 206}
test imgPhoto-4.82 {ImgPhotoCmd, transparency set: too many opts} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 0 -alpha -bogus 1
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
test imgPhoto-4.83 {ImgPhotoCmd, transparency set: invalid opt} -setup {
    image create photo photo1 -data black
} -body {
    photo1 transparency set 0 0 0 -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -alpha}
test imgPhoto-4.84 {ImgPhotoCmd, transparency set: invalid newVal} -setup {
    image create photo photo1 -data white
} -body {
    photo1 transparency set 0 0 bogus -alpha
} -cleanup {
    imageCleanup
} -returnCodes error -result {expected integer but got "bogus"}
test imgPhoto-4.85 {ImgPhotoCmd, transparency set: invalid newVal} -setup {
    image create photo photo1 -data red
} -body {
    photo1 transparency set 0 0 -1 -alpha
} -returnCodes error -result \
    {invalid alpha value "-1": must be integer between 0 and 255}
test imgPhoto-4.86 {ImgPhotoCmd, transparency set: invalid newVal} -setup {
    image create photo photo1 -data green
} -body {
    photo1 transparency set 0 0 256 -alpha
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {invalid alpha value "256": must be integer between 0 and 255}
test imgPhoto-4.87 {ImgPhotoCmd, transparency set: no opt} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 2 1
    photo1 transparency set 0 0 0
    photo1 transparency set 1 0 1
    list [photo1 transparency get 0 0 -alpha] \
        [photo1 transparency get 1 0 -alpha]
} -cleanup {
    imageCleanup
} -result {255 0}
# deleted: test imgPhoto-4.88 {ImgPhotoCmd, transparency set: -boolean}
test imgPhoto-4.89 {ImgPhotoCmd, transparency set: -alpha} -setup {
    image create photo photo1
} -body {
    photo1 put white -to 0 0 2 2
    photo1 transparency set 0 0 0 -alpha
    photo1 transparency set 1 0 1 -alpha
    photo1 transparency set 0 1 254 -alpha
    photo1 transparency set 1 1 255 -alpha
    list [photo1 transparency get 0 0] [photo1 transparency get 1 0] \
	[photo1 transparency get 0 1] [photo1 transparency get 1 1]
} -cleanup {
    imageCleanup
} -result {1 0 0 0}
test imgPhoto-4.90 {ImgPhotoCmd put: existing but not allowed opt} -setup {
    image create photo photo1
} -body {
    photo1 put yellow -from 0 0 1 1
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-from": must be -format, or -to}
test imgPhoto-4.91 {ImgPhotoCmd put: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 put {{0 1 2 3}} -bogus x
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -format, or -to}
test imgPhoto-4.92 {ImgPhotocmd put: missing data} -setup {
    image create photo photo1
} -body {
    photo1 put -to 0 0
} -returnCodes error -result \
    {wrong # args: should be "photo1 put data ?-option value ...?"}
test imgPhoto-4.93 {ImgPhotoCmd put: data in ppm format} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    set imgdata [photo1 data -format ppm]
    photo2 put $imgdata -format ppm
    set result {}
    if {[image width photo1] != [image width photo2] \
            || [image height photo1] != [image height photo2]} {
        lappend result [list [image width photo2] [image height photo2]]
    } else {
        lappend result 1
    }
    foreach point {{206 125} {67 12} {13 46} {19 184}} {
        if {[photo1 get {*}$point] ne [photo2 get {*}$point]} {
            lappend result [photo2 get {*}$point]
        } else {
            lappend result 1
        }
    }
    set result
} -cleanup {
    imageCleanup
} -result {1 1 1 1 1}
test imgPhoto-4.94 {ImgPhotoCmd put: unknown format} -setup {
    image create photo photo1
} -body {
    photo1 put {no real data} -format bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result {image format "bogus" is not supported}
test imgPhoto-4.95 {ImgPhotoCmd put: default fmt, invalid data} -setup {
    image create photo photo1
} -body {
    photo1 put {{red green blue} {red " blue}}
    #"
} -cleanup {
    imageCleanup
} -returnCodes error -result {unmatched open quote in list}
test imgPhoto-4.96 {ImgPhotoCmd put: "default" handler is selected} -setup {
    image create photo photo1
    image create photo photo2
    set imgData {{{1 2 3 4} {5 6 7 8} {9 10 11 12}}
        {{13 14 15 15} {17 18 19 20} {21 22 23 24}}}
} -body {
    photo1 put $imgData
    photo2 put $imgData -format default
    set result {}
    lappend result [list [image width photo1] [image height photo1]]
    lappend result [list [image width photo2] [image height photo2]]
    lappend result [string equal \
        [photo1 data -format "default -colorformat rgba"] \
        [photo2 data -format "default -colorformat rgba"]]
    set result
} -cleanup {
    imageCleanup
    unset result
    unset imgData
} -result {{3 2} {3 2} 1}
test imgPhoto-4.97 {ImgPhotoCmd put: image size} -setup {
    image create photo photo1
} -body {
    photo1 put {{red green blue} {blue red green}}
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {3 2}
test imgPhoto-4.98 {ImgPhotoCmd put: -to with 2 coords} -setup {
    image create photo photo1
} -body {
    photo1 put {{"alice blue" "blanched almond"}
		{"deep sky blue" "ghost white"}
		{#AABBCC #AABBCCDD}} -to 5 6
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {7 9}
test imgPhoto-4.99 {ImgPhotoCmd put: -to with 4 coords} -setup {
    image create photo photo1
} -body {
    photo1 put {{#123 #456 #678} {#9AB #CDE #F01}} -to 1 2 20 21
    set result {}
    lappend result [photo1 get 19 20 -withalpha]
    lappend result [string equal \
	[photo1 data -from 1 2 4 4] [photo1 data -from 4 2 7 4]]
    lappend result [string equal \
	[photo1 data -from 10 12 13 14] [photo1 data -from 16 16 19 18]]
    set result
} -cleanup {
    imageCleanup
} -result {{17 34 51 255} 1 1}
test imgPhoto-4.100 {ImgPhotoCmd put: no changes on empty data} -setup {
    image create photo photo1
} -body {
    photo1 put {{brown blue} {cyan coral}}
    set imgData [photo1 data]
    photo1 put {}
    string equal $imgData [photo1 data]
} -cleanup {
    imageCleanup
} -result 1
test imgPhoto-4.101 {ImgPhotoCmd get: too many args} -setup {
    image create photo photo1
} -body {
    photo1 get 0 0 -withalpha bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {wrong # args: should be "photo1 get x y ?-withalpha?"}
test imgPhoto-4.102 {ImgPhotoCmd get: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 get 0 0 -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -withalpha}
test imgPhoto-4.103 {ImgPhotoCmd data: accepted opts} -setup {
    image create photo photo1 -data black
} -body {
    photo1 data -format default -from 0 0 -grayscale -background blue
} -cleanup {
    imageCleanup
} -result {{#000000}}
test imgPhoto-4.104 {ImgPhotoCmd data: existing but not accepted opt} -setup {
    image create photo photo1
} -body {
    photo1 data -to
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-to": must be -background, -format, -from, or -grayscale}
test imgPhoto-4.105 {ImgPhotoCmd data: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 data -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-bogus": must be -background, -format, -from, or -grayscale}
test imgPhoto-4.106 {ImgPhotoCmd data: extra arg before options} -setup {
    image create photo photo1
} -body {
    photo1 data bogus -grayscale
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {wrong # args: should be "photo1 data ?-option value ...?"}
test imgPhoto-4.107 {ImgPhotoCmd data: extra arg after options} -setup {
    image create photo photo1
} -body {
    photo1 data -format default bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {wrong # args: should be "photo1 data ?-option value ...?"}
test imgPhoto-4.108 {ImgPhotoCmd data: invalid -from coords #1} -setup {
    image create photo photo1 -data blue
} -body {
    photo1 data -from 2 0
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {coordinates for -from option extend outside image}
test imgPhoto-4.109 {ImgPhotoCmd data: invalid -from coords #2} -setup {
    image create photo photo1 -data blue
} -body {
    photo1 data -from 0 2
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {coordinates for -from option extend outside image}
test imgPhoto-4.110 {ImgPhotoCmd data: invalid -from coords #3} -setup {
    image create photo photo1 -data blue
} -body {
    photo1 data -from 0 0 2 1
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {coordinates for -from option extend outside image}
test imgPhoto-4.111 {ImgPhotoCmd data: invalid -from coords #4} -setup {
    image create photo photo1 -data blue
} -body {
    photo1 data -from 0 0 1 2
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {coordinates for -from option extend outside image}
test imgPhoto-4.112 {ImgPhotoCmd data: -from with 2 coords} -setup {
    image create photo photo1 -data {
        {black black black black black}
        {white white white white white}
        {green green green green green}}
} -body {
    set imgData [photo1 data -from 2 1]
    list [llength [lindex $imgData 0]] [llength $imgData]
} -cleanup {
    imageCleanup
    unset imgData
} -result {3 2}
test imgPhoto-4.113 {ImgPhotoCmd data: default is rgb format} -setup {
    image create photo photo1 -data red
} -body {
    photo1 data
} -cleanup {
    imageCleanup
} -result {{#ff0000}}
test imgPhoto-4.114 {ImgPhotoCmd data: unknown format} -setup {
    image create photo photo1
} -body {
    photo1 data -format bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result {image string format "bogus" is unknown}
test imgPhoto-4.115 {ImgPhotoCmd data: rgb colorformat} -setup {
    image create photo photo1 -data {{red#a green#b} {blue#c white}}
} -body {
    photo1 data -format {default -colorformat rgb}
} -result {{#ff0000 #008000} {#0000ff #ffffff}}
test imgPhoto-4.116 {ImgPhotoCmd data: rgba colorformat} -setup {
    image create photo photo1 -data {{red green} {blue white}}
} -body {
    photo1 data -format {default -colorformat rgba}
} -result {{#ff0000ff #008000ff} {#0000ffff #ffffffff}}
test imgPhoto-4.117 {ImgPhotoCmd data: list colorformat} -setup {
    image create photo photo1 -data {{red#a green} {blue#c white#d}}
} -body {
    photo1 data -format {default -colorformat list}
} -result {{{255 0 0 170} {0 128 0 255}} {{0 0 255 204} {255 255 255 221}}}
# This testcase fails with Tcl < 8.6.7, due to [25842c]
test imgPhoto-4.118 {ImgPhotoCmd data: using data for new image
    results in same image as orignial } -constraints {
        hasTeapotPhoto hasTranspTeapotPhoto needsTcl867
} -setup {
    image create photo teapot -file $teapotPhotoFile
    teapot copy teapot -from 50 60 70 80 -shrink
    image create photo teapotTransp -file $transpTeapotPhotoFile
    teapotTransp copy teapotTransp -from 100 110 120 130 -shrink
    image create photo photo1
} -body {
    set result {}
    # We don't test gif here, as there seems to be a problem with
    # <imgName> data and gif format ("too many colors", probably a bug)
    foreach fmt {ppm png {default -colorformat rgba} \
            {default -colorformat list}} {
        set imgData [teapotTransp data -format $fmt]
        photo1 blank
        photo1 put $imgData
        if { ! [string equal [photo1 data] [teapotTransp data]]} {
            lappend result $fmt
        }
    }
    set imgData [teapot data -format default]
    photo1 blank
    photo1 put $imgData
    if { ! [string equal [photo1 data] [teapot data]]} {
        lappend result default
    }
    set result
} -cleanup {
    unset imgData
    unset result
    imageCleanup
} -result {}

test imgPhoto-5.1 {ImgPhotoGet/Free procedures, shared instances} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
    image create photo photo1 -file $teapotPhotoFile
    .c create image 0 0 -image photo1 -tags photo1.1
    .c create image 256 0 -image photo1 -tags photo1.2
    .c create image 0 256 -image photo1 -tags photo1.3
    update
    .c delete i1.1
    photo1 configure -width 1
    update
    .c delete i1.2
    photo1 configure -height 1
    update
    image delete photo1
} -cleanup {
    destroy .c
} -result {}

test imgPhoto-6.1 {ImgPhotoDisplay procedure, blank display} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
    image create photo photo1 -width 10 -height 10
    photo1 blank
    .c create image 10 10 -image photo1
    update
} -cleanup {
    destroy .c
    image delete photo1
} -result {}

test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
    image create photo photo1 -file $teapotPhotoFile
    .c create image 0 0 -image photo1 -anchor nw
    update
    .c delete all
    image delete photo1
} -cleanup {
    destroy .c
}  -result {}
test imgPhoto-7.2 {ImgPhotoFree procedures, unlinking} -constraints {
    hasTeapotPhoto
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create photo photo1 -file $teapotPhotoFile
    pack [canvas .c]
    .c create image 10 10 -image photo1 -anchor nw
    button .b1 -image photo1
    button .b2 -image photo1
    button .b3 -image photo1
    pack .b1 .b2 .b3
    update
    destroy .b2
    update
    destroy .b3
    update
    destroy .b1
    update
    .c delete all
} -cleanup {
    destroy .c
    image delete photo1
} -result {}
test imgPhoto-7.3 {ImgPhotoFree procedures, multiple visuals} -constraints {
    hasTeapotPhoto
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create photo photo1 -file $teapotPhotoFile
    button .b1 -image photo1
    frame .f -visual best
    button .f.b2 -image photo1
    pack .f.b2
    pack .b1 .f
    update
    destroy .b1
    update
    .f.b2 configure -image {}
    update
    destroy .f
    image delete photo1
} -result {}

test imgPhoto-8.1 {ImgPhotoDelete procedure} -constraints hasTeapotPhoto -body {
    image create photo photo2 -file $teapotPhotoFile
    image delete photo2
} -result {}
test imgPhoto-8.2 {ImgPhotoDelete procedure} -constraints {
    hasTeapotPhoto
} -setup {
    set x {}
} -body {
    image create photo photo2 -file $teapotPhotoFile
    rename photo2 newphoto2
    lappend x [info command photo2] [info command new*] [newphoto2 cget -file]
    image delete photo2
    lappend x [info command new*]
} -result [list {} newphoto2 $teapotPhotoFile {}]
test imgPhoto-8.3 {ImgPhotoDelete procedure, name cleanup} -body {
    image create photo photo1
    image create photo photo2 -width 10 -height 10
    image delete photo2
    photo1 copy photo2
} -returnCodes error -cleanup {
    imageCleanup
} -result {image "photo2" doesn't exist or is not a photo image}

test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo2 -file $teapotPhotoFile
    rename photo2 {}
    list [expr {"photo2" in [imageNames]}] [catch {photo2 foo} msg] $msg
} -result {0 1 {invalid command name "photo2"}}

test imgPhoto-10.1 {Tk_ImgPhotoPutBlock procedure} -setup {
    imageCleanup
} -body {
    image create photo photo1
    photo1 put "{#ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000}" -to 0 0
    photo1 put "{#00ff00 #00ff00}" -to 2 0
    list [photo1 get 2 0] [photo1 get 3 0] [photo1 get 4 0]
} -result {{0 255 0} {0 255 0} {255 0 0}}
test imgPhoto-10.2 {Tk_ImgPhotoPutBlock, same source and dest img} -constraints {
    hasTeapotPhoto
} -setup {
    imageCleanup
} -body {
    # Test for bug e4336bef5d
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2 -file $teapotPhotoFile
    photo2 copy photo1 -to 1 2
    photo1 copy photo1 -to 1 2
    string equal [photo1 data] [photo2 data]
} -cleanup {
    imageCleanup
} -result 1
test imgPhoto-10.3 {Tk_ImgPhotoPutBlock, same source and dest img} -constraints {
    hasTeapotPhoto
} -setup {
    imageCleanup
} -body {
    # Test for bug e4336bef5d
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2 -file $teapotPhotoFile
    photo2 copy photo1 -from 2 1 -to 4 5 300 300
    photo1 copy photo1 -from 2 1 -to 4 5 300 300
    string equal [photo1 data] [photo2 data]
} -cleanup {
    imageCleanup
} -result 1
test imgPhoto-10.4 {Tk_ImgPhotoPutBlock, empty image} -setup {
    imageCleanup
} -body {
    image create photo photo1
    photo1 copy photo1 -to 0 5 10 20
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {0 0}

test imgPhoto-11.1 {Tk_FindPhoto} -setup {
    imageCleanup
} -body {
    image create bitmap i1
    image create photo photo1
    photo1 copy i1
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "i1" doesn't exist or is not a photo image}

test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} -constraints hasTeapotPhoto -body {
    image create photo p3 -file $teapotPhotoFile
    set result [list [p3 get 50 50] [p3 get 100 100]]
    p3 copy p3 -zoom 2
    lappend result [image width p3] [image height p3] [p3 get 100 100]
} -cleanup {
    image delete p3

} -result {{19 92 192} {169 117 90} 512 512 {19 92 192}}
test imgPhoto-12.2 {Tk_ImgPhotoPutZoomedBlock, same source and dest img} -constraints {
    hasTeapotPhoto
} -setup {
    imageCleanup
} -body {
    # Test for bug e4336bef5d
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2 -file $teapotPhotoFile
    photo2 copy photo1 -to 0 1 200 200 -zoom 2 3
    photo1 copy photo1 -to 0 1 200 200 -zoom 2 3
    string equal [photo1 data] [photo2 data]
} -cleanup {
    imageCleanup
} -result 1
test imgPhoto-12.3 {Tk_ImgPhotoPutZoomedBlock, same source and dest img} -setup {
    imageCleanup
} -body {
    # Test for bug e4336bef5d
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2 -file $teapotPhotoFile
    photo2 copy photo1 -from 1 0 -to 4 5 300 300 -zoom 1 2
    photo1 copy photo1 -from 1 0 -to 4 5 300 300 -zoom 1 2
    string equal [photo1 data] [photo2 data]
} -cleanup {
    imageCleanup
} -result 1
test imgPhoto-12.4 {Tk_ImgPhotoPutZoomedBlock, empty image} -setup {
    imageCleanup
} -body {
    image create photo photo1
    photo1 copy photo1 -to 0 5 10 20
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {0 0}

test imgPhoto-13.1 {check separation of images in different interpreters} -setup {
    imageCleanup
    set data {
	R0lGODlhQgBkAPUAANbWxs7Wxs7OxsbOxsbGxsbGvb3Gvca9vcDAwL21vbW1vbW1tbWtta2t
	ta2ltaWltaWlraWctaWcrZycrZyUrZSUrZSMrZSMpYyMrYyMpYyEpYSEpYR7pYR7nHp7pYRz
	pYRynHtzpXtznHtrnHNrnHNjnGtjnGtjlGtalGNalGNSlGNSjFpSlFpKlFpKjFJKjFJCjFI5
	jEo5jEo5hEoxhEIxhDkphDkhhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAQgBkAAAG
	/kCEcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vH7P
	7/v/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmOBZxXnAQEnKIIBUQJCguoDKkIBgWhpUev
|
|
|

|
|
|
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|

|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
|
<
<

|





|
|
|
|
|
|
>
>
>
|
|
|
|
<
<
|
|
|

|
|
>
|
|
|
|
|
<
<
|
|
|
|
|
<
<
>
|
|
|
|
<
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<

|
|
|
|
<

|
|
<
<
|

|
|
|
|


|
|
<
<
|
|
|
<
<
|
<
<
|
|
|
<
<
|
|
<
<
<
<
<
<
|
|
|

|

|
<
<
<
|
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
|
<
|
<
<
<
|
|
<
<
|
<
<
|
|
<
<
|
|
<
<
|
|
<
<
|
<
<
|
|
|
<
|
<
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
>
>
>
>
|
|
<
<
|
<
<
|
|
<
<
|
<
<
<
|
|
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
|
>
>
|
|
<
<
<
|
<
<
|
|
<
<
<
<
<
|
|
|
<
<
|
|
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
|
<
<
|
|
|
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
|
|
<
<
<
<
|
<
<
<
<
<
>
|
<
<
|
<
<
<
<
<
<
<
<
<
|
>
>
>
|
<
<
|
<
<
<
|
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
|
<
|
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
<
<
|
|
<
<
|
|
<
<
<
<
|
|
<
<
|
|
<
<
|
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
>
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
|
|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
>
>
>
>
>
>
|
|
<
|
|
|
>
|
|
|
|
|
>
|
<
<
|
|
>
|
|
>
|
|
|
<
>
|
<
|
>
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
|
|
|
<
<
|
<
<
|
>
|
>
>
>
|
>
>
>
|
>
>
>
>
>
|
<
|
<
|
|
<
<
|
<
|
|
<
>
>
|
>
>
>
<
<
<
<
|
<
<
|
<
|
<
|
<
<
|
<
|
<
<
>
>
|
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
>
>
|
<
<
<
<
>
>
|
<
<
|
<
<
<
|
<
>
|
|
|
|
<
>
|
<
>
|
<
<
<
|
<
>
|
<
|
<
<
<
<
<
|
|
|
<
>
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<

|
|
|
|
|
|
|
<
<
|
|
<
<
<
<
|
|
|
|
|
|
|
<
<
|
|
<
<
<
<
|
|
|
|
|
|
|
|
<
<
>






|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
|
|
|
|


|


|

|
|
<
<
|
|
|
<
<
<
|
|
|

|
<
<
<
|
|
<
|
|
<
<
<
|
|


|
|
<
<
|
<
<
<
<
<
|
<
|
|
|
|









|
<
<
<
|
<
<
<
<
<
|
|

|








|
|
|
|
|
|
|
|
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
|
|
|
<
<
|
|
|
|
|
|
|
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
<

|
|
<
<
|
|
|




<

>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|







1
2
3
4
5
6
7

8
9
10
11




































































12

13
14
15





16




17














18




19

20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58


59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
















81
82
83

84
85
86
87
88

89
90
91


92
93
94
95
96
97
98
99
100
101


102
103
104


105


106
107
108


109
110






111
112
113
114
115
116
117



118






119


120






121










122



123


124
125

126



127
128


129


130
131


132
133


134
135


136


137
138
139

140


141
142


143















144
145
146
147
148
149
150
151
152


153


154
155


156



157
158
159


160
161


162


163
164


165









166
167
168
169
170



171


172
173





174
175
176


177
178





179
180


181
182





183


184
185
186





187
188


189
190





191
192


193
194





195
196


197
198





199
200
201
202
203
204
205
206
207
208
209
210
211
212


213

214
215




216





217
218


219









220
221
222
223
224


225



226

227


228


229
230


231


232
233


234


235
236







237
238


239

240


241


242
243




244


245
246


247


248
249




250


251
252


253


254
255




256
257


258
259




260
261


262
263


264
265


266
267


268


269
270


271


272
273
274
275


276


277
278


279


280
281


282


283
284


285


286
287


288


289
290


291


292
293


294
295
296


297


298


299
300


301


302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320


321
322
323
324
325
326
327
328
329

330
331

332
333
334


335



336
337


338



339
340


341



342
343


344



345
346

347
348
349


350


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368

369
370


371

372
373

374
375
376
377
378
379




380


381

382

383


384

385


386
387
388


389
390
























391


392
393
394




395
396
397


398



399

400
401
402
403
404

405
406

407
408



409

410
411

412





413
414
415

416
417


418
419




420


421
422




423
424
425
426
427
428
429
430


431
432




433
434
435
436
437
438
439


440
441




442
443
444
445
446
447
448
449


450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467


















































































































































































































































































































































































































468














469

470
471



472
473
474
475
476
477
478
479
480
481
482
483
484


485
486
487



488
489
490
491
492



493
494

495
496



497
498
499
500
501
502


503





504

505
506
507
508
509
510
511
512
513
514
515
516
517
518



519





520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539




540
541
542
543
544
545
546
547
548
549
550


551
552
553


554
555
556
557
558
559
560

561
562
563
564
565





































566
567
568

569
570
571


572
573
574
575
576
577
578

579
580
581



































582
583
584
585
586
587
588
589
590
591
# This file is a Tcl script to test out the "photo" image type and the
# other procedures in the file tkImgPhoto.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Australian National University
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.

# All rights reserved.
#
# Author: Paul Mackerras (paulus@cs.anu.edu.au)





































































package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands






eval image delete [image names]



















canvas .c




pack .c

update



set README [makeFile {
README -- Tk test suite design document.
} README-imgPhoto]

# find the teapot.ppm file for use in these tests
set teapotPhotoFile [file join [file dirname [info script]] teapot.ppm]
testConstraint hasTeapotPhoto [file exists $teapotPhotoFile]

proc base64ok {} {
    expr {
        ![catch {package require base64}]
    }
}

testConstraint base64PackageNeeded [base64ok]

test imgPhoto-1.1 {options for photo images} {
    image create photo p1 -width 79 -height 83
    list [lindex [p1 configure -width] 4] [lindex [p1 configure -height] 4] \
	[image width p1] [image height p1]


} {79 83 79 83}
test imgPhoto-1.2 {options for photo images} {
    list [catch {image create photo p1 -file no.such.file} err] \
	[string tolower $err]
} {1 {couldn't open "no.such.file": no such file or directory}}
test imgPhoto-1.3 {options for photo images} hasTeapotPhoto {
    list [catch {image create photo p1 -file $teapotPhotoFile \
	    -format no.such.format} err] $err
} {1 {image file format "no.such.format" is not supported}}
test imgPhoto-1.4 {options for photo images} hasTeapotPhoto {
    image create photo p1 -file $teapotPhotoFile
    list [image width p1] [image height p1]


} {256 256}
test imgPhoto-1.5 {options for photo images} hasTeapotPhoto {
    image create photo p1 -file $teapotPhotoFile \
	    -format ppm -width 79 -height 83
    list [image width p1] [image height p1] \


	[lindex [p1 configure -file] 4] [lindex [p1 configure -format] 4]
} [list 79 83 $teapotPhotoFile ppm]
test imgPhoto-1.6 {options for photo images} {
    image create photo p1 -palette 2/2/2 -gamma 2.2
    list [format %.1f [lindex [p1 configure -gamma] 4]] \


	    [lindex [p1 configure -palette] 4]
} {2.2 2/2/2}
test imgPhoto-1.7 {options for photo images} {
    list [catch {image create photo p1 -file $README} err] $err
} [subst {1 {couldn't recognize data in image file "$README"}}]
test imgPhoto-1.8 {options for photo images} {
    list [catch {image create photo -blah blah} err] $err
} {1 {unknown option "-blah"}}
test imgPhoto-1.9 {options for photo images - error case} {
    list [catch {image create photo -format} err] $err
} {1 {value for "-format" missing}}
test imgPhoto-1.10 {options for photo images - error case} {
    list [catch {image create photo -data} err] $err
} {1 {value for "-data" missing}}
test imgPhoto-1.11 {options for photo images - error case} {
    list [catch {image create photo p1 -format} err] $err
} {1 {value for "-format" missing}}

















test imgPhoto-2.1 {ImgPhotoCreate procedure} {
    eval image delete [image names]

    catch {image create photo -blah blah}
    image names
} {}
test imgPhoto-2.2 {ImgPhotoCreate procedure} {
    eval image delete [image names]

    image create photo image1
    list [info commands image1] [image names] \
	    [image width image1] [image height image1]


} {image1 image1 0 0}
# test imgPhoto-2.3 {ImgPhotoCreate procedure: creation failure} {
#     image create photo p1
#     image create photo p2 -width 10 -height 10
#     catch {image create photo p2 -file bogus.img} msg
#     p1 copy p2
#     set msg
# } {couldn't open "bogus.img": no such file or directory}

test imgPhoto-3.1 {ImgPhotoConfigureMaster procedure} hasTeapotPhoto {


    image create photo p1 -file $teapotPhotoFile
    p1 configure -file $teapotPhotoFile
} {}


test imgPhoto-3.2 {ImgPhotoConfigureMaster procedure} hasTeapotPhoto {


    image create photo p1 -file $teapotPhotoFile
    list [catch {p1 configure -file bogus} err] [string tolower $err] \
	[image width p1] [image height p1]


} {1 {couldn't open "bogus": no such file or directory} 256 256}
test imgPhoto-3.3 {ImgPhotoConfigureMaster procedure} hasTeapotPhoto {






    image create photo p1
    .c create image 10 10 -image p1 -tags p1.1 -anchor nw
    .c create image 300 10 -image p1 -tags p1.2 -anchor nw
    update
    p1 configure -file $teapotPhotoFile
    update
    list [image width p1] [image height p1] [.c bbox p1.1] [.c bbox p1.2]



} {256 256 {10 10 266 266} {300 10 556 266}}









eval image delete [image names]






image create photo p1










.c create image 10 10 -image p1



update



test imgPhoto-4.1 {ImgPhotoCmd procedure} {

    list [catch {p1} err] $err



} {1 {wrong # args: should be "p1 option ?arg arg ...?"}}
test imgPhoto-4.2 {ImgPhotoCmd procedure} {


    list [catch {p1 blah} err] $err


} {1 {bad option "blah": must be blank, cget, configure, copy, data, get, put, read, redither, transparency, or write}}
test imgPhoto-4.3 {ImgPhotoCmd procedure: blank option} {


    p1 blank
    list [catch {p1 blank x} err] $err


} {1 {wrong # args: should be "p1 blank"}}
test imgPhoto-4.4 {ImgPhotoCmd procedure: cget option} {


    list [catch {p1 cget} msg] $msg


} {1 {wrong # args: should be "p1 cget option"}}
test imgPhoto-4.5 {ImgPhotoCmd procedure: cget option} {
    image create photo p2 -width 25 -height 30

    list [p2 cget -width] [p2 cget -height]


} {25 30}
test imgPhoto-4.6 {ImgPhotoCmd procedure: configure option} {


    llength [p1 configure]















} {7}
test imgPhoto-4.7 {ImgPhotoCmd procedure: configure option} {
    p1 conf -palette 3/4/2
    p1 configure -palette
} {-palette {} {} {} 3/4/2}
test imgPhoto-4.8 {ImgPhotoCmd procedure: configure option} {
    list [catch {p1 configure -blah} msg] $msg
} {1 {unknown option "-blah"}}
test imgPhoto-4.9 {ImgPhotoCmd procedure: configure option} {


    list [catch {p1 configure -palette {} -gamma} msg] $msg


} {1 {value for "-gamma" missing}}
test imgPhoto-4.10 {ImgPhotoCmd procedure: copy option} hasTeapotPhoto {


    image create photo p2 -file $teapotPhotoFile



    p1 configure -width 0 -height 0 -palette {} -gamma 1
    p1 copy p2
    list [image width p1] [image height p1] [p1 get 100 100]


} {256 256 {169 117 90}}
test imgPhoto-4.11 {ImgPhotoCmd procedure: copy option} {


    list [catch {p1 copy} msg] $msg


} {1 {wrong # args: should be "p1 copy source-image ?-compositingrule rule? ?-from x1 y1 x2 y2? ?-to x1 y1 x2 y2? ?-zoom x y? ?-subsample x y?"}}
test imgPhoto-4.12 {ImgPhotoCmd procedure: copy option} {


    list [catch {p1 copy blah} msg] $msg









} {1 {image "blah" doesn't exist or is not a photo image}}
test imgPhoto-4.13 {ImgPhotoCmd procedure: copy option} {
    list [catch {p1 copy p2 -blah} msg] $msg
} {1 {unrecognized option "-blah": must be -compositingrule, -from, -shrink, -subsample, -to, or -zoom}}
test imgPhoto-4.14 {ImgPhotoCmd procedure: copy option} {



    list [catch {p1 copy p2 -from -to} msg] $msg


} {1 {the "-from" option requires one to four integer values}}
test imgPhoto-4.15 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2
    p1 copy p2 -from 0 70 60 120 -shrink
    list [image width p1] [image height p1] [p1 get 20 10]


} {60 50 {215 154 120}}
test imgPhoto-4.16 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2 -from 60 120 0 70 -to 20 50
    list [image width p1] [image height p1] [p1 get 40 80]


} {80 100 {19 92 192}}
test imgPhoto-4.17 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2 -from 0 120 60 70 -to 0 0 100 100


    list [image width p1] [image height p1] [p1 get 80 60]
} {100 100 {215 154 120}}
test imgPhoto-4.18 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2 -from 60 70 0 120 -zoom 2
    list [image width p1] [image height p1] [p1 get 100 50]


} {120 100 {169 99 47}}
test imgPhoto-4.19 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2 -from 0 70 60 120
    list [image width p1] [image height p1] [p1 get 100 50]


} {120 100 {169 99 47}}
test imgPhoto-4.20 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2 -from 20 20 200 180 -subsample 2 -shrink
    list [image width p1] [image height p1] [p1 get 50 30]


} {90 80 {207 146 112}}
test imgPhoto-4.21 {ImgPhotoCmd procedure: copy option} {





    p1 copy p2
    set result [list [image width p1] [image height p1]]
    p1 conf -width 49 -height 51
    lappend result [image width p1] [image height p1]
    p1 copy p2
    lappend result [image width p1] [image height p1]
    p1 copy p2 -from 0 0 10 10 -shrink
    lappend result [image width p1] [image height p1]
    p1 conf -width 0
    p1 copy p2 -from 0 0 10 10 -shrink
    lappend result [image width p1] [image height p1]
    p1 conf -height 0
    p1 copy p2 -from 0 0 10 10 -shrink
    lappend result [image width p1] [image height p1]


} {256 256 49 51 49 51 49 51 10 51 10 10}

test imgPhoto-4.22 {ImgPhotoCmd procedure: get option} hasTeapotPhoto {
    p1 read $teapotPhotoFile




    list [p1 get 100 100] [p1 get 150 100] [p1 get 100 150]





} {{169 117 90} {172 115 84} {35 35 35}}
test imgPhoto-4.23 {ImgPhotoCmd procedure: get option} {


    list [catch {p1 get 256 0} err] $err









} {1 {p1 get: coordinates out of range}}
test imgPhoto-4.24 {ImgPhotoCmd procedure: get option} {
    list [catch {p1 get 0 -1} err] $err
} {1 {p1 get: coordinates out of range}}
test imgPhoto-4.25 {ImgPhotoCmd procedure: get option} {


    list [catch {p1 get} err] $err



} {1 {wrong # args: should be "p1 get x y"}}

test imgPhoto-4.26 {ImgPhotoCmd procedure: put option} {


    list [catch {p1 put} err] $err


} {1 {wrong # args: should be "p1 put data ?options?"}}
test imgPhoto-4.27 {ImgPhotoCmd procedure: put option} {


    list [catch {p1 put {{white} {white white}}} err] $err


} {1 {all elements of color list must have the same number of elements}}
test imgPhoto-4.28 {ImgPhotoCmd procedure: put option} {


    list [catch {p1 put {{blahgle}}} err] $err


} {1 {can't parse color "blahgle"}}
test imgPhoto-4.29 {ImgPhotoCmd procedure: put option} {







    p1 put {{white}} -to 10 10 20 20
    p1 get 19 19


} {255 255 255}

test imgPhoto-4.30 {ImgPhotoCmd procedure: read option} {


    list [catch {p1 read} err] $err


} {1 {wrong # args: should be "p1 read fileName ?options?"}}
test imgPhoto-4.31 {ImgPhotoCmd procedure: read option} hasTeapotPhoto {




    list [catch {p1 read $teapotPhotoFile -zoom 2} err] $err


} {1 {unrecognized option "-zoom": must be -format, -from, -shrink, or -to}}
test imgPhoto-4.32 {ImgPhotoCmd procedure: read option} {


    list [catch {p1 read bogus} err] [string tolower $err]


} {1 {couldn't open "bogus": no such file or directory}}
test imgPhoto-4.33 {ImgPhotoCmd procedure: read option} hasTeapotPhoto {




    list [catch {p1 read $teapotPhotoFile -format bogus} err] $err


} {1 {image file format "bogus" is not supported}}
test imgPhoto-4.34 {ImgPhotoCmd procedure: read option} {


    list [catch {p1 read $README} err] $err


} [subst {1 {couldn't recognize data in image file "$README"}}]
test imgPhoto-4.35 {ImgPhotoCmd procedure: read option} hasTeapotPhoto {




    p1 read $teapotPhotoFile
    list [image width p1] [image height p1] [p1 get 120 120]


} {256 256 {161 109 82}}
test imgPhoto-4.36 {ImgPhotoCmd procedure: read option} hasTeapotPhoto {




    p1 read $teapotPhotoFile -from 0 70 60 120 -to 10 10 -shrink
    list [image width p1] [image height p1] [p1 get 29 19]


} {70 60 {244 180 144}}
test imgPhoto-4.37 {ImgPhotoCmd procedure: redither option} {


    p1 redither
    list [catch {p1 redither x} err] $err


} {1 {wrong # args: should be "p1 redither"}}
test imgPhoto-4.38 {ImgPhotoCmd procedure: write option} {


    list [catch {p1 write} err] $err


} {1 {wrong # args: should be "p1 write fileName ?options?"}}
test imgPhoto-4.39 {ImgPhotoCmd procedure: write option} {


    list [catch {p1 write teapot.tmp -format bogus} err] $err


} {1 {image file format "bogus" is unknown}}
eval image delete [image names]
image create photo p1
test imgPhoto-4.40 {ImgPhotoCmd procedure: transparency option} {


    list [catch {p1 transparency} err] $err


} {1 {wrong # args: should be "p1 transparency option ?arg arg ...?"}}
test imgPhoto-4.41 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get} err] $err


} {1 {wrong # args: should be "p1 transparency get x y"}}
test imgPhoto-4.42 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get 0} err] $err


} {1 {wrong # args: should be "p1 transparency get x y"}}
test imgPhoto-4.43 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get 0 0 0} err] $err


} {1 {wrong # args: should be "p1 transparency get x y"}}
test imgPhoto-4.44 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get bogus 0} err] $err


} {1 {expected integer but got "bogus"}}
test imgPhoto-4.45 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get 0 bogus} err] $err


} {1 {expected integer but got "bogus"}}
test imgPhoto-4.46 {ImgPhotoCmd procedure: transparency get option} {


    p1 put white
    p1 transparency get 0 0
} 0


test imgPhoto-4.47 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get 1 0} err] $err


} {1 {p1 transparency get: coordinates out of range}}
test imgPhoto-4.48 {ImgPhotoCmd procedure: transparency get option} {


    list [catch {p1 transparency get -1 0} err] $err


} {1 {p1 transparency get: coordinates out of range}}
test imgPhoto-4.49 {ImgPhotoCmd procedure: transparency get option} {
    list [catch {p1 transparency get 0 1} err] $err
} {1 {p1 transparency get: coordinates out of range}}
test imgPhoto-4.50 {ImgPhotoCmd procedure: transparency get option} {
    list [catch {p1 transparency get 0 -1} err] $err
} {1 {p1 transparency get: coordinates out of range}}
test imgPhoto-4.51 {ImgPhotoCmd procedure: transparency get option} {

    p1 blank
    p1 transparency get 0 0
} 1
test imgPhoto-4.52 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set} err] $err
} {1 {wrong # args: should be "p1 transparency set x y boolean"}}
test imgPhoto-4.53 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set 0} err] $err
} {1 {wrong # args: should be "p1 transparency set x y boolean"}}
test imgPhoto-4.54 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set 0 0} err] $err


} {1 {wrong # args: should be "p1 transparency set x y boolean"}}
test imgPhoto-4.55 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set 0 0 0 0} err] $err
} {1 {wrong # args: should be "p1 transparency set x y boolean"}}
test imgPhoto-4.56 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set bogus 0 0} err] $err
} {1 {expected integer but got "bogus"}}
test imgPhoto-4.57 {ImgPhotoCmd procedure: transparency set option} {
    list [catch {p1 transparency set 0 bogus 0} err] $err

} {1 {expected integer but got "bogus"}}
test imgPhoto-4.58 {ImgPhotoCmd procedure: transparency set option} {

    list [catch {p1 transparency set 0 0 bogus} err] $err
} {1 {expected boolean value but got "bogus"}}
test imgPhoto-4.59 {ImgPhotoCmd procedure: transparency set option} {


    list [catch {p1 transparency set 1 0 0} err] $err



} {1 {p1 transparency set: coordinates out of range}}
test imgPhoto-4.60 {ImgPhotoCmd procedure: transparency set option} {


    list [catch {p1 transparency set -1 0 0} err] $err



} {1 {p1 transparency set: coordinates out of range}}
test imgPhoto-4.61 {ImgPhotoCmd procedure: transparency set option} {


    list [catch {p1 transparency set 0 1 0} err] $err



} {1 {p1 transparency set: coordinates out of range}}
test imgPhoto-4.62 {ImgPhotoCmd procedure: transparency set option} {


    list [catch {p1 transparency set 0 -1 0} err] $err



} {1 {p1 transparency set: coordinates out of range}}
test imgPhoto-4.63 {ImgPhotoCmd procedure: transparency set option} {

    p1 transparency set 0 0 false
    p1 transparency get 0 0
} 0


test imgPhoto-4.64 {ImgPhotoCmd procedure: transparency set option} {


    p1 transparency set 0 0 true
    p1 transparency get 0 0
} 1
# Now for some heftier testing, checking that setting and resetting of
# pixels' transparency status doesn't "leak" with any one-off errors.
proc checkImgTrans {img width height} {
    set result {}
    for {set x 0} {$x<$width} {incr x} {
	for {set y 0} {$y<$height} {incr y} {
	    if {[$img transparency get $x $y]} {
		lappend result $x $y
	    }
	}
    }
    return $result
}
test imgPhoto-4.65 {ImgPhotoCmd procedure: transparency get option} {

    p1 put white -to 0 0 3 3

    checkImgTrans p1 3 3
} {}


test imgPhoto-4.66 {ImgPhotoCmd procedure: transparency get option} {

    p1 blank
    checkImgTrans p1 3 3

} {0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2}
proc checkImgTransLoopSetReset {img width height} {
    set result {}
    for {set x 0} {$x<$width} {incr x} {
	for {set y 0} {$y<$height} {incr y} {
	    $img put white -to 0 0 3 3




	    $img transparency set $x $y 1


	    set result [concat $result [checkImgTrans $img $width $height]]

	    lappend result ,

	    $img transparency set $x $y 0


	    set result [concat $result [checkImgTrans $img $width $height]]

	    lappend result .


	}
    }
    return $result


}
test imgPhoto-4.67 {ImgPhotoCmd procedure: transparency set option} {
























    checkImgTransLoopSetReset p1 3 3


} {0 0 , . 0 1 , . 0 2 , . 1 0 , . 1 1 , . 1 2 , . 2 0 , . 2 1 , . 2 2 , .}
proc checkImgTransLoopResetSet {img width height} {
    set result {}




    for {set x 0} {$x<$width} {incr x} {
	for {set y 0} {$y<$height} {incr y} {
	    $img blank


	    $img transparency set $x $y 0



	    set result [concat $result [checkImgTrans $img $width $height]]

	    lappend result ,
	    $img transparency set $x $y 1
	    set result [concat $result [checkImgTrans $img $width $height]]
	    lappend result .
	}

    }
    return $result

}
test imgPhoto-4.67a {ImgPhotoCmd procedure: transparency set option} {



    checkImgTransLoopResetSet p1 3 3

} {0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 2 1 0 1 1 1 2 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 1 0 1 1 1 2 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 1 1 2 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 0 1 2 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 0 1 1 2 0 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 0 1 1 1 2 2 1 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 2 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 . 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 , 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2 .}
catch {rename checkImgTransLoopSetReset {}}

catch {rename checkImgTransLoopResetSet {}}





# Test the compositing rules for copying images
image create photo p1 -width 3 -height 3
image create photo p2 -width 2 -height 2

test imgPhoto-4.68 {ImgPhotoCmd procedure: copy with -compositingrule} {
    list [catch {p1 copy p2 -to 1 1 -compositingrule} msg] $msg


} {1 {the "-compositingrule" option requires a value}}
test imgPhoto-4.69 {ImgPhotoCmd procedure: copy with -compositingrule} {




    list [catch {p1 copy p2 -to 1 1 -compositingrule BAD} msg] $msg


} {1 {bad compositing rule "BAD": must be overlay or set}}
test imgPhoto-4.70 {ImgPhotoCmd procedure: copy with -compositingrule} {




    # Tests default compositing rule
    p1 blank
    p2 blank
    p1 put white -to 0 0 2 2
    p2 put white -to 0 0 2 2
    p2 transparency set 0 0 true
    p1 copy p2 -to 1 1
    checkImgTrans p1 3 3


} {0 2 2 0}
test imgPhoto-4.71 {ImgPhotoCmd procedure: copy with -compositingrule} {




    p1 blank
    p2 blank
    p1 put white -to 0 0 2 2
    p2 put white -to 0 0 2 2
    p2 transparency set 0 0 true
    p1 copy p2 -to 1 1 -compositingrule overlay
    checkImgTrans p1 3 3


} {0 2 2 0}
test imgPhoto-4.72 {ImgPhotoCmd procedure: copy with -compositingrule} {




    p1 blank
    p2 blank
    p1 put white -to 0 0 2 2
    p2 put white -to 0 0 2 2
    p2 transparency set 0 0 true
    p1 copy p2 -to 1 1 -compositingrule set
    checkImgTrans p1 3 3
} {0 2 1 1 2 0}


catch {rename checkImgTrans {}}
test imgPhoto-4.74 {ImgPhotoCmd procedure: put option error handling} -setup {
    image create photo photo1
} -body {
    photo1 put {{white}} -to 10 10 20 20 {{white}}
} -cleanup {
    image delete photo1
} -returnCodes error -result {wrong # args: should be "photo1 put data ?options?"}
test imgPhoto-4.75 {<photo> read command: filename starting with '-'} -constraints {
    hasTeapotPhoto
} -body {
    file copy -force $teapotPhotoFile -teapotPhotoFile
    image create photo photo1
    photo1 read -teapotPhotoFile
} -cleanup {
    image delete photo1
    file delete ./-teapotPhotoFile
} -result {}

































































































































































































































































































































































































































test imgPhoto-5.1 {ImgPhotoGet/Free procedures, shared instances} hasTeapotPhoto {

    eval image delete [image names]
    .c delete all



    image create photo p1 -file $teapotPhotoFile
    .c create image 0 0 -image p1 -tags p1.1
    .c create image 256 0 -image p1 -tags p1.2
    .c create image 0 256 -image p1 -tags p1.3
    update
    .c delete i1.1
    p1 configure -width 1
    update
    .c delete i1.2
    p1 configure -height 1
    update
    image delete p1
} {}



test imgPhoto-6.1 {ImgPhotoDisplay procedure, blank display} {
    .c delete all



    image create photo p1 -width 10 -height 10
    p1 blank
    .c create image 10 10 -image p1
    update
} {}




test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} hasTeapotPhoto {

    eval image delete [image names]
    .c delete all



    image create photo p1 -file $teapotPhotoFile
    .c create image 0 0 -image p1 -anchor nw
    update
    .c delete all
    image delete p1
} {}


test imgPhoto-7.2 {ImgPhotoFree procedures, unlinking} hasTeapotPhoto {





    image create photo p1 -file $teapotPhotoFile

    .c create image 10 10 -image p1 -anchor nw
    button .b1 -image p1
    button .b2 -image p1
    button .b3 -image p1
    pack .b1 .b2 .b3
    update
    destroy .b2
    update
    destroy .b3
    update
    destroy .b1
    update
    .c delete all
} {}



test imgPhoto-7.3 {ImgPhotoFree procedures, multiple visuals} hasTeapotPhoto {





    image create photo p1 -file $teapotPhotoFile
    button .b1 -image p1
    frame .f -visual best
    button .f.b2 -image p1
    pack .f.b2
    pack .b1 .f
    update
    destroy .b1
    update
    .f.b2 configure -image {}
    update
    destroy .f
    image delete p1
} {}

test imgPhoto-8.1 {ImgPhotoDelete procedure} hasTeapotPhoto {
    image create photo p2 -file $teapotPhotoFile
    image delete p2
} {}
test imagePhoto-8.2 {ImgPhotoDelete procedure} hasTeapotPhoto {




    image create photo p2 -file $teapotPhotoFile
    rename p2 newp2
    set x [list [info command p2] [info command new*] [newp2 cget -file]]
    image delete p2
    append x [info command new*]
} [list {} newp2 $teapotPhotoFile]
test imagePhoto-8.3 {ImgPhotoDelete procedure, name cleanup} {
    image create photo p1
    image create photo p2 -width 10 -height 10
    image delete p2
    list [catch {p1 copy p2} msg] $msg


} {1 {image "p2" doesn't exist or is not a photo image}}

test imagePhoto-9.1 {ImgPhotoCmdDeletedProc procedure} hasTeapotPhoto {


    image create photo p2 -file $teapotPhotoFile
    rename p2 {}
    list [lsearch -exact [image names] p2] [catch {p2 foo} msg] $msg
} {-1 1 {invalid command name "p2"}}

test imgPhoto-10.1 {Tk_ImgPhotoPutBlock procedure} {
    eval image delete [image names]

    image create photo p1
    p1 put {{#ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000}} -to 0 0
    p1 put {{#00ff00 #00ff00}} -to 2 0
    list [p1 get 2 0] [p1 get 3 0] [p1 get 4 0]
} {{0 255 0} {0 255 0} {255 0 0}}






































test imgPhoto-11.1 {Tk_FindPhoto} {
    eval image delete [image names]

    image create bitmap i1
    image create photo p1
    list [catch {p1 copy i1} msg] $msg


} {1 {image "i1" doesn't exist or is not a photo image}}

test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} hasTeapotPhoto {
    image create photo p3 -file $teapotPhotoFile
    set result [list [p3 get 50 50] [p3 get 100 100]]
    p3 copy p3 -zoom 2
    lappend result [image width p3] [image height p3] [p3 get 100 100]

    image delete p3
    set result
} {{19 92 192} {169 117 90} 512 512 {19 92 192}}




































test imgPhoto-13.1 {check separation of images in different interpreters} {
    image delete {*}[image names]
    set data {
	R0lGODlhQgBkAPUAANbWxs7Wxs7OxsbOxsbGxsbGvb3Gvca9vcDAwL21vbW1vbW1tbWtta2t
	ta2ltaWltaWlraWctaWcrZycrZyUrZSUrZSMrZSMpYyMrYyMpYyEpYSEpYR7pYR7nHp7pYRz
	pYRynHtzpXtznHtrnHNrnHNjnGtjnGtjlGtalGNalGNSlGNSjFpSlFpKlFpKjFJKjFJCjFI5
	jEo5jEo5hEoxhEIxhDkphDkhhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAQgBkAAAG
	/kCEcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vH7P
	7/v/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmOBZxXnAQEnKIIBUQJCguoDKkIBgWhpUev
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644

1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675


1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686

1687




1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701

1702


1703
1704
1705
1706
1707
1708
1709
1710
1711

1712



1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949



1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976



1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007

2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046


2047
2048
2049

2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
	arGTEQhIhE7QjLA+MKDOxClGwuoJtWi0uBIUIxjDSE2wQ4iHl7ywQDjGwZws/NcAlgBjaKQJ
	JDVuoQBeUeACoFkMcFqgQL1IgxpRSsjsqHA/gy0tHvmAx2z2BxIupaJrnVxCEAAAOw==
    }
    interp create x1
    interp create x2
    x1 eval {load {} Tk}
    x2 eval {load {} Tk}
} -body {
    x1 eval [list image create photo T1_data -data $data]
    x2 eval [list image create photo T1_data -data $data]
} -cleanup {

    interp delete x1
    interp delete x2
} -result T1_data

test imgPhoto-14.1 {GIF writes work correctly} -setup {
    set data {
	R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
	hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwP8AAAD/
	AP//AAAA//8A/wD//////ywAAAAAYwA5AAAI/wAZCBxIsKDBgwgTKlzIsKHD
	hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN
	mzhz6tzJs6fPn0CDCh1KtKhRiwoSKEXAtGlTpUqPGkyagOmCq1edNsWalWkC
	BUSXIuDqFepBqFWtZv3KU+zYrkrBSqT6dgECtjOTbu16NwFHvV3lshRLti/J
	qlgRCE6ZuO9ik4Dt+k0ZVyZiyVIvXr77ODPEy5g9T4zMWfTEzXdNz1VbWvXn
	uqldP1TAOrbshqBb314Y2W7n3Qdpv7UNPCHpycUVbv6dnODy5sqzQldIe8H0
	hciva9/Ovbv37+BzBgEEADs=
    }


    set tmpfilename [makeFile {} imgPhoto-14.1.gif]
    removeFile $tmpfilename
} -body {
    image create photo photo1 -data $data
    photo1 write $tmpfilename -format gif
    image create photo photo2 -file $tmpfilename
    string equal [photo1 data] [photo2 data]
} -cleanup {
    catch {image delete photo1 photo2}
    catch {file delete -force $tmpfilename}
} -result 1

test imgPhoto-14.2 {GIF -index handler buffer sizing} -setup {




    set data {
	R0lGODlhIAAgAKEAAPkOSQsi7////////yH/C05FVFNDQVBFMi4wAwEAAAAh
	+QQJMgAAACwGAAYAFAAUAAACEYyPqcvtD6OctNqLs968+68VACH5BAkyAAEA
	LAMAAwAaABoAAAI0jH+gq+gfmFzQzUsr3gBybn1gIm5kaUaoubbuC8fyTNel
	Ohv1CSO533u8KrgbUfc5Ci/EAgA7
    }
} -body {
    # Bug 1458234 makes this crash when trying to access buffers of the wrong
    # size, caused when the initial frame is not the largest frame.
    set i [image create photo]
    $i configure -data $data -format {gif -index 2}
} -cleanup {
    image delete $i
} -returnCodes error -result {no image data for this index}

test imgPhoto-14.3 {GIF -index interleaving and small frames} -body {


    # Interleaved GIFs used to crash us when a smaller subsequent frame was
    # accessed.
    set i [image create photo]
    $i configure -format {GIF -index 1} -data {
	R0lGODdhAQAFAPAAAP8AAAAAACwAAAAAAQAFAEACAoRdACwAAAAAAQAEAEACAoRRADs=
    }
} -cleanup {
    image delete $i
}

test imgPhoto-14.4 {GIF buffer overflow} -setup {



    set data {
	R0lGODlhCgAKAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/
	AP//AAAA//8A/wD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBmZgBm
	mQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/
	AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMz
	mTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPM
	ADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYA
	mWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZ
	AGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/
	mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lm
	AJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnM
	mZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wz
	AMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZ
	mcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8A
	AP8AM/8AZv8Amf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9m
	mf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///MAP/MM//MZv/Mmf/MzP/M////
	AP//M///Zv//mf//zP///yH5BAEAABAALAAAAAAKAAoAABUSAAD/HEiwoMGD
	CBMqXMiwYcKAADs=
    }
} -body {
    # This crashes Tk up to 8.4.17 and 8.5.0
    set i [image create photo]
    $i configure -data $data
} -cleanup {
    image delete $i
} -returnCodes error -result {malformed image}
test imgPhoto-14.5 {Bug [fbaed1f66b] - GIF decoder with deferred clear code} -setup {
    set fileName [file join [file dirname [info script]] deferredClearCode.gif]
} -body {
    # This erroneously produced "malformed image" error.
    # The animated GIF "deferredClearCode.gif" has two frames, and calling for -index 2
    # simply is an easy way to trigger the problem of improper management of a deferred
    # clear code. The effect was that the GIF decoder bailed out before the end of the
    # image reading, and produced the inappropriate "malformed image error".
    image create photo -file $fileName -format "gif -index 2"
} -returnCodes error -result {no image data for this index}

test imgPhoto-14.6 {Access Subimage after Subimage with buffer overflow. Ticket 4da2191b} -setup {
    set data {
	R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
	hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwP8AAAD/
	AP//AAAA//8A/wD//////ywAAAAAYwA5AAAI/wAZCBxIsKDBgwgTKlzIsKHD
	hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN
	mzhz6tzJs6fPn0CDCh1KtKhRiwoSKEXAtGlTpUqPGkyagOmCq1edNsWalWkC
	BUSXIuDqFepBqFWtZv3KU+zYrkrBSqT6dgECtjOTbu16NwFHvV3lshRLti/J
	qlgRCE6ZuO9ik4Dt+k0ZVyZiyVIvXr77ODPEy5g9T4zMWfTEzXdNz1VbWvXn
	uqldP1TAOrbshqBb314Y2W7n3Qdpv7UNPCHpycUVbv6dnODy5sqzQldIe8H0
	hciva9/Ovbv37+BzBgE7ACH5BAFkAAMALAAAAAAEAAQAAAMEKLrckgA7
    }
} -body {
    image create photo photo1 -data $data -format "GIF -index 1"
} -cleanup {
    catch {image delete photo1}
} -result photo1

test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
    nonPortable
} -body {
    # This is not portable to very large machines with more than around 3GB of
    # free memory available...
    image create photo -width 32000 -height 32000
} -returnCodes error -result {not enough free memory for image buffer}

test imgPhoto-16.1 {copying to self doesn't access freed memory} -setup {
    set i [image create photo]
} -body {
    # Bug 877950 makes this crash when trying to copy out of a deallocated
    # area.
    $i put red -to 0 0 1000 1000
    $i copy $i -from 0 0 1000 1000 -to 500 0
} -cleanup {
    image delete $i
} -result {}

# Check that we can guess our supported output formats [Bug 2983824]
test imgPhoto-17.1 {photo write: format guessing from filename} -setup {
    set i [image create photo -width 3 -height 3]
} -body {
    set f [makeFile {} test.png]
    $i write $f
    set fd [open $f]
    seek $fd 1
    read $fd 3
} -cleanup {
    catch {close $fd}
    image delete $i
    catch {removeFile $f}
} -result PNG
test imgPhoto-17.2 {photo write: format guessing from filename} -setup {
    set i [image create photo -width 3 -height 3]
} -body {
    set f [makeFile {} test.gif]
    $i write $f
    set fd [open $f]
    read $fd 3
} -cleanup {
    catch {close $fd}
    image delete $i
    catch {removeFile $f}
} -result GIF
test imgPhoto-17.3 {photo write: format guessing from filename} -setup {
    set i [image create photo -width 3 -height 3]
} -body {
    set f [makeFile {} test.ppm]
    $i write $f
    set fd [open $f]
    read $fd 3
} -cleanup {
    catch {close $fd}
    image delete $i
    catch {removeFile $f}
} -result "P6\n"
test imgPhoto-17.4 {photo write: default format not supported} -setup {
    image create photo photo1 -data {{blue blue} {red red} {green green}}
    set f [makeFile {} test.txt]
} -body {
    photo1 write $f -format default
} -cleanup {
    imageCleanup
    catch {removeFile $f}
    unset f
} -returnCodes error -result \
    {image file format "default" has no file writing capability}
test imgPhoto-17.5 {photo write: file with extension .default} -setup {
    image create photo photo1 -data {{black}}
    set f [makeFile {} test.default]
} -body {
    photo1 write $f
} -cleanup {
    imageCleanup
    catch {removeFile $f}
    unset f
} -returnCodes error -result \
    {image file format "default" has no file writing capability}

test imgPhoto-18.1 {MatchFileFormat: "default" format not supported} -setup {
    image create photo photo1
    set f [makeFile {} test.txt]
} -body {
    photo1 read $f -format default
} -cleanup {
    imageCleanup
    catch {removeFile $f}
    unset f
} -returnCodes error -result {-file option isn't supported for default images}

test imgPhoto-19.1 {MatchStringFormat: with "-format default"} -setup {
    image create photo photo1
} -body {
    photo1 put {{red blue red} {yellow green yellow}} -format default
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {3 2}
test imgPhoto-19.2 {MatchStringFormat: without -format option,
        default fmt} -body {
    image create photo photo1
    photo1 put {{red} {green}}
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {1 2}
test imgPhoto-19.3 {MatchStringFormat: "-format ppm"} -setup {
    image create photo photo1
    image create photo photo2
    photo2 put {cyan cyan}
    set imgData [photo2 data -format ppm]
} -body {
    photo1 put $imgData -format ppm
    list [image width photo1] [image height photo1]
} -cleanup {
    unset imgData
    imageCleanup
} -result {1 2}
test imgPhoto-19.4 {MatchStringFormat: ppm fmt, without opt} -constraints {
    hasTeapotPhoto
} -setup {
    image create photo photo1 -file $teapotPhotoFile
    image create photo photo2
} -body {
    set imgData [photo1 data -format ppm]
    photo2 put $imgData
    list [image width photo2] [image height photo2]
} -cleanup {
    imageCleanup
    unset imgData
} -result {256 256}
test imgPhoto-19.5 {MatchStirngFormat: unknown -format} -setup {
    image create photo photo1
} -body {
    photo1 put {} -format bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result {image format "bogus" is not supported}
test imgPhoto-19.6 {MatchStringFormat: invalid data for default} -setup {
    image create photo photo1
} -body {
    photo1 put bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "bogus"}
test imgPhoto-19.7 {MatchStringFormat: invalid data for default} -setup {
    image create photo photo1
} -body {
    photo1 put bogus -format dEFault
} -cleanup {
    imageCleanup
} -returnCodes error -result {invalid color name "bogus"}
test imgPhoto-19.8 {MatchStirngFormat: invalid data for gif} -setup {
    image create photo photo1
} -body {
    photo1 put bogus -format giF
} -cleanup {
    imageCleanup
} -returnCodes error -result {couldn't recognize image data}

# Reject corrupted or truncated image [Bug b601ce3ab1].
# WARNING - tests 20.1-20.9 will cause a segfault on 8.5.19 and lower,
#           and on 8.6.6 and lower.
test imgPhoto-20.1 {Reject corrupted GIF (binary string)} -setup {



    set data [binary decode base64 {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.2 {Reject corrupted GIF (base 64 string)} -setup {
    set data {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.3 {Reject corrupted GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptMangled.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.4 {Reject truncated GIF (binary string)} -setup {



    set data [binary decode base64 {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-20.5 {Reject truncated GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-20.6 {Reject truncated GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptTruncated.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-20.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.

    set data [binary decode base64 {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.8 {Reject corrupted GIF (> 4Gb) (base 64 string)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set data {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.9 {Reject corrupted GIF (> 4Gb) (file)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set fileName [file join [file dirname [info script]] corruptMangled4G.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-20.10 {Valid GIF (binary string)} -setup {


    # Test the binary string reader with a valid GIF.
    # This is not tested elsewhere.
    # Tests 20.11, 20.12, with matching data, are included for completeness.

    set data [binary decode base64 {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-20.11 {Valid GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-20.12 {Valid GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] red.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -result gif1

catch {rename foreachPixel {}}
catch {rename checkImgTrans {}}
catch {rename checkImgTransLoop {}}
imageFinish

# cleanup
removeFile README-imgPhoto
cleanupTests
return

# Local variables:
# mode: tcl
# End:







<


<
>


|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
>
|
|
<
<
|
|
|
<
|
|
|
>

>
>
>
>






<
<
<
<




>
|
>
>
|
|
<






>

>
>
>
|




















<
<
<
<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
|
|
|
|
|
<
<
|
|


<

<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|

|
>
>
>
|








|









|






|
>
>
>
|







|








|






|
|





>
|








|















|












|
>
>


|
>
|








|









|







|
<
<
|





<
<
<
<
613
614
615
616
617
618
619

620
621

622
623
624
625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655


656
657
658

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673




674
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715




716
717
718
719
720
721
722
723
724
725
726
727
728
729

































730
731

732
733
734
735
736
737


738
739
740
741

742

743




























































744

















































































745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886


887
888
889
890
891
892




	arGTEQhIhE7QjLA+MKDOxClGwuoJtWi0uBIUIxjDSE2wQ4iHl7ywQDjGwZws/NcAlgBjaKQJ
	JDVuoQBeUeACoFkMcFqgQL1IgxpRSsjsqHA/gy0tHvmAx2z2BxIupaJrnVxCEAAAOw==
    }
    interp create x1
    interp create x2
    x1 eval {load {} Tk}
    x2 eval {load {} Tk}

    x1 eval [list image create photo T1_data -data $data]
    x2 eval [list image create photo T1_data -data $data]

    unset data
    interp delete x1
    interp delete x2
} {}

test imgPhoto-14.1 {GIF writes work correctly} {

    set data "R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwP8AAAD/
AP//AAAA//8A/wD//////ywAAAAAYwA5AAAI/wAZCBxIsKDBgwgTKlzIsKHD
hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN
mzhz6tzJs6fPn0CDCh1KtKhRiwoSKEXAtGlTpUqPGkyagOmCq1edNsWalWkC
BUSXIuDqFepBqFWtZv3KU+zYrkrBSqT6dgECtjOTbu16NwFHvV3lshRLti/J
qlgRCE6ZuO9ik4Dt+k0ZVyZiyVIvXr77ODPEy5g9T4zMWfTEzXdNz1VbWvXn
uqldP1TAOrbshqBb314Y2W7n3Qdpv7UNPCHpycUVbv6dnODy5sqzQldIe8H0
hciva9/Ovbv37+BzBgEEADs=

"
    set photo [image create photo -data $data]
    set filename [makeFile {} imgPhoto-14.1.gif]
    removeFile imgPhoto-14.1.gif


    $photo write $filename -format gif
    set photo2 [image create photo -file $filename]
    set result [string equal [$photo data] [$photo2 data]]

    image delete $photo $photo2
    catch {file delete -force $filename}
    set result
} 1
test imgPhoto-14.2 {GIF -index handler buffer sizing} -setup {
    set i [image create photo]
} -body {
    # Bug 1458234 makes this crash when trying to access buffers of the
    # wrong size, caused when the initial frame is not the largest frame.
    set data {
	R0lGODlhIAAgAKEAAPkOSQsi7////////yH/C05FVFNDQVBFMi4wAwEAAAAh
	+QQJMgAAACwGAAYAFAAUAAACEYyPqcvtD6OctNqLs968+68VACH5BAkyAAEA
	LAMAAwAaABoAAAI0jH+gq+gfmFzQzUsr3gBybn1gIm5kaUaoubbuC8fyTNel
	Ohv1CSO533u8KrgbUfc5Ci/EAgA7
    }




    $i configure -data $data -format {gif -index 2}
} -cleanup {
    image delete $i
} -returnCodes error -result {no image data for this index}

test imgPhoto-14.3 {GIF -index interleaving and small frames} -setup {
    set i [image create photo]
} -body {
    # Interleaved GIFs used to crash us when a smaller subsequent frame
    # was accessed.

    $i configure -format {GIF -index 1} -data {
	R0lGODdhAQAFAPAAAP8AAAAAACwAAAAAAQAFAEACAoRdACwAAAAAAQAEAEACAoRRADs=
    }
} -cleanup {
    image delete $i
}

test imgPhoto-14.4 {GIF buffer overflow} -setup {
    set i [image create photo]
} -body {
    # This crashes Tk up to 8.4.17 and 8.5.0
    $i configure -data {
	R0lGODlhCgAKAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/
	AP//AAAA//8A/wD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBmZgBm
	mQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/
	AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMz
	mTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPM
	ADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYA
	mWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZ
	AGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/
	mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lm
	AJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnM
	mZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wz
	AMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZ
	mcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8A
	AP8AM/8AZv8Amf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9m
	mf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///MAP/MM//MZv/Mmf/MzP/M////
	AP//M///Zv//mf//zP///yH5BAEAABAALAAAAAAKAAoAABUSAAD/HEiwoMGD
	CBMqXMiwYcKAADs=
    }




} -cleanup {
    image delete $i
} -returnCodes error -result {malformed image}
test imgPhoto-14.5 {Bug [fbaed1f66b] - GIF decoder with deferred clear code} -setup {
    set fileName [file join [file dirname [info script]] deferredClearCode.gif]
} -body {
    # This erroneously produced "malformed image" error.
    # The animated GIF "deferredClearCode.gif" has two frames, and calling for -index 2
    # simply is an easy way to trigger the problem of improper management of a deferred
    # clear code. The effect was that the GIF decoder bailed out before the end of the
    # image reading, and produced the inappropriate "malformed image error".
    image create photo -file $fileName -format "gif -index 2"
} -returnCodes error -result {no image data for this index}


































test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} \
	{nonPortable} {

    # This is not portable to very large machines with more around
    # 3GB of free memory available...
    list [catch {image create photo -width 32000 -height 32000} msg] $msg
} {1 {not enough free memory for image buffer}}

test imgPhoto-16.1 {copying to self doesn't access freed memory} {


    # Bug 877950 makes this crash when trying to copy out of a deallocated area
    set i [image create photo]
    $i put red -to 0 0 1000 1000
    $i copy $i -from 0 0 1000 1000 -to 500 0

    image delete $i

} {}














































































































































# Reject corrupted or truncated image [Bug b601ce3ab1].
# WARNING - tests 18.1-18.9 will cause a segfault on 8.5.19 and lower,
#           and on 8.6.6 and lower.
test imgPhoto-18.1 {Reject corrupted GIF (binary string)} -constraints {
    base64PackageNeeded
} -setup {
    package require base64
    set data [base64::decode {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.2 {Reject corrupted GIF (base 64 string)} -setup {
    set data {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.3 {Reject corrupted GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptMangled.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.4 {Reject truncated GIF (binary string)} -constraints {
    base64PackageNeeded
} -setup {
    package require base64
    set data [base64::decode {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.5 {Reject truncated GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.6 {Reject truncated GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptTruncated.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints {
    base64PackageNeeded nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    package require base64
    set data [base64::decode {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.8 {Reject corrupted GIF (> 4Gb) (base 64 string)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set data {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.9 {Reject corrupted GIF (> 4Gb) (file)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set fileName [file join [file dirname [info script]] corruptMangled4G.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.10 {Valid GIF (binary string)} -constraints {
    base64PackageNeeded
} -setup {
    # Test the binary string reader with a valid GIF.
    # This is not tested elsewhere.
    # Tests 18.11, 18.12, with matching data, are included for completeness.
    package require base64
    set data [base64::decode {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-18.11 {Valid GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-18.12 {Valid GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] red.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -result gif1

destroy .c


eval image delete [image names]

# cleanup
removeFile README-imgPhoto
cleanupTests
return




Deleted tests/imgSVGnano.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# This file is a Tcl script to test out the code in tkImgSVGnano.c, which reads
# and write SVG-format image files for photo widgets. The files is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 2018 Rene Zaumseil
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

namespace eval svgnano {
    variable data
    set data(plus) {<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<path fill="none" stroke="#000000" d="M0 0 h16 v16 h-16 z"/>
<path fill="none" stroke="#000000" d="M8 4 v 8 M4 8 h 8"/>
<circle fill="yellow" stroke="red" cx="10" cy="80" r="10" />
<ellipse fill="none" stroke="blue" stroke-width="3" cx="60" cy="60" rx="10" ry="20" />
<line x1="10" y1="90" x2="50" y2="99"/>
<rect fill="none" stroke="green"  x="20" y="20" width="60" height="50" rx="3" ry="3"/>
<polyline fill="red" stroke="purple" points="80,10 90,20 85,40"/>
<polygon fill ="yellow" points="80,80 70,85 90,90"/>
</svg>}
    set data(bad) {<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0:w
">
</svg>}

    tcltest::makeFile $data(plus) plus.svg
    set data(plusFilePath) [file join [tcltest::configure -tmpdir] plus.svg]

    tcltest::makeFile $data(bad) bad.svg
    set data(badFilePath) [file join [tcltest::configure -tmpdir] bad.svg]

test imgSVGnano-1.1 {reading simple image} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {100 100}

test imgSVGnano-1.2 {simple image with options} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus) -format {svg -dpi 100 -scale 3}
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {300 300}

# test on crash found by Koen Danckaert
test imgSVGnano-1.3 {reformat image options} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus)
    catch {foo configure -format {svg -scale}}
    list {}
} -cleanup {
    rename foo ""
} -result {{}}

test imgSVGnano-1.4 {image options} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus)
    foo configure -format {svg -scale 2}
    foo configure -format {svg -dpi 600}
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {100 100}
test imgSVGnano-1.5 {reading simple image from file} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -file $data(plusFilePath)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {100 100}

test imgSVGnano-1.6 {simple image with options} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -file $data(plusFilePath) -format {svg -dpi 100 -scale 3}
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {300 300}
test imgSVGnano-1.7 {Very small scale gives 1x1 image} -body {
    image create photo foo -format "svg -scale 0.000001"\
	    -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}
test imgSVGnano-1.8 {Very small scale gives 1x1 image from file} -body {
    image create photo foo -format "svg -scale 0.000001"\
	    -file $data(plusFilePath)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}

test imgSVGnano-2.1 {reading a bad image} -body {
    image create photo foo -format svg -data $data(bad)
} -returnCodes error -result {couldn't recognize image data}
test imgSVGnano-2.2 {using bad option} -body {
    image create photo foo -data $data(plus) -format {svg -scale 0}
} -returnCodes error -result {-scale value must be positive}
test imgSVGnano-2.3 {using bad option} -body {
    image create photo foo -data $data(plus)
    foo configure -format {svg 1.0}
} -cleanup {
    rename foo ""
} -returnCodes error -result {bad option "1.0": must be -dpi, -scale, -scaletoheight, or -scaletowidth}
test imgSVGnano-2.4 {reading a bad image from file} -body {
    image create photo foo -format svg -file $data(badFilePath)
} -returnCodes error -match glob\
    -result {couldn't recognize data in image file "*/bad.svg"}

# -scaletoheight and -scaletowidth options
test imgSVGnano-3.1 {multiple scale options} -body {
    image create photo foo -format "svg -scale 1 -scaletowidth 20"\
	    -data $data(bad)
} -returnCodes error -result {only one of -scale, -scaletoheight, -scaletowidth may be given}

test imgSVGnano-3.2 {no number parameter to -scaletowidth} -body {
    image create photo foo -format "svg -scaletowidth invalid"\
	    -data $data(plus)
} -returnCodes error -result {expected integer but got "invalid"}

test imgSVGnano-3.3 {no number parameter to -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight invalid"\
	    -data $data(plus)
} -returnCodes error -result {expected integer but got "invalid"}

test imgSVGnano-3.4 {zero parameter to -scaletowidth} -body {
    image create photo foo -format "svg -scaletowidth 0"\
	    -data $data(plus)
} -returnCodes error -result {-scaletowidth value must be positive}

test imgSVGnano-3.5 {zero parameter to -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight 0"\
	    -data $data(plus)
} -returnCodes error -result {-scaletoheight value must be positive}

test imgSVGnano-3.6 {no number parameter to -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight invalid"\
	    -data $data(plus)
} -returnCodes error -result {expected integer but got "invalid"}

test imgSVGnano-3.7 {Option -scaletowidth} -body {
    image create photo foo -format "svg -scaletowidth 20"\
	    -data $data(plus)
    image width foo
} -cleanup {
    rename foo ""
} -result 20

test imgSVGnano-3.8 {Option -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight 20"\
	    -data $data(plus)
    image height foo
} -cleanup {
    rename foo ""
} -result 20

test imgSVGnano-3.10 {change from -scaletoheight to -scale} -body {
    set res {}
    image create photo foo -format "svg -scaletoheight 16"\
	    -data $data(plus)
    lappend res [image width foo] [image height foo]
    foo configure -format "svg -scale 2"
    lappend res [image width foo] [image height foo]
} -cleanup {
    rename foo ""
    unset res
} -result {16 16 200 200}

# svg file access
test imgSVGnano-4.1 {reread file on configure -scale} -setup {
    catch {rename foo ""}
    set res {}
} -body {
    image create photo foo -file $data(plusFilePath)
    lappend res [image width foo] [image height foo]
    foo configure -format "svg -scale 2"
    lappend res [image width foo] [image height foo]
} -cleanup {
    rename foo ""
    unset res
} -result {100 100 200 200}


test imgSVGnano-4.2 {error on file not accessible on reread due to configure} -setup {
    catch {rename foo ""}
    tcltest::makeFile $data(plus) tmpplus.svg
    image create photo foo -file [file join [tcltest::configure -tmpdir] tmpplus.svg]
    tcltest::removeFile tmpplus.svg
} -body {
    foo configure -format "svg -scale 2"
} -cleanup {
    rename foo ""
    tcltest::removeFile tmpplus.svg
} -returnCodes error -match glob -result {couldn't open "*/tmpplus.svg": no such file or directory}

# Special images
test imgSVGnano-5.0 {image without any of  "width", "height" and "viewbox"} -body {
    image create photo foo -data\
			{<?xml version="1.0"?><!DOCTYPE svg PUBLIC\
			"-//W3C//DTD SVG 1.0//EN\"\
			"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\
			<svg xmlns="http://www.w3.org/2000/svg">\
			<g style="fill-opacity:0.7;">\
			<circle cx="6.5cm" cy="2cm" r="100" style="fill:green;\
			stroke:black; stroke-width:0.1cm" transform="translate(-70,150)"/>\
			</g></svg>}
} -cleanup {
    rename foo ""
} -result {foo}

test imgSVGnano-5.1 {bug ea665e08f3 - too many values in parameters of the transform attribute} -body {
    # shall not loop endlessly
    image create photo foo -data\
			{<?xml version="1.0"?><!DOCTYPE svg PUBLIC\
			"-//W3C//DTD SVG 1.0//EN\"\
			"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\
			<svg xmlns="http://www.w3.org/2000/svg">\
			<circle cx="6.5cm" cy="2cm" r="100" transform="skewX(1 1)"/>\
			</g></svg>}
} -cleanup {
    rename foo ""
} -result {foo}

};# end of namespace svgnano

namespace delete svgnano
imageFinish
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































Changes to tests/listbox.test.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
# This file is a Tcl script to test out the "listbox" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


set fixed {Courier -12}

proc record {name args} {
    global log
    lappend log [format {%s %.6g %.6g} $name {*}$args]
}



|
|
|





|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# This file is a Tcl script to test out the "listbox" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# 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.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

set fixed {Courier -12}

proc record {name args} {
    global log
    lappend log [format {%s %.6g %.6g} $name {*}$args]
}
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164



165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994


995
996
997
998
999

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120


1121
1122


1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185



1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939


1940

1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001

2002
2003
2004
2005
2006
2007

2008






2009
2010
2011

2012


2013




2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058

2059

2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359

2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462

2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477

2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526


2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560


2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681

2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708






2709


2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761

2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778

2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880

2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906

2907


2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932

2933
2934

2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
    wm deiconify .
}

# Procedure that creates a second listbox for checking things related
# to partially visible lines.

proc mkPartial {{w .partial}} {
    destroy $w
    toplevel $w
    wm geometry $w +0+0
    listbox $w.l -width 30 -height 5
    pack $w.l -expand 1 -fill both
    $w.l insert end one two three four five six seven eight nine ten \
	    eleven twelve thirteen fourteen fifteen
    update
    scan [wm geometry $w] "%dx%d" width height
    wm geometry $w ${width}x[expr $height-3]
    update
}

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Listbox.borderWidth 2
option add *Listbox.selectBorderWidth 1
option add *Listbox.highlightThickness 2
option add *Listbox.font {Helvetica -12 bold}

# Listbox used in 3.* configuration options tests
listbox .l
pack .l
update
resetGridInfo
test listbox-1.1 {configuration options} -body {
    .l configure -activestyle under
    list [lindex [.l configure -activestyle] 4] [.l cget -activestyle]
} -cleanup {
    .l configure -activestyle [lindex [.l configure -activestyle] 3]
} -result {underline underline}
test listbox-1.2 {configuration options} -body {
    .l configure -activestyle foo
} -returnCodes error -result {bad activestyle "foo": must be dotbox, none, or underline}
test listbox-1.3 {configuration options} -body {
    .l configure -background #ff0000
    list [lindex [.l configure -background] 4] [.l cget -background]
} -cleanup {
    .l configure -background [lindex [.l configure -background] 3]
} -result {{#ff0000} #ff0000}
test listbox-1.4 {configuration options} -body {
    .l configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-1.5 {configuration options} -body {
    .l configure -bd 4
    list [lindex [.l configure -bd] 4] [.l cget -bd]
} -cleanup {
    .l configure -bd [lindex [.l configure -bd] 3]
} -result {4 4}
test listbox-1.6 {configuration options} -body {
    .l configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.7 {configuration options} -body {
    .l configure -bg #ff0000
    list [lindex [.l configure -bg] 4] [.l cget -bg]
} -cleanup {
    .l configure -bg [lindex [.l configure -bg] 3]
} -result {{#ff0000} #ff0000}
test listbox-1.8 {configuration options} -body {
    .l configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-1.9 {configuration options} -body {
    .l configure -borderwidth 1.3
    list [lindex [.l configure -borderwidth] 4] [.l cget -borderwidth]
} -cleanup {
    .l configure -borderwidth [lindex [.l configure -borderwidth] 3]
} -result {1 1}
test listbox-1.10 {configuration options} -body {
    .l configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.11 {configuration options} -body {
    .l configure -cursor arrow
    list [lindex [.l configure -cursor] 4] [.l cget -cursor]
} -cleanup {
    .l configure -cursor [lindex [.l configure -cursor] 3]
} -result {arrow arrow}
test listbox-1.12 {configuration options} -body {
    .l configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test listbox-1.13 {configuration options} -body {
    .l configure -disabledforeground #110022
    list [lindex [.l configure -disabledforeground] 4] [.l cget -disabledforeground]
} -cleanup {
    .l configure -disabledforeground [lindex [.l configure -disabledforeground] 3]
} -result {{#110022} #110022}
test listbox-1.14 {configuration options} -body {
    .l configure -disabledforeground bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-1.15 {configuration options} -body {
    .l configure -exportselection yes
    list [lindex [.l configure -exportselection] 4] [.l cget -exportselection]
} -cleanup {
    .l configure -exportselection [lindex [.l configure -exportselection] 3]
} -result {1 1}
test listbox-1.16 {configuration options} -body {
    .l configure -exportselection xyzzy
} -returnCodes error -result {expected boolean value but got "xyzzy"}
test listbox-1.17 {configuration options} -body {
    .l configure -fg #110022
    list [lindex [.l configure -fg] 4] [.l cget -fg]
} -cleanup {
    .l configure -fg [lindex [.l configure -fg] 3]
} -result {{#110022} #110022}
test listbox-1.18 {configuration options} -body {
    .l configure -fg bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-1.19 {configuration options} -body {
    .l configure -font {Helvetica 12}
    list [lindex [.l configure -font] 4] [.l cget -font]
} -cleanup {
    .l configure -font [lindex [.l configure -font] 3]
} -result {{Helvetica 12} {Helvetica 12}}
test listbox-1.21 {configuration options} -body {
    .l configure -foreground #110022
    list [lindex [.l configure -foreground] 4] [.l cget -foreground]
} -cleanup {
    .l configure -foreground [lindex [.l configure -foreground] 3]
} -result {{#110022} #110022}
test listbox-1.22 {configuration options} -body {

    .l configure -foreground bogus
} -returnCodes error -result {unknown color name "bogus"}



test listbox-1.23 {configuration options} -body {
    .l configure -height 30
    list [lindex [.l configure -height] 4] [.l cget -height]
} -cleanup {
    .l configure -height [lindex [.l configure -height] 3]
} -result {30 30}
test listbox-1.24 {configuration options} -body {
    .l configure -height 20p
} -returnCodes error -result {expected integer but got "20p"}

test listbox-1.25 {configuration options} -body {
    .l configure -highlightbackground #112233
    list [lindex [.l configure -highlightbackground] 4] [.l cget -highlightbackground]
} -cleanup {
    .l configure -highlightbackground [lindex [.l configure -highlightbackground] 3]
} -result {{#112233} #112233}
test listbox-1.26 {configuration options} -body {
    .l configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test listbox-1.27 {configuration options} -body {
    .l configure -highlightcolor #123456
    list [lindex [.l configure -highlightcolor] 4] [.l cget -highlightcolor]
} -cleanup {
    .l configure -highlightcolor [lindex [.l configure -highlightcolor] 3]
} -result {{#123456} #123456}
test listbox-1.28 {configuration options} -body {
    .l configure -highlightcolor bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-1.29 {configuration options} -body {
    .l configure -highlightthickness 6
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {6 6}
test listbox-1.30 {configuration options} -body {
    .l configure -highlightthickness bogus
} -returnCodes error -result {bad screen distance "bogus"}
test listbox-1.31 {configuration options} -body {
    .l configure -highlightthickness -2
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {0 0}
test listbox-1.32.1 {configuration options} -setup {
    set res {}
} -body {
    .l configure -justify left
    set res [list [lindex [.l configure -justify] 4] [.l cget -justify]]
    .l configure -justify center
    lappend res [lindex [.l configure -justify] 4] [.l cget -justify]
    .l configure -justify right
    lappend res [lindex [.l configure -justify] 4] [.l cget -justify]
} -cleanup {
    .l configure -justify [lindex [.l configure -justify] 3]
} -result {left left center center right right}
test listbox-1.32.2 {configuration options} -body {
    .l configure -justify bogus
} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
test listbox-1.33 {configuration options} -body {
    .l configure -relief groove
    list [lindex [.l configure -relief] 4] [.l cget -relief]
} -cleanup {
    .l configure -relief [lindex [.l configure -relief] 3]
} -result {groove groove}
test listbox-1.34 {configuration options} -body {
    .l configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test listbox-1.35 {configuration options} -body {
    .l configure -selectbackground #110022
    list [lindex [.l configure -selectbackground] 4] [.l cget -selectbackground]
} -cleanup {
    .l configure -selectbackground [lindex [.l configure -selectbackground] 3]
} -result {{#110022} #110022}
test listbox-1.36 {configuration options} -body {
    .l configure -selectbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-1.37 {configuration options} -body {
    .l configure -selectborderwidth 1.3
    list [lindex [.l configure -selectborderwidth] 4] [.l cget -selectborderwidth]
} -cleanup {
    .l configure -selectborderwidth [lindex [.l configure -selectborderwidth] 3]
} -result {1 1}
test listbox-1.38 {configuration options} -body {
    .l configure -selectborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.39 {configuration options} -body {
    .l configure -selectforeground #654321

    list [lindex [.l configure -selectforeground] 4] [.l cget -selectforeground]
} -cleanup {
    .l configure -selectforeground [lindex [.l configure -selectforeground] 3]
} -result {{#654321} #654321}
test listbox-1.40 {configuration options} -body {
    .l configure -selectforeground bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-1.41 {configuration options} -body {
    .l configure -selectmode string
    list [lindex [.l configure -selectmode] 4] [.l cget -selectmode]

} -cleanup {
    .l configure -selectmode [lindex [.l configure -selectmode] 3]
} -result {string string}
test listbox-1.43 {configuration options} -body {
    .l configure -setgrid false
    list [lindex [.l configure -setgrid] 4] [.l cget -setgrid]
} -cleanup {
    .l configure -setgrid [lindex [.l configure -setgrid] 3]
} -result {0 0}
test listbox-1.44 {configuration options} -body {
    .l configure -setgrid lousy
} -returnCodes error -result {expected boolean value but got "lousy"}
test listbox-1.45 {configuration options} -body {
    .l configure -state disabled
    list [lindex [.l configure -state] 4] [.l cget -state]
} -cleanup {
    .l configure -state [lindex [.l configure -state] 3]
} -result {disabled disabled}
test listbox-1.46 {configuration options} -body {
    .l configure -state foo
} -returnCodes error -result {bad state "foo": must be disabled or normal}
test listbox-1.47 {configuration options} -body {
    .l configure -takefocus {any string}
    list [lindex [.l configure -takefocus] 4] [.l cget -takefocus]
} -cleanup {
    .l configure -takefocus [lindex [.l configure -takefocus] 3]
} -result {{any string} {any string}}
test listbox-1.49 {configuration options} -body {
    .l configure -width 45
    list [lindex [.l configure -width] 4] [.l cget -width]
} -cleanup {
    .l configure -width [lindex [.l configure -width] 3]
} -result {45 45}
test listbox-1.50 {configuration options} -body {
    .l configure -width 3p
} -returnCodes error -result {expected integer but got "3p"}
test listbox-1.51 {configuration options} -body {
    .l configure -xscrollcommand {Some command}
    list [lindex [.l configure -xscrollcommand] 4] [.l cget -xscrollcommand]
} -cleanup {
    .l configure -xscrollcommand [lindex [.l configure -xscrollcommand] 3]
} -result {{Some command} {Some command}}
test listbox-1.53 {configuration options} -body {
    .l configure -yscrollcommand {Another command}
    list [lindex [.l configure -yscrollcommand] 4] [.l cget -yscrollcommand]
} -cleanup {
    .l configure -yscrollcommand [lindex [.l configure -yscrollcommand] 3]
} -result {{Another command} {Another command}}
test listbox-1.55 {configuration options} -body {
    .l configure -listvar testVariable
    list [lindex [.l configure -listvar] 4] [.l cget -listvar]
} -cleanup {
    .l configure -listvar [lindex [.l configure -listvar] 3]
} -result {testVariable testVariable}


test listbox-2.1 {Tk_ListboxCmd procedure} -body {
    listbox
} -returnCodes error -result {wrong # args: should be "listbox pathName ?-option value ...?"}
test listbox-2.2 {Tk_ListboxCmd procedure} -body {
    listbox gorp
} -returnCodes error -result {bad window path name "gorp"}
test listbox-2.3 {Tk_ListboxCmd procedure} -setup {
    destroy .l
} -body {
    listbox .l
    list [winfo exists .l] [winfo class .l] [info commands .l]
} -result {1 Listbox .l}
test listbox-2.4 {Tk_ListboxCmd procedure} -setup {
    destroy .l
} -body {
    listbox .l -gorp foo
} -cleanup {
    destroy .l
} -returnCodes error -result {unknown option "-gorp"}
test listbox-2.4.1 {Tk_ListboxCmd procedure} -setup {
    destroy .l
} -body {
    catch {listbox .l -gorp foo}
    list [winfo exists .l] [info commands .l]
} -cleanup {
    destroy .l
} -result {0 {}}
test listbox-2.5 {Tk_ListboxCmd procedure} -setup {
    destroy .l
} -body {
    listbox .l
} -cleanup {
    destroy .l
} -result {.l}


# Listbox used in 3.1 -3.115 tests
destroy .l
listbox .l -width 20 -height 5 -bd 4 -highlightthickness 1 -selectborderwidth 2
pack .l
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11 el12 el13 el14 \
	el15 el16 el17
update
test listbox-3.1 {ListboxWidgetCmd procedure} -body {
    .l
} -returnCodes error -result {wrong # args: should be ".l option ?arg ...?"}
test listbox-3.2 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.3 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate a b
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.4 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}
test listbox-3.5 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 3
    .l index active
} -result 3
test listbox-3.6 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate -1
    .l index active
} -result 0
test listbox-3.7 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 30
    .l index active
} -result 17
test listbox-3.8 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate end
    .l index active
} -result 17
test listbox-3.9 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.10 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox a b
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.11 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}
test listbox-3.12 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l yview 3
    update
    list [.l bbox 2] [.l bbox 8]
} -result {{} {}}
test listbox-3.13 {ListboxWidgetCmd procedure, "bbox" option} -cleanup {
    destroy .l2
} -body {
    # Used to generate a core dump before a bug was fixed (the last
    # element would be on-screen if it existed, but it doesn't exist).

    listbox .l2
    pack .l2 -side top
    tkwait visibility .l2
    set x [.l2 bbox 0]
    destroy .l2
    set x
} -cleanup {
    destroy .l2
} -result {}
test listbox-3.14 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview 3
    update
    list [.l bbox 3] [.l bbox 4]
} -result {{7 7 17 14} {7 26 17 14}}
test listbox-3.15 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview 0
    update
    list [.l bbox -1] [.l bbox 0]
} -result {{} {7 7 17 14}}
test listbox-3.16 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview end
    update
    list [.l bbox 17] [.l bbox end] [.l bbox 18]
} -result {{7 83 24 14} {7 83 24 14} {}}
test listbox-3.17 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -setup {
    destroy .t
} -body {
    toplevel .t
    wm geom .t +0+0
    listbox .t.l -width 10 -height 5
    .t.l insert 0 "Short" "Somewhat longer" "Really, quite a whole lot longer than can possibly fit on the screen" "Short"
    pack .t.l
    update
    .t.l xview moveto .2
    .t.l bbox 2
} -cleanup {
    destroy .t
} -result {-72 39 393 14}
test listbox-3.18 {ListboxWidgetCmd procedure, "bbox" option, partial last line} -constraints {
	fonts
} -body {
    mkPartial
    list [.partial.l bbox 3] [.partial.l bbox 4]
} -result {{5 56 24 14} {5 73 23 14}}
test listbox-3.18a {ListboxWidgetCmd procedure, "bbox" option, justified} -constraints {
	fonts
} -setup {
    destroy .top.l .top
    unset -nocomplain res
} -body {
    toplevel .top
    listbox .top.l -justify left
    .top.l insert end Item1 LongerItem2 MuchLongerItem3
    pack .top.l
    update
    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
    .top.l configure -justify center
    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
    .top.l configure -justify right
    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
} -cleanup {
    destroy .top.l .top
    unset -nocomplain res
} -result [list \
    {5 5 34 14} {5 22 74 14} {5 39 106 14}     \
    {58 5 34 14} {38 22 74 14} {22 39 106 14}  \
    {111 5 34 14} {71 22 74 14} {39 39 106 14} \
]
test listbox-3.18b {ListboxWidgetCmd procedure, "bbox" option, justified, non-default borderwidth} -setup {
    destroy .top.l .top
    unset -nocomplain lres res
} -body {
    # This test checks whether all "x" values from bbox for different size
    # items with different justification settings are all positive or zero
    # This checks a bit the calculation of this x value with non-default
    # borders widths of the listbox
    toplevel .top
    listbox .top.l -justify left -borderwidth 17 -highlightthickness 19 -selectborderwidth 22
    .top.l insert end Item1 LongerItem2 MuchLongerItem3
    .top.l selection set 1
    pack .top.l
    update
    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
    .top.l configure -justify center
    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
    .top.l configure -justify right
    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
    set res 1
    for {set i 0} {$i < [llength $lres]} {incr i 4} {
        set res [expr {$res * [expr {[lindex $lres $i] >= 0}] }]
    }
    set res
} -cleanup {
    destroy .top.l .top
    unset -nocomplain lres res
} -result 1
test listbox-3.19 {ListboxWidgetCmd procedure, "cget" option} -body {
    .l cget
} -returnCodes error -result {wrong # args: should be ".l cget option"}
test listbox-3.20 {ListboxWidgetCmd procedure, "cget" option} -body {
    .l cget a b
} -returnCodes error -result {wrong # args: should be ".l cget option"}
test listbox-3.21 {ListboxWidgetCmd procedure, "cget" option} -body {
    .l cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} -body {
    .l cget -setgrid
} -result 0
test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} -body {
    llength [.l configure]
} -result 28
test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} -body {
    .l configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test listbox-3.25 {ListboxWidgetCmd procedure, "configure" option} -body {
    .l configure -setgrid
} -result {-setgrid setGrid SetGrid 0 0}
test listbox-3.26 {ListboxWidgetCmd procedure, "configure" option} -body {
    .l configure -gorp is_messy
} -returnCodes error -result {unknown option "-gorp"}
test listbox-3.27 {ListboxWidgetCmd procedure, "configure" option} -body {
    set oldbd [.l cget -bd]
    set oldht [.l cget -highlightthickness]
    .l configure -bd 3 -highlightthickness 0
    set x "[.l cget -bd] [.l cget -highlightthickness]"
    .l configure -bd $oldbd -highlightthickness $oldht
    set x
} -result {3 0}
test listbox-3.28 {ListboxWidgetCmd procedure, "curselection" option} -body {
    .l curselection a
} -returnCodes error -result {wrong # args: should be ".l curselection"}
test listbox-3.29 {ListboxWidgetCmd procedure, "curselection" option} -body {
    .l selection clear 0 end
    .l selection set 3 6
    .l selection set 9
    .l curselection
} -result {3 4 5 6 9}
test listbox-3.30 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.31 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete a b c
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.32 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}
test listbox-3.33 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete 2 123ab
} -returnCodes error -result {bad listbox index "123ab": must be active, anchor, end, @x,y, or a number}
test listbox-3.34 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 3
    list [.l2 get 2] [.l2 get 3] [.l2 index end]
} -cleanup {
    destroy .l2
} -result {el2 el4 7}
test listbox-3.35 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 2 4
    list [.l2 get 1] [.l2 get 2] [.l2 index end]
} -cleanup {
    destroy .l2
} -result {el1 el5 5}
test listbox-3.36 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -1 2
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el3 el4 el5 el6 el7}
test listbox-3.37 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -1 -1
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.38 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 2 end
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1}
test listbox-3.39 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 5 20
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4}
test listbox-3.40 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete end 20
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4 el5 el6}
test listbox-3.41 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 8 20
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.42 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.43 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get a b c
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.44 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 2.4
} -returnCodes error -result {bad listbox index "2.4": must be active, anchor, end, @x,y, or a number}
test listbox-3.45 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get end bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}
test listbox-3.46 {ListboxWidgetCmd procedure, "get" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    list [.l2 get 0] [.l2 get 3] [.l2 get end]
} -cleanup {
    destroy .l2
} -result {el0 el3 el7}
test listbox-3.47 {ListboxWidgetCmd procedure, "get" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    list [.l2 get 0] [.l2 get end]
} -cleanup {
    destroy .l2
} -result {{} {}}
test listbox-3.48 {ListboxWidgetCmd procedure, "get" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 "two words" el4 el5 el6 el7
    .l2 get 3 end
} -cleanup {
    destroy .l2
} -result {{two words} el4 el5 el6 el7}
test listbox-3.49 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1
} -result {}
test listbox-3.50 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1 -1
} -result {}
test listbox-3.51 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1 3
} -result {el0 el1 el2 el3}
test listbox-3.52 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 end
} -result {el12 el13 el14 el15 el16 el17}
test listbox-3.53 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 20
} -result {el12 el13 el14 el15 el16 el17}
test listbox-3.54 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get end
} -result {el17}
test listbox-3.55 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 30
} -result {}
test listbox-3.56 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 30 35
} -result {}
test listbox-3.57 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.58 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index a b
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.59 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index @
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or a number}
test listbox-3.60 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 2
} -result 2
test listbox-3.61 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index -1
} -result -1
test listbox-3.62 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index end
} -result 18
test listbox-3.63 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 34
} -result 18
test listbox-3.64 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert
} -returnCodes error -result {wrong # args: should be ".l insert index ?element ...?"}
test listbox-3.65 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}
test listbox-3.66 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c d e
    .l2 insert 3 x y z
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {a b c x y z d e}
test listbox-3.67 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c
    .l2 insert -1 x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {x a b c}
test listbox-3.68 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c
    .l2 insert end x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {a b c x}
test listbox-3.69 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c
    .l2 insert 43 x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {a b c x}
test listbox-3.70 {ListboxWidgetCmd procedure, "nearest" option} -body {
    .l nearest
} -returnCodes error -result {wrong # args: should be ".l nearest y"}
test listbox-3.71 {ListboxWidgetCmd procedure, "nearest" option} -body {
    .l nearest a b
} -returnCodes error -result {wrong # args: should be ".l nearest y"}
test listbox-3.72 {ListboxWidgetCmd procedure, "nearest" option} -body {
    .l nearest 20p
} -returnCodes error -result {expected integer but got "20p"}
test listbox-3.73 {ListboxWidgetCmd procedure, "nearest" option} -body {
    .l yview 3
    .l nearest 1000
} -result 7
test listbox-3.74 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan a b
} -returnCodes error -result {wrong # args: should be ".l scan mark|dragto x y"}
test listbox-3.75 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan a b c d
} -returnCodes error -result {wrong # args: should be ".l scan mark|dragto x y"}
test listbox-3.76 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan foo bogus 2
} -returnCodes error -result {expected integer but got "bogus"}
test listbox-3.77 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan foo 2 2.3
} -returnCodes error -result {expected integer but got "2.3"}
test listbox-3.78 {ListboxWidgetCmd procedure, "scan" option} -constraints {
	fonts
} -setup {
    destroy .t
} -body {
    toplevel .t
    wm geom .t +0+0
    listbox .t.l -width 10 -height 5
    .t.l insert 0 "Short" "Somewhat longer" "Really, quite a whole lot longer than can possibly fit on the screen" "Short" a b c d e f g h i j
    pack .t.l
    update
    .t.l scan mark 100 140
    .t.l scan dragto 90 137
    update
    list [format {%.6g %.6g} {*}[.t.l xview]] [format {%.6g %.6g} {*}[.t.l yview]]
} -cleanup {
    destroy .t
} -result {{0.249364 0.427481} {0.0714286 0.428571}}
test listbox-3.79 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan foo 2 4
} -returnCodes error -result {bad option "foo": must be mark or dragto}
test listbox-3.80 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.81 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see a b
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.82 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see gorp
} -returnCodes error -result {bad listbox index "gorp": must be active, anchor, end, @x,y, or a number}
test listbox-3.83 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 7
    .l index @0,0
} -result 7
test listbox-3.84 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 11
    .l index @0,0
} -result 7
test listbox-3.85 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 6
    .l index @0,0
} -result 6
test listbox-3.86 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 5
    .l index @0,0
} -result 3
test listbox-3.87 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 12
    .l index @0,0
} -result 8
test listbox-3.88 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 13
    .l index @0,0
} -result 11
test listbox-3.89 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see -1
    .l index @0,0
} -result 0
test listbox-3.90 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see end
    .l index @0,0
} -result 13
test listbox-3.91 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 322
    .l index @0,0
} -result 13
test listbox-3.92 {ListboxWidgetCmd procedure, "see" option, partial last line} -body {
    mkPartial
    .partial.l see 4
    .partial.l index @0,0
} -result 1
test listbox-3.93 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l select a
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.94 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l select a b c d
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.95 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}
test listbox-3.96 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a 0 lousy
} -returnCodes error -result {bad listbox index "lousy": must be active, anchor, end, @x,y, or a number}
test listbox-3.97 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor 0 0
} -returnCodes error -result {wrong # args: should be ".l selection anchor index"}
test listbox-3.98 {ListboxWidgetCmd procedure, "selection" option} -body {
    list [.l selection anchor 5; .l index anchor] \
	    [.l selection anchor 0; .l index anchor]
} -result {5 0}
test listbox-3.99 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor -1
    .l index anchor
} -result 0
test listbox-3.100 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor end
    .l index anchor
} -result 17
test listbox-3.101 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor 44
    .l index anchor
} -result 17
test listbox-3.102 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set 2 8
    .l selection clear 3 4
    .l curselection
} -result {2 5 6 7 8}
test listbox-3.103 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection includes 0 0
} -returnCodes error -result {wrong # args: should be ".l selection includes index"}
test listbox-3.104 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set 2 8
    .l selection clear 4
    list [.l selection includes 3] [.l selection includes 4] \
	    [.l selection includes 5]
} -result {1 0 1}
test listbox-3.105 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection set 0 end
    .l selection includes -1
} -result 0
test listbox-3.106 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set end
    .l selection includes end
} -result 1
test listbox-3.107 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection set 0 end
    .l selection includes 44
} -result 0
test listbox-3.108 {ListboxWidgetCmd procedure, "selection" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 selection includes 0
} -cleanup {
    destroy .l2
} -result 0
test listbox-3.109 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set 2
    .l selection set 5 7
    .l curselection
} -result {2 5 6 7}
test listbox-3.110 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set 2
    .l selection set 5 7
    .l selection set 5 7
    .l curselection
} -result {2 5 6 7}
test listbox-3.111 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection badOption 0 0
} -returnCodes error -result {bad option "badOption": must be anchor, clear, includes, or set}
test listbox-3.112 {ListboxWidgetCmd procedure, "size" option} -body {
    .l size a
} -returnCodes error -result {wrong # args: should be ".l size"}
test listbox-3.113 {ListboxWidgetCmd procedure, "size" option} -body {
    .l size
} -result 18
test listbox-3.114 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0 1}
test listbox-3.115 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
} -body {
    listbox .l2 -width 10 -height 5 -font $fixed
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    pack .l2
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0 1}

test listbox-3.116 {ListboxWidgetCmd procedure, "xview" option} -constraints {
	fonts
} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed


    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 insert 1 "0123456789a123456789b123456789c123456789d123456789"

    .l2 xview 4
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0.08 0.28}
test listbox-3.117 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l xview foo
} -returnCodes error -result {expected integer but got "foo"}
test listbox-3.118 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l xview zoom a b
} -returnCodes error -result {unknown option "zoom": must be moveto or scroll}
test listbox-3.119 {ListboxWidgetCmd procedure, "xview" option} -constraints {
	fonts
} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 insert 1 "0123456789a123456789b123456789c123456789d123456789"
    .l xview 0
    .l2 xview moveto .4
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0.4 0.6}
test listbox-3.120 {ListboxWidgetCmd procedure, "xview" option} -constraints {
	fonts
} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 insert 1 "0123456789a123456789b123456789c123456789d123456789"
    .l2 xview 0
    .l2 xview scroll 2 units
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0.04 0.24}
test listbox-3.121 {ListboxWidgetCmd procedure, "xview" option} -constraints {
	fonts
} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 insert 1 "0123456789a123456789b123456789c123456789d123456789"
    .l2 xview 30
    .l2 xview scroll -1 pages
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0.44 0.64}
test listbox-3.122 {ListboxWidgetCmd procedure, "xview" option} -constraints {
	fonts
} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 insert 1 "0123456789a123456789b123456789c123456789d123456789"
    .l2 configure -width 1
    update
    .l2 xview 30
    .l2 xview scroll -4 pages
    update
    format {%.6g %.6g} {*}[.l2 xview]
} -cleanup {
    destroy .l2
} -result {0.52 0.54}
test listbox-3.123 {ListboxWidgetCmd procedure, "yview" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    pack  .l2
    update
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0 1}
test listbox-3.124 {ListboxWidgetCmd procedure, "yview" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el1
    pack  .l2
    update
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0 1}

test listbox-3.125 {ListboxWidgetCmd procedure, "yview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 yview 4
    update
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0.2 0.45}
test listbox-3.126 {ListboxWidgetCmd procedure, "yview" option, partial last line} -setup {
    destroy .l
    listbox .l -width 10 -height 5 -font $fixed

    pack .l
    update


} -body {
    .l insert 0 a b c d e f g h i j k l m n o p q r s t


    mkPartial
    format {%.6g %.6g} {*}[.partial.l yview]
} -cleanup {
    destroy .l
} -result {0 0.266667}

# Listbox used in 3.127 -3.137 tests
destroy .l
listbox .l -width 20 -height 5 -bd 4 -highlightthickness 1 -selectborderwidth 2
pack .l
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11 el12 el13 el14 \
	el15 el16 el17
update
test listbox-3.127 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo
} -returnCodes error -result {bad listbox index "foo": must be active, anchor, end, @x,y, or a number}
test listbox-3.128 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo a b
} -returnCodes error -result {unknown option "foo": must be moveto or scroll}
test listbox-3.129 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 yview 0
    .l2 yview moveto .31
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0.3 0.55}
test listbox-3.130 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 yview 2
    .l2 yview scroll 2 pages
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0.4 0.65}
test listbox-3.131 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update
} -body {
    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 yview 10
    .l2 yview scroll -3 units
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0.35 0.6}
test listbox-3.132 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
    update



} -body {

    .l2 insert 0 a b c d e f g h i j k l m n o p q r s t
    .l2 configure -height 2
    update
    .l2 yview 15
    .l2 yview scroll -4 pages
    format {%.6g %.6g} {*}[.l2 yview]
} -cleanup {
    destroy .l2
} -result {0.55 0.65}
test listbox-3.133 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l whoknows
} -returnCodes error -result {bad option "whoknows": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}
test listbox-3.134 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l c
} -returnCodes error -result {ambiguous option "c": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}
test listbox-3.135 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l in
} -returnCodes error -result {ambiguous option "in": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}
test listbox-3.136 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l s
} -returnCodes error -result {ambiguous option "s": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}
test listbox-3.137 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l se
} -returnCodes error -result {ambiguous option "se": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}

# No tests for DestroyListbox:  I can't come up with anything to test
# in this procedure.


test listbox-4.1 {ConfigureListbox procedure} -constraints {
	fonts
} -setup {
    deleteWindows
    destroy .l
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l
    update
} -body {
    update
    set x [getsize .]
    .l configure -setgrid 0
    update
    list $x [getsize .]
} -cleanup {
    deleteWindows
} -result {25x15 185x263}
resetGridInfo
test listbox-4.2 {ConfigureListbox procedure} -setup {
    deleteWindows
    destroy .l
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l
    update
} -body {
    .l configure -highlightthickness -3
    .l cget -highlightthickness
} -cleanup {
    deleteWindows
} -result 0
test listbox-4.3 {ConfigureListbox procedure} -setup {
    deleteWindows
    destroy .l
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l
    update
} -body {
    .l configure -exportselection 0
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 3 5
    .l configure -exportselection 1
    selection get
} -cleanup {
    deleteWindows
} -result {el3
el4
el5}
test listbox-4.4 {ConfigureListbox procedure} -setup {
    deleteWindows
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l
    update
} -body {
    entry .e
    .e insert 0 abc
    .e select from 0
    .e select to 2
    .l configure -exportselection 0
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 3 5
    .l selection clear 3 5
    .l configure -exportselection 1
    list [selection own] [selection get]
} -cleanup {
    deleteWindows
} -result {.e ab}
test listbox-4.5 {-exportselection option} -setup {
    deleteWindows
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l
    update
} -body {
    selection clear .
    .l configure -exportselection 1
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 1 1
    set x {}
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l config -exportselection 0
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l selection clear 0 end
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l selection set 1 3
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l config -exportselection 1
    lappend x [catch {selection get} msg] $msg [.l curselection]
} -cleanup {
    deleteWindows
} -result {0 el1 1 1 {PRIMARY selection doesn't exist or form "STRING" not defined} 1 1 {PRIMARY selection doesn't exist or form "STRING" not defined} {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined} {1 2 3} 0 {el1
el2
el3} {1 2 3}}
test listbox-4.6 {ConfigureListbox procedure} -constraints {
	fonts
} -setup {
    deleteWindows
} -body {

    # The following code (reset geometry, withdraw, etc.) is necessary
    # to reset the state of some window managers like olvwm under
    # SunOS 4.1.3.

    wm geom . 300x300
    update
    wm geom . {}
    wm withdraw .
    listbox .l2 -font $fixed -width 15 -height 20
    pack .l2
    update
    wm deiconify .
    set x [getsize .]
    .l2 configure -setgrid 1
    update
    list $x [getsize .]
} -cleanup {
    deleteWindows
} -result {115x328 15x20}
test listbox-4.7 {ConfigureListbox procedure} -setup {
    deleteWindows
} -body {
    wm withdraw .
    listbox .l2 -font $fixed -width 30 -height 20 -setgrid 1
    wm geom . +25+25
    pack .l2
    update
    wm deiconify .
    set result [getsize .]
    wm geom . 26x15
    update
    lappend result [getsize .]
    .l2 configure -setgrid 1
    update
    lappend result [getsize .]
} -cleanup {
    deleteWindows
    wm geom . {}
} -result {30x20 26x15 26x15}

resetGridInfo
test listbox-4.8 {ConfigureListbox procedure} -setup {
    destroy .l2
} -body {
    listbox .l2 -width 15 -height 20 -xscrollcommand "record x" \
	    -yscrollcommand "record y"
    pack .l2
    update
    .l2 configure -fg black
    set log {}
    update
    set log
} -cleanup {
    destroy .l2
} -result {{y 0 1} {x 0 1}}
test listbox-4.9 {ConfigureListbox procedure, -listvar} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result [list a b c d]
test listbox-4.10 {ConfigureListbox, no listvar -> existing listvar} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2
    .l2 insert end 1 2 3 4
    .l2 configure -listvar x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result [list a b c d]
test listbox-4.11 {ConfigureListbox procedure, listvar -> no listvar} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 configure -listvar {}
    .l2 insert end 1 2 3 4
    list $x [.l2 get 0 end]
} -cleanup {
    destroy .l2
} -result [list [list a b c d] [list a b c d 1 2 3 4]]
test listbox-4.12 {ConfigureListbox procedure, listvar -> different listvar} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    set y [list 1 2 3 4]
    listbox .l2
    .l2 configure -listvar x
    .l2 configure -listvar y
    .l2 insert end 5 6 7 8
    list $x $y
} -cleanup {
    destroy .l2
} -result [list [list a b c d] [list 1 2 3 4 5 6 7 8]]
test listbox-4.13 {ConfigureListbox, no listvar -> non-existant listvar} -setup {
    destroy .l2
} -body {
    catch {unset x}
    listbox .l2
    .l2 insert end a b c d
    .l2 configure -listvar x
    set x
} -cleanup {
    destroy .l2
} -result [list a b c d]
test listbox-4.14 {ConfigureListbox, non-existant listvar} -setup {
    destroy .l2
} -body {
    catch {unset x}
    listbox .l2 -listvar x
    list [info exists x] $x
} -cleanup {
    destroy .l2
} -result [list 1 {}]
test listbox-4.15 {ConfigureListbox, listvar -> non-existant listvar} -setup {
    destroy .l2
} -body {
    catch {unset y}
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 configure -listvar y
    list [info exists y] $y
} -cleanup {
    destroy .l2
} -result [list 1 [list a b c d]]
test listbox-4.16 {ConfigureListbox, listvar -> same listvar} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 configure -listvar x
    set x
} -cleanup {
    destroy .l2
} -result [list a b c d]
test listbox-4.17 {ConfigureListbox, no listvar -> no listvar} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c d
    .l2 configure -listvar {}
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result [list a b c d]
test listbox-4.18 {ConfigureListbox, no listvar -> bad listvar} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c d
    set x "this is a \" bad list"
    catch {.l2 configure -listvar x} result
    list [.l2 get 0 end] [.l2 cget -listvar] $result
} -cleanup {
    destroy .l2
} -result [list [list a b c d] {} \
	"unmatched open quote in list: invalid -listvariable value"]
test listbox-4.19 {ConfigureListbox, no listvar -> bad non-existent listvar} -setup {
    destroy .l2
} -body {
    unset -nocomplain ::foo
    listbox .l2 -listvar foo
    .l2 insert end a b c d
    catch {.l2 configure -listvar ::zoo::bar::foo} result
    list [.l2 get 0 end] [.l2 cget -listvar] $foo $result
} -cleanup {
    destroy .l2
} -result [list [list a b c d] foo [list a b c d] \
	{can't set "::zoo::bar::foo": parent namespace doesn't exist}]


# No tests for DisplayListbox:  I don't know how to test this procedure.

test listbox-5.1 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 15 -height 20
    pack .l
    list [winfo reqwidth .l] [winfo reqheight .l]
} -result {115 328}
test listbox-5.2 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 0 -height 10
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} -result {17 168}
test listbox-5.3 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 0 -height 10 -bd 3
    .l insert 0 Short "Really much longer" Longer
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} -result {138 170}
test listbox-5.4 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 10 -height 0
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} -result {80 24}
test listbox-5.5 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 10 -height 0 -highlightthickness 0
    .l insert 0 Short "Really much longer" Longer
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} -result {76 52}
test listbox-5.6 {ListboxComputeGeometry procedure} -setup {
    destroy .l
} -body {
    # If "0" in selected font had 0 width, caused divide-by-zero error.


    pack [listbox .l -font {{open look glyph}}]
    update
} -cleanup {
    destroy .l
} -result {}


# Listbox used in 6.*, 7.* tests
destroy .l
listbox .l -height 2 -xscrollcommand "record x" -yscrollcommand "record y"
pack .l
update
test listbox-6.1 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert end a b c d
    .l insert 5 x y z
    .l insert 2 A
    .l insert 0 q r s
    .l get 0 end
} -result {q r s a b A c d x y z}
test listbox-6.2 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l insert 2 A B
    .l index anchor
} -result 4
test listbox-6.3 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l insert 3 A B
    .l index anchor
} -result 2
test listbox-6.4 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l insert 2 A B
    .l index @0,0
} -result 5
test listbox-6.5 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l insert 3 A B
    .l index @0,0
} -result 3
test listbox-6.6 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 5
    .l insert 5 A B
    .l index active
} -result 7
test listbox-6.7 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 5
    .l insert 6 A B
    .l index active
} -result 5
test listbox-6.8 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c
    .l index active
} -result 2
test listbox-6.9 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0
    .l index active
} -result 0
test listbox-6.10 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b "two words"  c d e f g h i j
    update
    set log {}
    .l insert 0 word
    update
    set log
} -result {{y 0 0.166667}}
test listbox-6.11 {InsertEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b "two words"  c d e f g h i j
    update
    set log {}
    .l insert 0 "much longer entry"
    update
    set log
} -result {{y 0 0.166667} {x 0 1}}
test listbox-6.12 {InsertEls procedure} -constraints {
	fonts
} -setup {
    destroy .l2
} -body {
    listbox .l2 -width 0 -height 0
    pack .l2 -side top
    .l2 insert 0 a b "two words"  c d
    set x {}
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
    .l2 insert 0 "much longer entry"
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
} -cleanup {
    destroy .l2
} -result {80 93 122 110}
test listbox-6.13 {InsertEls procedure, check -listvar update} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 insert 0 1 2 3 4
    set x
} -cleanup {
    destroy .l2
} -result [list 1 2 3 4 a b c d]
test listbox-6.14 {InsertEls procedure, check selection update} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 0 1 2 3 4
    .l2 selection set 2 4
    .l2 insert 0 a
    .l2 curselection
} -cleanup {
    destroy .l2
} -result [list 3 4 5]
test listbox-6.15 {InsertEls procedure, lost namespaced listvar} -body {
    destroy .l2
    namespace eval test { variable foo {a b} }
    listbox .l2 -listvar ::test::foo
    namespace delete test
    .l2 insert end c d
    .l2 delete end
    .l2 insert end e f
    catch {set ::test::foo} result
    list [.l2 get 0 end] [.l2 cget -listvar] $result
} -cleanup {
    destroy .l2
} -result [list [list a b c e f] ::test::foo \
	{can't read "::test::foo": no such variable}]


test listbox-7.1 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection set 1 6
    .l delete 4 3
    list [.l size] [selection get]
} -result {10 {b
c
d
e
f
g}}
test listbox-7.2 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection set 3 6
    .l delete 4 4
    list [.l size] [.l get 4] [.l curselection]
} -result {9 f {3 4 5}}
test listbox-7.3 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l delete 0 3
    list [.l size] [.l get 0] [.l get 1]
} -result {6 e f}
test listbox-7.4 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l delete 8 1000
    list [.l size] [.l get 7]
} -result {8 h}
test listbox-7.5 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l delete 0 1
    .l index anchor
} -result 0
test listbox-7.6 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l delete 2
    .l index anchor
} -result 2
test listbox-7.7 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 4
    .l delete 2 5
    .l index anchor
} -result 2
test listbox-7.8 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 3
    .l delete 4 5
    .l index anchor
} -result 3
test listbox-7.9 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 1 2
    .l index @0,0
} -result 1
test listbox-7.10 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 3 4
    .l index @0,0
} -result 3
test listbox-7.11 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 4 6
    .l index @0,0
} -result 3
test listbox-7.12 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 3 end
    .l index @0,0
} -result 1
test listbox-7.13 {DeleteEls procedure, updating view with partial last line} -body {
    mkPartial
    .partial.l yview 8
    update
    .partial.l delete 10 13
    .partial.l index @0,0
} -result 7
test listbox-7.14 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 3 4
    .l index active
} -result 4
test listbox-7.15 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 5 7
    .l index active
} -result 5
test listbox-7.16 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 5 end
    .l index active
} -result 4
test listbox-7.17 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 0 end
    .l index active
} -result 0
test listbox-7.18 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c "two words" d e f g h i j
    update
    set log {}
    .l delete 4 6
    update
    set log
} -result {{y 0 0.25}}
test listbox-7.19 {DeleteEls procedure} -body {
    .l delete 0 end
    .l insert 0 a b c "two words" d e f g h i j
    update
    set log {}
    .l delete 3
    update
    set log
} -result {{y 0 0.2} {x 0 1}}
test listbox-7.20 {DeleteEls procedure} -constraints {
	fonts
} -setup {
    destroy .l2
} -body {
    listbox .l2 -width 0 -height 0
    pack .l2 -side top
    .l2 insert 0 a b "two words" c d e f g
    set x {}
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
    .l2 delete 2 4
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
} -result {80 144 17 93}

test listbox-7.21 {DeleteEls procedure, check -listvar update} -setup {
    destroy .l2
} -body {
    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 delete 0 1
    set x
} -result [list c d]


test listbox-8.1 {ListboxEventProc procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -setgrid 1
    pack .l
    update
    set x [getsize .]
    destroy .l
    list $x [getsize .] [winfo exists .l] [info command .l]
} -cleanup {
    destroy .l
} -result {20x10 150x178 0 {}}
resetGridInfo
test listbox-8.2 {ListboxEventProc procedure} -constraints {
	fonts
} -setup {
    destroy .l
} -body {
    listbox .l -height 5 -width 10
    .l insert 0 a b c "A string that is very very long" d e f g h i j k
    pack .l
    update
    place .l -width 50 -height 80
    update
    list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} -cleanup {
    destroy .l
} -result {{0 0.222222} {0 0.333333}}
test listbox-8.3 {ListboxEventProc procedure} -setup {
    deleteWindows
} -body {
    listbox .l1 -bg #543210
    rename .l1 .l2
    set x {}
    lappend x [winfo children .]
    lappend x [.l2 cget -bg]
    destroy .l1
    lappend x [info command .l*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {.l1 #543210 {} {}}


test listbox-9.1 {ListboxCmdDeletedProc procedure} -setup {
    deleteWindows
} -body {
    listbox .l1
    rename .l1 {}
    list [info command .l*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}
test listbox-9.2 {ListboxCmdDeletedProc procedure, disabling -setgrid} -constraints {
	fonts
} -setup {
    destroy .top
} -body {
    toplevel .top
    wm geom .top +0+0
    listbox .top.l -setgrid 1 -width 20 -height 10
    pack .top.l
    update
    set x [getsize .top]
    rename .top.l {}
    update
    lappend x [getsize .top]
} -cleanup {
    destroy .top
} -result {20x10 150x178}


# Listbox used in 10.* tests
destroy .l
test listbox-10.1 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]


    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11

    .l activate 3
    update
    list [.l activate 3; .l index active] [.l activate 6; .l index active]
} -cleanup {
    destroy .l
} -result {3 6}
test listbox-10.2 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l selection anchor 2
    update
    .l index anchor
} -cleanup {
    destroy .l
} -result 2
test listbox-10.3 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l insert end A B C D E
    .l selection anchor end
    update
    .l delete 12 end
    list [.l index anchor] [.l index end]
} -cleanup {
    destroy .l
} -result {12 12}
test listbox-10.4 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index a
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "a": must be active, anchor, end, @x,y, or a number}
test listbox-10.5 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index end
} -cleanup {
    destroy .l
} -result 12
test listbox-10.6 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l get end
} -cleanup {
    destroy .l
} -result {el11}
test listbox-10.7 {GetListboxIndex procedure} -setup {

    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l delete 0 end
    update

    .l index end






} -cleanup {
    destroy .l
} -result 0

test listbox-10.8 {GetListboxIndex procedure} -setup {


    destroy .l




} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or a number}
test listbox-10.9 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @foo
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@foo": must be active, anchor, end, @x,y, or a number}
test listbox-10.10 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1x3
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1x3": must be active, anchor, end, @x,y, or a number}
test listbox-10.11 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,": must be active, anchor, end, @x,y, or a number}
test listbox-10.12 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,foo

} -cleanup {

    destroy .l
} -returnCodes error -result {bad listbox index "@1,foo": must be active, anchor, end, @x,y, or a number}
test listbox-10.13 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,2x
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,2x": must be active, anchor, end, @x,y, or a number}
test listbox-10.14 {GetListboxIndex procedure} -constraints {
    fonts
} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    list [.l index @5,57] [.l index @5,58]
} -cleanup {
    .l delete 0 end
} -cleanup {
    destroy .l
} -result {3 3}
test listbox-10.15 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 1xy
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "1xy": must be active, anchor, end, @x,y, or a number}
test listbox-10.16 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 3
} -cleanup {
    destroy .l
} -result 3
test listbox-10.17 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 20
} -cleanup {
    destroy .l
} -result 12
test listbox-10.18 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l get 20
} -cleanup {
    destroy .l
} -result {}
test listbox-10.19 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index -1
} -cleanup {
    destroy .l
} -result -1
test listbox-10.20 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l delete 0 end
    update
    .l index 1
} -cleanup {
    destroy .l
} -result 0


test listbox-11.1 {ChangeListboxView procedure, boundary conditions for index} -setup {
    destroy .l
} -body {
    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview -1
    update
    lappend x [.l index @0,0]
} -cleanup {
    destroy .l
} -result {3 0}
test listbox-11.2 {ChangeListboxView procedure, boundary conditions for index} -setup {
    destroy .l
} -body {
    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview 20
    update
    lappend x [.l index @0,0]
} -cleanup {
    destroy .l
} -result {3 5}
test listbox-11.3 {ChangeListboxView procedure} -setup {
    destroy .l
} -body {
    listbox .l -height 5 -yscrollcommand "record y"
    pack .l
    .l insert 0 a b c d e f g h i j
    update
    set log {}
    .l yview 2
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log
} -cleanup {
    destroy .l
} -result {{0.2 0.7} {{y 0.2 0.7}}}
test listbox-11.4 {ChangeListboxView procedure} -setup {
    destroy .l
} -body {
    listbox .l -height 5 -yscrollcommand "record y"
    pack .l
    .l insert 0 a b c d e f g h i j
    update
    set log {}
    .l yview 8
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log
} -cleanup {
    destroy .l
} -result {{0.5 1} {{y 0.5 1}}}
test listbox-11.5 {ChangeListboxView procedure} -setup {
    destroy .l
} -body {
    listbox .l -height 5 -yscrollcommand "record y"
    pack .l
    update
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set log {}
    .l yview 3
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log
} -cleanup {
    destroy .l
} -result {{0.3 0.8} {}}
test listbox-11.6 {ChangeListboxView procedure, partial last line} -body {
    mkPartial
    .partial.l yview 13
    .partial.l index @0,0
} -cleanup {
    destroy .l
} -result 11


# Listbox used in 12.* tests
destroy .l
listbox .l -font $fixed -xscrollcommand "record x" -width 10
.l insert 0 0123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789
pack .l
update
test listbox-12.1 {ChangeListboxOffset procedure} -constraints {
	fonts
} -body {
    set log {}
    .l xview 99
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} -result {{0.9 1} {{x 0.9 1}}}
test listbox-12.2 {ChangeListboxOffset procedure} -constraints {
	fonts
} -body {
    set log {}
    .l xview 99
    .l xview moveto -.25
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} -result {{0 0.1} {{x 0 0.1}}}
test listbox-12.3 {ChangeListboxOffset procedure} -constraints {
	fonts
} -body {
    .l xview 10
    update
    set log {}
    .l xview 10
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} -result {{0.1 0.2} {}}


# Listbox used in 13.* tests
destroy .l
listbox .l -font $fixed -width 10 -height 5
pack .l
.l insert 0 a bb c d e f g h i j k l m n o p q r s
.l insert 0 0123456789a123456789b123456789c123456789d123456789
update
set width [expr [lindex [.l bbox 2] 2] - [lindex [.l bbox 1] 2]]
set height [expr [lindex [.l bbox 2] 1] - [lindex [.l bbox 1] 1]]
test listbox-13.1 {ListboxScanTo procedure} -constraints {
	fonts
} -body {
    .l yview 0
    .l xview 0
    .l scan mark 10 20
    .l scan dragto [expr 10-$width] [expr 20-$height]
    update
    list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} -result {{0.2 0.4} {0.5 0.75}}
test listbox-13.2 {ListboxScanTo procedure} -constraints {
	fonts
} -body {
    .l yview 5
    .l xview 10
    .l scan mark 10 20
    .l scan dragto 20 40
    update
    set x [list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]]
    .l scan dragto [expr 20-$width] [expr 40-$height]
    update
    lappend x [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} -result {{0 0.2} {0 0.25} {0.2 0.4} {0.5 0.75}}
test listbox-13.3 {ListboxScanTo procedure} -constraints {
	fonts
} -body {
    .l yview moveto 1.0
    .l xview moveto 1.0
    .l scan mark 10 20
    .l scan dragto 5 10
    update
    set x [list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]]
    .l scan dragto [expr 5+$width] [expr 10+$height]
    update
    lappend x [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} -result {{0.8 1} {0.75 1} {0.6 0.8} {0.25 0.5}}


test listbox-14.1 {NearestListboxElement procedure, partial last line} -body {
    mkPartial
    .partial.l nearest [winfo height .partial.l]
} -result 4
# Listbox used in 14.* tests
destroy .l
listbox .l -font $fixed -width 20 -height 10
.l insert 0 a b c d e f g h i j k l m n o p q r s t
.l yview 4
pack .l
update
test listbox-14.2 {NearestListboxElement procedure} -constraints {
	fonts
} -body {
    .l index @50,0
} -result 4
test listbox-14.3 {NearestListboxElement procedure} -constraints {
	fonts
} -body {
    list [.l index @50,35] [.l index @50,36]
} -result {5 6}
test listbox-14.4 {NearestListboxElement procedure} -constraints {
	fonts
} -body {
    .l index @50,200
} -result 13


# Listbox used in 15.* 16.* and 17.* tests
destroy .l
listbox .l -font $fixed -width 20 -height 10
pack .l
update
test listbox-15.1 {ListboxSelect procedure} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j k l m n o p
    .l select set 2 4
    .l select set 7 12
    .l select clear 4 7
    .l curselection
} -result {2 3 8 9 10 11 12}
test listbox-15.2 {ListboxSelect procedure} -setup {
    destroy .e
} -body {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j k l m n o p

    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 7
    .l selection clear 2 4
    set x [selection own]
    .l selection set 3
    list $x [selection own] [selection get]
} -cleanup {
    destroy .e
} -result {.e .l d}
test listbox-15.3 {ListboxSelect procedure} -body {
    .l delete 0 end
    .l selection clear 0 end
    .l select set 0 end
    .l curselection
} -result {}
test listbox-15.4 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 -1
    .l curselection
} -result {}
test listbox-15.5 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 3
    .l curselection
} -result {0 1 2 3}
test listbox-15.6 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 2 4
    .l curselection
} -result {2 3 4}
test listbox-15.7 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 4 end
    .l curselection
} -result {4 5}
test listbox-15.8 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 4 30
    .l curselection
} -result {4 5}
test listbox-15.9 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set end 30
    .l curselection
} -result 5
test listbox-15.10 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 20 25
    .l curselection
} -result {}


test listbox-16.1 {ListboxFetchSelection procedure} -body {
    .l delete 0 end
    .l insert 0 a b c "two words" e f g h i \\ k l m n o p
    .l selection set 2 4
    .l selection set 9
    .l selection set 11 12
    selection get
} -result "c\ntwo words\ne\n\\\nl\nm"
test listbox-16.2 {ListboxFetchSelection procedure} -body {
    .l delete 0 end
    .l insert 0 a b c "two words" e f g h i \\ k l m n o p
    .l selection set 3
    selection get
} -result "two words"
test listbox-16.3 {ListboxFetchSelection procedure, retrieve in several parts} -body {
    set long "This is quite a long string\n"
    append long $long $long $long $long
    append long $long $long $long $long
    append long $long $long
    .l delete 0 end
    .l insert 0 1$long 2$long 3$long 4$long 5$long
    .l selection set 0 end
    set sel [selection get]
    string compare 1$long\n2$long\n3$long\n4$long\n5$long $sel
} -cleanup {
    catch {unset long sel}
} -result 0


test listbox-17.1 {ListboxLostSelection procedure} -setup {
    destroy .e
} -body {
    .l delete 0 end
    .l insert 0 a b c d e
    .l select set 0 end

    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 5
    .l curselection
} -cleanup {
    destroy .e
} -result {}
test listbox-17.2 {ListboxLostSelection procedure} -setup {
    destroy .e
} -body {
    .l delete 0 end
    .l insert 0 a b c d e
    .l select set 0 end
    .l configure -exportselection 0

    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 5
    .l curselection
} -cleanup {
    destroy .e
} -result {0 1 2 3 4}


# Listbox used in 18.* tests
destroy .l
listbox .l -font $fixed -width 10 -height 5
pack .l
update
test listbox-18.1 {ListboxUpdateVScrollbar procedure} -body {
    .l configure -yscrollcommand "record y"
    set log {}
    .l insert 0 a b c
    update
    .l insert end d e f g h
    update
    .l delete 0 end
    update
    set log
} -result {{y 0 1} {y 0 0.625} {y 0 1}}
test listbox-18.2 {ListboxUpdateVScrollbar procedure, partial last line} -body {
    mkPartial
    .partial.l configure -yscrollcommand "record y"
    set log {}
    .partial.l yview 3
    update
    set log
} -result {{y 0.2 0.466667}}
test listbox-18.3 {ListboxUpdateVScrollbar procedure} -body {
    proc bgerror args {
	    global x errorInfo
	    set x [list $args $errorInfo]
    }
    .l configure -yscrollcommand gorp
    .l insert 0 foo
    update
    set x
} -cleanup {
    rename bgerror {}
} -result {{{invalid command name "gorp"}} {invalid command name "gorp"
    while executing
"gorp 0.0 1.0"
    (vertical scrolling command executed by listbox)}}




# Listbox used in 19.* tests
destroy .l
listbox .l -font $fixed -width 10 -height 5
pack .l
update
test listbox-19.1 {ListboxUpdateVScrollbar procedure} -constraints {
	fonts
} -body {
    .l configure -xscrollcommand "record x"
    set log {}
    .l insert 0 abc
    update
    .l insert 0 "This is a much longer string..."
    update
    .l delete 0 end
    update
    set log
} -result {{x 0 1} {x 0 0.322581} {x 0 1}}
test listbox-19.2 {ListboxUpdateVScrollbar procedure} -body {
    proc bgerror args {
	    global x errorInfo
	    set x [list $args $errorInfo]
    }
    .l configure -xscrollcommand bogus
    .l insert 0 foo
    update
    set x
} -result {{{invalid command name "bogus"}} {invalid command name "bogus"
    while executing
"bogus 0.0 1.0"
    (horizontal scrolling command executed by listbox)}}




test listbox-20.1 {listbox vs hidden commands} -setup {
    deleteWindows
} -body {
    set l [interp hidden]
    listbox .l
    interp hide {} .l
    destroy .l
    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 eq $res2}
} -result 1


# tests for ListboxListVarProc
test listbox-21.1 {ListboxListVarProc} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x
    set x [list a b c d]
    .l get 0 end
} -cleanup {
    destroy .l
} -result [list a b c d]
test listbox-21.2 {ListboxListVarProc} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    unset x
    set x
} -cleanup {
    destroy .l
} -result [list a b c d]
test listbox-21.3 {ListboxListVarProc} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    .l configure -listvar {}
    unset x
    info exists x
} -cleanup {
    destroy .l
} -result 0
test listbox-21.4 {ListboxListVarProc} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    lappend x e f g
    .l size
} -cleanup {
    destroy .l
} -result 7
test listbox-21.5 {ListboxListVarProc, test selection after listvar mod} -setup {
    destroy .l
} -body {
    set x [list a b c d e f g]
    listbox .l -listvar x
    .l selection set end
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l curselection
} -cleanup {
    destroy .l
} -result {}
test listbox-21.6 {ListboxListVarProc, test selection after listvar mod} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 3
    lappend x e f g
    .l curselection
} -cleanup {
    destroy .l
} -result 3
test listbox-21.7 {ListboxListVarProc, test selection after listvar mod} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 0
    set x [linsert $x 0 1 2 3 4]
    .l curselection
} -cleanup {
    destroy .l
} -result 0
test listbox-21.8 {ListboxListVarProc, test selection after listvar mod} -setup {
    destroy .l
} -body {
    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 2
    set x [list a b c]
    .l curselection
} -cleanup {
    destroy .l
} -result 2
test listbox-21.9 {ListboxListVarProc, test hscrollbar after listvar mod} -setup {
    destroy .l
} -body {
    set x {}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    pack .l
    update idletasks
    set log {}
    lappend x "0000000000"
    update idletasks
    lappend x "00000000000000000000"
    update idletasks
    set log
} -cleanup {
    destroy .l
} -result [list {x 0 1} {x 0 0.5}]
test listbox-21.10 {ListboxListVarProc, test hscrollbar after listvar mod} -setup {
    destroy .l
} -body {
    catch {unset x}

    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    pack .l
    update idletasks
    set log {}
    lappend x "0000000000"
    update idletasks
    lappend x "00000000000000000000"
    update idletasks
    set x [list "0000000000"]
    update idletasks
    set log
} -cleanup {
    destroy .l
} -result [list {x 0 1} {x 0 0.5} {x 0 1}]
test listbox-21.11 {ListboxListVarProc, bad list} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x
    set x [list a b c d]
    catch {set x "this is a \" bad list"} result
    set result
} -cleanup {
    destroy .l
} -result {can't set "x": invalid listvar value}
test listbox-21.12 {ListboxListVarProc, cleanup item attributes} -setup {
    destroy .l






} -body {


    set x [list a b c d e f g]
    listbox .l -listvar x
    .l itemconfigure end -fg red
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l itemcget end -fg
} -cleanup {
    destroy .l
} -result {}
test listbox-21.12a {ListboxListVarProc, cleanup item attributes} -setup {
    destroy .l
} -body {
    set x [list a b c d e f g]
    listbox .l -listvar x
    .l itemconfigure end -fg red
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l itemcget end -fg
} -cleanup {
    destroy .l
} -result {}
test listbox-21.13 {listbox item configurations and listvar based deletions} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x
    .l insert end a b c
    .l itemconfigure 1 -fg red
    set x [list b c]
    .l itemcget 1 -fg
} -cleanup {
    destroy .l
} -result red
test listbox-21.14 {listbox item configurations and listvar based inserts} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x
    .l insert end a b c
    .l itemconfigure 0 -fg red
    set x [list 1 2 3 4 a b c]
    .l itemcget 0 -fg
} -cleanup {
    destroy .l
} -result red
test listbox-21.15 {ListboxListVarProc, update vertical scrollbar} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -font $fixed -height 3 -yscrollcommand "record y" -listvar x
    update
    set log {}

    pack .l
    set timeout [after 500 {lappend log timeout3}]
    vwait log
    update
    lappend x a b c d e f
    vwait log
    set log
} -cleanup {
    destroy .l
    after cancel $timeout
} -result [list {y 0 1} {y 0 0.5}]
test listbox-21.16 {ListboxListVarProc, update vertical scrollbar} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x -height 3
    pack .l

    set x [list 0 1 2 3 4 5]
    .l yview scroll 3 units
    update
    set result {}
    lappend result [format {%.6g %.6g} {*}[.l yview]]
    set x [lreplace $x 3 3]
    set x [lreplace $x 3 3]
    set x [lreplace $x 3 3]
    update
    lappend result [format {%.6g %.6g} {*}[.l yview]]
    set result
} -cleanup {
    destroy .l
} -result [list {0.5 1} {0 1}]


# UpdateHScrollbar
test listbox-22.1 {UpdateHScrollbar} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 10 -xscrollcommand "record x"
    pack .l
    update idletasks
    set log {}
    set timeout [after 500 {lappend log timeout4}]
    .l insert end "0000000000"
    vwait log
    .l insert end "00000000000000000000"
    vwait log
    set log
} -cleanup {
    destroy .l
    after cancel $timeout
} -result [list {x 0 1} {x 0 0.5}]


# ConfigureListboxItem
test listbox-23.1 {ConfigureListboxItem} -setup {
    destroy .l
} -body {
    listbox .l
    catch {.l itemconfigure 0} result
    set result
} -cleanup {
    destroy .l
} -result {item number "0" out of range}
test listbox-23.2 {ConfigureListboxItem} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemconfigure 0
} -cleanup {
    destroy .l
} -result [list {-background background Background {} {}} \
	{-bg -background} \
	{-fg -foreground} \
	{-foreground foreground Foreground {} {}} \
	{-selectbackground selectBackground Foreground {} {}} \
	{-selectforeground selectForeground Background {} {}}]
test listbox-23.3 {ConfigureListboxItem, itemco shortcut} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemco 0 -background
} -cleanup {
    destroy .l
} -result {-background background Background {} {}}
test listbox-23.4 {ConfigureListboxItem, wrong num args} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a
    catch {.l itemco} result
    set result
} -cleanup {
    destroy .l
} -result {wrong # args: should be ".l itemconfigure index ?-option value ...?"}
test listbox-23.5 {ConfigureListboxItem, multiple calls} -setup {
    destroy .l
} -body {
    listbox .l
    set i 0
    foreach color {red orange yellow green blue white violet} {
	.l insert end $color
	.l itemconfigure $i -bg $color
	incr i
    }
    pack .l
    update
    list [.l itemcget 0 -bg] [.l itemcget 1 -bg] [.l itemcget 2 -bg] \
	    [.l itemcget 3 -bg] [.l itemcget 4 -bg] [.l itemcget 5 -bg] \
	    [.l itemcget 6 -bg]
} -cleanup {
    destroy .l
} -result {red orange yellow green blue white violet}

# Listbox used in 23.6 -23.17 tests
destroy .l
listbox .l
.l insert end a b c d

test listbox-23.6 {configuration options} -body {
    .l itemconfigure 0 -background #ff0000
    list [lindex [.l itemconfigure 0 -background] 4] [.l itemcget 0 -background]
} -cleanup {
    .l configure -background #ffffff
} -result {{#ff0000} #ff0000}
test listbox-23.7 {configuration options} -body {
    .l configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-23.8 {configuration options} -body {
    .l itemconfigure 0 -bg #ff0000
    list [lindex [.l itemconfigure 0 -bg] 4] [.l itemcget 0 -bg]
} -cleanup {
    .l configure -bg #ffffff
} -result {{#ff0000} #ff0000}
test listbox-23.9 {configuration options} -body {
    .l configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-23.10 {configuration options} -body {
    .l itemconfigure 0 -fg #110022
    list [lindex [.l itemconfigure 0 -fg] 4] [.l itemcget 0 -fg]
} -cleanup {
    .l configure -fg #000000
} -result {{#110022} #110022}
test listbox-23.11 {configuration options} -body {
    .l configure -fg bogus

} -returnCodes error -result {unknown color name "bogus"}


test listbox-23.12 {configuration options} -body {
    .l itemconfigure 0 -foreground #110022
    list [lindex [.l itemconfigure 0 -foreground] 4] [.l itemcget 0 -foreground]
} -cleanup {
    .l configure -foreground #000000
} -result {{#110022} #110022}
test listbox-23.13 {configuration options} -body {
    .l configure -foreground bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-23.14 {configuration options} -body {
    .l itemconfigure 0 -selectbackground #110022
    list [lindex [.l itemconfigure 0 -selectbackground] 4] [.l itemcget 0 -selectbackground]
} -cleanup {
    .l configure -selectbackground #c3c3c3
} -result {{#110022} #110022}
test listbox-23.15 {configuration options} -body {
    .l configure -selectbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test listbox-23.16 {configuration options} -body {
    .l itemconfigure 0 -selectforeground #654321
    list [lindex [.l itemconfigure 0 -selectforeground] 4] [.l itemcget 0 -selectforeground]
} -cleanup {
    .l configure -selectforeground #000000
} -result {{#654321} #654321}
test listbox-23.17 {configuration options} -body {

    .l configure -selectforeground bogus
} -returnCodes error -result {unknown color name "bogus"}



# ListboxWidgetObjCmd, itemcget
test listbox-24.1 {itemcget} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemcget 0 -fg
} -cleanup {
    destroy .l
} -result {}
test listbox-24.2 {itemcget} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemconfigure 0 -fg red
    .l itemcget 0 -fg
} -cleanup {
    destroy .l
} -result red
test listbox-24.3 {itemcget} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    catch {.l itemcget 0} result
    set result
} -cleanup {
    destroy .l
} -result {wrong # args: should be ".l itemcget index option"}
test listbox-24.4 {itemcget, itemcg shortcut} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    catch {.l itemcg 0} result
    set result
} -cleanup {
    destroy .l
} -result {wrong # args: should be ".l itemcget index option"}


# General item configuration issues
test listbox-25.1 {listbox item configurations and widget based deletions} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a
    .l itemconfigure 0 -fg red
    .l delete 0 end
    .l insert end a
    .l itemcget 0 -fg
} -cleanup {
    destroy .l
} -result {}
test listbox-25.2 {listbox item configurations and widget based inserts} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l itemconfigure 0 -fg red
    .l insert 0 1 2 3 4
    list [.l itemcget 0 -fg] [.l itemcget 4 -fg]
} -cleanup {
    destroy .l
} -result {{} red}


# state issues
test listbox-26.1 {listbox disabled state disallows inserts} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l configure -state disabled
    .l insert end d e f
    .l get 0 end
} -cleanup {
    destroy .l
} -result [list a b c]
test listbox-26.2 {listbox disabled state disallows deletions} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l configure -state disabled
    .l delete 0 end
    .l get 0 end
} -cleanup {
    destroy .l
} -result [list a b c]
test listbox-26.3 {listbox disabled state disallows selection modification} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l selection set 0
    .l selection set 2
    .l configure -state disabled
    .l selection clear 0 end
    .l selection set 1
    .l curselection
} -cleanup {
    destroy .l
} -result [list 0 2]
test listbox-26.4 {listbox disabled state disallows anchor modification} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l selection anchor 0
    .l configure -state disabled
    .l selection anchor 2
    .l index anchor
} -cleanup {
    destroy .l
} -result 0
test listbox-26.5 {listbox disabled state disallows active modification} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c
    .l activate 0
    .l configure -state disabled
    .l activate 2
    .l index active
} -cleanup {
    destroy .l
} -result 0


test listbox-27.1 {widget deletion while active} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    update
    .l configure -cursor xterm -xscrollcommand { destroy .l }
    update idle
    winfo exists .l
} -cleanup {
    destroy .l
} -result 0


test listbox-28.1 {listbox -activestyle} -setup {
    destroy .l
} -body {
    listbox .l -activ non
    .l cget -activestyle
} -cleanup {
    destroy .l
} -result none
test listbox-28.2 {listbox -activestyle} -constraints {
	nonwin
} -setup {
    destroy .l
} -body {
    listbox .l
    .l cget -activestyle
} -cleanup {
    destroy .l
} -result dotbox
test listbox-28.3 {listbox -activestyle} -constraints {
	win
} -setup {
    destroy .l
} -body {
    listbox .l
    .l cget -activestyle
} -cleanup {
    destroy .l
} -result underline
test listbox-28.4 {listbox -activestyle} -setup {
    destroy .l
} -body {
    listbox .l -activestyle und
    .l cget -activestyle
} -cleanup {
    destroy .l
} -result underline


test listbox-29.1 {listbox selection behavior, -state disabled}  -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end 1 2 3
    .l selection set 2
    set out [.l selection includes 2]
    .l configure -state disabled
    # still return 1 when disabled, because 'selection get' will work,
    # but selection cannot be changed (new behavior since 8.4)
    .l selection set 3
    lappend out [.l selection includes 2] [.l curselection]
} -cleanup {
    destroy .l
} -result {1 1 2}

test listbox-30.1 {Bug 3607326} -setup {
    destroy .l
    unset -nocomplain a
} -body {
    array set a {}
    listbox .l -listvariable a







|
















<



<




<
<
<
|
|
<
|
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
>
|
|
>
>
>
|
|
|
|
|
|
|
<
|
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
|
|
|
<
|
|
<
|
<
>
|
|
<
<
<
<
<
<
<
<
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|
|
|
|
|
|
|
<


|
|
|
<
<
<
<
<
<
<
<
|
|
<
<
|
|
|
<

<
<
|

<
<
|





|
|
|
|
|
|
|
|
|
|
|
|
|


|
|


|
|


|
|


|
|
|
|
|
|
|
|
|
|
|



|
|
<
<









|
<
<
|
<
<



|
|
<
<



|
|
<
<



|
|
<
<
|
<








<
<
|
|
<
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|
|

|
|
|
|
|






|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<


|

<
<
|
|
|
<


|

<
<
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<



<
<
|
|
|
<


<
<
|
|
|
<



<
<
|
|

|
|
|
|
|
|
|
|

|
|

|
|

|
|

|
|

|
|
|
|
|
|
|
|
|
|
|

|
|

|
|

|
|

|
|
|
|
|
|
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<




<
<
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<










<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|


|
|


|
|


|
|




|
|
|
|
|





|
|


|
|



|
|


|
|
|
<


|
<
<
|




|
|
<
<

<

|
|
|
|
|
|
|
|

|
|
|
<



<
<
|
|
|
<
|
|
|

|
<
<
|
<
<
<
<
|
|
>
>
|
|
<
<
<
>
|
|
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<

|

|
<
<
|
|
<
<
<
<
<
<
<
<
<
|
|

|
<
<
|
|
<
<
<
<
<
<
<
<
<
|
|

|
<
<
|
|
<
<
<
<
<
<
<
<
<
|

|
|

|
<
<
|
|
|
<
|
|

|
<
<
|
|
|
<
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
|
>
|
|
>
>
|
|
>
>


<
<
|
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
<
<
<
<
<
|
|
|
<
<
|
|
<
<
<
<
<
<
|
|
|
<
<
|
|
<
<
<
<
<
<
|
|
|
<
<
|
|
<
|
<

>
>
>
|
>
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|




<
|
<
<
<
|


<
<





<
<
|

|
<
<
<
<
<
<


|
<
<
|
<
<
<
<
<
<






<
<
|


|
<
<
|
<
<











<
<
|
|
<
<
<
<
<















<
<
|


|
<
<
<
|









|
|



|


<
<
|
|
<
|

|

|






|


|
<
|
<
|

|
|
<
|

|

|



<
<
|
|
|
<

|
|
<
<
|
|
|
<

|
|
|
|
<
<
|
|
|
<

|
|
|
|
<
<
|
|
|
<


|
|
|
|

<
<
|
|
|
<

|
|
|

<
<
|
|
|
<

|

<
<
|
|
|
<


|
|

<
<
|
|
|
<

|
|

<
<
|
|
|
<
|
|
|
|
<
<
|
|
|
<
|
|

|
|
<
<
|

|
|
<

|
|
|
|
<
<
|

<



|
<
<
|
<



|
|
<
<
|
<




|
|
<
<
|
<





|
|
<
<
|
<




|
|
<
<
|
<





|
|
<
<


>


|
<
<


<
|



|






|
|





|
|





|
|






|
|






|
|





|
|





|
|



|
|



|
|







|
|







|
|
<
<
|
<







<
<
|
|
|
<




<
<
|
|
|
<





<
<
|
|









<
<
|



|





|





|





|
|




|
|




|
|





|
|





|
|





|
|





|
|






|
|






|
|






|
|






|
|





|
|





|
|





|
|





|
|





|
|







|
|







|
|
<
<
|
<







|
>
|
|
<




|

<
|
<
<
|
<






<
<
|

|
<
<
|
<







<
<
|
|

<







<
<
|

<
|

<



<
<
|
|
<
<
|
<





|


|
<

|
|

<
|
<
<
<
|
>
>
|
>

<

<
<
|
|
<
<
<
<

<

|
<
<
|
<
<
<
<


<


<
<
|
|
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<

|
<
<
|
<
<
<
<
<

<
<
|
|
>
|
|
|
|
<
|
>
|
>
>
>
>
>
>
|
|
|
>
|
>
>
|
>
>
>
>
|
|
<
<
|
<
<
|
|
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
|
|
<
<
|
|
|
|
<
<
|
|
<
<
|
<
<
<
<
|
|
>
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









<
<
|
|
|
<









<
<
|
|
|
<








<
<
|
|
|
<








<
<
|
|
|
<


<







<
<
|
|



<
<
<
|

<
|




|
<
<




|
|
<
<

<



|
|
<
<






|

<
<
|







|
<
<






|
|
<
<









|
|
<
<









|

<
|


|
<
|





|
<
<

|
|
<
<

|
|
<
<

<
|

<
<
<
<
<
|






|
|
<
<


>








<
<
|
|




|
|



|

|
|





|
|





|
|





|
|





|
|





|
|





<
|

|






|
|




|
|









|
|
<

<
|
<
<



>





|
<
<
|
<
<




>





<
<
|

<
<
|



|









|
|






|
|

|
|





<
<
|



>
>
|

<
|



|
<
<









|
|

|
|





|




>
>

|
<
|
<



|
|
<
<

<

|
|
<




<
<
|
|
|
<




<
<
|
|
|
<





|
<
<
|
|
<




|
<
<
|
|
<






|
<
<
|
|
<





|
<
<
|
|
<





|
<
<
|
|
<





|
<
<
|
|
|
|


|
<

|

|

<
<
|
|
|
<

>


|
<

|

|

|

<
<
|
|
|
<





<
<
|
|
|
>
>
>
>
>
>
|
>
>






<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
|
<






<
<
|
|
|
<






<
<
|
|
|
<

<
<

>

<
<


|

<
<
<
|
|
|
<



>











<
<
|

<

|
|
|


|
<
<

|

|

<
<
<
|

<

|
|
<



<
<
|
|
|
<



<
<
|





|
|
<



<
<
|
|
|
<




<
<
|
|
|
<












<
<
|
<
<
|


>
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
|
<
<
>
|
>
>
|
|
|
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
|
<
<
<
|
<
|
>
|
<
>
|


|
|
<



|
<
<
|
|
<




<
<
|
|
|
<




<
<
|
|
|
<




<
<
|

<

|
|
<






|
<
<
|
|
<





<
<
|

<

|
|
<





<
<
|
|
|
<





<
<
|
|
|
<








<
<
|
|
|
<






|
<
<
|
|
<






<
<
<
|

|

<





<
<
<
|

|

<


<
<
|
|
<
<

<


<
<
|
|
<
<

<


<
<
|
|

<


<
<
|

<
|

<









<
<
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63

64
65
66
67



68
69

70

71

72






73








74








75








76








77

78















79








80





81

82





83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99

































100
















101

102
103



104








105
106
107

108
109

110

111
112
113








114






















































115

116
117
118
119
120
121
122
123

124
125
126
127
128








129
130


131
132
133

134


135
136


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193
194
195


196


197
198
199
200
201


202
203
204
205
206


207
208
209
210
211


212

213
214
215
216
217
218
219
220


221
222


223
224
225




















































226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284


285
286
287

288
289
290
291


292
293
294

295
296
297
298


299
300
301

302
303
304
305


306
307
308

309
310
311
312


313
314
315

316
317
318
319


320
321
322

323
324
325
326


327
328
329

330
331
332
333


334
335
336
337
338
339
340
341
342
343
344
345
346
347
348

349
350
351


352
353
354

355
356


357
358
359

360
361
362


363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420


421
422
423

424
425
426
427


428
429
430

431
432
433
434


435
436
437

438
439
440
441


442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468


469

470
471
472
473
474
475
476
477
478
479


480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607


608
609
610
611
612
613
614


615

616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631


632
633
634

635
636
637
638
639


640




641
642
643
644
645
646



647
648
649


650
651
652
653
654
655
656
657









658
659
660
661


662
663









664
665
666
667


668
669









670
671
672
673


674
675









676
677
678
679
680
681


682
683
684

685
686
687
688


689
690
691

692
693
694
695














696
697
698



699
700
701
702
703
704
705
706
707
708
709
710


711








712
713
714
715
716
717
718






719
720
721


722
723






724
725
726


727
728






729
730
731


732
733

734

735
736
737
738
739
740










741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758

759



760
761
762


763
764
765
766
767


768
769
770






771
772
773


774






775
776
777
778
779
780


781
782
783
784


785


786
787
788
789
790
791
792
793
794
795
796


797
798





799
800
801
802
803
804
805
806
807
808
809
810
811
812
813


814
815
816
817



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835


836
837

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852

853

854
855
856
857

858
859
860
861
862
863
864
865


866
867
868

869
870
871


872
873
874

875
876
877
878
879


880
881
882

883
884
885
886
887


888
889
890

891
892
893
894
895
896
897


898
899
900

901
902
903
904
905


906
907
908

909
910
911


912
913
914

915
916
917
918
919


920
921
922

923
924
925
926


927
928
929

930
931
932
933


934
935
936

937
938
939
940
941


942
943
944
945

946
947
948
949
950


951
952

953
954
955
956


957

958
959
960
961
962


963

964
965
966
967
968
969


970

971
972
973
974
975
976
977


978

979
980
981
982
983
984


985

986
987
988
989
990
991
992


993
994
995
996
997
998


999
1000

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085


1086

1087
1088
1089
1090
1091
1092
1093


1094
1095
1096

1097
1098
1099
1100


1101
1102
1103

1104
1105
1106
1107
1108


1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119


1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268


1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286

1287


1288

1289
1290
1291
1292
1293
1294


1295
1296
1297


1298

1299
1300
1301
1302
1303
1304
1305


1306
1307
1308

1309
1310
1311
1312
1313
1314
1315


1316
1317

1318
1319

1320
1321
1322


1323
1324


1325

1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338

1339



1340
1341
1342
1343
1344
1345

1346


1347
1348




1349

1350
1351


1352




1353
1354

1355
1356


1357
1358





1359


1360
1361





1362
1363


1364





1365


1366
1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395


1396


1397
1398





1399
1400


1401





1402
1403


1404
1405
1406
1407


1408
1409


1410




1411
1412
1413
1414
1415
1416



























































































1417
1418
1419
1420
1421
1422
1423
1424
1425


1426
1427
1428

1429
1430
1431
1432
1433
1434
1435
1436
1437


1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
1448


1449
1450
1451

1452
1453
1454
1455
1456
1457
1458
1459


1460
1461
1462

1463
1464

1465
1466
1467
1468
1469
1470
1471


1472
1473
1474
1475
1476



1477
1478

1479
1480
1481
1482
1483
1484


1485
1486
1487
1488
1489
1490


1491

1492
1493
1494
1495
1496


1497
1498
1499
1500
1501
1502
1503
1504


1505
1506
1507
1508
1509
1510
1511
1512
1513


1514
1515
1516
1517
1518
1519
1520
1521


1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532


1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554


1555
1556
1557


1558
1559
1560


1561

1562
1563





1564
1565
1566
1567
1568
1569
1570
1571
1572


1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583


1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666

1667

1668


1669
1670
1671
1672
1673
1674
1675
1676
1677
1678


1679


1680
1681
1682
1683
1684
1685
1686
1687
1688
1689


1690
1691


1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723


1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736


1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764

1765

1766
1767
1768
1769
1770


1771

1772
1773
1774

1775
1776
1777
1778


1779
1780
1781

1782
1783
1784
1785


1786
1787
1788

1789
1790
1791
1792
1793
1794


1795
1796

1797
1798
1799
1800
1801


1802
1803

1804
1805
1806
1807
1808
1809
1810


1811
1812

1813
1814
1815
1816
1817
1818


1819
1820

1821
1822
1823
1824
1825
1826


1827
1828

1829
1830
1831
1832
1833
1834


1835
1836
1837
1838
1839
1840
1841

1842
1843
1844
1845
1846


1847
1848
1849

1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861


1862
1863
1864

1865
1866
1867
1868
1869


1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887





1888









1889
1890

1891
1892
1893
1894
1895
1896


1897
1898
1899

1900
1901
1902
1903
1904
1905


1906
1907
1908

1909


1910
1911
1912


1913
1914
1915
1916



1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934


1935
1936

1937
1938
1939
1940
1941
1942
1943


1944
1945
1946
1947
1948



1949
1950

1951
1952
1953

1954
1955
1956


1957
1958
1959

1960
1961
1962


1963
1964
1965
1966
1967
1968
1969
1970

1971
1972
1973


1974
1975
1976

1977
1978
1979
1980


1981
1982
1983

1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995


1996


1997
1998
1999
2000
2001
2002






2003








2004

2005



2006


2007
2008
2009
2010
2011
2012
2013








2014
2015


2016


2017



2018

2019
2020
2021

2022
2023
2024
2025
2026
2027

2028
2029
2030
2031


2032
2033

2034
2035
2036
2037


2038
2039
2040

2041
2042
2043
2044


2045
2046
2047

2048
2049
2050
2051


2052
2053

2054
2055
2056

2057
2058
2059
2060
2061
2062
2063


2064
2065

2066
2067
2068
2069
2070


2071
2072

2073
2074
2075

2076
2077
2078
2079
2080


2081
2082
2083

2084
2085
2086
2087
2088


2089
2090
2091

2092
2093
2094
2095
2096
2097
2098
2099


2100
2101
2102

2103
2104
2105
2106
2107
2108
2109


2110
2111

2112
2113
2114
2115
2116
2117



2118
2119
2120
2121

2122
2123
2124
2125
2126



2127
2128
2129
2130

2131
2132


2133
2134


2135

2136
2137


2138
2139


2140

2141
2142


2143
2144
2145

2146
2147


2148
2149

2150
2151

2152
2153
2154
2155
2156
2157
2158
2159
2160


2161
2162
2163
2164
2165
2166
2167
2168
    wm deiconify .
}

# Procedure that creates a second listbox for checking things related
# to partially visible lines.

proc mkPartial {{w .partial}} {
    catch {destroy $w}
    toplevel $w
    wm geometry $w +0+0
    listbox $w.l -width 30 -height 5
    pack $w.l -expand 1 -fill both
    $w.l insert end one two three four five six seven eight nine ten \
	    eleven twelve thirteen fourteen fifteen
    update
    scan [wm geometry $w] "%dx%d" width height
    wm geometry $w ${width}x[expr $height-3]
    update
}

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Listbox.borderWidth 2

option add *Listbox.highlightThickness 2
option add *Listbox.font {Helvetica -12 bold}


listbox .l
pack .l
update
resetGridInfo



set i 1


foreach test {

    {-activestyle under underline foo {bad activestyle "foo": must be dotbox, none, or underline}}

    {-background #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}








    {-bd 4 4 badValue {bad screen distance "badValue"}}








    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}








    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}








    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}

    {-disabledforeground #110022 #110022 bogus {unknown color name "bogus"}}















    {-exportselection yes 1 xyzzy {expected boolean value but got "xyzzy"}}








    {-fg #110022 #110022 bogus {unknown color name "bogus"}}





    {-font {Helvetica 12} {Helvetica 12} {} {font "" doesn't exist}}

    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}





    {-height 30 30 20p {expected integer but got "20p"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}
    {-highlightthickness -2 0 {} {}}
    {-relief groove groove 1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    {-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
    {-selectborderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}
    {-selectmode string string {} {}}
    {-setgrid false 0 lousy {expected boolean value but got "lousy"}}
    {-state disabled disabled foo {bad state "foo": must be disabled or normal}}
    {-takefocus "any string" "any string" {} {}}

    {-width 45 45 3p {expected integer but got "3p"}}
    {-xscrollcommand {Some command} {Some command} {} {}}
    {-yscrollcommand {Another command} {Another command} {} {}}
    {-listvar testVariable testVariable {} {}}

































} {
















    set name [lindex $test 0]

    test listbox-1.$i {configuration options} {
	.l configure $name [lindex $test 1]



	list [lindex [.l configure $name] 4] [.l cget $name]








    } [list [lindex $test 2] [lindex $test 2]]
    incr i
    if {[lindex $test 3] != ""} {

	test listbox-1.$i {configuration options} {
	    list [catch {.l configure $name [lindex $test 3]} msg] $msg

	} [list 1 [lindex $test 4]]

    }
    .l configure $name [lindex [.l configure $name] 3]
    incr i








}
























































test listbox-2.1 {Tk_ListboxCmd procedure} {
    list [catch {listbox} msg] $msg
} {1 {wrong # args: should be "listbox pathName ?options?"}}
test listbox-2.2 {Tk_ListboxCmd procedure} {
    list [catch {listbox gorp} msg] $msg
} {1 {bad window path name "gorp"}}
test listbox-2.3 {Tk_ListboxCmd procedure} {
    catch {destroy .l}

    listbox .l
    list [winfo exists .l] [winfo class .l] [info commands .l]
} {1 Listbox .l}
test listbox-2.4 {Tk_ListboxCmd procedure} {
    catch {destroy .l}








    list [catch {listbox .l -gorp foo} msg] $msg [winfo exists .l] \
	    [info commands .l]


} {1 {unknown option "-gorp"} 0 {}}
test listbox-2.5 {Tk_ListboxCmd procedure} {
    catch {destroy .l}

    listbox .l


} {.l}



catch {destroy .l}
listbox .l -width 20 -height 5 -bd 4 -highlightthickness 1 -selectborderwidth 2
pack .l
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11 el12 el13 el14 \
	el15 el16 el17
update
test listbox-3.1 {ListboxWidgetCmd procedure} {
    list [catch .l msg] $msg
} {1 {wrong # args: should be ".l option ?arg arg ...?"}}
test listbox-3.2 {ListboxWidgetCmd procedure, "activate" option} {
    list [catch {.l activate} msg] $msg
} {1 {wrong # args: should be ".l activate index"}}
test listbox-3.3 {ListboxWidgetCmd procedure, "activate" option} {
    list [catch {.l activate a b} msg] $msg
} {1 {wrong # args: should be ".l activate index"}}
test listbox-3.4 {ListboxWidgetCmd procedure, "activate" option} {
    list [catch {.l activate fooey} msg] $msg
} {1 {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}}
test listbox-3.5 {ListboxWidgetCmd procedure, "activate" option} {
    .l activate 3
    .l index active
} 3
test listbox-3.6 {ListboxWidgetCmd procedure, "activate" option} {
    .l activate -1
    .l index active
} {0}
test listbox-3.7 {ListboxWidgetCmd procedure, "activate" option} {
    .l activate 30
    .l index active
} {17}
test listbox-3.8 {ListboxWidgetCmd procedure, "activate" option} {
    .l activate end
    .l index active
} {17}
test listbox-3.9 {ListboxWidgetCmd procedure, "bbox" option} {
    list [catch {.l bbox} msg] $msg
} {1 {wrong # args: should be ".l bbox index"}}
test listbox-3.10 {ListboxWidgetCmd procedure, "bbox" option} {
    list [catch {.l bbox a b} msg] $msg
} {1 {wrong # args: should be ".l bbox index"}}
test listbox-3.11 {ListboxWidgetCmd procedure, "bbox" option} {
    list [catch {.l bbox fooey} msg] $msg
} {1 {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}}
test listbox-3.12 {ListboxWidgetCmd procedure, "bbox" option} {
    .l yview 3
    update
    list [.l bbox 2] [.l bbox 8]
} {{} {}}
test listbox-3.13 {ListboxWidgetCmd procedure, "bbox" option} {


    # Used to generate a core dump before a bug was fixed (the last
    # element would be on-screen if it existed, but it doesn't exist).

    listbox .l2
    pack .l2 -side top
    tkwait visibility .l2
    set x [.l2 bbox 0]
    destroy .l2
    set x
} {}


test listbox-3.14 {ListboxWidgetCmd procedure, "bbox" option} {fonts} {


    .l yview 3
    update
    list [.l bbox 3] [.l bbox 4]
} {{7 7 17 14} {7 26 17 14}}
test listbox-3.15 {ListboxWidgetCmd procedure, "bbox" option} {fonts} {


    .l yview 0
    update
    list [.l bbox -1] [.l bbox 0]
} {{} {7 7 17 14}}
test listbox-3.16 {ListboxWidgetCmd procedure, "bbox" option} {fonts} {


    .l yview end
    update
    list [.l bbox 17] [.l bbox end] [.l bbox 18]
} {{7 83 24 14} {7 83 24 14} {}}
test listbox-3.17 {ListboxWidgetCmd procedure, "bbox" option} {fonts failsOnQuarz} {


    catch {destroy .t}

    toplevel .t
    wm geom .t +0+0
    listbox .t.l -width 10 -height 5
    .t.l insert 0 "Short" "Somewhat longer" "Really, quite a whole lot longer than can possibly fit on the screen" "Short"
    pack .t.l
    update
    .t.l xview moveto .2
    .t.l bbox 2


} {-72 39 393 14}
test listbox-3.18 {ListboxWidgetCmd procedure, "bbox" option, partial last line} {fonts failsOnQuarz} {


    mkPartial
    list [.partial.l bbox 3] [.partial.l bbox 4]
} {{5 56 24 14} {5 73 23 14}}




















































test listbox-3.19 {ListboxWidgetCmd procedure, "cget" option} {
    list [catch {.l cget} msg] $msg
} {1 {wrong # args: should be ".l cget option"}}
test listbox-3.20 {ListboxWidgetCmd procedure, "cget" option} {
    list [catch {.l cget a b} msg] $msg
} {1 {wrong # args: should be ".l cget option"}}
test listbox-3.21 {ListboxWidgetCmd procedure, "cget" option} {
    list [catch {.l cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} {
    .l cget -setgrid
} {0}
test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} {
    llength [.l configure]
} {27}
test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} {
    list [catch {.l configure -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test listbox-3.25 {ListboxWidgetCmd procedure, "configure" option} {
    .l configure -setgrid
} {-setgrid setGrid SetGrid 0 0}
test listbox-3.26 {ListboxWidgetCmd procedure, "configure" option} {
    list [catch {.l configure -gorp is_messy} msg] $msg
} {1 {unknown option "-gorp"}}
test listbox-3.27 {ListboxWidgetCmd procedure, "configure" option} {
    set oldbd [.l cget -bd]
    set oldht [.l cget -highlightthickness]
    .l configure -bd 3 -highlightthickness 0
    set x "[.l cget -bd] [.l cget -highlightthickness]"
    .l configure -bd $oldbd -highlightthickness $oldht
    set x
} {3 0}
test listbox-3.28 {ListboxWidgetCmd procedure, "curselection" option} {
    list [catch {.l curselection a} msg] $msg
} {1 {wrong # args: should be ".l curselection"}}
test listbox-3.29 {ListboxWidgetCmd procedure, "curselection" option} {
    .l selection clear 0 end
    .l selection set 3 6
    .l selection set 9
    .l curselection
} {3 4 5 6 9}
test listbox-3.30 {ListboxWidgetCmd procedure, "delete" option} {
    list [catch {.l delete} msg] $msg
} {1 {wrong # args: should be ".l delete firstIndex ?lastIndex?"}}
test listbox-3.31 {ListboxWidgetCmd procedure, "delete" option} {
    list [catch {.l delete a b c} msg] $msg
} {1 {wrong # args: should be ".l delete firstIndex ?lastIndex?"}}
test listbox-3.32 {ListboxWidgetCmd procedure, "delete" option} {
    list [catch {.l delete badIndex} msg] $msg
} {1 {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}}
test listbox-3.33 {ListboxWidgetCmd procedure, "delete" option} {
    list [catch {.l delete 2 123ab} msg] $msg
} {1 {bad listbox index "123ab": must be active, anchor, end, @x,y, or a number}}
test listbox-3.34 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 3
    list [.l2 get 2] [.l2 get 3] [.l2 index end]


} {el2 el4 7}
test listbox-3.35 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 2 4
    list [.l2 get 1] [.l2 get 2] [.l2 index end]


} {el1 el5 5}
test listbox-3.36 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -3 2
    .l2 get 0 end


} {el3 el4 el5 el6 el7}
test listbox-3.37 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -3 -1
    .l2 get 0 end


} {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.38 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 2 end
    .l2 get 0 end


} {el0 el1}
test listbox-3.39 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 5 20
    .l2 get 0 end


} {el0 el1 el2 el3 el4}
test listbox-3.40 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete end 20
    .l2 get 0 end


} {el0 el1 el2 el3 el4 el5 el6}
test listbox-3.41 {ListboxWidgetCmd procedure, "delete" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 8 20
    .l2 get 0 end


} {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.42 {ListboxWidgetCmd procedure, "get" option} {
    list [catch {.l get} msg] $msg
} {1 {wrong # args: should be ".l get firstIndex ?lastIndex?"}}
test listbox-3.43 {ListboxWidgetCmd procedure, "get" option} {
    list [catch {.l get a b c} msg] $msg
} {1 {wrong # args: should be ".l get firstIndex ?lastIndex?"}}
test listbox-3.44 {ListboxWidgetCmd procedure, "get" option} {
    list [catch {.l get 2.4} msg] $msg
} {1 {bad listbox index "2.4": must be active, anchor, end, @x,y, or a number}}
test listbox-3.45 {ListboxWidgetCmd procedure, "get" option} {
    list [catch {.l get end bogus} msg] $msg
} {1 {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}}
test listbox-3.46 {ListboxWidgetCmd procedure, "get" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    list [.l2 get 0] [.l2 get 3] [.l2 get end]


} {el0 el3 el7}
test listbox-3.47 {ListboxWidgetCmd procedure, "get" option} {
    catch {destroy .l2}

    listbox .l2
    list [.l2 get 0] [.l2 get end]


} {{} {}}
test listbox-3.48 {ListboxWidgetCmd procedure, "get" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 el0 el1 el2 "two words" el4 el5 el6 el7
    .l2 get 3 end


} {{two words} el4 el5 el6 el7}
test listbox-3.49 {ListboxWidgetCmd procedure, "get" option} {
    .l get -1
} {}
test listbox-3.50 {ListboxWidgetCmd procedure, "get" option} {
    .l get -2 -1
} {}
test listbox-3.51 {ListboxWidgetCmd procedure, "get" option} {
    .l get -2 3
} {el0 el1 el2 el3}
test listbox-3.52 {ListboxWidgetCmd procedure, "get" option} {
    .l get 12 end
} {el12 el13 el14 el15 el16 el17}
test listbox-3.53 {ListboxWidgetCmd procedure, "get" option} {
    .l get 12 20
} {el12 el13 el14 el15 el16 el17}
test listbox-3.54 {ListboxWidgetCmd procedure, "get" option} {
    .l get end
} {el17}
test listbox-3.55 {ListboxWidgetCmd procedure, "get" option} {
    .l get 30
} {}
test listbox-3.56 {ListboxWidgetCmd procedure, "get" option} {
    .l get 30 35
} {}
test listbox-3.57 {ListboxWidgetCmd procedure, "index" option} {
    list [catch {.l index} msg] $msg
} {1 {wrong # args: should be ".l index index"}}
test listbox-3.58 {ListboxWidgetCmd procedure, "index" option} {
    list [catch {.l index a b} msg] $msg
} {1 {wrong # args: should be ".l index index"}}
test listbox-3.59 {ListboxWidgetCmd procedure, "index" option} {
    list [catch {.l index @} msg] $msg
} {1 {bad listbox index "@": must be active, anchor, end, @x,y, or a number}}
test listbox-3.60 {ListboxWidgetCmd procedure, "index" option} {
    .l index 2
} 2
test listbox-3.61 {ListboxWidgetCmd procedure, "index" option} {
    .l index -1
} -1
test listbox-3.62 {ListboxWidgetCmd procedure, "index" option} {
    .l index end
} 18
test listbox-3.63 {ListboxWidgetCmd procedure, "index" option} {
    .l index 34
} 34
test listbox-3.64 {ListboxWidgetCmd procedure, "insert" option} {
    list [catch {.l insert} msg] $msg
} {1 {wrong # args: should be ".l insert index ?element element ...?"}}
test listbox-3.65 {ListboxWidgetCmd procedure, "insert" option} {
    list [catch {.l insert badIndex} msg] $msg
} {1 {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}}
test listbox-3.66 {ListboxWidgetCmd procedure, "insert" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert end a b c d e
    .l2 insert 3 x y z
    .l2 get 0 end


} {a b c x y z d e}
test listbox-3.67 {ListboxWidgetCmd procedure, "insert" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert end a b c
    .l2 insert -1 x
    .l2 get 0 end


} {x a b c}
test listbox-3.68 {ListboxWidgetCmd procedure, "insert" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert end a b c
    .l2 insert end x
    .l2 get 0 end


} {a b c x}
test listbox-3.69 {ListboxWidgetCmd procedure, "insert" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert end a b c
    .l2 insert 43 x
    .l2 get 0 end


} {a b c x}
test listbox-3.70 {ListboxWidgetCmd procedure, "nearest" option} {
    list [catch {.l nearest} msg] $msg
} {1 {wrong # args: should be ".l nearest y"}}
test listbox-3.71 {ListboxWidgetCmd procedure, "nearest" option} {
    list [catch {.l nearest a b} msg] $msg
} {1 {wrong # args: should be ".l nearest y"}}
test listbox-3.72 {ListboxWidgetCmd procedure, "nearest" option} {
    list [catch {.l nearest 20p} msg] $msg
} {1 {expected integer but got "20p"}}
test listbox-3.73 {ListboxWidgetCmd procedure, "nearest" option} {
    .l yview 3
    .l nearest 1000
} {7}
test listbox-3.74 {ListboxWidgetCmd procedure, "scan" option} {
    list [catch {.l scan a b} msg] $msg
} {1 {wrong # args: should be ".l scan mark|dragto x y"}}
test listbox-3.75 {ListboxWidgetCmd procedure, "scan" option} {
    list [catch {.l scan a b c d} msg] $msg
} {1 {wrong # args: should be ".l scan mark|dragto x y"}}
test listbox-3.76 {ListboxWidgetCmd procedure, "scan" option} {
    list [catch {.l scan foo bogus 2} msg] $msg
} {1 {expected integer but got "bogus"}}
test listbox-3.77 {ListboxWidgetCmd procedure, "scan" option} {
    list [catch {.l scan foo 2 2.3} msg] $msg
} {1 {expected integer but got "2.3"}}
test listbox-3.78 {ListboxWidgetCmd procedure, "scan" option} {fonts failsOnQuarz} {


    catch {destroy .t}

    toplevel .t
    wm geom .t +0+0
    listbox .t.l -width 10 -height 5
    .t.l insert 0 "Short" "Somewhat longer" "Really, quite a whole lot longer than can possibly fit on the screen" "Short" a b c d e f g h i j
    pack .t.l
    update
    .t.l scan mark 100 140
    .t.l scan dragto 90 137
    update
    list [format {%.6g %.6g} {*}[.t.l xview]] [format {%.6g %.6g} {*}[.t.l yview]]


} {{0.249364 0.427481} {0.0714286 0.428571}}
test listbox-3.79 {ListboxWidgetCmd procedure, "scan" option} {
    list [catch {.l scan foo 2 4} msg] $msg
} {1 {bad option "foo": must be mark or dragto}}
test listbox-3.80 {ListboxWidgetCmd procedure, "see" option} {
    list [catch {.l see} msg] $msg
} {1 {wrong # args: should be ".l see index"}}
test listbox-3.81 {ListboxWidgetCmd procedure, "see" option} {
    list [catch {.l see a b} msg] $msg
} {1 {wrong # args: should be ".l see index"}}
test listbox-3.82 {ListboxWidgetCmd procedure, "see" option} {
    list [catch {.l see gorp} msg] $msg
} {1 {bad listbox index "gorp": must be active, anchor, end, @x,y, or a number}}
test listbox-3.83 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 7
    .l index @0,0
} {7}
test listbox-3.84 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 11
    .l index @0,0
} {7}
test listbox-3.85 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 6
    .l index @0,0
} {6}
test listbox-3.86 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 5
    .l index @0,0
} {3}
test listbox-3.87 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 12
    .l index @0,0
} {8}
test listbox-3.88 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 13
    .l index @0,0
} {11}
test listbox-3.89 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see -1
    .l index @0,0
} {0}
test listbox-3.90 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see end
    .l index @0,0
} {13}
test listbox-3.91 {ListboxWidgetCmd procedure, "see" option} {
    .l yview 7
    .l see 322
    .l index @0,0
} {13}
test listbox-3.92 {ListboxWidgetCmd procedure, "see" option, partial last line} {
    mkPartial
    .partial.l see 4
    .partial.l index @0,0
} {1}
test listbox-3.93 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l select a} msg] $msg
} {1 {wrong # args: should be ".l selection option index ?index?"}}
test listbox-3.94 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l select a b c d} msg] $msg
} {1 {wrong # args: should be ".l selection option index ?index?"}}
test listbox-3.95 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l selection a bogus} msg] $msg
} {1 {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}}
test listbox-3.96 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l selection a 0 lousy} msg] $msg
} {1 {bad listbox index "lousy": must be active, anchor, end, @x,y, or a number}}
test listbox-3.97 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l selection anchor 0 0} msg] $msg
} {1 {wrong # args: should be ".l selection anchor index"}}
test listbox-3.98 {ListboxWidgetCmd procedure, "selection" option} {
    list [.l selection anchor 5; .l index anchor] \
	    [.l selection anchor 0; .l index anchor]
} {5 0}
test listbox-3.99 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection anchor -1
    .l index anchor
} {0}
test listbox-3.100 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection anchor end
    .l index anchor
} {17}
test listbox-3.101 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection anchor 44
    .l index anchor
} {17}
test listbox-3.102 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection clear 0 end
    .l selection set 2 8
    .l selection clear 3 4
    .l curselection
} {2 5 6 7 8}
test listbox-3.103 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l selection includes 0 0} msg] $msg
} {1 {wrong # args: should be ".l selection includes index"}}
test listbox-3.104 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection clear 0 end
    .l selection set 2 8
    .l selection clear 4
    list [.l selection includes 3] [.l selection includes 4] \
	    [.l selection includes 5]
} {1 0 1}
test listbox-3.105 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection set 0 end
    .l selection includes -1
} {0}
test listbox-3.106 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection clear 0 end
    .l selection set end
    .l selection includes end
} {1}
test listbox-3.107 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection set 0 end
    .l selection includes 44
} {0}
test listbox-3.108 {ListboxWidgetCmd procedure, "selection" option} {
    catch {destroy .l2}

    listbox .l2
    .l2 selection includes 0
} {0}


test listbox-3.109 {ListboxWidgetCmd procedure, "selection" option} {
    .l selection clear 0 end
    .l selection set 2
    .l selection set 5 7
    .l curselection
} {2 5 6 7}
test listbox-3.110 {ListboxWidgetCmd procedure, "selection" option} {


    .l selection set 5 7

    .l curselection
} {2 5 6 7}
test listbox-3.111 {ListboxWidgetCmd procedure, "selection" option} {
    list [catch {.l selection badOption 0 0} msg] $msg
} {1 {bad option "badOption": must be anchor, clear, includes, or set}}
test listbox-3.112 {ListboxWidgetCmd procedure, "size" option} {
    list [catch {.l size a} msg] $msg
} {1 {wrong # args: should be ".l size"}}
test listbox-3.113 {ListboxWidgetCmd procedure, "size" option} {
    .l size
} {18}
test listbox-3.114 {ListboxWidgetCmd procedure, "xview" option} {
    catch {destroy .l2}

    listbox .l2
    update
    format {%.6g %.6g} {*}[.l2 xview]


} {0 1}
test listbox-3.115 {ListboxWidgetCmd procedure, "xview" option} {
    catch {destroy .l}

    listbox .l -width 10 -height 5 -font $fixed
    .l insert 0 a b c d e f g h i j k l m n o p q r s t
    pack .l
    update
    format {%.6g %.6g} {*}[.l xview]


} {0 1}




catch {destroy .l}
listbox .l -width 10 -height 5 -font $fixed
.l insert 0 a b c d e f g h i j k l m n o p q r s t
.l insert 1 "0123456789a123456789b123456789c123456789d123456789"
pack .l
update



test listbox-3.116 {ListboxWidgetCmd procedure, "xview" option} {fonts} {
    .l xview 4
    format {%.6g %.6g} {*}[.l xview]


} {0.08 0.28}
test listbox-3.117 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l xview foo} msg] $msg
} {1 {expected integer but got "foo"}}
test listbox-3.118 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l xview zoom a b} msg] $msg
} {1 {unknown option "zoom": must be moveto or scroll}}
test listbox-3.119 {ListboxWidgetCmd procedure, "xview" option} {fonts} {









    .l xview 0
    .l xview moveto .4
    update
    format {%.6g %.6g} {*}[.l xview]


} {0.4 0.6}
test listbox-3.120 {ListboxWidgetCmd procedure, "xview" option} {fonts} {









    .l xview 0
    .l xview scroll 2 units
    update
    format {%.6g %.6g} {*}[.l xview]


} {0.04 0.24}
test listbox-3.121 {ListboxWidgetCmd procedure, "xview" option} {fonts} {









    .l xview 30
    .l xview scroll -1 pages
    update
    format {%.6g %.6g} {*}[.l xview]


} {0.44 0.64}
test listbox-3.122 {ListboxWidgetCmd procedure, "xview" option} {fonts} {









    .l configure -width 1
    update
    .l xview 30
    .l xview scroll -4 pages
    update
    format {%.6g %.6g} {*}[.l xview]


} {0.52 0.54}
test listbox-3.123 {ListboxWidgetCmd procedure, "yview" option} {
    catch {destroy .l}

    listbox .l
    pack  .l
    update
    format {%.6g %.6g} {*}[.l yview]


} {0 1}
test listbox-3.124 {ListboxWidgetCmd procedure, "yview" option} {
    catch {destroy .l}

    listbox .l
    .l insert 0 el1
    pack  .l
    update














    format {%.6g %.6g} {*}[.l yview]
} {0 1}
catch {destroy .l}



listbox .l -width 10 -height 5 -font $fixed
.l insert 0 a b c d e f g h i j k l m n o p q r s t
pack .l
update
test listbox-3.125 {ListboxWidgetCmd procedure, "yview" option} {
    .l yview 4
    update
    format {%.6g %.6g} {*}[.l yview]
} {0.2 0.45}
test listbox-3.126 {ListboxWidgetCmd procedure, "yview" option, partial last line} {
    mkPartial
    format {%.6g %.6g} {*}[.partial.l yview]


} {0 0.266667}








test listbox-3.127 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l yview foo} msg] $msg
} {1 {bad listbox index "foo": must be active, anchor, end, @x,y, or a number}}
test listbox-3.128 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l yview foo a b} msg] $msg
} {1 {unknown option "foo": must be moveto or scroll}}
test listbox-3.129 {ListboxWidgetCmd procedure, "xview" option} {






    .l yview 0
    .l yview moveto .31
    format {%.6g %.6g} {*}[.l yview]


} {0.3 0.55}
test listbox-3.130 {ListboxWidgetCmd procedure, "xview" option} {






    .l yview 2
    .l yview scroll 2 pages
    format {%.6g %.6g} {*}[.l yview]


} {0.4 0.65}
test listbox-3.131 {ListboxWidgetCmd procedure, "xview" option} {






    .l yview 10
    .l yview scroll -3 units
    format {%.6g %.6g} {*}[.l yview]


} {0.35 0.6}
test listbox-3.132 {ListboxWidgetCmd procedure, "xview" option} {

    .l configure -height 2

    update
    .l yview 15
    .l yview scroll -4 pages
    format {%.6g %.6g} {*}[.l yview]
} {0.55 0.65}
test listbox-3.133 {ListboxWidgetCmd procedure, "xview" option} {










    list [catch {.l whoknows} msg] $msg
} {1 {bad option "whoknows": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}}
test listbox-3.134 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l c} msg] $msg
} {1 {ambiguous option "c": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}}
test listbox-3.135 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l in} msg] $msg
} {1 {ambiguous option "in": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}}
test listbox-3.136 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l s} msg] $msg
} {1 {ambiguous option "s": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}}
test listbox-3.137 {ListboxWidgetCmd procedure, "xview" option} {
    list [catch {.l se} msg] $msg
} {1 {ambiguous option "se": must be activate, bbox, cget, configure, curselection, delete, get, index, insert, itemcget, itemconfigure, nearest, scan, see, selection, size, xview, or yview}}

# No tests for DestroyListbox:  I can't come up with anything to test
# in this procedure.


test listbox-4.1 {ConfigureListbox procedure} {fonts failsOnQuarz} {



    catch {destroy .l}
    listbox .l -setgrid 1 -width 25 -height 15
    pack .l


    update
    set x [getsize .]
    .l configure -setgrid 0
    update
    list $x [getsize .]


} {25x15 185x263}
resetGridInfo
test listbox-4.2 {ConfigureListbox procedure} {






    .l configure -highlightthickness -3
    .l cget -highlightthickness
} {0}


test listbox-4.3 {ConfigureListbox procedure} {






    .l configure -exportselection 0
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 3 5
    .l configure -exportselection 1
    selection get


} {el3
el4
el5}
test listbox-4.4 {ConfigureListbox procedure} {


    catch {destroy .e}


    entry .e
    .e insert 0 abc
    .e select from 0
    .e select to 2
    .l configure -exportselection 0
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 3 5
    .l selection clear 3 5
    .l configure -exportselection 1
    list [selection own] [selection get]


} {.e ab}
test listbox-4.5 {-exportselection option} {





    selection clear .
    .l configure -exportselection 1
    .l delete 0 end
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8
    .l selection set 1 1
    set x {}
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l config -exportselection 0
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l selection clear 0 end
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l selection set 1 3
    lappend x [catch {selection get} msg] $msg [.l curselection]
    .l config -exportselection 1
    lappend x [catch {selection get} msg] $msg [.l curselection]


} {0 el1 1 1 {PRIMARY selection doesn't exist or form "STRING" not defined} 1 1 {PRIMARY selection doesn't exist or form "STRING" not defined} {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined} {1 2 3} 0 {el1
el2
el3} {1 2 3}}
test listbox-4.6 {ConfigureListbox procedure} {fonts failsOnQuarz} {



    catch {destroy .l}

    # The following code (reset geometry, withdraw, etc.) is necessary
    # to reset the state of some window managers like olvwm under
    # SunOS 4.1.3.

    wm geom . 300x300
    update
    wm geom . {}
    wm withdraw .
    listbox .l -font $fixed -width 15 -height 20
    pack .l
    update
    wm deiconify .
    set x [getsize .]
    .l configure -setgrid 1
    update
    list $x [getsize .]


} {115x328 15x20}
test listbox-4.7 {ConfigureListbox procedure} {

    catch {destroy .l}
    wm withdraw .
    listbox .l -font $fixed -width 30 -height 20 -setgrid 1
    wm geom . +25+25
    pack .l
    update
    wm deiconify .
    set result [getsize .]
    wm geom . 26x15
    update
    lappend result [getsize .]
    .l configure -setgrid 1
    update
    lappend result [getsize .]
} {30x20 26x15 26x15}

wm geom . {}

catch {destroy .l}
resetGridInfo
test listbox-4.8 {ConfigureListbox procedure} {
    catch {destroy .l}

    listbox .l -width 15 -height 20 -xscrollcommand "record x" \
	    -yscrollcommand "record y"
    pack .l
    update
    .l configure -fg black
    set log {}
    update
    set log


} {{y 0 1} {x 0 1}}
test listbox-4.9 {ConfigureListbox procedure, -listvar} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l get 0 end


} [list a b c d]
test listbox-4.10 {ConfigureListbox, no listvar -> existing listvar} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l
    .l insert end 1 2 3 4
    .l configure -listvar x
    .l get 0 end


} [list a b c d]
test listbox-4.11 {ConfigureListbox procedure, listvar -> no listvar} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l configure -listvar {}
    .l insert end 1 2 3 4
    list $x [.l get 0 end]


} [list [list a b c d] [list a b c d 1 2 3 4]]
test listbox-4.12 {ConfigureListbox procedure, listvar -> different listvar} {
    catch {destroy .l}

    set x [list a b c d]
    set y [list 1 2 3 4]
    listbox .l
    .l configure -listvar x
    .l configure -listvar y
    .l insert end 5 6 7 8
    list $x $y


} [list [list a b c d] [list 1 2 3 4 5 6 7 8]]
test listbox-4.13 {ConfigureListbox, no listvar -> non-existant listvar} {
    catch {destroy .l}

    catch {unset x}
    listbox .l
    .l insert end a b c d
    .l configure -listvar x
    set x


} [list a b c d]
test listbox-4.14 {ConfigureListbox, non-existant listvar} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x
    list [info exists x] $x


} [list 1 {}]
test listbox-4.15 {ConfigureListbox, listvar -> non-existant listvar} {
    catch {destroy .l}

    catch {unset y}
    set x [list a b c d]
    listbox .l -listvar x
    .l configure -listvar y
    list [info exists y] $y


} [list 1 [list a b c d]]
test listbox-4.16 {ConfigureListbox, listvar -> same listvar} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l configure -listvar x
    set x


} [list a b c d]
test listbox-4.17 {ConfigureListbox, no listvar -> no listvar} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    .l configure -listvar {}
    .l get 0 end


} [list a b c d]
test listbox-4.18 {ConfigureListbox, no listvar -> bad listvar} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    set x "this is a \" bad list"
    catch {.l configure -listvar x} result
    list [.l get 0 end] [.l cget -listvar] $result


} [list [list a b c d] {} \
	"unmatched open quote in list: invalid -listvariable value"]
test listbox-4.19 {ConfigureListbox, no listvar -> bad non-existent listvar} {
    catch {destroy .l}

    unset -nocomplain ::foo
    listbox .l -listvar foo
    .l insert end a b c d
    catch {.l configure -listvar ::zoo::bar::foo} result
    list [.l get 0 end] [.l cget -listvar] $foo $result


} [list [list a b c d] foo [list a b c d] \
	{can't set "::zoo::bar::foo": parent namespace doesn't exist}]


# No tests for DisplayListbox:  I don't know how to test this procedure.

test listbox-5.1 {ListboxComputeGeometry procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -font $fixed -width 15 -height 20
    pack .l
    list [winfo reqwidth .l] [winfo reqheight .l]
} {115 328}
test listbox-5.2 {ListboxComputeGeometry procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -font $fixed -width 0 -height 10
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} {17 168}
test listbox-5.3 {ListboxComputeGeometry procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -font $fixed -width 0 -height 10 -bd 3
    .l insert 0 Short "Really much longer" Longer
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} {138 170}
test listbox-5.4 {ListboxComputeGeometry procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -font $fixed -width 10 -height 0
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} {80 24}
test listbox-5.5 {ListboxComputeGeometry procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -font $fixed -width 10 -height 0 -highlightthickness 0
    .l insert 0 Short "Really much longer" Longer
    pack .l
    update
    list [winfo reqwidth .l] [winfo reqheight .l]
} {76 52}
test listbox-5.6 {ListboxComputeGeometry procedure} {


    # If "0" in selected font had 0 width, caused divide-by-zero error.

    catch {destroy .l}
    pack [listbox .l -font {{open look glyph}}]
    update
} {}





catch {destroy .l}
listbox .l -height 2 -xscrollcommand "record x" -yscrollcommand "record y"
pack .l
update
test listbox-6.1 {InsertEls procedure} {
    .l delete 0 end
    .l insert end a b c d
    .l insert 5 x y z
    .l insert 2 A
    .l insert 0 q r s
    .l get 0 end
} {q r s a b A c d x y z}
test listbox-6.2 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l insert 2 A B
    .l index anchor
} {4}
test listbox-6.3 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l insert 3 A B
    .l index anchor
} {2}
test listbox-6.4 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l insert 2 A B
    .l index @0,0
} {5}
test listbox-6.5 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l insert 3 A B
    .l index @0,0
} {3}
test listbox-6.6 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 5
    .l insert 5 A B
    .l index active
} {7}
test listbox-6.7 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 5
    .l insert 6 A B
    .l index active
} {5}
test listbox-6.8 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b c
    .l index active
} {2}
test listbox-6.9 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0
    .l index active
} {0}
test listbox-6.10 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b "two words"  c d e f g h i j
    update
    set log {}
    .l insert 0 word
    update
    set log
} {{y 0 0.166667}}
test listbox-6.11 {InsertEls procedure} {
    .l delete 0 end
    .l insert 0 a b "two words"  c d e f g h i j
    update
    set log {}
    .l insert 0 "much longer entry"
    update
    set log
} {{y 0 0.166667} {x 0 1}}
test listbox-6.12 {InsertEls procedure} {fonts failsOnQuarz} {


    catch {destroy .l2}

    listbox .l2 -width 0 -height 0
    pack .l2 -side top
    .l2 insert 0 a b "two words"  c d
    set x {}
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
    .l2 insert 0 "much longer entry"
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]


} {80 93 122 110}
test listbox-6.13 {InsertEls procedure, check -listvar update} {
    catch {destroy .l2}

    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 insert 0 1 2 3 4
    set x


} [list 1 2 3 4 a b c d]
test listbox-6.14 {InsertEls procedure, check selection update} {
    catch {destroy .l2}

    listbox .l2
    .l2 insert 0 0 1 2 3 4
    .l2 selection set 2 4
    .l2 insert 0 a
    .l2 curselection


} [list 3 4 5]
test listbox-6.15 {InsertEls procedure, lost namespaced listvar} {
    destroy .l2
    namespace eval test { variable foo {a b} }
    listbox .l2 -listvar ::test::foo
    namespace delete test
    .l2 insert end c d
    .l2 delete end
    .l2 insert end e f
    catch {set ::test::foo} result
    list [.l2 get 0 end] [.l2 cget -listvar] $result


} [list [list a b c e f] ::test::foo \
	{can't read "::test::foo": no such variable}]


test listbox-7.1 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection set 1 6
    .l delete 4 3
    list [.l size] [selection get]
} {10 {b
c
d
e
f
g}}
test listbox-7.2 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection set 3 6
    .l delete 4 4
    list [.l size] [.l get 4] [.l curselection]
} {9 f {3 4 5}}
test listbox-7.3 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l delete 0 3
    list [.l size] [.l get 0] [.l get 1]
} {6 e f}
test listbox-7.4 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l delete 8 1000
    list [.l size] [.l get 7]
} {8 h}
test listbox-7.5 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l delete 0 1
    .l index anchor
} {0}
test listbox-7.6 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 2
    .l delete 2
    .l index anchor
} {2}
test listbox-7.7 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 4
    .l delete 2 5
    .l index anchor
} {2}
test listbox-7.8 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l selection anchor 3
    .l delete 4 5
    .l index anchor
} {3}
test listbox-7.9 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 1 2
    .l index @0,0
} {1}
test listbox-7.10 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 3 4
    .l index @0,0
} {3}
test listbox-7.11 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 4 6
    .l index @0,0
} {3}
test listbox-7.12 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    .l delete 3 end
    .l index @0,0
} {1}
test listbox-7.13 {DeleteEls procedure, updating view with partial last line} {
    mkPartial
    .partial.l yview 8
    update
    .partial.l delete 10 13
    .partial.l index @0,0
} {7}
test listbox-7.14 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 3 4
    .l index active
} {4}
test listbox-7.15 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 5 7
    .l index active
} {5}
test listbox-7.16 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 5 end
    .l index active
} {4}
test listbox-7.17 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j
    .l activate 6
    .l delete 0 end
    .l index active
} {0}
test listbox-7.18 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c "two words" d e f g h i j
    update
    set log {}
    .l delete 4 6
    update
    set log
} {{y 0 0.25}}
test listbox-7.19 {DeleteEls procedure} {
    .l delete 0 end
    .l insert 0 a b c "two words" d e f g h i j
    update
    set log {}
    .l delete 3
    update
    set log
} {{y 0 0.2} {x 0 1}}
test listbox-7.20 {DeleteEls procedure} {fonts failsOnQuarz} {


    catch {destroy .l2}

    listbox .l2 -width 0 -height 0
    pack .l2 -side top
    .l2 insert 0 a b "two words" c d e f g
    set x {}
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
    .l2 delete 2 4
    lappend x [winfo reqwidth .l2] [winfo reqheight .l2]
} {80 144 17 93}
catch {destroy .l2}
test listbox-7.21 {DeleteEls procedure, check -listvar update} {
    catch {destroy .l2}

    set x [list a b c d]
    listbox .l2 -listvar x
    .l2 delete 0 1
    set x
} [list c d]


test listbox-8.1 {ListboxEventProc procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -setgrid 1
    pack .l
    update
    set x [getsize .]
    destroy .l
    list $x [getsize .] [winfo exists .l] [info command .l]


} {20x10 150x178 0 {}}
resetGridInfo
test listbox-8.2 {ListboxEventProc procedure} {fonts failsOnQuarz} {


    catch {destroy .l}

    listbox .l -height 5 -width 10
    .l insert 0 a b c "A string that is very very long" d e f g h i j k
    pack .l
    update
    place .l -width 50 -height 80
    update
    list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]


} {{0 0.222222} {0 0.333333}}
test listbox-8.3 {ListboxEventProc procedure} {
    deleteWindows

    listbox .l1 -bg #543210
    rename .l1 .l2
    set x {}
    lappend x [winfo children .]
    lappend x [.l2 cget -bg]
    destroy .l1
    lappend x [info command .l*] [winfo children .]


} {.l1 #543210 {} {}}


test listbox-9.1 {ListboxCmdDeletedProc procedure} {
    deleteWindows

    listbox .l1
    rename .l1 {}
    list [info command .l*] [winfo children .]


} {{} {}}
test listbox-9.2 {ListboxCmdDeletedProc procedure, disabling -setgrid} {fonts failsOnQuarz} {


    catch {destroy .top}

    toplevel .top
    wm geom .top +0+0
    listbox .top.l -setgrid 1 -width 20 -height 10
    pack .top.l
    update
    set x [wm geometry .top]
    rename .top.l {}
    update
    lappend x [wm geometry .top]

    destroy .top
    set x
} {20x10+0+0 150x178+0+0}


catch {destroy .l}



listbox .l
pack .l
.l delete 0 end
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
test listbox-10.1 {GetListboxIndex procedure} {
    .l activate 3

    list [.l activate 3; .l index active] [.l activate 6; .l index active]


} {3 6}
test listbox-10.2 {GetListboxIndex procedure} {




    .l selection anchor 2

    .l index anchor
} 2


test listbox-10.3 {GetListboxIndex procedure} {




    .l insert end A B C D E
    .l selection anchor end

    .l delete 12 end
    list [.l index anchor] [.l index end]


} {12 12}
test listbox-10.4 {GetListboxIndex procedure} {





    list [catch {.l index a} msg] $msg


} {1 {bad listbox index "a": must be active, anchor, end, @x,y, or a number}}
test listbox-10.5 {GetListboxIndex procedure} {





    .l index end
} {12}


test listbox-10.6 {GetListboxIndex procedure} {





    .l get end


} {el11}
test listbox-10.7 {GetListboxIndex procedure} {
    .l delete 0 end
    .l index end
} 0
.l delete 0 end
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11

update
test listbox-10.8 {GetListboxIndex procedure} {
    list [catch {.l index @} msg] $msg
} {1 {bad listbox index "@": must be active, anchor, end, @x,y, or a number}}
test listbox-10.9 {GetListboxIndex procedure} {
    list [catch {.l index @foo} msg] $msg
} {1 {bad listbox index "@foo": must be active, anchor, end, @x,y, or a number}}
test listbox-10.10 {GetListboxIndex procedure} {
    list [catch {.l index @1x3} msg] $msg
} {1 {bad listbox index "@1x3": must be active, anchor, end, @x,y, or a number}}
test listbox-10.11 {GetListboxIndex procedure} {
    list [catch {.l index @1,} msg] $msg
} {1 {bad listbox index "@1,": must be active, anchor, end, @x,y, or a number}}
test listbox-10.12 {GetListboxIndex procedure} {
    list [catch {.l index @1,foo} msg] $msg
} {1 {bad listbox index "@1,foo": must be active, anchor, end, @x,y, or a number}}
test listbox-10.13 {GetListboxIndex procedure} {
    list [catch {.l index @1,2x} msg] $msg
} {1 {bad listbox index "@1,2x": must be active, anchor, end, @x,y, or a number}}
test listbox-10.14 {GetListboxIndex procedure} {fonts} {
    list [.l index @5,57] [.l index @5,58]
} {3 3}
test listbox-10.15 {GetListboxIndex procedure} {


    list [catch {.l index 1xy} msg] $msg


} {1 {bad listbox index "1xy": must be active, anchor, end, @x,y, or a number}}
test listbox-10.16 {GetListboxIndex procedure} {





    .l index 3
} {3}


test listbox-10.17 {GetListboxIndex procedure} {





    .l index 20
} {20}


test listbox-10.18 {GetListboxIndex procedure} {
    .l get 20
} {}
test listbox-10.19 {GetListboxIndex procedure} {


    .l index -2
} -2


test listbox-10.20 {GetListboxIndex procedure} {




    .l delete 0 end
    .l index 1
} 1

test listbox-11.1 {ChangeListboxView procedure, boundary conditions for index} {
    catch {destroy .l}



























































































    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview -1
    update
    lappend x [.l index @0,0]


} {3 0}
test listbox-11.2 {ChangeListboxView procedure, boundary conditions for index} {
    catch {destroy .l}

    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview 20
    update
    lappend x [.l index @0,0]


} {3 5}
test listbox-11.3 {ChangeListboxView procedure} {
    catch {destroy .l}

    listbox .l -height 5 -yscrollcommand "record y"
    pack .l
    .l insert 0 a b c d e f g h i j
    update
    set log {}
    .l yview 2
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log


}  {{0.2 0.7} {{y 0.2 0.7}}}
test listbox-11.4 {ChangeListboxView procedure} {
    catch {destroy .l}

    listbox .l -height 5 -yscrollcommand "record y"
    pack .l
    .l insert 0 a b c d e f g h i j
    update
    set log {}
    .l yview 8
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log


}  {{0.5 1} {{y 0.5 1}}}
test listbox-11.5 {ChangeListboxView procedure} {
    catch {destroy .l}

    listbox .l -height 5 -yscrollcommand "record y"
    pack .l

    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set log {}
    .l yview 3
    update
    list [format {%.6g %.6g} {*}[.l yview]] $log


}  {{0.3 0.8} {}}
test listbox-11.6 {ChangeListboxView procedure, partial last line} {
    mkPartial
    .partial.l yview 13
    .partial.l index @0,0



} {11}


catch {destroy .l}
listbox .l -font $fixed -xscrollcommand "record x" -width 10
.l insert 0 0123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789
pack .l
update
test listbox-12.1 {ChangeListboxOffset procedure} {fonts} {


    set log {}
    .l xview 99
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} {{0.9 1} {{x 0.9 1}}}
test listbox-12.2 {ChangeListboxOffset procedure} {fonts} {


    set log {}

    .l xview moveto -.25
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} {{0 0.1} {{x 0 0.1}}}
test listbox-12.3 {ChangeListboxOffset procedure} {fonts} {


    .l xview 10
    update
    set log {}
    .l xview 10
    update
    list [format {%.6g %.6g} {*}[.l xview]] $log
} {{0.1 0.2} {}}



catch {destroy .l}
listbox .l -font $fixed -width 10 -height 5
pack .l
.l insert 0 a bb c d e f g h i j k l m n o p q r s
.l insert 0 0123456789a123456789b123456789c123456789d123456789
update
set width [expr [lindex [.l bbox 2] 2] - [lindex [.l bbox 1] 2]]
set height [expr [lindex [.l bbox 2] 1] - [lindex [.l bbox 1] 1]]
test listbox-13.1 {ListboxScanTo procedure} {fonts} {


    .l yview 0
    .l xview 0
    .l scan mark 10 20
    .l scan dragto [expr 10-$width] [expr 20-$height]
    update
    list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} {{0.2 0.4} {0.5 0.75}}
test listbox-13.2 {ListboxScanTo procedure} {fonts} {


    .l yview 5
    .l xview 10
    .l scan mark 10 20
    .l scan dragto 20 40
    update
    set x [list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]]
    .l scan dragto [expr 20-$width] [expr 40-$height]
    update
    lappend x [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} {{0 0.2} {0 0.25} {0.2 0.4} {0.5 0.75}}
test listbox-13.3 {ListboxScanTo procedure} {fonts} {


    .l yview moveto 1.0
    .l xview moveto 1.0
    .l scan mark 10 20
    .l scan dragto 5 10
    update
    set x [list [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]]
    .l scan dragto [expr 5+$width] [expr 10+$height]
    update
    lappend x [format {%.6g %.6g} {*}[.l xview]] [format {%.6g %.6g} {*}[.l yview]]
} {{0.8 1} {0.75 1} {0.64 0.84} {0.25 0.5}}


test listbox-14.1 {NearestListboxElement procedure, partial last line} {
    mkPartial
    .partial.l nearest [winfo height .partial.l]
} {4}

catch {destroy .l}
listbox .l -font $fixed -width 20 -height 10
.l insert 0 a b c d e f g h i j k l m n o p q r s t
.l yview 4
pack .l
update
test listbox-14.2 {NearestListboxElement procedure} {fonts} {


    .l index @50,0
} {4}
test listbox-14.3 {NearestListboxElement procedure} {fonts failsOnQuarz} {


    list [.l index @50,35] [.l index @50,36]
} {5 6}
test listbox-14.4 {NearestListboxElement procedure} {fonts} {


    .l index @50,200

} {13}






test listbox-15.1 {ListboxSelect procedure} {
    .l delete 0 end
    .l insert 0 a b c d e f g h i j k l m n o p
    .l select set 2 4
    .l select set 7 12
    .l select clear 4 7
    .l curselection
} {2 3 8 9 10 11 12}
test listbox-15.2 {ListboxSelect procedure} {


    .l delete 0 end
    .l insert 0 a b c d e f g h i j k l m n o p
    catch {destroy .e}
    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 7
    .l selection clear 2 4
    set x [selection own]
    .l selection set 3
    list $x [selection own] [selection get]


} {.e .l d}
test listbox-15.3 {ListboxSelect procedure} {
    .l delete 0 end
    .l selection clear 0 end
    .l select set 0 end
    .l curselection
} {}
test listbox-15.4 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -2 -1
    .l curselection
} {}
test listbox-15.5 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 3
    .l curselection
} {0 1 2 3}
test listbox-15.6 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 2 4
    .l curselection
} {2 3 4}
test listbox-15.7 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 4 end
    .l curselection
} {4 5}
test listbox-15.8 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 4 30
    .l curselection
} {4 5}
test listbox-15.9 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set end 30
    .l curselection
} {5}
test listbox-15.10 {ListboxSelect procedure, boundary conditions for indices} {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 20 25
    .l curselection

} {}

test listbox-16.1 {ListboxFetchSelection procedure} {
    .l delete 0 end
    .l insert 0 a b c "two words" e f g h i \\ k l m n o p
    .l selection set 2 4
    .l selection set 9
    .l selection set 11 12
    selection get
} "c\ntwo words\ne\n\\\nl\nm"
test listbox-16.2 {ListboxFetchSelection procedure} {
    .l delete 0 end
    .l insert 0 a b c "two words" e f g h i \\ k l m n o p
    .l selection set 3
    selection get
} "two words"
test listbox-16.3 {ListboxFetchSelection procedure, retrieve in several parts} {
    set long "This is quite a long string\n"
    append long $long $long $long $long
    append long $long $long $long $long
    append long $long $long
    .l delete 0 end
    .l insert 0 1$long 2$long 3$long 4$long 5$long
    .l selection set 0 end
    set sel [selection get]
    string compare 1$long\n2$long\n3$long\n4$long\n5$long $sel
} {0}
catch {unset long sel}



test listbox-17.1 {ListboxLostSelection procedure} {


    .l delete 0 end
    .l insert 0 a b c d e
    .l select set 0 end
    catch {destroy .e}
    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 5
    .l curselection
} {}


test listbox-17.2 {ListboxLostSelection procedure} {


    .l delete 0 end
    .l insert 0 a b c d e
    .l select set 0 end
    .l configure -exportselection 0
    catch {destroy .e}
    entry .e
    .e insert 0 "This is some text"
    .e select from 0
    .e select to 5
    .l curselection


} {0 1 2 3 4}



catch {destroy .l}
listbox .l -font $fixed -width 10 -height 5
pack .l
update
test listbox-18.1 {ListboxUpdateVScrollbar procedure} {
    .l configure -yscrollcommand "record y"
    set log {}
    .l insert 0 a b c
    update
    .l insert end d e f g h
    update
    .l delete 0 end
    update
    set log
} {{y 0 1} {y 0 0.625} {y 0 1}}
test listbox-18.2 {ListboxUpdateVScrollbar procedure, partial last line} {
    mkPartial
    .partial.l configure -yscrollcommand "record y"
    set log {}
    .partial.l yview 3
    update
    set log
} {{y 0.2 0.466667}}
test listbox-18.3 {ListboxUpdateVScrollbar procedure} {
    proc bgerror args {
	global x errorInfo
	set x [list $args $errorInfo]
    }
    .l configure -yscrollcommand gorp
    .l insert 0 foo
    update
    set x


} {{{invalid command name "gorp"}} {invalid command name "gorp"
    while executing
"gorp 0.0 1.0"
    (vertical scrolling command executed by listbox)}}
if {[info exists bgerror]} {
    rename bgerror {}
}


catch {destroy .l}
listbox .l -font $fixed -width 10 -height 5
pack .l
update
test listbox-19.1 {ListboxUpdateVScrollbar procedure} {fonts} {


    .l configure -xscrollcommand "record x"
    set log {}
    .l insert 0 abc
    update
    .l insert 0 "This is a much longer string..."
    update
    .l delete 0 end
    update
    set log
} {{x 0 1} {x 0 0.322581} {x 0 1}}
test listbox-19.2 {ListboxUpdateVScrollbar procedure} {
    proc bgerror args {
	global x errorInfo
	set x [list $args $errorInfo]
    }
    .l configure -xscrollcommand bogus
    .l insert 0 foo
    update
    set x
} {{{invalid command name "bogus"}} {invalid command name "bogus"
    while executing
"bogus 0.0 1.0"
    (horizontal scrolling command executed by listbox)}}

set l [interp hidden]
deleteWindows

test listbox-20.1 {listbox vs hidden commands} {

    catch {destroy .l}

    listbox .l
    interp hide {} .l
    destroy .l
    list [winfo children .] [interp hidden]
} [list {} $l]




# tests for ListboxListVarProc
test listbox-21.1 {ListboxListVarProc} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x
    set x [list a b c d]
    .l get 0 end


} [list a b c d]
test listbox-21.2 {ListboxListVarProc} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    unset x
    set x


} [list a b c d]
test listbox-21.3 {ListboxListVarProc} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l configure -listvar {}
    unset x
    info exists x
} 0


test listbox-21.4 {ListboxListVarProc} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    lappend x e f g
    .l size
} 7


test listbox-21.5 {ListboxListVarProc, test selection after listvar mod} {
    catch {destroy .l}

    set x [list a b c d e f g]
    listbox .l -listvar x
    .l selection set end
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l curselection
} {}


test listbox-21.6 {ListboxListVarProc, test selection after listvar mod} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 3
    lappend x e f g
    .l curselection
} 3


test listbox-21.7 {ListboxListVarProc, test selection after listvar mod} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 0
    set x [linsert $x 0 1 2 3 4]
    .l curselection
} 0


test listbox-21.8 {ListboxListVarProc, test selection after listvar mod} {
    catch {destroy .l}

    set x [list a b c d]
    listbox .l -listvar x
    .l selection set 2
    set x [list a b c]
    .l curselection
} 2


test listbox-21.9 {ListboxListVarProc, test hscrollbar after listvar mod} {
    catch {destroy .l}
    catch {unset x}
    set log {}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    pack .l
    update

    lappend x "0000000000"
    update
    lappend x "00000000000000000000"
    update
    set log


} [list {x 0 1} {x 0 1} {x 0 0.5}]
test listbox-21.10 {ListboxListVarProc, test hscrollbar after listvar mod} {
    catch {destroy .l}

    catch {unset x}
    set log {}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    pack .l
    update

    lappend x "0000000000"
    update
    lappend x "00000000000000000000"
    update
    set x [list "0000000000"]
    update
    set log


} [list {x 0 1} {x 0 1} {x 0 0.5} {x 0 1}]
test listbox-21.11 {ListboxListVarProc, bad list} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x
    set x [list a b c d]
    catch {set x "this is a \" bad list"} result
    set result


} {can't set "x": invalid listvar value}
test listbox-21.12 {ListboxListVarProc, cleanup item attributes} {
    catch {destroy .l}
    set x [list a b c d e f g]
    listbox .l -listvar x
    .l itemconfigure end -fg red
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l itemcget end -fg
} {}
test listbox-21.12a {ListboxListVarProc, cleanup item attributes} {
    catch {destroy .l}
    set x [list a b c d e f g]
    listbox .l -listvar x
    .l itemconfigure end -fg red
    set x [list a b c d]
    set x [list 0 1 2 3 4 5 6]
    .l itemcget end -fg





} {}









test listbox-21.13 {listbox item configurations and listvar based deletions} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x
    .l insert end a b c
    .l itemconfigure 1 -fg red
    set x [list b c]
    .l itemcget 1 -fg


} red
test listbox-21.14 {listbox item configurations and listvar based inserts} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x
    .l insert end a b c
    .l itemconfigure 0 -fg red
    set x [list 1 2 3 4 a b c]
    .l itemcget 0 -fg


} red
test listbox-21.15 {ListboxListVarProc, update vertical scrollbar} {
    catch {destroy .l}

    catch {unset x}


    set log {}
    listbox .l -listvar x -yscrollcommand "record y" -font fixed -height 3
    pack .l


    update
    lappend x a b c d e f
    update
    set log



} [list {y 0 1} {y 0 0.5}]
test listbox-21.16 {ListboxListVarProc, update vertical scrollbar} {
    catch {destroy .l}

    catch {unset x}
    listbox .l -listvar x -height 3
    pack .l
    update
    set x [list 0 1 2 3 4 5]
    .l yview scroll 3 units
    update
    set result {}
    lappend result [format {%.6g %.6g} {*}[.l yview]]
    set x [lreplace $x 3 3]
    set x [lreplace $x 3 3]
    set x [lreplace $x 3 3]
    update
    lappend result [format {%.6g %.6g} {*}[.l yview]]
    set result


} [list {0.5 1} {0 1}]


# UpdateHScrollbar
test listbox-22.1 {UpdateHScrollbar} {
    catch {destroy .l}
    set log {}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x"
    pack .l
    update


    .l insert end "0000000000"
    update
    .l insert end "00000000000000000000"
    update
    set log



} [list {x 0 1} {x 0 1} {x 0 0.5}]


# ConfigureListboxItem
test listbox-23.1 {ConfigureListboxItem} {
    catch {destroy .l}

    listbox .l
    catch {.l itemconfigure 0} result
    set result


} {item number "0" out of range}
test listbox-23.2 {ConfigureListboxItem} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    .l itemconfigure 0


} [list {-background background Background {} {}} \
	{-bg -background} \
	{-fg -foreground} \
	{-foreground foreground Foreground {} {}} \
	{-selectbackground selectBackground Foreground {} {}} \
	{-selectforeground selectForeground Background {} {}}]
test listbox-23.3 {ConfigureListboxItem, itemco shortcut} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    .l itemco 0 -background


} {-background background Background {} {}}
test listbox-23.4 {ConfigureListboxItem, wrong num args} {
    catch {destroy .l}

    listbox .l
    .l insert end a
    catch {.l itemco} result
    set result


} {wrong # args: should be ".l itemconfigure index ?option? ?value? ?option value ...?"}
test listbox-23.5 {ConfigureListboxItem, multiple calls} {
    catch {destroy .l}

    listbox .l
    set i 0
    foreach color {red orange yellow green blue white violet} {
	.l insert end $color
	.l itemconfigure $i -bg $color
	incr i
    }
    pack .l
    update
    list [.l itemcget 0 -bg] [.l itemcget 1 -bg] [.l itemcget 2 -bg] \
	    [.l itemcget 3 -bg] [.l itemcget 4 -bg] [.l itemcget 5 -bg] \
	    [.l itemcget 6 -bg]


} {red orange yellow green blue white violet}


catch {destroy .l}
listbox .l
.l insert end a b c d
set i 6
foreach test {
    {-background #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}








    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}

    {-fg #110022 #110022 bogus {unknown color name "bogus"}}



    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}


    {-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
    {-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}
} {
    set name [lindex $test 0]
    test listbox-23.$i {configuration options} {
	.l itemconfigure 0 $name [lindex $test 1]
	list [lindex [.l itemconfigure 0 $name] 4] [.l itemcget 0 $name]








    } [list [lindex $test 2] [lindex $test 2]]
    incr i


    if {[lindex $test 3] != ""} {


	test listbox-23.$i {configuration options} {



	    list [catch {.l configure $name [lindex $test 3]} msg] $msg

	} [list 1 [lindex $test 4]]
    }
    .l configure $name [lindex [.l configure $name] 3]

    incr i
}

# ListboxWidgetObjCmd, itemcget
test listbox-24.1 {itemcget} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    .l itemcget 0 -fg
} {}


test listbox-24.2 {itemcget} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    .l itemconfigure 0 -fg red
    .l itemcget 0 -fg


} red
test listbox-24.3 {itemcget} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    catch {.l itemcget 0} result
    set result


} {wrong # args: should be ".l itemcget index option"}
test listbox-24.4 {itemcget, itemcg shortcut} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c d
    catch {.l itemcg 0} result
    set result


} {wrong # args: should be ".l itemcget index option"}


# General item configuration issues
test listbox-25.1 {listbox item configurations and widget based deletions} {
    catch {destroy .l}

    listbox .l
    .l insert end a
    .l itemconfigure 0 -fg red
    .l delete 0 end
    .l insert end a
    .l itemcget 0 -fg
} {}


test listbox-25.2 {listbox item configurations and widget based inserts} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l itemconfigure 0 -fg red
    .l insert 0 1 2 3 4
    list [.l itemcget 0 -fg] [.l itemcget 4 -fg]


} [list {} red]


# state issues
test listbox-26.1 {listbox disabled state disallows inserts} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l configure -state disabled
    .l insert end d e f
    .l get 0 end


} [list a b c]
test listbox-26.2 {listbox disabled state disallows deletions} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l configure -state disabled
    .l delete 0 end
    .l get 0 end


} [list a b c]
test listbox-26.3 {listbox disabled state disallows selection modification} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l selection set 0
    .l selection set 2
    .l configure -state disabled
    .l selection clear 0 end
    .l selection set 1
    .l curselection


} [list 0 2]
test listbox-26.4 {listbox disabled state disallows anchor modification} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l selection anchor 0
    .l configure -state disabled
    .l selection anchor 2
    .l index anchor
} 0


test listbox-26.5 {listbox disabled state disallows active modification} {
    catch {destroy .l}

    listbox .l
    .l insert end a b c
    .l activate 0
    .l configure -state disabled
    .l activate 2
    .l index active



} 0

test listbox-27.1 {widget deletion while active} {
    destroy .l

    pack [listbox .l]
    update
    .l configure -cursor xterm -xscrollcommand { destroy .l }
    update idle
    winfo exists .l



} 0

test listbox-28.1 {listbox -activestyle} {
    destroy .l

    listbox .l -activ non
    .l cget -activestyle


} none
test listbox-28.2-nonwin {listbox -activestyle} {nonwin} {


    destroy .l

    listbox .l
    .l cget -activestyle


} dotbox
test listbox-28.2-win {listbox -activestyle} {win} {


    destroy .l

    listbox .l
    .l cget -activestyle


} underline
test listbox-28.3 {listbox -activestyle} {
    destroy .l

    listbox .l -activestyle und
    .l cget -activestyle


} underline


test listbox-29.1 {listbox selection behavior, -state disabled} {
    destroy .l

    listbox .l
    .l insert end 1 2 3
    .l selection set 2
    set out [.l selection includes 2]
    .l configure -state disabled
    # still return 1 when disabled, because 'selection get' will work,
    # but selection cannot be changed (new behavior since 8.4)
    .l selection set 3
    lappend out [.l selection includes 2] [.l curselection]


} {1 1 2}

test listbox-30.1 {Bug 3607326} -setup {
    destroy .l
    unset -nocomplain a
} -body {
    array set a {}
    listbox .l -listvariable a
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
    unset -nocomplain res
} -body {
    pack [listbox .l -state normal]
    update
    bind .l <<ListboxSelect>> {lappend res [%W curselection]}
    .l insert end a b c
    focus -force .l
    event generate .l <Button-1> -x 5 -y 5  ; # <<ListboxSelect>> fires
    .l configure -state disabled
    focus -force .l
    event generate .l <Control-Home> ; # <<ListboxSelect>> does NOT fire
    .l configure -state normal
    focus -force .l
    event generate .l <Control-End>  ; # <<ListboxSelect>> fires
    .l selection clear 0 end         ; # <<ListboxSelect>> does NOT fire







|







2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
    unset -nocomplain res
} -body {
    pack [listbox .l -state normal]
    update
    bind .l <<ListboxSelect>> {lappend res [%W curselection]}
    .l insert end a b c
    focus -force .l
    event generate .l <1> -x 5 -y 5  ; # <<ListboxSelect>> fires
    .l configure -state disabled
    focus -force .l
    event generate .l <Control-Home> ; # <<ListboxSelect>> does NOT fire
    .l configure -state normal
    focus -force .l
    event generate .l <Control-End>  ; # <<ListboxSelect>> fires
    .l selection clear 0 end         ; # <<ListboxSelect>> does NOT fire
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
    destroy .l
} -body {
    pack [listbox .l -exportselection true]
    update
    bind .l <<ListboxSelect>> {lappend res [list [selection own] [%W curselection]]}
    .l insert end a b c
    focus -force .l
    event generate .l <Button-1> -x 5 -y 5  ; # <<ListboxSelect>> fires
    selection clear                  ; # <<ListboxSelect>> fires again
    update
    set res
} -cleanup {
    destroy .l
} -result {{.l 0} {{} {}}}

test listbox-32.1 {Bug [5d991b822e]} {
    # Want this not to segfault, or write to variable with empty name
    set var INIT
    listbox .b -listvariable var
    trace add variable var unset {apply {args {
        .b configure -listvariable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
    info exists {}
} 0
test listbox-32.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    listbox .b -listvariable var
    trace add variable var unset {apply {args {
        .b configure -listvariable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}

resetGridInfo
deleteWindows
option clear

# cleanup
cleanupTests
return







|

<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2199
2200
2201
2202
2203
2204
2205
2206
2207

2208
2209
2210
2211
2212



























2213
2214
2215
2216
2217
2218
2219
    destroy .l
} -body {
    pack [listbox .l -exportselection true]
    update
    bind .l <<ListboxSelect>> {lappend res [list [selection own] [%W curselection]]}
    .l insert end a b c
    focus -force .l
    event generate .l <1> -x 5 -y 5  ; # <<ListboxSelect>> fires
    selection clear                  ; # <<ListboxSelect>> fires again

    set res
} -cleanup {
    destroy .l
} -result {{.l 0} {{} {}}}




























resetGridInfo
deleteWindows
option clear

# cleanup
cleanupTests
return

Changes to tests/main.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24


25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71


72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# This file contains tests for the tkMain.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test main-1.1 {StdinProc} -constraints stdio -setup {
    set script [makeFile {close stdin; exit} script]


} -body {
    exec [interpreter] <$script
} -cleanup {
    removeFile script
} -returnCodes ok

test main-2.1 {Tk_MainEx: -encoding option} -constraints stdio -setup {


	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts $f {puts [string equal \u20AC €]; exit}

	close $f
	catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]}
} -body {
	read $f
} -cleanup {
	close $f
	removeFile script
} -result "script {} 0\n1\n"

test main-2.2 {Tk_MainEx: -encoding option} -constraints stdio -setup {


	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts $f {puts [string equal \u20AC €]; exit}

	close $f
	catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
} -body {
	read $f
} -cleanup {
	close $f
	removeFile script
} -result "script {} 0\n0\n"

    # Procedure to simulate interactive typing of commands, line by line,
	# for test 2.3
    proc type {chan script} {
        foreach line [split $script \n] {
            if {[catch {
                puts $chan $line
                flush $chan
            }]} {
                return
            }
            # Grrr... Behavior depends on this value.
            after 1000
        }
    }

test main-2.3 {Tk_MainEx: -encoding option} -constraints stdio -setup {


	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts $f {puts [string equal \u20AC €]}

	close $f
	catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]}
} -body {
	type $f {
		puts $argv
		exit
	}
	gets $f
} -cleanup {
	close $f
	removeFile script
} -returnCodes ok -result {-enc utf-8 script}

test main-3.1 {Tk_ParseArgv: -help option} -constraints unix -body {
    # Run only on unix as Win32 pops up native dialog
    exec [interpreter] -help
} -returnCodes error -match glob -result {% application-specific initialization failed: Command-specific options:*}

test main-3.2 {Tk_ParseArgv: -help option} -setup {
    set maininterp [interp create]
} -body {
    $maininterp eval { set argc 1 ; set argv -help }
    load {} Tk $maininterp
} -cleanup {






|




<




|
>
>

|


|

|
>
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|

|
>
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|

|
<













|
>
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|




|







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# This file contains tests for the tkMain.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test main-1.1 {StdinProc} -constraints stdio -setup {
    set script [makeFile {
	close stdin; exit
    } script]
} -body {
    list [catch {exec [interpreter] <$script} msg] $msg
} -cleanup {
    removeFile script
} -result {0 {}}

test main-2.1 {Tk_MainEx: -encoding option} -constraints {
        stdio
    } -setup {
        set script [makeFile {} script]
        file delete $script
        set f [open $script w]
        fconfigure $f -encoding utf-8
        puts $f {puts [list $argv0 $argv $tcl_interactive]}
        puts -nonewline $f {puts [string equal \u20ac }
        puts $f "\u20ac]; exit"
        close $f
        catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]}
    } -body {
        read $f
    } -cleanup {
        close $f
        removeFile script
    } -result [list script {} 0]\n1\n

test main-2.2 {Tk_MainEx: -encoding option} -constraints {
        stdio
    } -setup {
        set script [makeFile {} script]
        file delete $script
        set f [open $script w]
        fconfigure $f -encoding utf-8
        puts $f {puts [list $argv0 $argv $tcl_interactive]}
        puts -nonewline $f {puts [string equal \u20ac }
        puts $f "\u20ac]; exit"
        close $f
        catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
    } -body {
        read $f
    } -cleanup {
        close $f
        removeFile script
    } -result [list script {} 0]\n0\n

    # Procedure to simulate interactive typing of commands, line by line

    proc type {chan script} {
        foreach line [split $script \n] {
            if {[catch {
                puts $chan $line
                flush $chan
            }]} {
                return
            }
            # Grrr... Behavior depends on this value.
            after 1000
        }
    }

test main-2.3 {Tk_MainEx: -encoding option} -constraints {
        stdio
    } -setup {
        set script [makeFile {} script]
        file delete $script
        set f [open $script w]
        fconfigure $f -encoding utf-8
        puts $f {puts [list $argv0 $argv $tcl_interactive]}
        puts -nonewline $f {puts [string equal \u20ac }
        puts $f "\u20ac]"
        close $f
        catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]}
    } -body {
        type $f {
            puts $argv
	    exit
        }
        list [catch {gets $f} line] $line
    } -cleanup {
        close $f
        removeFile script
    } -result {0 {-enc utf-8 script}}

test main-3.1 {Tk_ParseArgv: -help option} -constraints unix -body {
    # Run only on unix as Win32 pops up native dialog
    exec [interpreter] -help
} -returnCodes error -match glob -result {*Application initialization failed: Command-specific options:*}

test main-3.2 {Tk_ParseArgv: -help option} -setup {
    set maininterp [interp create]
} -body {
    $maininterp eval { set argc 1 ; set argv -help }
    load {} Tk $maininterp
} -cleanup {

Changes to tests/menu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243


244
245


246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471

472


473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515

516


517
518
519
520
521
522
523

524
525
526
527
528
529
530


531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

557


558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612


613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650

651
652
653
654

655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690



691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780


781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833


834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

891
892
893
894

895
896
897


898
899
900
901
902

903
904
905

906
907
908
909
910
911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945


946
947
948
949
950
951
952
953

954
955


956


957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

974
975

976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136

1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990




1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015

2016
2017
2018
2019
2020
2021
2022
2023
2024
2025


2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168

2169
2170
2171
2172
2173
2174
2175
2176
2177

2178
2179
2180
2181
2182
2183
2184
2185

2186
2187
2188
2189
2190
2191
2192
2193


2194
2195
2196
2197
2198
2199
2200
2201
2202


2203
2204
2205
2206
2207
2208
2209
2210
2211


2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237

2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282









2283




2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396

2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606



2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622


2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730

2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743


2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789





2790

2791


2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873

2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909



2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043

3044
3045
3046
3047
3048
3049
3050
3051
3052
3053

3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224

3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258



3259



3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319

3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337

3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527

3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539

3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564

3565
3566
3567
3568
3569
3570
3571







3572
3573


3574




3575
3576














3577
3578



3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737


3738
3739
3740





3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858


3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882

3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894


3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928

3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942

3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# find the earth.gif file for use in these tests (tests 2.*)
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
testConstraint hasEarthPhoto [file exists $earthPhotoFile]

test menu-1.1 {Tk_MenuCmd procedure} -body {
    menu
} -returnCodes error -result {wrong # args: should be "menu pathName ?-option value ...?"}
test menu-1.2 {Tk_MenuCmd procedure} -body {
    menu bogus
} -returnCodes error -result {bad window path name "bogus"}
test menu-1.3 {Tk_MenuCmd procedure} -body {
    destroy .m1
    menu .m1 foo
} -returnCodes error -result {unknown option "foo"}
test menu-1.4 {Tk_MenuCmd procedure} -body {
    destroy .m1
    menu .m1
} -cleanup {
    deleteWindows
} -result {.m1}
test menu-1.5 {Tk_MenuCmd - creating menubar} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label Test -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-1.6 {Tk_MenuCmd procedure menu ref no cascade} -setup {
    deleteWindows
} -body {
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    menu .m1
} -cleanup {
    deleteWindows
} -result {.m1}
test menu-1.7 {Tk_MenuCmd procedure one clone cascade} -setup {
    deleteWindows
} -body {

    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
} -cleanup {
    deleteWindows
} -result {.m2}
test menu-1.8 {Tk_MenuCmd procedure two clone cascades} -setup {
    deleteWindows
} -body {


    menu .m1
    .m1 add cascade -menu .m2
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    menu .m2
} -cleanup {
    deleteWindows
} -result {.m2}
test menu-1.9 {Tk_MenuCmd procedure two clone cascades different order} -setup {
    deleteWindows
} -body {


    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [menu .m2]
} -cleanup {
    deleteWindows
} -result {.m2}
test menu-1.10 {Tk_MenuCmd procedure two clone cascades menus last} -setup {
    deleteWindows
} -body {


    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    list [menu .m2]
} -cleanup {
    deleteWindows
} -result {.m2}
test menu-1.11 {Tk_MenuCmd procedure three clones cascades} -setup {
    deleteWindows
} -body {



    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    toplevel .t4 -menu .m1
    wm geometry .t4 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    list [menu .m2]
} -cleanup {
    deleteWindows
} -result {.m2}
test menu-1.12 {Tk_MenuCmd procedure} -setup {
    deleteWindows
} -body {
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [menu .m1]
} -cleanup {
    deleteWindows
} -result {.m1}
test menu-1.13 {Tk_MenuCmd procedure} -setup {
    deleteWindows
} -body {

    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [menu .m1]
} -cleanup {
    deleteWindows
} -result {.m1}
test menu-1.14 {Tk_MenuCmd procedure} -setup {
    deleteWindows
} -body {


    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    toplevel .t4 -menu .m1
    wm geometry .t4 +0+0
    list [menu .m1]
} -cleanup {
    deleteWindows
} -result {.m1}

# Used for 2.1 - 2.30 tests
destroy .m1
menu .m1
test menu-2.1 {configuration options -activebackground #012345} -body {
    .m1 configure -activebackground #012345
    .m1 cget -activebackground
} -result {#012345}
test menu-2.2 {configuration options -activebackground non-existent} -body {
    .m1 configure -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.3 {configuration options -activeborderwidth 1.3} -body {
    .m1 configure -activeborderwidth 1.3
    .m1 cget -activeborderwidth
} -result {1.3}
test menu-2.4 {configuration options -activeborderwidth badValue} -body {
    .m1 configure -activeborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}

test menu-2.5 {configuration options -activeforeground #ff0000} -body {
    .m1 configure -activeforeground #ff0000
    .m1 cget -activeforeground
} -result {#ff0000}
test menu-2.6 {configuration options -activeforeground non-existent} -body {
    .m1 configure -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.6a {configuration options -activerelief sunken} -body {
    .m1 configure -activerelief sunken
    .m1 cget -activerelief
} -result {sunken}
test menu-2.6b {configuration options -activerelief badValue} -body {
    .m1 configure -activerelief badValue
} -returnCodes error -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}

test menu-2.7 {configuration options -background #ff0000} -body {
    .m1 configure -background #ff0000
    .m1 cget -background
} -result {#ff0000}
test menu-2.8 {configuration options -background non-existent} -body {
    .m1 configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.9 {configuration options -bg #110022} -body {
    .m1 configure -bg #110022
    .m1 cget -bg
} -result {#110022}
test menu-2.10 {configuration options -bg bogus} -body {
    .m1 configure -bg bogus
} -returnCodes error -result {unknown color name "bogus"}

test menu-2.11 {configuration options -borderwidth 1.3} -body {
    .m1 configure -borderwidth 1.3
    .m1 cget -borderwidth
} -result {1.3}
test menu-2.12 {configuration options -borderwidth badValue} -body {
    .m1 configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}

test menu-2.13 {configuration options -cursor arrow} -body {
    .m1 configure -cursor arrow
    .m1 cget -cursor
} -result {arrow}
test menu-2.14 {configuration options -cursor badValue} -body {
    .m1 configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}

test menu-2.15 {configuration options -disabledforeground #00ff00} -body {
    .m1 configure -disabledforeground #00ff00
    .m1 cget -disabledforeground
} -result {#00ff00}
test menu-2.16 {configuration options -disabledforeground xyzzy} -body {
    .m1 configure -disabledforeground xyzzy
} -returnCodes error -result {unknown color name "xyzzy"}

test menu-2.17 {configuration options -fg #110022} -body {
    .m1 configure -fg #110022
    .m1 cget -fg
} -result {#110022}
test menu-2.18 {configuration options -fg bogus} -body {
    .m1 configure -fg bogus
} -returnCodes error -result {unknown color name "bogus"}

test menu-2.19 {configuration options -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*} -body {
    .m1 configure -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    .m1 cget -font
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}
test menu-2.20 {configuration options -foreground #110022} -body {

    .m1 configure -foreground #110022
    .m1 cget -foreground
} -result {#110022}
test menu-2.21 {configuration options -foreground bogus} -body {
    .m1 configure -foreground bogus


} -returnCodes error -result {unknown color name "bogus"}



test menu-2.22 {configuration options -postcommand {any old string}} -body {

    .m1 configure -postcommand {any old string}
    .m1 cget -postcommand
} -result {any old string}
test menu-2.23 {configuration options -relief groove} -body {
    .m1 configure -relief groove
    .m1 cget -relief
} -result {groove}
test menu-2.24 {configuration options -relief 1.5} -body {
    .m1 configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test menu-2.25 {configuration options -selectcolor #110022} -body {
    .m1 configure -selectcolor #110022
    .m1 cget -selectcolor
} -result {#110022}
test menu-2.26 {configuration options -selectcolor bogus} -body {
    .m1 configure -selectcolor bogus
} -returnCodes error -result {unknown color name "bogus"}

test menu-2.27 {configuration options -takefocus {any string}} -body {
    .m1 configure -takefocus {any string}
    .m1 cget -takefocus
} -result {any string}
test menu-2.28 {configuration options -tearoff 0} -body {
    .m1 configure -tearoff 0
    .m1 cget -tearoff
} -result 0
test menu-2.29 {configuration options -tearoff 1} -body {
    .m1 configure -tearoff 1
    .m1 cget -tearoff
} -result 1
test menu-2.30 {configuration options -tearoffcommand {any old string}} -body {
    .m1 configure -tearoffcommand {any old string}
    .m1 cget -tearoffcommand
} -result {any old string}

destroy .m1

# We need to test all of the options with all of the different types of
# menu entries. The following code sets up .m1 with 6 items. It then
# runs through the 2.31 - 2.228 tests below
# index 0 is tearoff, 1 command, 2 cascade, 3 separator, 4 checkbutton,
# 5 radiobutton
deleteWindows
menu .m1 -tearoff 1
.m1 add command -label "command"
menu .m2 -tearoff 1
.m2 add command -label "test"
.m1 add cascade -label "cascade" -menu .m2
.m1 add separator
.m1 add checkbutton -label "checkbutton" -variable check -onvalue on -offvalue off
.m1 add radiobutton -label "radiobutton" -variable radio

if {[testConstraint hasEarthPhoto]} {
    image create photo image1 -file $earthPhotoFile
}

test menu-2.31 {entry configuration options 0 -activebackground #012345 tearoff} -body {
    .m1 entryconfigure 0 -activebackground #012345
} -returnCodes error -result {unknown option "-activebackground"}

test menu-2.32 {entry configuration options 1 -activebackground #012345 command} -body {
    .m1 entryconfigure 1 -activebackground #012345
    lindex [.m1 entryconfigure 1 -activebackground] 4
} -result {#012345}

test menu-2.33 {entry configuration options 2 -activebackground #012345 cascade} -body {
    .m1 entryconfigure 2 -activebackground #012345
    lindex [.m1 entryconfigure 2 -activebackground] 4
} -result {#012345}

test menu-2.34 {entry configuration options 3 -activebackground #012345 separator} -body {
    .m1 entryconfigure 3 -activebackground #012345
} -returnCodes error -result {unknown option "-activebackground"}

test menu-2.35 {entry configuration options 4 -activebackground #012345 checkbutton} -body {
    .m1 entryconfigure 4 -activebackground #012345
    lindex [.m1 entryconfigure 4 -activebackground] 4
} -result {#012345}

test menu-2.36 {entry configuration options 5 -activebackground #012345 radiobutton} -body {
    .m1 entryconfigure 5 -activebackground #012345
    lindex [.m1 entryconfigure 5 -activebackground] 4
} -result {#012345}

test menu-2.37 {entry configuration options 0 -activebackground non-existent tearoff} -body {
    .m1 entryconfigure 0 -activebackground non-existent
} -returnCodes error -result {unknown option "-activebackground"}

test menu-2.38 {entry configuration options 1 -activebackground non-existent command} -body {
    .m1 entryconfigure 1 -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.39 {entry configuration options 2 -activebackground non-existent cascade} -body {
    .m1 entryconfigure 2 -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.40 {entry configuration options 3 -activebackground non-existent separator} -body {
    .m1 entryconfigure 3 -activebackground non-existent
} -returnCodes error -result {unknown option "-activebackground"}

test menu-2.41 {entry configuration options 4 -activebackground non-existent checkbutton} -body {
    .m1 entryconfigure 4 -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.42 {entry configuration options 5 -activebackground non-existent radiobutton} -body {
    .m1 entryconfigure 5 -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.43 {entry configuration options 0 -activeforeground #ff0000 tearoff} -body {
    .m1 entryconfigure 0 -activeforeground #ff0000
} -returnCodes error -result {unknown option "-activeforeground"}

test menu-2.44 {entry configuration options 1 -activeforeground #ff0000 command} -body {
    .m1 entryconfigure 1 -activeforeground #ff0000
    lindex [.m1 entryconfigure 1 -activeforeground] 4
} -result {#ff0000}

test menu-2.45 {entry configuration options 2 -activeforeground #ff0000 cascade} -body {
    .m1 entryconfigure 2 -activeforeground #ff0000
    lindex [.m1 entryconfigure 2 -activeforeground] 4
} -result {#ff0000}

test menu-2.46 {entry configuration options 3 -activeforeground #ff0000 separator} -body {
    .m1 entryconfigure 3 -activeforeground #ff0000
} -returnCodes error -result {unknown option "-activeforeground"}

test menu-2.47 {entry configuration options 4 -activeforeground #ff0000 checkbutton} -body {
    .m1 entryconfigure 4 -activeforeground #ff0000
    lindex [.m1 entryconfigure 4 -activeforeground] 4
} -result {#ff0000}

test menu-2.48 {entry configuration options 5 -activeforeground #ff0000 radiobutton} -body {
    .m1 entryconfigure 5 -activeforeground #ff0000
    lindex [.m1 entryconfigure 5 -activeforeground] 4
} -result {#ff0000}

test menu-2.49 {entry configuration options 0 -activeforeground non-existent tearoff} -body {
    .m1 entryconfigure 0 -activeforeground non-existent
} -returnCodes error -result {unknown option "-activeforeground"}

test menu-2.50 {entry configuration options 1 -activeforeground non-existent command} -body {
    .m1 entryconfigure 1 -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.51 {entry configuration options 2 -activeforeground non-existent cascade} -body {
    .m1 entryconfigure 2 -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.52 {entry configuration options 3 -activeforeground non-existent separator} -body {
    .m1 entryconfigure 3 -activeforeground non-existent
} -returnCodes error -result {unknown option "-activeforeground"}

test menu-2.53 {entry configuration options 4 -activeforeground non-existent checkbutton} -body {
    .m1 entryconfigure 4 -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.54 {entry configuration options 5 -activeforeground non-existent radiobutton} -body {
    .m1 entryconfigure 5 -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.55 {entry configuration options 0 -accelerator Ctrl+S tearoff} -body {
    .m1 entryconfigure 0 -accelerator Ctrl+S
} -returnCodes error -result {unknown option "-accelerator"}

test menu-2.56 {entry configuration options 1 -accelerator Ctrl+S command} -body {
    .m1 entryconfigure 1 -accelerator Ctrl+S
    lindex [.m1 entryconfigure 1 -accelerator] 4
} -result {Ctrl+S}

test menu-2.57 {entry configuration options 2 -accelerator Ctrl+S cascade} -body {
    .m1 entryconfigure 2 -accelerator Ctrl+S
    lindex [.m1 entryconfigure 2 -accelerator] 4
} -result {Ctrl+S}

test menu-2.58 {entry configuration options 3 -accelerator Ctrl+S separator} -body {
    .m1 entryconfigure 3 -accelerator Ctrl+S
} -returnCodes error -result {unknown option "-accelerator"}

test menu-2.59 {entry configuration options 4 -accelerator Ctrl+S checkbutton} -body {
    .m1 entryconfigure 4 -accelerator Ctrl+S
    lindex [.m1 entryconfigure 4 -accelerator] 4
} -result {Ctrl+S}

test menu-2.60 {entry configuration options 5 -accelerator Ctrl+S radiobutton} -body {
    .m1 entryconfigure 5 -accelerator Ctrl+S
    lindex [.m1 entryconfigure 5 -accelerator] 4
} -result {Ctrl+S}

test menu-2.61 {entry configuration options 0 -background #ff0000 tearoff} -body {
    .m1 entryconfigure 0 -background #ff0000
    lindex [.m1 entryconfigure 0 -background] 4
} -result {#ff0000}

test menu-2.62 {entry configuration options 1 -background #ff0000 command} -body {
    .m1 entryconfigure 1 -background #ff0000
    lindex [.m1 entryconfigure 1 -background] 4
} -result {#ff0000}

test menu-2.63 {entry configuration options 2 -background #ff0000 cascade} -body {
    .m1 entryconfigure 2 -background #ff0000
    lindex [.m1 entryconfigure 2 -background] 4
} -result {#ff0000}

test menu-2.64 {entry configuration options 3 -background #ff0000 separator} -body {
    .m1 entryconfigure 3 -background #ff0000
    lindex [.m1 entryconfigure 3 -background] 4
} -result {#ff0000}

test menu-2.65 {entry configuration options 4 -background #ff0000 checkbutton} -body {
    .m1 entryconfigure 4 -background #ff0000
    lindex [.m1 entryconfigure 4 -background] 4
} -result {#ff0000}

test menu-2.66 {entry configuration options 5 -background #ff0000 radiobutton} -body {
    .m1 entryconfigure 5 -background #ff0000
    lindex [.m1 entryconfigure 5 -background] 4
} -result {#ff0000}

test menu-2.67 {entry configuration options 0 -background non-existent tearoff} -body {
    .m1 entryconfigure 0 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}


test menu-2.68 {entry configuration options 1 -background non-existent command} -body {
    .m1 entryconfigure 1 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}




test menu-2.69 {entry configuration options 2 -background non-existent cascade} -body {
    .m1 entryconfigure 2 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.70 {entry configuration options 3 -background non-existent separator} -body {
    .m1 entryconfigure 3 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.71 {entry configuration options 4 -background non-existent checkbutton} -body {
    .m1 entryconfigure 4 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.72 {entry configuration options 5 -background non-existent radiobutton} -body {
    .m1 entryconfigure 5 -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.73 {entry configuration options 0 -bitmap questhead tearoff} -body {
    .m1 entryconfigure 0 -bitmap questhead
} -returnCodes error -result {unknown option "-bitmap"}

test menu-2.74 {entry configuration options 1 -bitmap questhead command} -body {
    .m1 entryconfigure 1 -bitmap questhead
    lindex [.m1 entryconfigure 1 -bitmap] 4
} -result {questhead}

test menu-2.75 {entry configuration options 2 -bitmap questhead cascade} -body {
    .m1 entryconfigure 2 -bitmap questhead
    lindex [.m1 entryconfigure 2 -bitmap] 4
} -result {questhead}

test menu-2.76 {entry configuration options 3 -bitmap questhead separator} -body {
    .m1 entryconfigure 3 -bitmap questhead
} -returnCodes error -result {unknown option "-bitmap"}

test menu-2.77 {entry configuration options 4 -bitmap questhead checkbutton} -body {
    .m1 entryconfigure 4 -bitmap questhead
    lindex [.m1 entryconfigure 4 -bitmap] 4
} -result {questhead}


test menu-2.78 {entry configuration options 5 -bitmap questhead radiobutton} -body {
    .m1 entryconfigure 5 -bitmap questhead
    lindex [.m1 entryconfigure 5 -bitmap] 4
} -result {questhead}




test menu-2.79 {entry configuration options 0 -bitmap badValue tearoff} -body {
    .m1 entryconfigure 0 -bitmap badValue
} -returnCodes error -result {unknown option "-bitmap"}

test menu-2.80 {entry configuration options 1 -bitmap badValue command} -body {
    .m1 entryconfigure 1 -bitmap badValue
} -returnCodes error -result {bitmap "badValue" not defined}


test menu-2.81 {entry configuration options 2 -bitmap badValue cascade} -body {
    .m1 entryconfigure 2 -bitmap badValue
} -returnCodes error -result {bitmap "badValue" not defined}

test menu-2.82 {entry configuration options 3 -bitmap badValue separator} -body {
    .m1 entryconfigure 3 -bitmap badValue


} -returnCodes error -result {unknown option "-bitmap"}

test menu-2.83 {entry configuration options 4 -bitmap badValue checkbutton} -body {
    .m1 entryconfigure 4 -bitmap badValue
} -returnCodes error -result {bitmap "badValue" not defined}

test menu-2.84 {entry configuration options 5 -bitmap badValue radiobutton} -body {
    .m1 entryconfigure 5 -bitmap badValue
} -returnCodes error -result {bitmap "badValue" not defined}

test menu-2.85 {entry configuration options 0 -columnbreak 1 tearoff} -body {
    .m1 entryconfigure 0 -columnbreak 1
} -returnCodes error -result {unknown option "-columnbreak"}

test menu-2.86 {entry configuration options 1 -columnbreak 1 command} -body {
    .m1 entryconfigure 1 -columnbreak 1
    lindex [.m1 entryconfigure 1 -columnbreak] 4
} -result 1

test menu-2.87 {entry configuration options 2 -columnbreak 1 cascade} -body {
    .m1 entryconfigure 2 -columnbreak 1
    lindex [.m1 entryconfigure 2 -columnbreak] 4
} -result 1

test menu-2.88 {entry configuration options 3 -columnbreak 1 separator} -body {
    .m1 entryconfigure 3 -columnbreak 1

} -returnCodes error -result {unknown option "-columnbreak"}



test menu-2.89 {entry configuration options 4 -columnbreak 1 checkbutton} -body {
    .m1 entryconfigure 4 -columnbreak 1
    lindex [.m1 entryconfigure 4 -columnbreak] 4
} -result 1

test menu-2.90 {entry configuration options 5 -columnbreak 1 radiobutton} -body {
    .m1 entryconfigure 5 -columnbreak 1
    lindex [.m1 entryconfigure 5 -columnbreak] 4
} -result 1

test menu-2.91 {entry configuration options 0 -command beep tearoff} -body {
    .m1 entryconfigure 0 -command beep
} -returnCodes error -result {unknown option "-command"}

test menu-2.92 {entry configuration options 1 -command beep command} -body {
    .m1 entryconfigure 1 -command beep
    lindex [.m1 entryconfigure 1 -command] 4
} -result {beep}

test menu-2.93 {entry configuration options 2 -command beep cascade} -body {
    .m1 entryconfigure 2 -command beep
    lindex [.m1 entryconfigure 2 -command] 4
} -result {beep}

test menu-2.94 {entry configuration options 3 -command beep separator} -body {
    .m1 entryconfigure 3 -command beep
} -returnCodes error -result {unknown option "-command"}

test menu-2.95 {entry configuration options 4 -command beep checkbutton} -body {
    .m1 entryconfigure 4 -command beep
    lindex [.m1 entryconfigure 4 -command] 4
} -result {beep}

test menu-2.96 {entry configuration options 5 -command beep radiobutton} -body {
    .m1 entryconfigure 5 -command beep
    lindex [.m1 entryconfigure 5 -command] 4
} -result {beep}

test menu-2.97 {entry configuration options 0 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* tearoff} -body {
    .m1 entryconfigure 0 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
} -returnCodes error -result {unknown option "-font"}

test menu-2.98 {entry configuration options 1 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* command} -body {
    .m1 entryconfigure 1 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    lindex [.m1 entryconfigure 1 -font] 4
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}

test menu-2.99 {entry configuration options 2 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* cascade} -body {
    .m1 entryconfigure 2 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    lindex [.m1 entryconfigure 2 -font] 4
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}

test menu-2.100 {entry configuration options 3 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* separator} -body {
    .m1 entryconfigure 3 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*


} -returnCodes error -result {unknown option "-font"}

test menu-2.101 {entry configuration options 4 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* checkbutton} -body {
    .m1 entryconfigure 4 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    lindex [.m1 entryconfigure 4 -font] 4
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}

test menu-2.102 {entry configuration options 5 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* radiobutton} -body {
    .m1 entryconfigure 5 -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    lindex [.m1 entryconfigure 5 -font] 4
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}

test menu-2.103 {entry configuration options 0 -font {kill rock stars} tearoff} -body {
    .m1 entryconfigure 0 -font {kill rock stars}

} -returnCodes error -result {unknown option "-font"}

test menu-2.104 {entry configuration options 1 -font {kill rock stars} command} -body {
    .m1 entryconfigure 1 -font {kill rock stars}
} -returnCodes error -result {expected integer but got "rock"}

test menu-2.105 {entry configuration options 2 -font {kill rock stars} cascade} -body {
    .m1 entryconfigure 2 -font {kill rock stars}
} -returnCodes error -result {expected integer but got "rock"}

test menu-2.106 {entry configuration options 3 -font {kill rock stars} separator} -body {
    .m1 entryconfigure 3 -font {kill rock stars}
} -returnCodes error -result {unknown option "-font"}

test menu-2.107 {entry configuration options 4 -font {kill rock stars} checkbutton} -body {
    .m1 entryconfigure 4 -font {kill rock stars}
} -returnCodes error -result {expected integer but got "rock"}


test menu-2.108 {entry configuration options 5 -font {kill rock stars} radiobutton} -body {
    .m1 entryconfigure 5 -font {kill rock stars}
} -returnCodes error -result {expected integer but got "rock"}

test menu-2.109 {entry configuration options 0 -foreground #110022 tearoff} -body {
    .m1 entryconfigure 0 -foreground #110022

} -returnCodes error -result {unknown option "-foreground"}

test menu-2.110 {entry configuration options 1 -foreground #110022 command} -body {
    .m1 entryconfigure 1 -foreground #110022

    lindex [.m1 entryconfigure 1 -foreground] 4
} -result {#110022}

test menu-2.111 {entry configuration options 2 -foreground #110022 cascade} -body {
    .m1 entryconfigure 2 -foreground #110022
    lindex [.m1 entryconfigure 2 -foreground] 4
} -result {#110022}

test menu-2.112 {entry configuration options 3 -foreground #110022 separator} -body {
    .m1 entryconfigure 3 -foreground #110022
} -returnCodes error -result {unknown option "-foreground"}

test menu-2.113 {entry configuration options 4 -foreground #110022 checkbutton} -body {
    .m1 entryconfigure 4 -foreground #110022
    lindex [.m1 entryconfigure 4 -foreground] 4
} -result {#110022}

test menu-2.114 {entry configuration options 5 -foreground #110022 radiobutton} -body {
    .m1 entryconfigure 5 -foreground #110022
    lindex [.m1 entryconfigure 5 -foreground] 4
} -result {#110022}

test menu-2.115 {entry configuration options 0 -foreground non-existent tearoff} -body {
    .m1 entryconfigure 0 -foreground non-existent
} -returnCodes error -result {unknown option "-foreground"}

test menu-2.116 {entry configuration options 1 -foreground non-existent command} -body {
    .m1 entryconfigure 1 -foreground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.117 {entry configuration options 2 -foreground non-existent cascade} -body {
    .m1 entryconfigure 2 -foreground non-existent
} -returnCodes error -result {unknown color name "non-existent"}


test menu-2.118 {entry configuration options 3 -foreground non-existent separator} -body {
    .m1 entryconfigure 3 -foreground non-existent



} -returnCodes error -result {unknown option "-foreground"}

test menu-2.119 {entry configuration options 4 -foreground non-existent checkbutton} -body {
    .m1 entryconfigure 4 -foreground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.120 {entry configuration options 5 -foreground non-existent radiobutton} -body {
    .m1 entryconfigure 5 -foreground non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.121 {entry configuration options 0 -image image1 tearoff} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 0 -image image1
} -returnCodes error -result {unknown option "-image"}

test menu-2.122 {entry configuration options 1 -image image1 command} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 1 -image {}
} -body {
    .m1 entryconfigure 1 -image image1
    lindex [.m1 entryconfigure 1 -image] 4
} -cleanup {
    .m1 entryconfigure 1 -image {}
} -result {image1}


test menu-2.123 {entry configuration options 2 -image image1 cascade} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 2 -image {}
} -body {
    .m1 entryconfigure 2 -image image1
    lindex [.m1 entryconfigure 2 -image] 4
} -cleanup {
    .m1 entryconfigure 2 -image {}
} -result {image1}

test menu-2.124 {entry configuration options 3 -image image1 separator} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 3 -image image1
} -returnCodes error -result {unknown option "-image"}

test menu-2.125 {entry configuration options 4 -image image1 checkbutton} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 4 -image {}
} -body {
    .m1 entryconfigure 4 -image image1
    lindex [.m1 entryconfigure 4 -image] 4
} -cleanup {
    .m1 entryconfigure 4 -image {}
} -result {image1}


test menu-2.126 {entry configuration options 5 -image image1 radiobutton} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 5 -image {}
} -body {
    .m1 entryconfigure 5 -image image1
    lindex [.m1 entryconfigure 5 -image] 4
} -cleanup {
    .m1 entryconfigure 5 -image {}
} -result {image1}

test menu-2.127 {entry configuration options 0 -image bogus tearoff} -body {
    .m1 entryconfigure 0 -image bogus
} -returnCodes error -result {unknown option "-image"}

test menu-2.128 {entry configuration options 1 -image bogus command} -body {
    .m1 entryconfigure 1 -image bogus
} -returnCodes error -result {image "bogus" doesn't exist}

test menu-2.129 {entry configuration options 2 -image bogus cascade} -body {
    .m1 entryconfigure 2 -image bogus
} -returnCodes error -result {image "bogus" doesn't exist}

test menu-2.130 {entry configuration options 3 -image bogus separator} -body {
    .m1 entryconfigure 3 -image bogus
} -returnCodes error -result {unknown option "-image"}

test menu-2.131 {entry configuration options 4 -image bogus checkbutton} -body {
    .m1 entryconfigure 4 -image bogus
} -returnCodes error -result {image "bogus" doesn't exist}

test menu-2.132 {entry configuration options 5 -image bogus radiobutton} -body {
    .m1 entryconfigure 5 -image bogus
} -returnCodes error -result {image "bogus" doesn't exist}



test menu-2.133 {entry configuration options 0 -image {} tearoff} -body {
    .m1 entryconfigure 0 -image
} -returnCodes error -result {unknown option "-image"}

test menu-2.134 {entry configuration options 1 -image {} command} -setup {
    .m1 entryconfigure 1 -image {}
} -body {
    .m1 entryconfigure 1 -image
    lindex [.m1 entryconfigure 1 -image] 4
} -result {}

test menu-2.135 {entry configuration options 2 -image {} cascade} -setup {
    .m1 entryconfigure 2 -image {}
} -body {
    .m1 entryconfigure 2 -image
    lindex [.m1 entryconfigure 2 -image] 4
} -result {}


test menu-2.136 {entry configuration options 3 -image {} separator} -body {
    .m1 entryconfigure 3 -image
} -returnCodes error -result {unknown option "-image"}

test menu-2.137 {entry configuration options 4 -image {} checkbutton} -body {
    .m1 entryconfigure 4 -image
    lindex [.m1 entryconfigure 4 -image] 4
} -result {}

test menu-2.138 {entry configuration options 5 -image {} radiobutton} -body {
    .m1 entryconfigure 5 -image
    lindex [.m1 entryconfigure 5 -image] 4
} -result {}

test menu-2.139 {entry configuration options 0 -indicatoron 1 tearoff} -body {
    .m1 entryconfigure 0 -indicatoron 1
} -returnCodes error -result {unknown option "-indicatoron"}

test menu-2.140 {entry configuration options 1 -indicatoron 1 command} -body {
    .m1 entryconfigure 1 -indicatoron 1
} -returnCodes error -result {unknown option "-indicatoron"}

test menu-2.141 {entry configuration options 2 -indicatoron 1 cascade} -body {
    .m1 entryconfigure 2 -indicatoron 1
} -returnCodes error -result {unknown option "-indicatoron"}

test menu-2.142 {entry configuration options 3 -indicatoron 1 separator} -body {
    .m1 entryconfigure 3 -indicatoron 1
} -returnCodes error -result {unknown option "-indicatoron"}

test menu-2.143 {entry configuration options 4 -indicatoron 1 checkbutton} -body {
    .m1 entryconfigure 4 -indicatoron 1
    lindex [.m1 entryconfigure 4 -indicatoron] 4
} -result 1



test menu-2.144 {entry configuration options 5 -indicatoron 1 radiobutton} -body {
    .m1 entryconfigure 5 -indicatoron 1
    lindex [.m1 entryconfigure 5 -indicatoron] 4
} -result 1

test menu-2.145 {entry configuration options 0 -label test tearoff} -body {
    .m1 entryconfigure 0 -label test
} -returnCodes error -result {unknown option "-label"}

test menu-2.146 {entry configuration options 1 -label test command} -body {
    .m1 entryconfigure 1 -label test
    lindex [.m1 entryconfigure 1 -label] 4
} -result {test}

test menu-2.147 {entry configuration options 2 -label test cascade} -body {
    .m1 entryconfigure 2 -label test
    lindex [.m1 entryconfigure 2 -label] 4
} -result {test}

test menu-2.148 {entry configuration options 3 -label test separator} -body {
    .m1 entryconfigure 3 -label test
} -returnCodes error -result {unknown option "-label"}

test menu-2.149 {entry configuration options 4 -label test checkbutton} -body {
    .m1 entryconfigure 4 -label test
    lindex [.m1 entryconfigure 4 -label] 4
} -result {test}

test menu-2.150 {entry configuration options 5 -label test radiobutton} -body {
    .m1 entryconfigure 5 -label test
    lindex [.m1 entryconfigure 5 -label] 4
} -result {test}

test menu-2.151 {entry configuration options 0 -menu .m2 tearoff} -body {
    .m1 entryconfigure 0 -menu .m2
} -returnCodes error -result {unknown option "-menu"}

test menu-2.152 {entry configuration options 1 -menu .m2 command} -body {
    .m1 entryconfigure 1 -menu .m2
} -returnCodes error -result {unknown option "-menu"}

test menu-2.153 {entry configuration options 2 -menu .m2 cascade} -body {
    .m1 entryconfigure 2 -menu .m2
    lindex [.m1 entryconfigure 2 -menu] 4
} -result {.m2}

test menu-2.154 {entry configuration options 3 -menu .m2 separator} -body {
    .m1 entryconfigure 3 -menu .m2
} -returnCodes error -result {unknown option "-menu"}

test menu-2.155 {entry configuration options 4 -menu .m2 checkbutton} -body {
    .m1 entryconfigure 4 -menu .m2
} -returnCodes error -result {unknown option "-menu"}

test menu-2.156 {entry configuration options 5 -menu .m2 radiobutton} -body {
    .m1 entryconfigure 5 -menu .m2
} -returnCodes error -result {unknown option "-menu"}


test menu-2.157 {entry configuration options 0 -offvalue off tearoff} -body {
    .m1 entryconfigure 0 -offvalue off
} -returnCodes error -result {unknown option "-offvalue"}


test menu-2.158 {entry configuration options 1 -offvalue off command} -body {
    .m1 entryconfigure 1 -offvalue off


} -returnCodes error -result {unknown option "-offvalue"}

test menu-2.159 {entry configuration options 2 -offvalue off cascade} -body {
    .m1 entryconfigure 2 -offvalue off
} -returnCodes error -result {unknown option "-offvalue"}


test menu-2.160 {entry configuration options 3 -offvalue off separator} -body {
    .m1 entryconfigure 3 -offvalue off

} -returnCodes error -result {unknown option "-offvalue"}

test menu-2.161 {entry configuration options 4 -offvalue off checkbutton} -body {
    .m1 entryconfigure 4 -offvalue off
    lindex [.m1 entryconfigure 4 -offvalue] 4
} -result {off}

test menu-2.162 {entry configuration options 5 -offvalue off radiobutton} -body {
    .m1 entryconfigure 5 -offvalue off
} -returnCodes error -result {unknown option "-offvalue"}

test menu-2.163 {entry configuration options 0 -onvalue on tearoff} -body {
    .m1 entryconfigure 0 -onvalue on
} -returnCodes error -result {unknown option "-onvalue"}


test menu-2.164 {entry configuration options 1 -onvalue on command} -body {
    .m1 entryconfigure 1 -onvalue on
} -returnCodes error -result {unknown option "-onvalue"}

test menu-2.165 {entry configuration options 2 -onvalue on cascade} -body {
    .m1 entryconfigure 2 -onvalue on
} -returnCodes error -result {unknown option "-onvalue"}

test menu-2.166 {entry configuration options 3 -onvalue on separator} -body {
    .m1 entryconfigure 3 -onvalue on
} -returnCodes error -result {unknown option "-onvalue"}

test menu-2.167 {entry configuration options 4 -onvalue on checkbutton} -body {
    .m1 entryconfigure 4 -onvalue on
    lindex [.m1 entryconfigure 4 -onvalue] 4
} -result {on}

test menu-2.168 {entry configuration options 5 -onvalue on radiobutton} -body {
    .m1 entryconfigure 5 -onvalue on
} -returnCodes error -result {unknown option "-onvalue"}

test menu-2.169 {entry configuration options 0 -selectcolor #110022 tearoff} -body {
    .m1 entryconfigure 0 -selectcolor #110022
} -returnCodes error -result {unknown option "-selectcolor"}



test menu-2.170 {entry configuration options 1 -selectcolor #110022 command} -body {
    .m1 entryconfigure 1 -selectcolor #110022
} -returnCodes error -result {unknown option "-selectcolor"}

test menu-2.171 {entry configuration options 2 -selectcolor #110022 cascade} -body {
    .m1 entryconfigure 2 -selectcolor #110022
} -returnCodes error -result {unknown option "-selectcolor"}


test menu-2.172 {entry configuration options 3 -selectcolor #110022 separator} -body {
    .m1 entryconfigure 3 -selectcolor #110022


} -returnCodes error -result {unknown option "-selectcolor"}



test menu-2.173 {entry configuration options 4 -selectcolor #110022 checkbutton} -body {
    .m1 entryconfigure 4 -selectcolor #110022
    lindex [.m1 entryconfigure 4 -selectcolor] 4
} -result {#110022}

test menu-2.174 {entry configuration options 5 -selectcolor #110022 radiobutton} -body {
    .m1 entryconfigure 5 -selectcolor #110022
    lindex [.m1 entryconfigure 5 -selectcolor] 4
} -result {#110022}

test menu-2.175 {entry configuration options 0 -selectcolor non-existent tearoff} -body {
    .m1 entryconfigure 0 -selectcolor non-existent
} -returnCodes error -result {unknown option "-selectcolor"}

test menu-2.176 {entry configuration options 1 -selectcolor non-existent command} -body {
    .m1 entryconfigure 1 -selectcolor non-existent

} -returnCodes error -result {unknown option "-selectcolor"}


test menu-2.177 {entry configuration options 2 -selectcolor non-existent cascade} -body {
    .m1 entryconfigure 2 -selectcolor non-existent
} -returnCodes error -result {unknown option "-selectcolor"}

test menu-2.178 {entry configuration options 3 -selectcolor non-existent separator} -body {
    .m1 entryconfigure 3 -selectcolor non-existent
} -returnCodes error -result {unknown option "-selectcolor"}

test menu-2.179 {entry configuration options 4 -selectcolor non-existent checkbutton} -body {
    .m1 entryconfigure 4 -selectcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.180 {entry configuration options 5 -selectcolor non-existent radiobutton} -body {
    .m1 entryconfigure 5 -selectcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}

test menu-2.181 {entry configuration options 0 -selectimage image1 tearoff} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 0 -selectimage image1
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.182 {entry configuration options 1 -selectimage image1 command} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 1 -selectimage image1
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.183 {entry configuration options 2 -selectimage image1 cascade} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 2 -selectimage image1
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.184 {entry configuration options 3 -selectimage image1 separator} -constraints {
    hasEarthPhoto
} -body {
    .m1 entryconfigure 3 -selectimage image1
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.185 {entry configuration options 4 -selectimage image1 checkbutton} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 4 -selectimage {}
} -body {
    .m1 entryconfigure 4 -selectimage image1
    lindex [.m1 entryconfigure 4 -selectimage] 4
} -cleanup {
    .m1 entryconfigure 4 -selectimage {}
} -result {image1}

test menu-2.186 {entry configuration options 5 -selectimage image1 radiobutton} -constraints {
    hasEarthPhoto
} -setup {
    .m1 entryconfigure 5 -selectimage {}
} -body {
    .m1 entryconfigure 5 -selectimage image1
    lindex [.m1 entryconfigure 5 -selectimage] 4
} -cleanup {
    .m1 entryconfigure 5 -selectimage {}
} -result {image1}

test menu-2.187 {entry configuration options 0 -selectimage bogus tearoff} -body {
    .m1 entryconfigure 0 -selectimage bogus
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.188 {entry configuration options 1 -selectimage bogus command} -body {
    .m1 entryconfigure 1 -selectimage bogus
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.189 {entry configuration options 2 -selectimage bogus cascade} -body {
    .m1 entryconfigure 2 -selectimage bogus
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.190 {entry configuration options 3 -selectimage bogus separator} -body {
    .m1 entryconfigure 3 -selectimage bogus
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.191 {entry configuration options 4 -selectimage bogus checkbutton} -body {
    .m1 entryconfigure 4 -selectimage bogus
} -returnCodes error -result {image "bogus" doesn't exist}

test menu-2.192 {entry configuration options 5 -selectimage bogus radiobutton} -body {
    .m1 entryconfigure 5 -selectimage bogus
} -returnCodes error -result {image "bogus" doesn't exist}

test menu-2.193 {entry configuration options 0 -selectimage {} tearoff} -body {
    .m1 entryconfigure 0 -selectimage
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.194 {entry configuration options 1 -selectimage {} command} -body {
    .m1 entryconfigure 1 -selectimage
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.195 {entry configuration options 2 -selectimage {} cascade} -body {
    .m1 entryconfigure 2 -selectimage
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.196 {entry configuration options 3 -selectimage {} separator} -body {
    .m1 entryconfigure 3 -selectimage
} -returnCodes error -result {unknown option "-selectimage"}

test menu-2.197 {entry configuration options 4 -selectimage {} checkbutton} -body {
    .m1 entryconfigure 4 -selectimage
    lindex [.m1 entryconfigure 4 -selectimage] 4
} -result {}

test menu-2.198 {entry configuration options 5 -selectimage {} radiobutton} -body {
    .m1 entryconfigure 5 -selectimage
    lindex [.m1 entryconfigure 5 -selectimage] 4
} -result {}

test menu-2.199 {entry configuration options 0 -state normal tearoff} -body {
    .m1 entryconfigure 0 -state normal
    lindex [.m1 entryconfigure 0 -state] 4
} -result {normal}

test menu-2.200 {entry configuration options 1 -state normal command} -body {
    .m1 entryconfigure 1 -state normal
    lindex [.m1 entryconfigure 1 -state] 4
} -result {normal}

test menu-2.201 {entry configuration options 2 -state normal cascade} -body {
    .m1 entryconfigure 2 -state normal
    lindex [.m1 entryconfigure 2 -state] 4
} -result {normal}

test menu-2.202 {entry configuration options 3 -state normal separator} -body {
    .m1 entryconfigure 3 -state normal
} -returnCodes error -result {unknown option "-state"}

test menu-2.203 {entry configuration options 4 -state normal checkbutton} -body {
    .m1 entryconfigure 4 -state normal
    lindex [.m1 entryconfigure 4 -state] 4
} -result {normal}

test menu-2.204 {entry configuration options 5 -state normal radiobutton} -body {
    .m1 entryconfigure 5 -state normal
    lindex [.m1 entryconfigure 5 -state] 4
} -result {normal}

test menu-2.205 {entry configuration options 0 -value {any string} tearoff} -body {
    .m1 entryconfigure 0 -value {any string}
} -returnCodes error -result {unknown option "-value"}

test menu-2.206 {entry configuration options 1 -value {any string} command} -body {
    .m1 entryconfigure 1 -value {any string}
} -returnCodes error -result {unknown option "-value"}


test menu-2.207 {entry configuration options 2 -value {any string} cascade} -body {
    .m1 entryconfigure 2 -value {any string}
} -returnCodes error -result {unknown option "-value"}

test menu-2.208 {entry configuration options 3 -value {any string} separator} -body {
    .m1 entryconfigure 3 -value {any string}
} -returnCodes error -result {unknown option "-value"}

test menu-2.209 {entry configuration options 4 -value {any string} checkbutton} -body {

    .m1 entryconfigure 4 -value {any string}
} -returnCodes error -result {unknown option "-value"}


test menu-2.210 {entry configuration options 5 -value {any string} radiobutton} -body {
    .m1 entryconfigure 5 -value {any string}
    lindex [.m1 entryconfigure 5 -value] 4
} -result {any string}


test menu-2.211 {entry configuration options 0 -variable {any string} tearoff} -body {
    .m1 entryconfigure 0 -variable {any string}
} -returnCodes error -result {unknown option "-variable"}

test menu-2.212 {entry configuration options 1 -variable {any string} command} -body {
    .m1 entryconfigure 1 -variable {any string}
} -returnCodes error -result {unknown option "-variable"}

test menu-2.213 {entry configuration options 2 -variable {any string} cascade} -body {
    .m1 entryconfigure 2 -variable {any string}
} -returnCodes error -result {unknown option "-variable"}

test menu-2.214 {entry configuration options 3 -variable {any string} separator} -body {
    .m1 entryconfigure 3 -variable {any string}
} -returnCodes error -result {unknown option "-variable"}

test menu-2.215 {entry configuration options 4 -variable {any string} checkbutton} -body {
    .m1 entryconfigure 4 -variable {any string}
    lindex [.m1 entryconfigure 4 -variable] 4
} -result {any string}

test menu-2.216 {entry configuration options 5 -variable {any string} radiobutton} -body {
    .m1 entryconfigure 5 -variable {any string}
    lindex [.m1 entryconfigure 5 -variable] 4
} -result {any string}

test menu-2.217 {entry configuration options 0 -underline 0 tearoff} -body {
    .m1 entryconfigure 0 -underline 0
} -returnCodes error -result {unknown option "-underline"}

test menu-2.218 {entry configuration options 1 -underline 0 command} -body {
    .m1 entryconfigure 1 -underline 0
    lindex [.m1 entryconfigure 1 -underline] 4
} -result 0

test menu-2.219 {entry configuration options 2 -underline 0 cascade} -body {
    .m1 entryconfigure 2 -underline 0
    lindex [.m1 entryconfigure 2 -underline] 4
} -result 0

test menu-2.220 {entry configuration options 3 -underline 0 separator} -body {
    .m1 entryconfigure 3 -underline 0
} -returnCodes error -result {unknown option "-underline"}

test menu-2.221 {entry configuration options 4 -underline 0 checkbutton} -body {
    .m1 entryconfigure 4 -underline 0
    lindex [.m1 entryconfigure 4 -underline] 4
} -result 0

test menu-2.222 {entry configuration options 5 -underline 0 radiobutton} -body {
    .m1 entryconfigure 5 -underline 0
    lindex [.m1 entryconfigure 5 -underline] 4
} -result 0

test menu-2.223 {entry configuration options 0 -underline 3p tearoff} -body {
    .m1 entryconfigure 0 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.224 {entry configuration options 1 -underline 3p command} -body {
    .m1 entryconfigure 1 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.225 {entry configuration options 2 -underline 3p cascade} -body {
    .m1 entryconfigure 2 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.226 {entry configuration options 3 -underline 3p separator} -body {
    .m1 entryconfigure 3 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.227 {entry configuration options 4 -underline 3p checkbutton} -body {
    .m1 entryconfigure 4 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.228 {entry configuration options 5 -underline 3p radiobutton} -body {
    .m1 entryconfigure 5 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

deleteWindows
if {[testConstraint hasEarthPhoto]} {
    image delete image1
}



test menu-3.1 {MenuWidgetCmd procedure} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 option ?arg ...?"}
test menu-3.2 {MenuWidgetCmd, Tcl_Preserve and Tcl_Release} -constraints {
	nonUnixUserInteraction
} -setup {
    destroy .m1
} -body  {
    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "menu-3.2: Hit Escape"
    .m1 post 40 40
} -cleanup {
    destroy .m1
} -returnCodes ok -result {}
test menu-3.3 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 activate index"}
test menu-3.4 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 activate "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.5 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add separator
    .m1 activate 2
} -cleanup {
	destroy .m1
} -result {}
test menu-3.6 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -state disabled
    .m1 activate 1
} -cleanup {
	destroy .m1
} -result {}

test menu-3.7 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate 1
} -cleanup {
	destroy .m1
} -result {}

test menu-3.8 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 add type ?-option value ...?"}

test menu-3.9 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry type "foo": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-3.10 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
	destroy .m1
} -result {}
test menu-3.11 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 cget
} -returnCodes error -result {wrong # args: should be ".m1 cget option"}
test menu-3.12 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.13 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Some string"
    .m1 cget -postcommand
} -cleanup {
	destroy .m1
} -result {Some string}
test menu-3.14 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.15 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone a b c d
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.16 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.17 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1 tearoff
} -cleanup {
	destroy .m1
} -result {}
test menu-3.18 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    llength [.m1 configure]
} -cleanup {
	destroy .m1
} -result 21
test menu-3.19 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.20 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "A random String"
} -cleanup {
	destroy .m1
} -result {}
test menu-3.21 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Another string"
    lindex [.m1 configure -postcommand] 4
} -cleanup {
	destroy .m1
} -result {Another string}
test menu-3.22 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete
} -returnCodes error -result {wrong # args: should be ".m1 delete first ?last?"}
test menu-3.23 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.24 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 delete 0 "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.25 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete 0
} -cleanup {
	destroy .m1
} -result {}
test menu-3.26 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 delete 1 0
} -cleanup {
	destroy .m1
} -result {}
test menu-3.27 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 delete 1 3
} -cleanup {
	destroy .m1
} -result {}
test menu-3.28 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 2
    .m1 delete 1 3
} -cleanup {
	destroy .m1
} -result {}
test menu-3.29 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 3
    .m1 delete 1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.29+1 {MenuWidgetCmd, "delete", Bug 220950} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "bogus"
    .m1 add command -label "ok"
    .m1 delete 10 20
    .m1 entrycget last -label
} -cleanup {
    destroy .m1
} -result ok
test menu-3.30 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.31 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget index option foo
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.32 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget foo -label
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.33 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.34 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure
} -returnCodes error -result {wrong # args: should be ".m1 entryconfigure index ?-option value ...?"}
test menu-3.35 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.36 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    llength [.m1 entryconfigure 1]
} -cleanup {
	destroy .m1
} -result 15
test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.38 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -label "changed"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
} -result {changed}
test menu-3.39 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 index
} -returnCodes error -result {wrong # args: should be ".m1 index string"}
test menu-3.40 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 index foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.41 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test"
    .m1 add command -label "3"
    .m1 add command -label "another label"
    .m1 add command -label "end"
    .m1 add command -label "3a"
    .m1 add command -label "final entry"
    list [.m1 index "test"] [.m1 index "3"] [.m1 index "3a"] [.m1 index "end"]
} -cleanup {
	destroy .m1
} -result {1 3 5 6}
test menu-3.42 {MenuWidgetCmd procedure, "insert" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 insert
} -returnCodes error -result {wrong # args: should be ".m1 insert index type ?-option value ...?"}
test menu-3.43 {MenuWidgetCmd procedure, "insert" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 insert 1 command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.44 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 invoke
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 invoke index"}
test menu-3.45 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 invoke foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.46 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "set foo" -command "set foo hello"
    list [.m1 invoke 1] [set foo] [unset foo]
} -cleanup {
	destroy .m1
} -returnCodes ok -result {hello hello {}}
test menu-3.47 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "On Windows, hit Escape to get this menu to go away"
    .m1 post
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 post x y ?index?"}
test menu-3.48 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 post foo 40
} -cleanup {
	destroy .m1
} -returnCodes error -result {expected integer but got "foo"}
test menu-3.49 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 post 40 bar
} -cleanup {
	destroy .m1
} -returnCodes error -result {expected integer but got "bar"}
test menu-3.50 {MenuWidgetCmd procedure, "post" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.50: hit Escape" -command "puts hello"
    .m1 post 40 40
} -cleanup {
	destroy .m1
} -result {}
test menu-3.51 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 postcascade
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 postcascade index"}
test menu-3.52 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 postcascade foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.53 {MenuWidgetCmd procedure, "postcascade" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1 .m2
} -body {
    menu .m1
    .m1 add command -label "menu-3.53 - hit Escape"
    menu .m2
    .m1 post 40 40
    .m1 add cascade -menu .m2
    .m1 postcascade 1
} -cleanup {
	destroy .m1 .m2
} -result {}
test menu-3.54 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1 .m2
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2 -label "menu-3.57 - hit Escape"
    .m1 postcascade 1
    .m1 postcascade none
} -cleanup {
	destroy .m1 .m2
} -result {}
test menu-3.55 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 type
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 type index"}
test menu-3.56 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 type foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.57 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {command}
test menu-3.58 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add separator
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {separator}
test menu-3.59 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {checkbutton}
test menu-3.60 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {radiobutton}
test menu-3.61 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {cascade}
test menu-3.62 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 type 0
} -cleanup {
	destroy .m1
} -result {tearoff}
test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 unpost foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 unpost"}
test menu-3.64 {MenuWidgetCmd procedure, "unpost" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.64 - hit Escape"
    .m1 post 40 40
    .m1 unpost
} -cleanup {
	destroy .m1
} -result {}
test menu-3.65 {MenuWidgetCmd procedure, "yposition" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 yposition
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 yposition index"}
test menu-3.66a {MenuWidgetCmd procedure, "yposition" option, no tearoff} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 0
test menu-3.66b {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    notAqua
} -setup {
	destroy .m1
} -body {
    # on Win or Linux, tearoff menus are supported
    # see menu-3.66c for aqua
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 1
test menu-3.66c {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    aqua
} -setup {
	destroy .m1
} -body {
    # on OS X, tearoff menus are not supported
    # see menu-3.66b for win or linux
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 0
test menu-3.67 {MenuWidgetCmd procedure, bad option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad option "foo": must be activate, add, cget, clone, configure, delete, entrycget, entryconfigure, index, insert, invoke, post, postcascade, type, unpost, xposition, or yposition}
test menu-3.68 {MenuWidgetCmd procedure, fix for bug#508988} -setup {
    deleteWindows
} -body {
    set t .t
    set m1 .t.m1
    set c1 .t.c1
    set c2 .t.c2
    toplevel .t
    menu $m1 -tearoff 1
    menu $c1 -tearoff 1
    $c1 add command -label c1
    menu $c2 -tearoff 1
    $c2 add command -label c2
    $m1 add cascade -label c1 -menu $c1
    $t configure -menu $m1
    $m1 entryconfigure 1 -menu $c2 -label c2
    $t configure -menu ""
    list [winfo exists $c1] [winfo exists $c2]
} -cleanup {
    deleteWindows
} -result {1 1}
test menu-3.69 {MenuWidgetCmd procedure, "xposition" option} -setup {
    destroy .m1
    menu .m1
} -body {
    .m1 xposition
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 xposition index"}
test menu-3.70 {MenuWidgetCmd procedure, "xposition" option} -setup {
    destroy .m1
    menu .m1
} -body {
    .m1 xposition 1
    subst {} ;# just checking that the xposition does not produce an error...
} -cleanup {
    destroy .m1
} -result {}
test menu-3.71 {MenuWidgetCmd procedure, "index end" option, bug [f3cd942e9e]} -setup {
    destroy .m1
} -body {
    menu .m1
    list [.m1 index "end"]
} -cleanup {
    destroy .m1
} -result none


test menu-4.1 {TkInvokeMenu: disabled} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off \
	-state disabled
    list [catch {.m1 invoke 1} msg] $foo
} -cleanup {
    destroy .m1
} -result {0 off}
test menu-4.2 {TkInvokeMenu: tearoff} -setup {
    destroy .m1
} -body {
    menu .m1
	catch {.m1 invoke 0}
} -cleanup {
    deleteWindows
} -result 0
test menu-4.3 {TkInvokeMenu: checkbutton -on} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 \
		[catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.4 {TkInvokeMenu: checkbutton -off} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    .m1 invoke 1
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 off 0 {}}
test menu-4.5 {TkInvokeMenu: checkbutton array element} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo(1) -onvalue on
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo(1)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.6 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 one 0 {}}
test menu-4.7 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 2} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 two 0 {}}
test menu-4.8 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.9 {TkInvokeMenu: radiobutton array element} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo(2) -value one
    .m1 add radiobutton -label "2" -variable foo(2) -value two
    .m1 add radiobutton -label "3" -variable foo(2) -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo(2)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.10 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "test" -command "set menu_test menu-4.8"
    list [catch {.m1 invoke 1} msg] $msg [catch {set menu_test} msg2] $msg2 [catch {unset menu_test} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 menu-4.8 0 menu-4.8 0 {}}
test menu-4.11 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test" -menu .m1.m2
    list [catch {.m1 invoke 1} msg] $msg
} -cleanup {
	destroy .m1
} -result {0 {}}
test menu-4.12 {TkInvokeMenu} -setup {
    destroy .m1




} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test" -command ".m1 delete 1"
    list [catch {.m1 invoke 1} msg] $msg [catch {.m1 type "test"} msg2] $msg2
} -cleanup {
	destroy .m1
} -result {0 {} 1 {bad menu entry index "test"}}

test menu-5.1 {DestroyMenuInstance} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -returnCodes ok
test menu-5.2 {DestroyMenuInstance - cascade menu} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    destroy .m1 .m2
} -returnCodes ok
test menu-5.3 {DestroyMenuInstance - multiple cascade parents} -setup {
    destroy .m1 .m2 .m3
} -body {

    menu .m1
    .m1 add cascade -menu .m3
    menu .m2
    .m2 add cascade -menu .m3
    menu .m3
    list [destroy .m3] [destroy .m1 .m2]
} -returnCodes ok -result {{} {}}
test menu-5.4 {DestroyMenuInstance - multiple cascade parents} -setup {
    destroy .m1 .m2 .m3 .m4
} -body {


    menu .m1
    .m1 add cascade -menu .m4
    menu .m2
    .m2 add cascade -menu .m4
    menu .m3
    .m3 add cascade -menu .m4
    menu .m4
    list [destroy .m4] [destroy .m1 .m2 .m3]
} -returnCodes ok -result {{} {}}
test menu-5.5 {DestroyMenuInstance - cascades of cloned menus} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    . configure -menu .m1
    list [destroy .m2] [.m1 entrycget 1 -menu] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} .m2 {} {}}
test menu-5.6 {DestroyMenuInstance - cascades of cloned menus} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1
    list [destroy .m2] [. configure -menu ""] [destroy .t2 .m1]
} -returnCodes ok -result {{} {} {}}
test menu-5.7 {DestroyMenuInstance - basic clones} -setup {
    destroy .m1
} -body {
    menu .m1
    set tearoff [tk::TearOffMenu .m1]
    list [destroy $tearoff] [destroy .m1]
} -result {{} {}}
test menu-5.8 {DestroyMenuInstance - multiple clones} -setup {
    destroy .m1
} -body {
    menu .m1
    set tearoff1 [tk::TearOffMenu .m1]
    set tearoff2 [tk::TearOffMenu .m1]
    list [destroy $tearoff1] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-5.9 {DestroyMenuInstace - main menu} -setup {
    destroy .m1
} -body {
    menu .m1
    tk::TearOffMenu .m1
    destroy .m1
} -returnCodes ok
test menu-5.10 {DestroyMenuInstance - freeing entries} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "foo"
    destroy .m1
} -returnCodes ok
test menu-5.11 {DestroyMenuInstace - no entries} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 configure -tearoff 0
    destroy .m1
} -returnCodes ok
test menu-5.12 {DestroyMenuInstance - platform data} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -returnCodes ok
test menu-5.13 {DestroyMenuInstance - clones when mismatched tearoffs} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [destroy .m2] [destroy .m1]
} -result {{} {}}


test menu-6.1 {TkDestroyMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -returnCodes ok
test menu-6.2 {TkDestroyMenu - reentrancy} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    bind .m1 <Destroy> {destroy .m1}
    menu .m2
    bind .m2 <Destroy> {destroy .m2}
    list [destroy .m1] [destroy .m2]
} -returnCodes ok -result {{} {}}
test menu-6.3 {TkDestroyMenu - reentrancy} -setup {
    destroy .m1 .m2 .m3
} -body {

    menu .m1
    bind .m1 <Destroy> {destroy .m2}
    .m1 clone .m2
    .m1 clone .m3
    list [destroy .m1] [winfo exists .m2]
} -returnCodes ok -result {{} 0}
test menu-6.4 {TkDestroyMenu - reentrancy - clones} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m1.m3
    destroy .m1
} -cleanup {
    deleteWindows
} -returnCodes ok
test menu-6.5 {TkDestroyMenu} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 clone .m2
    destroy .m1
    winfo exists .m2
} -result 0
test menu-6.6 {TkDestroyMenu} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 clone .m2 tearoff
    destroy .m1
} -result {}
test menu-6.7 {TkDestroyMenu} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 clone .m2
    destroy .m2
    destroy .m1
} -returnCodes ok -result {}
test menu-6.8 {TkDestroyMenu} -setup {
    destroy .m1 .m2 .m3
} -body {

    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    destroy .m1
    list [winfo exists .m2] [winfo exists .m3]
} -result {0 0}
test menu-6.9 {TkDestroyMenu} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m1 clone .m3
	list [destroy .m2] [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {} {}}
test menu-6.10 {TkDestroyMenu} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m1 clone .m3
	list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.11 {TkDestroyMenu} -setup {
    deleteWindows
} -body {


    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m2] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.12 {TkDestroyMenu} -setup {
    deleteWindows
} -body {


    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.13 {TkDestroyMenu} -setup {
    deleteWindows
} -body {


    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m4] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.14 {TkDestroyMenu} -setup {
	destroy .m1
} -body {
    menu .m1
    . configure -menu .m1
    list [destroy .m1] [. configure -menu ""]
} -returnCodes ok -result {{} {}}
test menu-6.15 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    list [destroy .m1] [destroy .t2] [. configure -menu ""]
} -result {{} {} {}}
test menu-6.16 {TkDestroyMenu} -setup {
    deleteWindows
} -body {

    menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    toplevel .t3
    wm geometry .t3 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    .t3 configure -menu .m1
    list [destroy .m1] [destroy .t2] [destroy .t3] [. configure -menu ""]
} -result {{} {} {} {}}

test menu-7.1 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    destroy .m1
} -returnCodes ok
test menu-7.2 {UnhookCascadeEntry} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -menu .m2
    destroy .m1
} -returnCodes ok
test menu-7.3 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m2 add cascade -menu .cascade
    .m1 add cascade -menu .cascade
    list [destroy .m1] [destroy .m2]
} -returnCodes ok -result {{} {}}
test menu-7.4 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    list [destroy .m1] [destroy .m2]
} -returnCodes ok -result {{} {}}
test menu-7.5 {UnhookCascadeEntry} -setup {
    deleteWindows









} -body {




    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [destroy .m1] [destroy .m2 .m3]
} -returnCodes ok -result {{} {}}
test menu-7.6 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [destroy .m2] [destroy .m1 .m3]
} -returnCodes ok -result {{} {}}
test menu-7.7 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [destroy .m3] [destroy .m1 .m2]
} -returnCodes ok -result {{} {}}
test menu-7.8 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [destroy .m1] [destroy .m2]
} -returnCodes ok -result {{} {}}
test menu-7.9 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    destroy .m1
    destroy .m2
} -returnCodes ok

test menu-8.1 {DestroyMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [.m1 delete 1] [destroy .m1 .m2]
} -result {{} {}}
test menu-8.2 {DestroyMenuEntry} -constraints hasEarthPhoto -setup {
    deleteWindows
    catch {image delete image1a}
} -body {
    image create photo image1a -file $earthPhotoFile
    menu .m1
    .m1 add command -image image1a
    list [.m1 delete 1] [destroy .m1] [image delete image1a]
} -result {{} {} {}}
test menu-8.3 {DestroyMenuEntry} -constraints testImageType -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    list [.m1 delete 1] [destroy .m1]
} -cleanup {
    imageCleanup
    deleteWindows
} -result {{} {}}
test menu-8.4 {DestroyMenuEntry} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -variable foo
    list [.m1 delete 1] [destroy .m1]
} -result {{} {}}
test menu-8.5 {DestroyMenuEntry} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 delete 1] [destroy .m1]
} -result {{} {}}
test menu-8.6 {DestroyMenuEntry} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [.m1 delete 1] [.m1 entrycget 1 -label] [destroy .m1]
} -result {{} two {}}
test menu-8.7 {DestroyMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 clone .m2 tearoff
    list [.m2 delete 1] [destroy .m1]
} -result {{} {}}


# test menu-9 - Can only change when fonts change on system, which cannot
# be done from tcl.

test menu-9.1 {ConfigureMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    list [.m1 configure -postcommand "beep"] [.m1 cget -postcommand]
} -cleanup {
    deleteWindows
} -result {{} beep}
test menu-9.2 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 configure -tearoff 0] [.m1 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-9.3 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    list [.m1 configure -postcommand "beep"] [.m1 cget -postcommand]
} -cleanup {
    deleteWindows
} -result {{} beep}
test menu-9.4 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -fg red
} -cleanup {
    deleteWindows
} -result {}
test menu-9.5 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "two"
    .m1 configure -fg red
} -cleanup {
    deleteWindows
} -result {}
test menu-9.6 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "two"
    .m1 add command -label "three"
    .m1 configure -fg red
} -cleanup {
    deleteWindows
} -result {}
test menu-9.7 {ConfigureMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 tearoff
    list [.m1 configure -fg red] [.m2 cget -fg]
} -cleanup {
    deleteWindows
} -result {{} red}
test menu-9.8 {ConfigureMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 tearoff
    list [.m2 configure -fg red] [.m1 cget -fg]
} -cleanup {
    deleteWindows
} -result {{} red}
test menu-9.9 {ConfigureMenu}  -setup {
    destroy .m1
} -body {
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}


test menu-10.1 {PostProcessEntry: array variable} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    set foo(1) on
    .m1 add checkbutton -variable foo(1) -onvalue on -offvalue off -label "Nonsense"
    set foo(1)
} -cleanup {
    deleteWindows
} -result {on}
test menu-10.2 {PostProcessEntry: array variable} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo(1) -onvalue on -offvalue off -label "Nonsense"
    set foo(1)
} -cleanup {
    deleteWindows
} -result {off}


test menu-11.1 {ConfigureMenuEntry} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo -onvalue on -offvalue off -label "Nonsense"
    list [.m1 entryconfigure 1 -variable bar] [.m1 entrycget 1 -variable]
} -cleanup {
    deleteWindows
} -result {{} bar}
test menu-11.2 {ConfigureMenuEntry} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 entryconfigure 1 -label ""] [.m1 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-11.3 {ConfigureMenuEntry} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command
    list [.m1 entryconfigure 1 -label "test"] [.m1 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.4 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
    list [.m1 entryconfigure 1 -accel "S"] [.m1 entrycget 1 -accel]
} -cleanup {
    deleteWindows
} -result {{} S}
test menu-11.5 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
    list [.m1 entryconfigure 1 -label "test"] [.m1 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.6 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
    .m1 entryconfigure 1 -label "test"
} -cleanup {
    deleteWindows
} -result {}
test menu-11.7 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m2
    menu .m1
    .m1 add cascade
    .m1 entryconfigure 1 -label "test" -menu .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-11.8 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade
    .m1 entryconfigure 1 -label "test" -menu .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-11.9 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m3
    .m1 entryconfigure 1 -label "test" -menu .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-11.10 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade
    .m1 entryconfigure 1 -label "test" -menu .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-11.11 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m2
    .m1 entryconfigure 1 -label "test" -menu .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-11.12 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {



    menu .m1
    menu .m2
    .m2 add cascade -menu .m1
    menu .m3
    .m3 add cascade -menu .m1
    menu .m4
    .m4 add cascade -menu .m1
    menu .m5
    .m5 add cascade
    .m5 entryconfigure 1 -label "test" -menu .m1
} -cleanup {
    deleteWindows
} -result {}
test menu-11.13 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {


    menu .m1
    menu .m2
    .m2 add cascade -menu .m1
    menu .m3
    .m3 add cascade -menu .m1
    menu .m4
    .m4 add cascade -menu .m1
    .m3 entryconfigure 1 -label "test" -menu .m1
} -cleanup {
    deleteWindows
} -result {}
test menu-11.14 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
    list [.m1 entryconfigure 1 -variable "test"] [.m1 entrycget 1 -variable]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.15 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    list [.m1 add checkbutton -label "test"] [.m1 entrycget 1 -variable]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.16 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
} -cleanup {
    deleteWindows
} -result {}
test menu-11.17 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
    list [.m1 entryconfigure 1 -onvalue "test"] [.m1 entrycget 1 -onvalue]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.18 {ConfigureMenuEntry} -constraints testImageType -setup {
    deleteWindows
    imageCleanup
} -body {
    menu .m1
    .m1 add command
    image create test image1
    .m1 entryconfigure 1 -image image1
} -cleanup {
    deleteWindows
    imageCleanup
} -result {}
test menu-11.19 {ConfigureMenuEntry} -constraints {
    testImageType hasEarthPhoto
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    image create photo image2 -file $earthPhotoFile
    menu .m1
    .m1 add command -image image1
    .m1 entryconfigure 1 -image image2
} -cleanup {
    deleteWindows
    imageCleanup
} -result {}
test menu-11.20 {ConfigureMenuEntry} -constraints {
    testImageType hasEarthPhoto
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create photo image1 -file $earthPhotoFile
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1
    .m1 entryconfigure 1 -selectimage image2
} -cleanup {
    deleteWindows
    imageCleanup
} -result {}
test menu-11.21 {ConfigureMenuEntry} -constraints {
    testImageType hasEarthPhoto
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create photo image1 -file $earthPhotoFile
    image create test image2
    image create test image3
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 entryconfigure 1 -selectimage image3
} -cleanup {
    deleteWindows
    imageCleanup
} -result {}


test menu-12.1 {ConfigureMenuCloneEntries} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m2 configure -tearoff 0
    .m1 clone .m3
    .m1 add command -label "test"
    .m1 add command -label "test2"
    .m1 entryconfigure 1 -gork "foo"
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-gork"}
test menu-12.2 {ConfigureMenuCloneEntries} -setup {
    deleteWindows
} -body {


    menu .m1
    .m1 clone .m2
    menu .m3
    .m1 add cascade -menu .m3
    menu .m4
    .m1 entryconfigure 1 -menu .m4
} -cleanup {
    deleteWindows
} -result {}
test menu-12.3 {ConfigureMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 add cascade -label dummy
    .m1 entryconfigure dummy -menu .m3
} -cleanup {
    deleteWindows
} -result {}
test menu-12.4 {ConfigureMenuCloneEntries} -setup {
    deleteWindows
} -body {
     menu .m1
     .m1 add cascade -label File -menu .m1.foo
     menu .m1.foo
     .m1.foo add command -label bar
     .m1 clone .m2
     .m1 entryconfigure File -state disabled
} -cleanup {
    deleteWindows
} -result {}


test menu-13.1 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget active -label
} -cleanup {
    deleteWindows
} -result {test2}
test menu-13.2 {TkGetMenuIndex} -setup {





    deleteWindows

} -body {


    menu .m1
    .m1 add command -label "last"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget last -label
} -cleanup {
    deleteWindows
} -result {test3}
test menu-13.3 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "last"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget end -label
} -cleanup {
    deleteWindows
} -result {test3}
test menu-13.4 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert last command -label "test2"] [.m1 entrycget last -label]
} -cleanup {
    deleteWindows
} -result {{} test2}
test menu-13.5 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert end command -label "test2"] [.m1 entrycget end -label]
} -cleanup {
    deleteWindows
} -result {{} test2}
test menu-13.6 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget none -label
} -cleanup {
    deleteWindows
} -result {}
#test menu-13.7 - Need to add @test here.
test menu-13.7 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 entrycget 1 -label
} -cleanup {
    deleteWindows
} -result {active}
test menu-13.8 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "active"
    .m1 entrycget -1 -label
} -returnCodes error -result {bad menu entry index "-1"}
test menu-13.9 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
    .m1 entrycget 999 -label
} -cleanup {
    deleteWindows
} -result {test2}
test menu-13.10 {TkGetMenuIndex} -setup {
    deleteWindows

} -body {
    menu .m1
    .m1 insert 999 command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
    deleteWindows
} -result {test}
test menu-13.11 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "1test"
    .m1 entrycget 1test -label
} -cleanup {
    deleteWindows
} -result {1test}
test menu-13.12 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2" -command "beep"
    .m1 add command -label "test3"
    .m1 entrycget test2 -command
} -cleanup {
    deleteWindows
} -result {beep}

test menu-14.1 {MenuCmdDeletedProc} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1
} -cleanup {
    deleteWindows
} -returnCodes ok



test menu-14.2 {MenuCmdDeletedProc} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    destroy .m1
} -cleanup {
    deleteWindows
} -returnCodes ok

test menu-15.1 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.2 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test3"
    .m1 insert 2 command -label "test2"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.3 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.4 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {}

test menu-16.1 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert foo command -label "test"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-16.2 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 insert test command -label "foo"
} -cleanup {
    deleteWindows
} -result {}
test menu-16.3 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert -1 command -label "test"
} -returnCodes error -result {bad menu entry index "-1"}
test menu-16.4 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test"
    .m1 insert 0 command -label "test2"
    .m1 entrycget 1 -label
} -cleanup {
    deleteWindows
} -result {test2}
test menu-16.5 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade
} -cleanup {
    deleteWindows
} -result {}
test menu-16.6 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
} -cleanup {
    deleteWindows
} -result {}
test menu-16.7 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}
test menu-16.8 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton
} -cleanup {
    deleteWindows
} -result {}
test menu-16.9 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
    deleteWindows
} -result {}
test menu-16.10 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add blork
} -returnCodes error -result {bad menu entry type "blork": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-16.11 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}
test menu-16.12 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m2 add command -label "test"] [.m1 entrycget 1 -label] [.m3 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test test}
test menu-16.13 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m3 add command -label "test"] [.m1 entrycget 1 -label] [.m2 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test test}
test menu-16.14 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -blork
} -returnCodes error -result {unknown option "-blork"}
test menu-16.15 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "File"
    menu .container
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.16 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    set tearoff [tk::TearOffMenu .m2]
    list [.m2 add cascade -menu .m1] [$tearoff unpost]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.17 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    . configure -menu .container
    set tearoff [tk::TearOffMenu .container]
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.18 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    .container add cascade -menu .m1
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.19 {MenuAddOrInsert - Insert a cascade deep into the tree} -setup {
    deleteWindows
} -body {
    menu .menubar
    menu .menubar.test -tearoff 0
    .menubar add cascade -label Test -underline 0 -menu .menubar.test
    menu .menubar.test.cascade -tearoff 0
    .menubar.test.cascade add command -label SubItem -command "puts SubItemSelected"
    . configure -menu .menubar
    list [catch {.menubar.test add cascade -label SubMenu \
		-menu .menubar.test.cascade}] \
		[info commands .\#menubar.\#menubar\#test.\#menubar\#test\#cascade] \
		[. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {0 .#menubar.#menubar#test.#menubar#test#cascade {}}


test menu-17.1 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[unset foo]
} -cleanup {
    deleteWindows
} -result {{} {}}
# menu-17.2 - Don't know how to generate the flags in the if
test menu-17.2 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-17.3 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} hello {}}
test menu-17.4 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "goodbye"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} hello {}}
test menu-17.5 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "goodbye"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} goodbye {}}
test menu-17.6 {MenuVarProc [5d991b822e]} -setup {
    deleteWindows
} -body {
    # Want this not to crash
    menu .b
    set var INIT
    .b add checkbutton -variable var
    trace add variable var unset {apply {args {
        .b entryconfigure 1 -variable {}
    }}}
    unset var
} -cleanup {
    deleteWindows
} -result {}
test menu-17.7 {MenuVarProc [5d991b822e]} -setup {
    deleteWindows
} -body {
    # Want this not to duplicate traces
    menu .b
    set var INIT
    .b add checkbutton -variable var
    trace add variable var unset {apply {args {
        .b entryconfigure 1 -variable new
    }}}
    unset var
} -cleanup {
    deleteWindows
} -result {}


test menu-18.1 {TkActivateMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate 1
} -cleanup {
    deleteWindows
} -result {}
test menu-18.2 {TkActivateMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"

    .m1 activate 0
} -cleanup {
    deleteWindows
} -result {}
test menu-18.3 {TkActivateMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
    .m1 activate 1
    .m1 activate 2
} -cleanup {
    deleteWindows
} -result {}
test menu-18.4 {TkActivateMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
    .m1 activate 1
    .m1 activate 1
} -cleanup {
    deleteWindows
} -result {}


test menu-19.1 {TkPostCommand} -constraints nonUnixUserInteraction -setup {
    deleteWindows
} -body {
    menu .m1 -postcommand "set menu_test menu-19.1"
    .m1 add command -label "menu-19.1 - hit Escape"
    list [.m1 post 40 40] [.m1 unpost] [set menu_test]



} -cleanup {



    deleteWindows
} -result {menu-19.1 {} menu-19.1}
test menu-19.2 {TkPostCommand} -constraints nonUnixUserInteraction -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "menu-19.2 - hit Escape"
    list [.m1 post 40 40] [.m1 unpost]
} -cleanup {
    deleteWindows
} -result {{} {}}

test menu-20.1 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2]
} -cleanup {
    deleteWindows
} -result {}
test menu-20.2 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 normal
    deleteWindows
} -result {}
test menu-20.3 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 tearoff
} -cleanup {
    deleteWindows
} -result {}
test menu-20.4 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 menubar
} -cleanup {
    deleteWindows
} -result {}
test menu-20.5 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 foo
} -returnCodes error -result {bad menu type "foo": must be normal, tearoff, or menubar}
test menu-20.6 {CloneMenu - hooking up bookeeping ptrs} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
} -cleanup {
    deleteWindows
} -result {}
test menu-20.7 {CloneMenu - hooking up bookeeping ptrs - multiple children} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 clone .m2
    .m1 clone .m3
} -cleanup {
    deleteWindows
} -result {}
test menu-20.8 {CloneMenu - cascade entries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m2
    .m1 clone .foo
} -cleanup {
    deleteWindows
} -result {}
test menu-20.9 {CloneMenu - cascades entries} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    .m1 clone .foo
} -cleanup {
    deleteWindows
} -result {}
test menu-20.10 {CloneMenu - tearoff fields} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 1
    list [.m1 clone .m2 normal] [.m2 cget -tearoff]
} -cleanup {
    deleteWindows
} -result {{} 1}
test menu-20.11 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 clone .m2
} -returnCodes error -result {window name "m2" already exists in parent}

test menu-21.1 {MenuDoYPosition} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 yposition glorp
} -returnCodes error -result {bad menu entry index "glorp"}
test menu-21.2 {MenuDoYPosition} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "Test"
    .m1 yposition 1
} -cleanup {
    deleteWindows
} -returnCodes ok -match glob -result {*}

test menu-22.1 {GetIndexFromCoords} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    .m1 index @5
} -cleanup {
    deleteWindows
} -result 0
test menu-22.2 {GetIndexFromCoords} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    .m1 index @5,5
} -cleanup {
    deleteWindows
} -result 0
test menu-22.3 {GetIndexFromCoords: mapped window, y only} -setup {
    deleteWindows
} -constraints {x11} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    .m1 index @5
} -cleanup {
    deleteWindows
} -result 0
test menu-22.4 {GetIndexFromCoords: mapped window x,y} -setup {
    deleteWindows
} -constraints {x11} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    .m1 index @$x,5
} -cleanup {
    deleteWindows
} -result 0
test menu-22.5 {GetIndexFromCoords: mapped wide window} -setup {
    deleteWindows
} -constraints {x11} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    wm geometry .m1 200x100
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    .m1 index @$x,5
} -cleanup {
    deleteWindows
} -result 0

test menu-23.1 {RecursivelyDeleteMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    . configure -menu .m1
    . configure -menu ""
} -cleanup {
    deleteWindows
} -result {}
test menu-23.2 {RecursivelyDeleteMenu} -setup {
    deleteWindows
} -body {
    menu .m2
    .m2 add command -label "test2"
    menu .m1
    .m1 add cascade -label "test1" -menu .m2
    . configure -menu .m1
    . configure -menu ""
} -cleanup {
    deleteWindows
} -result {}

test menu-24.1 {TkNewMenuName} -setup {
    deleteWindows
} -body {
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-24.2 {TkNewMenuName} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m1\#0
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-24.3 {TkNewMenuName} -setup {
    deleteWindows
} -body {
    menu .#m
    rename .#m hideme
    list [catch {. configure -menu [menu .m]}] [. configure -menu ""] [destroy .#m] \
		[destroy .m] [destroy hideme]
} -result {0 {} {} {} {}}


test menu-25.1 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.2 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.3 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    destroy .m1
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.4 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    menu .m2
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.5 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {

    . configure -menu ""
    menu .m1
    . configure -menu .m1
    .m1 clone .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.6 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {

    . configure -menu ""
    menu .m1
    .m1 clone .m2
    . configure -menu .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.7 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    .t2 configure -menu .m1
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.8 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {

    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1







    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {


    deleteWindows




} -result {{} {}}
test menu-25.9 {TkSetWindowMenuBar} -setup {














    deleteWindows
} -body {



    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t3 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.10 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.11 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.12 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.13 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.14 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.15 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.16 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    list [toplevel .t2 -menu m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {.t2 {}}


test menu-26.1 {DestroyMenuHashTable} -setup {
    catch {interp delete testinterp}
    deleteWindows
} -body {
    interp create testinterp
    load {} Tk testinterp
    interp eval testinterp {menu .m1}
    interp delete testinterp
} -returnCodes ok -result {}


test menu-27.1 {GetMenuHashTable} -setup {
    catch {interp delete testinterp}
    deleteWindows
} -body {
    interp create testinterp
    load {} Tk testinterp
    list [catch {interp eval testinterp {menu .m1}} msg] $msg [interp delete testinterp]
} -cleanup {
    deleteWindows
} -result {0 .m1 {}}


test menu-28.1 {TkCreateMenuReferences - not there before} -setup {
    deleteWindows
} -body {
    menu .m1
} -cleanup {
    deleteWindows
} -result {.m1}
test menu-28.2 {TkCreateMenuReferences - there already} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
} -cleanup {
    deleteWindows
} -result {.m2}


test menu-29.1 {TkFindMenuReferences - not there} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    .m1 add cascade -menu .m2
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}


test menu-30.1 {TkFindMenuReferences - there already} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}


test menu-31.1 {TkFreeMenuReferences - menuPtr} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1


} -cleanup {
    deleteWindows
} -result {}





test menu-31.2 {TkFreeMenuReferences - cascadePtr} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    .m1 add cascade -menu .m2
    .m1 entryconfigure 1 -menu .m3
} -cleanup {
    deleteWindows
} -result {}
test menu-31.3 {TkFreeMenuReferences - topLevelListPtr} -setup {
    deleteWindows
} -body {
    . configure -menu .m1
    . configure -menu ""
} -cleanup {
    deleteWindows
} -returnCodes ok -result {}
test menu-31.4 {TkFreeMenuReferences - not empty} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -menu .m3
    menu .m2
    .m2 add cascade -menu .m3
    .m2 entryconfigure 1 -menu ".foo"
} -cleanup {
    deleteWindows
} -result {}


test menu-32.1 {DeleteMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label foo
    .m1 clone .m2
    .m1 delete 1
} -cleanup {
    deleteWindows
} -result {}
test menu-32.2 {DeleteMenuCloneEntries} -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    .m1 delete 2 3
} -cleanup {
    deleteWindows
} -result {}
test menu-32.3 {DeleteMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    .m2 configure -tearoff 1
    .m1 delete 1 2
} -cleanup {
    deleteWindows
} -result {}
test menu-32.4 {DeleteMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    .m2 configure -tearoff 0
    .m1 delete 2 3
} -cleanup {
    deleteWindows
} -result {}
test menu-32.5 {DeleteMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 clone .m2
    .m1 activate one
    .m1 delete one
} -cleanup {
    deleteWindows
} -result {}
test menu-32.6 {DeleteMenuCloneEntries - reentrancy - crashes tk8.0} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test \
		-command ".m1 delete test ; .m1 add command -label test -command \".m1 delete test\"; .m1 delete test"
    .m1 invoke test
} -cleanup {
    deleteWindows
} -result {}
test menu-32.7 {DeleteMenuCloneEntries - one entry} -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    .m1 delete Hello
} -cleanup {
    deleteWindows
} -result {}
test menu-32.8 {Ensure all menu clone commands are deleted} -setup {
    deleteWindows
} -body {
    # SF bug #465324


    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar.test add command -label "hi"
    for {set i 0} {$i < 10} {incr i} {
		.menubar add cascade -menu .menubar.test -label "Test"
		.menubar delete Test
    }

    info commands .#menubar*test*
} -cleanup {
    deleteWindows
} -result {}
test menu-32.9 {Ensure deleting of clones doesn't corrupt menu refs} -setup {
    set res {}
    deleteWindows
} -body {
    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar add cascade -menu .menubar.test -label "Test"
    menu .menubar.cascade

    .menubar.test add cascade -menu .menubar.cascade -label "Cascade"

    lappend res [.menubar.test entrycget 1 -menu]
    lappend res [.#menubar.#menubar#test entrycget 1 -menu]
    destroy .menubar.test
    menu .menubar.test
    .menubar.test add cascade -menu .menubar.cascade -label "Cascade"
    lappend res [.menubar.test entrycget 1 -menu]
    lappend res [.#menubar.#menubar#test entrycget 1 -menu]
    return $res
} -cleanup {
    deleteWindows
} -result {.menubar.cascade .#menubar.#menubar#test.#menubar#cascade .menubar.cascade .#menubar.#menubar#test.#menubar#cascade}




test menu-33.1 {menu vs command hiding} -setup {
    deleteWindows
} -body {
	set l [interp hidden]
    menu .m
    interp hide {} .m
    destroy .m
    set result [list [winfo children .] [interp hidden]]
	expr {$result eq [list {} $l]}
} -result 1

# menu-34 MenuInit only called at boot time

# creating menus on two different screens then deleting the
# menu from the first screen crashes Tk8.3.1
#
test menu-34.1 {menus on multiple screens - crashes tk8.3.1, Bug 5454} -constraints {
	altDisplay
} -setup {
    deleteWindows
} -body {
    toplevel .one
    menu .one.m
    toplevel .two -screen $::env(TK_ALT_DISPLAY)
    menu .two.m
    destroy .one
    destroy .two
} -result {}

test menu-35.1 {menu -underline string overruns Bug 1599877} -setup {
   destroy .m
} -body {
    # ensure that -underline does not do string overruns [Bug 1599877]

    menu .m
    .m add command -label "File" -underline [expr {1<<30}]
    . configure -menu .m
    update
    tk::TraverseToMenu . "e"
} -cleanup {
    deleteWindows
} -result {}

test menu-37.1 {menubar menues cannot be posted - bug 2160206} -setup {
    catch {destroy .m}
} -body {
    # On Linux the following used to panic
    # It now returns an error (on all platforms)

    menu .m -type menubar
    list [catch ".m post 1 1" msg] $msg
} -cleanup {
    destroy .m
} -result {1 {a menubar menu cannot be posted}}

test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup {
} -constraints {userInteraction} -body {
    toplevel .top
    ttk::menubutton .top.mb -text "Some menu";
    menu .top.mb.m;
    .top.mb.m add command -label "Item 1";
    .top.mb.m add command -label "Item 2";
    .top.mb configure -menu .top.mb.m;
    pack .top.mb
    update
    # simulate mouse click on the menubutton, which posts its menu
    event generate .top.mb <Button-1> -warp 1
    update
    after 50
    event generate .top.mb <ButtonRelease-1>
    update
    # simulate mouse click on the menu again, i.e. without
    # entering/leaving the posted menu
    event generate .top.mb <Button-1>
    update
    after 50
    event generate .top.mb <ButtonRelease-1>
    update
    # the menu shall have been unposted by the second click
    winfo ismapped .top.mb.m
} -cleanup {
    destroy .top.mb.m .top.m .top
} -result 0


# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:



|
|



<


<

|



|
|
|
|
|
|
|
<
|
|
|
|
|
<
<
|
|
|
<


|
<
<
|
|
|
|


|
<
<
|
|
|
|
>




|
<
<
|
|
|
|
>
>






|
<
<
|
|
|
|
>
>






|
<
<
|
|
|
|
>
>






|
<
<
|
|
|
|
>
>
>








|
<
<
|
|
|
|


|
<
<
|
|
|
|
>




|
<
<
|
|
|
|
>
>






|
<
<
|

<
|

|
|
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
>
|
<
<
<
<
>
>
|
|
>
>
|
>
|
|
|
|
|
|
|
<
<
<
|
|
|
<
|
|
|
|
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
>




|


|
|

|





<




<
<
<
|
<
|
<
|
<
<
|
<
<
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
|
|
|
<
<
<
<
|
<
<
<
<
|
<
|
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
|
<
<
<
|
<
<
<
<
|
<
|
<
|
<
<
<
|
|
<
<
<
|
|
<
<
<
<
|
<
<
<
<
|
<
|
<
|
|
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
<
<
<
|
|
|
|
>
|
<
<
<
>
|
>
>
|
<
|
|
<
<
<
|
<
<
<
|
<
<
|
|
<
|
|
|
<
|
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
|
|
>
|
<
<
<
>
|
>
>
|
<
|
|
<
<
<
>
|
<
|
<
|
|
<
>
>
|
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
|
|
<
<
<
|
<
<
>
|
>
>
|
<
<
<
|
|
<
<
<
|
|
<
<
|
|
<
<
<
<
|
<
<
<
<
|
<
|
|
|
<
<
<
<
|
|
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
<
<
|
<
<
>
>
|
|
<
<
<
<
|
<
<
<
<
|
<
<
>
|
|
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
>
|
<
<
<
|
<
<
>
|
|
<
<
>
<
<
|
<
<
<
|
|
<
<
<
|
<
<
<
|
|
<
<
|
<
|
|
<
|
|
<
<
|
|
<
<
<
>
|
<
<
>
>
>
|
|
<
<
<
|
<
<
<
|
<
<
|
|
|
|
|
<
<
<
<
<
<
|
<
<
>
|
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
|
|
|
<
<
<
|
<
<
<
<
<
>
|
<
<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
|
<
|
|
<
<
|
|
|
|
|
<
<
<
|
<
<
<
|
>
>
|
<
|
|
|
<
<
<
<
<
|
<
<
<
<
<
<
>
|
<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
|
|
<
<
|
|
<
<
<
|
<
<
<
<
|
>
>
|
<
<
<
|
|
<
|
|
<
<
<
<
|
<
<
<
<
|
|
<
|
|
|
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
|
|
<
|
|
<
<
|
|
<
<
<
>
|
<
<
<
>
|
<
<
>
>
|
|
<
<
<
>
|
<
|
>
|
|
<
|
<
<
|
<
<
|
|
<
<
<
>
|
<
|
<
|
|
<
|
|
<
<
|
|
<
<
<
<
|
<
<
<
|
|
<
<
|
>
>
|
<
|
|
<
<
<
|
>
|
<
>
>
|
>
>
|
<
<
<
|
|
<
<
<
|
|
<
|
<
|
|
<
>
|
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<

<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
|
|
>
|
|
<
|
|
|
<
|
|
>
|
|
|
>
|
|
|
<
|
>
|
|
<
|
|
|
|
|
|
|
<
|
<
|
<
<
<
|
<
<
|
<
<
<
<
|
|
|
<
|
|
|
<
|
|
<
<
<
<
|
<
|
<
|
<
<
<
<
|
|
<
<
<
|
<
|
<
|
<
<
<
|
|
<
<
|
<
|
<
|
<
<
<
|
|
<
<
|
<
<
<
<
|
|
|
|
|
<

<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
|
<

<
|
<
|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<

<
<
<
<
|
<
>
|
|
<

<
<
<
|
<
>
|
|
<

<
<
|
<
>
|
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|
<

|
|
<
<
|
|
<

|
|
|
|
<

|
<
<
|
|
|
<


|
<
<
|
|
|
<

|
|
|
|
<

|
|
|
|
<
|
|
|
|
|
<

|
<
<
|
|
|
<


|
<
<
|
|
|
<




|
<
<
|
|
|
<





|
<
<
|
|
|
<





|
<
<
|











|
|
<

|
|
|
|
<

|
|
|
|
<

|
|
|
|
<


|
<
<
|
|
|
<

|
|
|
|
<

|
|
|
|
<


|
|
<
<
|
|
<


|
<
<
|
|
|
<



|
<
<
|
|
|
<

|
|
|
|
<

|
|
|
|
<
|






|
<
<
|
|
|
<

|
|
|
|
<


|
<
<
|
|
|
<

<
<
|
|
|
|
<

|
<
<
|
|
|
<



<
<
|
|
|
|
<


<
<
|
|
|
|
<

|
<
<
|
|
|
<

|
<
<
|
|
<
<
|
<

|
|
<
<
|
|
|
<

|
<
<
|
|
|
<

|
<
<
|
|
<
<
|
|

|



|
<
<
|
|
|
|




|
<
<
|
|
|
<

<
<
|
|
|
|
<

|
<
<
|
|
|
<


<
<
|
|
|
|
<


<
<
|
|
|
|
<


<
<
|
|
|
|
<


<
<
|
|
|
|
<


<
<
|
|
|
|
<
|
<
<
|
|
|
|
<

|
<
<
|
|
<
<
|
<

|

<
<
|
|
|
|
<

|
<
<
|
|
|
<
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<

<
<
|
|
|
<
<














|
|
|
|

|







|







<
<
<
<
<
<
<
<

<
|
|
<




|
<
<
|
|
|
<

|
<
<
|
|
|
<



|
<
<
<
|
|
|
<




|
<
<
|
|
|
<



|
<
<
|
|
|
<

|



|
<
<
|
|
|
<

|



|
<
<
|
|
|
<





|
<
<
|
|
|
<





|
<
<
|
|
|
<
|


|
<
<
|
|
|
<


|
<
<
|
|
|
>
>
>
>
<
<
<
<
<
<
<

|
|
<

|
|
|
|
|



|
|
|
|
|
>





|
|
|
|
|
>
>







|
|
|
|
|




|
|
|
|
|
>







|
|
|
|
<


|
|
|
|
<



|
|
|
|
<


|
|
|
|
<


|
|
|
|
<


|
|
|
|
<

|
|
|
|
|





|

<
|
|
<

|
|
|
|
|




|
|
|
|
|
>




|
|
|
|
|



|
|
<
<
|
|
|




|
|
|
|


|
|
|
|
|



|
|
|
|
|
>





|
|
|
|
>



|
|
|
|
|
>



|
|
|
|
|
>
>




|
|
|
|
|
>
>




|
|
|
|
|
>
>




|
|
|
|
<


|
|
|
|
|





|
|
|
|
|
>








|
|

|
<
|


|
|
|
|
<


|
|
|
|
|




|
|
|
|
|




|
|
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>






|
|
|
<
<
|
|
<
<
<
<
|
<
<
<
<






|
|
|
|
|



|
|
|
|
|




|
|

|
|
|



|
|
|
<

|



|
|
|
|
<
|





|
<
<
<
|
|
|
<


|
|
|
|
<


|
|
|
|
<
|


|
|
|
|
|



|
|
<



>
|
|
<

|
<
<
|
|
|
<


|
<
<
|
|
|
<

|
<
<
|
|
|
<


|
<
<
|
|
|
<



|
<
<
|
|
|
<




|
<
<
|
|
|
|


|
<
<
|
|
|
|


|
<
<
|
|
|
<

|
<
<
<
|

|
|
<




|
|
<
<
|
|
<



|
<
<
<
|

|
|
<



|
<
<
|
|
|
<


|
<
<
|
|
|
<


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
|
|



|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
|
|
>
>
>









|
<
<
|
|
|
|
>
>







|
<
<
|
|
<
|


|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|


|
<
<
|
|
|
|
<



|
<
<
<
|
|
<
|
|
|
<




|
<
<
<
|
|
<
|
|
|
<




|
<
<
<
|
|
<
|
|
|
|





|
<
<
<
<
|

|
|
|
>






|
<
<
|
|
|
|
>
>





|
<
<
|
|
|
|



|
|
|
<
|
|
|





|
<
<
<
|

|
<
|
|




|
<
<
|
|
>
>
>
>
>
|
>
|
>
>





<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|





|
<
<
|

|
<
|
|



|
<
<
|
|
<
|


|
|
|
<
|



|
<
<
<
<
|
>
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|




|
<
<
<
|
<
<
<
<
<
|
|
|
>
>
>
|
<
|


|
|
<
<

|
<
|

|
<
<
|
|
<
|



|
<
<
|
|
<
|


|
<
<
|
|
<
|

|
<
<
|

|
<
|

|
|
|
<
|


|
<
<
|
|
<
|

|
|
|
<
|
|


|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
|
|
<
|

|
<
<
|
|
|
|
>



|
<
<
|
|
|
|
>



|
<
<
|
|
<
|

|
|
|
|
|




|
<
<
|
|
|
|



|
<
<
|
|
|
|




|
<
<
|
|
|
|




|
<
<
|
|
<
|







|
|
|
<
<
|

<
|
<
|



|
<
<
<
|

|
<
|


|
<
<
<
|
|
<
|



|
<
<
<
|
|
<
|


|
<
<
<
|
|
<
|


|
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
<
|
<
|
<
<
<
<
<
<
<
|
|
|
<
|


|
<
<
|
|
<
|


>
<
<
<
<
<
<
<
<
<
<

|
<
<
|
|
<
|




|
<
<
<
|

|
<
|


|
>
>
>
|
>
>
>
<
<
<
<
<
<
<
<
<
<
<

|
|
|

|
<
<
|
|
|
|

|
<
|
|
|
|

|
<
<
|
|
|
|

|
<
<
|
|
|
|

|
|
|
|
|

|
<
<
|
|
|
|
>


|
<
<
|
|
|
|


|
<
<
|
|
|
|
>



|
<
<
|
|
|
|
|
|
|
<
<
|
|
|


|
|

|
<
|

|
|
|
<
|


|
|
<
<

|
<
|



|
<
<
|
|
<
|



|
<
<
|
|
<
|





|
<
<
|
|
<
|







|
<
<
|
|
<
|








|
<
<
|

|
<
|


|
<
<
|
|
|
|





|
<
<
|

|
<
|

|
<
<
|
|
|
|


|
<
<
|
|
<
|


|
<
|

<
|
<
<

|
<
<
|
|
<
<

|
<
<
|
|
<
<

|

|
<
<
|
|
|
|




|
<
<
|
|
|
|
>





|
<
<
|
|
|
|
>





|
<
<
|
|
|
|






|
<
<
|
|
|
|
>







>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>








<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|


|
<
<
|
|
<
<

|
<
<
|
|
<
|


|
<
<
|
|
<
<

|
<
<
|
|
<
|



|
<
<
|

<
|
|
<
<



|
<
|

|
|
<
<



<
<
|

<
|
<
|
|
<
<
|
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<


|
<
<
|

<
|
<
|


<

|
<
<
|
|
|
<
|
|

|
>
>
|
<
|
>
>
>
>
>
|
<
|



|
<
<
|
|
<
<

|
|
<
<
|
|
|




|
<
<
<
|

|
|
|



|
<
<
|
|
<
|
|






|
<
<
|
|
|
|







|
<
<
|
|
|
|







|
<
<
|
|
|
|





|
<
<
|
|
<
|

<
|
|
<
<
|
|
<
|


|
<
<
|
|
<
<

>
>





|
|



|
<
<
|
|
|
|







>







|
<
<
|

>
>

|
<
|
<



|
|
<






|
|
<
<
<






|

|
<
<

>





|
<
<

|
<
<


>


<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<

<



<
<
<
<
1
2
3
4
5
6
7
8

9
10

11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27


28
29
30

31
32
33


34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49
50


51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112


113
114
115
116
117
118
119
120
121
122


123
124
125
126
127
128
129
130
131
132
133
134
135


136
137

138
139
140
141
142



143


144







145




146










147




148







149







150







151


152












153


154

155

156
157




158
159
160
161
162
163
164
165
166
167
168
169
170
171
172



173
174
175

176
177
178
179
180





181

182








183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203



204

205

206


207





208
209




210






211
212



213



214



215



216



217
218



219




220





221
222
223
224




225




226

227
228



229



230



231



232



233
234



235




236

237

238



239
240



241
242




243




244

245

246
247




248




249

250


251




252
253
254
255
256
257



258
259
260
261
262

263
264



265



266


267
268

269
270
271

272


273




274



275



276
277
278
279



280
281
282
283
284

285
286



287
288

289

290
291

292
293
294
295



296



297



298




299
300



301


302
303
304
305
306



307
308



309
310


311
312




313




314

315
316
317




318
319



320


321
322




323




324


325
326
327
328




329




330


331
332
333



334






335
336



337
338



339


340
341
342


343


344



345
346



347



348
349


350

351
352

353
354


355
356



357
358


359
360
361
362
363



364



365


366
367
368
369
370






371


372
373









374
375
376
377
378

379
380
381



382





383
384




385





386



387

388

389
390


391
392
393
394
395



396



397
398
399
400

401
402
403





404






405
406



407




408




409


410
411


412
413


414
415



416




417
418
419
420



421
422

423
424




425




426
427

428
429
430



431




432



433



434




435
436

437
438


439
440



441
442



443
444


445
446
447
448



449
450

451
452
453
454

455


456


457
458



459
460

461

462
463

464
465


466
467




468



469
470


471
472
473
474

475
476



477
478
479

480
481
482
483
484
485



486
487



488
489

490

491
492

493
494
495
496
497


















498

499





500





501












502



503










504



505



506



507



508



509



510



511



512



513



514










































515
516
517
518
519
520
521
522

523
524
525

526
527
528
529
530
531
532
533
534
535

536
537
538
539

540
541
542
543
544
545
546

547

548



549


550




551
552
553

554
555
556

557
558




559

560

561




562
563



564

565

566



567
568


569

570

571



572
573


574




575
576
577
578
579

580


581


582









583
584

585

586

587


588




589







590




591




592

593
594
595

596



597

598
599
600

601


602

603
604
605

606

























































607


608
609
610

611
612
613


614
615

616
617
618
619
620

621
622


623
624
625

626
627
628


629
630
631

632
633
634
635
636

637
638
639
640
641

642
643
644
645
646

647
648


649
650
651

652
653
654


655
656
657

658
659
660
661
662


663
664
665

666
667
668
669
670
671


672
673
674

675
676
677
678
679
680


681
682
683
684
685
686
687
688
689
690
691
692
693
694

695
696
697
698
699

700
701
702
703
704

705
706
707
708
709

710
711
712


713
714
715

716
717
718
719
720

721
722
723
724
725

726
727
728
729


730
731

732
733
734


735
736
737

738
739
740
741


742
743
744

745
746
747
748
749

750
751
752
753
754

755
756
757
758
759
760
761
762


763
764
765

766
767
768
769
770

771
772
773


774
775
776

777


778
779
780
781

782
783


784
785
786

787
788
789


790
791
792
793

794
795


796
797
798
799

800
801


802
803
804

805
806


807
808


809

810
811
812


813
814
815

816
817


818
819
820

821
822


823
824


825
826
827
828
829
830
831
832


833
834
835
836
837
838
839
840
841


842
843
844

845


846
847
848
849

850
851


852
853
854

855
856


857
858
859
860

861
862


863
864
865
866

867
868


869
870
871
872

873
874


875
876
877
878

879
880


881
882
883
884

885


886
887
888
889

890
891


892
893


894

895
896
897


898
899
900
901

902
903


904
905
906

907
908







909



















910
911

912


913
914
915


916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950








951

952
953

954
955
956
957
958


959
960
961

962
963


964
965
966

967
968
969
970



971
972
973

974
975
976
977
978


979
980
981

982
983
984
985


986
987
988

989
990
991
992
993
994


995
996
997

998
999
1000
1001
1002
1003


1004
1005
1006

1007
1008
1009
1010
1011
1012


1013
1014
1015

1016
1017
1018
1019
1020
1021


1022
1023
1024

1025
1026
1027
1028


1029
1030
1031

1032
1033
1034


1035
1036
1037
1038
1039
1040
1041







1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117

1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150

1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180


1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350


1351
1352




1353




1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388

1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404



1405
1406
1407

1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419

1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432

1433
1434
1435
1436
1437
1438

1439
1440


1441
1442
1443

1444
1445
1446


1447
1448
1449

1450
1451


1452
1453
1454

1455
1456
1457


1458
1459
1460

1461
1462
1463
1464


1465
1466
1467

1468
1469
1470
1471
1472


1473
1474
1475
1476
1477
1478
1479


1480
1481
1482
1483
1484
1485
1486


1487
1488
1489

1490
1491



1492
1493
1494
1495

1496
1497
1498
1499
1500
1501


1502
1503

1504
1505
1506
1507



1508
1509
1510
1511

1512
1513
1514
1515


1516
1517
1518

1519
1520
1521


1522
1523
1524

1525
1526
1527


1528
1529

1530
1531
1532
1533


1534
1535

1536
1537
1538
1539


1540
1541

1542
1543
1544
1545


1546
1547
1548
1549
1550
1551
1552
1553


1554
1555

1556
1557
1558
1559


1560
1561

1562
1563
1564
1565


1566
1567

1568
1569
1570
1571


1572
1573

1574
1575
1576
1577


1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594


1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608


1609
1610

1611
1612
1613
1614


1615
1616

1617
1618
1619


1620
1621

1622
1623
1624


1625
1626

1627
1628
1629
1630


1631
1632
1633
1634

1635
1636
1637
1638



1639
1640

1641
1642
1643

1644
1645
1646
1647
1648



1649
1650

1651
1652
1653

1654
1655
1656
1657
1658



1659
1660

1661
1662
1663
1664
1665
1666
1667
1668
1669
1670




1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683


1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695


1696
1697
1698
1699
1700
1701
1702
1703
1704
1705

1706
1707
1708
1709
1710
1711
1712
1713
1714



1715
1716
1717

1718
1719
1720
1721
1722
1723
1724


1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741












1742


1743
1744

1745
1746
1747
1748


1749
1750

1751
1752
1753
1754


1755
1756

1757
1758
1759
1760
1761
1762
1763


1764
1765
1766

1767
1768
1769
1770
1771
1772


1773
1774

1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785




1786
1787
1788
1789
1790
1791


1792
1793

1794
1795
1796
1797


1798
1799

1800
1801
1802
1803
1804
1805



1806





1807
1808
1809
1810
1811
1812
1813

1814
1815
1816
1817
1818


1819
1820

1821
1822
1823


1824
1825

1826
1827
1828
1829
1830


1831
1832

1833
1834
1835
1836


1837
1838

1839
1840
1841


1842
1843
1844

1845
1846
1847
1848
1849

1850
1851
1852
1853


1854
1855

1856
1857
1858
1859
1860

1861
1862
1863
1864
1865


1866
1867

1868
1869
1870


1871
1872

1873
1874
1875


1876
1877

1878
1879
1880


1881
1882

1883
1884
1885


1886
1887

1888
1889
1890


1891
1892

1893
1894
1895
1896
1897

1898
1899
1900


1901
1902
1903
1904
1905
1906
1907
1908
1909


1910
1911
1912
1913
1914
1915
1916
1917
1918


1919
1920

1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932


1933
1934
1935
1936
1937
1938
1939
1940


1941
1942
1943
1944
1945
1946
1947
1948
1949


1950
1951
1952
1953
1954
1955
1956
1957
1958


1959
1960

1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971


1972
1973

1974

1975
1976
1977
1978
1979



1980
1981
1982

1983
1984
1985
1986



1987
1988

1989
1990
1991
1992
1993



1994
1995

1996
1997
1998
1999



2000
2001

2002
2003
2004
2005



2006









2007




2008

2009

2010

2011







2012
2013
2014

2015
2016
2017
2018


2019
2020

2021
2022
2023
2024










2025
2026


2027
2028

2029
2030
2031
2032
2033
2034



2035
2036
2037

2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048











2049
2050
2051
2052
2053
2054


2055
2056
2057
2058
2059
2060

2061
2062
2063
2064
2065
2066


2067
2068
2069
2070
2071
2072


2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084


2085
2086
2087
2088
2089
2090
2091
2092


2093
2094
2095
2096
2097
2098
2099


2100
2101
2102
2103
2104
2105
2106
2107
2108


2109
2110
2111
2112
2113
2114
2115


2116
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128
2129

2130
2131
2132
2133
2134


2135
2136

2137
2138
2139
2140
2141


2142
2143

2144
2145
2146
2147
2148


2149
2150

2151
2152
2153
2154
2155
2156
2157


2158
2159

2160
2161
2162
2163
2164
2165
2166
2167
2168


2169
2170

2171
2172
2173
2174
2175
2176
2177
2178
2179
2180


2181
2182
2183

2184
2185
2186
2187


2188
2189
2190
2191
2192
2193
2194
2195
2196
2197


2198
2199
2200

2201
2202
2203


2204
2205
2206
2207
2208
2209
2210


2211
2212

2213
2214
2215
2216

2217
2218

2219


2220
2221


2222
2223


2224
2225


2226
2227


2228
2229
2230
2231


2232
2233
2234
2235
2236
2237
2238
2239
2240


2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251


2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262


2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273


2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330










2331







2332















2333

2334
2335
2336
2337


2338
2339


2340
2341


2342
2343

2344
2345
2346
2347


2348
2349


2350
2351


2352
2353

2354
2355
2356
2357
2358


2359
2360

2361
2362


2363
2364
2365
2366

2367
2368
2369
2370


2371
2372
2373


2374
2375

2376

2377
2378


2379
2380








2381
2382




2383
2384
2385


2386
2387

2388

2389
2390
2391

2392
2393


2394
2395
2396

2397
2398
2399
2400
2401
2402
2403

2404
2405
2406
2407
2408
2409
2410

2411
2412
2413
2414
2415


2416
2417


2418
2419
2420


2421
2422
2423
2424
2425
2426
2427
2428



2429
2430
2431
2432
2433
2434
2435
2436
2437


2438
2439

2440
2441
2442
2443
2444
2445
2446
2447
2448


2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460


2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472


2473
2474
2475
2476
2477
2478
2479
2480
2481
2482


2483
2484

2485
2486

2487
2488


2489
2490

2491
2492
2493
2494


2495
2496


2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510


2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530


2531
2532
2533
2534
2535
2536

2537

2538
2539
2540
2541
2542

2543
2544
2545
2546
2547
2548
2549
2550



2551
2552
2553
2554
2555
2556
2557
2558
2559


2560
2561
2562
2563
2564
2565
2566
2567


2568
2569


2570
2571
2572
2573
2574


2575
2576




























2577

2578

2579
2580
2581




# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


# find the earth.gif file for use in these tests
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
testConstraint hasEarthPhoto [file exists $earthPhotoFile]

test menu-1.1 {Tk_MenuCmd procedure} {
    list [catch menu msg] $msg
} {1 {wrong # args: should be "menu pathName ?options?"}}
test menu-1.2 {Tk_MenuCmd procedure} {
    list [catch "menu bogus" msg] $msg
} {1 {bad window path name "bogus"}}
test menu-1.3 {Tk_MenuCmd procedure} {

    list [catch "menu .m1 foo" msg] $msg
} {1 {unknown option "foo"}}
test menu-1.4 {Tk_MenuCmd procedure} {
    catch {destroy .m1}
    list [catch {menu .m1} msg] $msg [destroy .m1]


} {0 .m1 {}}
test menu-1.5 {Tk_MenuCmd - creating menubar} {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label Test -menu ""
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]


} {{} {} {}}
test menu-1.6 {Tk_MenuCmd procedure menu ref no cascade} {
    catch {destroy .t2}
    catch {destroy .m1}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [catch {menu .m1} msg] $msg [destroy .m1 .t2]


} {0 .m1 {}}
test menu-1.7 {Tk_MenuCmd procedure one clone cascade} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {menu .m2} msg] $msg [destroy .t2 .m1 .m2]


} {0 .m2 {}}
test menu-1.8 {Tk_MenuCmd procedure two clone cascades} {
    catch {destroy .m1}
    catch {destroy .t2}
    catch {destroy .t3}
    catch {destroy .m2}
    menu .m1
    .m1 add cascade -menu .m2
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [catch {menu .m2} msg] $msg [destroy .t2 .t3 .m1 .m2]


} {0 .m2 {}}
test menu-1.9 {Tk_MenuCmd procedure two clone cascades different order} {
    catch {destroy .t2}
    catch {destroy .m1}
    catch {destroy .t3}
    catch {destroy .m2}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [catch {menu .m2} msg] $msg [destroy .t2 .t3 .m1 .m2]


} {0 .m2 {}}
test menu-1.10 {Tk_MenuCmd procedure two clone cascades menus last} {
    catch {destroy .t2}
    catch {destroy .t3}
    catch {destroy .m1}
    catch {destroy .m2}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {menu .m2} msg] $msg [destroy .t2 .t3 .m1 .m2]


} {0 .m2 {}}
test menu-1.11 {Tk_MenuCmd procedure three clones cascades} {
    catch {destroy .t2}
    catch {destroy .t3}
    catch {destroy .t4}
    catch {destroy .m1}
    catch {destroy .m2}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    toplevel .t4 -menu .m1
    wm geometry .t4 +0+0
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {menu .m2} msg] $msg [destroy .t2 .t3 .t4 .m1 .m2]


} {0 .m2 {}}
test menu-1.12 {Tk_MenuCmd procedure} {
    catch {destroy .t2}
    catch {destroy .m1}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [catch {menu .m1} msg] $msg [destroy .t2 .m1]


} {0 .m1 {}}
test menu-1.13 {Tk_MenuCmd procedure} {
    catch {destroy .t2}
    catch {destroy .t3}
    catch {destroy .m1}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [catch {menu .m1} msg] $msg [destroy .t2 .t3 .m1]


} {0 .m1 {}}
test menu-1.14 {Tk_MenuCmd procedure} {
    catch {destroy .t2}
    catch {destroy .t3}
    catch {destroy .t4}
    catch {destroy .m1}
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    toplevel .t4 -menu .m1
    wm geometry .t4 +0+0
    list [catch {menu .m1} msg] $msg [destroy .t2 .t3 .t4 .m1]


} {0 .m1 {}}


catch {destroy .m1}
menu .m1
set i 1
foreach configTest {
    {-activebackground #012345 #012345 non-existent



	    {unknown color name "non-existent"}}


    {-activeborderwidth 1.3 1.3 badValue {bad screen distance "badValue"}}







    {-activeforeground #ff0000 #ff0000 non-existent




	    {unknown color name "non-existent"}}










    {-background #ff0000 #ff0000 non-existent




	    {unknown color name "non-existent"}}







    {-bg #110022 #110022 bogus {unknown color name "bogus"}}







    {-borderwidth 1.3 1.3 badValue {bad screen distance "badValue"}}







    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}


    {-disabledforeground #00ff00 #00ff00 xyzzy {unknown color name "xyzzy"}}












    {-fg #110022 #110022 bogus {unknown color name "bogus"}}


    {-font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*

	    -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* {}

	    {font "" doesn't exist}}
    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}




    {-postcommand "any old string" "any old string" {} {}}
    {-relief groove groove 1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    {-selectcolor #110022 #110022 bogus {unknown color name "bogus"}}
    {-takefocus "any string" "any string" {} {}}
    {-tearoff 0 0}
    {-tearoff 1 1}
    {-tearoffcommand "any old string" "any old string" {} {}}
} {
    set name [lindex $configTest 0]
    set value [lindex $configTest 1]
    set result [lindex $configTest 2]
    test menu-2.$i [list configuration options $name $value $result] {
	.m1 configure $name $value
	lindex [.m1 configure $name] 4
    } $result



    incr i
    if {[lindex $configTest 3] != ""} {
	set value [lindex $configTest 3]

	set result [lindex $configTest 4]
	test menu-2.$i [list configuration options $name $value $result] {
	    list [catch {.m1 configure $name $value} msg] $msg
	} [list 1 $result]
    }





    .m1 configure $name [lindex [.m1 configure $name] 3]

    incr i








}
destroy .m1

# We need to test all of the options with all of the different types of
# menu entries. The following code sets up .m1 with 6 items. It then
# runs through the big table below it.
# index 0 is tearoff, 1 command, 2 cascade, 3 separator, 4 checkbutton,
# 5 radiobutton

menu .m1
.m1 add command -label "command"
menu .m2
.m2 add command -label "test"
.m1 add cascade -label "cascade" -menu .m2
.m1 add separator
.m1 add checkbutton -label "checkbutton" -variable check -onvalue on -offvalue off
.m1 add radiobutton -label "radiobutton" -variable radio

if {[testConstraint hasEarthPhoto]} {
    image create photo image1 -file $earthPhotoFile
}




foreach configTest {

    {-activebackground

        {{#012345


            {{unknown option "-activebackground"} #012345 #012345





            {unknown option "-activebackground"} #012345 #012345
            }




        }






        {non-existent
            {{unknown option "-activebackground"}



	    {unknown color name "non-existent"}



	    {unknown color name "non-existent"}



	    {unknown option "-activebackground"}



	    {unknown color name "non-existent"}



	    {unknown color name "non-existent"}
	    }



	}}




    }





    {-activeforeground
    	{{#ff0000
	    {{unknown option "-activeforeground"}
	    #ff0000 #ff0000 {unknown option "-activeforeground"} #ff0000 #ff0000




	    }




	}

	{non-existent
	    {{unknown option "-activeforeground"}



	    {unknown color name "non-existent"}



	    {unknown color name "non-existent"}



	    {unknown option "-activeforeground"}



	    {unknown color name "non-existent"}



	    {unknown color name "non-existent"}
	    }



	}}




    }

    {-accelerator

    	{{"Ctrl+S"



	    {{unknown option "-accelerator"}
	    "Ctrl+S" "Ctrl+S" {unknown option "-accelerator"}



	    "Ctrl+S" "Ctrl+S"
	    }




	}}




    }

    {-background

    	{{#ff0000
    	    {#ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000




	    }




	}

	{non-existent


	    {{unknown color name "non-existent"}




	    {unknown color name "non-existent"}
	    {unknown color name "non-existent"}
	    {unknown color name "non-existent"}
	    {unknown color name "non-existent"}
	    {unknown color name "non-existent"}
	    }



	}}
    }
    {-bitmap
    	{{questhead
	    {{unknown option "-bitmap"} questhead questhead

	    {unknown option "-bitmap"} questhead questhead
	    }



	}



	{badValue


	    {{unknown option "-bitmap"}
	    {bitmap "badValue" not defined}

	    {bitmap "badValue" not defined}
	    {unknown option "-bitmap"}
	    {bitmap "badValue" not defined}

	    {bitmap "badValue" not defined}


	    }




	}}



    }



    {-columnbreak
	{{1
	    {{unknown option "-columnbreak"} 1 1
	    {unknown option "-columnbreak"} 1 1}



	}}
    }
    {-command
    	{{beep
	    {{unknown option "-command"} beep beep

	    {unknown option "-command"} beep beep
	    }



	}}
    }

    {-font

    	{{-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
	    {{unknown option "-font"}

    	    -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    	    -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
	    {unknown option "-font"}
    	    -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*



    	    -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*



	    }



	}




	{{kill rock stars}
	    {{unknown option "-font"}



	    {expected integer but got "rock"}


	    {expected integer but got "rock"}
	    {unknown option "-font"}
	    {expected integer but got "rock"}
	    {expected integer but got "rock"}
	    }



	}}
    }



    {-foreground
    	{{#110022


	    {{unknown option "-foreground"} #110022 #110022
	    {unknown option "-foreground"} #110022 #110022




	    }




	}

	{non-existent
	    {{unknown option "-foreground"}
	    {unknown color name "non-existent"}




	    {unknown color name "non-existent"}
	    {unknown option "-foreground"}



	    {unknown color name "non-existent"}


	    {unknown color name "non-existent"}
	    }




	}}




    }


    {-image
    	{{image1
	    {{unknown option "-image"} image1 image1
	    {unknown option "-image"} image1 image1




	    }




	}


	{bogus
	    {{unknown option "-image"}
	    {image "bogus" doesn't exist}



	    {image "bogus" doesn't exist}






	    {unknown option "-image"}
	    {image "bogus" doesn't exist}



	    {image "bogus" doesn't exist}
	    }



	}


	{""
	    {{unknown option "-image"}
	    {}


	    {}


	    {unknown option "-image"}



	    {}
	    {}



	    }



	}}
    }


    {-indicatoron

    	{{1
	    {{unknown option "-indicatoron"}

	    {unknown option "-indicatoron"}
	    {unknown option "-indicatoron"}


	    {unknown option "-indicatoron"} 1 1
	    }



	}}
    }


    {-label
    	{{test
	    {{unknown option "-label"} test test
	    {unknown option "-label"} test test
	    }



	}}



    }


    {-menu
    	{{.m2
	    {{unknown option "-menu"}
	    {unknown option "-menu"} .m2
	    {unknown option "-menu"}






	    {unknown option "-menu"}


	    {unknown option "-menu"}
	    }









	}}
    }
    {-offvalue
    	{{off
	    {{unknown option "-offvalue"}

	    {unknown option "-offvalue"}
	    {unknown option "-offvalue"}
	    {unknown option "-offvalue"}



    	    off





	    {unknown option "-offvalue"}
	    }




	}}





    }



    {-onvalue

    	{{on

	    {{unknown option "-onvalue"}
	    {unknown option "-onvalue"}


	    {unknown option "-onvalue"}
	    {unknown option "-onvalue"}
    	    on
	    {unknown option "-onvalue"}
	    }



	}}



    }
    {-selectcolor
    	{{#110022
	    {{unknown option "-selectcolor"}

	    {unknown option "-selectcolor"}
	    {unknown option "-selectcolor"}
	    {unknown option "-selectcolor"}





    	    #110022






    	    #110022
	    }



	}




	{non-existent




	    {{unknown option "-selectcolor"}


	    {unknown option "-selectcolor"}
	    {unknown option "-selectcolor"}


	    {unknown option "-selectcolor"}
	    {unknown color name "non-existent"}


	    {unknown color name "non-existent"}
	    }



	}}




    }
    {-selectimage
    	{{image1
    	    {{unknown option "-selectimage"}



    	    {unknown option "-selectimage"}
    	    {unknown option "-selectimage"}

    	    {unknown option "-selectimage"} image1 image1
	    }




	}




	{bogus
	    {{unknown option "-selectimage"}

	    {unknown option "-selectimage"}
	    {unknown option "-selectimage"}
	    {unknown option "-selectimage"}



	    {image "bogus" doesn't exist}




	    {image "bogus" doesn't exist}



	    }



	}




	{""
	    {{unknown option "-selectimage"}

	    {unknown option "-selectimage"}
	    {unknown option "-selectimage"}


	    {unknown option "-selectimage"}
	    {}



	    {}
	    }



	}}
    }


    {-state
    	{{normal
    	    {normal normal normal {unknown option "-state"} normal normal
	    }



	}}
    }

    {-value
    	{{"any string"
    	    {{unknown option "-value"}
    	    {unknown option "-value"}

    	    {unknown option "-value"}


    	    {unknown option "-value"}


    	    {unknown option "-value"} "any string"
	    }



	}}
    }

    {-variable

    	{{"any string"
    	    {{unknown option "-variable"}

    	    {unknown option "-variable"}
    	    {unknown option "-variable"}


    	    {unknown option "-variable"}
    	    "any string"




    	    "any string"



	    }
	}}


    }
    {-underline
    	{{0
    	    {{unknown option "-underline"} 0 0

    	    {unknown option "-underline"} 0 0
	    }



	}
	{3p
	    {{unknown option "-underline"}

	    {expected integer but got "3p"}
	    {expected integer but got "3p"}
	    {unknown option "-underline"}
	    {expected integer but got "3p"}
	    {expected integer but got "3p"}
	    }



	}}
    }



} {
    set name [lindex $configTest 0]

    foreach attempt [lindex $configTest 1] {

    	set value [lindex $attempt 0]
    	set options [lindex $attempt 1]

    	foreach item {0 1 2 3 4 5} {
    	    catch {unset msg}
	    # OK, it's an overeager constraint, but it should also
	    # normally hold anyway
    	    test menu-2.$i [list entry configuration options $name $item $value [.m1 type $item]] hasEarthPhoto {


















            	set result [catch {.m1 entryconfigure $item $name $value} msg]

                if {$result == 1} {





            	    set msg





            	} else {












            	    lindex [.m1 entryconfigure $item $name] 4



            	}










    	    } [lindex $options $item]



    	    incr i



    	}



    }



}







if {[testConstraint hasEarthPhoto]} {



    image delete image1



}



destroy .m1



destroy .m2











































test menu-3.1 {MenuWidgetCmd procedure} {
    catch {destroy .m1}
    menu .m1
    list [catch {.m1} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 option ?arg arg ...?"} {}}
test menu-3.2 {MenuWidgetCmd, Tcl_Preserve and Tcl_Release} {nonUnixUserInteraction } {
    catch {destroy .m1}

    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "menu-3.2: Hit Escape"
    list [catch {.m1 post 40 40} msg] $msg

} {0 {}}
test menu-3.3 {MenuWidgetCmd procedure, "activate" option} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 activate} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 activate index"} {}}
test menu-3.4 {MenuWidgetCmd procedure, "activate" option} {
    catch {destroy .m1}
    menu .m1

    list [catch {.m1 activate "foo"} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.5 {MenuWidgetCmd procedure, "activate" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    .m1 add separator
    list [catch {.m1 activate 2} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-3.6 {MenuWidgetCmd procedure, "activate" option} {
    catch {destroy .m1}

    menu .m1

    .m1 add command -label "test"



    .m1 entryconfigure 1 -state disabled


    list [catch {.m1 activate 1} msg] $msg [destroy .m1]




} {0 {} {}}
test menu-3.7 {MenuWidgetCmd procedure, "activate" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 activate 1} msg] $msg [destroy .m1]

} {0 {} {}}
test menu-3.8 {MenuWidgetCmd procedure, "add" option} {




    catch {destroy .m1}

    menu .m1

    list [catch {.m1 add} msg] $msg [destroy .m1]




} {1 {wrong # args: should be ".m1 add type ?options?"} {}}
test menu-3.9 {MenuWidgetCmd procedure, "add" option} {



    catch {destroy .m1}

    menu .m1

    list [catch {.m1 add foo} msg] $msg [destroy .m1]



} {1 {bad menu entry type "foo": must be cascade, checkbutton, command, radiobutton, or separator} {}}
test menu-3.10 {MenuWidgetCmd procedure, "add" option} {


    catch {destroy .m1}

    menu .m1

    list [catch {.m1 add separator} msg] $msg [destroy .m1]



} {0 {} {}}
test menu-3.11 {MenuWidgetCmd procedure, "cget" option} {


    catch {destroy .m1}




    menu .m1
    list [catch {.m1 cget} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 cget option"} {}}
test menu-3.12 {MenuWidgetCmd procedure, "cget" option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 cget -gorp} msg] $msg [destroy .m1]


} {1 {unknown option "-gorp"} {}}









test menu-3.13 {MenuWidgetCmd procedure, "cget" option} {
    catch {destroy .m1}

    menu .m1

    .m1 configure -postcommand "Some string"

    list [catch {.m1 cget -postcommand} msg] $msg [destroy .m1]


} {0 {Some string} {}}




test menu-3.14 {MenuWidgetCmd procedure, "clone" option} {







    catch {destroy .m1}




    menu .m1




    list [catch {.m1 clone} msg] $msg [destroy .m1]

} {1 {wrong # args: should be ".m1 clone newMenuName ?menuType?"} {}}
test menu-3.15 {MenuWidgetCmd procedure, "clone" option} {
    catch {destroy .m1}

    menu .m1



    list [catch {.m1 clone a b c d} msg] $msg [destroy .m1]

} {1 {wrong # args: should be ".m1 clone newMenuName ?menuType?"} {}}
test menu-3.16 {MenuWidgetCmd procedure, "clone" option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 clone .m1.clone1} msg] $msg [destroy .m1]

} {0 {} {}}
test menu-3.17 {MenuWidgetCmd procedure, "clone" option} {
    catch {destroy .m1}

    menu .m1

























































    list [catch {.m1 clone .m1.clone1 tearoff} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.18 {MenuWidgetCmd procedure, "configure" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {llength [.m1 configure]} msg] $msg [destroy .m1]
} {0 20 {}}


test menu-3.19 {MenuWidgetCmd procedure, "configure" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 configure -gorp} msg] $msg [destroy .m1]
} {1 {unknown option "-gorp"} {}}
test menu-3.20 {MenuWidgetCmd procedure, "configure" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 configure -postcommand "A random String"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.21 {MenuWidgetCmd procedure, "configure" option} {
    catch {destroy .m1}

    menu .m1
    .m1 configure -postcommand "Another string"
    list [catch {lindex [.m1 configure -postcommand] 4} msg] $msg [destroy .m1]


} {0 {Another string} {}}
test menu-3.22 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 delete} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 delete first ?last?"} {}}
test menu-3.23 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 delete foo} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.24 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 delete 0 "foo"} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.25 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 delete 0} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.26 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "foo"
    list [catch {.m1 delete 1 0} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.27 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    list [catch {.m1 delete 1 3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.28 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 2
    list [catch {.m1 delete 1 3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.29 {MenuWidgetCmd procedure, "delete" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 3
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.29+1 {MenuWidgetCmd, "delete", Bug 220950} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "bogus"
    .m1 add command -label "ok"
    .m1 delete 10 20
    .m1 entrycget last -label
} -cleanup {
    destroy .m1
} -result ok
test menu-3.30 {MenuWidgetCmd procedure, "entrycget" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 entrycget} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 entrycget index option"} {}}
test menu-3.31 {MenuWidgetCmd procedure, "entrycget" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 entrycget index option foo} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 entrycget index option"} {}}
test menu-3.32 {MenuWidgetCmd procedure, "entrycget" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 entrycget foo -label} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.33 {MenuWidgetCmd procedure, "entrycget" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 entrycget 1 -label} msg] $msg [destroy .m1]


} {0 test {}}
test menu-3.34 {MenuWidgetCmd procedure, "entryconfigure" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 entryconfigure} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 entryconfigure index ?option value ...?"} {}}
test menu-3.35 {MenuWidgetCmd procedure, "entryconfigure" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 entryconfigure foo} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.36 {MenuWidgetCmd procedure, "entryconfigure" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {llength [.m1 entryconfigure 1]} msg] $msg [destroy .m1]
} {0 15 {}}


test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {lindex [.m1 entryconfigure 1 -label] 4} msg] $msg [destroy .m1]


} {0 test {}}
test menu-3.38 {MenuWidgetCmd procedure, "entryconfigure" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -label "changed"
    list [catch {lindex [.m1 entryconfigure 1 -label] 4} msg] $msg [destroy .m1]


} {0 changed {}}
test menu-3.39 {MenuWidgetCmd procedure, "index" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 index} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 index string"} {}}
test menu-3.40 {MenuWidgetCmd procedure, "index" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 index foo} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-3.41 {MenuWidgetCmd procedure, "index" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "3"
    .m1 add command -label "another label"
    .m1 add command -label "end"
    .m1 add command -label "3a"
    .m1 add command -label "final entry"
    list [.m1 index "test"] [.m1 index "3"] [.m1 index "3a"] [.m1 index "end"] [destroy .m1]


} {1 3 5 6 {}}
test menu-3.42 {MenuWidgetCmd procedure, "insert" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 insert} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 insert index type ?options?"} {}}
test menu-3.43 {MenuWidgetCmd procedure, "insert" option} {
    catch {destroy .m1}

    menu .m1
    .m1 insert 1 command -label "test"
    list [catch {.m1 entrycget 1 -label} msg] $msg [destroy .m1]


} {0 test {}}
test menu-3.44 {MenuWidgetCmd procedure, "invoke" option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 invoke} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 invoke index"} {}}
test menu-3.45 {MenuWidgetCmd procedure, "invoke" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 invoke foo} msg] $msg [destroy .m1]


} {1 {bad menu entry index "foo"} {}}
test menu-3.46 {MenuWidgetCmd procedure, "invoke" option} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add command -label "set foo" -command "set foo hello"


    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]
} {0 hello 0 hello 0 {} {}}
test menu-3.47 {MenuWidgetCmd procedure, "post" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "On Windows, hit Escape to get this menu to go away"


    list [catch {.m1 post} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 post x y"} {}}
test menu-3.48 {MenuWidgetCmd procedure, "post" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 post foo 40} msg] $msg [destroy .m1]


} {1 {expected integer but got "foo"} {}}
test menu-3.49 {MenuWidgetCmd procedure, "post" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 post 40 bar} msg] $msg [destroy .m1]


} {1 {expected integer but got "bar"} {}}
test menu-3.50 {MenuWidgetCmd procedure, "post" option} {nonUnixUserInteraction } {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "menu-3.53: hit Escape" -command "puts hello"
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-3.51 {MenuWidgetCmd procedure, "postcascade" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 postcascade} msg] $msg [destroy .m1]


} {1 {wrong # args: should be ".m1 postcascade index"} {}}
test menu-3.52 {MenuWidgetCmd procedure, "postcascade" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 postcascade foo} msg] $msg [destroy .m1]


} {1 {bad menu entry index "foo"} {}}
test menu-3.53 {MenuWidgetCmd procedure, "postcascade" option} {nonUnixUserInteraction } {


    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label "menu-3.56 - hit Escape"
    menu .m2
    .m1 post 40 40
    .m1 add cascade -menu .m2
    list [catch {.m1 postcascade 1} msg] $msg [destroy .m1 .m2]


} {0 {} {}}
test menu-3.54 {MenuWidgetCmd procedure, "postcascade" option} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2 -label "menu-3.57 - hit Escape"
    .m1 postcascade 1
    list [catch {.m1 postcascade none} msg] $msg [destroy .m1 .m2]


} {0 {} {}}
test menu-3.55 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 type} msg] $msg [destroy .m1]
} {1 {wrong # args: should be ".m1 type index"} {}}
test menu-3.56 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 type foo} msg] $msg [destroy .m1]


} {1 {bad menu entry index "foo"} {}}
test menu-3.57 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"


    list [catch {.m1 type 1} msg] $msg [destroy .m1]
} {0 command {}}
test menu-3.58 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add separator


    list [catch {.m1 type 1} msg] $msg [destroy .m1]
} {0 separator {}}
test menu-3.59 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label "test"


    list [catch {.m1 type 1} msg] $msg [destroy .m1]
} {0 checkbutton {}}
test menu-3.60 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label "test"


    list [catch {.m1 type 1} msg] $msg [destroy .m1]
} {0 radiobutton {}}
test menu-3.61 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label "test"


    list [catch {.m1 type 1} msg] $msg [destroy .m1]
} {0 cascade {}}
test menu-3.62 {MenuWidgetCmd procedure, "type" option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 type 0} msg] $msg [destroy .m1]
} {0 tearoff {}}
test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 unpost foo} msg] $msg [destroy .m1]


} {1 {wrong # args: should be ".m1 unpost"} {}}
test menu-3.64 {MenuWidgetCmd procedure, "unpost" option} {nonUnixUserInteraction } {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "menu-3.68 - hit Escape"
    .m1 post 40 40


    list [catch {.m1 unpost} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-3.65 {MenuWidgetCmd procedure, "yposition" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 yposition} msg] $msg [destroy .m1]


} {1 {wrong # args: should be ".m1 yposition index"} {}}
test menu-3.66 {MenuWidgetCmd procedure, "yposition" option} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 yposition 1}] [destroy .m1]







} {0 {}}



















test menu-3.67 {MenuWidgetCmd procedure, bad option} {
    catch {destroy .m1}

    menu .m1


    list [catch {.m1 foo} msg] $msg [destroy .m1]
} {1 {bad option "foo": must be activate, add, cget, clone, configure, delete, entrycget, entryconfigure, index, insert, invoke, post, postcascade, type, unpost, xposition, or yposition} {}}
test menu-3.68 {MenuWidgetCmd procedure, fix for bug#508988} {


    set t .t
    set m1 .t.m1
    set c1 .t.c1
    set c2 .t.c2
    toplevel .t
    menu $m1 -tearoff 1
    menu $c1 -tearoff 1
    $c1 add command -label c1
    menu $c2 -tearoff 1
    $c2 add command -label c2
    $m1 add cascade -label c1 -menu $c1
    $t configure -menu $m1
    $m1 entryconfigure 1 -menu $c2 -label c2
    $t configure -menu ""
    set l [list [winfo exists $c1] [winfo exists $c2]]
    destroy $t;
    set l;
} {1 1}
test menu-3.69 {MenuWidgetCmd procedure, "xposition" option} -setup {
    catch {destroy .m1}
    menu .m1
} -body {
    .m1 xposition
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 xposition index"}
test menu-3.70 {MenuWidgetCmd procedure, "xposition" option} -setup {
    catch {destroy .m1}
    menu .m1
} -body {
    .m1 xposition 1
    subst {} ;# just checking that the xposition does not produce an error...
} -cleanup {
    destroy .m1
} -result {}










test menu-4.1 {TkInvokeMenu: disabled} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off \
	-state disabled
    list [catch {.m1 invoke 1} msg] [destroy .m1] $foo


} {0 {} off}
test menu-4.2 {TkInvokeMenu: tearoff} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 invoke 0} msg] [destroy .m1]


} {0 {}}
test menu-4.3 {TkInvokeMenu: checkbutton -on} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]



} {0 {} 0 on 0 {} {}}
test menu-4.4 {TkInvokeMenu: checkbutton -off} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    .m1 invoke 1
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 off 0 {} {}}
test menu-4.5 {TkInvokeMenu: checkbutton array element} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo(1) -onvalue on
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo(1)} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 on 0 {} {}}
test menu-4.6 {TkInvokeMenu: radiobutton} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 one 0 {} {}}
test menu-4.7 {TkInvokeMenu: radiobutton} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 2} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 two 0 {} {}}
test menu-4.8 {TkInvokeMenu: radiobutton} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 three 0 {} {}}
test menu-4.9 {TkInvokeMenu: radiobutton array element} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo(2) -value one
    .m1 add radiobutton -label "2" -variable foo(2) -value two
    .m1 add radiobutton -label "3" -variable foo(2) -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo(2)} msg2] $msg2 [catch {unset foo} msg3] $msg3 [destroy .m1]


} {0 {} 0 three 0 {} {}}
test menu-4.10 {TkInvokeMenu} {
    catch {destroy .m1}

    catch {unset menu_test}
    menu .m1
    .m1 add command -label "test" -command "set menu_test menu-4.8"
    list [catch {.m1 invoke 1} msg] $msg [catch {set menu_test} msg2] $msg2 [catch {unset menu_test} msg3] $msg3 [destroy .m1]


} {0 menu-4.8 0 menu-4.8 0 {} {}}
test menu-4.11 {TkInvokeMenu} {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label "test" -menu .m1.m2
    list [catch {.m1 invoke 1} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-4.12 {TkInvokeMenu} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test" -command ".m1 delete 1"
    list [catch {.m1 invoke 1} msg] $msg [catch {.m1 type "test"} msg2] $msg2 [destroy .m1]
} {0 {} 1 {bad menu entry index "test"} {}}








test menu-5.1 {DestroyMenuInstance} {
    catch {destroy .m1}

    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-5.2 {DestroyMenuInstance - cascade menu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    list [catch {destroy .m2} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-5.3 {DestroyMenuInstance - multiple cascade parents} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 add cascade -menu .m3
    menu .m2
    .m2 add cascade -menu .m3
    menu .m3
    list [catch {destroy .m3} msg] $msg [destroy .m1 .m2]
} {0 {} {}}
test menu-5.4 {DestroyMenuInstance - multiple cascade parents} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    .m1 add cascade -menu .m4
    menu .m2
    .m2 add cascade -menu .m4
    menu .m3
    .m3 add cascade -menu .m4
    menu .m4
    list [catch {destroy .m4} msg] $msg [destroy .m1 .m2 .m3]
} {0 {} {}}
test menu-5.5 {DestroyMenuInstance - cascades of cloned menus} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    . configure -menu .m1
    list [catch {destroy .m2} msg] $msg [.m1 entrycget 1 -menu] [. configure -menu ""] [destroy .m1]
} {0 {} .m2 {} {}}
test menu-5.6 {DestroyMenuInstance - cascades of cloned menus} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1
    list [catch {destroy .m2} msg] $msg [. configure -menu ""] [destroy .t2 .m1]
} {0 {} {} {}}
test menu-5.7 {DestroyMenuInstance - basic clones} {
    catch {destroy .m1}

    menu .m1
    set tearoff [tk::TearOffMenu .m1]
    list [catch {destroy $tearoff} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-5.8 {DestroyMenuInstance - multiple clones} {
    catch {destroy .m1}

    menu .m1
    set tearoff1 [tk::TearOffMenu .m1]
    set tearoff2 [tk::TearOffMenu .m1]
    list [catch {destroy $tearoff1} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-5.9 {DestroyMenuInstace - master menu} {
    catch {destroy .m1}

    menu .m1
    tk::TearOffMenu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-5.10 {DestroyMenuInstance - freeing entries} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "foo"
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-5.11 {DestroyMenuInstace - no entries} {
    catch {destroy .m1}

    menu .m1
    .m1 configure -tearoff 0
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-5.12 {DestroyMenuInstance - platform data} {
    catch {destroy .m1}

    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-5.13 {DestroyMenuInstance - clones when mismatched tearoffs} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [destroy .m2] [destroy .m1]
} {{} {}}


test menu-6.1 {TkDestroyMenu} {
    catch {destroy .m1}

    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-6.2 {TkDestroyMenu - reentrancy} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    bind .m1 <Destroy> {destroy .m1}
    menu .m2
    bind .m2 <Destroy> {destroy .m2}
    list [catch {destroy .m1} msg] $msg [destroy .m2]
} {0 {} {}}
test menu-6.3 {TkDestroyMenu - reentrancy} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    bind .m1 <Destroy> {destroy .m2}
    .m1 clone .m2
    .m1 clone .m3
    list [catch {destroy .m1} msg] $msg [winfo exists .m2]
} {0 {} 0}
test menu-6.4 {TkDestroyMenu - reentrancy - clones} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2
    .m1 clone .m1.m3
    list [catch {destroy .m1} msg] $msg
} {0 {}}


test menu-6.5 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2
    destroy .m1
    winfo exists .m2
} {0}
test menu-6.6 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2 tearoff
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-6.7 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2
    destroy .m2
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-6.8 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    destroy .m1
    list [winfo exists .m2] [winfo exists .m3]
} {0 0}
test menu-6.9 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    list [catch {destroy .m2} msg] $msg [catch {destroy .m3} msg2] $msg2 [catch {destroy .m1} msg3] $msg3
} {0 {} 0 {} 0 {}}
test menu-6.10 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    list [catch {destroy .m3} msg] $msg [catch {destroy .m1} msg2] $msg2
} {0 {} 0 {}}
test menu-6.11 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [catch {destroy .m2} msg1] $msg1 [catch {destroy .m1} msg2] $msg2
} {0 {} 0 {}}
test menu-6.12 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [catch {destroy .m3} msg1] $msg1 [catch {destroy .m1} msg2] $msg2
} {0 {} 0 {}}
test menu-6.13 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [catch {destroy .m4} msg1] $msg1 [catch {destroy .m1} msg2] $msg2
} {0 {} 0 {}}
test menu-6.14 {TkDestroyMenu} {
    catch {destroy .m1}

    menu .m1
    . configure -menu .m1
    list [catch {destroy .m1} msg] $msg [. configure -menu ""]
} {0 {} {}}
test menu-6.15 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .t2}
    menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    list [catch {destroy .m1} msg] $msg [destroy .t2] [. configure -menu ""]
} {0 {} {} {}}
test menu-6.16 {TkDestroyMenu} {
    catch {destroy .m1}
    catch {destroy .t2}
    catch {destroy .t3}
    menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    toplevel .t3
    wm geometry .t3 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    .t3 configure -menu .m1
    list [catch {destroy .m1} msg] $msg [destroy .t2] [destroy .t3] [. configure -menu ""]
} {0 {} {} {} {}}

test menu-7.1 {UnhookCascadeEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-7.2 {UnhookCascadeEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -menu .m2
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-7.3 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m2 add cascade -menu .cascade
    .m1 add cascade -menu .cascade
    list [catch {destroy .m1} msg] $msg [destroy .m2]
} {0 {} {}}
test menu-7.4 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    list [catch {destroy .m1} msg] $msg [destroy .m2]
} {0 {} {}}
test menu-7.5 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [catch {destroy .m1} msg] $msg [destroy .m2 .m3]
} {0 {} {}}
test menu-7.6 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [catch {destroy .m2} msg] $msg [destroy .m1 .m3]
} {0 {} {}}
test menu-7.7 {UnhookCascadeEntry} {


    catch {destroy .m1}
    catch {destroy .m2}




    catch {destroy .m3}




    menu .m1
    menu .m2
    menu .m3
    .m1 add cascade -menu .cascade
    .m2 add cascade -menu .cascade
    .m3 add cascade -menu .cascade
    list [catch {destroy .m3} msg] $msg [destroy .m1 .m2]
} {0 {} {}}
test menu-7.8 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [catch {destroy .m1} msg] $msg [destroy .m2]
} {0 {} {}}
test menu-7.9 {UnhookCascadeEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    destroy .m1
    list [catch {destroy .m2} msg] $msg
} {0 {}}

test menu-8.1 {DestroyMenuEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [catch {.m1 delete 1} msg] $msg [destroy .m1 .m2]
} {0 {} {}}
test menu-8.2 {DestroyMenuEntry} hasEarthPhoto {

    catch {image delete image1a}
    catch {destroy .m1}
    image create photo image1a -file $earthPhotoFile
    menu .m1
    .m1 add command -image image1a
    list [catch {.m1 delete 1} msg] $msg [destroy .m1] [image delete image1a]
} {0 {} {} {}}
test menu-8.3 {DestroyMenuEntry} testImageType {
    catch {eval image delete [image names]}

    catch {destroy .m1}
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    list [catch {.m1 delete 1} msg] $msg [destroy .m1] [eval image delete [image names]]



} {0 {} {} {}}
test menu-8.4 {DestroyMenuEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -variable foo
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-8.5 {DestroyMenuEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-8.6 {DestroyMenuEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [catch {.m1 delete 1} msg] $msg [.m1 entrycget 1 -label] [destroy .m1]
} {0 {} two {}}
test menu-8.7 {DestroyMenuEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label "one"
    .m1 clone .m2 tearoff
    list [catch {.m2 delete 0} msg] $msg [destroy .m1]
} {0 {} {}}


# test menu-9 - Can only change when fonts change on system, which cannot
# be done from tcl.

test menu-9.1 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 configure -postcommand "beep"} msg] $msg [.m1 cget -postcommand] [destroy .m1]


} {0 {} beep {}}
test menu-9.2 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 configure -tearoff 0} msg] $msg [.m1 entrycget 1 -label] [destroy .m1]


} {0 {} test {}}
test menu-9.3 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 configure -postcommand "beep"} msg] $msg [.m1 cget -postcommand] [destroy .m1]


} {0 {} beep {}}
test menu-9.4 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 configure -fg red} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-9.5 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "two"
    list [catch {.m1 configure -fg red} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-9.6 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "two"
    .m1 add command -label "three"
    list [catch {.m1 configure -fg red} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-9.7 {ConfigureMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2 tearoff
    list [catch {.m1 configure -fg red} msg] $msg [.m2 cget -fg] [destroy .m1]


} {0 {} red {}}
test menu-9.8 {ConfigureMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2 tearoff
    list [catch {.m2 configure -fg red} msg] $msg [.m1 cget -fg] [destroy .m1]


} {0 {} red {}}
test menu-9.9 {ConfigureMenu} {
    catch {destroy .m1}

    menu .m1
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]



} {0 {} {} {}}

test menu-10.1 {PostProcessEntry: array variable} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    set foo(1) on
    .m1 add checkbutton -variable foo(1) -onvalue on -offvalue off -label "Nonsense"
    list [catch {set foo(1)} msg] $msg [destroy .m1]
} {0 on {}}


test menu-10.2 {PostProcessEntry: array variable} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo(1) -onvalue on -offvalue off -label "Nonsense"
    list [catch {set foo(1)} msg] $msg [destroy .m1]



} {0 off {}}

test menu-11.1 {ConfigureMenuEntry} {
    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo -onvalue on -offvalue off -label "Nonsense"
    list [catch {.m1 entryconfigure 1 -variable bar} msg] $msg [.m1 entrycget 1 -variable] [destroy .m1]


} {0 {} bar {}}
test menu-11.2 {ConfigureMenuEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 entryconfigure 1 -label ""} msg] $msg [.m1 entrycget 1 -label] [destroy .m1]


} {0 {} {} {}}
test menu-11.3 {ConfigureMenuEntry} {
    catch {destroy .m1}

    menu .m1
    .m1 add command
    list [catch {.m1 entryconfigure 1 -label "test"} cmd] $cmd [.m1 entrycget 1 -label] [destroy .m1]


} {0 {} test {}}
test menu-11.4 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command
    list [catch {.m1 entryconfigure 1 -accel "S"} msg] $msg [.m1 entrycget 1 -accel] [destroy .m1]


} {0 {} S {}}
test menu-11.5 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command
    list [catch {.m1 entryconfigure 1 -label "test"} msg] $msg [.m1 entrycget 1 -label] [destroy .m1]


} {0 {} test {}}
test menu-11.6 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command
    list [catch {.m1 entryconfigure 1 -label "test"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.7 {ConfigureMenuEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m2
    menu .m1
    .m1 add cascade
    list [catch {.m1 entryconfigure 1 -label "test" -menu .m2} msg] $msg [destroy .m1 .m2]


} {0 {} {}}
test menu-11.8 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade
    list [catch {.m1 entryconfigure 1 -label "test" -menu .m2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.9 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -menu .m3
    list [catch {.m1 entryconfigure 1 -label "test" -menu .m2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.10 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade
    list [catch {.m1 entryconfigure 1 -label "test" -menu .m2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.11 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {.m1 entryconfigure 1 -label "test" -menu .m2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.12 {ConfigureMenuEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    catch {destroy .m5}
    menu .m1
    menu .m2
    .m2 add cascade -menu .m1
    menu .m3
    .m3 add cascade -menu .m1
    menu .m4
    .m4 add cascade -menu .m1
    menu .m5
    .m5 add cascade
    list [catch {.m5 entryconfigure 1 -label "test" -menu .m1} msg] $msg [destroy .m1 .m2 .m3 .m4 .m5]


} {0 {} {}}
test menu-11.13 {ConfigureMenuEntry} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    menu .m2
    .m2 add cascade -menu .m1
    menu .m3
    .m3 add cascade -menu .m1
    menu .m4
    .m4 add cascade -menu .m1
    list [catch {.m3 entryconfigure 1 -label "test" -menu .m1} msg] $msg [destroy .m1 .m2 .m3 .m4]


} {0 {} {}}
test menu-11.14 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton
    list [catch {.m1 entryconfigure 1 -variable "test"} msg] $msg [.m1 entrycget 1 -variable] [destroy .m1]


} {0 {} test {}}
test menu-11.15 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add checkbutton -label "test"} msg] $msg [.m1 entrycget 1 -variable] [destroy .m1]


} {0 {} test {}}
test menu-11.16 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add radiobutton -label "test"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-11.17 {ConfigureMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton
    list [catch {.m1 entryconfigure 1 -onvalue "test"} msg] $msg [.m1 entrycget 1 -onvalue] [destroy .m1]


} {0 {} test {}}
test menu-11.18 {ConfigureMenuEntry} testImageType {
    catch {destroy .m1}
    catch {image delete image1}

    menu .m1
    .m1 add command
    image create test image1
    list [catch {.m1 entryconfigure 1 -image image1} msg] $msg [destroy .m1] [image delete image1]



} {0 {} {} {}}
test menu-11.19 {ConfigureMenuEntry} {testImageType hasEarthPhoto} {

    catch {destroy .m1}
    catch {image delete image1}
    catch {image delete image2}

    image create test image1
    image create photo image2 -file $earthPhotoFile
    menu .m1
    .m1 add command -image image1
    list [catch {.m1 entryconfigure 1 -image image2} msg] $msg [destroy .m1] [image delete image1] [image delete image2]



} {0 {} {} {} {}}
test menu-11.20 {ConfigureMenuEntry} {testImageType hasEarthPhoto} {

    catch {destroy .m1}
    catch {image delete image1}
    catch {image delete image2}

    image create photo image1 -file $earthPhotoFile
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1
    list [catch {.m1 entryconfigure 1 -selectimage image2} msg] $msg [destroy .m1] [image delete image1] [image delete image2]



} {0 {} {} {} {}}
test menu-11.21 {ConfigureMenuEntry} {testImageType hasEarthPhoto} {

    catch {destroy .m1}
    catch {image delete image1}
    catch {image delete image2}
    catch {image delete image3}
    image create photo image1 -file $earthPhotoFile
    image create test image2
    image create test image3
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    list [catch {.m1 entryconfigure 1 -selectimage image3} msg] $msg [destroy .m1] [image delete image1] [image delete image2] [image delete image3]




} {0 {} {} {} {} {}}

test menu-12.1 {ConfigureMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m2 configure -tearoff 0
    .m1 clone .m3
    .m1 add command -label "test"
    .m1 add command -label "test2"
    list [list [catch {.m1 entryconfigure 1 -gork "foo"} msg] $msg] [destroy .m1]


} {{1 {unknown option "-gork"}} {}}
test menu-12.2 {ConfigureMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    catch {destroy .m4}
    menu .m1
    .m1 clone .m2
    menu .m3
    .m1 add cascade -menu .m3
    menu .m4
    list [catch {.m1 entryconfigure 1 -menu .m4} msg] $msg [destroy .m1] [destroy .m3] [destroy .m4]


} {0 {} {} {} {}}
test menu-12.3 {ConfigureMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 clone .m2
    .m1 add cascade -label dummy
    list [catch {.m1 entryconfigure dummy -menu .m3} msg] $msg [destroy .m1]
} {0 {} {}}


test menu-12.4 {ConfigureMenuCloneEntries} {
     catch {destroy .m1}
     catch {destroy .m2}
     menu .m1
     .m1 add cascade -label File -menu .m1.foo
     menu .m1.foo
     .m1.foo add command -label bar
     .m1 clone .m2
     list [catch {.m1 entryconfigure File -state disabled} msg1] $msg1 [destroy .m1]



} {0 {} {}}

test menu-13.1 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    list [catch {.m1 entrycget active -label} msg] $msg [destroy .m1]


} {0 test2 {}}
test menu-13.2 {TkGetMenuIndex} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "last"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    list [catch {.m1 entrycget last -label} msg] $msg [destroy .m1]
} {0 test3 {}}
test menu-13.3 {TkGetMenuIndex} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "last"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2












    list [catch {.m1 entrycget end -label} msg] $msg [destroy .m1]


} {0 test3 {}}
test menu-13.4 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 insert last command -label "test2"} msg] $msg [.m1 entrycget last -label] [destroy .m1]


} {0 {} test2 {}}
test menu-13.5 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 insert end command -label "test2"} msg] $msg [.m1 entrycget end -label] [destroy .m1]


} {0 {} test2 {}}
test menu-13.6 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    list [catch {.m1 entrycget none -label} msg] $msg [destroy .m1]


} {0 {} {}}
#test menu-13.7 - Need to add @test here.
test menu-13.7 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    list [catch {.m1 entrycget 1 -label} msg] $msg [destroy .m1]


} {0 active {}}
test menu-13.8 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "active"
    list [catch {.m1 entrycget -1 -label} msg] $msg [destroy .m1]
} {1 {bad menu entry index "-1"} {}}
test menu-13.9 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
    list [catch {.m1 entrycget 999 -label} msg] $msg [destroy .m1]




} {0 test2 {}}
test menu-13.10 {TkGetMenuIndex} {
    catch {destroy .m1}
    menu .m1
    .m1 insert 999 command -label "test"
    list [catch {.m1 entrycget 1 -label} msg] $msg [destroy .m1]


} {0 test {}}
test menu-13.11 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "1test"
    list [catch {.m1 entrycget 1test -label} msg] $msg [destroy .m1]


} {0 1test {}}
test menu-13.12 {TkGetMenuIndex} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2" -command "beep"
    .m1 add command -label "test3"
    list [catch {.m1 entrycget test2 -command} msg] $msg [destroy .m1]



} {0 beep {}}






test menu-14.1 {MenuCmdDeletedProc} {
    catch {destroy .m1}
    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-14.2 {MenuCmdDeletedProc} {

    catch {destroy .m1}
    menu .m1
    .m1 clone .m2
    list [catch {destroy .m1} msg] $msg
} {0 {}}



test menu-15.1 {MenuNewEntry} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add command -label "test"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-15.2 {MenuNewEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test3"
    list [catch {.m1 insert 2 command -label "test2"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-15.3 {MenuNewEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 add command -label "test2"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-15.4 {MenuNewEntry} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add command -label "test"} msg] $msg [destroy .m1]


} {0 {} {}}

test menu-16.1 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 insert foo command -label "test"} msg] $msg [destroy .m1]
} {1 {bad menu entry index "foo"} {}}
test menu-16.2 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 insert test command -label "foo"} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.3 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 insert -1 command -label "test"} msg] $msg [destroy .m1]
} {1 {bad menu entry index "-1"} {}}
test menu-16.4 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 insert 0 command -label "test2"
    list [catch {.m1 entrycget 1 -label} msg] $msg [destroy .m1]


} {0 test2 {}}
test menu-16.5 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add cascade} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.6 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add checkbutton} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.7 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.8 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add radiobutton} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.9 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add separator} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.10 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add blork} msg] $msg [destroy .m1]
} {1 {bad menu entry type "blork": must be cascade, checkbutton, command, radiobutton, or separator} {}}
test menu-16.11 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-16.12 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [catch {.m2 add command -label "test"} msg1] $msg1 [catch {.m1 entrycget 1 -label} msg2] $msg2 [catch {.m3 entrycget 1 -label} msg3] $msg3 [destroy .m1]


} {0 {} 0 test 0 test {}}
test menu-16.13 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [catch {.m3 add command -label "test"} msg1] $msg1 [catch {.m1 entrycget 1 -label} msg2] $msg2 [catch {.m2 entrycget 1 -label} msg3] $msg3 [destroy .m1]


} {0 {} 0 test 0 test {}}
test menu-16.14 {MenuAddOrInsert} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 add command -blork} msg] $msg [destroy .m1]
} {1 {unknown option "-blork"} {}}
test menu-16.15 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .container}
    menu .m1
    .m1 add command -label "File"
    menu .container
    . configure -menu .container
    list [catch {.container add cascade -label "File" -menu .m1} msg] $msg [. configure -menu ""] [destroy .container .m1]


} {0 {} {} {}}
test menu-16.16 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    set tearoff [tk::TearOffMenu .m2]
    list [catch {.m2 add cascade -menu .m1} msg] $msg [$tearoff unpost] [catch {destroy .m1} msg2] $msg2 [catch {destroy .m2} msg3] $msg3


} {0 {} {} 0 {} 0 {}}
test menu-16.17 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .container}
    menu .m1
    menu .container
    . configure -menu .container
    set tearoff [tk::TearOffMenu .container]
    list [catch {.container add cascade -label "File" -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1 .container]


} {0 {} {} {}}
test menu-16.18 {MenuAddOrInsert} {
    catch {destroy .m1}
    catch {destroy .container}
    menu .m1
    menu .container
    .container add cascade -menu .m1
    . configure -menu .container
    list [catch {.container add cascade -label "File" -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1 .container]


} {0 {} {} {}}
test menu-16.19 {MenuAddOrInsert - Insert a cascade deep into the tree} {

    catch {destroy .menubar}
    menu .menubar
    menu .menubar.test -tearoff 0
    .menubar add cascade -label Test -underline 0 -menu .menubar.test
    menu .menubar.test.cascade -tearoff 0
    .menubar.test.cascade add command -label SubItem -command "puts SubItemSelected"
    . configure -menu .menubar
    list [catch {.menubar.test add cascade -label SubMenu \
	-menu .menubar.test.cascade} msg] \
	[info commands .\#menubar.\#menubar\#test.\#menubar\#test\#cascade] \
	[. configure -menu ""] [destroy .menubar]


} {0 .#menubar.#menubar#test.#menubar#test#cascade {} {}}


test menu-17.1 {MenuVarProc} {

    catch {destroy .m1}
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [catch {.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye} msg] $msg [catch {unset foo} msg2] $msg2 [destroy .m1]



} {0 {} 0 {} {}}
# menu-17.2 - Don't know how to generate the flags in the if
test menu-17.2 {MenuVarProc} {

    catch {destroy .m1}
    catch {unset foo}
    menu .m1
    list [catch {.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye} msg] $msg [set foo ""] [destroy .m1]



} {0 {} {} {}}
test menu-17.3 {MenuVarProc} {

    catch {destroy .m1}
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [catch {.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye} msg] $msg [set foo "hello"] [destroy .m1] [catch {unset foo} msg2] $msg2



} {0 {} hello {} 0 {}}
test menu-17.4 {MenuVarProc} {

    catch {destroy .m1}
    menu .m1
    set foo "goodbye"
    list [catch {.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye} msg] $msg [set foo "hello"] [destroy .m1] [catch {unset foo} msg2] $msg2



} {0 {} hello {} 0 {}}
test menu-17.5 {MenuVarProc} {

    catch {destroy .m1}
    menu .m1
    set foo "hello"
    list [catch {.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye} msg] $msg [set foo "goodbye"] [destroy .m1] [catch {unset foo} msg2] $msg2



} {0 {} goodbye {} 0 {}}














test menu-18.1 {TkActivateMenuEntry} {

    catch {destroy .m1}

    menu .m1

    .m1 add command -label "test"







    list [catch {.m1 activate 1} msg] $msg [destroy .m1]
} {0 {} {}}
test menu-18.2 {TkActivateMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    list [catch {.m1 activate 0} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-18.3 {TkActivateMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"










    .m1 activate 1
    list [catch {.m1 activate 2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-18.4 {TkActivateMenuEntry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
    .m1 activate 1
    list [catch {.m1 activate 1} msg] $msg [destroy .m1]



} {0 {} {}}

test menu-19.1 {TkPostCommand} {nonUnixUserInteraction } {

    catch {destroy .m1}
    menu .m1 -postcommand "set menu_test menu-19.1"
    .m1 add command -label "menu-19.1 - hit Escape"
    list [catch {.m1 post 40 40} msg] $msg [.m1 unpost] [set menu_test] [destroy .m1]
} {0 menu-19.1 {} menu-19.1 {}}
test menu-19.2 {TkPostCommand} {nonUnixUserInteraction } {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "menu-19.2 - hit Escape"
    list [catch {.m1 post 40 40} msg] $msg [.m1 unpost] [destroy .m1]
} {0 {} {} {}}












test menu-20.1 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2} msg1] $msg1 [destroy .m1]


} {0 {} {}}
test menu-20.2 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2 normal} msg1] $msg1 [destroy .m1]

} {0 {} {}}
test menu-20.3 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2 tearoff} msg1] $msg1 [destroy .m1]


} {0 {} {}}
test menu-20.4 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2 menubar} msg1] $msg1 [destroy .m1]


} {0 {} {}}
test menu-20.5 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2 foo} msg1] $msg1 [destroy .m1]
} {1 {bad menu type "foo": must be normal, tearoff, or menubar} {}}
test menu-20.6 {CloneMenu - hooking up bookeeping ptrs} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-20.7 {CloneMenu - hooking up bookeeping ptrs - multiple children} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 clone .m2
    list [catch {.m1 clone .m3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-20.8 {CloneMenu - cascade entries} {
    catch {destroy .m1}
    catch {destroy .foo}
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {.m1 clone .foo} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-20.9 {CloneMenu - cascades entries} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .foo}
    menu .m1
    .m1 add cascade -menu .m2
    menu .m2
    list [catch {.m1 clone .foo} msg] $msg [destroy .m1 .m2]


} {0 {} {}}
test menu-20.10 {CloneMenu - tearoff fields} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    list [catch {.m1 clone .m2 normal} msg1] $msg1 [catch {.m2 cget -tearoff} msg2] $msg2 [destroy .m1]
} {0 {} 0 1 {}}


test menu-20.11 {CloneMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    menu .m2
    list [catch {.m1 clone .m2} msg] $msg [destroy .m1 .m2]
} {1 {window name "m2" already exists in parent} {}}

test menu-21.1 {MenuDoYPosition} {

    catch {destroy .m1}
    menu .m1
    list [catch {.m1 yposition glorp} msg] $msg [destroy .m1]
} {1 {bad menu entry index "glorp"} {}}
test menu-21.2 {MenuDoYPosition} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "Test"
    list [catch {.m1 yposition 1}] [destroy .m1]
} {0 {}}



test menu-22.1 {GetIndexFromCoords} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    list [catch {.m1 index @5} msg] $msg [destroy .m1]


} {0 0 {}}
test menu-22.2 {GetIndexFromCoords} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    list [catch {.m1 index @5,5} msg] $msg [destroy .m1]


} {0 0 {}}
test menu-22.3 {GetIndexFromCoords: mapped window, y only} unix {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    list [catch {.m1 index @5} msg] $msg [destroy .m1]


} {0 0 {}}
test menu-22.4 {GetIndexFromCoords: mapped window x,y} unix {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    list [catch {.m1 index @$x,5} msg] $msg [destroy .m1]


} {0 0 {}}
test menu-22.5 {GetIndexFromCoords: mapped wide window} unix {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 configure -tearoff 0
    tk_popup .m1 0 0
    tkwait visibility .m1
    wm geometry .m1 200x100
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    list [catch {.m1 index @$x,5} msg] $msg [destroy .m1]


} {0 0 {}}

test menu-23.1 {RecursivelyDeleteMenu} {

    catch {destroy .m1}
    menu .m1
    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-23.2 {RecursivelyDeleteMenu} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m2
    .m2 add command -label "test2"
    menu .m1
    .m1 add cascade -label "test1" -menu .m2
    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg [destroy .m1 .m2]


} {0 {} {}}

test menu-24.1 {TkNewMenuName} {

    catch {destroy .m1}
    menu .m1
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-24.2 {TkNewMenuName} {
    catch {destroy .m1}
    catch {destroy .m1\#0}
    menu .m1
    menu .m1\#0
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-24.3 {TkNewMenuName} {

    catch {destroy .#m}
    menu .#m
    rename .#m hideme
    list [catch {. configure -menu [menu .m]} $msg] [. configure -menu ""] [destroy .#m] [destroy .m] [destroy hideme]

} {0 {} {} {} {}}


test menu-25.1 {TkSetWindowMenuBar} {


    . configure -menu ""
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""]


} {0 {} {}}
test menu-25.2 {TkSetWindowMenuBar} {


    . configure -menu ""
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""]


} {0 {} {}}
test menu-25.3 {TkSetWindowMenuBar} {


    . configure -menu ""
    catch {destroy .m1}
    menu .m1
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-25.4 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    menu .m2
    list [catch {. configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .m1 .m2]


} {0 {} {} {}}
test menu-25.5 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    .m1 clone .m2
    menu .m3
    list [catch {. configure -menu .m3} msg] $msg [. configure -menu ""] [destroy .m1 .m3]


} {0 {} {} {}}
test menu-25.6 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    . configure -menu ""
    menu .m1
    .m1 clone .m2
    . configure -menu .m2
    menu .m3
    list [catch {. configure -menu .m3} msg] $msg [. configure -menu ""] [destroy .m1 .m3]


} {0 {} {} {}}
test menu-25.7 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    .t2 configure -menu .m1
    list [catch {.t2 configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .t2 .m1 .m2]


} {0 {} {} {}}
test menu-25.8 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1
    list [catch {. configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .t2 .m1 .m2]
} {0 {} {} {}}
test menu-25.9 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    catch {destroy .t3}
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [catch {.t3 configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .t2 .t3 .m1 .m2]
} {0 {} {} {}}
test menu-25.10 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    catch {destroy .t3}
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [catch {.t2 configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .t2 .t3 .m1 .m2]
} {0 {} {} {}}
test menu-25.11 {TkSetWindowMenuBar} {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .t2}
    catch {destroy .t3}
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0










    list [catch {. configure -menu .m2} msg] $msg [. configure -menu ""] [destroy .t2 .t3 .m1 .m2]







} {0 {} {} {}}















test menu-25.12 {TkSetWindowMenuBar} {

    catch {destroy .m1}
    . configure -menu ""
    menu .m1
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-25.13 {TkSetWindowMenuBar} {


    . configure -menu ""
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""]


} {0 {} {}}
test menu-25.14 {TkSetWindowMenuBar} {

    catch {destroy .m1}
    . configure -menu ""
    menu .m1
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-25.15 {TkSetWindowMenuBar} {


    . configure -menu ""
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""]


} {0 {} {}}
test menu-25.16 {TkSetWindowMenuBar} {

    catch {destroy .m1}
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    list [catch {toplevel .t2 -menu m1} msg] $msg [. configure -menu ""] [destroy .t2 .m1]


} {0 .t2 {} {}}


test menu-26.1 {DestroyMenuHashTable} {
    catch {interp destroy testinterp}


    interp create testinterp
    load {} Tk testinterp
    interp eval testinterp {menu .m1}
    list [catch {interp delete testinterp} msg] $msg

} {0 {}}

test menu-27.1 {GetMenuHashTable} {
    catch {interp destroy testinterp}


    interp create testinterp
    load {} Tk testinterp
    list [catch {interp eval testinterp {menu .m1}} msg] $msg [interp delete testinterp]


} {0 .m1 {}}


test menu-28.1 {TkCreateMenuReferences - not there before} {

    catch {destroy .m1}
    list [catch {menu .m1} msg] $msg [destroy .m1]


} {0 .m1 {}}
test menu-28.2 {TkCreateMenuReferences - there already} {








    catch {destroy .m1}
    catch {destroy .m2}




    menu .m1
    .m1 add cascade -menu .m2
    list [catch {menu .m2} msg] $msg [destroy .m1 .m2]


} {0 .m2 {}}


test menu-29.1 {TkFindMenuReferences - not there} {

    catch {destroy .m1}
    . configure -menu ""
    menu .m1

    .m1 add cascade -menu .m2
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]


} {0 {} {} {}}
test menu-30.1 {TkFindMenuReferences - there already} {
    catch {destroy .m1}

    catch {destroy .m2}
    . configure -menu ""
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1 .m2]
} {0 {} {} {}}


test menu-31.1 {TkFreeMenuReferences - menuPtr} {
    catch {destroy .m1}
    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test menu-31.2 {TkFreeMenuReferences - cascadePtr} {

    catch {destroy .m1}
    . configure -menu ""
    menu .m1
    .m1 add cascade -menu .m2
    list [catch {.m1 entryconfigure 1 -menu .m3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-31.3 {TkFreeMenuReferences - topLevelListPtr} {


    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg
} {0 {}}


test menu-31.4 {TkFreeMenuReferences - not empty} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add cascade -menu .m3
    menu .m2
    .m2 add cascade -menu .m3
    list [catch {.m2 entryconfigure 1 -menu ".foo"} msg] $msg [destroy .m1 .m2]



} {0 {} {}}

test menu-32.1 {DeleteMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label foo
    .m1 clone .m2
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.2 {DeleteMenuCloneEntries} {

    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    list [catch {.m1 delete 2 3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.3 {DeleteMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    .m2 configure -tearoff 1
    list [catch {.m1 delete 1 2} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.4 {DeleteMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three
    .m1 add command -label four
    .m1 clone .m2
    .m2 configure -tearoff 0
    list [catch {.m1 delete 2 3} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.5 {DeleteMenuCloneEntries} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 clone .m2
    .m1 activate one
    list [catch {.m1 delete one} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.6 {DeleteMenuCloneEntries - reentrancy - crashes tk8.0} {

    catch {destroy .m1}
    menu .m1

    .m1 add command -label test -command ".m1 delete test ; .m1 add command -label test -command \".m1 delete test\"; .m1 delete test"
    list [catch {.m1 invoke test} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.7 {DeleteMenuCloneEntries - one entry} {

    catch {destroy .m1}
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {.m1 delete Hello} msg] $msg [destroy .m1]


} {0 {} {}}
test menu-32.8 {Ensure all menu clone commands are deleted} {


    # SF bug #465324
    catch {destroy .menubar}
    catch {destroy .menubar.test}
    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar.test add command -label "hi"
    for {set i 0} {$i < 10} {incr i} {
	.menubar add cascade -menu .menubar.test -label "Test"
	.menubar delete Test
    }

    info commands .#menubar*test*
} {}


test menu-32.9 {Ensure deleting of clones doesn't corrupt menu refs} {
    catch {destroy .menubar}
    catch {destroy .menubar.test}

    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar add cascade -menu .menubar.test -label "Test"
    menu .menubar.cascade

    .menubar.test add cascade -menu .menubar.cascade -label "Cascade"
    set res {}
    lappend res [.menubar.test entrycget 1 -menu]
    lappend res [.#menubar.#menubar#test entrycget 1 -menu]
    destroy .menubar.test
    menu .menubar.test
    .menubar.test add cascade -menu .menubar.cascade -label "Cascade"
    lappend res [.menubar.test entrycget 1 -menu]
    lappend res [.#menubar.#menubar#test entrycget 1 -menu]
    set res


} {.menubar.cascade .#menubar.#menubar#test.#menubar#cascade .menubar.cascade .#menubar.#menubar#test.#menubar#cascade}

set l [interp hidden]
deleteWindows

test menu-33.1 {menu vs command hiding} {

    catch {destroy .m}

    menu .m
    interp hide {} .m
    destroy .m
    list [winfo children .] [interp hidden]
} [list {} $l]


# menu-34 MenuInit only called at boot time

# creating menus on two different screens then deleting the
# menu from the first screen crashes Tk8.3.1
#
test menu-35.1 {menus on multiple screens - crashes tk8.3.1, Bug 5454} \
	{altDisplay} {



    toplevel .one
    menu .one.m
    toplevel .two -screen $::env(TK_ALT_DISPLAY)
    menu .two.m
    destroy .one
    destroy .two
} {}

test menu-36.1 {menu -underline string overruns Bug 1599877} {} {


    # ensure that -underline does not do string overruns [Bug 1599877]
    catch {destroy .m}
    menu .m
    .m add command -label "File" -underline [expr {1<<30}]
    . configure -menu .m
    update
    tk::TraverseToMenu . "e"
} {}



test menu-37.1 {menubar menues cannot be posted - bug 2160206} {} {


    # On Linux the following used to panic
    # It now returns an error (on all platforms)
    catch {destroy .m}
    menu .m -type menubar
    list [catch ".m post 1 1" msg] $msg


} {1 {a menubar menu cannot be posted}}































# cleanup

deleteWindows
cleanupTests
return




Changes to tests/menuDraw.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327







328



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

566



567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# This file is a Tcl script to test drawing of menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit

test menuDraw-1.1 {TkMenuInitializeDrawingFields} -setup {
    deleteWindows
} -body {
    menu .m1
} -cleanup {
    deleteWindows
} -result {.m1}


test menuDraw-2.1 {TkInitializeMenuEntryDrawingFields} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-3.1 {TkMenuFreeDrawOptions} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1
} -result {}


test menuDraw-4.1 {TkMenuEntryFreeDrawOptions} -setup {
    deleteWindows

} -body {
    menu .m1
    .m1 add command -label "This is a test"
    destroy .m1
} -result {}
test menuDraw-4.2 {TkMenuEntryFreeDrawOptions} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton -label "This is a test." -font "Courier 12" \
        -activeforeground red -background green -selectcolor purple
    destroy .m1
} -result {}


test menuDraw-5.1 {TkMenuConfigureDrawOptions - new menu} -setup {
    deleteWindows
} -body {
    menu .m1
} -cleanup {
    deleteWindows
} -result {.m1}
test menuDraw-5.2 {TkMenuConfigureDrawOptions - old menu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 configure -fg red
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-5.3 {TkMenuConfigureDrawOptions - no disabledFg} -setup {
    deleteWindows
} -body {
    menu .m1 -disabledforeground ""
} -cleanup {
    deleteWindows
} -result {.m1}


test menuDraw-6.1 {TkMenuConfigureEntryDrawOptions - no tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.2 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.3 {TkMenuConfigureEntryDrawOptions - active state - wrong entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state active
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.4 {TkMenuConfigureEntryDrawOptions - active state - correct entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 activate 1
    .m1 entryconfigure 1 -state active
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.5 {TkMenuConfigureEntryDrawOptions - deactivate entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 activate 1
    .m1 entryconfigure 1 -state normal
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.6 {TkMenuConfigureEntryDrawOptions - bad state} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad state "foo": must be active, normal, or disabled}
test menuDraw-6.7 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.8 {TkMenuConfigureEntryDrawOptions - border specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -background "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.9 {TkMenuConfigureEntryDrawOptions - foreground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -foreground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.10 {TkMenuConfigureEntryDrawOptions - activeBorder specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activebackground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.11 {TkMenuConfigureEntryDrawOptions - activeforeground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activeforeground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.12 {TkMenuConfigureEntryDrawOptions - selectcolor specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "foo" -selectcolor "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.13 {TkMenuConfigureEntryDrawOptions - textGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Helvetica 12"
    .m1 entryconfigure 1 -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.14 {TkMenuConfigureEntryDrawOptions - activeGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activeforeground "red"
    .m1 entryconfigure 1 -activeforeground "green"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.15 {TkMenuConfigureEntryDrawOptions - disabledGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1 -disabledforeground "red"
    .m1 add command -label "foo"
    .m1 configure -disabledforeground "green"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.16 {TkMenuConfigureEntryDrawOptions - indicatorGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "foo" -selectcolor "red"
    .m1 entryconfigure 1 -selectcolor "green"
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-7.1 {TkEventuallyRecomputeMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "This is a long label"
    set tearoff [tk::TearOffMenu .m1]
    update idletasks
    .m1 entryconfigure 1 -label "foo"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-7.2 {TkEventuallyRecomputeMenu - update pending} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "This is a long label"
    set tearoff [tk::TearOffMenu .m1]
    .m1 entryconfigure 1 -label "foo"
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-8.1 {TkRecomputeMenu} -constraints {
    win userInteraction
} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 configure -postcommand [.m1 add command -label foo]
    .m1 add command -label "Hit ESCAPE to make this menu go away."
    .m1 post 0 0
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-9.1 {TkEventuallyRedrawMenu - entry test} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo 0
    .m1 add radiobutton -variable foo -label test
    tk::TearOffMenu .m1
    update idletasks
    list [set foo test] [destroy .m1] [unset foo]
} -result {test {} {}}
test menuDraw-9.2 {TkEventuallyRedrawMenu - whole menu} -setup {
    deleteWindows
} -body {
    menu .m1
    tk::TearOffMenu .m1
} -cleanup {
    deleteWindows
} -returnCodes ok -match glob -result *


# Don't know how to test when window has been deleted and ComputeMenuGeometry
# gets called.
test menuDraw-10.1 {ComputeMenuGeometry - menubar} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test
    . configure -menu .m1
    list [update idletasks] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menuDraw-10.2 {ComputeMenuGeometry - non-menubar} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test
    update idletasks
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-10.3 {ComputeMenuGeometry - Resize necessary} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test
    update idletasks
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-10.4 {ComputeMenuGeometry - resize not necessary} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test
    update idletasks
    .m1 entryconfigure 1 -label test
    update idletasks
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-11.1 {TkMenuSelectImageProc - entry selected; redraw not pending} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup







} -body {



    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    update idletasks
    list [image delete image2] [destroy .m1]
} -cleanup {
    imageCleanup
} -result {{} {}}
test menuDraw-11.2 {TkMenuSelectImageProc - entry selected; redraw pending} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [image delete image2] [destroy .m1]
} -cleanup {
    imageCleanup
} -result {{} {}}
test menuDraw-11.3 {TkMenuSelectImageProc - entry not selected} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    set tearoff [tk::TearOffMenu .m1 40 40]
    update idletasks
    list [image delete image2] [destroy .m1]
} -cleanup {
    imageCleanup
} -result {{} {}}

#Don't know how to test missing tkwin in DisplayMenu
test menuDraw-12.1 {DisplayMenu - menubar background} -constraints unix -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label foo -menu .m2
    . configure -menu .m1
    list [update] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menuDraw-12.2 {Display menu - no entries} -setup {
    deleteWindows
} -body {
    menu .m1
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-12.3 {DisplayMenu - one entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-12.4 {DisplayMenu - two entries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw.12.5 {DisplayMenu - two columns - first bigger} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    .m1 add command -label "three" -columnbreak 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-12.5 {DisplayMenu - two column - second  bigger} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two" -columnbreak 1
    .m1 add command -label "three"
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw.12.7 {DisplayMenu - three columns} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two" -columnbreak 1
    .m1 add command -label "three"
    .m1 add command -label "four"
    .m1 add command -label "five"
    .m1 add command -label "six"
    set tearoff [tk::TearOffMenu .m1 40 40]
    update
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-12.6 {Display menu - testing for extra space and menubars} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1
    update
    . configure -menu ""
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-12.7 {Display menu - extra space at end of menu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    wm geometry $tearoff 200x100
    update
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-13.1 {TkMenuEventProc - Expose} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "one"
    menu .m2
    .m2 add command -label "two"
    set tearoff1 [tk::TearOffMenu .m1 40 40]
    set tearoff2 [tk::TearOffMenu .m2 40 40]
    list [raise $tearoff2] [update]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menuDraw-13.2 {TkMenuEventProc - ConfigureNotify} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [wm geometry $tearoff 200x100] [update]
} -cleanup {
    deleteWindows
} -result {{} {}}
# Testing deletes is hard, and I am going to do my best. Don't know how
# to test the case where we have already cleared the tkwin field in the
# menuPtr.
test menuDraw-13.4 {TkMenuEventProc - simple delete} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1
} -result {}
test menuDraw-13.5 {TkMenuEventProc - nothing pending} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label foo
    update idletasks
    destroy .m1
} -result {}


test menuDraw-14.1 {TkMenuImageProc} -constraints testImageType -setup {
    deleteWindows
} -body {
    catch {image delete image1}
    menu .m1
    image create test image1
    .m1 add command -image image1
    update idletasks
    image delete image1
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-14.2 {TkMenuImageProc} -constraints testImageType -setup {
    deleteWindows
} -body {
    catch {image delete image1}
    menu .m1
    image create test image1
    .m1 add command -image image1
    image delete image1
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-15.1 {TkPostTearoffMenu - Basic posting} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    tk::TearOffMenu .m1 40 40
} -cleanup {
    deleteWindows
} -returnCodes ok -match glob -result *
test menuDraw-15.2 {TkPostTearoffMenu - Deactivation} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -state active
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff index active
} -cleanup {
    deleteWindows
} -result none
test menuDraw-15.3 {TkPostTearoffMenu - post command} -setup {

    deleteWindows



} -body {
    catch {unset foo}
    menu .m1 -postcommand "set foo .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40}] [set foo] [unset foo] [destroy .m1]
} -result {0 .m1 {} {}}
test menuDraw-15.4 {TkPostTearoffMenu - post command deleting the menu} -setup {
    deleteWindows
} -body {
    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40} msg] $msg [winfo exists .m1]
} -result {0 {} 0}
test menuDraw-15.5 {TkPostTearoffMenu - tearoff at edge of screen} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    set height [winfo screenheight .m1]
    tk::TearOffMenu .m1 40 $height
} -cleanup {
    deleteWindows
} -returnCodes ok -match glob -result *
test menuDraw-15.6 {TkPostTearoffMenu - tearoff off right} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    set width [winfo screenwidth .m1]
    tk::TearOffMenu .m1 $width 40
} -cleanup {
    deleteWindows
} -returnCodes ok -match glob -result *


test menuDraw-16.1 {TkPostSubmenu} -constraints nonUnixUserInteraction -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to make this menu go away."
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
    $tearoff postcascade 0
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-16.2 {TkPostSubMenu} -constraints nonUnixUserInteraction -setup {
    deleteWindows
} -body {

    menu .m1
    .m1 add cascade -label "two" -menu .m2
    .m1 add cascade -label "three" -menu .m3
    menu .m2
    .m2 add command -label "two"
    menu .m3
    .m3 add command -label "three"
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
    $tearoff postcascade 1
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-16.3 {TkPostSubMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test -menu .m2
    .m1 postcascade 1
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-16.4 {TkPostSubMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-16.5 {TkPostSubMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2 -postcommand "glorp"
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade test
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid command name "glorp"}
test menuDraw-16.6 {TkPostSubMenu} -constraints {
    win userInteraction
} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to get rid of this menu"
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-17.1 {AdjustMenuCoords - menubar} -constraints unix -setup {
    deleteWindows
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label test -menu .m2
    menu .m2 -tearoff 0
    .m2 add command -label foo
    . configure -menu .m1
    foreach w [winfo children .] {
        if {[$w cget -type] == "menubar"} {
            break
        }
    }
    list [$w postcascade 0] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menuDraw-17.2 {AdjustMenuCoords - menu} -constraints {
    win userInteraction
} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to make this menu go away"
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
} -cleanup {
    deleteWindows
} -result {}

# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:



|
|





<
<

|
<
|
|
<
<
|

<
|
<
|

|
<
<
<
|

|
<
|

|
<
|
<
<
|
>
|


|
|
|
<
|
|
|
<
|
<
|

|
<
|
|
<
<
|
|
<
|

|
<
<
|
|
<
|
|
<
<
|

<
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|


|
<
<
|
|
<
|



|
<
<
|
|
<
|



|
<
<
|
|
<
|


|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
<
|

|
<
|




|
<
<
|
|
<
|



|
<
<
|


|
<
|
<
<



|
<
<
|


|
<
|







|
|
<
|

|
<
<
<
|



|
<
|



|
<
<
|
|
<
|


|
<
<
|
|
<
|


|
<
<
|
|
<
|




|
<
<
<
|

|
|
<
|
|
>
>
>
>
>
>
>
|
>
>
>






<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<






|
<
<
|


|
<
|



|
<
<
|
|
<
|


|
<
<
|
|
<
|



|
<
<
|
|
<
|




|
<
<
|
|
<
|





|
<
<
|
|
<
|





|
<
<
|
|
<
|








|
<
<
|
|
<
|
<
<



<
|
<
<
|
|
<
|




|
<
<
<
|

|
|
|






|
<
<
|
|
<
|



|
<
<
|



|
<
|

|
|
|
<
|



|
<
|

|
<
|





|
<
<
|
|
<
|




|
<
<
<
|

|
<
|


|
|
<
<
|
<
|



|
<
<
|
|
>
|
>
>
>
<
<
<
<
<
|
|
<
|



|
|
<
|



|
|
<
<
|
<
|



|
|
<
<


|
|
|






|
<
<
|
|
|
|
>









|
<
<
|
|
<
|


|
<
<
|
|
<
|



|
<
<
|
|
|
|




|
<
<
|
|
<
|
<
|





|
<
<
<
|

|
|
|






|
|
|

|
<
<
|
|
<
|
<
|





|
<
<
|


<



<
<
<
<
1
2
3
4
5
6
7
8
9
10


11
12

13
14


15
16

17

18
19
20



21
22
23

24
25
26

27


28
29
30
31
32
33
34
35

36
37
38

39

40
41
42

43
44


45
46

47
48
49


50
51

52
53


54
55

56

57
58
59


60
61

62
63
64


65
66

67
68
69
70


71
72

73
74
75
76
77


78
79

80
81
82
83
84


85
86

87
88
89
90


91
92

93
94
95


96
97

98
99
100


101
102

103
104
105


106
107

108
109
110


111
112

113
114
115


116
117

118
119
120


121
122

123
124
125
126


127
128

129
130
131
132


133
134

135
136
137
138


139
140

141
142
143
144



145
146
147

148
149
150
151
152
153


154
155

156
157
158
159
160


161
162
163
164

165


166
167
168
169


170
171
172
173

174
175
176
177
178
179
180
181
182
183

184
185
186



187
188
189
190
191

192
193
194
195
196


197
198

199
200
201
202


203
204

205
206
207
208


209
210

211
212
213
214
215
216



217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240


241
















242
243

244


245
246
247
248
249
250
251


252
253
254
255

256
257
258
259
260


261
262

263
264
265
266


267
268

269
270
271
272
273


274
275

276
277
278
279
280
281


282
283

284
285
286
287
288
289
290


291
292

293
294
295
296
297
298
299


300
301

302
303
304
305
306
307
308
309
310
311


312
313

314


315
316
317

318


319
320

321
322
323
324
325
326



327
328
329
330
331
332
333
334
335
336
337
338


339
340

341
342
343
344
345


346
347
348
349
350

351
352
353
354
355

356
357
358
359
360

361
362
363

364
365
366
367
368
369
370


371
372

373
374
375
376
377
378



379
380
381

382
383
384
385
386


387

388
389
390
391
392


393
394
395
396
397
398
399





400
401

402
403
404
405
406
407

408
409
410
411
412
413


414

415
416
417
418
419
420


421
422
423
424
425
426
427
428
429
430
431
432


433
434
435
436
437
438
439
440
441
442
443
444
445
446
447


448
449

450
451
452
453


454
455

456
457
458
459
460


461
462
463
464
465
466
467
468
469


470
471

472

473
474
475
476
477
478
479



480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495


496
497

498

499
500
501
502
503
504
505


506
507
508

509
510
511




# This file is a Tcl script to test drawing of menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



test menuDraw-1.1 {TkMenuInitializeDrawingFields} {

    catch {destroy .m1}
    list [menu .m1] [destroy .m1]


} {.m1 {}}


test menuDraw-2.1 {TkIntializeMenuEntryDrawingFields} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command] [destroy .m1]



} {{} {}}

test menuDraw-3.1 {TkMenuFreeDrawOptions} {

    catch {destroy .m1}
    menu .m1
    list [destroy .m1]

} {{}}



test menuDraw-4.1 {TkMenuEntryFreeDrawOptions} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "This is a test"
    list [destroy .m1]
} {{}}
test menuDraw-4.2 {TkMenuEntryFreeDrawOptions} {

	catch {destroy .m1}
	menu .m1
	.m1 add checkbutton -label "This is a test." -font "Courier 12" -activeforeground red -background green -selectcolor purple

	list [destroy .m1]

} {{}}

test menuDraw-5.1 {TkMenuConfigureDrawOptions - new menu} {

    catch {destroy .m1}
    list [menu .m1] [destroy .m1]


} {.m1 {}}
test menuDraw-5.2 {TkMenuConfigureDrawOptions - old menu} {

    catch {destroy .m1}
    menu .m1
    list [.m1 configure -fg red] [destroy .m1]


} {{} {}}
test menuDraw-5.3 {TkMenuConfigureDrawOptions - no disabledFg} {

	catch {destroy .m1}
	list [menu .m1 -disabledforeground ""] [destroy .m1]


} {.m1 {}}


test menuDraw-6.1 {TkMenuConfigureEntryDrawOptions - no tkfont specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo"] [destroy .m1]


} {{} {}}
test menuDraw-6.2 {TkMenuConfigureEntryDrawOptions - tkfont specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -font "Courier 12"] [destroy .m1]


} {{} {}}
test menuDraw-6.3 {TkMenuConfigureEntryDrawOptions - active state - wrong entry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    list [.m1 entryconfigure 1 -state active] [destroy .m1]


} {{} {}}
test menuDraw-6.4 {TkMenuConfigureEntryDrawOptions - active state - correct entry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    .m1 activate 1
    list [.m1 entryconfigure 1 -state active] [destroy .m1]


} {{} {}}
test menuDraw-6.5 {TkMenuConfigureEntryDrawOptions - deactivate entry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    .m1 activate 1
    list [.m1 entryconfigure 1 -state normal] [destroy .m1]


} {{} {}}
test menuDraw-6.6 {TkMenuConfigureEntryDrawOptions - bad state} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    list [catch {.m1 entryconfigure 1 -state foo} msg] $msg [destroy .m1]


} {1 {bad state "foo": must be active, normal, or disabled} {}}
test menuDraw-6.7 {TkMenuConfigureEntryDrawOptions - tkfont specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -font "Courier 12"] [destroy .m1]


} {{} {}}
test menuDraw-6.8 {TkMenuConfigureEntryDrawOptions - border specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -background "red"] [destroy .m1]


} {{} {}}
test menuDraw-6.9 {TkMenuConfigureEntryDrawOptions - foreground specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -foreground "red"] [destroy .m1]


} {{} {}}
test menuDraw-6.10 {TkMenuConfigureEntryDrawOptions - activeBorder specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -activebackground "red"] [destroy .m1]


} {{} {}}
test menuDraw-6.11 {TkMenuConfigureEntryDrawOptions - activeforeground specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add command -label "foo" -activeforeground "red"] [destroy .m1]


} {{} {}}
test menuDraw-6.12 {TkMenuConfigureEntryDrawOptions - selectcolor specified} {

    catch {destroy .m1}
    menu .m1
    list [.m1 add radiobutton -label "foo" -selectcolor "red"] [destroy .m1]


} {{} {}}
test menuDraw-6.13 {TkMenuConfigureEntryDrawOptions - textGC disposal} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo" -font "Helvetica 12"
    list [.m1 entryconfigure 1 -font "Courier 12"] [destroy .m1]


} {{} {}}
test menuDraw-6.14 {TkMenuConfigureEntryDrawOptions - activeGC disposal} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo" -activeforeground "red"
    list [.m1 entryconfigure 1 -activeforeground "green"] [destroy .m1]


} {{} {}}
test menuDraw-6.15 {TkMenuConfigureEntryDrawOptions - disabledGC disposal} {

    catch {destroy .m1}
    menu .m1 -disabledforeground "red"
    .m1 add command -label "foo"
    list [.m1 configure -disabledforeground "green"] [destroy .m1]


} {{} {}}
test menuDraw-6.16 {TkMenuConfigureEntryDrawOptions - indicatorGC disposal} {

    catch {destroy .m1}
    menu .m1
    .m1 add radiobutton -label "foo" -selectcolor "red"
    list [.m1 entryconfigure 1 -selectcolor "green"] [destroy .m1]



} {{} {}}

test menuDraw-7.1 {TkEventuallyRecomputeMenu} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "This is a long label"
    set tearoff [tk::TearOffMenu .m1]
    update idletasks
    list [.m1 entryconfigure 1 -label "foo"] [destroy .m1]


} {{} {}}
test menuDraw-7.2 {TkEventuallyRecomputeMenu - update pending} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "This is a long label"
    set tearoff [tk::TearOffMenu .m1]
    list [.m1 entryconfigure 1 -label "foo"] [destroy .m1]


} {{} {}}


test menuDraw-8.1 {TkRecomputeMenu} {win userInteraction} {

    catch {destroy .m1}


    menu .m1
    .m1 configure -postcommand [.m1 add command -label foo]
    .m1 add command -label "Hit ESCAPE to make this menu go away."
    list [.m1 post 0 0] [destroy .m1]


} {{} {}}


test menuDraw-9.1 {TkEventuallyRedrawMenu - entry test} {

    catch {destroy .m1}
    catch {unset foo}
    menu .m1
    set foo 0
    .m1 add radiobutton -variable foo -label test
    tk::TearOffMenu .m1
    update idletasks
    list [set foo test] [destroy .m1] [unset foo]
} {test {} {}}
test menuDraw-9.2 {TkEventuallyRedrawMenu - whole menu} {

    catch {destroy .m1}
    menu .m1
    list [catch {tk::TearOffMenu .m1}] [destroy .m1]



} {0 {}}

# Don't know how to test when window has been deleted and ComputeMenuGeometry
# gets called.
test menuDraw-10.1 {ComputeMenuGeometry - menubar} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label test
    . configure -menu .m1
    list [update idletasks] [. configure -menu ""] [destroy .m1]


} {{} {} {}}
test menuDraw-10.2 {ComputeMenuGeometry - non-menubar} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label test
    list [update idletasks] [destroy .m1]


} {{} {}}
test menuDraw-10.3 {ComputeMenuGeometry - Resize necessary} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label test
    list [update idletasks] [destroy .m1]


} {{} {}}
test menuDraw-10.4 {ComputeMenuGeometry - resize not necessary} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label test
    update idletasks
    .m1 entryconfigure 1 -label test
    list [update idletasks] [destroy .m1]



} {{} {}}

test menuDraw-11.1 {TkMenuSelectImageProc - entry selected; redraw not pending} testImageType {
    catch {destroy .m1}

    catch {eval image delete [image names]}
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    update idletasks
    list [image delete image2] [destroy .m1] [eval image delete [image names]]
} {{} {} {}}
test menuDraw-11.2 {TkMenuSelectImageProc - entry selected; redraw pending} testImageType {
    catch {destroy .m1}
    catch {eval image delete [image names]}
    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]

    list [image delete image2] [destroy .m1] [eval image delete [image names]]


} {{} {} {}}
















test menuDraw-11.3 {TkMenuSelectImageProc - entry not selected} testImageType {
    catch {destroy .m1}

    catch {eval image delete [image names]}


    image create test image1
    image create test image2
    menu .m1
    .m1 add checkbutton -image image1 -selectimage image2
    set tearoff [tk::TearOffMenu .m1 40 40]
    update idletasks
    list [image delete image2] [destroy .m1] [eval image delete [image names]]


} {{} {} {}}

#Don't know how to test missing tkwin in DisplayMenu
test menuDraw-12.1 {DisplayMenu - menubar background} unix {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -label foo -menu .m2
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]


} {{} {} {}}
test menuDraw-12.2 {Display menu - no entries} {

    catch {destroy .m1}
    menu .m1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw-12.3 {DisplayMenu - one entry} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw-12.4 {DisplayMenu - two entries} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw.12.5 {DisplayMenu - two columns - first bigger} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    .m1 add command -label "three" -columnbreak 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw-12.5 {DisplayMenu - two column - second  bigger} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two" -columnbreak 1
    .m1 add command -label "three"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw.12.7 {DisplayMenu - three columns} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two" -columnbreak 1
    .m1 add command -label "three"
    .m1 add command -label "four"
    .m1 add command -label "five"
    .m1 add command -label "six"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]


} {{} {}}
test menuDraw-12.6 {Display menu - testing for extra space and menubars} unix {

    catch {destroy .m1}


    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1

    list [update] [. configure -menu ""] [destroy .m1]


} {{} {} {}}
test menuDraw-12.7 {Display menu - extra space at end of menu} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    wm geometry $tearoff 200x100
    list [update] [destroy .m1]



} {{} {}}

test menuDraw-13.1 {TkMenuEventProc - Expose} {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add command -label "one"
    menu .m2
    .m2 add command -label "two"
    set tearoff1 [tk::TearOffMenu .m1 40 40]
    set tearoff2 [tk::TearOffMenu .m2 40 40]
    list [raise $tearoff2] [update] [destroy .m1] [destroy .m2]


} {{} {} {} {}}
test menuDraw-13.2 {TkMenuEventProc - ConfigureNotify} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [wm geometry $tearoff 200x100] [update] [destroy .m1]


} {{} {} {}}
# Testing deletes is hard, and I am going to do my best. Don't know how
# to test the case where we have already cleared the tkwin field in the
# menuPtr.
test menuDraw-13.4 {TkMenuEventProc - simple delete} {

    catch {destroy .m1}
    menu .m1
    list [destroy .m1]
} {{}}
test menuDraw-13.5 {TkMenuEventProc - nothing pending} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label foo
    update idletasks
    list [destroy .m1]

} {{}}

test menuDraw-14.1 {TkMenuImageProc} testImageType {

    catch {destroy .m1}
    catch {image delete image1}
    menu .m1
    image create test image1
    .m1 add command -image image1
    update idletasks
    list [image delete image1] [destroy .m1]


} {{} {}}
test menuDraw-14.2 {TkMenuImageProc} testImageType {

    catch {destroy .m1}
    catch {image delete image1}
    menu .m1
    image create test image1
    .m1 add command -image image1
    list [image delete image1] [destroy .m1]



} {{} {}}

test menuDraw-15.1 {TkPostTearoffMenu - Basic posting} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]
} {0 {}}


test menuDraw-15.2 {TkPostTearoffMenu - Deactivation} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo" -state active
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [$tearoff index active] [destroy .m1]


} {none {}}
test menuDraw-15.3 {TkPostTearoffMenu - post command} {
    catch {destroy .m1}
    catch {unset foo}
    menu .m1 -postcommand "set foo .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40}] [set foo] [unset foo] [destroy .m1]





} {0 .m1 {} {}}
test menuDraw-15.4 {TkPostTearoffMenu - post command deleting the menu} {

    catch {destroy .m1}
    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40} msg] $msg [winfo exists .m1]
} {0 {} 0}
test menuDraw-15.5 {TkPostTearoffMenu - tearoff at edge of screen} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    set height [winfo screenheight .m1]
    list [catch {tk::TearOffMenu .m1 40 $height}] [destroy .m1]
} {0 {}}


test menuDraw-15.6 {TkPostTearoffMenu - tearoff off right} {

    catch {destroy .m1}
    menu .m1
    .m1 add command -label "foo"
    set width [winfo screenwidth .m1]
    list [catch {tk::TearOffMenu .m1 $width 40}] [destroy .m1]
} {0 {}}




test menuDraw-16.1 {TkPostSubmenu} nonUnixUserInteraction {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to make this menu go away."
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
    list [$tearoff postcascade 0] [destroy .m1] [destroy .m2]


} {{} {} {}}
test menuDraw-16.2 {TkPostSubMenu} nonUnixUserInteraction {
    catch {destroy .m1}
    catch {destroy .m2}
    catch {destroy .m3}
    menu .m1
    .m1 add cascade -label "two" -menu .m2
    .m1 add cascade -label "three" -menu .m3
    menu .m2
    .m2 add command -label "two"
    menu .m3
    .m3 add command -label "three"
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff postcascade 0
    list [$tearoff postcascade 1] [destroy .m1] [destroy .m2] [destroy .m3]


} {{} {} {} {}}
test menuDraw-16.3 {TkPostSubMenu} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -label test -menu .m2
    list [.m1 postcascade 1] [destroy .m1]


} {{} {}}
test menuDraw-16.4 {TkPostSubMenu} {

    catch {destroy .m1}
    menu .m1
    .m1 add cascade -label test
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [$tearoff postcascade 0] [destroy .m1]


} {{} {}}
test menuDraw-16.5 {TkPostSubMenu} unix {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2 -postcommand "glorp"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {$tearoff postcascade test} msg] $msg [destroy .m1] [destroy .m2]


} {1 {invalid command name "glorp"} {} {}}
test menuDraw-16.6 {TkPostSubMenu} {win userInteraction} {

    catch {destroy .m1}

    catch {destroy .m2}
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to get rid of this menu"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [$tearoff postcascade 0] [destroy .m1] [destroy .m2]



} {{} {} {}}

test menuDraw-17.1 {AdjustMenuCoords - menubar} unix {
    catch {destroy .m1}
    catch {destroy .m2}
    menu .m1 -tearoff 0
    .m1 add cascade -label test -menu .m2
    menu .m2 -tearoff 0
    .m2 add command -label foo
    . configure -menu .m1
    foreach w [winfo children .] {
	if {[$w cget -type] == "menubar"} {
		break
	}
    }
    list [$w postcascade 0] [. configure -menu ""] [destroy .m1] [destroy .m2]


} {{} {} {} {}}
test menuDraw-17.2 {AdjustMenuCoords - menu} {win userInteraction} {

    catch {destroy .m1}

    catch {destroy .m2}
    menu .m1
    .m1 add cascade -label test -menu .m2
    menu .m2
    .m2 add command -label "Hit ESCAPE to make this menu go away"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [$tearoff postcascade 0] [destroy .m1] [destroy .m2]


} {{} {} {}}

# cleanup

deleteWindows
cleanupTests
return




Changes to tests/menubut.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28



29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72






73
74
75
76


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645




646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747

748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
# This file is a Tcl script to test menubuttons in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

# XXX This test file is woefully incomplete right now.  If any part
# XXX of a procedure has tests then the whole procedure has tests,
# XXX but many procedures have no tests.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Menubutton.borderWidth 2
option add *Menubutton.highlightThickness 2
option add *Menubutton.font {Helvetica -12 bold}
option add *Button.borderWidth 2
option add *Button.highlightThickness 2
option add *Button.font {Helvetica -12 bold}





menubutton .mb -text "Test"
pack .mb
update

test menubutton-1.1 {configuration options} -body {
    .mb configure -activebackground #012345
    .mb cget -activebackground
} -cleanup {
    .mb configure -activebackground [lindex [.mb configure -activebackground] 3]
} -result {#012345}
test menubutton-1.2 {configuration options} -body {
    .mb configure -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test menubutton-1.3 {configuration options} -body {
    .mb configure -activeforeground #ff0000
    .mb cget -activeforeground
} -cleanup {
    .mb configure -activeforeground [lindex [.mb configure -activeforeground] 3]
} -result {#ff0000}
test menubutton-1.4 {configuration options} -body {
    .mb configure -activeforeground non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test menubutton-1.5 {configuration options} -body {
    .mb configure -anchor nw
    .mb cget -anchor
} -cleanup {
    .mb configure -anchor [lindex [.mb configure -anchor] 3]
} -result {nw}
test menubutton-1.6 {configuration options} -body {
    .mb configure -anchor bogus
} -returnCodes error -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}
test menubutton-1.7 {configuration options} -body {
    .mb configure -background #ff0000
    .mb cget -background
} -cleanup {
    .mb configure -background [lindex [.mb configure -background] 3]
} -result {#ff0000}
test menubutton-1.8 {configuration options} -body {
    .mb configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test menubutton-1.9 {configuration options} -body {
    .mb configure -bd 4
    .mb cget -bd
} -cleanup {






    .mb configure -bd [lindex [.mb configure -bd] 3]
} -result 4
test menubutton-1.10 {configuration options} -body {
    .mb configure -bd badValue


} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.11 {configuration options} -body {
    .mb configure -bg #ff0000
    .mb cget -bg
} -cleanup {
    .mb configure -bg [lindex [.mb configure -bg] 3]
} -result {#ff0000}
test menubutton-1.12 {configuration options} -body {
    .mb configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test menubutton-1.13 {configuration options} -body {
    .mb configure -bitmap questhead
    .mb cget -bitmap
} -cleanup {
    .mb configure -bitmap [lindex [.mb configure -bitmap] 3]
} -result {questhead}
test menubutton-1.14 {configuration options} -body {
    .mb configure -bitmap badValue
} -returnCodes error -result {bitmap "badValue" not defined}
test menubutton-1.15 {configuration options} -body {
    .mb configure -borderwidth 1.3
    .mb cget -borderwidth
} -cleanup {
    .mb configure -borderwidth [lindex [.mb configure -borderwidth] 3]
} -result 1
test menubutton-1.16 {configuration options} -body {
    .mb configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.17 {configuration options} -body {
    .mb configure -cursor arrow
    .mb cget -cursor
} -cleanup {
    .mb configure -cursor [lindex [.mb configure -cursor] 3]
} -result {arrow}
test menubutton-1.18 {configuration options} -body {
    .mb configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test menubutton-1.19 {configuration options} -body {
    .mb configure -direction below
    .mb cget -direction
} -cleanup {
    .mb configure -direction [lindex [.mb configure -direction] 3]
} -result {below}
test menubutton-1.20 {configuration options} -body {
    .mb configure -direction badValue
} -returnCodes error -result {bad direction "badValue": must be above, below, flush, left, or right}
test menubutton-1.21 {configuration options} -body {
    .mb configure -disabledforeground #00ff00
    .mb cget -disabledforeground
} -cleanup {
    .mb configure -disabledforeground [lindex [.mb configure -disabledforeground] 3]
} -result {#00ff00}
test menubutton-1.22 {configuration options} -body {
    .mb configure -disabledforeground xyzzy
} -returnCodes error -result {unknown color name "xyzzy"}
test menubutton-1.23 {configuration options} -body {
    .mb configure -fg #110022
    .mb cget -fg
} -cleanup {
    .mb configure -fg [lindex [.mb configure -fg] 3]
} -result {#110022}
test menubutton-1.24 {configuration options} -body {
    .mb configure -fg bogus
} -returnCodes error -result {unknown color name "bogus"}
test menubutton-1.25 {configuration options} -body {
    .mb configure -font {Helvetica 12}
    .mb cget -font
} -cleanup {
    .mb configure -font [lindex [.mb configure -font] 3]
} -result {Helvetica 12}
test menubutton-1.26 {configuration options} -body {
    .mb configure -foreground #110022
    .mb cget -foreground
} -cleanup {
    .mb configure -foreground [lindex [.mb configure -foreground] 3]
} -result {#110022}
test menubutton-1.27 {configuration options} -body {
    .mb configure -foreground bogus
} -returnCodes error -result {unknown color name "bogus"}
test menubutton-1.28 {configuration options} -body {
    .mb configure -height 18
    .mb cget -height
} -cleanup {
    .mb configure -height [lindex [.mb configure -height] 3]
} -result 18
test menubutton-1.29 {configuration options} -body {
    .mb configure -height 20.0
} -returnCodes error -result {expected integer but got "20.0"}
test menubutton-1.30 {configuration options} -body {
    .mb configure -highlightbackground #112233
    .mb cget -highlightbackground
} -cleanup {
    .mb configure -highlightbackground [lindex [.mb configure -highlightbackground] 3]
} -result {#112233}
test menubutton-1.31 {configuration options} -body {
    .mb configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test menubutton-1.32 {configuration options} -body {
    .mb configure -highlightcolor #110022
    .mb cget -highlightcolor
} -cleanup {
    .mb configure -highlightcolor [lindex [.mb configure -highlightcolor] 3]
} -result {#110022}
test menubutton-1.33 {configuration options} -body {
    .mb configure -highlightcolor bogus
} -returnCodes error -result {unknown color name "bogus"}
test menubutton-1.34 {configuration options} -body {
    .mb configure -highlightthickness 18
    .mb cget -highlightthickness
} -cleanup {
    .mb configure -highlightthickness [lindex [.mb configure -highlightthickness] 3]
} -result 18
test menubutton-1.35 {configuration options} -body {
    .mb configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.36 {configuration options} -constraints {
    testImageType
} -setup {
    catch {image delete image1}
    image create test image1
} -body {
    .mb configure -image image1
    .mb cget -image
} -cleanup {
    .mb configure -image [lindex [.mb configure -image] 3]
    image create test image1
} -result {image1}
test menubutton-1.37 {configuration options} -setup {
    catch {image delete bogus}
} -body {

    .mb configure -image bogus
} -cleanup {

    .mb configure -image [lindex [.mb configure -image] 3]
} -returnCodes error -result {image "bogus" doesn't exist}
test menubutton-1.38 {configuration options} -body {
    .mb configure -indicatoron yes
    .mb cget -indicatoron
} -cleanup {
    .mb configure -indicatoron [lindex [.mb configure -indicatoron] 3]
} -result 1
test menubutton-1.39 {configuration options} -body {
    .mb configure -indicatoron no_way
} -returnCodes error -result {expected boolean value but got "no_way"}
test menubutton-1.40 {configuration options} -body {
    .mb configure -justify right
    .mb cget -justify
} -cleanup {
    .mb configure -justify [lindex [.mb configure -justify] 3]
} -result {right}
test menubutton-1.41 {configuration options} -body {
    .mb configure -justify bogus
} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
test menubutton-1.42 {configuration options} -body {
    .mb configure -menu {any old string}
    .mb cget -menu
} -cleanup {
    .mb configure -menu [lindex [.mb configure -menu] 3]
} -result {any old string}
test menubutton-1.43 {configuration options} -body {
    .mb configure -padx 12
    .mb cget -padx
} -cleanup {
    .mb configure -padx [lindex [.mb configure -padx] 3]
} -result 12
test menubutton-1.44 {configuration options} -body {
    .mb configure -padx 420x
} -returnCodes error -result {bad screen distance "420x"}
test menubutton-1.45 {configuration options} -body {
    .mb configure -pady 12
    .mb cget -pady
} -cleanup {
    .mb configure -pady [lindex [.mb configure -pady] 3]
} -result 12
test menubutton-1.46 {configuration options} -body {
    .mb configure -pady 420x
} -returnCodes error -result {bad screen distance "420x"}
test menubutton-1.47 {configuration options} -body {
    .mb configure -relief groove
    .mb cget -relief
} -cleanup {
    .mb configure -relief [lindex [.mb configure -relief] 3]
} -result {groove}
test menubutton-1.48 {configuration options} -body {
    .mb configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test menubutton-1.49 {configuration options} -body {
    .mb configure -state normal
    .mb cget -state
} -cleanup {
    .mb configure -state [lindex [.mb configure -state] 3]
} -result {normal}
test menubutton-1.50 {configuration options} -body {
    .mb configure -state bogus
} -returnCodes error -result {bad state "bogus": must be active, disabled, or normal}
test menubutton-1.51 {configuration options} -body {
    .mb configure -takefocus {any string}
    .mb cget -takefocus
} -cleanup {
    .mb configure -takefocus [lindex [.mb configure -takefocus] 3]
} -result {any string}
test menubutton-1.52 {configuration options} -body {
    .mb configure -text {Sample text}
    .mb cget -text
} -cleanup {
    .mb configure -text [lindex [.mb configure -text] 3]
} -result {Sample text}
test menubutton-1.53 {configuration options} -body {
    .mb configure -textvariable i
    .mb cget -textvariable
} -cleanup {
    .mb configure -textvariable [lindex [.mb configure -textvariable] 3]
} -result {i}
test menubutton-1.54 {configuration options} -body {
    .mb configure -underline 5
    .mb cget -underline
} -cleanup {
    .mb configure -underline [lindex [.mb configure -underline] 3]
} -result 5
test menubutton-1.55 {configuration options} -body {
    .mb configure -underline 3p
} -returnCodes error -result {expected integer but got "3p"}
test menubutton-1.56 {configuration options} -body {
    .mb configure -width 402
    .mb cget -width
} -cleanup {
    .mb configure -width [lindex [.mb configure -width] 3]
} -result 402
test menubutton-1.57 {configuration options} -body {
    .mb configure -width 3p
} -returnCodes error -result {expected integer but got "3p"}
test menubutton-1.58 {configuration options} -body {
    .mb configure -wraplength 100
    .mb cget -wraplength
} -cleanup {
    .mb configure -wraplength [lindex [.mb configure -wraplength] 3]
} -result 100
test menubutton-1.59 {configuration options} -body {
    .mb configure -wraplength 6x
} -returnCodes error -result {bad screen distance "6x"}


deleteWindows
menubutton .mb -text "Test"
pack .mb
update
test menubutton-2.1 {Tk_MenubuttonCmd procedure} -body {
    menubutton
} -returnCodes error -result {wrong # args: should be "menubutton pathName ?-option value ...?"}
test menubutton-2.2 {Tk_MenubuttonCmd procedure} -body {
    menubutton foo
} -returnCodes error -result {bad window path name "foo"}
test menubutton-2.3 {Tk_MenubuttonCmd procedure} -body {
    catch {destroy .mb}
    menubutton .mb
    winfo class .mb
} -result {Menubutton}
test menubutton-2.4 {Tk_ButtonCmd procedure} -setup {
    destroy .mb
} -body {
    menubutton .mb -gorp foo
} -returnCodes error -result {unknown option "-gorp"}
test menubutton-2.5 {Tk_ButtonCmd procedure} -setup {
    destroy .mb
} -body {
    catch {menubutton .mb -gorp foo}
    winfo exists .mb
} -result 0


deleteWindows
menubutton .mb -text "Test Menu"
pack .mb
test menubutton-3.1 {MenuButtonWidgetCmd procedure} -body {
    .mb
} -returnCodes error -result {wrong # args: should be ".mb option ?arg ...?"}
test menubutton-3.2 {ButtonWidgetCmd procedure, "cget" option} -body {
    .mb c
} -returnCodes error -result {ambiguous option "c": must be cget or configure}
test menubutton-3.3 {ButtonWidgetCmd procedure, "cget" option} -body {
    .mb cget
} -returnCodes error -result {wrong # args: should be ".mb cget option"}
test menubutton-3.4 {ButtonWidgetCmd procedure, "cget" option} -body {
    .mb cget a b
} -returnCodes error -result {wrong # args: should be ".mb cget option"}
test menubutton-3.5 {ButtonWidgetCmd procedure, "cget" option} -body {
    .mb cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menubutton-3.6 {ButtonWidgetCmd procedure, "cget" option} -body {
    .mb configure -highlightthickness 3
    .mb cget -highlightthickness
} -result 3
test menubutton-3.7 {ButtonWidgetCmd procedure, "configure" option} -body {
    llength [.mb configure]
} -result 33
test menubutton-3.8 {ButtonWidgetCmd procedure, "configure" option} -body {
    .mb configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menubutton-3.9 {ButtonWidgetCmd procedure, "configure" option} -body {
    .mb co -bg #ffffff -fg
} -returnCodes error -result {value for "-fg" missing}
test menubutton-3.10 {ButtonWidgetCmd procedure, "configure" option} -body {
    .mb configure -fg #123456
    .mb configure -bg #654321
    lindex [.mb configure -fg] 4
} -result {#123456}
test menubutton-3.11 {ButtonWidgetCmd procedure, "configure" option} -body {
    .mb foobar
} -returnCodes error -result {bad option "foobar": must be cget or configure}
deleteWindows

# XXX Need to add tests for several procedures here.   The tests for   XXX
# XXX ConfigureMenuButton aren't complete either.                      XXX

test menubutton-4.1 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -text "Menubutton 1"
    .mb1 configure -width 1i
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "1i"}
test menubutton-4.2 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -text "Menubutton 1"
    catch {.mb1 configure -width 1i}
    return $errorInfo
} -cleanup {
    deleteWindows
} -result {expected integer but got "1i"
    (processing -width option)
    invoked from within
".mb1 configure -width 1i"}

test menubutton-4.3 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -text "Menubutton 1"
    .mb1 configure -height 0.5c
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "0.5c"}
test menubutton-4.4 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -text "Menubutton 1"
    catch {.mb1 configure -height 0.5c}
    return $errorInfo
} -cleanup {
    deleteWindows
} -result {expected integer but got "0.5c"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5c"}

test menubutton-4.5 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    .mb1 configure -width abc
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad screen distance "abc"}
test menubutton-4.6 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    catch {.mb1 configure -width abc}
    return $errorInfo
} -cleanup {
    deleteWindows
} -result {bad screen distance "abc"
    (processing -width option)
    invoked from within
".mb1 configure -width abc"}

test menubutton-4.7 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    .mb1 configure -height 0.5x
} -cleanup {
    deleteWindows
    imageCleanup
} -returnCodes error -result {bad screen distance "0.5x"}
test menubutton-4.8 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    catch {.mb1 configure -height 0.5x}
    return $errorInfo
} -cleanup {
    deleteWindows
    imageCleanup
} -result {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5x"}

test menubutton-4.9 {ConfigureMenuButton procedure} -constraints {
    nonPortable fonts
} -setup {
    deleteWindows
} -body {
    button .mb1 -text "Sample text" -width 10 -height 2
    pack .mb1
    set result "[winfo reqwidth .mb1] [winfo reqheight .mb1]"
    .mb1 configure -bitmap questhead
    lappend result [winfo reqwidth .mb1] [winfo reqheight .mb1]
} -cleanup {
    deleteWindows
} -result {102 46 20 12}

test menubutton-4.10 {ConfigureMenuButton procedure - bad direction} -setup {
    deleteWindows
} -body {
    menubutton .mb -text "Test"
    .mb configure -direction badValue
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad direction "badValue": must be above, below, flush, left, or right}
test menubutton-4.11 {ConfigureMenuButton procedure - bad direction} -setup {
    deleteWindows
} -body {
    menubutton .mb -text "Test"
    catch {.mb configure -direction badValue}
    list [.mb cget -direction] [destroy .mb]
} -cleanup {
    deleteWindows
} -result {below {}}



# XXX Need to add tests for several procedures here. XXX

test menubutton-5.1 {MenuButtonEventProc procedure} -setup {
    deleteWindows
    set x {}
} -body {
    menubutton .mb1 -bg #543210
    rename .mb1 .mb2

    lappend x [winfo children .]
    lappend x [.mb2 cget -bg]
    destroy .mb1
    lappend x [info command .mb*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {.mb1 #543210 {} {}}


test menubutton-6.1 {MenuButtonCmdDeletedProc procedure} -setup {
    deleteWindows
} -body {
    menubutton .mb1
    rename .mb1 {}
    list [info command .mb*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}

if {[tk windowingsystem] == "aqua"} {
    set extraWidth 36
} else {
    set extraWidth 0
}
test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    image create test image1
} -body {
    menubutton .mb -image image1 -bd 4 -highlightthickness 0
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.2 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    image create test image1
} -body {
    menubutton .mb -image image1 -bd 3 -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.3 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    image create test image1
} -body {
    menubutton .mb -image image1 -bd 1 -highlightthickness 3 -padx 5 -pady 5
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result [list [expr {38 + $extraWidth}] 23]
test menubutton-7.4 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    image create test image1
} -body {
    menubutton .mb -image image1 -bd 2 -relief raised -width 40 \
        -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result [list [expr {48 + $extraWidth}] 23]
test menubutton-7.5 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    image create test image1
} -body {
    menubutton .mb -image image1 -bd 2 -relief raised -height 30 \
        -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result [list [expr {38 + $extraWidth}] 38]
test menubutton-7.6 {ComputeMenuButtonGeometry procedure} -setup {
    deleteWindows
} -body {
    menubutton .mb -bitmap question -bd 2 -relief raised \
        -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result [list [expr {25 + $extraWidth}] 35]
test menubutton-7.7 {ComputeMenuButtonGeometry procedure} -setup {
    deleteWindows
} -body {
    menubutton .mb -bitmap question -bd 2 -relief raised -width 40 \
        -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result [list [expr {46 + $extraWidth}] 33]
test menubutton-7.8 {ComputeMenuButtonGeometry procedure} -setup {
    deleteWindows
} -body {
    menubutton .mb -bitmap question -bd 2 -relief raised -height 50 \
        -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {

    deleteWindows




} -result [list [expr {23 + $extraWidth}] 56]
test menubutton-7.9 {ComputeMenuButtonGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    menubutton .mb -text String -bd 2 -relief raised -padx 0 -pady 0 \
        -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result {42 20}
test menubutton-7.10 {ComputeMenuButtonGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    menubutton .mb -text String -bd 2 -relief raised -width 20 \
        -padx 0 -pady 0 -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result {146 20}
test menubutton-7.11 {ComputeMenuButtonGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    menubutton .mb -text String -bd 2 -relief raised -height 2 \
        -padx 0 -pady 0 -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result {42 34}
test menubutton-7.12 {ComputeMenuButtonGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    menubutton .mb -text String -bd 2 -relief raised -padx 10 -pady 5 \
        -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result {62 30}
test menubutton-7.13 {ComputeMenuButtonGeometry procedure} -constraints {
    nonPortable fonts
} -setup {
    deleteWindows
} -body {
    menubutton .mb -text String -bd 2 -relief raised \
        -highlightthickness 1 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
} -result {78 28}
test menubutton-7.14 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType unix nonPortable
} -setup {
    deleteWindows
    image create test image1
} -body {
    # The following test is non-portable because the indicator's pixel
    # size varies to maintain constant absolute size.

    menubutton .mb -image image1 -bd 2 -relief raised \
        -highlightthickness 2 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result {64 23}
test menubutton-7.15 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType win nonPortable
} -setup {
    deleteWindows
    image create test image1
} -body {
    # The following test is non-portable because the indicator's pixel
    # size varies to maintain constant absolute size.


    menubutton .mb -image image1 -bd 2 -relief raised \
        -highlightthickness 2 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} -cleanup {
    deleteWindows
    imageCleanup
} -result {65 23}


test menubutton-8.1 {menubutton vs hidden commands} -body {
    set l [interp hidden]
    deleteWindows
    menubutton .mb
    interp hide {} .mb

    destroy .mb
    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 eq $res2}
} -result 1

test menubutton-9.1 {Bug [5d991b822e]} {
    # Want this not to segfault, or write to variable with empty name
    unset -nocomplain {}
    set var INIT
    menubutton .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update

    destroy .b
    info exists {}
} 0
test menubutton-9.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    menubutton .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}




deleteWindows
option clear
imageFinish

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:



|
|
|









<
<











>
>
>
|



>
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
<
>
>
>
>
>
>
|
|
|
|
>
>
|
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
|
|
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
|
>
|
<
|
<
|
<
<
<
|
<
<
|
<
<
<
<
<
|
<
|
|
<
|
<
<
<
|
<
|
<
<
<
|
<
<
|
|
|
<
<
<
|
|
<
<
<
|
<
<
<
|
|
<
|
|
|
<
<
<
|
|
|
|
|
|
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
|
<
|
|
<
<
|
<
<
<
|
|
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|



|
|
|
|
<




|
<
<
|
<
<
<
<
<
<
<

|
<
<
<
|


|
<
|
<
<
|
<
<
<
<
<
<
<

|
<
<
<
|


|
<
|
<
|

|
<
<
<
<
<
<
<
<
<
<
<
|


|
<
|
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<


|
<
<
<
<
|


|
<
|
<
<
<
|





<
<
|
<
|
<
<
|
<
<
<
<
<
<
<

|
|
<
<
<
|

<


|

<
<


>




<
<
|

<
|

<



<
<
|

<
<
<
<
<
|
|
<
<
<
<



|
<
<
<
|
|
<
<
<
<
|


|
<
<
<
|
|
<
<
<
<
|


|
<
<
<
|
|
<
<
<
<

|


|
<
<
<
|
|
<
<
<
<

|


<
<
<
|
|
<
|

|


|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
|


|
>
|
>
>
>
>
|
|
<
|
<
<

|


<
<
|
|
<
|
<
<

|


<
<
<
<
<
|
|
|

|


<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
|


|
<
<
|
<
<
<
<
<
<
<
|
|
|


|
<
<
<
|
<
<
<
<
<



>

|


|
<
|
|
|

<
<
|
|
<
>
|
|
<
<
<
|
<
<
<
<
<
|
|
<
<
|
|
>
|
<
<
<
<
<
|
<
<
<
|
<
<
|
<
<
|
|

|


<




<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36






37

38






39








40

41






42

43


44
45
46
47
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63
64
65
66
67








68



69
70



71
72

73
74























75








76




77









78

79
80





























81













82
83
84
85
86

87

88



89


90





91

92
93

94



95

96



97


98
99
100



101
102



103



104
105

106
107
108



109
110
111
112
113
114



115

116





117



118

119
120


121



122
123
124


125
126




127


128
129






















130
131




































132
133
134
135
136
137
138
139
140
141

142
143
144
145
146


147







148
149



150
151
152
153

154


155







156
157



158
159
160
161

162

163
164
165











166
167
168
169

170






171


172








173
174
175




176
177
178
179

180



181
182
183
184
185
186


187

188


189







190
191
192



193
194

195
196
197
198


199
200
201
202
203
204
205


206
207

208
209

210
211
212


213
214





215
216




217
218
219
220



221
222




223
224
225
226



227
228




229
230
231
232



233
234




235
236
237
238
239



240
241




242
243
244
245



246
247

248
249
250
251
252
253


254




255







256
257
258
259
260
261
262
263
264
265
266
267
268

269


270
271
272
273


274
275

276


277
278
279
280





281
282
283
284
285
286
287


288
289






290









291
292
293
294
295


296







297
298
299
300
301
302



303





304
305
306
307
308
309
310
311
312

313
314
315
316


317
318

319
320
321



322





323
324


325
326
327
328





329



330


331


332
333
334
335
336
337

338
339
340
341




# This file is a Tcl script to test menubuttons in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

# XXX This test file is woefully incomplete right now.  If any part
# XXX of a procedure has tests then the whole procedure has tests,
# XXX but many procedures have no tests.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Menubutton.borderWidth 2
option add *Menubutton.highlightThickness 2
option add *Menubutton.font {Helvetica -12 bold}
option add *Button.borderWidth 2
option add *Button.highlightThickness 2
option add *Button.font {Helvetica -12 bold}

eval image delete [image names]
if {[testConstraint testImageType]} {
    image create test image1
}
menubutton .mb -text "Test"
pack .mb
update
set i 1
foreach test {
    {-activebackground #012345 #012345 non-existent






	    {unknown color name "non-existent"}}

    {-activeforeground #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}








    {-anchor nw nw bogus {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}}

    {-background #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}

    {-bd 4 4 badValue {bad screen distance "badValue"}}


    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}
    {-bitmap questhead questhead badValue {bitmap "badValue" not defined}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-direction below below badValue {bad direction "badValue": must be above, below, flush, left, or right}}
    {-disabledforeground #00ff00 #00ff00 xyzzy {unknown color name "xyzzy"}}
    {-fg #110022 #110022 bogus {unknown color name "bogus"}}
    {-font {Helvetica 12} {Helvetica 12} {} {font "" doesn't exist}}
    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}
    {-height 18 18 20.0 {expected integer but got "20.0"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #110022 #110022 bogus {unknown color name "bogus"}}
    {-highlightthickness 18 18 badValue {bad screen distance "badValue"}}


    {-image image1 image1 bogus {image "bogus" doesn't exist}}
    {-indicatoron yes 1 no_way {expected boolean value but got "no_way"}}
    {-justify right right bogus {bad justification "bogus": must be left, right, or center}}
    {-menu "any old string" "any old string" {} {}}
    {-padx 12 12 420x {bad screen distance "420x"}}
    {-pady 12 12 420x {bad screen distance "420x"}}
    {-relief groove groove 1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    {-state normal normal bogus {bad state "bogus": must be active, disabled, or normal}}
    {-takefocus "any string" "any string" {} {}}
    {-text "Sample text" {Sample text} {} {}}
    {-textvariable i i {} {}}








    {-underline 5 5 3p {expected integer but got "3p"}}



    {-width 402 402 3p {expected integer but got "3p"}}
    {-wraplength 100 100 6x {bad screen distance "6x"}}



} {
    set name [lindex $test 0]

    test menubutton-1.$i {configuration options} testImageType {
	.mb configure $name [lindex $test 1]























	lindex [.mb configure $name] 4








    } [lindex $test 2]




    incr i









    if {[lindex $test 3] != ""} {

	test menubutton-1.$i {configuration options} {
	    list [catch {.mb configure $name [lindex $test 3]} msg] $msg





























	} [list 1 [lindex $test 4]]













    }
    .mb configure $name [lindex [.mb configure $name] 3]
    incr i
}


test menubutton-2.1 {Tk_MenubuttonCmd procedure} {

    list [catch {menubutton} msg] $msg



} {1 {wrong # args: should be "menubutton pathName ?options?"}}


test menubutton-2.2 {Tk_MenubuttonCmd procedure} {





    list [catch {menubutton foo} msg] $msg

} {1 {bad window path name "foo"}}
test menubutton-2.3 {Tk_MenubuttonCmd procedure} {

    catch {destroy .mb}



    menubutton .mb

    winfo class .mb



} {Menubutton}


test menubutton-2.4 {Tk_ButtonCmd procedure} {
    catch {destroy .mb}
    list [catch {menubutton .mb -gorp foo} msg] $msg [winfo exists .mb]



} {1 {unknown option "-gorp"} 0}




catch {destroy .mb}



menubutton .mb -text "Test Menu"
pack .mb

test menubutton-3.1 {MenuButtonWidgetCmd procedure} {
    list [catch {.mb} msg] $msg
} {1 {wrong # args: should be ".mb option ?arg arg ...?"}}



test menubutton-3.2 {ButtonWidgetCmd procedure, "cget" option} {
    list [catch {.mb c} msg] $msg
} {1 {ambiguous option "c": must be cget or configure}}
test menubutton-3.3 {ButtonWidgetCmd procedure, "cget" option} {
    list [catch {.mb cget} msg] $msg
} {1 {wrong # args: should be ".mb cget option"}}



test menubutton-3.4 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.mb cget a b} msg] $msg





} {1 {wrong # args: should be ".mb cget option"}}



test menubutton-3.5 {ButtonWidgetCmd procedure, "cget" option} {

    list [catch {.mb cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}


test menubutton-3.6 {ButtonWidgetCmd procedure, "cget" option} {



    .mb configure -highlightthickness 3
    .mb cget -highlightthickness
} {3}


test menubutton-3.7 {ButtonWidgetCmd procedure, "configure" option} {
    llength [.mb configure]




} {33}


test menubutton-3.8 {ButtonWidgetCmd procedure, "configure" option} {
    list [catch {.mb configure -gorp} msg] $msg






















} {1 {unknown option "-gorp"}}
test menubutton-3.9 {ButtonWidgetCmd procedure, "configure" option} {




































    list [catch {.mb co -bg #ffffff -fg} msg] $msg
} {1 {value for "-fg" missing}}
test menubutton-3.10 {ButtonWidgetCmd procedure, "configure" option} {
    .mb configure -fg #123456
    .mb configure -bg #654321
    lindex [.mb configure -fg] 4
} {#123456}
test menubutton-3.11 {ButtonWidgetCmd procedure, "configure" option} {
    list [catch {.mb foobar} msg] $msg
} {1 {bad option "foobar": must be cget or configure}}


# XXX Need to add tests for several procedures here.   The tests for   XXX
# XXX ConfigureMenuButton aren't complete either.                      XXX

test menubutton-4.1 {ConfigureMenuButton procedure} {


    catch {destroy .mb1}







    button .mb1 -text "Menubutton 1"
    list [catch {.mb1 configure -width 1i} msg] $msg $errorInfo



} {1 {expected integer but got "1i"} {expected integer but got "1i"
    (processing -width option)
    invoked from within
".mb1 configure -width 1i"}}

test menubutton-4.2 {ConfigureMenuButton procedure} {


    catch {destroy .mb1}







    button .mb1 -text "Menubutton 1"
    list [catch {.mb1 configure -height 0.5c} msg] $msg $errorInfo



} {1 {expected integer but got "0.5c"} {expected integer but got "0.5c"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5c"}}

test menubutton-4.3 {ConfigureMenuButton procedure} {

    catch {destroy .mb1}
    button .mb1 -bitmap questhead
    list [catch {.mb1 configure -width abc} msg] $msg $errorInfo











} {1 {bad screen distance "abc"} {bad screen distance "abc"
    (processing -width option)
    invoked from within
".mb1 configure -width abc"}}

test menubutton-4.4 {ConfigureMenuButton procedure} testImageType {






    catch {destroy .mb1}


    eval image delete [image names]








    image create test image1
    button .mb1 -image image1
    list [catch {.mb1 configure -height 0.5x} msg] $msg $errorInfo




} {1 {bad screen distance "0.5x"} {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5x"}}

test menubutton-4.5 {ConfigureMenuButton procedure} {nonPortable fonts} {



    catch {destroy .mb1}
    button .mb1 -text "Sample text" -width 10 -height 2
    pack .mb1
    set result "[winfo reqwidth .mb1] [winfo reqheight .mb1]"
    .mb1 configure -bitmap questhead
    lappend result [winfo reqwidth .mb1] [winfo reqheight .mb1]


} {102 46 20 12}

test menubutton-4.6 {ConfigureMenuButton procedure - bad direction} {


    catch {destroy .mb}







    menubutton .mb -text "Test"
    list [catch {.mb configure -direction badValue} msg] $msg \
	[.mb cget -direction] [destroy .mb]



} {1 {bad direction "badValue": must be above, below, flush, left, or right} below {}}


# XXX Need to add tests for several procedures here. XXX

test menubutton-5.1 {MenuButtonEventProc procedure} {
    deleteWindows


    menubutton .mb1 -bg #543210
    rename .mb1 .mb2
    set x {}
    lappend x [winfo children .]
    lappend x [.mb2 cget -bg]
    destroy .mb1
    lappend x [info command .mb*] [winfo children .]


} {.mb1 #543210 {} {}}


test menubutton-6.1 {MenuButtonCmdDeletedProc procedure} {
    deleteWindows

    menubutton .mb1
    rename .mb1 {}
    list [info command .mb*] [winfo children .]


} {{} {}}






test menubutton-7.1 {ComputeMenuButtonGeometry procedure} testImageType {
    catch {destroy .mb}




    menubutton .mb -image image1 -bd 4 -highlightthickness 0
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {38 23}



test menubutton-7.2 {ComputeMenuButtonGeometry procedure} testImageType {
    catch {destroy .mb}




    menubutton .mb -image image1 -bd 1 -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {36 21}



test menubutton-7.3 {ComputeMenuButtonGeometry procedure} testImageType {
    catch {destroy .mb}




    menubutton .mb -image image1 -bd 0 -highlightthickness 2 -padx 5 -pady 5
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {34 19}



test menubutton-7.4 {ComputeMenuButtonGeometry procedure} testImageType {
    catch {destroy .mb}




    menubutton .mb -image image1 -bd 2 -relief raised -width 40 \
	    -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {48 23}



test menubutton-7.5 {ComputeMenuButtonGeometry procedure} testImageType {
    catch {destroy .mb}




    menubutton .mb -image image1 -bd 2 -relief raised -height 30 \
	    -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]



} {38 38}
test menubutton-7.6 {ComputeMenuButtonGeometry procedure} {

    catch {destroy .mb}
    menubutton .mb -bitmap question -bd 2 -relief raised \
	    -highlightthickness 2
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {25 35}


test menubutton-7.7 {ComputeMenuButtonGeometry procedure} {




    catch {destroy .mb}







    menubutton .mb -bitmap question -bd 2 -relief raised -width 40 \
	    -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {46 33}
test menubutton-7.8 {ComputeMenuButtonGeometry procedure} {
    catch {destroy .mb}
    menubutton .mb -bitmap question -bd 2 -relief raised -height 50 \
	    -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {23 56}
test menubutton-7.9 {ComputeMenuButtonGeometry procedure} {fonts} {

    catch {destroy .mb}


    menubutton .mb -text String -bd 2 -relief raised -padx 0 -pady 0 \
	    -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]


} {42 20}
test menubutton-7.10 {ComputeMenuButtonGeometry procedure} {fonts} {

    catch {destroy .mb}


    menubutton .mb -text String -bd 2 -relief raised -width 20 \
	    -padx 0 -pady 0 -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]





} {146 20}
test menubutton-7.11 {ComputeMenuButtonGeometry procedure} {fonts} {
    catch {destroy .mb}
    menubutton .mb -text String -bd 2 -relief raised -height 2 \
	    -padx 0 -pady 0 -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]


} {42 34}
test menubutton-7.12 {ComputeMenuButtonGeometry procedure} {fonts} {






    catch {destroy .mb}









    menubutton .mb -text String -bd 2 -relief raised -padx 10 -pady 5 \
	    -highlightthickness 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {62 30}


test menubutton-7.13 {ComputeMenuButtonGeometry procedure} {nonPortable fonts} {







    catch {destroy .mb}
    menubutton .mb -text String -bd 2 -relief raised \
	    -highlightthickness 1 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {78 28}



test menubutton-7.14 {ComputeMenuButtonGeometry procedure} {testImageType unix nonPortable} {





    # The following test is non-portable because the indicator's pixel
    # size varies to maintain constant absolute size.

    catch {destroy .mb}
    menubutton .mb -image image1 -bd 2 -relief raised \
	    -highlightthickness 2 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]
} {64 23}

test menubutton-7.15 {ComputeMenuButtonGeometry procedure} {testImageType win nonPortable} {
    # The following test is non-portable because the indicator's pixel
    # size varies to maintain constant absolute size.



    catch {destroy .mb}
    menubutton .mb -image image1 -bd 2 -relief raised \

	    -highlightthickness 2 -indicatoron 1
    pack .mb
    list [winfo reqwidth .mb] [winfo reqheight .mb]



} {65 23}






set l [interp hidden]


deleteWindows

test menubutton-8.1 {menubutton vs hidden commands} {
    catch {destroy .mb}





    menubutton .mb



    interp hide {} .mb


    destroy .mb


    list [winfo children .] [interp hidden]
} [list {} $l]

eval image delete [image names]
deleteWindows
option clear


# cleanup
cleanupTests
return




Changes to tests/message.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118


119



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
# This file is a Tcl script to test out the "message" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::loadTestedCommands
eval tcltest::configure $argv


test message-1.1 {configuration option: "anchor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -anchor w
    .m cget -anchor
} -cleanup {
    destroy .m
} -result {w}
test message-1.2 {configuration option: "anchor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -anchor bogus
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}

test message-1.3 {configuration option: "aspect"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -aspect 3
    .m cget -aspect
} -cleanup {
    destroy .m
} -result 3
test message-1.4 {configuration option: "aspect"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -aspect bogus
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected integer but got "bogus"}

test message-1.5 {configuration option: "background"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -background #ff0000
    .m cget -background
} -cleanup {
    destroy .m
} -result {#ff0000}
test message-1.6 {configuration option: "background"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {



    .m configure -background non-existent
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "non-existent"}

test message-1.7 {configuration option: "bd"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bd 4
    .m cget -bd
} -cleanup {
    destroy .m
} -result 4
test message-1.8 {configuration option: "bd"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bd badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.9 {configuration option: "bg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bg #ff0000
    .m cget -bg
} -cleanup {
    destroy .m
} -result {#ff0000}
test message-1.10 {configuration option: "bg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bg non-existent
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "non-existent"}

test message-1.11 {configuration option: "borderwidth"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update


} -body {



    .m configure -borderwidth 1.3
    .m cget -borderwidth
} -cleanup {
    destroy .m
} -result 1
test message-1.12 {configuration option: "borderwidth"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -borderwidth badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.13 {configuration option: "cursor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -cursor arrow
    .m cget -cursor
} -cleanup {
    destroy .m
} -result {arrow}
test message-1.14 {configuration option: "cursor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -cursor badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad cursor spec "badValue"}

test message-1.15 {configuration option: "fg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -fg #00ff00
    .m cget -fg
} -cleanup {
    destroy .m
} -result {#00ff00}
test message-1.16 {configuration option: "fg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -fg badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "badValue"}

test message-1.17 {configuration option: "font"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -font fixed
    .m cget -font
} -cleanup {
    destroy .m
} -result {fixed}
test message-1.18 {configuration option: "font"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -font {}
} -cleanup {
    destroy .m
} -returnCodes {error} -result {font "" doesn't exist}

test message-1.19 {configuration option: "-foreground"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -foreground  green
    .m cget -foreground
} -cleanup {
    destroy .m
} -result {green}
test message-1.20 {configuration option: "-foreground"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -foreground  badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "badValue"}

test message-1.21 {configuration option: "highlightbackground"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightbackground  #112233
    .m cget -highlightbackground
} -cleanup {
    destroy .m
} -result {#112233}
test message-1.22 {configuration option: "highlightbackground"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightbackground  ugly
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "ugly"}

test message-1.23 {configuration option: "highlightcolor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightcolor #123456
    .m cget -highlightcolor
} -cleanup {
    destroy .m
} -result {#123456}
test message-1.24 {configuration option: "highlightcolor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightcolor non-existent
} -cleanup {
    destroy .m
} -returnCodes {error} -result {unknown color name "non-existent"}

test message-1.25 {configuration option: "highlightthickness"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightthickness  2
    .m cget -highlightthickness
} -cleanup {
    destroy .m
} -result 2
test message-1.26 {configuration option: "highlightthickness"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightthickness  badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.27 {configuration option: "justify"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -justify  right
    .m cget -justify
} -cleanup {
    destroy .m
} -result {right}
test message-1.28 {configuration option: "justify"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -justify bogus
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test message-1.29 {configuration option: "padx"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -padx  12m
    .m cget -padx
} -cleanup {
    destroy .m
} -result {12m}
test message-1.30 {configuration option: "padx"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -padx 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "420x"}

test message-1.31 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady  12m
    .m cget -pady
} -cleanup {
    destroy .m
} -result {12m}
test message-1.32 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "420x"}

test message-1.33 {configuration option: "relief"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -relief ridge
    .m cget -relief
} -cleanup {
    destroy .m
} -result {ridge}

test message-1.34 {configuration option: "relief"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -relief  badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}

test message-1.35 {configuration options: "text"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -text "Sample text"
    .m cget -text
} -cleanup {
    destroy .m
} -result {Sample text}

test message-1.36 {configuration option: "textvariable"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -textvariable  i
    .m cget -textvariable
} -cleanup {
    destroy .m
} -result {i}

test message-1.37 {configuration option: "width"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -width  2
    .m cget -width
} -cleanup {
    destroy .m
} -result 2
test message-1.38 {configuration option: "width"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -width badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}


test message-2.1 {Tk_MessageObjCmd procedure} -body {
    message
} -returnCodes {error} -result {wrong # args: should be "message pathName ?-option value ...?"}

test message-2.2 {Tk_MessageObjCmd procedure} -body {
    message foo
} -returnCodes {error} -result {bad window path name "foo"}
test message-2.3 {Tk_MessageObjCmd procedure} -body {
    catch {message foo}
    winfo child .
} -result {}

test message-2.4 {Tk_MessageObjCmd procedure} -body {
    message .s -gorp dump
} -returnCodes {error} -result {unknown option "-gorp"}
test message-2.5 {Tk_MessageObjCmd procedure} -body {
    catch {message .s -gorp dump}
    winfo child .
} -result {}


test message-3.1 {MessageWidgetObjCmd procedure} -setup {
    message .m
} -body {
    .m
} -cleanup {
    destroy .m
} -returnCodes error -result {wrong # args: should be ".m option ?arg ...?"}
test message-3.2 {MessageWidgetObjCmd procedure, "cget"} -setup {
    message .m
} -body {
    .m cget
} -cleanup {
    destroy .m
} -returnCodes error -result {wrong # args: should be ".m cget option"}
test message-3.3 {MessageWidgetObjCmd procedure, "cget"} -setup {
    message .m
} -body {
    .m cget -gorp
} -cleanup {
    destroy .m
} -returnCodes error -result {unknown option "-gorp"}

test message-3.4 {MessageWidgetObjCmd procedure, "configure"} -setup {
    message .m
} -body {
    .m configure -text foobar
    lindex [.m configure -text] 4
} -cleanup {
    destroy .m
} -result {foobar}
test message-3.5 {MessageWidgetObjCmd procedure, "configure"} -setup {
    message .m
} -body {
    llength [.m configure]
} -cleanup {
    destroy .m
} -result 21

test message-3.6 {MessageWidgetObjCmd procedure, "configure"} -setup {
    message .m
} -body {
    .m configure -foo
} -cleanup {
    destroy .m

} -returnCodes error -result {unknown option "-foo"}
test message-3.7 {MessageWidgetObjCmd procedure, "configure"} -setup {
    message .m
} -body {
    .m configure -bd 4
    .m configure -bg #ffffff
    lindex [.m configure -bd] 4
} -cleanup {
    destroy .m
} -result 4

test message-4.1 {Bug [5d991b822e]} {
    # Want this not to segfault, or write to variable with empty name
    unset -nocomplain {}
    set var INIT
    message .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
    info exists {}
} 0
test message-4.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    message .b -textvariable var
    trace add variable var unset {apply {args {
        .b configure -textvariable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}


cleanupTests
return



|
|
|



|

<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
|
|
|
>
>
>
|
<
<
|
|
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
|
<
<
<
<
>
>
|
>
>
>
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
<
<
<
|
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
|
<
<
<
|
<

|
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
|
<

|
>
|
<
|
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
<
<
|
|
<

|
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<

|
>
|

<
|
<

>
|
|

<


|
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

>


1
2
3
4
5
6
7
8
9
10
11

12
13



















14

15

















16


17









18
19
20
21
22
23
24


25
26



27

28












29
30
31
32
33








34



35


36
37




38
39
40
41
42
43
44








45




46




















47




48




















49
50
51
52
53




54

55

56





57






58






59








60






























61
62









63








64
65
66

67






68
69







70



















71
72

73



74

75
76









77
78

79



80

81
82
83
84

85


86

87






















88
89
90

91


92
93

94
95









96
97

98




















































99

100
101
102
103
104

105

106
107
108
109
110

111
112
113

114
115



























116
117
118
119
120
# This file is a Tcl script to test out the "message" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


option add *Message.borderWidth 2



















option add *Message.highlightThickness 2

option add *Message.font {Helvetica -12 bold}




















message .m









pack .m
update
set i 0
foreach test {
    {-anchor w w bogus {bad anchor "bogus": must be n, ne, e, se, s, sw, w, nw, or center}}
    {-aspect 3 3 bogus {expected integer but got "bogus"}}
    {-background #ff0000 #ff0000 non-existent


	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {bad screen distance "badValue"}}



    {-bg #ff0000 #ff0000 non-existent

	    {unknown color name "non-existent"}}












    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-fg #00ff00 #00ff00 badValue {unknown color name "badValue"}}
    {-font fixed fixed {} {font "" doesn't exist}}
    {-foreground green green badValue {unknown color name "badValue"}}








    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}



    {-highlightcolor #123456 #123456 non-existent


	    {unknown color name "non-existent"}}
    {-highlightthickness 2 2 badValue {bad screen distance "badValue"}}




    {-justify right right bogus {bad justification "bogus": must be left, right, or center}}
    {-padx 12m 12m 420x {bad screen distance "420x"}}
    {-pady 12m 12m 420x {bad screen distance "420x"}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-text "Sample text" {Sample text} {} {} {1 1 1 1}}
    {-textvariable i i {} {} {1 1 1 1}}
    {-width 32 32 badValue {bad screen distance "badValue"}}








} {




    set name [lindex $test 0]




















    test message-1.$i {configuration options} {




	.m configure $name [lindex $test 1]




















	lindex [.m configure $name] 4
    } [lindex $test 2]
    incr i
    if {[lindex $test 3] != ""} {
	test message-1.$i {configuration options} {




	    list [catch {.m configure $name [lindex $test 3]} msg] $msg

	} [list 1 [lindex $test 4]]

    }





    .m configure $name [lindex [.m configure $name] 3]






    incr i






}








destroy .m































test message-2.1 {Tk_MessageObjCmd procedure} {









    list [catch {message} msg] $msg








} {1 {wrong # args: should be "message pathName ?options?"}}
test message-2.2 {Tk_MessageObjCmd procedure} {
    list [catch {message foo} msg] $msg [winfo child .]

} {1 {bad window path name "foo"} {}}






test message-2.3 {Tk_MessageObjCmd procedure} {
    list [catch {message .s -gorp dumb} msg] $msg [winfo child .]







} {1 {unknown option "-gorp"} {}}




















test message-3.1 {MessageWidgetObjCmd procedure} {

    message .m



    set result [list [catch {.m} msg] $msg]

    destroy .m
    set result









} {1 {wrong # args: should be ".m option ?arg arg ...?"}}
test message-3.2 {MessageWidgetObjCmd procedure, "cget"} {

    message .m



    set result [list [catch {.m cget} msg] $msg]

    destroy .m
    set result
} {1 {wrong # args: should be ".m cget option"}}
test message-3.3 {MessageWidgetObjCmd procedure, "cget"} {

    message .m


    set result [list [catch {.m cget -gorp} msg] $msg]

    destroy .m






















    set result
} {1 {unknown option "-gorp"}}
test message-3.4 {MessageWidgetObjCmd procedure, "cget"} {

    message .m


    .m configure -text foobar
    set result [.m cget -text]

    destroy .m
    set result









} "foobar"
test message-3.5 {MessageWidgetObjCmd procedure, "configure"} {

    message .m




















































    set result [llength [.m configure]]

    destroy .m
    set result
} 21
test message-3.6 {MessageWidgetObjCmd procedure, "configure"} {
    message .m

    set result [list [catch {.m configure -foo} msg] $msg]

    destroy .m
    set result
} {1 {unknown option "-foo"}}
test message-3.7 {MessageWidgetObjCmd procedure, "configure"} {
    message .m

    .m configure -bd 4
    .m configure -bg #ffffff
    set result [lindex [.m configure -bd] 4]

    destroy .m
    set result



























} {4}

# cleanup
cleanupTests
return

Changes to tests/msgbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


22


23
24
25
26


27
28
29
30
31
32
33
34

35








36
37

38
39
40

41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118












119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# This file is a Tcl script to test out Tk's "tk_messageBox" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


test msgbox-1.1.1 {tk_messageBox command} -constraints notAqua -body {
    tk_messageBox -foo
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}
test msgbox-1.1.2 {tk_messageBox command} -constraints aqua -body {
    tk_messageBox -foo
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command}
test msgbox-1.2.1 {tk_messageBox command} -constraints notAqua -body {
    tk_messageBox -foo bar


} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}


test msgbox-1.2.2 {tk_messageBox command} -constraints aqua -body {
    tk_messageBox -foo bar
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command}



test msgbox-1.3 {tk_messageBox command} -body {
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}
test msgbox-1.4 {tk_messageBox command} -body {
    tk_messageBox -detail
} -returnCodes error -result {value for "-detail" missing}
test msgbox-1.5 {tk_messageBox command} -body {
    tk_messageBox -icon

} -returnCodes error -result {value for "-icon" missing}








test msgbox-1.6 {tk_messageBox command} -body {
    tk_messageBox -message

} -returnCodes error -result {value for "-message" missing}
test msgbox-1.7 {tk_messageBox command} -body {
    tk_messageBox -parent

} -returnCodes error -result {value for "-parent" missing}
test msgbox-1.8 {tk_messageBox command} -body {
    tk_messageBox -title

} -returnCodes error -result {value for "-title" missing}
test msgbox-1.9 {tk_messageBox command} -body {
    tk_messageBox -type
} -returnCodes error -result {value for "-type" missing}

test msgbox-1.10 {tk_messageBox command} -body {
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}

test msgbox-1.11 {tk_messageBox command} -body {
    tk_messageBox -type foo
} -returnCodes error -result {bad -type value "foo": must be abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel}

test msgbox-1.13 {tk_messageBox command} -body {
    tk_messageBox -default 1.1
} -returnCodes error -result {bad -default value "1.1": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.14 {tk_messageBox command} -body {
    tk_messageBox -default foo
} -returnCodes error -result {bad -default value "foo": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.16 {tk_messageBox command} -body {
    tk_messageBox -type yesno -default 3
} -returnCodes error -result {bad -default value "3": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.18 {tk_messageBox command} -body {
    tk_messageBox -icon foo
} -returnCodes error -result {bad -icon value "foo": must be error, info, question, or warning}

test msgbox-1.19 {tk_messageBox command} -body {
    tk_messageBox -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


catch {tk_messageBox -foo bar}
set isNative [expr {[info commands tk::MessageBox] == ""}]

proc ChooseMsg {parent btn} {
    global isNative
    if {!$isNative} {
	after 100 SendEventToMsg $parent $btn mouse
    }
}

proc ChooseMsgByKey {parent btn} {
    global isNative
    if {!$isNative} {
	after 100 SendEventToMsg $parent $btn key
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <Button-1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc SendEventToMsg {parent btn type} {
    if {$parent != "."} {
	set w $parent.__tk__messagebox
    } else {
	set w .__tk__messagebox
    }
    if ![winfo ismapped $w.$btn] {
	update
    }
    if {$type == "mouse"} {
	PressButton $w.$btn
    } else {
	event generate $w <Enter>
	focus $w
	event generate $w.$btn <Enter>
	event generate $w <Key> -keysym Return
    }
}












#
# Try out all combinations of (type) x (default button) and
# (type) x (icon).
#
test msgbox-2.1 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" -type abortretryignore
} -result {abort}
test msgbox-2.2 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" \
        -type abortretryignore -icon warning
} -result {abort}
test msgbox-2.3 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" \
        -type abortretryignore -icon error
} -result {abort}
test msgbox-2.4 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" \
        -type abortretryignore -icon info
} -result {abort}
test msgbox-2.5 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" \
        -type abortretryignore -icon question
} -result {abort}
test msgbox-2.6 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . abort
    tk_messageBox -title Hi -message "Please press abort" \
        -type abortretryignore -default abort
} -result {abort}
test msgbox-2.7 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type abortretryignore -default retry
} -result {retry}
test msgbox-2.8 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ignore
    tk_messageBox -title Hi -message "Please press ignore" \
        -type abortretryignore -default ignore
} -result {ignore}
test msgbox-2.9 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" -type ok
} -result {ok}
test msgbox-2.10 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type ok -icon warning
} -result {ok}
test msgbox-2.11 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type ok -icon error
} -result {ok}
test msgbox-2.12 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type ok -icon info
} -result {ok}
test msgbox-2.13 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type ok -icon question
} -result {ok}
test msgbox-2.14 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type ok -default ok
} -result {ok}
test msgbox-2.15 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" -type okcancel
} -result {ok}
test msgbox-2.16 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type okcancel -icon warning
} -result {ok}
test msgbox-2.17 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type okcancel -icon error
} -result {ok}
test msgbox-2.18 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type okcancel -icon info
} -result {ok}
test msgbox-2.19 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type okcancel -icon question
} -result {ok}
test msgbox-2.20 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . ok
    tk_messageBox -title Hi -message "Please press ok" \
        -type okcancel -default ok
} -result {ok}
test msgbox-2.21 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . cancel
    tk_messageBox -title Hi -message "Please press cancel" \
        -type okcancel -default cancel
} -result {cancel}
test msgbox-2.22 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" -type retrycancel
} -result {retry}
test msgbox-2.23 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type retrycancel -icon warning
} -result {retry}
test msgbox-2.24 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type retrycancel -icon error
} -result {retry}
test msgbox-2.25 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type retrycancel -icon info
} -result {retry}
test msgbox-2.26 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type retrycancel -icon question
} -result {retry}
test msgbox-2.27 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . retry
    tk_messageBox -title Hi -message "Please press retry" \
        -type retrycancel -default retry
} -result {retry}
test msgbox-2.28 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . cancel

    tk_messageBox -title Hi -message "Please press cancel" \
        -type retrycancel -default cancel
} -result {cancel}
test msgbox-2.29 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" -type yesno
} -result {yes}
test msgbox-2.30 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesno -icon warning
} -result {yes}
test msgbox-2.31 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesno -icon error
} -result {yes}
test msgbox-2.32 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesno -icon info
} -result {yes}
test msgbox-2.33 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesno -icon question
} -result {yes}
test msgbox-2.34 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesno -default yes
} -result {yes}
test msgbox-2.35 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . no
    tk_messageBox -title Hi -message "Please press no" \
        -type yesno -default no
} -result {no}
test msgbox-2.36 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" -type yesnocancel
} -result {yes}
test msgbox-2.37 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesnocancel -icon warning
} -result {yes}
test msgbox-2.38 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesnocancel -icon error
} -result {yes}
test msgbox-2.39 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesnocancel -icon info
} -result {yes}
test msgbox-2.40 {tk_messageBox command -icon option} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesnocancel -icon question
} -result {yes}
test msgbox-2.41 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . yes
    tk_messageBox -title Hi -message "Please press yes" \
        -type yesnocancel -default yes
} -result {yes}
test msgbox-2.42 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . no
    tk_messageBox -title Hi -message "Please press no" \
        -type yesnocancel -default no
} -result {no}
test msgbox-2.43 {tk_messageBox command} -constraints {
    nonUnixUserInteraction
} -body {
    ChooseMsg . cancel
    tk_messageBox -title Hi -message "Please press cancel" \
        -type yesnocancel -default cancel
} -result {cancel}



# These tests will hang your test suite if they fail.
test msgbox-3.1 {tk_messageBox handles withdrawn parent} -constraints {
	nonUnixUserInteraction
} -body {
    wm withdraw .
    ChooseMsg . "ok"
    tk_messageBox -title Hi -message "Please press ok" \
	    -type ok -default ok
} -cleanup {
    wm deiconify .
} -result {ok}

test msgbox-3.2 {tk_messageBox handles iconified parent} -constraints {
	nonUnixUserInteraction
} -body {
    wm iconify .
    ChooseMsg . "ok"
    tk_messageBox -title Hi -message "Please press ok" \
	    -type ok -default ok
} -cleanup {
    wm deiconify .
} -result {ok}

# cleanup
cleanupTests
return





|
|





<

<
|
|
|
|
|
|
|
|
>
>
|
>
>
|
|
|
|
>
>
|
|
|
|
<
<
|
|
>
|
>
>
>
>
>
>
>
>
|
|
>
|
|
|
>
|
|
|
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

|
|
|

<
<


















|


















|


>
>
>
>
>
>
>
>
>
>
>
>




<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
|
<
|
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
|
|
<
|
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
>


|
<
<




|
|
<

|
<
<




|
|
<




<
<
1
2
3
4
5
6
7
8
9
10

11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
























60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122



123















































124














125
126






127





128


129

130
131







132



133





134
135

136

137
138

139



































140




















141



142














143
144
145



























146


147















148
149
150



151
















































152



153
154
155
156
157


158
159
160
161
162
163

164
165


166
167
168
169
170
171

172
173
174
175


# This file is a Tcl script to test out Tk's "tk_messageBox" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



test msgbox-1.1 {tk_messageBox command} {
    list [catch {tk_messageBox -foo} msg] $msg
} {1 {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}}
test msgbox-1.2 {tk_messageBox command} {
    list [catch {tk_messageBox -foo bar} msg] $msg
} {1 {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}}

catch {tk_messageBox -foo bar} msg
regsub -all ,      $msg "" options
regsub \"-foo\" $options "" options

foreach option $options {
    if {[string index $option 0] eq "-"} {
	test msgbox-1.3$option {tk_messageBox command} -body {
	    tk_messageBox $option
	} -returnCodes error -result "value for \"$option\" missing"
    }
}

test msgbox-1.4 {tk_messageBox command} {
    list [catch {tk_messageBox -default} msg] $msg
} {1 {value for "-default" missing}}



test msgbox-1.5 {tk_messageBox command} {
    list [catch {tk_messageBox -type foo} msg] $msg
} {1 {bad -type value "foo": must be abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel}}

proc createPlatformMsg {val} {
    global tcl_platform
    if {$tcl_platform(platform) == "unix"} {
	return "invalid default button \"$val\""
    }
    return "bad -default value \"$val\": must be abort, retry, ignore, ok, cancel, no, or yes"
}

test msgbox-1.6 {tk_messageBox command} {
    list [catch {tk_messageBox -default 1.1} msg] $msg
} [list 1 [createPlatformMsg "1.1"]]

test msgbox-1.7 {tk_messageBox command} {
    list [catch {tk_messageBox -default foo} msg] $msg
} [list 1 [createPlatformMsg "foo"]]

test msgbox-1.8 {tk_messageBox command} {
    list [catch {tk_messageBox -type yesno -default 3} msg] $msg
} [list 1 [createPlatformMsg "3"]]

test msgbox-1.9 {tk_messageBox command} {
























    list [catch {tk_messageBox -icon foo} msg] $msg
} {1 {bad -icon value "foo": must be error, info, question, or warning}}

test msgbox-1.10 {tk_messageBox command} {
    list [catch {tk_messageBox -parent foo.bar} msg] $msg
} {1 {bad window path name "foo.bar"}}



set isNative [expr {[info commands tk::MessageBox] == ""}]

proc ChooseMsg {parent btn} {
    global isNative
    if {!$isNative} {
	after 100 SendEventToMsg $parent $btn mouse
    }
}

proc ChooseMsgByKey {parent btn} {
    global isNative
    if {!$isNative} {
	after 100 SendEventToMsg $parent $btn key
    }
}

proc PressButton {btn} {
    event generate $btn <Enter>
    event generate $btn <ButtonPress-1> -x 5 -y 5
    event generate $btn <ButtonRelease-1> -x 5 -y 5
}

proc SendEventToMsg {parent btn type} {
    if {$parent != "."} {
	set w $parent.__tk__messagebox
    } else {
	set w .__tk__messagebox
    }
    if ![winfo ismapped $w.$btn] {
	update
    }
    if {$type == "mouse"} {
	PressButton $w.$btn
    } else {
	event generate $w <Enter>
	focus $w
	event generate $w.$btn <Enter>
	event generate $w <KeyPress> -keysym Return
    }
}

set parent .

set specs {
    {"abortretryignore"  MB_ABORTRETRYIGNORE  3  {"abort"  "retry"  "ignore"}}
    {"ok"  		 MB_OK  	      1  {"ok"                      }}
    {"okcancel" 	 MB_OKCANCEL 	      2  {"ok"     "cancel"         }}
    {"retrycancel" 	 MB_RETRYCANCEL       2  {"retry"  "cancel"         }}
    {"yesno" 		 MB_YESNO 	      2  {"yes"    "no"             }}
    {"yesnocancel" 	 MB_YESNOCANCEL       3  {"yes"    "no"     "cancel"}}
}

#
# Try out all combinations of (type) x (default button) and
# (type) x (icon).
#



set count 1















































foreach spec $specs {














    set type [lindex $spec 0]
    set buttons [lindex $spec 3]












    set button [lindex $buttons 0]


    test msgbox-2.$count {tk_messageBox command} nonUnixUserInteraction {

	ChooseMsg $parent $button
	tk_messageBox -title Hi -message "Please press $button" \







		-type $type



    } $button





    incr count


    foreach icon {warning error info question} {

	test msgbox-2.$count {tk_messageBox command -icon option} \
		nonUnixUserInteraction {

	    ChooseMsg $parent $button



































	    tk_messageBox -title Hi -message "Please press $button" \




















		    -type $type -icon $icon



	} $button














        incr count
    }




























    foreach button $buttons {


	test msgbox-2.$count {tk_messageBox command} nonUnixUserInteraction {















	    ChooseMsg $parent $button
	    tk_messageBox -title Hi -message "Please press $button" \
		    -type $type -default $button



	} "$button"
















































        incr count



    }
}

# These tests will hang your test suite if they fail.
test msgbox-3.1 {tk_messageBox handles withdrawn parent} nonUnixUserInteraction {


    wm withdraw .
    ChooseMsg . "ok"
    tk_messageBox -title Hi -message "Please press ok" \
	    -type ok -default ok
} "ok"
wm deiconify .


test msgbox-3.2 {tk_messageBox handles iconified parent} nonUnixUserInteraction {


    wm iconify .
    ChooseMsg . "ok"
    tk_messageBox -title Hi -message "Please press ok" \
	    -type ok -default ok
} "ok"
wm deiconify .


# cleanup
cleanupTests
return


Changes to tests/obj.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24


25
26
27
28
# This file is a Tcl script to test new object types in Tk.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test obj-1.1 {TkGetPixelsFromObj} -body {
} -result {}

test obj-2.1 {FreePixelInternalRep} -body {
} -result {}

test obj-3.1 {DupPixelInternalRep} -body {
} -result {}

test obj-4.1 {SetPixelFromAny} -body {

} -result {}




# cleanup
cleanupTests
return



|
|



<



|
|

|
|

|
|

|
>
|

>
>




1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file is a Tcl script to test new object types in Tk.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test obj-1.1 {TkGetPixelsFromObj} {
} {}

test obj-2.1 {FreePixelInternalRep} {
} {}

test obj-3.1 {DupPixelInternalRep} {
} {}

test obj-4.1 {SetPixelFromAny} {
} {}



deleteWindows

# cleanup
cleanupTests
return

Changes to tests/oldpack.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453

454
455

456

457
458

459

460
461

462

463
464

465

466
467
468
469
470

471
472
473

474
475

476

477
478

479

480
481
482
483
484

485
486
487

488








489
490
491
492
493
494
495

496

497
498

499

500
501

502

503
504

505

506






507
508
509
510
511

512
513

514

515
516

517

518
519

520

521
522

523

524
525

526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
# This file is a Tcl script to test out the old syntax of Tk's
# "pack" command (before release 3.3).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1991-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# First, test a single window packed in various ways in a parent

destroy .pack
frame .pack
place .pack -width 100 -height 100
frame .pack.red -width 10 -height 20
label .pack.red.l -text R -bd 2 -relief raised
place .pack.red.l -relwidth 1.0 -relheight 1.0
frame .pack.green -width 30 -height 40
label .pack.green.l -text G -bd 2 -relief raised
place .pack.green.l -relwidth 1.0 -relheight 1.0
frame .pack.blue -width 40 -height 40
label .pack.blue.l -text B -bd 2 -relief raised
place .pack.blue.l -relwidth 1.0 -relheight 1.0
frame .pack.violet -width 80 -height 20
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0

if {![catch {pack ap .pack .pack.red top}]} {

# Don't execute any of this file if Tk is compiled with -DTCL_NO_DEPRECATED


test oldpack-1.1 {basic positioning} -body {
    #pack ap .pack .pack.red top
    update
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-1.2 {basic positioning} -body {
    pack append .pack .pack.red bottom
    update
    winfo geometry .pack.red
} -result 10x20+45+80
test oldpack-1.3 {basic positioning} -body {
    pack append .pack .pack.red left
    update
    winfo geometry .pack.red
} -result 10x20+0+40
test oldpack-1.4 {basic positioning} -body {
    pack append .pack .pack.red right
    update
    winfo geometry .pack.red
} -result 10x20+90+40

# Try adding padding around the window and make sure that the
# window gets a larger frame.

test oldpack-2.1 {padding} -body {
    pack append .pack .pack.red {t padx 20}
    update
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-2.2 {padding} -body {
    pack append .pack .pack.red {top pady 20}
    update
    winfo geometry .pack.red
} -result 10x20+45+10
test oldpack-2.3 {padding} -body {
    pack append .pack .pack.red {l padx 20}
    update
    winfo geometry .pack.red
} -result 10x20+10+40
test oldpack-2.4 {padding} -body {
    pack append .pack .pack.red {left pady 20}
    update
    winfo geometry .pack.red
} -result 10x20+0+40

# Position the window at different positions in its frame to
# make sure they all work.  Try two differenet frame locations,
# to make sure that frame offsets are being added in correctly.

test oldpack-3.1 {framing} -body {
    pack append .pack .pack.red {b padx 20 pady 30}
    update
    winfo geometry .pack.red
} -result 10x20+45+65
test oldpack-3.2 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fr n}
    update
    winfo geometry .pack.red
} -result 10x20+45+50
test oldpack-3.3 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} -result 10x20+90+50
test oldpack-3.4 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} -result 10x20+90+65
test oldpack-3.5 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} -result 10x20+90+80
test oldpack-3.6 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} -result 10x20+45+80
test oldpack-3.7 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} -result 10x20+0+80
test oldpack-3.8 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} -result 10x20+0+65
test oldpack-3.9 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} -result 10x20+0+50
test oldpack-3.10 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame c}
    update
    winfo geometry .pack.red
} -result 10x20+45+65
test oldpack-3.11 {framing} -body {
    pack append .pack .pack.red {r padx 20 pady 30}
    update
    winfo geometry .pack.red
} -result 10x20+80+40
test oldpack-3.12 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame n}
    update
    winfo geometry .pack.red
} -result 10x20+80+0
test oldpack-3.13 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} -result 10x20+90+0
test oldpack-3.14 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} -result 10x20+90+40
test oldpack-3.15 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} -result 10x20+90+80
test oldpack-3.16 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} -result 10x20+80+80
test oldpack-3.17 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} -result 10x20+70+80
test oldpack-3.18 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} -result 10x20+70+40
test oldpack-3.19 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} -result 10x20+70+0
test oldpack-3.20 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame center}
    update
    winfo geometry .pack.red
} -result 10x20+80+40

# Try out various filling combinations in a couple of different
# frame locations.

test oldpack-4.1 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} -result 100x20+0+65
test oldpack-4.2 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} -result 10x50+45+50
test oldpack-4.3 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} -result 100x50+0+50
test oldpack-4.4 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} -result 30x20+70+40
test oldpack-4.5 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} -result 10x100+80+0
test oldpack-4.6 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} -result 30x100+70+0

# Multiple windows:  make sure that space is properly subtracted
# from the cavity as windows are positioned inwards from all
# different sides.  Also make sure that windows get unmapped if
# there isn't enough space for them.

pack append .pack .pack.red top .pack.green top .pack.blue top \
    .pack.violet top
update
test oldpack-5.1 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-5.2 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+35+20
test oldpack-5.3 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+60
test oldpack-5.4 {multiple windows} -body {
    winfo ismapped .pack.violet
} -result 0

pack b .pack.blue .pack.violet top
update
test oldpack-5.5 {multiple windows} -body {
    winfo ismapped .pack.violet
} -result 1
test oldpack-5.6 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+10+60
test oldpack-5.7 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x20+30+80

pack after .pack.blue .pack.red top
update
test oldpack-5.8 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+35+0
test oldpack-5.9 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+10+40
test oldpack-5.10 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+60
test oldpack-5.11 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 0

pack before .pack.green .pack.red right .pack.blue left
update
test oldpack-5.12 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 1
test oldpack-5.13 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+90+40
test oldpack-5.14 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+0+30
test oldpack-5.15 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+50+0
test oldpack-5.16 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 50x20+40+40

pack append .pack .pack.violet left .pack.green bottom .pack.red bottom \
    .pack.blue bottom
update
test oldpack-5.17 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+0+40
test oldpack-5.18 {multiple windows} -body {
    winfo geometry .pack.green
} -result 20x40+80+60
test oldpack-5.19 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+85+40
test oldpack-5.20 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 20x40+80+0

pack after .pack.blue .pack.blue top .pack.red right .pack.green right \
    .pack.violet right
update
test oldpack-5.21 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+0
test oldpack-5.22 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+90+60
test oldpack-5.23 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+60+50
test oldpack-5.24 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 60x20+0+60

pack after .pack.blue .pack.red left .pack.green left .pack.violet left
update
test oldpack-5.25 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+0
test oldpack-5.26 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+0+60
test oldpack-5.27 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+10+50
test oldpack-5.28 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 60x20+40+60

pack append .pack .pack.violet left .pack.green left .pack.blue left \
    .pack.red left
update
test oldpack-5.29 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+0+40
test oldpack-5.30 {multiple windows} -body {
    winfo geometry .pack.green
} -result 20x40+80+30
test oldpack-5.31 {multiple windows} -body {
    winfo ismapped .pack.blue
} -result 0
test oldpack-5.32 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 0


# Test the ability of the packer to propagate geometry information
# to its parent.  Make sure it computes the parent's needs both in
# the direction of packing (width for "left" and "right" windows,
# for example), and perpendicular to the pack direction (height for
# "left" and "right" windows).

pack append .pack .pack.red top .pack.green top .pack.blue top \
    .pack.violet top
update
test oldpack-6.1 {geometry propagation} -body {
    winfo reqwidth .pack} -result 80
test oldpack-6.2 {geometry propagation} -body {
    winfo reqheight .pack} -result 120
destroy .pack.violet
update
test oldpack-6.3 {geometry propagation} -body {
    winfo reqwidth .pack} -result 40
test oldpack-6.4 {geometry propagation} -body {
    winfo reqheight .pack} -result 100
frame .pack.violet -width 80 -height 20 -bg violet
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0
pack append .pack .pack.red left .pack.green right .pack.blue bottom \
    .pack.violet top
update
test oldpack-6.5 {geometry propagation} -body {
    winfo reqwidth .pack} -result 120
test oldpack-6.6 {geometry propagation} -body {
    winfo reqheight .pack} -result 60
pack append .pack .pack.violet top .pack.green top .pack.blue left \
    .pack.red left
update
test oldpack-6.7 {geometry propagation} -body {
    winfo reqwidth .pack} -result 80
test oldpack-6.8 {geometry propagation} -body {
    winfo reqheight .pack} -result 100

# Test the "expand" option, and make sure space is evenly divided
# when several windows request expansion.

pack append .pack .pack.violet top .pack.green {left e} \
    .pack.blue {left expand} .pack.red {left expand}
update
test oldpack-7.1 {multiple expanded windows} -body {
    pack append .pack .pack.violet top .pack.green {left e} \
        .pack.blue {left expand} .pack.red {left expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.blue] \
        [winfo geometry .pack.red]
} -result {30x40+3+40 40x40+39+40 10x20+86+50}
test oldpack-7.2 {multiple expanded windows} -body {
    pack append .pack .pack.green left .pack.violet {bottom expand} \
        .pack.blue {bottom expand} .pack.red {bottom expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.blue] \
        [winfo geometry .pack.red]
} -result {70x20+30+77 40x40+45+30 10x20+60+3}
test oldpack-7.3 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.green {left e fill} .pack.red {left expand fill} \
        .pack.blue {top fill}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red] \
        [winfo geometry .pack.blue]
} -result {40x100+0+0 20x100+40+0 40x40+60+0}
test oldpack-7.4 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.red {top expand} .pack.violet {top expand} \
        .pack.blue {right fill}
    update
    list [winfo geometry .pack.red] [winfo geometry .pack.violet] \
        [winfo geometry .pack.blue]
} -result {10x20+45+5 80x20+10+35 40x40+60+60}
test oldpack-7.5 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.green {right frame s} .pack.red {top expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red]
} -result {30x40+70+60 10x20+30+40}
test oldpack-7.6 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.violet {bottom frame e} .pack.red {right expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.red]
} -result {80x20+20+80 10x20+45+30}

# Need more bizarre tests with combinations of expanded windows and
# windows in opposing directions!  Also, include padding in expanded
# (and unexpanded) windows.

# Syntax errors on pack commands

test oldpack-8.1 {syntax errors} -body {

    pack

} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.2 {syntax errors} -body {

    pack append

} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.3 {syntax errors} -body {

    pack gorp foo

} -returnCodes error -result {bad option "gorp": must be configure, content, forget, info, or propagate}
test oldpack-8.4 {syntax errors} -body {

    pack a .pack

} -returnCodes error -result {bad option "a": must be configure, content, forget, info, or propagate}
test oldpack-8.5 {syntax errors} -body {

    pack after foobar

} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.6 {syntax errors} -setup {
    destroy .pack.yellow
} -body {
    frame .pack.yellow -bg yellow

    pack after .pack.yellow
} -cleanup {
    destroy .pack.yellow

} -returnCodes error -result {window ".pack.yellow" isn't packed}
test oldpack-8.7 {syntax errors} -body {

    pack append foobar

} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.8 {syntax errors} -body {

    pack before foobar

} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.9 {syntax errors} -setup {
    destroy .pack.yellow
} -body {
    frame .pack.yellow -bg yellow

    pack before .pack.yellow
} -cleanup {
    destroy .pack.yellow

} -returnCodes error -result {window ".pack.yellow" isn't packed}








test oldpack-8.10 {syntax errors} -body {
    pack info .pack help
} -returnCodes error -result {wrong # args: should be "pack info window"}
test oldpack-8.11 {syntax errors} -body {
    pack info foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.12 {syntax errors} -body {

    pack append .pack .pack.blue

} -returnCodes error -result {wrong # args: window ".pack.blue" should be followed by options}
test oldpack-8.13 {syntax errors} -body {

    pack append . .pack.blue top

} -returnCodes error -result {can't pack ".pack.blue" inside "."}
test oldpack-8.14 {syntax errors} -body {

    pack append .pack .pack.blue f

} -returnCodes error -result {bad option "f": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}
test oldpack-8.15 {syntax errors} -body {

    pack append .pack .pack.blue pad

} -returnCodes error -result {bad option "pad": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}






test oldpack-8.16 {syntax errors} -body {
    pack append .pack .pack.blue {frame south}
} -returnCodes error -result {bad anchor "south": must be n, ne, e, se, s, sw, w, nw, or center}
test oldpack-8.17 {syntax errors} -body {
    pack append .pack .pack.blue {padx -2}

} -returnCodes error -result {bad pad value "-2": must be positive screen distance}
test oldpack-8.18 {syntax errors} -body {

    pack append .pack .pack.blue {padx}

} -returnCodes error -result {wrong # args: "padx" option must be followed by screen distance}
test oldpack-8.19 {syntax errors} -body {

    pack append .pack .pack.blue {pady -2}

} -returnCodes error -result {bad pad value "-2": must be positive screen distance}
test oldpack-8.20 {syntax errors} -body {

    pack append .pack .pack.blue {pady}

} -returnCodes error -result {wrong # args: "pady" option must be followed by screen distance}
test oldpack-8.21 {syntax errors} -body {

    pack append .pack .pack.blue "\{abc"

} -returnCodes error -result {unmatched open brace in list}
test oldpack-8.22 {syntax errors} -body {

    pack append .pack .pack.blue frame

} -returnCodes error -result {wrong # args: "frame" option must be followed by anchor point}

# Test "pack info" command output.

test oldpack-9.1 {information output} -body {
    pack append .pack .pack.blue {top fillx frame n} \
    .pack.red {bottom filly frame s} .pack.green {left fill frame w} \
    .pack.violet {right expand frame e}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor n -expand 0 -fill x -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor s -expand 0 -fill y -ipadx 0 -ipady 0 -padx 0 -pady 0 -side bottom} {-in .pack -anchor w -expand 0 -fill both -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left} {-in .pack -anchor e -expand 1 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side right}}
test oldpack-9.2 {information output} -body {
    pack append .pack .pack.blue {padx 10 frame nw} \
    .pack.red {pady 20 frame ne} .pack.green {frame se} \
    .pack.violet {frame sw}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor nw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 5 -pady 0 -side top} {-in .pack -anchor ne -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 10 -side top} {-in .pack -anchor se -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor sw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}
test oldpack-9.3 {information output} -body {
    pack append .pack .pack.blue {frame center} .pack.red {frame center} \
    .pack.green {frame c} .pack.violet {frame c}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}

}
destroy .pack

# cleanup
cleanupTests
return





|
|
|





<



|















<
<
<
<
<
|
|


|
|



|
|



|
|



|




|



|
|



|
|



|
|



|





|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|




|



|
|



|
|



|
|



|
|



|
|



|







|

|
<
<
|
<
<
|
<
<
|
<
<
<


|
<
<
|
<
<
|
<
<
<


|
<
<
|
<
<
|
<
<
|
<
<
<


|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
<

|

|
<
<
|
<
<
|
<
<
|
<
<
<

|

|
<
<
|
<
<
|
<
<
|
<
<
<


|
<
<
|
<
<
|
<
<
|
<
<
<

|

|
<
<
|
<
<
|
<
<
|
<
<









|

|
<
|
<


|
<
|
<




|

|
<
|
<

|

|
<
|
<





|

|

|


|
|
|

|


|
|
|

|


|


|
|
|

|


|


|
|
|

|




|
|

|




|







|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
<
<

>
|
<

>
|
|
>
|
>
|
|
>
|
>
|
|
<
<

>
|
<

>
|
>
>
>
>
>
>
>
>
<
<
|
<
<
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
>
>
>
>
>
>
|
<
<
<
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|
|
>
|
>
|



|

|
|
|
|
|
|

|
|
|
|
|
|

|
|
|
|

<
|




<
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31





32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224


225


226


227



228
229
230


231


232



233
234
235


236


237


238



239
240
241


242


243


244


245



246
247
248
249


250


251


252



253
254
255
256


257


258


259



260
261
262


263


264


265



266
267
268
269


270


271


272


273
274
275
276
277
278
279
280
281
282
283
284

285

286
287
288

289

290
291
292
293
294
295
296

297

298
299
300
301

302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392


393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409


410
411
412

413
414
415
416
417
418
419
420
421
422
423


424


425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452



453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

505
506
507
508
509

# This file is a Tcl script to test out the old syntax of Tk's
# "pack" command (before release 3.3).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


# First, test a single window packed in various ways in a parent

catch {destroy .pack}
frame .pack
place .pack -width 100 -height 100
frame .pack.red -width 10 -height 20
label .pack.red.l -text R -bd 2 -relief raised
place .pack.red.l -relwidth 1.0 -relheight 1.0
frame .pack.green -width 30 -height 40
label .pack.green.l -text G -bd 2 -relief raised
place .pack.green.l -relwidth 1.0 -relheight 1.0
frame .pack.blue -width 40 -height 40
label .pack.blue.l -text B -bd 2 -relief raised
place .pack.blue.l -relwidth 1.0 -relheight 1.0
frame .pack.violet -width 80 -height 20
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0






test oldpack-1.1 {basic positioning} {
    pack ap .pack .pack.red top
    update
    winfo geometry .pack.red
} 10x20+45+0
test oldpack-1.2 {basic positioning} {
    pack append .pack .pack.red bottom
    update
    winfo geometry .pack.red
} 10x20+45+80
test oldpack-1.3 {basic positioning} {
    pack append .pack .pack.red left
    update
    winfo geometry .pack.red
} 10x20+0+40
test oldpack-1.4 {basic positioning} {
    pack append .pack .pack.red right
    update
    winfo geometry .pack.red
} 10x20+90+40

# Try adding padding around the window and make sure that the
# window gets a larger frame.

test oldpack-2.1 {padding} {
    pack append .pack .pack.red {t padx 20}
    update
    winfo geometry .pack.red
} 10x20+45+0
test oldpack-2.2 {padding} {
    pack append .pack .pack.red {top pady 20}
    update
    winfo geometry .pack.red
} 10x20+45+10
test oldpack-2.3 {padding} {
    pack append .pack .pack.red {l padx 20}
    update
    winfo geometry .pack.red
} 10x20+10+40
test oldpack-2.4 {padding} {
    pack append .pack .pack.red {left pady 20}
    update
    winfo geometry .pack.red
} 10x20+0+40

# Position the window at different positions in its frame to
# make sure they all work.  Try two differenet frame locations,
# to make sure that frame offsets are being added in correctly.

test oldpack-3.1 {framing} {
    pack append .pack .pack.red {b padx 20 pady 30}
    update
    winfo geometry .pack.red
} 10x20+45+65
test oldpack-3.2 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 fr n}
    update
    winfo geometry .pack.red
} 10x20+45+50
test oldpack-3.3 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} 10x20+90+50
test oldpack-3.4 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} 10x20+90+65
test oldpack-3.5 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} 10x20+90+80
test oldpack-3.6 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} 10x20+45+80
test oldpack-3.7 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} 10x20+0+80
test oldpack-3.8 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} 10x20+0+65
test oldpack-3.9 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} 10x20+0+50
test oldpack-3.10 {framing} {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame c}
    update
    winfo geometry .pack.red
} 10x20+45+65
test oldpack-3.11 {framing} {
    pack append .pack .pack.red {r padx 20 pady 30}
    update
    winfo geometry .pack.red
} 10x20+80+40
test oldpack-3.12 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame n}
    update
    winfo geometry .pack.red
} 10x20+80+0
test oldpack-3.13 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} 10x20+90+0
test oldpack-3.14 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} 10x20+90+40
test oldpack-3.15 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} 10x20+90+80
test oldpack-3.16 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} 10x20+80+80
test oldpack-3.17 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} 10x20+70+80
test oldpack-3.18 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} 10x20+70+40
test oldpack-3.19 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} 10x20+70+0
test oldpack-3.20 {framing} {
    pack append .pack .pack.red {right padx 20 pady 30 frame center}
    update
    winfo geometry .pack.red
} 10x20+80+40

# Try out various filling combinations in a couple of different
# frame locations.

test oldpack-4.1 {filling} {
    pack append .pack .pack.red {bottom padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} 100x20+0+65
test oldpack-4.2 {filling} {
    pack append .pack .pack.red {bottom padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} 10x50+45+50
test oldpack-4.3 {filling} {
    pack append .pack .pack.red {bottom padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} 100x50+0+50
test oldpack-4.4 {filling} {
    pack append .pack .pack.red {right padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} 30x20+70+40
test oldpack-4.5 {filling} {
    pack append .pack .pack.red {right padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} 10x100+80+0
test oldpack-4.6 {filling} {
    pack append .pack .pack.red {right padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} 30x100+70+0

# Multiple windows:  make sure that space is properly subtracted
# from the cavity as windows are positioned inwards from all
# different sides.  Also make sure that windows get unmapped if
# there isn't enough space for them.

pack append .pack .pack.red top .pack.green top .pack.blue top \
	.pack.violet top
update
test oldpack-5.1 {multiple windows} {winfo geometry .pack.red} 10x20+45+0


test oldpack-5.2 {multiple windows} {winfo geometry .pack.green} 30x40+35+20


test oldpack-5.3 {multiple windows} {winfo geometry .pack.blue} 40x40+30+60


test oldpack-5.4 {multiple windows} {winfo ismapped .pack.violet} 0



pack b .pack.blue .pack.violet top
update
test oldpack-5.5 {multiple windows} {winfo ismapped .pack.violet} 1


test oldpack-5.6 {multiple windows} {winfo geometry .pack.violet} 80x20+10+60


test oldpack-5.7 {multiple windows} {winfo geometry .pack.blue} 40x20+30+80



pack after .pack.blue .pack.red top
update
test oldpack-5.8 {multiple windows} {winfo geometry .pack.green} 30x40+35+0


test oldpack-5.9 {multiple windows} {winfo geometry .pack.violet} 80x20+10+40


test oldpack-5.10 {multiple windows} {winfo geometry .pack.blue} 40x40+30+60


test oldpack-5.11 {multiple windows} {winfo ismapped .pack.red} 0



pack before .pack.green .pack.red right .pack.blue left
update
test oldpack-5.12 {multiple windows} {winfo ismapped .pack.red} 1


test oldpack-5.13 {multiple windows} {winfo geometry .pack.red} 10x20+90+40


test oldpack-5.14 {multiple windows} {winfo geometry .pack.blue} 40x40+0+30


test oldpack-5.15 {multiple windows} {winfo geometry .pack.green} 30x40+50+0


test oldpack-5.16 {multiple windows} {winfo geometry .pack.violet} 50x20+40+40



pack append .pack .pack.violet left .pack.green bottom .pack.red bottom \
	.pack.blue bottom
update
test oldpack-5.17 {multiple windows} {winfo geometry .pack.violet} 80x20+0+40


test oldpack-5.18 {multiple windows} {winfo geometry .pack.green} 20x40+80+60


test oldpack-5.19 {multiple windows} {winfo geometry .pack.red} 10x20+85+40


test oldpack-5.20 {multiple windows} {winfo geometry .pack.blue} 20x40+80+0



pack after .pack.blue .pack.blue top .pack.red right .pack.green right \
	.pack.violet right
update
test oldpack-5.21 {multiple windows} {winfo geometry .pack.blue} 40x40+30+0


test oldpack-5.22 {multiple windows} {winfo geometry .pack.red} 10x20+90+60


test oldpack-5.23 {multiple windows} {winfo geometry .pack.green} 30x40+60+50


test oldpack-5.24 {multiple windows} {winfo geometry .pack.violet} 60x20+0+60



pack after .pack.blue .pack.red left .pack.green left .pack.violet left
update
test oldpack-5.25 {multiple windows} {winfo geometry .pack.blue} 40x40+30+0


test oldpack-5.26 {multiple windows} {winfo geometry .pack.red} 10x20+0+60


test oldpack-5.27 {multiple windows} {winfo geometry .pack.green} 30x40+10+50


test oldpack-5.28 {multiple windows} {winfo geometry .pack.violet} 60x20+40+60



pack append .pack .pack.violet left .pack.green left .pack.blue left \
	.pack.red left
update
test oldpack-5.29 {multiple windows} {winfo geometry .pack.violet} 80x20+0+40


test oldpack-5.30 {multiple windows} {winfo geometry .pack.green} 20x40+80+30


test oldpack-5.31 {multiple windows} {winfo ismapped .pack.blue} 0


test oldpack-5.32 {multiple windows} {winfo ismapped .pack.red} 0




# Test the ability of the packer to propagate geometry information
# to its parent.  Make sure it computes the parent's needs both in
# the direction of packing (width for "left" and "right" windows,
# for example), and perpendicular to the pack direction (height for
# "left" and "right" windows).

pack append .pack .pack.red top .pack.green top .pack.blue top \
	.pack.violet top
update
test oldpack-6.1 {geometry propagation} {winfo reqwidth .pack} 80

test oldpack-6.2 {geometry propagation} {winfo reqheight .pack} 120

destroy .pack.violet
update
test oldpack-6.3 {geometry propagation} {winfo reqwidth .pack} 40

test oldpack-6.4 {geometry propagation} {winfo reqheight .pack} 100

frame .pack.violet -width 80 -height 20 -bg violet
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0
pack append .pack .pack.red left .pack.green right .pack.blue bottom \
	.pack.violet top
update
test oldpack-6.5 {geometry propagation} {winfo reqwidth .pack} 120

test oldpack-6.6 {geometry propagation} {winfo reqheight .pack} 60

pack append .pack .pack.violet top .pack.green top .pack.blue left \
	.pack.red left
update
test oldpack-6.7 {geometry propagation} {winfo reqwidth .pack} 80

test oldpack-6.8 {geometry propagation} {winfo reqheight .pack} 100


# Test the "expand" option, and make sure space is evenly divided
# when several windows request expansion.

pack append .pack .pack.violet top .pack.green {left e} \
	.pack.blue {left expand} .pack.red {left expand}
update
test oldpack-7.1 {multiple expanded windows} {
    pack append .pack .pack.violet top .pack.green {left e} \
	    .pack.blue {left expand} .pack.red {left expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.blue] \
	    [winfo geometry .pack.red]
} {30x40+3+40 40x40+39+40 10x20+86+50}
test oldpack-7.2 {multiple expanded windows} {
    pack append .pack .pack.green left .pack.violet {bottom expand} \
	    .pack.blue {bottom expand} .pack.red {bottom expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.blue] \
	    [winfo geometry .pack.red]
} {70x20+30+77 40x40+45+30 10x20+60+3}
test oldpack-7.3 {multiple expanded windows} {
    foreach i [winfo child .pack] {
	pack unpack $i
    }
    pack append .pack .pack.green {left e fill} .pack.red {left expand fill} \
	    .pack.blue {top fill}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red] \
	    [winfo geometry .pack.blue]
} {40x100+0+0 20x100+40+0 40x40+60+0}
test oldpack-7.4 {multiple expanded windows} {
    foreach i [winfo child .pack] {
	pack unpack $i
    }
    pack append .pack .pack.red {top expand} .pack.violet {top expand} \
	    .pack.blue {right fill}
    update
    list [winfo geometry .pack.red] [winfo geometry .pack.violet] \
	    [winfo geometry .pack.blue]
} {10x20+45+5 80x20+10+35 40x40+60+60}
test oldpack-7.5 {multiple expanded windows} {
    foreach i [winfo child .pack] {
	pack unpack $i
    }
    pack append .pack .pack.green {right frame s} .pack.red {top expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red]
} {30x40+70+60 10x20+30+40}
test oldpack-7.6 {multiple expanded windows} {
    foreach i [winfo child .pack] {
	pack unpack $i
    }
    pack append .pack .pack.violet {bottom frame e} .pack.red {right expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.red]
} {80x20+20+80 10x20+45+30}

# Need more bizarre tests with combinations of expanded windows and
# windows in opposing directions!  Also, include padding in expanded
# (and unexpanded) windows.

# Syntax errors on pack commands

test oldpack-8.1 {syntax errors} {
    set msg ""
    set result [catch {pack} msg]
    concat $result $msg
} {1 wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.2 {syntax errors} {
    set msg ""
    set result [catch {pack append} msg]
    concat $result $msg
} {1 wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.3 {syntax errors} {
    set msg ""
    set result [catch {pack gorp foo} msg]
    concat $result $msg
} {1 bad option "gorp": must be configure, forget, info, propagate, or slaves}
test oldpack-8.4 {syntax errors} {
    set msg ""
    set result [catch {pack a .pack} msg]
    concat $result $msg
} {1 bad option "a": must be configure, forget, info, propagate, or slaves}
test oldpack-8.5 {syntax errors} {
    set msg ""
    set result [catch {pack after foobar} msg]
    concat $result $msg
} {1 bad window path name "foobar"}
test oldpack-8.6 {syntax errors} {


    frame .pack.yellow -bg yellow
    set msg ""
    set result [catch {pack after .pack.yellow} msg]

    destroy .pack.yellow
    concat $result $msg
} {1 window ".pack.yellow" isn't packed}
test oldpack-8.7 {syntax errors} {
    set msg ""
    set result [catch {pack append foobar} msg]
    concat $result $msg
} {1 bad window path name "foobar"}
test oldpack-8.8 {syntax errors} {
    set msg ""
    set result [catch {pack before foobar} msg]
    concat $result $msg
} {1 bad window path name "foobar"}
test oldpack-8.9 {syntax errors} {


    frame .pack.yellow -bg yellow
    set msg ""
    set result [catch {pack before .pack.yellow} msg]

    destroy .pack.yellow
    concat $result $msg
} {1 window ".pack.yellow" isn't packed}
test oldpack-8.10 {syntax errors} {
    set msg ""
    set result [catch {pack info .pack help} msg]
    concat $result $msg
} {1 wrong # args: should be "pack info window"}
test oldpack-8.11 {syntax errors} {
    set msg ""
    set result [catch {pack info foobar} msg]


    concat $result $msg


} {1 bad window path name "foobar"}
test oldpack-8.12 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue} msg]
    concat $result $msg
} {1 wrong # args: window ".pack.blue" should be followed by options}
test oldpack-8.13 {syntax errors} {
    set msg ""
    set result [catch {pack append . .pack.blue top} msg]
    concat $result $msg
} {1 can't pack .pack.blue inside .}
test oldpack-8.14 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue f} msg]
    concat $result $msg
} {1 bad option "f": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}
test oldpack-8.15 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue pad} msg]
    concat $result $msg
} {1 bad option "pad": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}
test oldpack-8.16 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue {frame south}} msg]
    concat $result $msg
} {1 bad anchor "south": must be n, ne, e, se, s, sw, w, nw, or center}
test oldpack-8.17 {syntax errors} {
    set msg ""



    set result [catch {pack append .pack .pack.blue {padx -2}} msg]
    concat $result $msg
} {1 bad pad value "-2": must be positive screen distance}
test oldpack-8.18 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue {padx}} msg]
    concat $result $msg
} {1 wrong # args: "padx" option must be followed by screen distance}
test oldpack-8.19 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue {pady -2}} msg]
    concat $result $msg
} {1 bad pad value "-2": must be positive screen distance}
test oldpack-8.20 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue {pady}} msg]
    concat $result $msg
} {1 wrong # args: "pady" option must be followed by screen distance}
test oldpack-8.21 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue "\{abc"} msg]
    concat $result $msg
} {1 unmatched open brace in list}
test oldpack-8.22 {syntax errors} {
    set msg ""
    set result [catch {pack append .pack .pack.blue frame} msg]
    concat $result $msg
} {1 wrong # args: "frame" option must be followed by anchor point}

# Test "pack info" command output.

test oldpack-9.1 {information output} {
    pack append .pack .pack.blue {top fillx frame n} \
	.pack.red {bottom filly frame s} .pack.green {left fill frame w} \
	.pack.violet {right expand frame e}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
	    [pack info .pack.green] [pack info .pack.violet]
} {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor n -expand 0 -fill x -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor s -expand 0 -fill y -ipadx 0 -ipady 0 -padx 0 -pady 0 -side bottom} {-in .pack -anchor w -expand 0 -fill both -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left} {-in .pack -anchor e -expand 1 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side right}}
test oldpack-9.2 {information output} {
    pack append .pack .pack.blue {padx 10 frame nw} \
	.pack.red {pady 20 frame ne} .pack.green {frame se} \
	.pack.violet {frame sw}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
	    [pack info .pack.green] [pack info .pack.violet]
} {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor nw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 5 -pady 0 -side top} {-in .pack -anchor ne -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 10 -side top} {-in .pack -anchor se -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor sw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}
test oldpack-9.3 {information output} {
    pack append .pack .pack.blue {frame center} .pack.red {frame center} \
	.pack.green {frame c} .pack.violet {frame c}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
	    [pack info .pack.green] [pack info .pack.violet]
} {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}


catch {destroy .pack}

# cleanup
cleanupTests
return

Deleted tests/option.file3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
! This file is a sample option (resource) database used to test
! Tk's option-handling capabilities.

! Comment line \
  with a backslash-newline sequence embedded in it.

*x1: 	blue
	 tktest.x2		: green
*\
x3 \
  : pur\
ple
*x 4:	brówn
# More comments, this time delimited by hash-marks.
	# Comment-line with space.
*x6:
*x9: \ \	\\\101\n
# comment line as last line of file.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Changes to tests/option.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362


363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# This file is a Tcl script to test out the option-handling facilities
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint appNameIsTktest [expr {[winfo name .] eq "tktest"}]

deleteWindows

set appName [winfo name .]

# First, test basic retrievals, being sure to trigger all the various
# types of NodeElements (EXACT_LEAF_NAME, WILDCARD_NODE_CLASS, and
# everything in-between).

frame .op1 -class Class1
frame .op2 -class Class2
frame .op1.op3 -class Class1
frame .op1.op4 -class Class3
frame .op2.op5 -class Class2
frame .op1.op3.op6 -class Class4

# Configurations for tests 1.* - 12.*
option clear
option add *Color1 red
option add *x blue
option add *Class1.x yellow
option add $appName.op1.x green
option add *Class2.Color1 orange
option add $appName.op2.op5.Color2 purple
option add $appName.Class1.Class3.y brown
option add $appName*op6*Color2 black
option add $appName*Class1.op1.Color2 grey

test option-1.1 {basic option retrieval} -body {
    option get . x Color1
} -result blue
test option-1.2 {basic option retrieval} -body {
    option get . y Color1
} -result red
test option-1.3 {basic option retrieval} -body {
    option get . z Color1
} -result red
test option-1.4 {basic option retrieval} -body {
    option get . x Color2
} -result blue
test option-1.5 {basic option retrieval} -body {
    option get . y Color2
} -result {}
test option-1.6 {basic option retrieval} -body {
    option get . z Color2
} -result {}


test option-2.1 {basic option retrieval} -body {
    option get .op1 x Color1
} -result green
test option-2.2 {basic option retrieval} -body {
    option get .op1 y Color1
} -result red
test option-2.3 {basic option retrieval} -body {
    option get .op1 z Color1
} -result red
test option-2.4 {basic option retrieval} -body {
    option get .op1 x Color2
} -result green
test option-2.5 {basic option retrieval} -body {
    option get .op1 y Color2
} -result {}
test option-2.6 {basic option retrieval} -body {
    option get .op1 z Color2
} -result {}


test option-3.1 {basic option retrieval} -body {
    option get .op1.op3 x Color1
} -result yellow
test option-3.2 {basic option retrieval} -body {
    option get .op1.op3 y Color1
} -result red
test option-3.3 {basic option retrieval} -body {
    option get .op1.op3 z Color1
} -result red
test option-3.4 {basic option retrieval} -body {
    option get .op1.op3 x Color2
} -result yellow
test option-3.5 {basic option retrieval} -body {
    option get .op1.op3 y Color2
} -result {}
test option-3.6 {basic option retrieval} -body {
    option get .op1.op3 z Color2
} -result {}


test option-4.1 {basic option retrieval} -body {
    option get .op1.op3.op6 x Color1
} -result blue
test option-4.2 {basic option retrieval} -body {
    option get .op1.op3.op6 y Color1
} -result red
test option-4.3 {basic option retrieval} -body {
    option get .op1.op3.op6 z Color1
} -result red
test option-4.4 {basic option retrieval} -body {
    option get .op1.op3.op6 x Color2
} -result black
test option-4.5 {basic option retrieval} -body {
    option get .op1.op3.op6 y Color2
} -result black
test option-4.6 {basic option retrieval} -body {
    option get .op1.op3.op6 z Color2
} -result black


test option-5.1 {basic option retrieval} -body {
    option get .op1.op4 x Color1
} -result blue
test option-5.2 {basic option retrieval} -body {
    option get .op1.op4 y Color1
} -result brown
test option-5.3 {basic option retrieval} -body {
    option get .op1.op4 z Color1
} -result red
test option-5.4 {basic option retrieval} -body {
    option get .op1.op4 x Color2
} -result blue
test option-5.5 {basic option retrieval} -body {
    option get .op1.op4 y Color2
} -result brown
test option-5.6 {basic option retrieval} -body {
    option get .op1.op4 z Color2
} -result {}


test option-6.1 {basic option retrieval} -body {
    option get .op2 x Color1
} -result orange
test option-6.2 {basic option retrieval} -body {
    option get .op2 y Color1
} -result orange
test option-6.3 {basic option retrieval} -body {
    option get .op2 z Color1
} -result orange
test option-6.4 {basic option retrieval} -body {
    option get .op2 x Color2
} -result blue
test option-6.5 {basic option retrieval} -body {
    option get .op2 y Color2
} -result {}
test option-6.6 {basic option retrieval} -body {
    option get .op2 z Color2
} -result {}


test option-7.1 {basic option retrieval} -body {
    option get .op2.op5 x Color1
} -result orange
test option-7.2 {basic option retrieval} -body {
    option get .op2.op5 y Color1
} -result orange
test option-7.3 {basic option retrieval} -body {
    option get .op2.op5 z Color1
} -result orange
test option-7.4 {basic option retrieval} -body {
    option get .op2.op5 x Color2
} -result purple
test option-7.5 {basic option retrieval} -body {
    option get .op2.op5 y Color2
} -result purple
test option-7.6 {basic option retrieval} -body {
    option get .op2.op5 z Color2
} -result purple


# Now try similar tests to above, except jump around non-hierarchically
# between windows to make sure that the option stacks are pushed and
# popped correctly.

option get . foo Foo
test option-8.1 {stack pushing/popping} -body {
    option get .op2.op5 x Color1
} -result orange
test option-8.2 {stack pushing/popping} -body {
    option get .op2.op5 y Color1
} -result orange
test option-8.3 {stack pushing/popping} -body {
    option get .op2.op5 z Color1
} -result orange
test option-8.4 {stack pushing/popping} -body {
    option get .op2.op5 x Color2
} -result purple
test option-8.5 {stack pushing/popping} -body {
    option get .op2.op5 y Color2
} -result purple
test option-8.6 {stack pushing/popping} -body {
    option get .op2.op5 z Color2
} -result purple


test option-9.1 {stack pushing/popping} -body {
    option get . x Color1
} -result blue
test option-9.2 {stack pushing/popping} -body {
    option get . y Color1
} -result red
test option-9.3 {stack pushing/popping} -body {
    option get . z Color1
} -result red
test option-9.4 {stack pushing/popping} -body {
    option get . x Color2
} -result blue
test option-9.5 {stack pushing/popping} -body {
    option get . y Color2
} -result {}
test option-9.6 {stack pushing/popping} -body {
    option get . z Color2
} -result {}


test option-10.1 {stack pushing/popping} -body {
    option get .op1.op3.op6 x Color1
} -result blue
test option-10.2 {stack pushing/popping} -body {
    option get .op1.op3.op6 y Color1
} -result red
test option-10.3 {stack pushing/popping} -body {
    option get .op1.op3.op6 z Color1
} -result red
test option-10.4 {stack pushing/popping} -body {
    option get .op1.op3.op6 x Color2
} -result black
test option-10.5 {stack pushing/popping} -body {
    option get .op1.op3.op6 y Color2
} -result black
test option-10.6 {stack pushing/popping} -body {
    option get .op1.op3.op6 z Color2
} -result black


test option-11.1 {stack pushing/popping} -body {
    option get .op1.op3 x Color1
} -result yellow
test option-11.2 {stack pushing/popping} -body {
    option get .op1.op3 y Color1
} -result red
test option-11.3 {stack pushing/popping} -body {
    option get .op1.op3 z Color1
} -result red
test option-11.4 {stack pushing/popping} -body {
    option get .op1.op3 x Color2
} -result yellow
test option-11.5 {stack pushing/popping} -body {
    option get .op1.op3 y Color2
} -result {}
test option-11.6 {stack pushing/popping} -body {
    option get .op1.op3 z Color2
} -result {}


test option-12.1 {stack pushing/popping} -body {
    option get .op1 x Color1
} -result green
test option-12.2 {stack pushing/popping} -body {
    option get .op1 y Color1
} -result red
test option-12.3 {stack pushing/popping} -body {
    option get .op1 z Color1
} -result red
test option-12.4 {stack pushing/popping} -body {
    option get .op1 x Color2
} -result green
test option-12.5 {stack pushing/popping} -body {
    option get .op1 y Color2
} -result {}
test option-12.6 {stack pushing/popping} -body {
    option get .op1 z Color2
} -result {}

# Test the major priority levels (widgetDefault, etc.)

# Configurations for tests 13.*
option clear
option add $appName.op1.a 100 100
option add $appName.op1.A interactive interactive
option add $appName.op1.b userDefault userDefault
option add $appName.op1.B startupFile startupFile
option add $appName.op1.c widgetDefault widgetDefault
option add $appName.op1.C 0 0

test option-13.1 {priority levels} -body {
    option get .op1 a A
} -result 100
test option-13.2 {priority levels} -body {
    option get .op1 b A
} -result interactive
test option-13.3 {priority levels} -body {
    option get .op1 b B
} -result userDefault
test option-13.4 {priority levels} -body {
    option get .op1 c B
} -result startupFile
test option-13.5 {priority levels} -body {
    option get .op1 c C
} -result widgetDefault
option add $appName.op1.B file2 widget
test option-13.6 {priority levels} -body {
    option get .op1 c B
} -result startupFile
option add $appName.op1.B file2 startupFile
test option-13.7 {priority levels} -body {
    option get .op1 c B
} -result file2


# Test various error conditions

test option-14.1 {error conditions} -body {
    option
} -returnCodes error -result {wrong # args: should be "option cmd arg ?arg ...?"}
test option-14.2 {error conditions} -body {
    option x
} -returnCodes error -result {bad option "x": must be add, clear, get, or readfile}
test option-14.3 {error conditions} -body {
    option foo 3
} -returnCodes error -result {bad option "foo": must be add, clear, get, or readfile}
test option-14.4 {error conditions} -body {
    option add 3
} -returnCodes error -result {wrong # args: should be "option add pattern value ?priority?"}
test option-14.5 {error conditions} -body {
    option add . a b c
} -returnCodes error -result {wrong # args: should be "option add pattern value ?priority?"}
test option-14.6 {error conditions} -body {
    option add . a -1
} -returnCodes error -result {bad priority level "-1": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}
test option-14.7 {error conditions} -body {
    option add . a 101
} -returnCodes error -result {bad priority level "101": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}
test option-14.8 {error conditions} -body {
    option add . a gorp
} -returnCodes error -result {bad priority level "gorp": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}
test option-14.9 {error conditions} -body {
    option get 3
} -returnCodes error -result {wrong # args: should be "option get window name class"}
test option-14.10 {error conditions} -body {
    option get 3 4
} -returnCodes error -result {wrong # args: should be "option get window name class"}
test option-14.11 {error conditions} -body {
    option get 3 4 5 6
} -returnCodes error -result {wrong # args: should be "option get window name class"}
test option-14.12 {error conditions} -body {
    option get .gorp.gorp a A
} -returnCodes error -result {bad window path name ".gorp.gorp"}


set option1 [file join [testsDirectory] option.file1]


test option-15.1 {database files} -body {
    option read non-existent
} -returnCodes error -result {couldn't open "non-existent": no such file or directory}
test option-15.2 {database files} -body {
    option read $option1
    option get . x1 color
} -result blue
test option-15.3 {database files} -constraints appNameIsTktest -body {
    option read $option1
    option get . x2 color
} -result green
test option-15.4 {database files} -body {
    option read $option1
    option get . x3 color
} -result purple
test option-15.5 {database files} -body {
    option read $option1
    option get . {x 4} color
} -result brown
test option-15.6 {database files} -body {
    option read $option1
	option get . x6 color
} -result {}
test option-15.7 {database files} -body {
    option read $option1
	option get . x9 color
} -result " \\\t\\A\n"
test option-15.8 {database files} -body {
    option read $option1 widget foo
} -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
test option-15.9 {database files} -body {
    option add *x3 burgundy
    catch {option read $option1 userDefault}
    option get . x3 color
} -result burgundy
test option-15.10 {database files} -body {
    set option2 [file join [testsDirectory] option.file2]
    option read $option2
} -returnCodes error -result {missing colon on line 2}
set option3 [file join [testsDirectory] option.file3]
option read $option3
test option-15.11 {database files} {option get . {x 4} color} brówn

test option-16.1 {ReadOptionFile} -body {
    set option4 [makeFile {} option.file3]
    set file [open $option4 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4

} -result {true false}

set opt162val {label {
  foo bar
}
}
set opt162list [split $opt162val \n]

test option-16.2 {ticket 766ef52f3} {
    set option5 [makeFile {} option.file4]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok
} $opt162list

deleteWindows

# cleanup
cleanupTests
return






|
|
|



<





|
>













<











|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
|
<
<
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
<
|
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
<






|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<



<
<







|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

|
<
<

|
<
<
<



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<


>
>
|
|
|
<
|
|
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
|
|
<
|
|
|
<
|
<
|
|
<
<
<

|
|
|



|
|
<
|
>
|

<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<




<
<
<
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41


42


43


44


45


46


47

48


49


50


51


52
53




54

55


56


57


58


59


60


61

62


63


64


65


66


67


68

69


70


71


72


73


74


75

76



77

78


79


80


81


82

83


84


85


86


87


88



89
90
91
92
93
94
95


96


97


98


99


100


101

102


103


104


105


106


107


108

109


110


111


112


113


114


115

116


117


118


119


120


121


122

123


124


125


126


127


128


129
130
131


132
133
134
135
136
137
138
139


140


141


142


143


144
145


146
147



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193

194
195

196



197



198



199



200



201
202
203

204
205
206

207

208
209



210
211
212
213
214
215
216
217
218

219
220
221
222





223









224

225
226
227
228



# This file is a Tcl script to test out the option-handling facilities
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint appNameIsTktest [expr {[winfo name .] eq "tktest"}]

catch {destroy .op1}
catch {destroy .op2}
set appName [winfo name .]

# First, test basic retrievals, being sure to trigger all the various
# types of NodeElements (EXACT_LEAF_NAME, WILDCARD_NODE_CLASS, and
# everything in-between).

frame .op1 -class Class1
frame .op2 -class Class2
frame .op1.op3 -class Class1
frame .op1.op4 -class Class3
frame .op2.op5 -class Class2
frame .op1.op3.op6 -class Class4


option clear
option add *Color1 red
option add *x blue
option add *Class1.x yellow
option add $appName.op1.x green
option add *Class2.Color1 orange
option add $appName.op2.op5.Color2 purple
option add $appName.Class1.Class3.y brown
option add $appName*op6*Color2 black
option add $appName*Class1.op1.Color2 grey

test option-1.1 {basic option retrieval} {option get . x Color1} blue


test option-1.2 {basic option retrieval} {option get . y Color1} red


test option-1.3 {basic option retrieval} {option get . z Color1} red


test option-1.4 {basic option retrieval} {option get . x Color2} blue


test option-1.5 {basic option retrieval} {option get . y Color2} {}


test option-1.6 {basic option retrieval} {option get . z Color2} {}




test option-2.1 {basic option retrieval} {option get .op1 x Color1} green


test option-2.2 {basic option retrieval} {option get .op1 y Color1} red


test option-2.3 {basic option retrieval} {option get .op1 z Color1} red


test option-2.4 {basic option retrieval} {option get .op1 x Color2} green


test option-2.5 {basic option retrieval} {option get .op1 y Color2} {}
test option-2.6 {basic option retrieval} {option get .op1 z Color2} {}






test option-3.1 {basic option retrieval} {option get .op1.op3 x Color1} yellow


test option-3.2 {basic option retrieval} {option get .op1.op3 y Color1} red


test option-3.3 {basic option retrieval} {option get .op1.op3 z Color1} red


test option-3.4 {basic option retrieval} {option get .op1.op3 x Color2} yellow


test option-3.5 {basic option retrieval} {option get .op1.op3 y Color2} {}


test option-3.6 {basic option retrieval} {option get .op1.op3 z Color2} {}




test option-4.1 {basic option retrieval} {option get .op1.op3.op6 x Color1} blue


test option-4.2 {basic option retrieval} {option get .op1.op3.op6 y Color1} red


test option-4.3 {basic option retrieval} {option get .op1.op3.op6 z Color1} red


test option-4.4 {basic option retrieval} {option get .op1.op3.op6 x Color2} black


test option-4.5 {basic option retrieval} {option get .op1.op3.op6 y Color2} black


test option-4.6 {basic option retrieval} {option get .op1.op3.op6 z Color2} black




test option-5.1 {basic option retrieval} {option get .op1.op4 x Color1} blue


test option-5.2 {basic option retrieval} {option get .op1.op4 y Color1} brown


test option-5.3 {basic option retrieval} {option get .op1.op4 z Color1} red


test option-5.4 {basic option retrieval} {option get .op1.op4 x Color2} blue


test option-5.5 {basic option retrieval} {option get .op1.op4 y Color2} brown


test option-5.6 {basic option retrieval} {option get .op1.op4 z Color2} {}




test option-6.1 {basic option retrieval} {option get .op2 x Color1} orange



test option-6.2 {basic option retrieval} {option get .op2 y Color1} orange

test option-6.3 {basic option retrieval} {option get .op2 z Color1} orange


test option-6.4 {basic option retrieval} {option get .op2 x Color2} blue


test option-6.5 {basic option retrieval} {option get .op2 y Color2} {}


test option-6.6 {basic option retrieval} {option get .op2 z Color2} {}




test option-7.1 {basic option retrieval} {option get .op2.op5 x Color1} orange


test option-7.2 {basic option retrieval} {option get .op2.op5 y Color1} orange


test option-7.3 {basic option retrieval} {option get .op2.op5 z Color1} orange


test option-7.4 {basic option retrieval} {option get .op2.op5 x Color2} purple


test option-7.5 {basic option retrieval} {option get .op2.op5 y Color2} purple


test option-7.6 {basic option retrieval} {option get .op2.op5 z Color2} purple




# Now try similar tests to above, except jump around non-hierarchically
# between windows to make sure that the option stacks are pushed and
# popped correctly.

option get . foo Foo
test option-8.1 {stack pushing/popping} {option get .op2.op5 x Color1} orange


test option-8.2 {stack pushing/popping} {option get .op2.op5 y Color1} orange


test option-8.3 {stack pushing/popping} {option get .op2.op5 z Color1} orange


test option-8.4 {stack pushing/popping} {option get .op2.op5 x Color2} purple


test option-8.5 {stack pushing/popping} {option get .op2.op5 y Color2} purple


test option-8.6 {stack pushing/popping} {option get .op2.op5 z Color2} purple




test option-9.1 {stack pushing/popping} {option get . x Color1} blue


test option-9.2 {stack pushing/popping} {option get . y Color1} red


test option-9.3 {stack pushing/popping} {option get . z Color1} red


test option-9.4 {stack pushing/popping} {option get . x Color2} blue


test option-9.5 {stack pushing/popping} {option get . y Color2} {}


test option-9.6 {stack pushing/popping} {option get . z Color2} {}




test option-10.1 {stack pushing/popping} {option get .op1.op3.op6 x Color1} blue


test option-10.2 {stack pushing/popping} {option get .op1.op3.op6 y Color1} red


test option-10.3 {stack pushing/popping} {option get .op1.op3.op6 z Color1} red


test option-10.4 {stack pushing/popping} {option get .op1.op3.op6 x Color2} black


test option-10.5 {stack pushing/popping} {option get .op1.op3.op6 y Color2} black


test option-10.6 {stack pushing/popping} {option get .op1.op3.op6 z Color2} black




test option-11.1 {stack pushing/popping} {option get .op1.op3 x Color1} yellow


test option-11.2 {stack pushing/popping} {option get .op1.op3 y Color1} red


test option-11.3 {stack pushing/popping} {option get .op1.op3 z Color1} red


test option-11.4 {stack pushing/popping} {option get .op1.op3 x Color2} yellow


test option-11.5 {stack pushing/popping} {option get .op1.op3 y Color2} {}


test option-11.6 {stack pushing/popping} {option get .op1.op3 z Color2} {}




test option-12.1 {stack pushing/popping} {option get .op1 x Color1} green


test option-12.2 {stack pushing/popping} {option get .op1 y Color1} red


test option-12.3 {stack pushing/popping} {option get .op1 z Color1} red


test option-12.4 {stack pushing/popping} {option get .op1 x Color2} green


test option-12.5 {stack pushing/popping} {option get .op1 y Color2} {}


test option-12.6 {stack pushing/popping} {option get .op1 z Color2} {}



# Test the major priority levels (widgetDefault, etc.)



option add $appName.op1.a 100 100
option add $appName.op1.A interactive interactive
option add $appName.op1.b userDefault userDefault
option add $appName.op1.B startupFile startupFile
option add $appName.op1.c widgetDefault widgetDefault
option add $appName.op1.C 0 0

test option-13.1 {priority levels} {option get .op1 a A} 100


test option-13.2 {priority levels} {option get .op1 b A} interactive


test option-13.3 {priority levels} {option get .op1 b B} userDefault


test option-13.4 {priority levels} {option get .op1 c B} startupFile


test option-13.5 {priority levels} {option get .op1 c C} widgetDefault


option add $appName.op1.B file2 widget
test option-13.6 {priority levels} {option get .op1 c B} startupFile


option add $appName.op1.B file2 startupFile
test option-13.7 {priority levels} {option get .op1 c B} file2




# Test various error conditions

test option-14.1 {error conditions} {
    list [catch {option} msg] $msg
} {1 {wrong # args: should be "option cmd arg ?arg ...?"}}
test option-14.2 {error conditions} {
    list [catch {option x} msg] $msg
} {1 {bad option "x": must be add, clear, get, or readfile}}
test option-14.3 {error conditions} {
    list [catch {option foo 3} msg] $msg
} {1 {bad option "foo": must be add, clear, get, or readfile}}
test option-14.4 {error conditions} {
    list [catch {option add 3} msg] $msg
} {1 {wrong # args: should be "option add pattern value ?priority?"}}
test option-14.5 {error conditions} {
    list [catch {option add . a b c} msg] $msg
} {1 {wrong # args: should be "option add pattern value ?priority?"}}
test option-14.6 {error conditions} {
    list [catch {option add . a -1} msg] $msg
} {1 {bad priority level "-1": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}}
test option-14.7 {error conditions} {
    list [catch {option add . a 101} msg] $msg
} {1 {bad priority level "101": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}}
test option-14.8 {error conditions} {
    list [catch {option add . a gorp} msg] $msg
} {1 {bad priority level "gorp": must be widgetDefault, startupFile, userDefault, interactive, or a number between 0 and 100}}
test option-14.9 {error conditions} {
    list [catch {option get 3} msg] $msg
} {1 {wrong # args: should be "option get window name class"}}
test option-14.10 {error conditions} {
    list [catch {option get 3 4} msg] $msg
} {1 {wrong # args: should be "option get window name class"}}
test option-14.11 {error conditions} {
    list [catch {option get 3 4 5 6} msg] $msg
} {1 {wrong # args: should be "option get window name class"}}
test option-14.12 {error conditions} {
    list [catch {option get .gorp.gorp a A} msg] $msg
} {1 {bad window path name ".gorp.gorp"}}


set option1 [file join [testsDirectory] option.file1]
set option2 [file join [testsDirectory] option.file2]

test option-15.1 {database files} {
    list [catch {option read non-existent} msg] $msg
} {1 {couldn't open "non-existent": no such file or directory}}

option read $option1
test option-15.2 {database files} {option get . x1 color} blue

test option-15.3 {database files} appNameIsTktest {option get . x2 color} green



test option-15.4 {database files} {option get . x3 color} purple



test option-15.5 {database files} {option get . {x 4} color} brown



test option-15.6 {database files} {option get . x6 color} {}



test option-15.7 {database files} {option get . x9 color} " \t\\A\n"



test option-15.8 {database files} {
    list [catch {option read $option1 widget foo} msg] $msg
} {1 {wrong # args: should be "option readfile fileName ?priority?"}}

option add *x3 burgundy
catch {option read $option1 userDefault}
test option-15.9 {database files} {option get . x3 color} burgundy

test option-15.10 {database files} {

    list [catch {option read $option2} msg] $msg
} {1 {missing colon on line 2}}




test option-16.1 {ReadOptionFile} {
    set option3 [makeFile {} option.file3]
    set file [open $option3 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option3 userDefault
    set result [list [option get . x7 color] [option get . x8 color]]

    removeFile $option3
    set result
} {true false}






catch {destroy .op1}









catch {destroy .op2}


# cleanup
cleanupTests
return



Changes to tests/pack.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15

16




























17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83






84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000



1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348

1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371


1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
1583
1584

1585
1586
1587
1588
1589
1590
1591

1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618

1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636

1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
# This file is a Tcl script to test out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]






























# Create some test windows.

destroy .pack
toplevel .pack
wm geom .pack 300x200+0+0
wm minsize .pack 1 1
update idletasks
foreach i {a b c d} {
    frame .pack.$i
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30

test pack-1.1 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+0 300x160+0+40}
test pack-1.2 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+160 300x160+0+0}
test pack-1.3 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side left
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+0+80 280x200+20+0}
test pack-1.4 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+280+80 280x200+0+0}


test pack-2.1 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -padx 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+260+80 240x200+0+0}
test pack-2.2 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -padx {10 30}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+250+80 240x200+0+0}






test pack-2.3 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -padx {35 5}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+275+80 240x200+0+0}
test pack-2.4 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipadx 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {60x40+240+80 240x200+0+0}
test pack-2.5 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipadx 5 -padx 10
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {30x40+260+80 250x200+0+0}
test pack-2.6 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -padx 20 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+260+80 240x200+0+0}
test pack-2.7 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -padx {9 31} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+249+80 240x200+0+0}
test pack-2.8 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipadx 20 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {60x40+240+80 240x200+0+0}
test pack-2.9 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipadx 5 -padx 10 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {30x40+260+80 250x200+0+0}
test pack-2.10 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipadx 5 -padx {5 15} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {30x40+255+80 250x200+0+0}
test pack-2.11 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+0 300x160+0+40}
test pack-2.12 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx {0 40}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+120+0 300x160+0+40}
test pack-2.13 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx {31 9}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+151+0 300x160+0+40}
test pack-2.14 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {60x40+120+0 300x160+0+40}
test pack-2.15 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {30x40+135+0 300x160+0+40}
test pack-2.16 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx {5 15}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {30x40+130+0 300x160+0+40}
test pack-2.17 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx 20 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {260x40+20+0 300x160+0+40}
test pack-2.18 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx {25 15} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {260x40+25+0 300x160+0+40}
test pack-2.19 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 20 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {300x40+0+0 300x160+0+40}
test pack-2.20 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {280x40+10+0 300x160+0+40}
test pack-2.21 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx {5 15} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {280x40+5+0 300x160+0+40}

test pack-2.22 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -padx]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1
test pack-2.23 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipadx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipadx]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1

test pack-3.1 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+280+80 280x200+0+0}
test pack-3.2 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady {5 35}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+280+65 280x200+0+0}
test pack-3.3 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady {40 0}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+280+100 280x200+0+0}
test pack-3.4 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x80+280+60 280x200+0+0}
test pack-3.5 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 5 -pady 10
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+280+75 280x200+0+0}
test pack-3.6 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 5 -pady {5 15}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+280+70 280x200+0+0}
test pack-3.7 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady 20 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x160+280+20 280x200+0+0}
test pack-3.8 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady {35 5} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x160+280+35 280x200+0+0}
test pack-3.9 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 20 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x200+280+0 280x200+0+0}
test pack-3.10 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 5 -pady 10 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x180+280+10 280x200+0+0}
test pack-3.11 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -ipady 5 -pady {0 20} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x180+280+0 280x200+0+0}
test pack-3.12 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -pady 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+20 300x120+0+80}
test pack-3.13 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -pady {40 0}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+40 300x120+0+80}
test pack-3.14 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 20
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x80+140+0 300x120+0+80}
test pack-3.15 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady 10
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+10 300x130+0+70}
test pack-3.16 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady {3 17}
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+3 300x130+0+70}
test pack-3.17 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -pady 20 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+20 300x120+0+80}
test pack-3.18 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -pady {39 1} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x40+140+39 300x120+0+80}
test pack-3.19 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 20 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x80+140+0 300x120+0+80}
test pack-3.20 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady 10 -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+10 300x130+0+70}
test pack-3.21 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady {1 19} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+1 300x130+0+70}

test pack-3.22 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -pady]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1
test pack-3.23 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipady]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1

test pack-4.1 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n
    update
    winfo geometry .pack.a
} -result {30x70+135+20}
test pack-4.2 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor ne
    update
    winfo geometry .pack.a
} -result {30x70+260+20}
test pack-4.3 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor e
    update
    winfo geometry .pack.a
} -result {30x70+260+65}
test pack-4.4 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor se
    update
    winfo geometry .pack.a
} -result {30x70+260+110}
test pack-4.5 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor s
    update
    winfo geometry .pack.a
} -result {30x70+135+110}
test pack-4.6 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor sw
    update
    winfo geometry .pack.a
} -result {30x70+10+110}
test pack-4.7 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor w
    update
    winfo geometry .pack.a
} -result {30x70+10+65}
test pack-4.8 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor nw
    update
    winfo geometry .pack.a
} -result {30x70+10+20}
test pack-4.9 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.a
} -result {30x70+135+65}

# Repeat above tests, but with a frame that isn't at (0,0), so that
# we can be sure that the frame offset is being added in correctly.

test pack-5.1 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n
    update
    winfo geometry .pack.b
} -result {60x60+160+60}
test pack-5.2 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor ne
    update
    winfo geometry .pack.b
} -result {60x60+230+60}
test pack-5.3 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor e
    update
    winfo geometry .pack.b
} -result {60x60+230+90}
test pack-5.4 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor se
    update
    winfo geometry .pack.b
} -result {60x60+230+120}
test pack-5.5 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor s

    update
    winfo geometry .pack.b
} -result {60x60+160+120}
test pack-5.6 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor sw
    update
    winfo geometry .pack.b
} -result {60x60+90+120}
test pack-5.7 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor w
    update
    winfo geometry .pack.b
} -result {60x60+90+90}
test pack-5.8 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor nw
    update
    winfo geometry .pack.b
} -result {60x60+90+60}
test pack-5.9 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.b
} -result {60x60+160+90}

test pack-6.1 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+0+80 50x30+20+85 80x80+70+60 40x30+150+85}
test pack-6.2 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side left -expand yes
    pack .pack.b -side left
    pack .pack.c .pack.d -side left -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+18+80 50x30+56+85 80x80+124+60 40x30+241+85}
test pack-6.3 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+140+0 50x30+125+40 80x80+110+70 40x30+130+150}
test pack-6.4 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -expand yes
    pack .pack.b -side top
    pack .pack.c .pack.d -side top -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+140+3 50x30+125+46 80x80+110+79 40x30+130+166}
test pack-6.5 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side right
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+280+80 50x30+230+85 80x80+150+60 40x30+110+85}
test pack-6.6 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -expand yes
    pack .pack.b -side right
    pack .pack.c .pack.d -side right -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+262+80 50x30+194+85 80x80+95+60 40x30+18+85}
test pack-6.7 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side bottom
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+140+160 50x30+125+130 80x80+110+50 40x30+130+20}
test pack-6.8 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -expand yes
    pack .pack.b -side bottom
    pack .pack.c .pack.d -side bottom -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {20x40+140+157 50x30+125+124 80x80+110+40 40x30+130+3}
test pack-6.9 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -expand yes -fill both
    pack .pack.b -side right
    pack .pack.c -side top -expand 1 -fill both
    pack .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {300x65+0+135 50x30+250+52 250x105+0+0 40x30+0+105}
test pack-6.10 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side left -expand yes -fill both
    pack .pack.b -side top
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {100x200+0+0 50x30+175+0 160x170+140+30 40x30+100+170}
test pack-6.11 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side left -expand yes -fill both
    pack .pack.b -side top -expand yes -fill both
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {100x200+0+0 200x100+100+0 160x100+140+100 40x100+100+100}
test pack-6.12 {-expand option} -setup {
    toplevel .pack2 -height 400 -width 400
    wm geometry .pack2 +0+0
    pack propagate .pack2 0

    foreach i {w1 w2 w3} {
        frame .pack2.$i -width 30 -height 30 -bd 2 -relief raised
        label .pack2.$i.l -text $i
        place .pack2.$i.l -relwidth 1.0 -relheight 1.0
    }
} -body {
    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 -ipady 6 -expand 1 -side left
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]
} -cleanup {
    destroy .pack2
} -result {38x42+47+179 38x42+180+179 38x42+314+179}
test pack-6.13 {-expand option} -setup {
    toplevel .pack2 -height 400 -width 400
    wm geometry .pack2 +0+0
    pack propagate .pack2 0
    foreach i {w1 w2 w3} {
        frame .pack2.$i -width 30 -height 30 -bd 2 -relief raised
        label .pack2.$i.l -text $i
        place .pack2.$i.l -relwidth 1.0 -relheight 1.0
    }
} -body {
    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 \
        -ipady 6 -expand 1 -side top
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]
} -cleanup {
    destroy .pack2
} -result {38x42+181+45 38x42+181+178 38x42+181+312}


wm geometry .pack {}
test pack-7.1 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {230 100}
test pack-7.2 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {90 260}
test pack-7.3 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side right -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {230 100}
test pack-7.4 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side bottom -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {90 260}
test pack-7.5 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -padx 5 -pady 10
    pack .pack.b -side right -padx 5 -pady 10
    pack .pack.c -side bottom -padx 5 -pady 10
    pack .pack.d -side left -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {150 210}
test pack-7.6 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.c -side left
    pack .pack.d -side bottom
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {120 120}
test pack-7.7 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right
    pack .pack.c -side bottom
    pack .pack.d -side top
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {100 110}


# For the tests below, create a couple of "pad" windows to shrink
# the available space for the remaining windows.  The tests have to
# be done this way rather than shrinking the whole window, because
# some window managers like mwm won't let a top-level window get
# very small.

pack forget .pack.a .pack.b .pack.c .pack.d
frame .pack.right -width 200 -height 10 -bd 2 -relief raised
frame .pack.bottom -width 10 -height 150 -bd 2 -relief raised
pack .pack.right -side right
pack .pack.bottom -side bottom
pack .pack.a .pack.b .pack.c -side top
update
test pack-8.1 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+30+0 1 50x30+15+40 1 80x80+0+70 1}
wm geom .pack 270x250
update
test pack-8.2 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+25+0 1 50x30+10+40 1 70x30+0+70 1}
wm geom .pack 240x220
update
test pack-8.3 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+10+0 1 40x30+0+40 1 70x30+0+70 0}
wm geom .pack 350x350
update
test pack-8.4 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+65+0 1 50x30+50+40 1 80x80+35+70 1}
wm geom .pack {}
pack .pack.a -side left
pack .pack.b -side right
pack .pack.c -side left
update
test pack-8.5 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
wm geom .pack 320x180
update
test pack-8.6 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x30+0+0 1 50x30+70+0 1 50x30+20+0 1}
wm geom .pack 250x180
update
test pack-8.7 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x30+0+0 1 30x30+20+0 1 50x30+20+0 0}
pack forget .pack.b
update
test pack-8.8 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x30+0+0 1 30x30+20+0 0 30x30+20+0 1}
pack .pack.b -side right -after .pack.a
wm geom .pack {}
update
test pack-8.9 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
pack forget .pack.right .pack.bottom

test pack-9.1 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.b
    pack content .pack
} -result {.pack.b .pack.a .pack.c .pack.d}
test pack-9.2 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.a
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.3 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -before .pack.d
    pack content .pack
} -result {.pack.b .pack.c .pack.a .pack.d}
test pack-9.4 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.d -before .pack.a
    pack content .pack
} -result {.pack.d .pack.a .pack.b .pack.c}
test pack-9.5 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack propagate .pack.c 0
    pack .pack.a -in .pack.c
    list [pack content .pack] [pack content .pack.c]
} -result {{.pack.b .pack.c .pack.d} .pack.a}
test pack-9.6 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -in .pack
    pack content .pack
} -result {.pack.b .pack.c .pack.d .pack.a}
test pack-9.7 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -padx 0
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.8 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c
    pack .pack.d
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.9 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.b .pack.d .pack.c -before .pack.a
    pack content .pack
} -result {.pack.b .pack.d .pack.c .pack.a}
test pack-9.10 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.c .pack.d .pack.b -after .pack.a
    pack content .pack
} -result {.pack.a .pack.c .pack.d .pack.b}

test pack-10.1 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack forget .pack.a
    pack .pack.a
    pack info .pack.a
} -result {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}
test pack-10.2 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack .pack.a -pady 14
    pack info .pack.a
} -result {-in .pack -anchor n -expand 1 -fill both -ipadx 3 -ipady 4 -padx 1 -pady 14 -side bottom}
test pack-10.3 {bad -in window does not change container window} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    set result [list [winfo manager .pack.a]]
    catch {pack .pack.a -in .pack.a}
    lappend result [winfo manager .pack.a]
} -result {{} {}}
test pack-10.4 {bad -in window does not change container window} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    winfo manager .pack.a
    pack .pack.a -in .pack.a
} -returnCodes error -result {can't pack ".pack.a" inside itself}
test pack-10.5 {prevent management loops} -body {
    frame .f1
    frame .f2
    pack .f1 -in .f2
    pack .f2 -in .f1
} -cleanup {
    destroy .f1
    destroy .f2
} -returnCodes error -result {can't put ".f2" inside ".f1": would cause management loop}
test pack-10.6 {prevent management loops} -body {
    frame .f1
    frame .f2
    frame .f3
    pack .f1 -in .f2
    pack .f2 -in .f3
    pack .f3 -in .f1
} -cleanup {
    destroy .f1
    destroy .f2
    destroy .f3
} -returnCodes error -result {can't put ".f3" inside ".f1": would cause management loop}

test pack-11.1 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in .pack
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -in]+1]
} -result .pack
test pack-11.2 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d



} -body {
    pack .pack.a -anchor n
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -anchor]+1]
} -result n
test pack-11.3 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -anchor sw
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -anchor]+1]
} -result sw
test pack-11.4 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -expand yes
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -expand]+1]
} -result 1
test pack-11.5 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -expand no
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -expand]+1]
} -result 0
test pack-11.6 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -fill x
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -fill]+1]
} -result x
test pack-11.7 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -fill y
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -fill]+1]
} -result y
test pack-11.8 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -fill both
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -fill]+1]
} -result both
test pack-11.9 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -fill none
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -fill]+1]
} -result none
test pack-11.10 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipadx 14
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -ipadx]+1]
} -result 14
test pack-11.11 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipady 22
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -ipady]+1]
} -result 22
test pack-11.12 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx 2
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -padx]+1]
} -result 2
test pack-11.13 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx {2 9}
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -padx]+1]
} -result {2 9}
test pack-11.14 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady 3

    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -pady]+1]
} -result 3
test pack-11.15 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady {3 11}
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -pady]+1]
} -result {3 11}
test pack-11.16 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result top
test pack-11.17 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result bottom
test pack-11.18 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side left
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result left
test pack-11.19 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result right

test pack-12.1 {command options and errors} -body {
    pack
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.2 {command options and errors} -body {
    pack foo
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.3 {command options and errors} -body {
    pack configure x
} -returnCodes error -result {bad argument "x": must be name of window}
test pack-12.4 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack configure .pack.b .pack.c
    pack content .pack
} -result {.pack.b .pack.c}
test pack-12.5 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .foo
} -returnCodes error -result {bad window path name ".foo"}
test pack-12.6 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack
} -returnCodes error -result {can't pack ".pack": it's a top-level window}
test pack-12.7 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -after .foo
} -returnCodes error -result {bad window path name ".foo"}
test pack-12.8 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -after .pack.b
} -returnCodes error -result {window ".pack.b" isn't packed}
test pack-12.9 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -anchor gorp
} -returnCodes error -result {bad anchor "gorp": must be n, ne, e, se, s, sw, w, nw, or center}
test pack-12.10 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -before gorp
} -returnCodes error -result {bad window path name "gorp"}
test pack-12.11 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -before .pack.b
} -returnCodes error -result {window ".pack.b" isn't packed}
test pack-12.12 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -expand "who cares?"
} -returnCodes error -result {expected boolean value but got "who cares?"}
test pack-12.13 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -fill z
} -returnCodes error -result {bad fill style "z": must be none, x, y, or both}
test pack-12.14 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in z
} -returnCodes error -result {bad window path name "z"}
set pad [winfo pixels .pack 1c]
test pack-12.15 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx abc
} -returnCodes error -result {bad pad value "abc": must be positive screen distance}
test pack-12.16 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx {5 abc}
} -returnCodes error -result {bad 2nd pad value "abc": must be positive screen distance}
test pack-12.17 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx -1
} -returnCodes error -result {bad pad value "-1": must be positive screen distance}
test pack-12.18 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx {5 -1}
} -returnCodes error -result {bad 2nd pad value "-1": must be positive screen distance}
test pack-12.19 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady abc
} -returnCodes error -result {bad pad value "abc": must be positive screen distance}
test pack-12.20 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady {0 abc}
} -returnCodes error -result {bad 2nd pad value "abc": must be positive screen distance}
test pack-12.21 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady -1
} -returnCodes error -result {bad pad value "-1": must be positive screen distance}
test pack-12.22 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady {0 -1}
} -returnCodes error -result {bad 2nd pad value "-1": must be positive screen distance}
test pack-12.23 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipadx abc
} -returnCodes error -result {bad ipadx value "abc": must be positive screen distance}
test pack-12.24 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipadx -1
} -returnCodes error -result {bad ipadx value "-1": must be positive screen distance}
test pack-12.25 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipadx {5 5}
} -returnCodes error -result {bad ipadx value "5 5": must be positive screen distance}
test pack-12.26 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipady abc
} -returnCodes error -result {bad ipady value "abc": must be positive screen distance}
test pack-12.27 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipady -1
} -returnCodes error -result {bad ipady value "-1": must be positive screen distance}
test pack-12.28 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -ipady {5 5}
} -returnCodes error -result {bad ipady value "5 5": must be positive screen distance}
test pack-12.29 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bac
} -returnCodes error -result {bad side "bac": must be top, bottom, left, or right}
test pack-12.30 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -lousy bac
} -returnCodes error -result {bad option "-lousy": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}
test pack-12.31 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx
} -returnCodes error -result {extra option "-padx" (option with no value?)}
test pack-12.32 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a ? 22
} -returnCodes error -result {bad option "?": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}
test pack-12.33 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in .
} -returnCodes error -result {can't pack ".pack.a" inside "."}
test pack-12.34 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    frame .pack.a.a
    pack .pack.a.a -in .pack.b
} -returnCodes error -result {can't pack ".pack.a.a" inside ".pack.b"}
test pack-12.35 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in .pack.a
} -returnCodes error -result {can't pack ".pack.a" inside itself}
test pack-12.36 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack forget .pack.a .pack.d
    pack content .pack
} -result {.pack.b .pack.c}
test pack-12.37 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    .pack configure -width 300 -height 200
    pack propagate .pack 0
    pack .pack.a
    update
    set result [list [winfo reqwidth .pack] [winfo reqheight .pack]]
    pack propagate .pack 1
    update
    lappend result [winfo reqwidth .pack] [winfo reqheight .pack]
    return $result
} -result {300 200 20 40}
test pack-12.38 {command options and errors} -body {
    set result [pack propagate .pack.d]
    pack propagate .pack.d 0
    lappend result [pack propagate .pack.d]
    pack propagate .pack.d 1
    lappend result [pack propagate .pack.d]
    return $result
} -result {1 0 1}
test pack-12.39 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack propagate .dum
} -returnCodes error -result {bad window path name ".dum"}
test pack-12.40 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack propagate .pack foo
} -returnCodes error -result {expected boolean value but got "foo"}
test pack-12.41 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack propagate .pack foo bar
} -returnCodes error -result {wrong # args: should be "pack propagate window ?boolean?"}
test pack-12.42 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack content
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.43 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {

    pack content a b
} -returnCodes error -result {wrong # args: should be "pack content window"}
test pack-12.44 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack content .x
} -returnCodes error -result {bad window path name ".x"}
test pack-12.45 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack content .pack.a
} -returnCodes ok -result {}
test pack-12.46 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack lousy .pack
} -returnCodes error -result {bad option "lousy": must be configure, content, forget, info, or propagate}

test pack-13.1 {window deletion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom


    pack .pack.a .pack.d .pack.b .pack.c -side top
    update
    destroy .pack.d
    update
    set result [list [pack content .pack] [winfo geometry .pack.a] \
        [winfo geometry .pack.b] [winfo geometry .pack.c]]
} -result {{.pack.right .pack.bottom .pack.a .pack.b .pack.c} 20x40+30+0 50x30+15+40 80x80+0+70}

test pack-14.1 {respond to changes in expansion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    wm geom .pack {}
    pack .pack.a
    update
    set result [winfo geom .pack.a]
    wm geom .pack 400x300
    update
    lappend result [winfo geom .pack.a]
    pack .pack.a -expand true -fill both
    update
    lappend result [winfo geom .pack.a]
} -cleanup {
    wm geom .pack {}
} -result {20x40+0+0 20x40+90+0 200x150+0+0}


test pack-15.1 {managing geometry with -in option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    destroy .pack.f
} -body {
    pack .pack.a -side top
    frame .pack.f
    lower .pack.f
    pack .pack.f -side top
    frame .pack.f.f2
    lower .pack.f.f2
    pack .pack.f.f2 -side top
    pack .pack.b -in .pack.f.f2
    update
    set result [winfo geom .pack.b]
    pack forget .pack.a
    update
    lappend result [winfo geom .pack.b]
} -cleanup {
    destroy .pack.f
} -result {50x30+0+40 50x30+0+0}
test pack-15.2 {managing geometry with -in option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    destroy .pack.f
} -body {
    frame .pack.f
    lower .pack.f
    pack .pack.a -in .pack.f -side top
    update
    set result [winfo ismapped .pack.a]
    place .pack.f -x 30 -y 45
    update
    lappend result [winfo ismapped .pack.a] [winfo geometry .pack.a]
    place forget .pack.f
    update
    lappend result [winfo ismapped .pack.a]
} -cleanup {
    destroy .pack.f
} -result {0 1 20x40+30+45 0}
test pack-15.3 {managing geometry with -in option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    destroy .pack.f
} -body {
    pack .pack.a -side top
    frame .pack.f
    lower .pack.f
    pack .pack.f -side top
    frame .pack.f.f2
    lower .pack.f.f2
    pack .pack.f.f2 -side top
    pack .pack.b -in .pack.f.f2
    update
    set result [winfo ismapped .pack.b]
    pack forget .pack.f
    update
    lappend result [winfo ismapped .pack.b]
} -cleanup {
    destroy .pack.f
} -result {1 0}
test pack-15.4 {managing geometry with -in option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    destroy .pack.f1 .pack.f2
} -body {
    foreach i {1 2} {
        frame .pack.f$i -width 100 -height 40 -bd 2 -relief raised
        lower .pack.f$i
        pack propagate .pack.f$i 0
        pack .pack.f$i -side top
    }
    pack .pack.b -in .pack.f1 -side right
    update
    set result {}
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack .pack.b -in .pack.f2 -side bottom
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    .pack.f1 configure -width 50 -height 20
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack forget .pack.b
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
} -cleanup {
    destroy .pack.f1 .pack.f2
} -result {50x30+48+5 1 50x30+25+48 1 50x30+25+28 1 50x30+25+28 0}

test pack-15.5 {managing geometry with -in option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    destroy .pack.f1 .pack.f2
} -body {
    foreach i {1 2} {
        frame .pack.f$i -width 100 -height 20 -bd 2 -relief raised
        lower .pack.f$i
        pack propagate .pack.f$i 0
        pack .pack.f$i -side top
    }
    pack .pack.b -in .pack.f2 -side top
    update
    set result {}
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack .pack.a -before .pack.b -side top
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
} -cleanup {
    destroy .pack.f1 .pack.f2
} -result {50x16+25+22 1 50x16+25+22 0}

test pack-16.1 {geometry manager name} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    set result {}
} -body {
    lappend result [winfo manager .pack.a]
    pack .pack.a
    lappend result [winfo manager .pack.a]
    pack forget .pack.a
    lappend result [winfo manager .pack.a]
} -result {{} pack {}}

test pack-17.1 {PackLostContentProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
    update
    list [winfo manager .pack.a] [winfo geometry .pack.a]
} -result {place 20x40+40+10}
test pack-17.2 {PackLostContentProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
    update
    winfo manager .pack.a
    winfo geometry .pack.a
    pack info .pack.a
} -returnCodes error -result {window ".pack.a" isn't packed}

if {[tk windowingsystem] == "win32"} {
    proc packUpdate {} {
	update

    }
} else {
    proc packUpdate {} {
    }
}

test pack-18.1 {unmap content when container unmapped} -constraints {
    tempNotPc failsOnUbuntu failsOnXQuarz
} -setup {
    eval destroy [winfo child .pack]
} -body {
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
    # unmapped, the changes don't take effect until the window is remapped.
    # Who knows why?

    eval destroy [winfo child .pack]
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update idletasks
    set result [winfo ismapped .pack.a]
    wm iconify .pack

    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update idletasks
    lappend result [winfo width .pack.a ] [winfo height .pack.a] \
    [winfo ismapped .pack.a]
    wm deiconify .pack
    packUpdate
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}


test pack-18.2 {unmap content when container unmapped} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    eval destroy [winfo child .pack]
} -body {
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
    pack .pack.a
    pack .pack.b -in .pack.a
    update idletasks
    set result [winfo ismapped .pack.b]
    wm iconify .pack

    lappend result [winfo ismapped .pack.b]
    .pack.b configure -width 100 -height 30
    update idletasks
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
    [winfo ismapped .pack.b]
    wm deiconify .pack
    packUpdate
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}

test pack-19.1 {test respect for internalborder} -setup {
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    pack .pack.lf.f -fill both -expand 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
} -cleanup {
    destroy .pack.l .pack.lf

} -result {196x188+2+10 177x186+5+7}
test pack-19.2 {test support for minreqsize} -setup {
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25
    pack .pack.lf.f
    update
    set res [list [winfo geometry .pack.lf]]
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]
} -cleanup {
    destroy .pack.l .pack.lf

} -result {162x127+0+0 172x112+0+0}

test pack-20.1 {<<NoManagedChild>> fires on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result 1
test pack-20.2 {<<NoManagedChild>> fires on last packed child destruction} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <<NoManagedChild>> {incr A}
    destroy .1
    update
    set A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result 1
test pack-20.3 {<Configure> does not fire on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <Configure> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    destroy .1
} -result 0
test pack-20.4 {<<NoManagedChild>> does not fire on forelast pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack [frame .2]
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1 .2
} -result 0
test pack-20.5 {<Configure> does not fire on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack [frame .2]
    update
    bind . <Configure> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    destroy .1 .2
} -result 1
test pack-20.6 {<<NoManagedChild>> does not fire on last pack forget if propagation is off} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack propagate . 0
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result 0


# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
|
|

|
|
|





<

|
>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|













|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|

<
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
<
|
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
>
|

<


|
<
<
|
|

<


|
<
<
|

|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
>
|

<


|
<
<
|
|

<


|
<
<
|

|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
<
|
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|




|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
>
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|

|

<



|
|
|

<





|
|
|

<



|
|
|

<





|
|
|

<



|
|
|

<





|
|
|

<



|
|
|

<





|
|
|

<






|
|
|

<






|
|
|

<






|
|
|
|
|
|
>
|
|
|
|
|
|



<
<
|
|
<
<
<
<
<
|
<
<
<

|


<
<
|
>


|

<



|
|

<



|
|

<



|
|

<



|
|

<






|
|

<





|
|

<





|
>














|

|
|
|


|

|
|
|


|

|
|
|


|

|
|
|





|

|
|
|


|

|
|
|


|

|
|
|


|

|
|
|



|

|
|
|


|

<


|
|
|

<


|
|
|

<


|
|
|

<


|
|
|

<



|
|
|

<


|
|
|

<


|
|
|

<


|
|
|

<


|
|
|

<


|
|

|

<

|



|
|

<

|


|
|

<
|
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
<
<
|
|
|
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
>
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<
<
|

|
|
|
|
|
|
|
|
|
|

<

|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|

|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<

|
|
|

<
|
|
|

<


|
|
|

<








|
|
|





|
|
|

<
|
|
|

<
|
|
|

<
|
|
|

<
|
|
<
<
|
>
|
|
|

<
|
|
|

<
|
|
|

<
|
|

<
<
<
|
|
>
>




|
|
|

|
|
<
<
<










<
<
|
|

|

<
<










|


|
|
<
|

<
<











|
|
<
|

<
<










|


|
|
<
|

<
<

|
|
|
|














<
<
|
>
|

<
<

|
|
|
|








|
|
<

|


<





|

|

<




|
<
<
<
<
<
<
<
<
<
<
|
|

<
<
<
>
|
<
<
<
<
<
<
<
<
<
<













|


>


|

|

|

|
>

<
<
<





>




|


>


|

|

|

|

|
|

<











<

>
|
|
|

<











<

>
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
>



<
<
<
<
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64



65
66


67



68
69


70



71
72


73



74
75

76


77



78
79


80



81
82
83
84
85
86
87
88


















89



90
91


92



93
94


95



96
97


98



99
100



101


102
103


104



105
106


107



108
109


110



111
112


113



114
115


116



117
118


119



120
121


122



123
124


125



126
127


128



129
130


131



132
133


134



135
136


137



138
139
140
141

142
143
144


145
146
147

148
149
150


151
152
153


154



155
156


157



158
159


160



161
162


163



164
165


166



167
168


169



170
171


172



173
174


175



176
177


178



179
180


181



182
183


184



185
186


187



188
189


190



191
192


193



194
195


196



197
198


199



200
201


202



203
204


205



206
207


208



209
210


211



212
213


214



215
216
217
218

219
220
221


222
223
224

225
226
227


228
229
230


231


232
233


234


235
236


237


238
239


240


241

242

243


244
245


246


247
248


249


250
251


252


253
254


255


256
257
258
259
260
261




262


263
264




265


266
267




268


269
270




271


272
273




274
275



276




277


278
279




280


281
282




283


284
285




286


287
288
289
290

291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396


397
398





399



400
401
402
403


404
405
406
407
408
409

410
411
412
413
414
415

416
417
418
419
420
421

422
423
424
425
426
427

428
429
430
431
432
433

434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546

547
548
549
550
551
552

553
554
555
556
557
558

559
560
561
562
563
564

565
566
567
568
569
570
571

572
573
574
575
576
577

578
579
580
581
582
583

584
585
586
587
588
589

590
591
592
593
594
595

596
597
598
599
600
601
602

603
604
605
606
607
608
609
610

611
612
613
614
615
616
617

618
619





620
621






















622
623


624


625
626
627
628
629
630
631











632


633


634
635


636


637
638


639


640
641


642


643
644


645


646
647


648


649
650


651


652
653


654


655
656


657


658
659


660


661
662


663
664
665
666
667
668
669











670
671


672


673
674


675


676
677


678


679
680
681
682
683
684
685
686
687
688
689
690
691

692
693
694
695
696

697
698
699
700

701
702
703
704

705
706
707
708

709
710
711
712

713
714
715
716

717
718
719
720

721
722
723
724

725
726
727
728

729
730
731
732

733
734
735
736
737

738
739
740
741

742
743
744
745

746
747
748
749

750
751
752
753

754
755
756
757

758
759
760
761

762
763
764
765

766
767
768
769

770
771
772
773

774
775
776
777

778
779
780
781

782
783
784
785

786
787
788
789

790
791
792
793

794
795
796
797

798
799
800
801

802
803
804
805

806
807
808
809

810
811
812
813

814
815
816
817
818

819
820
821
822

823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852

853
854
855
856

857
858
859
860

861
862


863
864
865
866
867
868

869
870
871
872

873
874
875
876

877
878
879



880
881
882
883
884
885
886
887
888
889
890
891
892
893



894
895
896
897
898
899
900
901
902
903


904
905
906
907
908


909
910
911
912
913
914
915
916
917
918
919
920
921
922
923

924
925


926
927
928
929
930
931
932
933
934
935
936
937
938

939
940


941
942
943
944
945
946
947
948
949
950
951
952
953
954
955

956
957


958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976


977
978
979
980


981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998
999

1000
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013










1014
1015
1016



1017
1018










1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046



1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073

1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105























































1106









1107










1108










1109
1110
1111
1112
1113




# This file is a Tcl script to test out the "pack" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# Utility procedures:

proc pack1 {args} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    eval pack .pack.a $args
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
}
proc pack2 {args} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    eval pack .pack.a $args
    update
    winfo geometry .pack.a
}
proc pack3 {args} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    pack .pack.a -side  top
    pack .pack.c -side left
    eval pack .pack.b $args
    update
    winfo geometry .pack.b
}
proc pack4 {option value} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    pack .pack.a $option $value
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i $option]+1]
}

# Create some test windows.

catch {destroy .pack}
toplevel .pack
wm geom .pack 300x200+0+0
wm minsize .pack 1 1
update idletasks
foreach i {a b c d} {
    frame .pack.$i
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30

test pack-1.1 {-side option} {


    pack1 -side top



} {20x40+140+0 300x160+0+40}
test pack-1.2 {-side option} {


    pack1 -side bottom



} {20x40+140+160 300x160+0+0}
test pack-1.3 {-side option} {


    pack1 -side left



} {20x40+0+80 280x200+20+0}
test pack-1.4 {-side option} {


    pack1 -side right



} {20x40+280+80 280x200+0+0}


test pack-2.1 {x padding and filling} {


    pack1 -side right -padx 20



} {20x40+260+80 240x200+0+0}
test pack-2.1.1 {x padding and filling} {


    pack1 -side right -padx {10 30}



} {20x40+250+80 240x200+0+0}
test pack-2.1.2 {x padding and filling} {
    pack1 -side right -padx {35 5}
} {20x40+275+80 240x200+0+0}
test pack-2.2 {x padding and filling} {
    pack1 -side right -ipadx 20
} {60x40+240+80 240x200+0+0}
test pack-2.3 {x padding and filling} {


















    pack1 -side right -ipadx 5 -padx 10



} {30x40+260+80 250x200+0+0}
test pack-2.4 {x padding and filling} {


    pack1 -side right -padx 20 -fill x



} {20x40+260+80 240x200+0+0}
test pack-2.4.1 {x padding and filling} {


    pack1 -side right -padx {9 31} -fill x



} {20x40+249+80 240x200+0+0}
test pack-2.5 {x padding and filling} {


    pack1 -side right -ipadx 20 -fill x



} {60x40+240+80 240x200+0+0}
test pack-2.6 {x padding and filling} {



    pack1 -side right -ipadx 5 -padx 10 -fill x


} {30x40+260+80 250x200+0+0}
test pack-2.6.1 {x padding and filling} {


    pack1 -side right -ipadx 5 -padx {5 15} -fill x



} {30x40+255+80 250x200+0+0}
test pack-2.7 {x padding and filling} {


    pack1 -side top -padx 20



} {20x40+140+0 300x160+0+40}
test pack-2.7.1 {x padding and filling} {


    pack1 -side top -padx {0 40}



} {20x40+120+0 300x160+0+40}
test pack-2.7.2 {x padding and filling} {


    pack1 -side top -padx {31 9}



} {20x40+151+0 300x160+0+40}
test pack-2.8 {x padding and filling} {


    pack1 -side top -ipadx 20



} {60x40+120+0 300x160+0+40}
test pack-2.9 {x padding and filling} {


    pack1 -side top -ipadx 5 -padx 10



} {30x40+135+0 300x160+0+40}
test pack-2.9.1 {x padding and filling} {


    pack1 -side top -ipadx 5 -padx {5 15}



} {30x40+130+0 300x160+0+40}
test pack-2.10 {x padding and filling} {


    pack1 -side top -padx 20 -fill x



} {260x40+20+0 300x160+0+40}
test pack-2.10.1 {x padding and filling} {


    pack1 -side top -padx {25 15} -fill x



} {260x40+25+0 300x160+0+40}
test pack-2.11 {x padding and filling} {


    pack1 -side top -ipadx 20 -fill x



} {300x40+0+0 300x160+0+40}
test pack-2.12 {x padding and filling} {


    pack1 -side top -ipadx 5 -padx 10 -fill x



} {280x40+10+0 300x160+0+40}
test pack-2.12a {x padding and filling} {


    pack1 -side top -ipadx 5 -padx {5 15} -fill x



} {280x40+5+0 300x160+0+40}
set pad [winfo pixels .pack 1c]
test pack-2.13 {x padding and filling} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -padx 1c
    set x [pack info .pack.a]
    lindex $x [expr [lsearch -exact $x -padx]+1]


} $pad
test pack-2.14 {x padding and filling} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -ipadx 1c
    set x [pack info .pack.a]
    lindex $x [expr [lsearch -exact $x -ipadx]+1]


} $pad

test pack-3.1 {y padding and filling} {


    pack1 -side right -pady 20



} {20x40+280+80 280x200+0+0}
test pack-3.1.1 {y padding and filling} {


    pack1 -side right -pady {5 35}



} {20x40+280+65 280x200+0+0}
test pack-3.1.2 {y padding and filling} {


    pack1 -side right -pady {40 0}



} {20x40+280+100 280x200+0+0}
test pack-3.2 {y padding and filling} {


    pack1 -side right -ipady 20



} {20x80+280+60 280x200+0+0}
test pack-3.3 {y padding and filling} {


    pack1 -side right -ipady 5 -pady 10



} {20x50+280+75 280x200+0+0}
test pack-3.3.1 {y padding and filling} {


    pack1 -side right -ipady 5 -pady {5 15}



} {20x50+280+70 280x200+0+0}
test pack-3.4 {y padding and filling} {


    pack1 -side right -pady 20 -fill y



} {20x160+280+20 280x200+0+0}
test pack-3.4.1 {y padding and filling} {


    pack1 -side right -pady {35 5} -fill y



} {20x160+280+35 280x200+0+0}
test pack-3.5 {y padding and filling} {


    pack1 -side right -ipady 20 -fill y



} {20x200+280+0 280x200+0+0}
test pack-3.6 {y padding and filling} {


    pack1 -side right -ipady 5 -pady 10 -fill y



} {20x180+280+10 280x200+0+0}
test pack-3.6.1 {y padding and filling} {


    pack1 -side right -ipady 5 -pady {0 20} -fill y



} {20x180+280+0 280x200+0+0}
test pack-3.7 {y padding and filling} {


    pack1 -side top -pady 20



} {20x40+140+20 300x120+0+80}
test pack-3.7.1 {y padding and filling} {


    pack1 -side top -pady {40 0}



} {20x40+140+40 300x120+0+80}
test pack-3.8 {y padding and filling} {


    pack1 -side top -ipady 20



} {20x80+140+0 300x120+0+80}
test pack-3.9 {y padding and filling} {


    pack1 -side top -ipady 5 -pady 10



} {20x50+140+10 300x130+0+70}
test pack-3.9.1 {y padding and filling} {


    pack1 -side top -ipady 5 -pady {3 17}



} {20x50+140+3 300x130+0+70}
test pack-3.10 {y padding and filling} {


    pack1 -side top -pady 20 -fill y



} {20x40+140+20 300x120+0+80}
test pack-3.10.1 {y padding and filling} {


    pack1 -side top -pady {39 1} -fill y



} {20x40+140+39 300x120+0+80}
test pack-3.11 {y padding and filling} {


    pack1 -side top -ipady 20 -fill y



} {20x80+140+0 300x120+0+80}
test pack-3.12 {y padding and filling} {


    pack1 -side top -ipady 5 -pady 10 -fill y



} {20x50+140+10 300x130+0+70}
test pack-3.12.1 {y padding and filling} {


    pack1 -side top -ipady 5 -pady {1 19} -fill y



} {20x50+140+1 300x130+0+70}
set pad [winfo pixels .pack 1c]
test pack-3.13 {y padding and filling} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -pady 1c
    set x [pack info .pack.a]
    lindex $x [expr [lsearch -exact $x -pady]+1]


} $pad
test pack-3.14 {y padding and filling} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -ipady 1c
    set x [pack info .pack.a]
    lindex $x [expr [lsearch -exact $x -ipady]+1]


} $pad

test pack-4.1 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n


} {30x70+135+20}
test pack-4.2 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor ne


} {30x70+260+20}
test pack-4.3 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor e


} {30x70+260+65}
test pack-4.4 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor se


} {30x70+260+110}

test pack-4.5 {anchors} {

    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor s


} {30x70+135+110}
test pack-4.6 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor sw


} {30x70+10+110}
test pack-4.7 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor w


} {30x70+10+65}
test pack-4.8 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor nw


} {30x70+10+20}
test pack-4.9 {anchors} {


    pack2 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center


} {30x70+135+65}

# Repeat above tests, but with a frame that isn't at (0,0), so that
# we can be sure that the frame offset is being added in correctly.

test pack-5.1 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n


} {60x60+160+60}
test pack-5.2 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor ne


} {60x60+230+60}
test pack-5.3 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor e


} {60x60+230+90}
test pack-5.4 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor se


} {60x60+230+120}
test pack-5.5 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor s
} {60x60+160+120}



test pack-5.6 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor sw


} {60x60+90+120}
test pack-5.7 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor w


} {60x60+90+90}
test pack-5.8 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor nw


} {60x60+90+60}
test pack-5.9 {more anchors} {




    pack3 -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center


} {60x60+160+90}

test pack-6.1 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+0+80 50x30+20+85 80x80+70+60 40x30+150+85}
test pack-6.2 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side left -expand yes
    pack .pack.b -side left
    pack .pack.c .pack.d -side left -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+18+80 50x30+56+85 80x80+124+60 40x30+241+85}
test pack-6.3 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+140+0 50x30+125+40 80x80+110+70 40x30+130+150}
test pack-6.4 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side top -expand yes
    pack .pack.b -side top
    pack .pack.c .pack.d -side top -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+140+3 50x30+125+46 80x80+110+79 40x30+130+166}
test pack-6.5 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side right
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+280+80 50x30+230+85 80x80+150+60 40x30+110+85}
test pack-6.6 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side right -expand yes
    pack .pack.b -side right
    pack .pack.c .pack.d -side right -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+262+80 50x30+194+85 80x80+95+60 40x30+18+85}
test pack-6.7 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side bottom
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+140+160 50x30+125+130 80x80+110+50 40x30+130+20}
test pack-6.8 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side bottom -expand yes
    pack .pack.b -side bottom
    pack .pack.c .pack.d -side bottom -expand 1
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {20x40+140+157 50x30+125+124 80x80+110+40 40x30+130+3}
test pack-6.9 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side bottom -expand yes -fill both
    pack .pack.b -side right
    pack .pack.c -side top -expand 1 -fill both
    pack .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {300x65+0+135 50x30+250+52 250x105+0+0 40x30+0+105}
test pack-6.10 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side left -expand yes -fill both
    pack .pack.b -side top
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {100x200+0+0 50x30+175+0 160x170+140+30 40x30+100+170}
test pack-6.11 {-expand option} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side left -expand yes -fill both
    pack .pack.b -side top -expand yes -fill both
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
	    [winfo geometry .pack.c] [winfo geometry .pack.d]
} {100x200+0+0 200x100+100+0 160x100+140+100 40x100+100+100}
catch {destroy .pack2}
toplevel .pack2 -height 400 -width 400
wm geometry .pack2 +0+0
pack propagate .pack2 0
pack forget .pack2.a .pack2.b .pack2.c .pack2.d
foreach i {w1 w2 w3} {
    frame .pack2.$i -width 30 -height 30 -bd 2 -relief raised
    label .pack2.$i.l -text $i
    place .pack2.$i.l -relwidth 1.0 -relheight 1.0
}
test pack-6.12 {-expand option} {
    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 -ipady 6 -expand 1 -side left
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]


} {38x42+47+179 38x42+180+179 38x42+314+179}
test pack-6.13 {-expand option} {





    pack forget .pack2.w1 .pack2.w2 .pack2.w3



    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 \
	    -ipady 6 -expand 1 -side top
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]


} {38x42+181+45 38x42+181+178 38x42+181+312}
catch {destroy .pack2}

wm geometry .pack {}
test pack-7.1 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side left -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {230 100}
test pack-7.2 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {90 260}
test pack-7.3 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side right -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {230 100}
test pack-7.4 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side bottom -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {90 260}
test pack-7.5 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side top -padx 5 -pady 10
    pack .pack.b -side right -padx 5 -pady 10
    pack .pack.c -side bottom -padx 5 -pady 10
    pack .pack.d -side left -padx 5 -pady 10
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {150 210}
test pack-7.6 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side top
    pack .pack.c -side left
    pack .pack.d -side bottom
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {120 120}
test pack-7.7 {requesting size for parent} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side right
    pack .pack.c -side bottom
    pack .pack.d -side top
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} {100 110}


# For the tests below, create a couple of "pad" windows to shrink
# the available space for the remaining windows.  The tests have to
# be done this way rather than shrinking the whole window, because
# some window managers like mwm won't let a top-level window get
# very small.

pack forget .pack.a .pack.b .pack.c .pack.d
frame .pack.right -width 200 -height 10 -bd 2 -relief raised
frame .pack.bottom -width 10 -height 150 -bd 2 -relief raised
pack .pack.right -side right
pack .pack.bottom -side bottom
pack .pack.a .pack.b .pack.c -side top
update
test pack-8.1 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+30+0 1 50x30+15+40 1 80x80+0+70 1}
wm geom .pack 270x250
update
test pack-8.2 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+25+0 1 50x30+10+40 1 70x30+0+70 1}
wm geom .pack 240x220
update
test pack-8.3 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+10+0 1 40x30+0+40 1 70x30+0+70 0}
wm geom .pack 350x350
update
test pack-8.4 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+65+0 1 50x30+50+40 1 80x80+35+70 1}
wm geom .pack {}
pack .pack.a -side left
pack .pack.b -side right
pack .pack.c -side left
update
test pack-8.5 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
wm geom .pack 320x180
update
test pack-8.6 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x30+0+0 1 50x30+70+0 1 50x30+20+0 1}
wm geom .pack 250x180
update
test pack-8.7 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x30+0+0 1 30x30+20+0 1 50x30+20+0 0}
pack forget .pack.b
update
test pack-8.8 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x30+0+0 1 30x30+20+0 0 30x30+20+0 1}
pack .pack.b -side right -after .pack.a
wm geom .pack {}
update
test pack-8.9 {insufficient space} {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
	    [winfo geometry .pack.b] [winfo ismapped .pack.b] \
	    [winfo geometry .pack.c] [winfo ismapped .pack.c]
} {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
pack forget .pack.right .pack.bottom

test pack-9.1 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.b
    pack slaves .pack
} {.pack.b .pack.a .pack.c .pack.d}
test pack-9.2 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.a
    pack slaves .pack
} {.pack.a .pack.b .pack.c .pack.d}
test pack-9.3 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -before .pack.d
    pack slaves .pack
} {.pack.b .pack.c .pack.a .pack.d}
test pack-9.4 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.d -before .pack.a
    pack slaves .pack
} {.pack.d .pack.a .pack.b .pack.c}
test pack-9.5 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack propagate .pack.c 0
    pack .pack.a -in .pack.c
    list [pack slaves .pack] [pack slaves .pack.c]
} {{.pack.b .pack.c .pack.d} .pack.a}
test pack-9.6 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -in .pack
    pack slaves .pack
} {.pack.b .pack.c .pack.d .pack.a}
test pack-9.7 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -padx 0
    pack slaves .pack
} {.pack.a .pack.b .pack.c .pack.d}
test pack-9.8 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c
    pack .pack.d
    pack slaves .pack
} {.pack.a .pack.b .pack.c .pack.d}
test pack-9.9 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.b .pack.d .pack.c -before .pack.a
    pack slaves .pack
} {.pack.b .pack.d .pack.c .pack.a}
test pack-9.10 {window ordering} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.c .pack.d .pack.b -after .pack.a
    pack slaves .pack
} {.pack.a .pack.c .pack.d .pack.b}

test pack-10.1 {retaining/clearing configuration state} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
	-fill both -expand 1
    pack forget .pack.a
    pack .pack.a
    pack info .pack.a
} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}
test pack-10.2 {retaining/clearing configuration state} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
	-fill both -expand 1
    pack .pack.a -pady 14
    pack info .pack.a
} {-in .pack -anchor n -expand 1 -fill both -ipadx 3 -ipady 4 -padx 1 -pady 14 -side bottom}
test pack-10.3 {bad -in window does not change master} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [winfo manager .pack.a] \
         [catch {pack .pack.a -in .pack.a} err] $err \





         [winfo manager .pack.a]
} {{} 1 {can't pack .pack.a inside itself} {}}























test pack-11.1 {info option} {


    pack4 -in .pack


} .pack
test pack-11.2 {info option} {
    pack4 -anchor n
} n
test pack-11.3 {info option} {
    pack4 -anchor sw
} sw











test pack-11.4 {info option} {


    pack4 -expand yes


} 1
test pack-11.5 {info option} {


    pack4 -expand no


} 0
test pack-11.6 {info option} {


    pack4 -fill x


} x
test pack-11.7 {info option} {


    pack4 -fill y


} y
test pack-11.8 {info option} {


    pack4 -fill both


} both
test pack-11.9 {info option} {


    pack4 -fill none


} none
test pack-11.10 {info option} {


    pack4 -ipadx 14


} 14
test pack-11.11 {info option} {


    pack4 -ipady 22


} 22
test pack-11.12 {info option} {


    pack4 -padx 2


} 2
test pack-11.12.1 {info option} {


    pack4 -padx {2 9}


} {2 9}
test pack-11.13 {info option} {


    pack4 -pady 3
} 3
test pack-11.13.1 {info option} {
    pack4 -pady {3 11}
} {3 11}
test pack-11.14 {info option} {
    pack4 -side top











} top
test pack-11.15 {info option} {


    pack4 -side bottom


} bottom
test pack-11.16 {info option} {


    pack4 -side left


} left
test pack-11.17 {info option} {


    pack4 -side right


} right

test pack-12.1 {command options and errors} {
    list [catch {pack} msg] $msg
} {1 {wrong # args: should be "pack option arg ?arg ...?"}}
test pack-12.2 {command options and errors} {
    list [catch {pack foo} msg] $msg
} {1 {wrong # args: should be "pack option arg ?arg ...?"}}
test pack-12.3 {command options and errors} {
    list [catch {pack configure x} msg] $msg
} {1 {bad argument "x": must be name of window}}
test pack-12.4 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack configure .pack.b .pack.c
    pack slaves .pack
} {.pack.b .pack.c}
test pack-12.5 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .foo} msg] $msg
} {1 {bad window path name ".foo"}}
test pack-12.6 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack} msg] $msg
} {1 {can't pack ".pack": it's a top-level window}}
test pack-12.7 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -after .foo} msg] $msg
} {1 {bad window path name ".foo"}}
test pack-12.8 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -after .pack.b} msg] $msg
} {1 {window ".pack.b" isn't packed}}
test pack-12.9 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -anchor gorp} msg] $msg
} {1 {bad anchor "gorp": must be n, ne, e, se, s, sw, w, nw, or center}}
test pack-12.10 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -before gorp} msg] $msg
} {1 {bad window path name "gorp"}}
test pack-12.11 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -before .pack.b} msg] $msg
} {1 {window ".pack.b" isn't packed}}
test pack-12.12 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -expand "who cares?"} msg] $msg
} {1 {expected boolean value but got "who cares?"}}
test pack-12.13 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -fill z} msg] $msg
} {1 {bad fill style "z": must be none, x, y, or both}}
test pack-12.14 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -in z} msg] $msg
} {1 {bad window path name "z"}}
set pad [winfo pixels .pack 1c]
test pack-12.15 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -padx abc} msg] $msg
} {1 {bad pad value "abc": must be positive screen distance}}
test pack-12.15.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -padx {5 abc}} msg] $msg
} {1 {bad 2nd pad value "abc": must be positive screen distance}}
test pack-12.16 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -padx -1} msg] $msg
} {1 {bad pad value "-1": must be positive screen distance}}
test pack-12.16.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -padx {5 -1}} msg] $msg
} {1 {bad 2nd pad value "-1": must be positive screen distance}}
test pack-12.17 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -pady abc} msg] $msg
} {1 {bad pad value "abc": must be positive screen distance}}
test pack-12.17.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -pady {0 abc}} msg] $msg
} {1 {bad 2nd pad value "abc": must be positive screen distance}}
test pack-12.18 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -pady -1} msg] $msg
} {1 {bad pad value "-1": must be positive screen distance}}
test pack-12.18.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -pady {0 -1}} msg] $msg
} {1 {bad 2nd pad value "-1": must be positive screen distance}}
test pack-12.19 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipadx abc} msg] $msg
} {1 {bad ipadx value "abc": must be positive screen distance}}
test pack-12.20 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipadx -1} msg] $msg
} {1 {bad ipadx value "-1": must be positive screen distance}}
test pack-12.20.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipadx {5 5}} msg] $msg
} {1 {bad ipadx value "5 5": must be positive screen distance}}
test pack-12.21 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipady abc} msg] $msg
} {1 {bad ipady value "abc": must be positive screen distance}}
test pack-12.22 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipady -1} msg] $msg
} {1 {bad ipady value "-1": must be positive screen distance}}
test pack-12.22.1 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -ipady {5 5}} msg] $msg
} {1 {bad ipady value "5 5": must be positive screen distance}}
test pack-12.23 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -side bac} msg] $msg
} {1 {bad side "bac": must be top, bottom, left, or right}}
test pack-12.24 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -lousy bac} msg] $msg
} {1 {bad option "-lousy": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}}
test pack-12.25 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -padx} msg] $msg
} {1 {extra option "-padx" (option with no value?)}}
test pack-12.26 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a ? 22} msg] $msg
} {1 {bad option "?": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}}
test pack-12.27 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -in .} msg] $msg
} {1 {can't pack .pack.a inside .}}
test pack-12.28 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    frame .pack.a.a
    list [catch {pack .pack.a.a -in .pack.b} msg] $msg
} {1 {can't pack .pack.a.a inside .pack.b}}
test pack-12.29 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack .pack.a -in .pack.a} msg] $msg
} {1 {can't pack .pack.a inside itself}}
test pack-12.30 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a .pack.b .pack.c .pack.d
    pack forget .pack.a .pack.d
    pack slaves .pack
} {.pack.b .pack.c}
test pack-12.31 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    .pack configure -width 300 -height 200
    pack propagate .pack 0
    pack .pack.a
    update
    set result [list [winfo reqwidth .pack] [winfo reqheight .pack]]
    pack propagate .pack 1
    update
    lappend result [winfo reqwidth .pack] [winfo reqheight .pack]
    set result
} {300 200 20 40}
test pack-12.32 {command options and errors} {
    set result [pack propagate .pack.d]
    pack propagate .pack.d 0
    lappend result [pack propagate .pack.d]
    pack propagate .pack.d 1
    lappend result [pack propagate .pack.d]
    set result
} {1 0 1}
test pack-12.33 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack propagate .dum} msg] $msg
} {1 {bad window path name ".dum"}}
test pack-12.34 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack propagate .pack foo} msg] $msg
} {1 {expected boolean value but got "foo"}}
test pack-12.35 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack propagate .pack foo bar} msg] $msg
} {1 {wrong # args: should be "pack propagate window ?boolean?"}}
test pack-12.36 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack slaves} msg] $msg
} {1 {wrong # args: should be "pack option arg ?arg ...?"}}


test pack-12.37 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    list [catch {pack slaves a b} msg] $msg
} {1 {wrong # args: should be "pack slaves window"}}
test pack-12.38 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack slaves .x} msg] $msg
} {1 {bad window path name ".x"}}
test pack-12.39 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack slaves .pack.a} msg] $msg
} {0 {}}
test pack-12.40 {command options and errors} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    list [catch {pack lousy .pack} msg] $msg
} {1 {bad option "lousy": must be configure, forget, info, propagate, or slaves}}




pack .pack.right -side right
pack .pack.bottom -side bottom
test pack-13.1 {window deletion} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.d .pack.b .pack.c -side top
    update
    destroy .pack.d
    update
    set result [list [pack slaves .pack] [winfo geometry .pack.a] \
	    [winfo geometry .pack.b] [winfo geometry .pack.c]]
} {{.pack.right .pack.bottom .pack.a .pack.b .pack.c} 20x40+30+0 50x30+15+40 80x80+0+70}

test pack-14.1 {respond to changes in expansion} {
    pack forget .pack.a .pack.b .pack.c .pack.d



    wm geom .pack {}
    pack .pack.a
    update
    set result [winfo geom .pack.a]
    wm geom .pack 400x300
    update
    lappend result [winfo geom .pack.a]
    pack .pack.a -expand true -fill both
    update
    lappend result [winfo geom .pack.a]


} {20x40+0+0 20x40+90+0 200x150+0+0}
wm geom .pack {}

test pack-15.1 {managing geometry with -in option} {
    pack forget .pack.a .pack.b .pack.c .pack.d


    pack .pack.a -side top
    frame .pack.f
    lower .pack.f
    pack .pack.f -side top
    frame .pack.f.f2
    lower .pack.f.f2
    pack .pack.f.f2 -side top
    pack .pack.b -in .pack.f.f2
    update
    set result [winfo geom .pack.b]
    pack unpack .pack.a
    update
    lappend result [winfo geom .pack.b]
} {50x30+0+40 50x30+0+0}
catch {destroy .pack.f}

test pack-15.2 {managing geometry with -in option} {
    pack forget .pack.a .pack.b .pack.c .pack.d


    frame .pack.f
    lower .pack.f
    pack .pack.a -in .pack.f -side top
    update
    set result [winfo ismapped .pack.a]
    place .pack.f -x 30 -y 45
    update
    lappend result [winfo ismapped .pack.a] [winfo geometry .pack.a]
    place forget .pack.f
    update
    lappend result [winfo ismapped .pack.a]
} {0 1 20x40+30+45 0}
catch {destroy .pack.f}

test pack-15.3 {managing geometry with -in option} {
    pack forget .pack.a .pack.b .pack.c .pack.d


    pack .pack.a -side top
    frame .pack.f
    lower .pack.f
    pack .pack.f -side top
    frame .pack.f.f2
    lower .pack.f.f2
    pack .pack.f.f2 -side top
    pack .pack.b -in .pack.f.f2
    update
    set result [winfo ismapped .pack.b]
    pack unpack .pack.f
    update
    lappend result [winfo ismapped .pack.b]
} {1 0}
catch {destroy .pack.f}

test pack-15.4 {managing geometry with -in option} {
    pack forget .pack.a .pack.b .pack.c .pack.d


    foreach i {1 2} {
	frame .pack.f$i -width 100 -height 40 -bd 2 -relief raised
	lower .pack.f$i
	pack propagate .pack.f$i 0
	pack .pack.f$i -side top
    }
    pack .pack.b -in .pack.f1 -side right
    update
    set result {}
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack .pack.b -in .pack.f2 -side bottom
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    .pack.f1 configure -width 50 -height 20
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack forget .pack.b
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]


} {50x30+48+5 1 50x30+25+48 1 50x30+25+28 1 50x30+25+28 0}
catch {destroy .pack.f1 .pack.f2}
test pack-15.5 {managing geometry with -in option} {
    pack forget .pack.a .pack.b .pack.c .pack.d


    foreach i {1 2} {
	frame .pack.f$i -width 100 -height 20 -bd 2 -relief raised
	lower .pack.f$i
	pack propagate .pack.f$i 0
	pack .pack.f$i -side top
    }
    pack .pack.b -in .pack.f2 -side top
    update
    set result {}
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
    pack .pack.a -before .pack.b -side top
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
} {50x16+25+22 1 50x16+25+22 0}
catch {destroy .pack.f1 .pack.f2}


test pack-16.1 {geometry manager name} {
    pack forget .pack.a .pack.b .pack.c .pack.d
    set result {}

    lappend result [winfo manager .pack.a]
    pack .pack.a
    lappend result [winfo manager .pack.a]
    pack forget .pack.a
    lappend result [winfo manager .pack.a]
} {{} pack {}}

test pack-17.1 {PackLostSlaveProc procedure} {
    pack forget .pack.a .pack.b .pack.c .pack.d

    pack .pack.a
    update
    place .pack.a -x 40 -y 10
    update
    list [winfo manager .pack.a] [winfo geometry .pack.a] \










	[catch {pack info .pack.a} msg] $msg
} {place 20x40+40+10 1 {window ".pack.a" isn't packed}}




test pack-18.1 {unmap slaves when master unmapped} {tempNotPc failsOnUbuntu failsOnQuarz} {











    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
    # unmapped, the changes don't take effect until the window is remapped.
    # Who knows why?

    eval destroy [winfo child .pack]
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    update
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update
    lappend result [winfo width .pack.a ] [winfo height .pack.a] \
	[winfo ismapped .pack.a]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.a]
} {1 0 200 75 0 1}
test pack-18.2 {unmap slaves when master unmapped} {failsOnUbuntu failsOnQuarz} {




    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
    eval destroy [winfo child .pack]
    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
    pack .pack.a
    pack .pack.b -in .pack.a
    update
    set result [winfo ismapped .pack.b]
    wm iconify .pack
    update
    lappend result [winfo ismapped .pack.b]
    .pack.b configure -width 100 -height 30
    update
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
	[winfo ismapped .pack.b]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.b]
} {1 0 100 30 0 1}

test pack-19.1 {test respect for internalborder} {
    catch {eval pack forget [pack slaves .pack]}
    destroy .pack.l .pack.lf

    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    pack .pack.lf.f -fill both -expand 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]

    destroy .pack.l .pack.lf
    set res
} {196x188+2+10 177x186+5+7}
test pack-19.2 {test support for minreqsize} {
    catch {eval pack forget [pack slaves .pack]}
    destroy .pack.l .pack.lf

    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25
    pack .pack.lf.f
    update
    set res [list [winfo geometry .pack.lf]]
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]

    destroy .pack.l .pack.lf
    set res
} {162x127+0+0 172x112+0+0}
























































destroy .pack









foreach i {pack1 pack2 pack3 pack4} {










    rename $i {}










}

# cleanup
cleanupTests
return




Deleted tests/packgrid.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# This file is a Tcl script to test out interaction between Tk's "pack" and
# "grid" commands.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 2008 Peter Spjuth
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::*

test packgrid-1.1 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict
    grid .g
    pack .p
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-1.2 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict
    pack .p
    grid .g
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-1.3 {pack and grid in same container window} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    grid .g
    pack .p
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.4 {pack and grid in same container window} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    pack .p
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.5 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    grid .g
    pack .p
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.6 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    pack .p
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.7 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict should stop widget from being handled
    grid .g
    catch { pack .p }
    pack content .
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.8 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict should stop widget from being handled
    pack .p
    catch { grid .g }
    grid content .
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-2.1 {pack and grid in same container window, change propagation} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
    pack .p
    grid .g
    update
} -body {
    grid propagate . true
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-2.2 {pack and grid in same container window, change propagation} -setup {
    grid propagate . true
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
    pack .p
    grid .g
    update
} -body {
    pack propagate . true
} -returnCodes error -cleanup {
    destroy .p
    update
    destroy .g
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-2.3 {pack and grid in same container window, change propagation} -setup {
    grid propagate . false
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
    pack .p
    grid .g
    update
} -body {
    grid propagate . true
    update
    pack propagate . true
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-2.4 {pack and grid in same container window, change propagation} -setup {
    grid propagate . false
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
    pack .p
    grid .g
    update
} -body {
    pack propagate . true
    grid propagate . true
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-3.1 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok to steal if the other one is emptied
    grid .g
    pack .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-3.2 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok to steal if the other one is emptied
    pack .g
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-3.3 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Not ok to steal if the other one is not emptied
    grid .g
    grid .p
    pack .g
}  -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-3.4 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Not ok to steal if the other one is not emptied
    pack .g
    pack .p
    grid .g
}  -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-4.1 {content stolen after container destruction - bug [aa7679685e]} -setup {
    frame .f
    button .b -text hello
} -body {
    pack .f
    grid .b -in .f
    destroy .f
    set res [winfo manager .b]
    # shall not crash
    pack .b
    set res
} -cleanup {
    destroy .b
} -result {}

test packgrid-4.2 {content stolen after container destruction - bug [aa7679685e]} -setup {
    frame .f
    button .b -text hello
} -body {
    pack .f
    pack .b -in .f
    destroy .f
    set res [winfo manager .b]
    # shall not crash
    grid .b
    set res
} -cleanup {
    destroy .b
} -result {}

cleanupTests
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































Changes to tests/panedwindow.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

14



15

16



17













































18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377

378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425




426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459







460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490

491

492
493
494
495
496
497
498

499
500
501
502

503

504
505
506
507
508
509
510

511
512
513
514
515

516

517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597



598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722









723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839

840

841
842
843
844
845
846
847
848
849
850

851

852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937

938

939
940
941
942
943
944
945
946
947
948
949
950
951

952

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528

1529

1530

1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544

1545

1546

1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564

1565

1566

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584

1585

1586

1587
1588




1589

1590










1591
1592
1593
















1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664

1665

1666

1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681

1682

1683

1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703

1704

1705

1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719

1720

1721

1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735

1736

1737

1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751

1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766

1767

1768

1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782

1783

1784

1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799

1800

1801

1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816

1817

1818

1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841

1842

1843

1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858

1859

1860

1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879

1880

1881

1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

1901

1902

1903
1904





1905

1906










1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917

1918

1919

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

1969

1970

1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986

1987

1988

1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004

2005

2006

2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027

2028

2029

2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044

2045

2046

2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061

2062

2063

2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077

2078

2079

2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094

2095

2096

2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111

2112

2113

2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129

2130

2131

2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147

2148

2149

2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246





2247
2248
2249
2250
2251
2252

2253
2254
2255
2256


2257

2258
2259
2260
2261
2262
2263
2264

2265
2266
2267
2268
2269


2270

2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283



2284

2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300

2301


2302
2303

2304
2305

2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320


2321

2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335


2336

2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319

4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344

4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357

4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409

4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422

4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479

4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492

4493
4494
4495
4496
4497
4498
4499
4500
4501
4502

4503
4504
4505

4506
4507
4508
4509
4510
4511
4512
4513
4514
4515

4516
4517
4518

4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534

4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574

4575
4576
4577
4578
4579
4580
4581
4582

4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593

4594
4595
4596
4597
4598
4599
4600
4601
4602
4603

4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665

4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676

4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886

4887
4888
4889
4890
4891
4892
4893
4894
4895

4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907

4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929

4930
4931
4932

4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954

4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989

4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004

5005
5006
5007

5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023

5024
5025
5026
5027

5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045

5046
5047
5048

5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066

5067
5068
5069

5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087

5088
5089
5090

5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108

5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181

5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231

5232
5233
5234
5235
5236
5237
5238
5239
5240
5241

5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303

5304
5305
5306
5307
5308
5309
5310
5311

5312
5313
5314

5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330

5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380

5381
5382
5383
5384
5385
5386
5387
5388
5389
5390

5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404

5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426

5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485

5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508

5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523

5524
5525
5526

5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541

5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


deleteWindows



# Panedwindow for tests 1.*

panedwindow .p



# Buttons for tests 1.33 - 1.52













































.p add [button .b]
.p add [button .c]
test panedwindow-1.1 {configuration options: -background (good)} -body {
    .p configure -background #ff0000
    list [lindex [.p configure -background] 4] [.p cget -background]
} -cleanup {
    .p configure -background [lindex [.p configure -background] 3]
} -result {{#ff0000} #ff0000}
test panedwindow-1.2 {configuration options: -background (bad)} -body {
    .p configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test panedwindow-1.3 {configuration options: -bd (good)} -body {
    .p configure -bd 4
    list [lindex [.p configure -bd] 4] [.p cget -bd]
} -cleanup {
    .p configure -bd [lindex [.p configure -bd] 3]
} -result {4 4}
test panedwindow-1.4 {configuration options: -bd (bad)} -body {
    .p configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.5 {configuration options: -bg (good)} -body {
    .p configure -bg #ff0000
    list [lindex [.p configure -bg] 4] [.p cget -bg]
} -cleanup {
    .p configure -bg [lindex [.p configure -bg] 3]
} -result {{#ff0000} #ff0000}
test panedwindow-1.6 {configuration options: -bg (bad)} -body {
    .p configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test panedwindow-1.7 {configuration options: -borderwidth (good)} -body {
    .p configure -borderwidth 1.3
    list [lindex [.p configure -borderwidth] 4] [.p cget -borderwidth]
} -cleanup {
    .p configure -borderwidth [lindex [.p configure -borderwidth] 3]
} -result {1 1}
test panedwindow-1.8 {configuration options: -borderwidth (bad)} -body {
    .p configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.9 {configuration options: -cursor (good)} -body {
    .p configure -cursor arrow
    list [lindex [.p configure -cursor] 4] [.p cget -cursor]
} -cleanup {
    .p configure -cursor [lindex [.p configure -cursor] 3]
} -result {arrow arrow}
test panedwindow-1.10 {configuration options: -cursor (bad)} -body {
    .p configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test panedwindow-1.11 {configuration options: -handlesize (good)} -body {
    .p configure -handlesize 20
    list [lindex [.p configure -handlesize] 4] [.p cget -handlesize]
} -cleanup {
    .p configure -handlesize [lindex [.p configure -handlesize] 3]
} -result {20 20}
test panedwindow-1.12 {configuration options: -handlesize (bad)} -body {
    .p configure -handlesize badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.13 {configuration options: -height (good)} -body {
    .p configure -height 20
    list [lindex [.p configure -height] 4] [.p cget -height]
} -cleanup {
    .p configure -height [lindex [.p configure -height] 3]
} -result {20 20}
test panedwindow-1.14 {configuration options: -height (bad)} -body {
    .p configure -height badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.15 {configuration options: -opaqueresize (good)} -body {
    .p configure -opaqueresize true
    list [lindex [.p configure -opaqueresize] 4] [.p cget -opaqueresize]
} -cleanup {
    .p configure -opaqueresize [lindex [.p configure -opaqueresize] 3]
} -result {1 1}

test panedwindow-1.16 {configuration options: -opaqueresize (bad)} -body {
    .p configure -opaqueresize foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.17 {configuration options: -orient (good)} -body {
    .p configure -orient horizontal
    list [lindex [.p configure -orient] 4] [.p cget -orient]
} -cleanup {
    .p configure -orient [lindex [.p configure -orient] 3]
} -result {horizontal horizontal}
test panedwindow-1.18 {configuration options: -orient (bad)} -body {
    .p configure -orient badValue
} -returnCodes error -result {bad orient "badValue": must be horizontal or vertical}
test panedwindow-1.19 {configuration options: -proxybackground (good)} -body {
    .p configure -proxybackground "#f0a0a0"
    list [lindex [.p configure -proxybackground] 4] [.p cget -proxybackground]
} -cleanup {
    .p configure -proxybackground [lindex [.p configure -proxybackground] 3]
} -result {{#f0a0a0} #f0a0a0}
test panedwindow-1.20 {configuration options: -proxybackground (bad)} -body {
    .p configure -proxybackground badValue
} -returnCodes error -result {unknown color name "badValue"}
test panedwindow-1.21 {configuration options: -proxyborderwidth (good)} -body {
    .p configure -proxyborderwidth 1.3
    list [lindex [.p configure -proxyborderwidth] 4] [.p cget -proxyborderwidth]
} -cleanup {
    .p configure -proxyborderwidth [lindex [.p configure -proxyborderwidth] 3]
} -result {1.3 1.3}
test panedwindow-1.22 {configuration options: -proxyborderwidth (bad)} -body {
    .p configure -proxyborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.23 {configuration options: -proxyrelief (good)} -body {
    .p configure -proxyrelief groove
    list [lindex [.p configure -proxyrelief] 4] [.p cget -proxyrelief]
} -cleanup {
    .p configure -proxyrelief [lindex [.p configure -proxyrelief] 3]
} -result {groove groove}
test panedwindow-1.24 {configuration options: -proxyrelief (bad)} -body {
    .p configure -proxyrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.25 {configuration options: -relief (good)} -body {
    .p configure -relief groove
    list [lindex [.p configure -relief] 4] [.p cget -relief]
} -cleanup {
    .p configure -relief [lindex [.p configure -relief] 3]
} -result {groove groove}
test panedwindow-1.26 {configuration options: -relief (bad)} -body {
    .p configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.27 {configuration options: -sashcursor (good)} -body {
    .p configure -sashcursor arrow
    list [lindex [.p configure -sashcursor] 4] [.p cget -sashcursor]
} -cleanup {
    .p configure -sashcursor [lindex [.p configure -sashcursor] 3]
} -result {arrow arrow}
test panedwindow-1.28 {configuration options: -sashcursor (bad)} -body {
    .p configure -sashcursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test panedwindow-1.29 {configuration options: -sashpad (good)} -body {
    .p configure -sashpad 1.3
    list [lindex [.p configure -sashpad] 4] [.p cget -sashpad]
} -cleanup {
    .p configure -sashpad [lindex [.p configure -sashpad] 3]
} -result {1 1}
test panedwindow-1.30 {configuration options: -sashpad (bad)} -body {
    .p configure -sashpad badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.31 {configuration options: -sashrelief (good)} -body {
    .p configure -sashrelief groove
    list [lindex [.p configure -sashrelief] 4] [.p cget -sashrelief]

} -cleanup {
    .p configure -sashrelief [lindex [.p configure -sashrelief] 3]
} -result {groove groove}
test panedwindow-1.32 {configuration options: -sashrelief (bad)} -body {
    .p configure -sashrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.33 {configuration options: -sashwidth (good)} -body {
    .p configure -sashwidth 10
    list [lindex [.p configure -sashwidth] 4] [.p cget -sashwidth]
} -cleanup {
    .p configure -sashwidth [lindex [.p configure -sashwidth] 3]
} -result {10 10}
test panedwindow-1.34 {configuration options: -sashwidth (bad)} -body {
    .p configure -sashwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.35 {configuration options: -showhandle (good)} -body {
    .p configure -showhandle true
    list [lindex [.p configure -showhandle] 4] [.p cget -showhandle]
} -cleanup {
    .p configure -showhandle [lindex [.p configure -showhandle] 3]
} -result {1 1}
test panedwindow-1.36 {configuration options: -showhandle (bad)} -body {
    .p configure -showhandle foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.37 {configuration options: -width (good)} -body {
    .p configure -width 402
    list [lindex [.p configure -width] 4] [.p cget -width]
} -cleanup {
    .p configure -width [lindex [.p configure -width] 3]
} -result {402 402}
test panedwindow-1.38 {configuration options: -width (bad)} -body {
    .p configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}

test panedwindow-1.39 {configuration options: -after (good)} -body {
    .p paneconfigure .b -after .c
    list [lindex [.p paneconfigure .b -after] 4] \
        [.p panecget .b -after]
} -cleanup {
    .p paneconfig .b -after [lindex [.p paneconfig .b -after] 3]
} -result {.c .c}
test panedwindow-1.40 {configuration options: -after (bad)} -body {
    .p paneconfigure .b -after badValue
} -returnCodes error -result {bad window path name "badValue"}
test panedwindow-1.41 {configuration options: -before (good)} -body {
    .p paneconfigure .b -before .c
    list [lindex [.p paneconfigure .b -before] 4] \
        [.p panecget .b -before]
} -cleanup {
    .p paneconfig .b -before [lindex [.p paneconfig .b -before] 3]
} -result {.c .c}
test panedwindow-1.42 {configuration options: -before (bad)} -body {
    .p paneconfigure .b -before badValue
} -returnCodes error -result {bad window path name "badValue"}
test panedwindow-1.43 {configuration options: -height (good)} -body {
    .p paneconfigure .b -height 10
    list [lindex [.p paneconfigure .b -height] 4] \
        [.p panecget .b -height]
} -cleanup {
    .p paneconfig .b -height [lindex [.p paneconfig .b -height] 3]
} -result {10 10}
test panedwindow-1.44 {configuration options: -height (bad)} -body {
    .p paneconfigure .b -height badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.45 {configuration options: -hide (good)} -body {
    .p paneconfigure .b -hide false
    list [lindex [.p paneconfigure .b -hide] 4] \
        [.p panecget .b -hide]
} -cleanup {
    .p paneconfig .b -hide [lindex [.p paneconfig .b -hide] 3]
} -result {0 0}
test panedwindow-1.46 {configuration options: -hide (bad)} -body {
    .p paneconfigure .b -hide foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.47 {configuration options: -minsize (good)} -body {
    .p paneconfigure .b -minsize 10
    list [lindex [.p paneconfigure .b -minsize] 4] \
        [.p panecget .b -minsize]
} -cleanup {
    .p paneconfig .b -minsize [lindex [.p paneconfig .b -minsize] 3]
} -result {10 10}
test panedwindow-1.48 {configuration options: -minsize (bad)} -body {
    .p paneconfigure .b -minsize badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.49 {configuration options: -padx (good)} -body {
    .p paneconfigure .b -padx 1.3
    list [lindex [.p paneconfigure .b -padx] 4] \
        [.p panecget .b -padx]
} -cleanup {
    .p paneconfig .b -padx [lindex [.p paneconfig .b -padx] 3]
} -result {1 1}
test panedwindow-1.50 {configuration options: -padx (bad)} -body {
    .p paneconfigure .b -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.51 {configuration options: -pady (good)} -body {
    .p paneconfigure .b -pady 1.3
    list [lindex [.p paneconfigure .b -pady] 4] \
        [.p panecget .b -pady]
} -cleanup {
    .p paneconfig .b -pady [lindex [.p paneconfig .b -pady] 3]
} -result {1 1}
test panedwindow-1.52 {configuration options: -pady (bad)} -body {
    .p paneconfigure .b -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.53 {configuration options: -sticky (good)} -body {
    .p paneconfigure .b -sticky nsew
    list [lindex [.p paneconfigure .b -sticky] 4] \
        [.p panecget .b -sticky]
} -cleanup {
    .p paneconfig .b -sticky [lindex [.p paneconfig .b -sticky] 3]
} -result {nesw nesw}
test panedwindow-1.54 {configuration options: -sticky (bad)} -body {
    .p paneconfigure .b -sticky abcd
} -returnCodes error -result {bad stickyness value "abcd": must be a string containing zero or more of n, e, s, and w}
test panedwindow-1.55 {configuration options: -stretch (good)} -body {
    .p paneconfigure .b -stretch alw
    list [lindex [.p paneconfigure .b -stretch] 4] \
        [.p panecget .b -stretch]
} -cleanup {
    .p paneconfig .b -stretch [lindex [.p paneconfig .b -stretch] 3]
} -result {always always}
test panedwindow-1.56 {configuration options: -stretch (bad)} -body {
    .p paneconfigure .b -stretch foo
} -returnCodes error -result {bad stretch "foo": must be always, first, last, middle, or never}
test panedwindow-1.57 {configuration options: -width (good)} -body {
    .p paneconfigure .b -width 10
    list [lindex [.p paneconfigure .b -width] 4] \
        [.p panecget .b -width]
} -cleanup {
    .p paneconfig .b -width [lindex [.p paneconfig .b -width] 3]
} -result {10 10}
test panedwindow-1.58 {configuration options: -width (bad)} -body {
    .p paneconfigure .b -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
deleteWindows


test panedwindow-2.1 {panedwindow widget command} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {bad command "foo": must be add, cget, configure, forget, identify, panecget, paneconfigure, panes, proxy, or sash}


test panedwindow-3.1 {panedwindow panes subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list [list .b .c] [list .c]]


test panedwindow-4.1 {forget subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p forget
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p forget widget ?widget ...?"}
test panedwindow-4.2 {forget subcommand, forget one from start} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c} .c]
test panedwindow-4.3 {forget subcommand, forget one from end} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .d
    update
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c .d} {.b .c}]
test panedwindow-4.4 {forget subcommand, forget multiple} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .b .c
    update
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c .d} .d]
test panedwindow-4.5 {forget subcommand, panes are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    pack .p
    update

    set result [list [winfo ismapped .b] [winfo ismapped .c]]
    .p forget .b
    update

    lappend result [winfo ismapped .b] [winfo ismapped .c]

} -cleanup {
	deleteWindows
} -result [list 1 1 0 1]
test panedwindow-4.6 {forget subcommand, changes reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [frame .g -width 20 -height 20]
    set result [list [winfo reqwidth .p]]
    .p forget .f
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result [list 44 20]


test panedwindow-5.1 {sash subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p sash option ?arg ...?"}
test panedwindow-5.2 {sash subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash foo
} -cleanup {
	deleteWindows

} -returnCodes error -result {bad option "foo": must be coord, dragto, mark, or place}


test panedwindow-6.1 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash coord
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p sash coord index"}
test panedwindow-6.2 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p sash coord 0




} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-6.3 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash coord foo
} -cleanup {
	deleteWindows

} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-6.4 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 22 0]
test panedwindow-6.5 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 50 0]
test panedwindow-6.6 {sash coord subcommand, sashes correctly placed} -setup {







	deleteWindows
} -body {

    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 22]
test panedwindow-6.7 {sash coord subcommand, sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 50]
test panedwindow-6.8 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p

    list [catch {.p sash coord -1} msg] $msg \
        [catch {.p sash coord  0} msg] $msg \
        [catch {.p sash coord  1} msg] $msg
} -cleanup {

	deleteWindows

} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.9 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f]

    list [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] $msg \
	    [catch {.p sash coord  1} msg] $msg
} -cleanup {

	deleteWindows

} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.10 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f] [frame .p.f2]

    list [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] \
	    [catch {.p sash coord  1} msg] $msg \
	    [catch {.p sash coord  2} msg] $msg
} -cleanup {

	deleteWindows

} -result [list 1 "invalid sash index" 0 1 "invalid sash index" 1 "invalid sash index"]


test panedwindow-7.1 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p sash mark index ?x y?"}
test panedwindow-7.2 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.3 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows

} -returnCodes error -result {invalid sash index}
test panedwindow-7.4 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.5 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-7.6 {sash mark subcommand, mark defaults to 0 0} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-7.7 {sash mark subcommand, set mark} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 10 10
    .p sash mark 0
} -cleanup {
	deleteWindows
} -result [list 10 10]


test panedwindow-8.1 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p sash dragto index x y"}
test panedwindow-8.2 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto foo bar baz
} -cleanup {
	deleteWindows



} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.3 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows

} -returnCodes error -result {invalid sash index}
test panedwindow-8.4 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.5 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}


test panedwindow-9.1 {sash mark/sash dragto interaction} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 20 10
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 30 0]
test panedwindow-9.2 {sash mark/sash dragto interaction} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] [button .p.c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 10 20
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 30]
test panedwindow-9.3 {sash mark/sash dragto, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash mark 0 20 10
    .p sash dragto 0 10 10
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 15 0]


test panedwindow-10.1 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p sash place index x y"}
test panedwindow-10.2 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place foo bar baz
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.3 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-10.4 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.5 {sash place subcommand, errors} -setup {

	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-10.6 {sash place subcommand, moves sash} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 10 0]
test panedwindow-10.7 {sash place subcommand, moves sash} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 0 10
    .p sash coord 0
} -cleanup {









	deleteWindows
} -result [list 0 10]
test panedwindow-10.8 {sash place subcommand, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 15 0]
test panedwindow-10.9 {sash place subcommand, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg pink]
    .p sash place 0 2 0
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}


test panedwindow-11.1 {moving sash changes size of pane to left} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar] -sticky nsew
    .p sash place 0 30 0
    pack .p
    update
    winfo width .f
} -result 30
test panedwindow-11.2 {moving sash changes size of pane to right} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    pack .p
    update
    set result [winfo width .f2]
    .p sash place 0 30 0
    update
    lappend result [winfo width .f2]
} -cleanup {
	deleteWindows
} -result {20 10}
test panedwindow-11.3 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    .p sash place 0 30 0
    winfo reqwidth .p
} -result 44
test panedwindow-11.4 {moving sash changes size of pane above} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [button .c -text foobar] -sticky nsew
    .p sash place 0 0 20
    pack .p
    update
    set result [winfo height .f]

    set result
} -result 20
test panedwindow-11.5 {moving sash changes size of pane below} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    pack .p
    update
    set result [winfo height .f2]
    .p sash place 0 0 15
    update
    lappend result [winfo height .f2]

    set result
} -cleanup {
	deleteWindows
} -result {10 5}
test panedwindow-11.6 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .p]
    .p sash place 0 0 20
    lappend result [winfo reqheight .p]

    set result
} -cleanup {
	deleteWindows
} -result [list 24 24]
test panedwindow-11.7 {moving sash does not alter reqsize of widget} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .f]
    .p sash place 0 0 20
    lappend result [winfo reqheight .f]
} -cleanup {
	deleteWindows
} -result [list 10 10]
test panedwindow-11.8 {moving sash restricted to minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    pack .p
    update
    winfo width .f

} -result 15

test panedwindow-11.9 {moving sash restricted to minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 30] [button .c] -minsize 10
    .p sash place 0 0 5
    pack .p
    update
    winfo height .f

} -result 10

test panedwindow-11.10 {moving sash in unmapped window restricted to reqsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20]
    set result [list [.p sash coord 0]]
    .p sash place 0 100 0
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list {20 0} {40 0}]
test panedwindow-11.11 {moving sash right pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 0 80 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result {{60 0} {64 0}}
test panedwindow-11.12 {moving sash left pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 1 0 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result {{0 0} {4 0}}
test panedwindow-11.13 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 50
    update
    .p sash place 1 100 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result {46 0}
test panedwindow-11.14 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    update
    .p sash place 1 200 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result {96 0}
test panedwindow-11.15 {moving sash into "virtual" space on last pane increases reqsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    set result [winfo reqwidth .p]
    update
    .p sash place 1 200 0
    update
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {68 100}


test panedwindow-12.1 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update

    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}

    return $result
} -cleanup {
	deleteWindows
} -result [list 2 2 28 2 54 2]
test panedwindow-12.2 {vertical panedwindow lays out widgets properly} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2 \
            -orient vertical
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update

    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}

    return $result
} -cleanup {
	deleteWindows
} -result [list 2 2 2 18 2 34]
test panedwindow-12.3 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach {win color} {.p.f blue .p.f2 green} {
	    .p add [frame $win -width 20 -height 20 -bg $color] -padx 10 -pady 5 \
            -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}

    return $result
} -cleanup {
	deleteWindows
} -result [list 80 30 10 5 50 5 60 30 0 5 30 5]
test panedwindow-12.4 {vertical panedwindow lays out widgets properly} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach win {.p.f .p.f2} {
	.p add [frame $win -width 20 -height 20] -padx 10 -pady 5 -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}

    return $result
} -cleanup {
	deleteWindows
} -result [list 40 60 10 5 10 35 40 50 10 0 10 25]
test panedwindow-12.5 {panedwindow respects reqsize of panes when possible} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 30]
test panedwindow-12.6 {panedwindow takes explicit widget width over reqwidth} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -width 20 -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.7 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.8 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -height 15
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {20 20}
test panedwindow-12.9 {panedwindow pane width overrides widget width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 10 0
    pack .p
    update
    set result [winfo width .p.f]
    .p paneconfigure .p.f -width 30
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 10 10]
test panedwindow-12.10 {panedwindow respects reqsize of panes when possible} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 30]
test panedwindow-12.11 {panedwindow takes explicit height over reqheight} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -height 20 -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.12 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.13 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -width 15
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {20 20}
test panedwindow-12.14 {panedwindow pane height overrides widget width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 0 10
    pack .p
    update
    set result [winfo height .p.f]
    .p paneconfigure .p.f -height 30
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 10 10]


test panedwindow-13.1 {PanestructureProc, widget yields managements} -setup {
	deleteWindows
} -body {
    # Check that the panedwindow correctly yields geometry management of
    # a pane when the pane is destroyed.

    # This test should not cause a core dump, and it should not cause
    # a memory leak.

    panedwindow .p
    .p add [button .b]
    destroy .p
    pack .b
    destroy .b
    set result ""
} -result {}
test panedwindow-13.2 {PanedWindowLostPaneProc, widget yields management} -setup {
	deleteWindows
} -body {
    # Check that the paned window correctly yields geometry management of
    # a pane when some other geometry manager steals the pane from us.

    # This test should not cause a core dump, and it should not cause a
    # memory leak.

    panedwindow .p
    .p add [button .b]
    pack .p
    update
    pack .b
    update
    set result [.p panes]
    destroy .p .b
    set result
} -result {}


test panedwindow-14.1 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky n
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {n}
test panedwindow-14.2 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky s
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {s}
test panedwindow-14.3 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky e
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {e}
test panedwindow-14.4 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky w
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {w}
test panedwindow-14.5 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky sn
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {ns}
test panedwindow-14.6 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky ns
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {ns}
test panedwindow-14.7 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky en
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {ne}
test panedwindow-14.8 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky ne
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {ne}
test panedwindow-14.9 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky wn
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nw}
test panedwindow-14.10 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky nw
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nw}
test panedwindow-14.11 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky esn
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nes}
test panedwindow-14.12 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky nse
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nes}
test panedwindow-14.13 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky nsw
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nsw}
test panedwindow-14.14 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky nsew
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {nesw}
test panedwindow-14.15 {panedwindow sticky settings} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    .p add [button .b]
    .p paneconfigure .b -sticky ""
    .p panecget .b -sticky
} -cleanup {
    deleteWindows
} -result {}


test panedwindow-15.1 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky {}
    place .p -width 40 -height 40
    update
    list {} [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {{} 10 10 20 20}
test panedwindow-15.2 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky n
    place .p -width 40 -height 40
    update
    list n [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows

} -result {n 10 0 20 20}
test panedwindow-15.3 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky s
    place .p -width 40 -height 40
    update
    list s [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {s 10 20 20 20}
test panedwindow-15.4 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky e
    place .p -width 40 -height 40
    update
    list e [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {e 20 10 20 20}
test panedwindow-15.5 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky w
    place .p -width 40 -height 40
    update
    list w [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {w 0 10 20 20}
test panedwindow-15.6 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky ns
    place .p -width 40 -height 40
    update
    list ns [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {ns 10 0 20 40}
test panedwindow-15.7 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky ew
    place .p -width 40 -height 40
    update
    list ew [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {ew 0 10 40 20}
test panedwindow-15.8 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky nw
    place .p -width 40 -height 40
    update
    list nw [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {nw 0 0 20 20}
test panedwindow-15.9 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky ne
    place .p -width 40 -height 40
    update
    list ne [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {

    deleteWindows
} -result {ne 20 0 20 20}
test panedwindow-15.10 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky se
    place .p -width 40 -height 40
    update
    list se [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {se 20 20 20 20}
test panedwindow-15.11 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky sw
    place .p -width 40 -height 40
    update
    list sw [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {sw 0 20 20 20}
test panedwindow-15.12 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky nse
    place .p -width 40 -height 40
    update
    list nse [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {nse 20 0 20 40}
test panedwindow-15.13 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky nsw
    place .p -width 40 -height 40
    update
    list nsw [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {nsw 0 0 20 40}
test panedwindow-15.14 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky sew
    place .p -width 40 -height 40
    update
    list sew [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {sew 0 20 40 20}
test panedwindow-15.15 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky new
    place .p -width 40 -height 40
    update
    list new [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {new 0 0 40 20}
test panedwindow-15.16 {panedwindow sticky works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -height 20 -width 20 -bg red] -sticky news
    place .p -width 40 -height 40
    update
    list news [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {news 0 0 40 40}


test panedwindow-16.1 {setting minsize when pane is too small snaps width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f -height 20 -width 20 -bg red]
    set result [winfo reqwidth .p]
    .p paneconfigure .p.f -minsize 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result [list 20 40]


test panedwindow-17.1 {MoveSash, move right} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 30 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

} -cleanup {

	deleteWindows

} -result [list 42 42 {30 0}]
test panedwindow-17.2 {MoveSash, move right (unmapped) clipped by reqwidth} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 40 0]
test panedwindow-17.3 {MoveSash, move right (mapped, width < reqwidth) clipped by width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width < reqwidth
    place .p -x 0 -y 0 -width 32
    update

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 30 0]
test panedwindow-17.4 {MoveSash, move right (mapped, width > reqwidth) clipped by width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -width 102
    update

    .p sash place 0 200 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 100 0]
test panedwindow-17.5 {MoveSash, move right respects minsize} -setup {




	deleteWindows

} -body {










    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
















    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 30 0]
test panedwindow-17.6 {MoveSash, move right respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 40 0]
test panedwindow-17.7 {MoveSash, move right pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 62 0]
test panedwindow-17.8 {MoveSash, move right pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 52 0]
test panedwindow-17.9 {MoveSash, move right respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 50 0]
test panedwindow-17.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 0 50 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]

} -cleanup {

	deleteWindows

} -result [list [list 50 0] [list 52 0]]
test panedwindow-17.11 {MoveSash, move left} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 10 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

} -cleanup {

	deleteWindows

} -result [list 42 42 {10 0}]
test panedwindow-17.12 {MoveSash, move left, can't move outside of window} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 -100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 0]
test panedwindow-17.13 {MoveSash, move left respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 10 0]
test panedwindow-17.14 {MoveSash, move left respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1

} -cleanup {

	deleteWindows

} -result [list 22 0]
test panedwindow-17.15 {MoveSash, move left pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 0]
test panedwindow-17.16 {MoveSash, move left pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 10 0]
test panedwindow-17.17 {MoveSash, move left respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1

} -cleanup {

	deleteWindows

} -result [list 42 0]
test panedwindow-17.18 {MoveSash, move left, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue green} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 1 10 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]

} -cleanup {

	deleteWindows

} -result [list [list 8 0] [list 10 0]]


test panedwindow-18.1 {MoveSash, move down} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 30

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

} -cleanup {

	deleteWindows

} -result [list 42 42 {0 30}]
test panedwindow-18.2 {MoveSash, move down (unmapped) clipped by reqheight} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the reqheight of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 40]
test panedwindow-18.3 {MoveSash, move down (mapped, height < reqheight) clipped by height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a height < reqheight
    place .p -x 0 -y 0 -height 32
    update

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the visible height of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 30]
test panedwindow-18.4 {MoveSash, move down (mapped, height > reqheight) clipped by height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -height 102
    update

    .p sash place 0 0 200

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 100]
test panedwindow-18.5 {MoveSash, move down respects minsize} -setup {





	deleteWindows

} -body {










    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 30]
test panedwindow-18.6 {MoveSash, move down respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 40]
test panedwindow-18.7 {MoveSash, move down pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 62]
test panedwindow-18.8 {MoveSash, move down pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1

} -cleanup {

	deleteWindows

} -result [list 0 52]
test panedwindow-18.9 {MoveSash, move down respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 50]
test panedwindow-18.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 0 0 50

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]

} -cleanup {

	deleteWindows

} -result [list [list 0 50] [list 0 52]]
test panedwindow-18.11 {MoveSash, move up} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 10

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

} -cleanup {

	deleteWindows

} -result [list 42 42 {0 10}]
test panedwindow-18.12 {MoveSash, move up, can't move outside of window} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 -100

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 0]
test panedwindow-18.13 {MoveSash, move up respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 10]
test panedwindow-18.14 {MoveSash, move up respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1

} -cleanup {

	deleteWindows

} -result [list 0 22]
test panedwindow-18.15 {MoveSash, move up pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 0]
test panedwindow-18.16 {MoveSash, move up pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0

} -cleanup {

	deleteWindows

} -result [list 0 10]
test panedwindow-18.17 {MoveSash, move up respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1

} -cleanup {

	deleteWindows

} -result [list 0 42]
test panedwindow-18.18 {MoveSash, move up, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue green} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 1 0 10

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]

} -cleanup {

	deleteWindows

} -result [list [list 0 8] [list 0 10]]


# The following tests check that the panedwindow is correctly computing its
# geometry based on the various configuration options that can affect the
# geometry.

test panedwindow-19.1 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.2 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.3 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue] -pady 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 60] [list 60 80]]

test panedwindow-19.4 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.5 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.6 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue] -padx 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 60] [list 80 60]]

test panedwindow-19.7 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {





    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""

    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}




test panedwindow-19.8 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""

    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {60 20}




test panedwindow-19.9 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{20 0} {40 0}}





test panedwindow-19.10 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }

    return $result


} -cleanup {
    deleteWindows

} -result {{11 3 20 20} {53 3 20 20} {95 3 20 20}}


test panedwindow-19.11 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}




test panedwindow-19.12 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 60}




test panedwindow-19.13 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 20} {0 40}}

test panedwindow-19.14 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 53 20 20} {3 95 20 20}}
test panedwindow-19.15 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {22 20}

test panedwindow-19.16 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {72 20}

test panedwindow-19.17 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{23 0} {49 0}}

test panedwindow-19.18 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {59 3 20 20} {107 3 20 20}}

test panedwindow-19.19 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 22}

test panedwindow-19.20 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 72}

test panedwindow-19.21 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 23} {0 49}}

test panedwindow-19.22 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 59 20 20} {3 107 20 20}}
test panedwindow-19.23 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.24 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {66 20}

test panedwindow-19.25 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{20 0} {43 0}}

test panedwindow-19.26 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {56 3 20 20} {101 3 20 20}}

test panedwindow-19.27 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.28 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 66}

test panedwindow-19.29 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 20} {0 43}}

test panedwindow-19.30 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 56 20 20} {3 101 20 20}}
test panedwindow-19.31 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {22 20}

test panedwindow-19.32 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {72 20}

test panedwindow-19.33 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{21 0} {47 0}}

test panedwindow-19.34 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {59 3 20 20} {107 3 20 20}}

test panedwindow-19.35 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 22}

test panedwindow-19.36 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 72}

test panedwindow-19.37 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 21} {0 47}}

test panedwindow-19.38 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 59 20 20} {3 107 20 20}}
test panedwindow-19.39 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.40 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {80 20}

test panedwindow-19.41 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 0} {55 0}}

test panedwindow-19.42 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {63 3 20 20} {115 3 20 20}}

test panedwindow-19.43 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.44 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 80}

test panedwindow-19.45 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 25} {0 55}}

test panedwindow-19.46 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 63 20 20} {3 115 20 20}}
test panedwindow-19.47 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {22 20}

test panedwindow-19.48 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {92 20}

test panedwindow-19.49 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{28 0} {64 0}}

test panedwindow-19.50 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {69 3 20 20} {127 3 20 20}}

test panedwindow-19.51 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 22}

test panedwindow-19.52 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 92}

test panedwindow-19.53 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 28} {0 64}}

test panedwindow-19.54 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 69 20 20} {3 127 20 20}}
test panedwindow-19.55 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.56 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {86 20}

test panedwindow-19.57 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 0} {58 0}}

test panedwindow-19.58 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {66 3 20 20} {121 3 20 20}}

test panedwindow-19.59 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}

test panedwindow-19.60 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 86}

test panedwindow-19.61 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 25} {0 58}}

test panedwindow-19.62 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 66 20 20} {3 121 20 20}}
test panedwindow-19.63 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {22 20}

test panedwindow-19.64 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {92 20}

test panedwindow-19.65 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{26 0} {62 0}}

test panedwindow-19.66 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {69 3 20 20} {127 3 20 20}}

test panedwindow-19.67 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 22}

test panedwindow-19.68 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 92}

test panedwindow-19.69 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 26} {0 62}}

test panedwindow-19.70 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 69 20 20} {3 127 20 20}}
test panedwindow-19.71 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.72 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {64 24}

test panedwindow-19.73 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{22 2} {42 2}}

test panedwindow-19.74 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {55 5 20 20} {97 5 20 20}}

test panedwindow-19.75 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.76 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 64}

test panedwindow-19.77 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 22} {2 42}}

test panedwindow-19.78 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 55 20 20} {5 97 20 20}}
test panedwindow-19.79 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {26 24}

test panedwindow-19.80 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {76 24}

test panedwindow-19.81 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 2} {51 2}}

test panedwindow-19.82 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {61 5 20 20} {109 5 20 20}}

test panedwindow-19.83 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 26}

test panedwindow-19.84 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 76}

test panedwindow-19.85 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 25} {2 51}}

test panedwindow-19.86 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 61 20 20} {5 109 20 20}}
test panedwindow-19.87 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.88 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {70 24}

test panedwindow-19.89 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{22 2} {45 2}}

test panedwindow-19.90 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {58 5 20 20} {103 5 20 20}}

test panedwindow-19.91 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.92 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 70}

test panedwindow-19.93 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 22} {2 45}}

test panedwindow-19.94 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 58 20 20} {5 103 20 20}}
test panedwindow-19.95 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {26 24}

test panedwindow-19.96 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {76 24}

test panedwindow-19.97 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{23 2} {49 2}}

test panedwindow-19.98 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {61 5 20 20} {109 5 20 20}}

test panedwindow-19.99 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 26}

test panedwindow-19.100 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 76}

test panedwindow-19.101 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 23} {2 49}}

test panedwindow-19.102 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 61 20 20} {5 109 20 20}}
test panedwindow-19.103 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.104 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {84 24}

test panedwindow-19.105 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{27 2} {57 2}}

test panedwindow-19.106 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {65 5 20 20} {117 5 20 20}}

test panedwindow-19.107 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.108 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 84}

test panedwindow-19.109 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 27} {2 57}}

test panedwindow-19.110 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 65 20 20} {5 117 20 20}}
test panedwindow-19.111 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {26 24}

test panedwindow-19.112 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {96 24}

test panedwindow-19.113 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{30 2} {66 2}}

test panedwindow-19.114 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {71 5 20 20} {129 5 20 20}}

test panedwindow-19.115 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 26}

test panedwindow-19.116 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 96}

test panedwindow-19.117 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 30} {2 66}}

test panedwindow-19.118 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 71 20 20} {5 129 20 20}}
test panedwindow-19.119 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.120 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {90 24}

test panedwindow-19.121 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{27 2} {60 2}}

test panedwindow-19.122 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {68 5 20 20} {123 5 20 20}}

test panedwindow-19.123 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 24}

test panedwindow-19.124 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 90}

test panedwindow-19.125 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 27} {2 60}}

test panedwindow-19.126 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 68 20 20} {5 123 20 20}}
test panedwindow-19.127 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {26 24}

test panedwindow-19.128 {ComputeGeometry, three panes, reqsize set properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {96 24}

test panedwindow-19.129 {ComputeGeometry, sash coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{28 2} {64 2}}

test panedwindow-19.130 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {71 5 20 20} {129 5 20 20}}

test panedwindow-19.131 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 26}

test panedwindow-19.132 {ComputeGeometry, three panes, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {24 96}

test panedwindow-19.133 {ComputeGeometry, sash coords, vertical} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 28} {2 64}}

test panedwindow-19.134 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 71 20 20} {5 129 20 20}}


test panedwindow-20.1 {destroyed widgets are removed from panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    .p panes
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-20.2 {destroyed pane causes geometry recomputation} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    destroy .f
    winfo reqwidth .p
} -cleanup {
    deleteWindows
} -result 20


test panedwindow-21.1 {ArrangePanes, extra space is given to the last pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 100 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 78

test panedwindow-21.2 {ArrangePanes, extra space is given to the last pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 100 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 78

test panedwindow-21.3 {ArrangePanes, explicit height/width are preferred} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky ""
    .p paneconfigure .f1 -width 10 -height 15
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {10 15}
test panedwindow-21.4 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 10 0
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {10 20}
test panedwindow-21.5 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 0 10
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {20 10}
test panedwindow-21.6 {ArrangePanes, height of pane taken from total height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo y .p.f1
} -cleanup {
    deleteWindows
} -result 10

test panedwindow-21.7 {ArrangePanes, width of pane taken from total width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 40 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo x .p.f1
} -cleanup {
    deleteWindows
} -result 10

test panedwindow-21.8 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.9 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.10 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.11 {ArrangePanes, last pane shrinks} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 40 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 18

test panedwindow-21.12 {ArrangePanes, last pane shrinks} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 40 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 18

test panedwindow-21.13 {ArrangePanes, panedwindow resizes} -setup {
	deleteWindows
} -body {
	panedwindow .p -width 200 -borderwidth 0
	frame .f1 -height 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]

} -cleanup {
    deleteWindows
} -result {200 1 200 50}

test panedwindow-21.14 {ArrangePanes, panedwindow resizes} -setup {
	deleteWindows
} -body {
	panedwindow .p -height 200 -borderwidth 0 -orient vertical
	frame .f1 -width 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]

} -cleanup {
    deleteWindows
} -result {1 200 50 200}

test panedwindow-21.15 {ArrangePanes, last pane grows} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 50
	.p add [frame .f1 -width 50 -bg red] [frame .f2 -width 50 -bg white] \
		[frame .f3 -width 50 -bg blue] [frame .f4 -width 50 -bg green]
	.p sash place 1 250 0
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p configure -width 300
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]

} -cleanup {
    deleteWindows
} -result {50 150 1 1 211 50 150 1 89 300}


test panedwindow-22.1 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    # Basically just want to make sure that the PanedWindowReqProc is called
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {40 80}
test panedwindow-22.2 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    panedwindow .p -orient horizontal -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 10] [frame .f2 -width 10]
    set result [winfo reqwidth .p]
    .f1 configure -width 20
    lappend result [winfo reqwidth .p]
    destroy .p .f1 .f2
    expr {[lindex $result 1] - [lindex $result 0]}
} -cleanup {
	deleteWindows
} -result 10


test panedwindow-23.1 {ConfigurePanes, can't add panedwindow to itself} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add .p
} -cleanup {
	deleteWindows

} -returnCodes error -result {can't add .p to itself}
test panedwindow-23.2 {ConfigurePanes, bad window throws error} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add .b
} -cleanup {
	deleteWindows

} -returnCodes error -result {bad window path name ".b"}
test panedwindow-23.3 {ConfigurePanes, bad window aborts processing} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b .a}
    .p panes
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-23.4 {ConfigurePanes, bad option aborts processing} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b -sticky foobar}
    .p panes
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-23.5 {ConfigurePanes, after win isn't managed by panedwin} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -after .c
} -cleanup {
	deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.6 {ConfigurePanes, before win isn't managed by panedwin} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -before .c
} -cleanup {
	deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.7 {ConfigurePanes, -after {} is a no-op} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -after {}
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.8 {ConfigurePanes, -before {} is a no-op} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -before {}
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.9 {ConfigurePanes, new panes are added} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.10 {ConfigurePanes, options applied to all panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c] -sticky ne -height 5 -width 5 -minsize 10
    set result {}
    foreach w {.b .c} {
        set val {}
        foreach option {-sticky -height -width -minsize} {
            lappend val $option [.p panecget $w $option]
        }
        lappend result $w $val
    }

    return $result
} -cleanup {
	deleteWindows
} -result {.b {-sticky ne -height 5 -width 5 -minsize 10} .c {-sticky ne -height 5 -width 5 -minsize 10}}

test panedwindow-23.11 {ConfigurePanes, existing panes are reconfigured} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] -sticky nw -height 10
    .p add .b [button .c] -sticky se -height 2

    list [.p panes] [.p panecget .b -sticky] [.p panecget .b -height] \
	    [.p panecget .c -sticky] [.p panecget .c -height]
} -cleanup {
	deleteWindows
} -result [list {.b .c} es 2 es 2]
test panedwindow-23.12 {ConfigurePanes, widgets added to end by default} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c .d}
test panedwindow-23.13 {ConfigurePanes, -after, single addition} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .b
    .p add .c -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .c .b}
test panedwindow-23.14 {ConfigurePanes, -after, multiple additions} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b
    .p add .c .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .c .d .b}
test panedwindow-23.15 {ConfigurePanes, -after, relocates existing widget} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .d .b .c}
test panedwindow-23.16 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .b .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .d .c}
test panedwindow-23.17 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .b
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .d .a .c}
test panedwindow-23.18 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.19 {ConfigurePanes, -after, after last window} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -after .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .c .d}
test panedwindow-23.20 {ConfigurePanes, -before, before first window} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -before .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.21 {ConfigurePanes, -before, relocate existing windows} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d .b -before .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .b .a .c}
test panedwindow-23.22 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .c}
test panedwindow-23.23 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p add .a .b .a -after .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.c .a .b}
test panedwindow-23.24 {ConfigurePanes, panedwindow cannot manage toplevels} -setup {
	deleteWindows
} -body {
    panedwindow .p
    toplevel .t
    .p add .t
} -cleanup {
	deleteWindows
} -returnCodes error -result {can't add toplevel .t to .p}
test panedwindow-23.25 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    frame .f
    button .f.b
   .p add .f.b
} -cleanup {
	deleteWindows
} -returnCodes error -result {can't add .f.b to .p}
test panedwindow-23.26 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    frame .f
    panedwindow .f.p
    button .b
    .f.p add .b
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-23.27 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .p.b
    .p add .p.b
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-23.28 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    frame .f
    frame .f.f
    frame .f.f.f
    panedwindow .f.f.f.p
    button .b
    .f.f.f.p add .b
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-23.29 {ConfigurePanes, -hide works} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false
	frame .f1 -width 40 -height 100 -bg red
	frame .f2 -width 40 -height 100 -bg white
	frame .f3 -width 40 -height 100 -bg blue
	frame .f4 -width 40 -height 100 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]

} -cleanup {
    deleteWindows
} -result {1 1 1 1 40 40 40 40 171 1 0 1 1 40 40 40 40 128}

test panedwindow-23.30 {ConfigurePanes, -hide works} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 130 -height 100
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]

} -cleanup {
    deleteWindows
} -result {1 1 1 0 39 40 40 1 130 1 0 1 1 40 40 40 42 130}
test panedwindow-23.30a {ConfigurePanes, hidden panes are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p1 -sashrelief raised
    panedwindow .p2 -sashrelief raised
    label .l1 -text Label1
    label .l2 -text Label2
    label .l3 -text Label3
    .p2 add .l2 -sticky nsew
    .p2 add .l3 -sticky nsew
    .p1 add .p2 -sticky nsew
    .p1 add .l1 -sticky nsew
    pack .p1 -side top -expand 1 -fill both
	update
	set result [list]
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p2 paneconfigure .l1 -hide 1
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 1
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 0
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
} -cleanup {
    deleteWindows
} -result {{1 1 1 1 1} {1 1 0 1 1} {1 0 0 0 0} {1 1 0 1 1}}

test panedwindow-23.31 {ConfigurePanes, -hide works, last pane stretches} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 200 -height 200 -borderwidth 0
	frame .f1 -width 50 -bg red
	frame .f2 -width 50 -bg green
	frame .f3 -width 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
	.p paneconfigure .f2 -hide 1
	update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]

} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}

test panedwindow-23.32 {ConfigurePanes, -hide works, last pane stretches} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 200 -height 200 \
		-borderwidth 0 -orient vertical
	frame .f1 -height 50 -bg red
	frame .f2 -height 50 -bg green
	frame .f3 -height 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]

} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}


test panedwindow-23.33 {ConfigurePanes, -stretch first} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch first
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]

} -cleanup {
    deleteWindows
} -result {51 40 40 40 94 40 40 40}

test panedwindow-23.34 {ConfigurePanes, -stretch middle} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch middle
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]

} -cleanup {
    deleteWindows
} -result {40 45 46 40 40 45 94 40}

test panedwindow-23.35 {ConfigurePanes, -stretch always} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch always
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]

} -cleanup {
    deleteWindows
} -result {42 43 43 43 58 43 58 58}

test panedwindow-23.36 {ConfigurePanes, -stretch never} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch never
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]

} -cleanup {
    deleteWindows
} -result {40 40 40 40 40 40 40 40}


test panedwindow-24.1 {Unlink, remove a paned with -before/-after refs} -setup {
	deleteWindows
} -body {
    # Bug 928413
    set result {}
    panedwindow .pw
    label .pw.l1 -text Label1
    label .pw.l2 -text Label2
    label .pw.l3 -text Label3
    .pw add .pw.l1
    .pw add .pw.l3
    .pw add .pw.l2 -before .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    destroy .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    .pw paneconfigure .pw.l2 -before .pw.l1
    lappend result [.pw panecget .pw.l2 -before]
} -cleanup {
	deleteWindows
} -result {.pw.l3 {} .pw.l1}


test panedwindow-25.1 {DestroyPanedWindow} -setup {
	deleteWindows
} -body {
    # This test should not result in any memory leaks.
    panedwindow .p
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .q .r .s .t} {
	    .p add [button $w]
    }
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t} {
	    destroy $w
    }
    set result {}
} -result {}
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to panes} -setup {
    deleteWindows
} -body {
    panedwindow .pw
    .pw add [button .pw.b]
    pack .pw
    update
    set result [winfo ismapped .pw.b]
    pack forget .pw
    update
    lappend result [winfo ismapped .pw.b]
    lappend result [winfo ismapped .pw]
    pack .pw
    update
    lappend result [winfo ismapped .pw]
    lappend result [winfo ismapped .pw.b]
    destroy .pw .pw.b
    set result
} -cleanup {
	deleteWindows
} -result {1 0 0 1 1}


test panedwindow-26.1 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.2 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.3 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.4 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 24 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.5 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.6 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 -1
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.7 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 100
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.8 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 4
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.9 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 5
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.10 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 5
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.11 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.12 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    .p identify 48 0
} -cleanup {
	deleteWindows
} -result {1 sash}
test panedwindow-26.13 {identify subcommand errors} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4
    .p identify
} -cleanup {
	deleteWindows

} -returnCodes error -result {wrong # args: should be ".p identify x y"}
test panedwindow-26.14 {identify subcommand errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p identify foo bar
} -cleanup {
	deleteWindows

} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-26.15 {identify subcommand errors} -setup {
	deleteWindows

} -body {
    panedwindow .p
    .p identify 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-26.16 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.17 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.18 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 22
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.19 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 24
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.20 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 26
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.21 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify -1 26
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.22 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 100 26
} -cleanup {
	deleteWindows
} -result {}

test panedwindow-26.23 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 4 22
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.24 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {

    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 22
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.25 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 20
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.26 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {

    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.27 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    .p identify 0 48
} -cleanup {
	deleteWindows
} -result {1 sash}


test panedwindow-27.1 {destroy the window cleanly on error [Bug #616589]} -setup {
	deleteWindows
} -body {
    panedwindow .p -bogusopt bogus
} -cleanup {
	deleteWindows
} -returnCodes error -result {unknown option "-bogusopt"}
test panedwindow-27.2 {destroy the window cleanly on rename [Bug #616589]} -setup {
	deleteWindows
} -body {
    destroy .p
    panedwindow .p
    rename .p {}
    winfo exists .p
} -cleanup {
	deleteWindows
} -result 0


test panedwindow-28.1 {resizing width} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 5
    frame .f1 -width 100 -height 50 -bg blue
    frame .f2 -width 100 -height 50 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news
    pack .p -side top -fill both -expand 1
    wm geometry . ""
    update
    # Note the width
    set a [winfo width .f2]
    # Increase the size by 10
    regexp {^(\d+)x(\d+)} [wm geometry .] -> w h
    wm geometry . [expr {$w + 10}]x$h
    update
    set b "$a [winfo width .f2]"

} -cleanup {
    deleteWindows
} -result {100 110}

test panedwindow-28.2 {resizing height} -setup {
	deleteWindows
} -body {
    panedwindow .p -orient vertical -bd 5
    frame .f1 -width 50 -height 100 -bg blue
    frame .f2 -width 50 -height 100 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news
    pack .p -side top -fill both -expand 1
    wm geometry . ""
    update
    # Note the height
    set a [winfo height .f2]
    # Increase the size by 10
    regexp {^(\d+)x(\d+)} [wm geometry .] -> w h
    wm geometry . ${w}x[expr {$h + 10}]
    update
    set b "$a [winfo height .f2]"

} -cleanup {
    deleteWindows
} -result {100 110}


test panedwindow-29.1 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
	deleteWindows
} -body {
	toplevel .t -visual {truecolor 24}
	pack [panedwindow .t.p]
	.t.p add [frame .t.p.f1] [frame .t.p.f2]
	update
	# If we got here, we didn't crash and that's good

} -cleanup {
    deleteWindows
} -result {}

test panedwindow-29.2 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
    deleteWindows
} -body {
	toplevel .t -visual {pseudocolor 8}
	pack [frame .t.f -visual {truecolor 24}]
	pack [panedwindow .t.f.p]
	.t.f.p add [frame .t.f.p.f1 -width 5] [frame .t.f.p.f2 -width 5]
	update
	.t.f.p proxy place 1 1
	update
	.t.f.p proxy forget
	update
	# If we got here, we didn't crash and that's good

} -cleanup {
    deleteWindows
} -result {}


# cleanup
cleanupTests
return





|
|
|





<

>
|
>
>
>
|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
|
<
<
|
<
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
<
|
<
<
<
|
<
<
>
<
<
<
|
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
|
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|

|
<
<

|
<
|
<
|
|
|
<
<






<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<








|
|
|
|
<
<








|
|
|
|
<
<





>



>

>
|
|
|
|
<
<





|
|
|

<
|
<
<

|
<
|
>
|
|
<
<

|
<
|
>
|

<
|
<
<

|
<
|
>
|
|
<
<

|
>
>
>
>
<
<
<
<
<
<

|
<
|
>
|
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
>
>
>
>
>
>
>
|
|
>





|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<

>
|
|
|
<
>
|
>
|
|
<
<



>
|

|
<
>
|
>
|
|
<
<



>
|


|
<
>
|
>
|

<
|
<
<

|
<
|
>
|
|
<
<

|
|
|
|
|
<
<

|
<
|
>
|
|
<
<


|
|
|
|
|
<
<


|
|
|
|
|
<
<


|
|
|
|
|
<
<



|
|
|
|

<
|
<
<

|
<
|
>
|
|
<
<
<
<
<
|
>
>
>
|
|
<
<

|
<
|
>
|
|
<
<


|
|
|
|
|
<
<


|
|
|
|

<
|
<
<




|
|
|
|
|
<
<





|
|
|
|
|
<
<




|
|
|
|

<
|
<
<

|
<
|
>
|
|
<
|

|
<
<
|
|
<
|

|
<
<
|
|
<
|


|
<
<
|
|
>
<
<


|
<
<
|
|
<
|




<
<
|
|
<
|




|
>
>
>
>
>
>
>
>
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<
<
|

<
|
<
|






|
|
<
|








<
<
|
|
<
|




|
|
<
|







>

|
|
<
|









>

<
<
|
|
<
<






>

<
<
|
|
<
|






|
|
|
|
<
|





|
>
|
>
|
<
|






|
>
|
>
|
<
<





|
|
|
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
<
<







|
|
|
|
|
<
<







|
|
|
|
|
|
<









|
|
|

<
|
<
<
<




>

>
|
<
<
|
|
<
<
<





>

>
|
<
<
|
|
<
<


|
|









>
|
<
<
|
|
<
<













>
|
<
<
|
|
<
<








|
|
|
|
<
<








|
|
|
|
<
<





|
|
|
|
<
<






|
|
|
|
<
<








|
|
|
|
<
<








|
|
|
|
<
<








|
|
|
|
<
<






|
|
|
|
<
<







|
|
|
|
<
|









|
|
|


|
<
<

|



>






|
|
<
<

|



>









|

|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
<
<





|
|
|

<
|
<

<


|












>
|
>
|
>
|
|
<
<


|






|
>
|
>
|
>
|
|
<
<


|










|
>
|
>
|
>
|
|
<
<


|










|
>
|
>
|
>
|
|
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
<
<
<
<
<
<
<
<
<
|
|
|

<
<
<
|
|
|
<
<


|






|
<
<
<
<
<
<
<
<
<
|
|
|

<
|
<
<
<
|
|
<
<


|
|






|
>
|
>
|
>
|
|
<
<


|
|






|
>
|
>
|
>
|
|
<
<



|












>
|
>
|
>
|
|
<
<


|






|
>
|
>
|
>
|
|
<
<


|






|
>
|
>
|
>
|
|
<
<


|





|
>
|
>
|
>
|
|
<
<


|






|
>
|
>
|
>
|
|
<
<


|






|
>
|
>
|
>
|
|
<
<


|
|






|
>
|
>
|
>
|
|
<
<


|
|






|
>
|
>
|
>
|

<
|
<
<




|












>
|
>
|
>
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|










|
>
|
>
|
>
|
|
<
<



|










|
>
|
>
|
>
|
|
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>


|
|






|
>
|
>
|
>
|
|
<
<



|






|
<
<
<
<
<
<
<
<
<
<
|
|
|

<
|
<
<
<
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|
|






|
>
|
>
|
>
|
|
<
<



|
|






|
>
|
>
|
>
|
|
<
<




|












>
|
>
|
>
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|





|
>
|
>
|
>
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|






|
>
|
>
|
>
|
|
<
<



|
|






|
>
|
>
|
>
|
|
<
<



|
|






|
>
|
>
|
>
|
<





|
<
<


|




|
|
|
<
|
<
<


|




|
|
|
<
|
<
<


|




|
|
|
<
|
<
<








|
|
|
<
|
<
<








|
|
|
<
|
<
<








|
|
|

<
|
|
>
>
>
>
>
|
|
|
|
|
|
>
|
|
<
|
>
>

>
|
<
<
|
|
|
|
>
|
|
|
<
|
>
>

>
|
<
<
|
|
|
|
|
|
|
|
<
|
>
>
>

>
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>
|
<
>
|

>
|
<
<
|
|
|
|
|
|
|
|
|
|
<
|
>
>

>
|
<
<
|
|
|
|
|
|
|
|
|
<
|
>
>

>
|
<
<
|
|
|
|
|
|
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<



|
<
|
|
>
|
<
<




|
|
<
|
|

|
<
<





|
|
<
|
>
|
<
<






|
|
<
|
>
|
<
<






|
|
|
|
|
<
<






|
|
|
|
|
<
<







|
|
|
|
|
<
<





|
|
<
|
>
|
<
<






|
|
<
|
>
|
<
<









|
|
|
|
<
<









|
|
|
|
<
<









|
|
|
|
<
<





|
|
<
|
>
|
<
<






|
|
<
|
>
|
<
|







>
|
<
|
>
|
<
|







>
|
<
|
>
|
<
|













>
|
<
|
|

|
|
<







|
|
|
|
<
<







|
<
<


|
<
<

|
<
|
>
|
|
<
<

|
<
|
>
|
|
<
<



|
|
<
|
>
|
<
<



|
|
<
|
>
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<


|
|
|
|
|
<
<




|
|
|
|
|

>
|
<
<
|
|
|
<
<



>
|
|
|
|
|
|
<
<




|
|
|
|
|
<
<







|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<








|
|
|
|
|
<
<









|
|
|
|
|
<
<


|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
<
|
>
|
<
<


|
|
<
|
>
|
<
<





|
|
<
|
>
|
<
|



















>
|
<
|
>
|
<
|



















>
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
|











|
>
|
<
|
>
|
<
|













>
|
<
|
|
>
|
<
|















>
|
<
|
>
|
<
|















>
|
<
|
>
|
<
|















>
|
<
|
>
|
<
|















>
|
<
|
|

|
<
<














|
|
|

<
|
<
<



|


|


|
|
<
<















<
<
|

<
|
<
<



|
|
<
|
>
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
<
|
>
|
<
<



|
|
<
|
>
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
<
<




|
|
|
|
|
<
<

|
<
|
>
|
|
<
<

|
<
|
>
|
|
|
>
<
|
<
<
|
|
|
<
<



|
|
<
|
>
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
|
|
|
<
<



|
|
<
|
>
|
<
<



|
|
<
|
>
|
<
<




|
|
<
<
<
|
|
>




|
|
|
|
|
<
<




|
|
<
<
<
|
|
>




|
|
|
|
|
<
<




|
|
|
|
<

|
<
<
|
<
<
|
|
<
<




|
<
<


|
<
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
|

|
|
<
<
|





>
|
<
|
>
|
|
<
<
|










>
|
<
|
|




<
<
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71



72


73


74







75
76





77










78

















79
80





81

82



83


84



85
86
87



88































89



90
91









92





93





94
95
96
































97
98






99








100









101









102

103
104
105









106
107

108


109






110


111






112






















113




114
115
116


117
118

119

120
121
122


123
124
125
126
127
128



129















130




131
132


133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172


173
174
175
176
177
178
179
180
181

182


183
184

185
186
187
188


189
190

191
192
193
194

195


196
197

198
199
200
201


202
203
204
205
206
207






208
209

210
211
212
213


214
215
216
217
218
219
220
221
222


223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249











250
251


252
253
254
255
256

257
258
259
260
261


262
263
264
265
266
267
268

269
270
271
272
273


274
275
276
277
278
279
280
281

282
283
284
285
286

287


288
289

290
291
292
293


294
295
296
297
298
299


300
301

302
303
304
305


306
307
308
309
310
311
312


313
314
315
316
317
318
319


320
321
322
323
324
325
326


327
328
329
330
331
332
333
334

335


336
337

338
339
340
341





342
343
344
345
346
347


348
349

350
351
352
353


354
355
356
357
358
359
360


361
362
363
364
365
366
367

368


369
370
371
372
373
374
375
376
377


378
379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396

397


398
399

400
401
402
403

404
405
406


407
408

409
410
411


412
413

414
415
416
417


418
419
420


421
422
423


424
425

426
427
428
429
430


431
432

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447















448
449
450


451
452

453

454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471


472
473

474
475
476
477
478
479
480

481
482
483
484
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504


505
506


507
508
509
510
511
512
513
514


515
516

517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549
550


551
552
553
554
555
556
557
558
559


560
561
562
563
564
565
566
567
568


569
570
571
572
573
574
575
576
577


578
579
580
581
582
583
584
585
586
587
588
589


590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
611
612
613
614
615

616



617
618
619
620
621
622
623
624


625
626



627
628
629
630
631
632
633
634
635


636
637


638
639
640
641
642
643
644
645
646
647
648
649
650
651
652


653
654


655
656
657
658
659
660
661
662
663
664
665
666
667
668
669


670
671


672
673
674
675
676
677
678
679
680
681
682
683


684
685
686
687
688
689
690
691
692
693
694
695


696
697
698
699
700
701
702
703
704


705
706
707
708
709
710
711
712
713
714


715
716
717
718
719
720
721
722
723
724
725
726


727
728
729
730
731
732
733
734
735
736
737
738


739
740
741
742
743
744
745
746
747
748
749
750


751
752
753
754
755
756
757
758
759
760


761
762
763
764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787


788
789
790
791
792
793
794
795
796
797
798
799
800
801


802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820





821









822



823



824


























































825
826
827
828







829






















































830
831
832













833






834
835
836










837










838










839
840


841
842
843
844
845










846








847




848


849






850















































































851

852


853
854
855
856
857
858
859
860
861

862

863

864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885


886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902


903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923


924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987









988
989
990
991



992
993
994


995
996
997
998
999
1000
1001
1002
1003
1004









1005
1006
1007
1008

1009



1010
1011


1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029


1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047


1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070


1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087


1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104


1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120


1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137


1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154


1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190

1191


1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215


1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233


1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255


1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313


1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324










1325
1326
1327
1328

1329



1330
1331


1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349


1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368


1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387


1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411


1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429


1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447


1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464


1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482


1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500


1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519


1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543


1544
1545
1546
1547
1548
1549
1550
1551
1552
1553

1554


1555
1556
1557
1558
1559
1560
1561
1562
1563
1564

1565


1566
1567
1568
1569
1570
1571
1572
1573
1574
1575

1576


1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587

1588


1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600


1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628

1629
1630
1631
1632
1633
1634


1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648


1649
1650
1651
1652
1653
1654
1655
1656

1657
1658
1659
1660
1661
1662
1663


1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685
1686


1687
1688
1689
1690
1691
1692
1693
1694
1695
1696

1697
1698
1699
1700
1701
1702


1703
1704
1705
1706
1707
1708
1709
1710
1711

1712
1713
1714
1715
1716
1717


1718
1719
1720
1721
1722
1723
1724
1725



1726












1727





















1728












1729













1730








1731











1732














































1733


1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747























1748





































































































































































































































1749





















1750












1751













1752





































































































































































1753














1754









1755






























































































































































































1756




1757








1758
































































































































































































































































































































































































































































































































































































































































































1759
























































































































































































































































































































































































































































1760


1761
1762
1763
1764

1765
1766
1767
1768


1769
1770
1771
1772
1773
1774

1775
1776
1777
1778


1779
1780
1781
1782
1783
1784
1785

1786
1787
1788


1789
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799


1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810


1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821


1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833


1834
1835
1836
1837
1838
1839
1840

1841
1842
1843


1844
1845
1846
1847
1848
1849
1850
1851

1852
1853
1854


1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867


1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880


1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893


1894
1895
1896
1897
1898
1899
1900

1901
1902
1903


1904
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1922
1923
1924

1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935
1936
1937

1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961

1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972


1973
1974
1975
1976
1977
1978
1979
1980


1981
1982
1983


1984
1985

1986
1987
1988
1989


1990
1991

1992
1993
1994
1995


1996
1997
1998
1999
2000

2001
2002
2003


2004
2005
2006
2007
2008

2009
2010
2011


2012
2013
2014
2015
2016
2017
2018
2019


2020
2021
2022
2023
2024
2025
2026
2027


2028
2029
2030
2031
2032
2033
2034
2035


2036
2037
2038
2039
2040
2041
2042
2043


2044
2045
2046
2047
2048
2049
2050


2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062


2063
2064
2065


2066
2067
2068
2069
2070
2071
2072
2073
2074
2075


2076
2077
2078
2079
2080
2081
2082
2083
2084


2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096


2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109


2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122


2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135


2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148


2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161


2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174


2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187


2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200


2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213


2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227


2228
2229
2230
2231
2232
2233
2234


2235
2236
2237
2238
2239
2240
2241
2242


2243
2244
2245
2246
2247

2248
2249
2250


2251
2252
2253
2254

2255
2256
2257


2258
2259
2260
2261
2262
2263
2264

2265
2266
2267

2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289

2290
2291
2292

2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314

2315
































2316
2317

2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332

2333
2334
2335

2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351

2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373

2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394

2395
2396
2397

2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415

2416
2417
2418

2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436

2437
2438
2439
2440


2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458

2459


2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470


2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485


2486
2487

2488


2489
2490
2491
2492
2493

2494
2495
2496


2497
2498
2499
2500
2501
2502
2503
2504


2505
2506
2507
2508
2509
2510
2511
2512


2513
2514
2515
2516
2517
2518
2519
2520


2521
2522
2523
2524
2525
2526
2527
2528


2529
2530
2531
2532
2533

2534
2535
2536


2537
2538
2539
2540
2541

2542
2543
2544


2545
2546
2547
2548
2549
2550
2551
2552
2553


2554
2555
2556
2557
2558
2559
2560
2561
2562


2563
2564
2565
2566
2567
2568
2569
2570
2571


2572
2573
2574
2575
2576
2577
2578
2579
2580


2581
2582
2583
2584
2585
2586
2587
2588
2589


2590
2591

2592
2593
2594
2595


2596
2597

2598
2599
2600
2601
2602
2603

2604


2605
2606
2607


2608
2609
2610
2611
2612

2613
2614
2615


2616
2617
2618
2619
2620
2621
2622
2623


2624
2625
2626
2627
2628
2629
2630
2631


2632
2633
2634
2635
2636
2637
2638
2639


2640
2641
2642
2643
2644
2645
2646
2647


2648
2649
2650
2651
2652

2653
2654
2655


2656
2657
2658
2659
2660

2661
2662
2663


2664
2665
2666
2667
2668
2669



2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681


2682
2683
2684
2685
2686
2687



2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699


2700
2701
2702
2703
2704
2705
2706
2707

2708
2709


2710


2711
2712


2713
2714
2715
2716
2717


2718
2719
2720

2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739

2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762

2763
2764
2765
2766
2767


2768
2769
2770
2771
2772
2773
2774
2775

2776
2777
2778
2779


2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792

2793
2794
2795
2796
2797
2798


# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


set i 1
panedwindow .p
foreach {testName testData} {
    panedwindow-1.1 {-background
	"#ff0000" "#ff0000" non-existent {unknown color name "non-existent"}}
    panedwindow-1.2 {-bd
	4 4 badValue {bad screen distance "badValue"}}
    panedwindow-1.3 {-bg
	"#ff0000" "#ff0000" non-existent {unknown color name "non-existent"}}
    panedwindow-1.4 {-borderwidth
	1.3 1 badValue {bad screen distance "badValue"}}
    panedwindow-1.5 {-cursor
	arrow arrow badValue {bad cursor spec "badValue"}}
    panedwindow-1.6 {-handlesize
	20 20 badValue {bad screen distance "badValue"}}
    panedwindow-1.7 {-height
	20 20 badValue {bad screen distance "badValue"}}
    panedwindow-1.8 {-opaqueresize
	true 1 foo {expected boolean value but got "foo"}}
    panedwindow-1.9 {-proxybackground
	"#f0a0a0" "#f0a0a0" non-existent {unknown color name "non-existent"}}
    panedwindow-1.10 {-proxyborderwidth
	1.3 1.3 badValue {bad screen distance "badValue"}}
    panedwindow-1.11 {-proxyrelief
	groove groove
	1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    panedwindow-1.12 {-orient
	horizontal horizontal
	badValue {bad orient "badValue": must be horizontal or vertical}}
    panedwindow-1.13 {-relief
	groove groove
	1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    panedwindow-1.14 {-sashcursor
	arrow arrow badValue {bad cursor spec "badValue"}}
    panedwindow-1.15 {-sashpad
	1.3 1 badValue {bad screen distance "badValue"}}
    panedwindow-1.16 {-sashrelief
	groove groove
	1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}
    panedwindow-1.17 {-sashwidth
	10 10 badValue {bad screen distance "badValue"}}
    panedwindow-1.18 {-showhandle
	true 1 foo {expected boolean value but got "foo"}}
    panedwindow-1.19 {-width
	402 402 badValue {bad screen distance "badValue"}}
} {
    lassign $testData optionName goodIn goodOut badIn badOut
    test ${testName}(good) "configuration options: $optionName" {
	.p configure $optionName $goodIn
	list [lindex [.p configure $optionName] 4] [.p cget $optionName]
    } [list $goodOut $goodOut]
    test ${testName}(bad) "configuration options: $optionName" -body {
	.p configure $optionName $badIn
    } -returnCodes error -result $badOut
    # Reset to default
    .p configure $optionName [lindex [.p configure $optionName] 3]
}
.p add [button .b]
.p add [button .c]



foreach {testName testData} {


    panedwindow-1a.1 {-after .c .c badValue {bad window path name "badValue"}}


    panedwindow-1a.2 {-before .c .c badValue {bad window path name "badValue"}}







    panedwindow-1a.3 {-height 10 10 badValue {bad screen distance "badValue"}}
    panedwindow-1a.4 {-hide false 0 foo {expected boolean value but got "foo"}}





    panedwindow-1a.5 {-minsize 10 10 badValue {bad screen distance "badValue"}}










    panedwindow-1a.6 {-padx 1.3 1 badValue {bad screen distance "badValue"}}

















    panedwindow-1a.7 {-pady 1.3 1 badValue {bad screen distance "badValue"}}
    panedwindow-1a.8 {-sticky nsew nesw abcd {bad stickyness value "abcd": must be a string containing zero or more of n, e, s, and w}}





    panedwindow-1a.9 {-stretch alw always foo {bad stretch "foo": must be always, first, last, middle, or never}}

    panedwindow-1a.10 {-width 10 10 badValue {bad screen distance "badValue"}}



} {


    lassign $testData optionName goodIn goodOut badIn badOut



    test ${testName}(good) "configuration options: $optionName" {
	.p paneconfigure .b $optionName $goodIn
	list [lindex [.p paneconfigure .b $optionName] 4] \



	    [.p panecget .b $optionName]































    } [list $goodOut $goodOut]



    test ${testName}(bad) "configuration options: $optionName" -body {
	.p paneconfigure .b $optionName $badIn









    } -returnCodes error -result $badOut





    # Reset to default





    .p paneconfig .b $optionName [lindex [.p paneconfig .b $optionName] 3]
}
destroy .p .b .c

































test panedwindow-2.1 {panedwindow widget command} {






    panedwindow .p








    set result [list [catch {.p foo} msg] $msg]









    destroy .p









    set result

} {1 {bad command "foo": must be add, cget, configure, forget, identify, panecget, paneconfigure, panes, proxy, or sash}}

test panedwindow-3.1 {panedwindow panes subcommand} {









    panedwindow .p
    .p add [button .b]

    .p add [button .c]


    set result [list [.p panes]]






    .p forget .b


    lappend result [.p panes]






    destroy .p .b .c






















    set result




} [list [list .b .c] [list .c]]

test panedwindow-4.1 {forget subcommand} {


    panedwindow .p
    set result [list [catch {.p forget} msg] $msg]

    destroy .p

    set result
} [list 1 "wrong # args: should be \".p forget widget ?widget ...?\""]
test panedwindow-4.2 {forget subcommand, forget one from start} {


    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]



    destroy .p .b .c















    set result




} [list {.b .c} .c]
test panedwindow-4.3 {forget subcommand, forget one from end} {


    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .d
    update
    lappend result [.p panes]
    destroy .p .b .c .d
    set result
} [list {.b .c .d} {.b .c}]
test panedwindow-4.4 {forget subcommand, forget multiple} {


    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .b .c
    update
    lappend result [.p panes]
    destroy .p .b .c .d
    set result
} [list {.b .c .d} .d]
test panedwindow-4.5 {forget subcommand, panes are unmapped} {


    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    pack .p
    update

    set result [list [winfo ismapped .b] [winfo ismapped .c]]
    .p forget .b
    update

    lappend result [winfo ismapped .b] [winfo ismapped .c]
    destroy .p .b .c

    set result
} [list 1 1 0 1]
test panedwindow-4.6 {forget subcommand, changes reqsize of panedwindow} {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [frame .g -width 20 -height 20]
    set result [list [winfo reqwidth .p]]
    .p forget .f
    lappend result [winfo reqwidth .p]
    destroy .p .f .g
    set result
} [list 44 20]


test panedwindow-5.1 {sash subcommand} {


    panedwindow .p
    set result [list [catch {.p sash} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p sash option ?arg ...?\""]
test panedwindow-5.2 {sash subcommand} {


    panedwindow .p
    set result [list [catch {.p sash foo} msg] $msg]

    destroy .p
    set result
} [list 1 "bad option \"foo\": must be coord, dragto, mark, or place"]


test panedwindow-6.1 {sash coord subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash coord} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p sash coord index\""]
test panedwindow-6.2 {sash coord subcommand, errors} {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    set result [list [catch {.p sash coord 0} msg] $msg]
    destroy .p
    set result
} [list 1 "invalid sash index"]
test panedwindow-6.3 {sash coord subcommand, errors} {






    panedwindow .p
    set result [list [catch {.p sash coord foo} msg] $msg]

    destroy .p
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-6.4 {sash coord subcommand sashes correctly placed} {


    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    set result [.p sash coord 0]
    destroy .p .p.f .p.f2 .p.f3
    set result
} [list 22 0]
test panedwindow-6.5 {sash coord subcommand sashes correctly placed} {


    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    set result [.p sash coord 1]
    destroy .p .p.f .p.f2 .p.f3
    set result
} [list 50 0]
test panedwindow-6.6 {sash coord subcommand, sashes correctly placed} {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    set result [.p sash coord 0]
    destroy .p .p.f .p.f2 .p.f3
    set result
} [list 0 22]
test panedwindow-6.7 {sash coord subcommand, sashes correctly placed} {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    set result [.p sash coord 1]
    destroy .p .p.f .p.f2 .p.f3

    set result











} [list 0 50]
test panedwindow-6.8 {sash coord subcommand, errors} {


    panedwindow .p
    set result [list \
	    [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] $msg \
	    [catch {.p sash coord  1} msg] $msg \

	    ]
    destroy .p
    set result
} [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.9 {sash coord subcommand, errors} {


    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f]
    set result [list \
	    [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] $msg \
	    [catch {.p sash coord  1} msg] $msg \

	    ]
    destroy .p
    set result
} [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.10 {sash coord subcommand, errors} {


    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f] [frame .p.f2]
    set result [list \
	    [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] \
	    [catch {.p sash coord  1} msg] $msg \
	    [catch {.p sash coord  2} msg] $msg \

	    ]
    destroy .p
    set result
} [list 1 "invalid sash index" 0 1 "invalid sash index" 1 "invalid sash index"]


test panedwindow-8.1 {sash mark subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash mark} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p sash mark index ?x y?\""]
test panedwindow-8.2 {sash mark subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash mark foo} msg] $msg]
    destroy .p
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-8.3 {sash mark subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash mark 0 foo bar} msg] $msg]

    destroy .p
    set result
} [list 1 "invalid sash index"]
test panedwindow-8.4 {sash mark subcommand, errors} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [list [catch {.p sash mark 0 foo bar} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-8.5 {sash mark subcommand, errors} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [list [catch {.p sash mark 0 0 bar} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "expected integer but got \"bar\""]
test panedwindow-8.6 {sash mark subcommand, mark defaults to 0 0} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [.p sash mark 0]
    destroy .p .b .c
    set result
} [list 0 0]
test panedwindow-8.7 {sash mark subcommand, set mark} {


    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 10 10
    set result [.p sash mark 0]
    destroy .p .b .c
    set result
} [list 10 10]


test panedwindow-9.1 {sash dragto subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash dragto} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p sash dragto index x y\""]
test panedwindow-9.2 {sash dragto subcommand, errors} {





    panedwindow .p
    set result [list [catch {.p sash dragto foo bar baz} msg] $msg]
    destroy .p
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-9.3 {sash dragto subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash dragto 0 foo bar} msg] $msg]

    destroy .p
    set result
} [list 1 "invalid sash index"]
test panedwindow-9.4 {sash dragto subcommand, errors} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [list [catch {.p sash dragto 0 foo bar} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-9.5 {sash dragto subcommand, errors} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [list [catch {.p sash dragto 0 0 bar} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "expected integer but got \"bar\""]


test panedwindow-10.1 {sash mark/sash dragto interaction} {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 20 10
    set result [.p sash coord 0]
    destroy .p .f .c
    set result
} [list 30 0]
test panedwindow-10.2 {sash mark/sash dragto interaction} {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] [button .p.c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 10 20
    set result [.p sash coord 0]
    destroy .p .p.f .p.c
    set result
} [list 0 30]
test panedwindow-10.3 {sash mark/sash dragto, respects minsize}  {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash mark 0 20 10
    .p sash dragto 0 10 10
    set result [.p sash coord 0]
    destroy .p .f .c
    set result
} [list 15 0]


test panedwindow-11.1 {sash place subcommand, errors} {


    panedwindow .p
    set result [list [catch {.p sash place} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p sash place index x y\""]
test panedwindow-11.2 {sash place subcommand, errors} {

    destroy .p
    panedwindow .p
    list [catch {.p sash place foo bar baz} msg] $msg


} [list 1 "expected integer but got \"foo\""]
test panedwindow-11.3 {sash place subcommand, errors} {

    destroy .p
    panedwindow .p
    list [catch {.p sash place 0 foo bar} msg] $msg


} [list 1 "invalid sash index"]
test panedwindow-11.4 {sash place subcommand, errors} {

    destroy .p .b .c
    panedwindow .p
    .p add [button .b] [button .c]
    list [catch {.p sash place 0 foo bar} msg] $msg


} [list 1 "expected integer but got \"foo\""]
test panedwindow-11.5 {sash place subcommand, errors} {
    destroy .p .f .c .b


    panedwindow .p
    .p add [button .b] [button .c]
    list [catch {.p sash place 0 0 bar} msg] $msg


} [list 1 "expected integer but got \"bar\""]
test panedwindow-11.6 {sash place subcommand, moves sash} {

    destroy .p .f .c .b
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 10 0
    .p sash coord 0


} [list 10 0]
test panedwindow-11.7 {sash place subcommand, moves sash} {

    destroy .p .f .c
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 0 10
    .p sash coord 0
} [list 0 10]
test panedwindow-11.8 {sash place subcommand, respects minsize} {
    destroy .p .f .c
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    .p sash coord 0
} [list 15 0]
test panedwindow-11.9 {sash place subcommand, respects minsize} {
    destroy .p .f .c















    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg pink]
    list [catch {.p sash place 0 2 0} msg] $msg


} [list 1 {invalid sash index}]


test panedwindow-12.1 {moving sash changes size of pane to left} {

    destroy .p .f .c
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar] -sticky nsew
    .p sash place 0 30 0
    pack .p
    update
    winfo width .f
} 30
test panedwindow-12.2 {moving sash changes size of pane to right} {

    destroy .p .f .f2
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    pack .p
    update
    set result [winfo width .f2]
    .p sash place 0 30 0
    update
    lappend result [winfo width .f2]


} {20 10}
test panedwindow-12.3 {moving sash does not change reqsize of panedwindow} {

    destroy .p .f .f2
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    .p sash place 0 30 0
    winfo reqwidth .p
} 44
test panedwindow-12.4 {moving sash changes size of pane above} {

    destroy .p .f .c
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [button .c -text foobar] -sticky nsew
    .p sash place 0 0 20
    pack .p
    update
    set result [winfo height .f]
    destroy .p .f .c
    set result
} 20
test panedwindow-12.5 {moving sash changes size of pane below} {

    destroy .p .f .f2
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    pack .p
    update
    set result [winfo height .f2]
    .p sash place 0 0 15
    update
    lappend result [winfo height .f2]
    destroy .p .f .f2
    set result


} {10 5}
test panedwindow-12.6 {moving sash does not change reqsize of panedwindow} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .p]
    .p sash place 0 0 20
    lappend result [winfo reqheight .p]
    destroy .p .f .f2
    set result


} [list 24 24]
test panedwindow-12.7 {moving sash does not alter reqsize of widget} {

    destroy .p .f .f2
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .f]
    .p sash place 0 0 20
    lappend result [winfo reqheight .f]
    destroy .p .f .f2
    set result
} [list 10 10]
test panedwindow-12.8 {moving sash restricted to minsize} {

    destroy .p .f .c
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    pack .p
    update
    set result [winfo width .f]
    destroy .p .f .c
    set result
} 15
test panedwindow-12.10 {moving sash restricted to minsize} {

    destroy .p .f .c
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 30] [button .c] -minsize 10
    .p sash place 0 0 5
    pack .p
    update
    set result [winfo height .f]
    destroy .p .f .c
    set result
} 10
test panedwindow-12.12 {moving sash in unmapped window restricted to reqsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20]
    set result [list [.p sash coord 0]]
    .p sash place 0 100 0
    lappend result [.p sash coord 0]
    destroy .p .f .f2
    set result
} [list {20 0} {40 0}]
test panedwindow-12.13 {moving sash right pushes other sashes} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 0 80 0
    set result [list [.p sash coord 0] [.p sash coord 1]]
    destroy .p .f .f2 .f3
    set result
} {{60 0} {64 0}}
test panedwindow-12.14 {moving sash left pushes other sashes} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 1 0 0
    set result [list [.p sash coord 0] [.p sash coord 1]]
    destroy .p .f .f2 .f3
    set result
} {{0 0} {4 0}}
test panedwindow-12.15 {move sash in mapped window restricted to visible win} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 50
    update
    .p sash place 1 100 0
    update
    set result [.p sash coord 1]
    destroy .p .f .f2 .f3
    set result
} {46 0}
test panedwindow-12.16 {move sash in mapped window restricted to visible win} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    update
    .p sash place 1 200 0
    update
    set result [.p sash coord 1]
    destroy .p .f .f2 .f3
    set result
} {96 0}
test panedwindow-12.17 {moving sash into "virtual" space on \
	last pane increases reqsize} {

    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    set result [winfo reqwidth .p]
    update
    .p sash place 1 200 0
    update
    lappend result [winfo reqwidth .p]
    destroy .p .f .f2 .f3
    set result
} {68 100}


test panedwindow-13.1 {horizontal panedwindow lays out widgets properly} {



    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    set result {}
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    destroy .p .p.f .p.f2 .p.f3
    set result


} [list 2 2 28 2 54 2]
test panedwindow-13.2 {vertical panedwindow lays out widgets properly} {



    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2 \
            -orient vertical
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    set result {}
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    destroy .p .p.f .p.f2 .p.f3
    set result


} [list 2 2 2 18 2 34]
test panedwindow-13.3 {horizontal panedwindow lays out widgets properly} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach {win color} {.p.f blue .p.f2 green} {
	.p add [frame $win -width 20 -height 20 -bg $color] -padx 10 -pady 5 \
                -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    destroy .p .p.f .p.f2
    set result


} [list 80 30 10 5 50 5 60 30 0 5 30 5]
test panedwindow-13.4 {vertical panedwindow lays out widgets properly} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach win {.p.f .p.f2} {
	.p add [frame $win -width 20 -height 20] -padx 10 -pady 5 -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    destroy .p .p.f .p.f2
    set result


} [list 40 60 10 5 10 35 40 50 10 0 10 25]
test panedwindow-13.5 {panedwindow respects reqsize of panes when possible} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
    destroy .p .p.f
    set result
} [list 20 30]
test panedwindow-13.6 {panedwindow takes explicit widget width over reqwidth} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -width 20 -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
    destroy .p .p.f
    set result
} [list 20 20]
test panedwindow-13.7 {horizontal panedwindow reqheight is max slave height} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
    destroy .p .p.f .p.f2
    set result
} {20 40}
test panedwindow-13.8 {horizontal panedwindow reqheight is max slave height} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -height 15
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
    destroy .p .p.f .p.f2
    set result
} {20 20}
test panedwindow-13.9 {panedwindow pane width overrides widget width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 10 0
    pack .p
    update
    set result [winfo width .p.f]
    .p paneconfigure .p.f -width 30
    lappend result [winfo width .p.f]
    destroy .p .p.f .p.f2
    set result
} [list 10 10]
test panedwindow-13.10 {panedwindow respects reqsize of panes when possible} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
    destroy .p .p.f
    set result
} [list 20 30]
test panedwindow-13.11 {panedwindow takes explicit height over reqheight} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -height 20 -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
    destroy .p .p.f
    set result
} [list 20 20]
test panedwindow-13.12 {vertical panedwindow reqwidth is max slave width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
    destroy .p .p.f .p.f2
    set result
} {20 40}
test panedwindow-13.13 {vertical panedwindow reqwidth is max slave width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -width 15
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
    destroy .p .p.f .p.f2
    set result
} {20 20}
test panedwindow-13.14 {panedwindow pane height overrides widget width} {

    destroy .p
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 0 10
    pack .p
    update
    set result [winfo height .p.f]
    .p paneconfigure .p.f -height 30
    lappend result [winfo height .p.f]
    destroy .p
    set result
} [list 10 10]


test panedwindow-14.1 {PanestructureProc, widget yields managements} {


    # Check that the panedwindow correctly yields geometry management of
    # a slave when the slave is destroyed.

    # This test should not cause a core dump, and it should not cause
    # a memory leak.
    destroy .p .b
    panedwindow .p
    .p add [button .b]
    destroy .p
    pack .b
    destroy .b
    set result ""
} ""
test panedwindow-14.2 {PanedWindowLostSlaveProc, widget yields management} {


    # Check that the paned window correctly yields geometry management of
    # a slave when some other geometry manager steals the slave from us.

    # This test should not cause a core dump, and it should not cause a
    # memory leak.
    destroy .p .b
    panedwindow .p
    .p add [button .b]
    pack .p
    update
    pack .b
    update
    set result [.p panes]
    destroy .p .b
    set result
} {}

set stickysets [list n s e w sn ns en ne wn nw esn nse nsw nsew ""]
set stickygets [list n s e w ns ns ne ne nw nw nes nes nsw nesw ""]





set i 0









foreach s $stickysets g $stickygets {



    test panedwindow-15.[incr i] {panedwindow sticky settings} {



	destroy .p .b


























































	panedwindow .p -showhandle false
	.p add [button .b]
	.p paneconfigure .b -sticky $s
	set result [.p panecget .b -sticky]







	destroy .p .b






















































	set result
    } $g
}




















set i 0
foreach s [list {}  n  s  e  w ns ew nw ne se sw nse nsw sew new news] \
	x [list 10 10 10 20  0 10  0  0 20 20  0  20   0   0   0    0] \










	y [list 10  0 20 10 10  0 10  0  0 20 20   0   0  20   0    0] \










	w [list 20 20 20 20 20 20 40 20 20 20 20  20  20  40  40   40] \










	h [list 20 20 20 20 20 40 20 20 20 20 20  40  40  20  20   40] {
    test panedwindow-16.[incr i] {panedwindow sticky works} {


	panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
	.p add [frame .p.f -height 20 -width 20 -bg red] -sticky $s
	place .p -width 40 -height 40
	update
	set result [list $s [winfo x .p.f] [winfo y .p.f] \










		[winfo width .p.f] [winfo height .p.f]]








	destroy .p .p.f




	set result


    } [list $s $x $y $w $h]






}

















































































test panedwindow-17.1 {setting minsize when pane is too small snaps width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f -height 20 -width 20 -bg red]
    set result [winfo reqwidth .p]
    .p paneconfigure .p.f -minsize 40
    lappend result [winfo reqwidth .p]
    destroy .p .p.f .p.f2
    set result
} [list 20 40]


test panedwindow-18.1 {MoveSash, move right} {

    set result {}

    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 30 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 42 42 {30 0}]
test panedwindow-18.2 {MoveSash, move right (unmapped) clipped by reqwidth} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 40 0]
test panedwindow-18.3 {MoveSash, move right (mapped, width < reqwidth) clipped by width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width < reqwidth
    place .p -x 0 -y 0 -width 32
    update

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 30 0]
test panedwindow-18.4 {MoveSash, move right (mapped, width > reqwidth) clipped by width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -width 102
    update

    .p sash place 0 200 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 100 0]
test panedwindow-18.5 {MoveSash, move right respects minsize} {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 30 0]
test panedwindow-18.6 {MoveSash, move right respects minsize} {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 40 0]
test panedwindow-18.7 {MoveSash, move right pushes other sashes} {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 1]










    # Cleanup
    destroy .p .f1 .f2 .f3




    set result
} [list 62 0]
test panedwindow-18.8 {MoveSash, move right pushes other sashes, respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 1]










    # Cleanup
    destroy .p .f1 .f2 .f3


    set result



} [list 52 0]
test panedwindow-18.9 {MoveSash, move right respects minsize, exludes pad} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize 10 -padx 5
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 50 0]
test panedwindow-18.10 {MoveSash, move right, negative minsize becomes 0} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize -50
    }

    .p sash place 0 50 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [list [.p sash coord 0] [.p sash coord 1]]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list [list 50 0] [list 52 0]]
test panedwindow-18.11 {MoveSash, move left} {


    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 10 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 42 42 {10 0}]
test panedwindow-18.12 {MoveSash, move left, can't move outside of window} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 -100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 0]
test panedwindow-18.13 {MoveSash, move left respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 10 0]
test panedwindow-18.14 {MoveSash, move left respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    set result [.p sash coord 1]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 22 0]
test panedwindow-18.15 {MoveSash, move left pushes other sashes} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 0]
test panedwindow-18.16 {MoveSash, move left pushes other sashes, respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 10 0]
test panedwindow-18.17 {MoveSash, move left respects minsize, exludes pad} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize 10 -padx 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [.p sash coord 1]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 42 0]
test panedwindow-18.18 {MoveSash, move left, negative minsize becomes 0} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue green} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize -50
    }

    .p sash place 1 10 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [list [.p sash coord 0] [.p sash coord 1]]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list [list 8 0] [list 10 0]]


test panedwindow-19.1 {MoveSash, move down} {


    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 30

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 42 42 {0 30}]
test panedwindow-19.2 {MoveSash, move down (unmapped) clipped by reqheight} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the reqheight of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 40]
test panedwindow-19.3 {MoveSash, move down (mapped, height < reqheight) clipped by height} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a height < reqheight
    place .p -x 0 -y 0 -height 32
    update

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the visible height of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 30]
test panedwindow-19.4 {MoveSash, move down (mapped, height > reqheight) clipped by height} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -height 102
    update

    .p sash place 0 0 200

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 100]
test panedwindow-19.5 {MoveSash, move down respects minsize} {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 30]
test panedwindow-19.6 {MoveSash, move down respects minsize} {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 40]
test panedwindow-19.7 {MoveSash, move down pushes other sashes} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 1]











    # Cleanup
    destroy .p .f1 .f2 .f3


    set result



} [list 0 62]
test panedwindow-19.8 {MoveSash, move down pushes other sashes, respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 1]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 52]
test panedwindow-19.9 {MoveSash, move down respects minsize, exludes pad} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize 10 -pady 5
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 50]
test panedwindow-19.10 {MoveSash, move right, negative minsize becomes 0} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize -50
    }

    .p sash place 0 0 50

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [list [.p sash coord 0] [.p sash coord 1]]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list [list 0 50] [list 0 52]]
test panedwindow-19.11 {MoveSash, move up} {


    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 10

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 42 42 {0 10}]
test panedwindow-19.12 {MoveSash, move up, can't move outside of window} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 -100

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 0]
test panedwindow-19.13 {MoveSash, move up respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2

    set result
} [list 0 10]
test panedwindow-19.14 {MoveSash, move up respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    set result [.p sash coord 1]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 22]
test panedwindow-19.15 {MoveSash, move up pushes other sashes} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 0]
test panedwindow-19.16 {MoveSash, move up pushes other sashes, respects minsize} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    set result [.p sash coord 0]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 10]
test panedwindow-19.17 {MoveSash, move up respects minsize, exludes pad} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize 10 -pady 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [.p sash coord 1]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list 0 42]
test panedwindow-19.18 {MoveSash, move up, negative minsize becomes 0} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue green} {
	.p add [frame $w -height 20 -width 20 -bg $c] \
		-sticky nsew -minsize -50
    }

    .p sash place 1 0 10

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    set result [list [.p sash coord 0] [.p sash coord 1]]

    # Cleanup
    destroy .p .f1 .f2 .f3

    set result
} [list [list 0 8] [list 0 10]]


# The following tests check that the panedwindow is correctly computing its
# geometry based on the various configuration options that can affect the
# geometry.

test panedwindow-20.1 {ComputeGeometry, reqheight taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 60 20] [list 60 40]]

test panedwindow-20.2 {ComputeGeometry, reqheight taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 60 20] [list 60 40]]

test panedwindow-20.3 {ComputeGeometry, reqheight taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue] -pady 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 60 60] [list 60 80]]

test panedwindow-20.4 {ComputeGeometry, reqwidth taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 20 60] [list 40 60]]

test panedwindow-20.5 {ComputeGeometry, reqwidth taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 20 60] [list 40 60]]

test panedwindow-20.6 {ComputeGeometry, reqwidth taken from widgets} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue] -padx 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
    destroy .p .f1 .f2 .f3
    set result
} [list [list 60 60] [list 80 60]]


set i 6
foreach bd {0 2} {
    foreach sp {0 5} {
	foreach sw {0 3} {
	    foreach h {0 1} {
		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, one slave, reqsize set properly} {
		    # With just one slave, sashpad and sashwidth should not
		    # affect the panedwindow's geometry, since no sash should
		    # ever be drawn.
		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h
		    .p add [frame .p.f -width 20 -height 20 -bg red] -padx $h \
                            -sticky ""
		    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
		    destroy .p .p.f

		    set result
		} [list [expr {(2 * $bd) + 20 + (2 * $h)}] \
			[expr {(2 * $bd) + 20}]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, three panes, reqsize set properly} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h
		    foreach w {.p.f1 .p.f2 .p.f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
                                -sticky ""
		    }
		    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
		    destroy .p .p.f1 .p.f2 .p.f3

		    set result
		} [list [expr {(2 * $bd) + ($h?12:(2*$sw)) + (4*$sp) + 60}] \
			[expr {(2 * $bd) + 20}]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, sash coords} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h
		    foreach w {.f1 .f2 .f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
                                -sticky ""
		    }
		    set result [list [.p sash coord 0] [.p sash coord 1]]
		    destroy .p .f1 .f2 .f3

		    set result
		} [list [list [expr {$bd+20+($h?(6-$sw)/2:0)+$sp}] $bd] \
			[list [expr {$bd+40+($h?6+(6-$sw)/2:$sw)+(3*$sp)}] \
			    $bd]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry/ArrangePanes, slave coords} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h
		    foreach w {.p.f1 .p.f2 .p.f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
				-sticky nsew -pady 3 -padx 11
		    }
		    pack .p
		    update
		    set result {}
		    foreach w {.p.f1 .p.f2 .p.f3} {
			lappend result [list [winfo x $w] [winfo y $w] \
				[winfo width $w] [winfo height $w]]
		    }
		    destroy .p .p.f1 .p.f2 .p.f3
		    set result
		} [list [list [expr {$bd+11}] [expr {$bd+3}] 20 20] \
			[list [expr {$bd+53+($h?6:$sw)+(2*$sp)}] \
			    [expr {$bd+3}] 20 20] \

			[list [expr {$bd+95+($h?12:2*$sw)+(4*$sp)}] \
			    [expr {$bd+3}] 20 20]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, one slave, vertical} {


		    # With just one slave, sashpad and sashwidth should not
		    # affect the panedwindow's geometry, since no sash should
		    # ever be drawn.
		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -orient vertical -sashwidth $sw -handlesize 6 \
			    -showhandle $h
		    .p add [frame .f -width 20 -height 20 -bg red] -pady $h \
                            -sticky ""
		    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
		    destroy .p .f

		    set result
		} [list [expr {(2 * $bd) + 20}] \
			[expr {(2 * $bd) + 20 + (2 * $h)}]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, three panes, vertical} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h \
			    -orient vertical
		    foreach w {.f1 .f2 .f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
                                -sticky ""
		    }
		    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
		    destroy .p .f1 .f2 .f3

		    set result
		} [list [expr {(2 * $bd) + 20}] \
			[expr {(2 * $bd) + ($h?12:(2*$sw)) + (4*$sp) + 60}]]

		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \
			{ComputeGeometry, sash coords, vertical} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h \
			    -orient vertical
		    foreach w {.f1 .f2 .f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
                                -sticky ""
		    }
		    set result [list [.p sash coord 0] [.p sash coord 1]]



		    destroy .p .f1 .f2 .f3












		    set result





















		} [list [list $bd [expr {$bd+20+($h?(6-$sw)/2:0)+$sp}]] \












			[list $bd \













			    [expr {$bd+40+($h?6+(6-$sw)/2:$sw)+(3*$sp)}]]]




















		test panedwindow-20.[incr i]-$bd-$sp-$sw-$h \














































			{ComputeGeometry/ArrangePanes, slave coords, vert} {


		    panedwindow .p -borderwidth $bd -sashpad $sp \
			    -sashwidth $sw -handlesize 6 -showhandle $h \
			    -orient vertical
		    foreach w {.p.f1 .p.f2 .p.f3} {
			.p add [frame $w -width 20 -height 20 -bg blue] \
				-sticky nsew -pady 11 -padx 3
		    }
		    pack .p
		    update
		    set result {}
		    foreach w {.p.f1 .p.f2 .p.f3} {
			lappend result [list [winfo x $w] [winfo y $w] \
				[winfo width $w] [winfo height $w]]
		    }























		    destroy .p .p.f1 .p.f2 .p.f3





































































































































































































































		    set result





















		} [list [list [expr {$bd+3}] [expr {$bd+11}] 20 20] \












			[list [expr {$bd+3}] \













			    [expr {$bd+53+($h?6:$sw)+(2*$sp)}] 20 20] \





































































































































































			[list [expr {$bd+3}] \














			    [expr {$bd+95+($h?12:2*$sw)+(4*$sp)}] 20 20]]









	    }






























































































































































































	}




    }








}

























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































test panedwindow-21.1 {destroyed widgets are removed from panedwindow} {


    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    set result [.p panes]

    destroy .p
    set result
} {}
test panedwindow-21.2 {destroyed slave causes geometry recomputation} {


    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    destroy .f
    set result [winfo reqwidth .p]
    destroy .p .f2

    set result
} 20

test panedwindow-22.1 {ArrangePanes, extra space is given to the last pane} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 100 -x 0 -y 0
    update
    set result [winfo width .f2]
    destroy .p .f1 .f2

    set result
} 78
test panedwindow-22.2 {ArrangePanes, extra space is given to the last pane} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 100 -x 0 -y 0
    update
    set result [winfo height .f2]
    destroy .p .f1 .f2

    set result
} 78
test panedwindow-22.3 {ArrangePanes, explicit height/width are preferred} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky ""
    .p paneconfigure .f1 -width 10 -height 15
    pack .p
    update
    set result [list [winfo width .f1] [winfo height .f1]]
    destroy .p .f1 .f2
    set result
} {10 15}
test panedwindow-22.4 {ArrangePanes, panes clipped by size of pane} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 10 0
    pack .p
    update
    set result [list [winfo width .f1] [winfo height .f1]]
    destroy .p .f1 .f2
    set result
} {10 20}
test panedwindow-22.5 {ArrangePanes, panes clipped by size of pane} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 0 10
    pack .p
    update
    set result [list [winfo width .f1] [winfo height .f1]]
    destroy .p .f1 .f2
    set result
} {20 10}
test panedwindow-22.6 {ArrangePanes, height of pane taken from total height} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red] -sticky ""
    pack .p
    update
    set result [list [winfo y .p.f1]]
    destroy .p .p.f1 .p.f2

    set result
} 10
test panedwindow-22.8 {ArrangePanes, width of pane taken from total width} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 40 -height 40 -bg red] -sticky ""
    pack .p
    update
    set result [list [winfo x .p.f1]]
    destroy .p .p.f1 .p.f2

    set result
} 10
test panedwindow-22.9 {ArrangePanes, panes with width <= 0 are unmapped} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .f1]
    destroy .p .f1 .f2
    set result
} {1 0}
test panedwindow-22.10 {ArrangePanes, panes with width <= 0 are unmapped} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
    destroy .p .p.f1 .p.f2
    set result
} {1 0}
test panedwindow-22.11 {ArrangePanes, panes with width <= 0 are unmapped} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
    destroy .p .p.f1 .p.f2
    set result
} {1 0}
test panedwindow-22.12 {ArrangePanes, last pane shrinks} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 40 -x 0 -y 0
    update
    set result [winfo width .f2]
    destroy .p .f1 .f2

    set result
} 18
test panedwindow-22.13 {ArrangePanes, last pane shrinks} {


    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 40 -x 0 -y 0
    update
    set result [winfo height .f2]
    destroy .p .f1 .f2

    set result
} 18
test panedwindow-22.14 {ArrangePanes, panedwindow resizes} {

    -body {
	panedwindow .p -width 200 -borderwidth 0
	frame .f1 -height 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
    }
    -cleanup {destroy .p .f1}

    -result {200 1 200 50}
}
test panedwindow-22.15 {ArrangePanes, panedwindow resizes} {

    -body {
	panedwindow .p -height 200 -borderwidth 0 -orient vertical
	frame .f1 -width 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
    }
    -cleanup {destroy .p .f1}

    -result {1 200 50 200}
}
test panedwindow-22.16 {ArrangePanes, last pane grows} {

    -body {
	panedwindow .p -showhandle false -height 50
	.p add [frame .f1 -width 50 -bg red] [frame .f2 -width 50 -bg white] \
		[frame .f3 -width 50 -bg blue] [frame .f4 -width 50 -bg green]
	.p sash place 1 250 0
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p configure -width 300
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {50 150 1 1 211 50 150 1 89 300}
}


test panedwindow-23.1 {PanedWindowReqProc, react to slave geometry changes} {

    # Basically just want to make sure that the PanedWindowReqProc is called
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
    destroy .p .f1 .f2
    set result
} {40 80}
test panedwindow-23.2 {PanedWindowReqProc, react to slave geometry changes} {


    panedwindow .p -orient horizontal -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 10] [frame .f2 -width 10]
    set result [winfo reqwidth .p]
    .f1 configure -width 20
    lappend result [winfo reqwidth .p]
    destroy .p .f1 .f2
    expr {[lindex $result 1] - [lindex $result 0]}
} {10}




test panedwindow-24.1 {ConfigurePanes, can't add panedwindow to itself} {


    panedwindow .p
    set result [list [catch {.p add .p} msg] $msg]

    destroy .p
    set result
} [list 1 "can't add .p to itself"]
test panedwindow-24.2 {ConfigurePanes, bad window throws error} {


    panedwindow .p
    set result [list [catch {.p add .b} msg] $msg]

    destroy .p
    set result
} [list 1 "bad window path name \".b\""]
test panedwindow-24.3 {ConfigurePanes, bad window aborts processing} {


    panedwindow .p
    button .b
    catch {.p add .b .a}
    set result [.p panes]
    destroy .p .b

    set result
} {}
test panedwindow-24.4 {ConfigurePanes, bad option aborts processing} {


    panedwindow .p
    button .b
    catch {.p add .b -sticky foobar}
    set result [.p panes]
    destroy .p .b

    set result
} {}
test panedwindow-24.5 {ConfigurePanes, after win isn't managed by panedwin} {


    panedwindow .p
    button .b
    button .c
    set result [list [catch {.p add .b -after .c} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "window \".c\" is not managed by .p"]
test panedwindow-24.6 {ConfigurePanes, before win isn't managed by panedwin} {


    panedwindow .p
    button .b
    button .c
    set result [list [catch {.p add .b -before .c} msg] $msg]
    destroy .p .b .c
    set result
} [list 1 "window \".c\" is not managed by .p"]
test panedwindow-24.7 {ConfigurePanes, -after {} is a no-op} {


    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -after {}
    set result [.p panes]
    destroy .p .b .c
    set result
} {.b .c}
test panedwindow-24.8 {ConfigurePanes, -before {} is a no-op} {


    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -before {}
    set result [.p panes]
    destroy .p .b .c
    set result
} {.b .c}
test panedwindow-24.9 {ConfigurePanes, new panes are added} {


    panedwindow .p
    .p add [button .b] [button .c]
    set result [.p panes]
    destroy .p .b .c
    set result
} {.b .c}
test panedwindow-24.10 {ConfigurePanes, options applied to all panes} {


    panedwindow .p
    .p add [button .b] [button .c] -sticky ne -height 5 -width 5 -minsize 10
    set result {}
    foreach w {.b .c} {
	set val {}
	foreach option {-sticky -height -width -minsize} {
	    lappend val $option [.p panecget $w $option]
	}
	lappend result $w $val
    }
    destroy .p .b .c
    set result


} [list .b {-sticky ne -height 5 -width 5 -minsize 10} \
	.c {-sticky ne -height 5 -width 5 -minsize 10}]
test panedwindow-24.11 {ConfigurePanes, existing panes are reconfigured} {


    panedwindow .p
    .p add [button .b] -sticky nw -height 10
    .p add .b [button .c] -sticky se -height 2
    set result [list [.p panes] \
	    [.p panecget .b -sticky] [.p panecget .b -height] \
	    [.p panecget .c -sticky] [.p panecget .c -height]]
    destroy .p .b .c
    set result
} [list {.b .c} es 2 es 2]
test panedwindow-24.12 {ConfigurePanes, widgets added to end by default} {


    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [.p panes]
    destroy .p .b .c .d
    set result
} {.b .c .d}
test panedwindow-24.13 {ConfigurePanes, -after, single addition} {


    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .b
    .p add .c -after .a
    set result [.p panes]
    destroy .p .a .b .c
    set result
} {.a .c .b}
test panedwindow-24.14 {ConfigurePanes, -after, multiple additions} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b
    .p add .c .d -after .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.a .c .d .b}
test panedwindow-24.15 {ConfigurePanes, -after, relocates existing widget} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d -after .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.a .d .b .c}
test panedwindow-24.16 {ConfigurePanes, -after, relocates existing widgets} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .b .d -after .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.a .b .d .c}
test panedwindow-24.17 {ConfigurePanes, -after, relocates existing widgets} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .b
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.b .d .a .c}
test panedwindow-24.18 {ConfigurePanes, -after, relocates existing widgets} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.d .a .b .c}
test panedwindow-24.19 {ConfigurePanes, -after, after last window} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -after .c
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.a .b .c .d}
test panedwindow-24.20 {ConfigurePanes, -before, before first window} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -before .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.d .a .b .c}
test panedwindow-24.21 {ConfigurePanes, -before, relocate existing windows} {


    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d .b -before .a
    set result [.p panes]
    destroy .p .a .b .c .d
    set result
} {.d .b .a .c}
test panedwindow-24.22 {ConfigurePanes, slave specified multiple times} {


    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    set result [.p panes]
    destroy .p .a .b .c
    set result
} {.a .b .c}
test panedwindow-24.23 {ConfigurePanes, slave specified multiple times} {


    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p add .a .b .a -after .c
    set result [.p panes]
    destroy .p .a .b .c
    set result
} {.c .a .b}
test panedwindow-24.24 {ConfigurePanes, panedwindow cannot manage toplevels} {


    panedwindow .p
    toplevel .t
    set result [list [catch {.p add .t} msg] $msg]
    destroy .p .t
    set result
} [list 1 "can't add toplevel .t to .p"]
test panedwindow-24.25 {ConfigurePanes, restrict possible panes} {


    panedwindow .p
    frame .f
    button .f.b
    set result [list [catch {.p add .f.b} msg] $msg]
    destroy .p .f .f.b
    set result
} [list 1 "can't add .f.b to .p"]
test panedwindow-24.26 {ConfigurePanes, restrict possible panes} {


    frame .f
    panedwindow .f.p
    button .b
    set result [list [catch {.f.p add .b} msg] $msg]
    destroy .f.p .f .b

    set result
} [list 0 ""]
test panedwindow-24.27 {ConfigurePanes, restrict possible panes} {


    panedwindow .p
    button .p.b
    set result [list [catch {.p add .p.b} msg] $msg]
    destroy .p .p.b

    set result
} [list 0 ""]
test panedwindow-24.28 {ConfigurePanes, restrict possible panes} {


    frame .f
    frame .f.f
    frame .f.f.f
    panedwindow .f.f.f.p
    button .b
    set result [list [catch {.f.f.f.p add .b} msg] $msg]
    destroy .f .f.f .f.f.f .f.f.f.p .b

    set result
} [list 0 ""]
test panedwindow-24.29.1 {ConfigurePanes, -hide works} {

    -body {
	panedwindow .p -showhandle false
	frame .f1 -width 40 -height 100 -bg red
	frame .f2 -width 40 -height 100 -bg white
	frame .f3 -width 40 -height 100 -bg blue
	frame .f4 -width 40 -height 100 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {1 1 1 1 40 40 40 40 171 1 0 1 1 40 40 40 40 128}
}
test panedwindow-24.29.2 {ConfigurePanes, -hide works} {

    -body {
	panedwindow .p -showhandle false -width 130 -height 100
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {1 1 1 0 39 40 40 1 130 1 0 1 1 40 40 40 42 130}
































}
test panedwindow-24.29.3 {ConfigurePanes, -hide works, last pane stretches} {

    -body {
	panedwindow .p -showhandle false -width 200 -height 200 -borderwidth 0
	frame .f1 -width 50 -bg red
	frame .f2 -width 50 -bg green
	frame .f3 -width 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
    }
    -cleanup {destroy .p .f1 .f2 .f3}

    -result {50 50 94 50 50 147}
}
test panedwindow-24.29.4 {ConfigurePanes, -hide works, last pane stretches} {

    -body {
	panedwindow .p -showhandle false -width 200 -height 200 \
		-borderwidth 0 -orient vertical
	frame .f1 -height 50 -bg red
	frame .f2 -height 50 -bg green
	frame .f3 -height 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
    }
    -cleanup {destroy .p .f1 .f2 .f3}

    -result {50 50 94 50 50 147}
}

test panedwindow-24.30 {ConfigurePanes, -stretch first} {

    -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch first
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {51 40 40 40 94 40 40 40}
}
test panedwindow-24.31 {ConfigurePanes, -stretch middle} {

    -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch middle
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {40 45 46 40 40 45 94 40}
}
test panedwindow-24.32 {ConfigurePanes, -stretch always} {

    -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch always
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {42 43 43 43 58 43 58 58}
}
test panedwindow-24.33 {ConfigurePanes, -stretch never} {

    -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch never
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
    }
    -cleanup {destroy .p .f1 .f2 .f3 .f4}

    -result {40 40 40 40 40 40 40 40}
}

test panedwindow-25.1 {Unlink, remove a paned with -before/-after refs} {


    # Bug 928413
    set result {}
    panedwindow .pw
    label .pw.l1 -text Label1
    label .pw.l2 -text Label2
    label .pw.l3 -text Label3
    .pw add .pw.l1
    .pw add .pw.l3
    .pw add .pw.l2 -before .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    destroy .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    .pw paneconfigure .pw.l2 -before .pw.l1
    lappend result [.pw panecget .pw.l2 -before]
    destroy .pw
    set result
} {.pw.l3 {} .pw.l1}


test panedwindow-26.1 {DestroyPanedWindow} {


    # This test should not result in any memory leaks.
    panedwindow .p
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .q .r .s .t} {
	.p add [button $w]
    }
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t} {
	destroy $w
    }
    set result {}
} {}
test panedwindow-26.2 {UnmapNotify and MapNotify events are propagated to slaves} {


    panedwindow .pw
    .pw add [button .pw.b]
    pack .pw
    update
    set result [winfo ismapped .pw.b]
    pack forget .pw
    update
    lappend result [winfo ismapped .pw.b]
    lappend result [winfo ismapped .pw]
    pack .pw
    update
    lappend result [winfo ismapped .pw]
    lappend result [winfo ismapped .pw.b]
    destroy .pw .pw.b
    set result


} {1 0 0 1 1}


test panedwindow-27.1 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 0]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.2 {PanedWindowIdentifyCoords, padding is included} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 20 0]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.3 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 22 0]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.4 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 24 0]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.5 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 26 0]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.6 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 26 -1]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.7 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 26 100]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.8 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 22 4]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.9 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 22 5]
    destroy .p .f .f2
    set result
} {0 handle}
test panedwindow-27.10 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 20 5]
    destroy .p .f .f2
    set result
} {0 handle}
test panedwindow-27.11 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 20 0]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.12 {PanedWindowIdentifyCoords} {


    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    set result [.p identify 48 0]
    destroy .p .f .f2 .f3
    set result
} {1 sash}
test panedwindow-27.13 {identify subcommand errors} {


    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4
    set result [list [catch {.p identify} msg] $msg]

    destroy .p
    set result
} [list 1 "wrong # args: should be \".p identify x y\""]
test panedwindow-27.14 {identify subcommand errors} {


    panedwindow .p
    set result [list [catch {.p identify foo bar} msg] $msg]

    destroy .p
    set result
} [list 1 "expected integer but got \"foo\""]
test panedwindow-27.14a {identify subcommand errors} {
    panedwindow .p
    set result [list [catch {.p identify 0 bar} msg] $msg]

    destroy .p


    set result
} [list 1 "expected integer but got \"bar\""]
test panedwindow-27.15 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 0]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.16 {PanedWindowIdentifyCoords, padding is included} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 20]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.17 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 22]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.18 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 24]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.19 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 26]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.20 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify -1 26]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.21 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 100 26]
    destroy .p .f .f2

    set result
} {}
test panedwindow-27.22 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 4 22]
    destroy .p .f .f2



    set result
} {0 sash}
test panedwindow-27.23 {PanedWindowIdentifyCoords} {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 5 22]
    destroy .p .f .f2
    set result
} {0 handle}
test panedwindow-27.24 {PanedWindowIdentifyCoords} {


    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 5 20]
    destroy .p .f .f2



    set result
} {0 handle}
test panedwindow-27.25 {PanedWindowIdentifyCoords} {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    set result [.p identify 0 20]
    destroy .p .f .f2
    set result
} {0 sash}
test panedwindow-27.26 {PanedWindowIdentifyCoords} {


    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    set result [.p identify 0 48]
    destroy .p .f .f2 .f3
    set result
} {1 sash}


test panedwindow-28.1 {destroy the window cleanly on error [Bug #616589]} {


    list [catch {panedwindow .p -bogusopt bogus} msg] $msg


} {1 {unknown option "-bogusopt"}}
test panedwindow-28.2 {destroy the window cleanly on rename [Bug #616589]} {


    destroy .p
    panedwindow .p
    rename .p {}
    winfo exists .p
} {0}




test panedwindow-29.1 {resizing width} {

    -body {
        panedwindow .p -bd 5
        frame .f1 -width 100 -height 50 -bg blue
        frame .f2 -width 100 -height 50 -bg red

        .p add .f1 -sticky news
        .p add .f2 -sticky news
        pack .p -side top -fill both -expand 1
        wm geometry . ""
        update
        # Note the width
        set a [winfo width .f2]
        # Increase the size by 10
        regexp {^(\d+)x(\d+)} [wm geometry .] -> w h
        wm geometry . [expr {$w + 10}]x$h
        update
        set b "$a [winfo width .f2]"
    }
    -cleanup {destroy .p .f1 .f2}

    -result {100 110}
}

test panedwindow-29.2 {resizing height} {
    -body {
        panedwindow .p -orient vertical -bd 5
        frame .f1 -width 50 -height 100 -bg blue
        frame .f2 -width 50 -height 100 -bg red

        .p add .f1 -sticky news
        .p add .f2 -sticky news
        pack .p -side top -fill both -expand 1
        wm geometry . ""
        update
        # Note the height
        set a [winfo height .f2]
        # Increase the size by 10
        regexp {^(\d+)x(\d+)} [wm geometry .] -> w h
        wm geometry . ${w}x[expr {$h + 10}]
        update
        set b "$a [winfo height .f2]"
    }
    -cleanup {destroy .p .f1 .f2}

    -result {100 110}
}

test panedwindow-30.1 {display on depths other than the default one} {
    -constraints {pseudocolor8 haveTruecolor24}


    -body {
	toplevel .t -visual {truecolor 24}
	pack [panedwindow .t.p]
	.t.p add [frame .t.p.f1] [frame .t.p.f2]
	update
	# If we got here, we didn't crash and that's good
    }
    -cleanup {destroy .t}

    -result {}
}
test panedwindow-30.2 {display on depths other than the default one} {
    -constraints {pseudocolor8 haveTruecolor24}


    -body {
	toplevel .t -visual {pseudocolor 8}
	pack [frame .t.f -visual {truecolor 24}]
	pack [panedwindow .t.f.p]
	.t.f.p add [frame .t.f.p.f1 -width 5] [frame .t.f.p.f2 -width 5]
	update
	.t.f.p proxy place 1 1
	update
	.t.f.p proxy forget
	update
	# If we got here, we didn't crash and that's good
    }
    -cleanup {destroy .t}

    -result {}
}

# cleanup
cleanupTests
return


Deleted tests/pkgconfig.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# -*- tcl -*-
# Commands covered:  pkgconfig
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file into Tk runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2017 Stuart Cassoff <stwo@users.sourceforge.net>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint nodeprecated [expr {"nodeprecated" ni [tk::pkgconfig list]}]

test pkgconfig-1.1 {query keys} nodeprecated {
    lsort [::tk::pkgconfig list]
} [list \
    64bit bindir,install bindir,runtime debug demodir,install demodir,runtime \
    docdir,install docdir,runtime fontsystem includedir,install includedir,runtime \
    libdir,install libdir,runtime mem_debug optimized profiled \
    scriptdir,install scriptdir,runtime threaded \
]
test pkgconfig-1.2 {query keys multiple times} {
    string compare [::tk::pkgconfig list] [::tk::pkgconfig list]
} 0
test pkgconfig-1.3 {query value multiple times} {
    string compare \
	    [::tk::pkgconfig get 64bit] \
	    [::tk::pkgconfig get 64bit]
} 0


test pkgconfig-2.0 {error: missing subcommand} {
    catch {::tk::pkgconfig} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"}
test pkgconfig-2.1 {error: illegal subcommand} {
    catch {::tk::pkgconfig foo} msg
    set msg
} {bad subcommand "foo": must be get or list}
test pkgconfig-2.2 {error: list with arguments} {
    catch {::tk::pkgconfig list foo} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig list"}
test pkgconfig-2.3 {error: get without arguments} {
    catch {::tk::pkgconfig get} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig get key"}
test pkgconfig-2.4 {error: query unknown key} {
    catch {::tk::pkgconfig get foo} msg
    set msg
} {key not known}
test pkgconfig-2.5 {error: query with to many arguments} {
    catch {::tk::pkgconfig get foo bar} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"}

# cleanup
cleanupTests
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































Changes to tests/place.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350



351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533
# This file is a Tcl script to test out the "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# XXX - This test file is woefully incomplete.  At present, only a
# few of the features are tested.

# Widgets used in tests 1.* - 8.*
toplevel .t -width 300 -height 200 -bd 0
wm geom .t +0+0
frame .t.f -width 154 -height 84 -bd 2 -relief raised
place .t.f -x 48 -y 38
frame .t.f2 -width 30 -height 60 -bd 2 -relief raised
update

test place-1.1 {Tk_PlaceCmd procedure, "info" option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -x 0
    place info .t.f2
} -result {-in .t -x 0 -relx 0 -y 0 -rely 0 -width {} -relwidth {} -height {} -relheight {} -anchor nw -bordermode inside}
test place-1.2 {Tk_PlaceCmd procedure, "info" option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -x 1 -y 2 -width 3 -height 4 -relx 0.1 -rely 0.2 \
        -relwidth 0.3 -relheight 0.4 -anchor se -in .t.f  \
        -bordermode outside
    place info .t.f2
} -result {-in .t.f -x 1 -relx 0.1 -y 2 -rely 0.2 -width 3 -relwidth 0.3 -height 4 -relheight 0.4 -anchor se -bordermode outside}
test place-1.3 {Tk_PlaceCmd procedure, "info" option} -setup {
    place forget .t.f2
    destroy .t.a.b
} -body {
    # Make sure the result is built as a proper list by using a space in parent
    frame ".t.a b"
    place .t.f2 -x 1 -y 2 -width {} -height 4 -relx 0.2 -rely 0.2 \
        -relwidth 0.3 -relheight {} -anchor w -in ".t.a b"  \
        -bordermode ignore
    place info .t.f2
} -cleanup {
    destroy ".t.a.b"

} -result {-in {.t.a b} -x 1 -relx 0.2 -y 2 -rely 0.2 -width {} -relwidth 0.3 -height 4 -relheight {} -anchor w -bordermode ignore}


test place-2.1 {ConfigureContent procedure, -height option} -body {
    place .t.f2 -height abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-2.2 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 40
    update
    winfo height .t.f2
} -result 40
test place-2.3 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 120
    update
    place .t.f2 -height {}
    update
    winfo height .t.f2
} -result 60


test place-3.1 {ConfigureContent procedure, -relheight option} -body {
    place .t.f2 -relheight abcd
} -returnCodes error -result {expected floating-point number but got "abcd"}
test place-3.2 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .5
    update
    winfo height .t.f2
} -result 40
test place-3.3 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .8
    update
    place .t.f2 -relheight {}
    update
    winfo height .t.f2
} -result 60


test place-4.1 {ConfigureContent procedure, bad -in options} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f2
} -returnCodes error -result {can't place ".t.f2" relative to itself}
test place-4.2 {ConfigureContent procedure, bad -in option} -setup {
    place forget .t.f2
} -body {
    set result [list [winfo manager .t.f2]]
    catch {place .t.f2 -in .t.f2}
    lappend result [winfo manager .t.f2]
} -result {{} {}}
test place-4.3 {ConfigureContent procedure, bad -in option} -setup {
    place forget .t.f2
} -body {
    winfo manager .t.f2
    place .t.f2 -in .t.f2
} -returnCodes error -result {can't place ".t.f2" relative to itself}
test place-4.4 {ConfigureContent procedure, bad -in option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .
} -returnCodes error -result {can't place ".t.f2" relative to "."}
test place-4.5 {ConfigureContent procedure, bad -in option} -setup {
} -body {
    frame .t.f1
    place .t.f1 -in .t.f1
} -returnCodes error -result {can't place ".t.f1" relative to itself}
test place-4.6 {prevent management loops} -setup {
    place forget .t.f1
} -body {
    place .t.f1 -in .t.f2
    place .t.f2 -in .t.f1
} -returnCodes error -result {can't put ".t.f2" inside ".t.f1": would cause management loop}
test place-4.7 {prevent management loops} -setup {
    place forget .t.f1
    place forget .t.f2
} -body {
    frame .t.f3
    place .t.f1 -in .t.f2
    place .t.f2 -in .t.f3
    place .t.f3 -in .t.f1
} -returnCodes error -result {can't put ".t.f3" inside ".t.f1": would cause management loop}

test place-5.1 {ConfigureContent procedure, -relwidth option} -body {
    place .t.f2 -relwidth abcd
} -returnCodes error -result {expected floating-point number but got "abcd"}
test place-5.2 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .5
    update
    winfo width .t.f2
} -result 75
test place-5.3 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .8
    update
    place .t.f2 -relwidth {}
    update
    winfo width .t.f2
} -result 30

test place-6.1 {ConfigureContent procedure, -width option} -body {
    place .t.f2 -width abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-6.2 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 100
    update
    winfo width .t.f2
} -result 100
test place-6.3 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 120
    update
    place .t.f2 -width {}
    update
    winfo width .t.f2
} -result 30


test place-7.1 {ReconfigurePlacement procedure, computing position} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -x -2 -relx .5 -y 3 -rely .4
    update
    winfo geometry .t.f2
} -result {30x60+123+75}
test place-7.2 {ReconfigurePlacement procedure, position rounding} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -x -1.4 -y -2.3
    update
    winfo geometry .t.f2
} -result {30x60+49+38}
test place-7.3 {ReconfigurePlacement procedure, position rounding} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -x 1.4 -y 2.3
    update
    winfo geometry .t.f2
} -result {30x60+51+42}
test place-7.4 {ReconfigurePlacement procedure, position rounding} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -x -1.6 -y -2.7
    update
    winfo geometry .t.f2
} -result {30x60+48+37}
test place-7.5 {ReconfigurePlacement procedure, position rounding} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -x 1.6 -y 2.7
    update
    winfo geometry .t.f2
} -result {30x60+52+43}
test place-7.6 {ReconfigurePlacement procedure, position rounding} -setup {
    destroy .t.f3
} -body {
    frame .t.f3 -width 100 -height 100 -bg #f00000 -bd 0
    place .t.f3 -x 0 -y 0
    raise .t.f2
    place forget .t.f2
    place .t.f2 -in .t.f3 -relx .303 -rely .406 -relwidth .304 -relheight .206
    update
    winfo geometry .t.f2
} -cleanup {
    destroy .t.f3
} -result {31x20+30+41}
test place-7.7 {ReconfigurePlacement procedure, computing size} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 120 -height 89
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} -result {120 89}
test place-7.8 {ReconfigurePlacement procedure, computing size} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .4 -relheight .5
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} -result {60 40}
test place-7.9 {ReconfigurePlacement procedure, computing size} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 10 -relwidth .4 -height -4 -relheight .5
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} -result {70 36}
test place-7.10 {ReconfigurePlacement procedure, computing size} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 10 -relwidth .4 -height -4 -relheight .5
    place .t.f2 -width {} -relwidth {} -height {} -relheight {}
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} -result {30 60}

if {[tk windowingsystem] == "win32"} {
    proc placeUpdate {} {
	update
    }
} else {
    proc placeUpdate {} {
    }
}

test place-8.1 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
} -body {
    place .t.f2 -relx 1.0 -rely 1.0 -anchor sw
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t

    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 40 30 0 1}
test place-8.2 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
    update idletasks
} -body {
    place .t.f -x 0 -y 0 -width 200 -height 100
    place .t.f2 -in .t.f -relx 1.0 -rely 1.0 -anchor sw -width 50 -height 20
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t

    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 42 32 0 1}
destroy .t


test place-9.1 {PlaceObjCmd} -body {
    place
} -returnCodes error -result {wrong # args: should be "place option|pathName args"}
test place-9.2 {PlaceObjCmd} -body {
    place foo
} -returnCodes error -result {wrong # args: should be "place option|pathName args"}
test place-9.3 {PlaceObjCmd} -setup {
    destroy .foo
} -body {
    place .foo bar
} -returnCodes error -result {bad window path name ".foo"}
test place-9.4 {PlaceObjCmd} -setup {
    destroy .foo
} -body {
    place bar .foo
} -cleanup {
    destroy .foo
} -returnCodes error -result {bad window path name ".foo"}
test place-9.5 {PlaceObjCmd} -setup {
    destroy .foo
} -body {
    frame .foo
    place badopt .foo
} -cleanup {
    destroy .foo

} -returnCodes error -result {bad option "badopt": must be configure, content, forget, or info}
test place-9.6 {PlaceObjCmd, configure errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo
} -cleanup {
    destroy .foo
} -returnCodes ok -result {}

test place-9.7 {PlaceObjCmd, configure errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo bar
} -cleanup {
    destroy .foo



} -returnCodes ok -result {}
test place-9.8 {PlaceObjCmd, configure} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo
} -cleanup {
    destroy .foo

} -result [list {-anchor {} {} nw nw} {-bordermode {} {} inside inside} {-height {} {} {} {}} {-in {} {} {} .} {-relheight {} {} {} {}} {-relwidth {} {} {} {}} {-relx {} {} 0 0.0} {-rely {} {} 0 0.0} {-width {} {} {} {}} {-x {} {} 0 0} {-y {} {} 0 0}]
test place-9.9 {PlaceObjCmd, configure} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo -x
} -cleanup {
    destroy .foo

} -result {-x {} {} 0 0}
test place-9.10 {PlaceObjCmd, forget errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place forget .foo bar
} -cleanup {
    destroy .foo

} -returnCodes error -result {wrong # args: should be "place forget pathName"}
test place-9.11 {PlaceObjCmd, info errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place info .foo bar
} -cleanup {
    destroy .foo

} -returnCodes error -result {wrong # args: should be "place info pathName"}
test place-9.12 {PlaceObjCmd, content errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place content .foo bar
} -cleanup {
    destroy .foo

} -returnCodes error -result {wrong # args: should be "place content pathName"}


test place-10.1 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -badopt
} -cleanup {
    destroy .foo

} -returnCodes error -result {unknown option "-badopt"}
test place-10.2 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -anchor
} -cleanup {
    destroy .foo

} -returnCodes error -result {value for "-anchor" missing}
test place-10.3 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -bordermode j
} -cleanup {
    destroy .foo

} -returnCodes error -result {bad bordermode "j": must be inside, outside, or ignore}
test place-10.4 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo -x 0 -y
} -cleanup {
    destroy .foo
} -returnCodes error -result {value for "-y" missing}



test place-11.1 {PlaceObjCmd, content command} -setup {
    destroy .foo
} -body {
    frame .foo
    place content .foo
} -cleanup {
    destroy .foo
} -result {}

test place-11.2 {PlaceObjCmd, content command} -setup {
    destroy .foo .bar
} -body {
    frame .foo
    frame .bar
    place .bar -in .foo
    place content .foo
} -cleanup {
    destroy .foo .bar

} -result [list .bar]


test place-12.1 {PlaceObjCmd, forget command} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -width 50 -height 50
    update
    set res [winfo ismapped .foo]
    place forget .foo
    update
    lappend res [winfo ismapped .foo]
} -cleanup {
    destroy .foo
} -result {1 0}


test place-13.1 {test respect for internalborder} -setup {
    destroy .pack
} -body {
    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    place .pack.lf.f -x 0 -y 0 -relwidth 1.0 -relheight 1.0
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
} -cleanup {
    destroy .pack

} -result {196x188+2+10 177x186+5+7}


test place-14.1 {memory leak testing} -constraints memory -setup {
    destroy .f
    proc getbytes {} {
        set lines [split [memory info] "\n"]
        lindex [lindex $lines 3] 3
    }
    # Repeat each body checking that memory does not increase
    proc stress {args} {
        set res {}
        foreach body $args {
            set end 0
            for {set i 0} {$i < 5} {incr i} {
                uplevel 1 $body
                set tmp $end
                set end [getbytes]
            }
            lappend res [expr {$end - $tmp}]
        }
        return $res
    }
} -body {
    # Test all manners of forgetting content
    frame .f
    frame .f.f
    stress {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        place forget .f.f
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        pack .f.f
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        destroy .f
        frame .f
        frame .f.f
    }
} -cleanup {
    destroy .f
    rename getbytes {}
    rename stress {}
} -result {0 0 0}




# cleanup
cleanupTests
return






|
|



<





<
|
|




<







|
<
<


|
|
<
<

|
|

|
|
<
<
<



|
|
|
<
|
>
|

<
|
|
|
|

<



|
|

<





<
|

|
|
|
|

<



|
|

<





<
|

|

<
|
|
|

<
|
|
<
<
<
<
<
|
|
<
|

<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<

|
|
|
|

<



|
|

<





|

|
|
|
|

<



|
|

<





<
|

|

<



|
|

<



|
|

<



|
|

<



|
|

<



|
|
<
<







|
|
<
|

<



|
|

<



|
|

<



|
|

<




|

<
<
<
|
<
<
<
<
<
|


<

|


>


|


|

|
|


<
<


|


>


|


|

|
<

<
|
|
|
|
|
|
|
|
<
|
|
|
|
<
|
<
<
|
|
|
<

|
<

>
|
|
|
<

|
<

|
>
|
|
<

|
<

>
>
>
<
<
|
<


|
<

>
|
|
|
<


|
<

>
|
|
|
<

|
<

>
|
|
|
<

|
<

>
|
|
|
<

|
<

>
|

<
|
|
<

|
<

>
|
|
|
<

|
<

>
|
|
|
<

|
<

>
|
|
|
<

|
<

<
|
>

|
|
<

|
<

|
>
|
|
<



|
|
|
>
|

<
|
|
<







<

|
|

|
<
<












<

>
|

<
|
<


















|
|














|



<
|
>
>




<
<
<
1
2
3
4
5
6
7
8

9
10
11
12
13

14
15
16
17
18
19

20
21
22
23
24
25
26
27


28
29
30
31


32
33
34
35
36
37



38
39
40
41
42
43

44
45
46
47

48
49
50
51
52

53
54
55
56
57
58

59
60
61
62
63

64
65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81

82
83
84
85

86
87
88
89

90
91





92
93

94
95

96










97










98
99
100
101
102
103

104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127

128
129
130
131
132

133
134
135
136

137
138
139
140
141
142

143
144
145
146
147
148

149
150
151
152
153
154

155
156
157
158
159
160

161
162
163
164
165


166
167
168
169
170
171
172
173
174

175
176

177
178
179
180
181
182

183
184
185
186
187
188

189
190
191
192
193
194

195
196
197
198
199
200



201





202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234

235

236
237
238
239
240
241
242
243

244
245
246
247

248


249
250
251

252
253

254
255
256
257
258

259
260

261
262
263
264
265

266
267

268
269
270
271


272

273
274
275

276
277
278
279
280

281
282
283

284
285
286
287
288

289
290

291
292
293
294
295

296
297

298
299
300
301
302

303
304

305
306
307
308

309
310

311
312

313
314
315
316
317

318
319

320
321
322
323
324

325
326

327
328
329
330
331

332
333

334

335
336
337
338
339

340
341

342
343
344
345
346

347
348
349
350
351
352
353
354
355

356
357

358
359
360
361
362
363
364

365
366
367
368
369


370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385

386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431



# This file is a Tcl script to test out the "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# XXX - This test file is woefully incomplete.  At present, only a
# few of the features are tested.


toplevel .t -width 300 -height 200 -bd 0
wm geom .t +0+0
frame .t.f -width 154 -height 84 -bd 2 -relief raised
place .t.f -x 48 -y 38
frame .t.f2 -width 30 -height 60 -bd 2 -relief raised
update

test place-1.1 {Tk_PlaceCmd procedure, "info" option} {


    place .t.f2 -x 0
    place info .t.f2
} {-in .t -x 0 -relx 0 -y 0 -rely 0 -width {} -relwidth {} -height {} -relheight {} -anchor nw -bordermode inside}
test place-1.2 {Tk_PlaceCmd procedure, "info" option} {


    place .t.f2 -x 1 -y 2 -width 3 -height 4 -relx 0.1 -rely 0.2 \
	    -relwidth 0.3 -relheight 0.4 -anchor se -in .t.f  \
	    -bordermode outside
    place info .t.f2
} {-in .t.f -x 1 -relx 0.1 -y 2 -rely 0.2 -width 3 -relwidth 0.3 -height 4 -relheight 0.4 -anchor se -bordermode outside}
test place-1.3 {Tk_PlaceCmd procedure, "info" option} {



    # Make sure the result is built as a proper list by using a space in parent
    frame ".t.a b"
    place .t.f2 -x 1 -y 2 -width {} -height 4 -relx 0.2 -rely 0.2 \
	    -relwidth 0.3 -relheight {} -anchor w -in ".t.a b"  \
	    -bordermode ignore
    set res [place info .t.f2]

    destroy ".t.a b"
    set res
} {-in {.t.a b} -x 1 -relx 0.2 -y 2 -rely 0.2 -width {} -relwidth 0.3 -height 4 -relheight {} -anchor w -bordermode ignore}


test place-2.1 {ConfigureSlave procedure, -height option} {
    list [catch {place .t.f2 -height abcd} msg] $msg
} {1 {bad screen distance "abcd"}}
test place-2.2 {ConfigureSlave procedure, -height option} {
    place forget .t.f2

    place .t.f2 -in .t.f -height 40
    update
    winfo height .t.f2
} {40}
test place-2.3 {ConfigureSlave procedure, -height option} {
    place forget .t.f2

    place .t.f2 -in .t.f -height 120
    update
    place .t.f2 -height {}
    update
    winfo height .t.f2

} {60}

test place-3.1 {ConfigureSlave procedure, -relheight option} {
    list [catch {place .t.f2 -relheight abcd} msg] $msg
} {1 {expected floating-point number but got "abcd"}}
test place-3.2 {ConfigureSlave procedure, -relheight option} {
    place forget .t.f2

    place .t.f2 -in .t.f -relheight .5
    update
    winfo height .t.f2
} {40}
test place-3.3 {ConfigureSlave procedure, -relheight option} {
    place forget .t.f2

    place .t.f2 -in .t.f -relheight .8
    update
    place .t.f2 -relheight {}
    update
    winfo height .t.f2

} {60}

test place-4.1 {ConfigureSlave procedure, bad -in options} {
    place forget .t.f2

    list [catch {place .t.f2 -in .t.f2} msg] $msg
} [list 1 "can't place .t.f2 relative to itself"]
test place-4.2 {ConfigureSlave procedure, bad -in option} {
    place forget .t.f2

    list [winfo manager .t.f2] \
        [catch {place .t.f2 -in .t.f2} err] $err \





        [winfo manager .t.f2]
} {{} 1 {can't place .t.f2 relative to itself} {}}

test place-4.3 {ConfigureSlave procedure, bad -in option} {
    place forget .t.f2

    list [catch {place .t.f2 -in .} msg] $msg










} [list 1 "can't place .t.f2 relative to ."]











test place-5.1 {ConfigureSlave procedure, -relwidth option} {
    list [catch {place .t.f2 -relwidth abcd} msg] $msg
} {1 {expected floating-point number but got "abcd"}}
test place-5.2 {ConfigureSlave procedure, -relwidth option} {
    place forget .t.f2

    place .t.f2 -in .t.f -relwidth .5
    update
    winfo width .t.f2
} {75}
test place-5.3 {ConfigureSlave procedure, -relwidth option} {
    place forget .t.f2

    place .t.f2 -in .t.f -relwidth .8
    update
    place .t.f2 -relwidth {}
    update
    winfo width .t.f2
} {30}

test place-6.1 {ConfigureSlave procedure, -width option} {
    list [catch {place .t.f2 -width abcd} msg] $msg
} {1 {bad screen distance "abcd"}}
test place-6.2 {ConfigureSlave procedure, -width option} {
    place forget .t.f2

    place .t.f2 -in .t.f -width 100
    update
    winfo width .t.f2
} {100}
test place-6.3 {ConfigureSlave procedure, -width option} {
    place forget .t.f2

    place .t.f2 -in .t.f -width 120
    update
    place .t.f2 -width {}
    update
    winfo width .t.f2

} {30}

test place-7.1 {ReconfigurePlacement procedure, computing position} {
    place forget .t.f2

    place .t.f2 -in .t.f -x -2 -relx .5 -y 3 -rely .4
    update
    winfo geometry .t.f2
} {30x60+123+75}
test place-7.2 {ReconfigurePlacement procedure, position rounding} {
    place forget .t.f2

    place .t.f2 -in .t.f -x -1.4 -y -2.3
    update
    winfo geometry .t.f2
} {30x60+49+38}
test place-7.3 {ReconfigurePlacement procedure, position rounding} {
    place forget .t.f2

    place .t.f2 -in .t.f -x 1.4 -y 2.3
    update
    winfo geometry .t.f2
} {30x60+51+42}
test place-7.4 {ReconfigurePlacement procedure, position rounding} {
    place forget .t.f2

    place .t.f2 -in .t.f -x -1.6 -y -2.7
    update
    winfo geometry .t.f2
} {30x60+48+37}
test place-7.5 {ReconfigurePlacement procedure, position rounding} {
    place forget .t.f2

    place .t.f2 -in .t.f -x 1.6 -y 2.7
    update
    winfo geometry .t.f2
} {30x60+52+43}
test place-7.6 {ReconfigurePlacement procedure, position rounding} {


    frame .t.f3 -width 100 -height 100 -bg #f00000 -bd 0
    place .t.f3 -x 0 -y 0
    raise .t.f2
    place forget .t.f2
    place .t.f2 -in .t.f3 -relx .303 -rely .406 -relwidth .304 -relheight .206
    update
    winfo geometry .t.f2
} {31x20+30+41}
catch {destroy .t.f3}

test place-7.7 {ReconfigurePlacement procedure, computing size} {
    place forget .t.f2

    place .t.f2 -in .t.f -width 120 -height 89
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} {120 89}
test place-7.8 {ReconfigurePlacement procedure, computing size} {
    place forget .t.f2

    place .t.f2 -in .t.f -relwidth .4 -relheight .5
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} {60 40}
test place-7.9 {ReconfigurePlacement procedure, computing size} {
    place forget .t.f2

    place .t.f2 -in .t.f -width 10 -relwidth .4 -height -4 -relheight .5
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} {70 36}
test place-7.10 {ReconfigurePlacement procedure, computing size} {
    place forget .t.f2

    place .t.f2 -in .t.f -width 10 -relwidth .4 -height -4 -relheight .5
    place .t.f2 -width {} -relwidth {} -height {} -relheight {}
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} {30 60}










test place-8.1 {MasterStructureProc, mapping and unmapping slaves} {failsOnUbuntu failsOnQuarz} {
    place forget .t.f2
    place forget .t.f

    place .t.f2 -relx 1.0 -rely 1.0 -anchor sw
    update
    set result [winfo ismapped .t.f2]
    wm iconify .t
    update
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    lappend result [winfo ismapped .t.f2]
} {1 0 40 30 0 1}
test place-8.2 {MasterStructureProc, mapping and unmapping slaves} {failsOnUbuntu failsOnQuarz} {
    place forget .t.f2
    place forget .t.f


    place .t.f -x 0 -y 0 -width 200 -height 100
    place .t.f2 -in .t.f -relx 1.0 -rely 1.0 -anchor sw -width 50 -height 20
    update
    set result [winfo ismapped .t.f2]
    wm iconify .t
    update
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    lappend result [winfo ismapped .t.f2]
} {1 0 42 32 0 1}



test place-9.1 {PlaceObjCmd} {
    list [catch {place} msg] $msg
} [list 1 "wrong # args: should be \"place option|pathName args\""]
test place-9.2 {PlaceObjCmd} {
    list [catch {place foo} msg] $msg
} [list 1 "wrong # args: should be \"place option|pathName args\""]
test place-9.3 {PlaceObjCmd} {
    catch {destroy .foo}

    list [catch {place .foo bar} msg] $msg
} [list 1 "bad window path name \".foo\""]
test place-9.4 {PlaceObjCmd} {
    catch {destroy .foo}

    list [catch {place bar .foo} msg] $msg


} [list 1 "bad window path name \".foo\""]
test place-9.5 {PlaceObjCmd} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place badopt .foo} msg] $msg]

    destroy .foo
    set res
} [list 1 "bad option \"badopt\": must be configure, forget, info, or slaves"]
test place-9.6 {PlaceObjCmd, configure errors} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place configure .foo} msg] $msg]

    destroy .foo
    set res
} [list 0 ""]
test place-9.7 {PlaceObjCmd, configure errors} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place configure .foo bar} msg] $msg]

    destroy .foo
    set res
} [list 0 ""]
test place-9.8 {PlaceObjCmd, configure} {


    catch {destroy .foo}

    frame .foo
    place .foo -x 0 -y 0
    set res [place configure .foo]

    destroy .foo
    set res
} [list {-anchor {} {} nw nw} {-bordermode {} {} inside inside} {-height {} {} {} {}} {-in {} {} {} .} {-relheight {} {} {} {}} {-relwidth {} {} {} {}} {-relx {} {} 0 0.0} {-rely {} {} 0 0.0} {-width {} {} {} {}} {-x {} {} 0 0} {-y {} {} 0 0}]
test place-9.9 {PlaceObjCmd, configure} {
    catch {destroy .foo}

    frame .foo
    place .foo -x 0 -y 0
    set res [place configure .foo -x]

    destroy .foo
    set res
} [list -x {} {} 0 0]
test place-9.10 {PlaceObjCmd, forget errors} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place forget .foo bar} msg] $msg]

    destroy .foo
    set res
} [list 1 "wrong # args: should be \"place forget pathName\""]
test place-9.11 {PlaceObjCmd, info errors} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place info .foo bar} msg] $msg]

    destroy .foo
    set res
} [list 1 "wrong # args: should be \"place info pathName\""]
test place-9.12 {PlaceObjCmd, slaves errors} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place slaves .foo bar} msg] $msg]

    destroy .foo
    set res
} [list 1 "wrong # args: should be \"place slaves pathName\""]


test place-10.1 {ConfigureSlave} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place .foo -badopt} msg] $msg]

    destroy .foo
    set res
} [list 1 "unknown option \"-badopt\""]
test place-10.2 {ConfigureSlave} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place .foo -anchor} msg] $msg]

    destroy .foo
    set res
} [list 1 "value for \"-anchor\" missing"]
test place-10.3 {ConfigureSlave} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place .foo -bordermode j} msg] $msg]

    destroy .foo
    set res
} [list 1 "bad bordermode \"j\": must be inside, outside, or ignore"]
test place-10.4 {ConfigureSlave} {
    catch {destroy .foo}

    frame .foo
    set res [list [catch {place configure .foo -x 0 -y} msg] $msg]

    destroy .foo

    set res
} [list 1 "value for \"-y\" missing"]

test place-11.1 {PlaceObjCmd, slaves command} {
    catch {destroy .foo}

    frame .foo
    set res [place slaves .foo]

    destroy .foo
    set res
} {}
test place-11.2 {PlaceObjCmd, slaves command} {
    catch {destroy .foo .bar}

    frame .foo
    frame .bar
    place .bar -in .foo
    set res [place slaves .foo]
    destroy .foo
    destroy .bar
    set res
} [list .bar]


test place-12.1 {PlaceObjCmd, forget command} {
    catch {destroy .foo}

    frame .foo
    place .foo -width 50 -height 50
    update
    set res [winfo ismapped .foo]
    place forget .foo
    update
    lappend res [winfo ismapped .foo]

    destroy .foo
    set res
} [list 1 0]

test place-13.1 {test respect for internalborder} {


    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    place .pack.lf.f -x 0 -y 0 -relwidth 1.0 -relheight 1.0
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]

    destroy .pack
    set res
} {196x188+2+10 177x186+5+7}


test place-14.1 {memory leak testing} -setup {

    proc getbytes {} {
        set lines [split [memory info] "\n"]
        lindex [lindex $lines 3] 3
    }
    # Repeat each body checking that memory does not increase
    proc stress {args} {
        set res {}
        foreach body $args {
            set end 0
            for {set i 0} {$i < 5} {incr i} {
                uplevel 1 $body
                set tmp $end
                set end [getbytes]
            }
            lappend res [expr {$end - $tmp}]
        }
        return $res
    }
} -constraints {memory failsOnQuarz} -body {
    # Test all manners of forgetting a slave
    frame .f
    frame .f.f
    stress {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        place forget .f.f
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        pack .f.f
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        destroy .f
        frame .f
        frame .f.f
    }
} -result {0 0 0} -cleanup {
    destroy .f
    rename getbytes {}
    rename stress {}

}

catch {destroy .t}

# cleanup
cleanupTests
return



Changes to tests/raise.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# This file is a Tcl script to test out Tk's "raise" and
# "lower" commands, plus associated code to manage window
# stacking order.  It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# Procedure to create a bunch of overlapping windows, which should
# make it easy to detect differences in order.

proc raise_setup {} {
    foreach i [winfo child .raise] {
	        destroy $i
        }
    foreach i {a b c d e} {
	    label .raise.$i -text $i -relief raised -bd 2
    }
    place .raise.a -x 20 -y 60 -width 60 -height 80
    place .raise.b -x 60 -y 60 -width 60 -height 80
    place .raise.c -x 100 -y 60 -width 60 -height 80
    place .raise.d -x 40 -y 20 -width 100 -height 60
    place .raise.e -x 40 -y 120 -width 100 -height 60
}





|
|
|





<






|
|

|







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file is a Tcl script to test out Tk's "raise" and
# "lower" commands, plus associated code to manage window
# stacking order.  It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1993-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


# Procedure to create a bunch of overlapping windows, which should
# make it easy to detect differences in order.

proc raise_setup {} {
    foreach i [winfo child .raise] {
	destroy $i
    }
    foreach i {a b c d e} {
	label .raise.$i -text $i -relief raised -bd 2
    }
    place .raise.a -x 20 -y 60 -width 60 -height 80
    place .raise.b -x 60 -y 60 -width 60 -height 80
    place .raise.c -x 100 -y 60 -width 60 -height 80
    place .raise.d -x 40 -y 20 -width 100 -height 60
    place .raise.e -x 40 -y 120 -width 100 -height 60
}
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
	update
    }
}

toplevel .raise
wm geom .raise 250x200+0+0


test raise-1.1 {preserve creation order} -body {
    raise_setup
    tkwait visibility .raise.e
    raise_getOrder
} -result {d d d b c e e e}
test raise-1.2 {preserve creation order} -constraints testmakeexist -body {
    raise_setup
    testmakeexist .raise.a
    update
    raise_getOrder
} -result {d d d b c e e e}
test raise-1.3 {preserve creation order} -constraints testmakeexist -body {
    raise_setup
    testmakeexist .raise.c
    update
    raise_getOrder
} -result {d d d b c e e e}
test raise-1.4 {preserve creation order} -constraints testmakeexist -body {
    raise_setup
    testmakeexist .raise.e
    update
    raise_getOrder
} -result {d d d b c e e e}
test raise-1.5 {preserve creation order} -constraints testmakeexist -body {
    raise_setup
    testmakeexist .raise.d .raise.c .raise.b
    update
    raise_getOrder
} -result {d d d b c e e e}


test raise-2.1 {raise internal windows before creation} -body {
    raise_setup
    raise .raise.a
    update
    raise_getOrder
} -result {a d d a c a e e}
test raise-2.2 {raise internal windows before creation} -body {
    raise_setup
    raise .raise.c
    update
    raise_getOrder
} -result {d d c b c e e c}
test raise-2.3 {raise internal windows before creation} -body {
    raise_setup
    raise .raise.e
    update
    raise_getOrder
} -result {d d d b c e e e}
test raise-2.4 {raise internal windows before creation} -body {
    raise_setup
    raise .raise.e .raise.a
    update
    raise_getOrder
} -result {d d d b c e b c}
test raise-2.5 {raise internal windows before creation} -body {
    raise_setup
    raise .raise.a .raise.d
    update
    raise_getOrder
} -result {a d d a c e e e}


test raise-3.1 {raise internal windows after creation} -body {
    raise_setup
    update
    raise .raise.a .raise.d
    raise_getOrder
} -result {a d d a c e e e}
test raise-3.2 {raise internal windows after creation} -constraints {
	testmakeexist
} -body {
    raise_setup
    testmakeexist .raise.a .raise.b
    raise .raise.a .raise.b
    update
    raise_getOrder
} -result {d d d a c e e e}
test raise-3.3 {raise internal windows after creation} -constraints {
	testmakeexist
} -body {
    raise_setup
    testmakeexist .raise.a .raise.d
    raise .raise.a .raise.b
    update
    raise_getOrder
} -result {d d d a c e e e}
test raise-3.4 {raise internal windows after creation} -constraints {
	testmakeexist
} -body {
    raise_setup
    testmakeexist .raise.a .raise.c .raise.d
    raise .raise.a .raise.b
    update
    raise_getOrder
} -result {d d d a c e e e}


test raise-4.1 {raise relative to nephews} -body {
    raise_setup
    update
    frame .raise.d.child
    raise .raise.a .raise.d.child
    raise_getOrder
} -result {a d d a c e e e}
test raise-4.2 {raise relative to nephews} -setup {
    destroy .raise2
} -body {
    raise_setup
    update
    frame .raise2
    raise .raise.a .raise2
} -cleanup {
    destroy .raise2
} -returnCodes error -result {can't raise ".raise.a" above ".raise2"}


test raise-5.1 {lower internal windows} -body {
    raise_setup
    update
    lower .raise.d
    raise_getOrder
} -result {a b c b c e e e}
test raise-5.2 {lower internal windows} -body {
    raise_setup
    update
    lower .raise.d .raise.b
    raise_getOrder
} -result {d b c b c e e e}
test raise-5.3 {lower internal windows} -body {
    raise_setup
    update
    lower .raise.a .raise.e
    raise_getOrder
} -result {a d d a c e e e}
test raise-5.4 {lower internal windows} -setup {
    destroy .raise2
} -body {
    raise_setup
    update
    frame .raise2
    lower .raise.a .raise2
} -cleanup {
    destroy .raise2
} -returnCodes error -result {can't lower ".raise.a" below ".raise2"}


test raise-6.1 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    update
    raise .raise1
    winfo containing [winfo rootx .raise1] [winfo rooty .raise1]
} -result {.raise1}
test raise-6.2 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    update
    raise .raise2
    winfo containing [winfo rootx .raise1] [winfo rooty .raise1]
} -result {.raise2}
test raise-6.3 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    update
    raise .raise3
    raise .raise2
    raise .raise1 .raise3
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise2
    update
    after 500
    list $result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
} -result {.raise2 .raise1}
test raise-6.4 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    update
    raise .raise2
    raise .raise1
    lower .raise3 .raise1
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    wm geometry .raise2 +30+30
    wm geometry .raise1 +60+60
    destroy .raise1
    update
    after 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} -result {.raise1 .raise3}
test raise-6.5 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}
} -result 1
test raise-6.6 {raise/lower toplevel windows} -constraints {
	nonPortable
} -body {
    raise_makeToplevels
    update
    raise .raise2
    raise .raise1
    raise .raise3
    frame .raise1.f1
    frame .raise1.f1.f2
    lower .raise3 .raise1.f1.f2
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise1
    update
    after 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} -result {.raise1 .raise3}


test raise-7.1 {errors in raise/lower commands} -body {
    raise
} -returnCodes error -result {wrong # args: should be "raise window ?aboveThis?"}
test raise-7.2 {errors in raise/lower commands} -body {
    raise a b c
} -returnCodes error -result {wrong # args: should be "raise window ?aboveThis?"}
test raise-7.3 {errors in raise/lower commands} -body {
    raise badName
} -returnCodes error -result {bad window path name "badName"}
test raise-7.4 {errors in raise/lower commands} -body {
    raise . badName2
} -returnCodes error -result {bad window path name "badName2"}
test raise-7.5 {errors in raise/lower commands} -body {
    lower
} -returnCodes error -result {wrong # args: should be "lower window ?belowThis?"}
test raise-7.6 {errors in raise/lower commands} -body {
    lower a b c
} -returnCodes error -result {wrong # args: should be "lower window ?belowThis?"}
test raise-7.7 {errors in raise/lower commands} -body {
    lower badName3
} -returnCodes error -result {bad window path name "badName3"}
test raise-7.8 {errors in raise/lower commands} -body {
    lower . badName4
} -returnCodes error -result {bad window path name "badName4"}

deleteWindows

# cleanup
cleanupTests
return








<
|



|
|




|
|




|
|




|
|




|

<
|




|
|




|
|




|
|




|
|




|

<
|




|
|
<
<





|
|
<
<





|
|
<
<





|

<
|





|
|
<
<



|
<
<
|
|

|




|
|




|
|




|
|
<
<



|
<
<
|
|

|
<
<




|
|
<
<




|
|
<
<












|
|
<
<














|
|
<
<




|
|
<
<















|

<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






<
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129


130
131
132
133
134
135
136


137
138
139
140
141
142
143


144
145
146
147
148
149
150

151
152
153
154
155
156
157
158


159
160
161
162


163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184


185
186
187
188


189
190
191
192


193
194
195
196
197
198


199
200
201
202
203
204


205
206
207
208
209
210
211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234


235
236
237
238
239
240


241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

	update
    }
}

toplevel .raise
wm geom .raise 250x200+0+0


test raise-1.1 {preserve creation order} {
    raise_setup
    tkwait visibility .raise.e
    raise_getOrder
} {d d d b c e e e}
test raise-1.2 {preserve creation order} testmakeexist {
    raise_setup
    testmakeexist .raise.a
    update
    raise_getOrder
} {d d d b c e e e}
test raise-1.3 {preserve creation order} testmakeexist {
    raise_setup
    testmakeexist .raise.c
    update
    raise_getOrder
} {d d d b c e e e}
test raise-1.4 {preserve creation order} testmakeexist {
    raise_setup
    testmakeexist .raise.e
    update
    raise_getOrder
} {d d d b c e e e}
test raise-1.5 {preserve creation order} testmakeexist {
    raise_setup
    testmakeexist .raise.d .raise.c .raise.b
    update
    raise_getOrder
} {d d d b c e e e}


test raise-2.1 {raise internal windows before creation} {
    raise_setup
    raise .raise.a
    update
    raise_getOrder
} {a d d a c a e e}
test raise-2.2 {raise internal windows before creation} {
    raise_setup
    raise .raise.c
    update
    raise_getOrder
} {d d c b c e e c}
test raise-2.3 {raise internal windows before creation} {
    raise_setup
    raise .raise.e
    update
    raise_getOrder
} {d d d b c e e e}
test raise-2.4 {raise internal windows before creation} {
    raise_setup
    raise .raise.e .raise.a
    update
    raise_getOrder
} {d d d b c e b c}
test raise-2.5 {raise internal windows before creation} {
    raise_setup
    raise .raise.a .raise.d
    update
    raise_getOrder
} {a d d a c e e e}


test raise-3.1 {raise internal windows after creation} {
    raise_setup
    update
    raise .raise.a .raise.d
    raise_getOrder
} {a d d a c e e e}
test raise-3.2 {raise internal windows after creation} testmakeexist {


    raise_setup
    testmakeexist .raise.a .raise.b
    raise .raise.a .raise.b
    update
    raise_getOrder
} {d d d a c e e e}
test raise-3.3 {raise internal windows after creation} testmakeexist {


    raise_setup
    testmakeexist .raise.a .raise.d
    raise .raise.a .raise.b
    update
    raise_getOrder
} {d d d a c e e e}
test raise-3.4 {raise internal windows after creation} testmakeexist {


    raise_setup
    testmakeexist .raise.a .raise.c .raise.d
    raise .raise.a .raise.b
    update
    raise_getOrder
} {d d d a c e e e}


test raise-4.1 {raise relative to nephews} {
    raise_setup
    update
    frame .raise.d.child
    raise .raise.a .raise.d.child
    raise_getOrder
} {a d d a c e e e}
test raise-4.2 {raise relative to nephews} {


    raise_setup
    update
    frame .raise2
    list [catch {raise .raise.a .raise2} msg] $msg


} {1 {can't raise ".raise.a" above ".raise2"}}
catch {destroy .raise2}

test raise-5.1 {lower internal windows} {
    raise_setup
    update
    lower .raise.d
    raise_getOrder
} {a b c b c e e e}
test raise-5.2 {lower internal windows} {
    raise_setup
    update
    lower .raise.d .raise.b
    raise_getOrder
} {d b c b c e e e}
test raise-5.3 {lower internal windows} {
    raise_setup
    update
    lower .raise.a .raise.e
    raise_getOrder
} {a d d a c e e e}
test raise-5.4 {lower internal windows} {


    raise_setup
    update
    frame .raise2
    list [catch {lower .raise.a .raise2} msg] $msg


} {1 {can't lower ".raise.a" below ".raise2"}}
catch {destroy .raise2}

test raise-6.1 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    update
    raise .raise1
    winfo containing [winfo rootx .raise1] [winfo rooty .raise1]
} .raise1
test raise-6.2 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    update
    raise .raise2
    winfo containing [winfo rootx .raise1] [winfo rooty .raise1]
} .raise2
test raise-6.3 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    update
    raise .raise3
    raise .raise2
    raise .raise1 .raise3
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise2
    update
    after 500
    list $result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
} {.raise2 .raise1}
test raise-6.4 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    update
    raise .raise2
    raise .raise1
    lower .raise3 .raise1
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    wm geometry .raise2 +30+30
    wm geometry .raise1 +60+60
    destroy .raise1
    update
    after 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
test raise-6.5 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}
} 1
test raise-6.6 {raise/lower toplevel windows} {nonPortable} {


    raise_makeToplevels
    update
    raise .raise2
    raise .raise1
    raise .raise3
    frame .raise1.f1
    frame .raise1.f1.f2
    lower .raise3 .raise1.f1.f2
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise1
    update
    after 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}


test raise-7.1 {errors in raise/lower commands} {
    list [catch {raise} msg] $msg
} {1 {wrong # args: should be "raise window ?aboveThis?"}}
test raise-7.2 {errors in raise/lower commands} {
    list [catch {raise a b c} msg] $msg
} {1 {wrong # args: should be "raise window ?aboveThis?"}}
test raise-7.3 {errors in raise/lower commands} {
    list [catch {raise badName} msg] $msg
} {1 {bad window path name "badName"}}
test raise-7.4 {errors in raise/lower commands} {
    list [catch {raise . badName2} msg] $msg
} {1 {bad window path name "badName2"}}
test raise-7.5 {errors in raise/lower commands} {
    list [catch {lower} msg] $msg
} {1 {wrong # args: should be "lower window ?belowThis?"}}
test raise-7.6 {errors in raise/lower commands} {
    list [catch {lower a b c} msg] $msg
} {1 {wrong # args: should be "lower window ?belowThis?"}}
test raise-7.7 {errors in raise/lower commands} {
    list [catch {lower badName3} msg] $msg
} {1 {bad window path name "badName3"}}
test raise-7.8 {errors in raise/lower commands} {
    list [catch {lower . badName4} msg] $msg
} {1 {bad window path name "badName4"}}

deleteWindows

# cleanup
cleanupTests
return

Changes to tests/safe.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the Safe Tk facility. It is organized in
# the standard fashion for Tk tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test




|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the Safe Tk facility. It is organized in
# the standard fashion for Tk tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#
# This probably means that tk wasn't installed properly.

## it indicates that something went wrong sourcing tk.tcl.
## Ensure that any changes that occurred to tk.tcl will work or are properly
## prevented in a safe interpreter.  -- hobbs

# The set of hidden commands is platform dependent:

set hidden_cmds [list bell cd clipboard encoding exec exit \
	fconfigure glob grab load menu open pwd selection \
	socket source toplevel unload wm]
if {[package vsatisfies [package provide Tcl] 8.6.7-]} {
    lappend hidden_cmds tcl:encoding:dirs
}
if {[package vsatisfies [package provide Tcl] 8.7-]} {
    lappend hidden_cmds file tcl:encoding:system tcl:file:tempdir
    foreach cmd {
	cmdtype nameofexecutable
    } {lappend hidden_cmds tcl:info:$cmd}
    foreach cmd {
	autopurge list purge status
    } {lappend hidden_cmds tcl:process:$cmd}
    foreach cmd {
	lmkimg lmkzip mkimg mkkey mkzip mount  mount_data unmount
    } {lappend hidden_cmds tcl:zipfs:$cmd}
}
foreach cmd {
    atime attributes copy delete dirname executable exists extension
    isdirectory isfile link lstat mkdir mtime nativename normalize
    owned readable readlink rename rootname size stat tail tempfile
    type volumes writable
} {lappend hidden_cmds tcl:file:$cmd}
if {[tk windowingsystem] ne "x11"} {
    lappend hidden_cmds tk_chooseColor tk_chooseDirectory \
	tk_getOpenFile tk_getSaveFile tk_messageBox
}
if {[llength [info commands send]]} {
    lappend hidden_cmds send
}

set saveAutoPath $::auto_path
set auto_path [list [info library] $::tk_library]
set hidden_cmds [lsort $hidden_cmds]

test safe-1.1 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::loadTk [safe::interpCreate a]
    safe::interpDelete a
    set x {}
    return $x
} -result {}
test safe-1.2 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    lsort [interp hidden a]
} -cleanup {
    safe::interpDelete a
} -result $hidden_cmds
test safe-1.3 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    lsort [interp aliases a]
} -cleanup {
    safe::interpDelete a
} -match glob -result {*encoding*exit*glob*load*source*}

test safe-2.1 {Unsafe commands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {toplevel .t}} msg]} {
	set status ok
    }
    return $status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-2.2 {Unsafe commands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {menu .m}} msg]} {
	set status ok
    }
    return $status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-2.3 {Unsafe subcommands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
|






|









|








|










|












|







27
28
29
30
31
32
33


































34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#
# This probably means that tk wasn't installed properly.

## it indicates that something went wrong sourcing tk.tcl.
## Ensure that any changes that occurred to tk.tcl will work or are properly
## prevented in a safe interpreter.  -- hobbs



































set saveAutoPath $::auto_path
set auto_path [list [info library] $::tk_library]


test safe-1.1 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::loadTk [safe::interpCreate a]
    safe::interpDelete a
    set x {}
    set x
} -result {}
test safe-1.2 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    lsort [interp hidden a]
} -cleanup {
    safe::interpDelete a
} -match glob -result {bell cd clipboard encoding exec exit fconfigure*glob grab load menu open pwd selection*socket source*toplevel unload wm}
test safe-1.3 {Safe Tk loading into an interpreter} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    lsort [interp aliases a]
} -cleanup {
    safe::interpDelete a
} -match glob -result {*encoding*exit*load*source*}

test safe-2.1 {Unsafe commands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {toplevel .t}} msg]} {
	set status ok
    }
    set status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-2.2 {Unsafe commands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {menu .m}} msg]} {
	set status ok
    }
    set status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-2.3 {Unsafe subcommands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok
    if {[catch {interp invokehidden a toplevel .t} msg]} {
	set status broken
    }
    return $status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-3.2 {Unsafe commands are available hidden} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok
    if {[catch {interp invokehidden a menu .m} msg]} {
	set status broken
    }
    return $status
} -cleanup {
    safe::interpDelete a
} -result ok

test safe-4.1 {testing loadTk} -body {
    # no error shall occur, the user will eventually see a new toplevel
    set i [safe::loadTk [safe::interpCreate]]







|












|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok
    if {[catch {interp invokehidden a toplevel .t} msg]} {
	set status broken
    }
    set status
} -cleanup {
    safe::interpDelete a
} -result ok
test safe-3.2 {Unsafe commands are available hidden} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok
    if {[catch {interp invokehidden a menu .m} msg]} {
	set status broken
    }
    set status
} -cleanup {
    safe::interpDelete a
} -result ok

test safe-4.1 {testing loadTk} -body {
    # no error shall occur, the user will eventually see a new toplevel
    set i [safe::loadTk [safe::interpCreate]]
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
} -result {}

test safe-5.1 {loading Tk in safe interps without parent's clearance} -body {
    set i [safe::interpCreate]
    interp eval $i {load {} Tk}
} -cleanup {
    safe::interpDelete $i
} -returnCodes error -match glob -result {*not allowed}
test safe-5.2 {multi-level Tk loading with clearance} -setup {
    set safeParent [safe::interpCreate]
} -body {
    # No error shall occur in that test and no window shall remain at the end.
    set i [safe::interpCreate [list $safeParent x]]
    safe::loadTk $i
    interp eval $i {







|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
} -result {}

test safe-5.1 {loading Tk in safe interps without parent's clearance} -body {
    set i [safe::interpCreate]
    interp eval $i {load {} Tk}
} -cleanup {
    safe::interpDelete $i
} -returnCodes error -match glob -result {*not allowed*}
test safe-5.2 {multi-level Tk loading with clearance} -setup {
    set safeParent [safe::interpCreate]
} -body {
    # No error shall occur in that test and no window shall remain at the end.
    set i [safe::interpCreate [list $safeParent x]]
    safe::loadTk $i
    interp eval $i {
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
} -result {conflicting -display :23.56 and -use }

test safe-7.1 {canvas printing} -body {
    set i [safe::loadTk [safe::interpCreate]]
    interp eval $i {canvas .c; .c postscript}
} -cleanup {
    safe::interpDelete $i
} -returnCodes ok -match glob -result *

# cleanup
set ::auto_path $saveAutoPath
unset hidden_cmds
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|



<







210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
} -result {conflicting -display :23.56 and -use }

test safe-7.1 {canvas printing} -body {
    set i [safe::loadTk [safe::interpCreate]]
    interp eval $i {canvas .c; .c postscript}
} -cleanup {
    safe::interpDelete $i
} -match glob -result *

# cleanup
set ::auto_path $saveAutoPath

cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Deleted tests/safePrimarySelection.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# ------------------------------------------------------------------------------
# Tests that a Safe Base interpreter cannot write to the PRIMARY selection.
# ------------------------------------------------------------------------------
# - Tests 3.*, 6.* test that the fix for ticket de156e9efe implemented in branch
#   bug-de156e9efe has been applied and still works.  They test that a Safe Base
#   child interpreter cannot write to the PRIMARY selection.
# - The other tests verify that the parent interpreter and an child interpreter
#   CAN write to the PRIMARY selection, and therefore that the test scripts
#   themselves are valid.
# - A text, entry, ttk::entry, listbox, spinbox or ttk::spinbox widget can have
#   option -exportselection 1, meaning (in an unsafe interpreter) that a
#   selection made in one of these widgets is automatically written to the
#   PRIMARY selection.
# - A safe interpreter must not write to the PRIMARY selection.
# - The spinbox, ttk::spinbox are variants of entry, ttk::entry respectively.
# ------------------------------------------------------------------------------

namespace eval ::_test_tmp {}

# ------------------------------------------------------------------------------
#  Proc ::_test_tmp::unsafeInterp
# ------------------------------------------------------------------------------
# Command that creates an child interpreter and tries to load Tk.
# - This is necessary for loading Tk if the tests are done in the build
#   directory without installing Tk.  In that case the usual auto_path loading
#   mechanism cannot work because the tk binary is not where pkgIndex.tcl says
#   it is.
# - This command is not needed for Safe Base children because safe::loadTk does
#   something similar and works correctly.
# - Based on scripts in winSend.test.
# ------------------------------------------------------------------------------

namespace eval ::_test_tmp {
    variable TkLoadCmd
}

foreach pkg [info loaded] {
    if {[lindex $pkg 1] eq "Tk"} {
	set ::_test_tmp::TkLoadCmd [list load {*}$pkg]
	break
    }
}

proc ::_test_tmp::unsafeInterp {name} {
    variable TkLoadCmd
    interp create $name
    $name eval [list set argv [list -name $name]]
    catch {{*}$TkLoadCmd $name}
}


set ::_test_tmp::script {
    package require Tk
    namespace eval ::_test_tmp {}

    proc ::_test_tmp::getPrimarySelection {} {
        if {[catch {::tk::GetSelection . PRIMARY} sel]} {
            set sel {}
        }
        return $sel
    }

    proc ::_test_tmp::setPrimarySelection {} {
        destroy .preset
        text .preset -exportselection 1
        .preset insert end OLD_VALUE
        # pack .preset
        .preset tag add sel 1.0 end-1c
        update
        return
    }

    # Clearing the PRIMARY selection is troublesome.
    # The window need not be mapped.
    # However, the window must continue to exist, or some X11 servers
    # will set the PRIMARY selection to something else.
    proc ::_test_tmp::clearPrimarySelection {} {
        destroy .clear
        text .clear -exportselection 1
        .clear insert end TMP_VALUE
        # pack .clear
        .clear tag add sel 1.0 end-1c
        update
        .clear tag remove sel 1.0 end-1c
        update
        return
    }

    # If this interpreter can write to the PRIMARY
    # selection, the commands below will do so.

    proc ::_test_tmp::tryText {} {
        text .t -exportselection 1
        .t insert end PAYLOAD
        pack .t
        .t tag add sel 1.0 end-1c
        update
        return
    }

    proc ::_test_tmp::tryEntry {} {
        entry .t -exportselection 1
        .t insert end PAYLOAD
        pack .t
        .t selection range 0 end
        update
        return
    }

    proc ::_test_tmp::tryTtkEntry {} {
        ::ttk::entry .t -exportselection 1
        .t insert end PAYLOAD
        pack .t
        .t selection range 0 end
        update
        return
    }

    proc ::_test_tmp::tryListbox {} {
        listbox .t -exportselection 1
        .t insert end list1 PAYLOAD list3
        pack .t
        .t selection set 1
        update
        return
    }

    proc ::_test_tmp::trySpinbox {ver} {
        if {$ver == 1} {
            # spinbox as entry
            spinbox .t -exportselection 1 -values {1 2 3 4 5}
            .t delete 0 end
            .t insert end PAYLOAD
            pack .t
            .t selection range 0 end
            update
            return
            # selects PAYLOAD
        } elseif {$ver == 2} {
            # spinbox spun
            spinbox .t -exportselection 1 -values {1 2 3 4 5}
            .t invoke buttonup
            pack .t
            .t selection range 0 end
            update
            return
            # selects 2
        } else {
            # spinbox spun/selected/spun
            spinbox .t -exportselection 1 -values {1 2 3 4 5}
            .t invoke buttonup
            pack .t
            .t selection range 0 end
            update
            .t invoke buttonup
            update
            return
            # selects 3
        }
    }

    proc ::_test_tmp::tryTtkSpinbox {ver} {
        if {$ver == 1} {
            # ttk::spinbox as entry
            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
            .t delete 0 end
            .t insert end PAYLOAD
            pack .t
            .t selection range 0 end
            update
            return
        } elseif {$ver == 2} {
            # ttk::spinbox spun
            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
            ::ttk::spinbox::Spin .t +1
            ::ttk::spinbox::Spin .t +1
            pack .t
            # ttk::spinbox::Spin sets selection
            update
            return
            # selects 2
        } else {
            # ttk::spinbox spun/selected/spun
            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
            ::ttk::spinbox::Spin .t +1
            ::ttk::spinbox::Spin .t +1
            pack .t
            # ttk::spinbox::Spin sets selection
            update
            ::ttk::spinbox::Spin .t +1
            update
            return
            # selects 3
        }
    }
}

# Do this once for the parent interpreter.
eval $::_test_tmp::script

test safePrimarySelection-1.1 {parent interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryText
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.2 {parent interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.3 {parent interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.4 {parent interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryListbox
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.5 {parent interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.6 {parent interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-1.7 {parent interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-1.8 {parent interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.9 {parent interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-1.10 {parent interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-2.1 {child interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.2 {child interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.3 {child interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.4 {child interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.5 {child interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.6 {child interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-2.7 {child interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-2.8 {child interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.9 {child interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-2.10 {child interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-3.1 {IMPORTANT, safe interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.2 {IMPORTANT, safe interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.3 {IMPORTANT, safe interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.4 {IMPORTANT, safe interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.5 {IMPORTANT, safe interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.6 {IMPORTANT, safe interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.7 {IMPORTANT, safe interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.8 {IMPORTANT, safe interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.9 {IMPORTANT, safe interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.10 {IMPORTANT, safe interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-4.1 {parent interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryText
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.2 {parent interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.3 {parent interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.4 {parent interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryListbox
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.5 {parent interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.6 {parent interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-4.7 {parent interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-4.8 {parent interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.9 {parent interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-4.10 {parent interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-5.1 {child interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.2 {child interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.3 {child interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.4 {child interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.5 {child interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.6 {child interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-5.7 {child interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-5.8 {child interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.9 {child interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-5.10 {child interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-6.1 {IMPORTANT, safe interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.2 {IMPORTANT, safe interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.3 {IMPORTANT, safe interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.4 {IMPORTANT, safe interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.5 {IMPORTANT, safe interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.6 {IMPORTANT, safe interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.7 {IMPORTANT, safe interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.8 {IMPORTANT, safe interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.9 {IMPORTANT, safe interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.10 {IMPORTANT, safe interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}


namespace delete ::_test_tmp

# option clear
# cleanup
cleanupTests
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to tests/scale.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223






224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375




376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951













952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055

1056
1057




1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311


1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357

1358
1359
1360
1361
1362
1363
1364
1365




1366
1367
1368
1369
1370
1371

1372
1373
1374
1375

1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386




1387
1388
1389
1390
1391
1392

1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
# This file is a Tcl script to test out the "scale" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Scale.borderWidth 2
option add *Scale.highlightThickness 2
option add *Scale.font {Helvetica -12 bold}

# Widget used in 1.* tests
scale .s -from 100 -to 300
pack .s
update

test scale-1.1 {configuration options} -body {
    .s configure -activebackground #ff0000
    .s cget -activebackground
} -cleanup {
    .s configure -activebackground [lindex [.s configure -activebackground] 3]
} -result {#ff0000}
test scale-1.2 {configuration options} -body {
        .s configure -activebackground non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test scale-1.3 {configuration options} -body {
    .s configure -background #ff0000
    .s cget -background
} -cleanup {
    .s configure -background [lindex [.s configure -background] 3]
} -result {#ff0000}
test scale-1.4 {configuration options} -body {
        .s configure -background non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test scale-1.5 {configuration options} -body {
    .s configure -bd 4
    .s cget -bd
} -cleanup {
    .s configure -bd [lindex [.s configure -bd] 3]
} -result 4
test scale-1.6 {configuration options} -body {
        .s configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.7 {configuration options} -body {
    .s configure -bigincrement 12.5
    .s cget -bigincrement
} -cleanup {
    .s configure -bigincrement [lindex [.s configure -bigincrement] 3]
} -result {12.5}
test scale-1.8 {configuration options} -body {
        .s configure -bigincrement badValue
} -returnCodes error -result {expected floating-point number but got "badValue"}
test scale-1.9 {configuration options} -body {
    .s configure -bg #ff0000
    .s cget -bg
} -cleanup {
    .s configure -bg [lindex [.s configure -bg] 3]
} -result {#ff0000}
test scale-1.10 {configuration options} -body {
        .s configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test scale-1.11 {configuration options} -body {
    .s configure -borderwidth 1.3
    .s cget -borderwidth
} -cleanup {
    .s configure -borderwidth [lindex [.s configure -borderwidth] 3]
} -result 1
test scale-1.12 {configuration options} -body {
        .s configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.13 {configuration options} -body {
    .s configure -command {set x}
    .s cget -command
} -cleanup {
    .s configure -command [lindex [.s configure -command] 3]
} -result {set x}
test scale-1.15 {configuration options} -body {
    .s configure -cursor arrow
    .s cget -cursor
} -cleanup {
    .s configure -cursor [lindex [.s configure -cursor] 3]
} -result {arrow}
test scale-1.16 {configuration options} -body {
        .s configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test scale-1.17 {configuration options} -body {
    .s configure -digits 5
    .s cget -digits
} -cleanup {
    .s configure -digits [lindex [.s configure -digits] 3]
} -result 5
test scale-1.18 {configuration options} -body {
        .s configure -digits badValue
} -returnCodes error -result {expected integer but got "badValue"}
test scale-1.19 {configuration options} -body {
    .s configure -fg #00ff00
    .s cget -fg
} -cleanup {
    .s configure -fg [lindex [.s configure -fg] 3]
} -result {#00ff00}
test scale-1.20 {configuration options} -body {
        .s configure -fg badValue
} -returnCodes error -result {unknown color name "badValue"}
test scale-1.21 {configuration options} -body {
    .s configure -font fixed
    .s cget -font
} -cleanup {
    .s configure -font [lindex [.s configure -font] 3]
} -result {fixed}
test scale-1.23 {configuration options} -body {
    .s configure -foreground green
    .s cget -foreground
} -cleanup {
    .s configure -foreground [lindex [.s configure -foreground] 3]
} -result {green}
test scale-1.24 {configuration options} -body {
        .s configure -foreground badValue
} -returnCodes error -result {unknown color name "badValue"}
test scale-1.25 {configuration options} -body {
    .s configure -from -15.0
    .s cget -from
} -cleanup {
    .s configure -from [lindex [.s configure -from] 3]
} -result {-15.0}
test scale-1.26 {configuration options} -body {
        .s configure -from badValue
} -returnCodes error -result {expected floating-point number but got "badValue"}
test scale-1.27 {configuration options} -body {
    .s configure -highlightbackground #112233
    .s cget -highlightbackground
} -cleanup {
    .s configure -highlightbackground [lindex [.s configure -highlightbackground] 3]
} -result {#112233}
test scale-1.28 {configuration options} -body {
        .s configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test scale-1.29 {configuration options} -body {
    .s configure -highlightcolor #123456
    .s cget -highlightcolor
} -cleanup {
    .s configure -highlightcolor [lindex [.s configure -highlightcolor] 3]
} -result {#123456}
test scale-1.30 {configuration options} -body {
        .s configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test scale-1.31 {configuration options} -body {
    .s configure -highlightthickness 2
    .s cget -highlightthickness
} -cleanup {
    .s configure -highlightthickness [lindex [.s configure -highlightthickness] 3]
} -result 2
test scale-1.32 {configuration options} -body {
        .s configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.33 {configuration options} -body {
    .s configure -label {Some text}
    .s cget -label
} -cleanup {
    .s configure -label [lindex [.s configure -label] 3]
} -result {Some text}
test scale-1.35 {configuration options} -body {
    .s configure -length 130
    .s cget -length
} -cleanup {
    .s configure -length [lindex [.s configure -length] 3]
} -result 130
test scale-1.36 {configuration options} -body {
        .s configure -length badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.37 {configuration options} -body {
    .s configure -orient horizontal
    .s cget -orient
} -cleanup {
    .s configure -orient [lindex [.s configure -orient] 3]
} -result {horizontal}
test scale-1.38 {configuration options} -body {
        .s configure -orient badValue
} -returnCodes error -result {bad orient "badValue": must be horizontal or vertical}
test scale-1.39 {configuration options} -body {
    .s configure -orient horizontal
    .s cget -orient
} -cleanup {
    .s configure -orient [lindex [.s configure -orient] 3]
} -result {horizontal}
test scale-1.41 {configuration options} -body {
    .s configure -relief ridge
    .s cget -relief
} -cleanup {
    .s configure -relief [lindex [.s configure -relief] 3]
} -result {ridge}
test scale-1.42 {configuration options} -body {
        .s configure -relief badValue
} -returnCodes error -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test scale-1.43 {configuration options} -body {
    .s configure -repeatdelay 14
    .s cget -repeatdelay
} -cleanup {
    .s configure -repeatdelay [lindex [.s configure -repeatdelay] 3]
} -result 14
test scale-1.44 {configuration options} -body {
        .s configure -repeatdelay bogus
} -returnCodes error -result {expected integer but got "bogus"}
test scale-1.45 {configuration options} -body {
    .s configure -repeatinterval 14
    .s cget -repeatinterval
} -cleanup {
    .s configure -repeatinterval [lindex [.s configure -repeatinterval] 3]
} -result 14
test scale-1.46 {configuration options} -body {
        .s configure -repeatinterval bogus
} -returnCodes error -result {expected integer but got "bogus"}
test scale-1.47 {configuration options} -body {
    .s configure -resolution 2.0
    .s cget -resolution






} -cleanup {
    .s configure -resolution [lindex [.s configure -resolution] 3]
} -result {2.0}
test scale-1.48 {configuration options} -body {
        .s configure -resolution badValue
} -returnCodes error -result {expected floating-point number but got "badValue"}
test scale-1.49 {configuration options} -body {
    .s configure -showvalue 0
    .s cget -showvalue
} -cleanup {
    .s configure -showvalue [lindex [.s configure -showvalue] 3]
} -result 0
test scale-1.50 {configuration options} -body {
        .s configure -showvalue badValue
} -returnCodes error -result {expected boolean value but got "badValue"}
test scale-1.51 {configuration options} -body {
    .s configure -sliderlength 86
    .s cget -sliderlength


} -cleanup {
    .s configure -sliderlength [lindex [.s configure -sliderlength] 3]
} -result 86
test scale-1.52 {configuration options} -body {
        .s configure -sliderlength badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.53 {configuration options} -body {
    .s configure -sliderrelief raised
    .s cget -sliderrelief
} -cleanup {
    .s configure -sliderrelief [lindex [.s configure -sliderrelief] 3]
} -result {raised}
test scale-1.54 {configuration options} -body {
        .s configure -sliderrelief badValue
} -returnCodes error -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test scale-1.55 {configuration options} -body {
    .s configure -state d
    .s cget -state
} -cleanup {
    .s configure -state [lindex [.s configure -state] 3]
} -result {disabled}
test scale-1.56 {configuration options} -body {
        .s configure -state badValue
} -returnCodes error -result {bad state "badValue": must be active, disabled, or normal}
test scale-1.57 {configuration options} -body {
    .s configure -state n
    .s cget -state
} -cleanup {
    .s configure -state [lindex [.s configure -state] 3]
} -result {normal}
test scale-1.59 {configuration options} -body {
    .s configure -takefocus {any string}
    .s cget -takefocus
} -cleanup {
    .s configure -takefocus [lindex [.s configure -takefocus] 3]
} -result {any string}
test scale-1.61 {configuration options} -body {
    .s configure -tickinterval 4.3
    .s cget -tickinterval
} -cleanup {
    .s configure -tickinterval [lindex [.s configure -tickinterval] 3]
} -result {4.0}
test scale-1.62 {configuration options} -body {
        .s configure -tickinterval badValue
} -returnCodes error -result {expected floating-point number but got "badValue"}
test scale-1.63 {configuration options} -body {

    .s configure -to 14.9
    .s cget -to
} -cleanup {
    .s configure -to [lindex [.s configure -to] 3]
} -result {15.0}
test scale-1.64 {configuration options} -body {
        .s configure -to badValue
} -returnCodes error -result {expected floating-point number but got "badValue"}
test scale-1.65 {configuration options} -body {
    .s configure -troughcolor #ff0000

    .s cget -troughcolor
} -cleanup {
    .s configure -troughcolor [lindex [.s configure -troughcolor] 3]
} -result {#ff0000}
test scale-1.66 {configuration options} -body {
        .s configure -troughcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test scale-1.67 {configuration options} -body {
    .s configure -variable x
    .s cget -variable
} -cleanup {
    .s configure -variable [lindex [.s configure -variable] 3]
} -result {x}
test scale-1.69 {configuration options} -body {
    .s configure -width 32
    .s cget -width
} -cleanup {
    .s configure -width [lindex [.s configure -width] 3]
} -result 32
test scale-1.70 {configuration options} -body {
        .s configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .s


test scale-2.1 {Tk_ScaleCmd procedure} -body {
    scale
} -returnCodes error -result {wrong # args: should be "scale pathName ?-option value ...?"}
test scale-2.2 {Tk_ScaleCmd procedure} -body {
    scale foo
} -returnCodes error -result {bad window path name "foo"}
test scale-2.3 {Tk_ScaleCmd procedure} -body {
    catch {scale foo}
    winfo child .
} -result {}
test scale-2.4 {Tk_ScaleCmd procedure} -body {
    scale .s -gorp dumb
} -returnCodes error -result {unknown option "-gorp"}
test scale-2.5 {Tk_ScaleCmd procedure} -body {
    catch {scale .s -gorp dumb}
    winfo child .
} -result {}


# Widget used in 3.* tests
destroy .s
scale .s -from 100 -to 200
pack .s
update idletasks
test scale-3.1 {ScaleWidgetCmd procedure} -body {
    .s
} -returnCodes error -result {wrong # args: should be ".s option ?arg ...?"}
test scale-3.2 {ScaleWidgetCmd procedure, cget option} -body {
    .s cget
} -returnCodes error -result {wrong # args: should be ".s cget option"}
test scale-3.3 {ScaleWidgetCmd procedure, cget option} -body {
    .s cget a b
} -returnCodes error -result {wrong # args: should be ".s cget option"}
test scale-3.4 {ScaleWidgetCmd procedure, cget option} -body {
    .s cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test scale-3.5 {ScaleWidgetCmd procedure, cget option} -body {
    .s configure -highlightthickness 2
    .s cget -highlightthickness
} -result 2
test scale-3.6 {ScaleWidgetCmd procedure, configure option} -body {
    list [llength [.s configure]] [lindex [.s configure] 6]
} -result {33 {-command command Command {} {}}}
test scale-3.7 {ScaleWidgetCmd procedure, configure option} -body {
    .s configure -foo
} -returnCodes error -result {unknown option "-foo"}
test scale-3.8 {ScaleWidgetCmd procedure, configure option} -body {
    .s configure -borderwidth 2 -bg
} -returnCodes error -result {value for "-bg" missing}
test scale-3.9 {ScaleWidgetCmd procedure, coords option} -body {
    .s coords a b
} -returnCodes error -result {wrong # args: should be ".s coords ?value?"}
test scale-3.10 {ScaleWidgetCmd procedure, coords option} -body {




    .s coords bad
} -returnCodes error -result {expected floating-point number but got "bad"}
test scale-3.11 {ScaleWidgetCmd procedure} -constraints {
	fonts
} -body {
    .s configure -from 100 -to 200
    update idletasks
    .s set 120
    .s coords
} -result {38 34}
test scale-3.12 {ScaleWidgetCmd procedure, coords option} -constraints {
	fonts
} -body {
    .s configure -from 100 -to 200 -orient horizontal
    update idletasks
    .s set 120
    .s coords
} -result {34 31}
test scale-3.13 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical
    update
    .s get a
} -returnCodes error -result {wrong # args: should be ".s get ?x y?"}
test scale-3.14 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical
    update
    .s get a b c
} -returnCodes error -result {wrong # args: should be ".s get ?x y?"}
test scale-3.15 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical
    update







    .s get a 11
} -returnCodes error -result {expected integer but got "a"}
test scale-3.16 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical
    update
    .s get 12 b
} -returnCodes error -result {expected integer but got "b"}
test scale-3.17 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical
    update
    .s set 133
    .s get
} -result 133
test scale-3.18 {ScaleWidgetCmd procedure, get option} -body {
    .s configure -orient vertical -resolution 0.5
    update
    .s set 150
    .s get 37 34
} -result {119.5}
.s configure -resolution 1
test scale-3.19 {ScaleWidgetCmd procedure, identify option} -body {
    .s identify
} -returnCodes error -result {wrong # args: should be ".s identify x y"}
test scale-3.20 {ScaleWidgetCmd procedure, identify option} -body {
    .s identify 1 2 3
} -returnCodes error -result {wrong # args: should be ".s identify x y"}
test scale-3.21 {ScaleWidgetCmd procedure, identify option} -body {
    .s identify boo 16
} -returnCodes error -result {expected integer but got "boo"}
test scale-3.22 {ScaleWidgetCmd procedure, identify option} -body {
    .s identify 17 bad
} -returnCodes error -result {expected integer but got "bad"}
test scale-3.23 {ScaleWidgetCmd procedure, identify option} -constraints {
	fonts
} -body {
    .s configure -from 100 -to 200 -orient vertical -resolution 1
    update
    .s set 120
    list [.s identify 35 10] [.s identify 35 30] [.s identify 35 80] [.s identify 5 80]
} -result {trough1 slider trough2 {}}
test scale-3.24 {ScaleWidgetCmd procedure, set option} -body {
    .s set
} -returnCodes error -result {wrong # args: should be ".s set value"}
test scale-3.25 {ScaleWidgetCmd procedure, set option} -body {
    .s set a b
} -returnCodes error -result {wrong # args: should be ".s set value"}
test scale-3.26 {ScaleWidgetCmd procedure, set option} -body {
    .s set bad
} -returnCodes error -result {expected floating-point number but got "bad"}
test scale-3.27 {ScaleWidgetCmd procedure, set option} -body {
    .s configure -from 100 -to 200 -orient vertical -resolution 0.5
    update
    .s set 142
} -result {}
test scale-3.28 {ScaleWidgetCmd procedure, set option} -body {
    .s configure -from 100 -to 200 -orient vertical -resolution 1
    update
    .s set 118
    .s configure -state disabled
    .s set 181
    .s configure -state normal
    .s get
} -result 118
test scale-3.29 {ScaleWidgetCmd procedure} -body {
    .s dumb
} -returnCodes error -result {bad option "dumb": must be cget, configure, coords, get, identify, or set}
test scale-3.30 {ScaleWidgetCmd procedure} -body {
    .s c
} -returnCodes error -result {ambiguous option "c": must be cget, configure, coords, get, identify, or set}
test scale-3.31 {ScaleWidgetCmd procedure} -body {
    .s co
} -returnCodes error -result {ambiguous option "co": must be cget, configure, coords, get, identify, or set}
destroy .s

test scale-3.32 {ScaleWidgetCmd procedure, Tk_Preserve} -setup {
    destroy .s
} -body {
    proc kill args {
	    destroy .s
    }

    scale .s -variable x -from 0 -to 100 -orient horizontal
    pack .s
    update
    .s configure -command kill
    .s set 55
} -cleanup {
    destroy .s
} -result {}


test scale-4.1 {DestroyScale procedure} -setup {
    deleteWindows
} -body {
    set x 50
    scale .s -variable x -from 0 -to 100 -orient horizontal
    pack .s
    update
    destroy .s
    list [catch {set x foo} msg] $msg $x
} -result {0 foo foo}


test scale-5.1 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    set x 66
    set y 77
    scale .s -variable x -from 0 -to 100
    pack .s
    update
    .s configure -variable y
    list [catch {set x foo} msg] $msg $x [.s get]
} -cleanup {
    deleteWindows
} -result {0 foo foo 77}
test scale-5.2 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100
    .s configure -foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-foo"}
test scale-5.3 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    catch {unset x}
    scale .s -from 0 -to 100 -variable x
    set result $x
    lappend result [.s get]
    set x 92
    lappend result [.s get]
    .s set 3
    lappend result $x
    unset x
    lappend result [set x]
} -cleanup {
    deleteWindows
} -result {0 0 92 3 3}
test scale-5.4 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100
    .s configure -orient dumb
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad orient "dumb": must be horizontal or vertical}
test scale-5.5 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 1.11 -to 1.89 -resolution .1 -tickinterval .76
    list [format %.1f [.s cget -from]] [format %.1f [.s cget -to]] \
        [format %.1f [.s cget -tickinterval]]
} -cleanup {
    deleteWindows
} -result {1.1 1.9 0.8}
test scale-5.6 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 1 -to 10 -tickinterval -2
    pack .s
    set result [lindex [.s configure -tickinterval] 4]
    .s configure -from 10 -to 1 -tickinterval 2
    lappend result [lindex [.s configure -tickinterval] 4]
} -cleanup {
    deleteWindows
} -result {2.0 -2.0}
test scale-5.7 {ConfigureScale procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -state bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad state "bogus": must be active, disabled, or normal}


# Widget used in 6.* tests
destroy .s
scale .s -orient horizontal -length 200
pack .s
test scale-6.1 {ComputeFormat procedure} -body {
    .s configure -from 10 -to 100 -resolution 10
    .s set 49.3
    .s get
} -result 50
test scale-6.2 {ComputeFormat procedure} -body {
    .s configure -from 100 -to 1000 -resolution 100
    .s set 493
    .s get
} -result 500
test scale-6.3 {ComputeFormat procedure} -body {
    .s configure -from 1000 -to 10000 -resolution 1000
    .s set 4930
    .s get
} -result 5000
test scale-6.4 {ComputeFormat procedure} -body {
    .s configure -from 10000 -to 100000 -resolution 10000
    .s set 49000
    .s get
} -result 50000
test scale-6.5 {ComputeFormat procedure} -body {
    .s configure -from 100000 -to 1000000 -resolution 100000
    .s set 493000
    .s get
} -result 500000
test scale-6.6 {ComputeFormat procedure} -constraints {
	nonPortable
} -body {
    # This test is non-portable because some platforms format the
    # result as 5e+06.

    .s configure -from 1000000 -to 10000000 -resolution 1000000
    .s set 4930000
    .s get
} -result 5000000
test scale-6.7 {ComputeFormat procedure} -body {
    .s configure -from 1000000000 -to 10000000000 -resolution 1000000000
    .s set 4930000000
    expr {[.s get] == 5.0e+09}
} -result 1
test scale-6.8 {ComputeFormat procedure} -body {
    .s configure -from .1 -to 1 -resolution .1
    .s set .6
    .s get
} -result {0.6}
test scale-6.9 {ComputeFormat procedure} -body {
    .s configure -from .01 -to .1 -resolution .01
    .s set .06
    .s get
} -result {0.06}
test scale-6.10 {ComputeFormat procedure} -body {
    .s configure -from .001 -to .01 -resolution .001
    .s set .006
    .s get
} -result {0.006}
test scale-6.11 {ComputeFormat procedure} -body {
    .s configure -from .0001 -to .001 -resolution .0001
    .s set .0006
    .s get
} -result {0.0006}
test scale-6.12 {ComputeFormat procedure} -body {
    .s configure -from .00001 -to .0001 -resolution .00001
    .s set .00006
    .s get
} -result {0.00006}
test scale-6.13 {ComputeFormat procedure} -body {
    .s configure -from .000001 -to .00001 -resolution .000001
    .s set .000006
    expr {[.s get] == 6.0e-06}
} -result 1
test scale-6.14 {ComputeFormat procedure} -body {
    .s configure -to .00001 -from .0001 -resolution .00001
    .s set .00006
    .s get
} -result {0.00006}
test scale-6.15 {ComputeFormat procedure} -body {
    .s configure -to .000001 -from .00001 -resolution .000001
    .s set .000006
    expr {[.s get] == 6.0e-06}
} -result 1
test scale-6.16 {ComputeFormat procedure} -body {
    .s configure -from .00001 -to .0001 -resolution .00001 -digits 1
    .s set .00006
    expr {[.s get] == 6e-05}
} -result 1
test scale-6.17 {ComputeFormat procedure} -body {
    .s configure -from 10000000 -to 100000000 -resolution 10000000 -digits 3
    .s set 49300000
    .s get
} -result 50000000
test scale-6.18 {ComputeFormat procedure} -body {
    .s configure -length 200 -from 0 -to 10 -resolution 0 -digits 0
    .s set .111111111
    .s get
} -result {0.11}
test scale-6.19 {ComputeFormat procedure} -body {
    .s configure -length 200 -from 1000 -to 1002 -resolution 0 -digits 0
    .s set 1001.23456789
    .s get
} -result {1001.23}
test scale-6.20 {ComputeFormat procedure} -body {
    .s configure -length 200 -from 1000 -to 1001.8 -resolution 0 -digits 0
    .s set 1001.23456789
    .s get
} -result {1001.235}
test scale-6.21 {ComputeFormat procedure} -body {
    .s configure -length 200 -from 1000 -to 1001.8 -resolution 0 -digits 200
    .s set 1001.23456789
    .s get
} -result {1001.235}
destroy .s


test scale-7.1 {ComputeScaleGeometry procedure} -constraints {
    nonPortable fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 10 -label "Short" -orient vertical -length 5i
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {88 458}
test scale-7.2 {ComputeScaleGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -label "Long string" -orient vertical -tick 200
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {168 108}
test scale-7.3 {ComputeScaleGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -orient vertical -showvalue 0 -width 10 \
        -sliderlength 10
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {22 108}
test scale-7.4 {ComputeScaleGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -orient vertical -showvalue 0 -bd 5 \
        -relief sunken
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {39 114}
test scale-7.5 {ComputeScaleGeometry procedure} -constraints {
    nonPortable fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 10 -label "Short" -orient horizontal -length 5i
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {458 61}
test scale-7.6 {ComputeScaleGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -label "Long string" -orient horizontal \
        -tick 500
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {108 79}
test scale-7.7 {ComputeScaleGeometry procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -orient horizontal -showvalue 0
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {108 27}
test scale-7.8 {ComputeScaleGeometry procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 1000 -orient horizontal -showvalue 0 -bd 5 \
        -relief raised -highlightthickness 2
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]
} -cleanup {
    deleteWindows
} -result {114 39}


test scale-8.1 {ScaleElement procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 53 52] [.s identify 54 52] [.s identify 70 52] \
        [.s identify 71 52]
} -cleanup {
    deleteWindows
} -result {{} trough1 trough1 {}}
test scale-8.2 {ScaleElement procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 60 2] [.s identify 60 3] [.s identify 60 302] \
        [.s identify 60 303]
} -cleanup {
    deleteWindows
} -result {{} trough1 trough2 {}}
test scale-8.3 {ScaleElement procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 60 83] [.s identify 60 84] [.s identify 60 113] \
        [.s identify 60 114] \
} -cleanup {
    deleteWindows
} -result {trough1 slider slider trough2}
test scale-8.4 {ScaleElement procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient vertical -bd 4 -width 10 \
        -highlightthickness 1 -length 300 -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 4 40] [.s identify 5 40] [.s identify 22 40] \
        [.s identify 23 40] \
} -cleanup {
    deleteWindows
} -result {{} trough1 trough1 {}}
test scale-8.5 {ScaleElement procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient horizontal -bd 1 \
        -highlightthickness 2 -tick 20 -sliderlength 20 \
        -length 200 -label Test
    pack .s
    .s set 30
    update
    list [.s identify 150 36] [.s identify 150 37] [.s identify 150 53] \
        [.s identify 150 54]
} -cleanup {
    deleteWindows
} -result {{} trough2 trough2 {}}
test scale-8.6 {ScaleElement procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient horizontal -bd 2 \
        -highlightthickness 1 -tick 20 -length 200
    pack .s
    .s set 30
    update
    list [.s identify 150 20] [.s identify 150 21] [.s identify 150 39] \
        [.s identify 150 40]
} -cleanup {
    deleteWindows
} -result {{} trough2 trough2 {}}
test scale-8.7 {ScaleElement procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient horizontal -bd 4 -highlightthickness 2 \
        -length 200 -width 10 -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 30 5] [.s identify 30 6] [.s identify 30 23] \
        [.s identify 30 24]
} -cleanup {
    deleteWindows
} -result {{} trough1 trough1 {}}
test scale-8.8 {ScaleElement procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient horizontal -bd 1 -highlightthickness 2 \
        -tick 20 -sliderlength 20 -length 200 -label Test -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 2 28] [.s identify 3 28] [.s identify 202 28] \
        [.s identify 203 28]
} -cleanup {
    deleteWindows
} -result {{} trough1 trough2 {}}
test scale-8.9 {ScaleElement procedure} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -orient horizontal -bd 1 -highlightthickness 2 \
        -tick 20 -sliderlength 20 -length 200 -label Test -showvalue 0
    pack .s
    .s set 80
    update
    list [.s identify 145 28] [.s identify 146 28] [.s identify 165 28] \
        [.s identify 166 28]
} -cleanup {
    deleteWindows
} -result {trough1 slider slider trough2}


#widget used in 9.* tests
destroy .s
pack [scale .s]
test scale-9.1 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get 46 0
} -result 0
test scale-9.2 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 9
} -result 0
test scale-9.3 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 12
} -result 1
test scale-9.4 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 46
} -result 35
test scale-9.5 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update













    .s get -10 110
} -result 99
test scale-9.6 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 111
} -result 100
test scale-9.7 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 112
} -result 100
test scale-9.8 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2
    update
    .s get -10 154
} -result 100
test scale-9.9 {PixelToValue procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal
    update

    .s get 76 152
} -result 65
destroy .s


test scale-10.1 {ValueToPixel procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 0 -to 100 -sliderlength 20 -length 124 -bd 2 \
        -orient horizontal -label Test -tick 20
    pack .s
    update
    list [.s coords -10] [.s coords 40] [.s coords 1000]
} -cleanup {
    deleteWindows
} -result {{16 47} {56 47} {116 47}}
test scale-10.2 {ValueToPixel procedure} -constraints {
    fonts
} -setup {
    deleteWindows
} -body {
    scale .s -from 100 -to 0 -sliderlength 20 -length 122 -bd 1 \
        -orient vertical -label Test -tick 20
    pack .s
    update
    list [.s coords -10] [.s coords 40] [.s coords 1000]
} -cleanup {
    deleteWindows
} -result {{62 114} {62 74} {62 14}}


test scale-11.1 {ScaleEventProc procedure} -setup {
    deleteWindows
} -body {
    proc killScale value {
        global x
        if {$value > 30} {
            destroy .s1
            lappend x [winfo exists .s1] [info commands .s1]
        }
    }

    set x initial
    scale .s1 -from 0 -to 100 -command killScale
    .s1 set 20
    pack .s1
    update idletasks
    lappend x [winfo exists .s1]
    .s1 set 40
    update idletasks
    return $x
} -cleanup {
    rename killScale {}
    deleteWindows
} -result {initial 1 0 {}}
test scale-11.2 {ScaleEventProc procedure} -setup {
    deleteWindows
    set x {}
} -body {
    scale .s1 -bg #543210
    rename .s1 .s2

    lappend x [winfo children .]
    lappend x [.s2 cget -bg]
    destroy .s1
    lappend x [info command .s*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {.s1 #543210 {} {}}

test scale-12.1 {ScaleCmdDeletedProc procedure} -setup {
    deleteWindows
} -body {
    scale .s1
    rename .s1 {}
    list [info command .s*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}


# Widget used in 13.* tests
destroy .s

pack [scale .s]
update




test scale-13.1 {SetScaleValue procedure} -body {
    .s configure -from 0 -to 100 -command {set x} -variable y
    update
    set x xyzzy
    .s set 44
    set result [list $x $y]
    update
    lappend result $x $y
} -result {xyzzy 44 44 44}
test scale-13.2 {SetScaleValue procedure} -body {
    .s set -3
    .s get
} -result 0
test scale-13.3 {SetScaleValue procedure} -body {
    .s set 105
    .s get
} -result 100
.s configure -from 100 -to 0
test scale-13.4 {SetScaleValue procedure} -body {
    .s set -3
    .s get
} -result 0
test scale-13.5 {SetScaleValue procedure} -body {
    .s set 105
    .s get
} -result 100
test scale-13.6 {SetScaleValue procedure} -body {
    proc varTrace args {
        global traceInfo
        set traceInfo $args
    }
    .s configure -from 0 -to 100 -command {set x} -variable y
    update

    .s set 50
    update
    trace variable y w varTrace
    set traceInfo empty
    set x untouched
    .s set 50
    update
    list $x $traceInfo
} -result {untouched empty}


# Widget used in 14.* tests
destroy .s
pack [scale .s]
update
test scale-14.1 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0

    update
    .s get 84 152
} -result 72
test scale-14.2 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result 76

test scale-14.3 {RoundValueToResolution procedure} -body {
    .s configure -from 100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 84 152
} -result 28
test scale-14.4 {RoundValueToResolution procedure} -body {
    .s configure -from 100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result 24

test scale-14.5 {RoundValueToResolution procedure} -body {
    .s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update

    .s get 84 152
} -result -28
test scale-14.6 {RoundValueToResolution procedure} -body {
    .s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result -24

test scale-14.7 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update

    .s get 84 152
} -result -72
test scale-14.8 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result -76

test scale-14.9 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 2.25  -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 0
    update

    .s get 84 152
} -result {1.64}
test scale-14.10 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 2.25  -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 0
    update
    .s get 86 152
} -result {1.69}

test scale-14.11 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 225 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 0 -digits 5
    update

    .s get 84 152
} -result {164.25}
test scale-14.12 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 225 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 0 -digits 5
    update
    .s get 86 152
} -result {168.75}
destroy .s

test scale-14.13 {RoundValueToResolution procedure, round-off errors} -setup {
    # see [220665ffff], and duplicates [220265ffff] and [779559ffff]
    set x NotSet
    pack [scale .s -orient horizontal -resolution .1 -from -180 -to 180 -command "set x"]
    update
} -body {
    .s configure -background red
    update
    set x
} -cleanup {
    destroy .s
} -result {NotSet}

test scale-14a.1 {RoundValueToResolution, RoundIntervalToResolution procedures} -setup {
    pack [scale .s -orient horizontal]
    update
} -body {
    .s configure -length 400 -bd 0 -from 1 -to 9 -resolution 2 -tickinterval 1
    update
    .s get 200 0
} -cleanup {
    destroy .s
} -result 5
test scale-14a.2 {RoundValueToResolution, RoundIntervalToResolution procedures} -setup {
    pack [scale .s -orient horizontal]
    update
} -body {
    .s configure -length 400 -bd 0 -from -1.5 -to 1.5 -resolution 1 \
            -tickinterval 1 -digits 2
    update
    .s get 250 0
} -cleanup {
    destroy .s
} -result {0.5}


test scale-15.1 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from 0 -to -200 -variable y -orient horizontal -length 150
    pack .s
    return $y
} -result -130
test scale-15.2 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y -87
    .s get
} -result -87
test scale-15.3 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y 40q
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't set "y": can't assign non-numeric value to scale variable}
test scale-15.4 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    catch {set y 40q}
    .s get
} -cleanup {
    deleteWindows
} -result -130
test scale-15.5 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y 1
    scale .s -from 1 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y x
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't set "y": can't assign non-numeric value to scale variable}
test scale-15.6 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y 1
    scale .s -from 1 -to 0 -variable y -orient horizontal -length 150
    pack .s
    catch {set y x}
    .s get
} -cleanup {
    deleteWindows
} -result 1
test scale-15.7 {ScaleVarProc procedure, variable deleted} -setup {
    deleteWindows
} -body {
    set y 6
    scale .s -from 10 -to 0 -variable y -orient horizontal -length 150 \
        -command "set x"
    pack .s
    update
    set x untouched
    unset y
    update
    list [catch {set y} msg] $msg [.s get] $x
} -cleanup {
    deleteWindows
} -result {0 6 6 untouched}
test scale-15.8 {ScaleVarProc procedure, don't call -command} -setup {
    deleteWindows
} -body {
    set y 6
    scale .s -from 0 -to 100 -variable y -orient horizontal -length 150 \
        -command "set x"
    pack .s
    update
    set x untouched
    set y 60
    update
    list $x [.s get]
} -cleanup {
    deleteWindows
} -result {untouched 60}




test scale-16.1 {scale widget vs hidden commands} -body {
    set l [interp hidden]
    deleteWindows
    scale .s
    interp hide {} .s
    destroy .s
    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 eq $res2}
} -cleanup {
    deleteWindows
} -result 1


test scale-17.1 {bug fix 1786} -setup {
    deleteWindows
} -body {
    # Perhaps x is set to {}, depending on what other tests have run.
    # If x is unset, or set to something not convertable to a double,
    # then the scale try to initialize its value with the contents
    # of uninitialized memory.  Sometimes that causes an FPE.

    set x {}
    scale .s -from 100 -to 300
    pack .s
    update
    .s configure -variable x   ;# CRASH! -> Floating point exception

    # Bug 4833 changed the result to realize that x should pick up
    # a value from the scale.  In an FPE occurs, it is due to the
    # lack of errno being set to 0 by some libc's. (see bug 4942)
    return $x
} -cleanup {
    deleteWindows
} -result 100


test scale-18.1 {DestroyScale, -cursor option [Bug: 3897]} -setup {
    deleteWindows
} -body {
    scale .s -cursor trek
    destroy .s
} -result {}

test scale-18.2 {Scale button 1 events [Bug 787065]} -setup {

    destroy .s
    set ::error {}
    proc bgerror {args} {set ::error $args}
} -body {
    set y 5
    scale .s -from 0 -to 10 -variable y -orient horizontal -length 150
    pack .s
    tkwait visibility .s




    list [catch {
        event generate .s <Button-1> -x 0 -y 0
        event generate .s <ButtonRelease-1> -x 0 -y 0
        update
        set ::error
    } msg] $msg

} -cleanup {
    unset ::error
    rename bgerror {}
    destroy .s

} -result {0 {}}

test scale-18.3 {Scale button 2 events [Bug 787065]} -setup {

    destroy .s
    set ::error {}
    proc bgerror {args} {set ::error $args}
} -body {
    set y 5
    scale .s -from 0 -to 10 -variable y -orient horizontal -length 150
    pack .s
    tkwait visibility .s




    list [catch {
        event generate .s <Button-2> -x 0 -y 0
        event generate .s <ButtonRelease-2> -x 0 -y 0
        update
        set ::error
    } msg] $msg

} -cleanup {
    unset ::error
    rename bgerror {}
    destroy .s

} -result {0 {}}


test scale-19 {Bug [3529885fff] - Click in through goes in wrong direction} \
    -setup {
        catch {destroy .s}
        catch {destroy .s1 .s2 .s3 .s4}
        unset -nocomplain x1 x2 x3 x4 x y
        scale .s1 -from 0 -to 100 -resolution 1  -variable x1 -digits 4 -orient horizontal -length 100
        scale .s2 -from 0 -to 100 -resolution -1 -variable x2 -digits 4 -orient horizontal -length 100
        scale .s3 -from 100 -to 0 -resolution 1  -variable x3 -digits 4 -orient horizontal -length 100
        scale .s4 -from 100 -to 0 -resolution -1 -variable x4 -digits 4 -orient horizontal -length 100
        pack .s1 .s2 .s3 .s4 -side left
        update
    } \
    -body {
        foreach {x y} [.s1 coord 50] {}
        event generate .s1 <Button-1> -x $x -y $y
        event generate .s1 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s2 coord 50] {}
        event generate .s2 <Button-1> -x $x -y $y
        event generate .s2 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s3 coord 50] {}
        event generate .s3 <Button-1> -x $x -y $y
        event generate .s3 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s4 coord 50] {}
        event generate .s4 <Button-1> -x $x -y $y
        event generate .s4 <ButtonRelease-1> -x $x -y $y
        update
        list $x1 $x2 $x3 $x4
    } \
    -cleanup {
        unset x1 x2 x3 x4 x y
        destroy .s1 .s2 .s3 .s4
    } \
    -result {1.0 1.0 1.0 1.0}

test scale-20.1 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 1} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    pack .s
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {1 -1}
test scale-20.2 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 2} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
    set scaleVar 7
} -body {
    scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar}
    pack .s
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {7 -1}
test scale-20.3 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 3} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    .s set 10
    .s configure -command {set commandedVar}
    pack .s
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.4 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 4} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    .s set 10
    pack .s
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.5 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 5} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s
    .s set 10
    .s configure -command {set commandedVar}
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.6 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 6} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s
    .s configure -command {set commandedVar}
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.7 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 7} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    pack .s
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.8 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 8} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
    set scaleVar 7
} -body {
    scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar}
    pack .s
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}

test scale-21.1 {Bug [55b95f578a] - Associating variable with bignum value with scale crashes it} -setup {
    catch {destroy .s}
} -body {
    pack [scale .s]
    set foo 5.79e99
    # non-regression test for bug [55b95f578a] - shall just not crash
    .s configure -variable foo
} -cleanup {
    destroy .s
} -result {}
test scale-21.2 {Bug [55b95f578a] again - Bignum value for -from/-to with scale crashes it} -setup {
    catch {destroy .s}
} -body {
    pack [scale .s]
    # non-regression test for bug [55b95f578a] - shall just not crash
    .s configure -from -6.8e99 -to 8.8e99
} -cleanup {
    destroy .s
} -result {}

test scale-22.1 {Bug [5d991b822e]} {
    # Want this not to crash
    set var INIT
    scale .b -variable var
    trace add variable var unset {apply {args {
        .b configure -variable {}
    }}}
    pack .b
    bind .b <Configure> {unset var}
    update
    destroy .b
} {}
test scale-22.2 {Bug [5d991b822e]} {
    # Want this not to leak traces
    set var INIT
    scale .b -variable var
    trace add variable var unset {apply {args {
        .b configure -variable new
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}

option clear

# cleanup
cleanupTests
return



|
|
|



<










<



|
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
>
>
>
>
>
>
|
|
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
<
>
>
|
<
<
<
<
|
<
<
<
|
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
|
<
|
|
<
|
>
|
|
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|
|
|
|
|
|
<
<
<
<
|
|
<
<
<
<

<
<
<



|
|
|
|
|
|
|
|
|
|
|
|
|
<

|
|

|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
<
<
<
<
<
<
<
<

|
|
<
<
|
|


|
<
<
<
<
<
<
<
<
<
<
<
|
|
>
>
>
>
>
>
>
|
|
|
<
<
|
|
|
<
<


|
|
|
<


|

|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<


|
|
|
|
|
|
|
|
|
|
|
<
<

|
|
<
<





|
|
|
|
|
|
|
|
|
|
<
<
|
<
<

|

>





<
<
<
|

|
<
|






|

<
|
<
|







<
<
|
|
<
|

|
<
<
|
|
<
|









|
<
<
|
|
<
|

|
<
<
|
|
<
|


|
<
<
|
|
<
|





<
<
|
|
<
|
|
<
<
|

<
<
|


|



|
|



|
|



|
|



|
|



|
|
<
<


>



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
<

<
|
<
<
<
|




<
<
|
|
<
<
<
|




<
<
|
|
<
<
<
|

|



<
<
|
|
<
<
<
|

|



<
<
|
|
<
<
<
|




<
<
|
|
<
<
<
|

|



<
<
|
|
<
<
<
|




<
<
|
|
<
|

|



<
<
|

<
|
<
<
<
|





|
<
<
|
|
<
<
<
|





|
<
<
|
|
<
<
<
|





|
<
<
|
|
<
|

|




|
<
<
|
|
<
<
<
|

|
|




|
<
<
|
|
<
<
<
|

|




|
<
<
|
|
<
|

|




|
<
<
|
|
<
|

|




|
<
<
|
|
<
|

|




|
<
<
|

<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
<
<

|
|
<
<

|
|
<
<

|
<
<
|
|
>

<
<
|

|
<
<
<
|

|



<
<
|
|
<
<
<
|

|



<
<
|

<
|
<
<

|
|
|
|
|

>








<
<

|
|
|

<
<


>




<
<
|

|

<



<
<
|

<
<
|
>
|

>
>
>
>
|
<
<





|
|


|
|


|

|


|
|


|
|
<
<
<
<
<
<
<








|

<
<
|
<
<
<
|
<
>
|
<
<
<
<
|
|
<
<
<
|
<
<
<

|
|
<
<
<

<
|
<
|
<
|
>

|
|
<
<
<

<
|
<
|
<
|
>

|
|
<
<
<

|
<
<
|
<
|
>

|
|
<
<
<

<
|
<
|
<
|
>

|
|
<
<
<

<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
<
|

|
<
|



|
|
|
<
|





|
|
<
|



|
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<



|
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<


|






<
<
|
|
<
|


|






<
<
|

>
>

|
<
|



|
|
<
<
<
<

<
|
<
<














|
<
<
<
|

|
<
|


|

|
>
|
<
<
<
|
|
|
|
>
>
>
>
|
|
|
|
|
|
>
|
|
|
|
>
|

|
>
|
<
<
<
|
|
|
|
>
>
>
>
|
|
|
|
|
|
>
|
|
|
|
>
|
<















|


|


|


|










<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25






26

27






28








29

30






31

32






33








34


35











36
















37
38

39












40

41






42

43








44






45








46





47








48

49
50







51












52








53








54

55

56
57
58
59
60
61
62
63


64
65







66
67



68
69
70




71



72
73

74



75








76


77









78

79

80
81

82
83
84
85








86
87






















88

89
90
91
92
93
94
95




96
97




98



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133








134
135
136


137
138
139
140
141











142
143
144
145
146
147
148
149
150
151
152
153


154
155
156


157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178




179
180
181
182
183
184
185
186
187
188
189
190
191


192
193
194


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209


210


211
212
213
214
215
216
217
218
219



220
221
222

223
224
225
226
227
228
229
230
231

232

233
234
235
236
237
238
239
240


241
242

243
244
245


246
247

248
249
250
251
252
253
254
255
256
257
258


259
260

261
262
263


264
265

266
267
268
269


270
271

272
273
274
275
276
277


278
279

280
281


282
283


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395

396



397
398
399
400
401


402
403



404
405
406
407
408


409
410



411
412
413
414
415
416


417
418



419
420
421
422
423
424


425
426



427
428
429
430
431


432
433



434
435
436
437
438
439


440
441



442
443
444
445
446


447
448

449
450
451
452
453
454


455
456

457



458
459
460
461
462
463
464


465
466



467
468
469
470
471
472
473


474
475



476
477
478
479
480
481
482


483
484

485
486
487
488
489
490
491
492


493
494



495
496
497
498
499
500
501
502
503


504
505



506
507
508
509
510
511
512
513


514
515

516
517
518
519
520
521
522
523


524
525

526
527
528
529
530
531
532
533


534
535

536
537
538
539
540
541
542
543


544
545


546


547

548


















549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565


566
567
568


569
570
571


572
573


574
575
576
577


578
579
580



581
582
583
584
585
586


587
588



589
590
591
592
593
594


595
596

597


598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613


614
615
616
617
618


619
620
621
622
623
624
625


626
627
628
629

630
631
632


633
634


635
636
637
638
639
640
641
642
643


644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667







668
669
670
671
672
673
674
675
676
677


678



679

680
681




682
683



684



685
686
687



688

689

690

691
692
693
694
695



696

697

698

699
700
701
702
703



704
705


706

707
708
709
710
711



712

713

714

715
716
717
718
719



720


721






722
723




724






725


726
727






728



729
730
731

732
733
734
735
736
737
738

739
740
741
742
743
744
745
746

747
748
749
750
751


752
753





754







755
756
757
758


759
760





761







762
763
764
765
766
767
768
769
770


771
772

773
774
775
776
777
778
779
780
781
782


783
784
785
786
787
788

789
790
791
792
793
794




795

796


797
798
799
800
801
802
803
804
805
806
807
808
809
810
811



812
813
814

815
816
817
818
819
820
821
822



823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847



848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903

904
































































































































































905
906
907
908
909
# This file is a Tcl script to test out the "scale" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Scale.borderWidth 2
option add *Scale.highlightThickness 2
option add *Scale.font {Helvetica -12 bold}


scale .s -from 100 -to 300
pack .s
update
set i 1
foreach test {
    {-activebackground #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}

    {-background #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}








    {-bd 4 4 badValue {bad screen distance "badValue"}}

    {-bigincrement 12.5 12.5 badValue






	    {expected floating-point number but got "badValue"}}

    {-bg #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}








    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}


    {-command "set x" {set x} {} {}}











    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
















    {-digits 5 5 badValue {expected integer but got "badValue"}}
    {-fg #00ff00 #00ff00 badValue {unknown color name "badValue"}}

    {-font fixed fixed {} {font "" doesn't exist}}












    {-foreground green green badValue {unknown color name "badValue"}}

    {-from -15.0 -15.0 badValue






	    {expected floating-point number but got "badValue"}}

    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}








    {-highlightcolor #123456 #123456 non-existent






	    {unknown color name "non-existent"}}








    {-highlightthickness 2 2 badValue {bad screen distance "badValue"}}





    {-label "Some text" {Some text} {} {}}








    {-length 130 130 badValue {bad screen distance "badValue"}}

    {-orient horizontal horizontal badValue
	    {bad orient "badValue": must be horizontal or vertical}}







    {-orient horizontal horizontal {} {}}












    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}








    {-repeatdelay 14 14 bogus {expected integer but got "bogus"}}








    {-repeatinterval 14 14 bogus {expected integer but got "bogus"}}

    {-resolution 2.0 2.0 badValue

	    {expected floating-point number but got "badValue"}}
    {-showvalue 0 0 badValue {expected boolean value but got "badValue"}}
    {-sliderlength 86 86 badValue {bad screen distance "badValue"}}
    {-sliderrelief raised raised badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-state d disabled badValue
	    {bad state "badValue": must be active, disabled, or normal}}
    {-state n normal {} {}}
    {-takefocus "any string" "any string" {} {}}


    {-tickinterval 4.3 4.0 badValue
	    {expected floating-point number but got "badValue"}}







    {-to 14.9 15.0 badValue
	    {expected floating-point number but got "badValue"}}



    {-troughcolor #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-variable x x {} {}}




    {-width 32 32 badValue {bad screen distance "badValue"}}



} {
    set name [lindex $test 0]

    test scale-1.$i {configuration options} {



	.s configure $name [lindex $test 1]








	lindex [.s configure $name] 4


    } [lindex $test 2]









    incr i

    if {[lindex $test 3] ne ""} {

	test scale-1.$i {configuration options} {
	    list [catch {.s configure $name [lindex $test 3]} msg] $msg

	} [list 1 [lindex $test 4]]
    }
    .s configure $name [lindex [.s configure $name] 3]
    incr i








}
destroy .s
























test scale-2.1 {Tk_ScaleCmd procedure} {
    list [catch {scale} msg] $msg
} {1 {wrong # args: should be "scale pathName ?options?"}}
test scale-2.2 {Tk_ScaleCmd procedure} {
    list [catch {scale foo} msg] $msg [winfo child .]
} {1 {bad window path name "foo"} {}}
test scale-2.3 {Tk_ScaleCmd procedure} {




    list [catch {scale .s -gorp dumb} msg] $msg [winfo child .]
} {1 {unknown option "-gorp"} {}}








scale .s -from 100 -to 200
pack .s
update idletasks
test scale-3.1 {ScaleWidgetCmd procedure} {
    list [catch {.s} msg] $msg
} {1 {wrong # args: should be ".s option ?arg arg ...?"}}
test scale-3.2 {ScaleWidgetCmd procedure, cget option} {
    list [catch {.s cget} msg] $msg
} {1 {wrong # args: should be ".s cget option"}}
test scale-3.3 {ScaleWidgetCmd procedure, cget option} {
    list [catch {.s cget a b} msg] $msg
} {1 {wrong # args: should be ".s cget option"}}
test scale-3.4 {ScaleWidgetCmd procedure, cget option} {
    list [catch {.s cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test scale-3.5 {ScaleWidgetCmd procedure, cget option} {

    .s cget -highlightthickness
} {2}
test scale-3.6 {ScaleWidgetCmd procedure, configure option} {
    list [llength [.s configure]] [lindex [.s configure] 6]
} {33 {-command command Command {} {}}}
test scale-3.7 {ScaleWidgetCmd procedure, configure option} {
    list [catch {.s configure -foo} msg] $msg
} {1 {unknown option "-foo"}}
test scale-3.8 {ScaleWidgetCmd procedure, configure option} {
    list [catch {.s configure -borderwidth 2 -bg} msg] $msg
} {1 {value for "-bg" missing}}
test scale-3.9 {ScaleWidgetCmd procedure, coords option} {
    list [catch {.s coords a b} msg] $msg
} {1 {wrong # args: should be ".s coords ?value?"}}
test scale-3.10 {ScaleWidgetCmd procedure, coords option} {
    list [catch {.s coords bad} msg] $msg
} {1 {expected floating-point number but got "bad"}}
test scale-3.11 {ScaleWidgetCmd procedure} {fonts} {
    .s set 120








    .s coords
} {38 34}
test scale-3.12 {ScaleWidgetCmd procedure, coords option} {fonts} {


    .s configure -orient horizontal
    update
    .s set 120
    .s coords
} {34 31}











.s configure -orient vertical
update
test scale-3.13 {ScaleWidgetCmd procedure, get option} {
    list [catch {.s get a} msg] $msg
} {1 {wrong # args: should be ".s get ?x y?"}}
test scale-3.14 {ScaleWidgetCmd procedure, get option} {
    list [catch {.s get a b c} msg] $msg
} {1 {wrong # args: should be ".s get ?x y?"}}
test scale-3.15 {ScaleWidgetCmd procedure, get option} {
    list [catch {.s get a 11} msg] $msg
} {1 {expected integer but got "a"}}
test scale-3.16 {ScaleWidgetCmd procedure, get option} {


    list [catch {.s get 12 b} msg] $msg
} {1 {expected integer but got "b"}}
test scale-3.17 {ScaleWidgetCmd procedure, get option} {


    .s set 133
    .s get
} 133
test scale-3.18 {ScaleWidgetCmd procedure, get option} {
    .s configure -resolution 0.5

    .s set 150
    .s get 37 34
} 119.5
.s configure -resolution 1
test scale-3.19 {ScaleWidgetCmd procedure, identify option} {
    list [catch {.s identify} msg] $msg
} {1 {wrong # args: should be ".s identify x y"}}
test scale-3.20 {ScaleWidgetCmd procedure, identify option} {
    list [catch {.s identify 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s identify x y"}}
test scale-3.21 {ScaleWidgetCmd procedure, identify option} {
    list [catch {.s identify boo 16} msg] $msg
} {1 {expected integer but got "boo"}}
test scale-3.22 {ScaleWidgetCmd procedure, identify option} {
    list [catch {.s identify 17 bad} msg] $msg
} {1 {expected integer but got "bad"}}
test scale-3.23 {ScaleWidgetCmd procedure, identify option} {fonts} {




    .s set 120
    list [.s identify 35 10] [.s identify 35 30] [.s identify 35 80] [.s identify 5 80]
} {trough1 slider trough2 {}}
test scale-3.24 {ScaleWidgetCmd procedure, set option} {
    list [catch {.s set} msg] $msg
} {1 {wrong # args: should be ".s set value"}}
test scale-3.25 {ScaleWidgetCmd procedure, set option} {
    list [catch {.s set a b} msg] $msg
} {1 {wrong # args: should be ".s set value"}}
test scale-3.26 {ScaleWidgetCmd procedure, set option} {
    list [catch {.s set bad} msg] $msg
} {1 {expected floating-point number but got "bad"}}
test scale-3.27 {ScaleWidgetCmd procedure, set option} {


    .s set 142
} {}
test scale-3.28 {ScaleWidgetCmd procedure, set option} {


    .s set 118
    .s configure -state disabled
    .s set 181
    .s configure -state normal
    .s get
} {118}
test scale-3.29 {ScaleWidgetCmd procedure} {
    list [catch {.s dumb} msg] $msg
} {1 {bad option "dumb": must be cget, configure, coords, get, identify, or set}}
test scale-3.30 {ScaleWidgetCmd procedure} {
    list [catch {.s c} msg] $msg
} {1 {ambiguous option "c": must be cget, configure, coords, get, identify, or set}}
test scale-3.31 {ScaleWidgetCmd procedure} {
    list [catch {.s co} msg] $msg
} {1 {ambiguous option "co": must be cget, configure, coords, get, identify, or set}}


test scale-3.32 {ScaleWidgetCmd procedure, Tk_Preserve} {


    proc kill args {
	destroy .s
    }
    catch {destroy .s}
    scale .s -variable x -from 0 -to 100 -orient horizontal
    pack .s
    update
    .s configure -command kill
    .s set 55



} {}

test scale-4.1 {DestroyScale procedure} {

    catch {destroy .s}
    set x 50
    scale .s -variable x -from 0 -to 100 -orient horizontal
    pack .s
    update
    destroy .s
    list [catch {set x foo} msg] $msg $x
} {0 foo foo}


test scale-5.1 {ConfigureScale procedure} {

    catch {destroy .s}
    set x 66
    set y 77
    scale .s -variable x -from 0 -to 100
    pack .s
    update
    .s configure -variable y
    list [catch {set x foo} msg] $msg $x [.s get]


} {0 foo foo 77}
test scale-5.2 {ConfigureScale procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100
    list [catch {.s configure -foo bar} msg] $msg


} {1 {unknown option "-foo"}}
test scale-5.3 {ConfigureScale procedure} {

    catch {destroy .s}
    catch {unset x}
    scale .s -from 0 -to 100 -variable x
    set result $x
    lappend result [.s get]
    set x 92
    lappend result [.s get]
    .s set 3
    lappend result $x
    unset x
    lappend result [catch {set x} msg] $msg


} {0 0 92 3 0 3}
test scale-5.4 {ConfigureScale procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100
    list [catch {.s configure -orient dumb} msg] $msg


} {1 {bad orient "dumb": must be horizontal or vertical}}
test scale-5.5 {ConfigureScale procedure} {

    catch {destroy .s}
    scale .s -from 1.11 -to 1.89 -resolution .1 -tickinterval .76
    list [format %.1f [.s cget -from]] [format %.1f [.s cget -to]] \
	    [format %.1f [.s cget -tickinterval]]


} {1.1 1.9 0.8}
test scale-5.6 {ConfigureScale procedure} {

    catch {destroy .s}
    scale .s -from 1 -to 10 -tickinterval -2
    pack .s
    set result [lindex [.s configure -tickinterval] 4]
    .s configure -from 10 -to 1 -tickinterval 2
    lappend result [lindex [.s configure -tickinterval] 4]


} {2.0 -2.0}
test scale-5.7 {ConfigureScale procedure} {

    catch {destroy .s}
    list [catch {scale .s -from 0 -to 100 -state bogus} msg] $msg


} {1 {bad state "bogus": must be active, disabled, or normal}}



catch {destroy .s}
scale .s -orient horizontal -length 200
pack .s
test scale-6.1 {ComputeFormat procedure} {
    .s configure -from 10 -to 100 -resolution 10
    .s set 49.3
    .s get
} {50}
test scale-6.2 {ComputeFormat procedure} {
    .s configure -from 100 -to 1000 -resolution 100
    .s set 493
    .s get
} {500}
test scale-6.3 {ComputeFormat procedure} {
    .s configure -from 1000 -to 10000 -resolution 1000
    .s set 4930
    .s get
} {5000}
test scale-6.4 {ComputeFormat procedure} {
    .s configure -from 10000 -to 100000 -resolution 10000
    .s set 49000
    .s get
} {50000}
test scale-6.5 {ComputeFormat procedure} {
    .s configure -from 100000 -to 1000000 -resolution 100000
    .s set 493000
    .s get
} {500000}
test scale-6.6 {ComputeFormat procedure} {nonPortable} {


    # This test is non-portable because some platforms format the
    # result as 5e+06.

    .s configure -from 1000000 -to 10000000 -resolution 1000000
    .s set 4930000
    .s get
} {5000000}
test scale-6.7 {ComputeFormat procedure} {
    .s configure -from 1000000000 -to 10000000000 -resolution 1000000000
    .s set 4930000000
    expr {[.s get] == 5.0e+09}
} 1
test scale-6.8 {ComputeFormat procedure} {
    .s configure -from .1 -to 1 -resolution .1
    .s set .6
    .s get
} {0.6}
test scale-6.9 {ComputeFormat procedure} {
    .s configure -from .01 -to .1 -resolution .01
    .s set .06
    .s get
} {0.06}
test scale-6.10 {ComputeFormat procedure} {
    .s configure -from .001 -to .01 -resolution .001
    .s set .006
    .s get
} {0.006}
test scale-6.11 {ComputeFormat procedure} {
    .s configure -from .0001 -to .001 -resolution .0001
    .s set .0006
    .s get
} {0.0006}
test scale-6.12 {ComputeFormat procedure} {
    .s configure -from .00001 -to .0001 -resolution .00001
    .s set .00006
    .s get
} {0.00006}
test scale-6.13 {ComputeFormat procedure} {
    .s configure -from .000001 -to .00001 -resolution .000001
    .s set .000006
    expr {[.s get] == 6.0e-06}
} {1}
test scale-6.14 {ComputeFormat procedure} {
    .s configure -to .00001 -from .0001 -resolution .00001
    .s set .00006
    .s get
} {0.00006}
test scale-6.15 {ComputeFormat procedure} {
    .s configure -to .000001 -from .00001 -resolution .000001
    .s set .000006
    expr {[.s get] == 6.0e-06}
} {1}
test scale-6.16 {ComputeFormat procedure} {
    .s configure -from .00001 -to .0001 -resolution .00001 -digits 1
    .s set .00006
    expr {[.s get] == 6e-05}
} {1}
test scale-6.17 {ComputeFormat procedure} {
    .s configure -from 10000000 -to 100000000 -resolution 10000000 -digits 3
    .s set 49300000
    .s get
} {50000000}
test scale-6.18 {ComputeFormat procedure} {
    .s configure -length 200 -from 0 -to 10 -resolution 0 -digits 0
    .s set .111111111
    .s get
} {0.11}
test scale-6.19 {ComputeFormat procedure} {
    .s configure -length 200 -from 1000 -to 1002 -resolution 0 -digits 0
    .s set 1001.23456789
    .s get
} {1001.23}
test scale-6.20 {ComputeFormat procedure} {
    .s configure -length 200 -from 1000 -to 1001.8 -resolution 0 -digits 0
    .s set 1001.23456789
    .s get
} {1001.235}
test scale-6.21 {ComputeFormat procedure} {
    .s configure -length 200 -from 1000 -to 1001.8 -resolution 0 -digits 200
    .s set 1001.23456789
    .s get
} {1001.235}



test scale-7.1 {ComputeScaleGeometry procedure} {nonPortable fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 10 -label "Short" -orient vertical -length 5i
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {88 458}
test scale-7.2 {ComputeScaleGeometry procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 1000 -label "Long string" -orient vertical -tick 200
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {168 108}
test scale-7.3 {ComputeScaleGeometry procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 1000 -orient vertical -showvalue 0 -width 10 \
	    -sliderlength 10
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {22 108}
test scale-7.4 {ComputeScaleGeometry procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 1000 -orient vertical -showvalue 0 -bd 5 \
	    -relief sunken
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {39 114}
test scale-7.5 {ComputeScaleGeometry procedure} {nonPortable fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 10 -label "Short" -orient horizontal -length 5i
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {458 61}
test scale-7.6 {ComputeScaleGeometry procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 1000 -label "Long string" -orient horizontal \
	    -tick 500
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {108 79}
test scale-7.7 {ComputeScaleGeometry procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 1000 -orient horizontal -showvalue 0
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {108 27}
test scale-7.8 {ComputeScaleGeometry procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 1000 -orient horizontal -showvalue 0 -bd 5 \
	    -relief raised -highlightthickness 2
    pack .s
    update
    list [winfo reqwidth .s] [winfo reqheight .s]


} {114 39}


test scale-8.1 {ScaleElement procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 53 52] [.s identify 54 52] [.s identify 70 52] \
	    [.s identify 71 52]


} {{} trough1 trough1 {}}
test scale-8.2 {ScaleElement procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 60 2] [.s identify 60 3] [.s identify 60 302] \
	    [.s identify 60 303]


} {{} trough1 trough2 {}}
test scale-8.3 {ScaleElement procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -orient vertical -bd 1 -tick 20 -length 300
    pack .s
    .s set 30
    update
    list [.s identify 60 83] [.s identify 60 84] [.s identify 60 113] \
	    [.s identify 60 114] \


} {trough1 slider slider trough2}
test scale-8.4 {ScaleElement procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100 -orient vertical -bd 4 -width 10 \
	    -highlightthickness 1 -length 300 -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 4 40] [.s identify 5 40] [.s identify 22 40] \
	    [.s identify 23 40] \


} {{} trough1 trough1 {}}
test scale-8.5 {ScaleElement procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -orient horizontal -bd 1 \
	    -highlightthickness 2 -tick 20 -sliderlength 20 \
	    -length 200 -label Test
    pack .s
    .s set 30
    update
    list [.s identify 150 36] [.s identify 150 37] [.s identify 150 53] \
	    [.s identify 150 54]


} {{} trough2 trough2 {}}
test scale-8.6 {ScaleElement procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -orient horizontal -bd 2 \
	    -highlightthickness 1 -tick 20 -length 200
    pack .s
    .s set 30
    update
    list [.s identify 150 20] [.s identify 150 21] [.s identify 150 39] \
	    [.s identify 150 40]


} {{} trough2 trough2 {}}
test scale-8.7 {ScaleElement procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100 -orient horizontal -bd 4 -highlightthickness 2 \
	    -length 200 -width 10 -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 30 5] [.s identify 30 6] [.s identify 30 23] \
	    [.s identify 30 24]


} {{} trough1 trough1 {}}
test scale-8.8 {ScaleElement procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100 -orient horizontal -bd 1 -highlightthickness 2 \
	    -tick 20 -sliderlength 20 -length 200 -label Test -showvalue 0
    pack .s
    .s set 30
    update
    list [.s identify 2 28] [.s identify 3 28] [.s identify 202 28] \
	    [.s identify 203 28]


} {{} trough1 trough2 {}}
test scale-8.9 {ScaleElement procedure} {

    catch {destroy .s}
    scale .s -from 0 -to 100 -orient horizontal -bd 1 -highlightthickness 2 \
	    -tick 20 -sliderlength 20 -length 200 -label Test -showvalue 0
    pack .s
    .s set 80
    update
    list [.s identify 145 28] [.s identify 146 28] [.s identify 165 28] \
	    [.s identify 166 28]


} {trough1 slider slider trough2}



catch {destroy .s}


scale .s -from 0 -to 100 -sliderlength 10 -length 114 -bd 2

pack .s


















update
test scale-9.1 {PixelToValue procedure} {
    .s get 46 0
} 0
test scale-9.2 {PixelToValue procedure} {
    .s get -10 9
} 0
test scale-9.3 {PixelToValue procedure} {
    .s get -10 12
} 1
test scale-9.4 {PixelToValue procedure} {
    .s get -10 46
} 35
test scale-9.5 {PixelToValue procedure} {
    .s get -10 110
} 99
test scale-9.6 {PixelToValue procedure} {


    .s get -10 111
} 100
test scale-9.7 {PixelToValue procedure} {


    .s get -10 112
} 100
test scale-9.8 {PixelToValue procedure} {


    .s get -10 154
} 100


.s configure -orient horizontal
update
test scale-9.9 {PixelToValue procedure} {
    .s get 76 152


} 65

test scale-10.1 {ValueToPixel procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 0 -to 100 -sliderlength 20 -length 124 -bd 2 \
	    -orient horizontal -label Test -tick 20
    pack .s
    update
    list [.s coords -10] [.s coords 40] [.s coords 1000]


} {{16 47} {56 47} {116 47}}
test scale-10.2 {ValueToPixel procedure} {fonts} {



    catch {destroy .s}
    scale .s -from 100 -to 0 -sliderlength 20 -length 122 -bd 1 \
	    -orient vertical -label Test -tick 20
    pack .s
    update
    list [.s coords -10] [.s coords 40] [.s coords 1000]


} {{62 114} {62 74} {62 14}}


test scale-11.1 {ScaleEventProc procedure} {


    proc killScale value {
	global x
	if {$value > 30} {
	    destroy .s1
	    lappend x [winfo exists .s1] [info commands .s1]
	}
    }
    catch {destroy .s1}
    set x initial
    scale .s1 -from 0 -to 100 -command killScale
    .s1 set 20
    pack .s1
    update idletasks
    lappend x [winfo exists .s1]
    .s1 set 40
    update idletasks


    rename killScale {}
    set x
} {initial 1 0 {}}
test scale-11.2 {ScaleEventProc procedure} {
    deleteWindows


    scale .s1 -bg #543210
    rename .s1 .s2
    set x {}
    lappend x [winfo children .]
    lappend x [.s2 cget -bg]
    destroy .s1
    lappend x [info command .s*] [winfo children .]


} {.s1 #543210 {} {}}

test scale-12.1 {ScaleCmdDeletedProc procedure} {
    deleteWindows

    scale .s1
    rename .s1 {}
    list [info command .s*] [winfo children .]


} {{} {}}



catch {destroy .s}
scale .s -from 0 -to 100 -command {set x} -variable y
pack .s
update
proc varTrace args {
    global traceInfo
    set traceInfo $args
}
test scale-13.1 {SetScaleValue procedure} {


    set x xyzzy
    .s set 44
    set result [list $x $y]
    update
    lappend result $x $y
} {xyzzy 44 44 44}
test scale-13.2 {SetScaleValue procedure} {
    .s set -3
    .s get
} 0
test scale-13.3 {SetScaleValue procedure} {
    .s set 105
    .s get
} 100
.s configure -from 100 -to 0
test scale-13.4 {SetScaleValue procedure} {
    .s set -3
    .s get
} 0
test scale-13.5 {SetScaleValue procedure} {
    .s set 105
    .s get
} 100
test scale-13.6 {SetScaleValue procedure} {







    .s set 50
    update
    trace variable y w varTrace
    set traceInfo empty
    set x untouched
    .s set 50
    update
    list $x $traceInfo
} {untouched empty}



catch {destroy .s}



scale .s -from 0 -to 100 -sliderlength 10 -length 114 -bd 2 -orient horizontal

pack .s
update




.s configure -resolution 4.0
update



test scale-14.1 {RoundToResolution procedure} {



    .s get 84 152
} 72
test scale-14.2 {RoundToResolution procedure} {



    .s get 86 152

} 76

.s configure -from 100 -to 0

update
test scale-14.3 {RoundToResolution procedure} {
    .s get 84 152
} 28
test scale-14.4 {RoundToResolution procedure} {



    .s get 86 152

} 24

.s configure -from -100 -to 0

update
test scale-14.5 {RoundToResolution procedure} {
    .s get 84 152
} -28
test scale-14.6 {RoundToResolution procedure} {



    .s get 86 152
} -24


.s configure -from 0 -to -100

update
test scale-14.7 {RoundToResolution procedure} {
    .s get 84 152
} -72
test scale-14.8 {RoundToResolution procedure} {



    .s get 86 152

} -76

.s configure -from 0 -to 2.25 -resolution 0

update
test scale-14.9 {RoundToResolution procedure} {
    .s get 84 152
} 1.64
test scale-14.10 {RoundToResolution procedure} {



    .s get 86 152


} 1.69






.s configure -from 0 -to 225 -resolution 0  -digits 5
update




test scale-14.11 {RoundToResolution procedure} {






    .s get 84 152


} 164.25
test scale-14.12 {RoundToResolution procedure} {






    .s get 86 152



} 168.75

test scale-15.1 {ScaleVarProc procedure} {

    catch {destroy .s}
    set y -130
    scale .s -from 0 -to -200 -variable y -orient horizontal -length 150
    pack .s
    set y
} -130
test scale-15.2 {ScaleVarProc procedure} {

    catch {destroy .s}
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y -87
    .s get
} -87
test scale-15.3 {ScaleVarProc procedure} {

    catch {destroy .s}
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    list [catch {set y 40q} msg] $msg [.s get]


} {1 {can't set "y": can't assign non-numeric value to scale variable} -130}
test scale-15.4 {ScaleVarProc procedure} {





    catch {destroy .s}







    set y 1
    scale .s -from 1 -to 0 -variable y -orient horizontal -length 150
    pack .s
    list [catch {set y x} msg] $msg [.s get]


} {1 {can't set "y": can't assign non-numeric value to scale variable} 1}
test scale-15.5 {ScaleVarProc procedure, variable deleted} {





    catch {destroy .s}







    set y 6
    scale .s -from 10 -to 0 -variable y -orient horizontal -length 150 \
	    -command "set x"
    pack .s
    update
    set x untouched
    unset y
    update
    list [catch {set y} msg] $msg [.s get] $x


} {0 6 6 untouched}
test scale-15.6 {ScaleVarProc procedure, don't call -command} {

    catch {destroy .s}
    set y 6
    scale .s -from 0 -to 100 -variable y -orient horizontal -length 150 \
	    -command "set x"
    pack .s
    update
    set x untouched
    set y 60
    update
    list $x [.s get]


} {untouched 60}

set l [interp hidden]
deleteWindows

test scale-16.1 {scale widget vs hidden commands} {

    catch {destroy .s}
    scale .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]






test scale-17.1 {bug fix 1786} {


    # Perhaps x is set to {}, depending on what other tests have run.
    # If x is unset, or set to something not convertable to a double,
    # then the scale try to initialize its value with the contents
    # of uninitialized memory.  Sometimes that causes an FPE.

    set x {}
    scale .s -from 100 -to 300
    pack .s
    update
    .s configure -variable x   ;# CRASH! -> Floating point exception

    # Bug 4833 changed the result to realize that x should pick up
    # a value from the scale.  In an FPE occurs, it is due to the
    # lack of errno being set to 0 by some libc's. (see bug 4942)
    set x



} {100}

test scale-18.1 {DestroyScale, -cursor option [Bug: 3897]} {

    catch {destroy .s}
    scale .s -cursor trek
    destroy .s
} {}

test scale-18.2 {Scale button 1 events [Bug 787065]} \
    -setup {
        catch {destroy .s}



        set y 5
        scale .s -from 0 -to 10 -variable y -orient horizontal -length 150
        pack .s
        tkwait visibility .s
        set ::error {}
        proc bgerror {args} {set ::error $args}
    } \
    -body {
        list [catch {
            event generate .s <1> -x 0 -y 0
            event generate .s <ButtonRelease-1> -x 0 -y 0
            update
            set ::error
        } msg] $msg
    } \
    -cleanup {
        unset ::error
        rename bgerror {}
        catch {destroy .s}
    } \
    -result {0 {}}

test scale-18.3 {Scale button 2 events [Bug 787065]} \
    -setup {
        catch {destroy .s}



        set y 5
        scale .s -from 0 -to 10 -variable y -orient horizontal -length 150
        pack .s
        tkwait visibility .s
        set ::error {}
        proc bgerror {args} {set ::error $args}
    } \
    -body {
        list [catch {
            event generate .s <2> -x 0 -y 0
            event generate .s <ButtonRelease-2> -x 0 -y 0
            update
            set ::error
        } msg] $msg
    } \
    -cleanup {
        unset ::error
        rename bgerror {}
        catch {destroy .s}
    } \
    -result {0 {}}


test scale-19 {Bug [3529885fff] - Click in through goes in wrong direction} \
    -setup {
        catch {destroy .s}
        catch {destroy .s1 .s2 .s3 .s4}
        unset -nocomplain x1 x2 x3 x4 x y
        scale .s1 -from 0 -to 100 -resolution 1  -variable x1 -digits 4 -orient horizontal -length 100
        scale .s2 -from 0 -to 100 -resolution -1 -variable x2 -digits 4 -orient horizontal -length 100
        scale .s3 -from 100 -to 0 -resolution 1  -variable x3 -digits 4 -orient horizontal -length 100
        scale .s4 -from 100 -to 0 -resolution -1 -variable x4 -digits 4 -orient horizontal -length 100
        pack .s1 .s2 .s3 .s4 -side left
        update
    } \
    -body {
        foreach {x y} [.s1 coord 50] {}
        event generate .s1 <1> -x $x -y $y
        event generate .s1 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s2 coord 50] {}
        event generate .s2 <1> -x $x -y $y
        event generate .s2 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s3 coord 50] {}
        event generate .s3 <1> -x $x -y $y
        event generate .s3 <ButtonRelease-1> -x $x -y $y
        foreach {x y} [.s4 coord 50] {}
        event generate .s4 <1> -x $x -y $y
        event generate .s4 <ButtonRelease-1> -x $x -y $y
        update
        list $x1 $x2 $x3 $x4
    } \
    -cleanup {
        unset x1 x2 x3 x4 x y
        destroy .s1 .s2 .s3 .s4
    } \
    -result {1.0 1.0 1.0 1.0}


catch {destroy .s}
































































































































































option clear

# cleanup
cleanupTests
return

Changes to tests/scrollbar.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# This file is a Tcl script to test out scrollbar widgets and
# the "scrollbar" command of Tk.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]
testConstraint nodeprecated [expr {"nodeprecated" ni [tk::pkgconfig list]}]

proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {
        # Only Windows has [testmetrics]
	if [string match v* [$w cget -orient]] {
	    return [expr {[winfo height $w] - 2*[testmetrics cyvscroll $w]}]
	} else {
	    return [expr {[winfo width $w] - 2*[testmetrics cxhscroll $w]}]
	}
    } else {
        if {[tk windowingsystem] eq "x11"} {
            # Calculations here assume that the arrow area is a square.
	    if [string match v* [$w cget -orient]] {
	        return [expr {[winfo height $w] \
		        - ([winfo width $w] \
			    - [$w cget -highlightthickness] \
			    - [$w cget -bd] + 1)*2}]
	    } else {
	        return [expr {[winfo width $w] \
		        - ([winfo height $w] \
			    - [$w cget -highlightthickness] \
			    - [$w cget -bd] + 1)*2}]
	    }
        } else {
            # macOS aqua
	    if [string match v* [$w cget -orient]] {
	        return [expr {[winfo height $w] \
			- ([$w cget -highlightthickness] \
			  +[$w cget -bd])*2}]
	    } else {
	        return [expr {[winfo width $w] \
			- ([$w cget -highlightthickness] \
			  +[$w cget -bd])*2}]
	    }
        }
    }

}

# XXX Note: this test file is woefully incomplete.  Right now there are
# only bits and pieces of tests.  Please make this file more complete
# as you fix bugs and add features.

foreach {width height} [wm minsize .] {
    set height [expr {($height < 200) ? 200 : $height}]
    set width [expr {($width < 1) ? 1 : $width}]
}

frame .f -height $height -width $width
pack .f -side left
scrollbar .s
pack .s -side right -fill y
update
set i 1
foreach test {
    {-activebackground #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-activerelief sunken sunken non-existent
	    {bad relief "non-existent": must be flat, groove, raised, ridge, solid, or sunken}}
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {bad screen distance "badValue"}}
    {-bg #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-command "set x" {set x} {} {}}
    {-elementborderwidth 4 4 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}
    {-highlightthickness -2 0 {} {}}
    {-jump true 1 silly {expected boolean value but got "silly"}}
    {-orient horizontal horizontal badValue
	    {bad orientation "badValue": must be vertical or horizontal}}
    {-orient horizontal horizontal bogus {bad orientation "bogus": must be vertical or horizontal}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-repeatdelay 140 140 129.3 {expected integer but got "129.3"}}
    {-repeatinterval 140 140 129.3 {expected integer but got "129.3"}}
    {-takefocus "any string" "any string" {} {}}
    {-troughcolor #432 #432 lousy {unknown color name "lousy"}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {
    lassign $test name value okResult badValue badResult




|
|
|






|
<
<








<

|

|


<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
>
|
<





|
|












|

















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
22

23
24
25
26
27
28


29
30
31
32
33
34
35
36
37
38
39










40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# This file is a Tcl script to test out scrollbar widgets and
# the "scrollbar" command of Tk.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]



proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {

	if [string match v* [$w cget -orient]] {
	    return [expr [winfo height $w] - 2*[testmetrics cyvscroll $w]]
	} else {
	    return [expr [winfo width $w] - 2*[testmetrics cxhscroll $w]]
	}
    } else {


	if [string match v* [$w cget -orient]] {
	    return [expr [winfo height $w] \
		    - ([winfo width $w] \
			- [$w cget -highlightthickness] \
			- [$w cget -bd] + 1)*2]
	} else {
	    return [expr [winfo width $w] \
		    - ([winfo height $w] \
			- [$w cget -highlightthickness] \
			- [$w cget -bd] + 1)*2]
	}










    }
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]


# XXX Note: this test file is woefully incomplete.  Right now there are
# only bits and pieces of tests.  Please make this file more complete
# as you fix bugs and add features.

foreach {width height} [wm minsize .] {
    set height [expr ($height < 200) ? 200 : $height]
    set width [expr ($width < 1) ? 1 : $width]
}

frame .f -height $height -width $width
pack .f -side left
scrollbar .s
pack .s -side right -fill y
update
set i 1
foreach test {
    {-activebackground #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-activerelief sunken sunken non-existent
	    {bad relief type "non-existent": must be flat, groove, raised, ridge, solid, or sunken}}
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {bad screen distance "badValue"}}
    {-bg #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-command "set x" {set x} {} {}}
    {-elementborderwidth 4 4 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}
    {-highlightthickness -2 0 {} {}}
    {-jump true 1 silly {expected boolean value but got "silly"}}
    {-orient horizontal horizontal badValue
	    {bad orientation "badValue": must be vertical or horizontal}}
    {-orient horizontal horizontal bogus {bad orientation "bogus": must be vertical or horizontal}}
    {-relief ridge ridge badValue {bad relief type "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-repeatdelay 140 140 129.3 {expected integer but got "129.3"}}
    {-repeatinterval 140 140 129.3 {expected integer but got "129.3"}}
    {-takefocus "any string" "any string" {} {}}
    {-troughcolor #432 #432 lousy {unknown color name "lousy"}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {
    lassign $test name value okResult badValue badResult
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    }
    .s configure $name [lindex [.s configure $name] 3]
}

destroy .s
test scrollbar-2.1 {Tk_ScrollbarCmd procedure} -returnCodes error -body {
    scrollbar
} -result {wrong # args: should be "scrollbar pathName ?-option value ...?"}
test scrollbar-2.2 {Tk_ScrollbarCmd procedure} -body {
    scrollbar gorp
} -returnCodes error -result {bad window path name "gorp"}
test scrollbar-2.3 {Tk_ScrollbarCmd procedure} -setup {
    scrollbar .s
} -body {
    list [winfo class .s] [info command .s]







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    }
    .s configure $name [lindex [.s configure $name] 3]
}

destroy .s
test scrollbar-2.1 {Tk_ScrollbarCmd procedure} -returnCodes error -body {
    scrollbar
} -result {wrong # args: should be "scrollbar pathName ?options?"}
test scrollbar-2.2 {Tk_ScrollbarCmd procedure} -body {
    scrollbar gorp
} -returnCodes error -result {bad window path name "gorp"}
test scrollbar-2.3 {Tk_ScrollbarCmd procedure} -setup {
    scrollbar .s
} -body {
    list [winfo class .s] [info command .s]
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
} -result .s

scrollbar .s -orient vertical -command scroll -highlightthickness 2 -bd 2
pack .s -side right -fill y
update
test scrollbar-3.1 {ScrollbarWidgetCmd procedure} {
    list [catch {.s} msg] $msg
} {1 {wrong # args: should be ".s option ?arg ...?"}}
test scrollbar-3.2 {ScrollbarWidgetCmd procedure, "cget" option} {
    list [catch {.s cget} msg] $msg
} {1 {wrong # args: should be ".s cget option"}}
test scrollbar-3.3 {ScrollbarWidgetCmd procedure, "cget" option} {
    list [catch {.s cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test scrollbar-3.4 {ScrollbarWidgetCmd procedure, "activate" option} {







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
} -result .s

scrollbar .s -orient vertical -command scroll -highlightthickness 2 -bd 2
pack .s -side right -fill y
update
test scrollbar-3.1 {ScrollbarWidgetCmd procedure} {
    list [catch {.s} msg] $msg
} {1 {wrong # args: should be ".s option ?arg arg ...?"}}
test scrollbar-3.2 {ScrollbarWidgetCmd procedure, "cget" option} {
    list [catch {.s cget} msg] $msg
} {1 {wrong # args: should be ".s cget option"}}
test scrollbar-3.3 {ScrollbarWidgetCmd procedure, "cget" option} {
    list [catch {.s cget -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
test scrollbar-3.4 {ScrollbarWidgetCmd procedure, "activate" option} {
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
} {}
test scrollbar-3.14.1 {ScrollbarWidgetCmd procedure, "cget" option} emptyTest {
    # empty test; duplicated scrollbar-3.13
} {}
destroy .s2
test scrollbar-3.15 {ScrollbarWidgetCmd procedure, "configure" option} {
    llength [.s configure]
} 20
test scrollbar-3.16 {ScrollbarWidgetCmd procedure, "configure" option} {
    list [catch {.s configure -bad} msg] $msg
} {1 {unknown option "-bad"}}
test scrollbar-3.17 {ScrollbarWidgetCmd procedure, "configure" option} {
    .s configure -orient
} {-orient orient Orient vertical vertical}
test scrollbar-3.18 {ScrollbarWidgetCmd procedure, "configure" option} {







|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
} {}
test scrollbar-3.14.1 {ScrollbarWidgetCmd procedure, "cget" option} emptyTest {
    # empty test; duplicated scrollbar-3.13
} {}
destroy .s2
test scrollbar-3.15 {ScrollbarWidgetCmd procedure, "configure" option} {
    llength [.s configure]
} {20}
test scrollbar-3.16 {ScrollbarWidgetCmd procedure, "configure" option} {
    list [catch {.s configure -bad} msg] $msg
} {1 {unknown option "-bad"}}
test scrollbar-3.17 {ScrollbarWidgetCmd procedure, "configure" option} {
    .s configure -orient
} {-orient orient Orient vertical vertical}
test scrollbar-3.18 {ScrollbarWidgetCmd procedure, "configure" option} {
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.24 {ScrollbarWidgetCmd procedure, "delta" option} {
    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.25 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 20 0]
} 0
test scrollbar-3.26 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 20]
} [format %.6g [expr {20.0/([getTroughSize .s]-1)}]]
test scrollbar-3.27 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 -20]
} [format %.6g [expr {-20.0/([getTroughSize .s]-1)}]]
test scrollbar-3.28 {ScrollbarWidgetCmd procedure, "delta" option} {
    toplevel .t -width 250 -height 100
    wm geom .t +0+0
    scrollbar .t.s -orient horizontal -borderwidth 2
    place .t.s -width 201
    update
    set result [list [format {%.6g} [.t.s delta 0 20]] \
	    [format {%.6g} [.t.s delta [expr {[getTroughSize .t.s] - 1}] 0]]]
    destroy .t
    set result
} {0 1}
test scrollbar-3.29 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24} msg] $msg
} {1 {wrong # args: should be ".s fraction x y"}}
test scrollbar-3.30 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24 30 32} msg] $msg
} {1 {wrong # args: should be ".s fraction x y"}}
test scrollbar-3.31 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction silly 24} msg] $msg
} {1 {expected integer but got "silly"}}
test scrollbar-3.32 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.33 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 0]
} 0
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} 1
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr {(21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 179]
} 1
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s]}]]
} 1
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr {
    [format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s] - 2}]]]
	== [format %g [expr {(200.0 - [testmetrics cyvscroll .s]*2 - 2)
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)}]]}
} 1

toplevel .t -width 250 -height 100
wm geom .t +0+0
scrollbar .t.s -orient horizontal -borderwidth 2
place .t.s -width 201
update

test scrollbar-3.41 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0.5}
if {[testConstraint testmetrics]} {
    # Only Windows has [testmetrics]
    place configure .t.s -width [expr {2*[testmetrics cxhscroll .t.s]+1}]
} else {
    if {[tk windowingsystem] eq "x11"} {
        place configure .t.s -width [expr {[winfo height .t.s] - 2*([.t.s cget -highlightthickness] + [.t.s cget -bd] + 1)}]
    } else {
        # macOS aqua
        place configure .t.s -width [expr {2*([.t.s cget -highlightthickness] + [.t.s cget -bd])}]
    }
}
update
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} 0
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
    list [catch {.s get a} msg] $msg
} {1 {wrong # args: should be ".s get"}}
test scrollbar-3.44 {ScrollbarWidgetCmd procedure, "get" option} nodeprecated {
    .s set 100 10 13 14
    .s get
} {100 10 13 14}
test scrollbar-3.45 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 0.6 0.8
    set result {}
    foreach element [.s get] {







|


|


|







|

















|


|


|
|
|

|

|
|
|



|
|
|
|












<
|

<
<
<
<
|
<




|




|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289




290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.24 {ScrollbarWidgetCmd procedure, "delta" option} {
    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.25 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 20 0]
} {0}
test scrollbar-3.26 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 20]
} [format %.6g [expr 20.0/([getTroughSize .s]-1)]]
test scrollbar-3.27 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 -20]
} [format %.6g [expr -20.0/([getTroughSize .s]-1)]]
test scrollbar-3.28 {ScrollbarWidgetCmd procedure, "delta" option} {
    toplevel .t -width 250 -height 100
    wm geom .t +0+0
    scrollbar .t.s -orient horizontal -borderwidth 2
    place .t.s -width 201
    update
    set result [list [format {%.6g} [.t.s delta 0 20]] \
	    [format {%.6g} [.t.s delta [expr [getTroughSize .t.s] - 1] 0]]]
    destroy .t
    set result
} {0 1}
test scrollbar-3.29 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24} msg] $msg
} {1 {wrong # args: should be ".s fraction x y"}}
test scrollbar-3.30 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24 30 32} msg] $msg
} {1 {wrong # args: should be ".s fraction x y"}}
test scrollbar-3.31 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction silly 24} msg] $msg
} {1 {expected integer but got "silly"}}
test scrollbar-3.32 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.33 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 0]
} {0}
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} {1}
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr (21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {unix failsOnUbuntu failsOnQuarz} {
    format {%.6g} [.s fraction 4 179]
} {1}
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s]]]
} {1}
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {unix failsOnUbuntu failsOnQuarz} {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr \
    [format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s] - 2]]] \
	== [format %g [expr (200.0 - [testmetrics cyvscroll .s]*2 - 2) \
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)]]
} 1

toplevel .t -width 250 -height 100
wm geom .t +0+0
scrollbar .t.s -orient horizontal -borderwidth 2
place .t.s -width 201
update

test scrollbar-3.41 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0.5}
if {[testConstraint testmetrics]} {

    place configure .t.s -width [expr 2*[testmetrics cxhscroll .t.s]+1]
} else {




    place configure .t.s -width [expr [winfo reqwidth .t.s] - 4]

}
update
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0}
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
    list [catch {.s get a} msg] $msg
} {1 {wrong # args: should be ".s get"}}
test scrollbar-3.44 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 100 10 13 14
    .s get
} {100 10 13 14}
test scrollbar-3.45 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 0.6 0.8
    set result {}
    foreach element [.s get] {
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
} {1 {wrong # args: should be ".s identify x y"}}
test scrollbar-3.48 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify bogus 2} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 5
} {arrow1}
test scrollbar-3.50.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 5
} {trough1}
test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 195
} {arrow2}
test scrollbar-3.54.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 195
} {trough2}
test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg
} {1 {expected floating-point number but got "abc"}}
test scrollbar-3.58 {ScrollbarWidgetCmd procedure, "set" option} {







|


<
<
<
<










|


<
<
<
<







317
318
319
320
321
322
323
324
325
326




327
328
329
330
331
332
333
334
335
336
337
338
339




340
341
342
343
344
345
346
} {1 {wrong # args: should be ".s identify x y"}}
test scrollbar-3.48 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify bogus 2} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 5
} {arrow1}




test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54 {ScrollbarWidgetCmd procedure, "identify" option} {unixOrPc} {
    .s identify 5 195
} {arrow2}




test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg
} {1 {expected floating-point number but got "abc"}}
test scrollbar-3.58 {ScrollbarWidgetCmd procedure, "set" option} {
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    .s set .4 .3
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result
} {0.4 0.4}
test scrollbar-3.64 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set abc def ghi jkl} msg] $msg
} {1 {expected integer but got "abc"}}
test scrollbar-3.65 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 def ghi jkl} msg] $msg
} {1 {expected integer but got "def"}}
test scrollbar-3.66 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 ghi jkl} msg] $msg
} {1 {expected integer but got "ghi"}}
test scrollbar-3.67 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 3 jkl} msg] $msg
} {1 {expected integer but got "jkl"}}
test scrollbar-3.68 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set -10 50 20 30
    .s get
} {0 50 0 0}
test scrollbar-3.69 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 -10 20 30
    .s get
} {100 0 20 30}
test scrollbar-3.70 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 50 30 20
    .s get
} {100 50 30 30}
test scrollbar-3.71 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.72 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3 4 5} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.73 {ScrollbarWidgetCmd procedure} {
    list [catch {.s bogus} msg] $msg
} {1 {bad option "bogus": must be activate, cget, configure, delta, fraction, get, identify, or set}}
test scrollbar-3.74 {ScrollbarWidgetCmd procedure} {
    list [catch {.s c} msg] $msg
} {1 {ambiguous option "c": must be activate, cget, configure, delta, fraction, get, identify, or set}}

test scrollbar-4.1 {ScrollbarEventProc procedure} {
    catch {destroy .s1}
    scrollbar .s1 -bg #543210
    rename .s1 .s2
    set x {}
    lappend x [winfo exists .s1]







|


|


|


|


|



|



|





|


|





|







370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    .s set .4 .3
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result
} {0.4 0.4}
test scrollbar-3.64 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def ghi jkl} msg] $msg
} {1 {expected integer but got "abc"}}
test scrollbar-3.65 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 def ghi jkl} msg] $msg
} {1 {expected integer but got "def"}}
test scrollbar-3.66 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 ghi jkl} msg] $msg
} {1 {expected integer but got "ghi"}}
test scrollbar-3.67 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3 jkl} msg] $msg
} {1 {expected integer but got "jkl"}}
test scrollbar-3.68 {ScrollbarWidgetCmd procedure, "set" option} {
    .s set -10 50 20 30
    .s get
} {0 50 0 0}
test scrollbar-3.69 {ScrollbarWidgetCmd procedure, "set" option} {
    .s set 100 -10 20 30
    .s get
} {100 0 20 30}
test scrollbar-3.70 {ScrollbarWidgetCmd procedure, "set" option} {
    .s set 100 50 30 20
    .s get
} {100 50 30 30}
test scrollbar-3.71 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction" or ".s set totalUnits windowUnits firstUnit lastUnit"}}
test scrollbar-3.72 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3 4 5} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction" or ".s set totalUnits windowUnits firstUnit lastUnit"}}
test scrollbar-3.73 {ScrollbarWidgetCmd procedure} {
    list [catch {.s bogus} msg] $msg
} {1 {bad option "bogus": must be activate, cget, configure, delta, fraction, get, identify, or set}}
test scrollbar-3.74 {ScrollbarWidgetCmd procedure} {
    list [catch {.s c} msg] $msg
} {1 {bad option "c": must be activate, cget, configure, delta, fraction, get, identify, or set}}

test scrollbar-4.1 {ScrollbarEventProc procedure} {
    catch {destroy .s1}
    scrollbar .s1 -bg #543210
    rename .s1 .s2
    set x {}
    lappend x [winfo exists .s1]
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548




549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
test scrollbar-6.4 {ScrollbarPosition procedure} unix {
    .s identify 3 100
} {}
test scrollbar-6.6 {ScrollbarPosition procedure} unix {
    .s identify 19 100
} {}
test scrollbar-6.7 {ScrollbarPosition procedure} {
    .s identify [expr {[winfo width .s] / 2}] -1
} {}
test scrollbar-6.8 {ScrollbarPosition procedure} {
    .s identify [expr {[winfo width .s] / 2}] [winfo height .s]
} {}
test scrollbar-6.9 {ScrollbarPosition procedure} {
    .s identify -1 [expr {[winfo height .s] / 2}]
} {}
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr {[winfo height .s] / 2}]
} {}
test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 4
} {arrow1}
test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {
    .s identify 8 19
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 19
} {trough1}
test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] 0
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {[testmetrics cyvscroll .s] - 1}]
} {arrow1}
test scrollbar-6.16 {ScrollbarPosition procedure} unix {
    .s identify 8 20
} {trough1}
test scrollbar-6.17 {ScrollbarPosition procedure} {unix nonPortable} {
    # Don't know why this is non-portable, but it doesn't work on
    # some platforms.
    .s identify 8 51
} {trough1}
test scrollbar-6.18 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [testmetrics cyvscroll .s]
} {trough1}
test scrollbar-6.19 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {int(.2 / [.s delta 0 1])
						+ [testmetrics cyvscroll .s] - 1}]
} {trough1}
test scrollbar-6.20 {ScrollbarPosition procedure} unix {
    .s identify 8 52
} {slider}
test scrollbar-6.21 {ScrollbarPosition procedure} {unix nonPortable} {
    # Don't know why this is non-portable, but it doesn't work on
    # some platforms.
    .s identify 8 83
} {slider}
test scrollbar-6.22 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] \
	[expr {int(.2 / [.s delta 0 1] + 0.5) + [testmetrics cyvscroll .s]}]
} {slider}
test scrollbar-6.23 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {int(.4 / [.s delta 0 1])
						 + [testmetrics cyvscroll .s] - 1}]
} {slider}
test scrollbar-6.24 {ScrollbarPosition procedure} unix {
    .s identify 8 84
} {trough2}
test scrollbar-6.25 {ScrollbarPosition procedure} unix {
    .s identify 8 179
} {trough2}
test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win} {




    .s identify [expr {[winfo width .s] / 2}] [expr {int(.4 / [.s delta 0 1])
						 + [testmetrics cyvscroll .s]}]
} {trough2}
test scrollbar-6.28 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {[winfo height .s]
						 - [testmetrics cyvscroll .s] - 1}]
} {trough2}
test scrollbar-6.29.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {
    .s identify 8 180
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 180
} {trough2}
test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 195
} {arrow2}
test scrollbar-6.30.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 195
} {trough2}
test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}]  [expr {[winfo height .s]
						  - [testmetrics cyvscroll .s]}]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] [expr {[winfo height .s] - 1}]
} {arrow2}
test scrollbar-6.34 {ScrollbarPosition procedure} unix {
    .s identify 4 100
} {trough2}
test scrollbar-6.35 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {
    .s identify 18 100
} {trough2}
test scrollbar-6.37 {ScrollbarPosition procedure} win {
    .s identify 0 100
} {trough2}
test scrollbar-6.38 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] - 1}] 100
} {trough2}

catch {destroy .t}
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 4 8
} {arrow1}
test scrollbar-6.39.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 4 8
} {trough1}
test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr {[winfo height .t.s] / 2}]
} {arrow1}
test scrollbar-6.41.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 82 8
} {slider}
test scrollbar-6.41.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 82 8
} {trough2}
test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr {int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s]
		       - 1}] [expr {[winfo height .t.s] / 2}]
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {
    .t.s identify 100 18
} {trough2}
test scrollbar-6.46 {ScrollbarPosition procedure} win {
    .t.s identify 100 [expr {[winfo height .t.s] - 1}]
} {trough2}

test scrollbar-7.1 {EventuallyRedraw} {
    .s configure -orient horizontal
    update
    set result [.s cget -orient]
    .s configure -orient vertical
    update
    lappend result [.s cget -orient]
} {horizontal vertical}

catch {destroy .t}
toplevel .t
wm geometry .t +0+0
test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} notAqua {
    # constrained by notAqua because this test clicks on an arrow of the
    # scrollbar - but macOS has no such arrows in modern scrollbars
    proc doit {args} { destroy .t.f }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
    wm geometry .t 100x100
    .t.f.s set 0 .5
    update
    set result [winfo exists .t.f.s]
    event generate .t.f.s <Button> -button 1 -x [expr {[winfo width .t.f.s] / 2}] -y 5
    event generate .t <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 0}
test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} notAqua {
    # constrained by notAqua because this test clicks on an arrow of the
    # scrollbar - but macOS has no such arrows in modern scrollbars
    proc doit {args} { destroy .t.f.s }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
    wm geometry .t 100x100
    .t.f.s set 0 .5
    update
    set result [winfo exists .t.f.s]
    event generate .t.f.s <Button> -button 1 -x [expr {[winfo width .t.f.s] / 2}] -y 5
    event generate .t.f <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 1}

set l [interp hidden]
deleteWindows

test scrollbar-9.1 {scrollbar widget vs hidden commands} {
    catch {destroy .s}
    scrollbar .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]

test scrollbar-10.1 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
test scrollbar-10.2.3 {<MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}

test scrollbar-11.1 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body {
    proc destroy_scrollbar {} {
        if {[winfo exists .top.s]} {
            destroy .top.s
        }
    }
    toplevel .top
    scrollbar .top.s
    bind .top.s <Button-2> {destroy_scrollbar}
    pack .top.s
    focus -force .top.s
    update
    event generate .top.s <Button-2>
    update  ; # shall not trigger error  invalid command name ".top.s"
} -cleanup {
    destroy .top.s .top
} -result {}
test scrollbar-11.2 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body {
    proc destroy_scrollbar {{y 0}} {
        if {[winfo exists .top.s]} {
            destroy .top.s
        }
    }
    toplevel .top
    wm minsize .top 50 400
    update
    scrollbar .top.s
    bind .top.s <Button-2> {after idle destroy_scrollbar}
    pack .top.s -expand true -fill y
    focus -force .top.s
    update
    event generate .top.s <Button-2> -x 2 -y [expr {[winfo height .top.s] / 2}]
    update  ; # shall not trigger error  invalid command name ".top.s"
} -cleanup {
    destroy .top.s .top
} -result {}

catch {destroy .s}
catch {destroy .t}

# cleanup
cleanupTests
return







|


|


|


|

|


|
<
<
<
<


<
<
<
<

|


|










|


|
|










|
|


|
|







|
>
>
>
>
|
|


|
|

|


<
<
<
<
|


<
<
<
<

|
|


|




|






|










|


<
<
<
<

|

|


<
<
<
<

|
|

|


|
|














|
<
<











|






|
<
<











|


















|














|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465




466
467




468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525




526
527
528




529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559




560
561
562
563
564
565




566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589


590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608


609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667



















































668
669
670
671
672
673
674
test scrollbar-6.4 {ScrollbarPosition procedure} unix {
    .s identify 3 100
} {}
test scrollbar-6.6 {ScrollbarPosition procedure} unix {
    .s identify 19 100
} {}
test scrollbar-6.7 {ScrollbarPosition procedure} {
    .s identify [expr [winfo width .s] / 2] -1
} {}
test scrollbar-6.8 {ScrollbarPosition procedure} {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s]]
} {}
test scrollbar-6.9 {ScrollbarPosition procedure} {
    .s identify -1 [expr [winfo height .s] / 2]
} {}
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr [winfo height .s] / 2]
} {}
test scrollbar-6.11 {ScrollbarPosition procedure} unix {
    .s identify 8 4
} {arrow1}
test scrollbar-6.12 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnQuarz} {




    .s identify 8 19
} {arrow1}




test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] 0
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [testmetrics cyvscroll .s] - 1]
} {arrow1}
test scrollbar-6.16 {ScrollbarPosition procedure} unix {
    .s identify 8 20
} {trough1}
test scrollbar-6.17 {ScrollbarPosition procedure} {unix nonPortable} {
    # Don't know why this is non-portable, but it doesn't work on
    # some platforms.
    .s identify 8 51
} {trough1}
test scrollbar-6.18 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [testmetrics cyvscroll .s]
} {trough1}
test scrollbar-6.19 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr int(.2 / [.s delta 0 1]) \
						+ [testmetrics cyvscroll .s] - 1]
} {trough1}
test scrollbar-6.20 {ScrollbarPosition procedure} unix {
    .s identify 8 52
} {slider}
test scrollbar-6.21 {ScrollbarPosition procedure} {unix nonPortable} {
    # Don't know why this is non-portable, but it doesn't work on
    # some platforms.
    .s identify 8 83
} {slider}
test scrollbar-6.22 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] \
	[expr int(.2 / [.s delta 0 1] + 0.5) + [testmetrics cyvscroll .s]]
} {slider}
test scrollbar-6.23 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr int(.4 / [.s delta 0 1]) \
						 + [testmetrics cyvscroll .s] - 1]
} {slider}
test scrollbar-6.24 {ScrollbarPosition procedure} unix {
    .s identify 8 84
} {trough2}
test scrollbar-6.25 {ScrollbarPosition procedure} unix {
    .s identify 8 179
} {trough2}
test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win knownBug} {
    # This asks for 8,21, which is actually the slider, but there is a
    # bug in that GetSystemMetrics(SM_CYVTHUMB) actually returns a value
    # that is larger than the thumb displayed, skewing the ability to
    # calculate the trough2 area correctly (Win2k).  -- hobbs
    .s identify [expr [winfo width .s] / 2] [expr int(.4 / [.s delta 0 1]) \
						 + [testmetrics cyvscroll .s]]
} {trough2}
test scrollbar-6.28 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] \
						 - [testmetrics cyvscroll .s] - 1]
} {trough2}
test scrollbar-6.29 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnQuarz} {
    .s identify 8 180
} {arrow2}




test scrollbar-6.30 {ScrollbarPosition procedure} unix {
    .s identify 8 195
} {arrow2}




test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2]  [expr [winfo height .s] \
						  - [testmetrics cyvscroll .s]]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] - 1]
} {arrow2}
test scrollbar-6.34 {ScrollbarPosition procedure} unix {
    .s identify 4 100
} {trough2}
test scrollbar-6.35 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnQuarz} {
    .s identify 18 100
} {trough2}
test scrollbar-6.37 {ScrollbarPosition procedure} win {
    .s identify 0 100
} {trough2}
test scrollbar-6.38 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] - 1] 100
} {trough2}

catch {destroy .t}
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39 {ScrollbarPosition procedure} unix {
    .t.s identify 4 8
} {arrow1}




test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr [winfo height .t.s] / 2]
} {arrow1}
test scrollbar-6.41 {ScrollbarPosition procedure} unix {
    .t.s identify 82 8
} {slider}




test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s] \
		       - 1] [expr [winfo height .t.s] / 2]
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnQuarz} {
    .t.s identify 100 18
} {trough2}
test scrollbar-6.45 {ScrollbarPosition procedure} win {
    .t.s identify 100 [expr [winfo height .t.s] - 1]
} {trough2}

test scrollbar-7.1 {EventuallyRedraw} {
    .s configure -orient horizontal
    update
    set result [.s cget -orient]
    .s configure -orient vertical
    update
    lappend result [.s cget -orient]
} {horizontal vertical}

catch {destroy .t}
toplevel .t
wm geometry .t +0+0
test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} {


    proc doit {args} { destroy .t.f }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
    wm geometry .t 100x100
    .t.f.s set 0 .5
    update
    set result [winfo exists .t.f.s]
    event generate .t.f.s <ButtonPress> -button 1 -x [expr [winfo width .t.f.s] / 2] -y 5
    event generate .t <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 0}
test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} {


    proc doit {args} { destroy .t.f.s }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
    wm geometry .t 100x100
    .t.f.s set 0 .5
    update
    set result [winfo exists .t.f.s]
    event generate .t.f.s <ButtonPress> -button 1 -x [expr [winfo width .t.f.s] / 2] -y 5
    event generate .t.f <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 1}

set l [interp hidden]
deleteWindows

test scrollbar-9.1 {scrollbar widget vs hidden commands} {
    catch {destroy .s}
    scrollbar .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]

test scrollbar-10.1 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}




















































catch {destroy .s}
catch {destroy .t}

# cleanup
cleanupTests
return

Changes to tests/select.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# This file is a Tcl script to test out Tk's selection management code,
# especially the "selection" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display selection handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#

package require tcltest 2.2
namespace import ::tcltest::*
namespace import ::tk::test:loadTkCommand
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint cliboardManagerPresent 0
if {![catch {selection get -selection CLIPBOARD_MANAGER -type TARGETS}]} {
    if {"SAVE_TARGETS" in [selection get -selection CLIPBOARD_MANAGER -type TARGETS]} {
        testConstraint cliboardManagerPresent 1
    }
}
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
    global selValue selInfo
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr {$numBytes+$offset}]
}

proc errIncrHandler {type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    # Just sizing the selection;  don't do anything here.
	    set pass 1
	} else {
	    # Fetching the selection;  wait long enough to cause a timeout.
	    after 6000
	}
    }
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr {$numBytes+$offset}]
}

proc errHandler args {
    error "selection handler aborted"
}

proc badHandler {path type offset count} {
    global selValue selInfo
    selection handle -type $type $path {}
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr {$numBytes+$offset}]
}
proc reallyBadHandler {path type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    set pass 1
	} else {
	    selection handle -type $type $path {}
	}
    }
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr {$numBytes+$offset}]
}

# Eliminate any existing selection on the screen.  This is needed in case
# there is a selection in some other application, in order to prevent races
# from causing false errors in the tests below.

selection clear .

|
|

|
|








<
<



|
<
<
<
<
<
<













|


















|














|















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18






19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# This file is a Tcl script to test out Tk's selection management code,
# especially the "selection" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display selection handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#

package require tcltest 2.2


eval tcltest::configure $argv
tcltest::loadTestedCommands

namespace import -force ::tk::test:loadTkCommand







global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
    global selValue selInfo
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errIncrHandler {type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    # Just sizing the selection;  don't do anything here.
	    set pass 1
	} else {
	    # Fetching the selection;  wait long enough to cause a timeout.
	    after 6000
	}
    }
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errHandler args {
    error "selection handler aborted"
}

proc badHandler {path type offset count} {
    global selValue selInfo
    selection handle -type $type $path {}
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}
proc reallyBadHandler {path type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    set pass 1
	} else {
	    selection handle -type $type $path {}
	}
    }
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

# Eliminate any existing selection on the screen.  This is needed in case
# there is a selection in some other application, in order to prevent races
# from causing false errors in the tests below.

selection clear .
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221




222






















223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496




497
498
499
500
501
502
503
504
505
506
507




508
509
510
511
512
513
514
515
516
517
518




519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951

952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048


1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152


1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# Now we start the main body of the test code

test select-1.1 {Tk_CreateSelHandler procedure} -setup {
    setup
} -body {
    lsort [selection get TARGETS]
} -result {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.2 {Tk_CreateSelHandler procedure} -setup {
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    lsort [selection get TARGETS]
} -result {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.3 {Tk_CreateSelHandler procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-1.4.1 {Tk_CreateSelHandler procedure} -constraints unix -setup {
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    lsort [selection get TARGETS]
} -result {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}
test select-1.4.2 {Tk_CreateSelHandler procedure} -constraints win -setup {
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    lsort [selection get TARGETS]
} -result {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.5 {Tk_CreateSelHandler procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    list [selection get] $selInfo
} -result {{} {STRING 0 4000}}
test select-1.6.1 {Tk_CreateSelHandler procedure} -constraints unix -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    selection get
    selection get -type TEST
    selection handle .f1 {handler TEST2} TEST
    selection get -type TEST
    list $selInfo [lsort [selection get TARGETS]]
} -result {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}}
test select-1.6.2 {Tk_CreateSelHandler procedure} -constraints win -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    selection get
    selection get -type TEST
    selection handle .f1 {handler TEST2} TEST
    selection get -type TEST
    list $selInfo [lsort [selection get TARGETS]]
} -result {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.7.1 {Tk_CreateSelHandler procedure} -constraints unix -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    selection handle -selection CLIPBOARD .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f1 {handler TEST2} STRING
    list [lsort [selection get -selection PRIMARY TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} -result {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.7.2 {Tk_CreateSelHandler procedure} -constraints win -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    selection handle -selection CLIPBOARD .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f1 {handler TEST2} STRING
    list [lsort [selection get -selection PRIMARY TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} -result {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.8 {Tk_CreateSelHandler procedure} -setup {
    setup
} -body {
    selection handle -format INTEGER -type TEST .f1 {handler TEST}
    lsort [selection get TARGETS]
} -result {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}

##############################################################################

test select-2.1 {Tk_DeleteSelHandler procedure} -constraints unix -setup {
    setup




} -body {






















    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type TEST .f1 {}
    lappend result [lsort [selection get TARGETS]]
} -result {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING}}
test select-2.2 {Tk_DeleteSelHandler procedure} -constraints unix -setup {
    setup
} -body {
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type USER .f1 {}
    lappend result [lsort [selection get TARGETS]]
} -result {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}}
test select-2.3 {Tk_DeleteSelHandler procedure} -constraints unix -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    selection handle -selection PRIMARY .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {}
    list [lsort [selection get TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} -result {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.4 {Tk_DeleteSelHandler procedure} -constraints win -setup {
    setup
} -body {
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type TEST .f1 {}
    lappend result [lsort [selection get TARGETS]]
} -result {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER}}
test select-2.5 {Tk_DeleteSelHandler procedure} -constraints win -setup {
    setup
} -body {
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type USER .f1 {}
    lappend result [lsort [selection get TARGETS]]
} -result {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.6 {Tk_DeleteSelHandler procedure} -constraints win -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    selection handle -selection PRIMARY .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {}
    list [lsort [selection get TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} -result {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.7 {Tk_DeleteSelHandler procedure} -setup {
    setup
} -body {
    selection handle .f1 {handler STRING}
    list [selection handle .f1 {}] [selection handle .f1 {}]
} -result {{} {}}

##############################################################################

test select-3.1 {Tk_OwnSelection procedure} -setup {
    setup
} -body {
    selection own
} -result {.f1}
test select-3.2 {Tk_OwnSelection procedure} -body {
    setup .f1
    set result [selection own]
    setup .f2
    lappend result [selection own]
} -result {.f1 .f2}
test select-3.3 {Tk_OwnSelection procedure} -setup {
    setup .f1
    setup .f2
} -body {
    selection own -selection CLIPBOARD .f1
    list [selection own] [selection own -selection CLIPBOARD]
} -result {.f2 .f1}
test select-3.4 {Tk_OwnSelection procedure} -setup {
    global lostSel
    setup
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost} } .f1
    selection clear .f1
    set lostSel
} -result {lost}
test select-3.5 {Tk_OwnSelection procedure} -setup {
    global lostSel
    setup .f1
    setup .f2
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f2
    list $lostSel [selection own]
} -result {lost1 .f2}
test select-3.6 {Tk_OwnSelection procedure} -setup {
    global lostSel
    setup
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f1
    set result $lostSel
    selection clear .f1
    lappend result $lostSel
} -result {owned lost2}
test select-3.7 {Tk_OwnSelection procedure} -constraints x11 -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
    set result {}
    lappend result [dobg { selection own . }]
    lappend result [dobg {selection own}]
    update
    cleanupbg
    lappend result $lostSel
} -result {{} . lost1}
# check reentrancy on selection replacement
test select-3.8 {Tk_OwnSelection procedure} -setup {
    setup
} -body {
    selection own -selection CLIPBOARD -command { destroy .f1 } .f1
    selection own -selection CLIPBOARD .
} -result {}
test select-3.9 {Tk_OwnSelection procedure} -setup {
    setup .f2
    setup .f1
} -body {
    selection own -selection CLIPBOARD -command { destroy .f2 } .f1
    selection own -selection CLIPBOARD .f2
} -result {}
# multiple display tests
test select-3.10 {Tk_OwnSelection procedure} -constraints {
    altDisplay
} -body {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    list [selection own -displayof .f1] [selection own -displayof .f2]
} -result {.f1 .f2}
test select-3.11 {Tk_OwnSelection procedure} -constraints {
    altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
    update
    set result ""
} -body {
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection own .t; update"]
    lappend result [selection own -displayof .f1] \
	    [selection own -displayof .f2]
} -cleanup {
    cleanupbg

} -result {{} .f1 {}}

##############################################################################

test select-4.1 {Tk_ClearSelection procedure} -setup {
    setup
} -body {
    set result [selection own]
    selection clear .f1
    lappend result [selection own]
} -result {.f1 {}}
test select-4.2 {Tk_ClearSelection procedure} -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    selection clear .f1
    selection own -selection CLIPBOARD
} -result {.f1}
test select-4.3 {Tk_ClearSelection procedure} -setup {
    setup
} -body {
    list [selection clear .f1] [selection clear .f1]
} -result {{} {}}
test select-4.4 {Tk_ClearSelection procedure} -constraints x11 -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
    set result {}
    lappend result [dobg {selection clear; update}]
    update
    cleanupbg
    lappend result [selection own]
} -result {{} {}}
# multiple display tests
test select-4.5 {Tk_ClearSelection procedure} -constraints {
    altDisplay
} -setup {
    global lostSel lostSel2
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
} -body {
    set lostSel {owned}
    set lostSel2 {owned2}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel2 {lost2} } .f2
    update
    selection clear -displayof .f2
    update
    list $lostSel $lostSel2
} -result {owned lost2}
test select-4.6 {Tk_ClearSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    set lostSel {owned}
    set lostSel2 {owned2}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel2 {lost2} } .f2
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection own .t; update"]
    lappend result [selection own -displayof .f1] \
	    [selection own -displayof .f2] $lostSel $lostSel2
    cleanupbg
    set result
} -result {{} .f1 {} owned lost2}

##############################################################################

test select-5.1 {Tk_GetSelection procedure} -returnCodes error -setup {
    setup
} -body {
    selection get TEST
} -result {PRIMARY selection doesn't exist or form "TEST" not defined}
test select-5.2 {Tk_GetSelection procedure} -setup {
    setup
} -body {
    selection get TK_WINDOW
} -result {.f1}
test select-5.3 {Tk_GetSelection procedure} -setup {
    setup
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-5.4 {Tk_GetSelection procedure} -setup {
    setup
} -returnCodes error -body {
    selection handle .f1 ERROR errHandler
    selection get ERROR
} -result {PRIMARY selection doesn't exist or form "ERROR" not defined}
test select-5.5 {Tk_GetSelection procedure} -setup {
    setup
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {handler STRING}
    list [selection get] $selInfo
} -result "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000}"
test select-5.6 {Tk_GetSelection procedure} -setup {




    setup
} -returnCodes error -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {apply {{type offset count} {
	selection handle .f1 {}
	handler $type $offset $count
    }} STRING}
    selection get
} -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test select-5.7 {Tk_GetSelection procedure} -setup {




    setup
} -returnCodes error -body {
    set selValue "Test Value"
    set selInfo ""
    selection handle .f1 {apply {{type offset count} {
	destroy .f1
	handler $type $offset $count
    }} STRING}
    selection get
} -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test select-5.8 {Tk_GetSelection procedure} -setup {




    setup
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {apply {{type offset count} {
	selection clear
	handler $type $offset $count
    }} STRING}
    list [selection get] $selInfo [catch {selection get} msg] $msg
} -result "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000} 1 {PRIMARY selection doesn't exist or form \"STRING\" not defined}"
test select-5.9 {Tk_GetSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-5.10 {Tk_GetSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    selection own .f1
    set result ""
    lappend result [dobg {selection get TEST} 1]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {}}
# multiple display tests
test select-5.11 {Tk_GetSelection procedure} -constraints {
    altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f2 {handler TEST2} TEST
    set selValue "Test value"
    set selInfo ""
    set result [list [selection get TEST] $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [selection get -displayof .f2 TEST] $selInfo
} -result {{Test value} {TEST 0 4000} {Test value2} {TEST2 0 4000}}
test select-5.12 {Tk_GetSelection procedure} -constraints {
    altDisplay
} -setup {
    global lostSel lostSel2
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f2 {} TEST
    set selValue "Test value"
    set selInfo ""
    set result [list [catch {selection get TEST} msg] $msg $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [catch {selection get -displayof .f2 TEST} msg] $msg \
	    $selInfo
} -result {0 {Test value} {TEST 0 4000} 1 {PRIMARY selection doesn't exist or form "TEST" not defined} {}}
test select-5.13 {Tk_GetSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
    selection handle -selection PRIMARY .f2 {handler TEST2} TEST
    selection own .f2
    set selValue "Test value"
    set selInfo ""
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {Test value2} {TEST2 0 4000 TEST 0 4000}}
test select-5.14 {Tk_GetSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
    selection handle -selection PRIMARY .f2 {} TEST
    selection own .f2
    set selValue "Test value"
    set selInfo ""
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "TEST" not defined} {Test value2} {TEST 0 4000}}
test select-5.15 {Tk_GetSelection procedure} -setup {
    setup
    if {[llength [info command ::bgerror]]} {
	rename ::bgerror ::TMPbgerror
    }
    set ::bgerrors {}
} -body {
    proc ::bgerror msg {lappend ::bgerrors $msg}
    selection handle -type ERROR .f1 errHandler
    list [catch {selection get ERROR} msg] $msg [update] {*}$::bgerrors
} -cleanup {
    rename ::bgerror {}
    if {[llength [info command ::TMPbgerror]]} {
	rename ::TMPbgerror ::bgerror
    }
} -result {1 {PRIMARY selection doesn't exist or form "ERROR" not defined} {} {selection handler aborted}}

##############################################################################

test select-6.1 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection
} -result {wrong # args: should be "selection option ?arg ...?"}
# selection clear
test select-6.2 {Tk_SelectionCmd procedure} -body {
    selection clear -selection
} -returnCodes error -result {value for "-selection" missing}
test select-6.3 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own .
    set result [selection own]
    selection clear -displayof .f1
    lappend result [selection own]
} -result {. {}}
test select-6.4 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    set result [list [selection own] [selection own -selection CLIPBOARD]]
    selection clear -selection CLIPBOARD .f1
    lappend result [selection own] [selection own -selection CLIPBOARD]
} -result {.f1 .f1 .f1 {}}
test select-6.5 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .
    set result [list [selection own] [selection own -selection CLIPBOARD]]
    selection clear -selection CLIPBOARD -displayof .f1
    lappend result [selection own] [selection own -selection CLIPBOARD]
} -result {.f1 . .f1 {}}
test select-6.6 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection clear -badopt foo
} -result {bad option "-badopt": must be -displayof or -selection}
test select-6.7 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection clear -selectionfoo foo
} -result {bad option "-selectionfoo": must be -displayof or -selection}
test select-6.8 {Tk_SelectionCmd procedure} -body {
    destroy .f2
    selection clear -displayof .f2
} -returnCodes error -result {bad window path name ".f2"}
test select-6.9 {Tk_SelectionCmd procedure} -body {
    destroy .f2
    selection clear .f2
} -returnCodes error -result {bad window path name ".f2"}
test select-6.10 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    set result [selection own -selection PRIMARY]
    selection clear
    lappend result [selection own -selection PRIMARY]
} -result {.f1 {}}
test select-6.11 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own -selection CLIPBOARD .f1
    set result [selection own -selection CLIPBOARD]
    selection clear -selection CLIPBOARD
    lappend result [selection own -selection CLIPBOARD]
} -result {.f1 {}}
test select-6.12 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection clear foo bar
} -result {wrong # args: should be "selection clear ?-option value ...?"}
# selection get
test select-6.13 {Tk_SelectionCmd procedure} -body {
    selection get -selection
} -returnCodes error -result {value for "-selection" missing}
test select-6.14 {Tk_SelectionCmd procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler TEST}
    set selValue "Test value"
    set selInfo ""
    list [selection get -displayof .f1] $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-6.15 {Tk_SelectionCmd procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler TEST}
    selection own -selection CLIPBOARD .f1
    set selValue "Test value"
    set selInfo ""
    list [selection get -selection CLIPBOARD] $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-6.16 {Tk_SelectionCmd procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type STRING .f1 {handler STRING}
    set selValue "Test value"
    set selInfo ""
    list [selection get -type TEST] $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-6.17 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection get -badopt foo
} -result {bad option "-badopt": must be -displayof, -selection, or -type}
test select-6.18 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection get -selectionfoo foo
} -result {bad option "-selectionfoo": must be -displayof, -selection, or -type}
test select-6.19 {Tk_SelectionCmd procedure} -body {
    catch { destroy .f2 }
    selection get -displayof .f2
} -returnCodes error -result {bad window path name ".f2"}
test select-6.20 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection get foo bar
} -result {wrong # args: should be "selection get ?-option value ...?"}
test select-6.21 {Tk_SelectionCmd procedure} -setup {
    global selValue selInfo
    setup
} -body {
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type STRING .f1 {handler STRING}
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} -result {{Test value} {TEST 0 4000}}
# selection handle
# most of the handle section has been covered earlier
test select-6.22 {Tk_SelectionCmd procedure} -body {
    selection handle -selection
} -returnCodes error -result {value for "-selection" missing}
test select-6.23 {Tk_SelectionCmd procedure} -setup {
    global selValue selInfo
    setup
} -body {
    set selValue "Test value"
    set selInfo ""
    list [selection handle -format INTEGER .f1 {handler TEST}] [selection get -displayof .f1] $selInfo
} -result {{} {Test value} {TEST 0 4000}}
test select-6.24 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection handle -badopt foo
} -result {bad option "-badopt": must be -format, -selection, or -type}
test select-6.25 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection handle -selectionfoo foo
} -result {bad option "-selectionfoo": must be -format, -selection, or -type}
test select-6.26 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection handle
} -result {wrong # args: should be "selection handle ?-option value ...? window command"}
test select-6.27 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection handle .
} -result {wrong # args: should be "selection handle ?-option value ...? window command"}
test select-6.28 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection handle . foo bar baz blat
} -result {wrong # args: should be "selection handle ?-option value ...? window command"}
test select-6.29 {Tk_SelectionCmd procedure} -body {
    catch { destroy .f2 }
    selection handle .f2 dummy
} -returnCodes error -result {bad window path name ".f2"}
# selection own
test select-6.30 {Tk_SelectionCmd procedure} -body {
    selection own -selection
} -returnCodes error -result {value for "-selection" missing}
test select-6.31 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own .
    selection own -displayof .f1
} -result {.}
test select-6.32 {Tk_SelectionCmd procedure} -setup {
    setup
} -body {
    selection own .
    selection own -selection CLIPBOARD .f1
    list [selection own] [selection own -selection CLIPBOARD]
} -result {. .f1}
test select-6.33 {Tk_SelectionCmd procedure} -setup {
    global lostSel
    setup
} -body {
    set lostSel owned
    selection own -command { set lostSel lost } .
    selection own -selection CLIPBOARD .f1
    set result $lostSel
    selection own .f1
    lappend result $lostSel
} -result {owned lost}
test select-6.34 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection own -badopt foo
} -result {bad option "-badopt": must be -command, -displayof, or -selection}
test select-6.35 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection own -selectionfoo foo
} -result {bad option "-selectionfoo": must be -command, -displayof, or -selection}
test select-6.36 {Tk_SelectionCmd procedure} -body {
    destroy .f2
    selection own -displayof .f2
} -returnCodes error -result {bad window path name ".f2"}
test select-6.37 {Tk_SelectionCmd procedure} -body {
    destroy .f2
    selection own .f2
} -returnCodes error -result {bad window path name ".f2"}
test select-6.38 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection own foo bar baz
} -result {wrong # args: should be "selection own ?-option value ...? ?window?"}
test select-6.39 {Tk_SelectionCmd procedure} -returnCodes error -body {
    selection foo
} -result {bad option "foo": must be clear, get, handle, or own}

##############################################################################

# This test is non-portable because some old X11/News servers ignore a
# selection request when the window doesn't exist, which causes a different
# error message.
test select-7.1 {TkSelDeadWindow procedure} -constraints nonPortable -setup {
    setup
} -body {
    selection handle .f1 { handler TEST }
    set result [selection own]
    destroy .f1
    lappend result [selection own] [catch {selection get} msg] $msg
} -result {.f1 {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined}}

##############################################################################

# Check reentrancy on losing selection

test select-8.1 {TkSelEventProc procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection own -selection CLIPBOARD -command {destroy .f1} .f1
    update
    dobg {selection own -selection CLIPBOARD .}
    winfo children .
} -cleanup {
    cleanupbg
} -result {}

##############################################################################

test select-9.1 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    set selValue "1024"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
        .f1 {handler TEST}
    update
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 } {TEST 0 4000}}
test select-9.2 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "1024 0xffff  2048 -2  "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 0xffff 0x800 0xfffffffe } {TEST 0 4000}}
test select-9.3 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "   "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{ } {TEST 0 4000}}
test select-9.4 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "16 foobar 32"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x10 0x0 0x20 } {TEST 0 4000}}
test select-9.5 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    # Ensure that lists of atoms are constructed correctly, even when the
    # atom names have spaces in. [Bug 1353414]
    set selValue "foo bar"
    set selInfo ""
    set selType {text/x-tk-test;detail="foo bar"}
    selection handle -selection PRIMARY -format STRING -type $selType \
    .f1 [list handler $selType]
    lsort [dobg {selection get TARGETS}]
} -cleanup {
    cleanupbg
} -result {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW {text/x-tk-test;detail="foo bar"}}

##############################################################################

# note, we are not testing MULTIPLE style selections

# most control paths have been exercised above
test select-10.1 {ConvertSelection procedure, race with selection clear} -constraints {
    x11
} -setup {
    setup
} -body {
    proc Ready {fd} {
	variable x
	lappend x [gets $fd]
    }
    set fd [open "|[list [interpreter] -geometry +0+0 -name tktest]" r+]
    puts $fd "puts foo; [loadTkCommand]; flush stdout"
    flush $fd
    gets $fd
    fileevent $fd readable [list Ready $fd]
    set selValue "Just a simple test"
    set selInfo ""
    selection handle .f1 {handler STRING}
    update
    puts $fd {puts "[catch {selection get} msg]:$msg"; puts **DONE**; flush stdout}
    flush $fd
    after 200
    selection own .
    set x {}
    vwait [namespace which -variable x]
    puts $fd {exit}
    flush $fd
    # Don't understand why, but the [loadTkCommand] above causes
    # a "broken pipe" error when Tk was actually [load]ed in the child.
    catch {close $fd}
    lappend x $selInfo
} -result {{1:PRIMARY selection doesn't exist or form "STRING" not defined} {}}
test select-10.2 {ConvertSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    set selValue [string range $longValue 0 3999]
    set selInfo ""
    selection handle .f1 {handler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result [list [string range $longValue 0 3999] {STRING 0 4000 STRING 4000 4000 STRING 0 4000 STRING 4000 4000}]
test select-10.3 {ConvertSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle .f1 ERROR errHandler

    dobg {selection get ERROR}
} -cleanup {
    cleanupbg

} -result {PRIMARY selection doesn't exist or form "ERROR" not defined}
# testing timers
# This one hangs in Exceed
test select-10.4 {ConvertSelection procedure} -constraints {
    x11 noExceed failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {errIncrHandler STRING}
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000 STRING 0 4000 STRING 4000 4000}}
test select-10.5 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    set selValue "Test value"
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { badHandler .f1 STRING }
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}}
test select-10.6 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
    }


    set selValue $longValue
    set selInfo ""
    selection handle .f1 {weirdHandler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -cleanup {
    rename weirdHandler {}
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {STRING 0 4000}}

##############################################################################

# testing reentrancy
test select-11.1 {TkSelPropProc procedure} -constraints {x11 failsOnUbuntu} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { reallyBadHandler .f1 STRING }
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {.f1 STRING 0 4000 .f1 STRING 4000 4000 .f1 STRING 8000 4000 .f1 STRING 12000 4000 .f1 STRING 16000 4000 .f1 STRING 0 4000 .f1 STRING 4000 4000}}

##############################################################################

# Note, this assumes we are using CurrentTtime
test select-12.1 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [selection get -type TIMESTAMP]
    setupbg
    lappend result [dobg {selection get -type TIMESTAMP}]
    cleanupbg
    set result
} -result {0x0 {0x0 }}
test select-12.2 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [lsort [list [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.3 {DefaultSelection procedure} -constraints x11 -body {
    setup
    selection handle .f1 {handler TEST} TEST
    set result [list [lsort [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.4 {DefaultSelection procedure} -constraints x11 -setup {
    setup
    set result ""
} -body {
    lappend result [selection get -type TK_APPLICATION]
    setupbg
    lappend result [dobg {selection get -type TK_APPLICATION}]
    cleanupbg
    set result
} -result [list [winfo name .] [winfo name .]]
test select-12.5 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [selection get -type TK_WINDOW]
    setupbg
    lappend result [dobg {selection get -type TK_WINDOW}]
    cleanupbg
    set result
} -result {.f1 .f1}
test select-12.6 {DefaultSelection procedure} -body {
    setup
    selection handle .f1 {handler TARGETS.f1} TARGETS
    set selValue "Targets value"
    set selInfo ""
    set result [list [selection get TARGETS] $selInfo]
    selection handle .f1 {} TARGETS
    lappend result [selection get TARGETS]
} -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}

test select-13.1 {SelectionSize procedure, handler deleted} -constraints {
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    proc badHandler {path type offset count} {
	global selValue selInfo abortCount
	incr abortCount -1
	if {$abortCount == 0} {
	    selection handle -type $type $path {}
	}
	lappend selInfo $path $type $offset $count
	set numBytes [expr {[string length $selValue] - $offset}]
	if {$numBytes <= 0} {
	    return ""
	}
	string range $selValue $offset [expr {$numBytes+$offset}]
    }


    set selValue $longValue
    set selInfo ""
    selection handle .f1 {badHandler .f1 STRING}
    set result ""
    set abortCount 2
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000 .f1 STRING 4000 4000}}

test select-14.1 {Bug [73ba07efcd]: Use correct property type when handling MULTIPLE conversion requests} -constraints {
    cliboardManagerPresent
} -setup {
    proc get_clip {offset maxChars} {return abcd}
} -body {
    selection handle -selection CLIPBOARD . get_clip
    selection own -selection CLIPBOARD .
    selection get -selection CLIPBOARD_MANAGER -type SAVE_TARGETS
    clipboard get
} -cleanup {
    rename get_clip {}
} -result {abcd}


# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|
|

<

|
|

<


|
|


<




|
|

<



|
|

<



|
|


<





|
|


<








|
|
|


<








|
|
|

<





|
|

<





|
|

<


|



|

>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

<






|
|

<






|
|

<


|



|

<

|
|




|
|


<


|
|


<




|
|



<




|
|


<






|
|



<









|

|

<


|
|


<


|

|
<
<



|
|
<
<





<



<

>
|



|

<



|
|

<



|
|

<

|
|



<








|

|
<
<



<








|
|
<
<



<











|



|

<
|
|
|

<

|
|

<




|
|

<

|
|
|

<




|
|
>
>
>
>

<


<
|
<
<
|
|
|
>
>
>
>

<


|
<
<
<
|
|
|
>
>
>
>

<


|
<
<
<

|
|


<








|
|


<









|

|
<
<


<








|
|
<
<



<









|
|
<
<



<













|
|
<
<



<













|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|

|
|
|
|

<




|
|

<




|
|

<




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

<



|
|

<




|
|
|
|

|
|
|
|


<




|
|


<






|
|


<





|
|
|
|
|
|
|
|

|
|
|
|
|
|


<





|


|
|
|
|


<



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|

<


|
|

<



|
|


<






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|

<




|




>
|






<









|



|






|


<








|
|


<








|
|


<








|



|






|






>



|
<
<

<













|











|
|


<







|
|


<

>
|
<

>
|


|
<
<


<








|
|
<
<


<








|
|
<
<
<
<
<




>
>







<
<
|




|


<









|




|






|
|






|
|







|
|


<





|
|






|
|







|

|
<
<
<
<
<











|

>
>








|

<
<
<
<
<
<
<
<
<
<
<
<
|




<
<
<
<
105
106
107
108
109
110
111
112
113
114

115
116
117
118

119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137

138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235






























236
237
238

239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281

282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328

329
330
331
332
333


334
335
336
337
338


339
340
341
342
343

344
345
346

347
348
349
350
351
352
353
354

355
356
357
358
359
360

361
362
363
364
365
366

367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383


384
385
386

387
388
389
390
391
392
393
394
395
396


397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420

421
422
423
424

425
426
427
428
429
430
431

432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447

448
449

450


451
452
453
454
455
456
457
458

459
460
461



462
463
464
465
466
467
468
469

470
471
472



473
474
475
476
477

478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501


502
503

504
505
506
507
508
509
510
511
512
513


514
515
516

517
518
519
520
521
522
523
524
525
526
527


528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543
544
545


546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561
562




563












564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581

582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715
716
717
718

719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855


856

857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896

897
898
899

900
901
902
903
904
905


906
907

908
909
910
911
912
913
914
915
916
917


918
919

920
921
922
923
924
925
926
927
928
929





930
931
932
933
934
935
936
937
938
939
940
941
942


943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017





1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042












1043
1044
1045
1046
1047




set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# Now we start the main body of the test code

test select-1.1 {Tk_CreateSelHandler procedure} {
    setup

    lsort [selection get TARGETS]
} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.2 {Tk_CreateSelHandler procedure} {
    setup

    selection handle .f1 {handler TEST} TEST
    lsort [selection get TARGETS]
} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.3 {Tk_CreateSelHandler procedure} {
    global selValue selInfo
    setup

    selection handle .f1 {handler TEST} TEST
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} {{Test value} {TEST 0 4000}}
test select-1.4.1 {Tk_CreateSelHandler procedure} unix {
    setup

    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    lsort [selection get TARGETS]
} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}
test select-1.4.2 {Tk_CreateSelHandler procedure} win {
    setup

    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    lsort [selection get TARGETS]
} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}
test select-1.5 {Tk_CreateSelHandler procedure} {
    global selValue selInfo
    setup

    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    list [selection get] $selInfo
} {{} {STRING 0 4000}}
test select-1.6.1 {Tk_CreateSelHandler procedure} unix {
    global selValue selInfo
    setup

    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    selection get
    selection get -type TEST
    selection handle .f1 {handler TEST2} TEST
    selection get -type TEST
    list [set selInfo] [lsort [selection get TARGETS]]
} {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}}
test select-1.6.2 {Tk_CreateSelHandler procedure} win {
    global selValue selInfo
    setup

    selection handle .f1 {handler TEST} TEST
    selection handle .f1 {handler STRING}
    set selValue ""
    set selInfo ""
    selection get
    selection get -type TEST
    selection handle .f1 {handler TEST2} TEST
    selection get -type TEST
    list [set selInfo] [lsort [selection get TARGETS]]
} {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.7.1 {Tk_CreateSelHandler procedure} unix {
    setup

    selection own -selection CLIPBOARD .f1
    selection handle -selection CLIPBOARD .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f1 {handler TEST2} STRING
    list [lsort [selection get -selection PRIMARY TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.7.2 {Tk_CreateSelHandler procedure} win {
    setup

    selection own -selection CLIPBOARD .f1
    selection handle -selection CLIPBOARD .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f1 {handler TEST2} STRING
    list [lsort [selection get -selection PRIMARY TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-1.8 {Tk_CreateSelHandler procedure} {
    setup

    selection handle -format INTEGER -type TEST .f1 {handler TEST}
    lsort [selection get TARGETS]
} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}

##############################################################################

test select-2.1 {Tk_DeleteSelHandler procedure} unix {
    setup
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type TEST .f1 {}
    lappend result [lsort [selection get TARGETS]]
} {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING}}
test select-2.2 {Tk_DeleteSelHandler procedure} unix {
    setup
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type USER .f1 {}
    lappend result [lsort [selection get TARGETS]]
} {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER UTF8_STRING} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING}}
test select-2.3 {Tk_DeleteSelHandler procedure} unix {
    setup
    selection own -selection CLIPBOARD .f1
    selection handle -selection PRIMARY .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {}
    list [lsort [selection get TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW UTF8_STRING} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.4 {Tk_DeleteSelHandler procedure} win {
    setup
    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type TEST .f1 {}
    lappend result [lsort [selection get TARGETS]]






























} {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER}}
test select-2.5 {Tk_DeleteSelHandler procedure} win {
    setup

    selection handle .f1 {handler STRING}
    selection handle -type TEST .f1 {handler TEST}
    selection handle -type USER .f1 {handler USER}
    set result [list [lsort [selection get TARGETS]]]
    selection handle -type USER .f1 {}
    lappend result [lsort [selection get TARGETS]]
} {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.6 {Tk_DeleteSelHandler procedure} win {
    setup

    selection own -selection CLIPBOARD .f1
    selection handle -selection PRIMARY .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {}
    list [lsort [selection get TARGETS]] \
	[lsort [selection get -selection CLIPBOARD TARGETS]]
} {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-2.7 {Tk_DeleteSelHandler procedure} {
    setup

    selection handle .f1 {handler STRING}
    list [selection handle .f1 {}] [selection handle .f1 {}]
} {{} {}}

##############################################################################

test select-3.1 {Tk_OwnSelection procedure} {
    setup

    selection own
} {.f1}
test select-3.2 {Tk_OwnSelection procedure} {
    setup .f1
    set result [selection own]
    setup .f2
    lappend result [selection own]
} {.f1 .f2}
test select-3.3 {Tk_OwnSelection procedure} {
    setup .f1
    setup .f2

    selection own -selection CLIPBOARD .f1
    list [selection own] [selection own -selection CLIPBOARD]
} {.f2 .f1}
test select-3.4 {Tk_OwnSelection procedure} {
    global lostSel
    setup

    set lostSel {owned}
    selection own -command { set lostSel {lost} } .f1
    selection clear .f1
    set lostSel
} {lost}
test select-3.5 {Tk_OwnSelection procedure} {
    global lostSel
    setup .f1
    setup .f2

    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f2
    list $lostSel [selection own]
} {lost1 .f2}
test select-3.6 {Tk_OwnSelection procedure} {
    global lostSel
    setup

    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f1
    set result $lostSel
    selection clear .f1
    lappend result $lostSel
} {owned lost2}
test select-3.7 {Tk_OwnSelection procedure} unix {
    global lostSel
    setup
    setupbg

    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
    set result {}
    lappend result [dobg { selection own . }]
    lappend result [dobg {selection own}]
    update
    cleanupbg
    lappend result $lostSel
} {{} . lost1}
# check reentrancy on selection replacement
test select-3.8 {Tk_OwnSelection procedure} {
    setup

    selection own -selection CLIPBOARD -command { destroy .f1 } .f1
    selection own -selection CLIPBOARD .
} {}
test select-3.9 {Tk_OwnSelection procedure} {
    setup .f2
    setup .f1

    selection own -selection CLIPBOARD -command { destroy .f2 } .f1
    selection own -selection CLIPBOARD .f2
} {}
# multiple display tests
test select-3.10 {Tk_OwnSelection procedure} {altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    list [selection own -displayof .f1] [selection own -displayof .f2]
} {.f1 .f2}
test select-3.11 {Tk_OwnSelection procedure} {altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
    update
    set result ""

    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection own .t; update"]
    lappend result [selection own -displayof .f1] \
	    [selection own -displayof .f2]

    cleanupbg
    set result
} {{} .f1 {}}

##############################################################################

test select-4.1 {Tk_ClearSelection procedure} {
    setup

    set result [selection own]
    selection clear .f1
    lappend result [selection own]
} {.f1 {}}
test select-4.2 {Tk_ClearSelection procedure} {
    setup

    selection own -selection CLIPBOARD .f1
    selection clear .f1
    selection own -selection CLIPBOARD
} {.f1}
test select-4.3 {Tk_ClearSelection procedure} {
    setup

    list [selection clear .f1] [selection clear .f1]
} {{} {}}
test select-4.4 {Tk_ClearSelection procedure} unix {
    global lostSel
    setup
    setupbg

    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
    set result {}
    lappend result [dobg {selection clear; update}]
    update
    cleanupbg
    lappend result [selection own]
} {{} {}}
# multiple display tests
test select-4.5 {Tk_ClearSelection procedure} {altDisplay} {


    global lostSel lostSel2
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)

    set lostSel {owned}
    set lostSel2 {owned2}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel2 {lost2} } .f2
    update
    selection clear -displayof .f2
    update
    list $lostSel $lostSel2
} {owned lost2}
test select-4.6 {Tk_ClearSelection procedure} {unix altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg

    set lostSel {owned}
    set lostSel2 {owned2}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel2 {lost2} } .f2
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection own .t; update"]
    lappend result [selection own -displayof .f1] \
	    [selection own -displayof .f2] $lostSel $lostSel2
    cleanupbg
    set result
} {{} .f1 {} owned lost2}

##############################################################################

test select-5.1 {Tk_GetSelection procedure} {
    setup

    list [catch {selection get TEST} msg] $msg
} {1 {PRIMARY selection doesn't exist or form "TEST" not defined}}
test select-5.2 {Tk_GetSelection procedure} {
    setup

    selection get TK_WINDOW
} {.f1}
test select-5.3 {Tk_GetSelection procedure} {
    setup

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} {{Test value} {TEST 0 4000}}
test select-5.4 {Tk_GetSelection procedure} {
    setup

    selection handle .f1 ERROR errHandler
    list [catch {selection get ERROR} msg] $msg
} {1 {PRIMARY selection doesn't exist or form "ERROR" not defined}}
test select-5.5 {Tk_GetSelection procedure} {
    setup

    set selValue $longValue
    set selInfo ""
    selection handle .f1 {handler STRING}
    list [selection get] $selInfo
} "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000}"
test select-5.6 {Tk_GetSelection procedure} {
    proc weirdHandler {type offset count} {
	selection handle .f1 {}
	handler $type $offset $count
    }
    setup

    set selValue $longValue
    set selInfo ""

    selection handle .f1 {weirdHandler STRING}


    list [catch {selection get} msg] $msg
} {1 {PRIMARY selection doesn't exist or form "STRING" not defined}}
test select-5.7 {Tk_GetSelection procedure} {
    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
    }
    setup

    set selValue "Test Value"
    set selInfo ""
    selection handle .f1 {weirdHandler STRING}



    list [catch {selection get} msg] $msg
} {1 {PRIMARY selection doesn't exist or form "STRING" not defined}}
test select-5.8 {Tk_GetSelection procedure} {
    proc weirdHandler {type offset count} {
	selection clear
	handler $type $offset $count
    }
    setup

    set selValue $longValue
    set selInfo ""
    selection handle .f1 {weirdHandler STRING}



    list [selection get] $selInfo [catch {selection get} msg] $msg
} "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000} 1 {PRIMARY selection doesn't exist or form \"STRING\" not defined}"
test select-5.9 {Tk_GetSelection procedure} unix {
    setup
    setupbg

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} {{Test value} {TEST 0 4000}}
test select-5.10 {Tk_GetSelection procedure} unix {
    setup
    setupbg

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    selection own .f1
    set result ""
    lappend result [dobg {selection get TEST} 1]
    cleanupbg
    lappend result $selInfo
} {{selection owner didn't respond} {}}
# multiple display tests
test select-5.11 {Tk_GetSelection procedure} {altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f2 {handler TEST2} TEST
    set selValue "Test value"
    set selInfo ""
    set result [list [selection get TEST] $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [selection get -displayof .f2 TEST] $selInfo
} {{Test value} {TEST 0 4000} {Test value2} {TEST2 0 4000}}
test select-5.12 {Tk_GetSelection procedure} {altDisplay} {


    global lostSel lostSel2
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection handle -selection PRIMARY .f2 {} TEST
    set selValue "Test value"
    set selInfo ""
    set result [list [catch {selection get TEST} msg] $msg $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [catch {selection get -displayof .f2 TEST} msg] $msg \
	    $selInfo
} {0 {Test value} {TEST 0 4000} 1 {PRIMARY selection doesn't exist or form "TEST" not defined} {}}
test select-5.13 {Tk_GetSelection procedure} {unix altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
    selection handle -selection PRIMARY .f2 {handler TEST2} TEST
    selection own .f2
    set selValue "Test value"
    set selInfo ""
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} {{Test value} {Test value2} {TEST2 0 4000 TEST 0 4000}}
test select-5.14 {Tk_GetSelection procedure} {unix altDisplay} {


    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg

    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
    selection handle -selection PRIMARY .f2 {} TEST
    selection own .f2
    set selValue "Test value"
    set selInfo ""
    update
    set result ""
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} {{PRIMARY selection doesn't exist or form "TEST" not defined} {Test value2} {TEST 0 4000}}

















##############################################################################

test select-6.1 {Tk_SelectionCmd procedure} {
    list [catch {selection} cmd] $cmd
} {1 {wrong # args: should be "selection option ?arg arg ...?"}}
# selection clear
test select-6.2 {Tk_SelectionCmd procedure} {
    list [catch {selection clear -selection} cmd] $cmd
} {1 {value for "-selection" missing}}
test select-6.3 {Tk_SelectionCmd procedure} {
    setup

    selection own .
    set result [selection own]
    selection clear -displayof .f1
    lappend result [selection own]
} {. {}}
test select-6.4 {Tk_SelectionCmd procedure} {
    setup

    selection own -selection CLIPBOARD .f1
    set result [list [selection own] [selection own -selection CLIPBOARD]]
    selection clear -selection CLIPBOARD .f1
    lappend result [selection own] [selection own -selection CLIPBOARD]
} {.f1 .f1 .f1 {}}
test select-6.5 {Tk_SelectionCmd procedure} {
    setup

    selection own -selection CLIPBOARD .
    set result [list [selection own] [selection own -selection CLIPBOARD]]
    selection clear -selection CLIPBOARD -displayof .f1
    lappend result [selection own] [selection own -selection CLIPBOARD]
} {.f1 . .f1 {}}
test select-6.6 {Tk_SelectionCmd procedure} {
    list [catch {selection clear -badopt foo} cmd] $cmd
} {1 {bad option "-badopt": must be -displayof or -selection}}
test select-6.7 {Tk_SelectionCmd procedure} {
    list [catch {selection clear -selectionfoo foo} cmd] $cmd
} {1 {bad option "-selectionfoo": must be -displayof or -selection}}
test select-6.8 {Tk_SelectionCmd procedure} {
    catch {destroy .f2}
    list [catch {selection clear -displayof .f2} cmd] $cmd
} {1 {bad window path name ".f2"}}
test select-6.9 {Tk_SelectionCmd procedure} {
    catch {destroy .f2}
    list [catch {selection clear .f2} cmd] $cmd
} {1 {bad window path name ".f2"}}
test select-6.10 {Tk_SelectionCmd procedure} {
    setup

    set result [selection own -selection PRIMARY]
    selection clear
    lappend result [selection own -selection PRIMARY]
} {.f1 {}}
test select-6.11 {Tk_SelectionCmd procedure} {
    setup

    selection own -selection CLIPBOARD .f1
    set result [selection own -selection CLIPBOARD]
    selection clear -selection CLIPBOARD
    lappend result [selection own -selection CLIPBOARD]
} {.f1 {}}
test select-6.12 {Tk_SelectionCmd procedure} {
    list [catch {selection clear foo bar} cmd] $cmd
} {1 {wrong # args: should be "selection clear ?options?"}}
# selection get
test select-6.13 {Tk_SelectionCmd procedure} {
    list [catch {selection get -selection} cmd] $cmd
} {1 {value for "-selection" missing}}
test select-6.14 {Tk_SelectionCmd procedure} {
    global selValue selInfo
    setup

    selection handle .f1 {handler TEST}
    set selValue "Test value"
    set selInfo ""
    list [selection get -displayof .f1] $selInfo
} {{Test value} {TEST 0 4000}}
test select-6.15 {Tk_SelectionCmd procedure} {
    global selValue selInfo
    setup

    selection handle .f1 {handler STRING}
    selection handle -selection CLIPBOARD .f1 {handler TEST}
    selection own -selection CLIPBOARD .f1
    set selValue "Test value"
    set selInfo ""
    list [selection get -selection CLIPBOARD] $selInfo
} {{Test value} {TEST 0 4000}}
test select-6.16 {Tk_SelectionCmd procedure} {
    global selValue selInfo
    setup

    selection handle -type TEST .f1 {handler TEST}
    selection handle -type STRING .f1 {handler STRING}
    set selValue "Test value"
    set selInfo ""
    list [selection get -type TEST] $selInfo
} {{Test value} {TEST 0 4000}}
test select-6.17 {Tk_SelectionCmd procedure} {
    list [catch {selection get -badopt foo} cmd] $cmd
} {1 {bad option "-badopt": must be -displayof, -selection, or -type}}
test select-6.18 {Tk_SelectionCmd procedure} {
    list [catch {selection get -selectionfoo foo} cmd] $cmd
} {1 {bad option "-selectionfoo": must be -displayof, -selection, or -type}}
test select-6.19 {Tk_SelectionCmd procedure} {
    catch { destroy .f2 }
    list [catch {selection get -displayof .f2} cmd] $cmd
} {1 {bad window path name ".f2"}}
test select-6.20 {Tk_SelectionCmd procedure} {
    list [catch {selection get foo bar} cmd] $cmd
} {1 {wrong # args: should be "selection get ?options?"}}
test select-6.21 {Tk_SelectionCmd procedure} {
    global selValue selInfo
    setup

    selection handle -type TEST .f1 {handler TEST}
    selection handle -type STRING .f1 {handler STRING}
    set selValue "Test value"
    set selInfo ""
    list [selection get TEST] $selInfo
} {{Test value} {TEST 0 4000}}
# selection handle
# most of the handle section has been covered earlier
test select-6.22 {Tk_SelectionCmd procedure} {
    list [catch {selection handle -selection} cmd] $cmd
} {1 {value for "-selection" missing}}
test select-6.23 {Tk_SelectionCmd procedure} {
    global selValue selInfo
    setup

    set selValue "Test value"
    set selInfo ""
    list [selection handle -format INTEGER .f1 {handler TEST}] [selection get -displayof .f1] $selInfo
} {{} {Test value} {TEST 0 4000}}
test select-6.24 {Tk_SelectionCmd procedure} {
    list [catch {selection handle -badopt foo} cmd] $cmd
} {1 {bad option "-badopt": must be -format, -selection, or -type}}
test select-6.25 {Tk_SelectionCmd procedure} {
    list [catch {selection handle -selectionfoo foo} cmd] $cmd
} {1 {bad option "-selectionfoo": must be -format, -selection, or -type}}
test select-6.26 {Tk_SelectionCmd procedure} {
    list [catch {selection handle} cmd] $cmd
} {1 {wrong # args: should be "selection handle ?options? window command"}}
test select-6.27 {Tk_SelectionCmd procedure} {
    list [catch {selection handle .} cmd] $cmd
} {1 {wrong # args: should be "selection handle ?options? window command"}}
test select-6.28 {Tk_SelectionCmd procedure} {
    list [catch {selection handle . foo bar baz blat} cmd] $cmd
} {1 {wrong # args: should be "selection handle ?options? window command"}}
test select-6.29 {Tk_SelectionCmd procedure} {
    catch { destroy .f2 }
    list [catch {selection handle .f2 dummy} cmd] $cmd
} {1 {bad window path name ".f2"}}
# selection own
test select-6.30 {Tk_SelectionCmd procedure} {
    list [catch {selection own -selection} cmd] $cmd
} {1 {value for "-selection" missing}}
test select-6.31 {Tk_SelectionCmd procedure} {
    setup

    selection own .
    selection own -displayof .f1
} {.}
test select-6.32 {Tk_SelectionCmd procedure} {
    setup

    selection own .
    selection own -selection CLIPBOARD .f1
    list [selection own] [selection own -selection CLIPBOARD]
} {. .f1}
test select-6.33 {Tk_SelectionCmd procedure} {
    global lostSel
    setup

    set lostSel owned
    selection own -command { set lostSel lost } .
    selection own -selection CLIPBOARD .f1
    set result $lostSel
    selection own .f1
    lappend result $lostSel
} {owned lost}
test select-6.34 {Tk_SelectionCmd procedure} {
    list [catch {selection own -badopt foo} cmd] $cmd
} {1 {bad option "-badopt": must be -command, -displayof, or -selection}}
test select-6.35 {Tk_SelectionCmd procedure} {
    list [catch {selection own -selectionfoo foo} cmd] $cmd
} {1 {bad option "-selectionfoo": must be -command, -displayof, or -selection}}
test select-6.36 {Tk_SelectionCmd procedure} {
    catch {destroy .f2}
    list [catch {selection own -displayof .f2} cmd] $cmd
} {1 {bad window path name ".f2"}}
test select-6.37 {Tk_SelectionCmd procedure} {
    catch {destroy .f2}
    list [catch {selection own .f2} cmd] $cmd
} {1 {bad window path name ".f2"}}
test select-6.38 {Tk_SelectionCmd procedure} {
    list [catch {selection own foo bar baz} cmd] $cmd
} {1 {wrong # args: should be "selection own ?options? ?window?"}}
test select-6.39 {Tk_SelectionCmd procedure} {
    list [catch {selection foo} cmd] $cmd
} {1 {bad option "foo": must be clear, get, handle, or own}}

##############################################################################

# This test is non-portable because some old X11/News servers ignore
# a selection request when the window doesn't exist, which causes a
# different error message.
test select-7.1 {TkSelDeadWindow procedure} nonPortable {
    setup

    selection handle .f1 { handler TEST }
    set result [selection own]
    destroy .f1
    lappend result [selection own] [catch {selection get} msg] $msg
} {.f1 {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined}}

##############################################################################

# Check reentrancy on losing selection

test select-8.1 {TkSelEventProc procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    selection own -selection CLIPBOARD -command {destroy .f1} .f1
    update
    dobg {selection own -selection CLIPBOARD .}

} -cleanup {
    cleanupbg
} -result {}

##############################################################################

test select-9.1 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    set selValue "1024"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	    .f1 {handler TEST}
    update
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 } {TEST 0 4000}}
test select-9.2 {SelCvtToX and SelCvtFromX procedures} unix {
    setup
    setupbg

    set selValue "1024 0xffff  2048 -2  "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} {{0x400 0xffff 0x800 0xfffffffe } {TEST 0 4000}}
test select-9.3 {SelCvtToX and SelCvtFromX procedures} unix {
    setup
    setupbg

    set selValue "   "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} {{ } {TEST 0 4000}}
test select-9.4 {SelCvtToX and SelCvtFromX procedures} unix {
    setup
    setupbg

    set selValue "16 foobar 32"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} {{0x10 0x0 0x20 } {TEST 0 4000}}
test select-9.5 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    # Ensure that lists of atoms are constructed correctly, even when the
    # atom names have spaces in. [Bug 1353414]
    set selValue "foo bar"
    set selInfo ""
    set selType {text/x-tk-test;detail="foo bar"}
    selection handle -selection PRIMARY -format STRING -type $selType \
	.f1 [list handler $selType]
    lsort [dobg {selection get TARGETS}]
} -cleanup {
    cleanupbg
} -result {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW {text/x-tk-test;detail="foo bar"}}

##############################################################################

# note, we are not testing MULTIPLE style selections

# most control paths have been exercised above
test select-10.1 {ConvertSelection procedure, race with selection clear} unix {


    setup

    proc Ready {fd} {
	variable x
	lappend x [gets $fd]
    }
    set fd [open "|[list [interpreter] -geometry +0+0 -name tktest]" r+]
    puts $fd "puts foo; [loadTkCommand]; flush stdout"
    flush $fd
    gets $fd
    fileevent $fd readable [list Ready $fd]
    set selValue "Just a simple test"
    set selInfo ""
    selection handle .f1 {handler STRING}
    update
    puts $fd {puts "[catch {selection get} msg] $msg"; puts **DONE**; flush stdout}
    flush $fd
    after 200
    selection own .
    set x {}
    vwait [namespace which -variable x]
    puts $fd {exit}
    flush $fd
    # Don't understand why, but the [loadTkCommand] above causes
    # a "broken pipe" error when Tk was actually [load]ed in the child.
    catch {close $fd}
    lappend x $selInfo
} {{1 PRIMARY selection doesn't exist or form "STRING" not defined} {}}
test select-10.2 {ConvertSelection procedure} unix {
    setup
    setupbg

    set selValue [string range $longValue 0 3999]
    set selInfo ""
    selection handle .f1 {handler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} [list [string range $longValue 0 3999] {STRING 0 4000 STRING 4000 4000 STRING 0 4000 STRING 4000 4000}]
test select-10.3 {ConvertSelection procedure} unix {
    setup
    setupbg

    selection handle .f1 ERROR errHandler
    set result ""
    lappend result [dobg {selection get ERROR}]

    cleanupbg
    set result
} {{PRIMARY selection doesn't exist or form "ERROR" not defined}}
# testing timers
# This one hangs in Exceed
test select-10.4 {ConvertSelection procedure} {unix noExceed} {


    setup
    setupbg

    set selValue $longValue
    set selInfo ""
    selection handle .f1 {errIncrHandler STRING}
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} {{selection owner didn't respond} {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000 STRING 0 4000 STRING 4000 4000}}
test select-10.5 {ConvertSelection procedure, reentrancy issues} unix {


    setup
    setupbg

    set selValue "Test value"
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { badHandler .f1 STRING }
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}}
test select-10.6 {ConvertSelection procedure, reentrancy issues} unix {





    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
    }
    setup
    setupbg
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {weirdHandler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo


} {{PRIMARY selection doesn't exist or form "STRING" not defined} {STRING 0 4000}}

##############################################################################

# testing reentrancy
test select-11.1 {TkSelPropProc procedure} unix {
    setup
    setupbg

    set selValue $longValue
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { reallyBadHandler .f1 STRING }
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} {{selection owner didn't respond} {.f1 STRING 0 4000 .f1 STRING 4000 4000 .f1 STRING 8000 4000 .f1 STRING 12000 4000 .f1 STRING 16000 4000 .f1 STRING 0 4000 .f1 STRING 4000 4000}}

##############################################################################

# Note, this assumes we are using CurrentTtime
test select-12.1 {DefaultSelection procedure} unix {
    setup
    set result [selection get -type TIMESTAMP]
    setupbg
    lappend result [dobg {selection get -type TIMESTAMP}]
    cleanupbg
    set result
} {0x0 {0x0 }}
test select-12.2 {DefaultSelection procedure} unix {
    setup
    set result [lsort [list [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} {{MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.3 {DefaultSelection procedure} unix {
    setup
    selection handle .f1 {handler TEST} TEST
    set result [list [lsort [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.4 {DefaultSelection procedure} unix {
    setup
    set result ""

    lappend result [selection get -type TK_APPLICATION]
    setupbg
    lappend result [dobg {selection get -type TK_APPLICATION}]
    cleanupbg
    set result
} [list [winfo name .] [winfo name .]]
test select-12.5 {DefaultSelection procedure} unix {
    setup
    set result [selection get -type TK_WINDOW]
    setupbg
    lappend result [dobg {selection get -type TK_WINDOW}]
    cleanupbg
    set result
} {.f1 .f1}
test select-12.6 {DefaultSelection procedure} {
    setup
    selection handle .f1 {handler TARGETS.f1} TARGETS
    set selValue "Targets value"
    set selInfo ""
    set result [list [selection get TARGETS] $selInfo]
    selection handle .f1 {} TARGETS
    lappend result [selection get TARGETS]
} {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}

test select-13.1 {SelectionSize procedure, handler deleted} unix {





    proc badHandler {path type offset count} {
	global selValue selInfo abortCount
	incr abortCount -1
	if {$abortCount == 0} {
	    selection handle -type $type $path {}
	}
	lappend selInfo $path $type $offset $count
	set numBytes [expr {[string length $selValue] - $offset}]
	if {$numBytes <= 0} {
	    return ""
	}
	string range $selValue $offset [expr $numBytes+$offset]
    }
    setup
    setupbg
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {badHandler .f1 STRING}
    set result ""
    set abortCount 2
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000 .f1 STRING 4000 4000}}













catch {rename weirdHandler {}}

# cleanup
cleanupTests
return




Changes to tests/send.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2001 by ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint xhost [llength [auto_execok xhost]]
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]


# Compute a script that will load Tk into a child interpreter.

foreach pkg [info loaded] {
    if {[lindex $pkg 1] == "Tk"} {
	set loadTk "load $pkg"
	break




|
|
|
|









|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2001 by ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint xhost [llength [auto_execok xhost]]
testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# Compute a script that will load Tk into a child interpreter.

foreach pkg [info loaded] {
    if {[lindex $pkg 1] == "Tk"} {
	set loadTk "load $pkg"
	break
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
} "name2 {$commId name2\n}"
test send-7.4 {Tk_SetAppName procedure, name in use} {secureserver testsend} {
    tk appname name1
    testsend prop root InterpRegistry "$id foo\n$id foo #2\n$id foo #3\n"
    list [tk appname foo] [testsend prop root InterpRegistry]
} "{foo #4} {$commId foo #4\n$id foo\n$id foo #2\n$id foo #3\n}"

#macOS does not send to other processes
test send-8.1 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    setupbg
    set app [dobg {tk appname}]
    set a 66
    send -async $app [list send [tk appname] set a 77]
    set result $a
    after 200 set x 40
    tkwait variable x







<
|







195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
} "name2 {$commId name2\n}"
test send-7.4 {Tk_SetAppName procedure, name in use} {secureserver testsend} {
    tk appname name1
    testsend prop root InterpRegistry "$id foo\n$id foo #2\n$id foo #3\n"
    list [tk appname foo] [testsend prop root InterpRegistry]
} "{foo #4} {$commId foo #4\n$id foo\n$id foo #2\n$id foo #3\n}"


test send-8.1 {Tk_SendCmd procedure, options} {secureserver} {
    setupbg
    set app [dobg {tk appname}]
    set a 66
    send -async $app [list send [tk appname] set a 77]
    set result $a
    after 200 set x 40
    tkwait variable x
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
    set a altDisplay
    tk appname xyzgorp
    list \[send xyzgorp set a\] \[send -displayof .t xyzgorp set a\]
    "]
    cleanupbg
    set result
} {altDisplay homeDisplay}
# Since macOS has no registry of interpreters, 8.3, 8.4 and 8.10 will fail.
test send-8.3 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    list [catch {send -- -async foo bar baz} msg] $msg
} {1 {no application named "-async"}}
test send-8.4 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    list [catch {send -gorp foo bar baz} msg] $msg
} {1 {no application named "-gorp"}}
test send-8.5 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -async foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.6 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.7 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    send [tk appname] {set a new}
    set a
} {new}
test send-8.8 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    send [tk appname] set a new
    set a
} {new}
test send-8.9 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    string tolower [list [catch {send [tk appname] open bad_file} msg] \
	    $msg $errorInfo $errorCode]
} {1 {couldn't open "bad_file": no such file or directory} {couldn't open "bad_file": no such file or directory
    while executing
"open bad_file"
    invoked from within
"send [tk appname] open bad_file"} {posix enoent {no such file or directory}}}
test send-8.10 {Tk_SendCmd procedure, no such interpreter} {secureserver notAqua} {
    list [catch {send bogus_name bogus_command} msg] $msg
} {1 {no application named "bogus_name"}}

catch {
    newApp "" t_s_1 Test
    t_s_1 eval wm withdraw .
}







<
|


|

|


|


|



















|







220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    set a altDisplay
    tk appname xyzgorp
    list \[send xyzgorp set a\] \[send -displayof .t xyzgorp set a\]
    "]
    cleanupbg
    set result
} {altDisplay homeDisplay}

test send-8.3 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -- -async foo bar baz} msg] $msg
} {1 {no application named "-async"}}
test send-8.4 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -gorp foo bar baz} msg] $msg
} {1 {bad option "-gorp": must be -async, -displayof, or --}}
test send-8.5 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -async foo} msg] $msg
} {1 {wrong # args: should be "send ?options? interpName arg ?arg ...?"}}
test send-8.6 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send foo} msg] $msg
} {1 {wrong # args: should be "send ?options? interpName arg ?arg ...?"}}
test send-8.7 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    send [tk appname] {set a new}
    set a
} {new}
test send-8.8 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    send [tk appname] set a new
    set a
} {new}
test send-8.9 {Tk_SendCmd procedure, local execution} {secureserver} {
    set a initial
    string tolower [list [catch {send [tk appname] open bad_file} msg] \
	    $msg $errorInfo $errorCode]
} {1 {couldn't open "bad_file": no such file or directory} {couldn't open "bad_file": no such file or directory
    while executing
"open bad_file"
    invoked from within
"send [tk appname] open bad_file"} {posix enoent {no such file or directory}}}
test send-8.10 {Tk_SendCmd procedure, no such interpreter} {secureserver} {
    list [catch {send bogus_name bogus_command} msg] $msg
} {1 {no application named "bogus_name"}}

catch {
    newApp "" t_s_1 Test
    t_s_1 eval wm withdraw .
}
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
} {1 {couldn't open "bogus_file_name": no such file or directory} {couldn't open "bogus_file_name": no such file or directory
    while executing
"open bogus_file_name"
    invoked from within
"if 1 {open bogus_file_name}"
    invoked from within
"send t_s_1 {if 1 {open bogus_file_name}}"} {POSIX ENOENT {no such file or directory}}}
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu} {
    testsend prop root InterpRegistry "10234 bogus\n"
    set result [list [catch {send bogus bogus command} msg] $msg]
    winfo interps
    tk appname tktest
    set result
} {1 {no application named "bogus"}}








|







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
} {1 {couldn't open "bogus_file_name": no such file or directory} {couldn't open "bogus_file_name": no such file or directory
    while executing
"open bogus_file_name"
    invoked from within
"if 1 {open bogus_file_name}"
    invoked from within
"send t_s_1 {if 1 {open bogus_file_name}}"} {POSIX ENOENT {no such file or directory}}}
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu failsOnQuarz} {
    testsend prop root InterpRegistry "10234 bogus\n"
    set result [list [catch {send bogus bogus command} msg] $msg]
    winfo interps
    tk appname tktest
    set result
} {1 {no application named "bogus"}}

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
} {12345 newA newB}
test send-10.4 {SendEventProc procedure, leading nulls, bogus commands} {secureserver testsend} {
    testsend prop comm Comm \
	    "\n\nx\n-bogus\n\nc\n-n tktest\n-s set a 44\n"
    set a null
    update
    set a
} 44
test send-10.5 {SendEventProc procedure, extraneous command options} {secureserver testsend} {
    testsend prop comm Comm \
	    "c\n-n tktest\n-x miscellanous\n-y who knows?\n-s set a new\n"
    set a null
    update
    set a
} new
test send-10.6 {SendEventProc procedure, unknown interpreter} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n unknown\n-r $id 44\n-s set a new\n"
    set a null
    update
    list [testsend prop [winfo id .f] Comm] $a







|






|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
} {12345 newA newB}
test send-10.4 {SendEventProc procedure, leading nulls, bogus commands} {secureserver testsend} {
    testsend prop comm Comm \
	    "\n\nx\n-bogus\n\nc\n-n tktest\n-s set a 44\n"
    set a null
    update
    set a
} {44}
test send-10.5 {SendEventProc procedure, extraneous command options} {secureserver testsend} {
    testsend prop comm Comm \
	    "c\n-n tktest\n-x miscellanous\n-y who knows?\n-s set a new\n"
    set a null
    update
    set a
} {new}
test send-10.6 {SendEventProc procedure, unknown interpreter} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n unknown\n-r $id 44\n-s set a new\n"
    set a null
    update
    list [testsend prop [winfo id .f] Comm] $a
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
test send-12.1 {TimeoutProc procedure} {secureserver testsend} {
    testsend prop root InterpRegistry "$id dummy\n"
    list [catch {send dummy foo} msg] $msg
} {1 {target application died or uses a Tk version before 4.0}}

catch {testsend prop root InterpRegistry ""}

#macOS does not send to other processes
test send-12.2 {TimeoutProc procedure} {secureserver notAqua} {
    winfo interps
    tk appname tktest
    update
    setupbg
    set app [dobg {
	after 10 {after 10 {after 5000; exit}}
	tk appname
    }]
    after 200
    set result [list [catch {send $app foo} msg] $msg]
    cleanupbg
    set result
} {1 {target application died}}

#macOS does not send to other processes
winfo interps
tk appname tktest
test send-13.1 {DeleteProc procedure} {secureserver notAqua} {
    setupbg
    set app [dobg {rename send {}; tk appname}]
    set result [list [catch {send $app foo} msg] $msg [winfo interps]]
    cleanupbg
    set result
} {1 {no application named "tktest #2"} tktest}
test send-13.2 {DeleteProc procedure} {secureserver notAqua} {
    winfo interps
    tk appname tktest
    rename send {}
    set result {}
    lappend result [winfo interps] [info commands send]
    tk appname foo
    lappend result [winfo interps] [info commands send]







<
|














<


|






|







540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
test send-12.1 {TimeoutProc procedure} {secureserver testsend} {
    testsend prop root InterpRegistry "$id dummy\n"
    list [catch {send dummy foo} msg] $msg
} {1 {target application died or uses a Tk version before 4.0}}

catch {testsend prop root InterpRegistry ""}


test send-12.2 {TimeoutProc procedure} {secureserver} {
    winfo interps
    tk appname tktest
    update
    setupbg
    set app [dobg {
	after 10 {after 10 {after 5000; exit}}
	tk appname
    }]
    after 200
    set result [list [catch {send $app foo} msg] $msg]
    cleanupbg
    set result
} {1 {target application died}}


winfo interps
tk appname tktest
test send-13.1 {DeleteProc procedure} {secureserver} {
    setupbg
    set app [dobg {rename send {}; tk appname}]
    set result [list [catch {send $app foo} msg] $msg [winfo interps]]
    cleanupbg
    set result
} {1 {no application named "tktest #2"} tktest}
test send-13.2 {DeleteProc procedure} {secureserver} {
    winfo interps
    tk appname tktest
    rename send {}
    set result {}
    lappend result [winfo interps] [info commands send]
    tk appname foo
    lappend result [winfo interps] [info commands send]

Changes to tests/spinbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388


389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444


445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473



474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517





518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576



577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337

1338


1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358

1359
1360
1361
1362
1363
1364


1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438


1439






1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926


1927

1928
1929
1930
1931
1932
1933
1934

1935
1936
1937
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947
1948
1949
1950
1951
1952
1953
1954


1955

1956
1957
1958

1959
1960
1961
1962
1963
1964

1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014

2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059

2060


2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075


2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120

2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134

2135
2136
2137
2138
2139
2140
2141

2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153

2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223

2224
2225
2226
2227
2228
2229
2230

2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248

2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395


2396

2397
2398


2399
2400


2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417

2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618






2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647

2648


2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661

2662
2663
2664



2665
2666
2667
2668
2669
2670

2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791

2792
2793
2794
2795
2796
2797
2798
2799
2800

2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815

2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939

2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972

2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999

3000
3001
3002
3003
3004
3005
3006
3007
3008
3009

3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046



3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156




3157

3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181

3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194

3195
3196

3197
3198
3199
3200



3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217

3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233

3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246

3247
3248

3249
3250
3251
3252

3253
3254
3255
3256
3257
3258
3259
3260
3261
3262

3263
3264
3265
3266
3267
3268
3269
3270
3271


3272
3273

3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301









3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399

3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563

3564
3565
3566
3567
3568
3569

3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585

3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621

3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642


3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686

3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775

3776
3777
3778
3779
3780
3781
3782
# This file is a Tcl script to test spinbox widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        return 1
}
proc doval2 {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        set ::e mydata
        return 1
}
proc doval3 {W d i P s S v V} {
        set ::vVals [list $W $d $i $P $s $S $v $V]
        return 0
}

set cy [font metrics {Courier -12} -linespace]

test spinbox-1.1 {configuration option: "activebackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -activebackground #ff0000
    .e cget -activebackground
} -cleanup {
    destroy .e
} -result {#ff0000}
test spinbox-1.2 {configuration option: "activebackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -activebackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.3 {configuration option: "background"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -background #ff0000
    .e cget -background
} -cleanup {
    destroy .e
} -result {#ff0000}
test spinbox-1.4 {configuration option: "background" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.5 {configuration option: "bd"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test spinbox-1.6 {configuration option: "bd" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test spinbox-1.7 {configuration option: "bg"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bg #ff0000
    .e cget -bg
} -cleanup {
    destroy .e
} -result {#ff0000}
test spinbox-1.8 {configuration option: "bg" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.9 {configuration option: "borderwidth"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -borderwidth 1.3
    .e cget -borderwidth
} -cleanup {
    destroy .e
} -result 1
test spinbox-1.10 {configuration option: "borderwidth" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}


test spinbox-1.11 {configuration option: "buttonbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {

    .e configure -buttonbackground #ff0000
    .e cget -buttonbackground
} -cleanup {
    destroy .e
} -result {#ff0000}
test spinbox-1.12 {configuration option: "buttonbackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -buttonbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.13 {configuration option: "buttoncursor"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -buttoncursor arrow
    .e cget -buttoncursor
} -cleanup {
    destroy .e
} -result {arrow}
test spinbox-1.14 {configuration option: "buttoncursor" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -buttoncursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}

test spinbox-1.15 {configuration option: "command"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -command {a command}
    .e cget -command
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.16 {configuration option: "cursor"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -cursor arrow
    .e cget -cursor
} -cleanup {
    destroy .e
} -result {arrow}
test spinbox-1.17 {configuration option: "cursor" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}

test spinbox-1.18 {configuration option: "disabledbackground"} -setup {

        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledbackground green
    .e cget -disabledbackground
} -cleanup {
    destroy .e
} -result {green}
test spinbox-1.19 {configuration option: "disabledbackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.20 {configuration option: "disabledforeground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledforeground #110022
    .e cget -disabledforeground
} -cleanup {
    destroy .e
} -result {#110022}
test spinbox-1.21 {configuration option: "disabledforeground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledforeground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.22 {configuration option: "exportselection"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -exportselection yes
    .e cget -exportselection
} -cleanup {
    destroy .e
} -result 1
test spinbox-1.23 {configuration option: "exportselection" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}

test spinbox-1.24 {configuration option: "fg"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -fg #110022
    .e cget -fg
} -cleanup {
    destroy .e
} -result {#110022}
test spinbox-1.25 {configuration option: "fg" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -fg bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.26 {configuration option: "font"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
    .e cget -font
} -cleanup {
    destroy .e
} -result {-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*}
test spinbox-1.27 {configuration option: "font" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \

        -relief sunken
    pack .e
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}

test spinbox-1.28 {configuration option: "foreground"} -setup {

        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -foreground #110022
    .e cget -foreground
} -cleanup {
    destroy .e
} -result {#110022}
test spinbox-1.29 {configuration option: "foreground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update

} -body {

    .e configure -foreground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.30 {configuration option: "format"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -format %0.5f
    .e cget -format
} -cleanup {
    destroy .e
} -result {%0.5f}
test spinbox-1.31 {configuration option: "format" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -format %d
} -cleanup {
    destroy .e

} -returnCodes {error} -result {bad spinbox format specifier "%d"}

test spinbox-1.32 {configuration option: "from"} -setup {


        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -from -10
    .e cget -from
} -cleanup {
    destroy .e
} -result {-10.0}
test spinbox-1.33 {configuration option: "from" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -from bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}

test spinbox-1.34 {configuration option: "highlightbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightbackground #123456
    .e cget -highlightbackground
} -cleanup {
    destroy .e
} -result {#123456}
test spinbox-1.35 {configuration option: "highlightbackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightbackground ugly
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "ugly"}

test spinbox-1.36 {configuration option: "highlightcolor"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightcolor #123456
    .e cget -highlightcolor
} -cleanup {
    destroy .e
} -result {#123456}
test spinbox-1.37 {configuration option: "highlightcolor" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \


        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightcolor bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.38 {configuration option: "highlightthickness"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness 6
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 6
test spinbox-1.39 {configuration option: "highlightthickness" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness bogus
} -cleanup {
    destroy .e



} -returnCodes {error} -result {bad screen distance "bogus"}

test spinbox-1.40 {configuration option: "highlightthickness"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness -2
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 0

test spinbox-1.41 {configuration option: "increment"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -increment 1.0
    .e cget -increment
} -cleanup {
    destroy .e
} -result {1.0}
test spinbox-1.42 {configuration option: "increment" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -increment bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}

test spinbox-1.43 {configuration option: "insertbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertbackground #110022
    .e cget -insertbackground





} -cleanup {
    destroy .e
} -result {#110022}
test spinbox-1.44 {configuration option: "insertbackground" for spinbox} -setup {

        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertbackground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.45 {configuration option: "insertborderwidth"} -setup {
        spinbox .e -borderwidth 2 -insertwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertborderwidth 1.3
    .e cget -insertborderwidth
} -cleanup {
    destroy .e
} -result 1
test spinbox-1.46 {configuration option: "insertborderwidth" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}

test spinbox-1.47 {configuration option: "insertofftime"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertofftime 100
    .e cget -insertofftime
} -cleanup {
    destroy .e
} -result 100
test spinbox-1.48 {configuration option: "insertofftime" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test spinbox-1.49 {configuration option: "insertontime"} -setup {



        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertontime 100
    .e cget -insertontime
} -cleanup {

    destroy .e
} -result 100
test spinbox-1.50 {configuration option: "insertontime" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}


test spinbox-1.51 {configuration option: "invalidcommand"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -invalidcommand "a command"
    .e cget -invalidcommand
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.52 {configuration option: "invcmd"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -invcmd "a command"
    .e cget -invcmd
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.53 {configuration option: "justify"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -justify right
    .e cget -justify
} -cleanup {
    destroy .e
} -result {right}
test spinbox-1.54 {configuration option: "justify" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -justify bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test spinbox-1.55 {configuration option: "readonlybackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -readonlybackground green
    .e cget -readonlybackground
} -cleanup {
    destroy .e
} -result {green}
test spinbox-1.56 {configuration option: "readonlybackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test spinbox-1.57 {configuration option: "relief"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -relief groove
    .e cget -relief
} -cleanup {
    destroy .e
} -result {groove}
test spinbox-1.58 {configuration option: "relief" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -relief 1.5
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test spinbox-1.59 {configuration option: "repeatdelay"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatdelay 500
    .e cget -repeatdelay
} -cleanup {
    destroy .e
} -result 500
test spinbox-1.60 {configuration option: "repeatdelay" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatdelay 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test spinbox-1.61 {configuration option: "repeatinterval"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatinterval -500
    .e cget -repeatinterval
} -cleanup {
    destroy .e
} -result -500
test spinbox-1.62 {configuration option: "repeatinterval" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatinterval 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test spinbox-1.63 {configuration option: "selectbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectbackground #110022
    .e cget -selectbackground
} -cleanup {
    destroy .e
} -result {#110022}
test spinbox-1.64 {configuration option: "selectbackground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectbackground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.65 {configuration option: "selectborderwidth"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectborderwidth 1.3
    .e cget -selectborderwidth
} -cleanup {
    destroy .e
} -result 1
test spinbox-1.66 {configuration option: "selectborderwidth" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test spinbox-1.67 {configuration option: "selectforeground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectforeground #654321
    .e cget -selectforeground
} -cleanup {
    destroy .e
} -result {#654321}
test spinbox-1.68 {configuration option: "selectforeground" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectforeground bogus
} -cleanup {

    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}

test spinbox-1.69 {configuration option: "state"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -state n
    .e cget -state
} -cleanup {
    destroy .e
} -result {normal}
test spinbox-1.70 {configuration option: "state" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -state bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad state "bogus": must be disabled, normal, or readonly}

test spinbox-1.71 {configuration option: "takefocus"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -takefocus "any string"
    .e cget -takefocus
} -cleanup {
    destroy .e
} -result {any string}

test spinbox-1.72 {configuration option: "textvariable"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -textvariable i
    .e cget -textvariable
} -cleanup {
    destroy .e
} -result {i}

test spinbox-1.73 {configuration option: "to"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -to 14.9
    .e cget -to
} -cleanup {
    destroy .e
} -result {14.9}
test spinbox-1.74 {configuration option: "to" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -to bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}

test spinbox-1.75 {configuration option: "validate"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -validate "key"
    .e cget -validate
} -cleanup {
    destroy .e
} -result {key}
test spinbox-1.76 {configuration option: "validate" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -validate "bogus"
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad validate "bogus": must be all, key, focus, focusin, focusout, or none}

test spinbox-1.77 {configuration option: "validatecommand"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -validatecommand "a command"
    .e cget -validatecommand
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.78 {configuration option: "values"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -values {mon tue wed thur}
    .e cget -values
} -cleanup {
    destroy .e
} -result {mon tue wed thur}
test spinbox-1.79 {configuration option: "values" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -values {bad {}list}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {list element in braces followed by "list" instead of space}

test spinbox-1.80 {configuration option: "vcmd"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -vcmd "a command"
    .e cget -vcmd
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.81 {configuration option: "width"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -width 402
    .e cget -width
} -cleanup {
    destroy .e
} -result 402
test spinbox-1.82 {configuration option: "width" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test spinbox-1.83 {configuration option: "wrap"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -wrap yes
    .e cget -wrap
} -cleanup {
    destroy .e
} -result 1
test spinbox-1.84 {configuration option: "wrap" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -wrap xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}

test spinbox-1.85 {configuration option: "xscrollcommand"} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -xscrollcommand {Some command}
    .e cget -xscrollcommand
} -cleanup {
    destroy .e
} -result {Some command}


test spinbox-2.1 {Tk_SpinboxCmd procedure} -body {
    spinbox
} -returnCodes error -result {wrong # args: should be "spinbox pathName ?-option value ...?"}
test spinbox-2.2 {Tk_SpinboxCmd procedure} -body {
    spinbox gorp
} -returnCodes error -result {bad window path name "gorp"}
test spinbox-2.3 {Tk_SpinboxCmd procedure} -body {
    spinbox .e
    pack .e
    update
    list [winfo exists .e] [winfo class .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {1 Spinbox .e}
test spinbox-2.4 {Tk_SpinboxCmd procedure} -body {
    spinbox .e -gorp foo
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-gorp"}
test spinbox-2.4.1 {Tk_SpinboxCmd procedure} -body {
    catch {spinbox .e -gorp foo}
    list [winfo exists .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {0 {}}
test spinbox-2.5 {Tk_SpinboxCmd procedure} -body {
    spinbox .e
} -cleanup {
    destroy .e
} -result {.e}


test spinbox-3.1 {SpinboxWidgetCmd procedure} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e option ?arg ...?"}
test spinbox-3.2 {SpinboxWidgetCmd procedure, "bbox" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test spinbox-3.3 {SpinboxWidgetCmd procedure, "bbox" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test spinbox-3.4 {SpinboxWidgetCmd procedure, "bbox" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e bbox bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "bogus"}
test spinbox-3.5 {SpinboxWidgetCmd procedure, "bbox" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
   .e bbox 0
} -cleanup {
    destroy .e
} -result [list 5 5 0 $cy]

# Oryginaly the result was count using measurements
# and metrics. It was changed to less verbose solution - the result is the one
# that passes fonts constraint (this concerns tests 3.6, 3.7, 3.8, 3.10)
test spinbox-3.6 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no utf chars
    .e insert 0 "abc"
    list [.e bbox 3] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{19 5 7 13} {19 5 7 13}}
test spinbox-3.7 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab乎"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test spinbox-3.8 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab乎c"
    .e bbox 3
} -cleanup {
    destroy .e
} -result {31 5 7 13}
test spinbox-3.9 {SpinboxWidgetCmd procedure, "bbox" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no chars
    .e bbox end
} -cleanup {
    destroy .e
} -result "5 5 0 $cy"
test spinbox-3.10 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert 0 "abcdefghij乎klmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{5 5 7 13} {12 5 7 13} {75 5 12 13} {122 5 7 13}}
test spinbox-3.11 {SpinboxWidgetCmd procedure, "cget" widget command} -setup {
    spinbox .e
} -body {
    .e cget
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e cget option"}
test spinbox-3.12 {SpinboxWidgetCmd procedure, "cget" widget command} -setup {
    spinbox .e
} -body {
    .e cget a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e cget option"}
test spinbox-3.13 {SpinboxWidgetCmd procedure, "cget" widget command} -setup {
    spinbox .e
} -body {
    .e cget -gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-gorp"}
test spinbox-3.14 {SpinboxWidgetCmd procedure, "cget" widget command} -setup {
    spinbox .e
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test spinbox-3.15 {SpinboxWidgetCmd procedure, "configure" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 51
test spinbox-3.16 {SpinboxWidgetCmd procedure, "configure" widget command} -setup {
    spinbox .e
} -body {
    .e configure -foo
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "-foo"}
test spinbox-3.17 {SpinboxWidgetCmd procedure, "configure" widget command} -setup {
    spinbox .e
} -body {
    .e configure -bd 4
    .e configure -bg #ffffff
    lindex [.e configure -bd] 4
} -cleanup {
    destroy .e
} -result 4
test spinbox-3.18 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
} -body {
    .e delete
} -cleanup {

    destroy .e
} -returnCodes error -result {wrong # args: should be ".e delete firstIndex ?lastIndex?"}
test spinbox-3.19 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
} -body {
    .e delete a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e delete firstIndex ?lastIndex?"}
test spinbox-3.20 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
} -body {
    .e delete foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "foo"}
test spinbox-3.21 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
} -body {
    .e delete 0 bar
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "bar"}
test spinbox-3.22 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 2 4
    .e get
} -cleanup {
    destroy .e
} -result 014567890
test spinbox-3.23 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
} -body {
    .e insert end "01234567890"
    .e delete 6
    .e get
} -cleanup {
    destroy .e
} -result 0123457890
test spinbox-3.24 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "01234乎67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345乎7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456乎890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "012347890" "0123457890" "012345890"]
test spinbox-3.25 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test spinbox-3.26 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test spinbox-3.26.1 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test spinbox-3.27 {SpinboxWidgetCmd procedure, "get" widget command} -setup {
    spinbox .e
} -body {
    .e get foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e get"}
test spinbox-3.28 {SpinboxWidgetCmd procedure, "icursor" widget command} -setup {
    spinbox .e
} -body {
    .e icursor
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e icursor pos"}
test spinbox-3.29 {SpinboxWidgetCmd procedure, "icursor" widget command} -setup {

    spinbox .e
} -body {
    .e icursor foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "foo"}
test spinbox-3.30 {SpinboxWidgetCmd procedure, "icursor" widget command} -setup {
    spinbox .e
} -body {
    .e insert end "01234567890"
    .e icursor 4
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test spinbox-3.31 {SpinboxWidgetCmd procedure, "index" widget command} -setup {
    spinbox .e
} -body {
    .e in
} -cleanup {
    destroy .e
} -returnCodes error -result {ambiguous option "in": must be bbox, cget, configure, delete, get, icursor, identify, index, insert, invoke, scan, selection, set, validate, or xview}
test spinbox-3.32 {SpinboxWidgetCmd procedure, "index" widget command} -setup {
    spinbox .e
} -body {
    .e index
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e index string"}
test spinbox-3.33 {SpinboxWidgetCmd procedure, "index" widget command} -setup {

    spinbox .e


} -body {
    .e index foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "foo"}
test spinbox-3.34 {SpinboxWidgetCmd procedure, "index" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e index 0
} -cleanup {
    destroy .e
} -returnCodes {ok} -match glob -result {*}
test spinbox-3.35 {SpinboxWidgetCmd procedure, "index" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
# UTF

    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e
} -result {3 4 8}
test spinbox-3.36 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {


    spinbox .e
} -body {
    .e insert a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test spinbox-3.37 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
} -body {
    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test spinbox-3.38 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
} -body {
    .e insert foo Text
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "foo"}
test spinbox-3.39 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e insert 3 xxx
    .e get
} -cleanup {
    destroy .e
} -result {012xxx34567890}
test spinbox-3.40 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test spinbox-3.40.1 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test spinbox-3.41 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
} -body {
    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test spinbox-3.42 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e scan a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test spinbox-3.43 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {


    spinbox .e






    pack .e
    update
} -body {
    .e scan a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test spinbox-3.44 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be mark or dragto}
test spinbox-3.45 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e scan mark 20.1
} -cleanup {
    destroy .e
} -returnCodes error -result {expected integer but got "20.1"}

# This test is non-portable because character sizes vary.
test spinbox-3.46 {SpinboxWidgetCmd procedure, "scan" widget command} -constraints {
    fonts
} -setup {
    spinbox .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0
} -cleanup {
    destroy .e
} -result 2
test spinbox-3.47 {SpinboxWidgetCmd procedure, "select" widget command} -setup {
    spinbox .e
} -body {
    .e select
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection option ?index?"}
test spinbox-3.48 {SpinboxWidgetCmd procedure, "select" widget command} -setup {
    spinbox .e
} -body {
    .e select foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad selection option "foo": must be adjust, clear, element, from, present, range, or to}

test spinbox-3.49 {SpinboxWidgetCmd procedure, "select clear" widget command} -setup {
    spinbox .e
} -body {
    .e select clear gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection clear"}
test spinbox-3.50 {SpinboxWidgetCmd procedure, "select clear" widget command} -setup {
    spinbox .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test spinbox-3.50.1 {SpinboxWidgetCmd procedure, "select clear" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    catch {selection get}
    selection own
} -cleanup {
    destroy .e
} -result {.e}

test spinbox-3.51 {SpinboxWidgetCmd procedure, "selection present" widget command} -setup {
    spinbox .e
} -body {
    .e selection present foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection present"}
test spinbox-3.52 {SpinboxWidgetCmd procedure, "selection present" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test spinbox-3.53 {SpinboxWidgetCmd procedure, "selection present" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test spinbox-3.54 {SpinboxWidgetCmd procedure, "selection present" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
} -cleanup {
    destroy .e
} -result 0
test spinbox-3.55 {SpinboxWidgetCmd procedure, "selection adjust" widget command} -setup {
    spinbox .e
} -body {
    .e select adjust x
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "x"}
test spinbox-3.56 {SpinboxWidgetCmd procedure, "selection adjust" widget command} -setup {
    spinbox .e
} -body {
    .e select adjust 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection adjust index"}
test spinbox-3.57 {SpinboxWidgetCmd procedure, "selection adjust" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get
} -cleanup {
    destroy .e
} -result 123
test spinbox-3.58 {SpinboxWidgetCmd procedure, "selection adjust" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
    selection get
} -cleanup {
    destroy .e
} -result 234
test spinbox-3.59 {SpinboxWidgetCmd procedure, "selection from" widget command} -setup {
    spinbox .e
} -body {
    .e select from 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection from index"}

test spinbox-3.60 {SpinboxWidgetCmd procedure, "selection range" widget command} -setup {
    spinbox .e
} -body {
    .e select range 2
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection range start end"}
test spinbox-3.61 {SpinboxWidgetCmd procedure, "selection range" widget command} -setup {
    spinbox .e
} -body {
    .e selection range 2 3 4
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection range start end"}
test spinbox-3.62 {SpinboxWidgetCmd procedure, "selection range" widget command} -setup {
    spinbox .e
} -body {
    .e insert end 0123456789
    .e select from 1
    .e select to 5
    .e select range 4 4
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test spinbox-3.63 {SpinboxWidgetCmd procedure, "selection range" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]
} -cleanup {
    destroy .e
} -result {2 9 3}
test spinbox-3.64 {SpinboxWidgetCmd procedure, "selection to" widget command} -setup {
    spinbox .e
    pack .e
    update
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
} -body {

    .e select to 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection to index"}
test spinbox-3.64.1 {SpinboxWidgetCmd procedure, "selection" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state disabled
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {0 10}
test spinbox-3.64.2 {SpinboxWidgetCmd procedure, "selection" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state readonly
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 4}

test spinbox-3.65 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 5
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.053763 0.268817}
test spinbox-3.66 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "gorp"}
test spinbox-3.67 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.107527 0.322581}
test spinbox-3.68 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo bar
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview moveto fraction"}
test spinbox-3.69 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "foo"}
test spinbox-3.70 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.505376 0.720430}
test spinbox-3.71 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview scroll 24
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview scroll number pages|units"}
test spinbox-3.72 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll gorp units
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "gorp"}
test spinbox-3.73 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.193548 0.408602}
test spinbox-3.74 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.397849 0.612903}
test spinbox-3.75 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} -cleanup {
    destroy .e
} -result 32
test spinbox-3.76 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} -cleanup {
    destroy .e
} -result 29
test spinbox-3.77 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll 23 foobars
} -cleanup {
    destroy .e
} -returnCodes error -result {bad argument "foobars": must be pages or units}
test spinbox-3.78 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview eat 23 hamburgers
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "eat": must be moveto or scroll}
test spinbox-3.79 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview -1
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test spinbox-3.80 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 300
    .e index @0
} -cleanup {
    destroy .e
} -result 73
test spinbox-3.81 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e insert 10 乎
    update
# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:
# 0.106383 0.117021 0.117021

    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .11
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .12
    lappend x [format {%.6f} [lindex [.e xview] 0]]
} -cleanup {
    destroy .e
} -result {0.095745 0.106383 0.117021}

test spinbox-3.82 {SpinboxWidgetCmd procedure} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, identify, index, insert, invoke, scan, selection, set, validate, or xview}



test spinbox-5.1 {ConfigureSpinbox procedure, -textvariable} -body {

    set x 12345
    spinbox .e -textvariable x
    .e get
} -cleanup {
    destroy .e
} -result 12345
test spinbox-5.2 {ConfigureSpinbox procedure, -textvariable} -body {

    set x 12345
    spinbox .e -textvariable x
    set y abcde
    .e configure -textvariable y
    set x 54321
    .e get
} -cleanup {
    destroy .e
} -result {abcde}
test spinbox-5.3 {ConfigureSpinbox procedure, -textvariable} -setup {

    unset -nocomplain x
    spinbox .e
} -body {
    .e insert 0 "Some text"
    .e configure -textvariable x
    set x
} -cleanup {
    destroy .e
} -result {Some text}
test spinbox-5.4 {ConfigureSpinbox procedure, -textvariable} -setup {


    unset -nocomplain x

    spinbox .e
} -body {
    trace variable x w override

    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override

} -result {12345 12345}

test spinbox-5.5 {ConfigureSpinbox procedure} -setup {
    set x {}
    spinbox .e1
    spinbox .e2
} -body {
    .e2 insert end "This is some sample text"
    .e1 configure -exportselection false
    .e1 insert end "0123456789"
    pack .e1 .e2
    .e2 select from 0
    .e2 select to 10

    lappend x [selection get]
    .e1 select from 1
    .e1 select to 5
    lappend x [selection get]
    .e1 configure -exportselection 1
    lappend x [selection get]
    set x
} -cleanup {
    destroy .e1 .e2
} -result {{This is so} {This is so} 1234}
test spinbox-5.6 {ConfigureSpinbox procedure} -setup {
    spinbox .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test spinbox-5.6.1 {ConfigureSpinbox procedure} -setup {
    spinbox .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    catch {selection get}
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5}

test spinbox-5.7 {ConfigureSpinbox procedure} -setup {

    spinbox .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}

test spinbox-5.8 {ConfigureSpinbox procedure} -constraints {
    fonts
} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -width 0 -font {Helvetica -12}
    .e insert end "0123"
    update
    .e configure -font {Helvetica -24}
    update
    winfo geom .e
} -cleanup {
    destroy .e
} -result {79x37+0+0}
test spinbox-5.9 {ConfigureSpinbox procedure} -constraints {
    fonts
} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test spinbox-5.10 {ConfigureSpinbox procedure} -constraints {
    fonts

} -setup {


    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief flat
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test spinbox-5.11 {ConfigureSpinbox procedure} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
# If "0" in selected font had 0 width, caused divide-by-zero error.


    .e configure -font {{open look glyph}}
    .e scan dragto 30
    update
} -cleanup {
    destroy .e
} -result {}
test spinbox-5.12 {ConfigureSpinbox procedure, -from and -to swapping} -setup {
    spinbox .e
} -body {
    # this statement used to trigger error "-to value must be greater than -from value"
    # because default value for -to is zero (bug [841280ffff])
    set res [catch {.e configure -from 10}]
    .e configure -from 1971 -to 2016  ; # standard case
    lappend res [.e cget -from] [.e cget -to]
    .e configure -from 2016 -to 1971  ; # auto-swapping happens
    lappend res [.e cget -from] [.e cget -to]
    .e configure -to 1971 -from 2016 ; # auto-swapping, order of options does not matter
    lappend res [.e cget -from] [.e cget -to]
} -cleanup {
    destroy .e
} -result {0 1971.0 2016.0 1971.0 2016.0 1971.0 2016.0}

# No tests for DisplaySpinbox.

test spinbox-6.1 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]
} -cleanup {
    destroy .e
} -result {3 4}
test spinbox-6.2 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 -justify center \
	    -highlightthickness 3

    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]
} -cleanup {
    destroy .e
} -result {3 4}
test spinbox-6.3 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 -justify right \
	    -highlightthickness 3

    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]
} -cleanup {
    destroy .e
} -result {3 4}
test spinbox-6.4 {SpinboxComputeGeometry procedure} -setup {

    spinbox .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test spinbox-6.5 {SpinboxComputeGeometry procedure} -setup {

    spinbox .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test spinbox-6.6 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 10
    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]
} -cleanup {
    destroy .e
} -result {5 6}
test spinbox-6.7 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 5
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {94 39}
test spinbox-6.8 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {133 39}
test spinbox-6.9 {SpinboxComputeGeometry procedure} -constraints {
    fonts
} -setup {
    spinbox .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {42 39}


test spinbox-7.1 {InsertChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e

} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 2 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test spinbox-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 500 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test spinbox-7.3 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {5 9 5 8}
test spinbox-7.4 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test spinbox-7.5 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test spinbox-7.6 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 6 2 5}
test spinbox-7.7 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -xscrollcommand scroll
    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 7
test spinbox-7.8 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test spinbox-7.9 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 7
test spinbox-7.10 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 4

test spinbox-7.11 {InsertChars procedure} -constraints {
    fonts
} -setup {
    spinbox .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e
} -cleanup {
    destroy .e
} -result 70

test spinbox-8.1 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 2 4
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test spinbox-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll


    .e insert 0 abcde

    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]


    .e delete -1 2
    vwait scrollInfo


    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test spinbox-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 3 1000
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test spinbox-8.4 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6 1 5}
test spinbox-8.5 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5 1 4}
test spinbox-8.6 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 2 1 5}
test spinbox-8.7 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test spinbox-8.8 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 4 3 8}
test spinbox-8.9 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test spinbox-8.10 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 5 5 8}
test spinbox-8.11 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 8 4 8}
test spinbox-8.12 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test spinbox-8.13 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test spinbox-8.14 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 4 6
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test spinbox-8.15 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test spinbox-8.16 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test spinbox-8.17 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6






    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test spinbox-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    spinbox .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
    # To check that deletion actually happened we measure the new width
    # of the widget, based on the measuring width of the remaining text ("xyy")
    # in the widget. For that purpose we have to mirror the code in tkEntry.c
    # for computation of the reqwidth
    # note: XPAD corresponds to the hardcoded    #define XPAD 1
    set XPAD 1
    set buttonWidth [expr { [font measure [.e cget -font] "0"] + 2 * (1 + $XPAD) }]
    if {$buttonWidth < 11} {
        set buttonWidth 11
    }
    set expected [expr { [font measure [.e cget -font] "xyy"] \
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) \
                          + $buttonWidth } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {

    destroy .e


    unset XPAD buttonWidth expected
} -result 1

test spinbox-9.1 {SpinboxValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    spinbox .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override

} -result {12345 12345}





test spinbox-10.1 {SpinboxSetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    spinbox .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0
    pack .e
    .e configure -textvariable x

    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {ab 35}
test spinbox-10.2 {SpinboxSetValue procedure, updating selection} -setup {
    unset -nocomplain x
    spinbox .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test spinbox-10.3 {SpinboxSetValue procedure, updating selection} -setup {
    unset -nocomplain x
    spinbox .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 7}
test spinbox-10.4 {SpinboxSetValue procedure, updating selection} -setup {
    unset -nocomplain x
    spinbox .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 10}
test spinbox-10.5 {SpinboxSetValue procedure, updating display position} -setup {
    unset -nocomplain x

    spinbox .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test spinbox-10.6 {SpinboxSetValue procedure, updating display position} -setup {
    unset -nocomplain x
    spinbox .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 10
test spinbox-10.7 {SpinboxSetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    spinbox .e -highlightthickness 2 -bd 2
    pack .e
    update
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} -cleanup {
    destroy .e
} -result 3
test spinbox-10.8 {SpinboxSetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    spinbox .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} -cleanup {
    destroy .e
} -result 5

test spinbox-11.1 {SpinboxEventProc procedure} -setup {
    spinbox .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    pack .e
} -body {
    .e insert 0 abcdefg
    destroy .e
    update
} -cleanup {
    destroy .e
} -result {}
test spinbox-11.2 {SpinboxEventProc procedure} -setup {
    set x {}
} -body {
    spinbox .e1 -fg #112233
    rename .e1 .e2

    lappend x [winfo children .]
    lappend x [.e2 cget -fg]
    destroy .e1
    lappend x [info command .e*] [winfo children .]
} -cleanup {
    destroy .e1
} -result {.e1 #112233 {} {}}

test spinbox-12.1 {SpinboxCmdDeletedProc procedure} -body {

    button .b -text "xyz_123"
    rename .b {}
    list [info command .b*] [winfo children .]
} -cleanup {
    destroy .b
} -result {{} {}}


test spinbox-13.1 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update

    .e index end
} -cleanup {
    destroy .e
} -result 21
test spinbox-13.2 {GetSpinboxIndex procedure} -body {
    spinbox .e
    .e index abogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "abogus"}
test spinbox-13.3 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    .e index anchor
} -cleanup {
    destroy .e
} -result 1
test spinbox-13.4 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 4
    .e select to 1
    .e index anchor
} -cleanup {
    destroy .e
} -result 4
test spinbox-13.5 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} -cleanup {
    destroy .e
} -result 15
test spinbox-13.6 {GetSpinboxIndex procedure} -setup {
    spinbox .e
} -body {
    .e index ebogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "ebogus"}
test spinbox-13.7 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e icursor 2
    .e index insert
} -cleanup {
    destroy .e
} -result 2
test spinbox-13.8 {GetSpinboxIndex procedure} -setup {
    spinbox .e
} -body {
    .e index ibogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "ibogus"}
test spinbox-13.9 {GetSpinboxIndex procedure} -setup {
    spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6}

test spinbox-13.10 {GetSpinboxIndex procedure} -constraints x11 -body {
# On unix, when selection is cleared, spinbox widget's internal
# selection range is reset.
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

test spinbox-13.11 {GetSpinboxIndex procedure} -constraints aquaOrWin32 -body {
# On mac and pc, when selection is cleared, spinbox widget remembers
# last selected range.  When selection ownership is restored to
# spinbox, the old range will be rehighlighted.
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e

    catch {selection get}
    .e index sel.first
} -cleanup {
    destroy .e
} -result 1

test spinbox-13.12 {GetSpinboxIndex procedure} -constraints x11 -body {
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

test spinbox-13.12.1 {GetSpinboxIndex procedure} -constraints unix -body {
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]

# Testing:
    selection clear .e
    .e index bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "bogus"}

test spinbox-13.13 {GetSpinboxIndex procedure} -constraints win -body {
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "sbogus"}

test spinbox-13.14 {GetSpinboxIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, spinbox widget remembers
# last selected range.  When selection ownership is restored to

# spinbox, the old range will be rehighlighted.
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]

# Testing:
    selection clear .e
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}

test spinbox-13.14.1 {GetSpinboxIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, spinbox widget remembers
# last selected range.  When selection ownership is restored to
# spinbox, the old range will be rehighlighted.
# Previous settings:
	spinbox .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    catch {selection get}
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}

test spinbox-13.15 {GetSpinboxIndex procedure} -body {
    spinbox .e
    selection clear .e
    .e index @xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "@xyz"}

test spinbox-13.16 {GetSpinboxIndex procedure} -constraints fonts -body {



    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @4
} -cleanup {
    destroy .e
} -result 4
test spinbox-13.17 {GetSpinboxIndex procedure} -constraints fonts -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @11
} -cleanup {
    destroy .e
} -result 4
test spinbox-13.18 {GetSpinboxIndex procedure} -constraints fonts -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @12
} -cleanup {
    destroy .e
} -result 5
test spinbox-13.19 {GetSpinboxIndex procedure} -constraints fonts -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 6-11}]
} -cleanup {
    destroy .e
} -result 8
test spinbox-13.20 {GetSpinboxIndex procedure} -constraints fonts -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 5}]
} -cleanup {
    destroy .e
} -result 9
test spinbox-13.21 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @1000
} -cleanup {
    destroy .e
} -result 9
test spinbox-13.22 {GetSpinboxIndex procedure} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e index 1xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad spinbox index "1xyz"}
test spinbox-13.23 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index -1
} -cleanup {
    destroy .e
} -result 0
test spinbox-13.24 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 12
} -cleanup {
    destroy .e
} -result 12
test spinbox-13.25 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 49
} -cleanup {
    destroy .e
} -result 21

# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.





test spinbox-14.1 {SpinboxFetchSelection procedure} -body {

    spinbox .e
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get
} -cleanup {
    destroy .e
} -result {his is a test str}
test spinbox-14.3 {SpinboxFetchSelection procedure} -setup {
    set x {}
    for {set i 1} {$i <= 500} {incr i} {
        append x "This is line $i, out of 500\n"
}
} -body {
    spinbox .e
    .e insert end $x
    .e select from 0
    .e select to end
    string compare [selection get] $x
} -cleanup {
    destroy .e
} -result 0

test spinbox-15.1 {SpinboxLostSelection} -body {

    spinbox .e
    .e insert 0 "Text"
    .e select from 0
    .e select to 4
    set result [selection get]
    selection clear
    .e select from 0
    .e select to 4
    lappend result [selection get]
} -cleanup {
    destroy .e
} -result {Text Text}



test spinbox-16.1 {SpinboxVisibleRange procedure} -constraints fonts  -body {

    spinbox .e -width 10 -font {Helvetica -12}
    pack .e
    update
    .e insert 0 "............................."



    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test spinbox-16.2 {SpinboxVisibleRange procedure} -body {
    spinbox .e
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 1.000000}


test spinbox-17.1 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]

    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test spinbox-17.2 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    .e insert 0 0123456789abcdef
    update idletasks
    set timeout [after 500 {set $scrollInfo {-1000000 -1000000}}]
    .e xview 3
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test spinbox-17.3 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {

    destroy .e
    after cancel $timeout
} -result {0.000000 0.526316}
test spinbox-17.4 {SpinboxUpdateScrollbar procedure} -setup {

    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    spinbox .e -width 5
    pack .e
    update idletasks
    .e configure -xscrollcommand thisisnotacommand
    vwait x

    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
    (horizontal scrolling command executed by .e)}}




test spinbox-18.1 {Spinbox widget vs hiding} -setup {

    spinbox .e
} -body {
    set l [interp hidden]
    interp hide {} .e
    destroy .e
    set res1 [list [winfo children .] [interp hidden]]
    set res2 [list {} $l]
    expr {$res1 == $res2}
} -result 1

##
## Spinbox widget VALIDATION tests
##
# The validation tests build each one upon the previous, so cascading
# failures aren't good
#
# 19.* test cases in previous version highly depended on the previous
# test cases. This was replaced by inserting recently set configurations
# that matters for the test case
test spinbox-19.1 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e









    .e insert 0 a
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 0 a {} a all key}

test spinbox-19.2 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a   ;# previous settings
    .e insert 1 b
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 1 ab a b all key}

test spinbox-19.3 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 ab   ;# previous settings
    .e insert end c
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 2 abc ab c all key}

test spinbox-19.4 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abc   ;# previous settings
    .e insert 1 123
    list $::vVals $::e
} -cleanup {
    destroy .e
} -result {{.e 1 1 a123bc abc 123 all key} a123bc}

test spinbox-19.5 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a123bc   ;# previous settings
    .e delete 2
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 2 a13bc a123bc 2 all key}

test spinbox-19.6 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a13bc   ;# previous settings
    .e configure -validate key
    .e delete 1 3
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 1 abc a13bc 13 key key}

test spinbox-19.7 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abc                 ;# previous settings
    set ::vVals {}

    .e insert end d
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test spinbox-19.8 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e configure -validate focus    ;# previous settings
    .e insert end abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusin}

test spinbox-19.9 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd      ;# previous settings
    focus -force .e         ;# previous settings
    update                  ;# previous settings
# update necessary to process FocusIn event
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusout}

test spinbox-19.10 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusin}

test spinbox-19.11 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e             ;# previous settings
# update necessary to process FocusIn event
    update                      ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusout}

test spinbox-19.12 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test spinbox-19.13 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test spinbox-19.14 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test spinbox-19.15 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusout focusout}

# the same as 19.16 but added [.e validate] to returned list

test spinbox-19.16 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \

        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    list [.e validate] $::vVals
} -cleanup {
    destroy .e
} -result {1 {.e -1 -1 abcd abcd {} all forced}}



test spinbox-19.17 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::e newdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {focusout {.e -1 -1 newdata abcd {} focusout forced}}


# proc doval changed - returns 0
test spinbox-19.18 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e newdata                 ;# previous settings
    .e configure -validate all
    set ::e nextdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {none {.e -1 -1 nextdata newdata {} all forced}}



## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the spinbox textvar is also set
# proc doval2 used
test spinbox-19.19 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e
} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}}



## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the spinbox widget shown as is in the textvar.
test spinbox-19.20 {spinbox widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings
    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] ;# prev
    .e validate                     ;# previous settings

    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test spinbox-19.21 {spinbox widget validation - bug 40e4bf6198} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate key \
        -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \
        -textvariable ::e
    pack .e
    set ::e origdata
    .e insert 0 A
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}}


##
## End validation tests
##

test spinbox-20.1 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2f
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.2 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2.2f
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.3 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %.2f
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.4 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2.f
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.5 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2e-1f
} -cleanup {
    destroy .e
}  -returnCodes {error} -result {bad spinbox format specifier "%2e-1f"}
test spinbox-20.6 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format 2.2
} -cleanup {
    destroy .e
}  -returnCodes {error} -result {bad spinbox format specifier "2.2"}
test spinbox-20.7 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2.-2f
} -cleanup {
    destroy .e
}  -returnCodes {error} -result {bad spinbox format specifier "%2.-2f"}
test spinbox-20.8 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %-2.02f
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.9 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format "% 2.02f"
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.10 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format "% -2.200f"
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.11 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format "%09.200f"
} -cleanup {
    destroy .e
} -returnCodes ok
test spinbox-20.12 {spinbox config, -format specifier does something} -setup {
    spinbox .e
    set out {}
} -body {
    .e config -format "%02.f"
    .e config -values {} -from 0 -to 10 -increment 1
    lappend out [.e set 0]; # set currently doesn't force format
    .e invoke buttonup
    lappend out [.e set]; # but after invoke it should be formatted
    lappend out [.e set 3]; # set currently doesn't force format
    .e config -format "%03.f"
    lappend out [.e set]; # changing -format should cause formatting
} -cleanup {
    destroy .e
} -result {0 01 3 003}


test spinbox-21.1 {spinbox button, out of range checking} -body {

    spinbox .e -from -10 -to 20 -increment 2
    set out {}
    lappend out [.e get]; # -10
    .e delete 0 end
    .e insert 0 25; # set outside of range
    .e invoke buttondown; # should constrain
    lappend out [.e get]; # 20



<
<
|



<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>

<
|
<
<
<
<
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<

<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<

<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|
<
|
<
<
<
>
|
|
<
<
|
<
<
<
|
<
>
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
>
|
>
|
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
>
|
|
<
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
|
>
>
|
|
|
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
|
<
<
<
>
>
>
>
>
|
|
<
|
>
|
|
|
|
|
|
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
>
>
>
|
<
|
<
<
<
<
<
>
|
<
<
|
<
<
<
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<
<
|
<
<
|
<
<
<
<
<
<
|
|
<
<
<
|
|
<
<
<
<
<
|
<
<
<
|
|
<
|
>
|
<

<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
|
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
|
<
<
<
|
|
|
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
<
|
|
|
<
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<


|


<
<
<
<
<
<
|
|
<
<
|
<



<
<
|
|
<
<
|
<





<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
>
<
<
<
<
<
|
|
|
<



|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
>
|
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
>
|

<
<
|
|
>
>
|
<
|
<
<
|
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
|
<



<
<
|
|
<
<
|
<





<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
>
>
|
>
>
>
>
>
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
<
<
<
|

<





|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
<
|
<
<
|
<
<
|
|
|
<





|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
|
<




|
<
<
|
<
<
|
<





|
|
<
|
<
<
|
<





|
<
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
<
<
|
<






<
<
|
|
<
<
|
<






<
<
|
|
<
<
|
<
<
|
<
|
<
<
|
<
<
|
|
<
<
|
<
<
|
|
|
<




|
<
<
|
|
<
<
|
<





<
<
|
<
<
<
|
|
|
<
>
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<


<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<




<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<


<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<



<
<
|
|
<
<
<
<
<
<




<
<
|
|
<
<
<
<
<
<




|
<
<
|
<
<
<
<
<
<




|
<
<
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<


|

|
<
<
|
<
<
<
<
<
<


|
|
<
|
<
<
<
<
<
<
<
|
|
|
>







<
<
|
<
|
<
<
<
<
|
<
<
|

>
>
|
>



<
<
|
|
>






<
<
|
|
>
|

<



<
<
|
|
>
>
|
>
|
|

>


|
<
<
|
>
|
<
|
|
|
|
<
<
<
|
<
|
|
>

|
|

|


<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<


<




|
|
<
<
<
|
|
>
|

<
<

|
<

<

<
<
<
|
<
|
<
|
|

<
<


|


<
<
|
|
<
|
|

<
<

<
<
<
<
<
<
|
>
|
>
>
|

<
<



<
<
|
|
<
<
<
|
>
>
|


<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<



|
<
|
|

<
<



<
<
|
|
<
<
<
|
<
|

>



<
<
|
|
<
<
<
|
<
|

>



<
<
|
|
>
|

<
<




|
<
<
|
>
|

<
<




|
<
<
|
<
|
|

<
<




<
<
|
|
<
|
|

<
<



<
<
|
|
<
|
|

<
<



<
<
|
|
<
|
|

<
<


<
<
|
<

|
<
|
|
|
>
|
<

<
<

<
>

<
<
<
|
<
|
<
<
|
<
<
<

<
<

<
>

<
<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<







<
<
|
|
<
|
<
<




|
<
<
|
<
|
<




|
<
<
|
<
|
<





|
<
<
|
<
|
<





|
<
<
|
|
<
<
<
|
<




<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
>
>

>
|
|
>
>
|
|
>
>

<
<
<
|
|
<
<
|
<
<
<

<
<

<
>

<
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<




<
|
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<




<
|
<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<








<
<
|
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



<

|
<
<
|
<
|
<
<



>
>
>
>
>
>

<
<
<
<
<
<
<
<
<
<
<

<
<
<
|
<
<
<
|
<
|
<
<
<
<
<
<
>
|
>
>
|
<
|
<
|
<

|

|
<
<
|
>
|

|
>
>
>
|


<
<

>



<
<
|
|
<
<
|
<
|



|
<
<
|
|
<
<
|
<
|




<
<
|
|
<
<
|
<
|




<
<
|
|
<
>
|

<
<






|
<
<
|
<
<
|
<
|







|
<
<
|
<
<
|
<
<
|





|
<
<
|
<
<
|
<
|





|
<
<

|
<
|
|



|
<
<
|
|
<


>




<
<
|

|
>
|
|
|
<
<
|

|
<
|
|
<
|
|
|
>

|
<
<
|
<
|
<
<
|
|
<
<
<
<
<
<



|
<
<
|
<
<
<
<
<
<



|
<
<
|
<
<
<
<
<
<




|
<
<
|
<
<
|
<
<
|
|
<
<
<
<
<
<


|
<
<
|
<
<
|
<
<
|
|
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
>
|
|
<
<
<

<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
|
<
>
|
|
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
|
<
>
|
<
<
<
|
<
<
<
<
|
>
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
|
<
<
<
|
|
>
>
>
|
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<

|
<
<



>
>
>
>
|
>





<
<
|
|
|
<
<
<
<





|
<
<

|
>









<
<
|

>

<
>
|
|
|
|
>
>
>

<
<
|
|
|

<
<
|

|
<
|
|
|
<
>


|

<
<
<
|
|
<
|

<
<

<
>

<
<
<
|
|
<
<
|
<

|
<
>

|
>

<
<
<
>



|
<
|

|
<
<
>

<
<
<
|




>
>

|
>

<
<


|
|
<
<




<
<
|
<
<
|
<
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<


<
<
|
<
|
<
<
<
<
<
<
<
<
<



<
<
|
<
|
<
<
<
<
<
<
<
<
<

>


<
<
<
|
|
<
<
<
<
<
<
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<

|


<
<
|
<
<
<
<
|
|
<
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<

|


<
<
|
<
|
<
<
<
<
<
<
<
<
<


|


|
<
<
|
|
<
<
<
<
<
<
<
<
<
<

|


<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<

|


<
<
|
|
|
>
|
|
<
|
<
<
>
|
|
<
<
|
<
<
<
<
<
|
<
<
<
<
|
>

|
<
<
<
<
<
<
<
<
<
|

<
<
<
|

|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
>



<
|
<
<
<
<
<
<
<
<
<
<
<


<
<
|
>
>






|
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
|
<
|
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
<
<
|
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<
|
|
<
<
|
<

<








<
<
|

<
|
>







1
2
3


4
5
6
7

8
9












































































10


11



12
13













14





















15





















16
17

18




19















20









21











22

23









24





















25

26
27



















28





















29

30










31








32


33
34
35
















36







37

38



39
40
41


42



43

44
45




46






47


48
49
50
51

52
53
54
55
56










57






58
59
60
61

62
63
64

















































65
66
67


68
69
70
71
72
73
74



75
76




















77
78
79
80
81











82









83





84




85
86




87



88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103

104






105







106






107





















108
109
110
111
112
113

114





115
116


117








118
119
120








121

122










123
124
125








126


127

128






129









130


131

132
133





134

















135



136





















137














































138
139
140
141
142
143
144


145


146






147
148



149
150





151



152
153

154
155
156

157




158


159













160











161
162










163




164

165
166
167


168









169




170


171






172






173
174










175




176


177
178


179



180
181
182



183
184






185



186
187





188
189



190





191



192
193





194
195
196


197





198



199











200
201


















202
203










204
205




206








207




208




209


210
211
















212
213



214








215


216
217







218
219



220




221


222
223









224
225


226




227

228







229





















230


231
232

233

234
235






236






237

238






239

240






































241













242
243
244
245
246






247
248


249

250
251
252


253
254


255

256
257
258
259
260


261













262


263


264
265


266


267
268
269





270
271
272

273
274
275
276


277


278


279
280


281


282
283
284
285
286
287
288













289




290
291
292
293


294
295
296
297
298

299


300







301


302


303
304


305

306
307
308


309
310


311

312
313
314
315
316


317













318


319


320
321




322


323
324
325
326
327
328
329
330
331
332
333

























334

335



336
337

338
339
340
341
342
343


344


345


346
347


348


349

350


351


352
353
354

355
356
357
358
359
360


361
















362


363


364
365


366

367
368
369
370
371


372


373

374
375
376
377
378
379
380

381


382

383
384
385
386
387
388


389


390


391
392


393


394
395


396

397
398
399
400
401
402


403
404


405

406
407
408
409
410
411


412
413


414


415

416


417


418
419


420


421
422
423

424
425
426
427
428


429
430


431

432
433
434
435
436


437



438
439
440

441
442


443





























444






445
446


447
448




449


450
451






452
453
454
455


456
457




458


459
460




461


462
463






464
465


466
467






468


469
470






471


472
473






474
475
476


477
478






479
480
481
482


483
484






485
486
487
488
489


490






491
492
493
494
495


496






497


498
499






500


501
502






503
504
505
506
507


508






509
510
511
512

513







514
515
516
517
518
519
520
521
522
523
524


525

526




527


528
529
530
531
532
533
534
535
536


537
538
539
540
541
542
543
544
545


546
547
548
549
550

551
552
553


554
555
556
557
558
559
560
561
562
563
564
565
566


567
568
569

570
571
572
573



574

575
576
577
578
579
580
581
582
583
584


585
586









587


588
589

590
591
592
593
594
595



596
597
598
599
600


601
602

603

604



605

606

607
608
609


610
611
612
613
614


615
616

617
618
619


620






621
622
623
624
625
626
627


628
629
630


631
632



633
634
635
636
637
638





639












640
641
642
643

644
645
646


647
648
649


650
651



652

653
654
655
656
657
658


659
660



661

662
663
664
665
666
667


668
669
670
671
672


673
674
675
676
677


678
679
680
681


682
683
684
685
686


687

688
689
690


691
692
693
694


695
696

697
698
699


700
701
702


703
704

705
706
707


708
709
710


711
712

713
714
715


716
717


718

719
720

721
722
723
724
725

726


727

728
729



730

731


732



733


734

735
736



737
738

739

740
741
742
743
744
745
746


747
748

749

750
751
752
753
754
755
756


757
758

759

760
761
762
763
764
765
766


767
768

769

770
771
772
773
774
775
776


777
778

779


780
781
782
783
784


785

786

787
788
789
790
791


792

793

794
795
796
797
798
799


800

801

802
803
804
805
806
807


808
809



810

811
812
813
814



815



















816



817
818
819
820
821
822
823
824
825
826
827
828
829
830



831
832


833



834


835

836
837



838
839

840


841
842
843
844
845
846
847
848


849
850

851


852
853
854
855
856
857
858
859


860
861

862


863
864
865
866
867
868
869
870


871
872

873


874
875
876
877

878


879
880

881


882
883
884
885
886
887
888
889


890
891

892

893
894
895
896

897


898
899

900


901
902
903
904
905
906
907
908


909
910

911


912
913
914
915
916
917
918
919


920
921

922


923
924
925

926
927


928

929


930
931
932

933
934


935

936


937
938
939

940
941


942

943


944
945
946

947
948


949

950


951
952
953

954
955


956

957


958
959
960
961
962
963
964
965
966
967











968



969



970

971






972
973
974
975
976

977

978

979
980
981
982


983
984
985
986
987
988
989
990
991
992
993


994
995
996
997
998


999
1000


1001

1002
1003
1004
1005
1006


1007
1008


1009

1010
1011
1012
1013
1014


1015
1016


1017

1018
1019
1020
1021
1022


1023
1024

1025
1026
1027


1028
1029
1030
1031
1032
1033
1034


1035


1036

1037
1038
1039
1040
1041
1042
1043
1044
1045


1046


1047


1048
1049
1050
1051
1052
1053
1054


1055


1056

1057
1058
1059
1060
1061
1062
1063


1064
1065

1066
1067
1068
1069
1070
1071


1072
1073

1074
1075
1076
1077
1078
1079
1080


1081
1082
1083
1084
1085
1086
1087


1088
1089
1090

1091
1092

1093
1094
1095
1096
1097
1098


1099

1100


1101
1102






1103
1104
1105
1106


1107






1108
1109
1110
1111


1112






1113
1114
1115
1116
1117


1118


1119


1120
1121






1122
1123
1124


1125


1126


1127
1128






1129




































1130
1131
1132
1133
1134
1135
1136



1137









1138





1139

1140






1141
1142

1143
1144
1145

1146
1147
1148
1149
1150











1151


1152

1153
1154

1155
1156



1157




1158
1159
1160





1161
1162















1163



1164
1165


1166



1167
1168
1169
1170
1171
1172





1173
1174


1175






1176
1177


1178






1179

1180

1181




























1182
1183


1184




1185
1186
























1187






1188
1189


1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203


1204
1205
1206




1207
1208
1209
1210
1211
1212


1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224


1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1236
1237


1238
1239
1240
1241


1242
1243
1244

1245
1246
1247

1248
1249
1250
1251
1252



1253
1254

1255
1256


1257

1258
1259



1260
1261


1262

1263
1264

1265
1266
1267
1268
1269



1270
1271
1272
1273
1274

1275
1276
1277


1278
1279



1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290


1291
1292
1293
1294


1295
1296
1297
1298


1299


1300

1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319


1320

1321









1322
1323


1324

1325









1326
1327


1328

1329









1330
1331


1332

1333









1334
1335


1336

1337









1338
1339
1340


1341

1342









1343
1344
1345
1346



1347
1348










1349
1350
1351
1352


1353

1354












1355
1356
1357
1358


1359




1360
1361





1362
1363
1364
1365


1366

1367












1368
1369


1370
1371
1372
1373
1374









1375
1376
1377
1378


1379

1380









1381
1382
1383
1384
1385
1386


1387
1388










1389
1390
1391
1392



1393
1394













1395
1396
1397
1398


1399
1400
1401
1402
1403
1404

1405


1406
1407
1408


1409





1410




1411
1412
1413
1414









1415
1416



1417
1418
1419

1420









1421


1422

1423
1424
1425
1426
1427

1428











1429
1430


1431
1432
1433
1434
1435
1436
1437
1438
1439
1440













1441
1442


1443
1444


















1445
1446

1447

1448
1449

1450
1451


1452

1453
1454


1455

1456
1457


1458

1459
1460


1461

1462


1463
1464

1465


1466
1467

1468


1469
1470

1471
1472


1473

1474
1475


1476

1477
1478


1479

1480
1481


1482

1483

1484
1485
1486
1487
1488
1489
1490
1491


1492
1493

1494
1495
1496
1497
1498
1499
1500
1501
1502
# This file is a Tcl script to test spinbox widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#


# Copyright (c) 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands















































































proc scroll args {



    global scrollInfo
    set scrollInfo $args













}











































# Create additional widget that's used to hold the selection at times.


spinbox .sel




.sel insert end "This is some sample text"

























# Font names













set big -adobe-helvetica-medium-r-normal--24-240-75-75-p-*-iso8859-1









set fixed -adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1























# Create entries in the option database to be sure that geometry options
# like border width have predictable values.









































option add *Spinbox.borderWidth 2

option add *Spinbox.highlightThickness 2










option add *Spinbox.font {Helvetica -12}











spinbox .e -bd 2 -relief sunken
pack .e
update
























set i 1

foreach test {



    {-activebackground #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-background #ff0000 #ff0000 non-existent


	    {unknown color name "non-existent"}}



    {-bd 4 4 badValue {bad screen distance "badValue"}}

    {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}




    {-buttonbackground #ff0000 #ff0000 non-existent






	    {unknown color name "non-existent"}}


    {-buttoncursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-command {a command} {a command} {} {}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-disabledbackground green green non-existent

	{unknown color name "non-existent"}}
    {-disabledforeground #110022 #110022 bogus {unknown color name "bogus"}}
    {-exportselection yes 1 xyzzy {expected boolean value but got "xyzzy"}}
    {-fg #110022 #110022 bogus {unknown color name "bogus"}}
    {-font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*










	-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-* {}






	{font "" doesn't exist}}
    {-foreground #110022 #110022 bogus {unknown color name "bogus"}}
    {-format %0.5f %0.5f %d {bad spinbox format specifier "%d"}}
    {-from -10 -10.0 bogus {expected floating-point number but got "bogus"}}

    {-highlightbackground #123456 #123456 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}

















































    {-highlightthickness -2 0 {} {}}
    {-increment 1.0 1.0 bogus {expected floating-point number but got "bogus"}}
    {-insertbackground #110022 #110022 bogus {unknown color name "bogus"}}


    {-insertborderwidth 1.3 1 2.6x {bad screen distance "2.6x"}}
    {-insertofftime 100 100 3.2 {expected integer but got "3.2"}}
    {-insertontime 100 100 3.2 {expected integer but got "3.2"}}
    {-invalidcommand "a command" "a command" {} {}}
    {-invcmd "a command" "a command" {} {}}
    {-justify right right bogus {bad justification "bogus": must be left, right, or center}}
    {-readonlybackground green green non-existent



	{unknown color name "non-existent"}}
    {-relief groove groove 1.5 {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}}




















    {-repeatdelay 500 500 3p {expected integer but got "3p"}}
    {-repeatinterval -500 -500 3p {expected integer but got "3p"}}
    {-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
    {-selectborderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}











    {-state n normal bogus {bad state "bogus": must be disabled, normal, or readonly}}









    {-takefocus "any string" "any string" {} {}}





    {-textvariable i i {} {}}




    {-to 14.9 14.9 bogus {expected floating-point number but got "bogus"}}
    {-validate "key" "key" "bogus" {bad validate "bogus": must be all, key, focus, focusin, focusout, or none}}




    {-validatecommand "a command" "a command" {} {}}



    {-values {mon tue wed thur} {mon tue wed thur} {bad {}list} {list element in braces followed by "list" instead of space}}
    {-vcmd "a command" "a command" {} {}}
    {-width 402 402 3p {expected integer but got "3p"}}
    {-wrap yes 1 xyzzy {expected boolean value but got "xyzzy"}}
    {-xscrollcommand {Some command} {Some command} {} {}}
} {
    set name [lindex $test 0]

    test spinbox-1.$i {configuration options} {
	.e configure $name [lindex $test 1]
	list [lindex [.e configure $name] 4] [.e cget $name]
    } [list [lindex $test 2] [lindex $test 2]]
    incr i
    if {[lindex $test 3] != ""} {
	test spinbox-1.$i {configuration options} {
	    list [catch {.e configure $name [lindex $test 3]} msg] $msg

	} [list 1 [lindex $test 4]]

    }






    .e configure $name [lindex [.e configure $name] 3]







    incr i






}






















test spinbox-2.1 {Tk_SpinboxCmd procedure} {
    list [catch {spinbox} msg] $msg
} {1 {wrong # args: should be "spinbox pathName ?options?"}}
test spinbox-2.2 {Tk_SpinboxCmd procedure} {
    list [catch {spinbox gorp} msg] $msg

} {1 {bad window path name "gorp"}}





test spinbox-2.3 {Tk_SpinboxCmd procedure} {
    catch {destroy .e}


    spinbox .e








    list [winfo exists .e] [winfo class .e] [info commands .e]
} {1 Spinbox .e}
test spinbox-2.4 {Tk_SpinboxCmd procedure} {








    catch {destroy .e}

    list [catch {spinbox .e -gorp foo} msg] $msg [winfo exists .e] \










	    [info commands .e]
} {1 {unknown option "-gorp"} 0 {}}
test spinbox-2.5 {Tk_SpinboxCmd procedure} {








    catch {destroy .e}


    spinbox .e

} {.e}
















catch {destroy .e}


spinbox .e -font $fixed

pack .e
update























set cx [font measure $fixed a]



set cy [font metrics $fixed -linespace]





















set ux [font measure $fixed \u4e4e]















































test spinbox-3.1 {SpinboxWidgetCmd procedure} {
    list [catch {.e} msg] $msg
} {1 {wrong # args: should be ".e option ?arg arg ...?"}}
test spinbox-3.2 {SpinboxWidgetCmd procedure, "bbox" widget command} {
    list [catch {.e bbox} msg] $msg
} {1 {wrong # args: should be ".e bbox index"}}


test spinbox-3.3 {SpinboxWidgetCmd procedure, "bbox" widget command} {


    list [catch {.e bbox a b} msg] $msg






} {1 {wrong # args: should be ".e bbox index"}}
test spinbox-3.4 {SpinboxWidgetCmd procedure, "bbox" widget command} {



    list [catch {.e bbox bogus} msg] $msg
} {1 {bad spinbox index "bogus"}}





test spinbox-3.5 {SpinboxWidgetCmd procedure, "bbox" widget command} {



    .e delete 0 end
    .e bbox 0

} [list 5 5 0 $cy]
test spinbox-3.6 {SpinboxWidgetCmd procedure, "bbox" widget command} {
    # Tcl_UtfAtIndex(): no utf chars






    .e delete 0 end


    .e insert 0 "abc"













    list [.e bbox 3] [.e bbox end]











} [list "[expr 5+2*$cx] 5 $cx $cy" "[expr 5+2*$cx] 5 $cx $cy"]
test spinbox-3.7 {SpinboxWidgetCmd procedure, "bbox" widget command} {










    # Tcl_UtfAtIndex(): utf at end




    .e delete 0 end

    .e insert 0 "ab\u4e4e"
    .e bbox end
} "[expr 5+2*$cx] 5 $ux $cy"


test spinbox-3.8 {SpinboxWidgetCmd procedure, "bbox" widget command} {









    # Tcl_UtfAtIndex(): utf before index




    .e delete 0 end


    .e insert 0 "ab\u4e4ec"






    .e bbox 3






} "[expr 5+2*$cx+$ux] 5 $cx $cy"
test spinbox-3.9 {SpinboxWidgetCmd procedure, "bbox" widget command} {










    # Tcl_UtfAtIndex(): no chars




    .e delete 0 end


    .e bbox end
} "5 5 0 $cy"


test spinbox-3.10 {SpinboxWidgetCmd procedure, "bbox" widget command} {



    .e delete 0 end
    .e insert 0 "abcdefghij\u4e4eklmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]



} [list "5 5 $cx $cy" "[expr 5+$cx] 5 $cx $cy" "[expr 5+10*$cx] 5 $ux $cy" "[expr 5+$ux+15*$cx] 5 $cx $cy"]
test spinbox-3.11 {SpinboxWidgetCmd procedure, "cget" widget command} {






    list [catch {.e cget} msg] $msg



} {1 {wrong # args: should be ".e cget option"}}
test spinbox-3.12 {SpinboxWidgetCmd procedure, "cget" widget command} {





    list [catch {.e cget a b} msg] $msg
} {1 {wrong # args: should be ".e cget option"}}



test spinbox-3.13 {SpinboxWidgetCmd procedure, "cget" widget command} {





    list [catch {.e cget -gorp} msg] $msg



} {1 {unknown option "-gorp"}}
test spinbox-3.14 {SpinboxWidgetCmd procedure, "cget" widget command} {





    .e configure -bd 4
    .e cget -bd
} {4}


test spinbox-3.15 {SpinboxWidgetCmd procedure, "configure" widget command} {





    llength [.e configure]



} {49}











test spinbox-3.16 {SpinboxWidgetCmd procedure, "configure" widget command} {
    list [catch {.e configure -foo} msg] $msg


















} {1 {unknown option "-foo"}}
test spinbox-3.17 {SpinboxWidgetCmd procedure, "configure" widget command} {










    .e configure -bd 4
    .e configure -bg #ffffff




    lindex [.e configure -bd] 4








} {4}




test spinbox-3.18 {SpinboxWidgetCmd procedure, "delete" widget command} {




    list [catch {.e delete} msg] $msg


} {1 {wrong # args: should be ".e delete firstIndex ?lastIndex?"}}
test spinbox-3.19 {SpinboxWidgetCmd procedure, "delete" widget command} {
















    list [catch {.e delete a b c} msg] $msg
} {1 {wrong # args: should be ".e delete firstIndex ?lastIndex?"}}



test spinbox-3.20 {SpinboxWidgetCmd procedure, "delete" widget command} {








    list [catch {.e delete foo} msg] $msg


} {1 {bad spinbox index "foo"}}
test spinbox-3.21 {SpinboxWidgetCmd procedure, "delete" widget command} {







    list [catch {.e delete 0 bar} msg] $msg
} {1 {bad spinbox index "bar"}}



test spinbox-3.22 {SpinboxWidgetCmd procedure, "delete" widget command} {




    .e delete 0 end


    .e insert end "01234567890"
    .e delete 2 4









    .e get
} {014567890}


test spinbox-3.23 {SpinboxWidgetCmd procedure, "delete" widget command} {




    .e delete 0 end

    .e insert end "01234567890"







    .e delete 6





















    .e get


} {0123457890}
test spinbox-3.24 {SpinboxWidgetCmd procedure, "delete" widget command} {

    # UTF

    set x {}
    .e delete 0 end






    .e insert end "01234\u4e4e67890"






    .e delete 6

    lappend x [.e get]






    .e delete 0 end

    .e insert end "012345\u4e4e7890"






































    .e delete 6













    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456\u4e4e890"
    .e delete 6
    lappend x [.e get]






} [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
test spinbox-3.25 {SpinboxWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e delete 6 5
    .e get


} {01234567890}
test spinbox-3.26 {SpinboxWidgetCmd procedure, "delete" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get


} {01234567890}













test spinbox-3.27 {SpinboxWidgetCmd procedure, "get" widget command} {


    list [catch {.e get foo} msg] $msg


} {1 {wrong # args: should be ".e get"}}
test spinbox-3.28 {SpinboxWidgetCmd procedure, "icursor" widget command} {


    list [catch {.e icursor} msg] $msg


} {1 {wrong # args: should be ".e icursor pos"}}
test spinbox-3.29 {SpinboxWidgetCmd procedure, "icursor" widget command} {
    list [catch {.e icursor foo} msg] $msg





} {1 {bad spinbox index "foo"}}
test spinbox-3.30 {SpinboxWidgetCmd procedure, "icursor" widget command} {
    .e delete 0 end

    .e insert end "01234567890"
    .e icursor 4
    .e index insert
} {4}


test spinbox-3.31 {SpinboxWidgetCmd procedure, "index" widget command} {


    list [catch {.e in} msg] $msg


} {1 {ambiguous option "in": must be bbox, cget, configure, delete, get, icursor, identify, index, insert, invoke, scan, selection, set, validate, or xview}}
test spinbox-3.32 {SpinboxWidgetCmd procedure, "index" widget command} {


    list [catch {.e index} msg] $msg


} {1 {wrong # args: should be ".e index string"}}
test spinbox-3.33 {SpinboxWidgetCmd procedure, "index" widget command} {
    list [catch {.e index foo} msg] $msg
} {1 {bad spinbox index "foo"}}
test spinbox-3.34 {SpinboxWidgetCmd procedure, "index" widget command} {
    list [catch {.e index 0} msg] $msg
} {0 0}













test spinbox-3.35 {SpinboxWidgetCmd procedure, "index" widget command} {




    # UTF
    .e delete 0 end
    .e insert 0 abc\u4e4e\u0153def
    list [.e index 3] [.e index 4] [.e index end]


} {3 4 8}
test spinbox-3.36 {SpinboxWidgetCmd procedure, "insert" widget command} {
    list [catch {.e insert a} msg] $msg
} {1 {wrong # args: should be ".e insert index text"}}
test spinbox-3.37 {SpinboxWidgetCmd procedure, "insert" widget command} {

    list [catch {.e insert a b c} msg] $msg


} {1 {wrong # args: should be ".e insert index text"}}







test spinbox-3.38 {SpinboxWidgetCmd procedure, "insert" widget command} {


    list [catch {.e insert foo Text} msg] $msg


} {1 {bad spinbox index "foo"}}
test spinbox-3.39 {SpinboxWidgetCmd procedure, "insert" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e insert 3 xxx
    .e get


} {012xxx34567890}
test spinbox-3.40 {SpinboxWidgetCmd procedure, "insert" widget command} {


    .e delete 0 end

    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get


} {01234567890}













test spinbox-3.41 {SpinboxWidgetCmd procedure, "insert" widget command} {


    list [catch {.e insert a b c} msg] $msg


} {1 {wrong # args: should be ".e insert index text"}}
test spinbox-3.42 {SpinboxWidgetCmd procedure, "scan" widget command} {




    list [catch {.e scan a} msg] $msg


} {1 {wrong # args: should be ".e scan mark|dragto x"}}
test spinbox-3.43 {SpinboxWidgetCmd procedure, "scan" widget command} {
    list [catch {.e scan a b c} msg] $msg
} {1 {wrong # args: should be ".e scan mark|dragto x"}}
test spinbox-3.44 {SpinboxWidgetCmd procedure, "scan" widget command} {
    list [catch {.e scan foobar 20} msg] $msg
} {1 {bad scan option "foobar": must be mark or dragto}}
test spinbox-3.45 {SpinboxWidgetCmd procedure, "scan" widget command} {
    list [catch {.e scan mark 20.1} msg] $msg
} {1 {expected integer but got "20.1"}}
# This test is non-portable because character sizes vary.



























test spinbox-3.46 {SpinboxWidgetCmd procedure, "scan" widget command} {fonts} {



    .e delete 0 end
    update

    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0
} {2}


test spinbox-3.47 {SpinboxWidgetCmd procedure, "select" widget command} {


    list [catch {.e select} msg] $msg


} {1 {wrong # args: should be ".e selection option ?index?"}}
test spinbox-3.48 {SpinboxWidgetCmd procedure, "select" widget command} {


    list [catch {.e select foo} msg] $msg


} {1 {bad selection option "foo": must be adjust, clear, element, from, present, range, or to}}

test spinbox-3.49 {SpinboxWidgetCmd procedure, "select clear" widget command} {


    list [catch {.e select clear gorp} msg] $msg


} {1 {wrong # args: should be ".e selection clear"}}
test spinbox-3.50 {SpinboxWidgetCmd procedure, "select clear" widget command} {
    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
    list [catch {selection get} msg] $msg [selection own]


} {1 {PRIMARY selection doesn't exist or form "STRING" not defined} .e}
















test spinbox-3.51 {SpinboxWidgetCmd procedure, "selection present" widget command} {


    list [catch {.e selection present foo} msg] $msg


} {1 {wrong # args: should be ".e selection present"}}
test spinbox-3.52 {SpinboxWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} {1}


test spinbox-3.53 {SpinboxWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} {1}
.e configure -exportselection true

test spinbox-3.54 {SpinboxWidgetCmd procedure, "selection present" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
} {0}


test spinbox-3.55 {SpinboxWidgetCmd procedure, "selection adjust" widget command} {


    list [catch {.e select adjust x} msg] $msg


} {1 {bad spinbox index "x"}}
test spinbox-3.56 {SpinboxWidgetCmd procedure, "selection adjust" widget command} {


    list [catch {.e select adjust 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection adjust index"}}
test spinbox-3.57 {SpinboxWidgetCmd procedure, "selection adjust" widget command} {


    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get


} {123}
test spinbox-3.58 {SpinboxWidgetCmd procedure, "selection adjust" widget command} {


    .e delete 0 end

    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
    selection get


} {234}
test spinbox-3.59 {SpinboxWidgetCmd procedure, "selection from" widget command} {


    list [catch {.e select from 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection from index"}}

test spinbox-3.60 {SpinboxWidgetCmd procedure, "selection range" widget command} {


    list [catch {.e select range 2} msg] $msg


} {1 {wrong # args: should be ".e selection range start end"}}
test spinbox-3.61 {SpinboxWidgetCmd procedure, "selection range" widget command} {


    list [catch {.e selection range 2 3 4} msg] $msg


} {1 {wrong # args: should be ".e selection range start end"}}
test spinbox-3.62 {SpinboxWidgetCmd procedure, "selection range" widget command} {
    .e delete 0 end

    .e insert end 0123456789
    .e select from 1
    .e select to 5
    .e select range 4 4
    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test spinbox-3.63 {SpinboxWidgetCmd procedure, "selection range" widget command} {


    .e delete 0 end

    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]


} {2 9 3}



.e delete 0 end
.e insert end "This is quite a long text string, so long that it "
.e insert end "runs off the end of the window quite a bit."

test spinbox-3.64 {SpinboxWidgetCmd procedure, "selection to" widget command} {
    list [catch {.e select to 2 3} msg] $msg


} {1 {wrong # args: should be ".e selection to index"}}





























test spinbox-3.65 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 5
    format {%.6f %.6f} {*}[.e xview]


} {0.053763 0.268817}
test spinbox-3.66 {SpinboxWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview gorp} msg] $msg


} {1 {bad spinbox index "gorp"}}
test spinbox-3.67 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]


} {0.107527 0.322581}
test spinbox-3.68 {SpinboxWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview moveto foo bar} msg] $msg


} {1 {wrong # args: should be ".e xview moveto fraction"}}
test spinbox-3.69 {SpinboxWidgetCmd procedure, "xview" widget command} {




    list [catch {.e xview moveto foo} msg] $msg


} {1 {expected floating-point number but got "foo"}}
test spinbox-3.70 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]


} {0.505376 0.720430}
test spinbox-3.71 {SpinboxWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll 24} msg] $msg


} {1 {wrong # args: should be ".e xview scroll number units|pages"}}
test spinbox-3.72 {SpinboxWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll gorp units} msg] $msg


} {1 {expected integer but got "gorp"}}
test spinbox-3.73 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]


} {0.193548 0.408602}
test spinbox-3.74 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]


} {0.397849 0.612903}
test spinbox-3.75 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} {32}


test spinbox-3.76 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} {29}


test spinbox-3.77 {SpinboxWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview scroll 23 foobars} msg] $msg


} {1 {bad argument "foobars": must be units or pages}}
test spinbox-3.78 {SpinboxWidgetCmd procedure, "xview" widget command} {






    list [catch {.e xview eat 23 hamburgers} msg] $msg


} {1 {unknown option "eat": must be moveto or scroll}}
test spinbox-3.79 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 0
    update
    .e xview -4
    .e index @0
} {0}


test spinbox-3.80 {SpinboxWidgetCmd procedure, "xview" widget command} {






    .e xview 300
    .e index @0
} {73}
.e insert 10 \u4e4e

test spinbox-3.81 {SpinboxWidgetCmd procedure, "xview" widget command} {







    # UTF
    # If Tcl_NumUtfChars wasn't used, wrong answer would be:
    # 0.106383 0.117021 0.117021

    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .11
    lappend x [format {%.6f} [lindex [.e xview] 0]]
    .e xview moveto .12
    lappend x [format {%.6f} [lindex [.e xview] 0]]


} {0.095745 0.106383 0.117021}

test spinbox-3.82 {SpinboxWidgetCmd procedure} {




    list [catch {.e gorp} msg] $msg


} {1 {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, identify, index, insert, invoke, scan, selection, set, validate, or xview}}

frame .f -width 200 -height 50 -relief raised -bd 2
pack .f -side right
test spinbox-5.1 {ConfigureSpinbox procedure, -textvariable} {
    catch {destroy .e}
    set x 12345
    spinbox .e -textvariable x
    .e get


} {12345}
test spinbox-5.2 {ConfigureSpinbox procedure, -textvariable} {
    catch {destroy .e}
    set x 12345
    spinbox .e -textvariable x
    set y abcde
    .e configure -textvariable y
    set x 54321
    .e get


} {abcde}
test spinbox-5.3 {ConfigureSpinbox procedure, -textvariable} {
    catch {destroy .e}
    catch {unset x}
    spinbox .e

    .e insert 0 "Some text"
    .e configure -textvariable x
    set x


} {Some text}
test spinbox-5.4 {ConfigureSpinbox procedure, -textvariable} {
    proc override args {
	global x
	set x 12345
    }
    catch {destroy .e}
    catch {unset x}
    trace variable x w override
    spinbox .e
    .e insert 0 "Some text"
    .e configure -textvariable x
    set result [list $x [.e get]]


    unset x;  rename override {}
    set result
} {12345 12345}

test spinbox-5.5 {ConfigureSpinbox procedure} {
    catch {destroy .e}
    spinbox .e -exportselection false
    pack .e



    .e insert end "0123456789"

    .sel select from 0
    .sel select to 10
    set x {}
    lappend x [selection get]
    .e select from 1
    .e select to 5
    lappend x [selection get]
    .e configure -exportselection 1
    lappend x [selection get]
    set x


} {{This is so} {This is so} 1234}
test spinbox-5.6 {ConfigureSpinbox procedure} {









    catch {destroy .e}


    spinbox .e
    pack .e

    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    list [catch {selection get} msg] $msg [.e index sel.first] \
	    [.e index sel.last]



} {1 {PRIMARY selection doesn't exist or form "STRING" not defined} 1 5}
test spinbox-5.7 {ConfigureSpinbox procedure} {
    catch {destroy .e}
    spinbox .e -font $fixed -width 4 -xscrollcommand scroll
    pack .e


    .e insert end "01234567890"
    update

    .e configure -width 5

    format {%.6f %.6f} {*}$scrollInfo



} {0.000000 0.363636}

test spinbox-5.8 {ConfigureSpinbox procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -width 0
    pack .e


    .e insert end "0123"
    update
    .e configure -font $big
    update
    winfo geom .e


} {79x37+0+0}
test spinbox-5.9 {ConfigureSpinbox procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief raised
    pack .e


    .e insert end "0123"






    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} {0 0 1 1}
test spinbox-5.10 {ConfigureSpinbox procedure} {fonts} {
    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief flat
    pack .e


    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]


} {0 0 1 1}
test spinbox-5.11 {ConfigureSpinbox procedure} {



    # If "0" in selected font had 0 width, caused divide-by-zero error.

    catch {destroy .e}
    pack [spinbox .e -font {{open look glyph}}]
    .e scan dragto 30
    update





} {}













# No tests for DisplaySpinbox.

test spinbox-6.1 {SpinboxComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief raised -width 20 -highlightthickness 3
    pack .e


    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]


} {3 4}
test spinbox-6.2 {SpinboxComputeGeometry procedure} {fonts} {



    catch {destroy .e}

    spinbox .e -font $fixed -bd 2 -relief raised -width 20 -justify center \
	    -highlightthickness 3
    pack .e
    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]


} {3 4}
test spinbox-6.3 {SpinboxComputeGeometry procedure} {fonts} {



    catch {destroy .e}

    spinbox .e -font $fixed -bd 2 -relief raised -width 20 -justify right \
	    -highlightthickness 3
    pack .e
    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]


} {3 4}
test spinbox-6.4 {SpinboxComputeGeometry procedure} {
    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief raised -width 5
    pack .e


    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} {6}


test spinbox-6.5 {SpinboxComputeGeometry procedure} {
    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief raised -width 5
    pack .e


    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} {6}


test spinbox-6.6 {SpinboxComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $fixed -bd 2 -relief raised -width 10
    pack .e


    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]


} {5 6}
test spinbox-6.7 {SpinboxComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $big -bd 3 -relief raised -width 5
    pack .e


    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {94 39}
test spinbox-6.8 {SpinboxComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $big -bd 3 -relief raised -width 0
    pack .e


    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {133 39}
test spinbox-6.9 {SpinboxComputeGeometry procedure} {fonts} {

    catch {destroy .e}
    spinbox .e -font $big -bd 3 -relief raised -width 0 -highlightthickness 2
    pack .e


    update
    list [winfo reqwidth .e] [winfo reqheight .e]


} {42 39}


catch {destroy .e}

spinbox .e -width 10 -font $fixed -textvariable contents -xscrollcommand scroll
pack .e
focus .e
test spinbox-7.1 {InsertChars procedure} {
    .e delete 0 end

    .e insert 0 abcde


    .e insert 2 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abXXXcde abXXXcde {0.000000 1.000000}}

test spinbox-7.2 {InsertChars procedure} {


    .e delete 0 end



    .e insert 0 abcde


    .e insert 500 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abcdeXXX abcdeXXX {0.000000 1.000000}}
test spinbox-7.3 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {5 9 5 8}
test spinbox-7.4 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {2 9 2 8}
test spinbox-7.5 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {2 9 2 8}
test spinbox-7.6 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {2 6 2 5}
test spinbox-7.7 {InsertChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} {7}


test spinbox-7.8 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} {4}


test spinbox-7.9 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} {7}


test spinbox-7.10 {InsertChars procedure} {

    .e delete 0 end

    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} {4}


.e configure -width 0
test spinbox-7.11 {InsertChars procedure} {fonts} {



    .e delete 0 end

    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e



} {70}























.e configure -width 10
test spinbox-8.1 {DeleteChars procedure} {
    .e delete 0 end
    .e insert 0 abcde
    .e delete 2 4
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} {abe abe {0.000000 1.000000}}
test spinbox-8.2 {DeleteChars procedure} {
    .e delete 0 end
    .e insert 0 abcde
    .e delete -2 2
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {cde cde {0.000000 1.000000}}
test spinbox-8.3 {DeleteChars procedure} {


    .e delete 0 end



    .e insert 0 abcde


    .e delete 3 1000

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]



} {abc abc {0.000000 1.000000}}
test spinbox-8.4 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {1 6 1 5}
test spinbox-8.5 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]


} {1 5 1 4}
test spinbox-8.6 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]


} {1 2 1 5}
test spinbox-8.7 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8

    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test spinbox-8.8 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {3 4 3 8}
test spinbox-8.9 {DeleteChars procedure} {

    .e delete 0 end

    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8

    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test spinbox-8.10 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]


} {3 5 5 8}
test spinbox-8.11 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]


} {3 8 4 8}
test spinbox-8.12 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4

    .e index insert
} {1}


test spinbox-8.13 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5

    .e index insert
} {1}


test spinbox-8.14 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 4 6

    .e index insert
} {4}


test spinbox-8.15 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4

    .e index @0
} {1}


test spinbox-8.16 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5

    .e index @0
} {1}


test spinbox-8.17 {DeleteChars procedure} {

    .e delete 0 end


    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6
    .e index @0
} {4}
.e configure -width 0
test spinbox-8.18 {DeleteChars procedure} {fonts} {
    .e delete 0 end
    .e insert 0 "xyzzy"
    update











    .e delete 2 4



    winfo reqwidth .e



} {42}








test spinbox-9.1 {SpinboxValueChanged procedure} {
    catch {destroy .e}
    proc override args {
	global x
	set x 12345

    }

    catch {unset x}

    trace variable x w override
    spinbox .e -textvariable x
    .e insert 0 foo
    set result [list $x [.e get]]


    unset x; rename override {}
    set result
} {12345 12345}

catch {destroy .e}
spinbox .e
pack .e
.e configure -width 0
test spinbox-10.1 {SpinboxSetValue procedure} {fonts} {
    set x abcde
    set y ab


    .e configure -textvariable x
    update
    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]


} {ab 35}
test spinbox-10.2 {SpinboxSetValue procedure, updating selection} {


    catch {destroy .e}

    spinbox .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    list [catch {.e index sel.first} msg] $msg


} {1 {selection isn't in widget .e}}
test spinbox-10.3 {SpinboxSetValue procedure, updating selection} {


    catch {destroy .e}

    spinbox .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]


} {4 7}
test spinbox-10.4 {SpinboxSetValue procedure, updating selection} {


    catch {destroy .e}

    spinbox .e -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]


} {4 10}
test spinbox-10.5 {SpinboxSetValue procedure, updating display position} {

    catch {destroy .e}
    spinbox .e -width 10 -font $fixed -textvariable x
    pack .e


    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} {0}


test spinbox-10.6 {SpinboxSetValue procedure, updating display position} {


    catch {destroy .e}

    spinbox .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} {10}


test spinbox-10.7 {SpinboxSetValue procedure, updating insertion cursor} {


    catch {destroy .e}


    spinbox .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} {3}


test spinbox-10.8 {SpinboxSetValue procedure, updating insertion cursor} {


    catch {destroy .e}

    spinbox .e -width 10 -font $fixed -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} {5}



test spinbox-11.1 {SpinboxEventProc procedure} {

    catch {destroy .e}
    spinbox .e
    .e insert 0 abcdefg
    destroy .e
    update
} {}


test spinbox-11.2 {SpinboxEventProc procedure} {
    deleteWindows

    spinbox .e1 -fg #112233
    rename .e1 .e2
    set x {}
    lappend x [winfo children .]
    lappend x [.e2 cget -fg]
    destroy .e1
    lappend x [info command .e*] [winfo children .]


} {.e1 #112233 {} {}}

test spinbox-12.1 {SpinboxCmdDeletedProc procedure} {
    deleteWindows
    button .e1 -text "xyz_123"
    rename .e1 {}
    list [info command .e*] [winfo children .]


} {{} {}}

catch {destroy .e}

spinbox .e -font $fixed -width 5 -bd 2 -relief sunken
pack .e

.e insert 0 012345678901234567890
.e xview 4
update
test spinbox-13.1 {GetSpinboxIndex procedure} {
    .e index end
} {21}


test spinbox-13.2 {GetSpinboxIndex procedure} {

    list [catch {.e index abogus} msg] $msg


} {1 {bad spinbox index "abogus"}}
test spinbox-13.3 {GetSpinboxIndex procedure} {






    .e select from 1
    .e select to 6
    .e index anchor
} {1}


test spinbox-13.4 {GetSpinboxIndex procedure} {






    .e select from 4
    .e select to 1
    .e index anchor
} {4}


test spinbox-13.5 {GetSpinboxIndex procedure} {






    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} {15}


test spinbox-13.6 {GetSpinboxIndex procedure} {


    list [catch {.e index ebogus} msg] $msg


} {1 {bad spinbox index "ebogus"}}
test spinbox-13.7 {GetSpinboxIndex procedure} {






    .e icursor 2
    .e index insert
} {2}


test spinbox-13.8 {GetSpinboxIndex procedure} {


    list [catch {.e index ibogus} msg] $msg


} {1 {bad spinbox index "ibogus"}}
test spinbox-13.9 {GetSpinboxIndex procedure} {






    .e select from 1




































    .e select to 6
    list [.e index sel.first] [.e index sel.last]
} {1 6}
selection clear .e
test spinbox-13.10 {GetSpinboxIndex procedure} unix {
    # On unix, when selection is cleared, spinbox widget's internal
    # selection range is reset.













    list [catch {.e index sel.first} msg] $msg





} {1 {selection isn't in widget .e}}

test spinbox-13.11 {GetSpinboxIndex procedure} win {






    # On mac and pc, when selection is cleared, spinbox widget remembers
    # last selected range.  When selection ownership is restored to

    # spinbox, the old range will be rehighlighted.

    list [catch {selection get}] [.e index sel.first]

} {1 1}
test spinbox-13.12 {GetSpinboxIndex procedure} unix {
    list [catch {.e index sbogus} msg] $msg
} {1 {selection isn't in widget .e}}
test spinbox-13.13 {GetSpinboxIndex procedure} win {











    list [catch {.e index sbogus} msg] $msg


} {1 {bad spinbox index "sbogus"}}

test spinbox-13.14 {GetSpinboxIndex procedure} win {
    list [catch {selection get}] [catch {.e index sbogus}]

} {1 1}
test spinbox-13.15 {GetSpinboxIndex procedure} {



    list [catch {.e index @xyz} msg] $msg




} {1 {bad spinbox index "@xyz"}}
test spinbox-13.16 {GetSpinboxIndex procedure} {fonts} {
    .e index @4





} {4}
test spinbox-13.17 {GetSpinboxIndex procedure} {fonts} {















    .e index @11



} {4}
test spinbox-13.18 {GetSpinboxIndex procedure} {fonts} {


    .e index @12



} {5}
test spinbox-13.19 {GetSpinboxIndex procedure} {fonts} {
    # 11 is the minimum button width
    .e index @[expr [winfo width .e] - 6 - 11]
} {8}
test spinbox-13.20 {GetSpinboxIndex procedure} {fonts} {





    .e index @[expr [winfo width .e] - 5]
} {9}


test spinbox-13.21 {GetSpinboxIndex procedure} {






    .e index @1000
} {9}


test spinbox-13.22 {GetSpinboxIndex procedure} {






    list [catch {.e index 1xyz} msg] $msg

} {1 {bad spinbox index "1xyz"}}

test spinbox-13.23 {GetSpinboxIndex procedure} {




























    .e index -10
} {0}


test spinbox-13.24 {GetSpinboxIndex procedure} {




    .e index 12
} {12}
























test spinbox-13.25 {GetSpinboxIndex procedure} {






    .e index 49
} {21}



# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.

set x {}
for {set i 1} {$i <= 500} {incr i} {
    append x "This is line $i, out of 500\n"
}
test spinbox-14.1 {SpinboxFetchSelection procedure} {
    catch {destroy .e}
    spinbox .e
    .e insert end "This is a test string"
    .e select from 1
    .e select to 18
    selection get


} {his is a test str}
test spinbox-14.3 {SpinboxFetchSelection procedure} {
    catch {destroy .e}




    spinbox .e
    .e insert end $x
    .e select from 0
    .e select to end
    string compare [selection get] $x
} 0



test spinbox-15.1 {SpinboxLostSelection} {
    catch {destroy .e}
    spinbox .e
    .e insert 0 "Text"
    .e select from 0
    .e select to 4
    set result [selection get]
    selection clear
    .e select from 0
    .e select to 4
    lappend result [selection get]


} {Text Text}

# No tests for EventuallyRedraw.


catch {destroy .e}
spinbox .e -width 10 -xscrollcommand scroll
pack .e
update

test spinbox-16.1 {SpinboxVisibleRange procedure} {fonts} {
    .e delete 0 end
    .e insert 0 .............................
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 0.827586}
test spinbox-16.2 {SpinboxVisibleRange procedure} {
    .e delete 0 end
    format {%.6f %.6f} {*}[.e xview]


} {0.000000 1.000000}

catch {destroy .e}

spinbox .e -width 10 -xscrollcommand scroll -font $fixed
pack .e
update

test spinbox-17.1 {SpinboxUpdateScrollbar procedure} {
    .e delete 0 end
    .e insert 0 123
    update
    format {%.6f %.6f} {*}$scrollInfo



} {0.000000 1.000000}
test spinbox-17.2 {SpinboxUpdateScrollbar procedure} {

    .e delete 0 end
    .e insert 0 0123456789abcdef


    .e xview 3

    update
    format {%.6f %.6f} {*}$scrollInfo



} {0.187500 0.812500}
test spinbox-17.3 {SpinboxUpdateScrollbar procedure} {


    .e delete 0 end

    .e insert 0 abcdefghijklmnopqrs
    .e xview 6

    update
    format {%.6f %.6f} {*}$scrollInfo
} {0.315789 0.842105}
test spinbox-17.4 {SpinboxUpdateScrollbar procedure} {
    destroy .e



    set x "Background error did not happen"
    proc bgerror msg {
	global x
	set x $msg
    }

    spinbox .e -width 5 -xscrollcommand thisisnotacommand
    pack .e
    update


    rename bgerror {}
    list $x $errorInfo



} {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
    (horizontal scrolling command executed by .e)}}

set l [interp hidden]
deleteWindows

test spinbox-18.1 {Spinbox widget vs hiding} {
    destroy .e
    spinbox .e


    interp hide {} .e
    destroy .e
    list [winfo children .] [interp hidden]
} [list {} $l]



##
## Spinbox widget VALIDATION tests
##





destroy .e

catch {unset ::e}
catch {unset ::vVals}
spinbox .e -validate all \
	-validatecommand [list doval %W %d %i %P %s %S %v %V] \
	-invalidcommand bell \
	-textvariable ::e \
	-background red -foreground white
pack .e
proc doval {W d i P s S v V} {
    set ::vVals [list $W $d $i $P $s $S $v $V]
    return 1
}

# The validation tests build each one upon the previous, so cascading
# failures aren't good
#
test spinbox-19.1 {spinbox widget validation} {
    .e insert 0 a
    set ::vVals


} {.e 1 0 a {} a all key}

test spinbox-19.2 {spinbox widget validation} {









    .e insert 1 b
    set ::vVals


} {.e 1 1 ab a b all key}

test spinbox-19.3 {spinbox widget validation} {









    .e insert end c
    set ::vVals


} {.e 1 2 abc ab c all key}

test spinbox-19.4 {spinbox widget validation} {









    .e insert 1 123
    list $::vVals $::e


} {{.e 1 1 a123bc abc 123 all key} a123bc}

test spinbox-19.5 {spinbox widget validation} {









    .e delete 2
    set ::vVals


} {.e 0 2 a13bc a123bc 2 all key}

test spinbox-19.6 {spinbox widget validation} {









    .e configure -validate key
    .e delete 1 3
    set ::vVals


} {.e 0 1 abc a13bc 13 key key}

test spinbox-19.7 {spinbox widget validation} {









    set ::vVals {}
    .e configure -validate focus
    .e insert end d
    set ::vVals



} {}
test spinbox-19.8 {spinbox widget validation} {










    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focus focusin}

test spinbox-19.9 {spinbox widget validation} {












    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focus focusout}




.e configure -validate all
test spinbox-19.10 {spinbox widget validation} {





    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} all focusin}

test spinbox-19.11 {spinbox widget validation} {












    focus -force .
    # update necessary to process FocusOut event


    update
    set ::vVals
} {.e -1 -1 abcd abcd {} all focusout}
.e configure -validate focusin
test spinbox-19.12 {spinbox widget validation} {









    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focusin focusin}

test spinbox-19.13 {spinbox widget validation} {









    set ::vVals {}
    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals
} {}


.e configure -validate focuso
test spinbox-19.14 {spinbox widget validation} {










    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals



} {}
test spinbox-19.15 {spinbox widget validation} {













    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals


} {.e -1 -1 abcd abcd {} focusout focusout}
test spinbox-19.16 {spinbox widget validation} {
    list [.e validate] $::vVals
} {1 {.e -1 -1 abcd abcd {} all forced}}
test spinbox-19.17 {spinbox widget validation} {
    set ::e newdata

    list [.e cget -validate] $::vVals


} {focusout {.e -1 -1 newdata abcd {} focusout forced}}

proc doval {W d i P s S v V} {


    set ::vVals [list $W $d $i $P $s $S $v $V]





    return 0




}
.e configure -validate all

test spinbox-19.18 {spinbox widget validation} {









    set ::e nextdata
    list [.e cget -validate] $::vVals



} {none {.e -1 -1 nextdata newdata {} all forced}}

proc doval {W d i P s S v V} {

    set ::vVals [list $W $d $i $P $s $S $v $V]









    set ::e mydata


    return 1

}
.e configure -validate all

## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the spinbox textvar is also set

test spinbox-19.19 {spinbox widget validation} {











    .e validate
    list [.e cget -validate] [.e get] $::vVals


} {none mydata {.e -1 -1 nextdata nextdata {} all forced}}

.e configure -validate all

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the spinbox widget shown as is in the textvar.
test spinbox-19.20 {spinbox widget validation} {













    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals


} {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}



















# A format specifier is allowed to be of the form %[-+ 0]{0,1}\d.?\d?f
#

destroy .e

spinbox .e
test spinbox-20.1 {spinbox config, -format specifier} {

    list [catch {.e config -format %2f} msg] $msg
} {0 {}}


test spinbox-20.2 {spinbox config, -format specifier} {

    list [catch {.e config -format %2.2f} msg] $msg
} {0 {}}


test spinbox-20.3 {spinbox config, -format specifier} {

    list [catch {.e config -format %.2f} msg] $msg
} {0 {}}


test spinbox-20.4 {spinbox config, -format specifier} {

    list [catch {.e config -format %2.f} msg] $msg
} {0 {}}


test spinbox-20.5 {spinbox config, -format specifier} {

    list [catch {.e config -format %2e-1f} msg] $msg


} {1 {bad spinbox format specifier "%2e-1f"}}
test spinbox-20.6 {spinbox config, -format specifier} {

    list [catch {.e config -format 2.2} msg] $msg


} {1 {bad spinbox format specifier "2.2"}}
test spinbox-20.7 {spinbox config, -format specifier} {

    list [catch {.e config -format %2.-2f} msg] $msg


} {1 {bad spinbox format specifier "%2.-2f"}}
test spinbox-20.8 {spinbox config, -format specifier} {

    list [catch {.e config -format %-2.02f} msg] $msg
} {0 {}}


test spinbox-20.9 {spinbox config, -format specifier} {

    list [catch {.e config -format "% 2.02f"} msg] $msg
} {0 {}}


test spinbox-20.10 {spinbox config, -format specifier} {

    list [catch {.e config -format "% -2.200f"} msg] $msg
} {0 {}}


test spinbox-20.11 {spinbox config, -format specifier} {

    list [catch {.e config -format "%09.200f"} msg] $msg
} {0 {}}


test spinbox-20.12 {spinbox config, -format specifier does something} {

    set out {}

    .e config -format "%02.f"
    .e config -values {} -from 0 -to 10 -increment 1
    lappend out [.e set 0]; # set currently doesn't force format
    .e invoke buttonup
    lappend out [.e set]; # but after invoke it should be formatted
    lappend out [.e set 3]; # set currently doesn't force format
    .e config -format "%03.f"
    lappend out [.e set]; # changing -format should cause formatting


} {0 01 3 003}


test spinbox-21.1 {spinbox button, out of range checking} {
    destroy .e
    spinbox .e -from -10 -to 20 -increment 2
    set out {}
    lappend out [.e get]; # -10
    .e delete 0 end
    .e insert 0 25; # set outside of range
    .e invoke buttondown; # should constrain
    lappend out [.e get]; # 20
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838

3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861

3862
3863
3864
3865
3866
3867
3868
3869
3870
3871

3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902

3903




3904
3905
3906
3907
3908
3909
3910

3911
3912
3913
3914
3915
    .e insert 0 -9; # set just inside of range
    .e invoke buttondown; # wrap
    lappend out [.e get]; # 20
    .e invoke buttondown
    lappend out [.e get]; # 18
    .e invoke buttonup; # no wrap
    lappend out [.e get]; # 20
} -cleanup {
    destroy .e
} -result {-10 20 20 -10 -10 -10 20 20 18 -10 -10 -8 -10 -8 -10 20 18 20}

test spinbox-22.1 {spinbox config, -from changes SF bug 559078} -body {
    set val 5

    spinbox .e -from 1 -to 10 -textvariable val
    set val
} -cleanup {
    destroy .e
} -result 5
test spinbox-22.2 {spinbox config, -from changes SF bug 559078} -body {
    set val 5
    spinbox .e -from 1 -to 10 -textvariable val
    .e configure -from 3 -to 10
    set val
} -cleanup {
    destroy .e
} -result 5
test spinbox-22.3 {spinbox config, -from changes SF bug 559078} -body {
    set val 5
    spinbox .e -from 3 -to 10 -textvariable val
    .e configure -from 6 -to 10
    set val
} -cleanup {
    destroy .e
} -result 6

test spinbox-23.1 {selection present while disabled, bug 637828} -body {

    spinbox .e
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    set out [.e selection present]
    .e configure -state disabled
# still return 1 when disabled, because 'selection get' will work,
# but selection cannot be changed (new behavior since 8.4)
    .e select to 9
    lappend out [.e selection present] [selection get]

} -cleanup {
    destroy .e
} -result {1 1 345}

test spinbox-24.1 {error in trace proc attached to the textvariable} -setup {
    destroy .s
} -body {
    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    spinbox .s -textvariable myvar -from 1 -to 10
    catch {.s set mystring} result1
    catch {.s insert 0 mystring} result2
    catch {.s delete 0} result3
    catch {.s invoke buttonup} result4
    list $result1 $result2 $result3 $result4
} -cleanup {
    destroy .s
} -result [list {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!}]

test spinbox-25.1 {textvariable lives in a non-existing namespace} -setup {
    destroy .s
} -body {
    catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1
    set result1
} -cleanup {
    destroy .s
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}


# Collected comments about lacks from the test




# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.
# No tests for DisplaySpinbox.
# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.
# No tests for EventuallyRedraw

# option clear

# cleanup
cleanupTests
return









|
<
|

|

>
|

|
<
<
|
<
<
|

|
<
<
|
<
<
|

|
<
<

|
>






|
|


>
|
|
<

|

<








<
<
|




|

<


<
<
|

>
|
>
>
>
>


<
<
<

|
>



<
<
1546
1547
1548
1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561


1562


1563
1564
1565


1566


1567
1568
1569


1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585

1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1596


1597
1598
1599
1600
1601
1602
1603

1604
1605


1606
1607
1608
1609
1610
1611
1612
1613
1614
1615



1616
1617
1618
1619
1620
1621


    .e insert 0 -9; # set just inside of range
    .e invoke buttondown; # wrap
    lappend out [.e get]; # 20
    .e invoke buttondown
    lappend out [.e get]; # 18
    .e invoke buttonup; # no wrap
    lappend out [.e get]; # 20


} {-10 20 20 -10 -10 -10 20 20 18 -10 -10 -8 -10 -8 -10 20 18 20}

test spinbox-22.1 {spinbox config, -from changes SF bug 559078} {
    set val 5
    destroy .s
    spinbox .s -from 1 -to 10 -textvariable val
    set val
} {5}


test spinbox-22.2 {spinbox config, -from changes SF bug 559078} {


    .s configure -from 3 -to 10
    set val
} {5}


test spinbox-22.3 {spinbox config, -from changes SF bug 559078} {


    .s configure -from 6 -to 10
    set val
} {6}



test spinbox-23.1 {selection present while disabled, bug 637828} {
    destroy .e
    spinbox .e
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    set out [.e selection present]
    .e configure -state disabled
    # still return 1 when disabled, because 'selection get' will work,
    # but selection cannot be changed (new behavior since 8.4)
    .e select to 9
    lappend out [.e selection present] [selection get]
} {1 1 345}

destroy .e


test spinbox-24.1 {error in trace proc attached to the textvariable} {
    destroy .s

    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    spinbox .s -textvariable myvar -from 1 -to 10
    catch {.s set mystring} result1
    catch {.s insert 0 mystring} result2
    catch {.s delete 0} result3
    catch {.s invoke buttonup} result4
    list $result1 $result2 $result3 $result4


} [list {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!} \
    {can't set "myvar": Intentional error here!}]

test spinbox-25.1 {textvariable lives in a non-existing namespace} {
    destroy .s

    catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1
    set result1


} {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}

catch {unset ::e ::vVals}

##
## End validation tests
##

# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.




option clear

# cleanup
cleanupTests
return


Deleted tests/teapotTransparent.png.

cannot compute difference between binary files

Changes to tests/text.test.

more than 10,000 changes

Changes to tests/textBTree.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15





































































































































































































16
17
18
19
20
21
22
23
24
25






























26





















































































































































































































































27
28
29
30
31
32
33
34
35
36
37
38














39






























40



































































































































41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226

1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
# This file is a Tcl script to test out the B-tree facilities of
# Tk's text widget (the contents of the file "tkTextBTree.c".  There are
# several file with additional tests for other features of text widgets.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






































































































































































































proc setup {} {
    .t delete 1.0 100000.0
    .t tag delete x y
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1
    .t tag add x 1.5 1.13
    .t tag add x 2.2 2.6
    .t tag add y 1.5
}































# setup procedure for tests 10.*, 11.*, 12.*





















































































































































































































































proc msetup {} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t mark set m1 1.2
    .t mark set l1 1.2
    .t mark gravity l1 left
    .t mark set next 1.6
    .t mark set x 1.6
    .t mark set m2 2.0
    .t mark set m3 2.100
    .t tag add x 1.3 1.8
}













































# setup procedure for tests 16.*, 17.*, 18.9



































































































































proc setupBig {} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -foreground blue
    .t tag configure y -underline true
    # Create a Btree with 2002 lines (2000 + already existing + phantom at end)
    # This generates a level 3 node with 9 children
    # Most level 2 nodes cover 216 lines and have 6 children, except the last
    # level 2 node covers 274 lines and has 7 children.
    # Most level 1 nodes cover 36 lines and have 6 children, except the
    # rightmost node has 58 lines and 9 children.
    # Level 2: 2002 = 8*216 + 274
    # Level 1: 2002 = 54*36 + 58
    # Level 0: 2002 = 332*6 + 10
    for {set i 0} {$i < 2000} {incr i} {
        append x "Line $i abcd efgh ijkl\n"
    }
    .t insert insert $x
    .t debug 1
}

# Widget used in tests 1.* - 13.*
destroy .t
text .t
.t debug on

test btree-1.1 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-1.2 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 1.3 XXX
    .t get 1.0 1000000.0
} -result "LinXXXe 1\nLine 2\nLine 3\n"
test btree-1.3 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 3.0 YYY
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nYYYLine 3\n"
test btree-1.4 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.1 X\nYY
    .t get 1.0 1000000.0
} -result "Line 1\nLX\nYYine 2\nLine 3\n"
test btree-1.5 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.0 X\n\n\n
    .t get 1.0 1000000.0
} -result "Line 1\nX\n\n\nLine 2\nLine 3\n"
test btree-1.6 {basic insertions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.6 X\n
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2X\n\nLine 3\n"
test btree-1.7 {insertion before start of text} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 0.4 XXX
    .t get 1.0 1000000.0
} -result "XXXLine 1\nLine 2\nLine 3\n"
test btree-1.8 {insertion past end of text} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 100.0 ZZ
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3ZZ\n"
test btree-1.9 {insertion before start of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.-3 Q
    .t get 1.0 1000000.0
} -result "Line 1\nQLine 2\nLine 3\n"
test btree-1.10 {insertion past end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.40 XYZZY
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2XYZZY\nLine 3\n"
test btree-1.11 {insertion past end of last line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 3.40 ABC
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3ABC\n"


test btree-2.1 {basic deletions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.0 1.3
    .t get 1.0 1000000.0
} -result "e 1\nLine 2\nLine 3\n"
test btree-2.2 {basic deletions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 2.2
    .t get 1.0 1000000.0
} -result "Line 1\nLie 2\nLine 3\n"
test btree-2.3 {basic deletions} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 2.0 2.3
    .t get 1.0 1000000.0
} -result "Line 1\ne 2\nLine 3\n"
test btree-2.4 {deleting whole lines} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.2 3.0
    .t get 1.0 1000000.0
} -result "LiLine 3\n"
test btree-2.5 {deleting whole lines} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\n\n\nLine 5"
    .t delete 1.0 5.2
    .t get 1.0 1000000.0
} -result "ne 5\n"
test btree-2.6 {deleting before start of file} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 0.3 1.2
    .t get 1.0 1000000.0
} -result "ne 1\nLine 2\nLine 3\n"
test btree-2.7 {deleting after end of file} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 10.3
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.8 {deleting before start of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.-1 3.3
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\ne 3\n"
test btree-2.9 {deleting before start of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.-1 1.0
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.10 {deleting after end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 2.1
    .t get 1.0 1000000.0
} -result "Line 1ine 2\nLine 3\n"
test btree-2.11 {deleting after end of last line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.8 4.1
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.12 {deleting before start of file} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 0.0
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.13 {deleting past end of file} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 4.0
    .t get 1.0 1000000.0
} -result "Line 1\n"
test btree-2.14 {deleting with end before start of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.3 2.-3
    .t get 1.0 1000000.0
} -result "LinLine 2\nLine 3\n"
test btree-2.15 {deleting past end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.3 1.9
    .t get 1.0 1000000.0
} -result "Lin\nLine 2\nLine 3\n"
test btree-2.16 {deleting past end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.15
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLi\n"
test btree-2.17 {deleting past end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.0 3.15
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\n\n"
test btree-2.18 {deleting past end of line} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.0 3.15
    .t get 1.0 1000000.0
} -result "\n"
test btree-2.19 {deleting with negative range} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 2.4
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.20 {deleting with negative range} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.1
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.21 {deleting with negative range} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.2
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"


test btree-3.1 {inserting with tags} -body {
    setup
    .t insert 1.0 XXX
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.4 1.5 1.8 1.16 2.2 2.6} {1.8 1.9}}
test btree-3.2 {inserting with tags} -body {
    setup
    .t insert 1.15 YYY
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.13 2.2 2.6} {1.5 1.6}}
test btree-3.3 {inserting with tags} -body {
    setup
    .t insert 1.7 ZZZZ
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.17 2.2 2.6} {1.5 1.6}}
test btree-3.4 {inserting with tags} -body {
    setup
    .t insert 1.7 \n\n
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 3.6 4.2 4.6} {1.5 1.6}}
test btree-3.5 {inserting with tags} -body {
    setup
    .t insert 1.5 A\n
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 2.0 2.8 3.2 3.6} {2.0 2.1}}
test btree-3.6 {inserting with tags} -body {
    setup
    .t insert 1.13 A\n
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.13 3.2 3.6} {1.5 1.6}}


test btree-4.1 {deleting with tags} -body {
    setup
    .t delete 1.6 1.9
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.10 2.2 2.6} {1.5 1.6}}
test btree-4.2 {deleting with tags} -body {
    setup
    .t delete 1.1 2.3
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.4} {}}
test btree-4.3 {deleting with tags} -body {
    setup
    .t delete 1.4 2.1
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.9} {}}
test btree-4.4 {deleting with tags} -body {
    setup
    .t delete 1.14 2.1
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.13 1.15 1.19} {1.5 1.6}}
test btree-4.5 {deleting with tags} -body {
    setup
    .t delete 1.0 2.10
    list [.t tag ranges x] [.t tag ranges y]
} -result {{} {}}
test btree-4.6 {deleting with tags} -body {
    setup
    .t delete 1.0 1.5
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.0 1.8 2.2 2.6} {1.0 1.1}}
test btree-4.7 {deleting with tags} -body {
    setup
    .t delete 1.6 1.9
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 1.5 1.10 2.2 2.6} {1.5 1.6}}
test btree-4.8 {deleting with tags} -body {
    setup
    .t delete 1.5 1.13
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 2.2 2.6} {}}


test btree-5.1 {very large inserts, with tags} -setup {
    set bigText1 {}
    for {set i 0} {$i < 10} {incr i} {
        append bigText1 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.0 $bigText1
    list [.t tag ranges x] [.t tag ranges y]
} -result {{11.1 11.2 11.5 11.13 12.2 12.6} {11.5 11.6}}
test btree-5.2 {very large inserts, with tags} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.1 1.2 201.3 201.11 202.2 202.6} {201.3 201.4}}
test btree-5.3 {very large inserts, with tags} -body {
    setup
    for {set i 0} {$i < 200} {incr i} {
        .t insert 1.8 "longer line $i\n"
    }
    list [.t tag ranges x] [.t tag ranges y] [.t get 1.0 1.100] \
        [.t get 198.0 198.100]
} -result {{1.1 1.2 1.5 201.5 202.2 202.6} {1.5 1.6} {Text forlonger line 199} {longer line 2}}


test btree-6.1 {very large deletes, with tags}  -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    .t delete 1.2 201.2
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.4 1.12 2.2 2.6} {1.4 1.5}}
test btree-6.2 {very large deletes, with tags}  -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 200} {incr i} {
        .t delete 1.2 2.2
    }
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.4 1.12 2.2 2.6} {1.4 1.5}}
test btree-6.3 {very large deletes, with tags}  -setup {
    set bigText2 {}
     for {set i 0} {$i < 200} {incr i} {
            append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    .t delete 2.3 10000.0
    .t get 1.0 1000.0
} -result {TLine 0
Lin
}
test btree-6.4 {very large deletes, with tags} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
        .t delete 30.0 31.0
    }
    list [.t tag ranges x] [.t tag ranges y]
} -result {{101.0 101.1 101.4 101.12 102.2 102.6} {101.4 101.5}}
test btree-6.5 {very large deletes, with tags} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
        set j [expr {$i+2}]
        set k [expr {1+2*$i}]
        .t tag add x $j.1 $j.3
        .t tag add y $k.1 $k.6
    }
    .t delete 2.0 200.0
    list [.t tag ranges x] [.t tag ranges y]
} -result {{3.0 3.1 3.4 3.12 4.2 4.6} {1.1 1.6 3.4 3.5}}
test btree-6.6 {very large deletes, with tags} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
        set j [expr {$i+2}]
        set k [expr {1+2*$i}]
        .t tag add x $j.1 $j.3
        .t tag add y $k.1 $k.6
    }
    for {set i 199} {$i >= 2} {incr i -1} {
        .t delete $i.0 [expr {$i+1}].0
    }
    list [.t tag ranges x] [.t tag ranges y]
} -result {{3.0 3.1 3.4 3.12 4.2 4.6} {1.1 1.6 3.4 3.5}}


test btree-7.1 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.3 1.6 1.7 2.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.3 1.6 1.7 2.0}
test btree-7.2 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.3 1.6 1.6 2.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.3 2.0}
test btree-7.3 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.3 1.6 1.4 2.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.3 2.0}
test btree-7.4 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {2.0 4.3 1.4 1.10}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.4 1.10 2.0 4.3}
test btree-7.5 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {2.0 4.3 1.4 1.end}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.4 1.19 2.0 4.3}
test btree-7.6 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {2.0 4.3 1.4 2.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.4 4.3}
test btree-7.7 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {2.0 4.3 1.4 3.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.4 4.3}
test btree-7.8 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.1 4.2}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.1 4.2}
test btree-7.9 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.3 4.2}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.2 4.2}
test btree-7.10 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.1 3.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.1 4.0}
test btree-7.11 {tag addition and removal} -setup {
    .t delete 1.0 end
    .t tag remove x 1.0 end
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    set check {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.2 3.0}
    while {[llength $check]} {
        .t tag add x [lindex $check 0] [lindex $check 1]
        set check [lrange $check 2 end]
    }
    .t tag ranges x
} -result {1.2 4.0}


test btree-8.1 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 0.0 1.3
    .t tag ranges x
} -result {1.0 1.3}
test btree-8.2 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.40 2.4
    .t tag ranges x
} -result {1.19 2.4}
test btree-8.3 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 4.40 4.41
    .t tag ranges x
} -result {}
test btree-8.4 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 5.1 5.2
    .t tag ranges x
} -result {}
test btree-8.5 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 9.0
    .t tag ranges x
} -result {1.1 5.0}
test btree-8.6 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 1.90
    .t tag ranges x
} -result {1.1 1.19}
test btree-8.7 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 4.90
    .t tag ranges x
} -result {1.1 4.17}
test btree-8.8 {tag addition and removal, weird ranges} -body {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 3.0 3.0
    .t tag ranges x
} -result {}


test btree-9.1 {tag names} -body {
    setup
    .t tag names
} -result {sel x y}
test btree-9.2 {tag names} -body {
    setup
    .t tag add tag1 1.8
    .t tag add tag2 1.8
    .t tag add tag3 1.7 1.9
    .t tag names 1.8
} -result {x tag1 tag2 tag3}
test btree-9.3 {lots of tag names} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    foreach i {tag1 foo ThisOne {x space} q r s t} {
    .t tag add $i 150.2
    }
    foreach i {u tagA tagB tagC and more {$} \{} {
    .t tag add $i 150.1 150.3
    }
    .t tag names 150.2
} -result {tag1 foo ThisOne {x space} q r s t u tagA tagB tagC and more {$} \{}
test btree-9.4 {lots of tag names} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    .t tag delete tag1 foo ThisOne more {x space} q r s t u
    .t tag delete tagA tagB tagC and {$} \{ more
    foreach i {tag1 foo ThisOne more {x space} q r s t} {
    .t tag add $i 150.2
    }
    foreach i {foo ThisOne u tagA tagB tagC and more {$} \{} {
    .t tag add $i 150.4
    }
    .t tag delete tag1 more q r tagA
    .t tag names 150.2
} -result {foo ThisOne {x space} s t}


test btree-10.1 {basic mark facilities} -body {
    msetup
    list [lsort [.t mark names]] [.t index m1] [.t index m2] [.t index m3]
} -result {{current insert l1 m1 m2 m3 next x} 1.2 2.0 2.11}
test btree-10.2 {basic mark facilities} -body {
    msetup
    .t mark unset m2
    lsort [.t mark names]
} -result {current insert l1 m1 m3 next x}
test btree-10.3 {basic mark facilities} -body {
    msetup
    .t mark set m2 1.8
    list [lsort [.t mark names]] [.t index m1] [.t index m2] [.t index m3]
} -result {{current insert l1 m1 m2 m3 next x} 1.2 1.8 2.11}


test btree-11.1 {marks and inserts} -body {
    msetup
    .t insert 1.1 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.7 1.7 1.11 1.11 2.0 2.11}
test btree-11.2 {marks and inserts} -body {
    msetup
    .t insert 1.2 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.7 1.11 1.11 2.0 2.11}
test btree-11.3 {marks and inserts} -body {
    msetup
    .t insert 1.3 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.11 1.11 2.0 2.11}
test btree-11.4 {marks and inserts} -body {
    msetup
    .t insert 1.1 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {3.4 3.4 3.8 3.8 4.0 4.11}
test btree-11.5 {marks and inserts} -body {
    msetup
    .t insert 1.4 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 3.5 3.5 4.0 4.11}
test btree-11.6 {marks and inserts} -body {
    msetup
    .t insert 1.7 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.6 1.6 4.0 4.11}


test btree-12.1 {marks and deletes} -body {
    msetup
    .t delete 1.3 1.5
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.4 1.4 2.0 2.11}
test btree-12.2 {marks and deletes} -body {
    msetup
    .t delete 1.3 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.3 1.3 2.0 2.11}
test btree-12.3 {marks and deletes} -body {
    msetup
    .t delete 1.2 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.2 1.2 2.0 2.11}
test btree-12.4 {marks and deletes} -body {
    msetup
    .t delete 1.1 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.1 1.1 1.1 1.1 2.0 2.11}
test btree-12.5 {marks and deletes} -body {
    msetup
    .t delete 1.5 3.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.5 1.5 1.5 1.5}
test btree-12.6 {marks and deletes} -body {
    msetup
    .t mark set m2 4.5
    .t delete 1.5 4.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.2 1.5 1.5 1.9 1.5}
test btree-12.7 {marks and deletes} -body {
    msetup
    .t mark set m2 4.5
    .t mark set m3 4.5
    .t mark set m1 4.7
    .t delete 1.5 4.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} -result {1.2 1.11 1.5 1.5 1.9 1.9}


test btree-13.1 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag next x 2.2 2.1
} -result {}
test btree-13.2 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.2 2.3
} -result {2.2 2.4}
test btree-13.3 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.3 2.6
} -result {}
test btree-13.4 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.6
} -result {2.5 2.8}
test btree-13.5 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.5
} -result {}
test btree-13.6 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.1 2.4
    .t tag next x 2.5 2.8
} -result {}
test btree-13.7 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.4
} -result {}
test btree-13.8 {tag searching} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 190.3 191.2
    .t tag next x 3.5
} -result {190.3 191.2}
destroy .t


test btree-14.1 {check tag presence} -setup {
    destroy .t
    text .t
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 3.5 3.7
    .t tag add y 133.9 141.5
    .t tag add z 1.5 180.2
    .t tag add q 141.4 142.3
    .t tag add x 130.2 145.1
    .t tag add a 141.0
    .t tag add b 4.3
    .t tag add b 7.5
    .t tag add b 140.3
    for {set i 120} {$i < 160} {incr i} {
    .t tag add c $i.4
    }
    foreach i {a1 a2 a3 a4 a5 a6 a7 a8 a9 10 a11 a12 a13} {
    .t tag add $i 122.2
    }
    .t tag add x 141.3
    .t tag names 141.1
} -cleanup {
    destroy .t
} -result {x y z}
test btree-14.2 {TkTextIsElided} -setup {
    destroy .t
    text .t
} -body {
    .t delete 1.0 end
    .t tag config hidden -elide 1
    .t insert end "Line1\nLine2\nLine3\n"
    .t tag add hidden 2.0 3.0
    .t tag add sel 1.2 3.2
    # next line used to panic because of "Bad tag priority being toggled on"
    # (see bug [382da038c9])
    .t index "2.0 - 1 display line linestart"
} -cleanup {
    destroy .t
} -result {1.0}

test btree-15.1 {rebalance with empty node} -setup {
    destroy .t
} -body {
    text .t
    .t debug 1
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23"
    .t delete 6.0 12.0
    .t get 1.0 end
} -cleanup {
    destroy .t
} -result "1\n2\n3\n4\n5\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n"


test btree-16.1 {add tag does not push root above level 0} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t debug 0
    .t tag add x 1.1 1.10
    .t tag add x 5.1 5.10
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 1.10 5.1 5.10}
test btree-16.2 {add tag pushes root up to level 1 node} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 1.10
    .t tag add x 8.1 8.10
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 1.10 8.1 8.10}
test btree-16.3 {add tag pushes root up to level 2 node} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 8.1 9.10
    .t tag add x 180.1 180.end
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {8.1 9.10 180.1 180.23}
test btree-16.4 {add tag pushes root up to level 3 node} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add y 1.1 2000.0
    .t tag add x 1.1 8.10
    .t tag add x 180.end 217.0
    list [.t tag ranges x] [.t tag ranges y]
} -cleanup {
    destroy .t
} -result {{1.1 8.10 180.23 217.0} {1.1 2000.0}}
test btree-16.5 {add tag doesn't push root up} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 8.10
    .t tag add x 2000.0 2000.3
    .t tag add x 180.end 217.0
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 8.10 180.23 217.0 2000.0 2000.3}
test btree-16.6 {two node splits at once pushes root up} -setup {
    destroy .t
    text .t
} -body {
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
    .t tag add x 8.0 8.end
    .t tag add y 9.0 end
    set x {}
    for {} {$i < 50} {incr i} {
        append x "Line $i\n"
    }
    .t insert end $x y
    list [.t tag ranges x] [.t tag ranges y]
} -cleanup {
    destroy .t
} -result {{8.0 8.6} {9.0 51.0}}
# The following find bugs in the SearchStart procedures
test btree-16.7 {Partial tag remove from before first range} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.0
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {2.0 2.6}
test btree-16.8 {Partial tag remove from before first range} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.1
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {2.1 2.6}
test btree-16.9 {Partial tag remove from before first range} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.3
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {2.3 2.6}
test btree-16.10 {Partial tag remove from before first range} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.0 2.6
    .t tag remove x 1.0 2.5
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {2.5 2.6}
test btree-16.11 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.4
} -cleanup {
    destroy .t
} -result {}
test btree-16.12 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.3
} -cleanup {
    destroy .t
} -result {1.3 1.4}
test btree-16.13 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.0 1.4
    .t tag prevr x 1.3
} -cleanup {
    destroy .t
} -result {1.0 1.4}


test btree-17.1 {remove tag does not push root down} -setup {
    destroy .t
    text .t
} -body {
    .t debug 0
    setupBig
    .t tag add x 1.1 5.10
    .t tag remove x 3.1 5.end
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 3.1}
test btree-17.2 {remove tag pushes root from level 1 to level 0} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 8.10
    .t tag remove x 3.1 end
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 3.1}
test btree-17.3 {remove tag pushes root from level 2 to level 1} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 180.10
    .t tag remove x 35.1 end
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 35.1}
test btree-17.4 {remove tag doesn't change level 2} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 180.10
    .t tag remove x 35.1 180.0
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1.1 35.1 180.0 180.10}
test btree-17.5 {remove tag pushes root from level 3 to level 0} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 1.10
    .t tag add x 2000.1 2000.10
    .t tag remove x 1.0 2000.0
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {2000.1 2000.10}
test btree-17.6 {text deletion pushes root from level 3 to level 0} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.1 1.10
    .t tag add x 2000.1 2000.10
    .t delete 1.0 "1000.0 lineend +1 char"
    .t tag ranges x
} -cleanup {
    destroy .t
} -result {1000.1 1000.10}


test btree-18.1 {tag search back, no tag} -setup {
    destroy .t
    text .t
} -body {

    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag prev x 1.1 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.2 {tag search back, start at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.3 {tag search back, end at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.3 1.1
} -cleanup {
    destroy .t
} -result {1.1 1.4}
test btree-18.4 {tag search back, start within range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.10 1.0
} -cleanup {
    destroy .t
} -result {1.8 1.11}
test btree-18.5 {tag search back, start at end of range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    list [.t tag prev x 1.4 1.0] [.t tag prev x 1.11 1.0]
} -cleanup {
    destroy .t
} -result {{1.1 1.4} {1.8 1.11}}
test btree-18.6 {tag search back, start beyond range, same level 0 node} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 3.0
} -cleanup {
    destroy .t
} -result {1.16 1.17}
test btree-18.7 {tag search back, outside any range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.16
    .t tag prev x 1.8 1.5
} -cleanup {
    destroy .t
} -result {}
test btree-18.8 {tag search back, start at start of node boundary} -setup {
    destroy .t
    text .t
} -body {
    setupBig

    .t tag add x 2.5 2.8
    .t tag prev x 19.0
} -cleanup {
    destroy .t
} -result {2.5 2.8}
test btree-18.9 {tag search back, large complex btree spans} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.3 1.end
    .t tag add x 200.0 220.0
    .t tag add x 500.0 520.0
    list [.t tag prev x end] [.t tag prev x 433.0]

} -cleanup {
    destroy .t
} -result {{500.0 520.0} {200.0 220.0}}

# cleanup
cleanupTests
return





|
|
|



<



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















|





|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<



<
<
|
|
|

|




<
<
|
|
<
|
<
<



<
<
|
|
<
|
<
<




<
<
|
|
<
|
<
<




<
<
|
|
<
|
<

|





|



<
<
|

|
<
|
<
<
<
<



<
<
|
|
<
|
<
<
<
<



<
<
|
|
<
|
<
<
<
<



<
<
|
|
<
|
<
<
<
<



<
<
|
|
<
|
<
<
<
<


|
<
<
|
<
|
<
<
<
<


<
<
|
|
<
|
<
<
<
<


<
<
|


|
|

<





<
<
|
|
<
|
<
<



<
<
|
|
<
|
<
<



<
<
|
|
<
|
<
<



<
<
|
|
<
|
<
<




<
<
|
|
<
|
<
<




<
<
|

<
<
|
|
<
>


|
<
<
|
<
|
<
<




|
<
<
|
<
|
<
<




<
<
|
|
<
|
<
<




<
<
|
|
<
|
<
<




<
<
|
|
<
|
<
<




<
<
|
|
<
|
<
<



|
<
<
|
<
<
<

>


<
<
|
|
<
|
<
<




>
|
|
<




1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709




































































































































































































































710







































































































































































































































































































































































































































































































































































































































711

712
713
714


715
716
717
718
719
720
721
722
723


724
725

726


727
728
729


730
731

732


733
734
735
736


737
738

739


740
741
742
743


744
745

746

747
748
749
750
751
752
753
754
755
756
757


758
759
760

761




762
763
764


765
766

767




768
769
770


771
772

773




774
775
776


777
778

779




780
781
782


783
784

785




786
787
788


789

790




791
792


793
794

795




796
797


798
799
800
801
802
803

804
805
806
807
808


809
810

811


812
813
814


815
816

817


818
819
820


821
822

823


824
825
826


827
828

829


830
831
832
833


834
835

836


837
838
839
840


841
842


843
844

845
846
847
848


849

850


851
852
853
854
855


856

857


858
859
860
861


862
863

864


865
866
867
868


869
870

871


872
873
874
875


876
877

878


879
880
881
882


883
884

885


886
887
888
889


890



891
892
893
894


895
896

897


898
899
900
901
902
903
904

905
906
907
908
# This file is a Tcl script to test out the B-tree facilities of
# Tk's text widget (the contents of the file "tkTextBTree.c".  There are
# several file with additional tests for other features of text widgets.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

catch {destroy .t}
text .t
.t debug on

test btree-1.1 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-1.2 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 1.3 XXX
    .t get 1.0 1000000.0
} "LinXXXe 1\nLine 2\nLine 3\n"
test btree-1.3 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 3.0 YYY
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nYYYLine 3\n"
test btree-1.4 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.1 X\nYY
    .t get 1.0 1000000.0
} "Line 1\nLX\nYYine 2\nLine 3\n"
test btree-1.5 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.0 X\n\n\n
    .t get 1.0 1000000.0
} "Line 1\nX\n\n\nLine 2\nLine 3\n"
test btree-1.6 {basic insertions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.6 X\n
    .t get 1.0 1000000.0
} "Line 1\nLine 2X\n\nLine 3\n"
test btree-1.7 {insertion before start of text} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 0.4 XXX
    .t get 1.0 1000000.0
} "XXXLine 1\nLine 2\nLine 3\n"
test btree-1.8 {insertion past end of text} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 100.0 ZZ
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3ZZ\n"
test btree-1.9 {insertion before start of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.-3 Q
    .t get 1.0 1000000.0
} "Line 1\nQLine 2\nLine 3\n"
test btree-1.10 {insertion past end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 2.40 XYZZY
    .t get 1.0 1000000.0
} "Line 1\nLine 2XYZZY\nLine 3\n"
test btree-1.11 {insertion past end of last line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t insert 3.40 ABC
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3ABC\n"

test btree-2.1 {basic deletions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.0 1.3
    .t get 1.0 1000000.0
} "e 1\nLine 2\nLine 3\n"
test btree-2.2 {basic deletions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 2.2
    .t get 1.0 1000000.0
} "Line 1\nLie 2\nLine 3\n"
test btree-2.3 {basic deletions} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 2.0 2.3
    .t get 1.0 1000000.0
} "Line 1\ne 2\nLine 3\n"
test btree-2.4 {deleting whole lines} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.2 3.0
    .t get 1.0 1000000.0
} "LiLine 3\n"
test btree-2.5 {deleting whole lines} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\n\n\nLine 5"
    .t delete 1.0 5.2
    .t get 1.0 1000000.0
} "ne 5\n"
test btree-2.6 {deleting before start of file} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 0.3 1.2
    .t get 1.0 1000000.0
} "ne 1\nLine 2\nLine 3\n"
test btree-2.7 {deleting after end of file} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 10.3
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.8 {deleting before start of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.-1 3.3
    .t get 1.0 1000000.0
} "Line 1\nLine 2\ne 3\n"
test btree-2.9 {deleting before start of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.-1 1.0
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.10 {deleting after end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 2.1
    .t get 1.0 1000000.0
} "Line 1ine 2\nLine 3\n"
test btree-2.11 {deleting after end of last line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.8 4.1
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.12 {deleting before start of file} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 0.0
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.13 {deleting past end of file} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.8 4.0
    .t get 1.0 1000000.0
} "Line 1\n"
test btree-2.14 {deleting with end before start of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.3 2.-3
    .t get 1.0 1000000.0
} "LinLine 2\nLine 3\n"
test btree-2.15 {deleting past end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.3 1.9
    .t get 1.0 1000000.0
} "Lin\nLine 2\nLine 3\n"
test btree-2.16 {deleting past end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.15
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLi\n"
test btree-2.17 {deleting past end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.0 3.15
    .t get 1.0 1000000.0
} "Line 1\nLine 2\n\n"
test btree-2.18 {deleting past end of line} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 1.0 3.15
    .t get 1.0 1000000.0
} "\n"
test btree-2.19 {deleting with negative range} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 2.4
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.20 {deleting with negative range} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.1
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"
test btree-2.21 {deleting with negative range} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.2
    .t get 1.0 1000000.0
} "Line 1\nLine 2\nLine 3\n"

proc setup {} {
    .t delete 1.0 100000.0
    .t tag delete x y
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1
    .t tag add x 1.5 1.13
    .t tag add x 2.2 2.6
    .t tag add y 1.5
}

test btree-3.1 {inserting with tags} {
    setup
    .t insert 1.0 XXX
    list [.t tag ranges x] [.t tag ranges y]
} {{1.4 1.5 1.8 1.16 2.2 2.6} {1.8 1.9}}
test btree-3.2 {inserting with tags} {
    setup
    .t insert 1.15 YYY
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.13 2.2 2.6} {1.5 1.6}}
test btree-3.3 {inserting with tags} {
    setup
    .t insert 1.7 ZZZZ
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.17 2.2 2.6} {1.5 1.6}}
test btree-3.4 {inserting with tags} {
    setup
    .t insert 1.7 \n\n
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 3.6 4.2 4.6} {1.5 1.6}}
test btree-3.5 {inserting with tags} {
    setup
    .t insert 1.5 A\n
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 2.0 2.8 3.2 3.6} {2.0 2.1}}
test btree-3.6 {inserting with tags} {
    setup
    .t insert 1.13 A\n
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.13 3.2 3.6} {1.5 1.6}}

test btree-4.1 {deleting with tags} {
    setup
    .t delete 1.6 1.9
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.10 2.2 2.6} {1.5 1.6}}
test btree-4.2 {deleting with tags} {
    setup
    .t delete 1.1 2.3
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.4} {}}
test btree-4.3 {deleting with tags} {
    setup
    .t delete 1.4 2.1
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.9} {}}
test btree-4.4 {deleting with tags} {
    setup
    .t delete 1.14 2.1
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.13 1.15 1.19} {1.5 1.6}}
test btree-4.5 {deleting with tags} {
    setup
    .t delete 1.0 2.10
    list [.t tag ranges x] [.t tag ranges y]
} {{} {}}
test btree-4.6 {deleting with tags} {
    setup
    .t delete 1.0 1.5
    list [.t tag ranges x] [.t tag ranges y]
} {{1.0 1.8 2.2 2.6} {1.0 1.1}}
test btree-4.7 {deleting with tags} {
    setup
    .t delete 1.6 1.9
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 1.5 1.10 2.2 2.6} {1.5 1.6}}
test btree-4.8 {deleting with tags} {
    setup
    .t delete 1.5 1.13
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 2.2 2.6} {}}

set bigText1 {}
for {set i 0} {$i < 10} {incr i} {
    append bigText1 "Line $i\n"
}
set bigText2 {}
for {set i 0} {$i < 200} {incr i} {
    append bigText2 "Line $i\n"
}
test btree-5.1 {very large inserts, with tags} {
    setup
    .t insert 1.0 $bigText1
    list [.t tag ranges x] [.t tag ranges y]
} {{11.1 11.2 11.5 11.13 12.2 12.6} {11.5 11.6}}
test btree-5.2 {very large inserts, with tags} {
    setup
    .t insert 1.2 $bigText2
    list [.t tag ranges x] [.t tag ranges y]
} {{1.1 1.2 201.3 201.11 202.2 202.6} {201.3 201.4}}
test btree-5.3 {very large inserts, with tags} {
    setup
    for {set i 0} {$i < 200} {incr i} {
	.t insert 1.8 "longer line $i\n"
    }
    list [.t tag ranges x] [.t tag ranges y] [.t get 1.0 1.100] [.t get 198.0 198.100]
} {{1.1 1.2 1.5 201.5 202.2 202.6} {1.5 1.6} {Text forlonger line 199} {longer line 2}}

test btree-6.1 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    .t delete 1.2 201.2
    list [.t tag ranges x] [.t tag ranges y]
} {{1.4 1.12 2.2 2.6} {1.4 1.5}}
test btree-6.2 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 200} {incr i} {
	.t delete 1.2 2.2
    }
    list [.t tag ranges x] [.t tag ranges y]
} {{1.4 1.12 2.2 2.6} {1.4 1.5}}
test btree-6.3 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    .t delete 2.3 10000.0
    .t get 1.0 1000.0
} {TLine 0
Lin
}
test btree-6.4 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
	.t delete 30.0 31.0
    }
    list [.t tag ranges x] [.t tag ranges y]
} {{101.0 101.1 101.4 101.12 102.2 102.6} {101.4 101.5}}
test btree-6.5 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
	set j [expr $i+2]
	set k [expr 1+2*$i]
	.t tag add x $j.1 $j.3
	.t tag add y $k.1 $k.6
    }
    .t delete 2.0 200.0
    list [.t tag ranges x] [.t tag ranges y]
} {{3.0 3.1 3.4 3.12 4.2 4.6} {1.1 1.6 3.4 3.5}}
test btree-6.6 {very large deletes, with tags} {
    setup
    .t insert 1.1 $bigText2
    for {set i 0} {$i < 100} {incr i} {
	set j [expr $i+2]
	set k [expr 1+2*$i]
	.t tag add x $j.1 $j.3
	.t tag add y $k.1 $k.6
    }
    for {set i 199} {$i >= 2} {incr i -1} {
	.t delete $i.0 [expr $i+1].0
    }
    list [.t tag ranges x] [.t tag ranges y]
} {{3.0 3.1 3.4 3.12 4.2 4.6} {1.1 1.6 3.4 3.5}}

.t delete 1.0 end
.t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
set i 1
foreach check {
    {1.3 1.6 1.7 2.0 {1.3 1.6 1.7 2.0}}
    {1.3 1.6 1.6 2.0 {1.3 2.0}}
    {1.3 1.6 1.4 2.0 {1.3 2.0}}
    {2.0 4.3 1.4 1.10 {1.4 1.10 2.0 4.3}}
    {2.0 4.3 1.4 1.end {1.4 1.19 2.0 4.3}}
    {2.0 4.3 1.4 2.0 {1.4 4.3}}
    {2.0 4.3 1.4 3.0 {1.4 4.3}}
    {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.1 4.2 {1.1 4.2}}
    {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.3 4.2 {1.2 4.2}}
    {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.1 3.0 {1.1 4.0}}
    {1.2 1.3 1.6 1.7 1.end 2.0 2.4 2.7 3.0 4.0 1.2 3.0 {1.2 4.0}}
} {
    test btree-7.$i {tag addition and removal} {
	.t tag remove x 1.0 end
	while {[llength $check] > 2} {
	    .t tag add x [lindex $check 0] [lindex $check 1]
	    set check [lrange $check 2 end]
	}
	.t tag ranges x
    } [lindex $check [expr [llength $check]-1]]
    incr i
}

test btree-8.1 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 0.0 1.3
    .t tag ranges x
} {1.0 1.3}
test btree-8.2 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.40 2.4
    .t tag ranges x
} {1.19 2.4}
test btree-8.3 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 4.40 4.41
    .t tag ranges x
} {}
test btree-8.4 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 5.1 5.2
    .t tag ranges x
} {}
test btree-8.5 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 9.0
    .t tag ranges x
} {1.1 5.0}
test btree-8.6 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 1.90
    .t tag ranges x
} {1.1 1.19}
test btree-8.7 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1 4.90
    .t tag ranges x
} {1.1 4.17}
test btree-8.8 {tag addition and removal, weird ranges} {
    .t delete 1.0 100000.0
    .t tag delete x
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 3.0 3.0
    .t tag ranges x
} {}

test btree-9.1 {tag names} {
    setup
    .t tag names
} {sel x y}
test btree-9.2 {tag names} {
    setup
    .t tag add tag1 1.8
    .t tag add tag2 1.8
    .t tag add tag3 1.7 1.9
    .t tag names 1.8
} {x tag1 tag2 tag3}
test btree-9.3 {lots of tag names} {
    setup
    .t insert 1.2 $bigText2
    foreach i {tag1 foo ThisOne {x space} q r s t} {
	.t tag add $i 150.2
    }
    foreach i {u tagA tagB tagC and more {$} \{} {
	.t tag add $i 150.1 150.3
    }
    .t tag names 150.2
} {tag1 foo ThisOne {x space} q r s t u tagA tagB tagC and more {$} \{}
test btree-9.4 {lots of tag names} {
    setup
    .t insert 1.2 $bigText2
    .t tag delete tag1 foo ThisOne more {x space} q r s t u
    .t tag delete tagA tagB tagC and {$} \{ more
    foreach i {tag1 foo ThisOne more {x space} q r s t} {
	.t tag add $i 150.2
    }
    foreach i {foo ThisOne u tagA tagB tagC and more {$} \{} {
	.t tag add $i 150.4
    }
    .t tag delete tag1 more q r tagA
    .t tag names 150.2
} {foo ThisOne {x space} s t}

proc msetup {} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t mark set m1 1.2
    .t mark set l1 1.2
    .t mark gravity l1 left
    .t mark set next 1.6
    .t mark set x 1.6
    .t mark set m2 2.0
    .t mark set m3 2.100
    .t tag add x 1.3 1.8
}
test btree-10.1 {basic mark facilities} {
    msetup
    list [lsort [.t mark names]] [.t index m1] [.t index m2] [.t index m3]
} {{current insert l1 m1 m2 m3 next x} 1.2 2.0 2.11}
test btree-10.2 {basic mark facilities} {
    msetup
    .t mark unset m2
    lsort [.t mark names]
} {current insert l1 m1 m3 next x}
test btree-10.3 {basic mark facilities} {
    msetup
    .t mark set m2 1.8
    list [lsort [.t mark names]] [.t index m1] [.t index m2] [.t index m3]
} {{current insert l1 m1 m2 m3 next x} 1.2 1.8 2.11}

test btree-11.1 {marks and inserts} {
    msetup
    .t insert 1.1 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.7 1.7 1.11 1.11 2.0 2.11}
test btree-11.2 {marks and inserts} {
    msetup
    .t insert 1.2 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.7 1.11 1.11 2.0 2.11}
test btree-11.3 {marks and inserts} {
    msetup
    .t insert 1.3 abcde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.11 1.11 2.0 2.11}
test btree-11.4 {marks and inserts} {
    msetup
    .t insert 1.1 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {3.4 3.4 3.8 3.8 4.0 4.11}
test btree-11.5 {marks and inserts} {
    msetup
    .t insert 1.4 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 3.5 3.5 4.0 4.11}
test btree-11.6 {marks and inserts} {
    msetup
    .t insert 1.7 ab\n\ncde
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.6 1.6 4.0 4.11}

test btree-12.1 {marks and deletes} {
    msetup
    .t delete 1.3 1.5
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.4 1.4 2.0 2.11}
test btree-12.2 {marks and deletes} {
    msetup
    .t delete 1.3 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.3 1.3 2.0 2.11}
test btree-12.3 {marks and deletes} {
    msetup
    .t delete 1.2 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.2 1.2 2.0 2.11}
test btree-12.4 {marks and deletes} {
    msetup
    .t delete 1.1 1.8
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.1 1.1 1.1 1.1 2.0 2.11}
test btree-12.5 {marks and deletes} {
    msetup
    .t delete 1.5 3.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.5 1.5 1.5 1.5}
test btree-12.6 {marks and deletes} {
    msetup
    .t mark set m2 4.5
    .t delete 1.5 4.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.2 1.5 1.5 1.9 1.5}
test btree-12.7 {marks and deletes} {
    msetup
    .t mark set m2 4.5
    .t mark set m3 4.5
    .t mark set m1 4.7
    .t delete 1.5 4.1
    list [.t index l1] [.t index m1] [.t index next] [.t index x] [.t index m2] [.t index m3]
} {1.2 1.11 1.5 1.5 1.9 1.9}

destroy .t
text .t
test btree-13.1 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag next x 2.2 2.1
} {}
test btree-13.2 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.2 2.3
} {2.2 2.4}
test btree-13.3 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.3 2.6
} {}
test btree-13.4 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.6
} {2.5 2.8}
test btree-13.5 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.5
} {}
test btree-13.6 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.1 2.4
    .t tag next x 2.5 2.8
} {}
test btree-13.7 {tag searching} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.4
} {}
test btree-13.8 {tag searching} {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 190.3 191.2
    .t tag next x 3.5
} {190.3 191.2}

test btree-14.1 {check tag presence} {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 3.5 3.7
    .t tag add y 133.9 141.5
    .t tag add z 1.5 180.2
    .t tag add q 141.4 142.3
    .t tag add x 130.2 145.1
    .t tag add a 141.0
    .t tag add b 4.3
    .t tag add b 7.5
    .t tag add b 140.3
    for {set i 120} {$i < 160} {incr i} {
	.t tag add c $i.4
    }
    foreach i {a1 a2 a3 a4 a5 a6 a7 a8 a9 10 a11 a12 a13} {
	.t tag add $i 122.2
    }
    .t tag add x 141.3
    .t tag names 141.1
} {x y z}
test btree-14.2 {TkTextIsElided} {
    .t delete 1.0 end
    .t tag config hidden -elide 1
    .t insert end "Line1\nLine2\nLine3\n"
    .t tag add hidden 2.0 3.0
    .t tag add sel 1.2 3.2
    # next line used to panic because of "Bad tag priority being toggled on"
    # (see bug [382da038c9])
    .t index "2.0 - 1 display line linestart"
} {1.0}

test btree-15.1 {rebalance with empty node} {
    catch {destroy .t}
    text .t
    .t debug 1
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23"
    .t delete 6.0 12.0
    .t get 1.0 end
} "1\n2\n3\n4\n5\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n"

proc setupBig {} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -foreground blue
    .t tag configure y -underline true
    # Create a Btree with 2002 lines (2000 + already existing + phantom at end)
    # This generates a level 3 node with 9 children
    # Most level 2 nodes cover 216 lines and have 6 children, except the last
    # level 2 node covers 274 lines and has 7 children.
    # Most level 1 nodes cover 36 lines and have 6 children, except the
    # rightmost node has 58 lines and 9 children.
    # Level 2: 2002 = 8*216 + 274
    # Level 1: 2002 = 54*36 + 58
    # Level 0: 2002 = 332*6 + 10
    for {set i 0} {$i < 2000} {incr i} {
	append x "Line $i abcd efgh ijkl\n"
    }
    .t insert insert $x
    .t debug 1
}

test btree-16.1 {add tag does not push root above level 0} {
    catch {destroy .t}




































































































































































































































    text .t







































































































































































































































































































































































































































































































































































































































    setupBig

    .t tag add x 1.1 1.10
    .t tag add x 5.1 5.10
    .t tag ranges x


} {1.1 1.10 5.1 5.10}
test btree-16.2 {add tag pushes root up to level 1 node} {
    catch {destroy .t}
    text .t
    .t debug 1
    setupBig
    .t tag add x 1.1 1.10
    .t tag add x 8.1 8.10
    .t tag ranges x


} {1.1 1.10 8.1 8.10}
test btree-16.3 {add tag pushes root up to level 2 node} {

    .t tag remove x 1.0 end


    .t tag add x 8.1 9.10
    .t tag add x 180.1 180.end
    .t tag ranges x


} {8.1 9.10 180.1 180.23}
test btree-16.4 {add tag pushes root up to level 3 node} {

    .t tag remove x 1.0 end


    .t tag add y 1.1 2000.0
    .t tag add x 1.1 8.10
    .t tag add x 180.end 217.0
    list [.t tag ranges x] [.t tag ranges y]


} {{1.1 8.10 180.23 217.0} {1.1 2000.0}}
test btree-16.5 {add tag doesn't push root up} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 8.10
    .t tag add x 2000.0 2000.3
    .t tag add x 180.end 217.0
    .t tag ranges x


} {1.1 8.10 180.23 217.0 2000.0 2000.3}
test btree-16.6 {two node splits at once pushes root up} {

    .t delete 1.0 end

    for {set i 1} {$i < 10} {incr i} {
	.t insert end "Line $i\n"
    }
    .t tag add x 8.0 8.end
    .t tag add y 9.0 end
    set x {}
    for {} {$i < 50} {incr i} {
	append x "Line $i\n"
    }
    .t insert end $x y
    list [.t tag ranges x] [.t tag ranges y]


} {{8.0 8.6} {9.0 51.0}}
# The following find bugs in the SearchStart procedures
test btree-16.7 {Partial tag remove from before first range} {

    .t tag remove x 1.0 end




    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.0
    .t tag ranges x


} {2.0 2.6}
test btree-16.8 {Partial tag remove from before first range} {

    .t tag remove x 1.0 end




    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.1
    .t tag ranges x


} {2.1 2.6}
test btree-16.9 {Partial tag remove from before first range} {

    .t tag remove x 1.0 end




    .t tag add x 2.0 2.6
    .t tag remove x 1.0 2.3
    .t tag ranges x


} {2.3 2.6}
test btree-16.10 {Partial tag remove from before first range} {

    .t tag remove x 1.0 end




    .t tag add x 1.0 2.6
    .t tag remove x 1.0 2.5
    .t tag ranges x


} {2.5 2.6}
test btree-16.11 {StartSearchBack boundary case} {

    .t tag remove x 1.0 end




    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.4
} {}


test btree-16.12 {StartSearchBack boundary case} {

    .t tag remove x 1.0 end




    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.3


} {1.3 1.4}
test btree-16.13 {StartSearchBack boundary case} {

    .t tag remove x 1.0 end




    .t tag add x 1.0 1.4
    .t tag prevr x 1.3


} {1.0 1.4}


test btree-17.1 {remove tag does not push root down} {
    catch {destroy .t}
    text .t

    .t debug 0
    setupBig
    .t tag add x 1.1 5.10
    .t tag remove x 3.1 5.end
    .t tag ranges x


} {1.1 3.1}
test btree-17.2 {remove tag pushes root from level 1 to level 0} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 8.10
    .t tag remove x 3.1 end
    .t tag ranges x


} {1.1 3.1}
test btree-17.3 {remove tag pushes root from level 2 to level 1} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 180.10
    .t tag remove x 35.1 end
    .t tag ranges x


} {1.1 35.1}
test btree-17.4 {remove tag doesn't change level 2} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 180.10
    .t tag remove x 35.1 180.0
    .t tag ranges x


} {1.1 35.1 180.0 180.10}
test btree-17.5 {remove tag pushes root from level 3 to level 0} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.10
    .t tag add x 2000.1 2000.10
    .t tag remove x 1.0 2000.0
    .t tag ranges x


} {2000.1 2000.10}
test btree-17.6 {text deletion pushes root from level 3 to level 0} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.10
    .t tag add x 2000.1 2000.10
    .t delete 1.0 "1000.0 lineend +1 char"
    .t tag ranges x


} {1000.1 1000.10}



catch {destroy .t}
text .t

test btree-18.1 {tag search back, no tag} {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag prev x 1.1 1.1
} {}


test btree-18.2 {tag search back, start at existing range} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.1
} {}


test btree-18.3 {tag search back, end at existing range} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.3 1.1


} {1.1 1.4}
test btree-18.4 {tag search back, start within range} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.10 1.0


} {1.8 1.11}
test btree-18.5 {tag search back, start at end of range} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    list [.t tag prev x 1.4 1.0] [.t tag prev x 1.11 1.0]


} {{1.1 1.4} {1.8 1.11}}
test btree-18.6 {tag search back, start beyond range, same level 0 node} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 3.0


} {1.16 1.17}
test btree-18.7 {tag search back, outside any range} {

    .t tag remove x 1.0 end


    .t tag add x 1.1 1.4
    .t tag add x 1.16
    .t tag prev x 1.8 1.5
} {}


test btree-18.8 {tag search back, start at start of node boundary} {



    setupBig
    .t tag remove x 1.0 end
    .t tag add x 2.5 2.8
    .t tag prev x 19.0


} {2.5 2.8}
test btree-18.9 {tag search back, large complex btree spans} {

    .t tag remove x 1.0 end


    .t tag add x 1.3 1.end
    .t tag add x 200.0 220.0
    .t tag add x 500.0 520.0
    list [.t tag prev x end] [.t tag prev x 433.0]
} {{500.0 520.0} {200.0 220.0}}

destroy .t


# cleanup
cleanupTests
return

Changes to tests/textDisp.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# This file is a Tcl script to test the code in the file tkTextDisp.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Platform specific procedure for updating the text widget.

if {[tk windowingsystem] == "aqua"} {
    proc updateText {} {
	update idletasks
    }
    proc delay {} {
	update idletasks
	after 100
	update idletasks
    }
} else {
    proc updateText {} {
	update
    }
    proc delay {} {
	update
	after 100
	update
    }
}

# The procedure below is used as the scrolling command for the text;
# it just saves the scrolling information in a variable "scrollInfo".

proc scroll args {
    global scrollInfo
    set scrollInfo $args



|
|
|







<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13


14





















15
16
17
18
19
20
21
# This file is a Tcl script to test the code in the file tkTextDisp.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test



testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]






















# The procedure below is used as the scrolling command for the text;
# it just saves the scrolling information in a variable "scrollInfo".

proc scroll args {
    global scrollInfo
    set scrollInfo $args
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# The frame .f is needed to make sure that the overall window is always
# fairly wide, even if the text window is very narrow.  This is needed
# because some window managers don't allow the overall width of a window
# to get very narrow.

catch {destroy .f .t}
frame .f -width 100 -height 20
pack .f -side left

# On macOS the font "Courier New" has different metrics than "Courier",
# and this causes tests 20.1 - 20.5 to fail.  So we use "Courier" as the
# fixed font for testing on Aqua.

if {[tk windowingsystem] eq "aqua"} {
   set fixedFont {Courier -12}
} else {
  set fixedFont {"Courier New" -12}
}
# 15 on XP, 13 on Solaris 8
set fixedHeight [font metrics $fixedFont -linespace]
# 7 on all platforms
set fixedWidth [font measure $fixedFont m]
# 12 on XP
set fixedAscent [font metrics $fixedFont -ascent]
set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP







<
|
<
<
<

<
|
<
<
<







37
38
39
40
41
42
43

44



45

46



47
48
49
50
51
52
53
# The frame .f is needed to make sure that the overall window is always
# fairly wide, even if the text window is very narrow.  This is needed
# because some window managers don't allow the overall width of a window
# to get very narrow.

catch {destroy .f .t}
frame .f -width 100 -height 20

pack append . .f left





set fixedFont {Courier -12}



# 15 on XP, 13 on Solaris 8
set fixedHeight [font metrics $fixedFont -linespace]
# 7 on all platforms
set fixedWidth [font measure $fixedFont m]
# 12 on XP
set fixedAscent [font metrics $fixedFont -ascent]
set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


114
115
116
117
118
119
120
# 27 on XP, 27 on Solaris 8
set bigHeight [font metrics $bigFont -linespace]
# 21 on XP
set bigAscent [font metrics $bigFont -ascent]
set ascentDiff [expr {$bigAscent - $fixedAscent}]

text .t -font $fixedFont -width 20 -height 10 -yscrollcommand scroll
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .
updateText



# Some window managers (like olwm under SunOS 4.1.3) misbehave in a way
# that tends to march windows off the top and left of the screen.  If
# this happens, some tests will fail because parts of the window will
# not need to be displayed (because they're off-screen).  To keep this
# from happening, move the window if it's getting near the left or top
# edges of the screen.







|











|
>
>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 27 on XP, 27 on Solaris 8
set bigHeight [font metrics $bigFont -linespace]
# 21 on XP
set bigAscent [font metrics $bigFont -ascent]
set ascentDiff [expr {$bigAscent - $fixedAscent}]

text .t -font $fixedFont -width 20 -height 10 -yscrollcommand scroll
pack append . .t {top expand fill}
.t tag configure big -font $bigFont
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .
update

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

# Some window managers (like olwm under SunOS 4.1.3) misbehave in a way
# that tends to march windows off the top and left of the screen.  If
# this happens, some tests will fail because parts of the window will
# not need to be displayed (because they're off-screen).  To keep this
# from happening, move the window if it's getting near the left or top
# edges of the screen.
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {TRAFFIC SYSTEM}
    updateText
    destroy .txt
} {}

test textDisp-0.4 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {SYSTEM TRAFFIC}
    # Crash was here.
    updateText
    destroy .txt
} {}

test textDisp-0.5 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    .txt tag configure WELCOME -elide 1
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1

    .txt insert end "\n" {SYSTEM TRAFFIC}
    .txt insert end "\n" WELCOME
    # Crash was here.
    updateText
    destroy .txt
} {}

test textDisp-1.1 {GetStyle procedure, priorities and tab stops} {
    .t delete 1.0 end
    .t insert 1.0 "x\ty"
    .t tag delete x y z
    .t tag configure x -tabs 50
    .t tag configure y -foreground black
    .t tag configure z -tabs 70
    .t tag add x 1.0 1.end
    .t tag add y 1.0 1.end
    .t tag add z 1.0 1.end
    update idletasks
    set x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {}
    lappend x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs 30
    .t tag raise x
    update idletasks
    lappend x [lindex [.t bbox 1.2] 0]
} [list 75 55 55]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcd\nefg hijkl mnop qrstuv wxyz"
    .t tag configure x -wrap word
    .t tag configure y -wrap none
    .t tag raise y
    updateText
    set result [list [.t bbox 2.20]]
    .t tag add x 2.0 2.1
    lappend result [.t bbox 2.20]
    .t tag add y 1.end 2.2
    lappend result [.t bbox 2.20]
} [list [list 5 [expr {5+2*$fixedHeight}] 7 $fixedHeight] [list 40 [expr {5+2*$fixedHeight}] 7 $fixedHeight] {}]
.t tag delete x y

test textDisp-2.1 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [expr {5 + $fixedWidth * 19}] 5 $fixedWidth $fixedHeight] [list 5 [expr {5 + $fixedHeight}] $fixedWidth $fixedHeight]]
test textDisp-2.2 {LayoutDLine, basics} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.3 {LayoutDLine, basics} {textfonts} {







|












|













|







|

|







|












|













|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {TRAFFIC SYSTEM}
    update
    destroy .txt
} {}

test textDisp-0.4 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {SYSTEM TRAFFIC}
    # Crash was here.
    update
    destroy .txt
} {}

test textDisp-0.5 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    .txt tag configure WELCOME -elide 1
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1

    .txt insert end "\n" {SYSTEM TRAFFIC}
    .txt insert end "\n" WELCOME
    # Crash was here.
    update
    destroy .txt
} {}

test textDisp-1.1 {GetStyle procedure, priorities and tab stops} {
    .t delete 1.0 end
    .t insert 1.0 "x\ty"
    .t tag delete x y z
    .t tag configure x -tabs {50}
    .t tag configure y -foreground black
    .t tag configure z -tabs {70}
    .t tag add x 1.0 1.end
    .t tag add y 1.0 1.end
    .t tag add z 1.0 1.end
    update idletasks
    set x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {}
    lappend x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {30}
    .t tag raise x
    update idletasks
    lappend x [lindex [.t bbox 1.2] 0]
} [list 75 55 55]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcd\nefg hijkl mnop qrstuv wxyz"
    .t tag configure x -wrap word
    .t tag configure y -wrap none
    .t tag raise y
    update
    set result [list [.t bbox 2.20]]
    .t tag add x 2.0 2.1
    lappend result [.t bbox 2.20]
    .t tag add y 1.end 2.2
    lappend result [.t bbox 2.20]
} [list [list 5 [expr {5+2*$fixedHeight}] 7 $fixedHeight] [list 40 [expr {5+2*$fixedHeight}] 7 $fixedHeight] {}]
.t tag delete x y

test textDisp-2.1 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [expr 5 + $fixedWidth * 19] 5 $fixedWidth $fixedHeight] [list 5 [expr 5 + $fixedHeight] $fixedWidth $fixedHeight]]
test textDisp-2.2 {LayoutDLine, basics} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.3 {LayoutDLine, basics} {textfonts} {
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.13] [.t bbox 1.19] [.t bbox 1.20] [.t bbox 1.21]
} [list [list 96 5 $fixedWidth $fixedHeight] [list 138 5 $fixedWidth $fixedHeight] [list 145 5 0  $fixedHeight] [list 5 [expr {$fixedDiff + 18}] $fixedWidth $fixedHeight]]
test textDisp-2.6 {LayoutDLine, word wrap} failsOnUbuntu {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.15] [.t bbox 1.16]
} [list [list 110 5 35 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.7 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    .t tag add foo 1.4 1.6
    .t mark set insert 1.8
    list [.t bbox 1.2] [.t bbox 1.5] [.t bbox 1.11]
} [list [list 19 5 7 $fixedHeight] [list 40 5 7 $fixedHeight] [list 82 5 7 $fixedHeight]]
foreach m [.t mark names] {
    catch {.t mark unset $m}
}
scan [wm geom .] %dx%d width height
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} {textfonts} {
    wm geom . [expr {$width+1}]x$height
    updateText
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxx some sample text for testing."
    .t mark set foo 1.20
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 8 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
wm geom . {}
updateText
test textDisp-2.9 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list 68 5 77 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 110 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.10 {LayoutDLine, marks and tags} {textfonts} {







|
|



















|
|







|







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.13] [.t bbox 1.14] [.t bbox 1.19]
} [list [list 96 5 49 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 40 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.6 {LayoutDLine, word wrap} failsOnUbuntu {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.15] [.t bbox 1.16]
} [list [list 110 5 35 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.7 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    .t tag add foo 1.4 1.6
    .t mark set insert 1.8
    list [.t bbox 1.2] [.t bbox 1.5] [.t bbox 1.11]
} [list [list 19 5 7 $fixedHeight] [list 40 5 7 $fixedHeight] [list 82 5 7 $fixedHeight]]
foreach m [.t mark names] {
    catch {.t mark unset $m}
}
scan [wm geom .] %dx%d width height
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} {textfonts} {
    wm geom . [expr $width+1]x$height
    update
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxx some sample text for testing."
    .t mark set foo 1.20
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 8 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
wm geom . {}
update
test textDisp-2.9 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list 68 5 77 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 110 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.10 {LayoutDLine, marks and tags} {textfonts} {
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
test textDisp-2.16 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.1 1.20
    .t tag add x 1.21 1.end
    list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.41] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 61 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.17 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of very long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.18
    list [.t bbox 1.0] [.t bbox 1.18] [.t bbox 1.35] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 15 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.18 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to extend out of the window\n"
    .t insert end "Then\nmore lines\nThat are shorter"
    .t tag configure x -justify center
    .t tag configure y -justify right







|
|



|

|
|
|







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
test textDisp-2.16 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.1 1.20
    .t tag add x 1.21 1.end
    list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.36] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 43 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.17 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.20
    list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.36] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 19 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.18 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to extend out of the window\n"
    .t insert end "Then\nmore lines\nThat are shorter"
    .t tag configure x -justify center
    .t tag configure y -justify right
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
    set b1 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 2.0]
    set b2 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4]}]
    .t configure -spacing1 2 -spacing2 1 -spacing3 3
    set i [.t dlineinfo 1.0]
    set b1 [expr {[lindex $i 1] + [lindex $i 4] - $b1}]
    set i [.t dlineinfo 2.0]
    set b2 [expr {[lindex $i 1] + [lindex $i 4] - $b2}]
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 2 7 10 15]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.23 {LayoutDLine, spacing options} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
    set b1 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 2.0]
    set b2 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4]}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4]}]
    .t configure -spacing1 4 -spacing2 4 -spacing3 4
    .t tag configure x -spacing1 1 -spacing2 2 -spacing3 3
    .t tag add x 1.0 end
    .t tag configure y -spacing1 0 -spacing2 3
    .t tag add y 2.19 end
    .t tag raise y
    set i [.t dlineinfo 1.0]
    set b1 [expr {[lindex $i 1] + [lindex $i 4] - $b1}]
    set i [.t dlineinfo 2.0]
    set b2 [expr {[lindex $i 1] + [lindex $i 4] - $b2}]
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 1 5 13 16]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.24 {LayoutDLine, tabs, saving from first chunk} {textfonts} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -tabs 70
    .t tag configure y -tabs 80
    .t insert 1.0 "ab\tcde"
    .t tag add x 1.0 end
    .t tag add y 1.1 end
    lindex [.t bbox 1.3] 0
} 75
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {textfonts} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60 90 120]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2







|

|

|

|


|

|

|

|











|

|

|

|







|

|

|

|












|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
    set b1 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 2.0]
    set b2 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 2.end]
    set b3 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 3.0]
    set b4 [expr [lindex $i 1] + [lindex $i 4]]
    .t configure -spacing1 2 -spacing2 1 -spacing3 3
    set i [.t dlineinfo 1.0]
    set b1 [expr [lindex $i 1] + [lindex $i 4] - $b1]
    set i [.t dlineinfo 2.0]
    set b2 [expr [lindex $i 1] + [lindex $i 4] - $b2]
    set i [.t dlineinfo 2.end]
    set b3 [expr [lindex $i 1] + [lindex $i 4] - $b3]
    set i [.t dlineinfo 3.0]
    set b4 [expr [lindex $i 1] + [lindex $i 4] - $b4]
    list $b1 $b2 $b3 $b4
} [list 2 7 10 15]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.23 {LayoutDLine, spacing options} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
    set b1 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 2.0]
    set b2 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 2.end]
    set b3 [expr [lindex $i 1] + [lindex $i 4]]
    set i [.t dlineinfo 3.0]
    set b4 [expr [lindex $i 1] + [lindex $i 4]]
    .t configure -spacing1 4 -spacing2 4 -spacing3 4
    .t tag configure x -spacing1 1 -spacing2 2 -spacing3 3
    .t tag add x 1.0 end
    .t tag configure y -spacing1 0 -spacing2 3
    .t tag add y 2.19 end
    .t tag raise y
    set i [.t dlineinfo 1.0]
    set b1 [expr [lindex $i 1] + [lindex $i 4] - $b1]
    set i [.t dlineinfo 2.0]
    set b2 [expr [lindex $i 1] + [lindex $i 4] - $b2]
    set i [.t dlineinfo 2.end]
    set b3 [expr [lindex $i 1] + [lindex $i 4] - $b3]
    set i [.t dlineinfo 3.0]
    set b4 [expr [lindex $i 1] + [lindex $i 4] - $b4]
    list $b1 $b2 $b3 $b4
} [list 1 5 13 16]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.24 {LayoutDLine, tabs, saving from first chunk} {textfonts} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -tabs 70
    .t tag configure y -tabs 80
    .t insert 1.0 "ab\tcde"
    .t tag add x 1.0 end
    .t tag add y 1.1 end
    lindex [.t bbox 1.3] 0
} {75}
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {textfonts} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60 90 120]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
    .t tag add big 2.11 2.14
    list [.t bbox 1.1] [.t bbox 1.6] [.t dlineinfo 1.0] [.t dlineinfo 3.0]
} [list [list 12 [expr {5+$ascentDiff}] 7 $fixedHeight] [list 52 5 13 27] [list 5 5 114 27 [font metrics $bigFont -ascent]] [list 5 [expr {2* $fixedDiff + 85}] 35 $fixedHeight [expr {$fixedDiff + 10}]]]
.t configure -wrap char
test textDisp-4.1 {UpdateDisplayInfo, basic} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2\nLine 3\n"
    updateText
    .t delete 2.0 2.end
    updateText
    set res $tk_textRelayout
    .t insert 2.0 "New Line 2"
    updateText
    lappend res [.t bbox 1.0] [.t bbox 2.0] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] 2.0]
test textDisp-4.2 {UpdateDisplayInfo, re-use tail of text line} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    .t mark set x 2.21
    .t delete 2.2
    updateText
    set res $tk_textRelayout
    .t insert 2.0 X
    updateText
    lappend res [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 2.20 [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 12 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]
test textDisp-4.3 {UpdateDisplayInfo, tail of text line shifts} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    .t mark set x 2.21
    .t delete 2.2
    updateText
    list [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]
.t mark unset x
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    list [.t bbox 2.0] [.t bbox 2.25] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] {1.0 2.0 3.0}]
test textDisp-4.5 {UpdateDisplayInfo, tiny window} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    wm geom . 103x$height
    updateText
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    list [.t bbox 2.0] [.t bbox 2.1] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 1 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 1 $fixedHeight] {1.0 2.0 3.0}]
if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-4.6 {UpdateDisplayInfo, tiny window} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    frame .f2 -width 20 -height 100
    pack .f2 -before .f
    wm geom . 103x103
    updateText
    .t configure -wrap none -borderwidth 2
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    set x [list [.t bbox 1.0] [.t bbox 2.0] $tk_textRelayout]
    wm overrideredirect . 0
    updateText
    set x
} [list [list 5 5 1 1] {} 1.0]
catch {destroy .f2}
.t configure -borderwidth 0 -wrap char
wm geom . {}
updateText
set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
test textDisp-4.7 {UpdateDisplayInfo, filling in extra vertical space} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 1.0
    updateText
    .t yview 16.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    updateText
    set x
} {8.0 {16.0 17.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0} {8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0}}
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} failsOnXQuarz {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    updateText
    .t delete 5.0 14.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
} {1.0 {5.0 4.0 3.0 2.0 1.0} {1.0 2.0 3.0 4.0 5.0 eof}}
test textDisp-4.9 {UpdateDisplayInfo, filling in extra vertical space} {textfonts} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    updateText
    .t delete 15.0 end
    list [.t bbox 7.0] [.t bbox 12.0]
} [list [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 2 * $fixedHeight}] $fixedWidth $fixedHeight] [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 7 * $fixedHeight}] $fixedWidth $fixedHeight]]
test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    updateText
    .t delete 13.0 end
    updateText
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {5.0 {12.0 7.0 6.40 6.20 6.0 5.0} {5.0 6.0 6.20 6.40 7.0 12.0}}
test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around, not once but really quite a few times.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    updateText
    .t delete 14.0 end
    updateText
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {6.40 {13.0 7.0 6.80 6.60 6.40} {6.40 6.60 6.80 7.0 13.0}}
test textDisp-4.12 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16"
    button .b -text "Test" -bd 2 -highlightthickness 2
    .t window create 3.end -window .b
    .t yview moveto 1
    updateText
    .t yview moveto 0
    updateText
    .t yview moveto 1
    updateText
    winfo ismapped .b
} 0
.t configure -wrap word
.t delete 1.0 end
.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"
.t insert end "Line 8\nLine 9\nLine 10\nLine 11\nLine 12\nLine 13\n"
.t insert end "Line 14\nLine 15\nLine 16"
.t tag delete x
.t tag configure x -relief raised -borderwidth 2 -background white
test textDisp-4.13 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {4.0 10.0 11.0 12.0 13.0}}
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} failsOnXQuarz {
    .t tag remove x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {11.0 12.0 13.0}}
test textDisp-4.15 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 4.0
    updateText
    .t yview scroll -2 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0 4.0 11.0}}
test textDisp-4.16 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 4.0
    updateText
    .t yview scroll -2 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.0] [.t bbox 2.5] \
	    [.t bbox 2.23]
} [list {} {1.0 2.0 3.0 4.0} {} [list 17 [expr {$fixedDiff + 16}] 7 $fixedHeight] {}]
test textDisp-4.18 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview scroll 100 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list {} {1.0 2.0 3.0 4.0} [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.19 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview moveto 0
    .t xview scroll -10 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.5]
} [list {} {1.0 2.0 3.0 4.0} [list 38 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.20 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto 0.0
    .t xview scroll 100 units
    updateText
    .t delete 2.30 2.44
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list 2.0 {1.0 2.0 3.0 4.0} [list 108 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.21 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto .9
    updateText
    .t xview moveto .6
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {}}
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    updateText
    .t configure -wrap word
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 10 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
test textDisp-4.23 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    updateText
    .t configure -wrap char
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 115 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-5.1 {DisplayDLine, handling of spacing} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    updateText
    list [winfo geometry .t.f1] [winfo geometry .t.f2] \
	    [winfo geometry .t.f3] [winfo geometry .t.f4]
} [list 10x4+24+11 10x4+55+[expr {$fixedDiff/2 + 15}] 10x4+10+[expr {2*$fixedDiff + 43}] 10x4+76+[expr {2*$fixedDiff + 40}]]
.t tag delete spacing

# Although the following test produces a useful result, its main
# effect is to produce a core dump if Tk doesn't handle display
# relayout that occurs during redisplay.

test textDisp-5.2 {DisplayDLine, line resizes during display} {
    .t delete 1.0 end
    frame .t.f -width 20 -height 20 -bd 2 -relief raised
    bind .t.f <Configure> {.t.f configure -width 30 -height 30}
    .t window create insert -window .t.f
    updateText
    list [winfo width .t.f] [winfo height .t.f]
} [list 30 30]

.t configure -wrap char
test textDisp-6.1 {scrolling in DisplayText, scroll up} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 10.0} {2.0 10.0}}
test textDisp-6.2 {scrolling in DisplayText, scroll down} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.0 "New Line 2\n"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-6.3 {scrolling in DisplayText, multiple scrolls} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.end "is so long that it wraps"
    .t insert 4.end "is so long that it wraps"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 4.0 4.20} {2.0 2.20 4.0 4.20}}
test textDisp-6.4 {scrolling in DisplayText, scrolls interfere} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.end "is so long that it wraps around, not once but three times"
    .t insert 4.end "is so long that it wraps"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 2.40 2.60 4.0 4.20} {2.0 2.20 2.40 2.60 4.0 4.20 6.0}}
test textDisp-6.5 {scrolling in DisplayText, scroll source obscured} {nonPortable} {
    .t configure -wrap char
    frame .f2 -bg red
    place .f2 -in .t -relx 0.5 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.6 1.end
    updateText
    destroy .f2
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 4.0 5.0 9.0 10.0}}
test textDisp-6.6 {scrolling in DisplayText, Expose events after scroll} {unix nonPortable} {
    # this test depends on all of the expose events being handled at once
    .t configure -wrap char
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t configure -bd 2 -relief raised
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.6 1.end
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {borders 1.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0}}
.t configure -bd 0
test textDisp-6.7 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-6.8 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    updateText
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    .t count -update -ypixels 1.0 end ; update
    set scrollInfo
} [list 0.0 [expr {10.0/13}]]
.t configure -yscrollcommand {} -xscrollcommand scroll
test textDisp-6.9 {DisplayText, horizontal scrollbar updates} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo unchanged
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-6.10 {DisplayText, redisplay embedded windows after scroll.} {aqua} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4} {
	.t insert end "\nLine $i"
    }
    .t insert end "\n"
    .t window create end -create {
	button %W.button_one -text "Button 1"}
    .t insert end "\nLine 6\n"
    .t window create end -create {
	button %W.button_two -text "Button 2"}
    .t insert end "\nLine 8\n"
    .t window create end -create {
	button %W.button_three -text "Button 3"}
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textEmbWinDisplay
} {{4.0 6.0}}


# The following group of tests is marked non-portable because
# they result in a lot of extra redisplay under Ultrix.  I don't
# know why this is so.

.t configure -bd 2 -relief raised -wrap char
.t delete 1.0 end
.t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
    .t insert end "\nLine $i"
}
test textDisp-7.1 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -relwidth 0.6 -rely 0.22 -relheight 0.55
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {1.40 2.0 3.0 4.0 5.0 6.0}}
test textDisp-7.2 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.5 -rely 0 -relheight 0.5
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.5 -relwidth 0.5 -rely 0.5 -relheight 0.5
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 8.0}}
test textDisp-7.4 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 0 -relheight 0.2 \
	    -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20}}
test textDisp-7.5 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 1.0 -relheight 0.2 \
	    -anchor s -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 7.0 8.0}}
test textDisp-7.6 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor w -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.7 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 1.0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor e -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.8 {TkTextRedrawRegion} {nonPortable} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n"
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.0 -relwidth 0.4 -rely 0.35 -relheight 0.4 \
	    -anchor nw -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 eof}}
.t configure -bd 0

test textDisp-8.1 {TkTextChanged: redisplay whole lines} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around, two times"
    foreach i {3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.36 2.38
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.32]
} [list {2.0 2.18 2.38} {2.0 2.18 2.38} [list 101 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
.t configure -wrap char
test textDisp-8.2 {TkTextChanged, redisplay whole lines} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 1.2 xx
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.3 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.0 xx
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.4 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.5
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.5 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.40 1.44
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.6 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.41 1.44
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.2 1.end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 9.0 10.0}}
test textDisp-8.8 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t delete 2.19
    updateText
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-8.11 {TkTextChanged, scrollbar notification when changes are off-screen} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n"
    .t configure -yscrollcommand scroll
    updateText
    set scrollInfo ""
    .t insert end "a\nb\nc\n"
    # We need to wait for our asychronous callbacks to update the
    # scrollbar
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    .t configure -yscrollcommand ""
    set scrollInfo
} {0.0 0.625}
test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past and new lines} {
    .t delete 1.0 end
    .t configure -wrap none
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i Line $i\n"
    }
    .t tag add hidden 5.0 8.0
    .t tag configure hidden -elide true
    .t mark set insert 9.0
    updateText
    .t mark set insert 8.0        ; # up one line
    updateText
    set res [list $tk_textRedraw]
    .t mark set insert 12.2       ; # in the visible text
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 6.5        ; # in the hidden text
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 3.5        ; # in the visible text again
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 3.8        ; # within the same line
    updateText
    lappend res $tk_textRedraw
} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {3.0 4.0}}
test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} {
    .t delete 1.0 end
    .t insert 1.0 \nLine2\nLine3\n
    updateText
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.18} {2.0 2.18}}
test textDisp-9.2 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 1.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.17} {1.0 2.0 2.17}}
test textDisp-9.3 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.20
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.5 {TkTextRedrawTag} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.end
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap"
    updateText
    .t tag add big 2.2 3.5
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 3.0 3.20} {2.0 2.20 3.0 3.20 eof}}
test textDisp-9.7 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t tag remove big 2.19
    updateText
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-9.8 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 2.0 2.5
    updateText
    set tk_textRedraw
} {2.0 2.17}
test textDisp-9.9 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 1.5 2.5
    updateText
    set tk_textRedraw
} {2.0 2.17}
test textDisp-9.10 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    set tk_textRedraw none
    .t tag add big 1.3 1.5
    updateText
    set tk_textRedraw
} none
test textDisp-9.11 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 1.0 2.0
    updateText
    set tk_textRedraw
} {}
test textDisp-9.12 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 5} {incr i} {
      .t insert end "Line $i+++Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 2.6 3.6
    updateText
    .t tag add hidden 3.11 4.6
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 {2.0 eof}}
test textDisp-9.13 {TkTextRedrawTag} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - This is Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.17
    .t tag add hidden 6.8 7.17
    .t tag configure hidden -background red
    .t tag configure hidden -elide true
    updateText
    .t tag configure hidden -elide false
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 6.0 7.0} {2.0 6.0 7.0}}
test textDisp-9.14 {TkTextRedrawTag} {
    pack [text .tnocrash]
    for {set i 1} {$i < 6} {incr i} {
        .tnocrash insert end \nfoo$i
    }
    .tnocrash tag configure mytag1 -relief raised
    .tnocrash tag configure mytag2 -relief solid
    updateText
    proc doit {} {
        .tnocrash tag add mytag1 4.0 5.0
        .tnocrash tag add mytag2 4.0 5.0
        after idle {
            .tnocrash tag remove mytag1 1.0 end
            .tnocrash tag remove mytag2 1.0 end
        }







|

|


|





|


|


|





|


|







|







|



|

















|

|



|


|





|


















|

|


|


|



|

|






|







|

|






|

|








|

|

|

|










|

|


|


|

|





|

|





|

|







|

|








|

|







|


|









|

|








|

|








|









|

















|














|




|





|

|








|

|









|


|









|


|











|

|














|


|






<
|
<






|




<
|






|




|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














|

|





|

|





|

|






|

|






|

|






|

|






|

|








|

|











|

|









|

|








|

|








|

|








|

|








|

|


|





|

|








|

|


|





|

|







|

|






|




<
|
<












|

|


|


|


|


|





|









|

|






|

|






|

|

|






|

|

|


|



|

|

|






|

|

|







|

|







|

|







|

|







|
|

|

|





|

|










|

|






|





|

|









|







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927

928

929
930
931
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954






















955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158

1159

1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
    .t tag add big 2.11 2.14
    list [.t bbox 1.1] [.t bbox 1.6] [.t dlineinfo 1.0] [.t dlineinfo 3.0]
} [list [list 12 [expr {5+$ascentDiff}] 7 $fixedHeight] [list 52 5 13 27] [list 5 5 114 27 [font metrics $bigFont -ascent]] [list 5 [expr {2* $fixedDiff + 85}] 35 $fixedHeight [expr {$fixedDiff + 10}]]]
.t configure -wrap char
test textDisp-4.1 {UpdateDisplayInfo, basic} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2\nLine 3\n"
    update
    .t delete 2.0 2.end
    update
    set res $tk_textRelayout
    .t insert 2.0 "New Line 2"
    update
    lappend res [.t bbox 1.0] [.t bbox 2.0] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] 2.0]
test textDisp-4.2 {UpdateDisplayInfo, re-use tail of text line} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    .t mark set x 2.21
    .t delete 2.2
    update
    set res $tk_textRelayout
    .t insert 2.0 X
    update
    lappend res [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 2.20 [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 12 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]
test textDisp-4.3 {UpdateDisplayInfo, tail of text line shifts} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    .t mark set x 2.21
    .t delete 2.2
    update
    list [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]
.t mark unset x
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    list [.t bbox 2.0] [.t bbox 2.25] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] {1.0 2.0 3.0}]
test textDisp-4.5 {UpdateDisplayInfo, tiny window} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    wm geom . 103x$height
    update
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    list [.t bbox 2.0] [.t bbox 2.1] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 1 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 1 $fixedHeight] {1.0 2.0 3.0}]
if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-4.6 {UpdateDisplayInfo, tiny window} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    frame .f2 -width 20 -height 100
    pack before .f .f2 top
    wm geom . 103x103
    update
    .t configure -wrap none -borderwidth 2
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    set x [list [.t bbox 1.0] [.t bbox 2.0] $tk_textRelayout]
    wm overrideredirect . 0
    update
    set x
} [list [list 5 5 1 1] {} 1.0]
catch {destroy .f2}
.t configure -borderwidth 0 -wrap char
wm geom . {}
update
set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
test textDisp-4.7 {UpdateDisplayInfo, filling in extra vertical space} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 1.0
    update
    .t yview 16.0
    update
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    update
    set x
} {8.0 {16.0 17.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0} {8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0}}
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    update
    .t delete 5.0 14.0
    update
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
} {1.0 {5.0 4.0 3.0 2.0 1.0} {1.0 2.0 3.0 4.0 5.0 eof}}
test textDisp-4.9 {UpdateDisplayInfo, filling in extra vertical space} {textfonts} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    update
    .t delete 15.0 end
    list [.t bbox 7.0] [.t bbox 12.0]
} [list [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 2 * $fixedHeight}] $fixedWidth $fixedHeight] [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 7 * $fixedHeight}] $fixedWidth $fixedHeight]]
test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    update
    .t delete 13.0 end
    update
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {5.0 {12.0 7.0 6.40 6.20 6.0 5.0} {5.0 6.0 6.20 6.40 7.0 12.0}}
test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around, not once but really quite a few times.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    update
    .t delete 14.0 end
    update
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {6.40 {13.0 7.0 6.80 6.60 6.40} {6.40 6.60 6.80 7.0 13.0}}
test textDisp-4.12 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16"
    button .b -text "Test" -bd 2 -highlightthickness 2
    .t window create 3.end -window .b
    .t yview moveto 1
    update
    .t yview moveto 0
    update
    .t yview moveto 1
    update
    winfo ismapped .b
} {0}
.t configure -wrap word
.t delete 1.0 end
.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"
.t insert end "Line 8\nLine 9\nLine 10\nLine 11\nLine 12\nLine 13\n"
.t insert end "Line 14\nLine 15\nLine 16"
.t tag delete x
.t tag configure x -relief raised -borderwidth 2 -background white
test textDisp-4.13 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 1.0
    update
    .t yview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {4.0 10.0 11.0 12.0 13.0}}
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 1.0
    update
    .t yview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {11.0 12.0 13.0}}
test textDisp-4.15 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 4.0
    update
    .t yview scroll -2 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0 4.0 11.0}}
test textDisp-4.16 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 4.0
    update
    .t yview scroll -2 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.0] [.t bbox 2.5] \
	    [.t bbox 2.23]
} [list {} {1.0 2.0 3.0 4.0} {} [list 17 [expr {$fixedDiff + 16}] 7 $fixedHeight] {}]
test textDisp-4.18 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview scroll 100 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list {} {1.0 2.0 3.0 4.0} [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.19 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview moveto 0
    .t xview scroll -10 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.5]
} [list {} {1.0 2.0 3.0 4.0} [list 38 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.20 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto 0.0
    .t xview scroll 100 units
    update
    .t delete 2.30 2.44
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list 2.0 {1.0 2.0 3.0 4.0} [list 108 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-4.21 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto .9
    update
    .t xview moveto .6
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {}}
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    update
    .t configure -wrap word
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 10 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
test textDisp-4.23 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    update
    .t configure -wrap char
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 115 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-5.1 {DisplayDLine, handling of spacing} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    update
    list [winfo geometry .t.f1] [winfo geometry .t.f2] \
	    [winfo geometry .t.f3] [winfo geometry .t.f4]
} [list 10x4+24+11 10x4+55+[expr {$fixedDiff/2 + 15}] 10x4+10+[expr {2*$fixedDiff + 43}] 10x4+76+[expr {2*$fixedDiff + 40}]]
.t tag delete spacing

# Although the following test produces a useful result, its main
# effect is to produce a core dump if Tk doesn't handle display
# relayout that occurs during redisplay.

test textDisp-5.2 {DisplayDLine, line resizes during display} {
    .t delete 1.0 end
    frame .t.f -width 20 -height 20 -bd 2 -relief raised
    bind .t.f <Configure> {.t.f configure -width 30 -height 30}
    .t window create insert -window .t.f
    update
    list [winfo width .t.f] [winfo height .t.f]
} [list 30 30]

.t configure -wrap char
test textDisp-6.1 {scrolling in DisplayText, scroll up} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.0 3.0
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 10.0} {2.0 10.0}}
test textDisp-6.2 {scrolling in DisplayText, scroll down} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.0 "New Line 2\n"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-6.3 {scrolling in DisplayText, multiple scrolls} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.end "is so long that it wraps"
    .t insert 4.end "is so long that it wraps"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 4.0 4.20} {2.0 2.20 4.0 4.20}}
test textDisp-6.4 {scrolling in DisplayText, scrolls interfere} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.end "is so long that it wraps around, not once but three times"
    .t insert 4.end "is so long that it wraps"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 2.40 2.60 4.0 4.20} {2.0 2.20 2.40 2.60 4.0 4.20 6.0}}
test textDisp-6.5 {scrolling in DisplayText, scroll source obscured} {nonPortable} {
    .t configure -wrap char
    frame .f2 -bg red
    place .f2 -in .t -relx 0.5 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.6 1.end
    update
    destroy .f2
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 4.0 5.0 9.0 10.0}}
test textDisp-6.6 {scrolling in DisplayText, Expose events after scroll} {unix nonPortable} {
    # this test depends on all of the expose events being handled at once
    .t configure -wrap char
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t configure -bd 2 -relief raised
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.6 1.end
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {borders 1.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0}}
.t configure -bd 0
test textDisp-6.7 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end

    update ; .t count -update -ypixels 1.0 end ; update

    set scrollInfo
} {0.0 1.0}
test textDisp-6.8 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }

    update ; .t count -update -ypixels 1.0 end ; update
    set scrollInfo
} [list 0.0 [expr {10.0/13}]]
.t configure -yscrollcommand {} -xscrollcommand scroll
test textDisp-6.9 {DisplayText, horizontal scrollbar updates} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo unchanged
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]























# The following group of tests is marked non-portable because
# they result in a lot of extra redisplay under Ultrix.  I don't
# know why this is so.

.t configure -bd 2 -relief raised -wrap char
.t delete 1.0 end
.t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
    .t insert end "\nLine $i"
}
test textDisp-7.1 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -relwidth 0.6 -rely 0.22 -relheight 0.55
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {1.40 2.0 3.0 4.0 5.0 6.0}}
test textDisp-7.2 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.5 -rely 0 -relheight 0.5
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.5 -relwidth 0.5 -rely 0.5 -relheight 0.5
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 8.0}}
test textDisp-7.4 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 0 -relheight 0.2 \
	    -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20}}
test textDisp-7.5 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 1.0 -relheight 0.2 \
	    -anchor s -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 7.0 8.0}}
test textDisp-7.6 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor w -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.7 {TkTextRedrawRegion} {nonPortable} {
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 1.0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor e -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.8 {TkTextRedrawRegion} {nonPortable} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n"
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.0 -relwidth 0.4 -rely 0.35 -relheight 0.4 \
	    -anchor nw -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 eof}}
.t configure -bd 0

test textDisp-8.1 {TkTextChanged: redisplay whole lines} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around, two times"
    foreach i {3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.36 2.38
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.32]
} [list {2.0 2.18 2.38} {2.0 2.18 2.38} [list 101 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
.t configure -wrap char
test textDisp-8.2 {TkTextChanged, redisplay whole lines} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 1.2 xx
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.3 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.0 xx
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.4 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.5
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.5 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.40 1.44
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.6 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.41 1.44
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.2 1.end
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 9.0 10.0}}
test textDisp-8.8 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.2
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.0 3.0
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    update
    .t delete 2.19
    update
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-8.11 {TkTextChanged, scrollbar notification when changes are off-screen} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n"
    .t configure -yscrollcommand scroll
    update
    set scrollInfo ""
    .t insert end "a\nb\nc\n"
    # We need to wait for our asychronous callbacks to update the
    # scrollbar

    update ; .t count -update -ypixels 1.0 end ; update

    .t configure -yscrollcommand ""
    set scrollInfo
} {0.0 0.625}
test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past and new lines} {
    .t delete 1.0 end
    .t configure -wrap none
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i Line $i\n"
    }
    .t tag add hidden 5.0 8.0
    .t tag configure hidden -elide true
    .t mark set insert 9.0
    update
    .t mark set insert 8.0        ; # up one line
    update
    set res [list $tk_textRedraw]
    .t mark set insert 12.2       ; # in the visible text
    update
    lappend res $tk_textRedraw
    .t mark set insert 6.5        ; # in the hidden text
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.5        ; # in the visible text again
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.8        ; # within the same line
    update
    lappend res $tk_textRedraw
} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {3.0 4.0}}
test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} {
    .t delete 1.0 end
    .t insert 1.0 \nLine2\nLine3\n
    update
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.4
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.18} {2.0 2.18}}
test textDisp-9.2 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 1.2 2.4
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.17} {1.0 2.0 2.17}}
test textDisp-9.3 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.4
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.20
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.5 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.end
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap"
    update
    .t tag add big 2.2 3.5
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 3.0 3.20} {2.0 2.20 3.0 3.20 eof}}
test textDisp-9.7 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    update
    .t tag remove big 2.19
    update
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-9.8 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    .t tag add big 2.0 2.5
    update
    set tk_textRedraw
} {2.0 2.17}
test textDisp-9.9 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    .t tag add big 1.5 2.5
    update
    set tk_textRedraw
} {2.0 2.17}
test textDisp-9.10 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    set tk_textRedraw {none}
    .t tag add big 1.3 1.5
    update
    set tk_textRedraw
} {none}
test textDisp-9.11 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    .t tag add big 1.0 2.0
    update
    set tk_textRedraw
} {}
test textDisp-9.12 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 5} {incr i} {
      .t insert end "Line $i+++Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 2.6 3.6
    update
    .t tag add hidden 3.11 4.6
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 {2.0 eof}}
test textDisp-9.13 {TkTextRedrawTag} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - This is Line [format %c [expr 64+$i]]\n"
    }
    .t tag add hidden 2.8 2.17
    .t tag add hidden 6.8 7.17
    .t tag configure hidden -background red
    .t tag configure hidden -elide true
    update
    .t tag configure hidden -elide false
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 6.0 7.0} {2.0 6.0 7.0}}
test textDisp-9.14 {TkTextRedrawTag} {
    pack [text .tnocrash]
    for {set i 1} {$i < 6} {incr i} {
        .tnocrash insert end \nfoo$i
    }
    .tnocrash tag configure mytag1 -relief raised
    .tnocrash tag configure mytag2 -relief solid
    update
    proc doit {} {
        .tnocrash tag add mytag1 4.0 5.0
        .tnocrash tag add mytag2 4.0 5.0
        after idle {
            .tnocrash tag remove mytag1 1.0 end
            .tnocrash tag remove mytag2 1.0 end
        }
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    vwait done
} {}

test textDisp-10.1 {TkTextRelayoutWindow} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    updateText
    .t configure -bg black
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.20 3.0 3.20 4.0} {borders 1.0 2.0 2.20 3.0 3.20 4.0 eof}}
.t configure -bg [lindex [.t configure -bg] 3]
catch {destroy .top}
test textDisp-10.2 {TkTextRelayoutWindow} {
    toplevel .top -width 300 -height 200
    wm geometry .top +0+0
    text .top.t -font $fixedFont -width 20 -height 10 -relief raised -bd 2
    place .top.t -x 0 -y 0 -width 20 -height 20
    .top.t insert end "First line"
    .top.t see insert
    tkwait visibility .top.t
    place .top.t -width 150 -height 100
    updateText
    .top.t index @0,0
} {1.0}
catch {destroy .top}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
updateText
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 32.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t yview 28.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 31.4
    updateText
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 31.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {30.0 {}}
test textDisp-11.6 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 28.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.7 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {21.0 {21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0}}
test textDisp-11.8 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {38.0 {40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0}}
test textDisp-11.10 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview 10000.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0 197.0 198.0 199.0 200.0}}
test textDisp-11.11 {TkTextSetYView} {
    .t yview 195.0
    updateText
    set tk_textRedraw {}
    .t yview 197.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0}}
test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} failsOnXQuarz {
    .t insert 10.0 "Long line with enough text to wrap\n"
    .t yview 1.0
    updateText
    set tk_textRedraw {}
    .t see 10.30
    updateText
    list [.t index @0,0] $tk_textRedraw
} {2.0 10.20}
.t delete 10.0 11.0
test textDisp-11.13 {TkTestSetYView, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 20 -height 5
    pack .top.t
    .top.t insert end "Line 1"
    for {set i 2} {$i <= 100} {incr i} {
	.top.t insert end "\nLine $i"
    }
    updateText
    scan [wm geometry .top] "%dx%d" w2 h2
    wm geometry .top ${w2}x[expr {$h2-2}]
    updateText
    .top.t yview 1.0
    updateText
    set tk_textRedraw {}
    .top.t see 5.0
    updateText
    # Note, with smooth scrolling, the results of this test
    # have changed, and the old '2.0 {5.0 6.0}' is quite wrong.
    list [.top.t index @0,0] $tk_textRedraw
} {1.0 5.0}
catch {destroy .top}
toplevel .top
wm geometry .top +0+0
text .top.t -width 30 -height 3
pack .top.t
.top.t insert end "Line 1"
for {set i 2} {$i <= 20} {incr i} {
    .top.t insert end "\nLine $i"
}
updateText
test textDisp-11.14 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    updateText
    .top.t see 10.0
    .top.t index @0,0
} {8.0}
test textDisp-11.15 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    updateText
    .top.t see 11.0
    .top.t index @0,0
    # The index 9.0 should be just visible by a couple of pixels
} {9.0}
test textDisp-11.16 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    updateText
    .top.t see 5.0
    .top.t index @0,0
} {5.0}
test textDisp-11.17 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    updateText
    .top.t see 4.0
    .top.t index @0,0
    # The index 2.0 should be just visible by a couple of pixels
} {2.0}
test textDisp-11.18 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 20} {incr i} {
        .top.t insert end [string repeat "Line $i" 10]
        .top.t insert end "\n"
    }
    .top.t yview 4.0
    .top.t tag add hidden 4.10 "4.10 lineend"
    .top.t tag add hidden 5.15 10.3
    .top.t tag configure hidden -elide true
    updateText
    .top.t see "8.0 lineend"
    # The index "8.0 lineend" is on screen despite elided -> no scroll
    .top.t index @0,0
} {4.0}
test textDisp-11.19 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    # button just for having a line with a larger height
    button .top.t.b -text "Test" -bd 2 -highlightthickness 2
    .top.t window create 21.0 -window .top.t.b
    .top.t tag add hidden 15.36 21.0
    .top.t tag configure hidden -elide true
    .top.t configure -height 15
    wm geometry .top 300x200+0+0
    # Indices 21.0, 17.0 and 15.0 are all on the same display line
    # therefore index @0,0 shall be the same for all of them
    .top.t see end
    updateText
    .top.t see 21.0
    updateText
    set ind1 [.top.t index @0,0]
    .top.t see end
    updateText
    .top.t see 17.0
    updateText
    set ind2 [.top.t index @0,0]
    .top.t see end
    updateText
    .top.t see 15.0
    updateText
    set ind3 [.top.t index @0,0]
    list [expr {$ind1 == $ind2}] [expr {$ind1 == $ind3}]
} {1 1}
test textDisp-11.20 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    .top.t configure -wrap none
    for {set i 1} {$i < 5} {incr i} {







|

|













|









|


|


|

|

|




|

|


|

|

|




|


|




|


|




|


|


|

|


|


|

|


|




|


|




|


|


|


|


|













|

|
|

|


|













|


|





|






|





|














|



















|

|


|

|


|

|







1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
    vwait done
} {}

test textDisp-10.1 {TkTextRelayoutWindow} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    update
    .t configure -bg black
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.20 3.0 3.20 4.0} {borders 1.0 2.0 2.20 3.0 3.20 4.0 eof}}
.t configure -bg [lindex [.t configure -bg] 3]
catch {destroy .top}
test textDisp-10.2 {TkTextRelayoutWindow} {
    toplevel .top -width 300 -height 200
    wm geometry .top +0+0
    text .top.t -font $fixedFont -width 20 -height 10 -relief raised -bd 2
    place .top.t -x 0 -y 0 -width 20 -height 20
    .top.t insert end "First line"
    .top.t see insert
    tkwait visibility .top.t
    place .top.t -width 150 -height 100
    update
    .top.t index @0,0
} {1.0}
catch {destroy .top}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
update
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    update
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 32.0
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 28.0
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 31.4
    update
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 31.0
    update
    list [.t index @0,0] $tk_textRedraw
} {30.0 {}}
test textDisp-11.6 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 28.0
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.7 {TkTextSetYView} {
    .t yview 30.0
    update ; update
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    update
    list [.t index @0,0] $tk_textRedraw
} {21.0 {21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0}}
test textDisp-11.8 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    update
    list [.t index @0,0] $tk_textRedraw
} {38.0 {40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0}}
test textDisp-11.10 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview 10000.0
    update
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0 197.0 198.0 199.0 200.0}}
test textDisp-11.11 {TkTextSetYView} {
    .t yview 195.0
    update
    set tk_textRedraw {}
    .t yview 197.0
    update
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0}}
test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} {
    .t insert 10.0 "Long line with enough text to wrap\n"
    .t yview 1.0
    update
    set tk_textRedraw {}
    .t see 10.30
    update
    list [.t index @0,0] $tk_textRedraw
} {2.0 10.20}
.t delete 10.0 11.0
test textDisp-11.13 {TkTestSetYView, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 20 -height 5
    pack .top.t
    .top.t insert end "Line 1"
    for {set i 2} {$i <= 100} {incr i} {
	.top.t insert end "\nLine $i"
    }
    update
    scan [wm geometry .top] "%dx%d" w2 h2
    wm geometry .top ${w2}x[expr $h2-2]
    update
    .top.t yview 1.0
    update
    set tk_textRedraw {}
    .top.t see 5.0
    update
    # Note, with smooth scrolling, the results of this test
    # have changed, and the old '2.0 {5.0 6.0}' is quite wrong.
    list [.top.t index @0,0] $tk_textRedraw
} {1.0 5.0}
catch {destroy .top}
toplevel .top
wm geometry .top +0+0
text .top.t -width 30 -height 3
pack .top.t
.top.t insert end "Line 1"
for {set i 2} {$i <= 20} {incr i} {
    .top.t insert end "\nLine $i"
}
update
test textDisp-11.14 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    update
    .top.t see 10.0
    .top.t index @0,0
} {8.0}
test textDisp-11.15 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    update
    .top.t see 11.0
    .top.t index @0,0
    # The index 9.0 should be just visible by a couple of pixels
} {9.0}
test textDisp-11.16 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    update
    .top.t see 5.0
    .top.t index @0,0
} {5.0}
test textDisp-11.17 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    update
    .top.t see 4.0
    .top.t index @0,0
    # The index 2.0 should be just visible by a couple of pixels
} {2.0}
test textDisp-11.18 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 20} {incr i} {
        .top.t insert end [string repeat "Line $i" 10]
        .top.t insert end "\n"
    }
    .top.t yview 4.0
    .top.t tag add hidden 4.10 "4.10 lineend"
    .top.t tag add hidden 5.15 10.3
    .top.t tag configure hidden -elide true
    update
    .top.t see "8.0 lineend"
    # The index "8.0 lineend" is on screen despite elided -> no scroll
    .top.t index @0,0
} {4.0}
test textDisp-11.19 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    # button just for having a line with a larger height
    button .top.t.b -text "Test" -bd 2 -highlightthickness 2
    .top.t window create 21.0 -window .top.t.b
    .top.t tag add hidden 15.36 21.0
    .top.t tag configure hidden -elide true
    .top.t configure -height 15
    wm geometry .top 300x200+0+0
    # Indices 21.0, 17.0 and 15.0 are all on the same display line
    # therefore index @0,0 shall be the same for all of them
    .top.t see end
    update
    .top.t see 21.0
    update
    set ind1 [.top.t index @0,0]
    .top.t see end
    update
    .top.t see 17.0
    update
    set ind2 [.top.t index @0,0]
    .top.t see end
    update
    .top.t see 15.0
    update
    set ind3 [.top.t index @0,0]
    list [expr {$ind1 == $ind2}] [expr {$ind1 == $ind3}]
} {1 1}
test textDisp-11.20 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    .top.t configure -wrap none
    for {set i 1} {$i < 5} {incr i} {
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
test textDisp-11.21 {TkTextSetYView, window height smaller than the line height} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 10} {incr i} {
        .top.t insert end "Line $i\n"
    }
    set lineheight [font metrics [.top.t cget -font] -linespace]
    wm geometry .top 200x[expr {$lineheight / 2}]
    updateText
    .top.t see 1.0
    .top.t index @0,[expr {$lineheight - 2}]
} {1.0}

.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-12.1 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 52.0
    updateText
    .t index @0,0
} {49.0}
test textDisp-12.2 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 53.0
    updateText
    .t index @0,0
} {50.0}
test textDisp-12.3 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 50.10
    updateText
    .t index @0,0
} {45.0}
.t configure -wrap none
test textDisp-12.4 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 53.0
    updateText
    .t index @0,0
} {48.0}
test textDisp-12.5 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 50.10
    updateText
    .t index @0,0
} {45.0}

.t configure -wrap none
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"







|









|

|




|

|




|

|





|

|




|

|







1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
test textDisp-11.21 {TkTextSetYView, window height smaller than the line height} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 10} {incr i} {
        .top.t insert end "Line $i\n"
    }
    set lineheight [font metrics [.top.t cget -font] -linespace]
    wm geometry .top 200x[expr {$lineheight / 2}]
    update
    .top.t see 1.0
    .top.t index @0,[expr {$lineheight - 2}]
} {1.0}

.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-12.1 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 52.0
    update
    .t index @0,0
} {49.0}
test textDisp-12.2 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 53.0
    update
    .t index @0,0
} {50.0}
test textDisp-12.3 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 50.10
    update
    .t index @0,0
} {45.0}
.t configure -wrap none
test textDisp-12.4 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 53.0
    update
    .t index @0,0
} {48.0}
test textDisp-12.5 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 50.10
    update
    .t index @0,0
} {45.0}

.t configure -wrap none
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
} {1 {wrong # args: should be ".t see index"}}
test textDisp-13.3 {TkTextSeeCmd procedure} {
    list [catch {.t see badIndex} msg] $msg
} {1 {bad text index "badIndex"}}
test textDisp-13.4 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 4.2
    .t index @0,0
} {1.0}
test textDisp-13.5 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 12.1
    .t index @0,0
} {3.0}
test textDisp-13.6 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 30.50
    set x [.t index @0,0]
    .t configure -wrap none
    set x
} {27.0}
test textDisp-13.7 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.40
    updateText
    .t see 30.50
    .t yview 25.0
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.39
    lappend x [.t bbox 30.39]
    .t see 30.38
    lappend x [.t bbox 30.38]
    .t see 30.20
    lappend x [.t bbox 30.20]
} [list [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight]]
test textDisp-13.8 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    updateText
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
} [list [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight]]
test textDisp-13.9 {TkTextSeeCmd procedure} {textfonts} {
    wm geom . [expr {$width-2}]x$height
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    updateText
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90







|







|







|










|
















|










|




|







1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
} {1 {wrong # args: should be ".t see index"}}
test textDisp-13.3 {TkTextSeeCmd procedure} {
    list [catch {.t see badIndex} msg] $msg
} {1 {bad text index "badIndex"}}
test textDisp-13.4 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 4.2
    .t index @0,0
} {1.0}
test textDisp-13.5 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 12.1
    .t index @0,0
} {3.0}
test textDisp-13.6 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 30.50
    set x [.t index @0,0]
    .t configure -wrap none
    set x
} {27.0}
test textDisp-13.7 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.40
    update
    .t see 30.50
    .t yview 25.0
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.39
    lappend x [.t bbox 30.39]
    .t see 30.38
    lappend x [.t bbox 30.38]
    .t see 30.20
    lappend x [.t bbox 30.20]
} [list [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight]]
test textDisp-13.8 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    update
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
} [list [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight]]
test textDisp-13.9 {TkTextSeeCmd procedure} {textfonts} {
    wm geom . [expr $width-2]x$height
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    update
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
    toplevel .top2
    pack [text .top2.t2 -wrap none]
    for {set i 1} {$i < 5} {incr i} {
        .top2.t2 insert end [string repeat "Line $i: éèàçù" 5]\n

    }
    wm geometry .top2 300x200+0+0
    updateText
    .top2.t2 see "1.0 lineend"
    updateText
    set ref [.top2.t2 index @0,0]
    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    updateText
    set new [.top2.t2 index @0,0]
    set res [.top2.t2 compare $ref == $new]
    destroy .top2
    set res
} 0
wm geom . {}

.t configure -wrap none
test textDisp-14.1 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .5
    .t xview
} [list 0.5 [expr {6./7.}]]
.t configure -wrap char
test textDisp-14.2 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
.t configure -wrap none
test textDisp-14.3 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
test textDisp-14.4 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto} msg] $msg







|

|



|




|





|









|








|







1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
    toplevel .top2
    pack [text .top2.t2 -wrap none]
    for {set i 1} {$i < 5} {incr i} {
        .top2.t2 insert end [string repeat "Line $i: éèàçù" 5]\n

    }
    wm geometry .top2 300x200+0+0
    update
    .top2.t2 see "1.0 lineend"
    update
    set ref [.top2.t2 index @0,0]
    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    update
    set new [.top2.t2 index @0,0]
    set res [.top2.t2 compare $ref == $new]
    destroy .top2
    set res
} {0}
wm geom . {}

.t configure -wrap none
test textDisp-14.1 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .5
    .t xview
} [list 0.5 [expr {6./7.}]]
.t configure -wrap char
test textDisp-14.2 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
.t configure -wrap none
test textDisp-14.3 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
test textDisp-14.4 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto} msg] $msg
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview m 1.4
    .t xview
} [list [expr {9.0/14}] 1.0]
test textDisp-14.10 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.11 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.12 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll gorp units} msg] $msg
} {1 {expected floating-point number but got "gorp"}}
test textDisp-14.13 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 2 pa







|


|


|







1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview m 1.4
    .t xview
} [list [expr {9.0/14}] 1.0]
test textDisp-14.10 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number units|pages|pixels"}}
test textDisp-14.11 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number units|pages|pixels"}}
test textDisp-14.12 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll gorp units} msg] $msg
} {1 {expected integer but got "gorp"}}
test textDisp-14.13 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 2 pa
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
    .t xview scroll 100 units
    lappend x [.t index @0,22]
    .t xview scroll -15 units
    lappend x [.t index @0,22]
} {2.21 2.20 2.99 2.84}
test textDisp-14.15 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll 14 globs} msg] $msg
} {1 {bad argument "globs": must be pages, pixels, or units}}
test textDisp-14.16 {TkTextXviewCmd procedure} {
    list [catch {.t xview flounder} msg] $msg
} {1 {bad option "flounder": must be moveto or scroll}}

.t configure -wrap char
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"
}
.t insert end "Line 100"
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-15.1 {ScrollByLines procedure, scrolling backwards} {
    .t yview 45.0
    updateText
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-15.2 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {50.20}
test textDisp-15.3 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    .t yview scroll -4 units
    .t index @0,0
} {49.0}
test textDisp-15.4 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.20
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {49.0}
test textDisp-15.5 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.40
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {50.0}
test textDisp-15.6 {ScrollByLines procedure, scrolling backwards} {
    .t yview 3.2
    updateText
    .t yview scroll -5 units
    .t index @0,0
} {1.0}
test textDisp-15.7 {ScrollByLines procedure, scrolling forwards} {
    .t yview 48.0
    updateText
    .t yview scroll 4 units
    .t index @0,0
} {50.40}

test textDisp-15.8 {Scrolling near end of window} {
    set textheight 12
    set textwidth 30







|














|





|





|





|





|





|





|







1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
    .t xview scroll 100 units
    lappend x [.t index @0,22]
    .t xview scroll -15 units
    lappend x [.t index @0,22]
} {2.21 2.20 2.99 2.84}
test textDisp-14.15 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll 14 globs} msg] $msg
} {1 {bad argument "globs": must be units, pages, or pixels}}
test textDisp-14.16 {TkTextXviewCmd procedure} {
    list [catch {.t xview flounder} msg] $msg
} {1 {bad option "flounder": must be moveto or scroll}}

.t configure -wrap char
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"
}
.t insert end "Line 100"
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-15.1 {ScrollByLines procedure, scrolling backwards} {
    .t yview 45.0
    update
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-15.2 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.20}
test textDisp-15.3 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    update
    .t yview scroll -4 units
    .t index @0,0
} {49.0}
test textDisp-15.4 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.20
    update
    .t yview scroll -2 units
    .t index @0,0
} {49.0}
test textDisp-15.5 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.40
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.0}
test textDisp-15.6 {ScrollByLines procedure, scrolling backwards} {
    .t yview 3.2
    update
    .t yview scroll -5 units
    .t index @0,0
} {1.0}
test textDisp-15.7 {ScrollByLines procedure, scrolling forwards} {
    .t yview 48.0
    update
    .t yview scroll 4 units
    .t index @0,0
} {50.40}

test textDisp-15.8 {Scrolling near end of window} {
    set textheight 12
    set textwidth 30
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
    .tf.f.t tag configure Header -font {Helvetica 14 bold italic} \
      -wrap word -spacing1 12 -spacing3 4

    .tf.f.t insert end "Foo" Header
    for {set i 1} {$i < $textheight} {incr i} {
	.tf.f.t insert end "\nLine $i"
    }
    updateText
    set refind [.tf.f.t index @0,[winfo height .tf.f.t]]
    # Should scroll and should not crash!
    .tf.f.t yview scroll 1 unit
    # Check that it has scrolled
    set newind [.tf.f.t index @0,[winfo height .tf.f.t]]
    set res [.tf.f.t compare $newind > $refind]
    destroy .tf
    set res
} 1

.t configure -wrap char
.t delete 1.0 end
.t insert insert "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t tag add big 100.0 105.0
.t insert 151.end { has a lot of extra text, so that it wraps around on the screen several times over.}
.t insert 153.end { also has enoug extra text to wrap.}
updateText
.t count -update -ypixels 1.0 end
test textDisp-16.1 {TkTextYviewCmd procedure} {
    .t yview 21.0
    set x [.t yview]
    .t yview 1.0
    list [expr {int([lindex $x 0]*100)}] [expr {int ([lindex $x 1] * 100)}]
} {9 14}
test textDisp-16.2 {TkTextYviewCmd procedure} {
    list [catch {.t yview 2 3} msg] $msg
} {1 {bad option "2": must be moveto or scroll}}
test textDisp-16.3 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.4 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace 2 3} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.5 {TkTextYviewCmd procedure} {
    list [catch {.t yview -bogus 2} msg] $msg
} {1 {bad option "-bogus": must be moveto or scroll}}
test textDisp-16.6 {TkTextYviewCmd procedure, integer position} {
    .t yview 100.0
    updateText
    .t yview 98
    .t index @0,0
} {99.0}
test textDisp-16.7 {TkTextYviewCmd procedure} {
    .t yview 2.0
    .t yv -pickplace 13.0
    .t index @0,0







|
<



|
<


|










<
|




















|







1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975

1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
    .tf.f.t tag configure Header -font {Helvetica 14 bold italic} \
      -wrap word -spacing1 12 -spacing3 4

    .tf.f.t insert end "Foo" Header
    for {set i 1} {$i < $textheight} {incr i} {
	.tf.f.t insert end "\nLine $i"
    }
    update ; after 1000 ; update

    # Should scroll and should not crash!
    .tf.f.t yview scroll 1 unit
    # Check that it has scrolled
    set res [.tf.f.t index @0,[expr [winfo height .tf.f.t] - 15]]

    destroy .tf
    set res
} {12.0}

.t configure -wrap char
.t delete 1.0 end
.t insert insert "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t tag add big 100.0 105.0
.t insert 151.end { has a lot of extra text, so that it wraps around on the screen several times over.}
.t insert 153.end { also has enoug extra text to wrap.}

update ; .t count -update -ypixels 1.0 end
test textDisp-16.1 {TkTextYviewCmd procedure} {
    .t yview 21.0
    set x [.t yview]
    .t yview 1.0
    list [expr {int([lindex $x 0]*100)}] [expr {int ([lindex $x 1] * 100)}]
} {9 14}
test textDisp-16.2 {TkTextYviewCmd procedure} {
    list [catch {.t yview 2 3} msg] $msg
} {1 {bad option "2": must be moveto or scroll}}
test textDisp-16.3 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.4 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace 2 3} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.5 {TkTextYviewCmd procedure} {
    list [catch {.t yview -bogus 2} msg] $msg
} {1 {bad option "-bogus": must be moveto or scroll}}
test textDisp-16.6 {TkTextYviewCmd procedure, integer position} {
    .t yview 100.0
    update
    .t yview 98
    .t index @0,0
} {99.0}
test textDisp-16.7 {TkTextYviewCmd procedure} {
    .t yview 2.0
    .t yv -pickplace 13.0
    .t index @0,0
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {textfonts} {
    catch {destroy .top1}
    toplevel .top1
    wm geometry .top1 +0+0
    text .top1.t -height 3 -width 4 -wrap none -setgrid 1 -padx 6 \
	-spacing3 6
    pack .top1.t
    updateText
    .top1.t insert end "1\n2\n3\n4\n5\n6"
    .top1.t yview moveto 0.3333
    set result [.top1.t yview]
    destroy .top1
    set result
} [list [expr {1.0/3}] [expr {5.0/6}]]
test textDisp-16.19 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.20 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.21 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus bogus} msg] $msg
} {1 {bad argument "bogus": must be pages, pixels, or units}}
test textDisp-16.21.2 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus units} msg] $msg
} {1 {expected floating-point number but got "bogus"}}
test textDisp-16.22 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    .t yview scroll -1 pages
    .t index @0,0
} {42.0}
test textDisp-16.22.1 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    list [catch {.t yview scroll -3 p} res] $res
} {1 {ambiguous argument "p": must be pages, pixels, or units}}
test textDisp-16.23 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    .t yview scroll -3 pa
    .t index @0,0
} {26.0}
test textDisp-16.24 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 5.0
    updateText
    .t yview scroll -3 pa
    .t index @0,0
} {1.0}
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t configure -height 1
    updateText
    .t yview 50.0
    updateText
    .t yview scroll -1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    set x
} {49.0}
test textDisp-16.26 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    updateText
    .t yview scroll 1 pages
    .t index @0,0
} {58.0}
test textDisp-16.27 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    updateText
    .t yview scroll 2 pages
    .t index @0,0
} {66.0}
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {textfonts} {
    .t yview 98.0
    updateText
    .t yview scroll 1 page
    set res [expr {int([.t index @0,0])}]
    if {$fixedDiff > 1} {
	incr res -1
    }
    set res
} 102
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    updateText
    .t yview 50.0
    updateText
    .t yview scroll 1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    set x
} {51.0}
test textDisp-16.30 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 45.0
    updateText
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-16.31 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 149.0
    updateText
    .t yview scroll 4 units
    .t index @0,0
} {151.40}
test textDisp-16.32 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 12 bogoids} msg] $msg
} {1 {bad argument "bogoids": must be pages, pixels, or units}}
test textDisp-16.33 {TkTextYviewCmd procedure} {
    list [catch {.t yview bad_arg 1 2} msg] $msg
} {1 {bad option "bad_arg": must be moveto or scroll}}
test textDisp-16.34 {TkTextYviewCmd procedure} {
    set res {}
    .t yview 1.0
    lappend res [format %.12g [expr {[lindex [.t yview] 0]







|








|


|

|
|

|
|


|





|


|





|





|

|



|




|





|





|

|




|


|

|



|




|





|





|







2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {textfonts} {
    catch {destroy .top1}
    toplevel .top1
    wm geometry .top1 +0+0
    text .top1.t -height 3 -width 4 -wrap none -setgrid 1 -padx 6 \
	-spacing3 6
    pack .top1.t
    update
    .top1.t insert end "1\n2\n3\n4\n5\n6"
    .top1.t yview moveto 0.3333
    set result [.top1.t yview]
    destroy .top1
    set result
} [list [expr {1.0/3}] [expr {5.0/6}]]
test textDisp-16.19 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number units|pages|pixels"}}
test textDisp-16.20 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number units|pages|pixels"}}
test textDisp-16.21 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll badInt bogus} msg] $msg
} {1 {bad argument "bogus": must be units, pages, or pixels}}
test textDisp-16.21.2 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll badInt units} msg] $msg
} {1 {expected integer but got "badInt"}}
test textDisp-16.22 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    update
    .t yview scroll -1 pages
    .t index @0,0
} {42.0}
test textDisp-16.22.1 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    list [catch {.t yview scroll -3 p} res] $res
} {1 {ambiguous argument "p": must be units, pages, or pixels}}
test textDisp-16.23 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    update
    .t yview scroll -3 pa
    .t index @0,0
} {26.0}
test textDisp-16.24 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 5.0
    update
    .t yview scroll -3 pa
    .t index @0,0
} {1.0}
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t configure -height 1
    update
    .t yview 50.0
    update
    .t yview scroll -1 pages
    set x [.t index @0,0]
    .t configure -height 10
    update
    set x
} {49.0}
test textDisp-16.26 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    update
    .t yview scroll 1 pages
    .t index @0,0
} {58.0}
test textDisp-16.27 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    update
    .t yview scroll 2 pages
    .t index @0,0
} {66.0}
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {textfonts} {
    .t yview 98.0
    update
    .t yview scroll 1 page
    set res [expr int([.t index @0,0])]
    if {$fixedDiff > 1} {
	incr res -1
    }
    set res
} {102}
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    update
    .t yview 50.0
    update
    .t yview scroll 1 pages
    set x [.t index @0,0]
    .t configure -height 10
    update
    set x
} {51.0}
test textDisp-16.30 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 45.0
    update
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-16.31 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 149.0
    update
    .t yview scroll 4 units
    .t index @0,0
} {151.40}
test textDisp-16.32 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 12 bogoids} msg] $msg
} {1 {bad argument "bogoids": must be units, pages, or pixels}}
test textDisp-16.33 {TkTextYviewCmd procedure} {
    list [catch {.t yview bad_arg 1 2} msg] $msg
} {1 {bad option "bad_arg": must be moveto or scroll}}
test textDisp-16.34 {TkTextYviewCmd procedure} {
    set res {}
    .t yview 1.0
    lappend res [format %.12g [expr {[lindex [.t yview] 0]
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    updateText
    .t index @0,0
} {5.0}
test textDisp-16.43 {TkTextYviewCmd procedure with indices in elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll -15 units
    updateText
    .t index @0,0
} {5.0}
test textDisp-16.44 {TkTextYviewCmd procedure, scroll down, with elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    foreach x [list 0 1 2 3 4 5 6 7 8 9 0] {
      .t insert end "$x aaa1\n$x bbb2\n$x ccc3\n$x ddd4\n$x eee5\n$x fff6"
      .t insert end "$x 1111\n$x 2222\n$x 3333\n$x 4444\n$x 5555\n$x 6666" hidden
    }
    .t tag configure hidden -elide true ; # 5 hidden lines
    updateText
    .t see [expr {5 + [winfo height .t] / $fixedHeight + 1}].0
    updateText
    .t index @0,0
} {2.0}

.t delete 1.0 end
foreach i {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} {
    .t insert end "\nLine $i 11111 $i 22222 $i 33333 $i 44444 $i 55555"
    .t insert end " $i 66666 $i 77777 $i 88888 $i"







|













|










|
|
|







2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    update
    .t index @0,0
} {5.0}
test textDisp-16.43 {TkTextYviewCmd procedure with indices in elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll -15 units
    update
    .t index @0,0
} {5.0}
test textDisp-16.44 {TkTextYviewCmd procedure, scroll down, with elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    foreach x [list 0 1 2 3 4 5 6 7 8 9 0] {
      .t insert end "$x aaa1\n$x bbb2\n$x ccc3\n$x ddd4\n$x eee5\n$x fff6"
      .t insert end "$x 1111\n$x 2222\n$x 3333\n$x 4444\n$x 5555\n$x 6666" hidden
    }
    .t tag configure hidden -elide true ; # 5 hidden lines
    update
    .t see [expr {5 + [winfo height .t] / $fixedHeight} + 1].0
    update
    .t index @0,0
} {2.0}

.t delete 1.0 end
foreach i {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} {
    .t insert end "\nLine $i 11111 $i 22222 $i 33333 $i 44444 $i 55555"
    .t insert end " $i 66666 $i 77777 $i 88888 $i"
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503


2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {textfonts} {
    .t yview 10.0
    .t scan mark -10 60
    .t scan dragto -5 65
    set x [.t index @0,0]
    .t scan dragto 0 [expr {70 + $fixedDiff}]
    list $x [.t index @0,0]
} {9.0 8.0}
.t configure -xscrollcommand scroll -yscrollcommand {}
test textDisp-18.1 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-18.2 {GetXView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.3 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.4 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.5 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    .t xview scroll 31 units
    updateText
    set scrollInfo
} [list [expr {31.0/55}] [expr {51.0/55}]]
test textDisp-18.6 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 31 units
    updateText
    set x {}
    lappend x $scrollInfo
    .t configure -wrap char
    updateText
    lappend x $scrollInfo
    .t configure -wrap word
    updateText
    lappend x $scrollInfo
    .t configure -wrap none
    updateText
    lappend x $scrollInfo
} [list [list [expr {31.0/56}] [expr {51.0/56}]] {0.0 1.0} {0.0 1.0} [list 0.0 [expr {5.0/14}]]]
test textDisp-18.7 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo unchanged
    .t insert end xxxxxx\n
    .t insert end xxx
    updateText
    set scrollInfo
} {unchanged}
test textDisp-18.8 {GetXView procedure} {
    proc bgerror msg {
	global x errorInfo
	set x [list $msg $errorInfo]
    }
    proc bogus args {
	error "bogus scroll proc"
    }
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    updateText
    .t delete 1.0 end
    .t configure -xscrollcommand scrollError
    updateText
    set x
} {{scrolling error} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (horizontal scrolling command executed by text)}}
catch {rename bgerror {}}
catch {rename bogus {}}


.t configure -xscrollcommand {} -yscrollcommand scroll
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t insert 1.0 "Line1\nLine2"
    updateText
    set scrollInfo
} {unchanged}
test textDisp-19.3 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    set scrollInfo
} {unchanged}
test textDisp-19.4 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    updateText
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    set scrollInfo
} [list 0.0 [expr {70.0/91}]]
test textDisp-19.5 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    updateText
    set x $scrollInfo
} {0.0 0.625}
test textDisp-19.6 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 4.0
    updateText
    set x $scrollInfo
} {0.375 1.0}
test textDisp-19.7 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.26
    updateText
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 10.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.0
    updateText
    .t count -update -ypixels 1.0 end
    set x $scrollInfo
} {0.0625 0.6875}
test textDisp-19.9 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 3.0
    updateText
    set scrollInfo
} [list [expr {4.0/30}] 0.8]
test textDisp-19.10 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    updateText
    set scrollInfo
} [list [expr {1.0/3}] 1.0]
test textDisp-19.10.1 {Widget manipulation causes height miscount} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    updateText
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    updateText
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    updateText
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11.2 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.0 end
} 20
test textDisp-19.11.3 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines end 1.0
} -20
test textDisp-19.11.4 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.1 1.3
} 0
test textDisp-19.11.5 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.1
} 0
test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.5
} 0
test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.24
} 1
test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.40
} 2
test textDisp-19.11.8 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 displaylineend +1c" "16.0 lineend"
} 3
test textDisp-19.11.9 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 lineend"
} 4
test textDisp-19.11.10 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.11 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +2displaylines"
} 2
test textDisp-19.11.12 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 +1displayline" "16.0 +2displaylines -1c"
} 0
.t tag configure elide -elide 1
test textDisp-19.11.13 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines +6c"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.14 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines displaylineend"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.15 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines -1c"
} 3
test textDisp-19.11.15a {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.16 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    .t count -displaylines 12.0 16.0
} 2
test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {15.5 16.0 15.0 16.0 16.21 16.39}
test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "15.5 -2d lines"] \
      [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \
      [.t index "16.0 -3d lines"] [.t index "16.23 -4d lines"] \
      [.t index "16.42 -5d lines"]
} {11.5 14.0 11.0 11.0 11.2 11.3}
test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    .t count -displaylines 12.0 17.0
} 4
test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.44 16.57 16.39 16.57 16.74 17.0}
test textDisp-19.11.21 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "16.44 -2d lines"] \
      [.t index "16.57 -3d lines"] [.t index "16.39 -2d lines"] \
      [.t index "16.60 -4d lines"] [.t index "16.76 -4d lines"] \
      [.t index "17.0 -5d lines"]
} {11.5 11.0 11.0 10.3 11.2 11.0}
test textDisp-19.11.22 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    list [.t index "end +5d lines"] \
      [.t index "end -3d lines"] [.t index "1.0 -2d lines"] \
      [.t index "1.0 +4d lines"] [.t index "1.0 +50d lines"] \
      [.t index "end -50d lines"]
} {17.0 16.39 1.0 5.0 17.0 1.0}
test textDisp-19.11.23 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.3" "16.0 +1displaylines"
    list [.t index "11.5 +1d lines"] [.t index "11.5 +2d lines"] \
      [.t index "12.0 +1d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.23 16.44 16.39 16.57 16.39 16.60 16.77 16.79}
.t tag remove elide 1.0 end
test textDisp-19.11.24 {TextWidgetCmd procedure, "index +/-displaylines"} {
    list [.t index "11.5 + -1 display lines"] \
      [.t index "11.5 + +1 disp lines"] \
      [.t index "11.5 - -1 disp lines"] \
      [.t index "11.5 - +1 disp lines"] \
      [.t index "11.5 -1 disp lines"] \
      [.t index "11.5 +1 disp lines"] \
      [.t index "11.5 +0 disp lines"]
} {10.5 12.5 12.5 10.5 10.5 12.5 11.5}
.t tag remove elide 1.0 end
test textDisp-19.12 {GetYView procedure, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
    # Need to wait for asychronous calculations to complete.
    updateText
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
test textDisp-19.13 {GetYView procedure, partially visible last line} {textfonts} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4 has enough text to wrap around at least once"
    # Need to wait for asychronous calculations to complete.
    updateText
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
catch {destroy .top}
test textDisp-19.14 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t mark set insert 3.0
    .t tag configure x -background red
    .t tag add x 1.0 5.0
    updateText
    .t tag delete x
    set scrollInfo
} {unchanged}
test textDisp-19.15 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit little left on the last line."
    updateText
    .t configure -yscrollcommand scrollError
    proc bgerror args {
	global x errorInfo errorCode
	set x [list $args $errorInfo $errorCode]
    }
    .t delete 1.0 end
    updateText
    rename bgerror {}
    .t configure -yscrollcommand scroll
    set x
} {{{scrolling error}} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (vertical scrolling command executed by text)} NONE}

test textDisp-19.16 {count -ypixels} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set res {}
    lappend res \
      [.t count -ypixels 1.0 end] \
      [.t count -update -ypixels 1.0 end] \
      [.t count -ypixels 15.0 16.0] \
      [.t count -ypixels 15.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels 16.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels "16.0 +1 displaylines" "16.0 +4 displaylines +3c"]
} [list [expr {260 + 20 * $fixedDiff}] [expr {260 + 20 * $fixedDiff}] $fixedHeight [expr {2*$fixedHeight}] $fixedHeight [expr {3*$fixedHeight}]]
test textDisp-19.17 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15







|







|








|





|








|









|










|



|


|


|





|



|













|


|










>
>




|





|


|





|


|






|




|










|











|











|











|











|










|










|







|

|











|

|





|


|


|


|


|

|
|


|


|


|


|


|


|





|




|




|




|




|







|





|
|





|







|



|
|
|
|







|








|



















|

|
|










|

|
|











|

<
|
|




|











|
|






|



















|

<
|
<









|







2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754

2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802

2803

2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {textfonts} {
    .t yview 10.0
    .t scan mark -10 60
    .t scan dragto -5 65
    set x [.t index @0,0]
    .t scan dragto 0 [expr {70 + $fixedDiff}]
    list $x [.t index @0,0]
} {9.15 8.31}
.t configure -xscrollcommand scroll -yscrollcommand {}
test textDisp-18.1 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-18.2 {GetXView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.3 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.4 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.5 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    .t xview scroll 31 units
    update
    set scrollInfo
} [list [expr {31.0/55}] [expr {51.0/55}]]
test textDisp-18.6 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 31 units
    update
    set x {}
    lappend x $scrollInfo
    .t configure -wrap char
    update
    lappend x $scrollInfo
    .t configure -wrap word
    update
    lappend x $scrollInfo
    .t configure -wrap none
    update
    lappend x $scrollInfo
} [list [list [expr {31.0/56}] [expr {51.0/56}]] {0.0 1.0} {0.0 1.0} [list 0.0 [expr {5.0/14}]]]
test textDisp-18.7 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo unchanged
    .t insert end xxxxxx\n
    .t insert end xxx
    update
    set scrollInfo
} {unchanged}
test textDisp-18.8 {GetXView procedure} {
    proc bgerror msg {
	global x errorInfo
	set x [list $msg $errorInfo]
    }
    proc bogus args {
	error "bogus scroll proc"
    }
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    update
    .t delete 1.0 end
    .t configure -xscrollcommand scrollError
    update
    set x
} {{scrolling error} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (horizontal scrolling command executed by text)}}
catch {rename bgerror {}}
catch {rename bogus {}}
.t configure -xscrollcommand {} -yscrollcommand scroll

.t configure -xscrollcommand {} -yscrollcommand scroll
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line1\nLine2"
    update
    set scrollInfo
} {unchanged}
test textDisp-19.3 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update; after 10 ; update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    set scrollInfo
} {unchanged}
test textDisp-19.4 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    update
    set scrollInfo
} [list 0.0 [expr {70.0/91}]]
test textDisp-19.5 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    update ; after 100
    set x $scrollInfo
} {0.0 0.625}
test textDisp-19.6 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 4.0
    update
    set x $scrollInfo
} {0.375 1.0}
test textDisp-19.7 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.26
    update; after 1; update
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 10.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.0
    update
    .t count -update -ypixels 1.0 end
    set x $scrollInfo
} {0.0625 0.6875}
test textDisp-19.9 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 3.0
    update
    set scrollInfo
} [list [expr {4.0/30}] 0.8]
test textDisp-19.10 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    update
    set scrollInfo
} [list [expr {1.0/3}] 1.0]
test textDisp-19.10.1 {Widget manipulation causes height miscount} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    update
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit left on the last line."
    .t yview insert
    update
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit left on the last line."
    .t yview insert
    update
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11.2 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.0 end
} {20}
test textDisp-19.11.3 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines end 1.0
} {-20}
test textDisp-19.11.4 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.1 1.3
} {0}
test textDisp-19.11.5 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.1
} {0}
test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.5
} {0}
test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.20
} {1}
test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.40
} {2}
test textDisp-19.11.8 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 displaylineend +1c" "16.0 lineend"
} {3}
test textDisp-19.11.9 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 lineend"
} {4}
test textDisp-19.11.10 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.11 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +2displaylines"
} {2}
test textDisp-19.11.12 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 +1displayline" "16.0 +2displaylines -1c"
} {0}
.t tag configure elide -elide 1
test textDisp-19.11.13 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines +6c"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.14 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines displaylineend"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.15 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines -1c"
} {3}
test textDisp-19.11.15a {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.16 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    .t count -displaylines 12.0 16.0
} {2}
test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {15.5 16.0 15.0 16.0 16.15 16.33}
test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "15.5 -2d lines"] \
      [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \
      [.t index "16.0 -3d lines"] [.t index "16.17 -4d lines"] \
      [.t index "16.36 -5d lines"]
} {11.5 14.0 11.0 11.0 11.2 11.3}
test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    .t count -displaylines 12.0 17.0
} {4}
test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.38 16.50 16.33 16.50 16.67 17.0}
test textDisp-19.11.21 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "16.38 -2d lines"] \
      [.t index "16.50 -3d lines"] [.t index "16.33 -2d lines"] \
      [.t index "16.53 -4d lines"] [.t index "16.69 -4d lines"] \
      [.t index "17.1 -5d lines"]
} {11.5 11.0 11.0 10.3 11.2 11.0}
test textDisp-19.11.22 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    list [.t index "end +5d lines"] \
      [.t index "end -3d lines"] [.t index "1.0 -2d lines"] \
      [.t index "1.0 +4d lines"] [.t index "1.0 +50d lines"] \
      [.t index "end -50d lines"]
} {17.0 16.33 1.0 5.0 17.0 1.0}
test textDisp-19.11.23 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.3" "16.0 +1displaylines"
    list [.t index "11.5 +1d lines"] [.t index "11.5 +2d lines"] \
      [.t index "12.0 +1d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.17 16.33 16.28 16.46 16.28 16.49 16.65 16.72}
.t tag remove elide 1.0 end
test textDisp-19.11.24 {TextWidgetCmd procedure, "index +/-displaylines"} {
    list [.t index "11.5 + -1 display lines"] \
      [.t index "11.5 + +1 disp lines"] \
      [.t index "11.5 - -1 disp lines"] \
      [.t index "11.5 - +1 disp lines"] \
      [.t index "11.5 -1 disp lines"] \
      [.t index "11.5 +1 disp lines"] \
      [.t index "11.5 +0 disp lines"]
} {10.5 12.5 12.5 10.5 10.5 12.5 11.5}
.t tag remove elide 1.0 end
test textDisp-19.12 {GetYView procedure, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
    # Need to wait for asychronous calculations to complete.
    update ; after 10
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr $theight - 3]
    update
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
test textDisp-19.13 {GetYView procedure, partially visible last line} {textfonts} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4 has enough text to wrap around at least once"
    # Need to wait for asychronous calculations to complete.
    update ; after 10
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr $theight - 3]
    update
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
catch {destroy .top}
test textDisp-19.14 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit left on the last line."
    # Need to update so everything is calculated.

    update ; .t count -update -ypixels 1.0 end
    update ; after 10 ; update
    set scrollInfo "unchanged"
    .t mark set insert 3.0
    .t tag configure x -background red
    .t tag add x 1.0 5.0
    update
    .t tag delete x
    set scrollInfo
} {unchanged}
test textDisp-19.15 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit left on the last line."
    update
    .t configure -yscrollcommand scrollError
    proc bgerror args {
	global x errorInfo errorCode
	set x [list $args $errorInfo $errorCode]
    }
    .t delete 1.0 end
    update
    rename bgerror {}
    .t configure -yscrollcommand scroll
    set x
} {{{scrolling error}} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (vertical scrolling command executed by text)} NONE}

test textDisp-19.16 {count -ypixels} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit left on the last line."
    # Need to update so everything is calculated.

    update ; .t count -update -ypixels 1.0 end ; update

    set res {}
    lappend res \
      [.t count -ypixels 1.0 end] \
      [.t count -update -ypixels 1.0 end] \
      [.t count -ypixels 15.0 16.0] \
      [.t count -ypixels 15.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels 16.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels "16.0 +1 displaylines" "16.0 +4 displaylines +3c"]
} [list [expr {260 + 20 * $fixedDiff}] [expr {260 + 20 * $fixedDiff}] $fixedHeight [expr {2*$fixedHeight}] $fixedHeight [expr {3*$fixedHeight}]]
test textDisp-19.17 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
      [.t count -ypixels 5.0 25.0] \
      [.t count -ypixels 25.0 5.0] \
      [.t count -ypixels 25.4 27.50] \
      [.t count -ypixels 35.0 38.0]
    .t yview 35.0
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {4 * $fixedHeight}] [expr {3 * $fixedHeight}] 0 0 0 0 0 0 [expr {5 * $fixedHeight}] [expr {- 5 * $fixedHeight}] [expr {2 * $fixedHeight}] [expr {3 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.18 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    set res {}
    update
    lappend res [.t count -ypixels 5.0 25.0]
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    updateText
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {5 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.19 {count -ypixels with indices in elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 25} {incr i} {
        .t insert end [string repeat "Line $i -" 6]
        .t insert end "\n"
    }
    .t tag add hidden 5.27 11.0
    .t tag configure hidden -elide true
    .t yview 5.0
    updateText
    set res [list [.t count -ypixels 5.0 11.0] [.t count -ypixels 5.0 11.20]]
} [list [expr {1 * $fixedHeight}] [expr {2 * $fixedHeight}]]
.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-20.1 {FindDLine} failsOnUbuntu {
    .t yview 48.0
    list [.t dlineinfo 46.0] [.t dlineinfo 47.0] [.t dlineinfo 49.0] \
	    [.t dlineinfo 58.0]
} [list {} {} [list 3 [expr {$fixedDiff + 16}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.2 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview -pickplace 53.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21]
} [list [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
test textDisp-20.3 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 49.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 57.0]
} [list [list 3 [expr {$fixedDiff + 16}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.4 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 42.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 50.40]
} [list [list 3 [expr {8*$fixedDiff + 107}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
.t config -wrap none
test textDisp-20.5 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 48.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]

.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {textfonts} {
    .t yview 48.0
    list [.t index @-10,-10] [.t index @6,6] [.t index @22,6] \
	    [.t index @102,6] [.t index @38,[expr {$fixedHeight * 4 + 3}]] [.t index @44,67]
} {48.0 48.0 48.2 48.7 50.45 50.45}
.t insert end \n
test textDisp-21.2 {TkTextPixelIndex} {textfonts} {
    .t yview 195.0
    list [.t index @11,[expr {$fixedHeight * 5 + 5}]] [.t index @11,[expr {$fixedHeight * 6 + 5}]] [.t index @11,[expr {$fixedHeight * 7 + 5}]] \
	    [.t index @11,1002]
} {197.1 198.1 199.1 201.0}
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {textfonts} {







|













|












|










|




|


|
|
|


|
|
|


|
|

|










|







2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
      [.t count -ypixels 5.0 25.0] \
      [.t count -ypixels 25.0 5.0] \
      [.t count -ypixels 25.4 27.50] \
      [.t count -ypixels 35.0 38.0]
    .t yview 35.0
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {4 * $fixedHeight}] [expr {3 * $fixedHeight}] 0 0 0 0 0 0 [expr {5 * $fixedHeight}] [expr {- 5 * $fixedHeight}] [expr {2 * $fixedHeight}] [expr {3 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.18 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    set res {}
    update
    lappend res [.t count -ypixels 5.0 25.0]
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    update
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {5 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.19 {count -ypixels with indices in elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 25} {incr i} {
        .t insert end [string repeat "Line $i -" 6]
        .t insert end "\n"
    }
    .t tag add hidden 5.27 11.0
    .t tag configure hidden -elide true
    .t yview 5.0
    update
    set res [list [.t count -ypixels 5.0 11.0] [.t count -ypixels 5.0 11.20]]
} [list [expr {1 * $fixedHeight}] [expr {2 * $fixedHeight}]]
.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-20.1 {FindDLine} {textfonts} {
    .t yview 48.0
    list [.t dlineinfo 46.0] [.t dlineinfo 47.0] [.t dlineinfo 49.0] \
	    [.t dlineinfo 58.0]
} [list {} {} [list 3 [expr {$fixedDiff + 16}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.2 {FindDLine} {textfonts} {
    .t yview 100.0
    .t yview -pickplace 53.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.15]
} [list [list 3 [expr {-1 - $fixedDiff/2}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
test textDisp-20.3 {FindDLine} {textfonts} {
    .t yview 100.0
    .t yview 49.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 57.0]
} [list [list 3 [expr {$fixedDiff + 16}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.4 {FindDLine} {textfonts} {
    .t yview 100.0
    .t yview 42.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list 3 [expr {8*$fixedDiff + 107}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
.t config -wrap none
test textDisp-20.5 {FindDLine} {textfonts} {
    .t yview 100.0
    .t yview 48.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]

.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {textfonts} {
    .t yview 48.0
    list [.t index @-10,-10] [.t index @6,6] [.t index @22,6] \
	    [.t index @102,6] [.t index @38,[expr {$fixedHeight * 4 + 3}]] [.t index @44,67]
} {48.0 48.0 48.2 48.7 50.40 50.40}
.t insert end \n
test textDisp-21.2 {TkTextPixelIndex} {textfonts} {
    .t yview 195.0
    list [.t index @11,[expr {$fixedHeight * 5 + 5}]] [.t index @11,[expr {$fixedHeight * 6 + 5}]] [.t index @11,[expr {$fixedHeight * 7 + 5}]] \
	    [.t index @11,1002]
} {197.1 198.1 199.1 201.0}
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {textfonts} {
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
.tt.u insert end $message
.tt.u mark set insert 3.10
tkwait visibility .tt.u
set res [.tt.u count -displaylines 3.10 2.173]
destroy .tt
unset message
set res
} -1

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
updateText
.t tag add x 50.1
test textDisp-22.1 {TkTextCharBbox} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t bbox 47.2] [.t bbox 48.0] [.t bbox 50.5] [.t bbox 50.40] \
	    [.t bbox 58.0]
} [list {} [list 3 3 7 $fixedHeight] [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] [list 3 [expr {3+4*$fixedHeight}] 7 $fixedHeight] {}]
test textDisp-22.2 {TkTextCharBbox} {textfonts} {
    .t config -wrap none
    .t yview 48.0
    list [.t bbox 50.5] [.t bbox 50.40] [.t bbox 57.0]
} [list [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] {} [list 3 [expr {3+9*$fixedHeight}] 7 $fixedHeight]]
test textDisp-22.3 {TkTextCharBbox, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    updateText
    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 3]]
test textDisp-22.4 {TkTextCharBbox, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    updateText
    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 5]]
test textDisp-22.5 {TkTextCharBbox, cut-off char} {textfonts} {
    .t config -wrap none
    .t yview 10.0
    wm geom . [expr {$width-95}]x$height
    updateText
    .t bbox 15.6
} [list 45 [expr {3+5*$fixedHeight}] 7 $fixedHeight]
test textDisp-22.6 {TkTextCharBbox, line visible but not char} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 20.2 20.5
    wm geom . ${width}x[expr {$height+3}]
    updateText
    list [.t bbox 19.1] [.t bbox 20.1] [.t bbox 20.2]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] {} [list 17 [expr {3+10*$fixedHeight}] 14 7]]
wm geom . {}
updateText
test textDisp-22.7 {TkTextCharBbox, different character sizes} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 12.2 12.5
    updateText
    list [.t bbox 12.1] [.t bbox 12.2]
} [list [list 10 [expr {3 + 2*$fixedHeight + $ascentDiff}] 7 $fixedHeight] [list 17 [expr {3+ 2*$fixedHeight}] 14 27]]
.t tag remove big 1.0 end
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"







|









|






|








|
|





|
|





|
|






|
|



|




|







2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
.tt.u insert end $message
.tt.u mark set insert 3.10
tkwait visibility .tt.u
set res [.tt.u count -displaylines 3.10 2.173]
destroy .tt
unset message
set res
} {-1}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
update
.t tag add x 50.1
test textDisp-22.1 {TkTextCharBbox} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t bbox 47.2] [.t bbox 48.0] [.t bbox 50.5] [.t bbox 50.40] \
	    [.t bbox 58.0]
} [list {} [list 3 3 7 $fixedHeight] [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] [list 38 [expr {3+4*$fixedHeight}] 7 $fixedHeight] {}]
test textDisp-22.2 {TkTextCharBbox} {textfonts} {
    .t config -wrap none
    .t yview 48.0
    list [.t bbox 50.5] [.t bbox 50.40] [.t bbox 57.0]
} [list [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] {} [list 3 [expr {3+9*$fixedHeight}] 7 $fixedHeight]]
test textDisp-22.3 {TkTextCharBbox, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr $height-1]
    update
    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 3]]
test textDisp-22.4 {TkTextCharBbox, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr $height+1]
    update
    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 5]]
test textDisp-22.5 {TkTextCharBbox, cut-off char} {textfonts} {
    .t config -wrap none
    .t yview 10.0
    wm geom . [expr $width-95]x$height
    update
    .t bbox 15.6
} [list 45 [expr {3+5*$fixedHeight}] 7 $fixedHeight]
test textDisp-22.6 {TkTextCharBbox, line visible but not char} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 20.2 20.5
    wm geom . ${width}x[expr $height+3]
    update
    list [.t bbox 19.1] [.t bbox 20.1] [.t bbox 20.2]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] {} [list 17 [expr {3+10*$fixedHeight}] 14 7]]
wm geom . {}
update
test textDisp-22.7 {TkTextCharBbox, different character sizes} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 12.2 12.5
    update
    list [.t bbox 12.1] [.t bbox 12.2]
} [list [list 10 [expr {3 + 2*$fixedHeight + $ascentDiff}] 7 $fixedHeight] [list 17 [expr {3+ 2*$fixedHeight}] 14 27]]
.t tag remove big 1.0 end
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    updateText
    list [.t bbox .t.f1] [.t bbox .t.f2] [.t bbox .t.f3] [.t bbox .t.f4] \
	    [.t bbox 1.1] [.t bbox 2.9]
} [list [list 24 11 10 4] [list 55 [expr {$fixedDiff/2 + 15}] 10 4] [list 10 [expr {2*$fixedDiff + 43}] 10 4] [list 76 [expr {2*$fixedDiff + 40}] 10 4] [list 10 11 7 $fixedHeight] [list 69 [expr {$fixedDiff + 34}] 7 $fixedHeight]]
.t tag delete spacing
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.13
    .t tag add hidden 6.8 7.13
    .t tag configure hidden -elide true
    updateText
    list \
        [expr {[lindex [.t bbox 2.9]  0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.10] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.13] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 6.9]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.10] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.13] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.14] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.15] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.0]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.1]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.12] 0] - [lindex [.t bbox 6.8] 0]}]
} [list 0 0 0 0 0 0 0 0 0 0 0]
test textDisp-22.11 {TkTextCharBbox, handling of wrapped elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line _$i - Lines .$i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 1.30 2.5
    .t tag configure hidden -elide true
    updateText
    list \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.4]  0]}] \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.5]  0]}]
} [list 0 0]

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
updateText
test textDisp-23.1 {TkTextDLineInfo} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t dlineinfo 47.3] [.t dlineinfo 48.0] [.t dlineinfo 50.40] \
	    [.t dlineinfo 56.0]
} [list {} [list 3 3 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {4*$fixedDiff + 55}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-23.2 {TkTextDLineInfo} {textfonts} {
    .t config -bd 4 -wrap word
    updateText
    .t yview 48.0
    .t dlineinfo 50.40
} [list 7 [expr {4*$fixedDiff + 59}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]
.t config -bd 0
test textDisp-23.3 {TkTextDLineInfo} {textfonts} {
    .t config -wrap none
    updateText
    .t yview 48.0
    list [.t dlineinfo 50.40] [.t dlineinfo 57.3]
} [list [list 3 [expr {2*$fixedDiff + 29}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
test textDisp-23.4 {TkTextDLineInfo, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    updateText
    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 3 [expr {$fixedDiff + 10}]]]
test textDisp-23.5 {TkTextDLineInfo, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    updateText
    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 5 [expr {$fixedDiff + 10}]]]
wm geom . {}
updateText
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {textfonts} {
    .t config -wrap none
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t xview scroll 6 units
    updateText
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list -39 3 70 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {$fixedDiff + 16}] 364 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {2*$fixedDiff + 29}] 35 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
.t xview moveto 0
test textDisp-23.7 {TkTextDLineInfo, centering} {textfonts} {
    .t config -wrap word
    .t delete 1.0 end
    .t insert end "First line\n"







|








|




|

















|



|













|





|


|


|



|






|
|





|
|



|







|







3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    update
    list [.t bbox .t.f1] [.t bbox .t.f2] [.t bbox .t.f3] [.t bbox .t.f4] \
	    [.t bbox 1.1] [.t bbox 2.9]
} [list [list 24 11 10 4] [list 55 [expr {$fixedDiff/2 + 15}] 10 4] [list 10 [expr {2*$fixedDiff + 43}] 10 4] [list 76 [expr {2*$fixedDiff + 40}] 10 4] [list 10 11 7 $fixedHeight] [list 69 [expr {$fixedDiff + 34}] 7 $fixedHeight]]
.t tag delete spacing
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line [format %c [expr 64+$i]]\n"
    }
    .t tag add hidden 2.8 2.13
    .t tag add hidden 6.8 7.13
    .t tag configure hidden -elide true
    update
    list \
        [expr {[lindex [.t bbox 2.9]  0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.10] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.13] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 6.9]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.10] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.13] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.14] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.15] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.0]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.1]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.12] 0] - [lindex [.t bbox 6.8] 0]}]
} [list 0 0 0 0 0 0 0 0 0 0 0]
test textDisp-22.11 {TkTextCharBbox, handling of wrapped elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line _$i - Lines .$i - Line [format %c [expr 64+$i]]\n"
    }
    .t tag add hidden 1.30 2.5
    .t tag configure hidden -elide true
    update
    list \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.4]  0]}] \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.5]  0]}]
} [list 0 0]

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
update
test textDisp-23.1 {TkTextDLineInfo} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t dlineinfo 47.3] [.t dlineinfo 48.0] [.t dlineinfo 50.40] \
	    [.t dlineinfo 56.0]
} [list {} [list 3 3 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {4*$fixedDiff + 55}] 126 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-23.2 {TkTextDLineInfo} {textfonts} {
    .t config -bd 4 -wrap word
    update
    .t yview 48.0
    .t dlineinfo 50.40
} [list 7 [expr {4*$fixedDiff + 59}] 126 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]
.t config -bd 0
test textDisp-23.3 {TkTextDLineInfo} {textfonts} {
    .t config -wrap none
    update
    .t yview 48.0
    list [.t dlineinfo 50.40] [.t dlineinfo 57.3]
} [list [list 3 [expr {2*$fixedDiff + 29}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
test textDisp-23.4 {TkTextDLineInfo, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr $height-1]
    update
    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 3 [expr {$fixedDiff + 10}]]]
test textDisp-23.5 {TkTextDLineInfo, cut-off lines} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr $height+1]
    update
    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 5 [expr {$fixedDiff + 10}]]]
wm geom . {}
update
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {textfonts} {
    .t config -wrap none
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t xview scroll 6 units
    update
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list -39 3 70 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {$fixedDiff + 16}] 364 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {2*$fixedDiff + 29}] 35 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
.t xview moveto 0
test textDisp-23.7 {TkTextDLineInfo, centering} {textfonts} {
    .t config -wrap word
    .t delete 1.0 end
    .t insert end "First line\n"
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.2 {TkTextCharLayoutProc} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width+1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.3 {TkTextCharLayoutProc} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 01234567890123456789\n012345678901234567890
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20] [.t bbox 2.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 0 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
test textDisp-24.5 {TkTextCharLayoutProc, char doesn't fit, newline not visible} {unix textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 0\n1\n
    wm geom . 110x$height
    updateText
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 2.0]
} [list [list 3 3 4 $fixedHeight] [list 7 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 4 $fixedHeight]]
test textDisp-24.6 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.7 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width+1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-6}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 5 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-7}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 4 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.11 {TkTextCharLayoutProc, line ends with space that doesn't quite fit} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "01234567890123456789 \nabcdefg"
    wm geom . [expr {$width-2}]x$height
    updateText
    set result {}
    lappend result [.t bbox 1.21] [.t bbox 2.0]
    .t mark set insert 1.21
    lappend result [.t bbox 1.21] [.t bbox 2.0]
} [list [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.12 {TkTextCharLayoutProc, tab causes wrap} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghi"
    .t mark set insert 1.4
    .t insert insert \t\t\t
    list [.t bbox {insert -1c}] [.t bbox insert]
} [list [list 115 3 30 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width+1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 5 $fixedHeight]]
test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 3 $fixedHeight]]
test textDisp-24.16 {TkTextCharLayoutProc, no chars fit} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . 103x$height
    updateText
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list 3 3 1 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 1 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 1 $fixedHeight]]
if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.15] [.t bbox 1.16] [.t bbox 1.17]
} [list [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16]
} [list [list 101 3 7 $fixedHeight] [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight]]
test textDisp-24.20 {TkTextCharLayoutProc, vertical offset} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    set result {}
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure up -offset 6
    .t tag add up 2.1
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure  up -offset -2
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag delete up
    set result
} [list [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 19}] [expr {$fixedDiff + 16}]] [list 10 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 15}] [expr {$fixedDiff + 10}]]]
.t configure -width 30
updateText
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text xxxxxxx yyyyy zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    frame .t.f -width 30 -height 20 -bg black
    .t window create 1.36 -window .t.f
    .t bbox 1.26







|
|






|
|







|







|







|






|
|






|
|






|
|






|
|






|
|


















|






|
|






|
|










|










|





|

|
|
|





|

















|







3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.2 {TkTextCharLayoutProc} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr $width+1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.3 {TkTextCharLayoutProc} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr $width-1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 01234567890123456789\n012345678901234567890
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20] [.t bbox 2.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 0 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
test textDisp-24.5 {TkTextCharLayoutProc, char doesn't fit, newline not visible} {unix textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 0\n1\n
    wm geom . 110x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 2.0]
} [list [list 3 3 4 $fixedHeight] [list 7 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 4 $fixedHeight]]
test textDisp-24.6 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.7 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr $width+1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr $width-1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr $width-6]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 5 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr $width-7]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 4 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.11 {TkTextCharLayoutProc, line ends with space that doesn't quite fit} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "01234567890123456789 \nabcdefg"
    wm geom . [expr $width-2]x$height
    update
    set result {}
    lappend result [.t bbox 1.21] [.t bbox 2.0]
    .t mark set insert 1.21
    lappend result [.t bbox 1.21] [.t bbox 2.0]
} [list [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.12 {TkTextCharLayoutProc, tab causes wrap} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghi"
    .t mark set insert 1.4
    .t insert insert \t\t\t
    list [.t bbox {insert -1c}] [.t bbox insert]
} [list [list 115 3 30 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr $width+1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 5 $fixedHeight]]
test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr $width-1]x$height
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 3 $fixedHeight]]
test textDisp-24.16 {TkTextCharLayoutProc, no chars fit} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . 103x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list 3 3 1 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 1 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 1 $fixedHeight]]
if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xThis is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16]
} [list [list 101 3 7 $fixedHeight] [list 108 3 35 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16]
} [list [list 101 3 7 $fixedHeight] [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight]]
test textDisp-24.20 {TkTextCharLayoutProc, vertical offset} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    set result {}
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure up -offset 6
    .t tag add up 2.1
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure  up -offset -2
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag delete up
    set result
} [list [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 19}] [expr {$fixedDiff + 16}]] [list 10 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 15}] [expr {$fixedDiff + 10}]]]
.t configure -width 30
update
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text xxxxxxx yyyyy zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    frame .t.f -width 30 -height 20 -bg black
    .t window create 1.36 -window .t.f
    .t bbox 1.26
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
    .t insert end "zzzzzzz qqqqq rrrr ssss tt"
    .t window create end -window .t.f
    .t insert end "u vvvvv"
    .t bbox .t.f
} [list 3 [expr {2*$fixedDiff + 29}] 30 20]
catch {destroy .t.f}
.t configure -width 20
updateText
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts failsOnXQuarz} -setup {
    text .tt -tabs {40 right} -wrap none -font $fixedFont
    pack .tt
} -body {
    .tt insert end \t9\n\t99\n\t999
    updateText
    list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]
} -cleanup {
    destroy .tt
} -result [list [list 38 5 7 $fixedHeight] [list 38 20 7 $fixedHeight] [list 38 35 7 $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
    -tabs 100
updateText
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh
    list [.t bbox 1.3] [.t bbox 1.5] [.t bbox 1.6]
} [list [list 21 1 79 $fixedHeight] [list 107 1 93 $fixedHeight] [list 200 1 7 $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
	-tabs {}
updateText
test textDisp-26.1 {AdjustForTab procedure, no tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
	    [lindex [.t bbox 1.14] 0]
} [list 56 126 168]
test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {textfonts} {







|







<
<
<
<
<
<
<
<
<
<



|








|







3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356










3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
    .t insert end "zzzzzzz qqqqq rrrr ssss tt"
    .t window create end -window .t.f
    .t insert end "u vvvvv"
    .t bbox .t.f
} [list 3 [expr {2*$fixedDiff + 29}] 30 20]
catch {destroy .t.f}
.t configure -width 20
update
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]











.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
    -tabs 100
update
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh
    list [.t bbox 1.3] [.t bbox 1.5] [.t bbox 1.6]
} [list [list 21 1 79 $fixedHeight] [list 107 1 93 $fixedHeight] [list 200 1 7 $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
	-tabs {}
update
test textDisp-26.1 {AdjustForTab procedure, no tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
	    [lindex [.t bbox 1.14] 0]
} [list 56 126 168]
test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {textfonts} {
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
test textDisp-26.3 {AdjustForTab procedure, not enough tabs specified} {
    .t delete 1.0 end
    .t insert 1.0 a\tb\tc\td\te
    .t tag delete x
    .t tag configure x -tabs {40 70 right}
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] \
	    [expr {[lindex [.t bbox 1.4] 0] + [lindex [.t bbox 1.4] 2]}] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]}] \
	    [expr {[lindex [.t bbox 1.8] 0] + [lindex [.t bbox 1.8] 2]}]
} [list 40 70 100 130]
test textDisp-26.4 {AdjustForTab procedure, different alignments} {
    .t delete 1.0 end
    .t insert 1.0 a\tbc\tde\tfg\thi
    .t tag delete x
    .t tag configure x -tabs {40 center 80 left 130 right}
    .t tag add x 1.0 end







|
|
|







3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
test textDisp-26.3 {AdjustForTab procedure, not enough tabs specified} {
    .t delete 1.0 end
    .t insert 1.0 a\tb\tc\td\te
    .t tag delete x
    .t tag configure x -tabs {40 70 right}
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] \
	    [expr [lindex [.t bbox 1.4] 0] + [lindex [.t bbox 1.4] 2]] \
	    [expr [lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]] \
	    [expr [lindex [.t bbox 1.8] 0] + [lindex [.t bbox 1.8] 2]]
} [list 40 70 100 130]
test textDisp-26.4 {AdjustForTab procedure, different alignments} {
    .t delete 1.0 end
    .t insert 1.0 a\tbc\tde\tfg\thi
    .t tag delete x
    .t tag configure x -tabs {40 center 80 left 130 right}
    .t tag add x 1.0 end
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
    .t insert 1.0 a\t1.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} 120
test textDisp-26.6 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1,456.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.7] 0
} 120
test textDisp-26.7 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.456.234,7
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.11] 0
} 120
test textDisp-26.8 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\ttest
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} 120
test textDisp-26.9 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} 120
test textDisp-26.10 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} 120
test textDisp-26.11 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tx=1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    lindex [.t bbox 1.5] 0
} 120
test textDisp-26.12 {AdjustForTab procedure, adjusting chunks} {
    .t delete 1.0 end
    .t insert 1.0 a\tx1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    button .b -text "="
    .t window create 1.3 -window .b
    updateText
    lindex [.t bbox 1.5] 0
} 120
test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    .t tag configure x -tabs {10 30 center 50 right 120}
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \







|








|








|








|








|








|









|










|

|







3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
    .t insert 1.0 a\t1.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
test textDisp-26.6 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1,456.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.7] 0
} {120}
test textDisp-26.7 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.456.234,7
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.11] 0
} {120}
test textDisp-26.8 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\ttest
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
test textDisp-26.9 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
test textDisp-26.10 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
test textDisp-26.11 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tx=1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    lindex [.t bbox 1.5] 0
} {120}
test textDisp-26.12 {AdjustForTab procedure, adjusting chunks} {
    .t delete 1.0 end
    .t insert 1.0 a\tx1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    button .b -text "="
    .t window create 1.3 -window .b
    update
    lindex [.t bbox 1.5] 0
} {120}
test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    .t tag configure x -tabs {10 30 center 50 right 120}
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
      [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]]
    .t configure -tabstyle tabular
    set res
} [list 112 56 112 56]

.t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \
	-wrap char
updateText
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]
} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 130 5 7 $fixedHeight]]
test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end







|







3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
      [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]]
    .t configure -tabstyle tabular
    set res
} [list 112 56 112 56]

.t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \
	-wrap char
update
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]
} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 130 5 7 $fixedHeight]]
test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {150 center}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 32 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 39 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
    .t delete 1.0 end
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    updateText
    set res [.t bbox 2.23]
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list -28 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    updateText
    set res [.t bbox 2.23]
    .t configure -tabstyle tabular
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.2 {SizeOfTab procedure, fractional tab interpolation problem} {
    .t delete 1.0 end
    set interpolatetab {1c 2c}
    set precisetab {}
    for {set i 1} {$i < 20} {incr i} {
	lappend precisetab "${i}c"
    }
    .t configure -tabs $interpolatetab -wrap none -width 150
    .t insert 1.0 [string repeat "a\t" 20]
    updateText
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    updateText
    expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
} 0

.t configure -wrap char -tabs {} -width 20
updateText
test textDisp-27.8 {SizeOfTab procedure, right alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {100 left 140 right}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 137 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.9 {SizeOfTab procedure, left alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.10 {SizeOfTab procedure, numeric alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t123.4
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 117 5 27 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.5] [.t bbox 1.6]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
test textDisp-28.1 {"yview" option with bizarre scroll command} {
    catch {destroy .t2}
    toplevel .t2
    text .t2.t -width 40 -height 4
    .t2.t insert end "1\n2\n3\n4\n5\n6\n7\n8\n"
    pack .t2.t
    wm geometry .t2 +0+0
    updateText
    .t2.t configure -yscrollcommand bizarre_scroll
    .t2.t yview 100.0
    set result [.t2.t index @0,0]
    updateText
    lappend result [.t2.t index @0,0]
} {6.0 1.0}

test textDisp-29.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list 0.0 [expr {20.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 1 unit
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {1.0*$fixedWidth/300}] [expr {21.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - $fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - $fixedWidth}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap none -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 1\n
    .t2.t insert end [string repeat "abc" 30]
    updateText
    .t2.t xview scroll 5 unit
    updateText
    .t2.t xview
} [list [expr {5.0/90}] [expr {25.0/90}]]
test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 2 unit
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {2.0*$fixedWidth/300}] [expr {22.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - 2*$fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 7 pixels
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {7.0/300}] [expr {(20.0*$fixedWidth + 7)/300}]] 300x50+[expr {$twbw + $twht + 1 - 7}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - 7}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 17 pixels
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {17.0/300}] [expr {(20.0*$fixedWidth + 17)/300}]] 300x50+[expr {$twbw + $twht + 1 - 17}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.5 {miscellaneous: can show last character} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 121x141+200+200
    text .t2.t -width 5 -height 5 -font {Arial 10} \
      -wrap none -xscrollcommand ".t2.s set" \
      -bd 2 -highlightthickness 0 -padx 1
    .t2.t insert end "WWWWWWWWWWWWi"
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    grid .t2.t -row 0 -column 0 -sticky nsew
    grid .t2.s -row 1 -column 0 -sticky ew
    grid columnconfigure .t2 0 -weight 1
    grid rowconfigure .t2 0 -weight 1
    grid rowconfigure .t2 1 -weight 0
    updateText
    set xv [.t2.t xview]
    set xd [expr {[lindex $xv 1] - [lindex $xv 0]}]
    .t2.t xview moveto [expr {1.0-$xd}]
    set iWidth [lindex [.t2.t bbox end-2c] 2]
    .t2.t xview scroll 2 units
    set iWidth2 [lindex [.t2.t bbox end-2c] 2]








|














|




















|














|




|

|


|












|















|














|



|















|














|

|













|

|














|

|














|

|














|

|
















|







3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {150 center}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 32 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 39 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts failsOnQuarz} {
    .t delete 1.0 end
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    update
    set res [.t bbox 2.23]
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list -28 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    update
    set res [.t bbox 2.23]
    .t configure -tabstyle tabular
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.2 {SizeOfTab procedure, fractional tab interpolation problem} {
    .t delete 1.0 end
    set interpolatetab {1c 2c}
    set precisetab {}
    for {set i 1} {$i < 20} {incr i} {
	lappend precisetab "${i}c"
    }
    .t configure -tabs $interpolatetab -wrap none -width 150
    .t insert 1.0 [string repeat "a\t" 20]
    update
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    update
    expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
} {0}

.t configure -wrap char -tabs {} -width 20
update
test textDisp-27.8 {SizeOfTab procedure, right alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {100 left 140 right}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 137 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.9 {SizeOfTab procedure, left alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {120}
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.10 {SizeOfTab procedure, numeric alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t123.4
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 117 5 27 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs {120}
    .t tag add x 1.0 end
    list [.t bbox 1.5] [.t bbox 1.6]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
test textDisp-28.1 {"yview" option with bizarre scroll command} {
    catch {destroy .t2}
    toplevel .t2
    text .t2.t -width 40 -height 4
    .t2.t insert end "1\n2\n3\n4\n5\n6\n7\n8\n"
    pack .t2.t
    wm geometry .t2 +0+0
    update
    .t2.t configure -yscrollcommand bizarre_scroll
    .t2.t yview 100.0
    set result [.t2.t index @0,0]
    update
    lappend result [.t2.t index @0,0]
} {6.0 1.0}

test textDisp-29.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list 0.0 [expr {20.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 1 unit
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {1.0*$fixedWidth/300}] [expr {21.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - $fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - $fixedWidth}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap none -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 1\n
    .t2.t insert end [string repeat "abc" 30]
    update
    .t2.t xview scroll 5 unit
    update
    .t2.t xview
} [list [expr {5.0/90}] [expr {25.0/90}]]
test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 2 unit
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {2.0*$fixedWidth/300}] [expr {22.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - 2*$fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 7 pixels
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {7.0/300}] [expr {(20.0*$fixedWidth + 7)/300}]] 300x50+[expr {$twbw + $twht + 1 - 7}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - 7}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 17 pixels
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {17.0/300}] [expr {(20.0*$fixedWidth + 17)/300}]] 300x50+[expr {$twbw + $twht + 1 - 17}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.5 {miscellaneous: can show last character} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 121x141+200+200
    text .t2.t -width 5 -height 5 -font {Arial 10} \
      -wrap none -xscrollcommand ".t2.s set" \
      -bd 2 -highlightthickness 0 -padx 1
    .t2.t insert end "WWWWWWWWWWWWi"
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    grid .t2.t -row 0 -column 0 -sticky nsew
    grid .t2.s -row 1 -column 0 -sticky ew
    grid columnconfigure .t2 0 -weight 1
    grid rowconfigure .t2 0 -weight 1
    grid rowconfigure .t2 1 -weight 0
    update ; update
    set xv [.t2.t xview]
    set xd [expr {[lindex $xv 1] - [lindex $xv 0]}]
    .t2.t xview moveto [expr {1.0-$xd}]
    set iWidth [lindex [.t2.t bbox end-2c] 2]
    .t2.t xview scroll 2 units
    set iWidth2 [lindex [.t2.t bbox end-2c] 2]

3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 200 units
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {16.0/30}] 1.0] 300x50+-155+[expr {$fixedDiff + 18}] {}]
test textDisp-30.1 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 3.2
    .t2.t count -displaylines 1.0 end
} 1
test textDisp-30.2 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 2.2
    .t2.t count -displaylines 1.0 end
} 2
catch {destroy .t2}

.t configure -height 1
updateText

test textDisp-31.1 {line embedded window height update} failsOnUbuntu {
    set res {}
    .t delete 1.0 end
    .t insert end "abcd\nefgh\nijkl\nmnop\nqrst\nuvwx\nyx"
    frame .t.f -background red -width 100 -height 100
    .t window create 3.0 -window .t.f
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.2 {line update index shifting} failsOnUbuntu {
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 100







|

|








|






|



|

















|







3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 200 units
    update
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {16.0/30}] 1.0] 300x50+-155+[expr {$fixedDiff + 18}] {}]
test textDisp-30.1 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 3.2
    .t2.t count -displaylines 1.0 end
} {1}
test textDisp-30.2 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 2.2
    .t2.t count -displaylines 1.0 end
} {2}
catch {destroy .t2}

.t configure -height 1
update

test textDisp-31.1 {line embedded window height update} failsOnUbuntu {
    set res {}
    .t delete 1.0 end
    .t insert end "abcd\nefgh\nijkl\nmnop\nqrst\nuvwx\nyx"
    frame .t.f -background red -width 100 -height 100
    .t window create 3.0 -window .t.f
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.2 {line update index shifting} failsOnUbuntu {
    set res {}
    .t.f configure -height 100
    update
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 100
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.4 {line embedded image height update} {
    set res {}
    image create photo textest -height 100 -width 10
    .t delete 3.0
    .t image create 3.0 -image textest
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.5 {line update index shifting} failsOnUbuntu {
    set res {}
    textest configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 100







|





|




|









|










|







3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    .t.f configure -height 100
    update
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.4 {line embedded image height update} {
    set res {}
    image create photo textest -height 100 -width 10
    .t delete 3.0
    .t image create 3.0 -image textest
    update
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.5 {line update index shifting} failsOnUbuntu {
    set res {}
    textest configure -height 100
    update ; after 1000 ; update
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 100
4024
4025
4026
4027
4028
4029
4030

4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    textest configure -height 100

    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    textest configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.7 {line update index shifting, elided} {
    # The 'update' and 'delay' must be long enough to ensure all
    # asynchronous updates have been performed.
    set res {}
    .t delete 1.0 end
    lappend res [.t count -update -ypixels 1.0 end]
    .t insert 1.0 "abc\nabc"
    .t insert 1.0 "abc\n"
    lappend res [.t count -update -ypixels 1.0 end]
    .t tag configure elide -elide 1
    .t tag add elide 1.3 2.1
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {$fixedHeight * 1}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 2}] [expr {$fixedHeight * 1}] [expr {$fixedHeight * 1}]]

test textDisp-32.0 {everything elided} {
    # Must not crash
    pack [text .tt]
    .tt insert 0.0 HELLO
    .tt tag configure HIDE -elide 1
    .tt tag add HIDE 0.0 end
    updateText
    destroy .tt
} {}
test textDisp-32.1 {everything elided} {
    # Must not crash
    pack [text .tt]
    updateText
    .tt insert 0.0 HELLO
    updateText
    .tt tag configure HIDE -elide 1
    updateText
    .tt tag add HIDE 0.0 end
    updateText
    destroy .tt
} {}
test textDisp-32.2 {elide and tags} {
    pack [text .tt -height 30 -width 100 -bd 0 \
      -highlightthickness 0 -padx 0]
    .tt insert end \
      {test text using tags 1 and 3 } \
      {testtag1 testtag3} \
      {[this bit here uses tags 2 and 3]} \
      {testtag2 testtag3}
    updateText
    # indent left margin of tag 1 by 20 pixels
    # text should be indented
    .tt tag configure testtag1 -lmargin1 20
    updateText
    #1
    set res {}
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should not be indented, since
    # the indented tag and character is hidden.
    .tt tag configure testtag1 -elide 1
    updateText
    #2
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag1 -lmargin1 0
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 2 by 20 pixels
    # text should not be indented, since tag1 has lmargin1 of 0.
    .tt tag configure testtag2 -lmargin1 20
    updateText
    #3
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should now be indented, but
    # the bbox of 1.0 should have zero width and zero indent,
    # since it is elided at that position.
    .tt tag configure testtag1 -elide 1
    updateText
    #4
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag2 -lmargin1 {}
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 3 by 20 pixels
    # text should be indented, since this tag takes
    # precedence over testtag1, and is applied to the
    # start of the text.
    .tt tag configure testtag3 -lmargin1 20
    updateText
    #5
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should still be indented,
    # since it still has testtag3 on it.  Again the
    # bbox of 1.0 should have 0.
    .tt tag configure testtag1 -elide 1
    updateText
    #6
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    .tt tag configure testtag3 -lmargin1 {} -elide 0
    .tt tag configure testtag1 -elide 1 -lmargin1 20
    #7







>





|




|
















|



|










|





|

|

|

|










|


|
<







|
<









|
<







|
<











|
<







|
<







3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030

4031
4032
4033
4034
4035
4036
4037
4038

4039
4040
4041
4042
4043
4044
4045
4046
4047
4048

4049
4050
4051
4052
4053
4054
4055
4056

4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068

4069
4070
4071
4072
4073
4074
4075
4076

4077
4078
4079
4080
4081
4082
4083
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    textest configure -height 100
    update ; after 1000 ; update
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    textest configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.7 {line update index shifting, elided} {
    # The 'update' and 'delay' must be long enough to ensure all
    # asynchronous updates have been performed.
    set res {}
    .t delete 1.0 end
    lappend res [.t count -update -ypixels 1.0 end]
    .t insert 1.0 "abc\nabc"
    .t insert 1.0 "abc\n"
    lappend res [.t count -update -ypixels 1.0 end]
    .t tag configure elide -elide 1
    .t tag add elide 1.3 2.1
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {$fixedHeight * 1}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 2}] [expr {$fixedHeight * 1}] [expr {$fixedHeight * 1}]]

test textDisp-32.0 {everything elided} {
    # Must not crash
    pack [text .tt]
    .tt insert 0.0 HELLO
    .tt tag configure HIDE -elide 1
    .tt tag add HIDE 0.0 end
    update ; update ; update ; update
    destroy .tt
} {}
test textDisp-32.1 {everything elided} {
    # Must not crash
    pack [text .tt]
    update
    .tt insert 0.0 HELLO
    update
    .tt tag configure HIDE -elide 1
    update
    .tt tag add HIDE 0.0 end
    update ; update ; update ; update
    destroy .tt
} {}
test textDisp-32.2 {elide and tags} {
    pack [text .tt -height 30 -width 100 -bd 0 \
      -highlightthickness 0 -padx 0]
    .tt insert end \
      {test text using tags 1 and 3 } \
      {testtag1 testtag3} \
      {[this bit here uses tags 2 and 3]} \
      {testtag2 testtag3}
    update
    # indent left margin of tag 1 by 20 pixels
    # text should be indented
    .tt tag configure testtag1 -lmargin1 20 ; update

    #1
    set res {}
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should not be indented, since
    # the indented tag and character is hidden.
    .tt tag configure testtag1 -elide 1 ; update

    #2
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag1 -lmargin1 0
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 2 by 20 pixels
    # text should not be indented, since tag1 has lmargin1 of 0.
    .tt tag configure testtag2 -lmargin1 20 ; update

    #3
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should now be indented, but
    # the bbox of 1.0 should have zero width and zero indent,
    # since it is elided at that position.
    .tt tag configure testtag1 -elide 1 ; update

    #4
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag2 -lmargin1 {}
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 3 by 20 pixels
    # text should be indented, since this tag takes
    # precedence over testtag1, and is applied to the
    # start of the text.
    .tt tag configure testtag3 -lmargin1 20 ; update

    #5
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should still be indented,
    # since it still has testtag3 on it.  Again the
    # bbox of 1.0 should have 0.
    .tt tag configure testtag1 -elide 1 ; update

    #6
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    .tt tag configure testtag3 -lmargin1 {} -elide 0
    .tt tag configure testtag1 -elide 1 -lmargin1 20
    #7
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225

4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
    .tt tag configure emoticon -elide 1
    .tt insert end X
    .tt mark set MSGLEFT "end - 1 char"
    .tt mark gravity MSGLEFT left
    .tt insert end ":)" emoticon
    .tt image create end -image $img
    pack .tt
    updateText
} -cleanup {
    image delete $img
    destroy .tt
}

test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt see 1.0
    lindex [.tt yview] 0
} {0.0}
test textDisp-33.1 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt yview "1.0 +1 displaylines"
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
} {ok}
test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    updateText
    set tk_textHeightCalc ""
    set timer [after 200 lappend tk_textHeightCalc "Timed out"]
    .tt insert 1.0 [string repeat "more wrap + " 1]
    vwait tk_textHeightCalc
    after cancel $timer

    set tk_textHeightCalc
} {1.0}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt count -update -ypixels 1.0 end
    updateText
    # Each line should have been recalculated just once
    .tt debug 0
    expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]}
} 1
test textDisp-33.4 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt yview $idx
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }







|







<

|






<

|











<

<

<
|
>

|






<
|
<



|






|







4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121

4122
4123
4124
4125
4126
4127
4128
4129

4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142

4143

4144

4145
4146
4147
4148
4149
4150
4151
4152
4153
4154

4155

4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
    .tt tag configure emoticon -elide 1
    .tt insert end X
    .tt mark set MSGLEFT "end - 1 char"
    .tt mark gravity MSGLEFT left
    .tt insert end ":)" emoticon
    .tt image create end -image $img
    pack .tt
    update; update; update
} -cleanup {
    image delete $img
    destroy .tt
}

test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]

    .tt insert 1.0 [string repeat "more wrap + " 300]
    update ; update ; update
    .tt see 1.0
    lindex [.tt yview] 0
} {0.0}
test textDisp-33.1 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]

    .tt insert 1.0 [string repeat "more wrap + " 300]
    update ; update ; update
    .tt yview "1.0 +1 displaylines"
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
} {ok}
test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1

    set tk_textHeightCalc ""

    .tt insert 1.0 [string repeat "more wrap + " 1]

    after 100 ; update idletasks
    # Nothing should have been recalculated.
    set tk_textHeightCalc
} {}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]

    update ; .tt count -update -ypixels 1.0 end ; update

    # Each line should have been recalculated just once
    .tt debug 0
    expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]}
} {1}
test textDisp-33.4 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    update ; update ; update
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt yview $idx
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285



4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296

4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
    pack [text .tt -wrap char -font {{MS Sans Serif} 15}]
    font create no -family [lindex [.tt cget -font] 0] -size 24
    font create bi -family [lindex [.tt cget -font] 0] -size 24
    font configure bi -weight bold -slant italic
    .tt tag configure bi -font bi
    .tt tag configure no -font no
    .tt insert end abcd no efgh bi ijkl\n no
    updateText
    set bb {}
    for {set i 0} {$i < 12} {incr i 4} {
	lappend bb [lindex [.tt bbox 1.$i] 0]
    }
    foreach {a b c} $bb {}
    unset bb
    if {($b - $a) * 1.5 < ($c - $b)} {
	set result "italic font has much too much space"
    } else {
	set result "italic font measurement ok"
    }
} {italic font measurement ok}
destroy .tt

test textDisp-34.1 {Line heights recalculation problem: bug 2677890} -setup {
    pack [text .t1] -expand 1 -fill both



    set txt ""
    for {set i 1} {$i < 100} {incr i} {
        append txt "Line $i\n"
    }
    set result {}
} -body {
    .t1 insert end $txt
    .t1 debug 1
    set ge [winfo geometry .]
    scan $ge "%dx%d+%d+%d" width height left top
    updateText

    .t1 sync
    set negative 0
    bind .t1 <<WidgetViewSync>> { if {%d < 0} {set negative 1} }
    # Without the fix for bug 2677890, changing the width of the toplevel
    # will launch recomputation of the line heights, but will produce negative
    # number of still remaining outdated lines, which is obviously wrong.
    # Thus we use this way to check for regression regarding bug 2677890,
    # i.e. to check that the fix for this bug really is still in.
    wm geometry . "[expr {$width * 2}]x$height+$left+$top"
    updateText
    .t1 sync
    set negative
} -cleanup {
    destroy .t1
} -result 0

test textDisp-35.1 {Init value of charHeight - Dancing scrollbar bug 1499165} -setup {
    pack [text .t1] -fill both -expand y -side left
    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0







|














|
|
>
>
>

|
|



|
<
<
<
|
>
|
|
<
|
|
|
<
<
<
<
<
|

|
|







4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214



4215
4216
4217
4218

4219
4220
4221





4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
    pack [text .tt -wrap char -font {{MS Sans Serif} 15}]
    font create no -family [lindex [.tt cget -font] 0] -size 24
    font create bi -family [lindex [.tt cget -font] 0] -size 24
    font configure bi -weight bold -slant italic
    .tt tag configure bi -font bi
    .tt tag configure no -font no
    .tt insert end abcd no efgh bi ijkl\n no
    update
    set bb {}
    for {set i 0} {$i < 12} {incr i 4} {
	lappend bb [lindex [.tt bbox 1.$i] 0]
    }
    foreach {a b c} $bb {}
    unset bb
    if {($b - $a) * 1.5 < ($c - $b)} {
	set result "italic font has much too much space"
    } else {
	set result "italic font measurement ok"
    }
} {italic font measurement ok}
destroy .tt

test textDisp-34.1 {Text widgets multi-scrolling problem: Bug 2677890} -setup {
    pack [text .t1 -width 10 -yscrollcommand {.sy set}] \
	[ttk::scrollbar .sy -orient vertical -command {.t1 yview}] \
	-side left -fill both
    bindtags .sy {}; # No clicky!
    set txt ""
    for {set i 0} {$i < 99} {incr i} {
	lappend txt "$i" [list pc $i] "\n" ""
    }
    set result {}
} -body {
    .t1 insert end {*}$txt



    update
    lappend result [.sy get]
    .t1 replace 6.0 6.0+1c "*"
    lappend result [.sy get]

    after 0 {lappend result [.sy get]}
    after 1000 {lappend result [.sy get]}
    vwait result;vwait result





    return $result
} -cleanup {
    destroy .t1 .sy
} -result {{0.0 0.24} {0.0 0.24} {0.0 0.24} {0.0 0.24}}

test textDisp-35.1 {Init value of charHeight - Dancing scrollbar bug 1499165} -setup {
    pack [text .t1] -fill both -expand y -side left
    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0

Changes to tests/textImage.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180




181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218

219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420
421

422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
# textImage.test -- test images embedded in text widgets
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# One time setup.  Create a font to insure the tests are font metric invariant.

destroy .t
font create test_font -family courier -size 14
text .t -font test_font
destroy .t

test textImage-1.1 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image option ?arg ...?"}

test textImage-1.2 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image c
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous option "c": must be cget, configure, create, or names}

test textImage-1.3 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget

} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image cget index option"}

test textImage-1.4 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget blurf -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.5 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget 1.1 -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.6 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image configure index ?-option value ...?"}

test textImage-1.7 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.8 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure 1.1
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.9 {create argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image create index ?-option value ...?"}

test textImage-1.10 {create argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.11 {basic argument checking} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create 1000.1000 -image small
} -cleanup {
    destroy .t
    image delete small
} -returnCodes ok -result {small}

test textImage-1.12 {names argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image names dates places
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image names"}


test textImage-1.13 {names argument checking} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t

    lappend result [.t image names]
    .t image create insert -image small
    lappend result [.t image names]
    .t image create insert -image small
    lappend result [lsort [.t image names]]
    .t image create insert -image small -name little
    lappend result [lsort [.t image names]]
} -cleanup {
    destroy .t
    image delete small
} -result {{} small {small small#1} {little small small#1}}

test textImage-1.14 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image huh
} -cleanup {
    destroy .t
} -returnCodes error -result {bad option "huh": must be cget, configure, create, or names}

test textImage-1.15 {align argument checking} -setup {




    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small -align wrong
} -cleanup {
    destroy .t
    image delete small
} -returnCodes error -result {bad align "wrong": must be baseline, bottom, center, or top}

test textImage-1.16 {configure} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    .t image configure small
} -cleanup {
    destroy .t

    image delete small
} -result {{-align {} {} center center} {-padx {} {} 0 0} {-pady {} {} 0 0} {-image {} {} {} small} {-name {} {} {} {}}}

test textImage-1.17 {basic cget options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small

    foreach i {align padx pady image name} {
        lappend result $i:[.t image cget small -$i]
    }
    return $result
} -cleanup {
    destroy .t
    image delete small
} -result {align:center padx:0 pady:0 image:small name:}

test textImage-1.18 {basic configure options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small

    foreach {option value}  {align top padx 5 pady 7 image large name none} {
        .t image configure small -$option $value
    }
    update
    .t image configure small
} -cleanup {
    destroy .t
    image delete small large
} -result {{-align {} {} center top} {-padx {} {} 0 5} {-pady {} {} 0 7} {-image {} {} {} large} {-name {} {} {} none}}

test textImage-1.19 {basic image naming} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    .t image create end -image small -name small
    .t image create end -image small -name small#6342
    .t image create end -image small -name small
    lsort [.t image names]
} -cleanup {
    destroy .t
    image delete small
} -result {small small#1 small#6342 small#6343}

test textImage-2.1 {debug} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t debug 1
    .t insert end front
    .t image create end -image small
    .t insert end back
    .t delete small
    .t image names
    .t debug 0
} -cleanup {
    destroy .t
    image delete small
} -result {}


test textImage-3.1 {image change propagation} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo vary -width 5 -height 5
        vary put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image vary -align top
    update

    lappend result base:[.t bbox vary]
    foreach i {10 20 40} {
        vary configure -width $i -height $i
        update
        lappend result $i:[.t bbox vary]
    }
    return $result
} -cleanup {
    destroy .t
    image delete vary
} -result {{base:0 0 5 5} {10:0 0 10 10} {20:0 0 20 20} {40:0 0 40 40}}

test textImage-3.2 {delayed image management, see also bug 1591493} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -name test
    update

    foreach {x1 y1 w1 h1} [.t bbox test] {}
    lappend result [list $x1 $w1 $h1]
    .t image configure test -image small -align top
    update
    foreach {x2 y2 w2 h2} [.t bbox test] {}
    lappend result [list [expr {$x1==$x2}] [expr {$w2>0}] [expr {$h2>0}]]
} -cleanup {
    destroy .t
    image delete small
} -result {{0 0 0} {1 1 1}}


# some temporary random tests

test textImage-4.1 {alignment checking - except baseline} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small
    .t insert end test
    update

    lappend result default:[.t bbox small]
    foreach i {top bottom center} {
        .t image configure small -align $i
        update
        lappend result [.t image cget small -align]:[.t bbox small]
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
} -result {{default:50 22 5 5} {top:50 0 5 5} {bottom:50 45 5 5} {center:50 22 5 5}}

test textImage-4.2 {alignment checking - baseline} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    font create test_font2 -size 5
    text .t -font test_font2 -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -align baseline
    .t insert end test

    # Sizes larger than 25 can be too big and lead to a negative 'norm',
    # at least on Windows XP with certain settings.
    foreach size {10 15 20 25} {
    font configure test_font2 -size $size
    array set Metrics [font metrics test_font2]
    update
    foreach {x y w h} [.t bbox small] {}
    set norm [expr {
            (([image height large] - $Metrics(-linespace))/2
            + $Metrics(-ascent) - [image height small] - $y)
        }]
            lappend result "$size $norm"
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
    font delete test_font2
    unset Metrics

} -result {{10 0} {15 0} {20 0} {25 0}}

test textImage-4.3 {alignment and padding checking} -constraints {
    fonts
} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update

    lappend result default:[.t bbox small]
    foreach i {top bottom center baseline} {
        .t image configure small -align $i
        update
        lappend result $i:[.t bbox small]
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
} -result {{default:55 22 5 5} {top:55 10 5 5} {bottom:55 35 5 5} {center:55 22 5 5} {baseline:55 22 5 5}}


test textImage-5.1 {peer widget images} -setup {
    destroy .t .tt
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    pack [text .t]
    toplevel .tt
    pack [.t peer create .tt.t]
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update
    destroy .t .tt
} -cleanup {
    image delete small large
} -result {}

# cleanup
destroy .t

font delete test_font
imageFinish

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:






|



<


<


>
|




|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
>
<
<
<

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
|
<
|
|
|
<
<
|

|
<
<
|
|
|
|
>
|
|
|
<
<
|
<

|
|
<
|
|
|
<
<
|


|
<
<
<
|
|
|
|
>
|
|
>
|
|
|
|
|
|
|
<
<
<
|

|
|
<
|
|
|
<
<
|

|
>
>
>
>
<
<
|
<
<
<
|
|
|
<
<
<
|

|
<
<
|
|
|
|
>
|
|
|
|
<
<
>
<
<

|
<
<
<
|
|
|
|
>
|
|
|
>
|
|
|
|
<
<
<
|

|
<
<
<
|
|
|
|
|
|
>
|
|
|
>
|
|
|
|
|
<
<
<
|

|
<
<
|
|
|
|
>
|
|
|
|
|
|
|
<
<
<
|

|
<
<
|
|
|
|
>
|
|
|
|
|
|
|
|
|
<
<
<
<
|

|
<
<
<
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
<
<
<
|

|
<
<
<
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
<
<
<
|
<



|
<
<
<

|
|
|
|

>






>


|
|
|

|
<
<
<
|

|
<
<
<

|
|
|
|

>






>



|
|
|
|
|
|
|
|
|

<
<
<
<


>
|

|
<
<
<
<
<

|
|
|
|

>






>


|
|
|

|
<
<
<
|

<
|
<
<

|
|
|
|

>








|
<
<


|
>

<




<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12

13
14
15
16
17
18
19
20
21
22

23
24
25


26
27
28
29

30
31
32


33
34
35
36

37
38
39
40



41
42
43

44
45
46


47
48
49
50

51
52
53


54
55
56
57

58
59
60


61
62
63
64

65
66
67


68
69
70
71

72
73
74


75
76
77
78

79
80
81


82
83
84
85

86
87
88


89
90
91


92
93
94
95
96
97
98
99


100

101
102
103

104
105
106


107
108
109
110



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125



126
127
128
129

130
131
132


133
134
135
136
137
138
139


140



141
142
143



144
145
146


147
148
149
150
151
152
153
154
155


156


157
158



159
160
161
162
163
164
165
166
167
168
169
170
171



172
173
174



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190



191
192
193


194
195
196
197
198
199
200
201
202
203
204
205



206
207
208


209
210
211
212
213
214
215
216
217
218
219
220
221
222




223
224
225



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242



243
244
245



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261



262

263
264
265
266



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287



288
289
290



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317




318
319
320
321
322
323





324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344



345
346

347


348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363


364
365
366
367
368

369
370
371
372




# textImage.test -- test images embedded in text widgets
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


# One time setup.  Create a font to insure the tests are font metric invariant.

catch {destroy .t}
font create test_font -family courier -size 14
text .t -font test_font
destroy .t

test textImage-1.1 {basic argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image} msg] $msg


} {1 {wrong # args: should be ".t image option ?arg arg ...?"}}

test textImage-1.2 {basic argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image c} msg] $msg


} {1 {ambiguous option "c": must be cget, configure, create, or names}}

test textImage-1.3 {cget argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image cget} msg] $msg
} {1 {wrong # args: should be ".t image cget index option"}}




test textImage-1.4 {cget argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image cget blurf -flurp} msg] $msg


} {1 {bad text index "blurf"}}

test textImage-1.5 {cget argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image cget 1.1 -flurp} msg] $msg


} {1 {no embedded image at index "1.1"}}

test textImage-1.6 {configure argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image configure } msg] $msg


} {1 {wrong # args: should be ".t image configure index ?option value ...?"}}

test textImage-1.7 {configure argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image configure blurf } msg] $msg


} {1 {bad text index "blurf"}}

test textImage-1.8 {configure argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image configure 1.1 } msg] $msg


} {1 {no embedded image at index "1.1"}}

test textImage-1.9 {create argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image create} msg] $msg


} {1 {wrong # args: should be ".t image create index ?option value ...?"}}

test textImage-1.10 {create argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image create blurf } msg] $msg


} {1 {bad text index "blurf"}}

test textImage-1.11 {basic argument checking} {


	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image create 1000.1000 -image small} msg] $msg


} {0 small}


test textImage-1.12 {names argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image names dates places} msg] $msg


} {1 {wrong # args: should be ".t image names"}}


test textImage-1.13 {names argument checking} {



	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	set result ""
	lappend result [.t image names]
	.t image create insert -image small
	lappend result [.t image names]
	.t image create insert -image small
	lappend result [.t image names]
	.t image create insert -image small -name little
	lappend result [.t image names]



} {{} small {small#1 small} {small#1 small little}}

test textImage-1.14 {basic argument checking} {
	catch {destroy .t}

	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image huh} msg] $msg


} {1 {bad option "huh": must be cget, configure, create, or names}}

test textImage-1.15 {align argument checking} {
	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}


	catch {destroy .t}



	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	list [catch {.t image create end -image small -align wrong} msg] $msg



} {1 {bad align "wrong": must be baseline, bottom, center, or top}}

test textImage-1.16 {configure} {


	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -image small
	.t image configure small


} {{-align {} {} center center} {-padx {} {} 0 0} {-pady {} {} 0 0} {-image {} {} {} small} {-name {} {} {} {}}}



test textImage-1.17 {basic cget options} {



	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -image small
	set result ""
	foreach i {align padx pady image name} {
	    lappend result $i:[.t image cget small -$i]
	}
	set result



} {align:center padx:0 pady:0 image:small name:}

test textImage-1.18 {basic configure options} {



	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	    image create photo large -width 50 -height 50
	    large put green -to 0 0 50 50
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -image small
	set result ""
	foreach {option value}  {align top padx 5 pady 7 image large name none} {
	    .t image configure small -$option $value
	}
	update
	.t image configure small



} {{-align {} {} center top} {-padx {} {} 0 5} {-pady {} {} 0 7} {-image {} {} {} large} {-name {} {} {} none}}

test textImage-1.19 {basic image naming} {


	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -image small
	.t image create end -image small -name small
	.t image create end -image small -name small#6342
	.t image create end -image small -name small
	lsort [.t image names]



} {small small#1 small#6342 small#6343}

test textImage-2.1 {debug} {


	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t debug 1
	.t insert end front
	.t image create end -image small
	.t insert end back
	.t delete small
	.t image names
	.t debug 0




} {}

test textImage-3.1 {image change propagation} {



	catch {
	    image create photo vary -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -image vary -align top
	update
	set result ""
	lappend result base:[.t bbox vary]
	foreach i {10 20 40} {
	    vary configure -width $i -height $i
	    update
	    lappend result $i:[.t bbox vary]
	}
	set result



} {{base:0 0 5 5} {10:0 0 10 10} {20:0 0 20 20} {40:0 0 40 40}}

test textImage-3.2 {delayed image management, see also bug 1591493} {



	catch {
	    image create photo small -width 5 -height 5
	    small put red -to 0 0 4 4
	}
	catch {destroy .t}
	text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
	pack .t
	.t image create end -name test
	update
	set result ""
	foreach {x1 y1 w1 h1} [.t bbox test] {}
	lappend result [list $x1 $w1 $h1]
	.t image configure test -image small -align top
	update
	foreach {x2 y2 w2 h2} [.t bbox test] {}
	lappend result [list [expr {$x1==$x2}] [expr {$w2>0}] [expr {$h2>0}]]



} {{0 0 0} {1 1 1}}


# some temporary random tests

test textImage-4.1 {alignment checking - except baseline} {



    catch {
	image create photo small -width 5 -height 5
	small put red -to 0 0 4 4
	image create photo large -width 50 -height 50
	large put green -to 0 0 50 50
    }
    catch {destroy .t}
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small
    .t insert end test
    update
    set result ""
    lappend result default:[.t bbox small]
    foreach i {top bottom center} {
	.t image configure small -align $i
	update
	lappend result [.t image cget small -align]:[.t bbox small]
    }
    set result



} {{default:50 22 5 5} {top:50 0 5 5} {bottom:50 45 5 5} {center:50 22 5 5}}

test textImage-4.2 {alignment checking - baseline} {



    catch {
	image create photo small -width 5 -height 5
	small put red -to 0 0 4 4
	image create photo large -width 50 -height 50
	large put green -to 0 0 50 50
    }
    catch {destroy .t}
    font create test_font2 -size 5
    text .t -font test_font2 -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -align baseline
    .t insert end test
    set result ""
    # Sizes larger than 25 can be too big and lead to a negative 'norm',
    # at least on Windows XP with certain settings.
    foreach size {10 15 20 25} {
	font configure test_font2 -size $size
	array set Metrics [font metrics test_font2]
	update
	foreach {x y w h} [.t bbox small] {}
	set norm [expr {
	    (([image height large] - $Metrics(-linespace))/2
	    + $Metrics(-ascent) - [image height small] - $y)
	 }]
        lappend result "$size $norm"
    }




    font delete test_font2
    unset Metrics
    set result
} {{10 0} {15 0} {20 0} {25 0}}

test textImage-4.3 {alignment and padding checking} {fonts} {





    catch {
	image create photo small -width 5 -height 5
	small put red -to 0 0 4 4
	image create photo large -width 50 -height 50
	large put green -to 0 0 50 50
    }
    catch {destroy .t}
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update
    set result ""
    lappend result default:[.t bbox small]
    foreach i {top bottom center baseline} {
	.t image configure small -align $i
	update
	lappend result $i:[.t bbox small]
    }
    set result



} {{default:55 22 5 5} {top:55 10 5 5} {bottom:55 35 5 5} {center:55 22 5 5} {baseline:55 22 5 5}}


test textImage-5.0 {peer widget images} {


    catch {
	image create photo small -width 5 -height 5
	small put red -to 0 0 4 4
	image create photo large -width 50 -height 50
	large put green -to 0 0 50 50
    }
    catch {destroy .t .tt}
    pack [text .t]
    toplevel .tt
    pack [.t peer create .tt.t]
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update
    destroy .t .tt
} {}



# cleanup
catch {destroy .t}
foreach image [image names] {image delete $image}
font delete test_font


# cleanup
cleanupTests
return




Changes to tests/textIndex.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# This file is a Tcl script to test the code in the file tkTextIndex.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

catch {destroy .t}
text .t -font {Courier -12} -width 20 -height 10
pack .t -expand 1 -fill both
update
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
by GIrl .#@? x_yz
!@#$%
Line 7"

image create photo textimage -width 10 -height 10
textimage put red -to 0 0 9 9

test textIndex-1.1 {TkTextMakeByteIndex} {testtext} {



|
|
|









|
















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# This file is a Tcl script to test the code in the file tkTextIndex.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

catch {destroy .t}
text .t -font {Courier -12} -width 20 -height 10
pack append . .t {top expand fill}
update
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
b\u4e4fy GIrl .#@? x_yz
!@#$%
Line 7"

image create photo textimage -width 10 -height 10
textimage put red -to 0 0 9 9

test textIndex-1.1 {TkTextMakeByteIndex} {testtext} {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
} {3.4 4}
test textIndex-1.16 {TkTextMakeByteIndex: UTF-8 characters} {testtext} {
    testtext .t byteindex 5 100
} {5.18 20}
test textIndex-1.17 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
	{testtext} {
    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType))
    # Wrong answer would be ¹ (the 2nd byte of UTF rep of 0x4e4f).

    set x [testtext .t byteindex 5 2]
    list $x [.t get insert]
} {{5.2 4} y}
test textIndex-1.18 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
	{testtext} {
    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType))
    testtext .t byteindex 5 1
    .t get insert
} ""

test textIndex-2.1 {TkTextMakeCharIndex} {
    # (lineIndex < 0)
    .t index -1.3
} 1.0
test textIndex-2.2 {TkTextMakeCharIndex} {
    # (lineIndex < 0), because lineIndex == strtol(argv[2]) - 1







|









|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
} {3.4 4}
test textIndex-1.16 {TkTextMakeByteIndex: UTF-8 characters} {testtext} {
    testtext .t byteindex 5 100
} {5.18 20}
test textIndex-1.17 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
	{testtext} {
    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType))
    # Wrong answer would be \xb9 (the 2nd byte of UTF rep of 0x4e4f).

    set x [testtext .t byteindex 5 2]
    list $x [.t get insert]
} {{5.2 4} y}
test textIndex-1.18 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
	{testtext} {
    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType))
    testtext .t byteindex 5 1
    .t get insert
} "\u4e4f"

test textIndex-2.1 {TkTextMakeCharIndex} {
    # (lineIndex < 0)
    .t index -1.3
} 1.0
test textIndex-2.2 {TkTextMakeCharIndex} {
    # (lineIndex < 0), because lineIndex == strtol(argv[2]) - 1
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
} 3.5
test textIndex-2.11 {TkTextMakeCharIndex: verify index is in range} {
    # not (segPtr == NULL)
    .t index 3.4
} 3.4
test textIndex-2.12 {TkTextMakeCharIndex: verify index is in range} {
    # (segPtr->typePtr == &tkTextCharType)
    # Wrong answer would be ¹ (the 2nd byte of UTF rep of 0x4e4f).

    .t mark set insert 5.2
    .t get insert
} y
test textIndex-2.13 {TkTextMakeCharIndex: verify index is in range} {
    # not (segPtr->typePtr == &tkTextCharType)








|







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
} 3.5
test textIndex-2.11 {TkTextMakeCharIndex: verify index is in range} {
    # not (segPtr == NULL)
    .t index 3.4
} 3.4
test textIndex-2.12 {TkTextMakeCharIndex: verify index is in range} {
    # (segPtr->typePtr == &tkTextCharType)
    # Wrong answer would be \xb9 (the 2nd byte of UTF rep of 0x4e4f).

    .t mark set insert 5.2
    .t get insert
} y
test textIndex-2.13 {TkTextMakeCharIndex: verify index is in range} {
    # not (segPtr->typePtr == &tkTextCharType)

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
    .t index {2.5 - 6 chars}
} 1.6
test textIndex-14.15 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 1 chars}
} y
test textIndex-14.16 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 2 chars}
} 
test textIndex-14.17 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 3 chars}
} b

proc getword index {
    .t get [.t index "$index wordstart"] [.t index "$index wordend"]
}







|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
    .t index {2.5 - 6 chars}
} 1.6
test textIndex-14.15 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 1 chars}
} y
test textIndex-14.16 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 2 chars}
} \u4e4f
test textIndex-14.17 {TkTextIndexBackChars: UTF} {
    .t get {5.3 - 3 chars}
} b

proc getword index {
    .t get [.t index "$index wordstart"] [.t index "$index wordend"]
}
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    .t2 mark set $pos 1.0
    lappend res [.t2 index $pos]
    catch {destroy .t2}
    set res
} {3.4 3.0 1.0}

frame .f -width 100 -height 20
pack .f -side left

set fixedFont {Courier -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]

set varFont {Times -14}
set bigFont {Helvetica -24}
destroy .t
text .t -font $fixedFont -width 20 -height 10 -wrap char
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.








|









|







710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    .t2 mark set $pos 1.0
    lappend res [.t2 index $pos]
    catch {destroy .t2}
    set res
} {3.4 3.0 1.0}

frame .f -width 100 -height 20
pack append . .f left

set fixedFont {Courier -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]

set varFont {Times -14}
set bigFont {Helvetica -24}
destroy .t
text .t -font $fixedFont -width 20 -height 10 -wrap char
pack append . .t {top expand fill}
.t tag configure big -font $bigFont
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
    .t index "2.40 +1displaylines"
} {2.60}

test textIndex-19.12 {Display lines} {
    .t index "2.40 -1displaylines"
} {2.20}

test textIndex-19.12.1 {Display lines} {
    .t index "2.50 - 100 displaylines"
} {1.0}

test textIndex-19.12.2 {Display lines} {
    .t compare [.t index "2.50 + 100 displaylines"] == "end - 1 c"
} 1

test textIndex-19.13 {Display lines} {
    destroy {*}[pack content .]
    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
    scrollbar .sbar -command ".txt yview"
    grid .txt .sbar -sticky news
    grid configure .sbar -sticky ns
    grid rowconfigure    . 0 -weight 1
    grid columnconfigure . 0 -weight 1
    .txt configure -width 10







<
<
<
<
<
<
<
<

|







799
800
801
802
803
804
805








806
807
808
809
810
811
812
813
814
    .t index "2.40 +1displaylines"
} {2.60}

test textIndex-19.12 {Display lines} {
    .t index "2.40 -1displaylines"
} {2.20}









test textIndex-19.13 {Display lines} {
    destroy .t
    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
    scrollbar .sbar -command ".txt yview"
    grid .txt .sbar -sticky news
    grid configure .sbar -sticky ns
    grid rowconfigure    . 0 -weight 1
    grid columnconfigure . 0 -weight 1
    .txt configure -width 10
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
test textIndex-21.8 {text index wordend} {
    text_test_word worde "x.y" 0
} 1
test textIndex-21.9 {text index wordend} {
    text_test_word worde "x.y" end-1
} 2
test textIndex-21.10 {text index wordend, unicode} {
    text_test_word wordend "xyzÇde fg" 0
} 6
test textIndex-21.11 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
} 6
test textIndex-21.12 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
} 6
test textIndex-21.13 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
} 3
test textIndex-21.14 {text index wordend, unicode} {
    text_test_word wordend "윀윀 abc" 8
} 6

test textIndex-22.5 {text index wordstart} {
    text_test_word wordstart "one two three_words" 400
} 8
test textIndex-22.6 {text index wordstart} {
    text_test_word wordstart "one two three_words" 2







|


|


|


|


|







859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
test textIndex-21.8 {text index wordend} {
    text_test_word worde "x.y" 0
} 1
test textIndex-21.9 {text index wordend} {
    text_test_word worde "x.y" end-1
} 2
test textIndex-21.10 {text index wordend, unicode} {
    text_test_word wordend "xyz\u00c7de fg" 0
} 6
test textIndex-21.11 {text index wordend, unicode} {
    text_test_word wordend "xyz\uc700de fg" 0
} 6
test textIndex-21.12 {text index wordend, unicode} {
    text_test_word wordend "xyz\u203fde fg" 0
} 6
test textIndex-21.13 {text index wordend, unicode} {
    text_test_word wordend "xyz\u2045de fg" 0
} 3
test textIndex-21.14 {text index wordend, unicode} {
    text_test_word wordend "\uc700\uc700 abc" 8
} 6

test textIndex-22.5 {text index wordstart} {
    text_test_word wordstart "one two three_words" 400
} 8
test textIndex-22.6 {text index wordstart} {
    text_test_word wordstart "one two three_words" 2
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
test textIndex-22.9 {text index wordstart} {
    text_test_word wordstart "one two three" 4
} 4
test textIndex-22.10 {text index wordstart} {
    text_test_word wordstart "one two three" end-5
} 7
test textIndex-22.11 {text index wordstart, unicode} {
    text_test_word wordstart "one twÇo three" 7
} 4
test textIndex-22.12 {text index wordstart, unicode} {
    text_test_word wordstart "ab윀윀 cdef ghi" 12
} 10
test textIndex-22.13 {text index wordstart, unicode} {
    text_test_word wordstart "윀윀 abc" 8
} 3
test textIndex-22.14 {text index wordstart, unicode, start index at internal segment start} {
    catch {destroy .t}
    text .t
    .t insert end "C'est du texte en français\n"
    .t insert end "Это текст на русском"
    .t mark set insert 1.23
    set res [.t index "1.23 wordstart"]
    .t mark set insert 2.16
    lappend res [.t index "2.16 wordstart"] [.t index "2.15 wordstart"]
} {1.18 2.13 2.13}
test textIndex-22.15 {text index display wordstart} {
    catch {destroy .t}







|


|


|




|
|







893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
test textIndex-22.9 {text index wordstart} {
    text_test_word wordstart "one two three" 4
} 4
test textIndex-22.10 {text index wordstart} {
    text_test_word wordstart "one two three" end-5
} 7
test textIndex-22.11 {text index wordstart, unicode} {
    text_test_word wordstart "one tw\u00c7o three" 7
} 4
test textIndex-22.12 {text index wordstart, unicode} {
    text_test_word wordstart "ab\uc700\uc700 cdef ghi" 12
} 10
test textIndex-22.13 {text index wordstart, unicode} {
    text_test_word wordstart "\uc700\uc700 abc" 8
} 3
test textIndex-22.14 {text index wordstart, unicode, start index at internal segment start} {
    catch {destroy .t}
    text .t
    .t insert end "C'est du texte en fran\u00e7ais\n"
    .t insert end "\u042D\u0442\u043E\u0020\u0442\u0435\u043A\u0441\u0442\u0020\u043D\u0430\u0020\u0440\u0443\u0441\u0441\u043A\u043E\u043C"
    .t mark set insert 1.23
    set res [.t index "1.23 wordstart"]
    .t mark set insert 2.16
    lappend res [.t index "2.16 wordstart"] [.t index "2.15 wordstart"]
} {1.18 2.13 2.13}
test textIndex-22.15 {text index display wordstart} {
    catch {destroy .t}

Changes to tests/textMark.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15



16
17
18
19
20
21
22









23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53

54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# This file is a Tcl script to test the code in the file tkTextMark.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

destroy .t
text .t -width 20 -height 10



pack .t -expand 1 -fill both
update
.t debug on
wm geometry . {}
entry .t.e
.t peer create .pt










.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"

# The statements below reset the main window; it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

test textMark-1.1 {TkTextMarkCmd - missing option} -returnCodes error -body {
    .t mark
} -result {wrong # args: should be ".t mark option ?arg ...?"}
test textMark-1.2 {TkTextMarkCmd - bogus option} -returnCodes error -body {
    .t mark gorp
} -match glob -result {bad mark option "gorp": must be *}
test textMark-1.3 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark gravity foo
} -result {there is no mark named "foo"}
test textMark-1.4 {TkTextMarkCmd - "gravity" option} -body {

    .t mark set x 1.3
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.5 {TkTextMarkCmd - "gravity" option} -body {

    .t mark set x 1.3
    .t mark gr x left
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {left 1.3}
test textMark-1.6 {TkTextMarkCmd - "gravity" option} -body {

    .t mark set x 1.3
    .t mark gravity x right
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.7 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark set x 1.3
    .t mark gravity x gorp
} -result {bad mark gravity "gorp": must be left or right}
test textMark-1.8 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark gravity
} -result {wrong # args: should be ".t mark gravity markName ?gravity?"}

test textMark-2.1 {TkTextMarkCmd - "names" option} -body {
    .t mark names 2
} -returnCodes error -result {wrong # args: should be ".t mark names"}

test textMark-2.2 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    lsort [.t mark na]
} -result {current insert}
test textMark-2.3 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set a 1.1
    .t mark set "b c" 2.3
    lsort [.t mark names]
} -result {a {b c} current insert}

test textMark-3.1 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark set a
} -result {wrong # args: should be ".t mark set markName index"}
test textMark-3.2 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark s a b c
} -result {wrong # args: should be ".t mark set markName index"}
test textMark-3.3 {TkTextMarkCmd - "set" option} -body {
    .t mark set a @x
} -returnCodes error -result {bad text index "@x"}
test textMark-3.4 {TkTextMarkCmd - "set" option} -body {
    .t mark set a 1.2
    .t index a
} -result 1.2
test textMark-3.5 {TkTextMarkCmd - "set" option} -body {
    .t mark set a end
    .t index a
} -result {8.0}

test textMark-4.1 {TkTextMarkCmd - "unset" option} -body {
    .t mark unset
} -result {}
test textMark-4.2 {TkTextMarkCmd - "unset" option} -body {
    .t mark set a 1.2
    .t mark set b 2.3
    .t mark unset a b
    .t index a
} -returnCodes error -result {bad text index "a"}
test textMark-4.2.1 {TkTextMarkCmd - "unset" option} -body {
    .t mark set a 1.2
    .t mark set b 2.3
    .t mark unset a b
    .t index b
} -returnCodes error -result {bad text index "b"}
test textMark-4.3 {TkTextMarkCmd - "unset" option} -body {
    .t mark set a 1.2
    .t mark set b 2.3
    .t mark set 49ers 3.1
    .t mark unset {*}[.t mark names]
    lsort [.t mark names]
} -result {current insert}

test textMark-5.1 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark
} -result {wrong # args: should be ".t mark option ?arg ...?"}
test textMark-5.2 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark foo
} -result {bad mark option "foo": must be gravity, names, next, previous, set, or unset}

test textMark-6.1 {TkTextMarkSegToIndex} -body {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]
} -result {1.2 1.2 1.2 1.4}
test textMark-6.2 {TkTextMarkNameToIndex, with mark outside -startline/-endline range - bug 1630271} -body {
  .t mark set insert 1.0
  .t configure -startline 2
  set res [list [.t index insert] [.t index insert-1c] [.t get insert]]
  .t mark set insert end
  .t configure -endline 4
  lappend res [.t index insert]



|
|
|



<
|


|

>
>
>
|



<


>
>
>
>
>
>
>
>
>








<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
>



|
|
>

|


|
|
>




|
|
<
|
|
|
|
|

|
|
|
>
|
<
<

|
|
<
<



|

|
|
|
|
|
|
|
|
|
|


|
|


|

|
|
|
|



|
|
<
<
<
<
<
<
|



|

|

|
|
|
|
|
|

|





|







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40








41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81


82
83
84


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116






117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# This file is a Tcl script to test the code in the file tkTextMark.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

catch {destroy .t}
text .t -width 20 -height 10
testConstraint haveCourier12 [expr {[catch {
    .t configure -font {Courier 12}
}] == 0}]
pack append . .t {top expand fill}
update
.t debug on
wm geometry . {}

.t peer create .pt

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

entry .t.e
.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"









test textMark-1.1 {TkTextMarkCmd - missing option} haveCourier12 {
    list [catch {.t mark} msg] $msg
} {1 {wrong # args: should be ".t mark option ?arg arg ...?"}}
test textMark-1.2 {TkTextMarkCmd - bogus option} haveCourier12 {
    list [catch {.t mark gorp} msg] $msg
} {1 {bad mark option "gorp": must be gravity, names, next, previous, set, or unset}}
test textMark-1.3 {TkTextMarkCmd - "gravity" option} haveCourier12 {
    list [catch {.t mark gravity foo} msg] $msg
} {1 {there is no mark named "foo"}}
test textMark-1.4 {TkTextMarkCmd - "gravity" option} haveCourier12 {
    .t mark unset x
    .t mark set x 1.3
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} {right 1.4}
test textMark-1.5 {TkTextMarkCmd - "gravity" option} haveCourier12 {
    .t mark unset x
    .t mark set x 1.3
    .t mark g x left
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} {left 1.3}
test textMark-1.6 {TkTextMarkCmd - "gravity" option} haveCourier12 {
    .t mark unset x
    .t mark set x 1.3
    .t mark gravity x right
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} {right 1.4}
test textMark-1.7 {TkTextMarkCmd - "gravity" option} haveCourier12 {

    list [catch {.t mark gravity x gorp} msg] $msg
} {1 {bad mark gravity "gorp": must be left or right}}
test textMark-1.8 {TkTextMarkCmd - "gravity" option} haveCourier12 {
    list [catch {.t mark gravity} msg] $msg
} {1 {wrong # args: should be ".t mark gravity markName ?gravity?"}}

test textMark-2.1 {TkTextMarkCmd - "names" option} haveCourier12 {
    list [catch {.t mark names 2} msg] $msg
} {1 {wrong # args: should be ".t mark names"}}
.t mark unset x
test textMark-2.2 {TkTextMarkCmd - "names" option} haveCourier12 {


    lsort [.t mark na]
} {current insert}
test textMark-2.3 {TkTextMarkCmd - "names" option} haveCourier12 {


    .t mark set a 1.1
    .t mark set "b c" 2.3
    lsort [.t mark names]
} {a {b c} current insert}

test textMark-3.1 {TkTextMarkCmd - "set" option} haveCourier12 {
    list [catch {.t mark set a} msg] $msg
} {1 {wrong # args: should be ".t mark set markName index"}}
test textMark-3.2 {TkTextMarkCmd - "set" option} haveCourier12 {
    list [catch {.t mark s a b c} msg] $msg
} {1 {wrong # args: should be ".t mark set markName index"}}
test textMark-3.3 {TkTextMarkCmd - "set" option} haveCourier12 {
    list [catch {.t mark set a @x} msg] $msg
} {1 {bad text index "@x"}}
test textMark-3.4 {TkTextMarkCmd - "set" option} haveCourier12 {
    .t mark set a 1.2
    .t index a
} 1.2
test textMark-3.5 {TkTextMarkCmd - "set" option} haveCourier12 {
    .t mark set a end
    .t index a
} {8.0}

test textMark-4.1 {TkTextMarkCmd - "unset" option} haveCourier12 {
    list [catch {.t mark unset} msg] $msg
} {0 {}}
test textMark-4.2 {TkTextMarkCmd - "unset" option} haveCourier12 {
    .t mark set a 1.2
    .t mark set b 2.3
    .t mark unset a b
        list [catch {.t index a} msg] $msg [catch {.t index b} msg2] $msg2
} {1 {bad text index "a"} 1 {bad text index "b"}}






test textMark-4.3 {TkTextMarkCmd - "unset" option} haveCourier12 {
    .t mark set a 1.2
    .t mark set b 2.3
    .t mark set 49ers 3.1
    eval .t mark unset [.t mark names]
    lsort [.t mark names]
} {current insert}

test textMark-5.1 {TkTextMarkCmd - miscellaneous} haveCourier12 {
    list [catch {.t mark} msg] $msg
} {1 {wrong # args: should be ".t mark option ?arg arg ...?"}}
test textMark-5.2 {TkTextMarkCmd - miscellaneous} haveCourier12 {
    list [catch {.t mark foo} msg] $msg
} {1 {bad mark option "foo": must be gravity, names, next, previous, set, or unset}}

test textMark-6.1 {TkTextMarkSegToIndex} haveCourier12 {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]
} {1.2 1.2 1.2 1.4}
test textMark-6.2 {TkTextMarkNameToIndex, with mark outside -startline/-endline range - bug 1630271} -body {
  .t mark set insert 1.0
  .t configure -startline 2
  set res [list [.t index insert] [.t index insert-1c] [.t get insert]]
  .t mark set insert end
  .t configure -endline 4
  lappend res [.t index insert]
173
174
175
176
177
178
179
180
181
182
183
184
185

186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240


241

242
243


244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
} -cleanup {
  .t configure -startline {} -endline {}
  .pt configure -startline {} -endline {}
  .t mark unset mymark
} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -body {
  .t mark set insert 1.0
  .t configure -startline 5 -endline 5
  set res [.t index insert]
} -cleanup {
  .t configure -startline {} -endline {}
} -result {1.0}


test textMark-7.1 {MarkFindNext - invalid mark name} -body {
    .t mark next bogus

} -returnCodes error -result {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
    .t mark next current
} -result {insert}
test textMark-7.3 {MarkFindNext - numerical starting mark} -body {
    .t mark set current 1.0
    .t mark set insert 1.0
    .t mark next 1.0
} -result {insert}
test textMark-7.4 {MarkFindNext - mark on the same line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 1.1
    .t mark next current
} -result {insert}
test textMark-7.5 {MarkFindNext - mark on the next line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.end
    .t mark set insert 2.0
    .t mark next current
} -result {insert}
test textMark-7.6 {MarkFindNext - mark far away} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.2
    .t mark set insert 7.0
    .t mark next current
} -result {insert}
test textMark-7.7 {MarkFindNext - mark on top of end} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current end
    .t mark next end
} -result {current}
test textMark-7.8 {MarkFindNext - no next mark} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark next insert
} -result {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]]
} -result {current insert mymark}

test textMark-8.1 {MarkFindPrev - invalid mark name} -body {


    .t mark prev bogus

} -returnCodes error -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -body {


    .t mark set insert 2.0
    .t mark set current 2.0
    .t mark prev insert
} -result {current}
test textMark-8.3 {MarkFindPrev - numerical starting mark} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 1.0
    .t mark prev 1.1
} -result {current}
test textMark-8.4 {MarkFindPrev - mark on the same line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 1.1
    .t mark prev insert
} -result {current}
test textMark-8.5 {MarkFindPrev - mark on the previous line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.end
    .t mark set insert 2.0
    .t mark prev insert
} -result {current}
test textMark-8.6 {MarkFindPrev - mark far away} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.2
    .t mark set insert 7.0
    .t mark prev insert
} -result {current}
test textMark-8.7 {MarkFindPrev - mark on top of end} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 3.0
    .t mark set current end
    .t mark prev end
} -result {insert}
test textMark-8.8 {MarkFindPrev - no previous mark} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark prev current
} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}

destroy .pt
destroy .t

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|





>
|
|
>
|
|



|
|



|
|
<
<



|
|
<
<



|
|
<
<



|
|
<
<


|
|
<
<



|







|
>
>
|
>
|
|
>
>




|




















|






|






|












|
|
|




<
<
<
<
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196


197
198
199
200
201


202
203
204
205
206


207
208
209
210
211


212
213
214
215


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294




} -cleanup {
  .t configure -startline {} -endline {}
  .pt configure -startline {} -endline {}
  .t mark unset mymark
} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -body {
  .t mark set insert 1.0
  .t configure -start 5 -end 5
  set res [.t index insert]
} -cleanup {
  .t configure -startline {} -endline {}
} -result {1.0}

catch {eval {.t mark unset} [.t mark names]}
test textMark-7.1 {MarkFindNext - invalid mark name} haveCourier12 {
    catch {.t mark next bogus} x
    set x
} {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} haveCourier12 {
    .t mark set insert 2.0
    .t mark set current 2.0
    .t mark next current
} {insert}
test textMark-7.3 {MarkFindNext - numerical starting mark} haveCourier12 {
    .t mark set current 1.0
    .t mark set insert 1.0
    .t mark next 1.0
} {insert}
test textMark-7.4 {MarkFindNext - mark on the same line} haveCourier12 {


    .t mark set current 1.0
    .t mark set insert 1.1
    .t mark next current
} {insert}
test textMark-7.5 {MarkFindNext - mark on the next line} haveCourier12 {


    .t mark set current 1.end
    .t mark set insert 2.0
    .t mark next current
} {insert}
test textMark-7.6 {MarkFindNext - mark far away} haveCourier12 {


    .t mark set current 1.2
    .t mark set insert 7.0
    .t mark next current
} {insert}
test textMark-7.7 {MarkFindNext - mark on top of end} haveCourier12 {


    .t mark set current end
    .t mark next end
} {current}
test textMark-7.8 {MarkFindNext - no next mark} haveCourier12 {


    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark next insert
} {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]]
} -result {current insert mymark}

test textMark-8.1 {MarkFindPrev - invalid mark name} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    catch {.t mark prev bogus} x
    set x
} -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
    .t mark prev insert
} -result {current}
test textMark-8.3 {MarkFindPrev - numerical starting mark} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 1.0
    .t mark prev 1.1
} -result {current}
test textMark-8.4 {MarkFindPrev - mark on the same line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 1.1
    .t mark prev insert
} -result {current}
test textMark-8.5 {MarkFindPrev - mark on the previous line} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.end
    .t mark set insert 2.0
    .t mark prev insert
} -result {current}
test textMark-8.6 {MarkFindPrev - mark far away} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.2
    .t mark set insert 7.0
    .t mark prev insert
} -result {current}
test textMark-8.7 {MarkFindPrev - mark on top of end} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 3.0
    .t mark set current end
    .t mark prev end
} -result {insert}
test textMark-8.8 {MarkFindPrev - no previous mark} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark prev current
} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}

catch {destroy .t}
catch {destroy .pt}

# cleanup
cleanupTests
return




Changes to tests/textTag.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34


35
36
37
38
39

40
41
42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122


123
124
125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737

738

739

740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819



820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214


1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324


1325

1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369

1370
1371

1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445

1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
# This file is a Tcl script to test the code in the file tkTextTag.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

set textWidgetFont {Courier 12}
set bigFont        {Courier 24}

# what is needed is a font that is both fixed-width and featuring a
# specific size because in some tests (that will be constrained by
# haveFontSizes), a tag applying the $bigFont will be set to some
# characters, which action has the effect of changing what character
# is under the mouse pointer, which is the purpose of the tests
testConstraint haveFontSizes [expr {
    [font metrics $textWidgetFont -fixed] &&
    [font actual  $textWidgetFont -size] == 12 &&
    [font metrics $bigFont -fixed] &&
    [font actual  $bigFont -size] == 24 }
]

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

destroy .t
text .t -width 20 -height 10



pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}


# The statements below reset the main window;  it's needed if the window
# manager is mwm, to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .




.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"

test textTag-1.1 {tag configuration options} -body {
    .t tag configure x -background #012345
    .t tag cget x -background
} -cleanup {
    .t tag configure x -background [lindex [.t tag configure x -background] 3]
} -result {#012345}
test textTag-1.2 {configuration options} -body {
    .t tag configure x -background non-existent
} -cleanup {
    .t tag configure x -background [lindex [.t tag configure x -background] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.3 {tag configuration options} -body {
    .t tag configure x -bgstipple gray50
    .t tag cget x -bgstipple
} -cleanup {
    .t tag configure x -bgstipple [lindex [.t tag configure x -bgstipple] 3]
} -result {gray50}
test textTag-1.4 {configuration options} -body {
    .t tag configure x -bgstipple badStipple
} -cleanup {
    .t tag configure x -bgstipple [lindex [.t tag configure x -bgstipple] 3]
} -returnCodes error -result {bitmap "badStipple" not defined}
test textTag-1.5 {tag configuration options} -body {
    .t tag configure x -borderwidth 2
    .t tag cget x -borderwidth
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -result 2
test textTag-1.6 {configuration options} -body {
    .t tag configure x -borderwidth 46q
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -returnCodes error -result {bad screen distance "46q"}
test textTag-1.7 {tag configuration options} -body {
    .t tag configure x -fgstipple gray25
    .t tag cget x -fgstipple
} -cleanup {
    .t tag configure x -fgstipple [lindex [.t tag configure x -fgstipple] 3]
} -result {gray25}
test textTag-1.8 {configuration options} -body {
    .t tag configure x -fgstipple bogus
} -cleanup {
    .t tag configure x -fgstipple [lindex [.t tag configure x -fgstipple] 3]
} -returnCodes error -result {bitmap "bogus" not defined}
test textTag-1.9 {tag configuration options} -body {
    .t tag configure x -font fixed
    .t tag cget x -font
} -cleanup {
    .t tag configure x -font [lindex [.t tag configure x -font] 3]
} -result {fixed}
test textTag-1.10 {tag configuration options} -body {
    .t tag configure x -foreground #001122
    .t tag cget x -foreground
} -cleanup {
    .t tag configure x -foreground [lindex [.t tag configure x -foreground] 3]
} -result {#001122}
test textTag-1.11 {configuration options} -body {
    .t tag configure x -foreground {silly color}
} -cleanup {
    .t tag configure x -foreground [lindex [.t tag configure x -foreground] 3]
} -returnCodes error -result {unknown color name "silly color"}
test textTag-1.12 {tag configuration options} -body {
    .t tag configure x -justify left
    .t tag cget x -justify

} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]


} -result {left}
test textTag-1.13 {configuration options} -body {
    .t tag configure x -justify middle


} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]
} -returnCodes error -result {bad justification "middle": must be left, right, or center}
test textTag-1.14 {tag configuration options} -body {
    .t tag configure x -lmargin1 10
    .t tag cget x -lmargin1
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -result 10
test textTag-1.15 {configuration options} -body {
    .t tag configure x -lmargin1 bad
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.16 {tag configuration options} -body {
    .t tag configure x -lmargin2 10
    .t tag cget x -lmargin2
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -result 10
test textTag-1.17 {configuration options} -body {
    .t tag configure x -lmargin2 bad
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.17a {tag configuration options} -body {
    .t tag configure x -lmargincolor lightgreen
    .t tag cget x -lmargincolor
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]
} -result {lightgreen}
test textTag-1.17b {configuration options} -body {
    .t tag configure x -lmargincolor non-existent
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]

} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.18 {tag configuration options} -body {
    .t tag configure x -offset 2
    .t tag cget x -offset
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -result 2
test textTag-1.19 {configuration options} -body {
    .t tag configure x -offset 100xyz
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -returnCodes error -result {bad screen distance "100xyz"}
test textTag-1.20 {tag configuration options} -body {
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -result {on}
test textTag-1.21 {configuration options} -body {


    .t tag configure x -overstrike stupid
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-1.21a {tag configuration options} -body {
    .t tag configure x -overstrikefg red
    .t tag cget x -overstrikefg
} -cleanup {
    .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3]
} -result {red}
test textTag-1.21b {configuration options} -body {
    .t tag configure x -overstrikefg stupid
} -cleanup {
    .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3]
} -returnCodes error -result {unknown color name "stupid"}
test textTag-1.22 {tag configuration options} -body {
    .t tag configure x -relief raised
    .t tag cget x -relief
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -result {raised}
test textTag-1.23 {configuration options} -body {
    .t tag configure x -relief stupid
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -returnCodes error -result {bad relief "stupid": must be flat, groove, raised, ridge, solid, or sunken}
test textTag-1.24 {tag configuration options} -body {
    .t tag configure x -rmargin 10
    .t tag cget x -rmargin
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -result 10
test textTag-1.25 {configuration options} -body {
    .t tag configure x -rmargin bad
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.25a {tag configuration options} -body {
    .t tag configure x -rmargincolor darkblue
    .t tag cget x -rmargincolor
} -cleanup {
    .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3]
} -result {darkblue}
test textTag-1.25b {configuration options} -body {
    .t tag configure x -rmargincolor non-existent
} -cleanup {
    .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.25c {tag configuration options} -body {
    .t tag configure x -selectbackground #012345
    .t tag cget x -selectbackground
} -cleanup {
    .t tag configure x -selectbackground [lindex [.t tag configure x -selectbackground] 3]
} -result {#012345}
test textTag-1.25d {configuration options} -body {
    .t tag configure x -selectbackground non-existent
} -cleanup {
    .t tag configure x -selectbackground [lindex [.t tag configure x -selectbackground] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.25e {tag configuration options} -body {
    .t tag configure x -selectforeground #012345
    .t tag cget x -selectforeground
} -cleanup {
    .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3]
} -result {#012345}
test textTag-1.25f {configuration options} -body {
    .t tag configure x -selectforeground non-existent
} -cleanup {
    .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.26 {tag configuration options} -body {
    .t tag configure x -spacing1 10
    .t tag cget x -spacing1
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -result 10
test textTag-1.27 {configuration options} -body {

    .t tag configure x -spacing1 bad
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -returnCodes error -result {bad screen distance "bad"}

test textTag-1.28 {tag configuration options} -body {
    .t tag configure x -spacing2 10
    .t tag cget x -spacing2
} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -result 10
test textTag-1.29 {configuration options} -body {
    .t tag configure x -spacing2 bad
} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.30 {tag configuration options} -body {
    .t tag configure x -spacing3 10
    .t tag cget x -spacing3
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -result 10
test textTag-1.31 {configuration options} -body {
    .t tag configure x -spacing3 bad
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.32 {tag configuration options} -body {
    .t tag configure x -tabs {10 20 30}
    .t tag cget x -tabs
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -result {10 20 30}
test textTag-1.33 {configuration options} -body {
    .t tag configure x -tabs {10 fork}
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -returnCodes error -result {bad tab alignment "fork": must be left, right, center, or numeric}
test textTag-1.34 {tag configuration options} -body {
    .t tag configure x -underline no
    .t tag cget x -underline
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -result {no}
test textTag-1.35 {configuration options} -body {
    .t tag configure x -underline stupid
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-1.36 {tag configuration options} -body {
    .t tag configure x -underlinefg red
    .t tag cget x -underlinefg
} -cleanup {
    .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3]
} -result {red}
test textTag-1.37 {configuration options} -body {
    .t tag configure x -underlinefg stupid
} -cleanup {
    .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3]
} -returnCodes error -result {unknown color name "stupid"}


test textTag-2.1 {TkTextTagCmd - "add" option} -body {
    .t tag
} -returnCodes error -result {wrong # args: should be ".t tag option ?arg ...?"}
test textTag-2.2 {TkTextTagCmd - "add" option} -body {
    .t tag gorp
} -returnCodes error -result {bad tag option "gorp": must be add, bind, cget, configure, delete, lower, names, nextrange, prevrange, raise, ranges, or remove}
test textTag-2.3 {TkTextTagCmd - "add" option} -body {
    .t tag add foo
} -returnCodes error -result {wrong # args: should be ".t tag add tagName index1 ?index2 index1 index2 ...?"}
test textTag-2.4 {TkTextTagCmd - "add" option} -body {
    .t tag add x gorp
} -returnCodes error -result {bad text index "gorp"}
test textTag-2.5 {TkTextTagCmd - "add" option} -body {
    .t tag add x 1.2 gorp
} -returnCodes error -result {bad text index "gorp"}
test textTag-2.6 {TkTextTagCmd - "add" option} -setup {
    .t tag delete sel
} -body {
    .t tag add sel 3.2 3.4
    .t tag add sel 3.2 3.0
    .t tag ranges sel
} -result {3.2 3.4}
test textTag-2.7 {TkTextTagCmd - "add" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 1.0 1.end
    .t tag ranges x
} -cleanup {
    .t tag delete x
} -result {1.0 1.6}
test textTag-2.8 {TkTextTagCmd - "add" option} -setup {
    .t tag remove x 1.0 end
} -body {
    .t tag add x 1.2
    .t tag ranges x
} -cleanup {
    .t tag delete x
} -result {1.2 1.3}
test textTag-2.9 {TkTextTagCmd - "add" option} -setup {
    destroy .t.e
} -body {
    entry .t.e
    .t.e insert 0 "Text"
    .t.e select from 0
    .t.e select to 4
    .t tag add sel 3.2 3.4
    selection get
} -cleanup {
    destroy .t.e
} -result 34
test textTag-2.10 {TkTextTagCmd - "add" option} -setup {
    destroy .t.e
} -body {
    entry .t.e
    .t.e insert 0 "Text"
    .t.e select from 0
    .t.e select to 4
    .t configure -exportselection 0
    .t tag add sel 3.2 3.4
    selection get
} -cleanup {
    destroy .t.e
}  -result {Text}
test textTag-2.11 {TkTextTagCmd - "add" option} -body {
    .t tag remove sel 1.0 end
    .t tag add sel 1.1 1.5 2.4 3.1 4.2 4.4
    .t tag ranges sel
} -result {1.1 1.5 2.4 3.1 4.2 4.4}
test textTag-2.12 {TkTextTagCmd - "add" option} -body {
    .t tag remove sel 1.0 end
    .t tag add sel 1.1 1.5 2.4
    .t tag ranges sel
} -cleanup {
    .t tag remove sel 1.0 end
} -result {1.1 1.5 2.4 2.5}
test textTag-2.14 {tag add before -startline - Bug 1615425} -body {
    text .tt
    for {set i 1} {$i <10} {incr i} {
        .tt insert end "Line $i\n"
    }
    .tt tag configure mytag -font {Courier 12 bold}
    .tt peer create .ptt
    .ptt configure -startline 3 -endline 7
    # the test succeeds if next line does not crash
    .tt tag add mytag 1.0 1.end
    destroy .ptt .tt
    set res 1
} -result 1


test textTag-3.1 {TkTextTagCmd - "bind" option} -body {
    .t tag bind
} -returnCodes error -result {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}
test textTag-3.2 {TkTextTagCmd - "bind" option} -body {
    .t tag bind 1 2 3 4
} -returnCodes error -result {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}
test textTag-3.3 {TkTextTagCmd - "bind" option} -body {
    .t tag bind x <Enter> script1
    .t tag bind x <Enter>
} -cleanup {
    .t tag delete x
} -result {script1}
test textTag-3.4 {TkTextTagCmd - "bind" option} -body {
    .t tag bind x <Gorp> script2
} -returnCodes error -result {bad event type or keysym "Gorp"}
test textTag-3.5 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <Enter> script1
    .t tag bind x <FocusIn> script2
} -cleanup {
    .t tag delete x
} -returnCodes error -result {requested illegal events; only key, button, motion, enter, leave, and virtual events may be used}
test textTag-3.6 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <Enter> script1
    catch {.t tag bind x <FocusIn> script2}
    .t tag bind x
} -cleanup {
    .t tag delete x
} -result {<Enter>}
test textTag-3.7 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <Enter> script1
    .t tag bind x <Leave> script2
    .t tag bind x a xyzzy
    list [lsort [.t tag bind x]] [.t tag bind x <Enter>] [.t tag bind x a]
} -cleanup {
    .t tag delete x
} -result {{<Enter> <Leave> a} script1 xyzzy}
test textTag-3.8 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <Enter> script1
    .t tag bind x <Enter> +script2
    .t tag bind x <Enter>
} -cleanup {
    .t tag delete x
} -result {script1
script2}
test textTag-3.9 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <Enter>
} -cleanup {
    .t tag delete x
} -returnCodes ok -result {}
test textTag-3.10 {TkTextTagCmd - "bind" option} -body {
    .t tag delete x
    .t tag bind x <
} -cleanup {
    .t tag delete x
} -returnCodes error -result {no event type or button # or keysym}


test textTag-4.1 {TkTextTagCmd - "cget" option} -body {
    .t tag cget a
} -returnCodes error -result {wrong # args: should be ".t tag cget tagName option"}
test textTag-4.2 {TkTextTagCmd - "cget" option} -body {
    .t tag cget a b c
} -returnCodes error -result {wrong # args: should be ".t tag cget tagName option"}
test textTag-4.3 {TkTextTagCmd - "cget" option} -body {
    .t tag delete foo
    .t tag cget foo bar
} -returnCodes error -result {tag "foo" isn't defined in text widget}
test textTag-4.4 {TkTextTagCmd - "cget" option} -body {
    .t tag cget sel bogus
} -returnCodes error -result {unknown option "bogus"}
test textTag-4.5 {TkTextTagCmd - "cget" option} -body {
    .t tag delete x
    .t tag configure x -background red
    .t tag cget x -background
} -cleanup {
    .t tag delete x
} -result {red}


test textTag-5.1 {TkTextTagCmd - "configure" option} -body {
    .t tag configure
} -returnCodes error -result {wrong # args: should be ".t tag configure tagName ?-option value ...?"}
test textTag-5.2 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -foo
} -returnCodes error -result {unknown option "-foo"}
test textTag-5.3 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -background red -underline
} -cleanup {
    .t tag delete x
} -returnCodes error -result {value for "-underline" missing}
test textTag-5.4 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline yes
    .t tag configure x -underline
} -cleanup {
    .t tag delete x
} -result {-underline {} {} {} yes}
test textTag-5.4a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underlinefg lightgreen
    .t tag configure x -underlinefg
} -cleanup {
    .t tag delete x
} -result {-underlinefg {} {} {} lightgreen}
test textTag-5.5 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag delete x
} -result {on}
test textTag-5.5a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrikefg lightgreen
    .t tag configure x -overstrikefg
} -cleanup {
    .t tag delete x
} -result {-overstrikefg {} {} {} lightgreen}
test textTag-5.6 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -overstrike foo
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value but got "foo"}
test textTag-5.7 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline stupid
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-5.8 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify left
    .t tag configure x -justify
} -cleanup {
    .t tag delete x
} -result {-justify {} {} {} left}
test textTag-5.9 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify bogus
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
test textTag-5.10 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify fill
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justification "fill": must be left, right, or center}
test textTag-5.11 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 2
    .t tag configure x -offset
} -cleanup {
    .t tag delete x
} -result {-offset {} {} {} 2}
test textTag-5.12 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 1.0q
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "1.0q"}
test textTag-5.13 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5 \
        -lmargincolor darkblue -rmargincolor lightgreen
    list [.t tag configure x -lmargin1] [.t tag configure x -lmargin2] \
        [.t tag configure x -rmargin] [.t tag configure x -lmargincolor] \
        [.t tag configure x -rmargincolor]
} -cleanup {
    .t tag delete x
} -result [list {-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} \
                {-rmargin {} {} {} 5} \
                {-lmargincolor {} {} {} darkblue} {-rmargincolor {} {} {} lightgreen} \
          ]
test textTag-5.14 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "2.0x"}
test textTag-5.15 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin2 gorp
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "gorp"}
test textTag-5.15a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
test textTag-5.16 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargin 140.1.1
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "140.1.1"}
test textTag-5.16a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
.t tag delete x
test textTag-5.17 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2 -spacing2 4 -spacing3 6
    list [.t tag configure x -spacing1] [.t tag configure x -spacing2] \
        [.t tag configure x -spacing3]
} -cleanup {
    .t tag delete x
} -result {{-spacing1 {} {} {} 2} {-spacing2 {} {} {} 4} {-spacing3 {} {} {} 6}}
test textTag-5.18 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "2.0x"}
test textTag-5.19 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 lousy
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "lousy"}
test textTag-5.20 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 4.2.3
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "4.2.3"}
test textTag-5.21 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 2 -selectforeground blue \
        -selectbackground black
    .t tag configure sel -borderwidth 4 -foreground green -background yellow
    set x {}
    foreach i {-selectborderwidth -selectforeground -selectbackground} {
        lappend x [lindex [.t configure $i] 4]
    }
    return $x
} -result {4 green yellow}
test textTag-5.22 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 20
    .t tag configure sel -borderwidth {}
    .t cget -selectborderwidth
} -result {}
test textTag-5.23 {TkTextTagCmd - "configure" option} -body {
    set x {}
    # when [.t tag cget sel -selectbackground] == "", mirroring happens between
    #     the text widget option -selectbackground
    # and the tag         option -background
    .t tag configure sel -selectbackground {}
    .t configure -selectbackground black
    .t tag configure sel -background yellow
    lappend x [.t cget -selectbackground]
    .t tag configure sel -background orange
    .t configure -selectbackground blue
    lappend x [.t tag cget sel -background]
    # when [.t tag cget sel -selectbackground] != "", mirroring happens between
    #     the text widget option -selectbackground
    # and the tag         option -selectbackground
    .t tag configure sel -selectbackground green
    .t configure -selectbackground red
    lappend x [.t tag cget sel -selectbackground]
    .t configure -selectbackground black
    .t tag configure sel -selectbackground white
    lappend x [.t cget -selectbackground]
    return $x
} -result {yellow blue red white}
test textTag-5.24 {TkTextTagCmd - "configure" option} -body {
    set x {}
    # when [.t tag cget sel -selectforeground] == "", mirroring happens between
    #     the text widget option -selectforeground
    # and the tag         option -foreground
    .t tag configure sel -selectforeground {}
    .t configure -selectforeground black
    .t tag configure sel -foreground yellow
    lappend x [.t cget -selectforeground]
    .t tag configure sel -foreground orange
    .t configure -selectforeground blue
    lappend x [.t tag cget sel -foreground]
    # when [.t tag cget sel -selectforeground] != "", mirroring happens between
    #     the text widget option -selectforeground
    # and the tag         option -selectforeground
    .t tag configure sel -selectforeground green
    .t configure -selectforeground red
    lappend x [.t tag cget sel -selectforeground]
    .t configure -selectforeground black
    .t tag configure sel -selectforeground white
    lappend x [.t cget -selectforeground]
    return $x
} -result {yellow blue red white}

test textTag-6.1 {TkTextTagCmd - "delete" option} -body {
    .t tag delete
} -returnCodes error -result {wrong # args: should be ".t tag delete tagName ?tagName ...?"}
test textTag-6.2 {TkTextTagCmd - "delete" option} -body {
    .t tag delete zork
} -returnCodes ok -result {}
test textTag-6.3 {TkTextTagCmd - "delete" option} -setup {
    .t tag delete {*}[.t tag names]
} -body {
    .t tag config x -background black
    .t tag config y -foreground white
    .t tag config z -background black
    .t tag delete y z
    lsort [.t tag names]
} -cleanup {
    .t tag delete x
} -result {sel x}
test textTag-6.4 {TkTextTagCmd - "delete" option} -setup {
    .t tag delete {*}[.t tag names]
} -body {
    .t tag config x -background black
    .t tag config y -foreground white
    .t tag config z -background black
    eval .t tag delete [.t tag names]
    .t tag names
} -result {sel}
test textTag-6.5 {TkTextTagCmd - "delete" option} -body {
    .t tag bind x <Enter> foo
    .t tag delete x
    .t tag configure x -background black
    .t tag bind x

} -cleanup {

    .t tag delete x

} -result {}



test textTag-7.1 {TkTextTagCmd - "lower" option} -body {
    .t tag lower
} -returnCodes error -result {wrong # args: should be ".t tag lower tagName ?belowThis?"}
test textTag-7.2 {TkTextTagCmd - "lower" option} -body {
    .t tag lower foo
} -returnCodes error -result {tag "foo" isn't defined in text widget}
test textTag-7.3 {TkTextTagCmd - "lower" option} -body {
    .t tag lower sel bar
} -returnCodes error -result {tag "bar" isn't defined in text widget}
test textTag-7.4 {TkTextTagCmd - "lower" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag lower c
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {c sel a b d}
test textTag-7.5 {TkTextTagCmd - "lower" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag lower d b
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel a d b c}
test textTag-7.6 {TkTextTagCmd - "lower" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag lower a c
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel b a c d}


test textTag-8.1 {TkTextTagCmd - "names" option} -body {
    .t tag names a b
} -cleanup {
    .t tag delete {*}[.t tag names]
} -returnCodes error -result {wrong # args: should be ".t tag names ?index?"}
test textTag-8.2 {TkTextTagCmd - "names" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel a b c d}
test textTag-8.3 {TkTextTagCmd - "names" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag add "a b" 2.1 2.6
    .t tag add c 2.4 2.7
    .t tag names 2.5
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {c {a b}}





test textTag-9.1 {TkTextTagCmd - "nextrange" option} -body {
    .t tag nextrange x
} -returnCodes error -result {wrong # args: should be ".t tag nextrange tagName index1 ?index2?"}
test textTag-9.2 {TkTextTagCmd - "nextrange" option} -body {
    .t tag nextrange x 1 2 3
} -returnCodes error -result {wrong # args: should be ".t tag nextrange tagName index1 ?index2?"}
test textTag-9.3 {TkTextTagCmd - "nextrange" option} -body {
    .t tag nextrange foo 1.0
} -returnCodes ok -result {}
test textTag-9.4 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag nextrange x foo
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad text index "foo"}
test textTag-9.5 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 1.0 bar
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad text index "bar"}
test textTag-9.6 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 1.0
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-9.7 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.2
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-9.8 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.3
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-9.9 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.4
} -cleanup {
    .t tag delete x
} -result {2.9 3.1}
test textTag-9.10 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.4 2.9
} -cleanup {
    .t tag delete x
} -result {}
test textTag-9.11 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.4 2.10
} -cleanup {
    .t tag delete x
} -result {2.9 3.1}
test textTag-9.12 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 2.4 2.11
} -cleanup {
    .t tag delete x
} -result {2.9 3.1}
test textTag-9.13 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 7.0
} -cleanup {
    .t tag delete x
} -result {7.2 7.3}
test textTag-9.14 {TkTextTagCmd - "nextrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag nextrange x 7.3
} -cleanup {
    .t tag delete x
} -result {}


test textTag-10.1 {TkTextTagCmd - "prevrange" option} -body {
    .t tag prevrange x
} -returnCodes error -result {wrong # args: should be ".t tag prevrange tagName index1 ?index2?"}
test textTag-10.2 {TkTextTagCmd - "prevrange" option} -body {
    .t tag prevrange x 1 2 3
} -returnCodes error -result {wrong # args: should be ".t tag prevrange tagName index1 ?index2?"}
test textTag-10.3 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag prevrange foo end
} -cleanup {
    .t tag delete x
} -returnCodes ok -result {}
test textTag-10.4 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x foo
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad text index "foo"}
test textTag-10.5 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x end bar
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad text index "bar"}
test textTag-10.6 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x end
} -cleanup {
    .t tag delete x
} -result {7.2 7.3}
test textTag-10.7 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.4
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-10.8 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.5
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-10.9 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.9
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-10.10 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.9 2.6
} -cleanup {
    .t tag delete x
} -result {}
test textTag-10.11 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.9 2.5
} -cleanup {
    .t tag delete x
} -result {}
test textTag-10.12 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.9 2.3
} -cleanup {
    .t tag delete x
} -result {2.3 2.5}
test textTag-10.13 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 7.0
} -cleanup {
    .t tag delete x
} -result {2.9 3.1}
test textTag-10.14 {TkTextTagCmd - "prevrange" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.3 2.5
    .t tag add x 2.9 3.1
    .t tag add x 7.2
    .t tag prevrange x 2.3
} -cleanup {
    .t tag delete x
} -result {}


test textTag-11.1 {TkTextTagCmd - "raise" option} -body {
    .t tag raise
} -returnCodes error -result {wrong # args: should be ".t tag raise tagName ?aboveThis?"}
test textTag-11.2 {TkTextTagCmd - "raise" option} -body {
    .t tag raise foo
} -returnCodes error -result {tag "foo" isn't defined in text widget}
test textTag-11.3 {TkTextTagCmd - "raise" option} -body {
    .t tag raise sel bar
} -returnCodes error -result {tag "bar" isn't defined in text widget}
test textTag-11.4 {TkTextTagCmd - "raise" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag raise c
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel a b d c}
test textTag-11.5 {TkTextTagCmd - "raise" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag raise d b
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel a b d c}
test textTag-11.6 {TkTextTagCmd - "raise" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
    .t tag raise a c
    .t tag names
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {sel b c a d}


test textTag-12.1 {TkTextTagCmd - "ranges" option} -body {
    .t tag ranges
} -returnCodes error -result {wrong # args: should be ".t tag ranges tagName"}
test textTag-12.2 {TkTextTagCmd - "ranges" option} -body {
    .t tag delete x
    .t tag ranges x
} -result {}
test textTag-12.3 {TkTextTagCmd - "ranges" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.2
    .t tag add x 2.7 4.15
    .t tag add x 5.2 5.5
    .t tag ranges x
} -cleanup {
    .t tag delete x
} -result {2.2 2.3 2.7 4.6 5.2 5.5}
test textTag-12.4 {TkTextTagCmd - "ranges" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 1.0 3.0
    .t tag add x 4.0 end
    .t tag ranges x
} -cleanup {
    .t tag delete x
} -result {1.0 3.0 4.0 8.0}


test textTag-13.1 {TkTextTagCmd - "remove" option} -body {
    .t tag remove
} -returnCodes error -result {wrong # args: should be ".t tag remove tagName index1 ?index2 index1 index2 ...?"}
test textTag-13.2 {TkTextTagCmd - "remove" option} -setup {
    .t tag delete x
} -body {
    .t tag add x 2.2 2.11
    .t tag remove x 2.3 2.7
    .t tag ranges x
} -cleanup {
    .t tag delete x
} -result {2.2 2.3 2.7 2.11}
test textTag-13.3 {TkTextTagCmd - "remove" option} -setup {
    destroy .t.e
} -body {
    entry .t.e
    .t.e insert 0 "Text"
    .t configure -exportselection 1
    .t tag remove sel 1.0 end
    .t tag add sel 2.4 3.3
    .t.e select to 4
    .t tag remove sel 2.7 3.1
    selection get
} -cleanup {
    destroy .t.e
} -result {Text}


test textTag-14.1 {SortTags} -setup {
    .t tag delete a b c d
} -body {
    foreach i {a b c d} {
        .t tag add $i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete a b c d
} -result {a b c d}
.t tag delete a b c d
test textTag-14.2 {SortTags} -setup {
    .t tag delete a b c d
} -body {
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
    foreach i {d c b a} {
        .t tag add $i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete a b c d
} -result {a b c d}
test textTag-14.3 {SortTags} -setup {
    .t tag delete {*}[.t tag names]
} -body {
    for {set i 0} {$i < 30} {incr i} {
        .t tag add x$i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}
test textTag-14.4 {SortTags} -setup {
    .t tag delete {*}[.t tag names]
} -body {
    for {set i 0} {$i < 30} {incr i} {
        .t tag configure x$i -background black
    }
    for {set i 29} {$i >= 0} {incr i -1} {
        .t tag add x$i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}




set curFont [.t cget -font]
set curWrap [.t cget -wrap]
set c [.t bbox 2.1]
set x1 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y1 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 3.2]
set x2 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y2 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 4.3]
set x3 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y3 [expr {[lindex $c 1] + [lindex $c 3]/2}]
.t configure -font $textWidgetFont -wrap none
update
set c [.t bbox 2.1]
set x4 [expr [lindex $c 0] + [lindex $c 2]/2]
set y4 [expr [lindex $c 1] + [lindex $c 3]/2]
set c [.t bbox 3.2]
set x5 [expr [lindex $c 0] + [lindex $c 2]/2]
set y5 [expr [lindex $c 1] + [lindex $c 3]/2]
.t configure -font $curFont -wrap $curWrap

test textTag-15.1 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    bind .t <ButtonRelease> {lappend x up}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Button> -x $x1 -y $y1
    event gen .t <Motion> -x $x1 -y $y1
    event gen .t <ButtonRelease> -x $x1 -y $y1
    event gen .t <Button> -x $x1 -y $y1
    event gen .t <Motion> -x $x2 -y $y2
    event gen .t <ButtonRelease> -x $x2 -y $y2
    event gen .t <Button> -x $x2 -y $y2
    event gen .t <Motion> -x $x3 -y $y3
    event gen .t <ButtonRelease> -x $x3 -y $y3
    return $x
} -cleanup {
    .t tag delete x y
    bind .t <ButtonRelease> {}

} -result {x-up up up y-up up}

test textTag-15.2 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {

    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button> {lappend x x-down}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button> {lappend x y-down}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    .t tag bind y <Leave> {lappend x y-leave}
    event gen .t <Motion> -x 0 -y 0
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Motion> -x $x1 -y $y1
    lappend x |
    event gen .t <Button> -x $x1 -y $y1
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x |
    event gen .t <ButtonRelease> -x $x3 -y $y3
    return $x
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | x-up x-leave y-enter}

test textTag-15.3 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button-1> {lappend x x-down}
    .t tag bind x <ButtonRelease-1> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button-1> {lappend x y-down}
    .t tag bind y <ButtonRelease-1> {lappend x y-up}
    .t tag bind y <Leave> {lappend x y-leave}
    event gen .t <Motion> -x 0 -y 0
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Motion> -x $x1 -y $y1
    lappend x |
    event gen .t <Button-1> -x $x1 -y $y1
    lappend x |
    event gen .t <Button-2> -x $x1 -y $y1 -state 0x100
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3  -state 0x300
    lappend x |
    event gen .t <ButtonRelease-1> -x $x3 -y $y3 -state 0x300
    lappend x |
    event gen .t <ButtonRelease-2> -x $x3 -y $y3 -state 0x200
    return $x
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | | x-up | x-leave y-enter}





test textTag-16.1 {TkTextPickCurrent procedure} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    set x [.t index current]
    event gen .t <Motion> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Button-1> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x [.t index current]
    event gen .t <Button-3> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-3> -state 0x300 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-1> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
} -result {2.1 3.2 3.2 3.2 3.2 3.2 4.3}

test textTag-16.2 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    event gen .t <ButtonRelease-1> -state 0x100 -x $x4 -y $y4
    event gen .t <Motion> -x $x5 -y $y5
    set x [.t index current]
    .t tag add big 3.0
    update
    lappend x [.t index current]
} -cleanup {
    .t tag delete big
    .t configure -font $curFont -wrap $curWrap
} -result {3.2 3.1}

test textTag-16.3 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end

    }
    wm geometry . +200+200 ; update

    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a
    set x {}
    event gen .t <Motion> -x $x1 -y $y1
    .t tag add a 2.1 3.3
    .t tag add b 2.1
    .t tag add c 3.2
    update
    lappend x |
    event gen .t <Motion> -x $x2 -y $y2
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3
    return $x
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {enter-a enter-b | leave-b enter-c | leave-a leave-c}

test textTag-16.4 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a
    set x {}
    event gen .t <Motion> -x $x1 -y $y1
    .t tag add a 2.1 3.3
    .t tag add b 2.1
    .t tag add c 2.1
    update
    lappend x |
    .t tag lower c
    event gen .t <Motion> -x $x2 -y $y2
    return $x

} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {enter-a enter-b enter-c | leave-c leave-b}

test textTag-16.5 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x5 -y $y5
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.2}

test textTag-16.6 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {

    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x5 -y $y5
    update
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.1}

test textTag-16.7 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {

    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2

    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Leave> {.t tag add big 3.0 3.2}
    .t tag add a 2.1
    event gen .t <Motion> -x $x5 -y $y5
    update
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.1}


test textTag-17.1 {insert procedure inserts tags} -setup {
    .t delete 1.0 end
} -body {
    # Objectification of the text widget had a problem
    # with inserting tags when using 'end'. Check that
    # bug has been fixed.
    .t insert end abcd {x} \n {} efgh {y} \n {}
    .t dump -tag 1.0 end
} -result {tagon x 1.0 tagoff x 1.4 tagon y 2.0 tagoff y 2.4}



test textTag-18.1 {TkTextPickCurrent tag bindings} -setup {
    destroy .t
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \



|
|
|



<


|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
>
>
|


<

>









>
>
>








|
<
|
<
<
<
|
|
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
|
>
|
<
>
>
|
<
<
>
>
|
|
|
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
>
<
<
<
<
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
>
>
|
<
<
|
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
>
|
|
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<



|
|
<
<


<
<
|
|

<


<
<
|
|
<
<
<
<




|
<
<
|
<
<
<
<





<
<
|
|



|
|



<
<
|
|











|

|
|
|
|
|
|
|
|


<
<
|
|
|
|
|


|
<
<
|
|
<
<
<
<
<
<
<
<





<
<
|
|




<
<
|

|

|
|
<
<
|

|
<
<
|

<
|
|
|
|
|
|
|

|
|
|
|
|
|


|
<
<
|

<
|
|
|
|
|
|
|
|
<
<
|
|



<
<
|
<
<
<
<
<
<
<
|



<
<
|
<
<
<
<
<
<
<
|
|
<
<
|
|

|
<
<
|
|



<
<
|
|

|
<
<
|
|

|
<
<
|
|



<
<
|
|

|
<
<
|
|

|
<

<
|
<
<
|
<
<
<
|

|
<
<
|
|

|
<
<
|
<
<
<
<
<
<
|

|
<
<
|
<
|
<
<
<
<
<
|



|
<
<
|
|

|
<
<
|
|

|
<
<
|
|

|
<
<
|
|

|



|

|
|
|



<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
|
|
|
|
|
|
<





<
<
|
|
<
<





|
|




>
|
>
|
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<


<
<
|
|
<
|
<
<
<
<


<
<
|
|
<
|
<
<
<
<


<
<
|

<
|
|
<
<
|
|
<
|
<
<
<
<

<
<
|
|
<
|
<
<
<
<



<
<
|

|
>
>
>
|
|
|
|
|
|
|
|
|
|
<
<
<
|
<
<
|
|
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

|
<
<
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
<
|

|
|
|
|
|
|
|
<
<
|
|
<
<
|
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<
|
<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

|
<
<
|
<
<
<
<
<

|
<
<
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
|
|
<
<
<
<
<

<
<
<
|

|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<


<
<
|
|
<
|
<
<
<
<


<
<
|
|
<
|
<
<
<
<


<
<
|

<
|
|
|
|


|
|

<




<
<
|
|

<



<
<
|

<
|
|
|
|

<



<
<
|
|
<
<
<
<






<
<
|

|
|
<
<

|


<
<
|

|
<
<

|


|


|
|
<
|
<
<

|


<
<
|
|
<
<

|


|


<
<
|

>
>
|
<
<

|
|

<
<
<
<
<
<
<
<
|
|
|
|
|
<

|
<
<
|
<















<
<
<

>
|
<
|
<
<
|
|
>

|



|













|
<
<
|
<
|
|
<
<
|

|
|


|
|
















|
<
<
|

>
>
|
>
|
<
<
|
<














|
<
|
<
<
<
<
|
<
<
<
|
|




<
<
<
|
|
<
|
|
>
|
<
>
|
<

|
<













|
<
<
|
<
|
<
<
<
<
|
<

|
<












|
>
|
|
<
|
|
|
<
|
|

<
<
<
<
<
|


|

<
<
<
|
<
|
<
<
>
|
|

<
<
<
<
<
|


|


<
<
<
|
<
|
<
<
>
|
|

<
<
<
<
<
<
<
<
|


|
<

<
<
<
|

<
|

<





|

>







1
2
3
4
5
6
7
8
9

10
11
12


13















14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45



46
47


48

49








50

51








52

53








54

55
56




57








58

59
60
61
62

63
64
65


66
67
68
69
70


71







72





73




74










75




76



77


78







79
80
81


82



83
84






85











86
87

88








89

90

91



























92


93


94
95
96


97
98






















































99



100
101
102
103
104
105
106
107
108
109
110
111
112
113


114
115
116
117
118


119
120


121
122
123

124
125


126
127




128
129
130
131
132


133




134
135
136
137
138


139
140
141
142
143
144
145
146
147
148


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
181


182
183








184
185
186
187
188


189
190
191
192
193
194


195
196
197
198
199
200


201
202
203


204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222


223
224

225
226
227
228
229
230
231
232


233
234
235
236
237


238







239
240
241
242


243







244
245


246
247
248
249


250
251
252
253
254


255
256
257
258


259
260
261
262


263
264
265
266
267


268
269
270
271


272
273
274
275

276

277


278



279
280
281


282
283
284
285


286






287
288
289


290

291





292
293
294
295
296


297
298
299
300


301
302
303
304


305
306
307
308


309
310
311
312
313
314
315
316
317
318
319
320
321
322
323


324












































325
326
327
328
329
330
331
332
333

334
335
336
337
338


339
340


341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371




372
373


374
375

376




377
378


379
380

381




382
383


384
385

386
387


388
389

390




391


392
393

394




395
396
397


398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413



414


415
416





417


418
419





420


421
422





423


424
425





426


427
428





429


430
431





432
433


434





435


436
437





438


439
440





441


442
443





444



445
446
447
448
449
450
451
452
453


454
455


456





457


458
459





460


461
462





463


464
465





466


467
468





469


470
471





472


473
474





475
476


477





478
479


480





481


482
483





484


485
486





487



488
489
490
491
492
493
494
495
496
497
498
499

500




501
502


503
504

505




506
507


508
509

510




511
512


513
514

515
516
517
518
519
520
521
522
523

524
525
526
527


528
529
530

531
532
533


534
535

536
537
538
539
540

541
542
543


544
545




546
547
548
549
550
551


552
553
554
555


556
557
558
559


560
561
562


563
564
565
566
567
568
569
570
571

572


573
574
575
576


577
578


579
580
581
582
583
584
585


586
587
588
589
590


591
592
593
594








595
596
597
598
599

600
601


602

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617



618
619
620

621


622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644


645

646
647


648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672


673
674
675
676
677
678
679


680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

696




697



698
699
700
701
702
703



704
705

706
707
708
709

710
711

712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727


728

729




730

731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751

752
753
754





755
756
757
758
759



760

761


762
763
764
765





766
767
768
769
770
771



772

773


774
775
776
777








778
779
780
781

782



783
784

785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
# This file is a Tcl script to test the code in the file tkTextTag.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


















catch {destroy .t}
text .t -width 20 -height 10
testConstraint haveCourier12 [expr {[catch {
    .t configure -font {Courier 12}
}] == 0}]
pack append . .t {top expand fill}
update
.t debug on

wm geometry . {}
set bigFont {Helvetica 24}

# The statements below reset the main window;  it's needed if the window
# manager is mwm, to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

entry .t.e
.t.e insert 0 "Text"

.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"



set i 1



foreach test {
    {-background #012345 #012345 non-existent


	    {unknown color name "non-existent"}}

    {-bgstipple gray50 gray50 badStipple








	    {bitmap "badStipple" not defined}}

    {-borderwidth 2 2 46q








	    {bad screen distance "46q"}}

    {-fgstipple gray25 gray25 bogus








	    {bitmap "bogus" not defined}}

    {-font fixed fixed {}
	    {font "" doesn't exist}}




    {-foreground #001122 #001122 {silly color}








	    {unknown color name "silly color"}}

    {-justify left left middle
	    {bad justification "middle": must be left, right, or center}}
    {-lmargin1 10 10 bad
	    {bad screen distance "bad"}}

    {-lmargin2 10 10 bad
	    {bad screen distance "bad"}}
    {-offset 2 2 100xyz


	    {bad screen distance "100xyz"}}
    {-overstrike on on stupid
	    {expected boolean value but got "stupid"}}
    {-relief raised raised stupid
	    {bad relief type "stupid": must be flat, groove, raised, ridge, solid, or sunken}}


    {-rmargin 10 10 bad







	    {bad screen distance "bad"}}





    {-spacing1 10 10 bad




	    {bad screen distance "bad"}}










    {-spacing2 10 10 bad




	    {bad screen distance "bad"}}



    {-spacing3 10 10 bad


	    {bad screen distance "bad"}}







    {-tabs {10 20 30} {10 20 30} {10 fork}
	    {bad tab alignment "fork": must be left, right, center, or numeric}}
    {-underline no no stupid


	    {expected boolean value but got "stupid"}}



} {
    set name [lindex $test 0]






    test textTag-1.$i {tag configuration options} haveCourier12 {











	.t tag configure x $name [lindex $test 1]
	.t tag cget x $name

    } [lindex $test 2]








    incr i

    if {[lindex $test 3] != ""} {

	test textTag-1.$i {configuration options} haveCourier12 {



























	    list [catch {.t tag configure x $name [lindex $test 3]} msg] $msg


	} [list 1 [lindex $test 4]]


    }
    .t tag configure x $name [lindex [.t tag configure x $name] 3]
    incr i


}
test textTag-2.1 {TkTextTagCmd - "add" option} haveCourier12 {






















































    list [catch {.t tag} msg] $msg



} {1 {wrong # args: should be ".t tag option ?arg arg ...?"}}
test textTag-2.2 {TkTextTagCmd - "add" option} haveCourier12 {
    list [catch {.t tag gorp} msg] $msg
} {1 {bad tag option "gorp": must be add, bind, cget, configure, delete, lower, names, nextrange, prevrange, raise, ranges, or remove}}
test textTag-2.3 {TkTextTagCmd - "add" option} haveCourier12 {
    list [catch {.t tag add foo} msg] $msg
} {1 {wrong # args: should be ".t tag add tagName index1 ?index2 index1 index2 ...?"}}
test textTag-2.4 {TkTextTagCmd - "add" option} haveCourier12 {
    list [catch {.t tag add x gorp} msg] $msg
} {1 {bad text index "gorp"}}
test textTag-2.5 {TkTextTagCmd - "add" option} haveCourier12 {
    list [catch {.t tag add x 1.2 gorp} msg] $msg
} {1 {bad text index "gorp"}}
test textTag-2.6 {TkTextTagCmd - "add" option} haveCourier12 {


    .t tag add sel 3.2 3.4
    .t tag add sel 3.2 3.0
    .t tag ranges sel
} {3.2 3.4}
test textTag-2.7 {TkTextTagCmd - "add" option} haveCourier12 {


    .t tag add x 1.0 1.end
    .t tag ranges x


} {1.0 1.6}
test textTag-2.8 {TkTextTagCmd - "add" option} haveCourier12 {
    .t tag remove x 1.0 end

    .t tag add x 1.2
    .t tag ranges x


} {1.2 1.3}
test textTag-2.9 {TkTextTagCmd - "add" option} haveCourier12 {




    .t.e select from 0
    .t.e select to 4
    .t tag add sel 3.2 3.4
    selection get
} 34


test textTag-2.11 {TkTextTagCmd - "add" option} haveCourier12 {




    .t.e select from 0
    .t.e select to 4
    .t configure -exportselection 0
    .t tag add sel 3.2 3.4
    selection get


} Text
test textTag-2.12 {TkTextTagCmd - "add" option} haveCourier12 {
    .t tag remove sel 1.0 end
    .t tag add sel 1.1 1.5 2.4 3.1 4.2 4.4
    .t tag ranges sel
} {1.1 1.5 2.4 3.1 4.2 4.4}
test textTag-2.13 {TkTextTagCmd - "add" option} haveCourier12 {
    .t tag remove sel 1.0 end
    .t tag add sel 1.1 1.5 2.4
    .t tag ranges sel


} {1.1 1.5 2.4 2.5}
test textTag-2.14 {tag add before -startline - Bug 1615425} haveCourier12 {
    text .tt
    for {set i 1} {$i <10} {incr i} {
        .tt insert end "Line $i\n"
    }
    .tt tag configure mytag -font {Courier 12 bold}
    .tt peer create .ptt
    .ptt configure -startline 3 -endline 7
    # the test succeeds if next line does not crash
    .tt tag add mytag 1.0 1.end
    destroy .ptt .tt
    set res 1
} {1}

catch {.t tag delete x}
test textTag-3.1 {TkTextTagCmd - "bind" option} haveCourier12 {
    list [catch {.t tag bind} msg] $msg
} {1 {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}}
test textTag-3.2 {TkTextTagCmd - "bind" option} haveCourier12 {
    list [catch {.t tag bind 1 2 3 4} msg] $msg
} {1 {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}}
test textTag-3.3 {TkTextTagCmd - "bind" option} haveCourier12 {
    .t tag bind x <Enter> script1
    .t tag bind x <Enter>


} script1
test textTag-3.4 {TkTextTagCmd - "bind" option} haveCourier12 {
    list [catch {.t tag bind x <Gorp> script2} msg] $msg
} {1 {bad event type or keysym "Gorp"}}
test textTag-3.5 {TkTextTagCmd - "bind" option} haveCourier12 {
    .t tag delete x
    .t tag bind x <Enter> script1
    list [catch {.t tag bind x <FocusIn> script2} msg] $msg [.t tag bind x]


} {1 {requested illegal events; only key, button, motion, enter, leave, and virtual events may be used} <Enter>}
test textTag-3.6 {TkTextTagCmd - "bind" option} haveCourier12 {








    .t tag delete x
    .t tag bind x <Enter> script1
    .t tag bind x <Leave> script2
    .t tag bind x a xyzzy
    list [lsort [.t tag bind x]] [.t tag bind x <Enter>] [.t tag bind x a]


} {{<Enter> <Leave> a} script1 xyzzy}
test textTag-3.7 {TkTextTagCmd - "bind" option} haveCourier12 {
    .t tag delete x
    .t tag bind x <Enter> script1
    .t tag bind x <Enter> +script2
    .t tag bind x <Enter>


} {script1
script2}
test textTag-3.7a {TkTextTagCmd - "bind" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag bind x <Enter>} msg] $msg
} {0 {}}


test textTag-3.8 {TkTextTagCmd - "bind" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag bind x <} msg] $msg


} {1 {no event type or button # or keysym}}


test textTag-4.1 {TkTextTagCmd - "cget" option} haveCourier12 {
    list [catch {.t tag cget a} msg] $msg
} {1 {wrong # args: should be ".t tag cget tagName option"}}
test textTag-4.2 {TkTextTagCmd - "cget" option} haveCourier12 {
    list [catch {.t tag cget a b c} msg] $msg
} {1 {wrong # args: should be ".t tag cget tagName option"}}
test textTag-4.3 {TkTextTagCmd - "cget" option} haveCourier12 {
    .t tag delete foo
    list [catch {.t tag cget foo bar} msg] $msg
} {1 {tag "foo" isn't defined in text widget}}
test textTag-4.4 {TkTextTagCmd - "cget" option} haveCourier12 {
    list [catch {.t tag cget sel bogus} msg] $msg
} {1 {unknown option "bogus"}}
test textTag-4.5 {TkTextTagCmd - "cget" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -background red
    list [catch {.t tag cget x -background} msg] $msg


} {0 red}


test textTag-5.1 {TkTextTagCmd - "configure" option} haveCourier12 {
    list [catch {.t tag configure} msg] $msg
} {1 {wrong # args: should be ".t tag configure tagName ?option? ?value? ?option value ...?"}}
test textTag-5.2 {TkTextTagCmd - "configure" option} haveCourier12 {
    list [catch {.t tag configure x -foo} msg] $msg
} {1 {unknown option "-foo"}}
test textTag-5.3 {TkTextTagCmd - "configure" option} haveCourier12 {
    list [catch {.t tag configure x -background red -underline} msg] $msg


} {1 {value for "-underline" missing}}
test textTag-5.4 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -underline yes
    .t tag configure x -underline


} {-underline {} {} {} yes}







test textTag-5.5 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -overstrike on
    .t tag cget x -overstrike


} {on}







test textTag-5.6 {TkTextTagCmd - "configure" option} haveCourier12 {
    list [catch {.t tag configure x -overstrike foo} msg] $msg


} {1 {expected boolean value but got "foo"}}
test textTag-5.7 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -underline stupid} msg] $msg


} {1 {expected boolean value but got "stupid"}}
test textTag-5.8 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -justify left
    .t tag configure x -justify


} {-justify {} {} {} left}
test textTag-5.9 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -justify bogus} msg] $msg


} {1 {bad justification "bogus": must be left, right, or center}}
test textTag-5.10 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -justify fill} msg] $msg


} {1 {bad justification "fill": must be left, right, or center}}
test textTag-5.11 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -offset 2
    .t tag configure x -offset


} {-offset {} {} {} 2}
test textTag-5.12 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -offset 1.0q} msg] $msg


} {1 {bad screen distance "1.0q"}}
test textTag-5.13 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5

    list [.t tag configure x -lmargin1] [.t tag configure x -lmargin2] \

	    [.t tag configure x -rmargin]


} {{-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} {-rmargin {} {} {} 5}}



test textTag-5.14 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -lmargin1 2.0x} msg] $msg


} {1 {bad screen distance "2.0x"}}
test textTag-5.15 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -lmargin2 gorp} msg] $msg


} {1 {bad screen distance "gorp"}}






test textTag-5.16 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -rmargin 140.1.1} msg] $msg


} {1 {bad screen distance "140.1.1"}}

.t tag delete x





test textTag-5.17 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    .t tag configure x -spacing1 2 -spacing2 4 -spacing3 6
    list [.t tag configure x -spacing1] [.t tag configure x -spacing2] \
	    [.t tag configure x -spacing3]


} {{-spacing1 {} {} {} 2} {-spacing2 {} {} {} 4} {-spacing3 {} {} {} 6}}
test textTag-5.18 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -spacing1 2.0x} msg] $msg


} {1 {bad screen distance "2.0x"}}
test textTag-5.19 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -spacing1 lousy} msg] $msg


} {1 {bad screen distance "lousy"}}
test textTag-5.20 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t tag delete x
    list [catch {.t tag configure x -spacing1 4.2.3} msg] $msg


} {1 {bad screen distance "4.2.3"}}
test textTag-5.21 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t configure -selectborderwidth 2 -selectforeground blue \
	    -selectbackground black
    .t tag configure sel -borderwidth 4 -foreground green -background yellow
    set x {}
    foreach i {-selectborderwidth -selectforeground -selectbackground} {
	lappend x [lindex [.t configure $i] 4]
    }
    set x
} {4 green yellow}
test textTag-5.22 {TkTextTagCmd - "configure" option} haveCourier12 {
    .t configure -selectborderwidth 20
    .t tag configure sel -borderwidth {}
    .t cget -selectborderwidth


} {}













































test textTag-6.1 {TkTextTagCmd - "delete" option} haveCourier12 {
    list [catch {.t tag delete} msg] $msg
} {1 {wrong # args: should be ".t tag delete tagName ?tagName ...?"}}
test textTag-6.2 {TkTextTagCmd - "delete" option} haveCourier12 {
    list [catch {.t tag delete zork} msg] $msg
} {0 {}}
test textTag-6.3 {TkTextTagCmd - "delete" option} haveCourier12 {
    .t tag delete x

    .t tag config x -background black
    .t tag config y -foreground white
    .t tag config z -background black
    .t tag delete y z
    lsort [.t tag names]


} {sel x}
test textTag-6.4 {TkTextTagCmd - "delete" option} haveCourier12 {


    .t tag config x -background black
    .t tag config y -foreground white
    .t tag config z -background black
    eval .t tag delete [.t tag names]
    .t tag names
} {sel}
test textTag-6.5 {TkTextTagCmd - "delete" option} haveCourier12 {
    .t tag bind x <Enter> foo
    .t tag delete x
    .t tag configure x -background black
    .t tag bind x
} {}

proc tagsetup {} {
    .t tag delete x y z a b c d
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
	.t tag configure $i -background black
    }
}
test textTag-7.1 {TkTextTagCmd - "lower" option} haveCourier12 {
    list [catch {.t tag lower} msg] $msg
} {1 {wrong # args: should be ".t tag lower tagName ?belowThis?"}}
test textTag-7.2 {TkTextTagCmd - "lower" option} haveCourier12 {
    list [catch {.t tag lower foo} msg] $msg
} {1 {tag "foo" isn't defined in text widget}}
test textTag-7.3 {TkTextTagCmd - "lower" option} haveCourier12 {
    list [catch {.t tag lower sel bar} msg] $msg
} {1 {tag "bar" isn't defined in text widget}}
test textTag-7.4 {TkTextTagCmd - "lower" option} haveCourier12 {

    tagsetup




    .t tag lower c
    .t tag names


} {c sel a b d}
test textTag-7.5 {TkTextTagCmd - "lower" option} haveCourier12 {

    tagsetup




    .t tag lower d b
    .t tag names


} {sel a d b c}
test textTag-7.6 {TkTextTagCmd - "lower" option} haveCourier12 {

    tagsetup




    .t tag lower a c
    .t tag names


} {sel b a c d}


test textTag-8.1 {TkTextTagCmd - "names" option} haveCourier12 {
    list [catch {.t tag names a b} msg] $msg


} {1 {wrong # args: should be ".t tag names ?index?"}}
test textTag-8.2 {TkTextTagCmd - "names" option} haveCourier12 {

    tagsetup




    .t tag names


} {sel a b c d}
test textTag-8.3 {TkTextTagCmd - "names" option} haveCourier12 {

    tagsetup




    .t tag add "a b" 2.1 2.6
    .t tag add c 2.4 2.7
    .t tag names 2.5


} {c {a b}}

.t tag delete x y z a b c d {a b}
.t tag add x 2.3 2.5
.t tag add x 2.9 3.1
.t tag add x 7.2
test textTag-9.1 {TkTextTagCmd - "nextrange" option} haveCourier12 {
    list [catch {.t tag nextrange x} msg] $msg
} {1 {wrong # args: should be ".t tag nextrange tagName index1 ?index2?"}}
test textTag-9.2 {TkTextTagCmd - "nextrange" option} haveCourier12 {
    list [catch {.t tag nextrange x 1 2 3} msg] $msg
} {1 {wrong # args: should be ".t tag nextrange tagName index1 ?index2?"}}
test textTag-9.3 {TkTextTagCmd - "nextrange" option} haveCourier12 {
    list [catch {.t tag nextrange foo 1.0} msg] $msg
} {0 {}}
test textTag-9.4 {TkTextTagCmd - "nextrange" option} haveCourier12 {



    list [catch {.t tag nextrange x foo} msg] $msg


} {1 {bad text index "foo"}}
test textTag-9.5 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    list [catch {.t tag nextrange x 1.0 bar} msg] $msg


} {1 {bad text index "bar"}}
test textTag-9.6 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 1.0


} {2.3 2.5}
test textTag-9.7 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.2


} {2.3 2.5}
test textTag-9.8 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.3


} {2.3 2.5}
test textTag-9.9 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.4


} {2.9 3.1}
test textTag-9.10 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.4 2.9
} {}


test textTag-9.11 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.4 2.10


} {2.9 3.1}
test textTag-9.12 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 2.4 2.11


} {2.9 3.1}
test textTag-9.13 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 7.0


} {7.2 7.3}
test textTag-9.14 {TkTextTagCmd - "nextrange" option} haveCourier12 {





    .t tag nextrange x 7.3



} {}

test textTag-10.1 {TkTextTagCmd - "prevrange" option} haveCourier12 {
    list [catch {.t tag prevrange x} msg] $msg
} {1 {wrong # args: should be ".t tag prevrange tagName index1 ?index2?"}}
test textTag-10.2 {TkTextTagCmd - "prevrange" option} haveCourier12 {
    list [catch {.t tag prevrange x 1 2 3} msg] $msg
} {1 {wrong # args: should be ".t tag prevrange tagName index1 ?index2?"}}
test textTag-10.3 {TkTextTagCmd - "prevrange" option} haveCourier12 {


    list [catch {.t tag prevrange foo end} msg] $msg
} {0 {}}


test textTag-10.4 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    list [catch {.t tag prevrange x foo} msg] $msg


} {1 {bad text index "foo"}}
test textTag-10.5 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    list [catch {.t tag prevrange x end bar} msg] $msg


} {1 {bad text index "bar"}}
test textTag-10.6 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x end


} {7.2 7.3}
test textTag-10.7 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.4


} {2.3 2.5}
test textTag-10.8 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.5


} {2.3 2.5}
test textTag-10.9 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.9


} {2.3 2.5}
test textTag-10.10 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.9 2.6
} {}


test textTag-10.11 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.9 2.5
} {}


test textTag-10.12 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.9 2.3


} {2.3 2.5}
test textTag-10.13 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 7.0


} {2.9 3.1}
test textTag-10.14 {TkTextTagCmd - "prevrange" option} haveCourier12 {





    .t tag prevrange x 2.3



} {}

test textTag-11.1 {TkTextTagCmd - "raise" option} haveCourier12 {
    list [catch {.t tag raise} msg] $msg
} {1 {wrong # args: should be ".t tag raise tagName ?aboveThis?"}}
test textTag-11.2 {TkTextTagCmd - "raise" option} haveCourier12 {
    list [catch {.t tag raise foo} msg] $msg
} {1 {tag "foo" isn't defined in text widget}}
test textTag-11.3 {TkTextTagCmd - "raise" option} haveCourier12 {
    list [catch {.t tag raise sel bar} msg] $msg
} {1 {tag "bar" isn't defined in text widget}}
test textTag-11.4 {TkTextTagCmd - "raise" option} haveCourier12 {

    tagsetup




    .t tag raise c
    .t tag names


} {sel a b d c}
test textTag-11.5 {TkTextTagCmd - "raise" option} haveCourier12 {

    tagsetup




    .t tag raise d b
    .t tag names


} {sel a b d c}
test textTag-11.6 {TkTextTagCmd - "raise" option} haveCourier12 {

    tagsetup




    .t tag raise a c
    .t tag names


} {sel b c a d}


test textTag-12.1 {TkTextTagCmd - "ranges" option} haveCourier12 {
    list [catch {.t tag ranges} msg] $msg
} {1 {wrong # args: should be ".t tag ranges tagName"}}
test textTag-12.2 {TkTextTagCmd - "ranges" option} haveCourier12 {
    .t tag delete x
    .t tag ranges x
} {}
test textTag-12.3 {TkTextTagCmd - "ranges" option} haveCourier12 {
    .t tag delete x

    .t tag add x 2.2
    .t tag add x 2.7 4.15
    .t tag add x 5.2 5.5
    .t tag ranges x


} {2.2 2.3 2.7 4.6 5.2 5.5}
test textTag-12.4 {TkTextTagCmd - "ranges" option} haveCourier12 {
    .t tag delete x

    .t tag add x 1.0 3.0
    .t tag add x 4.0 end
    .t tag ranges x


} {1.0 3.0 4.0 8.0}


test textTag-13.1 {TkTextTagCmd - "remove" option} haveCourier12 {
    list [catch {.t tag remove} msg] $msg
} {1 {wrong # args: should be ".t tag remove tagName index1 ?index2 index1 index2 ...?"}}
test textTag-13.2 {TkTextTagCmd - "remove" option} haveCourier12 {
    .t tag delete x

    .t tag add x 2.2 2.11
    .t tag remove x 2.3 2.7
    .t tag ranges x


} {2.2 2.3 2.7 2.11}
test textTag-13.3 {TkTextTagCmd - "remove" option} haveCourier12 {




    .t configure -exportselection 1
    .t tag remove sel 1.0 end
    .t tag add sel 2.4 3.3
    .t.e select to 4
    .t tag remove sel 2.7 3.1
    selection get


} Text

.t tag delete x a b c d
test textTag-14.1 {SortTags} haveCourier12 {


    foreach i {a b c d} {
	.t tag add $i 2.0 2.2
    }
    .t tag names 2.1


} {a b c d}
.t tag delete a b c d
test textTag-14.2 {SortTags} haveCourier12 {


    foreach i {a b c d} {
	.t tag configure $i -background black
    }
    foreach i {d c b a} {
	.t tag add $i 2.0 2.2
    }
    .t tag names 2.1
} {a b c d}
.t tag delete x a b c d

test textTag-14.3 {SortTags} haveCourier12 {


    for {set i 0} {$i < 30} {incr i} {
	.t tag add x$i 2.0 2.2
    }
    .t tag names 2.1


} {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}
test textTag-14.4 {SortTags} haveCourier12 {


    for {set i 0} {$i < 30} {incr i} {
	.t tag configure x$i -background black
    }
    for {set i 29} {$i >= 0} {incr i -1} {
	.t tag add x$i 2.0 2.2
    }
    .t tag names 2.1


} {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}

foreach tag [.t tag names] {
    catch {.t tag delete $tag}
}


set c [.t bbox 2.1]
set x1 [expr [lindex $c 0] + [lindex $c 2]/2]
set y1 [expr [lindex $c 1] + [lindex $c 3]/2]
set c [.t bbox 3.2]








set x2 [expr [lindex $c 0] + [lindex $c 2]/2]
set y2 [expr [lindex $c 1] + [lindex $c 3]/2]
set c [.t bbox 4.3]
set x3 [expr [lindex $c 0] + [lindex $c 2]/2]
set y3 [expr [lindex $c 1] + [lindex $c 3]/2]


test textTag-15.1 {TkTextBindProc} haveCourier12 {


    event generate {} <Motion> -warp 1 -x -1 -y -1; update

    bind .t <ButtonRelease> {lappend x up}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Button> -x $x1 -y $y1
    event gen .t <Motion> -x $x1 -y $y1
    event gen .t <ButtonRelease> -x $x1 -y $y1
    event gen .t <Button> -x $x1 -y $y1
    event gen .t <Motion> -x $x2 -y $y2
    event gen .t <ButtonRelease> -x $x2 -y $y2
    event gen .t <Button> -x $x2 -y $y2
    event gen .t <Motion> -x $x3 -y $y3
    event gen .t <ButtonRelease> -x $x3 -y $y3



    bind .t <ButtonRelease> {}
    set x
} {x-up up up y-up up}

test textTag-15.2 {TkTextBindProc} haveCourier12 {


    event generate {} <Motion> -warp 1 -x -1 -y -1; update
    catch {.t tag delete x}
    catch {.t tag delete y}
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <ButtonPress> {lappend x x-down}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <ButtonPress> {lappend x y-down}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    .t tag bind y <Leave> {lappend x y-leave}
    event gen .t <Motion> -x 0 -y 0
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Motion> -x $x1 -y $y1
    lappend x |
    event gen .t <Button> -x $x1 -y $y1
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x |
    event gen .t <ButtonRelease> -x $x3 -y $y3
    set x


} {x-enter | x-down | | x-up x-leave y-enter}

test textTag-15.3 {TkTextBindProc} haveCourier12 {
    catch {.t tag delete x}


    catch {.t tag delete y}
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Any-ButtonPress-1> {lappend x x-down}
    .t tag bind x <Any-ButtonRelease-1> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Any-ButtonPress-1> {lappend x y-down}
    .t tag bind y <Any-ButtonRelease-1> {lappend x y-up}
    .t tag bind y <Leave> {lappend x y-leave}
    event gen .t <Motion> -x 0 -y 0
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
    event gen .t <Motion> -x $x1 -y $y1
    lappend x |
    event gen .t <Button-1> -x $x1 -y $y1
    lappend x |
    event gen .t <Button-2> -x $x1 -y $y1 -state 0x100
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3  -state 0x300
    lappend x |
    event gen .t <ButtonRelease-1> -x $x3 -y $y3 -state 0x300
    lappend x |
    event gen .t <ButtonRelease-2> -x $x3 -y $y3 -state 0x200
    set x


} {x-enter | x-down | | | x-up | x-leave y-enter}

foreach tag [.t tag names] {
    catch {.t tag delete $tag}
}
.t tag configure big -font $bigFont
test textTag-16.1 {TkTextPickCurrent procedure} haveCourier12 {


    event generate {} <Motion> -warp 1 -x -1 -y -1; update

    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    set x [.t index current]
    event gen .t <Motion> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Button-1> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x [.t index current]
    event gen .t <Button-3> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-3> -state 0x300 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-1> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
} {2.1 3.2 3.2 3.2 3.2 3.2 4.3}

test textTag-16.2 {TkTextPickCurrent procedure} {haveCourier12 failsOnUbuntu} {




    event generate {} <Motion> -warp 1 -x -1 -y -1; update



    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    event gen .t <Motion> -x $x2 -y $y2
    set x [.t index current]
    .t tag add big 3.0
    update
    lappend x [.t index current]



} {3.2 3.1}
.t tag remove big 1.0 end

foreach i {a b c d} {
    .t tag bind $i <Enter> "lappend x enter-$i"
    .t tag bind $i <Leave> "lappend x leave-$i"
}

test textTag-16.3 {TkTextPickCurrent procedure} haveCourier12 {
    event generate {} <Motion> -warp 1 -x -1 -y -1; update

    foreach i {a b c d} {
	.t tag remove $i 1.0 end

    }
    .t tag lower b
    .t tag lower a
    set x {}
    event gen .t <Motion> -x $x1 -y $y1
    .t tag add a 2.1 3.3
    .t tag add b 2.1
    .t tag add c 3.2
    update
    lappend x |
    event gen .t <Motion> -x $x2 -y $y2
    lappend x |
    event gen .t <Motion> -x $x3 -y $y3
    set x


} {enter-a enter-b | leave-b enter-c | leave-a leave-c}

test textTag-16.4 {TkTextPickCurrent procedure} haveCourier12 {




    event generate {} <Motion> -warp 1 -x -1 -y -1; update

    foreach i {a b c d} {
	.t tag remove $i 1.0 end

    }
    .t tag lower b
    .t tag lower a
    set x {}
    event gen .t <Motion> -x $x1 -y $y1
    .t tag add a 2.1 3.3
    .t tag add b 2.1
    .t tag add c 2.1
    update
    lappend x |
    .t tag lower c
    event gen .t <Motion> -x $x2 -y $y2
    set x
} {enter-a enter-b enter-c | leave-c leave-b}
foreach i {a b c d} {
    .t tag delete $i

}
test textTag-16.5 {TkTextPickCurrent procedure} haveCourier12 {
    event generate {} <Motion> -warp 1 -x -1 -y -1; update

    foreach i {a b c d} {
	.t tag remove $i 1.0 end
    }





    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x2 -y $y2
    .t index current



} {3.2}

test textTag-16.6 {TkTextPickCurrent procedure} {haveCourier12 failsOnUbuntu} {


    event generate {} <Motion> -warp 1 -x -1 -y -1; update
    foreach i {a b c d} {
	.t tag remove $i 1.0 end
    }





    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x2 -y $y2
    update
    .t index current



} {3.1}

test textTag-16.7 {TkTextPickCurrent procedure} {haveCourier12 failsOnUbuntu} {


    event generate {} <Motion> -warp 1 -x -1 -y -1; update
    foreach i {a b c d} {
	.t tag remove $i 1.0 end
    }








    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Leave> {.t tag add big 3.0 3.2}
    .t tag add a 2.1
    event gen .t <Motion> -x $x2 -y $y2

    .t index current



} {3.1}


test textTag-17.1 {insert procedure inserts tags} {
    .t delete 1.0 end

    # Objectification of the text widget had a problem
    # with inserting tags when using 'end'. Check that
    # bug has been fixed.
    .t insert end abcd {x} \n {} efgh {y} \n {}
    .t dump -tag 1.0 end
} {tagon x 1.0 tagoff x 1.4 tagon y 2.0 tagoff y 2.4}

catch {destroy .t}

test textTag-18.1 {TkTextPickCurrent tag bindings} -setup {
    destroy .t
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
} -body {
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
    # the actual tagged characters themselves.
    event gen .t <Motion> -warp 1 -x 0 -y 0 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    event gen .t <Motion> -warp 1 -x 20 -y 20 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    return $res
} -cleanup {
    destroy .t
} -result {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}}

destroy .t

# cleanup
cleanupTests
return







|




|




815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
    # the actual tagged characters themselves.
    event gen .t <Motion> -warp 1 -x 0 -y 0 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    event gen .t <Motion> -warp 1 -x 20 -y 20 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    set res
} -cleanup {
    destroy .t
} -result {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}}

catch {destroy .t}

# cleanup
cleanupTests
return

Changes to tests/textWind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16


17
18

19

20

21

22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661


662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726



727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843




844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863

864
865
866
867
868
869
870
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312

1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346

1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522

1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562

1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
# This file is a Tcl script to test the code in the file tkTextWind.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands


testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

deleteWindows



set fixedFont {"Courier" -12}

set fixedHeight [font metrics $fixedFont -linespace]

set fixedWidth [font measure $fixedFont m]

set fixedAscent [font metrics $fixedFont -ascent]


# Widget used in almost all tests
set tWidth 30

set tHeight 6
text .t -width $tWidth -height $tHeight -bd 2 -highlightthickness 2 \
        -font $fixedFont
pack .t -expand 1 -fill both
update
.t debug on

set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]

wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

# This update is needed on MacOS to make sure that the window is mapped
# when the tests begin.

update

set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
set padx [expr {$bw+$px+$hlth}]
set pady [expr {$bw+$py+$hlth}]

# ----------------------------------------------------------------------

test textWind-1.1 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -window]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] 3 3] \
    {-window {} {} {} .f}]

test textWind-1.2 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -align]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 3 3] \
    {-align {} {} center top}]

test textWind-1.3 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    .t window create 2.2 -create "Test script"
    .t window configure 2.2 -create
} -result {-create {} {} {} {Test script}}

test textWind-1.4 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    # the window .f should be wider than the fixed width
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth+5}]+[expr {$pady+$fixedHeight}] \
    {-padx {} {} 0 5} \
    [list [expr {$padx+2*$fixedWidth+10+2*5}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-1.5 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+4}] \
    {-pady {} {} 0 4} \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+20+2*4}] $fixedWidth $fixedHeight]]

test textWind-1.6 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]
} -result [list \
    5x$fixedHeight+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    {-stretch {} {} 0 1}]


.t delete 1.0 end
.t insert end "This is the first line"


test textWind-2.1 {TkTextWindowCmd procedure} -body {
    .t window
} -returnCodes error -result {wrong # args: should be ".t window option ?arg ...?"}
test textWind-2.2 {TkTextWindowCmd procedure, "cget" option} -body {
    .t window cget
} -returnCodes error -result {wrong # args: should be ".t window cget index option"}
test textWind-2.3 {TkTextWindowCmd procedure, "cget" option} -body {
    .t window cget a b c
} -returnCodes error -result {wrong # args: should be ".t window cget index option"}
test textWind-2.4 {TkTextWindowCmd procedure, "cget" option} -body {
    .t window cget gorp -padx
} -returnCodes error -result {bad text index "gorp"}
test textWind-2.5 {TkTextWindowCmd procedure, "cget" option} -body {
    .t window cget 1.2 -padx
} -returnCodes error -result {no embedded window at index "1.2"}
test textWind-2.6 {TkTextWindowCmd procedure, "cget" option} -setup {
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.3 -window .f -padx 1 -pady 2
    .t window cget .f -bogus
} -cleanup {
    destroy .f
} -returnCodes error -result {unknown option "-bogus"}
test textWind-2.7 {TkTextWindowCmd procedure, "cget" option} -setup {
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.3 -window .f -padx 1 -pady 2
    .t window cget .f -pady
} -cleanup {
    destroy .f
} -returnCodes ok -result 2
test textWind-2.8 {TkTextWindowCmd procedure} -body {
    .t window co
} -returnCodes error -result {wrong # args: should be ".t window configure index ?-option value ...?"}
test textWind-2.9 {TkTextWindowCmd procedure} -body {
    .t window configure gorp
} -returnCodes error -result {bad text index "gorp"}
test textWind-2.10 {TkTextWindowCmd procedure} -body {
    .t delete 1.0 end
    .t window configure 1.0
} -returnCodes error -result {no embedded window at index "1.0"}
test textWind-2.11 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.3 -window .f -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    .t window configure .f
} -cleanup {
    destroy .f
} -result  {{-align {} {} center baseline} {-create {} {} {} foo} {-padx {} {} 0 1} {-pady {} {} 0 2} {-stretch {} {} 0 0} {-window {} {} {} .f}}
test textWind-2.12 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    list [.t window configure .f -padx 33] [.t window configure .f -padx]
} -cleanup {
    destroy .f
} -result {{} {-padx {} {} 0 33}}
test textWind-2.13 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2
    update
    list [.t window configure .f -padx 14 -pady 15] \
        [.t window configure .f -padx] [.t window configure .f -pady]
} -cleanup {
    destroy .f
} -result {{} {-padx {} {} 0 14} {-pady {} {} 0 15}}
test textWind-2.14 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    .t window create
} -returnCodes error -result {wrong # args: should be ".t window create index ?-option value ...?"}
test textWind-2.15 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    .t window create gorp
} -returnCodes error -result {bad text index "gorp"}
test textWind-2.16 {TkTextWindowCmd procedure, don't insert after end} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t index .f
} -result {2.6}
test textWind-2.17 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    list [catch {.t window create 1.0} msg] $msg [.t window configure 1.0]
} -result {0 {} {{-align {} {} center center} {-create {} {} {} {}} {-padx {} {} 0 0} {-pady {} {} 0 0} {-stretch {} {} 0 0} {-window {} {} {} {}}}}
test textWind-2.18 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f -gorp stupid

} -returnCodes error -result {unknown option "-gorp"}
test textWind-2.19 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    catch {.t window create 1.0 -window .f -gorp stupid}
    list [winfo exists .f] [.t index 1.end] [catch {.t index .f}]
} -result {0 1.0 1}
test textWind-2.20 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -gorp -window .f stupid
} -returnCodes error -result {unknown option "-gorp"}
test textWind-2.21 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    catch {.t window create 1.0 -gorp -window .f stupid}
    list [winfo exists .f] [.t index 1.end] [catch {.t index .f}]
} -result {1 1.0 1}
test textWind-2.22 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    .t window c
} -returnCodes error -result {ambiguous window option "c": must be cget, configure, create, or names}
destroy .f
test textWind-2.23 {TkTextWindowCmd procedure, "names" option} -setup {
    .t delete 1.0 end
} -body {
    .t window names foo
} -returnCodes error -result {wrong # args: should be ".t window names"}
test textWind-2.24 {TkTextWindowCmd procedure, "names" option} -setup {
    .t delete 1.0 end
} -body {
    .t window names
} -result {}
test textWind-2.25 {TkTextWindowCmd procedure, "names" option} -setup {
    .t delete 1.0 end
    destroy .f .f2 .t.f .t.f2
} -body {
    foreach i {.f .f2 .t.f .t.f2} {
        frame $i -width 20 -height 20
        .t window create end -window $i
    }
    lsort [.t window names]
} -cleanup {
    destroy .f .f2 .t.f .t.f2

} -result {.f .f2 .t.f .t.f2}


test textWind-3.1 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    .t window configure 1.0 -foo bar
} -cleanup {
    destroy .f
} -returnCodes error -result {unknown option "-foo"}

test textWind-3.2 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    .t index .f
} -cleanup {
    destroy .f
} -returnCodes error -result {bad text index ".f"}

test textWind-3.3 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .f}
    list [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.4 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    .t index .t.f
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad text index ".t.f"}

test textWind-3.5 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .t.f}
    list [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.6 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 1.3 1 \
    [list [expr {$padx+3*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-3.7 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
    .t window create 1.3 -window .f.f
} -cleanup {
    destroy .f
} -returnCodes error -result {can't embed .f.f in .t}
test textWind-3.8 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    .t window configure 1.3 -window .t2
} -cleanup {
    destroy .t2
} -returnCodes error -result {can't embed .t2 in .t}
test textWind-3.9 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    catch {.t window configure 1.3 -window .t2}
    .t window configure 1.3 -window
} -cleanup {

    destroy .t2
} -result {-window {} {} {} {}}
test textWind-3.10 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.3
    .t window configure 1.3 -window .t
} -returnCodes error -result {can't embed .t in .t}
test textWind-3.11 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    # This test checks for various errors when the text claims
    # a window away from itself.

    .t insert 1.0 "Some sample text"
    button .t.b -text "Hello!"
    .t window create 1.4 -window .t.b
    .t window create 1.6 -window .t.b
    update
    .t index .t.b
} -result {1.6}


.t delete 1.0 end
frame .f -width 10 -height 20 -bg $color
.t window create 1.0 -window .f
test textWind-4.1 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align baseline
    .t window configure 1.0 -align
} -result {-align {} {} center baseline}
test textWind-4.2 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align bottom
    .t window configure 1.0 -align
} -result {-align {} {} center bottom}
test textWind-4.3 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align center
    .t window configure 1.0 -align
} -result {-align {} {} center center}
test textWind-4.4 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align top
    .t window configure 1.0 -align
} -result {-align {} {} center top}
test textWind-4.5 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align top
    .t window configure 1.0 -align gorp
} -returnCodes error -result {bad align "gorp": must be baseline, bottom, center, or top}
test textWind-4.6 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align top
    catch {.t window configure 1.0 -align gorp}
    .t window configure 1.0 -align
} -result {-align {} {} center top}

test textWind-5.1 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.2 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.3 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.4 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.5 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} -result [list 0 1.2 \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+(($fixedHeight-10)/2)}] 20 10] \
    [list [expr {$padx+2*$fixedWidth+20}] $pady $fixedWidth $fixedHeight]]


test textWind-6.1 {EmbWinRequestProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
    set result {}
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f

    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] $pady 10 20] \
    [list [expr {$padx+2*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight] \
    [list [expr {$padx+2*$fixedWidth}] $pady 25 30] \
    [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-7.1 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-7.2 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]

} -cleanup {
    destroy .t.f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-8.1 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f]
} -result [list destroyed \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    0]

test textWind-8.2 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    .t index .f
} -returnCodes error -result {bad text index ".f"}


test textWind-9.1 {EmbWinCleanupProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nA second line."
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.3 -window .f
    .t delete 1.5 2.1
    .t index .f
} -cleanup {
    destroy .f


} -result {1.7}


test textWind-10.1 {EmbWinLayoutProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"

    .t window create 1.5 -create {
        frame .f -width 10 -height 20 -bg $color
    }
    update
    list [winfo exists .f] [winfo width .f] [winfo height .f] [.t index .f]
} -cleanup {
    destroy .f
} -result {1 10 20 1.5}

test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        error "couldn't create window"
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{couldn't create window}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{bad window path name "gorp"}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg

	lappend msg $args
    }
} -body {



    .t insert 1.0 "Some sample text"

    set msg {}
    after idle {
        .t window create 1.5 -create {
            frame .t.f
            frame .t.f.f -width 10 -height 20 -bg $color
        }
    }
    set count 0
    while {([llength $msg] < 2) && ($count < 100)} {
        update
        incr count
        .t bbox 1.5
        after 10
    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result [list \
    {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    1]

test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {$msg == ""} {
	    lappend msg $args
	}
    }
} -body {
    .t insert 1.0 "Some sample text"
    set msg {}
    .t window create 1.5 -create {
        frame .t.f
        frame .t.f.f -width 10 -height 20 -bg $color
    }

    update idletasks
    lappend msg [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{{can't embed .t.f.f relative to .t}} 1}

test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] < 0} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    update
    .t window create 1.5 -create {
        concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t relative to .t}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints failsOnUbuntu -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"

    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"

    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update
    set i 0
    while {[llength $msg] == 1 && [incr i] < 200} { update }
    return $msg
} -cleanup {
    destroy .t2
    rename bgerror {}
} -result {{{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}}}





test textWind-10.9 {EmbWinLayoutProc procedure, steal window from self} -setup {
    .t delete 1.0 end
    destroy .t.b
} -body {
    .t insert 1.0 ABCDEFGHIJKLMNOP
    button .t.b -text "Hello!"
    .t window create 1.5 -window .t.b
    update
    .t window create 1.3 -create {concat .t.b}
    update
    .t index .t.b
} -cleanup {
    destroy .t.b
} -result {1.3}

test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char

    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth-1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char

    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char

    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] [expr {($tWidth-12)*$fixedWidth+1}] 20] \
    [list [expr {$padx+($tWidth-12)*$fixedWidth+1}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none

    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    {}]

test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none

    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] [expr {$tHeight*$fixedHeight}]] \
    {}]

test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char

    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] [expr {$tWidth*$fixedWidth}] [expr {($tHeight-1)*$fixedHeight}]] \
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update ; after 100 ; update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update ; after 100 ; update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}
    set x {no configures}
    .t delete 1.0
    .t insert 1.0 "X"
    update
    return $x
} -cleanup {
    destroy .f
    place forget .t
    pack .t
} -result {no configures}

test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
    .t insert end " and second here: "
    frame .f2 -width 40 -height 10 -bg $color
    .t window create end -window .f2
    .t insert end " with junk after it."
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]
} -cleanup {
    destroy .f .f2
} -result [list 1 \
    30x20+[expr {$padx+14*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+14*$fixedWidth}] [expr {$pady+$fixedHeight}] 30 20] \
    0]

test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
    .t insert end " and second here: "
    frame .f2 -width 40 -height 10 -bg $color
    .t window create end -window .f2
    .t insert end " with junk after it."
    update
    .t xview moveto 0
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} -cleanup {
  destroy .f .f2
  .t configure -wrap char
} -result [list 0 1 \
    40x10+[expr {$padx+37*$fixedWidth+30-25*$fixedWidth}]+[expr {$pady+$fixedHeight+((20-10)/2)}] \
    [list [expr {$padx+37*$fixedWidth+30-25*$fixedWidth}] [expr {$pady+$fixedHeight+((20-10)/2)}] 40 10]]

test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Map> {lappend x mapped}
    bind .f <Unmap> {lappend x unmapped}
    set x created
    update
    lappend x modified
    .t delete 1.0
    update
    lappend x replaced
    .t window configure .f -window {}
    .t delete 1.1
    .t window create 1.4 -window .f
    update
    lappend x off-screen
    .t configure -wrap none
    .t insert 1.0 "Enough text to make the line run off-screen"
    update
    return $x
} -cleanup {
    destroy .f
} -result {created mapped modified replaced unmapped mapped off-screen unmapped}


test textWind-13.1 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 5]]

test textWind-13.2 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+(($fixedHeight-7)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+(($fixedHeight-7)/2)}] 5 5]]

test textWind-13.3 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedAscent-6)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedAscent-6)}] 5 5]]

test textWind-13.4 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedHeight-7)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedHeight-7)}] 5 5]]

test textWind-13.5 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.6 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.7 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedAscent-1}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedAscent-1}]]]

test textWind-13.8 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    .t configure -spacing1 0 -spacing3 0
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+5+(($fixedHeight-5)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+5+(($fixedHeight-5)/2)}] 5 5]]


test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    bind .f <Unmap> {lappend x unmapped}
    set x modified
    .t insert 1.0 x
    lappend x removed
    .t window configure .f -window {}
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified removed unmapped updated}

test textWind-14.2 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    bind .f <Unmap> {lappend x unmapped}
    set x modified
    .t insert 1.0 x
    lappend x deleted
    .t delete .f
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified deleted updated}

test textWind-14.3 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    .t yview 2.0
    set result [winfo ismapped .f]
    update ; after 10
    list $result [winfo ismapped .f]
} -cleanup {
    destroy .f
} -result {1 0}

test textWind-14.4 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    .t yview 2.0
    set result [winfo ismapped .t.f]
    update
    list $result [winfo ismapped .t.f]
} -cleanup {
    destroy .t.f
} -result {1 0}

test textWind-15.1 {TkTextWindowIndex procedure} -setup {
    .t delete 1.0 end
} -body {
    .t index .foo
} -returnCodes error -result {bad text index ".foo"}

test textWind-15.2 {TkTextWindowIndex procedure} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]
} -cleanup {
    destroy .f
} -result [list 1.6 \
    [list [expr {$padx+6*$fixedWidth+30}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-16.1 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none

    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    update
    pack forget .t
    update
    winfo ismapped .f
} -cleanup {
    pack .t
} -result 0

test textWind-16.2 {EmbWinTextStructureProc procedure} -setup {

    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    update
    set result {}
    lappend result [winfo geom .f] [.t bbox .f]
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f .f2
} -result [list \
    30x20+[expr {$padx+6*$fixedWidth}]+$pady \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20] \
    30x20+[expr {$padx+6*$fixedWidth}]+[expr {$pady+30}] \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]

test textWind-16.3 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -wrap none

    .t insert 1.0 "Some sample text"
    .t window create 1.6
    update
    pack forget .t
    update
} -cleanup {
    pack .t
} -result {}

test textWind-16.4 {EmbWinTextStructureProc procedure} -setup {

    .t delete 1.0 end
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} -cleanup {
    pack .t
} -result [list 1 [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]


test textWind-17.1 {peer widgets and embedded windows} -setup {
    destroy .t .tt .f
} -body {
    pack [text .t]

    .t insert end "Line 1"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.3 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t .tt
    winfo exists .f
} -result 0

test textWind-17.2 {peer widgets and embedded windows} -setup {
    destroy .t .f .tt
} -body {
    pack [text .t]

    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.4 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t
    .tt.t insert 1.0 "foo"
    update
    destroy .tt
} -result {}

test textWind-17.3 {peer widget and -create} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    destroy .t .tt
} -result {}

test textWind-17.4 {peer widget deleted one window shouldn't delete others} -setup {
    destroy .t .tt
    set res {}
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    destroy .tt

    lappend res [.t get 1.2]
    update
    lappend res [.t get 1.2]
} -cleanup {
    destroy .t
} -result {{} {}}

test textWind-17.5 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t

} -result {.t.f .tt.t.f}

test textWind-17.6 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t

}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.7 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t

}  -result {.t.f {}}

test textWind-17.8 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t

}  -result {{-window {} {} {} .t.f} {-window {} {} {} {}}}

test textWind-17.9 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    .tt.t window configure 1.2 -window [frame .tt.t.f -width 10 -height 20 -bg red]
    list [.t window configure 1.2 -window] [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t

}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.10 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    .tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg blue]
    update ; update
    .t window configure 1.2 -create \
      {destroy %W.f ; frame %W.f -width 50 -height 7 -bg red}
    .tt.t window configure 1.2 -window {}
    .t window configure 1.2 -window {}
    set res [list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]]
    update
    lappend res [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t

}  -result {{-window {} {} {} {}} {-window {} {} {} {}} {-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-18.1 {embedded window deletion triggered by a script bound to <Map>} -setup {
    catch {destroy .t .f .f2}
} -body {
    pack [text .t]
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    .t window create end -window [frame .f -background red -width 80 -height 80]
    .t window create end -window [frame .f2 -background blue -width 80 -height 80]
    bind .f <Map> {.t delete .f}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait visibility .f2
    update
} -cleanup {
    destroy .t .f .f2
} -result {}


option clear

# cleanup
cleanupTests
return



|
|
|



<
|


>
|

|
>
>

|
>

>

>

>

|
|
>
|
|
<
|


|

<
<









<
<
|
<
|
<
<
<
<
<
<

<
<
|

<






|
<
<
<
<
|
<
|

<






|
<
<
<
<
|
<
|

<




|
<
|

<


<




<
<
|
<
<
|

<






<
<
|
<
<
|

<






<
<
|
<



>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
|
|
|
|
|
|
|

|
|
|
<
<
<
<

<





|
<
<
|
|
<
<
<
<

<






<
<
|
|
<
<
<
<

<






|
<
<
|
|
<
<
|
|
|
<
<
|
|
|
<
<
<
<

<




|
|

<

|
|
<
<
<
<

<

|
>
|
|
<
<
<
<

|

|
|
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|
|
|

<

|
|

<
<

|
|

|
<

>
|

<
|
|
<


|
<
<
|
<
|
|
<






|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<






|
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<







<
<
|
<
<
|
|
<




|
<
<
|
<
|
<
<
<
<
<
<
<
<
|
|
<



|
|
<
>
|
<
|

<


|
|
|
<
<


>






|

<



|


|
|


|
|


|
|


|
|

<
<
<
<
|
|
|

|

<
<





|
|
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|

<
<







<
<
<
|

|

<
<
<



>



<
<
<
<
<
<
<
|

|

<
<







<
<
<
<
<
|
|

<
<







>
|
|
<
<
<

|

<
<






|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|

<
|

<
<





|
|
>
>
|
|

|

<
<

>

|



<
<
|
<
|

<
<
<
<
<


|




<
<
<
|
<
<
|

<
<
<
<
<


|




<
<
<
|
<
<
<
<
<
|
|
>


<
>
>
>

>









<
<
|
<


<
<
<
<
|
<
<
<
|

<
<
<
<
<
<
<
<

|

|
|

>


<
<
<
|
|
|

<
<
<
<
<
<
<

<

|




<
<
<
|
<
<
|

<
<
<
<
<
<

>

|
|
|




<
<
<
|
<
<
|

<
<
<
<
<
<

>

|
|
|





|
<
<
<
|

>
>
>
>
|

<
<







|
|
<
<
|
<
<
<

>

|


<
<
<
<
<
|
|
<
<
<

>

|



<
<
<
<
<
|
|
<
<
<

>

|



<
<
<
<
<
|
|
<
<
<

>

|



<
<
<
<
<
|
|
<
<
<

>

|



<
<
<
<
<
|
|
<
<
<

>





<
<
<
<
|

|

<
<
<
<
<
<





|

|
<
|
<
|
|

<
<
<
<
<
<





|

|
<
|
|
<
<
|

<
<
<
<
<
<









<
<
<
|
<
|
<
|

<
<












<
<
<
<
<
<
|
|

<
<













|
<
|
<
<
<

|

<
<



















|
<
<
|

<
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|

<
<





<
<
<
<
<
|
|
<
<
<







|
|
<
<
<
<

<
|

<
<











|
<
<
|
|
|

<
<











|
<
<
|
<
|

<
<








<
<
|
<
|

<
<








|
|
|

|
<
<
|
|
<
|
>

<
<
<
<






<
<
<
<
|

|
<
<
<

>







|
|
<
<
|
>

<
<
<
<










|
|
<
<
<
<
<
<
|
<
<

>





|
|
<
<
|
>

<
<
<







|
|
<

<
|
|
<

>








|

|
|
<

>










|

|
|
<









|

|
|
<
<








>



<
<
|

|
|
<







|
<

>
|

|
|
<







|
|
<

>
|

|
|
<







|
<

>
|

|
|
<







|
|
<

>
|

|
|
<








|
|

>
|

|
|
<













|


|
<

>
|

|
|
<










|
<
<

>





1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38


39
40
41
42
43
44
45
46
47


48

49






50


51
52

53
54
55
56
57
58
59




60

61
62

63
64
65
66
67
68
69




70

71
72

73
74
75
76
77

78
79

80
81

82
83
84
85


86


87
88

89
90
91
92
93
94


95


96
97

98
99
100
101
102
103


104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124










125
126
127
128
129
130


131
132
133
134
135
136
137
138
139
140
141




142

143
144
145
146
147
148


149
150




151

152
153
154
155
156
157


158
159




160

161
162
163
164
165
166
167


168
169


170
171
172


173
174
175




176

177
178
179
180
181
182
183

184
185
186




187

188
189
190
191
192




193
194
195
196
197
198
199




200
201













202
203


204
205
206
207

208
209
210
211


212
213
214
215
216

217
218
219
220

221
222

223
224
225


226

227
228

229
230
231
232
233
234
235


236
237
238














239



240
241
242
243
244
245
246


247


248














249
250

251
252
253
254
255
256
257


258


259
260

261
262
263
264
265


266

267








268
269

270
271
272
273
274

275
276

277
278

279
280
281
282
283


284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315




316
317
318
319
320
321


322
323
324
325
326
327
328

329
330

















331
332
333
334
335
336













337



338
339
340


341
342
343
344
345
346
347



348
349
350
351



352
353
354
355
356
357
358







359
360
361
362


363
364
365
366
367
368
369





370
371
372


373
374
375
376
377
378
379
380
381
382



383
384
385


386
387
388
389
390
391
392




393











394
395

396
397


398
399
400
401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416
417
418


419

420
421





422
423
424
425
426
427
428



429


430
431





432
433
434
435
436
437
438



439





440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457
458


459

460
461




462



463
464








465
466
467
468
469
470
471
472
473



474
475
476
477







478

479
480
481
482
483
484



485


486
487






488
489
490
491
492
493
494
495
496
497



498


499
500






501
502
503
504
505
506
507
508
509
510
511
512



513
514
515
516
517
518
519
520


521
522
523
524
525
526
527
528
529


530



531
532
533
534
535
536





537
538



539
540
541
542
543
544
545





546
547



548
549
550
551
552
553
554





555
556



557
558
559
560
561
562
563





564
565



566
567
568
569
570
571
572





573
574



575
576
577
578
579
580
581




582
583
584
585






586
587
588
589
590
591
592
593

594

595
596
597






598
599
600
601
602
603
604
605

606
607


608
609






610
611
612
613
614
615
616
617
618



619

620

621
622


623
624
625
626
627
628
629
630
631
632
633
634






635
636
637


638
639
640
641
642
643
644
645
646
647
648
649
650
651

652



653
654
655


656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675


676
677

678
679


680
681
682
683
684





685
686
687


688
689
690
691
692





693
694
695


696
697
698
699
700





701
702
703


704
705
706
707
708





709
710
711


712
713
714
715
716





717
718
719


720
721
722
723
724





725
726
727


728
729
730
731
732





733
734
735


736
737
738
739
740





741
742



743
744
745
746
747
748
749
750
751




752

753
754


755
756
757
758
759
760
761
762
763
764
765
766


767
768
769
770


771
772
773
774
775
776
777
778
779
780
781
782


783

784
785


786
787
788
789
790
791
792
793


794

795
796


797
798
799
800
801
802
803
804
805
806
807
808
809


810
811

812
813
814




815
816
817
818
819
820




821
822
823



824
825
826
827
828
829
830
831
832
833
834


835
836
837




838
839
840
841
842
843
844
845
846
847
848
849






850


851
852
853
854
855
856
857
858
859


860
861
862



863
864
865
866
867
868
869
870
871

872

873
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888

889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904

905
906
907
908
909
910
911
912
913
914
915
916
917


918
919
920
921
922
923
924
925
926
927
928
929


930
931
932
933

934
935
936
937
938
939
940
941

942
943
944
945
946
947

948
949
950
951
952
953
954
955
956

957
958
959
960
961
962

963
964
965
966
967
968
969
970

971
972
973
974
975
976

977
978
979
980
981
982
983
984
985

986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041


1042
1043
1044
1045
1046
1047
1048
# This file is a Tcl script to test the code in the file tkTextWind.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Text.borderWidth 2
option add *Text.highlightThickness 2
option add *Text.font {Courier -12}

set fixedFont {Courier -12}
# 15 on XP, 13 on Solaris 8
set fixedHeight [font metrics $fixedFont -linespace]
# 7 on all platforms
set fixedWidth [font measure $fixedFont m]
# 12 on XP
set fixedAscent [font metrics $fixedFont -ascent]
set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP

catch {destroy .f}
catch {destroy .t}
catch {destroy .t2}

text .t -width 30 -height 6 -bd 2 -highlightthickness 2

pack append . .t {top expand fill}
update
.t debug on
wm geometry . {}
set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]



# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .



testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]









test textWind-1.1 {basic tests of options} {fonts} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
	    [.t window configure .f -window]




} {1 3x3+19+23 {19 23 3 3} {-window {} {} {} .f}}

test textWind-1.2 {basic tests of options} {fonts} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
	    [.t window configure .f -align]




} {1 3x3+19+18 {19 18 3 3} {-align {} {} center top}}

test textWind-1.3 {basic tests of options} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    .t window create 2.2 -create "Test script"
    .t window configure 2.2 -create
} {-create {} {} {} {Test script}}

test textWind-1.4 {basic tests of options} {fonts} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"

    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]


} {10x20+24+18 {-padx {} {} 0 5} {39 21 7 13}}


test textWind-1.5 {basic tests of options} {fonts} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]


} {10x20+19+22 {-pady {} {} 0 4} {19 46 7 13}}


test textWind-1.6 {basic tests of options} {fonts} {
    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]


} {5x13+19+18 {-stretch {} {} 0 1}}


.t delete 1.0 end
.t insert end "This is the first line"
frame .f -width 10 -height 6 -bg $color
.t window create 1.3 -window .f -padx 1 -pady 2
test textWind-2.1 {TkTextWindowCmd procedure} {
    list [catch {.t window} msg] $msg
} {1 {wrong # args: should be ".t window option ?arg arg ...?"}}
test textWind-2.2 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget} msg] $msg
} {1 {wrong # args: should be ".t window cget index option"}}
test textWind-2.3 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget a b c} msg] $msg
} {1 {wrong # args: should be ".t window cget index option"}}
test textWind-2.4 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget gorp -padx} msg] $msg
} {1 {bad text index "gorp"}}
test textWind-2.5 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget 1.2 -padx} msg] $msg
} {1 {no embedded window at index "1.2"}}










test textWind-2.6 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget .f -bogus} msg] $msg
} {1 {unknown option "-bogus"}}
test textWind-2.7 {TkTextWindowCmd procedure, "cget" option} {
    list [catch {.t window cget .f -pady} msg] $msg
} {0 2}


test textWind-2.8 {TkTextWindowCmd procedure} {
    list [catch {.t window co} msg] $msg
} {1 {wrong # args: should be ".t window configure index ?option value ...?"}}
test textWind-2.9 {TkTextWindowCmd procedure} {
    list [catch {.t window configure gorp} msg] $msg
} {1 {bad text index "gorp"}}
test textWind-2.10 {TkTextWindowCmd procedure} {
    .t delete 1.0 end
    list [catch {.t window configure 1.0} msg] $msg
} {1 {no embedded window at index "1.0"}}
test textWind-2.11 {TkTextWindowCmd procedure} {




    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    list [catch {.t window configure .f} msg] $msg


} {0 {{-align {} {} center baseline} {-create {} {} {} foo} {-padx {} {} 0 1} {-pady {} {} 0 2} {-stretch {} {} 0 0} {-window {} {} {} .f}}}
test textWind-2.12 {TkTextWindowCmd procedure} {




    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    list [.t window configure .f -padx 33] [.t window configure .f -padx]


} {{} {-padx {} {} 0 33}}
test textWind-2.13 {TkTextWindowCmd procedure} {




    .t delete 1.0 end

    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2
    update
    list [.t window configure .f -padx 14 -pady 15] \
	    [.t window configure .f -padx] [.t window configure .f -pady]


} {{} {-padx {} {} 0 14} {-pady {} {} 0 15}}
test textWind-2.14 {TkTextWindowCmd procedure} {


    list [catch {.t window create} msg] $msg
} {1 {wrong # args: should be ".t window create index ?option value ...?"}}
test textWind-2.15 {TkTextWindowCmd procedure} {


    list [catch {.t window create gorp} msg] $msg
} {1 {bad text index "gorp"}}
test textWind-2.16 {TkTextWindowCmd procedure, don't insert after end} {




    .t delete 1.0 end

    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t index .f
} {2.6}
test textWind-2.17 {TkTextWindowCmd procedure} {
    .t delete 1.0 end

    list [catch {.t window create 1.0} msg] $msg [.t window configure 1.0]
} {0 {} {{-align {} {} center center} {-create {} {} {} {}} {-padx {} {} 0 0} {-pady {} {} 0 0} {-stretch {} {} 0 0} {-window {} {} {} {}}}}
test textWind-2.18 {TkTextWindowCmd procedure} {




    .t delete 1.0 end

    frame .f -width 10 -height 6 -bg $color
    list [catch {.t window create 1.0 -window .f -gorp stupid} msg] $msg \
	    [winfo exists .f] [.t index 1.end] [catch {.t index .f}]
} {1 {unknown option "-gorp"} 0 1.0 1}
test textWind-2.19 {TkTextWindowCmd procedure} {




    .t delete 1.0 end
    catch {destroy .f}
    frame .f -width 10 -height 6 -bg $color
    list [catch {.t window create 1.0 -gorp -window .f stupid} msg] $msg \
	    [winfo exists .f] [.t index 1.end] [catch {.t index .f}]
} {1 {unknown option "-gorp"} 1 1.0 1}
test textWind-2.20 {TkTextWindowCmd procedure} {




    list [catch {.t window c} msg] $msg
} {1 {ambiguous window option "c": must be cget, configure, create, or names}}













destroy .f
test textWind-2.21 {TkTextWindowCmd procedure, "names" option} {


    list [catch {.t window names foo} msg] $msg
} {1 {wrong # args: should be ".t window names"}}
test textWind-2.22 {TkTextWindowCmd procedure, "names" option} {
    .t delete 1.0 end

    .t window names
} {}
test textWind-2.23 {TkTextWindowCmd procedure, "names" option} {
    .t delete 1.0 end


    foreach i {.f .f2 .t.f .t.f2} {
	frame $i -width 20 -height 20
	.t window create end -window $i
    }
    set result [.t window names]

    destroy .f .f2 .t.f .t.f2
    lsort $result
} {.f .f2 .t.f .t.f2}


test textWind-3.1 {EmbWinConfigure procedure} {
    .t delete 1.0 end

    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    list [catch {.t window configure 1.0 -foo bar} msg] $msg


} {1 {unknown option "-foo"}}

test textWind-3.2 {EmbWinConfigure procedure} {fonts} {
    .t delete 1.0 end

    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]


} {1 {bad text index ".f"} 0 {26 5 7 13}}
catch {destroy .f}
test textWind-3.3 {EmbWinConfigure procedure} {fonts} {














    .t delete 1.0 end



    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    list [catch {.t index .t.f} msg] $msg [winfo ismapped .t.f] [.t bbox 1.4]


} {1 {bad text index ".t.f"} 0 {26 5 7 13}}


catch {destroy .t.f}














test textWind-3.4 {EmbWinConfigure procedure} {fonts} {
    .t delete 1.0 end

    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]


} {0 1.3 1 {36 8 7 13}}


test textWind-3.5 {EmbWinConfigure procedure} {
    .t delete 1.0 end

    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
    list [catch {.t window create 1.3 -window .f.f} msg] $msg


} {1 {can't embed .f.f in .t}}

catch {destroy .f}








test textWind-3.6 {EmbWinConfigure procedure} {
    .t delete 1.0 end

    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    list [catch {.t window configure 1.3 -window .t2} msg] $msg \
	    [.t window configure 1.3 -window]

} {1 {can't embed .t2 in .t} {-window {} {} {} {}}}
catch {destroy .t2}

test textWind-3.7 {EmbWinConfigure procedure} {
    .t delete 1.0 end

    .t insert 1.0 "Some sample text"
    .t window create 1.3
    list [catch {.t window configure 1.3 -window .t} msg] $msg
} {1 {can't embed .t in .t}}
test textWind-3.8 {EmbWinConfigure procedure} {


    # This test checks for various errors when the text claims
    # a window away from itself.
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    button .t.b -text "Hello!"
    .t window create 1.4 -window .t.b
    .t window create 1.6 -window .t.b
    update
    .t index .t.b
} {1.6}


.t delete 1.0 end
frame .f -width 10 -height 20 -bg $color
.t window create 1.0 -window .f
test textWind-4.1 {AlignParseProc and AlignPrintProc procedures} {
    .t window configure 1.0 -align baseline
    .t window configure 1.0 -align
} {-align {} {} center baseline}
test textWind-4.2 {AlignParseProc and AlignPrintProc procedures} {
    .t window configure 1.0 -align bottom
    .t window configure 1.0 -align
} {-align {} {} center bottom}
test textWind-4.3 {AlignParseProc and AlignPrintProc procedures} {
    .t window configure 1.0 -align center
    .t window configure 1.0 -align
} {-align {} {} center center}
test textWind-4.4 {AlignParseProc and AlignPrintProc procedures} {
    .t window configure 1.0 -align top
    .t window configure 1.0 -align
} {-align {} {} center top}
test textWind-4.5 {AlignParseProc and AlignPrintProc procedures} {
    .t window configure 1.0 -align top




    list [catch {.t window configure 1.0 -align gorp} msg] $msg \
	    [.t window configure 1.0 -align]
} {1 {bad align "gorp": must be baseline, bottom, center, or top} {-align {} {} center top}}

test textWind-5.1 {EmbWinStructureProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} {1 {bad text index ".f"} {19 11 0 0} {19 5 7 13}}

test textWind-5.2 {EmbWinStructureProc procedure} {fonts} {
    .t delete 1.0 end

















    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f













    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]



} {1 {bad text index ".f"} {19 18 0 0} {19 5 7 13}}
test textWind-5.3 {EmbWinStructureProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]



} {0 1.2 {19 6 20 10} {39 5 7 13}}

test textWind-6.1 {EmbWinRequestProc procedure} {fonts} {
    .t delete 1.0 end



    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    set result {}
    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]







} {{19 5 10 20} {29 8 7 13} {19 5 25 30} {44 13 7 13}}

test textWind-7.1 {EmbWinLostSlaveProc procedure} {textfonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]





} [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]]
test textWind-7.2 {EmbWinLostSlaveProc procedure} {textfonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]
} [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]]
catch {destroy .f}
catch {destroy .t.f}




test textWind-8.1 {EmbWinDeleteProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [catch {.t index .f} msg] $msg \




	    [winfo exists .f]











} {destroyed {19 5 7 13} {26 5 7 13} 1 {bad text index ".f"} 0}


test textWind-9.1 {EmbWinCleanupProc procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text\nA second line."
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.3 -window .f
    .t delete 1.5 2.1
    .t index .f
} 1.7

proc bgerror args {
    global msg
    set msg $args
}

test textWind-10.1 {EmbWinLayoutProc procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    destroy .f
    .t window create 1.5 -create {
	frame .f -width 10 -height 20 -bg $color
    }
    update
    list [winfo exists .f] [winfo width .f] [winfo height .f] [.t index .f]


} {1 10 20 1.5}

test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} {fonts} {
    .t delete 1.0 end





    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
	error "couldn't create window"
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]



} {{{couldn't create window}} {40 11 0 0}}


test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} {fonts} {
    .t delete 1.0 end





    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
	concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]



} {{{bad window path name "gorp"}} {40 11 0 0}}





proc bgerror args {
    global msg
    if {[lsearch -exact $msg $args] == -1} {
	lappend msg $args
    }

}
test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    catch {destroy .t.f}
    set msg {}
    after idle {
        .t window create 1.5 -create {
            frame .t.f
            frame .t.f.f -width 10 -height 20 -bg $color
        }
    }
    set count 0
    while {([llength $msg] < 2) && ($count < 100)} {


	update ; incr count; .t bbox 1.5 ; after 10

    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]




} [list {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} [list 40 [expr {11+$fixedDiff/2}] 0 0] 1]



test textWind-10.4.1 {EmbWinLayoutProc procedure, error in creating window} {textfonts} {
    .t delete 1.0 end








    .t insert 1.0 "Some sample text"
    catch {destroy .t.f}
    .t window create 1.5 -create {
	frame .t.f
	frame .t.f.f -width 10 -height 20 -bg $color
    }
    set msg {}
    update idletasks
    lappend msg [winfo exists .t.f.f]



} [list {{can't embed .t.f.f relative to .t}} 1]
catch {destroy .t.f}
test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} {textfonts} {
    .t delete 1.0 end







    .t insert 1.0 "Some sample text"

    .t window create 1.5 -create {
	concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]



} [list {{can't embed .t relative to .t}} [list 40 [expr {11+$fixedDiff/2}] 0 0]]


test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} {textfonts failsOnQuarz} {
    .t delete 1.0 end






    .t insert 1.0 "Some sample text"
    catch {destroy .t2}
    .t window create 1.5 -create {
	toplevel .t2 -width 100 -height 150
	wm geom .t2 +0+0
	concat .t2
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]



} [list {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} [list 40 [expr {11+$fixedDiff/2}] 0 0]]


test textWind-10.6.1 {EmbWinLayoutProc procedure, error in creating window} failsOnUbuntu {
    .t delete 1.0 end






    .t insert 1.0 "Some sample text"
    catch {destroy .t2}
    .t window create 1.5 -create {
	toplevel .t2 -width 100 -height 150
	wm geom .t2 +0+0
	concat .t2
    }
    set msg {}
    update
    set i 0
    while {[llength $msg] == 1 && [incr i] < 200} { update }
    set msg



} {{{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}}}

proc bgerror args {
    global msg
    set msg $args
}
test textWind-10.7 {EmbWinLayoutProc procedure, steal window from self} {
    .t delete 1.0 end


    .t insert 1.0 ABCDEFGHIJKLMNOP
    button .t.b -text "Hello!"
    .t window create 1.5 -window .t.b
    update
    .t window create 1.3 -create {concat .t.b}
    update
    .t index .t.b
} {1.3}
catch {destroy .t2}


test textWind-10.8 {EmbWinLayoutProc procedure, doesn't fit on line} {fonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 125 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]





} {{89 5 126 20} {5 25 7 13}}
test textWind-10.9 {EmbWinLayoutProc procedure, doesn't fit on line} {fonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 126 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]





} {{89 5 126 20} {5 25 7 13}}
test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} {fonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 127 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]





} {{5 18 127 20} {132 21 7 13}}
test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} failsOnUbuntu {



    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]





} {{89 5 126 20} {}}
test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} {fonts} {



    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]





} {{89 5 126 78} {}}
test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} {fonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]




} {{5 18 210 65} {}}

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} failsOnUbuntu {
    .t delete 1.0 end






    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    winfo geom .f
} {30x20+119+55}

place forget .t

pack .t
test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} failsOnUbuntu {
    .t delete 1.0 end






    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update
    winfo geom .t.f
} {30x20+89+5}

place forget .t
pack .t


test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} {
    .t delete 1.0 end






    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}
    set x {no configures}
    .t delete 1.0
    .t insert 1.0 "X"
    update



    set x

} {no configures}

test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
    .t insert end " and second here: "
    frame .f2 -width 40 -height 10 -bg $color
    .t window create end -window .f2
    .t insert end " with junk after it."
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]






} {1 30x20+103+18 {103 18 30 20} 0}
test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
    .t insert end " and second here: "
    frame .f2 -width 40 -height 10 -bg $color
    .t window create end -window .f2
    .t insert end " with junk after it."
    update
    .t xview moveto 0
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} {0 1 40x10+119+23 {119 23 40 10}}

.t configure -wrap char




test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Map> {lappend x mapped}
    bind .f <Unmap> {lappend x unmapped}
    set x created
    update
    lappend x modified
    .t delete 1.0
    update
    lappend x replaced
    .t window configure .f -window {}
    .t delete 1.1
    .t window create 1.4 -window .f
    update
    lappend x off-screen
    .t configure -wrap none
    .t insert 1.0 "Enough text to make the line run off-screen"
    update
    set x


} {created mapped modified replaced unmapped mapped off-screen unmapped}


test textWind-13.1 {EmbWinBboxProc procedure} failsOnUbuntu {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x5+21+6 {21 6 5 5}}
test textWind-13.2 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x5+21+9 {21 9 5 5}}
test textWind-13.3 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x5+21+10 {21 10 5 5}}
test textWind-13.4 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x5+21+12 {21 12 5 5}}
test textWind-13.5 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x11+21+6 {21 6 5 11}}
test textWind-13.6 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x11+21+6 {21 6 5 11}}
test textWind-13.7 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x9+21+6 {21 6 5 9}}
test textWind-13.8 {EmbWinBboxProc procedure} {fonts} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]





} {5x11+21+6 {21 6 5 11}}
test textWind-13.9 {EmbWinBboxProc procedure, spacing options} {fonts} {



    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} {5x5+21+14 {21 14 5 5}}
.t configure -spacing1 0 -spacing2 0 -spacing3 0






test textWind-14.1 {EmbWinDelayedUnmap procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    bind .f <Unmap> {lappend x unmapped}
    set x modified
    .t insert 1.0 x
    lappend x removed
    .t window configure .f -window {}
    lappend x updated
    update
    set x


} {modified removed unmapped updated}
catch {destroy .f}
test textWind-14.2 {EmbWinDelayedUnmap procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    bind .f <Unmap> {lappend x unmapped}
    set x modified
    .t insert 1.0 x
    lappend x deleted
    .t delete .f
    lappend x updated
    update
    set x


} {modified deleted updated}

test textWind-14.3 {EmbWinDelayedUnmap procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    .t yview 2.0
    set result [winfo ismapped .f]
    update ; after 10
    list $result [winfo ismapped .f]


} {1 0}

test textWind-14.4 {EmbWinDelayedUnmap procedure} {
    .t delete 1.0 end


    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    .t yview 2.0
    set result [winfo ismapped .t.f]
    update
    list $result [winfo ismapped .t.f]
} {1 0}
catch {destroy .t.f}
catch {destroy .f}

test textWind-15.1 {TkTextWindowIndex procedure} {


    list [catch {.t index .foo} msg] $msg
} {1 {bad text index ".foo"}}

test textWind-15.2 {TkTextWindowIndex procedure} {fonts} {
    .t configure -wrap none
    .t delete 1.0 end




    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]




} {1.6 {77 8 7 13}}

test textWind-16.1 {EmbWinTextStructureProc procedure} {



    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    update
    pack forget .t
    update
    winfo ismapped .f
} 0
pack .t


test textWind-16.2 {EmbWinTextStructureProc procedure} failsOnUbuntu {
    .t configure -wrap none
    .t delete 1.0 end




    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    update
    set result {}
    lappend result [winfo geom .f] [.t bbox .f]
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} {30x20+47+5 {47 5 30 20} 30x20+47+35 {47 5 30 20}}
catch {destroy .f2}






test textWind-16.3 {EmbWinTextStructureProc procedure} {


    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    .t window create 1.6
    update
    pack forget .t
    update
} {}
pack .t


test textWind-16.4 {EmbWinTextStructureProc procedure} failsOnUbuntu {
    .t configure -wrap none
    .t delete 1.0 end



    .t insert 1.0 "Some sample text"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} {1 {47 5 30 20}}
pack .t



test textWind-17.1 {peer widgets and embedded windows} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert end "Line 1"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.3 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t .tt
    winfo exists .f
} {0}

test textWind-17.2 {peer widgets and embedded windows} {
    catch {destroy .t .f}

    pack [text .t]
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.4 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t
    .tt.t insert 1.0 "foo"
    update
    destroy .tt
} {}

test textWind-17.3 {peer widget and -create} {
    catch {destroy .t}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    destroy .t .tt
} {}

test textWind-17.4 {peer widget deleted one window shouldn't delete others} {
    catch {destroy .t .tt}


    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    destroy .tt
    set res {}
    lappend res [.t get 1.2]
    update
    lappend res [.t get 1.2]


} {{} {}}

test textWind-17.5 {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    set res [list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]]

    destroy .tt .t
    set res
} {.t.f .tt.t.f}

test textWind-17.6 {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    set res [list [.t window configure 1.2 -window] \
      [.tt.t window configure 1.2 -window]]

    destroy .tt .t
    set res
} {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.7 {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    set res [list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]]

    destroy .tt .t
    set res
} {.t.f {}}

test textWind-17.8 {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    set res [list [.t window configure 1.2 -window] \
      [.tt.t window configure 1.2 -window]]

    destroy .tt .t
    set res
} {{-window {} {} {} .t.f} {-window {} {} {} {}}}

test textWind-17.8a {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    .tt.t window configure 1.2 -window [frame .tt.t.f -width 10 -height 20 -bg red]
    set res [list [.t window configure 1.2 -window] \
      [.tt.t window configure 1.2 -window]]
    destroy .tt .t
    set res
} {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.9 {peer widget window configuration} {
    catch {destroy .t .tt}

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    .tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg blue]
    update ; update
    .t window configure 1.2 -create \
      {destroy %W.f ; frame %W.f -width 50 -height 7 -bg red}
    .tt.t window configure 1.2 -window {}
    .t window configure 1.2 -window {}
    set res [list [.t window configure 1.2 -window] \
      [.tt.t window configure 1.2 -window]]
    update
    lappend res [.t window configure 1.2 -window] \
      [.tt.t window configure 1.2 -window]

    destroy .tt .t
    set res
} {{-window {} {} {} {}} {-window {} {} {} {}} {-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-18.1 {embedded window deletion triggered by a script bound to <Map>} {
    catch {destroy .t .f}

    pack [text .t]
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    .t window create end -window [frame .f -background red -width 80 -height 80]
    .t window create end -window [frame .f2 -background blue -width 80 -height 80]
    bind .f <Map> {.t delete .f}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait visibility .f2
    update
} {}



catch {destroy .t}
option clear

# cleanup
cleanupTests
return

Changes to tests/tk.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# This file is a Tcl script to test the tk command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2002 ActiveState Corporation.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint testprintf [llength [info command testprintf]]

test tk-1.1 {tk command: general} -body {
    tk
} -returnCodes error -result {wrong # args: should be "tk subcommand ?arg ...?"}
test tk-1.2 {tk command: general} -body {
    tk xyz
} -returnCodes error -result {unknown or ambiguous subcommand "xyz": must be appname, busy, caret, fontchooser, inactive, scaling, useinputmethods, or windowingsystem}

# Value stored to restore default settings after 2.* tests
set appname [tk appname]
test tk-2.1 {tk command: appname} -body {
    tk appname xyz abc
} -returnCodes error -result {wrong # args: should be "tk appname ?newName?"}
test tk-2.2 {tk command: appname} -body {
    tk appname foobazgarply
} -result {foobazgarply}
test tk-2.3 {tk command: appname} -constraints unix -body {
    tk appname bazfoogarply
    expr {[lsearch -exact [winfo interps] [tk appname]] >= 0}
} -result 1
test tk-2.4 {tk command: appname} -body {
    tk appname [tk appname]
} -result [tk appname]
tk appname $appname

# Value stored to restore default settings after 3.* tests
set scaling [tk scaling]
test tk-3.1 {tk command: scaling} -body {
    tk scaling -displayof
} -returnCodes error -result {value for "-displayof" missing}
test tk-3.2 {tk command: scaling: get current} -body {
    tk scaling 1
    format %.2g [tk scaling]
}  -result 1
test tk-3.3 {tk command: scaling: get current} -body {
    tk scaling -displayof . 1.25
    format %.3g [tk scaling]
}  -result 1.25
test tk-3.4 {tk command: scaling: set new} -body {
    tk scaling xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test tk-3.5 {tk command: scaling: set new} -body {
    tk scaling -displayof . xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test tk-3.6 {tk command: scaling: set new} -body {



|
|
|






<
<


|


|








|





|
|










|



|







1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# This file is a Tcl script to test the tk command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2002 ActiveState Corporation.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test



test tk-1.1 {tk command: general} -body {
    tk
} -returnCodes error -result {wrong # args: should be "tk option ?arg?"}
test tk-1.2 {tk command: general} -body {
    tk xyz
} -returnCodes error -result {bad option "xyz": must be appname, caret, scaling, useinputmethods, windowingsystem, or inactive}

# Value stored to restore default settings after 2.* tests
set appname [tk appname]
test tk-2.1 {tk command: appname} -body {
    tk appname xyz abc
} -returnCodes error -result {wrong # args: should be "tk appname ?newName?"}
test tk-2.2 {tk command: appname} -body {
    tk appname foobazgarply
} -result foobazgarply
test tk-2.3 {tk command: appname} -constraints unix -body {
    tk appname bazfoogarply
    expr {[lsearch -exact [winfo interps] [tk appname]] >= 0}
} -result 1
test tk-2.4 {tk command: appname} -body {
    tk appname $appname
} -result $appname
tk appname $appname

# Value stored to restore default settings after 3.* tests
set scaling [tk scaling]
test tk-3.1 {tk command: scaling} -body {
    tk scaling -displayof
} -returnCodes error -result {value for "-displayof" missing}
test tk-3.2 {tk command: scaling: get current} -body {
    tk scaling 1
    format %.2g [tk scaling]
} -result 1
test tk-3.3 {tk command: scaling: get current} -body {
    tk scaling -displayof . 1.25
    format %.3g [tk scaling]
} -result 1.25
test tk-3.4 {tk command: scaling: set new} -body {
    tk scaling xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test tk-3.5 {tk command: scaling: set new} -body {
    tk scaling -displayof . xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test tk-3.6 {tk command: scaling: set new} -body {
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
} -result 0
test tk-4.4 {tk command: useinputmethods: set new} -body {
    tk useinputmethods xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test tk-4.5 {tk command: useinputmethods: set new} -body {
    tk useinputmethods -displayof . xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test tk-4.6 {tk command: useinputmethods: set new} -body {
    # This isn't really a test, but more of a check... The answer is what was
    # given, because we may be on a Unix system that doesn't have the XIM
    # stuff
    if {[tk useinputmethods 1] == 0} {
	puts "this wish doesn't have XIM (X Input Methods) support"
    }
    return $useim
} -result $useim
test tk-4.7 {tk command: useinputmethods: set new} -constraints win -body {
    # Mac and Windows don't have X Input Methods, so this should always return
    # 0
    tk useinputmethods 1
} -cleanup {
    tk useinputmethods $useim







|






|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
} -result 0
test tk-4.4 {tk command: useinputmethods: set new} -body {
    tk useinputmethods xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test tk-4.5 {tk command: useinputmethods: set new} -body {
    tk useinputmethods -displayof . xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test tk-4.6 {tk command: useinputmethods: set new} -constraints unix -body {
    # This isn't really a test, but more of a check... The answer is what was
    # given, because we may be on a Unix system that doesn't have the XIM
    # stuff
    if {[tk useinputmethods 1] == 0} {
	puts "this wish doesn't have XIM (X Input Methods) support"
    }
    set useim
} -result $useim
test tk-4.7 {tk command: useinputmethods: set new} -constraints win -body {
    # Mac and Windows don't have X Input Methods, so this should always return
    # 0
    tk useinputmethods 1
} -cleanup {
    tk useinputmethods $useim
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

# tk inactive
test tk-6.1 {tk inactive} -body {
    string is integer [tk inactive]
} -result 1
test tk-6.2 {tk inactive reset} -body {
    tk inactive reset
} -returnCodes ok -match glob -result *
test tk-6.3 {tk inactive wrong argument} -body {
    tk inactive foo
} -returnCodes 1 -result {bad option "foo": must be reset}
test tk-6.4 {tk inactive too many arguments} -body {
    tk inactive reset foo
} -returnCodes 1 -result {wrong # args: should be "tk inactive ?-displayof window? ?reset?"}
test tk-6.5 {tk inactive} -body {
    tk inactive reset
    update
    after 100
    set i [tk inactive]
    expr {$i < 0 || ( $i > 90 && $i < 200 )}
} -result 1

test tk-7.1 {tk inactive in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive}
} -cleanup {
    ::safe::interpDelete foo
} -result -1
test tk-7.2 {tk inactive reset in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive reset}
} -cleanup {
    ::safe::interpDelete foo
} -returnCodes 1 -result {resetting the user inactivity timer is not allowed in a safe interpreter}

test tk-8.1 {Test for ticket [1cc44617e2], see if TCL_LL_MODIFIER works as expected on all platforms} -constraints testprintf -body {
    testprintf -21474836480
} -result {-21474836480 18446744052234715136}

# tests of [tk busy] in busy.test

# cleanup
cleanupTests
return







|


|


|





|

















|
<
<
<
<
<
<




141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178






179
180
181
182

# tk inactive
test tk-6.1 {tk inactive} -body {
    string is integer [tk inactive]
} -result 1
test tk-6.2 {tk inactive reset} -body {
    tk inactive reset
} -match glob -result *
test tk-6.3 {tk inactive wrong argument} -body {
    tk inactive foo
} -returnCodes error -result {bad option "foo": must be reset}
test tk-6.4 {tk inactive too many arguments} -body {
    tk inactive reset foo
} -returnCodes error -result {wrong # args: should be "tk inactive ?-displayof window? ?reset?"}
test tk-6.5 {tk inactive} -body {
    tk inactive reset
    update
    after 100
    set i [tk inactive]
    expr {$i < 0 || ( $i > 90 && $i < 300 )}
} -result 1

test tk-7.1 {tk inactive in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive}
} -cleanup {
    ::safe::interpDelete foo
} -result -1
test tk-7.2 {tk inactive reset in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive reset}
} -cleanup {
    ::safe::interpDelete foo
} -returnCodes error -result {resetting the user inactivity timer is not allowed in a safe interpreter}







# cleanup
cleanupTests
return

Changes to tests/ttk/all.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# all.tcl --
#
# This file contains a top-level script to run all of the ttk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 2007 by the Tk developers.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [file dirname [tcltest::testsDirectory]] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]
encoding system utf-8
if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}






|












<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
# all.tcl --
#
# This file contains a top-level script to run all of the ttk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright (c) 2007 by the Tk developers.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [file dirname [tcltest::testsDirectory]] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]

if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}

Changes to tests/ttk/checkbutton.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#
# ttk::checkbutton widget tests.
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test checkbutton-1.1 "Checkbutton check" -body {
    pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb]
}
test checkbutton-1.2 "Checkbutton invoke" -body {
    .cb invoke





|
<







1
2
3
4
5
6

7
8
9
10
11
12
13
#
# ttk::checkbutton widget tests.
#

package require Tk
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test checkbutton-1.1 "Checkbutton check" -body {
    pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb]
}
test checkbutton-1.2 "Checkbutton invoke" -body {
    .cb invoke
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    lappend result [.cb cget -variable] [info exists .cb] [.cb state]
    .cb invoke
    lappend result [info exists .cb] [set .cb] [.cb state]
    .cb invoke
    lappend result [info exists .cb] [set .cb] [.cb state]
} -result [list .cb 0 alternate   1 on selected  1 off {}]

# Bug [109865fa01]
test checkbutton-1.7 "Button destroyed by click" -body {
    proc destroy_button {} {
        destroy .top
    }
    toplevel .top
    ttk::menubutton .top.mb -text Button -style TLabel
    bind .top.mb <ButtonRelease-1> destroy_button
    pack .top.mb
    focus -force .top.mb
    update
    event generate .top.mb <Button-1>
    event generate .top.mb <ButtonRelease-1>
    update  ; # shall not trigger error  invalid command name ".top.b"
} -result {}

# Bug [fa8de77936]
test checkbutton-1.8 "Empty -variable" -body {
    # shall simply not crash
    ttk::checkbutton .cbev -variable {}
    .cbev invoke
} -cleanup {
    destroy .cbev
} -result {}

tcltest::cleanupTests







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

41
42
43
44
45
46
47

























48
    lappend result [.cb cget -variable] [info exists .cb] [.cb state]
    .cb invoke
    lappend result [info exists .cb] [set .cb] [.cb state]
    .cb invoke
    lappend result [info exists .cb] [set .cb] [.cb state]
} -result [list .cb 0 alternate   1 on selected  1 off {}]


























tcltest::cleanupTests

Changes to tests/ttk/combobox.test.

1
2
3
4
5
6
7
8
9
10
11
12
#
# ttk::combobox widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test combobox-1.0 "Combobox tests -- setup" -body {
    ttk::combobox .cb
} -result .cb




|







1
2
3
4
5
6
7
8
9
10
11
12
#
# ttk::combobox widget tests
#

package require Tk 8.5
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test combobox-1.0 "Combobox tests -- setup" -body {
    ttk::combobox .cb
} -result .cb
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
} -result 1

test combobox-2.4 "current -- value not in list" -body {
    .cb set "z"
    .cb current
} -result -1

test combobox-2.5 "current -- set to end index" -body {
    .cb configure -values [list a b c d e thelastone]
    .cb current end
    .cb get
} -result thelastone

test combobox-2.6 "current -- set to unknown index" -body {
    .cb configure -values [list a b c d e]
    .cb current notanindex
} -returnCodes error -result {Incorrect index notanindex}

test combobox-2.end "Cleanup" -body { destroy .cb }

test combobox-3 "Read postoffset value dynamically from current style" -body {
    ttk::combobox .cb -values [list a b c] -style "DerivedStyle.TCombobox"
    pack .cb -expand true -fill both
    ttk::style configure DerivedStyle.TCombobox -postoffset [list 25 0 0 0]
    ttk::combobox::Post .cb
    expr {[winfo rootx .cb.popdown] - [winfo rootx .cb]}
} -result 25 -cleanup {
    destroy .cb
}

test combobox-1890211 "ComboboxSelected event after listbox unposted" -body {
    # whitebox test...
    pack [ttk::combobox .cb -values [list a b c]]
    set result [list]
    bind .cb <<ComboboxSelected>> {
    	lappend result Event [winfo ismapped .cb.popdown] [.cb get]







<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<







40
41
42
43
44
45
46











47
48









49
50
51
52
53
54
55
} -result 1

test combobox-2.4 "current -- value not in list" -body {
    .cb set "z"
    .cb current
} -result -1












test combobox-2.end "Cleanup" -body { destroy .cb }











test combobox-1890211 "ComboboxSelected event after listbox unposted" -body {
    # whitebox test...
    pack [ttk::combobox .cb -values [list a b c]]
    set result [list]
    bind .cb <<ComboboxSelected>> {
    	lappend result Event [winfo ismapped .cb.popdown] [.cb get]

Changes to tests/ttk/entry.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#
# Tile package: entry widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

variable scrollInfo
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

# Some of the tests raise background errors;




|
|
<


<
<







1
2
3
4
5
6

7
8


9
10
11
12
13
14
15
#
# Tile package: entry widget tests
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands



variable scrollInfo
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

# Some of the tests raise background errors;
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
test entry-2.1 "Create entry before scrollbar" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
}  -cleanup {destroy .te .tsb}

test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -constraints failsOnUbuntu -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    .te insert end [string repeat "abc" 50]
    catch {update} ; # error triggers because the -xscrollcommand callback
                     # errors out: invalid command name ".tsb"
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
    update ; # no error
    lappend res [expr [lindex [.tsb get] 1] < 1] ; # scrollbar did update
} -result 1 -cleanup {destroy .te .tsb}

test entry-2.2 "Initial scroll position" -body {
    ttk::entry .e -font fixed -width 5 -xscrollcommand scroll
    .e insert end "0123456789"
    pack .e;
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    set scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.0 0.5}
# NOTE: result can vary depending on font.

# Bounding box / scrolling tests.
test entry-3.0 "Series 3 setup" -body {
    ttk::style theme use default
    variable fixed TkFixedFont
    variable cw [font measure $fixed a]
    variable ch [font metrics $fixed -linespace]
    variable bd 2	;# border + padding
    variable ux [font measure $fixed ]

    pack [ttk::entry .e -font $fixed -width 20]
    update
}

test entry-3.1 "bbox widget command" -body {
    .e delete 0 end
    .e bbox 0
} -result [list $bd $bd 0 $ch]

test entry-3.2 "xview" -body {
    .e delete 0 end;
    .e insert end [string repeat "0" 40]
    set result [.e xview]
} -result {0.0 0.5}

test entry-3.3 "xview" -body {
    .e delete 0 end;
    .e insert end abcdefghijklmnopqrstuvwxyz
    .e xview end
    set result [.e index @0]
} -result 7

test entry-3.4 "xview" -body {
    .e delete 0 end;
    .e insert end abcdefghijklmnopqrstuvwxyz
    .e xview moveto 1.0
    set result [.e index @0]
} -result 7

test entry-3.5 "xview" -body {
    .e delete 0 end;
    .e insert end abcdefghijklmnopqrstuvwxyz
    .e xview scroll 5 units
    set result [.e index @0]
} -result 5

test entry-3.6 "xview" -body {
    .e delete 0 end;
    .e insert end [string repeat abcdefghijklmnopqrstuvwxyz 5]
    .e xview scroll 2 pages
    set result [.e index @0]
} -result 40

test entry-3.last "Series 3 cleanup" -body {
    destroy .e
}

# Selection tests:

test entry-4.0 "Selection test - setup" -body {







<
<
<
<
<
<
<
<
<
<
<
<



|
<
<

<
<
<
|





|



|













<
<
|
<
<
<
<
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







70
71
72
73
74
75
76












77
78
79
80


81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106




107
108
109





















110
111
112
113
114
115
116
test entry-2.1 "Create entry before scrollbar" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
}  -cleanup {destroy .te .tsb}













test entry-2.2 "Initial scroll position" -body {
    ttk::entry .e -font fixed -width 5 -xscrollcommand scroll
    .e insert end "0123456789"
    pack .e; update


    set scrollInfo



} -result {0.0 0.5} -cleanup { destroy .e }
# NOTE: result can vary depending on font.

# Bounding box / scrolling tests.
test entry-3.0 "Series 3 setup" -body {
    ttk::style theme use default
    variable fixed fixed
    variable cw [font measure $fixed a]
    variable ch [font metrics $fixed -linespace]
    variable bd 2	;# border + padding
    variable ux [font measure $fixed \u4e4e]

    pack [ttk::entry .e -font $fixed -width 20]
    update
}

test entry-3.1 "bbox widget command" -body {
    .e delete 0 end
    .e bbox 0
} -result [list $bd $bd 0 $ch]

test entry-3.2 "xview" -body {
    .e delete 0 end;
    .e insert end [string repeat "0" 40]


    update idletasks




    set result [.e xview]
} -result {0.0 0.5}






















test entry-3.last "Series 3 cleanup" -body {
    destroy .e
}

# Selection tests:

test entry-4.0 "Selection test - setup" -body {
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    .e insert insert e ; lappend result [.e index insert] [.e index end]
    set result
} -result [list 1 3  2 3  3 3  3 3  3 3] -cleanup {
    unset V
    destroy .e
}

test entry-10.1 {configuration option: "-placeholder"} -setup {
    pack [ttk::entry .e]
} -body {
    .e configure -placeholder {Some text}
    .e cget -placeholder
} -cleanup {
    destroy .e
} -result {Some text}

test entry-10.2 {configuration option: "-placeholderforeground"} -setup {
    pack [ttk::entry .e]
} -body {
    .e configure -placeholder {Some text} -placeholderforeground red
    .e cget -placeholderforeground
} -cleanup {
    destroy .e
} -result {red}

test entry-10.3 {styling option: "-placeholderforeground"} -setup {
    pack [ttk::entry .e]
} -body {
    set current [ttk::style configure TEntry -placeholderforeground]
    ttk::style configure TEntry -placeholderforeground blue
    set res [ttk::style configure TEntry -placeholderforeground]
    ttk::style configure TEntry -placeholderforeground $current
    set res
} -cleanup {
    destroy .e
} -result {blue}

test entry-11.1 {Bug [2830360fff] - Don't loose invalid at focus events} -setup {
    pack [ttk::entry .e]
    update
} -body {
    .e state invalid
    set res [.e state]
    event generate .e <FocusOut>
    lappend res [.e state]
} -result {invalid invalid} -cleanup {
    destroy .e
}

tcltest::cleanupTests







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

276
277
278
279
280
281
282










































283
    .e insert insert e ; lappend result [.e index insert] [.e index end]
    set result
} -result [list 1 3  2 3  3 3  3 3  3 3] -cleanup {
    unset V
    destroy .e
}











































tcltest::cleanupTests

Changes to tests/ttk/image.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test image-1.1 "Bad image element" -body {
    ttk::style element create BadImage image badimage
} -returnCodes error -result {image "badimage" doesn't exist}

test image-1.2 "Duplicate element" -setup {
|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test image-1.1 "Bad image element" -body {
    ttk::style element create BadImage image badimage
} -returnCodes error -result {image "badimage" doesn't exist}

test image-1.2 "Duplicate element" -setup {

Changes to tests/ttk/labelframe.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test labelframe-1.0 "Setup" -body {
    pack [ttk::labelframe .lf] -expand true -fill both
}

test labelframe-2.1 "Can't use indirect descendant as labelwidget" -body {
|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test labelframe-1.0 "Setup" -body {
    pack [ttk::labelframe .lf] -expand true -fill both
}

test labelframe-2.1 "Can't use indirect descendant as labelwidget" -body {
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    .lf configure -labelwidget .nosuchwindow
} -returnCodes error -result {bad window path name ".nosuchwindow"}


###
# See also series labelframe-4.x
#
test labelframe-3.1 "Add child content" -body {
    checkbutton .lf.cb -text "abcde"
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.2 "Remove child content" -body {
    .lf configure -labelwidget {}
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 0 {}]

test labelframe-3.3 "Re-add child content" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.4 "Re-manage child content" -body {
    pack .lf.cb -side right
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb] [.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-3.5 "Re-add child content" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.6 "Destroy child content" -body {
    destroy .lf.cb
    .lf cget -labelwidget
} -result {}

###
# Re-run series labelframe-3.x with nonchild content.
#
# @@@ ODDITY, 14 Nov 2005:
# @@@ labelframe-4.1 fails if .cb is a [checkbutton],
# @@@ but seems to succeed if it's some other widget class.
# @@@ I suspect a race condition; unable to track it down ATM.
#
# @@@ FOLLOWUP: This *may* have been caused by a bug in ManagerIdleProc
# @@@ (see manager.c r1.11). There's still probably a race condition in here.
#
test labelframe-4.1 "Add nonchild content" -body {
    checkbutton .cb -text "abcde"
    .lf configure -labelwidget .cb
    update
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]

} -result [list 1 1 labelframe]

test labelframe-4.2 "Remove nonchild content" -body {
    .lf configure -labelwidget {}
    update;
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]
} -result [list 0 0 {}]

test labelframe-4.3 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] [winfo manager .cb]
} -result [list 1 labelframe]

test labelframe-4.4 "Re-manage nonchild content" -body {
    pack .cb -side right
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-4.5 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 labelframe .cb]

test labelframe-4.6 "Destroy nonchild content" -body {
    destroy .cb
    .lf cget -labelwidget
} -result {}

test labelframe-5.0 "Cleanup" -body {
    destroy .lf
}







|





|




|




|




|




|





|









|







|





|




|






|






|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    .lf configure -labelwidget .nosuchwindow
} -returnCodes error -result {bad window path name ".nosuchwindow"}


###
# See also series labelframe-4.x
#
test labelframe-3.1 "Add child slave" -body {
    checkbutton .lf.cb -text "abcde"
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.2 "Remove child slave" -body {
    .lf configure -labelwidget {}
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 0 {}]

test labelframe-3.3 "Re-add child slave" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.4 "Re-manage child slave" -body {
    pack .lf.cb -side right
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb] [.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-3.5 "Re-add child slave" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.6 "Destroy child slave" -body {
    destroy .lf.cb
    .lf cget -labelwidget
} -result {}

###
# Re-run series labelframe-3.x with nonchild slaves.
#
# @@@ ODDITY, 14 Nov 2005:
# @@@ labelframe-4.1 fails if .cb is a [checkbutton],
# @@@ but seems to succeed if it's some other widget class.
# @@@ I suspect a race condition; unable to track it down ATM.
#
# @@@ FOLLOWUP: This *may* have been caused by a bug in ManagerIdleProc
# @@@ (see manager.c r1.11). There's still probably a race condition in here.
#
test labelframe-4.1 "Add nonchild slave" -body {
    checkbutton .cb -text "abcde"
    .lf configure -labelwidget .cb
    update
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]

} -result [list 1 1 labelframe]

test labelframe-4.2 "Remove nonchild slave" -body {
    .lf configure -labelwidget {}
    update;
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]
} -result [list 0 0 {}]

test labelframe-4.3 "Re-add nonchild slave" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] [winfo manager .cb]
} -result [list 1 labelframe]

test labelframe-4.4 "Re-manage nonchild slave" -body {
    pack .cb -side right
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-4.5 "Re-add nonchild slave" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 labelframe .cb]

test labelframe-4.6 "Destroy nonchild slave" -body {
    destroy .cb
    .lf cget -labelwidget
} -result {}

test labelframe-5.0 "Cleanup" -body {
    destroy .lf
}

Changes to tests/ttk/layout.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test layout-1.1 "Size computations for mixed-orientation layouts" -body {
    ttk::style theme use default

    set block [image create photo -width 10 -height 10]
    ttk::style element create block image $block
|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test layout-1.1 "Size computations for mixed-orientation layouts" -body {
    ttk::style theme use default

    set block [image create photo -width 10 -height 10]
    ttk::style element create block image $block
18
19
20
21
22
23
24
25
26
27
28
29

    pack .b -expand true -fill both

    list [winfo reqwidth .b] [winfo reqheight .b]

} -cleanup { destroy .b } -result [list 24 24]

test layout-2 "Empty -children not allowed" -body {
    ttk::style layout Test.Tentry {Entry.field -children {}}
} -returnCodes error -result {Invalid -children value}

tcltest::cleanupTests







<
<
<


17
18
19
20
21
22
23



24
25

    pack .b -expand true -fill both

    list [winfo reqwidth .b] [winfo reqheight .b]

} -cleanup { destroy .b } -result [list 24 24]





tcltest::cleanupTests

Changes to tests/ttk/notebook.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test notebook-1.0 "Setup" -body {
    ttk::notebook .nb
} -result .nb

#
|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test notebook-1.0 "Setup" -body {
    ttk::notebook .nb
} -result .nb

#

Changes to tests/ttk/panedwindow.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc propagate-geometry {} { update idletasks }

# Basic sanity checks:
#
test panedwindow-1.0 "Setup" -body {
|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

proc propagate-geometry {} { update idletasks }

# Basic sanity checks:
#
test panedwindow-1.0 "Setup" -body {
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
test paned-propagation-1 "Initial request size" -body {
    .pw add .pw.f1
    .pw add .pw.f2
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 100 105]

test paned-propagation-2 "Pane change before map" -body {
    .pw.f1 configure -width 200 -height 100
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 200 155]

test paned-propagation-3 "Map window" -body {
    pack .pw -expand true -fill both
    update
    list [winfo width .pw] [winfo height .pw] [.pw sashpos 0]
} -result [list 200 155 100]

test paned-propagation-4 "Pane change after map, off-axis" -body {
    .pw.f1 configure -width 100 ;# should be granted
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-5 "Pane change after map, on-axis" -body {
    .pw.f1 configure -height 50 ;# should be denied
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-cleanup "Clean up." -body { destroy .pw }

tcltest::cleanupTests







|











|





|








258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
test paned-propagation-1 "Initial request size" -body {
    .pw add .pw.f1
    .pw add .pw.f2
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 100 105]

test paned-propagation-2 "Slave change before map" -body {
    .pw.f1 configure -width 200 -height 100
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 200 155]

test paned-propagation-3 "Map window" -body {
    pack .pw -expand true -fill both
    update
    list [winfo width .pw] [winfo height .pw] [.pw sashpos 0]
} -result [list 200 155 100]

test paned-propagation-4 "Slave change after map, off-axis" -body {
    .pw.f1 configure -width 100 ;# should be granted
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-5 "Slave change after map, on-axis" -body {
    .pw.f1 configure -height 50 ;# should be denied
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-cleanup "Clean up." -body { destroy .pw }

tcltest::cleanupTests

Changes to tests/ttk/progressbar.test.

1
2
3
4
5
6
7
8
9
10
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands


test progressbar-1.1 "Setup" -body {
    ttk::progressbar .pb
} -result .pb

|
|
<







1
2

3
4
5
6
7
8
9
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands


test progressbar-1.1 "Setup" -body {
    ttk::progressbar .pb
} -result .pb

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    set PB		;# NOTREACHED
} -cleanup { unset PB } -returnCodes error -match glob -result "*YIPES!"

test progressbar-end "Cleanup" -body {
    destroy .pb
}

# check existence and default value of each non-core option of the widget
test progressbar-3.1 "progressbar non-core options" -setup {
    set res {}
    ttk::progressbar .defaultpb
} -body {
    foreach option {-anchor -foreground -justify -style -text -wraplength \
                    -length -maximum -mode -orient -phase -value -variable} {
        lappend res [.defaultpb cget $option]
    }
    set res
} -cleanup {
    unset res
    destroy .defaultpb
} -result {w black left {} {} 0 100 100 determinate horizontal 0 0.0 {}}

test progressbar-3.2 "TIP #442 options are taken into account" -setup {
    set res {}
    pack [ttk::progressbar .p -value 0 -maximum 50 -orient horizontal -mode determinate -length 500]
    set thefont [font actual {Arial 10}]
} -body {
    .p configure -anchor c -foreground blue -justify right \
            -text "TIP #442\noptions are now tested" -wraplength 100
    update
    .p step 10
    .p configure -anchor e -font $thefont -foreground green -justify center \
            -text "Changing the value of each option\nfrom TIP #442" -wraplength 250
    update
    .p step 20
    .p configure -orient vertical -text "Cannot be seen"
    update
    foreach option {-anchor -foreground -justify -text -wraplength} {
        lappend res [list $option [.p cget $option]]
    }
    set res
} -cleanup {
    unset res thefont
    destroy .p
} -result {{-anchor e} {-foreground green} {-justify center} {-text {Cannot be seen}} {-wraplength 250}}

tcltest::cleanupTests







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

78
79
80
81
82
83
84







































85
    set PB		;# NOTREACHED
} -cleanup { unset PB } -returnCodes error -match glob -result "*YIPES!"

test progressbar-end "Cleanup" -body {
    destroy .pb
}








































tcltest::cleanupTests

Changes to tests/ttk/radiobutton.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#
# ttk::radiobutton widget tests.
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test radiobutton-1.1 "Radiobutton check" -body {
    pack \
    	[ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \
	[ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \
	[ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \





|
<







1
2
3
4
5
6

7
8
9
10
11
12
13
#
# ttk::radiobutton widget tests.
#

package require Tk
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test radiobutton-1.1 "Radiobutton check" -body {
    pack \
    	[ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \
	[ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \
	[ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \

Changes to tests/ttk/scrollbar.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint coreScrollbar [expr {[tk windowingsystem] eq "aqua"}]

# Before 2019 the code in library/ttk/scrollbar.tcl would replace the
# constructor of ttk::scrollbar with the constructor of tk::scrollbar
# unless the -class or -style options were specified..
# Now there is an implementation of ttk::scrollbar for macOS.  The
# tests are left in place, though, except that scrollbar-swapout-1
# test was changed to expect the class to be TScrollbar instead of
# Scrollbar.

test scrollbar-swapout-1 "Don't use core scrollbars on OSX..." \
 -constraints {
     coreScrollbar
} -body {
    ttk::scrollbar .sb -command "yadda"
    list [winfo class .sb] [.sb cget -command]
} -result [list TScrollbar yadda] -cleanup {
    destroy .sb
}

test scrollbar-swapout-2 "... regardless of whether -style ..." \
-constraints {
    coreScrollbar
} -body {
    ttk::style layout Vertical.Custom.TScrollbar \
    	[ttk::style layout Vertical.TScrollbar] ; # See #1833339
    ttk::scrollbar .sb -command "yadda" -style Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command] [.sb cget -style]
} -result [list TScrollbar yadda Custom.TScrollbar] -cleanup {
    destroy .sb
}

test scrollbar-swapout-3 "... or -class is specified." -constraints {
    coreScrollbar
} -body {
    ttk::scrollbar .sb -command "yadda" -class Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command]
} -result [list Custom.TScrollbar yadda] -cleanup {
    destroy .sb
}

test scrollbar-1.0 "Setup" -body {
    ttk::scrollbar .tsb
} -result .tsb

test scrollbar-1.1 "Set method" -body {
    .tsb set 0.2 0.4
    .tsb get
} -result [list 0.2 0.4]

test scrollbar-1.2 "Set orientation" -body {
    .tsb configure -orient vertical
    pack .tsb -side right -anchor e -expand 1 -fill y
    wm geometry . 200x200
    update
    set w [winfo width .tsb] ; set h [winfo height .tsb]
    expr {$h > $w}
} -result 1

test scrollbar-1.3 "Change orientation" -body {
    .tsb configure -orient horizontal
    pack .tsb -side bottom -anchor s -expand 1 -fill x
    wm geometry . 200x200
    update
    set w [winfo width .tsb] ; set h [winfo height .tsb]
    expr {$h < $w}
} -result 1

test scrollbar-10.1.1 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [ttk::scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2.1 {<Shift-MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
test scrollbar-10.2.2 {<MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}

#
# Scale tests:
#

test scale-1.0 "Self-destruction" -body {
    trace variable v w { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes error -match glob -result "*"

test scale-2.1 "-state option" -setup {
    ttk::scale .s
    set res ""
} -body {
    # defaults
    lappend res [.s instate disabled] [.s cget -state]
    # set -state: instate returns accordingly
    .s configure -state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # back to normal
    .s configure -state normal
    lappend res [.s instate disabled] [.s cget -state]
    # use state command: -state does NOT reflect it
    .s state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # further use state command
    .s state readonly
    lappend res [.s state] [.s cget -state]
} -cleanup {
    destroy .s
    unset -nocomplain res
} -result {0 normal 1 disabled 0 normal 1 normal {disabled readonly} normal}

tcltest::cleanupTests

|
|
<




<
<
<
<
<
<
<
<
|
<
|



|



|
<










|



















<
<
<
|





<
<
<
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


1
2

3
4
5
6








7

8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46



47
48
49
50
51
52



53
54
55
56












































57
58
59
60
61
62
63
64
65
66
67























68
69
package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

testConstraint coreScrollbar [expr {[tk windowingsystem] eq "aqua"}]









test scrollbar-swapout-1 "Use core scrollbars on OSX..." -constraints {

    coreScrollbar
} -body {
    ttk::scrollbar .sb -command "yadda"
    list [winfo class .sb] [.sb cget -command]
} -result [list Scrollbar yadda] -cleanup {
    destroy .sb
}

test scrollbar-swapout-2 "... unless -style is specified ..." -constraints {

    coreScrollbar
} -body {
    ttk::style layout Vertical.Custom.TScrollbar \
    	[ttk::style layout Vertical.TScrollbar] ; # See #1833339
    ttk::scrollbar .sb -command "yadda" -style Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command] [.sb cget -style]
} -result [list TScrollbar yadda Custom.TScrollbar] -cleanup {
    destroy .sb
}

test scrollbar-swapout-3 "... or -class." -constraints {
    coreScrollbar
} -body {
    ttk::scrollbar .sb -command "yadda" -class Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command]
} -result [list Custom.TScrollbar yadda] -cleanup {
    destroy .sb
}

test scrollbar-1.0 "Setup" -body {
    ttk::scrollbar .tsb
} -result .tsb

test scrollbar-1.1 "Set method" -body {
    .tsb set 0.2 0.4
    .tsb get
} -result [list 0.2 0.4]

test scrollbar-1.2 "Set orientation" -body {
    .tsb configure -orient vertical



    set w [winfo reqwidth .tsb] ; set h [winfo reqheight .tsb]
    expr {$h > $w}
} -result 1

test scrollbar-1.3 "Change orientation" -body {
    .tsb configure -orient horizontal



    set w [winfo reqwidth .tsb] ; set h [winfo reqheight .tsb]
    expr {$h < $w}
} -result 1













































#
# Scale tests:
#

test scale-1.0 "Self-destruction" -body {
    trace variable v w { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes error -match glob -result "*"
























tcltest::cleanupTests

Changes to tests/ttk/spinbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#
# ttk::spinbox widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test spinbox-1.0 "Spinbox tests -- setup" -body {
    ttk::spinbox .sb
} -cleanup { destroy .sb } -result .sb

test spinbox-1.1 "Bad -values list" -setup {





|
<







1
2
3
4
5
6

7
8
9
10
11
12
13
#
# ttk::spinbox widget tests
#

package require Tk
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

test spinbox-1.0 "Spinbox tests -- setup" -body {
    ttk::spinbox .sb
} -cleanup { destroy .sb } -result .sb

test spinbox-1.1 "Bad -values list" -setup {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    .sb configure -validate focus
    .sb configure -validate focusin
    .sb configure -validate focusout
    .sb configure -validate none
    .sb cget -validate
} -cleanup {
    destroy .sb
} -result none

test spinbox-1.8.3 "option -validate" -setup {
    ttk::spinbox .sb -from 0 -to 100
} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    .sb configure -validate focus
    .sb configure -validate focusin
    .sb configure -validate focusout
    .sb configure -validate none
    .sb cget -validate
} -cleanup {
    destroy .sb
} -result {none}

test spinbox-1.8.3 "option -validate" -setup {
    ttk::spinbox .sb -from 0 -to 100
} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    pack .sb
    .sb set 50
    focus -force .sb
    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait
    set ::spinbox_test
} -cleanup {
    destroy .sb
} -result 50


test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup {
    ttk::spinbox .sb -values [list a b c d e a]
} -body {
    .sb current
} -cleanup {







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    pack .sb
    .sb set 50
    focus -force .sb
    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait
    set ::spinbox_test
} -cleanup {
    destroy .sb
} -result {50}


test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup {
    ttk::spinbox .sb -values [list a b c d e a]
} -body {
    .sb current
} -cleanup {
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
} -result -1

test spinbox-3.0 "textarea should expand to fill widget" -setup {
    set SBV 5
    set ::spinbox_test {}
    ttk::spinbox .sb -from 0 -to 10 -textvariable SBV
} -body {

    grid columnconfigure . 0 -weight 1
    update idletasks
    set timer [after 500 {set ::spinbox_test timedout}]
    bind . <Map> {
        after idle {
            wm geometry . "210x80"
	    update idletasks
            set ::spinbox_test [.sb identify element 25 5]
        }
        bind . <Map> {}
    }
    grid .sb -sticky ew
    vwait ::spinbox_test
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test SBV
} -result {textarea}

test spinbox-4.0 "Increment with duplicates in -values, wrap" -setup {
    ttk::spinbox .sb -values {one two three 4 5 two six} -wrap true
    set max [expr {[llength [.sb cget -values]] + 2}]
} -body {
    set ::spinbox_test [.sb get]
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Increment>>
        lappend ::spinbox_test [.sb get]
    }
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Decrement>>
        lappend ::spinbox_test [.sb get]
    }
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six one two one six two 5 4 three two one six}

test spinbox-4.1 "Increment with duplicates in -values, wrap, initial value set" -setup {
    ttk::spinbox .sb -values {one two three 4 5 two six} -wrap true
    set max [expr {[llength [.sb cget -values]] + 2}]
} -body {
    .sb set three
    set ::spinbox_test [.sb get]
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Increment>>
        lappend ::spinbox_test [.sb get]
    }
    .sb set two    ; # the first "two" in the -values list becomes the current value
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Decrement>>
        lappend ::spinbox_test [.sb get]
    }
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test max
} -result {three 4 5 two six one two three 4 5 one six two 5 4 three two one six}

test spinbox-4.2 "Increment with duplicates in -values, no wrap" -setup {
    ttk::spinbox .sb -values {one two three 4 5 two six} -wrap false
    set max [expr {[llength [.sb cget -values]] + 2}]
} -body {
    set ::spinbox_test [.sb get]
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Increment>>
        lappend ::spinbox_test [.sb get]
    }
    for {set i 0} {$i < $max} {incr i} {
        event generate .sb <<Decrement>>
        lappend ::spinbox_test [.sb get]
    }
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six six six two 5 4 three two one one one one}


# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55
    ttk::spinbox .sb -textvariable SBV -from 0 -to 100 -increment 5







>

<
<



<
|



<
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







200
201
202
203
204
205
206
207
208


209
210
211

212
213
214
215

216
217
218
219
220
221




























































222
223
224
225
226
227
228
} -result -1

test spinbox-3.0 "textarea should expand to fill widget" -setup {
    set SBV 5
    set ::spinbox_test {}
    ttk::spinbox .sb -from 0 -to 10 -textvariable SBV
} -body {
    grid .sb -sticky ew
    grid columnconfigure . 0 -weight 1


    bind . <Map> {
        after idle {
            wm geometry . "210x80"

            after 100 {set ::spinbox_test [.sb identify element 5 5]}
        }
        bind . <Map> {}
    }

    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test SBV
} -result {textarea}





























































# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55
    ttk::spinbox .sb -textvariable SBV -from 0 -to 100 -increment 5

Changes to tests/ttk/treetags.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

### treeview tag invariants:
#

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
        error "PANIC: $message ($expr failed)"
    }
}


proc itemConstraints {tv item} {
    # $tag in [$tv item $item -tags] <==> [$tv tag has $tag $item]
    foreach tag [$tv item $item -tags] {
	assert {$item in [$tv tag has $tag]}
    }
    foreach child [$tv children $item] {
	itemConstraints $tv $child
    }
}

proc treeConstraints {tv} {
    # $item in [$tv tag has $tag] <==> [$tv tag has $tag $item]
    #
    foreach tag [$tv tag names] {
	foreach item [$tv tag has $tag] {
	    assert {$tag in [$tv item $item -tags]}
	}
    }

    itemConstraints $tv {}
}
#
###


|
<










>




|











|







1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

package require Tk
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

### treeview tag invariants:
#

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
        error "PANIC: $message ($expr failed)"
    }
}
proc in {e l} { expr {[lsearch -exact $l $e] >= 0} }

proc itemConstraints {tv item} {
    # $tag in [$tv item $item -tags] <==> [$tv tag has $tag $item]
    foreach tag [$tv item $item -tags] {
	assert {[in $item [$tv tag has $tag]]}
    }
    foreach child [$tv children $item] {
	itemConstraints $tv $child
    }
}

proc treeConstraints {tv} {
    # $item in [$tv tag has $tag] <==> [$tv tag has $tag $item]
    #
    foreach tag [$tv tag names] {
	foreach item [$tv tag has $tag] {
	    assert {[in $tag [$tv item $item -tags]]}
	}
    }

    itemConstraints $tv {}
}
#
###
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
} -result [list tag1 tag2 tag3 tag4]

test treetags-1.10 "tag names - tag configured" -body {
    $tv tag configure tag5
    lsort [$tv tag names]
} -result [list tag1 tag2 tag3 tag4 tag5]

test treetags-1.11 "tag delete" -body {
    $tv tag delete tag5
    $tv tag delete tag4
    lsort [$tv tag names]
} -result [list tag1 tag2 tag3]

test treetags-1.end "cleanup" -body {
    $tv item item1 -tags tag1
    $tv item item2 -tags tag2
    list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3]
} -cleanup {
    treeConstraints $tv
} -result [list [list item1] [list item2] [list]]

test treetags-2.0 "tag bind" -body {
    $tv tag bind tag1 <Key> {set ::KEY %A}
    $tv tag bind tag1 <Key>
} -cleanup {
    treeConstraints $tv
} -result {set ::KEY %A}

test treetags-2.1 "Events delivered to tags" -body {
    focus -force $tv ; update	;# needed so [event generate] delivers Key
    $tv focus item1
    event generate $tv <a>
    set ::KEY
} -cleanup {
    treeConstraints $tv
} -result a

test treetags-2.2 "Events delivered to correct tags" -body {
    $tv tag bind tag2 <Key> [list set ::KEY2 %A]

    $tv focus item1
    event generate $tv <b>
    $tv focus item2
    event generate $tv <c>

    list $::KEY $::KEY2
} -cleanup {
    treeConstraints $tv
} -result [list b c]

test treetags-2.3 "Virtual events delivered to focus item" -body {







<
<
<
<
<
<









|
|





|

|






|


|

|







110
111
112
113
114
115
116






117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
} -result [list tag1 tag2 tag3 tag4]

test treetags-1.10 "tag names - tag configured" -body {
    $tv tag configure tag5
    lsort [$tv tag names]
} -result [list tag1 tag2 tag3 tag4 tag5]







test treetags-1.end "cleanup" -body {
    $tv item item1 -tags tag1
    $tv item item2 -tags tag2
    list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3]
} -cleanup {
    treeConstraints $tv
} -result [list [list item1] [list item2] [list]]

test treetags-2.0 "tag bind" -body {
    $tv tag bind tag1 <KeyPress> {set ::KEY %A}
    $tv tag bind tag1 <KeyPress>
} -cleanup {
    treeConstraints $tv
} -result {set ::KEY %A}

test treetags-2.1 "Events delivered to tags" -body {
    focus -force $tv ; update	;# needed so [event generate] delivers KeyPress
    $tv focus item1
    event generate $tv <KeyPress-a>
    set ::KEY
} -cleanup {
    treeConstraints $tv
} -result a

test treetags-2.2 "Events delivered to correct tags" -body {
    $tv tag bind tag2 <KeyPress> [list set ::KEY2 %A]

    $tv focus item1
    event generate $tv <KeyPress-b>
    $tv focus item2
    event generate $tv <KeyPress-c>

    list $::KEY $::KEY2
} -cleanup {
    treeConstraints $tv
} -result [list b c]

test treetags-2.3 "Virtual events delivered to focus item" -body {

Changes to tests/ttk/treeview.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do
# what it currently does)
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

# consistencyCheck --
#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]





|
|
<







1
2
3
4
5
6
7

8
9
10
11
12
13
14
#
# [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do
# what it currently does)
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

# consistencyCheck --
#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    .tv selection
} -result {}

test treeview-8.5 "Selection - bad operation" -body {
    .tv selection badop foo
} -returnCodes error -match glob -result {bad selection operation "badop": must be *}

test treeview-8.6 "Selection - <<TreeviewSelect>> on selection add" -body {
    .tv selection set {}
    bind .tv <<TreeviewSelect>> {set res 1}
    set res 0
    .tv selection add newnode.n1
    update
    set res
} -result 1

test treeview-8.7 "<<TreeviewSelect>> on selected item deletion" -body {
    .tv selection set {}
    .tv insert "" end -id selectedDoomed -text DeadItem
    .tv insert "" end -id doomed -text AlsoDead
    .tv selection add selectedDoomed
    update
    bind .tv <<TreeviewSelect>> {lappend res 1}
    set res 0
    .tv delete doomed
    update
    set res [expr {$res == 0}]
    .tv delete selectedDoomed
    update
    set res
} -result {1 1}

### NEED: more tests for see/yview/scrolling

proc scrollcallback {args} {
    set ::scrolldata $args
}
test treeview-9.0 "scroll callback - empty tree" -body {
    .tv configure -yscrollcommand scrollcallback
    .tv delete [.tv children {}]
    update
    set ::scrolldata
} -result [list 0.0 1.0]

test treeview-9.1 "scrolling" -setup {
    pack [ttk::treeview .tree -show tree] -fill y
    for {set i 1} {$i < 100} {incr i} {
        .tree insert {} end -text $i
    }
} -body {
    .tree yview scroll 5 units
    .tree identify item 2 2
} -cleanup {
    destroy .tree
} -result {I006}

test treeview-9.2 {scrolling on see command - bug [14188104c3]} -setup {
    toplevel .top
    ttk::treeview .top.tree -show {} -height 10 -columns {label} \
            -yscrollcommand [list .top.vs set]
    ttk::scrollbar .top.vs -command {.top.tree yview}
    grid .top.tree -row 0 -column 0 -sticky ns
    grid .top.vs -row 0 -column 1 -sticky ns
    update
    proc setrows {n} {
        .top.tree delete [.top.tree children {}]
        for {set i 1} {$i <= $n} {incr i} {
            .top.tree insert {} end -id row$i \
                    -values [list [format "Row %2.2d" $i]]
        }
        .top.tree see row1
        update idletasks
    }
} -body {
    setrows 10
    set res [.top.vs get]
    setrows 20
    lappend res [expr [lindex [.top.vs get] 1] < 1]
} -cleanup {
    destroy .top
} -result {0.0 1.0 1}

test treeview-9.3 {scrolling on see command, requested item is closed} -setup {
    toplevel .top
    ttk::treeview .top.tree -show tree -height 10 -columns {label} \
            -yscrollcommand [list .top.vs set]
    ttk::scrollbar .top.vs -command {.top.tree yview}
    grid .top.tree -row 0 -column 0 -sticky ns
    grid .top.vs -row 0 -column 1 -sticky ns

    .top.tree insert {} end -id a -text a
    .top.tree insert a  end -id b -text b
    .top.tree insert b  end -id c -text c
    .top.tree insert c  end -id d -text d
    .top.tree insert d  end -id e -text e
    for {set i 6} {$i <= 15} {incr i} {
        .top.tree insert {} end -id row$i \
                -values [list [format "Row %2.2d" $i]]
    }
    update
} -body {
    set before [lindex [.top.vs get] 1]
    .top.tree see e
    update idletasks
    set after [lindex [.top.vs get] 1]
    expr $after < $before
} -cleanup {
    destroy .top
} -result 1

### identify tests:
#
proc identify* {tv comps args} {
    foreach {x y} $args {
	foreach comp $comps {
	    lappend result [$tv identify $comp $x $y]
	}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







455
456
457
458
459
460
461

























462
463
464
465
466
467
468
469
470
471
472
473


































































474
475
476
477
478
479
480
    .tv selection
} -result {}

test treeview-8.5 "Selection - bad operation" -body {
    .tv selection badop foo
} -returnCodes error -match glob -result {bad selection operation "badop": must be *}


























### NEED: more tests for see/yview/scrolling

proc scrollcallback {args} {
    set ::scrolldata $args
}
test treeview-9.0 "scroll callback - empty tree" -body {
    .tv configure -yscrollcommand scrollcallback
    .tv delete [.tv children {}]
    update
    set ::scrolldata
} -result [list 0.0 1.0]



































































### identify tests:
#
proc identify* {tv comps args} {
    foreach {x y} $args {
	foreach comp $comps {
	    lappend result [$tv identify $comp $x $y]
	}
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
} -cleanup {
    destroy .tv
}

test treeview-3006842 "Null bindings" -setup {
    ttk::treeview .tv -show tree
} -body {
    .tv tag bind empty <Button-1> {}
    .tv insert {} end -text "Click me" -tags empty
    event generate .tv <Button-1> -x 10 -y 10
    .tv tag bind empty
} -result {} -cleanup {
    destroy .tv
}

test treeview-3085489-1 "tag add, no -tags" -setup {
    ttk::treeview .tv







|

|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
} -cleanup {
    destroy .tv
}

test treeview-3006842 "Null bindings" -setup {
    ttk::treeview .tv -show tree
} -body {
    .tv tag bind empty <ButtonPress-1> {}
    .tv insert {} end -text "Click me" -tags empty
    event generate .tv <ButtonPress-1> -x 10 -y 10
    .tv tag bind empty
} -result {} -cleanup {
    destroy .tv
}

test treeview-3085489-1 "tag add, no -tags" -setup {
    ttk::treeview .tv
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
    set item [.tv insert {} end]
    .tv tag remove foo $item
    .tv item $item -tags
} -cleanup {
    destroy .tv
} -result [list]

test treeview-368fa4561e "indicators cannot be clicked on leafs" -setup {
    pack [ttk::treeview .tv]
    .tv insert {} end -id foo -text "<-- (1) Click the blank space to my left"
    update
} -body {
    foreach {x y w h} [.tv bbox foo #0] {}
    set res [.tv item foo -open]
    # using $h even for x computation is intentional here in order to simulate
    # a mouse click on the (invisible since we're on a leaf) indicator
    event generate .tv <Button-1> \
            -x [expr {$x + $h / 2}] \
            -y [expr {$y + $h / 2}]
    lappend res [.tv item foo -open]
    .tv insert foo end -text "sub"
    lappend res [.tv item foo -open]
} -cleanup {
    destroy .tv
} -result {0 0 0}

test treeview-ce470f20fd-1 "dragging further than the right edge of the treeview is allowed" -setup {
    pack [ttk::treeview .tv]
    .tv heading #0 -text "Drag my right edge -->"
    update
} -body {
    set res [.tv column #0 -width]
    .tv drag #0 400
    lappend res [expr {[.tv column #0 -width] > $res}]
} -cleanup {
    destroy .tv
} -result {200 1}

proc nostretch {tv} {
    foreach col [$tv cget -columns] {
        $tv column $col -stretch 0
    }
    $tv column #0 -stretch 0
    update idletasks ; # redisplay $tv
}

test treeview-ce470f20fd-2 "changing -stretch resizes columns" -setup {
    pack [ttk::treeview .tv -columns {bar colA colB colC foo}]
    foreach col [.tv cget -columns] {
        .tv heading $col -text $col
    }
    nostretch .tv
    .tv column colA -width 50 ; .tv column colB -width 50 ; # slack created
    update idletasks ; # redisplay treeview
} -body {
    # when no column is stretchable and one of them becomes stretchable
    # the stretchable column takes the slack and the widget is redisplayed
    # automatically at idle time
    set res [.tv column colA -width]
    .tv column colA -stretch 1
    update idletasks ; # no slack anymore, widget redisplayed
    lappend res [expr {[.tv column colA -width] > $res}]
} -cleanup {
    destroy .tv
} -result {50 1}

test treeview-ce470f20fd-3 "changing -stretch resizes columns" -setup {
    pack [ttk::treeview .tv -columns {bar colA colB colC foo}]
    foreach col [.tv cget -columns] {
        .tv heading $col -text $col
    }
    .tv configure -displaycolumns {colB colA colC}
    nostretch .tv
    .tv column colA -width 50 ; .tv column colB -width 50 ; # slack created
    update idletasks ; # redisplay treeview
} -body {
    # only some columns are displayed (and in a different order than declared
    # in -columns), a displayed column becomes stretchable  --> the stretchable
    # column expands
    set res [.tv column colA -width]
    .tv column colA -stretch 1
    update idletasks ; # no slack anymore, widget redisplayed
    lappend res [expr {[.tv column colA -width] > $res}]
} -cleanup {
    destroy .tv
} -result {50 1}

test treeview-ce470f20fd-4 "changing -stretch resizes columns" -setup {
    pack [ttk::treeview .tv -columns {bar colA colB colC foo}]
    foreach col [.tv cget -columns] {
        .tv heading $col -text $col
    }
    .tv configure -displaycolumns {colB colA colC}
    nostretch .tv
    .tv column colA -width 50 ; .tv column bar -width 60 ; # slack created
    update idletasks ; # redisplay treeview
} -body {
    # only some columns are displayed (and in a different order than declared
    # in -columns), a non-displayed column becomes stretchable  --> nothing
    # happens
    set origTreeWidth [winfo width .tv]
    set res [list [.tv column bar -width] [.tv column colA -width]]
    .tv column bar -stretch 1
    update idletasks ; # no change, widget redisplayed
    lappend res [.tv column bar -width] [.tv column colA -width]
    # this column becomes visible  --> widget resizes
    .tv configure -displaycolumns {bar colC colA colB}
    update idletasks ; # no slack anymore because the widget resizes (shrinks)
    lappend res [.tv column bar -width] [.tv column colA -width] \
                [expr {[winfo width .tv] < $origTreeWidth}]
} -cleanup {
    destroy .tv
} -result {60 50 60 50 60 50 1}

tcltest::cleanupTests







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

632
633
634
635
636
637
638











































































































639
    set item [.tv insert {} end]
    .tv tag remove foo $item
    .tv item $item -tags
} -cleanup {
    destroy .tv
} -result [list]












































































































tcltest::cleanupTests

Changes to tests/ttk/ttk.test.

1
2
3
4
5


6
7
8
9
10
11
12

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands



proc skip args {}
proc ok {} { return }

variable widgetClasses {
    button checkbutton radiobutton menubutton label entry
    frame labelframe scrollbar

|
|
<

>
>







1
2
3

4
5
6
7
8
9
10
11
12
13

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

proc skip args {}
proc ok {} { return }

variable widgetClasses {
    button checkbutton radiobutton menubutton label entry
    frame labelframe scrollbar
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
    .t.b invoke
    list [winfo exists .t] [winfo exists .t.b]
} -result [list 0 0]

#
# Basic tests.
#
test ttk-1.1 "Create multiline button showing justified text" -body {
    pack [ttk::button .t -text "Hello\nWorld!!" -justify center] -expand true -fill both
    update
}

test ttk-1.2 "Check style" -body {
    .t cget -style
} -result {}








|
|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    .t.b invoke
    list [winfo exists .t] [winfo exists .t.b]
} -result [list 0 0]

#
# Basic tests.
#
test ttk-1.1 "Create button" -body {
    pack [ttk::button .t] -expand true -fill both
    update
}

test ttk-1.2 "Check style" -body {
    .t cget -style
} -result {}

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227





228
229
230
231
232
233
234
235
236
237
238

test ttk-2.7 "instate scripts, true" -body {
    set x 0
    .t instate !disabled { set x 1 }
    set x
} -result 1

test ttk-2.8 "bug 3223850: button state disabled during click" -setup {
    destroy .b
    set ttk28 {}
    pack [ttk::button .b -command {set ::ttk28 failed}]
    update
} -body {
    bind .b <Button-1> {after 0 {.b configure -state disabled}}
    after 1 {event generate .b <Button-1>}
    after 20 {event generate .b <ButtonRelease-1>}
    set aid [after 100 {set ::ttk28 [.b instate {disabled !pressed}]}]
    vwait ::ttk28
    after cancel $aid
    set ttk28
} -cleanup {
    destroy .b
    unset -nocomplain ttk28 aid
} -result 1

foreach wc $widgetClasses {
    test ttk-coreoptions-$wc "$wc has all core options" -body {
	ttk::$wc .w
	foreach option {-class -style -cursor -takefocus} {





	    .w cget $option
	}
    } -cleanup {
	catch {destroy .w}
    }
}

# misc. error detection
test ttk-3.0 "Bad option" -body {
    ttk::button .bad -badoption foo
} -returnCodes error -result {unknown option "-badoption"} -match glob







|



<

|
|













|
>
>
>
>
>


<
|







200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242

test ttk-2.7 "instate scripts, true" -body {
    set x 0
    .t instate !disabled { set x 1 }
    set x
} -result 1

test ttk-2.8 "bug 3223850: button state disabled during click" -constraints failsOnQuarz -setup {
    destroy .b
    set ttk28 {}
    pack [ttk::button .b -command {set ::ttk28 failed}]

} -body {
    bind .b <ButtonPress-1> {after 0 {.b configure -state disabled}}
    after 1 {event generate .b <ButtonPress-1>}
    after 20 {event generate .b <ButtonRelease-1>}
    set aid [after 100 {set ::ttk28 [.b instate {disabled !pressed}]}]
    vwait ::ttk28
    after cancel $aid
    set ttk28
} -cleanup {
    destroy .b
    unset -nocomplain ttk28 aid
} -result 1

foreach wc $widgetClasses {
    test ttk-coreoptions-$wc "$wc has all core options" -body {
	ttk::$wc .w
	foreach option {
	    -class
	    -style
	    -cursor
	    -takefocus
	} {
	    .w cget $option
	}

	destroy .w
    }
}

# misc. error detection
test ttk-3.0 "Bad option" -body {
    ttk::button .bad -badoption foo
} -returnCodes error -result {unknown option "-badoption"} -match glob
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# (@@@ "-font" is a compatibility option now, so tests 4.1-4.3
# don't really test anything useful at the moment.)
#

test ttk-4.0 "Setup" -body {
    catch { destroy .t }
    pack [ttk::label .t -text "Button 1"]
    testConstraint fontOption [expr {![catch { set prevFont [.t cget -font] }]}]
    ok
}

test ttk-4.1 "Change font" -constraints fontOption -body {
    .t configure -font "Helvetica 18 bold"
}
test ttk-4.2 "Check font" -constraints fontOption -body {







|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# (@@@ "-font" is a compatibility option now, so tests 4.1-4.3
# don't really test anything useful at the moment.)
#

test ttk-4.0 "Setup" -body {
    catch { destroy .t }
    pack [ttk::label .t -text "Button 1"]
    testConstraint fontOption [expr ![catch { set prevFont [.t cget -font] }]]
    ok
}

test ttk-4.1 "Change font" -constraints fontOption -body {
    .t configure -font "Helvetica 18 bold"
}
test ttk-4.2 "Check font" -constraints fontOption -body {
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
} -result {}

test ttk-12.2 "-cursor option" -body {
    .b configure -cursor arrow
    .b cget -cursor
} -result arrow

test ttk-12.2.1 "-cursor option, widget doesn't overwrite it" -setup {
    ttk::treeview .tr
    pack .tr
    update
} -body {
    .tr configure -cursor X_cursor
    event generate .tr <Motion>
    update
    .tr cget -cursor
} -cleanup {
    destroy .tr
} -result {X_cursor}

test ttk-12.3 "-borderwidth frame option" -body {
    destroy .t
    toplevel .t
    raise .t
    pack [set t [ttk::frame .t.f]] -expand true -fill x ;
    pack [ttk::label $t.l -text "ASDF QWERTY"] -expand true -fill both
    foreach theme {default alt} {







<
<
<
<
<
<
<
<
<
<
<
<
<







508
509
510
511
512
513
514













515
516
517
518
519
520
521
} -result {}

test ttk-12.2 "-cursor option" -body {
    .b configure -cursor arrow
    .b cget -cursor
} -result arrow














test ttk-12.3 "-borderwidth frame option" -body {
    destroy .t
    toplevel .t
    raise .t
    pack [set t [ttk::frame .t.f]] -expand true -fill x ;
    pack [ttk::label $t.l -text "ASDF QWERTY"] -expand true -fill both
    foreach theme {default alt} {

Changes to tests/ttk/validate.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
##
## Entry widget validation tests
## Derived from core test suite entry-19.1 through entry-19.20
##

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*

loadTestedCommands

testConstraint ttkEntry 1
testConstraint coreEntry [expr {![testConstraint ttkEntry]}]





|







1
2
3
4
5
6
7
8
9
10
11
12
13
##
## Entry widget validation tests
## Derived from core test suite entry-19.1 through entry-19.20
##

package require Tk 8.5
package require tcltest 2.2
namespace import -force tcltest::*

loadTestedCommands

testConstraint ttkEntry 1
testConstraint coreEntry [expr {![testConstraint ttkEntry]}]

Changes to tests/ttk/vsapi.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- tcl -*-
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint xpnative \
    [expr {"xpnative" in [ttk::style theme names]}]

test vsapi-1.1 "WINDOW WP_SMALLCLOSEBUTTON" -constraints {xpnative} -body {
    ttk::style element create smallclose vsapi \
        WINDOW 19 {disabled 4 pressed 3 active 2 {} 1}
    ttk::style layout CloseButton {CloseButton.smallclose -sticky news}
    ttk::button .b -style CloseButton
    pack .b -expand true -fill both



|
|
<



|







1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
# -*- tcl -*-
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*

loadTestedCommands

testConstraint xpnative \
    [expr {[lsearch -exact [ttk::style theme names] xpnative] != -1}]

test vsapi-1.1 "WINDOW WP_SMALLCLOSEBUTTON" -constraints {xpnative} -body {
    ttk::style element create smallclose vsapi \
        WINDOW 19 {disabled 4 pressed 3 active 2 {} 1}
    ttk::style layout CloseButton {CloseButton.smallclose -sticky news}
    ttk::button .b -style CloseButton
    pack .b -expand true -fill both

Changes to tests/unixButton.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file is a Tcl script to test the Unix specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkUnixButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Label.borderWidth 2
option add *Label.highlightThickness 0
option add *Label.font {Helvetica -12 bold}





|
|
|





<
<







1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
# This file is a Tcl script to test the Unix specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkUnixButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



# Create entries in the option database to be sure that geometry options
# like border width have predictable values.

option add *Label.borderWidth 2
option add *Label.highlightThickness 0
option add *Label.font {Helvetica -12 bold}
30
31
32
33
34
35
36


37
38
39
40
41
42
43


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
option add *Radiobutton.highlightThickness 2
option add *Radiobutton.font {Helvetica -12 bold}


proc bogusTrace args {
    error "trace aborted"
}



if {[tk windowingsystem] eq "aqua"} {
    set smallIndicator 20
    set bigIndicator 20
    set defaultBorder 10
} else {
    set smallIndicator 27


    set bigIndicator 40
    set defaultBorder 20
}
test unixbutton-1.1 {TkpComputeButtonGeometry procedure} -constraints {
    unix testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    image1 changed 0 0 0 0 60 40
    label .b1 -image image1 -bd 4 -padx 0 -pady 2
    button .b2 -image image1 -bd 4 -padx 0 -pady 2
    checkbutton .b3 -image image1 -bd 4 -padx 1 -pady 1
    radiobutton .b4 -image image1 -bd 4 -padx 2 -pady 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
    image delete image1
} -result [list 68 48 \
                74 54 \
	        [expr {72 + $bigIndicator}] 52 \
	        [expr {72 + $bigIndicator}] 52]
test unixbutton-1.2 {TkpComputeButtonGeometry procedure} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    label .b1 -bitmap question -bd 3 -padx 0 -pady 2
    button .b2 -bitmap question -bd 3 -padx 0 -pady 2
    checkbutton .b3 -bitmap question -bd 3 -padx 1 -pady 1
    radiobutton .b4 -bitmap question -bd 3 -padx 2 -pady 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result [list 23 33 \
	        29 39 \
	        [expr {27 + $smallIndicator}] 37 \
	        [expr {27 + $smallIndicator}] 37]
test unixbutton-1.3 {TkpComputeButtonGeometry procedure} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    label .b1 -bitmap question -bd 3 -highlightthickness 4
    button .b2 -bitmap question -bd 3 -highlightthickness 0
    checkbutton .b3 -bitmap question -bd 3 -highlightthickness 1 \
        -indicatoron 0
    radiobutton .b4 -bitmap question -bd 3 -highlightthickness 1 \
    -indicatoron false
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {31 41 25 35 25 35 25 35}
test unixbutton-1.4 {TkpComputeButtonGeometry procedure} -constraints {
    unix nonPortable fonts
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -padx 0 -pady 2 -font {Helvetica -18 bold}
    button .b2 -text Xagqpim -padx 0 -pady 2 -font {Helvetica -18 bold}
    checkbutton .b3 -text Xagqpim -padx 1 -pady 1 -font {Helvetica -18 bold}
    radiobutton .b4 -text Xagqpim -padx 2 -pady 0 -font {Helvetica -18 bold}
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {82 29 88 35 114 31 121 29}
test unixbutton-1.5 {TkpComputeButtonGeometry procedure} -constraints {
    unix nonPortable fonts
} -setup {
    deleteWindows
} -body {
    label .l1 -text "This is a long string that will wrap around on several lines.\n\nIt also has a blank line (above)." -wraplength 1.5i -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]
} -cleanup {
    deleteWindows
} -result {136 88}
test unixbutton-1.6 {TkpComputeButtonGeometry procedure} -constraints {
    unix nonPortable fonts
} -setup {
    deleteWindows
} -body {
    label .l1 -text "This is a long string without wrapping.\n\nIt also has a blank line (above)." -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]
} -cleanup {
    deleteWindows
} -result {231 46}
test unixbutton-1.7 {TkpComputeButtonGeometry procedure} -constraints {
    unix nonPortable fonts
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -width 10
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -height 5
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -width 20 -height 2
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -width 4
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {74 22 60 84 168 38 61 22}
test unixbutton-1.8 {TkpComputeButtonGeometry procedure} -constraints {
    unix nonPortable fonts
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 \
    -highlightthickness 4
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 \
    -highlightthickness 0
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1  \
    -highlightthickness 1 -indicatoron no
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -indicatoron 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {62 30 56 24 58 22 62 22}
test unixbutton-1.9 {TkpComputeButtonGeometry procedure} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    button .b2 -bitmap question -default active
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
    deleteWindows
} -result [list [expr {17 + $defaultBorder}] [expr {27 + $defaultBorder}]]
test unixbutton-1.10 {TkpComputeButtonGeometry procedure} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    button .b2 -bitmap question -default normal
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
    deleteWindows
} -result [list [expr {17 + $defaultBorder}] [expr {27 + $defaultBorder}]]
test unixbutton-1.11 {TkpComputeButtonGeometry procedure} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    button .b2 -bitmap question -default disabled
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
    deleteWindows
} -result {27 37}


test unixbutton-2.1 {disabled coloring check, bug 669595} -constraints {
    unix
} -setup {
    deleteWindows
    catch {unset value}
} -body {
    # this was just a visual bug, but at least this shows the visual

    set on 1
    set off 0
    label .l -text "The following widgets should\
        \nshow significant visible diffs\
        \nfor selected vs unselected."
    checkbutton .cb0 -anchor w -state disabled \
        -text Unselected -variable off
    checkbutton .cb1 -anchor w -state disabled \
        -text Selected -variable on
    checkbutton .cb2 -anchor w -state disabled \
        -text Unselected -variable off -disabledforeground ""
    checkbutton .cb3 -anchor w -state disabled \
        -text Selected -variable on -disabledforeground ""
    radiobutton .rb0 -anchor w -state disabled \
        -text Unselected -variable off
    radiobutton .rb1 -anchor w -state disabled \
        -text Selected -variable on -value 1
    radiobutton .rb2 -anchor w -state disabled \
        -text Unselected -variable off -disabledforeground ""
    radiobutton .rb3 -anchor w -state disabled \
        -text Selected -variable on -value 1 -disabledforeground ""
    pack .l .cb0 .cb1 .cb2 .cb3 .rb0 .rb1 .rb2 .rb3 -side top -fill x
    after 400
    set on

} -cleanup {
    deleteWindows
} -result 1


# cleanup
imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:







>
>

<
<
|
|
|
|
>
>
|
<
|
|
<
<

<
<









|
|
|
<
<
<
<
|
<
<
|
<
<

<







|
|
|
<
<
<
|
<
<
|
<
<

<



|

|



|
|
|
<
<
|
|
<
<

<







|
|
|
<
<
|
|
<
<

<




<
<
|
|
<
<

<




<
<
|
|
<
<

<







|
|
|
<
<
|
|
<
<

<

|

|

|




|
|
|
<
<
|
|
<
<

<


|
<
<
|
<
<

<


|
<
<
|
<
<

<


<
<
|

<
|
<
<
<
<
<

>



|
|

|

|

|

|

|

|

|

|



>
|
|
<

<

<


<
<
<
<
28
29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44

45
46


47


48
49
50
51
52
53
54
55
56
57
58
59




60


61


62

63
64
65
66
67
68
69
70
71
72



73


74


75

76
77
78
79
80
81
82
83
84
85
86
87


88
89


90

91
92
93
94
95
96
97
98
99
100


101
102


103

104
105
106
107


108
109


110

111
112
113
114


115
116


117

118
119
120
121
122
123
124
125
126
127


128
129


130

131
132
133
134
135
136
137
138
139
140
141
142
143


144
145


146

147
148
149


150


151

152
153
154


155


156

157
158


159
160

161





162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191

192

193
194




option add *Radiobutton.highlightThickness 2
option add *Radiobutton.font {Helvetica -12 bold}


proc bogusTrace args {
    error "trace aborted"
}
catch {unset value}
catch {unset value2}



eval image delete [image names]
label .l -text Label
button .b -text Button
checkbutton .c -text Checkbutton
radiobutton .r -text Radiobutton
pack .l .b .c .r
update


test unixbutton-1.1 {TkpComputeButtonGeometry procedure} {unix testImageType} {


    deleteWindows


    image create test image1
    image1 changed 0 0 0 0 60 40
    label .b1 -image image1 -bd 4 -padx 0 -pady 2
    button .b2 -image image1 -bd 4 -padx 0 -pady 2
    checkbutton .b3 -image image1 -bd 4 -padx 1 -pady 1
    radiobutton .b4 -image image1 -bd 4 -padx 2 -pady 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]




} {68 48 74 54 112 52 112 52}


test unixbutton-1.2 {TkpComputeButtonGeometry procedure} unix {


    deleteWindows

    label .b1 -bitmap question -bd 3 -padx 0 -pady 2
    button .b2 -bitmap question -bd 3 -padx 0 -pady 2
    checkbutton .b3 -bitmap question -bd 3 -padx 1 -pady 1
    radiobutton .b4 -bitmap question -bd 3 -padx 2 -pady 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]



} {23 33 29 39 54 37 54 37}


test unixbutton-1.3 {TkpComputeButtonGeometry procedure} unix {


    deleteWindows

    label .b1 -bitmap question -bd 3 -highlightthickness 4
    button .b2 -bitmap question -bd 3 -highlightthickness 0
    checkbutton .b3 -bitmap question -bd 3 -highlightthickness 1 \
	    -indicatoron 0
    radiobutton .b4 -bitmap question -bd 3 -highlightthickness 1 \
	-indicatoron false
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {31 41 25 35 25 35 25 35}
test unixbutton-1.4 {TkpComputeButtonGeometry procedure} {unix nonPortable fonts} {


    deleteWindows

    label .b1 -text Xagqpim -padx 0 -pady 2 -font {Helvetica -18 bold}
    button .b2 -text Xagqpim -padx 0 -pady 2 -font {Helvetica -18 bold}
    checkbutton .b3 -text Xagqpim -padx 1 -pady 1 -font {Helvetica -18 bold}
    radiobutton .b4 -text Xagqpim -padx 2 -pady 0 -font {Helvetica -18 bold}
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {82 29 88 35 114 31 121 29}
test unixbutton-1.5 {TkpComputeButtonGeometry procedure} {unix nonPortable fonts} {


    deleteWindows

    label .l1 -text "This is a long string that will wrap around on several lines.\n\nIt also has a blank line (above)." -wraplength 1.5i -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]


} {136 88}
test unixbutton-1.6 {TkpComputeButtonGeometry procedure} {unix nonPortable fonts} {


    deleteWindows

    label .l1 -text "This is a long string without wrapping.\n\nIt also has a blank line (above)." -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]


} {231 46}
test unixbutton-1.7 {TkpComputeButtonGeometry procedure} {unix nonPortable fonts} {


    deleteWindows

    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -width 10
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -height 5
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -width 20 -height 2
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -width 4
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {74 22 60 84 168 38 61 22}
test unixbutton-1.8 {TkpComputeButtonGeometry procedure} {unix nonPortable fonts} {


    deleteWindows

    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 \
	-highlightthickness 4
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 \
	-highlightthickness 0
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1  \
	-highlightthickness 1 -indicatoron no
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -indicatoron 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {62 30 56 24 58 22 62 22}
test unixbutton-1.9 {TkpComputeButtonGeometry procedure} unix {


    deleteWindows

    button .b2 -bitmap question -default active
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} {37 47}


test unixbutton-1.10 {TkpComputeButtonGeometry procedure} unix {


    deleteWindows

    button .b2 -bitmap question -default normal
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} {37 47}


test unixbutton-1.11 {TkpComputeButtonGeometry procedure} unix {


    deleteWindows

    button .b2 -bitmap question -default disabled
    list [winfo reqwidth .b2] [winfo reqheight .b2]


} {27 37}


test unixbutton-2.1 {disabled coloring check, bug 669595} unix {





    # this was just a visual bug, but at least this shows the visual
    deleteWindows
    set on 1
    set off 0
    label .l -text "The following widgets should\
	    \nshow significant visible diffs\
	    \nfor selected vs unselected."
    checkbutton .cb0 -anchor w -state disabled \
	    -text Unselected -variable off
    checkbutton .cb1 -anchor w -state disabled \
	    -text Selected -variable on
    checkbutton .cb2 -anchor w -state disabled \
	    -text Unselected -variable off -disabledforeground ""
    checkbutton .cb3 -anchor w -state disabled \
	    -text Selected -variable on -disabledforeground ""
    radiobutton .rb0 -anchor w -state disabled \
	    -text Unselected -variable off
    radiobutton .rb1 -anchor w -state disabled \
	    -text Selected -variable on -value 1
    radiobutton .rb2 -anchor w -state disabled \
	    -text Unselected -variable off -disabledforeground ""
    radiobutton .rb3 -anchor w -state disabled \
	    -text Selected -variable on -value 1 -disabledforeground ""
    pack .l .cb0 .cb1 .cb2 .cb3 .rb0 .rb1 .rb2 .rb3 -side top -fill x
    after 400
    set on
} 1

deleteWindows



# cleanup

cleanupTests
return




Changes to tests/unixEmbed.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# This file is a Tcl script to test out the procedures in the file
# tkUnixEmbed.c.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

namespace eval ::_test_tmp {}

# ------------------------------------------------------------------------------
#  Proc ::_test_tmp::testInterp
# ------------------------------------------------------------------------------
# Command that creates an child interpreter and tries to load Tk.
# This code is borrowed from safePrimarySelection.test
# This is necessary for loading Tktest if the tests are done in the build
# directory without installing Tk.  In that case the usual auto_path loading
# mechanism cannot work because the tk binary is not where pkgIndex.tcl says
# it is.
# ------------------------------------------------------------------------------

namespace eval ::_test_tmp {
    variable TkLoadCmd
}

foreach pkg [info loaded] {
    if {[lindex $pkg 1] eq "Tk"} {
	set ::_test_tmp::TkLoadCmd [list load {*}$pkg]
	break
    }
}

proc ::_test_tmp::testInterp {name} {
    variable TkLoadCmd
    interp create $name
    $name eval [list set argv [list -name $name]]
    catch {{*}$TkLoadCmd $name}
}

setupbg
dobg {wm withdraw .}

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.




|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11



































12
13
14
15
16
17
18
# This file is a Tcl script to test out the procedures in the file
# tkUnixEmbed.c.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands




































setupbg
dobg {wm withdraw .}

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340

341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737












738


739












740





741

742



743
744
745





746







747
748
749
750
751
752




753
754

755



756

757









758



759



760
761
762
763
764
765
766
767

768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \
	    && ([lindex $vals 2]/256 == $blue)
}

testConstraint pressbutton [llength [info commands pressbutton]]

test unixEmbed-1.1 {TkpUseWindow procedure, bad window identifier} -constraints {
	unix
} -setup {
	deleteWindows
} -body {
    toplevel .t -use xyz
} -returnCodes error -result {expected integer but got "xyz"}
test unixEmbed-1.2 {TkpUseWindow procedure, bad window identifier} -constraints {
	unix
} -setup {
	deleteWindows
} -body {
    toplevel .t -use 47
} -returnCodes error -result {couldn't create child of window "47"}
test unixEmbed-1.3 {TkpUseWindow procedure, inheriting colormap} -constraints {
	unix nonPortable
} -setup {
	deleteWindows
} -body {
    toplevel .t -colormap new
    wm geometry .t +0+0
    eatColors .t.t
    frame .t.f -container 1
    toplevel .x -use [winfo id .t.f]
    colorsFree .x
} -cleanup {
	deleteWindows
} -result 0

test unixEmbed-1.4 {TkpUseWindow procedure, inheriting colormap} -constraints {
	unix nonPortable
} -setup {
	deleteWindows
} -body {
    toplevel .t -container 1 -colormap new
    wm geometry .t +0+0
    eatColors .t2
    toplevel .x -use [winfo id .t]
    colorsFree .x
} -cleanup {
	deleteWindows
} -result 1


test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t -use $w
	list [testembed] [expr [lindex [lindex [testembed all] 0] 0] - $w]
    }
} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.5a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t -use [w]
        list [testembed] [expr {[lindex [lindex [testembed all] 0] 0] - [w]}]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg "set w2 [winfo id .f2]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    toplevel .t2 -use $w2
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.6a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w1 winfo id .f1
    child alias w2 winfo id .f2
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        toplevel .t2 -use [w2]
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    toplevel .t1 -use [winfo id .f1]
    toplevel .t2 -use [winfo id .f2]
    testembed
} -cleanup {
	deleteWindows
} -result {{XXX .f2 {} .t2} {XXX .f1 {} .t1}}

# Can't think of any way to test the procedures TkpMakeWindow,
# TkpMakeContainer, or EmbedErrorProc.


test unixEmbed-2.1 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    testembed
    }
    destroy .f1
    update
    dobg {
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.1a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
    }
    destroy .f1
    update
    child eval {
        testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    testembed
	    destroy .t1
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.2a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
        destroy .t1
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    toplevel .t1 -use [winfo id .f1]
    update
    destroy .f1
    testembed
} -result {}
test unixEmbed-2.4 {EmbeddedEventProc procedure} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    pack [frame .f1 -container 1 -width 200 -height 50]

    toplevel .t1 -use [winfo id .f1]
    set x [testembed]
    update
    destroy .t1

    update
    list $x [winfo exists .t1] [winfo exists .f1] [testembed]
} -cleanup {
	deleteWindows
} -result "{{XXX .f1 {} .t1}} 0 0 {}"


test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed nonPortable
} -body {

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    set x [testembed]
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
	deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}
test unixEmbed-3.1a {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed
} -setup {
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    set x [testembed]
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 {} {}}}}
test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constraints {
	unix
} -setup {
	deleteWindows
    update
} -body {
    toplevel .t1 -container 1
    wm geometry .t1 +0+0
    toplevel .t2 -use [winfo id .t1] -bg red
    update
    wm geometry .t2
} -cleanup {
	deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -bd 2 -relief raised
	    update
	    wm geometry .t1 +30+40
    }
    update
    dobg {
	    wm geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -bd 2 -relief raised
        update
        wm geometry .t1 +30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    update
	    wm geometry .t1 300x100+30+40
    }
    update
    dobg {
	    wm geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.4a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        wm geometry .t1 300x100+30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 300 -height 80
    }
    update
    list [winfo width .f1] [winfo height .f1] [dobg {wm geometry .t1}]
} -cleanup {
	deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.5a {ContainerEventProc procedure, geometry requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        .t1 configure -width 300 -height 80
        update
    }
    list [winfo width .f1] [winfo height .f1] [child eval {wm geometry .t1}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    set x unmapped
	    bind .t1 <Map> {set x mapped}
    }
    update
    dobg {
	    after 100
	    update
	    set x
    }
} -cleanup {
	deleteWindows
} -result {mapped}
test unixEmbed-3.6a {ContainerEventProc procedure, map requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x unmapped
        bind .t1 <Map> {set x mapped}
        update
        after 100
        update
        set x
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {mapped}
test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    bind .f1 <Destroy> {set x dead}
    set x alive
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
	deleteWindows
} -result {dead 0}
test unixEmbed-3.7a {ContainerEventProc procedure, destroy events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    bind .f1 <Destroy> {set x dead}
    set x alive
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
    interp delete child
    deleteWindows
} -result {dead 0}

test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 180 -height 100
    }
    update
    dobg {
	    winfo geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.1a {EmbedStructureProc procedure, configure events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        .t1 configure -width 180 -height 100
        update
        winfo geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    set x [testembed]
    destroy .f1
    update
    list $x [testembed]
} -cleanup {
	deleteWindows
} -result {{{XXX .f1 XXX {}}} {}}
test unixEmbed-4.2a {EmbedStructureProc procedure, destroy events} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    set x [testembed]
    destroy .f1
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result "{{XXX .f1 {} {}}} {}"


test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
    }
    focus -force .f1
    update
    dobg {set x}
} -cleanup {

	deleteWindows












} -result {{focus in .t1}}


test unixEmbed-5.1a {EmbedFocusProc procedure, FocusIn events} -constraints {












    unix





} -setup {

    deleteWindows



    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child





} -body {







    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]




        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}

        update



        set x {}

    }









    focus -force .f1



    update



    child eval {set x}
} -cleanup {
    interp delete child
    deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constraints {
	unix notAqua
} -setup {

	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-5.2a {EmbedFocusProc procedure, focusing on dead window} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
    }
    focus -force .f1
    update
    set x [dobg {update; set x}]
    focus .
    update
    list $x [dobg {update; set x}]
} -cleanup {
	deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
test unixEmbed-5.3a {EmbedFocusProc procedure, FocusOut events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x {}
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
    }
    focus -force .f1
    update
    set x [child eval {update; set x }]
    focus .
    update
    list $x [child eval {update; set x}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}


test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
            update
	    bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	    set x {}
	    .t1 configure -width 300 -height 120
	    update
	    list $x [winfo geom .t1]
    }
} -cleanup {
	deleteWindows
} -result {{{configure .t1 300 120}} 300x120+0+0}
test unixEmbed-6.1a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
        set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 300 120} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
            update
	    bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	    set x {}
	    .t1 configure -width 300 -height 120
            update
	    list $x [winfo geom .t1]
    }
} -cleanup {
	deleteWindows
} -result {{{configure .t1 200 200}} 200x200+0+0}
test unixEmbed-6.2a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
	set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 200 200} 200x200+0+0}

# Can't think up any tests for TkpGetOtherWindow procedure.

test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [dobg {
	    update
	    bind .t1 <Key> {lappend y {key %A}}
	    set y {}
	    event generate .t1 <Key> -keysym a
	    set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
# TkpRedirectKeyEvent is not implemented in win or aqua.  If someone
# implements it they should change the constraints for this test.
test unixEmbed-7.1a {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
    unix notAqua failsOnXQuarz
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym a
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
    set y [dobg {
	    update
	    bind .t1 <Key> {lappend y {key %A}}
	    set y {}
	    event generate .t1 <Key> -keysym b
	    set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}
test unixEmbed-7.2a {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym b
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}

test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
    unix notAqua failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
    }
    focus -force .f2
    update
    list [dobg {
	    focus .t1
	    set x [list [focus]]
	    update
	    after 500
	    update
	    lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.1a {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
    }
    # This should clear focus from the application embedded in .f1
    focus -force .f2
    update
    list [child eval {
        set x [list [focus]]
        focus .t1
	update
        lappend x [focus]
    }] [focus]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.2 {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete child}
    interp create child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    set w1 [winfo id .f1]
    child eval "set argv {-use [winfo id .f1]}"
    load {} Tk child
    child eval {
	    . configure -bd 2 -highlightthickness 2 -relief sunken
    }
    focus -force .f2
    update
    list [child eval {
	    focus .
	    set x [list [focus]]
	    update
	    lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
} -result {{{} .} .f1}
catch {interp delete child}

test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    frame .f3 -container 1 -width 200 -height 50
    frame .f4 -container 1 -width 200 -height 50
    pack .f1 .f2 .f3 .f4
    set x {}
    lappend x [testembed]
    foreach w {.f3 .f4 .f1 .f2} {
	    destroy $w
	    lappend x [testembed]
    }
    set x
} -cleanup {
	deleteWindows
} -result {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
	    set x {}
	    lappend x [testembed]
	    destroy .t1
	    lappend x [testembed]
    }
} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t1}} {}}
test unixEmbed-9.2a {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
        set x {}
        lappend x [testembed]
        destroy .t1
        lappend x [testembed]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t1}} {}}


test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix failsOnUbuntu failsOnXQuarz
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update idletasks
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update idletasks
    wm geometry .t1 +40+50
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix failsOnUbuntu failsOnXQuarz
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update idletasks
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update idletasks
    wm geometry .t1 70x300+10+20
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {70x300+0+0}

test unixEmbed-11.1 {focus -force works for embedded toplevels} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t
    pack [frame .t.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    toplevel .embed -use [winfo id .t.f] -bg green
    update idletasks
    focus -force .t
    focus -force .embed
    focus
} -cleanup {
    deleteWindows
} -result .embed
test unixEmbed-11.2 {mouse coordinates in embedded toplevels} -constraints {
    unix pressbutton
} -setup {
    deleteWindows
} -body {
    toplevel .main
    set result {}
    pack [button .main.b -text "Main Button" \
	      -command {lappend result ".main.b"}] -padx 30 -pady 30
    pack [frame .main.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    toplevel .embed -use [winfo id .main.f] -bg green
    pack [button .embed.b -text "Emb Button" \
	      -command {lappend result ".embed.b"}] -padx 30 -pady 30
    wm geometry .main 200x400+100+100
    update idletasks
    focus -force .main
    set x [expr {[winfo x .main ] + [winfo x .main.b] + 40}]
    set y [expr {[winfo y .main ] + [winfo y .main.b] + 38}]
    lappend result [winfo containing $x $y]
    after 200
    pressbutton $x $y
    update
    set y [expr {$y + 80}]
    lappend result [winfo containing $x $y]
    after 200
    pressbutton $x $y
    update
    set result
} -cleanup {
    deleteWindows
} -result {.main.b .main.b .embed.b .embed.b}


# cleanup
deleteWindows
cleanupbg
cleanupTests
return







<
<
|
<
<
<
|
|
|
|
<
<
<
|
|
|
|
<
|
<
|





|
<
|
|
>
|
<
|
|
|




|
<
|
|
>

|
<
<
|
<









<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<






|
|
|
|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<






<
<
|




<
|
<
<
|
<




|
|
|




|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
<




|
|
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<






|
|
<
<
|
<
|
>

<


>

|
<
<
|

<
|
|
<
>





|
|
|


<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<





<
<
|
|
<
<
|
<




|
|
|
|



|

<
<
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
|
|
|



|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<




|
|



|



<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<




|
|
|
|



|
|
|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<






|
|



|



<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
|
<




|
|



|



|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<




|
|




<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<




|
|
|
|
|




|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>

>
>
>
|
<
|
>
>
>
>
>
|
>
>
>
>
>
>
>

|
|
|
|
|
>
>
>
>
|
|
>
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
|
|
|
|
<
<
|
|
>
|
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
|
<
<
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<





|
|




|
|
|
|
|
|

<
<
|
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<



|
<



|




|
|
|
|

<
<
|


|
<
<
|
<








|
|


<
<
|
|
<
<

<


<


|
|
|
|
|
|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<

<


<

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
|
|
<
<
<

<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<

<
<
<
<
<
|
<
<
<
|






49
50
51
52
53
54
55


56



57
58
59
60



61
62
63
64

65

66
67
68
69
70
71
72

73
74
75
76

77
78
79
80
81
82
83
84

85
86
87
88
89


90

91
92
93
94
95
96
97
98
99


100





















101


102

103
104
105
106
107
108
109
110
111
112
113


114























115


116

117
118
119
120
121
122


123
124
125
126
127

128


129

130
131
132
133
134
135
136
137
138
139
140
141
142


















143








144


145

146
147
148
149
150
151
152
153
154
155




















156




157


158

159
160
161
162
163
164
165
166


167

168
169
170

171
172
173
174
175


176
177

178
179

180
181
182
183
184
185
186
187
188
189
190


191





















192


193


194
195
196
197
198


199
200


201

202
203
204
205
206
207
208
209
210
211
212
213
214


215
216


217
























218
219
220
221
222
223
224
225
226
227
228
229
230


231























232


233

234
235
236
237
238
239
240
241
242
243
244
245
246


247






















248


249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264


265

























266


267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282


283


















284







285


286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301


302























303


304

305
306
307
308
309
310
311
312
313
314

315


316















317









318


319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431


432
433
434
435

436
437
438
439
440
441
442
443















































































444
445





446
447








448


449
450
451

452





















453



454















455

456


457






458


















459








































































































































460


461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479


480
481

482























483






484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500


501
502
503
504


505

506
507
508
509
510
511
512
513
514
515
516
517


518
519


520

521
522

523
524
525
526
527
528
529
530
531


532


















533






534


535

536
537

538
539
540
















541
542


543
544



545


546



547










548




549



550







551





552



553
554
555
556
557
558
559

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \
	    && ([lindex $vals 2]/256 == $blue)
}



test unixEmbed-1.1 {TkpUseWindow procedure, bad window identifier} unix {



    catch {destroy .t}
    list [catch {toplevel .t -use xyz} msg] $msg
} {1 {expected integer but got "xyz"}}
test unixEmbed-1.2 {TkpUseWindow procedure, bad window identifier} unix {



    catch {destroy .t}
    list [catch {toplevel .t -use 47} msg] $msg
} {1 {couldn't create child of window "47"}}
test unixEmbed-1.3 {TkpUseWindow procedure, inheriting colormap} {unix nonPortable} {

    catch {destroy .t}

    catch {destroy .x}
    toplevel .t -colormap new
    wm geometry .t +0+0
    eatColors .t.t
    frame .t.f -container 1
    toplevel .x -use [winfo id .t.f]
    set result [colorsFree .x]

    destroy .t
    set result
} {0}
test unixEmbed-1.4 {TkpUseWindow procedure, inheriting colormap} {unix nonPortable} {

    catch {destroy .t}
    catch {destroy .t2}
    catch {destroy .x}
    toplevel .t -container 1 -colormap new
    wm geometry .t +0+0
    eatColors .t2
    toplevel .x -use [winfo id .t]
    set result [colorsFree .x]

    destroy .t
    set result
} {1}

test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t -use $w
	list [testembed] [expr [lindex [lindex [testembed all] 0] 0] - $w]
    }


} {{{XXX {} {} .t}} 0}





















test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg "set w2 [winfo id .f2]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	toplevel .t2 -use $w2
	testembed
    }


} {{XXX {} {} .t2} {XXX {} {} .t1}}























test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    toplevel .t1 -use [winfo id .f1]
    toplevel .t2 -use [winfo id .f2]
    testembed


} {{XXX .f2 {} .t2} {XXX .f1 {} .t1}}

# Can't think of any way to test the procedures TkpMakeWindow,
# TkpMakeContainer, or EmbedErrorProc.


test unixEmbed-2.1 {EmbeddedEventProc procedure} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	testembed
    }
    destroy .f1
    update
    dobg {
	testembed
    }


















} {}








test unixEmbed-2.2 {EmbeddedEventProc procedure} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	testembed
	destroy .t1
	testembed
    }




















} {}




test unixEmbed-2.3 {EmbeddedEventProc procedure} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    toplevel .t1 -use [winfo id .f1]
    update
    destroy .f1
    testembed
} {}
test unixEmbed-2.4 {EmbeddedEventProc procedure} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    toplevel .t1 -use [winfo id .f1]

    update
    destroy .t1
    set x [testembed]
    update
    list $x [testembed]


} {{{XXX .f1 {} {}}} {}}


test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} \
	{unix testembed nonPortable} {

    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    set x [testembed]
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	wm withdraw .t1
    }
    list $x [testembed]


} {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}





















test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} unix {


    deleteWindows


    toplevel .t1 -container 1
    wm geometry .t1 +0+0
    toplevel .t2 -use [winfo id .t1] -bg red
    update
    wm geometry .t2


} {200x200+0+0}
test unixEmbed-3.2a {ContainerEventProc procedure, disallow position changes} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1 -bd 2 -relief raised
	update
	wm geometry .t1 +30+40
    }
    update
    dobg {
	wm geometry .t1
    }


} {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} unix {


    deleteWindows
























    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	update
	wm geometry .t1 300x100+30+40
    }
    update
    dobg {
	wm geometry .t1
    }


} {300x100+0+0}























test unixEmbed-3.4 {ContainerEventProc procedure, geometry requests} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	.t1 configure -width 300 -height 80
    }
    update
    list [winfo width .f1] [winfo height .f1] [dobg {wm geometry .t1}]


} {300 80 300x80+0+0}






















test unixEmbed-3.5 {ContainerEventProc procedure, map requests} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	set x unmapped
	bind .t1 <Map> {set x mapped}
    }
    update
    dobg {
	after 100
	update
	set x
    }


} {mapped}

























test unixEmbed-3.6 {ContainerEventProc procedure, destroy events} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    bind .f1 <Destroy> {set x dead}
    set x alive
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	destroy .t1
    }
    update
    list $x [winfo exists .f1]


} {dead 0}


























test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	.t1 configure -width 180 -height 100
    }
    update
    dobg {
	winfo geometry .t1
    }


} {180x100+0+0}























test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    set x [testembed]
    destroy .f1

    list $x [testembed]


} {{{XXX .f1 XXX {}}} {}}

























test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	bind .t1 <FocusIn> {lappend x "focus in %W"}
	bind .t1 <FocusOut> {lappend x "focus out %W"}
	set x {}
    }
    focus -force .f1
    update
    dobg {set x}
} {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} unix {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} unix {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
	bind .t1 <FocusIn> {lappend x "focus in %W"}
	bind .t1 <FocusOut> {lappend x "focus out %W"}
	set x {}
    }
    focus -force .f1
    update
    set x [dobg {update; set x}]
    focus .
    update
    list $x [dobg {update; set x}]
} {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}

test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} unix {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {

	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	set x {}
	.t1 configure -width 300 -height 120
	update
	list $x [winfo geom .t1]
    }
} {{{configure .t1 300 120}} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} unix {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    after 300 {set x done}
    vwait x
    dobg {
	bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	set x {}
	.t1 configure -width 300 -height 120
	update
	list $x [winfo geom .t1]
    }
} {{{configure .t1 200 200}} 200x200+0+0}

# Can't think up any tests for TkpGetOtherWindow procedure.

test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} unix {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    focus -force .
    bind . <KeyPress> {lappend x {key %A %E}}
    set x {}
    set y [dobg {
	update
	bind .t1 <KeyPress> {lappend y {key %A}}
	set y {}
	event generate .t1 <KeyPress> -keysym a
	set y
    }]
    update
    bind . <KeyPress> {}


    list $x $y
} {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} unix {
    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update















































































    focus -force .f1
    update





    bind . <KeyPress> {lappend x {key %A}}
    set x {}








    set y [dobg {


	update
	bind .t1 <KeyPress> {lappend y {key %A}}
	set y {}

	event generate .t1 <KeyPress> -keysym b





















	set y



    }]















    update

    bind . <KeyPress> {}


    list $x $y






} {{} {{key b}}}



























































































































































test unixEmbed-8.1 {TkpClaimFocus procedure} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
    }
    focus -force .f2
    update
    list [dobg {
	focus .t1
	set x [list [focus]]
	update
	after 500
	update
	lappend x [focus]
    }] [focus]


} {{{} .t1} .f1}
test unixEmbed-8.2 {TkpClaimFocus procedure} unix {

    catch {interp delete child}























    deleteWindows






    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    interp create child

    child eval "set argv {-use [winfo id .f1]}"
    load {} Tk child
    child eval {
	. configure -bd 2 -highlightthickness 2 -relief sunken
    }
    focus -force .f2
    update
    list [child eval {
	focus .
	set x [list [focus]]
	update
	lappend x [focus]
    }] [focus]


} {{{} .} .f1}
catch {interp delete child}

test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    frame .f3 -container 1 -width 200 -height 50
    frame .f4 -container 1 -width 200 -height 50
    pack .f1 .f2 .f3 .f4
    set x {}
    lappend x [testembed]
    foreach w {.f3 .f4 .f1 .f2} {
	destroy $w
	lappend x [testembed]
    }
    set x


} {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} {unix testembed} {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
	set x {}
	lappend x [testembed]
	destroy .t1
	lappend x [testembed]
    }


} {{{XXX {} {} .t1}} {}}

























test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} unix {


    deleteWindows

    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update
    wm geometry .t1 +40+50
















    update
    wm geometry .t1


} {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} unix {



    deleteWindows


    frame .f1 -container 1 -width 200 -height 50



    pack .f1










    toplevel .t1 -use [winfo id .f1] -width 150 -height 80




    update



    wm geometry .t1 70x300+10+20







    update





    wm geometry .t1



} {70x300+0+0}

# cleanup
deleteWindows
cleanupbg
cleanupTests
return

Changes to tests/unixFont.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# This file is a Tcl script to test out the procedures in tkUnixFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.  Some tests depend on the
# fonts having or not having certain properties, which may not be valid
# at all sites.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

if {[tk windowingsystem] eq "x11"} {
    set xlsf [auto_execok xlsfonts]
}
foreach {constraint font} {
    hasArial	arial
    hasCourierNew	"courier new"










|
|






|
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
# This file is a Tcl script to test out the procedures in tkUnixFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.  Some tests depend on the
# fonts having or not having certain properties, which may not be valid
# at all sites.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]



if {[tk windowingsystem] eq "x11"} {
    set xlsf [auto_execok xlsfonts]
}
foreach {constraint font} {
    hasArial	arial
    hasCourierNew	"courier new"
45
46
47
48
49
50
51


52
53
54
55
56
57
58
}

catch {destroy .b}
toplevel .b
wm geom .b +0+0
update idletasks



# Font should be fixed width and have chars missing below char 32, so can
# test control char expansion and missing character code.

set courier {Courier -10}
set cx [font measure $courier 0]

label .b.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left -text "0" -font fixed







>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
}

catch {destroy .b}
toplevel .b
wm geom .b +0+0
update idletasks

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

# Font should be fixed width and have chars missing below char 32, so can
# test control char expansion and missing character code.

set courier {Courier -10}
set cx [font measure $courier 0]

label .b.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left -text "0" -font fixed
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
set ax [winfo reqwidth .b.l]
set ay [winfo reqheight .b.l]
proc getsize {} {
    update
    return "[winfo reqwidth .b.l] [winfo reqheight .b.l]"
}

test unixfont-1.1 {TkpGetNativeFont procedure: not native} {x11 noExceed} {
    list [catch {font measure {} xyz} msg] $msg
} {1 {font "" doesn't exist}}
test unixfont-1.2 {TkpGetNativeFont procedure: native} {x11 failsOnUbuntu} {
    font measure fixed 0
} 6

test unixfont-2.1 {TkpGetFontFromAttributes procedure: no family} x11 {
    font actual {-size 10}
    set x {}
} {}
test unixfont-2.2 {TkpGetFontFromAttributes procedure: Times relatives} \
	{x11 noExceed hasTimesNew failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Times New Roman"}] 1]
    lappend x [lindex [font actual {-family "New York"}] 1]
    lappend x [lindex [font actual {-family "Times"}] 1]
} {times times times}
test unixfont-2.3 {TkpGetFontFromAttributes procedure: Courier relatives} \
	{x11 noExceed hasCourierNew failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Courier New"}] 1]
    lappend x [lindex [font actual {-family "Monaco"}] 1]
    lappend x [lindex [font actual {-family "Courier"}] 1]
} {courier courier courier}
test unixfont-2.4 {TkpGetFontFromAttributes procedure: Helvetica relatives} \
	{x11 noExceed hasArial failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Arial"}] 1]
    lappend x [lindex [font actual {-family "Geneva"}] 1]
    lappend x [lindex [font actual {-family "Helvetica"}] 1]
} {helvetica helvetica helvetica}
test unixfont-2.5 {TkpGetFontFromAttributes procedure: fallback} x11 {
    font actual {-xyz-xyz-*-*-*-*-*-*-*-*-*-*-*-*}
    set x {}
} {}
test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} {x11 failsOnUbuntu} {
    lindex [font actual {-family fixed -size 10}] 1
} {fixed}
test unixfont-2.7 {TkpGetFontFromAttributes: fixed family not available!} x11 {
    # no test available
} {}
test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} {x11 failsOnUbuntu} {
    lindex [font actual {-family fixed -size 31}] 1
} {fixed}
test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} {x11 noExceed failsOnUbuntu} {
    lindex [font actual {-family courier}] 1
} {courier}
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {x11 failsOnUbuntuNoXft} {
    lindex [font actual {-family courier -size 37}] 3
} 37
test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} x11 {
    # On Linux, XListFonts() was returning names for fonts that do not
    # actually exist, causing the subsequent XLoadQueryFont() to fail
    # unexpectedly.  Now falls back to another font if that happens.

    font actual {-size 14}
    set x {}
} {}

test unixfont-3.1 {TkpDeleteFont procedure} x11 {
    font actual {-family xyz}
    set x {}
} {}

test unixfont-4.1 {TkpGetFontFamilies procedure} x11 {
    font families
    set x {}
} {}

test unixfont-5.1 {Tk_MeasureChars procedure: no chars to be measured} x11 {
    .b.l config -text "000000" -wrap [expr $ax*3]
    .b.l config -wrap 0
} {}
test unixfont-5.2 {Tk_MeasureChars procedure: no right margin} x11 {
    .b.l config -text "000000"
} {}
test unixfont-5.3 {Tk_MeasureChars procedure: loop over chars} x11 {
    .b.l config -text "0"
    .b.l config -text "\377"
    .b.l config -text "0\3770\377"
    .b.l config -text "000000000000000"
} {}
.b.l config -wrap [expr $ax*10]
test unixfont-5.4 {Tk_MeasureChars procedure: reached right edge} x11 {
    .b.l config -text "0000000000000"
    getsize
} "[expr $ax*10] [expr $ay*2]"
test unixfont-5.5 {Tk_MeasureChars procedure: ran out of chars} x11 {
    .b.l config -text "000000"
    getsize
} "[expr $ax*6] $ay"
test unixfont-5.6 {Tk_MeasureChars procedure: find last word} x11 {
    .b.l config -text "000000 00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.7 {Tk_MeasureChars procedure: already saw space in line} x11 {
    .b.l config -text "000000     00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.8 {Tk_MeasureChars procedure: internal spaces significant} {x11 failsOnUbuntu} {
    .b.l config -text "00  000     00000"
    getsize
} "[expr $ax*7] [expr $ay*2]"
test unixfont-5.9 {Tk_MeasureChars procedure: TK_PARTIAL_OK} {x11 failsOnUbuntu} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0000"
    .b.c index $t @[expr int($ax*2.5)],1
} 2
test unixfont-5.10 {Tk_MeasureChars procedure: TK_AT_LEAST_ONE} x11 {
    .b.l config -text "000000000000"
    getsize
} "[expr $ax*10] [expr $ay*2]"
test unixfont-5.11 {Tk_MeasureChars: TK_AT_LEAST_ONE + not even one char fit!} x11 {
    set a [.b.l cget -wrap]
    .b.l config -text "000000" -wrap 1
    set x [getsize]
    .b.l config -wrap $a
    set x
} "$ax [expr $ay*6]"
test unixfont-5.12 {Tk_MeasureChars procedure: include eol spaces} {x11 failsOnUbuntu} {
    .b.l config -text "000   \n000"
    getsize
} "[expr $ax*6] [expr $ay*2]"

test unixfont-6.1 {Tk_DrawChars procedure: loop test} x11 {
    .b.l config -text "a"
    update
} {}
test unixfont-6.2 {Tk_DrawChars procedure: loop test} x11 {
    .b.l config -text "abcd"
    update
} {}
test unixfont-6.3 {Tk_DrawChars procedure: special char} x11 {
    .b.l config -text "\001"
    update
} {}
test unixfont-6.4 {Tk_DrawChars procedure: normal then special} x11 {
    .b.l config -text "ab\001"
    update
} {}
test unixfont-6.5 {Tk_DrawChars procedure: ends with special} x11 {
    .b.l config -text "ab\001"
    update
} {}
test unixfont-6.6 {Tk_DrawChars procedure: more normal chars at end} x11 {
    .b.l config -text "ab\001def"
    update
} {}

test unixfont-7.1 {DrawChars procedure: no effects} x11 {
    .b.l config -text "abc"
    update
} {}
test unixfont-7.2 {DrawChars procedure: underlining} x11 {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 underline"
    update
    .b.l config -font $f
} {}
test unixfont-7.3 {DrawChars procedure: overstrike} x11 {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 overstrike"
    update
    .b.l config -font $f
} {}

test unixfont-8.1 {AllocFont procedure: use old font} x11 {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test unixfont-8.2 {AllocFont procedure: parse information from XLFD} x11 {
    expr {[lindex [font actual {-family times -size 0}] 3] == 0}
} 0
test unixfont-8.3 {AllocFont procedure: can't parse info from name} x11 {
    catch {unset fontArray}
    # check that font actual returns the correct attributes.
    # the values of those attributes are system dependent.
    array set fontArray [font actual a12biluc]
    set result [lsort [array names fontArray]]
    catch {unset fontArray}
    set result
} {-family -overstrike -size -slant -underline -weight}
test unixfont-8.4 {AllocFont procedure: classify characters} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "䀀"]   ;# 6
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    incr x [font measure $courier "\101"]   ;# 1
    set x
} [expr $cx*13]
test unixfont-8.5 {AllocFont procedure: setup widths of normal chars} x11 {
    font metrics $courier -fixed
} 1
test unixfont-8.6 {AllocFont procedure: setup widths of special chars} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "\001"]   ;# 4
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    set x
} [expr $cx*10]
test unixfont-8.7 {AllocFont procedure: XA_UNDERLINE_POSITION} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.8 {AllocFont procedure: no XA_UNDERLINE_POSITION} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.9 {AllocFont procedure: XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.10 {AllocFont procedure: no XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.11 {AllocFont procedure: XA_UNDERLINE_POSITION was 0} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}

test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\a0"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]
} {0 1 1 2}
test unixfont-9.2 {GetControlCharSubst procedure: 4 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\0010"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]







|


|

|

|




|






|






|





|



|


|


|


|


|

|
|








|




|




|



|


|






|



|



|



|



|



|



|
|



|






|




|



|



|



|



|



|




|



|





|






|







|

|
|








|

|





|

|
|






|



|



|



|



|




|








|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
set ax [winfo reqwidth .b.l]
set ay [winfo reqheight .b.l]
proc getsize {} {
    update
    return "[winfo reqwidth .b.l] [winfo reqheight .b.l]"
}

test unixfont-1.1 {TkpGetNativeFont procedure: not native} {unix noExceed} {
    list [catch {font measure {} xyz} msg] $msg
} {1 {font "" doesn't exist}}
test unixfont-1.2 {TkpGetNativeFont procedure: native} {unix failsOnUbuntu} {
    font measure fixed 0
} {6}

test unixfont-2.1 {TkpGetFontFromAttributes procedure: no family} unix {
    font actual {-size 10}
    set x {}
} {}
test unixfont-2.2 {TkpGetFontFromAttributes procedure: Times relatives} \
	{unix noExceed hasTimesNew failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Times New Roman"}] 1]
    lappend x [lindex [font actual {-family "New York"}] 1]
    lappend x [lindex [font actual {-family "Times"}] 1]
} {times times times}
test unixfont-2.3 {TkpGetFontFromAttributes procedure: Courier relatives} \
	{unix noExceed hasCourierNew failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Courier New"}] 1]
    lappend x [lindex [font actual {-family "Monaco"}] 1]
    lappend x [lindex [font actual {-family "Courier"}] 1]
} {courier courier courier}
test unixfont-2.4 {TkpGetFontFromAttributes procedure: Helvetica relatives} \
	{unix noExceed hasArial failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Arial"}] 1]
    lappend x [lindex [font actual {-family "Geneva"}] 1]
    lappend x [lindex [font actual {-family "Helvetica"}] 1]
} {helvetica helvetica helvetica}
test unixfont-2.5 {TkpGetFontFromAttributes procedure: fallback} unix {
    font actual {-xyz-xyz-*-*-*-*-*-*-*-*-*-*-*-*}
    set x {}
} {}
test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} {unix failsOnUbuntu} {
    lindex [font actual {-family fixed -size 10}] 1
} {fixed}
test unixfont-2.7 {TkpGetFontFromAttributes: fixed family not available!} unix {
    # no test available
} {}
test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} {unix failsOnUbuntu} {
    lindex [font actual {-family fixed -size 31}] 1
} {fixed}
test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} {unix noExceed failsOnUbuntu} {
    lindex [font actual {-family courier}] 1
} {courier}
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {unix failsOnUbuntu} {
    lindex [font actual {-family courier -size 37}] 3
} {37}
test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} unix {
    # On Linux, XListFonts() was returning names for fonts that do not
    # actually exist, causing the subsequent XLoadQueryFont() to fail
    # unexpectedly.  Now falls back to another font if that happens.

    font actual {-size 14}
    set x {}
} {}

test unixfont-3.1 {TkpDeleteFont procedure} unix {
    font actual {-family xyz}
    set x {}
} {}

test unixfont-4.1 {TkpGetFontFamilies procedure} unix {
    font families
    set x {}
} {}

test unixfont-5.1 {Tk_MeasureChars procedure: no chars to be measured} unix {
    .b.l config -text "000000" -wrap [expr $ax*3]
    .b.l config -wrap 0
} {}
test unixfont-5.2 {Tk_MeasureChars procedure: no right margin} unix {
    .b.l config -text "000000"
} {}
test unixfont-5.3 {Tk_MeasureChars procedure: loop over chars} unix {
    .b.l config -text "0"
    .b.l config -text "\377"
    .b.l config -text "0\3770\377"
    .b.l config -text "000000000000000"
} {}
.b.l config -wrap [expr $ax*10]
test unixfont-5.4 {Tk_MeasureChars procedure: reached right edge} unix {
    .b.l config -text "0000000000000"
    getsize
} "[expr $ax*10] [expr $ay*2]"
test unixfont-5.5 {Tk_MeasureChars procedure: ran out of chars} unix {
    .b.l config -text "000000"
    getsize
} "[expr $ax*6] $ay"
test unixfont-5.6 {Tk_MeasureChars procedure: find last word} unix {
    .b.l config -text "000000 00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.7 {Tk_MeasureChars procedure: already saw space in line} unix {
    .b.l config -text "000000     00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.8 {Tk_MeasureChars procedure: internal spaces significant} {unix failsOnUbuntu} {
    .b.l config -text "00  000     00000"
    getsize
} "[expr $ax*7] [expr $ay*2]"
test unixfont-5.9 {Tk_MeasureChars procedure: TK_PARTIAL_OK} {unix failsOnUbuntu} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0000"
    .b.c index $t @[expr int($ax*2.5)],1
} {2}
test unixfont-5.10 {Tk_MeasureChars procedure: TK_AT_LEAST_ONE} unix {
    .b.l config -text "000000000000"
    getsize
} "[expr $ax*10] [expr $ay*2]"
test unixfont-5.11 {Tk_MeasureChars: TK_AT_LEAST_ONE + not even one char fit!} unix {
    set a [.b.l cget -wrap]
    .b.l config -text "000000" -wrap 1
    set x [getsize]
    .b.l config -wrap $a
    set x
} "$ax [expr $ay*6]"
test unixfont-5.12 {Tk_MeasureChars procedure: include eol spaces} {unix failsOnUbuntu} {
    .b.l config -text "000   \n000"
    getsize
} "[expr $ax*6] [expr $ay*2]"

test unixfont-6.1 {Tk_DrawChars procedure: loop test} unix {
    .b.l config -text "a"
    update
} {}
test unixfont-6.2 {Tk_DrawChars procedure: loop test} unix {
    .b.l config -text "abcd"
    update
} {}
test unixfont-6.3 {Tk_DrawChars procedure: special char} unix {
    .b.l config -text "\001"
    update
} {}
test unixfont-6.4 {Tk_DrawChars procedure: normal then special} unix {
    .b.l config -text "ab\001"
    update
} {}
test unixfont-6.5 {Tk_DrawChars procedure: ends with special} unix {
    .b.l config -text "ab\001"
    update
} {}
test unixfont-6.6 {Tk_DrawChars procedure: more normal chars at end} unix {
    .b.l config -text "ab\001def"
    update
} {}

test unixfont-7.1 {DrawChars procedure: no effects} unix {
    .b.l config -text "abc"
    update
} {}
test unixfont-7.2 {DrawChars procedure: underlining} unix {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 underline"
    update
    .b.l config -font $f
} {}
test unixfont-7.3 {DrawChars procedure: overstrike} unix {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 overstrike"
    update
    .b.l config -font $f
} {}

test unixfont-8.1 {AllocFont procedure: use old font} unix {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test unixfont-8.2 {AllocFont procedure: parse information from XLFD} unix {
    expr {[lindex [font actual {-family times -size 0}] 3] == 0}
} {0}
test unixfont-8.3 {AllocFont procedure: can't parse info from name} unix {
    catch {unset fontArray}
    # check that font actual returns the correct attributes.
    # the values of those attributes are system dependent.
    array set fontArray [font actual a12biluc]
    set result [lsort [array names fontArray]]
    catch {unset fontArray}
    set result
} {-family -overstrike -size -slant -underline -weight}
test unixfont-8.4 {AllocFont procedure: classify characters} {unix failsOnUbuntu failsOnQuarz} {
    set x 0
    incr x [font measure $courier "\u4000"]   ;# 6
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    incr x [font measure $courier "\101"]   ;# 1
    set x
} [expr $cx*13]
test unixfont-8.5 {AllocFont procedure: setup widths of normal chars} unix {
    font metrics $courier -fixed
} {1}
test unixfont-8.6 {AllocFont procedure: setup widths of special chars} {unix failsOnUbuntu failsOnQuarz} {
    set x 0
    incr x [font measure $courier "\001"]   ;# 4
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    set x
} [expr $cx*10]
test unixfont-8.7 {AllocFont procedure: XA_UNDERLINE_POSITION} unix {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.8 {AllocFont procedure: no XA_UNDERLINE_POSITION} unix {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.9 {AllocFont procedure: XA_UNDERLINE_THICKNESS} unix {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.10 {AllocFont procedure: no XA_UNDERLINE_THICKNESS} unix {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.11 {AllocFont procedure: XA_UNDERLINE_POSITION was 0} unix {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}

test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} {unix failsOnUbuntu failsOnQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\a0"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]
} {0 1 1 2}
test unixfont-9.2 {GetControlCharSubst procedure: 4 chars subst} {unix failsOnUbuntu failsOnQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\0010"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]

Changes to tests/unixMenu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

303



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356






357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126

1127



1128

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179

1180
1181
1182


1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands


test unixMenu-1.1 {TkpNewMenu - normal menu} -constraints unix -setup {
    destroy .m1
} -body {
    list [menu .m1] [destroy .m1]
} -returnCodes ok -result {.m1 {}}
test unixMenu-1.2 {TkpNewMenu - help menu} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label Help -menu .m1.help
    list [menu .m1.help] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {.m1.help {} {}}


test unixMenu-2.1 {TkpDestroyMenu - nothing to do} -constraints unix -body {}


test unixMenu-3.1 {TkpDestroymenuEntry - nothing to do} -constraints unix -body {}


test unixMenu-4.1 {TkpConfigureMenuEntry - non-cascade entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label test
    list [.m1 entryconfigure test -label foo] [destroy .m1]
} -returnCodes ok -result {{} {}}
test unixMenu-4.2 {TkpConfigureMenuEntry - cascade entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -menu .m2 -label test
    menu .m1.foo -tearoff 0
    list [.m1 entryconfigure test -menu .m1.foo] [destroy .m1]
} -returnCodes ok -result {{} {}}


test unixMenu-5.1 {TkpMenuNewEntry - nothing to do} -constraints unix -body {}


test unixMenu-6.1 {TkpSetWindowMenuBar - null menu} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1
    list [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} {}}
test unixMenu-6.2 {TkpSetWindowMenuBar - menu} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} {} {}}


test unixMenu-7.1 {TkpSetMainMenubar - nothing to do} -constraints unix -body {}




test unixMenu-8.1 {GetMenuIndicatorGeometry - indicator off} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.2 {GetMenuIndicatorGeometry - not checkbutton or radio} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.3 {GetMenuIndicatorGeometry - checkbutton image} -constraints {
    unix testImageType
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    menu .m1
    image create test image1
    .m1 add checkbutton -image image1 -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -cleanup {
    image delete image1
} -returnCodes ok
test unixMenu-8.4 {GetMenuIndicatorGeometry - checkbutton bitmap} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -bitmap questhead -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.5 {GetMenuIndicatorGeometry - checkbutton} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.6 {GetMenuIndicatorGeometry - radiobutton image} -constraints {
    unix testImageType
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    menu .m1
    image create test image1
    .m1 add radiobutton -image image1 -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
    image delete image1
} -returnCodes ok
test unixMenu-8.7 {GetMenuIndicatorGeometry - radiobutton bitmap} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -bitmap questhead -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.8 {GetMenuIndicatorGeometry - radiobutton} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-8.9 {GetMenuIndicatorGeometry - hideMargin} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label foo -hidemargin 1
    .m1 invoke foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


test unixMenu-9.1 {GetMenuAccelGeometry - cascade entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-9.2 {GetMenuAccelGeometry - non-null label} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -accel "Ctrl+S"
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test unixMenu-9.3 {GetMenuAccelGeometry - null label} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


test unixMenu-10.1 {DrawMenuEntryBackground - active menubar} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1
    .m1 activate 1
    list [update] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} {} {}}
test unixMenu-10.2 {DrawMenuEntryBackground - active} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff activate 0
    list [update] [destroy .m1]
} -returnCodes ok -result {{} {}}
test unixMenu-10.3 {DrawMenuEntryBackground - non-active} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -returnCodes ok -result {{} {}}


test unixMenu-11.1 {DrawMenuEntryAccelerator - menubar} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
# drawArrow parameter is never false under Unix
test unixMenu-11.2 {DrawMenuEntryAccelerator - cascade entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
}  -result {{} {}}
test unixMenu-11.3 {DrawMenuEntryAccelerator - normal entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    set tearoff [tk::TearOffMenu .m1 40 40]



    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-11.4 {DrawMenuEntryAccelerator - null entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-12.1 {DrawMenuEntryIndicator - non-check or radio} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.2 {DrawMenuEntryIndicator - checkbutton - indicator off} -constraints {

    unix



} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.3 {DrawMenuEntryIndicator - checkbutton - not selected} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.4 {DrawMenuEntryIndicator - checkbutton - selected} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]



    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.5 {DrawMenuEntryIndicator - radiobutton - indicator off} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label foo -indicatoron 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.6 {DrawMenuEntryIndicator - radiobutton - not selected} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-12.7 {DrawMenuEntryIndicator - radiobutton - selected} -constraints {
    unix
} -setup {
    destroy .m1






} -body {
    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-13.1 {DrawMenuSeparator - menubar case} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-13.2 {DrawMenuSepartor - normal menu} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-14.1 {DrawMenuEntryLabel} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-15.1 {DrawMenuUnderline - menubar} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -underline 0
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-15.2 {DrawMenuUnderline - no menubar} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -underline 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-16.1 {TkpPostMenu} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


test unixMenu-17.1 {GetMenuSeparatorGeometry} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


test unixMenu-18.1 {GetTearoffEntryGeometry} -constraints {
    unix nonUnixUserInteraction
} -setup {
    destroy .mb
} -body {
    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    raise .
    list [tk::MbPost .mb] [tk::MenuUnpost .mb.m] [destroy .mb]
} -result {{} {} {}}


# Don't know how to reproduce the case where the tkwin has been deleted.

test unixMenu-19.1 {TkpComputeMenubarGeometry - zero entries} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
# Don't know how to generate one width windows
test unixMenu-19.2 {TkpComputeMenubarGeometry - one entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label File
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.3 {TkpComputeMenubarGeometry - entry with different font} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -font "Courier 24"
    .m1 add cascade -label File -font "Helvetica 18"
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.4 {TkpComputeMenubarGeometry - separator} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.5 {TkpComputeMenubarGeometry - First entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.6 {TkpComputeMenubarGeometry - First entry too wide} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File -font "Times 72"
    . configure -menu .m1
    wm geometry . 10x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.7 {TkpComputeMenubarGeometry - two entries fit} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 200x200
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.8 {TkpComputeMenubarGeometry - two entries; 2nd don't fit} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File
    .m1 add cascade -label Edit -font "Times 72"
    . configure -menu .m1
    wm geometry . 100x100
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.9 {TkpComputeMenubarGeometry - two entries; 1st dont fit} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File -font "Times 72"
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 100x100
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.10 {TkpComputeMenubarGeometry - two entries; neither fit} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0 -font "Times 72"
    .m1 add cascade -label File
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 10x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
# ABC notation; capital A means first window fits, small a means it
# does not. capital B menu means second window fist, etc.
test unixMenu-19.11 {TkpComputeMenubarGeometry - abc} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0 -font "Times 72"
    .m1 add cascade -label "aaaaa"
    .m1 add cascade -label "bbbbb"
    .m1 add cascade -label "ccccc"
    . configure -menu .m1
    wm geometry . 10x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.12 {TkpComputeMenubarGeometry - abC} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 10x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.13 {TkpComputeMenubarGeometry - aBc} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "B"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 10x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.14 {TkpComputeMenubarGeometry - aBC} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "B"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 60x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.15 {TkpComputeMenubarGeometry - Abc} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 60x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.16 {TkpComputeMenubarGeometry - AbC} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 60x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.17 {TkpComputeMenubarGeometry - ABc} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "B"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 60x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.18 {TkpComputeMenubarGeometry - ABC} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "B"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.19 {TkpComputeMenubarGeometry - help menu in first position} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.20 {TkpComputeMenubarGeometry - help menu in middle} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.21 {TkpComputeMenubarGeometry - help menu in first position} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.22 {TkpComputeMenubarGeometry - help item fits} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.23 {TkpComputeMenubarGeometry - help item does not fit} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Help -menu .m1.help -font "Helvetica 72"
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-19.24 {TkpComputeMenubarGeometry - help item only one} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}


test unixMenu-20.1 {DrawTearoffEntry - menubar} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label File
    . configure -menu .m1
    list [update] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}
test unixMenu-20.2 {DrawTearoffEntry - non-menubar} -constraints {
    unix nonUnixUserInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    .m1 post 40 40
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-21.1 {TkpInitializeMenuBindings - nothing to do} -constraints unix -body {}


test unixMenu-22.1 {SetHelpMenu - no menubars} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label test -menu .m1.test
    list [menu .m1.test] [destroy .m1]
} -result {.m1.test {}}
# Don't know how to automate missing tkwins
test unixMenu-22.2 {SetHelpMenu - menubar but no help menu} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label .m1.file
    list [menu .m1.file] [. configure -menu ""] [destroy .m1]
} -result {.m1.file {} {}}
test unixMenu-22.3 {SetHelpMenu - menubar with help menu} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label .m1.help
    list [menu .m1.help] [. configure -menu ""] [destroy .m1]
} -result {.m1.help {} {}}
test unixMenu-22.4 {SetHelpMenu - multiple menubars with same help menu} -constraints {
    unix
} -setup {
    destroy .m1 .t2
} -body {
    toplevel .t2
    wm geometry .t2 +40+40
    menu .m1 -tearoff 0
    . configure -menu .m1
    .t2 configure -menu .m1
    .m1 add cascade -label .m1.help
    list [menu .m1.help] [. configure -menu ""] [destroy .m1] [destroy .t2]
} -result {.m1.help {} {} {}}


test unixMenu-23.1 {TkpDrawMenuEntry - gc for active and not strict motif} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.2 {TkpDrawMenuEntry - gc for active menu item with its own gc} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activeforeground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.3 {TkpDrawMenuEntry - gc for active and strict motif} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    set tk_strictMotif 1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} -result {{} {} 0}
test unixMenu-23.4 {TkpDrawMenuEntry - gc for disabled with disabledfg and custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled -background red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.5 {TkpDrawMenuEntry - gc for disabled with disabledFg} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.6 {TkpDrawMenuEntry - gc for disabled - no disabledFg} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.7 {TkpDrawMenuEntry - gc for normal - custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -foreground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.8 {TkpDrawMenuEntry - gc for normal} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.9 {TkpDrawMenuEntry - gc for indicator - custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -selectcolor orange
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.10 {TkpDrawMenuEntry - gc for indicator} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.11 {TkpDrawMenuEntry - border - custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activebackground green
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.12 {TkpDrawMenuEntry - border} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.13 {TkpDrawMenuEntry - active border - strict motif} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    set tk_strictMotif 1
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} -result {{} {} 0}
test unixMenu-23.14 {TkpDrawMenuEntry - active border - custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activeforeground yellow
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.15 {TkpDrawMenuEntry - active border} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.16 {TkpDrawMenuEntry - font - custom entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -font "Helvectica 72"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.17 {TkpDrawMenuEntry - font} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1 -font "Courier 72"
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.18 {TkpDrawMenuEntry - separator} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.19 {TkpDrawMenuEntry - standard} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.20 {TkpDrawMenuEntry - disabled cascade item} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file
    .m1.file add command -label foo
    .m1 entryconfigure File -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.21 {TkpDrawMenuEntry - indicator} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label Foo
    .m1 invoke Foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test unixMenu-23.22 {TkpDrawMenuEntry - hide margin} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label Foo -hidemargin 1
    .m1 invoke Foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test unixMenu-24.1 {GetMenuLabelGeometry - image} -constraints {
    testImageType unix
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    menu .m1
    image create test image1
    .m1 add command -image image1
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test unixMenu-24.2 {GetMenuLabelGeometry - bitmap} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -bitmap questhead
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-24.3 {GetMenuLabelGeometry - no text} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-24.4 {GetMenuLabelGeometry - text} -constraints unix -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "This is a test."
    list [update idletasks] [destroy .m1]
} -result {{} {}}


test unixMenu-25.1 {TkpComputeStandardMenuGeometry - no entries} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.2 {TkpComputeStandardMenuGeometry - one entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "one"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.3 {TkpComputeStandardMenuGeometry - more than one entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.4 {TkpComputeStandardMenuGeometry - separator} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.5 {TkpComputeStandardMenuGeometry - tearoff entry} -constraints {
    unix nonUnixUserInteraction
} -setup {
    destroy .mb
} -body {
    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    catch {tk::MbPost .mb}
    list [update] [tk::MenuUnpost .mb.m] [destroy .mb]
} -result {{} {} {}}
test unixMenu-25.6 {TkpComputeStandardMenuGeometry - standard label geometry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.7 {TkpComputeStandardMenuGeometry - different font for entry} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -font "Helvetica 12"
    .m1 add command -label "test" -font "Courier 12"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.8 {TkpComputeStandardMenuGeometry - second entry larger} -constraints {

    unix



} -setup {

    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.9 {TkpComputeStandardMenuGeometry - first entry larger} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test test"
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.10 {TkpComputeStandardMenuGeometry - accelerator} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "Ctrl+S"

    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.11 {TkpComputeStandardMenuGeometry - second accel larger} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "1"
    .m1 add command -label "test" -accel "1 1"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.12 {TkpComputeStandardMenuGeometry - second accel smaller} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "1 1"
    .m1 add command -label "test" -accel "1"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.13 {TkpComputeStandardMenuGeometry - indicator} -constraints {
    unix
} -setup {
    destroy .m1
} -body {

    menu .m1
    .m1 add checkbutton -label test
    .m1 invoke 1


    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.14 {TkpComputeStandardMenuGeometry - second indicator less or equal } -constraints {
    unix testImageType
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test unixMenu-25.15 {TkpComputeStandardMenuGeometry - second indicator larger } -constraints {
    unix testImageType
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test unixMenu-25.16 {TkpComputeStandardMenuGeometry - zero sized menus} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.17 {TkpComputeStandardMenuGeometry - first column bigger} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three -columnbreak 1
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.18 {TkpComputeStandardMenuGeometry - second column bigger} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.19 {TkpComputeStandardMenuGeometry - three columns} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    .m1 add command -label four
    .m1 add command -label five -columnbreak 1
    .m1 add command -label six
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test unixMenu-25.20 {TkpComputeStandardMenuGeometry - hide margin} -constraints {
    unix
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add checkbutton -label one -hidemargin 1
    list [update idletasks] [destroy .m1]
} -result {{} {}}


test unixMenu-26.1 {TkpMenuInit - nothing to do} -constraints unix -body {}



# cleanup
deleteWindows
cleanupTests
return





|
|



<



<
|
|
<
|
|
|
|
<



|
|

<
|
<
<
|

<
|
<
<
|
<


|
|
|
<
<
|
<



|
<
|

|

<
|
|
<



|
|
|
|
<


<
<
|
|
<
<

>
>
|
<
<
|
<


|
<
|
|
<
<
|
<


|
<
|
|
<
<
|

<




|
<
|
<
<
|
<
<
|
<



|
<
|
|
<
<
|
<



|
<
|
|
<
<
|

<




|
<
<
|
|
<
<
|
<



|
<
|
|
<
<
|
<



|
<
|
|
<
<
|
<



|
<
<
|

|
<
<
|
<


|
<
|
|
<
<
|
<


|
<
|
|
|
<


|
<
<
|

|
<
<
|
<




|
|
|
|
<




|
|
|
<
<
|
<



|
<
|

|
<
<
|
<



|
|

|
<
<
|
<



|
|
|
<
<
|
<



>
>
>
<
<
<
<
<
|
<



|
|

<
|
<
<
|
<



|
|
|
>
|
>
>
>
<
<
<
<
<
<
<
|
|
<
<
|
<



|
|
|
<
<
|
<




>
>
>
<
<
<
<
<
|
<



|
|
|
<
<
|
<



|
|
|
<
<
|
>
>
>
>
>
>
<
<
<
<
<
<
<

<
|
|
<



|
|
|
|
<



|
|

<
|
|
<



|
|

<
|
|
<



|
|
|
|
<



|
|

<
|
|
<


|
<
<
|

|
|
<


|
<
<
|

|
<
<
|
<





|
|

<

<
|
<
<
|
<


|
|

|
<
<
|
<



|
|
|
<
<
|
<



|
|
|
<
<
|
<



|
|
|
<
<
|
<



|
|
|
<
<
|
<




|
|
|
<
<
|
<





|
|
|
<
<
|
<





|
|
|
<
<
|
<





|
|
|
<
<
|
<





|
|


|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
|
<






|
|
|
<
<
|
<









|
|
|
<
<
|
<









|
|
|
<
<
|
<









|
|
|
<
<
|
<







|
|
|
<
<
|
<







|
|
|
<
<
|
<





|
|

<
|
|
<



|
|
|
<
<
|
<



|
|

<
|

<
|
|
<


|
|

|
<
<
|
<



|
|
|
<
<
|
<



|
|
|
<
<
|
|






|
|

<
|
<
<
|
<





|
|
<
<
|
<





|
|
<
<
|
<






|
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
|
<




|
|
<
<
|
<





|
|
<
<
|
<





|
|
<
<
|
<





|
|
|
<





|
|
<
<
|
<






|
|
<
<
|
<





|
|
|
<





|
|
<
<
|
<




|
|
|
<




|
|
|
<




|
|
|
<




|
|
<
<
|
<







|
|
|
<





|
|
|
<





|

<
|
<
<
|

<




|
|
|
<



|
|
|
<



|
|
|
<



|

<
|
<
<
|
<


|
|
<
<
|
<



|
|
<
<
|
<




|
|
<
<
|
<



|
|
<
<
|
<






|
|
<
<
|
<



|
|
<
<
|
<



|
|
>
|
>
>
>
|
>
|
<

|
|

|
|
<
<
|
<

|
<

|
|
<
<
|
<

|
>

|
|
<
<
|
<

|
|

|
|
<
<
|
<

|
|

|
|
<
<
|
|
>

|

>
>
|
|
|
<
<
|

<







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<


|
|
<
<
|
<





|
|
<
<
|
<





|
|
<
<
|
<








|
|
<
<
|
<



|

<
|
<
<





1
2
3
4
5
6
7
8
9
10

11
12
13

14
15

16
17
18
19

20
21
22
23
24
25

26


27
28

29


30

31
32
33
34
35


36

37
38
39
40

41
42
43
44

45
46

47
48
49
50
51
52
53

54
55


56
57


58
59
60
61


62

63
64
65

66
67


68

69
70
71

72
73


74
75

76
77
78
79
80

81


82


83

84
85
86
87

88
89


90

91
92
93
94

95
96


97
98

99
100
101
102
103


104
105


106

107
108
109
110

111
112


113

114
115
116
117

118
119


120

121
122
123
124


125
126
127


128

129
130
131

132
133


134

135
136
137

138
139
140

141
142
143


144
145
146


147

148
149
150
151
152
153
154
155

156
157
158
159
160
161
162


163

164
165
166
167

168
169
170


171

172
173
174
175
176
177
178


179

180
181
182
183
184
185


186

187
188
189
190
191
192





193

194
195
196
197
198
199

200


201

202
203
204
205
206
207
208
209
210
211
212







213
214


215

216
217
218
219
220
221


222

223
224
225
226
227
228
229





230

231
232
233
234
235
236


237

238
239
240
241
242
243


244
245
246
247
248
249
250







251

252
253

254
255
256
257
258
259
260

261
262
263
264
265
266

267
268

269
270
271
272
273
274

275
276

277
278
279
280
281
282
283

284
285
286
287
288
289

290
291

292
293
294


295
296
297
298

299
300
301


302
303
304


305

306
307
308
309
310
311
312
313

314

315


316

317
318
319
320
321
322


323

324
325
326
327
328
329


330

331
332
333
334
335
336


337

338
339
340
341
342
343


344

345
346
347
348
349
350


351

352
353
354
355
356
357
358


359

360
361
362
363
364
365
366
367


368

369
370
371
372
373
374
375
376


377

378
379
380
381
382
383
384
385


386

387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476


477

478
479
480
481
482
483
484
485
486
487
488
489


490

491
492
493
494
495
496
497
498
499
500
501
502


503

504
505
506
507
508
509
510
511
512
513
514
515


516

517
518
519
520
521
522
523
524
525
526


527

528
529
530
531
532
533
534
535
536
537


538

539
540
541
542
543
544
545
546

547
548

549
550
551
552
553
554


555

556
557
558
559
560
561

562
563

564
565

566
567
568
569
570
571


572

573
574
575
576
577
578


579

580
581
582
583
584
585


586
587
588
589
590
591
592
593
594
595
596

597


598

599
600
601
602
603
604
605


606

607
608
609
610
611
612
613


614

615
616
617
618
619
620
621
622


623

624
625
626
627
628
629


630

631
632
633
634
635
636


637

638
639
640
641
642
643


644

645
646
647
648
649
650
651

652
653
654
655
656
657


658

659
660
661
662
663
664
665


666

667
668
669
670
671
672
673


674

675
676
677
678
679
680
681
682

683
684
685
686
687
688
689


690

691
692
693
694
695
696
697
698


699

700
701
702
703
704
705
706
707

708
709
710
711
712
713
714


715

716
717
718
719
720
721
722

723
724
725
726
727
728
729

730
731
732
733
734
735
736

737
738
739
740
741
742


743

744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761

762
763
764
765
766
767
768

769


770
771

772
773
774
775
776
777
778

779
780
781
782
783
784

785
786
787
788
789
790

791
792
793
794
795

796


797

798
799
800
801


802

803
804
805
806
807


808

809
810
811
812
813
814


815

816
817
818
819
820


821

822
823
824
825
826
827
828
829


830

831
832
833
834
835


836

837
838
839
840
841
842
843
844
845
846
847
848
849

850
851
852
853
854
855


856

857
858

859
860
861


862

863
864
865
866
867
868


869

870
871
872
873
874
875


876

877
878
879
880
881
882


883
884
885
886
887
888
889
890
891
892
893


894
895

896
897
898
899
900
901
902
903














904


905

906
907
908
909


910

911
912
913
914
915
916
917


918

919
920
921
922
923
924
925


926

927
928
929
930
931
932
933
934
935
936


937

938
939
940
941
942

943


944
945
946
947
948
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


test unixMenu-1.1 {TkpNewMenu - normal menu} unix {
    catch {destroy .m1}

    list [catch {menu .m1} msg] $msg [destroy .m1]
} {0 .m1 {}}
test unixMenu-1.2 {TkpNewMenu - help menu} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label Help -menu .m1.help
    list [catch {menu .m1.help} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 .m1.help {} {}}


test unixMenu-2.1 {TkpDestroyMenu - nothing to do} {} {}


test unixMenu-3.1 {TkpDestroymenuEntry - nothing to do} {} {}


test unixMenu-4.1 {TkpConfigureMenuEntry - non-cascade entry} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label test
    list [catch {.m1 entryconfigure test -label foo} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-4.2 {TkpConfigureMenuEntry - cascade entry} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -menu .m2 -label test
    menu .m1.foo -tearoff 0
    list [catch {.m1 entryconfigure test -menu .m1.foo} msg] $msg [destroy .m1]

} {0 {} {}}

test unixMenu-5.1 {TkpMenuNewEntry - nothing to do} {} {}


test unixMenu-6.1 {TkpSetWindowMenuBar - null menu} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-6.2 {TkpSetWindowMenuBar - menu} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo


    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}



test unixMenu-7.1 {TkpSetMainMenubar - nothing to do} {} {}

test unixMenu-8.1 {GetMenuIndicatorGeometry - indicator off} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.2 {GetMenuIndicatorGeometry - not checkbutton or radio} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.3 {GetMenuIndicatorGeometry - checkbutton image} {unix testImageType} {


    catch {destroy .m1}
    catch {image delete image1}

    menu .m1
    image create test image1
    .m1 add checkbutton -image image1 -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1] [image delete image1]

} {0 {} {}}


test unixMenu-8.4 {GetMenuIndicatorGeometry - checkbutton bitmap} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -bitmap questhead -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.5 {GetMenuIndicatorGeometry - checkbutton} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.6 {GetMenuIndicatorGeometry - radiobutton image} {unix testImageType} {


    catch {destroy .m1}
    catch {image delete image1}

    menu .m1
    image create test image1
    .m1 add radiobutton -image image1 -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1] [image delete image1]


} {0 {} {}}
test unixMenu-8.7 {GetMenuIndicatorGeometry - radiobutton bitmap} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -bitmap questhead -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.8 {GetMenuIndicatorGeometry - radiobutton} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-8.9 {GetMenuIndicatorGeometry - hideMargin} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label foo -hidemargin 1
    .m1 invoke foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]


} {0 {}}

test unixMenu-9.1 {GetMenuAccelGeometry - cascade entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-9.2 {GetMenuAccelGeometry - non-null label} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -accel "Ctrl+S"
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test unixMenu-9.3 {GetMenuAccelGeometry - null label} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]


} {0 {}}

test unixMenu-10.1 {DrawMenuEntryBackground - active menubar} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo
    . configure -menu .m1
    .m1 activate 1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-10.2 {DrawMenuEntryBackground - active} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff activate 0
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-10.3 {DrawMenuEntryBackground - non-active} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]

} {0 {} {}}

test unixMenu-11.1 {DrawMenuEntryAccelerator - menubar} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
# drawArrow parameter is never false under Unix
test unixMenu-11.2 {DrawMenuEntryAccelerator - cascade entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-11.3 {DrawMenuEntryAccelerator - normal entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-11.4 {DrawMenuEntryAccelerator - null entry} unix {





    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}


test unixMenu-12.1 {DrawMenuEntryIndicator - non-check or radio} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-12.2 {DrawMenuEntryIndicator - checkbutton - indicator off} unix {
    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]







} {0 {} {}}
test unixMenu-12.3 {DrawMenuEntryIndicator - checkbutton - not selected} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-12.4 {DrawMenuEntryIndicator - checkbutton - selected} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-12.5 {DrawMenuEntryIndicator - radiobutton - indicator off} unix {





    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label foo -indicatoron 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-12.6 {DrawMenuEntryIndicator - radiobutton - not selected} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}
test unixMenu-12.7 {DrawMenuEntryIndicator - radiobutton - selected} unix {


    catch {destroy .m1}
    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}









test unixMenu-13.1 {DrawMenuSeparator - menubar case} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-13.2 {DrawMenuSepartor - normal menu} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}


test unixMenu-14.1 {DrawMenuEntryLabel} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}


test unixMenu-15.1 {DrawMenuUnderline - menubar} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -underline 0
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-15.2 {DrawMenuUnderline - no menubar} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -underline 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}


test unixMenu-16.1 {TkpPostMenu} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]


} {0 {}}

test unixMenu-17.1 {GetMenuSeparatorGeometry} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]


} {0 {}}

test unixMenu-18.1 {GetTearoffEntryGeometry} {unix nonUnixUserInteraction} {


    catch {destroy .m1}

    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    raise .
    list [catch {tk::MbPost .mb} msg] $msg [tk::MenuUnpost .mb.m] [destroy .mb]
} {0 {} {} {}}


# Don't know how to reproduce the case where the tkwin has been deleted.

test unixMenu-19.1 {TkpComputeMenubarGeometry - zero entries} unix {


    catch {destroy .m1}

    menu .m1
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
# Don't know how to generate one width windows
test unixMenu-19.2 {TkpComputeMenubarGeometry - one entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label File
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.3 {TkpComputeMenubarGeometry - entry with different font} unix {


    catch {destroy .m1}

    menu .m1 -font "Courier 24"
    .m1 add cascade -label File -font "Helvetica 18"
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.4 {TkpComputeMenubarGeometry - separator} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add separator
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.5 {TkpComputeMenubarGeometry - First entry} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.6 {TkpComputeMenubarGeometry - First entry too wide} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File -font "Times 72"
    . configure -menu .m1
    wm geometry . 10x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.7 {TkpComputeMenubarGeometry - two entries fit} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 200x200
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.8 {TkpComputeMenubarGeometry - two entries; 2nd don't fit} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File
    .m1 add cascade -label Edit -font "Times 72"
    . configure -menu .m1
    wm geometry . 100x100
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.9 {TkpComputeMenubarGeometry - two entries; 1st dont fit} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File -font "Times 72"
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 100x100
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.10 {TkpComputeMenubarGeometry - two entries; neither fit} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0 -font "Times 72"
    .m1 add cascade -label File
    .m1 add cascade -label Edit
    . configure -menu .m1
    wm geometry . 10x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
# ABC notation; capital A means first window fits, small a means it
# does not. capital B menu means second window fist, etc.
test unixMenu-19.11 {TkpComputeMenubarGeometry - abc} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0 -font "Times 72"
    .m1 add cascade -label "aaaaa"
    .m1 add cascade -label "bbbbb"
    .m1 add cascade -label "ccccc"
    . configure -menu .m1
    wm geometry . 10x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.12 {TkpComputeMenubarGeometry - abC} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 10x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.13 {TkpComputeMenubarGeometry - aBc} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "B"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 10x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.14 {TkpComputeMenubarGeometry - aBC} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "aaaaa" -font "Times 72"
    .m1 add cascade -label "B"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 60x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.15 {TkpComputeMenubarGeometry - Abc} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 60x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.16 {TkpComputeMenubarGeometry - AbC} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "bbbbb" -font "Times 72"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 60x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.17 {TkpComputeMenubarGeometry - ABc} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "B"
    .m1 add cascade -label "ccccc" -font "Times 72"
    . configure -menu .m1
    wm geometry . 60x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.18 {TkpComputeMenubarGeometry - ABC} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label "A"
    .m1 add cascade -label "B"
    .m1 add cascade -label "C"
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.19 {TkpComputeMenubarGeometry - help menu in first position} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.20 {TkpComputeMenubarGeometry - help menu in middle} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.21 {TkpComputeMenubarGeometry - help menu in first position} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Edit -menu .m1.edit
    menu .m1.edit -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.22 {TkpComputeMenubarGeometry - help item fits} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.23 {TkpComputeMenubarGeometry - help item does not fit} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file -tearoff 0
    .m1 add cascade -label Help -menu .m1.help -font "Helvetica 72"
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-19.24 {TkpComputeMenubarGeometry - help item only one} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label Help -menu .m1.help
    menu .m1.help -tearoff 0
    . configure -menu .m1
    wm geometry . 100x10
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}


test unixMenu-20.1 {DrawTearoffEntry - menubar} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label File
    . configure -menu .m1
    list [catch {update} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test unixMenu-20.2 {DrawTearoffEntry - non-menubar} {unix nonUnixUserInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    .m1 post 40 40
     list [catch {update} msg] $msg [destroy .m1]
} {0 {} {}}


test unixMenu-21.1 {TkpInitializeMenuBindings - nothing to do} {} {}


test unixMenu-22.1 {SetHelpMenu - no menubars} unix {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label test -menu .m1.test
    list [catch {menu .m1.test} msg] $msg [destroy .m1]
} {0 .m1.test {}}
# Don't know how to automate missing tkwins
test unixMenu-22.2 {SetHelpMenu - menubar but no help menu} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label .m1.file
    list [catch {menu .m1.file} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 .m1.file {} {}}
test unixMenu-22.3 {SetHelpMenu - menubar with help menu} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    . configure -menu .m1
    .m1 add cascade -label .m1.help
    list [catch {menu .m1.help} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 .m1.help {} {}}
test unixMenu-22.4 {SetHelpMenu - multiple menubars with same help menu} unix {


    catch {destroy .m1}
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +40+40
    menu .m1 -tearoff 0
    . configure -menu .m1
    .t2 configure -menu .m1
    .m1 add cascade -label .m1.help
    list [catch {menu .m1.help} msg] $msg [. configure -menu ""] [destroy .m1] [destroy .t2]
} {0 .m1.help {} {} {}}


test unixMenu-23.1 {TkpDrawMenuEntry - gc for active and not strict motif} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.2 {TkpDrawMenuEntry - gc for active menu item with its own gc} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activeforeground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.3 {TkpDrawMenuEntry - gc for active and strict motif} unix {


    catch {destroy .m1}

    menu .m1
    set tk_strictMotif 1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} {{} {} 0}
test unixMenu-23.4 {TkpDrawMenuEntry - gc for disabled with disabledfg and custom entry} unix {


    catch {destroy .m1}

    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled -background red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.5 {TkpDrawMenuEntry - gc for disabled with disabledFg} unix {


    catch {destroy .m1}

    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.6 {TkpDrawMenuEntry - gc for disabled - no disabledFg} unix {


    catch {destroy .m1}

    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.7 {TkpDrawMenuEntry - gc for normal - custom entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -foreground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.8 {TkpDrawMenuEntry - gc for normal} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.9 {TkpDrawMenuEntry - gc for indicator - custom entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo -selectcolor orange
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.10 {TkpDrawMenuEntry - gc for indicator} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.11 {TkpDrawMenuEntry - border - custom entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activebackground green
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.12 {TkpDrawMenuEntry - border} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.13 {TkpDrawMenuEntry - active border - strict motif} unix {


    catch {destroy .m1}

    set tk_strictMotif 1
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} {{} {} 0}
test unixMenu-23.14 {TkpDrawMenuEntry - active border - custom entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activeforeground yellow
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.15 {TkpDrawMenuEntry - active border} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.16 {TkpDrawMenuEntry - font - custom entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -font "Helvectica 72"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.17 {TkpDrawMenuEntry - font} unix {
    catch {destroy .m1}

    menu .m1 -font "Courier 72"
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.18 {TkpDrawMenuEntry - separator} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.19 {TkpDrawMenuEntry - standard} unix {
    catch {destroy .mb}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.20 {TkpDrawMenuEntry - disabled cascade item} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file
    .m1.file add command -label foo
    .m1 entryconfigure File -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.21 {TkpDrawMenuEntry - indicator} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label Foo
    .m1 invoke Foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test unixMenu-23.22 {TkpDrawMenuEntry - hide margin} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label Foo -hidemargin 1
    .m1 invoke Foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test unixMenu-24.1 {GetMenuLabelGeometry - image} {testImageType unix} {


    catch {destroy .m1}
    catch {image delete image1}

    menu .m1
    image create test image1
    .m1 add command -image image1
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}
test unixMenu-24.2 {GetMenuLabelGeometry - bitmap} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -bitmap questhead
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-24.3 {GetMenuLabelGeometry - no text} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-24.4 {GetMenuLabelGeometry - text} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "This is a test."
    list [update idletasks] [destroy .m1]
} {{} {}}


test unixMenu-25.1 {TkpComputeStandardMenuGeometry - no entries} unix {


    catch {destroy .m1}

    menu .m1
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.2 {TkpComputeStandardMenuGeometry - one entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "one"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.3 {TkpComputeStandardMenuGeometry - more than one entry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.4 {TkpComputeStandardMenuGeometry - separator} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add separator
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.5 {TkpComputeStandardMenuGeometry - tearoff entry} {unix nonUnixUserInteraction} {


    catch {destroy .m1}

    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    catch {tk::MbPost .mb}
    list [update] [tk::MenuUnpost .mb.m] [destroy .mb]
} {{} {} {}}
test unixMenu-25.6 {TkpComputeStandardMenuGeometry - standard label geometry} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.7 {TkpComputeStandardMenuGeometry - different font for entry} unix {


    catch {destroy .m1}

    menu .m1 -font "Helvetica 12"
    .m1 add command -label "test" -font "Courier 12"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.8 {TkpComputeStandardMenuGeometry - second entry larger} unix {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.9 {TkpComputeStandardMenuGeometry - first entry larger} unix {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test test"
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.10 {TkpComputeStandardMenuGeometry - accelerator} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "Ctrl+S"

    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.11 {TkpComputeStandardMenuGeometry - second accel larger} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "1"
    .m1 add command -label "test" -accel "1 1"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.12 {TkpComputeStandardMenuGeometry - second accel smaller} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "1 1"
    .m1 add command -label "test" -accel "1"
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.13 {TkpComputeStandardMenuGeometry - indicator} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label test
    .m1 invoke 1
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.14 {TkpComputeStandardMenuGeometry - second indicator less or equal } {unix testImageType} {


    catch {destroy .m1}
    catch {image delete image1}
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}
test unixMenu-25.15 {TkpComputeStandardMenuGeometry - second indicator larger } {unix testImageType} {


    catch {destroy .m1}
    catch {image delete image1}

    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}














test unixMenu-25.16 {TkpComputeStandardMenuGeometry - zero sized menus} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.17 {TkpComputeStandardMenuGeometry - first column bigger} unix {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three -columnbreak 1
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.18 {TkpComputeStandardMenuGeometry - second column bigger} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.19 {TkpComputeStandardMenuGeometry - three columns} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    .m1 add command -label four
    .m1 add command -label five -columnbreak 1
    .m1 add command -label six
    list [update idletasks] [destroy .m1]
} {{} {}}
test unixMenu-25.20 {TkpComputeStandardMenuGeometry - hide margin} unix {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add checkbutton -label one -hidemargin 1
    list [update idletasks] [destroy .m1]
} {{} {}}


test unixMenu-26.1 {TkpMenuInit - nothing to do} {} {}



# cleanup
deleteWindows
cleanupTests
return

Changes to tests/unixSelect.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159

160

161
162
163
164
165
166
167
168
169
170
171



172
173
174
175
176
177
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218

219






220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267


268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
# This file contains tests for the tkUnixSelect.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 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.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
    global selValue selInfo
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
    return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errIncrHandler {type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
    if {$pass == 0} {
        # Just sizing the selection;  don't do anything here.
        set pass 1
    } else {
        # Fetching the selection;  wait long enough to cause a timeout.
        after 6000
    }
    }
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
    return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errHandler args {
    error "selection handler aborted"
}

proc badHandler {path type offset count} {
    global selValue selInfo
    selection handle -type $type $path {}
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
    return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}
proc reallyBadHandler {path type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
    if {$pass == 0} {
        set pass 1
    } else {
        selection handle -type $type $path {}
    }
    }
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
    return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

# Eliminate any existing selection on the screen.  This is needed in case
# there is a selection in some other application, in order to prevent races
# from causing false errors in the tests below.

selection clear .
after 1500

# common setup code
proc setup {{path .f1} {display {}}} {
    catch {destroy $path}
    if {$display == {}} {
    frame $path
    } else {
    toplevel $path -screen $display
    wm geom $path +0+0
    }
    selection own $path
}

# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# ----------------------------------------------------------------------

test unixSelect-1.1 {TkSelGetSelection procedure: simple i18n text} -constraints {
    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]

    update
    .e insert 0 über
    .e selection range 0 end
    dobg {string length [selection get]}
} -cleanup {
    cleanupbg
    destroy .e
} -result 4

test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 üф
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg

} -result ü?

test unixSelect-1.3 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue üф
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal üф $x] [string length $x]

    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg

} -result {1 2 {COMPOUND_TEXT 0 4000}}


test unixSelect-1.4 {TkSelGetSelection procedure: INCR i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    # This test is subtle.  The selection ends up getting fetched twice by
    # Tk:  once to compute the length, and again to actually send the data.
    # The first time through, we don't convert the data to ISO2022, so the
    # buffer boundaries end up being different in the two passes.



    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue [string repeat x 3999]üф[string repeat x 3999]
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal \
            [string repeat x 3999]üф[string repeat x 3999] $x] \
            [string length $x]
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg

} -result {1 8000 {COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3999 COMPOUND_TEXT 7998 4000 COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3998 COMPOUND_TEXT 7997 4000}}

test unixSelect-1.5 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue üф
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal üф $x] [string length $x]

    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg

} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.6 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg [subst -nobackslashes {entry .e; pack .e; update
    .e insert 0 über$longValue
    .e selection range 0 end}]
    string length [selection get]
} -cleanup {
    cleanupbg

} -result [expr {4 + [string length $longValue]}]







test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]ü
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü


test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 ü[string repeat x 3999]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result ü[string repeat x 3999]


test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]ü[string repeat x 4000]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü[string repeat x 4000]


# Now some tests to make sure that the right thing is done when
# transferring UTF8 selections, to prevent [Bug 614650] and its ilk
# from rearing its ugly head again.

test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]ü
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü


test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 ü[string repeat x 3999]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result ü[string repeat x 3999]


test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]ü[string repeat x 4000]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü[string repeat x 4000]


test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]

    update
    .e insert 0 überф
    .e selection range 0 end
    dobg {string length [selection get -type UTF8_STRING]}
} -cleanup {
    destroy .e
    cleanupbg
} -result 5

test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 üф
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg

} -result üф

test unixSelect-1.15 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat [string repeat Ää 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat Ää 50]\n 21]


test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 i[string repeat [string repeat Ää 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat Ää 50]\n 21]


test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 [string repeat [string repeat Ää 50]\n 21]
        # Has to be selected in a separate stage
        .t tag add sel 1.0 21.end+1c
    }
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat Ää 50]\n 21]


test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 i[string repeat [string repeat Ää 50]\n 21]
        # Has to be selected in a separate stage
        .t tag add sel 1.0 21.end+1c
    }
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat Ää 50]\n 21]


test unixSelect-1.19 {Automatic UTF8_STRING support for selection handle} -constraints {
    unix
} -setup {
    destroy .l
} -body {
    # See Bug #666346 "Selection handling crashes under KDE 3.0"
    label .l
    selection handle .l  [list handler STRING]
    set selValue "This is the selection value"
    selection own .l
    selection get -type UTF8_STRING
} -cleanup {
    destroy .l

} -result {This is the selection value}

# cleanup
cleanupTests
return






|





<
|












|







|
|
|
|
|
|
|




|














|






|
|
|
|
|




|















|

|
|











<
<
|
<
<
<

<
|
>

|

|
<


|
|
|
<
<

<

|
<
|
|

|
<

>
|
|
|
<
<


<

|

|


|
|
>

<
<

>
|
>

<
<
<
<
<
<




>
>
>

|

|


|
|
|
|

<
<

>
|
<
|
<
<


<

|

|


|
|
>

<
<

>
|
<
|
<
<

<
|
|
|
|
<

>
|
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
|
<

|
|
>
|
<
<

<

<
|
|
|

|
<

|
|
>
|
<
<

<

|
<
|
|

|
<

|
>
>



<
|
<
<

<

|
<
|
|

|
<

|
|
>
|
<
<

<

|
<
|
|

|
<

|
|
>
|
<
<

<

|
<
|
|

|
<

|
|
>
|
<
<
<

<
|
>

|

|
|

<
|
|
|
<
<

<

|
<
|
|

|
<

>
|
|
|
<
<

<

|
<
|
|

|
<

|
|
>
|
<
<

<

|
<
|
|

|
<

|
|
>
|
<
<

<

<
|
|
|
|


|
<

|
|
>
|
<
<

<

<
|
|
|
|


|
<

|
|
>
|
<
<
<
<





|
<

>
|




1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106


107



108

109
110
111
112
113
114

115
116
117
118
119


120

121
122

123
124
125
126

127
128
129
130
131


132
133

134
135
136
137
138
139
140
141
142
143


144
145
146
147
148






149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166


167
168
169

170


171
172

173
174
175
176
177
178
179
180
181
182


183
184
185

186


187

188
189
190
191

192
193
194
195
196
197
198
199
200
201











202

203
204
205
206
207


208

209

210
211
212
213
214

215
216
217
218
219


220

221
222

223
224
225
226

227
228
229
230
231
232
233

234


235

236
237

238
239
240
241

242
243
244
245
246


247

248
249

250
251
252
253

254
255
256
257
258


259

260
261

262
263
264
265

266
267
268
269
270



271

272
273
274
275
276
277
278
279

280
281
282


283

284
285

286
287
288
289

290
291
292
293
294


295

296
297

298
299
300
301

302
303
304
305
306


307

308
309

310
311
312
313

314
315
316
317
318


319

320

321
322
323
324
325
326
327

328
329
330
331
332


333

334

335
336
337
338
339
340
341

342
343
344
345
346




347
348
349
350
351
352

353
354
355
356
357
358
359
# This file contains tests for the tkUnixSelect.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# 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.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
    global selValue selInfo
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errIncrHandler {type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    # Just sizing the selection;  don't do anything here.
	    set pass 1
	} else {
	    # Fetching the selection;  wait long enough to cause a timeout.
	    after 6000
	}
    }
    lappend selInfo $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

proc errHandler args {
    error "selection handler aborted"
}

proc badHandler {path type offset count} {
    global selValue selInfo
    selection handle -type $type $path {}
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}
proc reallyBadHandler {path type offset count} {
    global selValue selInfo pass
    if {$offset == 4000} {
	if {$pass == 0} {
	    set pass 1
	} else {
	    selection handle -type $type $path {}
	}
    }
    lappend selInfo $path $type $offset $count
    set numBytes [expr {[string length $selValue] - $offset}]
    if {$numBytes <= 0} {
	return ""
    }
    string range $selValue $offset [expr $numBytes+$offset]
}

# Eliminate any existing selection on the screen.  This is needed in case
# there is a selection in some other application, in order to prevent races
# from causing false errors in the tests below.

selection clear .
after 1500

# common setup code
proc setup {{path .f1} {display {}}} {
    catch {destroy $path}
    if {$display == {}} {
	frame $path
    } else {
	toplevel $path -screen $display
	wm geom $path +0+0
    }
    selection own $path
}

# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}



test unixSelect-1.1 {TkSelGetSelection procedure: simple i18n text} unix {



    setupbg

    entry .e
    pack .e
    update
    .e insert 0 [encoding convertfrom identity \u00fcber]
    .e selection range 0 end
    set result [dobg {string bytelength [selection get]}]

    cleanupbg
    destroy .e
    set result
} {5}
test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 \u00fc\u0444
	.e selection range 0 end
    }
    set x [selection get]

    cleanupbg
    list [string equal \u00fc? $x] \
	    [string length $x] [string bytelength $x]
} {1 2 3}
test unixSelect-1.4 {TkSelGetSelection procedure: simple i18n text, iso2022} unix {


    setupbg
    setup

    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
	    {handler COMPOUND_TEXT}
    selection own .
    set selValue \u00fc\u0444
    set selInfo {}
    set result [dobg {
	set x [selection get -type COMPOUND_TEXT]
	list [string equal \u00fc\u0444 $x] \
		[string length $x] [string bytelength $x]
    }]


    cleanupbg
    lappend result $selInfo
} {1 2 4 {COMPOUND_TEXT 0 4000}}
test unixSelect-1.5 {TkSelGetSelection procedure: INCR i18n text, iso2022} unix {







    # This test is subtle.  The selection ends up getting fetched twice by
    # Tk:  once to compute the length, and again to actually send the data.
    # The first time through, we don't convert the data to ISO2022, so the
    # buffer boundaries end up being different in the two passes.

    setupbg
    setup
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
	    {handler COMPOUND_TEXT}
    selection own .
    set selValue [string repeat x 3999]\u00fc\u0444[string repeat x 3999]
    set selInfo {}
    set result [dobg {
	set x [selection get -type COMPOUND_TEXT]
	list [string equal \
		[string repeat x 3999]\u00fc\u0444[string repeat x 3999] $x] \
		[string length $x] [string bytelength $x]
    }]


    cleanupbg
    lappend result $selInfo
} {1 8000 8002 {COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3999 COMPOUND_TEXT 7998 4000 COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3998 COMPOUND_TEXT 7997 4000}}

test unixSelect-1.6 {TkSelGetSelection procedure: simple i18n text, iso2022} unix {


    setupbg
    setup

    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
	    {handler COMPOUND_TEXT}
    selection own .
    set selValue \u00fc\u0444
    set selInfo {}
    set result [dobg {
	set x [selection get -type COMPOUND_TEXT]
	list [string equal \u00fc\u0444 $x] \
		[string length $x] [string bytelength $x]
    }]


    cleanupbg
    lappend result $selInfo
} {1 2 4 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} unix {


    setupbg

    dobg "entry .e; pack .e; update
    .e insert 0 \[encoding convertfrom identity \\u00fcber\]$longValue
    .e selection range 0 end"
    set result [string bytelength [selection get]]

    cleanupbg
    set result
} [expr {5 + [string bytelength $longValue]}]
test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} unix {
    setupbg
    dobg {
	entry .e; pack .e; update
	.e insert 0 [string repeat x 3999]\u00fc
	.e selection range 0 end
    }











    set x [selection get]

    cleanupbg
    list [string equal [string repeat x 3999]\u00fc $x] \
	    [string length $x] [string bytelength $x]
} {1 4000 4001}
test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} unix {


    setupbg

    dobg {

	entry .e; pack .e; update
	.e insert 0 \u00fc[string repeat x 3999]
	.e selection range 0 end
    }
    set x [selection get]

    cleanupbg
    list [string equal \u00fc[string repeat x 3999] $x] \
	    [string length $x] [string bytelength $x]
} {1 4000 4001}
test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
	.e selection range 0 end
    }
    set x [selection get]

    cleanupbg
    list [string equal [string repeat x 3999]\u00fc[string repeat x 4000] $x] \
	    [string length $x] [string bytelength $x]
} {1 8000 8001}
# Now some tests to make sure that the right thing is done when
# transferring UTF8 selections, to prevent [Bug 614650] and its ilk
# from rearing its ugly head again.

test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 [string repeat x 3999]\u00fc
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal [string repeat x 3999]\u00fc $x] \
	    [string length $x] [string bytelength $x]
} {1 4000 4001}
test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 \u00fc[string repeat x 3999]
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal \u00fc[string repeat x 3999] $x] \
	    [string length $x] [string bytelength $x]
} {1 4000 4001}
test unixSelect-1.13 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal [string repeat x 3999]\u00fc[string repeat x 4000] $x] \
	    [string length $x] [string bytelength $x]
} {1 8000 8001}
test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} unix {



    setupbg

    entry .e
    pack .e
    update
    .e insert 0 [encoding convertfrom identity \u00fcber\u0444]
    .e selection range 0 end
    set result [dobg {string bytelength [selection get -type UTF8_STRING]}]
    cleanupbg
    destroy .e

    set result
} {5}
test unixSelect-1.15 {TkSelGetSelection procedure: simple i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 \u00fc\u0444
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal \u00fc\u0444 $x] \
	    [string length $x] [string bytelength $x]
} {1 2 4}
test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal [string repeat [string repeat \u00c4\u00e4 50]\n 21] $x] \
	    [string length $x] [string bytelength $x]
} {1 2121 4221}
test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {
	entry .e; pack .e; update

	.e insert 0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
	.e selection range 0 end
    }
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal i[string repeat [string repeat \u00c4\u00e4 50]\n 21] $x] \
	    [string length $x] [string bytelength $x]
} {1 2122 4222}
test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {

	text .t; pack .t; update
	.t insert 1.0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
	# Has to be selected in a separate stage
	.t tag add sel 1.0 21.end+1c
    }
    after 10
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal [string repeat [string repeat \u00c4\u00e4 50]\n 21] $x] \
	    [string length $x] [string bytelength $x]
} {1 2121 4221}
test unixSelect-1.19 {TkSelGetSelection procedure: INCR i18n text, utf-8} unix {


    setupbg

    dobg {

	text .t; pack .t; update
	.t insert 1.0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
	# Has to be selected in a separate stage
	.t tag add sel 1.0 21.end+1c
    }
    after 10
    set x [selection get -type UTF8_STRING]

    cleanupbg
    list [string equal i[string repeat [string repeat \u00c4\u00e4 50]\n 21] $x] \
	    [string length $x] [string bytelength $x]
} {1 2122 4222}
test unixSelect-1.20 {Automatic UTF8_STRING support for selection handle} unix {




    # See Bug #666346 "Selection handling crashes under KDE 3.0"
    label .l
    selection handle .l  [list handler STRING]
    set selValue "This is the selection value"
    selection own .l
    set result [selection get -type UTF8_STRING]

    destroy .l
    set result
} "This is the selection value"

# cleanup
cleanupTests
return

Changes to tests/unixWm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

namespace import -force ::tk::test:loadTkCommand

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

proc sleep ms {
    global x
    after $ms {set x 1}
    vwait x
}

# Procedure to set up a collection of top-level windows

proc makeToplevels {} {
    deleteWindows
    foreach i {.raise1 .raise2 .raise3} {
	toplevel $i
	wm geom $i 150x100+0+0
	update
    }
}

# On macOS windows are not allowed to overlap the menubar at the top
# of the screen.  So tests which move a window and then check whether
# it got moved to the requested location should use a y coordinate
# larger than the height of the menubar (normally 23 pixels).

if {[tk windowingsystem] eq "aqua"} {
    set mb [expr [menubarheight] + 1]
    set Y0 $mb
    set Y2 [expr $mb + 2]
    set Y5 [expr $mb + 5]
} else {
    set Y0 0
    set Y2 2
    set Y5 5
}

set i 1
foreach geom "+$Y0+80 +80+$Y0 +0+$Y0" {
    destroy .t
    test unixWm-1.$i {initial window position} unix {
	toplevel .t -width 200 -height 150
	wm geom .t $geom
	update
	wm geom .t
    } 200x150$geom




|
|
|








|
|


















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
















36
37
38
39
40
41
42
43
44
# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

namespace import -force ::tk::test:loadTkCommand

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

proc sleep ms {
    global x
    after $ms {set x 1}
    vwait x
}

# Procedure to set up a collection of top-level windows

proc makeToplevels {} {
    deleteWindows
    foreach i {.raise1 .raise2 .raise3} {
	toplevel $i
	wm geom $i 150x100+0+0
	update
    }
}

















set i 1
foreach geom {+20+80 +80+20 +0+0} {
    destroy .t
    test unixWm-1.$i {initial window position} unix {
	toplevel .t -width 200 -height 150
	wm geom .t $geom
	update
	wm geom .t
    } 200x150$geom
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
wm geom .t +200+200
update
wm geom .t +150+150
update
scan [wm geom .t] %dx%d+%d+%d width height x y
set xerr [expr 150-$x]
set yerr [expr 150-$y]
foreach geom "+20+80 +80+$Y0 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
    test unixWm-2.$i {moving window while mapped} unix {
	wm geom .t $geom
	update
	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+20+80 +80+$Y0 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
    test unixWm-3.$i {moving window while iconified} unix {
	wm iconify .t
	update idletasks
	wm geom .t $geom
	update idletasks
	wm deiconify .t
	update idletasks
	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+20+80 +100+40 +0+$Y0" {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	update idletasks
	wm geom .t $geom
	update idletasks
	wm deiconify .t
	update idletasks
	wm geom .t
    } 100x150$geom
    incr i
}

test unixWm-5.1 {compounded state changes} {unix nonPortable} {
    destroy .t







|











|


|

|

<








|


|

|

<







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
wm geom .t +200+200
update
wm geom .t +150+150
update
scan [wm geom .t] %dx%d+%d+%d width height x y
set xerr [expr 150-$x]
set yerr [expr 150-$y]
foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
    test unixWm-2.$i {moving window while mapped} unix {
	wm geom .t $geom
	update
	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom {+20+80 +80+20 +0+0 -0-0 +0-0 -0+0 -10-5 -10+5 +10-5} {
    test unixWm-3.$i {moving window while iconified} unix {
	wm iconify .t
	sleep 200
	wm geom .t $geom
	update
	wm deiconify .t

	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom {+20+80 +100+40 +0+0} {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	sleep 200
	wm geom .t $geom
	update
	wm deiconify .t

	wm geom .t
    } 100x150$geom
    incr i
}

test unixWm-5.1 {compounded state changes} {unix nonPortable} {
    destroy .t
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    wm withdraw .t
    wm iconify .t
    list [winfo ismapped .t] [wm state .t]
} {0 iconic}

destroy .t
toplevel .t -width 200 -height 100
wm geom .t +10+$Y0
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
    .t config -width 180 -height 150
    update
    wm geom .t
} 180x150+10+$Y0
test unixWm-6.2 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    update
    wm geom .t
} 250x60+10+$Y0
test unixWm-6.3 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    wm geom .t {}
    update
    wm geom .t
} 170x140+10+$Y0
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
    wm minsize .t 1 1
    update
    puts stdout "Please resize window \"t\" with the mouse (but don't move it!),"
    puts -nonewline stdout "then hit return: "
    flush stdout
    gets stdin







|






|





|






|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    wm withdraw .t
    wm iconify .t
    list [winfo ismapped .t] [wm state .t]
} {0 iconic}

destroy .t
toplevel .t -width 200 -height 100
wm geom .t +10+10
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
    .t config -width 180 -height 150
    update
    wm geom .t
} 180x150+10+10
test unixWm-6.2 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    update
    wm geom .t
} 250x60+10+10
test unixWm-6.3 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    wm geom .t {}
    update
    wm geom .t
} 170x140+10+10
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
    wm minsize .t 1 1
    update
    puts stdout "Please resize window \"t\" with the mouse (but don't move it!),"
    puts -nonewline stdout "then hit return: "
    flush stdout
    gets stdin
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    list [catch {wm iconwindow} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}
test unixWm-8.3 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t b c} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}
test unixWm-8.4 {icon windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .icon
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    update idletasks
    set result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    lappend result [wm iconwindow .t] [wm state .icon]
    wm iconwindow .t {}
    lappend result [wm iconwindow .t] [wm state .icon]
    update
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
    wm iconify .t
    update idletasks
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {.icon icon {} withdrawn 1 0 0 0}
test unixWm-8.5 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t .gorp} msg] $msg
} {1 {bad window path name ".gorp"}}







|




<









|







268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    list [catch {wm iconwindow} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}
test unixWm-8.3 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t b c} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}
test unixWm-8.4 {icon windows} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t
    destroy .icon
    toplevel .t -width 100 -height 30
    wm geom .t +0+0

    set result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    lappend result [wm iconwindow .t] [wm state .icon]
    wm iconwindow .t {}
    lappend result [wm iconwindow .t] [wm state .icon]
    update
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
    wm iconify .t
    update
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {.icon icon {} withdrawn 1 0 0 0}
test unixWm-8.5 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t .gorp} msg] $msg
} {1 {bad window path name ".gorp"}}
339
340
341
342
343
344
345

346
347
348
349
350
351
352
    wm geom .icon +0+0
    update
    set result [winfo ismapped .icon]
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    tkwait visibility .t	;# Needed to keep tvtwm happy.
    wm iconwindow .t .icon

    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {1 1 0}
test unixWm-8.9 {icon windows} {unix nonPortable} {
    # This test is non-portable because some window managers will
    # destroy an icon window when it's associated window is destroyed.

    destroy .t







>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
    wm geom .icon +0+0
    update
    set result [winfo ismapped .icon]
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    tkwait visibility .t	;# Needed to keep tvtwm happy.
    wm iconwindow .t .icon
    sleep 500
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {1 1 0}
test unixWm-8.9 {icon windows} {unix nonPortable} {
    # This test is non-portable because some window managers will
    # destroy an icon window when it's associated window is destroyed.

    destroy .t
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    wm geom .t +0+0
    wm command .t "test command"
    update
    testprop [testwrapper .t] WM_COMMAND
} {test
command
}
test unixWm-9.3 {TkWmMapWindow procedure, iconic windows} unix {
    destroy .t
    toplevel .t -width 100 -height 300 -bg blue
    wm geom .t +0+0
    wm iconify .t

    winfo ismapped .t
} 0
test unixWm-9.4 {TkWmMapWindow procedure, icon windows} unix {
    destroy .t

    toplevel .t -width 100 -height 50 -bg blue
    tkwait visibility .t
    wm iconwindow . .t
    update
    set result [winfo ismapped .t]
} 0
test unixWm-9.5 {TkWmMapWindow procedure, normal windows} unix {
    destroy .t
    toplevel .t -width 200 -height 20
    wm geom .t +0+0
    update
    winfo ismapped .t
} 1

test unixWm-10.1 {TkWmDeadWindow procedure, canceling UpdateGeometry idle handler} unix {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
    .t configure -width 200 -height 100







|




>

|


>

<



|






|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
    wm geom .t +0+0
    wm command .t "test command"
    update
    testprop [testwrapper .t] WM_COMMAND
} {test
command
}
test unixWm-9.3 {TkWmMapWindow procedure, iconic windows} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t
    toplevel .t -width 100 -height 300 -bg blue
    wm geom .t +0+0
    wm iconify .t
    sleep 500
    winfo ismapped .t
} {0}
test unixWm-9.4 {TkWmMapWindow procedure, icon windows} unix {
    destroy .t
    sleep 500
    toplevel .t -width 100 -height 50 -bg blue

    wm iconwindow . .t
    update
    set result [winfo ismapped .t]
} {0}
test unixWm-9.5 {TkWmMapWindow procedure, normal windows} unix {
    destroy .t
    toplevel .t -width 200 -height 20
    wm geom .t +0+0
    update
    winfo ismapped .t
} {1}

test unixWm-10.1 {TkWmDeadWindow procedure, canceling UpdateGeometry idle handler} unix {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
    .t configure -width 200 -height 100
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
    destroy .icon
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu} {
    wm iconify .t
    set result {}
    lappend result [winfo ismapped .t] [wm state .t]
    wm deiconify .t
    lappend result [winfo ismapped .t] [wm state .t]
} {0 iconic 1 normal}








|







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
    destroy .icon
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu failsOnQuarz} {
    wm iconify .t
    set result {}
    lappend result [winfo ismapped .t] [wm state .t]
    wm deiconify .t
    lappend result [winfo ismapped .t] [wm state .t]
} {0 iconic 1 normal}

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
} {passive active passive}

test unixWm-18.1 {Tk_WmCmd procedure, "frame" option} unix {
    list [catch {wm frame .t 12} msg] $msg
} {1 {wrong # args: should be "wm frame window"}}
test unixWm-18.2 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    expr [wm frame .t] == [winfo id .t]
} 0
test unixWm-18.3 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm overrideredirect .t2 1
    update
    set result [expr [wm frame .t2] == [winfo id .t2]]
    destroy .t2
    set result
} 1

test unixWm-19.1 {Tk_WmCmd procedure, "geometry" option} unix {
    list [catch {wm geometry .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm geometry window ?newGeometry?"}}
test unixWm-19.2 {Tk_WmCmd procedure, "geometry" option} {unix nonPortable} {
    wm geometry .t -1+5
    update







|









|







643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
} {passive active passive}

test unixWm-18.1 {Tk_WmCmd procedure, "frame" option} unix {
    list [catch {wm frame .t 12} msg] $msg
} {1 {wrong # args: should be "wm frame window"}}
test unixWm-18.2 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    expr [wm frame .t] == [winfo id .t]
} {0}
test unixWm-18.3 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm overrideredirect .t2 1
    update
    set result [expr [wm frame .t2] == [winfo id .t2]]
    destroy .t2
    set result
} {1}

test unixWm-19.1 {Tk_WmCmd procedure, "geometry" option} unix {
    list [catch {wm geometry .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm geometry window ?newGeometry?"}}
test unixWm-19.2 {Tk_WmCmd procedure, "geometry" option} {unix nonPortable} {
    wm geometry .t -1+5
    update
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
    toplevel .t2
    wm geom .t2 +0+0
    wm group .t .t2
    set hints [testprop [testwrapper .t] WM_HINTS]
    set result [expr [testwrapper .t2] - [lindex $hints 8]]
    destroy .t2
    set result
} 0
test unixWm-21.5 {Tk_WmCmd procedure, "group" option, create leader wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0







|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    toplevel .t2
    wm geom .t2 +0+0
    wm group .t .t2
    set hints [testprop [testwrapper .t] WM_HINTS]
    set result [expr [testwrapper .t2] - [lindex $hints 8]]
    destroy .t2
    set result
} {0}
test unixWm-21.5 {Tk_WmCmd procedure, "group" option, create leader wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826

827
828
829
830
831
832
833
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
    wm iconbitmap .t {}
    set bit [format 0x%x [expr 0x4 & [lindex [testprop [testwrapper .t] \
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
} {{} questhead 0x4 {} 0x0}
if {[tk windowingsystem] == "aqua"} {
    set result_22_3 {0 {}}
} else {
    set result_22_3 {1 {bitmap "bad-bitmap" not defined}}
}
test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \
unix {
    list [catch {wm iconbitmap .t bad-bitmap} msg] $msg
} $result_22_3


test unixWm-23.1 {Tk_WmCmd procedure, "iconify" option} unix {
    list [catch {wm iconify .t 12} msg] $msg
} {1 {wrong # args: should be "wm iconify window"}}
test unixWm-23.2 {Tk_WmCmd procedure, "iconify" option} unix {
    destroy .t2
    toplevel .t2







<
<
<
<
<
|
<

<
>







794
795
796
797
798
799
800





801

802

803
804
805
806
807
808
809
810
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
    wm iconbitmap .t {}
    set bit [format 0x%x [expr 0x4 & [lindex [testprop [testwrapper .t] \
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
} {{} questhead 0x4 {} 0x0}





test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option} unix {

    list [catch {wm iconbitmap .t bad-bitmap} msg] $msg

} {1 {bitmap "bad-bitmap" not defined}}

test unixWm-23.1 {Tk_WmCmd procedure, "iconify" option} unix {
    list [catch {wm iconify .t 12} msg] $msg
} {1 {wrong # args: should be "wm iconify window"}}
test unixWm-23.2 {Tk_WmCmd procedure, "iconify" option} unix {
    destroy .t2
    toplevel .t2
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify ".t2": it is an icon for ".t"}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    update idletasks
    wm iconify .t2
    update idletasks
    set result [winfo ismapped .t2]
    destroy .t2
    set result
} 0
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
    lappend result [winfo ismapped .t2]
    destroy .t2
    set result
} {1 0}

test unixWm-24.1 {Tk_WmCmd procedure, "iconmask" option} unix {
    list [catch {wm iconmask .t 12 13} msg] $msg







|
|



|

|



|
|



|


|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify .t2: it is an icon for .t}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    update
    wm iconify .t2
    update
    set result [winfo ismapped .t2]
    destroy .t2
    set result
} {0}
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update
    set result [winfo ismapped .t2]
    wm iconify .t2
    update
    lappend result [winfo ismapped .t2]
    destroy .t2
    set result
} {1 0}

test unixWm-24.1 {Tk_WmCmd procedure, "iconmask" option} unix {
    list [catch {wm iconmask .t 12 13} msg] $msg
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
    set bit [format 0x%x [expr 0xa & [lindex [testprop [testwrapper .t] \
	    WM_NORMAL_HINTS] 0]]]
    lappend result [wm sizefrom .t] $bit
} {{} program 0x8 user 0x2}
test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix {
    list [catch {wm sizefrom .t none} msg]  $msg
} {1 {bad argument "none": must be program or user}}
if {[tk windowingsystem] == "aqua"} {
    set result_35_1 {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}}
} else {
    set result_35_1 {1 {bad argument "1": must be normal, iconic, or withdrawn}}
}
test unixWm-35.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} {
    list [catch {wm state .t 1} msg]  $msg
} $result_35_1

test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix {
    list [catch {wm state .t iconic 1} msg]  $msg
} {1 {wrong # args: should be "wm state window ?state?"}}
test unixWm-35.3 {Tk_WmCmd procedure, "state" option} unix {
    set result {}
    destroy .t2
    toplevel .t2 -width 120 -height 300







<
<
<
<
|
|

<
>







1199
1200
1201
1202
1203
1204
1205




1206
1207
1208

1209
1210
1211
1212
1213
1214
1215
1216
    set bit [format 0x%x [expr 0xa & [lindex [testprop [testwrapper .t] \
	    WM_NORMAL_HINTS] 0]]]
    lappend result [wm sizefrom .t] $bit
} {{} program 0x8 user 0x2}
test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix {
    list [catch {wm sizefrom .t none} msg]  $msg
} {1 {bad argument "none": must be program or user}}





test unixWm-35.1 {Tk_WmCmd procedure, "state" option} unix {
    list [catch {wm state .t 1} msg]  $msg

} {1 {bad argument "1": must be normal, iconic, or withdrawn}}
test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix {
    list [catch {wm state .t iconic 1} msg]  $msg
} {1 {wrong # args: should be "wm state window ?state?"}}
test unixWm-35.3 {Tk_WmCmd procedure, "state" option} unix {
    set result {}
    destroy .t2
    toplevel .t2 -width 120 -height 300
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
    lappend result [wm transient .t2] [expr [testwrapper .t] - $transient]
    wm transient .t2 {}
    lappend result [wm transient .t2] \
	    [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
    destroy .t2
    set result
} {{} {} .t 0 {} {}}
test unixWm-37.4 {TkWmDeadWindow, destroy on toplevel should clear transient} {unix testwrapper} {
    destroy .t2
    toplevel .t2
    destroy .t3
    toplevel .t3
    wm transient .t2 .t3
    update
    destroy .t3
    update
    list [wm transient .t2] [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
} {{} {}}
test unixWm-37.5 {Tk_WmCmd procedure, "transient" option, create toplevel wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0
    set result [list [testwrapper .t2]]







|










|







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
    lappend result [wm transient .t2] [expr [testwrapper .t] - $transient]
    wm transient .t2 {}
    lappend result [wm transient .t2] \
	    [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
    destroy .t2
    set result
} {{} {} .t 0 {} {}}
test unixWm-37.4 {TkWmDeadWindow, destroy on master should clear transient} {unix testwrapper} {
    destroy .t2
    toplevel .t2
    destroy .t3
    toplevel .t3
    wm transient .t2 .t3
    update
    destroy .t3
    update
    list [wm transient .t2] [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
} {{} {}}
test unixWm-37.5 {Tk_WmCmd procedure, "transient" option, create master wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0
    set result [list [testwrapper .t2]]
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381

1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
    pack .t.l -fill both -expand 1
    update
    wm geometry .t
} {30x10+0+0}
test unixWm-40.2 {Tk_SetGrid procedure, turning on grid when dimensions already set} unix {
    destroy .t
    toplevel .t
    wm geometry .t 200x100+0+$Y0
    listbox .t.l -height 20 -width 20
    pack .t.l -fill both -expand 1
    update
    .t.l configure -setgrid 1
    update
    wm geometry .t
} "20x20+0+$Y0"

test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
    destroy .t
    toplevel .t -width 400 -height 150
    tkwait visibility .t
    wm geometry .t +0+0
    update idletasks

    set result {}
    lappend result [winfo width .t] [winfo height .t]
    .t configure -width 200 -height 300
    update idletasks
    lappend result [winfo width .t] [winfo height .t]
} {400 150 200 300}
test unixWm-41.2 {ConfigureEvent procedure, menubars} {nonPortable testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0
    update







|






|




<

<
>



|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351

1352

1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
    pack .t.l -fill both -expand 1
    update
    wm geometry .t
} {30x10+0+0}
test unixWm-40.2 {Tk_SetGrid procedure, turning on grid when dimensions already set} unix {
    destroy .t
    toplevel .t
    wm geometry .t 200x100+0+0
    listbox .t.l -height 20 -width 20
    pack .t.l -fill both -expand 1
    update
    .t.l configure -setgrid 1
    update
    wm geometry .t
} {20x20+0+0}

test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
    destroy .t
    toplevel .t -width 400 -height 150

    wm geometry .t +0+0

    tkwait visibility .t
    set result {}
    lappend result [winfo width .t] [winfo height .t]
    .t configure -width 200 -height 300
    sleep 500
    lappend result [winfo width .t] [winfo height .t]
} {400 150 200 300}
test unixWm-41.2 {ConfigureEvent procedure, menubars} {nonPortable testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0
    update
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
    update
    set result
} {configured: 130 200}

# No tests for ReparentEvent or ComputeReparentGeometry; I can't figure
# out how to exercise these procedures reliably.

test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu} {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    set result {}
    bind .t <Map> {set x "mapped"}
    bind .t <Unmap> {set x "unmapped"}
    set x {no event}
    wm iconify .t
    update idletasks
    lappend result $x [winfo ismapped .t]
    set x {no event}
    wm deiconify .t
    update idletasks
    lappend result $x [winfo ismapped .t]
} {unmapped 0 mapped 1}

test unixWm-43.1 {TopLevelReqProc procedure, embedded in same process} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0







|









<



<







1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423

1424
1425
1426
1427
1428
1429
1430
    update
    set result
} {configured: 130 200}

# No tests for ReparentEvent or ComputeReparentGeometry; I can't figure
# out how to exercise these procedures reliably.

test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    set result {}
    bind .t <Map> {set x "mapped"}
    bind .t <Unmap> {set x "unmapped"}
    set x {no event}
    wm iconify .t

    lappend result $x [winfo ismapped .t]
    set x {no event}
    wm deiconify .t

    lappend result $x [winfo ismapped .t]
} {unmapped 0 mapped 1}

test unixWm-43.1 {TopLevelReqProc procedure, embedded in same process} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0
1536
1537
1538
1539
1540
1541
1542

1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
    wm geometry .t +30+40
    wm overrideredirect .t 1
    tkwait visibility .t
    wm geometry .t 5x8
    update
    list [winfo width .t] [winfo height .t]
} {1 72}

destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.6 {UpdateGeometryInfo procedure, negative height} unix {
    wm grid .t 18 7 10 12
    wm geometry .t +30+40
    wm overrideredirect .t 1
    tkwait visibility .t
    wm geometry .t 20x1
    update
    list [winfo width .t] [winfo height .t]
} {100 1}

destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1
    update
    wm geometry .t +5-10
    update
    list [winfo x .t] [winfo y .t]
} [list 5 [expr [winfo screenheight .t] - 70]]

destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1
    update
    wm geometry .t -30+$Y2
    update
    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] $Y2]
destroy .t

test unixWm-44.9 {UpdateGeometryInfo procedure, updating fixed dimensions} {unix testwrapper} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm resizable .t 0 0
    wm geometry .t +0+0







>
|
|
<








>


|
|

<
|
<


>


|
|

<
|
<

|







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529

1530

1531
1532
1533
1534
1535
1536
1537
1538

1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
    wm geometry .t +30+40
    wm overrideredirect .t 1
    tkwait visibility .t
    wm geometry .t 5x8
    update
    list [winfo width .t] [winfo height .t]
} {1 72}
test unixWm-44.6 {UpdateGeometryInfo procedure, negative height} unix {
    destroy .t
    toplevel .t -width 80 -height 60

    wm grid .t 18 7 10 12
    wm geometry .t +30+40
    wm overrideredirect .t 1
    tkwait visibility .t
    wm geometry .t 20x1
    update
    list [winfo width .t] [winfo height .t]
} {100 1}

destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} unix {
    wm geometry .t +5-10
    wm overrideredirect .t 1

    tkwait visibility .t

    list [winfo x .t] [winfo y .t]
} [list 5 [expr [winfo screenheight .t] - 70]]

destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} unix {
    wm geometry .t -30+2
    wm overrideredirect .t 1

    tkwait visibility .t

    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] 2]
destroy .t

test unixWm-44.9 {UpdateGeometryInfo procedure, updating fixed dimensions} {unix testwrapper} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm resizable .t 0 0
    wm geometry .t +0+0
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {40 30 320 210 10 5}
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm minsize .t 30 40
    wm maxsize .t 200 500
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]







|







1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {40 30 320 210 10 5}
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper failsOnUbuntu failsOnQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm minsize .t 30 40
    wm maxsize .t 200 500
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [winfo height .t] \
	    [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {60 40 53 320 233 10 5}
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    frame .t.menu -height 23 -width 50
    testmenubar window .t .t.menu
    wm resizable .t 0 0
    wm geometry .t +0+0
    tkwait visibility .t







|







1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [winfo height .t] \
	    [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {60 40 53 320 233 10 5}
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper failsOnUbuntu failsOnQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    frame .t.menu -height 23 -width 50
    testmenubar window .t .t.menu
    wm resizable .t 0 0
    wm geometry .t +0+0
    tkwait visibility .t
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
    list [catch {wm geometry .t +20-} msg] $msg
} {1 {bad geometry specifier "+20-"}}
test unixWm-48.10 {ParseGeometry procedure} unix {
    list [catch {wm geometry .t +20+10z} msg] $msg
} {1 {bad geometry specifier "+20+10z"}}
test unixWm-48.11 {ParseGeometry procedure} unix {
    catch {wm geometry .t +-10+20}
} 0
test unixWm-48.12 {ParseGeometry procedure} unix {
    catch {wm geometry .t +30+-10}
} 0
test unixWm-48.13 {ParseGeometry procedure, resize causes window to move} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0
    update
    wm geom .t -0-0
    update







|


|







1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
    list [catch {wm geometry .t +20-} msg] $msg
} {1 {bad geometry specifier "+20-"}}
test unixWm-48.10 {ParseGeometry procedure} unix {
    list [catch {wm geometry .t +20+10z} msg] $msg
} {1 {bad geometry specifier "+20+10z"}}
test unixWm-48.11 {ParseGeometry procedure} unix {
    catch {wm geometry .t +-10+20}
} {0}
test unixWm-48.12 {ParseGeometry procedure} unix {
    catch {wm geometry .t +30+-10}
} {0}
test unixWm-48.13 {ParseGeometry procedure, resize causes window to move} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0
    update
    wm geom .t -0-0
    update
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861

1862
1863
1864
1865
1866
1867

1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
    testmenubar window .t .t.m
    update
    list [expr [winfo rootx .t.m.f] - $x] [expr [winfo rooty .t.m.f] - $y] \
	    [expr [winfo rootx .t.f] - $x] [expr [winfo rooty .t.f] - $y]
} {52 7 12 62}

deleteWindows
wm withdraw .
if {[tk windowingsystem] == "aqua"} {
    # Modern mac windows have no border.
    set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t}
} else {
    # Windows are assumed to have a border (invisible in Gnome 3).
    set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t}
}
test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} {unix failsOnUbuntu failsOnXQuarz} {
    update
    toplevel .t -width 300 -height 400 -bg green
    wm geom .t +100+100
    tkwait visibility .t
    toplevel .t2 -width 100 -height 200 -bg red
    wm geom .t2 +200+200
    tkwait visibility .t2
    raise .t2
    update
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    list [winfo containing [expr $x - 30]  [expr $y + 250]] \
	 [winfo containing [expr $x - 1]   [expr $y + 250]] \
	 [winfo containing $x              [expr $y + 250]] \
	 [winfo containing [expr $x + 99]  [expr $y + 250]] \
	 [winfo containing [expr $x + 100] [expr $y + 250]] \
	 [winfo containing [expr $x + 150] [expr $y + 90]] \
	 [winfo containing [expr $x + 199] [expr $y + 250]] \
	 [winfo containing [expr $x + 200] [expr $y + 250]] \
	 [winfo containing [expr $x + 220] [expr $y + 250]] \
} $result_50_1
test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix {
    deleteWindows
    toplevel .t -width 400 -height 300 -bg yellow
    wm geom .t +100+100
    tkwait visibility .t
    toplevel .t2 -width 200 -height 100 -bg blue
    wm overrideredirect .t2 1
    wm geom .t2 +200+200
    tkwait visibility .t2
    raise .t2
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    set y2 [winfo rooty .t2]
    list [winfo containing [expr $x +200] [expr $y - 30]] \
	 [winfo containing [expr $x +200] [expr $y - 1]] \
	 [winfo containing [expr $x +200] $y] \
	 [winfo containing [expr $x +200] [expr $y2 - 1]] \
	 [winfo containing [expr $x +200] $y2] \
	 [winfo containing [expr $x +200] [expr $y2 + 99]] \
	 [winfo containing [expr $x +200] [expr $y2 + 100]] \
	 [winfo containing [expr $x +200] [expr $y + 450]]
} {{} {} .t .t .t2 .t2 .t {}}
test unixWm-50.3 {
	Tk_CoordsToWindow procedure, finding a toplevel with embedding
} tempNotWin {
    deleteWindows
    catch {interp delete child}

    toplevel .t -width 300 -height 400 -bg blue
    wm geom .t +100+100
    frame .t.f -container 1 -bg red
    place .t.f -x 150 -y 50
    tkwait visibility .t.f
    update
    interp create child
    load {} Tk child
    child alias frameid winfo id .t.f
    child eval {
	wm withdraw .
        toplevel .x -width 100 -height 80 -use [frameid] -bg yellow
        tkwait visibility .x
        update

        set x [winfo rootx .x]
        set y [winfo rooty .x]
    }
    set result [list [child eval {winfo containing [expr $x - 1]  [expr $y + 50]}] \
	       	     [child eval {winfo containing $x [expr $y + 50]}]]
    interp delete child

    set x [winfo rootx .t]
    set y [winfo rooty .t]
    lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
	[winfo containing [expr $x + 200] [expr $y +50]]

    set result
} {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
    destroy .t

    catch {interp delete child}
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +100+100
    tkwait visibility .t
    update
    interp create child
    load {} Tk child
    child eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}
    set result [list [winfo containing 200 200] \
	    [child eval {winfo containing 200 200}]]
    interp delete child
    set result
} {{} .}
test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenubar} {
    deleteWindows
    toplevel .t -width 300 -height 400 -bd 2 -relief raised
    frame .t.f -width 150 -height 120 -bg green
    place .t.f -x 10 -y 150
    wm geom .t +0+50
    frame .t.menu -width 100 -height 30 -bd 2 -relief raised
    frame .t.menu.f -width 40 -height 20 -bg purple
    place .t.menu.f -x 30 -y 10
    testmenubar window .t .t.menu
    tkwait visibility .t.menu
    update
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    list [winfo containing $x             [expr $y - 31]] \
	 [winfo containing $x             [expr $y - 30]] \
	 [winfo containing [expr $x + 50] [expr $y - 19]] \
	 [winfo containing [expr $x + 50] [expr $y - 18]] \
	 [winfo containing [expr $x + 50] $y] \
	 [winfo containing [expr $x + 11] [expr $y + 152]] \
	 [winfo containing [expr $x + 12] [expr $y + 152]]
} {{} .t.menu .t.menu .t.menu.f .t .t .t.f}
test unixWm-50.6 {Tk_CoordsToWindow procedure, embedding within one app.} unix {
    deleteWindows
    toplevel .t -width 300 -height 400 -bg orange
    wm geom .t +0+50
    frame .t.f -container 1
    place .t.f -x 150 -y 50







|
<
<
<
<
<
<
<
|
|

|

|
|


<


|
|
|
|
|
<
|
|
|
|


|
|

|

|





|
|
|
|
|
|
|
|



|

<
<

|
|


|
<
|
<
|

|
|
<
>
|
|
<
|
|
<
>



|
>
|
|


<
|

|

<
|
|
|
|
|
|
















|
|
|
|
|
|
|







1751
1752
1753
1754
1755
1756
1757
1758







1759
1760
1761
1762
1763
1764
1765
1766
1767

1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804


1805
1806
1807
1808
1809
1810

1811

1812
1813
1814
1815

1816
1817
1818

1819
1820

1821
1822
1823
1824
1825
1826
1827
1828
1829
1830

1831
1832
1833
1834

1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
    testmenubar window .t .t.m
    update
    list [expr [winfo rootx .t.m.f] - $x] [expr [winfo rooty .t.m.f] - $y] \
	    [expr [winfo rootx .t.f] - $x] [expr [winfo rooty .t.f] - $y]
} {52 7 12 62}

deleteWindows
wm iconify .







test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords} {unix failsOnUbuntu failsOnQuarz} {
    deleteWindows
    toplevel .t -width 300 -height 400 -bg green
    wm geom .t +40+0
    tkwait visibility .t
    toplevel .t2 -width 100 -height 80 -bg red
    wm geom .t2 +140+200
    tkwait visibility .t2
    raise .t2

    set x [winfo rootx .t]
    set y [winfo rooty .t]
    list [winfo containing [expr $x - 30] [expr $y + 250]] \
	    [winfo containing [expr $x - 1] [expr $y + 250]] \
	    [winfo containing $x [expr $y + 250]] \
	    [winfo containing [expr $x + 99] [expr $y + 250]] \
	    [winfo containing [expr $x + 100] [expr $y + 250]] \

	    [winfo containing [expr $x + 199] [expr $y + 250]] \
	    [winfo containing [expr $x + 200] [expr $y + 250]] \
	    [winfo containing [expr $x + 220] [expr $y + 250]]
} {{} {} .t {} .t2 .t2 {} .t}
test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix {
    deleteWindows
    toplevel .t -width 300 -height 400 -bg yellow
    wm geom .t +0+50
    tkwait visibility .t
    toplevel .t2 -width 100 -height 80 -bg blue
    wm overrideredirect .t2 1
    wm geom .t2 +100+200
    tkwait visibility .t2
    raise .t2
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    set y2 [winfo rooty .t2]
    list [winfo containing [expr $x +150] 10] \
	    [winfo containing [expr $x +150] [expr $y - 1]] \
	    [winfo containing [expr $x +150] $y] \
	    [winfo containing [expr $x +150] [expr $y2 - 1]] \
	    [winfo containing [expr $x +150] $y2] \
	    [winfo containing [expr $x +150] [expr $y2 + 79]] \
	    [winfo containing [expr $x +150] [expr $y2 + 80]] \
	    [winfo containing [expr $x +150] [expr $y + 450]]
} {{} {} .t .t .t2 .t2 .t {}}
test unixWm-50.3 {
	Tk_CoordsToWindow procedure, finding a toplevel with embedding
} -constraints tempNotWin -setup {
    deleteWindows


    toplevel .t -width 300 -height 400 -bg blue
    wm geom .t +0+50
    frame .t.f -container 1
    place .t.f -x 150 -y 50
    tkwait visibility .t.f
    setupbg

} -body {

    dobg "
	wm withdraw .
	toplevel .x -width 100 -height 80 -use [winfo id .t.f] -bg yellow
	tkwait visibility .x"

    set result [dobg {
	set x [winfo rootx .x]
	set y [winfo rooty .x]

	list [winfo containing [expr $x - 1] [expr $y + 50]] \
		[winfo containing $x [expr $y +50]]

    }]
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
		[winfo containing [expr $x + 200] [expr $y +50]]
} -cleanup {
    cleanupbg
} -result {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
    destroy .t

    catch {interp delete slave}
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t

    interp create slave
    load {} Tk slave
    slave eval {wm geometry . 200x200+0+0; tkwait visibility .}
    set result [list [winfo containing 100 100] \
	    [slave eval {winfo containing 100 100}]]
    interp delete slave
    set result
} {{} .}
test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenubar} {
    deleteWindows
    toplevel .t -width 300 -height 400 -bd 2 -relief raised
    frame .t.f -width 150 -height 120 -bg green
    place .t.f -x 10 -y 150
    wm geom .t +0+50
    frame .t.menu -width 100 -height 30 -bd 2 -relief raised
    frame .t.menu.f -width 40 -height 20 -bg purple
    place .t.menu.f -x 30 -y 10
    testmenubar window .t .t.menu
    tkwait visibility .t.menu
    update
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    list [winfo containing $x [expr $y - 31]] \
		[winfo containing $x [expr $y - 30]] \
		[winfo containing [expr $x + 50] [expr $y - 19]] \
		[winfo containing [expr $x + 50] [expr $y - 18]] \
		[winfo containing [expr $x + 50] $y] \
		[winfo containing [expr $x + 11] [expr $y + 152]] \
		[winfo containing [expr $x + 12] [expr $y + 152]]
} {{} .t.menu .t.menu .t.menu.f .t .t .t.f}
test unixWm-50.6 {Tk_CoordsToWindow procedure, embedding within one app.} unix {
    deleteWindows
    toplevel .t -width 300 -height 400 -bg orange
    wm geom .t +0+50
    frame .t.f -container 1
    place .t.f -x 150 -y 50
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965

1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
	    [winfo containing $x [expr $y + 250]] \
	    [winfo containing $x [expr $y + 350]] \
	    [winfo containing $x [expr $y + 450]]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.8 {Tk_CoordsToWindow procedure, more basics} unix {
    destroy .t
    toplevel .t -width 400 -height 300 -bg green
    wm geom .t +0+30
    frame .t.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f -x 100 -y 100
    frame .t.f.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f.f -x 100 -y 0
    update
    set x [winfo rootx .t]
    set y [expr [winfo rooty .t] + 150]
    list [winfo containing [expr $x + 50] $y] \
	    [winfo containing [expr $x + 150] $y] \
	    [winfo containing [expr $x + 250] $y] \
	    [winfo containing [expr $x + 350] $y] \
	    [winfo containing [expr $x + 450] $y]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .t2

    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    tkwait visibility .t2
    set result [list [winfo containing 100 100]]
    wm iconify .t2
    update idletasks
    lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    frame .t.f -width 150 -height 150 -bd 2 -relief raised
    place .t.f -x 25 -y 25
    tkwait visibility .t.f
    update idletasks
    set result [list [winfo containing 100 100]]
    place forget .t.f
    update idletasks
    lappend result [winfo containing 100 100]
} {.t.f .t}
deleteWindows
wm deiconify .

# No tests for UpdateVRootGeometry, Tk_GetVRootGeometry,
# Tk_MoveToplevelWindow, UpdateWmProtocols, or TkWmProtocolEventProc.







|





|







|


>








<









<


|







1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
	    [winfo containing $x [expr $y + 250]] \
	    [winfo containing $x [expr $y + 350]] \
	    [winfo containing $x [expr $y + 450]]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.8 {Tk_CoordsToWindow procedure, more basics} unix {
    destroy .t
    toplevel .t -width 400 -height 300 -bg green
    wm geom .t +0+0
    frame .t.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f -x 100 -y 100
    frame .t.f.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f.f -x 100 -y 0
    update
    set x [winfo rooty .t]
    set y [expr [winfo rooty .t] + 150]
    list [winfo containing [expr $x + 50] $y] \
	    [winfo containing [expr $x + 150] $y] \
	    [winfo containing [expr $x + 250] $y] \
	    [winfo containing [expr $x + 350] $y] \
	    [winfo containing [expr $x + 450] $y]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu failsOnQuarz} {
    destroy .t
    destroy .t2
    sleep 500		;# Give window manager time to catch up.
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    tkwait visibility .t2
    set result [list [winfo containing 100 100]]
    wm iconify .t2

    lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    frame .t.f -width 150 -height 150 -bd 2 -relief raised
    place .t.f -x 25 -y 25
    tkwait visibility .t.f

    set result [list [winfo containing 100 100]]
    place forget .t.f
    update
    lappend result [winfo containing 100 100]
} {.t.f .t}
deleteWindows
wm deiconify .

# No tests for UpdateVRootGeometry, Tk_GetVRootGeometry,
# Tk_MoveToplevelWindow, UpdateWmProtocols, or TkWmProtocolEventProc.
2010
2011
2012
2013
2014
2015
2016

2017
2018
2019
2020
2021
2022
2023
2024
2025
2026

2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062

2063
2064
2065

2066
2067
2068
2069
2070
2071
2072
    update
    raise .raise3
    raise .raise2
    raise .raise1 .raise3
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise2

    list $result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
} {.raise2 .raise1}
test unixWm-51.4 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    raise .raise2
    raise .raise1
    lower .raise3 .raise1
    set result [winfo containing 100 100]
    destroy .raise1

    lappend result [winfo containing 100 100]
} {.raise1 .raise3}
test unixWm-51.5 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    update
    raise .raise2
    raise .raise1
    raise .raise3
    frame .raise1.f1
    frame .raise1.f1.f2
    lower .raise3 .raise1.f1.f2
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise1

    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
deleteWindows
test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapped} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    winfo containing 100 100
} {.t}
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} {unix failsOnXQuarz} {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green
	wm geometry $w +0+0
    }
    raise .t .t2

    update
    set result [list [winfo containing 100 100]]
    lower .t3

    lappend result [winfo containing 100 100]
} {.t3 .t}
test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm overrideredirect .t 1
    wm geometry .t +0+0







>










>














>














|


<




>



>







1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
    update
    raise .raise3
    raise .raise2
    raise .raise1 .raise3
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise2
    sleep 500
    list $result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
} {.raise2 .raise1}
test unixWm-51.4 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    raise .raise2
    raise .raise1
    lower .raise3 .raise1
    set result [winfo containing 100 100]
    destroy .raise1
    sleep 500
    lappend result [winfo containing 100 100]
} {.raise1 .raise3}
test unixWm-51.5 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    update
    raise .raise2
    raise .raise1
    raise .raise3
    frame .raise1.f1
    frame .raise1.f1.f2
    lower .raise3 .raise1.f1.f2
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise1
    sleep 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
deleteWindows
test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapped} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    winfo containing 100 100
} {.t}
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} unix {
    foreach w {.t .t2 .t3} {
	destroy $w

	toplevel $w -width 200 -height 200 -bg green
	wm geometry $w +0+0
    }
    raise .t .t2
    sleep 2000
    update
    set result [list [winfo containing 100 100]]
    lower .t3
    sleep 2000
    lappend result [winfo containing 100 100]
} {.t3 .t}
test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm overrideredirect .t 1
    wm geometry .t +0+0
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    raise .t
    lappend result [winfo containing $x $y]
    raise .t2
    lappend result [winfo containing $x $y]
} {.t2 .t .t2}
# The mac won't put an overrideredirect window above the root,
if {[tk windowingsystem] == "aqua"} {
    wm withdraw .
}
test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green
	wm overrideredirect $w 1
	wm geometry $w +0+0
	tkwait visibility $w
	update
    }
    lower .t3 .t2
    update

    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    lower .t2
    lappend result [winfo containing $x $y]
} {.t2 .t3}
if {[tk windowingsystem] == "aqua"} {
    wm deiconify .
}
test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
    makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}
} 1
test unixWm-51.11 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {







<
<
<
<



<




<















<
<
<







2042
2043
2044
2045
2046
2047
2048




2049
2050
2051

2052
2053
2054
2055

2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070



2071
2072
2073
2074
2075
2076
2077
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    raise .t
    lappend result [winfo containing $x $y]
    raise .t2
    lappend result [winfo containing $x $y]
} {.t2 .t .t2}




test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix {
    foreach w {.t .t2 .t3} {
	destroy $w

	toplevel $w -width 200 -height 200 -bg green
	wm overrideredirect $w 1
	wm geometry $w +0+0
	tkwait visibility $w

    }
    lower .t3 .t2
    update

    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    lower .t2
    lappend result [winfo containing $x $y]
} {.t2 .t3}



test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
    makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}
} 1
test unixWm-51.11 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
    .m add command -label Second
    .m add command -label Third
    .m post 30 30
    update
    set result [wm overrideredirect .m]
    destroy .m
    set result
} 1

# No tests for TkGetPointerCoords, CreateWrapper, or GetMaxSize.

test unixWm-55.1 {TkUnixSetMenubar procedure} {unix testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0







|







2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
    .m add command -label Second
    .m add command -label Third
    .m post 30 30
    update
    set result [wm overrideredirect .m]
    destroy .m
    set result
} {1}

# No tests for TkGetPointerCoords, CreateWrapper, or GetMaxSize.

test unixWm-55.1 {TkUnixSetMenubar procedure} {unix testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517

#
# wm attributes tests:
#
# NOTE: since [wm attributes] is not guaranteed to have any effect,
# the only thing we can really test here is the syntax.
#
if {[tk windowingsystem] == "aqua"} {
    set result_60_1 {-alpha 1.0 -fullscreen 0 -modified 0 -notify 0\
			 -titlepath {} -topmost 0 -transparent 0\
			 -type unsupported}
} else {
    set result_60_1 {-alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}}
}
test unixWm-60.1 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t
} -result $result_60_1

test unixWm-60.2 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -topmost
} -result 0








<
<
<
<
<
<
<




|







2439
2440
2441
2442
2443
2444
2445







2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457

#
# wm attributes tests:
#
# NOTE: since [wm attributes] is not guaranteed to have any effect,
# the only thing we can really test here is the syntax.
#







test unixWm-60.1 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t
} -result [list -alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}]

test unixWm-60.2 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -topmost
} -result 0

2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
    wm attributes .t -topmost 1
}

test unixWm-60.5 {wm attributes - bad attribute} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -foo
} -returnCodes 1 -match glob -result {bad attribute "-foo":*}

test unixWm-61.1 {Tk_WmCmd procedure, "iconphoto" option} unix {
    list [catch {wm iconph .} msg] $msg
} {1 {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}}
test unixWm-61.2 {Tk_WmCmd procedure, "iconphoto" option} unix {
    destroy .t
    toplevel .t







|







2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
    wm attributes .t -topmost 1
}

test unixWm-60.5 {wm attributes - bad attribute} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -foo
} -returnCodes error -match glob -result {bad attribute "-foo":*}

test unixWm-61.1 {Tk_WmCmd procedure, "iconphoto" option} unix {
    list [catch {wm iconph .} msg] $msg
} {1 {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}}
test unixWm-61.2 {Tk_WmCmd procedure, "iconphoto" option} unix {
    destroy .t
    toplevel .t

Changes to tests/util.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# This file is a Tcl script to test out the procedures in the file
# tkUtil.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

listbox .l -width 20 -height 5 -relief sunken -bd 2
pack .l
.l insert 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
update
test util-1.1 {Tk_GetScrollInfo procedure} -body {
    .l yview moveto a b
} -returnCodes error -result {wrong # args: should be ".l yview moveto fraction"}
test util-1.2 {Tk_GetScrollInfo procedure} -body {
    .l yview moveto xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
test util-1.3 {Tk_GetScrollInfo procedure} -body {
    .l yview 0
    .l yview moveto .5
    .l yview
} -result {0.5 0.75}
test util-1.4 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll a
} -returnCodes error -result {wrong # args: should be ".l yview scroll number pages|units"}
test util-1.5 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll a b c
} -returnCodes error -result {wrong # args: should be ".l yview scroll number pages|units"}
test util-1.6 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll xyz units
} -returnCodes error -result {expected floating-point number but got "xyz"}
test util-1.7 {Tk_GetScrollInfo procedure} -body {
    .l yview 0
    .l yview scroll 2 pages
    .l nearest 0
} -result 6
test util-1.8 {Tk_GetScrollInfo procedure} -body {
    .l yview 15
    .l yview scroll -2 pages
    .l nearest 0
} -result 9
test util-1.9 {Tk_GetScrollInfo procedure} -body {
    .l yview 0
    .l yview scroll 2 units
    .l nearest 0
} -result 2
test util-1.10 {Tk_GetScrollInfo procedure} -body {
    .l yview 15
    .l yview scroll -2 units
    .l nearest 0
} -result 13
test util-1.11 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll 3 zips
} -returnCodes error -result {bad argument "zips": must be pages or units}
test util-1.12 {Tk_GetScrollInfo procedure} -body {
    .l yview dropdead 3 times
} -returnCodes error -result {unknown option "dropdead": must be moveto or scroll}

# cleanup
cleanupTests
return




|
|
|





<





|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|



|
|



|
|



|
|



|
|
|
|
|
|
|




<
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

# This file is a Tcl script to test out the procedures in the file
# tkUtil.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands


listbox .l -width 20 -height 5 -relief sunken -bd 2
pack .l
.l insert 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
update
test util-1.1 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview moveto a b} msg] $msg
} {1 {wrong # args: should be ".l yview moveto fraction"}}
test util-1.2 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview moveto xyz} msg] $msg
} {1 {expected floating-point number but got "xyz"}}
test util-1.3 {Tk_GetScrollInfo procedure} {
    .l yview 0
    .l yview moveto .5
    .l yview
} {0.5 0.75}
test util-1.4 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview scroll a} msg] $msg
} {1 {wrong # args: should be ".l yview scroll number units|pages"}}
test util-1.5 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".l yview scroll number units|pages"}}
test util-1.6 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview scroll xyz units} msg] $msg
} {1 {expected integer but got "xyz"}}
test util-1.7 {Tk_GetScrollInfo procedure} {
    .l yview 0
    .l yview scroll 2 pages
    .l nearest 0
} {6}
test util-1.8 {Tk_GetScrollInfo procedure} {
    .l yview 15
    .l yview scroll -2 pages
    .l nearest 0
} {9}
test util-1.9 {Tk_GetScrollInfo procedure} {
    .l yview 0
    .l yview scroll 2 units
    .l nearest 0
} {2}
test util-1.10 {Tk_GetScrollInfo procedure} {
    .l yview 15
    .l yview scroll -2 units
    .l nearest 0
} {13}
test util-1.11 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview scroll 3 zips} msg] $msg
} {1 {bad argument "zips": must be units or pages}}
test util-1.12 {Tk_GetScrollInfo procedure} {
    list [catch {.l yview dropdead 3 times} msg] $msg
} {1 {unknown option "dropdead": must be moveto or scroll}}

# cleanup
cleanupTests
return

Changes to tests/visual.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401


402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451


452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523



524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# This file is a Tcl script to test the visual- and colormap-handling
# procedures in the file tkVisual.c.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

update

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:
# w -        Name of toplevel window to create.

proc eatColors {w} {
    catch {destroy $w}
    toplevel $w
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
        for {set x 0} {$x < 40} {incr x} {
            set color [format #%02x%02x%02x [expr {$x*6}] [expr {$y*30}] 0]
            $w.c create rectangle [expr {10*$x}] [expr {20*$y}] \
                [expr {10*$x + 10}] [expr {20*$y + 20}] -outline {} \
                -fill $color
        }
    }
    update
}

# colorsFree --
#
# Returns 1 if there appear to be free colormap entries in a window,
# 0 otherwise.
#
# Arguments:
# w -            Name of window in which to check.
# red, green, blue -    Intensities to use in a trial color allocation
#            to see if there are colormap entries free.

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr {([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green)
        && ([lindex $vals 2]/256 == $blue)}
}

# If more than one visual type is available for the screen, pick one
# that is *not* the default.

set default "[winfo visual .] [winfo depth .]"
set avail [winfo visualsavailable .]
set other {}
if {[llength $avail] > 1} {
    foreach visual $avail {
        if {$visual != $default} {
            set other $visual
            break
        }
    }
}
testConstraint haveOtherVisual [expr {$other ne ""}]
testConstraint havePseudocolorVisual [string match *pseudocolor* $avail]
testConstraint haveMultipleVisuals [expr {[llength $avail] > 1}]

# ----------------------------------------------------------------------

test visual-1.1 {Tk_GetVisual, copying from other window} -body {
    toplevel .t -visual .foo.bar
} -returnCodes error -result {bad window path name ".foo.bar"}
test visual-1.2 {Tk_GetVisual, copying from other window} -constraints {
    haveOtherVisual nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual .t1
    wm geom .t2 +5+5
    concat "[winfo visual .t2] [winfo depth .t2]"
} -cleanup {
    deleteWindows
} -result $other
test visual-1.3 {Tk_GetVisual, copying from other window} -constraints {
    haveOtherVisual
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual .
    wm geom .t2 +5+5
    concat "[winfo visual .t2] [winfo depth .t2]"
} -cleanup {
    deleteWindows
} -result $default
# Make sure reference count is incremented when copying visual (the
# following test will cause the colormap to be freed prematurely if
# the reference count isn't incremented).
test visual-1.4 {Tk_GetVisual, colormap reference count} -constraints {
    haveOtherVisual
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    set result [toplevel .t2 -gorp 80 -visual .t1]
    update
    return $result
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-gorp"}
test visual-1.5 {Tk_GetVisual, default colormap} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual default
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result $default


test visual-2.1 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.2 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.3 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.4 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.5 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.6 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.7 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.8 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 24}
test visual-2.9 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.10 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.11 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.12 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.13 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.14 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.15 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.16 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {directcolor 24}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {directcolor 24}
test visual-2.17 {Tk_GetVisual, different visual types} -constraints {
    nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual {truecolor 32}
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result {truecolor 32}


test visual-3.1 {Tk_GetVisual, parsing visual string} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 \
        -visual "[winfo visual .][winfo depth .]"
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"
} -cleanup {
    deleteWindows
} -result $default
test visual-3.2 {Tk_GetVisual, parsing visual string} -setup {
    deleteWindows
} -body {

    toplevel .t1 -width 250 -height 100 -visual goop20
    wm geometry .t1 +0+0
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown or ambiguous visual name "goop20": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}
test visual-3.3 {Tk_GetVisual, parsing visual string} -setup {
    deleteWindows
} -body {

    toplevel .t1 -width 250 -height 100 -visual d
    wm geometry .t1 +0+0
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown or ambiguous visual name "d": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}
test visual-3.4 {Tk_GetVisual, parsing visual string} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual static
    wm geometry .t1 +0+0
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown or ambiguous visual name "static": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}
test visual-3.5 {Tk_GetVisual, parsing visual string} -setup {
    deleteWindows
} -body {

    toplevel .t1 -width 250 -height 100 -visual "pseudocolor 48x"
    wm geometry .t1 +0+0
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "48x"}


test visual-4.1 {Tk_GetVisual, numerical visual id}  -constraints {
    haveOtherVisual nonPortable
} -setup {
    deleteWindows

    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual [winfo visual .]
    wm geom .t2 +5+5
    toplevel .t3 -width 150 -height 250 -visual [winfo visual .t1]
    wm geom .t3 +10+10
} -body {
    set v1 [list [winfo visualid .t2] [winfo visualid .t3]]
    set v2 [list [winfo visualid .] [winfo visualid .t1]]
    expr {$v1 eq $v2 ? "OK" : "[list $v1] ne [list $v2]"}
} -cleanup {
    deleteWindows
} -result OK


test visual-4.2 {Tk_GetVisual, numerical visual id} -setup {
    deleteWindows
} -body {
    toplevel .t1 -visual 12xyz
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad X identifier for visual: "12xyz"}
test visual-4.3 {Tk_GetVisual, numerical visual id} -setup {
    deleteWindows
} -body {
    toplevel .t1 -visual 1291673
} -cleanup {
    deleteWindows
} -returnCodes error -result {couldn't find an appropriate visual}


test visual-5.1 {Tk_GetVisual, no matching visual} -constraints {
    !havePseudocolorVisual
} -setup {
    deleteWindows
} -body {

    toplevel .t1 -width 250 -height 100 -visual "pseudocolor 8"
    wm geometry .t1 +0+0
} -cleanup {
    deleteWindows
} -returnCodes error -result {couldn't find an appropriate visual}


test visual-6.1 {Tk_GetVisual, no matching visual} -constraints {
    havePseudocolorVisual haveMultipleVisuals nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 250 -height 100 -visual "best"
    wm geometry .t1 +0+0
    update
    winfo visual .t1
} -cleanup {
    deleteWindows
} -result {pseudocolor}


# These tests are non-portable due to variations in how many colors
# are already in use on the screen.
test visual-7.1 {Tk_GetColormap, "new"} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    deleteWindows
} -body {
    eatColors .t1


    toplevel .t2 -width 30 -height 20
    wm geom .t2 +0+0
    update
    colorsFree .t2
} -cleanup {
    deleteWindows
} -result 0
test visual-7.2 {Tk_GetColormap, "new"} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    deleteWindows
} -body {
    eatColors .t1
    toplevel .t2 -width 30 -height 20 -colormap new
    wm geom .t2 +0+0
    update
    colorsFree .t2
} -cleanup {
    deleteWindows
} -result 1
test visual-7.3 {Tk_GetColormap, copy from other window} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    deleteWindows
} -body {
    eatColors .t1
    toplevel .t3 -width 400 -height 50 -colormap new
    wm geom .t3 +0+0

    toplevel .t2 -width 30 -height 20 -colormap .t3
    wm geom .t2 +0+0
    update
    destroy .t3
    colorsFree .t2
} -cleanup {
    deleteWindows
} -result 1
test visual-7.4 {Tk_GetColormap, copy from other window} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    deleteWindows
} -body {
    eatColors .t1
    toplevel .t3 -width 400 -height 50 -colormap new
    wm geom .t3 +0+0

    toplevel .t2 -width 30 -height 20 -colormap .
    wm geom .t2 +0+0
    update
    destroy .t3
    colorsFree .t2
} -cleanup {
    deleteWindows
} -result 0
test visual-7.5 {Tk_GetColormap, copy from other window} -constraints {
    defaultPseudocolor8 nonPortable
} -setup {
    deleteWindows
} -body {

    toplevel .t1 -width 400 -height 50 -colormap .choke.lots
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad window path name ".choke.lots"}
test visual-7.6 {Tk_GetColormap, copy from other window} -constraints {
    defaultPseudocolor8 haveOtherVisual nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 300 -height 150 -visual $other
    wm geometry .t1 +0+0
    toplevel .t2 -width 400 -height 50 -colormap .t1
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't use colormap for .t1: incompatible visuals}





test visual-8.1 {Tk_FreeColormap procedure} -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 300 -height 180 -colormap new
    wm geometry .t1 +0+0
    foreach i {.t2 .t3 .t4} {
        toplevel $i -width 250 -height 150 -colormap .t1
        wm geometry $i +0+0
    }
    destroy .t1
    destroy .t3
    destroy .t4
    update
} -cleanup {
    deleteWindows
} -result {}
test visual-8.2 {Tk_FreeColormap procedure} -constraints haveOtherVisual -setup {
    deleteWindows
} -body {
    toplevel .t1 -width 300 -height 180 -visual $other
    wm geometry .t1 +0+0
    foreach i {.t2 .t3 .t4} {
        toplevel $i -width 250 -height 150 -visual $other
        wm geometry $i +0+0
    }
    destroy .t2
    destroy .t3
    destroy .t4
    update
} -cleanup {
    deleteWindows
} -result {}


deleteWindows
rename eatColors {}
rename colorsFree {}

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:




|
|
|



<
|









|








|
|
|
|
|
|










|
|
|



|
|










|
|
|
|






<
<
|
|
|
|
<
|
<
|





<
<
|
|
<
|
<
|





<
<
|



|
<
|
<
|


|

|
<
<
|
|
<
|




<
<
|

<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
|

|



<
<
|
|
<
|
>
|
|
|
<
|
|
<
|
>
|
|
|
<
|
|
|
|
|
|
|
<
|
|
<
|
>
|
|
|
<
|

<
|
<
|
|
>






|



<
<
|
>
>
|
<
|
|
<
<
|
|
<
|
|
<
<
|

<
|
<
|
<
<
>
|
|
|
<
|

<
|
<
|
<
<




<
<
|
<



|
|
<
<
<

>
>




|
<
<
|
<
|
<
<
<




|
<
<
|
<
|
<
<
<


>





|
<
<
|
<
|
<
<
<


>





|
<
<
|
<
|
<
<
>
|
|
<
|
|
<
|
<
|


|
<
<
|
>
>
>
|

|

<



|
|





|
<
<
|

<



|
|





<
<
<
|








<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73


74
75
76
77

78

79
80
81
82
83
84


85
86

87

88
89
90
91
92
93


94
95
96
97
98

99

100
101
102
103
104
105


106
107

108
109
110
111
112


113
114



115





116



117





118










119








































































120
121
122





123
124




























































































125
126
127

128
129
130
131
132
133


134
135

136
137
138
139
140

141
142

143
144
145
146
147

148
149
150
151
152
153
154

155
156

157
158
159
160
161

162
163

164

165
166
167
168
169
170
171
172
173
174
175
176
177


178
179
180
181

182
183


184
185

186
187


188
189

190

191


192
193
194
195

196
197

198

199


200
201
202
203


204

205
206
207
208
209



210
211
212
213
214
215
216
217


218

219



220
221
222
223
224


225

226



227
228
229
230
231
232
233
234
235


236

237



238
239
240
241
242
243
244
245
246


247

248


249
250
251

252
253

254

255
256
257
258


259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277


278
279

280
281
282
283
284
285
286
287
288
289



290
291
292
293
294
295
296
297
298




# This file is a Tcl script to test the visual- and colormap-handling
# procedures in the file tkVisual.c.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

update

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:
# w -		Name of toplevel window to create.

proc eatColors {w} {
    catch {destroy $w}
    toplevel $w
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 40} {incr x} {
	    set color [format #%02x%02x%02x [expr $x*6] [expr $y*30] 0]
	    $w.c create rectangle [expr 10*$x] [expr 20*$y] \
		    [expr 10*$x + 10] [expr 20*$y + 20] -outline {} \
		    -fill $color
	}
    }
    update
}

# colorsFree --
#
# Returns 1 if there appear to be free colormap entries in a window,
# 0 otherwise.
#
# Arguments:
# w -			Name of window in which to check.
# red, green, blue -	Intensities to use in a trial color allocation
#			to see if there are colormap entries free.

proc colorsFree {w {red 31} {green 245} {blue 192}} {
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \
	    && ([lindex $vals 2]/256 == $blue)
}

# If more than one visual type is available for the screen, pick one
# that is *not* the default.

set default "[winfo visual .] [winfo depth .]"
set avail [winfo visualsavailable .]
set other {}
if {[llength $avail] > 1} {
    foreach visual $avail {
	if {$visual != $default} {
	    set other $visual
	    break
	}
    }
}
testConstraint haveOtherVisual [expr {$other ne ""}]
testConstraint havePseudocolorVisual [string match *pseudocolor* $avail]
testConstraint haveMultipleVisuals [expr {[llength $avail] > 1}]



test visual-1.1 {Tk_GetVisual, copying from other window} {
    list [catch {toplevel .t -visual .foo.bar} msg] $msg
} {1 {bad window path name ".foo.bar"}}
test visual-1.2 {Tk_GetVisual, copying from other window} {haveOtherVisual nonPortable} {

    catch {destroy .t1}

    catch {destroy .t2}
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual .t1
    wm geom .t2 +5+5
    concat "[winfo visual .t2] [winfo depth .t2]"


} $other
test visual-1.3 {Tk_GetVisual, copying from other window} haveOtherVisual {

    catch {destroy .t1}

    catch {destroy .t2}
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual .
    wm geom .t2 +5+5
    concat "[winfo visual .t2] [winfo depth .t2]"


} $default
# Make sure reference count is incremented when copying visual (the
# following test will cause the colormap to be freed prematurely if
# the reference count isn't incremented).
test visual-1.4 {Tk_GetVisual, colormap reference count} haveOtherVisual {

    catch {destroy .t1}

    catch {destroy .t2}
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    set result [list [catch {toplevel .t2 -gorp 80 -visual .t1} msg] $msg]
    update
    set result


} {1 {unknown option "-gorp"}}
test visual-1.5 {Tk_GetVisual, default colormap} {

    catch {destroy .t1}
    toplevel .t1 -width 250 -height 100 -visual default
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"


} $default




set i 1





foreach visual $avail {



    test visual-2.$i {Tk_GetVisual, different visual types} {nonPortable} {





	catch {destroy .t1}










	toplevel .t1 -width 250 -height 100 -visual $visual








































































	wm geometry .t1 +0+0
	update
	concat "[winfo visual .t1] [winfo depth .t1]"





    } $visual
    incr i




























































































}

test visual-3.1 {Tk_GetVisual, parsing visual string} {

    catch {destroy .t1}
    toplevel .t1 -width 250 -height 100 \
	    -visual "[winfo visual .][winfo depth .]"
    wm geometry .t1 +0+0
    update
    concat "[winfo visual .t1] [winfo depth .t1]"


} $default
test visual-3.2 {Tk_GetVisual, parsing visual string} {

    catch {destroy .t1}
    list [catch {
	toplevel .t1 -width 250 -height 100 -visual goop20
	wm geometry .t1 +0+0
    } msg] $msg

} {1 {unknown or ambiguous visual name "goop20": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}}
test visual-3.3 {Tk_GetVisual, parsing visual string} {

    catch {destroy .t1}
    list [catch {
	toplevel .t1 -width 250 -height 100 -visual d
	wm geometry .t1 +0+0
    } msg] $msg

} {1 {unknown or ambiguous visual name "d": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}}
test visual-3.4 {Tk_GetVisual, parsing visual string} {
    catch {destroy .t1}
    list [catch {
	toplevel .t1 -width 250 -height 100 -visual static
	wm geometry .t1 +0+0
    } msg] $msg

} {1 {unknown or ambiguous visual name "static": class must be best, directcolor, grayscale, greyscale, pseudocolor, staticcolor, staticgray, staticgrey, truecolor, or default}}
test visual-3.5 {Tk_GetVisual, parsing visual string} {

    catch {destroy .t1}
    list [catch {
	toplevel .t1 -width 250 -height 100 -visual "pseudocolor 48x"
	wm geometry .t1 +0+0
    } msg] $msg

} {1 {expected integer but got "48x"}}


test visual-4.1 {Tk_GetVisual, numerical visual id} -setup {

    catch {destroy .t1}
    catch {destroy .t2}
    catch {destroy .t3}
    toplevel .t1 -width 250 -height 100 -visual $other
    wm geom .t1 +0+0
    toplevel .t2 -width 200 -height 80 -visual [winfo visual .]
    wm geom .t2 +5+5
    toplevel .t3 -width 150 -height 250 -visual [winfo visual .t1]
    wm geom .t3 +10+10
} -constraints {haveOtherVisual nonPortable} -body {
    set v1 [list [winfo visualid .t2] [winfo visualid .t3]]
    set v2 [list [winfo visualid .] [winfo visualid .t1]]
    expr {$v1 eq $v2 ? "OK" : "[list $v1] ne [list $v2]"}


} -result OK -cleanup {
    destroy .t1 .t2 .t3
}
test visual-4.2 {Tk_GetVisual, numerical visual id} {

    catch {destroy .t1}
    list [catch {toplevel .t1 -visual 12xyz} msg] $msg


} {1 {bad X identifier for visual: "12xyz"}}
test visual-4.3 {Tk_GetVisual, numerical visual id} {

    catch {destroy .t1}
    list [catch {toplevel .t1 -visual 1291673} msg] $msg


} {1 {couldn't find an appropriate visual}}


test visual-5.1 {Tk_GetVisual, no matching visual} !havePseudocolorVisual {

    catch {destroy .t1}


    list [catch {
	toplevel .t1 -width 250 -height 100 -visual "pseudocolor 8"
	wm geometry .t1 +0+0
    } msg] $msg

} {1 {couldn't find an appropriate visual}}


test visual-6.1 {Tk_GetVisual, no matching visual} {havePseudocolorVisual haveMultipleVisuals nonPortable} {

    catch {destroy .t1}


    toplevel .t1 -width 250 -height 100 -visual "best"
    wm geometry .t1 +0+0
    update
    winfo visual .t1


} {pseudocolor}


# These tests are non-portable due to variations in how many colors
# are already in use on the screen.

if {[testConstraint defaultPseudocolor8]} {



    eatColors .t1
}
test visual-7.1 {Tk_GetColormap, "new"} {defaultPseudocolor8 nonPortable} {
    toplevel .t2 -width 30 -height 20
    wm geom .t2 +0+0
    update
    colorsFree .t2
} {0}


test visual-7.2 {Tk_GetColormap, "new"} {defaultPseudocolor8 nonPortable} {

    catch {destroy .t2}



    toplevel .t2 -width 30 -height 20 -colormap new
    wm geom .t2 +0+0
    update
    colorsFree .t2
} {1}


test visual-7.3 {Tk_GetColormap, copy from other window} {defaultPseudocolor8 nonPortable} {

    catch {destroy .t2}



    toplevel .t3 -width 400 -height 50 -colormap new
    wm geom .t3 +0+0
    catch {destroy .t2}
    toplevel .t2 -width 30 -height 20 -colormap .t3
    wm geom .t2 +0+0
    update
    destroy .t3
    colorsFree .t2
} {1}


test visual-7.4 {Tk_GetColormap, copy from other window} {defaultPseudocolor8 nonPortable} {

    catch {destroy .t2}



    toplevel .t3 -width 400 -height 50 -colormap new
    wm geom .t3 +0+0
    catch {destroy .t2}
    toplevel .t2 -width 30 -height 20 -colormap .
    wm geom .t2 +0+0
    update
    destroy .t3
    colorsFree .t2
} {0}


test visual-7.5 {Tk_GetColormap, copy from other window} {defaultPseudocolor8 nonPortable} {

    catch {destroy .t1}


    list [catch {
	toplevel .t1 -width 400 -height 50 -colormap .choke.lots
    } msg] $msg

} {1 {bad window path name ".choke.lots"}}
test visual-7.6 {Tk_GetColormap, copy from other window} {defaultPseudocolor8 haveOtherVisual nonPortable} {

    catch {destroy .t1}

    catch {destroy .t2}
    toplevel .t1 -width 300 -height 150 -visual $other
    wm geometry .t1 +0+0
    list [catch {toplevel .t2 -width 400 -height 50 -colormap .t1} msg] $msg


} {1 {can't use colormap for .t1: incompatible visuals}}
if {[testConstraint defaultPseudocolor8]} {
    catch {destroy .t1}
    catch {destroy .t2}
}

test visual-8.1 {Tk_FreeColormap procedure} {
    deleteWindows

    toplevel .t1 -width 300 -height 180 -colormap new
    wm geometry .t1 +0+0
    foreach i {.t2 .t3 .t4} {
	toplevel $i -width 250 -height 150 -colormap .t1
	wm geometry $i +0+0
    }
    destroy .t1
    destroy .t3
    destroy .t4
    update
} {}


test visual-8.2 {Tk_FreeColormap procedure} haveOtherVisual {
    deleteWindows

    toplevel .t1 -width 300 -height 180 -visual $other
    wm geometry .t1 +0+0
    foreach i {.t2 .t3 .t4} {
	toplevel $i -width 250 -height 150 -visual $other
	wm geometry $i +0+0
    }
    destroy .t2
    destroy .t3
    destroy .t4
    update



} {}

deleteWindows
rename eatColors {}
rename colorsFree {}

# cleanup
cleanupTests
return




Changes to tests/visual_bb.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/local/bin/wish -f
#
# This script displays provides visual tests for many of Tk's features.
# Each test displays a window with various information in it, along
# with instructions about how the window should appear.  You can look
# at the window to make sure it appears as expected.  Individual tests
# are kept in separate ".tcl" files in this directory.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands


set auto_path ". $auto_path"
wm title . "Visual Tests for Tk"

set testNum 1

# Each menu entry invokes a visual test file

proc runTest {file} {
    global testNum

    test "2.$testNum" "testing $file" {userInteraction} {
    uplevel #0 [list source -encoding utf-8 [file join [testsDirectory] $file]]
    concat ""
    } {}
    incr testNum
}

# The following procedure is invoked to print the contents of a canvas:

proc lpr {c args} {
    exec lpr <<[eval [list $c postscript] $args]
}

proc end {} {
    cleanupTests
    set ::EndOfVisualTests 1
}

# ----------------------------------------------------------------------

test 1.1 {running visual tests} -constraints userInteraction -body {
    #-------------------------------------------------------
    # The code below create the main window, consisting of a
    # menu bar and a message explaining the basic operation
    # of the program.
    #-------------------------------------------------------

    frame .menu -relief raised -borderwidth 1
    message .msg -font {Times 18} -relief raised -width 4i \
        -borderwidth 1 -text "This application provides a collection of visual tests for the Tk toolkit.  Each menu entry invokes a test, which displays information on the screen.  You can then verify visually that the information is being displayed in the correct way.  The tests under the \"Postscript\" menu exercise the Postscript-generation capabilities of canvas widgets."

    pack .menu -side top -fill x
    pack .msg -side bottom -expand yes -fill both

    #-------------------------------------------------------
    # The code below creates all the menus, which invoke procedures
    # to create particular demonstrations of various widgets.
    #-------------------------------------------------------

    menubutton .menu.file -text "File" -menu .menu.file.m
    menu .menu.file.m
    .menu.file.m add command -label "Quit" -command end

    menubutton .menu.group1 -text "Group 1" -menu .menu.group1.m
    menu .menu.group1.m
    .menu.group1.m add command -label "Canvas arcs" -command {runTest arc.tcl}
    .menu.group1.m add command -label "Beveled borders in text widgets" \
        -command {runTest bevel.tcl}
    .menu.group1.m add command -label "Colormap management" \
        -command {runTest cmap.tcl}
    .menu.group1.m add command -label "Label/button geometry" \
        -command {runTest butGeom.tcl}
    .menu.group1.m add command -label "Label/button colors" \
        -command {runTest butGeom2.tcl}

    menubutton .menu.ps -text "Canvas Postscript" -menu .menu.ps.m
    menu .menu.ps.m
    .menu.ps.m add command -label "Rectangles and other graphics" \
        -command {runTest canvPsGrph.tcl}
    .menu.ps.m add command -label "Text" \
        -command {runTest canvPsText.tcl}
    .menu.ps.m add command -label "Bitmaps" \
        -command {runTest canvPsBmap.tcl}
    .menu.ps.m add command -label "Images" \
        -command {runTest canvPsImg.tcl}
    .menu.ps.m add command -label "Arcs" \
        -command {runTest canvPsArc.tcl}

    pack .menu.file .menu.group1 .menu.ps -side left -padx 1m

    # Set up for keyboard-based menu traversal

    bind . <FocusIn> {
    if {("%d" == "NotifyVirtual") && ("%m" == "NotifyNormal")} {
        focus .menu
    }
    }
    tk_menuBar .menu .menu.file .menu.group1 .menu.ps

    # Set up a class binding to allow objects to be deleted from a canvas
    # by clicking with mouse button 1:

    bind Canvas <Button-1> {%W delete [%W find closest %x %y]}

    concat ""
} -result {}

if {![testConstraint userInteraction]} {
    cleanupTests
} else {
    vwait EndOfVisualTests
}









<
|

<












|
|















<
<
|








|

















|

|

|

|




|

|

|

|

|





|
|
|
|






|


|






1
2
3
4
5
6
7
8
9

10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/local/bin/wish -f
#
# This script displays provides visual tests for many of Tk's features.
# Each test displays a window with various information in it, along
# with instructions about how the window should appear.  You can look
# at the window to make sure it appears as expected.  Individual tests
# are kept in separate ".tcl" files in this directory.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


set auto_path ". $auto_path"
wm title . "Visual Tests for Tk"

set testNum 1

# Each menu entry invokes a visual test file

proc runTest {file} {
    global testNum

    test "2.$testNum" "testing $file" {userInteraction} {
	uplevel \#0 source [file join [testsDirectory] $file]
	concat ""
    } {}
    incr testNum
}

# The following procedure is invoked to print the contents of a canvas:

proc lpr {c args} {
    exec lpr <<[eval [list $c postscript] $args]
}

proc end {} {
    cleanupTests
    set ::EndOfVisualTests 1
}



test 1.1 "running visual tests" {userInteraction} {
    #-------------------------------------------------------
    # The code below create the main window, consisting of a
    # menu bar and a message explaining the basic operation
    # of the program.
    #-------------------------------------------------------

    frame .menu -relief raised -borderwidth 1
    message .msg -font {Times 18} -relief raised -width 4i \
	    -borderwidth 1 -text "This application provides a collection of visual tests for the Tk toolkit.  Each menu entry invokes a test, which displays information on the screen.  You can then verify visually that the information is being displayed in the correct way.  The tests under the \"Postscript\" menu exercise the Postscript-generation capabilities of canvas widgets."

    pack .menu -side top -fill x
    pack .msg -side bottom -expand yes -fill both

    #-------------------------------------------------------
    # The code below creates all the menus, which invoke procedures
    # to create particular demonstrations of various widgets.
    #-------------------------------------------------------

    menubutton .menu.file -text "File" -menu .menu.file.m
    menu .menu.file.m
    .menu.file.m add command -label "Quit" -command end

    menubutton .menu.group1 -text "Group 1" -menu .menu.group1.m
    menu .menu.group1.m
    .menu.group1.m add command -label "Canvas arcs" -command {runTest arc.tcl}
    .menu.group1.m add command -label "Beveled borders in text widgets" \
	    -command {runTest bevel.tcl}
    .menu.group1.m add command -label "Colormap management" \
	    -command {runTest cmap.tcl}
    .menu.group1.m add command -label "Label/button geometry" \
	    -command {runTest butGeom.tcl}
    .menu.group1.m add command -label "Label/button colors" \
	    -command {runTest butGeom2.tcl}

    menubutton .menu.ps -text "Canvas Postscript" -menu .menu.ps.m
    menu .menu.ps.m
    .menu.ps.m add command -label "Rectangles and other graphics" \
	    -command {runTest canvPsGrph.tcl}
    .menu.ps.m add command -label "Text" \
	    -command {runTest canvPsText.tcl}
    .menu.ps.m add command -label "Bitmaps" \
	    -command {runTest canvPsBmap.tcl}
    .menu.ps.m add command -label "Images" \
	    -command {runTest canvPsImg.tcl}
    .menu.ps.m add command -label "Arcs" \
	    -command {runTest canvPsArc.tcl}

    pack .menu.file .menu.group1 .menu.ps -side left -padx 1m

    # Set up for keyboard-based menu traversal

    bind . <Any-FocusIn> {
	if {("%d" == "NotifyVirtual") && ("%m" == "NotifyNormal")} {
	    focus .menu
	}
    }
    tk_menuBar .menu .menu.file .menu.group1 .menu.ps

    # Set up a class binding to allow objects to be deleted from a canvas
    # by clicking with mouse button 1:

    bind Canvas <1> {%W delete [%W find closest %x %y]}

    concat ""
} {}

if {![testConstraint userInteraction]} {
    cleanupTests
} else {
    vwait EndOfVisualTests
}

Changes to tests/winButton.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


20



21
22






23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# This file is a Tcl script to test the Windows specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkWinButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
imageInit

proc bogusTrace args {
    error "trace aborted"
}


option clear




# ----------------------------------------------------------------------







test winbutton-1.1 {TkpComputeButtonGeometry procedure} -constraints {
    testImageType win nonPortable
} -setup {
    # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
    # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
    deleteWindows
} -body {
    image create test image1
    image1 changed 0 0 0 0 60 40
    label .b1 -image image1 -bd 4 -padx 0 -pady 2
    button .b2 -image image1 -bd 4 -padx 0 -pady 2
    checkbutton .b3 -image image1 -bd 4 -padx 1 -pady 1 \
        -font {{MS Sans Serif} 8}
    radiobutton .b4 -image image1 -bd 4 -padx 2 -pady 0 \
        -font {{MS Sans Serif} 8}
    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {68 48 70 50 88 50 88 50}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
    image delete image1
} -result {68 48 70 50 90 52 90 52}

test winbutton-1.2 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
    # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
    deleteWindows
} -body {
    label .b1 -bitmap question -bd 3 -padx 0 -pady 2
    button .b2 -bitmap question -bd 3 -padx 0 -pady 2
    checkbutton .b3 -bitmap question -bd 3 -padx 1 -pady 1 \
        -font {{MS Sans Serif} 8}
    radiobutton .b4 -bitmap question -bd 3 -padx 2 -pady 0 \
        -font {{MS Sans Serif} 8}
    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {23 33 25 35 43 35 43 35}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {23 33 25 35 45 37 45 37}

test winbutton-1.3 {TkpComputeButtonGeometry procedure} -constraints win -setup {
    deleteWindows
} -body {
    label .b1 -bitmap question -bd 3 -highlightthickness 4
    button .b2 -bitmap question -bd 3 -highlightthickness 0
    checkbutton .b3 -bitmap question -bd 3 -highlightthickness 1 \
        -indicatoron 0
    radiobutton .b4 -bitmap question -bd 3 -indicatoron false
    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {31 41 23 33 25 35 25 35}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {31 41 23 33 27 37 27 37}

test winbutton-1.4 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -font {{MS Sans Serif} 8}
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -font {{MS Sans Serif} 8}
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -font {{MS Sans Serif} 8}
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -font {{MS Sans Serif} 8}
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {58 24 67 33 88 30 90 28}

test winbutton-1.5 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    deleteWindows
} -body {
    label .l1 -wraplength 1.5i -padx 0 -pady 0 \
        -text "This is a long string that will wrap around on several lines.\n\nIt also has a blank line (above)."
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]
} -cleanup {
    deleteWindows
} -result {178 84}

test winbutton-1.6 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    deleteWindows
} -body {
    label .l1 -padx 0 -pady 0 \
        -text "This is a long string without wrapping.\n\nIt also has a blank line (above)."
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]
} -cleanup {
    deleteWindows
} -result {222 52}

test winbutton-1.7 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -width 10
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -height 5
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -width 20 -height 2
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -width 4
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {74 24 67 97 174 46 64 28}

test winbutton-1.8 {TkpComputeButtonGeometry procedure} -constraints {
    win nonPortable
} -setup {
    deleteWindows
} -body {
    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 \
    -highlightthickness 4
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 \
    -highlightthickness 0
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1  \
    -highlightthickness 1 -indicatoron no
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -indicatoron 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
        [winfo reqwidth .b2] [winfo reqheight .b2] \
        [winfo reqwidth .b3] [winfo reqheight .b3] \
        [winfo reqwidth .b4] [winfo reqheight .b4]
} -cleanup {
    deleteWindows
} -result {66 32 65 31 69 31 71 29}

test winbutton-1.9 {TkpComputeButtonGeometry procedure} -constraints win -setup {
    deleteWindows
} -body {
    button .b2 -bitmap question -default normal
    list [winfo reqwidth .b2] [winfo reqheight .b2]
} -cleanup {
    deleteWindows
} -result {23 33}

# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:






|
|
|



<
|

<




>
>

>
>
>
|
<
>
>
>
>
>
>

|
<
<



<




|
<
|
<





|
|
|
<
<
<
|
<
|
<
<



<


|
<
|
<





|
|
|
<
<
|
<
|

<



|






|
|
|
<
<
|
<
|
<
<

<







|
|
|
<
<
|
<
|
<
<

<
<
|



<
<
|
<
|
<
<

<
<
|



<
<
|
<
|
<
<

<







|
|
|
<
<
|
<
|
<
<

<

|

|

|




|
|
|
<
<
|
<
|

<


<
<
|


<



<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11

12
13

14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32


33
34
35

36
37
38
39
40

41

42
43
44
45
46
47
48
49



50

51


52
53
54

55
56
57

58

59
60
61
62
63
64
65
66


67

68
69

70
71
72
73
74
75
76
77
78
79
80
81
82


83

84


85

86
87
88
89
90
91
92
93
94
95


96

97


98


99
100
101
102


103

104


105


106
107
108
109


110

111


112

113
114
115
116
117
118
119
120
121
122


123

124


125

126
127
128
129
130
131
132
133
134
135
136
137
138


139

140
141

142
143


144
145
146

147
148
149





# This file is a Tcl script to test the Windows specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkWinButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands


proc bogusTrace args {
    error "trace aborted"
}
catch {unset value}
catch {unset value2}
option clear
eval image delete [image names]
if {[testConstraint testImageType]} {
    image create test image1
}

label .l -text Label
button .b -text Button
checkbutton .c -text Checkbutton
radiobutton .r -text Radiobutton
pack .l .b .c .r
update

test winbutton-1.1 {TkpComputeButtonGeometry procedure} {testImageType win nonPortable} {


    # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
    # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
    deleteWindows

    image create test image1
    image1 changed 0 0 0 0 60 40
    label .b1 -image image1 -bd 4 -padx 0 -pady 2
    button .b2 -image image1 -bd 4 -padx 0 -pady 2
    checkbutton .b3 -image image1 -bd 4 -padx 1 -pady 1 -font {{MS Sans Serif} 8}

    radiobutton .b4 -image image1 -bd 4 -padx 2 -pady 0 -font {{MS Sans Serif} 8}

    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {68 48 70 50 88 50 88 50}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]



} {68 48 70 50 90 52 90 52}

test winbutton-1.2 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
    # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
    deleteWindows

    label .b1 -bitmap question -bd 3 -padx 0 -pady 2
    button .b2 -bitmap question -bd 3 -padx 0 -pady 2
    checkbutton .b3 -bitmap question -bd 3 -padx 1 -pady 1 -font {{MS Sans Serif} 8}

    radiobutton .b4 -bitmap question -bd 3 -padx 2 -pady 0 -font {{MS Sans Serif} 8}

    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {23 33 25 35 43 35 43 35}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {23 33 25 35 45 37 45 37}

test winbutton-1.3 {TkpComputeButtonGeometry procedure} win {
    deleteWindows

    label .b1 -bitmap question -bd 3 -highlightthickness 4
    button .b2 -bitmap question -bd 3 -highlightthickness 0
    checkbutton .b3 -bitmap question -bd 3 -highlightthickness 1 \
	    -indicatoron 0
    radiobutton .b4 -bitmap question -bd 3 -indicatoron false
    pack .b1 .b2 .b3 .b4
    update
    # with patch 463234 with native L&F enabled, this returns:
    # {31 41 23 33 25 35 25 35}
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {31 41 23 33 27 37 27 37}

test winbutton-1.4 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    deleteWindows

    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -font {{MS Sans Serif} 8}
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -font {{MS Sans Serif} 8}
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -font {{MS Sans Serif} 8}
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -font {{MS Sans Serif} 8}
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {58 24 67 33 88 30 90 28}

test winbutton-1.5 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    deleteWindows


    label .l1 -text "This is a long string that will wrap around on several lines.\n\nIt also has a blank line (above)." -wraplength 1.5i -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]


} {178 84}

test winbutton-1.6 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    deleteWindows


    label .l1 -text "This is a long string without wrapping.\n\nIt also has a blank line (above)." -padx 0 -pady 0
    pack .l1
    update
    list [winfo reqwidth .l1] [winfo reqheight .l1]


} {222 52}

test winbutton-1.7 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    deleteWindows

    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 -width 10
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 -height 5
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1 -width 20 -height 2
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -width 4
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {74 24 67 97 174 46 64 28}

test winbutton-1.8 {TkpComputeButtonGeometry procedure} {win nonPortable} {


    deleteWindows

    label .b1 -text Xagqpim -bd 2 -padx 0 -pady 2 \
	-highlightthickness 4
    button .b2 -text Xagqpim -bd 2 -padx 0 -pady 2 \
	-highlightthickness 0
    checkbutton .b3 -text Xagqpim -bd 2 -padx 1 -pady 1  \
	-highlightthickness 1 -indicatoron no
    radiobutton .b4 -text Xagqpim -bd 2 -padx 2 -pady 0 -indicatoron 0
    pack .b1 .b2 .b3 .b4
    update
    list [winfo reqwidth .b1] [winfo reqheight .b1] \
	    [winfo reqwidth .b2] [winfo reqheight .b2] \
	    [winfo reqwidth .b3] [winfo reqheight .b3] \
	    [winfo reqwidth .b4] [winfo reqheight .b4]


} {66 32 65 31 69 31 71 29}

test winbutton-1.9 {TkpComputeButtonGeometry procedure} win {
    deleteWindows

    button .b2 -bitmap question -default normal
    list [winfo reqwidth .b2] [winfo reqheight .b2]


} {23 33}

# cleanup

deleteWindows
cleanupTests
return





Changes to tests/winClipboard.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
# This file is a Tcl script to test out Tk's Windows specific
# clipboard code.  It is organized in the standard fashion for Tcl
# tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 by Sun Microsystems, Inc.
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

#################################################################
# Note that some of these tests may fail if another application #
# is grabbing the clipboard (e.g. an X server, or a VNC viewer) #
#################################################################

test winClipboard-1.1 {TkSelGetSelection} -constraints win -setup {
    clipboard clear
} -body {
    selection get -selection CLIPBOARD
} -cleanup {
    clipboard clear
} -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}

test winClipboard-1.2 {TkSelGetSelection} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append {}
    list [selection get -selection CLIPBOARD] [testclipboard]
} -cleanup {
    clipboard clear

} -result {{} {}}

test winClipboard-1.3 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append abcd
    update
    list [selection get -selection CLIPBOARD] [testclipboard]
} -cleanup {
    clipboard clear

} -result {abcd abcd}

test winClipboard-1.4 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    set map [list "\r" "\\r" "\n" "\\n"]
    clipboard append "line 1\nline 2"
    list [string map $map [selection get -selection CLIPBOARD]]\
        [string map $map [testclipboard]]
} -cleanup {
    clipboard clear
} -result [list "line 1\\nline 2" "line 1\\nline 2"]

test winClipboard-1.5 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    set map [list "\r" "\\r" "\n" "\\n"]
    clipboard append "line 1Ç\nline 2"
    list [string map $map [selection get -selection CLIPBOARD]]\
        [string map $map [testclipboard]]
} -cleanup {
    clipboard clear
} -result [list "line 1Ç\\nline 2" "line 1Ç\\nline 2"]

test winClipboard-1.6 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append "привет миф"
    list [selection get -selection CLIPBOARD] [testclipboard]
} -cleanup {
    clipboard clear
} -result [list "привет миф" "привет миф"]

test winClipboard-2.1 {TkSelUpdateClipboard reentrancy problem} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append -type OUR_ACTION "action data"
    clipboard append "string data"
    update
    list [selection get -selection CLIPBOARD -type OUR_ACTION] [testclipboard]
} -cleanup {
    clipboard clear
} -result {{action data} {string data}}


test winClipboard-2.2 {TkSelUpdateClipboard reentrancy problem} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append -type OUR_ACTION "new data"
    clipboard append "more data in string"
    update

    list [testclipboard] [selection get -selection CLIPBOARD -type OUR_ACTION]
} -cleanup {
    clipboard clear
} -result {{more data in string} {new data}}

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:








|
|





<

<
|
|
<

|

<
|
|
<
|
<
|
<
<

<

|
<
|
>
|
<
|
<
<

<


|
<
|
>
|
<
|
<
<

<
<

|
|
<
|
|
<
|
<
<

<
<
|
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<

|
<
<

<



|
<
|
<
|
>
|
<
<

<



>
|
<
|
|




<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16

17
18

19
20
21

22
23

24

25


26

27
28

29
30
31

32


33

34
35
36

37
38
39

40


41


42
43
44

45
46

47


48


49
50


51
52
53










54
55


56

57
58
59
60

61

62
63
64


65

66
67
68
69
70

71
72
73
74
75
76




# This file is a Tcl script to test out Tk's Windows specific
# clipboard code.  It is organized in the standard fashion for Tcl
# tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands



# Note that these tests may fail if another application is grabbing the
# clipboard (e.g. an X server)


test winClipboard-1.1 {TkSelGetSelection} win {
    clipboard clear

    catch {selection get -selection CLIPBOARD} msg
    set msg

} {CLIPBOARD selection doesn't exist or form "STRING" not defined}

test winClipboard-1.2 {TkSelGetSelection} {win testclipboard} {


    clipboard clear

    clipboard append {}
    catch {selection get -selection CLIPBOARD} r1

    catch {testclipboard} r2
    list $r1 $r2
} {{} {}}

test winClipboard-1.3 {TkSelGetSelection & TkWinClipboardRender} {win testclipboard} {


    clipboard clear

    clipboard append abcd
    update
    catch {selection get -selection CLIPBOARD} r1

    catch {testclipboard} r2
    list $r1 $r2
} {abcd abcd}

test winClipboard-1.4 {TkSelGetSelection & TkWinClipboardRender} {win testclipboard} {


    clipboard clear


    clipboard append "line 1\nline 2"
    catch {selection get -selection CLIPBOARD} r1
    catch {testclipboard} r2

    list $r1 $r2
} [list "line 1\nline 2" "line 1\r\nline 2"]

test winClipboard-1.5 {TkSelGetSelection & TkWinClipboardRender} {win testclipboard} {


    clipboard clear


    clipboard append "line 1\u00c7\nline 2"
    catch {selection get -selection CLIPBOARD} r1


    catch {testclipboard} r2
    list $r1 $r2
} [list "line 1\u00c7\nline 2" [bytestring "line 1\u00c7\r\nline 2"]]











test winClipboard-2.1 {TkSelUpdateClipboard reentrancy problem} {win testclipboard} {


    clipboard clear

    clipboard append -type OUR_ACTION "action data"
    clipboard append "string data"
    update
    catch {selection get -selection CLIPBOARD -type OUR_ACTION} r1

    catch {testclipboard} r2

    list $r1 $r2
} [list "action data" "string data"]
test winClipboard-2.2 {TkSelUpdateClipboard reentrancy problem} {win testclipboard} {


    clipboard clear

    clipboard append -type OUR_ACTION "new data"
    clipboard append "more data in string"
    update
    catch {testclipboard} r1
    catch {selection get -selection CLIPBOARD -type OUR_ACTION} r2

    list $r1 $r2
} [list "more data in string" "new data"]

# cleanup
cleanupTests
return




Changes to tests/winDialog.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# -*- tcl -*-
# This file is a Tcl script to test the Windows specific behavior of
# the common dialog boxes.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 1998-1999 ActiveState Corporation.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}

# Locale identifier LANG_ENGLISH is 0x09
testConstraint english [expr {
    [llength [info commands testwinlocale]]
    && (([testwinlocale] & 0xff) == 9)
}]

proc vista? {{prevista 0} {postvista 1}} {
    lassign [split $::tcl_platform(osVersion) .] major
    return [expr {$major >= 6 ? $postvista : $prevista}]
}

# What directory to use in initialdir tests. Old code used to use
# c:/. However, on Vista/later that is a protected directory if you
# are not running privileged. Moreover, not everyone has a drive c:
# but not having a TEMP would break a lot Windows programs
proc initialdir {} {
    # file join to return in Tcl canonical format (/ separator, not \)
    #return [file join $::env(TEMP)]
    return [tcltest::temporaryDirectory]
}


proc start {arg} {
    set ::tk_dialog 0
    set ::iter_after 0
    set ::dialogclass "#32770"

    after 1 $arg
}

proc then {cmd} {
    set ::command $cmd
    set ::dialogresult {}
    set ::testfont {}

    # Do not make the delay too short. The newer Vista dialogs take
    # time to come up. Even if the testforwindow returns true, the
    # controls are not ready to accept messages
    after 500 afterbody
    vwait ::dialogresult
    return $::dialogresult
}

proc afterbody {} {
    # On Vista and later, using the new file dialogs we have to find
    # the window using its title as tk_dialog will not be set at the C level
    if {[vista?]} {
        if {[catch {testfindwindow "" $::dialogclass} ::tk_dialog]} {
            if {[incr ::iter_after] > 30} {
                set ::dialogresult ">30 iterations waiting on tk_dialog"
                return
            }
            after 150 {afterbody}
            return
        }
    } else {
        if {$::tk_dialog == 0} {
            if {[incr ::iter_after] > 30} {
                set ::dialogresult ">30 iterations waiting on tk_dialog"
                return
            }
            after 150 {afterbody}
            return
        }
    }
    uplevel #0 {set dialogresult [eval $command]}
}

proc Click {button} {
    switch -exact -- $button {
        ok     { set button 1 }





|
|
|


<
|











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<







<

<
<
<
|





<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
<







1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
















23
24
25
26

27
28
29
30
31
32
33

34



35
36
37
38
39
40












41
42
43
44
45
46
47

48
49
50
51
52
53
54
# -*- tcl -*-
# This file is a Tcl script to test the Windows specific behavior of
# the common dialog boxes.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 1998-1999 ActiveState Corporation.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}

# Locale identifier LANG_ENGLISH is 0x09
testConstraint english [expr {
    [llength [info commands testwinlocale]]
    && (([testwinlocale] & 0xff) == 9)
}]

















proc start {arg} {
    set ::tk_dialog 0
    set ::iter_after 0


    after 1 $arg
}

proc then {cmd} {
    set ::command $cmd
    set ::dialogresult {}





    afterbody
    vwait ::dialogresult
    return $::dialogresult
}

proc afterbody {} {












    if {$::tk_dialog == 0} {
	if {[incr ::iter_after] > 30} {
	    set ::dialogresult ">30 iterations waiting on tk_dialog"
	    return
	}
	after 150 {afterbody}
	return

    }
    uplevel #0 {set dialogresult [eval $command]}
}

proc Click {button} {
    switch -exact -- $button {
        ok     { set button 1 }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    return [testwinevent $::tk_dialog $id WM_GETTEXT]
}

proc SetText {id text} {
    return [testwinevent $::tk_dialog $id WM_SETTEXT $text]
}

proc ApplyFont {font} {
     set ::testfont $font
}

# ----------------------------------------------------------------------

test winDialog-1.1 {Tk_ChooseColorObjCmd} -constraints {
    testwinevent
} -body {
    start {tk_chooseColor}
    then {
        Click cancel
    }
} -result 0
test winDialog-1.2 {Tk_ChooseColorObjCmd} -constraints {
    testwinevent
} -body {
    start {set clr [tk_chooseColor -initialcolor "#ff9933"]}
    then {
        set x [Click cancel]
    }







<
<
<
<
<
<







|







66
67
68
69
70
71
72






73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    return [testwinevent $::tk_dialog $id WM_GETTEXT]
}

proc SetText {id text} {
    return [testwinevent $::tk_dialog $id WM_SETTEXT $text]
}







test winDialog-1.1 {Tk_ChooseColorObjCmd} -constraints {
    testwinevent
} -body {
    start {tk_chooseColor}
    then {
        Click cancel
    }
} -result {0}
test winDialog-1.2 {Tk_ChooseColorObjCmd} -constraints {
    testwinevent
} -body {
    start {set clr [tk_chooseColor -initialcolor "#ff9933"]}
    then {
        set x [Click cancel]
    }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    testwinevent
} -setup {
    catch {unset a x}
} -body {
    set x {}
    start {
        set clr [tk_chooseColor -initialcolor "#ff9933" \
                     -title "Привет"]
    }
    then {
        if {[catch {
            array set a [testgetwindowinfo $::tk_dialog]
            if {[info exists a(text)]} {lappend x $a(text)}
        } err]} { lappend x $err }
        lappend x [Click ok]
    }
    lappend x $clr
} -result [list "Привет" 0 "#ff9933"]
test winDialog-1.6 {Tk_ChooseColorObjCmd: -parent} -constraints {
    testwinevent
} -setup {
    catch {unset a x}
} -body {
    start {set clr [tk_chooseColor -initialcolor "#ff9933" -parent .]}
    set x {}







|









|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    testwinevent
} -setup {
    catch {unset a x}
} -body {
    set x {}
    start {
        set clr [tk_chooseColor -initialcolor "#ff9933" \
                     -title "\u041f\u0440\u0438\u0432\u0435\u0442"]
    }
    then {
        if {[catch {
            array set a [testgetwindowinfo $::tk_dialog]
            if {[info exists a(text)]} {lappend x $a(text)}
        } err]} { lappend x $err }
        lappend x [Click ok]
    }
    lappend x $clr
} -result [list "\u041f\u0440\u0438\u0432\u0435\u0442" 0 "#ff9933"]
test winDialog-1.6 {Tk_ChooseColorObjCmd: -parent} -constraints {
    testwinevent
} -setup {
    catch {unset a x}
} -body {
    start {set clr [tk_chooseColor -initialcolor "#ff9933" -parent .]}
    set x {}
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271




272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
test winDialog-1.7 {Tk_ChooseColorObjCmd: -parent} -constraints {
    testwinevent
} -body {
    tk_chooseColor -initialcolor "#ff9933" -parent .xyzzy12
} -returnCodes error -match glob -result {bad window path name*}


test winDialog-2.1 {ColorDlgHookProc} -constraints {emptyTest nt} -body {}

test winDialog-3.1 {Tk_GetOpenFileObjCmd} -constraints {
    nt testwinevent english
} -body {
    start {tk_getOpenFile}
    then {
        set x [GetText cancel]
        Click cancel
    }
    return $x
} -result {Cancel}


test winDialog-4.1 {Tk_GetSaveFileObjCmd} -constraints {
    nt testwinevent english
} -body {
    start {tk_getSaveFile}
    then {
        set x [GetText cancel]
        Click cancel
    }
    return $x
} -result {Cancel}

test winDialog-5.1 {GetFileName: no arguments} -constraints {
    nt testwinevent
} -body {
    start {tk_getOpenFile -title Open}
    then {
        Click cancel
    }
} -result 0
test winDialog-5.2 {GetFileName: one argument} -constraints {
    nt
} -body {
    tk_getOpenFile -foo
} -returnCodes error -result {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
test winDialog-5.3 {GetFileName: many arguments} -constraints {
    nt testwinevent
} -body {
    start {tk_getOpenFile -initialdir [initialdir] -parent . -title test -initialfile foo}
    then {
        Click cancel
    }
} -result 0
test winDialog-5.4 {GetFileName: Tcl_GetIndexFromObj() != TCL_OK} -constraints {
    nt
} -body {
    tk_getOpenFile -foo bar -abc
} -returnCodes error -result {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
test winDialog-5.5 {GetFileName: Tcl_GetIndexFromObj() == TCL_OK} -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getOpenFile -title bar]}
    set y [then {
        Click cancel
    }]
    # Note this also tests fix for
    # https://core.tcl-lang.org/tk/tktview/4a0451f5291b3c9168cc560747dae9264e1d2ef6
    # $x is expected to be empty
    append x $y

} -result 0
test winDialog-5.6 {GetFileName: valid option, but missing value} -constraints {
    nt
} -body {
    tk_getOpenFile -initialdir bar -title
} -returnCodes error -result {value for "-title" missing}

test winDialog-5.7 {GetFileName: extension begins with .} -constraints {
    nt testwinevent
} -body {




    start {set x [tk_getSaveFile -defaultextension .foo -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.foo

test winDialog-5.7.1 {GetFileName: extension {} } -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getSaveFile -defaultextension {} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar

test winDialog-5.7.2 {GetFileName: extension {} Bug 47af31bd3ac6fbbb33cde1a5bab1e756ff2a6e00 } -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getSaveFile -filetypes {{All *}} -defaultextension {} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar

test winDialog-5.7.3 {GetFileName: extension {} Bug 47af31bd3ac6fbbb33cde1a5bab1e756ff2a6e00 } -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getSaveFile -filetypes {{All *}} -defaultextension {} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar.c} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.c

test winDialog-5.7.4 {GetFileName: extension {} } -constraints {
    nt testwinevent
} -body {
    # Although the docs do not explicitly mention, -filetypes seems to
    # override -defaultextension
    start {set x [tk_getSaveFile -filetypes {{C .c} {Tcl .tcl}} -defaultextension {foo} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.c

test winDialog-5.7.5 {GetFileName: extension {} } -constraints {
    nt testwinevent
} -body {
    # Although the docs do not explicitly mention, -filetypes seems to
    # override -defaultextension
    start {set x [tk_getSaveFile -filetypes {{C .c} {Tcl .tcl}} -defaultextension {} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.c


test winDialog-5.7.6 {GetFileName: All/extension } -constraints {
    nt testwinevent
} -body {
    # In 8.6.4 this combination resulted in bar.aaa.aaa which is bad
    start {set x [tk_getSaveFile -filetypes {{All *}} -defaultextension {aaa} -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.aaa

test winDialog-5.7.7 {tk_getOpenFile: -defaultextension} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    tcltest::makeFile "" "5 7 7.aaa" [initialdir]
    start {set x [tk_getOpenFile \
                      -defaultextension aaa \
                      -initialdir [file nativename [initialdir]] \
                      -initialfile "5 7 7" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "5 7 7.aaa"]

test winDialog-5.7.8 {tk_getOpenFile: -defaultextension} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    tcltest::makeFile "" "5 7 8.aaa" [initialdir]
    start {set x [tk_getOpenFile \
                      -defaultextension aaa \
                      -initialdir [file nativename [initialdir]] \
                      -initialfile "5 7 8.aaa" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "5 7 8.aaa"]

test winDialog-5.8 {GetFileName: extension doesn't begin with .} -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getSaveFile -defaultextension foo -title Save]}
    set msg {}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    set x "[file tail $x]$msg"
} -cleanup {
    unset msg
} -result bar.foo
test winDialog-5.9 {GetFileName: file types} -constraints {
    nt testwinevent
} -body {
    #        case FILE_TYPES:

    start {tk_getSaveFile -filetypes {{"foo files" .foo FOOF}} -title Foo}
    # XXX - currently disabled for vista style dialogs because the file
    # types control has no control ID and we don't have a mechanism to
    # locate it.
    if {[vista?]} {
        then {
            Click cancel
        }
        return 1
    } else {
        then {
            set x [GetText 0x470]
            Click cancel
        }
        return [string equal $x {foo files (*.foo)}]
    }
} -result 1
test winDialog-5.10 {GetFileName: file types: MakeFilter() fails} -constraints {
    nt
} -body {
#        if (MakeFilter(interp, string, &utfFilterString) != TCL_OK)

    tk_getSaveFile -filetypes {{"foo" .foo FOO}}
} -returnCodes error -result {bad Macintosh file type "FOO"}

test winDialog-5.11 {GetFileName: initial directory} -constraints {
    nt testwinevent
} -body {
#        case FILE_INITDIR:
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir [initialdir] \
                      -initialfile "12x 455" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "12x 455"]

test winDialog-5.12 {GetFileName: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string, &ds) == NULL)

    tk_getOpenFile -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}

test winDialog-5.12.1 {tk_getSaveFile: initial directory: ~} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir ~ \
                      -initialfile "5 12 1" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file normalize [file join ~ "5 12 1"]]

test winDialog-5.12.2 {tk_getSaveFile: initial directory: ~user} -constraints {
    nt testwinevent
} -body {

    # Note: this test will fail on Tcl versions 8.6.4 and earlier due
    # to a bug in file normalize for names of the form ~xxx that
    # returns the wrong dir on Windows.  In particular (in Win8 at
    # least) it returned /users/Default instead of /users/USERNAME...

    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir ~$::tcl_platform(user) \
                      -initialfile "5 12 2" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file normalize [file join ~$::tcl_platform(user) "5 12 2"]]

test winDialog-5.12.3 {tk_getSaveFile: initial directory: .} -constraints {
    nt testwinevent
} -body {
    # Windows remembers dirs from previous selections so use
    # a subdir for this test, not [initialdir] itself
    set newdir [tcltest::makeDirectory "5 12 3"]
    set cur [pwd]
    try {
        cd $newdir
        unset -nocomplain x
        start {set x [tk_getSaveFile \
                          -initialdir . \
                          -initialfile "testfile" -title Foo]}
        then {
            Click ok
        }
    } finally {
        cd $cur
    }
    string equal $x [file join $newdir testfile]
} -result 1

test winDialog-5.12.4 {tk_getSaveFile: initial directory: unicode} -constraints {
    nt testwinevent
} -body {
    set dir [tcltest::makeDirectory "ŧéŝŧ"]
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir $dir \
                      -initialfile "testfile" -title Foo]}
    then {
        Click ok
    }
    string equal $x [file join $dir testfile]
} -result 1

test winDialog-5.12.5 {tk_getSaveFile: initial directory: nativename} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir [file nativename [initialdir]] \
                      -initialfile "5 12 5" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "5 12 5"]

test winDialog-5.12.6 {tk_getSaveFile: initial directory: relative} -constraints {
    nt testwinevent
} -body {
    # Windows remembers dirs from previous selections so use
    # a subdir for this test, not [initialdir] itself
    set dir [tcltest::makeDirectory "5 12 6"]
    set cur [pwd]
    try {
        cd [file dirname $dir]
        unset -nocomplain x
        start {set x [tk_getSaveFile \
                          -initialdir "5 12 6" \
                          -initialfile "testfile" -title Foo]}
        then {
            Click ok
        }
    } finally {
        cd $cur
    }
    string equal $x [file join $dir testfile]
} -result 1

test winDialog-5.12.7 {tk_getOpenFile: initial directory: ~} -constraints {
    nt testwinevent
} -body {
    set fn [file tail [lindex [glob -types f ~/*] 0]]
    unset -nocomplain x
    start {set x [tk_getOpenFile \
                      -initialdir ~ \
                      -initialfile $fn -title Foo]}
    then {
        Click ok
    }
    string equal $x [file normalize [file join ~ $fn]]
} -result 1

test winDialog-5.12.8 {tk_getOpenFile: initial directory: .} -constraints {
    nt testwinevent
} -body {
    # Windows remembers dirs from previous selections so use
    # a subdir for this test, not [initialdir] itself
    set newdir [tcltest::makeDirectory "5 12 8"]
    set path [tcltest::makeFile "" "testfile" $newdir]
    set cur [pwd]
    try {
        cd $newdir
        unset -nocomplain x
        start {set x [tk_getOpenFile \
                          -initialdir . \
                          -initialfile "testfile" -title Foo]}
        then {
            Click ok
        }
    } finally {
        cd $cur
    }
    string equal $x $path
} -result 1

test winDialog-5.12.9 {tk_getOpenFile: initial directory: unicode} -constraints {
    nt testwinevent
} -body {
    set dir [tcltest::makeDirectory "ŧéŝŧ"]
    set path [tcltest::makeFile "" testfile $dir]
    unset -nocomplain x
    start {set x [tk_getOpenFile \
                      -initialdir $dir \
                      -initialfile "testfile" -title Foo]}
    then {
        Click ok
    }
    string equal $x $path
} -result 1

test winDialog-5.12.10 {tk_getOpenFile: initial directory: nativename} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    tcltest::makeFile "" "5 12 10" [initialdir]
    start {set x [tk_getOpenFile \
                      -initialdir [file nativename [initialdir]] \
                      -initialfile "5 12 10" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "5 12 10"]

test winDialog-5.12.11 {tk_getOpenFile: initial directory: relative} -constraints {
    nt testwinevent
} -body {
    # Windows remembers dirs from previous selections so use
    # a subdir for this test, not [initialdir] itself
    set dir [tcltest::makeDirectory "5 12 11"]
    set path [tcltest::makeFile "" testfile $dir]
    set cur [pwd]
    try {
        cd [file dirname $dir]
        unset -nocomplain x
        start {set x [tk_getOpenFile \
                          -initialdir [file tail $dir] \
                          -initialfile "testfile" -title Foo]}
        then {
            Click ok
        }
    } finally {
        cd $cur
    }
    string equal $x $path
} -result 1

test winDialog-5.13 {GetFileName: initial file} -constraints {
    nt testwinevent
} -body {
#        case FILE_INITFILE:

    start {set x [tk_getSaveFile -initialfile "12x 456" -title Foo]}
    then {
        Click ok
    }
    file tail $x
} -result "12x 456"
test winDialog-5.14 {GetFileName: initial file: Tcl_TranslateFileName()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
    tk_getOpenFile -initialfile ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}
if {![vista?]} {
    # XXX - disabled for Vista because the new dialogs allow long file
    # names to be specified but force the user to change it.
    test winDialog-5.15 {GetFileName: initial file: long name} -constraints {
        nt testwinevent
    } -body {
        start {
            set dialogresult [catch {
                tk_getSaveFile -initialfile [string repeat a 1024] -title Long
            } x]
        }
        then {
            Click ok
        }
        list $dialogresult [string match "invalid filename *" $x]
    } -result {1 1}
}
test winDialog-5.16 {GetFileName: parent} -constraints {
    nt
} -body {
#        case FILE_PARENT:

    toplevel .t
    set x 0
    start {tk_getOpenFile -parent .t -title Parent; set x 1}
    then {
        destroy .t
    }
    return $x
} -result 1
test winDialog-5.17 {GetFileName: title} -constraints {
    nt testwinevent
} -body {
#        case FILE_TITLE:

    start {tk_getOpenFile -title Narf}
    then {
        Click cancel
    }
} -result 0
if {[vista?]} {
    # In the newer file dialogs, the file type widget does not even exist
    # if no file types specified
    test winDialog-5.18 {GetFileName: no filter specified} -constraints {
        nt testwinevent
    } -body {
        #    if (ofn.lpstrFilter == NULL)
        start {tk_getOpenFile -title Filter}
        then {
            catch {set x [GetText 0x470]} y
            Click cancel
        }
        return $y
    } -result {Could not find control with id 1136}
} else {
    test winDialog-5.18 {GetFileName: no filter specified} -constraints {
        nt testwinevent
    } -body {
        #    if (ofn.lpstrFilter == NULL)

        start {tk_getOpenFile -title Filter}
        then {
            set x [GetText 0x470]
            Click cancel
        }
        return $x
    } -result {All Files (*.*)}
}
test winDialog-5.19 {GetFileName: parent HWND doesn't yet exist} -constraints {
    nt
} -setup {
    destroy .t
} -body {
#    if (Tk_WindowId(parent) == None)

    toplevel .t
    start {tk_getOpenFile -parent .t -title Open}
    then {
        destroy .t
    }
} -result {}
test winDialog-5.20 {GetFileName: parent HWND already exists} -constraints {
    nt
} -setup {
    destroy .t
} -body {
    toplevel .t
    update
    start {tk_getOpenFile -parent .t -title Open}
    then {
        destroy .t
    }
} -result {}
test winDialog-5.21 {GetFileName: call GetOpenFileName} -constraints {
    nt testwinevent english
} -body {
#        winCode = GetOpenFileName(&ofn);

    start {tk_getOpenFile -title Open}
    then {
        set x [GetText ok]
        Click cancel
    }
    return $x
} -result {&Open}
test winDialog-5.22 {GetFileName: call GetSaveFileName} -constraints {
    nt testwinevent english
} -body {
#        winCode = GetSaveFileName(&ofn);

    start {tk_getSaveFile -title Save}
    then {
        set x [GetText ok]
        Click cancel
    }
    return $x
} -result {&Save}

test winDialog-5.23 {GetFileName: convert \ to /} -constraints {
    nt testwinevent
} -body {
    set msg {}
    start {set x [tk_getSaveFile -title Back]}
    then {
	if {[catch {SetText [vista? 0x47C 0x3e9] [file nativename \
		[file join [initialdir] "12x 457"]]} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    return $x$msg
} -cleanup {
    unset msg
} -result [file join [initialdir] "12x 457"]

test winDialog-5.24 {GetFileName: file types: MakeFilter() succeeds} -constraints {
    nt
} -body {
    # MacOS type that is correct, but has embedded nulls.

    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {\0\0\0\0}}}}]}
    then {
        Click cancel
    }
    return $x
} -result 0
test winDialog-5.25 {GetFileName: file types: MakeFilter() succeeds} -constraints {
    nt
} -body {
    # MacOS type that is correct, but has embedded high-bit chars.

    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {••••}}}}]}
    then {
        Click cancel
    }
    return $x
} -result 0


test winDialog-6.1 {MakeFilter} -constraints {emptyTest nt} -body {}


test winDialog-7.1 {Tk_MessageBoxObjCmd} -constraints {emptyTest nt} -body {}


test winDialog-8.1 {OFNHookProc} -constraints {emptyTest nt} -body {}


## The Tk_ChooseDirectoryObjCmd hang on the static build of Windows
## because somehow the GetOpenFileName ends up a noop in the static
## build.
##
test winDialog-9.1 {Tk_ChooseDirectoryObjCmd: no arguments} -constraints {
    nt testwinevent
} -body {
    start {set x [tk_chooseDirectory]}
    set y [then {
        Click cancel
    }]
    # $x should be "" on a Cancel
    append x $y

} -result 0
test winDialog-9.2 {Tk_ChooseDirectoryObjCmd: one argument} -constraints {
    nt
} -body {
    tk_chooseDirectory -foo
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test winDialog-9.3 {Tk_ChooseDirectoryObjCmd: many arguments} -constraints {
    nt testwinevent
} -body {
    start {
        tk_chooseDirectory -initialdir [initialdir] -mustexist 1 -parent . -title test
    }
    then {
        Click cancel
    }
} -result 0
test winDialog-9.4 {Tk_ChooseDirectoryObjCmd: Tcl_GetIndexFromObj() != TCL_OK} -constraints {
    nt
} -body {
    tk_chooseDirectory -foo bar -abc
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test winDialog-9.5 {Tk_ChooseDirectoryObjCmd: Tcl_GetIndexFromObj() == TCL_OK} -constraints {
    nt testwinevent
} -body {
    start {tk_chooseDirectory -title bar}
    then {
        Click cancel
    }
} -result 0
test winDialog-9.6 {Tk_ChooseDirectoryObjCmd: valid option, but missing value} -constraints {
    nt
} -body {
    tk_chooseDirectory -initialdir bar -title
} -returnCodes error -result {value for "-title" missing}
test winDialog-9.7 {Tk_ChooseDirectoryObjCmd: -initialdir} -constraints {
    nt testwinevent
} -body {
#        case DIR_INITIAL:

    start {set x [tk_chooseDirectory -initialdir [initialdir] -title Foo]}
    then {
        Click ok
    }
    string tolower [set x]
} -result [string tolower [initialdir]]
test winDialog-9.8 {Tk_ChooseDirectoryObjCmd: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string,
#            &utfDirString) == NULL)

    tk_chooseDirectory -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}


test winDialog-10.1 {Tk_FontchooserObjCmd: no arguments} -constraints {
    nt testwinevent
} -body {
    start {tk fontchooser show}
    list [then {
	Click cancel
    }] $::testfont
} -result {0 {}}
test winDialog-10.2 {Tk_FontchooserObjCmd: -initialfont} -constraints {
    nt testwinevent
} -body {
    start {
        tk fontchooser configure -command ApplyFont -font system
        tk fontchooser show
    }
    list [then {
	Click cancel
    }] $::testfont
} -result {0 {}}
test winDialog-10.3 {Tk_FontchooserObjCmd: -initialfont} -constraints {
    nt testwinevent
} -body {
    start {
        tk fontchooser configure -command ApplyFont -font system
        tk fontchooser show
    }
    list [then {
	Click 1
    }] [expr {[llength $::testfont] ne {}}]
} -result {0 1}
test winDialog-10.4 {Tk_FontchooserObjCmd: -title} -constraints {
    nt testwinevent
} -body {
    start {
        tk fontchooser configure -command ApplyFont -title "tk test"
        tk fontchooser show
    }
    list [then {
	Click cancel
    }] $::testfont
} -result {0 {}}
test winDialog-10.5 {Tk_FontchooserObjCmd: -parent} -constraints {
    nt testwinevent
} -setup {
    array set a {parent {}}
} -body {
    start {
        tk fontchooser configure -command ApplyFont -parent .
        tk fontchooser show
    }
    then {
        array set a [testgetwindowinfo $::tk_dialog]
	Click cancel
    }
    list [expr {$a(parent) == [wm frame .]}] $::testfont
} -result {1 {}}
test winDialog-10.6 {Tk_FontchooserObjCmd: -apply} -constraints {
    nt testwinevent
} -body {
    start {
        tk fontchooser configure -command FooBarBaz
        tk fontchooser show
    }
    then {
	Click cancel
    }
} -result 0
test winDialog-10.7 {Tk_FontchooserObjCmd: -apply} -constraints {
    nt testwinevent
} -body {
    start {
        tk fontchooser configure -command ApplyFont -parent .
        tk fontchooser show
    }
    list [then {
	Click [expr {0x0402}] ;# value from XP
        Click cancel
    }] [expr {[llength $::testfont] > 0}]
} -result {0 1}
test winDialog-10.8 {Tk_FontchooserObjCmd: -title} -constraints {
    nt testwinevent
} -setup {
    array set a {text failed}
} -body {
    start {
        tk fontchooser configure -command ApplyFont -title "Hello"
        tk fontchooser show
    }
    then {
        array set a [testgetwindowinfo $::tk_dialog]
        Click cancel
    }
    set a(text)
} -result "Hello"
test winDialog-10.9 {Tk_FontchooserObjCmd: -title} -constraints {
    nt testwinevent
} -setup {
    array set a {text failed}
} -body {
    start {
        tk fontchooser configure -command ApplyFont \
            -title  "Привет"
        tk fontchooser show
    }
    then {
        array set a [testgetwindowinfo $::tk_dialog]
        Click cancel
    }
    set a(text)
} -result "Привет"

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 0}
}

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:








<
<





|
|










|
|









|

|








|

|

|








|
|
|
<
<
<
<
<
>
|





<



>
>
>
>



|





<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|





|


|



|


<
<
<
<
|
<
<
<
<
<
|
|
|
|
<
|



|



>



|
|

|


|


|
|



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|



|

|
|



|


<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
<



|





|


|



|



|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|

|
|
|
|
|
|
|
<










|











|





|



|
|






|



|
|



>






|
|








|
>







|


|





|

|


|
<
<
<
<
<
<
<
<
<
<








|
|
|
<
<
<
>
|









|


|

|










|

|








|

|

|


|



|
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
152
153
154
155
156
157
158


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213





214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236




237













238
239
240


























































































































241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262




263





264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294




































































































295












296






297











































































298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314



315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350















351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452










453
454
455
456
457
458
459
460
461
462
463



464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
















































































































519
520
521
522
523
524
525
526
527
528
529

test winDialog-1.7 {Tk_ChooseColorObjCmd: -parent} -constraints {
    testwinevent
} -body {
    tk_chooseColor -initialcolor "#ff9933" -parent .xyzzy12
} -returnCodes error -match glob -result {bad window path name*}




test winDialog-3.1 {Tk_GetOpenFileObjCmd} -constraints {
    nt testwinevent english
} -body {
    start {tk_getOpenFile}
    then {
	set x [GetText cancel]
	Click cancel
    }
    return $x
} -result {Cancel}


test winDialog-4.1 {Tk_GetSaveFileObjCmd} -constraints {
    nt testwinevent english
} -body {
    start {tk_getSaveFile}
    then {
	set x [GetText cancel]
	Click cancel
    }
    return $x
} -result {Cancel}

test winDialog-5.1 {GetFileName: no arguments} -constraints {
    nt testwinevent
} -body {
    start {tk_getOpenFile -title Open}
    then {
	Click cancel
    }
} -result {0}
test winDialog-5.2 {GetFileName: one argument} -constraints {
    nt
} -body {
    tk_getOpenFile -foo
} -returnCodes error -result {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
test winDialog-5.3 {GetFileName: many arguments} -constraints {
    nt testwinevent
} -body {
    start {tk_getOpenFile -initialdir c:/ -parent . -title test -initialfile foo}
    then {
	Click cancel
    }
} -result {0}
test winDialog-5.4 {GetFileName: Tcl_GetIndexFromObj() != TCL_OK} -constraints {
    nt
} -body {
    tk_getOpenFile -foo bar -abc
} -returnCodes error -result {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
test winDialog-5.5 {GetFileName: Tcl_GetIndexFromObj() == TCL_OK} -constraints {
    nt testwinevent
} -body {
    start {tk_getOpenFile -title bar}
    then {
	Click cancel





    }
} -result {0}
test winDialog-5.6 {GetFileName: valid option, but missing value} -constraints {
    nt
} -body {
    tk_getOpenFile -initialdir bar -title
} -returnCodes error -result {value for "-title" missing}

test winDialog-5.7 {GetFileName: extension begins with .} -constraints {
    nt testwinevent
} -body {
#    if (string[0] == '.') {
#	string++;
#    }

    start {set x [tk_getSaveFile -defaultextension .foo -title Save]}
    set msg {}
    then {
	if {[catch {SetText 0x47C bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }




    return [string totitle $x]$msg













} -cleanup {
    unset msg
} -result [string totitle [file join [pwd] bar.foo]]


























































































































test winDialog-5.8 {GetFileName: extension doesn't begin with .} -constraints {
    nt testwinevent
} -body {
    start {set x [tk_getSaveFile -defaultextension foo -title Save]}
    set msg {}
    then {
	if {[catch {SetText 0x47C bar} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    return [string totitle $x]$msg
} -cleanup {
    unset msg
} -result [string totitle [file join [pwd] bar.foo]]
test winDialog-5.9 {GetFileName: file types} -constraints {
    nt testwinevent
} -body {
#	case FILE_TYPES:

    start {tk_getSaveFile -filetypes {{"foo files" .foo FOOF}} -title Foo}




    then {





	set x [GetText 0x470]
	Click cancel
    }
    return $x

} -result {foo files (*.foo)}
test winDialog-5.10 {GetFileName: file types: MakeFilter() fails} -constraints {
    nt
} -body {
#	if (MakeFilter(interp, string, &utfFilterString) != TCL_OK)

    tk_getSaveFile -filetypes {{"foo" .foo FOO}}
} -returnCodes error -result {bad Macintosh file type "FOO"}
if {[info exists ::env(TEMP)]} {
test winDialog-5.11 {GetFileName: initial directory} -constraints {
    nt testwinevent
} -body {
#	case FILE_INITDIR:

    start {set x [tk_getSaveFile \
                      -initialdir [file normalize $::env(TEMP)] \
                      -initialfile "12x 455" -title Foo]}
    then {
	Click ok
    }
    return $x
} -result [file join [file normalize $::env(TEMP)] "12x 455"]
}
test winDialog-5.12 {GetFileName: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#	if (Tcl_TranslateFileName(interp, string, &ds) == NULL)

















































































































    tk_getOpenFile -initialdir ~12x/455






} -returnCodes error -result {user "12x" doesn't exist}











































































test winDialog-5.13 {GetFileName: initial file} -constraints {
    nt testwinevent
} -body {
#	case FILE_INITFILE:

    start {set x [tk_getSaveFile -initialfile "12x 456" -title Foo]}
    then {
	Click ok
    }
    string totitle $x
} -result [string totitle [file join [pwd] "12x 456"]]
test winDialog-5.14 {GetFileName: initial file: Tcl_TranslateFileName()} -constraints {
    nt
} -body {
#	if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
    tk_getOpenFile -initialfile ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}



test winDialog-5.15 {GetFileName: initial file: long name} -constraints {
    nt testwinevent
} -body {
    start {
	set dialogresult [catch {
	    tk_getSaveFile -initialfile [string repeat a 1024] -title Long
	} x]
    }
    then {
	Click ok
    }
    list $dialogresult [string match "invalid filename *" $x]
} -result {1 1}

test winDialog-5.16 {GetFileName: parent} -constraints {
    nt
} -body {
#	case FILE_PARENT:

    toplevel .t
    set x 0
    start {tk_getOpenFile -parent .t -title Parent; set x 1}
    then {
	destroy .t
    }
    return $x
} -result {1}
test winDialog-5.17 {GetFileName: title} -constraints {
    nt testwinevent
} -body {
#	case FILE_TITLE:

    start {tk_getOpenFile -title Narf}
    then {
	Click cancel
    }
} -result {0}















test winDialog-5.18 {GetFileName: no filter specified} -constraints {
    nt testwinevent
} -body {
#    if (ofn.lpstrFilter == NULL)

    start {tk_getOpenFile -title Filter}
    then {
	set x [GetText 0x470]
	Click cancel
    }
    return $x
} -result {All Files (*.*)}

test winDialog-5.19 {GetFileName: parent HWND doesn't yet exist} -constraints {
    nt
} -setup {
    destroy .t
} -body {
#    if (Tk_WindowId(parent) == None)

    toplevel .t
    start {tk_getOpenFile -parent .t -title Open}
    then {
	destroy .t
    }
} -result {}
test winDialog-5.20 {GetFileName: parent HWND already exists} -constraints {
    nt
} -setup {
    destroy .t
} -body {
    toplevel .t
    update
    start {tk_getOpenFile -parent .t -title Open}
    then {
	destroy .t
    }
} -result {}
test winDialog-5.21 {GetFileName: call GetOpenFileName} -constraints {
    nt testwinevent english
} -body {
#	winCode = GetOpenFileName(&ofn);

    start {tk_getOpenFile -title Open}
    then {
	set x [GetText ok]
	Click cancel
    }
    return $x
} -result {&Open}
test winDialog-5.22 {GetFileName: call GetSaveFileName} -constraints {
    nt testwinevent english
} -body {
#	winCode = GetSaveFileName(&ofn);

    start {tk_getSaveFile -title Save}
    then {
	set x [GetText ok]
	Click cancel
    }
    return $x
} -result {&Save}
if {[info exists ::env(TEMP)]} {
test winDialog-5.23 {GetFileName: convert \ to /} -constraints {
    nt testwinevent
} -body {
    set msg {}
    start {set x [tk_getSaveFile -title Back]}
    then {
	if {[catch {SetText 0x47C [file nativename \
		[file join [file normalize $::env(TEMP)] "12x 457"]]} msg]} {
	    Click cancel
	} else {
	    Click ok
	}
    }
    return $x$msg
} -cleanup {
    unset msg
} -result [file join [file normalize $::env(TEMP)] "12x 457"]
}
test winDialog-5.24 {GetFileName: file types: MakeFilter() succeeds} -constraints {
    nt
} -body {
    # MacOS type that is correct, but has embedded nulls.

    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {\0\0\0\0}}}}]}
    then {
	Click cancel
    }
    return $x
} -result {0}
test winDialog-5.25 {GetFileName: file types: MakeFilter() succeeds} -constraints {
    nt
} -body {
    # MacOS type that is correct, but has embedded high-bit chars.

    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {\u2022\u2022\u2022\u2022}}}}]}
    then {
	Click cancel
    }
    return $x
} -result {0}











## The Tk_ChooseDirectoryObjCmd hang on the static build of Windows
## because somehow the GetOpenFileName ends up a noop in the static
## build.
##
test winDialog-9.1 {Tk_ChooseDirectoryObjCmd: no arguments} -constraints {
    nt testwinevent
} -body {
    start {tk_chooseDirectory}
    then {
	Click cancel



    }
} -result {0}
test winDialog-9.2 {Tk_ChooseDirectoryObjCmd: one argument} -constraints {
    nt
} -body {
    tk_chooseDirectory -foo
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test winDialog-9.3 {Tk_ChooseDirectoryObjCmd: many arguments} -constraints {
    nt testwinevent
} -body {
    start {
	tk_chooseDirectory -initialdir c:/ -mustexist 1 -parent . -title test
    }
    then {
	Click cancel
    }
} -result {0}
test winDialog-9.4 {Tk_ChooseDirectoryObjCmd: Tcl_GetIndexFromObj() != TCL_OK} -constraints {
    nt
} -body {
    tk_chooseDirectory -foo bar -abc
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test winDialog-9.5 {Tk_ChooseDirectoryObjCmd: Tcl_GetIndexFromObj() == TCL_OK} -constraints {
    nt testwinevent
} -body {
    start {tk_chooseDirectory -title bar}
    then {
	Click cancel
    }
} -result {0}
test winDialog-9.6 {Tk_ChooseDirectoryObjCmd: valid option, but missing value} -constraints {
    nt
} -body {
    tk_chooseDirectory -initialdir bar -title
} -returnCodes error -result {value for "-title" missing}
test winDialog-9.7 {Tk_ChooseDirectoryObjCmd: -initialdir} -constraints {
    nt testwinevent
} -body {
#	case DIR_INITIAL:

    start {set x [tk_chooseDirectory -initialdir c:/ -title Foo]}
    then {
	Click ok
    }
    string tolower [set x]
} -result {c:/}
test winDialog-9.8 {Tk_ChooseDirectoryObjCmd: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#	if (Tcl_TranslateFileName(interp, string,
#		&utfDirString) == NULL)

    tk_chooseDirectory -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}

















































































































if {[testConstraint testwinevent]} {
    catch {testwinevent debug 0}
}

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/winFont.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


18



19


20



21



22








23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231

232
233
234
235

236
237
238
239
240
241
242
243
244
245
246

247
248
249
250

251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
# This file is a Tcl script to test out the procedures in tkWinFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands







test winfont-1.1 {TkpGetNativeFont procedure: not native} -constraints {


    win



} -body {



    catch {font delete xyz}








    font measure {} xyz
} -returnCodes error -result {font "" doesn't exist}
test winfont-1.2 {TkpGetNativeFont procedure: native} -constraints win -body {
    font measure ansifixed 0
    font measure ansi 0
    font measure device 0
    font measure oemfixed 0
    font measure systemfixed 0
    font measure system 0
    set x {}
} -result {}


test winfont-2.1 {TkpGetFontFromAttributes procedure: pointsize} -constraints {
    win
} -body {
    expr {[font actual {-size -10} -size] > 0}
} -result 1
test winfont-2.2 {TkpGetFontFromAttributes procedure: pointsize} -constraints {
    win
} -body {
    expr {[font actual {-family Arial} -size] > 0}
} -result 1
test winfont-2.3 {TkpGetFontFromAttributes procedure: normal weight} -constraints {
    win
} -body {
    font actual {-weight normal} -weight
} -result {normal}
test winfont-2.4 {TkpGetFontFromAttributes procedure: bold weight} -constraints {
    win
} -body {
    font actual {-weight bold} -weight
} -result {bold}
test winfont-2.5 {TkpGetFontFromAttributes procedure: no family} -constraints {
    win
} -body {
    catch {expr {[font actual {-size 10} -size]}}
} -result 0
test winfont-2.6 {TkpGetFontFromAttributes procedure: family} -constraints {
    win
} -body {
    font actual {-family Arial} -family
} -result {Arial}
test winfont-2.7 {TkpGetFontFromAttributes procedure: Times fonts} -constraints {
    win
} -setup {
    set x {}
} -body {
    lappend x [font actual {-family "Times"} -family]
    lappend x [font actual {-family "New York"} -family]
    lappend x [font actual {-family "Times New Roman"} -family]
} -result {Times Times {Times New Roman}}
test winfont-2.8 {TkpGetFontFromAttributes procedure: Courier fonts} -constraints {
    win
} -setup {
    set x {}
} -body {
    lappend x [font actual {-family "Courier"} -family]
    lappend x [font actual {-family "Monaco"} -family]
    lappend x [font actual {-family "Courier New"} -family]
} -match regexp -result {Courier (Courier|Monaco) {Courier New}}
test winfont-2.9 {TkpGetFontFromAttributes procedure: Helvetica fonts} -constraints {
    win
} -setup {
    set x {}
} -body {
    lappend x [font actual {-family "Helvetica"} -family]
    lappend x [font actual {-family "Geneva"} -family]
    lappend x [font actual {-family "Arial"} -family]
} -match regexp -result {Helvetica (Helvetica|Geneva) Arial}
test winfont-2.10 {TkpGetFontFromAttributes procedure: fallback} -constraints {
    win
} -body {
    # No way to get it to fail! Any font name is acceptable.
} -result {}


test winfont-3.1 {TkpDeleteFont procedure} -constraints win -body {
    catch {font delete xyz}
    font actual {-family xyz}
    set x {}
} -result {}


test winfont-4.1 {TkpGetFontFamilies procedure} -constraints win -body {
    font families
    set x {}
} -result {}

destroy .t
toplevel .t
wm geometry .t +0+0
update idletasks
label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left -text "0" -font systemfixed
pack .t.l
canvas .t.c -closeenough 0

set courier {Courier 14}
set cx [font measure $courier 0]
set t [.t.c create text 0 0 -anchor nw -just left -font $courier]
pack .t.c
update

set ax [winfo reqwidth .t.l]
set ay [winfo reqheight .t.l]
proc getsize {} {
    update
    return "[winfo reqwidth .t.l] [winfo reqheight .t.l]"
}

test winfont-5.1 {Tk_MeasureChars procedure: unbounded right margin} -constraints {
    win
} -setup {
    destroy .t.l
} -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap 0 -text "000000"
    list [expr {[winfo reqwidth .t.l] eq 6*$ax}] \
        [expr {[winfo reqheight .t.l] eq $ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.2 {Tk_MeasureChars procedure: static width buffer exceeded} -constraints {
    win
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap 100000 -text "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    list [expr {[winfo reqwidth .t.l] eq 256*$ax}] \
        [expr {[winfo reqheight .t.l] eq $ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.3 {Tk_MeasureChars procedure: all chars did fit} -constraints {

    win



} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap [expr {$ax*10}] -text "00000000"
    list [expr {[winfo reqwidth .t.l] eq 8*$ax}] \
        [expr {[winfo reqheight .t.l] eq $ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.4 {Tk_MeasureChars procedure: not all chars fit} -constraints {
    win
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap [expr {$ax*6}] -text "00000000"
    list [expr {[winfo reqwidth .t.l] eq 6*$ax}] \
        [expr {[winfo reqheight .t.l] eq 2*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.5 {Tk_MeasureChars procedure: include last partial char} -constraints {
    win
} -setup {
    destroy .t.c
}  -body {
    canvas .t.c -closeenough 0
    set t [.t.c create text 0 0 -anchor nw -just left -font $courier]
    pack .t.c
    update

    .t.c dchars $t 0 end
    .t.c insert $t 0 "0000"
    .t.c index $t @[expr {int($cx*2.5)}],1
} -cleanup {
    destroy .t.c
} -result 2

test winfont-5.6 {Tk_MeasureChars procedure: at least one char on line} -constraints {
    win

} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \

        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]

    set ay [winfo reqheight .t.l]

    .t.l config -text "000000" -wrap 1
    list [expr {[winfo reqwidth .t.l] eq $ax}] \
        [expr {[winfo reqheight .t.l] eq 6*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.7 {Tk_MeasureChars procedure: whole words} -constraints {
    win

} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \

        -text "0" -font systemfixed
    pack .t.l
    update

    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap [expr {$ax*8}] -text "000000 0000"
    list [expr {[winfo reqwidth .t.l] eq 6*$ax}] \
        [expr {[winfo reqheight .t.l] eq 2*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.8 {Tk_MeasureChars procedure: already saw space in line} -constraints {
    win
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap [expr {$ax*12}] -text "000000    0000000"
    list [expr {[winfo reqwidth .t.l] eq 7*$ax}] \
        [expr {[winfo reqheight .t.l] eq 2*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.9 {Tk_MeasureChars procedure: internal spaces significant} -constraints {
    win
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]


    .t.l config -wrap [expr {$ax*12}] -text "000  00   00000"
    list [expr {[winfo reqwidth .t.l] eq 7*$ax}] \
        [expr {[winfo reqheight .t.l] eq 2*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.10 {Tk_MeasureChars procedure: make first part of word fit} -constraints {
    win
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    set ax [winfo reqwidth .t.l]
    set ay [winfo reqheight .t.l]

    .t.l config -wrap [expr {$ax*12}] -text "0000000000000000"
    list [expr {[winfo reqwidth .t.l] eq 12*$ax}] \
        [expr {[winfo reqheight .t.l] eq 2*$ay}]
} -cleanup {
    destroy .t.l
} -result {1 1}

test winfont-5.11 {Tk_MeasureChars procedure: check for kerning} -constraints {
    win nonPortable
} -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update

    set font [.t.l cget -font]
    .t.l config -font {{MS Sans Serif} 8} -text "W"
    set width [winfo reqwidth .t.l]
    .t.l config -text "XaYoYaKaWx"
    set x [lindex [getsize] 0]
    .t.l config -font $font
    expr {$x < ($width*10)}
} -cleanup {
    destroy .t.l
} -result 1


test winfont-6.1 {Tk_DrawChars procedure: loop test} -constraints win -setup {
    destroy .t.l
}  -body {
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
        -text "0" -font systemfixed
    pack .t.l
    update
    .t.l config -text "a"
    update
} -cleanup {
    destroy .t.l
} -result {}


test winfont-7.1 {AllocFont procedure: use old font} -constraints win -setup {
    destroy .c
} -setup {
    catch {font delete xyz}
} -body {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} -result {}
test winfont-7.2 {AllocFont procedure: extract info from logfont} -constraints {
    win
} -body {
    font actual {arial 10 bold italic underline overstrike}
} -result {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1}
test winfont-7.3 {AllocFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric {arial 10 bold italic underline overstrike} -fixed
} -result 0
test winfont-7.4 {AllocFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric systemfixed -fixed
} -result 1

# cleanup

cleanupTests
return

# Local variables:
# mode: tcl
# End:









|
|



<
|


>
>

>
>
>
|
>
>
|
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
|
|
|







<
|

|
<
<
|
|
|
<
<
|
|
|
<
<

|
|
<
<

|
|
<
<

|
|
<
<

|
|
<
<

<



|
|
<
<

<



|
|
<
<

<



|
|
<
<

<
|

|
<


<
|

|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|
|
>
|
>
>
>
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
|
|
<
>
|
<
|
<
>
|
<
|
<
>
<
|
|
<
<
|
<
<
|
|
<
>
|
<
|
<
>
|
<
|
>
|
|
|
|
|
<
|
|
<
|
<
|
|
<
<
<
<
<
<
<
<

<
<
<
<
<
<
|
<
<
<
<
<
<
|
<

<
<
>

<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<





|
|
<
<

|
|
<
<

|
|
<
<

|


>


<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55


56
57
58


59
60
61


62
63
64


65
66
67


68
69
70


71
72
73


74

75
76
77
78
79


80

81
82
83
84
85


86

87
88
89
90
91


92

93
94
95

96
97

98
99
100
101
102





















103
104
105











106


107


108
109











110


111


112
113
114
115
116
117
118









119






120



















121









122
123
124



125
126

127
128

129

130
131

132

133

134
135


136


137
138

139
140

141

142
143

144
145
146
147
148
149
150

151
152

153

154
155








156






157






158

159


160
161

162

163



























































164




165
166
167
168
169
170
171


172
173
174


175
176
177


178
179
180
181
182
183
184





# This file is a Tcl script to test out the procedures in tkWinFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

catch {destroy .b}
catch {font delete xyz}

toplevel .b
wm geometry .b +0+0
update idletasks

set courier {Courier 14}
set cx [font measure $courier 0]

label .b.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left -text "0" -font systemfixed
pack .b.l
canvas .b.c -closeenough 0

set t [.b.c create text 0 0 -anchor nw -just left -font $courier]
pack .b.c
update

set ax [winfo reqwidth .b.l]
set ay [winfo reqheight .b.l]
proc getsize {} {
    update
    return "[winfo reqwidth .b.l] [winfo reqheight .b.l]"
}

test winfont-1.1 {TkpGetNativeFont procedure: not native} win {
    list [catch {font measure {} xyz} msg] $msg
} {1 {font "" doesn't exist}}
test winfont-1.2 {TkpGetNativeFont procedure: native} win {
    font measure ansifixed 0
    font measure ansi 0
    font measure device 0
    font measure oemfixed 0
    font measure systemfixed 0
    font measure system 0
    set x {}

} {}

test winfont-2.1 {TkpGetFontFromAttributes procedure: pointsize} win {


    expr [font actual {-size -10} -size]>0
} 1
test winfont-2.2 {TkpGetFontFromAttributes procedure: pointsize} win {


    expr [font actual {-family Arial} -size]>0
} 1
test winfont-2.3 {TkpGetFontFromAttributes procedure: normal weight} win {


    font actual {-weight normal} -weight
} normal
test winfont-2.4 {TkpGetFontFromAttributes procedure: bold weight} win {


    font actual {-weight bold} -weight
} bold
test winfont-2.5 {TkpGetFontFromAttributes procedure: no family} win {


    catch {expr {[font actual {-size 10} -size]}}
} 0
test winfont-2.6 {TkpGetFontFromAttributes procedure: family} win {


    font actual {-family Arial} -family
} Arial
test winfont-2.7 {TkpGetFontFromAttributes procedure: Times fonts} win {


    set x {}

    lappend x [font actual {-family "Times"} -family]
    lappend x [font actual {-family "New York"} -family]
    lappend x [font actual {-family "Times New Roman"} -family]
} {{Times New Roman} {Times New Roman} {Times New Roman}}
test winfont-2.8 {TkpGetFontFromAttributes procedure: Courier fonts} win {


    set x {}

    lappend x [font actual {-family "Courier"} -family]
    lappend x [font actual {-family "Monaco"} -family]
    lappend x [font actual {-family "Courier New"} -family]
} {{Courier New} {Courier New} {Courier New}}
test winfont-2.9 {TkpGetFontFromAttributes procedure: Helvetica fonts} win {


    set x {}

    lappend x [font actual {-family "Helvetica"} -family]
    lappend x [font actual {-family "Geneva"} -family]
    lappend x [font actual {-family "Arial"} -family]
} {Arial Arial Arial}
test winfont-2.10 {TkpGetFontFromAttributes procedure: fallback} win {


    # No way to get it to fail! Any font name is acceptable.

} {}

test winfont-3.1 {TkpDeleteFont procedure} win {

    font actual {-family xyz}
    set x {}

} {}

test winfont-4.1 {TkpGetFontFamilies procedure} win {
    font families
    set x {}





















} {}

test winfont-5.1 {Tk_MeasureChars procedure: unbounded right margin} win {











    .b.l config -wrap 0 -text "000000"


    getsize


} "[expr $ax*6] $ay"
test winfont-5.2 {Tk_MeasureChars procedure: static width buffer exceeded} win {











    .b.l config -wrap 100000 -text "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"


    getsize


} "[expr $ax*256] $ay"
test winfont-5.3 {Tk_MeasureChars procedure: all chars did fit} win {
    .b.l config -wrap [expr $ax*10] -text "00000000"
    getsize
} "[expr $ax*8] $ay"
test winfont-5.4 {Tk_MeasureChars procedure: not all chars fit} win {
    .b.l config -wrap [expr $ax*6] -text "00000000"









    getsize






} "[expr $ax*6] [expr $ay*2]"



















test winfont-5.5 {Tk_MeasureChars procedure: include last partial char} win {









    .b.c dchars $t 0 end
    .b.c insert $t 0 "0000"
    .b.c index $t @[expr int($cx*2.5)],1



} 2
test winfont-5.6 {Tk_MeasureChars procedure: at least one char on line} win {

    .b.l config -text "000000" -wrap 1
    getsize

} "$ax [expr $ay*6]"

test winfont-5.7 {Tk_MeasureChars procedure: whole words} win {
    .b.l config -wrap [expr $ax*8] -text "000000 0000"

    getsize

} "[expr $ax*6] [expr $ay*2]"

test winfont-5.8 {Tk_MeasureChars procedure: already saw space in line} win {
    .b.l config -wrap [expr $ax*12] -text "000000    0000000"


    getsize


} "[expr $ax*7] [expr $ay*2]"
test winfont-5.9 {Tk_MeasureChars procedure: internal spaces significant} win {

    .b.l config -wrap [expr $ax*12] -text "000  00   00000"
    getsize

} "[expr $ax*7] [expr $ay*2]"

test winfont-5.10 {Tk_MeasureChars procedure: make first part of word fit} win {
    .b.l config -wrap [expr $ax*12] -text "0000000000000000"

    getsize
} "[expr $ax*12] [expr $ay*2]"
test winfont-5.11 {Tk_MeasureChars procedure: check for kerning} \
	{win nonPortable} {
    set font [.b.l cget -font]
    .b.l config -font {{MS Sans Serif} 8} -text "W"
    set width [winfo reqwidth .b.l]

    .b.l config -text "XaYoYaKaWx"
    set x [lindex [getsize] 0]

    .b.l config -font $font

    expr $x < ($width*10)
} 1















test winfont-6.1 {Tk_DrawChars procedure: loop test} win {






    .b.l config -text "a"

    update


} {}


test winfont-7.1 {AllocFont procedure: use old font} win {

    font create xyz



























































    catch {destroy .c}




    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test winfont-7.2 {AllocFont procedure: extract info from logfont} win {


    font actual {arial 10 bold italic underline overstrike}
} {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1}
test winfont-7.3 {AllocFont procedure: extract info from textmetric} win {


    font metric {arial 10 bold italic underline overstrike} -fixed
} 0
test winfont-7.4 {AllocFont procedure: extract info from textmetric} win {


    font metric systemfixed -fixed
} 1

# cleanup
destroy .b
cleanupTests
return





Changes to tests/winMenu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609



610



611
612
613
614
615
616
617
618
619
620
621
622
623
624

625
626





627


628
629
630
631
632
633
634
635
636
637
638





639

640




641


642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217

1218



1219

1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270

1271
1272
1273


1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

test winMenu-1.1 {GetNewID} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
} -cleanup {
    destroy .m1
} -returnCodes ok -result {.m1}
test winMenu-1.2 {GetNewID} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -result {}


# Basically impossible to test menu IDs wrapping.

test winMenu-2.1 {FreeID} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -returnCodes ok


test winMenu-3.1 {TkpNewMenu} -constraints win -setup {
    destroy .m1
} -body {
    list [catch {menu .m1} msg] $msg [catch {destroy .m1} msg2] $msg2
} -result {0 .m1 0 {}}
test winMenu-3.2 {TkpNewMenu} -constraints win -setup {
    destroy .m1
} -body {
    . configure -menu ""
    menu .m1
    .m1 add command -label "foo"
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [catch {destroy .m1} msg2] $msg2
} -result {0 {} {} 0 {}}


test winMenu-4.1 {TkpDestroyMenu} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
} -returnCodes ok
test winMenu-4.2 {TkpDestroyMenu - help menu} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -menu .m1.system
    . configure -menu .m1
    list [catch {destroy .m1.system} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}


test winMenu-5.1 {TkpDestroyMenuEntry} -constraints win -setup {
    destroy .m1
} -body {
    . configure -menu ""
    menu .m1
    .m1 add command -label "test"
    update idletasks
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-6.1 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    list [catch {menu .m1} msg] $msg [destroy .m1]
} -result {0 .m1 {}}
test winMenu-6.2 {GetEntryText} -constraints {
    testImageType win
} -setup {
    destroy .m1
} -body {
    catch {image delete image1}
    menu .m1
    image create test image1
    list [catch {.m1 add command -image image1} msg] $msg [destroy .m1] [image delete image1]
} -result {0 {} {} {}}
test winMenu-6.3 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -bitmap questhead} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.4 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.5 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.6 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.7 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.8 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.9 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.10 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.11 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.12 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.13 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.14 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.15 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.16 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}

test winMenu-7.1 {ReconfigureWindowsMenu - system menu item removal} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system
    .m1.system add command -label foo
    update idletasks
    .m1.system add command -label bar
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}
test winMenu-7.2 {ReconfigureWindowsMenu - menu item removal} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label Hello
    update idletasks
    .m1 add command -label foo
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.3 {ReconfigureWindowsMenu - zero items} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    .m1 delete Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.4 {ReconfigureWindowsMenu - one item} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.5 {ReconfigureWindowsMenu - two items} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label One
    .m1 add command -label Two
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.6 {ReconfigureWindowsMenu - separator item} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add separator
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.7 {ReconfigureWindowsMenu - non-text item} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.8 {ReconfigureWindowsMenu - disabled item} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello -state disabled
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.9 {ReconfigureWindowsMenu - non-selected checkbutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add checkbutton -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.10 {ReconfigureWindowsMenu - non-selected radiobutton} -constraints {
    win
} -setup {

    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add radiobutton -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.11 {ReconfigureWindowsMenu - selected checkbutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add checkbutton -label Hello
    .m1 invoke Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.12 {ReconfigureWindowsMenu - selected radiobutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add radiobutton -label Hello
    .m1 invoke Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.13 {ReconfigureWindowsMenu - cascade missing} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-7.14 {ReconfigureWindowsMenu - cascade} -constraints win -setup {
    destroy .m1
} -body {
    catch {destroy .m2}
    menu .m1 -tearoff 0
    menu .m2
    .m1 add cascade -menu .m2 -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1] [destroy .m2]
} -result {0 {} {} {}}
test winMenu-7.15 {ReconfigureWindowsMenu - menubar without system menu} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.file
    menu .m1.file -tearoff 0
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}
test winMenu-7.16 {ReconfigureWindowsMenu - system menu already created} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    . configure -menu .m1
    update idletasks
    .m1.system add command -label Hello
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}
test winMenu-7.17 {ReconfigureWindowsMenu - system menu update pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}
test winMenu-7.18 {ReconfigureWindowsMenu - system menu update not pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label Hello
    update idletasks
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}
test winMenu-7.19 {ReconfigureWindowsMenu - column break} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    list [catch {update idletasks} msg] $msg [destroy .m1]
} -result {0 {} {}}


#Don't know how to generate nested post menus

test winMenu-8.1 {TkpPostMenu} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -postcommand "blork"
    .m1 post 40 40
} -returnCodes error -result {invalid command name "blork"}
test winMenu-8.2 {TkpPostMenu} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -postcommand "blork"
    .m1 post 40 40
    destroy .m1
} -returnCodes error -result {invalid command name "blork"}
test winMenu-8.3 {TkpPostMenu} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -postcommand "destroy .m1"
    list [.m1 post 40 40] [winfo exists .m1]
} -result {{} 0}
test winMenu-8.4 {TkpPostMenu - popup menu} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-8.3: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}
test winMenu-8.5 {TkpPostMenu - menu button} -constraints {
    win userInteraction
} -setup {
    destroy .mb
} -body {
    menubutton .mb -text test -menu .mb.menu
    menu .mb.menu
    .mb.menu add command -label "winMenu-8.4 - Hit ESCAPE."
    pack .mb
    list [tk::MbPost .mb] [destroy .mb]
} -result {{} {}}
test winMenu-8.6 {TkpPostMenu - update not pending} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-8.5 - Hit ESCAPE."
    update idletasks
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-9.1 {TkpMenuNewEntry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-10.1 {TkwinMenuProc} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-10.1: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}


# Can't generate a WM_INITMENU without a Tk menu yet.

test winMenu-11.1 {TkWinHandleMenuEvent - WM_INITMENU} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -postcommand "set foo test"
    .m1 add command -label "winMenu-11.1: Hit ESCAPE."
    list [.m1 post 40 40] [set foo] [unset foo] [destroy .m1]
} -result {test test {} {}}
test winMenu-11.2 {TkWinHandleMenuEvent - WM_COMMAND} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo -label "winMenu-11.2: Please select this menu item."
    list [.m1 post 40 40] [update] [set foo] [unset foo] [destroy .m1]
} -result {{} {} 1 {} {}}
test winMenu-11.3 {TkWinHandleMenuEvent - WM_COMMAND} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    proc bgerror {args} {
        global foo errorInfo
        set foo [list $args $errorInfo]
    }
    menu .m1
    .m1 add command -command {error 1} -label "winMenu-11.2: Please select this menu item."
    list [.m1 post 40 40] [update] [set foo] [unset foo] [destroy .m1]
} -result {{} {} {1 {1
    while executing
"error 1"
    (menu invoke)}} {} {}}


# Can't test WM_MENUCHAR

test winMenu-11.4 {TkWinHandleMenuEvent - WM_MEASUREITEM} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-11.3: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}
test winMenu-11.5 {TkWinHandleMenuEvent - WM_MEASUREITEM} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label "winMenu-11.4: Hit ESCAPE" -hidemargin 1
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}
test winMenu-11.6 {TkWinHandleMenuEvent - WM_DRAWITEM} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-11.5: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}
test winMenu-11.7 {TkWinHandleMenuEvent - WM_DRAWITEM - item disabled} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-11.6: Hit ESCAPE." -state disabled
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}
test winMenu-11.8 {TkWinHandleMenuEvent - WM_INITMENU - not pending} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label "winMenu-11.7: Hit ESCAPE"
    update idletasks
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-12.1 {TkpSetWindowMenuBar} -constraints win -setup {
    destroy .m1
} -body {
    . configure -menu ""
    menu .m1
    .m1 add command -label foo
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [catch {destroy .m1} msg2] $msg2
} -result {0 {} {} 0 {}}
test winMenu-12.2 {TkpSetWindowMenuBar} -constraints win -setup {
    destroy .m1
} -body {
    . configure -menu ""
    menu .m1
    .m1 add command -label foo
    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg [catch {destroy .m1} msg2] $msg2
} -result {0 {} 0 {}}
test winMenu-12.3 {TkpSetWindowMenuBar - no update pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    . configure -menu ""
    menu .m1 -tearoff 0
    .m1 add command -label foo
    update idletasks
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}


test winMenu-13.1 {TkpSetMainMenubar - nothing to do} -constraints {
    emptyTest win
} -body {}


test winMenu-14.1 {GetMenuIndicatorGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test winMenu-14.2 {GetMenuIndicatorGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -hidemargin 1
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


test winMenu-15.1 {GetMenuAccelGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo -accel Ctrl+U
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test winMenu-15.2 {GetMenuAccelGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok
test winMenu-15.3 {GetMenuAccelGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    tk::TearOffMenu .m1 40 40



    destroy .m1



} -returnCodes ok


test winMenu-16.1 {GetTearoffEntryGeometry} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-19.1: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}



test winMenu-17.1 {GetMenuSeparatorGeometry} -constraints win -setup {
    destroy .m1





} -body {


    menu .m1
    .m1 add separator
    tk::TearOffMenu .m1 40 40
    destroy .m1
} -returnCodes ok


# Currently, the only callers to DrawWindowsSystemBitmap want things
# centered vertically, and either centered or right aligned horizontally.
test winMenu-18.1 {DrawWindowsSystemBitmap - center aligned} -constraints {
    win





} -setup {

    destroy .m1




} -body {


    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-18.2 {DrawWindowsSystemBitmap - right aligned} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-19.1 {DrawMenuEntryIndicator - not checkbutton or radiobutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-19.2 {DrawMenuEntryIndicator - not selected} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-19.3 {DrawMenuEntryIndicator - checkbutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-19.4 {DrawMenuEntryIndicator - radiobutton} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-19.5 {DrawMenuEntryIndicator - disabled} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    .m1 entryconfigure foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-19.6 {DrawMenuEntryIndicator - indicator not on} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-20.1 {DrawMenuEntryAccelerator - disabled} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground red
    .m1 add command -label foo -accel "Ctrl+U" -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-20.2 {DrawMenuEntryAccelerator - normal text} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-20.3 {DrawMenuEntryAccelerator - disabled, no disabledforeground} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground ""
    .m1 add command -label foo -accel "Ctrl+U" -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-20.4 {DrawMenuEntryAccelerator - cascade, drawArrow true} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-20.5 {DrawMenuEntryAccelerator - cascade, drawArrow false} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "winMenu-23.5: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}


test winMenu-21.1 {DrawMenuSeparator} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-22.1 {DrawMenuUnderline} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -underline 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-23.1 {Don't know how to test MenuKeyBindProc} -constraints {
    win emptyTest
} -body {}


test winMenu-24.1 {TkpInitializeMenuBindings called at boot time} -constraints {
    win emptyTest
} -body {}


test winMenu-25.1 {DrawMenuEntryLabel - normal} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-25.2 {DrawMenuEntryLabel - disabled with fg} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground red
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-25.3 {DrawMenuEntryLabel - disabled with no fg} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-26.1 {TkpComputeMenubarGeometry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label File
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]
} -result {{} {} {}}


test winMenu-27.1 {DrawTearoffEntry} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "winMenu-24.4: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} -result {{} {}}


test winMenu-28.1 {TkpConfigureMenuEntry - update pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-28.2 {TkpConfigureMenuEntry - update not pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label One
    update idletasks
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-29.1 {TkpDrawMenuEntry - gc for active and not strict motif} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.2 {TkpDrawMenuEntry - gc for active menu item with its own gc} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activeforeground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.3 {TkpDrawMenuEntry - gc for active and strict motif} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    set tk_strictMotif 1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} -result {{} {} 0}

test winMenu-29.4 {TkpDrawMenuEntry - gc for disabled with disabledfg and custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled -background red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.5 {TkpDrawMenuEntry - gc for disabled with disabledFg} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.6 {TkpDrawMenuEntry - gc for disabled - no disabledFg} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.7 {TkpDrawMenuEntry - gc for normal - custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -foreground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.8 {TkpDrawMenuEntry - gc for normal} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.9 {TkpDrawMenuEntry - gc for indicator - custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo -selectcolor orange
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.10 {TkpDrawMenuEntry - gc for indicator} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.11 {TkpDrawMenuEntry - border - custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activebackground green
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.12 {TkpDrawMenuEntry - border} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.13 {TkpDrawMenuEntry - active border - strict motif} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    set tk_strictMotif 1
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} -result {{} {} 0}
test winMenu-29.14 {TkpDrawMenuEntry - active border - custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -activeforeground yellow
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.15 {TkpDrawMenuEntry - active border} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.16 {TkpDrawMenuEntry - font - custom entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo -font "Helvectica 72"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.17 {TkpDrawMenuEntry - font} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1 -font "Courier 72"
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.18 {TkpDrawMenuEntry - separator} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.19 {TkpDrawMenuEntry - standard} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.20 {TkpDrawMenuEntry - disabled cascade item} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file
    .m1.file add command -label foo
    .m1 entryconfigure File -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.21 {TkpDrawMenuEntry - indicator} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label winMenu-31.20
    .m1 invoke winMenu-31.20
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-29.22 {TkpDrawMenuEntry - indicator} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label winMenu-31.21 -hidemargin 1
    .m1 invoke winMenu-31.21
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-30.1 {GetMenuLabelGeometry - image} -constraints {
    testImageType win
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    menu .m1
    image create test image1
    .m1 add command -image image1
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test winMenu-30.2 {GetMenuLabelGeometry - bitmap} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -bitmap questhead
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-30.3 {GetMenuLabelGeometry - no text} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-30.4 {GetMenuLabelGeometry - text} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "This is a test."
    list [update idletasks] [destroy .m1]
} -result {{} {}}


test winMenu-31.1 {DrawMenuEntryBackground} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} -result {{} {}}
test winMenu-31.2 {DrawMenuEntryBackground} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff activate 0
    list [update] [destroy .m1]
} -result {{} {}}


test winMenu-32.1 {TkpComputeStandardMenuGeometry - no entries} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.2 {TkpComputeStandardMenuGeometry - one entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "one"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.3 {TkpComputeStandardMenuGeometry - more than one entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.4 {TkpComputeStandardMenuGeometry - separator} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.5 {TkpComputeStandardMenuGeometry - tearoff entry} -constraints {
    unix nonUnixUserInteraction
} -setup {
    destroy .mb
} -body {
    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    catch {tk::MbPost .mb}
    list [update] [destroy .mb]
} -result {{} {}}
test winMenu-32.6 {TkpComputeStandardMenuGeometry - standard label geometry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.7 {TkpComputeStandardMenuGeometry - different font for entry} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -font "Helvetica 12"
    .m1 add command -label "test" -font "Courier 12"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.8 {TkpComputeStandardMenuGeometry - second entry larger} -constraints {

    win



} -setup {

    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.9 {TkpComputeStandardMenuGeometry - first entry larger} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test test"
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.10 {TkpComputeStandardMenuGeometry - accelerator} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "Ctrl+S"

    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.11 {TkpComputeStandardMenuGeometry - second accel larger} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "1"
    .m1 add command -label "test" -accel "1 1"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.12 {TkpComputeStandardMenuGeometry - second accel smaller} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test" -accel "1 1"
    .m1 add command -label "test" -accel "1"
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.13 {TkpComputeStandardMenuGeometry - indicator} -constraints {

    win
} -setup {
    destroy .m1
} -body {

    menu .m1
    .m1 add checkbutton -label test
    .m1 invoke 1


    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.14 {TkpComputeStandardMenuGeometry - second indicator less or equal} -constraints {
    testImageType win
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test winMenu-32.15 {TkpComputeStandardMenuGeometry - second indicator larger} -constraints {
    testImageType unix
} -setup {
    destroy .m1
    catch {image delete image1}
} -body {
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} -result {{} {} {}}
test winMenu-32.16 {TkpComputeStandardMenuGeometry - zero sized menus} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.17 {TkpComputeStandardMenuGeometry - first column bigger} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three -columnbreak 1
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.18 {TkpComputeStandardMenuGeometry - second column bigger} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    list [update idletasks] [destroy .m1]
} -result {{} {}}
test winMenu-32.19 {TkpComputeStandardMenuGeometry - three columns} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    .m1 add command -label four
    .m1 add command -label five -columnbreak 1
    .m1 add command -label six
    list [update idletasks] [destroy .m1]
} -result {{} {}}


test winMenu-33.1 {TkpNotifyTopLevelCreate - no menu yet} -constraints {
    win
} -setup {
    destroy .m1 .t2
} -body {
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [update idletasks] [destroy .t2]
} -result {{} {}}
test winMenu-33.2 {TkpNotifyTopLevelCreate - menu} -constraints win -setup {
    destroy .m1 .t2
} -body {
    menu .m1
    menu .m1.system
    .m1 add cascade -menu .m1.system
    .m1.system add separator
    .m1.system add command -label foo
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [update idletasks] [destroy .m1] [destroy .t2]
} -result {{} {} {}}


test winMenu-34.1 {TkpMenuInit called at boot time} -constraints {
    emptyTest win
} -body {}

# cleanup
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:






|
|



<
|


|
|
<
<
<
|
<
<
<
<
|
<
<
<
<


|
|
<

|
<
|

|
|
<

|
|
|
<




|

<
|
|
<

|
|
|
|
<




|

<
|
|
<





|

<
|
|
<

|
|
<
<
|
<




|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|
|
|
<


|

|
<
<
|
<







|
|
<
<
|
<





|
|
|
<




|
|
|
<



|
|
|
<




|
|
<
<
|
<



|
|
<
<
|
<



|
|
<
<
|
<



|
|
<
<
|
<



<
<
<
|
>
|
<



|
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<



|
|
|
<





|
|
<
<
|
<





|
|
<
<
|
<







|
|
<
<
|
<





|
|
<
<
|
<







|
|
<
<
|
<




|

<

<
|
|
<

|
|
|
|
<
<
<
<
<
<
<
<


|
|
<
<
|
<



|
|
<
<
|
<




|
|
|
<
<
|
<




|

<
|
|
<


|

<
|
<
<
|
<



|

<

<
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<


|
|




|




<

<
|
<
<
|
<



|
|
<
<
|
<



|
|
<
<
|
<



|
|
|
<
|
<



|
|
|
<
|
<




|

<
|
|
<




|
|
|
<





|
|
<
<
|
<





|

<
|
<
<

<
|
|
<


|
<
|
|
|
<


|
<
<
|

|
|
<


|
<
|
|
|
<


|
<
|
|
|
<


|
>
>
>
|
>
>
>
|

|
<
<
<
|
<

|
|
|

|
>
|
|
>
>
>
>
>
|
>
>

|
|
|
<
|

<
<
|
|
>
>
>
>
>
|
>
|
>
>
>
>
|
>
>





|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<





|
|
|
<






|
|
<
<
|
<





|

<
|
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
|
<
|
<



|

<
|
|
<




|

<
|
|
<




|

<
|
|
<
<
<
|
|
<

<
|
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|

<
|
|
<



|

<
|
<
<
|
<



|

<
|
<
<
|
<



|
|
<
<
|
<




|

<
|
<
<
|
<





|
|
<
<
|
<





|
|
<
<
|
<






|
>
|
|
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
<
<
|
<




|
|
|
<




|
|
<
<
|
<





|
|
<
<
|
<





|
|
<
<
|
<





|
|
|
<





|
|
<
<
|
<






|
|
<
<
|
<





|
|
|
<





|
|
<
<
|
<




|
|
|
<




|
|
|
<




|
|
|
<




|
|
<
<
|
<







|
|
|
<





|
|
|
<





|

<
|
<
<
|

<




|
|
|
<



|
|
|
<



|
|
|
<



|

<
|
|
<




|
|
|
<





|

<
|
<
<
|
<


|
|
<
<
|
<



|
|
<
<
|
<




|
|
<
<
|
<



|
|
<
<
|
<






|
|
|
<
|
<



|
|
|
<
|
<



|
|
>
|
>
>
>
|
>
|
<

|
|

|
|
<
<
|
<

|
<

|
|
<
<
|
<

|
>

|
|
<
<
|
<

|
|

|
|
<
<
|
<

|
|

|
|
>
|
<
|
|
>

|

>
>
|
|
|
|
<
|

<







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<


|
|
<
<
|
<





|
|
|
<
|
<





|
|
<
<
|
<








|

<
|
<
|
|
<



|
|
|
|








|

<
|
<
<





<
<
<
<
<
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15



16




17




18
19
20
21

22
23

24
25
26
27

28
29
30
31

32
33
34
35
36
37

38
39

40
41
42
43
44

45
46
47
48
49
50

51
52

53
54
55
56
57
58
59

60
61

62
63
64


65

66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100
101
102

103
104
105
106
107

108
109
110
111
112

113
114
115
116
117

118
119
120
121
122

123
124
125
126
127

128
129
130
131
132

133
134
135
136
137

138
139
140
141
142


143

144
145
146
147
148
149
150
151
152


153

154
155
156
157
158
159
160
161

162
163
164
165
166
167
168

169
170
171
172
173
174

175
176
177
178
179
180


181

182
183
184
185
186


187

188
189
190
191
192


193

194
195
196
197
198


199

200
201
202



203
204
205

206
207
208
209
210


211

212
213
214
215
216
217


218

219
220
221
222
223
224


225

226
227
228
229
230
231

232
233
234
235
236
237
238


239

240
241
242
243
244
245
246


247

248
249
250
251
252
253
254
255
256


257

258
259
260
261
262
263
264


265

266
267
268
269
270
271
272
273
274


275

276
277
278
279
280
281

282

283
284

285
286
287
288
289








290
291
292
293


294

295
296
297
298
299


300

301
302
303
304
305
306
307


308

309
310
311
312
313
314

315
316

317
318
319
320

321


322

323
324
325
326
327

328

329


330

331
332
333
334
335
336


337

338
339
340
341
342
343


344

345
346
347
348
349
350
351
352
353
354
355
356
357

358

359


360

361
362
363
364
365


366

367
368
369
370
371


372

373
374
375
376
377
378

379

380
381
382
383
384
385

386

387
388
389
390
391
392

393
394

395
396
397
398
399
400
401

402
403
404
405
406
407
408


409

410
411
412
413
414
415
416

417


418

419
420

421
422
423

424
425
426

427
428
429


430
431
432
433

434
435
436

437
438
439

440
441
442

443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458



459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480

481
482


483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505











































506


507

508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523


524

525
526
527
528
529
530
531

532
533

534
535
536
537
538
539


540

541
542
543
544
545
546


547

548
549
550
551
552
553


554

555
556
557
558
559
560
561

562

563
564
565
566
567

568
569

570
571
572
573
574
575

576
577

578
579
580
581
582
583

584
585



586
587

588

589
590

591
592
593
594
595
596


597

598
599
600
601
602
603


604

605
606
607
608
609
610

611
612

613
614
615
616
617

618


619

620
621
622
623
624

625


626

627
628
629
630
631


632

633
634
635
636
637
638

639


640

641
642
643
644
645
646
647


648

649
650
651
652
653
654
655


656

657
658
659
660
661
662
663
664
665
666

667

668
669
670
671
672
673


674

675
676
677
678
679
680


681

682
683
684
685
686
687


688

689
690
691
692
693
694
695

696
697
698
699
700
701


702

703
704
705
706
707
708
709


710

711
712
713
714
715
716
717


718

719
720
721
722
723
724
725
726

727
728
729
730
731
732
733


734

735
736
737
738
739
740
741
742


743

744
745
746
747
748
749
750
751

752
753
754
755
756
757
758


759

760
761
762
763
764
765
766

767
768
769
770
771
772
773

774
775
776
777
778
779
780

781
782
783
784
785
786


787

788
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805

806
807
808
809
810
811
812

813


814
815

816
817
818
819
820
821
822

823
824
825
826
827
828

829
830
831
832
833
834

835
836
837
838
839

840
841

842
843
844
845
846
847
848

849
850
851
852
853
854
855

856


857

858
859
860
861


862

863
864
865
866
867


868

869
870
871
872
873
874


875

876
877
878
879
880


881

882
883
884
885
886
887
888
889
890

891

892
893
894
895
896
897

898

899
900
901
902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917


918

919
920

921
922
923


924

925
926
927
928
929
930


931

932
933
934
935
936
937


938

939
940
941
942
943
944
945
946

947
948
949
950
951
952
953
954
955
956
957
958

959
960

961
962
963
964
965
966
967
968














969


970

971
972
973
974


975

976
977
978
979
980
981
982
983

984

985
986
987
988
989
990
991


992

993
994
995
996
997
998
999
1000
1001
1002

1003

1004
1005

1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

1023


1024
1025
1026
1027
1028





# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

test winMenu-1.1 {GetNewID} win {
    catch {destroy .m1}



    list [catch {menu .m1} msg] $msg [destroy .m1]




} {0 .m1 {}}




# Basically impossible to test menu IDs wrapping.

test winMenu-2.1 {FreeID} win {
    catch {destroy .m1}

    menu .m1
    list [catch {destroy .m1} msg] $msg

} {0 {}}

test winMenu-3.1 {TkpNewMenu} win {
    catch {destroy .m1}

    list [catch {menu .m1} msg] $msg [catch {destroy .m1} msg2] $msg2
} {0 .m1 0 {}}
test winMenu-3.2 {TkpNewMenu} win {
    catch {destroy .m1}

    . configure -menu ""
    menu .m1
    .m1 add command -label "foo"
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [catch {destroy .m1} msg2] $msg2
} {0 {} {} 0 {}}


test winMenu-4.1 {TkpDestroyMenu} win {
    catch {destroy .m1}

    menu .m1
    list [catch {destroy .m1} msg] $msg
} {0 {}}
test winMenu-4.2 {TkpDestroyMenu - help menu} win {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -menu .m1.system
    . configure -menu .m1
    list [catch {destroy .m1.system} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}


test winMenu-5.1 {TkpDestroyMenuEntry} win {
    catch {destroy .m1}

    . configure -menu ""
    menu .m1
    .m1 add command -label "test"
    update idletasks
    list [catch {.m1 delete 1} msg] $msg [destroy .m1]
} {0 {} {}}


test winMenu-6.1 {GetEntryText} win {
    catch {destroy .m1}

    list [catch {menu .m1} msg] $msg [destroy .m1]
} {0 .m1 {}}
test winMenu-6.2 {GetEntryText} {testImageType win} {


    catch {destroy .m1}

    catch {image delete image1}
    menu .m1
    image create test image1
    list [catch {.m1 add command -image image1} msg] $msg [destroy .m1] [image delete image1]
} {0 {} {} {}}
test winMenu-6.3 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -bitmap questhead} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.4 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.5 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "foo"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.6 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "This string has one & in it"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.7 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.8 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.9 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "foo" -accel "bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.10 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.11 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.12 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.13 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "foo" -accel "&bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.14 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "&bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.15 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-6.16 {GetEntryText} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} {0 {} {}}

test winMenu-7.1 {ReconfigureWindowsMenu - system menu item removal} win {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -menu .m1.system
    menu .m1.system
    .m1.system add command -label foo
    update idletasks
    .m1.system add command -label bar
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test winMenu-7.2 {ReconfigureWindowsMenu - menu item removal} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label Hello
    update idletasks
    .m1 add command -label foo
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.3 {ReconfigureWindowsMenu - zero items} win {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label Hello
    .m1 delete Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.4 {ReconfigureWindowsMenu - one item} win {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.5 {ReconfigureWindowsMenu - two items} win {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label One
    .m1 add command -label Two
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.6 {ReconfigureWindowsMenu - separator item} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add separator
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.7 {ReconfigureWindowsMenu - non-text item} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.8 {ReconfigureWindowsMenu - disabled item} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label Hello -state disabled
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.9 {ReconfigureWindowsMenu - non-selected checkbutton} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add checkbutton -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]



} {0 {} {}}
test winMenu-7.10 {ReconfigureWindowsMenu - non-selected radiobutton} win {
    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add radiobutton -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.11 {ReconfigureWindowsMenu - selected checkbutton} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add checkbutton -label Hello
    .m1 invoke Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.12 {ReconfigureWindowsMenu - selected radiobutton} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add radiobutton -label Hello
    .m1 invoke Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.13 {ReconfigureWindowsMenu - cascade missing} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-7.14 {ReconfigureWindowsMenu - cascade} win {
    catch {destroy .m1}

    catch {destroy .m2}
    menu .m1 -tearoff 0
    menu .m2
    .m1 add cascade -menu .m2 -label Hello
    list [catch {update idletasks} msg] $msg [destroy .m1] [destroy .m2]
} {0 {} {} {}}
test winMenu-7.15 {ReconfigureWindowsMenu - menubar without system menu} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.file
    menu .m1.file -tearoff 0
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test winMenu-7.16 {ReconfigureWindowsMenu - system menu already created} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    . configure -menu .m1
    update idletasks
    .m1.system add command -label Hello
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test winMenu-7.17 {ReconfigureWindowsMenu - system menu update pending} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test winMenu-7.18 {ReconfigureWindowsMenu - system menu update not pending} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add cascade -menu .m1.system
    menu .m1.system -tearoff 0
    .m1.system add command -label Hello
    update idletasks
    . configure -menu .m1
    list [catch {update idletasks} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}
test winMenu-7.19 {ReconfigureWindowsMenu - column break} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    list [catch {update idletasks} msg] $msg [destroy .m1]
} {0 {} {}}


#Don't know how to generate nested post menus

test winMenu-8.1 {TkpPostMenu} win {
    catch {destroy .m1}

    menu .m1 -postcommand "blork"
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]
} {1 {invalid command name "blork"} {}}
test winMenu-8.2 {TkpPostMenu} win {
    catch {destroy .m1}








    menu .m1 -postcommand "destroy .m1"
    list [.m1 post 40 40] [winfo exists .m1]
} {{} 0}
test winMenu-8.3 {TkpPostMenu - popup menu} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-8.3: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}
test winMenu-8.4 {TkpPostMenu - menu button} {win userInteraction} {


    catch {destroy .mb}

    menubutton .mb -text test -menu .mb.menu
    menu .mb.menu
    .mb.menu add command -label "winMenu-8.4 - Hit ESCAPE."
    pack .mb
    list [tk::MbPost .mb] [destroy .m1]
} {{} {}}
test winMenu-8.5 {TkpPostMenu - update not pending} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-8.5 - Hit ESCAPE."
    update idletasks
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]
} {0 {} {}}


test winMenu-9.1 {TkpMenuNewEntry} win {
    catch {destroy .m1}

    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} {0 {} {}}


test winMenu-10.1 {TkwinMenuProc} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-10.1: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}


# Can't generate a WM_INITMENU without a Tk menu yet.

test winMenu-11.1 {TkWinHandleMenuEvent - WM_INITMENU} {win userInteraction} {


    catch {destroy .m1}

    catch {unset foo}
    menu .m1 -postcommand "set foo test"
    .m1 add command -label "winMenu-11.1: Hit ESCAPE."
    list [.m1 post 40 40] [set foo] [unset foo] [destroy .m1]
} {test test {} {}}
test winMenu-11.2 {TkWinHandleMenuEvent - WM_COMMAND} {win userInteraction} {


    catch {destroy .m1}

    catch {unset foo}
    menu .m1
    .m1 add checkbutton -variable foo -label "winMenu-11.2: Please select this menu item."
    list [.m1 post 40 40] [update] [set foo] [unset foo] [destroy .m1]
} {{} {} 1 {} {}}
test winMenu-11.3 {TkWinHandleMenuEvent - WM_COMMAND} {win userInteraction} {


    catch {destroy .m1}

    catch {unset foo}
    proc bgerror {args} {
	global foo errorInfo
	set foo [list $args $errorInfo]
    }
    menu .m1
    .m1 add command -command {error 1} -label "winMenu-11.2: Please select this menu item."
    list [.m1 post 40 40] [update] [set foo] [unset foo] [destroy .m1]
} {{} {} {1 {1
    while executing
"error 1"
    (menu invoke)}} {} {}}


# Can't test WM_MENUCHAR

test winMenu-11.4 {TkWinHandleMenuEvent - WM_MEASUREITEM} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-11.3: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}
test winMenu-11.5 {TkWinHandleMenuEvent - WM_MEASUREITEM} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label "winMenu-11.4: Hit ESCAPE" -hidemargin 1
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}
test winMenu-11.6 {TkWinHandleMenuEvent - WM_DRAWITEM} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-11.5: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}
test winMenu-11.7 {TkWinHandleMenuEvent - WM_DRAWITEM - item disabled} \
	{win userInteraction} {

    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-11.6: Hit ESCAPE." -state disabled
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}
test winMenu-11.8 {TkWinHandleMenuEvent - WM_INITMENU - not pending} \
	{win userInteraction} {

    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label "winMenu-11.7: Hit ESCAPE"
    update idletasks
    list [catch {.m1 post 40 40} msg] $msg [destroy .m1]
} {0 {} {}}


test winMenu-12.1 {TkpSetWindowMenuBar} win {
    catch {destroy .m1}

    . configure -menu ""
    menu .m1
    .m1 add command -label foo
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [catch {destroy .m1} msg2] $msg2
} {0 {} {} 0 {}}
test winMenu-12.2 {TkpSetWindowMenuBar} win {
    catch {destroy .m1}

    . configure -menu ""
    menu .m1
    .m1 add command -label foo
    . configure -menu .m1
    list [catch {. configure -menu ""} msg] $msg [catch {destroy .m1} msg2] $msg2
} {0 {} 0 {}}
test winMenu-12.3 {TkpSetWindowMenuBar - no update pending} win {


    catch {destroy .m1}

    . configure -menu ""
    menu .m1 -tearoff 0
    .m1 add command -label foo
    update idletasks
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]
} {0 {} {} {}}


test winMenu-13.1 {TkpSetMainMenubar - nothing to do} {emptyTest win} {} {}




test winMenu-14.1 {GetMenuIndicatorGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test winMenu-14.2 {GetMenuIndicatorGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo -hidemargin 1
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]


} {0 {}}

test winMenu-15.1 {GetMenuAccelGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo -accel Ctrl+U
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test winMenu-15.2 {GetMenuAccelGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]

} {0 {}}
test winMenu-15.3 {GetMenuAccelGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]
} {0 {}}

test winMenu-16.1 {GetTearoffEntryGeometry} {win userInteraction} {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "winMenu-19.1: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}

test winMenu-17.1 {GetMenuSeparatorGeometry} win {



    catch {destroy .m1}

    menu .m1
    .m1 add separator
    list [catch {tk::TearOffMenu .m1 40 40}] [destroy .m1]
} {0 {}}

# Currently, the only callers to DrawWindowsSystemBitmap want things
# centered vertically, and either centered or right aligned horizontally.
test winMenu-18.1 {DrawWindowsSystemBitmap - center aligned} win {
    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-18.2 {DrawWindowsSystemBitmap - right aligned} win {
    catch {destroy .m1}
    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]

} {{} {}}



test winMenu-19.1 {DrawMenuEntryIndicator - not checkbutton or radiobutton} \
	win {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-19.2 {DrawMenuEntryIndicator - not selected} win {
    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-19.3 {DrawMenuEntryIndicator - checkbutton} win {
    catch {destroy .m1}
    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}











































test winMenu-19.4 {DrawMenuEntryIndicator - radiobutton} win {


    catch {destroy .m1}

    menu .m1
    .m1 add radiobutton -label foo
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-19.5 {DrawMenuEntryIndicator - disabled} win {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke foo
    .m1 entryconfigure foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-19.6 {DrawMenuEntryIndicator - indicator not on} win {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo -indicatoron 0
    .m1 invoke foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test winMenu-20.1 {DrawMenuEntryAccelerator - disabled} win {
    catch {destroy .m1}

    menu .m1 -disabledforeground red
    .m1 add command -label foo -accel "Ctrl+U" -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-20.2 {DrawMenuEntryAccelerator - normal text} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -accel "Ctrl+U"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-20.3 {DrawMenuEntryAccelerator - disabled, no disabledforeground} win {


    catch {destroy .m1}

    menu .m1 -disabledforeground ""
    .m1 add command -label foo -accel "Ctrl+U" -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-20.4 {DrawMenuEntryAccelerator - cascade, drawArrow true} win {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-20.5 {DrawMenuEntryAccelerator - cascade, drawArrow false} \
	{win userInteraction} {

    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label "winMenu-23.5: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}


test winMenu-21.1 {DrawMenuSeparator} win {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test winMenu-22.1 {DrawMenuUnderline} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -underline 0
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test winMenu-23.1 {Don't know how to test MenuKeyBindProc} \
	{win emptyTest} {} {}



test winMenu-24.1 {TkpInitializeMenuBindings called at boot time} \
	{win emptyTest} {} {}



test winMenu-25.1 {DrawMenuEntryLabel - normal} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-25.2 {DrawMenuEntryLabel - disabled with fg} win {


    catch {destroy .m1}

    menu .m1 -disabledforeground red
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-25.3 {DrawMenuEntryLabel - disabled with no fg} win {


    catch {destroy .m1}

    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test winMenu-26.1 {TkpComputeMenubarGeometry} win {
    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label File
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]
} {{} {} {}}


test winMenu-27.1 {DrawTearoffEntry} {win userInteraction} {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "winMenu-24.4: Hit ESCAPE."
    list [.m1 post 40 40] [destroy .m1]
} {{} {}}


test winMenu-28.1 {TkpConfigureMenuEntry - update pending} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} {0 {} {}}
test winMenu-28.2 {TkpConfigureMenuEntry - update not pending} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label One
    update idletasks
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} {0 {} {}}


test winMenu-29.1 {TkpDrawMenuEntry - gc for active and not strict motif} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.2 {TkpDrawMenuEntry - gc for active menu item with its own gc} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activeforeground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.3 {TkpDrawMenuEntry - gc for active and strict motif} win {


    catch {destroy .m1}

    menu .m1
    set tk_strictMotif 1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} {{} {} 0}
test winMenu-29.4 \
	{TkpDrawMenuEntry - gc for disabled with disabledfg and custom entry} \
	win {

    catch {destroy .m1}

    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled -background red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.5 {TkpDrawMenuEntry - gc for disabled with disabledFg} win {


    catch {destroy .m1}

    menu .m1 -disabledforeground blue
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.6 {TkpDrawMenuEntry - gc for disabled - no disabledFg} win {


    catch {destroy .m1}

    menu .m1 -disabledforeground ""
    .m1 add command -label foo -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.7 {TkpDrawMenuEntry - gc for normal - custom entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -foreground red
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.8 {TkpDrawMenuEntry - gc for normal} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.9 {TkpDrawMenuEntry - gc for indicator - custom entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo -selectcolor orange
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.10 {TkpDrawMenuEntry - gc for indicator} win {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label foo
    .m1 invoke 1
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.11 {TkpDrawMenuEntry - border - custom entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activebackground green
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.12 {TkpDrawMenuEntry - border} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.13 {TkpDrawMenuEntry - active border - strict motif} win {


    catch {destroy .m1}

    set tk_strictMotif 1
    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1] [set tk_strictMotif 0]
} {{} {} 0}
test winMenu-29.14 {TkpDrawMenuEntry - active border - custom entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -activeforeground yellow
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.15 {TkpDrawMenuEntry - active border} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    .m1 entryconfigure 1 -state active
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.16 {TkpDrawMenuEntry - font - custom entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo -font "Helvectica 72"
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.17 {TkpDrawMenuEntry - font} win {
    catch {destroy .m1}

    menu .m1 -font "Courier 72"
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.18 {TkpDrawMenuEntry - separator} win {
    catch {destroy .m1}

    menu .m1
    .m1 add separator
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.19 {TkpDrawMenuEntry - standard} win {
    catch {destroy .mb}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.20 {TkpDrawMenuEntry - disabled cascade item} win {


    catch {destroy .m1}

    menu .m1
    .m1 add cascade -label File -menu .m1.file
    menu .m1.file
    .m1.file add command -label foo
    .m1 entryconfigure File -state disabled
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.21 {TkpDrawMenuEntry - indicator} win {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label winMenu-31.20
    .m1 invoke winMenu-31.20
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-29.22 {TkpDrawMenuEntry - indicator} win {
    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label winMenu-31.21 -hidemargin 1
    .m1 invoke winMenu-31.21
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}


test winMenu-30.1 {GetMenuLabelGeometry - image} {testImageType win} {


    catch {destroy .m1}
    catch {image delete image1}

    menu .m1
    image create test image1
    .m1 add command -image image1
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}
test winMenu-30.2 {GetMenuLabelGeometry - bitmap} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -bitmap questhead
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-30.3 {GetMenuLabelGeometry - no text} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-30.4 {GetMenuLabelGeometry - text} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "This is a test."
    list [update idletasks] [destroy .m1]
} {{} {}}


test winMenu-31.1 {DrawMenuEntryBackground} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    list [update] [destroy .m1]
} {{} {}}
test winMenu-31.2 {DrawMenuEntryBackground} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label foo
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff activate 0
    list [update] [destroy .m1]
} {{} {}}


test winMenu-32.1 {TkpComputeStandardMenuGeometry - no entries} win {


    catch {destroy .m1}

    menu .m1
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.2 {TkpComputeStandardMenuGeometry - one entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "one"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.3 {TkpComputeStandardMenuGeometry - more than one entry} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "one"
    .m1 add command -label "two"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.4 {TkpComputeStandardMenuGeometry - separator} win {


    catch {destroy .m1}

    menu .m1
    .m1 add separator
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.5 {TkpComputeStandardMenuGeometry - tearoff entry} {unix nonUnixUserInteraction} {


    catch {destroy .m1}

    menubutton .mb -text "test" -menu .mb.m
    menu .mb.m
    .mb.m add command -label test
    pack .mb
    catch {tk::MbPost .mb}
    list [update] [destroy .mb]
} {{} {}}
test winMenu-32.6 {TkpComputeStandardMenuGeometry - standard label geometry} \
	win {

    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.7 {TkpComputeStandardMenuGeometry - different font for entry} \
	win {

    catch {destroy .m1}

    menu .m1 -font "Helvetica 12"
    .m1 add command -label "test" -font "Courier 12"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.8 {TkpComputeStandardMenuGeometry - second entry larger} win {
    catch {destroy .m1}
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.9 {TkpComputeStandardMenuGeometry - first entry larger} win {
    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test test"
    .m1 add command -label "test"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.10 {TkpComputeStandardMenuGeometry - accelerator} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "Ctrl+S"

    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.11 {TkpComputeStandardMenuGeometry - second accel larger} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "1"
    .m1 add command -label "test" -accel "1 1"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.12 {TkpComputeStandardMenuGeometry - second accel smaller} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label "test" -accel "1 1"
    .m1 add command -label "test" -accel "1"
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.13 {TkpComputeStandardMenuGeometry - indicator} win {


    catch {destroy .m1}

    menu .m1
    .m1 add checkbutton -label test
    .m1 invoke 1
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.14 \
	{TkpComputeStandardMenuGeometry - second indicator less or equal} \
	{testImageType win} {

    catch {destroy .m1}
    catch {image delete image1}
    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}
test winMenu-32.15 {TkpComputeStandardMenuGeometry - second indicator larger} \
	{testImageType unix} {

    catch {destroy .m1}
    catch {image delete image1}

    image create test image1
    menu .m1
    .m1 add checkbutton -image image1
    .m1 invoke 1
    .m1 add checkbutton -label test
    .m1 invoke 2
    list [update idletasks] [destroy .m1] [image delete image1]
} {{} {} {}}














test winMenu-32.16 {TkpComputeStandardMenuGeometry - zero sized menus} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.17 {TkpComputeStandardMenuGeometry - first column bigger} win {


    catch {destroy .m1}

    menu .m1
    .m1 add command -label one
    .m1 add command -label two
    .m1 add command -label three -columnbreak 1
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.18 {TkpComputeStandardMenuGeometry - second column bigger} \
	win {

    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    list [update idletasks] [destroy .m1]
} {{} {}}
test winMenu-32.19 {TkpComputeStandardMenuGeometry - three columns} win {


    catch {destroy .m1}

    menu .m1 -tearoff 0
    .m1 add command -label one
    .m1 add command -label two -columnbreak 1
    .m1 add command -label three
    .m1 add command -label four
    .m1 add command -label five -columnbreak 1
    .m1 add command -label six
    list [update idletasks] [destroy .m1]
} {{} {}}


test winMenu-33.1 {TkpNotifyTopLevelCreate - no menu yet} win {

    catch {destroy .t2}
    catch {destroy .m1}

    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [update idletasks] [destroy .t2]
} {{} {}}
test winMenu-33.2 {TkpNotifyTopLevelCreate - menu} win {
    catch {destroy .t2}
    catch {destroy .m1}
    menu .m1
    menu .m1.system
    .m1 add cascade -menu .m1.system
    .m1.system add separator
    .m1.system add command -label foo
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    list [update idletasks] [destroy .m1] [destroy .t2]
} {{} {} {}}


test winMenu-34.1 {TkpMenuInit called at boot time} {emptyTest win} {} {}



# cleanup
deleteWindows
cleanupTests
return





Changes to tests/winMsgbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test the Windows specific message box
#
# Copyright © 2007 Pat Thoyts <patthoyts@users.sourceforge.net>

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint getwindowinfo [expr {[llength [info command ::testgetwindowinfo]] > 0}]

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}


|


<
|







1
2
3
4
5

6
7
8
9
10
11
12
13
# This file is a Tcl script to test the Windows specific message box
#
# Copyright (c) 2007 Pat Thoyts <patthoyts@users.sourceforge.net>

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint getwindowinfo [expr {[llength [info command ::testgetwindowinfo]] > 0}]

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
    set a(childtext) $childtext
    set windowInfo [array get a]
    testwinevent $hwnd $button WM_COMMAND
}

# -------------------------------------------------------------------------

test winMsgbox-1.1 {tk_messageBox ok} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.0 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type ok -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ok}

test winMsgbox-1.2 {tk_messageBox okcancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.1 [pid]"
    after 100 [list GetWindowInfo $title 1]
    tk_messageBox -icon info -type okcancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ok}

test winMsgbox-1.3 {tk_messageBox okcancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.2 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type okcancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

test winMsgbox-1.4 {tk_messageBox yesno} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.3 [pid]"
    after 100 [list GetWindowInfo $title 6]
    tk_messageBox -icon info -type yesno -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {yes}

test winMsgbox-1.5 {tk_messageBox yesno} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.4 [pid]"
    after 100 [list GetWindowInfo $title 7]
    tk_messageBox -icon info -type yesno -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {no}

test winMsgbox-1.6 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.5 [pid]"
    after 100 [list GetWindowInfo $title 3]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {abort}

test winMsgbox-1.7 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.6 [pid]"
    after 100 [list GetWindowInfo $title 4]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {retry}

test winMsgbox-1.8 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.7 [pid]"
    after 100 [list GetWindowInfo $title 5]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ignore}

test winMsgbox-1.9 {tk_messageBox retrycancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.8 [pid]"
    after 100 [list GetWindowInfo $title 4]
    tk_messageBox -icon info -type retrycancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {retry}

test winMsgbox-1.10 {tk_messageBox retrycancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.9 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type retrycancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

test winMsgbox-1.11 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.10 [pid]"
    after 100 [list GetWindowInfo $title 6]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {yes}

test winMsgbox-1.12 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.11 [pid]"
    after 100 [list GetWindowInfo $title 7]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {no}

test winMsgbox-1.13 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.12 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

# -------------------------------------------------------------------------

test winMsgbox-2.1 {tk_messageBox message} -constraints {win getwindowinfo} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.0 [pid]"
    set message "message"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "message"]

test winMsgbox-2.2 {tk_messageBox message (long)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.1 [pid]"
    set message [string repeat Ab 80]
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok [string repeat Ab 80]]

test winMsgbox-2.3 {tk_messageBox message (unicode)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.2 [pid]"
    set message "Поиск страниц"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "Поиск страниц"]

test winMsgbox-2.4 {tk_messageBox message (empty)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.3 [pid]"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok ""]

# -------------------------------------------------------------------------

test winMsgbox-3.1 {tk_messageBox detail (sourceforge bug #1692927)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-3.0 [pid]"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title \
               -message Hello -detail "Pleased to meet you"]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "Hello\n\nPleased to meet you"]

test winMsgbox-3.2 {tk_messageBox detail (unicode)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-3.1 [pid]"
    set message "Поиск"
    set detail "страниц"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message -detail $detail]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "Поиск\n\nстраниц"]

# -------------------------------------------------------------------------

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 0}
}
cleanupTests
return

# Local variables:
# mode: tcl
# indent-tabs-mode: nil
# End:







|










|










|










|










|










|










|










|










|










|










|










|










|












|














|
















|







|






|

|















<
<
|
















|







|
|






|













34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    set a(childtext) $childtext
    set windowInfo [array get a]
    testwinevent $hwnd $button WM_COMMAND
}

# -------------------------------------------------------------------------

test winMsgbox-1.0 {tk_messageBox ok} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.0 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type ok -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ok}

test winMsgbox-1.1 {tk_messageBox okcancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.1 [pid]"
    after 100 [list GetWindowInfo $title 1]
    tk_messageBox -icon info -type okcancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ok}

test winMsgbox-1.2 {tk_messageBox okcancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.2 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type okcancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

test winMsgbox-1.3 {tk_messageBox yesno} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.3 [pid]"
    after 100 [list GetWindowInfo $title 6]
    tk_messageBox -icon info -type yesno -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {yes}

test winMsgbox-1.4 {tk_messageBox yesno} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.4 [pid]"
    after 100 [list GetWindowInfo $title 7]
    tk_messageBox -icon info -type yesno -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {no}

test winMsgbox-1.5 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.5 [pid]"
    after 100 [list GetWindowInfo $title 3]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {abort}

test winMsgbox-1.6 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.6 [pid]"
    after 100 [list GetWindowInfo $title 4]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {retry}

test winMsgbox-1.7 {tk_messageBox abortretryignore} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.7 [pid]"
    after 100 [list GetWindowInfo $title 5]
    tk_messageBox -icon info -type abortretryignore -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {ignore}

test winMsgbox-1.8 {tk_messageBox retrycancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.8 [pid]"
    after 100 [list GetWindowInfo $title 4]
    tk_messageBox -icon info -type retrycancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {retry}

test winMsgbox-1.9 {tk_messageBox retrycancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.9 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type retrycancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

test winMsgbox-1.10 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.10 [pid]"
    after 100 [list GetWindowInfo $title 6]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {yes}

test winMsgbox-1.11 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.11 [pid]"
    after 100 [list GetWindowInfo $title 7]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {no}

test winMsgbox-1.12 {tk_messageBox yesnocancel} -constraints {win getwindowinfo} -setup {
    wm iconify .
} -body {
    global windowInfo
    set title "winMsgbox-1.12 [pid]"
    after 100 [list GetWindowInfo $title 2]
    tk_messageBox -icon info -type yesnocancel -title $title -message Message
} -cleanup {
    wm deiconify .
} -result {cancel}

# -------------------------------------------------------------------------

test winMsgbox-2.0 {tk_messageBox message} -constraints {win getwindowinfo} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.0 [pid]"
    set message "message"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "message"]

test winMsgbox-2.1 {tk_messageBox message (long)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.1 [pid]"
    set message [string repeat Ab 80]
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok [string repeat Ab 80]]

test winMsgbox-2.2 {tk_messageBox message (unicode)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.2 [pid]"
    set message "\u041f\u043e\u0438\u0441\u043a\u0020\u0441\u0442\u0440\u0430\u043d\u0438\u0446"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "\u041f\u043e\u0438\u0441\u043a\u0020\u0441\u0442\u0440\u0430\u043d\u0438\u0446"]

test winMsgbox-2.3 {tk_messageBox message (empty)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.3 [pid]"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok ""]



test winMsgbox-3.0 {tk_messageBox detail (sourceforge bug #1692927)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-3.0 [pid]"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title \
               -message Hello -detail "Pleased to meet you"]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "Hello\n\nPleased to meet you"]

test winMsgbox-3.1 {tk_messageBox detail (unicode)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-3.1 [pid]"
    set message "\u041f\u043e\u0438\u0441\u043a"
    set detail "\u0441\u0442\u0440\u0430\u043d\u0438\u0446"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message -detail $detail]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "\u041f\u043e\u0438\u0441\u043a\n\n\u0441\u0442\u0440\u0430\u043d\u0438\u0446"]

# -------------------------------------------------------------------------

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 0}
}
cleanupTests
return

# Local variables:
# mode: tcl
# indent-tabs-mode: nil
# End:

Changes to tests/winSend.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Compute a script that will load Tk into a child interpreter.




|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Compute a script that will load Tk into a child interpreter.
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
test winSend-1.6 {Tk_SetAppName - safe interps} winSend {
    newApp testApp -safe
    list [catch {testApp eval send testApp {set foo a}} msg] $msg [interp delete testApp]
} {1 {invalid command name "send"} {}}

test winSend-2.1 {Tk_SendObjCmd - # of args} winSend {
    list [catch {send tktest} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test winSend-2.1a {Tk_SendObjCmd: arguments} winSend {
    list [catch {send -bogus tktest} msg] $msg
} {1 {bad option "-bogus": must be -async, -displayof, or --}}
test winSend-2.1b {Tk_SendObjCmd: arguments} winSend {
    list [catch {send -async bogus foo} msg] $msg
} {1 {no registered server named "bogus"}}
test winSend-2.1c {Tk_SendObjCmd: arguments} winSend {







|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
test winSend-1.6 {Tk_SetAppName - safe interps} winSend {
    newApp testApp -safe
    list [catch {testApp eval send testApp {set foo a}} msg] $msg [interp delete testApp]
} {1 {invalid command name "send"} {}}

test winSend-2.1 {Tk_SendObjCmd - # of args} winSend {
    list [catch {send tktest} msg] $msg
} {1 {wrong # args: should be "send ?options? interpName arg ?arg ...?"}}
test winSend-2.1a {Tk_SendObjCmd: arguments} winSend {
    list [catch {send -bogus tktest} msg] $msg
} {1 {bad option "-bogus": must be -async, -displayof, or --}}
test winSend-2.1b {Tk_SendObjCmd: arguments} winSend {
    list [catch {send -async bogus foo} msg] $msg
} {1 {no registered server named "bogus"}}
test winSend-2.1c {Tk_SendObjCmd: arguments} winSend {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
} {a}
test winSend-2.3 {Tk_SendObjCmd - sending to ourselves in a different interpreter} winSend {
    newApp testApp
    list [catch {send testApp {set foo b}} msg] $msg [interp delete testApp]
} {0 b {}}
test winSend-2.4 {Tk_SendObjCmd - sending to ourselves in a different interp with errors} winSend {
    newApp testApp
    list [catch {send testApp {expr {2 / 0}}} msg] $msg $errorCode $errorInfo [interp delete testApp]
} "1 {divide by zero} {ARITH DIVZERO {divide by zero}} {divide by zero\n    while executing\n\"expr {2 / 0}\"\n    invoked from within\n\"send testApp {expr {2 / 0}}\"} {}"
test winSend-2.5 {Tk_SendObjCmd - sending to another app async} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }







|
|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
} {a}
test winSend-2.3 {Tk_SendObjCmd - sending to ourselves in a different interpreter} winSend {
    newApp testApp
    list [catch {send testApp {set foo b}} msg] $msg [interp delete testApp]
} {0 b {}}
test winSend-2.4 {Tk_SendObjCmd - sending to ourselves in a different interp with errors} winSend {
    newApp testApp
    list [catch {send testApp {expr 2 / 0}} msg] $msg $errorCode $errorInfo [interp delete testApp]
} "1 {divide by zero} {ARITH DIVZERO {divide by zero}} {divide by zero\n    while executing\n\"expr 2 / 0\"\n    invoked from within\n\"send testApp {expr 2 / 0}\"} {}"
test winSend-2.5 {Tk_SendObjCmd - sending to another app async} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
test winSend-2.7 {Tk_SendObjCmd - sending to another app - error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [catch {send $interp {expr {2 / 0}}} msg] $msg $errorCode $errorInfo
} "1 {divide by zero} {ARITH DIVZERO {divide by zero}} {divide by zero\n    while executing\n\"expr {2 / 0}\"\n    invoked from within\n\"send \$interp {expr {2 / 0}}\"}"

test winSend-3.1 {TkGetInterpNames} winSend {
    set origLength [llength $currentInterps]
    set newLength [llength [winfo interps]]
    expr {($newLength - 2) == $origLength}
} 1

test winSend-4.1 {DeleteProc - changing name of app} winSend {
    newApp a
    list [a eval tk appname foo] [interp delete a]
} {foo {}}
test winSend-4.2 {DeleteProc - normal} winSend {
    newApp a
    list [interp delete a]
} {{}}

test winSend-5.1 {ExecuteRemoteObject - no error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [send $interp {send [tk appname] {expr {2 / 1}}}]
} 2
test winSend-5.2 {ExecuteRemoteObject - error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [catch {send $interp {send [tk appname] {expr {2 / 0}}}} msg] $msg
} {1 {divide by zero}}

test winSend-6.1 {SendDDEServer - XTYP_CONNECT} winSend {
    set foo "Hello, World"
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {







|
|





|

















|
|







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
test winSend-2.7 {Tk_SendObjCmd - sending to another app - error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [catch {send $interp {expr 2 / 0}} msg] $msg $errorCode $errorInfo
} "1 {divide by zero} {ARITH DIVZERO {divide by zero}} {divide by zero\n    while executing\n\"expr 2 / 0\"\n    invoked from within\n\"send \$interp {expr 2 / 0}\"}"

test winSend-3.1 {TkGetInterpNames} winSend {
    set origLength [llength $currentInterps]
    set newLength [llength [winfo interps]]
    expr {($newLength - 2) == $origLength}
} {1}

test winSend-4.1 {DeleteProc - changing name of app} winSend {
    newApp a
    list [a eval tk appname foo] [interp delete a]
} {foo {}}
test winSend-4.2 {DeleteProc - normal} winSend {
    newApp a
    list [interp delete a]
} {{}}

test winSend-5.1 {ExecuteRemoteObject - no error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [send $interp {send [tk appname] {expr 2 / 1}}]
} {2}
test winSend-5.2 {ExecuteRemoteObject - error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [catch {send $interp {send [tk appname] {expr 2 / 0}}} msg] $msg
} {1 {divide by zero}}

test winSend-6.1 {SendDDEServer - XTYP_CONNECT} winSend {
    set foo "Hello, World"
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    set foo 3
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "send [tk appname] {expr {$foo + 1}}"
    list [catch "send \{$interp\} \{$command\}" msg] $msg
} {0 4}
test winSend-6.7 {SendDDEServer - XTYP_EXECUTE} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "send [tk appname] {expr {4 / 2}}"
    list [catch "send \{$interp\} \{$command\}" msg] $msg
} {0 2}
test winSend-6.8 {SendDDEServer - XTYP_WILDCONNECT} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "dde services Tk {}"
    list [catch "send \{$interp\} \{$command\}"]
} 0

test winSend-7.1 {DDEExitProc} winSend {
    newApp testApp
    list [interp delete testApp]
} {{}}

test winSend-8.1 {SendDdeConnect} winSend {







|









|











|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    set foo 3
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "send [tk appname] {expr $foo + 1}"
    list [catch "send \{$interp\} \{$command\}" msg] $msg
} {0 4}
test winSend-6.7 {SendDDEServer - XTYP_EXECUTE} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "send [tk appname] {expr 4 / 2}"
    list [catch "send \{$interp\} \{$command\}" msg] $msg
} {0 2}
test winSend-6.8 {SendDDEServer - XTYP_WILDCONNECT} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "dde services Tk {}"
    list [catch "send \{$interp\} \{$command\}"]
} {0}

test winSend-7.1 {DDEExitProc} winSend {
    newApp testApp
    list [interp delete testApp]
} {{}}

test winSend-8.1 {SendDdeConnect} winSend {
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    list [catch {dde request} msg] $msg
} {1 {wrong # args: should be "dde request serviceName topicName value"}}
test winSend-10.7 {Tk_DDEObjCmd - services wrong num args} winSend {
    list [catch {dde services} msg] $msg
} {1 {wrong # args: should be "dde services serviceName topicName"}}
test winSend-10.8 {Tk_DDEObjCmd - null service name} winSend {
    list [catch {dde services {} {tktest #2}}]
} 0
test winSend-10.9 {Tk_DDEObjCmd - null topic name} winSend {
    list [catch {dde services {Tk} {}}]
} 0
test winSend-10.10 {Tk_DDEObjCmd - execute - nothing to execute} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }







|


|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    list [catch {dde request} msg] $msg
} {1 {wrong # args: should be "dde request serviceName topicName value"}}
test winSend-10.7 {Tk_DDEObjCmd - services wrong num args} winSend {
    list [catch {dde services} msg] $msg
} {1 {wrong # args: should be "dde services serviceName topicName"}}
test winSend-10.8 {Tk_DDEObjCmd - null service name} winSend {
    list [catch {dde services {} {tktest #2}}]
} {0}
test winSend-10.9 {Tk_DDEObjCmd - null topic name} winSend {
    list [catch {dde services {Tk} {}}]
} {0}
test winSend-10.10 {Tk_DDEObjCmd - execute - nothing to execute} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
	}
    }
    send $interp {set foo winSend-10.17}
    list [catch {dde request Tk $interp foo} msg] $msg
} {0 winSend-10.17}
test winSend-10.18 {Tk_DDEObjCmd - services} winSend {
    set currentService [list Tk [tk appname]]
    list [catch {dde services Tk {}} msg] [expr {[lsearch $msg $currentService] >= 0}]
} {0 1}

# Get rid of the other app and all of its interps

set newInterps [winfo interps]
while {[llength $newInterps] != [llength $currentInterps]} {
    foreach interp $newInterps {







|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
	}
    }
    send $interp {set foo winSend-10.17}
    list [catch {dde request Tk $interp foo} msg] $msg
} {0 winSend-10.17}
test winSend-10.18 {Tk_DDEObjCmd - services} winSend {
    set currentService [list Tk [tk appname]]
    list [catch {dde services Tk {}} msg] [expr [lsearch $msg $currentService] >= 0]
} {0 1}

# Get rid of the other app and all of its interps

set newInterps [winfo interps]
while {[llength $newInterps] != [llength $currentInterps]} {
    foreach interp $newInterps {

Changes to tests/winWm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18

19













20
21

22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# This file tests  is a Tcl script to test the procedures in the file
# tkWinWm.c.  It is organized in the standard fashion for Tcl tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1996 by Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]



test winWm-1.1 {TkWmMapWindow} -constraints win -setup {













    destroy .t
} -body {

    toplevel .t
    wm override .t 1
    wm geometry .t +0+0
    update
    list [winfo rootx .t] [winfo rooty .t]
} -cleanup {
    destroy .t

} -result {0 0}
test winWm-1.2 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm transient .t .
    update
    wm iconify .
    update
    wm deiconify .
    update
    wm iconify .t
} -cleanup {
    destroy .t

} -returnCodes error -result {can't iconify ".t": it is a transient}
test winWm-1.3 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    update
    toplevel .t2
    update
    expr {[winfo x .t] != [winfo x .t2]}
} -cleanup {
    destroy .t .t2
} -result 1

test winWm-1.4 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t +10+10
    update
    toplevel .t2
    wm geometry .t2 +40+10
    update
    list [winfo x .t] [winfo x .t2]
} -cleanup {
    destroy .t .t2

} -result {10 40}
test winWm-1.5 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm iconify .t
    update
    wm state .t

} -result {iconic}


test winWm-2.1 {TkpWmSetState} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm iconify .t
    update
    lappend result [wm state .t]
    wm deiconify .t
    update
    lappend result [wm state .t]
} -cleanup {
    destroy .t

} -result {normal iconic normal}
test winWm-2.2 {TkpWmSetState} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm withdraw .t
    update
    lappend result [wm state .t]
    wm iconify .t
    update
    lappend result [wm state .t]
    wm deiconify .t
    update
    lappend result [wm state .t]
} -cleanup {
    destroy .t

} -result {normal withdrawn iconic normal}
test winWm-2.3 {TkpWmSetState} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm state .t withdrawn
    update
    lappend result [wm state .t]
    wm state .t iconic
    update
    lappend result [wm state .t]
    wm state .t normal
    update
    lappend result [wm state .t]
} -cleanup {
    destroy .t

} -result {normal withdrawn iconic normal}
test winWm-2.4 {TkpWmSetState} -constraints win -setup {
    destroy .t
    set result {}
} -body {
    toplevel .t
    wm geometry .t 150x50+10+10
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm iconify .t
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm geometry .t 200x50+10+10
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm deiconify .t
    update
    lappend result [list [wm state .t] [wm geometry .t]]
} -cleanup {
    destroy .t

} -result {{normal 150x50+10+10} {iconic 150x50+10+10} {iconic 150x50+10+10} {normal 200x50+10+10}}


test winWm-3.1 {ConfigureTopLevel: window geometry propagation} -constraints {
    win
} -setup {
    destroy .t
} -body {
    toplevel .t
    wm geometry .t +0+0
    button .t.b
    pack .t.b
    update
    set x [winfo x .t.b]
    destroy .t
    toplevel .t
    wm geometry .t +0+0
    button .t.b
    update
    pack .t.b
    update
    expr {$x == [winfo x .t.b]}
} -cleanup {
    destroy .t
} -result 1


test winWm-4.1 {ConfigureTopLevel: menu resizing} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    frame .t.f -width 100 -height 50
    pack .t.f
    menu .t.m
    .t.m add command -label "thisisreallylong"
    .t configure -menu .t.m
    wm geometry .t -0-0
    update
    set menuheight [winfo y .t]
    .t.m add command -label "thisisreallylong"
    wm geometry .t -0-0
    update
    set menuheight [expr {$menuheight - [winfo y .t]}]
    destroy .t

    toplevel .t
    frame .t.f -width 150 -height 50 -background red
    pack .t.f
    wm geometry .t -0-0
    update
    set y [winfo y .t]
    menu .t.m
    .t.m add command -label foo
    .t configure -menu .t.m
    update
    expr {$y - [winfo y .t]  eq  $menuheight + 1}
} -cleanup {
    destroy .t
} -result 1


# This test works on 8.0p2 but has not worked on anything since 8.2.
# It would be very strange to have a windows application increase the size
# of the clientarea when a menu wraps so I believe this test to be wrong.
# Original result was {50 50 50} new result may depend on the default menu
# font
test winWm-5.1 {UpdateGeometryInfo: menu resizing} -constraints win -setup {







|
|



<
|


|
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>




|
<

>
|
|
<
<







|
<

>
|
|
<
<




|
<

|
>
|
<
<






|
<

>
|
|
<
<



|
>
|
|

|
<
<










<

>
|
|
<
<













<

>
|
|
<
<













<

>
|
|
<

<













<

>
|

<
|
<
<
<
<













|
<

|
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|










|
<

|
|







1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45


46
47
48
49
50
51
52
53

54
55
56
57


58
59
60
61
62

63
64
65
66


67
68
69
70
71
72
73

74
75
76
77


78
79
80
81
82
83
84
85
86


87
88
89
90
91
92
93
94
95
96

97
98
99
100


101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134

135

136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152

153




154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
















173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
# This file tests  is a Tcl script to test the procedures in the file
# tkWinWm.c.  It is organized in the standard fashion for Tcl tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# Measure the height of a single menu line

toplevel .t
frame .t.f -width 100 -height 50
pack .t.f
menu .t.m
.t.m add command -label "thisisreallylong"
.t configure -menu .t.m
wm geometry .t -0-0
update
set menuheight [winfo y .t]
.t.m add command -label "thisisreallylong"
wm geometry .t -0-0
update
set menuheight [expr {$menuheight - [winfo y .t]}]
destroy .t

test winWm-1.1 {TkWmMapWindow} win {
    toplevel .t
    wm override .t 1
    wm geometry .t +0+0
    update
    set result [list [winfo rootx .t] [winfo rooty .t]]

    destroy .t
    set result
} {0 0}
test winWm-1.2 {TkWmMapWindow} win {


    toplevel .t
    wm transient .t .
    update
    wm iconify .
    update
    wm deiconify .
    update
    catch {wm iconify .t} msg

    destroy .t
    set msg
} {can't iconify ".t": it is a transient}
test winWm-1.3 {TkWmMapWindow} win {


    toplevel .t
    update
    toplevel .t2
    update
    set result [expr {[winfo x .t] != [winfo x .t2]}]

    destroy .t .t2
    set result
} 1
test winWm-1.4 {TkWmMapWindow} win {


    toplevel .t
    wm geometry .t +10+10
    update
    toplevel .t2
    wm geometry .t2 +40+10
    update
    set result [list [winfo x .t] [winfo x .t2]]

    destroy .t .t2
    set result
} {10 40}
test winWm-1.5 {TkWmMapWindow} win {


    toplevel .t
    wm iconify .t
    update
    set result [wm state .t]
    destroy .t
    set result
} iconic

test winWm-2.1 {TkpWmSetState} win {


    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm iconify .t
    update
    lappend result [wm state .t]
    wm deiconify .t
    update
    lappend result [wm state .t]

    destroy .t
    set result
} {normal iconic normal}
test winWm-2.2 {TkpWmSetState} win {


    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm withdraw .t
    update
    lappend result [wm state .t]
    wm iconify .t
    update
    lappend result [wm state .t]
    wm deiconify .t
    update
    lappend result [wm state .t]

    destroy .t
    set result
} {normal withdrawn iconic normal}
test winWm-2.3 {TkpWmSetState} win {


    toplevel .t
    wm geometry .t 150x50+10+10
    update
    set result [wm state .t]
    wm state .t withdrawn
    update
    lappend result [wm state .t]
    wm state .t iconic
    update
    lappend result [wm state .t]
    wm state .t normal
    update
    lappend result [wm state .t]

    destroy .t
    set result
} {normal withdrawn iconic normal}
test winWm-2.4 {TkpWmSetState} win {

    set result {}

    toplevel .t
    wm geometry .t 150x50+10+10
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm iconify .t
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm geometry .t 200x50+10+10
    update
    lappend result [list [wm state .t] [wm geometry .t]]
    wm deiconify .t
    update
    lappend result [list [wm state .t] [wm geometry .t]]

    destroy .t
    set result
} {{normal 150x50+10+10} {iconic 150x50+10+10} {iconic 150x50+10+10} {normal 200x50+10+10}}


test winWm-3.1 {ConfigureTopLevel: window geometry propagation} win {




    toplevel .t
    wm geometry .t +0+0
    button .t.b
    pack .t.b
    update
    set x [winfo x .t.b]
    destroy .t
    toplevel .t
    wm geometry .t +0+0
    button .t.b
    update
    pack .t.b
    update
    set x [expr {$x == [winfo x .t.b]}]

    destroy .t
    set x
} 1

test winWm-4.1 {ConfigureTopLevel: menu resizing} win {
















    set result {}
    toplevel .t
    frame .t.f -width 150 -height 50 -background red
    pack .t.f
    wm geometry .t -0-0
    update
    set y [winfo y .t]
    menu .t.m
    .t.m add command -label foo
    .t configure -menu .t.m
    update
    set result [expr {$y - [winfo y .t]}]

    destroy .t
    set result
} [expr {$menuheight + 1}]

# This test works on 8.0p2 but has not worked on anything since 8.2.
# It would be very strange to have a windows application increase the size
# of the clientarea when a menu wraps so I believe this test to be wrong.
# Original result was {50 50 50} new result may depend on the default menu
# font
test winWm-5.1 {UpdateGeometryInfo: menu resizing} -constraints win -setup {
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    toplevel .t
    frame .t.f -width 150 -height 50 -background red
    pack .t.f
    wm geometry .t -0-0
    update
    set y [winfo rooty .t]
    lappend result [winfo height .t]
    menu .t.m -tearoff 1
    .t configure -menu .t.m
    .t.m add command -label foo
    .t.m add command -label "thisisreallylong"
    .t.m add command -label "thisisreallylong"
    update
    lappend result [winfo height .t]
    lappend result [expr {$y - [winfo rooty .t]}]
    destroy .t
    return $result
} -cleanup {
    destroy .t
} -result {50 50 0}

test winWm-6.1 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm attributes .t
} -cleanup {
    destroy .t
} -result {-alpha 1.0 -transparentcolor {} -disabled 0 -fullscreen 0 -toolwindow 0 -topmost 0}
test winWm-6.2 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm attributes .t -disabled
} -cleanup {
    destroy .t
} -result 0
test winWm-6.3 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    # This isn't quite the correct error message yet, but it works.
    toplevel .t
    wm attributes .t -foo
} -cleanup {







|








|



















|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
    toplevel .t
    frame .t.f -width 150 -height 50 -background red
    pack .t.f
    wm geometry .t -0-0
    update
    set y [winfo rooty .t]
    lappend result [winfo height .t]
    menu .t.m
    .t configure -menu .t.m
    .t.m add command -label foo
    .t.m add command -label "thisisreallylong"
    .t.m add command -label "thisisreallylong"
    update
    lappend result [winfo height .t]
    lappend result [expr {$y - [winfo rooty .t]}]
    destroy .t
    set result
} -cleanup {
    destroy .t
} -result {50 50 0}

test winWm-6.1 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm attributes .t
} -cleanup {
    destroy .t
} -result {-alpha 1.0 -transparentcolor {} -disabled 0 -fullscreen 0 -toolwindow 0 -topmost 0}
test winWm-6.2 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm attributes .t -disabled
} -cleanup {
    destroy .t
} -result {0}
test winWm-6.3 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    # This isn't quite the correct error message yet, but it works.
    toplevel .t
    wm attributes .t -foo
} -cleanup {
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
} -result {}

test winWm-9.0 "Bug #2799589 - delayed activation of destroyed window" -constraints win -setup {
    proc winwm90click {w} {
        if {![winfo ismapped $w]} { update }
        event generate $w <Enter>
        focus -force $w
        event generate $w <Button-1> -x 5 -y 5
        event generate $w <ButtonRelease-1> -x 5 -y 5
    }
    proc winwm90proc3 {} {
        global winwm90done winwm90check
        set w .sd
        toplevel $w
        pack [button $w.b -text "OK" -command {set winwm90check 1}]







|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
} -result {}

test winWm-9.0 "Bug #2799589 - delayed activation of destroyed window" -constraints win -setup {
    proc winwm90click {w} {
        if {![winfo ismapped $w]} { update }
        event generate $w <Enter>
        focus -force $w
        event generate $w <ButtonPress-1> -x 5 -y 5
        event generate $w <ButtonRelease-1> -x 5 -y 5
    }
    proc winwm90proc3 {} {
        global winwm90done winwm90check
        set w .sd
        toplevel $w
        pack [button $w.b -text "OK" -command {set winwm90check 1}]
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
} -result ok

test winWm-9.1 "delayed activation of grabbed destroyed window" -constraints win -setup {
    proc winwm91click {w} {
        if {![winfo ismapped $w]} { update }
        event generate $w <Enter>
        focus -force $w
        event generate $w <Button-1> -x 5 -y 5
        event generate $w <ButtonRelease-1> -x 5 -y 5
    }
    proc winwm91proc3 {} {
        global winwm91done winwm91check
        set w .sd
        toplevel $w
        pack [button $w.b -text "OK" -command {set winwm91check 1}]







|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
} -result ok

test winWm-9.1 "delayed activation of grabbed destroyed window" -constraints win -setup {
    proc winwm91click {w} {
        if {![winfo ismapped $w]} { update }
        event generate $w <Enter>
        focus -force $w
        event generate $w <ButtonPress-1> -x 5 -y 5
        event generate $w <ButtonRelease-1> -x 5 -y 5
    }
    proc winwm91proc3 {} {
        global winwm91done winwm91check
        set w .sd
        toplevel $w
        pack [button $w.b -text "OK" -command {set winwm91check 1}]
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm91$cmd {}
    }
    destroy .tx .t .sd
} -result ok

test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints failsOnUbuntu -setup {
    destroy .t
    toplevel .t
    set winwm92 {}
    frame .t.f -background blue -height 200 -width 200
    frame .t.f.x -background red -height 100 -width 100
} -body {
    pack .t.f.x







|







506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm91$cmd {}
    }
    destroy .tx .t .sd
} -result ok

test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints {failsOnUbuntu failsOnQuarz} -setup {
    destroy .t
    toplevel .t
    set winwm92 {}
    frame .t.f -background blue -height 200 -width 200
    frame .t.f.x -background red -height 100 -width 100
} -body {
    pack .t.f.x
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
    vwait ::winwm92
    foreach id $aid {
	after cancel $id
    }
    set winwm92
} -cleanup {
    destroy .t.f.x .t.f .t
    unset -nocomplain winwm92 aid id
} -result ok

destroy .t

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:








|











<
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

    vwait ::winwm92
    foreach id $aid {
	after cancel $id
    }
    set winwm92
} -cleanup {
    destroy .t.f.x .t.f .t
    unset -nocomplain winwm92 aid
} -result ok

destroy .t

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/window.test.

1
2
3
4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# This file is a Tcl script to test the procedures in the file
# tkWindow.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands



namespace import ::tk::test::loadTkCommand
update

# XXX This file is woefully incomplete.  Right now it only tests
# a few parts of a few procedures in tkWindow.c

# ----------------------------------------------------------------------

test window-1.1 {Tk_CreateWindowFromPath procedure, parent dead} -setup {
    destroy .t
} -body {
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }

    set x unchanged

    frame .t -width 100 -height 50
    place .t -x 10 -y 10
    bind .t <Destroy> {button .t.b -text hello; pack .t.b}
    update
    destroy .t
    update
    set x
} -cleanup {
    rename bgerror {}

} -result {{can't create window: parent has been destroyed} {can't create window: parent has been destroyed
    while executing
"button .t.b -text hello"
    (command bound to event)}}


# Most of the tests below don't produce meaningful results;  they
# will simply dump core if there are bugs.

test window-2.1 {Tk_DestroyWindow procedure, destroy handler deletes parent} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    frame .t.f  -width 200 -height 200 -relief raised -bd 2
    place .t.f -x 0 -y 0
    frame .t.f.f -width 100 -height 100 -relief raised -bd 2
    place .t.f.f -relx 1 -rely 1 -anchor se
    bind .t.f <Destroy> {destroy .t}
    update
    destroy .t.f
} -result {}
test window-2.2 {Tk_DestroyWindow procedure, destroy handler deletes parent} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    frame .t.f  -width 200 -height 200 -relief raised -bd 2
    place .t.f -x 0 -y 0
    frame .t.f.f -width 100 -height 100 -relief raised -bd 2
    place .t.f.f -relx 1 -rely 1 -anchor se
    bind .t.f.f <Destroy> {destroy .t}
    update
    destroy .t.f
} -result {}
test window-2.3 {Tk_DestroyWindow procedure, destroy handler deletes parent} -setup {
    destroy .f
} -body {
    frame .f -width 80 -height 120 -relief raised -bd 2
    place .f -relx 0.5 -rely 0.5 -anchor center
    toplevel .f.t -width 300 -height 200
    wm geometry .f.t +0+0
    frame .f.t.f  -width 200 -height 200 -relief raised -bd 2
    place .f.t.f -x 0 -y 0
    frame .f.t.f.f -width 100 -height 100 -relief raised -bd 2
    place .f.t.f.f -relx 1 -rely 1 -anchor se
    update
    destroy .f
} -result {}

test window-2.4 {Tk_DestroyWindow, cleanup half dead window at exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        update
        bind . <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {}}

test window-2.5 {Tk_DestroyWindow, cleanup half dead windows at exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t
        update
        bind .t <Destroy> exit
        destroy .t
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {}}

test window-2.6 {Tk_DestroyWindow, cleanup half dead windows at exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t
        update
        bind .t <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {}}

test window-2.7 {Tk_DestroyWindow, cleanup half dead windows at exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t
        toplevel .t.f
        update
        bind .t.f <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {}}

test window-2.8 {Tk_DestroyWindow, cleanup half dead windows at exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        toplevel .t3
        update
        bind .t3 <Destroy> {destroy .t2}
        bind .t2 <Destroy> {destroy .t1}
        bind .t1 <Destroy> {exit 0}
        destroy .t3
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {}}


test window-2.9 {Tk_DestroyWindow, Destroy bindings evaluated after exit} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        update
        bind .t2 <Destroy> {puts "Destroy .t2" ; exit 1}
        bind .t1 <Destroy> {puts "Destroy .t1" ; exit 0}
        destroy .t2
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {Destroy .t2
Destroy .t1}}

test window-2.10 {Tk_DestroyWindow, Destroy binding evaluated once} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        update
        bind . <Destroy> {
            puts "Destroy ."
            bind . <Destroy> {puts "Re-Destroy ."}
            exit 0
        }
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {Destroy .}}

test window-2.11 {Tk_DestroyWindow, don't reanimate a half-dead window} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        update
        bind .t1 <Destroy> {
            if {[catch {entry .t2.newchild}]} {
                puts YES
            } else {
                puts NO
            }
        }
        bind .t2 <Destroy> {exit}
        destroy .t2
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 YES}


test window-3.1 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    frame .t.f -bd 2 -relief raised
    testmenubar window .t .t.f
    update
    # If stacking order isn't handle properly, generates an X error.
} -cleanup {
    destroy .t
} -result {}
test window-3.2 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    pack [entry .t.e2]
    update
    frame .t.f -bd 2 -relief raised
    raise .t.f .t.e
    testmenubar window .t .t.f
    update
    # If stacking order isn't handled properly, generates an X error.
} -cleanup {
    destroy .t
} -result {}


test window-4.1 {Tk_NameToWindow procedure} -constraints {
    testmenubar
} -setup {
    destroy .t
} -body {
    winfo geometry .t
} -cleanup {
    destroy .t
} -returnCodes error -result {bad window path name ".t"}
test window-4.2 {Tk_NameToWindow procedure} -constraints {
    testmenubar
} -setup {
    destroy .t
} -body {
    frame .t -width 100 -height 50
    place .t -x 10 -y 10
    update
    winfo geometry .t
} -cleanup {
    destroy .t
} -returnCodes ok -result {100x50+10+10}


test window-5.1 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    pack [entry .t.e2]
    frame .t.f -bd 2 -relief raised
    testmenubar window .t .t.f
    update
    lower .t.e2 .t.f
    update
    # If stacking order isn't handled properly, generates an X error.
} -cleanup {
    destroy .t
} -result {}


# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:



|
|



<
|

>
>
>
|





<
<
|
<
<

|
|

<

>






<
<

>
|




<



|
<
<









|
|
<
<









|
|
<
<










|

|
|
<








|

|



|

|
|
<









|

|



|

|
|
<









|

|



|

|
|
<










|

|



|

|
|
<













|

|



|

>
|
|
<











|

|



|


|
|
<












|

|



|

|
|
<

















|

|



|

<
|
|
<
|
<







|
<
<
|
|
<
|
<










<
<
<
|

|
<
<
|
<
|
<
<
|
|
<
<
|
<



|
<
<
|

<
|
|
<
|
<










<
<
<
|




<
<
<
<
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19


20


21
22
23
24

25
26
27
28
29
30
31
32


33
34
35
36
37
38
39

40
41
42
43


44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250

251

252
253
254
255
256
257
258
259


260
261

262

263
264
265
266
267
268
269
270
271
272



273
274
275


276

277


278
279


280

281
282
283
284


285
286

287
288

289

290
291
292
293
294
295
296
297
298
299



300
301
302
303
304




# This file is a Tcl script to test the procedures in the file
# tkWindow.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands
testConstraint unthreaded [expr {
    (![info exist tcl_platform(threaded)] || !$tcl_platform(threaded))
}]
namespace import -force ::tk::test::loadTkCommand
update

# XXX This file is woefully incomplete.  Right now it only tests
# a few parts of a few procedures in tkWindow.c



test window-1.1 {Tk_CreateWindowFromPath procedure, parent dead} {


    proc bgerror msg {
	global x errorInfo
	set x [list $msg $errorInfo]
    }

    set x unchanged
    catch {destroy .t}
    frame .t -width 100 -height 50
    place .t -x 10 -y 10
    bind .t <Destroy> {button .t.b -text hello; pack .t.b}
    update
    destroy .t
    update


    rename bgerror {}
    set x
} {{can't create window: parent has been destroyed} {can't create window: parent has been destroyed
    while executing
"button .t.b -text hello"
    (command bound to event)}}


# Most of the tests below don't produce meaningful results;  they
# will simply dump core if there are bugs.

test window-2.1 {Tk_DestroyWindow procedure, destroy handler deletes parent} {


    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    frame .t.f  -width 200 -height 200 -relief raised -bd 2
    place .t.f -x 0 -y 0
    frame .t.f.f -width 100 -height 100 -relief raised -bd 2
    place .t.f.f -relx 1 -rely 1 -anchor se
    bind .t.f <Destroy> {destroy .t}
    update
    destroy .t.f
} {}
test window-2.2 {Tk_DestroyWindow procedure, destroy handler deletes parent} {


    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    frame .t.f  -width 200 -height 200 -relief raised -bd 2
    place .t.f -x 0 -y 0
    frame .t.f.f -width 100 -height 100 -relief raised -bd 2
    place .t.f.f -relx 1 -rely 1 -anchor se
    bind .t.f.f <Destroy> {destroy .t}
    update
    destroy .t.f
} {}
test window-2.3 {Tk_DestroyWindow procedure, destroy handler deletes parent} {


    frame .f -width 80 -height 120 -relief raised -bd 2
    place .f -relx 0.5 -rely 0.5 -anchor center
    toplevel .f.t -width 300 -height 200
    wm geometry .f.t +0+0
    frame .f.t.f  -width 200 -height 200 -relief raised -bd 2
    place .f.t.f -x 0 -y 0
    frame .f.t.f.f -width 100 -height 100 -relief raised -bd 2
    place .f.t.f.f -relx 1 -rely 1 -anchor se
    update
    destroy .f
} {}

test window-2.4 {Tk_DestroyWindow, cleanup half dead window at exit} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        update
        bind . <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {}}

test window-2.5 {Tk_DestroyWindow, cleanup half dead windows at exit} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        toplevel .t
        update
        bind .t <Destroy> exit
        destroy .t
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {}}

test window-2.6 {Tk_DestroyWindow, cleanup half dead windows at exit} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        toplevel .t
        update
        bind .t <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {}}

test window-2.7 {Tk_DestroyWindow, cleanup half dead windows at exit} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        toplevel .t
        toplevel .t.f
        update
        bind .t.f <Destroy> exit
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {}}

test window-2.8 {Tk_DestroyWindow, cleanup half dead windows at exit} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        toplevel .t3
        update
        bind .t3 <Destroy> {destroy .t2}
        bind .t2 <Destroy> {destroy .t1}
        bind .t1 <Destroy> {exit 0}
        destroy .t3
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {}}

# window-2.9 deadlocks threaded Tk [Bug 1715716]
test window-2.9 {Tk_DestroyWindow, Destroy bindings
        evaluated after exit} {unixOrWin unthreaded} {

    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        update
        bind .t2 <Destroy> {puts "Destroy .t2" ; exit 1}
        bind .t1 <Destroy> {puts "Destroy .t1" ; exit 0}
        destroy .t2
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {Destroy .t2
Destroy .t1}}

test window-2.10 {Tk_DestroyWindow, Destroy binding
        evaluated once} unixOrWin {

    set code [loadTkCommand]
    append code {
        update
        bind . <Destroy> {
            puts "Destroy ."
            bind . <Destroy> {puts "Re-Destroy ."}
            exit 0
        }
        destroy .
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 {Destroy .}}

test window-2.11 {Tk_DestroyWindow, don't reanimate a half-dead window} \
        unixOrWin {

    set code [loadTkCommand]
    append code {
        toplevel .t1
        toplevel .t2
        update
        bind .t1 <Destroy> {
            if {[catch {entry .t2.newchild}]} {
                puts YES
            } else {
                puts NO
            }
        }
        bind .t2 <Destroy> {exit}
        destroy .t2
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
	set error 1
    } else {
	set error 0
    }
    removeFile script
    list $error $msg
} {0 YES}


test window-3.1 {Tk_MakeWindowExist procedure, stacking order and menubars} \
	{unix testmenubar} {

    catch {destroy .t}

    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    frame .t.f -bd 2 -relief raised
    testmenubar window .t .t.f
    update
    # If stacking order isn't handle properly, generates an X error.
} {}


test window-3.2 {Tk_MakeWindowExist procedure, stacking order and menubars} \
	{unix testmenubar} {

    catch {destroy .t}

    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    pack [entry .t.e2]
    update
    frame .t.f -bd 2 -relief raised
    raise .t.f .t.e
    testmenubar window .t .t.f
    update
    # If stacking order isn't handled properly, generates an X error.



} {}

test window-4.1 {Tk_NameToWindow procedure} {testmenubar} {


    catch {destroy .t}

    list [catch {winfo geometry .t} msg] $msg


} {1 {bad window path name ".t"}}
test window-4.2 {Tk_NameToWindow procedure} {testmenubar} {


    catch {destroy .t}

    frame .t -width 100 -height 50
    place .t -x 10 -y 10
    update
    list [catch {winfo geometry .t} msg] $msg


} {0 100x50+10+10}


test window-5.1 {Tk_MakeWindowExist procedure, stacking order and menubars} \
	{unix testmenubar} {

    catch {destroy .t}

    toplevel .t -width 300 -height 200
    wm geometry .t +0+0
    pack [entry .t.e]
    pack [entry .t.e2]
    frame .t.f -bd 2 -relief raised
    testmenubar window .t .t.f
    update
    lower .t.e2 .t.f
    update
    # If stacking order isn't handled properly, generates an X error.



} {}

# cleanup
cleanupTests
return




Changes to tests/winfo.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224


225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393


394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436




437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# This file is a Tcl script to test out the "winfo" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:
# w -        Name of toplevel window to create.
# options -    Options for w, such as "-colormap new".

proc eatColors {w {options ""}} {
    destroy $w
    eval toplevel $w $options
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
        for {set x 0} {$x < 40} {incr x} {
            set color [format #%02x%02x%02x [expr {$x*6}] [expr {$y*30}] 0]
            $w.c create rectangle [expr {10*$x}] [expr {20*$y}] \
                [expr {10*$x + 10}] [expr {20*$y + 20}] -outline {} \
                -fill $color
        }
    }
    update
}



# XXX - This test file is woefully incomplete.  At present, only a
# few of the winfo options are tested.

# ----------------------------------------------------------------------

test winfo-1.1 {"winfo atom" command} -body {
    winfo atom
} -returnCodes error -result {wrong # args: should be "winfo atom ?-displayof window? name"}
test winfo-1.2 {"winfo atom" command} -body {
    winfo atom a b
} -returnCodes error -result {wrong # args: should be "winfo atom ?-displayof window? name"}
test winfo-1.3 {"winfo atom" command} -body {
    winfo atom a b c d
} -returnCodes error -result {wrong # args: should be "winfo atom ?-displayof window? name"}
test winfo-1.4 {"winfo atom" command} -body {
    winfo atom -displayof geek foo
} -returnCodes error -result {bad window path name "geek"}
test winfo-1.5 {"winfo atom" command} -body {
    winfo atom PRIMARY
} -result 1
test winfo-1.6 {"winfo atom" command} -body {
    winfo atom -displayof . PRIMARY
} -result 1


test winfo-2.1 {"winfo atomname" command} -body {
    winfo atomname
} -returnCodes error -result {wrong # args: should be "winfo atomname ?-displayof window? id"}
test winfo-2.2 {"winfo atomname" command} -body {
    winfo atomname a b
} -returnCodes error -result {wrong # args: should be "winfo atomname ?-displayof window? id"}
test winfo-2.3 {"winfo atomname" command} -body {
    winfo atomname a b c d
} -returnCodes error -result {wrong # args: should be "winfo atomname ?-displayof window? id"}
test winfo-2.4 {"winfo atomname" command} -body {
    winfo atomname -displayof geek foo
} -returnCodes error -result {bad window path name "geek"}
test winfo-2.5 {"winfo atomname" command} -body {
    winfo atomname 44215
} -returnCodes error -result {no atom exists with id "44215"}
test winfo-2.6 {"winfo atomname" command} -body {
    winfo atomname 2
} -result SECONDARY
test winfo-2.7 {"winfo atom" command} -body {
    winfo atomname -displayof . 2
} -result SECONDARY


test winfo-3.1 {"winfo colormapfull" command} -constraints {
    defaultPseudocolor8
} -body {
    winfo colormapfull
} -returnCodes error -result {wrong # args: should be "winfo colormapfull window"}
test winfo-3.2 {"winfo colormapfull" command} -constraints {
    defaultPseudocolor8
} -body {
    winfo colormapfull a b
} -returnCodes error -result {wrong # args: should be "winfo colormapfull window"}
test winfo-3.3 {"winfo colormapfull" command} -constraints {
    defaultPseudocolor8
} -body {
    winfo colormapfull foo
} -returnCodes error -result {bad window path name "foo"}
test winfo-3.4 {"winfo colormapfull" command} -constraints {
    unix defaultPseudocolor8
} -body {
    eatColors .t {-colormap new}
    set result [list [winfo colormapfull .] [winfo colormapfull .t]]
    .t.c delete 34
    lappend result [winfo colormapfull .t]
    .t.c create rectangle 30 30 80 80 -fill #441739
    lappend result [winfo colormapfull .t]
    .t.c create rectangle 40 40 90 90 -fill #ffeedd
    lappend result [winfo colormapfull .t]
    destroy .t.c
    lappend result [winfo colormapfull .t]
} -cleanup {
    destroy .t
} -result {0 1 0 0 1 0}






test winfo-4.1 {"winfo containing" command} -body {
    winfo containing 22
} -returnCodes error -result {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}
test winfo-4.2 {"winfo containing" command} -body {
    winfo containing a b c
} -returnCodes error -result {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}
test winfo-4.3 {"winfo containing" command} -body {
    winfo containing a b c d e
} -returnCodes error -result {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}
test winfo-4.4 {"winfo containing" command} -body {
    winfo containing -displayof geek 25 30
} -returnCodes error -result {bad window path name "geek"}
test winfo-4.5 {"winfo containing" command} -body {
} -setup {
    destroy .t
} -body {
    toplevel .t -width 550 -height 400
    frame .t.f -width 80 -height 60 -bd 2 -relief raised
    place .t.f -x 50 -y 50
    wm geom .t +0+0
    update

    raise .t
    winfo containing [winfo rootx .t.f] [winfo rooty .t.f]
} -cleanup {
    destroy .t
} -result .t.f
test winfo-4.6 {"winfo containing" command} -constraints {
    nonPortable
} -setup {
    destroy .t
} -body {
    toplevel .t -width 550 -height 400
    frame .t.f -width 80 -height 60 -bd 2 -relief raised
    place .t.f -x 50 -y 50
    wm geom .t +0+0
    update

    winfo containing [expr {[winfo rootx .t.f]-1}] [expr {[winfo rooty .t.f]-1}]
} -cleanup {
    destroy .t
} -result .t
test winfo-4.7 {"winfo containing" command} -setup {
    destroy .t
} -body {
    toplevel .t -width 550 -height 400
    frame .t.f -width 80 -height 60 -bd 2 -relief raised
    place .t.f -x 50 -y 50
    wm geom .t +0+0
    update

    set x [winfo containing -display .t.f [expr {[winfo rootx .t]+600}] \
        [expr {[winfo rooty .t.f]+450}]]
    expr {($x == ".") || ($x == "")}
} -cleanup {
    destroy .t
} -result 1


test winfo-5.1 {"winfo interps" command} -body {
    winfo interps a
} -returnCodes error -result {wrong # args: should be "winfo interps ?-displayof window?"}
test winfo-5.2 {"winfo interps" command} -body {
    winfo interps a b c
} -returnCodes error -result {wrong # args: should be "winfo interps ?-displayof window?"}
test winfo-5.3 {"winfo interps" command} -body {
    winfo interps -displayof geek
} -returnCodes error -result {bad window path name "geek"}
test winfo-5.4 {"winfo interps" command} -constraints unix -body {
    expr {[lsearch -exact [winfo interps] [tk appname]] >= 0}
} -result 1
test winfo-5.5 {"winfo interps" command} -constraints unix -body {
    expr {[lsearch -exact [winfo interps -displayof .] [tk appname]] >= 0}
} -result 1


test winfo-6.1 {"winfo exists" command} -body {
    winfo exists
} -returnCodes error -result {wrong # args: should be "winfo exists window"}
test winfo-6.2 {"winfo exists" command} -body {
    winfo exists a b
} -returnCodes error -result {wrong # args: should be "winfo exists window"}
test winfo-6.3 {"winfo exists" command} -body {
    winfo exists gorp
} -result 0
test winfo-6.4 {"winfo exists" command} -body {
    winfo exists .
} -result 1
test winfo-6.5 {"winfo exists" command} -setup {
    destroy .b
} -body {
    button .b -text "Test button"
    set x [winfo exists .b]
    pack .b
    update
    bind .b <Destroy> {lappend x [winfo exists .x]}
    destroy .b
    lappend x [winfo exists .x]
} -result {1 0 0}




test winfo-7.1 {"winfo pathname" command} -body {
    winfo pathname
} -returnCodes error -result {wrong # args: should be "winfo pathname ?-displayof window? id"}
test winfo-7.2 {"winfo pathname" command} -body {
    winfo pathname a b
} -returnCodes error -result {wrong # args: should be "winfo pathname ?-displayof window? id"}
test winfo-7.3 {"winfo pathname" command} -body {
    winfo pathname a b c d
} -returnCodes error -result {wrong # args: should be "winfo pathname ?-displayof window? id"}
test winfo-7.4 {"winfo pathname" command} -body {
    winfo pathname -displayof geek 25
} -returnCodes error -result {bad window path name "geek"}
test winfo-7.5 {"winfo pathname" command} -body {
    winfo pathname xyz
} -returnCodes error -result {expected integer but got "xyz"}
test winfo-7.6 {"winfo pathname" command} -body {
    winfo pathname 224
} -returnCodes error -result {window id "224" doesn't exist in this application}
test winfo-7.7 {"winfo pathname" command} -setup {
    destroy .b
    button .b -text "Help"
    update
} -body {
    winfo pathname -displayof .b [winfo id .]
} -cleanup {
    destroy .b
} -result {.}
test winfo-7.8 {"winfo pathname" command} -constraints {
    unix testwrapper
} -body {
    winfo pathname [testwrapper .]
} -result {}


test winfo-8.1 {"winfo pointerx" command} -setup {
    destroy .b
    button .b -text "Help"
    update
} -body {
    catch [winfo pointerx .b]
} -body {
    catch [winfo pointerx .b]
} -result 1
test winfo-8.2 {"winfo pointery" command} -setup {
    destroy .b
    button .b -text "Help"
    update
} -body {
    catch [winfo pointery .b]
} -body {
    catch [winfo pointerx .b]
} -result 1
test winfo-8.3 {"winfo pointerxy" command} -setup {
    destroy .b
    button .b -text "Help"
    update
} -body {
    catch [winfo pointerxy .b]
} -body {
    catch [winfo pointerx .b]
} -result 1


test winfo-9.1 {"winfo viewable" command} -body {
    winfo viewable
} -returnCodes error -result {wrong # args: should be "winfo viewable window"}
test winfo-9.2 {"winfo viewable" command} -body {
    winfo viewable foo
} -returnCodes error -result {bad window path name "foo"}
test winfo-9.3 {"winfo viewable" command} -body {
    winfo viewable .
} -result 1
test winfo-9.4 {"winfo viewable" command} -constraints failsOnUbuntu -body {
    wm iconify .
    winfo viewable .
} -cleanup {
    wm deiconify .
} -result 0
test winfo-9.5 {"winfo viewable" command} -setup {
    deleteWindows
} -body {
    frame .f1 -width 100 -height 100 -relief raised -bd 2
    place .f1 -x 0 -y 0
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    list [winfo viewable .f1] [winfo viewable .f1.f2]
} -cleanup {
    deleteWindows
} -result {1 1}
test winfo-9.6 {"winfo viewable" command} -setup {
    deleteWindows
} -body {
    frame .f1 -width 100 -height 100 -relief raised -bd 2
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    list [winfo viewable .f1] [winfo viewable .f1.f2]
} -cleanup {
    deleteWindows
} -result {0 0}
test winfo-9.7 {"winfo viewable" command} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    deleteWindows
} -body {
    frame .f1 -width 100 -height 100 -relief raised -bd 2
    place .f1 -x 0 -y 0
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    wm iconify .
    list [winfo viewable .f1] [winfo viewable .f1.f2]
} -cleanup {
    wm deiconify .
    deleteWindows
} -result {0 0}


test winfo-10.1 {"winfo visualid" command} -body {
    winfo visualid
} -returnCodes error -result {wrong # args: should be "winfo visualid window"}
test winfo-10.2 {"winfo visualid" command} -body {
    winfo visualid gorp
} -returnCodes error -result {bad window path name "gorp"}
test winfo-10.3 {"winfo visualid" command} -body {
    expr {2 + [winfo visualid .] - [winfo visualid .]}
} -result 2


test winfo-11.1 {"winfo visualid" command} -body {
    winfo visualsavailable
} -returnCodes error -result {wrong # args: should be "winfo visualsavailable window ?includeids?"}
test winfo-11.2 {"winfo visualid" command} -body {
    winfo visualsavailable gorp
} -returnCodes error -result {bad window path name "gorp"}
test winfo-11.3 {"winfo visualid" command} -body {
    winfo visualsavailable . includeids foo
} -returnCodes error -result {wrong # args: should be "winfo visualsavailable window ?includeids?"}
test winfo-11.4 {"winfo visualid" command} -body {
    llength [lindex [winfo visualsa .] 0]
} -result 2
test winfo-11.5 {"winfo visualid" command} -body {
    llength [lindex [winfo visualsa . includeids] 0]
} -result 3
test winfo-11.6 {"winfo visualid" command} -body {
    set x [lindex [lindex [winfo visualsa . includeids] 0] 2]
    expr {$x + 2 - $x}
} -result 2


test winfo-12.1 {GetDisplayOf procedure} -body {
    winfo atom - foo x
} -returnCodes error -result {wrong # args: should be "winfo atom ?-displayof window? name"}
test winfo-12.2 {GetDisplayOf procedure} -body {
    winfo atom -d bad_window x
} -returnCodes error -result {bad window path name "bad_window"}


# Some embedding tests
#
test winfo-13.1 {root coordinates of embedded toplevel} -setup {
    deleteWindows
} -body {
    frame .con -container 1
    pack .con -expand yes -fill both
    toplevel .emb -use [winfo id .con] -bd 0 -highlightthickness 0
    button .emb.b
    pack .emb.b -expand yes -fill both
    update



    list rootx [expr {[winfo rootx .emb] == [winfo rootx .con]}] \
        rooty [expr {[winfo rooty .emb] == [winfo rooty .con]}]
} -cleanup {
    deleteWindows
} -result {rootx 1 rooty 1}

# Windows does not destroy the container when an embedded window is
# destroyed.  Unix and macOS do destroy it.  See ticket [67384bce7d].
if {[tk windowingsystem] == "win32"} {
   set result_13_2 {embedded 0 container 1}
} else {
   set result_13_2 {embedded 0 container 0}
}
test winfo-13.2 {destroying embedded toplevel} -setup {
    deleteWindows
} -body {
    frame .con -container 1
    pack .con -expand yes -fill both
    toplevel .emb -use [winfo id .con] -bd 0 -highlightthickness 0
    button .emb.b
    pack .emb.b -expand yes -fill both
    update

    destroy .emb
    update
    list embedded [winfo exists .emb.b] container [winfo exists .con]

} -cleanup {
    deleteWindows
} -result $result_13_2

test winfo-13.3 {destroying container window} -setup {
    deleteWindows
} -body {
    frame .con -container 1
    pack .con -expand yes -fill both
    toplevel .emb -use [winfo id .con] -bd 0 -highlightthickness 0
    button .emb.b
    pack .emb.b -expand yes -fill both
    update

    destroy .con
    update
    list child [winfo exists .emb.b] parent [winfo exists .emb]




} -cleanup {
    deleteWindows
} -result {child 0 parent 0}

test winfo-13.4 {[winfo containing] with embedded windows} -setup {
    deleteWindows
} -body {
    frame .con -container 1
    pack .con -expand yes -fill both
    toplevel .emb -use [winfo id .con] -bd 0 -highlightthickness 0
    button .emb.b
    pack .emb.b -expand yes -fill both
    update

    button .b
    pack .b -expand yes -fill both
    update
    string compare .emb.b \
        [winfo containing [winfo rootx .emb.b] [winfo rooty .emb.b]]
} -cleanup {
    deleteWindows
} -result 0


test winfo-14.1 {usage} -body {
    winfo ismapped
} -returnCodes error -result {wrong # args: should be "winfo ismapped window"}

test winfo-14.2 {usage} -body {
    winfo ismapped . .
} -returnCodes error -result {wrong # args: should be "winfo ismapped window"}

test winfo-14.3 {initially unmapped} -setup {
    destroy .t
} -body {
    toplevel .t
    winfo ismapped .t
} -cleanup {
    destroy .t
} -result 0

test winfo-14.4 {mapped at idle time} -setup {
    destroy .t
} -body {
    toplevel .t
    update idletasks
    winfo ismapped .t
} -cleanup {
    destroy .t
} -result 1

deleteWindows
# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:



|
|
|



<
|


|
<






|
|


|





|
|
|
|
|
|



>
>




<
<
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

<
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|

<
|
<
<
|
|
|
<
<
|
|
|
<
<
|
|
|
<
<










|
|
<

|
|
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<


<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
<
|
|

|
|
<

<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|

|
|
|
|
|
|
|

|
|

|
|
<
<







|

|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<

<
<
|
|
<
<

<
|

|
<
<
<
<

|
<
<
|
<
<
<
<

|
<
<
|
<
<
<
<

|
<
<

<
|
|
|
|
|
|
|

|
|


|
|
<
|
<
<






<
<
|
|

<





<
<
|
|

<







|
|
|
<

<
|
|
|
|
|
|
|
|
<
|

|
|
|
|
|
|
|
|
|
|

|
|

|
|

|
<
|

|
|
|
|
|
|

<


|
<
|






|
>
>
|
|
<
<
<
|
|
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<


|
>
|
|
<

|
<
<
<
<
<
<
<
<
|


|
>
>
>
>
|
|
<

|
<
|
<
<
<
|
|


<
<
<
|
|
|
|
|
|

|
|
|

|
|
|

|
|
<


|
<
<

|
|
<



|
<
<





<
<
<
<
1
2
3
4
5
6
7
8
9

10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86


87
88
89


90
91
92


93
94
95


96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126









127
128


129
130









131


132

133








134
135
136
137
138

139

140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199




200


201
202


203

204
205
206




207
208


209




210
211


212




213
214


215

216
217
218
219
220
221
222
223
224
225
226
227
228
229

230


231
232
233
234
235
236


237
238
239

240
241
242
243
244


245
246
247

248
249
250
251
252
253
254
255
256
257

258

259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295

296
297
298

299
300
301
302
303
304
305
306
307
308
309
310



311
312



313

314
315









316
317
318
319
320
321

322
323








324
325
326
327
328
329
330
331
332
333

334
335

336



337
338
339
340



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360


361
362
363

364
365
366
367


368
369
370
371
372




# This file is a Tcl script to test out the "winfo" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]


# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:
# w -		Name of toplevel window to create.
# options -	Options for w, such as "-colormap new".

proc eatColors {w {options ""}} {
    catch {destroy $w}
    eval toplevel $w $options
    wm geom $w +0+0
    canvas $w.c -width 400 -height 200 -bd 0
    pack $w.c
    for {set y 0} {$y < 8} {incr y} {
	for {set x 0} {$x < 40} {incr x} {
	    set color [format #%02x%02x%02x [expr $x*6] [expr $y*30] 0]
	    $w.c create rectangle [expr 10*$x] [expr 20*$y] \
		    [expr 10*$x + 10] [expr 20*$y + 20] -outline {} \
		    -fill $color
	}
    }
    update
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

# XXX - This test file is woefully incomplete.  At present, only a
# few of the winfo options are tested.



test winfo-1.1 {"winfo atom" command} {
    list [catch {winfo atom} msg] $msg
} {1 {wrong # args: should be "winfo atom ?-displayof window? name"}}
test winfo-1.2 {"winfo atom" command} {
    list [catch {winfo atom a b} msg] $msg
} {1 {wrong # args: should be "winfo atom ?-displayof window? name"}}
test winfo-1.3 {"winfo atom" command} {
    list [catch {winfo atom a b c d} msg] $msg
} {1 {wrong # args: should be "winfo atom ?-displayof window? name"}}
test winfo-1.4 {"winfo atom" command} {
    list [catch {winfo atom -displayof geek foo} msg] $msg
} {1 {bad window path name "geek"}}
test winfo-1.5 {"winfo atom" command} {
    winfo atom PRIMARY
} 1
test winfo-1.6 {"winfo atom" command} {
    winfo atom -displayof . PRIMARY

} 1

test winfo-2.1 {"winfo atomname" command} {
    list [catch {winfo atomname} msg] $msg
} {1 {wrong # args: should be "winfo atomname ?-displayof window? id"}}
test winfo-2.2 {"winfo atomname" command} {
    list [catch {winfo atomname a b} msg] $msg
} {1 {wrong # args: should be "winfo atomname ?-displayof window? id"}}
test winfo-2.3 {"winfo atomname" command} {
    list [catch {winfo atomname a b c d} msg] $msg
} {1 {wrong # args: should be "winfo atomname ?-displayof window? id"}}
test winfo-2.4 {"winfo atomname" command} {
    list [catch {winfo atomname -displayof geek foo} msg] $msg
} {1 {bad window path name "geek"}}
test winfo-2.5 {"winfo atomname" command} {
    list [catch {winfo atomname 44215} msg] $msg
} {1 {no atom exists with id "44215"}}
test winfo-2.6 {"winfo atomname" command} {
    winfo atomname 2
} SECONDARY
test winfo-2.7 {"winfo atom" command} {
    winfo atomname -displayof . 2
} SECONDARY


test winfo-3.1 {"winfo colormapfull" command} defaultPseudocolor8 {


    list [catch {winfo colormapfull} msg] $msg
} {1 {wrong # args: should be "winfo colormapfull window"}}
test winfo-3.2 {"winfo colormapfull" command} defaultPseudocolor8 {


    list [catch {winfo colormapfull a b} msg] $msg
} {1 {wrong # args: should be "winfo colormapfull window"}}
test winfo-3.3 {"winfo colormapfull" command} defaultPseudocolor8 {


    list [catch {winfo colormapfull foo} msg] $msg
} {1 {bad window path name "foo"}}
test winfo-3.4 {"winfo colormapfull" command} {unix defaultPseudocolor8} {


    eatColors .t {-colormap new}
    set result [list [winfo colormapfull .] [winfo colormapfull .t]]
    .t.c delete 34
    lappend result [winfo colormapfull .t]
    .t.c create rectangle 30 30 80 80 -fill #441739
    lappend result [winfo colormapfull .t]
    .t.c create rectangle 40 40 90 90 -fill #ffeedd
    lappend result [winfo colormapfull .t]
    destroy .t.c
    lappend result [winfo colormapfull .t]
} {0 1 0 0 1 0}
catch {destroy .t}


toplevel .t -width 550 -height 400
frame .t.f -width 80 -height 60 -bd 2 -relief raised
place .t.f -x 50 -y 50
wm geom .t +0+0
update
test winfo-4.1 {"winfo containing" command} {
    list [catch {winfo containing 22} msg] $msg
} {1 {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}}
test winfo-4.2 {"winfo containing" command} {
    list [catch {winfo containing a b c} msg] $msg
} {1 {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}}
test winfo-4.3 {"winfo containing" command} {
    list [catch {winfo containing a b c d e} msg] $msg
} {1 {wrong # args: should be "winfo containing ?-displayof window? rootX rootY"}}
test winfo-4.4 {"winfo containing" command} {
    list [catch {winfo containing -displayof geek 25 30} msg] $msg
} {1 {bad window path name "geek"}}
test winfo-4.5 {"winfo containing" command} {









    raise .t
    winfo containing [winfo rootx .t.f] [winfo rooty .t.f]


} .t.f
test winfo-4.6 {"winfo containing" command} {nonPortable} {









    winfo containing [expr [winfo rootx .t.f]-1] [expr [winfo rooty .t.f]-1]


} .t

test winfo-4.7 {"winfo containing" command} {








    set x [winfo containing -display .t.f [expr [winfo rootx .t]+600] \
	    [expr [winfo rooty .t.f]+450]]
    expr {($x == ".") || ($x == "")}
} {1}
destroy .t



test winfo-5.1 {"winfo interps" command} {
    list [catch {winfo interps a} msg] $msg
} {1 {wrong # args: should be "winfo interps ?-displayof window?"}}
test winfo-5.2 {"winfo interps" command} {
    list [catch {winfo interps a b c} msg] $msg
} {1 {wrong # args: should be "winfo interps ?-displayof window?"}}
test winfo-5.3 {"winfo interps" command} {
    list [catch {winfo interps -displayof geek} msg] $msg
} {1 {bad window path name "geek"}}
test winfo-5.4 {"winfo interps" command} unix {
    expr [lsearch -exact [winfo interps] [tk appname]] >= 0
} {1}
test winfo-5.5 {"winfo interps" command} unix {
    expr [lsearch -exact [winfo interps -displayof .] [tk appname]] >= 0

} {1}

test winfo-6.1 {"winfo exists" command} {
    list [catch {winfo exists} msg] $msg
} {1 {wrong # args: should be "winfo exists window"}}
test winfo-6.2 {"winfo exists" command} {
    list [catch {winfo exists a b} msg] $msg
} {1 {wrong # args: should be "winfo exists window"}}
test winfo-6.3 {"winfo exists" command} {
    winfo exists gorp
} {0}
test winfo-6.4 {"winfo exists" command} {
    winfo exists .
} {1}
test winfo-6.5 {"winfo exists" command} {


    button .b -text "Test button"
    set x [winfo exists .b]
    pack .b
    update
    bind .b <Destroy> {lappend x [winfo exists .x]}
    destroy .b
    lappend x [winfo exists .x]
} {1 0 0}

catch {destroy .b}
button .b -text "Help"
update
test winfo-7.1 {"winfo pathname" command} {
    list [catch {winfo pathname} msg] $msg
} {1 {wrong # args: should be "winfo pathname ?-displayof window? id"}}
test winfo-7.2 {"winfo pathname" command} {
    list [catch {winfo pathname a b} msg] $msg
} {1 {wrong # args: should be "winfo pathname ?-displayof window? id"}}
test winfo-7.3 {"winfo pathname" command} {
    list [catch {winfo pathname a b c d} msg] $msg
} {1 {wrong # args: should be "winfo pathname ?-displayof window? id"}}
test winfo-7.4 {"winfo pathname" command} {
    list [catch {winfo pathname -displayof geek 25} msg] $msg
} {1 {bad window path name "geek"}}
test winfo-7.5 {"winfo pathname" command} {
    list [catch {winfo pathname xyz} msg] $msg
} {1 {expected integer but got "xyz"}}
test winfo-7.6 {"winfo pathname" command} {
    list [catch {winfo pathname 224} msg] $msg
} {1 {window id "224" doesn't exist in this application}}
test winfo-7.7 {"winfo pathname" command} {




    winfo pathname -displayof .b [winfo id .]


} {.}
test winfo-7.8 {"winfo pathname" command} {unix testwrapper} {


    winfo pathname [testwrapper .]

} {}

test winfo-8.1 {"winfo pointerx" command} {




    catch [winfo pointerx .b]
} 1


test winfo-8.2 {"winfo pointery" command} {




    catch [winfo pointery .b]
} 1


test winfo-8.3 {"winfo pointerxy" command} {




    catch [winfo pointerxy .b]
} 1




test winfo-9.1 {"winfo viewable" command} {
    list [catch {winfo viewable} msg] $msg
} {1 {wrong # args: should be "winfo viewable window"}}
test winfo-9.2 {"winfo viewable" command} {
    list [catch {winfo viewable foo} msg] $msg
} {1 {bad window path name "foo"}}
test winfo-9.3 {"winfo viewable" command} {
    winfo viewable .
} {1}
test winfo-9.4 {"winfo viewable" command} {failsOnUbuntu failsOnQuarz} {
    wm iconify .
    winfo viewable .
} {0}
wm deiconify .

test winfo-9.5 {"winfo viewable" command} {


    frame .f1 -width 100 -height 100 -relief raised -bd 2
    place .f1 -x 0 -y 0
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    list [winfo viewable .f1] [winfo viewable .f1.f2]


} {1 1}
test winfo-9.6 {"winfo viewable" command} {
    deleteWindows

    frame .f1 -width 100 -height 100 -relief raised -bd 2
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    list [winfo viewable .f1] [winfo viewable .f1.f2]


} {0 0}
test winfo-9.7 {"winfo viewable" command} {failsOnUbuntu failsOnQuarz} {
    deleteWindows

    frame .f1 -width 100 -height 100 -relief raised -bd 2
    place .f1 -x 0 -y 0
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    wm iconify .
    list [winfo viewable .f1] [winfo viewable .f1.f2]
} {0 0}
wm deiconify .
deleteWindows



test winfo-10.1 {"winfo visualid" command} {
    list [catch {winfo visualid} msg] $msg
} {1 {wrong # args: should be "winfo visualid window"}}
test winfo-10.2 {"winfo visualid" command} {
    list [catch {winfo visualid gorp} msg] $msg
} {1 {bad window path name "gorp"}}
test winfo-10.3 {"winfo visualid" command} {
    expr 2+[winfo visualid .]-[winfo visualid .]

} {2}

test winfo-11.1 {"winfo visualid" command} {
    list [catch {winfo visualsavailable} msg] $msg
} {1 {wrong # args: should be "winfo visualsavailable window ?includeids?"}}
test winfo-11.2 {"winfo visualid" command} {
    list [catch {winfo visualsavailable gorp} msg] $msg
} {1 {bad window path name "gorp"}}
test winfo-11.3 {"winfo visualid" command} {
    list [catch {winfo visualsavailable . includeids foo} msg] $msg
} {1 {wrong # args: should be "winfo visualsavailable window ?includeids?"}}
test winfo-11.4 {"winfo visualid" command} {
    llength [lindex [winfo visualsa .] 0]
} {2}
test winfo-11.5 {"winfo visualid" command} {
    llength [lindex [winfo visualsa . includeids] 0]
} {3}
test winfo-11.6 {"winfo visualid" command} {
    set x [lindex [lindex [winfo visualsa . includeids] 0] 2]
    expr $x + 2 - $x

} {2}

test winfo-12.1 {GetDisplayOf procedure} {
    list [catch {winfo atom - foo x} msg] $msg
} {1 {wrong # args: should be "winfo atom ?-displayof window? name"}}
test winfo-12.2 {GetDisplayOf procedure} {
    list [catch {winfo atom -d bad_window x} msg] $msg
} {1 {bad window path name "bad_window"}}


# Some embedding tests
#


proc MakeEmbed {} {
    frame .con -container 1
    pack .con -expand yes -fill both
    toplevel .emb -use [winfo id .con] -bd 0 -highlightthickness 0
    button .emb.b
    pack .emb.b -expand yes -fill both
    update
}
test winfo-13.1 {root coordinates of embedded toplevel} {
    MakeEmbed
    set z [expr [winfo rootx .emb] == [winfo rootx .con] && \
		[winfo rooty .emb] == [winfo rooty .con]]



    destroy .emb
    destroy .con



    set z

} {1}
test winfo-13.2 {destroying embedded toplevel} {









    destroy .emb
    update
    expr [winfo exists .emb.b] || [winfo exists .con]
} 0

deleteWindows


test winfo-13.3 {destroying container window} {








    MakeEmbed
    destroy .con
    update
    set z [expr [winfo exists .emb.b] || [winfo exists .emb]]
    catch {destroy .emb}
    catch {destroy .con}
    set z
} 0

deleteWindows


test winfo-13.4 {[winfo containing] with embedded windows} {

    MakeEmbed



    button .b
    pack .b -expand yes -fill both
    update




    set z [string compare \
	[winfo containing [winfo rootx .emb.b] [winfo rooty .emb.b]] .emb.b]
    catch {destroy .con}
    catch {destroy .emb}
    set z
} 0

test winfo-14.1 {usage} {
    list [catch {winfo ismapped} msg] $msg
} {1 {wrong # args: should be "winfo ismapped window"}}

test winfo-14.2 {usage} {
    list [catch {winfo ismapped . .} msg] $msg
} {1 {wrong # args: should be "winfo ismapped window"}}

test winfo-14.3 {initially unmapped} {
    catch {destroy .t}

    toplevel .t
    winfo ismapped .t
} 0



test winfo-14.4 {mapped at idle time} {
    catch {destroy .t}

    toplevel .t
    update idletasks
    winfo ismapped .t
} 1



deleteWindows
# cleanup
cleanupTests
return




Changes to tests/wm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out Tk's interactions with the window
# manager, including the "wm" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

# This file tests window manager interactions that work across platforms.
# Window manager tests that only work on a specific platform should be placed
# in unixWm.test or winWm.test.

package require tcltest 2.2




|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out Tk's interactions with the window
# manager, including the "wm" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

# This file tests window manager interactions that work across platforms.
# Window manager tests that only work on a specific platform should be placed
# in unixWm.test or winWm.test.

package require tcltest 2.2
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
proc stdWindow {} {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
}

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# [raise] and [lower] may return before the window manager has completed the
# operation. The raiseDelay procedure idles for a while to give the operation
# a chance to complete.
#

proc raiseDelay {} {
    after 100;
    update
    update idletasks
}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}







|
|







|
<
<







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39


40
41
42
43
44
45
46
proc stdWindow {} {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnQuarz [expr {![info exists ::env(MAC_CI)]}]

# [raise] and [lower] may return before the window manager has completed the
# operation. The raiseDelay procedure idles for a while to give the operation
# a chance to complete.
#

proc raiseDelay {} {
    after 100; update


}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, -transparent, or -type}


### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -modified, -notify, or -titlepath}


### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {
642
643
644
645
646
647
648
649


650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
test wm-geometry-1.2 {usage} -returnCodes error -body {
    wm geometry . _ _
} -result {wrong # args: should be "wm geometry window ?newGeometry?"}
test wm-geometry-1.3 {usage} -returnCodes error -body {
    wm geometry . bogus
} -result {bad geometry specifier "bogus"}

test wm-geometry-2.1 {setting values} -body {


    wm geometry .t 150x150+50+50
    update
    set result [wm geometry .t]
    wm geometry .t {}
    update
    return [list $result [string equal [wm geometry .t] $result]]
} -cleanup {
    unset result
} -match glob -result [list 150x150+*+* 0]


### wm grid ###
test wm-grid-1.1 {usage} -returnCodes error -body {
    wm grid
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-grid-1.2 {usage} -returnCodes error -body {







|
>
>


|


|
<
<
|







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655


656
657
658
659
660
661
662
663
test wm-geometry-1.2 {usage} -returnCodes error -body {
    wm geometry . _ _
} -result {wrong # args: should be "wm geometry window ?newGeometry?"}
test wm-geometry-1.3 {usage} -returnCodes error -body {
    wm geometry . bogus
} -result {bad geometry specifier "bogus"}

test wm-geometry-2.1 {setting values} -setup {
    set result {}
} -body {
    wm geometry .t 150x150+50+50
    update
    lappend result [wm geometry .t]
    wm geometry .t {}
    update
    lappend result [string equal [wm geometry .t] "150x150+50+50"]


} -result [list 150x150+50+50 0]


### wm grid ###
test wm-grid-1.1 {usage} -returnCodes error -body {
    wm grid
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-grid-1.2 {usage} -returnCodes error -body {
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
} -result {wrong # args: should be "wm iconbitmap window ?bitmap?"}
test wm-iconbitmap-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13 14
} -result {wrong # args: should be "wm iconbitmap window ?-default? ?image?"}
test wm-iconbitmap-1.3 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13
} -result {illegal option "12" must be "-default"}
test wm-iconbitmap-1.4 {usage} -constraints notAqua -returnCodes error -body {
    wm iconbitmap .t bad-bitmap
} -result {bitmap "bad-bitmap" not defined}

test wm-iconbitmap-2.1 {setting and reading values} -constraints notAqua -setup {
    set result {}
} -body {
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t hourglass
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t {}
    lappend result [wm iconbitmap .t]







|



|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
} -result {wrong # args: should be "wm iconbitmap window ?bitmap?"}
test wm-iconbitmap-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13 14
} -result {wrong # args: should be "wm iconbitmap window ?-default? ?image?"}
test wm-iconbitmap-1.3 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13
} -result {illegal option "12" must be "-default"}
test wm-iconbitmap-1.4 {usage} -returnCodes error -body {
    wm iconbitmap .t bad-bitmap
} -result {bitmap "bad-bitmap" not defined}

test wm-iconbitmap-2.1 {setting and reading values} -setup {
    set result {}
} -body {
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t hourglass
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t {}
    lappend result [wm iconbitmap .t]
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
test wm-iconify-2.3 {Misc errors} -body {
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2
} -result {can't iconify ".t2": it is an icon for ".t"}
# test embedded window for Windows
test wm-iconify-2.4.1 {Misc errors} -constraints win -setup {
    destroy .t2
} -body {
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify ".t2": the container does not support the request}
# test embedded window for other platforms
test wm-iconify-2.4.2 {Misc errors} -constraints !win -setup {
    destroy .t2
} -body {
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify ".t2": it is an embedded window}

test wm-iconify-3.1 {iconify behavior} -constraints failsOnUbuntu -body {
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
    lappend result [winfo ismapped .t2]
} -cleanup {
    destroy .t2
} -result {1 0}


### wm iconmask ###







|









|









|

|


|


|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
test wm-iconify-2.3 {Misc errors} -body {
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2
} -result {can't iconify .t2: it is an icon for .t}
# test embedded window for Windows
test wm-iconify-2.4.1 {Misc errors} -constraints win -setup {
    destroy .t2
} -body {
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify .t2: the container does not support the request}
# test embedded window for other platforms
test wm-iconify-2.4.2 {Misc errors} -constraints !win -setup {
    destroy .t2
} -body {
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify .t2: it is an embedded window}

test wm-iconify-3.1 {iconify behavior} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .t2
    wm geom .t2 -0+0
    update
    set result [winfo ismapped .t2]
    wm iconify .t2
    update
    lappend result [winfo ismapped .t2]
} -cleanup {
    destroy .t2
} -result {1 0}


### wm iconmask ###
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
test wm-iconphoto-1.3 {usage} -returnCodes error -body {
    wm iconphoto . notanimage
} -result {can't use "notanimage" as iconphoto: not a photo image}
test wm-iconphoto-1.4 {usage} -returnCodes error -body {
    # we currently have no return info
    wm iconphoto . -default
} -result {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}
test wm-iconphoto-1.5.1 {usage} -constraints aquaOrWin32 -returnCodes error -body {
    wm iconphoto . -default [image create photo -file {}]
} -match {glob} -result {failed to create an iconphoto with image *}
test wm-iconphoto-1.5.2 {usage} -constraints x11 -body {
    wm iconphoto . -default [image create photo -file {}]
} -result {}

# All other iconphoto tests are platform specific


### wm iconposition ###
test wm-iconposition-1.1 {usage} -returnCodes error -body {
    wm iconposition







<
<
<
<
<
<







872
873
874
875
876
877
878






879
880
881
882
883
884
885
test wm-iconphoto-1.3 {usage} -returnCodes error -body {
    wm iconphoto . notanimage
} -result {can't use "notanimage" as iconphoto: not a photo image}
test wm-iconphoto-1.4 {usage} -returnCodes error -body {
    # we currently have no return info
    wm iconphoto . -default
} -result {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}







# All other iconphoto tests are platform specific


### wm iconposition ###
test wm-iconposition-1.1 {usage} -returnCodes error -body {
    wm iconposition
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
    wm resizable .t bad 0
} -result {expected boolean value but got "bad"}
test wm-resizable-1.5 {usage} -returnCodes error -body {
    wm resizable .t 1 bad
} -result {expected boolean value but got "bad"}

test wm-resizable-2.1 {setting and reading values} {
    wm resizable .t 0 0
    set result [wm resizable .t]
    wm resizable .t 0 1
    lappend result [wm resizable .t]
    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]
} {0 0 {0 1} {1 0} {1 1}}


### wm sizefrom ###
test wm-sizefrom-1.1 {usage} -returnCodes error -body {
    wm sizefrom
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-sizefrom-1.2 {usage} -returnCodes error -body {







|

<
<




|







1241
1242
1243
1244
1245
1246
1247
1248
1249


1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
    wm resizable .t bad 0
} -result {expected boolean value but got "bad"}
test wm-resizable-1.5 {usage} -returnCodes error -body {
    wm resizable .t 1 bad
} -result {expected boolean value but got "bad"}

test wm-resizable-2.1 {setting and reading values} {
    wm resizable .t 0 1
    set result [wm resizable .t]


    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]
} {0 1 {1 0} {1 1}}


### wm sizefrom ###
test wm-sizefrom-1.1 {usage} -returnCodes error -body {
    wm sizefrom
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-sizefrom-1.2 {usage} -returnCodes error -body {
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-2.3 {stacking order} -body {
    toplevel .t ; update
    toplevel .t2 ; update
    raise .
    raiseDelay
    raise .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t .t2
} -result {.t . .t2}
test wm-stackorder-2.4 {stacking order} -body {







<







1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-2.3 {stacking order} -body {
    toplevel .t ; update
    toplevel .t2 ; update
    raise .

    raise .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t .t2
} -result {.t . .t2}
test wm-stackorder-2.4 {stacking order} -body {
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -constraints failsOnUbuntu -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm iconify .t1
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}







|







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm iconify .t1
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582

test wm-stackorder-4.1 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .t
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-4.2 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .t
    wm stackorder . isbelow .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-4.3 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isa .
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-4.4 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isb .
} -cleanup {
    destroy .t
} -result 1
deleteWindows

test wm-stackorder-5.1 {a menu is not a toplevel} -body {
    toplevel .t
    menu .t.m -type menubar
    .t.m add cascade -label "File"
    .t configure -menu .t.m
    update
    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
    overrideredirect toplevel on unix} -constraints {x11 failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-5.2.1 {A normal toplevel can be raised above an \
    overrideredirect toplevel on macOS or win} -constraints aquaOrWin32 -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-5.3 {An overrideredirect window\
        can be explicitly lowered} -constraints failsOnXQuarz -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
} -cleanup {
    destroy .t
} -result 1

test wm-stackorder-6.1 {An embedded toplevel does not appear in the \
	stacking order} -body {
    toplevel .real -container 1
    toplevel .embd -bg blue -use [winfo id .real]
    update
    wm stackorder .
} -cleanup {
    deleteWindows
} -result {. .real}


stdWindow

### wm title ###
test wm-title-1.1 {usage} -returnCodes error -body {
    wm title
} -result {wrong # args: should be "wm option window ?arg ...?"}







|






|







|







|














|
|

<








<
<
<
<
<
<
<
<
<
<
<
<

|

<









|
|







>







1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521

1522
1523
1524
1525
1526
1527
1528
1529












1530
1531
1532

1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

test wm-stackorder-4.1 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .t
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result {0}
test wm-stackorder-4.2 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .t
    wm stackorder . isbelow .t
} -cleanup {
    destroy .t
} -result {1}
test wm-stackorder-4.3 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isa .
} -cleanup {
    destroy .t
} -result {0}
test wm-stackorder-4.4 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isb .
} -cleanup {
    destroy .t
} -result {1}
deleteWindows

test wm-stackorder-5.1 {a menu is not a toplevel} -body {
    toplevel .t
    menu .t.m -type menubar
    .t.m add cascade -label "File"
    .t configure -menu .t.m
    update
    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-5.2 {A normal toplevel can't be\
        raised above an overrideredirect toplevel} -body {
    toplevel .t

    wm overrideredirect .t 1
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 0












test wm-stackorder-5.3 {An overrideredirect window\
        can be explicitly lowered} -body {
    toplevel .t

    wm overrideredirect .t 1
    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
} -cleanup {
    destroy .t
} -result 1

test wm-stackorder-6.1 {An embedded toplevel does not\
        appear in the stacking order} -body {
    toplevel .real -container 1
    toplevel .embd -bg blue -use [winfo id .real]
    update
    wm stackorder .
} -cleanup {
    deleteWindows
} -result {. .real}


stdWindow

### wm title ###
test wm-title-1.1 {usage} -returnCodes error -body {
    wm title
} -result {wrong # args: should be "wm option window ?arg ...?"}
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
} -result {t Apa {}}


### wm transient ###
test wm-transient-1.1 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t 1 2
} -result {wrong # args: should be "wm transient window ?window?"}
test wm-transient-1.2 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t foo
} -result {bad window path name "foo"}
test wm-transient-1.3 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient foo .t
} -result {bad window path name "foo"}
deleteWindows
test wm-transient-1.4 {usage} -returnCodes error -body {
    toplevel .top
    toplevel .subject
    wm transient .subject .top
    wm iconify .subject
} -cleanup {
    deleteWindows
} -result {can't iconify ".subject": it is a transient}
test wm-transient-1.5 {usage} -returnCodes error -body {
    toplevel .icon -bg blue
    toplevel .top







|










|

|







1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
} -result {t Apa {}}


### wm transient ###
test wm-transient-1.1 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t 1 2
} -result {wrong # args: should be "wm transient window ?master?"}
test wm-transient-1.2 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t foo
} -result {bad window path name "foo"}
test wm-transient-1.3 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient foo .t
} -result {bad window path name "foo"}
deleteWindows
test wm-transient-1.4 {usage} -returnCodes error -body {
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    wm iconify .subject
} -cleanup {
    deleteWindows
} -result {can't iconify ".subject": it is a transient}
test wm-transient-1.5 {usage} -returnCodes error -body {
    toplevel .icon -bg blue
    toplevel .top
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
    toplevel .icon -bg blue
    toplevel .top
    wm iconwindow .top .icon
    toplevel .dummy
    wm transient .dummy .icon
} -cleanup {
    deleteWindows
} -result {can't make ".icon" a container: it is an icon for .top}
test wm-transient-1.7 {usage} -returnCodes error -body {
    toplevel .top
    wm transient .top .top
} -cleanup {
    deleteWindows
} -result {can't set ".top" as container: would cause management loop}
test wm-transient-1.8 {usage} -returnCodes error -body {
    toplevel .t1
    toplevel .t2
    toplevel .t3
    wm transient .t2 .t1
    wm transient .t3 .t2
    wm transient .t1 .t3
} -cleanup {
    deleteWindows
} -result {can't set ".t3" as container: would cause management loop}
test wm-transient-1.9 {usage} -returnCodes error -body {
    toplevel .top
    frame .top.f
    wm transient .top .top.f
} -cleanup {
    deleteWindows
} -result {can't set ".top" as container: would cause management loop}

test wm-transient-2.1 {basic get/set of toplevel} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    lappend results [wm transient .subject]
    wm transient .subject .top
    lappend results [wm transient .subject]
    wm transient .subject {}
    lappend results [wm transient .subject]
} -cleanup {
    deleteWindows
} -result {{} .top {}}
test wm-transient-2.2 {first toplevel parent of non-toplevel container window is used} -body {
    toplevel .top
    frame .top.f
    toplevel .subject
    wm transient .subject .top.f
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {.top}

test wm-transient-3.1 {transient toplevel is withdrawn
        when mapped if toplevel is withdrawn} -body {
    toplevel .top
    wm withdraw .top
    update
    toplevel .subject
    wm transient .subject .top
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-3.2 {already mapped transient toplevel
        takes on withdrawn state of toplevel} -body {
    toplevel .top
    wm withdraw .top
    update
    toplevel .subject
    update
    wm transient .subject .top
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-3.3 {withdraw/deiconify on the toplevel
        also does a withdraw/deiconify on the transient} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .top
    wm withdraw .top
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .top
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0 normal 1}

test wm-transient-4.1 {transient toplevel is withdrawn
        when mapped if toplevel is iconic} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .top
    wm iconify .top
    update
    toplevel .subject
    wm transient .subject .top
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.2 {already mapped transient toplevel
        is withdrawn if toplevel is iconic} -constraints failsOnUbuntu -body {
    toplevel .top
    raiseDelay
    wm iconify .top
    update idletasks
    toplevel .subject
    update idletasks
    wm transient .subject .top
    update idletasks
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.3 {iconify/deiconify on the toplevel
        does a withdraw/deiconify on the transient} -constraints failsOnUbuntu -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update idletasks
    wm transient .subject .top
    wm iconify .top
    update idletasks
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .top
    update idletasks
    lappend results [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0 normal 1}

test wm-transient-5.1 {an error during transient command should not
        cause the map/unmap binding to be deleted} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .top
    # Expect a bad window path error here
    lappend results [catch {wm transient .subject .bad}]
    wm withdraw .top
    update
    lappend results [wm state .subject]
    wm deiconify .top
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {1 withdrawn normal}
test wm-transient-5.2 {remove transient property when toplevel
        is destroyed} -body {
    toplevel .top
    toplevel .subject
    wm transient .subject .top
    update
    destroy .top
    update
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {}
test wm-transient-5.3 {remove transient property from window
        that had never been mapped when toplevel is destroyed} -body {
    toplevel .top
    toplevel .subject
    wm transient .subject .top
    destroy .top
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {}

test wm-transient-6.1 {a withdrawn transient does not track
        state changes in the toplevel} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .top
    wm withdraw .subject
    wm withdraw .top
    wm deiconify .top
    # idle handler should not map the transient
    update
    wm state .subject
} -cleanup {
    deleteWindows
} -result {withdrawn}
test wm-transient-6.2 {a withdrawn transient does not track
        state changes in the toplevel} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .top
    wm withdraw .subject
    wm withdraw .top
    wm deiconify .top
    # idle handler should not map the transient
    update
    lappend results [wm state .subject]
    wm deiconify .subject
    lappend results [wm state .subject]
    wm withdraw .top
    lappend results [wm state .subject]
    wm deiconify .top
    # idle handler should map transient
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn normal withdrawn normal}
test wm-transient-6.3 {a withdrawn transient does not track
        state changes in the toplevel} -body {
    toplevel .top
    toplevel .subject
    update
    # withdraw before making window a transient
    wm withdraw .subject
    wm transient .subject .top
    wm withdraw .top
    wm deiconify .top
    # idle handler should not map the transient
    update
    wm state .subject
} -cleanup {
    deleteWindows
} -result {withdrawn}

# wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two toplevels"
# wm-transient-7.3 through 7.5 all caused panics on Unix in Tk 8.4b1.
# 7.1 and 7.2 added to catch (potential) future errors.
#
test wm-transient-7.1 {Destroying transient} -body {
    toplevel .t
    toplevel .transient
    wm transient .transient .t
    destroy .transient
    destroy .t
    # OK: the above did not cause a panic.
} -cleanup {
    deleteWindows
}
test wm-transient-7.2 {Destroying toplevel} -body {
    toplevel .top
    toplevel .transient
    wm transient .transient .top
    destroy .top
    wm transient .transient
} -cleanup {
    deleteWindows
} -result {}
test wm-transient-7.3 {Reassign transient, destroy old toplevel} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t1	;# Caused panic in 8.4b1
    destroy .t2
    destroy .transient
} -cleanup {
    deleteWindows
}
test wm-transient-7.4 {Reassign transient, destroy new toplevel} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1







|

|
|


|

|
<
<
<
<
<
<
<
<
<
<
|
|


|

|


|


|





|
|
|
|

|



|


|
|
|


|






|
|
|



|





|



|


|
|


|







|
|
|


|






|
|
<
|
|

|
|
|




|
|


|

|
|
|
|

|
|









|


|


|


|





|

|

|

|






|
|

|
|






|
|


|

|
|







|


|


|

|
|





|

|







|
|




|
|
|







|













|
|

|
|




|











|







1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622










1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
    toplevel .icon -bg blue
    toplevel .top
    wm iconwindow .top .icon
    toplevel .dummy
    wm transient .dummy .icon
} -cleanup {
    deleteWindows
} -result {can't make ".icon" a master: it is an icon for .top}
test wm-transient-1.7 {usage} -returnCodes error -body {
    toplevel .master
    wm transient .master .master
} -cleanup {
    deleteWindows
} -result {can't make ".master" its own master}
test wm-transient-1.8 {usage} -returnCodes error -body {
    toplevel .master










    frame .master.f
    wm transient .master .master.f
} -cleanup {
    deleteWindows
} -result {can't make ".master" its own master}

test wm-transient-2.1 {basic get/set of master} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .subject
    lappend results [wm transient .subject]
    wm transient .subject .master
    lappend results [wm transient .subject]
    wm transient .subject {}
    lappend results [wm transient .subject]
} -cleanup {
    deleteWindows
} -result {{} .master {}}
test wm-transient-2.2 {first toplevel parent of non-toplevel master is used} -body {
    toplevel .master
    frame .master.f
    toplevel .subject
    wm transient .subject .master.f
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {.master}

test wm-transient-3.1 {transient toplevel is withdrawn
        when mapped if master is withdrawn} -body {
    toplevel .master
    wm withdraw .master
    update
    toplevel .subject
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-3.2 {already mapped transient toplevel
        takes on withdrawn state of master} -body {
    toplevel .master
    wm withdraw .master
    update
    toplevel .subject
    update
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-3.3 {withdraw/deiconify on the master
        also does a withdraw/deiconify on the transient} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm withdraw .master
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0 normal 1}

test wm-transient-4.1 {transient toplevel is withdrawn
        when mapped if master is iconic} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .master
    wm iconify .master
    update
    toplevel .subject
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.2 {already mapped transient toplevel
        is withdrawn if master is iconic} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .master

    wm iconify .master
    update
    toplevel .subject
    update
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.3 {iconify/deiconify on the master
        does a withdraw/deiconify on the transient} -constraints {failsOnUbuntu failsOnQuarz} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm iconify .master
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0 normal 1}

test wm-transient-5.1 {an error during transient command should not
        cause the map/unmap binding to be deleted} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    # Expect a bad window path error here
    lappend results [catch {wm transient .subject .bad}]
    wm withdraw .master
    update
    lappend results [wm state .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {1 withdrawn normal}
test wm-transient-5.2 {remove transient property when master
        is destroyed} -body {
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    update
    destroy .master
    update
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {}
test wm-transient-5.3 {remove transient property from window
        that had never been mapped when master is destroyed} -body {
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    destroy .master
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {}

test wm-transient-6.1 {a withdrawn transient does not track
        state changes in the master} -body {
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm withdraw .subject
    wm withdraw .master
    wm deiconify .master
    # idle handler should not map the transient
    update
    wm state .subject
} -cleanup {
    deleteWindows
} -result {withdrawn}
test wm-transient-6.2 {a withdrawn transient does not track
        state changes in the master} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm withdraw .subject
    wm withdraw .master
    wm deiconify .master
    # idle handler should not map the transient
    update
    lappend results [wm state .subject]
    wm deiconify .subject
    lappend results [wm state .subject]
    wm withdraw .master
    lappend results [wm state .subject]
    wm deiconify .master
    # idle handler should map transient
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn normal withdrawn normal}
test wm-transient-6.3 {a withdrawn transient does not track
        state changes in the master} -body {
    toplevel .master
    toplevel .subject
    update
    # withdraw before making window a transient
    wm withdraw .subject
    wm transient .subject .master
    wm withdraw .master
    wm deiconify .master
    # idle handler should not map the transient
    update
    wm state .subject
} -cleanup {
    deleteWindows
} -result {withdrawn}

# wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two masters"
# wm-transient-7.3 through 7.5 all caused panics on Unix in Tk 8.4b1.
# 7.1 and 7.2 added to catch (potential) future errors.
#
test wm-transient-7.1 {Destroying transient} -body {
    toplevel .t
    toplevel .transient
    wm transient .transient .t
    destroy .transient
    destroy .t
    # OK: the above did not cause a panic.
} -cleanup {
    deleteWindows
}
test wm-transient-7.2 {Destroying master} -body {
    toplevel .t
    toplevel .transient
    wm transient .transient .t
    destroy .t
    wm transient .transient
} -cleanup {
    deleteWindows
} -result {}
test wm-transient-7.3 {Reassign transient, destroy old master} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t1	;# Caused panic in 8.4b1
    destroy .t2
    destroy .transient
} -cleanup {
    deleteWindows
}
test wm-transient-7.4 {Reassign transient, destroy new master} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
    destroy .transient
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1		;# so did this
} -cleanup {
    deleteWindows
}

test wm-transient-8.1 {transient to withdrawn window, Bug 1163496} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    deleteWindows
    set result {}
} -body {
    # Verifies that transients stay on top of their toplevels, even if they were
    # made transients when those toplevels were withdrawn.
    toplevel .t1; wm withdraw  .t1;     update
    toplevel .t2; wm transient .t2 .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    wm deiconify .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    raise .t1; update
    lappend result [lsearch -all -inline -glob [wm stackorder .] ".t?"]







|



|
|







1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
    destroy .transient
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1		;# so did this
} -cleanup {
    deleteWindows
}

test wm-transient-8.1 {transient to withdrawn window, Bug 1163496} -constraints {failsOnUbuntu failsOnQuarz} -setup {
    deleteWindows
    set result {}
} -body {
    # Verifies that transients stay on top of their masters, even if they were
    # made transients when those masters were withdrawn.
    toplevel .t1; wm withdraw  .t1;     update
    toplevel .t2; wm transient .t2 .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    wm deiconify .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    raise .t1; update
    lappend result [lsearch -all -inline -glob [wm stackorder .] ".t?"]
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
test wm-state-2.7 {state change before map} -body {
    toplevel .t
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.8 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.9 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}







|







|







1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
test wm-state-2.7 {state change before map} -body {
    toplevel .t
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.8 {state change after map} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.9 {state change after map} -constraints {failsOnUbuntu failsOnQuarz} -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
test wm-forget-1.1 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result 1
test wm-forget-1.2 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    update
    toplevel .parent.child
    wm forget .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result 1
test wm-forget-1.3 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    wm manage .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result 1
test wm-forget-1.4 "pack into unmapped toplevel causes crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    pack [button .parent.child.button -text Hello]
    after 250 {destroy .parent}
    tkwait window .parent
} -cleanup {
    deleteWindows
} -result {}

test wm-forget-2 {bug [e9112ef96e] - [wm forget] doesn't completely} -setup {
    catch {destroy .l .f.b .f}
    set res {}
    if {[tk windowingsystem] == "aqua"} {
	proc doUpdate {} {update idletasks}
    } else {
	proc doUpdate {} {update}
    }
} -body {
    label .l -text "Top Dot"
    frame .f
    button .f.b -text Hello -command "puts Hello!"
    pack .l -side top
    pack .f.b
    pack .f -side bottom
    set res [winfo manager .f]
    pack forget .f
    doUpdate
    lappend res [winfo manager .f]
    wm manage .f
    doUpdate
    lappend res [winfo manager .f]
    wm forget .f
    doUpdate
    lappend res [winfo manager .f]
} -cleanup {
    destroy .l .f.b .f
    unset res
} -result {pack {} wm {}}

# FIXME:

# Test delivery of virtual events to the WM. We could check to see if the
# window was raised after a button click for example. This sort of testing may
# not be possible.

##############################################################################







|








|








|











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279






























2280
2281
2282
2283
2284
2285
2286
test wm-forget-1.1 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result {1}
test wm-forget-1.2 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    update
    toplevel .parent.child
    wm forget .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result {1}
test wm-forget-1.3 "bug #2009788: forget toplevel can cause crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    wm manage .parent.child
    winfo exists .parent.child
} -cleanup {
    deleteWindows
}  -result {1}
test wm-forget-1.4 "pack into unmapped toplevel causes crash" -body {
    toplevel .parent
    toplevel .parent.child
    wm forget .parent.child
    pack [button .parent.child.button -text Hello]
    after 250 {destroy .parent}
    tkwait window .parent
} -cleanup {
    deleteWindows
} -result {}































# FIXME:

# Test delivery of virtual events to the WM. We could check to see if the
# window was raised after a button click for example. This sort of testing may
# not be possible.

##############################################################################

Changes to tests/xmfbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# xmfbox.test --
#
#	This file is a Tcl script to test the file dialog that's used
#	when the tk_strictMotif flag is set. Because the file dialog
#	runs in a modal loop, the only way to test it sufficiently is
#	to call the internal Tcl procedures in xmfbox.tcl directly.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

set testPWD [pwd]


catch {unset data foo}

proc cleanup {} {
    global testPWD

    set err0 [catch {
	    cd $testPWD
    } msg0]

    set err1 [catch {
	    if [file exists ./~nosuchuser1] {
	        file delete ./~nosuchuser1
	    }
    } msg1]

    set err2 [catch {
	    if [file exists ./~nosuchuser2] {
	        file delete ./~nosuchuser2
	    }
    } msg2]

    set err3 [catch {
	    if [file exists ./~nosuchuser3] {
	        file delete ./~nosuchuser3
	    }
    } msg3]

    set err4 [catch {
	    if [file exists ./~nosuchuser4] {
	        file delete ./~nosuchuser4
	    }
    } msg4]

    if {$err0 || $err1 || $err2 || $err3 || $err4} {
	    error [list $msg0 $msg1 $msg2 $msg3 $msg4]
    }
    catch {unset foo}
    destroy .foo
}

# ----------------------------------------------------------------------

test xmfbox-1.1 {tk::MotifFDialog_Create, -parent switch} -constraints {
    unix
} -setup {
    catch {unset foo}
} -body {
    set x [tk::MotifFDialog_Create foo open {-parent .}]
} -cleanup {
    destroy $x

} -result {.foo}

test xmfbox-1.2 {tk::MotifFDialog_Create, -parent switch} -constraints {
    unix
} -setup {
    catch {unset foo}
    deleteWindows
} -body {
    toplevel .bar
    wm geometry .bar +0+0
    set x [tk::MotifFDialog_Create foo open {-parent .bar}]
} -cleanup {
    destroy $x
    destroy .bar

}  -result {.bar.foo}


test xmfbox-2.1 {tk::MotifFDialog_InterpFilter, ~ in dir names} -constraints {
    unix
} -body {
    cleanup
    file mkdir ./~nosuchuser1
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} -result "$testPWD/~nosuchuser1 *"

test xmfbox-2.2 {tk::MotifFDialog_InterpFilter, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} -result "$testPWD ./~nosuchuser1"

test xmfbox-2.3 {tk::MotifFDialog_Update, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    tk::MotifFDialog_InterpFilter $x
    tk::MotifFDialog_Update $x
    $::tk::dialog::file::foo(fList) get end
} -result {~nosuchuser1}

test xmfbox-2.4 {tk::MotifFDialog_LoadFile, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    expr {$i >= 0}
} -result 1

test xmfbox-2.5 {tk::MotifFDialog_BrowseFList, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    $::tk::dialog::file::foo(sEnt) get
} -result "$testPWD/~nosuchuser1"

test xmfbox-2.6 {tk::MotifFDialog_ActivateFList, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    tk::MotifFDialog_ActivateFList $x
    list $::tk::dialog::file::foo(selectPath) \
	    $::tk::dialog::file::foo(selectFile) $tk::Priv(selectFilePath)
} -result "$testPWD ~nosuchuser1 $testPWD/~nosuchuser1"

# cleanup
cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:







|
|




<
|



>
>






|



|
|
|



|
|
|



|
|
|



|
|
|



|


|


<
<
|
<
<

<

<
|
>
|

|
<
<

<
<



<
|
|
>
|

<
|
<
<






|

|
<
<






|

|
<
<








|

|
<
<





|

|
<
<








|

|
<
<










|





<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


60


61

62

63
64
65
66
67


68


69
70
71

72
73
74
75
76

77


78
79
80
81
82
83
84
85
86


87
88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
114


115
116
117
118
119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141




# xmfbox.test --
#
#	This file is a Tcl script to test the file dialog that's used
#	when the tk_strictMotif flag is set. Because the file dialog
#	runs in a modal loop, the only way to test it sufficiently is
#	to call the internal Tcl procedures in xmfbox.tcl directly.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
# All rights reserved.

package require tcltest 2.2

eval tcltest::configure $argv
tcltest::loadTestedCommands

set testPWD [pwd]
catch {unset foo}

catch {unset data foo}

proc cleanup {} {
    global testPWD

    set err0 [catch {
	cd $testPWD
    } msg0]

    set err1 [catch {
	if [file exists ./~nosuchuser1] {
	    file delete ./~nosuchuser1
	}
    } msg1]

    set err2 [catch {
	if [file exists ./~nosuchuser2] {
	    file delete ./~nosuchuser2
	}
    } msg2]

    set err3 [catch {
	if [file exists ./~nosuchuser3] {
	    file delete ./~nosuchuser3
	}
    } msg3]

    set err4 [catch {
	if [file exists ./~nosuchuser4] {
	    file delete ./~nosuchuser4
	}
    } msg4]

    if {$err0 || $err1 || $err2 || $err3 || $err4} {
	error [list $msg0 $msg1 $msg2 $msg3 $msg4]
    }
    catch {unset foo}
    catch {destroy .foo}
}



test xmfbox-1.1 {tk::MotifFDialog_Create, -parent switch} unix {


    catch {unset foo}

    set x [tk::MotifFDialog_Create foo open {-parent .}]

    catch {destroy $x}
    set x
} .foo

test xmfbox-1.2 {tk::MotifFDialog_Create, -parent switch} unix {


    catch {unset foo}


    toplevel .bar
    wm geometry .bar +0+0
    set x [tk::MotifFDialog_Create foo open {-parent .bar}]

    catch {destroy $x}
    catch {destroy .bar}
    set x
} .bar.foo


test xmfbox-2.1 {tk::MotifFDialog_InterpFilter, ~ in dir names} unix {


    cleanup
    file mkdir ./~nosuchuser1
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} [list $testPWD/~nosuchuser1 *]

test xmfbox-2.2 {tk::MotifFDialog_InterpFilter, ~ in file names} unix {


    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} [list $testPWD ./~nosuchuser1]

test xmfbox-2.3 {tk::MotifFDialog_Update, ~ in file names} unix {


    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    tk::MotifFDialog_InterpFilter $x
    tk::MotifFDialog_Update $x
    $::tk::dialog::file::foo(fList) get end
} ~nosuchuser1

test xmfbox-2.4 {tk::MotifFDialog_LoadFile, ~ in file names} unix {


    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    expr {$i >= 0}
} 1

test xmfbox-2.5 {tk::MotifFDialog_BrowseFList, ~ in file names} unix {


    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    $::tk::dialog::file::foo(sEnt) get
} $testPWD/~nosuchuser1

test xmfbox-2.6 {tk::MotifFDialog_ActivateFList, ~ in file names} unix {


    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    tk::MotifFDialog_ActivateFList $x
    list $::tk::dialog::file::foo(selectPath) \
	    $::tk::dialog::file::foo(selectFile) $tk::Priv(selectFilePath)
} [list $testPWD ~nosuchuser1 $testPWD/~nosuchuser1]

# cleanup
cleanup
cleanupTests
return




Changes to unix/Makefile.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#
# This file is a Makefile for Tk.  If it has the name "Makefile.in"
# then it is a template for a Makefile;  to generate the actual Makefile,
# run "./configure", which is a configuration script generated by the
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.

# Current Tk version;  used in various names.

TCLVERSION		= @TCL_VERSION@
TCLPATCHL		= @TCL_PATCH_LEVEL@
VERSION 		= @TK_VERSION@
MAJOR_VERSION		= @TK_MAJOR_VERSION@
MINOR_VERSION		= @TK_MINOR_VERSION@
PATCH_LEVEL		= @TK_PATCH_LEVEL@
LOCALES			= @LOCALES@

#----------------------------------------------------------------










<







1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
#
# This file is a Makefile for Tk.  If it has the name "Makefile.in"
# then it is a template for a Makefile;  to generate the actual Makefile,
# run "./configure", which is a configuration script generated by the
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.

# Current Tk version;  used in various names.

TCLVERSION		= @TCL_VERSION@

VERSION 		= @TK_VERSION@
MAJOR_VERSION		= @TK_MAJOR_VERSION@
MINOR_VERSION		= @TK_MINOR_VERSION@
PATCH_LEVEL		= @TK_PATCH_LEVEL@
LOCALES			= @LOCALES@

#----------------------------------------------------------------
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# Directory from which applications will reference the library of Tcl
# scripts (note: you can set the TK_LIBRARY environment variable at
# run-time to override the compiled-in location):
TK_LIBRARY		= @TK_LIBRARY@

# Path to use at runtime to refer to LIB_INSTALL_DIR:
LIB_RUNTIME_DIR		= @LIB_RUNTIME_DIR@

# Directory in which to install the program wish:
BIN_INSTALL_DIR		= $(INSTALL_ROOT)$(bindir)

# Directory in which to install the .a or .so binary for the Tk library:
LIB_INSTALL_DIR		= $(INSTALL_ROOT)$(libdir)
DLL_INSTALL_DIR		= @DLL_INSTALL_DIR@







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# Directory from which applications will reference the library of Tcl
# scripts (note: you can set the TK_LIBRARY environment variable at
# run-time to override the compiled-in location):
TK_LIBRARY		= @TK_LIBRARY@

# Path to use at runtime to refer to LIB_INSTALL_DIR:
LIB_RUNTIME_DIR		= $(libdir)

# Directory in which to install the program wish:
BIN_INSTALL_DIR		= $(INSTALL_ROOT)$(bindir)

# Directory in which to install the .a or .so binary for the Tk library:
LIB_INSTALL_DIR		= $(INSTALL_ROOT)$(libdir)
DLL_INSTALL_DIR		= @DLL_INSTALL_DIR@
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Directory in which to install html documentation:
HTML_INSTALL_DIR	= $(INSTALL_ROOT)$(HTML_DIR)

# Directory in which to install the configuration file tkConfig.sh:
CONFIG_INSTALL_DIR	= $(INSTALL_ROOT)$(libdir)

# Directory in which to install the demo files:
DEMO_INSTALL_DIR	= $(INSTALL_ROOT)@DEMO_DIR@

# The directory containing the Tcl sources and headers appropriate
# for this version of Tk ("srcdir" will be replaced or has already
# been replaced by the configure script):
TCLDIR   = @TCL_SRC_DIR@
TCL_GENERIC_DIR		= $(TCLDIR)/generic








|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Directory in which to install html documentation:
HTML_INSTALL_DIR	= $(INSTALL_ROOT)$(HTML_DIR)

# Directory in which to install the configuration file tkConfig.sh:
CONFIG_INSTALL_DIR	= $(INSTALL_ROOT)$(libdir)

# Directory in which to install the demo files:
DEMO_INSTALL_DIR	= $(INSTALL_ROOT)$(TK_LIBRARY)/demos

# The directory containing the Tcl sources and headers appropriate
# for this version of Tk ("srcdir" will be replaced or has already
# been replaced by the configure script):
TCLDIR   = @TCL_SRC_DIR@
TCL_GENERIC_DIR		= $(TCLDIR)/generic

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
INSTALL			= $(SHELL) $(UNIX_DIR)/install-sh -c
INSTALL_PROGRAM		= ${INSTALL}
INSTALL_LIBRARY		= ${INSTALL}
INSTALL_DATA		= ${INSTALL} -m 644
INSTALL_DATA_DIR	= ${INSTALL} -d -m 755

# The symbol below provides support for dynamic loading and shared
# libraries.  See configure.ac for a description of what it means.
# The value of the symbol is normally set by the configure script.

SHLIB_CFLAGS		= @SHLIB_CFLAGS@ -DBUILD_tk

# To enable support for stubs in Tcl.
STUB_LIB_FILE		= @TK_STUB_LIB_FILE@

TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
#TK_STUB_LIB_FILE	= libtkstub.a








|


|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
INSTALL			= $(SHELL) $(UNIX_DIR)/install-sh -c
INSTALL_PROGRAM		= ${INSTALL}
INSTALL_LIBRARY		= ${INSTALL}
INSTALL_DATA		= ${INSTALL} -m 644
INSTALL_DATA_DIR	= ${INSTALL} -d -m 755

# The symbol below provides support for dynamic loading and shared
# libraries.  See configure.in for a description of what it means.
# The value of the symbol is normally set by the configure script.

SHLIB_CFLAGS		= @SHLIB_CFLAGS@

# To enable support for stubs in Tcl.
STUB_LIB_FILE		= @TK_STUB_LIB_FILE@

TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
#TK_STUB_LIB_FILE	= libtkstub.a

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

# Libraries to use when linking.  This definition is determined by the
# configure script.
LIBS = @LIBS@ $(X11_LIB_SWITCHES) @TCL_LIBS@
WISH_LIBS = $(TCL_LIB_SPEC) @LIBS@ $(X11_LIB_SWITCHES) @TCL_LIBS@ @EXTRA_WISH_LIBS@

# The symbols below provide support for dynamic loading and shared
# libraries.  See configure.ac for a description of what the
# symbols mean.  The values of the symbols are normally set by the
# configure script.  You shouldn't normally need to modify any of
# these definitions by hand.

STLIB_LD		= @STLIB_LD@
SHLIB_LD		= @SHLIB_LD@
SHLIB_LD_LIBS		= @SHLIB_LD_LIBS@
TK_SHLIB_LD_EXTRAS	= @TK_SHLIB_LD_EXTRAS@

# Additional search flags needed to find the various shared libraries
# at run-time.  The first symbol is for use when creating a binary
# with cc, and the second is for use when running ld directly.
CC_SEARCH_FLAGS	= @CC_SEARCH_FLAGS@
LD_SEARCH_FLAGS	= @LD_SEARCH_FLAGS@

# support for embedded libraries on Darwin / Mac OS X
DYLIB_INSTALL_DIR	= ${LIB_RUNTIME_DIR}

# support for building the Aqua resource file
TK_RSRC_FILE		= @TK_RSRC_FILE@
WISH_RSRC_FILE		= @WISH_RSRC_FILE@
REZ			= @REZ@
REZ_SWITCHES = @REZ_FLAGS@ -i $(GENERIC_DIR) -i $(TCL_GENERIC_DIR)

# support for Xft:
XFT_CFLAGS		= @XFT_CFLAGS@
XFT_LIBS		= @XFT_LIBS@

#----------------------------------------------------------------
# The information below is modified by the configure script when







|
















|
<
<
<
<
<
<







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287






288
289
290
291
292
293
294

# Libraries to use when linking.  This definition is determined by the
# configure script.
LIBS = @LIBS@ $(X11_LIB_SWITCHES) @TCL_LIBS@
WISH_LIBS = $(TCL_LIB_SPEC) @LIBS@ $(X11_LIB_SWITCHES) @TCL_LIBS@ @EXTRA_WISH_LIBS@

# The symbols below provide support for dynamic loading and shared
# libraries.  See configure.in for a description of what the
# symbols mean.  The values of the symbols are normally set by the
# configure script.  You shouldn't normally need to modify any of
# these definitions by hand.

STLIB_LD		= @STLIB_LD@
SHLIB_LD		= @SHLIB_LD@
SHLIB_LD_LIBS		= @SHLIB_LD_LIBS@
TK_SHLIB_LD_EXTRAS	= @TK_SHLIB_LD_EXTRAS@

# Additional search flags needed to find the various shared libraries
# at run-time.  The first symbol is for use when creating a binary
# with cc, and the second is for use when running ld directly.
CC_SEARCH_FLAGS	= @CC_SEARCH_FLAGS@
LD_SEARCH_FLAGS	= @LD_SEARCH_FLAGS@

# support for embedded libraries on Darwin / Mac OS X
DYLIB_INSTALL_DIR	= $(libdir)







# support for Xft:
XFT_CFLAGS		= @XFT_CFLAGS@
XFT_LIBS		= @XFT_LIBS@

#----------------------------------------------------------------
# The information below is modified by the configure script when
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

CC_SWITCHES_NO_STUBS = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} ${CFLAGS_WARNING} \
${SHLIB_CFLAGS} -I${TCL_GENERIC_DIR} -I${TCL_PLATFORM_DIR} ${AC_FLAGS} \
${PROTO_FLAGS} ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
${NO_DEPRECATED_FLAGS} @EXTRA_CC_SWITCHES@

CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @TCL_STUB_FLAGS@

APP_CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @EXTRA_APP_CC_SWITCHES@

DEPEND_SWITCHES = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} -I${TCL_GENERIC_DIR} \
-I${TCL_PLATFORM_DIR} ${AC_FLAGS} ${PROTO_FLAGS} ${SECURITY_FLAGS} \
${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} @EXTRA_CC_SWITCHES@







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

CC_SWITCHES_NO_STUBS = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} ${CFLAGS_WARNING} \
${SHLIB_CFLAGS} -I${TCL_GENERIC_DIR} -I${TCL_PLATFORM_DIR} ${AC_FLAGS} \
${PROTO_FLAGS} ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
${NO_DEPRECATED_FLAGS} @EXTRA_CC_SWITCHES@

CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) ${TCL_STUB_FLAGS}

APP_CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @EXTRA_APP_CC_SWITCHES@

DEPEND_SWITCHES = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} -I${TCL_GENERIC_DIR} \
-I${TCL_PLATFORM_DIR} ${AC_FLAGS} ${PROTO_FLAGS} ${SECURITY_FLAGS} \
${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} @EXTRA_CC_SWITCHES@
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	tkMenu.o tkMenubutton.o tkMenuDraw.o tkMessage.o \
	tkPanedWindow.o tkScale.o tkScrollbar.o

CANV_OBJS = tkCanvas.o tkCanvArc.o tkCanvBmap.o tkCanvImg.o \
	tkCanvLine.o tkCanvPoly.o tkCanvPs.o tkCanvText.o \
	tkCanvUtil.o tkCanvWind.o tkRectOval.o tkTrig.o

IMAGE_OBJS = tkImage.o tkImgBmap.o tkImgGIF.o tkImgPNG.o tkImgPPM.o \
	tkImgPhoto.o tkImgPhInstance.o tkImgListFormat.o tkImgSVGnano.o

TEXT_OBJS = tkText.o tkTextBTree.o tkTextDisp.o tkTextImage.o tkTextIndex.o \
	tkTextMark.o tkTextTag.o tkTextWind.o

# either tkUnixFont.o (default) or tkUnixRFont.o (if --enable-xft)
#
FONT_OBJS = @UNIX_FONT_OBJS@

GENERIC_OBJS = tk3d.o tkArgv.o tkAtom.o tkBind.o tkBitmap.o tkBusy.o \
	tkClipboard.o \
	tkCmds.o tkColor.o tkConfig.o tkConsole.o tkCursor.o tkError.o \
	tkEvent.o tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o \
	tkGrid.o tkMain.o tkObj.o tkOldConfig.o tkOption.o tkPack.o \
	tkPkgConfig.o tkPlace.o	tkSelect.o tkStyle.o tkUndo.o tkUtil.o \
	tkVisual.o tkWindow.o

TTK_OBJS = \
	ttkBlink.o ttkButton.o ttkCache.o ttkClamTheme.o ttkClassicTheme.o \
	ttkDefaultTheme.o ttkElements.o ttkEntry.o ttkFrame.o ttkImage.o \
	ttkInit.o ttkLabel.o ttkLayout.o ttkManager.o ttkNotebook.o \
	ttkPanedwindow.o ttkProgress.o ttkScale.o ttkScrollbar.o ttkScroll.o \
	ttkSeparator.o ttkSquare.o ttkState.o \
	ttkTagSet.o ttkTheme.o ttkTrace.o ttkTrack.o ttkTreeview.o \
	ttkWidget.o ttkStubInit.o

STUB_OBJS = tkStubInit.o

STUB_LIB_OBJS = tkStubLib.o ttkStubLib.o

X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
	tkUnixFocus.o  $(FONT_OBJS) tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
	tkUnixSend.o tkUnixWm.o tkUnixXId.o

AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
	tkMacOSXDialog.o tkMacOSXDraw.o tkMacOSXEmbed.o tkMacOSXEntry.o \
	tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXImage.o \
	tkMacOSXInit.o tkMacOSXKeyboard.o tkMacOSXKeyEvent.o \
	tkMacOSXMenu.o \
	tkMacOSXMenubutton.o tkMacOSXMenus.o tkMacOSXMouseEvent.o \
	tkMacOSXNotify.o tkMacOSXRegion.o tkMacOSXScrlbr.o tkMacOSXSend.o \
	tkMacOSXServices.o tkMacOSXSubwindows.o tkMacOSXWindowEvent.o \
	tkMacOSXWm.o tkMacOSXXStubs.o \
	tkFileFilter.o tkMacWinMenu.o tkPointer.o tkUnix3d.o tkUnixScale.o \
	xcolors.o xdraw.o xgc.o ximage.o xutil.o \
	ttkMacOSXTheme.o

AQUA_TKTEST_OBJS = tkMacOSXTest.o








|
<








|
<


|
|
<










|












|
|
<


|







346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362

363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
	tkMenu.o tkMenubutton.o tkMenuDraw.o tkMessage.o \
	tkPanedWindow.o tkScale.o tkScrollbar.o

CANV_OBJS = tkCanvas.o tkCanvArc.o tkCanvBmap.o tkCanvImg.o \
	tkCanvLine.o tkCanvPoly.o tkCanvPs.o tkCanvText.o \
	tkCanvUtil.o tkCanvWind.o tkRectOval.o tkTrig.o

IMAGE_OBJS = tkImage.o tkImgBmap.o tkImgGIF.o tkImgPPM.o tkImgPhoto.o


TEXT_OBJS = tkText.o tkTextBTree.o tkTextDisp.o tkTextImage.o tkTextIndex.o \
	tkTextMark.o tkTextTag.o tkTextWind.o

# either tkUnixFont.o (default) or tkUnixRFont.o (if --enable-xft)
#
FONT_OBJS = @UNIX_FONT_OBJS@

GENERIC_OBJS = tk3d.o tkArgv.o tkAtom.o tkBind.o tkBitmap.o tkClipboard.o \

	tkCmds.o tkColor.o tkConfig.o tkConsole.o tkCursor.o tkError.o \
	tkEvent.o tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o \
	tkGrid.o tkMain.o tkObj.o tkOldConfig.o tkOption.o tkPack.o tkPlace.o \
	tkSelect.o tkStyle.o tkUndo.o tkUtil.o tkVisual.o tkWindow.o


TTK_OBJS = \
	ttkBlink.o ttkButton.o ttkCache.o ttkClamTheme.o ttkClassicTheme.o \
	ttkDefaultTheme.o ttkElements.o ttkEntry.o ttkFrame.o ttkImage.o \
	ttkInit.o ttkLabel.o ttkLayout.o ttkManager.o ttkNotebook.o \
	ttkPanedwindow.o ttkProgress.o ttkScale.o ttkScrollbar.o ttkScroll.o \
	ttkSeparator.o ttkSquare.o ttkState.o \
	ttkTagSet.o ttkTheme.o ttkTrace.o ttkTrack.o ttkTreeview.o \
	ttkWidget.o ttkStubInit.o

STUB_OBJS = tkStubInit.o tkStubLib.o

STUB_LIB_OBJS = tkStubLib.o ttkStubLib.o

X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
	tkUnixFocus.o  $(FONT_OBJS) tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
	tkUnixSend.o tkUnixWm.o tkUnixXId.o

AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
	tkMacOSXDialog.o tkMacOSXDraw.o tkMacOSXEmbed.o tkMacOSXEntry.o \
	tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXInit.o \
	tkMacOSXKeyboard.o tkMacOSXKeyEvent.o tkMacOSXMenu.o \

	tkMacOSXMenubutton.o tkMacOSXMenus.o tkMacOSXMouseEvent.o \
	tkMacOSXNotify.o tkMacOSXRegion.o tkMacOSXScrlbr.o tkMacOSXSend.o \
	tkMacOSXSubwindows.o tkMacOSXWindowEvent.o \
	tkMacOSXWm.o tkMacOSXXStubs.o \
	tkFileFilter.o tkMacWinMenu.o tkPointer.o tkUnix3d.o tkUnixScale.o \
	xcolors.o xdraw.o xgc.o ximage.o xutil.o \
	ttkMacOSXTheme.o

AQUA_TKTEST_OBJS = tkMacOSXTest.o

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

TTK_DECLS = \
	$(TTK_DIR)/ttk.decls

GENERIC_SRCS = \
	$(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \
	$(GENERIC_DIR)/tkAtom.c $(GENERIC_DIR)/tkBind.c	\
	$(GENERIC_DIR)/tkBitmap.c $(GENERIC_DIR)/tkBusy.c \
	$(GENERIC_DIR)/tkClipboard.c \
	$(GENERIC_DIR)/tkCmds.c $(GENERIC_DIR)/tkColor.c \
	$(GENERIC_DIR)/tkConfig.c $(GENERIC_DIR)/tkCursor.c \
	$(GENERIC_DIR)/tkError.c $(GENERIC_DIR)/tkEvent.c \
	$(GENERIC_DIR)/tkFocus.c $(GENERIC_DIR)/tkFont.c \
	$(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \
	$(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \
	$(GENERIC_DIR)/tkGrid.c $(GENERIC_DIR)/tkConsole.c \
	$(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \
	$(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \
	$(GENERIC_DIR)/tkPkgConfig.c \
	$(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkStyle.c \
	$(GENERIC_DIR)/tkUndo.c $(GENERIC_DIR)/tkUtil.c \
	$(GENERIC_DIR)/tkVisual.c $(GENERIC_DIR)/tkWindow.c \
	$(GENERIC_DIR)/tkButton.c $(GENERIC_DIR)/tkObj.c \
	$(GENERIC_DIR)/tkEntry.c $(GENERIC_DIR)/tkFrame.c \
	$(GENERIC_DIR)/tkListbox.c $(GENERIC_DIR)/tkMenu.c \
	$(GENERIC_DIR)/tkMenubutton.c $(GENERIC_DIR)/tkMenuDraw.c \
	$(GENERIC_DIR)/tkMessage.c $(GENERIC_DIR)/tkPanedWindow.c \
	$(GENERIC_DIR)/tkScale.c $(GENERIC_DIR)/tkScrollbar.c \
	$(GENERIC_DIR)/tkCanvas.c $(GENERIC_DIR)/tkCanvArc.c \
	$(GENERIC_DIR)/tkCanvBmap.c $(GENERIC_DIR)/tkCanvImg.c \
	$(GENERIC_DIR)/tkCanvLine.c $(GENERIC_DIR)/tkCanvPoly.c \
	$(GENERIC_DIR)/tkCanvPs.c $(GENERIC_DIR)/tkCanvText.c \
	$(GENERIC_DIR)/tkCanvUtil.c \
	$(GENERIC_DIR)/tkCanvWind.c $(GENERIC_DIR)/tkRectOval.c \
	$(GENERIC_DIR)/tkTrig.c $(GENERIC_DIR)/tkImage.c \
	$(GENERIC_DIR)/tkImgBmap.c $(GENERIC_DIR)/tkImgGIF.c \
	$(GENERIC_DIR)/tkImgPNG.c $(GENERIC_DIR)/tkImgPPM.c \
	$(GENERIC_DIR)/tkImgSVGnano.c $(GENERIC_DIR)/tkImgSVGnano.c \
	$(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhInstance.c \
	$(GENERIC_DIR)/tkImgListFormat.c $(GENERIC_DIR)/tkText.c \
	$(GENERIC_DIR)/tkTextBTree.c $(GENERIC_DIR)/tkTextDisp.c \
	$(GENERIC_DIR)/tkTextImage.c \
	$(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextMark.c \
	$(GENERIC_DIR)/tkTextTag.c $(GENERIC_DIR)/tkTextWind.c \
	$(GENERIC_DIR)/tkOldConfig.c $(GENERIC_DIR)/tkOldTest.c \
	$(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \
	$(GENERIC_DIR)/tkStubInit.c

TTK_SRCS = \
	$(TTK_DIR)/ttkBlink.c \
	$(TTK_DIR)/ttkButton.c \
	$(TTK_DIR)/ttkCache.c \
	$(TTK_DIR)/ttkClamTheme.c \
	$(TTK_DIR)/ttkClassicTheme.c \







|
<









<

















|
<
|
<






|







409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444

445
446
447
448
449
450
451
452
453
454
455
456
457
458

TTK_DECLS = \
	$(TTK_DIR)/ttk.decls

GENERIC_SRCS = \
	$(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \
	$(GENERIC_DIR)/tkAtom.c $(GENERIC_DIR)/tkBind.c	\
	$(GENERIC_DIR)/tkBitmap.c $(GENERIC_DIR)/tkClipboard.c \

	$(GENERIC_DIR)/tkCmds.c $(GENERIC_DIR)/tkColor.c \
	$(GENERIC_DIR)/tkConfig.c $(GENERIC_DIR)/tkCursor.c \
	$(GENERIC_DIR)/tkError.c $(GENERIC_DIR)/tkEvent.c \
	$(GENERIC_DIR)/tkFocus.c $(GENERIC_DIR)/tkFont.c \
	$(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \
	$(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \
	$(GENERIC_DIR)/tkGrid.c $(GENERIC_DIR)/tkConsole.c \
	$(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \
	$(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \

	$(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkStyle.c \
	$(GENERIC_DIR)/tkUndo.c $(GENERIC_DIR)/tkUtil.c \
	$(GENERIC_DIR)/tkVisual.c $(GENERIC_DIR)/tkWindow.c \
	$(GENERIC_DIR)/tkButton.c $(GENERIC_DIR)/tkObj.c \
	$(GENERIC_DIR)/tkEntry.c $(GENERIC_DIR)/tkFrame.c \
	$(GENERIC_DIR)/tkListbox.c $(GENERIC_DIR)/tkMenu.c \
	$(GENERIC_DIR)/tkMenubutton.c $(GENERIC_DIR)/tkMenuDraw.c \
	$(GENERIC_DIR)/tkMessage.c $(GENERIC_DIR)/tkPanedWindow.c \
	$(GENERIC_DIR)/tkScale.c $(GENERIC_DIR)/tkScrollbar.c \
	$(GENERIC_DIR)/tkCanvas.c $(GENERIC_DIR)/tkCanvArc.c \
	$(GENERIC_DIR)/tkCanvBmap.c $(GENERIC_DIR)/tkCanvImg.c \
	$(GENERIC_DIR)/tkCanvLine.c $(GENERIC_DIR)/tkCanvPoly.c \
	$(GENERIC_DIR)/tkCanvPs.c $(GENERIC_DIR)/tkCanvText.c \
	$(GENERIC_DIR)/tkCanvUtil.c \
	$(GENERIC_DIR)/tkCanvWind.c $(GENERIC_DIR)/tkRectOval.c \
	$(GENERIC_DIR)/tkTrig.c $(GENERIC_DIR)/tkImage.c \
	$(GENERIC_DIR)/tkImgBmap.c $(GENERIC_DIR)/tkImgGIF.c \
	$(GENERIC_DIR)/tkImgPPM.c \

	$(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkText.c \

	$(GENERIC_DIR)/tkTextBTree.c $(GENERIC_DIR)/tkTextDisp.c \
	$(GENERIC_DIR)/tkTextImage.c \
	$(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextMark.c \
	$(GENERIC_DIR)/tkTextTag.c $(GENERIC_DIR)/tkTextWind.c \
	$(GENERIC_DIR)/tkOldConfig.c $(GENERIC_DIR)/tkOldTest.c \
	$(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \
	$(GENERIC_DIR)/tkStubInit.c $(GENERIC_DIR)/tkStubLib.c

TTK_SRCS = \
	$(TTK_DIR)/ttkBlink.c \
	$(TTK_DIR)/ttkButton.c \
	$(TTK_DIR)/ttkCache.c \
	$(TTK_DIR)/ttkClamTheme.c \
	$(TTK_DIR)/ttkClassicTheme.c \
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
	$(MAC_OSX_DIR)/tkMacOSXBitmap.c $(MAC_OSX_DIR)/tkMacOSXButton.c \
	$(MAC_OSX_DIR)/tkMacOSXClipboard.c $(MAC_OSX_DIR)/tkMacOSXColor.c \
	$(MAC_OSX_DIR)/tkMacOSXConfig.c $(MAC_OSX_DIR)/tkMacOSXCursor.c \
	$(MAC_OSX_DIR)/tkMacOSXDebug.c $(MAC_OSX_DIR)/tkMacOSXDialog.c \
	$(MAC_OSX_DIR)/tkMacOSXDraw.c $(MAC_OSX_DIR)/tkMacOSXEmbed.c \
	$(MAC_OSX_DIR)/tkMacOSXEntry.c $(MAC_OSX_DIR)/tkMacOSXEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXFont.c $(MAC_OSX_DIR)/tkMacOSXHLEvents.c \
	$(MAC_OSX_DIR)/tkMacOSXImage.c \
	$(MAC_OSX_DIR)/tkMacOSXInit.c $(MAC_OSX_DIR)/tkMacOSXKeyboard.c \
	$(MAC_OSX_DIR)/tkMacOSXKeyEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXMenu.c \
	$(MAC_OSX_DIR)/tkMacOSXMenubutton.c $(MAC_OSX_DIR)/tkMacOSXMenus.c \
	$(MAC_OSX_DIR)/tkMacOSXMouseEvent.c $(MAC_OSX_DIR)/tkMacOSXNotify.c \
	$(MAC_OSX_DIR)/tkMacOSXRegion.c $(MAC_OSX_DIR)/tkMacOSXScrlbr.c \
	$(MAC_OSX_DIR)/tkMacOSXServices.c \
	$(MAC_OSX_DIR)/tkMacOSXSend.c $(MAC_OSX_DIR)/tkMacOSXSubwindows.c \
	$(MAC_OSX_DIR)/tkMacOSXTest.c $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXWm.c $(MAC_OSX_DIR)/tkMacOSXXStubs.c \
	$(GENERIC_DIR)/tkFileFilter.c $(GENERIC_DIR)/tkMacWinMenu.c \
	$(GENERIC_DIR)/tkPointer.c $(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixScale.c $(XLIB_DIR)/xcolors.c $(XLIB_DIR)/xdraw.c \
	$(XLIB_DIR)/xgc.c $(XLIB_DIR)/ximage.c $(XLIB_DIR)/xutil.c \
	$(TTK_DIR)/ttkMacOSXTheme.c

SRCS = $(GENERIC_SRCS) $(@TK_WINDOWINGSYSTEM@_SRCS) @PLAT_SRCS@

AQUA_RESOURCES = \
	$(MAC_OSX_DIR)/tkAboutDlg.r $(MAC_OSX_DIR)/tkMacOSXCursors.r \
	$(MAC_OSX_DIR)/tkMacOSXXCursors.r

AQUA_WISH_RESOURCES = $(MAC_OSX_DIR)/tkMacOSXAETE.r

AQUA_HDRS = $(MAC_OSX_DIR)/tkMacOSX.h $(GENERIC_DIR)/tkIntXlibDecls.h

AQUA_XLIB_HDRS = $(XLIB_DIR)/X11/*.h $(XLIB_DIR)/xbytes.h

AQUA_PRIVATE_HDRS = $(MAC_OSX_DIR)/tkMacOSXPort.h $(MAC_OSX_DIR)/tkMacOSXInt.h

X11_PRIVATE_HDRS = $(UNIX_DIR)/tkUnixPort.h $(UNIX_DIR)/tkUnixInt.h $(GENERIC_DIR)/tkIntXlibDecls.h







<

|
<



<











<
<
<
<
<
<







506
507
508
509
510
511
512

513
514

515
516
517

518
519
520
521
522
523
524
525
526
527
528






529
530
531
532
533
534
535
	$(MAC_OSX_DIR)/tkMacOSXBitmap.c $(MAC_OSX_DIR)/tkMacOSXButton.c \
	$(MAC_OSX_DIR)/tkMacOSXClipboard.c $(MAC_OSX_DIR)/tkMacOSXColor.c \
	$(MAC_OSX_DIR)/tkMacOSXConfig.c $(MAC_OSX_DIR)/tkMacOSXCursor.c \
	$(MAC_OSX_DIR)/tkMacOSXDebug.c $(MAC_OSX_DIR)/tkMacOSXDialog.c \
	$(MAC_OSX_DIR)/tkMacOSXDraw.c $(MAC_OSX_DIR)/tkMacOSXEmbed.c \
	$(MAC_OSX_DIR)/tkMacOSXEntry.c $(MAC_OSX_DIR)/tkMacOSXEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXFont.c $(MAC_OSX_DIR)/tkMacOSXHLEvents.c \

	$(MAC_OSX_DIR)/tkMacOSXInit.c $(MAC_OSX_DIR)/tkMacOSXKeyboard.c \
	$(MAC_OSX_DIR)/tkMacOSXKeyEvent.c $(MAC_OSX_DIR)/tkMacOSXMenu.c \

	$(MAC_OSX_DIR)/tkMacOSXMenubutton.c $(MAC_OSX_DIR)/tkMacOSXMenus.c \
	$(MAC_OSX_DIR)/tkMacOSXMouseEvent.c $(MAC_OSX_DIR)/tkMacOSXNotify.c \
	$(MAC_OSX_DIR)/tkMacOSXRegion.c $(MAC_OSX_DIR)/tkMacOSXScrlbr.c \

	$(MAC_OSX_DIR)/tkMacOSXSend.c $(MAC_OSX_DIR)/tkMacOSXSubwindows.c \
	$(MAC_OSX_DIR)/tkMacOSXTest.c $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXWm.c $(MAC_OSX_DIR)/tkMacOSXXStubs.c \
	$(GENERIC_DIR)/tkFileFilter.c $(GENERIC_DIR)/tkMacWinMenu.c \
	$(GENERIC_DIR)/tkPointer.c $(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixScale.c $(XLIB_DIR)/xcolors.c $(XLIB_DIR)/xdraw.c \
	$(XLIB_DIR)/xgc.c $(XLIB_DIR)/ximage.c $(XLIB_DIR)/xutil.c \
	$(TTK_DIR)/ttkMacOSXTheme.c

SRCS = $(GENERIC_SRCS) $(@TK_WINDOWINGSYSTEM@_SRCS) @PLAT_SRCS@







AQUA_HDRS = $(MAC_OSX_DIR)/tkMacOSX.h $(GENERIC_DIR)/tkIntXlibDecls.h

AQUA_XLIB_HDRS = $(XLIB_DIR)/X11/*.h $(XLIB_DIR)/xbytes.h

AQUA_PRIVATE_HDRS = $(MAC_OSX_DIR)/tkMacOSXPort.h $(MAC_OSX_DIR)/tkMacOSXInt.h

X11_PRIVATE_HDRS = $(UNIX_DIR)/tkUnixPort.h $(UNIX_DIR)/tkUnixInt.h $(GENERIC_DIR)/tkIntXlibDecls.h
573
574
575
576
577
578
579
580
581
582
583
584
585





586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

SHELL_ENV = \
	@LD_LIBRARY_PATH_VAR@="`pwd`:${TCL_BIN_DIR}:$${@LD_LIBRARY_PATH_VAR@}"; \
	export @LD_LIBRARY_PATH_VAR@; \
	TCL_LIBRARY=$(TCLDIR)/library; export TCL_LIBRARY; \
	TK_LIBRARY=@TK_SRC_DIR@/library; export TK_LIBRARY;

all: binaries libraries

binaries: ${LIB_FILE} ${WISH_EXE}

libraries:






# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tk.
${LIB_FILE}: ${STUB_LIB_FILE} @LIB_RSRC_FILE@ ${OBJS}
	rm -f $@
	@MAKE_LIB@

${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	@if test "x${LIB_FILE}" = "xlibtk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	    (cd ${TOP_DIR}/win; ${MAKE} tk${MAJOR_VERSION}${MINOR_VERSION}.dll); \
	    cp "${TOP_DIR}/win/tk${MAJOR_VERSION}${MINOR_VERSION}.dll" .; \
	fi
	rm -f $@
	@MAKE_STUB_LIB@

# Build Aqua resource files
${TK_RSRC_FILE}: $(AQUA_RESOURCES)
	rm -f $@
	if test "$(REZ)" != ""; then \
	    $(REZ) -o $@ $(REZ_SWITCHES) $(AQUA_RESOURCES); fi

${WISH_RSRC_FILE}: $(AQUA_WISH_RESOURCES)
	rm -f $@
	if test "$(REZ)" != ""; then \
	    $(REZ) -o $@ $(REZ_SWITCHES) $(AQUA_WISH_RESOURCES); fi

# Make target which outputs the list of the .o contained in the Tk lib
# usefull to build a single big shared library containing Tcl/Tk and other
# extensions.  used for the Tcl Plugin.  -- dl
tkLibObjs:
	@echo ${OBJS}
# This targets actually build the objects needed for the lib in the above
# case







|





>
>
>
>
>














<
<
<
<
<
<
<
<
<
<
<







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580











581
582
583
584
585
586
587

SHELL_ENV = \
	@LD_LIBRARY_PATH_VAR@="`pwd`:${TCL_BIN_DIR}:$${@LD_LIBRARY_PATH_VAR@}"; \
	export @LD_LIBRARY_PATH_VAR@; \
	TCL_LIBRARY=$(TCLDIR)/library; export TCL_LIBRARY; \
	TK_LIBRARY=@TK_SRC_DIR@/library; export TK_LIBRARY;

all: binaries libraries doc

binaries: ${LIB_FILE} ${WISH_EXE}

libraries:

$(TOP_DIR)/doc/man.macros:
	$(INSTALL_DATA) $(TCLDIR)/doc/man.macros $(TOP_DIR)/doc/man.macros

doc: $(TOP_DIR)/doc/man.macros

# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tk.
${LIB_FILE}: ${STUB_LIB_FILE} @LIB_RSRC_FILE@ ${OBJS}
	rm -f $@
	@MAKE_LIB@

${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	@if test "x${LIB_FILE}" = "xlibtk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	    (cd ${TOP_DIR}/win; ${MAKE} tk${MAJOR_VERSION}${MINOR_VERSION}.dll); \
	    cp "${TOP_DIR}/win/tk${MAJOR_VERSION}${MINOR_VERSION}.dll" .; \
	fi
	rm -f $@
	@MAKE_STUB_LIB@












# Make target which outputs the list of the .o contained in the Tk lib
# usefull to build a single big shared library containing Tcl/Tk and other
# extensions.  used for the Tcl Plugin.  -- dl
tkLibObjs:
	@echo ${OBJS}
# This targets actually build the objects needed for the lib in the above
# case
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
# burned into its ld search path. This keeps tktest from
# picking up an already installed version of the Tcl or
# Tk shared libraries.

$(TKTEST_EXE): $(TKTEST_OBJS) $(TK_LIB_FILE)
	$(MAKE) tktest-real LIB_RUNTIME_DIR="`pwd`:$(TCL_BIN_DIR)"

tktest-real: ${TK_STUB_LIB_FILE}
	${CC} ${CFLAGS} ${LDFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ $(WISH_LIBS) \
		${TK_STUB_LIB_FILE} ${TCL_STUB_LIB_SPEC} $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)

# # FIXME: This xttest rule seems to be broken in a number of ways.  It should
# # use CC_SEARCH_FLAGS, it does not include the shared lib location logic from
# # tktest, and it is not clear where this test.o object file comes from.
#
# xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ${TK_STUB_LIB_FILE}
# 	${CC} ${CFLAGS} ${LDFLAGS} test.o tkTest.o tkSquare.o \
# 		@TK_BUILD_LIB_SPEC@ ${TK_STUB_LIB_FILE}  ${TCL_STUB_LIB_SPEC} \
# 		$(WISH_LIBS) $(LD_SEARCH_FLAGS) -lXt -o xttest

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.
# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:
#	% make test TESTFLAGS="-verbose bps -file fileName.test"







|
|
|

|
|
|
|
|
|
|
|







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# burned into its ld search path. This keeps tktest from
# picking up an already installed version of the Tcl or
# Tk shared libraries.

$(TKTEST_EXE): $(TKTEST_OBJS) $(TK_LIB_FILE)
	$(MAKE) tktest-real LIB_RUNTIME_DIR="`pwd`:$(TCL_BIN_DIR)"

tktest-real:
	${CC} ${CFLAGS} ${LDFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ \
		$(WISH_LIBS) $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)

# FIXME: This xttest rule seems to be broken in a number of ways.
# It should use CC_SEARCH_FLAGS, it does not include the shared
# lib location logic from tktest, and it is not clear where this
# test.o object file comes from.
xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE)
	${CC} ${CFLAGS} ${LDFLAGS} test.o tkTest.o tkSquare.o \
		@TK_BUILD_LIB_SPEC@ \
		$(WISH_LIBS) $(LD_SEARCH_FLAGS) -lXt -o xttest

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.
# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:
#	% make test TESTFLAGS="-verbose bps -file fileName.test"
708
709
710
711
712
713
714




715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758

install: $(INSTALL_TARGETS)

install-strip:
	$(MAKE) $(INSTALL_TARGETS) \
		INSTALL_PROGRAM="$(INSTALL_PROGRAM) ${INSTALL_STRIP_PROGRAM}" \
		INSTALL_LIBRARY="$(INSTALL_LIBRARY) ${INSTALL_STRIP_LIBRARY}"





install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}
	@for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \
	    "$(PKG_INSTALL_DIR)" "$(CONFIG_INSTALL_DIR)" ; \
	    do \
	    if [ ! -d "$$i" ] ; then \
		echo "Making directory $$i"; \
		$(INSTALL_DATA_DIR) "$$i"; \
		else true; \
		fi; \
	    done;
	@if test "x$(TK_SHARED_BUILD)" = "x1"; then \
	    echo "Creating package index $(PKG_INDEX)"; \
	    rm -f "$(PKG_INDEX)"; \
	    (\
	    echo "if {[catch {package present Tcl 8.6-}]} return";\
	    relative=`echo | awk '{ORS=" "; split("$(TK_PKG_DIR)",a,"/"); for (f in a) {print ".."}}'`;\
	    if test "x$(DLL_INSTALL_DIR)" != "x$(BIN_INSTALL_DIR)"; then \
	    echo "package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE)]] Tk]";\
	    else \
	    echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	    echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin $(TK_LIB_FILE)]] Tk]";\
	    echo "} else {";\
	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin tk${MAJOR_VERSION}${MINOR_VERSION}.dll]] Tk]";\
	    echo "}";\
	    fi \
	    ) > "$(PKG_INDEX)"; \
	    fi
	@echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
	@@INSTALL_LIB@
	@chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
	@if test -f "tk${MAJOR_VERSION}${MINOR_VERSION}.dll"; then \
	    $(INSTALL_LIBRARY) "tk${MAJOR_VERSION}${MINOR_VERSION}.dll" "$(DLL_INSTALL_DIR)";\
	    chmod 555 "$(DLL_INSTALL_DIR)/tk${MAJOR_VERSION}${MINOR_VERSION}.dll";\
	    $(INSTALL_LIBRARY) "../win/libtk${MAJOR_VERSION}${MINOR_VERSION}.a" "$(LIB_INSTALL_DIR)";\
	    chmod 555 "$(LIB_INSTALL_DIR)/libtk${MAJOR_VERSION}${MINOR_VERSION}.a";\
	fi
	@echo "Installing ${WISH_EXE} as $(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@$(INSTALL_PROGRAM) ${WISH_EXE} "$(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@echo "Installing tkConfig.sh to $(CONFIG_INSTALL_DIR)/"
	@$(INSTALL_DATA) tkConfig.sh "$(CONFIG_INSTALL_DIR)/tkConfig.sh"
	@if test "$(STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \







>
>
>
>















|


|



|

|










|
|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

install: $(INSTALL_TARGETS)

install-strip:
	$(MAKE) $(INSTALL_TARGETS) \
		INSTALL_PROGRAM="$(INSTALL_PROGRAM) ${INSTALL_STRIP_PROGRAM}" \
		INSTALL_LIBRARY="$(INSTALL_LIBRARY) ${INSTALL_STRIP_LIBRARY}"

# Note: before running ranlib below, must cd to target directory because
# some ranlibs write to current directory, and this might not always be
# possible (e.g. if installing as root).

install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}
	@for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \
	    "$(PKG_INSTALL_DIR)" "$(CONFIG_INSTALL_DIR)" ; \
	    do \
	    if [ ! -d "$$i" ] ; then \
		echo "Making directory $$i"; \
		$(INSTALL_DATA_DIR) "$$i"; \
		else true; \
		fi; \
	    done;
	@if test "x$(TK_SHARED_BUILD)" = "x1"; then \
	    echo "Creating package index $(PKG_INDEX)"; \
	    rm -f "$(PKG_INDEX)"; \
	    (\
	    echo "if {![package vsatisfies [package provide Tcl] 8.5.0]} return";\
	    relative=`echo | awk '{ORS=" "; split("$(TK_PKG_DIR)",a,"/"); for (f in a) {print ".."}}'`;\
	    if test "x$(DLL_INSTALL_DIR)" != "x$(BIN_INSTALL_DIR)"; then \
	    echo "package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE)]]]";\
	    else \
	    echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	    echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin $(TK_LIB_FILE)]]]";\
	    echo "} else {";\
	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin tk${MAJOR_VERSION}${MINOR_VERSION}.dll]]]";\
	    echo "}";\
	    fi \
	    ) > "$(PKG_INDEX)"; \
	    fi
	@echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
	@@INSTALL_LIB@
	@chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
	@if test -f "tk${MAJOR_VERSION}${MINOR_VERSION}.dll"; then \
	    $(INSTALL_LIBRARY) "tk${MAJOR_VERSION}${MINOR_VERSION}.dll" "$(DLL_INSTALL_DIR)";\
	    chmod 555 "$(DLL_INSTALL_DIR)/tk${MAJOR_VERSION}${MINOR_VERSION}.dll";\
	    $(INSTALL_LIBRARY) "../win/libtk${MAJOR_VERSION}${MINOR_VERSION}.dll.a" "$(LIB_INSTALL_DIR)";\
	    chmod 555 "$(LIB_INSTALL_DIR)/libtk${MAJOR_VERSION}${MINOR_VERSION}.dll.a";\
	fi
	@echo "Installing ${WISH_EXE} as $(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@$(INSTALL_PROGRAM) ${WISH_EXE} "$(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@echo "Installing tkConfig.sh to $(CONFIG_INSTALL_DIR)/"
	@$(INSTALL_DATA) tkConfig.sh "$(CONFIG_INSTALL_DIR)/tkConfig.sh"
	@if test "$(STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \
898
899
900
901
902
903
904

905
906

907
908
909
910
911
912
913
914
915
916
917

Makefile: $(UNIX_DIR)/Makefile.in
	$(SHELL) config.status
#tkConfig.h: $(UNIX_DIR)/tkConfig.h.in
#	$(SHELL) config.status

clean:

	rm -f *.a *.o libtk* core errs *~ \#* TAGS *.E a.out \
		errors ${WISH_EXE} $(TKTEST_EXE) lib.exp Tk *.rsrc


distclean: clean
	rm -rf Makefile config.status config.cache config.log tkConfig.sh \
		tkConfig.h *.plist Tk.framework tk.pc

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

# Test binaries.  The rule for tkTestInit.o is complicated because
# it is is compiled from tkAppInit.c.  Can't use the "-o" option
# because this doesn't work on some strange compilers (e.g. UnixWare).







>

|
>



|







872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893

Makefile: $(UNIX_DIR)/Makefile.in
	$(SHELL) config.status
#tkConfig.h: $(UNIX_DIR)/tkConfig.h.in
#	$(SHELL) config.status

clean:
	rm -rf *.vfs
	rm -f *.a *.o libtk* core errs *~ \#* TAGS *.E a.out \
		errors ${WISH_EXE} $(TKTEST_EXE) lib.exp Tk *.rsrc \
		 *.zip

distclean: clean
	rm -rf Makefile config.status config.cache config.log tkConfig.sh \
		$(PACKAGE).* prototype tkConfig.h *.plist Tk.framework tk.pc

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

# Test binaries.  The rule for tkTestInit.o is complicated because
# it is is compiled from tkAppInit.c.  Can't use the "-o" option
# because this doesn't work on some strange compilers (e.g. UnixWare).
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962

tkBind.o: $(GENERIC_DIR)/tkBind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c

tkBitmap.o: $(GENERIC_DIR)/tkBitmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitmap.c

tkBusy.o: $(GENERIC_DIR)/tkBusy.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBusy.c

tkClipboard.o: $(GENERIC_DIR)/tkClipboard.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkClipboard.c

tkCmds.o: $(GENERIC_DIR)/tkCmds.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCmds.c

tkColor.o: $(GENERIC_DIR)/tkColor.c







<
<
<







922
923
924
925
926
927
928



929
930
931
932
933
934
935

tkBind.o: $(GENERIC_DIR)/tkBind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c

tkBitmap.o: $(GENERIC_DIR)/tkBitmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitmap.c




tkClipboard.o: $(GENERIC_DIR)/tkClipboard.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkClipboard.c

tkCmds.o: $(GENERIC_DIR)/tkCmds.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCmds.c

tkColor.o: $(GENERIC_DIR)/tkColor.c
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

tkOption.o: $(GENERIC_DIR)/tkOption.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkOption.c

tkPack.o: $(GENERIC_DIR)/tkPack.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPack.c

# TIP #59, embedding of configuration information into the binary library.
#
# Part of Tk's configuration information are the paths where it was installed
# and where it will look for its libraries (which can be different). We derive
# this information from the variables which can be overridden by the user. As
# every path can be configured separately we do not remember one general
# prefix/exec_prefix but all the different paths individually.

tkPkgConfig.o: $(GENERIC_DIR)/tkPkgConfig.c
	$(CC) -c $(CC_SWITCHES)					\
		-DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR)\"" \
		-DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR)\"" \
		-DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR)\"" \
		-DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR)\"" \
		-DCFG_INSTALL_DOCDIR="\"$(MAN_INSTALL_DIR)\"" \
		-DCFG_INSTALL_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		-DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \
		-DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \
		-DCFG_RUNTIME_SCRDIR="\"$(TK_LIBRARY)\"" \
		-DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \
		-DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \
		-DCFG_RUNTIME_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		$(GENERIC_DIR)/tkPkgConfig.c

tkPlace.o: $(GENERIC_DIR)/tkPlace.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPlace.c

tkSelect.o: $(GENERIC_DIR)/tkSelect.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkSelect.c

tkStyle.o: $(GENERIC_DIR)/tkStyle.c







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







982
983
984
985
986
987
988


























989
990
991
992
993
994
995

tkOption.o: $(GENERIC_DIR)/tkOption.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkOption.c

tkPack.o: $(GENERIC_DIR)/tkPack.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPack.c



























tkPlace.o: $(GENERIC_DIR)/tkPlace.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPlace.c

tkSelect.o: $(GENERIC_DIR)/tkSelect.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkSelect.c

tkStyle.o: $(GENERIC_DIR)/tkStyle.c
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

tkImage.o: $(GENERIC_DIR)/tkImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImage.c

tkImgBmap.o: $(GENERIC_DIR)/tkImgBmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgBmap.c

tkImgListFormat.o: $(GENERIC_DIR)/tkImgListFormat.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgListFormat.c

tkImgGIF.o: $(GENERIC_DIR)/tkImgGIF.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgGIF.c

tkImgPNG.o: $(GENERIC_DIR)/tkImgPNG.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPNG.c

tkImgPPM.o: $(GENERIC_DIR)/tkImgPPM.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPPM.c

tkImgSVGnano.o: $(GENERIC_DIR)/tkImgSVGnano.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgSVGnano.c

tkImgPhoto.o: $(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c

tkImgPhInstance.o: $(GENERIC_DIR)/tkImgPhInstance.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhInstance.c

tkOldTest.o: $(GENERIC_DIR)/tkOldTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkOldTest.c

tkTest.o: $(GENERIC_DIR)/tkTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkTest.c

tkText.o: $(GENERIC_DIR)/tkText.c







<
<
<



<
<
<



<
<
<
|


<
<
<







1078
1079
1080
1081
1082
1083
1084



1085
1086
1087



1088
1089
1090



1091
1092
1093



1094
1095
1096
1097
1098
1099
1100

tkImage.o: $(GENERIC_DIR)/tkImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImage.c

tkImgBmap.o: $(GENERIC_DIR)/tkImgBmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgBmap.c




tkImgGIF.o: $(GENERIC_DIR)/tkImgGIF.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgGIF.c




tkImgPPM.o: $(GENERIC_DIR)/tkImgPPM.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPPM.c




tkImgPhoto.o: $(GENERIC_DIR)/tkImgPhoto.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c




tkOldTest.o: $(GENERIC_DIR)/tkOldTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkOldTest.c

tkTest.o: $(GENERIC_DIR)/tkTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkTest.c

tkText.o: $(GENERIC_DIR)/tkText.c
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixFont.c

# NB: tkUnixRFont.o uses nondefault CFLAGS
tkUnixRFont.o: $(UNIX_DIR)/tkUnixRFont.c
	$(CC) -c $(CC_SWITCHES) $(XFT_CFLAGS) $(UNIX_DIR)/tkUnixRFont.c

tkUnixInit.o: $(UNIX_DIR)/tkUnixInit.c tkConfig.sh
	$(CC) -c $(CC_SWITCHES) \
	    $(UNIX_DIR)/tkUnixInit.c

tkUnixKey.o: $(UNIX_DIR)/tkUnixKey.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixKey.c

tkUnixMenu.o: $(UNIX_DIR)/tkUnixMenu.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixMenu.c







|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixFont.c

# NB: tkUnixRFont.o uses nondefault CFLAGS
tkUnixRFont.o: $(UNIX_DIR)/tkUnixRFont.c
	$(CC) -c $(CC_SWITCHES) $(XFT_CFLAGS) $(UNIX_DIR)/tkUnixRFont.c

tkUnixInit.o: $(UNIX_DIR)/tkUnixInit.c tkConfig.sh
	$(CC) -c $(CC_SWITCHES) -DTK_LIBRARY=\"${TK_LIBRARY}\" \
	    $(UNIX_DIR)/tkUnixInit.c

tkUnixKey.o: $(UNIX_DIR)/tkUnixKey.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixKey.c

tkUnixMenu.o: $(UNIX_DIR)/tkUnixMenu.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixMenu.c
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322

tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFont.c

tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c

tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXImage.c

tkMacOSXInit.o: $(MAC_OSX_DIR)/tkMacOSXInit.c tkConfig.sh
	$(CC) -c $(CC_SWITCHES) \
	    $(MAC_OSX_DIR)/tkMacOSXInit.c

tkMacOSXKeyboard.o: $(MAC_OSX_DIR)/tkMacOSXKeyboard.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXKeyboard.c

tkMacOSXKeyEvent.o: $(MAC_OSX_DIR)/tkMacOSXKeyEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXKeyEvent.c







<
<
<

|







1239
1240
1241
1242
1243
1244
1245



1246
1247
1248
1249
1250
1251
1252
1253
1254

tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFont.c

tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c




tkMacOSXInit.o: $(MAC_OSX_DIR)/tkMacOSXInit.c tkConfig.sh
	$(CC) -c $(CC_SWITCHES) -DTK_LIBRARY=\"${TK_LIBRARY}\" \
	    $(MAC_OSX_DIR)/tkMacOSXInit.c

tkMacOSXKeyboard.o: $(MAC_OSX_DIR)/tkMacOSXKeyboard.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXKeyboard.c

tkMacOSXKeyEvent.o: $(MAC_OSX_DIR)/tkMacOSXKeyEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXKeyEvent.c
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360

tkMacOSXScrlbr.o: $(MAC_OSX_DIR)/tkMacOSXScrlbr.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXScrlbr.c

tkMacOSXSend.o: $(MAC_OSX_DIR)/tkMacOSXSend.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXSend.c

tkMacOSXServices.o: $(MAC_OSX_DIR)/tkMacOSXServices.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXServices.c

tkMacOSXSubwindows.o: $(MAC_OSX_DIR)/tkMacOSXSubwindows.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXSubwindows.c

tkMacOSXTest.o: $(MAC_OSX_DIR)/tkMacOSXTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXTest.c

tkMacOSXWindowEvent.o: $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c







<
<
<







1276
1277
1278
1279
1280
1281
1282



1283
1284
1285
1286
1287
1288
1289

tkMacOSXScrlbr.o: $(MAC_OSX_DIR)/tkMacOSXScrlbr.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXScrlbr.c

tkMacOSXSend.o: $(MAC_OSX_DIR)/tkMacOSXSend.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXSend.c




tkMacOSXSubwindows.o: $(MAC_OSX_DIR)/tkMacOSXSubwindows.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXSubwindows.c

tkMacOSXTest.o: $(MAC_OSX_DIR)/tkMacOSXTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXTest.c

tkMacOSXWindowEvent.o: $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
	@echo "Warning: ttkStubInit.c may be out of date."
	@echo "Developers may want to run \"make genstubs\" to regenerate."
	@echo "This warning can be safely ignored, do not report as a bug!"

genstubs:
	$(TCL_EXE) $(TOOL_DIR)/genStubs.tcl $(GENERIC_DIR) \
		$(GENERIC_DIR)/tk.decls $(GENERIC_DIR)/tkInt.decls
	$(TCL_EXE) $(TOOL_DIR)/genStubs.tcl $(TTK_DIR) $(TTK_DIR)/ttk.decls

#
# Target to check that all exported functions have an entry in the stubs
# tables.
#

checkstubs: $(TK_LIB_FILE)







|







1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
	@echo "Warning: ttkStubInit.c may be out of date."
	@echo "Developers may want to run \"make genstubs\" to regenerate."
	@echo "This warning can be safely ignored, do not report as a bug!"

genstubs:
	$(TCL_EXE) $(TOOL_DIR)/genStubs.tcl $(GENERIC_DIR) \
		$(GENERIC_DIR)/tk.decls $(GENERIC_DIR)/tkInt.decls
	$(TCL_EXE) $(TTK_DIR)/ttkGenStubs.tcl $(TTK_DIR) $(TTK_DIR)/ttk.decls

#
# Target to check that all exported functions have an entry in the stubs
# tables.
#

checkstubs: $(TK_LIB_FILE)
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

1620
1621
1622
1623
1624

1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649

1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
# to put the distribution.  DISTDIR must be an absolute path name.
#

DISTROOT = /tmp/dist
DISTNAME = tk${VERSION}${PATCH_LEVEL}
ZIPNAME	 = tk${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip
DISTDIR	 = $(DISTROOT)/$(DISTNAME)
DIST_INSTALL_DATA   = CPPROG='cp -p' $(INSTALL) -m 644
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755

$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/aclocal.m4
	cd $(UNIX_DIR); autoconf
$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf
$(UNIX_DIR)/tkConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@

$(TOP_DIR)/manifest.uuid:
	printf "git." >$(TOP_DIR)/manifest.uuid
	git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid

dist:	$(UNIX_DIR)/configure $(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(MAC_OSX_DIR)/configure $(TOP_DIR)/doc/man.macros $(TOP_DIR)/manifest.uuid
	rm -rf $(DISTDIR)
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix

	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tk.spec \
		$(UNIX_DIR)/aclocal.m4 $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/tkConfig.sh.in $(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/README $(UNIX_DIR)/installManPage \
		$(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(DISTDIR)/unix
	$(DIST_INSTALL_SCRIPT) $(UNIX_DIR)/configure $(DISTDIR)/unix
	$(INSTALL_DATA_DIR) $(DISTDIR)/bitmaps
	@(cd $(TOP_DIR); for i in bitmaps/* ; do \
	    if [ -f $$i ] ; then \
		sed -e 's/static char/static unsigned char/' \
		       $$i > $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.[ch] $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/README $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog \
		$(TOP_DIR)/ChangeLog.2??? $(TOP_DIR)/README.md \
		$(TOP_DIR)/license.terms $(DISTDIR)
	rm -f $(DISTDIR)/generic/blt*.[ch]
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic/ttk
	$(DIST_INSTALL_DATA) $(TTK_DIR)/*.[ch] $(TTK_DIR)/ttk.decls \
		$(DISTDIR)/generic/ttk
	$(INSTALL_DATA_DIR) $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/Makefile.in $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/configure.ac \

		$(TOP_DIR)/win/tkConfig.sh.in \
		$(TOP_DIR)/win/aclocal.m4 $(TOP_DIR)/win/tcl.m4 \
		$(DISTDIR)/win
	$(DIST_INSTALL_SCRIPT) $(TOP_DIR)/win/configure $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.bat $(DISTDIR)/win

	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.vc $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/README $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/win
	$(INSTALL_DATA_DIR) $(DISTDIR)/win/rc
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/wish.exe.manifest.in $(DISTDIR)/win/
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/rc/*.{rc,cur,ico,bmp} $(DISTDIR)/win/rc
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.icns $(MAC_OSX_DIR)/*.tiff \
		$(MAC_OSX_DIR)/*.[ch] $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
		$(MAC_OSX_DIR)/*.sdef \
		$(DISTDIR)/macosx
	$(DIST_INSTALL_SCRIPT) $(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/macosx
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tk.xcode
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tk.xcode/project.pbxproj \
		$(MAC_OSX_DIR)/Tk.xcode/default.pbxuser \
		$(DISTDIR)/macosx/Tk.xcode
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tk.xcodeproj
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tk.xcodeproj/project.pbxproj \
		$(MAC_OSX_DIR)/Tk.xcodeproj/default.pbxuser \
		$(DISTDIR)/macosx/Tk.xcodeproj
	$(INSTALL_DATA_DIR) $(DISTDIR)/compat
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/compat/stdint.h \

		$(TOP_DIR)/compat/stdbool.h $(DISTDIR)/compat
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/*.[ch] $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/X11/*.h $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib/X11
	$(INSTALL_DATA_DIR) $(DISTDIR)/library
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
		$(TOP_DIR)/library/tclIndex \
		$(DISTDIR)/library
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/ttk
	$(DIST_INSTALL_DATA) $(TOP_DIR)/library/ttk/*.tcl $(DISTDIR)/library/ttk
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/images
	@(cd $(TOP_DIR); for i in library/images/* ; do \
	    if [ -f $$i ] ; then \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/msgs
	@(cd $(TOP_DIR); for i in library/msgs/*.msg ; do \
	    if [ -f $$i ] ; then \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/demos
	cp -pr $(TOP_DIR)/library/demos/*.tcl \
		$(TOP_DIR)/library/demos/*.msg \
		$(TOP_DIR)/library/demos/tclIndex \
		$(TOP_DIR)/library/demos/browse \
		$(TOP_DIR)/library/demos/hello $(TOP_DIR)/library/demos/ixset \
		$(TOP_DIR)/library/demos/rmt $(TOP_DIR)/library/demos/rolodex \
		$(TOP_DIR)/library/demos/square \
		$(TOP_DIR)/library/demos/tcolor \
		$(TOP_DIR)/library/demos/timer \
		$(TOP_DIR)/library/demos/widget \
		$(TOP_DIR)/library/demos/README \
		$(TOP_DIR)/license.terms $(DISTDIR)/library/demos
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/demos/images
	@(cd $(TOP_DIR); for i in library/demos/images/* ; do \
	    if [ -f $$i ] ; then \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/doc
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TEST_DIR)/*.{test,tcl} \
		$(TEST_DIR)/README $(TEST_DIR)/*.{gif,png,ppm,xbm} \
		$(TEST_DIR)/option.file* $(DISTDIR)/tests
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests/ttk
	$(DIST_INSTALL_DATA) $(TEST_DIR)/ttk/*.{test,tcl} $(DISTDIR)/tests/ttk

alldist: dist
	rm -f $(DISTROOT)/$(DISTNAME)-src.tar.gz $(DISTROOT)/$(ZIPNAME)
	cd $(DISTROOT); tar cf $(DISTNAME)-src.tar $(DISTNAME); \
		gzip -9 $(DISTNAME)-src.tar; zip -qr8 $(ZIPNAME) $(DISTNAME)

#







<
<
<
<
<
<


<
<





|

|
|
|
|
>
|




|
|






|
|
|
|
|



|
|
|
|
|
|
>



<
|
>
|
|
|
|
|
|
|
|



|

<
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|


|
|
|


|


|


|


|












|


|


|
|

|
|
|

|
|







1494
1495
1496
1497
1498
1499
1500






1501
1502


1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560

1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
# to put the distribution.  DISTDIR must be an absolute path name.
#

DISTROOT = /tmp/dist
DISTNAME = tk${VERSION}${PATCH_LEVEL}
ZIPNAME	 = tk${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip
DISTDIR	 = $(DISTROOT)/$(DISTNAME)






$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf



$(TOP_DIR)/manifest.uuid:
	printf "git." >$(TOP_DIR)/manifest.uuid
	git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid

dist:   $(UNIX_DIR)/configure $(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(MAC_OSX_DIR)/configure $(TOP_DIR)/doc/man.macros $(TOP_DIR)/manifest.uuid
	rm -rf $(DISTDIR)
	mkdir -p $(DISTDIR)/unix
	cp -p $(TOP_DIR)/manifest.uuid $(DISTDIR)
	cp -p $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	cp $(TOP_DIR)/license.terms $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	chmod 664 $(DISTDIR)/unix/Makefile.in
	cp $(UNIX_DIR)/configure $(UNIX_DIR)/configure.in $(UNIX_DIR)/tk.spec \
		$(UNIX_DIR)/aclocal.m4 $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/tkConfig.sh.in $(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/README $(UNIX_DIR)/installManPage \
		$(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(DISTDIR)/unix
	chmod 775 $(DISTDIR)/unix/configure
	mkdir $(DISTDIR)/bitmaps
	@(cd $(TOP_DIR); for i in bitmaps/* ; do \
	    if [ -f $$i ] ; then \
		sed -e 's/static char/static unsigned char/' \
		       $$i > $(DISTDIR)/$$i; \
	    fi; \
	done;)
	mkdir $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/*.[ch] $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
	cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog \
		$(TOP_DIR)/ChangeLog.2??? $(TOP_DIR)/README.md \
		$(TOP_DIR)/license.terms $(DISTDIR)
	rm -f $(DISTDIR)/generic/blt*.[ch]
	mkdir $(DISTDIR)/generic/ttk
	cp -p $(TTK_DIR)/*.[ch] $(TTK_DIR)/ttk.decls \
		$(TTK_DIR)/ttkGenStubs.tcl $(DISTDIR)/generic/ttk
	mkdir $(DISTDIR)/win
	cp $(TOP_DIR)/win/Makefile.in $(DISTDIR)/win
	cp $(TOP_DIR)/win/configure.in \
		$(TOP_DIR)/win/configure \
		$(TOP_DIR)/win/tkConfig.sh.in \
		$(TOP_DIR)/win/aclocal.m4 $(TOP_DIR)/win/tcl.m4 \
		$(DISTDIR)/win

	cp -p $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.bat $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/rules.vc $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
	mkdir $(DISTDIR)/win/rc
	cp -p $(TOP_DIR)/win/wish.exe.manifest.in $(DISTDIR)/win/
	cp -p $(TOP_DIR)/win/rc/*.{rc,cur,ico,bmp} $(DISTDIR)/win/rc
	mkdir $(DISTDIR)/macosx
	cp -p $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.icns $(MAC_OSX_DIR)/*.tiff \
		$(MAC_OSX_DIR)/*.[ch] $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
		$(MAC_OSX_DIR)/*.sdef $(MAC_OSX_DIR)/configure \
		$(DISTDIR)/macosx

	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/macosx
	mkdir $(DISTDIR)/macosx/Wish.xcode
	cp -p $(MAC_OSX_DIR)/Wish.xcode/project.pbxproj \
		$(MAC_OSX_DIR)/Wish.xcode/default.pbxuser \
		$(DISTDIR)/macosx/Wish.xcode
	mkdir $(DISTDIR)/macosx/Wish.xcodeproj
	cp -p $(MAC_OSX_DIR)/Wish.xcodeproj/project.pbxproj \
		$(MAC_OSX_DIR)/Wish.xcodeproj/default.pbxuser \
		$(DISTDIR)/macosx/Wish.xcodeproj
	mkdir $(DISTDIR)/compat
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/compat/unistd.h \
		$(TOP_DIR)/compat/stdlib.h $(TOP_DIR)/compat/limits.h \
		$(DISTDIR)/compat
	mkdir $(DISTDIR)/xlib
	cp -p $(XLIB_DIR)/*.[ch] $(DISTDIR)/xlib
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/xlib
	mkdir $(DISTDIR)/xlib/X11
	cp -p $(XLIB_DIR)/X11/*.h $(DISTDIR)/xlib/X11
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/xlib/X11
	mkdir $(DISTDIR)/library
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
		$(TOP_DIR)/library/tclIndex \
		$(DISTDIR)/library
	mkdir $(DISTDIR)/library/ttk
	cp -p $(TOP_DIR)/library/ttk/*.tcl $(DISTDIR)/library/ttk
	mkdir $(DISTDIR)/library/images
	@(cd $(TOP_DIR); for i in library/images/* ; do \
	    if [ -f $$i ] ; then \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	mkdir $(DISTDIR)/library/msgs
	@(cd $(TOP_DIR); for i in library/msgs/*.msg ; do \
	    if [ -f $$i ] ; then \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	mkdir $(DISTDIR)/library/demos
	cp -pr $(TOP_DIR)/library/demos/*.tcl \
		$(TOP_DIR)/library/demos/*.msg \
		$(TOP_DIR)/library/demos/tclIndex \
		$(TOP_DIR)/library/demos/browse \
		$(TOP_DIR)/library/demos/hello $(TOP_DIR)/library/demos/ixset \
		$(TOP_DIR)/library/demos/rmt $(TOP_DIR)/library/demos/rolodex \
		$(TOP_DIR)/library/demos/square \
		$(TOP_DIR)/library/demos/tcolor \
		$(TOP_DIR)/library/demos/timer \
		$(TOP_DIR)/library/demos/widget \
		$(TOP_DIR)/library/demos/README \
		$(TOP_DIR)/license.terms $(DISTDIR)/library/demos
	mkdir $(DISTDIR)/library/demos/images
	@(cd $(TOP_DIR); for i in library/demos/images/* ; do \
	    if [ -f $$i ] ; then \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	mkdir $(DISTDIR)/doc
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	mkdir $(DISTDIR)/tests
	cp -p $(TOP_DIR)/license.terms $(TEST_DIR)/*.{test,tcl} \
		$(TEST_DIR)/README $(TEST_DIR)/*.{gif,ppm,xbm} \
		$(TEST_DIR)/option.file* $(DISTDIR)/tests
	mkdir $(DISTDIR)/tests/ttk
	cp -p $(TEST_DIR)/ttk/*.{test,tcl} $(DISTDIR)/tests/ttk

alldist: dist
	rm -f $(DISTROOT)/$(DISTNAME)-src.tar.gz $(DISTROOT)/$(ZIPNAME)
	cd $(DISTROOT); tar cf $(DISTNAME)-src.tar $(DISTNAME); \
		gzip -9 $(DISTNAME)-src.tar; zip -qr8 $(ZIPNAME) $(DISTNAME)

#
1727
1728
1729
1730
1731
1732
1733


















































































1734
1735
1736
1737
1738
1739
1740
BUILD_HTML = \
	@if test -f "$(BUILD_TCLSH)"; then \
	$(SHELL_ENV) TCLSH="$(BUILD_TCLSH)"; else \
	TCLSH="$(TCL_EXE)"; fi ;\
	"$${TCLSH}" $(TOOL_DIR)/tcltk-man2html.tcl --htmldir="$(HTML_INSTALL_DIR)" \
		--srcdir=$(TOP_DIR)/.. $(BUILD_HTML_FLAGS)



















































































#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all binaries libraries objs doc html html-tcl html-tk test runtest
.PHONY: install install-strip install-binaries install-libraries







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
BUILD_HTML = \
	@if test -f "$(BUILD_TCLSH)"; then \
	$(SHELL_ENV) TCLSH="$(BUILD_TCLSH)"; else \
	TCLSH="$(TCL_EXE)"; fi ;\
	"$${TCLSH}" $(TOOL_DIR)/tcltk-man2html.tcl --htmldir="$(HTML_INSTALL_DIR)" \
		--srcdir=$(TOP_DIR)/.. $(BUILD_HTML_FLAGS)

#
# Targets to build Solaris package of the distribution for the current
# architecture.  To build stream packages for both sun4 and i86pc
# architectures:
#
#   On the sun4 machine, execute the following:
#     make distclean; ./configure
#     make DISTDIR=<distdir> package
#
#   Once the build is complete, execute the following on the i86pc
#   machine:
#     make DISTDIR=<distdir> package-quick
#
# <distdir> is the absolute path to a directory where the build should
# take place.  These steps will generate the $(PACKAGE).sun4 and
# $(PACKAGE).i86pc stream packages.  It is important that the packages be
# built in this fashion in order to ensure that the architecture
# independent files are exactly the same, including timestamps, in
# both packages.
#

PACKAGE=SCRPtk

package: dist package-config package-common package-binaries package-generate
package-quick: package-config package-binaries package-generate

#
# Configure for the current architecture in the dist directory.
#
package-config:
	mkdir -p $(DISTDIR)/unix/`arch`
	cd $(DISTDIR)/unix/`arch`; \
        ../configure --prefix=/opt/SUNWtcl/$(TCLVERSION) \
		--exec_prefix=/opt/SUNWtcl/$(TCLVERSION)/`arch` \
		--with-tcl=$(DISTDIR)/../tcl$(TCLVERSION)/unix/`arch` \
		--enable-shared
	mkdir -p $(DISTDIR)/SUNWtcl/$(TCLVERSION)
	mkdir -p $(DISTDIR)/SUNWtcl/$(TCLVERSION)/`arch`

#
# Build and install the architecture independent files in the dist directory.
#

package-common:
	cd $(DISTDIR)/unix/`arch`;\
	$(MAKE); \
	$(MAKE) install-libraries install-doc \
		prefix=$(DISTDIR)/SUNWtcl/$(TCLVERSION) \
		exec_prefix=$(DISTDIR)/SUNWtcl/$(TCLVERSION)/`arch`
	mkdir -p $(DISTDIR)/SUNWtcl/$(TCLVERSION)/bin
	sed -e "s/TCLVERSION/$(TCLVERSION)/g" \
		-e "s/TKVERSION/$(VERSION)/g" < $(UNIX_DIR)/wish.sh \
		> $(DISTDIR)/SUNWtcl/$(TCLVERSION)/bin/wish$(VERSION)
	chmod 755 $(DISTDIR)/SUNWtcl/$(TCLVERSION)/bin/wish$(VERSION)

#
# Build and install the architecture specific files in the dist directory.
#

package-binaries:
	cd $(DISTDIR)/unix/`arch`; \
	$(MAKE); \
	$(MAKE) install-binaries prefix=$(DISTDIR)/SUNWtcl/$(TCLVERSION) \
		exec_prefix=$(DISTDIR)/SUNWtcl/$(TCLVERSION)/`arch`

#
# Generate a package from the installed files in the dist directory for the
# current architecture.
#

package-generate:
	pkgproto $(DISTDIR)/SUNWtcl/$(TCLVERSION)/bin=bin \
		 $(DISTDIR)/SUNWtcl/$(TCLVERSION)/include=include \
		 $(DISTDIR)/SUNWtcl/$(TCLVERSION)/lib=lib \
		 $(DISTDIR)/SUNWtcl/$(TCLVERSION)/man=man \
		 $(DISTDIR)/SUNWtcl/$(TCLVERSION)/`arch`=`arch` \
	| $(TCL_EXE) $(TCLDIR)/unix/mkProto.tcl $(TCLVERSION) \
		$(UNIX_DIR) > prototype
	pkgmk -o -d . -f prototype -a `arch`
	pkgtrans -s . $(PACKAGE).`arch` $(PACKAGE)
	rm -rf $(PACKAGE)

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

.PHONY: all binaries libraries objs doc html html-tcl html-tk test runtest
.PHONY: install install-strip install-binaries install-libraries

Changes to unix/README.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Tk UNIX README
--------------

This is the directory where you configure, compile, test, and install UNIX
versions of Tk. This directory also contains source files for Tk that are
specific to UNIX.

The information in this file is maintained at:
	https://www.tcl-lang.org//doc/howto/compile.html

For information on platforms where Tcl/Tk is known to compile, along with any
porting notes for getting it to work on those platforms, see:
	https://www.tcl-lang.org//software/tcltk/platforms.html

The rest of this file contains instructions on how to do this. The release
should compile and run either "out of the box" or with trivial changes on any
UNIX-like system that approximates POSIX, BSD, or System V. We know that it
runs on workstations from Sun, H-P, DEC, IBM, and SGI, as well as PCs running
Linux, BSDI, and SCO UNIX. To compile for a PC running Windows, see the README
file in the directory ../win. To compile for MacOSX, see the README file in








|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Tk UNIX README
--------------

This is the directory where you configure, compile, test, and install UNIX
versions of Tk. This directory also contains source files for Tk that are
specific to UNIX.

The information in this file is maintained at:
	http://www.tcl.tk/doc/howto/compile.html

For information on platforms where Tcl/Tk is known to compile, along with any
porting notes for getting it to work on those platforms, see:
	http://www.tcl.tk/software/tcltk/platforms.html

The rest of this file contains instructions on how to do this. The release
should compile and run either "out of the box" or with trivial changes on any
UNIX-like system that approximates POSIX, BSD, or System V. We know that it
runs on workstations from Sun, H-P, DEC, IBM, and SGI, as well as PCs running
Linux, BSDI, and SCO UNIX. To compile for a PC running Windows, see the README
file in the directory ../win. To compile for MacOSX, see the README file in

Changes to unix/configure.

more than 10,000 changes

Deleted unix/configure.ac.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
#! /bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tk installation
dnl	to configure the system for the local environment.

AC_INIT([tk],[8.7])
AC_PREREQ(2.69)

dnl This is only used when included from macosx/configure.ac
m4_ifdef([SC_USE_CONFIG_HEADERS], [
    AC_CONFIG_HEADERS([tkConfig.h:../unix/tkConfig.h.in])
    AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TK_CONFIG_H  -imacros tkConfig.h"])
    AH_TOP([
    #ifndef _TKCONFIG
    #define _TKCONFIG])
    AH_BOTTOM([
    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_STRING
    /* override */ #undef PACKAGE_TARNAME
    #endif /* _TKCONFIG */])
])

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
if test "${TCL_MINOR_VERSION}" -lt 6 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
fi

SC_PROG_TCLSH
SC_BUILD_TCLSH

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
    prefix="$TCL_PREFIX"
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
# Make sure srcdir is fully qualified!
srcdir="`cd "$srcdir" ; pwd`"
TK_SRC_DIR="`cd "$srcdir"/..; pwd`"

#------------------------------------------------------------------------
# Compress and/or soft link the manpages?
#------------------------------------------------------------------------

SC_CONFIG_MANPAGES

#------------------------------------------------------------------------
# Standard compiler checks
#------------------------------------------------------------------------

# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
    CFLAGS=""
fi

AC_PROG_CC
AC_C_INLINE

#------------------------------------------------------------------------
# If we're using GCC, see if the compiler understands -pipe.  If so, use it.
# It makes compiling go faster.  (This is only a performance feature.)
#------------------------------------------------------------------------

if test -z "$no_pipe" && test -n "$GCC"; then
    AC_CACHE_CHECK([if the compiler understands -pipe],
	tcl_cv_cc_pipe, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_pipe = yes; then
	CFLAGS="$CFLAGS -pipe"
    fi
fi

#------------------------------------------------------------------------
# Embedded configuration information, encoding to use for the values, TIP #59
#------------------------------------------------------------------------

SC_TCL_CFG_ENCODING

SC_ENABLE_SHARED

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

SC_ENABLE_SYMBOLS

#--------------------------------------------------------------------
#	Detect what compiler flags to set for 64-bit support.
#--------------------------------------------------------------------

SC_TCL_EARLY_FLAGS

SC_TCL_64BIT_FLAGS

#--------------------------------------------------------------------
#	Check endianness because we can optimize some operations
#--------------------------------------------------------------------

AC_C_BIGENDIAN

#------------------------------------------------------------------------
# If Tcl and Tk are installed in different places, adjust the library
# search path to reflect this.
#------------------------------------------------------------------------

LIB_RUNTIME_DIR='$(libdir)'

if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib"
fi

if test "$TCL_PREFIX" != "$prefix"; then
    AC_MSG_WARN([
        Different --prefix selected for Tk and Tcl!
        [[package require Tk]] may not work correctly in tclsh.])
fi

#--------------------------------------------------------------------
#	Include sys/select.h if it exists and if it supplies things
#	that appear to be useful and aren't already in sys/types.h.
#	This appears to be true only on the RS/6000 under AIX.  Some
#	systems like OSF/1 have a sys/select.h that's of no use, and
#	other systems like SCO UNIX have a sys/select.h that's
#	pernicious.  If "fd_set" isn't defined anywhere then set a
#	special flag.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for fd_set in sys/types], tcl_cv_type_fd_set, [
    AC_TRY_COMPILE([#include <sys/types.h>],[fd_set readMask, writeMask;],
	tcl_cv_type_fd_set=yes, tcl_cv_type_fd_set=no)])
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
    AC_CACHE_CHECK([for fd_mask in sys/select], tcl_cv_grep_fd_mask, [
	AC_EGREP_HEADER(fd_mask, sys/select.h,
	     tcl_cv_grep_fd_mask=present, tcl_cv_grep_fd_mask=missing)])
    if test $tcl_cv_grep_fd_mask = present; then
	AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Should we include <sys/select.h>?])
	tk_ok=yes
    fi
fi
if test $tk_ok = no; then
    AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?])
fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T

AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "long long" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_intptr_t" != none; then
	AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
	   type wide enough to hold a pointer.])
    fi
])
AC_CHECK_TYPE([uintptr_t], [
    AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_uintptr_t" != none; then
	AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
	   type wide enough to hold a pointer.])
    fi
])

#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

AC_CACHE_CHECK([pw_gecos in struct pwd], tcl_cv_pwd_pw_gecos, [
    AC_TRY_COMPILE([#include <pwd.h>],
	    [struct passwd pwd; (void)pwd.pw_gecos;],
	    tcl_cv_pwd_pw_gecos=yes, tcl_cv_pwd_pw_gecos=no)])
if test $tcl_cv_pwd_pw_gecos = yes; then
    AC_DEFINE(HAVE_PW_GECOS, 1, [Does struct password have a pw_gecos field?])
fi

#--------------------------------------------------------------------
#	On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------

if test "`uname -s`" = "Darwin" ; then
    AC_MSG_CHECKING([whether to use Aqua])
    AC_ARG_ENABLE(aqua,
	AC_HELP_STRING([--enable-aqua=yes|no],
	    [use Aqua windowingsystem on Mac OS X (default: no)]),
	[tk_aqua=$enableval], [tk_aqua=no])
    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    AC_MSG_WARN([Aqua can only be used when CoreFoundation is available])
	    tk_aqua=no
	fi
	if test ! -d /System/Library/Frameworks/Cocoa.framework; then
	    AC_MSG_WARN([Aqua can only be used when Cocoa is available])
	    tk_aqua=no
	fi
	if test "`uname -r | awk -F. '{print [$]1}'`" -lt 9; then
	    AC_MSG_WARN([Aqua requires Mac OS X 10.5 or later])
	    tk_aqua=no
	fi
    fi
    AC_MSG_RESULT([$tk_aqua])
    if test "$fat_32_64" = yes; then
	if test $tk_aqua = no; then
	    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
		done
		CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
		LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
		AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
		    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval $v'="$hold_'$v'"'
		done])
	fi
	# remove 64-bit arch flags from CFLAGS et al. for combined 32 & 64 bit
	# fat builds if configuration does not support 64-bit.
	if test "$tcl_cv_lib_x11_64" = no; then
	    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
	    for v in CFLAGS CPPFLAGS LDFLAGS; do
		eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
	    done
	fi
    fi
    if test $tk_aqua = no; then
	# check if weak linking whole libraries is possible.
	AC_CACHE_CHECK([if ld accepts -weak-l flag], tcl_cv_ld_weak_l, [
	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    AC_TRY_LINK([#include <math.h>], [double f = sin(1.0);],
		tcl_cv_ld_weak_l=yes, tcl_cv_ld_weak_l=no)
	    LDFLAGS=$hold_ldflags])
    fi
    AC_CHECK_HEADERS(AvailabilityMacros.h)
    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_LINK([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #endif
		    int rand(void) __attribute__((weak_import));
		], [rand();],
		tcl_cv_cc_weak_import=yes, tcl_cv_cc_weak_import=no)
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_weak_import = yes; then
	    AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
	fi
	AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
	    tcl_cv_cc_darwin_c_source, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_COMPILE([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #endif
		    #define _DARWIN_C_SOURCE 1
		    #include <sys/cdefs.h>
		],,tcl_cv_cc_darwin_c_source=yes, tcl_cv_cc_darwin_c_source=no)
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_darwin_c_source = yes; then
	    AC_DEFINE(_DARWIN_C_SOURCE, 1,
		    [Are Darwin SUSv3 extensions available?])
	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then
    AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
    EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
        AC_DEFINE(TK_MAC_DEBUG, 1, [Are TkAqua debug messages enabled?])
    fi
else
    #--------------------------------------------------------------------
    #	Locate the X11 header files and the X11 library archive.  Try
    #	the ac_path_x macro first, but if it doesn't find the X stuff
    #	(e.g. because there's no xmkmf program) then check through
    #	a list of possible directories.  Under some conditions the
    #	autoconf macro will return an include directory that contains
    #	no include files, so double-check its result just to be safe.
    #--------------------------------------------------------------------

    SC_PATH_X
    TK_WINDOWINGSYSTEM=X11
fi

#--------------------------------------------------------------------
#	Various manipulations on the search path used at runtime to
#	find shared libraries:
#	1. If the X library binaries are in a non-standard directory,
#	   add the X library location into that search path.
#	2. On systems such as AIX and Ultrix that use "-L" as the
#	   search path option, colons cannot be used to separate
#	   directories from each other. Change colons to " -L".
#	3. Create two sets of search flags, one for use in cc lines
#	   and the other for when the linker is invoked directly.  In
#	   the second case, '-Wl,' must be stripped off and commas must
#	   be replaced by spaces.
#--------------------------------------------------------------------

if test "x${x_libraries}" != "x"; then
  if test "x${x_libraries}" != "xNONE"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${x_libraries}"
  fi
fi
if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then
    LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'`
fi

#--------------------------------------------------------------------
#	Check for the existence of various libraries.  The order here
#	is important, so that then end up in the right order in the
#	command line generated by make.  The -lsocket and -lnsl libraries
#	require a couple of special tricks:
#	1. Use "connect" and "accept" to check for -lsocket, and
#	   "gethostbyname" to check for -lnsl.
#	2. Use each function name only once:  can't redo a check because
#	   autoconf caches the results of the last check and won't redo it.
#	3. Use -lnsl and -lsocket only if they supply procedures that
#	   aren't already present in the normal libraries.  This is because
#	   IRIX 5.2 has libraries, but they aren't needed and they're
#	   bogus:  they goof up name resolution if used.
#	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
#	   To get around this problem, check for both libraries together
#	   if -lsocket doesn't work by itself.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_CHECK_LIB(Xbsd, main, [LIBS="$LIBS -lXbsd"])
fi

#--------------------------------------------------------------------
# One more check related to the X libraries.  The standard releases
# of Ultrix don't support the "xauth" mechanism, so send won't work
# unless TK_NO_SECURITY is defined.  However, there are usually copies
# of the MIT X server available as well, which do support xauth.
# Check for the MIT stuff and use it if it exists.
#
# Note: can't use ac_check_lib macro (at least, not in Autoconf 2.1)
# because it can't deal with the "-" in the library name.
#--------------------------------------------------------------------

if test -d /usr/include/mit -a $tk_aqua = no; then
    AC_MSG_CHECKING([MIT X libraries])
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -I/usr/include/mit"
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lX11-mit"
    AC_TRY_LINK([
	#include <X11/Xlib.h>
    ], [
	XOpenDisplay(0);
    ], [
	AC_MSG_RESULT([yes])
	XLIBSW="-lX11-mit"
	XINCLUDES="-I/usr/include/mit"
    ], AC_MSG_RESULT([no]))
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_MSG_CHECKING([whether to use xft])
    AC_ARG_ENABLE(xft,
	AC_HELP_STRING([--enable-xft],
	    [use freetype/fontconfig/xft (default: on)]),
	[enable_xft=$enableval], [enable_xft="default"])
    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	AC_MSG_RESULT([$enable_xft])
    else
	found_xft="yes"
	dnl make sure package configurator (xft-config or pkg-config
	dnl says that xft is present.
	XFT_CFLAGS=`xft-config --cflags 2>/dev/null` || found_xft="no"
	XFT_LIBS=`xft-config --libs 2>/dev/null` || found_xft="no"
	if test "$found_xft" = "no" ; then
	    found_xft=yes
	    XFT_CFLAGS=`pkg-config --cflags xft fontconfig 2>/dev/null` || found_xft="no"
	    XFT_LIBS=`pkg-config --libs xft fontconfig 2>/dev/null` || found_xft="no"
	fi
	AC_MSG_RESULT([$found_xft])
	dnl make sure that compiling against Xft header file doesn't bomb
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    AC_CHECK_HEADER(X11/Xft/Xft.h, [], [
		found_xft=no
	    ],[#include <X11/Xlib.h>])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl make sure that linking against Xft libraries finds freetype
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    AC_CHECK_LIB(Xft, XftFontOpen, [], [
		found_xft=no
	    ])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl make sure that linking against fontconfig libraries finds Fc* symbols
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW -lfontconfig"
	    AC_CHECK_LIB(fontconfig, FcFontSort, [
		XFT_LIBS="$XFT_LIBS -lfontconfig"
	    ], [])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl print a warning if xft is unusable and was specifically requested
	if test "$found_xft" = "no" ; then
	    if test "$enable_xft" = "yes" ; then
		AC_MSG_WARN([Can't find xft configuration, or xft is unusable])
	    fi
	    enable_xft=no
	    XFT_CFLAGS=""
	    XFT_LIBS=""
	else
            enable_xft=yes
	fi
    fi
    if test $enable_xft = "yes" ; then
	UNIX_FONT_OBJS=tkUnixRFont.o
	AC_DEFINE(HAVE_XFT, 1, [Have we turned on XFT (antialiased fonts)?])
    else
	UNIX_FONT_OBJS=tkUnixFont.o
    fi
    AC_SUBST(XFT_CFLAGS)
    AC_SUBST(XFT_LIBS)
    AC_SUBST(UNIX_FONT_OBJS)
fi

#--------------------------------------------------------------------
# XXX Do this last.
# It might modify XLIBSW which could affect other tests.
#
# Check whether the header and library for the XScreenSaver
# extension are available, and set HAVE_XSS if so.
# XScreenSaver is needed for Tk_GetUserInactiveTime().
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS $XINCLUDES"
    tk_oldLibs=$LIBS
    LIBS="$tk_oldLibs $XLIBSW"
    xss_header_found=no
    xss_lib_found=no
    AC_MSG_CHECKING([whether to try to use XScreenSaver])
    AC_ARG_ENABLE(xss,
	AC_HELP_STRING([--enable-xss],
	    [use XScreenSaver for activity timer (default: on)]),
	[enable_xss=$enableval], [enable_xss=yes])
    if test "$enable_xss" = "no" ; then
	AC_MSG_RESULT([$enable_xss])
    else
	AC_MSG_RESULT([$enable_xss])
	AC_CHECK_HEADER(X11/extensions/scrnsaver.h, [
	    xss_header_found=yes
	],,[#include <X11/Xlib.h>])
	AC_CHECK_FUNC(XScreenSaverQueryInfo,,[
	    AC_CHECK_LIB(Xext, XScreenSaverQueryInfo, [
		XLIBSW="$XLIBSW -lXext"
		xss_lib_found=yes
	    ], [
		AC_CHECK_LIB(Xss, XScreenSaverQueryInfo, [
		    if test "$tcl_cv_ld_weak_l" = yes; then
			# On Darwin, weak link libXss if possible,
			# as it is only available on Tiger or later.
			XLIBSW="$XLIBSW -Wl,-weak-lXss -lXext"
		    else
			XLIBSW="$XLIBSW -lXss -lXext"
		    fi
		    xss_lib_found=yes
		],, -lXext)
	    ])
	])
    fi
    if test $enable_xss = yes -a $xss_lib_found = yes -a $xss_header_found = yes; then
	AC_DEFINE(HAVE_XSS, 1, [Is XScreenSaver available?])
    fi
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Figure out whether "char" is unsigned.  If so, set a
#	#define for __CHAR_UNSIGNED__.
#--------------------------------------------------------------------

AC_C_CHAR_UNSIGNED

#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \${TCL_STUB_LIB_SPEC}"
    TCL_STUB_FLAGS="-DUSE_TCL_STUBS"
fi

test -z "$TK_LIBRARY" && TK_LIBRARY='$(prefix)/lib/tk$(VERSION)'
PRIVATE_INCLUDE_DIR='$(includedir)'
HTML_DIR='$(DISTDIR)/html'
TK_PKG_DIR='tk$(VERSION)'
TK_RSRC_FILE='tk$(VERSION).rsrc'
WISH_RSRC_FILE='wish$(VERSION).rsrc'

# Note:  in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..":  this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.

if test "`uname -s`" = "Darwin" ; then
    SC_ENABLE_FRAMEWORK
    TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version ${TK_VERSION}`echo ${TK_PATCH_LEVEL} | awk ['{match($0, "\\\.[0-9]+"); print substr($0,RSTART,RLENGTH)}']`"
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -install_name "${DYLIB_INSTALL_DIR}/${TK_LIB_FILE}" -unexported_symbols_list $$(f=$(TK_LIB_FILE).E && nm -gp tkMacOSX*.o 2>/dev/null | awk "/^[[0-9a-f]]+ . \.objc/ {print \$$3}" > $$f && nm -gjp "$(TCL_BIN_DIR)"/$(TCL_STUB_LIB_FILE) | grep ^_[[^_]] >> $$f && echo $$f)'
    echo "$LDFLAGS " | grep -q -- '-prebind ' && TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -seg1addr 0xb000000'
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tk-Info.plist'
    EXTRA_WISH_LIBS='-sectcreate __TEXT __info_plist Wish-Info.plist'
    EXTRA_APP_CC_SWITCHES="${EXTRA_APP_CC_SWITCHES}"' -mdynamic-no-pic'
    AC_CONFIG_FILES([Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in])
    for l in ${LOCALES}; do CFBUNDLELOCALIZATIONS="${CFBUNDLELOCALIZATIONS}<string>$l</string>"; done
    TK_YEAR="`date +%Y`"
fi

if test "$FRAMEWORK_BUILD" = "1" ; then
    AC_DEFINE(TK_FRAMEWORK, 1, [Is Tk built as a framework?])
    # Construct a fake local framework structure to make linking with
    # '-framework Tk' and running of tktest work
    AC_CONFIG_COMMANDS([Tk.framework], [n=Tk &&
        f=$n.framework && v=Versions/$VERSION &&
        rm -rf $f && mkdir -p $f/$v/Resources &&
        ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
        ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
        if test $tk_aqua = yes; then ln -s ../../../../$n.rsrc $f/$v/Resources; fi &&
        unset n f v
    ], VERSION=${TK_VERSION} && tk_aqua=${tk_aqua})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    TK_LIB_FILE="Tk"
    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="-ltk${TK_VERSION}"
	else
	    TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi

#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
eval "TK_STUB_LIB_FILE=libtkstub${TK_UNSHARED_LIB_SUFFIX}"
eval "TK_STUB_LIB_DIR=${libdir}"

if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
    TK_STUB_LIB_FLAG="-ltkstub${TK_VERSION}"
else
    TK_STUB_LIB_FLAG="-ltkstub`echo ${TK_VERSION} | tr -d .`"
fi

TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir
eval "TK_INCLUDE_SPEC=\"-I${includedir}\""

#------------------------------------------------------------------------
# Demo dir
#------------------------------------------------------------------------

AS_IF([test x"${DEMO_DIR}" = x], [DEMO_DIR='$(TK_LIBRARY)/demos'])
eval "TK_DEMO_DIR=\"`echo ${DEMO_DIR} | tr '()' '{}'`\""
eval "TK_DEMO_DIR=\"`echo ${TK_DEMO_DIR} | tr '()' '{}'`\""
AC_SUBST(DEMO_DIR)
AC_SUBST(TK_DEMO_DIR)

#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_YEAR)

AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_INCLUDE_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_PATH)

AC_SUBST(TK_SRC_DIR)

AC_SUBST(TK_SHARED_BUILD)
AC_SUBST(LD_LIBRARY_PATH_VAR)

AC_SUBST(TK_BUILD_LIB_SPEC)

AC_SUBST(TCL_STUB_FLAGS)
AC_SUBST(XINCLUDES)
AC_SUBST(XLIBSW)
AC_SUBST(LOCALES)

AC_SUBST(TK_WINDOWINGSYSTEM)
AC_SUBST(TK_PKG_DIR)
AC_SUBST(TK_LIBRARY)
AC_SUBST(LIB_RUNTIME_DIR)
AC_SUBST(PRIVATE_INCLUDE_DIR)
AC_SUBST(HTML_DIR)

AC_SUBST(EXTRA_CC_SWITCHES)
AC_SUBST(EXTRA_APP_CC_SWITCHES)
AC_SUBST(EXTRA_INSTALL)
AC_SUBST(EXTRA_INSTALL_BINARIES)
AC_SUBST(EXTRA_BUILD_HTML)
AC_SUBST(EXTRA_WISH_LIBS)
AC_SUBST(CFBUNDLELOCALIZATIONS)

AC_SUBST(TK_RSRC_FILE)
AC_SUBST(WISH_RSRC_FILE)
AC_SUBST(LIB_RSRC_FILE)
AC_SUBST(APP_RSRC_FILE)
AC_SUBST(REZ)
AC_SUBST(REZ_FLAGS)

AC_CONFIG_FILES([
    Makefile:../unix/Makefile.in
    tkConfig.sh:../unix/tkConfig.sh.in
    tk.pc:../unix/tk.pc.in
])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf
dnl End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added unix/configure.in.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
#! /bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tk installation
dnl	to configure the system for the local environment.

AC_INIT([tk],[8.5])
AC_PREREQ([2.59])

dnl This is only used when included from macosx/configure.ac
m4_ifdef([SC_USE_CONFIG_HEADERS], [
    AC_CONFIG_HEADERS([tkConfig.h:../unix/tkConfig.h.in])
    AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TK_CONFIG_H  -imacros tkConfig.h"])
    AH_TOP([
    #ifndef _TKCONFIG
    #define _TKCONFIG])
    AH_BOTTOM([
    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */])
])

TK_VERSION=8.5
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=5
TK_PATCH_LEVEL=".19"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.5+
Found config for Tcl ${TCL_VERSION}])
fi
if test "${TCL_MINOR_VERSION}" -lt 5 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.5+
Found config for Tcl ${TCL_VERSION}])
fi

SC_PROG_TCLSH
SC_BUILD_TCLSH

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
    prefix="$TCL_PREFIX"
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
# Make sure srcdir is fully qualified!
srcdir="`cd "$srcdir" ; pwd`"
TK_SRC_DIR="`cd "$srcdir"/..; pwd`"

#------------------------------------------------------------------------
# Compress and/or soft link the manpages?
#------------------------------------------------------------------------

SC_CONFIG_MANPAGES

#------------------------------------------------------------------------
# Standard compiler checks
#------------------------------------------------------------------------

# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
    CFLAGS=""
fi

AC_PROG_CC

# limits header checks must come early to prevent
# an autoconf bug that throws errors on configure
AC_CHECK_HEADER(limits.h,
    [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
    [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])

#--------------------------------------------------------------------
# Supply a substitute for stdlib.h if it doesn't define strtol,
# strtoul, or strtod (which it doesn't in some versions of SunOS).
#--------------------------------------------------------------------

AC_CHECK_HEADER(stdlib.h, tk_ok=1, tk_ok=0)
AC_EGREP_HEADER(strtol, stdlib.h, , tk_ok=0)
AC_EGREP_HEADER(strtoul, stdlib.h, , tk_ok=0)
AC_EGREP_HEADER(strtod, stdlib.h, , tk_ok=0)
if test $tk_ok = 0; then
    AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
fi

#------------------------------------------------------------------------
# If we're using GCC, see if the compiler understands -pipe.  If so, use it.
# It makes compiling go faster.  (This is only a performance feature.)
#------------------------------------------------------------------------

if test -z "$no_pipe" && test -n "$GCC"; then
    AC_CACHE_CHECK([if the compiler understands -pipe],
	tcl_cv_cc_pipe, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	AC_TRY_COMPILE(,,[tcl_cv_cc_pipe=yes],[tcl_cv_cc_pipe=no])
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_pipe = yes; then
	CFLAGS="$CFLAGS -pipe"
    fi
fi

#------------------------------------------------------------------------
# Threads support - this auto-enables if Tcl was compiled threaded
#------------------------------------------------------------------------

SC_ENABLE_THREADS

# Add the threads support libraries
LIBS="$LIBS$THREADS_LIBS"

SC_ENABLE_SHARED

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

SC_ENABLE_SYMBOLS

#--------------------------------------------------------------------
#	Detect what compiler flags to set for 64-bit support.
#--------------------------------------------------------------------

SC_TCL_EARLY_FLAGS

SC_TCL_64BIT_FLAGS

#--------------------------------------------------------------------
#	Check endianness because we can optimize some operations
#--------------------------------------------------------------------

AC_C_BIGENDIAN

#------------------------------------------------------------------------
# If Tcl and Tk are installed in different places, adjust the library
# search path to reflect this.
#------------------------------------------------------------------------

LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}'

if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib"
fi

if test "$TCL_PREFIX" != "$prefix"; then
    AC_MSG_WARN([
        Different --prefix selected for Tk and Tcl!
        [[package require Tk]] may not work correctly in tclsh.])
fi

#--------------------------------------------------------------------
#	Include sys/select.h if it exists and if it supplies things
#	that appear to be useful and aren't already in sys/types.h.
#	This appears to be true only on the RS/6000 under AIX.  Some
#	systems like OSF/1 have a sys/select.h that's of no use, and
#	other systems like SCO UNIX have a sys/select.h that's
#	pernicious.  If "fd_set" isn't defined anywhere then set a
#	special flag.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for fd_set in sys/types], tcl_cv_type_fd_set, [
    AC_TRY_COMPILE([#include <sys/types.h>],[fd_set readMask, writeMask;],
	[tcl_cv_type_fd_set=yes],[tcl_cv_type_fd_set=no])])
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
    AC_CACHE_CHECK([for fd_mask in sys/select], tcl_cv_grep_fd_mask, [
	AC_EGREP_HEADER(fd_mask, sys/select.h,
	     tcl_cv_grep_fd_mask=present, tcl_cv_grep_fd_mask=missing)])
    if test $tcl_cv_grep_fd_mask = present; then
	AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Should we include <sys/select.h>?])
	tk_ok=yes
    fi
fi
if test $tk_ok = no; then
    AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?])
fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME

#--------------------------------------------------------------------
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------

SC_BUGGY_STRTOD

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T

AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
#include <stdint.h>
]])

#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

AC_CACHE_CHECK([pw_gecos in struct pwd], tcl_cv_pwd_pw_gecos, [
    AC_TRY_COMPILE([#include <pwd.h>],
	    [struct passwd pwd; (void)pwd.pw_gecos;],
	    [tcl_cv_pwd_pw_gecos=yes],[tcl_cv_pwd_pw_gecos=no])])
if test $tcl_cv_pwd_pw_gecos = yes; then
    AC_DEFINE(HAVE_PW_GECOS, 1, [Does struct password have a pw_gecos field?])
fi

#--------------------------------------------------------------------
#	On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------

if test "`uname -s`" = "Darwin" ; then
    AC_MSG_CHECKING([whether to use Aqua])
    AC_ARG_ENABLE(aqua,
	AS_HELP_STRING([--enable-aqua=yes|no],
	    [use Aqua windowingsystem on Mac OS X (default: no)]),
	[tk_aqua=$enableval], [tk_aqua=no])
    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    AC_MSG_WARN([Aqua can only be used when CoreFoundation is available])
	    tk_aqua=no
	fi
	if test ! -d /System/Library/Frameworks/Cocoa.framework; then
	    AC_MSG_WARN([Aqua can only be used when Cocoa is available])
	    tk_aqua=no
	fi
	if test "`uname -r | awk -F. '{print [$]1}'`" -lt 9; then
	    AC_MSG_WARN([Aqua requires Mac OS X 10.5 or later])
	    tk_aqua=no
	fi
    fi
    AC_MSG_RESULT([$tk_aqua])
    if test "$fat_32_64" = yes; then
	if test $tk_aqua = no; then
	    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
		done
		CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
		LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
		AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
		    [tcl_cv_lib_x11_64=yes],[tcl_cv_lib_x11_64=no])
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval $v'="$hold_'$v'"'
		done])
	fi
	# remove 64-bit arch flags from CFLAGS et al. for combined 32 & 64 bit
	# fat builds if configuration does not support 64-bit.
	if test "$tcl_cv_lib_x11_64" = no; then
	    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
	    for v in CFLAGS CPPFLAGS LDFLAGS; do
		eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
	    done
	fi
    fi
    if test $tk_aqua = no; then
	# check if weak linking whole libraries is possible.
	AC_CACHE_CHECK([if ld accepts -weak-l flag], tcl_cv_ld_weak_l, [
	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    AC_TRY_LINK([#include <math.h>], [double f = sin(1.0);],
		    [tcl_cv_ld_weak_l=yes],[tcl_cv_ld_weak_l=no])
	    LDFLAGS=$hold_ldflags])
    fi
    AC_CHECK_HEADERS(AvailabilityMacros.h)
    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_LINK([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #endif
		    int rand(void) __attribute__((weak_import));
		], [rand();],
		[tcl_cv_cc_weak_import=yes],[tcl_cv_cc_weak_import=no])
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_weak_import = yes; then
	    AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
	fi
	AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
	    tcl_cv_cc_darwin_c_source, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_COMPILE([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #endif
		    #define _DARWIN_C_SOURCE 1
		    #include <sys/cdefs.h>
		],,[tcl_cv_cc_darwin_c_source=yes],[tcl_cv_cc_darwin_c_source=no])
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_darwin_c_source = yes; then
	    AC_DEFINE(_DARWIN_C_SOURCE, 1,
		    [Are Darwin SUSv3 extensions available?])
	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then
    AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
    EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
        AC_DEFINE(TK_MAC_DEBUG, 1, [Are TkAqua debug messages enabled?])
    fi
else
    #--------------------------------------------------------------------
    #	Locate the X11 header files and the X11 library archive.  Try
    #	the ac_path_x macro first, but if it doesn't find the X stuff
    #	(e.g. because there's no xmkmf program) then check through
    #	a list of possible directories.  Under some conditions the
    #	autoconf macro will return an include directory that contains
    #	no include files, so double-check its result just to be safe.
    #--------------------------------------------------------------------

    SC_PATH_X
    TK_WINDOWINGSYSTEM=X11
fi

#--------------------------------------------------------------------
#	Various manipulations on the search path used at runtime to
#	find shared libraries:
#	1. If the X library binaries are in a non-standard directory,
#	   add the X library location into that search path.
#	2. On systems such as AIX and Ultrix that use "-L" as the
#	   search path option, colons cannot be used to separate
#	   directories from each other. Change colons to " -L".
#	3. Create two sets of search flags, one for use in cc lines
#	   and the other for when the linker is invoked directly.  In
#	   the second case, '-Wl,' must be stripped off and commas must
#	   be replaced by spaces.
#--------------------------------------------------------------------

if test "x${x_libraries}" != "x"; then
  if test "x${x_libraries}" != "xNONE"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${x_libraries}"
  fi
fi
if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then
    LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'`
fi

#--------------------------------------------------------------------
#	Check for the existence of various libraries.  The order here
#	is important, so that then end up in the right order in the
#	command line generated by make.  The -lsocket and -lnsl libraries
#	require a couple of special tricks:
#	1. Use "connect" and "accept" to check for -lsocket, and
#	   "gethostbyname" to check for -lnsl.
#	2. Use each function name only once:  can't redo a check because
#	   autoconf caches the results of the last check and won't redo it.
#	3. Use -lnsl and -lsocket only if they supply procedures that
#	   aren't already present in the normal libraries.  This is because
#	   IRIX 5.2 has libraries, but they aren't needed and they're
#	   bogus:  they goof up name resolution if used.
#	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
#	   To get around this problem, check for both libraries together
#	   if -lsocket doesn't work by itself.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_CHECK_LIB(Xbsd, main, [LIBS="$LIBS -lXbsd"])
fi

#--------------------------------------------------------------------
# One more check related to the X libraries.  The standard releases
# of Ultrix don't support the "xauth" mechanism, so send won't work
# unless TK_NO_SECURITY is defined.  However, there are usually copies
# of the MIT X server available as well, which do support xauth.
# Check for the MIT stuff and use it if it exists.
#
# Note: can't use ac_check_lib macro (at least, not in Autoconf 2.1)
# because it can't deal with the "-" in the library name.
#--------------------------------------------------------------------

if test -d /usr/include/mit -a $tk_aqua = no; then
    AC_MSG_CHECKING([MIT X libraries])
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -I/usr/include/mit"
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lX11-mit"
    AC_TRY_LINK([
	#include <X11/Xlib.h>
    ], [
	XOpenDisplay(0);
    ], [
	AC_MSG_RESULT([yes])
	XLIBSW="-lX11-mit"
	XINCLUDES="-I/usr/include/mit"
    ],[AC_MSG_RESULT(no)])
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_MSG_CHECKING([whether to use xft])
    AC_ARG_ENABLE(xft,
	AS_HELP_STRING([--enable-xft],
	    [use freetype/fontconfig/xft (default: on)]),
	[enable_xft=$enableval], [enable_xft="default"])
    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	AC_MSG_RESULT([$enable_xft])
    else
	found_xft="yes"
	dnl make sure package configurator (xft-config or pkg-config
	dnl says that xft is present.
	XFT_CFLAGS=`xft-config --cflags 2>/dev/null` || found_xft="no"
	XFT_LIBS=`xft-config --libs 2>/dev/null` || found_xft="no"
	if test "$found_xft" = "no" ; then
	    found_xft=yes
	    XFT_CFLAGS=`pkg-config --cflags xft fontconfig 2>/dev/null` || found_xft="no"
	    XFT_LIBS=`pkg-config --libs xft fontconfig 2>/dev/null` || found_xft="no"
	fi
	AC_MSG_RESULT([$found_xft])
	dnl make sure that compiling against Xft header file doesn't bomb
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    AC_CHECK_HEADER(X11/Xft/Xft.h, [], [
		found_xft=no
	    ],[#include <X11/Xlib.h>])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl make sure that linking against Xft libraries finds freetype
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    AC_CHECK_LIB(Xft, XftFontOpen, [], [
		found_xft=no
	    ])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl make sure that linking against fontconfig libraries finds Fc* symbols
	if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW -lfontconfig"
	    AC_CHECK_LIB(fontconfig, FcFontSort, [
		XFT_LIBS="$XFT_LIBS -lfontconfig"
	    ], [])
	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
	dnl print a warning if xft is unusable and was specifically requested
	if test "$found_xft" = "no" ; then
	    if test "$enable_xft" = "yes" ; then
		AC_MSG_WARN([Can't find xft configuration, or xft is unusable])
	    fi
	    enable_xft=no
	    XFT_CFLAGS=""
	    XFT_LIBS=""
	else
            enable_xft=yes
	fi
    fi
    if test $enable_xft = "yes" ; then
	UNIX_FONT_OBJS=tkUnixRFont.o
	AC_DEFINE(HAVE_XFT, 1, [Have we turned on XFT (antialiased fonts)?])
    else
	UNIX_FONT_OBJS=tkUnixFont.o
    fi
    AC_SUBST(XFT_CFLAGS)
    AC_SUBST(XFT_LIBS)
    AC_SUBST(UNIX_FONT_OBJS)
fi

#--------------------------------------------------------------------
#	Check for XkbKeycodeToKeysym.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    tk_oldCFlags=$CFLAGS
    tk_oldLibs=$LIBS
    CFLAGS="$CFLAGS $XINCLUDES"
    LIBS="$LIBS $XLIBSW"
    AC_CHECK_HEADER(X11/XKBlib.h, [
	xkblib_header_found=yes
    ], [
	xkblib_header_found=no
    ], [#include <X11/Xlib.h>])
    if test $xkblib_header_found = "yes" ; then
	AC_CHECK_LIB(X11, XkbKeycodeToKeysym, [
	    xkbkeycodetokeysym_found=yes
	], [
	    xkbkeycodetokeysym_found=no
	])
    else
	xkbkeycodetokeysym_found=no
    fi
    if test $xkbkeycodetokeysym_found = "yes" ; then
	AC_DEFINE(HAVE_XKBKEYCODETOKEYSYM, 1, [Do we have XkbKeycodeToKeysym?])
    fi
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
# XXX Do this last.
# It might modify XLIBSW which could affect other tests.
#
# Check whether the header and library for the XScreenSaver
# extension are available, and set HAVE_XSS if so.
# XScreenSaver is needed for Tk_GetUserInactiveTime().
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS $XINCLUDES"
    tk_oldLibs=$LIBS
    LIBS="$tk_oldLibs $XLIBSW"
    xss_header_found=no
    xss_lib_found=no
    AC_MSG_CHECKING([whether to try to use XScreenSaver])
    AC_ARG_ENABLE(xss,
	AS_HELP_STRING([--enable-xss],
	    [use XScreenSaver for activity timer (default: on)]),
	[enable_xss=$enableval], [enable_xss=yes])
    if test "$enable_xss" = "no" ; then
	AC_MSG_RESULT([$enable_xss])
    else
	AC_MSG_RESULT([$enable_xss])
	AC_CHECK_HEADER(X11/extensions/scrnsaver.h, [
	    xss_header_found=yes
	],,[#include <X11/Xlib.h>])
	AC_CHECK_FUNC(XScreenSaverQueryInfo,,[
	    AC_CHECK_LIB(Xext, XScreenSaverQueryInfo, [
		XLIBSW="$XLIBSW -lXext"
		xss_lib_found=yes
	    ], [
		AC_CHECK_LIB(Xss, XScreenSaverQueryInfo, [
		    if test "$tcl_cv_ld_weak_l" = yes; then
			# On Darwin, weak link libXss if possible,
			# as it is only available on Tiger or later.
			XLIBSW="$XLIBSW -Wl,-weak-lXss -lXext"
		    else
			XLIBSW="$XLIBSW -lXss -lXext"
		    fi
		    xss_lib_found=yes
		],, -lXext)
	    ])
	])
    fi
    if test $enable_xss = yes -a $xss_lib_found = yes -a $xss_header_found = yes; then
	AC_DEFINE(HAVE_XSS, 1, [Is XScreenSaver available?])
    fi
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Figure out whether "char" is unsigned.  If so, set a
#	#define for __CHAR_UNSIGNED__.
#--------------------------------------------------------------------

AC_C_CHAR_UNSIGNED

#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \${TCL_STUB_LIB_SPEC}"
    TCL_STUB_FLAGS="-DUSE_TCL_STUBS"
fi

test -z "$TK_LIBRARY" && TK_LIBRARY='$(prefix)/lib/tk$(VERSION)'
PRIVATE_INCLUDE_DIR='$(includedir)'
HTML_DIR='$(DISTDIR)/html'
TK_PKG_DIR='tk$(VERSION)'
TK_RSRC_FILE='tk$(VERSION).rsrc'
WISH_RSRC_FILE='wish$(VERSION).rsrc'

# Note:  in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..":  this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.

if test "`uname -s`" = "Darwin" ; then
    SC_ENABLE_FRAMEWORK
    TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version ${TK_VERSION}`echo ${TK_PATCH_LEVEL} | awk ['{match($0, "\\\.[0-9]+"); print substr($0,RSTART,RLENGTH)}']`"
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -install_name "${DYLIB_INSTALL_DIR}/${TK_LIB_FILE}" -unexported_symbols_list $$(f=$(TK_LIB_FILE).E && nm -gp tkMacOSX*.o 2>/dev/null | awk "/^[[0-9a-f]]+ . \.objc/ {print \$$3}" > $$f && nm -gjp "$(TCL_BIN_DIR)"/$(TCL_STUB_LIB_FILE) | grep ^_[[^_]] >> $$f && echo $$f)'
    echo "$LDFLAGS " | grep -q -- '-prebind ' && TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -seg1addr 0xb000000'
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tk-Info.plist'
    EXTRA_WISH_LIBS='-sectcreate __TEXT __info_plist Wish-Info.plist'
    EXTRA_APP_CC_SWITCHES="${EXTRA_APP_CC_SWITCHES}"' -mdynamic-no-pic'
    AC_CONFIG_FILES([Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in])
    for l in ${LOCALES}; do CFBUNDLELOCALIZATIONS="${CFBUNDLELOCALIZATIONS}<string>$l</string>"; done
    TK_YEAR="`date +%Y`"
fi

if test "$FRAMEWORK_BUILD" = "1" ; then
    AC_DEFINE(TK_FRAMEWORK, 1, [Is Tk built as a framework?])
    # Construct a fake local framework structure to make linking with
    # '-framework Tk' and running of tktest work
    AC_CONFIG_COMMANDS([Tk.framework], [n=Tk &&
        f=$n.framework && v=Versions/$VERSION &&
        rm -rf $f && mkdir -p $f/$v/Resources &&
        ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
        ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
        if test $tk_aqua = yes; then ln -s ../../../../$n.rsrc $f/$v/Resources; fi &&
        unset n f v
    ], VERSION=${TK_VERSION} && tk_aqua=${tk_aqua})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    TK_LIB_FILE="Tk"
    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && mkdir -p "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources" && mkdir -p "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'" && mkdir -p "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && mkdir -p "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && mkdir -p "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="-ltk${TK_VERSION}"
	else
	    TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi

#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
eval "TK_STUB_LIB_FILE=libtkstub${TK_UNSHARED_LIB_SUFFIX}"
eval "TK_STUB_LIB_DIR=${libdir}"

if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
    TK_STUB_LIB_FLAG="-ltkstub${TK_VERSION}"
else
    TK_STUB_LIB_FLAG="-ltkstub`echo ${TK_VERSION} | tr -d .`"
fi

TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir
eval "TK_INCLUDE_SPEC=\"-I${includedir}\""

#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_YEAR)

AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_INCLUDE_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_PATH)

AC_SUBST(TK_SRC_DIR)

AC_SUBST(TK_SHARED_BUILD)
AC_SUBST(LD_LIBRARY_PATH_VAR)

AC_SUBST(TK_BUILD_LIB_SPEC)

AC_SUBST(TCL_STUB_FLAGS)
AC_SUBST(XINCLUDES)
AC_SUBST(XLIBSW)
AC_SUBST(LOCALES)

AC_SUBST(TK_WINDOWINGSYSTEM)
AC_SUBST(TK_PKG_DIR)
AC_SUBST(TK_LIBRARY)
AC_SUBST(LIB_RUNTIME_DIR)
AC_SUBST(PRIVATE_INCLUDE_DIR)
AC_SUBST(HTML_DIR)

AC_SUBST(EXTRA_CC_SWITCHES)
AC_SUBST(EXTRA_APP_CC_SWITCHES)
AC_SUBST(EXTRA_INSTALL)
AC_SUBST(EXTRA_INSTALL_BINARIES)
AC_SUBST(EXTRA_BUILD_HTML)
AC_SUBST(EXTRA_WISH_LIBS)
AC_SUBST(CFBUNDLELOCALIZATIONS)

AC_SUBST(TK_RSRC_FILE)
AC_SUBST(WISH_RSRC_FILE)
AC_SUBST(LIB_RSRC_FILE)
AC_SUBST(APP_RSRC_FILE)
AC_SUBST(REZ)
AC_SUBST(REZ_FLAGS)

AC_CONFIG_FILES([
    Makefile:../unix/Makefile.in
    tkConfig.sh:../unix/tkConfig.sh.in
    tk.pc:../unix/tk.pc.in
])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf
dnl End:

Changes to unix/install-sh.

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2020-07-26.22; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#



|







1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2011-04-20.01; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51

52



53
54
55
56
57
58
59
60
61
62
63
64
65











66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

tab='	'
nl='
'
IFS=" $tab$nl"

# Set DOITPROG to "echo" to test this script.


doit=${DOITPROG-}

doit_exec=${doit:-exec}




# Put in absolute file names if you don't have them in your path;
# or use environment vars.

chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}












posix_mkdir=

# Desired mode of installed file.
mode=0755

# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22

chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
dst_arg=

copy_on_change=false
is_target_a_directory=possibly

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...








|





<


|

|

>

>
|
>
>
>













>
>
>
>
>
>
>
>
>
>
>






<
<
<
<













|







31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86




87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.


nl='
'
IFS=" ""	$nl"

# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
  doit_exec=exec
else
  doit_exec=$doit
fi

# Put in absolute file names if you don't have them in your path;
# or use environment vars.

chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}

posix_glob='?'
initialize_posix_glob='
  test "$posix_glob" != "?" || {
    if (set -f) 2>/dev/null; then
      posix_glob=
    else
      posix_glob=:
    fi
  }
'

posix_mkdir=

# Desired mode of installed file.
mode=0755





chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
dst_arg=

copy_on_change=false
no_target_directory=

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -S OPTION     $stripprog installed files using OPTION.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
        shift;;

    --help) echo "$usage"; exit $?;;

    -m) mode=$2
        case $mode in

          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
        shift;;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
        shift;;

    -t)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
          -* | [=\(\)!]) dst_arg=./$dst_arg;;
        esac
        shift;;

    -T) is_target_a_directory=never;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --) shift
        break;;

    -*) echo "$0: invalid option: $1" >&2
        exit 1;;

    *)  break;;
  esac
  shift
done

# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.

if test -n "$dir_arg"; then
  if test -n "$dst_arg"; then
    echo "$0: target directory not allowed when installing a directory." >&2
    exit 1
  fi
fi

if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
    # Protect names problematic for 'test' and other utilities.
    case $dst_arg in
      -* | [=\(\)!]) dst_arg=./$dst_arg;;
    esac
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call 'install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  if test $# -gt 1 || test "$is_target_a_directory" = always; then
    if test ! -d "$dst_arg"; then
      echo "$0: $dst_arg: Is not a directory." >&2
      exit 1
    fi
  fi
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
        u_plus_rw=
      else
        u_plus_rw='% 200'
      fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
        u_plus_rw=
      else
        u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names problematic for 'test' and other utilities.
  case $src in
    -* | [=\(\)!]) src=./$src;;
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?







|

















|




|
>
|
|
|
|
|


|




|

<
<
|
<
<
<
<
|

|



|
|

|
|






<
<
<
<
<
<
<
<
<
<













<
<
<
<








|




<
<
<
<
<
<
<
<
<
















|

|




|

|







|

|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


162




163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179










180
181
182
183
184
185
186
187
188
189
190
191
192




193
194
195
196
197
198
199
200
201
202
203
204
205









206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -S            $stripprog installed files.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
	shift;;

    --help) echo "$usage"; exit $?;;

    -m) mode=$2
	case $mode in
	  *' '* | *'	'* | *'
'*	  | *'*'* | *'?'* | *'['*)
	    echo "$0: invalid mode: $mode" >&2
	    exit 1;;
	esac
	shift;;

    -o) chowncmd="$chownprog $2"
	shift;;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
	shift;;



    -t) dst_arg=$2




	shift;;

    -T) no_target_directory=true;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --)	shift
	break;;

    -*)	echo "$0: invalid option: $1" >&2
	exit 1;;

    *)  break;;
  esac
  shift
done











if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg




  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call `install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi










if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw='% 200'
      fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names starting with `-'.
  case $src in
    -*) src=./$src;;
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
273
274
275
276
277
278
279

280




281
282

283
284
285
286
287
288
289
290
291
292
293
294
295

296

























297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
















312
313
314
315
316
317
318
319
320
321
322





323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382


383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470


471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi

    dst=$dst_arg





    # If destination is a directory, append the input filename.

    if test -d "$dst"; then
      if test "$is_target_a_directory" = never; then
        echo "$0: $dst_arg: Is a directory" >&2
        exit 1
      fi
      dstdir=$dst
      dstbase=`basename "$src"`
      case $dst in
	*/) dst=$dst$dstbase;;
	*)  dst=$dst/$dstbase;;
      esac
      dstdir_status=0
    else

      dstdir=`dirname "$dst"`

























      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  case $dstdir in
    */) dstdirslash=$dstdir;;
    *)  dstdirslash=$dstdir/;;
  esac

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
















        # With -d, create the new directory with the user-specified mode.
        # Otherwise, rely on $mkdir_umask.
        if test -n "$dir_arg"; then
          mkdir_mode=-m$mode
        else
          mkdir_mode=
        fi

        posix_mkdir=false
	# The $RANDOM variable is not portable (e.g., dash).  Use it
	# here however when possible just to lower collision chance.





	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$

	trap '
	  ret=$?
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
	  exit $ret
	' 0

	# Because "mkdir -p" follows existing symlinks and we likely work
	# directly in world-writeable /tmp, make sure that the '$tmpdir'
	# directory is successfully created first before we actually test
	# 'mkdir -p'.
	if (umask $mkdir_umask &&
	    $mkdirprog $mkdir_mode "$tmpdir" &&
	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
	then
	  if test -z "$dir_arg" || {
	       # Check for POSIX incompatibilities with -m.
	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
	       # other-writable bit of parent directory when it shouldn't.
	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
	       test_tmpdir="$tmpdir/a"
	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
	       case $ls_ld_tmpdir in
		 d????-?r-*) different_mode=700;;
		 d????-?--*) different_mode=755;;
		 *) false;;
	       esac &&
	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
	       }
	     }
	  then posix_mkdir=:
	  fi
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
	else
	  # Remove any dirs left behind by ancient mkdir implementations.
	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
	fi
	trap '' 0;;

    esac

    if
      $posix_mkdir && (
        umask $mkdir_umask &&
        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

      # mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
        /*) prefix='/';;
        [-=\(\)!]*) prefix='./';;
        *)  prefix='';;
      esac



      oIFS=$IFS
      IFS=/
      set -f
      set fnord $dstdir
      shift
      set +f
      IFS=$oIFS

      prefixes=

      for d
      do
        test X"$d" = X && continue

        prefix=$prefix$d
        if test -d "$prefix"; then
          prefixes=
        else
          if $posix_mkdir; then
            (umask $mkdir_umask &&
             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
            # Don't fail if two instances are running concurrently.
            test -d "$prefix" || exit 1
          else
            case $prefix in
              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
              *) qprefix=$prefix;;
            esac
            prefixes="$prefixes '$qprefix'"
          fi
        fi
        prefix=$prefix/
      done

      if test -n "$prefixes"; then
        # Don't fail if two instances are running concurrently.
        (umask $mkdir_umask &&
         eval "\$doit_exec \$mkdirprog $prefixes") ||
          test -d "$dstdir" || exit 1
        obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=${dstdirslash}_inst.$$_
    rmtmp=${dstdirslash}_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.
    (umask $cp_umask &&
     { test -z "$stripcmd" || {
	 # Create $dsttmp read-write so that cp doesn't create it read-only,
	 # which would cause strip to fail.
	 if test -z "$doit"; then
	   : >"$dsttmp" # No need to fork-exec 'touch'.
	 else
	   $doit touch "$dsttmp"
	 fi
       }
     } &&
     $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&


       set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd -f "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

        # Now rename the file to the real destination.
        $doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:







>

>
>
>
>

|
>

|
|
|


|
<
<
<
<


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
<
<
<
<





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|

|
|
<
>
>
>
>
>
|
|
<
<
<
<
<

<
<
<
<
|
<
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>




|
|




|




|
|
|

>
>



|


|






|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|












|
|





<
<
<
<
<
<
<
<
<
<
<
|














|
|
>
>
|


|
>












|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|








|


|


256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278




279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312





313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350





351




352

353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460











461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi

    dst=$dst_arg
    # Protect names starting with `-'.
    case $dst in
      -*) dst=./$dst;;
    esac

    # If destination is a directory, append the input filename; won't work
    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test -n "$no_target_directory"; then
	echo "$0: $dst_arg: Is a directory" >&2
	exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`




      dstdir_status=0
    else
      # Prefer dirname, but fall back on a substitute if dirname fails.
      dstdir=`
	(dirname "$dst") 2>/dev/null ||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	     X"$dst" : 'X\(//\)[^/]' \| \
	     X"$dst" : 'X\(//\)$' \| \
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
	echo X"$dst" |
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)[^/].*/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\).*/{
		   s//\1/
		   q
		 }
		 s/.*/./; q'
      `

      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi






  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
	# Create intermediate dirs using mode 755 as modified by the umask.
	# This is like FreeBSD 'install' as of 1997-10-28.
	umask=`umask`
	case $stripcmd.$umask in
	  # Optimize common cases.
	  *[2367][2367]) mkdir_umask=$umask;;
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

	  *[0-7])
	    mkdir_umask=`expr $umask + 22 \
	      - $umask % 100 % 40 + $umask % 20 \
	      - $umask % 10 % 4 + $umask % 2
	    `;;
	  *) mkdir_umask=$umask,go-w;;
	esac

	# With -d, create the new directory with the user-specified mode.
	# Otherwise, rely on $mkdir_umask.
	if test -n "$dir_arg"; then
	  mkdir_mode=-m$mode
	else
	  mkdir_mode=
	fi

	posix_mkdir=false
	case $umask in

	  *[123567][0-7][0-7])
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
	    ;;
	  *)
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0










	    if (umask $mkdir_umask &&

		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
	    then
	      if test -z "$dir_arg" || {
		   # Check for POSIX incompatibilities with -m.
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
		   # other-writeable bit of parent directory when it shouldn't.
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.

		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
		   case $ls_ld_tmpdir in
		     d????-?r-*) different_mode=700;;
		     d????-?--*) different_mode=755;;
		     *) false;;
		   esac &&
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
		   }
		 }
	      then posix_mkdir=:
	      fi
	      rmdir "$tmpdir/d" "$tmpdir"
	    else
	      # Remove any dirs left behind by ancient mkdir implementations.
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
	    fi
	    trap '' 0;;
	esac;;
    esac

    if
      $posix_mkdir && (
	umask $mkdir_umask &&
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
	/*) prefix='/';;
	-*) prefix='./';;
	*)  prefix='';;
      esac

      eval "$initialize_posix_glob"

      oIFS=$IFS
      IFS=/
      $posix_glob set -f
      set fnord $dstdir
      shift
      $posix_glob set +f
      IFS=$oIFS

      prefixes=

      for d
      do
	test -z "$d" && continue

	prefix=$prefix$d
	if test -d "$prefix"; then
	  prefixes=
	else
	  if $posix_mkdir; then
	    (umask=$mkdir_umask &&
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
	    # Don't fail if two instances are running concurrently.
	    test -d "$prefix" || exit 1
	  else
	    case $prefix in
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
	      *) qprefix=$prefix;;
	    esac
	    prefixes="$prefixes '$qprefix'"
	  fi
	fi
	prefix=$prefix/
      done

      if test -n "$prefixes"; then
	# Don't fail if two instances are running concurrently.
	(umask $mkdir_umask &&
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
	  test -d "$dstdir" || exit 1
	obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
    rmtmp=$dstdir/_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.











    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&

       eval "$initialize_posix_glob" &&
       $posix_glob set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       $posix_glob set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
	# Now remove or move aside any old file at destination location.
	# We try this two ways since rm can't unlink itself on some
	# systems and the destination file might be busy for other
	# reasons.  In this case, the final cleanup might fail but the new
	# file should still install successfully.
	{
	  test ! -f "$dst" ||
	  $doit $rmcmd -f "$dst" 2>/dev/null ||
	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
	  } ||
	  { echo "$0: cannot unlink or rename $dst" >&2
	    (exit 1); exit 1
	  }
	} &&

	# Now rename the file to the real destination.
	$doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Changes to unix/installManPage.

55
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

# A sed script to parse the alternative names out of a man page.
#
# Backslashes are trippled in the sed script, because it is in
# backticks which doesn't pass backslashes literally.
#
Names=`sed -n '
#                               Look for a line that starts with .SH NAME


    /^\.SH NAME/{
#                               Read next line
	n
#                               Remove all commas ...
	s/,//g
#                               ... and backslash-escaped spaces.
	s/\\\ //g
#                               Delete from \- to the end of line
	s/ \\\-.*//
#                               Convert all non-space non-alphanum sequences
#                               to single underscores.
	s/[^ A-Za-z0-9][^ A-Za-z0-9]*/_/g
#                               print the result and exit
	p;q
    }' $ManPage`

if test -z "$Names" ; then
    echo "warning: no target names found in $ManPage"
fi







|
>
>









<
<
<







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73



74
75
76
77
78
79
80

# A sed script to parse the alternative names out of a man page.
#
# Backslashes are trippled in the sed script, because it is in
# backticks which doesn't pass backslashes literally.
#
Names=`sed -n '
#                               Look for a line, that starts with .SH NAME
#                               optionally allow NAME to be surrounded
#                               by quotes.
    /^\.SH NAME/{
#                               Read next line
	n
#                               Remove all commas ...
	s/,//g
#                               ... and backslash-escaped spaces.
	s/\\\ //g
#                               Delete from \- to the end of line
	s/ \\\-.*//



#                               print the result and exit
	p;q
    }' $ManPage`

if test -z "$Names" ; then
    echo "warning: no target names found in $ManPage"
fi
113
114
115
116
117
118
119
120
121
122
123
124
125
    if test -z "$First" ; then
	First=$Target
	sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
	    $ManPage > "$Dir/$First"
	chmod 644 "$Dir/$First"
	$Gzip "$Dir/$First"
    else
	ln "$SymOrLoc$First$Gz" "$Dir/$Target$Gz"
    fi
done

########################################################################
exit 0







|





112
113
114
115
116
117
118
119
120
121
122
123
124
    if test -z "$First" ; then
	First=$Target
	sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
	    $ManPage > "$Dir/$First"
	chmod 644 "$Dir/$First"
	$Gzip "$Dir/$First"
    else
	ln $SymOrLoc"$First$Gz" "$Dir/$Target$Gz"
    fi
done

########################################################################
exit 0

Changes to unix/tcl.m4.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )







|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    [with_tclconfig="${withval}"])
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \

			; do
		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.7 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi
	])

	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])







>
















|


|
|
















|
|
|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			; do
		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
		    break
		fi
		done
	    fi
	])

	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )







|

|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    [with_tkconfig="${withval}"])
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \

			; do
		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tk8.7 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.7 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.7 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi







>
















|


|
|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			; do
		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tk8.5 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
288
289
290
291
292
293
294




295
296
297
298
299
300
301

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
    fi





    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.







>
>
>
>







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""

    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
321
322
323
324
325
326
327






328
329
330
331
332
333
334
		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi







    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_PATCH_LEVEL)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_LIB_FILE)







>
>
>
>
>
>







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_PATCH_LEVEL)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_LIB_FILE)
361
362
363
364
365
366
367




368
369
370
371
372
373
374

    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. "${TK_BIN_DIR}/tkConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
    fi





    # If the TK_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TK_LIB_SPEC will be set to the value
    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
    # instead of TK_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.







>
>
>
>







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. "${TK_BIN_DIR}/tkConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""

    # If the TK_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TK_LIB_SPEC will be set to the value
    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
    # instead of TK_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
394
395
396
397
398
399
400






401
402
403
404
405
406
407
		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi







    AC_SUBST(TK_VERSION)
    AC_SUBST(TK_BIN_DIR)
    AC_SUBST(TK_SRC_DIR)

    AC_SUBST(TK_LIB_FILE)
    AC_SUBST(TK_LIB_FLAG)







>
>
>
>
>
>







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""

    AC_SUBST(TK_VERSION)
    AC_SUBST(TK_BIN_DIR)
    AC_SUBST(TK_SRC_DIR)

    AC_SUBST(TK_LIB_FILE)
    AC_SUBST(TK_LIB_FLAG)
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AC_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
    fi
    AC_SUBST(SHARED_BUILD)
])

#------------------------------------------------------------------------
# SC_ENABLE_FRAMEWORK --
#
#	Allows the building of shared libraries into frameworks
#







|


<
<
<
<
<
<
<
<








<







526
527
528
529
530
531
532
533
534
535








536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AS_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])








    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
    fi

])

#------------------------------------------------------------------------
# SC_ENABLE_FRAMEWORK --
#
#	Allows the building of shared libraries into frameworks
#
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
#		FRAMEWORK_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_FRAMEWORK], [
    if test "`uname -s`" = "Darwin" ; then
	AC_MSG_CHECKING([how to package libraries])
	AC_ARG_ENABLE(framework,
	    AC_HELP_STRING([--enable-framework],
		[package shared libraries in MacOSX frameworks (default: off)]),
	    [enable_framework=$enableval], [enable_framework=no])
	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		AC_MSG_WARN([Frameworks can only be built if --enable-shared is yes])
		enable_framework=no
	    fi







|







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
#		FRAMEWORK_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_FRAMEWORK], [
    if test "`uname -s`" = "Darwin" ; then
	AC_MSG_CHECKING([how to package libraries])
	AC_ARG_ENABLE(framework,
	    AS_HELP_STRING([--enable-framework],
		[package shared libraries in MacOSX frameworks (default: off)]),
	    [enable_framework=$enableval], [enable_framework=no])
	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		AC_MSG_WARN([Frameworks can only be built if --enable-shared is yes])
		enable_framework=no
	    fi
573
574
575
576
577
578
579













































































































































580
581
582
583
584
585
586
	    else
		AC_MSG_RESULT([static library])
	    fi
	    FRAMEWORK_BUILD=0
	fi
    fi
])














































































































































#------------------------------------------------------------------------
# SC_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging
#	can also be enabled.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
	    else
		AC_MSG_RESULT([static library])
	    fi
	    FRAMEWORK_BUILD=0
	fi
    fi
])

#------------------------------------------------------------------------
# SC_ENABLE_THREADS --
#
#	Specify if thread support should be enabled
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-threads
#
#	Sets the following vars:
#		THREADS_LIBS	Thread library(s)
#
#	Defines the following vars:
#		TCL_THREADS
#		_REENTRANT
#		_THREAD_SAFE
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_THREADS], [
    AC_ARG_ENABLE(threads,
	AS_HELP_STRING([--enable-threads],
	    [build with threads (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])

    if test "${TCL_THREADS}" = 1; then
	tcl_threaded_core=1;
    fi

    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
	TCL_THREADS=1
	# USE_THREAD_ALLOC tells us to try the special thread-based
	# allocator that significantly reduces lock contention
	AC_DEFINE(USE_THREAD_ALLOC, 1,
	    [Do we want to use the threaded memory allocator?])
	AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	if test "`uname -s`" = "SunOS" ; then
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		    [Do we really want to follow the standard? Yes we do!])
	fi
	AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
	AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
	if test "$tcl_ok" = "no"; then
	    # Check a little harder for __pthread_mutex_init in the same
	    # library, as some systems hide it there until pthread.h is
	    # defined.  We could alternatively do an AC_TRY_COMPILE with
	    # pthread.h, but that will work with libpthread really doesn't
	    # exist, like AIX 4.2.  [Bug: 4359]
	    AC_CHECK_LIB(pthread, __pthread_mutex_init,
		tcl_ok=yes, tcl_ok=no)
	fi

	if test "$tcl_ok" = "yes"; then
	    # The space is needed
	    THREADS_LIBS=" -lpthread"
	else
	    AC_CHECK_LIB(pthreads, pthread_mutex_init,
		tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = "yes"; then
		# The space is needed
		THREADS_LIBS=" -lpthreads"
	    else
		AC_CHECK_LIB(c, pthread_mutex_init,
		    tcl_ok=yes, tcl_ok=no)
		if test "$tcl_ok" = "no"; then
		    AC_CHECK_LIB(c_r, pthread_mutex_init,
			tcl_ok=yes, tcl_ok=no)
		    if test "$tcl_ok" = "yes"; then
			# The space is needed
			THREADS_LIBS=" -pthread"
		    else
			TCL_THREADS=0
			AC_MSG_WARN([Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...])
		    fi
		fi
	    fi
	fi

	# Does the pthread-implementation provide
	# 'pthread_attr_setstacksize' ?

	ac_saved_libs=$LIBS
	LIBS="$LIBS $THREADS_LIBS"
	AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork)
	AC_CHECK_FUNC(pthread_attr_get_np,tcl_ok=yes,tcl_ok=no)
	if test $tcl_ok = yes ; then
	    AC_DEFINE(HAVE_PTHREAD_ATTR_GET_NP, 1,
		[Do we want a BSD-like thread-attribute interface?])
	    AC_CACHE_CHECK([for pthread_attr_get_np declaration],
		tcl_cv_grep_pthread_attr_get_np, [
		AC_EGREP_HEADER(pthread_attr_get_np, pthread.h,
		    tcl_cv_grep_pthread_attr_get_np=present,
		    tcl_cv_grep_pthread_attr_get_np=missing)])
	    if test $tcl_cv_grep_pthread_attr_get_np = missing ; then
		AC_DEFINE(ATTRGETNP_NOT_DECLARED, 1,
		    [Is pthread_attr_get_np() declared in <pthread.h>?])
	    fi
	else
	    AC_CHECK_FUNC(pthread_getattr_np,tcl_ok=yes,tcl_ok=no)
	    if test $tcl_ok = yes ; then
		AC_DEFINE(HAVE_PTHREAD_GETATTR_NP, 1,
		    [Do we want a Linux-like thread-attribute interface?])
		AC_CACHE_CHECK([for pthread_getattr_np declaration],
		    tcl_cv_grep_pthread_getattr_np, [
		    AC_EGREP_HEADER(pthread_getattr_np, pthread.h,
			tcl_cv_grep_pthread_getattr_np=present,
			tcl_cv_grep_pthread_getattr_np=missing)])
		if test $tcl_cv_grep_pthread_getattr_np = missing ; then
		    AC_DEFINE(GETATTRNP_NOT_DECLARED, 1,
			[Is pthread_getattr_np declared in <pthread.h>?])
		fi
	    fi
	fi
	if test $tcl_ok = no; then
	    # Darwin thread stacksize API
	    AC_CHECK_FUNCS(pthread_get_stacksize_np)
	fi
	LIBS=$ac_saved_libs
    else
	TCL_THREADS=0
    fi
    # Do checking message here to not mess up interleaved configure output
    AC_MSG_CHECKING([for building with threads])
    if test "${TCL_THREADS}" = 1; then
	AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
	if test "${tcl_threaded_core}" = 1; then
	    AC_MSG_RESULT([yes (threaded core)])
	else
	    AC_MSG_RESULT([yes])
	fi
    else
	AC_MSG_RESULT([no (default)])
    fi

    AC_SUBST(TCL_THREADS)
])

#------------------------------------------------------------------------
# SC_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging
#	can also be enabled.
600
601
602
603
604
605
606



607
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false



#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AC_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.

    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
	AC_MSG_RESULT([no])
	AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?])
    else







>
>
>





|



>







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#		DBGX		Formerly used as debug library extension;
#				always blank now.
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AS_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    DBGX=""
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
	AC_MSG_RESULT([no])
	AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?])
    else
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AC_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])

    HAVE_LANGINFO=0
    if test "$langinfo_ok" = "yes"; then
	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
    fi
    AC_MSG_CHECKING([whether to use nl_langinfo])
    if test "$langinfo_ok" = "yes"; then
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else
	AC_MSG_RESULT([$langinfo_ok])
    fi







|










<
|







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AS_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])

    HAVE_LANGINFO=0
    if test "$langinfo_ok" = "yes"; then
	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
    fi
    AC_MSG_CHECKING([whether to use nl_langinfo])
    if test "$langinfo_ok" = "yes"; then
	AC_CACHE_VAL(tcl_cv_langinfo_h, [

	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <langinfo.h>]], [[nl_langinfo(CODESET);]])],[tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else
	AC_MSG_RESULT([$langinfo_ok])
    fi
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
787
788
789
790






791
792
793
794
795
796
797
#			according to the user's selection.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_MANPAGES], [
    AC_MSG_CHECKING([whether to use symlinks for manpages])
    AC_ARG_ENABLE(man-symlinks,
	AC_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks",
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_MSG_CHECKING([whether to compress the manpages])
    AC_ARG_ENABLE(man-compression,
	AC_HELP_STRING([--enable-man-compression=PROG],
	    [compress the manpages with PROG (default: off)]),
	[case $enableval in
	    yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])
    if test "$enableval" != "no"; then
	AC_MSG_CHECKING([for compressed file suffix])
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	AC_MSG_RESULT([$Z])
    fi

    AC_MSG_CHECKING([whether to add a package name suffix for the manpages])
    AC_ARG_ENABLE(man-suffix,
	AC_HELP_STRING([--enable-man-suffix=STRING],
	    [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]),
	[case $enableval in
	    yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_SUBST(MAN_FLAGS)
])

#--------------------------------------------------------------------
# SC_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command.

#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.

#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		AC_MSG_WARN([can't find uname command])
		tcl_cv_sys_version=unknown
	    else






		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
		if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then
		    tcl_cv_sys_version=NetBSD-Debian
		fi
	    fi







|

|
|




|






|













|






|










|
>








>




|
|






>
>
>
>
>
>







873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
#			according to the user's selection.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_MANPAGES], [
    AC_MSG_CHECKING([whether to use symlinks for manpages])
    AC_ARG_ENABLE(man-symlinks,
	AS_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	[test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])

    AC_MSG_CHECKING([whether to compress the manpages])
    AC_ARG_ENABLE(man-compression,
	AS_HELP_STRING([--enable-man-compression=PROG],
	    [compress the manpages with PROG (default: off)]),
	[case $enableval in
	    yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])
    if test "$enableval" != "no"; then
	AC_MSG_CHECKING([for compressed file suffix])
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	AC_MSG_RESULT([$Z])
    fi

    AC_MSG_CHECKING([whether to add a package name suffix for the manpages])
    AC_ARG_ENABLE(man-suffix,
	AS_HELP_STRING([--enable-man-suffix=STRING],
	    [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]),
	[case $enableval in
	    yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])

    AC_SUBST(MAN_FLAGS)
])

#--------------------------------------------------------------------
# SC_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command, but there are a few systems, like Next, where
#	this doesn't work.
#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	if test -f /usr/lib/NextStep/software_version; then
	    tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		AC_MSG_WARN([can't find uname command])
		tcl_cv_sys_version=unknown
	    else
		# Special check for weird MP-RAS system (uname returns weird
		# results, and the version is kept in special file).

		if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
		    tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
		fi
		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
		if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then
		    tcl_cv_sys_version=NetBSD-Debian
		fi
	    fi
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
#                       of a shared library (may request position-independent
#                       code, among other things).
#       SHLIB_LD -      Base command to use for combining object files
#                       into a shared library.
#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
#                       creating shared libraries.  This symbol typically
#                       goes at the end of the "ld" commands that build
#                       shared libraries. The value of the symbol defaults to
#                       "${LIBS}" if all of the dependent libraries should
#                       be specified when creating a shared library.  If
#                       dependent libraries should not be specified (as on some
#                       SunOS systems, where they cause the link to fail, or in
#                       general if Tcl and Tk aren't themselves shared
#                       libraries), then this symbol has an empty string
#                       as its value.
#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
#                       extensions.  An empty string means we don't know how
#                       to use shared libraries on this platform.
# TCL_SHLIB_LD_EXTRAS - Additional element which are added to SHLIB_LD_LIBS







|


|
|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
#                       of a shared library (may request position-independent
#                       code, among other things).
#       SHLIB_LD -      Base command to use for combining object files
#                       into a shared library.
#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
#                       creating shared libraries.  This symbol typically
#                       goes at the end of the "ld" commands that build
#                       shared libraries. The value of the symbol is
#                       "${LIBS}" if all of the dependent libraries should
#                       be specified when creating a shared library.  If
#                       dependent libraries should not be specified (as on
#                       SunOS 4.x, where they cause the link to fail, or in
#                       general if Tcl and Tk aren't themselves shared
#                       libraries), then this symbol has an empty string
#                       as its value.
#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
#                       extensions.  An empty string means we don't know how
#                       to use shared libraries on this platform.
# TCL_SHLIB_LD_EXTRAS - Additional element which are added to SHLIB_LD_LIBS
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948

949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AC_HELP_STRING([--enable-64bit],
	    [enable 64bit support (default: off)]),
	[do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT([$do64bit])

    # Step 0.b: Enable Solaris 64 bit VIS support?

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AC_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])
    # Force 64bit on with VIS
    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_TRY_LINK([
	    extern __attribute__((__visibility__("hidden"))) void f(void);

	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags])
    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])
	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,
	AC_HELP_STRING([--disable-rpath],
	    [disable rpath support (default: on)]),
	[doRpath=$enableval], [doRpath=yes])
    AC_MSG_RESULT([$doRpath])

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.

    SC_CONFIG_SYSTEM

    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

    # Require ranlib early so we can override it in special cases below.


    AC_REQUIRE([AC_PROG_RANLIB])

    # Step 3: set configuration options based on system name and version.

    do64bit_ok=no
    # default to '{$LIBS}' and set to "" on per-platform necessary basis
    SHLIB_LD_LIBS='${LIBS}'
    LDFLAGS_ORIG="$LDFLAGS"
    # When ld needs options to work in 64-bit mode, put them in
    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""
    UNSHARED_LIB_SUFFIX=""
    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g

    AS_IF([test "$GCC" = yes], [
	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

    ], [
	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""
    ])
    AC_CHECK_TOOL(AR, ar)
    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    PLAT_OBJS=""
    PLAT_SRCS=""
    LDAIX_SRC=""
    AS_IF([test "x${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"])
    case $system in
	AIX-*)
	    AS_IF([test "$GCC" != "yes"], [
		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r|*_r\ *)
			# ok ...
			;;
		    *)
			# Make sure only first arg gets _r







|








|












|

>
|
|





<






|















>


















>

<
|
<
<
<
<
<
<
<
<
<
<
|
<






<


|







1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134

1135










1136

1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
1150
1151
1152

AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AS_HELP_STRING([--enable-64bit],
	    [enable 64bit support (default: off)]),
	[do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT([$do64bit])

    # Step 0.b: Enable Solaris 64 bit VIS support?

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AS_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])
    # Force 64bit on with VIS
    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}]], [[f();]])],
	    [tcl_cv_cc_visibility_hidden=yes],
	    [tcl_cv_cc_visibility_hidden=no])
	CFLAGS=$hold_cflags])
    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])

    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,
	AS_HELP_STRING([--disable-rpath],
	    [disable rpath support (default: on)]),
	[doRpath=$enableval], [doRpath=yes])
    AC_MSG_RESULT([$doRpath])

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.

    SC_CONFIG_SYSTEM

    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

    # Require ranlib early so we can override it in special cases below.
    AS_IF([test x"${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"])

    AC_REQUIRE([AC_PROG_RANLIB])

    # Step 3: set configuration options based on system name and version.

    do64bit_ok=no
    # default to '{$LIBS}' and set to "" on per-platform necessary basis
    SHLIB_LD_LIBS='${LIBS}'
    LDFLAGS_ORIG="$LDFLAGS"
    # When ld needs options to work in 64-bit mode, put them in
    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""
    UNSHARED_LIB_SUFFIX=""
    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g
    CFLAGS_OPTIMIZE=-O
    AS_IF([test "$GCC" = yes], [

	CFLAGS_WARNING="-Wall -Wpointer-arith"










    ], [CFLAGS_WARNING=""])

    AC_CHECK_TOOL(AR, ar)
    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    PLAT_OBJS=""
    PLAT_SRCS=""
    LDAIX_SRC=""

    case $system in
	AIX-*)
	    AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r|*_r\ *)
			# ok ...
			;;
		    *)
			# Make sure only first arg gets _r
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111



1112
1113
1114
1115
1116
1117
1118
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o"
	    PLAT_OBJS='${CYGWIN_OBJS}'
	    PLAT_SRCS='${CYGWIN_SRCS}'
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_NEEDS_EXP_FILE=1
	    TCL_EXPORT_FILE_SUFFIX='${VERSION}.dll.a'
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
	    AC_CACHE_CHECK(for Cygwin version of gcc,
		ac_cv_cygwin,
		AC_TRY_COMPILE([
		#ifdef __CYGWIN__
		    #error cygwin
		#endif
		], [],
		ac_cv_cygwin=no,
		ac_cv_cygwin=yes)
	    )
	    if test "$ac_cv_cygwin" = "no"; then
		AC_MSG_ERROR([${CC} is not a cygwin compiler.])
	    fi



	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
		then :
		else







|
|


|
<
<




|



|



|
|
|




>
>
>







1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244


1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*|MINGW32_*|MSYS_*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD='${CC} -shared'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o tclWinError.o"


	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_NEEDS_EXP_FILE=1
	    TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
	    AC_CACHE_CHECK(for Cygwin version of gcc,
		ac_cv_cygwin,
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef __CYGWIN__
		    #error cygwin
		#endif
		]], [[]])],
		[ac_cv_cygwin=no],
		[ac_cv_cygwin=yes])
	    )
	    if test "$ac_cv_cygwin" = "no"; then
		AC_MSG_ERROR([${CC} is not a cygwin compiler.])
	    fi
	    if test "x${TCL_THREADS}" = "x0"; then
		AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads])
	    fi
	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
		then :
		else
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    ])
	    AS_IF([test "$GCC" = yes], [
		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    ], [
		CFLAGS="$CFLAGS -z"
	    ])

	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
	    #CFLAGS="$CFLAGS +DAportable"

	    # Check to enable 64-bit flags for compiler/linker
	    AS_IF([test "$do64bit" = "yes"], [
		AS_IF([test "$GCC" = yes], [
		    case `${CC} -dumpmachine` in
			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD='${CC} -shared'
			    AS_IF([test $doRpath = yes], [
				CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
			    ;;
		    esac
		], [







<
<














|







1315
1316
1317
1318
1319
1320
1321


1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    ])
	    AS_IF([test "$GCC" = yes], [
		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}


	    ])

	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
	    #CFLAGS="$CFLAGS +DAportable"

	    # Check to enable 64-bit flags for compiler/linker
	    AS_IF([test "$do64bit" = "yes"], [
		AS_IF([test "$GCC" = yes], [
		    case `${CC} -dumpmachine` in
			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD='${CC} -shared'
			    AS_IF([test $doRpath = yes], [
				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
			    ;;
		    esac
		], [
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
	    ]) ;;
	IRIX-5.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AC_LIBOBJ(mkstemp)
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    ;;
	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AC_LIBOBJ(mkstemp)
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    AS_IF([test "$GCC" = yes], [
		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"
	    ], [
		case $system in
		    IRIX-6.3)







<

|








<

|







1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386
1387
	    ]) ;;
	IRIX-5.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    ;;
	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    AS_IF([test "$GCC" = yes], [
		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"
	    ], [
		case $system in
		    IRIX-6.3)
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317










1318
1319
1320











1321
1322
1323








1324
1325
1326
1327
1328






















1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363

1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AC_LIBOBJ(mkstemp)
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])

	    # Check to enable 64-bit flags for compiler/linker

	    AS_IF([test "$do64bit" = yes], [
	        AS_IF([test "$GCC" = yes], [
	            AC_MSG_WARN([64bit mode not supported by gcc])
	        ], [
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        ])
	    ])
	    ;;
	Linux*|GNU*|NetBSD-Debian)
	    SHLIB_CFLAGS="-fPIC -fno-common"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    CFLAGS=$hold_cflags])
		AS_IF([test $tcl_cv_cc_m64 = yes], [
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		])
	   ])

	    # The combo of gcc + glibc has a bug related to inlining of
	    # functions like strtol()/strtoul(). The -fno-builtin flag should address
	    # this problem but it does not work. The -fno-inline flag is kind
	    # of overkill but it works. Disable inlining only when one of the
	    # files in compat/*.c is being linked in.

	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
	    ;;
	Lynx*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    CFLAGS_OPTIMIZE=-02
	    SHLIB_LD='${CC} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-mshared -ldl"
	    LD_FLAGS="-Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [










		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    ;;











	OpenBSD-*)
	    arch=`arch -s`
	    case "$arch" in








	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"






















		;;
	    esac
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
	    LDFLAGS="-Wl,-export-dynamic"
	    CFLAGS_OPTIMIZE="-O2"
	    # On OpenBSD:	Compile with -pthread
	    #		Don't link with -lpthread
	    LIBS=`echo $LIBS | sed s/-lpthread//`
	    CFLAGS="$CFLAGS -pthread"

	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"

	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.

	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])

	    # The -pthread needs to go in the LDFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
	    LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
	    case $system in
	    FreeBSD-3.*)
		# Version numbers are dot-stripped by system policy.
		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
		TCL_LIB_VERSIONS_OK=nodots







<

|
















|













|






|








|















>
>
>
>
>
>
>
>
>
>
|
|

>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<
|
<
<
<
<
<
|
|
|
|
>













|

>
|
|
|
|
>



>






|
|
>
|
|
|
|







1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531




1532





1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])

	    # Check to enable 64-bit flags for compiler/linker

	    AS_IF([test "$do64bit" = yes], [
	        AS_IF([test "$GCC" = yes], [
	            AC_MSG_WARN([64bit mode not supported by gcc])
	        ], [
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        ])
	    ])
	    ;;
	Linux*|GNU*|NetBSD-Debian)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_m64=yes],[tcl_cv_cc_m64=no])
		    CFLAGS=$hold_cflags])
		AS_IF([test $tcl_cv_cc_m64 = yes], [
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		])
	   ])

	    # The combo of gcc + glibc has a bug related to inlining of
	    # functions like strtod(). The -fno-builtin flag should address
	    # this problem but it does not work. The -fno-inline flag is kind
	    # of overkill but it works. Disable inlining only when one of the
	    # files in compat/*.c is being linked in.

	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
	    ;;
	Lynx*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    CFLAGS_OPTIMIZE=-02
	    SHLIB_LD='${CC} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-mshared -ldl"
	    LD_FLAGS="-Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    ;;
	MP-RAS-02*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	MP-RAS-*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OpenBSD-*)
	    arch=`arch -s`
	    case "$arch" in
	    vax)
		# Equivalent using configure option --disable-load
		# Step 4 will set the necessary variables
		DL_OBJS=""
		SHLIB_LD_LIBS=""
		;;
	    *)
		case "$arch" in
		alpha|sparc|sparc64)
		    SHLIB_CFLAGS="-fPIC"
		    ;;
		*)
		    SHLIB_CFLAGS="-fpic"
		    ;;
		esac
		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
		SHLIB_SUFFIX=".so"
		DL_OBJS="tclLoadDl.o"
		DL_LIBS=""
		AS_IF([test $doRpath = yes], [
		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
		LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
		;;
	    esac
	    case "$arch" in
	    vax)
		CFLAGS_OPTIMIZE="-O1"
		;;
	    sh)
		CFLAGS_OPTIMIZE="-O0"
		;;
	    *)
		CFLAGS_OPTIMIZE="-O2"
		;;
	    esac




	    AS_IF([test "${TCL_THREADS}" = "1"], [





		# On OpenBSD:	Compile with -pthread
		#		Don't link with -lpthread
		LIBS=`echo $LIBS | sed s/-lpthread//`
		CFLAGS="$CFLAGS -pthread"
	    ])
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    ])
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the LDFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
	    case $system in
	    FreeBSD-3.*)
		# Version numbers are dot-stripped by system policy.
		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
		TCL_LIB_VERSIONS_OK=nodots
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419

1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447




1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523










1524
1525
1526
1527
1528

























1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"

			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"

			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_single_module = yes], [
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    ])
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""




	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"

		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
			tcl_cv_ld_search_paths_first=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
	    ])
	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
		    [Compiler support for module scope symbols])
		tcl_cv_cc_visibility_hidden=yes
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])
	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    AC_MSG_CHECKING([whether to use CoreFoundation])
	    AC_ARG_ENABLE(corefoundation,
		AC_HELP_STRING([--enable-corefoundation],
		    [use CoreFoundation API on MacOSX (default: on)]),
		[tcl_corefoundation=$enableval], [tcl_corefoundation=yes])
	    AC_MSG_RESULT([$tcl_corefoundation])
	    AS_IF([test $tcl_corefoundation = yes], [
		AC_CACHE_CHECK([for CoreFoundation.framework],
			tcl_cv_lib_corefoundation, [
		    hold_libs=$LIBS
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    # On Tiger there is no 64-bit CF, so remove 64-bit
			    # archs from CFLAGS et al. while testing for
			    # presence of CF. 64-bit CF is disabled in
			    # tclUnixPort.h if necessary.
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
			done])
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>],
			[CFBundleRef b = CFBundleGetMainBundle();],
			tcl_cv_lib_corefoundation=yes,
			tcl_cv_lib_corefoundation=no)
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done])
		    LIBS=$hold_libs])
		AS_IF([test $tcl_cv_lib_corefoundation = yes], [
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_DEFINE(HAVE_COREFOUNDATION, 1,
			[Do we have access to Darwin CoreFoundation.framework?])
		], [tcl_corefoundation=no])
		AS_IF([test "$fat_32_64" = yes -a $tcl_corefoundation = yes],[
		    AC_CACHE_CHECK([for 64-bit CoreFoundation],
			    tcl_cv_lib_corefoundation_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>],
			    [CFBundleRef b = CFBundleGetMainBundle();],
			    tcl_cv_lib_corefoundation_64=yes,
			    tcl_cv_lib_corefoundation_64=no)
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		    AS_IF([test $tcl_cv_lib_corefoundation_64 = no], [
			AC_DEFINE(NO_COREFOUNDATION_64, 1,
			    [Is Darwin CoreFoundation unavailable for 64-bit?])
                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"
		    ])
		])
	    ])
	    ;;










	OS/390-*)
	    SHLIB_LD_LIBS=""
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])

























	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    AS_IF([test "$SHARED_BUILD" = 1], [
	        SHLIB_LD='ld -shared -expect_unresolved "*"'
	    ], [
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
	    ])
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa

	    CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
	    CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
	    LIBS=`echo $LIBS | sed s/-lpthreads//`
	    AS_IF([test "$GCC" = yes], [
		LIBS="$LIBS -lpthread -lmach -lexc"
	    ], [
		CFLAGS="$CFLAGS -pthread"
		LDFLAGS="$LDFLAGS -pthread"

	    ])
	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.

	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""







>
|
|










>
|
|


















|







>
>
>
>





>
|
|







<









|
















|
|
|
|
















|
|
|
|











>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|




>
|
|
|
|
|
|
|
|
>





>







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_ppc64=yes],
				    [tcl_cv_cc_arch_ppc64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_x86_64=yes],
				    [tcl_cv_cc_arch_x86_64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_single_module=yes],[tcl_cv_ld_single_module=no])
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_single_module = yes], [
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    ])
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
	    AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
		LDFLAGS="$LDFLAGS -prebind"])
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],
			[tcl_cv_ld_search_paths_first=yes],
			[tcl_cv_ld_search_paths_first=no])
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
	    ])
	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
		    [Compiler support for module scope symbols])

	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])
	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    AC_MSG_CHECKING([whether to use CoreFoundation])
	    AC_ARG_ENABLE(corefoundation,
		AS_HELP_STRING([--enable-corefoundation],
		    [use CoreFoundation API on MacOSX (default: on)]),
		[tcl_corefoundation=$enableval], [tcl_corefoundation=yes])
	    AC_MSG_RESULT([$tcl_corefoundation])
	    AS_IF([test $tcl_corefoundation = yes], [
		AC_CACHE_CHECK([for CoreFoundation.framework],
			tcl_cv_lib_corefoundation, [
		    hold_libs=$LIBS
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    # On Tiger there is no 64-bit CF, so remove 64-bit
			    # archs from CFLAGS et al. while testing for
			    # presence of CF. 64-bit CF is disabled in
			    # tclUnixPort.h if necessary.
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
			done])
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <CoreFoundation/CoreFoundation.h>]],
			[[CFBundleRef b = CFBundleGetMainBundle();]])],
			[tcl_cv_lib_corefoundation=yes],
			[tcl_cv_lib_corefoundation=no])
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done])
		    LIBS=$hold_libs])
		AS_IF([test $tcl_cv_lib_corefoundation = yes], [
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_DEFINE(HAVE_COREFOUNDATION, 1,
			[Do we have access to Darwin CoreFoundation.framework?])
		], [tcl_corefoundation=no])
		AS_IF([test "$fat_32_64" = yes -a $tcl_corefoundation = yes],[
		    AC_CACHE_CHECK([for 64-bit CoreFoundation],
			    tcl_cv_lib_corefoundation_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <CoreFoundation/CoreFoundation.h>]],
			    [[CFBundleRef b = CFBundleGetMainBundle();]])],
			    [tcl_cv_lib_corefoundation_64=yes],
			    [tcl_cv_lib_corefoundation_64=no])
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		    AS_IF([test $tcl_cv_lib_corefoundation_64 = no], [
			AC_DEFINE(NO_COREFOUNDATION_64, 1,
			    [Is Darwin CoreFoundation unavailable for 64-bit?])
                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"
		    ])
		])
	    ])
	    ;;
	NEXTSTEP-*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD='${CC} -nostdlib -r'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadNext.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OS/390-*)
	    SHLIB_LD_LIBS=""
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])
	    ;;
	OSF1-1.0|OSF1-1.1|OSF1-1.2)
	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
	    SHLIB_CFLAGS=""
	    # Hack: make package name same as library name
	    SHLIB_LD='ld -R -export $@:'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadOSF.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-1.*)
	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
	    SHLIB_CFLAGS="-fPIC"
	    AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [
	        SHLIB_LD="ld -non_shared"
	    ])
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    AS_IF([test "$SHARED_BUILD" = 1], [
	        SHLIB_LD='ld -shared -expect_unresolved "*"'
	    ], [
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
	    ])
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    AS_IF([test "${TCL_THREADS}" = 1], [
		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
		LIBS=`echo $LIBS | sed s/-lpthreads//`
		AS_IF([test "$GCC" = yes], [
		    LIBS="$LIBS -lpthread -lmach -lexc"
		], [
		    CFLAGS="$CFLAGS -pthread"
		    LDFLAGS="$LDFLAGS -pthread"
		])
	    ])
	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
1581
1582
1583
1584
1585
1586
1587





























1588
1589
1590
1591
1592
1593
1594
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;





























	SunOS-5.[[0-6]])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SINIX*5.4*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SunOS-4*)
	    SHLIB_CFLAGS="-PIC"
	    SHLIB_LD="ld"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

	    # SunOS can't handle version numbers with dots in them in library
	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	    # requires an extra version number at the end of .so file names.
	    # So, the library has to have a name like libtcl75.so.1.0

	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	SunOS-5.[[0-6]])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;







|







1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no])
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AC_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])

    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
	AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
	SHLIB_CFLAGS=""







|







2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AS_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])

    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
	AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
	SHLIB_CFLAGS=""
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821

1822
1823

1824
1825
1826
1827
1828
1829
1830

1831
1832

1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    HP_UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])
    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${LDFLAGS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        AS_IF([test "$RANLIB" = ""], [
            MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}'

        ], [
            MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@'

        ])
        INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
    ])

    # Stub lib does not depend on shared/static configuration
    AS_IF([test "$RANLIB" = ""], [
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}'

    ], [
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@'

    ])
    INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"'

    # Define TCL_LIBS now that we know what DL_LIBS is.
    # The trick here is that we don't want to change the value of TCL_LIBS if
    # it is already set when tclConfig.sh had been loaded by Tk.
    AS_IF([test "x${TCL_LIBS}" = x], [
        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"])
    AC_SUBST(TCL_LIBS)

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_TRY_COMPILE([],
	    [
		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ],
	    tcl_cv_cast_to_union=yes,
	    tcl_cv_cast_to_union=no)
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi

    AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)

    # FIXME: This subst was left in only because the TCL_DL_LIBS
    # entry in tclConfig.sh uses it. It is not clear why someone
    # would use TCL_DL_LIBS instead of TCL_LIBS.
    AC_SUBST(DL_LIBS)

    AC_SUBST(DL_OBJS)
    AC_SUBST(PLAT_OBJS)







|
<
<

<
|
|




<
<
<
<
<








|











>


>

<





>


>

<














|
<


|
|
|






<
<







2049
2050
2051
2052
2053
2054
2055
2056


2057

2058
2059
2060
2061
2062
2063





2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088

2089
2090
2091
2092
2093
2094
2095
2096
2097
2098

2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113

2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124


2125
2126
2127
2128
2129
2130
2131
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;


	    IRIX*) ;;

	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])






    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        AS_IF([test "$RANLIB" = ""], [
            MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}'
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ], [
            MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@'
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))'
        ])

    ])

    # Stub lib does not depend on shared/static configuration
    AS_IF([test "$RANLIB" = ""], [
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}'
        INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"'
    ], [
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@'
        INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))'
    ])


    # Define TCL_LIBS now that we know what DL_LIBS is.
    # The trick here is that we don't want to change the value of TCL_LIBS if
    # it is already set when tclConfig.sh had been loaded by Tk.
    AS_IF([test "x${TCL_LIBS}" = x], [
        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"])
    AC_SUBST(TCL_LIBS)

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ]])],
	    [tcl_cv_cast_to_union=yes],
	    [tcl_cv_cast_to_union=no])
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi



    # FIXME: This subst was left in only because the TCL_DL_LIBS
    # entry in tclConfig.sh uses it. It is not clear why someone
    # would use TCL_DL_LIBS instead of TCL_LIBS.
    AC_SUBST(DL_LIBS)

    AC_SUBST(DL_OBJS)
    AC_SUBST(PLAT_OBJS)
1894
1895
1896
1897
1898
1899
1900
1901
1902






















































































































1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918


1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954





1955
1956
1957

1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
    AC_SUBST(MAKE_LIB)
    AC_SUBST(MAKE_STUB_LIB)
    AC_SUBST(INSTALL_LIB)
    AC_SUBST(DLL_INSTALL_DIR)
    AC_SUBST(INSTALL_STUB_LIB)
    AC_SUBST(RANLIB)
])

#--------------------------------------------------------------------






















































































































# SC_MISSING_POSIX_HEADERS
#
#	Supply substitutes for missing POSIX header files.  Special
#	notes:
#	    - stdlib.h doesn't define strtol or strtoul in some
#	      versions of SunOS
#	    - some versions of string.h don't declare procedures such
#	      as strstr
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		NO_DIRENT_H


#		NO_STDLIB_H
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
    AC_TRY_LINK([#include <sys/types.h>
#include <dirent.h>], [
#ifndef _POSIX_SOURCE
#   ifdef __Lynx__
	/*
	 * Generate compilation error to make the test fail:  Lynx headers
	 * are only valid if really in the POSIX environment.
	 */

	missing_procedure();
#   endif
#endif
DIR *d;
struct dirent *entryPtr;
char *p;
d = opendir("foobar");
entryPtr = readdir(d);
p = entryPtr->d_name;
closedir(d);
], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])

    if test $tcl_cv_dirent_h = no; then
	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
    fi






    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
    fi
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_HAVE_HEADERS(sys/param.h)
])

#--------------------------------------------------------------------
# SC_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|










>
>











|
|

















|





>
>
>
>
>



>


















|







2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
    AC_SUBST(MAKE_LIB)
    AC_SUBST(MAKE_STUB_LIB)
    AC_SUBST(INSTALL_LIB)
    AC_SUBST(DLL_INSTALL_DIR)
    AC_SUBST(INSTALL_STUB_LIB)
    AC_SUBST(RANLIB)
])

#--------------------------------------------------------------------
# SC_SERIAL_PORT
#
#	Determine which interface to use to talk to the serial port.
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives,
#	and some build environments have stdin not pointing at a
#	pseudo-terminal (usually /dev/null instead.)
#
# Arguments:
#	none
#
# Results:
#
#	Defines only one of the following vars:
#		HAVE_SYS_MODEM_H
#		USE_TERMIOS
#		USE_TERMIO
#		USE_SGTTY
#
#--------------------------------------------------------------------

AC_DEFUN([SC_SERIAL_PORT], [
    AC_CHECK_HEADERS(sys/modem.h)
    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
    AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <termios.h>

int main() {
    struct termios t;
    if (tcgetattr(0, &t) == 0) {
	cfsetospeed(&t, 0);
	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no])
    if test $tcl_cv_api_serial = no ; then
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <termio.h>

int main() {
    struct termio t;
    if (ioctl(0, TCGETA, &t) == 0) {
	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no])
    fi
    if test $tcl_cv_api_serial = no ; then
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sgtty.h>

int main() {
    struct sgttyb t;
    if (ioctl(0, TIOCGETP, &t) == 0) {
	t.sg_ospeed = 0;
	t.sg_flags |= ODDP | EVENP | RAW;
	return 0;
    }
    return 1;
}]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no])
    fi
    if test $tcl_cv_api_serial = no ; then
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <termios.h>
#include <errno.h>

int main() {
    struct termios t;
    if (tcgetattr(0, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	cfsetospeed(&t, 0);
	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no])
    fi
    if test $tcl_cv_api_serial = no; then
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <termio.h>
#include <errno.h>

int main() {
    struct termio t;
    if (ioctl(0, TCGETA, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
    }]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no])
    fi
    if test $tcl_cv_api_serial = no; then
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sgtty.h>
#include <errno.h>

int main() {
    struct sgttyb t;
    if (ioctl(0, TIOCGETP, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	t.sg_ospeed = 0;
	t.sg_flags |= ODDP | EVENP | RAW;
	return 0;
    }
    return 1;
}]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=none],[tcl_cv_api_serial=none])
    fi])
    case $tcl_cv_api_serial in
	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
    esac
])

#--------------------------------------------------------------------
# SC_MISSING_POSIX_HEADERS
#
#	Supply substitutes for missing POSIX header files.  Special
#	notes:
#	    - stdlib.h doesn't define strtol, strtoul, or
#	      strtod insome versions of SunOS
#	    - some versions of string.h don't declare procedures such
#	      as strstr
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		NO_DIRENT_H
#		NO_VALUES_H
#		HAVE_LIMITS_H or NO_LIMITS_H
#		NO_STDLIB_H
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]], [[
#ifndef _POSIX_SOURCE
#   ifdef __Lynx__
	/*
	 * Generate compilation error to make the test fail:  Lynx headers
	 * are only valid if really in the POSIX environment.
	 */

	missing_procedure();
#   endif
#endif
DIR *d;
struct dirent *entryPtr;
char *p;
d = opendir("foobar");
entryPtr = readdir(d);
p = entryPtr->d_name;
closedir(d);
]])],[tcl_cv_dirent_h=yes],[tcl_cv_dirent_h=no])])

    if test $tcl_cv_dirent_h = no; then
	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
    fi

    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
    AC_CHECK_HEADER(limits.h,
	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
    fi
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_CHECK_HEADERS([sys/param.h])
])

#--------------------------------------------------------------------
# SC_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
#--------------------------------------------------------------------

AC_DEFUN([SC_PATH_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
	else
	    if test ! -r $x_includes/X11/Xlib.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Xlib.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"







|









|







2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
#--------------------------------------------------------------------

AC_DEFUN([SC_PATH_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <X11/Xlib.h>]])],[],[not_really_there="yes"])
	else
	    if test ! -r $x_includes/X11/Xlib.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <X11/Xlib.h>]])],[found_xincludes="yes"],[found_xincludes="no"])
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Xlib.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
2085
2086
2087
2088
2089
2090
2091





2092




2093
2094
2095
2096
2097
2098
2099

AC_DEFUN([SC_BLOCKING_STYLE], [
    AC_CHECK_HEADERS(sys/ioctl.h)
    AC_CHECK_HEADERS(sys/filio.h)
    SC_CONFIG_SYSTEM
    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
    case $system in





	OSF*)




	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	*)
	    AC_MSG_RESULT([O_NONBLOCK])
	    ;;
    esac







>
>
>
>
>

>
>
>
>







2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495

AC_DEFUN([SC_BLOCKING_STYLE], [
    AC_CHECK_HEADERS(sys/ioctl.h)
    AC_CHECK_HEADERS(sys/filio.h)
    SC_CONFIG_SYSTEM
    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
    case $system in
	# There used to be code here to use FIONBIO under AIX.  However, it
	# was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
	# using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
	# code (JO, 5/31/97).

	OSF*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	SunOS-4*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	*)
	    AC_MSG_RESULT([O_NONBLOCK])
	    ;;
    esac
2121
2122
2123
2124
2125
2126
2127
2128
2129

2130
2131
2132
2133
2134
2135
2136

2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
























































2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200


2201
2202
2203

2204
2205
2206
2207
2208
2209
2210
AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME

    AC_CHECK_FUNCS(gmtime_r localtime_r mktime)

    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
	    tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])

    if test $tcl_cv_member_tm_tzadj = yes ; then
	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
    fi

    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; (void)tm.tm_gmtoff;],
	    tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])

    if test $tcl_cv_member_tm_gmtoff = yes ; then
	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
    fi

    #
    # Its important to include time.h in this check, as some systems
    # (like convex) have timezone functions, etc.
    #
    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
	AC_TRY_COMPILE([#include <time.h>],
	    [extern long timezone;
	    timezone += 1;
	    exit (0);],
	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
    if test $tcl_cv_timezone_long = yes ; then
	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
    else
	#
	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
	#
	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
	    AC_TRY_COMPILE([#include <time.h>],
		[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

























































#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) or thread library (-lpthread) are dealt with here.
#
# Arguments:
#	None.
#
# Results:
#
#	Sets the following vars:
#		THREADS_LIBS	Thread library(s)
#
#	Defines the following vars:
#		_REENTRANT
#		_THREAD_SAFE
#
#	Might append to the following vars:
#		LIBS
#		MATH_LIBS
#
#	Might define the following vars:
#		HAVE_NET_ERRNO_H
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.


    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")


    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])







|
|
>





|
|
>









|
|

|
|







|
|

|
|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|






<
<
<
<
<
<
<













>
>



>







2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634







2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME

    AC_CHECK_FUNCS(gmtime_r localtime_r mktime)

    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[struct tm tm; tm.tm_tzadj;]])],
	    [tcl_cv_member_tm_tzadj=yes],
	    [tcl_cv_member_tm_tzadj=no])])
    if test $tcl_cv_member_tm_tzadj = yes ; then
	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
    fi

    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[struct tm tm; tm.tm_gmtoff;]])],
	    [tcl_cv_member_tm_gmtoff=yes],
	    [tcl_cv_member_tm_gmtoff=no])])
    if test $tcl_cv_member_tm_gmtoff = yes ; then
	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
    fi

    #
    # Its important to include time.h in this check, as some systems
    # (like convex) have timezone functions, etc.
    #
    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]],
	    [[extern long timezone;
	    timezone += 1;
	    exit (0);]])],
	    [tcl_cv_timezone_long=yes],[tcl_cv_timezone_long=no])])
    if test $tcl_cv_timezone_long = yes ; then
	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
    else
	#
	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
	#
	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]],
		[[extern time_t timezone;
		timezone += 1;
		exit (0);]])],
		[tcl_cv_timezone_time=yes],[tcl_cv_timezone_time=no])])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_BUGGY_STRTOD
#
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_RUN_IFELSE([AC_LANG_SOURCE([[
		#include <stdlib.h>
		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}]])],
		[tcl_cv_strtod_buggy=ok],
		[tcl_cv_strtod_buggy=buggy],
		[tcl_cv_strtod_buggy=buggy])])
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) are dealt with here.
#
# Arguments:
#	None.
#
# Results:
#







#	Might append to the following vars:
#		LIBS
#		MATH_LIBS
#
#	Might define the following vars:
#		HAVE_NET_ERRNO_H
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.
    # Also, Linux requires the "ieee" library for math to work
    # right (and it must appear before "-lm").
    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])

    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
    if test "$tcl_checkBoth" = 1; then
	tk_oldLibs=$LIBS
	LIBS="$LIBS -lsocket -lnsl"
	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
    fi
    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
	    [LIBS="$LIBS -lnsl"])])

    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
    AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
    AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
    if test "$tcl_ok" = "no"; then
	# Check a little harder for __pthread_mutex_init in the same
	# library, as some systems hide it there until pthread.h is
	# defined.  We could alternatively do an AC_TRY_COMPILE with
	# pthread.h, but that will work with libpthread really doesn't
	# exist, like AIX 4.2.  [Bug: 4359]
	AC_CHECK_LIB(pthread, __pthread_mutex_init,
		tcl_ok=yes, tcl_ok=no)
    fi

    if test "$tcl_ok" = "yes"; then
	# The space is needed
	THREADS_LIBS=" -lpthread"
    else
	AC_CHECK_LIB(pthreads, pthread_mutex_init,
	_ok=yes, tcl_ok=no)
	if test "$tcl_ok" = "yes"; then
	    # The space is needed
	    THREADS_LIBS=" -lpthreads"
	else
	    AC_CHECK_LIB(c, pthread_mutex_init,
		    tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = "no"; then
		AC_CHECK_LIB(c_r, pthread_mutex_init,
			tcl_ok=yes, tcl_ok=no)
		if test "$tcl_ok" = "yes"; then
		    # The space is needed
		    THREADS_LIBS=" -pthread"
		else
		    AC_MSG_WARN([Don't know how to find pthread lib on your system - you must edit the LIBS in the Makefile...])
		fi
	    fi
	fi
    fi

    # Does the pthread-implementation provide
    # 'pthread_attr_setstacksize' ?

    ac_saved_libs=$LIBS
    LIBS="$LIBS $THREADS_LIBS"
    AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork)
    LIBS=$ac_saved_libs

    # TIP #509
    AC_CHECK_DECLS([PTHREAD_MUTEX_RECURSIVE],tcl_ok=yes,tcl_ok=no, [[#include <pthread.h>]])
])

#--------------------------------------------------------------------
# SC_TCL_EARLY_FLAGS
#
#	Check for what flags are needed to be passed so the correct OS
#	features are available.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2688
2689
2690
2691
2692
2693
2694

















































2695
2696
2697
2698
2699
2700
2701
    if test "$tcl_checkBoth" = 1; then
	tk_oldLibs=$LIBS
	LIBS="$LIBS -lsocket -lnsl"
	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
    fi
    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
	    [LIBS="$LIBS -lnsl"])])

















































])

#--------------------------------------------------------------------
# SC_TCL_EARLY_FLAGS
#
#	Check for what flags are needed to be passed so the correct OS
#	features are available.
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    AC_TRY_COMPILE([[#define ]$1[ 1
]$2], $3,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[







|
|
|

|







2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define $1 1
$2]], [[$3]])],
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)]))
    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
	# See if we could use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_TRY_COMPILE(,[switch (0) {
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?])
	AC_MSG_RESULT([yes])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);],
		tcl_cv_DIR64=yes,tcl_cv_DIR64=no)])
	if test "x${tcl_cv_DIR64}" = "xyes" ; then
	    AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
	fi

	AC_CHECK_FUNCS(open64 lseek64)
	AC_MSG_CHECKING([for off64_t])
	AC_CACHE_VAL(tcl_cv_type_off64_t,[
	    AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
],
		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
	dnl functions lseek64 and open64 are defined.
	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])







|
|
|


|
|
|

|
|







|
|
|





|
|
|
|





|
|
|







|
|
|







2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[__int64 value = (__int64) 0;]])],
	    [tcl_type_64bit=__int64],[tcl_type_64bit="long long"])
	# See if we should use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) {
            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
        }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
	AC_MSG_RESULT([using long])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]],
		[[struct dirent64 p;]])],[tcl_cv_struct_dirent64=yes],[tcl_cv_struct_dirent64=no])])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]], [[struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);]])],
		[tcl_cv_DIR64=yes],[tcl_cv_DIR64=no])])
	if test "x${tcl_cv_DIR64}" = "xyes" ; then
	    AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h>]], [[struct stat64 p;
]])],
		[tcl_cv_struct_stat64=yes],[tcl_cv_struct_stat64=no])])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
	fi

	AC_CHECK_FUNCS(open64 lseek64)
	AC_MSG_CHECKING([for off64_t])
	AC_CACHE_VAL(tcl_cv_type_off64_t,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]], [[off64_t offset;
]])],
		[tcl_cv_type_off64_t=yes],[tcl_cv_type_off64_t=no])])
	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
	dnl functions lseek64 and open64 are defined.
	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AC_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	with_tcencoding=${withval})

    if test x"${with_tcencoding}" != x ; then
	AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}",
	    [What encoding should be used for embedded configuration info?])
    else
	AC_DEFINE(TCL_CFGVAL_ENCODING,"iso8859-1",
	    [What encoding should be used for embedded configuration info?])







|

|







2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AS_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	[with_tcencoding=${withval}])

    if test x"${with_tcencoding}" != x ; then
	AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}",
	    [What encoding should be used for embedded configuration info?])
    else
	AC_DEFINE(TCL_CFGVAL_ENCODING,"iso8859-1",
	    [What encoding should be used for embedded configuration info?])
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_TRY_RUN([[
#include <stdlib.h>
#include <string.h>
int main() {]$2[}]],[tcl_cv_]$1[_unbroken]=ok,
		[tcl_cv_]$1[_unbroken]=broken,[tcl_cv_]$1[_unbroken]=unknown))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi
    if test ["$tcl_ok"] = 0; then







|


|
<







2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884

2885
2886
2887
2888
2889
2890
2891
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_RUN_IFELSE([AC_LANG_SOURCE([[[
#include <stdlib.h>
#include <string.h>
int main() {]$2[}]]])],[tcl_cv_$1_unbroken=ok],[tcl_cv_$1_unbroken=broken],[tcl_cv_$1_unbroken=unknown]))

	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi
    if test ["$tcl_ok"] = 0; then
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_DECL], [AC_CHECK_DECLS(gethostbyaddr_r, [
    tcl_cv_api_gethostbyaddr_r=yes],[tcl_cv_api_gethostbyaddr_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_TYPE], [AC_CHECK_FUNC(gethostbyaddr_r, [
    AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *addr;
	int length;
	int type;
	struct hostent *result;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
			       &h_errnop);
    ], tcl_cv_api_gethostbyaddr_r_7=yes, tcl_cv_api_gethostbyaddr_r_7=no)])
    tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1,
	    [Define to 1 if gethostbyaddr_r takes 7 args.])
    else
	AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *addr;
	    int length;
	    int type;
	    struct hostent *result, *resultp;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
				   &resultp, &h_errnop);
	], tcl_cv_api_gethostbyaddr_r_8=yes, tcl_cv_api_gethostbyaddr_r_8=no)])
	tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1,
		[Define to 1 if gethostbyaddr_r takes 8 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|

|










|






|

|










|







2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_DECL], [AC_CHECK_DECLS(gethostbyaddr_r, [
    tcl_cv_api_gethostbyaddr_r=yes],[tcl_cv_api_gethostbyaddr_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_TYPE], [AC_CHECK_FUNC(gethostbyaddr_r, [
    AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <netdb.h>
    ]], [[
	char *addr;
	int length;
	int type;
	struct hostent *result;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
			       &h_errnop);
    ]])],[tcl_cv_api_gethostbyaddr_r_7=yes],[tcl_cv_api_gethostbyaddr_r_7=no])])
    tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1,
	    [Define to 1 if gethostbyaddr_r takes 7 args.])
    else
	AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <netdb.h>
	]], [[
	    char *addr;
	    int length;
	    int type;
	    struct hostent *result, *resultp;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
				   &resultp, &h_errnop);
	]])],[tcl_cv_api_gethostbyaddr_r_8=yes],[tcl_cv_api_gethostbyaddr_r_8=no])])
	tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1,
		[Define to 1 if gethostbyaddr_r takes 8 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664































2665
2666
2667
2668
2669
2670
2671

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_DECL], [AC_CHECK_DECLS(gethostbyname_r, [
    tcl_cv_api_gethostbyname_r=yes],[tcl_cv_api_gethostbyname_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_TYPE], [AC_CHECK_FUNC(gethostbyname_r, [
    AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *name;
	struct hostent *he, *res;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop);
    ], tcl_cv_api_gethostbyname_r_6=yes, tcl_cv_api_gethostbyname_r_6=no)])
    tcl_ok=$tcl_cv_api_gethostbyname_r_6
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1,
	    [Define to 1 if gethostbyname_r takes 6 args.])
    else
	AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *name;
	    struct hostent *he;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop);
	], tcl_cv_api_gethostbyname_r_5=yes, tcl_cv_api_gethostbyname_r_5=no)])
	tcl_ok=$tcl_cv_api_gethostbyname_r_5
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1,
		[Define to 1 if gethostbyname_r takes 5 args.])
	else
	    AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [
	    AC_TRY_COMPILE([
		#include <netdb.h>
	    ], [
		char *name;
		struct hostent *he;
		struct hostent_data data;

		(void) gethostbyname_r(name, he, &data);
	    ], tcl_cv_api_gethostbyname_r_3=yes, tcl_cv_api_gethostbyname_r_3=no)])
	    tcl_ok=$tcl_cv_api_gethostbyname_r_3
	    if test "$tcl_ok" = yes; then
		AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1,
		    [Define to 1 if gethostbyname_r takes 3 args.])
	    fi
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1,
	    [Define to 1 if gethostbyname_r is available.])
    fi
])])
































#--------------------------------------------------------------------
# SC_TCL_GETPWUID_R
#
#	Check if we have MT-safe variant of getpwuid() and if yes,
#	which one exactly.
#







|

|







|






|

|







|






|

|





|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_DECL], [AC_CHECK_DECLS(gethostbyname_r, [
    tcl_cv_api_gethostbyname_r=yes],[tcl_cv_api_gethostbyname_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_TYPE], [AC_CHECK_FUNC(gethostbyname_r, [
    AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <netdb.h>
    ]], [[
	char *name;
	struct hostent *he, *res;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop);
    ]])],[tcl_cv_api_gethostbyname_r_6=yes],[tcl_cv_api_gethostbyname_r_6=no])])
    tcl_ok=$tcl_cv_api_gethostbyname_r_6
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1,
	    [Define to 1 if gethostbyname_r takes 6 args.])
    else
	AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <netdb.h>
	]], [[
	    char *name;
	    struct hostent *he;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop);
	]])],[tcl_cv_api_gethostbyname_r_5=yes],[tcl_cv_api_gethostbyname_r_5=no])])
	tcl_ok=$tcl_cv_api_gethostbyname_r_5
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1,
		[Define to 1 if gethostbyname_r takes 5 args.])
	else
	    AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#include <netdb.h>
	    ]], [[
		char *name;
		struct hostent *he;
		struct hostent_data data;

		(void) gethostbyname_r(name, he, &data);
	    ]])],[tcl_cv_api_gethostbyname_r_3=yes],[tcl_cv_api_gethostbyname_r_3=no])])
	    tcl_ok=$tcl_cv_api_gethostbyname_r_3
	    if test "$tcl_ok" = yes; then
		AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1,
		    [Define to 1 if gethostbyname_r takes 3 args.])
	    fi
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1,
	    [Define to 1 if gethostbyname_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETADDRINFO
#
#	Check if we have 'getaddrinfo'
#
# Arguments:
#	None
#
# Results:
#	Might define the following vars:
#		HAVE_GETADDRINFO
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETADDRINFO], [AC_CHECK_FUNC(getaddrinfo, [
    AC_CACHE_CHECK([for working getaddrinfo], tcl_cv_api_getaddrinfo, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <netdb.h>
    ]], [[
	const char *name, *port;
	struct addrinfo *aiPtr, hints;
	(void)getaddrinfo(name,port, &hints, &aiPtr);
	(void)freeaddrinfo(aiPtr);
    ]])],[tcl_cv_api_getaddrinfo=yes],[tcl_cv_getaddrinfo=no])])
    tcl_ok=$tcl_cv_api_getaddrinfo
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETADDRINFO, 1,
	    [Define to 1 if getaddrinfo is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETPWUID_R
#
#	Check if we have MT-safe variant of getpwuid() and if yes,
#	which one exactly.
#
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
#		HAVE_GETPWUID_R_4
#		HAVE_GETPWUID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [
    AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	uid_t uid;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwuid_r(uid, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwuid_r_5=yes, tcl_cv_api_getpwuid_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwuid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R_5, 1,
	    [Define to 1 if getpwuid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    uid_t uid;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(uid, &pw, buf, buflen);
	], tcl_cv_api_getpwuid_r_4=yes, tcl_cv_api_getpwuid_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwuid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWUID_R_4, 1,
		[Define to 1 if getpwuid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
#		HAVE_GETPWUID_R_4
#		HAVE_GETPWUID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [
    AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <pwd.h>
    ]], [[
	uid_t uid;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwuid_r(uid, &pw, buf, buflen, &pwp);
    ]])],[tcl_cv_api_getpwuid_r_5=yes],[tcl_cv_api_getpwuid_r_5=no])])
    tcl_ok=$tcl_cv_api_getpwuid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R_5, 1,
	    [Define to 1 if getpwuid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <pwd.h>
	]], [[
	    uid_t uid;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(uid, &pw, buf, buflen);
	]])],[tcl_cv_api_getpwuid_r_4=yes],[tcl_cv_api_getpwuid_r_4=no])])
	tcl_ok=$tcl_cv_api_getpwuid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWUID_R_4, 1,
		[Define to 1 if getpwuid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
#		HAVE_GETPWNAM_R_4
#		HAVE_GETPWNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [
    AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	char *name;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwnam_r(name, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwnam_r_5=yes, tcl_cv_api_getpwnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R_5, 1,
	    [Define to 1 if getpwnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    char *name;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(name, &pw, buf, buflen);
	], tcl_cv_api_getpwnam_r_4=yes, tcl_cv_api_getpwnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWNAM_R_4, 1,
		[Define to 1 if getpwnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
#		HAVE_GETPWNAM_R_4
#		HAVE_GETPWNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [
    AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <pwd.h>
    ]], [[
	char *name;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwnam_r(name, &pw, buf, buflen, &pwp);
    ]])],[tcl_cv_api_getpwnam_r_5=yes],[tcl_cv_api_getpwnam_r_5=no])])
    tcl_ok=$tcl_cv_api_getpwnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R_5, 1,
	    [Define to 1 if getpwnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <pwd.h>
	]], [[
	    char *name;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(name, &pw, buf, buflen);
	]])],[tcl_cv_api_getpwnam_r_4=yes],[tcl_cv_api_getpwnam_r_4=no])])
	tcl_ok=$tcl_cv_api_getpwnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWNAM_R_4, 1,
		[Define to 1 if getpwnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
#		HAVE_GETGRGID_R_4
#		HAVE_GETGRGID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [
    AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	gid_t gid;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrgid_r(gid, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrgid_r_5=yes, tcl_cv_api_getgrgid_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrgid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R_5, 1,
	    [Define to 1 if getgrgid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    gid_t gid;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrgid_r(gid, &gr, buf, buflen);
	], tcl_cv_api_getgrgid_r_4=yes, tcl_cv_api_getgrgid_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrgid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRGID_R_4, 1,
		[Define to 1 if getgrgid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
#		HAVE_GETGRGID_R_4
#		HAVE_GETGRGID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [
    AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <grp.h>
    ]], [[
	gid_t gid;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrgid_r(gid, &gr, buf, buflen, &grp);
    ]])],[tcl_cv_api_getgrgid_r_5=yes],[tcl_cv_api_getgrgid_r_5=no])])
    tcl_ok=$tcl_cv_api_getgrgid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R_5, 1,
	    [Define to 1 if getgrgid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <grp.h>
	]], [[
	    gid_t gid;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrgid_r(gid, &gr, buf, buflen);
	]])],[tcl_cv_api_getgrgid_r_4=yes],[tcl_cv_api_getgrgid_r_4=no])])
	tcl_ok=$tcl_cv_api_getgrgid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRGID_R_4, 1,
		[Define to 1 if getgrgid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
#		HAVE_GETGRNAM_R_4
#		HAVE_GETGRNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [
    AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	char *name;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrnam_r(name, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrnam_r_5=yes, tcl_cv_api_getgrnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R_5, 1,
	    [Define to 1 if getgrnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    char *name;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrnam_r(name, &gr, buf, buflen);
	], tcl_cv_api_getgrnam_r_4=yes, tcl_cv_api_getgrnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRNAM_R_4, 1,
		[Define to 1 if getgrnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R, 1,
	    [Define to 1 if getgrnam_r is available.])
    fi
])])

AC_DEFUN([SC_TCL_IPV6],[
	NEED_FAKE_RFC2553=0
	AC_CHECK_FUNCS(getnameinfo getaddrinfo freeaddrinfo gai_strerror,,[NEED_FAKE_RFC2553=1])
	AC_CHECK_TYPES([
		struct addrinfo,
		struct in6_addr,
		struct sockaddr_in6,
		struct sockaddr_storage],,[NEED_FAKE_RFC2553=1],[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
]])
if test "x$NEED_FAKE_RFC2553" = "x1"; then
   AC_DEFINE([NEED_FAKE_RFC2553], 1,
        [Use compat implementation of getaddrinfo() and friends])
   AC_LIBOBJ([fake-rfc2553])
   AC_CHECK_FUNC(strlcpy)
fi
])

#------------------------------------------------------------------------
# SC_CC_FOR_BUILD
#	For cross compiles, locate a C compiler that can generate native binaries.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		CC_FOR_BUILD
#		EXEEXT_FOR_BUILD
#------------------------------------------------------------------------

dnl Get a default for CC_FOR_BUILD to put into Makefile.
AC_DEFUN([AX_CC_FOR_BUILD],[# Put a plausible default for CC_FOR_BUILD in Makefile.
    if test -z "$CC_FOR_BUILD"; then
      if test "x$cross_compiling" = "xno"; then
        CC_FOR_BUILD='$(CC)'
      else
        AC_MSG_CHECKING([for gcc])
        AC_CACHE_VAL(ac_cv_path_cc, [
            search_path=`echo ${PATH} | sed -e 's/:/ /g'`
            for dir in $search_path ; do
                for j in `ls -r $dir/gcc 2> /dev/null` \
                        `ls -r $dir/gcc 2> /dev/null` ; do
                    if test x"$ac_cv_path_cc" = x ; then
                        if test -f "$j" ; then
                            ac_cv_path_cc=$j
                            break
                        fi
                    fi
                done
            done
        ])
      fi
    fi
    AC_SUBST(CC_FOR_BUILD)
    # Also set EXEEXT_FOR_BUILD.
    if test "x$cross_compiling" = "xno"; then
      EXEEXT_FOR_BUILD='$(EXEEXT)'
      OBJEXT_FOR_BUILD='$(OBJEXT)'
    else
      OBJEXT_FOR_BUILD='.no'
      AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
        [rm -f conftest*
         echo 'int main () { return 0; }' > conftest.c
         bfd_cv_build_exeext=
         ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
         for file in conftest.*; do
           case $file in
           *.c | *.o | *.obj | *.ilk | *.pdb) ;;
           *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
           esac
         done
         rm -f conftest*
         test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
      EXEEXT_FOR_BUILD=""
      test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
    fi
    AC_SUBST(EXEEXT_FOR_BUILD)])dnl
    AC_SUBST(OBJEXT_FOR_BUILD)])dnl
])


#------------------------------------------------------------------------
# SC_ZIPFS_SUPPORT
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		ZIP_PROG
#       ZIP_PROG_OPTIONS
#       ZIP_PROG_VFSSEARCH
#       ZIP_INSTALL_OBJS
#------------------------------------------------------------------------

AC_DEFUN([SC_ZIPFS_SUPPORT], [
    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""

    AC_MSG_CHECKING([for zip])
    AC_CACHE_VAL(ac_cv_path_zip, [
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then
            if test -f "$j" ; then
            ac_cv_path_zip=$j
            break
            fi
        fi
        done
    done
    ])
    if test -f "$ac_cv_path_zip" ; then
        ZIP_PROG="$ac_cv_path_zip"
        AC_MSG_RESULT([$ZIP_PROG])
        ZIP_PROG_OPTIONS="-rq"
        ZIP_PROG_VFSSEARCH="*"
        AC_MSG_RESULT([Found INFO Zip in environment])
        # Use standard arguments for zip
    else
        # It is not an error if an installed version of Zip can't be located.
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        AC_MSG_RESULT([No zip found on PATH. Building minizip])
    fi
    AC_SUBST(ZIP_PROG)
    AC_SUBST(ZIP_PROG_OPTIONS)
    AC_SUBST(ZIP_PROG_VFSSEARCH)
    AC_SUBST(ZIP_INSTALL_OBJS)
])

# Local Variables:
# mode: autoconf
# End:







|


|






|






|


|






|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336















































































































































3337
3338
3339
#		HAVE_GETGRNAM_R_4
#		HAVE_GETGRNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [
    AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <grp.h>
    ]], [[
	char *name;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrnam_r(name, &gr, buf, buflen, &grp);
    ]])],[tcl_cv_api_getgrnam_r_5=yes],[tcl_cv_api_getgrnam_r_5=no])])
    tcl_ok=$tcl_cv_api_getgrnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R_5, 1,
	    [Define to 1 if getgrnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <grp.h>
	]], [[
	    char *name;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrnam_r(name, &gr, buf, buflen);
	]])],[tcl_cv_api_getgrnam_r_4=yes],[tcl_cv_api_getgrnam_r_4=no])])
	tcl_ok=$tcl_cv_api_getgrnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRNAM_R_4, 1,
		[Define to 1 if getgrnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R, 1,
	    [Define to 1 if getgrnam_r is available.])
    fi
])])
















































































































































# Local Variables:
# mode: autoconf
# End:

Changes to unix/tk.pc.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# tk pkg-config source file

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
demodir=@TK_DEMO_DIR@

Name: The Tk Toolkit
Description: Tk is a cross-platform graphical user interface toolkit, the standard GUI not only for Tcl, but for many other dynamic languages as well.
URL: https://www.tcl-lang.org/
Version: @TK_VERSION@@TK_PATCH_LEVEL@
Requires: tcl >= 8.6
Libs: -L${libdir} @TK_LIB_FLAG@ @TK_STUB_LIB_FLAG@
Libs.private: @XFT_LIBS@ @XLIBSW@
Cflags: -I${includedir}






<



|

|
|


1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
# tk pkg-config source file

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@


Name: The Tk Toolkit
Description: Tk is a cross-platform graphical user interface toolkit, the standard GUI not only for Tcl, but for many other dynamic languages as well.
URL: http://www.tcl.tk/
Version: @TK_VERSION@@TK_PATCH_LEVEL@
Requires: tcl >= 8.5
Libs: -L${libdir} @TK_LIB_FLAG@
Libs.private: @XFT_LIBS@ @XLIBSW@
Cflags: -I${includedir}

Changes to unix/tk.spec.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       8.7a4
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           https://www.tcl-lang.org/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.6.0
Requires:      tcl >= 8.6.0

%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks.  When paired with
the Tk toolkit, Tcl provides the fastest and most powerful way to
create GUI applications that run on PCs, Unix, and Mac OS X.  Tcl






|




|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       8.5.19
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           http://www.tcl.tk/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.5.0
Requires:      tcl >= 8.5.0

%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks.  When paired with
the Tk toolkit, Tcl provides the fastest and most powerful way to
create GUI applications that run on PCs, Unix, and Mac OS X.  Tcl

Changes to unix/tkAppInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


















81

82
83
84
85
86
87
88
89
90
91
92
/*
 * tkAppInit.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for wish and other Tk-based applications.
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#include "tkPort.h"

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus
}
#endif
#endif /* TK_TEST */

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   define MODULE_SCOPE extern
#endif
MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *);
MODULE_SCOPE int main(int, char **);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tk_Main()
 */

#ifdef TK_LOCAL_MAIN_HOOK
MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif

/* Make sure the stubbed variants of those are never used. */
#undef Tcl_ObjSetVar2
#undef Tcl_NewStringObj

/*
 *----------------------------------------------------------------------
 *
 * main --
 *
 *	This is the main program for the application.
 *
 * Results:
 *	None: Tk_Main never returns here, so this procedure never returns
 *	either.
 *
 * Side effects:
 *	Just about anything, since from here we call arbitrary Tcl code.
 *
 *----------------------------------------------------------------------
 */

int
main(
    int argc,			/* Number of command-line arguments. */
    char **argv)		/* Values of command-line arguments. */
{


















#ifdef TK_LOCAL_MAIN_HOOK

    TK_LOCAL_MAIN_HOOK(&argc, &argv);
#elif (TCL_MAJOR_VERSION > 8) || (TCL_MINOR_VERSION > 6)
    /* This doesn't work with Tcl 8.6 */
    TclZipfs_AppHook(&argc, &argv);
#endif

    Tk_Main(argc, argv, TK_LOCAL_APPINIT);
    return 0;			/* Needed only to prevent compiler warning. */
}

/*



|
|



<





<
<

|


<
|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>

<
<
<







1
2
3
4
5
6
7
8

9
10
11
12
13


14
15
16
17

18





19





























20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63



64
65
66
67
68
69
70
/*
 * tkAppInit.c --
 *
 *	Provides a default version of the Tcl_AppInit procedure for use in
 *	wish and similar Tk-based applications.
 *
 * Copyright (c) 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.
 */



#include "tk.h"
#include "locale.h"

#ifdef TK_TEST

extern int		Tktest_Init(Tcl_Interp *interp);





#endif /* TK_TEST */






























/*
 *----------------------------------------------------------------------
 *
 * main --
 *
 *	This is the main program for the application.
 *
 * Results:
 *	None: Tk_Main never returns here, so this procedure never returns
 *	either.
 *
 * Side effects:
 *	Whatever the application does.
 *
 *----------------------------------------------------------------------
 */

int
main(
    int argc,			/* Number of command-line arguments. */
    char **argv)		/* Values of command-line arguments. */
{
    /*
     * The following #if block allows you to change the AppInit function by
     * using a #define of TCL_LOCAL_APPINIT instead of rewriting this entire
     * file. The #if checks for that #define and uses Tcl_AppInit if it
     * doesn't exist.
     */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
    extern int TK_LOCAL_APPINIT (Tcl_Interp *interp);

    /*
     * The following #if block allows you to change how Tcl finds the startup
     * script, prime the library or encoding paths, fiddle with the argv,
     * etc., without needing to rewrite Tk_Main()
     */

#ifdef TK_LOCAL_MAIN_HOOK
    extern int TK_LOCAL_MAIN_HOOK (int *argc, char ***argv);
    TK_LOCAL_MAIN_HOOK(&argc, &argv);



#endif

    Tk_Main(argc, argv, TK_LOCAL_APPINIT);
    return 0;			/* Needed only to prevent compiler warning. */
}

/*
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
 *----------------------------------------------------------------------
 */

int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

#if defined(USE_CUSTOM_EXIT_PROC)
    if (TkpWantsExitProc()) {
	/* The cast below avoids warnings from old gcc compilers. */
	Tcl_SetExitProc((void *)TkpExitProc);
    }
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);

#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
     *     return TCL_ERROR;
     * }
     *
     * where "Mod" is the name of the module. (Dynamically-loadable packages
     * should have the same entry-point name.)
     */

    /*
     * Call Tcl_CreateObjCommand for application-specific commands, if they
     * weren't already created by the init procedures called above.
     */

    /*
     * Specify a user-specific startup file to invoke if the application is
     * run interactively. Typically the startup file is "~/.apprc" where "app"
     * is the name of the application. If this line is deleted then no user-
     * specific startup file will be run under any conditions.
     */

    Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
	    Tcl_NewStringObj("~/.wishrc", -1), TCL_GLOBAL_ONLY);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|








<
<
<
<
<
<
<




|
>










|
<



|







|


|
<










86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
 *----------------------------------------------------------------------
 */

int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    if (Tcl_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);








#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
            (Tcl_PackageInitProc *) NULL);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
     *     return TCL_ERROR;
     * }
     *
     * where "Mod" is the name of the module.

     */

    /*
     * Call Tcl_CreateCommand for application-specific commands, if they
     * weren't already created by the init procedures called above.
     */

    /*
     * Specify a user-specific startup file to invoke if the application is
     * run interactively. Typically the startup file is "~/.apprc" where "app"
     * is the name of the application. If this line is deleted then no user-
     * -specific startup file will be run under any conditions.
     */

    Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);

    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkConfig.h.in.

1
2
3
4
5
6


7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32



33
34
35
36
37
38
39
40
41















42
43
44
45
46
47
48
49
50
51
52
53
54
55
/* ../unix/tkConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TKCONFIG
    #define _TKCONFIG



/* Define if building universal (internal helper macro) */

#undef AC_APPLE_UNIVERSAL_BUILD

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION

/* Do we have access to Darwin CoreFoundation.framework? */
#undef HAVE_COREFOUNDATION

/* Is 'DIR64' in <sys/types.h>? */
#undef HAVE_DIR64

/* Compiler support for module scope symbols */
#undef HAVE_HIDDEN

/* Do we have the intptr_t type? */
#undef HAVE_INTPTR_T

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the `Xft' library (-lXft). */
#undef HAVE_LIBXFT




/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the `open64' function. */
#undef HAVE_OPEN64
















/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS

/* Do we have <stdbool.h>? */
#undef HAVE_STDBOOL_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */






>
>
|
>
|













<
<
|
<







>
>
>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63



64
65
66
67
68
69
70
/* ../unix/tkConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TKCONFIG
    #define _TKCONFIG

/* Is pthread_attr_get_np() declared in <pthread.h>? */
#undef ATTRGETNP_NOT_DECLARED

/* Is pthread_getattr_np declared in <pthread.h>? */
#undef GETATTRNP_NOT_DECLARED

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION

/* Do we have access to Darwin CoreFoundation.framework? */
#undef HAVE_COREFOUNDATION

/* Is 'DIR64' in <sys/types.h>? */
#undef HAVE_DIR64



/* Define to 1 if the system has the type `intptr_t'. */

#undef HAVE_INTPTR_T

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the `Xft' library (-lXft). */
#undef HAVE_LIBXFT

/* Do we have <limits.h>? */
#undef HAVE_LIMITS_H

/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the `open64' function. */
#undef HAVE_OPEN64

/* Define to 1 if you have the `pthread_atfork' function. */
#undef HAVE_PTHREAD_ATFORK

/* Do we want a BSD-like thread-attribute interface? */
#undef HAVE_PTHREAD_ATTR_GET_NP

/* Define to 1 if you have the `pthread_attr_setstacksize' function. */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE

/* Do we want a Linux-like thread-attribute interface? */
#undef HAVE_PTHREAD_GETATTR_NP

/* Define to 1 if you have the `pthread_get_stacksize_np' function. */
#undef HAVE_PTHREAD_GET_STACKSIZE_NP

/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS




/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113






114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159


160

161
162
163
164
165
166
167
168
169
170
171
172
173
174



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T

/* Do we have the uintptr_t type? */
#undef HAVE_UINTPTR_T

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT

/* Have we turned on XFT (antialiased fonts)? */
#undef HAVE_XFT




/* Is XScreenSaver available? */
#undef HAVE_XSS

/* Is this a Mac I see before me? */
#undef MAC_OSX_TCL

/* Are we building TkAqua? */
#undef MAC_OSX_TK

/* No Compiler support for module scope symbols */
#undef MODULE_SCOPE

/* Is no debugging enabled? */
#undef NDEBUG

/* Is Darwin CoreFoundation unavailable for 64-bit? */
#undef NO_COREFOUNDATION_64

/* Do we have fd_set? */
#undef NO_FD_SET







/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

/* What encoding should be used for embedded configuration info? */
#undef TCL_CFGVAL_ENCODING

/* Is this a 64-bit build? */
#undef TCL_CFG_DO64BIT

/* Is this an optimized build? */
#undef TCL_CFG_OPTIMIZED

/* Is bytecode debugging enabled? */
#undef TCL_COMPILE_DEBUG

/* Are bytecode statistics enabled? */
#undef TCL_COMPILE_STATS

/* Is memory debugging enabled? */
#undef TCL_MEM_DEBUG

/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT



/* Do 'long' and 'long long' have the same size (64-bit)? */

#undef TCL_WIDE_INT_IS_LONG

/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is Tk built as a framework? */
#undef TK_FRAMEWORK

/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG




/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
#  undef WORDS_BIGENDIAN
# endif
#endif

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE








|










>
>
>










|










>
>
>
>
>
>













<
<
<









<
<
<


















>
>
|
>














>
>
>
|
|
<
<
<
<
<
<
|
<
<







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150



151
152
153
154
155
156
157
158
159



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200






201


202
203
204
205
206
207
208

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T

/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT

/* Have we turned on XFT (antialiased fonts)? */
#undef HAVE_XFT

/* Do we have XkbKeycodeToKeysym? */
#undef HAVE_XKBKEYCODETOKEYSYM

/* Is XScreenSaver available? */
#undef HAVE_XSS

/* Is this a Mac I see before me? */
#undef MAC_OSX_TCL

/* Are we building TkAqua? */
#undef MAC_OSX_TK

/* Compiler support for module scope symbols */
#undef MODULE_SCOPE

/* Is no debugging enabled? */
#undef NDEBUG

/* Is Darwin CoreFoundation unavailable for 64-bit? */
#undef NO_COREFOUNDATION_64

/* Do we have fd_set? */
#undef NO_FD_SET

/* Do we have <limits.h>? */
#undef NO_LIMITS_H

/* Do we have <stdlib.h>? */
#undef NO_STDLIB_H

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME




/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS




/* Is this a 64-bit build? */
#undef TCL_CFG_DO64BIT

/* Is this an optimized build? */
#undef TCL_CFG_OPTIMIZED

/* Is bytecode debugging enabled? */
#undef TCL_COMPILE_DEBUG

/* Are bytecode statistics enabled? */
#undef TCL_COMPILE_STATS

/* Is memory debugging enabled? */
#undef TCL_MEM_DEBUG

/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT

/* Are we building with threads enabled? */
#undef TCL_THREADS

/* Are wide integers to be implemented with C 'long's? */
#undef TCL_WIDE_INT_IS_LONG

/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is Tk built as a framework? */
#undef TK_FRAMEWORK

/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG

/* Do we want to use the threaded memory allocator? */
#undef USE_THREAD_ALLOC

/* Define to 1 if your processor stores words with the most significant byte
   first (like Motorola and SPARC, unlike Intel and VAX). */






#undef WORDS_BIGENDIAN



/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE

200
201
202
203
204
205
206



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
#undef _OE_SOCKETS

/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS

/* Do we want the reentrant OS API? */
#undef _REENTRANT




/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED

/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif

/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
#undef inline
#endif

/* Signed integer type wide enough to hold a pointer. */
#undef intptr_t

/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t

/* Unsigned integer type wide enough to hold a pointer. */
#undef uintptr_t


    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_STRING
    /* override */ #undef PACKAGE_TARNAME

    #endif /* _TKCONFIG */







>
>
>












<
<
<
<
<
<
<
<
<
<
<
<






|


<
<
|
<
|





|
|
>

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237












238
239
240
241
242
243
244
245
246


247

248
249
250
251
252
253
254
255
256
257
#undef _OE_SOCKETS

/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS

/* Do we want the reentrant OS API? */
#undef _REENTRANT

/* Do we want the thread-safe OS API? */
#undef _THREAD_SAFE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED

/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif













/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t

/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t



/* Do we want to use the strtod() in compat? */

#undef strtod


    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */

Changes to unix/tkConfig.sh.in.

91
92
93
94
95
96
97
98
99
100
TK_STUB_LIB_SPEC='@TK_STUB_LIB_SPEC@'

# Path to the Tk stub library in the build directory.
TK_BUILD_STUB_LIB_PATH='@TK_BUILD_STUB_LIB_PATH@'

# Path to the Tk stub library in the install directory.
TK_STUB_LIB_PATH='@TK_STUB_LIB_PATH@'

# Top-level directory in which Tk's demo files are installed.
TK_DEMO_DIR='@TK_DEMO_DIR@'







<
<
<
91
92
93
94
95
96
97



TK_STUB_LIB_SPEC='@TK_STUB_LIB_SPEC@'

# Path to the Tk stub library in the build directory.
TK_BUILD_STUB_LIB_PATH='@TK_BUILD_STUB_LIB_PATH@'

# Path to the Tk stub library in the install directory.
TK_STUB_LIB_PATH='@TK_STUB_LIB_PATH@'



Changes to unix/tkUnix.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50


51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#ifdef HAVE_XSS
#   include <X11/extensions/scrnsaver.h>
#   ifdef __APPLE__
/* Support for weak-linked libXss. */
#	define HaveXSSLibrary()	(&XScreenSaverQueryInfo != NULL)
#   else
/* Other platforms always link libXss. */
#	define HaveXSSLibrary()	(1)
#   endif
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo
 *	server" command.
 *
 * Results:
 *	Sets the interpreter result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkGetServerInfo(
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    Tk_Window tkwin)		/* Token for window; this selects a particular
				 * display and server. */
{


    Tcl_SetObjResult(interp, Tcl_ObjPrintf("X%dR%d %s %d",
	    ProtocolVersion(Tk_Display(tkwin)),
	    ProtocolRevision(Tk_Display(tkwin)),
	    ServerVendor(Tk_Display(tkwin)),
	    VendorRelease(Tk_Display(tkwin))));

}

/*
 *----------------------------------------------------------------------
 *
 * TkGetDefaultScreenName --
 *
 *	Returns the name of the screen that Tk should use during
 *	initialization.
 *
 * Results:
 *	Returns the argument or a string that should not be freed by the
 *	caller.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Interp used to find environment
				 * variables. */
    const char *screenName)	/* Screen name from command line, or NULL. */
{
    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY);
    }
    return screenName;
}








|
<
<
<
<
<
<
<












|














>
>
|
|
|
|
|
>




















|



|







9
10
11
12
13
14
15
16







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#ifdef HAVE_XSS
#include <X11/extensions/scrnsaver.h>







#endif

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo
 *	server" command.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkGetServerInfo(
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    Tk_Window tkwin)		/* Token for window; this selects a particular
				 * display and server. */
{
    char buffer[8 + TCL_INTEGER_SPACE * 2];
    char buffer2[TCL_INTEGER_SPACE];

    sprintf(buffer, "X%dR%d ", ProtocolVersion(Tk_Display(tkwin)),
	    ProtocolRevision(Tk_Display(tkwin)));
    sprintf(buffer2, " %d", VendorRelease(Tk_Display(tkwin)));
    Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
	    buffer2, (char *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetDefaultScreenName --
 *
 *	Returns the name of the screen that Tk should use during
 *	initialization.
 *
 * Results:
 *	Returns the argument or a string that should not be freed by the
 *	caller.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CONST char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Interp used to find environment
				 * variables. */
    CONST char *screenName)	/* Screen name from command line, or NULL. */
{
    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY);
    }
    return screenName;
}

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
void
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. */
{
  (void)tkwin;
  (void)x;
  (void)y;
  (void)state;

  /*
   * This function intentionally left blank
   */
}

/*
 *----------------------------------------------------------------------







<
<
<
<
<







100
101
102
103
104
105
106





107
108
109
110
111
112
113
void
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. */
{





  /*
   * This function intentionally left blank
   */
}

/*
 *----------------------------------------------------------------------
212
213
214
215
216
217
218
219



220
221

222
223
224
225
226
227
228
    int eventBase, errorBase, major, minor;

    /*
     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash
     * on some buggy versions of XFree86.
     */

    if (HaveXSSLibrary()



	    && XScreenSaverQueryExtension(dpy, &eventBase, &errorBase)
	    && XScreenSaverQueryVersion(dpy, &major, &minor)) {

	XScreenSaverInfo *info = XScreenSaverAllocInfo();

	if (info == NULL) {
	    /*
	     * We are out of memory.
	     */








|
>
>
>
|
|
>







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    int eventBase, errorBase, major, minor;

    /*
     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash
     * on some buggy versions of XFree86.
     */

    if (
#ifdef __APPLE__
 	XScreenSaverQueryInfo != NULL && /* Support for weak-linked libXss. */
#endif
	XScreenSaverQueryExtension(dpy, &eventBase, &errorBase) &&
	XScreenSaverQueryVersion(dpy, &major, &minor)) {

	XScreenSaverInfo *info = XScreenSaverAllocInfo();

	if (info == NULL) {
	    /*
	     * We are out of memory.
	     */

Changes to unix/tkUnix3d.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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"

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif

/*
 * This structure is used to keep track of the extra colors used by Unix 3D
 * borders.
 */







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * 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"

#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif

/*
 * This structure is used to keep track of the extra colors used by Unix 3D
 * borders.
 */
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 *
 *----------------------------------------------------------------------
 */

TkBorder *
TkpGetBorder(void)
{
    UnixBorder *borderPtr = (UnixBorder *)ckalloc(sizeof(UnixBorder));

    borderPtr->solidGC = NULL;
    return (TkBorder *) borderPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeBorder --







|
<
|







42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
 *
 *----------------------------------------------------------------------
 */

TkBorder *
TkpGetBorder(void)
{
    UnixBorder *borderPtr = (UnixBorder *) ckalloc(sizeof(UnixBorder));

    borderPtr->solidGC = None;
    return (TkBorder *) borderPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeBorder --
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
void
TkpFreeBorder(
    TkBorder *borderPtr)
{
    UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
    Display *display = DisplayOfScreen(borderPtr->screen);

    if (unixBorderPtr->solidGC != NULL) {
	Tk_FreeGC(display, unixBorderPtr->solidGC);
    }
}
/*
 *--------------------------------------------------------------
 *
 * Tk_3DVerticalBevel --







|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
void
TkpFreeBorder(
    TkBorder *borderPtr)
{
    UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
    Display *display = DisplayOfScreen(borderPtr->screen);

    if (unixBorderPtr->solidGC != None) {
	Tk_FreeGC(display, unixBorderPtr->solidGC);
    }
}
/*
 *--------------------------------------------------------------
 *
 * Tk_3DVerticalBevel --
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
				 * TK_RELIEF_RAISED means interior of object
				 * should appear higher than exterior. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    GC left, right;
    Display *display = Tk_Display(tkwin);

    if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT)) {
	TkpGetShadows(borderPtr, tkwin);
    }

    if (relief == TK_RELIEF_RAISED) {
	XFillRectangle(display, drawable,
		(leftBevel) ? borderPtr->lightGC : borderPtr->darkGC,
		x, y, (unsigned) width, (unsigned) height);







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
				 * TK_RELIEF_RAISED means interior of object
				 * should appear higher than exterior. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    GC left, right;
    Display *display = Tk_Display(tkwin);

    if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
	TkpGetShadows(borderPtr, tkwin);
    }

    if (relief == TK_RELIEF_RAISED) {
	XFillRectangle(display, drawable,
		(leftBevel) ? borderPtr->lightGC : borderPtr->darkGC,
		x, y, (unsigned) width, (unsigned) height);
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	right = borderPtr->lightGC;
	goto ridgeGroove;
    } else if (relief == TK_RELIEF_FLAT) {
	XFillRectangle(display, drawable, borderPtr->bgGC, x, y,
		(unsigned) width, (unsigned) height);
    } else if (relief == TK_RELIEF_SOLID) {
	UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
	if (unixBorderPtr->solidGC == NULL) {
	    XGCValues gcValues;

	    gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
	    unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	}
	XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
		(unsigned) width, (unsigned) height);







|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	right = borderPtr->lightGC;
	goto ridgeGroove;
    } else if (relief == TK_RELIEF_FLAT) {
	XFillRectangle(display, drawable, borderPtr->bgGC, x, y,
		(unsigned) width, (unsigned) height);
    } else if (relief == TK_RELIEF_SOLID) {
	UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
	if (unixBorderPtr->solidGC == None) {
	    XGCValues gcValues;

	    gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
	    unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	}
	XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
		(unsigned) width, (unsigned) height);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
				 * TK_RELIEF_RAISED means interior of object
				 * should appear higher than exterior. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    Display *display = Tk_Display(tkwin);
    int bottom, halfway, x1, x2, x1Delta, x2Delta;
    UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
    GC topGC = NULL, bottomGC = NULL;
				/* Initializations needed only to prevent
				 * compiler warnings. */

    if ((borderPtr->lightGC == NULL) && (relief != TK_RELIEF_FLAT) &&
	    (relief != TK_RELIEF_SOLID)) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*
     * Compute a GC for the top half of the bevel and a GC for the bottom half
     * (they're the same in many cases).







|



|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
				 * TK_RELIEF_RAISED means interior of object
				 * should appear higher than exterior. */
{
    TkBorder *borderPtr = (TkBorder *) border;
    Display *display = Tk_Display(tkwin);
    int bottom, halfway, x1, x2, x1Delta, x2Delta;
    UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
    GC topGC = None, bottomGC = None;
				/* Initializations needed only to prevent
				 * compiler warnings. */

    if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT) &&
	    (relief != TK_RELIEF_SOLID)) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*
     * Compute a GC for the top half of the bevel and a GC for the bottom half
     * (they're the same in many cases).
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	topGC = bottomGC = (topBevel? borderPtr->lightGC : borderPtr->darkGC);
	break;
    case TK_RELIEF_RIDGE:
	topGC = borderPtr->lightGC;
	bottomGC = borderPtr->darkGC;
	break;
    case TK_RELIEF_SOLID:
	if (unixBorderPtr->solidGC == NULL) {
	    XGCValues gcValues;

	    gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
	    unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	}
	XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
		(unsigned) width, (unsigned) height);







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	topGC = bottomGC = (topBevel? borderPtr->lightGC : borderPtr->darkGC);
	break;
    case TK_RELIEF_RIDGE:
	topGC = borderPtr->lightGC;
	bottomGC = borderPtr->darkGC;
	break;
    case TK_RELIEF_SOLID:
	if (unixBorderPtr->solidGC == None) {
	    XGCValues gcValues;

	    gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
	    unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	}
	XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
		(unsigned) width, (unsigned) height);
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
				 * drawing. */
{
    XColor lightColor, darkColor;
    int stressed, tmp1, tmp2;
    int r, g, b;
    XGCValues gcValues;

    if (borderPtr->lightGC != NULL) {
	return;
    }
    stressed = TkpCmapStressed(tkwin, borderPtr->colormap);

    /*
     * First, handle the case of a color display with lots of colors. The
     * shadow colors get computed using whichever formula results in the







|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
				 * drawing. */
{
    XColor lightColor, darkColor;
    int stressed, tmp1, tmp2;
    int r, g, b;
    XGCValues gcValues;

    if (borderPtr->lightGC != None) {
	return;
    }
    stressed = TkpCmapStressed(tkwin, borderPtr->colormap);

    /*
     * First, handle the case of a color display with lots of colors. The
     * shadow colors get computed using whichever formula results in the
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
	 * color for the light shadow by reducing each color component by 10%.
	 *
	 * Compute the colors using integers, not using lightColor.red etc.:
	 * these are shorts and may have problems with integer overflow.
	 */

	/*
	 * Compute the dark shadow color.
	 */

	r = (int) borderPtr->bgColorPtr->red;
	g = (int) borderPtr->bgColorPtr->green;
	b = (int) borderPtr->bgColorPtr->blue;

	if (r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) {
	    darkColor.red = (MAX_INTENSITY + 3*r)/4;
	    darkColor.green = (MAX_INTENSITY + 3*g)/4;
	    darkColor.blue = (MAX_INTENSITY + 3*b)/4;
	} else {
	    darkColor.red = (60 * r)/100;
	    darkColor.green = (60 * g)/100;
	    darkColor.blue = (60 * b)/100;
	}

	/*
	 * Allocate the dark shadow color and its GC.
	 */

	borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor);
	gcValues.foreground = borderPtr->darkColorPtr->pixel;
	borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);

	/*
	 * Compute the light shadow color.
	 */

	if (g > MAX_INTENSITY*0.95) {
	    lightColor.red = (90 * r)/100;
	    lightColor.green = (90 * g)/100;
	    lightColor.blue = (90 * b)/100;
	} else {







|

















|







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
	 * color for the light shadow by reducing each color component by 10%.
	 *
	 * Compute the colors using integers, not using lightColor.red etc.:
	 * these are shorts and may have problems with integer overflow.
	 */

	/*
	 * Compute the dark shadow color
	 */

	r = (int) borderPtr->bgColorPtr->red;
	g = (int) borderPtr->bgColorPtr->green;
	b = (int) borderPtr->bgColorPtr->blue;

	if (r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) {
	    darkColor.red = (MAX_INTENSITY + 3*r)/4;
	    darkColor.green = (MAX_INTENSITY + 3*g)/4;
	    darkColor.blue = (MAX_INTENSITY + 3*b)/4;
	} else {
	    darkColor.red = (60 * r)/100;
	    darkColor.green = (60 * g)/100;
	    darkColor.blue = (60 * b)/100;
	}

	/*
	 * Allocate the dark shadow color and its GC
	 */

	borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor);
	gcValues.foreground = borderPtr->darkColorPtr->pixel;
	borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);

	/*
	 * Compute the light shadow color
	 */

	if (g > MAX_INTENSITY*0.95) {
	    lightColor.red = (90 * r)/100;
	    lightColor.green = (90 * g)/100;
	    lightColor.blue = (90 * b)/100;
	} else {
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
	    if (tmp1 > MAX_INTENSITY) {
		tmp1 = MAX_INTENSITY;
	    }
	    tmp2 = (MAX_INTENSITY + b)/2;
	    lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2;
	}

	/*
	 * Allocate the light shadow color and its GC.
	 */

	borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor);
	gcValues.foreground = borderPtr->lightColorPtr->pixel;
	borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	return;
    }

    if (borderPtr->shadow == None) {
	borderPtr->shadow = Tk_GetBitmap(NULL, tkwin,
		Tk_GetUid("gray50"));
	if (borderPtr->shadow == None) {
	    Tcl_Panic("TkpGetShadows couldn't allocate bitmap for border");
	}
    }
    if (borderPtr->visual->map_entries > 2) {
	/*







|
|
|








|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
	    if (tmp1 > MAX_INTENSITY) {
		tmp1 = MAX_INTENSITY;
	    }
	    tmp2 = (MAX_INTENSITY + b)/2;
	    lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2;
	}

       /*
        * Allocate the light shadow color and its GC
        */

	borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor);
	gcValues.foreground = borderPtr->lightColorPtr->pixel;
	borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
	return;
    }

    if (borderPtr->shadow == None) {
	borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin,
		Tk_GetUid("gray50"));
	if (borderPtr->shadow == None) {
	    Tcl_Panic("TkpGetShadows couldn't allocate bitmap for border");
	}
    }
    if (borderPtr->visual->map_entries > 2) {
	/*

Changes to unix/tkUnixButton.c.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    TkButton info;		/* Generic button info. */
} UnixButton;

/*
 * The class function table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * The button image.
 * The header info here is ignored, it's the image that's important. The
 * colors will be applied as follows:
 *   A = Background
 *   B = Background
 *   C = 3D light
 *   D = selectColor
 *   E = 3D dark
 *   F = Background
 *   G = Indicator Color
 *   H = disabled Indicator Color
 */

/* XPM */
static const char *const button_images[] = {
    /* width height ncolors chars_per_pixel */
    "52 26 7 1",
    /* colors */
    "A c #808000000000",
    "B c #000080800000",
    "C c #808080800000",
    "D c #000000008080",







|


<
<

















|







31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    TkButton info;		/* Generic button info. */
} UnixButton;

/*
 * The class function table for the button widgets.
 */

Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */


};

/*
 * The button image.
 * The header info here is ignored, it's the image that's important. The
 * colors will be applied as follows:
 *   A = Background
 *   B = Background
 *   C = 3D light
 *   D = selectColor
 *   E = 3D dark
 *   F = Background
 *   G = Indicator Color
 *   H = disabled Indicator Color
 */

/* XPM */
static char *button_images[] = {
    /* width height ncolors chars_per_pixel */
    "52 26 7 1",
    /* colors */
    "A c #808000000000",
    "B c #000080800000",
    "C c #808080800000",
    "D c #000000008080",
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    Pixmap pixmap;
    int depth;

    /*
     * Sanity check.
     */

    if (tkwin == NULL || display == NULL || d == None || bgBorder == NULL
	    || indicatorColor == NULL) {
	return;
    }

    if (disableColor == NULL) {
	disableColor = bg_brdr->bgColorPtr;
    }







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    Pixmap pixmap;
    int depth;

    /*
     * Sanity check.
     */

    if (tkwin == NULL || display == None || d == None || bgBorder == NULL
	    || indicatorColor == NULL) {
	return;
    }

    if (disableColor == NULL) {
	disableColor = bg_brdr->bgColorPtr;
    }
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    /*
     * Create the image, painting it into an XImage one pixel at a time.
     */

    for (iy=0 ; iy<dim ; iy++) {
	for (ix=0 ; ix<dim ; ix++) {
	    XPutPixel(img, ix, iy,
		    imgColors[button_images[imgstart+iy][imgsel+ix] - 'A']);
	}
    }

    /*
     * Copy onto our target drawable surface.
     */

    memset(&gcValues, 0, sizeof(gcValues));
    gcValues.background = bg_brdr->bgColorPtr->pixel;
    gcValues.graphics_exposures = False;
    copyGC = Tk_GetGC(tkwin, 0, &gcValues);

    XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0,
	    (unsigned)dim, (unsigned)dim);
    XCopyArea(display, pixmap, d, copyGC, 0, 0,
	    (unsigned)dim, (unsigned)dim, x, y);

    /*
     * Tidy up.
     */

    Tk_FreeGC(display, copyGC);
    XDestroyImage(img);







|













|

|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    /*
     * Create the image, painting it into an XImage one pixel at a time.
     */

    for (iy=0 ; iy<dim ; iy++) {
	for (ix=0 ; ix<dim ; ix++) {
	    XPutPixel(img, ix, iy,
		    imgColors[button_images[imgstart+iy][imgsel+ix] - 'A'] );
	}
    }

    /*
     * Copy onto our target drawable surface.
     */

    memset(&gcValues, 0, sizeof(gcValues));
    gcValues.background = bg_brdr->bgColorPtr->pixel;
    gcValues.graphics_exposures = False;
    copyGC = Tk_GetGC(tkwin, 0, &gcValues);

    XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0,
	    (unsigned int)dim, (unsigned int)dim);
    XCopyArea(display, pixmap, d, copyGC, 0, 0,
	    (unsigned int)dim, (unsigned int)dim, x, y);

    /*
     * Tidy up.
     */

    Tk_FreeGC(display, copyGC);
    XDestroyImage(img);
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407




408
409
410
411
412
413
414
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    TCL_UNUSED(Tk_Window))
{

    return (TkButton *)ckalloc(sizeof(UnixButton));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This function is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the button in its current mode.
 *	The REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

static void
ShiftByOffset(
    TkButton *butPtr,
    int relief,
    int *x,		/* shift this x coordinate */
    int *y,		/* shift this y coordinate */
    int width,		/* width of image/text */
    int height)		/* height of image/text */
{
    if (relief != TK_RELIEF_RAISED
	    && butPtr->type == TYPE_BUTTON
	    && !Tk_StrictMotif(butPtr->tkwin)) {
	int shiftX;
	int shiftY;

	/*
	 * This is an (unraised) button widget, so we offset the text to make
	 * the button appear to move up and down as the relief changes.
	 */

	shiftX = shiftY = (relief == TK_RELIEF_SUNKEN) ? 2 : 1;

	if (relief != TK_RELIEF_RIDGE) {
	    /*
	     * Take back one pixel if the padding is even, otherwise the
	     * content will be displayed too far right/down.
	     */

	    if ((Tk_Width(butPtr->tkwin) - width) % 2 == 0) {
		shiftX -= 1;
	    }
	    if ((Tk_Height(butPtr->tkwin) - height) % 2 == 0) {
		shiftY -= 1;
	    }
	}

	*x += shiftX;
	*y += shiftY;
    }
}

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
    int y, relief;
    Tk_Window tkwin = butPtr->tkwin;
    int width = 0, height = 0, fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;




    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0;
				/* image information that will be used to
				 * restrict disabled pixmap as well */

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {







|

>
|




















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|










>
>
>
>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350









































351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    UnixButton *butPtr = (UnixButton *) ckalloc(sizeof(UnixButton));
    return (TkButton *) butPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This function is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Commands are output to X to display the button in its current mode.
 *	The REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */










































void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    register TkButton *butPtr = (TkButton *) clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
    int y, relief;
    Tk_Window tkwin = butPtr->tkwin;
    int width = 0, height = 0, fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;
    int offset;			/* 1 means this is a button widget, so we
				 * offset the text to make the button appear
				 * to move up and down as the relief
				 * changes. */
    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0;
				/* image information that will be used to
				 * restrict disabled pixmap as well */

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
462
463
464
465
466
467
468


469
470
471
472
473
474
475
    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (butPtr->flags & SELECTED) {
	    relief = TK_RELIEF_SUNKEN;
	} else if (butPtr->overRelief != relief) {
	    relief = butPtr->offRelief;
	}
    }



    /*
     * In order to avoid screen flashes, this function redraws the button in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-screen image has
     * been cleared.
     */







>
>







424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (butPtr->flags & SELECTED) {
	    relief = TK_RELIEF_SUNKEN;
	} else if (butPtr->overRelief != relief) {
	    relief = butPtr->offRelief;
	}
    }

    offset = (butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin);

    /*
     * In order to avoid screen flashes, this function redraws the button in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-screen image has
     * been cleared.
     */
554
555
556
557
558
559
560
561










562
563
564
565
566
567
568
	    break;
	}

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y);

	x += butPtr->indicatorSpace;
	ShiftByOffset(butPtr, relief, &x, &y, width, height);










	imageXOffset += x;
	imageYOffset += y;

	if (butPtr->image != NULL) {
	    /*
	     * Do boundary clipping, so that Tk_RedrawImage is passed valid
	     * coordinates. [Bug 979239]







|
>
>
>
>
>
>
>
>
>
>







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
	    break;
	}

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y);

	x += butPtr->indicatorSpace;

	x += offset;
	y += offset;
	if (relief == TK_RELIEF_RAISED) {
	    x -= offset;
	    y -= offset;
	} else if (relief == TK_RELIEF_SUNKEN) {
	    x += offset;
	    y += offset;
	}

	imageXOffset += x;
	imageYOffset += y;

	if (butPtr->image != NULL) {
	    /*
	     * Do boundary clipping, so that Tk_RedrawImage is passed valid
	     * coordinates. [Bug 979239]
612
613
614
615
616
617
618
619









620
621
622
623
624
625
626
		butPtr->underline);
	y += fullHeight/2;
    } else {
	if (haveImage) {
	    TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		    butPtr->indicatorSpace + width, height, &x, &y);
	    x += butPtr->indicatorSpace;
	    ShiftByOffset(butPtr, relief, &x, &y, width, height);









	    imageXOffset += x;
	    imageYOffset += y;
	    if (butPtr->image != NULL) {
		/*
		 * Do boundary clipping, so that Tk_RedrawImage is passed
		 * valid coordinates. [Bug 979239]
		 */







|
>
>
>
>
>
>
>
>
>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
		butPtr->underline);
	y += fullHeight/2;
    } else {
	if (haveImage) {
	    TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		    butPtr->indicatorSpace + width, height, &x, &y);
	    x += butPtr->indicatorSpace;

	    x += offset;
	    y += offset;
	    if (relief == TK_RELIEF_RAISED) {
		x -= offset;
		y -= offset;
	    } else if (relief == TK_RELIEF_SUNKEN) {
		x += offset;
		y += offset;
	    }
	    imageXOffset += x;
	    imageYOffset += y;
	    if (butPtr->image != NULL) {
		/*
		 * Do boundary clipping, so that Tk_RedrawImage is passed
		 * valid coordinates. [Bug 979239]
		 */
665
666
667
668
669
670
671
672









673
674
675
676
677
678
679
	    y += height/2;
	} else {
 	    TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		    butPtr->indicatorSpace + butPtr->textWidth,
		    butPtr->textHeight, &x, &y);

	    x += butPtr->indicatorSpace;
	    ShiftByOffset(butPtr, relief, &x, &y, width, height);









	    Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
		    x, y, 0, -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
		    butPtr->textLayout, x, y, butPtr->underline);
	    y += butPtr->textHeight/2;
	}
    }







|
>
>
>
>
>
>
>
>
>







648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
	    y += height/2;
	} else {
 	    TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		    butPtr->indicatorSpace + butPtr->textWidth,
		    butPtr->textHeight, &x, &y);

	    x += butPtr->indicatorSpace;

	    x += offset;
	    y += offset;
	    if (relief == TK_RELIEF_RAISED) {
		x -= offset;
		y -= offset;
	    } else if (relief == TK_RELIEF_SUNKEN) {
		x += offset;
		y += offset;
	    }
	    Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
		    x, y, 0, -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
		    butPtr->textLayout, x, y, butPtr->underline);
	    y += butPtr->textHeight/2;
	}
    }
801
802
803
804
805
806
807


808
809
810
811
812
813
814
	 */

	Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,
		Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		butPtr->borderWidth, relief);
    }
    if (butPtr->highlightWidth > 0) {


	if (butPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),
		    pixmap);
	}








>
>







793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
	 */

	Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,
		Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		butPtr->borderWidth, relief);
    }
    if (butPtr->highlightWidth > 0) {
	GC gc;

	if (butPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),
		    pixmap);
	}

852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    TkButton *butPtr)	/* Button whose geometry may have changed. */
{
    int width, height, avgWidth, txtWidth, txtHeight;
    int haveImage = 0, haveText = 0;
    Tk_FontMetrics fm;

    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;








|







846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    register TkButton *butPtr)	/* Button whose geometry may have changed. */
{
    int width, height, avgWidth, txtWidth, txtHeight;
    int haveImage = 0, haveText = 0;
    Tk_FontMetrics fm;

    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;

Changes to unix/tkUnixColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tkUnixColor.c --
 *
 *	This file contains the platform specific color routines needed for X
 *	support.
 *
 * 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.
 */

#include "tkUnixInt.h"
#include "tkColor.h"

/*
 * If a colormap fills up, attempts to allocate new colors from that colormap
 * will fail. When that happens, we'll just choose the closest color from
 * those that are available in the colormap. One of the following structures
 * will be created for each "stressed" colormap to keep track of the colors












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tkUnixColor.c --
 *
 *	This file contains the platform specific color routines needed for X
 *	support.
 *
 * 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.
 */

#include "tkInt.h"
#include "tkColor.h"

/*
 * If a colormap fills up, attempts to allocate new colors from that colormap
 * will fail. When that happens, we'll just choose the closest color from
 * those that are available in the colormap. One of the following structures
 * will be created for each "stressed" colormap to keep track of the colors
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
     * color is allocated twice in different places and then freed twice, the
     * second free generates an error (this bug existed as of 10/1/92). To get
     * around this problem, ignore errors that occur during the free
     * operation.
     */

    visual = tkColPtr->visual;
    if ((visual->c_class != StaticGray) && (visual->c_class != StaticColor)
	    && (tkColPtr->color.pixel != BlackPixelOfScreen(screen))
	    && (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) {
	Tk_ErrorHandler handler;

	handler = Tk_CreateErrorHandler(DisplayOfScreen(screen),
		-1, -1, -1, NULL, NULL);
	XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,







|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
     * color is allocated twice in different places and then freed twice, the
     * second free generates an error (this bug existed as of 10/1/92). To get
     * around this problem, ignore errors that occur during the free
     * operation.
     */

    visual = tkColPtr->visual;
    if ((visual->class != StaticGray) && (visual->class != StaticColor)
	    && (tkColPtr->color.pixel != BlackPixelOfScreen(screen))
	    && (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) {
	Tk_ErrorHandler handler;

	handler = Tk_CreateErrorHandler(DisplayOfScreen(screen),
		-1, -1, -1, NULL, NULL);
	XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
     * XParseColor for non-# names: this saves a server round-trip for those
     * names.
     */

    if (*name != '#') {
	XColor screen;

	if (((*name - 'A') & 0xDF) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {
	    if (!((name[0] - 'G') & 0xDF) && !((name[1] - 'R') & 0xDF)
		    && !((name[2] - 'A') & 0xDB) && !((name[3] - 'Y') & 0xDF)
		    && !name[4]) {
		name = "#808080808080";
		goto gotWebColor;
	    } else {
		const char *p = tkWebColors[((*name - 'A') & 0x1F)];
		if (p) {
		    const char *q = name;
		    while (!((*p - *(++q)) & 0xDF)) {
			if (!*p++) {
			    name = p;
			    goto gotWebColor;
			}
		    }
		}
	}
	}
	if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return NULL;
    } else if (XAllocNamedColor(display, colormap, name, &screen, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    /*
	     * Couldn't allocate the color. Try translating the name to a
	     * color value, to see whether the problem is a bad color name or
	     * a full colormap. If the colormap is full, then pick an







|
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|

<


|







132
133
134
135
136
137
138
139






140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
     * XParseColor for non-# names: this saves a server round-trip for those
     * names.
     */

    if (*name != '#') {
	XColor screen;

	if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {






	    const char *p = tkWebColors[((*name - 'A') & 0x1f)];
	    if (p) {
		const char *q = name;
		while (!((*p - *(++q)) & 0xdf)) {
		    if (!*p++) {
			name = p;
			goto gotWebColor;
		    }
		}
	    }
	}

	if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return (TkColor *) NULL;
    } else if (XAllocNamedColor(display, colormap, name, &screen, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    /*
	     * Couldn't allocate the color. Try translating the name to a
	     * color value, to see whether the problem is a bad color name or
	     * a full colormap. If the colormap is full, then pick an
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
	if (XAllocColor(display, colormap, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    FindClosestColor(tkwin, &color, &color);
	}
    }

    tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
    tkColPtr->color = color;

    return tkColPtr;
}

/*
 *----------------------------------------------------------------------







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
	if (XAllocColor(display, colormap, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    FindClosestColor(tkwin, &color, &color);
	}
    }

    tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
    tkColPtr->color = color;

    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    Display *display = Tk_Display(tkwin);
    Colormap colormap = Tk_Colormap(tkwin);
    TkColor *tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));

    tkColPtr->color.red = colorPtr->red;
    tkColPtr->color.green = colorPtr->green;
    tkColPtr->color.blue = colorPtr->blue;
    if (XAllocColor(display, colormap, &tkColPtr->color) != 0) {
	DeleteStressedCmap(display, colormap);
    } else {







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    Display *display = Tk_Display(tkwin);
    Colormap colormap = Tk_Colormap(tkwin);
    TkColor *tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));

    tkColPtr->color.red = colorPtr->red;
    tkColPtr->color.green = colorPtr->green;
    tkColPtr->color.blue = colorPtr->blue;
    if (XAllocColor(display, colormap, &tkColPtr->color) != 0) {
	DeleteStressedCmap(display, colormap);
    } else {
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
{
    TkStressedCmap *stressPtr;
    double tmp, distance, closestDistance;
    int i, closest, numFound;
    XColor *colorPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Colormap colormap = Tk_Colormap(tkwin);
    XVisualInfo templ, *visInfoPtr;

    /*
     * Find the TkStressedCmap structure for this colormap, or create a new
     * one if needed.
     */

    for (stressPtr = dispPtr->stressPtr; ; stressPtr = stressPtr->nextPtr) {
	if (stressPtr == NULL) {
	    stressPtr = (TkStressedCmap *)ckalloc(sizeof(TkStressedCmap));
	    stressPtr->colormap = colormap;
	    templ.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));

	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &templ, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *)
		    ckalloc(stressPtr->numColors * sizeof(XColor));
	    for (i = 0; i < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);








|








|

|


|






|
|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
{
    TkStressedCmap *stressPtr;
    double tmp, distance, closestDistance;
    int i, closest, numFound;
    XColor *colorPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Colormap colormap = Tk_Colormap(tkwin);
    XVisualInfo template, *visInfoPtr;

    /*
     * Find the TkStressedCmap structure for this colormap, or create a new
     * one if needed.
     */

    for (stressPtr = dispPtr->stressPtr; ; stressPtr = stressPtr->nextPtr) {
	if (stressPtr == NULL) {
	    stressPtr = (TkStressedCmap *) ckalloc(sizeof(TkStressedCmap));
	    stressPtr->colormap = colormap;
	    template.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));

	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &template, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *) ckalloc((unsigned)
		    (stressPtr->numColors * sizeof(XColor)));
	    for (i = 0; i < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
	    prevPtr = stressPtr, stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    if (prevPtr == NULL) {
		dispPtr->stressPtr = stressPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = stressPtr->nextPtr;
	    }
	    ckfree(stressPtr->colorPtr);
	    ckfree(stressPtr);
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------







|
|







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
	    prevPtr = stressPtr, stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    if (prevPtr == NULL) {
		dispPtr->stressPtr = stressPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = stressPtr->nextPtr;
	    }
	    ckfree((char *) stressPtr->colorPtr);
	    ckfree((char *) stressPtr);
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
	    stressPtr != NULL; stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    return 1;
	}
    }
    return 0;
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<








428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
	    stressPtr != NULL; stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    return 1;
	}
    }
    return 0;
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixConfig.c.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    (void)tkwin;
    (void)dbName;
    (void)className;

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4







|
|

<
<
<
<







31
32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    CONST char *dbName,		/* The option database name. */
    CONST char *className)	/* The name of the option class. */
{




    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4

Changes to unix/tkUnixCursor.c.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
} TkUnixCursor;

/*
 * The table below is used to map from the name of a cursor to its index in
 * the official cursor font:
 */

static const struct CursorName {
    const char *name;
    unsigned int shape;
} cursorNames[] = {
    {"X_cursor",		XC_X_cursor},
    {"arrow",			XC_arrow},
    {"based_arrow_down",	XC_based_arrow_down},
    {"based_arrow_up",		XC_based_arrow_up},
    {"boat",			XC_boat},







|
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
} TkUnixCursor;

/*
 * The table below is used to map from the name of a cursor to its index in
 * the official cursor font:
 */

static struct CursorName {
    CONST char *name;
    unsigned int shape;
} cursorNames[] = {
    {"X_cursor",		XC_X_cursor},
    {"arrow",			XC_arrow},
    {"based_arrow_down",	XC_based_arrow_down},
    {"based_arrow_up",		XC_based_arrow_up},
    {"boat",			XC_boat},
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
"static unsigned char myarrow-mask_bits[] = {\n" \
"   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,\n" \
"   0xfe, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,\n" \
"   0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01};"

#endif /* DEFINE_MYARROW_CURSOR */

static const struct TkCursorName {
    const char *name;
    const char *data;
    char *mask;
} tkCursorNames[] = {
    {"none",	CURSOR_NONE_DATA,	NULL},
#ifdef DEFINE_MYARROW_CURSOR
    {"myarrow",	CURSOR_MYARROW_DATA,	CURSOR_MYARROW_MASK},
#endif /* DEFINE_MYARROW_CURSOR */
    {NULL,	NULL,			NULL}
};

/*
 * Font to use for cursors:
 */

#ifndef CURSORFONT
#define CURSORFONT "cursor"
#endif

static Cursor		CreateCursorFromTableOrFile(Tcl_Interp *interp,
			    Tk_Window tkwin, int argc, const char **argv,
			    const struct TkCursorName *tkCursorPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *
 *	Retrieve a cursor by name. Parse the cursor name into fields and







|
|
|


















|
|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
"static unsigned char myarrow-mask_bits[] = {\n" \
"   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,\n" \
"   0xfe, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,\n" \
"   0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01};"

#endif /* DEFINE_MYARROW_CURSOR */

static struct TkCursorName {
    char *name;
    char *data;
    char *mask;
} tkCursorNames[] = {
    {"none",	CURSOR_NONE_DATA,	NULL},
#ifdef DEFINE_MYARROW_CURSOR
    {"myarrow",	CURSOR_MYARROW_DATA,	CURSOR_MYARROW_MASK},
#endif /* DEFINE_MYARROW_CURSOR */
    {NULL,	NULL,			NULL}
};

/*
 * Font to use for cursors:
 */

#ifndef CURSORFONT
#define CURSORFONT "cursor"
#endif

static Cursor		CreateCursorFromTableOrFile(Tcl_Interp *interp,
			    Tk_Window tkwin, int argc, CONST char **argv,
			    struct TkCursorName *tkCursorPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *
 *	Retrieve a cursor by name. Parse the cursor name into fields and
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    TkUnixCursor *cursorPtr = NULL;
    Cursor cursor = None;
    int argc;
    const char **argv = NULL;
    Display *display = Tk_Display(tkwin);
    int inTkTable = 0;
    const struct TkCursorName *tkCursorPtr = NULL;

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badString;
    }







|


|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    TkUnixCursor *cursorPtr = NULL;
    Cursor cursor = None;
    int argc;
    CONST char **argv = NULL;
    Display *display = Tk_Display(tkwin);
    int inTkTable = 0;
    struct TkCursorName* tkCursorPtr = NULL;

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badString;
    }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	    }
	}
    }

    if ((argv[0][0] != '@') && !inTkTable) {
	XColor fg, bg;
	unsigned int maskIndex;
	const struct CursorName *namePtr;
	TkDisplay *dispPtr;

	/*
	 * The cursor is to come from the standard cursor font. If one arg, it
	 * is cursor name (use black and white for fg and bg). If two args,
	 * they are name and fg color (ignore mask). If three args, they are
	 * name, fg, bg. Some of the code below is stolen from the







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	    }
	}
    }

    if ((argv[0][0] != '@') && !inTkTable) {
	XColor fg, bg;
	unsigned int maskIndex;
	register struct CursorName *namePtr;
	TkDisplay *dispPtr;

	/*
	 * The cursor is to come from the standard cursor font. If one arg, it
	 * is cursor name (use black and white for fg and bg). If two args,
	 * they are name and fg color (ignore mask). If three args, they are
	 * name, fg, bg. Some of the code below is stolen from the
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	maskIndex = namePtr->shape + 1;
	if (argc == 1) {
	    fg.red = fg.green = fg.blue = 0;
	    bg.red = bg.green = bg.blue = 65535;
	} else {
	    if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"invalid color name \"%s\"", argv[1]));
		Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
		goto cleanup;
	    }
	    if (argc == 2) {
		bg.red = bg.green = bg.blue = 0;
		maskIndex = namePtr->shape;
	    } else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
		    &bg) == 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"invalid color name \"%s\"", argv[2]));
		Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
		goto cleanup;
	    }
	}
	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (dispPtr->cursorFont == None) {
	    dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
	    if (dispPtr->cursorFont == None) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't load cursor font", -1));
		Tcl_SetErrorCode(interp, "TK", "CURSOR", "FONT", NULL);
		goto cleanup;
	    }
	}
	cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
		dispPtr->cursorFont, namePtr->shape, maskIndex,
		&fg, &bg);
    } else {
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (!inTkTable && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    cursorPtr = NULL;
	    goto cleanup;
	}

	/*
	 * If the cursor is to be created from bitmap files, then there should
	 * be either two elements in the list (source, color) or four (source







<
|
|







<
|
|







<
|
<












|
|
<
<







271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295

296

297
298
299
300
301
302
303
304
305
306
307
308
309
310


311
312
313
314
315
316
317

	maskIndex = namePtr->shape + 1;
	if (argc == 1) {
	    fg.red = fg.green = fg.blue = 0;
	    bg.red = bg.green = bg.blue = 65535;
	} else {
	    if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) {

		Tcl_AppendResult(interp, "invalid color name \"", argv[1],
			"\"", NULL);
		goto cleanup;
	    }
	    if (argc == 2) {
		bg.red = bg.green = bg.blue = 0;
		maskIndex = namePtr->shape;
	    } else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
		    &bg) == 0) {

		Tcl_AppendResult(interp, "invalid color name \"", argv[2],
			"\"", NULL);
		goto cleanup;
	    }
	}
	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (dispPtr->cursorFont == None) {
	    dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
	    if (dispPtr->cursorFont == None) {

		Tcl_SetResult(interp, "couldn't load cursor font", TCL_STATIC);

		goto cleanup;
	    }
	}
	cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
		dispPtr->cursorFont, namePtr->shape, maskIndex,
		&fg, &bg);
    } else {
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (!inTkTable && Tcl_IsSafe(interp)) {
	    Tcl_AppendResult(interp, "can't get cursor from a file in",
		    " a safe interpreter", NULL);


	    cursorPtr = NULL;
	    goto cleanup;
	}

	/*
	 * If the cursor is to be created from bitmap files, then there should
	 * be either two elements in the list (source, color) or four (source
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
	}

	cursor = CreateCursorFromTableOrFile(interp, tkwin, argc, argv,
		tkCursorPtr);
    }

    if (cursor != None) {
	cursorPtr = (TkUnixCursor *)ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }

  cleanup:
    if (argv != NULL) {
	ckfree(argv);
    }
    return (TkCursor *) cursorPtr;

  badString:
    if (argv) {
	ckfree(argv);
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad cursor spec \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCursorFromTableOrFile --
 *
 *	Create a cursor defined in a file or the Tk static cursor table. A
 *	cursor defined in a file starts with the '@' character. This method







|






|





|

|
<


|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
	}

	cursor = CreateCursorFromTableOrFile(interp, tkwin, argc, argv,
		tkCursorPtr);
    }

    if (cursor != None) {
	cursorPtr = (TkUnixCursor *) ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }

  cleanup:
    if (argv != NULL) {
	ckfree((char *) argv);
    }
    return (TkCursor *) cursorPtr;

  badString:
    if (argv) {
	ckfree((char *) argv);
    }
    Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL);

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCursorFromTableOrFile --
 *
 *	Create a cursor defined in a file or the Tk static cursor table. A
 *	cursor defined in a file starts with the '@' character. This method
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
 */

static Cursor
CreateCursorFromTableOrFile(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    int argc,
    const char **argv,		/* Cursor spec parsed into elements. */
    const struct TkCursorName *tkCursorPtr)
				/* Non-NULL when cursor is defined in Tk
				 * table. */
{
    Cursor cursor = None;

    int width, height, maskWidth, maskHeight;
    int xHot = -1, yHot = -1;
    int dummy1, dummy2;
    XColor fg, bg;
    const char *fgColor;
    const char *bgColor;
    int inTkTable = (tkCursorPtr != NULL);

    Display *display = Tk_Display(tkwin);
    Drawable drawable = RootWindowOfScreen(Tk_Screen(tkwin));

    Pixmap source = None;
    Pixmap mask = None;







|
|









|
|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
 */

static Cursor
CreateCursorFromTableOrFile(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    int argc,
    CONST char **argv,		/* Cursor spec parsed into elements. */
    struct TkCursorName *tkCursorPtr)
				/* Non-NULL when cursor is defined in Tk
				 * table. */
{
    Cursor cursor = None;

    int width, height, maskWidth, maskHeight;
    int xHot = -1, yHot = -1;
    int dummy1, dummy2;
    XColor fg, bg;
    CONST char *fgColor;
    CONST char *bgColor;
    int inTkTable = (tkCursorPtr != NULL);

    Display *display = Tk_Display(tkwin);
    Drawable drawable = RootWindowOfScreen(Tk_Screen(tkwin));

    Pixmap source = None;
    Pixmap mask = None;
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->data, NULL,
		&width, &height, &xHot, &yHot);
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL);
	    goto cleanup;
	}

	source = XCreateBitmapFromData(display, drawable, data, width,height);
	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, &argv[0][1],
		(unsigned *) &width, (unsigned *) &height,
		&source, &xHot, &yHot) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", &argv[0][1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) {
	if (inTkTable) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad hot spot in bitmap data for \"%s\"", argv[0]));

	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad hot spot in bitmap file \"%s\"", &argv[0][1]));
	}
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "HOTSPOT", NULL);
	goto cleanup;
    }

    /*
     * Parse color names from optional fg and bg arguments
     */

    if (argc == 1) {
	fg.red = fg.green = fg.blue = 0;
	bg.red = bg.green = bg.blue = 65535;
    } else if (argc == 2) {
	fgColor = argv[1];
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", fgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
	if (inTkTable) {
	    bg.red = bg.green = bg.blue = 0;
	} else {
	    bg = fg;
	}
    } else {
	/* 3 or 4 arguments */
	if (inTkTable) {
	    fgColor = argv[1];
	    bgColor = argv[2];
	} else {
	    fgColor = argv[2];
	    bgColor = argv[3];
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", fgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", bgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
    }

    /*
     * If there is no mask data, then create the cursor now.
     */







<
|
|







|

<
|
|






<
|
>

|
|

<













<
|
|

















<
|
|



<
|
|







415
416
417
418
419
420
421

422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440

441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483

484
485
486
487
488
489
490
491
492
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->data, NULL,
		&width, &height, &xHot, &yHot);
	if (data == NULL) {

	    Tcl_AppendResult(interp, "error reading bitmap data for \"",
		    argv[0], "\"", NULL);
	    goto cleanup;
	}

	source = XCreateBitmapFromData(display, drawable, data, width,height);
	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, &argv[0][1],
		(unsigned int *) &width, (unsigned int *) &height,
		&source, &xHot, &yHot) != BitmapSuccess) {

	    Tcl_AppendResult(interp, "cleanup reading bitmap file \"",
		    &argv[0][1], "\"", NULL);
	    goto cleanup;
	}
    }

    if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) {
	if (inTkTable) {

	    Tcl_AppendResult(interp, "bad hot spot in bitmap data for \"",
		    argv[0], "\"", NULL);
	} else {
	    Tcl_AppendResult(interp, "bad hot spot in bitmap file \"",
		    &argv[0][1], "\"", NULL);
	}

	goto cleanup;
    }

    /*
     * Parse color names from optional fg and bg arguments
     */

    if (argc == 1) {
	fg.red = fg.green = fg.blue = 0;
	bg.red = bg.green = bg.blue = 65535;
    } else if (argc == 2) {
	fgColor = argv[1];
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {

	    Tcl_AppendResult(interp, "invalid color name \"",
		    fgColor, "\"", NULL);
	    goto cleanup;
	}
	if (inTkTable) {
	    bg.red = bg.green = bg.blue = 0;
	} else {
	    bg = fg;
	}
    } else {
	/* 3 or 4 arguments */
	if (inTkTable) {
	    fgColor = argv[1];
	    bgColor = argv[2];
	} else {
	    fgColor = argv[2];
	    bgColor = argv[3];
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {

	    Tcl_AppendResult(interp, "invalid color name \"",
		    fgColor, "\"", NULL);
	    goto cleanup;
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {

	    Tcl_AppendResult(interp, "invalid color name \"",
		    bgColor, "\"", NULL);
	    goto cleanup;
	}
    }

    /*
     * If there is no mask data, then create the cursor now.
     */
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->mask, NULL,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap mask data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL);
	    goto cleanup;
	}

	mask = XCreateBitmapFromData(display, drawable, data, maskWidth,
		maskHeight);

	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, argv[1],
		(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
		&mask, &dummy1, &dummy2) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", argv[1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((maskWidth != width) || (maskHeight != height)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"source and mask bitmaps have different sizes", -1));
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL);

	goto cleanup;
    }

    cursor = XCreatePixmapCursor(display, source, mask,
	    &fg, &bg, (unsigned) xHot, (unsigned) yHot);

  cleanup:







<
|
|











<
|
|





<
|
<
>







507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533

534

535
536
537
538
539
540
541
542
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->mask, NULL,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (data == NULL) {

	    Tcl_AppendResult(interp, "error reading bitmap mask data for \"",
		    argv[0], "\"", NULL);
	    goto cleanup;
	}

	mask = XCreateBitmapFromData(display, drawable, data, maskWidth,
		maskHeight);

	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, argv[1],
		(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
		&mask, &dummy1, &dummy2) != BitmapSuccess) {

	    Tcl_AppendResult(interp, "cleanup reading bitmap file \"",
		    argv[1], "\"", NULL);
	    goto cleanup;
	}
    }

    if ((maskWidth != width) || (maskHeight != height)) {

	Tcl_SetResult(interp, "source and mask bitmaps have different sizes",

		TCL_STATIC);
	goto cleanup;
    }

    cursor = XCreatePixmapCursor(display, source, mask,
	    &fg, &bg, (unsigned) xHot, (unsigned) yHot);

  cleanup:
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    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. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{
    Cursor cursor;
    Pixmap sourcePixmap, maskPixmap;







|
|







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    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. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{
    Cursor cursor;
    Pixmap sourcePixmap, maskPixmap;
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
	    (unsigned) height);
    cursor = XCreatePixmapCursor(display, sourcePixmap,
	    maskPixmap, &fgColor, &bgColor, (unsigned) xHot, (unsigned) yHot);
    Tk_FreePixmap(display, sourcePixmap);
    Tk_FreePixmap(display, maskPixmap);

    if (cursor != None) {
	cursorPtr = (TkUnixCursor *)ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }
    return (TkCursor *) cursorPtr;
}

/*







|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
	    (unsigned) height);
    cursor = XCreatePixmapCursor(display, sourcePixmap,
	    maskPixmap, &fgColor, &bgColor, (unsigned) xHot, (unsigned) yHot);
    Tk_FreePixmap(display, sourcePixmap);
    Tk_FreePixmap(display, maskPixmap);

    if (cursor != None) {
	cursorPtr = (TkUnixCursor *) ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }
    return (TkCursor *) cursorPtr;
}

/*
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr;

    XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor);

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>









619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr;

    XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor);
    Tk_FreeXId(unixCursorPtr->display, (XID) unixCursorPtr->info.cursor);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixDefault.h.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.
 * ACTIVE_BG -		Background color when widget is active.
 * SELECT_BG -		Background color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.
 * PLACEHOLDER_FG -	Foreground color for placeholder text.
 */

#define BLACK		"#000000"
#define WHITE		"#ffffff"

#define NORMAL_BG	"#d9d9d9"
#define ACTIVE_BG	"#ececec"
#define SELECT_BG	"#c3c3c3"
#define TROUGH		"#b3b3b3"
#define INDICATOR	WHITE

#define DISABLED	"#a3a3a3"
#define PLACEHOLDER_FG	"#b3b3b3"	/* grey70 */

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG







<









|
>

<







18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.
 * ACTIVE_BG -		Background color when widget is active.
 * SELECT_BG -		Background color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.

 */

#define BLACK		"#000000"
#define WHITE		"#ffffff"

#define NORMAL_BG	"#d9d9d9"
#define ACTIVE_BG	"#ececec"
#define SELECT_BG	"#c3c3c3"
#define TROUGH		"#b3b3b3"
#define CHECK_INDICATOR	WHITE
#define MENU_INDICATOR  BLACK
#define DISABLED	"#a3a3a3"


/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		BLACK
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""
#define DEF_BUTTON_PADX			"3m"
#define DEF_LABCHKRAD_PADX		"1"
#define DEF_BUTTON_PADY			"1m"
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"raised"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"







|














|

|


|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		BLACK
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		(char *) NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""
#define DEF_BUTTON_PADX			"3m"
#define DEF_LABCHKRAD_PADX		"1"
#define DEF_BUTTON_PADY			"1m"
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"raised"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		CHECK_INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		(char *) NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		(char *) NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	BLACK
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		NULL
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	BLACK
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		(char *) NULL
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#define DEF_ENTRY_INSERT_BG		BLACK
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"2"
#define DEF_ENTRY_JUSTIFY		"left"
#define DEF_ENTRY_PLACEHOLDER		""
#define DEF_ENTRY_PLACEHOLDERFG		PLACEHOLDER_FG
#define DEF_ENTRY_READONLY_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"
#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"0"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	BLACK
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			NULL
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		NULL
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG
#define DEF_FRAME_BG_IMAGE		NULL
#define DEF_FRAME_BG_MONO		WHITE
#define DEF_FRAME_BG_TILE		"0"
#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG







<
<










|

|








<

<







149
150
151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177

178
179
180
181
182
183
184
#define DEF_ENTRY_INSERT_BG		BLACK
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"2"
#define DEF_ENTRY_JUSTIFY		"left"


#define DEF_ENTRY_READONLY_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"
#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"0"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	BLACK
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			(char *) NULL
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		(char *) NULL
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG

#define DEF_FRAME_BG_MONO		WHITE

#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkDefaultFont"
#define DEF_LISTBOX_FG			BLACK
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"
#define DEF_LISTBOX_JUSTIFY		"left"
#define DEF_LISTBOX_RELIEF		"sunken"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	BLACK
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		NULL
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	NULL
#define DEF_MENU_ENTRY_ACTIVE_FG	NULL
#define DEF_MENU_ENTRY_ACCELERATOR	NULL
#define DEF_MENU_ENTRY_BG		NULL
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		NULL
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		NULL
#define DEF_MENU_ENTRY_FONT		NULL
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		NULL
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		NULL
#define DEF_MENU_ENTRY_MENU		NULL
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"1"
#define DEF_MENU_ACTIVE_FG_COLOR	BLACK
#define DEF_MENU_ACTIVE_FG_MONO		WHITE
#define DEF_MENU_ACTIVE_RELIEF		"raised"
#define DEF_MENU_BG_COLOR		NORMAL_BG
#define DEF_MENU_BG_MONO		WHITE
#define DEF_MENU_BORDER_WIDTH		"1"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"TkMenuFont"
#define DEF_MENU_FG			BLACK
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"raised"
#define DEF_MENU_SELECT_COLOR		BLACK
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_TAKE_FOCUS		"0"
#define DEF_MENU_TEAROFF		"0"
#define DEF_MENU_TEAROFF_CMD		NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */








<











|






|
|
|
|


|

|
|

|

|
|


|

|
|

|











<










|


|
|







217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkDefaultFont"
#define DEF_LISTBOX_FG			BLACK
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"

#define DEF_LISTBOX_RELIEF		"sunken"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	BLACK
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		(char *) NULL
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	(char *) NULL
#define DEF_MENU_ENTRY_ACTIVE_FG	(char *) NULL
#define DEF_MENU_ENTRY_ACCELERATOR	(char *) NULL
#define DEF_MENU_ENTRY_BG		(char *) NULL
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		(char *) NULL
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		(char *) NULL
#define DEF_MENU_ENTRY_FONT		(char *) NULL
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		(char *) NULL
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		(char *) NULL
#define DEF_MENU_ENTRY_MENU		(char *) NULL
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	(char *) NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		(char *) NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	(char *) NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT	(char *) NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"1"
#define DEF_MENU_ACTIVE_FG_COLOR	BLACK
#define DEF_MENU_ACTIVE_FG_MONO		WHITE

#define DEF_MENU_BG_COLOR		NORMAL_BG
#define DEF_MENU_BG_MONO		WHITE
#define DEF_MENU_BORDER_WIDTH		"1"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"TkMenuFont"
#define DEF_MENU_FG			BLACK
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"raised"
#define DEF_MENU_SELECT_COLOR		MENU_INDICATOR
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_TAKE_FOCUS		"0"
#define DEF_MENU_TEAROFF		"1"
#define DEF_MENU_TEAROFF_CMD		(char *) NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		BLACK
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	BLACK
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"0"
#define DEF_MENUBUTTON_JUSTIFY		"center"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"







|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		BLACK
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	BLACK
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		(char *) NULL
#define DEF_MENUBUTTON_INDICATOR	"0"
#define DEF_MENUBUTTON_JUSTIFY		"center"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"1"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:







|








|







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"1"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	        "300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		(char *) NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"sunken"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	NULL
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"11"

/*
 * Defaults for texts:
 */







|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"sunken"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	(char *) NULL
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"11"

/*
 * Defaults for texts:
 */
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
#define DEF_TEXT_HIGHLIGHT		BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH	"1"
#define DEF_TEXT_INSERT_BG		BLACK
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	SELECT_BG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	BLACK
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"raised"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		NULL
#define DEF_TEXT_UNDO			"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"

/*
 * Defaults for canvas items
 * (arcs, bitmaps, lines, polygons, rectangles, and ovals):
 */

#define DEF_CANVBMAP_FG			BLACK
#define DEF_CANVITEM_OUTLINE		BLACK

/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""

/*
 * Defaults for busy windows:
 */

#define DEF_BUSY_CURSOR			"watch"

#endif /* _TKUNIXDEFAULT */







<

|


















|
|











<
<
<
<
<
<
<
<










<
<
<
<
<
<

475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514








515
516
517
518
519
520
521
522
523
524






525
#define DEF_TEXT_HIGHLIGHT		BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH	"1"
#define DEF_TEXT_INSERT_BG		BLACK
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"

#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO    	"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	SELECT_BG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	BLACK
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"raised"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		(char *) NULL
#define DEF_TEXT_UNDO    		"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"









/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""







#endif /* _TKUNIXDEFAULT */

Changes to unix/tkUnixDialog.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 */

static int
EvalObjv(
    Tcl_Interp *interp,		/* Current interpreter. */
    char *cmdName,		/* Name of the TCL command to call */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tcl_Obj *cmdObj, **objs;
    int result;

    cmdObj = Tcl_NewStringObj(cmdName, -1);
    Tcl_IncrRefCount(cmdObj);
    objs = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc+1));
    objs[0] = cmdObj;
    memcpy(objs+1, objv, sizeof(Tcl_Obj *) * (unsigned)objc);

    result = Tcl_EvalObjv(interp, objc+1, objs, 0);

    Tcl_DecrRefCount(cmdObj);
    ckfree(objs);

    return result;
}

/*
 *----------------------------------------------------------------------
 *







|






|






|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 */

static int
EvalObjv(
    Tcl_Interp *interp,		/* Current interpreter. */
    char *cmdName,		/* Name of the TCL command to call */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Arguments. */
{
    Tcl_Obj *cmdObj, **objs;
    int result;

    cmdObj = Tcl_NewStringObj(cmdName, -1);
    Tcl_IncrRefCount(cmdObj);
    objs = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj*) * (unsigned)(objc+1));
    objs[0] = cmdObj;
    memcpy(objs+1, objv, sizeof(Tcl_Obj *) * (unsigned)objc);

    result = Tcl_EvalObjv(interp, objc+1, objs, 0);

    Tcl_DecrRefCount(cmdObj);
    ckfree((char *) objs);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::ColorDialog", objc-1, objv+1);
}

/*
 *----------------------------------------------------------------------
 *







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::ColorDialog", objc-1, objv+1);
}

/*
 *----------------------------------------------------------------------
 *
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tk_Window tkwin = clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifOpenFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::OpenFDialog", objc-1, objv+1);
    }
}







|

|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Arguments. */
{
    Tk_Window tkwin = (Tk_Window)clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifOpenFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::OpenFDialog", objc-1, objv+1);
    }
}
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tk_Window tkwin = clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifSaveFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::SaveFDialog", objc-1, objv+1);
    }
}







|

|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Arguments. */
{
    Tk_Window tkwin = (Tk_Window)clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifSaveFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::SaveFDialog", objc-1, objv+1);
    }
}
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
 */

int
Tk_MessageBoxCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::MessageBox", objc-1, objv+1);
}

#endif /* TK_OBSOLETE_UNIX_DIALOG_WRAPPERS */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|













173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
 */

int
Tk_MessageBoxCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::MessageBox", objc-1, objv+1);
}

#endif /* TK_OBSOLETE_UNIX_DIALOG_WRAPPERS */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixDraw.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * tkUnixDraw.c --
 *
 *	This file contains X specific drawing routines.
 *
 * 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.
 */

#include "tkInt.h"

#ifndef _WIN32
#include "tkUnixInt.h"
#endif

/*
 * The following structure is used to pass information to ScrollRestrictProc
 * from TkScrollWindow.
 */

typedef struct ScrollInfo {
    int done;			/* Flag is 0 until filtering is done. */
    Display *display;		/* Display to filter. */
    Window window;		/* Window to filter. */
    Region region;		/* Region into which damage is accumulated. */
    int dx, dy;			/* Amount by which window was shifted. */
} ScrollInfo;

/*
 * Forward declarations for functions declared later in this file:
 */

static Tk_RestrictProc ScrollRestrictProc;

/*
 *----------------------------------------------------------------------
 *
 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate damage













|












|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * tkUnixDraw.c --
 *
 *	This file contains X specific drawing routines.
 *
 * 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.
 */

#include "tkInt.h"

#if !defined(__WIN32__)
#include "tkUnixInt.h"
#endif

/*
 * The following structure is used to pass information to ScrollRestrictProc
 * from TkScrollWindow.
 */

typedef struct ScrollInfo {
    int done;			/* Flag is 0 until filtering is done. */
    Display *display;		/* Display to filter. */
    Window window;		/* Window to filter. */
    TkRegion region;		/* Region into which damage is accumulated. */
    int dx, dy;			/* Amount by which window was shifted. */
} ScrollInfo;

/*
 * Forward declarations for functions declared later in this file:
 */

static Tk_RestrictAction ScrollRestrictProc(ClientData arg, XEvent *eventPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate damage
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    ScrollInfo info;

    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
	    x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);

    info.done = 0;
    info.window = Tk_WindowId(tkwin);
    info.display = Tk_Display(tkwin);
    info.region = damageRgn;
    info.dx = dx;
    info.dy = dy;

    /*
     * Sync the event stream so all of the expose events will be on the Tk
     * event queue before we start filtering. This avoids busy waiting while
     * we filter events.
     */

    TkpSync(info.display);
    prevProc = Tk_RestrictEvents(ScrollRestrictProc, &info, &prevArg);

    while (!info.done) {
	Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
    }
    Tk_RestrictEvents(prevProc, prevArg, &prevArg);

    if (XEmptyRegion(damageRgn)) {
	return 0;
    } else {
	return 1;
    }
}

/*







|

|
|



















|
>



|

|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    Tk_RestrictProc *oldProc;
    ClientData oldArg, dummy;
    ScrollInfo info;

    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
	    x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);

    info.done = 0;
    info.window = Tk_WindowId(tkwin);
    info.display = Tk_Display(tkwin);
    info.region = damageRgn;
    info.dx = dx;
    info.dy = dy;

    /*
     * Sync the event stream so all of the expose events will be on the Tk
     * event queue before we start filtering. This avoids busy waiting while
     * we filter events.
     */

    TkpSync(info.display);
    oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info,
	    &oldArg);
    while (!info.done) {
	Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
    }
    Tk_RestrictEvents(oldProc, oldArg, &dummy);

    if (XEmptyRegion((Region) damageRgn)) {
	return 0;
    } else {
	return 1;
    }
}

/*
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    if (eventPtr->type == NoExpose) {
	info->done = 1;
    } else if (eventPtr->type == GraphicsExpose) {
	rect.x = eventPtr->xgraphicsexpose.x;
	rect.y = eventPtr->xgraphicsexpose.y;
	rect.width = eventPtr->xgraphicsexpose.width;
	rect.height = eventPtr->xgraphicsexpose.height;
	XUnionRectWithRegion(&rect, info->region,
		info->region);

	if (eventPtr->xgraphicsexpose.count == 0) {
	    info->done = 1;
	}
    } else if (eventPtr->type == Expose) {
	/*
	 * This case is tricky. This event was already queued before the
	 * XCopyArea was issued. If this area overlaps the area being copied,
	 * then some of the copied area may be invalid. The easiest way to
	 * handle this case is to mark both the original area and the shifted
	 * area as damaged.
	 */

	rect.x = eventPtr->xexpose.x;
	rect.y = eventPtr->xexpose.y;
	rect.width = eventPtr->xexpose.width;
	rect.height = eventPtr->xexpose.height;
	XUnionRectWithRegion(&rect, info->region,
		info->region);
	rect.x += info->dx;
	rect.y += info->dy;
	XUnionRectWithRegion(&rect, info->region,
		info->region);
    } else {
	return TK_DEFER_EVENT;
    }
    return TK_DISCARD_EVENT;
}

/*







|
|

















|
|


|
|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    if (eventPtr->type == NoExpose) {
	info->done = 1;
    } else if (eventPtr->type == GraphicsExpose) {
	rect.x = eventPtr->xgraphicsexpose.x;
	rect.y = eventPtr->xgraphicsexpose.y;
	rect.width = eventPtr->xgraphicsexpose.width;
	rect.height = eventPtr->xgraphicsexpose.height;
	XUnionRectWithRegion(&rect, (Region) info->region,
		(Region) info->region);

	if (eventPtr->xgraphicsexpose.count == 0) {
	    info->done = 1;
	}
    } else if (eventPtr->type == Expose) {
	/*
	 * This case is tricky. This event was already queued before the
	 * XCopyArea was issued. If this area overlaps the area being copied,
	 * then some of the copied area may be invalid. The easiest way to
	 * handle this case is to mark both the original area and the shifted
	 * area as damaged.
	 */

	rect.x = eventPtr->xexpose.x;
	rect.y = eventPtr->xexpose.y;
	rect.width = eventPtr->xexpose.width;
	rect.height = eventPtr->xexpose.height;
	XUnionRectWithRegion(&rect, (Region) info->region,
		(Region) info->region);
	rect.x += info->dx;
	rect.y += info->dy;
	XUnionRectWithRegion(&rect, (Region) info->region,
		(Region) info->region);
    } else {
	return TK_DEFER_EVENT;
    }
    return TK_DISCARD_EVENT;
}

/*
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;

    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrameEx(
    Tk_Window tkwin,
    Drawable drawable,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, drawable, border, highlightWidth,
	    highlightWidth, Tk_Width(tkwin) - 2*highlightWidth,
	    Tk_Height(tkwin) - 2*highlightWidth, borderWidth, relief);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<






|













|

<





|











199
200
201
202
203
204
205


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{


    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrame --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrame(
    Tk_Window tkwin,

    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, highlightWidth,
	    highlightWidth, Tk_Width(tkwin) - 2*highlightWidth,
	    Tk_Height(tkwin) - 2*highlightWidth, borderWidth, relief);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixEmbed.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkUnixEmbed.c --
 *
 *	This file contains platform-specific functions for UNIX to provide
 *	basic operations needed for application embedding (where one
 *	application can use as its main window an internal window from some
 *	other application). Also includes code to support busy windows.
 *
 * 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.
 */

#include "tkUnixInt.h"
#include "tkBusy.h"

/*
 * One of the following structures exists for each container in this
 * application. It keeps track of the container window and its associated
 * embedded window.
 */







|








<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
/*
 * tkUnixEmbed.c --
 *
 *	This file contains platform-specific functions for UNIX to provide
 *	basic operations needed for application embedding (where one
 *	application can use as its main window an internal window from some
 *	other application).
 *
 * 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.
 */

#include "tkUnixInt.h"


/*
 * One of the following structures exists for each container in this
 * application. It keeps track of the container window and its associated
 * embedded window.
 */

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
				 * in this process. Note that this is *not*
				 * the same window as wrapper: wrapper is the
				 * parent of embeddedPtr. */
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

typedef struct {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
				 * in this process. Note that this is *not*
				 * the same window as wrapper: wrapper is the
				 * parent of embeddedPtr. */
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

typedef struct ThreadSpecificData {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
    if (TkpScanWindowId(interp, string, &parent) != TCL_OK) {
	return TCL_ERROR;
    }

    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, parent);

    if (usePtr != NULL && !(usePtr->flags & TK_CONTAINER)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" doesn't have -container option set",
		usePtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL);
	return TCL_ERROR;

    }

    /*
     * Tk sets the window colormap to the screen default colormap in
     * tkWindow.c:AllocWindow. This doesn't work well for embedded windows. So
     * we override the colormap and visual settings to be the same as the
     * parent window (which is in the container app).
     */

    anyError = 0;
    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
	    EmbedErrorProc, &anyError);
    if (!XGetWindowAttributes(winPtr->display, parent, &parentAtts)) {
        anyError = 1;
    }
    XSync(winPtr->display, False);
    Tk_DeleteErrorHandler(handler);
    if (anyError) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "couldn't create child of window \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "NO_TARGET", NULL);
	}
	return TCL_ERROR;
    }
    Tk_SetWindowVisual(tkwin, parentAtts.visual, parentAtts.depth,
	    parentAtts.colormap);

    /*
     * Create an event handler to clean up the Container structure when tkwin
     * is eventually deleted.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
	    winPtr);

    /*
     * Save information about the container and the embedded window in a
     * Container structure. If there is already an existing Container
     * structure, it means that both container and embedded app. are in the
     * same process.
     */

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parent == parent) {
	    winPtr->flags |= TK_BOTH_HALVES;
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    break;
	}
    }
    if (containerPtr == NULL) {
	containerPtr = (Container *)ckalloc(sizeof(Container));
	containerPtr->parent = parent;
	containerPtr->parentRoot = parentAtts.root;
	containerPtr->parentPtr = NULL;
	containerPtr->wrapper = None;
	containerPtr->nextPtr = tsdPtr->firstContainerPtr;
	tsdPtr->firstContainerPtr = containerPtr;
    }







|













|
|
<







>
|
|
|
<
<
|
>











|







<
|
|












|

















|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    CONST char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);

	return TCL_ERROR;
    }
    if (TkpScanWindowId(interp, string, &parent) != TCL_OK) {
	return TCL_ERROR;
    }

    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, parent);
    if (usePtr != NULL) {
	if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
                    "\" doesn't have -container option set", NULL);


	    return TCL_ERROR;
	}
    }

    /*
     * Tk sets the window colormap to the screen default colormap in
     * tkWindow.c:AllocWindow. This doesn't work well for embedded windows. So
     * we override the colormap and visual settings to be the same as the
     * parent window (which is in the container app).
     */

    anyError = 0;
    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
	    EmbedErrorProc, (ClientData) &anyError);
    if (!XGetWindowAttributes(winPtr->display, parent, &parentAtts)) {
        anyError = 1;
    }
    XSync(winPtr->display, False);
    Tk_DeleteErrorHandler(handler);
    if (anyError) {
	if (interp != NULL) {

	    Tcl_AppendResult(interp, "couldn't create child of window \"",
		    string, "\"", NULL);
	}
	return TCL_ERROR;
    }
    Tk_SetWindowVisual(tkwin, parentAtts.visual, parentAtts.depth,
	    parentAtts.colormap);

    /*
     * Create an event handler to clean up the Container structure when tkwin
     * is eventually deleted.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
	    (ClientData) winPtr);

    /*
     * Save information about the container and the embedded window in a
     * Container structure. If there is already an existing Container
     * structure, it means that both container and embedded app. are in the
     * same process.
     */

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parent == parent) {
	    winPtr->flags |= TK_BOTH_HALVES;
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    break;
	}
    }
    if (containerPtr == NULL) {
	containerPtr = (Container *) ckalloc(sizeof(Container));
	containerPtr->parent = parent;
	containerPtr->parentRoot = parentAtts.root;
	containerPtr->parentPtr = NULL;
	containerPtr->wrapper = None;
	containerPtr->nextPtr = tsdPtr->firstContainerPtr;
	tsdPtr->firstContainerPtr = containerPtr;
    }
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316

    /*
     * Register the window as a container so that, for example, we can find
     * out later if the embedded app. is in the same process.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *)ckalloc(sizeof(Container));
    containerPtr->parent = Tk_WindowId(tkwin);
    containerPtr->parentRoot = RootWindowOfScreen(Tk_Screen(tkwin));
    containerPtr->parentPtr = winPtr;
    containerPtr->wrapper = None;
    containerPtr->embeddedPtr = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Request SubstructureNotify events so that we can find out when the
     * embedded application creates its window or attempts to resize it. Also
     * watch Configure events on the container so that we can resize the child
     * to match.
     */

    winPtr->atts.event_mask |= SubstructureRedirectMask|SubstructureNotifyMask;
    XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
    Tk_CreateEventHandler(tkwin,
	    SubstructureNotifyMask|SubstructureRedirectMask,
	    ContainerEventProc, winPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc,
	    containerPtr);
    Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc,
	    containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedErrorProc --
 *







|




















|

|

|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

    /*
     * Register the window as a container so that, for example, we can find
     * out later if the embedded app. is in the same process.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *) ckalloc(sizeof(Container));
    containerPtr->parent = Tk_WindowId(tkwin);
    containerPtr->parentRoot = RootWindowOfScreen(Tk_Screen(tkwin));
    containerPtr->parentPtr = winPtr;
    containerPtr->wrapper = None;
    containerPtr->embeddedPtr = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Request SubstructureNotify events so that we can find out when the
     * embedded application creates its window or attempts to resize it. Also
     * watch Configure events on the container so that we can resize the child
     * to match.
     */

    winPtr->atts.event_mask |= SubstructureRedirectMask|SubstructureNotifyMask;
    XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
    Tk_CreateEventHandler(tkwin,
	    SubstructureNotifyMask|SubstructureRedirectMask,
	    ContainerEventProc, (ClientData) winPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc,
	    (ClientData) containerPtr);
    Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc,
	    (ClientData) containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedErrorProc --
 *
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

static int
EmbedErrorProc(
    ClientData clientData,	/* Points to integer to set. */
    XErrorEvent *errEventPtr)	/* Points to information about error (not
				 * used). */
{
    int *iPtr = (int *)clientData;
    (void)errEventPtr;

    *iPtr = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------







|
<







325
326
327
328
329
330
331
332

333
334
335
336
337
338
339

static int
EmbedErrorProc(
    ClientData clientData,	/* Points to integer to set. */
    XErrorEvent *errEventPtr)	/* Points to information about error (not
				 * used). */
{
    int *iPtr = (int *) clientData;


    *iPtr = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}

/*







|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}

/*
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Ignore any X protocol errors that happen in this function (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
	    -1, -1, NULL, NULL);

    /*
     * Find the Container structure associated with the parent window.
     */

    for (containerPtr = tsdPtr->firstContainerPtr;
	    containerPtr->parent != eventPtr->xmaprequest.parent;







|












|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Ignore any X protocol errors that happen in this function (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
	    -1, -1, NULL, (ClientData) NULL);

    /*
     * Find the Container structure associated with the parent window.
     */

    for (containerPtr = tsdPtr->firstContainerPtr;
	    containerPtr->parent != eventPtr->xmaprequest.parent;
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
 */

static void
EmbedStructureProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {
        /*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != NULL) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->wrapper != None) {

	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    XMoveResizeWindow(eventPtr->xconfigure.display,
		    containerPtr->wrapper, 0, 0,
		    (unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window) containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {







|



<
<
<
<
<
<
<

<






|







492
493
494
495
496
497
498
499
500
501
502







503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
 */

static void
EmbedStructureProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *) clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {







	if (containerPtr->wrapper != None) {

	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, (ClientData) NULL);
	    XMoveResizeWindow(eventPtr->xconfigure.display,
		    containerPtr->wrapper, 0, 0,
		    (unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window) containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;
    Display *display;

    display = Tk_Display(containerPtr->parentPtr);
    if (eventPtr->type == FocusIn) {
	/*
	 * The focus just arrived at the container. Change the X focus to move
	 * it to the embedded application, if there is one. Ignore X errors
	 * that occur during this operation (it's possible that the new focus
	 * window isn't mapped).
	 */

	if (containerPtr->wrapper != None) {
	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    XSetInputFocus(display, containerPtr->wrapper, RevertToParent,
		    CurrentTime);
	    Tk_DeleteErrorHandler(errHandler);
	}
    }
}








|














|







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *) clientData;
    Tk_ErrorHandler errHandler;
    Display *display;

    display = Tk_Display(containerPtr->parentPtr);
    if (eventPtr->type == FocusIn) {
	/*
	 * The focus just arrived at the container. Change the X focus to move
	 * it to the embedded application, if there is one. Ignore X errors
	 * that occur during this operation (it's possible that the new focus
	 * window isn't mapped).
	 */

	if (containerPtr->wrapper != None) {
	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, (ClientData) NULL);
	    XSetInputFocus(display, containerPtr->wrapper, RevertToParent,
		    CurrentTime);
	    Tk_DeleteErrorHandler(errHandler);
	}
    }
}

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    if ((objc > 1) && (strcmp(Tcl_GetString(objv[1]), "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);
    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr != NULL) {
	    embeddedInterp = containerPtr->embeddedPtr->mainPtr->interp;
	}
	if (containerPtr->parentPtr != NULL) {
	    parentInterp = containerPtr->parentPtr->mainPtr->interp;
	}
	if (embeddedInterp != interp && parentInterp != interp) {
	    continue;
	}
	Tcl_DStringStartSublist(&dString);
	/* Parent id */
	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Parent pathName */
	if (containerPtr->parentPtr == NULL ||
	    parentInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}
        /* Wrapper */
	if (containerPtr->wrapper == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->wrapper);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Embedded window pathName */
	if (containerPtr->embeddedPtr == NULL ||
	    embeddedInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->embeddedPtr->pathName);
	}
	Tcl_DStringEndSublist(&dString);
    }







|

|
|





<


<

|







<
<
<
<
<
<
<
<
<

<



|




<
|
<





<



|




<
|
<







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872

873
874

875
876
877
878
879
880
881
882
883









884

885
886
887
888
889
890
891
892

893

894
895
896
897
898

899
900
901
902
903
904
905
906

907

908
909
910
911
912
913
914
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    CONST char **argv)		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if ((argc > 1) && (strcmp(argv[1], "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);
    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {









	Tcl_DStringStartSublist(&dString);

	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%x", (int) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	if (containerPtr->parentPtr == NULL) {

	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}

	if (containerPtr->wrapper == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%x", (int) containerPtr->wrapper);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	if (containerPtr->embeddedPtr == NULL) {

	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->embeddedPtr->pathName);
	}
	Tcl_DStringEndSublist(&dString);
    }
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkUnixContainerId --







|







967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree((char *) containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkUnixContainerId --
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parent;
	}
    }
    Tcl_Panic("TkUnixContainerId couldn't find window");
    return None;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpShowBusyWindow --
 *
 *	Makes a busy window "appear".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arranges for the busy window to start intercepting events and the
 *	cursor to change to the configured "hey, I'm busy!" setting.
 *
 *----------------------------------------------------------------------
 */

void
TkpShowBusyWindow(
    TkBusy busy)
{
    Busy *busyPtr = (Busy *) busy;

    if (busyPtr->tkBusy != NULL) {
	Tk_MapWindow(busyPtr->tkBusy);

	/*
	 * Always raise the busy window just in case new sibling windows have
	 * been created in the meantime. Can't use Tk_RestackWindow because it
	 * doesn't work under Win32.
	 */

	XRaiseWindow(Tk_Display(busyPtr->tkBusy),
		Tk_WindowId(busyPtr->tkBusy));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpHideBusyWindow --
 *
 *	Makes a busy window "disappear".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arranges for the busy window to stop intercepting events, and the
 *	cursor to change back to its normal setting.
 *
 *----------------------------------------------------------------------
 */

void
TkpHideBusyWindow(
    TkBusy busy)
{
    Busy *busyPtr = (Busy *) busy;

    if (busyPtr->tkBusy != NULL) {
	Tk_UnmapWindow(busyPtr->tkBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeTransparentWindowExist --
 *
 *	Construct the platform-specific resources for a transparent window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Moves the specified window in the stacking order.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent)		/* Parent window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    long int mask = CWDontPropagate | CWEventMask;

    /*
     * Ignore the important events while the window is mapped.
     */

#define USER_EVENTS \
	(EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | \
	ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
#define PROP_EVENTS \
	(KeyPressMask | KeyReleaseMask | ButtonPressMask | \
	ButtonReleaseMask | PointerMotionMask)

    winPtr->atts.do_not_propagate_mask = PROP_EVENTS;
    winPtr->atts.event_mask = USER_EVENTS;
    winPtr->changes.border_width = 0;
    winPtr->depth = 0;

    winPtr->window = XCreateWindow(winPtr->display, parent,
	    winPtr->changes.x, winPtr->changes.y,
	    (unsigned) winPtr->changes.width,		/* width */
	    (unsigned) winPtr->changes.height,		/* height */
	    (unsigned) winPtr->changes.border_width,	/* border_width */
	    winPtr->depth, InputOnly, winPtr->visual, mask, &winPtr->atts);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateBusy --
 *
 *	Construct the platform-specific parts of a busy window. Note that this
 *	postpones the actual creation of the window resource until later.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets up part of the busy window structure.
 *
 *----------------------------------------------------------------------
 */

void
TkpCreateBusy(
    Tk_FakeWin *winPtr,
    Tk_Window tkRef,
    Window *parentPtr,
    Tk_Window tkParent,
    TkBusy busy)
{
    Window root, parent, *dummy;
    unsigned int count;
    (void)busy;

    if (winPtr->flags & TK_REPARENTED) {
	/*
	 * This works around a bug in the implementation of menubars for
	 * non-MacIntosh window systems (Win32 and X11). Tk doesn't reset the
	 * pointers to the parent window when the menu is reparented (since
	 * winPtr->parentPtr points to the wrong window). We get around this
	 * by determining the parent via the native API calls.
	 */

	if (XQueryTree(Tk_Display(tkRef), Tk_WindowId(tkRef), &root,
		&parent, &dummy, &count) > 0) {
	    XFree(dummy);
	    *parentPtr = parent;
	} else {
	    *parentPtr = None;
	}
    } else {
	*parentPtr = Tk_WindowId(tkParent);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1006
1007
1008
1009
1010
1011
1012



































































































































































1013
1014
1015
1016
1017
1018
1019
1020
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parent;
	}
    }
    Tcl_Panic("TkUnixContainerId couldn't find window");
    return None;
}




































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixEvent.c.

8
9
10
11
12
13
14
15
16
17

18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include <signal.h>
#undef register /* Keyword "register" is used in XKBlib.h, so don't try tricky things here */
#define XkbOpenDisplay XkbOpenDisplay_ /* Move out of the way, conflicting definitions */
#include <X11/XKBlib.h>

#undef XkbOpenDisplay


/*
 * The following static indicates whether this module has been initialized in
 * the current thread.
 */

typedef struct {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for functions that are referenced only in this file:
 */

static void		DisplayCheckProc(ClientData clientData, int flags);
static void		DisplayExitHandler(ClientData clientData);
static void		DisplayFileProc(ClientData clientData, int flags);
static void		DisplaySetupProc(ClientData clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
static void		InstantiateIMCallback(Display *, XPointer client_data, XPointer call_data);
static void		DestroyIMCallback(XIM im, XPointer client_data, XPointer call_data);
static void		OpenIM(TkDisplay *dispPtr);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkCreateXEventSource --







|
<
|
>
|
>






|














<
<







8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46
47
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include <signal.h>
#ifdef HAVE_XKBKEYCODETOKEYSYM

#  include <X11/XKBlib.h>
#else
#  define XkbOpenDisplay(D,V,E,M,m,R) ((V),(E),(M),(m),(R),(NULL))
#endif

/*
 * The following static indicates whether this module has been initialized in
 * the current thread.
 */

typedef struct ThreadSpecificData {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for functions that are referenced only in this file:
 */

static void		DisplayCheckProc(ClientData clientData, int flags);
static void		DisplayExitHandler(ClientData clientData);
static void		DisplayFileProc(ClientData clientData, int flags);
static void		DisplaySetupProc(ClientData clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS


static void		OpenIM(TkDisplay *dispPtr);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkCreateXEventSource --
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayExitHandler(
    ClientData dummy)	/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------







|



<







86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayExitHandler(
    ClientData clientData)	/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158


159
160
161









162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
 *	Opens a display.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    const char *displayNameStr)
{
    TkDisplay *dispPtr;
    Display *display;
    int event = 0;
    int error = 0;
    int major = 1;
    int minor = 0;
    int reason = 0;
    /* Disabled, until we have a better test. See [Bug 3613668] */
#if 0
    static int xinited = 0;
    static Tcl_Mutex xinitMutex = NULL;

    if (!xinited) {
	Tcl_MutexLock(&xinitMutex);
	if (!xinited) {
	    /* Necessary for threaded apps, of no consequence otherwise  */
	    /* need only be called once, but must be called before *any* */
	    /* Xlib call is made. If xinitMutex is still NULL after the  */
	    /* Tcl_MutexLock call, Tcl was compiled without threads so   */
	    /* we cannot use XInitThreads() either.                      */
	    if (xinitMutex != NULL){
		XInitThreads();
	    }
	    xinited = 1;
	}
	Tcl_MutexUnlock(&xinitMutex);
    }
#endif

    /*
    ** Bug [3607830]: Before using Xkb, it must be initialized and confirmed
    **                that the server supports it.  The XkbOpenDisplay call
    **                will perform this check and return NULL if the extension
    **                is not supported.


    */
    display = XkbOpenDisplay(displayNameStr, &event, &error, &major,
	    &minor, &reason);










    if (display == NULL) {
	return NULL;
    }
    dispPtr = (TkDisplay *)ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;

#ifdef TK_USE_INPUT_METHODS
    OpenIM(dispPtr);
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);

    /*
     * Observed weird WidthMMOfScreen() in X on Wayland on a
     * Fedora 30/i386 running in a VM. Fallback to 75 dpi,
     * otherwise many other strange things may happen later.
     * See: [https://core.tcl-lang.org/tk/tktview?name=a01b6f7227]
     */
    if (WidthMMOfScreen(DefaultScreenOfDisplay(display)) <= 0) {
	int mm;

	mm = WidthOfScreen(DefaultScreenOfDisplay(display)) * (25.4 / 75.0);
	WidthMMOfScreen(DefaultScreenOfDisplay(display)) = mm;
    }
    if (HeightMMOfScreen(DefaultScreenOfDisplay(display)) <= 0) {
	int mm;

	mm = HeightOfScreen(DefaultScreenOfDisplay(display)) * (25.4 / 75.0);
	HeightMMOfScreen(DefaultScreenOfDisplay(display)) = mm;
    }

    /*
     * Key map info must be available immediately, because of "send event".
     */
    TkpInitKeymapInfo(dispPtr);

    return dispPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --







|








<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<


|


>
>

|

>
>
>
>
>
>
>
>
>




|


>


<
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129




130










131






132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160


161
162
163

























164
165
166
167
168
169
170
 *	Opens a display.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    CONST char *displayNameStr)
{
    TkDisplay *dispPtr;
    Display *display;
    int event = 0;
    int error = 0;
    int major = 1;
    int minor = 0;
    int reason = 0;




    unsigned int use_xkb = 0;

















    /*
    ** Bug [3607830]: Before using Xkb, it must be initialized and confirmed
    **                that the serve supports it.  The XkbOpenDisplay call
    **                will perform this check and return NULL if the extension
    **                is not supported.
    **
    ** Work around un-const-ified Xkb headers using (char *) cast.
    */
    display = XkbOpenDisplay((char *)displayNameStr, &event, &error, &major,
	    &minor, &reason);

    if (display == NULL) {
	/*fprintf(stderr,"event=%d error=%d major=%d minor=%d reason=%d\nDisabling xkb\n",
	event, error, major, minor, reason);*/
	display  = XOpenDisplay(displayNameStr);
    } else {
	use_xkb = TK_DISPLAY_USE_XKB;
	/*fprintf(stderr, "Using xkb %d.%d\n", major, minor);*/
    }

    if (display == NULL) {
	return NULL;
    }
    dispPtr = (TkDisplay *) ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
    dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
    OpenIM(dispPtr);


#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, (ClientData) dispPtr);

























    return dispPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
218
219
220
221
222
223
224


225
226
227
228
229
230
231
 */

void
TkpCloseDisplay(
    TkDisplay *dispPtr)
{
    TkSendCleanup(dispPtr);



    TkWmCleanup(dispPtr);

#ifdef TK_USE_INPUT_METHODS
    if (dispPtr->inputXfs) {
	XFreeFontSet(dispPtr->display, dispPtr->inputXfs);
    }







>
>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
 */

void
TkpCloseDisplay(
    TkDisplay *dispPtr)
{
    TkSendCleanup(dispPtr);

    TkFreeXId(dispPtr);

    TkWmCleanup(dispPtr);

#ifdef TK_USE_INPUT_METHODS
    if (dispPtr->inputXfs) {
	XFreeFontSet(dispPtr->display, dispPtr->inputXfs);
    }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
    if (dispPtr->clipWindow != NULL) {
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->applicationAtom);
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->windowAtom);

	Tk_DestroyWindow(dispPtr->clipWindow);
	Tcl_Release(dispPtr->clipWindow);
	dispPtr->clipWindow = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
    if (dispPtr->clipWindow != NULL) {
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->applicationAtom);
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->windowAtom);

	Tk_DestroyWindow(dispPtr->clipWindow);
	Tcl_Release((ClientData) dispPtr->clipWindow);
	dispPtr->clipWindow = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
 *	Tcl even if there is no more data on the X connection.
 *
 *----------------------------------------------------------------------
 */

static void
DisplaySetupProc(
    ClientData dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    static Tcl_Time blockTime = { 0, 0 };
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {







|




<







259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
 *	Tcl even if there is no more data on the X connection.
 *
 *----------------------------------------------------------------------
 */

static void
DisplaySetupProc(
    ClientData clientData,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    static Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);
	if (event.type > MappingNotify) {
	    continue;
	}
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
		} else if (dispPtr->display == event.x.xany.display) {
		    if (dispPtr->focusPtr != NULL) {







<
<
<







325
326
327
328
329
330
331



332
333
334
335
336
337
338
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);



	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
		} else if (dispPtr->display == event.x.xany.display) {
		    if (dispPtr->focusPtr != NULL) {
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
 *	Moves queued events onto the Tcl event queue.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCheckProc(
    ClientData dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {







|



<







388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
 *	Moves queued events onto the Tcl event queue.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCheckProc(
    ClientData clientData,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;


    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
    }

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 */

static void
DisplayFileProc(
    ClientData clientData,	/* The display pointer. */
    int flags)			/* Should be TCL_READABLE. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    Display *display = dispPtr->display;
    int numFound;
    (void)flags;

    XFlush(display);
    numFound = XEventsQueued(display, QueuedAfterReading);
    if (numFound == 0) {
	/*
	 * Things are very tricky if there aren't any events readable at this
	 * point (after all, there was supposedly data available on the







|


<







426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
 */

static void
DisplayFileProc(
    ClientData clientData,	/* The display pointer. */
    int flags)			/* Should be TCL_READABLE. */
{
    TkDisplay *dispPtr = (TkDisplay *) clientData;
    Display *display = dispPtr->display;
    int numFound;


    XFlush(display);
    numFound = XEventsQueued(display, QueuedAfterReading);
    if (numFound == 0) {
	/*
	 * Things are very tricky if there aren't any events readable at this
	 * point (after all, there was supposedly data available on the
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) {
	    DisplayFileProc(dispPtr, TCL_READABLE);
	}
    }
    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*







|







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) {
	    DisplayFileProc((ClientData)dispPtr, TCL_READABLE);
	}
    }
    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
    /*
     * Transfer events from the X event queue to the Tk event queue.
     */

    TransferXEventsToTcl(display);
}
#ifdef TK_USE_INPUT_METHODS

static void
InstantiateIMCallback(
    Display      *display,
    XPointer     client_data,
    XPointer     call_data)
{
    TkDisplay    *dispPtr;
    (void)display;
    (void)call_data;

    dispPtr = (TkDisplay *) client_data;
    OpenIM(dispPtr);
    XUnregisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
}

static void
DestroyIMCallback(
    XIM         im,
    XPointer    client_data,
    XPointer    call_data)
{
    TkDisplay   *dispPtr;
    (void)im;
    (void)call_data;

    dispPtr = (TkDisplay *) client_data;
    dispPtr->inputMethod = NULL;
    ++dispPtr->ximGeneration;
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
}

/*
 *--------------------------------------------------------------
 *
 * OpenIM --
 *
 *	Tries to open an X input method associated with the given display.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







631
632
633
634
635
636
637

































638
639
640
641
642
643
644
    /*
     * Transfer events from the X event queue to the Tk event queue.
     */

    TransferXEventsToTcl(display);
}
#ifdef TK_USE_INPUT_METHODS


































/*
 *--------------------------------------------------------------
 *
 * OpenIM --
 *
 *	Tries to open an X input method associated with the given display.
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;

    if (XSetLocaleModifiers("") == NULL) {
	return;
    }

    ++dispPtr->ximGeneration;
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }

    /* Require X11R6 */
    {
	XIMCallback destroy_cb;

	destroy_cb.callback = DestroyIMCallback;
	destroy_cb.client_data = (XPointer) dispPtr;
	if (XSetIMValues(dispPtr->inputMethod, XNDestroyCallback,
		&destroy_cb, NULL))
	    goto error;
    }

    if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
	    NULL) != NULL) || (stylePtr == NULL)) {
	goto error;
    }

    /*
     * Select the best input style supported by both the IM and Tk.







<





<
<
<
<
<
<
<
<
<
<
<







661
662
663
664
665
666
667

668
669
670
671
672











673
674
675
676
677
678
679
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;

    if (XSetLocaleModifiers("") == NULL) {
	return;
    }


    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }












    if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
	    NULL) != NULL) || (stylePtr == NULL)) {
	goto error;
    }

    /*
     * Select the best input style supported by both the IM and Tk.
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832

    return;

error:
    if (dispPtr->inputMethod) {
	XCloseIM(dispPtr->inputMethod);
	dispPtr->inputMethod = NULL;
	++dispPtr->ximGeneration;
    }
}
#endif /* TK_USE_INPUT_METHODS */

void
TkpWarpPointer(
    TkDisplay *dispPtr)
{
    Window w;			/* Which window to warp relative to. */

    if (dispPtr->warpWindow != NULL) {
	w = Tk_WindowId(dispPtr->warpWindow);
    } else {
	w = RootWindow(dispPtr->display,
		Tk_ScreenNumber(dispPtr->warpMainwin));
    }
    XWarpPointer(dispPtr->display, None, w, 0, 0, 0, 0,
	    (int) dispPtr->warpX, (int) dispPtr->warpY);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








712
713
714
715
716
717
718

719
720
721
















722
723
724
725
726
727
728
729

    return;

error:
    if (dispPtr->inputMethod) {
	XCloseIM(dispPtr->inputMethod);
	dispPtr->inputMethod = NULL;

    }
}
#endif /* TK_USE_INPUT_METHODS */

















/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixFont.c.

8
9
10
11
12
13
14


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkFont.h"



/*
 * The preferred font encodings.
 */

static const char encodingList[][10] = {
    "iso8859-1", "jis0208", "jis0212"
};

/*
 * The following structure represents a font family. It is assumed that all
 * screen fonts constructed from the same "font family" share certain
 * properties; all screen fonts with the same "font family" point to a shared
 * instance of this structure. The most important shared property is the
 * character existence metrics, used to determine if a screen font can display
 * a given Unicode character.
 *
 * Under Unix, there are three attributes that uniquely identify a "font
 * family": the foundry, face name, and charset.
 */

#define FONTMAP_SHIFT		10


#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)
#define FONTMAP_NUMCHARS	0x40000
#define FONTMAP_PAGES		(FONTMAP_NUMCHARS / FONTMAP_BITSPERPAGE)

typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    size_t refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */
    /*
     * Key.
     */

    Tk_Uid foundry;		/* Foundry key for this FontFamily. */
    Tk_Uid faceName;		/* Face name key for this FontFamily. */
    Tcl_Encoding encoding;	/* Encoding key for this FontFamily. */

    /*
     * Derived properties.
     */

    int isTwoByteFont;		/* 1 if this is a double-byte font, 0
				 * otherwise. */
    char *fontMap[FONTMAP_PAGES];
				/* Two-level sparse table used to determine
				 * quickly if the specified character exists.
				 * As characters are encountered, more pages
				 * in this table are dynamically allocated. The
				 * contents of each page is a bitmask
				 * consisting of FONTMAP_BITSPERPAGE bits,
				 * representing whether this font can be used
				 * to display the given character at the
				 * corresponding bit position. The high bits
				 * of the character are used to pick which
				 * page of the table is used. */







>
>





|
|
















>

<
<



|




















|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkFont.h"
#include <netinet/in.h>		/* for htons() prototype */
#include <arpa/inet.h>		/* inet_ntoa() */

/*
 * The preferred font encodings.
 */

static CONST char *encodingList[] = {
    "iso8859-1", "jis0208", "jis0212", NULL
};

/*
 * The following structure represents a font family. It is assumed that all
 * screen fonts constructed from the same "font family" share certain
 * properties; all screen fonts with the same "font family" point to a shared
 * instance of this structure. The most important shared property is the
 * character existence metrics, used to determine if a screen font can display
 * a given Unicode character.
 *
 * Under Unix, there are three attributes that uniquely identify a "font
 * family": the foundry, face name, and charset.
 */

#define FONTMAP_SHIFT		10

#define FONTMAP_PAGES		(1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT))
#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)



typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    int refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */
    /*
     * Key.
     */

    Tk_Uid foundry;		/* Foundry key for this FontFamily. */
    Tk_Uid faceName;		/* Face name key for this FontFamily. */
    Tcl_Encoding encoding;	/* Encoding key for this FontFamily. */

    /*
     * Derived properties.
     */

    int isTwoByteFont;		/* 1 if this is a double-byte font, 0
				 * otherwise. */
    char *fontMap[FONTMAP_PAGES];
				/* Two-level sparse table used to determine
				 * quickly if the specified character exists.
				 * As characters are encountered, more pages
				 * in this table are dynamically alloced. The
				 * contents of each page is a bitmask
				 * consisting of FONTMAP_BITSPERPAGE bits,
				 * representing whether this font can be used
				 * to display the given character at the
				 * corresponding bit position. The high bits
				 * of the character are used to pick which
				 * page of the table is used. */
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187






188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
 * The following structure and definition is used to keep track of the
 * alternative names for various encodings. Asking for an encoding that
 * matches one of the alias patterns will result in actually getting the
 * encoding by its real name.
 */

typedef struct EncodingAlias {
    const char *realName;	/* The real name of the encoding to load if
				 * the provided name matched the pattern. */
    const char *aliasPattern;	/* Pattern for encoding name, of the form that
				 * is acceptable to Tcl_StringMatch. */
} EncodingAlias;

/*
 * Just some utility structures used for passing around values in helper
 * functions.
 */

typedef struct FontAttributes {
    TkFontAttributes fa;
    TkXLFDAttributes xa;
} FontAttributes;

typedef struct {
    FontFamily *fontFamilyList; /* The list of font families that are
				 * currently loaded. As screen fonts are
				 * loaded, this list grows to hold information
				 * about what characters exist in each font
				 * family. */
    FontFamily controlFamily;	/* FontFamily used to handle control character
				 * expansions. The encoding of this FontFamily
				 * converts UTF-8 to backslashed escape
				 * sequences. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The set of builtin encoding alises to convert the XLFD names for the
 * encodings into the names expected by the Tcl encoding package.
 */

static const EncodingAlias encodingAliases[] = {
    {"gb2312-raw",	"gb2312*"},
    {"big5",		"big5*"},
    {"cns11643-1",	"cns11643*-1"},
    {"cns11643-1",	"cns11643*.1-0"},
    {"cns11643-2",	"cns11643*-2"},
    {"cns11643-2",	"cns11643*.2-0"},
    {"jis0201",		"jisx0201*"},
    {"jis0201",		"jisx0202*"},
    {"jis0208",		"jisc6226*"},
    {"jis0208",		"jisx0208*"},
    {"jis0212",		"jisx0212*"},
    {"tis620",		"tis620*"},
    {"ksc5601",		"ksc5601*"},
    {"dingbats",	"*dingbats"},






    {"ucs-2be",		"iso10646-1"},

    {NULL,		NULL}
};

/*
 * Functions used only in this file.
 */

static void		FontPkgCleanup(void *clientData);
static FontFamily *	AllocFontFamily(Display *display,
			    XFontStruct *fontStructPtr, int base);
static SubFont *	CanUseFallback(UnixFont *fontPtr,
			    const char *fallbackName, int ch,
			    SubFont **fixSubFontPtrPtr);
static SubFont *	CanUseFallbackWithAliases(UnixFont *fontPtr,
			    const char *fallbackName, int ch,
			    Tcl_DString *nameTriedPtr,
			    SubFont **fixSubFontPtrPtr);
static int		ControlUtfProc(void *clientData, const char *src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
static XFontStruct *	CreateClosestFont(Tk_Window tkwin,
			    const TkFontAttributes *faPtr,
			    const TkXLFDAttributes *xaPtr);
static SubFont *	FindSubFontForChar(UnixFont *fontPtr, int ch,
			    SubFont **fixSubFontPtrPtr);
static void		FontMapInsert(SubFont *subFontPtr, int ch);
static void		FontMapLoadPage(SubFont *subFontPtr, int row);
static int		FontMapLookup(SubFont *subFontPtr, int ch);
static void		FreeFontFamily(FontFamily *afPtr);
static const char *	GetEncodingAlias(const char *name);
static int		GetFontAttributes(Display *display,
			    XFontStruct *fontStructPtr, FontAttributes *faPtr);
static XFontStruct *	GetScreenFont(Display *display,
			    FontAttributes *wantPtr, char **nameList,
			    int bestIdx[], unsigned bestScore[]);
static XFontStruct *	GetSystemFont(Display *display);
static int		IdentifySymbolEncodings(FontAttributes *faPtr);
static void		InitFont(Tk_Window tkwin, XFontStruct *fontStructPtr,
			    UnixFont *fontPtr);
static void		InitSubFont(Display *display,
			    XFontStruct *fontStructPtr, int base,
			    SubFont *subFontPtr);
static char **		ListFonts(Display *display, const char *faceName,
			    int *numNamesPtr);
static char **		ListFontOrAlias(Display *display, const char*faceName,
			    int *numNamesPtr);
static unsigned		RankAttributes(FontAttributes *wantPtr,
			    FontAttributes *gotPtr);
static void		ReleaseFont(UnixFont *fontPtr);
static void		ReleaseSubFont(Display *display, SubFont *subFontPtr);
static int		SeenName(const char *name, Tcl_DString *dsPtr);

static int		Ucs2beToUtfProc(void *clientData, const char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
static int		UtfToUcs2beProc(void *clientData, const char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);


/*
 *-------------------------------------------------------------------------
 *
 * FontPkgCleanup --
 *
 *	This function is called when an application is created. It initializes







|

|













|

















|














>
>
>
>
>
>

>







|



|


|


|




|
|






|




|







|

|

|



|
>
|



|



>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
 * The following structure and definition is used to keep track of the
 * alternative names for various encodings. Asking for an encoding that
 * matches one of the alias patterns will result in actually getting the
 * encoding by its real name.
 */

typedef struct EncodingAlias {
    char *realName;		/* The real name of the encoding to load if
				 * the provided name matched the pattern. */
    char *aliasPattern;		/* Pattern for encoding name, of the form that
				 * is acceptable to Tcl_StringMatch. */
} EncodingAlias;

/*
 * Just some utility structures used for passing around values in helper
 * functions.
 */

typedef struct FontAttributes {
    TkFontAttributes fa;
    TkXLFDAttributes xa;
} FontAttributes;

typedef struct ThreadSpecificData {
    FontFamily *fontFamilyList; /* The list of font families that are
				 * currently loaded. As screen fonts are
				 * loaded, this list grows to hold information
				 * about what characters exist in each font
				 * family. */
    FontFamily controlFamily;	/* FontFamily used to handle control character
				 * expansions. The encoding of this FontFamily
				 * converts UTF-8 to backslashed escape
				 * sequences. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The set of builtin encoding alises to convert the XLFD names for the
 * encodings into the names expected by the Tcl encoding package.
 */

static EncodingAlias encodingAliases[] = {
    {"gb2312-raw",	"gb2312*"},
    {"big5",		"big5*"},
    {"cns11643-1",	"cns11643*-1"},
    {"cns11643-1",	"cns11643*.1-0"},
    {"cns11643-2",	"cns11643*-2"},
    {"cns11643-2",	"cns11643*.2-0"},
    {"jis0201",		"jisx0201*"},
    {"jis0201",		"jisx0202*"},
    {"jis0208",		"jisc6226*"},
    {"jis0208",		"jisx0208*"},
    {"jis0212",		"jisx0212*"},
    {"tis620",		"tis620*"},
    {"ksc5601",		"ksc5601*"},
    {"dingbats",	"*dingbats"},
#ifdef WORDS_BIGENDIAN
    {"unicode",		"iso10646-1"},
#else
    /*
     * ucs-2be is needed if native order isn't BE.
     */
    {"ucs-2be",		"iso10646-1"},
#endif
    {NULL,		NULL}
};

/*
 * Functions used only in this file.
 */

static void		FontPkgCleanup(ClientData clientData);
static FontFamily *	AllocFontFamily(Display *display,
			    XFontStruct *fontStructPtr, int base);
static SubFont *	CanUseFallback(UnixFont *fontPtr,
			    CONST char *fallbackName, int ch,
			    SubFont **fixSubFontPtrPtr);
static SubFont *	CanUseFallbackWithAliases(UnixFont *fontPtr,
			    char *fallbackName, int ch,
			    Tcl_DString *nameTriedPtr,
			    SubFont **fixSubFontPtrPtr);
static int		ControlUtfProc(ClientData clientData, CONST char *src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
static XFontStruct *	CreateClosestFont(Tk_Window tkwin,
			    CONST TkFontAttributes *faPtr,
			    CONST TkXLFDAttributes *xaPtr);
static SubFont *	FindSubFontForChar(UnixFont *fontPtr, int ch,
			    SubFont **fixSubFontPtrPtr);
static void		FontMapInsert(SubFont *subFontPtr, int ch);
static void		FontMapLoadPage(SubFont *subFontPtr, int row);
static int		FontMapLookup(SubFont *subFontPtr, int ch);
static void		FreeFontFamily(FontFamily *afPtr);
static CONST char *	GetEncodingAlias(CONST char *name);
static int		GetFontAttributes(Display *display,
			    XFontStruct *fontStructPtr, FontAttributes *faPtr);
static XFontStruct *	GetScreenFont(Display *display,
			    FontAttributes *wantPtr, char **nameList,
			    int bestIdx[], unsigned int bestScore[]);
static XFontStruct *	GetSystemFont(Display *display);
static int		IdentifySymbolEncodings(FontAttributes *faPtr);
static void		InitFont(Tk_Window tkwin, XFontStruct *fontStructPtr,
			    UnixFont *fontPtr);
static void		InitSubFont(Display *display,
			    XFontStruct *fontStructPtr, int base,
			    SubFont *subFontPtr);
static char **		ListFonts(Display *display, CONST char *faceName,
			    int *numNamesPtr);
static char **		ListFontOrAlias(Display *display, CONST char*faceName,
			    int *numNamesPtr);
static unsigned int	RankAttributes(FontAttributes *wantPtr,
			    FontAttributes *gotPtr);
static void		ReleaseFont(UnixFont *fontPtr);
static void		ReleaseSubFont(Display *display, SubFont *subFontPtr);
static int		SeenName(CONST char *name, Tcl_DString *dsPtr);
#ifndef WORDS_BIGENDIAN
static int		Ucs2beToUtfProc(ClientData clientData, CONST char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
static int		UtfToUcs2beProc(ClientData clientData, CONST char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
#endif

/*
 *-------------------------------------------------------------------------
 *
 * FontPkgCleanup --
 *
 *	This function is called when an application is created. It initializes
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
 *	Releases thread-specific resources used by font pkg.
 *
 *-------------------------------------------------------------------------
 */

static void
FontPkgCleanup(
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->controlFamily.encoding != NULL) {
	FontFamily *familyPtr = &tsdPtr->controlFamily;
	int i;







|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
 *	Releases thread-specific resources used by font pkg.
 *
 *-------------------------------------------------------------------------
 */

static void
FontPkgCleanup(
    ClientData clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->controlFamily.encoding != NULL) {
	FontFamily *familyPtr = &tsdPtr->controlFamily;
	int i;
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317






318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338



339
340
341
342
343
344
345
346
347
348
349
 *	None.
 *
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    SubFont dummy;
    int i;
    Tcl_Encoding ucs2;

    if (tsdPtr->controlFamily.encoding == NULL) {







	Tcl_EncodingType type = {"X11ControlChars", ControlUtfProc, ControlUtfProc, NULL, NULL, 0};
	tsdPtr->controlFamily.refCount = 2;
	tsdPtr->controlFamily.encoding = Tcl_CreateEncoding(&type);
	tsdPtr->controlFamily.isTwoByteFont = 0;

	dummy.familyPtr = &tsdPtr->controlFamily;
	dummy.fontMap = tsdPtr->controlFamily.fontMap;
	for (i = 0x00; i < 0x20; i++) {
	    FontMapInsert(&dummy, i);
	    FontMapInsert(&dummy, i + 0x80);
	}


	/*
	 * UCS-2BE is unicode (UCS-2) in big-endian format. Define this if
	 * if it doesn't exist yet. It is used in iso10646 fonts.
	 */

	ucs2 = Tcl_GetEncoding(NULL, "ucs-2be");
	if (ucs2 == NULL) {
	    Tcl_EncodingType ucs2type = {"ucs-2be", Ucs2beToUtfProc, UtfToUcs2beProc, NULL, NULL, 2};



	    Tcl_CreateEncoding(&ucs2type);
	} else {
	    Tcl_FreeEncoding(ucs2);
	}
	Tcl_CreateThreadExitHandler(FontPkgCleanup, NULL);
    }
}

/*
 *-------------------------------------------------------------------------
 *







|



>


<


>
>
>
>
>
>

<











>


|


|
|
|
>
>
>
|
|
<
<







312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359


360
361
362
363
364
365
366
 *	None.
 *
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_EncodingType type;
    SubFont dummy;
    int i;


    if (tsdPtr->controlFamily.encoding == NULL) {
	type.encodingName = "X11ControlChars";
	type.toUtfProc = ControlUtfProc;
	type.fromUtfProc = ControlUtfProc;
	type.freeProc = NULL;
	type.clientData = NULL;
	type.nullSize = 0;


	tsdPtr->controlFamily.refCount = 2;
	tsdPtr->controlFamily.encoding = Tcl_CreateEncoding(&type);
	tsdPtr->controlFamily.isTwoByteFont = 0;

	dummy.familyPtr = &tsdPtr->controlFamily;
	dummy.fontMap = tsdPtr->controlFamily.fontMap;
	for (i = 0x00; i < 0x20; i++) {
	    FontMapInsert(&dummy, i);
	    FontMapInsert(&dummy, i + 0x80);
	}

#ifndef WORDS_BIGENDIAN
	/*
	 * UCS-2BE is unicode (UCS-2) in big-endian format. Define this if
	 * native order isn't BE. It is used in iso10646 fonts.
	 */

	type.encodingName = "ucs-2be";
	type.toUtfProc = Ucs2beToUtfProc;
	type.fromUtfProc = UtfToUcs2beProc;
	type.freeProc = NULL;
	type.clientData = NULL;
	type.nullSize = 2;
	Tcl_CreateEncoding(&type);
#endif


	Tcl_CreateThreadExitHandler(FontPkgCleanup, NULL);
    }
}

/*
 *-------------------------------------------------------------------------
 *
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532

533
534
535
536
537
538
539
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
ControlUtfProc(
    TCL_UNUSED(void *),	/* Not used. */
    const char *src,		/* Source string in UTF-8. */
    int srcLen,			/* Source string length in bytes. */
    TCL_UNUSED(int),			/* Conversion control flags. */
    TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;

    int ch, result;
    static const char hexChars[] = "0123456789ABCDEF";
    static const char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - 6;

    for ( ; src < srcEnd; ) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += TkUtfToUniChar(src, &ch);
	dst[0] = '\\';
	if (((size_t)ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    dst[1] = mapChars[ch];
	    dst += 2;
	} else if ((size_t)ch < 256) {
	    dst[1] = 'x';
	    dst[2] = hexChars[(ch >> 4) & 0xF];
	    dst[3] = hexChars[ch & 0xF];
	    dst += 4;
	} else if ((size_t)ch < 0x10000) {
	    dst[1] = 'u';
	    dst[2] = hexChars[(ch >> 12) & 0xF];
	    dst[3] = hexChars[(ch >> 8) & 0xF];
	    dst[4] = hexChars[(ch >> 4) & 0xF];
	    dst[5] = hexChars[ch & 0xF];
	    dst += 6;
	} else {
	    /* TODO we can do better here */
	    dst[1] = 'u';
	    dst[2] = 'F';
	    dst[3] = 'F';
	    dst[4] = 'F';
	    dst[5] = 'D';
	    dst += 6;
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = dst - dstStart;
    return result;
}


/*
 *-------------------------------------------------------------------------
 *
 * Ucs2beToUtfProc --
 *
 *	Convert from UCS-2BE (big-endian 16-bit Unicode) to UTF-8.

 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
Ucs2beToUtfProc(
    TCL_UNUSED(void *),		/* Not used. */
    const char *src,		/* Source string in Unicode. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    const char *dstEnd, *dstStart;
    int result, numChars, charLimit = INT_MAX;
    unsigned short ch;

    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    result = TCL_OK;

    /* check alignment with ucs-2 (2 == sizeof(UCS-2)) */
    if ((srcLen % 2) != 0) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen--;
    }
    /* If last code point is a high surrogate, we cannot handle that yet */
    if ((srcLen >= 2) && ((src[srcLen - 2] & 0xFC) == 0xD8)) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen -= 2;
    }

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - 4;

    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}

	ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF);
	src += 2 /* sizeof(UTF-16) */;

	/*
	 * Special case for 1-byte utf chars for speed. Make sure we work with
	 * unsigned short-size data.


	 */
	if (ch && ch < 0x80) {
	    *dst++ = (ch & 0xFF);
	} else {
	    dst += Tcl_UniCharToUtf(ch, dst);
	}

    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}







|
|

|
|




















|

>
|
|
|

















|

|


|

|
|

|

|
|
|
|
<
<
<
<
<
<
<
<









>






>












|
|


|




















|
|
|
<

<
<
<







<
<
<
<
<





|

|





<
<
<

<
<
>
>

|
<
<
|
<
>







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445








446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

503



504
505
506
507
508
509
510





511
512
513
514
515
516
517
518
519
520
521
522
523



524


525
526
527
528


529

530
531
532
533
534
535
536
537
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
ControlUtfProc(
    ClientData clientData,	/* Not used. */
    CONST char *src,		/* Source string in UTF-8. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;
    Tcl_UniChar ch;
    int result;
    static char hexChars[] = "0123456789abcdef";
    static char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - 6;

    for ( ; src < srcEnd; ) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += Tcl_UtfToUniChar(src, &ch);
	dst[0] = '\\';
	if ((ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    dst[1] = mapChars[ch];
	    dst += 2;
	} else if (ch < 256) {
	    dst[1] = 'x';
	    dst[2] = hexChars[(ch >> 4) & 0xf];
	    dst[3] = hexChars[ch & 0xf];
	    dst += 4;
	} else {
	    dst[1] = 'u';
	    dst[2] = hexChars[(ch >> 12) & 0xf];
	    dst[3] = hexChars[(ch >> 8) & 0xf];
	    dst[4] = hexChars[(ch >> 4) & 0xf];
	    dst[5] = hexChars[ch & 0xf];








	    dst += 6;
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = dst - dstStart;
    return result;
}

#ifndef WORDS_BIGENDIAN
/*
 *-------------------------------------------------------------------------
 *
 * Ucs2beToUtfProc --
 *
 *	Convert from UCS-2BE (big-endian 16-bit Unicode) to UTF-8.
 *	This is only defined on LE machines.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
Ucs2beToUtfProc(
    ClientData clientData,	/* Not used. */
    CONST char *src,		/* Source string in Unicode. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd;
    char *dstEnd, *dstStart;
    int result, numChars;





    result = TCL_OK;

    /* check alignment with ucs-2 (2 == sizeof(UCS-2)) */
    if ((srcLen % 2) != 0) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen--;
    }






    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; src < srcEnd; numChars++) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}




	/*


	 * Need to swap byte-order on little-endian machines (x86) for
	 * UCS-2BE. We know this is an LE->BE swap.
	 */



	dst += Tcl_UniCharToUtf(htons(*((short *)src)), dst);

	src += 2 /* sizeof(UCS-2) */;
    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619


620
621
622
623
624
625
626
627
628
629

630
631
632
633
634
635
636
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
UtfToUcs2beProc(
    TCL_UNUSED(void *),	/* TableEncodingData that specifies
				 * encoding. */
    const char *src,		/* Source string in UTF-8. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars;
    int ch;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if (!(flags & TCL_ENCODING_END)) {
	srcClose -= 6;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - 2 /* sizeof(UCS-2) */;

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += TkUtfToUniChar(src, &ch);
	if (ch > 0xFFFF) {
	    ch = 0xFFFD;
	}

	/*
	 * Ensure big-endianness (store big bits first).


	 */

	*dst++ = (char)((ch >> 8) & 0xFF);
	*dst++ = (char)(ch & 0xFF);
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}


/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.







|

|


|




















|

|




|
|












>






|
|
<
<
<



>
>


|
|






>







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612



613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
UtfToUcs2beProc(
    ClientData clientData,	/* TableEncodingData that specifies
				 * encoding. */
    CONST char *src,		/* Source string in UTF-8. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars;
    Tcl_UniChar ch;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - 2 /* sizeof(UCS-2) */;

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
        }
	src += Tcl_UtfToUniChar(src, &ch);




	/*
	 * Ensure big-endianness (store big bits first).
	 * XXX: This hard-codes the assumed size of Tcl_UniChar as 2. Make
	 * sure to work in char* for Tcl_UtfToUniChar alignment. [Bug 1122671]
	 */

	*dst++ = (ch >> 8);
	*dst++ = (ch & 0xFF);
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}
#endif /* WORDS_BIGENDIAN */

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    UnixFont *fontPtr;
    XFontStruct *fontStructPtr;
    FontAttributes fa;
    const char *p;
    int hasSpace, dashes, hasWild;

    /*
     * The behavior of X when given a name that isn't an XLFD is unspecified.
     * For example, Exceed 6 returns a valid font for any random string. This
     * is awkward since system names have higher priority than the other Tk
     * font syntaxes. So, we need to perform a quick sanity check on the name







|




|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST char *name)		/* Platform-specific font name. */
{
    UnixFont *fontPtr;
    XFontStruct *fontStructPtr;
    FontAttributes fa;
    CONST char *p;
    int hasSpace, dashes, hasWild;

    /*
     * The behavior of X when given a name that isn't an XLFD is unspecified.
     * For example, Exceed 6 returns a valid font for any random string. This
     * is awkward since system names have higher priority than the other Tk
     * font syntaxes. So, we need to perform a quick sanity check on the name
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
	 * out and lost. But make sure we don't have an "-option value" string
	 * since TkFontParseXLFD would return a false success when attempting
	 * to parse it.
	 */

	if (name[0] == '-') {
	    if (name[1] != '*') {
		const char *dash;

		dash = strchr(name + 1, '-');
		if ((dash == NULL) || (isspace(UCHAR(dash[-1])))) {
		    return NULL;
		}
	    }
	} else if (name[0] != '*') {
	    return NULL;
	}
	if (TkFontParseXLFD(name, &fa.fa, &fa.xa) != TCL_OK) {
	    return NULL;
	}
	fontStructPtr = CreateClosestFont(tkwin, &fa.fa, &fa.xa);
    }
    fontPtr = (UnixFont *)ckalloc(sizeof(UnixFont));
    InitFont(tkwin, fontStructPtr, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------







|














|







700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
	 * out and lost. But make sure we don't have an "-option value" string
	 * since TkFontParseXLFD would return a false success when attempting
	 * to parse it.
	 */

	if (name[0] == '-') {
	    if (name[1] != '*') {
		char *dash;

		dash = strchr(name + 1, '-');
		if ((dash == NULL) || (isspace(UCHAR(dash[-1])))) {
		    return NULL;
		}
	    }
	} else if (name[0] != '*') {
	    return NULL;
	}
	if (TkFontParseXLFD(name, &fa.fa, &fa.xa) != TCL_OK) {
	    return NULL;
	}
	fontStructPtr = CreateClosestFont(tkwin, &fa.fa, &fa.xa);
    }
    fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont));
    InitFont(tkwin, fontStructPtr, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    UnixFont *fontPtr;
    TkXLFDAttributes xa;
    XFontStruct *fontStructPtr;

    TkInitXLFDAttributes(&xa);
    fontStructPtr = CreateClosestFont(tkwin, faPtr, &xa);

    fontPtr = (UnixFont *) tkFontPtr;
    if (fontPtr == NULL) {
	fontPtr = (UnixFont *)ckalloc(sizeof(UnixFont));
    } else {
	ReleaseFont(fontPtr);
    }
    InitFont(tkwin, fontStructPtr, fontPtr);

    fontPtr->font.fa.underline = faPtr->underline;
    fontPtr->font.fa.overstrike = faPtr->overstrike;







|











|







759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    UnixFont *fontPtr;
    TkXLFDAttributes xa;
    XFontStruct *fontStructPtr;

    TkInitXLFDAttributes(&xa);
    fontStructPtr = CreateClosestFont(tkwin, faPtr, &xa);

    fontPtr = (UnixFont *) tkFontPtr;
    if (fontPtr == NULL) {
	fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont));
    } else {
	ReleaseFont(fontPtr);
    }
    InitFont(tkwin, fontStructPtr, fontPtr);

    fontPtr->font.fa.underline = faPtr->underline;
    fontPtr->font.fa.overstrike = faPtr->overstrike;
835
836
837
838
839
840
841
842
843
844
845
846
847


848
849
850
851
852
853
854
 */

void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    int i, isNew, numNames;
    char *family, **nameList;
    Tcl_HashTable familyTable;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_Obj *resultPtr, *strPtr;



    Tcl_InitHashTable(&familyTable, TCL_STRING_KEYS);
    nameList = ListFonts(Tk_Display(tkwin), "*", &numNames);
    for (i = 0; i < numNames; i++) {
	char *familyEnd;

	family = strchr(nameList[i] + 1, '-');







|





>
>







834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
 */

void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    int i, new, numNames;
    char *family, **nameList;
    Tcl_HashTable familyTable;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_Obj *resultPtr, *strPtr;

    resultPtr = Tcl_GetObjResult(interp);

    Tcl_InitHashTable(&familyTable, TCL_STRING_KEYS);
    nameList = ListFonts(Tk_Display(tkwin), "*", &numNames);
    for (i = 0; i < numNames; i++) {
	char *familyEnd;

	family = strchr(nameList[i] + 1, '-');
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
	}
	family++;			/* Advance to char after '-'. */
	familyEnd = strchr(family, '-');
	if (familyEnd == NULL) {
	    continue;			/* See comment above. */
	}
	*familyEnd = '\0';
	Tcl_CreateHashEntry(&familyTable, family, &isNew);
    }
    XFreeFontNames(nameList);

    hPtr = Tcl_FirstHashEntry(&familyTable, &search);
    resultPtr = Tcl_NewObj();
    while (hPtr != NULL) {
	strPtr = Tcl_NewStringObj((const char *)Tcl_GetHashKey(&familyTable, hPtr), -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_SetObjResult(interp, resultPtr);

    Tcl_DeleteHashTable(&familyTable);
}

/*
 *-------------------------------------------------------------------------
 *







|




<

|



<







865
866
867
868
869
870
871
872
873
874
875
876

877
878
879
880
881

882
883
884
885
886
887
888
	}
	family++;			/* Advance to char after '-'. */
	familyEnd = strchr(family, '-');
	if (familyEnd == NULL) {
	    continue;			/* See comment above. */
	}
	*familyEnd = '\0';
	Tcl_CreateHashEntry(&familyTable, family, &new);
    }
    XFreeFontNames(nameList);

    hPtr = Tcl_FirstHashEntry(&familyTable, &search);

    while (hPtr != NULL) {
	strPtr = Tcl_NewStringObj(Tcl_GetHashKey(&familyTable, hPtr), -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }


    Tcl_DeleteHashTable(&familyTable);
}

/*
 *-------------------------------------------------------------------------
 *
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
    Tk_Font tkfont)
{
    int i;
    Tcl_Obj *objv[3], *resultPtr, *listPtr;
    UnixFont *fontPtr;
    FontFamily *familyPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (UnixFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	objv[0] = Tcl_NewStringObj(familyPtr->faceName, -1);
	objv[1] = Tcl_NewStringObj(familyPtr->foundry, -1);
	objv[2] = Tcl_NewStringObj(
		Tcl_GetEncodingName(familyPtr->encoding), -1);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *







|










<







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
    Tk_Font tkfont)
{
    int i;
    Tcl_Obj *objv[3], *resultPtr, *listPtr;
    UnixFont *fontPtr;
    FontFamily *familyPtr;

    resultPtr = Tcl_GetObjResult(interp);
    fontPtr = (UnixFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	objv[0] = Tcl_NewStringObj(familyPtr->faceName, -1);
	objv[1] = Tcl_NewStringObj(familyPtr->foundry, -1);
	objv[2] = Tcl_NewStringObj(
		Tcl_GetEncodingName(familyPtr->encoding), -1);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    FontAttributes atts;
    UnixFont *fontPtr = (UnixFont *) tkfont;
				/* Structure describing the logical font */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
				 * FindSubFontForChar needs to fix up the
				 * memory allocation */
    SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
				/* Pointer to the subfont to use for the given
				 * character */

    GetFontAttributes(Tk_Display(tkwin), thisSubFontPtr->fontStructPtr, &atts);
    *faPtr = atts.fa;
}

/*
 *---------------------------------------------------------------------------
 *







|












<







941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    Tcl_UniChar c,		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    FontAttributes atts;
    UnixFont *fontPtr = (UnixFont *) tkfont;
				/* Structure describing the logical font */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
				 * FindSubFontForChar needs to fix up the
				 * memory allocation */
    SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
				/* Pointer to the subfont to use for the given
				 * character */

    GetFontAttributes(Tk_Display(tkwin), thisSubFontPtr->fontStructPtr, &atts);
    *faPtr = atts.fa;
}

/*
 *---------------------------------------------------------------------------
 *
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
 *
 *---------------------------------------------------------------------------
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length







|







982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
 *
 *---------------------------------------------------------------------------
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;
    int curX, curByte, ch;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */

    fontPtr = (UnixFont *) tkfont;

    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	const char *p, *end, *next;

	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
	 *    represented by a single screen font.
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,







|
















|
>















|







1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;
    int curX, curByte;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */

    fontPtr = (UnixFont *) tkfont;

    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	CONST char *p, *end, *next;
	Tcl_UniChar ch;
	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
	 *    represented by a single screen font.
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,
1076
1077
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
	    curX += XTextWidth(lastSubFontPtr->fontStructPtr,
		    Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString));
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	const char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote;

	FontFamily *familyPtr;
	XChar2b buf[8];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + TkUtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
	for (p = source; ; ) {
	    if ((ch < BASE_CHARS) && (fontPtr->widths[ch] != 0)) {
		newX += fontPtr->widths[ch];
	    } else {
		lastSubFontPtr = FindSubFontForChar(fontPtr, ch, NULL);
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p, 0, NULL,
			(char *)&buf[0].byte1, sizeof(buf), NULL, &dstWrote, NULL);
		if (familyPtr->isTwoByteFont) {
		    newX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    buf, dstWrote >> 1);
		} else {
		    newX += XTextWidth(lastSubFontPtr->fontStructPtr,
			    (char *)&buf[0].byte1, dstWrote);
		}
	    }
	    if (newX > maxLength) {
		break;
	    }
	    curX = newX;
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += TkUtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {







|

>

|







|













|
|


|

|
|













|







1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
	    curX += XTextWidth(lastSubFontPtr->fontStructPtr,
		    Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString));
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	CONST char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote;
	Tcl_UniChar ch;
	FontFamily *familyPtr;
	char buf[16];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + Tcl_UtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
	for (p = source; ; ) {
	    if ((ch < BASE_CHARS) && (fontPtr->widths[ch] != 0)) {
		newX += fontPtr->widths[ch];
	    } else {
		lastSubFontPtr = FindSubFontForChar(fontPtr, ch, NULL);
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p,
			0, NULL, buf, sizeof(buf), NULL, &dstWrote, NULL);
		if (familyPtr->isTwoByteFont) {
		    newX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    (XChar2b *) buf, dstWrote >> 1);
		} else {
		    newX += XTextWidth(lastSubFontPtr->fontStructPtr, buf,
			    dstWrote);
		}
	    }
	    if (newX > maxLength) {
		break;
	    }
	    curX = newX;
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += Tcl_UtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += TkUtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += TkUtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}








|





|







1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += Tcl_UtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += Tcl_UtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}

1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
 *
 *---------------------------------------------------------------------------
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(int),		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and







|

|







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
 *
 *---------------------------------------------------------------------------
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
1221
1222
1223
1224
1225
1226
1227

1228
1229
1230
1231
1232
1233
1234
				 * no characters fit. TK_ISOLATE_END means
				 * that the last character should not be
				 * considered in context with the rest of the
				 * string (used for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *---------------------------------------------------------------------------
 *







>







1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
				 * no characters fit. TK_ISOLATE_END means
				 * that the last character should not be
				 * considered in context with the rest of the
				 * string (used for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    (void) numBytes; /*unused*/
    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *---------------------------------------------------------------------------
 *
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278

1279

1280
1281
1282
1283
1284
1285
1286
void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    int xStart, needWidth, window_width, do_width, ch;

    FontFamily *familyPtr;
#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    int rx, ry;
    unsigned width, height, border_width, depth;
    Drawable root;
#endif


    lastSubFontPtr = &fontPtr->subFontArray[0];

    xStart = x;

#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    /*
     * Get the window width so we can abort drawing outside of the window
     */








|










|


|
|
>



|



>

>







1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    CONST char *p, *end, *next;
    int xStart, needWidth, window_width, do_width;
    Tcl_UniChar ch;
    FontFamily *familyPtr;
#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    int rx, ry;
    unsigned int width, height, border_width, depth;
    Drawable root;
#endif

    fontPtr = (UnixFont *) tkfont;
    lastSubFontPtr = &fontPtr->subFontArray[0];

    xStart = x;

#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    /*
     * Get the window width so we can abort drawing outside of the window
     */

1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {







|







1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On X11 this
 *	context isn't consulted, so we just call Tk_DrawChars().
 *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(int),		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
 *-------------------------------------------------------------------------
 *
 * CreateClosestFont --
 *







<
<
<
















|






|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
|
|







1372
1373
1374
1375
1376
1377
1378



1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
































1409
1410

1411
1412
1413
1414
1415
1416
1417
1418
1419
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On X11 this
 *	context isn't consulted, so we just call Tk_DrawChars().
 *



 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
































    (void) numBytes; /*unused*/


    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x, y);
}

/*
 *-------------------------------------------------------------------------
 *
 * CreateClosestFont --
 *
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
 *
 *-------------------------------------------------------------------------
 */

static XFontStruct *
CreateClosestFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr,
				/* Set of generic attributes to match. */
    const TkXLFDAttributes *xaPtr)
				/* Set of X-specific attributes to match. */
{
    FontAttributes want;
    char **nameList;
    int numNames, nameIdx, bestIdx[2];
    Display *display;
    XFontStruct *fontStructPtr;
    unsigned bestScore[2];

    want.fa = *faPtr;
    want.xa = *xaPtr;

    if (want.xa.foundry == NULL) {
	want.xa.foundry = Tk_GetUid("adobe");
    }







|

|







|







1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
 *
 *-------------------------------------------------------------------------
 */

static XFontStruct *
CreateClosestFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST TkFontAttributes *faPtr,
				/* Set of generic attributes to match. */
    CONST TkXLFDAttributes *xaPtr)
				/* Set of X-specific attributes to match. */
{
    FontAttributes want;
    char **nameList;
    int numNames, nameIdx, bestIdx[2];
    Display *display;
    XFontStruct *fontStructPtr;
    unsigned int bestScore[2];

    want.fa = *faPtr;
    want.xa = *xaPtr;

    if (want.xa.foundry == NULL) {
	want.xa.foundry = Tk_GetUid("adobe");
    }
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
     * foreach fallback for fontname
     *	    try the fallback
     *	    try all aliases for the fallback
     */

    nameList = ListFontOrAlias(display, want.fa.family, &numNames);
    if (numNames == 0) {
	const char *const *const *fontFallbacks;
	int i, j;
	const char *fallback;

	fontFallbacks = TkFontGetFallbacks();
	for (i = 0; fontFallbacks[i] != NULL; i++) {
	    for (j = 0; (fallback = fontFallbacks[i][j]) != NULL; j++) {
		if (strcasecmp(want.fa.family, fallback) == 0) {
		    break;
		}







|

|







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
     * foreach fallback for fontname
     *	    try the fallback
     *	    try all aliases for the fallback
     */

    nameList = ListFontOrAlias(display, want.fa.family, &numNames);
    if (numNames == 0) {
	char ***fontFallbacks;
	int i, j;
	char *fallback;

	fontFallbacks = TkFontGetFallbacks();
	for (i = 0; fontFallbacks[i] != NULL; i++) {
	    for (j = 0; (fallback = fontFallbacks[i][j]) != NULL; j++) {
		if (strcasecmp(want.fa.family, fallback) == 0) {
		    break;
		}
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
	    return GetSystemFont(display);
	}
    }

  found:
    bestIdx[0] = -1;
    bestIdx[1] = -1;
    bestScore[0] = (unsigned) -1;
    bestScore[1] = (unsigned) -1;
    for (nameIdx = 0; nameIdx < numNames; nameIdx++) {
	FontAttributes got;
	int scalable;
	unsigned score;

	if (TkFontParseXLFD(nameList[nameIdx], &got.fa, &got.xa) != TCL_OK) {
	    continue;
	}
	IdentifySymbolEncodings(&got);
	scalable = (got.fa.size == 0.0);
	score = RankAttributes(&want, &got);
	if (score < bestScore[scalable]) {
	    bestIdx[scalable] = nameIdx;
	    bestScore[scalable] = score;
	}
	if (score == 0) {
	    break;







|
|



|





|







1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
	    return GetSystemFont(display);
	}
    }

  found:
    bestIdx[0] = -1;
    bestIdx[1] = -1;
    bestScore[0] = (unsigned int) -1;
    bestScore[1] = (unsigned int) -1;
    for (nameIdx = 0; nameIdx < numNames; nameIdx++) {
	FontAttributes got;
	int scalable;
	unsigned int score;

	if (TkFontParseXLFD(nameList[nameIdx], &got.fa, &got.xa) != TCL_OK) {
	    continue;
	}
	IdentifySymbolEncodings(&got);
	scalable = (got.fa.size == 0);
	score = RankAttributes(&want, &got);
	if (score < bestScore[scalable]) {
	    bestIdx[scalable] = nameIdx;
	    bestScore[scalable] = score;
	}
	if (score == 0) {
	    break;
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
    fmPtr = &fontPtr->font.fm;
    fmPtr->ascent = fontStructPtr->ascent;
    fmPtr->descent = fontStructPtr->descent;
    fmPtr->maxWidth = fontStructPtr->max_bounds.width;
    fmPtr->fixed = fixed;

    fontPtr->display = display;
    fontPtr->pixelSize = (int)(TkFontGetPixels(tkwin, fa.fa.size) + 0.5);
    fontPtr->xa = fa.xa;

    fontPtr->numSubFonts = 1;
    fontPtr->subFontArray = fontPtr->staticSubFonts;
    InitSubFont(display, fontStructPtr, 1, &fontPtr->subFontArray[0]);

    fontPtr->controlSubFont = fontPtr->subFontArray[0];
    subFontPtr = FindSubFontForChar(fontPtr, '0', NULL);
    controlPtr = &fontPtr->controlSubFont;
    controlPtr->fontStructPtr = subFontPtr->fontStructPtr;
    controlPtr->familyPtr = &tsdPtr->controlFamily;
    controlPtr->fontMap = tsdPtr->controlFamily.fontMap;

    pageMap = fontPtr->subFontArray[0].fontMap[0];
    for (i = 0; i < 256; i++) {
	if ((minHi > 0) || (i < minLo) || (i > maxLo)
		|| !((pageMap[i>>3] >> (i&7)) & 1)) {
	    n = 0;
	} else if (fontStructPtr->per_char == NULL) {
	    n = fontStructPtr->max_bounds.width;
	} else {
	    n = fontStructPtr->per_char[i - minLo].width;
	}
	fontPtr->widths[i] = n;







|
















|







1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
    fmPtr = &fontPtr->font.fm;
    fmPtr->ascent = fontStructPtr->ascent;
    fmPtr->descent = fontStructPtr->descent;
    fmPtr->maxWidth = fontStructPtr->max_bounds.width;
    fmPtr->fixed = fixed;

    fontPtr->display = display;
    fontPtr->pixelSize = TkFontGetPixels(tkwin, fa.fa.size);
    fontPtr->xa = fa.xa;

    fontPtr->numSubFonts = 1;
    fontPtr->subFontArray = fontPtr->staticSubFonts;
    InitSubFont(display, fontStructPtr, 1, &fontPtr->subFontArray[0]);

    fontPtr->controlSubFont = fontPtr->subFontArray[0];
    subFontPtr = FindSubFontForChar(fontPtr, '0', NULL);
    controlPtr = &fontPtr->controlSubFont;
    controlPtr->fontStructPtr = subFontPtr->fontStructPtr;
    controlPtr->familyPtr = &tsdPtr->controlFamily;
    controlPtr->fontMap = tsdPtr->controlFamily.fontMap;

    pageMap = fontPtr->subFontArray[0].fontMap[0];
    for (i = 0; i < 256; i++) {
	if ((minHi > 0) || (i < minLo) || (i > maxLo)
		|| (((pageMap[i>>3] >> (i&7)) & 1) == 0)) {
	    n = 0;
	} else if (fontStructPtr->per_char == NULL) {
	    n = fontStructPtr->max_bounds.width;
	} else {
	    n = fontStructPtr->per_char[i - minLo].width;
	}
	fontPtr->widths[i] = n;
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
	/*
	 * If the XA_UNDERLINE_THICKNESS property does not exist, the X manual
	 * recommends using the width of the stem on a capital letter. I don't
	 * know of a way to get the stem width of a letter, so guess and use
	 * 1/3 the width of a capital I.
	 */

	fontPtr->barHeight = fontPtr->widths[(unsigned char)'I'] / 3;
	if (fontPtr->barHeight == 0) {
	    fontPtr->barHeight = 1;
	}
    }
    if (fontPtr->underlinePos + fontPtr->barHeight > fontStructPtr->descent) {
	/*
	 * If this set of cobbled together values would cause the bottom of







|







1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
	/*
	 * If the XA_UNDERLINE_THICKNESS property does not exist, the X manual
	 * recommends using the width of the stem on a capital letter. I don't
	 * know of a way to get the stem width of a letter, so guess and use
	 * 1/3 the width of a capital I.
	 */

	fontPtr->barHeight = fontPtr->widths['I'] / 3;
	if (fontPtr->barHeight == 0) {
	    fontPtr->barHeight = 1;
	}
    }
    if (fontPtr->underlinePos + fontPtr->barHeight > fontStructPtr->descent) {
	/*
	 * If this set of cobbled together values would cause the bottom of
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
{
    int i;

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	ReleaseSubFont(fontPtr->display, &fontPtr->subFontArray[i]);
    }
    if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	ckfree(fontPtr->subFontArray);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * InitSubFont --







|







1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
{
    int i;

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	ReleaseSubFont(fontPtr->display, &fontPtr->subFontArray[i]);
    }
    if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	ckfree((char *) fontPtr->subFontArray);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * InitSubFont --
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
 */

static FontFamily *
AllocFontFamily(
    Display *display,		/* Display in which font will be used. */
    XFontStruct *fontStructPtr,	/* Screen font whose FontFamily is to be
				 * returned. */
    TCL_UNUSED(int))			/* Non-zero if this font family is to be used
				 * in the base font of a font object. */
{
    FontFamily *familyPtr;
    FontAttributes fa;
    Tcl_Encoding encoding;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    GetFontAttributes(display, fontStructPtr, &fa);
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = (FontFamily *)ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
    familyPtr->nextPtr = tsdPtr->fontFamilyList;
    tsdPtr->fontFamilyList = familyPtr;

    /*
     * Set key for this FontFamily.
     */







|
















<
|
<





|







1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840

1841

1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
 */

static FontFamily *
AllocFontFamily(
    Display *display,		/* Display in which font will be used. */
    XFontStruct *fontStructPtr,	/* Screen font whose FontFamily is to be
				 * returned. */
    int base)			/* Non-zero if this font family is to be used
				 * in the base font of a font object. */
{
    FontFamily *familyPtr;
    FontAttributes fa;
    Tcl_Encoding encoding;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    GetFontAttributes(display, fontStructPtr, &fa);
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {

	    Tcl_FreeEncoding(encoding);

	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
    familyPtr->nextPtr = tsdPtr->fontFamilyList;
    tsdPtr->fontFamilyList = familyPtr;

    /*
     * Set key for this FontFamily.
     */
1939
1940
1941
1942
1943
1944
1945

1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    int i;

    if (familyPtr == NULL) {
	return;
    }

    if (familyPtr->refCount-- > 1) {
	return;
    }
    if (familyPtr->encoding) {
	Tcl_FreeEncoding(familyPtr->encoding);
    }
    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*
     * Delete from list.
     */

    for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) {
	if (*familyPtrPtr == familyPtr) {
	    *familyPtrPtr = familyPtr->nextPtr;
	    break;
	}
	familyPtrPtr = &(*familyPtrPtr)->nextPtr;
    }

    ckfree(familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * FindSubFontForChar --
 *







>
|


<
|
<


















|







1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914

1915

1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    int i;

    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
	return;
    }

    Tcl_FreeEncoding(familyPtr->encoding);

    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*
     * Delete from list.
     */

    for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) {
	if (*familyPtrPtr == familyPtr) {
	    *familyPtrPtr = familyPtr->nextPtr;
	    break;
	}
	familyPtrPtr = &(*familyPtrPtr)->nextPtr;
    }

    ckfree((char *) familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * FindSubFontForChar --
 *
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
				 * will be displayed. */
    int ch,			/* The Unicode character to be displayed. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    int i, j, k, numNames;
    Tk_Uid faceName;
    const char *fallback;
    const char *const *aliases;
    char **nameList;
    const char *const *anyFallbacks;
    const char *const *const *fontFallbacks;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if (ch < 0 || ch >= FONTMAP_NUMCHARS) {
	ch = 0xFFFD;
    }

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}
    }

    if (FontMapLookup(&fontPtr->controlSubFont, ch)) {
	return &fontPtr->controlSubFont;







|
<
<
<
<



|
|


|







1963
1964
1965
1966
1967
1968
1969
1970




1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
				 * will be displayed. */
    int ch,			/* The Unicode character to be displayed. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    int i, j, k, numNames;
    Tk_Uid faceName;
    char *fallback, **aliases, **nameList, **anyFallbacks, ***fontFallbacks;




    SubFont *subFontPtr;
    Tcl_DString ds;

    if (FontMapLookup(&fontPtr->subFontArray[0], ch)) {
	return &fontPtr->subFontArray[0];
    }

    for (i = 1; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}
    }

    if (FontMapLookup(&fontPtr->controlSubFont, ch)) {
	return &fontPtr->controlSubFont;
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
    /*
     * Try all face names available in the whole system until we find one that
     * can be used.
     */

    nameList = ListFonts(fontPtr->display, "*", &numNames);
    for (i = 0; i < numNames; i++) {
	char *fallbck = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallbck, '-')[0] = '\0';
	if (SeenName(fallbck, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallbck, ch,
		    fixSubFontPtrPtr);
	    if (subFontPtr != NULL) {
		XFreeFontNames(nameList);
		goto end;
	    }
	}
    }







|
|
|
|







2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
    /*
     * Try all face names available in the whole system until we find one that
     * can be used.
     */

    nameList = ListFonts(fontPtr->display, "*", &numNames);
    for (i = 0; i < numNames; i++) {
	fallback = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallback, '-')[0] = '\0';
	if (SeenName(fallback, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallback, ch,
		    fixSubFontPtrPtr);
	    if (subFontPtr != NULL) {
		XFreeFontNames(nameList);
		goto end;
	    }
	}
    }
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
FontMapLookup(
    SubFont *subFontPtr,	/* Contains font mapping cache to be queried
				 * and possibly updated. */
    int ch)			/* Character to be tested. */
{
    int row, bitOffset;

    if (ch < 0 ||  ch >= FONTMAP_NUMCHARS) {
	return 0;
    }
    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
}







<
<
<







2121
2122
2123
2124
2125
2126
2127



2128
2129
2130
2131
2132
2133
2134
FontMapLookup(
    SubFont *subFontPtr,	/* Contains font mapping cache to be queried
				 * and possibly updated. */
    int ch)			/* Character to be tested. */
{
    int row, bitOffset;




    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
}
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
FontMapInsert(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int ch)			/* Character to be added to cache. */
{
    int row, bitOffset;

    if (ch >= 0 &&  ch < FONTMAP_NUMCHARS) {
	row = ch >> FONTMAP_SHIFT;
	if (subFontPtr->fontMap[row] == NULL) {
	    FontMapLoadPage(subFontPtr, row);
	}
	bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
	subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * FontMapLoadPage --
 *







<
|
|
|
|
|
|
<







2161
2162
2163
2164
2165
2166
2167

2168
2169
2170
2171
2172
2173

2174
2175
2176
2177
2178
2179
2180
FontMapInsert(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int ch)			/* Character to be added to cache. */
{
    int row, bitOffset;


    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);

}

/*
 *-------------------------------------------------------------------------
 *
 * FontMapLoadPage --
 *
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    char buf[16], src[6];
    int minHi, maxHi, minLo, maxLo, scale, checkLo;
    int i, end, bitOffset, isTwoByteFont, n;
    Tcl_Encoding encoding;
    XFontStruct *fontStructPtr;
    XCharStruct *widths;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    subFontPtr->fontMap[row] = (char *)ckalloc(FONTMAP_BITSPERPAGE / 8);
    memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8);

    if (subFontPtr->familyPtr == &tsdPtr->controlFamily) {
	return;
    }

    fontStructPtr = subFontPtr->fontStructPtr;







|








|







2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    char buf[16], src[TCL_UTF_MAX];
    int minHi, maxHi, minLo, maxLo, scale, checkLo;
    int i, end, bitOffset, isTwoByteFont, n;
    Tcl_Encoding encoding;
    XFontStruct *fontStructPtr;
    XCharStruct *widths;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8);
    memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8);

    if (subFontPtr->familyPtr == &tsdPtr->controlFamily) {
	return;
    }

    fontStructPtr = subFontPtr->fontStructPtr;
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, TkUniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];







|







2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
 *---------------------------------------------------------------------------
 */

static SubFont *
CanUseFallbackWithAliases(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,		/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    SubFont *subFontPtr;
    const char *const *aliases;
    int i;

    if (SeenName(faceName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(fontPtr, faceName, ch, fixSubFontPtrPtr);
	if (subFontPtr != NULL) {
	    return subFontPtr;
	}







|










|







2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
 *---------------------------------------------------------------------------
 */

static SubFont *
CanUseFallbackWithAliases(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    char *faceName,		/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    SubFont *subFontPtr;
    char **aliases;
    int i;

    if (SeenName(faceName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(fontPtr, faceName, ch, fixSubFontPtrPtr);
	if (subFontPtr != NULL) {
	    return subFontPtr;
	}
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
SeenName(
    const char *name,		/* The name to check. */
    Tcl_DString *dsPtr)		/* Contains names that have already been
				 * seen. */
{
    const char *seen, *end;

    seen = Tcl_DStringValue(dsPtr);
    end = seen + Tcl_DStringLength(dsPtr);
    while (seen < end) {
	if (strcasecmp(seen, name) == 0) {
	    return 1;
	}
	seen += strlen(seen) + 1;
    }
    Tcl_DStringAppend(dsPtr, name, (int) (strlen(name) + 1));
    return 0;
}

/*
 *-------------------------------------------------------------------------
 *
 * CanUseFallback --







|



|









|







2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
SeenName(
    CONST char *name,		/* The name to check. */
    Tcl_DString *dsPtr)		/* Contains names that have already been
				 * seen. */
{
    CONST char *seen, *end;

    seen = Tcl_DStringValue(dsPtr);
    end = seen + Tcl_DStringLength(dsPtr);
    while (seen < end) {
	if (strcasecmp(seen, name) == 0) {
	    return 1;
	}
	seen += strlen(seen) + 1;
    }
    Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1));
    return 0;
}

/*
 *-------------------------------------------------------------------------
 *
 * CanUseFallback --
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
 *-------------------------------------------------------------------------
 */

static SubFont *
CanUseFallback(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,	/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    int i, nameIdx, numNames, srcLen, numEncodings, bestIdx[2];
    Tk_Uid hateFoundry;
    const char *charset, *hateCharset;
    unsigned bestScore[2];
    char **nameList;
    char **nameListOrig;
    char src[6];
    FontAttributes want, got;
    Display *display;
    SubFont subFont;
    XFontStruct *fontStructPtr;
    Tcl_DString dsEncodings;
    Tcl_Encoding *encodingCachePtr;








|







|
|
|
<
<







2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403


2404
2405
2406
2407
2408
2409
2410
 *-------------------------------------------------------------------------
 */

static SubFont *
CanUseFallback(
    UnixFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    CONST char *faceName,	/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    SubFont **fixSubFontPtrPtr)	/* Subfont reference to fix up if we
				 * reallocate our subfont table. */
{
    int i, nameIdx, numNames, srcLen, numEncodings, bestIdx[2];
    Tk_Uid hateFoundry;
    CONST char *charset, *hateCharset;
    unsigned int bestScore[2];
    char **nameList, **nameListOrig, src[TCL_UTF_MAX];


    FontAttributes want, got;
    Display *display;
    SubFont subFont;
    XFontStruct *fontStructPtr;
    Tcl_DString dsEncodings;
    Tcl_Encoding *encodingCachePtr;

2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = TkUniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = (double)-fontPtr->pixelSize;

    hateFoundry = NULL;
    hateCharset = NULL;
    numEncodings = 0;
    Tcl_DStringInit(&dsEncodings);

    charset = NULL;	/* numNames must be > 0 to get here. */

  retry:
    bestIdx[0] = -1;
    bestIdx[1] = -1;
    bestScore[0] = (unsigned) -1;
    bestScore[1] = (unsigned) -1;
    for (nameIdx = 0; nameIdx < numNames; nameIdx++) {
	Tcl_Encoding encoding;
	char dst[16];
	int scalable, srcRead, dstWrote;
	unsigned score;

	if (nameList[nameIdx] == NULL) {
	    continue;
	}
	if (TkFontParseXLFD(nameList[nameIdx], &got.fa, &got.xa) != TCL_OK) {
	    goto crossout;
	}







|





|






|




|
|




|







2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = Tcl_UniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = -fontPtr->pixelSize;

    hateFoundry = NULL;
    hateCharset = NULL;
    numEncodings = 0;
    Tcl_DStringInit(&dsEncodings);

    charset = NULL;	/* lint, since numNames must be > 0 to get here. */

  retry:
    bestIdx[0] = -1;
    bestIdx[1] = -1;
    bestScore[0] = (unsigned int) -1;
    bestScore[1] = (unsigned int) -1;
    for (nameIdx = 0; nameIdx < numNames; nameIdx++) {
	Tcl_Encoding encoding;
	char dst[16];
	int scalable, srcRead, dstWrote;
	unsigned int score;

	if (nameList[nameIdx] == NULL) {
	    continue;
	}
	if (TkFontParseXLFD(nameList[nameIdx], &got.fa, &got.xa) != TCL_OK) {
	    goto crossout;
	}
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631

2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
	    goto crossout;
	}

	/*
	 * D. Rank each name and pick the best match.
	 */

	scalable = (got.fa.size == 0.0);
	score = RankAttributes(&want, &got);
	if (score < bestScore[scalable]) {
	    bestIdx[scalable] = nameIdx;
	    bestScore[scalable] = score;
	}
	if (score == 0) {
	    break;
	}
	continue;

    crossout:
	if (nameList == nameListOrig) {
	    /*
	     * Not allowed to change pointers to memory that X gives you, so
	     * make a copy.
	     */

	    nameList = (char **)ckalloc(numNames * sizeof(char *));
	    memcpy(nameList, nameListOrig, numNames * sizeof(char *));
	}
	nameList[nameIdx] = NULL;
    }

    fontStructPtr = GetScreenFont(display, &want, nameList, bestIdx,
	    bestScore);

    encodingCachePtr = (Tcl_Encoding *) Tcl_DStringValue(&dsEncodings);
    for (i = numEncodings; --i >= 0; encodingCachePtr++) {
	Tcl_FreeEncoding(*encodingCachePtr);
    }
    Tcl_DStringFree(&dsEncodings);
    numEncodings = 0;

    if (fontStructPtr == NULL) {
	if (nameList != nameListOrig) {
	    ckfree(nameList);
	}
	XFreeFontNames(nameListOrig);
	return NULL;
    }

    InitSubFont(display, fontStructPtr, 0, &subFont);
    if (FontMapLookup(&subFont, ch) == 0) {
	/*
	 * E. If the font we picked cannot actually display the character,
	 * cross out all names with the same foundry and encoding and pick
	 * another font.
	 */

	hateFoundry = got.xa.foundry;
	hateCharset = charset;
	ReleaseSubFont(display, &subFont);
	goto retry;
    }
    if (nameList != nameListOrig) {
	ckfree(nameList);
    }
    XFreeFontNames(nameListOrig);

    if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
	SubFont *newPtr;


	newPtr = (SubFont *)ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1));
	memcpy(newPtr, fontPtr->subFontArray,
		fontPtr->numSubFonts * sizeof(SubFont));
	if (fixSubFontPtrPtr != NULL) {
	    SubFont *fixSubFontPtr = *fixSubFontPtrPtr;

	    if (fixSubFontPtr != &fontPtr->controlSubFont) {
		*fixSubFontPtrPtr =
			newPtr + (fixSubFontPtr - fontPtr->subFontArray);
	    }
	}
	if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	    ckfree(fontPtr->subFontArray);
	}
	fontPtr->subFontArray = newPtr;
    }
    fontPtr->subFontArray[fontPtr->numSubFonts] = subFont;
    fontPtr->numSubFonts++;
    return &fontPtr->subFontArray[fontPtr->numSubFonts - 1];
}







|

















|

















|



















|






>
|
|


|







|







2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
	    goto crossout;
	}

	/*
	 * D. Rank each name and pick the best match.
	 */

	scalable = (got.fa.size == 0);
	score = RankAttributes(&want, &got);
	if (score < bestScore[scalable]) {
	    bestIdx[scalable] = nameIdx;
	    bestScore[scalable] = score;
	}
	if (score == 0) {
	    break;
	}
	continue;

    crossout:
	if (nameList == nameListOrig) {
	    /*
	     * Not allowed to change pointers to memory that X gives you, so
	     * make a copy.
	     */

	    nameList = (char **) ckalloc(numNames * sizeof(char *));
	    memcpy(nameList, nameListOrig, numNames * sizeof(char *));
	}
	nameList[nameIdx] = NULL;
    }

    fontStructPtr = GetScreenFont(display, &want, nameList, bestIdx,
	    bestScore);

    encodingCachePtr = (Tcl_Encoding *) Tcl_DStringValue(&dsEncodings);
    for (i = numEncodings; --i >= 0; encodingCachePtr++) {
	Tcl_FreeEncoding(*encodingCachePtr);
    }
    Tcl_DStringFree(&dsEncodings);
    numEncodings = 0;

    if (fontStructPtr == NULL) {
	if (nameList != nameListOrig) {
	    ckfree((char *) nameList);
	}
	XFreeFontNames(nameListOrig);
	return NULL;
    }

    InitSubFont(display, fontStructPtr, 0, &subFont);
    if (FontMapLookup(&subFont, ch) == 0) {
	/*
	 * E. If the font we picked cannot actually display the character,
	 * cross out all names with the same foundry and encoding and pick
	 * another font.
	 */

	hateFoundry = got.xa.foundry;
	hateCharset = charset;
	ReleaseSubFont(display, &subFont);
	goto retry;
    }
    if (nameList != nameListOrig) {
	ckfree((char *) nameList);
    }
    XFreeFontNames(nameListOrig);

    if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
	SubFont *newPtr;

	newPtr = (SubFont *)
		ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1));
	memcpy((char *) newPtr, fontPtr->subFontArray,
		fontPtr->numSubFonts * sizeof(SubFont));
	if (fixSubFontPtrPtr != NULL) {
	    register SubFont *fixSubFontPtr = *fixSubFontPtrPtr;

	    if (fixSubFontPtr != &fontPtr->controlSubFont) {
		*fixSubFontPtrPtr =
			newPtr + (fixSubFontPtr - fontPtr->subFontArray);
	    }
	}
	if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	    ckfree((char *) fontPtr->subFontArray);
	}
	fontPtr->subFontArray = newPtr;
    }
    fontPtr->subFontArray[fontPtr->numSubFonts] = subFont;
    fontPtr->numSubFonts++;
    return &fontPtr->subFontArray[fontPtr->numSubFonts - 1];
}
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static unsigned
RankAttributes(
    FontAttributes *wantPtr,	/* The desired attributes. */
    FontAttributes *gotPtr)	/* The attributes we have to live with. */
{
    unsigned penalty;

    penalty = 0;
    if (gotPtr->xa.foundry != wantPtr->xa.foundry) {
	penalty += 4500;
    }
    if (gotPtr->fa.family != wantPtr->fa.family) {
	penalty += 9000;







|




|







2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static unsigned int
RankAttributes(
    FontAttributes *wantPtr,	/* The desired attributes. */
    FontAttributes *gotPtr)	/* The attributes we have to live with. */
{
    unsigned int penalty;

    penalty = 0;
    if (gotPtr->xa.foundry != wantPtr->xa.foundry) {
	penalty += 4500;
    }
    if (gotPtr->fa.family != wantPtr->fa.family) {
	penalty += 9000;
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
    if (gotPtr->xa.slant != wantPtr->xa.slant) {
	penalty += 10;
    }
    if (gotPtr->xa.setwidth != wantPtr->xa.setwidth) {
	penalty += 1000;
    }

    if (gotPtr->fa.size == 0.0) {
	/*
	 * A scalable font is almost always acceptable, but the corresponding
	 * bitmapped font would be better.
	 */

	penalty += 10;
    } else {
	int diff;

	/*
	 * It's worse to be too large than to be too small.
	 */

	diff = (int) (150 * (-gotPtr->fa.size - -wantPtr->fa.size));
	if (diff > 0) {
	    penalty += 600;
	} else if (diff < 0) {
	    penalty += 150;
	    diff = -diff;
	}
	penalty += diff;
    }
    if (gotPtr->xa.charset != wantPtr->xa.charset) {
	size_t i;
	const char *gotAlias, *wantAlias;

	penalty += 65000;
	gotAlias = GetEncodingAlias(gotPtr->xa.charset);
	wantAlias = GetEncodingAlias(wantPtr->xa.charset);
	if (strcmp(gotAlias, wantAlias) != 0) {
	    penalty += 30000;
	    for (i = 0; i < sizeof(encodingList)/sizeof(encodingList[0]); i++) {
		if (strcmp(gotAlias, encodingList[i]) == 0) {
		    penalty -= 30000;
		    break;
		}
		penalty += 20000;
	    }
	}







|













|






|


|
|






|







2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
    if (gotPtr->xa.slant != wantPtr->xa.slant) {
	penalty += 10;
    }
    if (gotPtr->xa.setwidth != wantPtr->xa.setwidth) {
	penalty += 1000;
    }

    if (gotPtr->fa.size == 0) {
	/*
	 * A scalable font is almost always acceptable, but the corresponding
	 * bitmapped font would be better.
	 */

	penalty += 10;
    } else {
	int diff;

	/*
	 * It's worse to be too large than to be too small.
	 */

	diff = (-gotPtr->fa.size - -wantPtr->fa.size);
	if (diff > 0) {
	    penalty += 600;
	} else if (diff < 0) {
	    penalty += 150;
	    diff = -diff;
	}
	penalty += 150 * diff;
    }
    if (gotPtr->xa.charset != wantPtr->xa.charset) {
	int i;
	CONST char *gotAlias, *wantAlias;

	penalty += 65000;
	gotAlias = GetEncodingAlias(gotPtr->xa.charset);
	wantAlias = GetEncodingAlias(wantPtr->xa.charset);
	if (strcmp(gotAlias, wantAlias) != 0) {
	    penalty += 30000;
	    for (i = 0; encodingList[i] != NULL; i++) {
		if (strcmp(gotAlias, encodingList[i]) == 0) {
		    penalty -= 30000;
		    break;
		}
		penalty += 20000;
	    }
	}
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
GetScreenFont(
    Display *display,		/* Display for new XFontStruct. */
    FontAttributes *wantPtr,	/* Contains desired actual pixel-size if the
				 * best font was scalable. */
    char **nameList,		/* Array of XLFDs. */
    int bestIdx[2],		/* Indices into above array for XLFD of best
				 * bitmapped and best scalable font. */
    unsigned bestScore[2])	/* Scores of best bitmapped and best scalable
				 * font. XLFD corresponding to lowest score
				 * will be constructed. */
{
    XFontStruct *fontStructPtr;

    if ((bestIdx[0] < 0) && (bestIdx[1] < 0)) {
	return NULL;







|







2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
GetScreenFont(
    Display *display,		/* Display for new XFontStruct. */
    FontAttributes *wantPtr,	/* Contains desired actual pixel-size if the
				 * best font was scalable. */
    char **nameList,		/* Array of XLFDs. */
    int bestIdx[2],		/* Indices into above array for XLFD of best
				 * bitmapped and best scalable font. */
    unsigned int bestScore[2])	/* Scores of best bitmapped and best scalable
				 * font. XLFD corresponding to lowest score
				 * will be constructed. */
{
    XFontStruct *fontStructPtr;

    if ((bestIdx[0] < 0) && (bestIdx[1] < 0)) {
	return NULL;
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
	}
	rest = str;
	for (i = XLFD_PIXEL_SIZE; i < XLFD_CHARSET; i++) {
	    rest = strchr(rest + 1, '-');
	}
	*str = '\0';
	sprintf(buf, "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]],
		(int)(-wantPtr->fa.size+0.5), rest);
	*str = '-';
	fontStructPtr = XLoadQueryFont(display, buf);
	bestScore[1] = INT_MAX;
    }
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, nameList[bestIdx[0]]);
	if (fontStructPtr == NULL) {







|







2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
	}
	rest = str;
	for (i = XLFD_PIXEL_SIZE; i < XLFD_CHARSET; i++) {
	    rest = strchr(rest + 1, '-');
	}
	*str = '\0';
	sprintf(buf, "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]],
		-wantPtr->fa.size, rest);
	*str = '-';
	fontStructPtr = XLoadQueryFont(display, buf);
	bestScore[1] = INT_MAX;
    }
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, nameList[bestIdx[0]]);
	if (fontStructPtr == NULL) {
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
 *
 *---------------------------------------------------------------------------
 */

static char **
ListFonts(
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char buf[256];

    sprintf(buf, "-*-%.80s-*-*-*-*-*-*-*-*-*-*-*-*", faceName);
    return XListFonts(display, buf, 10000, numNamesPtr);
}

static char **
ListFontOrAlias(
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char **nameList;
    const char *const *aliases;
    int i;

    nameList = ListFonts(display, faceName, numNamesPtr);
    if (nameList != NULL) {
	return nameList;
    }
    aliases = TkFontGetAliasList(faceName);







|












|



|
<







2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908

2909
2910
2911
2912
2913
2914
2915
 *
 *---------------------------------------------------------------------------
 */

static char **
ListFonts(
    Display *display,		/* Display to query. */
    CONST char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char buf[256];

    sprintf(buf, "-*-%.80s-*-*-*-*-*-*-*-*-*-*-*-*", faceName);
    return XListFonts(display, buf, 10000, numNamesPtr);
}

static char **
ListFontOrAlias(
    Display *display,		/* Display to query. */
    CONST char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char **nameList, **aliases;

    int i;

    nameList = ListFonts(display, faceName, numNamesPtr);
    if (nameList != NULL) {
	return nameList;
    }
    aliases = TkFontGetAliasList(faceName);
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
 */

static int
IdentifySymbolEncodings(
    FontAttributes *faPtr)
{
    int i, j;
    const char *const *aliases;
    const char *const *symbolClass;

    symbolClass = TkFontGetSymbolClass();
    for (i = 0; symbolClass[i] != NULL; i++) {
	if (strcasecmp(faPtr->fa.family, symbolClass[i]) == 0) {
	    faPtr->xa.charset = Tk_GetUid(GetEncodingAlias(symbolClass[i]));
	    return 1;
	}







<
|







2950
2951
2952
2953
2954
2955
2956

2957
2958
2959
2960
2961
2962
2963
2964
 */

static int
IdentifySymbolEncodings(
    FontAttributes *faPtr)
{
    int i, j;

    char **aliases, **symbolClass;

    symbolClass = TkFontGetSymbolClass();
    for (i = 0; symbolClass[i] != NULL; i++) {
	if (strcasecmp(faPtr->fa.family, symbolClass[i]) == 0) {
	    faPtr->xa.charset = Tk_GetUid(GetEncodingAlias(symbolClass[i]));
	    return 1;
	}
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static const char *
GetEncodingAlias(
    const char *name)		/* The name to look up. */
{
    const EncodingAlias *aliasPtr;

    for (aliasPtr = encodingAliases; aliasPtr->aliasPattern != NULL; ) {
	if (Tcl_StringCaseMatch(name, aliasPtr->aliasPattern, 0)) {
	    return aliasPtr->realName;
	}
	aliasPtr++;
    }
    return name;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkDrawAngledChars --
 *
 *	Draw some characters at an angle. This is awkward here because we have
 *	no reliable way of drawing any characters at an angle in classic X11;
 *	we have to draw on a Pixmap which is converted to an XImage (from
 *	helper function GetImageOfText), rotate the image (hokey code!) onto
 *	another XImage (from helper function InitDestImage), and then use the
 *	rotated image as a mask when drawing. This is pretty awful; improved
 *	versions are welcomed!
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Target drawable is updated.
 *
 *---------------------------------------------------------------------------
 */

static inline XImage *
GetImageOfText(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int *realWidthPtr, int *realHeightPtr)
{
    int width, height;
    TkFont *fontPtr = (TkFont *) tkfont;
    Pixmap bitmap;
    GC bitmapGC;
    XGCValues values;
    XImage *image = NULL;

    (void) Tk_MeasureChars(tkfont, source, numBytes, -1, 0, &width);
    height = fontPtr->fm.ascent + fontPtr->fm.descent;

    if ((width > 0) && (height > 0)) {
	bitmap = Tk_GetPixmap(display, drawable, width, height, 1);
	values.graphics_exposures = False;
	values.foreground = BlackPixel(display, DefaultScreen(display));
	bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground,
		&values);
	XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height);

	values.font = Tk_FontId(tkfont);
	values.foreground = WhitePixel(display, DefaultScreen(display));
	values.background = BlackPixel(display, DefaultScreen(display));
	XChangeGC(display, bitmapGC, GCFont|GCForeground|GCBackground, &values);
	Tk_DrawChars(display, bitmap, bitmapGC, tkfont, source, numBytes, 0,
		fontPtr->fm.ascent);
	XFreeGC(display, bitmapGC);

	image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes,
		ZPixmap);
	Tk_FreePixmap(display, bitmap);
    }

    *realWidthPtr = width;
    *realHeightPtr = height;
    return image;
}

static inline XImage *
InitDestImage(
    Display *display,
    Drawable drawable,
    int width,
    int height,
    Pixmap *bitmapPtr)
{
    Pixmap bitmap = None;
    XImage *image = NULL;
    GC bitmapGC;
    XGCValues values;

    if ((width > 0) && (height > 0)) {
	bitmap = Tk_GetPixmap(display, drawable, width, height, 1);
	values.graphics_exposures = False;
	values.foreground = BlackPixel(display, DefaultScreen(display));
	bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground,
		&values);
	XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height);
	XFreeGC(display, bitmapGC);

	image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes,
		ZPixmap);
    }
    *bitmapPtr = bitmap;
    return image;
}

void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,
    double angle)
{
    if (angle == 0.0) {
	Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y);
    } else {
	double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);
	int bufHeight, bufWidth, srcWidth, srcHeight, i, j, dx, dy;
	Pixmap buf;
	XImage *srcImage = GetImageOfText(display, drawable, tkfont, source,
		numBytes, &srcWidth, &srcHeight);
	XImage *dstImage;
	enum {Q0=1,R1,Q1,R2,Q2,R3,Q3} quadrant;
	GC bwgc, cpgc;
	XGCValues values;
	int ascent = ((TkFont *) tkfont)->fm.ascent;

	/*
	 * First, work out what quadrant we are operating in. We also handle
	 * the rectilinear rotations as special cases. Conceptually, there's
	 * also R0 (angle == 0.0) but that has been already handled as a
	 * special case above.
	 *
	 *        R1
	 *   Q1   |   Q0
	 *        |
	 * R2 ----+---- R0
	 *        |
	 *   Q2   |   Q3
	 *        R3
	 */

	if (angle < 90.0) {
	    quadrant = Q0;
	} else if (angle == 90.0) {
	    quadrant = R1;
	} else if (angle < 180.0) {
	    quadrant = Q1;
	} else if (angle == 180.0) {
	    quadrant = R2;
	} else if (angle < 270.0) {
	    quadrant = Q2;
	} else if (angle == 270.0) {
	    quadrant = R3;
	} else {
	    quadrant = Q3;
	}

	if (srcImage == NULL) {
	    return;
	}
	bufWidth = srcWidth*fabs(cosA) + srcHeight*fabs(sinA);
	bufHeight = srcHeight*fabs(cosA) + srcWidth*fabs(sinA);
	dstImage = InitDestImage(display, drawable, bufWidth,bufHeight, &buf);
	if (dstImage == NULL) {
	    Tk_FreePixmap(display, buf);
	    XDestroyImage(srcImage);
	    return;
	}

	/*
	 * Do the rotation, setting or resetting pixels in the destination
	 * image dependent on whether the corresponding pixel (after rotation
	 * to source image space) is set.
	 */

	for (i=0 ; i<srcWidth ; i++) {
	    for (j=0 ; j<srcHeight ; j++) {
		switch (quadrant) {
		case Q0:
		    dx = ROUND16(i*cosA + j*sinA);
		    dy = ROUND16(j*cosA + (srcWidth - i)*sinA);
		    break;
		case R1:
		    dx = j;
		    dy = srcWidth - i;
		    break;
		case Q1:
		    dx = ROUND16((i - srcWidth)*cosA + j*sinA);
		    dy = ROUND16((srcWidth-i)*sinA + (j-srcHeight)*cosA);
		    break;
		case R2:
		    dx = srcWidth - i;
		    dy = srcHeight - j;
		    break;
		case Q2:
		    dx = ROUND16((i-srcWidth)*cosA + (j-srcHeight)*sinA);
		    dy = ROUND16((j - srcHeight)*cosA - i*sinA);
		    break;
		case R3:
		    dx = srcHeight - j;
		    dy = i;
		    break;
		default:
		    dx = ROUND16(i*cosA + (j - srcHeight)*sinA);
		    dy = ROUND16(j*cosA - i*sinA);
		}

		if (dx < 0 || dy < 0 || dx >= bufWidth || dy >= bufHeight) {
		    continue;
		}
		XPutPixel(dstImage, dx, dy,
			XGetPixel(dstImage,dx,dy) | XGetPixel(srcImage,i,j));
	    }
	}
	XDestroyImage(srcImage);

	/*
	 * Schlep the data back to the Xserver.
	 */

	values.function = GXcopy;
	values.foreground = WhitePixel(display, DefaultScreen(display));
	values.background = BlackPixel(display, DefaultScreen(display));
	bwgc = XCreateGC(display, buf, GCFunction|GCForeground|GCBackground,
		&values);
	XPutImage(display, buf, bwgc, dstImage, 0,0, 0,0, bufWidth,bufHeight);
	XFreeGC(display, bwgc);
	XDestroyImage(dstImage);

	/*
	 * Calculate where we want to draw the text.
	 */

	switch (quadrant) {
	case Q0:
	    dx = x;
	    dy = y - srcWidth*sinA;
	    break;
	case R1:
	    dx = x;
	    dy = y - srcWidth;
	    break;
	case Q1:
	    dx = x + srcWidth*cosA;
	    dy = y + srcHeight*cosA - srcWidth*sinA;
	    break;
	case R2:
	    dx = x - srcWidth;
	    dy = y - srcHeight;
	    break;
	case Q2:
	    dx = x + srcWidth*cosA + srcHeight*sinA;
	    dy = y + srcHeight*cosA;
	    break;
	case R3:
	    dx = x - srcHeight;
	    dy = y;
	    break;
	default:
	    dx = x + srcHeight*sinA;
	    dy = y;
	}

	/*
	 * Apply a correction to deal with the fact that we aren't told to
	 * draw from our top-left corner but rather from the left-end of our
	 * baseline.
	 */

	dx -= ascent*sinA;
	dy -= ascent*cosA;

	/*
	 * Transfer the text to the screen. This is done by using it as a mask
	 * and then drawing through that mask with the original drawing color.
	 */

	values.function = GXcopy;
	values.fill_style = FillSolid;
	values.clip_mask = buf;
	values.clip_x_origin = dx;
	values.clip_y_origin = dy;
	cpgc = XCreateGC(display, drawable,
		GCFunction|GCFillStyle|GCClipMask|GCClipXOrigin|GCClipYOrigin,
		&values);
	XCopyGC(display, gc, GCForeground, cpgc);
	XFillRectangle(display, drawable, cpgc, dx, dy, bufWidth,
		bufHeight);
	XFreeGC(display, cpgc);

	Tk_FreePixmap(display, buf);
	return;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|

|


|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009















































































































































































































































































































3010
3011
3012
3013
3014
3015
3016
3017
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static CONST char *
GetEncodingAlias(
    CONST char *name)		/* The name to look up. */
{
    EncodingAlias *aliasPtr;

    for (aliasPtr = encodingAliases; aliasPtr->aliasPattern != NULL; ) {
	if (Tcl_StringMatch((char *) name, aliasPtr->aliasPattern)) {
	    return aliasPtr->realName;
	}
	aliasPtr++;
    }
    return name;
}
















































































































































































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixInit.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 */

#include "tkUnixInt.h"

#ifdef HAVE_COREFOUNDATION
static int		GetLibraryPath(Tcl_Interp *interp);
#else
#define GetLibraryPath(dummy)	(void)dummy
#endif /* HAVE_COREFOUNDATION */

/*
 *----------------------------------------------------------------------
 *
 * TkpInit --
 *







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 */

#include "tkUnixInt.h"

#ifdef HAVE_COREFOUNDATION
static int		GetLibraryPath(Tcl_Interp *interp);
#else
#define GetLibraryPath(dummy)	(void)0
#endif /* HAVE_COREFOUNDATION */

/*
 *----------------------------------------------------------------------
 *
 * TkpInit --
 *
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 */

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    const char *p, *name;

    name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}







|

|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 */

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    CONST char *p, *name;

    name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 *	Generates messages on stdout.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, -1);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}







|
|


<







96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
 *	Generates messages on stdout.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayWarning(
    CONST char *msg,		/* Message to be displayed. */
    CONST char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, -1);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
 *
 * Side effects:
 *	Same as for Tcl_MacOSXOpenVersionedBundleResources.
 *
 *----------------------------------------------------------------------
 */

#ifdef TK_FRAMEWORK
static int
GetLibraryPath(
    Tcl_Interp *interp)
{

    int foundInFramework = TCL_ERROR;
    char tkLibPath[PATH_MAX + 1];

    foundInFramework = Tcl_MacOSXOpenVersionedBundleResources(interp,
	    "com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
	    tkLibPath);
    if (tkLibPath[0] != '\0') {
        Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
    }
    return foundInFramework;
}
#else
static int
GetLibraryPath(
    TCL_UNUSED(Tcl_Interp *))
{
    return TCL_ERROR;
}
#endif

#endif /* HAVE_COREFOUNDATION */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<




>







|


<

<
<
<
<

<

>









127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149




150

151
152
153
154
155
156
157
158
159
160
161
 *
 * Side effects:
 *	Same as for Tcl_MacOSXOpenVersionedBundleResources.
 *
 *----------------------------------------------------------------------
 */


static int
GetLibraryPath(
    Tcl_Interp *interp)
{
#ifdef TK_FRAMEWORK
    int foundInFramework = TCL_ERROR;
    char tkLibPath[PATH_MAX + 1];

    foundInFramework = Tcl_MacOSXOpenVersionedBundleResources(interp,
	    "com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
	    tkLibPath);
    if (tkLibPath[0] != '\0') {
        Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
    }
    return foundInFramework;

#else




    return TCL_ERROR;

#endif
}
#endif /* HAVE_COREFOUNDATION */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixKey.c.

8
9
10
11
12
13
14
15
16




17






18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72

73
74
75
76
77
78
79
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#undef register /* Keyword "register" is used in XKBlib.h, so don't try tricky things here */
#define XkbOpenDisplay XkbOpenDisplay_ /* Move out of the way, conflicting definitions */




#include <X11/XKBlib.h>






#undef XkbOpenDisplay

/*
 * Prototypes for local functions defined in this file:
 */

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the XIM caret. This is called by
 *	widgets to indicate their cursor placement. This is currently only
 *	used for over-the-spot XIM.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetCaretPos(
    Tk_Window tkwin,
    int x,
    int y,
    int height)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;

    if ((dispPtr->caret.winPtr == winPtr)
	    && (dispPtr->caret.x == x)
	    && (dispPtr->caret.y == y)
	    && (dispPtr->caret.height == height)) {

	return;
    }

    dispPtr->caret.winPtr = winPtr;
    dispPtr->caret.x = x;
    dispPtr->caret.y = y;
    dispPtr->caret.height = height;


    /*
     * Adjust the XIM caret position.
     */

#ifdef TK_USE_INPUT_METHODS
    if ((dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (dispPtr->inputStyle & XIMPreeditPosition)
	    && (winPtr->inputContext != NULL)) {

	XVaNestedList preedit_attr;
	XPoint spot;

	spot.x = dispPtr->caret.x;
	spot.y = dispPtr->caret.y + dispPtr->caret.height;
	preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
	XSetICValues(winPtr->inputContext, XNPreeditAttributes, preedit_attr,

		NULL);
	XFree(preedit_attr);
    }
#endif
}

/*







|
|
>
>
>
>
|
>
>
>
>
>
>
|











|















|
|
|
|
>








>



<
<
|
|
|
>






|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
** Bug [3607830]: Before using Xkb, it must be initialized.  TkpOpenDisplay
**                does this and sets the USE_XKB flag if xkb is supported.
**                (should this be function ptr?)
*/
#ifdef HAVE_XKBKEYCODETOKEYSYM
#  include <X11/XKBlib.h>
#else
#  define XkbKeycodeToKeysym(D,K,G,L) XKeycodeToKeysym(D,K,L)
#endif
#define TkKeycodeToKeysym(D,K,G,L)		\
    ((D)->flags & TK_DISPLAY_USE_XKB) ?		\
      XkbKeycodeToKeysym((D)->display,K,G,L) :	\
      XKeycodeToKeysym((D)->display,K,L)

/*
 * Prototypes for local functions defined in this file:
 */

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the XIM caret. This is called by
 *	widgets to indicate their cursor placement.  This is currently only
 *	used for over-the-spot XIM.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetCaretPos(
    Tk_Window tkwin,
    int x,
    int y,
    int height)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;

    if (   dispPtr->caret.winPtr == winPtr
	&& dispPtr->caret.x == x
	&& dispPtr->caret.y == y
	&& dispPtr->caret.height == height)
    {
	return;
    }

    dispPtr->caret.winPtr = winPtr;
    dispPtr->caret.x = x;
    dispPtr->caret.y = y;
    dispPtr->caret.height = height;

#ifdef TK_USE_INPUT_METHODS
    /*
     * Adjust the XIM caret position.
     */


    if (   (dispPtr->flags & TK_DISPLAY_USE_IM)
	&& (dispPtr->inputStyle & XIMPreeditPosition)
	&& (winPtr->inputContext != NULL) )
    {
	XVaNestedList preedit_attr;
	XPoint spot;

	spot.x = dispPtr->caret.x;
	spot.y = dispPtr->caret.y + dispPtr->caret.height;
	preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
	XSetICValues(winPtr->inputContext,
		XNPreeditAttributes, preedit_attr,
		NULL);
	XFree(preedit_attr);
    }
#endif
}

/*
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
 *	Stores the input string in the specified Tcl_DString. Modifies the
 *	internal input state. This routine can only be called once for a given
 *	event.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    TkSizeT len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

    if (kePtr->charValuePtr != NULL) {
	Tcl_DStringSetLength(dsPtr, kePtr->charValueLen);
	memcpy(Tcl_DStringValue(dsPtr), kePtr->charValuePtr,
		kePtr->charValueLen+1);
	return Tcl_DStringValue(dsPtr);
    }

    /*
     * Only do this for KeyPress events, otherwise
     * further Xlib function behavior might be undefined.
     */

    if (eventPtr->type != KeyPress) {
	len = 0;
	Tcl_DStringSetLength(dsPtr, len);
	goto done;
    }

#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)) {


	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		&kePtr->keysym, &status);

	if (status == XBufferOverflow) {
	    /*
	     * Expand buffer and try again.
	     */

	    Tcl_DStringSetLength(dsPtr, len);
	    len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		    &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
	/*
	 * Overallocate the dstring to the maximum stack amount.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);

	len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(&buf), Tcl_DStringLength(&buf),
                &kePtr->keysym, &status);

	/*
	 * If the buffer wasn't big enough, grow the buffer and try again.
	 */

	if (status == XBufferOverflow) {
	    Tcl_DStringSetLength(&buf, len);
	    len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(&buf), len, &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}

	Tcl_DStringSetLength(&buf, len);
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
	Tcl_DStringFree(&buf);
#endif /* X_HAVE_UTF8_STRING */
    } else
#endif /* TK_USE_INPUT_METHODS */
    {
	/*
	 * Fall back to convert a keyboard event to a UTF-8 string using
	 * XLookupString. This is used when input methods are turned off.

	 *
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = TkUniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {
	    /*
	     * len > 1 should only happen if someone has called XRebindKeysym.
	     * Assume UTF-8.
	     */

	    Tcl_DStringSetLength(dsPtr, len);
	    strncpy(Tcl_DStringValue(dsPtr), Tcl_DStringValue(&buf), len);
	}
    }

    /*
     * Cache the string in the event so that if/when we return to this
     * function, we will be able to produce it without asking X. This stops us
     * from having to reenter the XIM engine. [Bug 1373712]
     */

done:
    kePtr->charValuePtr = (char *)ckalloc(len + 1);
    kePtr->charValueLen = len;
    memcpy(kePtr->charValuePtr, Tcl_DStringValue(dsPtr), len + 1);
    return Tcl_DStringValue(dsPtr);
}

/*
 * When mapping from a keysym to a keycode, need information about the
 * modifier state to be used so that when they call XbkKeycodeToKeysym taking
 * into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int state, mincode, maxcode;
    KeyCode keycode;

    if (keySym == NoSymbol) {
	keycode = 0;
    } else {
	keycode = XKeysymToKeycode(dispPtr->display, keySym);
    }







|





|










|



<
<
<
<
<
<
<
<
<
<
<


|
>
>








|
<
<
<
<
















>
















>









|
>












|



















<
|

|





|










|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129











130
131
132
133
134
135
136
137
138
139
140
141
142
143




144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
 *	Stores the input string in the specified Tcl_DString. Modifies the
 *	internal input state. This routine can only be called once for a given
 *	event.
 *
 *----------------------------------------------------------------------
 */

char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    int len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

    if (kePtr->charValuePtr != NULL) {
	Tcl_DStringSetLength(dsPtr, kePtr->charValueLen);
	memcpy(Tcl_DStringValue(dsPtr), kePtr->charValuePtr,
		(unsigned) kePtr->charValueLen+1);
	return Tcl_DStringValue(dsPtr);
    }












#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)
	    && (eventPtr->type == KeyPress))
    {
	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		&kePtr->keysym, &status);

	if (status == XBufferOverflow) { /* Expand buffer and try again */




	    Tcl_DStringSetLength(dsPtr, len);
	    len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		    &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
	/*
	 * Overallocate the dstring to the maximum stack amount.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);

	len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(&buf), Tcl_DStringLength(&buf),
                &kePtr->keysym, &status);

	/*
	 * If the buffer wasn't big enough, grow the buffer and try again.
	 */

	if (status == XBufferOverflow) {
	    Tcl_DStringSetLength(&buf, len);
	    len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(&buf), len, &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}

	Tcl_DStringSetLength(&buf, len);
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
	Tcl_DStringFree(&buf);
#endif /* X_HAVE_UTF8_STRING */
    } else
#endif /* TK_USE_INPUT_METHODS */
    {
	/*
	 * Fall back to convert a keyboard event to a UTF-8 string using
	 * XLookupString. This is used when input methods are turned off and
	 * for KeyRelease events.
	 *
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = Tcl_UniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {
	    /*
	     * len > 1 should only happen if someone has called XRebindKeysym.
	     * Assume UTF-8.
	     */

	    Tcl_DStringSetLength(dsPtr, len);
	    strncpy(Tcl_DStringValue(dsPtr), Tcl_DStringValue(&buf), len);
	}
    }

    /*
     * Cache the string in the event so that if/when we return to this
     * function, we will be able to produce it without asking X. This stops us
     * from having to reenter the XIM engine. [Bug 1373712]
     */


    kePtr->charValuePtr = ckalloc((unsigned) len + 1);
    kePtr->charValueLen = len;
    memcpy(kePtr->charValuePtr, Tcl_DStringValue(dsPtr), (unsigned) len + 1);
    return Tcl_DStringValue(dsPtr);
}

/*
 * When mapping from a keysym to a keycode, need information about the
 * modifier state to be used so that when they call TkKeycodeToKeysym taking
 * into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int state;
    KeyCode keycode;

    if (keySym == NoSymbol) {
	keycode = 0;
    } else {
	keycode = XKeysymToKeycode(dispPtr->display, keySym);
    }
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
		if (state & 2) {
		    eventPtr->xkey.state |= dispPtr->modeModMask;
		}
		break;
	    }
	}
    }

    /*
     * Filter keycodes out of range, otherwise further Xlib function
     * behavior might be undefined, in particular XIM could cause crashes.
     */

    mincode = 0;
    maxcode = -1;
    XDisplayKeycodes(dispPtr->display, &mincode, &maxcode);
    if (keycode < (KeyCode)mincode) {
	keycode = mincode;
    } else if (keycode > (KeyCode)maxcode) {
	keycode = maxcode;
    }

    eventPtr->xkey.keycode = keycode;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







255
256
257
258
259
260
261















262
263
264
265
266
267
268
		if (state & 2) {
		    eventPtr->xkey.state |= dispPtr->modeModMask;
		}
		break;
	    }
	}
    }















    eventPtr->xkey.keycode = keycode;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;
    TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr;

    /*
     * X11 keycodes always lie in the inclusive range [8,255].
     */

    if (eventPtr->xkey.keycode > 0xff) {
        return NoSymbol;
    }

    /*
     * Refresh the mapping information if it's stale. This must happen before
     * we do any input method processing. [Bug 3599312]
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);







<
<
<
<
<
<
<
<







286
287
288
289
290
291
292








293
294
295
296
297
298
299
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;
    TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr;









    /*
     * Refresh the mapping information if it's stale. This must happen before
     * we do any input method processing. [Bug 3599312]
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	index = 2;
    }
    if ((eventPtr->xkey.state & ShiftMask)
	    || ((dispPtr->lockUsage != LU_IGNORE)
	    && (eventPtr->xkey.state & LockMask))) {
	index += 1;
    }
    sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, 0,
	    index);

    /*
     * Special handling: if the key was shifted because of Lock, but lock is
     * only caps lock, not shift lock, and the shifted keysym isn't upper-case
     * alphabetic, then switch back to the unshifted keysym.
     */

#ifndef XK_Oslash
    /* XK_Oslash is the official name, but might not be present in older X11 headers */
#   define XK_Oslash XK_Ooblique
#endif
    if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
	    && (dispPtr->lockUsage == LU_CAPS)) {
	if (!(((sym >= XK_A) && (sym <= XK_Z))
		|| ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
		|| ((sym >= XK_Oslash) && (sym <= XK_Thorn)))) {
	    index &= ~1;
	    sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
		    0, index);
	}
    }

    /*
     * Another bit of special handling: if this is a shifted key and there is
     * no keysym defined, then use the keysym for the unshifted key.
     */

    if ((index & 1) && (sym == NoSymbol)) {
	sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
		0, index & ~1);
    }
    return sym;
}

/*
 *--------------------------------------------------------------







|








<
<
<
<




|

|










|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348




349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
	index = 2;
    }
    if ((eventPtr->xkey.state & ShiftMask)
	    || ((dispPtr->lockUsage != LU_IGNORE)
	    && (eventPtr->xkey.state & LockMask))) {
	index += 1;
    }
    sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode, 0,
	    index);

    /*
     * Special handling: if the key was shifted because of Lock, but lock is
     * only caps lock, not shift lock, and the shifted keysym isn't upper-case
     * alphabetic, then switch back to the unshifted keysym.
     */





    if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
	    && (dispPtr->lockUsage == LU_CAPS)) {
	if (!(((sym >= XK_A) && (sym <= XK_Z))
		|| ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
		|| ((sym >= XK_Ooblique) && (sym <= XK_Thorn)))) {
	    index &= ~1;
	    sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode,
		    0, index);
	}
    }

    /*
     * Another bit of special handling: if this is a shifted key and there is
     * no keysym defined, then use the keysym for the unshifted key.
     */

    if ((index & 1) && (sym == NoSymbol)) {
	sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode,
		0, index & ~1);
    }
    return sym;
}

/*
 *--------------------------------------------------------------
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

517
518
519
520
521
522
523
524
525
526
527
528

    dispPtr->lockUsage = LU_IGNORE;
    codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex;
    for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}
	keysym = XkbKeycodeToKeysym(dispPtr->display, *codePtr, 0, 0);
	if (keysym == XK_Shift_Lock) {
	    dispPtr->lockUsage = LU_SHIFT;
	    break;
	}
	if (keysym == XK_Caps_Lock) {
	    dispPtr->lockUsage = LU_CAPS;
	    break;
	}
    }

    /*
     * Look through the keycodes associated with modifiers to see if the the
     * "mode switch", "meta", or "alt" keysyms are associated with any
     * modifiers. If so, remember their modifier mask bits.
     */

    dispPtr->modeModMask = 0;
    dispPtr->metaModMask = 0;
    dispPtr->altModMask = 0;
    codePtr = modMapPtr->modifiermap;
    max = 8 * modMapPtr->max_keypermod;
    for (i = 0; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}
	keysym = XkbKeycodeToKeysym(dispPtr->display, *codePtr, 0, 0);

	if (keysym == XK_Mode_switch) {
	    dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
	if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) {
	    dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
	if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) {
	    dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
    }

    /*
     * Create an array of the keycodes for all modifier keys.
     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree(dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = 0;
    arraySize = KEYCODE_ARRAY_SIZE;
    dispPtr->modKeyCodes = (KeyCode *)ckalloc(KEYCODE_ARRAY_SIZE * sizeof(KeyCode));

    for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}

	/*
	 * Make sure that the keycode isn't already in the array.
	 */

	for (j = 0; j < dispPtr->numModKeyCodes; j++) {
	    if (dispPtr->modKeyCodes[j] == *codePtr) {
		/*
		 * 'continue' the outer loop.
		 */

		goto nextModCode;
	    }
	}
	if (dispPtr->numModKeyCodes >= arraySize) {
	    KeyCode *newCodes;

	    /*
	     * Ran out of space in the array; grow it.
	     */

	    arraySize *= 2;

	    newCodes = (KeyCode *)ckalloc(arraySize * sizeof(KeyCode));
	    memcpy(newCodes, dispPtr->modKeyCodes,
		    dispPtr->numModKeyCodes * sizeof(KeyCode));
	    ckfree(dispPtr->modKeyCodes);
	    dispPtr->modKeyCodes = newCodes;
	}
	dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
	dispPtr->numModKeyCodes++;
    nextModCode:
	continue;
    }
    XFreeModifiermap(modMapPtr);







|




















|




|
<
















|



|
>











<
<
<
<




|






>
|
|
|
|
|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475




476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

    dispPtr->lockUsage = LU_IGNORE;
    codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex;
    for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}
	keysym = TkKeycodeToKeysym(dispPtr, *codePtr, 0, 0);
	if (keysym == XK_Shift_Lock) {
	    dispPtr->lockUsage = LU_SHIFT;
	    break;
	}
	if (keysym == XK_Caps_Lock) {
	    dispPtr->lockUsage = LU_CAPS;
	    break;
	}
    }

    /*
     * Look through the keycodes associated with modifiers to see if the the
     * "mode switch", "meta", or "alt" keysyms are associated with any
     * modifiers. If so, remember their modifier mask bits.
     */

    dispPtr->modeModMask = 0;
    dispPtr->metaModMask = 0;
    dispPtr->altModMask = 0;
    codePtr = modMapPtr->modifiermap;
    max = 8*modMapPtr->max_keypermod;
    for (i = 0; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}
	keysym = TkKeycodeToKeysym(dispPtr, *codePtr, 0, 0);

	if (keysym == XK_Mode_switch) {
	    dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
	if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) {
	    dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
	if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) {
	    dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
	}
    }

    /*
     * Create an array of the keycodes for all modifier keys.
     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree((char *) dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = 0;
    arraySize = KEYCODE_ARRAY_SIZE;
    dispPtr->modKeyCodes = (KeyCode *)
	    ckalloc((unsigned) (KEYCODE_ARRAY_SIZE * sizeof(KeyCode)));
    for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}

	/*
	 * Make sure that the keycode isn't already in the array.
	 */

	for (j = 0; j < dispPtr->numModKeyCodes; j++) {
	    if (dispPtr->modKeyCodes[j] == *codePtr) {




		goto nextModCode;
	    }
	}
	if (dispPtr->numModKeyCodes >= arraySize) {
	    KeyCode *new;

	    /*
	     * Ran out of space in the array; grow it.
	     */

	    arraySize *= 2;
	    new = (KeyCode *)
		    ckalloc((unsigned) (arraySize * sizeof(KeyCode)));
	    memcpy(new, dispPtr->modKeyCodes,
		    (dispPtr->numModKeyCodes * sizeof(KeyCode)));
	    ckfree((char *) dispPtr->modKeyCodes);
	    dispPtr->modKeyCodes = new;
	}
	dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
	dispPtr->numModKeyCodes++;
    nextModCode:
	continue;
    }
    XFreeModifiermap(modMapPtr);

Changes to unix/tkUnixMenu.c.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
/*
 * tkUnixMenu.c --
 *
 *	This module implements the UNIX platform-specific features of menus.
 *
 * 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.
 */


#include "tkUnixInt.h"
#include "tkMenu.h"

/*
 * Constants used for menu drawing.
 */












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tkUnixMenu.c --
 *
 *	This module implements the UNIX platform-specific features of menus.
 *
 * 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.
 */

#include "default.h"
#include "tkUnixInt.h"
#include "tkMenu.h"

/*
 * Constants used for menu drawing.
 */

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * Procedures used internally.
 */

static void		SetHelpMenu(TkMenu *menuPtr);
static void		DrawMenuEntryAccelerator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int height, int drawArrow);
static void		DrawMenuEntryBackground(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int heigth);
static void		DrawMenuEntryIndicator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder border, XColor *indicatorColor,
			    XColor *disableColor, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int x, int y,
			    int width, int height);
static void		DrawMenuEntryLabel(TkMenu * menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawMenuSeparator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawTearoffEntry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawMenuUnderline(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		GetMenuAccelGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static void		GetMenuLabelGeometry(TkMenuEntry *mePtr,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetMenuIndicatorGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetMenuSeparatorGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetTearoffEntryGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpNewMenu --
 *







|
|
|








|



|



|



|



|



|


|



|



|



|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Procedures used internally.
 */

static void		SetHelpMenu(TkMenu *menuPtr);
static void		DrawMenuEntryAccelerator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    Tk_3DBorder activeBorder, int x, int y,
			    int width, int height, int drawArrow);
static void		DrawMenuEntryBackground(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int heigth);
static void		DrawMenuEntryIndicator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder border, XColor *indicatorColor,
			    XColor *disableColor, Tk_Font tkfont,
			    CONST Tk_FontMetrics *fmPtr, int x, int y,
			    int width, int height);
static void		DrawMenuEntryLabel(TkMenu * menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawMenuSeparator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawTearoffEntry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		DrawMenuUnderline(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    int x, int y, int width, int height);
static void		GetMenuAccelGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    CONST Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static void		GetMenuLabelGeometry(TkMenuEntry *mePtr,
			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetMenuIndicatorGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    CONST Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetMenuSeparatorGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    CONST Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetTearoffEntryGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    CONST Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpNewMenu --
 *
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 *	All platform-specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenu(
    TCL_UNUSED(TkMenu *))
{
    /*
     * Nothing to do.
     */
}

/*







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 *	All platform-specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenu(
    TkMenu *menuPtr)
{
    /*
     * Nothing to do.
     */
}

/*
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
 *	All platform specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuEntry(
    TCL_UNUSED(TkMenuEntry *))
{
    /*
     * Nothing to do.
     */
}

/*







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
 *	All platform specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuEntry(
    TkMenuEntry *mEntryPtr)
{
    /*
     * Nothing to do.
     */
}

/*
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

int
TkpConfigureMenuEntry(
    TkMenuEntry *mePtr)/* Information about menu entry; may or may
				 * not already have values for some fields. */
{
    /*
     * If this is a cascade menu, and the child menu exists, check to see if
     * the child menu is a help menu.
     */








|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

int
TkpConfigureMenuEntry(
    register TkMenuEntry *mePtr)/* Information about menu entry; may or may
				 * not already have values for some fields. */
{
    /*
     * If this is a cascade menu, and the child menu exists, check to see if
     * the child menu is a help menu.
     */

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
 *	None on Unix.
 *
 *----------------------------------------------------------------------
 */

int
TkpMenuNewEntry(
    TCL_UNUSED(TkMenuEntry *))
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 *	None on Unix.
 *
 *----------------------------------------------------------------------
 */

int
TkpMenuNewEntry(
    TkMenuEntry *mePtr)
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
 *	Recompute geometry of given window.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(const char *))
{
    /*
     * Nothing to do.
     */
}

/*







|
|
|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
 *	Recompute geometry of given window.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    char *menuName)
{
    /*
     * Nothing to do.
     */
}

/*
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
 *----------------------------------------------------------------------
 */

static void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are interested in. */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    int borderWidth;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (!mePtr->hideMargin && mePtr->indicatorOn) {
	    if ((mePtr->image != NULL) || (mePtr->bitmapPtr != NULL)) {
		*widthPtr = (14 * mePtr->height) / 10;
		*heightPtr = mePtr->height;
		if (mePtr->type == CHECK_BUTTON_ENTRY) {







|
|



<
<







319
320
321
322
323
324
325
326
327
328
329
330


331
332
333
334
335
336
337
 *----------------------------------------------------------------------
 */

static void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are interested in. */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{


    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (!mePtr->hideMargin && mePtr->indicatorOn) {
	    if ((mePtr->image != NULL) || (mePtr->bitmapPtr != NULL)) {
		*widthPtr = (14 * mePtr->height) / 10;
		*heightPtr = mePtr->height;
		if (mePtr->type == CHECK_BUTTON_ENTRY) {
349
350
351
352
353
354
355


356
357
358
359
360
361


362
363
364
365
366
367

368
369
370
371
372
373
374
			    INT2PTR((80 * mePtr->height) / 100);
		} else {
		    mePtr->platformEntryData = (TkMenuPlatformEntryData)
			    INT2PTR(mePtr->height);
		}
	    }
	} else {


	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		    &borderWidth);
	    *heightPtr = 0;
	    *widthPtr = borderWidth;
	}
    } else {


	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		&borderWidth);
	*heightPtr = 0;
	*widthPtr = borderWidth;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetMenuAccelGeometry --
 *
 *	Get the geometry of the accelerator area of a menu item.







>
>
|
|




>
>


|
|


>







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
			    INT2PTR((80 * mePtr->height) / 100);
		} else {
		    mePtr->platformEntryData = (TkMenuPlatformEntryData)
			    INT2PTR(mePtr->height);
		}
	    }
	} else {
	    int borderWidth;

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->borderWidthPtr, &borderWidth);
	    *heightPtr = 0;
	    *widthPtr = borderWidth;
	}
    } else {
	int borderWidth;

	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		&borderWidth);
        *heightPtr = 0;
        *widthPtr = borderWidth;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetMenuAccelGeometry --
 *
 *	Get the geometry of the accelerator area of a menu item.
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407
 */

static void
GetMenuAccelGeometry(
    TkMenu *menuPtr,		/* The menu was are drawing */
    TkMenuEntry *mePtr,		/* The entry we are getting the geometry for */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The width of the acclerator area */
    int *heightPtr)		/* The height of the accelerator area */
{
    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
    	*widthPtr = 2 * CASCADE_ARROW_WIDTH;
    } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) {

	const char *accel = Tcl_GetString(mePtr->accelPtr);

	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
    } else {
    	*widthPtr = 0;
    }
}

/*
 *----------------------------------------------------------------------







|






|
>
|

|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
 */

static void
GetMenuAccelGeometry(
    TkMenu *menuPtr,		/* The menu was are drawing */
    TkMenuEntry *mePtr,		/* The entry we are getting the geometry for */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The width of the acclerator area */
    int *heightPtr)		/* The height of the accelerator area */
{
    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
    	*widthPtr = 2 * CASCADE_ARROW_WIDTH;
    } else if ((menuPtr->menuType != MENUBAR)
	    && (mePtr->accelPtr != NULL)) {
	char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL);

    	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
    } else {
    	*widthPtr = 0;
    }
}

/*
 *----------------------------------------------------------------------
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
    	bgBorder = activeBorder;

	if ((menuPtr->menuType == MENUBAR)
		&& ((menuPtr->postedCascade == NULL)
		|| (menuPtr->postedCascade != mePtr))) {
	    relief = TK_RELIEF_FLAT;
	} else {
	    Tk_GetReliefFromObj(NULL, menuPtr->activeReliefPtr, &relief);
	}

	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height,
		activeBorderWidth, relief);
    } else {
	Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height,
		0, TK_RELIEF_FLAT);







|

>







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
    	bgBorder = activeBorder;

	if ((menuPtr->menuType == MENUBAR)
		&& ((menuPtr->postedCascade == NULL)
		|| (menuPtr->postedCascade != mePtr))) {
	    relief = TK_RELIEF_FLAT;
	} else {
	    relief = TK_RELIEF_RAISED;
	}

	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height,
		activeBorderWidth, relief);
    } else {
	Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height,
		0, TK_RELIEF_FLAT);
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
static void
DrawMenuEntryAccelerator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The precalculated gc to draw with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    Tk_3DBorder activeBorder,	/* The border for an active item */
    Tk_3DBorder bgBorder,	/* The background border */
    int x,			/* Left coordinate of entry rect */
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];







|

<







479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
static void
DrawMenuEntryAccelerator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The precalculated gc to draw with */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    Tk_3DBorder activeBorder,	/* The border for an active item */

    int x,			/* Left coordinate of entry rect */
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    if ((mePtr->type == CASCADE_ENTRY) && drawArrow) {
    	points[0].x = x + width - borderWidth - activeBorderWidth
		- CASCADE_ARROW_WIDTH;
    	points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + CASCADE_ARROW_HEIGHT;
    	points[2].x = points[0].x + CASCADE_ARROW_WIDTH;
    	points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d,
		(mePtr->state == ENTRY_ACTIVE) ? activeBorder : bgBorder,
		points, 3, DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr)
	    	? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

	if (menuPtr->menuType == MENUBAR) {
	    left += 5;
	}
	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
		mePtr->accelLength, left,
		(y + (height + fmPtr->ascent - fmPtr->descent) / 2));
    }
}

/*
 *----------------------------------------------------------------------







|





|
<
|



|

|




|







504
505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    if ((mePtr->type == CASCADE_ENTRY) && drawArrow) {
    	points[0].x = x + width - borderWidth - activeBorderWidth
	        - CASCADE_ARROW_WIDTH;
    	points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + CASCADE_ARROW_HEIGHT;
    	points[2].x = points[0].x + CASCADE_ARROW_WIDTH;
    	points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, 3,

		DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr)
	    	? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
	int left = x + mePtr->labelWidth + activeBorderWidth
	        + mePtr->indicatorSpace;

	if (menuPtr->menuType == MENUBAR) {
	    left += 5;
	}
    	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
		mePtr->accelLength, left,
		(y + (height + fmPtr->ascent - fmPtr->descent) / 2));
    }
}

/*
 *----------------------------------------------------------------------
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable to draw into */
    Tk_3DBorder border,		/* The background color */
    XColor *indicatorColor,	/* The color to draw indicators with */
    XColor *disableColor,	/* The color use use when disabled */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics of the font */
    int x,			/* The left of the entry rect */
    int y,			/* The top of the entry rect */
    TCL_UNUSED(int),			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    /*
     * Draw check-button indicator.
     */

    if ((mePtr->type == CHECK_BUTTON_ENTRY) && mePtr->indicatorOn) {







|
|


|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable to draw into */
    Tk_3DBorder border,		/* The background color */
    XColor *indicatorColor,	/* The color to draw indicators with */
    XColor *disableColor,	/* The color use use when disabled */
    Tk_Font tkfont,		/* The font to draw with */
    CONST Tk_FontMetrics *fmPtr,/* The font metrics of the font */
    int x,			/* The left of the entry rect */
    int y,			/* The top of the entry rect */
    int width,			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    /*
     * Draw check-button indicator.
     */

    if ((mePtr->type == CHECK_BUTTON_ENTRY) && mePtr->indicatorOn) {
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* The drawable we are using */
    TCL_UNUSED(GC),			/* The gc to draw into */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics from the font */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    Tk_3DBorder border;

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
	    TK_RELIEF_RAISED);
}

/*







|

|
|
|





>






|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are using */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The font to draw with */
    CONST Tk_FontMetrics *fmPtr,/* The font metrics from the font */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    Tk_3DBorder border;

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].x = width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
	    TK_RELIEF_RAISED);
}

/*
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
static void
DrawMenuEntryLabel(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are drawing. */
    Drawable d,			/* What we are drawing into. */
    GC gc,			/* The gc we are drawing into.*/
    Tk_Font tkfont,		/* The precalculated font. */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics. */
    int x,			/* Left edge. */
    int y,			/* Top edge. */
    int width,			/* width of entry. */
    int height)			/* height of entry. */
{
    int indicatorSpace = mePtr->indicatorSpace;
    int activeBorderWidth, leftEdge, imageHeight, imageWidth;







|







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
static void
DrawMenuEntryLabel(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are drawing. */
    Drawable d,			/* What we are drawing into. */
    GC gc,			/* The gc we are drawing into.*/
    Tk_Font tkfont,		/* The precalculated font. */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics. */
    int x,			/* Left edge. */
    int y,			/* Top edge. */
    int width,			/* width of entry. */
    int height)			/* height of entry. */
{
    int indicatorSpace = mePtr->indicatorSpace;
    int activeBorderWidth, leftEdge, imageHeight, imageWidth;
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
     */

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight);
	haveImage = 1;
    }
    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
	if (mePtr->labelLength > 0) {
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
	    textHeight = fmPtr->linespace;
	    haveText = 1;
	}
    }

    /*
     * Now work out what the relative positions are.
     */

    if (haveImage && haveText) {
	int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth);

	switch ((enum compound) mePtr->compound) {
	case COMPOUND_TOP:
	    textXOffset = (fullWidth - textWidth)/2;
	    textYOffset = imageHeight/2 + 2;
	    imageXOffset = (fullWidth - imageWidth)/2;
	    imageYOffset = -textHeight/2;
	    break;







<





|
<












<







697
698
699
700
701
702
703

704
705
706
707
708
709

710
711
712
713
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
     */

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight);
	haveImage = 1;
    }
    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
	if (mePtr->labelLength > 0) {
	    char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
	    textHeight = fmPtr->linespace;
	    haveText = 1;
	}
    }

    /*
     * Now work out what the relative positions are.
     */

    if (haveImage && haveText) {
	int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth);

	switch ((enum compound) mePtr->compound) {
	case COMPOUND_TOP:
	    textXOffset = (fullWidth - textWidth)/2;
	    textYOffset = imageHeight/2 + 2;
	    imageXOffset = (fullWidth - imageWidth)/2;
	    imageYOffset = -textHeight/2;
	    break;
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
		    imageWidth, imageHeight, d, leftEdge + imageXOffset,
		    (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset));
    	} else {
	    Tk_RedrawImage(mePtr->image, 0, 0, imageWidth,
		    imageHeight, d, leftEdge + imageXOffset,
		    (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset));
    	}
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	XCopyPlane(menuPtr->display, bitmap, d,	gc, 0, 0,
		(unsigned) imageWidth, (unsigned) imageHeight,
		leftEdge + imageXOffset,
		(int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1);
    }
    if ((mePtr->compound != COMPOUND_NONE) || !haveImage) {
	int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;

    	if (mePtr->labelLength > 0) {
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
		    mePtr->labelLength, leftEdge + textXOffset,
		    baseline + textYOffset);
	    DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		    x + textXOffset, y + textYOffset,
		    width, height);
    	}
    }

    if (mePtr->state == ENTRY_DISABLED) {
	if (menuPtr->disabledFgPtr == NULL) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
		    (unsigned) width, (unsigned) height);
	} else if ((mePtr->image != NULL)
		&& (menuPtr->disabledImageGC != NULL)) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
		    leftEdge + imageXOffset,
		    (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
    }
}







|











|















|







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
		    imageWidth, imageHeight, d, leftEdge + imageXOffset,
		    (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset));
    	} else {
	    Tk_RedrawImage(mePtr->image, 0, 0, imageWidth,
		    imageHeight, d, leftEdge + imageXOffset,
		    (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset));
    	}
    } else if (mePtr->bitmapPtr != None) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	XCopyPlane(menuPtr->display, bitmap, d,	gc, 0, 0,
		(unsigned) imageWidth, (unsigned) imageHeight,
		leftEdge + imageXOffset,
		(int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1);
    }
    if ((mePtr->compound != COMPOUND_NONE) || !haveImage) {
	int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;

    	if (mePtr->labelLength > 0) {
	    char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);

	    Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
		    mePtr->labelLength, leftEdge + textXOffset,
		    baseline + textYOffset);
	    DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		    x + textXOffset, y + textYOffset,
		    width, height);
    	}
    }

    if (mePtr->state == ENTRY_DISABLED) {
	if (menuPtr->disabledFgPtr == NULL) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
		    (unsigned) width, (unsigned) height);
	} else if ((mePtr->image != NULL)
		&& (menuPtr->disabledImageGC != None)) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
		    leftEdge + imageXOffset,
		    (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
    }
}
843
844
845
846
847
848
849
850
851
852
853
854
855
856




857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
static void
DrawMenuUnderline(
    TkMenu *menuPtr,		/* The menu to draw into */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x, int y,
    TCL_UNUSED(int), int height)
{
    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;





	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge, ch;
	    const char *label, *start, *end;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = start + TkUtfToUniChar(start, &ch);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }

	    Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, leftEdge,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    start - label, end - label);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen so that the top left corner of the
 *      specified entry is located at the point (x, y) in screen coordinates.
 *      If the entry parameter is negative, the upper left corner of the
 *      menu itself is placed at the point.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    int x, int y, int index)
{
    return TkpPostTearoffMenu(interp, menuPtr, x, y, index);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --
 *
 *	Posts a tearoff menu on the screen so that the top left corner of the
 *      specified entry is located at the point (x, y) in screen coordinates.
 *      If the index parameter is negative, the upper left corner of the menu
 *      itself is placed at the point.  On unix this is called when posting
 *      any menu.  Adjusts the menu's position so that it fits on the screen,
 *      and maps and raises the menu.
 *
 * Results:
 *	Returns a standard Tcl Error.
 *
 * Side effects:
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The root X,Y coordinates where the
				 * specified entry will be posted */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * 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.
     */

    Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
	&vRootWidth, &vRootHeight);
    vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
    if (x > vRootX + vRootWidth) {
	x = vRootX + vRootWidth;
    }
    if (x < vRootX) {
	x = vRootX;
    }
    vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
    if (y > vRootY + vRootHeight) {
	y = vRootY + vRootHeight;
    }
    if (y < vRootY) {
	y = vRootY;
    }
    Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
    if (!Tk_IsMapped(menuPtr->tkwin)) {
	Tk_MapWindow(menuPtr->tkwin);
    }
    TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetMenuSeparatorGeometry --
 *
 *	Gets the width and height of the indicator area of a menu.
 *
 * Results:
 *	widthPtr and heightPtr are set.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetMenuSeparatorGeometry(
    TCL_UNUSED(TkMenu *),		/* The menu we are measuring */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    *widthPtr = 0;
    *heightPtr = fmPtr->linespace;
}








|

|




>
>
>
>
|

|
|

|

|




















|
<
<
<














|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|
|
|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891



892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908































































































909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
static void
DrawMenuUnderline(
    TkMenu *menuPtr,		/* The menu to draw into */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x, int y,
    int width, int height)
{
    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	/*
	 * Do the unicode call just to prevent overruns.
	 */

	Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge;
	    CONST char *label, *start, *end;

	    label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = Tcl_UtfNext(start);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }

	    Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, leftEdge,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    start - label, end - label);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen



 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    int x, int y)
{
    return TkPostTearoffMenu(interp, menuPtr, x, y);































































































}

/*
 *----------------------------------------------------------------------
 *
 * GetMenuSeparatorGeometry --
 *
 *	Gets the width and height of the indicator area of a menu.
 *
 * Results:
 *	widthPtr and heightPtr are set.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetMenuSeparatorGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    *widthPtr = 0;
    *heightPtr = fmPtr->linespace;
}

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
 *
 *----------------------------------------------------------------------
 */

static void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
	*widthPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
	*widthPtr = Tk_TextWidth(tkfont, "W", 1);
    }
}







|

|



|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
 *
 *----------------------------------------------------------------------
 */

static void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    if (menuPtr->menuType != MASTER_MENU) {
	*heightPtr = 0;
	*widthPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
	*widthPtr = Tk_TextWidth(tkfont, "W", 1);
    }
}
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098


1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, i, j, x, y, currentRowHeight, maxWidth;
    int maxWindowWidth, lastRowBreak, lastEntry;
    int activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }



    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    maxWidth = 0;
    if (menuPtr->numEntries == 0) {
	height = 0;
    } else {
	int borderWidth;

	maxWindowWidth = Tk_Width(menuPtr->tkwin);
	if (maxWindowWidth == 1) {
	    maxWindowWidth = 0x7FFFFFF;
	}
	currentRowHeight = 0;
	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		&borderWidth);
	x = y = borderWidth;
	lastRowBreak = 0;

	/*
	 * On the Mac especially, getting font metrics can be quite slow, so
	 * we want to do it intelligently. We are going to precalculate them
	 * and pass them down to all of the measuring and drawing routines.
	 * We will measure the font metrics of the menu once, and if an entry
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);

	for (i = 0; i < (int)menuPtr->numEntries; i++) {
	    mePtr = menuPtr->entries[i];
	    mePtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    if (mePtr->fontPtr != NULL) {
		tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
		Tk_GetFontMetrics(tkfont, &entryMetrics);
		fmPtr = &entryMetrics;
	    } else {







|






>
>










|










|








|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, i, j, x, y, currentRowHeight, maxWidth;
    int maxWindowWidth, lastRowBreak, lastEntry;
    int borderWidth, activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    maxWidth = 0;
    if (menuPtr->numEntries == 0) {
	height = 0;
    } else {
	int borderWidth;

	maxWindowWidth = Tk_Width(menuPtr->tkwin);
	if (maxWindowWidth == 1) {
	    maxWindowWidth = 0x7ffffff;
	}
	currentRowHeight = 0;
	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		&borderWidth);
	x = y = borderWidth;
	lastRowBreak = 0;

	/*
	 * On the Mac especially, getting font metrics can be quite slow, so
	 * we want to do it intelligently. We are going to precalculate them
	 * and pass them down to all of the measureing and drawing routines.
	 * We will measure the font metrics of the menu once, and if an entry
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);

	for (i = 0; i < menuPtr->numEntries; i++) {
	    mePtr = menuPtr->entries[i];
	    mePtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    if (mePtr->fontPtr != NULL) {
		tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
		Tk_GetFontMetrics(tkfont, &entryMetrics);
		fmPtr = &entryMetrics;
	    } else {
1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
		    mePtr->width += width;
		}
		mePtr->width += 2 * activeBorderWidth + 10;
	    }
	    if (mePtr->entryFlags & ENTRY_HELP_MENU) {
		helpMenuIndex = i;
	    } else if (x + mePtr->width + borderWidth > maxWindowWidth) {

		if (i == lastRowBreak) {
		    mePtr->y = y;
		    mePtr->x = x;
		    lastRowBreak++;
		    y += mePtr->height;
		    currentRowHeight = 0;
		} else {
		    x = borderWidth;
		    for (j = lastRowBreak; j < i; j++) {
			menuPtr->entries[j]->y = y + currentRowHeight
				- menuPtr->entries[j]->height;
			menuPtr->entries[j]->x = x;
			x += menuPtr->entries[j]->width;
		    }
		    lastRowBreak = i;
		    y += currentRowHeight;
		    currentRowHeight = mePtr->height;
		}







>










|







1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
		    mePtr->width += width;
		}
		mePtr->width += 2 * activeBorderWidth + 10;
	    }
	    if (mePtr->entryFlags & ENTRY_HELP_MENU) {
		helpMenuIndex = i;
	    } else if (x + mePtr->width + borderWidth > maxWindowWidth) {

		if (i == lastRowBreak) {
		    mePtr->y = y;
		    mePtr->x = x;
		    lastRowBreak++;
		    y += mePtr->height;
		    currentRowHeight = 0;
		} else {
		    x = borderWidth;
		    for (j = lastRowBreak; j < i; j++) {
			menuPtr->entries[j]->y = y + currentRowHeight
			        - menuPtr->entries[j]->height;
			menuPtr->entries[j]->x = x;
			x += menuPtr->entries[j]->width;
		    }
		    lastRowBreak = i;
		    y += currentRowHeight;
		    currentRowHeight = mePtr->height;
		}
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
	    lastEntry--;
	}
	if ((lastEntry >= 0) && (x + menuPtr->entries[lastEntry]->width
		+ borderWidth > maxWidth)) {
	    maxWidth = x + menuPtr->entries[lastEntry]->width + borderWidth;
	}
	x = borderWidth;
	for (j = lastRowBreak; j < (int)menuPtr->numEntries; j++) {
	    if (j == helpMenuIndex) {
		continue;
	    }
	    menuPtr->entries[j]->y = y + currentRowHeight
		    - menuPtr->entries[j]->height;
	    menuPtr->entries[j]->x = x;
	    x += menuPtr->entries[j]->width;







|







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
	    lastEntry--;
	}
	if ((lastEntry >= 0) && (x + menuPtr->entries[lastEntry]->width
		+ borderWidth > maxWidth)) {
	    maxWidth = x + menuPtr->entries[lastEntry]->width + borderWidth;
	}
	x = borderWidth;
	for (j = lastRowBreak; j < menuPtr->numEntries; j++) {
	    if (j == helpMenuIndex) {
		continue;
	    }
	    menuPtr->entries[j]->y = y + currentRowHeight
		    - menuPtr->entries[j]->height;
	    menuPtr->entries[j]->x = x;
	    x += menuPtr->entries[j]->width;
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
 *
 *----------------------------------------------------------------------
 */

static void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The font we are drawing with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;

    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = x + width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}







|

|
|
|







|







|







1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
 *
 *----------------------------------------------------------------------
 */

static void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The font we are drawing with */
    CONST Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;

    if (menuPtr->menuType != MASTER_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
 *	Alt-key bindings.
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter to set. */
    TCL_UNUSED(Tk_BindingTable))
				/* The table to add to. */
{
    /*
     * Nothing to do.
     */
}








|
|







1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
 *	Alt-key bindings.
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    Tcl_Interp *interp,		/* The interpreter to set. */
    Tk_BindingTable bindingTable)
				/* The table to add to. */
{
    /*
     * Nothing to do.
     */
}

1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
 *	Will set the ENTRY_HELP_MENU flag appropriately.
 *
 *----------------------------------------------------------------------
 */

static void
SetHelpMenu(
    TkMenu *menuPtr)		/* The menu we are checking */
{
    TkMenuEntry *cascadeEntryPtr;
    int useMotifHelp = 0;
    const char *option = NULL;
    if (menuPtr->tkwin) {
	option = Tk_GetOption(menuPtr->tkwin, "useMotifHelp", "UseMotifHelp");
	if (option != NULL) {
	    Tcl_GetBoolean(NULL, option, &useMotifHelp);
	}
    }

    if (!useMotifHelp) {
	return;
    }

    for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr != NULL;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if ((cascadeEntryPtr->menuPtr->menuType == MENUBAR)
		&& (cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin != NULL)
		&& (menuPtr->mainMenuPtr->tkwin != NULL)) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    char *helpMenuName = (char *)ckalloc(strlen(Tk_PathName(
		    mainMenuPtr->tkwin)) + strlen(".help") + 1);

	    strcpy(helpMenuName, Tk_PathName(mainMenuPtr->tkwin));
	    strcat(helpMenuName, ".help");
	    if (strcmp(helpMenuName,
		    Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		cascadeEntryPtr->entryFlags |= ENTRY_HELP_MENU;
	    } else {
		cascadeEntryPtr->entryFlags &= ~ENTRY_HELP_MENU;
	    }
	    ckfree(helpMenuName);
	}
    }







|



















|
|
|
|
|

|


|







1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
 *	Will set the ENTRY_HELP_MENU flag appropriately.
 *
 *----------------------------------------------------------------------
 */

static void
SetHelpMenu(
     TkMenu *menuPtr)		/* The menu we are checking */
{
    TkMenuEntry *cascadeEntryPtr;
    int useMotifHelp = 0;
    const char *option = NULL;
    if (menuPtr->tkwin) {
	option = Tk_GetOption(menuPtr->tkwin, "useMotifHelp", "UseMotifHelp");
	if (option != NULL) {
	    Tcl_GetBoolean(NULL, option, &useMotifHelp);
	}
    }

    if (!useMotifHelp) {
	return;
    }

    for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr != NULL;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if ((cascadeEntryPtr->menuPtr->menuType == MENUBAR)
		&& (cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin != NULL)
		&& (menuPtr->masterMenuPtr->tkwin != NULL)) {
	    TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
	    char *helpMenuName = ckalloc(strlen(Tk_PathName(
		    masterMenuPtr->tkwin)) + strlen(".help") + 1);

	    strcpy(helpMenuName, Tk_PathName(masterMenuPtr->tkwin));
	    strcat(helpMenuName, ".help");
	    if (strcmp(helpMenuName,
		    Tk_PathName(menuPtr->masterMenuPtr->tkwin)) == 0) {
		cascadeEntryPtr->entryFlags |= ENTRY_HELP_MENU;
	    } else {
		cascadeEntryPtr->entryFlags &= ~ENTRY_HELP_MENU;
	    }
	    ckfree(helpMenuName);
	}
    }
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
 *	X Server commands are executed to display the menu entry.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TkMenuEntry *mePtr,		/* The entry to draw */
    Drawable d,			/* What to draw into */
    Tk_Font tkfont,		/* Precalculated font for menu */
    const Tk_FontMetrics *menuMetricsPtr,
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. */

{
    GC gc, indicatorGC;
    XColor *indicatorColor, *disableColor = NULL;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
    int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
    int adjustedY = y + padY;
    int adjustedHeight = height - 2 * padY;

    /*
     * Choose the gc for drawing the foreground part of the entry.







|
|
|
|
|
|
|
|
|
|
|
|
>





|







1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
 *	X Server commands are executed to display the menu entry.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TkMenuEntry *mePtr,		    /* The entry to draw */
    Drawable d,			    /* What to draw into */
    Tk_Font tkfont,		    /* Precalculated font for menu */
    CONST Tk_FontMetrics *menuMetricsPtr,
				    /* Precalculated metrics for menu */
    int x,			    /* X-coordinate of topleft of entry */
    int y,			    /* Y-coordinate of topleft of entry */
    int width,			    /* Width of the entry rectangle */
    int height,			    /* Height of the current rectangle */
    int strictMotif,		    /* Boolean flag */
    int drawArrow)		    /* Whether or not to draw the cascade
				     * arrow for cascade items. Only applies
				     * to Windows. */
{
    GC gc, indicatorGC;
    XColor *indicatorColor, *disableColor = NULL;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    CONST Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
    int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
    int adjustedY = y + padY;
    int adjustedHeight = height - 2 * padY;

    /*
     * Choose the gc for drawing the foreground part of the entry.
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	    if (cascadeEntryPtr->namePtr != NULL) {
		const char *name = Tcl_GetString(cascadeEntryPtr->namePtr);

		if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
		    if (cascadeEntryPtr->state == ENTRY_DISABLED) {
			parentDisabled = 1;
		    }
		    break;
    	    	}







|







1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	    if (cascadeEntryPtr->namePtr != NULL) {
		char *name = Tcl_GetString(cascadeEntryPtr->namePtr);

		if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
		    if (cascadeEntryPtr->state == ENTRY_DISABLED) {
			parentDisabled = 1;
		    }
		    break;
    	    	}
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
    } else if (mePtr->type == TEAROFF_ENTRY) {
	DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
    } else {
	DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
	DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		activeBorder, bgBorder, x, adjustedY, width, adjustedHeight,
		drawArrow);
	if (!mePtr->hideMargin) {
	    if (mePtr->state == ENTRY_ACTIVE) {
		bgBorder = activeBorder;
	    }
	    DrawMenuEntryIndicator(menuPtr, mePtr, d, bgBorder, indicatorColor,
		    disableColor, tkfont, fmPtr, x, adjustedY, width,
		    adjustedHeight);







|
<







1433
1434
1435
1436
1437
1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
    } else if (mePtr->type == TEAROFF_ENTRY) {
	DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
    } else {
	DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
	DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);

	if (!mePtr->hideMargin) {
	    if (mePtr->state == ENTRY_ACTIVE) {
		bgBorder = activeBorder;
	    }
	    DrawMenuEntryIndicator(menuPtr, mePtr, d, bgBorder, indicatorColor,
		    disableColor, tkfont, fmPtr, x, adjustedY, width,
		    adjustedHeight);
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
 *----------------------------------------------------------------------
 */

static void
GetMenuLabelGeometry(
    TkMenuEntry *mePtr,		/* The entry we are computing */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    int *widthPtr,		/* The resulting width of the label portion */
    int *heightPtr)		/* The resulting height of the label
				 * portion */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    int haveImage = 0;

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

    	Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
	haveImage = 1;
    } else {
	*heightPtr = 0;
	*widthPtr = 0;
    }

    if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
	/*
	 * We don't care about the text in this case.
	 */
    } else {
	/*
	 * Either it is compound or we don't have an image.
	 */

    	if (mePtr->labelPtr != NULL) {
	    int textWidth;
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);

	    if ((mePtr->compound != COMPOUND_NONE) && haveImage) {
		switch ((enum compound) mePtr->compound) {
		case COMPOUND_TOP:
		case COMPOUND_BOTTOM:
		    if (textWidth > *widthPtr) {
			*widthPtr = textWidth;
		    }







|












<


















|
<

>







1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485

1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504

1505
1506
1507
1508
1509
1510
1511
1512
1513
 *----------------------------------------------------------------------
 */

static void
GetMenuLabelGeometry(
    TkMenuEntry *mePtr,		/* The entry we are computing */
    Tk_Font tkfont,		/* The precalculated font */
    CONST Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    int *widthPtr,		/* The resulting width of the label portion */
    int *heightPtr)		/* The resulting height of the label
				 * portion */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    int haveImage = 0;

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

    	Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
	haveImage = 1;
    } else {
	*heightPtr = 0;
	*widthPtr = 0;
    }

    if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
	/*
	 * We don't care about the text in this case.
	 */
    } else {
	/*
	 * Either it is compound or we don't have an image.
	 */

    	if (mePtr->labelPtr != NULL) {
	    int textWidth;
	    char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);

	    if ((mePtr->compound != COMPOUND_NONE) && haveImage) {
		switch ((enum compound) mePtr->compound) {
		case COMPOUND_TOP:
		case COMPOUND_BOTTOM:
		    if (textWidth > *widthPtr) {
			*widthPtr = textWidth;
		    }
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);

    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);







|







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812

1813
1814
1815
1816
1817
1818
1819
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > accelWidth) {
	    	accelWidth = width;
	    }

	    GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, fmPtr,
		    &width, &height);
	    if (height > mePtr->height) {
	    	mePtr->height = height;
	    }
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > indicatorSpace) {
	    	indicatorSpace = width;
	    }

	    mePtr->height += 2 * activeBorderWidth + MENU_DIVIDER_HEIGHT;
    	}
	mePtr->y = y;
	y += mePtr->height;
	if (y > windowHeight) {
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < (int)menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + borderWidth;

    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */








|
|












|









|








|
>







1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > accelWidth) {
	    	accelWidth = width;
	    }

	    GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont,
	    	    fmPtr, &width, &height);
	    if (height > mePtr->height) {
	    	mePtr->height = height;
	    }
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > indicatorSpace) {
	    	indicatorSpace = width;
	    }

	    mePtr->height += 2 * activeBorderWidth + MENU_DIVIDER_HEIGHT;
    	}
        mePtr->y = y;
	y += mePtr->height;
	if (y > windowHeight) {
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + 2 * borderWidth;

    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */

1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    TCL_UNUSED(Tcl_Interp *),	/* The interp the menu lives in. */
    TCL_UNUSED(const char *))	/* The name of the menu to reconfigure. */
{
    /*
     * Nothing to do.
     */
}

/*







|
|







1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    Tcl_Interp *interp,		/* The interp the menu lives in. */
    char *menuName)		/* The name of the menu to reconfigure. */
{
    /*
     * Nothing to do.
     */
}

/*

Changes to unix/tkUnixMenubu.c.

9
10
11
12
13
14
15











16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 * 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"













/*
 *----------------------------------------------------------------------
 *
 * TkpCreateMenuButton --
 *
 *	Allocate a new TkMenuButton structure.
 *
 * Results:
 *	Returns a newly allocated TkMenuButton structure.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

TkMenuButton *
TkpCreateMenuButton(
    TCL_UNUSED(Tk_Window))
{
    return (TkMenuButton *)ckalloc(sizeof(TkMenuButton));
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>
>
>
>
>
>
>












|






|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 * 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"

/*
 * The structure below defines menubutton class behavior by means of functions
 * that can be invoked from generic window code.
 */

Tk_ClassProcs tkpMenubuttonClass = {
    sizeof(Tk_ClassProcs),	/* size */
    TkMenuButtonWorldChanged,	/* worldChangedProc */
    NULL,
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateMenuButton --
 *
 *	Allocate a new TkMenuButton structure.
 *
 * Results:
 *	Returns a newly allocated TkMenuButton structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkMenuButton *
TkpCreateMenuButton(
    Tk_Window tkwin)
{
    return (TkMenuButton *)ckalloc(sizeof(TkMenuButton));
}

/*
 *----------------------------------------------------------------------
 *
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization needed only to stop compiler
				 * warning. */
    int y = 0;
    Tk_Window tkwin = mbPtr->tkwin;
    int fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int imageWidth, imageHeight;
    int imageXOffset, imageYOffset;
    int width = 0, height = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well */







|






|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization needed only to stop compiler
				 * warning. */
    int y = 0;
    register Tk_Window tkwin = mbPtr->tkwin;
    int fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int imageWidth, imageHeight;
    int imageXOffset, imageYOffset;
    int width = 0, height = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well */
276
277
278
279
280
281
282


283
284
285
286
287
288
289
	Tk_Draw3DRectangle(tkwin, pixmap, border,
		mbPtr->highlightWidth, mbPtr->highlightWidth,
		Tk_Width(tkwin) - 2*mbPtr->highlightWidth,
		Tk_Height(tkwin) - 2*mbPtr->highlightWidth,
		mbPtr->borderWidth, mbPtr->relief);
    }
    if (mbPtr->highlightWidth != 0) {


	if (mbPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);
	}
	Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);
    }







>
>







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
	Tk_Draw3DRectangle(tkwin, pixmap, border,
		mbPtr->highlightWidth, mbPtr->highlightWidth,
		Tk_Width(tkwin) - 2*mbPtr->highlightWidth,
		Tk_Height(tkwin) - 2*mbPtr->highlightWidth,
		mbPtr->borderWidth, mbPtr->relief);
    }
    if (mbPtr->highlightWidth != 0) {
	GC gc;

	if (mbPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);
	}
	Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);
    }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TkMenuButton *mbPtr)
{
    (void)mbPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
 *







<







328
329
330
331
332
333
334

335
336
337
338
339
340
341
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TkMenuButton *mbPtr)
{

}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
 *

Changes to unix/tkUnixPort.h.

13
14
15
16
17
18
19






20







21
22
23
24

25



26
27



28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53

54
55
56
57
58
59
60
61
 */

#ifndef _UNIXPORT
#define _UNIXPORT

#define __UNIX__ 1







#include <stdio.h>







#include <pwd.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>

#include <ctype.h>



#include <math.h>
#include <string.h>



#include <limits.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif

#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)

#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xresource.h>







>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
|

>
|
>
>
>

|
>
>
>
|
>
|














|

|





>
|
<
>
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
 */

#ifndef _UNIXPORT
#define _UNIXPORT

#define __UNIX__ 1

/*
 * Macro to use instead of "void" for arguments that must have
 * type "void *" in ANSI C;  maps them to type "char *" in
 * non-ANSI systems.  This macro may be used in some of the include
 * files below, which is why it is defined here.
 */

#ifndef VOID
#   ifdef __STDC__
#       define VOID void
#   else
#       define VOID char
#   endif
#endif

#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifndef NO_LIMITS_H
#   include <limits.h>
#else
#   include "../compat/limits.h"
#endif
#include <math.h>
#include <pwd.h>
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#       include <sys/time.h>
#   else
#       include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#ifndef NO_UNISTD_H
#   include <unistd.h>

#else
#   include "../compat/unistd.h"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xresource.h>
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121












122
123
124
125
126
127
128
 * Define "NBBY" (number of bits per byte) if it's not already defined.
 */

#ifndef NBBY
#   define NBBY 8
#endif


#include "tkIntXlibDecls.h"
#define UINT unsigned int
#define HWND void *
#define HDC void *
#define HINSTANCE void *
#define COLORREF void *
#define HMENU void *
#define TkWinDCState void
#define HPALETTE void *
#define WNDPROC void *
#define WPARAM void *
#define LPARAM void *
#define LRESULT void *













/*
 * Supply macros for seek offsets, if they're not already provided by
 * an include file.
 */

#ifndef SEEK_SET







>
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * Define "NBBY" (number of bits per byte) if it's not already defined.
 */

#ifndef NBBY
#   define NBBY 8
#endif

#ifdef __CYGWIN__
#   include "tkIntXlibDecls.h"
#   define UINT unsigned int
#   define HWND void *
#   define HDC void *
#   define HINSTANCE void *
#   define COLORREF void *
#   define HMENU void *
#   define TkWinDCState void
#   define HPALETTE void *
#   define WNDPROC void *
#   define WPARAM void *
#   define LPARAM void *
#   define LRESULT void *

#else /* !__CYGWIN__ */
    /*
     * The TkPutImage macro strips off the color table information, which isn't
     * needed for X.
     */

#   define TkPutImage(colors, ncolors, display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
		XPutImage(display, pixels, gc, image, srcx, srcy, destx, \
		desty, width, height);

#endif /* !__CYGWIN__ */

/*
 * Supply macros for seek offsets, if they're not already provided by
 * an include file.
 */

#ifndef SEEK_SET
170
171
172
173
174
175
176
177
178
179

180




181
182

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "%#08lx", (unsigned long) (w))
#endif

/*
 * Used by tkWindow.c
 */


#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)





#endif /* _UNIXPORT */







|
|
|
>
|
>
>
>
>


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "%#08lx", (unsigned long) (w))
#endif

/*
 * The following declaration is used to get access to a private Tcl interface
 * that is needed for portability reasons.
 *
 * Disabled for now to determined whether we really still need this.

#ifndef _TCLINT
#include <tclInt.h>
#endif
 */

#endif /* _UNIXPORT */

Changes to unix/tkUnixRFont.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89




90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
 */

#include "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>

#define MAX_CACHED_COLORS 16

typedef struct {
    XftFont *ftFont;
    XftFont *ft0Font;
    FcPattern *source;
    FcCharSet *charset;
    double angle;
} UnixFtFace;

typedef struct {
    XftColor color;
    int next;
} UnixFtColorList;

typedef struct {
    TkFont font;	    	/* Stuff used by generic font package. Must be
				 * first in structure. */
    UnixFtFace *faces;
    int nfaces;
    FcFontSet *fontset;
    FcPattern *pattern;

    Display *display;
    int screen;
    XftDraw *ftDraw;
    int ncolors;
    int firstColor;
    UnixFtColorList colors[MAX_CACHED_COLORS];
} UnixFtFont;

/*
 * Used to describe the current clipping box. Can't be passed normally because
 * the information isn't retrievable from the GC.
 */

typedef struct {
    Region clipRegion;		/* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
 *
 *	This procedure is called when an application is created. It
 *	initializes all the structures that are used by the

 *	platform-dependant code on a per application basis.
 *	Note that this is called before TkpInit() !
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */


static int utf8ToUcs4(const char *source, FcChar32 *c, int numBytes)
{
    if (numBytes >= 6) {
    	return TkUtfToUniChar(source, (int *)c);
    }
    return FcUtf8ToUcs4((const FcChar8 *)source, c, numBytes);
}

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{




    (void)mainPtr;

}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;

	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
	i = 0;
    }
    if ((angle == 0.0 && !fontPtr->faces[i].ft0Font) || (angle != 0.0 &&
	    (!fontPtr->faces[i].ftFont || fontPtr->faces[i].angle != angle))){
	FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);
	double s = sin(angle*PI/180.0), c = cos(angle*PI/180.0);
	FcMatrix mat;
	XftFont *ftFont;

	/*
	 * Initialize the matrix manually so this can compile with HP-UX cc
	 * (which does not allow non-constant structure initializers). [Bug
	 * 2978410]
	 */

	mat.xx = mat.yy = c;
	mat.xy = -(mat.yx = s);

	if (angle != 0.0) {
	    FcPatternAddMatrix(pat, FC_MATRIX, &mat);
	}
	ftFont = XftFontOpenPattern(fontPtr->display, pat);
	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail, but
	     * sometimes does anyway. Usual cause appears to be a
	     * misconfigured fontconfig installation; see [Bug 1090382]. Try a
	     * fallback:
	     */

	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
		    FC_FAMILY, FcTypeString, "sans",
		    FC_SIZE, FcTypeDouble, 12.0,
		    FC_MATRIX, FcTypeMatrix, &mat,
		    NULL);
	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail. Impossible to
	     * proceed at this point.
	     */

	    Tcl_Panic("Cannot find a usable font");
	}

	if (angle == 0.0) {
	    fontPtr->faces[i].ft0Font = ftFont;
	} else {
	    if (fontPtr->faces[i].ftFont) {
		XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	    }
	    fontPtr->faces[i].ftFont = ftFont;
	    fontPtr->faces[i].angle = angle;
	}
    }
    return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontAttributes --
 * 	Fill in TkFontAttributes from an XftFont.
 */

static void
GetTkFontAttributes(
    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    int weight, slant, pxsize;
    double size, ptsize;

    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = ptsize;
    } else if (XftPatternGetDouble(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = -ptsize;
    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = (double)-pxsize;
    } else {
	size = 12.0;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
	    &weight) != XftResultMatch) {
	weight = XFT_WEIGHT_MEDIUM;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
	    &slant) != XftResultMatch) {
	slant = XFT_SLANT_ROMAN;
    }

#ifdef DEBUG_FONTSEL
    printf("family %s size %d weight %d slant %d\n",
	    family, (int)size, weight, slant);
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    faPtr->size = size;
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = 0;
    faPtr->overstrike = 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontMetrics --
 * 	Fill in TkFontMetrics from an XftFont.
 */

static void
GetTkFontMetrics(
    XftFont *ftFont,
    TkFontMetrics *fmPtr)
{
    int spacing;

    if (XftPatternGetInteger(ftFont->pattern, XFT_SPACING, 0,
	    &spacing) != XftResultMatch) {







<
<


<


<


<
<
<
<
<











<
|
<







|





<
<
<
<
<
|
>
|
<
|
<
<
|
<
<
<
<
<
|
|
<
<
|
<
<
<
<





>
>
>
>
|
>





|
<






<










<
|
|
|
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|
|

<

|
|
<
|



|
|

<
|


<
|
<
<
<
|
|
<
<
<
<














|
<
|
|

|


|
<
<
<


|

|










|

|

















|
<







10
11
12
13
14
15
16


17
18

19
20

21
22





23
24
25
26
27
28
29
30
31
32
33

34

35
36
37
38
39
40
41
42
43
44
45
46
47





48
49
50

51


52





53
54


55




56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88

89
90
91


92
93













94
95
96
97
98
99
100

101
102
103

104
105
106
107
108
109
110

111
112
113

114



115
116




117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
 */

#include "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>



typedef struct {
    XftFont *ftFont;

    FcPattern *source;
    FcCharSet *charset;

} UnixFtFace;






typedef struct {
    TkFont font;	    	/* Stuff used by generic font package. Must be
				 * first in structure. */
    UnixFtFace *faces;
    int nfaces;
    FcFontSet *fontset;
    FcPattern *pattern;

    Display *display;
    int screen;
    XftDraw *ftDraw;

    XftColor color;

} UnixFtFont;

/*
 * Used to describe the current clipping box. Can't be passed normally because
 * the information isn't retrievable from the GC.
 */

typedef struct ThreadSpecificData {
    Region clipRegion;		/* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*





 * Package initialization:
 * 	Nothing to do here except register the fact that we're using Xft in
 * 	the TIP 59 configuration database.

 */








#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "ascii"


#endif





void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    static Tcl_Config cfg[] = {
	{ "fontsystem", "xft" },
	{ 0,0 }
    };

    Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4)

{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;

	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
	i = 0;
    }

    if (!fontPtr->faces[i].ftFont) {
	FcPattern *pat = FcFontRenderPrepare(0,
	    fontPtr->pattern, fontPtr->faces[i].source);


	XftFont *ftFont = XftFontOpenPattern(fontPtr->display, pat);














	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail,
	     * but sometimes does anyway.  Usual cause appears to be
	     * a misconfigured fontconfig installation; see [Bug 1090382].
	     * Try a fallback:
	     */

	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
			FC_FAMILY, FcTypeString, "sans",
			FC_SIZE, FcTypeDouble, 12.0,

			NULL);
	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail.
	     * Impossible to proceed at this point.
	     */

	    Tcl_Panic("Cannot find a usable font.");
	}


	fontPtr->faces[i].ftFont = ftFont;



    }
    return fontPtr->faces[i].ftFont;




}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontAttributes --
 * 	Fill in TkFontAttributes from an XftFont.
 */

static void
GetTkFontAttributes(
    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    char *family = "Unknown", **familyPtr = &family;

    int weight, slant, size, pxsize;
    double ptsize;

    (void)XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = (int)ptsize;



    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = -pxsize;
    } else {
	size = 12;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
	    &weight) != XftResultMatch) {
	weight = XFT_WEIGHT_MEDIUM;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
	    &slant) != XftResultMatch) {
	slant = XFT_SLANT_ROMAN;
    }

#if DEBUG_FONTSEL
    printf("family %s size %d weight %d slant %d\n",
	    family, size, weight, slant);
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    faPtr->size = size;
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = 0;
    faPtr->overstrike = 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontMetrics --
 * 	Fill in TkFontMetrics from an XftFont.
 */

static void GetTkFontMetrics(

    XftFont *ftFont,
    TkFontMetrics *fmPtr)
{
    int spacing;

    if (XftPatternGetInteger(ftFont->pattern, XFT_SPACING, 0,
	    &spacing) != XftResultMatch) {
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
 *
 * Results:
 * 	On error, frees fontPtr and returns NULL, otherwise returns fontPtr.
 *
 *---------------------------------------------------------------------------
 */

static void
FinishedWithFont(
    UnixFtFont *fontPtr);

static int
InitFontErrorProc(
    ClientData clientData,
    TCL_UNUSED(XErrorEvent *))
{
    int *errorFlagPtr = (int *)clientData;

    if (errorFlagPtr != NULL) {
	*errorFlagPtr = 1;
    }
    return 0;
}

static UnixFtFont *
InitFont(
    Tk_Window tkwin,
    FcPattern *pattern,
    UnixFtFont *fontPtr)
{
    FcFontSet *set;
    FcCharSet *charset;
    FcResult result;
    XftFont *ftFont;
    int i, iWidth, errorFlag;
    Tk_ErrorHandler handler;

    if (!fontPtr) {
	fontPtr = (UnixFtFont *)ckalloc(sizeof(UnixFtFont));
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);

    /*
     * Generate the list of fonts
     */

    set = FcFontSort(0, pattern, FcTrue, NULL, &result);
    if (!set || set->nfont == 0) {
	ckfree(fontPtr);
	return NULL;
    }

    fontPtr->fontset = set;
    fontPtr->pattern = pattern;
    fontPtr->faces = (UnixFtFace *)ckalloc(set->nfont * sizeof(UnixFtFace));
    fontPtr->nfaces = set->nfont;

    /*
     * Fill in information about each returned font
     */

    for (i = 0; i < set->nfont; i++) {
	fontPtr->faces[i].ftFont = 0;
	fontPtr->faces[i].ft0Font = 0;
	fontPtr->faces[i].source = set->fonts[i];
	if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
		&charset) == FcResultMatch) {
	    fontPtr->faces[i].charset = FcCharSetCopy(charset);
	} else {
	    fontPtr->faces[i].charset = 0;
	}
	fontPtr->faces[i].angle = 0.0;
    }

    fontPtr->display = Tk_Display(tkwin);
    fontPtr->screen = Tk_ScreenNumber(tkwin);
    fontPtr->ftDraw = 0;
    fontPtr->ncolors = 0;

    fontPtr->firstColor = -1;



    /*
     * Fill in platform-specific fields of TkFont.
     */

    errorFlag = 0;
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
		    -1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
    ftFont = GetFont(fontPtr, 0, 0.0);
    if ((ftFont == NULL) || errorFlag) {
	Tk_DeleteErrorHandler(handler);
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);
    Tk_DeleteErrorHandler(handler);
    if (errorFlag) {
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }

    /*
     * Fontconfig can't report any information about the position or thickness
     * of underlines or overstrikes. Thus, we use some defaults that are
     * hacked around from backup defaults in tkUnixFont.c, which are in turn
     * based on recommendations in the X manual. The comments from that file
     * leading to these computations were:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|
<


|










|
|





|








<







<





|
>
|
>
>




<
<
<
<
|
<
<
<
<
<
<



<
<
<
<
<
<







198
199
200
201
202
203
204

















205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265




266






267
268
269






270
271
272
273
274
275
276
 *
 * Results:
 * 	On error, frees fontPtr and returns NULL, otherwise returns fontPtr.
 *
 *---------------------------------------------------------------------------
 */


















static UnixFtFont *
InitFont(
    Tk_Window tkwin,
    FcPattern *pattern,
    UnixFtFont *fontPtr)
{
    FcFontSet *set;
    FcCharSet *charset;
    FcResult result;
    XftFont *ftFont;
    int i;


    if (!fontPtr) {
	fontPtr = (UnixFtFont *) ckalloc(sizeof(UnixFtFont));
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);

    /*
     * Generate the list of fonts
     */

    set = FcFontSort(0, pattern, FcTrue, NULL, &result);
    if (!set) {
	ckfree((char *)fontPtr);
	return NULL;
    }

    fontPtr->fontset = set;
    fontPtr->pattern = pattern;
    fontPtr->faces = (UnixFtFace *) ckalloc(set->nfont * sizeof(UnixFtFace));
    fontPtr->nfaces = set->nfont;

    /*
     * Fill in information about each returned font
     */

    for (i = 0; i < set->nfont; i++) {
	fontPtr->faces[i].ftFont = 0;

	fontPtr->faces[i].source = set->fonts[i];
	if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
		&charset) == FcResultMatch) {
	    fontPtr->faces[i].charset = FcCharSetCopy(charset);
	} else {
	    fontPtr->faces[i].charset = 0;
	}

    }

    fontPtr->display = Tk_Display(tkwin);
    fontPtr->screen = Tk_ScreenNumber(tkwin);
    fontPtr->ftDraw = 0;
    fontPtr->color.color.red = 0;
    fontPtr->color.color.green = 0;
    fontPtr->color.color.blue = 0;
    fontPtr->color.color.alpha = 0xffff;
    fontPtr->color.pixel = 0xffffffff;

    /*
     * Fill in platform-specific fields of TkFont.
     */




    ftFont = GetFont(fontPtr, 0);






    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);







    /*
     * Fontconfig can't report any information about the position or thickness
     * of underlines or overstrikes. Thus, we use some defaults that are
     * hacked around from backup defaults in tkUnixFont.c, which are in turn
     * based on recommendations in the X manual. The comments from that file
     * leading to these computations were:
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
     *
     * Note that nothing corresponding to *either* property is reported by
     * Fontconfig at all. [Bug 1961455]
     */

    {
	TkFont *fPtr = &fontPtr->font;


	fPtr->underlinePos = fPtr->fm.descent / 2;
	handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
			-1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
	errorFlag = 0;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	Tk_DeleteErrorHandler(handler);
	if (errorFlag) {
	    FinishedWithFont(fontPtr);
	    ckfree(fontPtr);
	    return NULL;
	}
	fPtr->underlineHeight = iWidth / 3;
	if (fPtr->underlineHeight == 0) {
	    fPtr->underlineHeight = 1;
	}
	if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) {
	    fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos;
	    if (fPtr->underlineHeight == 0) {







>


<
<
<

<
<
<
<
<
<







285
286
287
288
289
290
291
292
293
294



295






296
297
298
299
300
301
302
     *
     * Note that nothing corresponding to *either* property is reported by
     * Fontconfig at all. [Bug 1961455]
     */

    {
	TkFont *fPtr = &fontPtr->font;
	int iWidth;

	fPtr->underlinePos = fPtr->fm.descent / 2;



	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);






	fPtr->underlineHeight = iWidth / 3;
	if (fPtr->underlineHeight == 0) {
	    fPtr->underlineHeight = 1;
	}
	if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) {
	    fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos;
	    if (fPtr->underlineHeight == 0) {
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463

static void
FinishedWithFont(
    UnixFtFont *fontPtr)
{
    Display *display = fontPtr->display;
    int i;
    Tk_ErrorHandler handler =
	    Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

    for (i = 0; i < fontPtr->nfaces; i++) {
	if (fontPtr->faces[i].ftFont) {
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	}
	if (fontPtr->faces[i].ft0Font) {
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);
	}
	if (fontPtr->faces[i].charset) {
	    FcCharSetDestroy(fontPtr->faces[i].charset);
	}
    }
    if (fontPtr->faces) {
	ckfree(fontPtr->faces);
    }
    if (fontPtr->pattern) {
	FcPatternDestroy(fontPtr->pattern);
    }
    if (fontPtr->ftDraw) {
	XftDrawDestroy(fontPtr->ftDraw);
    }
    if (fontPtr->font.fid) {
	XUnloadFont(fontPtr->display, fontPtr->font.fid);
    }
    if (fontPtr->fontset) {
	FcFontSetDestroy(fontPtr->fontset);
    }
    Tk_DeleteErrorHandler(handler);
}

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    UnixFtFont *fontPtr;
    FcPattern *pattern;
#ifdef DEBUG_FONTSEL
    printf("TkpGetNativeFont %s\n", name);
#endif /* DEBUG_FONTSEL */

    pattern = XftXlfdParse(name, FcFalse, FcFalse);
    if (!pattern) {
	return NULL;
    }







|
|





<
<
<





|



















|



|







311
312
313
314
315
316
317
318
319
320
321
322
323
324



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

static void
FinishedWithFont(
    UnixFtFont *fontPtr)
{
    Display *display = fontPtr->display;
    int i;
    Tk_ErrorHandler handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL,
	    (ClientData) NULL);

    for (i = 0; i < fontPtr->nfaces; i++) {
	if (fontPtr->faces[i].ftFont) {
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	}



	if (fontPtr->faces[i].charset) {
	    FcCharSetDestroy(fontPtr->faces[i].charset);
	}
    }
    if (fontPtr->faces) {
	ckfree((char *)fontPtr->faces);
    }
    if (fontPtr->pattern) {
	FcPatternDestroy(fontPtr->pattern);
    }
    if (fontPtr->ftDraw) {
	XftDrawDestroy(fontPtr->ftDraw);
    }
    if (fontPtr->font.fid) {
	XUnloadFont(fontPtr->display, fontPtr->font.fid);
    }
    if (fontPtr->fontset) {
	FcFontSetDestroy(fontPtr->fontset);
    }
    Tk_DeleteErrorHandler(handler);
}

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST char *name)		/* Platform-specific font name. */
{
    UnixFtFont *fontPtr;
    FcPattern *pattern;
#if DEBUG_FONTSEL
    printf("TkpGetNativeFont %s\n", name);
#endif /* DEBUG_FONTSEL */

    pattern = XftXlfdParse(name, FcFalse, FcFalse);
    if (!pattern) {
	return NULL;
    }
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    XftPattern *pattern;
    int weight, slant;
    UnixFtFont *fontPtr;

#ifdef DEBUG_FONTSEL
    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
	    faPtr->size, faPtr->weight, faPtr->slant);
#endif /* DEBUG_FONTSEL */
    pattern = XftPatternCreate();
    if (faPtr->family) {
	XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
    }
    if (faPtr->size > 0.0) {
	XftPatternAddDouble(pattern, XFT_SIZE, faPtr->size);
    } else if (faPtr->size < 0.0) {
	XftPatternAddDouble(pattern, XFT_SIZE, TkFontGetPoints(tkwin, faPtr->size));
    } else {
	XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
    }
    switch (faPtr->weight) {
    case TK_FW_NORMAL:
    default:
	weight = XFT_WEIGHT_MEDIUM;







|






|







|
|
|
|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    XftPattern *pattern;
    int weight, slant;
    UnixFtFont *fontPtr;

#if DEBUG_FONTSEL
    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
	    faPtr->size, faPtr->weight, faPtr->slant);
#endif /* DEBUG_FONTSEL */
    pattern = XftPatternCreate();
    if (faPtr->family) {
	XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
    }
    if (faPtr->size > 0) {
	XftPatternAddDouble(pattern, XFT_SIZE, (double)faPtr->size);
    } else if (faPtr->size < 0) {
	XftPatternAddInteger(pattern, XFT_PIXEL_SIZE, -faPtr->size);
    } else {
	XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
    }
    switch (faPtr->weight) {
    case TK_FW_NORMAL:
    default:
	weight = XFT_WEIGHT_MEDIUM;
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
    Tcl_Obj *resultPtr;
    XftFontSet *list;
    int i;

    resultPtr = Tcl_NewListObj(0, NULL);

    list = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin),
		(char *) 0,		/* pattern elements */
		XFT_FAMILY, (char*) 0);	/* fields */
    for (i = 0; i < list->nfont; i++) {
	char *family, **familyPtr = &family;

	if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
		== XftResultMatch) {
	    Tcl_Obj *strPtr = Tcl_NewStringObj(family, -1);


	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
    }
    XftFontSetDestroy(list);

    Tcl_SetObjResult(interp, resultPtr);
}







|
|


<

|
<
|
>







488
489
490
491
492
493
494
495
496
497
498

499
500

501
502
503
504
505
506
507
508
509
    Tcl_Obj *resultPtr;
    XftFontSet *list;
    int i;

    resultPtr = Tcl_NewListObj(0, NULL);

    list = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin),
		(char*)0,		/* pattern elements */
		XFT_FAMILY, (char*)0);	/* fields */
    for (i = 0; i < list->nfont; i++) {
	char *family, **familyPtr = &family;

	if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
		== XftResultMatch)

	{
	    Tcl_Obj *strPtr = Tcl_NewStringObj(family, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
    }
    XftFontSetDestroy(list);

    Tcl_SetObjResult(interp, resultPtr);
}
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
TkpGetSubFonts(
    Tcl_Interp *interp,
    Tk_Font tkfont)
{
    Tcl_Obj *objv[3], *listPtr, *resultPtr;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    FcPattern *pattern;
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    const char *foundry = "Unknown";
    const char *const *foundryPtr = &foundry;
    const char *encoding = "Unknown";
    const char *const *encodingPtr = &encoding;
    int i;

    resultPtr = Tcl_NewListObj(0, NULL);

    for (i = 0; i < fontPtr->nfaces ; ++i) {
 	pattern = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);







|
<
|
<
|
<







525
526
527
528
529
530
531
532

533

534

535
536
537
538
539
540
541
TkpGetSubFonts(
    Tcl_Interp *interp,
    Tk_Font tkfont)
{
    Tcl_Obj *objv[3], *listPtr, *resultPtr;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    FcPattern *pattern;
    char *family = "Unknown", **familyPtr = &family;

    char *foundry = "Unknown", **foundryPtr = &foundry;

    char *encoding = "Unknown", **encodingPtr = &encoding;

    int i;

    resultPtr = Tcl_NewListObj(0, NULL);

    for (i = 0; i < fontPtr->nfaces ; ++i) {
 	pattern = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),	/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
				/* Actual font used to render the character */

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length







|

|






|










|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    Tcl_UniChar c,		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4);
				/* Actual font used to render the character */

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
				 * terminating character. */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;
    int clen, curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0, errorFlag = 0;
    Tk_ErrorHandler handler;
#ifdef DEBUG_FONTSEL
    char string[256];
    int len = 0;
#endif /* DEBUG_FONTSEL */

    handler = Tk_CreateErrorHandler(fontPtr->display,
	    -1, -1, -1, InitFontErrorProc, &errorFlag);
    curX = 0;
    curByte = 0;
    sawNonSpace = 0;
    while (numBytes > 0) {
	int unichar;

	clen = TkUtfToUniChar(source, &unichar);
	c = (FcChar32) unichar;

	if (clen <= 0) {
	    /*
	     * This can't happen (but see #1185640)
	     */

	    *lengthPtr = curX;







|
<
|




<
<




|

|
|







606
607
608
609
610
611
612
613

614
615
616
617
618


619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
				 * terminating character. */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;
    int clen, curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0;

#if DEBUG_FONTSEL
    char string[256];
    int len = 0;
#endif /* DEBUG_FONTSEL */



    curX = 0;
    curByte = 0;
    sawNonSpace = 0;
    while (numBytes > 0) {
	Tcl_UniChar unichar;

	clen = Tcl_UtfToUniChar(source, &unichar);
	c = (FcChar32)unichar;

	if (clen <= 0) {
	    /*
	     * This can't happen (but see #1185640)
	     */

	    *lengthPtr = curX;
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951

952








953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

974


975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999



1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#ifdef DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c, 0.0);

	if (!errorFlag) {
	    XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
	} else {
	    extents.xOff = 0;
	    errorFlag = 0;
	}

	newX = curX + extents.xOff;
	newByte = curByte + clen;
	if (maxLength >= 0 && newX > maxLength) {
	    if (flags & TK_PARTIAL_OK ||
		    (flags & TK_AT_LEAST_ONE && curByte == 0)) {
		curX = newX;
		curByte = newByte;
	    } else if (flags & TK_WHOLE_WORDS) {
		if ((flags & TK_AT_LEAST_ONE) && (termX == 0)) {
		    /*
		     * No space was seen before reaching the right
		     * of the allotted maxLength space, i.e. no word
		     * boundary. Return the string that fills the
		     * allotted space, without overfill.
		     * curX and curByte are already the right ones:
		     */
		} else {
		    curX = termX;
		    curByte = termByte;
		}
	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }
    Tk_DeleteErrorHandler(handler);
#ifdef DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
#endif /* DEBUG_FONTSEL */
    *lengthPtr = curX;
    return curByte;
}

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,
    const char *source,
    int numBytes,
    int rangeStart,
    int rangeLength,
    int maxLength,
    int flags,
    int *lengthPtr)
{
    (void) numBytes; /*unused*/

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * LookUpColor --
 *
 *	Convert a pixel value to an XftColor.  This can be slow due to the
 * need to call XQueryColor, which involves a server round-trip.  To
 * avoid that, a least-recently-used cache of up to MAX_CACHED_COLORS
 * is kept, in the form of a linked list.  The returned color is moved
 * to the front of the list, so repeatedly asking for the same one
 * should be fast.
 *
 * Results:
 *      A pointer to the XftColor structure for the requested color is
 * returned.
 *
 * Side effects:
 *      The converted color is stored in a cache in the UnixFtFont structure.  The cache
 * can hold at most MAX_CACHED_COLORS colors.  If no more slots are available, the least
 * recently used color is replaced with the new one.
 *----------------------------------------------------------------------
 */

static XftColor *
LookUpColor(Display *display,      /* Display to lookup colors on */
	    UnixFtFont *fontPtr,   /* Font to search for cached colors */
	    unsigned long pixel)   /* Pixel value to translate to XftColor */
{
    int i, last = -1, last2 = -1;
    XColor xcolor;

    for (i = fontPtr->firstColor;
	 i >= 0; last2 = last, last = i, i = fontPtr->colors[i].next) {

	if (pixel == fontPtr->colors[i].color.pixel) {
	    /*
	     * Color found in cache.  Move it to the front of the list and return it.
	     */
	    if (last >= 0) {
		fontPtr->colors[last].next = fontPtr->colors[i].next;
		fontPtr->colors[i].next = fontPtr->firstColor;
		fontPtr->firstColor = i;
	    }

	    return &fontPtr->colors[i].color;
	}
    }

    /*
     * Color wasn't found, so it needs to be added to the cache.
     * If a spare slot is available, it can be put there.  If not, last
     * will now point to the least recently used color, so replace that one.
     */

    if (fontPtr->ncolors < MAX_CACHED_COLORS) {
	last2 = -1;
	last = fontPtr->ncolors++;
    }

    /*
     * Translate the pixel value to a color.  Needs a server round-trip.
     */
    xcolor.pixel = pixel;
    XQueryColor(display, DefaultColormap(display, fontPtr->screen), &xcolor);

    fontPtr->colors[last].color.color.red = xcolor.red;
    fontPtr->colors[last].color.color.green = xcolor.green;
    fontPtr->colors[last].color.color.blue = xcolor.blue;
    fontPtr->colors[last].color.color.alpha = 0xFFFF;
    fontPtr->colors[last].color.pixel = pixel;

    /*
     * Put at the front of the list.
     */
    if (last2 >= 0) {
	fontPtr->colors[last2].next = fontPtr->colors[last].next;
    }
    fontPtr->colors[last].next = fontPtr->firstColor;
    fontPtr->firstColor = last;

    return &fontPtr->colors[last].color;
}

#define NUM_SPEC    1024

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }
    XGetGCValues(display, gc, GCForeground, &values);

    xftcolor = LookUpColor(display, fontPtr, values.foreground);








    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0) {
	XftFont *ftFont;
	FcChar32 c;

	clen = utf8ToUcs4(source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {

	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);


	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);

	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = x;
		specs[nspec].y = y;
		if (++nspec == NUM_SPEC) {
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    nspec = 0;
		}
	    }
	    x += metrics.xOff;
	    y += metrics.yOff;
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);



    }

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
    if (fontPtr->font.fa.underline != 0) {
	XFillRectangle(display, drawable, gc, xStart,
		y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
    if (fontPtr->font.fa.overstrike != 0) {
	y -= fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10;
	XFillRectangle(display, drawable, gc, xStart, y,
		(unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkDrawAngledChars --
 *
 *	Draw some characters at an angle. This would be simple code, except
 *	Xft has bugs with cumulative errors in character positioning which are
 *	caused by trying to perform all calculations internally with integers.
 *	So we have to do the work ourselves with floating-point math.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Target drawable is updated.
 *
 *---------------------------------------------------------------------------
 */

void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int xStart = x, yStart = y;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
#ifdef XFT_HAS_FIXED_ROTATED_PLACEMENT
    int clen, nglyph;
    FT_UInt glyphs[NUM_SPEC];
    XGlyphInfo metrics;
    XftFont *currentFtFont;
    int originX, originY;

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }

    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;

    while (numBytes > 0) {
	XftFont *ftFont;
	FcChar32 c;

	clen = utf8ToUcs4(source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	if (!ftFont) {
	    continue;
	}

	if (ftFont != currentFtFont || nglyph == NUM_SPEC) {
	    if (nglyph) {
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */

		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		/*
		 * Draw glyph only when it fits entirely into 16 bit coords.
		 */

		if (x >= minCoord && y >= minCoord &&
		    x <= maxCoord - metrics.width &&
		    y <= maxCoord - metrics.height) {

		    /*
		     * NOTE:
		     * The whole algorithm has a design problem, the choice of
		     * NUM_SPEC is arbitrary, and so the inter-glyph spacing could
		     * look arbitrary. This algorithm has to draw the whole string
		     * at once (or whole blocks with same font), this requires a
		     * dynamic 'glyphs' array. In case of overflow the array has to
		     * be divided until the maximal string will fit. (GC)
                     * Given the resolution of current displays though, this should
                     * not be a huge issue since NUM_SPEC is 1024 and thus able to
                     * cover about 6000 pixels for a 6 pixel wide font (which is
                     * a very small barely readable font)
		     */

		    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			    originX, originY, glyphs, nglyph);
		}
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {
	XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
		nglyph, &metrics);

	/*
	 * Draw glyph only when it fits entirely into 16 bit coords.
	 */

	if (x >= minCoord && y >= minCoord &&
	    x <= maxCoord - metrics.width &&
	    y <= maxCoord - metrics.height) {
	    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		    originX, originY, glyphs, nglyph);
	}
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0) {
	XftFont *ftFont, *ft0Font;
	FcChar32 c;

	clen = utf8ToUcs4(source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);

	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = ROUND16(x);
		specs[nspec].y = ROUND16(y);
		if (++nspec == NUM_SPEC) {
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    nspec = 0;
		}
	    }
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
    if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
	XPoint points[5];
	double width = (x - xStart) * cosA + (yStart - y) * sinA;
	double barHeight = fontPtr->font.underlineHeight;
	double dy = fontPtr->font.underlinePos;

	if (fontPtr->font.fa.underline != 0) {
	    if (fontPtr->font.underlineHeight == 1) {
		dy++;
	    }
	    points[0].x = xStart + ROUND16(dy*sinA);
	    points[0].y = yStart + ROUND16(dy*cosA);
	    points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
	    points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
	    if (fontPtr->font.underlineHeight == 1) {
		XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
	    } else {
		points[2].x = xStart + ROUND16(dy*sinA + width*cosA
			+ barHeight*sinA);
		points[2].y = yStart + ROUND16(dy*cosA - width*sinA
			+ barHeight*cosA);
		points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
		points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
		points[4].x = points[0].x;
		points[4].y = points[0].y;
		XFillPolygon(display, drawable, gc, points, 5, Complex,
			CoordModeOrigin);
		XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	    }
	}
	if (fontPtr->font.fa.overstrike != 0) {
	    dy = -fontPtr->font.fm.descent
		   - (fontPtr->font.fm.ascent) / 10;
	    points[0].x = xStart + ROUND16(dy*sinA);
	    points[0].y = yStart + ROUND16(dy*cosA);
	    points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
	    points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
	    if (fontPtr->font.underlineHeight == 1) {
		XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
	    } else {
		points[2].x = xStart + ROUND16(dy*sinA + width*cosA
			+ barHeight*sinA);
		points[2].y = yStart + ROUND16(dy*cosA - width*sinA
			+ barHeight*cosA);
		points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
		points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
		points[4].x = points[0].x;
		points[4].y = points[0].y;
		XFillPolygon(display, drawable, gc, points, 5, Complex,
			CoordModeOrigin);
		XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	    }
	}
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On X11 this
 *	context isn't consulted, so we just call Tk_DrawChars().
 *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

void
TkUnixSetXftClipRegion(
    Region clipRegion)	/* The clipping region to install. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->clipRegion = clipRegion;
}

/*
 * Local Variables:
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


|

<
|
<
<
<
<








|
<
<
<
<
<
<
<
<
<
|
|
<







<
|










|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|











<


|







|






|
|





>
|
>
>
>
>
>
>
>
>
|



|



|










|

>

>
>


|
<
<
<
|
<
<
<
<
|
<
|
|
|
|
|
<
<
<



|
>
>
>



<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
642
643
644
645
646
647
648
649
650
651
652
653

654




655
656
657
658
659
660
661
662
663









664
665

666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697



















































































698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780



781




782

783
784
785
786
787



788
789
790
791
792
793
794
795
796
797



798
799
800
801
802
803
804
805
806
807
808
809

































































































810
811








812





813



814













815













816
















































817

























































































































































































818
819







		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#if DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c);


	XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);





	newX = curX + extents.xOff;
	newByte = curByte + clen;
	if (maxLength >= 0 && newX > maxLength) {
	    if (flags & TK_PARTIAL_OK ||
		    (flags & TK_AT_LEAST_ONE && curByte == 0)) {
		curX = newX;
		curByte = newByte;
	    } else if (flags & TK_WHOLE_WORDS && termX != 0) {









		curX = termX;
		curByte = termByte;

	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }

#if DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
#endif /* DEBUG_FONTSEL */
    *lengthPtr = curX;
    return curByte;
}

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,
    CONST char *source,
    int numBytes,
    int rangeStart,
    int rangeLength,
    int maxLength,
    int flags,
    int *lengthPtr)
{
    (void) numBytes; /*unused*/

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}




















































































#define NUM_SPEC    1024

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */

    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XColor xcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler = Tk_CreateErrorHandler(display, -1, -1, -1,
		NULL, (ClientData) NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }
    XGetGCValues(display, gc, GCForeground, &values);
    if (values.foreground != fontPtr->color.pixel) {
	xcolor.pixel = values.foreground;
	XQueryColor(display, DefaultColormap(display, fontPtr->screen),
		&xcolor);
	fontPtr->color.color.red = xcolor.red;
	fontPtr->color.color.green = xcolor.green;
	fontPtr->color.color.blue = xcolor.blue;
	fontPtr->color.color.alpha = 0xffff;
	fontPtr->color.pixel = values.foreground;
    }
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && x <= maxCoord && y <= maxCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c);
	if (ftFont) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    specs[nspec].x = x;
	    specs[nspec].y = y;
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);
	    x += metrics.xOff;



	    y += metrics.yOff;




	    nspec++;

	    if (nspec == NUM_SPEC) {
		XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color,
			specs, nspec);
		nspec = 0;
	    }



	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
    }
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }

  doUnderlineStrikeout:



    if (fontPtr->font.fa.underline != 0) {
	XFillRectangle(display, drawable, gc, xStart,
		y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
    if (fontPtr->font.fa.overstrike != 0) {
	y -= fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10;
	XFillRectangle(display, drawable, gc, xStart, y,
		(unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
}


































































































void








TkUnixSetXftClipRegion(





    TkRegion clipRegion)	/* The clipping region to install. */



{













    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)













            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));










































































































































































































































    tsdPtr->clipRegion = (Region) clipRegion;
}







Changes to unix/tkUnixScale.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 * 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 "tkScale.h"

#if defined(_WIN32)
#define snprintf _snprintf
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static void		DisplayHorizontalScale(TkScale *scalePtr,
			    Drawable drawable, XRectangle *drawnAreaPtr);
static void		DisplayHorizontalValue(TkScale *scalePtr,
			    Drawable drawable, double value, int top,
			    const char *format);
static void		DisplayVerticalScale(TkScale *scalePtr,
			    Drawable drawable, XRectangle *drawnAreaPtr);
static void		DisplayVerticalValue(TkScale *scalePtr,
			    Drawable drawable, double value, int rightEdge,
			    const char *format);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScale --
 *
 *	Allocate a new TkScale structure.
 *
 * Results:
 *	Returns a newly allocated TkScale structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkScale *
TkpCreateScale(
    TCL_UNUSED(Tk_Window))
{
    return (TkScale *)ckalloc(sizeof(TkScale));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScale --
 *







<
<
<
<







|
<



|
<



















|

|







9
10
11
12
13
14
15




16
17
18
19
20
21
22
23

24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 * 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 "tkScale.h"





/*
 * Forward declarations for functions defined later in this file:
 */

static void		DisplayHorizontalScale(TkScale *scalePtr,
			    Drawable drawable, XRectangle *drawnAreaPtr);
static void		DisplayHorizontalValue(TkScale *scalePtr,
			    Drawable drawable, double value, int top);

static void		DisplayVerticalScale(TkScale *scalePtr,
			    Drawable drawable, XRectangle *drawnAreaPtr);
static void		DisplayVerticalValue(TkScale *scalePtr,
			    Drawable drawable, double value, int rightEdge);


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScale --
 *
 *	Allocate a new TkScale structure.
 *
 * Results:
 *	Returns a newly allocated TkScale structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkScale *
TkpCreateScale(
    Tk_Window tkwin)
{
    return (TkScale *) ckalloc(sizeof(TkScale));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScale --
 *
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 *----------------------------------------------------------------------
 */

void
TkpDestroyScale(
    TkScale *scalePtr)
{
    Tcl_EventuallyFree(scalePtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * DisplayVerticalScale --
 *







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 *----------------------------------------------------------------------
 */

void
TkpDestroyScale(
    TkScale *scalePtr)
{
    Tcl_EventuallyFree((ClientData) scalePtr, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * DisplayVerticalScale --
 *
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		    / (double) scalePtr->fontHeight;
	    if (ticks > maxTicks) {
		tickInterval *= (ticks / maxTicks);
	    }
	    for (tickValue = scalePtr->fromValue; ;
		    tickValue += tickInterval) {
		/*
		 * The TkRoundValueToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundValueToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayVerticalValue(scalePtr, drawable, tickValue,
			scalePtr->vertTickRightX, scalePtr->tickFormat);
	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayVerticalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->vertValueRightX, scalePtr->valueFormat);
    }

    /*
     * Display the trough and the slider.
     */

    Tk_Draw3DRectangle(tkwin, drawable,







|



|










|










|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
		    / (double) scalePtr->fontHeight;
	    if (ticks > maxTicks) {
		tickInterval *= (ticks / maxTicks);
	    }
	    for (tickValue = scalePtr->fromValue; ;
		    tickValue += tickInterval) {
		/*
		 * The TkRoundToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayVerticalValue(scalePtr, drawable, tickValue,
			scalePtr->vertTickRightX);
	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayVerticalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->vertValueRightX);
    }

    /*
     * Display the trough and the slider.
     */

    Tk_Draw3DRectangle(tkwin, drawable,
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
		scalePtr->labelLength, scalePtr->vertLabelX,
		scalePtr->inset + (3 * fm.ascent) / 2);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayVerticalValue --







|
|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
                scalePtr->labelLength, scalePtr->vertLabelX,
                scalePtr->inset + (3*fm.ascent)/2);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayVerticalValue --
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
 *	corresponds to "value".
 *
 *----------------------------------------------------------------------
 */

static void
DisplayVerticalValue(
    TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* Y-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int rightEdge,		/* X-coordinate of right edge of text,
				 * specified in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int y, width, length;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the y-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    if (y - fm.ascent < scalePtr->inset + SPACING) {
	y = scalePtr->inset + SPACING + fm.ascent;
    }
    if (y + fm.descent > Tk_Height(tkwin) - scalePtr->inset - SPACING) {
	y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent;
    }
    Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
	    scalePtr->tkfont, valueString, length, rightEdge - width, y);
}

/*







|






|

<

|






|
<
<








|


|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 *	corresponds to "value".
 *
 *----------------------------------------------------------------------
 */

static void
DisplayVerticalValue(
    register TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* Y-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int rightEdge)		/* X-coordinate of right edge of text,
				 * specified in pixels. */

{
    register Tk_Window tkwin = scalePtr->tkwin;
    int y, width, length;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
    sprintf(valueString, scalePtr->format, value);


    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the y-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    if ((y - fm.ascent) < (scalePtr->inset + SPACING)) {
	y = scalePtr->inset + SPACING + fm.ascent;
    }
    if ((y + fm.descent) > (Tk_Height(tkwin) - scalePtr->inset - SPACING)) {
	y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent;
    }
    Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
	    scalePtr->tkfont, valueString, length, rightEdge - width, y);
}

/*
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    Drawable drawable,		/* Where to display scale (window or
				 * pixmap). */
    XRectangle *drawnAreaPtr)	/* Initally contains area of window; if only a
				 * part of the scale is redrawn, gets modified
				 * to reflect the part of the window that was
				 * redrawn. */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int x, y, width, height, shadowWidth;
    double tickInterval = scalePtr->tickInterval;
    Tk_3DBorder sliderBorder;

    /*
     * Display the information from bottom to top across the window.
     */

    if (!(scalePtr->flags & REDRAW_OTHER)) {







|

|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    Drawable drawable,		/* Where to display scale (window or
				 * pixmap). */
    XRectangle *drawnAreaPtr)	/* Initally contains area of window; if only a
				 * part of the scale is redrawn, gets modified
				 * to reflect the part of the window that was
				 * redrawn. */
{
    register Tk_Window tkwin = scalePtr->tkwin;
    int x, y, width, height, shadowWidth;
    double tickValue, tickInterval = scalePtr->tickInterval;
    Tk_3DBorder sliderBorder;

    /*
     * Display the information from bottom to top across the window.
     */

    if (!(scalePtr->flags & REDRAW_OTHER)) {
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    if (scalePtr->flags & REDRAW_OTHER) {
	/*
	 * Display the tick marks.
	 */

	if (tickInterval != 0) {
	    char valueString[TCL_DOUBLE_SPACE];
	    double ticks, maxTicks, tickValue;

	    /*
	     * Ensure that we will only draw enough of the tick values such
	     * that they don't overlap. We base this off the width that
	     * fromValue would take. Not exact, but better than no constraint.
	     */

	    ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
		    / tickInterval);
	    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->tickFormat,
		    scalePtr->fromValue) < 0) {
		valueString[TCL_DOUBLE_SPACE - 1] = '\0';
	    }
	    maxTicks = (double) Tk_Width(tkwin)
		    / (double) Tk_TextWidth(scalePtr->tkfont, valueString, -1);
	    if (ticks > maxTicks) {
		tickInterval *= ticks / maxTicks;
	    }
	    tickValue = scalePtr->fromValue;
	    while (1) {
		/*
		 * The TkRoundValueToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundValueToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayHorizontalValue(scalePtr, drawable, tickValue,
			scalePtr->horizTickY, scalePtr->tickFormat);
		tickValue += tickInterval;
	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayHorizontalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->horizValueY, scalePtr->valueFormat);
    }

    /*
     * Display the trough and the slider.
     */

    y = scalePtr->horizTroughY;







|









<
|
<
<



|

|
|

|



|










|
<










|







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355


356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    if (scalePtr->flags & REDRAW_OTHER) {
	/*
	 * Display the tick marks.
	 */

	if (tickInterval != 0) {
	    char valueString[TCL_DOUBLE_SPACE];
	    double ticks, maxTicks;

	    /*
	     * Ensure that we will only draw enough of the tick values such
	     * that they don't overlap. We base this off the width that
	     * fromValue would take. Not exact, but better than no constraint.
	     */

	    ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
		    / tickInterval);

	    sprintf(valueString, scalePtr->format, scalePtr->fromValue);


	    maxTicks = (double) Tk_Width(tkwin)
		    / (double) Tk_TextWidth(scalePtr->tkfont, valueString, -1);
	    if (ticks > maxTicks) {
		tickInterval *= (ticks / maxTicks);
	    }
	    for (tickValue = scalePtr->fromValue; ;
		 tickValue += tickInterval) {
		/*
		 * The TkRoundToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayHorizontalValue(scalePtr, drawable, tickValue,
			scalePtr->horizTickY);

	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayHorizontalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->horizValueY);
    }

    /*
     * Display the trough and the slider.
     */

    y = scalePtr->horizTroughY;
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
		scalePtr->labelLength, scalePtr->inset + fm.ascent/2,
		scalePtr->horizLabelY + fm.ascent);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayHorizontalValue --







|
|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
                scalePtr->labelLength, scalePtr->inset + fm.ascent/2,
                scalePtr->horizLabelY + fm.ascent);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayHorizontalValue --
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
 *	that corresponds to "value".
 *
 *----------------------------------------------------------------------
 */

static void
DisplayHorizontalValue(
    TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* X-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int top,			/* Y-coordinate of top edge of text, specified
				 * in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int x, y, length, width;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    x = TkScaleValueToPixel(scalePtr, value);
    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = top + fm.ascent;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the x-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    x -= width / 2;
    if (x < scalePtr->inset + SPACING) {
	x = scalePtr->inset + SPACING;
    }

    /*
     * Check the right border so use starting point +text width for the check.
     */








|






|

<

|







|
<
<








|
|







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
 *	that corresponds to "value".
 *
 *----------------------------------------------------------------------
 */

static void
DisplayHorizontalValue(
    register TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* X-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int top)			/* Y-coordinate of top edge of text, specified
				 * in pixels. */

{
    register Tk_Window tkwin = scalePtr->tkwin;
    int x, y, length, width;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    x = TkScaleValueToPixel(scalePtr, value);
    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = top + fm.ascent;
    sprintf(valueString, scalePtr->format, value);


    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the x-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    x -= (width)/2;
    if (x < (scalePtr->inset + SPACING)) {
	x = scalePtr->inset + SPACING;
    }

    /*
     * Check the right border so use starting point +text width for the check.
     */

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    Pixmap pixmap;
    int result;
    char string[TCL_DOUBLE_SPACE];
    XRectangle drawnArea;
    Tcl_DString buf;

    scalePtr->flags &= ~REDRAW_PENDING;
    if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
	goto done;
    }

    /*
     * Invoke the scale's command if needed.
     */

    Tcl_Preserve(scalePtr);
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
	if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
		scalePtr->value) < 0) {
	    string[TCL_DOUBLE_SPACE - 1] = '\0';
	}
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, string, -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);

	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }
    scalePtr->flags &= ~INVOKE_COMMAND;
    if (scalePtr->flags & SCALE_DELETED) {
	Tcl_Release(scalePtr);
	return;
    }
    Tcl_Release(scalePtr);

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * In order to avoid screen flashes, this function redraws the scale in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-sreen image has
     * been cleared.







|






<










|

|
<
|
<
<
<
|
<
<
<
<
>


|

|



|


|







526
527
528
529
530
531
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
548
549
550
551
552

553



554




555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *) clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    Pixmap pixmap;
    int result;
    char string[TCL_DOUBLE_SPACE];
    XRectangle drawnArea;


    scalePtr->flags &= ~REDRAW_PENDING;
    if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
	goto done;
    }

    /*
     * Invoke the scale's command if needed.
     */

    Tcl_Preserve((ClientData) scalePtr);
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve((ClientData) interp);

	sprintf(string, scalePtr->format, scalePtr->value);



	result = Tcl_VarEval(interp, scalePtr->command, " ", string,




		(char *) NULL);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundError(interp);
	}
	Tcl_Release((ClientData) interp);
    }
    scalePtr->flags &= ~INVOKE_COMMAND;
    if (scalePtr->flags & SCALE_DELETED) {
	Tcl_Release((ClientData) scalePtr);
	return;
    }
    Tcl_Release((ClientData) scalePtr);

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * In order to avoid screen flashes, this function redraws the scale in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-sreen image has
     * been cleared.
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
	if (scalePtr->highlightWidth != 0) {
	    GC gc;

	    if (scalePtr->flags & GOT_FOCUS) {
		gc = Tk_GCForColor(scalePtr->highlightColorPtr, pixmap);
	    } else {
		gc = Tk_GCForColor(
			Tk_3DBorderColor(scalePtr->highlightBorder), pixmap);
	    }
	    Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, pixmap);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*







|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	if (scalePtr->highlightWidth != 0) {
	    GC gc;

	    if (scalePtr->flags & GOT_FOCUS) {
		gc = Tk_GCForColor(scalePtr->highlightColorPtr, pixmap);
	    } else {
		gc = Tk_GCForColor(
                        Tk_3DBorderColor(scalePtr->highlightBorder), pixmap);
	    }
	    Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, pixmap);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	    return OTHER;
	}
	sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
		- scalePtr->sliderLength/2;
	if (y < sliderFirst) {
	    return TROUGH1;
	}
	if (y < sliderFirst + scalePtr->sliderLength) {
	    return SLIDER;
	}
	return TROUGH2;
    }

    if ((y < scalePtr->horizTroughY)
	    || (y >= (scalePtr->horizTroughY + 2*scalePtr->borderWidth +
	    scalePtr->width))) {
	return OTHER;
    }
    if ((x < scalePtr->inset)
	    || (x >= (Tk_Width(scalePtr->tkwin) - scalePtr->inset))) {
	return OTHER;
    }
    sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
	    - scalePtr->sliderLength/2;
    if (x < sliderFirst) {
	return TROUGH1;
    }
    if (x < sliderFirst + scalePtr->sliderLength) {
	return SLIDER;
    }
    return TROUGH2;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



















|












673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
	    return OTHER;
	}
	sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
		- scalePtr->sliderLength/2;
	if (y < sliderFirst) {
	    return TROUGH1;
	}
	if (y < (sliderFirst+scalePtr->sliderLength)) {
	    return SLIDER;
	}
	return TROUGH2;
    }

    if ((y < scalePtr->horizTroughY)
	    || (y >= (scalePtr->horizTroughY + 2*scalePtr->borderWidth +
	    scalePtr->width))) {
	return OTHER;
    }
    if ((x < scalePtr->inset)
	    || (x >= (Tk_Width(scalePtr->tkwin) - scalePtr->inset))) {
	return OTHER;
    }
    sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
	    - scalePtr->sliderLength/2;
    if (x < sliderFirst) {
	return TROUGH1;
    }
    if (x < (sliderFirst+scalePtr->sliderLength)) {
	return SLIDER;
    }
    return TROUGH2;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixScrlbr.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

const Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *







|
|
<
<
<







32
33
34
35
36
37
38
39
40



41
42
43
44
45
46
47

/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs)	/* size */



};

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 */

TkScrollbar *
TkpCreateScrollbar(
    Tk_Window tkwin)
{
    UnixScrollbar *scrollPtr = (UnixScrollbar *)ckalloc(sizeof(UnixScrollbar));

    scrollPtr->troughGC = NULL;
    scrollPtr->copyGC = NULL;

    Tk_CreateEventHandler(tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    TkScrollbarEventProc, scrollPtr);

    return (TkScrollbar *) scrollPtr;
}

/*
 *--------------------------------------------------------------
 *







<
|
|



|







57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
 */

TkScrollbar *
TkpCreateScrollbar(
    Tk_Window tkwin)
{
    UnixScrollbar *scrollPtr = (UnixScrollbar *)ckalloc(sizeof(UnixScrollbar));

    scrollPtr->troughGC = None;
    scrollPtr->copyGC = None;

    Tk_CreateEventHandler(tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    TkScrollbarEventProc, (ClientData) scrollPtr);

    return (TkScrollbar *) scrollPtr;
}

/*
 *--------------------------------------------------------------
 *
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;
    XPoint points[7];
    Tk_3DBorder border;
    int relief, width, elementBorderWidth;
    Pixmap pixmap;

    if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	goto done;







|
|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
    register Tk_Window tkwin = scrollPtr->tkwin;
    XPoint points[7];
    Tk_3DBorder border;
    int relief, width, elementBorderWidth;
    Pixmap pixmap;

    if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	goto done;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

extern void
TkpComputeScrollbarGeometry(
    TkScrollbar *scrollPtr)
				/* Scrollbar whose geometry may have
				 * changed. */
{
    int width, fieldLength;

    if (scrollPtr->highlightWidth < 0) {
	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
	    : Tk_Height(scrollPtr->tkwin);

    /*
     * Next line assumes that the arrow area is a square.
     */

    scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
	    : Tk_Width(scrollPtr->tkwin))
	    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always displayed in the
     * scrollbar and so that it has at least a minimal width (so it can be
     * grabbed with the mouse).
     */

    if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
	scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderFirst < 0) {
	scrollPtr->sliderFirst = 0;
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {

	scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast > fieldLength) {
	scrollPtr->sliderLast = fieldLength;
    }
    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;







|











<
<
<
<
<
















|





|
>







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287





288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

extern void
TkpComputeScrollbarGeometry(
    register TkScrollbar *scrollPtr)
				/* Scrollbar whose geometry may have
				 * changed. */
{
    int width, fieldLength;

    if (scrollPtr->highlightWidth < 0) {
	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
	    : Tk_Height(scrollPtr->tkwin);





    scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
	    : Tk_Width(scrollPtr->tkwin))
	    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always displayed in the
     * scrollbar and so that it has at least a minimal width (so it can be
     * grabbed with the mouse).
     */

    if (scrollPtr->sliderFirst > (fieldLength - MIN_SLIDER_LENGTH)) {
	scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderFirst < 0) {
	scrollPtr->sliderFirst = 0;
    }
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
	    + MIN_SLIDER_LENGTH)) {
	scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast > fieldLength) {
	scrollPtr->sliderLast = fieldLength;
    }
    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    UnixScrollbar *unixScrollPtr = (UnixScrollbar *)scrollPtr;

    if (unixScrollPtr->troughGC != NULL) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
    }
    if (unixScrollPtr->copyGC != NULL) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->copyGC);
    }
}

/*
 *----------------------------------------------------------------------
 *







|


|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    UnixScrollbar *unixScrollPtr = (UnixScrollbar *)scrollPtr;

    if (unixScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
    }
    if (unixScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->copyGC);
    }
}

/*
 *----------------------------------------------------------------------
 *
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
 *	Configuration info may get changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)
				/* Information about widget; may or may not
				 * already have values for some fields. */
{
    XGCValues gcValues;
    GC newGC;
    UnixScrollbar *unixScrollPtr = (UnixScrollbar *) scrollPtr;

    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);

    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
    newGC = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
    if (unixScrollPtr->troughGC != NULL) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
    }
    unixScrollPtr->troughGC = newGC;
    if (unixScrollPtr->copyGC == NULL) {
	gcValues.graphics_exposures = False;
	unixScrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin,
		GCGraphicsExposures, &gcValues);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --







|




|





|
|


|
|

|
|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
 *	Configuration info may get changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    register TkScrollbar *scrollPtr)
				/* Information about widget; may or may not
				 * already have values for some fields. */
{
    XGCValues gcValues;
    GC new;
    UnixScrollbar *unixScrollPtr = (UnixScrollbar *) scrollPtr;

    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);

    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
    new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
    if (unixScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
    }
    unixScrollPtr->troughGC = new;
    if (unixScrollPtr->copyGC == None) {
	gcValues.graphics_exposures = False;
	unixScrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin, GCGraphicsExposures,
	    &gcValues);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{
    int length, width, tmp;
    const int inset = scrollPtr->inset;

    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);
	width = Tk_Width(scrollPtr->tkwin);
    } else {
	tmp = x;
	x = y;
	y = tmp;
	length = Tk_Width(scrollPtr->tkwin);
	width = Tk_Height(scrollPtr->tkwin);
    }


    if (x<inset || x>=width-inset || y<inset || y>=length-inset) {
	return OUTSIDE;
    }

    /*
     * All of the calculations in this procedure mirror those in
     * TkpDisplayScrollbar. Be sure to keep the two consistent.
     */

    if (y < inset + scrollPtr->arrowLength) {
	return TOP_ARROW;
    }
    if (y < scrollPtr->sliderFirst) {
	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
	return SLIDER;
    }
    if (y >= length - (scrollPtr->arrowLength + inset)) {
	return BOTTOM_ARROW;
    }
    return BOTTOM_GAP;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|




<












>
|








|








|












425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{
    int length, width, tmp;


    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);
	width = Tk_Width(scrollPtr->tkwin);
    } else {
	tmp = x;
	x = y;
	y = tmp;
	length = Tk_Width(scrollPtr->tkwin);
	width = Tk_Height(scrollPtr->tkwin);
    }

    if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
	    || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
	return OUTSIDE;
    }

    /*
     * All of the calculations in this procedure mirror those in
     * TkpDisplayScrollbar. Be sure to keep the two consistent.
     */

    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
	return TOP_ARROW;
    }
    if (y < scrollPtr->sliderFirst) {
	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
	return SLIDER;
    }
    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
	return BOTTOM_ARROW;
    }
    return BOTTOM_GAP;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixSelect.c.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
				 * for the next chunk; -1 means all data has
				 * been transferred for this conversion. -2
				 * means only the final zero-length transfer
				 * still has to be done. Otherwise it is the
				 * offset of the next chunk of data to
				 * transfer. */
    Tcl_EncodingState state;	/* The encoding state needed across chunks. */
    char buffer[4];	/* A buffer to hold part of a UTF character
				 * that is split across chunks.*/
} ConvertInfo;

/*
 * When handling INCR-style selection retrievals, the selection owner uses the
 * following data structure to communicate between the ConvertSelection
 * function and TkSelPropProc.







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
				 * for the next chunk; -1 means all data has
				 * been transferred for this conversion. -2
				 * means only the final zero-length transfer
				 * still has to be done. Otherwise it is the
				 * offset of the next chunk of data to
				 * transfer. */
    Tcl_EncodingState state;	/* The encoding state needed across chunks. */
    char buffer[TCL_UTF_MAX];	/* A buffer to hold part of a UTF character
				 * that is split across chunks.*/
} ConvertInfo;

/*
 * When handling INCR-style selection retrievals, the selection owner uses the
 * following data structure to communicate between the ConvertSelection
 * function and TkSelPropProc.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    Time time;			/* Timestamp corresponding to selection at
				 * beginning of request; used to abort
				 * transfer if selection changes. */
    struct IncrInfo *nextPtr;	/* Next in list of all INCR-style retrievals
				 * currently pending. */
} IncrInfo;

typedef struct {
    IncrInfo *pendingIncrs;	/* List of all incr structures currently
				 * active. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Largest property that we'll accept when sending or receiving the selection:







|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    Time time;			/* Timestamp corresponding to selection at
				 * beginning of request; used to abort
				 * transfer if selection changes. */
    struct IncrInfo *nextPtr;	/* Next in list of all INCR-style retrievals
				 * currently pending. */
} IncrInfo;

typedef struct ThreadSpecificData {
    IncrInfo *pendingIncrs;	/* List of all incr structures currently
				 * active. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Largest property that we'll accept when sending or receiving the selection:
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    retr.result = -1;
    retr.idleTime = 0;
    retr.encFlags = TCL_ENCODING_START;
    retr.nextPtr = pendingRetrievals;
    Tcl_DStringInit(&retr.buf);
    pendingRetrievals = &retr;

    /*
     * Delete the property to indicate that no parameters are supplied for
     * the conversion request.
     */

    XDeleteProperty(winPtr->display, retr.winPtr->window, retr.property);

    /*
     * Initiate the request for the selection. Note: can't use TkCurrentTime
     * for the time. If we do, and this application hasn't received any X
     * events in a long time, the current time will be way in the past and
     * could even predate the time when the selection was made; if this
     * happens, the request will be rejected.
     */

    XConvertSelection(winPtr->display, retr.selection, retr.target,
	    retr.property, retr.winPtr->window, CurrentTime);

    /*
     * Enter a loop processing X events until the selection has been retrieved
     * and processed. If no response is received within a few seconds, then
     * timeout.
     */

    retr.timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
	    &retr);
    while (retr.result == -1) {
	Tcl_DoOneEvent(0);
    }
    Tcl_DeleteTimerHandler(retr.timeout);

    /*
     * Unregister the information about the selection retrieval in progress.







<
<
<
<
<
<
<


















|







161
162
163
164
165
166
167







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    retr.result = -1;
    retr.idleTime = 0;
    retr.encFlags = TCL_ENCODING_START;
    retr.nextPtr = pendingRetrievals;
    Tcl_DStringInit(&retr.buf);
    pendingRetrievals = &retr;








    /*
     * Initiate the request for the selection. Note: can't use TkCurrentTime
     * for the time. If we do, and this application hasn't received any X
     * events in a long time, the current time will be way in the past and
     * could even predate the time when the selection was made; if this
     * happens, the request will be rejected.
     */

    XConvertSelection(winPtr->display, retr.selection, retr.target,
	    retr.property, retr.winPtr->window, CurrentTime);

    /*
     * Enter a loop processing X events until the selection has been retrieved
     * and processed. If no response is received within a few seconds, then
     * timeout.
     */

    retr.timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
	    (ClientData) &retr);
    while (retr.result == -1) {
	Tcl_DoOneEvent(0);
    }
    Tcl_DeleteTimerHandler(retr.timeout);

    /*
     * Unregister the information about the selection retrieval in progress.
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
 *	until eventually there's no more selection to fetch.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    IncrInfo *incrPtr;
    TkSelHandler *selPtr;
    int length, numItems;
    unsigned long i;
    Atom target, formatType;
    long buffer[TK_SEL_WORDS_AT_ONCE];
    TkDisplay *dispPtr = TkGetDisplay(eventPtr->xany.display);
    Tk_ErrorHandler errorHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)







|

|
|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
 *	until eventually there's no more selection to fetch.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    register XEvent *eventPtr)	/* X PropertyChange event. */
{
    register IncrInfo *incrPtr;
    register TkSelHandler *selPtr;
    int length, numItems;
    unsigned long i;
    Atom target, formatType;
    long buffer[TK_SEL_WORDS_AT_ONCE];
    TkDisplay *dispPtr = TkGetDisplay(eventPtr->xany.display);
    Tk_ErrorHandler errorHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
		 * Pass the rest of the buffer space into the selection
		 * handler.
		 */

		length = strlen(incrPtr->converts[i].buffer);
		strcpy((char *)buffer, incrPtr->converts[i].buffer);

		numItems = selPtr->proc(selPtr->clientData,
			incrPtr->converts[i].offset,
			((char *) buffer) + length,
			TK_SEL_BYTES_AT_ONCE - length);
		TkSelSetInProgress(ip.nextPtr);
		if (ip.selPtr == NULL) {
		    /*
		     * The selection handler deleted itself.







|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
		 * Pass the rest of the buffer space into the selection
		 * handler.
		 */

		length = strlen(incrPtr->converts[i].buffer);
		strcpy((char *)buffer, incrPtr->converts[i].buffer);

		numItems = (*selPtr->proc)(selPtr->clientData,
			incrPtr->converts[i].offset,
			((char *) buffer) + length,
			TK_SEL_BYTES_AT_ONCE - length);
		TkSelSetInProgress(ip.nextPtr);
		if (ip.selPtr == NULL) {
		    /*
		     * The selection handler deleted itself.
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
		if (numItems > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
	    }
	    ((char *) buffer)[numItems] = 0;

	    errorHandler = Tk_CreateErrorHandler(eventPtr->xproperty.display,
		    -1, -1, -1, NULL, NULL);

	    /*
	     * Encode the data using the proper format for each type.
	     */

	    if ((formatType == XA_STRING)
		    || (dispPtr && formatType==dispPtr->utf8Atom)







|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
		if (numItems > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
	    }
	    ((char *) buffer)[numItems] = 0;

	    errorHandler = Tk_CreateErrorHandler(eventPtr->xproperty.display,
		    -1, -1, -1, (int (*)()) NULL, NULL);

	    /*
	     * Encode the data using the proper format for each type.
	     */

	    if ((formatType == XA_STRING)
		    || (dispPtr && formatType==dispPtr->utf8Atom)
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
			(unsigned char *) Tcl_DStringValue(&ds),
			Tcl_DStringLength(&ds));

		/*
		 * Preserve any left-over bytes.
		 */

		if (srcLen > 3) {
		    Tcl_Panic("selection conversion left too many bytes unconverted");
		}
		memcpy(incrPtr->converts[i].buffer, src, srcLen + 1);
		Tcl_DStringFree(&ds);
	    } else {
		/*
		 * Set the property to the encoded string value.
		 */

		char *propPtr = (char *) SelCvtToX((char *) buffer,







|


|







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
			(unsigned char *) Tcl_DStringValue(&ds),
			Tcl_DStringLength(&ds));

		/*
		 * Preserve any left-over bytes.
		 */

		if (srcLen > TCL_UTF_MAX) {
		    Tcl_Panic("selection conversion left too many bytes unconverted");
		}
		memcpy(incrPtr->converts[i].buffer, src, (size_t) srcLen+1);
		Tcl_DStringFree(&ds);
	    } else {
		/*
		 * Set the property to the encoded string value.
		 */

		char *propPtr = (char *) SelCvtToX((char *) buffer,
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558
559
560

561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594
595

596

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    Tcl_Interp *interp;

    /*
     * Case #1: SelectionClear events.
     */

    if (eventPtr->type == SelectionClear) {
	TkSelClearSelection(tkwin, eventPtr);
    }

    /*
     * Case #2: SelectionNotify events. Call the relevant function to handle
     * the incoming selection.
     */

    if (eventPtr->type == SelectionNotify) {
	TkSelRetrievalInfo *retrPtr;
	char *propInfo, **propInfoPtr = &propInfo;
	Atom type;
	int format, result;
	unsigned long numItems, bytesAfter;


	for (retrPtr = pendingRetrievals; ; retrPtr = retrPtr->nextPtr) {
	    if (retrPtr == NULL) {
		return;
	    }
	    if ((retrPtr->winPtr == winPtr)
		    && (retrPtr->selection == eventPtr->xselection.selection)
		    && (retrPtr->target == eventPtr->xselection.target)
		    && (retrPtr->result == -1)) {
		if (retrPtr->property == eventPtr->xselection.property) {
		    break;
		}
		if (eventPtr->xselection.property == None) {

		    Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(
			    "%s selection doesn't exist or form \"%s\" not defined",
			    Tk_GetAtomName(tkwin, retrPtr->selection),

			    Tk_GetAtomName(tkwin, retrPtr->target)));
		    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION",
			    "NONE", NULL);
		    retrPtr->result = TCL_ERROR;
		    return;
		}
	    }
	}

	propInfo = NULL;
	result = XGetWindowProperty(eventPtr->xselection.display,
		eventPtr->xselection.requestor, retrPtr->property,
		0, MAX_PROP_WORDS, False, (Atom) AnyPropertyType,
		&type, &format, &numItems, &bytesAfter,
		(unsigned char **) propInfoPtr);
	if ((result != Success) || (type == None)) {
	    return;
	}
	if (bytesAfter != 0) {
	    Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		    "selection property too large", -1));
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE",NULL);

	    retrPtr->result = TCL_ERROR;
	    XFree(propInfo);
	    return;
	}
	if ((type == XA_STRING) || (type == dispPtr->textAtom)
		|| (type == dispPtr->compoundTextAtom)) {
	    Tcl_Encoding encoding;
		Tcl_DString ds;

	    if (format != 8) {

		Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(

			"bad format for string selection: wanted \"8\", got \"%d\"",
			format));
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
		retrPtr->result = TCL_ERROR;
		return;
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve(interp);

	    /*
	     * Convert the X selection data into UTF before passing it to the
	     * selection callback. Note that the COMPOUND_TEXT uses a modified
	     * iso2022 encoding, not the current system encoding. For now
	     * we'll just blindly apply the iso2022 encoding. This is probably
	     * wrong, but it's a placeholder until we figure out what we're







|


|

















|




>













>
|
<

>
|
<
|
















<
|
<
>







<
<

>
|
>

|
|
<




|







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

557
558
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577

578
579
580
581
582
583
584
585


586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603
604
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    register XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    Tcl_Interp *interp;

    /*
     * Case #1: SelectionClear events.
     */

    if (eventPtr->type == SelectionClear) {
	TkSelClearSelection(tkwin, eventPtr);
    }

    /*
     * Case #2: SelectionNotify events. Call the relevant function to handle
     * the incoming selection.
     */

    if (eventPtr->type == SelectionNotify) {
	register TkSelRetrievalInfo *retrPtr;
	char *propInfo, **propInfoPtr = &propInfo;
	Atom type;
	int format, result;
	unsigned long numItems, bytesAfter;
	Tcl_DString ds;

	for (retrPtr = pendingRetrievals; ; retrPtr = retrPtr->nextPtr) {
	    if (retrPtr == NULL) {
		return;
	    }
	    if ((retrPtr->winPtr == winPtr)
		    && (retrPtr->selection == eventPtr->xselection.selection)
		    && (retrPtr->target == eventPtr->xselection.target)
		    && (retrPtr->result == -1)) {
		if (retrPtr->property == eventPtr->xselection.property) {
		    break;
		}
		if (eventPtr->xselection.property == None) {
		    Tcl_SetResult(retrPtr->interp, NULL, TCL_STATIC);
		    Tcl_AppendResult(retrPtr->interp,

			    Tk_GetAtomName(tkwin, retrPtr->selection),
			    " selection doesn't exist or form \"",
			    Tk_GetAtomName(tkwin, retrPtr->target),

			    "\" not defined", NULL);
		    retrPtr->result = TCL_ERROR;
		    return;
		}
	    }
	}

	propInfo = NULL;
	result = XGetWindowProperty(eventPtr->xselection.display,
		eventPtr->xselection.requestor, retrPtr->property,
		0, MAX_PROP_WORDS, False, (Atom) AnyPropertyType,
		&type, &format, &numItems, &bytesAfter,
		(unsigned char **) propInfoPtr);
	if ((result != Success) || (type == None)) {
	    return;
	}
	if (bytesAfter != 0) {

	    Tcl_SetResult(retrPtr->interp, "selection property too large",

		    TCL_STATIC);
	    retrPtr->result = TCL_ERROR;
	    XFree(propInfo);
	    return;
	}
	if ((type == XA_STRING) || (type == dispPtr->textAtom)
		|| (type == dispPtr->compoundTextAtom)) {
	    Tcl_Encoding encoding;


	    if (format != 8) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf,
			"bad format for string selection: wanted \"8\", got \"%d\"",
			format);
		Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE);

		retrPtr->result = TCL_ERROR;
		return;
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve((ClientData) interp);

	    /*
	     * Convert the X selection data into UTF before passing it to the
	     * selection callback. Note that the COMPOUND_TEXT uses a modified
	     * iso2022 encoding, not the current system encoding. For now
	     * we'll just blindly apply the iso2022 encoding. This is probably
	     * wrong, but it's a placeholder until we figure out what we're
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    }
	    Tcl_ExternalToUtfDString(encoding, propInfo, (int)numItems, &ds);
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }

	    retrPtr->result = retrPtr->proc(retrPtr->clientData, interp,
		    Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	    Tcl_Release(interp);
	} else if (type == dispPtr->utf8Atom) {
	    /*
	     * The X selection data is in UTF-8 format already. We can't
	     * guarantee that propInfo is NULL-terminated, so we might have to
	     * copy the string.
	     */

	    char *propData = propInfo;

	    if (format != 8) {

		Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(

			"bad format for string selection: wanted \"8\", got \"%d\"",
			format));
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
		retrPtr->result = TCL_ERROR;
		return;
	    }

	    if (propInfo[numItems] != '\0') {
		propData = (char *)ckalloc(numItems + 1);
		strcpy(propData, propInfo);
		propData[numItems] = '\0';
	    }
	    retrPtr->result = retrPtr->proc(retrPtr->clientData,
		    retrPtr->interp, propData);
	    if (propData != propInfo) {
		ckfree(propData);
	    }

	} else if (type == dispPtr->incrAtom) {
	    /*
	     * It's a !?#@!?!! INCR-style reception. Arrange to receive the
	     * selection in pieces, using the ICCCM protocol, then hang around
	     * until either the selection is all here or a timeout occurs.
	     */

	    retrPtr->idleTime = 0;
	    Tk_CreateEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,
		    retrPtr);
	    XDeleteProperty(Tk_Display(tkwin), Tk_WindowId(tkwin),
		    retrPtr->property);
	    while (retrPtr->result == -1) {
		Tcl_DoOneEvent(0);
	    }
	    Tk_DeleteEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,
		    retrPtr);
	} else {
	    Tcl_DString ds;

	    if (format != 32 && format != 8) {

		Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(
			"bad format for selection: wanted \"32\" or "
			"\"8\", got \"%d\"", format));
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
		retrPtr->result = TCL_ERROR;
		return;
	    }
	    Tcl_DStringInit(&ds);
	    if (format == 32) {
		SelCvtFromX32((long *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    } else {
		SelCvtFromX8((char *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve(interp);
	    retrPtr->result = retrPtr->proc(retrPtr->clientData,
		    interp, Tcl_DStringValue(&ds));
	    Tcl_Release(interp);
	    Tcl_DStringFree(&ds);
	}
	XFree(propInfo);
	return;
    }

    /*







|
|

|










>
|
>

|
|
<





|



|


|











|






|




>
|
|
|
|
<












|
|

|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    }
	    Tcl_ExternalToUtfDString(encoding, propInfo, (int)numItems, &ds);
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }

	    retrPtr->result = (*retrPtr->proc)(retrPtr->clientData,
		    interp, Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	    Tcl_Release((ClientData) interp);
	} else if (type == dispPtr->utf8Atom) {
	    /*
	     * The X selection data is in UTF-8 format already. We can't
	     * guarantee that propInfo is NULL-terminated, so we might have to
	     * copy the string.
	     */

	    char *propData = propInfo;

	    if (format != 8) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf,
			"bad format for string selection: wanted \"8\", got \"%d\"",
			format);
		Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE);

		retrPtr->result = TCL_ERROR;
		return;
	    }

	    if (propInfo[numItems] != '\0') {
		propData = ckalloc((size_t) numItems + 1);
		strcpy(propData, propInfo);
		propData[numItems] = '\0';
	    }
	    retrPtr->result = (*retrPtr->proc)(retrPtr->clientData,
		    retrPtr->interp, propData);
	    if (propData != propInfo) {
		ckfree((char *) propData);
	    }

	} else if (type == dispPtr->incrAtom) {
	    /*
	     * It's a !?#@!?!! INCR-style reception. Arrange to receive the
	     * selection in pieces, using the ICCCM protocol, then hang around
	     * until either the selection is all here or a timeout occurs.
	     */

	    retrPtr->idleTime = 0;
	    Tk_CreateEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,
		    (ClientData) retrPtr);
	    XDeleteProperty(Tk_Display(tkwin), Tk_WindowId(tkwin),
		    retrPtr->property);
	    while (retrPtr->result == -1) {
		Tcl_DoOneEvent(0);
	    }
	    Tk_DeleteEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,
		    (ClientData) retrPtr);
	} else {
	    Tcl_DString ds;

	    if (format != 32 && format != 8) {
		char buf[64 + TCL_INTEGER_SPACE];

		sprintf(buf, "bad format for selection: wanted \"32\" or "
			"\"8\", got \"%d\"", format);
		Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE);

		retrPtr->result = TCL_ERROR;
		return;
	    }
	    Tcl_DStringInit(&ds);
	    if (format == 32) {
		SelCvtFromX32((long *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    } else {
		SelCvtFromX8((char *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve((ClientData) interp);
	    retrPtr->result = (*retrPtr->proc)(retrPtr->clientData,
		    interp, Tcl_DStringValue(&ds));
	    Tcl_Release((ClientData) interp);
	    Tcl_DStringFree(&ds);
	}
	XFree(propInfo);
	return;
    }

    /*
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
774
775
776
 *----------------------------------------------------------------------
 */

static void
SelTimeoutProc(
    ClientData clientData)	/* Information about retrieval in progress. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;

    /*
     * Make sure that the retrieval is still in progress. Then see how long
     * it's been since any sort of response was received from the other side.
     */

    if (retrPtr->result != -1) {
	return;
    }
    retrPtr->idleTime++;
    if (retrPtr->idleTime >= 5) {
	/*
	 * Use a careful function to store the error message, because the
	 * result could already be partially filled in with a partial
	 * selection return.
	 */

	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection owner didn't respond", -1));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "IGNORED", NULL);

	retrPtr->result = TCL_ERROR;
    } else {
	retrPtr->timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
		retrPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertSelection --







|

















<
|
<
>



|







731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756

757
758
759
760
761
762
763
764
765
766
767
768
 *----------------------------------------------------------------------
 */

static void
SelTimeoutProc(
    ClientData clientData)	/* Information about retrieval in progress. */
{
    register TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *) clientData;

    /*
     * Make sure that the retrieval is still in progress. Then see how long
     * it's been since any sort of response was received from the other side.
     */

    if (retrPtr->result != -1) {
	return;
    }
    retrPtr->idleTime++;
    if (retrPtr->idleTime >= 5) {
	/*
	 * Use a careful function to store the error message, because the
	 * result could already be partially filled in with a partial
	 * selection return.
	 */


	Tcl_SetResult(retrPtr->interp, "selection owner didn't respond",

		TCL_STATIC);
	retrPtr->result = TCL_ERROR;
    } else {
	retrPtr->timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
		(ClientData) retrPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertSelection --
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844

static void
ConvertSelection(
    TkWindow *winPtr,		/* Window that received the conversion
				 * request; may not be selection's current
				 * owner, be we set it to the current
				 * owner. */
    XSelectionRequestEvent *eventPtr)
				/* Event describing request. */
{
	union {
		XSelectionEvent xsel;
		XEvent ev;
	} reply;	/* Used to notify requestor that selection
				 * info is ready. */
    int multiple;		/* Non-zero means a MULTIPLE request is being
				 * handled. */
    IncrInfo incr;		/* State of selection conversion. */
    Atom singleInfo[2];		/* incr.multAtoms points here except for
				 * multiple conversions. */
    unsigned long i;
    Tk_ErrorHandler errorHandler;
    TkSelectionInfo *infoPtr;
    TkSelInProgress ip;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    errorHandler = Tk_CreateErrorHandler(eventPtr->display, -1, -1,
	    -1, NULL, NULL);

    /*
     * Initialize the reply event.
     */

    reply.xsel.type = SelectionNotify;
    reply.xsel.serial = 0;
    reply.xsel.send_event = True;
    reply.xsel.display = eventPtr->display;
    reply.xsel.requestor = eventPtr->requestor;
    reply.xsel.selection = eventPtr->selection;
    reply.xsel.target = eventPtr->target;
    reply.xsel.property = eventPtr->property;
    if (reply.xsel.property == None) {
	reply.xsel.property = reply.xsel.target;
    }
    reply.xsel.time = eventPtr->time;

    for (infoPtr = winPtr->dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == eventPtr->selection) {
	    break;
	}
    }







|


<
<
<
|













|
|





|
|
|
|
|
|
|
|
|
|

|







784
785
786
787
788
789
790
791
792
793



794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833

static void
ConvertSelection(
    TkWindow *winPtr,		/* Window that received the conversion
				 * request; may not be selection's current
				 * owner, be we set it to the current
				 * owner. */
    register XSelectionRequestEvent *eventPtr)
				/* Event describing request. */
{



    XSelectionEvent reply;	/* Used to notify requestor that selection
				 * info is ready. */
    int multiple;		/* Non-zero means a MULTIPLE request is being
				 * handled. */
    IncrInfo incr;		/* State of selection conversion. */
    Atom singleInfo[2];		/* incr.multAtoms points here except for
				 * multiple conversions. */
    unsigned long i;
    Tk_ErrorHandler errorHandler;
    TkSelectionInfo *infoPtr;
    TkSelInProgress ip;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    errorHandler = Tk_CreateErrorHandler(eventPtr->display, -1, -1,-1,
	    (int (*)()) NULL, NULL);

    /*
     * Initialize the reply event.
     */

    reply.type = SelectionNotify;
    reply.serial = 0;
    reply.send_event = True;
    reply.display = eventPtr->display;
    reply.requestor = eventPtr->requestor;
    reply.selection = eventPtr->selection;
    reply.target = eventPtr->target;
    reply.property = eventPtr->property;
    if (reply.property == None) {
	reply.property = reply.target;
    }
    reply.time = eventPtr->time;

    for (infoPtr = winPtr->dispPtr->selectionInfoPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == eventPtr->selection) {
	    break;
	}
    }
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
     * conversions to perform.
     */

    incr.winPtr = winPtr;
    incr.selection = eventPtr->selection;
    if (eventPtr->target != winPtr->dispPtr->multipleAtom) {
	multiple = 0;
	singleInfo[0] = reply.xsel.target;
	singleInfo[1] = reply.xsel.property;
	incr.multAtoms = singleInfo;
	incr.numConversions = 1;
    } else {
	Atom type, **multAtomsPtr = &incr.multAtoms;
	int format, result;
	unsigned long bytesAfter;

	multiple = 1;
	incr.multAtoms = NULL;
	if (eventPtr->property == None) {
	    goto refuse;
	}
	result = XGetWindowProperty(eventPtr->display, eventPtr->requestor,
		eventPtr->property, 0, MAX_PROP_WORDS, False,
		winPtr->dispPtr->atomPairAtom, &type, &format,
		&incr.numConversions, &bytesAfter,
		(unsigned char **) multAtomsPtr);
	if ((result != Success) || (bytesAfter != 0) || (format != 32)
		|| (type == None)) {
	    if (incr.multAtoms != NULL) {
		XFree((char *) incr.multAtoms);
	    }
	    goto refuse;
	}
	incr.numConversions /= 2;	/* Two atoms per conversion. */
    }

    /*
     * Loop through all of the requested conversions, and either return the
     * entire converted selection, if it can be returned in a single bunch, or
     * return INCR information only (the actual selection will be returned
     * below).
     */

    incr.converts = (ConvertInfo *)ckalloc(incr.numConversions * sizeof(ConvertInfo));

    incr.numIncrs = 0;
    for (i = 0; i < incr.numConversions; i++) {
	Atom target, property, type;
	long buffer[TK_SEL_WORDS_AT_ONCE];
	TkSelHandler *selPtr;
	int numItems, format;
	char *propPtr;

	target = incr.multAtoms[2*i];
	property = incr.multAtoms[2*i + 1];
	incr.converts[i].offset = -1;
	incr.converts[i].buffer[0] = '\0';

	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->target == target)
		    && (selPtr->selection == eventPtr->selection)) {
		break;
	    }
	}

	if (selPtr == NULL) {
	    /*
	     * Nobody seems to know about this kind of request. If it's of a
	     * sort that we can handle without any help, do it. Otherwise mark
	     * the request as an error.
	     */

	    numItems = TkSelDefaultSelection(infoPtr, target, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);
	    if (numItems < 0) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	} else {
	    ip.selPtr = selPtr;
	    ip.nextPtr = TkSelGetInProgress();
	    TkSelSetInProgress(&ip);
	    type = selPtr->format;
	    numItems = selPtr->proc(selPtr->clientData, 0, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE);
	    TkSelSetInProgress(ip.nextPtr);
	    if ((ip.selPtr == NULL) || (numItems < 0)) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    if (numItems > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");







|
|













|
<
|








|









|
>




|




















|













|
|







842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864

865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
     * conversions to perform.
     */

    incr.winPtr = winPtr;
    incr.selection = eventPtr->selection;
    if (eventPtr->target != winPtr->dispPtr->multipleAtom) {
	multiple = 0;
	singleInfo[0] = reply.target;
	singleInfo[1] = reply.property;
	incr.multAtoms = singleInfo;
	incr.numConversions = 1;
    } else {
	Atom type, **multAtomsPtr = &incr.multAtoms;
	int format, result;
	unsigned long bytesAfter;

	multiple = 1;
	incr.multAtoms = NULL;
	if (eventPtr->property == None) {
	    goto refuse;
	}
	result = XGetWindowProperty(eventPtr->display, eventPtr->requestor,
		eventPtr->property, 0, MAX_PROP_WORDS, False, XA_ATOM,

		&type, &format, &incr.numConversions, &bytesAfter,
		(unsigned char **) multAtomsPtr);
	if ((result != Success) || (bytesAfter != 0) || (format != 32)
		|| (type == None)) {
	    if (incr.multAtoms != NULL) {
		XFree((char *) incr.multAtoms);
	    }
	    goto refuse;
	}
	incr.numConversions /= 2;		/* Two atoms per conversion. */
    }

    /*
     * Loop through all of the requested conversions, and either return the
     * entire converted selection, if it can be returned in a single bunch, or
     * return INCR information only (the actual selection will be returned
     * below).
     */

    incr.converts = (ConvertInfo *)
	    ckalloc((unsigned) incr.numConversions * sizeof(ConvertInfo));
    incr.numIncrs = 0;
    for (i = 0; i < incr.numConversions; i++) {
	Atom target, property, type;
	long buffer[TK_SEL_WORDS_AT_ONCE];
	register TkSelHandler *selPtr;
	int numItems, format;
	char *propPtr;

	target = incr.multAtoms[2*i];
	property = incr.multAtoms[2*i + 1];
	incr.converts[i].offset = -1;
	incr.converts[i].buffer[0] = '\0';

	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->target == target)
		    && (selPtr->selection == eventPtr->selection)) {
		break;
	    }
	}

	if (selPtr == NULL) {
	    /*
	     * Nobody seems to know about this kind of request. If it's of a
	     * sort that we can handle without any help, do it. Otherwise mark
	     * the request as an errror.
	     */

	    numItems = TkSelDefaultSelection(infoPtr, target, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);
	    if (numItems < 0) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	} else {
	    ip.selPtr = selPtr;
	    ip.nextPtr = TkSelGetInProgress();
	    TkSelSetInProgress(&ip);
	    type = selPtr->format;
	    numItems = (*selPtr->proc)(selPtr->clientData, 0,
		    (char *) buffer, TK_SEL_BYTES_AT_ONCE);
	    TkSelSetInProgress(ip.nextPtr);
	    if ((ip.selPtr == NULL) || (numItems < 0)) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    if (numItems > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    numItems = 1;
	    propPtr = (char *) buffer;
	    format = 32;
	    incr.converts[i].offset = 0;
	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, format, PropModeReplace,
		    (unsigned char *) propPtr, numItems);
	} else if (type == winPtr->dispPtr->utf8Atom) {
	    /*
	     * This matches selection requests of type UTF8_STRING, which
	     * allows us to pass our utf-8 information untouched.
	     */

	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, 8, PropModeReplace,
		    (unsigned char *) buffer, numItems);
	} else if ((type == XA_STRING)
		|| (type == winPtr->dispPtr->compoundTextAtom)) {
	    Tcl_DString ds;
	    Tcl_Encoding encoding;

	    /*
	     * STRING is Latin-1, COMPOUND_TEXT is an iso2022 variant. We need
	     * to convert the selection text into these external forms before
	     * modifying the property.
	     */

	    if (type == XA_STRING) {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    }
	    Tcl_UtfToExternalDString(encoding, (char *) buffer, -1, &ds);
	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, 8, PropModeReplace,
		    (unsigned char *) Tcl_DStringValue(&ds),
		    Tcl_DStringLength(&ds));
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    Tcl_DStringFree(&ds);
	} else {
	    propPtr = (char *) SelCvtToX((char *) buffer,
		    type, (Tk_Window) winPtr, &numItems);
	    if (propPtr == NULL) {
		goto refuse;
	    }
	    format = 32;
	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, format, PropModeReplace,
		    (unsigned char *) propPtr, numItems);
	    ckfree(propPtr);
	}
    }

    /*
     * Send an event back to the requestor to indicate that the first stage of
     * conversion is complete (everything is done except for long conversions
     * that have to be done in INCR mode).
     */

    if (incr.numIncrs > 0) {
	XSelectInput(reply.xsel.display, reply.xsel.requestor,
		PropertyChangeMask);
	incr.timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc, &incr);

	incr.idleTime = 0;
	incr.reqWindow = reply.xsel.requestor;
	incr.time = infoPtr->time;
	incr.nextPtr = tsdPtr->pendingIncrs;
	tsdPtr->pendingIncrs = &incr;
    }
    if (multiple) {
	XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		reply.xsel.property, winPtr->dispPtr->atomPairAtom,
		32, PropModeReplace, (unsigned char *) incr.multAtoms,
		(int) incr.numConversions*2);
    } else {
	/*
	 * Not a MULTIPLE request. The first property in "multAtoms" got set
	 * to None if there was an error in conversion.
	 */

	reply.xsel.property = incr.multAtoms[1];
    }
    XSendEvent(reply.xsel.display, reply.xsel.requestor, False, 0, &reply.ev);
    Tk_DeleteErrorHandler(errorHandler);

    /*
     * Handle any remaining INCR-mode transfers. This all happens in callbacks
     * to TkSelPropProc, so just wait until the number of uncompleted INCR
     * transfers drops to zero.
     */

    if (incr.numIncrs > 0) {
	IncrInfo *incrPtr2;

	while (incr.numIncrs > 0) {
	    Tcl_DoOneEvent(0);
	}
	Tcl_DeleteTimerHandler(incr.timeout);
	errorHandler = Tk_CreateErrorHandler(winPtr->display,
		-1, -1, -1, NULL, NULL);
	XSelectInput(reply.xsel.display, reply.xsel.requestor, 0L);
	Tk_DeleteErrorHandler(errorHandler);
	if (tsdPtr->pendingIncrs == &incr) {
	    tsdPtr->pendingIncrs = incr.nextPtr;
	} else {
	    for (incrPtr2 = tsdPtr->pendingIncrs; incrPtr2 != NULL;
		    incrPtr2 = incrPtr2->nextPtr) {
		if (incrPtr2->nextPtr == &incr) {
		    incrPtr2->nextPtr = incr.nextPtr;
		    break;
		}
	    }
	}
    }

    /*
     * All done. Cleanup and return.
     */

    ckfree(incr.converts);
    if (multiple) {
	XFree((char *) incr.multAtoms);
    }
    return;

    /*
     * An error occurred. Send back a refusal message.
     */

  refuse:
    reply.xsel.property = None;
    XSendEvent(reply.xsel.display, reply.xsel.requestor, False, 0, &reply.ev);
    Tk_DeleteErrorHandler(errorHandler);
    return;
}

/*
 *----------------------------------------------------------------------
 *







|








|
<
|

















|
<
|












|
|
|











<
|
|
>

|





|
|
|







|

|
















|
|


















|










|
|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    numItems = 1;
	    propPtr = (char *) buffer;
	    format = 32;
	    incr.converts[i].offset = 0;
	    XChangeProperty(reply.display, reply.requestor,
		    property, type, format, PropModeReplace,
		    (unsigned char *) propPtr, numItems);
	} else if (type == winPtr->dispPtr->utf8Atom) {
	    /*
	     * This matches selection requests of type UTF8_STRING, which
	     * allows us to pass our utf-8 information untouched.
	     */

	    XChangeProperty(reply.display, reply.requestor, property, type, 8,

		    PropModeReplace, (unsigned char *) buffer, numItems);
	} else if ((type == XA_STRING)
		|| (type == winPtr->dispPtr->compoundTextAtom)) {
	    Tcl_DString ds;
	    Tcl_Encoding encoding;

	    /*
	     * STRING is Latin-1, COMPOUND_TEXT is an iso2022 variant. We need
	     * to convert the selection text into these external forms before
	     * modifying the property.
	     */

	    if (type == XA_STRING) {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    }
	    Tcl_UtfToExternalDString(encoding, (char *) buffer, -1, &ds);
	    XChangeProperty(reply.display, reply.requestor, property, type, 8,

		    PropModeReplace, (unsigned char *) Tcl_DStringValue(&ds),
		    Tcl_DStringLength(&ds));
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    Tcl_DStringFree(&ds);
	} else {
	    propPtr = (char *) SelCvtToX((char *) buffer,
		    type, (Tk_Window) winPtr, &numItems);
	    if (propPtr == NULL) {
		goto refuse;
	    }
	    format = 32;
	    XChangeProperty(reply.display, reply.requestor, property, type,
		    format, PropModeReplace, (unsigned char *) propPtr,
		    numItems);
	    ckfree(propPtr);
	}
    }

    /*
     * Send an event back to the requestor to indicate that the first stage of
     * conversion is complete (everything is done except for long conversions
     * that have to be done in INCR mode).
     */

    if (incr.numIncrs > 0) {

	XSelectInput(reply.display, reply.requestor, PropertyChangeMask);
	incr.timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc,
	    (ClientData) &incr);
	incr.idleTime = 0;
	incr.reqWindow = reply.requestor;
	incr.time = infoPtr->time;
	incr.nextPtr = tsdPtr->pendingIncrs;
	tsdPtr->pendingIncrs = &incr;
    }
    if (multiple) {
	XChangeProperty(reply.display, reply.requestor, reply.property,
		XA_ATOM, 32, PropModeReplace,
		(unsigned char *) incr.multAtoms,
		(int) incr.numConversions*2);
    } else {
	/*
	 * Not a MULTIPLE request. The first property in "multAtoms" got set
	 * to None if there was an error in conversion.
	 */

	reply.property = incr.multAtoms[1];
    }
    XSendEvent(reply.display, reply.requestor, False, 0, (XEvent *) &reply);
    Tk_DeleteErrorHandler(errorHandler);

    /*
     * Handle any remaining INCR-mode transfers. This all happens in callbacks
     * to TkSelPropProc, so just wait until the number of uncompleted INCR
     * transfers drops to zero.
     */

    if (incr.numIncrs > 0) {
	IncrInfo *incrPtr2;

	while (incr.numIncrs > 0) {
	    Tcl_DoOneEvent(0);
	}
	Tcl_DeleteTimerHandler(incr.timeout);
	errorHandler = Tk_CreateErrorHandler(winPtr->display,
		-1, -1,-1, (int (*)()) NULL, NULL);
	XSelectInput(reply.display, reply.requestor, 0L);
	Tk_DeleteErrorHandler(errorHandler);
	if (tsdPtr->pendingIncrs == &incr) {
	    tsdPtr->pendingIncrs = incr.nextPtr;
	} else {
	    for (incrPtr2 = tsdPtr->pendingIncrs; incrPtr2 != NULL;
		    incrPtr2 = incrPtr2->nextPtr) {
		if (incrPtr2->nextPtr == &incr) {
		    incrPtr2->nextPtr = incr.nextPtr;
		    break;
		}
	    }
	}
    }

    /*
     * All done. Cleanup and return.
     */

    ckfree((char *) incr.converts);
    if (multiple) {
	XFree((char *) incr.multAtoms);
    }
    return;

    /*
     * An error occurred. Send back a refusal message.
     */

  refuse:
    reply.property = None;
    XSendEvent(reply.display, reply.requestor, False, 0, (XEvent *) &reply);
    Tk_DeleteErrorHandler(errorHandler);
    return;
}

/*
 *----------------------------------------------------------------------
 *
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

1166

1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
 *
 *----------------------------------------------------------------------
 */

static void
SelRcvIncrProc(
    ClientData clientData,	/* Information about retrieval. */
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    Atom type;
    int format, result;
    unsigned long numItems, bytesAfter;
    Tcl_Interp *interp;

    if ((eventPtr->xproperty.atom != retrPtr->property)
	    || (eventPtr->xproperty.state != PropertyNewValue)
	    || (retrPtr->result != -1)) {
	return;
    }
    propInfo = NULL;
    result = XGetWindowProperty(eventPtr->xproperty.display,
	    eventPtr->xproperty.window, retrPtr->property, 0, MAX_PROP_WORDS,
	    True, (Atom) AnyPropertyType, &type, &format, &numItems,
	    &bytesAfter, (unsigned char **) propInfoPtr);
    if ((result != Success) || (type == None)) {
	return;
    }
    if (bytesAfter != 0) {
	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection property too large", -1));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE", NULL);

	retrPtr->result = TCL_ERROR;
	goto done;
    }
    if ((type == XA_STRING)
	    || (type == retrPtr->winPtr->dispPtr->textAtom)
	    || (type == retrPtr->winPtr->dispPtr->utf8Atom)
	    || (type == retrPtr->winPtr->dispPtr->compoundTextAtom)) {
	char *dst, *src;
	int srcLen, dstLen, srcRead, dstWrote, soFar;
	Tcl_Encoding encoding;
	Tcl_DString *dstPtr, temp;

	if (format != 8) {

	    Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(

		    "bad format for string selection: wanted \"8\", got \"%d\"",
		    format));
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
		    NULL);
	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	interp = retrPtr->interp;
	Tcl_Preserve(interp);

	if (type == retrPtr->winPtr->dispPtr->compoundTextAtom) {
	    encoding = Tcl_GetEncoding(NULL, "iso2022");
	} else if (type == retrPtr->winPtr->dispPtr->utf8Atom) {
	    encoding = Tcl_GetEncoding(NULL, "utf-8");
	} else {
	    encoding = Tcl_GetEncoding(NULL, "iso8859-1");







|

|




















<
|
<
>













>
|
>

|
|
<




|







1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136

1137

1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
 *
 *----------------------------------------------------------------------
 */

static void
SelRcvIncrProc(
    ClientData clientData,	/* Information about retrieval. */
    register XEvent *eventPtr)	/* X PropertyChange event. */
{
    register TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *) clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    Atom type;
    int format, result;
    unsigned long numItems, bytesAfter;
    Tcl_Interp *interp;

    if ((eventPtr->xproperty.atom != retrPtr->property)
	    || (eventPtr->xproperty.state != PropertyNewValue)
	    || (retrPtr->result != -1)) {
	return;
    }
    propInfo = NULL;
    result = XGetWindowProperty(eventPtr->xproperty.display,
	    eventPtr->xproperty.window, retrPtr->property, 0, MAX_PROP_WORDS,
	    True, (Atom) AnyPropertyType, &type, &format, &numItems,
	    &bytesAfter, (unsigned char **) propInfoPtr);
    if ((result != Success) || (type == None)) {
	return;
    }
    if (bytesAfter != 0) {

	Tcl_SetResult(retrPtr->interp, "selection property too large",

		TCL_STATIC);
	retrPtr->result = TCL_ERROR;
	goto done;
    }
    if ((type == XA_STRING)
	    || (type == retrPtr->winPtr->dispPtr->textAtom)
	    || (type == retrPtr->winPtr->dispPtr->utf8Atom)
	    || (type == retrPtr->winPtr->dispPtr->compoundTextAtom)) {
	char *dst, *src;
	int srcLen, dstLen, srcRead, dstWrote, soFar;
	Tcl_Encoding encoding;
	Tcl_DString *dstPtr, temp;

	if (format != 8) {
	    char buf[64 + TCL_INTEGER_SPACE];

	    sprintf(buf,
		    "bad format for string selection: wanted \"8\", got \"%d\"",
		    format);
	    Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE);

	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	interp = retrPtr->interp;
	Tcl_Preserve((ClientData) interp);

	if (type == retrPtr->winPtr->dispPtr->compoundTextAtom) {
	    encoding = Tcl_GetEncoding(NULL, "iso2022");
	} else if (type == retrPtr->winPtr->dispPtr->utf8Atom) {
	    encoding = Tcl_GetEncoding(NULL, "utf-8");
	} else {
	    encoding = Tcl_GetEncoding(NULL, "iso8859-1");
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
	    srcLen = Tcl_DStringLength(&temp);
	} else if (numItems == 0) {
	    /*
	     * There is no new data, so we're done.
	     */

	    retrPtr->result = TCL_OK;
	    Tcl_Release(interp);
	    goto done;
	} else {
	    src = propInfo;
	    srcLen = numItems;
	}

	/*







|







1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
	    srcLen = Tcl_DStringLength(&temp);
	} else if (numItems == 0) {
	    /*
	     * There is no new data, so we're done.
	     */

	    retrPtr->result = TCL_OK;
	    Tcl_Release((ClientData) interp);
	    goto done;
	} else {
	    src = propInfo;
	    srcLen = numItems;
	}

	/*
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
	    }
	    Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
	    dst = Tcl_DStringValue(dstPtr) + soFar;
	    dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
	}
	Tcl_DStringSetLength(dstPtr, soFar);

	result = retrPtr->proc(retrPtr->clientData, interp,
		Tcl_DStringValue(dstPtr));
	Tcl_Release(interp);

	/*
	 * Copy any unused data into the destination buffer so we can pick it
	 * up next time around.
	 */

	Tcl_DStringSetLength(dstPtr, 0);







|

|







1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
	    }
	    Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
	    dst = Tcl_DStringValue(dstPtr) + soFar;
	    dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
	}
	Tcl_DStringSetLength(dstPtr, soFar);

	result = (*retrPtr->proc)(retrPtr->clientData, interp,
		Tcl_DStringValue(dstPtr));
	Tcl_Release((ClientData) interp);

	/*
	 * Copy any unused data into the destination buffer so we can pick it
	 * up next time around.
	 */

	Tcl_DStringSetLength(dstPtr, 0);
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
	}
    } else if (numItems == 0) {
	retrPtr->result = TCL_OK;
    } else {
	Tcl_DString ds;

	if (format != 32 && format != 8) {

	    Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(
		    "bad format for selection: wanted \"32\" or "
		    "\"8\", got \"%d\"", format));
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
		    NULL);
	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	Tcl_DStringInit(&ds);
	if (format == 32) {
	    SelCvtFromX32((long *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	} else {
	    SelCvtFromX8((char *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	}
	interp = retrPtr->interp;
	Tcl_Preserve(interp);
	result = retrPtr->proc(retrPtr->clientData, interp,
		Tcl_DStringValue(&ds));
	Tcl_Release(interp);
	Tcl_DStringFree(&ds);
	if (result != TCL_OK) {
	    retrPtr->result = result;
	}
    }

  done:







>
|
|
|
|
<












|
|

|







1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
	}
    } else if (numItems == 0) {
	retrPtr->result = TCL_OK;
    } else {
	Tcl_DString ds;

	if (format != 32 && format != 8) {
	    char buf[64 + TCL_INTEGER_SPACE];

	    sprintf(buf, "bad format for selection: wanted \"32\" or "
		    "\"8\", got \"%d\"", format);
	    Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE);

	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	Tcl_DStringInit(&ds);
	if (format == 32) {
	    SelCvtFromX32((long *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	} else {
	    SelCvtFromX8((char *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	}
	interp = retrPtr->interp;
	Tcl_Preserve((ClientData) interp);
	result = (*retrPtr->proc)(retrPtr->clientData, interp,
		Tcl_DStringValue(&ds));
	Tcl_Release((ClientData) interp);
	Tcl_DStringFree(&ds);
	if (result != TCL_OK) {
	    retrPtr->result = result;
	}
    }

  done:
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345

    size = TK_SEL_BYTES_AT_ONCE;
    ip.selPtr = selPtr;
    ip.nextPtr = TkSelGetInProgress();
    TkSelSetInProgress(&ip);

    do {
	chunkSize = selPtr->proc(selPtr->clientData, size, (char *) buffer,
		TK_SEL_BYTES_AT_ONCE);
	if (ip.selPtr == NULL) {
	    size = 0;
	    break;
	}
	size += chunkSize;
    } while (chunkSize == TK_SEL_BYTES_AT_ONCE);







|







1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332

    size = TK_SEL_BYTES_AT_ONCE;
    ip.selPtr = selPtr;
    ip.nextPtr = TkSelGetInProgress();
    TkSelSetInProgress(&ip);

    do {
	chunkSize = (*selPtr->proc)(selPtr->clientData, size, (char *) buffer,
		TK_SEL_BYTES_AT_ONCE);
	if (ip.selPtr == NULL) {
	    size = 0;
	    break;
	}
	size += chunkSize;
    } while (chunkSize == TK_SEL_BYTES_AT_ONCE);
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391

static void
IncrTimeoutProc(
    ClientData clientData)	/* Information about INCR-mode selection
				 * retrieval for which we are selection
				 * owner. */
{
    IncrInfo *incrPtr = (IncrInfo *)clientData;

    incrPtr->idleTime++;
    if (incrPtr->idleTime >= 5) {
	incrPtr->numIncrs = 0;
    } else {
	incrPtr->timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc,
		incrPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SelCvtToX --







|






|







1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

static void
IncrTimeoutProc(
    ClientData clientData)	/* Information about INCR-mode selection
				 * retrieval for which we are selection
				 * owner. */
{
    register IncrInfo *incrPtr = (IncrInfo *) clientData;

    incrPtr->idleTime++;
    if (incrPtr->idleTime >= 5) {
	incrPtr->numIncrs = 0;
    } else {
	incrPtr->timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc,
		(ClientData) incrPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SelCvtToX --
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
     * 2. If type is anything else, convert each field from an ASCII number to
     *    a 32-bit binary number.
     */

    if (Tcl_SplitList(NULL, string, &numFields, &field) != TCL_OK) {
	return NULL;
    }
    propPtr = (long *)ckalloc(numFields * sizeof(long));

    /*
     * Convert the fields one-by-one.
     */

    for (i=0 ; i<numFields ; i++) {
	if (type == XA_ATOM) {







|







1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
     * 2. If type is anything else, convert each field from an ASCII number to
     *    a 32-bit binary number.
     */

    if (Tcl_SplitList(NULL, string, &numFields, &field) != TCL_OK) {
	return NULL;
    }
    propPtr = (long *) ckalloc((unsigned) numFields*sizeof(long));

    /*
     * Convert the fields one-by-one.
     */

    for (i=0 ; i<numFields ; i++) {
	if (type == XA_ATOM) {
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
	}
    }

    /*
     * Release the parsed list.
     */

    ckfree(field);
    *numLongsPtr = i;
    return propPtr;
}

/*
 *----------------------------------------------------------------------
 *







|







1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
	}
    }

    /*
     * Release the parsed list.
     */

    ckfree((char *) field);
    *numLongsPtr = i;
    return propPtr;
}

/*
 *----------------------------------------------------------------------
 *
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SelCvtFromX32(
    long *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 32-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{







|







1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SelCvtFromX32(
    register long *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 32-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
	}
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
SelCvtFromX8(
    char *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 8-bit values in property. */
    TCL_UNUSED(Atom),			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    TCL_UNUSED(Tk_Window),		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*
     * Convert each long in the property to a string value, which is a
     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */







|

|


|







1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
	}
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
SelCvtFromX8(
    register char *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 8-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*
     * Convert each long in the property to a string value, which is a
     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */

Changes to unix/tkUnixSend.c.

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 * commands. This could happen if interpreters invoke each other recursively.
 * It's unlikely, but possible.
 */

typedef struct PendingCommand {
    int serial;			/* Serial number expected in result. */
    TkDisplay *dispPtr;		/* Display being used for communication. */
    const char *target;		/* Name of interpreter command is being sent
				 * to. */
    Window commWindow;		/* Target's communication window. */
    Tcl_Interp *interp;		/* Interpreter from which the send was
				 * invoked. */
    int code;			/* Tcl return code for command will be stored
				 * here. */
    char *result;		/* String result for command (malloc'ed), or
				 * NULL. */
    char *errorInfo;		/* Information for "errorInfo" variable, or
				 * NULL (malloc'ed). */
    char *errorCode;		/* Information for "errorCode" variable, or
				 * NULL (malloc'ed). */
    int gotResponse;		/* 1 means a response has been received, 0
				 * means the command is still outstanding. */
    struct PendingCommand *nextPtr;
				/* Next in list of all outstanding commands.
				 * NULL means end of list. */
} PendingCommand;

typedef struct {
    PendingCommand *pendingCommands;
				/* List of all commands currently being waited
				 * for. */
    RegisteredInterp *interpListPtr;
				/* List of all interpreters registered in the
				 * current process. */
} ThreadSpecificData;







|



















|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 * commands. This could happen if interpreters invoke each other recursively.
 * It's unlikely, but possible.
 */

typedef struct PendingCommand {
    int serial;			/* Serial number expected in result. */
    TkDisplay *dispPtr;		/* Display being used for communication. */
    CONST char *target;		/* Name of interpreter command is being sent
				 * to. */
    Window commWindow;		/* Target's communication window. */
    Tcl_Interp *interp;		/* Interpreter from which the send was
				 * invoked. */
    int code;			/* Tcl return code for command will be stored
				 * here. */
    char *result;		/* String result for command (malloc'ed), or
				 * NULL. */
    char *errorInfo;		/* Information for "errorInfo" variable, or
				 * NULL (malloc'ed). */
    char *errorCode;		/* Information for "errorCode" variable, or
				 * NULL (malloc'ed). */
    int gotResponse;		/* 1 means a response has been received, 0
				 * means the command is still outstanding. */
    struct PendingCommand *nextPtr;
				/* Next in list of all outstanding commands.
				 * NULL means end of list. */
} PendingCommand;

typedef struct ThreadSpecificData {
    PendingCommand *pendingCommands;
				/* List of all commands currently being waited
				 * for. */
    RegisteredInterp *interpListPtr;
				/* List of all interpreters registered in the
				 * current process. */
} ThreadSpecificData;
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
static int		AppendErrorProc(ClientData clientData,
			    XErrorEvent *errorPtr);
static void		AppendPropCarefully(Display *display,
			    Window window, Atom property, char *value,
			    int length, PendingCommand *pendingPtr);
static void		DeleteProc(ClientData clientData);
static void		RegAddName(NameRegistry *regPtr,
			    const char *name, Window commWindow);
static void		RegClose(NameRegistry *regPtr);
static void		RegDeleteName(NameRegistry *regPtr, const char *name);
static Window		RegFindName(NameRegistry *regPtr, const char *name);
static NameRegistry *	RegOpen(Tcl_Interp *interp,
			    TkDisplay *dispPtr, int lock);
static void		SendEventProc(ClientData clientData, XEvent *eventPtr);
static int		SendInit(Tcl_Interp *interp, TkDisplay *dispPtr);
static Tk_RestrictProc SendRestrictProc;

static int		ServerSecure(TkDisplay *dispPtr);
static void		UpdateCommWindow(TkDisplay *dispPtr);
static int		ValidateName(TkDisplay *dispPtr, const char *name,
			    Window commWindow, int oldOK);

/*
 *----------------------------------------------------------------------
 *
 * RegOpen --
 *







|

|
|




|
>


|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
static int		AppendErrorProc(ClientData clientData,
			    XErrorEvent *errorPtr);
static void		AppendPropCarefully(Display *display,
			    Window window, Atom property, char *value,
			    int length, PendingCommand *pendingPtr);
static void		DeleteProc(ClientData clientData);
static void		RegAddName(NameRegistry *regPtr,
			    CONST char *name, Window commWindow);
static void		RegClose(NameRegistry *regPtr);
static void		RegDeleteName(NameRegistry *regPtr, CONST char *name);
static Window		RegFindName(NameRegistry *regPtr, CONST char *name);
static NameRegistry *	RegOpen(Tcl_Interp *interp,
			    TkDisplay *dispPtr, int lock);
static void		SendEventProc(ClientData clientData, XEvent *eventPtr);
static int		SendInit(Tcl_Interp *interp, TkDisplay *dispPtr);
static Tk_RestrictAction SendRestrictProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ServerSecure(TkDisplay *dispPtr);
static void		UpdateCommWindow(TkDisplay *dispPtr);
static int		ValidateName(TkDisplay *dispPtr, CONST char *name,
			    Window commWindow, int oldOK);

/*
 *----------------------------------------------------------------------
 *
 * RegOpen --
 *
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
				 * use the registry until we close it. */
{
    NameRegistry *regPtr;
    int result, actualFormat;
    unsigned long bytesAfter;
    Atom actualType;
    char **propertyPtr;
    Tk_ErrorHandler handler;

    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, dispPtr);
    }

    handler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1, NULL, NULL);

    regPtr = (NameRegistry *)ckalloc(sizeof(NameRegistry));
    regPtr->dispPtr = dispPtr;
    regPtr->locked = 0;
    regPtr->modified = 0;
    regPtr->allocedByX = 1;
    propertyPtr = &regPtr->property;

    if (lock && !localData.sendDebug) {







<





<
<
|







258
259
260
261
262
263
264

265
266
267
268
269


270
271
272
273
274
275
276
277
				 * use the registry until we close it. */
{
    NameRegistry *regPtr;
    int result, actualFormat;
    unsigned long bytesAfter;
    Atom actualType;
    char **propertyPtr;


    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, dispPtr);
    }



    regPtr = (NameRegistry *) ckalloc(sizeof(NameRegistry));
    regPtr->dispPtr = dispPtr;
    regPtr->locked = 0;
    regPtr->modified = 0;
    regPtr->allocedByX = 1;
    propertyPtr = &regPtr->property;

    if (lock && !localData.sendDebug) {
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	    XFree(regPtr->property);
	    regPtr->propLength = 0;
	    regPtr->property = NULL;
	}
	XDeleteProperty(dispPtr->display,
		RootWindow(dispPtr->display, 0),
		dispPtr->registryProperty);
        XSync(dispPtr->display, False);
    }

    Tk_DeleteErrorHandler(handler);

    /*
     * Xlib placed an extra null byte after the end of the property, just to
     * make sure that it is always NULL-terminated. Be sure to include this
     * byte in our count if it's needed to ensure null termination (note: as
     * of 8/95 I'm no longer sure why this code is needed; seems like it
     * shouldn't be).
     */







<


<
<







303
304
305
306
307
308
309

310
311


312
313
314
315
316
317
318
	    XFree(regPtr->property);
	    regPtr->propLength = 0;
	    regPtr->property = NULL;
	}
	XDeleteProperty(dispPtr->display,
		RootWindow(dispPtr->display, 0),
		dispPtr->registryProperty);

    }



    /*
     * Xlib placed an extra null byte after the end of the property, just to
     * make sure that it is always NULL-terminated. Be sure to include this
     * byte in our count if it's needed to ensure null termination (note: as
     * of 8/95 I'm no longer sure why this code is needed; seems like it
     * shouldn't be).
     */
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
 *----------------------------------------------------------------------
 */

static Window
RegFindName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    const char *name)		/* Name of an application. */
{
    char *p;

    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p;

	while ((*p != 0) && (!isspace(UCHAR(*p)))) {
	    p++;
	}
	if ((*p != 0) && (strcmp(name, p+1) == 0)) {
	    unsigned id;

	    if (sscanf(entry, "%x", &id) == 1) {
		/*
		 * Must cast from an unsigned int to a Window in case we are
		 * on a 64-bit architecture.
		 */








|










|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
 *----------------------------------------------------------------------
 */

static Window
RegFindName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    CONST char *name)		/* Name of an application. */
{
    char *p;

    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p;

	while ((*p != 0) && (!isspace(UCHAR(*p)))) {
	    p++;
	}
	if ((*p != 0) && (strcmp(name, p+1) == 0)) {
	    unsigned int id;

	    if (sscanf(entry, "%x", &id) == 1) {
		/*
		 * Must cast from an unsigned int to a Window in case we are
		 * on a 64-bit architecture.
		 */

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
 *----------------------------------------------------------------------
 */

static void
RegDeleteName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    const char *name)		/* Name of an application. */
{
    char *p;

    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p, *entryName;

	while ((*p != 0) && (!isspace(UCHAR(*p)))) {







|







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
 *----------------------------------------------------------------------
 */

static void
RegDeleteName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    CONST char *name)		/* Name of an application. */
{
    char *p;

    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p, *entryName;

	while ((*p != 0) && (!isspace(UCHAR(*p)))) {
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
 *----------------------------------------------------------------------
 */

static void
RegAddName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    const char *name,		/* Name of an application. The caller must
				 * ensure that this name isn't already
				 * registered. */
    Window commWindow)		/* X identifier for comm. window of
				 * application. */
{
    char id[30], *newProp;
    int idLength, newBytes;

    sprintf(id, "%x ", (unsigned) commWindow);
    idLength = strlen(id);
    newBytes = idLength + strlen(name) + 1;
    newProp = (char *)ckalloc(regPtr->propLength + newBytes);
    strcpy(newProp, id);
    strcpy(newProp+idLength, name);
    if (regPtr->property != NULL) {
	memcpy(newProp + newBytes, regPtr->property, regPtr->propLength);
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {







|








|


|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
 *----------------------------------------------------------------------
 */

static void
RegAddName(
    NameRegistry *regPtr,	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
    CONST char *name,		/* Name of an application. The caller must
				 * ensure that this name isn't already
				 * registered. */
    Window commWindow)		/* X identifier for comm. window of
				 * application. */
{
    char id[30], *newProp;
    int idLength, newBytes;

    sprintf(id, "%x ", (unsigned int) commWindow);
    idLength = strlen(id);
    newBytes = idLength + strlen(name) + 1;
    newProp = ckalloc((unsigned) (regPtr->propLength + newBytes));
    strcpy(newProp, id);
    strcpy(newProp+idLength, name);
    if (regPtr->property != NULL) {
	memcpy(newProp + newBytes, regPtr->property, regPtr->propLength);
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 */

static void
RegClose(
    NameRegistry *regPtr)	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
{
    Tk_ErrorHandler handler;

    handler = Tk_CreateErrorHandler(regPtr->dispPtr->display, -1, -1, -1,
            NULL, NULL);

    if (regPtr->modified) {
	if (!regPtr->locked && !localData.sendDebug) {
	    Tcl_Panic("The name registry was modified without being locked!");
	}
	XChangeProperty(regPtr->dispPtr->display,
		RootWindow(regPtr->dispPtr->display, 0),
		regPtr->dispPtr->registryProperty, XA_STRING, 8,







<
<
<
<
<







511
512
513
514
515
516
517





518
519
520
521
522
523
524
 */

static void
RegClose(
    NameRegistry *regPtr)	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
{





    if (regPtr->modified) {
	if (!regPtr->locked && !localData.sendDebug) {
	    Tcl_Panic("The name registry was modified without being locked!");
	}
	XChangeProperty(regPtr->dispPtr->display,
		RootWindow(regPtr->dispPtr->display, 0),
		regPtr->dispPtr->registryProperty, XA_STRING, 8,
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
     * as invoking a subprocess that needs to do I/O to the screen); if the
     * ungrab command is still sitting in our output buffer, we could
     * deadlock.
     */

    XFlush(regPtr->dispPtr->display);

    Tk_DeleteErrorHandler(handler);

    if (regPtr->property != NULL) {
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {
	    ckfree(regPtr->property);
	}
    }
    ckfree(regPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ValidateName --
 *







<
<







|







537
538
539
540
541
542
543


544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
     * as invoking a subprocess that needs to do I/O to the screen); if the
     * ungrab command is still sitting in our output buffer, we could
     * deadlock.
     */

    XFlush(regPtr->dispPtr->display);



    if (regPtr->property != NULL) {
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {
	    ckfree(regPtr->property);
	}
    }
    ckfree((char *) regPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ValidateName --
 *
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
 *----------------------------------------------------------------------
 */

static int
ValidateName(
    TkDisplay *dispPtr,		/* Display for which to perform the
				 * validation. */
    const char *name,		/* The name of an application. */
    Window commWindow,		/* X identifier for the application's comm.
				 * window. */
    int oldOK)			/* Non-zero means that we should consider an
				 * application to be valid even if it looks
				 * like an old-style (pre-4.0) one; 0 means
				 * consider these invalid. */
{
    int result, actualFormat, argc, i;
    unsigned long length, bytesAfter;
    Atom actualType;
    char *property, **propertyPtr = &property;
    Tk_ErrorHandler handler;
    const char **argv;

    property = NULL;

    /*
     * Ignore X errors when reading the property (e.g., the window might not
     * exist). If an error occurs, result will be some value other than
     * Success.







|












|







569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
 *----------------------------------------------------------------------
 */

static int
ValidateName(
    TkDisplay *dispPtr,		/* Display for which to perform the
				 * validation. */
    CONST char *name,		/* The name of an application. */
    Window commWindow,		/* X identifier for the application's comm.
				 * window. */
    int oldOK)			/* Non-zero means that we should consider an
				 * application to be valid even if it looks
				 * like an old-style (pre-4.0) one; 0 means
				 * consider these invalid. */
{
    int result, actualFormat, argc, i;
    unsigned long length, bytesAfter;
    Atom actualType;
    char *property, **propertyPtr = &property;
    Tk_ErrorHandler handler;
    CONST char **argv;

    property = NULL;

    /*
     * Ignore X errors when reading the property (e.g., the window might not
     * exist). If an error occurs, result will be some value other than
     * Success.
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
	if (Tcl_SplitList(NULL, property, &argc, &argv) == TCL_OK) {
	    for (i = 0; i < argc; i++) {
		if (strcmp(argv[i], name) == 0) {
		    result = 1;
		    break;
		}
	    }
	    ckfree(argv);
	}
    } else {
	result = 0;
    }
    Tk_DeleteErrorHandler(handler);
    if (property != NULL) {
	XFree(property);







|







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
	if (Tcl_SplitList(NULL, property, &argc, &argv) == TCL_OK) {
	    for (i = 0; i < argc; i++) {
		if (strcmp(argv[i], name) == 0) {
		    result = 1;
		    break;
		}
	    }
	    ckfree((char *) argv);
	}
    } else {
	result = 0;
    }
    Tk_DeleteErrorHandler(handler);
    if (property != NULL) {
	XFree(property);
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
	secure = 1;
#else
	/*
	 * We don't understand what the X server is letting in, so we err on
	 * the side of safety.
	 */

	secure = 0;
#endif /* FamilyServerInterpreted */
    }
    if (addrPtr != NULL) {
	XFree((char *) addrPtr);
    }
    return secure;
#endif /* TK_NO_SECURITY */
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetAppName --
 *
 *	This function is called to associate an ASCII name with a Tk
 *	application. If the application has already been named, the name
 *	replaces the old one.
 *
 * Results:
 *	The return value is the name actually given to the application. This
 *	will normally be the same as name, but if name was already in use for
 *	an application then a name of the form "name #2" will be chosen, with
 *	a high enough number to make the name unique.
 *
 * Side effects:
 *	Registration info is saved, thereby allowing the "send" command to be
 *	used later to invoke commands in the application. In addition, the
 *	"send" command is created in the application's interpreter. The
 *	registration will be removed automatically if the interpreter is
 *	deleted or the "send" command is removed.
 *
 *----------------------------------------------------------------------
 */

const char *
Tk_SetAppName(
    Tk_Window tkwin,		/* Token for any window in the application to
				 * be named: it is just used to identify the
				 * application and the display. */
    const char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
    RegisteredInterp *riPtr, *riPtr2;
    Window w;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    NameRegistry *regPtr;
    Tcl_Interp *interp;
    const char *actualName;
    Tcl_DString dString;
    int offset, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    interp = winPtr->mainPtr->interp;
    if (dispPtr->commTkwin == NULL) {







|










|




















|


|




|









|







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
	secure = 1;
#else
	/*
	 * We don't understand what the X server is letting in, so we err on
	 * the side of safety.
	 */

	goto insecure;
#endif /* FamilyServerInterpreted */
    }
    if (addrPtr != NULL) {
	XFree((char *) addrPtr);
    }
    return secure;
#endif /* TK_NO_SECURITY */
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SetAppName --
 *
 *	This function is called to associate an ASCII name with a Tk
 *	application. If the application has already been named, the name
 *	replaces the old one.
 *
 * Results:
 *	The return value is the name actually given to the application. This
 *	will normally be the same as name, but if name was already in use for
 *	an application then a name of the form "name #2" will be chosen, with
 *	a high enough number to make the name unique.
 *
 * Side effects:
 *	Registration info is saved, thereby allowing the "send" command to be
 *	used later to invoke commands in the application. In addition, the
 *	"send" command is created in the application's interpreter. The
 *	registration will be removed automatically if the interpreter is
 *	deleted or the "send" command is removed.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_SetAppName(
    Tk_Window tkwin,		/* Token for any window in the application to
				 * be named: it is just used to identify the
				 * application and the display. */
    CONST char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
    RegisteredInterp *riPtr, *riPtr2;
    Window w;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    NameRegistry *regPtr;
    Tcl_Interp *interp;
    CONST char *actualName;
    Tcl_DString dString;
    int offset, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    interp = winPtr->mainPtr->interp;
    if (dispPtr->commTkwin == NULL) {
826
827
828
829
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
	if (riPtr == NULL) {
	    /*
	     * This interpreter isn't currently registered; create the data
	     * structure that will be used to register it locally, plus add
	     * the "send" command to the interpreter.
	     */

	    riPtr = (RegisteredInterp *)ckalloc(sizeof(RegisteredInterp));
	    riPtr->interp = interp;
	    riPtr->dispPtr = winPtr->dispPtr;
	    riPtr->nextPtr = tsdPtr->interpListPtr;
	    tsdPtr->interpListPtr = riPtr;
	    riPtr->name = NULL;
	    Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd, riPtr, DeleteProc);

	    if (Tcl_IsSafe(interp)) {
		Tcl_HideCommand(interp, "send", "send");
	    }
	    break;
	}
	if (riPtr->interp == interp) {
	    /*







|





|
>







814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
	if (riPtr == NULL) {
	    /*
	     * This interpreter isn't currently registered; create the data
	     * structure that will be used to register it locally, plus add
	     * the "send" command to the interpreter.
	     */

	    riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
	    riPtr->interp = interp;
	    riPtr->dispPtr = winPtr->dispPtr;
	    riPtr->nextPtr = tsdPtr->interpListPtr;
	    tsdPtr->interpListPtr = riPtr;
	    riPtr->name = NULL;
	    Tcl_CreateCommand(interp, "send", Tk_SendCmd, (ClientData) riPtr,
		    DeleteProc);
	    if (Tcl_IsSafe(interp)) {
		Tcl_HideCommand(interp, "send", "send");
	    }
	    break;
	}
	if (riPtr->interp == interp) {
	    /*
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989


990

991

992
993
994
995
996

997
998
999




1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
     * We've now got a name to use. Store it in the name registry and in the
     * local entry for this application, plus put it in a property on the
     * commWindow.
     */

    RegAddName(regPtr, actualName, Tk_WindowId(dispPtr->commTkwin));
    RegClose(regPtr);
    riPtr->name = (char *)ckalloc(strlen(actualName) + 1);
    strcpy(riPtr->name, actualName);
    if (actualName != name) {
	Tcl_DStringFree(&dString);
    }
    UpdateCommWindow(dispPtr);

    return riPtr->name;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SendObjCmd --
 *
 *	This function is invoked to process the "send" Tcl command. See the
 *	user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    TCL_UNUSED(void *),	/* Information about sender (only dispPtr
				 * field is used). */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    TkWindow *winPtr;
    Window commWindow;
    PendingCommand pending;
    RegisteredInterp *riPtr;
    const char *destName;
    int result, index, async, i, firstArg;

    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    TkDisplay *dispPtr;
    Tcl_Time timeout;
    NameRegistry *regPtr;
    Tcl_DString request;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Interp *localInterp;	/* Used when the interpreter to send the
				 * command to is within the same process. */

    /*
     * Process options, if any.
     */

    async = 0;
    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    break;
	}
	if (index == SEND_ASYNC) {


	    ++async;

	} else if (index == SEND_DISPLAYOF) {

	    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[++i]),
		    (Tk_Window) winPtr);
	    if (winPtr == NULL) {
		return TCL_ERROR;
	    }

	} else if (index == SEND_LAST) {
	    i++;
	    break;




	}
    }

    if (objc < (i+2)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-option value ...? interpName arg ?arg ...?");
	return TCL_ERROR;
    }
    destName = Tcl_GetString(objv[i]);
    firstArg = i+1;

    dispPtr = winPtr->dispPtr;
    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, winPtr->dispPtr);
    }

    /*
     * See if the target interpreter is local. If so, execute the command
     * directly without going through the X server. The only tricky thing is
     * passing the result from the target interpreter to the invoking
     * interpreter. Watch out: they could be the same!
     */

    for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
	    riPtr = riPtr->nextPtr) {
	if ((riPtr->dispPtr != dispPtr)
		|| (strcmp(riPtr->name, destName) != 0)) {
	    continue;
	}
	Tcl_Preserve(riPtr);
	localInterp = riPtr->interp;
	Tcl_Preserve(localInterp);
	if (firstArg == (objc-1)) {
	    result = Tcl_EvalEx(localInterp, Tcl_GetString(objv[firstArg]), -1, TCL_EVAL_GLOBAL);
	} else {
	    Tcl_DStringInit(&request);
	    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
	    for (i = firstArg+1; i < objc; i++) {
		Tcl_DStringAppend(&request, " ", 1);
		Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
	    }
	    result = Tcl_EvalEx(localInterp, Tcl_DStringValue(&request), -1, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(&request);
	}
	if (interp != localInterp) {
	    if (result == TCL_ERROR) {
		Tcl_Obj *errorObjPtr;







|












|














|
|


|
|

<
<
<
<
<
<



|
|
|
>
|



















|
|
<


|
>
>
|
>
|
>
|




>
|


>
>
>
>



|
|
|


|




















|

|
|
|


|
|

|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940






941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969

970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
     * We've now got a name to use. Store it in the name registry and in the
     * local entry for this application, plus put it in a property on the
     * commWindow.
     */

    RegAddName(regPtr, actualName, Tk_WindowId(dispPtr->commTkwin));
    RegClose(regPtr);
    riPtr->name = (char *) ckalloc((unsigned) (strlen(actualName) + 1));
    strcpy(riPtr->name, actualName);
    if (actualName != name) {
	Tcl_DStringFree(&dString);
    }
    UpdateCommWindow(dispPtr);

    return riPtr->name;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_SendCmd --
 *
 *	This function is invoked to process the "send" Tcl command. See the
 *	user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendCmd(
    ClientData clientData,	/* Information about sender (only dispPtr
				 * field is used). */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    CONST char **argv)		/* Argument strings. */
{






    TkWindow *winPtr;
    Window commWindow;
    PendingCommand pending;
    register RegisteredInterp *riPtr;
    CONST char *destName;
    int result, c, async, i, firstArg;
    size_t length;
    Tk_RestrictProc *prevRestrictProc;
    ClientData prevArg;
    TkDisplay *dispPtr;
    Tcl_Time timeout;
    NameRegistry *regPtr;
    Tcl_DString request;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Interp *localInterp;	/* Used when the interpreter to send the
				 * command to is within the same process. */

    /*
     * Process options, if any.
     */

    async = 0;
    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    for (i = 1; i < (argc-1); ) {
	if (argv[i][0] != '-') {

	    break;
	}
	c = argv[i][1];
	length = strlen(argv[i]);
	if ((c == 'a') && (strncmp(argv[i], "-async", length) == 0)) {
	    async = 1;
	    i++;
	} else if ((c == 'd') && (strncmp(argv[i], "-displayof",
		length) == 0)) {
	    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[i+1],
		    (Tk_Window) winPtr);
	    if (winPtr == NULL) {
		return TCL_ERROR;
	    }
	    i += 2;
	} else if (strcmp(argv[i], "--") == 0) {
	    i++;
	    break;
	} else {
	    Tcl_AppendResult(interp, "bad option \"", argv[i],
		    "\": must be -async, -displayof, or --", NULL);
	    return TCL_ERROR;
	}
    }

    if (argc < (i+2)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?options? interpName arg ?arg ...?\"", NULL);
	return TCL_ERROR;
    }
    destName = argv[i];
    firstArg = i+1;

    dispPtr = winPtr->dispPtr;
    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, winPtr->dispPtr);
    }

    /*
     * See if the target interpreter is local. If so, execute the command
     * directly without going through the X server. The only tricky thing is
     * passing the result from the target interpreter to the invoking
     * interpreter. Watch out: they could be the same!
     */

    for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
	    riPtr = riPtr->nextPtr) {
	if ((riPtr->dispPtr != dispPtr)
		|| (strcmp(riPtr->name, destName) != 0)) {
	    continue;
	}
	Tcl_Preserve((ClientData) riPtr);
	localInterp = riPtr->interp;
	Tcl_Preserve((ClientData) localInterp);
	if (firstArg == (argc-1)) {
	    result = Tcl_EvalEx(localInterp, argv[firstArg], -1, TCL_EVAL_GLOBAL);
	} else {
	    Tcl_DStringInit(&request);
	    Tcl_DStringAppend(&request, argv[firstArg], -1);
	    for (i = firstArg+1; i < argc; i++) {
		Tcl_DStringAppend(&request, " ", 1);
		Tcl_DStringAppend(&request, argv[i], -1);
	    }
	    result = Tcl_EvalEx(localInterp, Tcl_DStringValue(&request), -1, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(&request);
	}
	if (interp != localInterp) {
	    if (result == TCL_ERROR) {
		Tcl_Obj *errorObjPtr;
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148




















1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
		errorObjPtr = Tcl_GetVar2Ex(localInterp, "errorCode", NULL,
			TCL_GLOBAL_ONLY);
		Tcl_SetObjErrorCode(interp, errorObjPtr);
	    }
	    Tcl_SetObjResult(interp, Tcl_GetObjResult(localInterp));
	    Tcl_ResetResult(localInterp);
	}
	Tcl_Release(riPtr);
	Tcl_Release(localInterp);
	return result;
    }

    /*
     * Bind the interpreter name to a communication window.
     */

    regPtr = RegOpen(interp, winPtr->dispPtr, 0);
    commWindow = RegFindName(regPtr, destName);
    RegClose(regPtr);
    if (commWindow == None) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"no application named \"%s\"", destName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "APPLICATION", destName,
		NULL);
	return TCL_ERROR;
    }

    /*
     * Send the command to the target interpreter by appending it to the comm
     * window in the communication window.
     */

    localData.sendSerial++;
    Tcl_DStringInit(&request);
    Tcl_DStringAppend(&request, "\0c\0-n ", 6);
    Tcl_DStringAppend(&request, destName, -1);
    if (!async) {
	char buffer[TCL_INTEGER_SPACE * 2];

	sprintf(buffer, "%x %d",
		(unsigned) Tk_WindowId(dispPtr->commTkwin),
		localData.sendSerial);
	Tcl_DStringAppend(&request, "\0-r ", 4);
	Tcl_DStringAppend(&request, buffer, -1);
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
    for (i = firstArg+1; i < objc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
    }

    if (!async) {
	/*
	 * Register the fact that we're waiting for a command to complete
	 * (this is needed by SendEventProc and by AppendErrorProc to pass
	 * back the command's results). Set up a timeout handler so that
	 * we can check during long sends to make sure that the destination
	 * application is still alive.
	 *
	 * We prepare the pending struct here in order to catch potential
	 * early X errors from AppendPropCarefully() due to XSync().
	 */

	pending.serial = localData.sendSerial;
	pending.dispPtr = dispPtr;
	pending.target = destName;
	pending.commWindow = commWindow;
	pending.interp = interp;
	pending.result = NULL;
	pending.errorInfo = NULL;
	pending.errorCode = NULL;
	pending.gotResponse = 0;
	pending.nextPtr = tsdPtr->pendingCommands;
	tsdPtr->pendingCommands = &pending;
    }
    (void) AppendPropCarefully(dispPtr->display, commWindow,
	    dispPtr->commProperty, Tcl_DStringValue(&request),
	    Tcl_DStringLength(&request) + 1, (async ? NULL : &pending));
    Tcl_DStringFree(&request);
    if (async) {
	/*
	 * This is an asynchronous send: return immediately without waiting
	 * for a response.
	 */

	return TCL_OK;
    }





















    /*
     * Enter a loop processing X events until the result comes in or the
     * target is declared to be dead. While waiting for a result, look only at
     * send-related events so that the send is synchronous with respect to
     * other events in the application.
     */

    prevProc = Tk_RestrictEvents(SendRestrictProc, NULL, &prevArg);
    Tcl_GetTime(&timeout);
    timeout.sec += 2;
    while (!pending.gotResponse) {
	if (!TkUnixDoOneXEvent(&timeout)) {
	    /*
	     * An unusually long amount of time has elapsed during the
	     * processing of a sent command. Check to make sure that the
	     * target application still exists. If it does, reset the timeout.
	     */

	    if (!ValidateName(pending.dispPtr, pending.target,
		    pending.commWindow, 0)) {
		const char *msg;

		if (ValidateName(pending.dispPtr, pending.target,
			pending.commWindow, 1)) {
		    msg = "target application died or uses a Tk version before 4.0";
		} else {
		    msg = "target application died";
		}
		pending.code = TCL_ERROR;
		pending.result = (char *)ckalloc(strlen(msg) + 1);
		strcpy(pending.result, msg);
		pending.gotResponse = 1;
	    } else {
		Tcl_GetTime(&timeout);
		timeout.sec += 2;
	    }
	}
    }
    Tk_RestrictEvents(prevProc, prevArg, &prevArg);

    /*
     * Unregister the information about the pending command and return the
     * result.
     */

    if (tsdPtr->pendingCommands != &pending) {







|
|











<
|
<
<
















|





|
|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|












|








|








|







1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072


1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098

























1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
		errorObjPtr = Tcl_GetVar2Ex(localInterp, "errorCode", NULL,
			TCL_GLOBAL_ONLY);
		Tcl_SetObjErrorCode(interp, errorObjPtr);
	    }
	    Tcl_SetObjResult(interp, Tcl_GetObjResult(localInterp));
	    Tcl_ResetResult(localInterp);
	}
	Tcl_Release((ClientData) riPtr);
	Tcl_Release((ClientData) localInterp);
	return result;
    }

    /*
     * Bind the interpreter name to a communication window.
     */

    regPtr = RegOpen(interp, winPtr->dispPtr, 0);
    commWindow = RegFindName(regPtr, destName);
    RegClose(regPtr);
    if (commWindow == None) {

	Tcl_AppendResult(interp, "no application named \"",destName,"\"",NULL);


	return TCL_ERROR;
    }

    /*
     * Send the command to the target interpreter by appending it to the comm
     * window in the communication window.
     */

    localData.sendSerial++;
    Tcl_DStringInit(&request);
    Tcl_DStringAppend(&request, "\0c\0-n ", 6);
    Tcl_DStringAppend(&request, destName, -1);
    if (!async) {
	char buffer[TCL_INTEGER_SPACE * 2];

	sprintf(buffer, "%x %d",
		(unsigned int) Tk_WindowId(dispPtr->commTkwin),
		localData.sendSerial);
	Tcl_DStringAppend(&request, "\0-r ", 4);
	Tcl_DStringAppend(&request, buffer, -1);
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, argv[firstArg], -1);
    for (i = firstArg+1; i < argc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, argv[i], -1);

























    }
    (void) AppendPropCarefully(dispPtr->display, commWindow,
	    dispPtr->commProperty, Tcl_DStringValue(&request),
	    Tcl_DStringLength(&request) + 1, (async ? NULL : &pending));
    Tcl_DStringFree(&request);
    if (async) {
	/*
	 * This is an asynchronous send: return immediately without waiting
	 * for a response.
	 */

	return TCL_OK;
    }

    /*
     * Register the fact that we're waiting for a command to complete (this is
     * needed by SendEventProc and by AppendErrorProc to pass back the
     * command's results). Set up a timeout handler so that we can check
     * during long sends to make sure that the destination application is
     * still alive.
     */

    pending.serial = localData.sendSerial;
    pending.dispPtr = dispPtr;
    pending.target = destName;
    pending.commWindow = commWindow;
    pending.interp = interp;
    pending.result = NULL;
    pending.errorInfo = NULL;
    pending.errorCode = NULL;
    pending.gotResponse = 0;
    pending.nextPtr = tsdPtr->pendingCommands;
    tsdPtr->pendingCommands = &pending;

    /*
     * Enter a loop processing X events until the result comes in or the
     * target is declared to be dead. While waiting for a result, look only at
     * send-related events so that the send is synchronous with respect to
     * other events in the application.
     */

    prevRestrictProc = Tk_RestrictEvents(SendRestrictProc, NULL, &prevArg);
    Tcl_GetTime(&timeout);
    timeout.sec += 2;
    while (!pending.gotResponse) {
	if (!TkUnixDoOneXEvent(&timeout)) {
	    /*
	     * An unusually long amount of time has elapsed during the
	     * processing of a sent command. Check to make sure that the
	     * target application still exists. If it does, reset the timeout.
	     */

	    if (!ValidateName(pending.dispPtr, pending.target,
		    pending.commWindow, 0)) {
		char *msg;

		if (ValidateName(pending.dispPtr, pending.target,
			pending.commWindow, 1)) {
		    msg = "target application died or uses a Tk version before 4.0";
		} else {
		    msg = "target application died";
		}
		pending.code = TCL_ERROR;
		pending.result = (char *) ckalloc((unsigned) (strlen(msg) + 1));
		strcpy(pending.result, msg);
		pending.gotResponse = 1;
	    } else {
		Tcl_GetTime(&timeout);
		timeout.sec += 2;
	    }
	}
    }
    (void) Tk_RestrictEvents(prevRestrictProc, prevArg, &prevArg);

    /*
     * Unregister the information about the pending command and return the
     * result.
     */

    if (tsdPtr->pendingCommands != &pending) {
1204
1205
1206
1207
1208
1209
1210


1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
	 */

	Tcl_ResetResult(interp);
	Tcl_AddErrorInfo(interp, pending.errorInfo);
	ckfree(pending.errorInfo);
    }
    if (pending.errorCode != NULL) {


	Tcl_SetObjErrorCode(interp, Tcl_NewStringObj(pending.errorCode, -1));
	ckfree(pending.errorCode);
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(pending.result, -1));
    ckfree(pending.result);
    return pending.code;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetInterpNames --







>
>
|


<
|







1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1207
	 */

	Tcl_ResetResult(interp);
	Tcl_AddErrorInfo(interp, pending.errorInfo);
	ckfree(pending.errorInfo);
    }
    if (pending.errorCode != NULL) {
	Tcl_Obj *errorObjPtr = Tcl_NewStringObj(pending.errorCode, -1);

	Tcl_SetObjErrorCode(interp, errorObjPtr);
	ckfree(pending.errorCode);
    }

    Tcl_SetResult(interp, pending.result, TCL_DYNAMIC);
    return pending.code;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetInterpNames --
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    NameRegistry *regPtr;
    Tcl_Obj *resultObj = Tcl_NewObj();
    char *p;

    /*
     * Read the registry property, then scan through all of its entries.
     * Validate each entry to be sure that its application still exists.
     */

    regPtr = RegOpen(interp, winPtr->dispPtr, 1);
    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p, *entryName;
	Window commWindow;
	unsigned id;

	if (sscanf(p, "%x", (unsigned *) &id) != 1) {
	    commWindow = None;
	} else {
	    commWindow = id;
	}
	while ((*p != 0) && (!isspace(UCHAR(*p)))) {
	    p++;
	}
	if (*p != 0) {
	    p++;
	}
	entryName = p;
	while (*p != 0) {
	    p++;
	}
	p++;
	if (ValidateName(winPtr->dispPtr, entryName, commWindow, 1)) {
	    /*
	     * The application still exists; add its name to the result.
	     */

	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(entryName, -1));
	} else {
	    int count;

	    /*
	     * This name is bogus (perhaps the application died without
	     * cleaning up its entry in the registry?). Delete the name.
	     */







<











|

|




















|
<







1225
1226
1227
1228
1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    NameRegistry *regPtr;

    char *p;

    /*
     * Read the registry property, then scan through all of its entries.
     * Validate each entry to be sure that its application still exists.
     */

    regPtr = RegOpen(interp, winPtr->dispPtr, 1);
    for (p=regPtr->property ; p-regPtr->property<(int)regPtr->propLength ;) {
	char *entry = p, *entryName;
	Window commWindow;
	unsigned int id;

	if (sscanf(p, "%x",(unsigned int *) &id) != 1) {
	    commWindow = None;
	} else {
	    commWindow = id;
	}
	while ((*p != 0) && (!isspace(UCHAR(*p)))) {
	    p++;
	}
	if (*p != 0) {
	    p++;
	}
	entryName = p;
	while (*p != 0) {
	    p++;
	}
	p++;
	if (ValidateName(winPtr->dispPtr, entryName, commWindow, 1)) {
	    /*
	     * The application still exists; add its name to the result.
	     */

	    Tcl_AppendElement(interp, entryName);

	} else {
	    int count;

	    /*
	     * This name is bogus (perhaps the application died without
	     * cleaning up its entry in the registry?). Delete the name.
	     */
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
	    }
	    regPtr->propLength -= p - entry;
	    regPtr->modified = 1;
	    p = entry;
	}
    }
    RegClose(regPtr);
    Tcl_SetObjResult(interp, resultObj);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkSendCleanup --







<







1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
	    }
	    regPtr->propLength -= p - entry;
	    regPtr->modified = 1;
	    p = entry;
	}
    }
    RegClose(regPtr);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkSendCleanup --
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342

void
TkSendCleanup(
    TkDisplay *dispPtr)
{
    if (dispPtr->commTkwin != NULL) {
	Tk_DeleteEventHandler(dispPtr->commTkwin, PropertyChangeMask,
		SendEventProc, dispPtr);
	Tk_DestroyWindow(dispPtr->commTkwin);
	Tcl_Release(dispPtr->commTkwin);
	dispPtr->commTkwin = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *







|

|







1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

void
TkSendCleanup(
    TkDisplay *dispPtr)
{
    if (dispPtr->commTkwin != NULL) {
	Tk_DeleteEventHandler(dispPtr->commTkwin, PropertyChangeMask,
		SendEventProc, (ClientData) dispPtr);
	Tk_DestroyWindow(dispPtr->commTkwin);
	Tcl_Release((ClientData) dispPtr->commTkwin);
	dispPtr->commTkwin = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter to use for error reporting (no
				 * errors are ever returned, but the
				 * interpreter is needed anyway). */
    TkDisplay *dispPtr)		/* Display to initialize. */
{
    XSetWindowAttributes atts;

    /*
     * Create the window used for communication, and set up an event handler
     * for it.
     */

    dispPtr->commTkwin = (Tk_Window) TkAllocWindow(dispPtr,
    	DefaultScreen(dispPtr->display), NULL);
    Tcl_Preserve(dispPtr->commTkwin);
    ((TkWindow *) dispPtr->commTkwin)->flags |=
	    TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
    TkWmNewWindow((TkWindow *) dispPtr->commTkwin);
    atts.override_redirect = True;
    Tk_ChangeWindowAttributes(dispPtr->commTkwin,
	    CWOverrideRedirect, &atts);
    Tk_CreateEventHandler(dispPtr->commTkwin, PropertyChangeMask,
	    SendEventProc, dispPtr);
    Tk_MakeWindowExist(dispPtr->commTkwin);

    /*
     * Get atoms used as property names.
     */

    dispPtr->commProperty = Tk_InternAtom(dispPtr->commTkwin, "Comm");







|













|
|
<





|







1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting (no
				 * errors are ever returned, but the
				 * interpreter is needed anyway). */
    TkDisplay *dispPtr)		/* Display to initialize. */
{
    XSetWindowAttributes atts;

    /*
     * Create the window used for communication, and set up an event handler
     * for it.
     */

    dispPtr->commTkwin = (Tk_Window) TkAllocWindow(dispPtr,
    	DefaultScreen(dispPtr->display), NULL);
    Tcl_Preserve((ClientData) dispPtr->commTkwin);
    ((TkWindow *) dispPtr->commTkwin)->flags |=TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;

    TkWmNewWindow((TkWindow *) dispPtr->commTkwin);
    atts.override_redirect = True;
    Tk_ChangeWindowAttributes(dispPtr->commTkwin,
	    CWOverrideRedirect, &atts);
    Tk_CreateEventHandler(dispPtr->commTkwin, PropertyChangeMask,
	    SendEventProc, (ClientData) dispPtr);
    Tk_MakeWindowExist(dispPtr->commTkwin);

    /*
     * Get atoms used as property names.
     */

    dispPtr->commProperty = Tk_InternAtom(dispPtr->commTkwin, "Comm");
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
 */

static void
SendEventProc(
    ClientData clientData,	/* Display information. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    const char *p;
    int result, actualFormat;
    unsigned long numItems, bytesAfter;
    Atom actualType;
    Tcl_Interp *remoteInterp;	/* Interp in which to execute the command. */
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








|

|







1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
 */

static void
SendEventProc(
    ClientData clientData,	/* Display information. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkDisplay *dispPtr = (TkDisplay *) clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    register char *p;
    int result, actualFormat;
    unsigned long numItems, bytesAfter;
    Atom actualType;
    Tcl_Interp *remoteInterp;	/* Interp in which to execute the command. */
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
	if (*p == 0) {
	    p++;
	    continue;
	}

	if ((*p == 'c') && (p[1] == 0)) {
	    Window commWindow;
	    const char *interpName, *script, *serial;
	    char *end;
	    Tcl_DString reply;
	    RegisteredInterp *riPtr;

	    /*
	     *----------------------------------------------------------
	     * This is an incoming command from some other application.
	     * Iterate over all of its options. Stop when we reach the end of







|
<







1453
1454
1455
1456
1457
1458
1459
1460

1461
1462
1463
1464
1465
1466
1467
	if (*p == 0) {
	    p++;
	    continue;
	}

	if ((*p == 'c') && (p[1] == 0)) {
	    Window commWindow;
	    char *interpName, *script, *serial, *end;

	    Tcl_DString reply;
	    RegisteredInterp *riPtr;

	    /*
	     *----------------------------------------------------------
	     * This is an incoming command from some other application.
	     * Iterate over all of its options. Stop when we reach the end of
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
		    result = TCL_ERROR;
		    goto returnResult;
		}
		if (strcmp(riPtr->name, interpName) == 0) {
		    break;
		}
	    }
	    Tcl_Preserve(riPtr);

	    /*
	     * We must protect the interpreter because the script may enter
	     * another event loop, which might call Tcl_DeleteInterp.
	     */

	    remoteInterp = riPtr->interp;
	    Tcl_Preserve(remoteInterp);

	    result = Tcl_EvalEx(remoteInterp, script, -1, TCL_EVAL_GLOBAL);

	    /*
	     * The call to Tcl_Release may have released the interpreter which
	     * will cause the "send" command for that interpreter to be
	     * deleted. The command deletion callback will set the
	     * riPtr->interp field to NULL, hence the check below for NULL.
	     */

	    if (commWindow != None) {
		Tcl_DStringAppend(&reply, Tcl_GetString(Tcl_GetObjResult(remoteInterp)),
			-1);
		if (result == TCL_ERROR) {
		    const char *varValue;

		    varValue = Tcl_GetVar2(remoteInterp, "errorInfo",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-i ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		    varValue = Tcl_GetVar2(remoteInterp, "errorCode",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-e ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		}
	    }
	    Tcl_Release(remoteInterp);
	    Tcl_Release(riPtr);

	    /*
	     * Return the result to the sender if a commWindow was specified
	     * (if none was specified then this is an asynchronous call).
	     * Right now reply has everything but the completion code, but it
	     * needs the NULL to terminate the current option.
	     */







|







|











|


|















|
|







1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
		    result = TCL_ERROR;
		    goto returnResult;
		}
		if (strcmp(riPtr->name, interpName) == 0) {
		    break;
		}
	    }
	    Tcl_Preserve((ClientData) riPtr);

	    /*
	     * We must protect the interpreter because the script may enter
	     * another event loop, which might call Tcl_DeleteInterp.
	     */

	    remoteInterp = riPtr->interp;
	    Tcl_Preserve((ClientData) remoteInterp);

	    result = Tcl_EvalEx(remoteInterp, script, -1, TCL_EVAL_GLOBAL);

	    /*
	     * The call to Tcl_Release may have released the interpreter which
	     * will cause the "send" command for that interpreter to be
	     * deleted. The command deletion callback will set the
	     * riPtr->interp field to NULL, hence the check below for NULL.
	     */

	    if (commWindow != None) {
		Tcl_DStringAppend(&reply, Tcl_GetStringResult(remoteInterp),
			-1);
		if (result == TCL_ERROR) {
		    CONST char *varValue;

		    varValue = Tcl_GetVar2(remoteInterp, "errorInfo",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-i ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		    varValue = Tcl_GetVar2(remoteInterp, "errorCode",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-e ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		}
	    }
	    Tcl_Release((ClientData) remoteInterp);
	    Tcl_Release((ClientData) riPtr);

	    /*
	     * Return the result to the sender if a commWindow was specified
	     * (if none was specified then this is an asynchronous call).
	     * Right now reply has everything but the completion code, but it
	     * needs the NULL to terminate the current option.
	     */
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
			dispPtr->commProperty, Tcl_DStringValue(&reply),
			Tcl_DStringLength(&reply) + 1, NULL);
		XFlush(dispPtr->display);
		Tcl_DStringFree(&reply);
	    }
	} else if ((*p == 'r') && (p[1] == 0)) {
	    int serial, code, gotSerial;
	    const char *errorInfo, *errorCode, *resultString;
	    PendingCommand *pcPtr;

	    /*
	     *----------------------------------------------------------
	     * This is a reply to some command that we sent out. Iterate over
	     * all of its options. Stop when we reach the end of the property
	     * or something that doesn't look like an option.







|







1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
			dispPtr->commProperty, Tcl_DStringValue(&reply),
			Tcl_DStringLength(&reply) + 1, NULL);
		XFlush(dispPtr->display);
		Tcl_DStringFree(&reply);
	    }
	} else if ((*p == 'r') && (p[1] == 0)) {
	    int serial, code, gotSerial;
	    char *errorInfo, *errorCode, *resultString;
	    PendingCommand *pcPtr;

	    /*
	     *----------------------------------------------------------
	     * This is a reply to some command that we sent out. Iterate over
	     * all of its options. Stop when we reach the end of the property
	     * or something that doesn't look like an option.
1694
1695
1696
1697
1698
1699
1700
1701

1702
1703
1704
1705
1706

1707
1708
1709
1710

1711
1712
1713
1714
1715
1716
1717
	    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
		    pcPtr = pcPtr->nextPtr) {
		if ((serial != pcPtr->serial) || (pcPtr->result != NULL)) {
		    continue;
		}
		pcPtr->code = code;
		if (resultString != NULL) {
		    pcPtr->result = (char *)ckalloc(strlen(resultString) + 1);

		    strcpy(pcPtr->result, resultString);
		}
		if (code == TCL_ERROR) {
		    if (errorInfo != NULL) {
			pcPtr->errorInfo = (char *)ckalloc(strlen(errorInfo) + 1);

			strcpy(pcPtr->errorInfo, errorInfo);
		    }
		    if (errorCode != NULL) {
			pcPtr->errorCode = (char *)ckalloc(strlen(errorCode) + 1);

			strcpy(pcPtr->errorCode, errorCode);
		    }
		}
		pcPtr->gotResponse = 1;
		break;
	    }
	} else {







|
>




|
>



|
>







1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
	    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
		    pcPtr = pcPtr->nextPtr) {
		if ((serial != pcPtr->serial) || (pcPtr->result != NULL)) {
		    continue;
		}
		pcPtr->code = code;
		if (resultString != NULL) {
		    pcPtr->result = (char *) ckalloc((unsigned)
			    (strlen(resultString) + 1));
		    strcpy(pcPtr->result, resultString);
		}
		if (code == TCL_ERROR) {
		    if (errorInfo != NULL) {
			pcPtr->errorInfo = (char *) ckalloc((unsigned)
				(strlen(errorInfo) + 1));
			strcpy(pcPtr->errorInfo, errorInfo);
		    }
		    if (errorCode != NULL) {
			pcPtr->errorCode = (char *) ckalloc((unsigned)
				(strlen(errorCode) + 1));
			strcpy(pcPtr->errorCode, errorCode);
		    }
		}
		pcPtr->gotResponse = 1;
		break;
	    }
	} else {
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776

1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
    PendingCommand *pendingPtr)	/* Pending command to mark complete if an
				 * error occurs during the property op. NULL
				 * means just ignore the error. */
{
    Tk_ErrorHandler handler;

    handler = Tk_CreateErrorHandler(display, -1, -1, -1, AppendErrorProc,
	    pendingPtr);
    XChangeProperty(display, window, property, XA_STRING, 8,
	    PropModeAppend, (unsigned char *) value, length);
    Tk_DeleteErrorHandler(handler);
}

/*
 * The function below is invoked if an error occurs during the XChangeProperty
 * operation above.
 */


static int
AppendErrorProc(
    ClientData clientData,	/* Command to mark complete, or NULL. */
    TCL_UNUSED(XErrorEvent *))	/* Information about error. */
{
    PendingCommand *pendingPtr = (PendingCommand *)clientData;
    PendingCommand *pcPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (pendingPtr == NULL) {
	return 0;
    }

    /*
     * Make sure this command is still pending.
     */

    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
	    pcPtr = pcPtr->nextPtr) {
	if ((pcPtr == pendingPtr) && (pcPtr->result == NULL)) {
	    pcPtr->result = (char *)ckalloc(strlen(pcPtr->target) + 50);

	    sprintf(pcPtr->result, "no application named \"%s\"",
		    pcPtr->target);
	    pcPtr->code = TCL_ERROR;
	    pcPtr->gotResponse = 1;
	    break;
	}
    }







|










>



|

|
|














|
>







1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
    PendingCommand *pendingPtr)	/* Pending command to mark complete if an
				 * error occurs during the property op. NULL
				 * means just ignore the error. */
{
    Tk_ErrorHandler handler;

    handler = Tk_CreateErrorHandler(display, -1, -1, -1, AppendErrorProc,
	    (ClientData) pendingPtr);
    XChangeProperty(display, window, property, XA_STRING, 8,
	    PropModeAppend, (unsigned char *) value, length);
    Tk_DeleteErrorHandler(handler);
}

/*
 * The function below is invoked if an error occurs during the XChangeProperty
 * operation above.
 */

	/* ARGSUSED */
static int
AppendErrorProc(
    ClientData clientData,	/* Command to mark complete, or NULL. */
    XErrorEvent *errorPtr)	/* Information about error. */
{
    PendingCommand *pendingPtr = (PendingCommand *) clientData;
    register PendingCommand *pcPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (pendingPtr == NULL) {
	return 0;
    }

    /*
     * Make sure this command is still pending.
     */

    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
	    pcPtr = pcPtr->nextPtr) {
	if ((pcPtr == pendingPtr) && (pcPtr->result == NULL)) {
	    pcPtr->result = (char *) ckalloc((unsigned)
		    (strlen(pcPtr->target) + 50));
	    sprintf(pcPtr->result, "no application named \"%s\"",
		    pcPtr->target);
	    pcPtr->code = TCL_ERROR;
	    pcPtr->gotResponse = 1;
	    break;
	}
    }
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
 */

static void
DeleteProc(
    ClientData clientData)	/* Info about registration, passed as
				 * ClientData. */
{
    RegisteredInterp *riPtr = (RegisteredInterp *)clientData;
    RegisteredInterp *riPtr2;
    NameRegistry *regPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    regPtr = RegOpen(riPtr->interp, riPtr->dispPtr, 1);
    RegDeleteName(regPtr, riPtr->name);
    RegClose(regPtr);

    if (tsdPtr->interpListPtr == riPtr) {
	tsdPtr->interpListPtr = riPtr->nextPtr;
    } else {
	for (riPtr2 = tsdPtr->interpListPtr; riPtr2 != NULL;
		riPtr2 = riPtr2->nextPtr) {
	    if (riPtr2->nextPtr == riPtr) {
		riPtr2->nextPtr = riPtr->nextPtr;
		break;
	    }
	}
    }
    ckfree(riPtr->name);
    riPtr->interp = NULL;
    UpdateCommWindow(riPtr->dispPtr);
    Tcl_EventuallyFree(riPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * SendRestrictProc --
 *
 *	This function filters incoming events when a "send" command is
 *	outstanding. It defers all events except those containing send
 *	commands and results.
 *
 * Results:
 *	False is returned except for property-change events on a commWindow.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static Tk_RestrictAction
SendRestrictProc(
    TCL_UNUSED(void *),		/* Not used. */
    XEvent *eventPtr)		/* Event that just arrived. */
{
    TkDisplay *dispPtr;

    if (eventPtr->type != PropertyNotify) {
	return TK_DEFER_EVENT;
    }
    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;







|
|



















|


|




















>


|
|







1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
 */

static void
DeleteProc(
    ClientData clientData)	/* Info about registration, passed as
				 * ClientData. */
{
    RegisteredInterp *riPtr = (RegisteredInterp *) clientData;
    register RegisteredInterp *riPtr2;
    NameRegistry *regPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    regPtr = RegOpen(riPtr->interp, riPtr->dispPtr, 1);
    RegDeleteName(regPtr, riPtr->name);
    RegClose(regPtr);

    if (tsdPtr->interpListPtr == riPtr) {
	tsdPtr->interpListPtr = riPtr->nextPtr;
    } else {
	for (riPtr2 = tsdPtr->interpListPtr; riPtr2 != NULL;
		riPtr2 = riPtr2->nextPtr) {
	    if (riPtr2->nextPtr == riPtr) {
		riPtr2->nextPtr = riPtr->nextPtr;
		break;
	    }
	}
    }
    ckfree((char *) riPtr->name);
    riPtr->interp = NULL;
    UpdateCommWindow(riPtr->dispPtr);
    Tcl_EventuallyFree((ClientData) riPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
 * SendRestrictProc --
 *
 *	This function filters incoming events when a "send" command is
 *	outstanding. It defers all events except those containing send
 *	commands and results.
 *
 * Results:
 *	False is returned except for property-change events on a commWindow.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
static Tk_RestrictAction
SendRestrictProc(
    ClientData clientData,		/* Not used. */
    register XEvent *eventPtr)		/* Event that just arrived. */
{
    TkDisplay *dispPtr;

    if (eventPtr->type != PropertyNotify) {
	return TK_DEFER_EVENT;
    }
    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
1948
1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050


2051
2052





2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
 *
 * Side effects:
 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */


int
TkpTestsendCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    enum {
	TESTSEND_BOGUS, TESTSEND_PROP, TESTSEND_SERIAL
    };
    static const char *const testsendOptions[] = {
	"bogus",   "prop",   "serial",  NULL
    };
    TkWindow *winPtr = (TkWindow *)clientData;
    Tk_ErrorHandler handler;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == TESTSEND_BOGUS) {
        handler = Tk_CreateErrorHandler(winPtr->dispPtr->display, -1, -1, -1,
                NULL, NULL);
	XChangeProperty(winPtr->dispPtr->display,
		RootWindow(winPtr->dispPtr->display, 0),
		winPtr->dispPtr->registryProperty, XA_INTEGER, 32,
		PropModeReplace,
		(unsigned char *) "This is bogus information", 6);
        Tk_DeleteErrorHandler(handler);
    } else if (index == TESTSEND_PROP) {
	int result, actualFormat;
	unsigned long length, bytesAfter;
	Atom actualType, propName;
	char *property, **propertyPtr = &property, *p, *end;
	Window w;

	if ((objc != 4) && (objc != 5)) {
		Tcl_WrongNumArgs(interp, 1, objv,
			"prop window name ?value ?");
	    return TCL_ERROR;
	}
	if (strcmp(Tcl_GetString(objv[2]), "root") == 0) {
	    w = RootWindow(winPtr->dispPtr->display, 0);
	} else if (strcmp(Tcl_GetString(objv[2]), "comm") == 0) {
	    w = Tk_WindowId(winPtr->dispPtr->commTkwin);
	} else {
	    w = strtoul(Tcl_GetString(objv[2]), &end, 0);
	}
	propName = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
	if (objc == 4) {
	    property = NULL;
	    result = XGetWindowProperty(winPtr->dispPtr->display, w, propName,
		    0, 100000, False, XA_STRING, &actualType, &actualFormat,
		    &length, &bytesAfter, (unsigned char **) propertyPtr);
	    if ((result == Success) && (actualType != None)
		    && (actualFormat == 8) && (actualType == XA_STRING)) {
		for (p = property; (unsigned long)(p-property) < length; p++) {
		    if (*p == 0) {
			*p = '\n';
		    }
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(property, -1));
	    }
	    if (property != NULL) {
		XFree(property);
	    }
	} else if (Tcl_GetString(objv[4])[0] == 0) {
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);
	    XDeleteProperty(winPtr->dispPtr->display, w, propName);
            Tk_DeleteErrorHandler(handler);
	} else {
	    Tcl_DString tmp;

	    Tcl_DStringInit(&tmp);
	    for (p = Tcl_DStringAppend(&tmp, Tcl_GetString(objv[4]),
		    (int) strlen(Tcl_GetString(objv[4]))); *p != 0; p++) {
		if (*p == '\n') {
		    *p = 0;
		}
	    }
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);
	    XChangeProperty(winPtr->dispPtr->display, w, propName, XA_STRING,
		    8, PropModeReplace, (unsigned char*)Tcl_DStringValue(&tmp),
		    p-Tcl_DStringValue(&tmp));
            Tk_DeleteErrorHandler(handler);
	    Tcl_DStringFree(&tmp);
	}


    } else if (index == TESTSEND_SERIAL) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(localData.sendSerial+1));





    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>




|
|

<
<
<
<
<
<
|
<
<

|
|
|



|
<
<
<
<
<
<





<
|






|
|
|


|

|


|

|
|











|




|
<
<

<




|
|




|
<



<


>
>
|
|
>
>
>
>
>











1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948






1949


1950
1951
1952
1953
1954
1955
1956
1957






1958
1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000


2001

2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015

2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
 *
 * Side effects:
 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TkpTestsendCmd(
    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 ...?\"", 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, **propertyPtr = &property, *p, *end;
	Window w;

	if ((argc != 4) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
		    " prop window name ?value ?\"", 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 **) propertyPtr);
	    if ((result == Success) && (actualType != None)
		    && (actualFormat == 8) && (actualType == XA_STRING)) {
		for (p = property; (unsigned long)(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", localData.sendSerial+1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be bogus, prop, or serial", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixWm.c.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;	/* Interpreter in which to invoke command. */
    char command[TKFLEXARRAY];	/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
    (offsetof(ProtocolHandler, command) + 1 + cmdLength)

/*
 * Data for [wm attributes] command:
 */

typedef struct {
    double alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
    int topmost;		/* Flag: true=>stay-on-top */
    int zoomed;			/* Flag: true=>maximized */
    int fullscreen;		/* Flag: true=>fullscreen */
} WmAttributes;

typedef enum {
    WMATT_ALPHA, WMATT_TOPMOST, WMATT_ZOOMED, WMATT_FULLSCREEN,
    WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-topmost", "-zoomed", "-fullscreen",
    "-type", NULL
};

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.







|
|







|




<

|
|
|
|







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[4];		/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
    ((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))

/*
 * Data for [wm attributes] command:
 */

typedef struct {
    double 	alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
    int 	topmost;	/* Flag: true=>stay-on-top */
    int 	zoomed;		/* Flag: true=>maximized */
    int 	fullscreen;	/* Flag: true=>fullscreen */
} WmAttributes;

typedef enum {
    WMATT_ALPHA, WMATT_TOPMOST, WMATT_ZOOMED, WMATT_FULLSCREEN,
    WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *WmAttributeNames[] = {
    "-alpha", "-topmost", "-zoomed", "-fullscreen",
    "-type", NULL
};

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *containerPtr;	/* Container window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */
    int withdrawn;		/* Non-zero means window has been withdrawn. */








|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *masterPtr;	/* Master window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */
    int withdrawn;		/* Non-zero means window has been withdrawn. */

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
     */

    WmAttributes attributes;	/* Current state of [wm attributes] */
    WmAttributes reqState;	/* Requested state of [wm attributes] */
    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* number of transients on this window */
    int iconDataSize;		/* size of iconphoto image data */
    unsigned char *iconDataPtr;	/* iconphoto image data, if set */







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
     */

    WmAttributes attributes;	/* Current state of [wm attributes] */
    WmAttributes reqState;	/* Requested state of [wm attributes] */
    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    CONST char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* number of transients on this window */
    int iconDataSize;		/* size of iconphoto image data */
    unsigned char *iconDataPtr;	/* iconphoto image data, if set */
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the container.
 */

#define WM_NEVER_MAPPED			1
#define WM_UPDATE_PENDING		2
#define WM_NEGATIVE_X			4
#define WM_NEGATIVE_Y			8
#define WM_UPDATE_SIZE_HINTS		0x10
#define WM_SYNC_PENDING			0x20
#define WM_VROOT_OFFSET_STALE		0x40
#define WM_ABOUT_TO_MAP			0x100
#define WM_MOVE_PENDING			0x200
#define WM_COLORMAPS_EXPLICIT		0x400
#define WM_ADDED_TOPLEVEL_COLORMAP	0x800
#define WM_WIDTH_NOT_RESIZABLE		0x1000
#define WM_HEIGHT_NOT_RESIZABLE		0x2000
#define WM_WITHDRAWN			0x4000

/*
 * Wrapper for XGetWindowProperty and XChangeProperty to make them a *bit*
 * less verbose.
 */

#define GetWindowProperty(wrapperPtr, atom, length, type, typePtr, formatPtr, numItemsPtr, bytesAfterPtr, itemsPtr) \
    (XGetWindowProperty((wrapperPtr)->display, (wrapperPtr)->window,	\
	    (atom), 0, (long) (length), False, (type),			\
	    (typePtr), (formatPtr), (numItemsPtr), (bytesAfterPtr),	\
	    (unsigned char **) (itemsPtr)) == Success)
#define SetWindowProperty(wrapperPtr, atomName, type, width, data, length) \
    XChangeProperty((wrapperPtr)->display, (wrapperPtr)->window,	\
	    Tk_InternAtom((Tk_Window) wrapperPtr, (atomName)),		\
	    (type), (width), PropModeReplace, (unsigned char *) (data), \
	    (int) (length))

/*
 * This module keeps a list of all top-level windows, primarily to simplify
 * the job of Tk_CoordsToWindow. The list is called firstWmPtr and is stored
 * in the TkDisplay structure.
 */

/*
 * The following structures are the official type records for geometry
 * management of top-level and menubar windows.
 */

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		MenubarReqProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};
static const Tk_GeomMgr menubarMgrType = {
    "menubar",			/* name */
    MenubarReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};

/*
 * Structures of the following type are used for communication between
 * WaitForEvent, WaitRestrictProc, and WaitTimeoutProc.
 */








|

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
<


|
|
|


|
|
|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
















279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the master.
 */

#define WM_NEVER_MAPPED			1
#define WM_UPDATE_PENDING		2
#define WM_NEGATIVE_X			4
#define WM_NEGATIVE_Y			8
#define WM_UPDATE_SIZE_HINTS		0x10
#define WM_SYNC_PENDING			0x20
#define WM_VROOT_OFFSET_STALE		0x40
#define WM_ABOUT_TO_MAP			0x100
#define WM_MOVE_PENDING			0x200
#define WM_COLORMAPS_EXPLICIT		0x400
#define WM_ADDED_TOPLEVEL_COLORMAP	0x800
#define WM_WIDTH_NOT_RESIZABLE		0x1000
#define WM_HEIGHT_NOT_RESIZABLE		0x2000
#define WM_WITHDRAWN			0x4000

















/*
 * This module keeps a list of all top-level windows, primarily to simplify
 * the job of Tk_CoordsToWindow. The list is called firstWmPtr and is stored
 * in the TkDisplay structure.
 */

/*
 * The following structures are the official type records for geometry
 * management of top-level and menubar windows.
 */

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		MenubarReqProc(ClientData clientData, Tk_Window tkwin);


static const Tk_GeomMgr wmMgrType = {
    "wm",				/* name */
    TopLevelReqProc,			/* requestProc */
    NULL,				/* lostSlaveProc */
};
static const Tk_GeomMgr menubarMgrType = {
    "menubar",				/* name */
    MenubarReqProc,			/* requestProc */
    NULL,				/* lostSlaveProc */
};

/*
 * Structures of the following type are used for communication between
 * WaitForEvent, WaitRestrictProc, and WaitTimeoutProc.
 */

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
static void		ConfigureEvent(WmInfo *wmPtr,
			    XConfigureEvent *eventPtr);
static void		CreateWrapper(WmInfo *wmPtr);
static void		GetMaxSize(WmInfo *wmPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		MenubarDestroyProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ParseGeometry(Tcl_Interp *interp, const char *string,
			    TkWindow *winPtr);
static void		ReparentEvent(WmInfo *wmPtr, XReparentEvent *eventPtr);
static void		PropertyEvent(WmInfo *wmPtr, XPropertyEvent *eventPtr);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *reparentTable);
static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
static void		ConfigureEvent(WmInfo *wmPtr,
			    XConfigureEvent *eventPtr);
static void		CreateWrapper(WmInfo *wmPtr);
static void		GetMaxSize(WmInfo *wmPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		MenubarDestroyProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ParseGeometry(Tcl_Interp *interp, char *string,
			    TkWindow *winPtr);
static void		ReparentEvent(WmInfo *wmPtr, XReparentEvent *eventPtr);
static void		PropertyEvent(WmInfo *wmPtr, XPropertyEvent *eventPtr);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *reparentTable);
static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
static void 		CheckNetWmState(WmInfo *, Atom *atoms, int numAtoms);
static void 		UpdateNetWmState(WmInfo *);
static void		WaitForConfigureNotify(TkWindow *winPtr,
			    unsigned long serial);
static int		WaitForEvent(Display *display,
			    WmInfo *wmInfoPtr, int type, XEvent *eventPtr);
static void		WaitForMapNotify(TkWindow *winPtr, int mapped);
static Tk_RestrictProc WaitRestrictProc;
static void		WrapperEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WmWaitMapProc(ClientData clientData,
			    XEvent *eventPtr);

static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 *--------------------------------------------------------------
 *
 * TkWmCleanup --
 *







|
|

|

>


|


|


|
|
|
|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|
|
|
|


|


|


|


|


|


|


|


|


|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
static void 		CheckNetWmState(WmInfo *, Atom *atoms, int numAtoms);
static void 		UpdateNetWmState(WmInfo *);
static void		WaitForConfigureNotify(TkWindow *winPtr,
			    unsigned long serial);
static int		WaitForEvent(Display *display,
			    WmInfo *wmInfoPtr, int type, XEvent *eventPtr);
static void		WaitForMapNotify(TkWindow *winPtr, int mapped);
static Tk_RestrictAction
			WaitRestrictProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WrapperEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WmWaitMapProc(ClientData clientData, XEvent *eventPtr);
static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 *--------------------------------------------------------------
 *
 * TkWmCleanup --
 *
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	if (wmPtr->iconDataPtr != NULL) {
	    ckfree(wmPtr->iconDataPtr);
	}
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	if (wmPtr->menubar != NULL) {
	    Tk_DestroyWindow(wmPtr->menubar);
	}
	if (wmPtr->wrapperPtr != NULL) {
	    Tk_DestroyWindow((Tk_Window) wmPtr->wrapperPtr);
	}
	while (wmPtr->protPtr != NULL) {
	    ProtocolHandler *protPtr = wmPtr->protPtr;


	    wmPtr->protPtr = protPtr->nextPtr;
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	}
	if (wmPtr->cmdArgv != NULL) {
	    ckfree(wmPtr->cmdArgv);
	}
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	}
	ckfree(wmPtr);
    }
    if (dispPtr->iconDataPtr != NULL) {
	ckfree(dispPtr->iconDataPtr);
	dispPtr->iconDataPtr = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *







|











|

>

|


|


|

|


|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	if (wmPtr->iconDataPtr != NULL) {
	    ckfree((char *) wmPtr->iconDataPtr);
	}
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	if (wmPtr->menubar != NULL) {
	    Tk_DestroyWindow(wmPtr->menubar);
	}
	if (wmPtr->wrapperPtr != NULL) {
	    Tk_DestroyWindow((Tk_Window) wmPtr->wrapperPtr);
	}
	while (wmPtr->protPtr != NULL) {
	    ProtocolHandler *protPtr;

	    protPtr = wmPtr->protPtr;
	    wmPtr->protPtr = protPtr->nextPtr;
	    Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
	}
	if (wmPtr->cmdArgv != NULL) {
	    ckfree((char *) wmPtr->cmdArgv);
	}
	if (wmPtr->clientMachine != NULL) {
	    ckfree((char *) wmPtr->clientMachine);
	}
	ckfree((char *) wmPtr);
    }
    if (dispPtr->iconDataPtr != NULL) {
	ckfree((char *) dispPtr->iconDataPtr);
	dispPtr->iconDataPtr = NULL;
    }
}

/*
 *--------------------------------------------------------------
 *
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
 *--------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    WmInfo *wmPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;

    wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));
    memset(wmPtr, 0, sizeof(WmInfo));
    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->containerPtr = NULL;
    wmPtr->numTransients = 0;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
    wmPtr->hints.icon_mask = None;
    wmPtr->hints.window_group = None;

    /*
     * Initialize attributes.
     */

    wmPtr->attributes.alpha = 1.0;
    wmPtr->attributes.topmost = 0;
    wmPtr->attributes.zoomed = 0;
    wmPtr->attributes.fullscreen = 0;
    wmPtr->reqState = wmPtr->attributes;

    /*







|


|



|













<







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
 *--------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    register WmInfo *wmPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;

    wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));
    memset(wmPtr, 0, sizeof(WmInfo));
    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->masterPtr = NULL;
    wmPtr->numTransients = 0;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
    wmPtr->hints.icon_mask = None;
    wmPtr->hints.window_group = None;

    /*
     * Initialize attributes.
     */

    wmPtr->attributes.alpha = 1.0;
    wmPtr->attributes.topmost = 0;
    wmPtr->attributes.zoomed = 0;
    wmPtr->attributes.fullscreen = 0;
    wmPtr->reqState = wmPtr->attributes;

    /*
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
    UpdateVRootGeometry(wmPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmMapWindow --
 *







|







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    UpdateVRootGeometry(wmPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
 */

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    XTextProperty textProp;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	Tcl_DString ds;

	wmPtr->flags &= ~WM_NEVER_MAPPED;








|







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
 */

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    XTextProperty textProp;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	Tcl_DString ds;

	wmPtr->flags &= ~WM_NEVER_MAPPED;

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729

730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
	 * Store all the window-manager-related information for the window.
	 */

	TkWmSetClass(winPtr);
	UpdateTitle(winPtr);
	UpdatePhotoIcon(winPtr);

	if (wmPtr->containerPtr != NULL) {
	    /*
	     * Don't map a transient if the container is not mapped.
	     */

	    if (!Tk_IsMapped(wmPtr->containerPtr)) {
		wmPtr->withdrawn = 1;
		wmPtr->hints.initial_state = WithdrawnState;
	    }

	    /*
	     * Make sure that we actually set the transient-for property, even
	     * if we are withdrawn. [Bug 1163496]
	     */

	    XSetTransientForHint(winPtr->display, wmPtr->wrapperPtr->window,
		    wmPtr->containerPtr->wmInfoPtr->wrapperPtr->window);
	}

	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	UpdateHints(winPtr);
	UpdateWmProtocols(wmPtr);
	if (wmPtr->cmdArgv != NULL) {
	    UpdateCommand(winPtr);
	}
	if (wmPtr->clientMachine != NULL) {
	    Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	    if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		    &textProp) != 0) {
		unsigned long pid = (unsigned long) getpid();


		XSetWMClientMachine(winPtr->display,
			wmPtr->wrapperPtr->window, &textProp);
		XFree((char *) textProp.value);

		/*
		 * Inform the server (and more particularly any session
		 * manager) what our process ID is. We only do this when the
		 * CLIENT_MACHINE property is set since the spec for
		 * _NET_WM_PID requires that to be set too.
		 */

		SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_PID",

			XA_CARDINAL, 32, &pid, 1);

	    }
	    Tcl_DStringFree(&ds);
	}
    }
    if (wmPtr->hints.initial_state == WithdrawnState) {
	return;
    }
    if (wmPtr->iconFor != NULL) {
	/*
	 * This window is an icon for somebody else. Make sure that the
	 * geometry is up-to-date, then return without mapping the window.
	 */

	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
	}
	UpdateGeometryInfo(winPtr);
	return;
    }
    wmPtr->flags |= WM_ABOUT_TO_MAP;
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    UpdateGeometryInfo(winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Update _NET_WM_STATE hints:
     */
    UpdateNetWmState(wmPtr);








|

|


|










|













>

|
|









|
>
|
>














|

|




|

|







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
	 * Store all the window-manager-related information for the window.
	 */

	TkWmSetClass(winPtr);
	UpdateTitle(winPtr);
	UpdatePhotoIcon(winPtr);

	if (wmPtr->masterPtr != NULL) {
	    /*
	     * Don't map a transient if the master is not mapped.
	     */

	    if (!Tk_IsMapped(wmPtr->masterPtr)) {
		wmPtr->withdrawn = 1;
		wmPtr->hints.initial_state = WithdrawnState;
	    }

	    /*
	     * Make sure that we actually set the transient-for property, even
	     * if we are withdrawn. [Bug 1163496]
	     */

	    XSetTransientForHint(winPtr->display, wmPtr->wrapperPtr->window,
		    wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
	}

	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	UpdateHints(winPtr);
	UpdateWmProtocols(wmPtr);
	if (wmPtr->cmdArgv != NULL) {
	    UpdateCommand(winPtr);
	}
	if (wmPtr->clientMachine != NULL) {
	    Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	    if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		    &textProp) != 0) {
		unsigned long pid = (unsigned long) getpid();
		Atom atom;

		XSetWMClientMachine(winPtr->display, wmPtr->wrapperPtr->window,
			&textProp);
		XFree((char *) textProp.value);

		/*
		 * Inform the server (and more particularly any session
		 * manager) what our process ID is. We only do this when the
		 * CLIENT_MACHINE property is set since the spec for
		 * _NET_WM_PID requires that to be set too.
		 */

		atom = Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_PID");
		XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
			atom, XA_CARDINAL, 32, PropModeReplace,
			(unsigned char *) &pid, 1);
	    }
	    Tcl_DStringFree(&ds);
	}
    }
    if (wmPtr->hints.initial_state == WithdrawnState) {
	return;
    }
    if (wmPtr->iconFor != NULL) {
	/*
	 * This window is an icon for somebody else. Make sure that the
	 * geometry is up-to-date, then return without mapping the window.
	 */

	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
	}
	UpdateGeometryInfo((ClientData) winPtr);
	return;
    }
    wmPtr->flags |= WM_ABOUT_TO_MAP;
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
    }
    UpdateGeometryInfo((ClientData) winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Update _NET_WM_STATE hints:
     */
    UpdateNetWmState(wmPtr);

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
 *--------------------------------------------------------------
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    WmInfo *wmPtr2;

    if (wmPtr == NULL) {
	return;
    }
    if ((WmInfo *) winPtr->dispPtr->firstWmPtr == wmPtr) {
	winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr;
    } else {
	WmInfo *prevPtr;

	for (prevPtr = (WmInfo *) winPtr->dispPtr->firstWmPtr; ;
		prevPtr = prevPtr->nextPtr) {
	    /* ASSERT: prevPtr != NULL [Bug 1789819] */
	    if (prevPtr->nextPtr == wmPtr) {
		prevPtr->nextPtr = wmPtr->nextPtr;
		break;
	    }
	}
    }
    if (wmPtr->title != NULL) {
	ckfree(wmPtr->title);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    if (wmPtr->iconDataPtr != NULL) {
	ckfree(wmPtr->iconDataPtr);
    }
    if (wmPtr->hints.flags & IconPixmapHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }







|








|

















|







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
 *--------------------------------------------------------------
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    WmInfo *wmPtr2;

    if (wmPtr == NULL) {
	return;
    }
    if ((WmInfo *) winPtr->dispPtr->firstWmPtr == wmPtr) {
	winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr;
    } else {
	register WmInfo *prevPtr;

	for (prevPtr = (WmInfo *) winPtr->dispPtr->firstWmPtr; ;
		prevPtr = prevPtr->nextPtr) {
	    /* ASSERT: prevPtr != NULL [Bug 1789819] */
	    if (prevPtr->nextPtr == wmPtr) {
		prevPtr->nextPtr = wmPtr->nextPtr;
		break;
	    }
	}
    }
    if (wmPtr->title != NULL) {
	ckfree(wmPtr->title);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    if (wmPtr->iconDataPtr != NULL) {
	ckfree((char *) wmPtr->iconDataPtr);
    }
    if (wmPtr->hints.flags & IconPixmapHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }
889
890
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

	XUnmapWindow(winPtr->display, winPtr->window);
	XReparentWindow(winPtr->display, winPtr->window,
		XRootWindow(winPtr->display, winPtr->screenNum), 0, 0);
	Tk_DestroyWindow((Tk_Window) wmPtr->wrapperPtr);
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr = wmPtr->protPtr;


	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree(wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }

    /*
     * Reset all transient windows whose container is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	    wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->containerPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->containerPtr,
		    StructureNotifyMask, WmWaitMapProc, wmPtr2->winPtr);

	    wmPtr2->containerPtr = NULL;
	    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr2->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_TRANSIENT_FOR"));

		/*
		 * FIXME: Need a call like Win32's UpdateWrapper() so we can
		 * recreate the wrapper and get rid of the transient window
		 * decorations.
		 */
	    }
	}
    }
    /* ASSERT: numTransients == 0 [Bug 1789819] */

    if (wmPtr->containerPtr != NULL) {
	wmPtr2 = wmPtr->containerPtr->wmInfoPtr;

	/*
	 * If we had a container, tell them that we aren't tied to them anymore
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
		StructureNotifyMask, WmWaitMapProc, winPtr);
	wmPtr->containerPtr = NULL;
    }
    ckfree(wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * TkWmSetClass --







|

>

|


|


|


|



|




|

|
|
>
|














|
|


|





|
|
|

|







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

	XUnmapWindow(winPtr->display, winPtr->window);
	XReparentWindow(winPtr->display, winPtr->window,
		XRootWindow(winPtr->display, winPtr->screenNum), 0, 0);
	Tk_DestroyWindow((Tk_Window) wmPtr->wrapperPtr);
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr;

	protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
    }

    /*
     * Reset all transient windows whose master is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	    wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->masterPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
		    StructureNotifyMask,
		    WmWaitMapProc, (ClientData) wmPtr2->winPtr);
	    wmPtr2->masterPtr = NULL;
	    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr2->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_TRANSIENT_FOR"));

		/*
		 * FIXME: Need a call like Win32's UpdateWrapper() so we can
		 * recreate the wrapper and get rid of the transient window
		 * decorations.
		 */
	    }
	}
    }
    /* ASSERT: numTransients == 0 [Bug 1789819] */

    if (wmPtr->masterPtr != NULL) {
	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;

	/*
	 * If we had a master, tell them that we aren't tied to them anymore
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
		StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr);
	wmPtr->masterPtr = NULL;
    }
    ckfree((char *) wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * TkWmSetClass --
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035

1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
{
    if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    if (winPtr->classUid != NULL) {
	XClassHint *classPtr;
	Tcl_DString name, ds;

	Tcl_UtfToExternalDString(NULL, winPtr->nameUid, -1, &name);
	Tcl_UtfToExternalDString(NULL, winPtr->classUid, -1, &ds);
	classPtr = XAllocClassHint();
	classPtr->res_name = Tcl_DStringValue(&name);
	classPtr->res_class = Tcl_DStringValue(&ds);
	XSetClassHint(winPtr->display, winPtr->wmInfoPtr->wrapperPtr->window,
		classPtr);
	XFree((char *) classPtr);
	Tcl_DStringFree(&name);
	Tcl_DStringFree(&ds);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	This function is invoked to process the "wm" Tcl command.
 *
 *----------------------------------------------------------------------
 */


int
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 = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname", "iconphoto",
	"iconposition", "iconwindow", "manage", "maxsize",
	"minsize", "overrideredirect", "positionfrom",
	"protocol", "resizable", "sizefrom", "stackorder",

	"state", "title", "transient", "withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
	WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPHOTO,
	WMOPT_ICONPOSITION, WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE,
	WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, WMOPT_POSITIONFROM,
	WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, WMOPT_STACKORDER,
	WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, WMOPT_WITHDRAW };

    int index;

    const char *argv1;
    TkWindow *winPtr;
    Tk_Window targetWin;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetString(objv[1]);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", objv[1]->length) == 0)
	    && (objv[1]->length >= 3)) {
	int wmTracing;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (dispPtr->flags & TK_DISPLAY_WM_TRACING) != 0));

	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (wmTracing) {
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &targetWin) != TCL_OK) {
	return TCL_ERROR;
    }
    winPtr = (TkWindow *) targetWin;
    if (!Tk_IsTopLevel(winPtr) &&
	    (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:







|


|


|




|













>





|

|
|

|
|
|
|
|
|
>
|


|
|
<
|
|
|
|
|
>

>
|










|
|
|

<





|
|
>













|
|













|
|
<
<







964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


1080
1081
1082
1083
1084
1085
1086
{
    if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    if (winPtr->classUid != NULL) {
	XClassHint *classPtr;
	Tcl_DString name, class;

	Tcl_UtfToExternalDString(NULL, winPtr->nameUid, -1, &name);
	Tcl_UtfToExternalDString(NULL, winPtr->classUid, -1, &class);
	classPtr = XAllocClassHint();
	classPtr->res_name = Tcl_DStringValue(&name);
	classPtr->res_class = Tcl_DStringValue(&class);
	XSetClassHint(winPtr->display, winPtr->wmInfoPtr->wrapperPtr->window,
		classPtr);
	XFree((char *) classPtr);
	Tcl_DStringFree(&name);
	Tcl_DStringFree(&class);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	This function is invoked to process the "wm" Tcl command.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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 = (Tk_Window) clientData;
    static CONST char *optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,

	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW };
    int index;
    int length;
    char *argv1;
    TkWindow *winPtr;
    Tk_Window targetWin;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", (size_t) length) == 0)
	    && (length >= 3)) {
	int wmTracing;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetResult(interp,
		    ((dispPtr->flags & TK_DISPLAY_WM_TRACING) ? "on" : "off"),
		    TCL_STATIC);
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (wmTracing) {
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &targetWin) != TCL_OK) {
	return TCL_ERROR;
    }
    winPtr = (TkWindow *) targetWin;
    if (!Tk_IsTopLevel(winPtr) &&
	    (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", NULL);


	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewWideIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewWideIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);

	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;







|



|

|









|

|
|
<
|
|














<
|
<
>







1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208

1209

1210
1211
1212
1213
1214
1215
1216
1217
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
		    wmPtr->minAspect.y, wmPtr->maxAspect.x,

		    wmPtr->maxAspect.y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {

	    Tcl_SetResult(interp, "aspect number can't be <= 0",

		    TCL_STATIC);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

1282
1283

1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
WmSetAttribute(
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter */
    WmAttribute attribute,	/* Code of attribute to set */
    Tcl_Obj *value)		/* New value */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA: {
	unsigned long opacity;	/* 0=transparent, 0xFFFFFFFF=opaque */

	if (TCL_OK != Tcl_GetDoubleFromObj(interp, value,
		&wmPtr->reqState.alpha)) {
	    return TCL_ERROR;
	}
	if (wmPtr->reqState.alpha < 0.0) {
	    wmPtr->reqState.alpha = 0.0;
	}
	if (wmPtr->reqState.alpha > 1.0) {
	    wmPtr->reqState.alpha = 1.0;
	}

	if (!wmPtr->wrapperPtr) {
	    break;
	}

	opacity = 0xFFFFFFFFul * wmPtr->reqState.alpha;

	SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_WINDOW_OPACITY",
		XA_CARDINAL, 32, &opacity, 1L);

	wmPtr->attributes.alpha = wmPtr->reqState.alpha;

	break;
    }
    case WMATT_TOPMOST:
	if (Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.topmost) != TCL_OK) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_ABOVE", wmPtr->reqState.topmost);

	break;
    case WMATT_TYPE:
	if (TCL_OK != SetNetWmType(winPtr, value))
	    return TCL_ERROR;
	break;
    case WMATT_ZOOMED:
	if (Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.zoomed) != TCL_OK) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_MAXIMIZED_VERT",
		wmPtr->reqState.zoomed);
	SetNetWmState(winPtr, "_NET_WM_STATE_MAXIMIZED_HORZ",
		wmPtr->reqState.zoomed);
	break;
    case WMATT_FULLSCREEN:
	if (Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.fullscreen) != TCL_OK) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_FULLSCREEN",
		wmPtr->reqState.fullscreen);
	break;
    case _WMATT_LAST_ATTRIBUTE:
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







<




















>
|
|
>





|
|


|
>






|
|








|
|





|







1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
WmSetAttribute(
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter */
    WmAttribute attribute,	/* Code of attribute to set */
    Tcl_Obj *value)		/* New value */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA: {
	unsigned long opacity;	/* 0=transparent, 0xFFFFFFFF=opaque */

	if (TCL_OK != Tcl_GetDoubleFromObj(interp, value,
		&wmPtr->reqState.alpha)) {
	    return TCL_ERROR;
	}
	if (wmPtr->reqState.alpha < 0.0) {
	    wmPtr->reqState.alpha = 0.0;
	}
	if (wmPtr->reqState.alpha > 1.0) {
	    wmPtr->reqState.alpha = 1.0;
	}

	if (!wmPtr->wrapperPtr) {
	    break;
	}

	opacity = 0xFFFFFFFFul * wmPtr->reqState.alpha;
	XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
		Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_WINDOW_OPACITY"),
		XA_CARDINAL, 32, PropModeReplace,
		(unsigned char *)&opacity, 1L);
	wmPtr->attributes.alpha = wmPtr->reqState.alpha;

	break;
    }
    case WMATT_TOPMOST:
	if (TCL_OK != Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.topmost)) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_ABOVE",
		wmPtr->reqState.topmost);
	break;
    case WMATT_TYPE:
	if (TCL_OK != SetNetWmType(winPtr, value))
	    return TCL_ERROR;
	break;
    case WMATT_ZOOMED:
	if (TCL_OK != Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.zoomed)) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_MAXIMIZED_VERT",
		wmPtr->reqState.zoomed);
	SetNetWmState(winPtr, "_NET_WM_STATE_MAXIMIZED_HORZ",
		wmPtr->reqState.zoomed);
	break;
    case WMATT_FULLSCREEN:
	if (TCL_OK != Tcl_GetBooleanFromObj(interp, value,
		&wmPtr->reqState.fullscreen)) {
	    return TCL_ERROR;
	}
	SetNetWmState(winPtr, "_NET_WM_STATE_FULLSCREEN",
		wmPtr->reqState.fullscreen);
	break;
    case _WMATT_LAST_ATTRIBUTE:	/* NOTREACHED */
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	return Tcl_NewDoubleObj(wmPtr->attributes.alpha);
    case WMATT_TOPMOST:
	return Tcl_NewWideIntObj(wmPtr->attributes.topmost != 0);
    case WMATT_ZOOMED:
	return Tcl_NewWideIntObj(wmPtr->attributes.zoomed != 0);
    case WMATT_FULLSCREEN:
	return Tcl_NewWideIntObj(wmPtr->attributes.fullscreen != 0);
    case WMATT_TYPE:
	return GetNetWmType(winPtr);
    case _WMATT_LAST_ATTRIBUTE:
	break;
    }

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * WmAttributesCmd --







|

|

|


|


>







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	return Tcl_NewDoubleObj(wmPtr->attributes.alpha);
    case WMATT_TOPMOST:
	return Tcl_NewBooleanObj(wmPtr->attributes.topmost);
    case WMATT_ZOOMED:
	return Tcl_NewBooleanObj(wmPtr->attributes.zoomed);
    case WMATT_FULLSCREEN:
	return Tcl_NewBooleanObj(wmPtr->attributes.fullscreen);
    case WMATT_TYPE:
	return GetNetWmType(winPtr);
    case _WMATT_LAST_ATTRIBUTE:	/*NOTREACHED*/
	break;
    }
    /*NOTREACHED*/
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * WmAttributesCmd --
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
 * See also: TIP#231, EWMH.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(interp, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(interp, result,
		    WmGetAttribute(winPtr, (WmAttribute)attribute));
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, (WmAttribute)attribute));
	return TCL_OK;
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr,interp,(WmAttribute)attribute,objv[i+1]) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	return TCL_OK;
    }

    Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");







|



|










|




|
|


|





|
|


|







1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
 * See also: TIP#231, EWMH.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    int attribute = 0;

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(interp, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(interp, result,
		    WmGetAttribute(winPtr, attribute));
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames,
		    "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, attribute));
	return TCL_OK;
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames,
		    "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr,interp,attribute,objv[i+1]) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	return TCL_OK;
    }

    Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,
				"WM_CLIENT_MACHINE"));
	    }
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)ckalloc(objv[3]->length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;
	Tcl_DString ds;

	Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,







|



|

|
|
>







<
|



|


|










|

|







1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {

	    Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree((char *) wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,
				"WM_CLIENT_MACHINE"));
	    }
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    wmPtr->clientMachine = ckalloc((unsigned) length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;
	Tcl_DString ds;

	Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
1501
1502
1503
1504
1505
1506
1507

1508

1509
1510
1511
1512
1513
1514
1515
1516
	    /*
	     * Inform the server (and more particularly any session manager)
	     * what our process ID is. We only do this when the CLIENT_MACHINE
	     * property is set since the spec for _NET_WM_PID requires that to
	     * be set too.
	     */


	    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_PID", XA_CARDINAL,

		    32, &pid, 1);
	}
	Tcl_DStringFree(&ds);
    }
    return TCL_OK;
}

/*







>
|
>
|







1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
	    /*
	     * Inform the server (and more particularly any session manager)
	     * what our process ID is. We only do this when the CLIENT_MACHINE
	     * property is set since the spec for _NET_WM_PID requires that to
	     * be set too.
	     */

	    XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
		    Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_PID"),
		    XA_CARDINAL,32, PropModeReplace, (unsigned char *) &pid,
		    1);
	}
	Tcl_DStringFree(&ds);
    }
    return TCL_OK;
}

/*
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583

1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window *cmapList;
    TkWindow *winPtr2;
    int count, i, windowObjc, gotToplevel;
    Tcl_Obj **windowObjv, *resultObj;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    Tk_MakeWindowExist((Tk_Window) winPtr);
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    if (objc == 3) {
	if (XGetWMColormapWindows(winPtr->display,
		wmPtr->wrapperPtr->window, &cmapList, &count) == 0) {
	    return TCL_OK;
	}
	resultObj = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    if ((i == (count-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    winPtr2 = (TkWindow *)
		   Tk_IdToWindow(winPtr->display, cmapList[i]);
	    if (winPtr2 == NULL) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_ObjPrintf("0x%lx", cmapList[i]));

	    } else {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(winPtr2->pathName, -1));
	    }
	}
	XFree((char *) cmapList);
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    cmapList = (Window *)ckalloc((windowObjc+1) * sizeof(Window));
    gotToplevel = 0;
    for (i = 0; i < windowObjc; i++) {
	Tk_Window mapWin;

	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		&mapWin) != TCL_OK) {
	    ckfree(cmapList);
	    return TCL_ERROR;
	}
	winPtr2 = (TkWindow *) mapWin;
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {







|

|



|
>














<





|
|

<
|
>

<
|



<






>
|






|







1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552

1553
1554
1555
1556
1557
1558
1559
1560

1561
1562
1563

1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window *cmapList;
    TkWindow *winPtr2;
    int count, i, windowObjc, gotToplevel;
    Tcl_Obj **windowObjv;
    char buffer[20];

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    Tk_MakeWindowExist((Tk_Window) winPtr);
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    if (objc == 3) {
	if (XGetWMColormapWindows(winPtr->display,
		wmPtr->wrapperPtr->window, &cmapList, &count) == 0) {
	    return TCL_OK;
	}

	for (i = 0; i < count; i++) {
	    if ((i == (count-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    winPtr2 = (TkWindow *) Tk_IdToWindow(winPtr->display,
		    cmapList[i]);
	    if (winPtr2 == NULL) {

		sprintf(buffer, "0x%lx", cmapList[i]);
		Tcl_AppendElement(interp, buffer);
	    } else {

		Tcl_AppendElement(interp, winPtr2->pathName);
	    }
	}
	XFree((char *) cmapList);

	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (Window *) ckalloc((unsigned)
	    (windowObjc+1) * sizeof(Window));
    gotToplevel = 0;
    for (i = 0; i < windowObjc; i++) {
	Tk_Window mapWin;

	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		&mapWin) != TCL_OK) {
	    ckfree((char *) cmapList);
	    return TCL_ERROR;
	}
	winPtr2 = (TkWindow *) mapWin;
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    XSetWMColormapWindows(winPtr->display, wmPtr->wrapperPtr->window,
	    cmapList, windowObjc);
    ckfree(cmapList);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmCommandCmd --







|







1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    XSetWMColormapWindows(winPtr->display, wmPtr->wrapperPtr->window,
	    cmapList, windowObjc);
    ckfree((char *) cmapList);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmCommandCmd --
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int cmdArgc;
    const char **cmdArgv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {

	    char *arg = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, -1));
	    ckfree(arg);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree(wmPtr->cmdArgv);
	    wmPtr->cmdArgv = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
	    }
	}
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree(wmPtr->cmdArgv);
    }
    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = cmdArgv;
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	UpdateCommand(winPtr);
    }
    return TCL_OK;







|



|

|
|

|







>
|
|
<
<






|












|







1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646


1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int cmdArgc;
    CONST char **cmdArgv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    Tcl_SetResult(interp,
		    Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
		    TCL_DYNAMIC);


	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree((char *) wmPtr->cmdArgv);
	    wmPtr->cmdArgv = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
	    }
	}
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = cmdArgv;
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	UpdateCommand(winPtr);
    }
    return TCL_OK;
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }
    wmPtr->flags &= ~WM_WITHDRAWN;
    TkpWmSetState(winPtr, NormalState);
    return TCL_OK;
}








|



|

|






<
|
|
<



|
|
<
<







1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707

1708
1709

1710
1711
1712
1713
1714


1715
1716
1717
1718
1719
1720
1721
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		": it is an embedded window", NULL);


	return TCL_ERROR;
    }
    wmPtr->flags &= ~WM_WITHDRAWN;
    TkpWmSetState(winPtr, NormalState);
    return TCL_OK;
}

1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));

	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmForgetCmd --
 *
 *	This procedure is invoked to process the "wm forget" 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
WmForgetCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);
	TkWmDeadWindow(winPtr);
	winPtr->flags &=
		~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	RemapWindows(winPtr, winPtr->parentPtr);

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	/*
	 * Flags (above) must be cleared before calling TkMapTopFrame (below).
	 */

	TkMapTopFrame(frameWin);
    } else {
	/*
	 * Already not managed by wm - ignore it.
	 */
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|



|

|
|










<
|
>



|
|
















|
|











|
|
|
|
|
|

|





<
|

<
<
<
<
<
<
<
|
<
|


<
|
<







1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758

1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809







1810

1811
1812
1813

1814

1815
1816
1817
1818
1819
1820
1821
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {

	Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		TCL_STATIC);
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmForgetCmd --
 *
 *	This procedure is invoked to process the "wm forget" 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
WmForgetCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel or Frame to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Tk_Window frameWin = (Tk_Window) winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);
	TkWmDeadWindow(winPtr);

	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	RemapWindows(winPtr, winPtr->parentPtr);







	/* flags (above) must be cleared before calling */

	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {

	/* Already not managed by wm - ignore it */

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|



|

|











|
|







1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%x", (unsigned int) window);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920


1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936
1937
1938
1939
1940
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }
    if (objc == 3) {


	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
	ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d",
		width, height, xSign, wmPtr->x, ySign, wmPtr->y));

	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);







|



|

|


|






>
>











|
|
>







1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[16 + TCL_INTEGER_SPACE * 4];

	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
	ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
		ySign, wmPtr->y);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewWideIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewWideIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewWideIntObj(wmPtr->heightInc);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.







|



|

|









|

|
|
<
|
|







1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970
1971
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
		    wmPtr->reqGridHeight, wmPtr->widthInc,

		    wmPtr->heightInc);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) !=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);







<
|
<



<
|
<



<
|
<



<
|
<







1984
1985
1986
1987
1988
1989
1990

1991

1992
1993
1994

1995

1996
1997
1998

1999

2000
2001
2002

2003

2004
2005
2006
2007
2008
2009
2010
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) !=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {

	    Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (reqHeight < 0) {

	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (widthInc <= 0) {

	    Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (heightInc <= 0) {

	    Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073

2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    const char *argv3;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {







|

|


|
>







|



|







2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
	    CreateWrapper(wmPtr2);
	}
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(wmPtr2->wrapperPtr);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = (char *)ckalloc(objv[3]->length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*







|







2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
	    CreateWrapper(wmPtr2);
	}
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(wmPtr2->wrapperPtr);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = ckalloc((unsigned) length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display,
			    wmPtr->hints.icon_pixmap), -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);







|



|

|

|







|
|
|







2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
		    TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;
    }
    if (wmPtr->containerPtr != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is a transient",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is an icon for \"%s\"",
		winPtr->pathName, Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }
    if (TkpWmSetState(winPtr, IconicState) == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't send iconify message to window manager", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|



|

|
<





|
|
<
<
<


|
|
|
<
<



|
<
|
<



|
|
<
<



|
|
|







2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175

2176
2177
2178
2179
2180
2181
2182



2183
2184
2185
2186
2187


2188
2189
2190
2191

2192

2193
2194
2195
2196
2197


2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", NULL);



	return TCL_ERROR;
    }
    if (wmPtr->masterPtr != NULL) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", NULL);


	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,

		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an embedded window", NULL);


	return TCL_ERROR;
    }
    if (TkpWmSetState(winPtr, IconicState) == 0) {
	Tcl_SetResult(interp,
		"couldn't send iconify message to window manager",
		TCL_STATIC);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);







|

|

|







|

|







2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340

2341
2342
2343

2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {

	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
	}

	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = Tcl_GetString(objv[3]);
	wmPtr->iconName = (char *)ckalloc(objv[3]->length + 1);
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;
}







|



|

|
|
>






>
|
<
<
>



|

|
|







2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303


2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetResult(interp,
		((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),


		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree((char *) wmPtr->iconName);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = ckalloc((unsigned) length + 1);
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;
}
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i, size = 0, width, height, index = 0, x, y, isDefault = 0;
    unsigned long *iconPropertyData;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,







|



|

|







2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i, size = 0, width, height, index = 0, x, y, isDefault = 0;
    unsigned long *iconPropertyData;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468

2469

2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
     * Iterate over all images to retrieve their sizes, in order to allocate a
     * buffer large enough to hold all images.
     */

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use \"%s\" as iconphoto: not a photo image",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);

	/*
	 * We need to cardinals for width & height and one cardinal for each
	 * image pixel.
	 */

	size += 2 + width * height;
    }

    /*
     * We have calculated the size of the data. Try to allocate the needed
     * memory space. This is an unsigned long array (despite this being twice
     * as much as is really needed on LP64 platforms) because that's what X
     * defines CARD32 arrays to use. [Bug 2902814]
     */

    iconPropertyData = (unsigned long *)attemptckalloc(sizeof(unsigned long) * size);

    if (iconPropertyData == NULL) {
	return TCL_ERROR;
    }
    memset(iconPropertyData, 0, sizeof(unsigned long) * size);

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    ckfree((char *) iconPropertyData);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "failed to create an iconphoto with image \"%s\"",
		Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Each image data will be placed as an array of 32bit packed
	 * CARDINAL, in a window property named "_NET_WM_ICON": _NET_WM_ICON
	 *
	 * _NET_WM_ICON CARDINAL[][2+n]/32
	 *
	 * This is an array of possible icons for the client. This spec. does
	 * not stipulate what size these icons should be, but individual
	 * desktop environments or toolkits may do so. The Window Manager MAY
	 * scale any of these icons to an appropriate size.
	 *
	 * This is an array of 32bit packed CARDINAL ARGB with high byte being
	 * A, low byte being B. The first two cardinals are width, height.
	 * Data is in rows, left to right and top to bottom. The data will be
	 * endian-swapped going to the server if necessary. [Bug 2830420]

	 *

	 * The image data will be encoded in the iconPropertyData array.
	 */

	iconPropertyData[index++] = (unsigned long) width;
	iconPropertyData[index++] = (unsigned long) height;
	for (y = 0; y < height; y++) {
	    for (x = 0; x < width; x++) {
		unsigned char *pixelPtr =
			block.pixelPtr + x*block.pixelSize + y*block.pitch;
		unsigned long R, G, B, A;

		R = pixelPtr[block.offset[0]];
		G = pixelPtr[block.offset[1]];
		B = pixelPtr[block.offset[2]];
		A = pixelPtr[block.offset[3]];
		iconPropertyData[index++] = A<<24 | R<<16 | G<<8 | B<<0;
	    }
	}
    }
    if (wmPtr->iconDataPtr != NULL) {
	ckfree(wmPtr->iconDataPtr);
	wmPtr->iconDataPtr = NULL;
    }
    if (isDefault) {
	if (winPtr->dispPtr->iconDataPtr != NULL) {
	    ckfree(winPtr->dispPtr->iconDataPtr);
	}
	winPtr->dispPtr->iconDataPtr = (unsigned char *) iconPropertyData;
	winPtr->dispPtr->iconDataSize = size;
    } else {
	wmPtr->iconDataPtr = (unsigned char *) iconPropertyData;
	wmPtr->iconDataSize = size;
    }







|
|
<
<



















|
>








|
<
<
<
<




















>
|
>
|


|
|


|

|










|




|







2366
2367
2368
2369
2370
2371
2372
2373
2374


2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404




2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
     * Iterate over all images to retrieve their sizes, in order to allocate a
     * buffer large enough to hold all images.
     */

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]),
		    "\" as iconphoto: not a photo image", NULL);


	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);

	/*
	 * We need to cardinals for width & height and one cardinal for each
	 * image pixel.
	 */

	size += 2 + width * height;
    }

    /*
     * We have calculated the size of the data. Try to allocate the needed
     * memory space. This is an unsigned long array (despite this being twice
     * as much as is really needed on LP64 platforms) because that's what X
     * defines CARD32 arrays to use. [Bug 2902814]
     */

    iconPropertyData = (unsigned long *)
	    attemptckalloc(sizeof(unsigned long) * size);
    if (iconPropertyData == NULL) {
	return TCL_ERROR;
    }
    memset(iconPropertyData, 0, sizeof(unsigned long) * size);

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    Tcl_Free((char *) iconPropertyData);




	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Each image data will be placed as an array of 32bit packed
	 * CARDINAL, in a window property named "_NET_WM_ICON": _NET_WM_ICON
	 *
	 * _NET_WM_ICON CARDINAL[][2+n]/32
	 *
	 * This is an array of possible icons for the client. This spec. does
	 * not stipulate what size these icons should be, but individual
	 * desktop environments or toolkits may do so. The Window Manager MAY
	 * scale any of these icons to an appropriate size.
	 *
	 * This is an array of 32bit packed CARDINAL ARGB with high byte being
	 * A, low byte being B. The first two cardinals are width, height.
	 * Data is in rows, left to right and top to bottom. The data will be
	 * endian-swapped going to the server if necessary. [Bug 2830420]
	 */

	/*
	 * Encode the image data in the iconPropertyData array.
	 */

	iconPropertyData[index++] = (unsigned) width;
	iconPropertyData[index++] = (unsigned) height;
	for (y = 0; y < height; y++) {
	    for (x = 0; x < width; x++) {
		register unsigned char *pixelPtr =
			block.pixelPtr + x*block.pixelSize + y*block.pitch;
		register unsigned long R, G, B, A;

		R = pixelPtr[block.offset[0]];
		G = pixelPtr[block.offset[1]];
		B = pixelPtr[block.offset[2]];
		A = pixelPtr[block.offset[3]];
		iconPropertyData[index++] = A<<24 | R<<16 | G<<8 | B<<0;
	    }
	}
    }
    if (wmPtr->iconDataPtr != NULL) {
	ckfree((char *) wmPtr->iconDataPtr);
	wmPtr->iconDataPtr = NULL;
    }
    if (isDefault) {
	if (winPtr->dispPtr->iconDataPtr != NULL) {
	    ckfree((char *) winPtr->dispPtr->iconDataPtr);
	}
	winPtr->dispPtr->iconDataPtr = (unsigned char *) iconPropertyData;
	winPtr->dispPtr->iconDataSize = size;
    } else {
	wmPtr->iconDataPtr = (unsigned char *) iconPropertyData;
	wmPtr->iconDataSize = size;
    }
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
	    Tcl_Obj *results[2];

	    results[0] = Tcl_NewWideIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->hints.icon_y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    UpdateHints(winPtr);







|



|

|








|

|
|
|



|



|







2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
	    char buf[TCL_INTEGER_SPACE * 2];

	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
		    wmPtr->hints.icon_y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    UpdateHints(winPtr);
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*







|

|










|







2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use %s as icon window: not at top level",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "INNER", NULL);
	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is already an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;

	    wmPtr3->iconFor = NULL;
	    wmPtr3->withdrawn = 1;
	    wmPtr3->hints.initial_state = WithdrawnState;
	}

	/*
	 * Disable button events in the icon window: some window managers







|
|
<
<




|
|
<
|




<







2580
2581
2582
2583
2584
2585
2586
2587
2588


2589
2590
2591
2592
2593
2594

2595
2596
2597
2598
2599

2600
2601
2602
2603
2604
2605
2606
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
		    " as icon window: not at top level", NULL);


	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
		    " is already an icon for ", Tk_PathName(wmPtr2->iconFor),

		    NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;

	    wmPtr3->iconFor = NULL;
	    wmPtr3->withdrawn = 1;
	    wmPtr3->hints.initial_state = WithdrawnState;
	}

	/*
	 * Disable button events in the icon window: some window managers
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
	wmPtr->icon = tkwin2;
	wmPtr2->iconFor = (Tk_Window) winPtr;
	if (!wmPtr2->withdrawn && !(wmPtr2->flags & WM_NEVER_MAPPED)) {
	    wmPtr2->withdrawn = 0;
	    if (XWithdrawWindow(Tk_Display(tkwin2),
		    Tk_WindowId(wmPtr2->wrapperPtr),
		    Tk_ScreenNumber(tkwin2)) == 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't send withdraw message to window manager",
			-1));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	    WaitForMapNotify((TkWindow *) tkwin2, 0);
	}
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmManageCmd --
 *
 *	This procedure is invoked to process the "wm manage" 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
WmManageCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a frame,"
		    " labelframe or toplevel", Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	winPtr->flags |=
		TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    TkWmMapWindow(winPtr);
	    Tk_UnmapWindow(frameWin);
	}
	wmPtr = winPtr->wmInfoPtr;
	winPtr->flags &= ~TK_MAPPED;
	RemapWindows(winPtr, wmPtr->wrapperPtr);

	/*
	 * Flags (above) must be set before calling TkMapTopFrame (below).
	 */

	TkMapTopFrame(frameWin);
    } else if (Tk_IsTopLevel(frameWin)) {
	/*
	 * Already managed by wm - ignore it.
	 */
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

|
<














|
|











|
|
|
|
|
|

|
|



|
|
|
<




<
|








<
<
|
<
|
|

<
|
<







2620
2621
2622
2623
2624
2625
2626
2627
2628
2629

2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671

2672
2673
2674
2675

2676
2677
2678
2679
2680
2681
2682
2683
2684


2685

2686
2687
2688

2689

2690
2691
2692
2693
2694
2695
2696
	wmPtr->icon = tkwin2;
	wmPtr2->iconFor = (Tk_Window) winPtr;
	if (!wmPtr2->withdrawn && !(wmPtr2->flags & WM_NEVER_MAPPED)) {
	    wmPtr2->withdrawn = 0;
	    if (XWithdrawWindow(Tk_Display(tkwin2),
		    Tk_WindowId(wmPtr2->wrapperPtr),
		    Tk_ScreenNumber(tkwin2)) == 0) {
		Tcl_SetResult(interp,
			"couldn't send withdraw message to window manager",
			TCL_STATIC);

		return TCL_ERROR;
	    }
	    WaitForMapNotify((TkWindow *) tkwin2, 0);
	}
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmManageCmd --
 *
 *	This procedure is invoked to process the "wm manage" 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
WmManageCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel or Frame to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Tk_Window frameWin = (Tk_Window) winPtr;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_AppendResult(interp, "window \"",
		Tk_PathName(frameWin), "\" is not manageable: must be "
		"a frame, labelframe or toplevel", NULL);

	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);

	winPtr->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    TkWmMapWindow(winPtr);
	    Tk_UnmapWindow(frameWin);
	}
	wmPtr = winPtr->wmInfoPtr;
	winPtr->flags &= ~TK_MAPPED;
	RemapWindows(winPtr, wmPtr->wrapperPtr);


	/* flags (above) must be set before calling */

	/* TkMapTopFrame (below) */
	TkMapTopFrame (frameWin);
    } else if (Tk_IsTopLevel(frameWin)) {

	/* Already managed by wm - ignore it */

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;







|



|

|







|


<
|
|







2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729

2730
2731
2732
2733
2734
2735
2736
2737
2738
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];

	GetMaxSize(wmPtr, &width, &height);

	sprintf(buf, "%d %d", width, height);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	results[0] = Tcl_NewWideIntObj(wmPtr->minWidth);
	results[1] = Tcl_NewWideIntObj(wmPtr->minHeight);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;







|



|

|







|

<
|
|







2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786

2787
2788
2789
2790
2791
2792
2793
2794
2795
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];


	sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int boolean, curValue;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	/*







|



|










|







2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    int boolean, curValue;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (objc == 3) {
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue);
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	/*
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;







|



|

|
|










<
<

|

|

<





|
|







2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896


2897
2898
2899
2900
2901

2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {


	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}

	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057

3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    TkSizeT cmdLength;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */

	Tcl_Obj *resultObj = Tcl_NewObj();

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol),-1));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Special case for _NET_WM_PING: that's always handled directly.
     */

    if (strcmp(Tcl_GetString(objv[3]), "_NET_WM_PING") == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not alter handling of that protocol", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "PROTOCOL", "RESERVED", NULL);

	return TCL_ERROR;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = TkGetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
    }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {







|



|

|
|

|
|










<
<


|
|

<











|
<











<
|
<
>
















|



|

|







2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963


2964
2965
2966
2967
2968

2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980

2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991

2992

2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    register ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    int cmdLength;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */



	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_AppendElement(interp,
		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	}

	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetResult(interp, protPtr->command, TCL_STATIC);

		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Special case for _NET_WM_PING: that's always handled directly.
     */

    if (strcmp(Tcl_GetString(objv[3]), "_NET_WM_PING") == 0) {

	Tcl_SetResult(interp, "may not alter handling of that protocol",

		TCL_STATIC);
	return TCL_ERROR;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
    }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127

3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];


	results[0] = Tcl_NewWideIntObj(!(wmPtr->flags&WM_WIDTH_NOT_RESIZABLE));
	results[1] = Tcl_NewWideIntObj(!(wmPtr->flags&WM_HEIGHT_NOT_RESIZABLE));
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {







|



|

|







|

>
|
|
|







3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d",
		(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;







|



|

|
|










<
<

|

|

<






|
|







3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125


3126
3127
3128
3129
3130

3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {


	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}

	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310

3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328

3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };
    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    /* ASSERT: true [Bug 1789819]*/
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj((*window_ptr)->pathName, -1));
	    }
	    ckfree(windows);
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
    } else {
	Tk_Window relWin;
	TkWindow *winPtr2;
	int index1=-1, index2=-1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4], &relWin) != TCL_OK) {
	    return TCL_ERROR;
	}
	winPtr2 = (TkWindow *) relWin;

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't a top-level window",
		    winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);

	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (window_ptr = windows; *window_ptr ; window_ptr++) {
	    if (*window_ptr == winPtr) {
		index1 = (window_ptr - windows);
	    }
	    if (*window_ptr == winPtr2) {
		index2 = (window_ptr - windows);
	    }
	}
	/* ASSERT: index1 != -1 && index2 != -2 [Bug 1789819] */
	ckfree(windows);


	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|


|













<
<


<
|

|
<

<
<












|
|
<
<




|
|
<




|
|
<









>

<
|
<

<
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|







|







3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193


3194
3195

3196
3197
3198

3199


3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213


3214
3215
3216
3217
3218
3219

3220
3221
3222
3223
3224
3225

3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236

3237

3238

3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static CONST char *optionStrings[] = {
	"isabove", "isbelow", NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };
    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {


	    /* ASSERT: true [Bug 1789819]*/
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {

		Tcl_AppendElement(interp, (*window_ptr)->pathName);
	    }
	    ckfree((char *) windows);

	    return TCL_OK;


	}
    } else {
	Tk_Window relWin;
	TkWindow *winPtr2;
	int index1=-1, index2=-1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4], &relWin) != TCL_OK) {
	    return TCL_ERROR;
	}
	winPtr2 = (TkWindow *) relWin;

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", NULL);


	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);

	if (windows == NULL) {

	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);

	    return TCL_ERROR;

	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		if (*window_ptr == winPtr) {
		    index1 = (window_ptr - windows);
		}
		if (*window_ptr == winPtr2) {
		    index2 = (window_ptr - windows);
		}
	    }
	    /* ASSERT: index1 != -1 && index2 != -2 [Bug 1789819] */
	    ckfree((char *) windows);
	}

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of %s: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
	    return TCL_ERROR;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (index == OPT_NORMAL) {
	    wmPtr->flags &= ~WM_WITHDRAWN;
	    (void) TkpWmSetState(winPtr, NormalState);
	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->containerPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
	    if (TkpWmSetState(winPtr, IconicState) == 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't send iconify message to window manager",
			-1));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	} else { /* OPT_WITHDRAWN */
	    wmPtr->flags |= WM_WITHDRAWN;
	    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't send withdraw message to window manager",
			-1));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	}
    } else {
	const char *state;

	if (wmPtr->iconFor != NULL) {
	    state = "icon";
	} else if (wmPtr->withdrawn) {
	    state = "withdrawn";
	} else if (Tk_IsMapped((Tk_Window) winPtr)
		|| ((wmPtr->flags & WM_NEVER_MAPPED)
			&& (wmPtr->hints.initial_state == NormalState))) {
	    state = "normal";
	} else {
	    state = "iconic";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(state, -1));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|



|

|
|











|
|
|
<



|
|








|
|
<
<
<


|
|
|
<
<
<



|

|
<





|

|
<




<
<

|

|



|

|

<







3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307

3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322



3323
3324
3325
3326
3327



3328
3329
3330
3331
3332
3333

3334
3335
3336
3337
3338
3339
3340
3341

3342
3343
3344
3345


3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356

3357
3358
3359
3360
3361
3362
3363
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"normal", "iconic", "withdrawn", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]), ": it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);

	    return TCL_ERROR;
	}

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (index == OPT_NORMAL) {
	    wmPtr->flags &= ~WM_WITHDRAWN;
	    (void) TkpWmSetState(winPtr, NormalState);
	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
			"\": override-redirect flag is set", NULL);



		return TCL_ERROR;
	    }
	    if (wmPtr->masterPtr != NULL) {
		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
			"\": it is a transient", NULL);



		return TCL_ERROR;
	    }
	    if (TkpWmSetState(winPtr, IconicState) == 0) {
		Tcl_SetResult(interp,
			"couldn't send iconify message to window manager",
			TCL_STATIC);

		return TCL_ERROR;
	    }
	} else { /* OPT_WITHDRAWN */
	    wmPtr->flags |= WM_WITHDRAWN;
	    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
		Tcl_SetResult(interp,
			"couldn't send withdraw message to window manager",
			TCL_STATIC);

		return TCL_ERROR;
	    }
	}
    } else {


	if (wmPtr->iconFor != NULL) {
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
	} else if (wmPtr->withdrawn) {
	    Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
	} else if (Tk_IsMapped((Tk_Window) winPtr)
		|| ((wmPtr->flags & WM_NEVER_MAPPED)
			&& (wmPtr->hints.initial_state == NormalState))) {
	    Tcl_SetResult(interp, "normal", TCL_STATIC);
	} else {
	    Tcl_SetResult(interp, "iconic", TCL_STATIC);
	}

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476

3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487


3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->title) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->title, -1));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, -1));
	}


    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	argv3 = Tcl_GetString(objv[3]);
	wmPtr->title = (char *)ckalloc(objv[3]->length + 1);
	strcpy(wmPtr->title, argv3);

	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;







|



|

|
|
>






<
|
<
|
<
>
>


|

|
|







3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394

3395

3396

3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }
    if (objc == 3) {

	Tcl_SetResult(interp, (char *)

		((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),

		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->title != NULL) {
	    ckfree((char *) wmPtr->title);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->title = ckalloc((unsigned) length + 1);
	strcpy(wmPtr->title, argv3);

	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619

3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (containerPtr != NULL) {
	    /*
	     * If we had a container, tell them that we aren't tied to them
	     * anymore
	     */

	    containerPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) containerPtr, StructureNotifyMask,
		    WmWaitMapProc, winPtr);

	    /*
	     * FIXME: Need a call like Win32's UpdateWrapper() so we can
	     * recreate the wrapper and get rid of the transient window
	     * decorations.
	     */
	}

	wmPtr->containerPtr = NULL;
    } else {
	Tk_Window container;

	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container)!=TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = (TkWindow *) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
	    /*
	     * Ensure that the container window is actually a Tk toplevel.
	     */

	    containerPtr = containerPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = containerPtr->wmInfoPtr;
	if (wmPtr2->wrapperPtr == NULL) {
	    CreateWrapper(wmPtr2);
	}

	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	if (containerPtr != wmPtr->containerPtr) {
	    /*
	     * Remove old container map/unmap binding before setting the new
	     * container. The event handler will ensure that transient states
	     * reflect the state of the container.
	     */

	    if (wmPtr->containerPtr != NULL) {
		wmPtr->containerPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
			StructureNotifyMask, WmWaitMapProc, winPtr);

	    }

	    containerPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) containerPtr,
		    StructureNotifyMask, WmWaitMapProc, winPtr);

	    wmPtr->containerPtr = containerPtr;
	}
    }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->containerPtr != NULL && !Tk_IsMapped(wmPtr->containerPtr)) {
	    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't send withdraw message to window manager",
			-1));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	} else {
	    if (wmPtr->containerPtr != NULL) {
		XSetTransientForHint(winPtr->display,
			wmPtr->wrapperPtr->window,
			wmPtr->containerPtr->wmInfoPtr->wrapperPtr->window);
	    } else {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_TRANSIENT_FOR"));
	    }
	}
    }
    return TCL_OK;
}

/*







|

|
|



|



|
|




|

|



|
|
|








|

|

|


|
|

|


|

|


|
|
|
<



|





|
|
|
<



<
<
|
|
<
<
|
|
<
<
<
|

|
|
|


|
|
|
|
>


|
|
|

|



|

|

|
<



|


|


|







3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491

3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503

3504
3505
3506


3507
3508


3509
3510



3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *masterPtr = wmPtr->masterPtr;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (masterPtr != NULL) {
	    Tcl_SetResult(interp, Tk_PathName(masterPtr), TCL_STATIC);
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (masterPtr != NULL) {
	    /*
	     * If we had a master, tell them that we aren't tied to them
	     * anymore
	     */

	    masterPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) masterPtr, StructureNotifyMask,
		    WmWaitMapProc, (ClientData) winPtr);

	    /*
	     * FIXME: Need a call like Win32's UpdateWrapper() so we can
	     * recreate the wrapper and get rid of the transient window
	     * decorations.
	     */
	}

	wmPtr->masterPtr = NULL;
    } else {
	Tk_Window masterWin;

	if (TkGetWindowFromObj(interp, tkwin, objv[3], &masterWin)!=TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = (TkWindow *) masterWin;
	while (!Tk_TopWinHierarchy(masterPtr)) {
	    /*
	     * Ensure that the master window is actually a Tk toplevel.
	     */

	    masterPtr = masterPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) masterPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);

	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;
	if (wmPtr2->wrapperPtr == NULL) {
	    CreateWrapper(wmPtr2);
	}

	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor), NULL);

	    return TCL_ERROR;
	}



	if (masterPtr == winPtr) {
	    Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),


		    "\" its own master", NULL);
	    return TCL_ERROR;



	} else if (masterPtr != wmPtr->masterPtr) {
	    /*
	     * Remove old master map/unmap binding before setting the new
	     * master. The event handler will ensure that transient states
	     * reflect the state of the master.
	     */

	    if (wmPtr->masterPtr != NULL) {
		wmPtr->masterPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
			StructureNotifyMask,
			WmWaitMapProc, (ClientData) winPtr);
	    }

	    masterPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) masterPtr,
		    StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr);

	    wmPtr->masterPtr = masterPtr;
	}
    }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->masterPtr != NULL && !Tk_IsMapped(wmPtr->masterPtr)) {
	    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
		Tcl_SetResult(interp,
			"couldn't send withdraw message to window manager",
			TCL_STATIC);

		return TCL_ERROR;
	    }
	} else {
	    if (wmPtr->masterPtr != NULL) {
		XSetTransientForHint(winPtr->display,
			wmPtr->wrapperPtr->window,
			wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
	    } else {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_TRANSIENT_FOR"));
	    }
	}
    }
    return TCL_OK;
}

/*
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }
    wmPtr->flags |= WM_WITHDRAWN;
    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't send withdraw message to window manager", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry. Schedules a geometry
 * update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
 * that is the container of a transient toplevel.
 */

static void
WmWaitMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL) {
	return;
    }

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    (void) TkpWmSetState(winPtr, NormalState);
	}







|



|

|






<
|
|
<




|
|
|
















|






|







|
|

|







3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585

3586
3587

3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    wmPtr->flags |= WM_WITHDRAWN;
    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
	Tcl_SetResult(interp,
		"couldn't send withdraw message to window manager",
		TCL_STATIC);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry. Schedules a geometry
 * update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
 * that is the master of a transient toplevel.
 */

static void
WmWaitMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;
    TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;

    if (masterPtr == NULL) {
	return;
    }

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    (void) TkpWmSetState(winPtr, NormalState);
	}
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
	widthInc = 1;







|







3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
	widthInc = 1;
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {







|







3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
    wmPtr->heightInc = 1;

    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
    wmPtr->heightInc = 1;

    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164

4165

4166
4167

4168

4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
				 * wmPtr->wrapperPtr. */
{
    TkWindow *wrapperPtr = wmPtr->wrapperPtr;
    Window vRoot, ancestor, *children, dummy2, *virtualRootPtr, **vrPtrPtr;
    Atom actualType;
    int actualFormat;
    unsigned long numItems, bytesAfter;
    unsigned dummy;
    Tk_ErrorHandler handler;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;
    Atom WM_ROOT = Tk_InternAtom((Tk_Window) wrapperPtr, "__WM_ROOT");
    Atom SWM_ROOT = Tk_InternAtom((Tk_Window) wrapperPtr, "__SWM_ROOT");

    /*
     * Identify the root window for wrapperPtr. This is tricky because of
     * virtual root window managers like tvtwm. If the window has a property
     * named __SWM_ROOT or __WM_ROOT then this property gives the id for a
     * virtual root window that should be used instead of the root window of
     * the screen.
     */

    vRoot = RootWindow(wrapperPtr->display, wrapperPtr->screenNum);
    wmPtr->vRoot = None;
    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
    vrPtrPtr = &virtualRootPtr;		/* Silence GCC warning */
    if ((GetWindowProperty(wrapperPtr, WM_ROOT, 1, XA_WINDOW,

	    &actualType, &actualFormat, &numItems, &bytesAfter, vrPtrPtr)

	    && (actualType == XA_WINDOW))
	|| (GetWindowProperty(wrapperPtr, SWM_ROOT, 1, XA_WINDOW,

	    &actualType, &actualFormat, &numItems, &bytesAfter, vrPtrPtr)

	    && (actualType == XA_WINDOW))) {
	if ((actualFormat == 32) && (numItems == 1)) {
	    vRoot = wmPtr->vRoot = *virtualRootPtr;
	} else if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	    printf("%s format %d numItems %ld\n",
		    "ReparentEvent got bogus VROOT property:", actualFormat,
		    numItems);
	}
	XFree((char *) virtualRootPtr);
    }
    Tk_DeleteErrorHandler(handler);

    if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("ReparentEvent: %s (%p) reparented to 0x%x, vRoot = 0x%x\n",
		wmPtr->winPtr->pathName, wmPtr->winPtr,
		(unsigned) reparentEventPtr->parent, (unsigned) vRoot);
    }

    /*
     * Fetch correct geometry information for the new virtual root.
     */

    UpdateVRootGeometry(wmPtr);







|


<
<













|
>
|
>

|
>
|
>















|







4039
4040
4041
4042
4043
4044
4045
4046
4047
4048


4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
				 * wmPtr->wrapperPtr. */
{
    TkWindow *wrapperPtr = wmPtr->wrapperPtr;
    Window vRoot, ancestor, *children, dummy2, *virtualRootPtr, **vrPtrPtr;
    Atom actualType;
    int actualFormat;
    unsigned long numItems, bytesAfter;
    unsigned int dummy;
    Tk_ErrorHandler handler;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;



    /*
     * Identify the root window for wrapperPtr. This is tricky because of
     * virtual root window managers like tvtwm. If the window has a property
     * named __SWM_ROOT or __WM_ROOT then this property gives the id for a
     * virtual root window that should be used instead of the root window of
     * the screen.
     */

    vRoot = RootWindow(wrapperPtr->display, wrapperPtr->screenNum);
    wmPtr->vRoot = None;
    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
    vrPtrPtr = &virtualRootPtr;		/* Silence GCC warning */
    if (((XGetWindowProperty(wrapperPtr->display, wrapperPtr->window,
	    Tk_InternAtom((Tk_Window) wrapperPtr, "__WM_ROOT"), 0, (long) 1,
	    False, XA_WINDOW, &actualType, &actualFormat, &numItems,
	    &bytesAfter, (unsigned char **) vrPtrPtr) == Success)
	    && (actualType == XA_WINDOW))
	    || ((XGetWindowProperty(wrapperPtr->display, wrapperPtr->window,
	    Tk_InternAtom((Tk_Window) wrapperPtr, "__SWM_ROOT"), 0, (long) 1,
	    False, XA_WINDOW, &actualType, &actualFormat, &numItems,
	    &bytesAfter, (unsigned char **) vrPtrPtr) == Success)
	    && (actualType == XA_WINDOW))) {
	if ((actualFormat == 32) && (numItems == 1)) {
	    vRoot = wmPtr->vRoot = *virtualRootPtr;
	} else if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	    printf("%s format %d numItems %ld\n",
		    "ReparentEvent got bogus VROOT property:", actualFormat,
		    numItems);
	}
	XFree((char *) virtualRootPtr);
    }
    Tk_DeleteErrorHandler(handler);

    if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("ReparentEvent: %s (%p) reparented to 0x%x, vRoot = 0x%x\n",
		wmPtr->winPtr->pathName, wmPtr->winPtr,
		(unsigned int) reparentEventPtr->parent, (unsigned int) vRoot);
    }

    /*
     * Fetch correct geometry information for the new virtual root.
     */

    UpdateVRootGeometry(wmPtr);
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
static int
ComputeReparentGeometry(
    WmInfo *wmPtr)		/* Information about toplevel window whose
				 * reparent info is to be recomputed. */
{
    TkWindow *wrapperPtr = wmPtr->wrapperPtr;
    int width, height, bd;
    unsigned dummy;
    int xOffset, yOffset, x, y;
    Window dummy2;
    Status status;
    Tk_ErrorHandler handler;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
    (void) XTranslateCoordinates(wrapperPtr->display, wrapperPtr->window,
	    wmPtr->reparent, 0, 0, &xOffset, &yOffset, &dummy2);
    status = XGetGeometry(wrapperPtr->display, wmPtr->reparent,
	    &dummy2, &x, &y, (unsigned *) &width, (unsigned *) &height,
	    (unsigned *) &bd, &dummy);
    Tk_DeleteErrorHandler(handler);
    if (status == 0) {
	/*
	 * It appears that the reparented parent went away and no-one told us.
	 * Reset the window to indicate that it's not reparented.
	 */








|










|
|







4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
static int
ComputeReparentGeometry(
    WmInfo *wmPtr)		/* Information about toplevel window whose
				 * reparent info is to be recomputed. */
{
    TkWindow *wrapperPtr = wmPtr->wrapperPtr;
    int width, height, bd;
    unsigned int dummy;
    int xOffset, yOffset, x, y;
    Window dummy2;
    Status status;
    Tk_ErrorHandler handler;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
    (void) XTranslateCoordinates(wrapperPtr->display, wrapperPtr->window,
	    wmPtr->reparent, 0, 0, &xOffset, &yOffset, &dummy2);
    status = XGetGeometry(wrapperPtr->display, wmPtr->reparent,
	    &dummy2, &x, &y, (unsigned int *) &width,
	    (unsigned int *) &height, (unsigned int *) &bd, &dummy);
    Tk_DeleteErrorHandler(handler);
    if (status == 0) {
	/*
	 * It appears that the reparented parent went away and no-one told us.
	 * Reset the window to indicate that it's not reparented.
	 */

4373
4374
4375
4376
4377
4378
4379
4380


4381
4382
4383
4384
4385
4386
4387
4388
4389
    if (eventPtr->atom == _NET_WM_STATE) {
	Atom actualType;
	int actualFormat;
	unsigned long numItems, bytesAfter;
	unsigned char *propertyValue = 0;
	long maxLength = 1024;

	if (GetWindowProperty(wrapperPtr, _NET_WM_STATE, maxLength, XA_ATOM,


		&actualType, &actualFormat, &numItems, &bytesAfter,
		&propertyValue)) {
	    CheckNetWmState(wmPtr, (Atom *) propertyValue, (int) numItems);
	    XFree(propertyValue);
	}
    }
}

/*







|
>
>

|







4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
    if (eventPtr->atom == _NET_WM_STATE) {
	Atom actualType;
	int actualFormat;
	unsigned long numItems, bytesAfter;
	unsigned char *propertyValue = 0;
	long maxLength = 1024;

	if (XGetWindowProperty(
		wrapperPtr->display, wrapperPtr->window, _NET_WM_STATE,
		0l, maxLength, False, XA_ATOM,
		&actualType, &actualFormat, &numItems, &bytesAfter,
		&propertyValue) == Success) {
	    CheckNetWmState(wmPtr, (Atom *) propertyValue, (int) numItems);
	    XFree(propertyValue);
	}
    }
}

/*
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
 * Side effects:
 *	Tk's internal data structures for the window get modified to reflect
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static const unsigned WrapperEventMask =
	(StructureNotifyMask | PropertyChangeMask);

static void
WrapperEventProc(
    ClientData clientData,	/* Information about toplevel window. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;
    XEvent mapEvent;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    wmPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;








|
|






|







4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
 * Side effects:
 *	Tk's internal data structures for the window get modified to reflect
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static const unsigned int WrapperEventMask =
    (StructureNotifyMask | PropertyChangeMask);

static void
WrapperEventProc(
    ClientData clientData,	/* Information about toplevel window. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    WmInfo *wmPtr = (WmInfo *) clientData;
    XEvent mapEvent;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    wmPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

4488
4489
4490
4491
4492
4493
4494

4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */


static void
TopLevelReqProc(
    TCL_UNUSED(void *),		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr == NULL) {
	return;
    }

    if ((wmPtr->width >= 0) && (wmPtr->height >= 0)) {
	/*
	 * Explicit dimensions have been set for this window, so we should
	 * ignore the geometry request. It's actually important to ignore the
	 * geometry request because, due to quirks in window managers,
	 * invoking UpdateGeometryInfo may cause the window to move. For
	 * example, if "wm geometry -10-20" was invoked, the window may be
	 * positioned incorrectly the first time it appears (because we didn't
	 * know the proper width of the window manager borders); if we invoke
	 * UpdateGeometryInfo again, the window will be positioned correctly,
	 * which may cause it to jump on the screen.
	 */

	return;
    }

    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }

    /*
     * If the window isn't being positioned by its upper left corner then we
     * have to move it as well.
     */







>


|



|

|

<



















|







4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409

4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    if ((wmPtr = winPtr->wmInfoPtr) == NULL)
	return;


    if ((wmPtr->width >= 0) && (wmPtr->height >= 0)) {
	/*
	 * Explicit dimensions have been set for this window, so we should
	 * ignore the geometry request. It's actually important to ignore the
	 * geometry request because, due to quirks in window managers,
	 * invoking UpdateGeometryInfo may cause the window to move. For
	 * example, if "wm geometry -10-20" was invoked, the window may be
	 * positioned incorrectly the first time it appears (because we didn't
	 * know the proper width of the window manager borders); if we invoke
	 * UpdateGeometryInfo again, the window will be positioned correctly,
	 * which may cause it to jump on the screen.
	 */

	return;
    }

    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }

    /*
     * If the window isn't being positioned by its upper left corner then we
     * have to move it as well.
     */
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;
    unsigned long serial;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * Compute the new size for the top-level window. See the user







|
|







4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    register TkWindow *winPtr = (TkWindow *) clientData;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;
    unsigned long serial;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * Compute the new size for the top-level window. See the user
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
     * There may also be a size-hint-update request pending from somewhere
     * else, too.
     */

    if (((width != winPtr->changes.width)
	    || (height != winPtr->changes.height))
	    && (wmPtr->gridWin == NULL)
	    && !(wmPtr->sizeHintsFlags & (PMinSize|PMaxSize))) {
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }
    if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
	UpdateSizeHints(winPtr, width, height);
    }

    /*
     * Reconfigure the wrapper if it isn't already configured correctly. A few
     * tricky points:
     *
     * 1. If the window is embedded and the container is also in this process,
     *    don't actually reconfigure the window; just pass the desired size on
     *    to the container. Also, zero out any position information, since
     *    embedded windows are not allowed to move.
     * 2. Sometimes the window manager will give us a different size than we
     *    asked for (e.g. mwm has a minimum size for windows), so base the
     *    size check on what we *asked for* last time, not what we got.
     * 3. Can't just reconfigure always, because we may not get a







|










|







4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
     * There may also be a size-hint-update request pending from somewhere
     * else, too.
     */

    if (((width != winPtr->changes.width)
	    || (height != winPtr->changes.height))
	    && (wmPtr->gridWin == NULL)
	    && ((wmPtr->sizeHintsFlags & (PMinSize|PMaxSize)) == 0)) {
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }
    if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
	UpdateSizeHints(winPtr, width, height);
    }

    /*
     * Reconfigure the wrapper if it isn't already configured correctly. A few
     * tricky points:
     *
     * 1. If the window is embeddedand the container is also in this process,
     *    don't actually reconfigure the window; just pass the desired size on
     *    to the container. Also, zero out any position information, since
     *    embedded windows are not allowed to move.
     * 2. Sometimes the window manager will give us a different size than we
     *    asked for (e.g. mwm has a minimum size for windows), so base the
     *    size check on what we *asked for* last time, not what we got.
     * 3. Can't just reconfigure always, because we may not get a
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
	}
	return;
    }
    serial = NextRequest(winPtr->display);
    height += wmPtr->menuHeight;
    if (wmPtr->flags & WM_MOVE_PENDING) {
	if ((x + wmPtr->xInParent == winPtr->changes.x) &&
		(y+wmPtr->yInParent+wmPtr->menuHeight == winPtr->changes.y)
		&& (width == wmPtr->wrapperPtr->changes.width)
		&& (height == wmPtr->wrapperPtr->changes.height)) {
	    /*
	     * The window already has the correct geometry, so don't bother to
	     * configure it; the X server appears to ignore these requests, so
	     * we won't get back a ConfigureNotify and the
	     * WaitForConfigureNotify call below will hang for a while.







|







4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
	}
	return;
    }
    serial = NextRequest(winPtr->display);
    height += wmPtr->menuHeight;
    if (wmPtr->flags & WM_MOVE_PENDING) {
	if ((x + wmPtr->xInParent == winPtr->changes.x) &&
		(y + wmPtr->yInParent + wmPtr->menuHeight == winPtr->changes.y)
		&& (width == wmPtr->wrapperPtr->changes.width)
		&& (height == wmPtr->wrapperPtr->changes.height)) {
	    /*
	     * The window already has the correct geometry, so don't bother to
	     * configure it; the X server appears to ignore these requests, so
	     * we won't get back a ConfigureNotify and the
	     * WaitForConfigureNotify call below will hang for a while.
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833

static void
UpdateSizeHints(
    TkWindow *winPtr,
    int newWidth,
    int newHeight)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    XSizeHints *hintsPtr;
    int maxWidth, maxHeight;

    wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS;

    hintsPtr = XAllocSizeHints();
    if (hintsPtr == NULL) {







|







4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737

static void
UpdateSizeHints(
    TkWindow *winPtr,
    int newWidth,
    int newHeight)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    XSizeHints *hintsPtr;
    int maxWidth, maxHeight;

    wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS;

    hintsPtr = XAllocSizeHints();
    if (hintsPtr == NULL) {
4933
4934
4935
4936
4937
4938
4939


4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952

4953
4954


4955
4956
4957
4958
4959
4960
4961

    string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
    Tcl_UtfToExternalDString(NULL, string, -1, &ds);
    XStoreName(winPtr->display, wmPtr->wrapperPtr->window,
	    Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);



    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_NAME", XA_UTF8_STRING, 8,
	    string, strlen(string));

    /*
     * Set icon name:
     */

    if (wmPtr->iconName != NULL) {
	Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
	XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
		Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);


	SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_ICON_NAME",
		XA_UTF8_STRING, 8, wmPtr->iconName, strlen(wmPtr->iconName));


    }
}

/*
 *--------------------------------------------------------------
 *
 * UpdatePhotoIcon --







>
>
|
|











>
|
|
>
>







4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870

    string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
    Tcl_UtfToExternalDString(NULL, string, -1, &ds);
    XStoreName(winPtr->display, wmPtr->wrapperPtr->window,
	    Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);

    XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
	    Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_NAME"),
	    XA_UTF8_STRING, 8, PropModeReplace,
	    (const unsigned char *) string, (signed int) strlen(string));

    /*
     * Set icon name:
     */

    if (wmPtr->iconName != NULL) {
	Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
	XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
		Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);

	XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
		Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_ICON_NAME"),
		XA_UTF8_STRING, 8, PropModeReplace,
		(const unsigned char *) wmPtr->iconName,
		(signed int) strlen(wmPtr->iconName));
    }
}

/*
 *--------------------------------------------------------------
 *
 * UpdatePhotoIcon --
4978
4979
4980
4981
4982
4983
4984



4985



4986
4987
4988
4989
4990
4991
4992
4993
    int size = wmPtr->iconDataSize;

    if (data == NULL) {
	data = winPtr->dispPtr->iconDataPtr;
	size = winPtr->dispPtr->iconDataSize;
    }
    if (data != NULL) {



	SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_ICON", XA_CARDINAL, 32,



		data, size);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SetNetWmState --







>
>
>
|
>
>
>
|







4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
    int size = wmPtr->iconDataSize;

    if (data == NULL) {
	data = winPtr->dispPtr->iconDataPtr;
	size = winPtr->dispPtr->iconDataSize;
    }
    if (data != NULL) {
	/*
	 * Set icon:
	 */

	XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
		Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_ICON"),
		XA_CARDINAL, 32, PropModeReplace,
		(unsigned char *) data, size);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SetNetWmState --
5120
5121
5122
5123
5124
5125
5126

5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_VERT");
	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_HORZ");
    }
    if (wmPtr->reqState.fullscreen) {
	atoms[numAtoms++] = Tk_InternAtom(tkwin, "_NET_WM_STATE_FULLSCREEN");
    }


    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_STATE", XA_ATOM, 32, atoms,
	    numAtoms);
}

/*
 *----------------------------------------------------------------------
 *
 * WaitForConfigureNotify --
 *
 *	This function is invoked in order to synchronize with the window
 *	manager. It waits for a ConfigureNotify event to arrive, signalling







>
|
|

|







5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_VERT");
	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_HORZ");
    }
    if (wmPtr->reqState.fullscreen) {
	atoms[numAtoms++] = Tk_InternAtom(tkwin, "_NET_WM_STATE_FULLSCREEN");
    }

    XChangeProperty(Tk_Display(tkwin), wmPtr->wrapperPtr->window,
	    Tk_InternAtom(tkwin, "_NET_WM_STATE"), XA_ATOM, 32,
	    PropModeReplace, (unsigned char *) atoms, numAtoms);
}

/*
 *----------------------------------------------------------------------
 *
 * WaitForConfigureNotify --
 *
 *	This function is invoked in order to synchronize with the window
 *	manager. It waits for a ConfigureNotify event to arrive, signalling
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260

5261
5262
5263
5264
5265
5266
5267
5268
5269
5270

5271
5272
5273
5274
5275
5276
5277
WaitForEvent(
    Display *display,		/* Display event is coming from. */
    WmInfo *wmInfoPtr,		/* Window for which event is desired. */
    int type,			/* Type of event that is wanted. */
    XEvent *eventPtr)		/* Place to store event. */
{
    WaitRestrictInfo info;
    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    Tcl_Time timeout;

    /*
     * Set up an event filter to select just the events we want, and a timer
     * handler, then wait for events until we get the event we want or a
     * timeout happens.
     */

    info.display = display;
    info.wmInfoPtr = wmInfoPtr;
    info.type = type;
    info.eventPtr = eventPtr;
    info.foundEvent = 0;
    prevProc = Tk_RestrictEvents(WaitRestrictProc, &info, &prevArg);


    Tcl_GetTime(&timeout);
    timeout.sec += 2;

    while (!info.foundEvent) {
	if (!TkUnixDoOneXEvent(&timeout)) {
	    break;
	}
    }
    Tk_RestrictEvents(prevProc, prevArg, &prevArg);

    if (info.foundEvent) {
	return TCL_OK;
    }
    return TCL_ERROR;
}

/*







|
|













|
>









|
>







5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
WaitForEvent(
    Display *display,		/* Display event is coming from. */
    WmInfo *wmInfoPtr,		/* Window for which event is desired. */
    int type,			/* Type of event that is wanted. */
    XEvent *eventPtr)		/* Place to store event. */
{
    WaitRestrictInfo info;
    Tk_RestrictProc *oldRestrictProc;
    ClientData oldRestrictData;
    Tcl_Time timeout;

    /*
     * Set up an event filter to select just the events we want, and a timer
     * handler, then wait for events until we get the event we want or a
     * timeout happens.
     */

    info.display = display;
    info.wmInfoPtr = wmInfoPtr;
    info.type = type;
    info.eventPtr = eventPtr;
    info.foundEvent = 0;
    oldRestrictProc = Tk_RestrictEvents(WaitRestrictProc, (ClientData) &info,
	    &oldRestrictData);

    Tcl_GetTime(&timeout);
    timeout.sec += 2;

    while (!info.foundEvent) {
	if (!TkUnixDoOneXEvent(&timeout)) {
	    break;
	}
    }
    (void) Tk_RestrictEvents(oldRestrictProc, oldRestrictData,
	    &oldRestrictData);
    if (info.foundEvent) {
	return TCL_OK;
    }
    return TCL_ERROR;
}

/*
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
 */

static Tk_RestrictAction
WaitRestrictProc(
    ClientData clientData,	/* Pointer to WaitRestrictInfo structure. */
    XEvent *eventPtr)		/* Event that is about to be handled. */
{
    WaitRestrictInfo *infoPtr = (WaitRestrictInfo *)clientData;

    if (eventPtr->type == ReparentNotify) {
	return TK_PROCESS_EVENT;
    }
    if (((eventPtr->xany.window != infoPtr->wmInfoPtr->wrapperPtr->window)
	    && (eventPtr->xany.window != infoPtr->wmInfoPtr->reparent))
	    || (eventPtr->xany.display != infoPtr->display)) {







|







5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
 */

static Tk_RestrictAction
WaitRestrictProc(
    ClientData clientData,	/* Pointer to WaitRestrictInfo structure. */
    XEvent *eventPtr)		/* Event that is about to be handled. */
{
    WaitRestrictInfo *infoPtr = (WaitRestrictInfo *) clientData;

    if (eventPtr->type == ReparentNotify) {
	return TK_PROCESS_EVENT;
    }
    if (((eventPtr->xany.window != infoPtr->wmInfoPtr->wrapperPtr->window)
	    && (eventPtr->xany.window != infoPtr->wmInfoPtr->reparent))
	    || (eventPtr->xany.display != infoPtr->display)) {
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444

5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481

5482
5483

5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496

5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525

5526

5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
}

/*
 *----------------------------------------------------------------------
 *
 * SetNetWmType --
 *
 *	Set the extended window manager hints for a toplevel window to the
 *	types provided. The specification states that this may be a list of
 *	window types in preferred order. To permit for future type
 *	definitions, the set of names is unconstrained and names are converted
 *	to upper-case and appended to "_NET_WM_WINDOW_TYPE_" before being
 *	converted to an Atom.
 *
 *----------------------------------------------------------------------
 */

static int
SetNetWmType(
    TkWindow *winPtr,
    Tcl_Obj *typePtr)
{
    Atom *atoms = NULL;
    WmInfo *wmPtr;

    Tcl_Obj **objv;
    int objc, n;
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tcl_Interp *interp = Tk_Interp(tkwin);

    if (TCL_OK != Tcl_ListObjGetElements(interp, typePtr, &objc, &objv)) {
	return TCL_ERROR;
    }

    if (!Tk_HasWrapper(tkwin)) {
	return TCL_OK; /* error?? */
    }

    if (objc > 0) {
	atoms = (Atom *)ckalloc(sizeof(Atom) * objc);
    }

    for (n = 0; n < objc; ++n) {
	Tcl_DString ds, dsName;
	TkSizeT len;
	char *name = TkGetStringFromObj(objv[n], &len);

	Tcl_UtfToUpper(name);
	Tcl_UtfToExternalDString(NULL, name, len, &dsName);
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "_NET_WM_WINDOW_TYPE_", 20);
	Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsName),
		Tcl_DStringLength(&dsName));
	Tcl_DStringFree(&dsName);
	atoms[n] = Tk_InternAtom(tkwin, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
    }

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }


    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_WINDOW_TYPE", XA_ATOM, 32,

	    atoms, objc);

    ckfree(atoms);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetNetWmType --
 *
 *	Read the extended window manager type hint from a window and return as
 *	a list of names suitable for use with SetNetWmType.

 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetNetWmType(
    TkWindow *winPtr)
{
    Atom typeAtom, actualType, *atoms;
    int actualFormat;
    unsigned long n, count, bytesAfter;
    unsigned char *propertyValue = NULL;
    long maxLength = 1024;
    Tk_Window tkwin = (Tk_Window) winPtr;
    TkWindow *wrapperPtr;
    Tcl_Obj *typePtr;
    Tcl_Interp *interp;
    Tcl_DString ds;

    interp = Tk_Interp(tkwin);
    typePtr = Tcl_NewListObj(0, NULL);

    if (winPtr->wmInfoPtr->wrapperPtr == NULL) {
	CreateWrapper(winPtr->wmInfoPtr);
    }
    wrapperPtr = winPtr->wmInfoPtr->wrapperPtr;

    typeAtom = Tk_InternAtom(tkwin, "_NET_WM_WINDOW_TYPE");
    if (GetWindowProperty(wrapperPtr, typeAtom, maxLength, XA_ATOM,

	    &actualType, &actualFormat, &count, &bytesAfter, &propertyValue)){

	atoms = (Atom *) propertyValue;
	for (n = 0; n < count; ++n) {
	    const char *name = Tk_GetAtomName(tkwin, atoms[n]);

	    if (strncmp("_NET_WM_WINDOW_TYPE_", name, 20) == 0) {
		Tcl_ExternalToUtfDString(NULL, name+20, -1, &ds);
		Tcl_UtfToLower(Tcl_DStringValue(&ds));
		Tcl_ListObjAppendElement(interp, typePtr,
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		Tcl_DStringFree(&ds);







|
|
|
|
|
|





|
<
<

|

>


|
















|
|
<















>

|
>
|

|








|
|
>





|
<






|














|
>
|
>
|


<







5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357


5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382

5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421

5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449

5450
5451
5452
5453
5454
5455
5456
}

/*
 *----------------------------------------------------------------------
 *
 * SetNetWmType --
 *
 *	Set the extended window manager hints for a toplevel window
 *	to the types provided. The specification states that this
 *	may be a list of window types in preferred order. To permit
 *	for future type definitions, the set of names is unconstrained
 *	and names are converted to upper-case and appended to
 *	"_NET_WM_WINDOW_TYPE_" before being converted to an Atom.
 *
 *----------------------------------------------------------------------
 */

static int
SetNetWmType(TkWindow *winPtr, Tcl_Obj *typePtr)


{
    Atom typeAtom, *atoms = NULL;
    WmInfo *wmPtr;
    TkWindow *wrapperPtr;
    Tcl_Obj **objv;
    int objc, n;
    Tk_Window tkwin = (Tk_Window)winPtr;
    Tcl_Interp *interp = Tk_Interp(tkwin);

    if (TCL_OK != Tcl_ListObjGetElements(interp, typePtr, &objc, &objv)) {
	return TCL_ERROR;
    }

    if (!Tk_HasWrapper(tkwin)) {
	return TCL_OK; /* error?? */
    }

    if (objc > 0) {
	atoms = (Atom *)ckalloc(sizeof(Atom) * objc);
    }

    for (n = 0; n < objc; ++n) {
	Tcl_DString ds, dsName;
	int len;
	char *name = Tcl_GetStringFromObj(objv[n], &len);

	Tcl_UtfToUpper(name);
	Tcl_UtfToExternalDString(NULL, name, len, &dsName);
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "_NET_WM_WINDOW_TYPE_", 20);
	Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsName),
		Tcl_DStringLength(&dsName));
	Tcl_DStringFree(&dsName);
	atoms[n] = Tk_InternAtom(tkwin, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
    }

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    wrapperPtr = wmPtr->wrapperPtr;

    typeAtom = Tk_InternAtom(tkwin, "_NET_WM_WINDOW_TYPE");
    XChangeProperty(Tk_Display(tkwin), wrapperPtr->window, typeAtom,
	XA_ATOM, 32, PropModeReplace, (unsigned char *) atoms, objc);

    ckfree((char *)atoms);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetNetWmType --
 *
 *	Read the extended window manager type hint from a window
 *	and return as a list of names suitable for use with
 *	SetNetWmType.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetNetWmType(TkWindow *winPtr)

{
    Atom typeAtom, actualType, *atoms;
    int actualFormat;
    unsigned long n, count, bytesAfter;
    unsigned char *propertyValue = NULL;
    long maxLength = 1024;
    Tk_Window tkwin = (Tk_Window)winPtr;
    TkWindow *wrapperPtr;
    Tcl_Obj *typePtr;
    Tcl_Interp *interp;
    Tcl_DString ds;

    interp = Tk_Interp(tkwin);
    typePtr = Tcl_NewListObj(0, NULL);

    if (winPtr->wmInfoPtr->wrapperPtr == NULL) {
	CreateWrapper(winPtr->wmInfoPtr);
    }
    wrapperPtr = winPtr->wmInfoPtr->wrapperPtr;

    typeAtom = Tk_InternAtom(tkwin, "_NET_WM_WINDOW_TYPE");
    if (Success == XGetWindowProperty(wrapperPtr->display,
	    wrapperPtr->window, typeAtom, 0L, maxLength, False,
	    XA_ATOM, &actualType, &actualFormat, &count,
	    &bytesAfter, &propertyValue)) {
	atoms = (Atom *)propertyValue;
	for (n = 0; n < count; ++n) {
	    const char *name = Tk_GetAtomName(tkwin, atoms[n]);

	    if (strncmp("_NET_WM_WINDOW_TYPE_", name, 20) == 0) {
		Tcl_ExternalToUtfDString(NULL, name+20, -1, &ds);
		Tcl_UtfToLower(Tcl_DStringValue(&ds));
		Tcl_ListObjAppendElement(interp, typePtr,
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		Tcl_DStringFree(&ds);
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
 *
 *--------------------------------------------------------------
 */

static int
ParseGeometry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    const char *string,		/* String containing new geometry. Has the
				 * standard form "=wxh+x+y". */
    TkWindow *winPtr)		/* Pointer to top-level window whose geometry
				 * is to be changed. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, flags;
    char *end;
    const char *p = string;

    /*
     * The leading "=" is optional.
     */

    if (*p == '=') {
	p++;







|




|


|







5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
 *
 *--------------------------------------------------------------
 */

static int
ParseGeometry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    char *string,		/* String containing new geometry. Has the
				 * standard form "=wxh+x+y". */
    TkWindow *winPtr)		/* Pointer to top-level window whose geometry
				 * is to be changed. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, flags;
    char *end;
    register char *p = string;

    /*
     * The leading "=" is optional.
     */

    if (*p == '=') {
	p++;
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	    wmPtr->sizeHintsFlags |= USPosition;
	    flags |= WM_UPDATE_SIZE_HINTS;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.
     */

    wmPtr->width = width;
    wmPtr->height = height;
    wmPtr->x = x;
    wmPtr->y = y;
    flags |= WM_MOVE_PENDING;
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad geometry specifier \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "GEOMETRY", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --







|



















|





<
|
<







5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592

5593

5594
5595
5596
5597
5598
5599
5600
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	    wmPtr->sizeHintsFlags |= USPosition;
	    flags |= WM_UPDATE_SIZE_HINTS;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.
     */

    wmPtr->width = width;
    wmPtr->height = height;
    wmPtr->x = x;
    wmPtr->y = y;
    flags |= WM_MOVE_PENDING;
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:

    Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    int x, y;
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * Search back through this window's parents all the way to a top-level
     * window, combining the offsets of each window within its parent.
     */

    x = y = 0;







|







5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    int x, y;
    register TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * Search back through this window's parents all the way to a top-level
     * window, combining the offsets of each window within its parent.
     */

    x = y = 0;
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int PointInWindow(
    int x,
    int y,
    WmInfo *wmPtr)
{
    XWindowChanges changes = wmPtr->winPtr->changes;
    return (x >= changes.x &&
            x < changes.x + changes.width &&
            y >= changes.y - wmPtr->menuHeight &&
            y < changes.y + changes.height);
}

Tk_Window
Tk_CoordsToWindow(
    int rootX, int rootY,	/* Coordinates of point in root window. If a
				 * virtual-root window manager is in use,
				 * these coordinates refer to the virtual
				 * root, not the real root. */
    Tk_Window tkwin)		/* Token for any window in application; used







<
<
<
<
<
<
<
<
<
<
<
<







5705
5706
5707
5708
5709
5710
5711












5712
5713
5714
5715
5716
5717
5718
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */













Tk_Window
Tk_CoordsToWindow(
    int rootX, int rootY,	/* Coordinates of point in root window. If a
				 * virtual-root window manager is in use,
				 * these coordinates refer to the virtual
				 * root, not the real root. */
    Tk_Window tkwin)		/* Token for any window in application; used
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
	}
	if (child == None) {
	    Tk_DeleteErrorHandler(handler);
	    return NULL;
	}
	for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL;
		wmPtr = wmPtr->nextPtr) {
            if (wmPtr->winPtr->mainPtr == NULL) {
                continue;
            }
	    if (child == wmPtr->reparent) {
                if (PointInWindow(x, y, wmPtr)) {
                    goto gotToplevel;
                } else {

                    /*
                     * Return NULL if the point is in the title bar or border.
                     */

                    return NULL;
                }
	    }
	    if (wmPtr->wrapperPtr != NULL) {
		if (child == wmPtr->wrapperPtr->window) {
		    goto gotToplevel;
		} else if (wmPtr->winPtr->flags & TK_EMBEDDED &&
                           TkpGetOtherWindow(wmPtr->winPtr) == NULL) {

                    /*
                     * This toplevel is embedded in a window belonging to
                     * a different application.
                     */

                    int rx, ry;
                    Tk_GetRootCoords((Tk_Window) wmPtr->winPtr, &rx, &ry);
                    childX -= rx;
                    childY -= ry;
                    goto gotToplevel;
                }
	    } else if (child == wmPtr->winPtr->window) {
		goto gotToplevel;
	    }
	}
	x = childX;
	y = childY;
	parent = window;







<
<
<
|
<
|
<
<
<
<
<
<
<
<




<
<
|
<
<
<
<
<
<
<
<
<
<
<







5775
5776
5777
5778
5779
5780
5781



5782

5783








5784
5785
5786
5787


5788











5789
5790
5791
5792
5793
5794
5795
	}
	if (child == None) {
	    Tk_DeleteErrorHandler(handler);
	    return NULL;
	}
	for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL;
		wmPtr = wmPtr->nextPtr) {



	    if (wmPtr->reparent == child) {

		goto gotToplevel;








	    }
	    if (wmPtr->wrapperPtr != NULL) {
		if (child == wmPtr->wrapperPtr->window) {
		    goto gotToplevel;


		}











	    } else if (child == wmPtr->winPtr->window) {
		goto gotToplevel;
	    }
	}
	x = childX;
	y = childY;
	parent = window;
5923
5924
5925
5926
5927
5928
5929



5930
5931
5932
5933
5934
5935
5936
	 * or below
	 */

	Tk_DeleteErrorHandler(handler);
	handler = NULL;
    }
    winPtr = wmPtr->winPtr;




    /*
     * Step 3: at this point winPtr and wmPtr refer to the toplevel that
     * contains the given coordinates, and childX and childY give the
     * translated coordinates in the *parent* of the toplevel. Now decide
     * whether the coordinates are in the menubar or the actual toplevel, and
     * translate the coordinates into the coordinate system of that window.







>
>
>







5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
	 * or below
	 */

	Tk_DeleteErrorHandler(handler);
	handler = NULL;
    }
    winPtr = wmPtr->winPtr;
    if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
	return NULL;
    }

    /*
     * Step 3: at this point winPtr and wmPtr refer to the toplevel that
     * contains the given coordinates, and childX and childY give the
     * translated coordinates in the *parent* of the toplevel. Now decide
     * whether the coordinates are in the menubar or the actual toplevel, and
     * translate the coordinates into the coordinate system of that window.
5979
5980
5981
5982
5983
5984
5985

5986
5987
5988
5989
5990
5991
5992
5993
5994
5995

5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
		    && (tmpy < (childPtr->changes.height + bd))) {
		nextPtr = childPtr;
	    }
	}
	if (nextPtr == NULL) {
	    break;
	}

	x -= nextPtr->changes.x;
	y -= nextPtr->changes.y;
	if ((nextPtr->flags & TK_CONTAINER)
		&& (nextPtr->flags & TK_BOTH_HALVES)) {
	    /*
	     * The window containing the point is a container, and the
	     * embedded application is in this same process. Switch over to
	     * the toplevel for the embedded application and start processing
	     * that toplevel from scratch.
	     */

	    winPtr = TkpGetOtherWindow(nextPtr);
	    if (winPtr == NULL) {
		return (Tk_Window) nextPtr;
	    }
	    wmPtr = winPtr->wmInfoPtr;
	    childX = x;
	    childY = y;
	    goto gotToplevel;
	} else {
            winPtr = nextPtr;
        }
    }
    if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
        return NULL;
    }
    return (Tk_Window) winPtr;
}

/*
 *----------------------------------------------------------------------
 *







>
|
|
|
|






>
|

|





<
<
|
<
<
<







5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888


5889



5890
5891
5892
5893
5894
5895
5896
		    && (tmpy < (childPtr->changes.height + bd))) {
		nextPtr = childPtr;
	    }
	}
	if (nextPtr == NULL) {
	    break;
	}
	winPtr = nextPtr;
	x -= winPtr->changes.x;
	y -= winPtr->changes.y;
	if ((winPtr->flags & TK_CONTAINER)
		&& (winPtr->flags & TK_BOTH_HALVES)) {
	    /*
	     * The window containing the point is a container, and the
	     * embedded application is in this same process. Switch over to
	     * the toplevel for the embedded application and start processing
	     * that toplevel from scratch.
	     */

	    winPtr = TkpGetOtherWindow(winPtr);
	    if (winPtr == NULL) {
		return NULL;
	    }
	    wmPtr = winPtr->wmInfoPtr;
	    childX = x;
	    childY = y;
	    goto gotToplevel;


	}



    }
    return (Tk_Window) winPtr;
}

/*
 *----------------------------------------------------------------------
 *
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
static void
UpdateVRootGeometry(
    WmInfo *wmPtr)		/* Window manager information to be updated.
				 * The wmPtr->vRoot field must be valid. */
{
    TkWindow *winPtr = wmPtr->winPtr;
    int bd;
    unsigned dummy;
    Window dummy2;
    Status status;
    Tk_ErrorHandler handler;

    /*
     * If this isn't a virtual-root window manager, just return information
     * about the screen.







|







5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
static void
UpdateVRootGeometry(
    WmInfo *wmPtr)		/* Window manager information to be updated.
				 * The wmPtr->vRoot field must be valid. */
{
    TkWindow *winPtr = wmPtr->winPtr;
    int bd;
    unsigned int dummy;
    Window dummy2;
    Status status;
    Tk_ErrorHandler handler;

    /*
     * If this isn't a virtual-root window manager, just return information
     * about the screen.
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
    /*
     * Refresh the virtual root information if it's out of date.
     */

    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, NULL, NULL);
    status = XGetGeometry(winPtr->display, wmPtr->vRoot,
	    &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
	    (unsigned *) &wmPtr->vRootWidth,
	    (unsigned *) &wmPtr->vRootHeight, (unsigned *) &bd,
	    &dummy);
    if (winPtr->dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ",
		wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth);
	printf("height = %d, status = %d\n", wmPtr->vRootHeight, status);
    }
    Tk_DeleteErrorHandler(handler);







|
|







5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
    /*
     * Refresh the virtual root information if it's out of date.
     */

    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, NULL, NULL);
    status = XGetGeometry(winPtr->display, wmPtr->vRoot,
	    &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
	    (unsigned int *) &wmPtr->vRootWidth,
	    (unsigned int *) &wmPtr->vRootHeight, (unsigned int *) &bd,
	    &dummy);
    if (winPtr->dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ",
		wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth);
	printf("height = %d, status = %d\n", wmPtr->vRootHeight, status);
    }
    Tk_DeleteErrorHandler(handler);
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;
    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
    if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	wmPtr->sizeHintsFlags |= USPosition;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server
     * that would overwrite wmPtr->x and wmPtr->y and lose the new position.
     */

    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
	}
	UpdateGeometryInfo(winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateWmProtocols --







|








|












|

|







6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;
    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
    if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	wmPtr->sizeHintsFlags |= USPosition;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server
     * that would overwrite wmPtr->x and wmPtr->y and lose the new position.
     */

    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
	}
	UpdateGeometryInfo((ClientData) winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateWmProtocols --
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255


6256
6257
6258
6259
6260
6261
6262
6263
6264
 *	The WM_PROTOCOLS property gets changed for wmPtr's window.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateWmProtocols(
    WmInfo *wmPtr)	/* Information about top-level window. */
{
    ProtocolHandler *protPtr;
    Atom deleteWindowAtom, pingAtom;
    int count;
    Atom *arrayPtr, *atomPtr;

    /*
     * There are only two tricky parts here. First, there could be any number
     * of atoms for the window, so count them and malloc an array to hold all
     * of their atoms. Second, we *always* want to respond to the
     * WM_DELETE_WINDOW and _NET_WM_PING protocols, even if no-one's
     * officially asked.
     */

    for (protPtr = wmPtr->protPtr, count = 2; protPtr != NULL;
	    protPtr = protPtr->nextPtr, count++) {
	/* Empty loop body; we're just counting the handlers. */
    }
    arrayPtr = (Atom *)ckalloc(count * sizeof(Atom));
    deleteWindowAtom = Tk_InternAtom((Tk_Window) wmPtr->winPtr,
	    "WM_DELETE_WINDOW");
    pingAtom = Tk_InternAtom((Tk_Window) wmPtr->winPtr, "_NET_WM_PING");
    arrayPtr[0] = deleteWindowAtom;
    arrayPtr[1] = pingAtom;
    for (protPtr = wmPtr->protPtr, atomPtr = &arrayPtr[1];
	    protPtr != NULL; protPtr = protPtr->nextPtr) {
	if (protPtr->protocol != deleteWindowAtom
		&& protPtr->protocol != pingAtom) {
	    *(atomPtr++) = protPtr->protocol;
	}
    }
    SetWindowProperty(wmPtr->wrapperPtr, "WM_PROTOCOLS", XA_ATOM, 32,


	    arrayPtr, atomPtr-arrayPtr);
    ckfree(arrayPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmProtocolEventProc --
 *







|

|
















|












|
>
>
|
|







6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
 *	The WM_PROTOCOLS property gets changed for wmPtr's window.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateWmProtocols(
    register WmInfo *wmPtr)	/* Information about top-level window. */
{
    register ProtocolHandler *protPtr;
    Atom deleteWindowAtom, pingAtom;
    int count;
    Atom *arrayPtr, *atomPtr;

    /*
     * There are only two tricky parts here. First, there could be any number
     * of atoms for the window, so count them and malloc an array to hold all
     * of their atoms. Second, we *always* want to respond to the
     * WM_DELETE_WINDOW and _NET_WM_PING protocols, even if no-one's
     * officially asked.
     */

    for (protPtr = wmPtr->protPtr, count = 2; protPtr != NULL;
	    protPtr = protPtr->nextPtr, count++) {
	/* Empty loop body; we're just counting the handlers. */
    }
    arrayPtr = (Atom *) ckalloc((unsigned) count * sizeof(Atom));
    deleteWindowAtom = Tk_InternAtom((Tk_Window) wmPtr->winPtr,
	    "WM_DELETE_WINDOW");
    pingAtom = Tk_InternAtom((Tk_Window) wmPtr->winPtr, "_NET_WM_PING");
    arrayPtr[0] = deleteWindowAtom;
    arrayPtr[1] = pingAtom;
    for (protPtr = wmPtr->protPtr, atomPtr = &arrayPtr[1];
	    protPtr != NULL; protPtr = protPtr->nextPtr) {
	if (protPtr->protocol != deleteWindowAtom
		&& protPtr->protocol != pingAtom) {
	    *(atomPtr++) = protPtr->protocol;
	}
    }
    XChangeProperty(wmPtr->winPtr->display, wmPtr->wrapperPtr->window,
	    Tk_InternAtom((Tk_Window) wmPtr->winPtr, "WM_PROTOCOLS"),
	    XA_ATOM, 32, PropModeReplace, (unsigned char *) arrayPtr,
	    atomPtr-arrayPtr);
    ckfree((char *) arrayPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmProtocolEventProc --
 *
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294

void
TkWmProtocolEventProc(
    TkWindow *winPtr,		/* Window to which the event was sent. */
    XEvent *eventPtr)		/* X event. */
{
    WmInfo *wmPtr;
    ProtocolHandler *protPtr;
    Atom protocol;
    int result;
    const char *protocolName;
    Tcl_Interp *interp;

    protocol = (Atom) eventPtr->xclient.data.l[0];

    /*
     * If this is a _NET_WM_PING message, send it back to the root window
     * immediately. We do that here because scripts *cannot* respond correctly







|


|







6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176

void
TkWmProtocolEventProc(
    TkWindow *winPtr,		/* Window to which the event was sent. */
    XEvent *eventPtr)		/* X event. */
{
    WmInfo *wmPtr;
    register ProtocolHandler *protPtr;
    Atom protocol;
    int result;
    CONST char *protocolName;
    Tcl_Interp *interp;

    protocol = (Atom) eventPtr->xclient.data.l[0];

    /*
     * If this is a _NET_WM_PING message, send it back to the root window
     * immediately. We do that here because scripts *cannot* respond correctly
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328


6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
     * Tk_GetAtomName.
     */

    protocolName = Tk_GetAtomName((Tk_Window) winPtr, protocol);
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {


		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			protocolName));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
	    Tcl_Release(protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.







|

|


>
>
|
|
<
|

|
|







6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214

6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
     * Tk_GetAtomName.
     */

    protocolName = Tk_GetAtomName((Tk_Window) winPtr, protocol);
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve((ClientData) protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve((ClientData) interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(interp, "\n    (command for \"");
		Tcl_AddErrorInfo(interp, protocolName);
		Tcl_AddErrorInfo(interp,
			"\" window manager protocol)");

		Tcl_BackgroundError(interp);
	    }
	    Tcl_Release((ClientData) interp);
	    Tcl_Release((ClientData) protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483

TkWindow **
TkWmStackorderToplevel(
    TkWindow *parentPtr)	/* Parent toplevel window. */
{
    Window dummy1, dummy2, vRoot;
    Window *children;
    unsigned numChildren, i;
    TkWindow *childWinPtr, **windows, **window_ptr;
    Tcl_HashTable table;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    /*
     * Map X Window ids to a TkWindow of the wrapped toplevel.
     */

    Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
    TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);

    window_ptr = windows = (TkWindow **)ckalloc((table.numEntries+1) * sizeof(TkWindow *));
    if (windows == NULL) {
	return NULL;
    }

    /*
     * Special cases: If zero or one toplevels were mapped there is no need to
     * call XQueryTree.
     */

    switch (table.numEntries) {
    case 0:
	windows[0] = NULL;
	goto done;
    case 1:
	hPtr = Tcl_FirstHashEntry(&table, &search);
	windows[0] = (TkWindow *)Tcl_GetHashValue(hPtr);
	windows[1] = NULL;
	goto done;
    }

    vRoot = parentPtr->wmInfoPtr->vRoot;
    if (vRoot == None) {
	vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) parentPtr));
    }

    if (XQueryTree(parentPtr->display, vRoot, &dummy1, &dummy2,
	    &children, &numChildren) == 0) {
	ckfree(windows);
	windows = NULL;
    } else {
	for (i = 0; i < numChildren; i++) {
	    hPtr = Tcl_FindHashEntry(&table, children[i]);
	    if (hPtr != NULL) {
		childWinPtr = (TkWindow *)Tcl_GetHashValue(hPtr);
		*window_ptr++ = childWinPtr;
	    }
	}

	/*
	 * ASSERT: window_ptr - windows == table.numEntries
	 * (#matched toplevel windows == #children) [Bug 1789819]
	 */

	*window_ptr = NULL;
	if (numChildren) {
	    XFree((char *) children);
	}
    }

  done:







|












|
|
<
<












|











|



|

|



<
<
|


<







6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317


6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351


6352
6353
6354

6355
6356
6357
6358
6359
6360
6361

TkWindow **
TkWmStackorderToplevel(
    TkWindow *parentPtr)	/* Parent toplevel window. */
{
    Window dummy1, dummy2, vRoot;
    Window *children;
    unsigned int numChildren, i;
    TkWindow *childWinPtr, **windows, **window_ptr;
    Tcl_HashTable table;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;

    /*
     * Map X Window ids to a TkWindow of the wrapped toplevel.
     */

    Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
    TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);

    window_ptr = windows = (TkWindow **)
	    ckalloc((table.numEntries+1) * sizeof(TkWindow *));



    /*
     * Special cases: If zero or one toplevels were mapped there is no need to
     * call XQueryTree.
     */

    switch (table.numEntries) {
    case 0:
	windows[0] = NULL;
	goto done;
    case 1:
	hPtr = Tcl_FirstHashEntry(&table, &search);
	windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
	windows[1] = NULL;
	goto done;
    }

    vRoot = parentPtr->wmInfoPtr->vRoot;
    if (vRoot == None) {
	vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) parentPtr));
    }

    if (XQueryTree(parentPtr->display, vRoot, &dummy1, &dummy2,
	    &children, &numChildren) == 0) {
	ckfree((char *) windows);
	windows = NULL;
    } else {
	for (i = 0; i < numChildren; i++) {
	    hPtr = Tcl_FindHashEntry(&table, (char *) children[i]);
	    if (hPtr != NULL) {
		childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
		*window_ptr++ = childWinPtr;
	    }
	}


	/* ASSERT: window_ptr - windows == table.numEntries
	 * (#matched toplevel windows == #children) [Bug 1789819]
	 */

	*window_ptr = NULL;
	if (numChildren) {
	    XFree((char *) children);
	}
    }

  done:
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
    int aboveBelow,		/* Gives relative position for restacking;
				 * must be Above or Below. */
    TkWindow *otherPtr)		/* Window relative to which to restack; if
				 * NULL, then winPtr gets restacked above or
				 * below *all* siblings. */
{
    XWindowChanges changes;
    unsigned mask;
    TkWindow *wrapperPtr;

    memset(&changes, 0, sizeof(XWindowChanges));
    changes.stack_mode = aboveBelow;
    mask = CWStackMode;

    /*







|







6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
    int aboveBelow,		/* Gives relative position for restacking;
				 * must be Above or Below. */
    TkWindow *otherPtr)		/* Window relative to which to restack; if
				 * NULL, then winPtr gets restacked above or
				 * below *all* siblings. */
{
    XWindowChanges changes;
    unsigned int mask;
    TkWindow *wrapperPtr;

    memset(&changes, 0, sizeof(XWindowChanges));
    changes.stack_mode = aboveBelow;
    mask = CWStackMode;

    /*
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
    }

    /*
     * Make a new bigger array and use it to reset the property. Automatically
     * add the toplevel itself as the last element of the list.
     */

    newPtr = (Window *)ckalloc((count+2) * sizeof(Window));
    for (i = 0; i < count; i++) {
	newPtr[i] = oldPtr[i];
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr->window;
    newPtr[count] = topPtr->window;
    XSetWMColormapWindows(topPtr->display, wrapperPtr->window, newPtr,
	    count+1);
    ckfree(newPtr);
    if (oldPtr != NULL) {
	XFree((char *) oldPtr);
    }
}

/*
 *----------------------------------------------------------------------







|










|







6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
    }

    /*
     * Make a new bigger array and use it to reset the property. Automatically
     * add the toplevel itself as the last element of the list.
     */

    newPtr = (Window *) ckalloc((unsigned) (count+2) * sizeof(Window));
    for (i = 0; i < count; i++) {
	newPtr[i] = oldPtr[i];
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr->window;
    newPtr[count] = topPtr->window;
    XSetWMColormapWindows(topPtr->display, wrapperPtr->window, newPtr,
	    count+1);
    ckfree((char *) newPtr);
    if (oldPtr != NULL) {
	XFree((char *) oldPtr);
    }
}

/*
 *----------------------------------------------------------------------
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
				 * which lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;
    Window w, root, child;
    int rootX, rootY;
    unsigned mask;

    wmPtr = winPtr->wmInfoPtr;

    w = wmPtr->vRoot;
    if (w == None) {
	w = RootWindow(winPtr->display, winPtr->screenNum);
    }







|







6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
				 * which lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;
    Window w, root, child;
    int rootX, rootY;
    unsigned int mask;

    wmPtr = winPtr->wmInfoPtr;

    w = wmPtr->vRoot;
    if (w == None) {
	w = RootWindow(winPtr->display, winPtr->screenNum);
    }
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
 *
 *----------------------------------------------------------------------
 */

static void
TkSetTransientFor(Tk_Window tkwin, Tk_Window parent)
{
    if (parent == NULL) {
	parent = Tk_Parent(tkwin);
	while (!Tk_IsTopLevel(parent))
	    parent = Tk_Parent(parent);
    }
    /*
     * Prevent crash due to incomplete initialization, or other problems.
     * [Bugs 3554026, 3561016]







|







6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
 *
 *----------------------------------------------------------------------
 */

static void
TkSetTransientFor(Tk_Window tkwin, Tk_Window parent)
{
    if (parent == None) {
	parent = Tk_Parent(tkwin);
	while (!Tk_IsTopLevel(parent))
	    parent = Tk_Parent(parent);
    }
    /*
     * Prevent crash due to incomplete initialization, or other problems.
     * [Bugs 3554026, 3561016]
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934




6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --
 *
 *	Configure the window to be either a pull-down menu, a pop-up menu, or
 *	as a toplevel (torn-off) menu or palette.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the style bit used to create a new Mac toplevel.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeMenuWindow(
    Tk_Window tkwin,		/* New window. */
    int typeFlag)		/* TK_MAKE_MENU_DROPDOWN means menu is only
				 * posted briefly as a pulldown or cascade,
				 * TK_MAKE_MENU_POPUP means it is a popup.
				 * TK_MAKE_MENU_TEAROFF means menu is always
				 * visible, e.g. as a torn-off menu.
				 * Determines whether save_under and
				 * override_redirect should be set, plus how
				 * to flag it for the window manager. */
{
    WmInfo *wmPtr;
    XSetWindowAttributes atts;
    TkWindow *wrapperPtr;
    Tcl_Obj *typeObj;

    if (!Tk_HasWrapper(tkwin)) {
	return;
    }
    wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    wrapperPtr = wmPtr->wrapperPtr;
    if (typeFlag == TK_MAKE_MENU_TEAROFF) {




	atts.override_redirect = False;
	atts.save_under = False;
	typeObj = Tcl_NewStringObj("menu", -1);
	TkSetTransientFor(tkwin, NULL);
    } else {
	atts.override_redirect = True;
	atts.save_under = True;
	if (typeFlag == TK_MAKE_MENU_DROPDOWN) {
	    typeObj = Tcl_NewStringObj("dropdown_menu", -1);
	} else {
	    typeObj = Tcl_NewStringObj("popup_menu", -1);
	}
    }
    SetNetWmType((TkWindow *)tkwin, typeObj);

    /*
     * The override-redirect and save-under bits must be set on the wrapper
     * window in order to have the desired effect. However, also set the
     * override-redirect bit on the window itself, so that the "wm







|
|













|
|
<
<
|

|
<














|
>
>
>
>



|
<
<
<
<
<
<
<
<







6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791


6792
6793
6794

6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817








6818
6819
6820
6821
6822
6823
6824
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --
 *
 *	Configure the window to be either a pull-down (or pop-up) menu, or as
 *	a toplevel (torn-off) menu or palette.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the style bit used to create a new Mac toplevel.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeMenuWindow(
    Tk_Window tkwin,		/* New window. */
    int transient)		/* 1 means menu is only posted briefly as a
				 * popup or pulldown or cascade. 0 means menu


				 * is always visible, e.g. as a torn-off menu.
				 * Determines whether save_under and
				 * override_redirect should be set. */

{
    WmInfo *wmPtr;
    XSetWindowAttributes atts;
    TkWindow *wrapperPtr;
    Tcl_Obj *typeObj;

    if (!Tk_HasWrapper(tkwin)) {
	return;
    }
    wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    wrapperPtr = wmPtr->wrapperPtr;
    if (transient) {
	atts.override_redirect = True;
	atts.save_under = True;
	typeObj = Tcl_NewStringObj("dropdown_menu", -1);
    } else {
	atts.override_redirect = False;
	atts.save_under = False;
	typeObj = Tcl_NewStringObj("menu", -1);
	TkSetTransientFor(tkwin, None);








    }
    SetNetWmType((TkWindow *)tkwin, typeObj);

    /*
     * The override-redirect and save-under bits must be set on the wrapper
     * window in order to have the desired effect. However, also set the
     * override-redirect bit on the window itself, so that the "wm
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
CreateWrapper(
    WmInfo *wmPtr)		/* Window manager information for the
				 * window. */
{
    TkWindow *winPtr, *wrapperPtr;
    Window parent;
    Tcl_HashEntry *hPtr;
    int isNew;

    winPtr = wmPtr->winPtr;
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }

    /*







|







6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
CreateWrapper(
    WmInfo *wmPtr)		/* Window manager information for the
				 * window. */
{
    TkWindow *winPtr, *wrapperPtr;
    Window parent;
    Tcl_HashEntry *hPtr;
    int new;

    winPtr = wmPtr->winPtr;
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }

    /*
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
	    parent, wrapperPtr->changes.x, wrapperPtr->changes.y,
	    (unsigned) wrapperPtr->changes.width,
	    (unsigned) wrapperPtr->changes.height,
	    (unsigned) wrapperPtr->changes.border_width, wrapperPtr->depth,
	    InputOutput, wrapperPtr->visual,
	    wrapperPtr->dirtyAtts|CWOverrideRedirect, &wrapperPtr->atts);
    hPtr = Tcl_CreateHashEntry(&wrapperPtr->dispPtr->winTable,
	    (char *) wrapperPtr->window, &isNew);
    Tcl_SetHashValue(hPtr, wrapperPtr);
    wrapperPtr->mainPtr = winPtr->mainPtr;
    wrapperPtr->mainPtr->refCount++;
    wrapperPtr->dirtyAtts = 0;
    wrapperPtr->dirtyChanges = 0;
    wrapperPtr->wmInfoPtr = wmPtr;








|







6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
	    parent, wrapperPtr->changes.x, wrapperPtr->changes.y,
	    (unsigned) wrapperPtr->changes.width,
	    (unsigned) wrapperPtr->changes.height,
	    (unsigned) wrapperPtr->changes.border_width, wrapperPtr->depth,
	    InputOutput, wrapperPtr->visual,
	    wrapperPtr->dirtyAtts|CWOverrideRedirect, &wrapperPtr->atts);
    hPtr = Tcl_CreateHashEntry(&wrapperPtr->dispPtr->winTable,
	    (char *) wrapperPtr->window, &new);
    Tcl_SetHashValue(hPtr, wrapperPtr);
    wrapperPtr->mainPtr = winPtr->mainPtr;
    wrapperPtr->mainPtr->refCount++;
    wrapperPtr->dirtyAtts = 0;
    wrapperPtr->dirtyChanges = 0;
    wrapperPtr->wmInfoPtr = wmPtr;

7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
    /*
     * Tk must monitor structure events for wrapper windows in order to detect
     * changes made by window managers such as resizing, mapping, unmapping,
     * etc..
     */

    Tk_CreateEventHandler((Tk_Window) wmPtr->wrapperPtr,
	    WrapperEventMask, WrapperEventProc, wmPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmFocusToplevel --
 *







|







6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
    /*
     * Tk must monitor structure events for wrapper windows in order to detect
     * changes made by window managers such as resizing, mapping, unmapping,
     * etc..
     */

    Tk_CreateEventHandler((Tk_Window) wmPtr->wrapperPtr,
	    WrapperEventMask, WrapperEventProc, (ClientData) wmPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmFocusToplevel --
 *
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
				 * canceled and the menu height is reset to
				 * 0. */
{
    WmInfo *wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    Tk_Window parent;
    TkWindow *menubarPtr = (TkWindow *) menubar;

    /*
     * Could be a Frame (i.e. not a toplevel).
     */

    if (wmPtr == NULL) {
	return;
    }

    if (wmPtr->menubar != NULL) {
	/*
	 * There's already a menubar for this toplevel. If it isn't the same
	 * as the new menubar, unmap it so that it is out of the way, and
	 * reparent it back to its original parent.
	 */







<
|
<
<
|

<







6992
6993
6994
6995
6996
6997
6998

6999


7000
7001

7002
7003
7004
7005
7006
7007
7008
				 * canceled and the menu height is reset to
				 * 0. */
{
    WmInfo *wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    Tk_Window parent;
    TkWindow *menubarPtr = (TkWindow *) menubar;


    /* Could be a Frame (i.e. not a toplevel) */


    if (wmPtr == NULL)
	return;


    if (wmPtr->menubar != NULL) {
	/*
	 * There's already a menubar for this toplevel. If it isn't the same
	 * as the new menubar, unmap it so that it is out of the way, and
	 * reparent it back to its original parent.
	 */
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
	parent = Tk_Parent(wmPtr->menubar);
	if (parent != NULL) {
	    Tk_MakeWindowExist(parent);
	    XReparentWindow(Tk_Display(wmPtr->menubar),
		    Tk_WindowId(wmPtr->menubar), Tk_WindowId(parent), 0, 0);
	}
	Tk_DeleteEventHandler(wmPtr->menubar, StructureNotifyMask,
		MenubarDestroyProc, wmPtr->menubar);
	Tk_ManageGeometry(wmPtr->menubar, NULL, NULL);
    }

    wmPtr->menubar = menubar;
    if (menubar == NULL) {
	wmPtr->menuHeight = 0;
    } else {







|







7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
	parent = Tk_Parent(wmPtr->menubar);
	if (parent != NULL) {
	    Tk_MakeWindowExist(parent);
	    XReparentWindow(Tk_Display(wmPtr->menubar),
		    Tk_WindowId(wmPtr->menubar), Tk_WindowId(parent), 0, 0);
	}
	Tk_DeleteEventHandler(wmPtr->menubar, StructureNotifyMask,
		MenubarDestroyProc, (ClientData) wmPtr->menubar);
	Tk_ManageGeometry(wmPtr->menubar, NULL, NULL);
    }

    wmPtr->menubar = menubar;
    if (menubar == NULL) {
	wmPtr->menuHeight = 0;
    } else {
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
	    CreateWrapper(wmPtr);
	}
	XReparentWindow(Tk_Display(menubar), Tk_WindowId(menubar),
		wmPtr->wrapperPtr->window, 0, 0);
	menubarPtr->wmInfoPtr = wmPtr;
	Tk_MoveResizeWindow(menubar, 0, 0, Tk_Width(tkwin), wmPtr->menuHeight);
	Tk_MapWindow(menubar);
	Tk_CreateEventHandler(menubar, StructureNotifyMask,
		MenubarDestroyProc, menubar);
	Tk_ManageGeometry(menubar, &menubarMgrType, wmPtr);
	menubarPtr->flags |= TK_REPARENTED;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, tkwin);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|
|
|




|







7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
	    CreateWrapper(wmPtr);
	}
	XReparentWindow(Tk_Display(menubar), Tk_WindowId(menubar),
		wmPtr->wrapperPtr->window, 0, 0);
	menubarPtr->wmInfoPtr = wmPtr;
	Tk_MoveResizeWindow(menubar, 0, 0, Tk_Width(tkwin), wmPtr->menuHeight);
	Tk_MapWindow(menubar);
	Tk_CreateEventHandler(menubar, StructureNotifyMask, MenubarDestroyProc,
		(ClientData) menubar);
	Tk_ManageGeometry(menubar, &menubarMgrType, (ClientData) wmPtr);
	menubarPtr->flags |= TK_REPARENTED;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) tkwin);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
	return;
    }
    wmPtr = ((TkWindow *) clientData)->wmInfoPtr;
    wmPtr->menubar = NULL;
    wmPtr->menuHeight = 0;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, wmPtr->winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
	return;
    }
    wmPtr = ((TkWindow *) clientData)->wmInfoPtr;
    wmPtr->menubar = NULL;
    wmPtr->menuHeight = 0;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) wmPtr->winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271

static void
MenubarReqProc(
    ClientData clientData,	/* Pointer to the window manager information
				 * for tkwin's toplevel. */
    Tk_Window tkwin)		/* Handle for menubar window. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;

    wmPtr->menuHeight = Tk_ReqHeight(tkwin);
    if (wmPtr->menuHeight <= 0) {
	wmPtr->menuHeight = 1;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, wmPtr->winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







|







7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138

static void
MenubarReqProc(
    ClientData clientData,	/* Pointer to the window manager information
				 * for tkwin's toplevel. */
    Tk_Window tkwin)		/* Handle for menubar window. */
{
    WmInfo *wmPtr = (WmInfo *) clientData;

    wmPtr->menuHeight = Tk_ReqHeight(tkwin);
    if (wmPtr->menuHeight <= 0) {
	wmPtr->menuHeight = 1;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) wmPtr->winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetWrapperWindow(
    TkWindow *winPtr)		/* A toplevel window pointer. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if ((winPtr == NULL) || (wmPtr == NULL)) {
	return NULL;
    }

    return wmPtr->wrapperPtr;
}







|







7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetWrapperWindow(
    TkWindow *winPtr)		/* A toplevel window pointer. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if ((winPtr == NULL) || (wmPtr == NULL)) {
	return NULL;
    }

    return wmPtr->wrapperPtr;
}
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
 *----------------------------------------------------------------------
 */

static void
UpdateCommand(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tcl_DString cmds, ds;
    int i, *offsets;
    char **cmdArgv;

    /*
     * Translate the argv strings into the external encoding. To avoid
     * allocating lots of memory, the strings are appended to a buffer with
     * nulls between each string.
     *
     * This code is tricky because we need to pass and array of pointers to
     * XSetCommand. However, we can't compute the pointers as we go because
     * the DString buffer space could get reallocated. So, store offsets for
     * each element as we go, then compute pointers from the offsets once the
     * entire DString is done.
     */

    cmdArgv = (char **)ckalloc(sizeof(char *) * wmPtr->cmdArgc);
    offsets = (int *)ckalloc(sizeof(int) * wmPtr->cmdArgc);
    Tcl_DStringInit(&cmds);
    for (i = 0; i < wmPtr->cmdArgc; i++) {
	Tcl_UtfToExternalDString(NULL, wmPtr->cmdArgv[i], -1, &ds);
	offsets[i] = Tcl_DStringLength(&cmds);
	Tcl_DStringAppend(&cmds, Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds)+1);
	Tcl_DStringFree(&ds);
    }
    cmdArgv[0] = Tcl_DStringValue(&cmds);
    for (i = 1; i < wmPtr->cmdArgc; i++) {
	cmdArgv[i] = cmdArgv[0] + offsets[i];
    }

    XSetCommand(winPtr->display, wmPtr->wrapperPtr->window,
	    cmdArgv, wmPtr->cmdArgc);
    Tcl_DStringFree(&cmds);
    ckfree(cmdArgv);
    ckfree(offsets);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWmSetState --
 *







|
















|
|
















|
|







7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
 *----------------------------------------------------------------------
 */

static void
UpdateCommand(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tcl_DString cmds, ds;
    int i, *offsets;
    char **cmdArgv;

    /*
     * Translate the argv strings into the external encoding. To avoid
     * allocating lots of memory, the strings are appended to a buffer with
     * nulls between each string.
     *
     * This code is tricky because we need to pass and array of pointers to
     * XSetCommand. However, we can't compute the pointers as we go because
     * the DString buffer space could get reallocated. So, store offsets for
     * each element as we go, then compute pointers from the offsets once the
     * entire DString is done.
     */

    cmdArgv = (char **) ckalloc(sizeof(char *) * wmPtr->cmdArgc);
    offsets = (int *) ckalloc(sizeof(int) * wmPtr->cmdArgc);
    Tcl_DStringInit(&cmds);
    for (i = 0; i < wmPtr->cmdArgc; i++) {
	Tcl_UtfToExternalDString(NULL, wmPtr->cmdArgv[i], -1, &ds);
	offsets[i] = Tcl_DStringLength(&cmds);
	Tcl_DStringAppend(&cmds, Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds)+1);
	Tcl_DStringFree(&ds);
    }
    cmdArgv[0] = Tcl_DStringValue(&cmds);
    for (i = 1; i < wmPtr->cmdArgc; i++) {
	cmdArgv[i] = cmdArgv[0] + offsets[i];
    }

    XSetCommand(winPtr->display, wmPtr->wrapperPtr->window,
	    cmdArgv, wmPtr->cmdArgc);
    Tcl_DStringFree(&cmds);
    ckfree((char *) cmdArgv);
    ckfree((char *) offsets);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWmSetState --
 *
7423
7424
7425
7426
7427
7428
7429
7430

7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
}

/*
 *----------------------------------------------------------------------
 *
 * RemapWindows
 *
 *	Adjust parent/child relationships of the given window hierarchy.

 *
 * Results:
 *	None
 *
 * Side effects:
 *	Keeps windowing system (X11) happy
 *
 *----------------------------------------------------------------------
 */

static void
RemapWindows(
    TkWindow *winPtr,
    TkWindow *parentPtr)
{
    XWindowAttributes win_attr;

    if (winPtr->window) {
	XGetWindowAttributes(winPtr->display, winPtr->window, &win_attr);
	if (parentPtr == NULL) {
	    XReparentWindow(winPtr->display, winPtr->window,
		    XRootWindow(winPtr->display, winPtr->screenNum),
		    win_attr.x, win_attr.y);
	} else if (parentPtr->window) {
	    XReparentWindow(parentPtr->display, winPtr->window,
		    parentPtr->window,
		    win_attr.x, win_attr.y);
	}
    }







|
>


|


|





|
|
|







|







7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
}

/*
 *----------------------------------------------------------------------
 *
 * RemapWindows
 *
 *	Adjust parent/child relation ships of
 *	the given window hierarchy.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	keeps windowing system (X11) happy
 *
 *----------------------------------------------------------------------
 */

static void
RemapWindows(winPtr, parentPtr)
     TkWindow *winPtr;
     TkWindow *parentPtr;
{
    XWindowAttributes win_attr;

    if (winPtr->window) {
	XGetWindowAttributes(winPtr->display, winPtr->window, &win_attr);
	if (parentPtr == NULL) {
	    XReparentWindow(winPtr->display, winPtr->window,
	            XRootWindow(winPtr->display, winPtr->screenNum),
		    win_attr.x, win_attr.y);
	} else if (parentPtr->window) {
	    XReparentWindow(parentPtr->display, winPtr->window,
		    parentPtr->window,
		    win_attr.x, win_attr.y);
	}
    }

Changes to unix/tkUnixXId.c.

1
2









3
4
5
6
7
8
9
10








11
12
























































































































































































































































































































































































































































13
14
15
16
17
18
19
/*
 * tkUnixXId.c --









 *
 * Copyright (c) 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.
 */









#include "tkUnixInt.h"


























































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * Tk_GetPixmap --
 *
 *	Same as the XCreatePixmap function except that it manages resource


>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
/*
 * tkUnixXId.c --
 *
 *	This file provides a replacement function for the default X resource
 *	allocator (_XAllocID). The problem with the default allocator is that
 *	it never re-uses ids, which causes long-lived applications to crash
 *	when X resource identifiers wrap around. The replacement functions in
 *	this file re-use old identifiers to prevent this problem.
 *
 *	The code in this file is based on similar implementations by
 *	George C. Kaplan and Michael Hoegeman.
 *
 * Copyright (c) 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.
 */

/*
 * The definition below is needed on some systems so that we can access the
 * resource_alloc field of Display structures in order to replace the resource
 * allocator.
 */

#define XLIB_ILLEGAL_ACCESS 1

#include "tkUnixInt.h"

/*
 * A structure of the following type is used to hold one or more available
 * resource identifiers. There is a list of these structures for each display.
 */

#define IDS_PER_STACK 10
typedef struct TkIdStack {
    XID ids[IDS_PER_STACK];	/* Array of free identifiers. */
    int numUsed;		/* Indicates how many of the entries in ids
				 * are currently in use. */
    TkDisplay *dispPtr;		/* Display to which ids belong. */
    struct TkIdStack *nextPtr;	/* Next bunch of free identifiers for the same
				 * display. */
} TkIdStack;

/*
 * Forward declarations for functions defined in this file:
 */

static XID		AllocXId(Display *display);
static Tk_RestrictAction CheckRestrictProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WindowIdCleanup(ClientData clientData);
static void		WindowIdCleanup2(ClientData clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkInitXId --
 *
 *	This function is called to initialize the id allocator for a given
 *	display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The official allocator for the display is set up to be AllocXId.
 *
 *----------------------------------------------------------------------
 */

void
TkInitXId(
    TkDisplay *dispPtr)		/* Tk's information about the display. */
{
    dispPtr->idStackPtr = NULL;
    dispPtr->defaultAllocProc = (XID (*) (Display *display))
	    dispPtr->display->resource_alloc;
    dispPtr->display->resource_alloc = AllocXId;
    dispPtr->windowStackPtr = NULL;
    dispPtr->idCleanupScheduled = (Tcl_TimerToken) 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeXId --
 *
 *	This function is called to free resources for the id allocator for a
 *	given display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the id and window stack pools.
 *
 *----------------------------------------------------------------------
 */

void
TkFreeXId(
    TkDisplay *dispPtr)		/* Tk's information about the display. */
{
    TkIdStack *stackPtr, *freePtr;

    if (dispPtr->idCleanupScheduled) {
	Tcl_DeleteTimerHandler(dispPtr->idCleanupScheduled);
    }

    for (stackPtr = dispPtr->idStackPtr; stackPtr != NULL; ) {
	freePtr = stackPtr;
	stackPtr = stackPtr->nextPtr;
	ckfree((char *) freePtr);
    }
    dispPtr->idStackPtr = NULL;

    for (stackPtr = dispPtr->windowStackPtr; stackPtr != NULL; ) {
	freePtr = stackPtr;
	stackPtr = stackPtr->nextPtr;
	ckfree((char *) freePtr);
    }
    dispPtr->windowStackPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * AllocXId --
 *
 *	This function is invoked by Xlib as the resource allocator for a
 *	display.
 *
 * Results:
 *	The return value is an X resource identifier that isn't currently in
 *	use.
 *
 * Side effects:
 *	The identifier is removed from the stack of free identifiers, if it
 *	was previously on the stack.
 *
 *----------------------------------------------------------------------
 */

static XID
AllocXId(
    Display *display)		/* Display for which to allocate. */
{
    TkDisplay *dispPtr;
    TkIdStack *stackPtr;

    /*
     * Find Tk's information about the display.
     */

    dispPtr = TkGetDisplay(display);

    /*
     * If the topmost chunk on the stack is empty then free it. Then check for
     * a free id on the stack and return it if it exists.
     */

    stackPtr = dispPtr->idStackPtr;
    if (stackPtr != NULL) {
	while (stackPtr->numUsed == 0) {
	    dispPtr->idStackPtr = stackPtr->nextPtr;
	    ckfree((char *) stackPtr);
	    stackPtr = dispPtr->idStackPtr;
	    if (stackPtr == NULL) {
		goto defAlloc;
	    }
	}
	stackPtr->numUsed--;
	return stackPtr->ids[stackPtr->numUsed];
    }

    /*
     * No free ids in the stack: just get one from the default allocator.
     */

  defAlloc:
    return (*dispPtr->defaultAllocProc)(display);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeXId --
 *
 *	This function is called to indicate that an X resource identifier is
 *	now free.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The identifier is added to the stack of free identifiers for its
 *	display, so that it can be re-used.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeXId(
    Display *display,		/* Display for which xid was allocated. */
    XID xid)			/* Identifier that is no longer in use. */
{
    TkDisplay *dispPtr;
    TkIdStack *stackPtr;

    /*
     * Find Tk's information about the display.
     */

    dispPtr = TkGetDisplay(display);

    /*
     * Add a new chunk to the stack if the current chunk is full.
     */

    stackPtr = dispPtr->idStackPtr;
    if ((stackPtr == NULL) || (stackPtr->numUsed >= IDS_PER_STACK)) {
	stackPtr = (TkIdStack *) ckalloc(sizeof(TkIdStack));
	stackPtr->numUsed = 0;
	stackPtr->dispPtr = dispPtr;
	stackPtr->nextPtr = dispPtr->idStackPtr;
	dispPtr->idStackPtr = stackPtr;
    }

    /*
     * Add the id to the current chunk.
     */

    stackPtr->ids[stackPtr->numUsed] = xid;
    stackPtr->numUsed++;
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeWindowId --
 *
 *	This function is invoked instead of TkFreeXId for window ids. See
 *	below for the reason why.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The id given by w will eventually be freed, so that it can be reused
 *	for other resources.
 *
 * Design:
 *	Freeing window ids is very tricky because there could still be events
 *	pending for a window in the event queue (or even in the server) at the
 *	time the window is destroyed. If the window id were to get reused
 *	immediately for another window, old events could "drop in" on the new
 *	window, causing unexpected behavior.
 *
 *	Thus we have to wait to re-use a window id until we know that there
 *	are no events left for it. Right now this is done in two steps. First,
 *	we wait until we know that the server has seen the XDestroyWindow
 *	request, so we can be sure that it won't generate more events for the
 *	window and that any existing events are in our queue. Second, we make
 *	sure that there are no events whatsoever in our queue (this is
 *	conservative but safe).
 *
 *	The first step is done by remembering the request id of the
 *	XDestroyWindow request and using LastKnownRequestProcessed to see what
 *	events the server has processed. If multiple windows get destroyed at
 *	about the same time, we just remember the most recent request number
 *	for any of them (again, conservative but safe).
 *
 *	There are a few other complications as well. When Tk destroys a
 *	sub-tree of windows, it only issues a single XDestroyWindow call, at
 *	the very end for the root of the subtree. We can't free any of the
 *	window ids until the final XDestroyWindow call. To make sure that this
 *	happens, we have to keep track of deletions in progress, hence the
 *	need for the "destroyCount" field of the display.
 *
 *	One final problem. Some servers, like Sun X11/News servers still seem
 *	to have problems with ids getting reused too quickly. I'm not
 *	completely sure why this is a problem, but delaying the recycling of
 *	ids appears to eliminate it. Therefore, we wait an additional few
 *	seconds, even after "the coast is clear" before reusing the ids.
 *
 *----------------------------------------------------------------------
 */

void
TkFreeWindowId(
    TkDisplay *dispPtr,		/* Display that w belongs to. */
    Window w)			/* X identifier for window on dispPtr. */
{
    TkIdStack *stackPtr;

    /*
     * Put the window id on a separate stack of window ids, rather than the
     * main stack, so it won't get reused right away. Add a new chunk to the
     * stack if the current chunk is full.
     */

    stackPtr = dispPtr->windowStackPtr;
    if ((stackPtr == NULL) || (stackPtr->numUsed >= IDS_PER_STACK)) {
	stackPtr = (TkIdStack *) ckalloc(sizeof(TkIdStack));
	stackPtr->numUsed = 0;
	stackPtr->dispPtr = dispPtr;
	stackPtr->nextPtr = dispPtr->windowStackPtr;
	dispPtr->windowStackPtr = stackPtr;
    }

    /*
     * Add the id to the current chunk.
     */

    stackPtr->ids[stackPtr->numUsed] = w;
    stackPtr->numUsed++;

    /*
     * Schedule a call to WindowIdCleanup if one isn't already scheduled.
     */

    if (!dispPtr->idCleanupScheduled) {
	dispPtr->idCleanupScheduled = Tcl_CreateTimerHandler(100,
		WindowIdCleanup, (ClientData) dispPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * WindowIdCleanup --
 *
 *	See if we can now free up all the accumulated ids of deleted windows.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If it's safe to move the window ids back to the main free list, we
 *	schedule this to happen after a few mores seconds of delay. If it's
 *	not safe to move them yet, a timer handler gets invoked to try again
 *	later.
 *
 *----------------------------------------------------------------------
 */

static void
WindowIdCleanup(
    ClientData clientData)	/* Pointer to TkDisplay for display */
{
    TkDisplay *dispPtr = (TkDisplay *) clientData;
    int anyEvents, delta;
    Tk_RestrictProc *oldProc;
    ClientData oldData;
    static Tcl_Time timeout = {0, 0};

    dispPtr->idCleanupScheduled = (Tcl_TimerToken) 0;

    /*
     * See if it's safe to recycle the window ids. It's safe if:
     * (a) no deletions are in progress.
     * (b) the server has seen all of the requests up to the last
     *     XDestroyWindow request.
     * (c) there are no events in the event queue; the only way to test for
     *     this right now is to create a restrict proc that will filter the
     *     events, then call Tcl_DoOneEvent to see if the function gets
     *     invoked.
     */

    if (dispPtr->destroyCount > 0) {
	goto tryAgain;
    }
    delta = LastKnownRequestProcessed(dispPtr->display)
	    - dispPtr->lastDestroyRequest;
    if (delta < 0) {
	XSync(dispPtr->display, False);
    }
    anyEvents = 0;
    oldProc = Tk_RestrictEvents(CheckRestrictProc, (ClientData) &anyEvents,
	    &oldData);
    TkUnixDoOneXEvent(&timeout);
    Tk_RestrictEvents(oldProc, oldData, &oldData);
    if (anyEvents) {
	goto tryAgain;
    }

    /*
     * These ids look safe to recycle, but we still need to delay a bit more
     * (see comments for TkFreeWindowId). Schedule the final freeing.
     */

    if (dispPtr->windowStackPtr != NULL) {
	Tcl_CreateTimerHandler(5000, WindowIdCleanup2,
		(ClientData) dispPtr->windowStackPtr);
	dispPtr->windowStackPtr = NULL;
    }
    return;

    /*
     * It's still not safe to free up the ids. Try again a bit later.
     */

  tryAgain:
    dispPtr->idCleanupScheduled = Tcl_CreateTimerHandler(500,
	    WindowIdCleanup, (ClientData) dispPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WindowIdCleanup2 --
 *
 *	This function is the last one in the chain that recycles window ids.
 *	It takes all of the ids indicated by its argument and adds them back
 *	to the main id free list.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Window ids get added to the main free list for their display.
 *
 *----------------------------------------------------------------------
 */

static void
WindowIdCleanup2(
    ClientData clientData)	/* Pointer to TkIdStack list. */
{
    TkIdStack *stackPtr = (TkIdStack *) clientData;
    TkIdStack *lastPtr;

    lastPtr = stackPtr;
    while (lastPtr->nextPtr != NULL) {
	lastPtr = lastPtr->nextPtr;
    }
    lastPtr->nextPtr = stackPtr->dispPtr->idStackPtr;
    stackPtr->dispPtr->idStackPtr = stackPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckRestrictProc --
 *
 *	This function is a restrict function, called by Tcl_DoOneEvent to
 *	filter X events. All it does is to set a flag to indicate that there
 *	are X events present.
 *
 * Results:
 *	Sets the integer pointed to by the argument, then returns
 *	TK_DEFER_EVENT.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
CheckRestrictProc(
    ClientData clientData,	/* Pointer to flag to set. */
    XEvent *eventPtr)		/* Event to filter; not used. */
{
    int *flag = (int *) clientData;
    *flag = 1;
    return TK_DEFER_EVENT;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetPixmap --
 *
 *	Same as the XCreatePixmap function except that it manages resource
59
60
61
62
63
64
65

66
67





































68
69
70
71
72
73
74

void
Tk_FreePixmap(
    Display *display,		/* Display for which pixmap was allocated. */
    Pixmap pixmap)		/* Identifier for pixmap. */
{
    XFreePixmap(display, pixmap);

}







































/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *
 *	Given a string, produce the corresponding Window Id.







>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569

void
Tk_FreePixmap(
    Display *display,		/* Display for which pixmap was allocated. */
    Pixmap pixmap)		/* Identifier for pixmap. */
{
    XFreePixmap(display, pixmap);
    Tk_FreeXId(display, (XID) pixmap);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWindowWasRecentlyDeleted --
 *
 *	Checks whether the window was recently deleted. This is called by the
 *	generic error handler to detect asynchronous notification of errors
 *	due to operations by Tk on a window that was already deleted by the
 *	server.
 *
 * Results:
 *	1 if the window was deleted recently, 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpWindowWasRecentlyDeleted(
    Window win,			/* The window to check for. */
    TkDisplay *dispPtr)		/* The window belongs to this display. */
{
    TkIdStack *stackPtr;
    int i;

    for (stackPtr = dispPtr->windowStackPtr; stackPtr != NULL;
	    stackPtr = stackPtr->nextPtr) {
	for (i = 0; i < stackPtr->numUsed; i++) {
	    if ((Window) stackPtr->ids[i] == win) {
		return 1;
	    }
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *
 *	Given a string, produce the corresponding Window Id.
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,
    const char *string,
    Window *idPtr)
{
    int code;
    Tcl_Obj obj;

    obj.refCount = 1;
    obj.bytes = (char *) string;	/* DANGER?! */







|







579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,
    CONST char *string,
    Window *idPtr)
{
    int code;
    Tcl_Obj obj;

    obj.refCount = 1;
    obj.bytes = (char *) string;	/* DANGER?! */

Changes to win/Makefile.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# This file is a Makefile for Tk.  If it has the name "Makefile.in" then it
# is a template for a Makefile; to generate the actual Makefile, run
# "./configure", which is a configuration script generated by the "autoconf"
# program (constructs like "@foo@" will get replaced in the actual Makefile.

TCLVERSION		= @TCL_VERSION@
TCLPATCHL		= @TCL_PATCH_LEVEL@
VERSION			= @TK_VERSION@
PATCH_LEVEL		= @TK_PATCH_LEVEL@

#--------------------------------------------------------------------------
# Things you can change to personalize the Makefile for your own site (you can
# make these changes in either Makefile.in or Makefile, but changes to
# Makefile will get lost if you re-run the configuration script).






<
<







1
2
3
4
5
6


7
8
9
10
11
12
13
#
# This file is a Makefile for Tk.  If it has the name "Makefile.in" then it
# is a template for a Makefile; to generate the actual Makefile, run
# "./configure", which is a configuration script generated by the "autoconf"
# program (constructs like "@foo@" will get replaced in the actual Makefile.



VERSION			= @TK_VERSION@
PATCH_LEVEL		= @TK_PATCH_LEVEL@

#--------------------------------------------------------------------------
# Things you can change to personalize the Makefile for your own site (you can
# make these changes in either Makefile.in or Makefile, but changes to
# Makefile will get lost if you re-run the configuration script).
66
67
68
69
70
71
72
73



74
75
76
77
78
79
80
81
82

# Directory in which to install manual entries for Tk's C library
# procedures:
MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3

# Directory in which to install manual entries for the built-in Tk commands:
MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann




# Directory in which to install the pkgIndex.tcl file for loadable Tk
PKG_INSTALL_DIR		= $(LIB_INSTALL_DIR)/tk$(VERSION)

# Package index file for loadable Tk
PKG_INDEX		= $(PKG_INSTALL_DIR)/pkgIndex.tcl

# The directory containing the Tcl source and header files.
TCL_SRC_DIR		= @TCL_SRC_DIR@









>
>
>

|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

# Directory in which to install manual entries for Tk's C library
# procedures:
MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3

# Directory in which to install manual entries for the built-in Tk commands:
MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann

# Libraries built with optimization switches have this additional extension
TK_DBGX = @TK_DBGX@

# Directory in which to install the pkgIndex.tcl file for loadable Tk
PKG_INSTALL_DIR		= $(LIB_INSTALL_DIR)/tk$(VERSION)$(TK_DBGX)

# Package index file for loadable Tk
PKG_INDEX		= $(PKG_INSTALL_DIR)/pkgIndex.tcl

# The directory containing the Tcl source and header files.
TCL_SRC_DIR		= @TCL_SRC_DIR@

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
DLLSUFFIX		= @DLLSUFFIX@
LIBSUFFIX		= @LIBSUFFIX@
EXESUFFIX		= @EXESUFFIX@

TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
TK_LIB_FILE		= @TK_LIB_FILE@
TK_DLL_FILE		= @TK_DLL_FILE@
TEST_DLL_FILE		= tktest$(VER)${DLLSUFFIX}
TEST_LIB_FILE		= @LIBPREFIX@tktest$(VER)${LIBSUFFIX}

SHARED_LIBRARIES 	= $(TK_DLL_FILE) $(TK_STUB_LIB_FILE)
STATIC_LIBRARIES	= $(TK_LIB_FILE)

WISH			= wish$(VER)${EXESUFFIX}
TKTEST			= tktest.exe
CAT32			= cat32.exe
MAN2TCL			= man2tcl.exe

@SET_MAKE@

# Setting the VPATH variable to a list of paths will cause the
# makefile to look into these paths when resolving .c to .obj
# dependencies.








<
<





|
|
|







127
128
129
130
131
132
133


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
DLLSUFFIX		= @DLLSUFFIX@
LIBSUFFIX		= @LIBSUFFIX@
EXESUFFIX		= @EXESUFFIX@

TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
TK_LIB_FILE		= @TK_LIB_FILE@
TK_DLL_FILE		= @TK_DLL_FILE@



SHARED_LIBRARIES 	= $(TK_DLL_FILE) $(TK_STUB_LIB_FILE)
STATIC_LIBRARIES	= $(TK_LIB_FILE)

WISH			= wish$(VER)${EXESUFFIX}
TKTEST			= tktest${EXEEXT}
CAT32			= cat32$(EXEEXT)
MAN2TCL			= man2tcl$(EXEEXT)

@SET_MAKE@

# Setting the VPATH variable to a list of paths will cause the
# makefile to look into these paths when resolving .c to .obj
# dependencies.

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222



223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@

# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS		= $(CFLAGS_DEBUG)
#CFLAGS		= $(CFLAGS_OPTIMIZE)
#CFLAGS		= $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS		= @CFLAGS@ @CFLAGS_DEFAULT@ -D_ATL_XP_TARGETING

# Special compiler flags to use when building man2tcl on Windows.
MAN2TCLFLAGS	= @MAN2TCLFLAGS@

AR		= @AR@
RANLIB		= @RANLIB@
CC		= @CC@
RC		= @RC@
RES		= @RES@
TK_RES		= @TK_RES@
AC_FLAGS	= @EXTRA_CFLAGS@ @DEFS@ @TCL_DEFS@
CPPFLAGS	= @CPPFLAGS@
LDFLAGS		= @LDFLAGS@ @LDFLAGS_DEFAULT@
LDFLAGS_CONSOLE	= @LDFLAGS_CONSOLE@
LDFLAGS_WINDOW	= @LDFLAGS_WINDOW@

OBJEXT		= @OBJEXT@
STLIB_LD	= @STLIB_LD@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_SUFFIX	= @SHLIB_SUFFIX@
VER		= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER		= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@
LIBS		= $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@
RMDIR		= rm -rf
MKDIR		= mkdir -p
SHELL		= @SHELL@
RM		= rm -f
COPY		= cp

BUILD_TCLSH	= @BUILD_TCLSH@

# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# TCL_EXE is the name of a tclsh executable that is available *BEFORE*
# running make for the first time. Certain build targets (make genstubs)
# need it to be available on the PATH. This executable should *NOT* be
# required just to do a normal build although it can be required to run
# make dist.
TCL_EXE			= @TCLSH_PROG@
WINE    		= @WINE@

CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
-I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \
-I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \
${AC_FLAGS} $(NO_DEPRECATED_FLAGS) -DUSE_TCL_STUBS

CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@




# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL		= cp
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA	= ${INSTALL}

WISH_OBJS = \
	winMain.$(OBJEXT)

TKTEST_OBJS = \

	tkSquare.$(OBJEXT) \
	tkTest.$(OBJEXT) \
	tkOldTest.$(OBJEXT) \
	tkWinTest.$(OBJEXT)

XLIB_OBJS = \
	xcolors.$(OBJEXT) \







|










|




>




















|








<





|



>
>
>














>







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@

# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS		= $(CFLAGS_DEBUG)
#CFLAGS		= $(CFLAGS_OPTIMIZE)
#CFLAGS		= $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS		= @CFLAGS@ @CFLAGS_DEFAULT@ -D_ATL_XP_TARGETING=1 -D__USE_MINGW_ANSI_STDIO=0

# Special compiler flags to use when building man2tcl on Windows.
MAN2TCLFLAGS	= @MAN2TCLFLAGS@

AR		= @AR@
RANLIB		= @RANLIB@
CC		= @CC@
RC		= @RC@
RES		= @RES@
TK_RES		= @TK_RES@
AC_FLAGS	= @EXTRA_CFLAGS@ @DEFS@
CPPFLAGS	= @CPPFLAGS@
LDFLAGS		= @LDFLAGS@ @LDFLAGS_DEFAULT@
LDFLAGS_CONSOLE	= @LDFLAGS_CONSOLE@
LDFLAGS_WINDOW	= @LDFLAGS_WINDOW@
EXEEXT		= @EXEEXT@
OBJEXT		= @OBJEXT@
STLIB_LD	= @STLIB_LD@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_SUFFIX	= @SHLIB_SUFFIX@
VER		= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER		= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@
LIBS		= $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@
RMDIR		= rm -rf
MKDIR		= mkdir -p
SHELL		= @SHELL@
RM		= rm -f
COPY		= cp

BUILD_TCLSH	= @BUILD_TCLSH@

# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	=
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# TCL_EXE is the name of a tclsh executable that is available *BEFORE*
# running make for the first time. Certain build targets (make genstubs)
# need it to be available on the PATH. This executable should *NOT* be
# required just to do a normal build although it can be required to run
# make dist.
TCL_EXE			= @TCLSH_PROG@


CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
-I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \
-I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \
${AC_FLAGS} $(NO_DEPRECATED_FLAGS)

CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@

STUB_CC_SWITCHES	= ${CC_SWITCHES} -DUSE_TCL_STUBS
CON_CC_SWITCHES		= ${CC_SWITCHES} -DCONSOLE

# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL		= cp
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA	= ${INSTALL}

WISH_OBJS = \
	winMain.$(OBJEXT)

TKTEST_OBJS = \
	testMain.$(OBJEXT) \
	tkSquare.$(OBJEXT) \
	tkTest.$(OBJEXT) \
	tkOldTest.$(OBJEXT) \
	tkWinTest.$(OBJEXT)

XLIB_OBJS = \
	xcolors.$(OBJEXT) \
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
	tkWinX.$(OBJEXT) \
	stubs.$(OBJEXT) \
	tk3d.$(OBJEXT) \
	tkArgv.$(OBJEXT) \
	tkAtom.$(OBJEXT) \
	tkBind.$(OBJEXT) \
	tkBitmap.$(OBJEXT) \
	tkBusy.$(OBJEXT) \
	tkButton.$(OBJEXT) \
	tkCanvArc.$(OBJEXT) \
	tkCanvBmap.$(OBJEXT) \
	tkCanvImg.$(OBJEXT) \
	tkCanvLine.$(OBJEXT) \
	tkCanvPoly.$(OBJEXT) \
	tkCanvPs.$(OBJEXT) \







<







280
281
282
283
284
285
286

287
288
289
290
291
292
293
	tkWinX.$(OBJEXT) \
	stubs.$(OBJEXT) \
	tk3d.$(OBJEXT) \
	tkArgv.$(OBJEXT) \
	tkAtom.$(OBJEXT) \
	tkBind.$(OBJEXT) \
	tkBitmap.$(OBJEXT) \

	tkButton.$(OBJEXT) \
	tkCanvArc.$(OBJEXT) \
	tkCanvBmap.$(OBJEXT) \
	tkCanvImg.$(OBJEXT) \
	tkCanvLine.$(OBJEXT) \
	tkCanvPoly.$(OBJEXT) \
	tkCanvPs.$(OBJEXT) \
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
	tkGC.$(OBJEXT) \
	tkGeometry.$(OBJEXT) \
	tkGet.$(OBJEXT) \
	tkGrab.$(OBJEXT) \
	tkGrid.$(OBJEXT) \
	tkImage.$(OBJEXT) \
	tkImgBmap.$(OBJEXT) \
	tkImgListFormat.$(OBJEXT) \
	tkImgGIF.$(OBJEXT) \
	tkImgPNG.$(OBJEXT) \
	tkImgPPM.$(OBJEXT) \
	tkImgSVGnano.$(OBJEXT) \
	tkImgPhoto.$(OBJEXT) \
	tkImgPhInstance.$(OBJEXT) \
	tkImgUtil.$(OBJEXT) \
	tkListbox.$(OBJEXT) \
	tkMacWinMenu.$(OBJEXT) \
	tkMain.$(OBJEXT) \
	tkMain2.$(OBJEXT) \
	tkMenu.$(OBJEXT) \
	tkMenubutton.$(OBJEXT) \
	tkMenuDraw.$(OBJEXT) \
	tkMessage.$(OBJEXT) \
	tkPanedWindow.$(OBJEXT) \
	tkObj.$(OBJEXT) \
	tkOldConfig.$(OBJEXT) \
	tkOption.$(OBJEXT) \
	tkPack.$(OBJEXT) \
	tkPkgConfig.$(OBJEXT) \
	tkPlace.$(OBJEXT) \
	tkPointer.$(OBJEXT) \
	tkRectOval.$(OBJEXT) \
	tkScale.$(OBJEXT) \
	tkScrollbar.$(OBJEXT) \
	tkSelect.$(OBJEXT) \
	tkStyle.$(OBJEXT) \







<

<

<

<




<









<







310
311
312
313
314
315
316

317

318

319

320
321
322
323

324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
	tkGC.$(OBJEXT) \
	tkGeometry.$(OBJEXT) \
	tkGet.$(OBJEXT) \
	tkGrab.$(OBJEXT) \
	tkGrid.$(OBJEXT) \
	tkImage.$(OBJEXT) \
	tkImgBmap.$(OBJEXT) \

	tkImgGIF.$(OBJEXT) \

	tkImgPPM.$(OBJEXT) \

	tkImgPhoto.$(OBJEXT) \

	tkImgUtil.$(OBJEXT) \
	tkListbox.$(OBJEXT) \
	tkMacWinMenu.$(OBJEXT) \
	tkMain.$(OBJEXT) \

	tkMenu.$(OBJEXT) \
	tkMenubutton.$(OBJEXT) \
	tkMenuDraw.$(OBJEXT) \
	tkMessage.$(OBJEXT) \
	tkPanedWindow.$(OBJEXT) \
	tkObj.$(OBJEXT) \
	tkOldConfig.$(OBJEXT) \
	tkOption.$(OBJEXT) \
	tkPack.$(OBJEXT) \

	tkPlace.$(OBJEXT) \
	tkPointer.$(OBJEXT) \
	tkRectOval.$(OBJEXT) \
	tkScale.$(OBJEXT) \
	tkScrollbar.$(OBJEXT) \
	tkSelect.$(OBJEXT) \
	tkStyle.$(OBJEXT) \
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463

# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:
#	% make test TESTFLAGS="-verbose bps -file fileName.test"

test: test-classic test-ttk

test-classic: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32)
	$(SHELL_ENV) $(WINE) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \
	$(TESTFLAGS) | $(WINE) ./$(CAT32)

test-ttk: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32)
	$(SHELL_ENV) $(WINE) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \
	$(TESTFLAGS) | $(WINE) ./$(CAT32)

runtest: binaries $(TKTEST) $(TEST_DLL_FILE)
	$(SHELL_ENV) $(WINE) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT)

# This target can be used to run wish from the build directory
# via `make shell` or `make shell SCRIPT=foo.tcl`
shell: binaries
	$(SHELL_ENV) $(WINE) ./$(WISH) $(SCRIPT)

demo: $(WISH)
	$(SHELL_ENV) $(WINE) ./$(WISH) $(ROOT_DIR)/library/demos/widget

# This target can be used to run wish inside either gdb or insight
gdb: binaries
	@echo "set env TCL_LIBRARY=$(TCL_SRC_DIR_NATIVE)/library" > gdb.run
	@echo "set env TK_LIBRARY=$(ROOT_DIR_NATIVE)/library" >> gdb.run
	PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; \
	gdb ./$(WISH) --command=gdb.run







|
|
|

|
|
|

|
|




|


|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:
#	% make test TESTFLAGS="-verbose bps -file fileName.test"

test: test-classic test-ttk

test-classic: binaries $(TKTEST) $(CAT32)
	$(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \
	$(TESTFLAGS) | ./$(CAT32)

test-ttk: binaries $(TKTEST) $(CAT32)
	$(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \
	$(TESTFLAGS) | ./$(CAT32)

runtest: binaries $(TKTEST)
	$(SHELL_ENV) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT)

# This target can be used to run wish from the build directory
# via `make shell` or `make shell SCRIPT=foo.tcl`
shell: binaries
	$(SHELL_ENV) ./$(WISH) $(SCRIPT)

demo: $(WISH)
	$(SHELL_ENV) ./$(WISH) $(ROOT_DIR)/library/demos/widget

# This target can be used to run wish inside either gdb or insight
gdb: binaries
	@echo "set env TCL_LIBRARY=$(TCL_SRC_DIR_NATIVE)/library" > gdb.run
	@echo "set env TK_LIBRARY=$(ROOT_DIR_NATIVE)/library" >> gdb.run
	PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; \
	gdb ./$(WISH) --command=gdb.run
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
		echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \
		$(COPY) $$i "$(BIN_INSTALL_DIR)"; \
	    fi; \
	    done
	@echo "Creating package index $(PKG_INDEX)";
	@$(RM) $(PKG_INDEX);
	@(\
	echo "if {[catch {package present Tcl 8.6-}]} return";\
	echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]] Tk]";\
	echo "} else {";\
	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE)]] Tk]";\
	echo "}";\
	) > $(PKG_INDEX);
	@for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \
	    do \
	    if [ -f $$i ]; then \
		echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \
		$(COPY) $$i "$(LIB_INSTALL_DIR)"; \







|


|

|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
		echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \
		$(COPY) $$i "$(BIN_INSTALL_DIR)"; \
	    fi; \
	    done
	@echo "Creating package index $(PKG_INDEX)";
	@$(RM) $(PKG_INDEX);
	@(\
	echo "if {![package vsatisfies [package provide Tcl] 8.5.0]} return";\
	echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]]]";\
	echo "} else {";\
	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE)]]]";\
	echo "}";\
	) > $(PKG_INDEX);
	@for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \
	    do \
	    if [ -f $$i ]; then \
		echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \
		$(COPY) $$i "$(LIB_INSTALL_DIR)"; \
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
	@for i in "$(GENERIC_DIR)/tkInt.h" "$(GENERIC_DIR)/tkIntDecls.h" \
		"$(GENERIC_DIR)/tkIntPlatDecls.h" "$(GENERIC_DIR)/tkPort.h" \
		"$(WIN_DIR)/tkWinPort.h" "$(WIN_DIR)/tkWinInt.h" "$(WIN_DIR)/tkWin.h"; \
	    do \
	    $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \
	    done;

$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@

tktest: $(TKTEST)

$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@

${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE}
	@MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS)

# Msys make requires this next rule for some reason.
$(TCL_SRC_DIR)/win/cat.c:

cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME)

$(CAT32): cat32.${OBJEXT}
	$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)

# The following targets are configured by autoconf to generate either
# a shared library or static library








|
|
<





|
|
|



<
<
<




|







601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620



621
622
623
624
625
626
627
628
629
630
631
632
	@for i in "$(GENERIC_DIR)/tkInt.h" "$(GENERIC_DIR)/tkIntDecls.h" \
		"$(GENERIC_DIR)/tkIntPlatDecls.h" "$(GENERIC_DIR)/tkPort.h" \
		"$(WIN_DIR)/tkWinPort.h" "$(WIN_DIR)/tkWinInt.h" "$(WIN_DIR)/tkWin.h"; \
	    do \
	    $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \
	    done;

$(WISH): $(WISH_OBJS) $(TK_LIB_FILE) $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) $(WISH_OBJS) $(TCL_LIB_FILE) $(TK_LIB_FILE) $(LIBS) \

	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@

tktest: $(TKTEST)

$(TKTEST): $(TKTEST_OBJS) $(TK_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) $(TKTEST_OBJS) $(TCL_LIB_FILE) \
	$(TK_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@




# Msys make requires this next rule for some reason.
$(TCL_SRC_DIR)/win/cat.c:

cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c
	$(CC) -c $(CC_SWITCHES) "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME)

$(CAT32): cat32.${OBJEXT}
	$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)

# The following targets are configured by autoconf to generate either
# a shared library or static library

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
	@$(RM) ${TK_LIB_FILE}
	@MAKE_LIB@ ${TK_OBJS}
	@POST_MAKE_LIB@

# Special case object file targets

winMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

testMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DTK_TEST -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkTest.$(OBJEXT): tkTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkOldTest.$(OBJEXT): tkOldTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkWinTest.$(OBJEXT): tkWinTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkSquare.$(OBJEXT): tkSquare.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkMain2.$(OBJEXT): tkMain.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkUnixMenubu.$(OBJEXT): ${UNIX_DIR}/tkUnixMenubu.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

tkUnixScale.$(OBJEXT): ${UNIX_DIR}/tkUnixScale.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

# Extra dependency info
tkConsole.$(OBJEXT): configure Makefile
tkMain.$(OBJEXT): configure Makefile
tkMain2.$(OBJEXT): configure Makefile
tkWindow.$(OBJEXT): configure Makefile

# Add the object extension to the implicit rules.  By default .obj is not
# automatically added.

.SUFFIXES: .${OBJEXT}
.SUFFIXES: .$(RES)
.SUFFIXES: .rc

# Implicit rule for all object files that will end up in the Tk library

%.$(OBJEXT): %.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

.rc.$(RES):
	$(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@

depend:

cleanhelp:
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl.exe

clean: cleanhelp
	$(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(WISH) $(TKTEST) $(CAT32)
	$(RM) *.pch *.ilk *.pdb


distclean: clean
	$(RM) Makefile config.status config.cache config.log tkConfig.sh \
		wish.exe.manifest

Makefile: $(SRC_DIR)/Makefile.in
	./config.status







|


|













<
<
<

|


|




<












|


|




|




|
>







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667



668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
	@$(RM) ${TK_LIB_FILE}
	@MAKE_LIB@ ${TK_OBJS}
	@POST_MAKE_LIB@

# Special case object file targets

winMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

testMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DTK_TEST @DEPARG@ $(CC_OBJNAME)

tkTest.$(OBJEXT): tkTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkOldTest.$(OBJEXT): tkOldTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkWinTest.$(OBJEXT): tkWinTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkSquare.$(OBJEXT): tkSquare.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)




tkUnixMenubu.$(OBJEXT): ${UNIX_DIR}/tkUnixMenubu.c
	$(CC) -c $(STUB_CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

tkUnixScale.$(OBJEXT): ${UNIX_DIR}/tkUnixScale.c
	$(CC) -c $(STUB_CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

# Extra dependency info
tkConsole.$(OBJEXT): configure Makefile
tkMain.$(OBJEXT): configure Makefile

tkWindow.$(OBJEXT): configure Makefile

# Add the object extension to the implicit rules.  By default .obj is not
# automatically added.

.SUFFIXES: .${OBJEXT}
.SUFFIXES: .$(RES)
.SUFFIXES: .rc

# Implicit rule for all object files that will end up in the Tk library

%.$(OBJEXT): %.c
	$(CC) -c $(STUB_CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

.rc.$(RES):
	$(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(TCL_PLATFORM_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@

depend:

cleanhelp:
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl${EXEEXT}

clean: cleanhelp
	$(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(WISH) $(TKTEST) $(CAT32)
	$(RM) *.pch *.ilk *.pdb *.zip
	$(RMDIR) *.vfs

distclean: clean
	$(RM) Makefile config.status config.cache config.log tkConfig.sh \
		wish.exe.manifest

Makefile: $(SRC_DIR)/Makefile.in
	./config.status
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
	@echo "This warning can be safely ignored, do not report as a bug!"

genstubs:
	$(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \
	    "$(GENERIC_DIR_NATIVE)" \
	    "$(GENERIC_DIR_NATIVE)/tk.decls" \
	    "$(GENERIC_DIR_NATIVE)/tkInt.decls"
	$(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \
	    "$(TTK_DIR)" \
	    "$(TTK_DIR)/ttk.decls"

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#







|







720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
	@echo "This warning can be safely ignored, do not report as a bug!"

genstubs:
	$(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \
	    "$(GENERIC_DIR_NATIVE)" \
	    "$(GENERIC_DIR_NATIVE)/tk.decls" \
	    "$(GENERIC_DIR_NATIVE)/tkInt.decls"
	$(TCL_EXE) "$(TTK_DIR)/ttkGenStubs.tcl" \
	    "$(TTK_DIR)" \
	    "$(TTK_DIR)/ttk.decls"

#
# The list of all the targets that do not correspond to real files. This stops
# 'make' from getting confused when someone makes an error in a rule.
#

Changes to win/README.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Tk 8.7 for Windows

Originally by Scott Stanton while at Sun Microsystems Labs

This is the directory where you configure and compile the Windows
version of Tk.  This directory also contains source files for Tk
that are specific to Microsoft Windows.  The rest of this file
contains information specific to the Windows version of Tk.

Please see the README and win/README files that come with the
associated Tcl release for an extensive set of pointers to
documentation.  You will need to obtain and compile the
Tcl release before using the Tk source distrition.

If you install the Tk sources next to the Tcl sources, then
the Tk Makefiles (e.g., makefile.vc for VC++) will properly
locate the necessary Tcl files.  Otherwise you may need to
edit makefile.vc and adjust the path to Tcl accordingly.

Information about compiling for windows is maintained at:
    https://www.tcl-lang.org/doc/howto/compile.html
|



















|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Tk 8.5 for Windows

Originally by Scott Stanton while at Sun Microsystems Labs

This is the directory where you configure and compile the Windows
version of Tk.  This directory also contains source files for Tk
that are specific to Microsoft Windows.  The rest of this file
contains information specific to the Windows version of Tk.

Please see the README and win/README files that come with the
associated Tcl release for an extensive set of pointers to
documentation.  You will need to obtain and compile the
Tcl release before using the Tk source distrition.

If you install the Tk sources next to the Tcl sources, then
the Tk Makefiles (e.g., makefile.vc for VC++) will properly
locate the necessary Tcl files.  Otherwise you may need to
edit makefile.vc and adjust the path to Tcl accordingly.

Information about compiling for windows is maintained at:
    http://www.tcl.tk/doc/howto/compile.html

Changes to win/buildall.vc.bat.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

:: Where is the Tcl source directory?
:: You can set the TCLDIR environment variable to your Tcl HEAD checkout
if "%TCLDIR%" == "" set TCLDIR=..\..\tcl

:: Build the normal stuff along with the help file.
::
set OPTS=none
if not %SYMBOLS%.==. set OPTS=symbols
nmake -nologo -f makefile.vc release htmlhelp OPTS=%OPTS% %1
if errorlevel 1 goto error

:: Build the static core and shell.
::
set OPTS=static,msvcrt
if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
if errorlevel 1 goto error

set OPTS=
set SYMBOLS=
goto end








|
|
|




|
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

:: Where is the Tcl source directory?
:: You can set the TCLDIR environment variable to your Tcl HEAD checkout
if "%TCLDIR%" == "" set TCLDIR=..\..\tcl

:: Build the normal stuff along with the help file.
::
set OPTS=threads
if not %SYMBOLS%.==. set OPTS=symbols,threads
nmake -nologo -f makefile.vc release OPTS=%OPTS% %1
if errorlevel 1 goto error

:: Build the static core and shell.
::
set OPTS=static,msvcrt,threads
if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt,threads
nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
if errorlevel 1 goto error

set OPTS=
set SYMBOLS=
goto end

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

:help
title buildall.vc.bat help message
echo usage:
echo   %0                 : builds Tk for all build types (do this first)
echo   %0 install         : installs all the release builds (do this second)
echo   %0 symbols         : builds Tk for all debugging build types
echo   %0 symbols install : install all the debug builds.
echo.
goto out

:end
title Building Tk, please wait... DONE!
echo DONE!
goto out

:out
pause
title Command Prompt







|











89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

:help
title buildall.vc.bat help message
echo usage:
echo   %0                 : builds Tk for all build types (do this first)
echo   %0 install         : installs all the release builds (do this second)
echo   %0 symbols         : builds Tk for all debugging build types
echo   %0 symbols install : install all the debug builds
echo.
goto out

:end
title Building Tk, please wait... DONE!
echo DONE!
goto out

:out
pause
title Command Prompt

Changes to win/configure.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463












464

465
466

467
468
469


470
471
472
473


474
475



476
477

478
479

















































480
481
482
483

484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515

516
517
518

519


520
521
522
523
524
525
526
527

528
529
530
531
532
533


534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556





557


558
559
560
561
562
563


564
565
566
567
568
569
570
571
572
573
574
575

576





577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi


as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '
    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi
  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'
fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
  fi
  # We don't want this to propagate to other subprocesses.
          { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '\${1+\"\$@\"}'='\"\$@\"'
  setopt NO_GLOB_SUBST
else
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :

else
  exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
test -x / || exit 1"
  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
  if (eval "$as_required") 2>/dev/null; then :
  as_have_required=yes
else
  as_have_required=no
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :

else
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  as_found=:
  case $as_dir in #(
	 /*)
	   for as_base in sh bash ksh sh5; do
	     # Try only shells that exist, to save several forks.
	     as_shell=$as_dir/$as_base
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
  CONFIG_SHELL=$as_shell as_have_required=yes
		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
  break 2
fi
fi
	   done;;
       esac
  as_found=false
done
$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
  CONFIG_SHELL=$SHELL as_have_required=yes
fi; }
IFS=$as_save_IFS


      if test "x$CONFIG_SHELL" != x; then :
  export CONFIG_SHELL
             # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    if test x$as_have_required = xno; then :
  $as_echo "$0: This script requires a shell more modern than all"
  $as_echo "$0: the shells that I found on your system."
  if test x${ZSH_VERSION+set} = xset ; then
    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
  fi
  exit 1
fi
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
} # as_fn_set_status

# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
  set +e
  as_fn_set_status $1
  exit $1
} # as_fn_exit

# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{

  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
      test -d "$as_dir" && break
    done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"


} # as_fn_mkdir_p

# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
  as_expr=false
fi

if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi

if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
  as_dirname=dirname
else
  as_dirname=false
fi


as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||

$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`

# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits















  as_lineno_1=$LINENO as_lineno_1a=$LINENO
  as_lineno_2=$LINENO as_lineno_2a=$LINENO

  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)


  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |


    sed '
      s/[$]LINENO.*/&-/



      t lineno
      b

      :lineno
      N

















































      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//

    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }


  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}

ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;

esac

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file

else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null

fi


if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||

      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi


else
  as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null

if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"







test -n "$DJDIR" || exec 7<&0 </dev/null


exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`



#
# Initializations.
#
ac_default_prefix=/usr/local
ac_clean_files=
ac_config_libobj_dir=.
LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=







# Identity of this package.
PACKAGE_NAME=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
PACKAGE_URL=

ac_unique_file="../generic/tk.h"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>

#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"

ac_subst_vars='LTLIBOBJS
LIBOBJS
RES
RC_DEFINES
RC_DEFINE
RC_INCLUDE
RC_TYPE
RC_OUT
TK_LD_SEARCH_FLAGS
TK_CC_SEARCH_FLAGS
TK_BUILD_STUB_LIB_PATH
TK_STUB_LIB_PATH
TK_STUB_LIB_SPEC
TK_BUILD_LIB_SPEC
TK_LIB_SPEC
TK_LIB_FLAG
MAKE_EXE
MAKE_DLL
POST_MAKE_LIB
MAKE_STUB_LIB
MAKE_LIB
LIBRARIES
EXESUFFIX
LIBSUFFIX
LIBPREFIX
DLLSUFFIX
LIBS_GUI
TK_SHARED_BUILD
SHLIB_SUFFIX
SHLIB_CFLAGS
SHLIB_LD_LIBS
SHLIB_LD
STLIB_LD
TK_RES
LDFLAGS_WINDOW
LDFLAGS_CONSOLE
LDFLAGS_OPTIMIZE
LDFLAGS_DEBUG
CC_EXENAME
CC_OBJNAME
DEPARG
EXTRA_CFLAGS
CFG_TK_EXPORT_FILE_SUFFIX
CFG_TK_UNSHARED_LIB_SUFFIX
CFG_TK_SHARED_LIB_SUFFIX
TCL_PATCH_LEVEL
TCL_MINOR_VERSION
TCL_MAJOR_VERSION
TK_BIN_DIR
TK_SRC_DIR
TK_BUILD_STUB_LIB_SPEC
TK_STUB_LIB_FLAG
TK_STUB_LIB_FILE
TK_DLL_FILE
TK_LIB_FILE
TK_PATCH_LEVEL
TK_MINOR_VERSION
TK_MAJOR_VERSION
TK_VERSION
MACHINE
TK_WIN_VERSION
TCLSH_PROG
BUILD_TCLSH
VC_MANIFEST_EMBED_EXE
VC_MANIFEST_EMBED_DLL
LDFLAGS_DEFAULT
CFLAGS_DEFAULT
MAN2TCLFLAGS
CFLAGS_WARNING
CFLAGS_OPTIMIZE
CFLAGS_DEBUG
DL_LIBS
WINE
CYGPATH
TCL_DEFS
TCL_STUB_LIB_SPEC
TCL_STUB_LIB_FLAG
TCL_STUB_LIB_FILE
TCL_LIB_SPEC
TCL_LIB_FLAG
TCL_LIB_FILE
TCL_ZIP_FILE
TCL_SRC_DIR
TCL_BIN_DIR
TCL_VERSION
SHARED_BUILD
SET_MAKE
RC
RANLIB
AR
EGREP
GREP
CPP
OBJEXT
EXEEXT
ac_ct_CC
CPPFLAGS
LDFLAGS
CFLAGS
CC
target_alias
host_alias
build_alias
LIBS
ECHO_T
ECHO_N
ECHO_C
DEFS
mandir
localedir
libdir
psdir
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
bindir
program_transform_name
prefix
exec_prefix
PACKAGE_URL
PACKAGE_BUGREPORT
PACKAGE_STRING
PACKAGE_VERSION
PACKAGE_TARNAME
PACKAGE_NAME
PATH_SEPARATOR
SHELL
OBJEXT_FOR_BUILD'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_shared
with_tcl
enable_64bit
enable_symbols
enable_embedded_manifest
'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CPP'


# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
ac_unrecognized_opts=
ac_unrecognized_sep=
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
exec_prefix=NONE
no_create=
no_recursion=
prefix=NONE


|

<
|
<
<


|
|
|

|
<
|


|


<
<
|
<
|
<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<

|
<
<
<

<
|
<
<
|
<
<
<





<
|
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<





|





<
<
<
<
<

>
|


|
>
|
|
<
<
<
|
<
<
<
|
|
|
|
<
|







>
>
>
>
>
>
>
>
>
>
>
>

>
|
|
>
|
|
<
>
>
|
<
<
|
>
>
|
<
>
>
>
|
|
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
>

|
|
>

<
<
<
<


|
|




|
<
<
|
<
|
<
|
<
<
|
>


<
|
<
>

<
<
>

>
>
|
|
<
|
<
|
<
|
>
|
<
<

|

>
>

|

|
<


|





<
|








>
>
>
>
>
|
>
>
|


|


>
>





<

<




>

>
>
>
>
>

|
|
|
|
|
<





|


|


|



|



|
|




|


|

|
|
|
>

|



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
<







1
2
3
4

5


6
7
8
9
10
11
12

13
14
15
16
17
18


19

20



21
22













































23

24
25






26

27










28






29
30



31

32


33



34
35
36
37
38

39

40
41


42















































43






44
















45
46




























47





































48














































































49


50
51





























































52

53
54
55
56
57
58
59
60
61
62
63





64
65
66
67
68
69
70
71
72



73



74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107


108
109
110
111

112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177




178
179
180
181
182
183
184
185
186


187

188

189


190
191
192
193

194

195
196


197
198
199
200
201
202

203

204

205
206
207


208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312










































































































































313


















314
315
316
317


318
319
320
321
322
323
324
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for tk 8.5.
#

# Copyright (C) 2003 Free Software Foundation, Inc.


# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
## --------------------- ##

# Be Bourne compatible

if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
  emulate sh
  NULLCMD=:
  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'


elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then

  set -o posix



fi
DUALCASE=1; export DUALCASE # for MKS sh















































# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then






  as_unset=unset

else










  as_unset=false






fi






# Work around bugs in pre-3.0 UWIN ksh.


$as_unset ENV MAIL MAILPATH



PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.

for as_var in \

  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \


  LC_TELEPHONE LC_TIME















































do






  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
















    eval $as_var=C; export $as_var
  else




























    $as_unset $as_var





































  fi














































































done



# Required to use basename.





























































if expr a : '\(a\)' >/dev/null 2>&1; then

  as_expr=expr
else
  as_expr=false
fi

if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi







# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)$' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }



  	  /^X\/\(\/\/\)$/{ s//\1/; q; }



  	  /^X\/\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; q'`



# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  echo "#! /bin/sh" >conf$$.sh
  echo  "exit 0"   >>conf$$.sh
  chmod +x conf$$.sh
  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
    PATH_SEPARATOR=';'
  else
    PATH_SEPARATOR=:
  fi
  rm -f conf$$.sh
fi


  as_lineno_1=$LINENO
  as_lineno_2=$LINENO
  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
  test "x$as_lineno_1" != "x$as_lineno_2" &&
  test "x$as_lineno_3"  = "x$as_lineno_2"  || {

  # Find who we are.  Look in the path if we contain no path at all
  # relative or not.
  case $0 in


    *[\\/]* ) as_myself=$0 ;;
    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do

  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done

       ;;
  esac

  # We did not find ourselves, most probably we were run as `sh COMMAND'
  # in which case we are not to be found in the path.
  if test "x$as_myself" = x; then
    as_myself=$0
  fi
  if test ! -f "$as_myself"; then
    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
   { (exit 1); exit 1; }; }
  fi
  case $CONFIG_SHELL in
  '')
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for as_base in sh bash ksh sh5; do
	 case $as_dir in
	 /*)
	   if ("$as_dir/$as_base" -c '
  as_lineno_1=$LINENO
  as_lineno_2=$LINENO
  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
  test "x$as_lineno_1" != "x$as_lineno_2" &&
  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
	     CONFIG_SHELL=$as_dir/$as_base
	     export CONFIG_SHELL
	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
	   fi;;
	 esac
       done
done
;;
  esac

  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
  # uniformly replaced by the line number.  The first 'sed' inserts a
  # line-number line before each line; the second 'sed' does the real
  # work.  The second script uses 'N' to pair each line-number line
  # with the numbered line, and appends trailing '-' during
  # substitution so that $LINENO is not a special case at line end.
  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
  sed '=' <$as_myself |
    sed '
      N
      s,$,-,
      : loop
      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
      t loop
      s,-$,,
      s,^['$as_cr_digits']*\n,,
    ' >$as_me.lineno &&
  chmod +x $as_me.lineno ||
    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
   { (exit 1); exit 1; }; }





  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensible to this).
  . ./$as_me.lineno
  # Exit status is that of the last command.
  exit
}




case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in

  *c*,-n*) ECHO_N= ECHO_C='

' ECHO_T='	' ;;


  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac


if expr a : '\(a\)' >/dev/null 2>&1; then

  as_expr=expr
else


  as_expr=false
fi

rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then

  # We could just check for DJGPP; but this test a) works b) is more generic

  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).

  if test -f conf$$.exe; then
    # Don't use ln at all; we don't have any links
    as_ln_s='cp -p'


  else
    as_ln_s='ln -s'
  fi
elif ln conf$$.file conf$$ 2>/dev/null; then
  as_ln_s=ln
else
  as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file


if mkdir -p . 2>/dev/null; then
  as_mkdir_p=:
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi


as_executable_p="test -f"

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"


# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" 	$as_nl"

# CDPATH.
$as_unset CDPATH


# Name of the host.
# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`

exec 6>&1

#
# Initializations.
#
ac_default_prefix=/usr/local

ac_config_libobj_dir=.

cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Maximum number of lines to put in a shell here document.
# This variable seems obsolete.  It should probably be removed, and
# only ac_max_sed_lines should be used.
: ${ac_max_here_lines=38}

# Identity of this package.
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
PACKAGE_VERSION='8.5'
PACKAGE_STRING='tk 8.5'
PACKAGE_BUGREPORT=''


ac_unique_file="../generic/tk.h"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# if HAVE_STDINT_H
#  include <stdint.h>
# endif
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif"

ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_DEFS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING MAN2TCLFLAGS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE BUILD_TCLSH TCLSH_PROG TK_WIN_VERSION MACHINE TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_DBGX TK_LIB_FILE TK_DLL_FILE TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_SRC_DIR TK_BIN_DIR TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_DBGX CFG_TK_SHARED_LIB_SUFFIX CFG_TK_UNSHARED_LIB_SUFFIX CFG_TK_EXPORT_FILE_SUFFIX TK_SHARED_BUILD DEPARG EXTRA_CFLAGS STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES TK_RES RES LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TK_LIB_FLAG TK_LIB_SPEC TK_BUILD_LIB_SPEC TK_STUB_LIB_SPEC TK_STUB_LIB_PATH TK_BUILD_STUB_LIB_PATH TK_CC_SEARCH_FLAGS TK_LD_SEARCH_FLAGS LIBOBJS LTLIBOBJS'










































































































































ac_subst_files=''



















# Initialize some variables set by options.
ac_init_help=
ac_init_version=false


# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
exec_prefix=NONE
no_create=
no_recursion=
prefix=NONE
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
x_libraries=NONE

# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'

includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
mandir='${datarootdir}/man'

ac_prev=
ac_dashdash=
for ac_option
do
  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval $ac_prev=\$ac_option
    ac_prev=
    continue
  fi

  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_dashdash$ac_option in
  --)
    ac_dashdash=yes ;;

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir=$ac_optarg ;;

  -build | --build | --buil | --bui | --bu)







<



|
<



>


<
|
<
<
<
<
<
<
|


<




|




<
|
<
<
<



|
<
<







333
334
335
336
337
338
339

340
341
342
343

344
345
346
347
348
349

350






351
352
353

354
355
356
357
358
359
360
361
362

363



364
365
366
367


368
369
370
371
372
373
374
x_libraries=NONE

# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.

bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'

sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'

infodir='${prefix}/info'






mandir='${prefix}/man'

ac_prev=

for ac_option
do
  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval "$ac_prev=\$ac_option"
    ac_prev=
    continue
  fi


  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`




  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_option in



  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir=$ac_optarg ;;

  -build | --build | --buil | --bui | --bu)
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file=$ac_optarg ;;

  --config-cache | -C)
    cache_file=config.cache ;;

  -datadir | --datadir | --datadi | --datad)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=*)
    datadir=$ac_optarg ;;

  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
  | --dataroo | --dataro | --datar)
    ac_prev=datarootdir ;;
  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval enable_$ac_useropt=no ;;

  -docdir | --docdir | --docdi | --doc | --do)
    ac_prev=docdir ;;
  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
    docdir=$ac_optarg ;;

  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
    ac_prev=dvidir ;;
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval enable_$ac_useropt=\$ac_optarg ;;

  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \







|

|
<
<
<
|
<
<
<
|


|

|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
|


|

|
|
|
|
|
<
|
|
<
<

|







382
383
384
385
386
387
388
389
390
391



392



393
394
395
396
397
398
399










400




401



402
403
404
405
406
407
408
409
410
411

412
413


414
415
416
417
418
419
420
421
422
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file=$ac_optarg ;;

  --config-cache | -C)
    cache_file=config.cache ;;

  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \



  | --da=*)



    datadir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid feature name: $ac_feature" >&2










   { (exit 1); exit 1; }; }




    ac_feature=`echo $ac_feature | sed 's/-/_/g'`



    eval "enable_$ac_feature=no" ;;

  -enable-* | --enable-*)
    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
   { (exit 1); exit 1; }; }
    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
    case $ac_option in

      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
      *) ac_optarg=yes ;;


    esac
    eval "enable_$ac_feature='$ac_optarg'" ;;

  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
    ac_init_help=short ;;

  -host | --host | --hos | --ho)
    ac_prev=host_alias ;;
  -host=* | --host=* | --hos=* | --ho=*)
    host_alias=$ac_optarg ;;

  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
    ac_prev=htmldir ;;
  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
  | --ht=*)
    htmldir=$ac_optarg ;;

  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir=$ac_optarg ;;








<
<
<
<
<
<







435
436
437
438
439
440
441






442
443
444
445
446
447
448
    ac_init_help=short ;;

  -host | --host | --hos | --ho)
    ac_prev=host_alias ;;
  -host=* | --host=* | --hos=* | --ho=*)
    host_alias=$ac_optarg ;;







  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir=$ac_optarg ;;

974
975
976
977
978
979
980
981
982
983
984
985
986
987

988
989
990

991
992
993
994
995
996
997
  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir=$ac_optarg ;;

  -localedir | --localedir | --localedi | --localed | --locale)
    ac_prev=localedir ;;
  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
    localedir=$ac_optarg ;;

  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst | --locals)

    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)

    localstatedir=$ac_optarg ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir=$ac_optarg ;;








<
<
<
<
<

|
>


|
>







459
460
461
462
463
464
465





466
467
468
469
470
471
472
473
474
475
476
477
478
479
  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir=$ac_optarg ;;






  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst \
  | --locals | --local | --loca | --loc | --lo)
    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
    localstatedir=$ac_optarg ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir=$ac_optarg ;;

1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name=$ac_optarg ;;

  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
    ac_prev=pdfdir ;;
  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
    pdfdir=$ac_optarg ;;

  -psdir | --psdir | --psdi | --psd | --ps)
    ac_prev=psdir ;;
  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
    psdir=$ac_optarg ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \







<
<
<
<
<
<
<
<
<
<







530
531
532
533
534
535
536










537
538
539
540
541
542
543
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name=$ac_optarg ;;











  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1173

1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213


1214


1215




1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233


1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288



1289

1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302


1303













1304

1305












1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338



1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379


1380
1381
1382
1383
1384
1385

1386
1387

1388
1389
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442

1443

1444

1445
1446
1447
1448
1449
1450
1451

1452










1453













1454













1455
1456
1457
1458
1459
1460
1461
1462


1463


1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt

    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=no ;;

  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes=$ac_optarg ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: \`$ac_option'
Try \`$0 --help' for more information"

    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;

    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi

if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in
    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi

# Check all directory arguments for consistency.

for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;


  esac


  # Be sure to have absolute directory names.




  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;

  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done

# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.
if test "x$host_alias" != x; then
  if test "x$build_alias" = x; then
    cross_compiling=maybe


  elif test "x$build_alias" != "x$host_alias"; then
    cross_compiling=yes
  fi
fi

ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-

test "$silent" = yes && exec 6>/dev/null


ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
  as_fn_error $? "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
  as_fn_error $? "pwd does not report name of working directory"


# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then the parent directory.
  ac_confdir=`$as_dirname -- "$as_myself" ||
$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_myself" : 'X\(//\)[^/]' \| \
	 X"$as_myself" : 'X\(//\)$' \| \
	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||

$as_echo X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
  srcdir=$ac_confdir
  if test ! -r "$srcdir/$ac_unique_file"; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."



  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"

fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi
# Remove unnecessary trailing slashes from srcdir.
# Double slashes in file names in object file debugging info
# mess up M-x gdb in Emacs.
case $srcdir in


*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;













esac

for ac_var in $ac_precious_vars; do












  eval ac_env_${ac_var}_set=\${${ac_var}+set}
  eval ac_env_${ac_var}_value=\$${ac_var}
  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
  eval ac_cv_env_${ac_var}_value=\$${ac_var}
done

#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures this package to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print \`checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for \`--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or \`..']




Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]

  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]
_ACEOF

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then



  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]

  --enable-shared         build and link with shared libraries (default: on)
  --enable-64bit          enable 64bit support (where applicable)

  --enable-symbols        build with debugging symbols (default: off)
  --enable-embedded-manifest
                          embed manifest if possible (default: yes)

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-tcl              directory containing tcl configuration
                          (tclConfig.sh)


Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.

  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix

case $srcdir in
  .)  # We are building in place.
    ac_srcdir=.

    ac_top_srcdir=$ac_top_builddir_sub

    ac_abs_top_srcdir=$ac_pwd ;;

  [\\/]* | ?:[\\/]* )  # Absolute name.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir
    ac_abs_top_srcdir=$srcdir ;;
  *) # Relative name.
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir

    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;










esac













ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix














    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.
    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&


      $SHELL "$ac_srcdir/configure" --help=recursive


    else
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
configure
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi

## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##

# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext
  if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest.$ac_objext; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_compile

# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_cpp ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if { { ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } > conftest.i && {
	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
	 test ! -s conftest.err
       }; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

    ac_retval=1
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_cpp

# ac_fn_c_try_run LINENO
# ----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
# that executables *can* be run.
ac_fn_c_try_run ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
  { { case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }; then :
  ac_retval=0
else
  $as_echo "$as_me: program exited with status $ac_status" >&5
       $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

       ac_retval=$ac_status
fi
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_run

# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
# the include files in INCLUDES and setting the cache variable VAR
# accordingly.
ac_fn_c_check_header_mongrel ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if eval \${$3+:} false; then :
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
else
  # Is the header compilable?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
$as_echo_n "checking $2 usability... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_header_compiler=yes
else
  ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
$as_echo "$ac_header_compiler" >&6; }

# Is the header present?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
$as_echo_n "checking $2 presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <$2>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  ac_header_preproc=yes
else
  ac_header_preproc=no
fi
rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }

# So?  What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
  yes:no: )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
  no:yes:* )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
esac
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
else
  eval "$3=\$ac_header_compiler"
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_mongrel

# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
# INCLUDES, setting the cache variable VAR accordingly.
ac_fn_c_check_header_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  eval "$3=yes"
else
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_compile
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##

hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`

/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`

/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`

_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    $as_echo "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF


## ----------- ##







|

|
|
|
|
|
<
|
|
<
<

|


|

|
|
<
>
|
<
<
|
<
<
<
<
<



















|
|
>





<
|
|
>
|
|




|

|
|







|
<
|
<
<
<
<
<
<


<
>
|
<
<
<

|
<

|
<
<
>
>

>
>
|
>
>
>
>

|
|
>

<













>
>











<
<
<
<
<
<
<
<



|
|
|
|
|
|
>
|
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|

|





|
|
>
>
>
|
>
|
<
<
<
<
<
<
<

<
<
<
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
<








|













|





>
>
>


|

|









|
|
|
>
|
|
|
|
|
|
<
<
|
<
|
<
<
<
<
<







|
>
>



<


>


>









>






<
|
|





<

<




>

<
<
|


|
<
<
|
|
|
<
<
<
<
|
|
<
<
|


|

>
|
>
|
>
|

|
<
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
|
|
|
|
|
>
>
|
>
>

|
|
|



|


|
|

|



|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|




<


















|











|
|
<







580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595


596
597
598
599
600
601
602
603

604
605


606





607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654

655






656
657

658
659



660
661

662
663


664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704








705
706
707
708
709
710
711
712
713
714
715
716



717



718



719



720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735







736



737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827


828

829





830
831
832
833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864

865
866
867
868
869
870
871

872

873
874
875
876
877
878


879
880
881
882


883
884
885




886
887


888
889
890
891
892
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976


















































































































































977




























































































978
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid package name: $ac_package" >&2
   { (exit 1); exit 1; }; }
    ac_package=`echo $ac_package| sed 's/-/_/g'`
    case $ac_option in

      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
      *) ac_optarg=yes ;;


    esac
    eval "with_$ac_package='$ac_optarg'" ;;

  -without-* | --without-*)
    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid package name: $ac_package" >&2

   { (exit 1); exit 1; }; }
    ac_package=`echo $ac_package | sed 's/-/_/g'`


    eval "with_$ac_package=no" ;;






  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes=$ac_optarg ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) { echo "$as_me: error: unrecognized option: $ac_option
Try \`$0 --help' for more information." >&2
   { (exit 1); exit 1; }; }
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.

    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
   { (exit 1); exit 1; }; }
    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
    eval "$ac_envvar='$ac_optarg'"
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  { echo "$as_me: error: missing argument to $ac_option" >&2

   { (exit 1); exit 1; }; }






fi


# Be sure to have absolute paths.
for ac_var in exec_prefix prefix



do
  eval ac_val=$`echo $ac_var`

  case $ac_val in
    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;


    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
   { (exit 1); exit 1; }; };;
  esac
done

# Be sure to have absolute paths.
for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
	      localstatedir libdir includedir oldincludedir infodir mandir
do
  eval ac_val=$`echo $ac_var`
  case $ac_val in
    [\\/$]* | ?:[\\/]* ) ;;
    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
   { (exit 1); exit 1; }; };;
  esac

done

# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.
if test "x$host_alias" != x; then
  if test "x$build_alias" = x; then
    cross_compiling=maybe
    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used." >&2
  elif test "x$build_alias" != "x$host_alias"; then
    cross_compiling=yes
  fi
fi

ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-

test "$silent" = yes && exec 6>/dev/null










# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then its parent.
  ac_confdir=`(dirname "$0") 2>/dev/null ||
$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$0" : 'X\(//\)[^/]' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X"$0" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }



  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }



  	  /^X\(\/\/\)$/{ s//\1/; q; }



  	  /^X\(\/\).*/{ s//\1/; q; }



  	  s/.*/./; q'`
  srcdir=$ac_confdir
  if test ! -r $srcdir/$ac_unique_file; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
  if test "$ac_srcdir_defaulted" = yes; then
    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
   { (exit 1); exit 1; }; }
  else
    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
   { (exit 1); exit 1; }; }
  fi







fi



(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
   { (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
ac_env_build_alias_set=${build_alias+set}
ac_env_build_alias_value=$build_alias
ac_cv_env_build_alias_set=${build_alias+set}
ac_cv_env_build_alias_value=$build_alias
ac_env_host_alias_set=${host_alias+set}
ac_env_host_alias_value=$host_alias
ac_cv_env_host_alias_set=${host_alias+set}
ac_cv_env_host_alias_value=$host_alias
ac_env_target_alias_set=${target_alias+set}
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
ac_env_CC_set=${CC+set}
ac_env_CC_value=$CC
ac_cv_env_CC_set=${CC+set}
ac_cv_env_CC_value=$CC
ac_env_CFLAGS_set=${CFLAGS+set}
ac_env_CFLAGS_value=$CFLAGS
ac_cv_env_CFLAGS_set=${CFLAGS+set}
ac_cv_env_CFLAGS_value=$CFLAGS
ac_env_LDFLAGS_set=${LDFLAGS+set}
ac_env_LDFLAGS_value=$LDFLAGS
ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
ac_cv_env_LDFLAGS_value=$LDFLAGS
ac_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_env_CPPFLAGS_value=$CPPFLAGS
ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_cv_env_CPPFLAGS_value=$CPPFLAGS
ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP


#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures tk 8.5 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print \`checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for \`--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or \`..']

_ACEOF

  cat <<_ACEOF
Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
			  [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
			  [PREFIX]

By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR           user executables [EPREFIX/bin]
  --sbindir=DIR          system admin executables [EPREFIX/sbin]
  --libexecdir=DIR       program executables [EPREFIX/libexec]
  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
  --oldincludedir=DIR    C header files for non-gcc [/usr/include]


  --infodir=DIR          info documentation [PREFIX/info]

  --mandir=DIR           man documentation [PREFIX/man]





_ACEOF

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of tk 8.5:";;
   esac
  cat <<\_ACEOF

Optional Features:

  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-threads        build with threads (default: off)
  --enable-shared         build and link with shared libraries (default: on)
  --enable-64bit          enable 64bit support (where applicable)
  --enable-wince          enable Win/CE support (where applicable)
  --enable-symbols        build with debugging symbols (default: off)
  --enable-embedded-manifest
                          embed manifest if possible (default: yes)

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-tcl              directory containing tcl configuration
                          (tclConfig.sh)
  --with-celib=DIR        use Windows/CE support library from DIR

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>

  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
              headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.


_ACEOF

fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  ac_popdir=`pwd`
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue


    test -d $ac_dir || continue
    ac_builddir=.

if test "$ac_dir" != .; then


  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
  # A "../" for each directory in $ac_dir_suffix.
  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`




else
  ac_dir_suffix= ac_top_builddir=


fi

case $srcdir in
  .)  # No --srcdir option.  We are building in place.
    ac_srcdir=.
    if test -z "$ac_top_builddir"; then
       ac_top_srcdir=.
    else
       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
    fi ;;
  [\\/]* | ?:[\\/]* )  # Absolute path.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir ;;

  *) # Relative path.
    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac

# Do not use `cd foo && pwd` to compute absolute paths, because
# the directories may not exist.
case `pwd` in
.) ac_abs_builddir="$ac_dir";;
*)
  case "$ac_dir" in
  .) ac_abs_builddir=`pwd`;;
  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
  *) ac_abs_builddir=`pwd`/"$ac_dir";;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_builddir=${ac_top_builddir}.;;
*)
  case ${ac_top_builddir}. in
  .) ac_abs_top_builddir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_srcdir=$ac_srcdir;;
*)
  case $ac_srcdir in
  .) ac_abs_srcdir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_srcdir=$ac_top_srcdir;;
*)
  case $ac_top_srcdir in
  .) ac_abs_top_srcdir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
  esac;;
esac

    cd $ac_dir
    # Check for guested configure; otherwise get Cygnus style configure.
    if test -f $ac_srcdir/configure.gnu; then
      echo
      $SHELL $ac_srcdir/configure.gnu  --help=recursive
    elif test -f $ac_srcdir/configure; then
      echo
      $SHELL $ac_srcdir/configure  --help=recursive
    elif test -f $ac_srcdir/configure.ac ||
	   test -f $ac_srcdir/configure.in; then
      echo
      $ac_configure --help
    else
      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi
    cd $ac_popdir
  done
fi

test -n "$ac_init_help" && exit 0
if $ac_init_version; then
  cat <<\_ACEOF
tk configure 8.5
generated by GNU Autoconf 2.59

Copyright (C) 2003 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit 0
fi
exec 5>config.log


















































































































































cat >&5 <<_ACEOF




























































































This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by tk $as_me 8.5, which was
generated by GNU Autoconf 2.59.  Invocation command line was

  $ $0 $@

_ACEOF

{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##

hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`

/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`

/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`

_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  echo "PATH: $as_dir"
done


} >&5

cat >&5 <<_ACEOF


## ----------- ##
1780
1781
1782
1783
1784
1785
1786

1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819


1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836

1837
1838
1839

1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857

1858
1859
1860
1861
1862
1863
1864
1865

1866
1867
1868
1869
1870

1871
1872

1873
1874
1875

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887

1888
1889
1890

1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903

1904
1905
1906

1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936
1937

1938
1939
1940
1941

1942
1943
1944
1945

1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973

1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060

2061

2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074


























2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
# Strip out --no-create and --no-recursion so they do not pile up.
# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
ac_configure_args0=
ac_configure_args1=

ac_must_keep_next=false
for ac_pass in 1 2
do
  for ac_arg
  do
    case $ac_arg in
    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
    | -silent | --silent | --silen | --sile | --sil)
      continue ;;
    *\'*)
      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.
      else
	case $ac_arg in
	  *=* | --config-cache | -C | -disable-* | --disable-* \
	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
	  | -with-* | --with-* | -without-* | --without-* | --x)
	    case "$ac_configure_args0 " in
	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
	    esac
	    ;;
	  -* ) ac_must_keep_next=true ;;
	esac
      fi
      as_fn_append ac_configure_args " '$ac_arg'"


      ;;
    esac
  done
done
{ ac_configure_args0=; unset ac_configure_args0;}
{ ac_configure_args1=; unset ac_configure_args1;}

# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
  # Save into config.log some information that might help in debugging.
  {
    echo


    $as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"

    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done

  (set) 2>&1 |
    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      sed -n \
	"s/'\''/'\''\\\\'\'''\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
      ;; #(
    *)

      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)

    echo


    $as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"

    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then

      $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"

      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then

      $as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"

      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_file2=$prefix/etc/config.site
else
  ac_site_file1=$ac_default_prefix/share/config.site
  ac_site_file2=$ac_default_prefix/etc/config.site
fi

for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
  test "x$ac_site_file" = xNONE && continue
  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
  fi
done

if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special files
  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do

  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,set)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,);;
    *)
      if test "x$ac_old_val" != "x$ac_new_val"; then
	# differences in whitespace do not lead to failure.
	ac_old_val_w=`echo x $ac_old_val`
	ac_new_val_w=`echo x $ac_new_val`
	if test "$ac_old_val_w" != "$ac_new_val_w"; then
	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
	  ac_cache_corrupted=:
	else
	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
	  eval $ac_var=\$ac_old_val
	fi
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}

      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in

    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}

  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5

fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu






























# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then







>










|
|


|

|















|
>
>




|
|




|
|





>
|

|
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>

|
|

|
|
|

>
|

|
<
<
>


>
|

|
>



|
<
<
<
|




>
|
|
|
>



|
<
<
<
|





>
|

|
>

|



|
|

|
|

|

|




|
|
|






>




>




>




>





<
<
<

<

|
<
<
|
<
<
<
<
<
<
|
|
<
|
|
<
|
>
|
<
<
|
|
|

|
<
<
<
<




|
|
|
|
|

|
|



|
|






|
>


|
|


|
|


|
|




<
<
<
<
|
|
<
<
<
<
<
<
|
|
|
|
>





>
|




|




<
<
|
|
>
|
>

<
<
<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

|
|







1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
















1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112


1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124



1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138



1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197



1198

1199
1200


1201






1202
1203

1204
1205

1206
1207
1208


1209
1210
1211
1212
1213




1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254




1255
1256






1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277


1278
1279
1280
1281
1282
1283



1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
# Strip out --no-create and --no-recursion so they do not pile up.
# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
ac_sep=
ac_must_keep_next=false
for ac_pass in 1 2
do
  for ac_arg
  do
    case $ac_arg in
    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
    | -silent | --silent | --silen | --sile | --sil)
      continue ;;
    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
    2)
      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.
      else
	case $ac_arg in
	  *=* | --config-cache | -C | -disable-* | --disable-* \
	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
	  | -with-* | --with-* | -without-* | --without-* | --x)
	    case "$ac_configure_args0 " in
	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
	    esac
	    ;;
	  -* ) ac_must_keep_next=true ;;
	esac
      fi
      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
      # Get rid of the leading space.
      ac_sep=" "
      ;;
    esac
  done
done
$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }

# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Be sure not to use single quotes in there, as some shells,
# such as our DU 5.0 friend, will then `close' the trap.
trap 'exit_status=$?
  # Save into config.log some information that might help in debugging.
  {
    echo

    cat <<\_ASBOX
## ---------------- ##
## Cache variables. ##
## ---------------- ##
_ASBOX
    echo
    # The following way of writing the cache mishandles newlines in values,
















{
  (set) 2>&1 |
    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
    *ac_space=\ *)
      sed -n \
	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
      ;;
    *)
      sed -n \
	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
      ;;
    esac;


}
    echo

    cat <<\_ASBOX
## ----------------- ##
## Output variables. ##
## ----------------- ##
_ASBOX
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=$`echo $ac_var`



      echo "$ac_var='"'"'$ac_val'"'"'"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      cat <<\_ASBOX
## ------------- ##
## Output files. ##
## ------------- ##
_ASBOX
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=$`echo $ac_var`



	echo "$ac_var='"'"'$ac_val'"'"'"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      cat <<\_ASBOX
## ----------- ##
## confdefs.h. ##
## ----------- ##
_ASBOX
      echo
      sed "/^$/d" confdefs.h | sort
      echo
    fi
    test "$ac_signal" != 0 &&
      echo "$as_me: caught signal $ac_signal"
    echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core &&
  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
     ' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo >confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF


cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF






# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.


if test -z "$CONFIG_SITE"; then






  if test "x$prefix" != xNONE; then
    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"

  else
    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"

  fi
fi
for ac_site_file in $CONFIG_SITE; do


  if test -r "$ac_site_file"; then
    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
echo "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file"




  fi
done

if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special
  # files actually), so we avoid doing that.
  if test -f "$cache_file"; then
    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . $cache_file;;
      *)                      . ./$cache_file;;
    esac
  fi
else
  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in `(set) 2>&1 |
	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
  eval ac_new_val="\$ac_env_${ac_var}_value"
  case $ac_old_set,$ac_new_set in
    set,)
      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,set)
      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,);;
    *)
      if test "x$ac_old_val" != "x$ac_new_val"; then




	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}






	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
echo "$as_me:   former value:  $ac_old_val" >&2;}
	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
echo "$as_me:   current value: $ac_new_val" >&2;}
	ac_cache_corrupted=:
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then


  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
echo "$as_me: error: changes in the environment can compromise the build" >&2;}
  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
   { (exit 1); exit 1; }; }
fi




ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu






























# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.5
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=5
TK_PATCH_LEVEL=".19"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241


2242
2243

























2244










2245



2246

2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411

2412
2413

2414
2415
2416
2417
2418
2419
2420
2421


2422
2423
2424

2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438




2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481



2482

2483
2484
2485
2486
2487
2488
2489
2490
2491



2492
2493
2494
2495
2496
2497
2498
2499
2500


2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524

2525
2526





















2527



2528


2529



2530
2531
2532


2533
2534
2535
2536
2537
2538







2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560

2561
2562
2563
2564
2565
2566
2567
2568
2569

2570

2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642




2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680

2681

2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693




2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706


2707



















2708
2709



2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724

2725
2726
2727
2728
2729
2730
2731
2732

2733

2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744


2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765





2766
2767
2768
2769
2770
2771
2772


2773


2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810




2811
2812
2813

2814
2815
2816
2817
2818
2819
2820
2821
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
          if test -n "$ac_tool_prefix"; then
    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5


$as_echo "no" >&6; }
fi








































  fi

fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
  fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl.exe
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl.exe
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  test -n "$ac_ct_CC" && break
done

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
fi

fi


test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }


# Provide some information about the compiler.

$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
  { { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;


esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5

  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    sed '10a\
... rest of stderr output deleted ...
         10q' conftest.err >conftest.er1
    cat conftest.er1 >&5
  fi
  rm -f conftest.er1 conftest.err
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
done

cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`

# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"

ac_rmfiles=
for ac_file in $ac_files
do
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
  esac
done
rm -f $ac_rmfiles

if { { ac_try="$ac_link_default"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :



  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.

# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile.  We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )



	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )
	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
	then :; else
	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`


	fi
	# We set ac_cv_exeext here because the later test for it is not
	# safe: cross compilers may not add the suffix if given an `-o'
	# argument, so we may need to know it at that point already.
	# Even if this section looks crufty: it has the advantage of
	# actually working.
	break;;
    * )
	break;;
  esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=

else
  ac_file=''
fi
if test -z "$ac_file"; then :
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}

as_fn_error 77 "C compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5; }





















else



  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5


$as_echo "yes" >&6; }



fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }


{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save







{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`

	  break;;
    * ) break;;
  esac
done
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }

fi

rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }

rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdio.h>
int
main ()
{
FILE *f = fopen ("conftest.out", "w");
 return ferror (f) || fclose (f) != 0;

  ;
  return 0;
}
_ACEOF
ac_clean_files="$ac_clean_files conftest.out"
# Check that the compiler produces executables we can run.  If not, either
# the compiler is broken, or we cross compile.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
$as_echo_n "checking whether we are cross compiling... " >&6; }
if test "$cross_compiling" != yes; then
  { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
  if { ac_try='./conftest$ac_cv_exeext'
  { { case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }; then
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5; }
    fi
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
$as_echo "$cross_compiling" >&6; }

rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  for ac_file in conftest.o conftest.obj conftest.*; do
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }

fi

rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

int
main ()
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  ac_compiler_gnu=yes
else



  ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
$as_echo "$ac_cv_c_compiler_gnu" >&6; }
if test $ac_compiler_gnu = yes; then
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_save_c_werror_flag=$ac_c_werror_flag
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no

   CFLAGS="-g"

   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_prog_cc_g=yes
else
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

else
  ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext





/* end confdefs.h.  */

int
main ()
{

  ;


  return 0;


}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
if ${ac_cv_prog_cc_c89+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>

struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{







|
|
|
|









|
|

|



|
<





|
|

|
|

<






|
|
|
|









|
|

|



|
<





|
|

|
|


<
<
<
<
<
<
<
<
<
|
<





|
|

|
|
|
|









|
|

|



|
<





|
|

|
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>

>
>
>
|
>




|
|
|
|










|
|





|



|
<

















|
|

|
|

<




|



|
|
|
|









|
|

|



|
<





|
|

|
|

<






|



|
|
|
|









|
|

|



|
<





|
|

|
|

<




<
<
<
<
<
<
<
<
<
|
<





|
|
|
|
>


>
|
|
|
<
|
|
|
|
>
>
|
|
|
>
|

<
<
<
<
<
<
<
|
|
<

|
>
>
>
>











|



|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
|
>
>
>
|
>
|
|
|
<
|



|
>
>
>






<
<
|
>
>
|
|
<
<
<
<





<
<

<
<
<
<
<
|


<
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
|
>
>
>
|
<
<
>
>
|
|
<

|

>
>
>
>
>
>
>
|
|
<
<
<
<
<
<
|
|

|
|







|

>





|
|
|
|
>

>
|
|
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|

|
>
>
>
>











<
<
<
<
<
<
|
|

|
|
|
<

|





|


|
|
|
|
>

>


|
|


|
|
|
|

|
>
>
>
>













>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|



|
|
|
<
<
<
<


>
|
|
|
|

|
<
<
>
|
>
|










>
>
|
|
<
<
|
|
|
<
<
<
|
<
<
<
<
<
|
<
|
<
|
>
>
>
>
>
|
|
|
|
<
|
<
>
>
|
>
>
|
<
<
|

|

<
<
<
<
<
|
|















|
|
|
|

|

|
>
>
>
>



>
|







1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393

1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432









1433

1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462

1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610

1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641

1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656









1657

1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685







1686
1687

1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712




















1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724

1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738


1739
1740
1741
1742
1743




1744
1745
1746
1747
1748


1749





1750
1751
1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789


1790
1791
1792
1793

1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805






1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839



























































1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860






1861
1862
1863
1864
1865
1866

1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948




1949
1950
1951
1952
1953
1954
1955
1956
1957


1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975


1976
1977
1978



1979





1980

1981

1982
1983
1984
1985
1986
1987
1988
1989
1990
1991

1992

1993
1994
1995
1996
1997
1998


1999
2000
2001
2002





2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi










  CC=$ac_ct_CC

else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi

fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="cc"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi

  CC=$ac_ct_CC
else
  CC="$ac_cv_prog_CC"
fi

fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
  fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


  test -n "$ac_ct_CC" && break
done










  CC=$ac_ct_CC

fi

fi


test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
See \`config.log' for more details." >&5
echo "$as_me: error: no acceptable C compiler found in \$PATH
See \`config.log' for more details." >&2;}
   { (exit 1); exit 1; }; }

# Provide some information about the compiler.
echo "$as_me:$LINENO:" \
     "checking for C compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5

  (eval $ac_compiler --version </dev/null >&5) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
  (eval $ac_compiler -v </dev/null >&5) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
  (eval $ac_compiler -V </dev/null >&5) 2>&5
  ac_status=$?







  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }


cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5




















  (eval $ac_link_default) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; then
  # Find the output, starting from the most likely.  This scheme is
# not robust to junk in `.', hence go to wildcards (a.*) only as a last
# resort.

# Be careful to initialize this variable, since it used to be cached.
# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
ac_cv_exeext=
# b.out is created by i960 compilers.

for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
	;;
    conftest.$ac_ext )
	# This is the source file.
	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )


	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	# FIXME: I believe we export ac_cv_exeext for Libtool,
	# but it would be cool to find out if it's true.  Does anybody
	# maintain Libtool? --akim.
	export ac_cv_exeext




	break;;
    * )
	break;;
  esac
done


else





  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5


{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
See \`config.log' for more details." >&5
echo "$as_me: error: C compiler cannot create executables
See \`config.log' for more details." >&2;}
   { (exit 77); exit 77; }; }
fi

ac_exeext=$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_file" >&5
echo "${ECHO_T}$ac_file" >&6

# Check the compiler produces executables we can run.  If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether the C compiler works" >&5
echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
# If not cross compiling, check that we can run a simple program.
if test "$cross_compiling" != yes; then
  if { ac_try='./$ac_file'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details." >&5
echo "$as_me: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details." >&2;}
   { (exit 1); exit 1; }; }
    fi


  fi
fi
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6


rm -f a.out a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
# Check the compiler produces executables we can run.  If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $cross_compiling" >&5
echo "${ECHO_T}$cross_compiling" >&6

echo "$as_me:$LINENO: checking for suffix of executables" >&5
echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6






if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; then
  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	  export ac_cv_exeext
	  break;;
    * ) break;;
  esac
done
else
  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details." >&5
echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details." >&2;}
   { (exit 1); exit 1; }; }
fi

rm -f conftest$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
echo "${ECHO_T}$ac_cv_exeext" >&6

rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT



























































echo "$as_me:$LINENO: checking for suffix of object files" >&5
echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
if test "${ac_cv_objext+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.o conftest.obj






if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; then
  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do

  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
See \`config.log' for more details." >&5
echo "$as_me: error: cannot compute suffix of object files: cannot compile
See \`config.log' for more details." >&2;}
   { (exit 1); exit 1; }; }
fi

rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
echo "${ECHO_T}$ac_cv_objext" >&6
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
if test "${ac_cv_c_compiler_gnu+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

int
main ()
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_compiler_gnu=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_compiler_gnu=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu

fi
echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
GCC=`test $ac_compiler_gnu = yes && echo yes`




ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
CFLAGS="-g"
echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
if test "${ac_cv_prog_cc_g+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF


/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?


  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5



  echo "$as_me:$LINENO: \$? = $ac_status" >&5





  (exit $ac_status); } &&

	 { ac_try='test -z "$ac_c_werror_flag"

			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?

  echo "$as_me:$LINENO: \$? = $ac_status" >&5

  (exit $ac_status); }; }; then
  ac_cv_prog_cc_g=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5



ac_cv_prog_cc_g=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi





echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
if test "$ac_test_CFLAGS" = set; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi
echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
if test "${ac_cv_prog_cc_stdc+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  ac_cv_prog_cc_stdc=no
ac_save_CC=$CC
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861


2862




2863
2864
2865


2866



















2867





2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884


2885
2886
2887
2888
2889

















































2890

































2891










2892
















































2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907




2908
2909
2910
2911
2912
2913
2914
2915


2916



















2917




2918
2919
2920
2921
2922
2923
2924
2925

2926
2927
2928
2929
2930
2931
2932
  va_end (v);
  return s;
}

/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
   function prototypes and stuff, but not '\xHH' hex character constants.
   These don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF


for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \




	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"


  if ac_fn_c_try_compile "$LINENO"; then :



















  ac_cv_prog_cc_c89=$ac_arg





fi
rm -f core conftest.err conftest.$ac_objext
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in
  x)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
  xno)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
  *)


    CC="$CC $ac_cv_prog_cc_c89"
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c89" != xno; then :



















































































fi



























































ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
if ${ac_cv_c_inline+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
#endif

_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  ac_cv_c_inline=$ac_kw




fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  test "$ac_cv_c_inline" != no && break
done

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
$as_echo "$ac_cv_c_inline" >&6; }


case $ac_cv_c_inline in
  inline | yes) ;;
  *)
    case $ac_cv_c_inline in
      no) ac_val=;;
      *) ac_val=$ac_cv_c_inline;;







|


|


<
<
<
<
<














>
>
|
>
>
>
>
|


>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>

|
<

|



|
|
<
<
<
|
|
|

>
>
|
<
<

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
|
|
|



|
>
>
>
>








>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>

|
<



|
|
>







2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064





2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118

2119
2120
2121
2122
2123
2124
2125



2126
2127
2128
2129
2130
2131
2132


2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
  va_end (v);
  return s;
}

/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
   function prototypes and stuff, but not '\xHH' hex character constants.
   These don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std1 is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std1.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];






int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF
# Don't try gcc -ansi; that turns off useful extensions and
# breaks some systems' header files.
# AIX			-qlanglvl=ansi
# Ultrix and OSF/1	-std1
# HP-UX 10.20 and later	-Ae
# HP-UX older versions	-Aa -D_HPUX_SOURCE
# SVR4			-Xc -D__EXTENSIONS__
for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"
  rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_prog_cc_stdc=$ac_arg
break
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

fi
rm -f conftest.err conftest.$ac_objext

done
rm -f conftest.$ac_ext conftest.$ac_objext
CC=$ac_save_CC

fi

case "x$ac_cv_prog_cc_stdc" in



  x|xno)
    echo "$as_me:$LINENO: result: none needed" >&5
echo "${ECHO_T}none needed" >&6 ;;
  *)
    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
    CC="$CC $ac_cv_prog_cc_stdc" ;;


esac

# Some people use a C++ compiler to compile C.  Since we use `exit',
# in C++ we need to declare it.  In case someone uses the same compiler
# for both compiling C and C++ we need to have the C++ compiler decide
# the declaration of exit, since it's the most demanding environment.
cat >conftest.$ac_ext <<_ACEOF
#ifndef __cplusplus
  choke me
#endif
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  for ac_declaration in \
   '' \
   'extern "C" void std::exit (int) throw (); using std::exit;' \
   'extern "C" void std::exit (int); using std::exit;' \
   'extern "C" void exit (int) throw ();' \
   'extern "C" void exit (int);' \
   'void exit (int);'
do
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_declaration
#include <stdlib.h>
int
main ()
{
exit (42);
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  :
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

continue
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_declaration
int
main ()
{
exit (42);
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  break
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
  echo '#ifdef __cplusplus' >>confdefs.h
  echo $ac_declaration      >>confdefs.h
  echo '#endif'             >>confdefs.h
fi

else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


echo "$as_me:$LINENO: checking for inline" >&5
echo $ECHO_N "checking for inline... $ECHO_C" >&6
if test "${ac_cv_c_inline+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
#endif

_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_c_inline=$ac_kw; break
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

done

fi
echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
echo "${ECHO_T}$ac_cv_c_inline" >&6


case $ac_cv_c_inline in
  inline | yes) ;;
  *)
    case $ac_cv_c_inline in
      no) ac_val=;;
      *) ac_val=$ac_cv_c_inline;;
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969




2970
2971
2972
2973
2974
2975
2976
2977








2978









2979
2980



2981
2982
2983
2984
2985
2986
2987
2988




2989
2990
2991








2992









2993
2994
2995



2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028




3029
3030
3031
3032
3033
3034
3035
3036








3037









3038
3039



3040
3041
3042
3043
3044
3045
3046
3047




3048
3049
3050








3051









3052
3053
3054



3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070

3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215




3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229


3230



















3231
3232



3233
3234
3235
3236
3237
3238
3239




3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256




3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276




3277
3278
3279
3280
3281
3282
3283
esac

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if ${ac_cv_prog_CPP+:} false; then :
  $as_echo_n "(cached) " >&6
else
      # Double quotes because CPP needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    do
      ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF








if ac_fn_c_try_cpp "$LINENO"; then :










else



  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF








if ac_fn_c_try_cpp "$LINENO"; then :









  # Broken: success on invalid input.
continue
else



  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF








if ac_fn_c_try_cpp "$LINENO"; then :










else



  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF








if ac_fn_c_try_cpp "$LINENO"; then :









  # Broken: success on invalid input.
continue
else



  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :

else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }

fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -z "$GREP"; then
  ac_path_GREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in grep ggrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
  # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
   then ac_cv_path_EGREP="$GREP -E"
   else
     if test -z "$EGREP"; then
  ac_path_EGREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in egrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
  # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'EGREP' >> "conftest.nl"
    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP="$ac_path_EGREP"
      ac_path_EGREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_EGREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP"; then
    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_EGREP=$EGREP
fi

   fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  ac_cv_header_stdc=yes
else



  ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <stdlib.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then :
  :
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else







|
|





|
|













|
>
>
>
>








>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|

>
>
>



|

|

|
>
>
>
>



>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>



>
>
>




|



|
|











|
|









|
>
>
>
>








>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|

>
>
>



|

|

|
>
>
>
>



>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>



>
>
>




|



|
|
|

|
|
|
|
>









|
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<

|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|
|
|
|

|
>
>
>
>














>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|



|
>
>
>
>





|
|









|
>
>
>
>





|
|









|


|
>
>
>
>







2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595



























2596



2597







2598







2599


2600
2601




2602
2603















































2604











2605







2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
esac

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if test "${ac_cv_prog_CPP+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
      # Double quotes because CPP needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    do
      ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } >/dev/null; then
  if test -s conftest.err; then
    ac_cpp_err=$ac_c_preproc_warn_flag
    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
  else
    ac_cpp_err=
  fi
else
  ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
  :
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext

  # OK, works on sane cases.  Now check whether non-existent headers
  # can be detected and how.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } >/dev/null; then
  if test -s conftest.err; then
    ac_cpp_err=$ac_c_preproc_warn_flag
    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
  else
    ac_cpp_err=
  fi
else
  ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
  # Broken: success on invalid input.
continue
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
echo "$as_me:$LINENO: result: $CPP" >&5
echo "${ECHO_T}$CPP" >&6
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } >/dev/null; then
  if test -s conftest.err; then
    ac_cpp_err=$ac_c_preproc_warn_flag
    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
  else
    ac_cpp_err=
  fi
else
  ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
  :
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext

  # OK, works on sane cases.  Now check whether non-existent headers
  # can be detected and how.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } >/dev/null; then
  if test -s conftest.err; then
    ac_cpp_err=$ac_c_preproc_warn_flag
    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
  else
    ac_cpp_err=
  fi
else
  ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
  # Broken: success on invalid input.
continue
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
  :
else
  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&5
echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&2;}
   { (exit 1); exit 1; }; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


echo "$as_me:$LINENO: checking for egrep" >&5
echo $ECHO_N "checking for egrep... $ECHO_C" >&6
if test "${ac_cv_prog_egrep+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else



























  if echo a | (grep -E '(a|b)') >/dev/null 2>&1



    then ac_cv_prog_egrep='grep -E'







    else ac_cv_prog_egrep='egrep'







    fi


fi
echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5




echo "${ECHO_T}$ac_cv_prog_egrep" >&6
 EGREP=$ac_cv_prog_egrep



































































echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_header_stdc=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_header_stdc=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then
  :
else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <stdlib.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then
  :
else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then
  :
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302







3303



3304
3305





3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317

3318

3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641





































3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674

3675

3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697

3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720

3721

3722
3723
3724
3725
3726
3727
3728
int
main ()
{
  int i;
  for (i = 0; i < 256; i++)
    if (XOR (islower (i), ISLOWER (i))
	|| toupper (i) != TOUPPER (i))
      return 2;
  return 0;
}
_ACEOF







if ac_fn_c_try_run "$LINENO"; then :




else





  ac_cv_header_stdc=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
$as_echo "$ac_cv_header_stdc" >&6; }
if test $ac_cv_header_stdc = yes; then


$as_echo "#define STDC_HEADERS 1" >>confdefs.h


fi


if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$AR"; then
  ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_AR"; then
  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_AR" = x; then
    AR=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    AR=$ac_ct_AR
  fi
else
  AR="$ac_cv_prog_AR"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
$as_echo "$RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_RANLIB"; then
  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
$as_echo "$ac_ct_RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_RANLIB" = x; then
    RANLIB=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RANLIB=$ac_ct_RANLIB
  fi
else
  RANLIB="$ac_cv_prog_RANLIB"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
set dummy ${ac_tool_prefix}windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$RC"; then
  ac_cv_prog_RC="$RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RC="${ac_tool_prefix}windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
$as_echo "$RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RC"; then
  ac_ct_RC=$RC
  # Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RC+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_RC"; then
  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RC="windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_RC=$ac_cv_prog_ac_ct_RC
if test -n "$ac_ct_RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
$as_echo "$ac_ct_RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_RC" = x; then
    RC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RC=$ac_ct_RC
  fi
else
  RC="$ac_cv_prog_RC"
fi


#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat >conftest.make <<\_ACEOF
SHELL = /bin/sh
all:
	@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
  *@@@%%%=?*=@@@%%%*)
    eval ac_cv_prog_make_${ac_make}_set=yes;;
  *)
    eval ac_cv_prog_make_${ac_make}_set=no;;
esac
rm -f conftest.make
fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  SET_MAKE=
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  SET_MAKE="MAKE=${MAKE-make}"
fi


#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------









































#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
$as_echo_n "checking how to build libraries... " >&6; }
    # Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :
  enableval=$enable_shared; tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
$as_echo "shared" >&6; }
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	SHARED_BUILD=0


$as_echo "#define STATIC_BUILD 1" >>confdefs.h


    fi



#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------


    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true

# Check whether --with-tcl was given.
if test "${with_tcl+set}" = set; then :

  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
	if ${ac_cv_c_tclconfig+:} false; then :
  $as_echo_n "(cached) " >&6
else


	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
			if test -f "${with_tclconfig}"; then
			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else

		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5

		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			../tcl \







|
|


>
>
>
>
>
>
>
|
>
>
>
|

>
>
>
>
>
|

|
<

<


|
|


>
|
>







|
|
|
|









|
|

|



|
<





|
|

|
|

<






|
|
|
|









|
|

|



|
<





|
|

|
|


<
<
<
<
<
<
<
<
<
|
<







|
|
|
|









|
|

|



|
<





|
|

|
|

<






|
|
|
|









|
|

|



|
<





|
|

|
|


<
<
<
<
<
<
<
<
<
|
<







|
|
|
|









|
|

|



|
<





|
|

|
|

<






|
|
|
|









|
|

|



|
<





|
|

|
|


<
<
<
<
<
<
<
<
<
|
<









|
|

|
|
|
















|
|


|
|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
|
|
<
<
<
<
<
<
<
|
|
|
|
|
|
<

|
|


|
|


>
|
>


<

















|
|
>
|
|
<
|
|
|
|








|
|






>
|
>







2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759

2760

2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808

2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835

2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847









2848

2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876

2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914

2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926









2927

2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955

2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966

2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993

2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005









3006

3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100







3101
3102
3103
3104
3105
3106

3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120

3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142

3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
int
main ()
{
  int i;
  for (i = 0; i < 256; i++)
    if (XOR (islower (i), ISLOWER (i))
	|| toupper (i) != TOUPPER (i))
      exit(2);
  exit (0);
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  :
else
  echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

( exit $ac_status )
ac_cv_header_stdc=no
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext

fi

fi
fi
echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
echo "${ECHO_T}$ac_cv_header_stdc" >&6
if test $ac_cv_header_stdc = yes; then

cat >>confdefs.h <<\_ACEOF
#define STDC_HEADERS 1
_ACEOF

fi


if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_AR+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$AR"; then
  ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  echo "$as_me:$LINENO: result: $AR" >&5
echo "${ECHO_T}$AR" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_AR"; then
  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
echo "${ECHO_T}$ac_ct_AR" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi










  AR=$ac_ct_AR

else
  AR="$ac_cv_prog_AR"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_RANLIB+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  echo "$as_me:$LINENO: result: $RANLIB" >&5
echo "${ECHO_T}$RANLIB" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_RANLIB"; then
  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
echo "${ECHO_T}$ac_ct_RANLIB" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi










  RANLIB=$ac_ct_RANLIB

else
  RANLIB="$ac_cv_prog_RANLIB"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
set dummy ${ac_tool_prefix}windres; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_RC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$RC"; then
  ac_cv_prog_RC="$RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RC="${ac_tool_prefix}windres"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
  echo "$as_me:$LINENO: result: $RC" >&5
echo "${ECHO_T}$RC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi


fi
if test -z "$ac_cv_prog_RC"; then
  ac_ct_RC=$RC
  # Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_RC+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$ac_ct_RC"; then
  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RC="windres"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


fi
fi
ac_ct_RC=$ac_cv_prog_ac_ct_RC
if test -n "$ac_ct_RC"; then
  echo "$as_me:$LINENO: result: $ac_ct_RC" >&5
echo "${ECHO_T}$ac_ct_RC" >&6
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi










  RC=$ac_ct_RC

else
  RC="$ac_cv_prog_RC"
fi


#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
set x ${MAKE-make}
ac_make=`echo "" | sed 'y,:./+-,___p_,'`
if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.make <<\_ACEOF
SHELL = /bin/sh
all:
	@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
  *@@@%%%=?*=@@@%%%*)
    eval ac_cv_prog_make_${ac_make}_set=yes;;
  *)
    eval ac_cv_prog_make_${ac_make}_set=no;;
esac
rm -f conftest.make
fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
  echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
  SET_MAKE=
else
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
  SET_MAKE="MAKE=${MAKE-make}"
fi


#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------




#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
#--------------------------------------------------------------------


    echo "$as_me:$LINENO: checking for building with threads" >&5
echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
    # Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then
  enableval="$enable_threads"
  tcl_ok=$enableval
else
  tcl_ok=no
fi;

    if test "$tcl_ok" = "yes"; then
	echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
	TCL_THREADS=1
	cat >>confdefs.h <<\_ACEOF
#define TCL_THREADS 1
_ACEOF

	# USE_THREAD_ALLOC tells us to try the special thread-based
	# allocator that significantly reduces lock contention
	cat >>confdefs.h <<\_ACEOF
#define USE_THREAD_ALLOC 1
_ACEOF

    else
	TCL_THREADS=0
	echo "$as_me:$LINENO: result: no (default)" >&5
echo "${ECHO_T}no (default)" >&6
    fi



#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------


    echo "$as_me:$LINENO: checking how to build libraries" >&5
echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
    # Check whether --enable-shared or --disable-shared was given.







if test "${enable_shared+set}" = set; then
  enableval="$enable_shared"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi;

    if test "$tcl_ok" = "yes" ; then
	echo "$as_me:$LINENO: result: shared" >&5
echo "${ECHO_T}shared" >&6
	SHARED_BUILD=1
    else
	echo "$as_me:$LINENO: result: static" >&5
echo "${ECHO_T}static" >&6
	SHARED_BUILD=0

cat >>confdefs.h <<\_ACEOF
#define STATIC_BUILD 1
_ACEOF

    fi



#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------


    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true

# Check whether --with-tcl or --without-tcl was given.
if test "${with_tcl+set}" = set; then
  withval="$with_tcl"
  with_tclconfig="${withval}"
fi;

	echo "$as_me:$LINENO: checking for Tcl configuration" >&5
echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6
	if test "${ac_cv_c_tclconfig+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else


	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
			if test -f "${with_tclconfig}"; then
			    { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
   { (exit 1); exit 1; }; }
		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			../tcl \
3778
3779
3780
3781
3782
3783
3784

3785

3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821








3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885

3886
3887
3888
3889


3890

3891











3892


3893










3894
3895
3896

3897

3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989




3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003


4004



















4005
4006



4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
	    fi

fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"

	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5

	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	fi
    fi


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
    fi

    #
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    #

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi









    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

















if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then
    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better." "$LINENO" 5
fi
if test "${TCL_MINOR_VERSION}" -lt 6; then
    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better." "$LINENO" 5
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

# On IRIX 5.3, sys/types and inttypes.h are conflicting.
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
		  inttypes.h stdint.h unistd.h
do :
  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
  cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF

fi

done




    # Step 0: Enable 64 bit support?

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
$as_echo_n "checking if 64bit support is requested... " >&6; }
    # Check whether --enable-64bit was given.
if test "${enable_64bit+set}" = set; then :

  enableval=$enable_64bit; do64bit=$enableval
else
  do64bit=no
fi




    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5











$as_echo "$do64bit" >&6; }













    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""


$as_echo "#define MODULE_SCOPE extern" >>confdefs.h



    # Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CYGPATH+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$CYGPATH"; then
  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CYGPATH="cygpath -m"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
$as_echo "$CYGPATH" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


    # Extract the first word of "wine", so it can be a program name with args.
set dummy wine; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_WINE+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -n "$WINE"; then
  ac_cv_prog_WINE="$WINE" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_WINE="wine"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
WINE=$ac_cv_prog_WINE
if test -n "$WINE"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
$as_echo "$WINE" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi



    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
$as_echo_n "checking for cross-compile version of gcc... " >&6; }
if ${ac_cv_cross+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

	    #ifndef _WIN32
		#error cross-compiler
	    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  ac_cv_cross=no
else



  ac_cv_cross=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
$as_echo "$ac_cv_cross" >&6; }

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-${CC}"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
	esac
      fi







>
|
>



|
|




|
|


|
|


|
|

















>
>
>
>
>
>
>
>



















<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
|
|
|
>
|


|
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>

>
>
>
>
>
>
>
>
>
>



>
|
>




|
|
|
|









|
|

|



|
<






|
|

<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|
|
|
|

|
>
>
>
>














>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|


|
|




|






|







3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294














3295
3296
3297
3298
3299

















3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374

3375
3376
3377
3378
3379
3380
3381
3382
3383



3384
3385




















3386















3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
	    fi

fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" >&5
echo "$as_me: error: Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" >&2;}
   { (exit 1); exit 1; }; }
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6
	fi
    fi


    echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        echo "$as_me:$LINENO: result: loading" >&5
echo "${ECHO_T}loading" >&6
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6
    fi

    #
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    #

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi

    #
    # eval is required to do the TCL_DBGX substitution
    #

    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""

    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""






























#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------




















    # Step 0: Enable 64 bit support?

    echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
    # Check whether --enable-64bit or --disable-64bit was given.
if test "${enable_64bit+set}" = set; then
  enableval="$enable_64bit"
  do64bit=$enableval
else
  do64bit=no
fi;
    echo "$as_me:$LINENO: result: $do64bit" >&5
echo "${ECHO_T}$do64bit" >&6

    # Cross-compiling options for Windows/CE builds

    echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
    # Check whether --enable-wince or --disable-wince was given.
if test "${enable_wince+set}" = set; then
  enableval="$enable_wince"
  doWince=$enableval
else
  doWince=no
fi;
    echo "$as_me:$LINENO: result: $doWince" >&5
echo "${ECHO_T}$doWince" >&6

    echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6

# Check whether --with-celib or --without-celib was given.
if test "${with_celib+set}" = set; then
  withval="$with_celib"
  CELIB_DIR=$withval
else
  CELIB_DIR=NO_CELIB
fi;
    echo "$as_me:$LINENO: result: $CELIB_DIR" >&5
echo "${ECHO_T}$CELIB_DIR" >&6

    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""

cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE extern
_ACEOF


    # Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CYGPATH+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test -n "$CYGPATH"; then
  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for ac_exec_ext in '' $ac_executable_extensions; do
  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CYGPATH="cygpath -m"
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
done


  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
  echo "$as_me:$LINENO: result: $CYGPATH" >&5
echo "${ECHO_T}$CYGPATH" >&6
else



  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6




















fi

















    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5
echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6
if test "${ac_cv_cross+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

	    #ifndef _WIN32
		#error cross-compiler
	    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_cross=no
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_cross=yes
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $ac_cv_cross" >&5
echo "${ECHO_T}$ac_cv_cross" >&6

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-gcc"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-gcc"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
	esac
      fi
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084




4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098


4099



















4100
4101



4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231


4232
4233

4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278

    if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then
	conftest=/tmp/conftest.rc
	echo "STRINGTABLE BEGIN" > $conftest
	echo "101 \"name\"" >> $conftest
	echo "END" >> $conftest

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows native path bug in windres" >&5
$as_echo_n "checking for Windows native path bug in windres... " >&6; }
	cyg_conftest=`$CYGPATH $conftest`
	if { ac_try='$RC -o conftest.res.o $cyg_conftest'
  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; } ; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	    CYGPATH=echo
	fi
	conftest=
	cyg_conftest=
    fi

    if test "$CYGPATH" = "echo"; then
        DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
    fi

    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5
$as_echo_n "checking for mingw32 version of gcc... " >&6; }
if ${ac_cv_win32+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main ()
{

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  ac_cv_win32=no
else



  ac_cv_win32=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
$as_echo "$ac_cv_win32" >&6; }
	if test "$ac_cv_win32" != "yes"; then
	    as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
$as_echo_n "checking for working -municode linker flag... " >&6; }
if ${ac_cv_municode+:} false; then :
  $as_echo_n "(cached) " >&6
else

# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_link ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext conftest$ac_exeext
  if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest$ac_exeext && {
	 test "$cross_compiling" = yes ||
	 test -x conftest$ac_exeext
       }; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1
fi
  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
  # interfere with the next link command; also delete a directory that is
  # left behind by Apple's compiler.  We do this before executing the actions.
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_link
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
  ac_cv_municode=yes
else
  ac_cv_municode=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_municode" >&5
$as_echo "$ac_cv_municode" >&6; }
	CFLAGS=$hold_cflags
	if test "$ac_cv_municode" = "yes" ; then
	    extra_ldflags="$extra_ldflags -municode"
	else
	    extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
	fi
    fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
$as_echo_n "checking compiler flags... " >&6; }
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \$@"
	MAKE_STUB_LIB="\${STLIB_LD} \$@"
	POST_MAKE_LIB="\${RANLIB} \$@"
	MAKE_EXE="\${CC} -o \$@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then


		as_fn_error $? "${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." "$LINENO" 5

	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	#







|
|


|


|
|
|
|

|
|

















|
|
|
|

|
>
>
>
>














>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|


|
|

|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|



|
















|
|


|


|
|



>
>
|
|
>





|







|


|
|
|






|



<
<
<
<
<
<
<
<
<







3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579

3580






3581




















3582














3583







3584


































3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652









3653
3654
3655
3656
3657
3658
3659

    if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then
	conftest=/tmp/conftest.rc
	echo "STRINGTABLE BEGIN" > $conftest
	echo "101 \"name\"" >> $conftest
	echo "END" >> $conftest

	echo "$as_me:$LINENO: checking for Windows native path bug in windres" >&5
echo $ECHO_N "checking for Windows native path bug in windres... $ECHO_C" >&6
	cyg_conftest=`$CYGPATH $conftest`
	if { ac_try='$RC -o conftest.res.o $cyg_conftest'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } ; then
	    echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
	else
	    echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
	    CYGPATH=echo
	fi
	conftest=
	cyg_conftest=
    fi

    if test "$CYGPATH" = "echo"; then
        DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
    fi

    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	echo "$as_me:$LINENO: checking for mingw32 version of gcc" >&5
echo $ECHO_N "checking for mingw32 version of gcc... $ECHO_C" >&6
if test "${ac_cv_win32+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_win32=no
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_win32=yes
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $ac_cv_win32" >&5
echo "${ECHO_T}$ac_cv_win32" >&6
	if test "$ac_cv_win32" != "yes"; then
	    { { echo "$as_me:$LINENO: error: ${CC} cannot produce win32 executables." >&5

echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;}






   { (exit 1); exit 1; }; }




















	fi














    fi










































    echo "$as_me:$LINENO: checking compiler flags" >&5
echo $ECHO_N "checking compiler flags... $ECHO_C" >&6
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \$@"
	MAKE_STUB_LIB="\${STLIB_LD} \$@"
	POST_MAKE_LIB="\${RANLIB} \$@"
	MAKE_EXE="\${CC} -o \$@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            echo "$as_me:$LINENO: result: using static flags" >&5
echo "${ECHO_T}using static flags" >&6
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            echo "$as_me:$LINENO: result: using shared flags" >&5
echo "${ECHO_T}using shared flags" >&6

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		{ { echo "$as_me:$LINENO: error: ${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." >&5
echo "$as_me: error: ${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." >&2;}
   { (exit 1); exit 1; }; }
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX="\${DBGX}.exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\$@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.a"
	LIBFLAGSUFFIX="\${DBGX}"
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wdeclaration-after-statement -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=










	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	#
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305




4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319


4320



















4321
4322



4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
	#LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}"
	LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}"
	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    ia64)
		MACHINE="IA64"
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    *)
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

		    #ifndef _WIN64
			#error 32-bit
		    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  tcl_win_64bit=yes
else



  tcl_win_64bit=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
		if test "$tcl_win_64bit" = "yes" ; then
			do64bit=amd64
			MACHINE="AMD64"
			{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
	fi

	LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;







|
|



|
|


|
>
>
>
>














>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|


|

|
|
|
|






|
|


|


|
|



|











|
|
|










|
|


|







3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
	#LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}"
	LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}"
	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
		;;
	    ia64)
		MACHINE="IA64"
		echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
		;;
	    *)
		cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

		    #ifndef _WIN64
			#error 32-bit
		    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_win_64bit=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_win_64bit=no

fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
		if test "$tcl_win_64bit" = "yes" ; then
		    do64bit=amd64
		    MACHINE="AMD64"
		    echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            echo "$as_me:$LINENO: result: using static flags" >&5
echo "${ECHO_T}using static flags" >&6
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            echo "$as_me:$LINENO: result: using shared flags" >&5
echo "${ECHO_T}using shared flags" >&6
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX="\${DBGX}.exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.lib"
	LIBFLAGSUFFIX="\${DBGX}"

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
	fi

	LIBS="user32.lib advapi32.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;
4403
4404
4405
4406
4407
4408
4409







































































































4410

4411
4412
4413
4414
4415
4416
4417
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi








































































































	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"


	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>







3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	if test "$doWince" != "no" ; then
	    # Set defaults for common evc4/PPC2003 setup
	    # Currently Tcl requires 300+, possibly 420+ for sockets
	    CEVERSION=420; 		# could be 211 300 301 400 420 ...
	    TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
	    ARCH=ARM;		# could be ARM MIPS X86EM ...
	    PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
	    if test "$doWince" != "yes"; then
		# If !yes then the user specified something
		# Reset ARCH to allow user to skip specifying it
		ARCH=
		eval `echo $doWince | awk -F "," '{ \
	if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
	if ($1 < 400)	  { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
	if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
	if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
	if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
		}'`
		if test "x${ARCH}" = "x" ; then
		    ARCH=$TARGETCPU;
		fi
	    fi
	    OSVERSION=WCE$CEVERSION;
	    if test "x${WCEROOT}" = "x" ; then
		WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
		if test ! -d "${WCEROOT}" ; then
		    WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
		fi
	    fi
	    if test "x${SDKROOT}" = "x" ; then
		SDKROOT="C:/Program Files/Windows CE Tools"
		if test ! -d "${SDKROOT}" ; then
		    SDKROOT="C:/Windows CE Tools"
		fi
	    fi
	    # The space-based-path will work for the Makefile, but will
	    # not work if AC_TRY_COMPILE is called.
	    WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
	    SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
	    if test ! -d "${CELIB_DIR}/inc"; then
		{ { echo "$as_me:$LINENO: error: Invalid celib directory \"${CELIB_DIR}\"" >&5
echo "$as_me: error: Invalid celib directory \"${CELIB_DIR}\"" >&2;}
   { (exit 1); exit 1; }; }
	    fi
	    if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\
		-o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
		{ { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
   { (exit 1); exit 1; }; }
	    else
		CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
		if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
		    CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
		fi
		CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
	    fi
	fi

	if test "$doWince" != "no" ; then
	    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
	    if test "${TARGETCPU}" = "X86"; then
		CC="${CEBINROOT}/cl.exe"
	    else
		CC="${CEBINROOT}/cl${ARCH}.exe"
	    fi
	    CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
	    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
	    arch=`echo ${ARCH} | awk '{print tolower($0)}'`
	    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS"
	    for i in $defs ; do
		cat >>confdefs.h <<_ACEOF
#define $i 1
_ACEOF

	    done
#	    if test "${ARCH}" = "X86EM"; then
#		AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
#	    fi
	    cat >>confdefs.h <<_ACEOF
#define _WIN32_WCE $CEVERSION
_ACEOF

	    cat >>confdefs.h <<_ACEOF
#define UNDER_CE $CEVERSION
_ACEOF

	    CFLAGS_DEBUG="-nologo -Zi -Od"
	    CFLAGS_OPTIMIZE="-nologo -O2"
	    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
	    lflags="-nodefaultlib -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
	    LINKBIN="\"${CEBINROOT}/link.exe\""

	    if test "${CEVERSION}" -lt 400 ; then
		LIBS="coredll.lib corelibc.lib winsock.lib"
	    else
		LIBS="coredll.lib corelibc.lib ws2.lib"
	    fi
	    # celib currently stuck at wce300 status
	    #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib"
	    LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\""
	    LIBS_GUI="commctrl.lib commdlg.lib"
	else
	    LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
	fi

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450

4451

4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464




4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482







4483



4484
4485





4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497

4498

4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513




4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529


4530



















4531
4532



4533
4534
4535
4536
4537
4538
4539
4540
4541

4542

4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555




4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574


4575



















4576
4577



4578
4579
4580
4581
4582
4583
4584
4585
4586

4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609




4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622


4623



















4624
4625



4626
4627
4628
4629
4630
4631
4632
4633
4634

4635

4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646








































































































































4647
4648
4649
4650
4651
4652

4653

















































































































































































































4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671




4672
4673
4674
4675
4676
4677
4678
4679
4680
4681












4682









4683
4684



4685
4686
4687
4688
4689
4690
4691
4692
4693

4694

4695
4696
















































































































































































































































































4697
4698
4699
4700
4701











4702
4703
4704








4705
4706














4707
4708

4709

4710
4711
4712
4713
4714
4715
4716

4717

4718



4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733

4734
4735
4736
4737
4738
4739
4740
4741
4742

4743

4744

4745
4746
4747
4748

4749

4750
4751
4752
4753

4754
4755
4756
4757
4758
4759
4760
4761
4762
4763

4764

4765
4766
4767
4768
4769

4770

4771
4772

4773

4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786


4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797

4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809




4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-Fo\$@"
	CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\$@')\""

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	if test "${TARGETCPU}" != "X86"; then
	    LDFLAGS_CONSOLE="-link ${lflags}"
	    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then

	$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h


    fi

    if test "${GCC}" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
$as_echo_n "checking for SEH support in compiler... " >&6; }
if ${tcl_cv_seh+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
  tcl_cv_seh=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }

_ACEOF







if ac_fn_c_try_run "$LINENO"; then :



  tcl_cv_seh=yes
else





  tcl_cv_seh=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
$as_echo "$tcl_cv_seh" >&6; }
	if test "$tcl_cv_seh" = "no" ; then


$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h


	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
if ${tcl_cv_eh_disposition+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN

int
main ()
{

		EXCEPTION_DISPOSITION x;

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  tcl_cv_eh_disposition=yes
else



  tcl_cv_eh_disposition=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
$as_echo "$tcl_cv_eh_disposition" >&6; }
	if test "$tcl_cv_eh_disposition" = "no" ; then


$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h


	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
if ${tcl_cv_winnt_ignore_void+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN

int
main ()
{

		CHAR c;
		SHORT s;
		LONG l;

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  tcl_cv_winnt_ignore_void=yes
else



  tcl_cv_winnt_ignore_void=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then


$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h

	fi

	ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
if test "x$ac_cv_header_stdbool_h" = xyes; then :

$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h

fi



	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
$as_echo_n "checking for cast to union support... " >&6; }
if ${tcl_cv_cast_to_union+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

int
main ()
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF


if ac_fn_c_try_compile "$LINENO"; then :



















  tcl_cv_cast_to_union=yes
else



  tcl_cv_cast_to_union=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
$as_echo "$tcl_cv_cast_to_union" >&6; }
	if test "$tcl_cv_cast_to_union" = "yes"; then


$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h


	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version














































































































































#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
if test "x$ac_cv_header_errno_h" = xyes; then :



















































































































































































































else
  MAN2TCLFLAGS="-DNO_ERRNO_H"
fi




#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking availability of _strtoi64" >&5
$as_echo_n "checking availability of _strtoi64... " >&6; }
if ${tcl_cv_strtoi64+:} false; then :
  $as_echo_n "(cached) " >&6
else

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
{
_strtoi64(0,0,0)
  ;
  return 0;
}
_ACEOF












if ac_fn_c_try_link "$LINENO"; then :









  tcl_cv_strtoi64=yes
else



  tcl_cv_strtoi64=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoi64" >&5
$as_echo "$tcl_cv_strtoi64" >&6; }
if test $tcl_cv_strtoi64 = no; then


$as_echo "#define NO_STRTOI64 1" >>confdefs.h


fi

















































































































































































































































































#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------












ac_fn_c_check_header_compile "$LINENO" "uxtheme.h" "ac_cv_header_uxtheme_h" "#include <windows.h>
"
if test "x$ac_cv_header_uxtheme_h" = xyes; then :








  $as_echo "#define HAVE_UXTHEME_H 1" >>confdefs.h















else
  { $as_echo "$as_me:${as_lineno-$LINENO}: xpnative theme will be unavailable" >&5

$as_echo "$as_me: xpnative theme will be unavailable" >&6;}

fi


ac_fn_c_check_header_compile "$LINENO" "vssym32.h" "ac_cv_header_vssym32_h" "#include <windows.h>
#include <uxtheme.h>
"
if test "x$ac_cv_header_vssym32_h" = xyes; then :

  $as_echo "#define HAVE_VSSYM32_H 1" >>confdefs.h





fi



#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
$as_echo_n "checking for build with symbols... " >&6; }
    # Check whether --enable-symbols was given.
if test "${enable_symbols+set}" = set; then :

  enableval=$enable_symbols; tcl_ok=$enableval
else
  tcl_ok=no
fi

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'



$as_echo "#define NDEBUG 1" >>confdefs.h


	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }


	$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h


    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'

	if test "$tcl_ok" = "yes"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
$as_echo "yes (standard debugging)" >&6; }
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then


$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h


    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then


$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h




$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h


    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
$as_echo "enabled symbols mem compile debugging" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "enabled $tcl_ok debugging" >&6; }
	fi
    fi




#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5
$as_echo_n "checking whether to embed manifest... " >&6; }
    # Check whether --enable-embedded-manifest was given.
if test "${enable_embedded_manifest+set}" = set; then :
  enableval=$enable_embedded_manifest; embed_ok=$enableval

else
  embed_ok=yes
fi


    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
       -a "$GCC" != "yes" ; then
	# Add the magic to embed the manifest into the dll/exe
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext




/* end confdefs.h.  */

#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "manifest needed" >/dev/null 2>&1; then :

	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
	# Could add 'if test -f' check, but manifest should be created
	# in this compiler case
	# Add in a manifest argument that may be specified
	# XXX Needs improvement so that the test for existence accounts
	# XXX for a provided (known) manifest
	VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;2 ; fi"
	VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;1 ; fi"
	result=yes
	if test "xwish.exe.manifest" != x ; then
	    result="yes (wish.exe.manifest)"
	fi

fi
rm -f conftest*

    fi
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
$as_echo "$result" >&6; }





    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh in Tcl build directory" >&5
$as_echo_n "checking for tclsh in Tcl build directory... " >&6; }
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
$as_echo "$BUILD_TCLSH" >&6; }



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
$as_echo_n "checking for tclsh... " >&6; }

    if ${ac_cv_path_tclsh+:} false; then :
  $as_echo_n "(cached) " >&6
else

	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \
		    `ls -r $dir/tclsh* 2> /dev/null` ; do
		if test x"$ac_cv_path_tclsh" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_tclsh=$j
			break
		    fi
		fi
	    done
	done

fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
$as_echo "$TCLSH_PROG" >&6; }
    else
	# It is not an error if an installed version of Tcl can't be located.
	TCLSH_PROG=""
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
$as_echo "No tclsh found on PATH" >&6; }
    fi



#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------







|









>
|
>




|
|
|
|

|


|
>
>
>
>


















>
>
>
>
>
>
>
|
>
>
>


>
>
>
>
>
|

|
<


<

|
|


>
|
>









|
|
|
|

|
>
>
>
>
















>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|


|
|


>
|
>







|
|
|
|

|
>
>
>
>



















>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|


|
|


>
|
|
<

<
<
<
<
<
|
<
<





|
|
|
|

|
>
>
>
>













>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
|

|


|
|


>
|
>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<
<
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
|
|
|


|
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>


>
>
>
|

|
|

|
|


>
|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
|
>

|
|
|
|
<
|
>
|
>

>
>
>











|
|
|
|
>
|


|
<




>

>
|
>

|
|

>
|
>




>

|
|







>
|
>





>
|
>


>
|
>





|
|

|
|



>
>






|
|
|
|
|
>


|
<







|
>
>
>
>








|


















|
|





|
|
|
|
|



|
|

|
|




















|
|



|
|







3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022

4023
4024

4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181

4182





4183


4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401


4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010

5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038

5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115

5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-Fo\$@"
	CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\$@')\""

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then
	    LDFLAGS_CONSOLE="-link ${lflags}"
	    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	cat >>confdefs.h <<\_ACEOF
#define TCL_CFG_DO64BIT 1
_ACEOF

    fi

    if test "${GCC}" = "yes" ; then
	echo "$as_me:$LINENO: checking for SEH support in compiler" >&5
echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6
if test "${tcl_cv_seh+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  if test "$cross_compiling" = yes; then
  tcl_cv_seh=no
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }

_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_seh=yes
else
  echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

( exit $ac_status )
tcl_cv_seh=no
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext

fi


fi
echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5
echo "${ECHO_T}$tcl_cv_seh" >&6
	if test "$tcl_cv_seh" = "no" ; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_NO_SEH 1
_ACEOF

	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5
echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6
if test "${tcl_cv_eh_disposition+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN

int
main ()
{

		EXCEPTION_DISPOSITION x;

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_eh_disposition=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_cv_eh_disposition=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5
echo "${ECHO_T}$tcl_cv_eh_disposition" >&6
	if test "$tcl_cv_eh_disposition" = "no" ; then

cat >>confdefs.h <<\_ACEOF
#define EXCEPTION_DISPOSITION int
_ACEOF

	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5
echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6
if test "${tcl_cv_winnt_ignore_void+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN

int
main ()
{

		CHAR c;
		SHORT s;
		LONG l;

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_winnt_ignore_void=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_cv_winnt_ignore_void=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5
echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_WINNT_IGNORE_VOID 1
_ACEOF







	fi



	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	echo "$as_me:$LINENO: checking for cast to union support" >&5
echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
if test "${tcl_cv_cast_to_union+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

int
main ()
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_cast_to_union=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_cv_cast_to_union=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
	if test "$tcl_cv_cast_to_union" = "yes"; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_CAST_TO_UNION 1
_ACEOF

	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version






echo "$as_me:$LINENO: checking for intptr_t" >&5
echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6
if test "${ac_cv_type_intptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

#include <stdint.h>


int
main ()
{
if ((intptr_t *) 0)
  return 0;
if (sizeof (intptr_t))
  return 0;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_type_intptr_t=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_type_intptr_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5
echo "${ECHO_T}$ac_cv_type_intptr_t" >&6
if test $ac_cv_type_intptr_t = yes; then

cat >>confdefs.h <<_ACEOF
#define HAVE_INTPTR_T 1
_ACEOF


fi
echo "$as_me:$LINENO: checking for uintptr_t" >&5
echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
if test "${ac_cv_type_uintptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

#include <stdint.h>


int
main ()
{
if ((uintptr_t *) 0)
  return 0;
if (sizeof (uintptr_t))
  return 0;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_type_uintptr_t=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_type_uintptr_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
if test $ac_cv_type_uintptr_t = yes; then

cat >>confdefs.h <<_ACEOF
#define HAVE_UINTPTR_T 1
_ACEOF


fi


#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------



# On IRIX 5.3, sys/types and inttypes.h are conflicting.









for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
		  inttypes.h stdint.h unistd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default

#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  eval "$as_ac_Header=yes"
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

eval "$as_ac_Header=no"
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
if test `eval echo '${'$as_ac_Header'}'` = yes; then
  cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF

fi

done


if test "${ac_cv_header_errno_h+set}" = set; then
  echo "$as_me:$LINENO: checking for errno.h" >&5
echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
if test "${ac_cv_header_errno_h+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
echo "${ECHO_T}$ac_cv_header_errno_h" >&6
else
  # Is the header compilable?
echo "$as_me:$LINENO: checking errno.h usability" >&5
echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default
#include <errno.h>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_header_compiler=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6

# Is the header present?
echo "$as_me:$LINENO: checking errno.h presence" >&5
echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <errno.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } >/dev/null; then
  if test -s conftest.err; then
    ac_cpp_err=$ac_c_preproc_warn_flag
    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
  else
    ac_cpp_err=
  fi
else
  ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
  ac_header_preproc=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6

# So?  What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
  yes:no: )
    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
    ac_header_preproc=yes
    ;;
  no:yes:* )
    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
    (
      cat <<\_ASBOX
## ----------------------------- ##
## Report this to the tk lists.  ##
## ----------------------------- ##
_ASBOX
    ) |
      sed "s/^/$as_me: WARNING:     /" >&2
    ;;
esac
echo "$as_me:$LINENO: checking for errno.h" >&5
echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
if test "${ac_cv_header_errno_h+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  ac_cv_header_errno_h=$ac_header_preproc
fi
echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
echo "${ECHO_T}$ac_cv_header_errno_h" >&6

fi
if test $ac_cv_header_errno_h = yes; then
  :
else
  MAN2TCLFLAGS="-DNO_ERRNO_H"
fi




#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

echo "$as_me:$LINENO: checking availability of _strtoi64" >&5
echo $ECHO_N "checking availability of _strtoi64... $ECHO_C" >&6
if test "${tcl_cv_strtoi64+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

    cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
{
_strtoi64(0,0,0)
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_strtoi64=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_cv_strtoi64=no
fi
rm -f conftest.err conftest.$ac_objext \
      conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $tcl_cv_strtoi64" >&5
echo "${ECHO_T}$tcl_cv_strtoi64" >&6
if test $tcl_cv_strtoi64 = no; then

cat >>confdefs.h <<\_ACEOF
#define NO_STRTOI64 1
_ACEOF

fi

echo "$as_me:$LINENO: checking for intptr_t" >&5
echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6
if test "${ac_cv_type_intptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
if ((intptr_t *) 0)
  return 0;
if (sizeof (intptr_t))
  return 0;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_type_intptr_t=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_type_intptr_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5
echo "${ECHO_T}$ac_cv_type_intptr_t" >&6
if test $ac_cv_type_intptr_t = yes; then


cat >>confdefs.h <<\_ACEOF
#define HAVE_INTPTR_T 1
_ACEOF

else

    echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5
echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6
if test "${tcl_cv_intptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

    for tcl_cv_intptr_t in "int" "long" "__int64" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))];
test_array [0] = 0

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_ok=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_ok=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5
echo "${ECHO_T}$tcl_cv_intptr_t" >&6
    if test "$tcl_cv_intptr_t" != none; then

cat >>confdefs.h <<_ACEOF
#define intptr_t $tcl_cv_intptr_t
_ACEOF

    fi

fi

echo "$as_me:$LINENO: checking for uintptr_t" >&5
echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
if test "${ac_cv_type_uintptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
if ((uintptr_t *) 0)
  return 0;
if (sizeof (uintptr_t))
  return 0;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_type_uintptr_t=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_type_uintptr_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
if test $ac_cv_type_uintptr_t = yes; then


cat >>confdefs.h <<\_ACEOF
#define HAVE_UINTPTR_T 1
_ACEOF

else

    echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5
echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6
if test "${tcl_cv_uintptr_t+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned __int64" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))];
test_array [0] = 0

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_ok=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_ok=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5
echo "${ECHO_T}$tcl_cv_uintptr_t" >&6
    if test "$tcl_cv_uintptr_t" != none; then

cat >>confdefs.h <<_ACEOF
#define uintptr_t $tcl_cv_uintptr_t
_ACEOF

    fi

fi


#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------

echo "$as_me:$LINENO: checking for uxtheme.h" >&5
echo $ECHO_N "checking for uxtheme.h... $ECHO_C" >&6
if test "${ac_cv_header_uxtheme_h+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <windows.h>

#include <uxtheme.h>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_header_uxtheme_h=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_header_uxtheme_h=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_header_uxtheme_h" >&5
echo "${ECHO_T}$ac_cv_header_uxtheme_h" >&6

if test $ac_cv_header_uxtheme_h = yes; then
  cat >>confdefs.h <<\_ACEOF
#define HAVE_UXTHEME_H 1
_ACEOF

else
  { echo "$as_me:$LINENO: xpnative theme will be unavailable" >&5
echo "$as_me: xpnative theme will be unavailable" >&6;}
fi



#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------


    echo "$as_me:$LINENO: checking for build with symbols" >&5
echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
    # Check whether --enable-symbols or --disable-symbols was given.
if test "${enable_symbols+set}" = set; then
  enableval="$enable_symbols"
  tcl_ok=$enableval
else
  tcl_ok=no
fi;

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	DBGX=""

cat >>confdefs.h <<\_ACEOF
#define NDEBUG 1
_ACEOF

	echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6

	cat >>confdefs.h <<\_ACEOF
#define TCL_CFG_OPTIMIZED 1
_ACEOF

    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	DBGX=g
	if test "$tcl_ok" = "yes"; then
	    echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
echo "${ECHO_T}yes (standard debugging)" >&6
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then

cat >>confdefs.h <<\_ACEOF
#define TCL_MEM_DEBUG 1
_ACEOF

    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then

cat >>confdefs.h <<\_ACEOF
#define TCL_COMPILE_DEBUG 1
_ACEOF


cat >>confdefs.h <<\_ACEOF
#define TCL_COMPILE_STATS 1
_ACEOF

    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5
echo "${ECHO_T}enabled symbols mem compile debugging" >&6
	else
	    echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
echo "${ECHO_T}enabled $tcl_ok debugging" >&6
	fi
    fi


TK_DBGX=${DBGX}

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------


    echo "$as_me:$LINENO: checking whether to embed manifest" >&5
echo $ECHO_N "checking whether to embed manifest... $ECHO_C" >&6
    # Check whether --enable-embedded-manifest or --disable-embedded-manifest was given.
if test "${enable_embedded_manifest+set}" = set; then
  enableval="$enable_embedded_manifest"
  embed_ok=$enableval
else
  embed_ok=yes
fi;


    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
       -a "$GCC" != "yes" ; then
	# Add the magic to embed the manifest into the dll/exe
	cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "manifest needed" >/dev/null 2>&1; then

	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
	# Could add 'if test -f' check, but manifest should be created
	# in this compiler case
	# Add in a manifest argument that may be specified
	# XXX Needs improvement so that the test for existence accounts
	# XXX for a provided (known) manifest
	VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;2 ; fi"
	VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;1 ; fi"
	result=yes
	if test "xwish.exe.manifest" != x ; then
	    result="yes (wish.exe.manifest)"
	fi

fi
rm -f conftest*

    fi
    echo "$as_me:$LINENO: result: $result" >&5
echo "${ECHO_T}$result" >&6





    echo "$as_me:$LINENO: checking for tclsh in Tcl build directory" >&5
echo $ECHO_N "checking for tclsh in Tcl build directory... $ECHO_C" >&6
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}
    echo "$as_me:$LINENO: result: $BUILD_TCLSH" >&5
echo "${ECHO_T}$BUILD_TCLSH" >&6



    echo "$as_me:$LINENO: checking for tclsh" >&5
echo $ECHO_N "checking for tclsh... $ECHO_C" >&6

    if test "${ac_cv_path_tclsh+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \
		    `ls -r $dir/tclsh* 2> /dev/null` ; do
		if test x"$ac_cv_path_tclsh" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_tclsh=$j
			break
		    fi
		fi
	    done
	done

fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	echo "$as_me:$LINENO: result: $TCLSH_PROG" >&5
echo "${ECHO_T}$TCLSH_PROG" >&6
    else
	# It is not an error if an installed version of Tcl can't be located.
	TCLSH_PROG=""
	echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5
echo "${ECHO_T}No tclsh found on PATH" >&6
    fi



#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------
4898
4899
4900
4901
4902
4903
4904

4905



4906
4907
4908
4909
4910
4911
4912
TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"

eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"




eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names
eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"







>
|
>
>
>







5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=\"${LIBPREFIX}tk${VER}${LIBSUFFIX}\""
else
 eval "TK_LIB_FILE=\"${LIBPREFIX}tk${VER}${DLLSUFFIX}.a\""
fi

eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names
eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
4930
4931
4932
4933
4934
4935
4936



4937

4938
4939



4940

4941
4942
4943
4944
4945
4946
4947

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then



    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"

    TK_RES=""
else



    RC_DEFINES=""

    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in







>
>
>
|
>


>
>
>
|
>







5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
    else
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    fi
    TK_RES=""
else
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} DEBUG"
    else
        RC_DEFINES=""
    fi
    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in
4980
4981
4982
4983
4984
4985
4986
4987




4988
4989
4990
4991
4992
4993
4994







# win/tcl.m4 doesn't set (LDFLAGS)


















|
>
>
>
>







5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328



















5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086

5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126















5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148

5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162








5163

5164
5165
5166
5167
5168
5169
5170

5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324

5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428

5429
5430
5431
5432

5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455

5456
5457
5458








5459
5460


5461













5462
5463
5464
5465
5466

5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487



5488








5489


5490









5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505


5506
5507

5508
5509


5510
5511



5512


5513
5514
5515
5516



5517



5518
5519
5520



5521
5522
5523




5524
5525
5526
5527

5528
5529
5530
5531
5532


5533
5534








5535



5536
5537
5538
5539
5540

5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570


5571
5572
5573
5574

5575
5576
5577
5578








5579
5580
5581
5582
5583
5584
5585
5586
5587
5588

5589
5590
5591
5592
5593

5594
5595
5596

5597



5598



5599

5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629

5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647

5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666




5667
5668
5669
5670


5671
5672
5673
5674
5675







5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693


5694
5695

5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713

5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742

5743
5744
5745
5746
5747

5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774

5775
5776
5777
5778
5779
5780
5781
5782
5783


5784
5785

5786
5787

5788

5789

5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801

5802
5803
5804
5805

5806
5807
5808
5809
5810
5811

5812
5813
5814
5815
5816
5817
5818
5819
5820


5821









5822
5823





5824
5825





5826
5827


5828
5829
5830
5831
5832






5833
5834
5835
5836
5837
5838

5839
5840
5841


5842
5843

5844
5845
5846
5847
5848


5849
5850
5851
5852
5853


5854
5855

5856
5857
5858
5859

5860
5861
5862


5863
5864
5865
5866
5867
5868



5869
5870
5871


5872



5873
5874
5875
5876
5877
5878

5879
5880
5881
5882
5883
5884
5885
5886
5887
5888


5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903








5904





5905


5906
5907
5908
5909

5910









5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926




5927
5928
5929
5930
5931



5932
5933
5934
5935
5936
5937
5938
5939

5940
5941
5942






5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019

6020
6021
6022
6023
6024
6025
6026
6027
6028















6029
6030
6031
6032
6033
6034
6035
6036
6037





6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059

6060

6061

6062
6063
6064
6065
6066
6067
6068
































6069






6070
6071
6072
6073




















6074
6075
6076

6077
6078
6079
6080
6081


6082
6083
6084
6085
6086
6087
6088
6089
6090
6091

6092
6093
6094
6095
6096
6097
6098

6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109


6110

6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159

6160

6161
6162
6163

6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195



# undefined at this point for win











ac_config_files="$ac_config_files Makefile tkConfig.sh wish.exe.manifest"

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # `set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # `set' quotes correctly as required by POSIX, so do not add quotes.

      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
















# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
# take arguments), then branch to the quote section.  Otherwise,
# look for a macro that doesn't take arguments.
ac_script='
:mline
/\\$/{
 N
 s,\\\n,,
 b mline
}
t clear
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any

:quote
s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
s/\[/\\&/g
s/\]/\\&/g
s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'








DEFS=`sed -n "$ac_script" confdefs.h`



ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.

  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs



: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.

debug=false
ac_cs_recheck=false
ac_cs_silent=false

SHELL=\${CONFIG_SHELL-$SHELL}
export SHELL
_ASEOF
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi


as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '
    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi
  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'
fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C

export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
} # as_fn_set_status

# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
  set +e
  as_fn_set_status $1
  exit $1
} # as_fn_exit

# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
  as_expr=false
fi

if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi

if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
  as_dirname=dirname
else
  as_dirname=false
fi


as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||

$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`

# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits

ECHO_C= ECHO_N= ECHO_T=

case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in








  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;


  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null













       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac


rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'



  fi








else


  as_ln_s='cp -pR'









fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null


# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{

  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {


    as_dirs=
    while :; do

      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(


      *) as_qdir=$as_dir;;
      esac



      as_dirs="'$as_qdir' $as_dirs"


      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \



	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||



$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/



	    q
	  }
	  /^X\(\/\/\)[^/].*/{




	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{

	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/


	    q
	  }








	  s/.*/./; q'`



      test -d "$as_dir" && break
    done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"



} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi


# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"


exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##


## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1


cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.








ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@


on `(hostname || uname -n) 2>/dev/null | sed 1q`
"

_ACEOF


case $ac_config_files in *"
"*) set x $ac_config_files; shift; ac_config_files=$*;;
esac











cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
config_files="$ac_config_files"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit
      --config     print configuration, then exit
  -q, --quiet, --silent
                   do not print progress messages
  -d, --debug      don't remove temporary files
      --recheck    update $as_me by reconfiguring in the same conditions
      --file=FILE[:TEMPLATE]
                   instantiate the configuration file FILE

Configuration files:
$config_files

Report bugs to the package provider."

_ACEOF

cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
config.status
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
test -n "\$AWK" || AWK=awk
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# The default lists apply if the user does not specify any file.

ac_need_defaults=:
while test $# != 0
do
  case $1 in
  --*=?*)
    ac_option=`expr "X$1" : 'X\([^=]*\)='`
    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
    ac_shift=:
    ;;
  --*=)
    ac_option=`expr "X$1" : 'X\([^=]*\)='`
    ac_optarg=
    ac_shift=:
    ;;
  *)
    ac_option=$1
    ac_optarg=$2
    ac_shift=shift
    ;;




  esac

  case $ac_option in
  # Handling of the options.


  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )







    $as_echo "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.


  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;


  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then

  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  CONFIG_SHELL='$SHELL'
  export CONFIG_SHELL
  exec "\$@"
fi

_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
exec 5>>config.log
{
  echo
  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
  $as_echo "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1

# Handling of arguments.
for ac_config_target in $ac_config_targets
do
  case $ac_config_target in

    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
    "tkConfig.sh") CONFIG_FILES="$CONFIG_FILES tkConfig.sh" ;;
    "wish.exe.manifest") CONFIG_FILES="$CONFIG_FILES wish.exe.manifest" ;;

  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;

  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
  trap 'as_fn_exit 1' 1 2 13 15
}

# Create a (secure) tmp directory for tmp files.

{
  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
  test -d "$tmp"
}  ||
{
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")


} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp


# Set up the scripts for CONFIG_FILES section.

# No need to generate them if there are no CONFIG_FILES.

# This happens for instance with `./config.status config.h'.

if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
if test "x$ac_cr" = x; then
  eval ac_cr=\$\'\\r\'
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then

  ac_cs_awk_cr='\\r'
else
  ac_cs_awk_cr=$ac_cr
fi


echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF


{

  echo "cat >conf$$subs.awk <<_ACEOF" &&
  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
  echo "_ACEOF"
} >conf$$subs.sh ||
  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
  . ./conf$$subs.sh ||


    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5










  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`





  if test $ac_delim_n = $ac_delim_num; then
    break





  elif $ac_last_try; then
    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5


  else
    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
  fi
done
rm -f conf$$subs.sh







cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h

s/^/S["/; s/!.*/"]=/
p
g


s/^[^!]*!//
:repl

t repl
s/'"$ac_delim"'$//
t delim
:nl
h


s/\(.\{148\}\)..*/\1/
t more1
s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
p
n


b repl
:more1

s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{148\}//

t nl
:delim
h


s/\(.\{148\}\)..*/\1/
t more2
s/["\\]/\\&/g; s/^/"/; s/$/"/
p
b
:more2



s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g


s/.\{148\}//



t delim
' <conf$$subs.awk | sed '
/^[^""]/{
  N
  s/\n//
}

' >>$CONFIG_STATUS || ac_write_fail=1
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
  for (key in S) S_is_set[key] = 1
  FS = ""

}
{


  line = $ 0
  nfields = split(line, field, "@")
  substed = 0
  len = length(field[1])
  for (i = 2; i < nfields; i++) {
    key = field[i]
    keylen = length(key)
    if (S_is_set[key]) {
      value = S[key]
      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
      len += length(value) + length(field[++i])
      substed = 1
    } else
      len += 1 + keylen
  }














  print line


}

_ACAWK
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1









if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
  cat
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF

# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
h
s///




s/^/:/
s/[	 ]*$/:/
s/:\$(srcdir):/:/g
s/:\${srcdir}:/:/g
s/:@srcdir@:/:/g



s/^:*//
s/:*$//
x
s/\(=[	 ]*\).*/\1/
G
s/\n//
s/^[^=]*=[	 ]*$//
}'

fi

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1






fi # test -n "$CONFIG_FILES"


eval set X "  :F $CONFIG_FILES      "
shift
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS
  shift
  ac_file=$1
  shift

  case $ac_mode in
  :L) ac_source=$1;;
  :[FH])
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain `:'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
    fi
    # Neutralize special characters interpreted by sed in replacement strings.
    case $configure_input in #(
    *\&* | *\|* | *\\* )
       ac_sed_conf_input=`$as_echo "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||

$as_echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }















	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`





  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix

case $srcdir in
  .)  # We are building in place.
    ac_srcdir=.

    ac_top_srcdir=$ac_top_builddir_sub

    ac_abs_top_srcdir=$ac_pwd ;;

  [\\/]* | ?:[\\/]* )  # Absolute name.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir
    ac_abs_top_srcdir=$srcdir ;;
  *) # Relative name.
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
































    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;






esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix






















  case $ac_mode in
  :F)
  #

  # CONFIG_FILE
  #

_ACEOF



cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# If the template does not know about datarootdir, expand it.
# FIXME: This hack should be removed a few years after 2.60.
ac_datarootdir_hack=; ac_datarootdir_seen=
ac_sed_dataroot='
/datarootdir/ {
  p
  q
}
/@datadir@/p

/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)

  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;


esac

_ACEOF

# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s&@top_builddir@&$ac_top_builddir_sub&;t t
s&@top_build_prefix@&$ac_top_build_prefix&;t t
s&@srcdir@&$ac_srcdir&;t t
s&@abs_srcdir@&$ac_abs_srcdir&;t t
s&@top_srcdir@&$ac_top_srcdir&;t t
s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
s&@builddir@&$ac_builddir&;t t
s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 ;;



  esac

done # for ac_tag




as_fn_exit 0
_ACEOF

ac_clean_files=$ac_clean_files_save

test $ac_write_fail = 0 ||
  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5


# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded.  So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status.  When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
  ac_cs_success=:
  ac_config_status_args=
  test "$silent" = yes &&
    ac_config_status_args="$ac_config_status_args --quiet"
  exec 5>/dev/null
  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi









<
<
<
<
<
<
<
<
|



















|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
|
|
|



|


>
|

|
<
|

<

|


|
|
|
|
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

|
<
<
<
<
<
<

|
|

|

<
>
|
|
|
|
|
<
<
<
<
<
<
|
<
<
>
>
>
>
>
>
>
>
|
>




<


>
|
<
|
<
|
|







|
<


|
|
<
|









<

|
|
|
|
|
|

|
<
|


|


<
<
|
<
|
<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<

|
<
<
<

<
|
<
<
|
<
<
<





<
|
|
>
|
|
<
<
|
|
<
<
<
<
<
|
<
|
<
<
<

<
<
<
|

<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<





|





<
<
<
<
<

>
|


|
>
|
|
<
<
<
|
<
<
<
|
|
|
|
<
|







|
>
|
<
|
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
|
>
|
<
|
<
|
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
>
>
>

>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
|
<
<
|
|
|
<
<
<
<
|
<
<

|
>
>
|
|
>
|
<
>
>
|
|
>
>
>
|
>
>
|
<
|
|
>
>
>
|
>
>
>
|
<
<
>
>
>
|
|
|
>
>
>
>
|
|
<
<
>
|
<
<
<
|
>
>
|
<
>
>
>
>
>
>
>
>
|
>
>
>
|
|
|
<
|
>

<

|





<
<
<
<
<
<
<
<
<
|








|
|
|
>
>
|
|
|

>
|
|

|
>
>
>
>
>
>
>
>
|
|
|







>
|
<
|


>
|
|
<
>

>
>
>

>
>
>

>
|
<
|

|

<

|
|
<

|


|
<
<
|


|
|




|
<

>
|
<

|
|
|

|


<
<
|
<


|
|
>




<
<
<
<
<
|
|
|


|




>
>
>
>




>
>


|
|
|
>
>
>
>
>
>
>
|
|



|
|
|
|
|

<
<





>
>
|
|
>

|
<













|

>
|
<
<
<
<
<



|
|
|
<
<
<
<
<
<

<
<
<

|
<
<


|
>
|
|
|
|
|
>


<










|

|
<
<


<
|
<
<
<
|

>



|
|


|
|
>
>
|
<
>
|
|
>
|
>
|
>
|
|

<
<
<
<
<
|
|
<
|
>
|
|
|
<
>
|
|
|
|
|
<
>
|
|
|
|
|
|
<
<
|
>
>
|
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
|
<
>
>
>
>
>
|
<
>
>
|
|
<
<
<
>
>
>
>
>
>
|
|
|
|
|
<
>
|
<
<
>
>
|
<
>
|
|
|
<
<
>
>
|
|
|
<
<
>
>
|
<
>
|
<
<
<
>
|
<
<
>
>
|
|
|
<
<
<
>
>
>
|
<
<
>
>
|
>
>
>
|
<
<
<
|
<
>
|
|
|
|
|
<
<
|
<
<
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
|
<
<

>
|
>
>
>
>
>
>
>
>
>
|
|
|
<
|
<
<
|
<
<
<
<
|
|
<
|
>
>
>
>
|
<
<
<
<
>
>
>
|
<
<
<
<
<
<
<
>
|
|
|
>
>
>
>
>
>


|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
|
|



|
>
|
|
|
<
<
|
|
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
|
<
<
<
|
>
>
>
>
>
|


|
<
<
|
|
|
<
<
<
<
|
|
<
<
|


|

>
|
>
|
>
|

|
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>

|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>
|
<
|
<
|
>
>
|
|
|
|
<
|
<
<
<
<
>
|
<
|
<
<
<
<
>
|
|
<
<
<
<
<
<
<
<
<
>
>
|
>

<
<
<
<
|
|


|


|
<
<
|
|
|
|
|
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
|
<
|
|
<
<
|
|
|
<

|
>

>

|

>

<
<
<




















|
<
<
<
<



5355
5356
5357
5358
5359
5360
5361








5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
















5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400

5401
5402

5403
5404
5405
5406
5407
5408
5409
5410
5411



5412
5413











5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445






5446
5447
5448
5449
5450
5451

5452
5453
5454
5455
5456
5457






5458


5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472

5473
5474
5475
5476

5477

5478
5479
5480
5481
5482
5483
5484
5485
5486
5487

5488
5489
5490
5491

5492
5493
5494
5495
5496
5497
5498
5499
5500
5501

5502
5503
5504
5505
5506
5507
5508
5509
5510

5511
5512
5513
5514
5515
5516


5517

5518



5519
5520













































5521

5522
5523






5524

5525










5526






5527
5528



5529

5530


5531



5532
5533
5534
5535
5536

5537
5538
5539
5540
5541


5542
5543





5544

5545



5546



5547
5548







5549






















































5550

5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561





5562
5563
5564
5565
5566
5567
5568
5569
5570



5571



5572
5573
5574
5575

5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586

5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615


5616
5617
5618

5619

5620


5621







5622





5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648


5649
5650
5651




5652


5653
5654
5655
5656
5657
5658
5659
5660

5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671

5672
5673
5674
5675
5676
5677
5678
5679
5680
5681


5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693


5694
5695



5696
5697
5698
5699

5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714

5715
5716
5717

5718
5719
5720
5721
5722
5723
5724









5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767

5768
5769
5770
5771
5772
5773

5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785

5786
5787
5788
5789

5790
5791
5792

5793
5794
5795
5796
5797


5798
5799
5800
5801
5802
5803
5804
5805
5806
5807

5808
5809
5810

5811
5812
5813
5814
5815
5816
5817
5818


5819

5820
5821
5822
5823
5824
5825
5826
5827
5828





5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871


5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883

5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900





5901
5902
5903
5904
5905
5906






5907



5908
5909


5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921

5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934


5935
5936

5937



5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952

5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963





5964
5965

5966
5967
5968
5969
5970

5971
5972
5973
5974
5975
5976

5977
5978
5979
5980
5981
5982
5983


5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004

6005
6006
6007
6008
6009
6010

6011
6012
6013
6014



6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025

6026
6027


6028
6029
6030

6031
6032
6033
6034


6035
6036
6037
6038
6039


6040
6041
6042

6043
6044



6045
6046


6047
6048
6049
6050
6051



6052
6053
6054
6055


6056
6057
6058
6059
6060
6061
6062



6063

6064
6065
6066
6067
6068
6069


6070


6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086

6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104


6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119

6120


6121




6122
6123

6124
6125
6126
6127
6128
6129




6130
6131
6132
6133







6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147

6148

















6149
6150


6151



6152











6153

6154




6155

6156
6157









6158
6159






6160
6161
6162
6163
6164
6165
6166
6167
6168
6169


6170
6171
6172

6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189


6190



6191
6192
6193
6194
6195
6196
6197
6198
6199
6200


6201
6202
6203




6204
6205


6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218

6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286

6287
6288

6289

6290
6291
6292
6293
6294
6295
6296

6297




6298
6299

6300




6301
6302
6303









6304
6305
6306
6307
6308




6309
6310
6311
6312
6313
6314
6315
6316


6317
6318
6319
6320
6321
6322
6323




6324








6325
6326
6327

6328
6329


6330
6331
6332

6333
6334
6335
6336
6337
6338
6339
6340
6341
6342



6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363




6364
6365
6366



# undefined at this point for win











                              ac_config_files="$ac_config_files Makefile tkConfig.sh wish.exe.manifest"

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
















{
  (set) 2>&1 |
    case `(ac_space=' '; set | grep ac_space) 2>&1` in
    *ac_space=\ *)
      # `set' does not quote correctly, so add quotes (double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \).
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;;
    *)
      # `set' quotes correctly as required by POSIX, so do not add quotes.
      sed -n \
	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
      ;;
    esac;

} |
  sed '

     t clear
     : clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     t end
     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     : end' >>confcache
if diff $cache_file confcache >/dev/null 2>&1; then :; else
  if test -w $cache_file; then
    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"



    cat confcache >$cache_file
  else











    echo "not updating unwritable cache $cache_file"
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

# VPATH may cause trouble with some makes, so we remove $(srcdir),
# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
s/:*\$(srcdir):*/:/;
s/:*\${srcdir}:*/:/;
s/:*@srcdir@:*/:/;
s/^\([^=]*=[	 ]*\):*/\1/;
s/:*$//;
s/^[^=]*=[	 ]*$//;
}'
fi

# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
# take arguments), then we branch to the quote section.  Otherwise,
# look for a macro that doesn't take arguments.
cat >confdef2opt.sed <<\_ACEOF






t clear
: clear
s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\),-D\1=\2,g
t quote
s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\),-D\1=\2,g
t quote

d
: quote
s,[	 `~#$^&*(){}\\|;'"<>?],\\&,g
s,\[,\\&,g
s,\],\\&,g
s,\$,$$,g






p


_ACEOF
# We use echo to avoid assuming a particular line-breaking character.
# The extra dot is to prevent the shell from consuming trailing
# line-breaks from the sub-command output.  A line-break within
# single-quotes doesn't work because, if this script is created in a
# platform that uses two characters for line-breaks (e.g., DOS), tr
# would break.
ac_LF_and_DOT=`echo; echo .`
DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
rm -f confdef2opt.sed


ac_libobjs=
ac_ltlibobjs=

for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_i=`echo "$ac_i" |
	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`

  # 2. Add them.

  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs



: ${CONFIG_STATUS=./config.status}

ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
echo "$as_me: creating $CONFIG_STATUS" >&6;}

cat >$CONFIG_STATUS <<_ACEOF
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.

debug=false
ac_cs_recheck=false
ac_cs_silent=false

SHELL=\${CONFIG_SHELL-$SHELL}
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF
## --------------------- ##
## M4sh Initialization.  ##
## --------------------- ##

# Be Bourne compatible

if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
  emulate sh
  NULLCMD=:
  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'


elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then

  set -o posix



fi
DUALCASE=1; export DUALCASE # for MKS sh















































# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then






  as_unset=unset

else










  as_unset=false






fi






# Work around bugs in pre-3.0 UWIN ksh.


$as_unset ENV MAIL MAILPATH



PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.

for as_var in \
  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
  LC_TELEPHONE LC_TIME
do


  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
    eval $as_var=C; export $as_var





  else

    $as_unset $as_var



  fi



done








# Required to use basename.






















































if expr a : '\(a\)' >/dev/null 2>&1; then

  as_expr=expr
else
  as_expr=false
fi

if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi







# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)$' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }



  	  /^X\/\(\/\/\)$/{ s//\1/; q; }



  	  /^X\/\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; q'`



# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  echo "#! /bin/sh" >conf$$.sh

  echo  "exit 0"   >>conf$$.sh
  chmod +x conf$$.sh
  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
    PATH_SEPARATOR=';'
  else
    PATH_SEPARATOR=:
  fi
  rm -f conf$$.sh
fi


  as_lineno_1=$LINENO
  as_lineno_2=$LINENO
  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
  test "x$as_lineno_1" != "x$as_lineno_2" &&
  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
  # Find who we are.  Look in the path if we contain no path at all
  # relative or not.
  case $0 in
    *[\\/]* ) as_myself=$0 ;;
    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done

       ;;


  esac
  # We did not find ourselves, most probably we were run as `sh COMMAND'
  # in which case we are not to be found in the path.

  if test "x$as_myself" = x; then

    as_myself=$0


  fi







  if test ! -f "$as_myself"; then





    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
   { (exit 1); exit 1; }; }
  fi
  case $CONFIG_SHELL in
  '')
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  for as_base in sh bash ksh sh5; do
	 case $as_dir in
	 /*)
	   if ("$as_dir/$as_base" -c '
  as_lineno_1=$LINENO
  as_lineno_2=$LINENO
  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
  test "x$as_lineno_1" != "x$as_lineno_2" &&
  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
	     CONFIG_SHELL=$as_dir/$as_base
	     export CONFIG_SHELL
	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
	   fi;;


	 esac
       done
done




;;


  esac

  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
  # uniformly replaced by the line number.  The first 'sed' inserts a
  # line-number line before each line; the second 'sed' does the real
  # work.  The second script uses 'N' to pair each line-number line
  # with the numbered line, and appends trailing '-' during
  # substitution so that $LINENO is not a special case at line end.

  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
  sed '=' <$as_myself |
    sed '
      N
      s,$,-,
      : loop
      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
      t loop
      s,-$,,
      s,^['$as_cr_digits']*\n,,

    ' >$as_me.lineno &&
  chmod +x $as_me.lineno ||
    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
   { (exit 1); exit 1; }; }

  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensible to this).
  . ./$as_me.lineno


  # Exit status is that of the last command.
  exit
}


case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
  *c*,-n*) ECHO_N= ECHO_C='
' ECHO_T='	' ;;
  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac



if expr a : '\(a\)' >/dev/null 2>&1; then
  as_expr=expr



else
  as_expr=false
fi


rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
  # We could just check for DJGPP; but this test a) works b) is more generic
  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
  if test -f conf$$.exe; then
    # Don't use ln at all; we don't have any links
    as_ln_s='cp -p'
  else
    as_ln_s='ln -s'
  fi
elif ln conf$$.file conf$$ 2>/dev/null; then
  as_ln_s=ln
else
  as_ln_s='cp -p'

fi
rm -f conf$$ conf$$.exe conf$$.file


if mkdir -p . 2>/dev/null; then
  as_mkdir_p=:
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi










as_executable_p="test -f"

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"


# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" 	$as_nl"

# CDPATH.
$as_unset CDPATH

exec 6>&1

# Open the log real soon, to keep \$[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.  Logging --version etc. is OK.
exec 5>>config.log
{
  echo
  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
} >&5
cat >&5 <<_CSEOF

This file was extended by tk $as_me 8.5, which was
generated by GNU Autoconf 2.59.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

_CSEOF
echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5

echo >&5
_ACEOF

# Files that config.status was made for.
if test -n "$ac_config_files"; then
  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS

fi

if test -n "$ac_config_headers"; then
  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
fi

if test -n "$ac_config_links"; then
  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
fi

if test -n "$ac_config_commands"; then
  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS

fi

cat >>$CONFIG_STATUS <<\_ACEOF


ac_cs_usage="\
\`$as_me' instantiates files from templates according to the
current configuration.


Usage: $0 [OPTIONS] [FILE]...

  -h, --help       print this help, then exit
  -V, --version    print version number, then exit


  -q, --quiet      do not print progress messages
  -d, --debug      don't remove temporary files
      --recheck    update $as_me by reconfiguring in the same conditions
  --file=FILE[:TEMPLATE]
		   instantiate the configuration file FILE

Configuration files:
$config_files

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF

cat >>$CONFIG_STATUS <<_ACEOF

ac_cs_version="\\
tk config.status 8.5
configured by $0, generated by GNU Autoconf 2.59,
  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2003 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."


srcdir=$srcdir

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF
# If no file are specified by the user, then we need to provide default
# value.  By we need to know if files were specified by the user.
ac_need_defaults=:
while test $# != 0
do
  case $1 in





  --*=*)
    ac_option=`expr "x$1" : 'x\([^=]*\)='`
    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
    ac_shift=:
    ;;
  -*)
    ac_option=$1
    ac_optarg=$2
    ac_shift=shift
    ;;
  *) # This is not an option, so the user has probably given explicit
     # arguments.
     ac_option=$1
     ac_need_defaults=false;;
  esac

  case $ac_option in
  # Handling of the options.
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --vers* | -V )
    echo "$ac_cs_version"; exit 0 ;;
  --he | --h)
    # Conflict between --help and --header
    { { echo "$as_me:$LINENO: error: ambiguous option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: ambiguous option: $1
Try \`$0 --help' for more information." >&2;}
   { (exit 1); exit 1; }; };;
  --help | --hel | -h )
    echo "$ac_cs_usage"; exit 0 ;;
  --debug | --d* | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
    ac_need_defaults=false;;
  --header | --heade | --head | --hea )
    $ac_shift
    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
    ac_need_defaults=false;;


  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: unrecognized option: $1
Try \`$0 --help' for more information." >&2;}
   { (exit 1); exit 1; }; } ;;

  *) ac_config_targets="$ac_config_targets $1" ;;


  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
if \$ac_cs_recheck; then
  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion





fi

_ACEOF














cat >>$CONFIG_STATUS <<\_ACEOF


for ac_config_target in $ac_config_targets
do
  case "$ac_config_target" in
  # Handling of arguments.
  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
  "tkConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tkConfig.sh" ;;
  "wish.exe.manifest" ) CONFIG_FILES="$CONFIG_FILES wish.exe.manifest" ;;
  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
   { (exit 1); exit 1; }; };;
  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason to put it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Create a temporary directory, and hook for its removal unless debugging.


$debug ||
{

  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0



  trap '{ (exit 1); exit 1; }' 1 2 13 15
}

# Create a (secure) tmp directory for tmp files.

{
  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
  test -n "$tmp" && test -d "$tmp"
}  ||
{
  tmp=./confstat$$-$RANDOM
  (umask 077 && mkdir $tmp)
} ||
{
   echo "$me: cannot create a temporary directory in ." >&2

   { (exit 1); exit 1; }
}

_ACEOF

cat >>$CONFIG_STATUS <<_ACEOF

#
# CONFIG_FILES section.
#






# No need to generate the scripts if there are no CONFIG_FILES.
# This happens for instance when ./config.status config.h

if test -n "\$CONFIG_FILES"; then
  # Protect against being on the right side of a sed subst in config.status.
  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
s,@SHELL@,$SHELL,;t t

s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t

s,@exec_prefix@,$exec_prefix,;t t
s,@prefix@,$prefix,;t t
s,@program_transform_name@,$program_transform_name,;t t
s,@bindir@,$bindir,;t t
s,@sbindir@,$sbindir,;t t
s,@libexecdir@,$libexecdir,;t t
s,@datadir@,$datadir,;t t


s,@sysconfdir@,$sysconfdir,;t t
s,@sharedstatedir@,$sharedstatedir,;t t
s,@localstatedir@,$localstatedir,;t t
s,@libdir@,$libdir,;t t
s,@includedir@,$includedir,;t t
s,@oldincludedir@,$oldincludedir,;t t
s,@infodir@,$infodir,;t t
s,@mandir@,$mandir,;t t
s,@build_alias@,$build_alias,;t t
s,@host_alias@,$host_alias,;t t
s,@target_alias@,$target_alias,;t t
s,@DEFS@,$DEFS,;t t
s,@ECHO_C@,$ECHO_C,;t t
s,@ECHO_N@,$ECHO_N,;t t
s,@ECHO_T@,$ECHO_T,;t t
s,@LIBS@,$LIBS,;t t
s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@ac_ct_CC@,$ac_ct_CC,;t t

s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@AR@,$AR,;t t
s,@ac_ct_AR@,$ac_ct_AR,;t t

s,@RANLIB@,$RANLIB,;t t
s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
s,@RC@,$RC,;t t
s,@ac_ct_RC@,$ac_ct_RC,;t t



s,@SET_MAKE@,$SET_MAKE,;t t
s,@TCL_THREADS@,$TCL_THREADS,;t t
s,@TCL_VERSION@,$TCL_VERSION,;t t
s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t

s,@TCL_DEFS@,$TCL_DEFS,;t t
s,@CYGPATH@,$CYGPATH,;t t


s,@CELIB_DIR@,$CELIB_DIR,;t t
s,@DL_LIBS@,$DL_LIBS,;t t
s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t

s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
s,@MAN2TCLFLAGS@,$MAN2TCLFLAGS,;t t
s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t


s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
s,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t
s,@VC_MANIFEST_EMBED_EXE@,$VC_MANIFEST_EMBED_EXE,;t t
s,@BUILD_TCLSH@,$BUILD_TCLSH,;t t
s,@TCLSH_PROG@,$TCLSH_PROG,;t t


s,@TK_WIN_VERSION@,$TK_WIN_VERSION,;t t
s,@MACHINE@,$MACHINE,;t t
s,@TK_VERSION@,$TK_VERSION,;t t

s,@TK_MAJOR_VERSION@,$TK_MAJOR_VERSION,;t t
s,@TK_MINOR_VERSION@,$TK_MINOR_VERSION,;t t



s,@TK_PATCH_LEVEL@,$TK_PATCH_LEVEL,;t t
s,@TK_DBGX@,$TK_DBGX,;t t


s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t
s,@TK_DLL_FILE@,$TK_DLL_FILE,;t t
s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t
s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t
s,@TK_BUILD_STUB_LIB_SPEC@,$TK_BUILD_STUB_LIB_SPEC,;t t



s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t
s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t
s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t
s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t


s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t
s,@TCL_DBGX@,$TCL_DBGX,;t t
s,@CFG_TK_SHARED_LIB_SUFFIX@,$CFG_TK_SHARED_LIB_SUFFIX,;t t
s,@CFG_TK_UNSHARED_LIB_SUFFIX@,$CFG_TK_UNSHARED_LIB_SUFFIX,;t t
s,@CFG_TK_EXPORT_FILE_SUFFIX@,$CFG_TK_EXPORT_FILE_SUFFIX,;t t
s,@TK_SHARED_BUILD@,$TK_SHARED_BUILD,;t t
s,@DEPARG@,$DEPARG,;t t



s,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;t t

s,@STLIB_LD@,$STLIB_LD,;t t
s,@SHLIB_LD@,$SHLIB_LD,;t t
s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t
s,@CC_OBJNAME@,$CC_OBJNAME,;t t


s,@CC_EXENAME@,$CC_EXENAME,;t t


s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t
s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t
s,@LDFLAGS_CONSOLE@,$LDFLAGS_CONSOLE,;t t
s,@LDFLAGS_WINDOW@,$LDFLAGS_WINDOW,;t t
s,@RC_OUT@,$RC_OUT,;t t
s,@RC_TYPE@,$RC_TYPE,;t t
s,@RC_INCLUDE@,$RC_INCLUDE,;t t
s,@RC_DEFINE@,$RC_DEFINE,;t t
s,@RC_DEFINES@,$RC_DEFINES,;t t
s,@TK_RES@,$TK_RES,;t t
s,@RES@,$RES,;t t
s,@LIBS_GUI@,$LIBS_GUI,;t t
s,@DLLSUFFIX@,$DLLSUFFIX,;t t
s,@LIBPREFIX@,$LIBPREFIX,;t t
s,@LIBSUFFIX@,$LIBSUFFIX,;t t
s,@EXESUFFIX@,$EXESUFFIX,;t t

s,@LIBRARIES@,$LIBRARIES,;t t
s,@MAKE_LIB@,$MAKE_LIB,;t t
s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t
s,@MAKE_DLL@,$MAKE_DLL,;t t
s,@MAKE_EXE@,$MAKE_EXE,;t t
s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t
s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t
s,@TK_BUILD_LIB_SPEC@,$TK_BUILD_LIB_SPEC,;t t
s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t
s,@TK_STUB_LIB_PATH@,$TK_STUB_LIB_PATH,;t t
s,@TK_BUILD_STUB_LIB_PATH@,$TK_BUILD_STUB_LIB_PATH,;t t
s,@TK_CC_SEARCH_FLAGS@,$TK_CC_SEARCH_FLAGS,;t t
s,@TK_LD_SEARCH_FLAGS@,$TK_LD_SEARCH_FLAGS,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF



_ACEOF

  cat >>$CONFIG_STATUS <<\_ACEOF
  # Split the substitutions into bite-sized pieces for seds with
  # small command number limits, like on Digital OSF/1 and HP-UX.
  ac_max_sed_lines=48
  ac_sed_frag=1 # Number of current file.
  ac_beg=1 # First line for current file.
  ac_end=$ac_max_sed_lines # Line after last line for current file.
  ac_more_lines=:
  ac_sed_cmds=
  while $ac_more_lines; do
    if test $ac_beg -gt 1; then
      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
    else

      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag


    fi




    if test ! -s $tmp/subs.frag; then
      ac_more_lines=false

    else
      # The purpose of the label and of the branching condition is to
      # speed up the sed processing (if there are no `@' at all, there
      # is no need to browse any of the substitutions).
      # These are the two extra sed commands mentioned above.
      (echo ':t




  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
      if test -z "$ac_sed_cmds"; then
	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
      else







	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
      fi
      ac_sed_frag=`expr $ac_sed_frag + 1`
      ac_beg=$ac_end
      ac_end=`expr $ac_end + $ac_max_sed_lines`
    fi
  done
  if test -z "$ac_sed_cmds"; then
    ac_sed_cmds=cat
  fi
fi # test -n "$CONFIG_FILES"

_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF

for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue

















  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case $ac_file in


  - | *:- | *:-:* ) # input from stdin



	cat >$tmp/stdin











	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`

	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;




  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`

	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
  * )   ac_file_in=$ac_file.in ;;









  esac







  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }


  	  /^X\(\/\/\)$/{ s//\1/; q; }
  	  /^X\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; q'`

  { if $as_mkdir_p; then
    mkdir -p "$ac_dir"
  else
    as_dir="$ac_dir"
    as_dirs=
    while test ! -d "$as_dir"; do
      as_dirs="$as_dir $as_dirs"
      as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
  	  /^X\(\/\/\)$/{ s//\1/; q; }


  	  /^X\(\/\).*/{ s//\1/; q; }



  	  s/.*/./; q'`
    done
    test ! -n "$as_dirs" || mkdir $as_dirs
  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
   { (exit 1); exit 1; }; }; }

  ac_builddir=.

if test "$ac_dir" != .; then


  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
  # A "../" for each directory in $ac_dir_suffix.
  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`




else
  ac_dir_suffix= ac_top_builddir=


fi

case $srcdir in
  .)  # No --srcdir option.  We are building in place.
    ac_srcdir=.
    if test -z "$ac_top_builddir"; then
       ac_top_srcdir=.
    else
       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
    fi ;;
  [\\/]* | ?:[\\/]* )  # Absolute path.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir ;;

  *) # Relative path.
    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac

# Do not use `cd foo && pwd` to compute absolute paths, because
# the directories may not exist.
case `pwd` in
.) ac_abs_builddir="$ac_dir";;
*)
  case "$ac_dir" in
  .) ac_abs_builddir=`pwd`;;
  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
  *) ac_abs_builddir=`pwd`/"$ac_dir";;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_builddir=${ac_top_builddir}.;;
*)
  case ${ac_top_builddir}. in
  .) ac_abs_top_builddir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_srcdir=$ac_srcdir;;
*)
  case $ac_srcdir in
  .) ac_abs_srcdir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
  esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_srcdir=$ac_top_srcdir;;
*)
  case $ac_top_srcdir in
  .) ac_abs_top_srcdir=$ac_abs_builddir;;
  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
  esac;;
esac



  if test x"$ac_file" != x-; then
    { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
    rm -f "$ac_file"
  fi
  # Let's still pretend it is `configure' which instantiates (i.e., don't
  # use $as_me), people would be surprised to read:
  #    /* config.h.  Generated by config.status.  */
  if test x"$ac_file" = x-; then
    configure_input=
  else
    configure_input="$ac_file.  "
  fi
  configure_input=$configure_input"Generated from `echo $ac_file_in |
				     sed 's,.*/,,'` by configure."

  # First look for the input files in the build tree, otherwise in the
  # src tree.
  ac_file_inputs=`IFS=:
    for f in $ac_file_in; do
      case $f in
      -) echo $tmp/stdin ;;

      [\\/$]*)
	 # Absolute (can't be DOS-style, as IFS=:)

	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5

echo "$as_me: error: cannot find input file: $f" >&2;}
   { (exit 1); exit 1; }; }
	 echo "$f";;
      *) # Relative
	 if test -f "$f"; then
	   # Build tree
	   echo "$f"

	 elif test -f "$srcdir/$f"; then




	   # Source tree
	   echo "$srcdir/$f"

	 else




	   # /dev/null tree
	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}









   { (exit 1); exit 1; }; }
	 fi;;
      esac
    done` || { (exit 1); exit 1; }
_ACEOF




cat >>$CONFIG_STATUS <<_ACEOF
  sed "$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s,@configure_input@,$configure_input,;t t


s,@srcdir@,$ac_srcdir,;t t
s,@abs_srcdir@,$ac_abs_srcdir,;t t
s,@top_srcdir@,$ac_top_srcdir,;t t
s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
s,@builddir@,$ac_builddir,;t t
s,@abs_builddir@,$ac_abs_builddir,;t t
s,@top_builddir@,$ac_top_builddir,;t t




s,@abs_top_builddir@,$ac_abs_top_builddir,;t t








" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
  rm -f $tmp/stdin
  if test x"$ac_file" != x-; then

    mv $tmp/out $ac_file
  else


    cat $tmp/out
    rm -f $tmp/out
  fi


done
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF

{ (exit 0); exit 0; }
_ACEOF
chmod +x $CONFIG_STATUS
ac_clean_files=$ac_clean_files_save





# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded.  So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status.  When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
  ac_cs_success=:
  ac_config_status_args=
  test "$silent" = yes &&
    ac_config_status_args="$ac_config_status_args --quiet"
  exec 5>/dev/null
  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || { (exit 1); exit 1; }




fi


Deleted win/configure.ac.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#! /bin/bash -norc
# This file is an input file used by the GNU "autoconf" program to
# generate the file "configure", which is run during Tk installation
# to configure the system for the local environment.

AC_INIT(../generic/tk.h)
AC_PREREQ(2.69)

# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
# libdir must be a fully qualified path (not ${exec_prefix}/lib)
eval libdir="$libdir"

#------------------------------------------------------------------------
# Standard compiler checks
#------------------------------------------------------------------------

# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
    CFLAGS=""
fi

AC_PROG_CC
AC_C_INLINE
AC_HEADER_STDC

AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib)
AC_CHECK_TOOL(RC, windres)

#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

AC_PROG_MAKE_SET

#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------

AC_OBJEXT
AC_EXEEXT

#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

SC_ENABLE_SHARED

#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG($TK_PATCH_LEVEL)
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better.])
fi
if test "${TCL_MINOR_VERSION}" -lt 6; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better.])
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)

#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

AC_CACHE_CHECK([availability of _strtoi64], tcl_cv_strtoi64, [
    AC_TRY_LINK([#include <stdlib.h>],
	    [_strtoi64(0,0,0)],
	    tcl_cv_strtoi64=yes, tcl_cv_strtoi64=no)])
if test $tcl_cv_strtoi64 = no; then
    AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?])
fi

#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------

AC_CHECK_HEADER([uxtheme.h], [AC_DEFINE(HAVE_UXTHEME_H)],
	[AC_MSG_NOTICE([xpnative theme will be unavailable])],
	[#include <windows.h>])
AC_CHECK_HEADER([vssym32.h], [AC_DEFINE(HAVE_VSSYM32_H)], [],
	[#include <windows.h>
#include <uxtheme.h>])

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------

SC_ENABLE_SYMBOLS

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------

SC_EMBED_MANIFEST(wish.exe.manifest)

SC_BUILD_TCLSH
SC_PROG_TCLSH

#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"

eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names
eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}"

eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}"

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}
CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX}

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    TK_RES=""
else
    RC_DEFINES=""
    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in
     *a*) TK_RELEASE_LEVEL=0 ;;
     *b*) TK_RELEASE_LEVEL=1 ;;
     *)   TK_RELEASE_LEVEL=2 ;;
esac
TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`"
AC_SUBST(TK_WIN_VERSION)
# X86|AMD64|IA64 for manifest
AC_SUBST(MACHINE)

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_DLL_FILE)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_BIN_DIR)

AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)

AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX)

AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(CYGPATH)
AC_SUBST(DEPARG)
AC_SUBST(CC_OBJNAME)
AC_SUBST(CC_EXENAME)

# win/tcl.m4 doesn't set (LDFLAGS)
AC_SUBST(LDFLAGS_DEFAULT)
AC_SUBST(LDFLAGS_DEBUG)
AC_SUBST(LDFLAGS_OPTIMIZE)
AC_SUBST(LDFLAGS_CONSOLE)
AC_SUBST(LDFLAGS_WINDOW)
AC_SUBST(AR)
AC_SUBST(RANLIB)
AC_SUBST(TK_RES)

AC_SUBST(STLIB_LD)
AC_SUBST(SHLIB_LD)
AC_SUBST(SHLIB_LD_LIBS)
AC_SUBST(SHLIB_CFLAGS)
AC_SUBST(SHLIB_SUFFIX)
AC_SUBST(TK_SHARED_BUILD)

AC_SUBST(LIBS)
AC_SUBST(LIBS_GUI)
AC_SUBST(DLLSUFFIX)
AC_SUBST(LIBPREFIX)
AC_SUBST(LIBSUFFIX)
AC_SUBST(EXESUFFIX)
AC_SUBST(LIBRARIES)
AC_SUBST(MAKE_LIB)
AC_SUBST(MAKE_STUB_LIB)
AC_SUBST(POST_MAKE_LIB)
AC_SUBST(MAKE_DLL)
AC_SUBST(MAKE_EXE)

AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_BUILD_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_BUILD_STUB_LIB_PATH)

# undefined at this point for win
AC_SUBST(TK_CC_SEARCH_FLAGS)
AC_SUBST(TK_LD_SEARCH_FLAGS)

AC_SUBST(RC)
AC_SUBST(RC_OUT)
AC_SUBST(RC_TYPE)
AC_SUBST(RC_INCLUDE)
AC_SUBST(RC_DEFINE)
AC_SUBST(RC_DEFINES)
AC_SUBST(RES)

AC_OUTPUT(Makefile tkConfig.sh wish.exe.manifest)

dnl Local Variables:
dnl mode: autoconf;
dnl End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































Added win/configure.in.

































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#! /bin/bash -norc
# This file is an input file used by the GNU "autoconf" program to
# generate the file "configure", which is run during Tk installation
# to configure the system for the local environment.

AC_INIT([tk],[8.5])
AC_CONFIG_SRCDIR([../generic/tk.h])
AC_PREREQ([2.59])

# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.5
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=5
TK_PATCH_LEVEL=".19"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
# libdir must be a fully qualified path (not ${exec_prefix}/lib)
eval libdir="$libdir"

#------------------------------------------------------------------------
# Standard compiler checks
#------------------------------------------------------------------------

# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
    CFLAGS=""
fi

AC_PROG_CC
AC_C_INLINE
AC_HEADER_STDC

AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib)
AC_CHECK_TOOL(RC, windres)

#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

AC_PROG_MAKE_SET

#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------

AC_OBJEXT
AC_EXEEXT

#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
#--------------------------------------------------------------------

SC_ENABLE_THREADS

#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

SC_ENABLE_SHARED

#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG($TK_PATCH_LEVEL)
SC_LOAD_TCLCONFIG

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
#include <stdint.h>
]])

#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)

#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

AC_CACHE_CHECK([availability of _strtoi64], tcl_cv_strtoi64, [
    AC_TRY_LINK([#include <stdlib.h>],
	    [_strtoi64(0,0,0)],
	    [tcl_cv_strtoi64=yes],[tcl_cv_strtoi64=no])])
if test $tcl_cv_strtoi64 = no; then
    AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?])
fi

AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "__int64" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_intptr_t" != none; then
	AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
	   type wide enough to hold a pointer.])
    fi
])
AC_CHECK_TYPE([uintptr_t], [
    AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned __int64" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_uintptr_t" != none; then
	AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
	   type wide enough to hold a pointer.])
    fi
])

#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------

AC_CHECK_HEADER([uxtheme.h], [AC_DEFINE(HAVE_UXTHEME_H)],
	[AC_MSG_NOTICE([xpnative theme will be unavailable])],
	[#include <windows.h>])

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------

SC_ENABLE_SYMBOLS

TK_DBGX=${DBGX}

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------

SC_EMBED_MANIFEST(wish.exe.manifest)

SC_BUILD_TCLSH
SC_PROG_TCLSH

#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=\"${LIBPREFIX}tk${VER}${LIBSUFFIX}\""
else
 eval "TK_LIB_FILE=\"${LIBPREFIX}tk${VER}${DLLSUFFIX}.a\""
fi

eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names
eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}"

eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}"

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}
CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX}

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
    else
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    fi
    TK_RES=""
else
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} DEBUG"
    else
        RC_DEFINES=""
    fi
    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in
     *a*) TK_RELEASE_LEVEL=0 ;;
     *b*) TK_RELEASE_LEVEL=1 ;;
     *)   TK_RELEASE_LEVEL=2 ;;
esac
TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`"
AC_SUBST(TK_WIN_VERSION)
# X86|AMD64|IA64 for manifest
AC_SUBST(MACHINE)

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_DBGX)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_DLL_FILE)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_BIN_DIR)

AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_DBGX)
AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX)
AC_SUBST(TK_SHARED_BUILD)

AC_SUBST(CYGPATH)
AC_SUBST(DEPARG)
AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(STLIB_LD)
AC_SUBST(SHLIB_LD)
AC_SUBST(SHLIB_LD_LIBS)
AC_SUBST(SHLIB_CFLAGS)
AC_SUBST(SHLIB_SUFFIX)
AC_SUBST(CC_OBJNAME)
AC_SUBST(CC_EXENAME)
AC_SUBST(LDFLAGS_DEFAULT)
AC_SUBST(LDFLAGS_DEBUG)
AC_SUBST(LDFLAGS_OPTIMIZE)
AC_SUBST(LDFLAGS_CONSOLE)
AC_SUBST(LDFLAGS_WINDOW)
AC_SUBST(AR)
AC_SUBST(RANLIB)
AC_SUBST(RC)
AC_SUBST(RC_OUT)
AC_SUBST(RC_TYPE)
AC_SUBST(RC_INCLUDE)
AC_SUBST(RC_DEFINE)
AC_SUBST(RC_DEFINES)
AC_SUBST(TK_RES)
AC_SUBST(RES)
AC_SUBST(LIBS)
AC_SUBST(LIBS_GUI)
AC_SUBST(DLLSUFFIX)
AC_SUBST(LIBPREFIX)
AC_SUBST(LIBSUFFIX)
AC_SUBST(EXESUFFIX)
AC_SUBST(LIBRARIES)
AC_SUBST(MAKE_LIB)
AC_SUBST(MAKE_STUB_LIB)
AC_SUBST(POST_MAKE_LIB)
AC_SUBST(MAKE_DLL)
AC_SUBST(MAKE_EXE)

AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_BUILD_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_BUILD_STUB_LIB_PATH)

# undefined at this point for win
AC_SUBST(TK_CC_SEARCH_FLAGS)
AC_SUBST(TK_LD_SEARCH_FLAGS)

AC_CONFIG_FILES([Makefile tkConfig.sh wish.exe.manifest])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf
dnl End:

Added win/makefile.bc.















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
#
# Makefile for Borland C++ 5.5 (or C++ Builder 5), adapted from the makefile
#   for Visual C++ that came with tk 8.3.3
#
# Some "not so obvious" details in this makefile are preceded by a comment
# "maintenance hint", which tries to explain what's going on. Better to
# leave those in place.
# Helmut Giese, July 2002
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.

# Does not depend on the presence of any environment variables in
# order to compile tcl; all needed information is derived from
# location of the compiler directories.

#
# Project directories
#
# ROOT    = top of source tree
#
# TMPDIR  = location where .obj files should be stored during build
#
# TOOLS32 = location of Borland development tools.
#
# TCLDIR = location of top of Tcl source hierarchy
#

ROOT        = ..
TCLDIR      = ..\..\tcl8.4
INSTALLDIR  = D:\tmp\tcl

# If you have C++ Builder 5 or the free Borland C++ 5.5 compiler
# adapt the following paths as appropriate for your system
TOOLS32    = d:\cbld5
TOOLS32_rc = d:\cbld5
#TOOLS32    = c:\bc55
#TOOLS32_rc = c:\bc55

cc32      = "$(TOOLS32)\bin\bcc32.exe"
link32    = "$(TOOLS32)\bin\ilink32.exe"
lib32     = "$(TOOLS32)\bin\tlib.exe"
rc32      = "$(TOOLS32_rc)\bin\brcc32.exe"
include32 = -I"$(TOOLS32)\include;$(TOOLS32)\include\mfc"
libpath32 = -L"$(TOOLS32)\lib"

# Uncomment the following line to compile with thread support
#THREADDEFINES = -DTCL_THREADS=1

# Allow definition of NDEBUG via command line
# Set NODEBUG to 0 to compile with symbols
!if !defined(NODEBUG)
NODEBUG = 1
!endif

# uncomment the following two lines to compile with TCL_MEM_DEBUG
#DEBUGDEFINES =-DTCL_MEM_DEBUG

######################################################################
# Do not modify below this line
######################################################################

TCLNAMEPREFIX = tcl
TKNAMEPREFIX = tk
WISHNAMEPREFIX = wish
VERSION = 84
DOTVERSION = 8.4

TCLSTUBPREFIX = $(TCLNAMEPREFIX)stub
TKSTUBPREFIX  = $(TKNAMEPREFIX)stub


BINROOT   = .
!IF "$(NODEBUG)" == "1"
TMPDIRNAME  = Release
DBGX        =
!ELSE
TMPDIRNAME  = Debug
DBGX        =
#DBGX       = d
!ENDIF
TMPDIR      = $(BINROOT)\$(TMPDIRNAME)
OUTDIRNAME  = $(TMPDIRNAME)
OUTDIR      = $(TMPDIR)

TCLLIB        = $(TCLNAMEPREFIX)$(VERSION)$(DBGX).lib
TCLPLUGINLIB  = $(TCLNAMEPREFIX)$(VERSION)p.lib
TCLSTUBLIB    = $(TCLSTUBPREFIX)$(VERSION)$(DBGX).lib
TKDLLNAME     = $(TKNAMEPREFIX)$(VERSION)$(DBGX).dll
TKDLL         = $(OUTDIR)\$(TKDLLNAME)
TKLIB         = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)$(DBGX).lib
TKSTUBLIBNAME = $(TKSTUBPREFIX)$(VERSION)$(DBGX).lib
TKSTUBLIB     = $(OUTDIR)\$(TKSTUBLIBNAME)
TKPLUGINDLLNAME = $(TKNAMEPREFIX)$(VERSION)p$(DBG).dll
TKPLUGINDLL   = $(OUTDIR)\$(TKPLUGINDLLNAME)
TKPLUGINLIB   = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)p$(DBGX).lib

WISH      = $(OUTDIR)\$(WISHNAMEPREFIX)$(VERSION)$(DBGX).exe
WISHC     = $(OUTDIR)\$(WISHNAMEPREFIX)c$(VERSION)$(DBGX).exe
WISHP     = $(OUTDIR)\$(WISHNAMEPREFIX)p$(VERSION)$(DBGX).exe
TKTEST    = $(OUTDIR)\$(TKNAMEPREFIX)test.exe
CAT32     = $(TMPDIR)\cat32.exe

BIN_INSTALL_DIR     = $(INSTALLDIR)\bin
INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include
LIB_INSTALL_DIR     = $(INSTALLDIR)\lib
SCRIPT_INSTALL_DIR  = $(LIB_INSTALL_DIR)\tk$(DOTVERSION)

WISHOBJS = \
  $(TMPDIR)\winMain.obj

TKTESTOBJS = \
  $(TMPDIR)\tkTest.obj \
  $(TMPDIR)\tkSquare.obj \
  $(TMPDIR)\testMain.obj \
  $(TMPDIR)\tkOldTest.obj \
  $(TMPDIR)\tkWinTest.obj \
  $(TCLLIBDIR)\tclThreadTest.obj

XLIBOBJS = \
  $(TMPDIR)\xcolors.obj \
  $(TMPDIR)\xdraw.obj \
  $(TMPDIR)\xgc.obj \
  $(TMPDIR)\ximage.obj \
  $(TMPDIR)\xutil.obj

TKOBJS = \
	$(TMPDIR)\tkConsole.obj \
	$(TMPDIR)\tkUnixMenubu.obj \
	$(TMPDIR)\tkUnixScale.obj \
	$(XLIBOBJS) \
	$(TMPDIR)\tkWin3d.obj \
	$(TMPDIR)\tkWin32Dll.obj \
	$(TMPDIR)\tkWinButton.obj \
	$(TMPDIR)\tkWinClipboard.obj \
	$(TMPDIR)\tkWinColor.obj \
	$(TMPDIR)\tkWinConfig.obj \
	$(TMPDIR)\tkWinCursor.obj \
	$(TMPDIR)\tkWinDialog.obj \
	$(TMPDIR)\tkWinDraw.obj \
	$(TMPDIR)\tkWinEmbed.obj \
	$(TMPDIR)\tkWinFont.obj \
	$(TMPDIR)\tkWinImage.obj \
	$(TMPDIR)\tkWinInit.obj \
	$(TMPDIR)\tkWinKey.obj \
	$(TMPDIR)\tkWinMenu.obj \
	$(TMPDIR)\tkWinPixmap.obj \
	$(TMPDIR)\tkWinPointer.obj \
	$(TMPDIR)\tkWinRegion.obj \
	$(TMPDIR)\tkWinScrlbr.obj \
	$(TMPDIR)\tkWinSend.obj \
	$(TMPDIR)\tkWinWindow.obj \
	$(TMPDIR)\tkWinWm.obj \
	$(TMPDIR)\tkWinX.obj \
	$(TMPDIR)\stubs.obj \
	$(TMPDIR)\tk3d.obj \
	$(TMPDIR)\tkArgv.obj \
	$(TMPDIR)\tkAtom.obj \
	$(TMPDIR)\tkBind.obj \
	$(TMPDIR)\tkBitmap.obj \
	$(TMPDIR)\tkButton.obj \
	$(TMPDIR)\tkCanvArc.obj \
	$(TMPDIR)\tkCanvBmap.obj \
	$(TMPDIR)\tkCanvImg.obj \
	$(TMPDIR)\tkCanvLine.obj \
	$(TMPDIR)\tkCanvPoly.obj \
	$(TMPDIR)\tkCanvPs.obj \
	$(TMPDIR)\tkCanvText.obj \
	$(TMPDIR)\tkCanvUtil.obj \
	$(TMPDIR)\tkCanvWind.obj \
	$(TMPDIR)\tkCanvas.obj \
	$(TMPDIR)\tkClipboard.obj \
	$(TMPDIR)\tkCmds.obj \
	$(TMPDIR)\tkColor.obj \
	$(TMPDIR)\tkConfig.obj \
	$(TMPDIR)\tkCursor.obj \
	$(TMPDIR)\tkEntry.obj \
	$(TMPDIR)\tkError.obj \
	$(TMPDIR)\tkEvent.obj \
	$(TMPDIR)\tkFileFilter.obj \
	$(TMPDIR)\tkFocus.obj \
	$(TMPDIR)\tkFont.obj \
	$(TMPDIR)\tkFrame.obj \
	$(TMPDIR)\tkGC.obj \
	$(TMPDIR)\tkGeometry.obj \
	$(TMPDIR)\tkGet.obj \
	$(TMPDIR)\tkGrab.obj \
	$(TMPDIR)\tkGrid.obj \
	$(TMPDIR)\tkImage.obj \
	$(TMPDIR)\tkImgBmap.obj \
	$(TMPDIR)\tkImgGIF.obj \
	$(TMPDIR)\tkImgPPM.obj \
	$(TMPDIR)\tkImgPhoto.obj \
	$(TMPDIR)\tkImgUtil.obj \
	$(TMPDIR)\tkListbox.obj \
	$(TMPDIR)\tkMacWinMenu.obj \
	$(TMPDIR)\tkMain.obj \
	$(TMPDIR)\tkMenu.obj \
	$(TMPDIR)\tkMenubutton.obj \
	$(TMPDIR)\tkMenuDraw.obj \
	$(TMPDIR)\tkMessage.obj \
	$(TMP_DIR)\tkPanedWindow.obj \
	$(TMPDIR)\tkObj.obj \
	$(TMPDIR)\tkOldConfig.obj \
	$(TMPDIR)\tkOption.obj \
	$(TMPDIR)\tkPack.obj \
	$(TMPDIR)\tkPlace.obj \
	$(TMPDIR)\tkPointer.obj \
	$(TMPDIR)\tkRectOval.obj \
	$(TMPDIR)\tkScale.obj \
	$(TMPDIR)\tkScrollbar.obj \
	$(TMPDIR)\tkSelect.obj \
	$(TMPDIR)\tkText.obj \
	$(TMPDIR)\tkTextBTree.obj \
	$(TMPDIR)\tkTextDisp.obj \
	$(TMPDIR)\tkTextImage.obj \
	$(TMPDIR)\tkTextIndex.obj \
	$(TMPDIR)\tkTextMark.obj \
	$(TMPDIR)\tkTextTag.obj \
	$(TMPDIR)\tkTextWind.obj \
	$(TMPDIR)\tkTrig.obj \
	$(TMPDIR)\tkUtil.obj \
	$(TMPDIR)\tkVisual.obj \
	$(TMPDIR)\tkStubInit.obj \
	$(TMPDIR)\tkWindow.obj

# Maintenance hint: Please have multiple members of TKSTUBOBJS be separated
# by exactly one ' ' (see below the rule for making TKSTUBLIB)
TKSTUBOBJS = $(TMPDIR)\tkStubLib.obj

WIN_DIR      = $(ROOT)\win
GENERICDIR  = $(ROOT)\generic
XLIBDIR     = $(ROOT)\xlib
BITMAPDIR   = $(ROOT)\bitmaps
TCLLIBDIR   = $(TCLDIR)\win\$(OUTDIRNAME)
RCDIR       = $(WIN_DIR)\rc

TK_INCLUDES = -I$(WIN_DIR) -I$(GENERICDIR) -I$(BITMAPDIR) -I$(XLIBDIR) \
      -I$(TCLDIR)\generic -I$(TCLDIR)\win

TK_DEFINES  = -D__WIN32__ $(DEBUGDEFINES) $(THREADDEFINES) SUPPORT_CONFIG_EMBEDDED

######################################################################
# Compile flags
######################################################################

!IF "$(NODEBUG)" == "1"
# these macros cause maximum optimization and no symbols
cdebug = -v- -vi- -O2 -D_DEBUG
!ELSE
# these macros enable debugging
cdebug = -k -Od -r- -v -vi- -y
!ENDIF

SYSDEFINES = _MT;NO_STRICT;_NO_VCL

# declarations common to all compiler options
cbase = -3 -a4 -c -g0 -tWM -Ve -Vx -X-
WARNINGS = -w-rch -w-pch -w-par -w-dup -w-pro -w-dpu

ccons = -tWC

CFLAGS      = $(cdebug) $(cbase) $(WARNINGS) -D$(SYSDEFINES)

CON_CFLAGS  = $(CFLAGS) $(TK_DEFINES) $(include32) $(ccons)
WISH_CFLAGS = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES)
TK_CFLAGS   = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES) \
                   -DUSE_TCL_STUBS

######################################################################
# Link flags
######################################################################

!IF "$(NODEBUG)" == "1"
ldebug =
!ELSE
ldebug = -v
!ENDIF

# declarations common to all linker options
LNFLAGS = -D"" -Gn -I$(TMPDIR) -x $(ldebug) $(libpath32)
# -Gi: create lib file (is -Gl in doc)
# -aa: Windows app, -ap: Windows console app
LNFLAGS_DLL  = -ap -Gi -Tpd
LNFLAGS_CONS = -ap -Tpe
LNFLAGS_GUI  = -aa -Tpe

LNLIBS = import32 cw32mt


######################################################################
# Project specific targets
######################################################################

all:      setup $(WISH) $(CAT32)
install:  install-binaries install-libraries
plugin:   setup $(TKPLUGINDLL) $(WISHP)
tktest:   setup $(TKTEST) $(CAT32)

# Maintenance hint: We want to set environment variables before calling tktest.
#  If we do this in the form of normal commands, they will not persist up to
#  the call of tktest. Therfore we put all commands wanted into a batch file.
#  The normal way of using 'echo >x.bat' and 'echo >>x.bat' does not work here
#  because we cannot write '... > tktest.txt' this way. Hence this advanced
#  form of loop hopping:
#    - Have MAKE produce a temporary file with the content we want.
#    - Use it as input to the COPY command to produce a batch file.
#    - Run the batch file and be happy.
#
test:     setup $(TKTEST) $(TKLIB) $(CAT32)
  copy &&!
  set TCL_LIBRARY=$(TCLDIR)/library
  set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH)
  $(TKTEST) $(ROOT)/tests/all.tcl > tktest.txt
! _test.bat
  _test.bat
#  del _test.bat

runtest:  setup $(TKTEST) $(TKLIB) $(CAT32)
  echo set TCL_LIBRARY=$(TCLDIR)/library             > _test2.bat
  echo set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH) >> _test2.bat
  echo $(TKTEST)                                    >> _test2.bat
  _test2.bat
#  del _test2.bat

console-wish : all $(WISHC)

stubs:
  $(TCLDIR)\win\$(TMPDIRNAME)\tclsh$(VERSION)$(DBGX) \
    $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
    $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls

setup:
  @mkd $(TMPDIR)
  @mkd $(OUTDIR)

install-binaries:
  @mkd "$(BIN_INSTALL_DIR)"
  copy $(TKDLL) "$(BIN_INSTALL_DIR)"
  copy $(WISH) "$(BIN_INSTALL_DIR)"
  @mkd "$(LIB_INSTALL_DIR)"
  copy $(TKLIB) "$(LIB_INSTALL_DIR)"

install-libraries:
  @mkd "$(INCLUDE_INSTALL_DIR)"
  @mkd "$(INCLUDE_INSTALL_DIR)\X11"
  copy "$(GENERICDIR)\tk.h"             "$(INCLUDE_INSTALL_DIR)"
  copy "$(GENERICDIR)\tkDecls.h"        "$(INCLUDE_INSTALL_DIR)"
  copy "$(GENERICDIR)\tkPlatDecls.h"    "$(INCLUDE_INSTALL_DIR)"
  copy "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)"
  xcopy "$(XLIBDIR)\X11\*.h"            "$(INCLUDE_INSTALL_DIR)\X11"
  @mkd "$(SCRIPT_INSTALL_DIR)"
  @mkd "$(SCRIPT_INSTALL_DIR)\images"
  @mkd "$(SCRIPT_INSTALL_DIR)\demos"
  @mkd "$(SCRIPT_INSTALL_DIR)\demos\images"
  @mkd "$(SCRIPT_INSTALL_DIR)\msgs"
  xcopy "$(ROOT)\library"		"$(SCRIPT_INSTALL_DIR)"
  xcopy "$(ROOT)\library\images"	"$(SCRIPT_INSTALL_DIR)\images"
  xcopy "$(ROOT)\library\demos"		"$(SCRIPT_INSTALL_DIR)\demos"
  xcopy "$(ROOT)\library\demos\images"	"$(SCRIPT_INSTALL_DIR)\demos\images"
  xcopy "$(ROOT)\library\msgs"		"$(SCRIPT_INSTALL_DIR)\msgs"

$(TKLIB): $(TKDLL) $(TKSTUBLIB)

# Maintenance hint: The macro puts a '+-' before the first member of
#   TKSTUBOBJS, than replaces any ' ' with ' +-' - together putting '+-' in
#   front of any member of TKSTUBOBJS (provided, they are separated in their
#   defintion by just one space).
#
# The first time you *make* this target, you will get a warning
#   tkStubLib not found in library
# This is (probably) because of the '-' option, telling TLIB to remove
# 'tkStubLib' when it does not yet exist. Forcing a re-make when it already
# exists avoids this warning.
#
$(TKSTUBLIB): $(TKSTUBOBJS)
    $(lib32) $@ +-$(TKSTUBOBJS: = +-)

#    $(lib32) $@ @&&!
#+-$(TKSTUBOBJS: = &^
#+-)
#!

$(TKDLL): $(TKOBJS) $(TMPDIR)\tk.res
    $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 @&&!
      $(TKOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLSTUBLIB),, $(TMPDIR)\tk.res
!

$(TKPLUGINLIB): $(TKPLUGINDLL)

#$(TKPLUGINDLL): $(TKOBJS) $(TMPDIR)\tk.res
#        $(link32) $(ldebug) $(dlllflags) \
#    -out:$@ $(TMPDIR)\tk.res $(TCLLIBDIR)\$(TCLPLUGINLIB) \
#    $(guilibsdll) @<<
#      $(TKOBJS)
#<<

$(WISH): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res
  $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&!
    $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
!

$(WISHC): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res
  $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&!
    $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
!

$(WISHP): $(WISHOBJS) $(TKPLUGINLIB) $(TMPDIR)\wish.res
  $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \
    $(guilibsdll) $(TCLLIBDIR)\$(TCLPLUGINLIB) \
    $(TKPLUGINLIB) $(WISHOBJS)

$(TKTEST): $(TKTESTOBJS) $(TKLIB) $(TMPDIR)\wish.res
  $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&!
    $(TKTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
!
#  $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \
#    $(guilibsdll) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB) $(TKTESTOBJS)

#$(CAT32): $(TCLDIR)\win\cat.c
#  $(cc32) $(CON_CFLAGS) -o$(TMPDIR)\cat.obj $?
#  $(link32) $(conlflags) -out:$@ -stack:16384 $(TMPDIR)\cat.obj $(conlibs)

$(CAT32): $(TCLDIR)\win\cat.c
  $(cc32) $(CONS_CFLAGS) -o$(TMPDIR)\cat.obj $?
  $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 \
      $(TMPDIR)\cat.obj, $@, -x, $(LNLIBS),,

#
# Regenerate the stubs files.
#

genstubs:
  tclsh$(VERSION) $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
    $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls

#
# Special case object file targets
#

$(TMPDIR)\testMain.obj: $(WIN_DIR)\winMain.c
  $(cc32) $(WISH_CFLAGS) -DTK_TEST -o$@ $?

$(TMPDIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
  $(cc32) $(WISH_CFLAGS) -o$@ $?

$(TMPDIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
  $(cc32) $(WISH_CFLAGS) -o$@ $?

$(TMPDIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
  $(cc32) $(WISH_CFLAGS) -o$@ $?

$(TMPDIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
  $(cc32) $(WISH_CFLAGS) -o$@ $?

$(TMPDIR)\winMain.obj: $(WIN_DIR)\winMain.c
  $(cc32) $(WISH_CFLAGS) -o$@ $?

$(TMPDIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
  $(cc32) $(TK_CFLAGS) -DSTATIC_BUILD -o$@ $?

#
# Implicit rules
#

{$(XLIBDIR)}.c{$(TMPDIR)}.obj:
  $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<

{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
  $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<

{$(WIN_DIR)}.c{$(TMPDIR)}.obj:
  $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<

{$(ROOT)\unix}.c{$(TMPDIR)}.obj:
  $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<

{$(RCDIR)}.rc{$(TMPDIR)}.res:
  $(rc32) -I"$(GENERICDIR)" -I"$(TOOLS32)\include" -I"$(TCLDIR)\generic" \
      -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $<

clean:
  -@del $(OUTDIR)\*.exp
  -@del $(OUTDIR)\*.lib
  -@del $(OUTDIR)\*.dll
  -@del $(OUTDIR)\*.exe
  -@del $(OUTDIR)\*.pdb
  -@del $(TMPDIR)\*.pch
  -@del $(TMPDIR)\*.obj
  -@del $(TMPDIR)\*.res
  -@del $(TMPDIR)\*.exe
  -@rmd $(OUTDIR)
  -@rmd $(TMPDIR)

# dependencies

$(TMPDIR)\tk.res: \
    $(RCDIR)\buttons.bmp \
    $(RCDIR)\cursor*.cur \
    $(RCDIR)\tk.ico

$(GENERICDIR)/default.h: $(WIN_DIR)/tkWinDefault.h
$(GENERICDIR)/tkButton.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkCanvas.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkEntry.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkFrame.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkListbox.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkMenubutton.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkMessage.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkScale.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkScrollbar.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkText.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/default.h
$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/default.h

$(GENERICDIR)/tkText.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextBTree.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextImage.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextMark.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/tkText.h
$(GENERICDIR)/tkTextWind.c: $(GENERICDIR)/tkText.h

$(GENERICDIR)/tkMacWinMenu.c: $(GENERICDIR)/tkMenu.h
$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/tkMenu.h
$(GENERICDIR)/tkMenuDraw.c: $(GENERICDIR)/tkMenu.h
$(WIN_DIR)/tkWinMenu.c: $(GENERICDIR)/tkMenu.h


Changes to win/makefile.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16








17
18


19
20
21
22




23




24

25


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


48
49
50
51
52
53



54
55
56







57
58
59











60
61
62
63
64
65
66
67
68
69
70

















71
72


73
74





75
76










77
78
79
80

81




82








83



84
85





86
87



88






89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121


122
123
124



125


126

127
128
129
130
131






132
133
134
135
136
137
138
#------------------------------------------------------------- -*- makefile -*-
# makefile.vc --
#
#	Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001-2005 ActiveState Corporation.
# Copyright (c) 2001-2004 David Gravereaux.
# Copyright (c) 2003-2008 Pat Thoyts.
# Copyright (c) 2017 Ashok P. Nadkarni
#------------------------------------------------------------------------------









# General usage:
#   nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]]


#
# For MACRODEF, see TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md)
# or examine Sections 6-8 in rules.vc. This makefile has the following
# values for the OPTS macro in addition to the ones described there.




#	noxp     = If you do not have the uxtheme.h header then you




#                  cannot include support for XP themeing.

#	square   = Include the demo square widget.


#
# Possible values for TARGET are:
#	release  -- Builds the core, the shell and the dlls. (default)
#	dlls     -- Just builds the windows extensions.
#	shell    -- Just builds the shell and the core.
#	core     -- Only builds the core [tkXX.(dll|lib)].
#	all      -- Builds everything.
#	test     -- Builds and runs the test suite.
#	tktest   -- Just builds the binaries for the test suite.
#	install  -- Installs the built binaries and libraries to $(INSTALLDIR)
#		    as the root of the install tree.
#	cwish    -- Builds a console version of wish.
#	tidy/clean/hose -- varying levels of cleaning.
#	genstubs -- Rebuilds the Stubs table and support files (dev only).
#	depend   -- Generates an accurate set of source dependancies for this
#		    makefile.  Helpful to avoid problems when the sources are
#		    refreshed and you rebuild, but can "overbuild" when common
#		    headers like tkInt.h just get small changes.
#	htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the
#		    troff manual pages found in $(ROOT)\doc. You need to
#		    have installed the HTML Help Compiler package from Microsoft
#		    to produce the .chm file.


#
# The steps to setup a Visual C++ environment depend on which
# version of Visual Studio and/or the Windows SDK you are building
# against and are not described here. The simplest method is generally
# to start a command shell using one of the short cuts installed by
# Visual Studio/Windows SDK for the appropriate target architecture.



#
# NOTE: For older (Visual C++ 6 or the 2003 SDK), to use the Platform
# SDK (not expressly needed), run setenv.bat after vcvars32.bat







# according to the instructions for it.  This can also turn on the
# 64-bit compiler, if your SDK has it.
#











# Examples:
# Assuming Tcl sources lie in ../../tcl
#       c:\tcl_src\win\>nmake -f makefile.vc release
# If Tcl sources are not in ../../tcl, use the TCLDIR macro to specify dir
#       c:\tcl_src\win\>nmake -f makefile.vc release TCLDIR=c:\src\tcl
# Run the test suite
#       c:\tcl_src\win\>nmake -f makefile.vc test
# Install Tk in location specified by INSTALLDIR macro
#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
# Build release with PDB files
#       c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs

















# Build debug version
#       c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols


#
###############################################################################






# The PROJECT macro is used by rules.vc for generating appropriate










# macros and rules.
PROJECT = tk

# Default target to build if no target is specified. If unspecified, the

# rules.vc file will set up "all" as the target.




DEFAULT_BUILD_TARGET = release












# We have a custom resource file
RCFILE = tk.rc






USE_WIDECHAR_API  = 0










# The rules.vc file does much of the hard work in terms of defining
# the build configuration, macros, output directories etc.

!include "rules-ext.vc"

# TCLINSTALL is set to 1 by rules.vc to indicate we are building against
# an installed Tcl and 0 if building against Tcl source. Tk needs the latter.
!if $(TCLINSTALL)
!message *** Warning: Tk requires the source distribution of Tcl to build from,
!message ***    at this time, sorry.  Please set the TCLDIR macro to point to the
!message ***    Tcl sources.
!endif

# Extra makefile options processing for non-standard OPTS values ...
!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
HAVE_UXTHEME_H    = 1
TTK_SQUARE_WIDGET = 0
!else
!if [nmakehlp -f $(OPTS) "noxp"]
!message *** Exclude support for XP theme
HAVE_UXTHEME_H  = 0
!else
HAVE_UXTHEME_H  = 1
!endif
!if [nmakehlp -f "$(OPTS)" "square"]
!message *** Include ttk square demo widget
TTK_SQUARE_WIDGET   = 1
!else
TTK_SQUARE_WIDGET   = 0
!endif
!endif


TK_NO_DEPRECATED = 0
!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]


!if [nmakehlp -f $(CHECKS) "nodep"]
TK_NO_DEPRECATED = 1
!endif



!endif




WISHC 		= "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(VERSION)$(SUFX).exe"

TKTEST		= "$(OUT_DIR)\$(PROJECT)test.exe"
CAT32		= "$(OUT_DIR)\cat32.exe"







WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(TCL_USE_STATIC_PACKAGES)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res













<


>
>
>
>
>
>
>
>
|
|
>
>

<
<
<
>
>
>
>
|
>
>
>
>
|
>
|
>
>

|




















>
>

<
<
|
|
|
>
>
>

<
<
>
>
>
>
>
>
>
|
<

>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>

|
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
|
<
|
<
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
|
|
>
>
>
>
>

|
>
>
>

>
>
>
>
>
>
|
<
>
|

<
<






|


















>
|
|
>
>
|
|
|
>
>
>
|
>
>

>
|




>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74


75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144

145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187


188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#------------------------------------------------------------- -*- makefile -*-
# makefile.vc --
#
#	Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001-2005 ActiveState Corporation.
# Copyright (c) 2001-2004 David Gravereaux.
# Copyright (c) 2003-2008 Pat Thoyts.

#------------------------------------------------------------------------------

# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
MSG = ^
You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
Platform SDK first to setup the environment.  Jump to this line to read^
the build instructions.
!error $(MSG)
!endif

#------------------------------------------------------------------------------
# HOW TO USE this makefile:
#



# 1)  It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the
#     environment.  This is used as a check to see if vcvars32.bat had been
#     run prior to running nmake or during the installation of Microsoft
#     Visual C++, MSVCDir had been set globally and the PATH adjusted.
#     Either way is valid.
#
#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
#     directory to setup the proper environment, if needed, for your
#     current setup.  This is a needed bootstrap requirement and allows the
#     swapping of different environments to be easier.
#
# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
#     vcvars32.bat according to the instructions for it.  This can also
#     turn on the 64-bit compiler, if your SDK has it.
#
# 3)  Targets are:
#	release  -- Builds the core, the shell and the dlls. (default)
#	dlls     -- Just builds the windows extensions.
#	shell    -- Just builds the shell and the core.
#	core     -- Only builds the core [tkXX.(dll|lib)].
#	all      -- Builds everything.
#	test     -- Builds and runs the test suite.
#	tktest   -- Just builds the binaries for the test suite.
#	install  -- Installs the built binaries and libraries to $(INSTALLDIR)
#		    as the root of the install tree.
#	cwish    -- Builds a console version of wish.
#	tidy/clean/hose -- varying levels of cleaning.
#	genstubs -- Rebuilds the Stubs table and support files (dev only).
#	depend   -- Generates an accurate set of source dependancies for this
#		    makefile.  Helpful to avoid problems when the sources are
#		    refreshed and you rebuild, but can "overbuild" when common
#		    headers like tkInt.h just get small changes.
#	htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the
#		    troff manual pages found in $(ROOT)\doc. You need to
#		    have installed the HTML Help Compiler package from Microsoft
#		    to produce the .chm file.
#	winhelp  -- Builds the windows .hlp file for Tcl from the troff man
#		    files found in $(ROOT)\doc.
#


# 4)  Macros usable on the commandline:
#	TCLDIR=<path>
#		Sets the location for where to find the Tcl headers and
#		libraries.  The install point is assumed when not specified.
#		Tk does need the source directory, though.  Tk comes very close
#		to not needing the sources, but does, in fact, require them.
#


#	INSTALLDIR=<path>
#		Sets where to install Tcl from the built binaries.
#		C:\Progra~1\Tcl is assumed when not specified.
#
#	OPTS=loimpact,msvcrt,nothreads,noxp,pdbs,profile,square,static,staticpkg,symbols,unchecked,none
#		Sets special options for the core.  The default is for none.
#		Any combination of the above may be used (comma separated).
#		'none' will over-ride everything to nothing.

#
#		loimpact = Adds a flag for how NT treats the heap to keep memory
#			   in use, low.  This is said to impact alloc performance.
#		msvcrt   = Affects the static option only to switch it from
#			   using libcmt(d) as the C runtime [by default] to
#			   msvcrt(d). This is useful for static embedding
#			   support.
#		nothreads= Turns off full multithreading support.
#		noxp     = If you do not have the uxtheme.h header then you
#                          cannot include support for XP themeing.
#		square   = Include the demo square widget.
#		static   = Builds a static library of the core instead of a
#			   dll.  The shell will be static (and large), as well.
#		staticpkg= Affects the static option only to switch wishXX.exe
#			   to have the dde and reg extension linked inside it.
#		pdbs     = Build detached symbols for release builds.
#		profile  = Adds profiling hooks.  Map file is assumed.
#		thrdalloc = Use the thread allocator (shared global free pool)
#			   This is the default on threaded builds.
#		tclalloc = Use the old non-thread allocator
#		symbols  = Debug build. Links to the debug C runtime, disables
#			   optimizations and creates pdb symbols files.
#		unchecked = Allows a symbols build to not use the debug
#			   enabled runtime (msvcrt.dll not msvcrtd.dll
#			   or libcmt.lib not libcmtd.lib).
#
#	STATS=compdbg,memdbg,none
#		Sets optional memory and bytecode compiler debugging code added
#		to the core.  The default is for none.  Any combination of the
#		above may be used (comma separated).  'none' will over-ride
#		everything to nothing.
#
#		compdbg  = Enables byte compilation logging.
#		memdbg   = Enables the debugging memory allocator.
#
#	CHECKS=64bit,fullwarn,nodep,none
#		Sets special macros for checking compatability.
#
#		64bit    = Enable 64bit portability warnings (if available)
#		fullwarn = Builds with full compiler and link warnings enabled.
#			    Very verbose.

#		nodep	 = Turns off compatability macros to ensure the core
#			    isn't being built with deprecated functions.
#
#	MACHINE=(ALPHA|AMD64|IA64|IX86)
#		Set the machine type used for the compiler, linker, and
#		resource compiler.  This hook is needed to tell the tools
#		when alternate platforms are requested.  IX86 is the default
#		when not specified. If the CPU environment variable has been
#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
#

#	TMP_DIR=<path>
#	OUT_DIR=<path>
#		Hooks to allow the intermediate and output directories to be
#		changed.  $(OUT_DIR) is assumed to be
#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
#
#	TESTPAT=<file>
#		Reads the tests requested to be run from this file.
#
# 5)  Examples:

#

#	Basic syntax of calling nmake looks like this:
#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
#
#                        Standard (no frills)
#       c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tk_src\win\>nmake -f makefile.vc release
#       c:\tk_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
#
#                         Building for Win64
#       c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tk_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
#       Targeting Windows pre64 RETAIL
#       c:\tk_src\win\>nmake -f makefile.vc MACHINE=IA64
#
#------------------------------------------------------------------------------
#==============================================================================
###############################################################################


#    //==================================================================\\
#   >>[               -> Do not modify below this line. <-               ]<<
#   >>[  Please, use the commandline macros to modify how Tcl is built.  ]<<
#   >>[  If you need more features, send us a patch for more macros.     ]<<
#    \\==================================================================//


###############################################################################
#==============================================================================
#------------------------------------------------------------------------------

!if !exist("makefile.vc")
MSG = ^
You must run this makefile only from the directory it is in.^
Please `cd` to its location first.
!error $(MSG)
!endif


PROJECT = tk
!include "rules.vc"



!if $(TCLINSTALL)
!message *** Warning: Tk requires the source distribution of Tcl to build from,
!message ***    at this time, sorry.  Please set the TCLDIR macro to point to the
!message ***    Tcl sources.
!endif

# Extra makefile options processing...
!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
HAVE_UXTHEME_H    = 1
TTK_SQUARE_WIDGET = 0
!else
!if [nmakehlp -f $(OPTS) "noxp"]
!message *** Exclude support for XP theme
HAVE_UXTHEME_H  = 0
!else
HAVE_UXTHEME_H  = 1
!endif
!if [nmakehlp -f "$(OPTS)" "square"]
!message *** Include ttk square demo widget
TTK_SQUARE_WIDGET   = 1
!else
TTK_SQUARE_WIDGET   = 0
!endif
!endif

STUBPREFIX = $(PROJECT)stub
WISHNAMEPREFIX = wish

BINROOT		= $(MAKEDIR)	# originally .
ROOT		= $(MAKEDIR)\..	# originally ..

TK_LIBRARY	= $(ROOT)\library

TKIMPLIB	= "$(OUT_DIR)\$(PROJECT)$(TK_VERSION)$(SUFX).lib"
TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
TKLIB		= "$(OUT_DIR)\$(TKLIBNAME)"

TKSTUBLIBNAME	= $(STUBPREFIX)$(TK_VERSION).lib
TKSTUBLIB	= "$(OUT_DIR)\$(TKSTUBLIBNAME)"

WISH 		= "$(OUT_DIR)\$(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe"
WISHC 		= "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(TK_VERSION)$(SUFX).exe"

TKTEST		= "$(OUT_DIR)\$(PROJECT)test.exe"
CAT32		= "$(OUT_DIR)\cat32.exe"

LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_DOTVERSION)
INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include

WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(TCL_USE_STATIC_PACKAGES)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	$(TMP_DIR)\tkWinX.obj \
	$(TMP_DIR)\stubs.obj \
	$(TMP_DIR)\tk3d.obj \
	$(TMP_DIR)\tkArgv.obj \
	$(TMP_DIR)\tkAtom.obj \
	$(TMP_DIR)\tkBind.obj \
	$(TMP_DIR)\tkBitmap.obj \
	$(TMP_DIR)\tkBusy.obj \
	$(TMP_DIR)\tkButton.obj \
	$(TMP_DIR)\tkCanvArc.obj \
	$(TMP_DIR)\tkCanvBmap.obj \
	$(TMP_DIR)\tkCanvImg.obj \
	$(TMP_DIR)\tkCanvLine.obj \
	$(TMP_DIR)\tkCanvPoly.obj \
	$(TMP_DIR)\tkCanvPs.obj \







<







290
291
292
293
294
295
296

297
298
299
300
301
302
303
	$(TMP_DIR)\tkWinX.obj \
	$(TMP_DIR)\stubs.obj \
	$(TMP_DIR)\tk3d.obj \
	$(TMP_DIR)\tkArgv.obj \
	$(TMP_DIR)\tkAtom.obj \
	$(TMP_DIR)\tkBind.obj \
	$(TMP_DIR)\tkBitmap.obj \

	$(TMP_DIR)\tkButton.obj \
	$(TMP_DIR)\tkCanvArc.obj \
	$(TMP_DIR)\tkCanvBmap.obj \
	$(TMP_DIR)\tkCanvImg.obj \
	$(TMP_DIR)\tkCanvLine.obj \
	$(TMP_DIR)\tkCanvPoly.obj \
	$(TMP_DIR)\tkCanvPs.obj \
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
	$(TMP_DIR)\tkGC.obj \
	$(TMP_DIR)\tkGeometry.obj \
	$(TMP_DIR)\tkGet.obj \
	$(TMP_DIR)\tkGrab.obj \
	$(TMP_DIR)\tkGrid.obj \
	$(TMP_DIR)\tkImage.obj \
	$(TMP_DIR)\tkImgBmap.obj \
	$(TMP_DIR)\tkImgListFormat.obj \
	$(TMP_DIR)\tkImgGIF.obj \
	$(TMP_DIR)\tkImgPNG.obj \
	$(TMP_DIR)\tkImgPPM.obj \
	$(TMP_DIR)\tkImgSVGnano.obj \
	$(TMP_DIR)\tkImgPhoto.obj \
	$(TMP_DIR)\tkImgPhInstance.obj \
	$(TMP_DIR)\tkImgUtil.obj \
	$(TMP_DIR)\tkListbox.obj \
	$(TMP_DIR)\tkMacWinMenu.obj \
	$(TMP_DIR)\tkMain.obj \
	$(TMP_DIR)\tkMain2.obj \
	$(TMP_DIR)\tkMenu.obj \
	$(TMP_DIR)\tkMenubutton.obj \
	$(TMP_DIR)\tkMenuDraw.obj \
	$(TMP_DIR)\tkMessage.obj \
	$(TMP_DIR)\tkPanedWindow.obj \
	$(TMP_DIR)\tkObj.obj \
	$(TMP_DIR)\tkOldConfig.obj \
	$(TMP_DIR)\tkOption.obj \
	$(TMP_DIR)\tkPack.obj \
	$(TMP_DIR)\tkPkgConfig.obj \
	$(TMP_DIR)\tkPlace.obj \
	$(TMP_DIR)\tkPointer.obj \
	$(TMP_DIR)\tkRectOval.obj \
	$(TMP_DIR)\tkScale.obj \
	$(TMP_DIR)\tkScrollbar.obj \
	$(TMP_DIR)\tkSelect.obj \
	$(TMP_DIR)\tkStyle.obj \







<

<

<

<




<









<







320
321
322
323
324
325
326

327

328

329

330
331
332
333

334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
	$(TMP_DIR)\tkGC.obj \
	$(TMP_DIR)\tkGeometry.obj \
	$(TMP_DIR)\tkGet.obj \
	$(TMP_DIR)\tkGrab.obj \
	$(TMP_DIR)\tkGrid.obj \
	$(TMP_DIR)\tkImage.obj \
	$(TMP_DIR)\tkImgBmap.obj \

	$(TMP_DIR)\tkImgGIF.obj \

	$(TMP_DIR)\tkImgPPM.obj \

	$(TMP_DIR)\tkImgPhoto.obj \

	$(TMP_DIR)\tkImgUtil.obj \
	$(TMP_DIR)\tkListbox.obj \
	$(TMP_DIR)\tkMacWinMenu.obj \
	$(TMP_DIR)\tkMain.obj \

	$(TMP_DIR)\tkMenu.obj \
	$(TMP_DIR)\tkMenubutton.obj \
	$(TMP_DIR)\tkMenuDraw.obj \
	$(TMP_DIR)\tkMessage.obj \
	$(TMP_DIR)\tkPanedWindow.obj \
	$(TMP_DIR)\tkObj.obj \
	$(TMP_DIR)\tkOldConfig.obj \
	$(TMP_DIR)\tkOption.obj \
	$(TMP_DIR)\tkPack.obj \

	$(TMP_DIR)\tkPlace.obj \
	$(TMP_DIR)\tkPointer.obj \
	$(TMP_DIR)\tkRectOval.obj \
	$(TMP_DIR)\tkScale.obj \
	$(TMP_DIR)\tkScrollbar.obj \
	$(TMP_DIR)\tkSelect.obj \
	$(TMP_DIR)\tkStyle.obj \
300
301
302
303
304
305
306
307
308

309
310
311


312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327

328











329









330

331

332













333







































334












335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

372




373
374
375
376
377
378
379
380
381
382

383




384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430




431


432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529


















530

531


532


533










534


535


536



















537




538


















539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
        $(TMP_DIR)\ttkWidget.obj \
        $(TMP_DIR)\ttkStubInit.obj

TKSTUBOBJS = \
	$(TMP_DIR)\tkStubLib.obj \
	$(TMP_DIR)\ttkStubLib.obj

### The following paths CANNOT have spaces in them as they appear on
### the left side of implicit rules.

XLIBDIR		= $(ROOT)\xlib
TTKDIR		= $(ROOT)\generic\ttk
BITMAPDIR	= $(ROOT)\bitmaps



# Additional include and C macro definitions for the implicit rules
# defined in rules.vc
PRJ_INCLUDES	= -I"$(BITMAPDIR)" -I"$(XLIBDIR)"


CONFIG_DEFS     =/DSTDC_HEADERS=1 /DHAVE_SYS_TYPES_H=1 /DHAVE_SYS_STAT_H=1 \
		 /DHAVE_STRING_H=1 /DHAVE_MEMORY_H=1 \
		 /DHAVE_STRINGS_H=1 \
		 /DSUPPORT_CONFIG_EMBEDDED \
!if $(HAVE_UXTHEME_H)
		 /DHAVE_UXTHEME_H=1 \
!endif
!if $(TTK_SQUARE_WIDGET)
		 /DTTK_SQUARE_WIDGET=1 \
!endif
!if $(TK_NO_DEPRECATED)

		 /DTK_NO_DEPRECATED=1











!endif











PRJ_DEFINES	= /DBUILD_ttk $(CONFIG_DEFS) /Dinline=__inline /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE















# Additional Link libraries needed beyond those in rules.vc







































PRJ_LIBS   = netapi32.lib gdi32.lib user32.lib userenv.lib














#---------------------------------------------------------------------
# TkTest flags
#---------------------------------------------------------------------

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif


#---------------------------------------------------------------------
# Project specific targets
#---------------------------------------------------------------------

release:  setup $(TKSTUBLIB) $(WISH)
all:	  release $(CAT32)
core:	  setup $(TKSTUBLIB) $(TKLIB)
cwish:	  $(WISHC)
install:  install-binaries install-libraries install-docs
!if $(SYMBOLS)
install:    install-pdbs
!endif
tktest:	  setup $(TKTEST) $(CAT32)

setup: default-setup

test: test-classic test-ttk

test-classic: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif

	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) | $(CAT32)





test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif

	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32)





runtest: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(DEBUGGER) $(TKTEST)

rundemo: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(TKTEST) $(ROOT:\=/)\library\demos\widget

shell: setup $(WISH)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(DEBUGGER) $(WISH) <<
	console show
<<

dbgshell: setup $(WISH)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(LIBDIR:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	windbg $(WISH)





!if $(STATIC_BUILD)



$(TKLIB): $(TKOBJS)
	$(LIBCMD) @<<

$**
<<

!else

$(TKLIB): $(TKOBJS)
	$(DLLCMD) @<<
$**
<<
	$(_VC_MANIFEST_EMBED_DLL)
	@if exist $*.exp del $*.exp

$(TKIMPLIB): $(TKLIB)

!endif # $(STATIC_BUILD)

$(TKSTUBLIB): $(TKSTUBOBJS)
	$(LIBCMD) -nodefaultlib $**


$(WISH): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
	$(GUIEXECMD) -stack:2300000 $**
	$(_VC_MANIFEST_EMBED_EXE)


$(WISHC): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
	$(CONEXECMD) -stack:2300000 $**
	$(_VC_MANIFEST_EMBED_EXE)


$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB)
	$(GUIEXECMD) -stack:2300000 $**
	$(_VC_MANIFEST_EMBED_EXE)


$(CAT32): $(_TCLDIR)\win\cat.c
	$(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $?
	$(CONEXECMD) /DCONSOLE -stack:16384 $(TMP_DIR)\cat.obj
	$(_VC_MANIFEST_EMBED_EXE)

#---------------------------------------------------------------------
# Regenerate the stubs files.  [Development use only]
#---------------------------------------------------------------------

genstubs:
!if !exist($(TCLSH))
	@echo Build tclsh first!
!else
	set TCL_LIBRARY=$(TCL_LIBRARY)
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
		$(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
!endif


#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------

!if defined(PROCESSOR_ARCHITECTURE) && "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
HHC="%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe"
!else
HHC="%ProgramFiles%\HTML Help Workshop\hhc.exe"
!endif
HTMLDIR=$(ROOT)\html
HTMLBASE=TclTk$(TCL_VERSION)
HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp
CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm

htmlhelp: chmsetup $(CHMFILE)

$(CHMFILE): $(DOCDIR)\*
	@$(TCLSH) $(TCLTOOLSDIR)\tcltk-man2html.tcl
	@echo Compiling HTML help project
	@"$(HHC)" <<$(HHPFILE) >NUL
[OPTIONS]
Compatibility=1.1 or later
Compiled file=$(HTMLBASE).chm
Display compile progress=no
Error log file=$(HTMLBASE).log
Language=0x409 English (United States)
Title=Tcl/Tk $(TCL_DOTVERSION) Help
[FILES]
contents.htm
docs.css
Keywords
TclCmd
TclLib
TkCmd
TkLib
UserCmd
<<

chmsetup:
	@if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR)



















install-docs:

!if exist("$(CHMFILE)")


	@echo Installing compiled HTML help


	@$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\"










!endif


# "emacs font-lock highlighting fix






















install-pdbs:




	@echo Installing debug symbols


















	@$(CPY) "$(OUT_DIR)\*.pdb" "$(BIN_INSTALL_DIR)\"
# "emacs font-lock highlighting fix


#---------------------------------------------------------------------
# Special case object file targets
#---------------------------------------------------------------------

$(TMP_DIR)\testMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DTK_TEST /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?

$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\winMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?

$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
	$(cc32) $(pkgcflags) /DUNICODE /D_UNICODE -Fo$@ $?

# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported
# and no reference made to a C runtime.

$(TMP_DIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
	$(cc32) $(stubscflags) -Fo$@ $?

$(TMP_DIR)\ttkStubLib.obj : $(TTKDIR)\ttkStubLib.c
	$(cc32) $(stubscflags) -Fo$@ $?

$(TMP_DIR)\wish.exe.manifest: $(WIN_DIR)\wish.exe.manifest.in
	@nmakehlp -s << $** >$@
@MACHINE@	  $(MACHINE:IX86=X86)
@TK_WIN_VERSION@  $(DOTVERSION).0.0
<<

#---------------------------------------------------------------------
# Generate the source dependencies.  Having dependency rules will
# improve incremental build accuracy without having to resort to a
# full rebuild just because some non-global header file like
# tclCompile.h was changed.  These rules aren't needed when building







|
|
>



>
>

<
<
|
>


|
|







|
>
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>

>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>









>










<
<
<


<





|






>

>
>
>
>



|






>

>
>
>
>



|










|










|












|








>
>
>
>
|
>
>


|
>


<

|
<
|



|
|
<

<


|


|
|



|
|



|
|




|
|




















|
<
|
|


|








|






|














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>






|




|


|


|


|


|



<
<
<




|
|

<
<




|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416


417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544



545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640

641
642

643
644
645
646
647
648

649

650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844



845
846
847
848
849
850
851


852
853
854
855
856
857
858
859
860
861
862
863
        $(TMP_DIR)\ttkWidget.obj \
        $(TMP_DIR)\ttkStubInit.obj

TKSTUBOBJS = \
	$(TMP_DIR)\tkStubLib.obj \
	$(TMP_DIR)\ttkStubLib.obj


WIN_DIR          = $(ROOT)\win
GENERICDIR	= $(ROOT)\generic
XLIBDIR		= $(ROOT)\xlib
TTKDIR		= $(ROOT)\generic\ttk
BITMAPDIR	= $(ROOT)\bitmaps
DOCDIR		= $(ROOT)\doc
RCDIR		= $(WIN_DIR)\rc



TK_INCLUDES	= -I"$(WIN_DIR)" -I"$(GENERICDIR)" -I"$(BITMAPDIR)" -I"$(XLIBDIR)" \
			$(TCL_INCLUDES)

CONFIG_DEFS     =/DSTDC_HEADERS=1 /DHAVE_SYS_TYPES_H=1 /DHAVE_SYS_STAT_H=1 \
		 /DHAVE_STDLIB_H=1 /DHAVE_STRING_H=1 /DHAVE_MEMORY_H=1 \
		 /DHAVE_STRINGS_H=1 /DHAVE_INTTYPES_H=1 \
		 /DSUPPORT_CONFIG_EMBEDDED \
!if $(HAVE_UXTHEME_H)
		 /DHAVE_UXTHEME_H=1 \
!endif
!if $(TTK_SQUARE_WIDGET)
		 /DTTK_SQUARE_WIDGET=1 \
!endif

TK_DEFINES	=/DBUILD_ttk $(OPTDEFINES)  $(CONFIG_DEFS) /Dinline=__inline

#---------------------------------------------------------------------
# Compile flags
#---------------------------------------------------------------------

!if !$(DEBUG)
!if $(OPTIMIZING)
### This cranks the optimization level to maximize speed
###  We can't use -O2 because sometimes it causes problems.
cdebug	= $(OPTIMIZATIONS)
!else
cdebug	=
!endif
!if $(SYMBOLS)
cdebug	= $(cdebug) -Zi
!endif
!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
### Warnings are too many, can't support warnings into errors.
cdebug	= -Zi -Od $(DEBUGFLAGS)
!else
cdebug	= -Zi -WX $(DEBUGFLAGS)
!endif

### Declarations common to all compiler options
cwarn = $(WARNINGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\

!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else
crt = -MT
!endif
!endif

BASE_CFLAGS	= $(cdebug) $(cflags) $(crt) $(TK_INCLUDES)
TK_CFLAGS	= $(BASE_CFLAGS) $(TK_DEFINES) /DUSE_TCL_STUBS
CON_CFLAGS	= $(cdebug) $(cflags) $(crt) /DCONSOLE
WISH_CFLAGS	= $(BASE_CFLAGS) $(TK_DEFINES)
STUB_CFLAGS     = $(cflags) $(cdebug) $(TK_DEFINES)


#---------------------------------------------------------------------
# Link flags
#---------------------------------------------------------------------

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3
!if $(SYMBOLS)
ldebug	= $(ldebug) -debug -debugtype:cv
!endif
!endif

### Declarations common to all linker options
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)

!if $(PROFILE)
lflags	= $(lflags) -profile
!endif

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
lflags	= $(lflags) -nodefaultlib:libucrt.lib
!endif

!if $(LOIMPACT)
lflags	= $(lflags) -ws:aggressive
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

baselibs   = kernel32.lib user32.lib ws2_32.lib
# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
baselibs   = $(baselibs) bufferoverflowU.lib
!endif
!endif
!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
baselibs   = $(baselibs) ucrt.lib
!endif

guilibs	  = $(baselibs) gdi32.lib


#---------------------------------------------------------------------
# TkTest flags
#---------------------------------------------------------------------

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif


#---------------------------------------------------------------------
# Project specific targets
#---------------------------------------------------------------------

release:  setup $(TKSTUBLIB) $(WISH)
all:	  release $(CAT32)
core:	  setup $(TKSTUBLIB) $(TKLIB)
cwish:	  $(WISHC)
install:  install-binaries install-libraries install-docs



tktest:	  setup $(TKTEST) $(CAT32)



test: test-classic test-ttk

test-classic: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) | $(CAT32)
!else
	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) > tests.log
	type tests.log | more
!endif

test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32)
!else
	$(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/ttk/all.tcl" $(TESTFLAGS) > tests.log
	type tests.log | more
!endif

runtest: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(DEBUGGER) $(TKTEST)

rundemo: setup $(TKTEST) $(TKLIB) $(CAT32)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(TKTEST) $(ROOT:\=/)\library\demos\widget

shell: setup $(WISH)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	$(DEBUGGER) $(WISH) <<
	console show
<<

dbgshell: setup $(WISH)
	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
	@set TK_LIBRARY=$(TK_LIBRARY:\=/)
	@set TCLLIBPATH=
!if $(TCLINSTALL)
	@set PATH=$(_TCLDIR)\bin;$(PATH)
!else
	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
	windbg $(WISH)

setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

!if !$(STATIC_BUILD)
$(TKIMPLIB): $(TKLIB)
!endif

$(TKLIB): $(TKOBJS)
!if $(STATIC_BUILD)
	$(lib32) -nologo -out:$@ @<<
$**
<<

!else
	$(link32) $(dlllflags) -base:@$(COFFBASE),tk -out:$@ $(guilibs) \

		$(TCLSTUBLIB) @<<
$**
<<
	$(_VC_MANIFEST_EMBED_DLL)
	-@del $*.exp
!endif




$(TKSTUBLIB): $(TKSTUBOBJS)
	$(lib32) -nologo -nodefaultlib -out:$@ $**


$(WISH): $(WISHOBJS) $(TKIMPLIB)
	$(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
	$(_VC_MANIFEST_EMBED_EXE)


$(WISHC): $(WISHOBJS) $(TKIMPLIB)
	$(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
	$(_VC_MANIFEST_EMBED_EXE)


$(TKTEST): $(TKTESTOBJS) $(TKIMPLIB)
	$(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
	$(_VC_MANIFEST_EMBED_EXE)


$(CAT32): $(_TCLDIR)\win\cat.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $?
	$(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj $(baselibs)
	$(_VC_MANIFEST_EMBED_EXE)

#---------------------------------------------------------------------
# Regenerate the stubs files.  [Development use only]
#---------------------------------------------------------------------

genstubs:
!if !exist($(TCLSH))
	@echo Build tclsh first!
!else
	set TCL_LIBRARY=$(TCL_LIBRARY)
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
		$(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
!endif


#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------

# NOTE: you can define HHC on the command-line to override this

!ifndef HHC
HHC=""%ProgramFiles%\HTML Help Workshop\hhc.exe""
!endif
HTMLDIR=$(ROOT)\html
HTMLBASE=TclTk$(VERSION)
HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp
CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm

htmlhelp: chmsetup $(CHMFILE)

$(CHMFILE): $(DOCDIR)\*
	@$(TCLSH) $(TCLTOOLSDIR)\tcltk-man2html.tcl
	@echo Compiling HTML help project
	@$(HHC) <<$(HHPFILE) >NUL
[OPTIONS]
Compatibility=1.1 or later
Compiled file=$(HTMLBASE).chm
Display compile progress=no
Error log file=$(HTMLBASE).log
Language=0x409 English (United States)
Title=Tcl/Tk $(DOT_VERSION) Help
[FILES]
contents.htm
docs.css
Keywords
TclCmd
TclLib
TkCmd
TkLib
UserCmd
<<

chmsetup:
	@if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR)

#-------------------------------------------------------------------------
# Build the old-style Windows .hlp file
#-------------------------------------------------------------------------

HLPBASE		= $(PROJECT)$(TK_VERSION)
HELPFILE	= $(OUT_DIR)\$(HLPBASE).hlp
HELPCNT		= $(OUT_DIR)\$(HLPBASE).cnt
DOCTMP_DIR	= $(OUT_DIR)\$(PROJECT)_docs
HELPRTF		= $(DOCTMP_DIR)\$(PROJECT).rtf
MAN2HELP	= $(DOCTMP_DIR)\man2help.tcl
MAN2HELP2	= $(DOCTMP_DIR)\man2help2.tcl
INDEX		= $(DOCTMP_DIR)\index.tcl
BMP		= $(DOCTMP_DIR)\lamp.bmp
BMP_NOPATH	= lamp.bmp
MAN2TCL		= $(DOCTMP_DIR)\man2tcl.exe

winhelp: docsetup $(HELPFILE)

docsetup:
	@if not exist $(DOCTMP_DIR)\nul mkdir $(DOCTMP_DIR)

$(MAN2HELP) $(MAN2HELP2) $(INDEX): $(TCLTOOLSDIR)\$$(@F)
	$(CPY) $(TCLTOOLSDIR)\$(@F) $(@D)

$(BMP):
	$(CPY) $(WIN_DIR)\rc\$(@F) $(@D)

$(HELPFILE): $(HELPRTF) $(BMP)
	cd $(DOCTMP_DIR)
	start /wait hcrtf.exe -x <<$(PROJECT).hpj
[OPTIONS]
COMPRESS=12 Hall Zeck
LCID=0x409 0x0 0x0 ; English (United States)
TITLE=Tk Reference Manual
BMROOT=.
CNT=$(@B).cnt
HLP=$(@B).hlp

[FILES]
$(PROJECT).rtf

[WINDOWS]
main="Tcl/Tk Reference Manual",,27648,(r15263976),(r4227327)

[CONFIG]
BrowseButtons()
CreateButton(1, "Web", ExecFile("http://www.tcl.tk"))
CreateButton(2, "SF", ExecFile("http://sf.net/projects/tcl"))
CreateButton(3, "Wiki", ExecFile("http://wiki.tcl.tk"))
CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/"))
<<
	cd $(MAKEDIR)
	@$(CPY) "$(DOCTMP_DIR)\$(@B).hlp" "$(OUT_DIR)"
	@$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)"

$(MAN2TCL): $(TCLTOOLSDIR)\$$(@B).c
	$(cc32) $(TK_CFLAGS) -Fo$(@D)\ $(TCLTOOLSDIR)\$(@B).c
	$(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj
	$(_VC_MANIFEST_EMBED_EXE)

$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX)
	$(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(TK_VERSION) $(DOCDIR:\=/)

install-docs:
!if exist($(HELPFILE))
	$(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\"
	$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\"
	$(TCLSH) <<
puts "Installing $(PROJECT)'s helpfile contents into Tcl's ..."
set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" r]
while {![eof $$f]} {
    if {[regexp {:Include $(PROJECT)([0-9]{2}).cnt} [gets $$f] dummy ver]} {
	if {$$ver == $(TK_VERSION)} {
	    puts "Already installed."
	    exit
	} else {
	    # do something here logical to remove (or replace) it.
	    puts "$$ver != $(TK_VERSION), unfinished code path, die, die!"
	    exit 1
	}
    }
}
close $$f
set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" a]
puts $$f {:Include $(HLPBASE).cnt}
close $$f
<<
	start /wait winhlp32 -g $(DOC_INSTALL_DIR)\tcl$(TK_VERSION).hlp

!endif

#---------------------------------------------------------------------
# Special case object file targets
#---------------------------------------------------------------------

$(TMP_DIR)\testMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(WISH_CFLAGS) /DTK_TEST \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?

$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
	$(cc32) $(WISH_CFLAGS) -Fo$@ $?

$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
	$(cc32) $(WISH_CFLAGS) -Fo$@ $?

$(TMP_DIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
	$(cc32) $(WISH_CFLAGS) -Fo$@ $?

$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
	$(cc32) $(WISH_CFLAGS) -Fo$@ $?

$(TMP_DIR)\winMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(WISH_CFLAGS) \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?




# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported
# and no reference made to a C runtime.

$(TMP_DIR)\tkStubLib.obj: $(GENERICDIR)\tkStubLib.c
	$(cc32) $(STUB_CFLAGS) $(TK_INCLUDES) -Zl /DSTATIC_BUILD -Fo$@ $?




$(TMP_DIR)\wish.exe.manifest: $(WIN_DIR)\wish.exe.manifest.in
	@nmakehlp -s << $** >$@
@MACHINE@	  $(MACHINE:IX86=X86)
@TK_WIN_VERSION@  $(TK_DOTVERSION).0.0
<<

#---------------------------------------------------------------------
# Generate the source dependencies.  Having dependency rules will
# improve incremental build accuracy without having to resort to a
# full rebuild just because some non-global header file like
# tclCompile.h was changed.  These rules aren't needed when building
625
626
627
628
629
630
631



632


633
634
635
636



637


638
639
640
641
642
643
644







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722





















!message

#---------------------------------------------------------------------
# Implicit rules
#---------------------------------------------------------------------

{$(XLIBDIR)}.c{$(TMP_DIR)}.obj::



	$(CCPKGCMD) @<<


$<
<<

{$(TTKDIR)}.c{$(TMP_DIR)}.obj::



	$(CCPKGCMD) @<<


$<
<<

{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<








$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest

.SUFFIXES:
.SUFFIXES:.c .rc


#---------------------------------------------------------------------
# Installation.
#---------------------------------------------------------------------

install-binaries:
	@echo installing binaries
	@$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\"
!if "$(TKLIB)" != "$(TKIMPLIB)"
	@$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\"
!endif
	@$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\"
	@$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
!if !$(STATIC_BUILD)
	@echo creating package index
	@type << > $(OUT_DIR)\pkgIndex.tcl
if {[catch {package present Tcl 8.6-}]} { return }
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
	|| ([info exists ::argv] && ("-display" in $$::argv)))} {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(DOTVERSION).dll] Tk]
} else {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk]
}
<<
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
!endif

#"

install-libraries:
	@echo installing Tk headers
	@$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"
	@echo installing script library
	@$(CPY) "$(LIBDIR)\*" "$(SCRIPT_INSTALL_DIR)\"
	@echo installing theme library
	@$(CPY) "$(LIBDIR)\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
	@echo installing images
	@$(CPY) "$(LIBDIR)\images\*" "$(SCRIPT_INSTALL_DIR)\images\"

	@echo installing language files
	@$(CPY) "$(LIBDIR)\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
	@echo installing demos
	@$(CPY) "$(DEMODIR)\*" "$(DEMO_INSTALL_DIR)\"
	@$(CPY) "$(DEMODIR)\images\*" "$(DEMO_INSTALL_DIR)\images\"

#"

#---------------------------------------------------------------------
# Clean up
#---------------------------------------------------------------------

clean: default-clean
realclean: hose
hose: default-hose
tidy:
!if "$(TKLIB)" != "$(TKIMPLIB)"
	@echo Removing $(TKLIB) ...
	@if exist $(TKLIB) del $(TKLIB)
!endif
	@echo Removing $(TKIMPLIB) ...
	@if exist $(TKIMPLIB) del $(TKIMPLIB)
	@echo Removing $(WISH) ...
	@if exist $(WISH) del $(WISH)
	@echo Removing $(TKTEST) ...
	@if exist $(TKTEST) del $(TKTEST)
	@echo Removing $(TKSTUBLIB) ...
	@if exist $(TKSTUBLIB) del $(TKSTUBLIB)





























>
>
>
|
>
>




>
>
>
|
>
>




|


>
>
>
>
>
>
>















|







|


|

|















|

|
|
|
>
|
|
|
|
<







<
<
<

|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994



995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
!message

#---------------------------------------------------------------------
# Implicit rules
#---------------------------------------------------------------------

{$(XLIBDIR)}.c{$(TMP_DIR)}.obj::
	$(cc32) /DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
	$(cc32) /DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(TTKDIR)}.c{$(TMP_DIR)}.obj::
	$(cc32) /DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(WIN_DIR)}.c{$(TMP_DIR)}.obj::
	$(cc32) /DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
	$(cc32) /DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(RCDIR)}.rc{$(TMP_DIR)}.res:
	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" $(TCL_INCLUDES) \
	    -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    -d TCL_THREADS=$(TCL_THREADS) \
	    -d STATIC_BUILD=$(STATIC_BUILD) \
	    $<

$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest

.SUFFIXES:
.SUFFIXES:.c .rc


#---------------------------------------------------------------------
# Installation.
#---------------------------------------------------------------------

install-binaries:
	@echo installing binaries
	@$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\"
!if $(TKLIB) != $(TKIMPLIB)
	@$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\"
!endif
	@$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\"
	@$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
!if !$(STATIC_BUILD)
	@echo creating package index
	@type << > $(OUT_DIR)\pkgIndex.tcl
if {![package vsatisfies [package provide Tcl] $(TK_DOTVERSION).0]} return
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
	|| ([info exists ::argv] && ("-display" in $$::argv)))} {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(TK_DOTVERSION).dll]]
} else {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)]]
}
<<
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
!endif

#"

install-libraries:
	@echo installing Tk headers
	@$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"
	@echo installing script library
	@$(CPY) "$(ROOT)\library\*" "$(SCRIPT_INSTALL_DIR)\"
	@echo installing theme library
	@$(CPY) "$(ROOT)\library\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
	@echo installing demos
	@$(CPY) "$(ROOT)\library\demos\*" "$(SCRIPT_INSTALL_DIR)\demos\"
	@$(CPY) "$(ROOT)\library\demos\images\*" "$(SCRIPT_INSTALL_DIR)\demos\images\"
	@echo installing images
	@$(CPY) "$(ROOT)\library\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
	@echo installing language files
	@$(CPY) "$(ROOT)\library\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"


#"

#---------------------------------------------------------------------
# Clean up
#---------------------------------------------------------------------




tidy:
!if $(TKLIB) != $(TKIMPLIB)
	@echo Removing $(TKLIB) ...
	@if exist $(TKLIB) del $(TKLIB)
!endif
	@echo Removing $(TKIMPLIB) ...
	@if exist $(TKIMPLIB) del $(TKIMPLIB)
	@echo Removing $(WISH) ...
	@if exist $(WISH) del $(WISH)
	@echo Removing $(TKTEST) ...
	@if exist $(TKTEST) del $(TKTEST)
	@echo Removing $(TKSTUBLIB) ...
	@if exist $(TKSTUBLIB) del $(TKSTUBLIB)

clean:
	@echo Cleaning $(TMP_DIR)\* ...
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
	@echo Cleaning $(WIN_DIR)\nmakehlp.obj ...
	@if exist $(WIN_DIR)\nmakehlp.obj del $(WIN_DIR)\nmakehlp.obj
	@echo Cleaning $(WIN_DIR)\nmakehlp.exe ...
	@if exist $(WIN_DIR)\nmakehlp.exe del $(WIN_DIR)\nmakehlp.exe
	@echo Cleaning $(WIN_DIR)\_junk.pch ...
	@if exist $(WIN_DIR)\_junk.pch del $(WIN_DIR)\_junk.pch
	@echo Cleaning $(WIN_DIR)\vercl.x ...
	@if exist $(WIN_DIR)\vercl.x del $(WIN_DIR)\vercl.x
	@echo Cleaning $(WIN_DIR)\vercl.i ...
	@if exist $(WIN_DIR)\vercl.i del $(WIN_DIR)\vercl.i
	@echo Cleaning $(WIN_DIR)\versions.vc ...
	@if exist $(WIN_DIR)\versions.vc del $(WIN_DIR)\versions.vc

realclean: hose

hose:
	@echo Hosing $(OUT_DIR)\* ...
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

Added win/mkd.bat.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
@echo off

if exist %1\nul goto end

md %1
if errorlevel 1 goto end

echo Created directory %1

:end


Changes to win/nmakehlp.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_REG
#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)







|
<
<
<


|







10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#ifdef _MSC_VER



#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#endif
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;

pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};

/*
 * exitcodes: 0 == no, 1 == yes, 2 == error
 */

int
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);








|
















|
|













|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;

pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};

/*
 * exitcodes: 0 == no, 1 == yes, 2 == error
 */

int
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    const char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.







|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}

static int
CheckForLinkerFeature(
    const char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}

static int
CheckForLinkerFeature(
    char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.







|







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{
    size_t cbBuffer = 100;
    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
	/*
	 * Read data until we see our match string.
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit(*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
			    && (!strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}

		memcpy(szBuffer, p, q - p);
		szBuffer[q-p] = 0;
		szResult = szBuffer;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}







<









|









|








|
|



<
|
|







501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{

    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
	/*
	 * Read data until we see our match string.
	 */

	while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit((unsigned char)*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
			    && !strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}


		*q = 0;
		szResult = p;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
    char * value;
} list_item_t;

/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
    list_item_t *itemPtr = malloc(sizeof(list_item_t));
    if (itemPtr) {
	itemPtr->key = strdup(key);
	itemPtr->value = strdup(value);
	itemPtr->nextPtr = NULL;

	while(*listPtrPtr) {
	    listPtrPtr = &(*listPtrPtr)->nextPtr;







|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    char * value;
} list_item_t;

/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
    list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
    if (itemPtr) {
	itemPtr->key = strdup(key);
	itemPtr->value = strdup(value);
	itemPtr->nextPtr = NULL;

	while(*listPtrPtr) {
	    listPtrPtr = &(*listPtrPtr)->nextPtr;
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690











691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    size_t cbBuffer = 1024;
    static char szBuffer[1024], szCopy[1024];
    char *szResult = NULL;
    list_item_t *substPtr = NULL;
    FILE *fp, *sp;

    fp = fopen(filename, "rt");
    if (fp != NULL) {

	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
		    op = szBuffer;
		    while (op != m) *cp++ = *op++;
		    sp = p->value;
		    while (sp && *sp) *cp++ = *sp++;
		    op += strlen(p->key);
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf(szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}












/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];
    char szTmp[MAX_PATH + 1];
    char *p;
    GetCurrentDirectory(MAX_PATH, szCwd);
    while ((p = strchr(szPath, '/')) && *p)
	*p = '\\';
    PathCombine(szTmp, szCwd, szPath);
    PathCanonicalize(szCwd, szTmp);
    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];

    int dirlen, keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;







<

<












|
















|













|
















|








>
>
>
>
>
>
>
>
>
>
>













|
<
<
|
<
<
<
















>
|







607
608
609
610
611
612
613

614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708


709



710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{

    static char szBuffer[1024], szCopy[1024];

    list_item_t *substPtr = NULL;
    FILE *fp, *sp;

    fp = fopen(filename, "rt");
    if (fp != NULL) {

	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifndef NDEBUG
	{
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
		    op = szBuffer;
		    while (op != m) *cp++ = *op++;
		    sp = p->value;
		    while (sp && *sp) *cp++ = *sp++;
		    op += strlen(p->key);
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf("%s", szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}

BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
    #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
    DWORD pathAttr = GetFileAttributes(szPath);
    return (pathAttr != INVALID_FILE_ATTRIBUTES &&
	    !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}


/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];



    GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);



    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];
    size_t dirlen;
    int keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (PathFileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));







|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (FileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));
787
788
789
790
791
792
793

794
795
796
797
798
799
800
801
802
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{

    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;







>
|
|







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    size_t i;
    int ret;
    static const char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;

Changes to win/rc/lamp.bmp.

cannot compute difference between binary files

Changes to win/rc/tk.ico.

cannot compute difference between binary files

Changes to win/rc/tk.rc.

1
2
3
4
5
6
7
8
9
10






11
12
13
14
15
16
17
18
19
20
21
22
23
24
//
// Version Resource Script
//

#include <windows.h>
#include <tk.h>

//
// build-up the name suffix that defines the type of build this is.
//






#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG	    "g"
#else
#define SUFFIX_DEBUG	    ""
#endif

#define SUFFIX		    SUFFIX_DEBUG


VS_VERSION_INFO	VERSIONINFO
 FILEVERSION	TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 PRODUCTVERSION	TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG










>
>
>
>
>
>






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//
// Version Resource Script
//

#include <windows.h>
#include <tk.h>

//
// build-up the name suffix that defines the type of build this is.
//
#if TCL_THREADS
#define SUFFIX_THREADS	    "t"
#else
#define SUFFIX_THREADS	    ""
#endif

#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG	    "g"
#else
#define SUFFIX_DEBUG	    ""
#endif

#define SUFFIX		    SUFFIX_THREADS SUFFIX_DEBUG


VS_VERSION_INFO	VERSIONINFO
 FILEVERSION	TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 PRODUCTVERSION	TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG

Changes to win/rc/wish.ico.

cannot compute difference between binary files

Changes to win/rc/wish.rc.

1
2
3
4
5
6
7
8
9
10






11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//
// Version Resource Script
//

#include <windows.h>
#include <tk.h>

//
// build-up the name suffix that defines the type of build this is.
//






#if STATIC_BUILD
#define SUFFIX_STATIC	    "s"
#else
#define SUFFIX_STATIC	    ""
#endif

#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG	    "g"
#else
#define SUFFIX_DEBUG	    ""
#endif

#define SUFFIX		    SUFFIX_STATIC SUFFIX_DEBUG


VS_VERSION_INFO VERSIONINFO
 FILEVERSION    TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 PRODUCTVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG










>
>
>
>
>
>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//
// Version Resource Script
//

#include <windows.h>
#include <tk.h>

//
// build-up the name suffix that defines the type of build this is.
//
#if TCL_THREADS
#define SUFFIX_THREADS	    "t"
#else
#define SUFFIX_THREADS	    ""
#endif

#if STATIC_BUILD
#define SUFFIX_STATIC	    "s"
#else
#define SUFFIX_STATIC	    ""
#endif

#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG	    "g"
#else
#define SUFFIX_DEBUG	    ""
#endif

#define SUFFIX		    SUFFIX_THREADS SUFFIX_STATIC SUFFIX_DEBUG


VS_VERSION_INFO VERSIONINFO
 FILEVERSION    TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 PRODUCTVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG

Added win/rmd.bat.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@echo off

if not exist %1\nul goto end

echo Removing directory %1

if "%OS%" == "Windows_NT" goto winnt

deltree /y %1
if errorlevel 1 goto end
goto success

:winnt
rmdir /s /q %1
if errorlevel 1 goto end

:success
echo Deleted directory %1

:end

Deleted win/rules-ext.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.

!ifndef _RULES_EXT_VC

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif

!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif

# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
!endif

# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""

_RULESDIR = $(TCLDIR:/=\)

!else

# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif

!endif # defined(INSTALLDIR)....

!endif # ifndef TCLDIR

# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif

!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.

!if exist("rules.vc") # The extension has its own copy

!if [echo TCL_RULES_MAJOR = \> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif

!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif

!endif # if exist("rules.vc")

!endif # if $(_RULESDIR) != "."

# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c

# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR

!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif

!endif # _RULES_EXT_VC
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Changes to win/rules.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143





144
145
146








147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584

585
586

587
588
589
590
591
592
593
594
595
596
597


598

599
600
601



602

603
604
605



606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634






635









636


637






638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686

687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735


736
737
738
739



740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790



791
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999


1000

1001
1002
1003

1004

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151


1152
1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245


1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256


1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390

1391
1392
1393
1394

1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427





1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470



1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510

1511
1512


1513


1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548



1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600




1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683




1684

1685
1686




1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706


1707
1708
1709
1710



1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752


1753



1754
1755
1756
1757
1758
1759
1760
1761


1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777



1778
1779
1780



1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805

1806



1807
1808
#------------------------------------------------------------- -*- makefile -*-
# rules.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file does all the hard work in terms of parsing build options,
# compiler switches, defining common targets and macros. The Tcl makefile
# directly includes this. Extensions include it via "rules-ext.vc".
#
# See TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
# Copyright (c) 2003-2008 Patrick Thoyts
# Copyright (c) 2017      Ashok P. Nadkarni
#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 6

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""
PRJ_PACKAGE_TCLNAME = $(PROJECT)
!endif

# Also special case Tcl and Tk to save some typing later
DOING_TCL = 0
DOING_TK  = 0
!if "$(PROJECT)" == "tcl"
DOING_TCL = 1
!elseif "$(PROJECT)" == "tk"
DOING_TK = 1
!endif

!ifndef NEED_TK
# Backwards compatibility
!ifdef PROJECT_REQUIRES_TK
NEED_TK = $(PROJECT_REQUIRES_TK)
!else
NEED_TK = 0
!endif
!endif

!ifndef NEED_TCL_SOURCE
NEED_TCL_SOURCE = 0
!endif

!ifdef NEED_TK_SOURCE
!if $(NEED_TK_SOURCE)
NEED_TK = 1
!endif
!else
NEED_TK_SOURCE = 0
!endif

################################################################
# Nmake is a pretty weak environment in syntax and capabilities
# so this file is necessarily verbose. It's broken down into
# the following parts.
#
# 0. Sanity check that compiler environment is set up and initialize
#    any built-in settings from the parent makefile
# 1. First define the external tools used for compiling, copying etc.
#    as this is independent of everything else.
# 2. Figure out our build structure in terms of the directory, whether
#    we are building Tcl or an extension, etc.
# 3. Determine the compiler and linker versions
# 4. Build the nmakehlp helper application
# 5. Determine the supported compiler options and features
# 6. Parse the OPTS macro value for user-specified build configuration
# 7. Parse the STATS macro value for statistics instrumentation
# 8. Parse the CHECKS macro for additional compilation checks
# 9. Extract Tcl, and possibly Tk, version numbers from the headers
# 10. Based on this selected configuration, construct the output
#     directory and file paths
# 11. Construct the paths where the package is to be installed
# 12. Set up the actual options passed to compiler and linker based
#     on the information gathered above.
# 13. Define some standard build targets and implicit rules. These may
#     be optionally disabled by the parent makefile.
# 14. (For extensions only.) Compare the configuration of the target
#     Tcl and the extensions and warn against discrepancies.
#
# One final note about the macro names used. They are as they are
# for historical reasons. We would like legacy extensions to
# continue to work with this make include file so be wary of
# changing them for consistency or clarity.

# 0. Sanity check compiler environment

# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)

!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
MSG = ^
Visual C++ compiler environment not initialized.
!error $(MSG)
!endif

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif


################################################################
# 1. Define external programs being used

#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
# "delete all" method.
#----------------------------------------------------------


RMDIR	= rmdir /S /Q





CPY	= xcopy /i /y >NUL
CPYDIR  = xcopy /e /i /y >NUL
COPY	= copy /y >NUL








MKDIR   = mkdir

######################################################################
# 2. Figure out our build environment in terms of what we're building.
#
# (a) Tcl itself
# (b) Tk
# (c) a Tcl extension using libraries/includes from an *installed* Tcl
# (d) a Tcl extension using libraries/includes from Tcl source directory
#
# This last is needed because some extensions still need
# some Tcl interfaces that are not publicly exposed.
#
# The fragment will set the following macros:
# ROOT - root of this module sources
# COMPATDIR - source directory that holds compatibility sources
# DOCDIR - source directory containing documentation files
# GENERICDIR - platform-independent source directory
# WIN_DIR - Windows-specific source directory
# TESTDIR - directory containing test files
# TOOLSDIR - directory containing build tools
# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
#    when building Tcl itself.
# _INSTALLDIR - native form of the installation path. For Tcl
#    this will be the root of the Tcl installation. For extensions
#    this will be the lib directory under the root.
# TCLINSTALL  - set to 1 if _TCLDIR refers to
#    headers and libraries from an installed Tcl, and 0 if built against
#    Tcl sources. Not set when building Tcl itself. Yes, not very well
#    named.
# _TCL_H - native path to the tcl.h file
#
# If Tk is involved, also sets the following
# _TKDIR - native form Tk installation OR Tk source. Not set if building
#    Tk itself.
# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
# _TK_H - native path to the tk.h file

# Root directory for sources and assumed subdirectories
ROOT = $(MAKEDIR)\..
# The following paths CANNOT have spaces in them as they appear on the
# left side of implicit rules.
!ifndef COMPATDIR
COMPATDIR	= $(ROOT)\compat
!endif
!ifndef DOCDIR
DOCDIR		= $(ROOT)\doc
!endif
!ifndef GENERICDIR
GENERICDIR	= $(ROOT)\generic
!endif
!ifndef TOOLSDIR
TOOLSDIR	= $(ROOT)\tools
!endif
!ifndef TESTDIR
TESTDIR	= $(ROOT)\tests
!endif
!ifndef LIBDIR
!if exist("$(ROOT)\library")
LIBDIR          = $(ROOT)\library
!else
LIBDIR          = $(ROOT)\lib
!endif
!endif
!ifndef DEMODIR
!if exist("$(LIBDIR)\demos")
DEMODIR		= $(LIBDIR)\demos
!else
DEMODIR		= $(ROOT)\demos
!endif
!endif # ifndef DEMODIR
# Do NOT use WINDIR because it is Windows internal environment
# variable to point to c:\windows!
WIN_DIR		= $(ROOT)\win

!ifndef RCDIR
!if exist("$(WIN_DIR)\rc")
RCDIR           = $(WIN_DIR)\rc
!else
RCDIR           = $(WIN_DIR)
!endif
!endif
RCDIR = $(RCDIR:/=\)

# The target directory where the built packages and binaries will be installed.
# INSTALLDIR is the (optional) path specified by the user.
# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
!ifdef INSTALLDIR
### Fix the path separators.
_INSTALLDIR	= $(INSTALLDIR:/=\)
!else
### Assume the normal default.
_INSTALLDIR	= $(HOMEDRIVE)\Tcl
!endif

!if $(DOING_TCL)

# BEGIN Case 2(a) - Building Tcl itself

# Only need to define _TCL_H
_TCL_H = ..\generic\tcl.h

# END Case 2(a) - Building Tcl itself

!elseif $(DOING_TK)

# BEGIN Case 2(b) - Building Tk

TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
!if "$(TCLDIR)" == ""
!if [echo TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
!endif # TCLDIR == ""

_TCLDIR	= $(TCLDIR:/=\)
_TCL_H  = $(_TCLDIR)\generic\tcl.h
!if !exist("$(_TCL_H)")
!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
!endif

_TK_H = ..\generic\tk.h

# END Case 2(b) - Building Tk

!else

# BEGIN Case 2(c) or (d) - Building an extension other than Tk

# If command line has specified Tcl location through TCLDIR, use it
# else default to the INSTALLDIR setting
!if "$(TCLDIR)" != ""

_TCLDIR	= $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
TCLINSTALL	= 1
_TCL_H          = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
TCLINSTALL	= 0
_TCL_H          = $(_TCLDIR)\generic\tcl.h
!endif

!else  #  # Case 2(c) for extensions with TCLDIR undefined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)

TCLINSTALL	= 1
TCLDIR          = $(_INSTALLDIR)\..
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TCLDIR		= $(_INSTALLDIR)\..
_TCL_H          = $(_TCLDIR)\include\tcl.h

!else # exist(...) && !$(NEED_TCL_SOURCE)

!if [echo _TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
TCLINSTALL      = 0
TCLDIR         = $(_TCLDIR)
_TCL_H          = $(_TCLDIR)\generic\tcl.h

!endif # exist(...) && !$(NEED_TCL_SOURCE)

!endif # TCLDIR

!ifndef _TCL_H
MSG =^
Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
!error $(MSG)
!endif

# Now do the same to locate Tk headers and libs if project requires Tk
!if $(NEED_TK)

!if "$(TKDIR)" != ""

_TKDIR = $(TKDIR:/=\)
!if exist("$(_TKDIR)\include\tk.h")
TKINSTALL      = 1
_TK_H          = $(_TKDIR)\include\tk.h
!elseif exist("$(_TKDIR)\generic\tk.h")
TKINSTALL      = 0
_TK_H          = $(_TKDIR)\generic\tk.h
!endif

!else # TKDIR not defined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

TKINSTALL      = 1
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TKDIR         = $(_INSTALLDIR)\..
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)

!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!if [echo _TKDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
!error *** Could not locate Tk source directory.
!endif
!include nmakehlp.out
TKINSTALL      = 0
TKDIR          = $(_TKDIR)
_TK_H          = $(_TKDIR)\generic\tk.h

!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!endif # TKDIR

!ifndef _TK_H
MSG =^
Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
!error $(MSG)
!endif

!endif # NEED_TK

!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tcl.^
*** Please set the TCLDIR macro to point to the Tcl sources.
!error $(MSG)
!endif

!if $(NEED_TK_SOURCE)
!if $(TKINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tk.^
*** Please set the TKDIR macro to point to the Tk sources.
!error $(MSG)
!endif
!endif


# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
!endif

# END Case 2(c) or (d) - Building an extension
!endif # if $(DOING_TCL)

################################################################
# 3. Determine compiler version and architecture
# In this section, we figure out the compiler version and the
# architecture for which we are building. This sets the
# following macros:
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
#     This is also printed by the compiler in dotted form 19.10 etc.
# VCVER - the "marketing version", for example Visual C++ 6 for internal
#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.

#----------------------------------------------------------------
# Figure out the compiler architecture and version by writing
# the C macros to a file, preprocessing them with the C
# preprocessor and reading back the created file

_HASH=^#
_VC_MANIFEST_EMBED_EXE=
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \
    && ![echo $(_HASH)endif >> vercl.x] \
    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
!include vercl.i
!if $(VCVERSION) < 1900
!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc
!endif
!else
# The simple calculation above does not apply to new Visual Studio releases
# Keep the compiler version in its native form.
VCVER = $(VCVERSION)
!endif
!endif

!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
!endif

#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86
!elseif "$(MACHINE)" == "x64"
!undef MACHINE
MACHINE = AMD64
!endif
!if "$(MACHINE)" != "$(ARCH)"
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
!endif
!else
MACHINE=$(ARCH)
!endif

#---------------------------------------------------------------
# The PLATFORM_IDENTIFY macro matches the values returned by
# the Tcl platform::identify command
!if "$(MACHINE)" == "AMD64"
PLATFORM_IDENTIFY = win32-x86_64
!else
PLATFORM_IDENTIFY = win32-ix86
!endif

# The MULTIPLATFORM macro controls whether binary extensions are installed
# in platform-specific directories. Intended to be set/used by extensions.
!ifndef MULTIPLATFORM_INSTALL
MULTIPLATFORM_INSTALL = 0
!endif

#------------------------------------------------------------
# Figure out the *host* architecture by reading the registry

!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86
!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!endif

################################################################
# 4. Build the nmakehlp program
# This is a helper app we need to overcome nmake's limiting
# environment. We will call out to it to get various bits of
# information about supported compiler options etc.
#
# Tcl itself will always use the nmakehlp.c program which is
# in its own source. It will be kept updated there.
#
# Extensions built against an installed Tcl will use the installed
# copy of Tcl's nmakehlp.c if there is one and their own version
# otherwise. In the latter case, they would also be using their own
# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
# or rules.vc.
#
# Extensions built against Tcl sources will use the one from the Tcl source.
#
# When building an extension using a sufficiently new version of Tcl,
# rules-ext.vc will define NMAKEHLPC appropriately to point to the
# copy of nmakehlp.c to be used.

!ifndef NMAKEHLPC
# Default to the one in the current directory (the extension's own nmakehlp.c)
NMAKEHLPC = nmakehlp.c

!if !$(DOING_TCL)
!if $(TCLINSTALL)
!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
!endif
!else # !$(TCLINSTALL)
!if exist("$(_TCLDIR)\win\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c

!endif
!endif # $(TCLINSTALL)
!endif # !$(DOING_TCL)

!endif # NMAKEHLPC

# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif

################################################################
# 5. Test for compiler features
# Visual C++ compiler options have changed over the years. Check
# which options are supported by the compiler in use.
#
# The following macros are set:

# OPTIMIZATIONS - the compiler flags to be used for optimized builds
# DEBUGFLAGS - the compiler flags to be used for debug builds
# LINKERFLAGS - Flags passed to the linker
#
# Note that these are the compiler settings *available*, not those
# that will be *used*. The latter depends on the OPTS macro settings
# which we have not yet parsed.

#
# Also note that some of the flags in OPTIMIZATIONS are not really
# related to optimization. They are placed there only for legacy reasons
# as some extensions expect them to be included in that macro.

# -Op improves float consistency. Note only needed for older compilers
# Newer compilers do not need or support this option.
!if [nmakehlp -c -Op]
FPOPTS  = -Op
!endif

# Strict floating point semantics - present in newer compilers in lieu of -Op
!if [nmakehlp -c -fp:strict]
FPOPTS  = $(FPOPTS) -fp:strict
!endif

!if "$(MACHINE)" == "IX86"

### test for pentium errata
!if [nmakehlp -c -QI0f]
!message *** Compiler has 'Pentium 0x0f fix'
FPOPTS  = $(FPOPTS) -QI0f
!else
!message *** Compiler does not have 'Pentium 0x0f fix'
!endif
!endif


### test for optimizations

# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
# documentation. Note we do NOT want /Gs as that inserts a _chkstk
# stack probe at *every* function entry, not just those with more than
# a page of stack allocation resulting in a performance hit.  However,
# /O2 documentation is misleading as its stack probes are simply the
# default page size locals allocation probes and not what is implied
# by an explicit /Gs option.

OPTIMIZATIONS = $(FPOPTS)

!if [nmakehlp -c -O2]


OPTIMIZING = 1

OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
!else
# Legacy, really. All modern compilers support this



!message *** Compiler does not have 'Optimizations'

OPTIMIZING = 0
!endif




# Checks for buffer overflows in local arrays
!if [nmakehlp -c -GS]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
!endif

# Link time optimization. Note that this option (potentially) makes
# generated libraries only usable by the specific VC++ version that
# created it. Requires /LTCG linker option
!if [nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
CC_GL_OPT_ENABLED = 1
!else
# In newer compilers -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
!endif
!endif # [nmakehlp -c -GL]

DEBUGFLAGS     = $(FPOPTS)

# Run time error checks. Not available or valid in a release, non-debug build
# RTC is for modern compilers, -GZ is legacy
!if [nmakehlp -c -RTC1]
DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
!endif


#----------------------------------------------------------------






# Linker flags












# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test






# if the linker supports a specific option. Without these flags link will
# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
# They are not passed through to the actual application / extension
# link rules.
!ifndef LINKER_TESTFLAGS
LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
!endif

LINKERFLAGS     =

# If compiler has enabled link time optimization, linker must too with -ltcg
!ifdef CC_GL_OPT_ENABLED
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     = $(LINKERFLAGS) -ltcg
!endif
!endif

########################################################################

# 6. Parse the OPTS macro to work out the requested build configuration.
# Based on this, we will construct the actual switches to be passed to the
# compiler and linker using the macros defined in the previous section.
# The following macros are defined by this section based on OPTS
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
#                1 -> build as a static library and shell
# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
# DEBUG - 1 -> debug build, 0 -> release builds
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
# PGO     - 1 -> profile based optimization, 0 -> no
# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
#           0 -> link to static C runtime for static Tcl build.
#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
#           in the Tcl shell. 0 -> keep them as shared libraries
#           Does not impact shared Tcl builds.
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
#           0 -> Use the non-thread allocator.
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
#           C runtime, 0 -> use the debug C runtime.
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
#           configuration (ignored for Tcl itself)
# _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build
#           (CRT library should support this, not needed for Tcl 9.x)
# TCL_UTF_MAX=4 - forces a build allowing 4-byte UTF-8 sequences internally.
#           (Not needed for Tcl 9.x)
# Further, LINKERFLAGS are modified based on above.


# Default values for all the above

STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
SYMBOLS		= 0
PROFILE		= 0
PGO		= 0
MSVCRT		= 1

TCL_USE_STATIC_PACKAGES	= 0
USE_THREAD_ALLOC = 1
UNCHECKED	= 0
CONFIG_CHECK    = 1
!if $(DOING_TCL)
USE_STUBS       = 0
!else
USE_STUBS       = 1
!endif

# If OPTS is not empty AND does not contain "none" which turns off all OPTS
# set the above macros based on OPTS content
!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]

# OPTS are specified, parse them

!if [nmakehlp -f $(OPTS) "static"]
!message *** Doing static
STATIC_BUILD	= 1
!endif

!if [nmakehlp -f $(OPTS) "nostubs"]
!message *** Not using stubs
USE_STUBS	= 0
!endif

!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt

!else
!if $(STATIC_BUILD)
MSVCRT		= 0
!endif
!endif
!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]

!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1


!endif

!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded tcl



TCL_THREADS = 0
USE_THREAD_ALLOC= 0
!endif

!if "$(TCL_MAJOR_VERSION)" == "8"
!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
_USE_64BIT_TIME_T = 1
!endif

!if [nmakehlp -f $(OPTS) "utfmax"]
!message *** Force allowing 4-byte UTF-8 sequences internally
TCL_UTF_MAX = 4
!endif
!endif

# Yes, it's weird that the "symbols" option controls DEBUG and
# the "pdbs" option controls SYMBOLS. That's historical.
!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
!else
DEBUG		= 0
!endif

!if [nmakehlp -f $(OPTS) "pdbs"]
!message *** Doing pdbs
SYMBOLS		= 1
!else
SYMBOLS		= 0
!endif

!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE		= 1
!else
PROFILE		= 0
!endif

!if [nmakehlp -f $(OPTS) "pgi"]
!message *** Doing profile guided optimization instrumentation
PGO		= 1
!elseif [nmakehlp -f $(OPTS) "pgo"]
!message *** Doing profile guided optimization
PGO		= 2
!else
PGO		= 0
!endif

!if [nmakehlp -f $(OPTS) "loimpact"]
!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.



!endif

# TBD - should get rid of this option
!if [nmakehlp -f $(OPTS) "thrdalloc"]
!message *** Doing thrdalloc
USE_THREAD_ALLOC = 1
!endif

!if [nmakehlp -f $(OPTS) "tclalloc"]

USE_THREAD_ALLOC = 0
!endif

!if [nmakehlp -f $(OPTS) "unchecked"]
!message *** Doing unchecked
UNCHECKED = 1
!else
UNCHECKED = 0
!endif

!if [nmakehlp -f $(OPTS) "noconfigcheck"]
CONFIG_CHECK = 1
!else
CONFIG_CHECK = 0
!endif

!endif # "$(OPTS)" != ""  && ... parsing of OPTS

# Set linker flags based on above

!if $(PGO) > 1
!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!elseif $(PGO) > 0
!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 7. Parse the STATS macro to configure code instrumentation
# The following macros are set by this section:
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
#                 0 -> disables
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
#                     0 -> disables

# Default both are off
TCL_MEM_DEBUG	    = 0
TCL_COMPILE_DEBUG   = 0

!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]

!if [nmakehlp -f $(STATS) "memdbg"]
!message *** Doing memdbg
TCL_MEM_DEBUG	    = 1
!else
TCL_MEM_DEBUG	    = 0
!endif

!if [nmakehlp -f $(STATS) "compdbg"]
!message *** Doing compdbg
TCL_COMPILE_DEBUG   = 1
!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 8. Parse the CHECKS macro to configure additional compiler checks
# The following macros are set by this section:
# WARNINGS - compiler switches that control the warnings level
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
#                     0 -> enable deprecated functions

# Defaults - Permit deprecated functions and warning level 3
TCL_NO_DEPRECATED	    = 0
WARNINGS		    = -W3

!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]

!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
TCL_NO_DEPRECATED	    = 1
!endif

!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
WARNINGS		    = -W4
!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
!endif
!endif

!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
!message *** Doing 64bit portability warnings
WARNINGS		    = $(WARNINGS) -Wp64
!endif

!endif

################################################################
# 9. Extract various version numbers
# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
# respectively. For extensions, versions are extracted from the
# configure.in or configure.ac from the TEA configuration if it
# exists, and unset otherwise.
# Sets the following macros:
# TCL_MAJOR_VERSION
# TCL_MINOR_VERSION
# TCL_PATCH_LEVEL
# TCL_VERSION
# TK_MAJOR_VERSION
# TK_MINOR_VERSION
# TK_PATCH_LEVEL
# TK_VERSION
# DOTVERSION - set as (for example) 2.5
# VERSION - set as (for example 25)
#--------------------------------------------------------------

!if [echo REM = This file is generated from rules.vc > versions.vc]
!endif
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
!endif
!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
!endif

!if defined(_TK_H)
!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
!endif
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
!endif
!endif # _TK_H

!include versions.vc

TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!if defined(_TK_H)
TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!endif

# Set DOTVERSION and VERSION
!if $(DOING_TCL)

DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
VERSION = $(TCL_VERSION)

!elseif $(DOING_TK)

DOTVERSION = $(TK_DOTVERSION)
VERSION = $(TK_VERSION)

!else # Doing a non-Tk extension

# If parent makefile has not defined DOTVERSION, try to get it from TEA
# first from a configure.in file, and then from configure.ac
!ifndef DOTVERSION
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
!endif
!endif
!include versions.vc
!endif # DOTVERSION
VERSION         = $(DOTVERSION:.=)

!endif # $(DOING_TCL) ... etc.

# Windows RC files have 3 version components. Ensure this irrespective
# of how many components the package has specified. Basically, ensure
# minimum 4 components by appending 4 0's and then pick out the first 4.
# Also take care of the fact that DOTVERSION may have "a" or "b" instead
# of "." separating the version components.
DOTSEPARATED=$(DOTVERSION:a=.)
DOTSEPARATED=$(DOTSEPARATED:b=.)
!if [echo RCCOMMAVERSION = \> versions.vc] \
  || [for /f "tokens=1,2,3,4,5* delims=." %a in ("$(DOTSEPARATED).0.0.0.0") do echo %a,%b,%c,%d >> versions.vc]
!error *** Could not generate RCCOMMAVERSION ***
!endif
!include versions.vc

################################################################
# 10. Construct output directory and file paths
# Figure-out how to name our intermediate and output directories.
# In order to avoid inadvertent mixing of object files built using
# different compilers, build configurations etc.,


#

# Naming convention (suffixes):
#   t = full thread support. (Not used for Tcl >= 8.7)
#   s = static library (as opposed to an import library)

#   g = linked to the debug enabled C run-time.

#   x = special static build when it links to the dynamic C run-time.
#
# The following macros are set in this section:
# SUFX - the suffix to use for binaries based on above naming convention
# BUILDDIRTOP - the toplevel default output directory
#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
# TMP_DIR - directory where object files are created
# OUT_DIR - directory where output executables are created
# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
# parent makefile (or command line). The default values are
# based on BUILDDIRTOP.
# STUBPREFIX - name of the stubs library for this project
# PRJIMPLIB - output path of the generated project import library
# PRJLIBNAME - name of generated project library
# PRJLIB     - output path of generated project library
# PRJSTUBLIBNAME - name of the generated project stubs library
# PRJSTUBLIB - output path of the generated project stubs library
# RESFILE - output resource file (only if not static build)

SUFX	    = tsgx

!if $(DEBUG)
BUILDDIRTOP = Debug
!else
BUILDDIRTOP = Release
!endif

!if "$(MACHINE)" != "IX86"
BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
!endif
!if $(VCVER) > 6
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif

!if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED)
SUFX	    = $(SUFX:g=)
!endif

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX	    = $(SUFX:s=)
EXT	    = dll
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!endif

!if !$(TCL_THREADS) || $(TCL_VERSION) > 86
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
SUFX	    = $(SUFX:t=)
!endif

!ifndef TMP_DIR
TMP_DIR	    = $(TMP_DIRFULL)
!ifndef OUT_DIR
OUT_DIR	    = .\$(BUILDDIRTOP)
!endif
!else
!ifndef OUT_DIR
OUT_DIR	    = $(TMP_DIR)
!endif
!endif

# Relative paths -> absolute
!if [echo OUT_DIR = \> nmakehlp.out] \
   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
!endif
!if [echo TMP_DIR = \>> nmakehlp.out] \
   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
!endif
!include nmakehlp.out


# The name of the stubs library for the project being built
STUBPREFIX      = $(PROJECT)stub

# Set up paths to various Tcl executables and libraries needed by extensions
!if $(DOING_TCL)

TCLSHNAME       = $(PROJECT)sh$(VERSION)$(SUFX).exe
TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)

TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"

!else # !$(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl

# When building extensions, we need to locate tclsh. Depending on version
# of Tcl we are building against, this may or may not have a "t" suffix.
# Try various possibilities in turn.
TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist("$(TCLSH)")
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif


TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES    = -I"$(_TCLDIR)\include"

!else # Building against Tcl sources

TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist($(TCLSH))
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif
TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\library
TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"

!endif # TCLINSTALL

tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"

!endif # $(DOING_TCL)



# We need a tclsh that will run on the host machine as part of the build.
# IX86 runs on all architectures.
!ifndef TCLSH_NATIVE
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
TCLSH_NATIVE	= $(TCLSH)

!else
!error You must explicitly set TCLSH_NATIVE for cross-compilation
!endif
!endif

# Do the same for Tk and Tk extensions that require the Tk libraries
!if $(DOING_TK) || $(NEED_TK)
WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib

!if $(DOING_TK)
WISH 		= $(OUT_DIR)\$(WISHNAME)
TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"

!else # effectively NEED_TK

!if $(TKINSTALL) # Building against installed Tk
WISH		= $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.

!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\include"
!else # Building against Tk sources
WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)

!endif
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif # TKINSTALL
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

# If extension parent makefile has not defined a resource definition file,
# we will generate one from standard template.
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
!ifdef RCFILE
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
!else
RESFILE = $(TMP_DIR)\$(PROJECT).res
!endif
!endif

###################################################################
# 11. Construct the paths for the installation directories
# The following macros get defined in this section:
# LIB_INSTALL_DIR - where libraries should be installed
# BIN_INSTALL_DIR - where the executables should be installed
# DOC_INSTALL_DIR - where documentation should be installed
# SCRIPT_INSTALL_DIR - where scripts should be installed
# INCLUDE_INSTALL_DIR - where C include files should be installed
# DEMO_INSTALL_DIR - where demos should be installed
# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)

!if $(DOING_TCL) || $(DOING_TK)
LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
!if $(DOING_TCL)
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
MODULE_INSTALL_DIR	= $(_INSTALLDIR)\lib\tcl$(TCL_MAJOR_VERSION)
!else # DOING_TK
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)


!endif
DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include

!else # extension other than Tk

PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
!if $(MULTIPLATFORM_INSTALL)
LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
!else


LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
!endif
DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\..\include

!endif

###################################################################
# 12. Set up actual options to be passed to the compiler and linker
# Now we have all the information we need, set up the actual flags and

# options that we will pass to the compiler and linker. The main
# makefile should use these in combination with whatever other flags
# and switches are specific to it.
# The following macros are defined, names are for historical compatibility:
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
# crt - Compiler switch that selects the appropriate C runtime
# cdebug - Compiler switches related to debug AND optimizations
# cwarn - Compiler switches that set warning levels
# cflags - complete compiler switches (subsumes cdebug and cwarn)
# ldebug - Linker switches controlling debug information and optimization
# lflags - complete linker switches (subsumes ldebug) except subsystem type
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
# conlflags - complete linker switches for console program (subsumes lflags)
# guilflags - complete linker switches for GUI program (subsumes lflags)
# baselibs - minimum Windows libraries required. Parent makefile can
#    define PRJ_LIBS before including rules.rc if additional libs are needed

OPTDEFINES	= /DSTDC_HEADERS
!if $(VCVERSION) >= 1600
OPTDEFINES	= $(OPTDEFINES) /DHAVE_STDINT_H=1
!else
OPTDEFINES	= $(OPTDEFINES) /DMP_NO_STDINT=1
!endif
!if $(VCVERSION) >= 1800
OPTDEFINES	= $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
!endif

!if $(TCL_MEM_DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DTCL_MEM_DEBUG
!endif
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DTCL_COMPILE_DEBUG /DTCL_COMPILE_STATS
!endif
!if $(TCL_THREADS) && $(TCL_VERSION) < 87
OPTDEFINES	= $(OPTDEFINES) /DTCL_THREADS=1
!if $(USE_THREAD_ALLOC) && $(TCL_VERSION) < 87
OPTDEFINES	= $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) /DSTATIC_BUILD
!elseif $(TCL_VERSION) > 86
OPTDEFINES	= $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) /DMP_64BIT
!endif
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) /DTCL_NO_DEPRECATED
!endif

!if $(USE_STUBS)
# Note we do not define USE_TCL_STUBS even when building tk since some
# test targets in tk do not use stubs
!if !$(DOING_TCL)
USE_STUBS_DEFS  = /DUSE_TCL_STUBS /DUSE_TCLOO_STUBS
!if $(NEED_TK)
USE_STUBS_DEFS  = $(USE_STUBS_DEFS) /DUSE_TK_STUBS
!endif
!endif
!endif # USE_STUBS

!if !$(DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DNDEBUG
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) /DNO_STRTOI64=1
!endif

!if "$(TCL_MAJOR_VERSION)" == "8"
!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES	= $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
!endif
!if "$(TCL_UTF_MAX)" == "4"
OPTDEFINES	= $(OPTDEFINES) /DTCL_UTF_MAX=4
!endif

# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
COMPILERFLAGS  = /D_ATL_XP_TARGETING
!endif

# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
               /DMODULE_SCOPE=extern
!endif

# crt picks the C run time based on selected OPTS
!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else
crt = -MT
!endif
!endif


# cdebug includes compiler options for debugging as well as optimization.
!if $(DEBUG)

# In debugging mode, optimizations need to be disabled
cdebug = -Zi -Od $(DEBUGFLAGS)


!else

cdebug = $(OPTIMIZATIONS)

!if $(SYMBOLS)
cdebug = $(cdebug) -Zi

!endif

!endif # $(DEBUG)

# cwarn includes default warning levels.
cwarn = $(WARNINGS)

!if "$(MACHINE)" == "AMD64"
# Disable pointer<->int warnings related to cast between different sizes
# There are a gadzillion of these due to use of ClientData and
# clutter up compiler
# output increasing chance of a real warning getting lost. So disable them.
# Eventually some day, Tcl will be 64-bit clean.
cwarn = $(cwarn) -wd4311 -wd4312
!endif

### Common compiler options that are architecture specific
!if "$(MACHINE)" == "ARM"
carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!else
carch =
!endif

!if $(DEBUG)
# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif

INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
!if !$(DOING_TCL) && !$(DOING_TK)
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"





!endif

# These flags are defined roughly in the order of the pre-reform
# rules.vc/makefile.vc to help visually compare that the pre- and
# post-reform build logs

# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)

# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
# BUILD_$(PROJECT) macro which should be defined only for the shared
# library *implementation* and not for its caller interface

appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
appcflags = $(appcflags_nostubs) $(USE_STUBS_DEFS)
pkgcflags = $(appcflags) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)
pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)

# stubscflags contains $(cflags) plus flags used for building a stubs
# library for the package.  Note: /DSTATIC_BUILD is defined in
# $(OPTDEFINES) only if the OPTS configuration indicates a static
# library. However the stubs library is ALWAYS static hence included
# here irrespective of the OPTS setting.
#
# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
# without stating why. Tcl itself compiled stubs libs with this flag.
# so we do not remove it from cflags. -GL may prevent extensions
# compiled with one VC version to fail to link against stubs library
# compiled with another VC version. Check for this and fix accordingly.
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)

# Link flags

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3
!if $(SYMBOLS)
ldebug	= $(ldebug) -debug -debugtype:cv
!endif
!endif




# Note: Profiling is currently only possible with the Visual Studio Enterprise
!if $(PROFILE)
ldebug= $(ldebug) -profile
!endif

### Declarations common to all linker versions
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
lflags	= $(lflags) -nodefaultlib:libucrt.lib
!endif

# Old linkers (Visual C++ 6 in particular) will link for fast loading
# on Win98. Since we do not support Win98 any more, we specify nowin98
# as recommended for NT and later. However, this is only required by
# IX86 on older compilers and only needed if we are not doing a static build.

!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
# Align sections for PE size savings.
lflags	= $(lflags) -opt:nowin98
!endif
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

# Libraries that are required for every image.
# Extensions should define any additional libraries with $(PRJ_LIBS)
winlibs   = kernel32.lib advapi32.lib

!if $(NEED_TK)
winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
!endif

# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "AMD64"

!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
winlibs   = $(winlibs) bufferoverflowU.lib


!endif


!endif

baselibs = $(winlibs) $(PRJ_LIBS)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
baselibs   = $(baselibs) ucrt.lib
!endif

################################################################
# 13. Define standard commands, common make targets and implicit rules

CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\


LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)

CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
	    $(TCL_INCLUDES) \
	    /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    /DCOMMAVERSION=$(RCCOMMAVERSION) \
	    /DDOTVERSION=\"$(DOTVERSION)\" \
	    /DVERSION=\"$(VERSION)\" \
	    /DSUFX=\"$(SUFX)\" \
	    /DPROJECT=\"$(PROJECT)\" \
	    /DPRJLIBNAME=\"$(PRJLIBNAME)\"

!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
!endif


default-target: $(DEFAULT_BUILD_TARGET)




!if $(MULTIPLATFORM_INSTALL)
default-pkgindex:
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
!else
default-pkgindex:
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
!endif

default-pkgindex-tea:
	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
@PKG_LIB_FILE@       $(PRJLIBNAME)
<<

default-install: default-install-binaries default-install-libraries
!if $(SYMBOLS)
default-install: default-install-pdbs
!endif

# Again to deal with historical brokenness, there is some confusion
# in terminlogy. For extensions, the "install-binaries" was used to
# locate target directory for *binary shared libraries* and thus
# the appropriate macro is LIB_INSTALL_DIR since BIN_INSTALL_DIR is
# for executables (exes). On the other hand the "install-libraries"
# target is for *scripts* and should have been called "install-scripts".
default-install-binaries: $(PRJLIB)
	@echo Installing binaries to '$(LIB_INSTALL_DIR)'
	@if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
	@$(CPY) $(PRJLIB) "$(LIB_INSTALL_DIR)" >NUL

# Alias for default-install-scripts
default-install-libraries: default-install-scripts

default-install-scripts: $(OUT_DIR)\pkgIndex.tcl
	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)

default-install-stubs:
	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-pdbs:
	@echo Installing PDBs to '$(LIB_INSTALL_DIR)'

	@if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"




	@$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\"

default-install-docs-html:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-docs-n:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-demos:
	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"

default-clean:
	@echo Cleaning $(TMP_DIR)\* ...
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)

	@echo Cleaning $(WIN_DIR)\nmakehlp.obj, nmakehlp.exe ...
	@if exist $(WIN_DIR)\nmakehlp.obj del $(WIN_DIR)\nmakehlp.obj
	@if exist $(WIN_DIR)\nmakehlp.exe del $(WIN_DIR)\nmakehlp.exe
	@if exist $(WIN_DIR)\nmakehlp.out del $(WIN_DIR)\nmakehlp.out
	@echo Cleaning $(WIN_DIR)\nmhlp-out.txt ...
	@if exist $(WIN_DIR)\nmhlp-out.txt del $(WIN_DIR)\nmhlp-out.txt
	@echo Cleaning $(WIN_DIR)\_junk.pch ...
	@if exist $(WIN_DIR)\_junk.pch del $(WIN_DIR)\_junk.pch
	@echo Cleaning $(WIN_DIR)\vercl.x, vercl.i ...
	@if exist $(WIN_DIR)\vercl.x del $(WIN_DIR)\vercl.x
	@if exist $(WIN_DIR)\vercl.i del $(WIN_DIR)\vercl.i
	@echo Cleaning $(WIN_DIR)\versions.vc, version.vc ...
	@if exist $(WIN_DIR)\versions.vc del $(WIN_DIR)\versions.vc
	@if exist $(WIN_DIR)\version.vc del $(WIN_DIR)\version.vc

default-hose: default-clean
	@echo Hosing $(OUT_DIR)\* ...
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

# Only for backward compatibility
default-distclean: default-hose

default-setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

default-test: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)

default-shell: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	$(DEBUGGER) $(TCLSH)

# Generation of Windows version resource
!ifdef RCFILE


# Note: don't use $** in below rule because there may be other dependencies
# and only the "main" rc must be passed to the resource compiler
$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
	$(RESCMD) $(RCDIR)\$(PROJECT).rc

!else

# If parent makefile has not defined a resource definition file,
# we will generate one from standard template.
$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc

$(TMP_DIR)\$(PROJECT).rc:
	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
#include <winver.h>

VS_VERSION_INFO VERSIONINFO
 FILEVERSION	COMMAVERSION
 PRODUCTVERSION	COMMAVERSION
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG




 FILEFLAGS	VS_FF_DEBUG

#else
 FILEFLAGS	0x0L




#endif
 FILEOS		VOS_NT_WINDOWS32
 FILETYPE	VFT_DLL
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription",  "Tcl extension " PROJECT
            VALUE "OriginalFilename", PRJLIBNAME
            VALUE "FileVersion",      DOTVERSION
            VALUE "ProductName",      "Package " PROJECT " for Tcl"
            VALUE "ProductVersion",   DOTVERSION
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END


END

<<




!endif # ifdef RCFILE

!ifndef DISABLE_IMPLICIT_RULES
DISABLE_IMPLICIT_RULES = 0
!endif

!if !$(DISABLE_IMPLICIT_RULES)
# Implicit rule definitions - only for building library objects. For stubs and
# main application, the makefile should define explicit rules.

{$(ROOT)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(WIN_DIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(RCDIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(WIN_DIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

.SUFFIXES:
.SUFFIXES:.c .rc



!endif




################################################################
# 14. Sanity check selected options against Tcl build options
# When building an extension, certain configuration options should
# match the ones used when Tcl was built. Here we check and
# warn on a mismatch.
!if !$(DOING_TCL)



!if $(TCLINSTALL) # Building against an installed Tcl
!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
!endif
!else # !$(TCLINSTALL) - building against Tcl source
!if exist("$(OUT_DIR)\tcl.nmake")
TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)

!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).



!endif
!if $(TCL_VERSION) < 87 && defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).



!endif
!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
!endif
!endif

!endif # TCLNMAKECONFIG

!endif # !$(DOING_TCL)


#----------------------------------------------------------
# Display stats being used.
#----------------------------------------------------------

!if !$(DOING_TCL)
!message *** Building against Tcl at '$(_TCLDIR)'
!endif
!if !$(DOING_TK) && $(NEED_TK)
!message *** Building against Tk at '$(_TKDIR)'
!endif
!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'

!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).




!endif # ifdef _RULES_VC
|


|
|
<
<
<
<
<






<





<
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<







>

>
>
>
>
>

<

>
>
>
>
>
>
>
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<











|

<




<
<
<
<

<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<

|
|
<
>

<
<

<
|
<
<
<
<

<
<
<
<
<
<
>
|
<
<
|
<
<
<
>
|
<
<
<
|
<
<
|
<

<
<
<
<


<
>
|
<
<
<
<
<
<
<
>


>
|
<
|
|
|
|
|

|

|
>
>
|
>
|
|
|
>
>
>
|
>
|


>
>
>
|




<
<
<


<
<
<
<
<

<

|

<
<






>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>

>
>
|
>
>
>
>
>
>
|
|
<
<

|




<
<

|

<

<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>

<
>

|





>

|

<
<
<

<
<
<
<
<
<
<
<
<



|
|
<
<
<

<
|
|
|

|
<
>

<



<
<



>
>

<
|
|
>
>
>

|

<
<




<
<
<
<
<
<
<
<
<






<






<






<









<

|
>
>
>

<
<




<

>


<






<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
>
>
|
>
|
|
|
>
|
>
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|















|




















|















<
<
<
<
<
<
<
<
<
<

>
|
<
|
<
<

<
<
<
<
<
|
<
<
|
|
|
|
|
|
<
<
<
<
|
|

|
>
|
<
<
<
|
|

<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<

<
|
<
>
>

<
<
<
|
|
>

<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
>
|
|
<
<
|
<
<
<
<
<
<
|
<
<
>

<
|
<
|
|
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
>
>

<
|
|
<
|
<
<
<
<

>
>
|
<

<
<
<
<
<

<
<
<
|
>
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
<
<







|

|





<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<









|



|


<

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
<
<
<
<
<
<
<
<
<
<
<
<
>

<
|

<
<
>



<
>
|
<
>


|
|
<
|
|
<
<
<
<
<
<
|
<
|
<
<
<

|
<
|
|
<
<

|
<
|
|
>
>
>
>
>
|
|
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<

<
|
<
<
<
<
<
<
<
<
>
>
>

<
|
<

|
<
<
|
<
<

|
<
<
<
<
|
<
<
<
<

<
|
<
<
<
|
<
<
<
<
<
<

<
<
<
|
>
|
<
>
>

>
>

|
<
|
<
<

|
<
|
|
|
|
<
|
>
|
|
|
|
|
|
<
<
<
<
<
<
<
<

<
<
<
>

<
>
>
>

|
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
>
|
>
>
>
>
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
|
<
<
<
<
|
<
<
>

<
<
<
|
|
<
|
<
<
<
|
<
<
<

<
<
<
<
|
>
>
>
>
|
>
|
<
>
>
>
>
|
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
>
>
|
|
<
|
>
>
>
|
|
<
<


<
<
<
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<

<
<
<
<
|
<
<

<
<
|
<
<
|
<
<
|
>
>

>
>
>

<
<
<
<
<
|

>
>
<
<
<
<
<
<
<
<
<

|
<
|
|
<
<
>
>
>
|
|
<
>
>
>

<
<

<

|
<
<
<





<
<
<
<
<
<


<

>
|
>
>
>

|
1
2
3
4
5





6
7
8
9
10
11

12
13
14
15
16





17




18



19








20
















































21




22

23


24




25
26





27




28













29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54



































55




































56










































































































































































































57



58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74




75


76
77



































78
79
80
81
82
83
84
85
86
87
88
89
90





















91


92




93
94
95

96
97


98

99




100






101
102


103



104
105



106


107

108




109
110

111
112







113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149



150
151





152

153
154
155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191


192
193
194
195
196
197


198
199
200

201

202
203




























204
205

206
207
208
209
210
211
212
213
214
215
216
217



218









219
220
221
222
223



224

225
226
227
228
229

230
231

232
233
234


235
236
237
238
239
240

241
242
243
244
245
246
247
248


249
250
251
252









253
254
255
256
257
258

259
260
261
262
263
264

265
266
267
268
269
270

271
272
273
274
275
276
277
278
279

280
281
282
283
284
285


286
287
288
289

290
291
292
293

294
295
296
297
298
299





300
301






































































































302














































































303

304
305
306
307
308
309
310
311
312
313
314
315



316













317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369










370
371
372

373


374





375


376
377
378
379
380
381




382
383
384
385
386
387



388
389
390





391


















392

393

394

395
396
397



398
399
400
401



402







403






404
405
406






407
408
409


410






411


412
413

414

415
416

417




418


419







420
421
422















423
424
425
426
427
428
429
430

431
432

433




434
435
436
437

438





439



440
441
442

443














444
445








446
447
448
449
450
451
452
453
454
455
456
457
458
459
460





461
462
463
464
465











466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484

















485
486
487












488
489

490
491


492
493
494
495

496
497

498
499
500
501
502

503
504






505

506



507
508

509
510


511
512

513
514
515
516
517
518
519
520
521



522


523
524




525




526












527

528








529
530
531
532

533

534
535


536


537
538




539




540

541



542






543



544
545
546

547
548
549
550
551
552
553

554


555
556

557
558
559
560

561
562
563
564
565
566
567
568








569



570
571

572
573
574
575
576








577


578


































579

580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606













607













608
609




610




611


612
613



614
615

616



617



618




619
620
621
622
623
624
625
626

627
628
629
630
631




632
633
634











635
636
637
638
639

640
641
642
643
644
645


646
647



648




649




650




651




652


653


654


655


656
657
658
659
660
661
662
663





664
665
666
667









668
669

670
671


672
673
674
675
676

677
678
679
680


681

682
683



684
685
686
687
688






689
690

691
692
693
694
695
696
697
698
#------------------------------------------------------------------------------
# rules.vc --
#
#	Microsoft Visual C++ makefile include for decoding the commandline
#	macros.  This file does not need editing to build Tcl.





#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
# Copyright (c) 2003-2008 Patrick Thoyts

#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1






cc32		= $(CC)   # built-in default.




link32		= link



lib32		= lib








rc32		= $(RC)   # built-in default.





















































!ifndef INSTALLDIR

### Assume the normal default.


_INSTALLDIR	= C:\Program Files\Tcl




!else
### Fix the path separators.





_INSTALLDIR	= $(INSTALLDIR:/=\)




!endif














#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
# "delete all" method.
#----------------------------------------------------------

!if "$(OS)" == "Windows_NT"
RMDIR	= rmdir /S /Q
ERRNULL  = 2>NUL
!if ![ver | find "4.0" > nul]
CPY	= echo y | xcopy /i >NUL
COPY	= copy >NUL
!else
CPY	= xcopy /i /y >NUL

COPY	= copy /y >NUL
!endif
!else # "$(OS)" != "Windows_NT"
CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
RMDIR	= deltree /Y
NULL    = \NUL # Used in testing directory existence
ERRNULL = >NUL # Win9x shell cannot redirect stderr
!endif
MKDIR   = mkdir




































#------------------------------------------------------------------------------




































# Determine the host and target architectures and compiler version.










































































































































































































#------------------------------------------------------------------------------




_HASH=^#
_VC_MANIFEST_EMBED_EXE=
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \
    && ![echo $(_HASH)endif >> vercl.x] \
    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
!include vercl.i

!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc
!endif




!endif


!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
!endif




































!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86
!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!endif






















!ifndef MACHINE


MACHINE=$(ARCH)




!endif

!ifndef CFG_ENCODING

CFG_ENCODING	= \"cp1252\"
!endif




!message ===============================================================================











#----------------------------------------------------------
# build the helper app we need to overcome nmake's limiting


# environment.



#----------------------------------------------------------




!if !exist(nmakehlp.exe)


!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]

!endif




!endif


#----------------------------------------------------------
# Test for compiler features







#----------------------------------------------------------

### test for optimizations
!if [nmakehlp -c -Ot]
!message *** Compiler has 'Optimizations'

OPTIMIZING	= 1
!else
!message *** Compiler does not have 'Optimizations'
OPTIMIZING	= 0
!endif

OPTIMIZATIONS   =

!if [nmakehlp -c -Ot]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
!endif

!if [nmakehlp -c -Oi]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
!endif

!if [nmakehlp -c -Op]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
!endif

!if [nmakehlp -c -fp:strict]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
!endif

!if [nmakehlp -c -Gs]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
!endif

!if [nmakehlp -c -GS]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
!endif




!if [nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL





!endif


DEBUGFLAGS     =



!if [nmakehlp -c -RTC1]
DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
!endif

COMPILERFLAGS  =-W3 /D_ATL_XP_TARGETING

# In v13 -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
!if ![nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
!endif
!endif

!if "$(MACHINE)" == "IX86"
### test for pentium errata
!if [nmakehlp -c -QI0f]
!message *** Compiler has 'Pentium 0x0f fix'
COMPILERFLAGS  = $(COMPILERFLAGS) -QI0f
!else
!message *** Compiler does not have 'Pentium 0x0f fix'
!endif
!endif

!if "$(MACHINE)" == "IA64"
### test for Itanium errata
!if [nmakehlp -c -QIA64_Bx]
!message *** Compiler has 'B-stepping errata workarounds'
COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
!else
!message *** Compiler does not have 'B-stepping errata workarounds'
!endif
!endif

# Prevents "LNK1561: entry point must be defined" error compiling from VS-IDE:


!ifndef LINKER_TESTFLAGS
LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmhlp-out.txt
!endif

LINKERFLAGS     =



!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     =-ltcg
!endif



#----------------------------------------------------------
# Decode the options requested.




























#----------------------------------------------------------


!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
STATIC_BUILD	= 0
TCL_THREADS	= 0
DEBUG		= 0
SYMBOLS		= 0
PROFILE		= 0
PGO		= 0
MSVCRT		= 1
LOIMPACT	= 0
TCL_USE_STATIC_PACKAGES	= 0
USE_THREAD_ALLOC = 0
UNCHECKED	= 0



!else









!if [nmakehlp -f $(OPTS) "static"]
!message *** Doing static
STATIC_BUILD	= 1
!else
STATIC_BUILD	= 0



!endif

!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
MSVCRT		= 1
!else
!if !$(STATIC_BUILD)

MSVCRT		= 1
!else

MSVCRT		= 0
!endif
!endif


!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1
!else
TCL_USE_STATIC_PACKAGES	= 0
!endif

!if [nmakehlp -f $(OPTS) "threads"]
!message *** Doing threads
TCL_THREADS = 1
USE_THREAD_ALLOC = 1
!else
TCL_THREADS = 0
USE_THREAD_ALLOC = 0
!endif


!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
_USE_64BIT_TIME_T = 1
!endif









!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
!else
DEBUG		= 0
!endif

!if [nmakehlp -f $(OPTS) "pdbs"]
!message *** Doing pdbs
SYMBOLS		= 1
!else
SYMBOLS		= 0
!endif

!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE		= 1
!else
PROFILE		= 0
!endif

!if [nmakehlp -f $(OPTS) "pgi"]
!message *** Doing profile guided optimization instrumentation
PGO		= 1
!elseif [nmakehlp -f $(OPTS) "pgo"]
!message *** Doing profile guided optimization
PGO		= 2
!else
PGO		= 0
!endif

!if [nmakehlp -f $(OPTS) "loimpact"]
!message *** Doing loimpact
LOIMPACT	= 1
!else
LOIMPACT	= 0
!endif


!if [nmakehlp -f $(OPTS) "thrdalloc"]
!message *** Doing thrdalloc
USE_THREAD_ALLOC = 1
!endif

!if [nmakehlp -f $(OPTS) "tclalloc"]
!message *** Doing tclalloc
USE_THREAD_ALLOC = 0
!endif

!if [nmakehlp -f $(OPTS) "unchecked"]
!message *** Doing unchecked
UNCHECKED = 1
!else
UNCHECKED = 0
!endif





!endif







































































































#----------------------------------------------------------














































































# Figure-out how to name our intermediate and output directories.

# We wouldn't want different builds to use the same .obj files
# by accident.
#----------------------------------------------------------

#----------------------------------------
# Naming convention:
#   t = full thread support.
#   s = static library (as opposed to an
#	import library)
#   g = linked to the debug enabled C
#	run-time.
#   x = special static build when it



#	links to the dynamic C run-time.













#----------------------------------------
SUFX	    = tsgx

!if $(DEBUG)
BUILDDIRTOP = Debug
!else
BUILDDIRTOP = Release
!endif

!if "$(MACHINE)" != "IX86"
BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
!endif
!if $(VCVER) > 6
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif

!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
SUFX	    = $(SUFX:g=)
!endif

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX	    = $(SUFX:s=)
EXT	    = dll
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!endif

!if !$(TCL_THREADS)
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
SUFX	    = $(SUFX:t=)
!endif

!ifndef TMP_DIR
TMP_DIR	    = $(TMP_DIRFULL)
!ifndef OUT_DIR
OUT_DIR	    = .\$(BUILDDIRTOP)
!endif
!else
!ifndef OUT_DIR
OUT_DIR	    = $(TMP_DIR)
!endif
!endif












#----------------------------------------------------------
# Decode the statistics requested.

#----------------------------------------------------------








!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]


TCL_MEM_DEBUG	    = 0
TCL_COMPILE_DEBUG   = 0
!else
!if [nmakehlp -f $(STATS) "memdbg"]
!message *** Doing memdbg
TCL_MEM_DEBUG	    = 1




!else
TCL_MEM_DEBUG	    = 0
!endif
!if [nmakehlp -f $(STATS) "compdbg"]
!message *** Doing compdbg
TCL_COMPILE_DEBUG   = 1



!else
TCL_COMPILE_DEBUG   = 0
!endif





!endif






















#----------------------------------------------------------

# Decode the checks requested.
#----------------------------------------------------------




!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
TCL_NO_DEPRECATED	    = 0
WARNINGS		    = -W3
!else



!if [nmakehlp -f $(CHECKS) "nodep"]







!message *** Doing nodep check






TCL_NO_DEPRECATED	    = 1
!else
TCL_NO_DEPRECATED	    = 0






!endif
!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check


WARNINGS		    = -W4






!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]


LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
!endif

!else

WARNINGS		    = -W3
!endif

!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]




!message *** Doing 64bit portability warnings


WARNINGS		    = $(WARNINGS) -Wp64







!endif
!endif
















!if $(PGO) > 1
!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif

!elseif $(PGO) > 0
!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]

LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument




!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)

!endif





!endif




#----------------------------------------------------------
# Set our defines now armed with our options.

#----------------------------------------------------------















OPTDEFINES	= /DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) /DSTDC_HEADERS









!if $(TCL_MEM_DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DTCL_MEM_DEBUG
!endif
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DTCL_COMPILE_DEBUG /DTCL_COMPILE_STATS
!endif
!if $(TCL_THREADS)
OPTDEFINES	= $(OPTDEFINES) /DTCL_THREADS=1
!if $(USE_THREAD_ALLOC)
OPTDEFINES	= $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) /DSTATIC_BUILD





!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) /DTCL_NO_DEPRECATED
!endif












!if !$(DEBUG)
OPTDEFINES	= $(OPTDEFINES) /DNDEBUG
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) /DNO_STRTOI64
!endif


!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES	= $(OPTDEFINES) /D_USE_64BIT_TIME_T
!endif


















#----------------------------------------------------------
# Locate the Tcl headers to build against












#----------------------------------------------------------


!if "$(PROJECT)" == "tcl"



_TCL_H          = ..\generic\tcl.h

!else


# If INSTALLDIR set to tcl root dir then reset to the lib dir.
!if exist("$(_INSTALLDIR)\include\tcl.h")

_INSTALLDIR=$(_INSTALLDIR)\lib
!endif

!if !defined(TCLDIR)
!if exist("$(_INSTALLDIR)\..\include\tcl.h")

TCLINSTALL	= 1
_TCLDIR		= $(_INSTALLDIR)\..






_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h

TCLDIR          = $(_INSTALLDIR)\..



!else
MSG=^

Failed to find tcl.h.  Set the TCLDIR macro.
!error $(MSG)


!endif
!else

_TCLDIR	= $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h")
TCLINSTALL	= 1
_TCL_H          = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h")
TCLINSTALL	= 0
_TCL_H          = $(_TCLDIR)\generic\tcl.h
!else
MSG =^



Failed to find tcl.h.  The TCLDIR macro does not appear correct.


!error $(MSG)
!endif




!endif




!endif














#--------------------------------------------------------------








# Extract various version numbers from tcl headers
# The generated file is then included in the makefile.
#--------------------------------------------------------------


!if [echo REM = This file is generated from rules.vc > versions.vc]

!endif
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \


   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]


!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \




   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]




!endif

!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \



   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]






!endif




# If building the tcl core then we need additional package versions
!if "$(PROJECT)" == "tcl"

!if [echo PKG_HTTP_VER = \>> versions.vc] \
   && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
!endif
!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
   && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
!endif
!if [echo PKG_MSGCAT_VER = \>> versions.vc] \

   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]


!endif
!if [echo PKG_PLATFORM_VER = \>> versions.vc] \

   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
!endif
!if [echo PKG_SHELL_VER = \>> versions.vc] \
   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]

!endif
!if [echo PKG_DDE_VER = \>> versions.vc] \
   && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
!endif
!if [echo PKG_REG_VER =\>> versions.vc] \
   && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
!endif
!endif












!include versions.vc


#--------------------------------------------------------------
# Setup tcl version dependent stuff headers
#--------------------------------------------------------------

!if "$(PROJECT)" != "tcl"











TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)




































!if $(TCLINSTALL)
TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
!endif
TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib"

TCLDDELIB	= "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib"
COFFBASE	= \must\have\tcl\sources\to\build\this\target
TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES    = -I"$(_TCLDIR)\include"
!else
TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
!endif
TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
TCL_LIBRARY	= $(_TCLDIR)\library
TCLREGLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib"
TCLDDELIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib"

COFFBASE	= "$(_TCLDIR)\win\coffbase.txt"
TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
!endif



























!endif





#-------------------------------------------------------------------------




# Locate the Tk headers to build against


#-------------------------------------------------------------------------




!if "$(PROJECT)" == "tk"
_TK_H          = ..\generic\tk.h

_INSTALLDIR    = $(_INSTALLDIR)\..



!endif








!ifdef PROJECT_REQUIRES_TK
!if !defined(TKDIR)
!if exist("$(_INSTALLDIR)\..\include\tk.h")
TKINSTALL      = 1
_TKDIR         = $(_INSTALLDIR)\..
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)
!elseif exist("$(_TCLDIR)\include\tk.h")

TKINSTALL      = 1
_TKDIR         = $(_TCLDIR)
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)
!endif




!else
_TKDIR = $(TKDIR:/=\)
!if exist("$(_TKDIR)\include\tk.h")











TKINSTALL      = 1
_TK_H          = $(_TKDIR)\include\tk.h
!elseif exist("$(_TKDIR)\generic\tk.h")
TKINSTALL      = 0
_TK_H          = $(_TKDIR)\generic\tk.h

!else
MSG =^
Failed to find tk.h. The TKDIR macro does not appear correct.
!error $(MSG)
!endif
!endif


!endif




#-------------------------------------------------------------------------




# Extract Tk version numbers




#-------------------------------------------------------------------------









!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"





!if [echo TK_MAJOR_VERSION = \>> versions.vc] \


   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]


!endif
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
!endif
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
!endif






!include versions.vc

TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)










!if "$(PROJECT)" != "tk"

!if $(TKINSTALL)
WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"


TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
TK_INCLUDES     = -I"$(_TKDIR)\include"
!else
WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"

TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif


!endif


!endif




#----------------------------------------------------------
# Display stats being used.
#----------------------------------------------------------







!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'

!message *** Suffix for binaries will be '$(SUFX)'
!message *** Optional defines are '$(OPTDEFINES)'
!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
!message *** Host architecture is $(NATIVE_ARCH)
!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
!message *** Link options '$(LINKERFLAGS)'

!endif

Changes to win/stubs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66




67
68
69
70
71
72
73
74
75
76













77
78
79
80
81
82
83


84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
#include "tkInt.h"

/*
 * Undocumented Xlib internal function
 */

int
_XInitImageFuncPtrs(
    XImage *image)
{
    (void)image;

    return Success;
}

/*
 * From Xutil.h
 */

void
XSetWMClientMachine(
    Display *display,
    Window w,
    XTextProperty *text_prop)
{
	(void)display;
	(void)w;
	(void)text_prop;
}

Status
XStringListToTextProperty(
    char **list,
    int count,
    XTextProperty *text_prop_return)
{
    (void)list;
    (void)count;
    (void)text_prop_return;

    return Success;
}

/*
 * From Xlib.h
 */

int
XChangeProperty(
    Display *display,
    Window w,
    Atom property,
    Atom type,
    int format,
    int mode,
    _Xconst unsigned char *data,
    int nelements)
{
    (void)display;

    (void)w;
    (void)property;
    (void)type;
    (void)format;
    (void)mode;
    (void)data;
    (void)nelements;





    return Success;
}

XIC
XCreateIC(XIM xim, ...)
{
    (void)xim;
    return NULL;
}














int
XDeleteProperty(
    Display *display,
    Window w,
    Atom property)
{


    (void)display;
    (void)w;
    (void)property;


    return Success;
}

Bool
XFilterEvent(
    XEvent *event,
    Window window)
{
    (void)event;
    (void)window;

    return 0;
}

int
XForceScreenSaver(
    Display *display,
    int mode)
{
    (void)display;
    (void)mode;

    return Success;
}

int
XFreeCursor(
    Display *display,
    Cursor cursor)
{
    (void)display;
    (void)cursor;

    return Success;
}

GContext
XGContextFromGC(
    GC gc)
{
    (void)gc;

    return (GContext) NULL;
}

char *
XGetAtomName(
    Display *display,
    Atom atom)
{
    (void)display;
    (void)atom;

    return NULL;
}

int
XGetWindowAttributes(
    Display *display,
    Window w,
    XWindowAttributes *window_attributes_return)
{
    (void)display;
    (void)w;
    (void)window_attributes_return;

    return Success;
}

Status
XGetWMColormapWindows(
    Display *display,
    Window w,
    Window **windows_return,
    int *count_return)
{
    (void)display;
    (void)w;
    (void)windows_return;
    (void)count_return;

    return Success;
}

int
XIconifyWindow(
    Display *display,
    Window w,
    int screen_number)
{
    (void)display;
    (void)w;
    (void)screen_number;

    return Success;
}

XHostAddress *
XListHosts(
    Display *display,
    int *nhosts_return,
    Bool *state_return)
{
    (void)display;
    (void)nhosts_return;
    (void)state_return;

    return NULL;
}

int
XLookupColor(
    Display *display,
    Colormap colormap,
    _Xconst char *color_name,
    XColor *exact_def_return,
    XColor *screen_def_return)
{
    (void)display;
    (void)colormap;
    (void)color_name;
    (void)exact_def_return;
    (void)screen_def_return;

    return Success;
}

int
XNextEvent(
    Display *display,
    XEvent *event_return)
{
    (void)display;
    (void)event_return;

    return Success;
}

int
XPutBackEvent(
    Display *display,
    XEvent *event)
{
    (void)display;
    (void)event;

    return Success;
}

int
XQueryColors(
    Display *display,
    Colormap colormap,
    XColor *defs_in_out,
    int ncolors)
{
    (void)display;
    (void)colormap;
    (void)defs_in_out;
    (void)ncolors;

    return Success;
}

int
XQueryTree(
    Display *display,
    Window w,
    Window *root_return,
    Window *parent_return,
    Window **children_return,
    unsigned int *nchildren_return)
{
    (void)display;
    (void)w;
    (void)root_return;
    (void)parent_return;
    (void)children_return;
    (void)nchildren_return;

    return Success;
}

int
XRefreshKeyboardMapping(
    XMappingEvent *event_map)
{
    (void)event_map;

    return Success;
}

Window
XRootWindow(
    Display *display,
    int screen_number)
{
    (void)display;
    (void)screen_number;

    return (Window) NULL;
}

int
XSelectInput(
    Display *display,
    Window w,
    long event_mask)
{
    (void)display;
    (void)w;
    (void)event_mask;

    return Success;
}

int
XSendEvent(
    Display *display,
    Window w,
    Bool propagate,
    long event_mask,
    XEvent *event_send)
{
    (void)display;
    (void)w;
    (void)propagate;
    (void)event_mask;
    (void)event_send;

    return Success;
}

int
XSetCommand(
    Display *display,
    Window w,
    char **argv,
    int argc)
{
    (void)display;
    (void)w;
    (void)argv;
    (void)argc;

    return Success;
}

XErrorHandler
XSetErrorHandler(
    XErrorHandler handler)
{
    (void)handler;

    return NULL;
}

int
XSetIconName(
    Display *display,
    Window w,
    _Xconst char *icon_name)
{
    (void)display;
    (void)w;
    (void)icon_name;

    return Success;
}

int
XSetWindowBackground(
    Display *display,
    Window w,
    unsigned long background_pixel)
{
    (void)display;
    (void)w;
    (void)background_pixel;

    return Success;
}

int
XSetWindowBackgroundPixmap(
    Display *display,
    Window w,
    Pixmap background_pixmap)
{
    (void)display;
    (void)w;
    (void)background_pixmap;

    return Success;
}

int
XSetWindowBorder(
    Display *display,
    Window w,
    unsigned long border_pixel)
{
    (void)display;
    (void)w;
    (void)border_pixel;

    return Success;
}

int
XSetWindowBorderPixmap(
    Display *display,
    Window w,
    Pixmap border_pixmap)
{
    (void)display;
    (void)w;
    (void)border_pixmap;

    return Success;
}

int
XSetWindowBorderWidth(
    Display *display,
    Window w,
    unsigned int width)
{
    (void)display;
    (void)w;
    (void)width;

    return Success;
}

int
XSetWindowColormap(
    Display *display,
    Window w,
    Colormap colormap)
{
    (void)display;
    (void)w;
    (void)colormap;

    return Success;
}

Bool
XTranslateCoordinates(
    Display *display,
    Window src_w,
    Window dest_w,
    int src_x,
    int src_y,
    int *dest_x_return,
    int *dest_y_return,
    Window *child_return)
{
    (void)display;
    (void)src_w;
    (void)dest_w;
    (void)src_x;
    (void)src_y;
    (void)dest_x_return;
    (void)dest_y_return;
    (void)child_return;

    return 0;
}

int
XWindowEvent(
    Display *display,
    Window w,
    long event_mask,
    XEvent *event_return)
{
    (void)display;
    (void)w;
    (void)event_mask;
    (void)event_return;

    return Success;
}

int
XWithdrawWindow(
    Display *display,
    Window w,
    int screen_number)
{
    (void)display;
    (void)w;
    (void)screen_number;

    return Success;
}

int
XmbLookupString(
    XIC ic,
    XKeyPressedEvent *event,
    char *buffer_return,
    int bytes_buffer,
    KeySym *keysym_return,
    Status *status_return)
{
    (void)ic;
    (void)event;
    (void)buffer_return;
    (void)bytes_buffer;
    (void)keysym_return;
    (void)status_return;

    return Success;
}

int
XGetWindowProperty(
    Display *display,
    Window w,
    Atom property,
    long long_offset,
    long long_length,
    Bool del,
    Atom req_type,
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    unsigned char **prop_return)
{
    (void)display;
    (void)w;
    (void)property;
    (void)long_offset;
    (void)long_length;
    (void)del;
    (void)req_type;

    *actual_type_return = None;
    *actual_format_return = 0;
    *nitems_return = 0;
    *bytes_after_return = 0;
    *prop_return = NULL;
    return BadValue;
}

/*
 * The following functions were implemented as macros under Windows.
 */

int
XFlush(
    Display *display)
{
    (void)display;

    return 0;
}

int
XGrabServer(
    Display *display)
{
    (void)display;

    return 0;
}

int
XUngrabServer(
    Display *display)
{
    (void)display;

    return 0;
}

int
XFree(
    void *data)
{
	if ((data) != NULL) {
		ckfree(data);
	}
    return 0;
}

int
XNoOp(
    Display *display)
{
    display->request++;
    return 0;
}

XAfterFunction
XSynchronize(
    Display *display,
    Bool onoff)
{
    (void)onoff;

    display->request++;
    return NULL;
}

int
XSync(
    Display *display,
    Bool discard)
{
    (void)discard;

    display->request++;
    return 0;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

int
XOffsetRegion(
    Region rgn,
	int dx,
	int dy)
{
    (void)rgn;
    (void)dx;
    (void)dy;

	return 0;
}
|









<
<













<
<
<








<
<
<
<
|

















|
>
|
<
|
|
|
|
|
>
>
>
>
|
|





<


>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
|
|
|
>
|
<







<
<
<








<
<
<








<
<
<







<
<








<
<
<









<
<
<
<










<
<
<
<
<
|








<
<
<
<









<
<
<
<











<
<
<
<
<
<








<
<
<








<
<
<










<
<
<
<
<












<
<
<
<
<
<
<







<
<








<
<
<









<
<
<
<











<
<
<
<
<
<










<
<
<
<
<







<
<









<
<
<
<









<
<
<
<









<
<
<
<









<
<
<
<









<
<
<
<









<
<
<
<









<
<
<
<














<
<
<
<
<
<
<
<
<










<
<
<
<
<









<
<
<
<












<
<
<
<
<
<
<










|







<
<
<
<
<
<
<
<







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29
30
31




32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104



105
106
107
108
109
110
111
112



113
114
115
116
117
118
119
120



121
122
123
124
125
126
127


128
129
130
131
132
133
134
135



136
137
138
139
140
141
142
143
144




145
146
147
148
149
150
151
152
153
154





155
156
157
158
159
160
161
162
163




164
165
166
167
168
169
170
171
172




173
174
175
176
177
178
179
180
181
182
183






184
185
186
187
188
189
190
191



192
193
194
195
196
197
198
199



200
201
202
203
204
205
206
207
208
209





210
211
212
213
214
215
216
217
218
219
220
221







222
223
224
225
226
227
228


229
230
231
232
233
234
235
236



237
238
239
240
241
242
243
244
245




246
247
248
249
250
251
252
253
254
255
256






257
258
259
260
261
262
263
264
265
266





267
268
269
270
271
272
273


274
275
276
277
278
279
280
281
282




283
284
285
286
287
288
289
290
291




292
293
294
295
296
297
298
299
300




301
302
303
304
305
306
307
308
309




310
311
312
313
314
315
316
317
318




319
320
321
322
323
324
325
326
327




328
329
330
331
332
333
334
335
336




337
338
339
340
341
342
343
344
345
346
347
348
349
350









351
352
353
354
355
356
357
358
359
360





361
362
363
364
365
366
367
368
369




370
371
372
373
374
375
376
377
378
379
380
381







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399








400
401
402
403
404
405
406



























































































#include "tk.h"

/*
 * Undocumented Xlib internal function
 */

int
_XInitImageFuncPtrs(
    XImage *image)
{


    return Success;
}

/*
 * From Xutil.h
 */

void
XSetWMClientMachine(
    Display *display,
    Window w,
    XTextProperty *text_prop)
{



}

Status
XStringListToTextProperty(
    char **list,
    int count,
    XTextProperty *text_prop_return)
{




    return (Status) 0;
}

/*
 * From Xlib.h
 */

int
XChangeProperty(
    Display *display,
    Window w,
    Atom property,
    Atom type,
    int format,
    int mode,
    _Xconst unsigned char *data,
    int nelements)
{
    return Success;
}


Cursor
XCreateGlyphCursor(
    Display *display,
    Font source_font,
    Font mask_font,
    unsigned int source_char,
    unsigned int mask_char,
    XColor _Xconst *foreground_color,
    XColor _Xconst *background_color)
{
    return 1;
}

XIC
XCreateIC(XIM xim, ...)
{

    return NULL;
}

Cursor
XCreatePixmapCursor(
    Display *display,
    Pixmap source,
    Pixmap mask,
    XColor *foreground_color,
    XColor *background_color,
    unsigned int x,
    unsigned int y)
{
    return (Cursor) NULL;
}

int
XDeleteProperty(
    Display *display,
    Window w,
    Atom property)
{
    return Success;
}

void
XDestroyIC(
    XIC ic)
{

}

Bool
XFilterEvent(
    XEvent *event,
    Window window)
{



    return 0;
}

int
XForceScreenSaver(
    Display *display,
    int mode)
{



    return Success;
}

int
XFreeCursor(
    Display *display,
    Cursor cursor)
{



    return Success;
}

GContext
XGContextFromGC(
    GC gc)
{


    return (GContext) NULL;
}

char *
XGetAtomName(
    Display *display,
    Atom atom)
{



    return NULL;
}

int
XGetWindowAttributes(
    Display *display,
    Window w,
    XWindowAttributes *window_attributes_return)
{




    return Success;
}

Status
XGetWMColormapWindows(
    Display *display,
    Window w,
    Window **windows_return,
    int *count_return)
{





    return (Status) 0;
}

int
XIconifyWindow(
    Display *display,
    Window w,
    int screen_number)
{




    return Success;
}

XHostAddress *
XListHosts(
    Display *display,
    int *nhosts_return,
    Bool *state_return)
{




    return NULL;
}

int
XLookupColor(
    Display *display,
    Colormap colormap,
    _Xconst char *color_name,
    XColor *exact_def_return,
    XColor *screen_def_return)
{






    return Success;
}

int
XNextEvent(
    Display *display,
    XEvent *event_return)
{



    return Success;
}

int
XPutBackEvent(
    Display *display,
    XEvent *event)
{



    return Success;
}

int
XQueryColors(
    Display *display,
    Colormap colormap,
    XColor *defs_in_out,
    int ncolors)
{





    return Success;
}

int
XQueryTree(
    Display *display,
    Window w,
    Window *root_return,
    Window *parent_return,
    Window **children_return,
    unsigned int *nchildren_return)
{







    return Success;
}

int
XRefreshKeyboardMapping(
    XMappingEvent *event_map)
{


    return Success;
}

Window
XRootWindow(
    Display *display,
    int screen_number)
{



    return (Window) NULL;
}

int
XSelectInput(
    Display *display,
    Window w,
    long event_mask)
{




    return Success;
}

int
XSendEvent(
    Display *display,
    Window w,
    Bool propagate,
    long event_mask,
    XEvent *event_send)
{






    return Success;
}

int
XSetCommand(
    Display *display,
    Window w,
    char **argv,
    int argc)
{





    return Success;
}

XErrorHandler
XSetErrorHandler(
    XErrorHandler handler)
{


    return NULL;
}

int
XSetIconName(
    Display *display,
    Window w,
    _Xconst char *icon_name)
{




    return Success;
}

int
XSetWindowBackground(
    Display *display,
    Window w,
    unsigned long background_pixel)
{




    return Success;
}

int
XSetWindowBackgroundPixmap(
    Display *display,
    Window w,
    Pixmap background_pixmap)
{




    return Success;
}

int
XSetWindowBorder(
    Display *display,
    Window w,
    unsigned long border_pixel)
{




    return Success;
}

int
XSetWindowBorderPixmap(
    Display *display,
    Window w,
    Pixmap border_pixmap)
{




    return Success;
}

int
XSetWindowBorderWidth(
    Display *display,
    Window w,
    unsigned int width)
{




    return Success;
}

int
XSetWindowColormap(
    Display *display,
    Window w,
    Colormap colormap)
{




    return Success;
}

Bool
XTranslateCoordinates(
    Display *display,
    Window src_w,
    Window dest_w,
    int src_x,
    int src_y,
    int *dest_x_return,
    int *dest_y_return,
    Window *child_return)
{









    return 0;
}

int
XWindowEvent(
    Display *display,
    Window w,
    long event_mask,
    XEvent *event_return)
{





    return Success;
}

int
XWithdrawWindow(
    Display *display,
    Window w,
    int screen_number)
{




    return Success;
}

int
XmbLookupString(
    XIC ic,
    XKeyPressedEvent *event,
    char *buffer_return,
    int bytes_buffer,
    KeySym *keysym_return,
    Status *status_return)
{







    return Success;
}

int
XGetWindowProperty(
    Display *display,
    Window w,
    Atom property,
    long long_offset,
    long long_length,
    Bool delete,
    Atom req_type,
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    unsigned char **prop_return)
{








    *actual_type_return = None;
    *actual_format_return = 0;
    *nitems_return = 0;
    *bytes_after_return = 0;
    *prop_return = NULL;
    return BadValue;
}



























































































Deleted win/targets.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**

$(PRJ_STUBOBJS):
	$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS

!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
	@nmakehlp -s << $** >$@
@MACHINE@	  $(MACHINE:IX86=X86)
<<
!endif

!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
       $(LIBCMD) $**
!else
       $(DLLCMD) $**
       $(_VC_MANIFEST_EMBED_DLL)
!endif
       -@del $*.exp
!endif

!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif

# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif

# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif

!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif

!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif

!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Changes to win/tcl.m4.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )







|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    [with_tclconfig="${withval}"])
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )







|

|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    [with_tkconfig="${withval}"])
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#
# Results:
#
#	Substitutes the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE
#		TCL_ZIP_FILE
#
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then







<







247
248
249
250
251
252
253

254
255
256
257
258
259
260
#
# Results:
#
#	Substitutes the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE

#
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
276
277
278
279
280
281
282








283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi









    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_ZIP_FILE)
    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)







>
>
>
>
>
>
>
>








<







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi

    #
    # eval is required to do the TCL_DBGX substitution
    #

    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""

    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)


    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376



































377
378
379
380
381
382
383
384
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	[  --enable-shared         build and link with shared libraries (default: on)],
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
    fi



































    AC_SUBST(SHARED_BUILD)
])

#------------------------------------------------------------------------
# SC_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging







<
<
<
<
<
<
<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







360
361
362
363
364
365
366








367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	[  --enable-shared         build and link with shared libraries (default: on)],
	[tcl_ok=$enableval], [tcl_ok=yes])








    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
    fi
])

#------------------------------------------------------------------------
# SC_ENABLE_THREADS --
#
#	Specify if thread support should be enabled
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-threads=yes|no
#
#	Defines the following vars:
#		TCL_THREADS
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_THREADS], [
    AC_MSG_CHECKING(for building with threads)
    AC_ARG_ENABLE(threads, [  --enable-threads        build with threads (default: off)],
	[tcl_ok=$enableval], [tcl_ok=no])

    if test "$tcl_ok" = "yes"; then
	AC_MSG_RESULT(yes)
	TCL_THREADS=1
	AC_DEFINE(TCL_THREADS)
	# USE_THREAD_ALLOC tells us to try the special thread-based
	# allocator that significantly reduces lock contention
	AC_DEFINE(USE_THREAD_ALLOC)
    else
	TCL_THREADS=0
	AC_MSG_RESULT([no (default)])
    fi
    AC_SUBST(TCL_THREADS)
])

#------------------------------------------------------------------------
# SC_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420

421
422
423
424
425
426
427
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false

#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols, [  --enable-symbols        build with debugging symbols (default: off)],    [tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'

	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
	AC_MSG_RESULT([no])

	AC_DEFINE(TCL_CFG_OPTIMIZED)
    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'

	if test "$tcl_ok" = "yes"; then
	    AC_MSG_RESULT([yes (standard debugging)])
	fi
    fi
    AC_SUBST(CFLAGS_DEFAULT)
    AC_SUBST(LDFLAGS_DEFAULT)








>










>







>







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#		DBGX		Debug library extension
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols, [  --enable-symbols        build with debugging symbols (default: off)],    [tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	DBGX=""
	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
	AC_MSG_RESULT([no])

	AC_DEFINE(TCL_CFG_OPTIMIZED)
    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	DBGX=g
	if test "$tcl_ok" = "yes"; then
	    AC_MSG_RESULT([yes (standard debugging)])
	fi
    fi
    AC_SUBST(CFLAGS_DEFAULT)
    AC_SUBST(LDFLAGS_DEFAULT)

495
496
497
498
499
500
501











502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,[  --enable-64bit          enable 64bit support (where applicable)], [do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT($do64bit)












    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""
	AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden])

    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
    AC_CHECK_PROG(WINE, wine, wine,)

    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_TRY_COMPILE([
	    #ifndef _WIN32
		#error cross-compiler
	    #endif
	], [],
	ac_cv_cross=no,
	ac_cv_cross=yes)
      )

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-${CC}"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
	esac
      fi







>
>
>
>
>
>
>
>
>
>
>






<











|



|
|
|





|






|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,[  --enable-64bit          enable 64bit support (where applicable)], [do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT($do64bit)

    # Cross-compiling options for Windows/CE builds

    AC_MSG_CHECKING([if Windows/CE build is requested])
    AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
    AC_MSG_RESULT($doWince)

    AC_MSG_CHECKING([for Windows/CE celib directory])
    AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR],
	    CELIB_DIR=$withval, CELIB_DIR=NO_CELIB)
    AC_MSG_RESULT([$CELIB_DIR])

    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""
	AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden])

    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)


    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #ifndef _WIN32
		#error cross-compiler
	    #endif
	]], [[]])],
	[ac_cv_cross=no],
	[ac_cv_cross=yes])
      )

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-gcc"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-gcc"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
	esac
      fi
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	AC_CACHE_CHECK(for mingw32 version of gcc,
	    ac_cv_win32,
	    AC_TRY_COMPILE([
		#ifdef _WIN32
		    #error win32
		#endif
	    ], [],
	    ac_cv_win32=no,
	    ac_cv_win32=yes)
	)
	if test "$ac_cv_win32" != "yes"; then
	    AC_MSG_ERROR([${CC} cannot produce win32 executables.])
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	AC_CACHE_CHECK(for working -municode linker flag,
	    ac_cv_municode,
	AC_TRY_LINK([
	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}
	],
	[],
	    ac_cv_municode=yes,
	    ac_cv_municode=no)
	)
	CFLAGS=$hold_cflags
	if test "$ac_cv_municode" = "yes" ; then
	    extra_ldflags="$extra_ldflags -municode"
	else
	    extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
	fi
    fi

    AC_MSG_CHECKING([compiler flags])
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \[$]@"
	MAKE_STUB_LIB="\${STLIB_LD} \[$]@"
	POST_MAKE_LIB="\${RANLIB} \[$]@"
	MAKE_EXE="\${CC} -o \[$]@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		AC_MSG_ERROR([${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain.])
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	#







|



|
|
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|



















|













|







|


|
|
|






|



<
<
<
<
<
<
<
<
<







626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643


















644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707









708
709
710
711
712
713
714
    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	AC_CACHE_CHECK(for mingw32 version of gcc,
	    ac_cv_win32,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef _WIN32
		    #error win32
		#endif
	    ]], [[]])],
	    [ac_cv_win32=no],
	    [ac_cv_win32=yes])
	)
	if test "$ac_cv_win32" != "yes"; then
	    AC_MSG_ERROR([${CC} cannot produce win32 executables.])
	fi


















    fi

    AC_MSG_CHECKING([compiler flags])
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \[$]@"
	MAKE_STUB_LIB="\${STLIB_LD} \[$]@"
	POST_MAKE_LIB="\${RANLIB} \[$]@"
	MAKE_EXE="\${CC} -o \[$]@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		AC_MSG_ERROR([${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain.])
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX="\${DBGX}.exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\[$]@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.a"
	LIBFLAGSUFFIX="\${DBGX}"
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wdeclaration-after-statement -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=










	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	#
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    *)
		AC_TRY_COMPILE([
		    #ifndef _WIN64
			#error 32-bit
		    #endif
		], [],
			tcl_win_64bit=yes,
			tcl_win_64bit=no
		)
		if test "$tcl_win_64bit" = "yes" ; then
			do64bit=amd64
			MACHINE="AMD64"
			AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
	fi

	LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;







|



|
|
|


|
|
|









|






|











|
|
|













|







732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    *)
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		    #ifndef _WIN64
			#error 32-bit
		    #endif
		]], [[]])],
		    [tcl_win_64bit=yes],
		    [tcl_win_64bit=no]
		)
		if test "$tcl_win_64bit" = "yes" ; then
		    do64bit=amd64
		    MACHINE="AMD64"
		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX="\${DBGX}.exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.lib"
	LIBFLAGSUFFIX="\${DBGX}"

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
	fi

	LIBS="user32.lib advapi32.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;
800
801
802
803
804
805
806


























































































807

808
809
810
811
812
813
814
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi



























































































	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"


	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>







819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	if test "$doWince" != "no" ; then
	    # Set defaults for common evc4/PPC2003 setup
	    # Currently Tcl requires 300+, possibly 420+ for sockets
	    CEVERSION=420; 		# could be 211 300 301 400 420 ...
	    TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
	    ARCH=ARM;		# could be ARM MIPS X86EM ...
	    PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
	    if test "$doWince" != "yes"; then
		# If !yes then the user specified something
		# Reset ARCH to allow user to skip specifying it
		ARCH=
		eval `echo $doWince | awk -F "," '{ \
	if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
	if ([$]1 < 400)	  { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
	if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
	if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
	if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
		}'`
		if test "x${ARCH}" = "x" ; then
		    ARCH=$TARGETCPU;
		fi
	    fi
	    OSVERSION=WCE$CEVERSION;
	    if test "x${WCEROOT}" = "x" ; then
		WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
		if test ! -d "${WCEROOT}" ; then
		    WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
		fi
	    fi
	    if test "x${SDKROOT}" = "x" ; then
		SDKROOT="C:/Program Files/Windows CE Tools"
		if test ! -d "${SDKROOT}" ; then
		    SDKROOT="C:/Windows CE Tools"
		fi
	    fi
	    # The space-based-path will work for the Makefile, but will
	    # not work if AC_TRY_COMPILE is called.
	    WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
	    SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
	    if test ! -d "${CELIB_DIR}/inc"; then
		AC_MSG_ERROR([Invalid celib directory "${CELIB_DIR}"])
	    fi
	    if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\
		-o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
		AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
	    else
		CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
		if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
		    CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
		fi
		CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
	    fi
	fi

	if test "$doWince" != "no" ; then
	    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
	    if test "${TARGETCPU}" = "X86"; then
		CC="${CEBINROOT}/cl.exe"
	    else
		CC="${CEBINROOT}/cl${ARCH}.exe"
	    fi
	    CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
	    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
	    arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
	    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS"
	    for i in $defs ; do
		AC_DEFINE_UNQUOTED($i)
	    done
#	    if test "${ARCH}" = "X86EM"; then
#		AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
#	    fi
	    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION)
	    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION)
	    CFLAGS_DEBUG="-nologo -Zi -Od"
	    CFLAGS_OPTIMIZE="-nologo -O2"
	    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
	    lflags="-nodefaultlib -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
	    LINKBIN="\"${CEBINROOT}/link.exe\""
	    AC_SUBST(CELIB_DIR)
	    if test "${CEVERSION}" -lt 400 ; then
		LIBS="coredll.lib corelibc.lib winsock.lib"
	    else
		LIBS="coredll.lib corelibc.lib ws2.lib"
	    fi
	    # celib currently stuck at wce300 status
	    #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib"
	    LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\""
	    LIBS_GUI="commctrl.lib commdlg.lib"
	else
	    LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
	fi

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-Fo\[$]@"
	CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\[$]@')\""

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	if test "${TARGETCPU}" != "X86"; then
	    LDFLAGS_CONSOLE="-link ${lflags}"
	    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	AC_DEFINE(TCL_CFG_DO64BIT)
    fi

    if test "${GCC}" = "yes" ; then
	AC_CACHE_CHECK(for SEH support in compiler,
	    tcl_cv_seh,
	AC_TRY_RUN([
	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }
	],
	    tcl_cv_seh=yes,
	    tcl_cv_seh=no,
	    tcl_cv_seh=no)
	)
	if test "$tcl_cv_seh" = "no" ; then
	    AC_DEFINE(HAVE_NO_SEH, 1,
		    [Defined when mingw does not support SEH])
	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
	    tcl_cv_eh_disposition,
	    AC_TRY_COMPILE([
#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN
	    ],[
		EXCEPTION_DISPOSITION x;
	    ],
		tcl_cv_eh_disposition=yes,
		tcl_cv_eh_disposition=no)
	)
	if test "$tcl_cv_eh_disposition" = "no" ; then
	AC_DEFINE(EXCEPTION_DISPOSITION, int,
		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
	    tcl_cv_winnt_ignore_void,
	    AC_TRY_COMPILE([
		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN
	    ], [
		CHAR c;
		SHORT s;
		LONG l;
	    ],
        tcl_cv_winnt_ignore_void=yes,
        tcl_cv_winnt_ignore_void=no)
	)
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
	fi

	AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_TRY_COMPILE([],
	    [
		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ],
	    tcl_cv_cast_to_union=yes,
	    tcl_cv_cast_to_union=no)
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi
    fi








|















|














|
|
|
|














|



|

|
|
|












|




|



|
|
|






<
<






|
<


|
|
|







941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035


1036
1037
1038
1039
1040
1041
1042

1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-Fo\[$]@"
	CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\[$]@')\""

	# Specify linker flags depending on the type of app being
	# built -- Console vs. Window.
	if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then
	    LDFLAGS_CONSOLE="-link ${lflags}"
	    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	AC_DEFINE(TCL_CFG_DO64BIT)
    fi

    if test "${GCC}" = "yes" ; then
	AC_CACHE_CHECK(for SEH support in compiler,
	    tcl_cv_seh,
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }
	]])],
	    [tcl_cv_seh=yes],
	    [tcl_cv_seh=no],
	    [tcl_cv_seh=no])
	)
	if test "$tcl_cv_seh" = "no" ; then
	    AC_DEFINE(HAVE_NO_SEH, 1,
		    [Defined when mingw does not support SEH])
	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
	    tcl_cv_eh_disposition,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN
	    ]], [[
		EXCEPTION_DISPOSITION x;
	    ]])],
	    [tcl_cv_eh_disposition=yes],
	    [tcl_cv_eh_disposition=no])
	)
	if test "$tcl_cv_eh_disposition" = "no" ; then
	AC_DEFINE(EXCEPTION_DISPOSITION, int,
		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
	    tcl_cv_winnt_ignore_void,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN
	    ]], [[
		CHAR c;
		SHORT s;
		LONG l;
	    ]])],
	    [tcl_cv_winnt_ignore_void=yes],
	    [tcl_cv_winnt_ignore_void=no])
	)
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
	fi



	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ]])],
	    [tcl_cv_cast_to_union=yes],
	    [tcl_cv_cast_to_union=no])
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi
    fi

966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
#		--with-tcl=...
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the tcl build dir.
#------------------------------------------------------------------------

AC_DEFUN([SC_WITH_TCL], [
    if test -d ../../tcl8.7$1/win;  then
	TCL_BIN_DEFAULT=../../tcl8.7$1/win
    else
	TCL_BIN_DEFAULT=../../tcl8.7/win
    fi

    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.7 binaries from DIR],
	    TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`)
    if test ! -d $TCL_BIN_DIR; then
	AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
    fi
    if test ! -f $TCL_BIN_DIR/Makefile; then
	AC_MSG_ERROR(There is no Makefile in $TCL_BIN_DIR:  perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
    else







|
|

|


|







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
#		--with-tcl=...
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the tcl build dir.
#------------------------------------------------------------------------

AC_DEFUN([SC_WITH_TCL], [
    if test -d ../../tcl8.5$1/win;  then
	TCL_BIN_DEFAULT=../../tcl8.5$1/win
    else
	TCL_BIN_DEFAULT=../../tcl8.5/win
    fi

    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.5 binaries from DIR],
	    TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`)
    if test ! -d $TCL_BIN_DIR; then
	AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
    fi
    if test ! -f $TCL_BIN_DIR/Makefile; then
	AC_MSG_ERROR(There is no Makefile in $TCL_BIN_DIR:  perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
    else
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
# Results
#	Subst's the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    AC_MSG_RESULT($BUILD_TCLSH)
    AC_SUBST(BUILD_TCLSH)
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#







|







1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
# Results
#	Subst's the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}
    AC_MSG_RESULT($BUILD_TCLSH)
    AC_SUBST(BUILD_TCLSH)
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
#		VC_MANIFEST_EMBED_EXE
#
#--------------------------------------------------------------------

AC_DEFUN([SC_EMBED_MANIFEST], [
    AC_MSG_CHECKING(whether to embed manifest)
    AC_ARG_ENABLE(embedded-manifest,
	AC_HELP_STRING([--enable-embedded-manifest],
		[embed manifest if possible (default: yes)]),
	[embed_ok=$enableval], [embed_ok=yes])

    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \







|







1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
#		VC_MANIFEST_EMBED_EXE
#
#--------------------------------------------------------------------

AC_DEFUN([SC_EMBED_MANIFEST], [
    AC_MSG_CHECKING(whether to embed manifest)
    AC_ARG_ENABLE(embedded-manifest,
	AS_HELP_STRING([--enable-embedded-manifest],
		[embed manifest if possible (default: yes)]),
	[embed_ok=$enableval], [embed_ok=yes])

    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
	fi
	])
    fi
    AC_MSG_RESULT([$result])
    AC_SUBST(VC_MANIFEST_EMBED_DLL)
    AC_SUBST(VC_MANIFEST_EMBED_EXE)
])

#------------------------------------------------------------------------
# SC_CC_FOR_BUILD
#	For cross compiles, locate a C compiler that can generate native binaries.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		CC_FOR_BUILD
#		EXEEXT_FOR_BUILD
#------------------------------------------------------------------------

dnl Get a default for CC_FOR_BUILD to put into Makefile.
AC_DEFUN([AX_CC_FOR_BUILD],
[# Put a plausible default for CC_FOR_BUILD in Makefile.
if test -z "$CC_FOR_BUILD"; then
  if test "x$cross_compiling" = "xno"; then
    CC_FOR_BUILD='$(CC)'
  else
    AC_MSG_CHECKING([for gcc])
    AC_CACHE_VAL(ac_cv_path_cc, [
	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/gcc 2> /dev/null` \
		    `ls -r $dir/gcc 2> /dev/null` ; do
		if test x"$ac_cv_path_cc" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_cc=$j
			break
		    fi
		fi
	    done
	done
    ])
  fi
fi
AC_SUBST(CC_FOR_BUILD)
# Also set EXEEXT_FOR_BUILD.
if test "x$cross_compiling" = "xno"; then
  EXEEXT_FOR_BUILD='$(EXEEXT)'
  OBJEXT_FOR_BUILD='$(OBJEXT)'
else
  OBJEXT_FOR_BUILD='.no'
  AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
    [rm -f conftest*
     echo 'int main () { return 0; }' > conftest.c
     bfd_cv_build_exeext=
     ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
     for file in conftest.*; do
       case $file in
       *.c | *.o | *.obj | *.ilk | *.pdb) ;;
       *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
     rm -f conftest*
     test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
  EXEEXT_FOR_BUILD=""
  test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
fi
AC_SUBST(EXEEXT_FOR_BUILD)])dnl
AC_SUBST(OBJEXT_FOR_BUILD)])dnl



#------------------------------------------------------------------------
# SC_ZIPFS_SUPPORT
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		ZIP_PROG
#       ZIP_PROG_OPTIONS
#       ZIP_PROG_VFSSEARCH
#       ZIP_INSTALL_OBJS
#------------------------------------------------------------------------

AC_DEFUN([SC_ZIPFS_SUPPORT], [
    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""

    AC_MSG_CHECKING([for zip])
    AC_CACHE_VAL(ac_cv_path_zip, [
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then
            if test -f "$j" ; then
            ac_cv_path_zip=$j
            break
            fi
        fi
        done
    done
    ])
    if test -f "$ac_cv_path_zip" ; then
        ZIP_PROG="$ac_cv_path_zip"
        AC_MSG_RESULT([$ZIP_PROG])
        ZIP_PROG_OPTIONS="-rq"
        ZIP_PROG_VFSSEARCH="*"
        AC_MSG_RESULT([Found INFO Zip in environment])
        # Use standard arguments for zip
    else
        # It is not an error if an installed version of Zip can't be located.
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        AC_MSG_RESULT([No zip found on PATH building minizip])
    fi
    AC_SUBST(ZIP_PROG)
    AC_SUBST(ZIP_PROG_OPTIONS)
    AC_SUBST(ZIP_PROG_VFSSEARCH)
    AC_SUBST(ZIP_INSTALL_OBJS)
])







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1244
1245
1246
1247
1248
1249
1250



























































































































	fi
	])
    fi
    AC_MSG_RESULT([$result])
    AC_SUBST(VC_MANIFEST_EMBED_DLL)
    AC_SUBST(VC_MANIFEST_EMBED_EXE)
])



























































































































Changes to win/tkConfig.sh.in.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'

# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@

# TK_DBGX used to be used to distinguish debug vs. non-debug builds.
# This was a righteous pain so the core doesn't do that any more.
TK_DBGX=

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

# Additional libraries to use when linking Tk.
TK_LIBS='@LIBS@ @LIBS_GUI@'








<
|
|







21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36

# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'

# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@


# This indicates if Tk was build with debugging symbols
TK_DBGX=@TK_DBGX@

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

# Additional libraries to use when linking Tk.
TK_LIBS='@LIBS@ @LIBS_GUI@'

Changes to win/tkWin.h.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41





42
43
44
45
46
47
48

#ifndef _TKWIN
#define _TKWIN

/*
 * We must specify the lower version we intend to support. In particular
 * the SystemParametersInfo API doesn't like to receive structures that
 * are larger than it expects which affects the font assignments.
 *
 * WINVER = 0x0600 means Windows Vista and above. Even though we still
 * support Windows XP, but the Vista-specifics are tested at runtime.
 */

#ifndef WINVER
#   define WINVER 0x0600
#endif
#ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0600
#endif
#ifndef _WIN32_IE
#   define _WIN32_IE 0x0700
#endif

#ifndef _TK
#include <tk.h>
#endif

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN






/*
 * The following messages are used to communicate between a Tk toplevel
 * and its container window. A Tk container may not be able to provide
 * service to all of the following requests at the moment. But an embedded
 * Tk window will send out these requests to support external Tk container
 * application.







|

|
<



|


|
<
<
<









>
>
>
>
>







12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#ifndef _TKWIN
#define _TKWIN

/*
 * We must specify the lower version we intend to support. In particular
 * the SystemParametersInfo API doesn't like to receive structures that
 * are larger than it expects which affects the font assignements.
 *
 * WINVER = 0x0410 means Windows 98 and above

 */

#ifndef WINVER
#define WINVER 0x0500
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500



#endif

#ifndef _TK
#include <tk.h>
#endif

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * The following messages are used to communicate between a Tk toplevel
 * and its container window. A Tk container may not be able to provide
 * service to all of the following requests at the moment. But an embedded
 * Tk window will send out these requests to support external Tk container
 * application.
78
79
80
81
82
83
84



85
 * Exported procedures defined for the Windows platform only.
 *
 *--------------------------------------------------------------
 */

#include "tkPlatDecls.h"




#endif /* _TKWIN */







>
>
>

79
80
81
82
83
84
85
86
87
88
89
 * Exported procedures defined for the Windows platform only.
 *
 *--------------------------------------------------------------
 */

#include "tkPlatDecls.h"

# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _TKWIN */

Changes to win/tkWin32Dll.c.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    HINSTANCE hInstance,
    DWORD reason,
    LPVOID reserved)
{
#ifdef HAVE_NO_SEH
    TCLEXCEPTION_REGISTRATION registration;
#endif
    (void)reserved;

    /*
     * If we are attaching to the DLL from a new process, tell Tk about the
     * hInstance to use.
     */

    switch (reason) {
    case DLL_PROCESS_ATTACH:
	DisableThreadLibraryCalls(hInstance);
	TkWinSetHINSTANCE(hInstance);
	break;

    case DLL_PROCESS_DETACH:
	/*
	 * Protect the call to TkFinalize in an SEH block. We can't be
	 * guarenteed Tk is always being unloaded from a stable condition.
	 */

#ifdef HAVE_NO_SEH
#   ifdef __WIN64
	__asm__ __volatile__ (

	    /*
	     * Construct an TCLEXCEPTION_REGISTRATION to protect the call to
	     * TkFinalize
	     */

	    "leaq	%[registration], %%rdx"		"\n\t"
	    "movq	%%gs:0,		%%rax"		"\n\t"
	    "movq	%%rax,		0x0(%%rdx)"	"\n\t" /* link */
	    "leaq	1f,		%%rax"		"\n\t"
	    "movq	%%rax,		0x8(%%rdx)"	"\n\t" /* handler */
	    "movq	%%rbp,		0x10(%%rdx)"	"\n\t" /* rbp */
	    "movq	%%rsp,		0x18(%%rdx)"	"\n\t" /* rsp */
	    "movl	%[error],	0x20(%%rdx)"	"\n\t" /* status */

	    /*
	     * Link the TCLEXCEPTION_REGISTRATION on the chain







<















|



|










|







100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    HINSTANCE hInstance,
    DWORD reason,
    LPVOID reserved)
{
#ifdef HAVE_NO_SEH
    TCLEXCEPTION_REGISTRATION registration;
#endif


    /*
     * If we are attaching to the DLL from a new process, tell Tk about the
     * hInstance to use.
     */

    switch (reason) {
    case DLL_PROCESS_ATTACH:
	DisableThreadLibraryCalls(hInstance);
	TkWinSetHINSTANCE(hInstance);
	break;

    case DLL_PROCESS_DETACH:
	/*
	 * Protect the call to TkFinalize in an SEH block. We can't be
	 * guaranteed Tk is always being unloaded from a stable condition.
	 */

#ifdef HAVE_NO_SEH
#   ifdef _WIN64
	__asm__ __volatile__ (

	    /*
	     * Construct an TCLEXCEPTION_REGISTRATION to protect the call to
	     * TkFinalize
	     */

	    "leaq	%[registration], %%rdx"		"\n\t"
	    "movq	%%gs:0,		%%rax"		"\n\t"
	    "movq	%%rax,		0x0(%%rdx)"	"\n\t" /* link */
	    "leaq	1f(%%rip),	%%rax"		"\n\t"
	    "movq	%%rax,		0x8(%%rdx)"	"\n\t" /* handler */
	    "movq	%%rbp,		0x10(%%rdx)"	"\n\t" /* rbp */
	    "movq	%%rsp,		0x18(%%rdx)"	"\n\t" /* rsp */
	    "movl	%[error],	0x20(%%rdx)"	"\n\t" /* status */

	    /*
	     * Link the TCLEXCEPTION_REGISTRATION on the chain

Changes to win/tkWin3d.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 *
 *----------------------------------------------------------------------
 */

TkBorder *
TkpGetBorder(void)
{
    WinBorder *borderPtr = (WinBorder *)ckalloc(sizeof(WinBorder));

    borderPtr->light2ColorPtr = NULL;
    borderPtr->dark2ColorPtr = NULL;
    return (TkBorder *) borderPtr;
}

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 *
 *----------------------------------------------------------------------
 */

TkBorder *
TkpGetBorder(void)
{
    WinBorder *borderPtr = (WinBorder *) ckalloc(sizeof(WinBorder));

    borderPtr->light2ColorPtr = NULL;
    borderPtr->dark2ColorPtr = NULL;
    return (TkBorder *) borderPtr;
}

/*

Changes to win/tkWinButton.c.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

/*
 * Cached information about the boxes bitmap, and the default border width for
 * a button in string form for use in Tk_OptionSpec for the various button
 * widget classes.
 */

typedef struct {
    BITMAPINFOHEADER *boxesPtr;	/* Information about the bitmap. */
    DWORD *boxesPalette;	/* Pointer to color palette. */
    LPSTR boxesBits;		/* Pointer to bitmap data. */
    DWORD boxHeight;		/* Height of each sub-image. */
    DWORD boxWidth;		/* Width of each sub-image. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

/*
 * Cached information about the boxes bitmap, and the default border width for
 * a button in string form for use in Tk_OptionSpec for the various button
 * widget classes.
 */

typedef struct ThreadSpecificData {
    BITMAPINFOHEADER *boxesPtr;	/* Information about the bitmap. */
    DWORD *boxesPalette;	/* Pointer to color palette. */
    LPSTR boxesBits;		/* Pointer to bitmap data. */
    DWORD boxHeight;		/* Height of each sub-image. */
    DWORD boxWidth;		/* Width of each sub-image. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
			    ClientData instanceData);
static void		InitBoxes(void);

/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL					/* modalProc */
};









|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
			    ClientData instanceData);
static void		InitBoxes(void);

/*
 * The class procedure table for the button widgets.
 */

Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL					/* modalProc */
};


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    HRSRC hrsrc;
    HGLOBAL hblk;
    LPBITMAPINFOHEADER newBitmap;
    size_t size;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    hrsrc = FindResourceW(module, L"buttons", (LPWSTR) RT_BITMAP);
    if (hrsrc == NULL) {
	Tcl_Panic("FindResourceW() failed for buttons bitmap resource, "
            "resources in tk_base.rc must be linked into Tk dll or static executable");
    } else {
	hblk = LoadResource(module, hrsrc);
	tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
    }

    /*
     * Copy the DIBitmap into writable memory.
     */

    if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
	    && !(tsdPtr->boxesPtr->biHeight % 2)) {
	size = tsdPtr->boxesPtr->biSize
		+ (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount)
		+ tsdPtr->boxesPtr->biSizeImage;
	newBitmap = (LPBITMAPINFOHEADER)ckalloc(size);
	memcpy(newBitmap, tsdPtr->boxesPtr, size);
	tsdPtr->boxesPtr = newBitmap;
	tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4;
	tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2;
	tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
		+ tsdPtr->boxesPtr->biSize);
	tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)







|

|















|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    HRSRC hrsrc;
    HGLOBAL hblk;
    LPBITMAPINFOHEADER newBitmap;
    size_t size;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    hrsrc = FindResource(module, "buttons", RT_BITMAP);
    if (hrsrc == NULL) {
	Tcl_Panic("FindResource() failed for buttons bitmap resource, "
            "resources in tk_base.rc must be linked into Tk dll or static executable");
    } else {
	hblk = LoadResource(module, hrsrc);
	tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
    }

    /*
     * Copy the DIBitmap into writable memory.
     */

    if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
	    && !(tsdPtr->boxesPtr->biHeight % 2)) {
	size = tsdPtr->boxesPtr->biSize
		+ (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount)
		+ tsdPtr->boxesPtr->biSizeImage;
	newBitmap = (LPBITMAPINFOHEADER) ckalloc(size);
	memcpy(newBitmap, tsdPtr->boxesPtr, size);
	tsdPtr->boxesPtr = newBitmap;
	tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4;
	tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2;
	tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
		+ tsdPtr->boxesPtr->biSize);
	tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 * Side effects:
 *	Updates some of.
 *
 *----------------------------------------------------------------------
 */

void
TkpButtonSetDefaults(void)
{
    int width = GetSystemMetrics(SM_CXEDGE);
	if (width > 0) {
	    sprintf(tkDefButtonBorderWidth, "%d", width);
	}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *







|


|
|
|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 * Side effects:
 *	Updates some of.
 *
 *----------------------------------------------------------------------
 */

void
TkpButtonSetDefaults()
{
    int width = GetSystemMetrics(SM_CXEDGE);
    if (width > 0) {
	sprintf(tkDefButtonBorderWidth, "%d", width);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    WinButton *butPtr;
    (void)tkwin;

    butPtr = (WinButton *)ckalloc(sizeof(WinButton));
    butPtr->hwnd = NULL;
    return (TkButton *) butPtr;
}

/*







<







207
208
209
210
211
212
213

214
215
216
217
218
219
220
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    WinButton *butPtr;


    butPtr = (WinButton *)ckalloc(sizeof(WinButton));
    butPtr->hwnd = NULL;
    return (TkButton *) butPtr;
}

/*
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Button instance data. */
{
    Window window;
    HWND parent;
    LPCWSTR windowClass;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);
    if (butPtr->info.type == TYPE_LABEL) {
	windowClass = L"STATIC";
	butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    } else {
	windowClass = L"BUTTON";
	butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    }
    butPtr->hwnd = CreateWindowW(windowClass, NULL, butPtr->style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
		    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    butPtr->oldProc = (WNDPROC)SetWindowLongPtrW(butPtr->hwnd, GWLP_WNDPROC,
	    (LONG_PTR) ButtonProc);

    window = Tk_AttachHWND(tkwin, butPtr->hwnd);
    return window;
}

/*
 *----------------------------------------------------------------------







|




|


|


|




|
|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Button instance data. */
{
    Window window;
    HWND parent;
    char *class;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);
    if (butPtr->info.type == TYPE_LABEL) {
	class = "STATIC";
	butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    } else {
	class = "BUTTON";
	butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    }
    butPtr->hwnd = CreateWindow(class, NULL, butPtr->style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
		    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    butPtr->oldProc = (WNDPROC)SetWindowLongPtr(butPtr->hwnd, GWLP_WNDPROC,
	    (INT_PTR) ButtonProc);

    window = Tk_AttachHWND(tkwin, butPtr->hwnd);
    return window;
}

/*
 *----------------------------------------------------------------------
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
TkpDestroyButton(
    TkButton *butPtr)
{
    WinButton *winButPtr = (WinButton *)butPtr;
    HWND hwnd = winButPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --







|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
TkpDestroyButton(
    TkButton *butPtr)
{
    WinButton *winButPtr = (WinButton *)butPtr;
    HWND hwnd = winButPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winButPtr->oldProc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkWinDCState state;
    HDC dc;
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
    int y, relief;
    Tk_Window tkwin = butPtr->tkwin;
    int width = 0, height = 0, haveImage = 0, haveText = 0, drawRing = 0;
    RECT rect;
    int defaultWidth;		/* Width of default ring. */
    int offset;			/* 0 means this is a label widget. 1 means it
				 * is a flavor of button, so we offset the
				 * text to make the button appear to move up
				 * and down as the relief changes. */







|






|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkWinDCState state;
    HDC dc;
    register TkButton *butPtr = (TkButton *) clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
    int y, relief;
    register Tk_Window tkwin = butPtr->tkwin;
    int width = 0, height = 0, haveImage = 0, haveText = 0, drawRing = 0;
    RECT rect;
    int defaultWidth;		/* Width of default ring. */
    int offset;			/* 0 means this is a label widget. 1 means it
				 * is a flavor of button, so we offset the
				 * text to make the button appear to move up
				 * and down as the relief changes. */
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
	}
    }

    /*
     * Compute width of default ring and offset for pushed buttons.
     */

    if (butPtr->type == TYPE_LABEL) {
	defaultWidth = butPtr->highlightWidth;
        offset = 0;
    } else if (butPtr->type == TYPE_BUTTON) {
	defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE)
		? butPtr->highlightWidth : 0);
	offset = 1;
    } else {
	defaultWidth = 0;
	if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	    offset = 1;







|
<
<
<







401
402
403
404
405
406
407
408



409
410
411
412
413
414
415
	}
    }

    /*
     * Compute width of default ring and offset for pushed buttons.
     */

    if (butPtr->type == TYPE_BUTTON) {



	defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE)
		? butPtr->highlightWidth : 0);
	offset = 1;
    } else {
	defaultWidth = 0;
	if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	    offset = 1;
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
	Tk_Draw3DRectangle(tkwin, pixmap, border,
		defaultWidth, defaultWidth,
		Tk_Width(tkwin) - 2*defaultWidth,
		Tk_Height(tkwin) - 2*defaultWidth,
		butPtr->borderWidth, relief);
    }
    if (defaultWidth != 0) {
        int highlightColor;

	dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
        if (butPtr->type == TYPE_LABEL) {
            highlightColor = (int) Tk_3DBorderColor(butPtr->highlightBorder)->pixel;
        } else {
            highlightColor = (int) butPtr->highlightColorPtr->pixel;
        }
	TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth,
		highlightColor);
	TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin),
		highlightColor);
	TkWinFillRect(dc, 0, Tk_Height(tkwin) - defaultWidth,
		Tk_Width(tkwin), defaultWidth,
		highlightColor);
	TkWinFillRect(dc, Tk_Width(tkwin) - defaultWidth, 0,
		defaultWidth, Tk_Height(tkwin),
		highlightColor);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    if (butPtr->flags & GOT_FOCUS) {
	Tk_SetCaretPos(tkwin, x, y, 0 /* not used */);
    }








<
<

<
<
<
<
<

|

|


|


|







755
756
757
758
759
760
761


762





763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
	Tk_Draw3DRectangle(tkwin, pixmap, border,
		defaultWidth, defaultWidth,
		Tk_Width(tkwin) - 2*defaultWidth,
		Tk_Height(tkwin) - 2*defaultWidth,
		butPtr->borderWidth, relief);
    }
    if (defaultWidth != 0) {


	dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);





	TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth,
		(int) butPtr->highlightColorPtr->pixel);
	TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin),
		(int) butPtr->highlightColorPtr->pixel);
	TkWinFillRect(dc, 0, Tk_Height(tkwin) - defaultWidth,
		Tk_Width(tkwin), defaultWidth,
		(int) butPtr->highlightColorPtr->pixel);
	TkWinFillRect(dc, Tk_Width(tkwin) - defaultWidth, 0,
		defaultWidth, Tk_Height(tkwin),
		(int) butPtr->highlightColorPtr->pixel);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    if (butPtr->flags & GOT_FOCUS) {
	Tk_SetCaretPos(tkwin, x, y, 0 /* not used */);
    }

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    TkButton *butPtr)	/* Button whose geometry may have changed. */
{
    int txtWidth, txtHeight;	/* Width and height of text */
    int imgWidth, imgHeight;	/* Width and height of image */
    int width = 0, height = 0;	/* Width and height of button */
    int haveImage, haveText;
    int avgWidth;
    int minWidth;







|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
 *	The button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeButtonGeometry(
    register TkButton *butPtr)	/* Button whose geometry may have changed. */
{
    int txtWidth, txtHeight;	/* Width and height of text */
    int imgWidth, imgHeight;	/* Width and height of image */
    int width = 0, height = 0;	/* Width and height of button */
    int haveImage, haveText;
    int avgWidth;
    int minWidth;
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319

	    if (butPtr->info.state != STATE_DISABLED) {
		Tcl_Preserve(interp);
		code = TkInvokeButton((TkButton*)butPtr);
		if (code != TCL_OK && code != TCL_CONTINUE
			&& code != TCL_BREAK) {
		    Tcl_AddErrorInfo(interp, "\n    (button invoke)");
		    Tcl_BackgroundException(interp, code);
		}
		Tcl_Release(interp);
	    }
	    Tcl_ServiceAll();
	    return 0;
	}
    }
    /* FALLTHRU */
    default:
	if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return DefWindowProcW(hwnd, message, wParam, lParam);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|









|



|









1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

	    if (butPtr->info.state != STATE_DISABLED) {
		Tcl_Preserve(interp);
		code = TkInvokeButton((TkButton*)butPtr);
		if (code != TCL_OK && code != TCL_CONTINUE
			&& code != TCL_BREAK) {
		    Tcl_AddErrorInfo(interp, "\n    (button invoke)");
		    Tcl_BackgroundError(interp);
		}
		Tcl_Release(interp);
	    }
	    Tcl_ServiceAll();
	    return 0;
	}
    }
    /* FALLTHRU */
    default:
	if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinClipboard.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkSelect.h"
#include <shlobj.h>    /* for DROPFILES */

static void		UpdateClipboard(HWND hwnd);

/*
 *----------------------------------------------------------------------
 *
 * TkSelGetSelection --







<







8
9
10
11
12
13
14

15
16
17
18
19
20
21
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkSelect.h"


static void		UpdateClipboard(HWND hwnd);

/*
 *----------------------------------------------------------------------
 *
 * TkSelGetSelection --
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    char *data, *destPtr;
    Tcl_DString ds;
    HGLOBAL handle;
    Tcl_Encoding encoding;
    int result, locale, noBackslash = 0;

    if (!OpenClipboard(NULL)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "clipboard cannot be opened, another application grabbed it"));
        Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "BUSY", NULL);
        return TCL_ERROR;
    }
    if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
	    || (target != XA_STRING)) {

	goto error;
    }

    /*
     * Attempt to get the data in Unicode form if available as this is less
     * work that CF_TEXT.
     */

    result = TCL_ERROR;
    if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
	handle = GetClipboardData(CF_UNICODETEXT);
	if (!handle) {
	    CloseClipboard();
	    goto error;
	}
	data = (char *)GlobalLock(handle);
	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString((WCHAR *)data, wcslen((WCHAR *)data), &ds);

	GlobalUnlock(handle);
    } else if (IsClipboardFormatAvailable(CF_TEXT)) {
	/*
	 * Determine the encoding to use to convert this text.
	 */

	if (IsClipboardFormatAvailable(CF_LOCALE)) {
	    handle = GetClipboardData(CF_LOCALE);
	    if (!handle) {
		CloseClipboard();
		goto error;
	    }

	    /*
	     * Get the locale identifier, determine the proper code page to
	     * use, and find the corresponding encoding.
	     */

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, "cp######", -1);
	    data = (char *)GlobalLock(handle);

	    /*
	     * Even though the documentation claims that GetLocaleInfo expects
	     * an LCID, on Windows 9x it really seems to expect a LanguageID.
	     */

	    locale = LANGIDFROMLCID(*((int*)data));
	    GetLocaleInfoA(locale, LOCALE_IDEFAULTANSICODEPAGE,
		    Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2);
	    GlobalUnlock(handle);

	    encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	} else {
	    encoding = NULL;







|

<
<
<
<
<
<

|
>















|

|
>




















|







|







48
49
50
51
52
53
54
55
56






57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    char *data, *destPtr;
    Tcl_DString ds;
    HGLOBAL handle;
    Tcl_Encoding encoding;
    int result, locale;







    if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
	    || (target != XA_STRING)
	    || !OpenClipboard(NULL)) {
	goto error;
    }

    /*
     * Attempt to get the data in Unicode form if available as this is less
     * work that CF_TEXT.
     */

    result = TCL_ERROR;
    if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
	handle = GetClipboardData(CF_UNICODETEXT);
	if (!handle) {
	    CloseClipboard();
	    goto error;
	}
	data = GlobalLock(handle);
	Tcl_DStringInit(&ds);
	Tcl_UniCharToUtfDString((Tcl_UniChar *)data,
		Tcl_UniCharLen((Tcl_UniChar *)data), &ds);
	GlobalUnlock(handle);
    } else if (IsClipboardFormatAvailable(CF_TEXT)) {
	/*
	 * Determine the encoding to use to convert this text.
	 */

	if (IsClipboardFormatAvailable(CF_LOCALE)) {
	    handle = GetClipboardData(CF_LOCALE);
	    if (!handle) {
		CloseClipboard();
		goto error;
	    }

	    /*
	     * Get the locale identifier, determine the proper code page to
	     * use, and find the corresponding encoding.
	     */

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, "cp######", -1);
	    data = GlobalLock(handle);

	    /*
	     * Even though the documentation claims that GetLocaleInfo expects
	     * an LCID, on Windows 9x it really seems to expect a LanguageID.
	     */

	    locale = LANGIDFROMLCID(*((int*)data));
	    GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE,
		    Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2);
	    GlobalUnlock(handle);

	    encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	} else {
	    encoding = NULL;
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
	if (!handle) {
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    CloseClipboard();
	    goto error;
	}
	data = (char *)GlobalLock(handle);
	Tcl_ExternalToUtfDString(encoding, data, -1, &ds);
	GlobalUnlock(handle);
	if (encoding) {
	    Tcl_FreeEncoding(encoding);
	}
    } else if (IsClipboardFormatAvailable(CF_HDROP)) {
	DROPFILES *drop;

	handle = GetClipboardData(CF_HDROP);
	if (!handle) {
	    CloseClipboard();
	    goto error;
	}
	Tcl_DStringInit(&ds);
	drop = (DROPFILES *) GlobalLock(handle);
	if (drop->fWide) {
	    WCHAR *fname = (WCHAR *) ((char *) drop + drop->pFiles);
	    Tcl_DString dsTmp;
	    int count = 0;
	    size_t len;

	    while (*fname != 0) {
		if (count) {
		    Tcl_DStringAppend(&ds, "\n", 1);
		}
		len = wcslen(fname);
		Tcl_DStringInit(&dsTmp);
		Tcl_WCharToUtfDString(fname, len, &dsTmp);
		Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsTmp),
			Tcl_DStringLength(&dsTmp));
		Tcl_DStringFree(&dsTmp);
		fname += len + 1;
		count++;
	    }
	    noBackslash = (count > 0);
	}
	GlobalUnlock(handle);
    } else {
	CloseClipboard();
	goto error;
    }

    /*
     * Translate CR/LF to LF.
     */

    data = destPtr = Tcl_DStringValue(&ds);
    while (*data) {
	if (data[0] == '\r' && data[1] == '\n') {
	    data++;
	} else if (noBackslash && data[0] == '\\') {
	    data++;
	    *destPtr++ = '/';
	} else {
	    *destPtr++ = *data++;
	}
    }
    *destPtr = '\0';

    /*
     * Pass the data off to the selection procedure.
     */

    result = proc(clientData, interp, Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);
    CloseClipboard();
    return result;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "%s selection doesn't exist or form \"%s\" not defined",
	    Tk_GetAtomName(tkwin, selection), Tk_GetAtomName(tkwin, target)));
    Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetSelectionOwner --







|





<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













<
<
<










|





|
|
|
<







122
123
124
125
126
127
128
129
130
131
132
133
134


135





























136
137
138
139
140
141
142
143
144
145
146
147
148



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
	if (!handle) {
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    CloseClipboard();
	    goto error;
	}
	data = GlobalLock(handle);
	Tcl_ExternalToUtfDString(encoding, data, -1, &ds);
	GlobalUnlock(handle);
	if (encoding) {
	    Tcl_FreeEncoding(encoding);
	}
































    } else {
	CloseClipboard();
	goto error;
    }

    /*
     * Translate CR/LF to LF.
     */

    data = destPtr = Tcl_DStringValue(&ds);
    while (*data) {
	if (data[0] == '\r' && data[1] == '\n') {
	    data++;



	} else {
	    *destPtr++ = *data++;
	}
    }
    *destPtr = '\0';

    /*
     * Pass the data off to the selection procedure.
     */

    result = (*proc)(clientData, interp, Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);
    CloseClipboard();
    return result;

  error:
    Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
	    " selection doesn't exist or form \"",
	    Tk_GetAtomName(tkwin, target), "\" not defined", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetSelectionOwner --
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    Display *display,
    Atom selection,
    Window owner,
    Time time)
{
    HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
    Tk_Window tkwin;
    (void)display;
    (void)time;

    /*
     * This is a gross hack because the Tk_InternAtom interface is broken. It
     * expects a Tk_Window, even though it only needs a Tk_Display.
     */

    tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;







<
<







190
191
192
193
194
195
196


197
198
199
200
201
202
203
    Display *display,
    Atom selection,
    Window owner,
    Time time)
{
    HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
    Tk_Window tkwin;



    /*
     * This is a gross hack because the Tk_InternAtom interface is broken. It
     * expects a Tk_Window, even though it only needs a Tk_Display.
     */

    tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
{
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;
    HGLOBAL handle;
    char *buffer, *p, *rawText, *endPtr;
    int length;
    Tcl_DString ds;
    (void)format;

    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == XA_STRING) {
	    break;
	}
    }







<







239
240
241
242
243
244
245

246
247
248
249
250
251
252
{
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;
    HGLOBAL handle;
    char *buffer, *p, *rawText, *endPtr;
    int length;
    Tcl_DString ds;


    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == XA_STRING) {
	    break;
	}
    }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334






335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
















350
351
352
353
354
355
356
	}
    }

    /*
     * Copy the data and change EOL characters.
     */

    buffer = rawText = (char *)ckalloc(length + 1);
    if (targetPtr != NULL) {
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = cbPtr->nextPtr) {
	    for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
		    p < endPtr; p++) {
		if (*p == '\n') {
		    *buffer++ = '\r';
		}
		*buffer++ = *p;
	    }
	}
    }
    *buffer = '\0';







	Tcl_DStringInit(&ds);
	Tcl_UtfToWCharDString(rawText, -1, &ds);
	ckfree(rawText);
	handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
		(unsigned) Tcl_DStringLength(&ds) + 2);
	if (!handle) {
	    Tcl_DStringFree(&ds);
	    return;
	}
	buffer = (char *)GlobalLock(handle);
	memcpy(buffer, Tcl_DStringValue(&ds),
		(unsigned) Tcl_DStringLength(&ds) + 2);
	GlobalUnlock(handle);
	Tcl_DStringFree(&ds);
	SetClipboardData(CF_UNICODETEXT, handle);
















}

/*
 *----------------------------------------------------------------------
 *
 * TkSelUpdateClipboard --
 *







|














>
>
>
>
>
>

|







|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
	}
    }

    /*
     * Copy the data and change EOL characters.
     */

    buffer = rawText = ckalloc((unsigned)length + 1);
    if (targetPtr != NULL) {
	for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
		cbPtr = cbPtr->nextPtr) {
	    for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
		    p < endPtr; p++) {
		if (*p == '\n') {
		    *buffer++ = '\r';
		}
		*buffer++ = *p;
	    }
	}
    }
    *buffer = '\0';

    /*
     * Depending on the platform, turn the data into Unicode or the system
     * encoding before placing it on the clipboard.
     */

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	Tcl_DStringInit(&ds);
	Tcl_UtfToUniCharDString(rawText, -1, &ds);
	ckfree(rawText);
	handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
		(unsigned) Tcl_DStringLength(&ds) + 2);
	if (!handle) {
	    Tcl_DStringFree(&ds);
	    return;
	}
	buffer = GlobalLock(handle);
	memcpy(buffer, Tcl_DStringValue(&ds),
		(unsigned) Tcl_DStringLength(&ds) + 2);
	GlobalUnlock(handle);
	Tcl_DStringFree(&ds);
	SetClipboardData(CF_UNICODETEXT, handle);
    } else {
	Tcl_UtfToExternalDString(NULL, rawText, -1, &ds);
	ckfree(rawText);
	handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
		(unsigned) Tcl_DStringLength(&ds) + 1);
	if (!handle) {
	    Tcl_DStringFree(&ds);
	    return;
	}
	buffer = GlobalLock(handle);
	memcpy(buffer, Tcl_DStringValue(&ds),
		(unsigned) Tcl_DStringLength(&ds) + 1);
	GlobalUnlock(handle);
	Tcl_DStringFree(&ds);
	SetClipboardData(CF_TEXT, handle);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkSelUpdateClipboard --
 *
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

void
TkSelUpdateClipboard(
    TkWindow *winPtr,
    TkClipboardTarget *targetPtr)
{
    HWND hwnd = TkWinGetHWND(winPtr->window);
    (void)targetPtr;

    UpdateClipboard(hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateClipboard --







<
<







347
348
349
350
351
352
353


354
355
356
357
358
359
360

void
TkSelUpdateClipboard(
    TkWindow *winPtr,
    TkClipboardTarget *targetPtr)
{
    HWND hwnd = TkWinGetHWND(winPtr->window);


    UpdateClipboard(hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateClipboard --
398
399
400
401
402
403
404






405



406
407
408
409
410
411
412
UpdateClipboard(
    HWND hwnd)
{
    TkWinUpdatingClipboard(TRUE);
    OpenClipboard(hwnd);
    EmptyClipboard();







    SetClipboardData(CF_UNICODETEXT, NULL);



    CloseClipboard();
    TkWinUpdatingClipboard(FALSE);
}

/*
 *--------------------------------------------------------------
 *







>
>
>
>
>
>
|
>
>
>







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
UpdateClipboard(
    HWND hwnd)
{
    TkWinUpdatingClipboard(TRUE);
    OpenClipboard(hwnd);
    EmptyClipboard();

    /*
     * CF_UNICODETEXT is only supported on NT, but it it is prefered when
     * possible.
     */

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	SetClipboardData(CF_UNICODETEXT, NULL);
    } else {
	SetClipboardData(CF_TEXT, NULL);
    }
    CloseClipboard();
    TkWinUpdatingClipboard(FALSE);
}

/*
 *--------------------------------------------------------------
 *
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    if (eventPtr->type == SelectionClear) {
	TkSelClearSelection(tkwin, eventPtr);
    }
}








|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
 *
 *--------------------------------------------------------------
 */

void
TkSelEventProc(
    Tk_Window tkwin,		/* Window for which event was targeted. */
    register XEvent *eventPtr)	/* X event: either SelectionClear,
				 * SelectionRequest, or SelectionNotify. */
{
    if (eventPtr->type == SelectionClear) {
	TkSelClearSelection(tkwin, eventPtr);
    }
}

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    (void)eventPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

<









435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    register XEvent *eventPtr)	/* X PropertyChange event. */
{

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinColor.c.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
 * The sysColors array contains the names and index values for the Windows
 * indirect system color names. In use, all of the names will have the string
 * "System" prepended, but we omit it in the table to save space.
 */

typedef struct {
    const char *name;
    int index;
} SystemColorEntry;

static const SystemColorEntry sysColors[] = {
    {"3dDarkShadow",		COLOR_3DDKSHADOW},
    {"3dLight",			COLOR_3DLIGHT},
    {"ActiveBorder",		COLOR_ACTIVEBORDER},
    {"ActiveCaption",		COLOR_ACTIVECAPTION},
    {"AppWorkspace",		COLOR_APPWORKSPACE},
    {"Background",		COLOR_BACKGROUND},
    {"ButtonFace",		COLOR_BTNFACE},







|



|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
 * The sysColors array contains the names and index values for the Windows
 * indirect system color names. In use, all of the names will have the string
 * "System" prepended, but we omit it in the table to save space.
 */

typedef struct {
    char *name;
    int index;
} SystemColorEntry;

static SystemColorEntry sysColors[] = {
    {"3dDarkShadow",		COLOR_3DDKSHADOW},
    {"3dLight",			COLOR_3DLIGHT},
    {"ActiveBorder",		COLOR_ACTIVEBORDER},
    {"ActiveCaption",		COLOR_ACTIVECAPTION},
    {"AppWorkspace",		COLOR_APPWORKSPACE},
    {"Background",		COLOR_BACKGROUND},
    {"ButtonFace",		COLOR_BTNFACE},
54
55
56
57
58
59
60
61
62
63
64
65

66





67
68
69
70
71
72
73
    {"InactiveBorder",		COLOR_INACTIVEBORDER},
    {"InactiveCaption",		COLOR_INACTIVECAPTION},
    {"InactiveCaptionText",	COLOR_INACTIVECAPTIONTEXT},
    {"InfoBackground",		COLOR_INFOBK},
    {"InfoText",		COLOR_INFOTEXT},
    {"Menu",			COLOR_MENU},
    {"MenuText",		COLOR_MENUTEXT},
    {"PlaceHolderText",		COLOR_GRAYTEXT},
    {"Scrollbar",		COLOR_SCROLLBAR},
    {"Window",			COLOR_WINDOW},
    {"WindowFrame",		COLOR_WINDOWFRAME},
    {"WindowText",		COLOR_WINDOWTEXT}

};






/*
 * Forward declarations for functions defined later in this file.
 */

static int		FindSystemColor(const char *name, XColor *colorPtr,
			    int *indexPtr);







<



|
>

>
>
>
>
>







54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    {"InactiveBorder",		COLOR_INACTIVEBORDER},
    {"InactiveCaption",		COLOR_INACTIVECAPTION},
    {"InactiveCaptionText",	COLOR_INACTIVECAPTIONTEXT},
    {"InfoBackground",		COLOR_INFOBK},
    {"InfoText",		COLOR_INFOTEXT},
    {"Menu",			COLOR_MENU},
    {"MenuText",		COLOR_MENUTEXT},

    {"Scrollbar",		COLOR_SCROLLBAR},
    {"Window",			COLOR_WINDOW},
    {"WindowFrame",		COLOR_WINDOWFRAME},
    {"WindowText",		COLOR_WINDOWTEXT},
    {NULL,			0}
};

typedef struct ThreadSpecificData {
    int ncolors;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined later in this file.
 */

static int		FindSystemColor(const char *name, XColor *colorPtr,
			    int *indexPtr);
93
94
95
96
97
98
99










100













101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
static int
FindSystemColor(
    const char *name,		/* Color name. */
    XColor *colorPtr,		/* Where to store results. */
    int *indexPtr)		/* Out parameter to store color index. */
{
    int l, u, r, i;










    int index;














    /*
     * Perform a binary search on the sorted array of colors.
     */

    l = 0;
    u = (sizeof(sysColors) / sizeof(sysColors[0])) - 1;
    while (l <= u) {
	i = (l + u) / 2;
	r = strcasecmp(name, sysColors[i].name);
	if (r == 0) {
	    break;
	} else if (r < 0) {
	    u = i-1;
	} else {
	    l = i+1;
	}
    }
    if (l > u) {
	return 0;
    }

    *indexPtr = index = sysColors[i].index;
    colorPtr->pixel = GetSysColor(index);

    /*
     * x257 is (value<<8 + value) to get the properly bit shifted and padded
     * value. [Bug: 4919]
     */

    colorPtr->red = GetRValue(colorPtr->pixel) * 257;







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>






|















|
|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
static int
FindSystemColor(
    const char *name,		/* Color name. */
    XColor *colorPtr,		/* Where to store results. */
    int *indexPtr)		/* Out parameter to store color index. */
{
    int l, u, r, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Count the number of elements in the color array if we haven't done so
     * yet.
     */

    if (tsdPtr->ncolors == 0) {
	SystemColorEntry *ePtr;
	int version;

	version = LOBYTE(LOWORD(GetVersion()));
	for (ePtr = sysColors; ePtr->name != NULL; ePtr++) {
	    if (version < 4) {
		if (ePtr->index == COLOR_3DDKSHADOW) {
		    ePtr->index = COLOR_BTNSHADOW;
		} else if (ePtr->index == COLOR_3DLIGHT) {
		    ePtr->index = COLOR_BTNHIGHLIGHT;
		}
	    }
	    tsdPtr->ncolors++;
	}
    }

    /*
     * Perform a binary search on the sorted array of colors.
     */

    l = 0;
    u = tsdPtr->ncolors - 1;
    while (l <= u) {
	i = (l + u) / 2;
	r = strcasecmp(name, sysColors[i].name);
	if (r == 0) {
	    break;
	} else if (r < 0) {
	    u = i-1;
	} else {
	    l = i+1;
	}
    }
    if (l > u) {
	return 0;
    }

    *indexPtr = sysColors[i].index;
    colorPtr->pixel = GetSysColor(sysColors[i].index);

    /*
     * x257 is (value<<8 + value) to get the properly bit shifted and padded
     * value. [Bug: 4919]
     */

    colorPtr->red = GetRValue(colorPtr->pixel) * 257;
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
     * color index.
     */

    if (((strncasecmp(name, "system", 6) == 0)
	    && FindSystemColor(name+6, &color, &index))
	    || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
		    &color)) {
	winColPtr = (WinColor *)ckalloc(sizeof(WinColor));
	winColPtr->info.color = color;
	winColPtr->index = index;

	XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
		&winColPtr->info.color);
 	return (TkColor *) winColPtr;
    }







|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
     * color index.
     */

    if (((strncasecmp(name, "system", 6) == 0)
	    && FindSystemColor(name+6, &color, &index))
	    || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
		    &color)) {
	winColPtr = (WinColor *) ckalloc(sizeof(WinColor));
	winColPtr->info.color = color;
	winColPtr->index = index;

	XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
		&winColPtr->info.color);
 	return (TkColor *) winColPtr;
    }
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

TkColor *
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    WinColor *tkColPtr = (WinColor *)ckalloc(sizeof(WinColor));

    tkColPtr->info.color.red = colorPtr->red;
    tkColPtr->info.color.green = colorPtr->green;
    tkColPtr->info.color.blue = colorPtr->blue;
    tkColPtr->info.color.pixel = 0;
    tkColPtr->index = -1;
    XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), &tkColPtr->info.color);







|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

TkColor *
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    WinColor *tkColPtr = (WinColor *) ckalloc(sizeof(WinColor));

    tkColPtr->info.color.red = colorPtr->red;
    tkColPtr->info.color.green = colorPtr->green;
    tkColPtr->info.color.blue = colorPtr->blue;
    tkColPtr->info.color.pixel = 0;
    tkColPtr->index = -1;
    XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), &tkColPtr->info.color);
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
 *----------------------------------------------------------------------
 */

int
TkWinIndexOfColor(
    XColor *colorPtr)
{
    WinColor *winColPtr = (WinColor *) colorPtr;
    if (winColPtr->info.magic == COLOR_MAGIC) {
	return winColPtr->index;
    }
    return -1;
}

/*







|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
 *----------------------------------------------------------------------
 */

int
TkWinIndexOfColor(
    XColor *colorPtr)
{
    register WinColor *winColPtr = (WinColor *) colorPtr;
    if (winColPtr->info.magic == COLOR_MAGIC) {
	return winColPtr->index;
    }
    return -1;
}

/*
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    Display *display,
    Colormap colormap,
    XColor *color)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    PALETTEENTRY entry, closeEntry;
    HDC dc = GetDC(NULL);
    (void)display;

    entry.peRed = (color->red) >> 8;
    entry.peGreen = (color->green) >> 8;
    entry.peBlue = (color->blue) >> 8;
    entry.peFlags = 0;

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE);
	UINT newPixel, closePixel;
	int isNew;
	size_t refCount;
	Tcl_HashEntry *entryPtr;
	UINT index;

	/*
	 * Find the nearest existing palette entry.
	 */








<









<
|







332
333
334
335
336
337
338

339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
    Display *display,
    Colormap colormap,
    XColor *color)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    PALETTEENTRY entry, closeEntry;
    HDC dc = GetDC(NULL);


    entry.peRed = (color->red) >> 8;
    entry.peGreen = (color->green) >> 8;
    entry.peBlue = (color->blue) >> 8;
    entry.peFlags = 0;

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE);
	UINT newPixel, closePixel;

	int new, refCount;
	Tcl_HashEntry *entryPtr;
	UINT index;

	/*
	 * Find the nearest existing palette entry.
	 */

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	if ((index >= cmap->size) || (newPixel != closePixel)) {
	    if (cmap->size == sizePalette) {
		color->red   = closeEntry.peRed * 257;
		color->green = closeEntry.peGreen * 257;
		color->blue  = closeEntry.peBlue * 257;
		entry = closeEntry;
		if (index >= cmap->size) {
		    OutputDebugStringW(L"XAllocColor: Colormap is bigger than we thought");
		}
	    } else {
		cmap->size++;
		ResizePalette(cmap->palette, cmap->size);
		SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);
	    }
	}

	color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);
	entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,
		INT2PTR(color->pixel), &isNew);
	if (isNew) {
	    refCount = 1;
	} else {
	    refCount = (size_t)Tcl_GetHashValue(entryPtr) + 1;
	}
	Tcl_SetHashValue(entryPtr, INT2PTR(refCount));
    } else {
	/*
	 * Determine what color will actually be used on non-colormap systems.
	 */








|










|
|


|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
	if ((index >= cmap->size) || (newPixel != closePixel)) {
	    if (cmap->size == sizePalette) {
		color->red   = closeEntry.peRed * 257;
		color->green = closeEntry.peGreen * 257;
		color->blue  = closeEntry.peBlue * 257;
		entry = closeEntry;
		if (index >= cmap->size) {
		    OutputDebugString("XAllocColor: Colormap is bigger than we thought");
		}
	    } else {
		cmap->size++;
		ResizePalette(cmap->palette, cmap->size);
		SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);
	    }
	}

	color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);
	entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,
		INT2PTR(color->pixel), &new);
	if (new) {
	    refCount = 1;
	} else {
	    refCount = (PTR2INT(Tcl_GetHashValue(entryPtr))) + 1;
	}
	Tcl_SetHashValue(entryPtr, INT2PTR(refCount));
    } else {
	/*
	 * Determine what color will actually be used on non-colormap systems.
	 */

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
    Colormap colormap,
    unsigned long *pixels,
    int npixels,
    unsigned long planes)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    COLORREF cref;
    UINT count, index;
    size_t refCount;
    int i;
    PALETTEENTRY entry, *entries;
    Tcl_HashEntry *entryPtr;
    HDC dc = GetDC(NULL);
    (void)display;
    (void)planes;

    /*
     * We don't have to do anything for non-palette devices.
     */

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	/*
	 * This is really slow for large values of npixels.
	 */

	for (i = 0; i < npixels; i++) {
	    entryPtr = Tcl_FindHashEntry(&cmap->refCounts, INT2PTR(pixels[i]));
	    if (!entryPtr) {
		Tcl_Panic("Tried to free a color that isn't allocated");
	    }
	    refCount = (size_t)Tcl_GetHashValue(entryPtr) - 1;
	    if (refCount == 0) {
		cref = pixels[i] & 0x00ffffff;
		index = GetNearestPaletteIndex(cmap->palette, cref);
		GetPaletteEntries(cmap->palette, index, 1, &entry);
		if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) {
		    count = cmap->size - index;
		    entries = (PALETTEENTRY *)ckalloc(sizeof(PALETTEENTRY) * count);

		    GetPaletteEntries(cmap->palette, index+1, count, entries);
		    SetPaletteEntries(cmap->palette, index, count, entries);
		    ckfree(entries);
		    cmap->size--;
		} else {
		    Tcl_Panic("Tried to free a color that isn't allocated");
		}
		Tcl_DeleteHashEntry(entryPtr);
	    } else {
		Tcl_SetHashValue(entryPtr, INT2PTR(refCount));
	    }
	}
    }







|
<




<
<













|

|






|
>


|


|







432
433
434
435
436
437
438
439

440
441
442
443


444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    Colormap colormap,
    unsigned long *pixels,
    int npixels,
    unsigned long planes)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    COLORREF cref;
    UINT count, index, refCount;

    int i;
    PALETTEENTRY entry, *entries;
    Tcl_HashEntry *entryPtr;
    HDC dc = GetDC(NULL);



    /*
     * We don't have to do anything for non-palette devices.
     */

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	/*
	 * This is really slow for large values of npixels.
	 */

	for (i = 0; i < npixels; i++) {
	    entryPtr = Tcl_FindHashEntry(&cmap->refCounts, INT2PTR(pixels[i]));
	    if (!entryPtr) {
		Tcl_Panic("Tried to free a color that isn't allocated.");
	    }
	    refCount = PTR2INT(Tcl_GetHashValue(entryPtr)) - 1;
	    if (refCount == 0) {
		cref = pixels[i] & 0x00ffffff;
		index = GetNearestPaletteIndex(cmap->palette, cref);
		GetPaletteEntries(cmap->palette, index, 1, &entry);
		if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) {
		    count = cmap->size - index;
		    entries = (PALETTEENTRY *)
			    ckalloc(sizeof(PALETTEENTRY) * count);
		    GetPaletteEntries(cmap->palette, index+1, count, entries);
		    SetPaletteEntries(cmap->palette, index, count, entries);
		    ckfree((char *) entries);
		    cmap->size--;
		} else {
		    Tcl_Panic("Tried to free a color that isn't allocated.");
		}
		Tcl_DeleteHashEntry(entryPtr);
	    } else {
		Tcl_SetHashValue(entryPtr, INT2PTR(refCount));
	    }
	}
    }
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    int alloc)
{
    char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
    LOGPALETTE *logPalettePtr;
    PALETTEENTRY *entryPtr;
    TkWinColormap *cmap;
    Tcl_HashEntry *hashPtr;
    int isNew;
    UINT i;
    HPALETTE sysPal;
    (void)display;
    (void)w;
    (void)visual;
    (void)alloc;

    /*
     * Allocate a starting palette with all of the reserved colors.
     */

    logPalettePtr = (LOGPALETTE *) logPalBuf;
    logPalettePtr->palVersion = 0x300;
    sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
    logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256,
	    logPalettePtr->palPalEntry);

    cmap = (TkWinColormap *)ckalloc(sizeof(TkWinColormap));
    cmap->size = logPalettePtr->palNumEntries;
    cmap->stale = 0;
    cmap->palette = CreatePalette(logPalettePtr);

    /*
     * Add hash entries for each of the static colors.
     */

    Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
    for (i = 0; i < logPalettePtr->palNumEntries; i++) {
	entryPtr = logPalettePtr->palPalEntry + i;
	hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, INT2PTR(PALETTERGB(
		entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue)), &isNew);
	Tcl_SetHashValue(hashPtr, INT2PTR(1));
    }

    return (Colormap)cmap;
}

/*







|


<
<
<
<











|












|







506
507
508
509
510
511
512
513
514
515




516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
    int alloc)
{
    char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
    LOGPALETTE *logPalettePtr;
    PALETTEENTRY *entryPtr;
    TkWinColormap *cmap;
    Tcl_HashEntry *hashPtr;
    int new;
    UINT i;
    HPALETTE sysPal;





    /*
     * Allocate a starting palette with all of the reserved colors.
     */

    logPalettePtr = (LOGPALETTE *) logPalBuf;
    logPalettePtr->palVersion = 0x300;
    sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
    logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256,
	    logPalettePtr->palPalEntry);

    cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap));
    cmap->size = logPalettePtr->palNumEntries;
    cmap->stale = 0;
    cmap->palette = CreatePalette(logPalettePtr);

    /*
     * Add hash entries for each of the static colors.
     */

    Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
    for (i = 0; i < logPalettePtr->palNumEntries; i++) {
	entryPtr = logPalettePtr->palPalEntry + i;
	hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, INT2PTR(PALETTERGB(
		entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue)), &new);
	Tcl_SetHashValue(hashPtr, INT2PTR(1));
    }

    return (Colormap)cmap;
}

/*
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

int
XFreeColormap(
    Display *display,
    Colormap colormap)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    (void)display;

    if (!DeleteObject(cmap->palette)) {
	Tcl_Panic("Unable to free colormap, palette is still selected");
    }
    Tcl_DeleteHashTable(&cmap->refCounts);
    ckfree(cmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinSelectPalette --







<


|


|







563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582

int
XFreeColormap(
    Display *display,
    Colormap colormap)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;


    if (!DeleteObject(cmap->palette)) {
	Tcl_Panic("Unable to free colormap, palette is still selected.");
    }
    Tcl_DeleteHashTable(&cmap->refCounts);
    ckfree((char *) cmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinSelectPalette --

Changes to win/tkWinConfig.c.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valueObjPtr;
    Tk_Uid classUid;

    if (tkwin == NULL) {
	return NULL;
    }







|
|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    CONST char *dbName,		/* The option database name. */
    CONST char *className)	/* The name of the option class. */
{
    Tcl_Obj *valueObjPtr;
    Tk_Uid classUid;

    if (tkwin == NULL) {
	return NULL;
    }

Changes to win/tkWinCursor.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

/*
 * The table below is used to map from the name of a predefined cursor to its
 * resource identifier.
 */

static struct CursorName {
    const char *name;
    LPCTSTR id;
} cursorNames[] = {
    {"starting",		IDC_APPSTARTING},
    {"arrow",			IDC_ARROW},
    {"ibeam",			IDC_IBEAM},
    {"icon",			IDC_ICON},
    {"no",			IDC_NO},







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

/*
 * The table below is used to map from the name of a predefined cursor to its
 * resource identifier.
 */

static struct CursorName {
    char *name;
    LPCTSTR id;
} cursorNames[] = {
    {"starting",		IDC_APPSTARTING},
    {"arrow",			IDC_ARROW},
    {"ibeam",			IDC_IBEAM},
    {"icon",			IDC_ICON},
    {"no",			IDC_NO},
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
    {NULL,			0}
};

/*
 * The default cursor is used whenever no other cursor has been specified.
 */

#define TK_DEFAULT_CURSOR	(LPCWSTR)IDC_ARROW


/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *
 *	Retrieve a system cursor by name.







|
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    {NULL,			0}
};

/*
 * The default cursor is used whenever no other cursor has been specified.
 */

#define TK_DEFAULT_CURSOR	IDC_ARROW


/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *
 *	Retrieve a system cursor by name.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    struct CursorName *namePtr;
    TkWinCursor *cursorPtr;
    int argc;
    const char **argv = NULL;
    (void)tkwin;

    /*
     * All cursor names are valid lists of one element (for
     * Unix-compatability), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badCursorSpec;
    }

    cursorPtr = (TkWinCursor *)ckalloc(sizeof(TkWinCursor));
    cursorPtr->info.cursor = (Tk_Cursor) cursorPtr;
    cursorPtr->winCursor = NULL;
    cursorPtr->system = 0;

    if (argv[0][0] == '@') {
	/*
	 * Check for system cursor of type @<filename>, where only the name is
	 * allowed. This accepts any of:
	 *	-cursor @/winnt/cursors/globe.ani
	 *	-cursor @C:/Winnt/cursors/E_arrow.cur
	 *	-cursor {@C:/Program\ Files/Cursors/bart.ani}
	 *      -cursor {{@C:/Program Files/Cursors/bart.ani}}
	 *	-cursor [list @[file join "C:/Program Files" Cursors bart.ani]]
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter",-1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    ckfree(argv);
	    ckfree(cursorPtr);
	    return NULL;
	}
	cursorPtr->winCursor = LoadCursorFromFileA(&(argv[0][1]));
    } else {
	/*
	 * Check for the cursor in the system cursor set.
	 */

	for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) {
	    if (strcmp(namePtr->name, argv[0]) == 0) {
		cursorPtr->winCursor = LoadCursorW(NULL, (LPCWSTR) namePtr->id);
		break;
	    }
	}

	if (cursorPtr->winCursor == NULL) {
	    /*
	     * Hmm, it is not in the system cursor set. Check to see if it is
	     * one of our application resources.
	     */

	    cursorPtr->winCursor = LoadCursorA(Tk_GetHINSTANCE(), argv[0]);
	} else {
	    cursorPtr->system = 1;
	}
    }

    if (cursorPtr->winCursor == NULL) {
	ckfree(cursorPtr);
    badCursorSpec:
	ckfree(argv);
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad cursor spec \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL);
	return NULL;
    }
    ckfree(argv);
    return (TkCursor *) cursorPtr;

}

/*
 *----------------------------------------------------------------------
 *
 * TkCreateCursorFromData --
 *







|
<



|









|
















|
|
<
|
|


|







|










|






|

|
<
|
<

|
|
|
>







96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169

170
171
172
173
174
175
176
177
178
179
180
181
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    struct CursorName *namePtr;
    TkWinCursor *cursorPtr;
    int argc;
    CONST char **argv = NULL;


    /*
     * All cursor names are valid lists of one element (for
     * Unix-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badCursorSpec;
    }

    cursorPtr = (TkWinCursor *) ckalloc(sizeof(TkWinCursor));
    cursorPtr->info.cursor = (Tk_Cursor) cursorPtr;
    cursorPtr->winCursor = NULL;
    cursorPtr->system = 0;

    if (argv[0][0] == '@') {
	/*
	 * Check for system cursor of type @<filename>, where only the name is
	 * allowed. This accepts any of:
	 *	-cursor @/winnt/cursors/globe.ani
	 *	-cursor @C:/Winnt/cursors/E_arrow.cur
	 *	-cursor {@C:/Program\ Files/Cursors/bart.ani}
	 *      -cursor {{@C:/Program Files/Cursors/bart.ani}}
	 *	-cursor [list @[file join "C:/Program Files" Cursors bart.ani]]
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_AppendResult(interp, "can't get cursor from a file in",
		    " a safe interpreter", NULL);

	    ckfree((char *) argv);
	    ckfree((char *) cursorPtr);
	    return NULL;
	}
	cursorPtr->winCursor = LoadCursorFromFile(&(argv[0][1]));
    } else {
	/*
	 * Check for the cursor in the system cursor set.
	 */

	for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) {
	    if (strcmp(namePtr->name, argv[0]) == 0) {
		cursorPtr->winCursor = LoadCursor(NULL, namePtr->id);
		break;
	    }
	}

	if (cursorPtr->winCursor == NULL) {
	    /*
	     * Hmm, it is not in the system cursor set. Check to see if it is
	     * one of our application resources.
	     */

	    cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), argv[0]);
	} else {
	    cursorPtr->system = 1;
	}
    }

    if (cursorPtr->winCursor == NULL) {
	ckfree((char *) cursorPtr);
    badCursorSpec:
	ckfree((char *) argv);

	Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL);

	return NULL;
    } else {
	ckfree((char *) argv);
	return (TkCursor *) cursorPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkCreateCursorFromData --
 *
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    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. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{
    (void)tkwin;
    (void)source;
    (void)mask;
    (void)width;
    (void)height;
    (void)xHot;
    (void)yHot;
    (void)fgColor;
    (void)bgColor;

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeCursor --







|
|





<
<
<
<
<
<
<
<
<
<







189
190
191
192
193
194
195
196
197
198
199
200
201
202










203
204
205
206
207
208
209
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    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. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{










    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeCursor --
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
 *----------------------------------------------------------------------
 */

void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    (void)cursorPtr;

    /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCursor --







<
<







220
221
222
223
224
225
226


227
228
229
230
231
232
233
 *----------------------------------------------------------------------
 */

void
TkpFreeCursor(
    TkCursor *cursorPtr)
{


    /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCursor --
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
TkpSetCursor(
    TkpCursor cursor)
{
    HCURSOR hcursor;
    TkWinCursor *winCursor = (TkWinCursor *) cursor;

    if (winCursor == NULL || winCursor->winCursor == NULL) {
	hcursor = LoadCursorW(NULL, TK_DEFAULT_CURSOR);
    } else {
	hcursor = winCursor->winCursor;
    }

    if (hcursor != NULL) {
	SetCursor(hcursor);
    }







|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
TkpSetCursor(
    TkpCursor cursor)
{
    HCURSOR hcursor;
    TkWinCursor *winCursor = (TkWinCursor *) cursor;

    if (winCursor == NULL || winCursor->winCursor == NULL) {
	hcursor = LoadCursor(NULL, TK_DEFAULT_CURSOR);
    } else {
	hcursor = winCursor->winCursor;
    }

    if (hcursor != NULL) {
	SetCursor(hcursor);
    }

Changes to win/tkWinDefault.h.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		HIGHLIGHT
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_OVER_RELIEF		""
#define DEF_BUTTON_PADX			"1"
#define DEF_LABCHKRAD_PADX		"1"
#define DEF_BUTTON_PADY			"1"
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"raised"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"







|















|


|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		HIGHLIGHT
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		(char *) NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_OVER_RELIEF		""
#define DEF_BUTTON_PADX			"1"
#define DEF_LABCHKRAD_PADX		"1"
#define DEF_BUTTON_PADY			"1"
#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"raised"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		(char *) NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		(char *) NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	SELECT_FG
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		NULL
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#define DEF_CANVAS_SCROLL_REGION	""
#define DEF_CANVAS_SELECT_COLOR		SELECT_BG
#define DEF_CANVAS_SELECT_MONO		BLACK
#define DEF_CANVAS_SELECT_BD_COLOR	"1"
#define DEF_CANVAS_SELECT_BD_MONO	"0"
#define DEF_CANVAS_SELECT_FG_COLOR	SELECT_FG
#define DEF_CANVAS_SELECT_FG_MONO	WHITE
#define DEF_CANVAS_TAKE_FOCUS		(char *) NULL
#define DEF_CANVAS_WIDTH		"10c"
#define DEF_CANVAS_X_SCROLL_CMD		""
#define DEF_CANVAS_X_SCROLL_INCREMENT	"0"
#define DEF_CANVAS_Y_SCROLL_CMD		""
#define DEF_CANVAS_Y_SCROLL_INCREMENT	"0"

/*
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#define DEF_ENTRY_INSERT_BG		TEXT_FG
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"2"
#define DEF_ENTRY_JUSTIFY		"left"
#define DEF_ENTRY_PLACEHOLDER		""
#define DEF_ENTRY_PLACEHOLDERFG		"SystemPlaceHolderText"
#define DEF_ENTRY_READONLY_BG_COLOR	"SystemButtonFace"
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"
#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"0"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	SELECT_FG
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			NULL
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		NULL
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG
#define DEF_FRAME_BG_IMAGE		NULL
#define DEF_FRAME_BG_MONO		WHITE
#define DEF_FRAME_BG_TILE		"0"
#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG







<
<










|

|








<

<







153
154
155
156
157
158
159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181

182
183
184
185
186
187
188
#define DEF_ENTRY_INSERT_BG		TEXT_FG
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"2"
#define DEF_ENTRY_JUSTIFY		"left"


#define DEF_ENTRY_READONLY_BG_COLOR	"SystemButtonFace"
#define DEF_ENTRY_READONLY_BG_MONO	WHITE
#define DEF_ENTRY_RELIEF		"sunken"
#define DEF_ENTRY_SCROLL_COMMAND	""
#define DEF_ENTRY_SELECT_COLOR		SELECT_BG
#define DEF_ENTRY_SELECT_MONO		BLACK
#define DEF_ENTRY_SELECT_BD_COLOR	"0"
#define DEF_ENTRY_SELECT_BD_MONO	"0"
#define DEF_ENTRY_SELECT_FG_COLOR	SELECT_FG
#define DEF_ENTRY_SELECT_FG_MONO	WHITE
#define DEF_ENTRY_SHOW			(char *) NULL
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		(char *) NULL
#define DEF_ENTRY_TEXT_VARIABLE		""
#define DEF_ENTRY_WIDTH			"20"

/*
 * Defaults for frames:
 */

#define DEF_FRAME_BG_COLOR		NORMAL_BG

#define DEF_FRAME_BG_MONO		WHITE

#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkDefaultFont"
#define DEF_LISTBOX_FG			NORMAL_FG
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		HIGHLIGHT
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"
#define DEF_LISTBOX_JUSTIFY		"left"
#define DEF_LISTBOX_RELIEF		"sunken"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		NULL
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	NULL
#define DEF_MENU_ENTRY_ACTIVE_FG	NULL
#define DEF_MENU_ENTRY_ACCELERATOR	NULL
#define DEF_MENU_ENTRY_BG		NULL
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		NULL
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		NULL
#define DEF_MENU_ENTRY_FONT		NULL
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		NULL
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		NULL
#define DEF_MENU_ENTRY_MENU		NULL
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	SELECT_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	SELECT_FG
#define DEF_MENU_ACTIVE_FG_MONO		WHITE
#define DEF_MENU_ACTIVE_RELIEF		"flat"
#define DEF_MENU_BG_COLOR		MENU_BG
#define DEF_MENU_BG_MONO		WHITE
#define DEF_MENU_BORDER_WIDTH		"0"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"TkMenuFont"
#define DEF_MENU_FG			MENU_FG
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		MENU_FG
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_TAKE_FOCUS		"0"
#define DEF_MENU_TEAROFF		"0"
#define DEF_MENU_TEAROFF_CMD		NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */








<











|






|
|
|
|


|

|
|

|

|
|


|

|
|

|











<













|
|







220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkDefaultFont"
#define DEF_LISTBOX_FG			NORMAL_FG
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		HIGHLIGHT
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"

#define DEF_LISTBOX_RELIEF		"sunken"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
#define DEF_LISTBOX_SELECT_BD		"0"
#define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG
#define DEF_LISTBOX_SELECT_FG_MONO	WHITE
#define DEF_LISTBOX_SELECT_MODE		"browse"
#define DEF_LISTBOX_SET_GRID		"0"
#define DEF_LISTBOX_STATE		"normal"
#define DEF_LISTBOX_TAKE_FOCUS		(char *) NULL
#define DEF_LISTBOX_WIDTH		"20"

/*
 * Defaults for individual entries of menus:
 */

#define DEF_MENU_ENTRY_ACTIVE_BG	(char *) NULL
#define DEF_MENU_ENTRY_ACTIVE_FG	(char *) NULL
#define DEF_MENU_ENTRY_ACCELERATOR	(char *) NULL
#define DEF_MENU_ENTRY_BG		(char *) NULL
#define DEF_MENU_ENTRY_BITMAP		NULL
#define DEF_MENU_ENTRY_COLUMN_BREAK	"0"
#define DEF_MENU_ENTRY_COMMAND		(char *) NULL
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		(char *) NULL
#define DEF_MENU_ENTRY_FONT		(char *) NULL
#define DEF_MENU_ENTRY_HIDE_MARGIN	"0"
#define DEF_MENU_ENTRY_IMAGE		(char *) NULL
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		(char *) NULL
#define DEF_MENU_ENTRY_MENU		(char *) NULL
#define DEF_MENU_ENTRY_OFF_VALUE	"0"
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	(char *) NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		(char *) NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	(char *) NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT	(char *) NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	SELECT_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	SELECT_FG
#define DEF_MENU_ACTIVE_FG_MONO		WHITE

#define DEF_MENU_BG_COLOR		MENU_BG
#define DEF_MENU_BG_MONO		WHITE
#define DEF_MENU_BORDER_WIDTH		"0"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"TkMenuFont"
#define DEF_MENU_FG			MENU_FG
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		MENU_FG
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_TAKE_FOCUS		"0"
#define DEF_MENU_TEAROFF		"1"
#define DEF_MENU_TEAROFF_CMD		(char *) NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*
 * Defaults for menubuttons:
 */

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	HIGHLIGHT
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"0"
#define DEF_MENUBUTTON_JUSTIFY		"center"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"







|







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	HIGHLIGHT
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		(char *) NULL
#define DEF_MENUBUTTON_INDICATOR	"0"
#define DEF_MENUBUTTON_JUSTIFY		"center"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		HIGHLIGHT
#define DEF_SCALE_HIGHLIGHT_WIDTH	"2"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:







|








|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		HIGHLIGHT
#define DEF_SCALE_HIGHLIGHT_WIDTH	"2"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		(char *) NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
#define DEF_SCROLLBAR_HIGHLIGHT	HIGHLIGHT
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"sunken"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	NULL
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"10"

/*
 * Defaults for texts:
 */







|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
#define DEF_SCROLLBAR_HIGHLIGHT	HIGHLIGHT
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"sunken"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	(char *) NULL
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"10"

/*
 * Defaults for texts:
 */
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
#define DEF_TEXT_HIGHLIGHT		HIGHLIGHT
#define DEF_TEXT_HIGHLIGHT_WIDTH	"0"
#define DEF_TEXT_INSERT_BG		TEXT_FG
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	NULL
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		NULL
#define DEF_TEXT_UNDO			"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"

/*
 * Defaults for canvas items
 * (arcs, bitmaps, lines, polygons, rectangles, and ovals):
 */

#define DEF_CANVBMAP_FG			NORMAL_FG
#define DEF_CANVITEM_OUTLINE		NORMAL_FG

/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""

/*
 * Defaults for busy windows:
 */

#define DEF_BUSY_CURSOR			"wait"

#endif /* _TKWINDEFAULT */







<

|


















|
|











<
<
<
<
<
<
<
<










<
<
<
<
<
<

478
479
480
481
482
483
484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517








518
519
520
521
522
523
524
525
526
527






528
#define DEF_TEXT_HIGHLIGHT		HIGHLIGHT
#define DEF_TEXT_HIGHLIGHT_WIDTH	"0"
#define DEF_TEXT_INSERT_BG		TEXT_FG
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"

#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO    	"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	NULL
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"
#define DEF_TEXT_SET_GRID		"0"
#define DEF_TEXT_SPACING1		"0"
#define DEF_TEXT_SPACING2		"0"
#define DEF_TEXT_SPACING3		"0"
#define DEF_TEXT_STATE			"normal"
#define DEF_TEXT_TABS			""
#define DEF_TEXT_TABSTYLE		"tabular"
#define DEF_TEXT_TAKE_FOCUS		(char *) NULL
#define DEF_TEXT_UNDO    		"0"
#define DEF_TEXT_WIDTH			"80"
#define DEF_TEXT_WRAP			"char"
#define DEF_TEXT_XSCROLL_COMMAND	""
#define DEF_TEXT_YSCROLL_COMMAND	""

/*
 * Defaults for canvas text:
 */

#define DEF_CANVTEXT_FONT		"TkDefaultFont"









/*
 * Defaults for toplevels (most of the defaults for frames also apply
 * to toplevels):
 */

#define DEF_TOPLEVEL_CLASS		"Toplevel"
#define DEF_TOPLEVEL_MENU		""
#define DEF_TOPLEVEL_SCREEN		""
#define DEF_TOPLEVEL_USE		""







#endif /* _TKWINDEFAULT */

Changes to win/tkWinDialog.c.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44



45
46




47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * tkWinDialog.c --
 *
 *	Contains the Windows implementation of the common dialog boxes.
 *
 * 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.
 */


#include "tkWinInt.h"
#include "tkFileFilter.h"
#include "tkFont.h"

#include <commdlg.h>		/* includes common dialog functionality */



#include <dlgs.h>		/* includes common dialog template defines */
#include <cderr.h>		/* includes the common dialog error codes */

#include <shlobj.h>		/* includes SHBrowseForFolder */

#ifdef _MSC_VER
#   pragma comment (lib, "shell32.lib")
#   pragma comment (lib, "comdlg32.lib")
#   pragma comment (lib, "uuid.lib")
#endif

/* These needed for compilation with VC++ 5.2 */
/* XXX - remove these since need at least VC 6 */
#ifndef BIF_EDITBOX
#define BIF_EDITBOX 0x10
#endif

#ifndef BIF_VALIDATE
#define BIF_VALIDATE 0x0020
#endif

/* This "new" dialog style is now actually the "old" dialog style post-Vista */
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif

#ifndef BFFM_VALIDATEFAILEDW

#define BFFM_VALIDATEFAILEDW 4



#endif /* BFFM_VALIDATEFAILEDW */





typedef struct {
    int debugFlag;		/* Flags whether we should output debugging
				 * information while displaying a builtin
				 * dialog. */
    Tcl_Interp *debugInterp;	/* Interpreter to used for debugging. */
    UINT WM_LBSELCHANGED;	/* Holds a registered windows event used for
				 * communicating between the Directory Chooser
				 * dialog and its hook proc. */
    HHOOK hMsgBoxHook;		/* Hook proc for tk_messageBox and the */
    HICON hSmallIcon;		/* icons used by a parent to be used in */
    HICON hBigIcon;		/* the message box */
    int   newFileDialogsState;
#define FDLG_STATE_INIT 0       /* Uninitialized */
#define FDLG_STATE_USE_NEW 1    /* Use the new dialogs */
#define FDLG_STATE_USE_OLD 2    /* Use the old dialogs */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structures are used by Tk_MessageBoxCmd() to parse arguments
 * and return results.
 */










|
>


<


>
>
>




<


<
<



<








<




|
>
|
>
>
>
|

>
>
>
>
|










<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23

24
25


26
27
28

29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63




64
65
66
67
68
69
70
/*
 * tkWinDialog.c --
 *
 *	Contains the Windows implementation of the common dialog boxes.
 *
 * 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.
 */
#define WINVER        0x0500   /* Requires Windows 2K definitions */
#define _WIN32_WINNT  0x0500
#include "tkWinInt.h"
#include "tkFileFilter.h"


#include <commdlg.h>		/* includes common dialog functionality */
#ifdef _MSC_VER
#   pragma comment (lib, "comdlg32.lib")
#endif
#include <dlgs.h>		/* includes common dialog template defines */
#include <cderr.h>		/* includes the common dialog error codes */

#include <shlobj.h>		/* includes SHBrowseForFolder */

#ifdef _MSC_VER
#   pragma comment (lib, "shell32.lib")


#endif

/* These needed for compilation with VC++ 5.2 */

#ifndef BIF_EDITBOX
#define BIF_EDITBOX 0x10
#endif

#ifndef BIF_VALIDATE
#define BIF_VALIDATE 0x0020
#endif


#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif

#ifndef BFFM_VALIDATEFAILED
#ifdef UNICODE
#define BFFM_VALIDATEFAILED 4
#else
#define BFFM_VALIDATEFAILED 3
#endif
#endif /* BFFM_VALIDATEFAILED */

#ifndef OPENFILENAME_SIZE_VERSION_400
#define OPENFILENAME_SIZE_VERSION_400 76
#endif

typedef struct ThreadSpecificData {
    int debugFlag;		/* Flags whether we should output debugging
				 * information while displaying a builtin
				 * dialog. */
    Tcl_Interp *debugInterp;	/* Interpreter to used for debugging. */
    UINT WM_LBSELCHANGED;	/* Holds a registered windows event used for
				 * communicating between the Directory Chooser
				 * dialog and its hook proc. */
    HHOOK hMsgBoxHook;		/* Hook proc for tk_messageBox and the */
    HICON hSmallIcon;		/* icons used by a parent to be used in */
    HICON hBigIcon;		/* the message box */




} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structures are used by Tk_MessageBoxCmd() to parse arguments
 * and return results.
 */
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694



695
696
697
698
699
700
701
702
				 * for setting the "tk_dialog" variable. */
    int dynFileBufferSize;	/* Dynamic filename buffer size, stored to
				 * avoid shrinking and expanding the buffer
				 * when selection changes */
    WCHAR *dynFileBuffer;	/* Dynamic filename buffer */
} OFNData;

/*
 * The following structure is used to gather options used by various
 * file dialogs
 */
typedef struct OFNOpts {
    Tk_Window tkwin;            /* Owner window for dialog */
    Tcl_Obj *extObj;            /* Default extension */
    Tcl_Obj *titleObj;          /* Title for dialog */
    Tcl_Obj *filterObj;         /* File type filter list */
    Tcl_Obj *typeVariableObj;   /* Variable in which to store type selected */
    Tcl_Obj *initialTypeObj;    /* Initial value of above, or NULL */
    Tcl_DString utfDirString;   /* Initial dir */
    int multi;                  /* Multiple selection enabled */
    int confirmOverwrite;       /* Confirm before overwriting */
    int mustExist;              /* Used only for  */
    int forceXPStyle;          /* XXX - Force XP style even on newer systems */
    WCHAR file[TK_MULTI_MAX_PATH]; /* File name
                                      XXX - fixed size because it was so
                                      historically. Why not malloc'ed ?
                                   */
} OFNOpts;

/* Define the operation for which option parsing is to be done. */
enum OFNOper {
    OFN_FILE_SAVE,              /* tk_getOpenFile */
    OFN_FILE_OPEN,              /* tk_getSaveFile */
    OFN_DIR_CHOOSE              /* tk_chooseDirectory */
};


/*
 * The following definitions are required when using older versions of
 * Visual C++ (like 6.0) and possibly MingW. Those headers do not contain
 * required definitions for interfaces new to Vista that we need for
 * the new file dialogs. Duplicating definitions is OK because they
 * should forever remain unchanged.
 *
 * XXX - is there a better/easier way to use new data definitions with
 * older compilers? Should we prefix definitions with Tcl_ instead
 * of using the same names as in the SDK?
 */
#ifndef __IShellItem_INTERFACE_DEFINED__
#  define __IShellItem_INTERFACE_DEFINED__
#ifdef __MSVCRT__
typedef struct IShellItem IShellItem;

typedef enum __MIDL_IShellItem_0001 {
    SIGDN_NORMALDISPLAY = 0,SIGDN_PARENTRELATIVEPARSING = 0x80018001,SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
    SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,SIGDN_PARENTRELATIVEEDITING = 0x80031001,SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
    SIGDN_FILESYSPATH = 0x80058000,SIGDN_URL = 0x80068000
} SIGDN;

typedef DWORD SICHINTF;

typedef struct IShellItemVtbl
{
    BEGIN_INTERFACE

    HRESULT (STDMETHODCALLTYPE *QueryInterface)(IShellItem *, REFIID, void **);
    ULONG (STDMETHODCALLTYPE *AddRef)(IShellItem *);
    ULONG (STDMETHODCALLTYPE *Release)(IShellItem *);
    HRESULT (STDMETHODCALLTYPE *BindToHandler)(IShellItem *, IBindCtx *, REFGUID, REFIID, void **);
    HRESULT (STDMETHODCALLTYPE *GetParent)(IShellItem *, IShellItem **);
    HRESULT (STDMETHODCALLTYPE *GetDisplayName)(IShellItem *, SIGDN, LPOLESTR *);
    HRESULT (STDMETHODCALLTYPE *GetAttributes)(IShellItem *, SFGAOF, SFGAOF *);
    HRESULT (STDMETHODCALLTYPE *Compare)(IShellItem *, IShellItem *, SICHINTF, int *);

    END_INTERFACE
} IShellItemVtbl;
struct IShellItem {
    CONST_VTBL struct IShellItemVtbl *lpVtbl;
};
#endif
#endif

#ifndef __IShellItemArray_INTERFACE_DEFINED__
#define __IShellItemArray_INTERFACE_DEFINED__

typedef enum SIATTRIBFLAGS {
    SIATTRIBFLAGS_AND	= 0x1,
    SIATTRIBFLAGS_OR	= 0x2,
    SIATTRIBFLAGS_APPCOMPAT	= 0x3,
    SIATTRIBFLAGS_MASK	= 0x3,
    SIATTRIBFLAGS_ALLITEMS	= 0x4000
} SIATTRIBFLAGS;
#ifdef __MSVCRT__
typedef ULONG SFGAOF;
#endif /* __MSVCRT__ */
typedef struct IShellItemArray IShellItemArray;
typedef struct IShellItemArrayVtbl
{
    BEGIN_INTERFACE

    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
        IShellItemArray *, REFIID riid,void **ppvObject);
    ULONG ( STDMETHODCALLTYPE *AddRef )(IShellItemArray *);
    ULONG ( STDMETHODCALLTYPE *Release )(IShellItemArray *);
    HRESULT ( STDMETHODCALLTYPE *BindToHandler )(IShellItemArray *,
        IBindCtx *, REFGUID, REFIID, void **);
    /* flags is actually is enum GETPROPERTYSTOREFLAGS */
    HRESULT ( STDMETHODCALLTYPE *GetPropertyStore )(
        IShellItemArray *, int,  REFIID, void **);
    /* keyType actually REFPROPERTYKEY */
    HRESULT ( STDMETHODCALLTYPE *GetPropertyDescriptionList )(
         IShellItemArray *, void *, REFIID, void **);
    HRESULT ( STDMETHODCALLTYPE *GetAttributes )(IShellItemArray *,
        SIATTRIBFLAGS, SFGAOF, SFGAOF *);
    HRESULT ( STDMETHODCALLTYPE *GetCount )(
        IShellItemArray *, DWORD *);
    HRESULT ( STDMETHODCALLTYPE *GetItemAt )(
        IShellItemArray *, DWORD, IShellItem **);
    /* ppenumShellItems actually (IEnumShellItems **) */
    HRESULT ( STDMETHODCALLTYPE *EnumItems )(
        IShellItemArray *, void **);

    END_INTERFACE
} IShellItemArrayVtbl;

struct IShellItemArray {
    CONST_VTBL struct IShellItemArrayVtbl *lpVtbl;
};

#endif /* __IShellItemArray_INTERFACE_DEFINED__ */

/*
 * Older compilers do not define these CLSIDs so we do so here under
 * a slightly different name so as to not clash with the definitions
 * in new compilers
 */
static const CLSID ClsidFileOpenDialog = {
    0xDC1C5A9C, 0xE88A, 0X4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}
};
static const CLSID ClsidFileSaveDialog = {
    0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}
};
static const IID IIDIFileOpenDialog = {
    0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}
};
static const IID IIDIFileSaveDialog = {
    0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}
};
static const IID IIDIShellItem = {
	0x43826D1E, 0xE718, 0x42EE, {0xBC, 0x55, 0xA1, 0xE2, 0x61, 0xC3, 0x7B, 0xFE}
};

#ifdef __IFileDialog_INTERFACE_DEFINED__
# define TCLCOMDLG_FILTERSPEC COMDLG_FILTERSPEC
#else

/* Forward declarations for structs that are referenced but not used */
typedef struct IPropertyStore IPropertyStore;
typedef struct IPropertyDescriptionList IPropertyDescriptionList;
typedef struct IFileOperationProgressSink IFileOperationProgressSink;
typedef enum FDAP {
    FDAP_BOTTOM	= 0,
    FDAP_TOP	= 1
} FDAP;

typedef struct {
    LPCWSTR pszName;
    LPCWSTR pszSpec;
} TCLCOMDLG_FILTERSPEC;

enum _FILEOPENDIALOGOPTIONS {
    FOS_OVERWRITEPROMPT	= 0x2,
    FOS_STRICTFILETYPES	= 0x4,
    FOS_NOCHANGEDIR	= 0x8,
    FOS_PICKFOLDERS	= 0x20,
    FOS_FORCEFILESYSTEM	= 0x40,
    FOS_ALLNONSTORAGEITEMS	= 0x80,
    FOS_NOVALIDATE	= 0x100,
    FOS_ALLOWMULTISELECT	= 0x200,
    FOS_PATHMUSTEXIST	= 0x800,
    FOS_FILEMUSTEXIST	= 0x1000,
    FOS_CREATEPROMPT	= 0x2000,
    FOS_SHAREAWARE	= 0x4000,
    FOS_NOREADONLYRETURN	= 0x8000,
    FOS_NOTESTFILECREATE	= 0x10000,
    FOS_HIDEMRUPLACES	= 0x20000,
    FOS_HIDEPINNEDPLACES	= 0x40000,
    FOS_NODEREFERENCELINKS	= 0x100000,
    FOS_DONTADDTORECENT	= 0x2000000,
    FOS_FORCESHOWHIDDEN	= 0x10000000,
    FOS_DEFAULTNOMINIMODE	= 0x20000000,
    FOS_FORCEPREVIEWPANEON	= 0x40000000
} ;
typedef DWORD FILEOPENDIALOGOPTIONS;

typedef struct IFileDialog IFileDialog;
typedef struct IFileDialogVtbl
{
    BEGIN_INTERFACE

    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
         IFileDialog *, REFIID, void **);
    ULONG ( STDMETHODCALLTYPE *AddRef )( IFileDialog *);
    ULONG ( STDMETHODCALLTYPE *Release )( IFileDialog *);
    HRESULT ( STDMETHODCALLTYPE *Show )( IFileDialog *, HWND);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileDialog *,
        UINT, const TCLCOMDLG_FILTERSPEC *);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )(IFileDialog *, UINT);
    HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )(IFileDialog *, UINT *);
    /* XXX - Actually pfde is IFileDialogEvents* but we do not use
       this call and do not want to define IFileDialogEvents as that
       pulls in a whole bunch of other stuff. */
    HRESULT ( STDMETHODCALLTYPE *Advise )(
        IFileDialog *, void *, DWORD *);
    HRESULT ( STDMETHODCALLTYPE *Unadvise )(IFileDialog *, DWORD);
    HRESULT ( STDMETHODCALLTYPE *SetOptions )(
        IFileDialog *, FILEOPENDIALOGOPTIONS);
    HRESULT ( STDMETHODCALLTYPE *GetOptions )(
        IFileDialog *, FILEOPENDIALOGOPTIONS *);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )(
        IFileDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *SetFolder )(
        IFileDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *GetFolder )(
        IFileDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )(
        IFileDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *SetFileName )(
        IFileDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetFileName )(
        IFileDialog *,  LPWSTR *);
    HRESULT ( STDMETHODCALLTYPE *SetTitle )(
        IFileDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )(
        IFileDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )(
        IFileDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetResult )(
        IFileDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *AddPlace )(
        IFileDialog *, IShellItem *, FDAP);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )(
         IFileDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *Close )( IFileDialog *, HRESULT);
    HRESULT ( STDMETHODCALLTYPE *SetClientGuid )(
        IFileDialog *, REFGUID);
    HRESULT ( STDMETHODCALLTYPE *ClearClientData )( IFileDialog *);
    /* pFilter actually IShellItemFilter. But deprecated in Win7 AND we do
       not use it anyways. So define as void* */
    HRESULT ( STDMETHODCALLTYPE *SetFilter )(
         IFileDialog *, void *);

    END_INTERFACE
} IFileDialogVtbl;

struct IFileDialog {
    CONST_VTBL struct IFileDialogVtbl *lpVtbl;
};


typedef struct IFileSaveDialog IFileSaveDialog;
typedef struct IFileSaveDialogVtbl {
    BEGIN_INTERFACE

    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
        IFileSaveDialog *, REFIID, void **);
    ULONG ( STDMETHODCALLTYPE *AddRef )( IFileSaveDialog *);
    ULONG ( STDMETHODCALLTYPE *Release )( IFileSaveDialog *);
    HRESULT ( STDMETHODCALLTYPE *Show )(
        IFileSaveDialog *, HWND);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileSaveDialog *,
        UINT, const TCLCOMDLG_FILTERSPEC *);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )(
        IFileSaveDialog *, UINT);
    HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )(
         IFileSaveDialog *, UINT *);
    /* Actually pfde is IFileSaveDialogEvents* */
    HRESULT ( STDMETHODCALLTYPE *Advise )(
         IFileSaveDialog *, void *, DWORD *);
    HRESULT ( STDMETHODCALLTYPE *Unadvise )( IFileSaveDialog *, DWORD);
    HRESULT ( STDMETHODCALLTYPE *SetOptions )(
         IFileSaveDialog *, FILEOPENDIALOGOPTIONS);
    HRESULT ( STDMETHODCALLTYPE *GetOptions )(
         IFileSaveDialog *, FILEOPENDIALOGOPTIONS *);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )(
         IFileSaveDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *SetFolder )(
        IFileSaveDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *GetFolder )(
         IFileSaveDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )(
         IFileSaveDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *SetFileName )(
         IFileSaveDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetFileName )(
         IFileSaveDialog *,  LPWSTR *);
    HRESULT ( STDMETHODCALLTYPE *SetTitle )(
         IFileSaveDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )(
         IFileSaveDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )(
         IFileSaveDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetResult )(
         IFileSaveDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *AddPlace )(
         IFileSaveDialog *, IShellItem *, FDAP);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )(
         IFileSaveDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *Close )( IFileSaveDialog *, HRESULT);
    HRESULT ( STDMETHODCALLTYPE *SetClientGuid )(
        IFileSaveDialog *, REFGUID);
    HRESULT ( STDMETHODCALLTYPE *ClearClientData )( IFileSaveDialog *);
    /* pFilter Actually IShellItemFilter* */
    HRESULT ( STDMETHODCALLTYPE *SetFilter )(
        IFileSaveDialog *, void *);
    HRESULT ( STDMETHODCALLTYPE *SetSaveAsItem )(
        IFileSaveDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *SetProperties )(
        IFileSaveDialog *, IPropertyStore *);
    HRESULT ( STDMETHODCALLTYPE *SetCollectedProperties )(
        IFileSaveDialog *, IPropertyDescriptionList *, BOOL);
    HRESULT ( STDMETHODCALLTYPE *GetProperties )(
        IFileSaveDialog *, IPropertyStore **);
    HRESULT ( STDMETHODCALLTYPE *ApplyProperties )(
        IFileSaveDialog *, IShellItem *, IPropertyStore *,
        HWND, IFileOperationProgressSink *);

    END_INTERFACE

} IFileSaveDialogVtbl;

struct IFileSaveDialog {
    CONST_VTBL struct IFileSaveDialogVtbl *lpVtbl;
};

typedef struct IFileOpenDialog IFileOpenDialog;
typedef struct IFileOpenDialogVtbl {
    BEGIN_INTERFACE

    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
        IFileOpenDialog *, REFIID, void **);
    ULONG ( STDMETHODCALLTYPE *AddRef )( IFileOpenDialog *);
    ULONG ( STDMETHODCALLTYPE *Release )( IFileOpenDialog *);
    HRESULT ( STDMETHODCALLTYPE *Show )( IFileOpenDialog *, HWND);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileOpenDialog *,
        UINT, const TCLCOMDLG_FILTERSPEC *);
    HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )(
        IFileOpenDialog *, UINT);
    HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )(
        IFileOpenDialog *, UINT *);
    /* Actually pfde is IFileDialogEvents* */
    HRESULT ( STDMETHODCALLTYPE *Advise )(
        IFileOpenDialog *, void *, DWORD *);
    HRESULT ( STDMETHODCALLTYPE *Unadvise )( IFileOpenDialog *, DWORD);
    HRESULT ( STDMETHODCALLTYPE *SetOptions )(
        IFileOpenDialog *, FILEOPENDIALOGOPTIONS);
    HRESULT ( STDMETHODCALLTYPE *GetOptions )(
        IFileOpenDialog *, FILEOPENDIALOGOPTIONS *);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )(
        IFileOpenDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *SetFolder )(
        IFileOpenDialog *, IShellItem *);
    HRESULT ( STDMETHODCALLTYPE *GetFolder )(
        IFileOpenDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )(
        IFileOpenDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *SetFileName )(
        IFileOpenDialog *,  LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetFileName )(
        IFileOpenDialog *, LPWSTR *);
    HRESULT ( STDMETHODCALLTYPE *SetTitle )(
        IFileOpenDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )(
        IFileOpenDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )(
        IFileOpenDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *GetResult )(
        IFileOpenDialog *, IShellItem **);
    HRESULT ( STDMETHODCALLTYPE *AddPlace )(
        IFileOpenDialog *, IShellItem *, FDAP);
    HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )(
        IFileOpenDialog *, LPCWSTR);
    HRESULT ( STDMETHODCALLTYPE *Close )( IFileOpenDialog *, HRESULT);
    HRESULT ( STDMETHODCALLTYPE *SetClientGuid )(
        IFileOpenDialog *, REFGUID);
    HRESULT ( STDMETHODCALLTYPE *ClearClientData )(
        IFileOpenDialog *);
    HRESULT ( STDMETHODCALLTYPE *SetFilter )(
        IFileOpenDialog *,
        /* pFilter is actually IShellItemFilter */
        void *);
    HRESULT ( STDMETHODCALLTYPE *GetResults )(
        IFileOpenDialog *, IShellItemArray **);
    HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )(
        IFileOpenDialog *, IShellItemArray **);

    END_INTERFACE
} IFileOpenDialogVtbl;

struct IFileOpenDialog
{
    CONST_VTBL struct IFileOpenDialogVtbl *lpVtbl;
};

#endif /* __IFileDialog_INTERFACE_DEFINED__ */

/*
 * Definitions of functions used only in this file.
 */

static UINT APIENTRY	ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg,
			    LPARAM wParam, LPARAM lParam);
static UINT CALLBACK	ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static void             CleanupOFNOptions(OFNOpts *optsPtr);
static int              ParseOFNOptions(ClientData clientData,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj *const objv[], enum OFNOper oper, OFNOpts *optsPtr);
static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr,
                         enum OFNOper oper);
static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
                            enum OFNOper oper);
static int 		GetFileName(ClientData clientData,
                                    Tcl_Interp *interp, int objc,
                                    Tcl_Obj *const objv[], enum OFNOper oper);
static int MakeFilterVista(Tcl_Interp *interp, OFNOpts *optsPtr,
               DWORD *countPtr, TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr,
               DWORD *defaultFilterIndexPtr);
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr);
static int 		MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr,
			    Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
			    int *indexPtr);
static UINT APIENTRY	OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void		SetTkDialog(ClientData clientData);
static const char *ConvertExternalFilename(LPCWSTR, Tcl_DString *);
static void             LoadShellProcs(void);


/* Definitions of dynamically loaded Win32 calls */
typedef HRESULT (STDAPICALLTYPE SHCreateItemFromParsingNameProc)(
    PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
struct ShellProcPointers {
    SHCreateItemFromParsingNameProc *SHCreateItemFromParsingName;
} ShellProcs;


/*
 *-------------------------------------------------------------------------
 *
 * LoadShellProcs --
 *
 *     Some shell functions are not available on older versions of
 *     Windows. This function dynamically loads them and stores pointers
 *     to them in ShellProcs. Any function that is not available has
 *     the corresponding pointer set to NULL.
 *
 *     Note this call never fails. Unavailability of a function is not
 *     a reason for failure. Caller should check whether a particular
 *     function pointer is NULL or not. Once loaded a function stays
 *     forever loaded.
 *
 *     XXX - we load the function pointers into global memory. This implies
 *     there is a potential (however small) for race conditions between
 *     threads. However, Tk is in any case meant to be loaded in exactly
 *     one thread so this should not be an issue and saves us from
 *     unnecessary bookkeeping.
 *
 * Return value:
 *     None.
 *
 * Side effects:
 *     ShellProcs is populated.
 *-------------------------------------------------------------------------
 */
static void LoadShellProcs(void)
{
    static HMODULE shell32_handle = NULL;

    if (shell32_handle != NULL) {
	return; /* We have already been through here. */
    }

    shell32_handle = GetModuleHandleW(L"shell32.dll");
    if (shell32_handle == NULL) { /* Should never happen but check anyways. */
	return;
    }

    ShellProcs.SHCreateItemFromParsingName = (SHCreateItemFromParsingNameProc*)
	    (void *)GetProcAddress(shell32_handle, "SHCreateItemFromParsingName");
}


/*
 *-------------------------------------------------------------------------
 *
 * EatSpuriousMessageBugFix --
 *
 *	In the file open/save dialog, double clicking on a list item causes
 *	the dialog box to close, but an unwanted WM_LBUTTONUP message is sent
 *	to the window underneath. If the window underneath happens to be a
 *	windows control (eg a button) then it will be activated by accident.
 *
 * 	This problem does not occur in dialog boxes, because windows must do
 * 	some special processing to solve the problem. (separate message
 * 	processing functions are used to cope with keyboard navigation of
 * 	controls.)
 *
 * 	Here is one solution. After returning, we flush all mouse events
 *      for 1/4 second. In 8.6.5 and earlier, the code used to
 *      poll the message queue consuming WM_LBUTTONUP messages.
 * 	On seeing a WM_LBUTTONDOWN message, it would exit early, since the user
 * 	must be doing something new. However this early exit does not work
 *      on Vista and later because the Windows sends both BUTTONDOWN and
 *      BUTTONUP after the DBLCLICK instead of just BUTTONUP as on XP.
 *      Rather than try and figure out version specific sequences, we
 *      ignore all mouse events in that interval.
 *
 *      This fix only works for the current application, so the problem will
 * 	still occur if the open dialog happens to be over another applications
 * 	button. However this is a fairly rare occurrance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Consumes unwanted mouse related messages.
 *
 *-------------------------------------------------------------------------
 */

static void
EatSpuriousMessageBugFix(void)
{
    MSG msg;
    DWORD nTime = GetTickCount() + 250;

    while (GetTickCount() < nTime) {



	PeekMessageW(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<

|
|
<
<
<
<







|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|
<
|
|
|
<
<
<
<
<
|
|
|





|











>
>
>
|







158
159
160
161
162
163
164















































































































































































































































































































































































































165
166
167
168
169
170
171
172








173
174
175




176
177
178
179
180
181
182
183

184






















































185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204





205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
				 * for setting the "tk_dialog" variable. */
    int dynFileBufferSize;	/* Dynamic filename buffer size, stored to
				 * avoid shrinking and expanding the buffer
				 * when selection changes */
    WCHAR *dynFileBuffer;	/* Dynamic filename buffer */
} OFNData;
















































































































































































































































































































































































































/*
 * Definitions of functions used only in this file.
 */

static UINT APIENTRY	ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg,
			    LPARAM wParam, LPARAM lParam);
static UINT CALLBACK	ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);








static int 		GetFileName(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[], int isOpen);




static int 		MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr,
			    Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
			    int *indexPtr);
static UINT APIENTRY	OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void		SetTkDialog(ClientData clientData);
static const char *ConvertExternalFilename(WCHAR *filename,

			    Tcl_DString *dsPtr);























































/*
 *-------------------------------------------------------------------------
 *
 * EatSpuriousMessageBugFix --
 *
 *	In the file open/save dialog, double clicking on a list item causes
 *	the dialog box to close, but an unwanted WM_LBUTTONUP message is sent
 *	to the window underneath. If the window underneath happens to be a
 *	windows control (eg a button) then it will be activated by accident.
 *
 * 	This problem does not occur in dialog boxes, because windows must do
 * 	some special processing to solve the problem. (separate message
 * 	processing functions are used to cope with keyboard navigation of
 * 	controls.)
 *
 * 	Here is one solution. After returning, we poll the message queue for

 * 	1/4s looking for WM_LBUTTON up messages. If we see one it's consumed.
 * 	If we get a WM_LBUTTONDOWN message, then we exit early, since the user
 * 	must be doing something new. This fix only works for the current





 * 	application, so the problem will still occur if the open dialog
 * 	happens to be over another applications button. However this is a
 * 	fairly rare occurrance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Consumes an unwanted BUTTON messages.
 *
 *-------------------------------------------------------------------------
 */

static void
EatSpuriousMessageBugFix(void)
{
    MSG msg;
    DWORD nTime = GetTickCount() + 250;

    while (GetTickCount() < nTime) {
	if (PeekMessageA(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){
	    break;
	}
	PeekMessageA(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
int
Tk_ChooseColorObjCmd(
    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, parent;
    HWND hWnd;
    int i, oldMode, winCode, result;
    CHOOSECOLORW chooseColor;
    static int inited = 0;
    static COLORREF dwCustColors[16];
    static long oldColor;		/* the color selected last time */
    static const char *const optionStrings[] = {
	"-initialcolor", "-parent", "-title", NULL
    };
    enum options {
	COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
    };

    result = TCL_OK;







|






|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
int
Tk_ChooseColorObjCmd(
    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, parent;
    HWND hWnd;
    int i, oldMode, winCode, result;
    CHOOSECOLORW chooseColor;
    static int inited = 0;
    static COLORREF dwCustColors[16];
    static long oldColor;		/* the color selected last time */
    static const char *optionStrings[] = {
	"-initialcolor", "-parent", "-title", NULL
    };
    enum options {
	COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
    };

    result = TCL_OK;
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

810
811
812
813
814
815
816
817
	    dwCustColors[i] = RGB(255-i * 10, i, i * 10);
	}
	oldColor = RGB(0xa0, 0xa0, 0xa0);
	inited = 1;
    }

    parent			= tkwin;
    chooseColor.lStructSize	= sizeof(CHOOSECOLOR);
    chooseColor.hwndOwner	= NULL;
    chooseColor.hInstance	= NULL;
    chooseColor.rgbResult	= oldColor;
    chooseColor.lpCustColors	= dwCustColors;
    chooseColor.Flags		= CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
    chooseColor.lCustData	= (LPARAM) NULL;
    chooseColor.lpfnHook	= (LPOFNHOOKPROC)(void *)ColorDlgHookProc;
    chooseColor.lpTemplateName	= (LPWSTR) interp;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));

	    Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL);
	    return TCL_ERROR;
	}

	string = Tcl_GetString(valuePtr);
	switch ((enum options) index) {
	case COLOR_INITIAL: {
	    XColor *colorPtr;







|

















|
|



<
|
>
|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
	    dwCustColors[i] = RGB(255-i * 10, i, i * 10);
	}
	oldColor = RGB(0xa0, 0xa0, 0xa0);
	inited = 1;
    }

    parent			= tkwin;
    chooseColor.lStructSize	= sizeof(CHOOSECOLORW);
    chooseColor.hwndOwner	= NULL;
    chooseColor.hInstance	= NULL;
    chooseColor.rgbResult	= oldColor;
    chooseColor.lpCustColors	= dwCustColors;
    chooseColor.Flags		= CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
    chooseColor.lCustData	= (LPARAM) NULL;
    chooseColor.lpfnHook	= (LPOFNHOOKPROC)(void *)ColorDlgHookProc;
    chooseColor.lpTemplateName	= (LPWSTR) interp;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {

	    string = Tcl_GetString(optionPtr);
	    Tcl_AppendResult(interp, "value for \"", string, "\" missing",
		    NULL);
	    return TCL_ERROR;
	}

	string = Tcl_GetString(valuePtr);
	switch ((enum options) index) {
	case COLOR_INITIAL: {
	    XColor *colorPtr;
864
865
866
867
868
869
870

871
872
873
874
875

876
877
878
879
880
881
882
     * 3. Process the result of the dialog
     */

    if (winCode) {
	/*
	 * User has selected a color
	 */


	Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%02x%02x%02x",
		GetRValue(chooseColor.rgbResult),
		GetGValue(chooseColor.rgbResult),
		GetBValue(chooseColor.rgbResult)));

	oldColor = chooseColor.rgbResult;
	result = TCL_OK;
    }

    return result;
}








>

|


|
>







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
     * 3. Process the result of the dialog
     */

    if (winCode) {
	/*
	 * User has selected a color
	 */
	char color[100];

	sprintf(color, "#%02x%02x%02x",
		GetRValue(chooseColor.rgbResult),
		GetGValue(chooseColor.rgbResult),
		GetBValue(chooseColor.rgbResult));
	Tcl_AppendResult(interp, color, NULL);
	oldColor = chooseColor.rgbResult;
	result = TCL_OK;
    }

    return result;
}

904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
    UINT uMsg,			/* Type of message. */
    WPARAM wParam,		/* First message parameter. */
    LPARAM lParam)		/* Second message parameter. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *title;
    CHOOSECOLOR *ccPtr;
    (void)wParam;

    if (WM_INITDIALOG == uMsg) {

	/*
	 * Set the title string of the dialog.
	 */

	ccPtr = (CHOOSECOLOR *) lParam;
	title = (const char *) ccPtr->lCustData;

	if ((title != NULL) && (title[0] != '\0')) {
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    SetWindowTextW(hDlg, Tcl_UtfToWCharDString(title, -1, &ds));
	    Tcl_DStringFree(&ds);
	}
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
	    Tcl_DoWhenIdle(SetTkDialog, hDlg);
	}
	return TRUE;
    }
    return FALSE;
}

/*







|
<







|





<
|




|







439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
    UINT uMsg,			/* Type of message. */
    WPARAM wParam,		/* First message parameter. */
    LPARAM lParam)		/* Second message parameter. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *title;
    CHOOSECOLORW *ccPtr;


    if (WM_INITDIALOG == uMsg) {

	/*
	 * Set the title string of the dialog.
	 */

	ccPtr = (CHOOSECOLORW *) lParam;
	title = (const char *) ccPtr->lCustData;

	if ((title != NULL) && (title[0] != '\0')) {
	    Tcl_DString ds;


	    SetWindowTextW(hDlg, (WCHAR *)Tcl_WinUtfToTChar(title,-1,&ds));
	    Tcl_DStringFree(&ds);
	}
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
	    Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg);
	}
	return TRUE;
    }
    return FALSE;
}

/*
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_OPEN);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileCmd --
 *







|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, 1);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileCmd --
 *
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038



1039






1040



1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_SAVE);
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupOFNOptions --
 *
 *	Cleans up any storage allocated by ParseOFNOptions
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Releases resources held by *optsPtr
 *----------------------------------------------------------------------
 */
static void CleanupOFNOptions(OFNOpts *optsPtr)
{
    Tcl_DStringFree(&optsPtr->utfDirString);
}



/*
 *----------------------------------------------------------------------
 *
 * ParseOFNOptions --
 *
 *	Option parsing for tk_get{Open,Save}File
 *
 * Results:
 *	TCL_OK on success, TCL_ERROR otherwise
 *
 * Side effects:
 *	Returns option values in *optsPtr. Note these may include string
 *      pointers into objv[]
 *----------------------------------------------------------------------
 */

static int
ParseOFNOptions(

    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper,			/* 1 for Open, 0 for Save */
    OFNOpts *optsPtr)           /* Output, uninitialized on entry */
{



    int i;






    Tcl_DString ds;



    enum options {
	FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, FILE_PARENT,
	FILE_TITLE, FILE_TYPEVARIABLE, FILE_MULTIPLE, FILE_CONFIRMOW,
        FILE_MUSTEXIST,
    };
    struct Options {
	const char *name;
	enum options value;
    };
    static const struct Options saveOptions[] = {
	{"-confirmoverwrite",	FILE_CONFIRMOW},







|





|

|


|


<
<
<
<
<
<
<
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<



<
>




|
|

>
>
>
|
>
>
>
>
>
>
|
>
>
>


|
<







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536







537
538


539












540
541
542

543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * GetFileName --
 *
 *	Calls GetOpenFileName() or GetSaveFileName().
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:







 *	See user documentation.
 *


 *----------------------------------------------------------------------












 */

static int

GetFileName(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    int open)			/* 1 to call GetOpenFileName(), 0 to call
				 * GetSaveFileName(). */
{
    OPENFILENAMEW ofn;
    WCHAR file[TK_MULTI_MAX_PATH];
    OFNData ofnData;
    int cdlgerr;
    int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0;
    int confirmOverwrite = 1;
    const char *extension = NULL, *title = NULL;
    Tk_Window tkwin = (Tk_Window) clientData;
    HWND hWnd;
    Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL;
    Tcl_DString utfFilterString, utfDirString, ds;
    Tcl_DString extString, filterString, dirString, titleString;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    enum options {
	FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, FILE_PARENT,
	FILE_TITLE, FILE_TYPEVARIABLE, FILE_MULTIPLE, FILE_CONFIRMOW

    };
    struct Options {
	const char *name;
	enum options value;
    };
    static const struct Options saveOptions[] = {
	{"-confirmoverwrite",	FILE_CONFIRMOW},
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091

1092
1093



1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129



1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598



1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
	{"-initialfile",	FILE_INITFILE},
	{"-multiple",		FILE_MULTIPLE},
	{"-parent",		FILE_PARENT},
	{"-title",		FILE_TITLE},
	{"-typevariable",	FILE_TYPEVARIABLE},
	{NULL,			FILE_DEFAULT/*ignored*/ }
    };
    static const struct Options dirOptions[] = {
	{"-initialdir", FILE_INITDIR},
        {"-mustexist",  FILE_MUSTEXIST},
	{"-parent",	FILE_PARENT},
	{"-title",	FILE_TITLE},
	{NULL,		FILE_DEFAULT/*ignored*/ }
    };

    const struct Options *options = NULL;

    switch (oper) {
    case OFN_FILE_SAVE: options = saveOptions; break;
    case OFN_DIR_CHOOSE: options = dirOptions; break;
    case OFN_FILE_OPEN: options = openOptions; break;
    }

    ZeroMemory(optsPtr, sizeof(*optsPtr));
    // optsPtr->forceXPStyle = 1;
    optsPtr->tkwin = (Tk_Window)clientData;
    optsPtr->confirmOverwrite = 1; /* By default we ask for confirmation */

    Tcl_DStringInit(&optsPtr->utfDirString);
    optsPtr->file[0] = 0;




    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *valuePtr;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], options,
		sizeof(struct Options), "option", 0, &index) != TCL_OK) {
            /*
             * XXX -xpstyle is explicitly checked for as it is undocumented
             * and we do not want it to show in option error messages.
             */
            if (strcmp(Tcl_GetString(objv[i]), "-xpstyle"))
                goto error_return;
            if (i + 1 == objc) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj("value for \"-xpstyle\" missing", -1));
                Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
                goto error_return;
            }
	    if (Tcl_GetBooleanFromObj(interp, objv[i+1],
                                      &optsPtr->forceXPStyle) != TCL_OK)
                goto error_return;

            continue;

	} else if (i + 1 == objc) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                                 "value for \"%s\" missing", options[index].name));
            Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
            goto error_return;
	}

        valuePtr = objv[i + 1];
	string = Tcl_GetString(valuePtr);
	switch (options[index].value) {
	case FILE_DEFAULT:



	    optsPtr->extObj = valuePtr;
	    break;
	case FILE_TYPES:
	    optsPtr->filterObj = valuePtr;
	    break;
	case FILE_INITDIR:
	    Tcl_DStringFree(&optsPtr->utfDirString);
	    if (Tcl_TranslateFileName(interp, string,
                                      &optsPtr->utfDirString) == NULL)
		goto error_return;

	    break;
	case FILE_INITFILE:
	    if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
		goto error_return;

	    Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(),
                              Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL,
                              (char *) &optsPtr->file[0], sizeof(optsPtr->file),
                              NULL, NULL, NULL);
	    Tcl_DStringFree(&ds);
	    break;
	case FILE_PARENT:
	    optsPtr->tkwin = Tk_NameToWindow(interp, string, (Tk_Window)clientData);
	    if (optsPtr->tkwin == NULL)
		goto error_return;

	    break;
	case FILE_TITLE:
	    optsPtr->titleObj = valuePtr;
	    break;
	case FILE_TYPEVARIABLE:
	    optsPtr->typeVariableObj = valuePtr;
	    optsPtr->initialTypeObj = Tcl_ObjGetVar2(interp, valuePtr,
                                                     NULL, TCL_GLOBAL_ONLY);
	    break;
	case FILE_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr,
                                      &optsPtr->multi) != TCL_OK)
                goto error_return;

	    break;
	case FILE_CONFIRMOW:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr,
                                      &optsPtr->confirmOverwrite) != TCL_OK)
                goto error_return;
	    break;
        case FILE_MUSTEXIST:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr,
                                      &optsPtr->mustExist) != TCL_OK)
                goto error_return;
            break;
	}
    }

    return TCL_OK;

error_return:                   /* interp should already hold error */
    /* On error, we need to clean up anything we might have allocated */
    CleanupOFNOptions(optsPtr);
    return TCL_ERROR;

}


/*
 *----------------------------------------------------------------------
 * VistaFileDialogsAvailable
 *
 *      Checks whether the new (Vista) file dialogs can be used on
 *      the system.
 *
 * Returns:
 *      1 if new dialogs are available, 0 otherwise
 *
 * Side effects:
 *      Loads required procedures dynamically if available.
 *      If new dialogs are available, COM is also initialized.
 *----------------------------------------------------------------------
 */
static int VistaFileDialogsAvailable(void)
{
    HRESULT hr;
    IFileDialog *fdlgPtr = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
        Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->newFileDialogsState == FDLG_STATE_INIT) {
        tsdPtr->newFileDialogsState = FDLG_STATE_USE_OLD;
        LoadShellProcs();
        if (ShellProcs.SHCreateItemFromParsingName != NULL) {
            hr = CoInitialize(0);
            /* XXX - need we schedule CoUninitialize at thread shutdown ? */

            /* Ensure all COM interfaces we use are available */
            if (SUCCEEDED(hr)) {
                hr = CoCreateInstance(&ClsidFileOpenDialog, NULL,
                                      CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgPtr);
                if (SUCCEEDED(hr)) {
                    fdlgPtr->lpVtbl->Release(fdlgPtr);
                    hr = CoCreateInstance(&ClsidFileSaveDialog, NULL,
                             CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog,
                                          (void **) &fdlgPtr);
                    if (SUCCEEDED(hr)) {
                        fdlgPtr->lpVtbl->Release(fdlgPtr);

                        /* Looks like we have all we need */
                        tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW;
                    }
                }
            }
        }
    }

    return (tsdPtr->newFileDialogsState == FDLG_STATE_USE_NEW);
}

/*
 *----------------------------------------------------------------------
 *
 * GetFileNameVista --
 *
 *	Displays the new file dialogs on Vista and later.
 *      This function must generally not be called unless the
 *      tsdPtr->newFileDialogsState is FDLG_STATE_USE_NEW but if
 *      it is, it will just pass the call to the older GetFileNameXP
 *
 * Results:
 *	TCL_OK - dialog was successfully displayed, results returned in interp
 *      TCL_ERROR - error return
 *
 * Side effects:
 *      Dialogs is displayed
 *----------------------------------------------------------------------
 */
static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
                            enum OFNOper oper)
{
    HRESULT hr;
    HWND hWnd;
    DWORD flags, nfilters, defaultFilterIndex;
    TCLCOMDLG_FILTERSPEC *filterPtr = NULL;
    IFileDialog *fdlgIf = NULL;
    IShellItem *dirIf = NULL;
    LPWSTR wstr;
    Tcl_Obj *resultObj = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    int oldMode;

    if (tsdPtr->newFileDialogsState != FDLG_STATE_USE_NEW) {
	Tcl_Panic("Internal error: GetFileNameVista: IFileDialog API not available");
	return TCL_ERROR;
    }

    /*
     * At this point new interfaces are supposed to be available.
     * fdlgIf is actually a IFileOpenDialog or IFileSaveDialog
     * both of which inherit from IFileDialog. We use the common
     * IFileDialog interface for the most part, casting only for
     * type-specific calls.
     */
    Tk_MakeWindowExist(optsPtr->tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin));

    /*
     * The only validation we need to do w.r.t caller supplied data
     * is the filter specification so do that before creating
     */
    if (MakeFilterVista(interp, optsPtr, &nfilters, &filterPtr,
                        &defaultFilterIndex) != TCL_OK)
        return TCL_ERROR;

    /*
     * Beyond this point, do not just return on error as there will be
     * resources that need to be released/freed.
     */

    if (oper == OFN_FILE_OPEN || oper == OFN_DIR_CHOOSE)
        hr = CoCreateInstance(&ClsidFileOpenDialog, NULL,
                              CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgIf);
    else
        hr = CoCreateInstance(&ClsidFileSaveDialog, NULL,
                              CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog, (void **) &fdlgIf);

    if (FAILED(hr))
        goto vamoose;

    /*
     * Get current settings first because we want to preserve existing
     * settings like whether to show hidden files etc. based on the
     * user's existing preference
     */
    hr = fdlgIf->lpVtbl->GetOptions(fdlgIf, &flags);
    if (FAILED(hr))
        goto vamoose;

    if (filterPtr) {
        /*
         * Causes -filetypes {{All *}} -defaultextension ext to return
         * foo.ext.ext when foo is typed into the entry box
         *     flags |= FOS_STRICTFILETYPES;
         */
        hr = fdlgIf->lpVtbl->SetFileTypes(fdlgIf, nfilters, filterPtr);
        if (FAILED(hr))
            goto vamoose;
        hr = fdlgIf->lpVtbl->SetFileTypeIndex(fdlgIf, defaultFilterIndex);
        if (FAILED(hr))
            goto vamoose;
    }

    /* Flags are equivalent to those we used in the older API */

    /*
     * Following flags must be set irrespective of original setting
     * XXX - should FOS_NOVALIDATE be there ? Note FOS_NOVALIDATE has different
     * semantics than OFN_NOVALIDATE in the old API.
     */
    flags |=
        FOS_FORCEFILESYSTEM | /* Only want files, not other shell items */
        FOS_NOVALIDATE |           /* Don't check for access denied etc. */
        FOS_PATHMUSTEXIST;           /* The *directory* path must exist */


    if (oper == OFN_DIR_CHOOSE) {
        flags |= FOS_PICKFOLDERS;
        if (optsPtr->mustExist)
            flags |= FOS_FILEMUSTEXIST; /* XXX - check working */
    } else
        flags &= ~ FOS_PICKFOLDERS;

    if (optsPtr->multi)
        flags |= FOS_ALLOWMULTISELECT;
    else
        flags &= ~FOS_ALLOWMULTISELECT;

    if (optsPtr->confirmOverwrite)
        flags |= FOS_OVERWRITEPROMPT;
    else
        flags &= ~FOS_OVERWRITEPROMPT;

    hr = fdlgIf->lpVtbl->SetOptions(fdlgIf, flags);
    if (FAILED(hr))
        goto vamoose;

    if (optsPtr->extObj != NULL) {
        Tcl_DString ds;
        const char *src;

        src = Tcl_GetString(optsPtr->extObj);
        Tcl_DStringInit(&ds);
        wstr = Tcl_UtfToWCharDString(src, optsPtr->extObj->length, &ds);
        if (wstr[0] == '.')
            ++wstr;
        hr = fdlgIf->lpVtbl->SetDefaultExtension(fdlgIf, wstr);
        Tcl_DStringFree(&ds);
        if (FAILED(hr))
            goto vamoose;
    }

    if (optsPtr->titleObj != NULL) {
        Tcl_DString ds;
        const char *src;

        src = Tcl_GetString(optsPtr->titleObj);
        Tcl_DStringInit(&ds);
        wstr = Tcl_UtfToWCharDString(src, optsPtr->titleObj->length, &ds);
        hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, wstr);
        Tcl_DStringFree(&ds);
        if (FAILED(hr))
            goto vamoose;
    }

    if (optsPtr->file[0]) {
        hr = fdlgIf->lpVtbl->SetFileName(fdlgIf, optsPtr->file);
        if (FAILED(hr))
            goto vamoose;
    }

    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
        Tcl_Obj *normPath, *iniDirPath;
        iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), -1);
        Tcl_IncrRefCount(iniDirPath);
        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            LPCWSTR nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = (LPCWSTR)Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = ShellProcs.SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
                    /* Note we use SetFolder, not SetDefaultFolder - see MSDN */
                    fdlgIf->lpVtbl->SetFolder(fdlgIf, dirIf); /* Ignore errors */
                }
            }
            Tcl_DecrRefCount(normPath); /* ALSO INVALIDATES nativePath !! */
        }
        Tcl_DecrRefCount(iniDirPath);
    }

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    hr = fdlgIf->lpVtbl->Show(fdlgIf, hWnd);
    Tcl_SetServiceMode(oldMode);
    EatSpuriousMessageBugFix();

    /*
     * Ensure that hWnd is enabled, because it can happen that we have updated
     * the wrapper of the parent, which causes us to leave this child disabled
     * (Windows loses sync).
     */

    if (hWnd)
        EnableWindow(hWnd, 1);

    /*
     * Clear interp result since it might have been set during the modal loop.
     * https://core.tcl-lang.org/tk/tktview/4a0451f5291b3c9168cc560747dae9264e1d2ef6
     */
    Tcl_ResetResult(interp);

    if (SUCCEEDED(hr)) {
        if ((oper == OFN_FILE_OPEN) && optsPtr->multi) {
            IShellItemArray *multiIf;
            DWORD dw, count;
            IFileOpenDialog *fodIf = (IFileOpenDialog *) fdlgIf;
            hr = fodIf->lpVtbl->GetResults(fodIf, &multiIf);
            if (SUCCEEDED(hr)) {
                Tcl_Obj *multiObj;
                hr = multiIf->lpVtbl->GetCount(multiIf, &count);
                multiObj = Tcl_NewListObj(count, NULL);
                if (SUCCEEDED(hr)) {
                    IShellItem *itemIf;
                    for (dw = 0; dw < count; ++dw) {
                        hr = multiIf->lpVtbl->GetItemAt(multiIf, dw, &itemIf);
                        if (FAILED(hr))
                            break;
                        hr = itemIf->lpVtbl->GetDisplayName(itemIf,
                                        SIGDN_FILESYSPATH, &wstr);
                        if (SUCCEEDED(hr)) {
                            Tcl_DString fnds;

                            ConvertExternalFilename(wstr, &fnds);
                            CoTaskMemFree(wstr);
                            Tcl_ListObjAppendElement(
                                interp, multiObj,
                                Tcl_NewStringObj(Tcl_DStringValue(&fnds),
                                                 Tcl_DStringLength(&fnds)));
                            Tcl_DStringFree(&fnds);
                        }
                        itemIf->lpVtbl->Release(itemIf);
                        if (FAILED(hr))
                            break;
                    }
                }
                multiIf->lpVtbl->Release(multiIf);
                if (SUCCEEDED(hr))
                    resultObj = multiObj;
                else
                    Tcl_DecrRefCount(multiObj);
            }
        } else {
            IShellItem *resultIf;
            hr = fdlgIf->lpVtbl->GetResult(fdlgIf, &resultIf);
            if (SUCCEEDED(hr)) {
                hr = resultIf->lpVtbl->GetDisplayName(resultIf, SIGDN_FILESYSPATH,
                                                      &wstr);
                if (SUCCEEDED(hr)) {
                    Tcl_DString fnds;

                    ConvertExternalFilename(wstr, &fnds);
                    resultObj = Tcl_NewStringObj(Tcl_DStringValue(&fnds),
                                                 Tcl_DStringLength(&fnds));
                    CoTaskMemFree(wstr);
                    Tcl_DStringFree(&fnds);
                }
                resultIf->lpVtbl->Release(resultIf);
            }
        }
        if (SUCCEEDED(hr)) {
            if (filterPtr && optsPtr->typeVariableObj) {
                UINT ftix;

                hr = fdlgIf->lpVtbl->GetFileTypeIndex(fdlgIf, &ftix);
                if (SUCCEEDED(hr)) {
                    /* Note ftix is a 1-based index */
                    if (ftix > 0 && ftix <= nfilters) {
                        Tcl_DString ftds;
                        Tcl_Obj *ftobj;

                        Tcl_DStringInit(&ftds);
                        Tcl_WCharToUtfDString(filterPtr[ftix-1].pszName, wcslen(filterPtr[ftix-1].pszName), &ftds);
                        ftobj = Tcl_NewStringObj(Tcl_DStringValue(&ftds),
                                Tcl_DStringLength(&ftds));
                        Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL,
                                ftobj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
                        Tcl_DStringFree(&ftds);
                    }
                }
            }
        }
    } else {
        if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
            hr = 0;             /* User cancelled, return empty string */
    }

vamoose: /* (hr != 0) => error */
    if (dirIf)
        dirIf->lpVtbl->Release(dirIf);
    if (fdlgIf)
        fdlgIf->lpVtbl->Release(fdlgIf);

    if (filterPtr)
        FreeFilterVista(nfilters, filterPtr);

    if (hr == 0) {
        if (resultObj)          /* May be NULL if user cancelled */
            Tcl_SetObjResult(interp, resultObj);
        return TCL_OK;
    } else {
        if (resultObj)
            Tcl_DecrRefCount(resultObj);
        Tcl_SetObjResult(interp, TkWin32ErrorObj(hr));
        return TCL_ERROR;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetFileNameXP --
 *
 *	Displays the old pre-Vista file dialogs.
 *
 * Results:
 *	TCL_OK - if dialog was successfully displayed
 *      TCL_ERROR - error return
 *
 * Side effects:
 *      See user documentation.
 *----------------------------------------------------------------------
 */
static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr, enum OFNOper oper)
{
    OPENFILENAMEW ofn;
    OFNData ofnData;
    int cdlgerr;
    int filterIndex = 0, result = TCL_ERROR, winCode, oldMode;
    HWND hWnd;
    Tcl_DString utfFilterString, ds;
    Tcl_DString extString, filterString, dirString, titleString;
    const char *str;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
        Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    ZeroMemory(&ofnData, sizeof(OFNData));
    Tcl_DStringInit(&utfFilterString);
    Tcl_DStringInit(&dirString); /* XXX - original code was missing this
                                    leaving dirString uninitialized for
                                    the unlikely code path where cwd failed */

    if (MakeFilter(interp, optsPtr->filterObj, &utfFilterString,
                   optsPtr->initialTypeObj, &filterIndex) != TCL_OK) {
	goto end;
    }

    Tk_MakeWindowExist(optsPtr->tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin));

    ZeroMemory(&ofn, sizeof(OPENFILENAME));



    ofn.lStructSize = sizeof(OPENFILENAME);

    ofn.hwndOwner = hWnd;
    ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
    ofn.lpstrFile = optsPtr->file;
    ofn.nMaxFile = TK_MULTI_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
	    | OFN_EXPLORER| OFN_ENABLEHOOK| OFN_ENABLESIZING;
    ofn.lpfnHook = (LPOFNHOOKPROC)(void *)OFNHookProc;
    ofn.lCustData = (LPARAM) &ofnData;

    if (oper != OFN_FILE_SAVE) {
	ofn.Flags |= OFN_FILEMUSTEXIST;
    } else if (optsPtr->confirmOverwrite) {
	ofn.Flags |= OFN_OVERWRITEPROMPT;
    }
    if (tsdPtr->debugFlag != 0) {
	ofnData.interp = interp;
    }
    if (optsPtr->multi != 0) {
	ofn.Flags |= OFN_ALLOWMULTISELECT;

	/*
	 * Starting buffer size. The buffer will be expanded by the OFN dialog
	 * procedure when necessary
	 */

	ofnData.dynFileBufferSize = 512;
	ofnData.dynFileBuffer = (WCHAR *)ckalloc(512 * sizeof(WCHAR));
    }

    if (optsPtr->extObj != NULL) {
	str = Tcl_GetString(optsPtr->extObj);
	if (str[0] == '.') {
	    ++str;
	}
	Tcl_DStringInit(&extString);
	ofn.lpstrDefExt = Tcl_UtfToWCharDString(str, -1, &extString);
    }

    Tcl_DStringInit(&filterString);
    ofn.lpstrFilter = Tcl_UtfToWCharDString(Tcl_DStringValue(&utfFilterString),
	    Tcl_DStringLength(&utfFilterString), &filterString);

    ofn.nFilterIndex = filterIndex;

    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
	Tcl_DStringInit(&dirString);
	Tcl_UtfToWCharDString(Tcl_DStringValue(&optsPtr->utfDirString),
		Tcl_DStringLength(&optsPtr->utfDirString), &dirString);
    } else {
	/*
	 * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure
	 * that we set the [pwd] if the user didn't specify anything else.
	 */

	Tcl_DString cwd;

	Tcl_DStringFree(&optsPtr->utfDirString);
	if ((Tcl_GetCwd(interp, &optsPtr->utfDirString) == NULL) ||
		(Tcl_TranslateFileName(interp,
                     Tcl_DStringValue(&optsPtr->utfDirString), &cwd) == NULL)) {
	    Tcl_ResetResult(interp);
	} else {
		Tcl_DStringInit(&dirString);
		Tcl_UtfToWCharDString(Tcl_DStringValue(&cwd),
		    Tcl_DStringLength(&cwd), &dirString);
	}
	Tcl_DStringFree(&cwd);
    }
    ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString);

    if (optsPtr->titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	ofn.lpstrTitle = Tcl_UtfToWCharDString(Tcl_GetString(optsPtr->titleObj), -1, &titleString);
    }

    /*
     * Popup the dialog.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    if (oper != OFN_FILE_SAVE) {
	winCode = GetOpenFileNameW(&ofn);
    } else {
	winCode = GetSaveFileNameW(&ofn);
    }
    Tcl_SetServiceMode(oldMode);
    EatSpuriousMessageBugFix();








<
<
<
<
<
<
<
<
|

<
<
<
<
<
|
|
<
<
<
>
|
|
>
>
>




|



<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<

|
|
<
|


<



>
>
>
|


|


|

|
|
>


|
|
>

|
<
|



|
|
|
>


|


|
|
|


|
<
|
>



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|



|
|

|
>
>
>
|
>


|


|



|

|





|











|
<
<
<
<
|
|


<
|

>


|
<
|
|








|
|

|


<
|






|
|
|







|







588
589
590
591
592
593
594








595
596





597
598



599
600
601
602
603
604
605
606
607
608
609
610
611
612





613











614
615
616

617
618
619

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

663
664
665
666
667
668















669
























































































670




671









672







673





















































































674













































































































































































































675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718




719
720
721
722

723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
	{"-initialfile",	FILE_INITFILE},
	{"-multiple",		FILE_MULTIPLE},
	{"-parent",		FILE_PARENT},
	{"-title",		FILE_TITLE},
	{"-typevariable",	FILE_TYPEVARIABLE},
	{NULL,			FILE_DEFAULT/*ignored*/ }
    };








    const struct Options *options = open ? openOptions : saveOptions;






    file[0] = '\0';
    ZeroMemory(&ofnData, sizeof(OFNData));



    Tcl_DStringInit(&utfFilterString);
    Tcl_DStringInit(&utfDirString);

    /*
     * Parse the arguments.
     */

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], options,
		sizeof(struct Options), "option", 0, &index) != TCL_OK) {





	    goto end;











	} else if (i + 1 == objc) {
	    Tcl_AppendResult(interp, "value for \"", options[index].name,
		    "\" missing", NULL);

	    goto end;
	}


	string = Tcl_GetString(valuePtr);
	switch (options[index].value) {
	case FILE_DEFAULT:
	    if (string[0] == '.') {
		string++;
	    }
	    extension = string;
	    break;
	case FILE_TYPES:
	    filterObj = valuePtr;
	    break;
	case FILE_INITDIR:
	    Tcl_DStringFree(&utfDirString);
	    if (Tcl_TranslateFileName(interp, string,
		    &utfDirString) == NULL) {
		goto end;
	    }
	    break;
	case FILE_INITFILE:
	    if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
		goto end;
	    }
	    Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(),
		    Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL,

		    (char *) file, sizeof(file), NULL, NULL, NULL);
	    Tcl_DStringFree(&ds);
	    break;
	case FILE_PARENT:
	    tkwin = Tk_NameToWindow(interp, string, tkwin);
	    if (tkwin == NULL) {
		goto end;
	    }
	    break;
	case FILE_TITLE:
	    title = string;
	    break;
	case FILE_TYPEVARIABLE:
	    typeVariableObj = valuePtr;
	    initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL,
		    TCL_GLOBAL_ONLY);
	    break;
	case FILE_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) {

		return TCL_ERROR;
	    }
	    break;
	case FILE_CONFIRMOW:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr,
		    &confirmOverwrite) != TCL_OK) {















		return TCL_ERROR;
























































































	    }




	    break;









	}







    }



































































































































































































































































































    if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj,
	    &filterIndex) != TCL_OK) {
	goto end;
    }

    Tk_MakeWindowExist(tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(tkwin));

    ZeroMemory(&ofn, sizeof(OPENFILENAMEW));
    if (LOBYTE(LOWORD(GetVersion())) < 5) {
	ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
    } else {
	ofn.lStructSize = sizeof(OPENFILENAMEW);
    }
    ofn.hwndOwner = hWnd;
    ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
    ofn.lpstrFile = file;
    ofn.nMaxFile = TK_MULTI_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
	    | OFN_EXPLORER | OFN_ENABLEHOOK| OFN_ENABLESIZING;
    ofn.lpfnHook = (LPOFNHOOKPROC)(void *)OFNHookProc;
    ofn.lCustData = (LPARAM) &ofnData;

    if (open != 0) {
	ofn.Flags |= OFN_FILEMUSTEXIST;
    } else if (confirmOverwrite) {
	ofn.Flags |= OFN_OVERWRITEPROMPT;
    }
    if (tsdPtr->debugFlag != 0) {
	ofnData.interp = interp;
    }
    if (multi != 0) {
	ofn.Flags |= OFN_ALLOWMULTISELECT;

	/*
	 * Starting buffer size. The buffer will be expanded by the OFN dialog
	 * procedure when necessary
	 */

	ofnData.dynFileBufferSize = 512;
	ofnData.dynFileBuffer = (WCHAR *)ckalloc(512 * sizeof(WCHAR));
    }

    if (extension != NULL) {




	Tcl_WinUtfToTChar(extension, -1, &extString);
	ofn.lpstrDefExt = (WCHAR *) Tcl_DStringValue(&extString);
    }


    Tcl_WinUtfToTChar(Tcl_DStringValue(&utfFilterString),
	    Tcl_DStringLength(&utfFilterString), &filterString);
    ofn.lpstrFilter = (WCHAR *) Tcl_DStringValue(&filterString);
    ofn.nFilterIndex = filterIndex;

    if (Tcl_DStringValue(&utfDirString)[0] != '\0') {

	Tcl_WinUtfToTChar(Tcl_DStringValue(&utfDirString),
		Tcl_DStringLength(&utfDirString), &dirString);
    } else {
	/*
	 * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure
	 * that we set the [pwd] if the user didn't specify anything else.
	 */

	Tcl_DString cwd;

	Tcl_DStringFree(&utfDirString);
	if ((Tcl_GetCwd(interp, &utfDirString) == NULL) ||
		(Tcl_TranslateFileName(interp,
			Tcl_DStringValue(&utfDirString), &cwd) == NULL)) {
	    Tcl_ResetResult(interp);
	} else {

	    Tcl_WinUtfToTChar(Tcl_DStringValue(&cwd),
		    Tcl_DStringLength(&cwd), &dirString);
	}
	Tcl_DStringFree(&cwd);
    }
    ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString);

    if (title != NULL) {
	Tcl_WinUtfToTChar(title, -1, &titleString);
	ofn.lpstrTitle = (WCHAR *) Tcl_DStringValue(&titleString);
    }

    /*
     * Popup the dialog.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    if (open != 0) {
	winCode = GetOpenFileNameW(&ofn);
    } else {
	winCode = GetSaveFileNameW(&ofn);
    }
    Tcl_SetServiceMode(oldMode);
    EatSpuriousMessageBugFix();

1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
     */

    cdlgerr = CommDlgExtendedError();

    /*
     * We now allow FNERR_BUFFERTOOSMALL when multiselection is enabled. The
     * filename buffer has been dynamically allocated by the OFN dialog
     * procedure to accommodate all selected files.
     */

    if ((winCode != 0)
	    || ((cdlgerr == FNERR_BUFFERTOOSMALL)
		    && (ofn.Flags & OFN_ALLOWMULTISELECT))) {
	int gotFilename = 0;	/* Flag for tracking whether we have any
				 * filename at all. For details, see







|







794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
     */

    cdlgerr = CommDlgExtendedError();

    /*
     * We now allow FNERR_BUFFERTOOSMALL when multiselection is enabled. The
     * filename buffer has been dynamically allocated by the OFN dialog
     * procedure to accomodate all selected files.
     */

    if ((winCode != 0)
	    || ((cdlgerr == FNERR_BUFFERTOOSMALL)
		    && (ofn.Flags & OFN_ALLOWMULTISELECT))) {
	int gotFilename = 0;	/* Flag for tracking whether we have any
				 * filename at all. For details, see
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845

1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		gotFilename |= (Tcl_DStringLength(&ds) > 0);
	    }
	    Tcl_SetObjResult(interp, returnList);
	    Tcl_DStringFree(&ds);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    ConvertExternalFilename(ofn.lpstrFile, &ds), -1));
	    gotFilename = (Tcl_DStringLength(&ds) > 0);
	    Tcl_DStringFree(&ds);
	}
	result = TCL_OK;
	if ((ofn.nFilterIndex > 0) && gotFilename && optsPtr->typeVariableObj
		&& optsPtr->filterObj) {
	    int listObjc, count;
	    Tcl_Obj **listObjv = NULL;
	    Tcl_Obj **typeInfo = NULL;

	    if (Tcl_ListObjGetElements(interp, optsPtr->filterObj,
		    &listObjc, &listObjv) != TCL_OK) {
		result = TCL_ERROR;
	    } else if (Tcl_ListObjGetElements(interp,
		    listObjv[ofn.nFilterIndex - 1], &count,
		    &typeInfo) != TCL_OK) {
		result = TCL_ERROR;
	    } else {
                /*
                 * BUGFIX for d43a10ce2fed950e00890049f3c273f2cdd12583
                 * The original code was broken because it passed typeinfo[0]
                 * directly into Tcl_ObjSetVar2. In the case of typeInfo[0]
                 * pointing into a list which is also referenced by
                 * typeVariableObj, TOSV2 shimmers the object into
                 * variable intrep which loses the list representation.
                 * This invalidates typeInfo[0] which is freed but
                 * nevertheless stored as the value of the variable.
                 */
                Tcl_Obj *selFilterObj = typeInfo[0];
                Tcl_IncrRefCount(selFilterObj);
                if (Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL,
                                   selFilterObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
                    result = TCL_ERROR;
                }
                Tcl_DecrRefCount(selFilterObj);
	    }
	}
    } else if (cdlgerr == FNERR_INVALIDFILENAME) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid filename \"%s\"",
		ConvertExternalFilename(ofn.lpstrFile, &ds)));
	Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "INVALID_FILENAME",
		NULL);
	Tcl_DStringFree(&ds);
    } else {
	result = TCL_OK;
    }

    if (ofn.lpstrTitle != NULL) {
	Tcl_DStringFree(&titleString);
    }
    if (ofn.lpstrInitialDir != NULL) {
        /* XXX - huh? lpstrInitialDir is set from Tcl_DStringValue which
           can never return NULL */
	Tcl_DStringFree(&dirString);
    }
    Tcl_DStringFree(&filterString);
    if (ofn.lpstrDefExt != NULL) {
	Tcl_DStringFree(&extString);
    }

end:

    Tcl_DStringFree(&utfFilterString);
    if (ofnData.dynFileBuffer != NULL) {
	ckfree(ofnData.dynFileBuffer);
	ofnData.dynFileBuffer = NULL;
    }

    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * GetFileName --
 *
 *	Calls GetOpenFileName() or GetSaveFileName().
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
GetFileName(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper)  	/* 1 to call GetOpenFileName(), 0 to call
				 * GetSaveFileName(). */
{
    OFNOpts ofnOpts;
    int result;

    result = ParseOFNOptions(clientData, interp, objc, objv, oper, &ofnOpts);
    if (result != TCL_OK)
        return result;

    if (VistaFileDialogsAvailable() && ! ofnOpts.forceXPStyle)
        result = GetFileNameVista(interp, &ofnOpts, oper);
    else
        result = GetFileNameXP(interp, &ofnOpts, oper);

    CleanupOFNOptions(&ofnOpts);
    return result;
}


/*
 *-------------------------------------------------------------------------
 *
 * OFNHookProc --
 *
 *	Dialog box hook function. This is used to sets the "tk_dialog"







|
|




|
|




|






<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
|
<

<
|
|
<
|









<
<







|
>


|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883













884
885
886
887

888

889

890
891

892
893
894
895
896
897
898
899
900
901


902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918











































919
920
921
922
923
924
925
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		gotFilename |= (Tcl_DStringLength(&ds) > 0);
	    }
	    Tcl_SetObjResult(interp, returnList);
	    Tcl_DStringFree(&ds);
	} else {
	    Tcl_AppendResult(interp, ConvertExternalFilename(
		    ofn.lpstrFile, &ds), NULL);
	    gotFilename = (Tcl_DStringLength(&ds) > 0);
	    Tcl_DStringFree(&ds);
	}
	result = TCL_OK;
	if ((ofn.nFilterIndex > 0) && gotFilename && typeVariableObj
		&& filterObj) {
	    int listObjc, count;
	    Tcl_Obj **listObjv = NULL;
	    Tcl_Obj **typeInfo = NULL;

	    if (Tcl_ListObjGetElements(interp, filterObj,
		    &listObjc, &listObjv) != TCL_OK) {
		result = TCL_ERROR;
	    } else if (Tcl_ListObjGetElements(interp,
		    listObjv[ofn.nFilterIndex - 1], &count,
		    &typeInfo) != TCL_OK) {
		result = TCL_ERROR;













	    } else if (Tcl_ObjSetVar2(interp, typeVariableObj, NULL,
		    typeInfo[0], TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
		result = TCL_ERROR;
	    }

	}

    } else if (cdlgerr == FNERR_INVALIDFILENAME) {

	Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC);
	Tcl_AppendResult(interp, ConvertExternalFilename(

		ofn.lpstrFile, &ds), "\"", NULL);
	Tcl_DStringFree(&ds);
    } else {
	result = TCL_OK;
    }

    if (ofn.lpstrTitle != NULL) {
	Tcl_DStringFree(&titleString);
    }
    if (ofn.lpstrInitialDir != NULL) {


	Tcl_DStringFree(&dirString);
    }
    Tcl_DStringFree(&filterString);
    if (ofn.lpstrDefExt != NULL) {
	Tcl_DStringFree(&extString);
    }

  end:
    Tcl_DStringFree(&utfDirString);
    Tcl_DStringFree(&utfFilterString);
    if (ofnData.dynFileBuffer != NULL) {
	ckfree((char *)ofnData.dynFileBuffer);
	ofnData.dynFileBuffer = NULL;
    }

    return result;
}












































/*
 *-------------------------------------------------------------------------
 *
 * OFNHookProc --
 *
 *	Dialog box hook function. This is used to sets the "tk_dialog"
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
    HWND hdlg,			/* Handle to child dialog window. */
    UINT uMsg,			/* Message identifier */
    WPARAM wParam,		/* Message parameter */
    LPARAM lParam)		/* Message parameter */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    OPENFILENAME *ofnPtr;
    OFNData *ofnData;
    (void)wParam;

    if (uMsg == WM_INITDIALOG) {
	TkWinSetUserData(hdlg, lParam);
    } else if (uMsg == WM_NOTIFY) {
	OFNOTIFY *notifyPtr = (OFNOTIFY *) lParam;

	/*
	 * This is weird... or not. The CDN_FILEOK is NOT sent when the
	 * selection exceeds declared buffer size (the nMaxFile member of the
	 * OPENFILENAME struct passed to GetOpenFileName function). So, we
	 * have to rely on the most recent CDN_SELCHANGE then. Unfortunately
	 * this means, that gathering the selected filenames happens twice







|

<




|







941
942
943
944
945
946
947
948
949

950
951
952
953
954
955
956
957
958
959
960
961
    HWND hdlg,			/* Handle to child dialog window. */
    UINT uMsg,			/* Message identifier */
    WPARAM wParam,		/* Message parameter */
    LPARAM lParam)		/* Message parameter */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    OPENFILENAMEW *ofnPtr;
    OFNData *ofnData;


    if (uMsg == WM_INITDIALOG) {
	TkWinSetUserData(hdlg, lParam);
    } else if (uMsg == WM_NOTIFY) {
	OFNOTIFYW *notifyPtr = (OFNOTIFYW *) lParam;

	/*
	 * This is weird... or not. The CDN_FILEOK is NOT sent when the
	 * selection exceeds declared buffer size (the nMaxFile member of the
	 * OPENFILENAME struct passed to GetOpenFileName function). So, we
	 * have to rely on the most recent CDN_SELCHANGE then. Unfortunately
	 * this means, that gathering the selected filenames happens twice
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
	     */

	    ofnPtr = notifyPtr->lpOFN;
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    buffer = ofnData->dynFileBuffer;
	    hdlg = GetParent(hdlg);

	    selsize = (int) SendMessageW(hdlg, CDM_GETSPEC, 0, 0);
	    dirsize = (int) SendMessageW(hdlg, CDM_GETFOLDERPATH, 0, 0);
	    buffersize = (selsize + dirsize + 1);

	    /*
	     * Just empty the buffer if dirsize indicates an error. [Bug
	     * 3071836]
	     */

	    if ((selsize > 1) && (dirsize > 0)) {
		if (ofnData->dynFileBufferSize < buffersize) {
		    buffer = (WCHAR *)ckrealloc(buffer, buffersize * sizeof(WCHAR));
		    ofnData->dynFileBufferSize = buffersize;
		    ofnData->dynFileBuffer = buffer;
		}

		SendMessageW(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer);
		buffer += dirsize;








|
|









|







976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
	     */

	    ofnPtr = notifyPtr->lpOFN;
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    buffer = ofnData->dynFileBuffer;
	    hdlg = GetParent(hdlg);

	    selsize = SendMessageW(hdlg, CDM_GETSPEC, 0, 0);
	    dirsize = SendMessageW(hdlg, CDM_GETFOLDERPATH, 0, 0);
	    buffersize = (selsize + dirsize + 1);

	    /*
	     * Just empty the buffer if dirsize indicates an error. [Bug
	     * 3071836]
	     */

	    if ((selsize > 1) && (dirsize > 0)) {
		if (ofnData->dynFileBufferSize < buffersize) {
		    buffer = (WCHAR *) ckrealloc((char *) buffer, buffersize * sizeof(WCHAR));
		    ofnData->dynFileBufferSize = buffersize;
		    ofnData->dynFileBuffer = buffer;
		}

		SendMessageW(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer);
		buffer += dirsize;

2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
		     */

		    Tcl_DString tmpfile;
		    ConvertExternalFilename(buffer, &tmpfile);
		    if (TCL_PATH_ABSOLUTE ==
			    Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
			/* re-get the full path to the start of the buffer */
			buffer = ofnData->dynFileBuffer;
			SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
		    } else {
			*(buffer-1) = '\\';
		    }
		    buffer[selsize] = '\0'; /* Second NULL terminator. */
		    Tcl_DStringFree(&tmpfile);
		}







|







1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
		     */

		    Tcl_DString tmpfile;
		    ConvertExternalFilename(buffer, &tmpfile);
		    if (TCL_PATH_ABSOLUTE ==
			    Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
			/* re-get the full path to the start of the buffer */
			buffer = (WCHAR *) ofnData->dynFileBuffer;
			SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
		    } else {
			*(buffer-1) = '\\';
		    }
		    buffer[selsize] = '\0'; /* Second NULL terminator. */
		    Tcl_DStringFree(&tmpfile);
		}
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
    } else if (uMsg == WM_WINDOWPOSCHANGED) {
	/*
	 * This message is delivered at the right time to enable Tk to set the
	 * debug information. Unhooks itself so it won't set the debug
	 * information every time it gets a WM_WINDOWPOSCHANGED message.
	 */

	ofnPtr = (OPENFILENAME *) TkWinGetUserData(hdlg);
	if (ofnPtr != NULL) {
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    if (ofnData->interp != NULL) {
		hdlg = GetParent(hdlg);
		tsdPtr->debugInterp = ofnData->interp;
		Tcl_DoWhenIdle(SetTkDialog, hdlg);
	    }







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
    } else if (uMsg == WM_WINDOWPOSCHANGED) {
	/*
	 * This message is delivered at the right time to enable Tk to set the
	 * debug information. Unhooks itself so it won't set the debug
	 * information every time it gets a WM_WINDOWPOSCHANGED message.
	 */

	ofnPtr = (OPENFILENAMEW *) TkWinGetUserData(hdlg);
	if (ofnPtr != NULL) {
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    if (ofnData->interp != NULL) {
		hdlg = GetParent(hdlg);
		tsdPtr->debugInterp = ofnData->interp;
		Tcl_DoWhenIdle(SetTkDialog, hdlg);
	    }
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148

    if (flist.filters == NULL) {
	/*
	 * Use "All Files (*.*) as the default filter if none is specified
	 */
	const char *defaultFilter = "All Files (*.*)";

	p = filterStr = (char *)ckalloc(30);

	strcpy(p, defaultFilter);
	p+= strlen(defaultFilter);

	*p++ = '\0';
	*p++ = '*';
	*p++ = '.';
	*p++ = '*';
	*p++ = '\0';
	*p++ = '\0';
	*p = '\0';

    } else {
	TkSizeT len;

	if (valuePtr == NULL) {
	    len = 0;
	} else {
	    (void) TkGetStringFromObj(valuePtr, &len);
	}

	/*
	 * We format the filetype into a string understood by Windows: {"Text
	 * Documents" {.doc .txt} {TEXT}} becomes "Text Documents
	 * (*.doc,*.txt)\0*.doc;*.txt\0"
	 *
	 * See the Windows OPENFILENAME manual page for details on the filter
	 * string format.
	 */

	/*
	 * Since we may only add asterisks (*) to the filter, we need at most
	 * twice the size of the string to format the filter
	 */

	filterStr = (char *)ckalloc(len * 3);

	for (filterPtr = flist.filters, p = filterStr; filterPtr;
		filterPtr = filterPtr->next) {
	    const char *sep;
	    FileFilterClause *clausePtr;

	    /*







|













|




|
















|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169

    if (flist.filters == NULL) {
	/*
	 * Use "All Files (*.*) as the default filter if none is specified
	 */
	const char *defaultFilter = "All Files (*.*)";

	p = filterStr = ckalloc(30);

	strcpy(p, defaultFilter);
	p+= strlen(defaultFilter);

	*p++ = '\0';
	*p++ = '*';
	*p++ = '.';
	*p++ = '*';
	*p++ = '\0';
	*p++ = '\0';
	*p = '\0';

    } else {
	int len;

	if (valuePtr == NULL) {
	    len = 0;
	} else {
	    (void) Tcl_GetStringFromObj(valuePtr, &len);
	}

	/*
	 * We format the filetype into a string understood by Windows: {"Text
	 * Documents" {.doc .txt} {TEXT}} becomes "Text Documents
	 * (*.doc,*.txt)\0*.doc;*.txt\0"
	 *
	 * See the Windows OPENFILENAME manual page for details on the filter
	 * string format.
	 */

	/*
	 * Since we may only add asterisks (*) to the filter, we need at most
	 * twice the size of the string to format the filter
	 */

	filterStr = ckalloc((unsigned int) len * 3);

	for (filterPtr = flist.filters, p = filterStr; filterPtr;
		filterPtr = filterPtr->next) {
	    const char *sep;
	    FileFilterClause *clausePtr;

	    /*
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
	 */

	*p++ = '\0';
	*p = '\0';
    }

    Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr));
    ckfree(filterStr);

    TkFreeFileFilters(&flist);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeFilterVista
 *
 *      Frees storage previously allocated by MakeFilterVista.
 *      count is the number of elements in dlgFilterPtr[]
 */
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr)
{
    if (dlgFilterPtr != NULL) {
        DWORD dw;
        for (dw = 0; dw < count; ++dw) {
            if (dlgFilterPtr[dw].pszName != NULL)
                ckfree((char *)dlgFilterPtr[dw].pszName);
            if (dlgFilterPtr[dw].pszSpec != NULL)
                ckfree((char *)dlgFilterPtr[dw].pszSpec);
        }
        ckfree(dlgFilterPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeFilterVista --
 *
 *	Returns file type filters in a format required
 *	by the Vista file dialogs.
 *
 * Results:
 *	A standard TCL return value.
 *
 * Side effects:
 *      Various values are returned through the parameters as
 *      described in the comments below.
 *----------------------------------------------------------------------
 */
static int MakeFilterVista(
    Tcl_Interp *interp,		/* Current interpreter. */
    OFNOpts *optsPtr,           /* Caller specified options */
    DWORD *countPtr,            /* Will hold number of filters */
    TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr, /* Will hold pointer to filter array.
                                         Set to NULL if no filters specified.
                                         Must be freed by calling
                                         FreeFilterVista */
    DWORD *initialIndexPtr)     /* Will hold index of default type */
{
    TCLCOMDLG_FILTERSPEC *dlgFilterPtr;
    const char *initial = NULL;
    FileFilterList flist;
    FileFilter *filterPtr;
    DWORD initialIndex = 0;
    Tcl_DString ds, patterns;
    int       i;

    if (optsPtr->filterObj == NULL) {
        *dlgFilterPtrPtr = NULL;
        *countPtr = 0;
        return TCL_OK;
    }

    if (optsPtr->initialTypeObj)
	initial = Tcl_GetString(optsPtr->initialTypeObj);

    TkInitFileFilters(&flist);
    if (TkGetFileFilters(interp, &flist, optsPtr->filterObj, 1) != TCL_OK)
	return TCL_ERROR;

    if (flist.filters == NULL) {
        *dlgFilterPtrPtr = NULL;
        *countPtr = 0;
        return TCL_OK;
    }

    Tcl_DStringInit(&ds);
    Tcl_DStringInit(&patterns);
    dlgFilterPtr = (TCLCOMDLG_FILTERSPEC *)ckalloc(flist.numFilters * sizeof(*dlgFilterPtr));

    for (i = 0, filterPtr = flist.filters;
         filterPtr;
         filterPtr = filterPtr->next, ++i) {
	const char *sep;
	FileFilterClause *clausePtr;
	int nbytes;

	/* Check if this entry should be shown as the default */
	if (initial && strcmp(initial, filterPtr->name) == 0)
            initialIndex = i+1; /* Windows filter indices are 1-based */

	/* First stash away the text description of the pattern */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(filterPtr->name, -1, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszName = (LPCWSTR)ckalloc(nbytes);
	memmove((void *) dlgFilterPtr[i].pszName, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);

	/*
	 * Loop through and join patterns with a ";" Each "clause"
	 * corresponds to a single textual description (called typename)
	 * in the tk_getOpenFile docs. Each such typename may occur
	 * multiple times and all these form a single filter entry
	 * with one clause per occurence. Further each clause may specify
	 * multiple patterns. Hence the nested loop here.
	 */
	sep = "";
	for (clausePtr=filterPtr->clauses ; clausePtr;
	     clausePtr=clausePtr->next) {
	    GlobPattern *globPtr;
	    for (globPtr = clausePtr->patterns; globPtr;
		    globPtr = globPtr->next) {
		Tcl_DStringAppend(&patterns, sep, -1);
		Tcl_DStringAppend(&patterns, globPtr->pattern, -1);
		sep = ";";
	    }
	}

	/* Again we need a Unicode form of the string */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(Tcl_DStringValue(&patterns), -1, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszSpec = (LPCWSTR)ckalloc(nbytes);
	memmove((void *)dlgFilterPtr[i].pszSpec, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);
	Tcl_DStringSetLength(&patterns, 0);
    }
    Tcl_DStringFree(&patterns);

    if (initialIndex == 0) {
	initialIndex = 1;       /* If no default, show first entry */
    }
    *initialIndexPtr = initialIndex;
    *dlgFilterPtrPtr = dlgFilterPtr;
    *countPtr = flist.numFilters;

    TkFreeFileFilters(&flist);
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseDirectoryObjCmd --
 *
 *	This function implements the "tk_chooseDirectory" dialog box for the







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<







1225
1226
1227
1228
1229
1230
1231




















1232


1233
























































































































1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
	 */

	*p++ = '\0';
	*p = '\0';
    }

    Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr));




















    ckfree((char *) filterStr);



























































































































    TkFreeFileFilters(&flist);
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseDirectoryObjCmd --
 *
 *	This function implements the "tk_chooseDirectory" dialog box for the
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442

2443

2444
2445

2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463


2464
2465
2466
2467
2468



2469





2470


2471





2472



2473
2474






2475
2476
2477
2478

2479


2480
2481
2482







2483





2484
2485






2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
Tk_ChooseDirectoryObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WCHAR path[MAX_PATH];
    int oldMode, result;
    LPCITEMIDLIST pidl;		/* Returned by browser */
    BROWSEINFOW bInfo;		/* Used by browser */
    ChooseDir cdCBData;	    /* Structure to pass back and forth */
    LPMALLOC pMalloc;		/* Used by shell */

    HWND hWnd;

    WCHAR saveDir[MAX_PATH];
    Tcl_DString titleString;	/* Title */

    Tcl_DString tempString;	/* temporary */
    Tcl_Obj *objPtr;
    OFNOpts ofnOpts;
    const char *utfDir;

    result = ParseOFNOptions(clientData, interp, objc, objv,
                 OFN_DIR_CHOOSE, &ofnOpts);
    if (result != TCL_OK)
        return result;

    /* Use new dialogs if available */
    if (VistaFileDialogsAvailable() && ! ofnOpts.forceXPStyle) {
        result = GetFileNameVista(interp, &ofnOpts, OFN_DIR_CHOOSE);
        CleanupOFNOptions(&ofnOpts);
        return result;

    }

    /* Older dialogs */



    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    cdCBData.interp = interp;
    cdCBData.mustExist = ofnOpts.mustExist;









    utfDir = Tcl_DStringValue(&ofnOpts.utfDirString);


    if (utfDir[0] != '\0') {





	LPCWSTR uniStr;




	Tcl_DStringInit(&tempString);






	Tcl_UtfToWCharDString(Tcl_DStringValue(&ofnOpts.utfDirString), -1,
                          &tempString);
        uniStr = (WCHAR *) Tcl_DStringValue(&tempString);


        /* Convert possible relative path to full path to keep dialog happy. */



        GetFullPathNameW(uniStr, MAX_PATH, saveDir, NULL);
        wcsncpy(cdCBData.initDir, saveDir, MAX_PATH);







    }






    /* XXX - rest of this (original) code has no error checks at all. */







    /*
     * Get ready to call the browser
     */

    Tk_MakeWindowExist(ofnOpts.tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(ofnOpts.tkwin));

    /*
     * Setup the parameters used by SHBrowseForFolder
     */

    bInfo.hwndOwner = hWnd;
    bInfo.pszDisplayName = path;
    bInfo.pidlRoot = NULL;
    if (wcslen(cdCBData.initDir) == 0) {
	GetCurrentDirectoryW(MAX_PATH, cdCBData.initDir);
    }
    bInfo.lParam = (LPARAM) &cdCBData;

    if (ofnOpts.titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	bInfo.lpszTitle = Tcl_UtfToWCharDString(Tcl_GetString(ofnOpts.titleObj), -1, &titleString);
    } else {
	bInfo.lpszTitle = L"Please choose a directory, then select OK.";
    }

    /*
     * Set flags to add edit box, status text line and use the new ui. Allow
     * override with magic variable (ignore errors in retrieval). See







|




>

>


>


<
|
|
<
<
<
<
|
<
<
<
|
<
>
|

|
>
>




|
>
>
>

>
>
>
>
>
|
>
>
|
>
>
>
>
>
|
>
>
>
|
|
>
>
>
>
>
>
|
|
|

>
|
>
>

|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
|
<
>
>
>
>
>
>





|
|













|
|
|







1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328

1329
1330




1331



1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
Tk_ChooseDirectoryObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WCHAR path[MAX_PATH];
    int oldMode, result = TCL_ERROR, i;
    LPCITEMIDLIST pidl;		/* Returned by browser */
    BROWSEINFOW bInfo;		/* Used by browser */
    ChooseDir cdCBData;	    /* Structure to pass back and forth */
    LPMALLOC pMalloc;		/* Used by shell */
    Tk_Window tkwin = (Tk_Window) clientData;
    HWND hWnd;
    const char *utfTitle = NULL;/* Title for window */
    WCHAR saveDir[MAX_PATH];
    Tcl_DString titleString;	/* Title */
    Tcl_DString initDirString;	/* Initial directory */
    Tcl_DString tempString;	/* temporary */
    Tcl_Obj *objPtr;

    static const char *optionStrings[] = {
	"-initialdir", "-mustexist",  "-parent",  "-title", NULL




    };



    enum options {

	DIR_INITIAL,   DIR_EXIST,  DIR_PARENT, FILE_TITLE
    };

    /*
     * Initialize
     */

    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    cdCBData.interp = interp;

    /*
     * Process the command line options
     */

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	const WCHAR *uniStr;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", 0,
		&index) != TCL_OK) {
	    goto cleanup;
	}
	if (i + 1 == objc) {
	    string = Tcl_GetString(optionPtr);
	    Tcl_AppendResult(interp, "value for \"", string, "\" missing",
		    NULL);
	    goto cleanup;
	}

	string = Tcl_GetString(valuePtr);
	switch ((enum options) index) {
	case DIR_INITIAL:
	    if (Tcl_TranslateFileName(interp,string,&initDirString) == NULL) {
		goto cleanup;
	    }
	    Tcl_WinUtfToTChar(Tcl_DStringValue(&initDirString), -1,
		    &tempString);
	    uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

	    /*
	     * Convert possible relative path to full path to keep dialog
	     * happy.
	     */

	    GetFullPathNameW(uniStr, MAX_PATH, saveDir, NULL);
	    wcsncpy(cdCBData.initDir, saveDir, MAX_PATH);
	    Tcl_DStringFree(&initDirString);
	    Tcl_DStringFree(&tempString);
	    break;
	case DIR_EXIST:
	    if (Tcl_GetBooleanFromObj(interp, valuePtr,
		    &cdCBData.mustExist) != TCL_OK) {
		goto cleanup;
	    }
	    break;
	case DIR_PARENT:
	    tkwin = Tk_NameToWindow(interp, string, tkwin);
	    if (tkwin == NULL) {
		goto cleanup;
	    }

	    break;
	case FILE_TITLE:
	    utfTitle = string;
	    break;
	}
    }

    /*
     * Get ready to call the browser
     */

    Tk_MakeWindowExist(tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(tkwin));

    /*
     * Setup the parameters used by SHBrowseForFolder
     */

    bInfo.hwndOwner = hWnd;
    bInfo.pszDisplayName = path;
    bInfo.pidlRoot = NULL;
    if (wcslen(cdCBData.initDir) == 0) {
	GetCurrentDirectoryW(MAX_PATH, cdCBData.initDir);
    }
    bInfo.lParam = (LPARAM) &cdCBData;

    if (utfTitle != NULL) {
	Tcl_WinUtfToTChar(utfTitle, -1, &titleString);
	bInfo.lpszTitle = (LPWSTR) Tcl_DStringValue(&titleString);
    } else {
	bInfo.lpszTitle = L"Please choose a directory, then select OK.";
    }

    /*
     * Set flags to add edit box, status text line and use the new ui. Allow
     * override with magic variable (ignore errors in retrieval). See
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567

2568
2569
2570
2571
2572
2573
2574
     * user a chance to change their mind on an invalid folder if mustexist is
     * 0.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    GetCurrentDirectoryW(MAX_PATH, saveDir);
    if (SHGetMalloc(&pMalloc) == NOERROR) {
        /*
         * XXX - MSDN says CoInitialize must have been called before
         * SHBrowseForFolder can be used but don't see that called anywhere.
         */
	pidl = SHBrowseForFolderW(&bInfo);

	/*
	 * This is a fix for Windows 2000, which seems to modify the folder
	 * name buffer even when the dialog is canceled (in this case the
	 * buffer contains garbage). See [Bug #3002230]
	 */

	path[0] = '\0';

	/*
	 * Null for cancel button or invalid dir, otherwise valid.
	 */

	if (pidl != NULL) {
	    if (!SHGetPathFromIDListW(pidl, path)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error: not a file system folder", -1));
		Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "PSEUDO", NULL);

	    }
	    pMalloc->lpVtbl->Free(pMalloc, (void *) pidl);
	} else if (wcslen(cdCBData.retDir) > 0) {
	    wcscpy(path, cdCBData.retDir);
	}
	pMalloc->lpVtbl->Release(pMalloc);
    }







<
<
<
<
















<
|
<
>







1457
1458
1459
1460
1461
1462
1463




1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479

1480

1481
1482
1483
1484
1485
1486
1487
1488
     * user a chance to change their mind on an invalid folder if mustexist is
     * 0.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    GetCurrentDirectoryW(MAX_PATH, saveDir);
    if (SHGetMalloc(&pMalloc) == NOERROR) {




	pidl = SHBrowseForFolderW(&bInfo);

	/*
	 * This is a fix for Windows 2000, which seems to modify the folder
	 * name buffer even when the dialog is canceled (in this case the
	 * buffer contains garbage). See [Bug #3002230]
	 */

	path[0] = '\0';

	/*
	 * Null for cancel button or invalid dir, otherwise valid.
	 */

	if (pidl != NULL) {
	    if (!SHGetPathFromIDListW(pidl, path)) {

		Tcl_SetResult(interp, "Error: Not a file system folder\n",

			TCL_VOLATILE);
	    }
	    pMalloc->lpVtbl->Free(pMalloc, (void *) pidl);
	} else if (wcslen(cdCBData.retDir) > 0) {
	    wcscpy(path, cdCBData.retDir);
	}
	pMalloc->lpVtbl->Release(pMalloc);
    }
2588
2589
2590
2591
2592
2593
2594
2595
2596

2597
2598
2599

2600





2601
2602
2603
2604
2605
2606
2607
2608
     * slashes are used instead of forward slashes
     */

    Tcl_ResetResult(interp);
    if (*path) {
	Tcl_DString ds;

	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		ConvertExternalFilename(path, &ds), -1));

	Tcl_DStringFree(&ds);
    }


    CleanupOFNOptions(&ofnOpts);





    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ChooseDirectoryValidateProc --
 *







<
|
>



>
|
>
>
>
>
>
|







1502
1503
1504
1505
1506
1507
1508

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
     * slashes are used instead of forward slashes
     */

    Tcl_ResetResult(interp);
    if (*path) {
	Tcl_DString ds;


	Tcl_AppendResult(interp, ConvertExternalFilename(path,
		&ds), NULL);
	Tcl_DStringFree(&ds);
    }

    result = TCL_OK;

    if (utfTitle != NULL) {
	Tcl_DStringFree(&titleString);
    }

  cleanup:
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ChooseDirectoryValidateProc --
 *
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664


2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
    Tcl_DString initDirString;
    WCHAR string[MAX_PATH];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->debugFlag) {
	tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
	Tcl_DoWhenIdle(SetTkDialog, hwnd);
    }
    chooseDirSharedData->retDir[0] = '\0';
    switch (message) {
    case BFFM_VALIDATEFAILEDW:
	/*
	 * First save and check to see if it is a valid path name, if so then
	 * make that path the one shown in the window. Otherwise, it failed
	 * the check and should be treated as such. Use
	 * Set/GetCurrentDirectory which allows relative path names and names
	 * with forward slashes. Use Tcl_TranslateFileName to make sure names
	 * like ~ are converted correctly.
	 */

	Tcl_DStringInit(&initDirString);
	Tcl_WCharToUtfDString((WCHAR *) lParam, wcslen((WCHAR *) lParam), &initDirString);
	if (Tcl_TranslateFileName(chooseDirSharedData->interp,
		Tcl_DStringValue(&initDirString), &tempString) == NULL) {
	    /*
	     * Should we expose the error (in the interp result) to the user
	     * at this point?
	     */

	    chooseDirSharedData->retDir[0] = '\0';
	    return 1;
	}
	Tcl_DStringSetLength(&initDirString, 0);
	wcsncpy(string, Tcl_UtfToWCharDString(Tcl_DStringValue(&tempString), -1, &initDirString),


		MAX_PATH);
	Tcl_DStringFree(&initDirString);
	Tcl_DStringFree(&tempString);

	if (SetCurrentDirectoryW(string) == 0) {

	    /*
	     * Get the full path name to the user entry, at this point it does
	     * not exist so see if it is supposed to. Otherwise just return
	     * it.
	     */

	    GetFullPathNameW(string, MAX_PATH,
		    chooseDirSharedData->retDir, NULL);
	    if (chooseDirSharedData->mustExist) {
		/*
		 * User HAS to select a valid directory.
		 */

		wsprintfW(selDir, L"Directory '%s' does not exist,\n"
		        L"please select or enter an existing directory.",
			chooseDirSharedData->retDir);
		MessageBoxW(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK);
		chooseDirSharedData->retDir[0] = '\0';
		return 1;
	    }
	} else {
	    /*







|



|









|
<










|
|
>
>


<
















|
<







1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571

1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587

1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604

1605
1606
1607
1608
1609
1610
1611
    Tcl_DString initDirString;
    WCHAR string[MAX_PATH];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->debugFlag) {
	tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
	Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd);
    }
    chooseDirSharedData->retDir[0] = '\0';
    switch (message) {
    case BFFM_VALIDATEFAILED:
	/*
	 * First save and check to see if it is a valid path name, if so then
	 * make that path the one shown in the window. Otherwise, it failed
	 * the check and should be treated as such. Use
	 * Set/GetCurrentDirectory which allows relative path names and names
	 * with forward slashes. Use Tcl_TranslateFileName to make sure names
	 * like ~ are converted correctly.
	 */

	Tcl_WinTCharToUtf((TCHAR *) lParam, -1, &initDirString);

	if (Tcl_TranslateFileName(chooseDirSharedData->interp,
		Tcl_DStringValue(&initDirString), &tempString) == NULL) {
	    /*
	     * Should we expose the error (in the interp result) to the user
	     * at this point?
	     */

	    chooseDirSharedData->retDir[0] = '\0';
	    return 1;
	}
	Tcl_DStringFree(&initDirString);
	Tcl_WinUtfToTChar(Tcl_DStringValue(&tempString), -1, &initDirString);
	Tcl_DStringFree(&tempString);
	wcsncpy(string, (WCHAR *) Tcl_DStringValue(&initDirString),
		MAX_PATH);
	Tcl_DStringFree(&initDirString);


	if (SetCurrentDirectoryW(string) == 0) {

	    /*
	     * Get the full path name to the user entry, at this point it does
	     * not exist so see if it is supposed to. Otherwise just return
	     * it.
	     */

	    GetFullPathNameW(string, MAX_PATH,
		    chooseDirSharedData->retDir, NULL);
	    if (chooseDirSharedData->mustExist) {
		/*
		 * User HAS to select a valid directory.
		 */

		wsprintfW(selDir, L"Directory '%.200s' does not exist,\nplease select or enter an existing directory.",

			chooseDirSharedData->retDir);
		MessageBoxW(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK);
		chooseDirSharedData->retDir[0] = '\0';
		return 1;
	    }
	} else {
	    /*
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
	 * Directory browser initializing - tell it where to start from, user
	 * specified parameter.
	 */

	WCHAR *initDir = chooseDirSharedData->initDir;

	SetCurrentDirectoryW(initDir);

	if (*initDir == '\\') {
	    /*
	     * BFFM_SETSELECTIONW only understands UNC paths as pidls, so
	     * convert path to pidl using IShellFolder interface.
	     */

	    LPMALLOC pMalloc;
	    LPSHELLFOLDER psfFolder;

	    if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
		if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) {
		    LPITEMIDLIST pidlMain;
		    ULONG ulCount, ulAttr;

		    if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
			    psfFolder, hwnd, NULL, initDir,
			    &ulCount,&pidlMain,&ulAttr))
			    && (pidlMain != NULL)) {
			SendMessageW(hwnd, BFFM_SETSELECTIONW, FALSE,
				(LPARAM) pidlMain);
			pMalloc->lpVtbl->Free(pMalloc, pidlMain);
		    }
		    psfFolder->lpVtbl->Release(psfFolder);
		}







|









|












|
|







1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
	 * Directory browser intializing - tell it where to start from, user
	 * specified parameter.
	 */

	WCHAR *initDir = chooseDirSharedData->initDir;

	SetCurrentDirectoryW(initDir);

	if (*initDir == '\\') {
	    /*
	     * BFFM_SETSELECTION only understands UNC paths as pidls, so
	     * convert path to pidl using IShellFolder interface.
	     */

	    LPMALLOC pMalloc;
	    LPSHELLFOLDER psfFolder;

	    if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
		if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) {
		    LPITEMIDLIST pidlMain;
		    ULONG ulCount, ulAttr;

		    if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
			    psfFolder, hwnd, NULL, (WCHAR *)
			    initDir, &ulCount,&pidlMain,&ulAttr))
			    && (pidlMain != NULL)) {
			SendMessageW(hwnd, BFFM_SETSELECTIONW, FALSE,
				(LPARAM) pidlMain);
			pMalloc->lpVtbl->Free(pMalloc, pidlMain);
		    }
		    psfFolder->lpVtbl->Release(psfFolder);
		}
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836

2837
2838
2839
2840
2841
2842
2843
2844
int
Tk_MessageBoxObjCmd(
    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, parent;
    HWND hWnd;
    Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj;
    int defaultBtn, icon, type;
    int i, oldMode, winCode;
    UINT flags;
    static const char *const optionStrings[] = {
	"-default",	"-detail",	"-icon",	"-message",
	"-parent",	"-title",	"-type",	NULL
    };
    enum options {
	MSG_DEFAULT,	MSG_DETAIL,	MSG_ICON,	MSG_MESSAGE,
	MSG_PARENT,	MSG_TITLE,	MSG_TYPE
    };
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_DString titleBuf, tmpBuf;
    LPCWSTR titlePtr, tmpPtr;
    const char *src;

    defaultBtn = -1;
    detailObj = NULL;
    icon = MB_ICONINFORMATION;
    messageObj = NULL;
    parent = tkwin;
    titleObj = NULL;
    type = MB_OK;

    for (i = 1; i < objc; i += 2) {
	int index;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));

	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL);
	    return TCL_ERROR;
	}

	switch ((enum options) index) {
	case MSG_DEFAULT:
	    defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap,
		    valuePtr);







|





|









<
<
<
















|
|



<
|
>
|







1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729



1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
int
Tk_MessageBoxObjCmd(
    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, parent;
    HWND hWnd;
    Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj;
    int defaultBtn, icon, type;
    int i, oldMode, winCode;
    UINT flags;
    static const char *optionStrings[] = {
	"-default",	"-detail",	"-icon",	"-message",
	"-parent",	"-title",	"-type",	NULL
    };
    enum options {
	MSG_DEFAULT,	MSG_DETAIL,	MSG_ICON,	MSG_MESSAGE,
	MSG_PARENT,	MSG_TITLE,	MSG_TYPE
    };
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));




    defaultBtn = -1;
    detailObj = NULL;
    icon = MB_ICONINFORMATION;
    messageObj = NULL;
    parent = tkwin;
    titleObj = NULL;
    type = MB_OK;

    for (i = 1; i < objc; i += 2) {
	int index;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {

	    const char *string = Tcl_GetString(optionPtr);
	    Tcl_AppendResult(interp, "value for \"", string, "\" missing",
		    NULL);
	    return TCL_ERROR;
	}

	switch ((enum options) index) {
	case MSG_DEFAULT:
	    defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap,
		    valuePtr);
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920

2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
		for (j = 0; j < 3; j++) {
		    if (allowedTypes[i].btnIds[j] == defaultBtn) {
			defaultBtnIdx = j;
			break;
		    }
		}
		if (defaultBtnIdx < 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "invalid default button \"%s\"",
			    TkFindStateString(buttonMap, defaultBtn)));
		    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
		    return TCL_ERROR;
		}
		break;
	    }
	}
	flags = buttonFlagMap[defaultBtnIdx];
    }

    flags |= icon | type | MB_TASKMODAL | MB_SETFOREGROUND;

    tmpObj = messageObj ? Tcl_DuplicateObj(messageObj) : Tcl_NewObj();

    Tcl_IncrRefCount(tmpObj);
    if (detailObj) {
	Tcl_AppendStringsToObj(tmpObj, "\n\n", NULL);
	Tcl_AppendObjToObj(tmpObj, detailObj);
    }

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);

    /*
     * MessageBoxW exists for all platforms. Use it to allow unicode error
     * message to be displayed correctly where possible by the OS.
     *
     * In order to have the parent window icon reflected in a MessageBox, we
     * have to create a hook that will trigger when the MessageBox is being
     * created.
     */

    tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL);
    tsdPtr->hBigIcon   = TkWinGetIcon(parent, ICON_BIG);
    tsdPtr->hMsgBoxHook = SetWindowsHookExW(WH_CBT, MsgBoxCBTProc, NULL,
	    GetCurrentThreadId());
    src = Tcl_GetString(tmpObj);
    Tcl_DStringInit(&tmpBuf);
    tmpPtr = Tcl_UtfToWCharDString(src, tmpObj->length, &tmpBuf);
    if (titleObj != NULL) {
	src = Tcl_GetString(titleObj);
	Tcl_DStringInit(&titleBuf);
	titlePtr = Tcl_UtfToWCharDString(src, titleObj->length, &titleBuf);
    } else {
	titlePtr = L"";
	Tcl_DStringInit(&titleBuf);
    }
    winCode = MessageBoxW(hWnd, tmpPtr, titlePtr, flags);
    Tcl_DStringFree(&titleBuf);
    Tcl_DStringFree(&tmpBuf);
    UnhookWindowsHookEx(tsdPtr->hMsgBoxHook);
    (void) Tcl_SetServiceMode(oldMode);

    /*
     * Ensure that hWnd is enabled, because it can happen that we have updated
     * the wrapper of the parent, which causes us to leave this child disabled
     * (Windows loses sync).
     */

    EnableWindow(hWnd, 1);

    Tcl_DecrRefCount(tmpObj);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    TkFindStateString(buttonMap, winCode), -1));
    return TCL_OK;
}

static LRESULT CALLBACK
MsgBoxCBTProc(
    int nCode,
    WPARAM wParam,







<
|
|
|










|
>


|


















<
<
<
<
<
<
<
<
<
<
<
|
|
<












|
|







1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857











1858
1859

1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
		for (j = 0; j < 3; j++) {
		    if (allowedTypes[i].btnIds[j] == defaultBtn) {
			defaultBtnIdx = j;
			break;
		    }
		}
		if (defaultBtnIdx < 0) {

		    Tcl_AppendResult(interp, "invalid default button \"",
			    TkFindStateString(buttonMap, defaultBtn),
			    "\"", NULL);
		    return TCL_ERROR;
		}
		break;
	    }
	}
	flags = buttonFlagMap[defaultBtnIdx];
    }

    flags |= icon | type | MB_TASKMODAL | MB_SETFOREGROUND;

    tmpObj = messageObj ? Tcl_DuplicateObj(messageObj)
	    : Tcl_NewUnicodeObj(NULL, 0);
    Tcl_IncrRefCount(tmpObj);
    if (detailObj) {
	Tcl_AppendUnicodeToObj(tmpObj, L"\n\n", 2);
	Tcl_AppendObjToObj(tmpObj, detailObj);
    }

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);

    /*
     * MessageBoxW exists for all platforms. Use it to allow unicode error
     * message to be displayed correctly where possible by the OS.
     *
     * In order to have the parent window icon reflected in a MessageBox, we
     * have to create a hook that will trigger when the MessageBox is being
     * created.
     */

    tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL);
    tsdPtr->hBigIcon   = TkWinGetIcon(parent, ICON_BIG);
    tsdPtr->hMsgBoxHook = SetWindowsHookExW(WH_CBT, MsgBoxCBTProc, NULL,
	    GetCurrentThreadId());











    winCode = MessageBoxW(hWnd, Tcl_GetUnicode(tmpObj),
	    titleObj ? Tcl_GetUnicode(titleObj) : L"", flags);

    UnhookWindowsHookEx(tsdPtr->hMsgBoxHook);
    (void) Tcl_SetServiceMode(oldMode);

    /*
     * Ensure that hWnd is enabled, because it can happen that we have updated
     * the wrapper of the parent, which causes us to leave this child disabled
     * (Windows loses sync).
     */

    EnableWindow(hWnd, 1);

    Tcl_DecrRefCount(tmpObj);

    Tcl_SetResult(interp, TkFindStateString(buttonMap, winCode), TCL_STATIC);
    return TCL_OK;
}

static LRESULT CALLBACK
MsgBoxCBTProc(
    int nCode,
    WPARAM wParam,
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
SetTkDialog(
    ClientData clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    char buf[32];

    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)clientData);
    Tcl_SetVar2(tsdPtr->debugInterp, "tk_dialog", NULL, buf, TCL_GLOBAL_ONLY);
}

/*
 * Factored out a common pattern in use in this file.
 */

static const char *
ConvertExternalFilename(
    LPCWSTR  filename,
    Tcl_DString *dsPtr)
{
    char *p;

    Tcl_DStringInit(dsPtr);
    Tcl_WCharToUtfDString(filename, wcslen(filename), dsPtr);
    for (p = Tcl_DStringValue(dsPtr); *p != '\0'; p++) {
	/*
	 * Change the pathname to the Tcl "normalized" pathname, where back
	 * slashes are used instead of forward slashes
	 */

	if (*p == '\\') {
	    *p = '/';
	}
    }
    return Tcl_DStringValue(dsPtr);
}

/*
 * ----------------------------------------------------------------------
 *
 * GetFontObj --
 *
 *	Convert a windows LOGFONT into a Tk font description.
 *
 * Result:
 *	A list containing a Tk font description.
 *
 * ----------------------------------------------------------------------
 */

static Tcl_Obj *
GetFontObj(
    HDC hdc,
    LOGFONTW *plf)
{
    Tcl_DString ds;
    Tcl_Obj *resObj;
    int pt = 0;

    resObj = Tcl_NewListObj(0, NULL);
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(plf->lfFaceName, wcslen(plf->lfFaceName), &ds);
    Tcl_ListObjAppendElement(NULL, resObj,
	    Tcl_NewStringObj(Tcl_DStringValue(&ds), -1));
    Tcl_DStringFree(&ds);
    pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
    Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewWideIntObj(pt));
    if (plf->lfWeight >= 700) {
	Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1));
    }
    if (plf->lfItalic) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("italic", -1));
    }
    if (plf->lfUnderline) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("underline", -1));
    }
    if (plf->lfStrikeOut) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("overstrike", -1));
    }
    return resObj;
}

static void
ApplyLogfont(
    Tcl_Interp *interp,
    Tcl_Obj *cmdObj,
    HDC hdc,
    LOGFONTW *logfontPtr)
{
    int objc;
    Tcl_Obj **objv, **tmpv;

    Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv);
    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
    tmpv[objc] = GetFontObj(hdc, logfontPtr);
    TkBackgroundEvalObjv(interp, objc+1, tmpv, TCL_EVAL_GLOBAL);
    ckfree(tmpv);
}

/*
 * ----------------------------------------------------------------------
 *
 * HookProc --
 *
 *	Font selection hook. If the user selects Apply on the dialog, we call
 *	the applyProc script with the currently selected font as arguments.
 *
 * ----------------------------------------------------------------------
 */

typedef struct HookData {
    Tcl_Interp *interp;
    Tcl_Obj *titleObj;
    Tcl_Obj *cmdObj;
    Tcl_Obj *parentObj;
    Tcl_Obj *fontObj;
    HWND hwnd;
    Tk_Window parent;
} HookData;

static UINT_PTR CALLBACK
HookProc(
    HWND hwndDlg,
    UINT msg,
    WPARAM wParam,
    LPARAM lParam)
{
    CHOOSEFONT *pcf = (CHOOSEFONT *) lParam;
    HWND hwndCtrl;
    static HookData *phd = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (WM_INITDIALOG == msg && lParam != 0) {
	phd = (HookData *) pcf->lCustData;
	phd->hwnd = hwndDlg;
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = phd->interp;
	    Tcl_DoWhenIdle(SetTkDialog, hwndDlg);
	}
	if (phd->titleObj != NULL) {
	    Tcl_DString title;

	    Tcl_DStringInit(&title);
	    Tcl_UtfToWCharDString(Tcl_GetString(phd->titleObj), -1, &title);
	    if (Tcl_DStringLength(&title) > 0) {
		SetWindowTextW(hwndDlg, (LPCWSTR) Tcl_DStringValue(&title));
	    }
	    Tcl_DStringFree(&title);
	}

	/*
	 * Disable the colour combobox (0x473) and its label (0x443).
	 */

	hwndCtrl = GetDlgItem(hwndDlg, 0x443);
	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	hwndCtrl = GetDlgItem(hwndDlg, 0x473);
	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	return 1; /* we handled the message */
    }

    if (WM_DESTROY == msg) {
	phd->hwnd = NULL;
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	return 0;
    }

    /*
     * Handle apply button by calling the provided command script as a
     * background evaluation (ie: errors dont come back here).
     */

    if (WM_COMMAND == msg && LOWORD(wParam) == 1026) {
	LOGFONTW lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}};
	HDC hdc = GetDC(hwndDlg);

	SendMessageW(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf);
	if (phd && phd->cmdObj) {
	    ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf);
	}
	if (phd && phd->parent) {
	    Tk_SendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	}
	return 1;
    }
    return 0; /* pass on for default processing */
}

/*
 * Helper for the FontchooserConfigure command to return the current value of
 * any of the options (which may be NULL in the structure)
 */

enum FontchooserOption {
    FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd,
    FontchooserVisible
};

static Tcl_Obj *
FontchooserCget(
    HookData *hdPtr,
    int optionIndex)
{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (hdPtr->parentObj) {
	    resObj = hdPtr->parentObj;
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
	if (hdPtr->titleObj) {
	    resObj = hdPtr->titleObj;
	} else {
	    resObj =  Tcl_NewStringObj("", 0);
	}
	break;
    case FontchooserFont:
	if (hdPtr->fontObj) {
	    resObj = hdPtr->fontObj;
	} else {
	    resObj = Tcl_NewStringObj("", 0);
	}
	break;
    case FontchooserCmd:
	if (hdPtr->cmdObj) {
	    resObj = hdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewStringObj("", 0);
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewWideIntObj((hdPtr->hwnd != NULL) && IsWindow(hdPtr->hwnd));
	break;
    default:
	resObj = Tcl_NewStringObj("", 0);
    }
    return resObj;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserConfigureCmd --
 *
 *	Implementation of the 'tk fontchooser configure' ensemble command. See
 *	the user documentation for what it does.
 *
 * Results:
 *	See the user documentation.
 *
 * Side effects:
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    HookData *hdPtr = NULL;
    int i, r = TCL_OK;
    static const char *const optionStrings[] = {
	"-parent", "-title", "-font", "-command", "-visible", NULL
    };

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    /*
     * With no arguments we return all the options in a dict.
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && optionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(optionStrings[i], -1);
	    valueObj = FontchooserCget(hdPtr, i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *),  "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
	     * If one option and no arg - return the current value.
	     */

	    Tcl_SetObjResult(interp, FontchooserCget(hdPtr, optionIndex));
	    return TCL_OK;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "VALUE", NULL);
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    static const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);

	    if (parent == NULL) {
		return TCL_ERROR;
	    }
	    if (hdPtr->parentObj) {
		Tcl_DecrRefCount(hdPtr->parentObj);
	    }
	    hdPtr->parentObj = objv[i+1];
	    if (Tcl_IsShared(hdPtr->parentObj)) {
		hdPtr->parentObj = Tcl_DuplicateObj(hdPtr->parentObj);
	    }
	    Tcl_IncrRefCount(hdPtr->parentObj);
	    break;
	}
	case FontchooserTitle:
	    if (hdPtr->titleObj) {
		Tcl_DecrRefCount(hdPtr->titleObj);
	    }
	    hdPtr->titleObj = objv[i+1];
	    if (Tcl_IsShared(hdPtr->titleObj)) {
		hdPtr->titleObj = Tcl_DuplicateObj(hdPtr->titleObj);
	    }
	    Tcl_IncrRefCount(hdPtr->titleObj);
	    break;
	case FontchooserFont:
	    if (hdPtr->fontObj) {
		Tcl_DecrRefCount(hdPtr->fontObj);
	    }
	    Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->fontObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->fontObj)) {
		    hdPtr->fontObj = Tcl_DuplicateObj(hdPtr->fontObj);
		}
		Tcl_IncrRefCount(hdPtr->fontObj);
	    } else {
		hdPtr->fontObj = NULL;
	    }
	    break;
	case FontchooserCmd:
	    if (hdPtr->cmdObj) {
		Tcl_DecrRefCount(hdPtr->cmdObj);
	    }
	    Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->cmdObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->cmdObj)) {
		    hdPtr->cmdObj = Tcl_DuplicateObj(hdPtr->cmdObj);
		}
		Tcl_IncrRefCount(hdPtr->cmdObj);
	    } else {
		hdPtr->cmdObj = NULL;
	    }
	    break;
	}
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserShowCmd --
 *
 *	Implements the 'tk fontchooser show' ensemble command. The per-interp
 *	configuration data for the dialog is held in an interp associated
 *	structure.
 *
 *	Calls the Win32 FontChooser API which provides a modal dialog. See
 *	HookProc where we make a few changes to the dialog and set some
 *	additional state.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_DString ds;
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    CHOOSEFONTW cf;
    LOGFONTW lf;
    HDC hdc;
    HookData *hdPtr;
    int r = TCL_OK, oldMode = 0;
    (void)objc;
    (void)objv;

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    parent = tkwin;
    if (hdPtr->parentObj) {
	parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj),
		tkwin);
	if (parent == NULL) {
	    return TCL_ERROR;
	}
    }

    Tk_MakeWindowExist(parent);

    ZeroMemory(&cf, sizeof(CHOOSEFONT));
    ZeroMemory(&lf, sizeof(LOGFONT));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONT);
    cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent));
    cf.lpLogFont = &lf;
    cf.nFontType = SCREEN_FONTTYPE;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK;
    cf.rgbColors = RGB(0,0,0);
    cf.lpfnHook = HookProc;
    cf.lCustData = (INT_PTR) hdPtr;
    hdPtr->interp = interp;
    hdPtr->parent = parent;
    hdc = GetDC(cf.hwndOwner);

    if (hdPtr->fontObj != NULL) {
	TkFont *fontPtr;
	Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, hdPtr->fontObj);

	if (f == NULL) {
	    return TCL_ERROR;
	}
	fontPtr = (TkFont *) f;
	cf.Flags |= CF_INITTOLOGFONTSTRUCT;
	Tcl_DStringInit(&ds);
	wcsncpy(lf.lfFaceName, Tcl_UtfToWCharDString(fontPtr->fa.family, -1, &ds),
		LF_FACESIZE-1);
	Tcl_DStringFree(&ds);
	lf.lfFaceName[LF_FACESIZE-1] = 0;
	lf.lfHeight = -MulDiv((int)(TkFontGetPoints(tkwin, fontPtr->fa.size) + 0.5),
	    GetDeviceCaps(hdc, LOGPIXELSY), 72);
	if (fontPtr->fa.weight == TK_FW_BOLD) {
	    lf.lfWeight = FW_BOLD;
	}
	if (fontPtr->fa.slant != TK_FS_ROMAN) {
	    lf.lfItalic = TRUE;
	}
	if (fontPtr->fa.underline) {
	    lf.lfUnderline = TRUE;
	}
	if (fontPtr->fa.overstrike) {
	    lf.lfStrikeOut = TRUE;
	}
	Tk_FreeFont(f);
    }

    if (TCL_OK == r && hdPtr->cmdObj != NULL) {
	int len = 0;

	r = Tcl_ListObjLength(interp, hdPtr->cmdObj, &len);
	if (len > 0) {
	    cf.Flags |= CF_APPLY;
	}
    }

    if (TCL_OK == r) {
	oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	if (ChooseFontW(&cf)) {
	    if (hdPtr->cmdObj) {
		ApplyLogfont(hdPtr->interp, hdPtr->cmdObj, hdc, &lf);
	    }
	    if (hdPtr->parent) {
		Tk_SendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL);
	    }
	}
	Tcl_SetServiceMode(oldMode);
	EnableWindow(cf.hwndOwner, 1);
    }

    ReleaseDC(cf.hwndOwner, hdc);
    return r;
}

/*
 * ----------------------------------------------------------------------
 *
 * FontchooserHideCmd --
 *
 *	Implementation of the 'tk fontchooser hide' ensemble. See the user
 *	documentation for details.
 *	As the Win32 FontChooser function is always modal all we do here is
 *	destroy the dialog
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    ClientData dummy,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    HookData *hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);
    (void)dummy;
    (void)objc;
    (void)objv;

    if (hdPtr->hwnd && IsWindow(hdPtr->hwnd)) {
	EndDialog(hdPtr->hwnd, 0);
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * DeleteHookData --
 *
 *	Clean up the font chooser configuration data when the interp is
 *	destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteHookData(ClientData clientData, Tcl_Interp *dummy)
{
    HookData *hdPtr = (HookData *)clientData;
    (void)dummy;

    if (hdPtr->parentObj) {
	Tcl_DecrRefCount(hdPtr->parentObj);
    }
    if (hdPtr->fontObj) {
	Tcl_DecrRefCount(hdPtr->fontObj);
    }
    if (hdPtr->titleObj) {
	Tcl_DecrRefCount(hdPtr->titleObj);
    }
    if (hdPtr->cmdObj) {
	Tcl_DecrRefCount(hdPtr->cmdObj);
    }
    ckfree(hdPtr);
}

/*
 * ----------------------------------------------------------------------
 *
 * TkInitFontchooser --
 *
 *	Associate the font chooser configuration data with the Tcl
 *	interpreter. There is one font chooser per interp.
 *
 * ----------------------------------------------------------------------
 */

MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
const TkEnsemble tkFontchooserEnsemble[] = {
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

int
TkInitFontchooser(Tcl_Interp *interp, ClientData dummy)
{
    HookData *hdPtr = (HookData *)ckalloc(sizeof(HookData));
    (void)dummy;

    memset(hdPtr, 0, sizeof(HookData));
    Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteHookData, hdPtr);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|








|




|
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949

1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961




























































































































































































































































































































































































































































































































































































1962
1963
1964
1965
1966
1967
1968
1969
SetTkDialog(
    ClientData clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    char buf[32];

    sprintf(buf, "0x%p", (HWND) clientData);
    Tcl_SetVar(tsdPtr->debugInterp, "tk_dialog", buf, TCL_GLOBAL_ONLY);
}

/*
 * Factored out a common pattern in use in this file.
 */

static const char *
ConvertExternalFilename(
    WCHAR *filename,
    Tcl_DString *dsPtr)
{
    char *p;

    Tcl_WinTCharToUtf((TCHAR *) filename, -1, dsPtr);

    for (p = Tcl_DStringValue(dsPtr); *p != '\0'; p++) {
	/*
	 * Change the pathname to the Tcl "normalized" pathname, where back
	 * slashes are used instead of forward slashes
	 */

	if (*p == '\\') {
	    *p = '/';
	}
    }
    return Tcl_DStringValue(dsPtr);
}





























































































































































































































































































































































































































































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinDraw.c.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33

#include "tkWinInt.h"

/*
 * These macros convert between X's bizarre angle units to radians.
 */


#define XAngleToRadians(a) ((double)(a) / 64 * PI / 180);

/*
 * Translation table between X gc functions and Win32 raster op modes.
 */

const int tkpWinRopModes[] = {
    R2_BLACK,			/* GXclear */
    R2_MASKPEN,			/* GXand */
    R2_MASKPENNOT,		/* GXandReverse */
    R2_COPYPEN,			/* GXcopy */
    R2_MASKNOTPEN,		/* GXandInverted */
    R2_NOT,			/* GXnoop */
    R2_XORPEN,			/* GXxor */







>






|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include "tkWinInt.h"

/*
 * These macros convert between X's bizarre angle units to radians.
 */

#define PI 3.14159265358979
#define XAngleToRadians(a) ((double)(a) / 64 * PI / 180);

/*
 * Translation table between X gc functions and Win32 raster op modes.
 */

CONST int tkpWinRopModes[] = {
    R2_BLACK,			/* GXclear */
    R2_MASKPEN,			/* GXand */
    R2_MASKPENNOT,		/* GXandReverse */
    R2_COPYPEN,			/* GXcopy */
    R2_MASKNOTPEN,		/* GXandInverted */
    R2_NOT,			/* GXnoop */
    R2_XORPEN,			/* GXxor */
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 */

#define NOTSRCAND	(DWORD)0x00220326 /* dest = (NOT source) AND dest */
#define NOTSRCINVERT	(DWORD)0x00990066 /* dest = (NOT source) XOR dest */
#define SRCORREVERSE	(DWORD)0x00DD0228 /* dest = source OR (NOT dest) */
#define SRCNAND		(DWORD)0x007700E6 /* dest = NOT (source AND dest) */

const int tkpWinBltModes[] = {
    BLACKNESS,			/* GXclear */
    SRCAND,			/* GXand */
    SRCERASE,			/* GXandReverse */
    SRCCOPY,			/* GXcopy */
    NOTSRCAND,			/* GXandInverted */
    PATCOPY,			/* GXnoop */
    SRCINVERT,			/* GXxor */







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 */

#define NOTSRCAND	(DWORD)0x00220326 /* dest = (NOT source) AND dest */
#define NOTSRCINVERT	(DWORD)0x00990066 /* dest = (NOT source) XOR dest */
#define SRCORREVERSE	(DWORD)0x00DD0228 /* dest = source OR (NOT dest) */
#define SRCNAND		(DWORD)0x007700E6 /* dest = NOT (source AND dest) */

CONST int tkpWinBltModes[] = {
    BLACKNESS,			/* GXclear */
    SRCAND,			/* GXand */
    SRCERASE,			/* GXandReverse */
    SRCCOPY,			/* GXcopy */
    NOTSRCAND,			/* GXandInverted */
    PATCOPY,			/* GXnoop */
    SRCINVERT,			/* GXxor */
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#   define MAX(a,b)	((a<b) ? b : a)
#endif

/*
 * The followng typedef is used to pass Windows GDI drawing functions.
 */

typedef BOOL (CALLBACK *WinDrawFunc)(HDC dc, const POINT *points, int npoints);

typedef struct {
    POINT *winPoints;		/* Array of points that is reused. */
    int nWinPoints;		/* Current size of point array. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:







|

|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#   define MAX(a,b)	((a<b) ? b : a)
#endif

/*
 * The followng typedef is used to pass Windows GDI drawing functions.
 */

typedef BOOL (CALLBACK *WinDrawFunc)(HDC dc, CONST POINT* points, int npoints);

typedef struct ThreadSpecificData {
    POINT *winPoints;		/* Array of points that is reused. */
    int nWinPoints;		/* Current size of point array. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    /*
     * To avoid paying the cost of a malloc on every drawing routine, we reuse
     * the last array if it is large enough.
     */

    if (npoints > tsdPtr->nWinPoints) {
	if (tsdPtr->winPoints != NULL) {
	    ckfree(tsdPtr->winPoints);
	}
	tsdPtr->winPoints = (POINT *)ckalloc(sizeof(POINT) * npoints);
	if (tsdPtr->winPoints == NULL) {
	    tsdPtr->nWinPoints = -1;
	    return NULL;
	}
	tsdPtr->nWinPoints = npoints;
    }








|

|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    /*
     * To avoid paying the cost of a malloc on every drawing routine, we reuse
     * the last array if it is large enough.
     */

    if (npoints > tsdPtr->nWinPoints) {
	if (tsdPtr->winPoints != NULL) {
	    ckfree((char *) tsdPtr->winPoints);
	}
	tsdPtr->winPoints = (POINT *) ckalloc(sizeof(POINT) * npoints);
	if (tsdPtr->winPoints == NULL) {
	    tsdPtr->nWinPoints = -1;
	    return NULL;
	}
	tsdPtr->nWinPoints = npoints;
    }

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
	    /*
	     * Case 2: transparent bitmaps are handled by setting the
	     * destination to the foreground color whenever the source pixel
	     * is set.
	     */

	    fgBrush = CreateSolidBrush(gc->foreground);
	    oldBrush = (HBRUSH)SelectObject(destDC, fgBrush);
	    SetBkColor(destDC, RGB(255,255,255));
	    SetTextColor(destDC, RGB(0,0,0));
	    BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC,
		    src_x, src_y, MASKPAT);
	    SelectObject(destDC, oldBrush);
	    DeleteObject(fgBrush);
	} else {







|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
	    /*
	     * Case 2: transparent bitmaps are handled by setting the
	     * destination to the foreground color whenever the source pixel
	     * is set.
	     */

	    fgBrush = CreateSolidBrush(gc->foreground);
	    oldBrush = SelectObject(destDC, fgBrush);
	    SetBkColor(destDC, RGB(255,255,255));
	    SetTextColor(destDC, RGB(0,0,0));
	    BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC,
		    src_x, src_y, MASKPAT);
	    SelectObject(destDC, oldBrush);
	    DeleteObject(fgBrush);
	} else {
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
	     */

	    BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y,
		    SRCCOPY);
	    BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC,
		    dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin,
		    SRCAND);
	    oldBrush = (HBRUSH)SelectObject(destDC, fgBrush);
	    BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC,
		    0, 0, MASKPAT);

	    /*
	     * Set background bits. Same as foreground, except we use ((NOT
	     * source) AND mask) and the background brush.
	     */







|







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
	     */

	    BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y,
		    SRCCOPY);
	    BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC,
		    dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin,
		    SRCAND);
	    oldBrush = SelectObject(destDC, fgBrush);
	    BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC,
		    0, 0, MASKPAT);

	    /*
	     * Set background bits. Same as foreground, except we use ((NOT
	     * source) AND mask) and the background brush.
	     */
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
    TkWinReleaseDrawableDC(src, srcDC, &srcState);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage, XPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of of the
 *	specified drawable.
 *
 * Results:
 *	None.
 *







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
    TkWinReleaseDrawableDC(src, srcDC, &srcState);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of of the
 *	specified drawable.
 *
 * Results:
 *	None.
 *
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
	/*
	 * Do not use a palette for TrueColor images.
	 */

	usePalette = (image->bits_per_pixel < 16);

	if (usePalette) {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER)
		    + sizeof(RGBQUAD)*ncolors);
	} else {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER));
	}

	infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth = image->width;
	infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
	infoPtr->bmiHeader.biPlanes = 1;
	infoPtr->bmiHeader.biBitCount = image->bits_per_pixel;







|


|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
	/*
	 * Do not use a palette for TrueColor images.
	 */

	usePalette = (image->bits_per_pixel < 16);

	if (usePalette) {
	    infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER)
		    + sizeof(RGBQUAD)*ncolors);
	} else {
	    infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER));
	}

	infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth = image->width;
	infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
	infoPtr->bmiHeader.biPlanes = 1;
	infoPtr->bmiHeader.biBitCount = image->bits_per_pixel;
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
		infoPtr->bmiColors[i].rgbReserved = 0;
	    }
	} else {
	    infoPtr->bmiHeader.biClrUsed = 0;
	}
	bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT,
		image->data, infoPtr, DIB_RGB_COLORS);
	ckfree(infoPtr);
    }
    if (!bitmap) {
	Tcl_Panic("Fail to allocate bitmap");
	DeleteDC(dcMem);
    	TkWinReleaseDrawableDC(d, dc, &state);
	return BadValue;
    }
    bitmap = (HBITMAP)SelectObject(dcMem, bitmap);
    BitBlt(dc, dest_x, dest_y, (int) width, (int) height, dcMem, src_x, src_y,
	    SRCCOPY);
    DeleteObject(SelectObject(dcMem, bitmap));
    DeleteDC(dcMem);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

#undef XPutImage
int
XPutImage(
    Display *display,
    Drawable d,			/* Destination drawable. */
    GC gc,
    XImage *image,		/* Source image. */
    int src_x, int src_y,	/* Offset of subimage. */
    int dest_x, int dest_y,	/* Position of subimage origin in drawable. */
    unsigned int width, unsigned int height)
				/* Dimensions of subimage. */
{
    return TkPutImage(NULL, 0, display, d, gc, image,
		src_x, src_y, dest_x, dest_y, width, height);
}

/*
 *----------------------------------------------------------------------
 *
 * XFillRectangles --
 *
 *	Fill multiple rectangular areas in the given drawable.







|


|
<
<
<

|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







580
581
582
583
584
585
586
587
588
589
590



591
592
593
594
595
596
597
598
599
















600
601
602
603
604
605
606
		infoPtr->bmiColors[i].rgbReserved = 0;
	    }
	} else {
	    infoPtr->bmiHeader.biClrUsed = 0;
	}
	bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT,
		image->data, infoPtr, DIB_RGB_COLORS);
	ckfree((char *) infoPtr);
    }
    if (!bitmap) {
	Tcl_Panic("Fail to allocate bitmap\n");



    }
    bitmap = SelectObject(dcMem, bitmap);
    BitBlt(dc, dest_x, dest_y, (int) width, (int) height, dcMem, src_x, src_y,
	    SRCCOPY);
    DeleteObject(SelectObject(dcMem, bitmap));
    DeleteDC(dcMem);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

















/*
 *----------------------------------------------------------------------
 *
 * XFillRectangles --
 *
 *	Fill multiple rectangular areas in the given drawable.
637
638
639
640
641
642
643

644
645
646
647
648
649
650
    Display *display,
    Drawable d,
    GC gc,
    XRectangle *rectangles,
    int nrectangles)
{
    HDC dc;

    RECT rect;
    TkWinDCState state;
    HBRUSH brush, oldBrush;

    if (d == None) {
	return BadDrawable;
    }







>







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
    Display *display,
    Drawable d,
    GC gc,
    XRectangle *rectangles,
    int nrectangles)
{
    HDC dc;
    int i;
    RECT rect;
    TkWinDCState state;
    HBRUSH brush, oldBrush;

    if (d == None) {
	return BadDrawable;
    }
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793

	/*
	 * Select stipple pattern into destination dc.
	 */

	stipple = CreatePatternBrush(twdPtr->bitmap.handle);
	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = (HBRUSH)SelectObject(dc, stipple);
	dcMem = CreateCompatibleDC(dc);

	/*
	 * For each rectangle, create a drawing surface which is the size of
	 * the rectangle and fill it with the background color. Then merge the
	 * result with the stipple pattern.
	 */

	while (nrectangles-- > 0) {
	    bitmap = CreateCompatibleBitmap(dc, rectangles[0].width,
		    rectangles[0].height);
	    oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);
	    rect.left = 0;
	    rect.top = 0;
	    rect.right = rectangles[0].width;
	    rect.bottom = rectangles[0].height;
	    FillRect(dcMem, &rect, brush);
	    BitBlt(dc, rectangles[0].x, rectangles[0].y, rectangles[0].width,
		    rectangles[0].height, dcMem, 0, 0, COPYFG);
	    if (gc->fill_style == FillOpaqueStippled) {
		FillRect(dcMem, &rect, bgBrush);
		BitBlt(dc, rectangles[0].x, rectangles[0].y,
			rectangles[0].width, rectangles[0].height, dcMem,
			0, 0, COPYBG);
	    }
	    SelectObject(dcMem, oldBitmap);
	    DeleteObject(bitmap);
	    ++rectangles;
	}

	DeleteDC(dcMem);
	SelectObject(dc, oldBrush);
	DeleteObject(stipple);
	DeleteObject(bgBrush);
    } else {
	if (gc->function == GXcopy) {
	    while (nrectangles-- > 0) {
		rect.left = rectangles[0].x;
		rect.right = rect.left + rectangles[0].width;
		rect.top = rectangles[0].y;
		rect.bottom = rect.top + rectangles[0].height;
		FillRect(dc, &rect, brush);
		++rectangles;
	    }
	} else {
	    HPEN newPen = CreatePen(PS_NULL, 0, gc->foreground);
	    HPEN oldPen = (HPEN)SelectObject(dc, newPen);
	    oldBrush = (HBRUSH)SelectObject(dc, brush);

	    while (nrectangles-- > 0) {
		Rectangle(dc, rectangles[0].x, rectangles[0].y,
		    rectangles[0].x + rectangles[0].width + 1,
		    rectangles[0].y + rectangles[0].height + 1);
		++rectangles;
	    }

	    SelectObject(dc, oldBrush);
	    SelectObject(dc, oldPen);
	    DeleteObject(newPen);
	}
    }
    DeleteObject(brush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeAndStrokePath --
 *
 *	This function draws a shape using a list of points, a stipple pattern,
 *	and the specified drawing function. It does it through creation of a
 *	so-called 'path' (see GDI documentation on MSDN).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
static void
MakeAndStrokePath(
    HDC dc,
    POINT *winPoints,
    int npoints,
    WinDrawFunc func)        /* Name of the Windows GDI drawing function:
                                this is either Polyline or Polygon. */
{
    BeginPath(dc);
    func(dc, winPoints, npoints);
    /*
     * In the case of closed polylines, the first and last points
     * are the same. We want miter or bevel join be rendered also
     * at this point, this needs telling the Windows GDI that the
     * path is closed.
     */
    if (func == Polyline) {
        if ((winPoints[0].x == winPoints[npoints-1].x) &&
                (winPoints[0].y == winPoints[npoints-1].y)) {
            CloseFigure(dc);
        }
        EndPath(dc);
        StrokePath(dc);
    } else {
        EndPath(dc);
        StrokeAndFillPath(dc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RenderObject --
 *
 *	This function draws a shape using a list of points, a stipple pattern,







|








|
|
|
|


|
|

|
|


|
|




<








|
|
|
|
|

<



|
|

|
|
|
|
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717
718
719
720














































721
722
723
724
725
726
727

	/*
	 * Select stipple pattern into destination dc.
	 */

	stipple = CreatePatternBrush(twdPtr->bitmap.handle);
	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = SelectObject(dc, stipple);
	dcMem = CreateCompatibleDC(dc);

	/*
	 * For each rectangle, create a drawing surface which is the size of
	 * the rectangle and fill it with the background color. Then merge the
	 * result with the stipple pattern.
	 */

	for (i = 0; i < nrectangles; i++) {
	    bitmap = CreateCompatibleBitmap(dc, rectangles[i].width,
		    rectangles[i].height);
	    oldBitmap = SelectObject(dcMem, bitmap);
	    rect.left = 0;
	    rect.top = 0;
	    rect.right = rectangles[i].width;
	    rect.bottom = rectangles[i].height;
	    FillRect(dcMem, &rect, brush);
	    BitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width,
		    rectangles[i].height, dcMem, 0, 0, COPYFG);
	    if (gc->fill_style == FillOpaqueStippled) {
		FillRect(dcMem, &rect, bgBrush);
		BitBlt(dc, rectangles[i].x, rectangles[i].y,
			rectangles[i].width, rectangles[i].height, dcMem,
			0, 0, COPYBG);
	    }
	    SelectObject(dcMem, oldBitmap);
	    DeleteObject(bitmap);

	}

	DeleteDC(dcMem);
	SelectObject(dc, oldBrush);
	DeleteObject(stipple);
	DeleteObject(bgBrush);
    } else {
	if (gc->function == GXcopy) {
	    for (i = 0; i < nrectangles; i++) {
		rect.left = rectangles[i].x;
		rect.right = rect.left + rectangles[i].width;
		rect.top = rectangles[i].y;
		rect.bottom = rect.top + rectangles[i].height;
		FillRect(dc, &rect, brush);

	    }
	} else {
	    HPEN newPen = CreatePen(PS_NULL, 0, gc->foreground);
	    HPEN oldPen = SelectObject(dc, newPen);
	    oldBrush = SelectObject(dc, brush);

	    for (i = 0; i < nrectangles; i++) {
		Rectangle(dc, rectangles[i].x, rectangles[i].y,
		    rectangles[i].x + rectangles[i].width + 1,
		    rectangles[i].y + rectangles[i].height + 1);

	    }

	    SelectObject(dc, oldBrush);
	    SelectObject(dc, oldPen);
	    DeleteObject(newPen);
	}
    }
    DeleteObject(brush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}















































/*
 *----------------------------------------------------------------------
 *
 * RenderObject --
 *
 *	This function draws a shape using a list of points, a stipple pattern,
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
    GC gc,
    XPoint *points,
    int npoints,
    int mode,
    HPEN pen,
    WinDrawFunc func)
{
    RECT rect = {0,0,0,0};
    HPEN oldPen;
    HBRUSH oldBrush;
    POINT *winPoints = ConvertPoints(points, npoints, mode, &rect);

    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {







|







742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
    GC gc,
    XPoint *points,
    int npoints,
    int mode,
    HPEN pen,
    WinDrawFunc func)
{
    RECT rect = {0, 0, 0, 0};
    HPEN oldPen;
    HBRUSH oldBrush;
    POINT *winPoints = ConvertPoints(points, npoints, mode, &rect);

    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911

912
913
914
915
916
917
918
	height = rect.bottom - rect.top;

	/*
	 * Select stipple pattern into destination dc.
	 */

	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = (HBRUSH)SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle));

	/*
	 * Create temporary drawing surface containing a copy of the
	 * destination equal in size to the bounding box of the object.
	 */

	dcMem = CreateCompatibleDC(dc);
	oldBitmap = (HBITMAP)SelectObject(dcMem, CreateCompatibleBitmap(dc, width,
		height));
	oldPen = (HPEN)SelectObject(dcMem, pen);
	BitBlt(dcMem, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY);

	/*
	 * Translate the object for rendering in the temporary drawing
	 * surface.
	 */

	for (i = 0; i < npoints; i++) {
	    winPoints[i].x -= rect.left;
	    winPoints[i].y -= rect.top;
	}

	/*
	 * Draw the object in the foreground color and copy it to the
	 * destination wherever the pattern is set.
	 */

	SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE
		: WINDING);
	oldMemBrush = (HBRUSH)SelectObject(dcMem, CreateSolidBrush(gc->foreground));
        MakeAndStrokePath(dcMem, winPoints, npoints, func);
	BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG);

	/*
	 * If we are rendering an opaque stipple, then draw the polygon in the
	 * background color and copy it to the destination wherever the
	 * pattern is clear.
	 */

	if (gc->fill_style == FillOpaqueStippled) {
	    DeleteObject(SelectObject(dcMem,
		    CreateSolidBrush(gc->background)));
            MakeAndStrokePath(dcMem, winPoints, npoints, func);
	    BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0,
		    COPYBG);
	}

	SelectObject(dcMem, oldPen);
	DeleteObject(SelectObject(dcMem, oldMemBrush));
	DeleteObject(SelectObject(dcMem, oldBitmap));
	DeleteDC(dcMem);
    } else {
	oldPen = (HPEN)SelectObject(dc, pen);
	oldBrush = (HBRUSH)SelectObject(dc, CreateSolidBrush(gc->foreground));
	SetROP2(dc, tkpWinRopModes[gc->function]);

	SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE
		: WINDING);

        MakeAndStrokePath(dc, winPoints, npoints, func);

	SelectObject(dc, oldPen);
    }
    DeleteObject(SelectObject(dc, oldBrush));
}

/*
 *----------------------------------------------------------------------







|







|

|



















|
|











|









|
|




>
|
>







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
	height = rect.bottom - rect.top;

	/*
	 * Select stipple pattern into destination dc.
	 */

	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle));

	/*
	 * Create temporary drawing surface containing a copy of the
	 * destination equal in size to the bounding box of the object.
	 */

	dcMem = CreateCompatibleDC(dc);
	oldBitmap = SelectObject(dcMem, CreateCompatibleBitmap(dc, width,
		height));
	oldPen = SelectObject(dcMem, pen);
	BitBlt(dcMem, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY);

	/*
	 * Translate the object for rendering in the temporary drawing
	 * surface.
	 */

	for (i = 0; i < npoints; i++) {
	    winPoints[i].x -= rect.left;
	    winPoints[i].y -= rect.top;
	}

	/*
	 * Draw the object in the foreground color and copy it to the
	 * destination wherever the pattern is set.
	 */

	SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE
		: WINDING);
	oldMemBrush = SelectObject(dcMem, CreateSolidBrush(gc->foreground));
	(*func)(dcMem, winPoints, npoints);
	BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG);

	/*
	 * If we are rendering an opaque stipple, then draw the polygon in the
	 * background color and copy it to the destination wherever the
	 * pattern is clear.
	 */

	if (gc->fill_style == FillOpaqueStippled) {
	    DeleteObject(SelectObject(dcMem,
		    CreateSolidBrush(gc->background)));
	    (*func)(dcMem, winPoints, npoints);
	    BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0,
		    COPYBG);
	}

	SelectObject(dcMem, oldPen);
	DeleteObject(SelectObject(dcMem, oldMemBrush));
	DeleteObject(SelectObject(dcMem, oldBitmap));
	DeleteDC(dcMem);
    } else {
	oldPen = SelectObject(dc, pen);
	oldBrush = SelectObject(dc, CreateSolidBrush(gc->foreground));
	SetROP2(dc, tkpWinRopModes[gc->function]);

	SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE
		: WINDING);

	(*func)(dc, winPoints, npoints);

	SelectObject(dc, oldPen);
    }
    DeleteObject(SelectObject(dc, oldBrush));
}

/*
 *----------------------------------------------------------------------
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
    int npoints,
    int shape,
    int mode)
{
    HPEN pen;
    TkWinDCState state;
    HDC dc;
    (void)shape;

    if (d == None) {
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);

    pen = (HPEN)GetStockObject(NULL_PEN);
    RenderObject(dc, gc, points, npoints, mode, pen, Polygon);

    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangle, XDrawRectangles --
 *
 *	Draws a rectangle.
 *
 * Results:
 *	None.
 *
 * Side effects:







<







|









|







919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
    int npoints,
    int shape,
    int mode)
{
    HPEN pen;
    TkWinDCState state;
    HDC dc;


    if (d == None) {
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);

    pen = GetStockObject(NULL_PEN);
    RenderObject(dc, gc, points, npoints, mode, pen, Polygon);

    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XDrawRectangle --
 *
 *	Draws a rectangle.
 *
 * Results:
 *	None.
 *
 * Side effects:
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);

    pen = SetUpGraphicsPort(gc);
    SetBkMode(dc, TRANSPARENT);
    oldPen = (HPEN)SelectObject(dc, pen);
    oldBrush = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH));
    SetROP2(dc, tkpWinRopModes[gc->function]);

    Rectangle(dc, x, y, (int) x+width+1, (int) y+height+1);

    DeleteObject(SelectObject(dc, oldPen));
    SelectObject(dc, oldBrush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

int
XDrawRectangles(
    Display *display,
    Drawable d,
    GC gc,
    XRectangle rects[],
    int nrects)
{
    int ret = Success;

    while (nrects-- > 0) {
	ret = XDrawRectangle(display, d, gc, rects[0].x, rects[0].y,
		    rects[0].width, rects[0].height);
	if (ret != Success) {
	    break;
	}
	++rects;
    }
    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * XDrawArc, XDrawArcs --
 *
 *	Draw an arc.
 *
 * Results:
 *	None.
 *
 * Side effects:







|
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987





















988
989
990
991
992
993
994
995
996
997
998
999
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);

    pen = SetUpGraphicsPort(gc);
    SetBkMode(dc, TRANSPARENT);
    oldPen = SelectObject(dc, pen);
    oldBrush = SelectObject(dc, GetStockObject(NULL_BRUSH));
    SetROP2(dc, tkpWinRopModes[gc->function]);

    Rectangle(dc, x, y, (int) x+width+1, (int) y+height+1);

    DeleteObject(SelectObject(dc, oldPen));
    SelectObject(dc, oldBrush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}






















/*
 *----------------------------------------------------------------------
 *
 * XDrawArc --
 *
 *	Draw an arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0);
}

int
XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    display->request++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 0);
	if (ret != Success) {
	    break;
	}
	++arcs;
    }
    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * XFillArc, XFillArcs --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|







1011
1012
1013
1014
1015
1016
1017
























1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0);
}

























/*
 *----------------------------------------------------------------------
 *
 * XFillArc --
 *
 *	Draw a filled arc.
 *
 * Results:
 *	None.
 *
 * Side effects:
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1);
}

int
XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    display->request++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 1);
	if (ret != Success) {
	    break;
	}
	++arcs;
    }
    return ret;
}

/*
 *----------------------------------------------------------------------
 *
 * DrawOrFillArc --
 *
 *	This function handles the rendering of drawn or filled arcs and







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1041
1042
1043
1044
1045
1046
1047
























1048
1049
1050
1051
1052
1053
1054
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1);
}

























/*
 *----------------------------------------------------------------------
 *
 * DrawOrFillArc --
 *
 *	This function handles the rendering of drawn or filled arcs and
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
    /*
     * Now draw a filled or open figure. Note that we have to increase the
     * size of the bounding box by one to account for the difference in pixel
     * definitions between X and Windows.
     */

    pen = SetUpGraphicsPort(gc);
    oldPen = (HPEN)SelectObject(dc, pen);
    if (!fill) {
	/*
	 * Note that this call will leave a gap of one pixel at the end of the
	 * arc for thin arcs. We can't use ArcTo because it's only supported
	 * under Windows NT.
	 */

	SetBkMode(dc, TRANSPARENT);
	Arc(dc, x, y, (int) (x+width+1), (int) (y+height+1), xstart, ystart,
		xend, yend);
    } else {
	brush = CreateSolidBrush(gc->foreground);
	oldBrush = (HBRUSH)SelectObject(dc, brush);
	if (gc->arc_mode == ArcChord) {
	    Chord(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	} else if (gc->arc_mode == ArcPieSlice) {
	    Pie(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	}







|












|







1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
    /*
     * Now draw a filled or open figure. Note that we have to increase the
     * size of the bounding box by one to account for the difference in pixel
     * definitions between X and Windows.
     */

    pen = SetUpGraphicsPort(gc);
    oldPen = SelectObject(dc, pen);
    if (!fill) {
	/*
	 * Note that this call will leave a gap of one pixel at the end of the
	 * arc for thin arcs. We can't use ArcTo because it's only supported
	 * under Windows NT.
	 */

	SetBkMode(dc, TRANSPARENT);
	Arc(dc, x, y, (int) (x+width+1), (int) (y+height+1), xstart, ystart,
		xend, yend);
    } else {
	brush = CreateSolidBrush(gc->foreground);
	oldBrush = SelectObject(dc, brush);
	if (gc->arc_mode == ArcChord) {
	    Chord(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	} else if (gc->arc_mode == ArcPieSlice) {
	    Pie(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	}
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin));
    RECT scrollRect;
    (void)gc;

    scrollRect.left = x;
    scrollRect.top = y;
    scrollRect.right = x + width;
    scrollRect.bottom = y + height;
    return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn,
	    NULL, 0) == NULLREGION) ? 0 : 1;







|



<







1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin));
    RECT scrollRect;


    scrollRect.left = x;
    scrollRect.top = y;
    scrollRect.right = x + width;
    scrollRect.bottom = y + height;
    return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn,
	    NULL, 0) == NULLREGION) ? 0 : 1;
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461

    rect.left = x;
    rect.top = y;
    rect.right = x + width;
    rect.bottom = y + height;
    oldColor = SetBkColor(dc, (COLORREF)pixel);
    SetBkMode(dc, OPAQUE);
    ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --







|







1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326

    rect.left = x;
    rect.top = y;
    rect.right = x + width;
    rect.bottom = y + height;
    oldColor = SetBkColor(dc, (COLORREF)pixel);
    SetBkMode(dc, OPAQUE);
    ExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;

    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrameEx(
    Tk_Window tkwin,
    Drawable drawable,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, drawable, border, highlightWidth,
	    highlightWidth, Tk_Width(tkwin) - 2 * highlightWidth,
	    Tk_Height(tkwin) - 2 * highlightWidth, borderWidth, relief);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<






|













|

<





|











1346
1347
1348
1349
1350
1351
1352


1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{


    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrame --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrame(
    Tk_Window tkwin,

    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, highlightWidth,
	    highlightWidth, Tk_Width(tkwin) - 2 * highlightWidth,
	    Tk_Height(tkwin) - 2 * highlightWidth, borderWidth, relief);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinEmbed.c.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
				 * or NULL if the embedded application isn't
				 * in this process. */
    HWND embeddedMenuHWnd;	/* Tk's embedded menu window handler. */
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

typedef struct {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		ContainerEventProc(ClientData clientData,







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
				 * or NULL if the embedded application isn't
				 * in this process. */
    HWND embeddedMenuHWnd;	/* Tk's embedded menu window handler. */
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

typedef struct ThreadSpecificData {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		ContainerEventProc(ClientData clientData,
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
void
TkWinCleanupContainerList(void)
{
    Container *nextPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (; tsdPtr->firstContainerPtr != NULL;
	    tsdPtr->firstContainerPtr = nextPtr) {
	nextPtr = tsdPtr->firstContainerPtr->nextPtr;
	ckfree(tsdPtr->firstContainerPtr);
    }
    tsdPtr->firstContainerPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTestembedCmd --
 *
 *	Test command for the embedding facility.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */


int
TkpTestembedCmd(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    (void)dummy;
    (void)interp;
    (void)objc;
    (void)objv;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DetachEmbeddedWindow --







|


|

|


















>


|

|
|

<
<
<
<
<







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106





107
108
109
110
111
112
113
void
TkWinCleanupContainerList(void)
{
    Container *nextPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (; tsdPtr->firstContainerPtr != (Container *) NULL;
	    tsdPtr->firstContainerPtr = nextPtr) {
	nextPtr = tsdPtr->firstContainerPtr->nextPtr;
	ckfree((char *) tsdPtr->firstContainerPtr);
    }
    tsdPtr->firstContainerPtr = (Container *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTestembedCmd --
 *
 *	Test command for the embedding facility.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TkpTestembedCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int argc,
    CONST char **argv)
{





    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DetachEmbeddedWindow --
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    BOOL detachFlag)		/* a flag of truely detaching */
{
    TkpWinToplevelDetachWindow(winPtr);
    if(detachFlag) {
	TkpWinToplevelOverrideRedirect(winPtr, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MapEmbeddedWindow --
 *
 *	This function is required for mapping an embedded window during idle.
 *	The input winPtr must be preserved using Tcl_Preserve before call this







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    BOOL detachFlag)		/* a flag of truely detaching */
{
    TkpWinToplevelDetachWindow(winPtr);
    if(detachFlag) {
	TkpWinToplevelOverrideRedirect(winPtr, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MapEmbeddedWindow --
 *
 *	This function is required for mapping an embedded window during idle.
 *	The input winPtr must be preserved using Tcl_Preserve before call this
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
static
void Tk_MapEmbeddedWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessageW(hwnd, TK_STATE, -1, -1) - 1;

	if (state < 0 || state > 3) {
	    state = NormalState;
	}

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release(winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *







|












|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
static
void Tk_MapEmbeddedWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessage(hwnd, TK_STATE, -1, -1) - 1;

	if (state < 0 || state > 3) {
	    state = NormalState;
	}

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release((ClientData)winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return either
 *		a TRUE (non-zero) if it is available for use or a FALSE (zero)
 *		othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window to
 *	use is a valid container. Without an id verification, an invalid
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be defined/used in future for other
 *	needs.
 *
 *	We do not enforce the above protocol for the reason of backward
 *	compatibility. If the window to use is unable to handle TK_INFO
 *	messages (e.g., legacy Tk container applications before 8.5), a dialog
 *	box with a warning message pops up and the user is asked to confirm if
 *	the attachment should proceed. However, we may have to enforce it in







|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return either
 *		a TRUE (non-zero) if it is available for use or a FALSE (zero)
 *		othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window to
 *	use is a valid container. Without an id verification, an invalid
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be definded/used in future for other
 *	needs.
 *
 *	We do not enforce the above protocol for the reason of backward
 *	compatibility. If the window to use is unable to handle TK_INFO
 *	messages (e.g., legacy Tk container applications before 8.5), a dialog
 *	box with a warning message pops up and the user is asked to confirm if
 *	the attachment should proceed. However, we may have to enforce it in
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int id;
    HWND hwnd;
/*
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
*/

/*
    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
*/

    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);







|












|
|
<







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    CONST char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int id;
    HWND hwnd;
/*
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
*/

/*
    if (winPtr->window != None) {
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);

	return TCL_ERROR;
    }
*/

    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
     * Check if the window is a valid handle. If it is invalid, return
     * TCL_ERROR and potentially leave an error message in the interp's
     * result.
     */

    if (!IsWindow(hwnd)) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" doesn't exist", string));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "EXIST", NULL);
	}
	return TCL_ERROR;
    }

    id = SendMessageW(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessageW(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "The container is already in use", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"the window to use is not a Tk container", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL);
	return TCL_ERROR;
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	WCHAR msg[256];

	wsprintfW(msg, L"Unable to get information of window \"%.40hs\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBoxW(hwnd, msg, L"Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Operation has been canceled", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL);
	    return TCL_ERROR;
	}
    }

    Tk_DetachEmbeddedWindow(winPtr, FALSE);

    /*
     * Store the parent window in the platform private data slot so
     * TkWmMapWindow can use it when creating the wrapper window.
     */

    winPtr->privatePtr = (struct TkWindowPrivate*) hwnd;
    winPtr->flags |= TK_EMBEDDED;
    winPtr->flags &= ~(TK_MAPPED);

    /*
     * Preserve the winPtr and create an idle handler to map the embedded
     * window.
     */

    Tcl_Preserve(winPtr);
    Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, winPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|
|
<




|

|
<
|
<



<
|
|








|

|
|

<
|
<




















|
|







271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286

287

288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
     * Check if the window is a valid handle. If it is invalid, return
     * TCL_ERROR and potentially leave an error message in the interp's
     * result.
     */

    if (!IsWindow(hwnd)) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "window \"", string,
		    "\" doesn't exist", NULL);

	}
	return TCL_ERROR;
    }

    id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {

    	    Tcl_AppendResult(interp, "The container is already in use", NULL);

	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {

	Tcl_AppendResult(interp, "the window to use is not a Tk container",
		NULL);
	return TCL_ERROR;
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	char msg[256];

	sprintf(msg, "Unable to get information of window \"%.79s\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBox(hwnd, msg, "Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {

    	    Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC);

	    return TCL_ERROR;
	}
    }

    Tk_DetachEmbeddedWindow(winPtr, FALSE);

    /*
     * Store the parent window in the platform private data slot so
     * TkWmMapWindow can use it when creating the wrapper window.
     */

    winPtr->privatePtr = (struct TkWindowPrivate*) hwnd;
    winPtr->flags |= TK_EMBEDDED;
    winPtr->flags &= ~(TK_MAPPED);

    /*
     * Preserve the winPtr and create an idle handler to map the embedded
     * window.
     */

    Tcl_Preserve((ClientData) winPtr);
    Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, (ClientData) winPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

    /*
     * Register the window as a container so that, for example, we can find
     * out later if the embedded app. is in the same process.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *)ckalloc(sizeof(Container));
    containerPtr->parentPtr = winPtr;
    containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin));
    containerPtr->embeddedHWnd = NULL;
    containerPtr->embeddedPtr = NULL;
    containerPtr->embeddedMenuHWnd = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Unlike in tkUnixEmbed.c, we don't make any requests for events in the
     * embedded window here. Now we just allow the embedding of another TK
     * application into TK windows. When the embedded window makes a request,
     * that will be done by sending to the container window a WM_USER message,
     * which will be intercepted by TkWinContainerProc.
     *
     * We need to get structure events of the container itself, though.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    ContainerEventProc, containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinEmbeddedEventProc --
 *







|




















|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

    /*
     * Register the window as a container so that, for example, we can find
     * out later if the embedded app. is in the same process.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *) ckalloc(sizeof(Container));
    containerPtr->parentPtr = winPtr;
    containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin));
    containerPtr->embeddedHWnd = NULL;
    containerPtr->embeddedPtr = NULL;
    containerPtr->embeddedMenuHWnd = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Unlike in tkUnixEmbed.c, we don't make any requests for events in the
     * embedded window here. Now we just allow the embedding of another TK
     * application into TK windows. When the embedded window makes a request,
     * that will be done by sending to the container window a WM_USER message,
     * which will be intercepted by TkWinContainerProc.
     *
     * We need to get structure events of the container itself, though.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    ContainerEventProc, (ClientData) containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinEmbeddedEventProc --
 *
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;

    if (eventPtr->type == ConfigureNotify) {

	/*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != NULL) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }

	/*
	 * Resize the embedded window, if there is any.
	 */

	if (containerPtr->embeddedHWnd) {
	    SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);







<
<
<
<
<
<
<
<
<







845
846
847
848
849
850
851









852
853
854
855
856
857
858
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;

    if (eventPtr->type == ConfigureNotify) {









	/*
	 * Resize the embedded window, if there is any.
	 */

	if (containerPtr->embeddedHWnd) {
	    SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedHWnd;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedMenuHWND --
 *
 *	This function returns the embedded menu window id.
 *







|







934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedHWnd;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedMenuHWND --
 *
 *	This function returns the embedded menu window id.
 *
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
    TkWindow *topLevelPtr,	/* Top-level window containing desired focus
				 * window; should be embedded. */
    int force)			/* One means that the container should claim
				 * the focus if it doesn't currently have
				 * it. */
{
    HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window));
    SendMessageW(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedirectKeyEvent --
 *







|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
    TkWindow *topLevelPtr,	/* Top-level window containing desired focus
				 * window; should be embedded. */
    int force)			/* One means that the container should claim
				 * the focus if it doesn't currently have
				 * it. */
{
    HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window));
    SendMessage(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedirectKeyEvent --
 *
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{
    (void)winPtr;
    (void)eventPtr;
    /* not implemented */
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --







<
<







1030
1031
1032
1033
1034
1035
1036


1037
1038
1039
1040
1041
1042
1043
void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{


    /* not implemented */
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
    while (1) {
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessageW(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
	    containerPtr->parentPtr = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	prevPtr = containerPtr;
	containerPtr = containerPtr->nextPtr;
	if (containerPtr == NULL) {
	    return;
	}
    }
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree(containerPtr);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

















|










1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
    while (1) {
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessage(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
	    containerPtr->parentPtr = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	prevPtr = containerPtr;
	containerPtr = containerPtr->nextPtr;
	if (containerPtr == NULL) {
	    return;
	}
    }
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree((char *) containerPtr);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinFont.c.

1
2
3
4
5
6
7
8
9
10
11
/*
 * tkWinFont.c --
 *
 *	Contains the Windows implementation of the platform-independent font
 *	package interface.
 *
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of



|







1
2
3
4
5
6
7
8
9
10
11
/*
 * tkWinFont.c --
 *
 *	Contains the Windows implementation of the platform-independant font
 *	package interface.
 *
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 * a given Unicode character.
 *
 * Under Windows, a "font family" is uniquely identified by its face name.
 */

#define FONTMAP_SHIFT	    10


#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)
#define FONTMAP_NUMCHARS	0x40000
#define FONTMAP_PAGES		(FONTMAP_NUMCHARS / FONTMAP_BITSPERPAGE)

typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    size_t refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */
    /*
     * Key.
     */

    Tk_Uid faceName;		/* Face name key for this FontFamily. */

    /*
     * Derived properties.
     */

    Tcl_Encoding encoding;	/* Encoding for this font family. */
    int isSymbolFont;		/* Non-zero if this is a symbol font. */
    int isWideFont;		/* 1 if this is a double-byte font, 0
				 * otherwise. */
    BOOL (WINAPI *textOutProc)(HDC hdc, int x, int y, WCHAR *str, int len);
				/* The procedure to use to draw text after it
				 * has been converted from UTF-8 to the
				 * encoding of this font. */
    BOOL (WINAPI *getTextExtentPoint32Proc)(HDC, WCHAR *, int, LPSIZE);
				/* The procedure to use to measure text after
				 * it has been converted from UTF-8 to the
				 * encoding of this font. */

    char *fontMap[FONTMAP_PAGES];
				/* Two-level sparse table used to determine
				 * quickly if the specified character exists.







>

<
<



|
















|



|







24
25
26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 * a given Unicode character.
 *
 * Under Windows, a "font family" is uniquely identified by its face name.
 */

#define FONTMAP_SHIFT	    10

#define FONTMAP_PAGES	    	(1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT))
#define FONTMAP_BITSPERPAGE	(1 << FONTMAP_SHIFT)



typedef struct FontFamily {
    struct FontFamily *nextPtr;	/* Next in list of all known font families. */
    int refCount;		/* How many SubFonts are referring to this
				 * FontFamily. When the refCount drops to
				 * zero, this FontFamily may be freed. */
    /*
     * Key.
     */

    Tk_Uid faceName;		/* Face name key for this FontFamily. */

    /*
     * Derived properties.
     */

    Tcl_Encoding encoding;	/* Encoding for this font family. */
    int isSymbolFont;		/* Non-zero if this is a symbol font. */
    int isWideFont;		/* 1 if this is a double-byte font, 0
				 * otherwise. */
    BOOL (WINAPI *textOutProc)(HDC, int, int, TCHAR *, int);
				/* The procedure to use to draw text after it
				 * has been converted from UTF-8 to the
				 * encoding of this font. */
    BOOL (WINAPI *getTextExtentPoint32Proc)(HDC, TCHAR *, int, LPSIZE);
				/* The procedure to use to measure text after
				 * it has been converted from UTF-8 to the
				 * encoding of this font. */

    char *fontMap[FONTMAP_PAGES];
				/* Two-level sparse table used to determine
				 * quickly if the specified character exists.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 * object is made up of however many SubFonts are necessary to display a
 * stream of multilingual characters.
 */

typedef struct SubFont {
    char **fontMap;		/* Pointer to font map from the FontFamily,
				 * cached here to save a dereference. */
    HFONT hFont0;		/* The specific screen font that will be used
				 * when displaying/measuring chars belonging
				 * to the FontFamily. */
    FontFamily *familyPtr;	/* The FontFamily for this SubFont. */
    HFONT hFontAngled;
    double angle;
} SubFont;

/*
 * The following structure represents Windows' implementation of a font
 * object.
 */








|



<
<







90
91
92
93
94
95
96
97
98
99
100


101
102
103
104
105
106
107
 * object is made up of however many SubFonts are necessary to display a
 * stream of multilingual characters.
 */

typedef struct SubFont {
    char **fontMap;		/* Pointer to font map from the FontFamily,
				 * cached here to save a dereference. */
    HFONT hFont;		/* The specific screen font that will be used
				 * when displaying/measuring chars belonging
				 * to the FontFamily. */
    FontFamily *familyPtr;	/* The FontFamily for this SubFont. */


} SubFont;

/*
 * The following structure represents Windows' implementation of a font
 * object.
 */

122
123
124
125
126
127
128

129
130
131
132
133
134
135
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * AllocFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */

    HWND hwnd;			/* Toplevel window of application that owns
				 * this font, used for getting HDC for
				 * offscreen measurements. */
    int pixelSize;		/* Original pixel size used when font was
				 * constructed. */
    int widths[BASE_CHARS];	/* Widths of first 128 chars in the base font,
				 * for handling common case. The base font is







>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * AllocFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */

    HWND hwnd;			/* Toplevel window of application that owns
				 * this font, used for getting HDC for
				 * offscreen measurements. */
    int pixelSize;		/* Original pixel size used when font was
				 * constructed. */
    int widths[BASE_CHARS];	/* Widths of first 128 chars in the base font,
				 * for handling common case. The base font is
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181






182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    {DEFAULT_GUI_FONT,	    "defaultgui"},
    {OEM_FIXED_FONT,	    "oemfixed"},
    {SYSTEM_FIXED_FONT,	    "systemfixed"},
    {SYSTEM_FONT,	    "system"},
    {-1,		    NULL}
};

typedef struct {
    FontFamily *fontFamilyList; /* The list of font families that are
				 * currently loaded. As screen fonts are
				 * loaded, this list grows to hold information
				 * about what characters exist in each font
				 * family. */
    Tcl_HashTable uidTable;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;







/*
 * Procedures used only in this file.
 */

static FontFamily *	AllocFontFamily(HDC hdc, HFONT hFont, int base);
static SubFont *	CanUseFallback(HDC hdc, WinFont *fontPtr,
			    const char *fallbackName, int ch,
			    SubFont **subFontPtrPtr);
static SubFont *	CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr,
			    const char *faceName, int ch,
			    Tcl_DString *nameTriedPtr,
			    SubFont **subFontPtrPtr);
static int		FamilyExists(HDC hdc, const char *faceName);
static const char *	FamilyOrAliasExists(HDC hdc, const char *faceName);
static SubFont *	FindSubFontForChar(WinFont *fontPtr, int ch,
			    SubFont **subFontPtrPtr);
static void		FontMapInsert(SubFont *subFontPtr, int ch);
static void		FontMapLoadPage(SubFont *subFontPtr, int row);
static int		FontMapLookup(SubFont *subFontPtr, int ch);
static void		FreeFontFamily(FontFamily *familyPtr);
static HFONT		GetScreenFont(const TkFontAttributes *faPtr,
			    const char *faceName, int pixelSize,
			    double angle);
static void		InitFont(Tk_Window tkwin, HFONT hFont,
			    int overstrike, WinFont *tkFontPtr);
static inline void	InitSubFont(HDC hdc, HFONT hFont, int base,
			    SubFont *subFontPtr);
static int		CreateNamedSystemLogFont(Tcl_Interp *interp,
			    Tk_Window tkwin, const char* name,
			    LOGFONTW* logFontPtr);
static int		CreateNamedSystemFont(Tcl_Interp *interp,
			    Tk_Window tkwin, const char* name, HFONT hFont);
static int		LoadFontRanges(HDC hdc, HFONT hFont,
			    USHORT **startCount, USHORT **endCount,
			    int *symbolPtr);
static void		MultiFontTextOut(HDC hdc, WinFont *fontPtr,
			    const char *source, int numBytes,
			    double x, double y, double angle);
static void		ReleaseFont(WinFont *fontPtr);
static inline void	ReleaseSubFont(SubFont *subFontPtr);
static int		SeenName(const char *name, Tcl_DString *dsPtr);
static inline HFONT	SelectFont(HDC hdc, WinFont *fontPtr,
			    SubFont *subFontPtr, double angle);
static inline void	SwapLong(PULONG p);
static inline void	SwapShort(USHORT *p);
static int CALLBACK	WinFontCanUseProc(ENUMLOGFONTW *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);
static int CALLBACK	WinFontExistProc(ENUMLOGFONTW *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);
static int CALLBACK	WinFontFamilyEnumProc(ENUMLOGFONTW *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);

/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --







|




|




>
>
>
>
>
>






|


<
|

|
|






|
|
<


|


|
|

|




|
<

|
|
<
<
|
|
|


|


|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223


224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
    {DEFAULT_GUI_FONT,	    "defaultgui"},
    {OEM_FIXED_FONT,	    "oemfixed"},
    {SYSTEM_FIXED_FONT,	    "systemfixed"},
    {SYSTEM_FONT,	    "system"},
    {-1,		    NULL}
};

typedef struct ThreadSpecificData {
    FontFamily *fontFamilyList; /* The list of font families that are
				 * currently loaded. As screen fonts are
				 * loaded, this list grows to hold information
				 * about what characters exist in each font
				 * family.  */
    Tcl_HashTable uidTable;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Information cached about the system at startup time.
 */

static Tcl_Encoding systemEncoding;

/*
 * Procedures used only in this file.
 */

static FontFamily *	AllocFontFamily(HDC hdc, HFONT hFont, int base);
static SubFont *	CanUseFallback(HDC hdc, WinFont *fontPtr,
			    char *fallbackName,	int ch,
			    SubFont **subFontPtrPtr);
static SubFont *	CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr,

			    char *faceName, int ch, Tcl_DString *nameTriedPtr,
			    SubFont **subFontPtrPtr);
static int		FamilyExists(HDC hdc, CONST char *faceName);
static char *		FamilyOrAliasExists(HDC hdc, CONST char *faceName);
static SubFont *	FindSubFontForChar(WinFont *fontPtr, int ch,
			    SubFont **subFontPtrPtr);
static void		FontMapInsert(SubFont *subFontPtr, int ch);
static void		FontMapLoadPage(SubFont *subFontPtr, int row);
static int		FontMapLookup(SubFont *subFontPtr, int ch);
static void		FreeFontFamily(FontFamily *familyPtr);
static HFONT		GetScreenFont(CONST TkFontAttributes *faPtr,
			    CONST char *faceName, int pixelSize);

static void		InitFont(Tk_Window tkwin, HFONT hFont,
			    int overstrike, WinFont *tkFontPtr);
static void		InitSubFont(HDC hdc, HFONT hFont, int base,
			    SubFont *subFontPtr);
static int		CreateNamedSystemLogFont(Tcl_Interp *interp,
			    Tk_Window tkwin, CONST char* name,
			    LOGFONT* logFontPtr);
static int		CreateNamedSystemFont(Tcl_Interp *interp,
			    Tk_Window tkwin, CONST char* name, HFONT hFont);
static int		LoadFontRanges(HDC hdc, HFONT hFont,
			    USHORT **startCount, USHORT **endCount,
			    int *symbolPtr);
static void		MultiFontTextOut(HDC hdc, WinFont *fontPtr,
			    CONST char *source, int numBytes, int x, int y);

static void		ReleaseFont(WinFont *fontPtr);
static void		ReleaseSubFont(SubFont *subFontPtr);
static int		SeenName(CONST char *name, Tcl_DString *dsPtr);


static void		SwapLong(PULONG p);
static void		SwapShort(USHORT *p);
static int CALLBACK	WinFontCanUseProc(ENUMLOGFONT *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);
static int CALLBACK	WinFontExistProc(ENUMLOGFONT *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);
static int CALLBACK	WinFontFamilyEnumProc(ENUMLOGFONT *lfPtr,
			    NEWTEXTMETRIC *tmPtr, int fontType,
			    LPARAM lParam);

/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
253
254
255
256
257
258
259










260
261
262
263
264
265
266
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{










    TkWinSetupSystemFonts(mainPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --







>
>
>
>
>
>
>
>
>
>







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
 *-------------------------------------------------------------------------
 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	/*
	 * If running NT, then we will be calling some Unicode functions
	 * explictly. So, even if the Tcl system encoding isn't Unicode, make
	 * sure we convert to/from the Unicode char set.
	 */

	systemEncoding = TkWinGetUnicodeEncoding();
    }

    TkWinSetupSystemFonts(mainPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    int object;
    WinFont *fontPtr;

    object = TkFindStateNum(NULL, NULL, systemMap, name);
    if (object < 0) {
	return NULL;
    }

    tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
    fontPtr = (WinFont *)ckalloc(sizeof(WinFont));
    InitFont(tkwin, (HFONT)GetStockObject(object), 0, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * CreateNamedSystemFont --
 *
 *	This function registers a Windows logical font description with the Tk
 *	named font mechanism.
 *
 * Side effects:

 *	A new named font is added to the Tk font registry.
 *
 *---------------------------------------------------------------------------
 */

static int
CreateNamedSystemLogFont(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    const char* name,
    LOGFONTW* logFontPtr)
{
    HFONT hFont;
    int r;

    hFont = CreateFontIndirectW(logFontPtr);
    r = CreateNamedSystemFont(interp, tkwin, name, hFont);
    DeleteObject((HGDIOBJ)hFont);
    return r;
}

/*
 *---------------------------------------------------------------------------
 *
 * CreateNamedSystemFont --
 *
 *	This function registers a Windows font with the Tk named font
 *	mechanism.
 *
 * Side effects:

 *	A new named font is added to the Tk font registry.
 *
 *---------------------------------------------------------------------------
 */

static int
CreateNamedSystemFont(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    const char* name,
    HFONT hFont)
{
    WinFont winfont;
    int r;

    TkDeleteNamedFont(NULL, tkwin, name);
    InitFont(tkwin, hFont, 0, &winfont);
    r = TkCreateNamedFont(interp, tkwin, name, &winfont.font.fa);
    TkpDeleteFont((TkFont *)&winfont);
    return r;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkWinSystemFonts --
 *
 *	Create some platform specific named fonts that to give access to the
 *	system fonts. These are all defined for the Windows desktop
 *	parameters.
 *
 *---------------------------------------------------------------------------
 */

void
TkWinSetupSystemFonts(
    TkMainInfo *mainPtr)
{
    Tcl_Interp *interp;
    Tk_Window tkwin;
    const TkStateMap *mapPtr;
    NONCLIENTMETRICSW ncMetrics;
    ICONMETRICSW iconMetrics;
    HFONT hFont;

    interp = (Tcl_Interp *) mainPtr->interp;
    tkwin = (Tk_Window) mainPtr->winPtr;

    /* force this for now */
    if (((TkWindow *) tkwin)->mainPtr == NULL) {
	((TkWindow *) tkwin)->mainPtr = mainPtr;
    }

    /*
     * If this API call fails then we will fallback to setting these named
     * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when
     * WINVER has been defined for a higher platform than we are running on.
     * (i.e. WINVER=0x0600 and running on XP).
     */

    ZeroMemory(&ncMetrics, sizeof(ncMetrics));
    ncMetrics.cbSize = sizeof(ncMetrics);
    if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
	    sizeof(ncMetrics), &ncMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont",
		&ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont",
		&ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkTextFont",
		&ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont",
		&ncMetrics.lfMenuFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont",
		&ncMetrics.lfStatusFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont",
		&ncMetrics.lfCaptionFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont",
		&ncMetrics.lfSmCaptionFont);
    }

    iconMetrics.cbSize = sizeof(iconMetrics);
    if (SystemParametersInfoW(SPI_GETICONMETRICS, sizeof(iconMetrics),
	    &iconMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkIconFont",
		&iconMetrics.lfFont);
    }

    /*
     * Identify an available fixed font. Equivalent to ANSI_FIXED_FONT but
     * more reliable on Russian Windows.
     */

    {
	LOGFONTW lfFixed = {
	    0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
	    0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L""
	};
	long pointSize, dpi;
	HDC hdc = GetDC(NULL);
	dpi = GetDeviceCaps(hdc, LOGPIXELSY);
	pointSize = -MulDiv(ncMetrics.lfMessageFont.lfHeight, 72, dpi);
	lfFixed.lfHeight = -MulDiv(pointSize+1, dpi, 72);
	ReleaseDC(NULL, hdc);
	CreateNamedSystemLogFont(interp, tkwin, "TkFixedFont", &lfFixed);
    }

    /*
     * Setup the remaining standard Tk font names as named fonts.
     */

    for (mapPtr = systemMap; mapPtr->strKey != NULL; mapPtr++) {
	hFont = (HFONT) GetStockObject(mapPtr->numKey);
	CreateNamedSystemFont(interp, tkwin, mapPtr->strKey, hFont);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFromAttributes --







|










|
|






<





|
>









|
|




|







<


|
|

|
>









|














<



|
<





|
<




|
|







|



|
|
|
|




|


|

|

|

|

|

|

|



|


|








|

|















|
|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384

385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST char *name)		/* Platform-specific font name. */
{
    int object;
    WinFont *fontPtr;

    object = TkFindStateNum(NULL, NULL, systemMap, name);
    if (object < 0) {
	return NULL;
    }

    tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
    fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
    InitFont(tkwin, GetStockObject(object), 0, fontPtr);

    return (TkFont *) fontPtr;
}

/*
 *---------------------------------------------------------------------------

 * CreateNamedSystemFont --
 *
 *	This function registers a Windows logical font description with the Tk
 *	named font mechanism.
 *
 * Side effects
 *
 *	A new named font is added to the Tk font registry.
 *
 *---------------------------------------------------------------------------
 */

static int
CreateNamedSystemLogFont(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    CONST char* name,
    LOGFONTA* logFontPtr)
{
    HFONT hFont;
    int r;

    hFont = CreateFontIndirect(logFontPtr);
    r = CreateNamedSystemFont(interp, tkwin, name, hFont);
    DeleteObject((HGDIOBJ)hFont);
    return r;
}

/*
 *---------------------------------------------------------------------------

 * CreateNamedSystemFont --
 *
 *	This function registers a Windows font with the Tk
 *	named font mechanism.
 *
 * Side effects
 *
 *	A new named font is added to the Tk font registry.
 *
 *---------------------------------------------------------------------------
 */

static int
CreateNamedSystemFont(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    CONST char* name,
    HFONT hFont)
{
    WinFont winfont;
    int r;

    TkDeleteNamedFont(NULL, tkwin, name);
    InitFont(tkwin, hFont, 0, &winfont);
    r = TkCreateNamedFont(interp, tkwin, name, &winfont.font.fa);
    TkpDeleteFont((TkFont *)&winfont);
    return r;
}

/*
 *---------------------------------------------------------------------------

 * TkWinSystemFonts --
 *
 *	Create some platform specific named fonts that to give access to the
 *	system fonts. These are all defined for the Windows desktop parameters.

 *
 *---------------------------------------------------------------------------
 */

void
TkWinSetupSystemFonts(TkMainInfo *mainPtr)

{
    Tcl_Interp *interp;
    Tk_Window tkwin;
    const TkStateMap *mapPtr;
    NONCLIENTMETRICS ncMetrics;
    ICONMETRICS iconMetrics;
    HFONT hFont;

    interp = (Tcl_Interp *) mainPtr->interp;
    tkwin = (Tk_Window) mainPtr->winPtr;

    /* force this for now */
    if (((TkWindow *) tkwin)->mainPtr == NULL) {
        ((TkWindow *) tkwin)->mainPtr = mainPtr;
    }

    /*
     * If this API call fails then we will fallback to setting these
     * named fonts from script in ttk/fonts.tcl. So far I've only
     * seen it fail when WINVER has been defined for a higher platform than
     * we are running on. (ie: WINVER=0x0600 and running on XP).
     */

    ZeroMemory(&ncMetrics, sizeof(ncMetrics));
    ncMetrics.cbSize = sizeof(ncMetrics);
    if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
	    sizeof(ncMetrics), &ncMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont",
	    &ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont",
	    &ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkTextFont",
	    &ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont",
	    &ncMetrics.lfMenuFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont",
	    &ncMetrics.lfStatusFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont",
	    &ncMetrics.lfCaptionFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont",
	    &ncMetrics.lfSmCaptionFont);
    }

    iconMetrics.cbSize = sizeof(iconMetrics);
    if (SystemParametersInfo(SPI_GETICONMETRICS, sizeof(iconMetrics),
	    &iconMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkIconFont",
	    &iconMetrics.lfFont);
    }

    /*
     * Identify an available fixed font. Equivalent to ANSI_FIXED_FONT but
     * more reliable on Russian Windows.
     */

    {
	LOGFONTA lfFixed = {
	    0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
	    0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, ""
	};
	long pointSize, dpi;
	HDC hdc = GetDC(NULL);
	dpi = GetDeviceCaps(hdc, LOGPIXELSY);
	pointSize = -MulDiv(ncMetrics.lfMessageFont.lfHeight, 72, dpi);
	lfFixed.lfHeight = -MulDiv(pointSize+1, dpi, 72);
	ReleaseDC(NULL, hdc);
	CreateNamedSystemLogFont(interp, tkwin, "TkFixedFont", &lfFixed);
    }

    /*
     * Setup the remaining standard Tk font names as named fonts.
     */

    for (mapPtr = systemMap; mapPtr->strKey != NULL; mapPtr++) {
        hFont = (HFONT)GetStockObject(mapPtr->numKey);
        CreateNamedSystemFont(interp, tkwin, mapPtr->strKey, hFont);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetFontFromAttributes --
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    int i, j;
    HDC hdc;
    HWND hwnd;
    HFONT hFont;
    Window window;
    WinFont *fontPtr;
    const char *const *const *fontFallbacks;
    Tk_Uid faceName, fallback, actualName;

    tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);








|








|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
    TkFont *tkFontPtr,		/* If non-NULL, store the information in this
				 * existing TkFont structure, rather than
				 * allocating a new structure to hold the
				 * font; the existing contents of the font
				 * will be released. If NULL, a new TkFont
				 * structure is allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    CONST TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    int i, j;
    HDC hdc;
    HWND hwnd;
    HFONT hFont;
    Window window;
    WinFont *fontPtr;
    char ***fontFallbacks;
    Tk_Uid faceName, fallback, actualName;

    tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
	}
    }

  found:
    ReleaseDC(hwnd, hdc);

    hFont = GetScreenFont(faPtr, faceName,
	    (int)(TkFontGetPixels(tkwin, faPtr->size) + 0.5), 0.0);
    if (tkFontPtr == NULL) {
	fontPtr = (WinFont *)ckalloc(sizeof(WinFont));
    } else {
	fontPtr = (WinFont *) tkFontPtr;
	ReleaseFont(fontPtr);
    }
    InitFont(tkwin, hFont, faPtr->overstrike, fontPtr);

    return (TkFont *) fontPtr;







|

|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
	}
    }

  found:
    ReleaseDC(hwnd, hdc);

    hFont = GetScreenFont(faPtr, faceName,
	    TkFontGetPixels(tkwin, faPtr->size));
    if (tkFontPtr == NULL) {
	fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
    } else {
	fontPtr = (WinFont *) tkFontPtr;
	ReleaseFont(fontPtr);
    }
    InitFont(tkwin, hFont, faPtr->overstrike, fontPtr);

    return (TkFont *) fontPtr;
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648
649




650
651
652
653
654
655
656
657
658
659
660
661
662
663


664



665
666
667
668
669
670
671
672
673
674
675
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    HDC hdc;
    HWND hwnd;
    Window window;
    Tcl_Obj *resultObj;

    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);
    resultObj = Tcl_NewObj();

    /*
     * On any version NT, there may fonts with international names. Use the
     * NT-only Unicode version of EnumFontFamilies to get the font names. If
     * we used the ANSI version on a non-internationalized version of NT, we
     * would get font names with '?' replacing all the international
     * characters.
     *
     * On a non-internationalized verson of 95, fonts with international names
     * are not allowed, so the ANSI version of EnumFontFamilies will work. On
     * an internationalized version of 95, there may be fonts with
     * international names; the ANSI version will work, fetching the name in
     * the system code page. Can't use the Unicode version of EnumFontFamilies
     * because it only exists under NT.
     */


    EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontFamilyEnumProc,
	    (LPARAM) resultObj);




    ReleaseDC(hwnd, hdc);
    Tcl_SetObjResult(interp, resultObj);
}

static int CALLBACK
WinFontFamilyEnumProc(
    ENUMLOGFONTW *lfPtr,		/* Logical-font data. */
    TCL_UNUSED(NEWTEXTMETRIC *),	/* Physical-font data (not used). */
    TCL_UNUSED(int),		/* Type of font (not used). */
    LPARAM lParam)		/* Result object to hold result. */
{
    WCHAR *faceName = lfPtr->elfLogFont.lfFaceName;
    Tcl_Obj *resultObj = (Tcl_Obj *) lParam;
    Tcl_DString faceString;






    Tcl_DStringInit(&faceString);
    Tcl_WCharToUtfDString(faceName, wcslen(faceName), &faceString);
    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
	    Tcl_DStringValue(&faceString), Tcl_DStringLength(&faceString)));
    Tcl_DStringFree(&faceString);
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *







<




<
















>
|
|
>
>
>
>

<




|
|
|


|
<

>
>

>
>
>
|
|
|
<







625
626
627
628
629
630
631

632
633
634
635

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    HDC hdc;
    HWND hwnd;
    Window window;


    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);


    /*
     * On any version NT, there may fonts with international names. Use the
     * NT-only Unicode version of EnumFontFamilies to get the font names. If
     * we used the ANSI version on a non-internationalized version of NT, we
     * would get font names with '?' replacing all the international
     * characters.
     *
     * On a non-internationalized verson of 95, fonts with international names
     * are not allowed, so the ANSI version of EnumFontFamilies will work. On
     * an internationalized version of 95, there may be fonts with
     * international names; the ANSI version will work, fetching the name in
     * the system code page. Can't use the Unicode version of EnumFontFamilies
     * because it only exists under NT.
     */

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontFamilyEnumProc,
		(LPARAM) interp);
    } else {
	EnumFontFamiliesA(hdc, NULL, (FONTENUMPROCA) WinFontFamilyEnumProc,
		(LPARAM) interp);
    }
    ReleaseDC(hwnd, hdc);

}

static int CALLBACK
WinFontFamilyEnumProc(
    ENUMLOGFONT *lfPtr,		/* Logical-font data. */
    NEWTEXTMETRIC *tmPtr,	/* Physical-font data (not used). */
    int fontType,		/* Type of font (not used). */
    LPARAM lParam)		/* Result object to hold result. */
{
    char *faceName;

    Tcl_DString faceString;
    Tcl_Obj *strPtr;
    Tcl_Interp *interp;

    interp = (Tcl_Interp *) lParam;
    faceName = lfPtr->elfLogFont.lfFaceName;
    Tcl_ExternalToUtfDString(systemEncoding, faceName, -1, &faceString);
    strPtr = Tcl_NewStringObj(Tcl_DStringValue(&faceString),
	    Tcl_DStringLength(&faceString));
    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), strPtr);

    Tcl_DStringFree(&faceString);
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    Tk_Font tkfont)		/* Font object to query. */
{
    int i;
    WinFont *fontPtr;
    FontFamily *familyPtr;
    Tcl_Obj *resultPtr, *strPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (WinFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	strPtr = Tcl_NewStringObj(familyPtr->faceName, -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *







|






<







705
706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
    Tk_Font tkfont)		/* Font object to query. */
{
    int i;
    WinFont *fontPtr;
    FontFamily *familyPtr;
    Tcl_Obj *resultPtr, *strPtr;

    resultPtr = Tcl_GetObjResult(interp);
    fontPtr = (WinFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	strPtr = Tcl_NewStringObj(familyPtr->faceName, -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    WinFont *fontPtr = (WinFont *) tkfont;
				/* Structure describing the logical font */
    HDC hdc = GetDC(fontPtr->hwnd);
				/* GDI device context */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
				 * FindSubFontForChar needs to fix up the
				 * memory allocation */
    SubFont *thisSubFontPtr =
	    FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
				/* Pointer to the subfont to use for the given
				 * character */
    FontFamily *familyPtr = thisSubFontPtr->familyPtr;
    HFONT oldfont;		/* Saved font from the device context */
    TEXTMETRICW tm;		/* Font metrics of the selected subfont */

    /*
     * Get the font attributes.
     */

    oldfont = (HFONT)SelectObject(hdc, thisSubFontPtr->hFont0);
    GetTextMetricsW(hdc, &tm);
    SelectObject(hdc, oldfont);
    ReleaseDC(fontPtr->hwnd, hdc);
    faPtr->family = familyPtr->faceName;
    faPtr->size = TkFontGetPoints(tkwin,
	    (double)(tm.tmInternalLeading - tm.tmHeight));
    faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = (tm.tmUnderlined != 0);
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_MeasureChars --
 *
 *	Determine the number of bytes 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.
 *
 * Results:
 *	The return value is the number of bytes from source that fit into the
 *	span that extends from 0 to maxLength. *lengthPtr is filled with the
 *	x-coordinate of the right edge of the last character that did fit.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length







|
|







|
|
|
|
|
|


|





|
|




|









|



















|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    Tcl_UniChar c,		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    WinFont *fontPtr = (WinFont *) tkfont;
				/* Structure describing the logical font */
    HDC hdc = GetDC(fontPtr->hwnd);
				/* GDI device context */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
				 * FindSubFontForChar needs to fix up
				 * the memory allocation */
    SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c,
						 &lastSubFontPtr);
				/* Pointer to the subfont to use for
				 * the given character */
    FontFamily *familyPtr = thisSubFontPtr->familyPtr;
    HFONT oldfont;		/* Saved font from the device context */
    TEXTMETRIC tm;		/* Font metrics of the selected subfont */

    /*
     * Get the font attributes.
     */

    oldfont = SelectObject(hdc, thisSubFontPtr->hFont);
    GetTextMetrics(hdc, &tm);
    SelectObject(hdc, oldfont);
    ReleaseDC(fontPtr->hwnd, hdc);
    faPtr->family = familyPtr->faceName;
    faPtr->size = TkFontGetPoints(tkwin,
	    tm.tmInternalLeading - tm.tmHeight);
    faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = (tm.tmUnderlined != 0);
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

/*
 *---------------------------------------------------------------------------
 *
 *  Tk_MeasureChars --
 *
 *	Determine the number of bytes 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.
 *
 * Results:
 *	The return value is the number of bytes from source that fit into the
 *	span that extends from 0 to maxLength. *lengthPtr is filled with the
 *	x-coordinate of the right edge of the last character that did fit.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883

884
885
886
887
888
889
890
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    HDC hdc;
    HFONT oldFont;
    WinFont *fontPtr;
    int curX, moretomeasure;
    int ch;
    SIZE size;
    FontFamily *familyPtr;
    Tcl_DString runString;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    const char *p, *end, *next = NULL, *start;

    if (numBytes == 0) {
	*lengthPtr = 0;
	return 0;
    }

    fontPtr = (WinFont *) tkfont;

    hdc = GetDC(fontPtr->hwnd);
    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = (HFONT)SelectObject(hdc, lastSubFontPtr->hFont0);

    /*
     * A three step process:
     * 1. Find a contiguous range of characters that can all be represented by
     *    a single screen font.
     * 2. Convert those chars to the encoding of that font.
     * 3. Measure converted chars.
     */

    moretomeasure = 0;
    curX = 0;
    start = source;
    end = start + numBytes;
    for (p = start; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	if (thisSubFontPtr != lastSubFontPtr) {
	    familyPtr = lastSubFontPtr->familyPtr;
	    Tcl_UtfToExternalDString(familyPtr->encoding, start,
		    (int) (p - start), &runString);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc,
		    (WCHAR *)Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    Tcl_DStringFree(&runString);
	    if (maxLength >= 0 && (curX+size.cx) > maxLength) {
		moretomeasure = 1;
		break;
	    }
	    curX += size.cx;
	    lastSubFontPtr = thisSubFontPtr;
	    start = p;

	    SelectObject(hdc, lastSubFontPtr->hFont0);
	}
	p = next;
    }

    if (!moretomeasure) {
	/*
	 * We get here if the previous loop was just finished normally,
	 * without a break. Just measure the last run and that's it.
	 */

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_UtfToExternalDString(familyPtr->encoding, start,
		(int) (p - start), &runString);
	size.cx = 0;
	familyPtr->getTextExtentPoint32Proc(hdc, (WCHAR *) Tcl_DStringValue(&runString),

		Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		&size);
	Tcl_DStringFree(&runString);
	if (maxLength >= 0 && (curX+size.cx) > maxLength) {
	    moretomeasure = 1;
	} else {
	    curX += size.cx;







|




|










|














|






|
|











|














|
>







820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    HDC hdc;
    HFONT oldFont;
    WinFont *fontPtr;
    int curX, moretomeasure;
    Tcl_UniChar ch;
    SIZE size;
    FontFamily *familyPtr;
    Tcl_DString runString;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    CONST char *p, *end, *next = NULL, *start;

    if (numBytes == 0) {
	*lengthPtr = 0;
	return 0;
    }

    fontPtr = (WinFont *) tkfont;

    hdc = GetDC(fontPtr->hwnd);
    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectObject(hdc, lastSubFontPtr->hFont);

    /*
     * A three step process:
     * 1. Find a contiguous range of characters that can all be represented by
     *    a single screen font.
     * 2. Convert those chars to the encoding of that font.
     * 3. Measure converted chars.
     */

    moretomeasure = 0;
    curX = 0;
    start = source;
    end = start + numBytes;
    for (p = start; p < end; ) {
	next = p + Tcl_UtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	if (thisSubFontPtr != lastSubFontPtr) {
	    familyPtr = lastSubFontPtr->familyPtr;
	    Tcl_UtfToExternalDString(familyPtr->encoding, start,
		    (int) (p - start), &runString);
	    size.cx = 0;
	    (*familyPtr->getTextExtentPoint32Proc)(hdc,
		    Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    Tcl_DStringFree(&runString);
	    if (maxLength >= 0 && (curX+size.cx) > maxLength) {
		moretomeasure = 1;
		break;
	    }
	    curX += size.cx;
	    lastSubFontPtr = thisSubFontPtr;
	    start = p;

	    SelectObject(hdc, lastSubFontPtr->hFont);
	}
	p = next;
    }

    if (!moretomeasure) {
	/*
	 * We get here if the previous loop was just finished normally,
	 * without a break. Just measure the last run and that's it.
	 */

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_UtfToExternalDString(familyPtr->encoding, start,
		(int) (p - start), &runString);
	size.cx = 0;
	(*familyPtr->getTextExtentPoint32Proc)(hdc,
		Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		&size);
	Tcl_DStringFree(&runString);
	if (maxLength >= 0 && (curX+size.cx) > maxLength) {
	    moretomeasure = 1;
	} else {
	    curX += size.cx;
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
	char buf[16];
	int dstWrote;
	int lastSize = 0;

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_DStringInit(&runString);
	for (p = start; p < end; ) {
	    next = p + TkUtfToUniChar(p, &ch);
	    Tcl_UtfToExternal(NULL, familyPtr->encoding, p,
		    (int) (next - p), 0, NULL, buf, sizeof(buf), NULL,
		    &dstWrote, NULL);
	    Tcl_DStringAppend(&runString,buf,dstWrote);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc,
		    (WCHAR *) Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    if ((curX+size.cx) > maxLength) {
		break;
	    }
	    lastSize = size.cx;
	    p = next;







|





|
|







914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
	char buf[16];
	int dstWrote;
	int lastSize = 0;

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_DStringInit(&runString);
	for (p = start; p < end; ) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    Tcl_UtfToExternal(NULL, familyPtr->encoding, p,
		    (int) (next - p), 0, NULL, buf, sizeof(buf), NULL,
		    &dstWrote, NULL);
	    Tcl_DStringAppend(&runString,buf,dstWrote);
	    size.cx = 0;
	    (*familyPtr->getTextExtentPoint32Proc)(hdc,
		    Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    if ((curX+size.cx) > maxLength) {
		break;
	    }
	    lastSize = size.cx;
	    p = next;
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999

    if ((flags & TK_WHOLE_WORDS) && (p < end)) {
	/*
	 * Scan the string for the last word break and than repeat the whole
	 * procedure without the maxLength limit or any flags.
	 */

	const char *lastWordBreak = NULL;
	int ch2;

	end = p;
	p = source;
	ch = ' ';
	while (p < end) {
	    next = p + TkUtfToUniChar(p, &ch2);
	    if ((ch != ' ') && (ch2 == ' ')) {
		lastWordBreak = p;
	    }
	    p = next;
	    ch = ch2;
	}

	if (lastWordBreak != NULL) {
	    return Tk_MeasureChars(tkfont, source, lastWordBreak-source,
		    -1, 0, lengthPtr);
	}
	if (flags & TK_AT_LEAST_ONE) {
	    p = end;
	} else {
	    p = source;
	    curX = 0;
	}
    }

    *lengthPtr = curX;
    return (int)(p - source);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpMeasureCharsInContext --
 *
 *	Determine the number of bytes from the string that will fit in the
 *	given horizontal span. The measurement is done under the assumption
 *	that TkpDrawCharsInContext() will be used to actually display the
 *	characters.
 *
 *	This one is almost the same as Tk_MeasureChars(), but with access to







|
|





|




















|





|







962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

    if ((flags & TK_WHOLE_WORDS) && (p < end)) {
	/*
	 * Scan the string for the last word break and than repeat the whole
	 * procedure without the maxLength limit or any flags.
	 */

	CONST char *lastWordBreak = NULL;
	Tcl_UniChar ch2;

	end = p;
	p = source;
	ch = ' ';
	while (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch2);
	    if ((ch != ' ') && (ch2 == ' ')) {
		lastWordBreak = p;
	    }
	    p = next;
	    ch = ch2;
	}

	if (lastWordBreak != NULL) {
	    return Tk_MeasureChars(tkfont, source, lastWordBreak-source,
		    -1, 0, lengthPtr);
	}
	if (flags & TK_AT_LEAST_ONE) {
	    p = end;
	} else {
	    p = source;
	    curX = 0;
	}
    }

    *lengthPtr = curX;
    return p - source;
}

/*
 *---------------------------------------------------------------------------
 *
 *  TkpMeasureCharsInContext --
 *
 *	Determine the number of bytes from the string that will fit in the
 *	given horizontal span. The measurement is done under the assumption
 *	that TkpDrawCharsInContext() will be used to actually display the
 *	characters.
 *
 *	This one is almost the same as Tk_MeasureChars(), but with access to
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
 *
 *---------------------------------------------------------------------------
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(int),		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and







|

|







1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
 *
 *---------------------------------------------------------------------------
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
				 * no characters fit. TK_ISOLATE_END means
				 * that the last character should not be
				 * considered in context with the rest of the
				 * string (used for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *---------------------------------------------------------------------------
 *







>







1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
				 * no characters fit. TK_ISOLATE_END means
				 * that the last character should not be
				 * considered in context with the rest of the
				 * string (used for breaking lines). */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    (void) numBytes; /*unused*/
    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *---------------------------------------------------------------------------
 *
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
 */

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    TCL_UNUSED(Tk_Font),	/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */







|

|







1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
 */

void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

    SetROP2(dc, tkpWinRopModes[gc->function]);

    if ((gc->clip_mask != None) &&
	    ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) {
	SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region);
    }

    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *) gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
	 * Select stipple pattern into destination dc.
	 */

	dcMem = CreateCompatibleDC(dc);

	stipple = CreatePatternBrush(twdPtr->bitmap.handle);
	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = (HBRUSH)SelectObject(dc, stipple);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
	 * bits. Then we draw onto a white background and copy the black bits.
	 * Both the foreground and background bits of the font are ANDed with
	 * the stipple pattern as they are copied.
	 */

	PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0xEA02E9);
	PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0x8A0E06);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);
	DeleteObject(bitmap);
	DeleteDC(dcMem);
	SelectObject(dc, oldBrush);
	DeleteObject(stipple);
    } else if (gc->function == GXcopy) {
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		0.0);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, (DWORD) tkpWinBltModes[gc->function]);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);
	DeleteObject(bitmap);
	DeleteDC(dcMem);
    }
    TkWinReleaseDrawableDC(drawable, dc, &state);
}

void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    TCL_UNUSED(Tk_Font),	/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    display->request++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

    SetROP2(dc, tkpWinRopModes[gc->function]);

    if ((gc->clip_mask != None) &&
	    ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) {
	SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region);
    }

    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
	 * Select stipple pattern into destination dc.
	 */

	dcMem = CreateCompatibleDC(dc);

	stipple = CreatePatternBrush(twdPtr->bitmap.handle);
	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = (HBRUSH)SelectObject(dc, stipple);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
	 * bits. Then we draw onto a white background and copy the black bits.
	 * Both the foreground and background bits of the font are ANDed with
	 * the stipple pattern as they are copied.
	 */

	PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle);
	BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0xEA02E9);
	PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle);
	BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0x8A0E06);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);
	DeleteObject(bitmap);
	DeleteDC(dcMem);
	SelectObject(dc, oldBrush);
	DeleteObject(stipple);
    } else if (gc->function == GXcopy) {
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		angle);
	BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, (DWORD) tkpWinBltModes[gc->function]);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);







|
|





|



|














|










|
|


|










|



|
















|



|













|
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202









































































1203











































































1204

1205
1206
1207
1208
1209
1210
1211
1212
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

    SetROP2(dc, tkpWinRopModes[gc->function]);

    if ((gc->clip_mask != None) &&
	    ((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
	SelectClipRgn(dc, (HRGN)((TkpClipMask*)gc->clip_mask)->value.region);
    }

    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
	 * Select stipple pattern into destination dc.
	 */

	dcMem = CreateCompatibleDC(dc);

	stipple = CreatePatternBrush(twdPtr->bitmap.handle);
	SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
	oldBrush = SelectObject(dc, stipple);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPoint(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
	 * bits. Then we draw onto a white background and copy the black bits.
	 * Both the foreground and background bits of the font are ANDed with
	 * the stipple pattern as they are copied.
	 */

	PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0xEA02E9);
	PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, 0x8A0E06);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);
	DeleteObject(bitmap);
	DeleteDC(dcMem);
	SelectObject(dc, oldBrush);
	DeleteObject(stipple);
    } else if (gc->function == GXcopy) {
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPoint(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);





















































































































































	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent);

	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
		0, 0, (DWORD) tkpWinBltModes[gc->function]);

	/*
	 * Destroy the temporary bitmap and restore the device context.
	 */

	SelectObject(dcMem, oldBitmap);
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On Windows
 *	this context isn't consulted, so we just call Tk_DrawChars().
  *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
*
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(int),		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);
    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
 *-------------------------------------------------------------------------
 *
 * MultiFontTextOut --
 *







|
<
<
<
















|






|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
|







1220
1221
1222
1223
1224
1225
1226
1227



1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257































1258


1259
1260
1261
1262
1263
1264
1265
1266
1267
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On Windows
 *	this context isn't consulted, so we just call Tk_DrawChars().
 *



 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{































    (void) numBytes; /*unused*/


    Tk_DrawChars(display, drawable, gc, tkfont,
	    source + rangeStart, rangeLength, x, y);
}

/*
 *-------------------------------------------------------------------------
 *
 * MultiFontTextOut --
 *
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
 */

static void
MultiFontTextOut(
    HDC hdc,			/* HDC to draw into. */
    WinFont *fontPtr,		/* Contains set of fonts to use when drawing
				 * following string. */
    const char *source,		/* Potentially multilingual UTF-8 string. */
    int numBytes,		/* Length of string in bytes. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)
{
    int ch;
    SIZE size;
    HFONT oldFont;
    FontFamily *familyPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    SubFont *lastSubFontPtr, *thisSubFontPtr;
    TEXTMETRICW tm;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
    GetTextMetricsW(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
	 * The drawing API has a limit of 32767 pixels in one go.
	 * To avoid spending time on a rare case we do not measure each char,
	 * instead we limit to drawing chunks of 200 bytes since that works
	 * well in practice.
	 */

	if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) {
	    if (p > source) {
		familyPtr = lastSubFontPtr->familyPtr;
 		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			(int) (p - source), &runString);
		familyPtr->textOutProc(hdc, x-((double)tm.tmOverhang/2), y,
			(WCHAR *)Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
		familyPtr->getTextExtentPoint32Proc(hdc,
			(WCHAR *)Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
			&size);
		x += cosA*size.cx;
		y -= sinA*size.cx;
		Tcl_DStringFree(&runString);
	    }
	    lastSubFontPtr = thisSubFontPtr;
	    source = p;
	    SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
	    GetTextMetricsW(hdc, &tm);
	}
	p = next;
    }
    if (p > source) {
	familyPtr = lastSubFontPtr->familyPtr;
 	Tcl_UtfToExternalDString(familyPtr->encoding, source,
		(int) (p - source), &runString);
	familyPtr->textOutProc(hdc, x-((double)tm.tmOverhang/2), y,
		(WCHAR *)Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
	Tcl_DStringFree(&runString);
    }
    SelectObject(hdc, oldFont);
}

static inline HFONT
SelectFont(
    HDC hdc,
    WinFont *fontPtr,
    SubFont *subFontPtr,
    double angle)
{
    if (angle == 0.0) {
	return (HFONT)SelectObject(hdc, subFontPtr->hFont0);
    } else if (angle == subFontPtr->angle) {
	return (HFONT)SelectObject(hdc, subFontPtr->hFontAngled);
    } else {
	if (subFontPtr->hFontAngled) {
	    DeleteObject(subFontPtr->hFontAngled);
	}
	subFontPtr->hFontAngled = GetScreenFont(&fontPtr->font.fa,
		subFontPtr->familyPtr->faceName, fontPtr->pixelSize, angle);
	if (subFontPtr->hFontAngled == NULL) {
	    return (HFONT)SelectObject(hdc, subFontPtr->hFont0);
	}
	subFontPtr->angle = angle;
	return (HFONT)SelectObject(hdc, subFontPtr->hFontAngled);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * InitFont --
 *
 *	Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().







|

|

<

|




|

|
<


|
|



|














|
|
|
|
|


|
<




|
|







|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291

1292
1293
1294
1295
1296
1297
1298
1299
1300

1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330

1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350

























1351
1352
1353
1354
1355
1356
1357
 */

static void
MultiFontTextOut(
    HDC hdc,			/* HDC to draw into. */
    WinFont *fontPtr,		/* Contains set of fonts to use when drawing
				 * following string. */
    CONST char *source,		/* Potentially multilingual UTF-8 string. */
    int numBytes,		/* Length of string in bytes. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */

{
    Tcl_UniChar ch;
    SIZE size;
    HFONT oldFont;
    FontFamily *familyPtr;
    Tcl_DString runString;
    CONST char *p, *end, *next;
    SubFont *lastSubFontPtr, *thisSubFontPtr;
    TEXTMETRIC tm;


    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectObject(hdc, lastSubFontPtr->hFont);
    GetTextMetrics(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + Tcl_UtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
	 * The drawing API has a limit of 32767 pixels in one go.
	 * To avoid spending time on a rare case we do not measure each char,
	 * instead we limit to drawing chunks of 200 bytes since that works
	 * well in practice.
	 */

	if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) {
	    if (p > source) {
		familyPtr = lastSubFontPtr->familyPtr;
 		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			(int) (p - source), &runString);
		(*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y,
			Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString)>>familyPtr->isWideFont);
		(*familyPtr->getTextExtentPoint32Proc)(hdc,
			Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
			&size);
		x += size.cx;

		Tcl_DStringFree(&runString);
	    }
	    lastSubFontPtr = thisSubFontPtr;
	    source = p;
	    SelectObject(hdc, lastSubFontPtr->hFont);
	    GetTextMetrics(hdc, &tm);
	}
	p = next;
    }
    if (p > source) {
	familyPtr = lastSubFontPtr->familyPtr;
 	Tcl_UtfToExternalDString(familyPtr->encoding, source,
		(int) (p - source), &runString);
	(*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y,
		Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
	Tcl_DStringFree(&runString);
    }
    SelectObject(hdc, oldFont);
}


























/*
 *---------------------------------------------------------------------------
 *
 * InitFont --
 *
 *	Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
















1605



1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
static void
InitFont(
    Tk_Window tkwin,		/* Main window of interp in which font will be
				 * used, for getting HDC. */
    HFONT hFont,		/* Windows token for font. */
    int overstrike,		/* The overstrike attribute of logfont used to
				 * allocate this font. For some reason, the
				 * TEXTMETRICWs may contain incorrect info in
				 * the tmStruckOut field. */
    WinFont *fontPtr)		/* Filled with information constructed from
				 * the above arguments. */
{
    HDC hdc;
    HWND hwnd;
    HFONT oldFont;
    TEXTMETRICW tm;
    Window window;
    TkFontMetrics *fmPtr;
    Tcl_Encoding encoding;
    Tcl_DString faceString;
    TkFontAttributes *faPtr;
    WCHAR buf[LF_FACESIZE];

    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);
    oldFont = (HFONT)SelectObject(hdc, hFont);

    GetTextMetricsW(hdc, &tm);

















    GetTextFaceW(hdc, LF_FACESIZE, buf);



    Tcl_DStringInit(&faceString);
    Tcl_WCharToUtfDString(buf, wcslen(buf), &faceString);

    fontPtr->font.fid	= (Font) fontPtr;
    fontPtr->hwnd	= hwnd;
    fontPtr->pixelSize	= tm.tmHeight - tm.tmInternalLeading;

    faPtr		= &fontPtr->font.fa;
    faPtr->family	= Tk_GetUid(Tcl_DStringValue(&faceString));

    faPtr->size =
	TkFontGetPoints(tkwin,  (double)-(fontPtr->pixelSize));
    faPtr->weight =
	    (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant	= (tm.tmItalic != 0) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline	= (tm.tmUnderlined != 0) ? 1 : 0;
    faPtr->overstrike	= overstrike;

    fmPtr		= &fontPtr->font.fm;







|







|





|




|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
<









|







1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
static void
InitFont(
    Tk_Window tkwin,		/* Main window of interp in which font will be
				 * used, for getting HDC. */
    HFONT hFont,		/* Windows token for font. */
    int overstrike,		/* The overstrike attribute of logfont used to
				 * allocate this font. For some reason, the
				 * TEXTMETRICs may contain incorrect info in
				 * the tmStruckOut field. */
    WinFont *fontPtr)		/* Filled with information constructed from
				 * the above arguments. */
{
    HDC hdc;
    HWND hwnd;
    HFONT oldFont;
    TEXTMETRIC tm;
    Window window;
    TkFontMetrics *fmPtr;
    Tcl_Encoding encoding;
    Tcl_DString faceString;
    TkFontAttributes *faPtr;
    char buf[LF_FACESIZE * sizeof(WCHAR)];

    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);
    oldFont = SelectObject(hdc, hFont);

    GetTextMetrics(hdc, &tm);

    /*
     * On any version NT, there may fonts with international names. Use the
     * NT-only Unicode version of GetTextFace to get the font's name. If we
     * used the ANSI version on a non-internationalized version of NT, we
     * would get a font name with '?' replacing all the international
     * characters.
     *
     * On a non-internationalized verson of 95, fonts with international names
     * are not allowed, so the ANSI version of GetTextFace will work. On an
     * internationalized version of 95, there may be fonts with international
     * names; the ANSI version will work, fetching the name in the
     * international system code page. Can't use the Unicode version of
     * GetTextFace because it only exists under NT.
     */

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	GetTextFaceW(hdc, LF_FACESIZE, (WCHAR *) buf);
    } else {
	GetTextFaceA(hdc, LF_FACESIZE, (char *) buf);
    }
    Tcl_ExternalToUtfDString(systemEncoding, buf, -1, &faceString);


    fontPtr->font.fid	= (Font) fontPtr;
    fontPtr->hwnd	= hwnd;
    fontPtr->pixelSize	= tm.tmHeight - tm.tmInternalLeading;

    faPtr		= &fontPtr->font.fa;
    faPtr->family	= Tk_GetUid(Tcl_DStringValue(&faceString));

    faPtr->size =
	    TkFontGetPoints(tkwin, -(fontPtr->pixelSize));
    faPtr->weight =
	    (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant	= (tm.tmItalic != 0) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline	= (tm.tmUnderlined != 0) ? 1 : 0;
    faPtr->overstrike	= overstrike;

    fmPtr		= &fontPtr->font.fm;
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
{
    int i;

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	ReleaseSubFont(&fontPtr->subFontArray[i]);
    }
    if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	ckfree(fontPtr->subFontArray);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * InitSubFont --







|







1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
{
    int i;

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	ReleaseSubFont(&fontPtr->subFontArray[i]);
    }
    if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	ckfree((char *) fontPtr->subFontArray);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * InitSubFont --
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static inline void
InitSubFont(
    HDC hdc,			/* HDC in which font can be selected. */
    HFONT hFont,		/* The screen font. */
    int base,			/* Non-zero if this SubFont is being used as
				 * the base font for a font object. */
    SubFont *subFontPtr)	/* Filled with SubFont constructed from above
    				 * attributes. */
{
    subFontPtr->hFont0	    = hFont;
    subFontPtr->familyPtr   = AllocFontFamily(hdc, hFont, base);
    subFontPtr->fontMap	    = subFontPtr->familyPtr->fontMap;
    subFontPtr->hFontAngled = NULL;
    subFontPtr->angle	    = 0.0;
}

/*
 *-------------------------------------------------------------------------
 *
 * ReleaseSubFont --
 *
 *	Called to release the contents of a SubFont. The caller is responsible
 *	for freeing the memory used by the SubFont itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and resources are freed.
 *
 *---------------------------------------------------------------------------
 */

static inline void
ReleaseSubFont(
    SubFont *subFontPtr)	/* The SubFont to delete. */
{
    DeleteObject(subFontPtr->hFont0);
    if (subFontPtr->hFontAngled) {
	DeleteObject(subFontPtr->hFontAngled);
    }
    FreeFontFamily(subFontPtr->familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * AllocFontFamily --







|








|


<
<



















|



|
<
<
<







1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523


1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547



1548
1549
1550
1551
1552
1553
1554
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static void
InitSubFont(
    HDC hdc,			/* HDC in which font can be selected. */
    HFONT hFont,		/* The screen font. */
    int base,			/* Non-zero if this SubFont is being used as
				 * the base font for a font object. */
    SubFont *subFontPtr)	/* Filled with SubFont constructed from above
    				 * attributes. */
{
    subFontPtr->hFont	    = hFont;
    subFontPtr->familyPtr   = AllocFontFamily(hdc, hFont, base);
    subFontPtr->fontMap	    = subFontPtr->familyPtr->fontMap;


}

/*
 *-------------------------------------------------------------------------
 *
 * ReleaseSubFont --
 *
 *	Called to release the contents of a SubFont. The caller is responsible
 *	for freeing the memory used by the SubFont itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and resources are freed.
 *
 *---------------------------------------------------------------------------
 */

static void
ReleaseSubFont(
    SubFont *subFontPtr)	/* The SubFont to delete. */
{
    DeleteObject(subFontPtr->hFont);



    FreeFontFamily(subFontPtr->familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * AllocFontFamily --
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782

1783



1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
 */

static FontFamily *
AllocFontFamily(
    HDC hdc,			/* HDC in which font can be selected. */
    HFONT hFont,		/* Screen font whose FontFamily is to be
				 * returned. */
    TCL_UNUSED(int))			/* Non-zero if this font family is to be used
				 * in the base font of a font object. */
{
    Tk_Uid faceName;
    FontFamily *familyPtr;
    Tcl_DString faceString;
    Tcl_Encoding encoding;
    WCHAR buf[LF_FACESIZE];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    hFont = (HFONT)SelectObject(hdc, hFont);

    GetTextFaceW(hdc, LF_FACESIZE, buf);



    Tcl_DStringInit(&faceString);
    Tcl_WCharToUtfDString(buf, wcslen(buf), &faceString);
    faceName = Tk_GetUid(Tcl_DStringValue(&faceString));
    Tcl_DStringFree(&faceString);
    hFont = (HFONT)SelectObject(hdc, hFont);

    familyPtr = tsdPtr->fontFamilyList;
    for ( ; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if (familyPtr->faceName == faceName) {
	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = (FontFamily *)ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
    familyPtr->nextPtr = tsdPtr->fontFamilyList;
    tsdPtr->fontFamilyList = familyPtr;

    /*
     * Set key for this FontFamily.
     */







|






|



|
>
|
>
>
>
|
<


|









|







1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
 */

static FontFamily *
AllocFontFamily(
    HDC hdc,			/* HDC in which font can be selected. */
    HFONT hFont,		/* Screen font whose FontFamily is to be
				 * returned. */
    int base)			/* Non-zero if this font family is to be used
				 * in the base font of a font object. */
{
    Tk_Uid faceName;
    FontFamily *familyPtr;
    Tcl_DString faceString;
    Tcl_Encoding encoding;
    char buf[LF_FACESIZE * sizeof(WCHAR)];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    hFont = SelectObject(hdc, hFont);
    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	GetTextFaceW(hdc, LF_FACESIZE, (WCHAR *) buf);
    } else {
	GetTextFaceA(hdc, LF_FACESIZE, (char *) buf);
    }
    Tcl_ExternalToUtfDString(systemEncoding, buf, -1, &faceString);

    faceName = Tk_GetUid(Tcl_DStringValue(&faceString));
    Tcl_DStringFree(&faceString);
    hFont = SelectObject(hdc, hFont);

    familyPtr = tsdPtr->fontFamilyList;
    for ( ; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if (familyPtr->faceName == faceName) {
	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
    familyPtr->nextPtr = tsdPtr->fontFamilyList;
    tsdPtr->fontFamilyList = familyPtr;

    /*
     * Set key for this FontFamily.
     */
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
	 * some other location.
	 */

	encoding = Tcl_GetEncoding(NULL, faceName);
    }

    if (encoding == NULL) {
	encoding = TkWinGetUnicodeEncoding();
	familyPtr->textOutProc =
	    (BOOL (WINAPI *)(HDC, int, int, WCHAR *, int)) TextOutW;
	familyPtr->getTextExtentPoint32Proc =
	    (BOOL (WINAPI *)(HDC, WCHAR *, int, LPSIZE)) GetTextExtentPoint32W;
	familyPtr->isWideFont = 1;
    } else {
	familyPtr->textOutProc =
	    (BOOL (WINAPI *)(HDC, int, int, WCHAR *, int)) TextOutA;
	familyPtr->getTextExtentPoint32Proc =
	    (BOOL (WINAPI *)(HDC, WCHAR *, int, LPSIZE)) GetTextExtentPoint32A;
	familyPtr->isWideFont = 0;
    }

    familyPtr->encoding = encoding;

    return familyPtr;
}







|

|

|



|

|







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
	 * some other location.
	 */

	encoding = Tcl_GetEncoding(NULL, faceName);
    }

    if (encoding == NULL) {
	encoding = Tcl_GetEncoding(NULL, "unicode");
	familyPtr->textOutProc =
	    (BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutW;
	familyPtr->getTextExtentPoint32Proc =
	    (BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32W;
	familyPtr->isWideFont = 1;
    } else {
	familyPtr->textOutProc =
	    (BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutA;
	familyPtr->getTextExtentPoint32Proc =
	    (BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32A;
	familyPtr->isWideFont = 0;
    }

    familyPtr->encoding = encoding;

    return familyPtr;
}
1883
1884
1885
1886
1887
1888
1889

1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
    FontFamily **familyPtrPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (familyPtr == NULL) {
	return;
    }

    if (familyPtr->refCount-- > 1) {
    	return;
    }
    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }
    if (familyPtr->startCount != NULL) {
	ckfree(familyPtr->startCount);
    }
    if (familyPtr->endCount != NULL) {
	ckfree(familyPtr->endCount);
    }
    if (familyPtr->encoding != TkWinGetUnicodeEncoding()) {
	Tcl_FreeEncoding(familyPtr->encoding);
    }

    /*
     * Delete from list.
     */

    for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) {
	if (*familyPtrPtr == familyPtr) {
	    *familyPtrPtr = familyPtr->nextPtr;
	    break;
	}
	familyPtrPtr = &(*familyPtrPtr)->nextPtr;
    }

    ckfree(familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * FindSubFontForChar --
 *







>
|








|


|











|





|







1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
    FontFamily **familyPtrPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
    	return;
    }
    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }
    if (familyPtr->startCount != NULL) {
	ckfree((char *) familyPtr->startCount);
    }
    if (familyPtr->endCount != NULL) {
	ckfree((char *) familyPtr->endCount);
    }
    if (familyPtr->encoding != TkWinGetUnicodeEncoding()) {
	Tcl_FreeEncoding(familyPtr->encoding);
    }

    /*
     * Delete from list.
     */

    for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) {
	if (*familyPtrPtr == familyPtr) {
  	    *familyPtrPtr = familyPtr->nextPtr;
	    break;
	}
	familyPtrPtr = &(*familyPtrPtr)->nextPtr;
    }

    ckfree((char *) familyPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * FindSubFontForChar --
 *
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
    int ch,			/* The Unicode character to be displayed. */
    SubFont **subFontPtrPtr)	/* Pointer to var to be fixed up if we
				 * reallocate the subfont table. */
{
    HDC hdc;
    int i, j, k;
    CanUse canUse;
    const char *const *aliases;
    const char *const *anyFallbacks;
    const char *const *const *fontFallbacks;
    const char *fallbackName;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if ((ch < BASE_CHARS) || (ch >= FONTMAP_NUMCHARS)) {
	return &fontPtr->subFontArray[0];
    }

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}







<
|
|
|



|







1763
1764
1765
1766
1767
1768
1769

1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
    int ch,			/* The Unicode character to be displayed. */
    SubFont **subFontPtrPtr)	/* Pointer to var to be fixed up if we
				 * reallocate the subfont table. */
{
    HDC hdc;
    int i, j, k;
    CanUse canUse;

    char **aliases, **anyFallbacks;
    char ***fontFallbacks;
    char *fallbackName;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if (ch < BASE_CHARS) {
	return &fontPtr->subFontArray[0];
    }

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}
2039
2040
2041
2042
2043
2044
2045

2046
2047




2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097

    canUse.hdc = hdc;
    canUse.fontPtr = fontPtr;
    canUse.nameTriedPtr = &ds;
    canUse.ch = ch;
    canUse.subFontPtr = NULL;
    canUse.subFontPtrPtr = subFontPtrPtr;

    EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontCanUseProc,
	    (LPARAM) &canUse);




    subFontPtr = canUse.subFontPtr;

  end:
    Tcl_DStringFree(&ds);

    if (subFontPtr == NULL) {
	/*
	 * No font can display this character. We will use the base font and
	 * have it display the "unknown" character.
	 */

	subFontPtr = &fontPtr->subFontArray[0];
	FontMapInsert(subFontPtr, ch);
    }
    ReleaseDC(fontPtr->hwnd, hdc);
    return subFontPtr;
}

static int CALLBACK
WinFontCanUseProc(
    ENUMLOGFONTW *lfPtr,		/* Logical-font data. */
    TCL_UNUSED(NEWTEXTMETRIC *),	/* Physical-font data (not used). */
    TCL_UNUSED(int),		/* Type of font (not used). */
    LPARAM lParam)		/* Result object to hold result. */
{
    int ch;
    HDC hdc;
    WinFont *fontPtr;
    CanUse *canUsePtr;
    char *fallbackName;
    SubFont *subFontPtr;
    Tcl_DString faceString;
    Tcl_DString *nameTriedPtr;

    canUsePtr	    = (CanUse *) lParam;
    ch		    = canUsePtr->ch;
    hdc		    = canUsePtr->hdc;
    fontPtr	    = canUsePtr->fontPtr;
    nameTriedPtr    = canUsePtr->nameTriedPtr;

    fallbackName = (char *) lfPtr->elfLogFont.lfFaceName;
    Tcl_DStringInit(&faceString);
    Tcl_WCharToUtfDString((WCHAR *)fallbackName, wcslen((WCHAR *)fallbackName), &faceString);
    fallbackName = Tcl_DStringValue(&faceString);

    if (SeenName(fallbackName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(hdc, fontPtr, fallbackName, ch,
		canUsePtr->subFontPtrPtr);
	if (subFontPtr != NULL) {
	    canUsePtr->subFontPtr = subFontPtr;







>
|
|
>
>
>
>







|












|
|
|

















|
|
<







1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909

1910
1911
1912
1913
1914
1915
1916

    canUse.hdc = hdc;
    canUse.fontPtr = fontPtr;
    canUse.nameTriedPtr = &ds;
    canUse.ch = ch;
    canUse.subFontPtr = NULL;
    canUse.subFontPtrPtr = subFontPtrPtr;
    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontCanUseProc,
		(LPARAM) &canUse);
    } else {
	EnumFontFamiliesA(hdc, NULL, (FONTENUMPROCA) WinFontCanUseProc,
		(LPARAM) &canUse);
    }
    subFontPtr = canUse.subFontPtr;

  end:
    Tcl_DStringFree(&ds);

    if (subFontPtr == NULL) {
	/*
	 * No font can display this character.  We will use the base font and
	 * have it display the "unknown" character.
	 */

	subFontPtr = &fontPtr->subFontArray[0];
	FontMapInsert(subFontPtr, ch);
    }
    ReleaseDC(fontPtr->hwnd, hdc);
    return subFontPtr;
}

static int CALLBACK
WinFontCanUseProc(
    ENUMLOGFONT *lfPtr,		/* Logical-font data. */
    NEWTEXTMETRIC *tmPtr,	/* Physical-font data (not used). */
    int fontType,		/* Type of font (not used). */
    LPARAM lParam)		/* Result object to hold result. */
{
    int ch;
    HDC hdc;
    WinFont *fontPtr;
    CanUse *canUsePtr;
    char *fallbackName;
    SubFont *subFontPtr;
    Tcl_DString faceString;
    Tcl_DString *nameTriedPtr;

    canUsePtr	    = (CanUse *) lParam;
    ch		    = canUsePtr->ch;
    hdc		    = canUsePtr->hdc;
    fontPtr	    = canUsePtr->fontPtr;
    nameTriedPtr    = canUsePtr->nameTriedPtr;

    fallbackName = lfPtr->elfLogFont.lfFaceName;
    Tcl_ExternalToUtfDString(systemEncoding, fallbackName, -1, &faceString);

    fallbackName = Tcl_DStringValue(&faceString);

    if (SeenName(fallbackName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(hdc, fontPtr, fallbackName, ch,
		canUsePtr->subFontPtrPtr);
	if (subFontPtr != NULL) {
	    canUsePtr->subFontPtr = subFontPtr;
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
FontMapLookup(
    SubFont *subFontPtr,	/* Contains font mapping cache to be queried
				 * and possibly updated. */
    int ch)			/* Character to be tested. */
{
    int row, bitOffset;

    if (ch < 0 || ch >= FONTMAP_NUMCHARS) {
	return 0;
    }

    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
}







<
<
<
<







1946
1947
1948
1949
1950
1951
1952




1953
1954
1955
1956
1957
1958
1959
FontMapLookup(
    SubFont *subFontPtr,	/* Contains font mapping cache to be queried
				 * and possibly updated. */
    int ch)			/* Character to be tested. */
{
    int row, bitOffset;





    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
}
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
FontMapInsert(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int ch)			/* Character to be added to cache. */
{
    int row, bitOffset;

    if (ch >= 0 && ch < FONTMAP_NUMCHARS) {
	row = ch >> FONTMAP_SHIFT;
	if (subFontPtr->fontMap[row] == NULL) {
	    FontMapLoadPage(subFontPtr, row);
	}
	bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
	subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * FontMapLoadPage --
 *
 *	Load information about all the characters on a given page. This
 *	information consists of one bit per character that indicates whether
 *	the associated HFONT can (1) or cannot (0) display the characters on
 *	the page.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory allocated.
 *
 *-------------------------------------------------------------------------
 */

static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    FontFamily *familyPtr;
    Tcl_Encoding encoding;
    int i, j, bitOffset, end, segCount;
    USHORT *startCount, *endCount;
    char buf[16], src[6];

    subFontPtr->fontMap[row] = (char *)ckalloc(FONTMAP_BITSPERPAGE / 8);
    memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8);

    familyPtr = subFontPtr->familyPtr;
    encoding = familyPtr->encoding;

    if (familyPtr->encoding == TkWinGetUnicodeEncoding()) {
	/*







<
|
|
|
|
|
|
<
















|













|

|

|







1986
1987
1988
1989
1990
1991
1992

1993
1994
1995
1996
1997
1998

1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
FontMapInsert(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int ch)			/* Character to be added to cache. */
{
    int row, bitOffset;


    row = ch >> FONTMAP_SHIFT;
    if (subFontPtr->fontMap[row] == NULL) {
	FontMapLoadPage(subFontPtr, row);
    }
    bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);

}

/*
 *-------------------------------------------------------------------------
 *
 * FontMapLoadPage --
 *
 *	Load information about all the characters on a given page. This
 *	information consists of one bit per character that indicates whether
 *	the associated HFONT can (1) or cannot (0) display the characters on
 *	the page.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Mempry allocated.
 *
 *-------------------------------------------------------------------------
 */

static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    FontFamily *familyPtr;
    Tcl_Encoding encoding;
    char src[TCL_UTF_MAX], buf[16];
    USHORT *startCount, *endCount;
    int i, j, bitOffset, end, segCount;

    subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8);
    memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8);

    familyPtr = subFontPtr->familyPtr;
    encoding = familyPtr->encoding;

    if (familyPtr->encoding == TkWinGetUnicodeEncoding()) {
	/*
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
	j = 0;
	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    for ( ; j < segCount; j++) {
		if (endCount[j] >= i) {
		    if (startCount[j] <= i) {
			bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
			subFontPtr->fontMap[row][bitOffset >> 3] |=
				1 << (bitOffset & 7);
		    }
		    break;
		}
	    }
	}
    } else if (familyPtr->isSymbolFont) {
	/*







|
<







2050
2051
2052
2053
2054
2055
2056
2057

2058
2059
2060
2061
2062
2063
2064
	j = 0;
	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    for ( ; j < segCount; j++) {
		if (endCount[j] >= i) {
		    if (startCount[j] <= i) {
			bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
			subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);

		    }
		    break;
		}
	    }
	}
    } else if (familyPtr->isSymbolFont) {
	/*
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
	 * we don't know the proper Unicode -> symbol font mapping, we can
	 * install the symbol font as the base font and access its glyphs.
	 */

	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    if (Tcl_UtfToExternal(NULL, encoding, src,
		    TkUniCharToUtf(i, src), TCL_ENCODING_STOPONERROR, NULL,
		    buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) {
		continue;
	    }
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
	}
    }







|







2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
	 * we don't know the proper Unicode -> symbol font mapping, we can
	 * install the symbol font as the base font and access its glyphs.
	 */

	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    if (Tcl_UtfToExternal(NULL, encoding, src,
		    Tcl_UniCharToUtf(i, src), TCL_ENCODING_STOPONERROR, NULL,
		    buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) {
		continue;
	    }
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
	}
    }
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
 */

static SubFont *
CanUseFallbackWithAliases(
    HDC hdc,			/* HDC in which font can be selected. */
    WinFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,	/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **subFontPtrPtr)	/* Variable to fixup if we reallocate the
				 * array of subfonts. */
{
    int i;
    const char *const *aliases;
    SubFont *subFontPtr;

    if (SeenName(faceName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(hdc, fontPtr, faceName, ch, subFontPtrPtr);
	if (subFontPtr != NULL) {
	    return subFontPtr;
	}







|










|







2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
 */

static SubFont *
CanUseFallbackWithAliases(
    HDC hdc,			/* HDC in which font can be selected. */
    WinFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    char *faceName,		/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    Tcl_DString *nameTriedPtr,	/* Records face names that have already been
				 * tried. It is possible for the same face
				 * name to be queried multiple times when
				 * trying to find a suitable screen font. */
    SubFont **subFontPtrPtr)	/* Variable to fixup if we reallocate the
				 * array of subfonts. */
{
    int i;
    char **aliases;
    SubFont *subFontPtr;

    if (SeenName(faceName, nameTriedPtr) == 0) {
	subFontPtr = CanUseFallback(hdc, fontPtr, faceName, ch, subFontPtrPtr);
	if (subFontPtr != NULL) {
	    return subFontPtr;
	}
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
SeenName(
    const char *name,		/* The name to check. */
    Tcl_DString *dsPtr)		/* Contains names that have already been
				 * seen. */
{
    const char *seen, *end;

    seen = Tcl_DStringValue(dsPtr);
    end = seen + Tcl_DStringLength(dsPtr);
    while (seen < end) {
	if (strcasecmp(seen, name) == 0) {
	    return 1;
	}
	seen += strlen(seen) + 1;
    }
    Tcl_DStringAppend(dsPtr, name, (int) (strlen(name) + 1));
    return 0;
}

/*
 *-------------------------------------------------------------------------
 *
 * CanUseFallback --







|



|









|







2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
SeenName(
    CONST char *name,		/* The name to check. */
    Tcl_DString *dsPtr)		/* Contains names that have already been
				 * seen. */
{
    CONST char *seen, *end;

    seen = Tcl_DStringValue(dsPtr);
    end = seen + Tcl_DStringLength(dsPtr);
    while (seen < end) {
	if (strcasecmp(seen, name) == 0) {
	    return 1;
	}
	seen += strlen(seen) + 1;
    }
    Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1));
    return 0;
}

/*
 *-------------------------------------------------------------------------
 *
 * CanUseFallback --
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
 */

static SubFont *
CanUseFallback(
    HDC hdc,			/* HDC in which font can be selected. */
    WinFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    const char *faceName,	/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    SubFont **subFontPtrPtr)	/* Variable to fix-up if we realloc the array
				 * of subfonts. */
{
    int i;
    HFONT hFont;







|







2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
 */

static SubFont *
CanUseFallback(
    HDC hdc,			/* HDC in which font can be selected. */
    WinFont *fontPtr,		/* The font object that will own the new
				 * screen font. */
    char *faceName,		/* Desired face name for new screen font. */
    int ch,			/* The Unicode character that the new screen
				 * font must be able to display. */
    SubFont **subFontPtrPtr)	/* Variable to fix-up if we realloc the array
				 * of subfonts. */
{
    int i;
    HFONT hFont;
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450

2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
	}
    }

    /*
     * Load this font and see if it has the desired character.
     */

    hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize,
	    0.0);
    InitSubFont(hdc, hFont, 0, &subFont);
    if (((ch < 256) && (subFont.familyPtr->isSymbolFont))
	    || (FontMapLookup(&subFont, ch) == 0)) {
	/*
	 * Don't use a symbol font as a fallback font for characters below
	 * 256.
	 */

	ReleaseSubFont(&subFont);
	return NULL;
    }

    if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
	SubFont *newPtr;


    	newPtr = (SubFont *)ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1));
	memcpy(newPtr, fontPtr->subFontArray,
		fontPtr->numSubFonts * sizeof(SubFont));
	if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	    ckfree(fontPtr->subFontArray);
	}

	/*
	 * Fix up the variable pointed to by subFontPtrPtr so it still points
	 * into the live array. [Bug 618872]
	 */








|
<















>
|
|


|







2239
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
	}
    }

    /*
     * Load this font and see if it has the desired character.
     */

    hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize);

    InitSubFont(hdc, hFont, 0, &subFont);
    if (((ch < 256) && (subFont.familyPtr->isSymbolFont))
	    || (FontMapLookup(&subFont, ch) == 0)) {
	/*
	 * Don't use a symbol font as a fallback font for characters below
	 * 256.
	 */

	ReleaseSubFont(&subFont);
	return NULL;
    }

    if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
	SubFont *newPtr;

    	newPtr = (SubFont *) ckalloc(sizeof(SubFont)
		* (fontPtr->numSubFonts + 1));
	memcpy((char *) newPtr, fontPtr->subFontArray,
		fontPtr->numSubFonts * sizeof(SubFont));
	if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
	    ckfree((char *) fontPtr->subFontArray);
	}

	/*
	 * Fix up the variable pointed to by subFontPtrPtr so it still points
	 * into the live array. [Bug 618872]
	 */

2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516

2517











2518




2519












2520
2521
2522
2523
2524
2525
2526
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static HFONT
GetScreenFont(
    const TkFontAttributes *faPtr,
				/* Desired font attributes for new HFONT. */
    const char *faceName,	/* Overrides font family specified in font
				 * attributes. */
    int pixelSize,		/* Overrides size specified in font
				 * attributes. */
    double angle)		/* What is the desired orientation of the
				 * font. */
{

    HFONT hFont;
    LOGFONTW lf;

    memset(&lf, 0, sizeof(lf));
    lf.lfHeight		= -pixelSize;
    lf.lfWidth		= 0;
    lf.lfEscapement	= ROUND16(angle * 10);
    lf.lfOrientation	= ROUND16(angle * 10);
    lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD;
    lf.lfItalic		= faPtr->slant;
    lf.lfUnderline	= faPtr->underline;
    lf.lfStrikeOut	= faPtr->overstrike;
    lf.lfCharSet	= DEFAULT_CHARSET;
    lf.lfOutPrecision	= OUT_TT_PRECIS;
    lf.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
    lf.lfQuality	= DEFAULT_QUALITY;
    lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;


    MultiByteToWideChar(CP_UTF8, 0, faceName, -1, lf.lfFaceName, LF_FACESIZE);











    lf.lfFaceName[LF_FACESIZE-1] = 0;




    hFont = CreateFontIndirectW(&lf);












    return hFont;
}

/*
 *-------------------------------------------------------------------------
 *
 * FamilyExists, FamilyOrAliasExists, WinFontExistsProc --







|

|

|

<
<

>






|
|










>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>







2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307


2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static HFONT
GetScreenFont(
    CONST TkFontAttributes *faPtr,
				/* Desired font attributes for new HFONT. */
    CONST char *faceName,	/* Overrides font family specified in font
				 * attributes. */
    int pixelSize)		/* Overrides size specified in font
				 * attributes. */


{
    Tcl_DString ds;
    HFONT hFont;
    LOGFONTW lf;

    memset(&lf, 0, sizeof(lf));
    lf.lfHeight		= -pixelSize;
    lf.lfWidth		= 0;
    lf.lfEscapement	= 0;
    lf.lfOrientation	= 0;
    lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD;
    lf.lfItalic		= faPtr->slant;
    lf.lfUnderline	= faPtr->underline;
    lf.lfStrikeOut	= faPtr->overstrike;
    lf.lfCharSet	= DEFAULT_CHARSET;
    lf.lfOutPrecision	= OUT_TT_PRECIS;
    lf.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
    lf.lfQuality	= DEFAULT_QUALITY;
    lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;

    Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &ds);

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	Tcl_UniChar *src, *dst;

	/*
	 * We can only store up to LF_FACESIZE wide characters
	 */

	if ((size_t)Tcl_DStringLength(&ds) >= (LF_FACESIZE * sizeof(WCHAR))) {
	    Tcl_DStringSetLength(&ds, LF_FACESIZE);
	}
	src = (Tcl_UniChar *) Tcl_DStringValue(&ds);
	dst = (Tcl_UniChar *) lf.lfFaceName;
	while (*src != '\0') {
	    *dst++ = *src++;
	}
	*dst = '\0';
	hFont = CreateFontIndirectW(&lf);
    } else {
	/*
	 * We can only store up to LF_FACESIZE characters
	 */

	if (Tcl_DStringLength(&ds) >= LF_FACESIZE) {
	    Tcl_DStringSetLength(&ds, LF_FACESIZE);
	}
	strcpy((char *) lf.lfFaceName, Tcl_DStringValue(&ds));
	hFont = CreateFontIndirectA((LOGFONTA *) &lf);
    }
    Tcl_DStringFree(&ds);
    return hFont;
}

/*
 *-------------------------------------------------------------------------
 *
 * FamilyExists, FamilyOrAliasExists, WinFontExistsProc --
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549





2550










2551
2552
2553
2554
2555
2556
2557
2558
2559

2560
2561




2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
 *
 *-------------------------------------------------------------------------
 */

static int
FamilyExists(
    HDC hdc,			/* HDC in which font family will be used. */
    const char *faceName)	/* Font family to query. */
{
    int result;
    Tcl_DString faceString;






    Tcl_DStringInit(&faceString);










    Tcl_UtfToWCharDString(faceName, -1, &faceString);

    /*
     * If the family exists, WinFontExistProc() will be called and
     * EnumFontFamilies() will return whatever WinFontExistProc() returns. If
     * the family doesn't exist, EnumFontFamilies() will just return a
     * non-zero value.
     */


    result = EnumFontFamiliesW(hdc, (WCHAR *)Tcl_DStringValue(&faceString),
	    (FONTENUMPROCW) WinFontExistProc, 0);




    Tcl_DStringFree(&faceString);
    return (result == 0);
}

static const char *
FamilyOrAliasExists(
    HDC hdc,
    const char *faceName)
{
    const char *const *aliases;
    int i;

    if (FamilyExists(hdc, faceName) != 0) {
	return faceName;
    }
    aliases = TkFontGetAliasList(faceName);
    if (aliases != NULL) {
	for (i = 0; aliases[i] != NULL; i++) {
	    if (FamilyExists(hdc, aliases[i]) != 0) {
		return aliases[i];
	    }
	}
    }
    return NULL;
}

static int CALLBACK
WinFontExistProc(
    TCL_UNUSED(ENUMLOGFONTW *),		/* Logical-font data. */
    TCL_UNUSED(NEWTEXTMETRIC *),	/* Physical-font data (not used). */
    TCL_UNUSED(int),		/* Type of font (not used). */
    TCL_UNUSED(LPARAM))		/* EnumFontData to hold result. */
{
    return 0;
}

/*
 * The following data structures are used when querying a TrueType font file
 * to determine which characters the font supports.
 */

#pragma pack(1)			/* Structures are byte aligned in file. */

#define CMAPHEX 0x636d6170	/* Key for character map resource. */

typedef struct CMAPTABLE {
    USHORT version;		/* Table version number (0). */
    USHORT numTables;		/* Number of encoding tables following. */
} CMAPTABLE;

typedef struct ENCODINGTABLE {







|




>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|








>
|
|
>
>
>
>




|


|

|



|














|
|
|
|











|







2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
 *
 *-------------------------------------------------------------------------
 */

static int
FamilyExists(
    HDC hdc,			/* HDC in which font family will be used. */
    CONST char *faceName)	/* Font family to query. */
{
    int result;
    Tcl_DString faceString;

    /*
     * Just immediately rule out the following fonts, because they look so
     * ugly on windows. The caller's fallback mechanism will cause the
     * corresponding appropriate TrueType fonts to be selected.
     */

    if (strcasecmp(faceName, "Courier") == 0) {
	return 0;
    }
    if (strcasecmp(faceName, "Times") == 0) {
	return 0;
    }
    if (strcasecmp(faceName, "Helvetica") == 0) {
	return 0;
    }

    Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &faceString);

    /*
     * If the family exists, WinFontExistProc() will be called and
     * EnumFontFamilies() will return whatever WinFontExistProc() returns. If
     * the family doesn't exist, EnumFontFamilies() will just return a
     * non-zero value.
     */

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	result = EnumFontFamiliesW(hdc, (WCHAR*) Tcl_DStringValue(&faceString),
		(FONTENUMPROCW) WinFontExistProc, 0);
    } else {
	result = EnumFontFamiliesA(hdc, (char *) Tcl_DStringValue(&faceString),
		(FONTENUMPROCA) WinFontExistProc, 0);
    }
    Tcl_DStringFree(&faceString);
    return (result == 0);
}

static char *
FamilyOrAliasExists(
    HDC hdc,
    CONST char *faceName)
{
    char **aliases;
    int i;

    if (FamilyExists(hdc, faceName) != 0) {
	return (char *) faceName;
    }
    aliases = TkFontGetAliasList(faceName);
    if (aliases != NULL) {
	for (i = 0; aliases[i] != NULL; i++) {
	    if (FamilyExists(hdc, aliases[i]) != 0) {
		return aliases[i];
	    }
	}
    }
    return NULL;
}

static int CALLBACK
WinFontExistProc(
    ENUMLOGFONT *lfPtr,		/* Logical-font data. */
    NEWTEXTMETRIC *tmPtr,	/* Physical-font data (not used). */
    int fontType,		/* Type of font (not used). */
    LPARAM lParam)		/* EnumFontData to hold result. */
{
    return 0;
}

/*
 * The following data structures are used when querying a TrueType font file
 * to determine which characters the font supports.
 */

#pragma pack(1)			/* Structures are byte aligned in file. */

#define CMAPHEX  0x636d6170	/* Key for character map resource. */

typedef struct CMAPTABLE {
    USHORT version;		/* Table version number (0). */
    USHORT numTables;		/* Number of encoding tables following. */
} CMAPTABLE;

typedef struct ENCODINGTABLE {
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
    USHORT entryCount;		/* Number valid low bytes for subHeader. */
    SHORT idDelta;		/* Constant adder to get base glyph index. */
    USHORT idRangeOffset;	/* Byte offset from here to appropriate
				 * glyphIndexArray. */
} SUBHEADER;

typedef struct HIBYTETABLE {
    USHORT format;		/* Format number is set to 2. */
    USHORT length;		/* The actual length in bytes of this
				 * subtable. */
    USHORT version;		/* Version number (starts at 0). */
    USHORT subHeaderKeys[256];	/* Maps high bytes to subHeaders: value is
				 * subHeader index * 8. */
#if 0
    SUBHEADER subHeaders[];	/* Variable-length array of SUBHEADERs. */







|







2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
    USHORT entryCount;		/* Number valid low bytes for subHeader. */
    SHORT idDelta;		/* Constant adder to get base glyph index. */
    USHORT idRangeOffset;	/* Byte offset from here to appropriate
				 * glyphIndexArray. */
} SUBHEADER;

typedef struct HIBYTETABLE {
    USHORT format;  		/* Format number is set to 2. */
    USHORT length;		/* The actual length in bytes of this
				 * subtable. */
    USHORT version;		/* Version number (starts at 0). */
    USHORT subHeaderKeys[256];	/* Maps high bytes to subHeaders: value is
				 * subHeader index * 8. */
#if 0
    SUBHEADER subHeaders[];	/* Variable-length array of SUBHEADERs. */
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
    char *s;

    segCount = 0;
    startCount = NULL;
    endCount = NULL;
    *symbolPtr = 0;

    hFont = (HFONT)SelectObject(hdc, hFont);

    i = 0;
    s = (char *) &i;
    *s = '\1';
    swapped = 0;

    if (i == 1) {
	swapped = 1;
    }

    cmapKey = CMAPHEX;
    if (swapped) {
	SwapLong(&cmapKey);
    }

    n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof(cmapTable));
    if (n != (int) GDI_ERROR) {
	if (swapped) {
	    SwapShort(&cmapTable.numTables);
	}
	for (i = 0; i < cmapTable.numTables; i++) {
	    offset = sizeof(cmapTable) + i * sizeof(encTable);
	    GetFontData(hdc, cmapKey, (DWORD) offset, &encTable,
		    sizeof(encTable));







|
















|







2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
    char *s;

    segCount = 0;
    startCount = NULL;
    endCount = NULL;
    *symbolPtr = 0;

    hFont = SelectObject(hdc, hFont);

    i = 0;
    s = (char *) &i;
    *s = '\1';
    swapped = 0;

    if (i == 1) {
	swapped = 1;
    }

    cmapKey = CMAPHEX;
    if (swapped) {
	SwapLong(&cmapKey);
    }

    n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof(cmapTable));
    if (n != (int)GDI_ERROR) {
	if (swapped) {
	    SwapShort(&cmapTable.numTables);
	}
	for (i = 0; i < cmapTable.numTables; i++) {
	    offset = sizeof(cmapTable) + i * sizeof(encTable);
	    GetFontData(hdc, cmapKey, (DWORD) offset, &encTable,
		    sizeof(encTable));
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
	    if (subTable.any.format == 4) {
		if (swapped) {
		    SwapShort(&subTable.segment.segCountX2);
		}
		segCount = subTable.segment.segCountX2 / 2;
		cbData = segCount * sizeof(USHORT);

		startCount = (USHORT *)ckalloc(cbData);
		endCount = (USHORT *)ckalloc(cbData);

		offset = encTable.offset + sizeof(subTable.segment);
		GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData);
		offset += cbData + sizeof(USHORT);
		GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData);
		if (swapped) {
		    for (i = 0; i < segCount; i++) {







|
|







2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
	    if (subTable.any.format == 4) {
		if (swapped) {
		    SwapShort(&subTable.segment.segCountX2);
		}
		segCount = subTable.segment.segCountX2 / 2;
		cbData = segCount * sizeof(USHORT);

		startCount = (USHORT *) ckalloc((unsigned)cbData);
		endCount = (USHORT *) ckalloc((unsigned)cbData);

		offset = encTable.offset + sizeof(subTable.segment);
		GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData);
		offset += cbData + sizeof(USHORT);
		GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData);
		if (swapped) {
		    for (i = 0; i < segCount; i++) {
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
	/*
	 * Bitmap font. We should also support ranges for the other *_CHARSET
	 * values.
	 */

	segCount = 1;
	cbData = segCount * sizeof(USHORT);
	startCount = (USHORT *)ckalloc(cbData);
	endCount = (USHORT *)ckalloc(cbData);
	startCount[0] = 0x0000;
	endCount[0] = 0x00ff;
    }
    SelectObject(hdc, hFont);

    *startCountPtr = startCount;
    *endCountPtr = endCount;







|
|







2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
	/*
	 * Bitmap font. We should also support ranges for the other *_CHARSET
	 * values.
	 */

	segCount = 1;
	cbData = segCount * sizeof(USHORT);
	startCount = (USHORT *) ckalloc((unsigned) cbData);
	endCount = (USHORT *) ckalloc((unsigned) cbData);
	startCount[0] = 0x0000;
	endCount[0] = 0x00ff;
    }
    SelectObject(hdc, hFont);

    *startCountPtr = startCount;
    *endCountPtr = endCount;
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static inline void
SwapShort(
    PUSHORT p)
{
    *p = (SHORT)(HIBYTE(*p) + (LOBYTE(*p) << 8));
}

static inline void
SwapLong(
    PULONG p)
{
    ULONG temp;

    temp = (LONG) ((BYTE) *p);
    temp <<= 8;







|






|







2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static void
SwapShort(
    PUSHORT p)
{
    *p = (SHORT)(HIBYTE(*p) + (LOBYTE(*p) << 8));
}

static void
SwapLong(
    PULONG p)
{
    ULONG temp;

    temp = (LONG) ((BYTE) *p);
    temp <<= 8;

Changes to win/tkWinImage.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

static int
DestroyImage(
    XImage *imagePtr)		/* Image to free. */
{
    if (imagePtr) {
	if (imagePtr->data) {
	    ckfree(imagePtr->data);
	}
	ckfree(imagePtr);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *







|

|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

static int
DestroyImage(
    XImage *imagePtr)		/* Image to free. */
{
    if (imagePtr) {
	if (imagePtr->data) {
	    ckfree((char*)imagePtr->data);
	}
	ckfree((char*)imagePtr);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    int offset,
    char *data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage* imagePtr = (XImage*)ckalloc(sizeof(XImage));
    (void)display;
    (void)visual;

    imagePtr->width = width;
    imagePtr->height = height;
    imagePtr->xoffset = offset;
    imagePtr->format = format;
    imagePtr->data = data;
    imagePtr->byte_order = LSBFirst;
    imagePtr->bitmap_unit = 8;







|
<
<
<







208
209
210
211
212
213
214
215



216
217
218
219
220
221
222
    int offset,
    char *data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage* imagePtr = (XImage *) ckalloc(sizeof(XImage));



    imagePtr->width = width;
    imagePtr->height = height;
    imagePtr->xoffset = offset;
    imagePtr->format = format;
    imagePtr->data = data;
    imagePtr->byte_order = LSBFirst;
    imagePtr->bitmap_unit = 8;
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
    int size;
    unsigned int n;
    unsigned int depth;
    unsigned char *data;
    TkWinDCState state;
    BOOL ret;
    (void)plane_mask;

    if (format != ZPixmap) {
	TkpDisplayWarning("Only ZPixmap types are implemented",

		"XGetImageZPixmap Failure");
	return NULL;
    }

    hdc = TkWinGetDrawableDC(display, d, &state);

    /*
     * Need to do a Blt operation to copy into a new bitmap.
     */

    hbmp = CreateCompatibleBitmap(hdc, (int) width, (int) height);
    hdcMem = CreateCompatibleDC(hdc);
    hbmpPrev = (HBITMAP)SelectObject(hdcMem, hbmp);
    hPal = state.palette;
    if (hPal) {
	hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
	n = RealizePalette(hdcMem);
	if (n > 0) {
	    UpdateColors(hdcMem);
	}







<


|
>












|







296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
    int size;
    unsigned int n;
    unsigned int depth;
    unsigned char *data;
    TkWinDCState state;
    BOOL ret;


    if (format != ZPixmap) {
	TkpDisplayWarning(
		"XGetImageZPixmap: only ZPixmap types are implemented",
		"XGetImageZPixmap Failure");
	return NULL;
    }

    hdc = TkWinGetDrawableDC(display, d, &state);

    /*
     * Need to do a Blt operation to copy into a new bitmap.
     */

    hbmp = CreateCompatibleBitmap(hdc, (int) width, (int) height);
    hdcMem = CreateCompatibleDC(hdc);
    hbmpPrev = SelectObject(hdcMem, hbmp);
    hPal = state.palette;
    if (hPal) {
	hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
	n = RealizePalette(hdcMem);
	if (n > 0) {
	    UpdateColors(hdcMem);
	}
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *) data,
		width, height, 32, (int) ((width + 31) >> 3) & ~1);
	if (ret_image == NULL) {
	    ckfree(data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree(ret_image->data);
	    ckfree(ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	pend = data + bmInfo->bmiHeader.biSizeImage;
	while (p < pend) {
	    *p = ~*p;







|


|









|
|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *)data,
		width, height, 32, (int) ((width + 31) >> 3) & ~1);
	if (ret_image == NULL) {
	    ckfree((char *)data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	pend = data + bmInfo->bmiHeader.biSizeImage;
	while (p < pend) {
	    *p = ~*p;
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *) data,
		width, height, 8, (int) width);
	if (ret_image == NULL) {
	    ckfree(data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree(ret_image->data);
	    ckfree(ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	palette = (unsigned short *) bmInfo->bmiColors;
	for (i = 0; i < bmInfo->bmiHeader.biSizeImage; i++, p++) {
	    *p = (unsigned char) palette[*p];
	}
    } else if (depth == 16) {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, (char *) data,
		width, height, 16, 0 /* will be calc'ed from bitmap_pad */);
	if (ret_image == NULL) {
	    ckfree(data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info directly into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		DIB_RGB_COLORS) == 0) {
	    ckfree(ret_image->data);
	    ckfree(ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
    } else {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *)ckalloc(width * height * 4);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data,
		width, height, 0, (int) width * 4);
	if (ret_image == NULL) {
	    ckfree(data);
	    goto cleanup;
	}

	if (depth <= 24) {
	    /*
	     * This used to handle 16 and 24 bpp, but now just handles 24. It
	     * can likely be optimized for that. -- hobbs
	     */

	    unsigned char *smallBitData, *smallBitBase, *bigBitData;
	    unsigned int byte_width, h, w;

	    byte_width = ((width * 3 + 3) & ~(unsigned)3);
	    smallBitBase = (unsigned char *)ckalloc(byte_width * height);
	    if (!smallBitBase) {
		ckfree(ret_image->data);
		ckfree(ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	    smallBitData = smallBitBase;

	    /*
	     * Get the BITMAP info into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree(ret_image->data);
		ckfree(ret_image);
		ckfree(smallBitBase);
		ret_image = NULL;
		goto cleanup;
	    }

	    /*
	     * Copy the 24 Bit Pixmap to a 32-Bit one.
	     */

	    for (h = 0; h < height; h++) {
		bigBitData   = (unsigned char *) ret_image->data + h * ret_image->bytes_per_line;
		smallBitData = smallBitBase + h * byte_width;

		for (w = 0; w < width; w++) {
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = 0;
		}
	    }

	    /*
	     * Free the Device contexts, and the Bitmap.
	     */

	    ckfree(smallBitBase);
	} else {
	    /*
	     * Get the BITMAP info directly into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree(ret_image->data);
		ckfree(ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	}
    }

  cleanup:
    if (bmInfo) {
	ckfree(bmInfo);
    }
    if (hPal) {
	SelectPalette(hdcMem, hPalPrev1, FALSE);
    }
    DeleteDC(hdcMem);
    DeleteObject(hbmp);








|


|









|
|










|








|









|
|





|








|













|

|
|











|
|
|









|














|







|
|








|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *)data,
		width, height, 8, (int) width);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	palette = (unsigned short *) bmInfo->bmiColors;
	for (i = 0; i < bmInfo->bmiHeader.biSizeImage; i++, p++) {
	    *p = (unsigned char) palette[*p];
	}
    } else if (depth == 16) {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, (char *) data,
		width, height, 16, 0 /* will be calc'ed from bitmap_pad */);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info directly into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		DIB_RGB_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
    } else {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *) ckalloc(width * height * 4);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data,
		width, height, 0, (int) width * 4);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	if (depth <= 24) {
	    /*
	     * This used to handle 16 and 24 bpp, but now just handles 24. It
	     * can likely be optimized for that. -- hobbs
	     */

	    unsigned char *smallBitData, *smallBitBase, *bigBitData;
	    unsigned int byte_width, h, w;

	    byte_width = ((width * 3 + 3) & ~(unsigned)3);
	    smallBitBase = (unsigned char *) ckalloc(byte_width * height);
	    if (!smallBitBase) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	    smallBitData = smallBitBase;

	    /*
	     * Get the BITMAP info into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ckfree((char *) smallBitBase);
		ret_image = NULL;
		goto cleanup;
	    }

	    /*
	     * Copy the 24 Bit Pixmap to a 32-Bit one.
	     */

	    for (h = 0; h < height; h++) {
		bigBitData   = (unsigned char *) (ret_image->data + h * ret_image->bytes_per_line);
		smallBitData = smallBitBase + h * byte_width;

		for (w = 0; w < width; w++) {
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = 0;
		}
	    }

	    /*
	     * Free the Device contexts, and the Bitmap.
	     */

	    ckfree((char *) smallBitBase);
	} else {
	    /*
	     * Get the BITMAP info directly into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	}
    }

  cleanup:
    if (bmInfo) {
	ckfree((char *) bmInfo);
    }
    if (hPal) {
	SelectPalette(hdcMem, hPalPrev1, FALSE);
    }
    DeleteDC(hdcMem);
    DeleteObject(hbmp);

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
	 * is consistent with the Unix behavior, but does not appear to handle
	 * all bit depths correctly. -- hobbs
	 */

	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
    } else {
	const char *errMsg = NULL;
	char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
	BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;

	if (twdPtr->bitmap.handle == NULL) {
	    errMsg = "XGetImage: not implemented for empty bitmap handles";
	} else if (format != XYPixmap) {
	    errMsg = "XGetImage: not implemented for format != XYPixmap";







|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
	 * is consistent with the Unix behavior, but does not appear to handle
	 * all bit depths correctly. -- hobbs
	 */

	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
    } else {
	char *errMsg = NULL;
	char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
	BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;

	if (twdPtr->bitmap.handle == NULL) {
	    errMsg = "XGetImage: not implemented for empty bitmap handles";
	} else if (format != XYPixmap) {
	    errMsg = "XGetImage: not implemented for format != XYPixmap";

Changes to win/tkWinInit.c.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 *----------------------------------------------------------------------
 */

int
TkpInit(
    Tcl_Interp *interp)
{
    (void)interp;
    /*
     * This is necessary for static initialization, and is ok otherwise
     * because TkWinXInit flips a static bit to do its work just once.
     */

    TkWinXInit(Tk_GetHINSTANCE());
    return TCL_OK;







<







31
32
33
34
35
36
37

38
39
40
41
42
43
44
 *----------------------------------------------------------------------
 */

int
TkpInit(
    Tcl_Interp *interp)
{

    /*
     * This is necessary for static initialization, and is ok otherwise
     * because TkWinXInit flips a static bit to do its work just once.
     */

    TkWinXInit(Tk_GetHINSTANCE());
    return TCL_OK;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    int argc, namelength;
    const char **argv = NULL, *name, *p;

    name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
    namelength = -1;
    if (name != NULL) {
	Tcl_SplitPath(name, &argc, &argv);
	if (argc > 0) {
	    name = argv[argc-1];
	    p = strrchr(name, '.');
	    if (p != NULL) {
		namelength = p - name;
	    }
	} else {
	    name = NULL;
	}
    }
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
	namelength = -1;
    }
    Tcl_DStringAppend(namePtr, name, namelength);
    if (argv != NULL) {
	ckfree(argv);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --







|

|



















|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    int argc, namelength;
    CONST char **argv = NULL, *name, *p;

    name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
    namelength = -1;
    if (name != NULL) {
	Tcl_SplitPath(name, &argc, &argv);
	if (argc > 0) {
	    name = argv[argc-1];
	    p = strrchr(name, '.');
	    if (p != NULL) {
		namelength = p - name;
	    }
	} else {
	    name = NULL;
	}
    }
    if ((name == NULL) || (*name == 0)) {
	name = "tk";
	namelength = -1;
    }
    Tcl_DStringAppend(namePtr, name, namelength);
    if (argv != NULL) {
	ckfree((char *)argv);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
 *	Displays a message box.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
#define TK_MAX_WARN_LEN 1024

    WCHAR titleString[TK_MAX_WARN_LEN];
    WCHAR *msgString; /* points to titleString, just after title, leaving space for ": " */
    int len; /* size of title, including terminating NULL */

    /* If running on Cygwin and we have a stderr channel, use it. */
#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9) {
	Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel, title, -1);
	    Tcl_WriteChars(errChannel, ": ", 2);
	    Tcl_WriteChars(errChannel, msg, -1);
	    Tcl_WriteChars(errChannel, "\n", 1);
	    return;
	}
    }
#endif /* !STATIC_BUILD */

    len = MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);
    msgString = &titleString[len + 1];
    titleString[TK_MAX_WARN_LEN - 1] = '\0';
    MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, (TK_MAX_WARN_LEN - 1) - len);

    /*
     * Truncate MessageBox string if it is too long to not overflow the screen
     * and cause possible oversized window error.
     */
    if (titleString[TK_MAX_WARN_LEN - 1] != '\0') {
	memcpy(titleString + (TK_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR));
    }
    if (IsDebuggerPresent()) {
	titleString[len - 1] = ':';
	titleString[len] = ' ';
	OutputDebugStringW(titleString);
    } else {
	titleString[len - 1] = '\0';
	MessageBoxW(NULL, msgString, titleString,
		MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL
		| MB_SETFOREGROUND | MB_TOPMOST);
    }
}

/*
 * ----------------------------------------------------------------------
 *
 * Win32ErrorObj --
 *
 *	Returns a string object containing text from a COM or Win32 error code
 *
 * Results:
 *	A Tcl_Obj containing the Win32 error message.
 *
 * Side effects:
 *	Removed the error message from the COM threads error object.
 *
 * ----------------------------------------------------------------------
 */

Tcl_Obj*
TkWin32ErrorObj(
    HRESULT hrError)
{
    LPWSTR lpBuffer = NULL, p = NULL;
    WCHAR  sBuffer[30];
    Tcl_Obj* errPtr = NULL;
    Tcl_DString ds;

    FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
	    | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError,
	    LANG_NEUTRAL, (LPWSTR)&lpBuffer, 0, NULL);

    if (lpBuffer == NULL) {
	lpBuffer = sBuffer;
	wsprintfW(sBuffer, L"Error Code: %08lX", hrError);
    }

    if ((p = wcsrchr(lpBuffer, '\r')) != NULL) {
	*p = '\0';
    }

    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(lpBuffer, wcslen(lpBuffer), &ds);
    errPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);

    if (lpBuffer != sBuffer) {
	LocalFree((HLOCAL)lpBuffer);
    }

    return errPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|


>
|
<
<















<
<
<
|
>




<
|
<
<
<
|
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









109
110
111
112
113
114
115
116
117
118
119
120
121


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136



137
138
139
140
141
142

143



144



145
146
147



















































148
149
150
151
152
153
154
155
156
 *	Displays a message box.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayWarning(
    CONST char *msg,		/* Message to be displayed. */
    CONST char *title)		/* Title of warning. */
{
#define TK_MAX_WARN_LEN 1024
    WCHAR msgString[TK_MAX_WARN_LEN + 5];
    WCHAR titleString[TK_MAX_WARN_LEN + 1];



    /* If running on Cygwin and we have a stderr channel, use it. */
#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9) {
	Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel, title, -1);
	    Tcl_WriteChars(errChannel, ": ", 2);
	    Tcl_WriteChars(errChannel, msg, -1);
	    Tcl_WriteChars(errChannel, "\n", 1);
	    return;
	}
    }
#endif /* !STATIC_BUILD */




    MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, TK_MAX_WARN_LEN);
    MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);
    /*
     * Truncate MessageBox string if it is too long to not overflow the screen
     * and cause possible oversized window error.
     */

	memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));



    titleString[TK_MAX_WARN_LEN] = L'\0';



    MessageBoxW(NULL, msgString, titleString,
	    MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL
	    | MB_SETFOREGROUND | MB_TOPMOST);



















































}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinInt.h.

22
23
24
25
26
27
28




29
30
31
32
33
34
35
 * Include platform specific public interfaces.
 */

#ifndef _TKWIN
#include "tkWin.h"
#endif





/*
 * Define constants missing from older Win32 SDK header files.
 */

#ifndef WS_EX_TOOLWINDOW
#define WS_EX_TOOLWINDOW	0x00000080L
#endif







>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * Include platform specific public interfaces.
 */

#ifndef _TKWIN
#include "tkWin.h"
#endif

#ifndef _TKPORT
#include "tkPort.h"
#endif

/*
 * Define constants missing from older Win32 SDK header files.
 */

#ifndef WS_EX_TOOLWINDOW
#define WS_EX_TOOLWINDOW	0x00000080L
#endif
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette)

/*
 * The following macros define the class names for Tk Window types.
 */

#define TK_WIN_TOPLEVEL_CLASS_NAME L"TkTopLevel"
#define TK_WIN_CHILD_CLASS_NAME L"TkChild"

/*
 * The following variable is a translation table between X gc functions and
 * Win32 raster and BitBlt op modes.
 */

MODULE_SCOPE const int tkpWinRopModes[];







|
|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette)

/*
 * The following macros define the class names for Tk Window types.
 */

#define TK_WIN_TOPLEVEL_CLASS_NAME "TkTopLevel"
#define TK_WIN_CHILD_CLASS_NAME "TkChild"

/*
 * The following variable is a translation table between X gc functions and
 * Win32 raster and BitBlt op modes.
 */

MODULE_SCOPE const int tkpWinRopModes[];
138
139
140
141
142
143
144
145
146

147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
































175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230

231







232
233
234
235
236
237
238
239
240

241

242







243
244
245
246
247
248
249
250
251
252
253
254
255
256

/*
 * Internal functions used by more than one source file.
 */

#include "tkIntPlatDecls.h"

#ifdef __cplusplus
extern "C" {

#endif

/*
 * Special proc needed as tsd accessor function between
 * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard
 */

MODULE_SCOPE void TkWinUpdatingClipboard(int mode);

/*
 * Used by tkWinDialog.c to associate the right icon with tk_messageBox
 */

MODULE_SCOPE HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize);

/*
 * Used by tkWinX.c on for certain system display change messages and cleanup
 * up containers
 */

MODULE_SCOPE void TkWinDisplayChanged(Display *display);
MODULE_SCOPE void TkWinCleanupContainerList(void);

/*
 * Used by tkWinWm.c for embedded menu handling. May become public.
 */

MODULE_SCOPE HWND Tk_GetMenuHWND(Tk_Window tkwin);
MODULE_SCOPE HWND Tk_GetEmbeddedMenuHWND(Tk_Window tkwin);

































/*
 * The following allows us to cache these encoding for multiple functions.
 */


MODULE_SCOPE Tcl_Encoding	TkWinGetKeyInputEncoding(void);
MODULE_SCOPE Tcl_Encoding	TkWinGetUnicodeEncoding(void);
MODULE_SCOPE void		TkWinSetupSystemFonts(TkMainInfo *mainPtr);

/*
 * Values returned by TkWinGetPlatformTheme.
 */

#define TK_THEME_WIN_CLASSIC    1
#define TK_THEME_WIN_XP         2
#define TK_THEME_WIN_VISTA      3

/*
 * The following is implemented in tkWinWm and used by tkWinEmbed.c
 */

MODULE_SCOPE void		TkpWinToplevelWithDraw(TkWindow *winPtr);
MODULE_SCOPE void		TkpWinToplevelIconify(TkWindow *winPtr);
MODULE_SCOPE void		TkpWinToplevelDeiconify(TkWindow *winPtr);
MODULE_SCOPE long		TkpWinToplevelIsControlledByWm(TkWindow *winPtr);
MODULE_SCOPE long		TkpWinToplevelMove(TkWindow *winPtr, int x, int y);
MODULE_SCOPE long		TkpWinToplevelOverrideRedirect(TkWindow *winPtr,
			    int reqValue);
MODULE_SCOPE void		TkpWinToplevelDetachWindow(TkWindow *winPtr);
MODULE_SCOPE int		TkpWmGetState(TkWindow *winPtr);

MODULE_SCOPE int		TkTranslateWinEvent(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam, LRESULT *result);
MODULE_SCOPE void		TkWinPointerEvent(HWND hwnd, int x, int y);

/*
 * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c
 */

MODULE_SCOPE void		TkSetCursorPos(int x, int y);

/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);


/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */

#ifndef GetClassLongPtr

#   define GetClassLongPtrW	GetClassLongW

#   define SetClassLongPtrW	SetClassLongW







#endif /* !GetClassLongPtr */
#ifndef GCLP_HICON
#   define GCLP_HICON		GCL_HICON
#endif /* !GCLP_HICON */
#ifndef GCLP_HICONSM
#   define GCLP_HICONSM		(-34)
#endif /* !GCLP_HICONSM */

#ifndef GetWindowLongPtr

#   define GetWindowLongPtrW	GetWindowLongW

#   define SetWindowLongPtrW	SetWindowLongW







#endif /* !GetWindowLongPtr */
#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC		GWL_WNDPROC
#define GWLP_HINSTANCE		GWL_HINSTANCE
#define GWLP_HWNDPARENT		GWL_HWNDPARENT
#define GWLP_USERDATA		GWL_USERDATA
#define GWLP_ID			GWL_ID
#endif /* !GWLP_WNDPROC */

#ifdef __cplusplus
}
#endif

#endif /* _TKWININT */







|
|
>

>





|





|






|






|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















<





|
|
|
|
|
|

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








>

>

>
>
>
>
>
>
>









>

>

>
>
>
>
>
>
>









<
<
<
<

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
















243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290




291

/*
 * Internal functions used by more than one source file.
 */

#include "tkIntPlatDecls.h"

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Special proc needed as tsd accessor function between
 * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard
 */

EXTERN void		TkWinUpdatingClipboard(int mode);

/*
 * Used by tkWinDialog.c to associate the right icon with tk_messageBox
 */

EXTERN HICON		TkWinGetIcon(Tk_Window tkw, DWORD iconsize);

/*
 * Used by tkWinX.c on for certain system display change messages and cleanup
 * up containers
 */

EXTERN void		TkWinDisplayChanged(Display *display);
MODULE_SCOPE void TkWinCleanupContainerList(void);

/*
 * Used by tkWinWm.c for embedded menu handling. May become public.
 */

EXTERN HWND		Tk_GetMenuHWND(Tk_Window tkwin);
EXTERN HWND		Tk_GetEmbeddedMenuHWND(Tk_Window tkwin);

/*
 * The following structure keeps track of whether we are using the multi-byte
 * or the wide-character interfaces to the operating system. System calls
 * should be made through the following function table.
 *
 * While some system calls need to use this A/W jump-table, it is not
 * necessary for all calls to do it, which is why you won't see this used
 * throughout the Tk code, but only in key areas. -- hobbs
 */

typedef struct TkWinProcs {
    int useWide;
    LRESULT (WINAPI *callWindowProc)(WNDPROC lpPrevWndFunc, HWND hWnd,
	    UINT Msg, WPARAM wParam, LPARAM lParam);
    LRESULT (WINAPI *defWindowProc)(HWND hWnd, UINT Msg, WPARAM wParam,
	    LPARAM lParam);
    ATOM (WINAPI *registerClass)(const WNDCLASS *lpWndClass);
    BOOL (WINAPI *setWindowText)(HWND hWnd, LPCTSTR lpString);
    HWND (WINAPI *createWindowEx)(DWORD dwExStyle, LPCTSTR lpClassName,
	    LPCTSTR lpWindowName, DWORD dwStyle, int x, int y,
	    int nWidth, int nHeight, HWND hWndParent, HMENU hMenu,
	    HINSTANCE hInstance, LPVOID lpParam);
    BOOL (WINAPI *insertMenu)(HMENU hMenu, UINT uPosition, UINT uFlags,
	    UINT uIDNewItem, LPCTSTR lpNewItem);
    int (WINAPI *getWindowText)(HWND hWnd, LPCTSTR lpString, int nMaxCount);
} TkWinProcs;

EXTERN TkWinProcs *tkWinProcs;

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

/*
 * The following allows us to cache these encoding for multiple functions.
 */


MODULE_SCOPE Tcl_Encoding	TkWinGetKeyInputEncoding(void);
MODULE_SCOPE Tcl_Encoding	TkWinGetUnicodeEncoding(void);
MODULE_SCOPE void		TkWinSetupSystemFonts(TkMainInfo *mainPtr);

/*
 * Values returned by TkWinGetPlatformTheme.
 */

#define TK_THEME_WIN_CLASSIC    1
#define TK_THEME_WIN_XP         2


/*
 * The following is implemented in tkWinWm and used by tkWinEmbed.c
 */

void			TkpWinToplevelWithDraw(TkWindow *winPtr);
void			TkpWinToplevelIconify(TkWindow *winPtr);
void			TkpWinToplevelDeiconify(TkWindow *winPtr);
long			TkpWinToplevelIsControlledByWm(TkWindow *winPtr);
long			TkpWinToplevelMove(TkWindow *winPtr, int x, int y);
long			TkpWinToplevelOverrideRedirect(TkWindow *winPtr,
			    int reqValue);
void			TkpWinToplevelDetachWindow(TkWindow *winPtr);
int			TkpWmGetState(TkWindow *winPtr);

















/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */

#ifndef GetClassLongPtr
#   define GetClassLongPtrA	GetClassLongA
#   define GetClassLongPtrW	GetClassLongW
#   define SetClassLongPtrA	SetClassLongA
#   define SetClassLongPtrW	SetClassLongW
#   ifdef UNICODE
#	define GetClassLongPtr	GetClassLongPtrW
#	define SetClassLongPtr	SetClassLongPtrW
#   else
#	define GetClassLongPtr	GetClassLongPtrA
#	define SetClassLongPtr	SetClassLongPtrA
#   endif /* !UNICODE */
#endif /* !GetClassLongPtr */
#ifndef GCLP_HICON
#   define GCLP_HICON		GCL_HICON
#endif /* !GCLP_HICON */
#ifndef GCLP_HICONSM
#   define GCLP_HICONSM		(-34)
#endif /* !GCLP_HICONSM */

#ifndef GetWindowLongPtr
#   define GetWindowLongPtrA	GetWindowLongA
#   define GetWindowLongPtrW	GetWindowLongW
#   define SetWindowLongPtrA	SetWindowLongA
#   define SetWindowLongPtrW	SetWindowLongW
#   ifdef UNICODE
#	define GetWindowLongPtr	GetWindowLongPtrW
#	define SetWindowLongPtr	SetWindowLongPtrW
#   else
#	define GetWindowLongPtr	GetWindowLongPtrW
#	define SetWindowLongPtr	SetWindowLongPtrW
#   endif /* !UNICODE */
#endif /* !GetWindowLongPtr */
#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC		GWL_WNDPROC
#define GWLP_HINSTANCE		GWL_HINSTANCE
#define GWLP_HWNDPARENT		GWL_HWNDPARENT
#define GWLP_USERDATA		GWL_USERDATA
#define GWLP_ID			GWL_ID
#endif /* !GWLP_WNDPROC */





#endif /* _TKWININT */

Changes to win/tkWinKey.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * tkWinKey.c --
 *
 *	This file contains X emulation routines for keyboard related
 *	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.
 */

#include "tkWinInt.h"
#include "X11/XF86keysym.h"

/*
 * The keymap table holds mappings of Windows keycodes to X keysyms. If
 * Windows ever comes along and changes the value of their keycodes, this will
 * break all kinds of things. However, this table lookup is much faster than
 * the alternative, in which we walked a list of keycodes looking for a match.
 * Since this lookup is performed for every Windows keypress event, it seems
 * like a worthwhile improvement to use the table.
 */

#define MAX_KEYCODE 183 /* VK_LAUNCH_APP2 is the last entry in our table below */
/* cf. https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx */

static const KeySym keymap[] = {
    NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol, /*0 0x0*/
    NoSymbol, NoSymbol, NoSymbol, XK_BackSpace, XK_Tab, /*5 0x5*/
    NoSymbol, NoSymbol, XK_Clear, XK_Return, NoSymbol, /*10 0xA*/
    NoSymbol, XK_Shift_L, XK_Control_L, XK_Alt_L, XK_Pause, /*15 0xE*/
    XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*20 0x14*/
    NoSymbol, NoSymbol, XK_Escape, NoSymbol, NoSymbol, /*25 0x19*/
    NoSymbol, NoSymbol, XK_space, XK_Prior, XK_Next, /*30 0x1E*/
    XK_End, XK_Home, XK_Left, XK_Up, XK_Right, /*35 0x23*/
    XK_Down, XK_Select, XK_Print, XK_Execute, NoSymbol, /*40 0x28*/
    XK_Insert, XK_Delete, XK_Help, NoSymbol, NoSymbol, /*45 0x2D*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*50 0x32*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*55 0x37*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*60 0x3C*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*65 0x41*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*70 0x46*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*75 0x4B*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*80 0x50*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*85 0x55*/
    NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol, /*90 0x5A*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*95 0x5F*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*100 0x64*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*105 0x69*/
    NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3, /*110 0x6E*/
    XK_F4, XK_F5, XK_F6, XK_F7, XK_F8, /*115 0x73*/
    XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, /*120 0x78*/
    XK_F14, XK_F15, XK_F16, XK_F17, XK_F18, /*125 0x7D*/
    XK_F19, XK_F20, XK_F21, XK_F22, XK_F23, /*130 0x82*/
    XK_F24, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*135 0x87*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_Num_Lock, /*140 0x8C*/
    XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*145 0x91*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*150 0x96*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*155 0x9B*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*160 0xA0*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*165 0xA5*/
    NoSymbol, NoSymbol, NoSymbol, XF86XK_AudioMute, XF86XK_AudioLowerVolume, /*170 0xAA*/
    XF86XK_AudioRaiseVolume, XF86XK_AudioNext, XF86XK_AudioPrev, XF86XK_AudioStop, XF86XK_AudioPlay, /*175 0xAF*/
    XF86XK_Mail, XF86XK_AudioMedia, XF86XK_Launch0, XF86XK_Launch1  /*180 0xB4*/
};

/*
 * Prototypes for local functions defined in this file:
 */

static KeySym		KeycodeToKeysym(unsigned int keycode,













<










|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
<







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
/*
 * tkWinKey.c --
 *
 *	This file contains X emulation routines for keyboard related
 *	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.
 */

#include "tkWinInt.h"


/*
 * The keymap table holds mappings of Windows keycodes to X keysyms. If
 * Windows ever comes along and changes the value of their keycodes, this will
 * break all kinds of things. However, this table lookup is much faster than
 * the alternative, in which we walked a list of keycodes looking for a match.
 * Since this lookup is performed for every Windows keypress event, it seems
 * like a worthwhile improvement to use the table.
 */

#define MAX_KEYCODE 179 /* VK_MEDIA_PLAY_PAUSE is the last entry in our table below */
/* cf. https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx */

static KeySym keymap[] = {
    NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, XK_BackSpace, XK_Tab,
    NoSymbol, NoSymbol, XK_Clear, XK_Return, NoSymbol,
    NoSymbol, XK_Shift_L, XK_Control_L, XK_Alt_L, XK_Pause,
    XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, XK_Escape, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, XK_space, XK_Prior, XK_Next,
    XK_End, XK_Home, XK_Left, XK_Up, XK_Right,
    XK_Down, XK_Select, XK_Print, XK_Execute, NoSymbol,
    XK_Insert, XK_Delete, XK_Help, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3,
    XK_F4, XK_F5, XK_F6, XK_F7, XK_F8,
    XK_F9, XK_F10, XK_F11, XK_F12, XK_F13,
    XK_F14, XK_F15, XK_F16, XK_F17, XK_F18,
    XK_F19, XK_F20, XK_F21, XK_F22, XK_F23,
    XK_F24, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_Num_Lock,
    XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*150 0x96*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*155 0x9b*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*160 0xa0*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*165 0xa5*/
    NoSymbol, NoSymbol, NoSymbol, XK_XF86AudioMute, XK_XF86AudioLowerVolume, /*170 0xaa*/
    XK_XF86AudioRaiseVolume, XK_XF86AudioNext, XK_XF86AudioPrev, XK_XF86AudioStop, XK_XF86AudioPlay  /*175 0xaf*/

};

/*
 * Prototypes for local functions defined in this file:
 */

static KeySym		KeycodeToKeysym(unsigned int keycode,
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111




112












113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128


129

130
131
132
133
134
135
136
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred: needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{
    XKeyEvent *keyEv = &eventPtr->xkey;
    int len;
    char buf[6];
    (void)winPtr;

    Tcl_DStringInit(dsPtr);
    if (keyEv->send_event == -1) {
	TkKeyEvent *ev = (TkKeyEvent *)keyEv;
	if (ev->nbytes > 0) {
	    Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
		    ev->trans_chars, ev->nbytes, dsPtr);
	}
    } else if (keyEv->send_event == -3) {

















	/*
	 * Special case for WM_UNICHAR and win2000 multilingual IME input

	 */

	len = TkUniCharToUtf(keyEv->keycode, buf);
	Tcl_DStringAppend(dsPtr, buf, len);
    } else {
	/*
	 * This is an event generated from generic code. It has no nchars or
	 * trans_chars members.
	 */

	KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0);

	if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
		|| (keysym == XK_Return) || (keysym == XK_Tab)) {


	    len = TkUniCharToUtf(keysym & 255, buf);

	    Tcl_DStringAppend(dsPtr, buf, len);
	}
    }
    return Tcl_DStringValue(dsPtr);
}

/*







|








<
<
<



<
|

|

|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>

|
>


<
|










>
>
|
>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97



98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred: needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{
    XKeyEvent *keyEv = &eventPtr->xkey;




    Tcl_DStringInit(dsPtr);
    if (keyEv->send_event == -1) {

	if (keyEv->nbytes > 0) {
	    Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
		    keyEv->trans_chars, keyEv->nbytes, dsPtr);
	}
    } else if (keyEv->send_event == -2) {
	/*
	 * Special case for win2000 multi-lingal IME input. xkey.trans_chars[]
	 * already contains a UNICODE char.
	 */

	int unichar;
	char buf[TCL_UTF_MAX];
	int len;

	unichar = keyEv->trans_chars[1] & 0xff;
	unichar <<= 8;
	unichar |= keyEv->trans_chars[0] & 0xff;

	len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf);

	Tcl_DStringAppend(dsPtr, buf, len);
    } else if (keyEv->send_event == -3) {
	/*
	 * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a
	 * UTF-8 char.
	 */


	Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes);
    } else {
	/*
	 * This is an event generated from generic code. It has no nchars or
	 * trans_chars members.
	 */

	KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0);

	if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
		|| (keysym == XK_Return) || (keysym == XK_Tab)) {
	    char buf[TCL_UTF_MAX];
	    int len;

	    len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf);
	    Tcl_DStringAppend(dsPtr, buf, len);
	}
    }
    return Tcl_DStringValue(dsPtr);
}

/*
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
KeySym
XKeycodeToKeysym(
    Display *display,
    unsigned int keycode,
    int index)
{
    int state = 0;
    (void)display;

    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}

KeySym
XkbKeycodeToKeysym(
    Display *display,
    unsigned int keycode,
    int group,
    int index)
{
    int state = 0;
    (void)display;
    (void)group;

    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







166
167
168
169
170
171
172


















173
174
175
176
177
178
179
KeySym
XKeycodeToKeysym(
    Display *display,
    unsigned int keycode,
    int index)
{
    int state = 0;



















    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
KeycodeToKeysym(
    unsigned int keycode,
    int state,
    int noascii)
{
    BYTE keys[256];
    int result, deadkey, shift;
    WCHAR buf[4];
    unsigned int scancode = MapVirtualKeyW(keycode, 0);

    /*
     * Do not run keycodes of lock keys through ToUnicode(). One of ToUnicode()'s
     * side effects is to handle the lights on the keyboard, and we don't want
     * to mess that up.
     */

    if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL ||
	    keycode == VK_NUMLOCK) {
	goto skipToUnicode;
    }

    /*
     * Use MapVirtualKeyW() to detect some dead keys.
     */

    if (MapVirtualKeyW(keycode, 2) > 0x7fffUL) {
	return XK_Multi_key;
    }

    /*
     * Set up a keyboard with correct modifiers
     */








|
|


|






|



|


|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
KeycodeToKeysym(
    unsigned int keycode,
    int state,
    int noascii)
{
    BYTE keys[256];
    int result, deadkey, shift;
    char buf[4];
    unsigned int scancode = MapVirtualKey(keycode, 0);

    /*
     * Do not run keycodes of lock keys through ToAscii(). One of ToAscii()'s
     * side effects is to handle the lights on the keyboard, and we don't want
     * to mess that up.
     */

    if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL ||
	    keycode == VK_NUMLOCK) {
	goto skipToAscii;
    }

    /*
     * Use MapVirtualKey() to detect some dead keys.
     */

    if (MapVirtualKey(keycode, 2) > 0x7fffUL) {
	return XK_Multi_key;
    }

    /*
     * Set up a keyboard with correct modifiers
     */

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    if (state & Mod3Mask) {
	keys[VK_SCROLL] = 1;
    }
    if (state & Mod1Mask) {
	keys[VK_NUMLOCK] = 1;
    }

    result = ToUnicode(keycode, scancode, keys, buf, 4, 0);

    if (result < 0) {
	/*
	 * Win95/98: This was a dead char, which is now remembered by the
	 * keyboard. Call ToUnicode() again to forget it.
	 * WinNT: This was a dead char, overwriting any previously remembered
	 * key. Calling ToUnicode() again does not affect anything.
	 */

	ToUnicode(keycode, scancode, keys, buf, 4, 0);
	return XK_Multi_key;
    }

    if (result == 2) {
	/*
	 * This was a dead char, and there were one previously remembered by
	 * the keyboard. Call ToUnicode() again with proper parameters to
	 * restore it.
	 *
	 * Get information about the old char
	 */

	deadkey = VkKeyScanW(buf[0]);
	shift = deadkey >> 8;
	deadkey &= 255;
	scancode = MapVirtualKeyW(deadkey, 0);

	/*
	 * Set up a keyboard with proper modifier keys
	 */

	memset(keys, 0, 256);
	if (shift & 1) {
	    keys[VK_SHIFT] = 0x80;
	}
	if (shift & 2) {
	    keys[VK_CONTROL] = 0x80;
	}
	if (shift & 4) {
	    keys[VK_MENU] = 0x80;
	}
	ToUnicode(deadkey, scancode, keys, buf, 4, 0);
	return XK_Multi_key;
    }

    /*
     * Keycode mapped to a valid Unicode character. Since the keysyms for
     * alphanumeric characters map onto Unicode, we just return it.
     *
     * We treat 0x7F as a special case mostly for backwards compatibility. In
     * versions of Tk<=8.2, Control-Backspace returned "XK_BackSpace" as the X
     * Keysym. This was due to the fact that we did not initialize the keys
     * array properly when we passed it to ToUnicode, above. We had previously
     * not been setting the state bit for the Control key. When we fixed that,
     * we found that Control-Backspace on Windows is interpreted as ASCII-127
     * (0x7F), which corresponds to the Delete key.
     *
     * Upon discovering this, we realized we had two choices: return XK_Delete
     * or return XK_BackSpace. If we returned XK_Delete, that could be
     * considered "more correct" (although the correctness would be dependent
     * on whether you believe that ToUnicode is doing the right thing in that
     * case); however, this would break backwards compatibility, and worse, it
     * would limit application programmers; they would effectively be unable
     * to bind to <Control-Backspace> on Windows. We therefore chose instead
     * to return XK_BackSpace (handled here by letting the code "fall-through"
     * to the return statement below, which works because the keycode for this
     * event is VK_BACKSPACE, and the keymap table maps that keycode to
     * XK_BackSpace).
     */

    if (result == 1 && buf[0] >= 0x20 && buf[0] != 0x7F) {
	return (KeySym) buf[0];
    }

    /*
     * Keycode is a non-alphanumeric key, so we have to do the lookup.
     */

  skipToUnicode:
    if (keycode > MAX_KEYCODE) {
	return NoSymbol;
    }
    switch (keycode) {
	/*
	 * Windows only gives us an undifferentiated VK_CONTROL code (for
	 * example) when either Control key is pressed. To distinguish between
	 * left and right, we use the Extended flag. Indeed, the right Control
	 * and Alt (aka Menu) keys are such extended keys (which their left
	 * counterparts are not).
	 * Regarding the shift case, Windows does not set the Extended flag for
	 * the neither the left nor the right shift key. As a consequence another
	 * way to distinguish between the two keys is to query the state of one
	 * of the two to determine which was actually pressed. So if the keycode

	 * indicates Shift, do this extra test. If the right-side key was
	 * pressed, return the appropriate keycode. Otherwise, we fall through
	 * and rely on the keymap table to hold the correct keysym value.
	 * Note: this little trick only works for KeyPress, not for KeyRelease,
	 * for reasons stated in bug [2945130]
	 */

    case VK_CONTROL:
        if (state & EXTENDED_MASK) {
            return XK_Control_R;
        }
	break;
    case VK_SHIFT:
	if (GetKeyState(VK_RSHIFT) & 0x80) {
	    return XK_Shift_R;
	}
	break;
    case VK_MENU:
        if (state & EXTENDED_MASK) {
            return XK_Alt_R;
        }
	break;
    }
    return keymap[keycode];
}

/*
 *----------------------------------------------------------------------







|




|

|


|






|





|


|















|




|
|




|






|
|









|
|






|







<
<
<
<
<
|
|
>
|
|
|
<
<



|
|
|







|
|
|







251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344





345
346
347
348
349
350


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    if (state & Mod3Mask) {
	keys[VK_SCROLL] = 1;
    }
    if (state & Mod1Mask) {
	keys[VK_NUMLOCK] = 1;
    }

    result = ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);

    if (result < 0) {
	/*
	 * Win95/98: This was a dead char, which is now remembered by the
	 * keyboard. Call ToAscii() again to forget it.
	 * WinNT: This was a dead char, overwriting any previously remembered
	 * key. Calling ToAscii() again does not affect anything.
	 */

	ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
	return XK_Multi_key;
    }

    if (result == 2) {
	/*
	 * This was a dead char, and there were one previously remembered by
	 * the keyboard. Call ToAscii() again with proper parameters to
	 * restore it.
	 *
	 * Get information about the old char
	 */

	deadkey = VkKeyScan(buf[0]);
	shift = deadkey >> 8;
	deadkey &= 255;
	scancode = MapVirtualKey(deadkey, 0);

	/*
	 * Set up a keyboard with proper modifier keys
	 */

	memset(keys, 0, 256);
	if (shift & 1) {
	    keys[VK_SHIFT] = 0x80;
	}
	if (shift & 2) {
	    keys[VK_CONTROL] = 0x80;
	}
	if (shift & 4) {
	    keys[VK_MENU] = 0x80;
	}
	ToAscii(deadkey, scancode, keys, (LPWORD) buf, 0);
	return XK_Multi_key;
    }

    /*
     * Keycode mapped to a valid Latin-1 character. Since the keysyms for
     * alphanumeric characters map onto Latin-1, we just return it.
     *
     * We treat 0x7F as a special case mostly for backwards compatibility. In
     * versions of Tk<=8.2, Control-Backspace returned "XK_BackSpace" as the X
     * Keysym. This was due to the fact that we did not initialize the keys
     * array properly when we passed it to ToAscii, above. We had previously
     * not been setting the state bit for the Control key. When we fixed that,
     * we found that Control-Backspace on Windows is interpreted as ASCII-127
     * (0x7F), which corresponds to the Delete key.
     *
     * Upon discovering this, we realized we had two choices: return XK_Delete
     * or return XK_BackSpace. If we returned XK_Delete, that could be
     * considered "more correct" (although the correctness would be dependant
     * on whether you believe that ToAscii is doing the right thing in that
     * case); however, this would break backwards compatibility, and worse, it
     * would limit application programmers; they would effectively be unable
     * to bind to <Control-Backspace> on Windows. We therefore chose instead
     * to return XK_BackSpace (handled here by letting the code "fall-through"
     * to the return statement below, which works because the keycode for this
     * event is VK_BACKSPACE, and the keymap table maps that keycode to
     * XK_BackSpace).
     */

    if (result == 1 && UCHAR(buf[0]) >= 0x20 && UCHAR(buf[0]) != 0x7F) {
	return (KeySym) UCHAR(buf[0]);
    }

    /*
     * Keycode is a non-alphanumeric key, so we have to do the lookup.
     */

  skipToAscii:
    if (keycode > MAX_KEYCODE) {
	return NoSymbol;
    }
    switch (keycode) {
	/*
	 * Windows only gives us an undifferentiated VK_CONTROL code (for
	 * example) when either Control key is pressed. To distinguish between





	 * left and right, we have to query the state of one of the two to
	 * determine which was actually pressed. So if the keycode indicates
	 * Control, Shift, or Menu (the key that everybody else calls Alt), do
	 * this extra test. If the right-side key was pressed, return the
	 * appropriate keycode. Otherwise, we fall through and rely on the
	 * keymap table to hold the correct keysym value.


	 */

    case VK_CONTROL:
	if (GetKeyState(VK_RCONTROL) & 0x80) {
	    return XK_Control_R;
	}
	break;
    case VK_SHIFT:
	if (GetKeyState(VK_RSHIFT) & 0x80) {
	    return XK_Shift_R;
	}
	break;
    case VK_MENU:
	if (GetKeyState(VK_RMENU) & 0x80) {
	    return XK_Alt_R;
	}
	break;
    }
    return keymap[keycode];
}

/*
 *----------------------------------------------------------------------
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    }

    /*
     * Create an array of the keycodes for all modifier keys.
     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree(dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = 0;
    arraySize = KEYCODE_ARRAY_SIZE;
    dispPtr->modKeyCodes = (KeyCode *)ckalloc(KEYCODE_ARRAY_SIZE * sizeof(KeyCode));

    for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}

	/*
	 * Make sure that the keycode isn't already in the array.
	 */

	for (j = 0; j < dispPtr->numModKeyCodes; j++) {
	    if (dispPtr->modKeyCodes[j] == *codePtr) {
		goto nextModCode;
	    }
	}
	if (dispPtr->numModKeyCodes >= arraySize) {
	    KeyCode *newKey;

	    /*
	     * Ran out of space in the array; grow it.
	     */

	    arraySize *= 2;

	    newKey = (KeyCode *)ckalloc(arraySize * sizeof(KeyCode));
	    memcpy(newKey, dispPtr->modKeyCodes,
		    dispPtr->numModKeyCodes * sizeof(KeyCode));
	    ckfree(dispPtr->modKeyCodes);
	    dispPtr->modKeyCodes = newKey;
	}
	dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
	dispPtr->numModKeyCodes++;
	nextModCode: continue;
    }
    XFreeModifiermap(modMapPtr);
}

/*
 * When mapping from a keysym to a keycode, need information about the
 * modifier state that should be used so that when they call XkbKeycodeToKeysym
 * taking into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    int i;
    SHORT result;
    int shift;
    (void)tkwin;

    eventPtr->xkey.keycode = 0;
    if (keySym == NoSymbol) {
	return;
    }

    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */

    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keySym) {
	    eventPtr->xkey.keycode = i;
	    return;
	}
    }
    if (keySym >= 0x20) {
	result = VkKeyScanW((WCHAR) keySym);
	if (result != -1) {
	    shift = result >> 8;
	    if (shift & 1)
		eventPtr->xkey.state |= ShiftMask;
	    if (shift & 2)
		eventPtr->xkey.state |= ControlMask;
	    if (shift & 4)







|



|
>















|






>
|
|
|
|
|










|












<



















|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
    }

    /*
     * Create an array of the keycodes for all modifier keys.
     */

    if (dispPtr->modKeyCodes != NULL) {
	ckfree((char *) dispPtr->modKeyCodes);
    }
    dispPtr->numModKeyCodes = 0;
    arraySize = KEYCODE_ARRAY_SIZE;
    dispPtr->modKeyCodes = (KeyCode *) ckalloc((unsigned)
	    (KEYCODE_ARRAY_SIZE * sizeof(KeyCode)));
    for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
	if (*codePtr == 0) {
	    continue;
	}

	/*
	 * Make sure that the keycode isn't already in the array.
	 */

	for (j = 0; j < dispPtr->numModKeyCodes; j++) {
	    if (dispPtr->modKeyCodes[j] == *codePtr) {
		goto nextModCode;
	    }
	}
	if (dispPtr->numModKeyCodes >= arraySize) {
	    KeyCode *new;

	    /*
	     * Ran out of space in the array; grow it.
	     */

	    arraySize *= 2;
	    new = (KeyCode *) ckalloc((unsigned)
		    (arraySize * sizeof(KeyCode)));
	    memcpy((void *) new, (void *) dispPtr->modKeyCodes,
		    (dispPtr->numModKeyCodes * sizeof(KeyCode)));
	    ckfree((char *) dispPtr->modKeyCodes);
	    dispPtr->modKeyCodes = new;
	}
	dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
	dispPtr->numModKeyCodes++;
	nextModCode: continue;
    }
    XFreeModifiermap(modMapPtr);
}

/*
 * When mapping from a keysym to a keycode, need information about the
 * modifier state that should be used so that when they call XKeycodeToKeysym
 * taking into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    int i;
    SHORT result;
    int shift;


    eventPtr->xkey.keycode = 0;
    if (keySym == NoSymbol) {
	return;
    }

    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */

    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keySym) {
	    eventPtr->xkey.keycode = i;
	    return;
	}
    }
    if (keySym >= 0x20) {
	result = VkKeyScan((char) keySym);
	if (result != -1) {
	    shift = result >> 8;
	    if (shift & 1)
		eventPtr->xkey.state |= ShiftMask;
	    if (shift & 2)
		eventPtr->xkey.state |= ControlMask;
	    if (shift & 4)
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
KeyCode
XKeysymToKeycode(
    Display *display,
    KeySym keysym)
{
    int i;
    SHORT result;
    (void)display;

    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */

    if (keysym == NoSymbol) {
	return 0;
    }
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keysym) {
	    return ((KeyCode) i);
	}
    }
    if (keysym >= 0x20) {
	result = VkKeyScanW((WCHAR) keysym);
	if (result != -1) {
	    return (KeyCode) (result & 0xff);
	}
    }

    return 0;
}







<
















|







618
619
620
621
622
623
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
KeyCode
XKeysymToKeycode(
    Display *display,
    KeySym keysym)
{
    int i;
    SHORT result;


    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */

    if (keysym == NoSymbol) {
	return 0;
    }
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keysym) {
	    return ((KeyCode) i);
	}
    }
    if (keysym >= 0x20) {
	result = VkKeyScan((char) keysym);
	if (result != -1) {
	    return (KeyCode) (result & 0xff);
	}
    }

    return 0;
}
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
 *----------------------------------------------------------------------
 */

XModifierKeymap	*
XGetModifierMapping(
    Display *display)
{
    XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
    (void)display;

    map->max_keypermod = 1;
    map->modifiermap = (KeyCode *)ckalloc(sizeof(KeyCode) * 8);
    map->modifiermap[ShiftMapIndex] = VK_SHIFT;
    map->modifiermap[LockMapIndex] = VK_CAPITAL;
    map->modifiermap[ControlMapIndex] = VK_CONTROL;
    map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;
    map->modifiermap[Mod2MapIndex] = VK_MENU;
    map->modifiermap[Mod3MapIndex] = VK_SCROLL;
    map->modifiermap[Mod4MapIndex] = 0;







|
|


|







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
 *----------------------------------------------------------------------
 */

XModifierKeymap	*
XGetModifierMapping(
    Display *display)
{
    XModifierKeymap *map = (XModifierKeymap *)
	    ckalloc(sizeof(XModifierKeymap));

    map->max_keypermod = 1;
    map->modifiermap = (KeyCode *) ckalloc(sizeof(KeyCode)*8);
    map->modifiermap[ShiftMapIndex] = VK_SHIFT;
    map->modifiermap[LockMapIndex] = VK_CAPITAL;
    map->modifiermap[ControlMapIndex] = VK_CONTROL;
    map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;
    map->modifiermap[Mod2MapIndex] = VK_MENU;
    map->modifiermap[Mod3MapIndex] = VK_SCROLL;
    map->modifiermap[Mod4MapIndex] = 0;
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
 *----------------------------------------------------------------------
 */

int
XFreeModifiermap(
    XModifierKeymap *modmap)
{
    ckfree(modmap->modifiermap);
    ckfree(modmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XStringToKeysym --







|
|







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
 *----------------------------------------------------------------------
 */

int
XFreeModifiermap(
    XModifierKeymap *modmap)
{
    ckfree((char *) modmap->modifiermap);
    ckfree((char *) modmap);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XStringToKeysym --
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
 *----------------------------------------------------------------------
 */

KeySym
XStringToKeysym(
    _Xconst char *string)
{
    (void)string;

    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString --







<
<







725
726
727
728
729
730
731


732
733
734
735
736
737
738
 *----------------------------------------------------------------------
 */

KeySym
XStringToKeysym(
    _Xconst char *string)
{


    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString --
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
{
    (void)keysym;

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<










748
749
750
751
752
753
754


755
756
757
758
759
760
761
762
763
764
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
{


    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinMenu.c.

1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16


17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 * tkWinMenu.c --
 *
 *	This module implements the Windows platform-specific features of
 *	menus.
 *
 * Copyright (c) 1996-1998 by 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.
 */



#define OEMRESOURCE
#include "tkWinInt.h"
#include "tkMenu.h"



/*
 * The class of the window for popup menus.
 */

#define MENU_CLASS_NAME			L"MenuWindowClass"
#define EMBEDDED_MENU_CLASS_NAME	L"EmbeddedMenuWindowClass"

/*
 * Used to align a windows bitmap inside a rectangle
 */

#define ALIGN_BITMAP_LEFT	0x00000001
#define ALIGN_BITMAP_RIGHT	0x00000002













>
>



>
>





|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * tkWinMenu.c --
 *
 *	This module implements the Windows platform-specific features of
 *	menus.
 *
 * Copyright (c) 1996-1998 by 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.
 */

#define WINVER        0x0500   /* Requires Windows 2K definitions */
#define _WIN32_WINNT  0x0500
#define OEMRESOURCE
#include "tkWinInt.h"
#include "tkMenu.h"

#include <string.h>

/*
 * The class of the window for popup menus.
 */

#define MENU_CLASS_NAME			"MenuWindowClass"
#define EMBEDDED_MENU_CLASS_NAME	"EmbeddedMenuWindowClass"

/*
 * Used to align a windows bitmap inside a rectangle
 */

#define ALIGN_BITMAP_LEFT	0x00000001
#define ALIGN_BITMAP_RIGHT	0x00000002
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
static int indicatorDimensions[2];
				/* The dimensions of the indicator space in a
				 * menu entry. Calculated at init time to save
				 * time. */

static BOOL showMenuAccelerators;

typedef struct {
    int inPostMenu;		/* We cannot be re-entrant like X Windows. */
    WORD lastCommandID;		/* The last command ID we allocated. */
    HWND menuHWND;		/* A window to service popup-menu messages
				 * in. */
    HWND embeddedMenuHWND;	/* A window to service embedded menu
				 * messages */
    int oldServiceMode;		/* Used while processing a menu; we need to







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
static int indicatorDimensions[2];
				/* The dimensions of the indicator space in a
				 * menu entry. Calculated at init time to save
				 * time. */

static BOOL showMenuAccelerators;

typedef struct ThreadSpecificData {
    int inPostMenu;		/* We cannot be re-entrant like X Windows. */
    WORD lastCommandID;		/* The last command ID we allocated. */
    HWND menuHWND;		/* A window to service popup-menu messages
				 * in. */
    HWND embeddedMenuHWND;	/* A window to service embedded menu
				 * messages */
    int oldServiceMode;		/* Used while processing a menu; we need to
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
			    Drawable d, GC gc, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int x, int y,
			    int width, int height);
static void		DrawWindowsSystemBitmap(Display *display,
			    Drawable drawable, GC gc, const RECT *rectPtr,
			    int bitmapID, int alignFlags);
static void		FreeID(WORD commandID);
static char *		GetEntryText(TkMenu *menuPtr, TkMenuEntry *mePtr);
static void		GetMenuAccelGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static void		GetMenuLabelGeometry(TkMenuEntry *mePtr,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);







|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
			    Drawable d, GC gc, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int x, int y,
			    int width, int height);
static void		DrawWindowsSystemBitmap(Display *display,
			    Drawable drawable, GC gc, const RECT *rectPtr,
			    int bitmapID, int alignFlags);
static void		FreeID(WORD commandID);
static TCHAR *		GetEntryText(TkMenuEntry *mePtr);
static void		GetMenuAccelGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static void		GetMenuLabelGeometry(TkMenuEntry *mePtr,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
static void		ReconfigureWindowsMenu(ClientData clientData);
static void		RecursivelyClearActiveMenu(TkMenu *menuPtr);
static void		SetDefaults(int firstTime);
static LRESULT CALLBACK	TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK	TkWinEmbeddedMenuProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);

static inline void
ScheduleMenuReconfigure(
    TkMenu *menuPtr)
{
    if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
	menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
	Tcl_DoWhenIdle(ReconfigureWindowsMenu, menuPtr);
    }
}

static inline void
CallPendingReconfigureImmediately(
    TkMenu *menuPtr)
{
    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
	Tcl_CancelIdleCall(ReconfigureWindowsMenu, menuPtr);
	ReconfigureWindowsMenu(menuPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetNewID --
 *
 *	Allocates a new menu id and marks it in use.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







187
188
189
190
191
192
193




















194
195
196
197
198
199
200
static void		ReconfigureWindowsMenu(ClientData clientData);
static void		RecursivelyClearActiveMenu(TkMenu *menuPtr);
static void		SetDefaults(int firstTime);
static LRESULT CALLBACK	TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK	TkWinEmbeddedMenuProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);





















/*
 *----------------------------------------------------------------------
 *
 * GetNewID --
 *
 *	Allocates a new menu id and marks it in use.
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    WORD curID = tsdPtr->lastCommandID;

    while (1) {
	Tcl_HashEntry *commandEntryPtr;
	int isNew;

	/*
	 * Try the next ID number, taking care to wrap rather than stray
	 * into the system menu IDs.  [Bug 3235256]
	 */
	if (++curID >= 0xF000) {
	    curID = 1;
	}

	/* Return error when we've checked all IDs without success. */
	if (curID == tsdPtr->lastCommandID) {
	    return TCL_ERROR;
	}

	commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
		INT2PTR(curID), &isNew);
	if (isNew) {
	    Tcl_SetHashValue(commandEntryPtr, mePtr);
	    *menuIDPtr = curID;
	    tsdPtr->lastCommandID = curID;
	    return TCL_OK;
	}
    }
}








|















|
|
|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    WORD curID = tsdPtr->lastCommandID;

    while (1) {
	Tcl_HashEntry *commandEntryPtr;
	int new;

	/*
	 * Try the next ID number, taking care to wrap rather than stray
	 * into the system menu IDs.  [Bug 3235256]
	 */
	if (++curID >= 0xF000) {
	    curID = 1;
	}

	/* Return error when we've checked all IDs without success. */
	if (curID == tsdPtr->lastCommandID) {
	    return TCL_ERROR;
	}

	commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
		INT2PTR(curID), &new);
	if (new) {
	    Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);
	    *menuIDPtr = curID;
	    tsdPtr->lastCommandID = curID;
	    return TCL_OK;
	}
    }
}

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

    /*
     * If the menuHWND is NULL, this table has been finalized already.
     */

    if (tsdPtr->menuHWND != NULL) {
	Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
		INT2PTR(commandID));

	if (entryPtr != NULL) {
	    Tcl_DeleteHashEntry(entryPtr);
	}
    }
}

/*







|
<







274
275
276
277
278
279
280
281

282
283
284
285
286
287
288

    /*
     * If the menuHWND is NULL, this table has been finalized already.
     */

    if (tsdPtr->menuHWND != NULL) {
	Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
		((char *) NULL) + commandID);

	if (entryPtr != NULL) {
	    Tcl_DeleteHashEntry(entryPtr);
	}
    }
}

/*
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
    HMENU winMenuHdl;
    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    winMenuHdl = CreatePopupMenu();

    if (winMenuHdl == NULL) {
    	Tcl_SetObjResult(menuPtr->interp, Tcl_NewStringObj(
		"No more menus can be allocated.", -1));
	Tcl_SetErrorCode(menuPtr->interp, "TK", "MENU", "SYSTEM_RESOURCES", NULL);
    	return TCL_ERROR;
    }

    /*
     * We hash all of the HMENU's so that we can get their menu ptrs back when
     * dispatch messages.
     */

    hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
	    (char *) winMenuHdl, &newEntry);
    Tcl_SetHashValue(hashEntryPtr, menuPtr);

    menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







>

<
|
|










|







311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
    HMENU winMenuHdl;
    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    winMenuHdl = CreatePopupMenu();

    if (winMenuHdl == NULL) {

    	Tcl_AppendResult(menuPtr->interp, "No more menus can be allocated.",
    		(char *) NULL);
    	return TCL_ERROR;
    }

    /*
     * We hash all of the HMENU's so that we can get their menu ptrs back when
     * dispatch messages.
     */

    hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
	    (char *) winMenuHdl, &newEntry);
    Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr);

    menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
 */

void
TkpDestroyMenu(
    TkMenu *menuPtr)		/* The common menu structure */
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    const char *searchName;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
	Tcl_CancelIdleCall(ReconfigureWindowsMenu, menuPtr);
    }

    if (winMenuHdl == NULL) {
	return;
    }

    if (menuPtr->menuFlags & MENU_SYSTEM_MENU) {
	TkMenuEntry *searchEntryPtr;
	Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp);
	char *menuName = (char *)Tcl_GetHashKey(tablePtr,
		menuPtr->menuRefPtr->hashEntryPtr);

	/*
	 * Search for the menu in the menubar, if it is present, get the
	 * wrapper window associated with the toplevel and reset its
	 * system menu to the default menu.
	 */







|




|









|







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
 */

void
TkpDestroyMenu(
    TkMenu *menuPtr)		/* The common menu structure */
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *searchName;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
	Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr);
    }

    if (winMenuHdl == NULL) {
	return;
    }

    if (menuPtr->menuFlags & MENU_SYSTEM_MENU) {
	TkMenuEntry *searchEntryPtr;
	Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp);
	char *menuName = Tcl_GetHashKey(tablePtr,
		menuPtr->menuRefPtr->hashEntryPtr);

	/*
	 * Search for the menu in the menubar, if it is present, get the
	 * wrapper window associated with the toplevel and reset its
	 * system menu to the default menu.
	 */
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
	/*
	 * Remove the menu from the menu hash table, then destroy the handle.
	 * If the menuHWND is NULL, this table has been finalized already.
	 */

	if (tsdPtr->menuHWND != NULL) {
	    Tcl_HashEntry *hashEntryPtr =
		Tcl_FindHashEntry(&tsdPtr->winMenuTable, winMenuHdl);

	    if (hashEntryPtr != NULL) {
		Tcl_DeleteHashEntry(hashEntryPtr);
	    }
	}
 	DestroyMenu(winMenuHdl);
    }
    menuPtr->platformData = NULL;







|
<







399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
	/*
	 * Remove the menu from the menu hash table, then destroy the handle.
	 * If the menuHWND is NULL, this table has been finalized already.
	 */

	if (tsdPtr->menuHWND != NULL) {
	    Tcl_HashEntry *hashEntryPtr =
		Tcl_FindHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl);

	    if (hashEntryPtr != NULL) {
		Tcl_DeleteHashEntry(hashEntryPtr);
	    }
	}
 	DestroyMenu(winMenuHdl);
    }
    menuPtr->platformData = NULL;
455
456
457
458
459
460
461


462

463
464
465
466
467
468
469
TkpDestroyMenuEntry(
    TkMenuEntry *mePtr)		/* The entry to destroy */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;

    if (NULL != winMenuHdl) {


	ScheduleMenuReconfigure(menuPtr);

    }
    FreeID((WORD) PTR2INT(mePtr->platformEntryData));
    mePtr->platformEntryData = NULL;
}

/*
 *----------------------------------------------------------------------







>
>
|
>







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
TkpDestroyMenuEntry(
    TkMenuEntry *mePtr)		/* The entry to destroy */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;

    if (NULL != winMenuHdl) {
	if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
	    menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
	    Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
	}
    }
    FreeID((WORD) PTR2INT(mePtr->platformEntryData));
    mePtr->platformEntryData = NULL;
}

/*
 *----------------------------------------------------------------------
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
GetEntryText(
    TkMenu *menuPtr,		/* The menu considered. */
    TkMenuEntry *mePtr)		/* A pointer to the menu entry. */
{
    char *itemText;

    if (mePtr->type == TEAROFF_ENTRY) {
	itemText = (char *)ckalloc(sizeof("(Tear-off)"));
	strcpy(itemText, "(Tear-off)");
    } else if (mePtr->imagePtr != NULL) {
	itemText = (char *)ckalloc(sizeof("(Image)"));
	strcpy(itemText, "(Image)");
    } else if (mePtr->bitmapPtr != NULL) {
	itemText = (char *)ckalloc(sizeof("(Pixmap)"));
	strcpy(itemText, "(Pixmap)");
    } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) {
	itemText = (char *)ckalloc(sizeof("( )"));
	strcpy(itemText, "( )");
    } else {
	int i;
	const char *label = (mePtr->labelPtr == NULL) ? ""
		: Tcl_GetString(mePtr->labelPtr);
	const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? ""
		: Tcl_GetString(mePtr->accelPtr);
	const char *p, *next;
	Tcl_DString itemString;
	int ch;

	/*
	 * We have to construct the string with an ampersand preceeding the
	 * underline character, and a tab seperating the text and the accel
	 * text. We have to be careful with ampersands in the string.
	 */

	Tcl_DStringInit(&itemString);

	for (p = label, i = 0; *p != '\0'; i++, p = next) {
	    if (i == mePtr->underline) {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    if (*p == '&') {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    next = p + TkUtfToUniChar(p, &ch);
	    Tcl_DStringAppend(&itemString, p, (int) (next - p));
	}
	if (mePtr->accelLength > 0) {
	    Tcl_DStringAppend(&itemString, "\t", 1);
	    for (p = accel, i = 0; *p != '\0'; i++, p = next) {
		if (*p == '&') {
		    Tcl_DStringAppend(&itemString, "&", 1);
		}
		next = p + TkUtfToUniChar(p, &ch);
		Tcl_DStringAppend(&itemString, p, (int) (next - p));
	    }
	}

	itemText = (char *)ckalloc(Tcl_DStringLength(&itemString) + 1);
	strcpy(itemText, Tcl_DStringValue(&itemString));
	Tcl_DStringFree(&itemString);
    }
    return itemText;
}

/*







<





|


|


|


|



|

|



<
















|








|




|







467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
GetEntryText(

    TkMenuEntry *mePtr)		/* A pointer to the menu entry. */
{
    char *itemText;

    if (mePtr->type == TEAROFF_ENTRY) {
	itemText = ckalloc(sizeof("(Tear-off)"));
	strcpy(itemText, "(Tear-off)");
    } else if (mePtr->imagePtr != NULL) {
	itemText = ckalloc(sizeof("(Image)"));
	strcpy(itemText, "(Image)");
    } else if (mePtr->bitmapPtr != NULL) {
	itemText = ckalloc(sizeof("(Pixmap)"));
	strcpy(itemText, "(Pixmap)");
    } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) {
	itemText = ckalloc(sizeof("( )"));
	strcpy(itemText, "( )");
    } else {
	int i;
	char *label = (mePtr->labelPtr == NULL) ? ""
		: Tcl_GetString(mePtr->labelPtr);
	char *accel = (mePtr->accelPtr == NULL) ? ""
		: Tcl_GetString(mePtr->accelPtr);
	const char *p, *next;
	Tcl_DString itemString;


	/*
	 * We have to construct the string with an ampersand preceeding the
	 * underline character, and a tab seperating the text and the accel
	 * text. We have to be careful with ampersands in the string.
	 */

	Tcl_DStringInit(&itemString);

	for (p = label, i = 0; *p != '\0'; i++, p = next) {
	    if (i == mePtr->underline) {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    if (*p == '&') {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    next = Tcl_UtfNext(p);
	    Tcl_DStringAppend(&itemString, p, (int) (next - p));
	}
	if (mePtr->accelLength > 0) {
	    Tcl_DStringAppend(&itemString, "\t", 1);
	    for (p = accel, i = 0; *p != '\0'; i++, p = next) {
		if (*p == '&') {
		    Tcl_DStringAppend(&itemString, "&", 1);
		}
		next = Tcl_UtfNext(p);
		Tcl_DStringAppend(&itemString, p, (int) (next - p));
	    }
	}

	itemText = ckalloc((unsigned)Tcl_DStringLength(&itemString) + 1);
	strcpy(itemText, Tcl_DStringValue(&itemString));
	Tcl_DStringFree(&itemString);
    }
    return itemText;
}

/*
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
 *----------------------------------------------------------------------
 */

static void
ReconfigureWindowsMenu(
    ClientData clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *itemText = NULL;
    LPCWSTR lpNewItem;
    UINT flags;
    UINT itemID;
    int i, count, systemMenu = 0, base;
    Tcl_DString translatedText;

    if (NULL == winMenuHdl) {
    	return;







|


|
|







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
 *----------------------------------------------------------------------
 */

static void
ReconfigureWindowsMenu(
    ClientData clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = (TkMenu *) clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    TCHAR *itemText = NULL;
    const TCHAR *lpNewItem;
    UINT flags;
    UINT itemID;
    int i, count, systemMenu = 0, base;
    Tcl_DString translatedText;

    if (NULL == winMenuHdl) {
    	return;
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	itemID = 0;
	Tcl_DStringInit(&translatedText);

	if ((menuPtr->menuType == MENUBAR) && (mePtr->type == TEAROFF_ENTRY)) {
	    continue;
	}

	itemText = GetEntryText(menuPtr, mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
		Tcl_DStringInit(&translatedText);
		Tcl_UtfToWCharDString(itemText, -1, &translatedText);
	    lpNewItem = (LPCWSTR) Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCWSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}

	/*
	 * Set enabling and disabling correctly.
	 */








|


<
|
|


|







586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
	itemID = 0;
	Tcl_DStringInit(&translatedText);

	if ((menuPtr->menuType == MENUBAR) && (mePtr->type == TEAROFF_ENTRY)) {
	    continue;
	}

	itemText = GetEntryText(mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {

	    Tcl_WinUtfToTChar(itemText, -1, &translatedText);
	    lpNewItem = Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCTSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}

	/*
	 * Set enabling and disabling correctly.
	 */

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709
710





711

712
713
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779




780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
			    & MENU_SYSTEM_MENU)) {
		Tcl_DString ds;
		TkMenuReferences *menuRefPtr;
		TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds,
			Tk_PathName(menuPtr->mainMenuPtr->tkwin), -1);
		Tcl_DStringAppend(&ds, ".system", 7);

		menuRefPtr = TkFindMenuReferences(menuPtr->interp,
			Tcl_DStringValue(&ds));

		Tcl_DStringFree(&ds);

		if ((menuRefPtr != NULL)
			&& (menuRefPtr->menuPtr != NULL)
			&& (menuPtr->parentTopLevelPtr != NULL)
			&& (systemMenuPtr->mainMenuPtr
				== menuRefPtr->menuPtr)) {
		    HMENU systemMenuHdl = (HMENU) systemMenuPtr->platformData;

		    HWND wrapper = TkWinGetWrapperWindow(menuPtr
			    ->parentTopLevelPtr);

		    if (wrapper != NULL) {
			DestroyMenu(systemMenuHdl);
			systemMenuHdl = GetSystemMenu(wrapper, FALSE);
			systemMenuPtr->menuFlags |= MENU_SYSTEM_MENU;
			systemMenuPtr->platformData =
				(TkMenuPlatformData) systemMenuHdl;





			ScheduleMenuReconfigure(systemMenuPtr);

		    }
		}
	    }
	    if (mePtr->childMenuRefPtr->menuPtr->menuFlags
		    & MENU_SYSTEM_MENU) {
		systemMenu++;
	    }
	}
	if (!systemMenu) {
	    InsertMenuW(winMenuHdl, 0xFFFFFFFF, flags, itemID, lpNewItem);

	}
	Tcl_DStringFree(&translatedText);
	if (itemText != NULL) {
	    ckfree(itemText);
	    itemText = NULL;
	}
    }


    if ((menuPtr->menuType == MENUBAR)
	    && (menuPtr->parentTopLevelPtr != NULL)) {

	HWND bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr);

	if (bar) {
	    DrawMenuBar(bar);
	}
    }

    menuPtr->menuFlags &= ~(MENU_RECONFIGURE_PENDING);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen so that the top left corner of the
 *      specified entry is located at the point (x, y) in screen coordinates.
 *      If the entry parameter is negative, the upper left corner of the
 *      menu itself is placed at the point.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *dummy,
    TkMenu *menuPtr,
    int x, int y, int index)
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    int result, flags;
    RECT noGoawayRect;
    POINT point;
    Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
    int oldServiceMode = Tcl_GetServiceMode();
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    tsdPtr->inPostMenu++;
    CallPendingReconfigureImmediately(menuPtr);





    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
	tsdPtr->inPostMenu--;
	return result;
    }

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
     * The post commands could have deleted the menu, which means
     * we are dead and should go away.
     */

    if (menuPtr->tkwin == NULL) {
	tsdPtr->inPostMenu--;







|










|

|
>


<






>
>
>
>
>
|
>









|
>











>
|
<













|
<
<
<












|

|









<


|
>
>
>
>







<
<
<
<
<
<
<







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737



738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769
770
771
772
773
774
775







776
777
778
779
780
781
782
			    & MENU_SYSTEM_MENU)) {
		Tcl_DString ds;
		TkMenuReferences *menuRefPtr;
		TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds,
			Tk_PathName(menuPtr->masterMenuPtr->tkwin), -1);
		Tcl_DStringAppend(&ds, ".system", 7);

		menuRefPtr = TkFindMenuReferences(menuPtr->interp,
			Tcl_DStringValue(&ds));

		Tcl_DStringFree(&ds);

		if ((menuRefPtr != NULL)
			&& (menuRefPtr->menuPtr != NULL)
			&& (menuPtr->parentTopLevelPtr != NULL)
			&& (systemMenuPtr->masterMenuPtr
				== menuRefPtr->menuPtr)) {
		    HMENU systemMenuHdl =
			(HMENU) systemMenuPtr->platformData;
		    HWND wrapper = TkWinGetWrapperWindow(menuPtr
			    ->parentTopLevelPtr);

		    if (wrapper != NULL) {
			DestroyMenu(systemMenuHdl);
			systemMenuHdl = GetSystemMenu(wrapper, FALSE);
			systemMenuPtr->menuFlags |= MENU_SYSTEM_MENU;
			systemMenuPtr->platformData =
				(TkMenuPlatformData) systemMenuHdl;
			if (!(systemMenuPtr->menuFlags
				& MENU_RECONFIGURE_PENDING)) {
			    systemMenuPtr->menuFlags
				    |= MENU_RECONFIGURE_PENDING;
			    Tcl_DoWhenIdle(ReconfigureWindowsMenu,
				    (ClientData) systemMenuPtr);
			}
		    }
		}
	    }
	    if (mePtr->childMenuRefPtr->menuPtr->menuFlags
		    & MENU_SYSTEM_MENU) {
		systemMenu++;
	    }
	}
	if (!systemMenu) {
	    (*tkWinProcs->insertMenu)(winMenuHdl, 0xFFFFFFFF, flags,
		    itemID, lpNewItem);
	}
	Tcl_DStringFree(&translatedText);
	if (itemText != NULL) {
	    ckfree(itemText);
	    itemText = NULL;
	}
    }


    if ((menuPtr->menuType == MENUBAR)
	    && (menuPtr->parentTopLevelPtr != NULL)) {
	HANDLE bar;
	bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr);

	if (bar) {
	    DrawMenuBar(bar);
	}
    }

    menuPtr->menuFlags &= ~(MENU_RECONFIGURE_PENDING);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostMenu --
 *
 *	Posts a menu on the screen



 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    int x, int y)
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    int result, flags;
    RECT noGoawayRect;
    POINT point;
    Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
    int oldServiceMode = Tcl_GetServiceMode();
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    tsdPtr->inPostMenu++;

    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
	Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr);
	ReconfigureWindowsMenu((ClientData) menuPtr);
    }

    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
	tsdPtr->inPostMenu--;
	return result;
    }








    /*
     * The post commands could have deleted the menu, which means
     * we are dead and should go away.
     */

    if (menuPtr->tkwin == NULL) {
	tsdPtr->inPostMenu--;
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
    }

    TrackPopupMenu(winMenuHdl, flags, x, y, 0,
	    tsdPtr->menuHWND, &noGoawayRect);
    Tcl_SetServiceMode(oldServiceMode);

    GetCursorPos(&point);
    TkWinPointerEvent(NULL, point.x, point.y);

    if (tsdPtr->inPostMenu) {
	tsdPtr->inPostMenu = 0;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --
 *
 *	Posts a tearoff menu on the screen so that the top left corner of the
 *      specified entry is located at the point (x, y) in screen coordinates.
 *      If the index parameter is negative, the upper left corner of the menu
 *      itself is placed at the point.  Adjusts the menu's position so that it
 *      fits on the screen, and maps and raises the menu.
 *
 * Results:
 *	Returns a standard Tcl Error.
 *
 * Side effects:
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    Tcl_Interp *dummy,		/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The root X,Y coordinates where we are
				 * posting */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;
    (void)dummy;

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * 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.
     */

    Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
	&vRootWidth, &vRootHeight);
    vRootWidth -= Tk_ReqWidth(menuPtr->tkwin);
    if (x > vRootX + vRootWidth) {
	x = vRootX + vRootWidth;
    }
    if (x < vRootX) {
	x = vRootX;
    }
    vRootHeight -= Tk_ReqHeight(menuPtr->tkwin);
    if (y > vRootY + vRootHeight) {
	y = vRootY + vRootHeight;
    }
    if (y < vRootY) {
	y = vRootY;
    }
    Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);
    if (!Tk_IsMapped(menuPtr->tkwin)) {
	Tk_MapWindow(menuPtr->tkwin);
    }
    TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuNewEntry --
 *
 *	Adds a pointer to a new menu entry structure with the platform-







|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







820
821
822
823
824
825
826
827
828
829
830
831
832
833































































































834
835
836
837
838
839
840
    }

    TrackPopupMenu(winMenuHdl, flags, x, y, 0,
	    tsdPtr->menuHWND, &noGoawayRect);
    Tcl_SetServiceMode(oldServiceMode);

    GetCursorPos(&point);
    Tk_PointerEvent(NULL, point.x, point.y);

    if (tsdPtr->inPostMenu) {
	tsdPtr->inPostMenu = 0;
    }
    return TCL_OK;
}
































































































/*
 *----------------------------------------------------------------------
 *
 * TkpMenuNewEntry --
 *
 *	Adds a pointer to a new menu entry structure with the platform-
969
970
971
972
973
974
975
976





977
978
979
980
981
982
983
{
    WORD commandID;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (GetNewID(mePtr, &commandID) != TCL_OK) {
    	return TCL_ERROR;
    }
    ScheduleMenuReconfigure(menuPtr);





    mePtr->platformEntryData = (TkMenuPlatformEntryData) INT2PTR(commandID);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
>
>
>
>
>







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
{
    WORD commandID;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (GetNewID(mePtr, &commandID) != TCL_OK) {
    	return TCL_ERROR;
    }

    if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
    	menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
    	Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
    }

    mePtr->platformEntryData = (TkMenuPlatformEntryData) INT2PTR(commandID);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT lResult;

    if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) {
	lResult = DefWindowProcW(hwnd, message, wParam, lParam);
    }
    return lResult;
}

/*
 *----------------------------------------------------------------------
 *







|







895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT lResult;

    if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) {
	lResult = DefWindowProc(hwnd, message, wParam, lParam);
    }
    return lResult;
}

/*
 *----------------------------------------------------------------------
 *
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
	lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		&lResult);
	if (lResult || (GetCapture() != hwnd)) {
	    break;
	}
	/* FALLTHRU */
    default:
	lResult = DefWindowProcW(hwnd, message, wParam, lParam);
	break;
    }
    return lResult;
}

/*
 *----------------------------------------------------------------------







|







994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
	lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		&lResult);
	if (lResult || (GetCapture() != hwnd)) {
	    break;
	}
	/* FALLTHRU */
    default:
	lResult = DefWindowProc(hwnd, message, wParam, lParam);
	break;
    }
    return lResult;
}

/*
 *----------------------------------------------------------------------
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173


1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
{
    Tcl_HashEntry *hashEntryPtr;
    int returnResult = 0;
    TkMenu *menuPtr;
    TkMenuEntry *mePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)phwnd;

    switch (*pMessage) {
    case WM_UNINITMENUPOPUP:
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*pwParam);
	if (hashEntryPtr != NULL) {
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
	    if ((menuPtr->menuRefPtr != NULL)
		    && (menuPtr->menuRefPtr->parentEntryPtr != NULL)) {
		TkPostSubmenu(menuPtr->interp,
			menuPtr->menuRefPtr->parentEntryPtr->menuPtr, NULL);
	    }
	}
	break;

    case WM_INITMENU:
	TkMenuInit();
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*pwParam);
	if (hashEntryPtr != NULL) {
	    tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
	    tsdPtr->modalMenuPtr = menuPtr;


	    CallPendingReconfigureImmediately(menuPtr);


	    RecursivelyClearActiveMenu(menuPtr);
	    if (!tsdPtr->inPostMenu) {
		Tcl_Interp *interp = menuPtr->interp;
		int code;


		Tcl_Preserve(interp);
		code = TkPreprocessMenu(menuPtr);
		if ((code != TCL_OK) && (code != TCL_CONTINUE)
			&& (code != TCL_BREAK)) {
		    Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
		    Tcl_BackgroundException(interp, code);
		}
		Tcl_Release(interp);
	    }
	    TkActivateMenuEntry(menuPtr, -1);
	    *plResult = 0;
	    returnResult = 1;
	} else {
	    tsdPtr->modalMenuPtr = NULL;
	}
	break;

    case WM_SYSCOMMAND:
    case WM_COMMAND:
	TkMenuInit();
	if (HIWORD(*pwParam) != 0) {
	    break;
	}
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
		INT2PTR(LOWORD(*pwParam)));
	if (hashEntryPtr == NULL) {
	    break;
	}
	mePtr = (TkMenuEntry *)Tcl_GetHashValue(hashEntryPtr);
	if (mePtr != NULL) {
	    TkMenuReferences *menuRefPtr;
	    TkMenuEntry *parentEntryPtr;
	    Tcl_Interp *interp;
	    int code;

	    /*
	     * We have to set the parent of this menu to be active if this is
	     * a submenu so that tearoffs will get the correct title.
	     */

	    menuPtr = mePtr->menuPtr;
	    menuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    Tk_PathName(menuPtr->tkwin));
	    if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) {
		for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ;
			parentEntryPtr = parentEntryPtr->nextCascadePtr) {
		    const char *name = Tcl_GetString(parentEntryPtr->namePtr);

		    if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
			break;
		    }
		}
		if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index]
			->state != ENTRY_DISABLED) {
		    TkActivateMenuEntry(parentEntryPtr->menuPtr,
			    parentEntryPtr->index);
		}
	    }

	    interp = menuPtr->interp;
	    Tcl_Preserve(interp);
	    code = TkInvokeMenu(interp, menuPtr, mePtr->index);
	    if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundException(interp, code);
	    }
	    Tcl_Release(interp);
	    *plResult = 0;
	    returnResult = 1;
	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*plParam);
	if (hashEntryPtr != NULL) {
	    TkSizeT i, len;
	    int underline;
	    Tcl_Obj *labelPtr;
	    WCHAR *wlabel;
	    int menuChar;
	    Tcl_DString ds;

	    *plResult = 0;
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
	    /*
	     * Assume we have something directly convertable to Tcl_UniChar.
	     * True at least for wide systems.
	     */
	    menuChar = Tcl_UniCharToUpper(LOWORD(*pwParam));

	    Tcl_DStringInit(&ds);
	    for (i = 0; i < menuPtr->numEntries; i++) {
		underline = menuPtr->entries[i]->underline;
		labelPtr = menuPtr->entries[i]->labelPtr;
		if ((underline >= 0) && (labelPtr != NULL)) {
		    /*
		     * Ensure we don't exceed the label length, then check
		     */
		    const char *src = TkGetStringFromObj(labelPtr, &len);

		    Tcl_DStringFree(&ds);
		    Tcl_DStringInit(&ds);
		    wlabel = Tcl_UtfToWCharDString(src, len, &ds);
		    if (((TkSizeT)underline + 1 < len + 1) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }
	    Tcl_DStringFree(&ds);
	}
	break;
    }

    case WM_MEASUREITEM: {
	LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam;








<




|

|











|


|

>
>
|
>
>


|


>
|




|

|
















|



|

















|













|



|

|







|

<
|

<
|
<


|




|

<







|
<
<
<
<
|







<







1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

1151
1152

1153

1154
1155
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1170




1171
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
{
    Tcl_HashEntry *hashEntryPtr;
    int returnResult = 0;
    TkMenu *menuPtr;
    TkMenuEntry *mePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    switch (*pMessage) {
    case WM_UNINITMENUPOPUP:
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		(char *) *pwParam);
	if (hashEntryPtr != NULL) {
	    menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
	    if ((menuPtr->menuRefPtr != NULL)
		    && (menuPtr->menuRefPtr->parentEntryPtr != NULL)) {
		TkPostSubmenu(menuPtr->interp,
			menuPtr->menuRefPtr->parentEntryPtr->menuPtr, NULL);
	    }
	}
	break;

    case WM_INITMENU:
	TkMenuInit();
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		(char *) *pwParam);
	if (hashEntryPtr != NULL) {
	    tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	    menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
	    tsdPtr->modalMenuPtr = menuPtr;
	    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
		Tcl_CancelIdleCall(ReconfigureWindowsMenu,
			(ClientData) menuPtr);
		ReconfigureWindowsMenu((ClientData) menuPtr);
	    }
	    RecursivelyClearActiveMenu(menuPtr);
	    if (!tsdPtr->inPostMenu) {
		Tcl_Interp *interp;
		int code;

		interp = menuPtr->interp;
		Tcl_Preserve((ClientData)interp);
		code = TkPreprocessMenu(menuPtr);
		if ((code != TCL_OK) && (code != TCL_CONTINUE)
			&& (code != TCL_BREAK)) {
		    Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
		    Tcl_BackgroundError(interp);
		}
		Tcl_Release((ClientData)interp);
	    }
	    TkActivateMenuEntry(menuPtr, -1);
	    *plResult = 0;
	    returnResult = 1;
	} else {
	    tsdPtr->modalMenuPtr = NULL;
	}
	break;

    case WM_SYSCOMMAND:
    case WM_COMMAND:
	TkMenuInit();
	if (HIWORD(*pwParam) != 0) {
	    break;
	}
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
		((char *) NULL) + LOWORD(*pwParam));
	if (hashEntryPtr == NULL) {
	    break;
	}
	mePtr = (TkMenuEntry *) Tcl_GetHashValue(hashEntryPtr);
	if (mePtr != NULL) {
	    TkMenuReferences *menuRefPtr;
	    TkMenuEntry *parentEntryPtr;
	    Tcl_Interp *interp;
	    int code;

	    /*
	     * We have to set the parent of this menu to be active if this is
	     * a submenu so that tearoffs will get the correct title.
	     */

	    menuPtr = mePtr->menuPtr;
	    menuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    Tk_PathName(menuPtr->tkwin));
	    if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) {
		for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ;
			parentEntryPtr = parentEntryPtr->nextCascadePtr) {
		    char *name = Tcl_GetString(parentEntryPtr->namePtr);

		    if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
			break;
		    }
		}
		if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index]
			->state != ENTRY_DISABLED) {
		    TkActivateMenuEntry(parentEntryPtr->menuPtr,
			    parentEntryPtr->index);
		}
	    }

	    interp = menuPtr->interp;
	    Tcl_Preserve((ClientData)interp);
	    code = TkInvokeMenu(interp, menuPtr, mePtr->index);
	    if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundError(interp);
	    }
	    Tcl_Release((ClientData)interp);
	    *plResult = 0;
	    returnResult = 1;
	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		(char *) *plParam);
	if (hashEntryPtr != NULL) {

	    int i, len, underline;
	    Tcl_Obj *labelPtr;

	    Tcl_UniChar *wlabel, menuChar;


	    *plResult = 0;
	    menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
	    /*
	     * Assume we have something directly convertable to Tcl_UniChar.
	     * True at least for wide systems.
	     */
	    menuChar = Tcl_UniCharToUpper((Tcl_UniChar) LOWORD(*pwParam));


	    for (i = 0; i < menuPtr->numEntries; i++) {
		underline = menuPtr->entries[i]->underline;
		labelPtr = menuPtr->entries[i]->labelPtr;
		if ((underline >= 0) && (labelPtr != NULL)) {
		    /*
		     * Ensure we don't exceed the label length, then check
		     */
		    wlabel = Tcl_GetUnicodeFromObj(labelPtr, &len);




		    if ((underline < len) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }

	}
	break;
    }

    case WM_MEASUREITEM: {
	LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam;

1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
	    Tk_Font tkfont;

	    if (itemPtr->itemState & ODS_NOACCEL && !showMenuAccelerators) {
		drawingParameters |= DRAW_MENU_ENTRY_NOUNDERLINE;
	    }
	    mePtr = (TkMenuEntry *) itemPtr->itemData;
	    menuPtr = mePtr->menuPtr;
	    twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));
	    twdPtr->type = TWD_WINDC;
	    twdPtr->winDC.hdc = itemPtr->hDC;

	    if (mePtr->state != ENTRY_DISABLED) {
		if (itemPtr->itemState & ODS_SELECTED) {
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		} else {







|







1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
	    Tk_Font tkfont;

	    if (itemPtr->itemState & ODS_NOACCEL && !showMenuAccelerators) {
		drawingParameters |= DRAW_MENU_ENTRY_NOUNDERLINE;
	    }
	    mePtr = (TkMenuEntry *) itemPtr->itemData;
	    menuPtr = mePtr->menuPtr;
	    twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
	    twdPtr->type = TWD_WINDC;
	    twdPtr->winDC.hdc = itemPtr->hDC;

	    if (mePtr->state != ENTRY_DISABLED) {
		if (itemPtr->itemState & ODS_SELECTED) {
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		} else {
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
	    Tk_GetFontMetrics(tkfont, &fontMetrics);
	    TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, &fontMetrics,
		    itemPtr->rcItem.left, itemPtr->rcItem.top,
		    itemPtr->rcItem.right - itemPtr->rcItem.left,
		    itemPtr->rcItem.bottom - itemPtr->rcItem.top,
		    0, drawingParameters);

	    ckfree(twdPtr);
	}
	*plResult = 1;
	returnResult = 1;
	break;
    }

    case WM_MENUSELECT: {
	UINT flags = HIWORD(*pwParam);

	TkMenuInit();

	if ((flags == 0xFFFF) && (*plParam == 0)) {
	    if (tsdPtr->modalMenuPtr != NULL) {
		Tcl_SetServiceMode(tsdPtr->oldServiceMode);
		RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr);
	    }
	} else {
	    menuPtr = NULL;
	    if (*plParam != 0) {
		hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
			*plParam);
		if (hashEntryPtr != NULL) {
		    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
		}
	    }

	    if (menuPtr != NULL) {
		long entryIndex = LOWORD(*pwParam);

                if ((menuPtr->menuType == MENUBAR) && menuPtr->tearoff) {
                    /*
                     * Windows passes the entry index starting at 0 for
                     * the first menu entry. However this entry #0 is the
                     * tearoff entry for Tk (the menu has -tearoff 1),
                     * which is ignored for MENUBAR menues on Windows.
                     */

                    entryIndex++;
                }
                mePtr = NULL;
		if (flags != 0xFFFF) {
		    if ((flags&MF_POPUP) && (entryIndex < (int)menuPtr->numEntries)) {
			mePtr = menuPtr->entries[entryIndex];
		    } else {
			hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
				INT2PTR(entryIndex));
			if (hashEntryPtr != NULL) {
			    mePtr = (TkMenuEntry *)Tcl_GetHashValue(hashEntryPtr);

			}
		    }
		}

		if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
		    TkActivateMenuEntry(menuPtr, -1);
		} else {
		    if (mePtr->index >= (int)menuPtr->numEntries) {
			Tcl_Panic("Trying to activate an entry which doesn't exist");
		    }
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		}
		MenuSelectEvent(menuPtr);
		Tcl_ServiceAll();
		*plResult = 0;
		returnResult = 1;







|




















|

|






<
<
<
<
<
<
<
<
<
<
|

|



|

|
>







|
|







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294










1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
	    Tk_GetFontMetrics(tkfont, &fontMetrics);
	    TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, &fontMetrics,
		    itemPtr->rcItem.left, itemPtr->rcItem.top,
		    itemPtr->rcItem.right - itemPtr->rcItem.left,
		    itemPtr->rcItem.bottom - itemPtr->rcItem.top,
		    0, drawingParameters);

	    ckfree((char *) twdPtr);
	}
	*plResult = 1;
	returnResult = 1;
	break;
    }

    case WM_MENUSELECT: {
	UINT flags = HIWORD(*pwParam);

	TkMenuInit();

	if ((flags == 0xFFFF) && (*plParam == 0)) {
	    if (tsdPtr->modalMenuPtr != NULL) {
		Tcl_SetServiceMode(tsdPtr->oldServiceMode);
		RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr);
	    }
	} else {
	    menuPtr = NULL;
	    if (*plParam != 0) {
		hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
			(char *) *plParam);
		if (hashEntryPtr != NULL) {
		    menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
		}
	    }

	    if (menuPtr != NULL) {
		long entryIndex = LOWORD(*pwParam);











		mePtr = NULL;
		if (flags != 0xFFFF) {
		    if ((flags&MF_POPUP) && (entryIndex<menuPtr->numEntries)) {
			mePtr = menuPtr->entries[entryIndex];
		    } else {
			hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
				((char *) NULL) + entryIndex);
			if (hashEntryPtr != NULL) {
			    mePtr = (TkMenuEntry *)
				    Tcl_GetHashValue(hashEntryPtr);
			}
		    }
		}

		if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
		    TkActivateMenuEntry(menuPtr, -1);
		} else {
		    if (mePtr->index >= menuPtr->numEntries) {
			Tcl_Panic("Trying to activate an entry which doesn't exist.");
		    }
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		}
		MenuSelectEvent(menuPtr);
		Tcl_ServiceAll();
		*plResult = 0;
		returnResult = 1;
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    TkSizeT i;
    TkMenuEntry *mePtr;

    TkActivateMenuEntry(menuPtr, -1);
    MenuSelectEvent(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	mePtr = menuPtr->entries[i];
	if (mePtr->state == ENTRY_ACTIVE) {







|







1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    int i;
    TkMenuEntry *mePtr;

    TkActivateMenuEntry(menuPtr, -1);
    MenuSelectEvent(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	mePtr = menuPtr->entries[i];
	if (mePtr->state == ENTRY_ACTIVE) {
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532


1533

1534
1535
1536
1537
1538
1539
1540

    if (menuPtr != NULL) {
	Tcl_HashEntry *hashEntryPtr;
	int newEntry;

	winMenuHdl = (HMENU) menuPtr->platformData;
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		winMenuHdl);
	Tcl_DeleteHashEntry(hashEntryPtr);
	DestroyMenu(winMenuHdl);
	winMenuHdl = CreateMenu();
	hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
		(char *) winMenuHdl, &newEntry);
	Tcl_SetHashValue(hashEntryPtr, menuPtr);
	menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
	TkWinSetMenu(tkwin, winMenuHdl);


	ScheduleMenuReconfigure(menuPtr);

    } else {
	TkWinSetMenu(tkwin, NULL);
    }
}

/*
 *----------------------------------------------------------------------







|





|


>
>
|
>







1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421

    if (menuPtr != NULL) {
	Tcl_HashEntry *hashEntryPtr;
	int newEntry;

	winMenuHdl = (HMENU) menuPtr->platformData;
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		(char *) winMenuHdl);
	Tcl_DeleteHashEntry(hashEntryPtr);
	DestroyMenu(winMenuHdl);
	winMenuHdl = CreateMenu();
	hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
		(char *) winMenuHdl, &newEntry);
	Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr);
	menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
	TkWinSetMenu(tkwin, winMenuHdl);
	if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
	    menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
	    Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
	}
    } else {
	TkWinSetMenu(tkwin, NULL);
    }
}

/*
 *----------------------------------------------------------------------
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. If
    				 * NULL, use the default menu bar. */
{
    (void)interp;
    (void)tkwin;
    (void)menuName;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------







|


<
<
<
<







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443




1444
1445
1446
1447
1448
1449
1450
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    char *menuName)		/* The name of the menu to put in front. If
    				 * NULL, use the default menu bar. */
{




    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* Precalculated font */
    const Tk_FontMetrics *fmPtr,/* Precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)menuPtr;
    (void)tkfont;
    (void)fmPtr;

    *heightPtr = indicatorDimensions[0];
    if (mePtr->hideMargin) {
	*widthPtr = 0;
    } else {
	int borderWidth;

	Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
		menuPtr->borderWidthPtr, &borderWidth);
	*widthPtr = indicatorDimensions[1] - borderWidth;

        /*
         * Quite dubious about the above (why would borderWidth play a role?)
         * and about how indicatorDimensions[1] is obtained in SetDefaults().
         * At least don't let the result be negative!
         */
        if (*widthPtr < 0) {
            *widthPtr = 0;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetMenuAccelGeometry --







<
<
<
<









<
<
<
<
<
<
<
<
<







1467
1468
1469
1470
1471
1472
1473




1474
1475
1476
1477
1478
1479
1480
1481
1482









1483
1484
1485
1486
1487
1488
1489
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* Precalculated font */
    const Tk_FontMetrics *fmPtr,/* Precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{




    *heightPtr = indicatorDimensions[0];
    if (mePtr->hideMargin) {
	*widthPtr = 0;
    } else {
	int borderWidth;

	Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
		menuPtr->borderWidthPtr, &borderWidth);
	*widthPtr = indicatorDimensions[1] - borderWidth;









    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetMenuAccelGeometry --
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
        /*
         * Cascade entries have no accelerator but do show an arrow. Set
         * this field width to the width of the OBM_MNARROW system bitmap
         * used to display the arrow. I couldn't find how to query the
         * system for this value, therefore I resort to hardcoding.
         */
	*widthPtr = CASCADE_ARROW_WIDTH;
    } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);

	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
    } else {
    	*widthPtr = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetTearoffEntryGeometry --







|
|
<
<
<
<
|
|
|


<
<







1506
1507
1508
1509
1510
1511
1512
1513
1514




1515
1516
1517
1518
1519


1520
1521
1522
1523
1524
1525
1526
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
	*widthPtr = 0;
    } else if (mePtr->accelPtr == NULL) {




	*widthPtr = 0;
    } else {
	char *accel = Tcl_GetString(mePtr->accelPtr);

	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);


    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetTearoffEntryGeometry --
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)mePtr;
    (void)tkfont;

    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
    }
    *widthPtr = 0;
}








<
<
<
|







1541
1542
1543
1544
1545
1546
1547



1548
1549
1550
1551
1552
1553
1554
1555
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{



    if (menuPtr->menuType != MASTER_MENU) {
	*heightPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
    }
    *widthPtr = 0;
}

1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)menuPtr;
    (void)mePtr;
    (void)tkfont;

    *widthPtr = 0;
    *heightPtr = fmPtr->linespace - (2 * fmPtr->descent);
}

/*
 *----------------------------------------------------------------------
 *







<
<
<
<







1574
1575
1576
1577
1578
1579
1580




1581
1582
1583
1584
1585
1586
1587
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{




    *widthPtr = 0;
    *heightPtr = fmPtr->linespace - (2 * fmPtr->descent);
}

/*
 *----------------------------------------------------------------------
 *
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
    POINT ptOrg;
    int topOffset, leftOffset;

    SetBkColor(hdc, gc->background);
    SetTextColor(hdc, gc->foreground);

    scratchDC = CreateCompatibleDC(hdc);
    bitmap = LoadBitmapW(NULL, (LPCWSTR)MAKEINTRESOURCE(bitmapID));

    SelectObject(scratchDC, bitmap);
    SetMapMode(scratchDC, GetMapMode(hdc));
    GetObjectA(bitmap, sizeof(BITMAP), &bm);
    ptSize.x = bm.bmWidth;
    ptSize.y = bm.bmHeight;
    DPtoLP(scratchDC, &ptSize, 1);

    ptOrg.y = ptOrg.x = 0;
    DPtoLP(scratchDC, &ptOrg, 1);








|



|







1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
    POINT ptOrg;
    int topOffset, leftOffset;

    SetBkColor(hdc, gc->background);
    SetTextColor(hdc, gc->foreground);

    scratchDC = CreateCompatibleDC(hdc);
    bitmap = LoadBitmap(NULL, MAKEINTRESOURCE(bitmapID));

    SelectObject(scratchDC, bitmap);
    SetMapMode(scratchDC, GetMapMode(hdc));
    GetObject(bitmap, sizeof(BITMAP), &bm);
    ptSize.x = bm.bmWidth;
    ptSize.y = bm.bmHeight;
    DPtoLP(scratchDC, &ptSize, 1);

    ptOrg.y = ptOrg.x = 0;
    DPtoLP(scratchDC, &ptOrg, 1);

1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left edge */
    int y,			/* Top edge */
    int width,
    int height)
{
    (void)tkfont;
    (void)fmPtr;
    (void)width;
    (void)height;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
    	if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
	    RECT rect;
	    GC whichGC;
	    int borderWidth, activeBorderWidth;








<
<
<
<
<







1687
1688
1689
1690
1691
1692
1693





1694
1695
1696
1697
1698
1699
1700
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left edge */
    int y,			/* Top edge */
    int width,
    int height)
{





    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
    	if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
	    RECT rect;
	    GC whichGC;
	    int borderWidth, activeBorderWidth;

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    int baseline;
    int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth;
    const char *accel;
    (void)activeBorder;
    (void)width;
    (void)height;

    if (menuPtr->menuType == MENUBAR) {
        return;
    }

    if (mePtr->accelPtr != NULL) {
	accel = Tcl_GetString(mePtr->accelPtr);
    } else {
	accel = NULL;
    }

    baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;

    /*
     * Draw disabled 3D text highlight only with the Win95/98 look.
     */

    if (TkWinGetPlatformTheme() != TK_THEME_WIN_XP) {
	if ((mePtr->state == ENTRY_DISABLED)
		&& (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) {
	    COLORREF oldFgColor = gc->foreground;

	    gc->foreground = GetSysColor(COLOR_3DHILIGHT);
	    if (!(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) {
		Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
			mePtr->accelLength, leftEdge + 1, baseline + 1);
	    }
	    gc->foreground = oldFgColor;
	}
    }

    if (accel != NULL) {
	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
		mePtr->accelLength, leftEdge, baseline);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuEntryArrow --
 *
 *	This function draws the arrow bitmap on the right side of a menu
 *	entry. This function is only used when drawing the arrow for:
 *	 - a disabled cascade item
 *	 - a cascade item in any state in a torn-off menu
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *







|
<
<
<
<
<
<
<













|





|



















|
|
<







1766
1767
1768
1769
1770
1771
1772
1773







1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814

1815
1816
1817
1818
1819
1820
1821
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    int baseline;
    int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth;
    char *accel;








    if (mePtr->accelPtr != NULL) {
	accel = Tcl_GetString(mePtr->accelPtr);
    } else {
	accel = NULL;
    }

    baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;

    /*
     * Draw disabled 3D text highlight only with the Win95/98 look.
     */

    if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) {
	if ((mePtr->state == ENTRY_DISABLED)
		&& (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) {
	    COLORREF oldFgColor = gc->foreground;

	    gc->foreground = GetSysColor(COLOR_3DHILIGHT);
	    if ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0) {
		Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
			mePtr->accelLength, leftEdge + 1, baseline + 1);
	    }
	    gc->foreground = oldFgColor;
	}
    }

    if (accel != NULL) {
	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
		mePtr->accelLength, leftEdge, baseline);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuEntryArrow --
 *
 *	This function draws the arrow bitmap on the right side of a menu
 *	entry. This function is only used when drawing the arrow for a
 *	disabled cascade menu.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
    GC gc,			/* The gc we are drawing with */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height,			/* Height of menu entry */
    int drawArrow)		/* For cascade menus, whether of not to draw
				 * the arrow. I cannot figure out Windows'
				 * algorithm for where to draw this. */
{
    COLORREF oldFgColor;
    COLORREF oldBgColor;
    RECT rect;
    (void)gc;
    (void)activeBorder;

    if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) {
	return;
    }

    /*
     * Don't draw the arrow if a submenu is not attached to this
     * cascade entry.
     */

    if ((mePtr->childMenuRefPtr == NULL)
           || (mePtr->childMenuRefPtr->menuPtr == NULL)) {
        return;
    }

    oldFgColor = gc->foreground;
    oldBgColor = gc->background;

    /*
     * Set bitmap bg to highlight color if the menu is highlighted.
     */

    if (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) {
	XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj(
		mePtr->menuPtr->tkwin, (mePtr->activeBorderPtr == NULL)
		? mePtr->menuPtr->activeBorderPtr
		: mePtr->activeBorderPtr));

	gc->background = activeBgColor->pixel;
    }

    gc->foreground = GetSysColor((mePtr->state == ENTRY_DISABLED)
	? COLOR_GRAYTEXT
		: ((mePtr->state == ENTRY_ACTIVE)
		? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));







|





<
<





<
<
<
<
<
<
<
<
<
<












<







1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842


1843
1844
1845
1846
1847










1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859

1860
1861
1862
1863
1864
1865
1866
    GC gc,			/* The gc we are drawing with */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height,			/* Height of menu entry */
    int drawArrow)		/* For cascade menus, whether of not to draw
				 * the arraw. I cannot figure out Windows'
				 * algorithm for where to draw this. */
{
    COLORREF oldFgColor;
    COLORREF oldBgColor;
    RECT rect;



    if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) {
	return;
    }











    oldFgColor = gc->foreground;
    oldBgColor = gc->background;

    /*
     * Set bitmap bg to highlight color if the menu is highlighted.
     */

    if (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) {
	XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj(
		mePtr->menuPtr->tkwin, (mePtr->activeBorderPtr == NULL)
		? mePtr->menuPtr->activeBorderPtr
		: mePtr->activeBorderPtr));

	gc->background = activeBgColor->pixel;
    }

    gc->foreground = GetSysColor((mePtr->state == ENTRY_DISABLED)
	? COLOR_GRAYTEXT
		: ((mePtr->state == ENTRY_ACTIVE)
		? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of item */
    int height)			/* height of item */
{
    XPoint points[2];
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    points[0].x = x;
    points[0].y = y + height / 2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,







<
<
<
<







1905
1906
1907
1908
1909
1910
1911




1912
1913
1914
1915
1916
1917
1918
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of item */
    int height)			/* height of item */
{
    XPoint points[2];
    Tk_3DBorder border;





    points[0].x = x;
    points[0].y = y + height / 2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135

2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left Edge */
    int y,			/* Top Edge */
    int width,			/* Width of entry */
    int height)			/* Height of entry */
{
    (void)fmPtr;
    (void)width;

    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;


	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    const char *label, *start, *end;
	    int ch;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = start + TkUtfToUniChar(start, &ch);
	    Tk_UnderlineChars(menuPtr->display, d,
		    gc, tkfont, label, x + mePtr->indicatorSpace,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    (int) (start - label), (int) (end - label));
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkWinMenuKeyObjCmd --
 *
 *	This function is invoked when keys related to pulling down menus is
 *	pressed. The corresponding Windows events are generated and passed to
 *	DefWindowProcW if appropriate. This cmd is registered as tk::WinMenuKey
 *	in the interp.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	The menu system may take over and process user events for menu input.
 *
 *--------------------------------------------------------------
 */

static int
TkWinMenuKeyObjCmd(
    ClientData dummy,	/* Unused. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    UINT scanCode;
    UINT virtualKey;
    XEvent *eventPtr;
    Tk_Window tkwin;
    TkWindow *winPtr;
    KeySym keySym;
    int i;
    (void)dummy;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "window keySym");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]),







<
<
<



>
|


<

|

|















|













|











<







1944
1945
1946
1947
1948
1949
1950



1951
1952
1953
1954
1955
1956
1957

1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left Edge */
    int y,			/* Top Edge */
    int width,			/* Width of entry */
    int height)			/* Height of entry */
{



    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	/* do the unicode call just to prevent overruns */
	Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len);
	if (mePtr->underline < len) {
	    const char *label, *start, *end;


	    label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = Tcl_UtfNext(start);
	    Tk_UnderlineChars(menuPtr->display, d,
		    gc, tkfont, label, x + mePtr->indicatorSpace,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    (int) (start - label), (int) (end - label));
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkWinMenuKeyObjCmd --
 *
 *	This function is invoked when keys related to pulling down menus is
 *	pressed. The corresponding Windows events are generated and passed to
 *	DefWindowProc if appropriate. This cmd is registered as tk::WinMenuKey
 *	in the interp.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	The menu system may take over and process user events for menu input.
 *
 *--------------------------------------------------------------
 */

static int
TkWinMenuKeyObjCmd(
    ClientData clientData,	/* Unused. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    UINT scanCode;
    UINT virtualKey;
    XEvent *eventPtr;
    Tk_Window tkwin;
    TkWindow *winPtr;
    KeySym keySym;
    int i;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "window keySym");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239

2240
2241
2242
2243
2244

2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
	return TCL_ERROR;
    }
    keySym = i;

    if (eventPtr->type == KeyPress) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKeyW(VK_LMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKeyW(VK_RMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29) | (1 << 24));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKeyW(VK_F10, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKeyW(virtualKey, 0);
	    if (0 != scanCode) {
		TkKeyEvent xkey;
		memcpy(&xkey, eventPtr, sizeof(xkey));
		CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYDOWN, virtualKey,
			(int) ((scanCode << 16) | (1 << 29)));

		for (i = 0; i < xkey.nbytes; i++) {
		    CallWindowProcW(DefWindowProcW,
			    Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
			    xkey.trans_chars[i],
			    (int) ((scanCode << 16) | (1 << 29)));

		}
	    }
	}
    } else if (eventPtr->type == KeyRelease) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKeyW(VK_LMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKeyW(VK_RMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKeyW(VK_F10, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_F10,
		    (int) (scanCode << 16) | (1 << 30) | (1 << 31));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKeyW(virtualKey, 0);
	    if (0 != scanCode) {
		CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16)
			| (1 << 29) | (1 << 30) | (1 << 31)));
	    }
	}
    }
    return TCL_OK;
}







|
|




|
|




|
|




|

|
<
|


>
|
|
|
|
|
>






|
|




|
|




|
|





|

|







2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052

2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
	return TCL_ERROR;
    }
    keySym = i;

    if (eventPtr->type == KeyPress) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKey(VK_LMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKey(VK_RMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29) | (1 << 24));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKey(VK_F10, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKey(virtualKey, 0);
	    if (0 != scanCode) {
		XKeyEvent xkey = eventPtr->xkey;

		CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYDOWN, virtualKey,
			(int) ((scanCode << 16) | (1 << 29)));
		if (xkey.nbytes > 0) {
		    for (i = 0; i < xkey.nbytes; i++) {
			CallWindowProc(DefWindowProc,
				Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
				xkey.trans_chars[i],
				(int) ((scanCode << 16) | (1 << 29)));
		    }
		}
	    }
	}
    } else if (eventPtr->type == KeyRelease) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKey(VK_LMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKey(VK_RMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKey(VK_F10, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_F10,
		    (int) (scanCode << 16) | (1 << 30) | (1 << 31));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKey(virtualKey, 0);
	    if (0 != scanCode) {
		CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16)
			| (1 << 29) | (1 << 30) | (1 << 31)));
	    }
	}
    }
    return TCL_OK;
}
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-Key>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Key-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------







|





|







2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyPress>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyPress-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight);
	haveImage = 1;
    }
    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
	if (mePtr->labelLength > 0) {
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
	    textHeight = fmPtr->linespace;
	    haveText = 1;
	}
    }








|







2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

	Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight);
	haveImage = 1;
    }
    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
	if (mePtr->labelLength > 0) {
	    char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
	    textHeight = fmPtr->linespace;
	    haveText = 1;
	}
    }

2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
		(unsigned) imageWidth, (unsigned) imageHeight,
		leftEdge + imageXOffset,
		(int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1);
    }
    if ((mePtr->compound != COMPOUND_NONE) || !haveImage) {
    	if (mePtr->labelLength > 0) {
	    int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    if (TkWinGetPlatformTheme() != TK_THEME_WIN_XP) {
		/*
		 * Win 95/98 systems draw disabled menu text with a 3D
		 * highlight, unless the menu item is highlighted,
		 */

		if ((mePtr->state == ENTRY_DISABLED) &&
			!(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) {
		    COLORREF oldFgColor = gc->foreground;

		    gc->foreground = GetSysColor(COLOR_3DHILIGHT);
		    Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
			    mePtr->labelLength, leftEdge + textXOffset + 1,
			    baseline + textYOffset + 1);
		    gc->foreground = oldFgColor;
		}
	    }







|

|






|

<







2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326

2327
2328
2329
2330
2331
2332
2333
		(unsigned) imageWidth, (unsigned) imageHeight,
		leftEdge + imageXOffset,
		(int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1);
    }
    if ((mePtr->compound != COMPOUND_NONE) || !haveImage) {
    	if (mePtr->labelLength > 0) {
	    int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
	    char *label = Tcl_GetString(mePtr->labelPtr);

	    if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) {
		/*
		 * Win 95/98 systems draw disabled menu text with a 3D
		 * highlight, unless the menu item is highlighted,
		 */

		if ((mePtr->state == ENTRY_DISABLED) &&
			((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) {
		    COLORREF oldFgColor = gc->foreground;

		    gc->foreground = GetSysColor(COLOR_3DHILIGHT);
		    Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
			    mePtr->labelLength, leftEdge + textXOffset + 1,
			    baseline + textYOffset + 1);
		    gc->foreground = oldFgColor;
		}
	    }
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
    }

    if (mePtr->state == ENTRY_DISABLED) {
	if (menuPtr->disabledFgPtr == NULL) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
		    (unsigned) width, (unsigned) height);
	} else if ((mePtr->image != NULL)
		&& menuPtr->disabledImageGC) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
		    leftEdge + imageXOffset,
		    (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
    }
}







|







2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
    }

    if (mePtr->state == ENTRY_DISABLED) {
	if (menuPtr->disabledFgPtr == NULL) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
		    (unsigned) width, (unsigned) height);
	} else if ((mePtr->image != NULL)
		&& (menuPtr->disabledImageGC)) {
	    XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
		    leftEdge + imageXOffset,
		    (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
    }
}
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
    const Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = x + width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}







<
<
<
<

|







|







2406
2407
2408
2409
2410
2411
2412




2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
    const Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;





    if (menuPtr->menuType != MASTER_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645

2646




2647
2648
2649
2650
2651
2652
2653
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

int
TkpConfigureMenuEntry(
    TkMenuEntry *mePtr)/* Information about menu entry; may or may
				 * not already have values for some fields. */
{

    ScheduleMenuReconfigure(mePtr->menuPtr);




    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawMenuEntry --







|


>
|
>
>
>
>







2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

int
TkpConfigureMenuEntry(
    register TkMenuEntry *mePtr)/* Information about menu entry; may or may
				 * not already have values for some fields. */
{
    TkMenu *menuPtr = mePtr->menuPtr;

    if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
	menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
	Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawMenuEntry --
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawingParameters)	/* Whether or not to draw the cascade arrow
				 * for cascade items and accelerator
				 * cues. */
{
    GC gc, indicatorGC;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
    int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;







|







2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawingParameters)	/* Whether or not to draw the cascade arrow
				 * for cascade items and accelerator
				 * cues. Only applies to Windows. */
{
    GC gc, indicatorGC;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
    int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
     * animated menus.  [Bug 1329198]
     */

    if (mePtr->image != NULL) {
	menuDc = TkWinGetDrawableDC(menuPtr->display, menuDrawable, &dcState);

	memDc = CreateCompatibleDC(menuDc);
	oldBitmap = (HBITMAP)SelectObject(memDc,
    			CreateCompatibleBitmap(menuDc, width, height) );

	memWinDraw.type = TWD_WINDC;
	memWinDraw.winDC.hdc = memDc;
	d = (Drawable)&memWinDraw;
	adjustedX = 0;
	adjustedY = padY;







|







2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
     * animated menus.  [Bug 1329198]
     */

    if (mePtr->image != NULL) {
	menuDc = TkWinGetDrawableDC(menuPtr->display, menuDrawable, &dcState);

	memDc = CreateCompatibleDC(menuDc);
	oldBitmap = SelectObject(memDc,
    			CreateCompatibleBitmap(menuDc, width, height) );

	memWinDraw.type = TWD_WINDC;
	memWinDraw.winDC.hdc = memDc;
	d = (Drawable)&memWinDraw;
	adjustedX = 0;
	adjustedY = padY;
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
	gc = mePtr->activeGC;
	if (gc == NULL) {
	    gc = menuPtr->activeGC;
	}
    } else {
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;
    	const char *name;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	    name = Tcl_GetString(cascadeEntryPtr->namePtr);
    	    if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
    	    	if (mePtr->state == ENTRY_DISABLED) {







|







2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
	gc = mePtr->activeGC;
	if (gc == NULL) {
	    gc = menuPtr->activeGC;
	}
    } else {
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;
	char *name;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	    name = Tcl_GetString(cascadeEntryPtr->namePtr);
    	    if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
    	    	if (mePtr->state == ENTRY_DISABLED) {
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
    int haveImage = 0;

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

    	Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
	haveImage = 1;
    } else {
	*heightPtr = 0;
	*widthPtr = 0;
    }

    if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
	/*
	 * We don't care about the text in this case.
	 */
    } else {
	/*
	 * Either it is compound or we don't have an image,
	 */

    	if (mePtr->labelPtr != NULL) {
	    int textWidth;
	    const char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);

	    if ((mePtr->compound != COMPOUND_NONE) && haveImage) {
		switch ((enum compound) mePtr->compound) {
		case COMPOUND_TOP:
		case COMPOUND_BOTTOM:







<


















|







2673
2674
2675
2676
2677
2678
2679

2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
    int haveImage = 0;

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
	haveImage = 1;
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);

    	Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
	haveImage = 1;
    } else {
	*heightPtr = 0;
	*widthPtr = 0;
    }

    if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
	/*
	 * We don't care about the text in this case.
	 */
    } else {
	/*
	 * Either it is compound or we don't have an image,
	 */

    	if (mePtr->labelPtr != NULL) {
	    int textWidth;
	    char *label = Tcl_GetString(mePtr->labelPtr);

	    textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);

	    if ((mePtr->compound != COMPOUND_NONE) && haveImage) {
		switch ((enum compound) mePtr->compound) {
		case COMPOUND_TOP:
		case COMPOUND_BOTTOM:
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of rectangle to draw */
    int height)			/* height of rectangle to draw */
{
    if (mePtr->state == ENTRY_ACTIVE
		|| (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)!=0 ) {
	int relief;
	int activeBorderWidth;

	bgBorder = activeBorder;

	if ((menuPtr->menuType == MENUBAR)
		&& ((menuPtr->postedCascade == NULL)
		|| (menuPtr->postedCascade != mePtr))) {
	    relief = TK_RELIEF_FLAT;
	} else {
	    Tk_GetReliefFromObj(NULL, menuPtr->activeReliefPtr, &relief);
	}
	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height,
		activeBorderWidth, relief);
    } else {
        Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0,
                TK_RELIEF_FLAT);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkpComputeStandardMenuGeometry --
 *







<
<
<

|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<







2781
2782
2783
2784
2785
2786
2787



2788
2789












2790
2791

2792
2793
2794
2795
2796
2797
2798
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of rectangle to draw */
    int height)			/* height of rectangle to draw */
{
    if (mePtr->state == ENTRY_ACTIVE
		|| (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)!=0 ) {



	bgBorder = activeBorder;
    }












    Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0,
	    TK_RELIEF_FLAT);

}

/*
 *--------------------------------------------------------------
 *
 * TkpComputeStandardMenuGeometry --
 *
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);
    Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
	    menuPtr->activeBorderWidthPtr, &activeBorderWidth);

    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	if (menuPtr->entries[i]->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
		    menuPtr->entries[i]->fontPtr);
    	    Tk_GetFontMetrics(tkfont, &entryMetrics);







|







2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);
    Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
	    menuPtr->activeBorderWidthPtr, &activeBorderWidth);

    for (i = 0; i < menuPtr->numEntries; i++) {
	if (menuPtr->entries[i]->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
		    menuPtr->entries[i]->fontPtr);
    	    Tk_GetFontMetrics(tkfont, &entryMetrics);
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084

3085
3086
3087
3088
3089
3090
3091
		menuPtr->entries[j]->labelWidth = labelWidth;
		menuPtr->entries[j]->width = indicatorSpace + labelWidth
			+ accelWidth + 2 * activeBorderWidth;
		menuPtr->entries[j]->x = x;
		menuPtr->entries[j]->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += indicatorSpace + labelWidth + accelWidth
		    + 2 * activeBorderWidth;
	    indicatorSpace = labelWidth = accelWidth = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}

	if (menuPtr->entries[i]->type == SEPARATOR_ENTRY) {
	    GetMenuSeparatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
	    menuPtr->entries[i]->height = height;
	} else if (menuPtr->entries[i]->type == TEAROFF_ENTRY) {
	    GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
	    menuPtr->entries[i]->height = height;

	} else {
	    /*
	     * For each entry, compute the height required by that particular
	     * entry, plus three widths: the width of the label, the width to
	     * allow for an indicator to be displayed to the left of the label
	     * (if any), and the width of the accelerator to be displayed to
	     * the right of the label (if any). These sizes depend, of course,







|













>







2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
		menuPtr->entries[j]->labelWidth = labelWidth;
		menuPtr->entries[j]->width = indicatorSpace + labelWidth
			+ accelWidth + 2 * activeBorderWidth;
		menuPtr->entries[j]->x = x;
		menuPtr->entries[j]->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += indicatorSpace + labelWidth + accelWidth
		    + 2 * borderWidth;
	    indicatorSpace = labelWidth = accelWidth = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}

	if (menuPtr->entries[i]->type == SEPARATOR_ENTRY) {
	    GetMenuSeparatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
	    menuPtr->entries[i]->height = height;
	} else if (menuPtr->entries[i]->type == TEAROFF_ENTRY) {
	    GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
	    menuPtr->entries[i]->height = height;

	} else {
	    /*
	     * For each entry, compute the height required by that particular
	     * entry, plus three widths: the width of the label, the width to
	     * allow for an indicator to be displayed to the left of the label
	     * (if any), and the width of the accelerator to be displayed to
	     * the right of the label (if any). These sizes depend, of course,
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141


3142
3143
3144
3145
3146
3147
3148
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < (int)menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + borderWidth;


    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */








|







|
|
>
>







2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth + accelSpace
	    + 2 * activeBorderWidth + 2 * borderWidth;


    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */

3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
 *----------------------------------------------------------------------
 */

static void
MenuSelectEvent(
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    union {XEvent general; XVirtualEvent virt;} event;
    union {DWORD msgpos; POINTS point;} root;

    memset(&event, 0, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = menuPtr->display->request;
    event.virt.send_event = 0;
    event.virt.display = menuPtr->display;
    Tk_MakeWindowExist(menuPtr->tkwin);
    event.virt.event = Tk_WindowId(menuPtr->tkwin);
    event.virt.root = XRootWindow(menuPtr->display, 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();

    root.msgpos = GetMessagePos();
    event.virt.x_root = root.point.x;
    event.virt.y_root = root.point.y;
    event.virt.state = TkWinGetModifierState();
    event.virt.same_screen = 1;
    event.virt.name = Tk_GetUid("MenuSelect");
    event.virt.user_data = NULL;
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuNotifyToplevelCreate --
 *







|


<
|
|
|
|

|
|
|
|


|
|
|
|
|
|
|







2977
2978
2979
2980
2981
2982
2983
2984
2985
2986

2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
 *----------------------------------------------------------------------
 */

static void
MenuSelectEvent(
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    XVirtualEvent event;
    union {DWORD msgpos; POINTS point;} root;


    event.type = VirtualEvent;
    event.serial = menuPtr->display->request;
    event.send_event = 0;
    event.display = menuPtr->display;
    Tk_MakeWindowExist(menuPtr->tkwin);
    event.event = Tk_WindowId(menuPtr->tkwin);
    event.root = XRootWindow(menuPtr->display, 0);
    event.subwindow = None;
    event.time = TkpGetMS();

    root.msgpos = GetMessagePos();
    event.x_root = root.point.x;
    event.y_root = root.point.y;
    event.state = TkWinGetModifierState();
    event.same_screen = 1;
    event.name = Tk_GetUid("MenuSelect");
    event.user_data = NULL;
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuNotifyToplevelCreate --
 *
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235



3236
3237
3238
3239
3240
3241
3242
3243
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    Tcl_Interp *interp,		/* The interp the menu lives in. */
    const char *menuName)	/* The name of the menu to reconfigure. */
{
    TkMenuReferences *menuRefPtr;
    TkMenu *menuPtr;

    if ((menuName != NULL) && (menuName[0] != '\0')) {
	menuRefPtr = TkFindMenuReferences(interp, menuName);
	if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) {
	    for (menuPtr = menuRefPtr->menuPtr->mainMenuPtr; menuPtr != NULL;
		    menuPtr = menuPtr->nextInstancePtr) {
		if (menuPtr->menuType == MENUBAR) {



		    ScheduleMenuReconfigure(menuPtr);
		}
	    }
	}
    }
}

/*







|







|

|
>
>
>
|







3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    Tcl_Interp *interp,		/* The interp the menu lives in. */
    char *menuName)		/* The name of the menu to reconfigure. */
{
    TkMenuReferences *menuRefPtr;
    TkMenu *menuPtr;

    if ((menuName != NULL) && (menuName[0] != '\0')) {
	menuRefPtr = TkFindMenuReferences(interp, menuName);
	if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) {
	    for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
		    menuPtr = menuPtr->nextInstancePtr) {
		if ((menuPtr->menuType == MENUBAR)
			&& !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
		    menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
		    Tcl_DoWhenIdle(ReconfigureWindowsMenu,
			    (ClientData) menuPtr);
		}
	    }
	}
    }
}

/*
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276

HWND
Tk_GetMenuHWND(
    Tk_Window tkwin)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)tkwin;

    TkMenuInit();
    return tsdPtr->embeddedMenuHWND;
}

/*
 *----------------------------------------------------------------------
 *







<
<







3067
3068
3069
3070
3071
3072
3073


3074
3075
3076
3077
3078
3079
3080

HWND
Tk_GetMenuHWND(
    Tk_Window tkwin)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    TkMenuInit();
    return tsdPtr->embeddedMenuHWND;
}

/*
 *----------------------------------------------------------------------
 *
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuExitHandler(
    ClientData dummy)	    /* Not used */
{
    (void)dummy;

    UnregisterClassW(MENU_CLASS_NAME, Tk_GetHINSTANCE());
    UnregisterClassW(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}

/*
 *----------------------------------------------------------------------
 *
 * MenuExitHandler --
 *







|

<
<
|
|







3089
3090
3091
3092
3093
3094
3095
3096
3097


3098
3099
3100
3101
3102
3103
3104
3105
3106
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuExitHandler(
    ClientData clientData)	    /* Not used */
{


    UnregisterClass(MENU_CLASS_NAME, Tk_GetHINSTANCE());
    UnregisterClass(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}

/*
 *----------------------------------------------------------------------
 *
 * MenuExitHandler --
 *
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuThreadExitHandler(
    ClientData dummy)	    /* Not used */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    DestroyWindow(tsdPtr->menuHWND);
    DestroyWindow(tsdPtr->embeddedMenuHWND);
    tsdPtr->menuHWND = NULL;
    tsdPtr->embeddedMenuHWND = NULL;

    Tcl_DeleteHashTable(&tsdPtr->winMenuTable);







|



<







3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuThreadExitHandler(
    ClientData clientData)	    /* Not used */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    DestroyWindow(tsdPtr->menuHWND);
    DestroyWindow(tsdPtr->embeddedMenuHWND);
    tsdPtr->menuHWND = NULL;
    tsdPtr->embeddedMenuHWND = NULL;

    Tcl_DeleteHashTable(&tsdPtr->winMenuTable);
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
Tcl_Obj *
TkWinGetMenuSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valuePtr = NULL;
    (void)tkwin;
    (void)className;

    if ((strcmp(dbName, "activeBorderWidth") == 0) ||
	    (strcmp(dbName, "borderWidth") == 0)) {
	valuePtr = Tcl_NewWideIntObj(defaultBorderWidth);
    } else if (strcmp(dbName, "font") == 0) {
	valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1);
    }

    return valuePtr;
}








<
<



|







3154
3155
3156
3157
3158
3159
3160


3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
Tcl_Obj *
TkWinGetMenuSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valuePtr = NULL;



    if ((strcmp(dbName, "activeBorderWidth") == 0) ||
	    (strcmp(dbName, "borderWidth") == 0)) {
	valuePtr = Tcl_NewIntObj(defaultBorderWidth);
    } else if (strcmp(dbName, "font") == 0) {
	valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1);
    }

    return valuePtr;
}

3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403

3404





3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423


3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
				 * called? */
{
    char sizeString[TCL_INTEGER_SPACE];
    char faceName[LF_FACESIZE];
    HDC scratchDC;
    int bold = 0;
    int italic = 0;
    TEXTMETRICW tm;
    int pointSize;
    HFONT menuFont;
    /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */

    NONCLIENTMETRICSW metrics;






    /*
     * Set all of the default options. The loop will terminate when we run out
     * of options via a break statement.
     */

    defaultBorderWidth = GetSystemMetrics(SM_CXBORDER);
    if (GetSystemMetrics(SM_CYBORDER) > defaultBorderWidth) {
	defaultBorderWidth = GetSystemMetrics(SM_CYBORDER);
    }

    scratchDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
    if (!firstTime) {
	Tcl_DStringFree(&menuFontDString);
    }
    Tcl_DStringInit(&menuFontDString);

    metrics.cbSize = sizeof(metrics);



    if (TkWinGetPlatformTheme() != TK_THEME_WIN_VISTA) {
	metrics.cbSize -= sizeof(int);
    }

    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize,
	    &metrics, 0);
    menuFont = CreateFontIndirectW(&metrics.lfMenuFont);
    SelectObject(scratchDC, menuFont);
    GetTextMetricsW(scratchDC, &tm);
    GetTextFaceA(scratchDC, LF_FACESIZE, faceName);
    pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading,
	    72, GetDeviceCaps(scratchDC, LOGPIXELSY));
    if (tm.tmWeight >= 700) {
	bold = 1;
    }
    if (tm.tmItalic) {
	italic = 1;







|



>
|
>
>
>
>
>











|





|

>
>
|
|


|
|
|

|
|







3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
				 * called? */
{
    char sizeString[TCL_INTEGER_SPACE];
    char faceName[LF_FACESIZE];
    HDC scratchDC;
    int bold = 0;
    int italic = 0;
    TEXTMETRIC tm;
    int pointSize;
    HFONT menuFont;
    /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */
    struct {
        NONCLIENTMETRICS metrics;
#if (WINVER < 0x0600)
        int padding;
#endif
    } nc;
    OSVERSIONINFOW os;

    /*
     * Set all of the default options. The loop will terminate when we run out
     * of options via a break statement.
     */

    defaultBorderWidth = GetSystemMetrics(SM_CXBORDER);
    if (GetSystemMetrics(SM_CYBORDER) > defaultBorderWidth) {
	defaultBorderWidth = GetSystemMetrics(SM_CYBORDER);
    }

    scratchDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    if (!firstTime) {
	Tcl_DStringFree(&menuFontDString);
    }
    Tcl_DStringInit(&menuFontDString);

    nc.metrics.cbSize = sizeof(nc);

    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
    GetVersionExW(&os);
    if (os.dwMajorVersion < 6) {
	nc.metrics.cbSize -= sizeof(int);
    }

    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nc.metrics.cbSize,
	    &nc.metrics, 0);
    menuFont = CreateFontIndirect(&nc.metrics.lfMenuFont);
    SelectObject(scratchDC, menuFont);
    GetTextMetrics(scratchDC, &tm);
    GetTextFace(scratchDC, LF_FACESIZE, faceName);
    pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading,
	    72, GetDeviceCaps(scratchDC, LOGPIXELSY));
    if (tm.tmWeight >= 700) {
	bold = 1;
    }
    if (tm.tmItalic) {
	italic = 1;
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476

3477
3478
3479
3480
3481





3482
3483
3484
3485
3486
3487
3488

3489

3490
3491
3492
3493
3494
3495
3496
    /*
     * Now we go ahead and get the dimensions of the check mark and the
     * appropriate margins. Since this is fairly hairy, we do it here to save
     * time when traversing large sets of menu items.
     *
     * The code below was given to me by Microsoft over the phone. It is the
     * only way to ensure menu items line up, and is not documented.
     * How strange the calculation of indicatorDimensions[1] is...!
     */


    indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK);
    indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) +
	    GetSystemMetrics(SM_CXBORDER)
	    + GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8)
	    - GetSystemMetrics(SM_CXFIXEDFRAME);






    /*
     * Accelerators used to be always underlines until Win2K when a system
     * parameter was introduced to hide them unless Alt is pressed.
     */

    showMenuAccelerators = TRUE;

    SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);

}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *







<


>
|
|
|
|
|
>
>
>
>
>







>
|
>







3274
3275
3276
3277
3278
3279
3280

3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
    /*
     * Now we go ahead and get the dimensions of the check mark and the
     * appropriate margins. Since this is fairly hairy, we do it here to save
     * time when traversing large sets of menu items.
     *
     * The code below was given to me by Microsoft over the phone. It is the
     * only way to ensure menu items line up, and is not documented.

     */

    if (TkWinGetPlatformId() >= VER_PLATFORM_WIN32_WINDOWS) {
	indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK);
	indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) +
		GetSystemMetrics(SM_CXBORDER)
		+ GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8)
		- GetSystemMetrics(SM_CXFIXEDFRAME);
    } else {
	DWORD dimensions = GetMenuCheckMarkDimensions();
	indicatorDimensions[0] = HIWORD(dimensions);
	indicatorDimensions[1] = LOWORD(dimensions);
    }

    /*
     * Accelerators used to be always underlines until Win2K when a system
     * parameter was introduced to hide them unless Alt is pressed.
     */

    showMenuAccelerators = TRUE;
    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{
    WNDCLASSW wndClass;

    wndClass.style = CS_OWNDC;
    wndClass.lpfnWndProc = TkWinMenuProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = Tk_GetHINSTANCE();
    wndClass.hIcon = NULL;
    wndClass.hCursor = NULL;
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = MENU_CLASS_NAME;
    if (!RegisterClassW(&wndClass)) {
	Tcl_Panic("Failed to register menu window class");
    }

    wndClass.lpfnWndProc = TkWinEmbeddedMenuProc;
    wndClass.lpszClassName = EMBEDDED_MENU_CLASS_NAME;
    if (!RegisterClassW(&wndClass)) {
	Tcl_Panic("Failed to register embedded menu window class");
    }

    TkCreateExitHandler(MenuExitHandler, NULL);
    SetDefaults(1);
}

/*







|











|
|




|
|







3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{
    WNDCLASS wndClass;

    wndClass.style = CS_OWNDC;
    wndClass.lpfnWndProc = TkWinMenuProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = Tk_GetHINSTANCE();
    wndClass.hIcon = NULL;
    wndClass.hCursor = NULL;
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = MENU_CLASS_NAME;
    if (!RegisterClass(&wndClass)) {
	Tcl_Panic("Failed to register menu window class.");
    }

    wndClass.lpfnWndProc = TkWinEmbeddedMenuProc;
    wndClass.lpszClassName = EMBEDDED_MENU_CLASS_NAME;
    if (!RegisterClass(&wndClass)) {
	Tcl_Panic("Failed to register embedded menu window class.");
    }

    TkCreateExitHandler(MenuExitHandler, NULL);
    SetDefaults(1);
}

/*
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579

void
TkpMenuThreadInit(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->menuHWND = CreateWindowW(MENU_CLASS_NAME, L"MenuWindow", WS_POPUP,
	    0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL);

    if (!tsdPtr->menuHWND) {
	Tcl_Panic("Failed to create the menu window");
    }

    tsdPtr->embeddedMenuHWND =
	    CreateWindowW(EMBEDDED_MENU_CLASS_NAME, L"EmbeddedMenuWindow",
	    WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL);

    if (!tsdPtr->embeddedMenuHWND) {
	Tcl_Panic("Failed to create the embedded menu window");
    }

    Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&tsdPtr->commandTable, TCL_ONE_WORD_KEYS);

    TkCreateThreadExitHandler(MenuThreadExitHandler, NULL);
}







|



|



|



|







3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393

void
TkpMenuThreadInit(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP,
	    0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL);

    if (!tsdPtr->menuHWND) {
	Tcl_Panic("Failed to create the menu window.");
    }

    tsdPtr->embeddedMenuHWND =
	    CreateWindow(EMBEDDED_MENU_CLASS_NAME, "EmbeddedMenuWindow",
	    WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL);

    if (!tsdPtr->embeddedMenuHWND) {
	Tcl_Panic("Failed to create the embedded menu window.");
    }

    Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&tsdPtr->commandTable, TCL_ONE_WORD_KEYS);

    TkCreateThreadExitHandler(MenuThreadExitHandler, NULL);
}

Changes to win/tkWinPixmap.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
    TkWinDrawable *newTwdPtr, *twdPtr;
    int planes;
    Screen *screen;

    display->request++;

    newTwdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));
    newTwdPtr->type = TWD_BITMAP;
    newTwdPtr->bitmap.depth = depth;
    twdPtr = (TkWinDrawable *) d;
    if (twdPtr->type != TWD_BITMAP) {
	if (twdPtr->window.winPtr == NULL) {
	    newTwdPtr->bitmap.colormap = DefaultColormap(display,
		    DefaultScreen(display));







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
    TkWinDrawable *newTwdPtr, *twdPtr;
    int planes;
    Screen *screen;

    display->request++;

    newTwdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
    newTwdPtr->type = TWD_BITMAP;
    newTwdPtr->bitmap.depth = depth;
    twdPtr = (TkWinDrawable *) d;
    if (twdPtr->type != TWD_BITMAP) {
	if (twdPtr->window.winPtr == NULL) {
	    newTwdPtr->bitmap.colormap = DefaultColormap(display,
		    DefaultScreen(display));
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
	 * people to report this as a bug...
	 */

	if (newTwdPtr->bitmap.handle == NULL && !repeatError) {
	    LPVOID lpMsgBuf;

	    repeatError = 1;
	    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
		    FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
		    NULL, GetLastError(),
		    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		    (LPWSTR)&lpMsgBuf, 0, NULL)) {
		MessageBoxW(NULL, (LPWSTR) lpMsgBuf,
			L"Tk_GetPixmap: Error from CreateDIBSection",
			MB_OK | MB_ICONINFORMATION);
		LocalFree(lpMsgBuf);
	    }
	}
    }

    if (newTwdPtr->bitmap.handle == NULL) {
	ckfree(newTwdPtr);
	return None;
    }

    return (Pixmap) newTwdPtr;
}

/*







|



|
|
|







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
	 * people to report this as a bug...
	 */

	if (newTwdPtr->bitmap.handle == NULL && !repeatError) {
	    LPVOID lpMsgBuf;

	    repeatError = 1;
	    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
		    FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
		    NULL, GetLastError(),
		    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		    (LPTSTR) &lpMsgBuf, 0, NULL)) {
		MessageBox(NULL, (LPCTSTR) lpMsgBuf,
			"Tk_GetPixmap: Error from CreateDIBSection",
			MB_OK | MB_ICONINFORMATION);
		LocalFree(lpMsgBuf);
	    }
	}
    }

    if (newTwdPtr->bitmap.handle == NULL) {
	ckfree((char *) newTwdPtr);
	return None;
    }

    return (Pixmap) newTwdPtr;
}

/*
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    Pixmap pixmap)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;

    display->request++;
    if (twdPtr != NULL) {
	DeleteObject(twdPtr->bitmap.handle);
	ckfree(twdPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetPixmapColormap --







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    Pixmap pixmap)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;

    display->request++;
    if (twdPtr != NULL) {
	DeleteObject(twdPtr->bitmap.handle);
	ckfree((char *) twdPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetPixmapColormap --
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    (void)display;
    (void)root_return;
    (void)x_return;
    (void)y_return;
    (void)border_width_return;
    (void)depth_return;

    if (twdPtr->type == TWD_BITMAP) {
	HDC dc;
	BITMAPINFO info;

	if (twdPtr->bitmap.handle == NULL) {
	    Tcl_Panic("XGetGeometry: invalid pixmap");







<
<
<
<
<
<







204
205
206
207
208
209
210






211
212
213
214
215
216
217
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;







    if (twdPtr->type == TWD_BITMAP) {
	HDC dc;
	BITMAPINFO info;

	if (twdPtr->bitmap.handle == NULL) {
	    Tcl_Panic("XGetGeometry: invalid pixmap");

Changes to win/tkWinPointer.c.

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    }
    if (GetKeyState(VK_MBUTTON) & 0x8000) {
	state |= Button2Mask;
    }
    if (GetKeyState(VK_RBUTTON) & 0x8000) {
	state |= Button3Mask;
    }
    if (GetKeyState(VK_XBUTTON1) & 0x8000) {
	state |= Button4Mask;
    }
    if (GetKeyState(VK_XBUTTON2) & 0x8000) {
	state |= Button5Mask;
    }
    return state;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinPointerEvent --
 *
 *	This procedure is called for each pointer-related event. It converts
 *	the position to root coords and updates the global pointer state
 *	machine. It also ensures that the mouse timer is scheduled.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May queue events and change the grab state.
 *
 *----------------------------------------------------------------------
 */

void
TkWinPointerEvent(
    HWND hwnd,			/* Window for coords, or NULL for the root
				 * window. */
    int x, int y)		/* Coords relative to hwnd, or screen if hwnd
				 * is NULL. */
{
    POINT pos;
    int state;







<
<
<
<
<
<






|















|







77
78
79
80
81
82
83






84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    }
    if (GetKeyState(VK_MBUTTON) & 0x8000) {
	state |= Button2Mask;
    }
    if (GetKeyState(VK_RBUTTON) & 0x8000) {
	state |= Button3Mask;
    }






    return state;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PointerEvent --
 *
 *	This procedure is called for each pointer-related event. It converts
 *	the position to root coords and updates the global pointer state
 *	machine. It also ensures that the mouse timer is scheduled.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May queue events and change the grab state.
 *
 *----------------------------------------------------------------------
 */

void
Tk_PointerEvent(
    HWND hwnd,			/* Window for coords, or NULL for the root
				 * window. */
    int x, int y)		/* Coords relative to hwnd, or screen if hwnd
				 * is NULL. */
{
    POINT pos;
    int state;
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    Display *display,
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    (void)display;
    (void)owner_events;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)time;

    keyboardWinPtr = TkWinGetWinPtr(grab_window);
    return GrabSuccess;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<
<
<
<







169
170
171
172
173
174
175






176
177
178
179
180
181
182
    Display *display,
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{






    keyboardWinPtr = TkWinGetWinPtr(grab_window);
    return GrabSuccess;
}

/*
 *----------------------------------------------------------------------
 *
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
 */

int
XUngrabKeyboard(
    Display *display,
    Time time)
{
    (void)display;
    (void)time;

    keyboardWinPtr = NULL;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<







194
195
196
197
198
199
200



201
202
203
204
205
206
207
 */

int
XUngrabKeyboard(
    Display *display,
    Time time)
{



    keyboardWinPtr = NULL;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
 *	May schedule a new timer and/or generate enter/leave events.
 *
 *----------------------------------------------------------------------
 */

void
MouseTimerProc(
    ClientData dummy)
{
    POINT pos;
    (void)dummy;

    mouseTimerSet = 0;

    /*
     * Get the current mouse position and window. Don't do anything if the
     * mouse hasn't moved since the last time we looked.
     */

    GetCursorPos(&pos);
    TkWinPointerEvent(NULL, pos.x, pos.y);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinCancelMouseTimer --
 *







|


<









|







216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 *	May schedule a new timer and/or generate enter/leave events.
 *
 *----------------------------------------------------------------------
 */

void
MouseTimerProc(
    ClientData clientData)
{
    POINT pos;


    mouseTimerSet = 0;

    /*
     * Get the current mouse position and window. Don't do anything if the
     * mouse hasn't moved since the last time we looked.
     */

    GetCursorPos(&pos);
    Tk_PointerEvent(NULL, pos.x, pos.y);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinCancelMouseTimer --
 *
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
void
TkGetPointerCoords(
    Tk_Window tkwin,		/* Window that identifies screen on which
				 * lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    POINT point;
    (void)tkwin;

    GetCursorPos(&point);
    *xPtr = point.x;
    *yPtr = point.y;
}

/*







<







280
281
282
283
284
285
286

287
288
289
290
291
292
293
void
TkGetPointerCoords(
    Tk_Window tkwin,		/* Window that identifies screen on which
				 * lookup is to be done. */
    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
{
    POINT point;


    GetCursorPos(&point);
    *xPtr = point.x;
    *yPtr = point.y;
}

/*
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
    Window *child_return,
    int *root_x_return,
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    (void)w;
    (void)root_return;
    (void)child_return;
    (void)win_x_return;
    (void)win_y_return;

    display->request++;
    TkGetPointerCoords(NULL, root_x_return, root_y_return);
    *mask_return = TkWinGetModifierState();
    return True;
}

/*
 *----------------------------------------------------------------------
 *
 * XWarpPointer, TkpWarpPointer --
 *
 *	Move pointer to new location. Note that implementation of XWarpPointer
 *	is incomplete.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Mouse pointer changes position on screen.
 *
 *----------------------------------------------------------------------
 */

/*
 * TkSetCursorPos is a helper function replacing SetCursorPos since this
 * latter Windows function appears to have been broken by Microsoft
 * since Win10 Falls Creator Update - See ticket [69b48f427e] along with
 * several other Internet reports about this breakage.
 */

void TkSetCursorPos(
    int x,
    int y)
{
    INPUT input;
    int xscreen = (int)(GetSystemMetrics(SM_CXSCREEN) - 1);
    int yscreen = (int)(GetSystemMetrics(SM_CYSCREEN) - 1);

    input.type = INPUT_MOUSE;
    input.mi.dx = (x * 65535 + xscreen/2) / xscreen;
    input.mi.dy = (y * 65535 + yscreen/2) / yscreen;

    /*
     * Horrible workaround here. There is a bug on Win 10: when warping to
     * pixel (x = 0, y = 0) the SendInput() below just does not move the
     * mouse pointer. However, as soon as dx or dy is non zero it moves as
     * expected. Given the scaling factor of 65535 (see above),
     * (dx = 1 , dy = 0) still means pixel (x = 0, y = 0).
     * See ticket [69b48f427e].
     */
    if (input.mi.dx == 0 && input.mi.dy == 0) {
        input.mi.dx = 1;
    }

    input.mi.mouseData = 0;
    input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
    input.mi.time = 0;
    input.mi.dwExtraInfo = 0;
    SendInput(1, &input, sizeof(input));







<
<
<
<
<
<









|

|
|










|
|
|
|
|
|










|
|










|







317
318
319
320
321
322
323






324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    Window *child_return,
    int *root_x_return,
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{






    display->request++;
    TkGetPointerCoords(NULL, root_x_return, root_y_return);
    *mask_return = TkWinGetModifierState();
    return True;
}

/*
 *----------------------------------------------------------------------
 *
 * XWarpPointer --
 *
 *	Move pointer to new location. This is not a complete implementation of
 *	this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Mouse pointer changes position on screen.
 *
 *----------------------------------------------------------------------
 */

 /*
  * TkSetCursorPos is a helper function replacing SetCursorPos since this
  * latter Windows function appears to have been broken by Microsoft
  * since Win10 Falls Creator Update - See ticket [69b48f427e] along with
  * several other Internet reports about this breakage.
  */

void TkSetCursorPos(
    int x,
    int y)
{
    INPUT input;
    int xscreen = (int)(GetSystemMetrics(SM_CXSCREEN) - 1);
    int yscreen = (int)(GetSystemMetrics(SM_CYSCREEN) - 1);

    input.type = INPUT_MOUSE;
    input.mi.dx = (x * 65535 + xscreen / 2) / xscreen;
    input.mi.dy = (y * 65535 + yscreen / 2) / yscreen;

    /*
     * Horrible workaround here. There is a bug on Win 10: when warping to
     * pixel (x = 0, y = 0) the SendInput() below just does not move the
     * mouse pointer. However, as soon as dx or dy is non zero it moves as
     * expected. Given the scaling factor of 65535 (see above),
     * (dx = 1 , dy = 0) still means pixel (x = 0, y = 0).
     * See ticket [69b48f427e].
     */
    if (input.mi.dx == 0 && input.mi.dy == 0) {
	input.mi.dx = 1;
    }

    input.mi.mouseData = 0;
    input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
    input.mi.time = 0;
    input.mi.dwExtraInfo = 0;
    SendInput(1, &input, sizeof(input));
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    int src_y,
    unsigned int src_width,
    unsigned int src_height,
    int dest_x,
    int dest_y)
{
    RECT r;
    (void)display;
    (void)src_w;
    (void)src_x;
    (void)src_y;
    (void)src_width;
    (void)src_height;

    GetWindowRect(Tk_GetHWND(dest_w), &r);
    TkSetCursorPos(r.left+dest_x, r.top+dest_y);
    return Success;
}

void
TkpWarpPointer(
    TkDisplay *dispPtr)
{
    if (dispPtr->warpWindow) {
	RECT r;

	GetWindowRect(Tk_GetHWND(Tk_WindowId(dispPtr->warpWindow)), &r);
	TkSetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY);
    } else {
	TkSetCursorPos(dispPtr->warpX, dispPtr->warpY);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * XGetInputFocus --
 *
 *	Retrieves the current keyboard focus window.







<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<







391
392
393
394
395
396
397






398
399
400
401
402














403
404
405
406
407
408
409
    int src_y,
    unsigned int src_width,
    unsigned int src_height,
    int dest_x,
    int dest_y)
{
    RECT r;







    GetWindowRect(Tk_GetHWND(dest_w), &r);
    TkSetCursorPos(r.left+dest_x, r.top+dest_y);
    return Success;
}















/*
 *----------------------------------------------------------------------
 *
 * XGetInputFocus --
 *
 *	Retrieves the current keyboard focus window.
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
XGetInputFocus(
    Display *display,
    Window *focus_return,
    int *revert_to_return)
{
    Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());

    *focus_return = tkwin ? Tk_WindowId(tkwin) : 0;
    *revert_to_return = RevertToParent;
    display->request++;
    return Success;
}

/*
 *----------------------------------------------------------------------







|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
XGetInputFocus(
    Display *display,
    Window *focus_return,
    int *revert_to_return)
{
    Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());

    *focus_return = tkwin ? Tk_WindowId(tkwin) : None;
    *revert_to_return = RevertToParent;
    display->request++;
    return Success;
}

/*
 *----------------------------------------------------------------------
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
int
XSetInputFocus(
    Display *display,
    Window focus,
    int revert_to,
    Time time)
{
    (void)revert_to;
    (void)time;

    display->request++;
    if (focus != None) {
	SetFocus(Tk_GetHWND(focus));
    }
    return Success;
}








<
<
<







451
452
453
454
455
456
457



458
459
460
461
462
463
464
int
XSetInputFocus(
    Display *display,
    Window focus,
    int revert_to,
    Time time)
{



    display->request++;
    if (focus != None) {
	SetFocus(Tk_GetHWND(focus));
    }
    return Success;
}

602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
	SetCapture(Tk_GetHWND(Tk_WindowId(winPtr)));
	captured = 1;
    } else {
	captured = 0;
	ReleaseCapture();
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetCapture --
 *
 *	This function requests which window is capturing the mouse.
 *
 * Results:
 *	The return value is a pointer to the capture window, if there is
 *      one, otherwise it is NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkpGetCapture(void)
{
    return Tk_HWNDToWindow(GetCapture());
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








556
557
558
559
560
561
562























563
564
565
566
567
568
569
570
	SetCapture(Tk_GetHWND(Tk_WindowId(winPtr)));
	captured = 1;
    } else {
	captured = 0;
	ReleaseCapture();
    }
}
























/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinPort.h.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _WINPORT
#define _WINPORT

/*
 *---------------------------------------------------------------------------
 * The following sets of #includes and #ifdefs are required to get Tcl to
 * compile under the windows compilers.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <wchar.h>
#include <io.h>

#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>

/*
 * Need to block out this include for building extensions with MetroWerks
 * compiler for Win32.
 */

#ifndef __MWERKS__







<
<
|
<
<
<
|
|
|
|
>
|
|
|
|
|
|
|
|
|







10
11
12
13
14
15
16


17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _WINPORT
#define _WINPORT



#include <X11/Xlib.h>



#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include <malloc.h>
#include <errno.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <fcntl.h>
#include <io.h>

/*
 * Need to block out this include for building extensions with MetroWerks
 * compiler for Win32.
 */

#ifndef __MWERKS__
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#   define _TCHAR_DEFINED
#endif
#if defined(_MSC_VER) && defined(__STDC__)
    /* VS2005 SP1 misses this. See [Bug #3110161] */
    typedef _TCHAR TCHAR;
#endif

#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#ifndef __GNUC__
#    define strncasecmp _strnicmp
#    define strcasecmp _stricmp
#endif

#define NBBY 8







<
<
<
<
<
<
<
<







57
58
59
60
61
62
63








64
65
66
67
68
69
70
#   define _TCHAR_DEFINED
#endif
#if defined(_MSC_VER) && defined(__STDC__)
    /* VS2005 SP1 misses this. See [Bug #3110161] */
    typedef _TCHAR TCHAR;
#endif










#ifndef __GNUC__
#    define strncasecmp _strnicmp
#    define strcasecmp _stricmp
#endif

#define NBBY 8
91
92
93
94
95
96
97


98
99
100
101
102
103
104

#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)


#   pragma warning(disable:4146)
#   pragma warning(disable:4267)
#   pragma warning(disable:4244)
#   pragma warning(disable:4311)
#   pragma warning(disable:4312)
#   pragma warning(disable:4996)
#if !defined(_WIN64)







>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)
#   pragma warning(disable:4047)
#   pragma warning(disable:4090) /* see: https://developercommunity.visualstudio.com/t/c-compiler-incorrect-propagation-of-const-qualifie/390711 */
#   pragma warning(disable:4146)
#   pragma warning(disable:4267)
#   pragma warning(disable:4244)
#   pragma warning(disable:4311)
#   pragma warning(disable:4312)
#   pragma warning(disable:4996)
#if !defined(_WIN64)
113
114
115
116
117
118
119








120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

#ifdef _MSC_VER
#    define TK_READ_DATA_PENDING(f) ((f)->_cnt > 0)
#else /* _MSC_VER */
#    define TK_READ_DATA_PENDING(f) ((f)->level > 0)
#endif /* _MSC_VER */









/*
 * The following Tk functions are implemented as macros under Windows.
 */

#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \
	| ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000)

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

/*
 * These calls implement native bitmaps which are not currently
 * supported under Windows.  The macros eliminate the calls.
 */

#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None

#endif /* _WINPORT */







>
>
>
>
>
>
>
>







<
<
<
<
<
<










103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124






125
126
127
128
129
130
131
132
133
134

#ifdef _MSC_VER
#    define TK_READ_DATA_PENDING(f) ((f)->_cnt > 0)
#else /* _MSC_VER */
#    define TK_READ_DATA_PENDING(f) ((f)->level > 0)
#endif /* _MSC_VER */

/*
 * The following stubs implement various calls that don't do anything
 * under Windows.
 */

#define TkFreeWindowId(dispPtr,w)
#define TkInitXId(dispPtr)

/*
 * The following Tk functions are implemented as macros under Windows.
 */

#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \
	| ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000)







/*
 * These calls implement native bitmaps which are not currently
 * supported under Windows.  The macros eliminate the calls.
 */

#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None

#endif /* _WINPORT */

Changes to win/tkWinRegion.c.

1
2
3
4
5
6
7
8
9
10
11
12
13







14
15
16
17
18
19
20
/*
 * tkWinRegion.c --
 *
 *	Tk Region emulation code.
 *
 * 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.
 */

#include "tkWinInt.h"









/*
 *----------------------------------------------------------------------
 *
 * TkCreateRegion --
 *
 *	Construct an empty region.













>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * tkWinRegion.c --
 *
 *	Tk Region emulation code.
 *
 * 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.
 */

#include "tkWinInt.h"

#undef TkCreateRegion
#undef TkDestroyRegion
#undef TkClipBox
#undef TkIntersectRegion
#undef TkUnionRectWithRegion
#undef TkRectInRegion
#undef TkSubtractRegion

/*
 *----------------------------------------------------------------------
 *
 * TkCreateRegion --
 *
 *	Construct an empty region.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 *
 * Side effects:
 *	Frees the storage associated with the specified region.
 *
 *----------------------------------------------------------------------
 */

int
TkDestroyRegion(
    TkRegion r)
{
    DeleteObject((HRGN) r);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipBox --
 *
 *	Computes the bounding box of a region.
 *
 * Results:
 *	Sets rect_return to the bounding box of the region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkClipBox(
    TkRegion r,
    XRectangle* rect_return)
{
    RECT rect;

    GetRgnBox((HRGN)r, &rect);
    rect_return->x = (short) rect.left;
    rect_return->y = (short) rect.top;
    rect_return->width = (short) (rect.right - rect.left);
    rect_return->height = (short) (rect.bottom - rect.top);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkIntersectRegion --
 *
 *	Compute the intersection of two regions.
 *
 * Results:
 *	Returns the result in the dr_return region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkIntersectRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUnionRectWithRegion --
 *
 *	Create the union of a source region and a rectangle.
 *
 * Results:
 *	Returns the result in the dr_return region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkUnionRectWithRegion(
    XRectangle *rectangle,
    TkRegion src_region,
    TkRegion dest_region_return)
{
    HRGN rectRgn = CreateRectRgn(rectangle->x, rectangle->y,
	    rectangle->x + rectangle->width, rectangle->y + rectangle->height);

    CombineRgn((HRGN) dest_region_return, (HRGN) src_region,
	    (HRGN) rectRgn, RGN_OR);
    DeleteObject(rectRgn);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *







|




<


















|











<


















|






<


















|











<







55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
 *
 * Side effects:
 *	Frees the storage associated with the specified region.
 *
 *----------------------------------------------------------------------
 */

void
TkDestroyRegion(
    TkRegion r)
{
    DeleteObject((HRGN) r);

}

/*
 *----------------------------------------------------------------------
 *
 * TkClipBox --
 *
 *	Computes the bounding box of a region.
 *
 * Results:
 *	Sets rect_return to the bounding box of the region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkClipBox(
    TkRegion r,
    XRectangle* rect_return)
{
    RECT rect;

    GetRgnBox((HRGN)r, &rect);
    rect_return->x = (short) rect.left;
    rect_return->y = (short) rect.top;
    rect_return->width = (short) (rect.right - rect.left);
    rect_return->height = (short) (rect.bottom - rect.top);

}

/*
 *----------------------------------------------------------------------
 *
 * TkIntersectRegion --
 *
 *	Compute the intersection of two regions.
 *
 * Results:
 *	Returns the result in the dr_return region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkIntersectRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND);

}

/*
 *----------------------------------------------------------------------
 *
 * TkUnionRectWithRegion --
 *
 *	Create the union of a source region and a rectangle.
 *
 * Results:
 *	Returns the result in the dr_return region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkUnionRectWithRegion(
    XRectangle *rectangle,
    TkRegion src_region,
    TkRegion dest_region_return)
{
    HRGN rectRgn = CreateRectRgn(rectangle->x, rectangle->y,
	    rectangle->x + rectangle->width, rectangle->y + rectangle->height);

    CombineRgn((HRGN) dest_region_return, (HRGN) src_region,
	    (HRGN) rectRgn, RGN_OR);
    DeleteObject(rectRgn);

}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkSubtractRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);
    return Success;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|






<









266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSubtractRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinScrlbr.c.

58
59
60
61
62
63
64


65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

/*
 * Declarations for functions defined in this file.
 */

static Window		CreateProc(Tk_Window tkwin, Window parent,
			    ClientData instanceData);


static void		ModalLoop(WinScrollbar *, XEvent *eventPtr);

static LRESULT CALLBACK	ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static void		UpdateScrollbar(WinScrollbar *scrollPtr);
static void		UpdateScrollbarMetrics(void);

/*
 * The class procedure table for the scrollbar widget.
 */

const Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,			/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL 			/* modalProc */
};

static void
WinScrollbarEventProc(ClientData clientData, XEvent *eventPtr)
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;

    if (eventPtr->type == ButtonPress) {
	ModalLoop(scrollPtr, eventPtr);
    } else {
	TkScrollbarEventProc(clientData, eventPtr);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
 *	Allocate a new TkScrollbar structure.







>
>
|
>









|



|


<
<
<
<
<
<
<
<
<
<
<
<







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84












85
86
87
88
89
90
91

/*
 * Declarations for functions defined in this file.
 */

static Window		CreateProc(Tk_Window tkwin, Window parent,
			    ClientData instanceData);
static void		ModalLoopProc(Tk_Window tkwin, XEvent *eventPtr);
static int		ScrollbarBindProc(ClientData clientData,
			    Tcl_Interp *interp, XEvent *eventPtr,
			    Tk_Window tkwin, KeySym keySym);
static LRESULT CALLBACK	ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static void		UpdateScrollbar(WinScrollbar *scrollPtr);
static void		UpdateScrollbarMetrics(void);

/*
 * The class procedure table for the scrollbar widget.
 */

Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,			/* worldChangedProc */
    CreateProc,			/* createProc */
    ModalLoopProc,		/* modalProc */
};














/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
 *	Allocate a new TkScrollbar structure.
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130









131
132
133
134
135
136
137
 */

TkScrollbar *
TkpCreateScrollbar(
    Tk_Window tkwin)
{
    WinScrollbar *scrollPtr;


    if (!initialized) {
	Tcl_MutexLock(&winScrlbrMutex);
	UpdateScrollbarMetrics();
	initialized = 1;
	Tcl_MutexUnlock(&winScrlbrMutex);
    }

    scrollPtr = (WinScrollbar *)ckalloc(sizeof(WinScrollbar));
    scrollPtr->winFlags = 0;
    scrollPtr->hwnd = NULL;

    Tk_CreateEventHandler(tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask,
	    WinScrollbarEventProc, scrollPtr);










    return (TkScrollbar *) scrollPtr;
}

/*
 *----------------------------------------------------------------------
 *







>








|




|
|
>
>
>
>
>
>
>
>
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 */

TkScrollbar *
TkpCreateScrollbar(
    Tk_Window tkwin)
{
    WinScrollbar *scrollPtr;
    TkWindow *winPtr = (TkWindow *)tkwin;

    if (!initialized) {
	Tcl_MutexLock(&winScrlbrMutex);
	UpdateScrollbarMetrics();
	initialized = 1;
	Tcl_MutexUnlock(&winScrlbrMutex);
    }

    scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));
    scrollPtr->winFlags = 0;
    scrollPtr->hwnd = NULL;

    Tk_CreateEventHandler(tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    TkScrollbarEventProc, (ClientData) scrollPtr);

    if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
	Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
		(ClientData)1);
	TkCreateBindingProcedure(winPtr->mainPtr->interp,
		winPtr->mainPtr->bindingTable,
		(ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
		ScrollbarBindProc, NULL, NULL);
    }

    return (TkScrollbar *) scrollPtr;
}

/*
 *----------------------------------------------------------------------
 *
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
	style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		| SBS_VERT;
    } else {
	style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		| SBS_HORZ;
    }

    scrollPtr->hwnd = CreateWindowW(L"SCROLLBAR", NULL, style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);

    /*
     * Ensure new window is inserted into the stacking order at the correct
     * place.
     */







|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
	style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		| SBS_VERT;
    } else {
	style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		| SBS_HORZ;
    }

    scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);

    /*
     * Ensure new window is inserted into the stacking order at the correct
     * place.
     */
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	    TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
		    Below);
	    break;
	}
    }

    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->oldProc = (WNDPROC)SetWindowLongPtrW(scrollPtr->hwnd,
	    GWLP_WNDPROC, (LONG_PTR) ScrollbarProc);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);

    UpdateScrollbar(scrollPtr);
    return window;
}

/*







|
|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
	    TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
		    Below);
	    break;
	}
    }

    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd,
	    GWLP_WNDPROC, (INT_PTR) ScrollbarProc);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);

    UpdateScrollbar(scrollPtr);
    return window;
}

/*
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->info.tkwin;

    scrollPtr->info.flags &= ~REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Destroy and recreate the scrollbar control if the orientation has
     * changed.
     */

    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
	HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));

	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc);
	DestroyWindow(hwnd);

	CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
		scrollPtr);
    } else {
	UpdateScrollbar(scrollPtr);
    }
}

/*
 *----------------------------------------------------------------------







|















|



|







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
    Tk_Window tkwin = scrollPtr->info.tkwin;

    scrollPtr->info.flags &= ~REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Destroy and recreate the scrollbar control if the orientation has
     * changed.
     */

    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
	HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));

	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) scrollPtr->oldProc);
	DestroyWindow(hwnd);

	CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
		(ClientData) scrollPtr);
    } else {
	UpdateScrollbar(scrollPtr);
    }
}

/*
 *----------------------------------------------------------------------
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    HWND hwnd = winScrollPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc);
	if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
	    ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
	    SetParent(hwnd, NULL);
	}
    }
    winScrollPtr->winFlags |= ALREADY_DEAD;
}







|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    HWND hwnd = winScrollPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc);
	if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
	    ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
	    SetParent(hwnd, NULL);
	}
    }
    winScrollPtr->winFlags |= ALREADY_DEAD;
}
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeScrollbarGeometry(
    TkScrollbar *scrollPtr)
				/* Scrollbar whose geometry may have
				 * changed. */
{
    int fieldLength, minThumbSize;

    /*
     * Windows doesn't use focus rings on scrollbars, but we still perform







|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeScrollbarGeometry(
    register TkScrollbar *scrollPtr)
				/* Scrollbar whose geometry may have
				 * changed. */
{
    int fieldLength, minThumbSize;

    /*
     * Windows doesn't use focus rings on scrollbars, but we still perform
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    case WM_VSCROLL: {
	Tcl_Interp *interp;
	Tcl_DString cmdString;
	int command = LOWORD(wParam);
	int code;

	GetCursorPos(&point);
	TkTranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
		MAKELPARAM(point.x, point.y), &result);

	if (command == SB_ENDSCROLL) {
	    return 0;
	}

	/*







|







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    case WM_VSCROLL: {
	Tcl_Interp *interp;
	Tcl_DString cmdString;
	int command = LOWORD(wParam);
	int code;

	GetCursorPos(&point);
	Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
		MAKELPARAM(point.x, point.y), &result);

	if (command == SB_ENDSCROLL) {
	    return 0;
	}

	/*
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
	    Tcl_DStringAppendElement(&cmdString, valueString);
	}

	interp = scrollPtr->info.interp;
	code = Tcl_EvalEx(interp, cmdString.string, -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
	    Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
	    Tcl_BackgroundException(interp, code);
	}
	Tcl_DStringFree(&cmdString);

	Tcl_ServiceAll();
	return 0;
    }

    default:
	if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return CallWindowProcW(scrollPtr->oldProc, hwnd, message, wParam, lParam);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *







|








|



|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
	    Tcl_DStringAppendElement(&cmdString, valueString);
	}

	interp = scrollPtr->info.interp;
	code = Tcl_EvalEx(interp, cmdString.string, -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
	    Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
	    Tcl_BackgroundError(interp);
	}
	Tcl_DStringFree(&cmdString);

	Tcl_ServiceAll();
	return 0;
    }

    default:
	if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
587
588
589
590
591
592
593
594
595
596
597

598
















599







600








601
602
603
604
605
606
607





608
609
610
611
612
613
614
615
616
617


618
619
620
621
622
623
624
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)
				/* Information about widget; may or may not
				 * already have values for some fields. */
{

    (void)scrollPtr;
















}
















/*
 *----------------------------------------------------------------------
 *
 * ModalLoop --
 *
 *	This function is invoked in response to a ButtonPress event.
 *	It resends the event to the Scrollbar window procedure,





 * 	which in turn enters a modal loop.
 *
 *----------------------------------------------------------------------
 */

static void
ModalLoop(
    WinScrollbar *scrollPtr,
    XEvent *eventPtr)
{


    int oldMode;

    if (scrollPtr->hwnd) {
	Tcl_Preserve(scrollPtr);
	scrollPtr->winFlags |= IN_MODAL_LOOP;
	oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);







|



>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>



|

|
|
>
>
>
>
>
|





|
|


>
>







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    register TkScrollbar *scrollPtr)
				/* Information about widget; may or may not
				 * already have values for some fields. */
{
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarBindProc --
 *
 *	This procedure is invoked when the default <ButtonPress> binding on
 *	the Scrollbar bind tag fires.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The event enters a modal loop.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarBindProc(
    ClientData clientData,
    Tcl_Interp *interp,
    XEvent *eventPtr,
    Tk_Window tkwin,
    KeySym keySym)
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (eventPtr->type == ButtonPress) {
	winPtr->flags |= TK_DEFER_MODAL;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ModalLoopProc --
 *
 *	This function is invoked at the end of the event processing whenever
 *	the ScrollbarBindProc has been invoked for a ButtonPress event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Enters a modal loop.
 *
 *----------------------------------------------------------------------
 */

static void
ModalLoopProc(
    Tk_Window tkwin,
    XEvent *eventPtr)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
    int oldMode;

    if (scrollPtr->hwnd) {
	Tcl_Preserve(scrollPtr);
	scrollPtr->winFlags |= IN_MODAL_LOOP;
	oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{
    int length, width, tmp;

    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);







|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{
    int length, width, tmp;

    if (scrollPtr->vertical) {
	length = Tk_Height(scrollPtr->tkwin);

Changes to win/tkWinSend.c.

10
11
12
13
14
15
16




17
18
19
20
21
22
23
 * 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 "tkWinSendCom.h"





/*
 * Should be defined in WTypes.h but mingw 1.0 is missing them.
 */

#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED
#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x01







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 "tkWinSendCom.h"

#ifdef _MSC_VER
#define vsnprintf _vsnprintf
#endif

/*
 * Should be defined in WTypes.h but mingw 1.0 is missing them.
 */

#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED
#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x01
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
} SendEvent;

#ifdef TK_SEND_ENABLED_ON_WINDOWS
typedef struct {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * Functions internal to this file.
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void		CmdDeleteProc(ClientData clientData);
static void		InterpDeleteProc(ClientData clientData,
			    Tcl_Interp *interp);
static void		RevokeObjectRegistration(RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static HRESULT		BuildMoniker(const char *name, LPMONIKER *pmk);
#ifdef TK_SEND_ENABLED_ON_WINDOWS
static HRESULT		RegisterInterp(const char *name,
			    RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static int		FindInterpreterObject(Tcl_Interp *interp,
			    const char *name, LPDISPATCH *ppdisp);
static int		Send(LPDISPATCH pdispInterp, Tcl_Interp *interp,
			    int async, ClientData clientData, int objc,
			    Tcl_Obj *const objv[]);

static void		SendTrace(const char *format, ...);
static Tcl_EventProc	SendEventProc;

#if defined(DEBUG) || defined(_DEBUG)
#define TRACE SendTrace
#else
#define TRACE 1 ? ((void)0) : SendTrace
#endif /* DEBUG || _DEBUG */

/*
 *--------------------------------------------------------------
 *
 * Tk_SetAppName --
 *
 *	This function is called to associate an ASCII name with a Tk







|










|




|





>







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
} SendEvent;

#ifdef TK_SEND_ENABLED_ON_WINDOWS
typedef struct {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#endif

/*
 * Functions internal to this file.
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void		CmdDeleteProc(ClientData clientData);
static void		InterpDeleteProc(ClientData clientData,
			    Tcl_Interp *interp);
static void		RevokeObjectRegistration(RegisteredInterp *riPtr);
#endif
static HRESULT		BuildMoniker(const char *name, LPMONIKER *pmk);
#ifdef TK_SEND_ENABLED_ON_WINDOWS
static HRESULT		RegisterInterp(const char *name,
			    RegisteredInterp *riPtr);
#endif
static int		FindInterpreterObject(Tcl_Interp *interp,
			    const char *name, LPDISPATCH *ppdisp);
static int		Send(LPDISPATCH pdispInterp, Tcl_Interp *interp,
			    int async, ClientData clientData, int objc,
			    Tcl_Obj *const objv[]);
static Tcl_Obj *	Win32ErrorObj(HRESULT hrError);
static void		SendTrace(const char *format, ...);
static Tcl_EventProc	SendEventProc;

#if defined(DEBUG) || defined(_DEBUG)
#define TRACE SendTrace
#else
#define TRACE 1 ? ((void)0) : SendTrace
#endif

/*
 *--------------------------------------------------------------
 *
 * Tk_SetAppName --
 *
 *	This function is called to associate an ASCII name with a Tk
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
				 * be named: it is just used to identify the
				 * application and the display.  */
    const char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS
    (void)tkwin;

    /*
     * Temporarily disabled for bug #858822
     */

    return name;
#else /* TK_SEND_ENABLED_ON_WINDOWS */

    ThreadSpecificData *tsdPtr = NULL;
    TkWindow *winPtr = (TkWindow *) tkwin;
    RegisteredInterp *riPtr = NULL;
    Tcl_Interp *interp;
    HRESULT hr = S_OK;

    interp = winPtr->mainPtr->interp;


    tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Initialise the COM library for this interpreter just once.
     */

    if (tsdPtr->initialized == 0) {
	hr = CoInitialize(0);
	if (FAILED(hr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "failed to initialize the COM library", -1));
	    Tcl_SetErrorCode(interp, "TK", "SEND", "COM", NULL);
	    return "";
	}
	tsdPtr->initialized = 1;
	TRACE("Initialized COM library for interp 0x%" TCL_Z_MODIFIER "x\n", (size_t)interp);
    }

    /*
     * If the interp hasn't been registered before then we need to create the
     * registration structure and the COM object. If it has been registered
     * already then we can reuse all and just register the new name.
     */

    riPtr = Tcl_GetAssocData(interp, "tkWinSend::ri", NULL);
    if (riPtr == NULL) {
	LPUNKNOWN *objPtr;

	riPtr = (RegisteredInterp *)ckalloc(sizeof(RegisteredInterp));
	memset(riPtr, 0, sizeof(RegisteredInterp));
	riPtr->interp = interp;

	objPtr = &riPtr->obj;
	hr = TkWinSendCom_CreateInstance(interp, &IID_IUnknown,
		(void **) objPtr);








<
<














>
>
|








|
|
<



|












|







122
123
124
125
126
127
128


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
				 * be named: it is just used to identify the
				 * application and the display.  */
    const char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS


    /*
     * Temporarily disabled for bug #858822
     */

    return name;
#else /* TK_SEND_ENABLED_ON_WINDOWS */

    ThreadSpecificData *tsdPtr = NULL;
    TkWindow *winPtr = (TkWindow *) tkwin;
    RegisteredInterp *riPtr = NULL;
    Tcl_Interp *interp;
    HRESULT hr = S_OK;

    interp = winPtr->mainPtr->interp;

    tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Initialise the COM library for this interpreter just once.
     */

    if (tsdPtr->initialized == 0) {
	hr = CoInitialize(0);
	if (FAILED(hr)) {
	    Tcl_SetResult(interp,
		    "failed to initialize the COM library", TCL_STATIC);

	    return "";
	}
	tsdPtr->initialized = 1;
	TRACE("Initialized COM library for interp 0x%08X\n", (long)interp);
    }

    /*
     * If the interp hasn't been registered before then we need to create the
     * registration structure and the COM object. If it has been registered
     * already then we can reuse all and just register the new name.
     */

    riPtr = Tcl_GetAssocData(interp, "tkWinSend::ri", NULL);
    if (riPtr == NULL) {
	LPUNKNOWN *objPtr;

	riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
	memset(riPtr, 0, sizeof(RegisteredInterp));
	riPtr->interp = interp;

	objPtr = &riPtr->obj;
	hr = TkWinSendCom_CreateInstance(interp, &IID_IUnknown,
		(void **) objPtr);

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS
    (void)interp;
    (void)tkwin;
    /*
     * Temporarily disabled for bug #858822
     */

    return TCL_OK;
#else /* TK_SEND_ENABLED_ON_WINDOWS */








<
<







215
216
217
218
219
220
221


222
223
224
225
226
227
228
int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS


    /*
     * Temporarily disabled for bug #858822
     */

    return TCL_OK;
#else /* TK_SEND_ENABLED_ON_WINDOWS */

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
			IMalloc *pMalloc = NULL;

			if (wcsncmp(olestr, oleszStub,
				wcslen(oleszStub)) == 0) {
			    LPOLESTR p = olestr + wcslen(oleszStub);

			    if (*p) {
				Tcl_DString ds;

				Tcl_DStringInit(&ds);
				Tcl_WCharToUtfDString(p + 1, wcslen(p + 1), &ds);
				result = Tcl_ListObjAppendElement(interp,
					objList,
					Tcl_NewStringObj(Tcl_DStringValue(&ds),
						Tcl_DStringLength(&ds)));
				Tcl_DStringFree(&ds);
			    }
			}

			hr = CoGetMalloc(1, &pMalloc);
			if (SUCCEEDED(hr)) {
			    pMalloc->lpVtbl->Free(pMalloc, (void*)olestr);
			    pMalloc->lpVtbl->Release(pMalloc);







<
<
<
<

|
<
<
<







254
255
256
257
258
259
260




261
262



263
264
265
266
267
268
269
			IMalloc *pMalloc = NULL;

			if (wcsncmp(olestr, oleszStub,
				wcslen(oleszStub)) == 0) {
			    LPOLESTR p = olestr + wcslen(oleszStub);

			    if (*p) {




				result = Tcl_ListObjAppendElement(interp,
					objList, Tcl_NewUnicodeObj(p + 1, -1));



			    }
			}

			hr = CoGetMalloc(1, &pMalloc);
			if (SUCCEEDED(hr)) {
			    pMalloc->lpVtbl->Free(pMalloc, (void*)olestr);
			    pMalloc->lpVtbl->Release(pMalloc);
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
	/*
	 * Expire the list if set.
	 */

	if (objList != NULL) {
	    Tcl_DecrRefCount(objList);
	}
	Tcl_SetObjResult(interp, TkWin32ErrorObj(hr));
	result = TCL_ERROR;
    }

    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objList);
    }








|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
	/*
	 * Expire the list if set.
	 */

	if (objList != NULL) {
	    Tcl_DecrRefCount(objList);
	}
	Tcl_SetObjResult(interp, Win32ErrorObj(hr));
	result = TCL_ERROR;
    }

    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objList);
    }

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    int result = TCL_OK;
    int i, optind, async = 0;
    Tcl_Obj *displayPtr = NULL;

    /*
     * Process the command options.
     */

    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		sizeof(char *), "option", 0, &optind) != TCL_OK) {
	    break;
	}
	if (optind == SEND_ASYNC) {
	    ++async;
	} else if (optind == SEND_DISPLAYOF) {
	    displayPtr = objv[++i];
	} else if (optind == SEND_LAST) {







|











|
|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    int result = TCL_OK;
    int i, optind, async = 0;
    Tcl_Obj *displayPtr = NULL;

    /*
     * Process the command options.
     */

    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObj(interp, objv[i], sendOptions,
		"option", 0, &optind) != TCL_OK) {
	    break;
	}
	if (optind == SEND_ASYNC) {
	    ++async;
	} else if (optind == SEND_DISPLAYOF) {
	    displayPtr = objv[++i];
	} else if (optind == SEND_LAST) {
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    }

    /*
     * We don't support displayPtr. See TIP #150.
     */

    if (displayPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"option not implemented: \"displayof\" is not available"
		" for this platform.", -1));
	Tcl_SetErrorCode(interp, "TK", "SEND", "DISPLAYOF_WIN", NULL);
	result = TCL_ERROR;
    }

    /*
     * Send the arguments to the foreign interp.
     */
    /* FIX ME: we need to check for local interp */
    if (result == TCL_OK) {
	LPDISPATCH pdisp;

	result = FindInterpreterObject(interp, Tcl_GetString(objv[i]), &pdisp);
	if (result == TCL_OK) {
	    i++;
	    result = Send(pdisp, interp, async, clientData, objc-i, objv+i);
	    pdisp->lpVtbl->Release(pdisp);
	}
    }







|
|
|
<









<







363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
    }

    /*
     * We don't support displayPtr. See TIP #150.
     */

    if (displayPtr) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp),
		"option not implemented: \"displayof\" is not available "
		"for this platform.", -1);

	result = TCL_ERROR;
    }

    /*
     * Send the arguments to the foreign interp.
     */
    /* FIX ME: we need to check for local interp */
    if (result == TCL_OK) {
	LPDISPATCH pdisp;

	result = FindInterpreterObject(interp, Tcl_GetString(objv[i]), &pdisp);
	if (result == TCL_OK) {
	    i++;
	    result = Send(pdisp, interp, async, clientData, objc-i, objv+i);
	    pdisp->lpVtbl->Release(pdisp);
	}
    }
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
			&IID_IUnknown, (void **) ppUnkInterp);
		if (SUCCEEDED(hr)) {
		    hr = pUnkInterp->lpVtbl->QueryInterface(pUnkInterp,
			    &IID_IDispatch, (void **) ppdisp);
		    pUnkInterp->lpVtbl->Release(pUnkInterp);

		} else {

		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "no application named \"%s\"", name));
		    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "APPLICATION",
			    NULL);
		    result = TCL_ERROR;
		}

		pmk->lpVtbl->Release(pmk);
	    }
	    pBindCtx->lpVtbl->Release(pBindCtx);
	}
	pROT->lpVtbl->Release(pROT);
    }
    if (FAILED(hr) && result == TCL_OK) {
	Tcl_SetObjResult(interp, TkWin32ErrorObj(hr));
	result = TCL_ERROR;
    }
    return result;
}

/*
 *--------------------------------------------------------------







>
|
|
<
<










|







436
437
438
439
440
441
442
443
444
445


446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
			&IID_IUnknown, (void **) ppUnkInterp);
		if (SUCCEEDED(hr)) {
		    hr = pUnkInterp->lpVtbl->QueryInterface(pUnkInterp,
			    &IID_IDispatch, (void **) ppdisp);
		    pUnkInterp->lpVtbl->Release(pUnkInterp);

		} else {
		    Tcl_ResetResult(interp);
		    Tcl_AppendResult(interp,
			    "no application named \"", name, "\"", NULL);


		    result = TCL_ERROR;
		}

		pmk->lpVtbl->Release(pmk);
	    }
	    pBindCtx->lpVtbl->Release(pBindCtx);
	}
	pROT->lpVtbl->Release(pROT);
    }
    if (FAILED(hr) && result == TCL_OK) {
	Tcl_SetObjResult(interp, Win32ErrorObj(hr));
	result = TCL_ERROR;
    }
    return result;
}

/*
 *--------------------------------------------------------------
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
     */

    if (riPtr->name != NULL) {
	free(riPtr->name);
	riPtr->name = NULL;
    }
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *
 * InterpDeleteProc --
 *
 *	This is called when the interpreter is deleted and used to unregister







|







553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
     */

    if (riPtr->name != NULL) {
	free(riPtr->name);
	riPtr->name = NULL;
    }
}
#endif

/*
 * ----------------------------------------------------------------------
 *
 * InterpDeleteProc --
 *
 *	This is called when the interpreter is deleted and used to unregister
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
static void
InterpDeleteProc(
    ClientData clientData,
    Tcl_Interp *interp)
{
    CoUninitialize();
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *
 * BuildMoniker --
 *
 *	Construct a moniker from the given name. This ensures that all our







|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
static void
InterpDeleteProc(
    ClientData clientData,
    Tcl_Interp *interp)
{
    CoUninitialize();
}
#endif

/*
 * ----------------------------------------------------------------------
 *
 * BuildMoniker --
 *
 *	Construct a moniker from the given name. This ensures that all our
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass);

    if (SUCCEEDED(hr)) {
	LPMONIKER pmkItem = NULL;
	Tcl_DString dString;

	Tcl_DStringInit(&dString);
	Tcl_UtfToWCharDString(name, -1, &dString);
	hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem);
	Tcl_DStringFree(&dString);
	if (SUCCEEDED(hr)) {
	    hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk);
	    pmkItem->lpVtbl->Release(pmkItem);
	}
	pmkClass->lpVtbl->Release(pmkClass);







|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
    HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass);

    if (SUCCEEDED(hr)) {
	LPMONIKER pmkItem = NULL;
	Tcl_DString dString;

	Tcl_DStringInit(&dString);
	Tcl_UtfToUniCharDString(name, -1, &dString);
	hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem);
	Tcl_DStringFree(&dString);
	if (SUCCEEDED(hr)) {
	    hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk);
	    pmkItem->lpVtbl->Release(pmkItem);
	}
	pmkClass->lpVtbl->Release(pmkClass);
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
    if (SUCCEEDED(hr)) {
	riPtr->name = strdup(actualName);
    }

    Tcl_DStringFree(&dString);
    return hr;
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *
 * Send --
 *
 *	Perform an interface call to the server object. We convert the Tcl







|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    if (SUCCEEDED(hr)) {
	riPtr->name = strdup(actualName);
    }

    Tcl_DStringFree(&dString);
    return hr;
}
#endif

/*
 * ----------------------------------------------------------------------
 *
 * Send --
 *
 *	Perform an interface call to the server object. We convert the Tcl
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

810
811
812
813
814

815

816

817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833












834






































835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854

855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874

875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

899
900

901
902
903
904
905


906
907
908
909
910
911
912

static int
Send(
    LPDISPATCH pdispInterp,	/* Pointer to the remote interp's COM
				 * object. */
    Tcl_Interp *interp,		/* The local interpreter. */
    int async,			/* Flag for the calling style. */
    ClientData dummy,	/* The RegisteredInterp structure for this
				 * interp. */
    int objc,			/* Number of arguments to be sent. */
    Tcl_Obj *const objv[])	/* The arguments to be sent. */
{
    VARIANT vCmd, vResult;
    DISPPARAMS dp;
    EXCEPINFO ei;
    UINT uiErr = 0;
    HRESULT hr = S_OK, ehr = S_OK;
    Tcl_Obj *cmd = NULL;
    DISPID dispid;
    Tcl_DString ds;
    const char *src;
    (void)dummy;

    cmd = Tcl_ConcatObj(objc, objv);

    /*
     * Setup the arguments for the COM method call.
     */

    VariantInit(&vCmd);
    VariantInit(&vResult);
    memset(&dp, 0, sizeof(dp));
    memset(&ei, 0, sizeof(ei));

    vCmd.vt = VT_BSTR;
    src = Tcl_GetString(cmd);
    Tcl_DStringInit(&ds);
    vCmd.bstrVal = SysAllocString(Tcl_UtfToWCharDString(src, cmd->length, &ds));
    Tcl_DStringFree(&ds);

    dp.cArgs = 1;
    dp.rgvarg = &vCmd;

    /*
     * Select the method to use based upon the async flag and call the method.
     */

    dispid = async ? TKWINSENDCOM_DISPID_ASYNC : TKWINSENDCOM_DISPID_SEND;

    hr = pdispInterp->lpVtbl->Invoke(pdispInterp, dispid,
	    &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
	    &dp, &vResult, &ei, &uiErr);

    /*
     * Convert the result into a string and place in the interps result.
     */

    ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR);
    if (SUCCEEDED(ehr)) {
	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(vResult.bstrVal, SysStringLen(vResult.bstrVal), &ds);
	Tcl_DStringResult(interp, &ds);
    }

    /*
     * Errors are returned as dispatch exceptions. If an error code was
     * returned then we decode the exception and setup the Tcl error
     * variables.
     */

    if (hr == DISP_E_EXCEPTION && ei.bstrSource != NULL) {
	Tcl_Obj *opError, *opErrorCode, *opErrorInfo;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(ei.bstrSource, SysStringLen(ei.bstrSource), &ds);

	opError = Tcl_NewStringObj(Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
	Tcl_ListObjIndex(interp, opError, 0, &opErrorCode);
	Tcl_SetObjErrorCode(interp, opErrorCode);

	Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo);

	Tcl_AppendObjToErrorInfo(interp, opErrorInfo);

    }

    /*
     * Clean up any COM allocated resources.
     */

    SysFreeString(ei.bstrDescription);
    SysFreeString(ei.bstrSource);
    SysFreeString(ei.bstrHelpFile);
    VariantClear(&vCmd);

    return (SUCCEEDED(hr) ? TCL_OK : TCL_ERROR);
}

/*
 * ----------------------------------------------------------------------
 *












 * TkWinSend_SetExcepInfo --






































 *
 *	Convert the error information from a Tcl interpreter into a COM
 *	exception structure. This information is then registered with the COM
 *	thread exception object so that it can be used for rich error
 *	reporting by COM clients.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The current COM thread has its error object modified.
 *
 * ----------------------------------------------------------------------
 */

void
TkWinSend_SetExcepInfo(
    Tcl_Interp *interp,
    EXCEPINFO *pExcepInfo)
{

    Tcl_Obj *opError, *opErrorInfo, *opErrorCode;
    ICreateErrorInfo *pCEI;
    IErrorInfo *pEI, **ppEI = &pEI;
    HRESULT hr;
    Tcl_DString ds;
    const char *src;

    if (!pExcepInfo) {
	return;
    }

    opError = Tcl_GetObjResult(interp);
    opErrorInfo = Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
    opErrorCode = Tcl_GetVar2Ex(interp, "errorCode", NULL, TCL_GLOBAL_ONLY);

    /*
     * Pack the trace onto the end of the Tcl exception descriptor.
     */

    opErrorCode = Tcl_DuplicateObj(opErrorCode);

    Tcl_IncrRefCount(opErrorCode);

    Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo);
    /* TODO: Handle failure to append */

    src = Tcl_GetString(opError);
    Tcl_DStringInit(&ds);
    pExcepInfo->bstrDescription =
	    SysAllocString(Tcl_UtfToWCharDString(src, opError->length, &ds));
    Tcl_DStringFree(&ds);
    src = Tcl_GetString(opErrorCode);
    Tcl_DStringInit(&ds);
    pExcepInfo->bstrSource =
	    SysAllocString(Tcl_UtfToWCharDString(src, opErrorCode->length, &ds));
    Tcl_DStringFree(&ds);
    Tcl_DecrRefCount(opErrorCode);
    pExcepInfo->scode = E_FAIL;

    hr = CreateErrorInfo(&pCEI);
    if (!SUCCEEDED(hr)) {
	return;
    }

    hr = pCEI->lpVtbl->SetGUID(pCEI, &IID_IDispatch);
    hr = pCEI->lpVtbl->SetDescription(pCEI, pExcepInfo->bstrDescription);

    hr = pCEI->lpVtbl->SetSource(pCEI, pExcepInfo->bstrSource);
    hr = pCEI->lpVtbl->QueryInterface(pCEI, &IID_IErrorInfo, (void **) ppEI);

    if (SUCCEEDED(hr)) {
	SetErrorInfo(0, pEI);
	pEI->lpVtbl->Release(pEI);
    }
    pCEI->lpVtbl->Release(pCEI);


}

/*
 * ----------------------------------------------------------------------
 *
 * TkWinSend_QueueCommand --
 *







|











<
<
<













<
<
|
<




















<
<
|








|


<
|
>
|
|
|
|
|
>
|
>
|
>

















>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















|
|


>
|
|
|
|
<
<

<
<
<
<
|
|
|

<
<
<
|
|
>
|
>
|
<
|
|
|
|
<
<
<
<
|
<
<
<
|

|
|
<
<
<
|
|
>
|
|
>
|
|
|
|
|
>
>







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745



746
747
748
749
750
751
752
753
754
755
756
757
758


759

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779


780
781
782
783
784
785
786
787
788
789
790
791

792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896


897




898
899
900
901



902
903
904
905
906
907

908
909
910
911




912



913
914
915
916



917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936

static int
Send(
    LPDISPATCH pdispInterp,	/* Pointer to the remote interp's COM
				 * object. */
    Tcl_Interp *interp,		/* The local interpreter. */
    int async,			/* Flag for the calling style. */
    ClientData clientData,	/* The RegisteredInterp structure for this
				 * interp. */
    int objc,			/* Number of arguments to be sent. */
    Tcl_Obj *const objv[])	/* The arguments to be sent. */
{
    VARIANT vCmd, vResult;
    DISPPARAMS dp;
    EXCEPINFO ei;
    UINT uiErr = 0;
    HRESULT hr = S_OK, ehr = S_OK;
    Tcl_Obj *cmd = NULL;
    DISPID dispid;




    cmd = Tcl_ConcatObj(objc, objv);

    /*
     * Setup the arguments for the COM method call.
     */

    VariantInit(&vCmd);
    VariantInit(&vResult);
    memset(&dp, 0, sizeof(dp));
    memset(&ei, 0, sizeof(ei));

    vCmd.vt = VT_BSTR;


    vCmd.bstrVal = SysAllocString(Tcl_GetUnicode(cmd));


    dp.cArgs = 1;
    dp.rgvarg = &vCmd;

    /*
     * Select the method to use based upon the async flag and call the method.
     */

    dispid = async ? TKWINSENDCOM_DISPID_ASYNC : TKWINSENDCOM_DISPID_SEND;

    hr = pdispInterp->lpVtbl->Invoke(pdispInterp, dispid,
	    &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
	    &dp, &vResult, &ei, &uiErr);

    /*
     * Convert the result into a string and place in the interps result.
     */

    ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR);
    if (SUCCEEDED(ehr)) {


	Tcl_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1));
    }

    /*
     * Errors are returned as dispatch exceptions. If an error code was
     * returned then we decode the exception and setup the Tcl error
     * variables.
     */

    if (hr == DISP_E_EXCEPTION) {
	Tcl_Obj *opError, *opErrorCode, *opErrorInfo;


	if (ei.bstrSource != NULL) {
	    int len;
	    char *szErrorInfo;

	    opError = Tcl_NewUnicodeObj(ei.bstrSource, -1);
	    Tcl_ListObjIndex(interp, opError, 0, &opErrorCode);
	    Tcl_SetObjErrorCode(interp, opErrorCode);

	    Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo);
	    szErrorInfo = Tcl_GetStringFromObj(opErrorInfo, &len);
	    Tcl_AddObjErrorInfo(interp, szErrorInfo, len);
	}
    }

    /*
     * Clean up any COM allocated resources.
     */

    SysFreeString(ei.bstrDescription);
    SysFreeString(ei.bstrSource);
    SysFreeString(ei.bstrHelpFile);
    VariantClear(&vCmd);

    return (SUCCEEDED(hr) ? TCL_OK : TCL_ERROR);
}

/*
 * ----------------------------------------------------------------------
 *
 * Win32ErrorObj --
 *
 *	Returns a string object containing text from a COM or Win32 error code
 *
 * Results:
 *	A Tcl_Obj containing the Win32 error message.
 *
 * Side effects:
 *	Removed the error message from the COM threads error object.
 *
 * ----------------------------------------------------------------------
 */

static Tcl_Obj*
Win32ErrorObj(
    HRESULT hrError)
{
    LPTSTR lpBuffer = NULL, p = NULL;
    TCHAR  sBuffer[30];
    Tcl_Obj* errPtr = NULL;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
	    NULL, (DWORD)hrError, LANG_NEUTRAL,
	    (LPTSTR)&lpBuffer, 0, NULL);

    if (lpBuffer == NULL) {
	lpBuffer = sBuffer;
	wsprintf(sBuffer, TEXT("Error Code: %08lX"), hrError);
    }

    if ((p = _tcsrchr(lpBuffer, TEXT('\r'))) != NULL) {
	*p = TEXT('\0');
    }

#ifdef _UNICODE
    errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer));
#else
    errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer));
#endif

    if (lpBuffer != sBuffer) {
	LocalFree((HLOCAL)lpBuffer);
    }

    return errPtr;
}

/*
 * ----------------------------------------------------------------------
 *
 * SetErrorInfo --
 *
 *	Convert the error information from a Tcl interpreter into a COM
 *	exception structure. This information is then registered with the COM
 *	thread exception object so that it can be used for rich error
 *	reporting by COM clients.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The current COM thread has its error object modified.
 *
 * ----------------------------------------------------------------------
 */

void
SetExcepInfo(
    Tcl_Interp* interp,
    EXCEPINFO *pExcepInfo)
{
    if (pExcepInfo) {
	Tcl_Obj *opError, *opErrorInfo, *opErrorCode;
	ICreateErrorInfo *pCEI;
	IErrorInfo *pEI, **ppEI = &pEI;
	HRESULT hr;







	opError = Tcl_GetObjResult(interp);
	opErrorInfo = Tcl_GetVar2Ex(interp, "errorInfo",NULL, TCL_GLOBAL_ONLY);
	opErrorCode = Tcl_GetVar2Ex(interp, "errorCode",NULL, TCL_GLOBAL_ONLY);




	if (Tcl_IsShared(opErrorCode)) {
	    Tcl_Obj *ec = Tcl_DuplicateObj(opErrorCode);

	    Tcl_IncrRefCount(ec);
	    Tcl_DecrRefCount(opErrorCode);
	    opErrorCode = ec;

	}
	Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo);

	pExcepInfo->bstrDescription = SysAllocString(Tcl_GetUnicode(opError));




	pExcepInfo->bstrSource = SysAllocString(Tcl_GetUnicode(opErrorCode));



	pExcepInfo->scode = E_FAIL;

	hr = CreateErrorInfo(&pCEI);
	if (SUCCEEDED(hr)) {



	    hr = pCEI->lpVtbl->SetGUID(pCEI, &IID_IDispatch);
	    hr = pCEI->lpVtbl->SetDescription(pCEI,
		    pExcepInfo->bstrDescription);
	    hr = pCEI->lpVtbl->SetSource(pCEI, pExcepInfo->bstrSource);
	    hr = pCEI->lpVtbl->QueryInterface(pCEI, &IID_IErrorInfo,
		    (void**) ppEI);
	    if (SUCCEEDED(hr)) {
		SetErrorInfo(0, pEI);
		pEI->lpVtbl->Release(pEI);
	    }
	    pCEI->lpVtbl->Release(pCEI);
	}
    }
}

/*
 * ----------------------------------------------------------------------
 *
 * TkWinSend_QueueCommand --
 *
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

static int
SendEventProc(
    Tcl_Event *eventPtr,
    int flags)
{
    SendEvent *evPtr = (SendEvent *)eventPtr;
    (void)flags;

    TRACE("SendEventProc\n");

    Tcl_EvalObjEx(evPtr->interp, evPtr->cmdPtr,
	    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);

    Tcl_DecrRefCount(evPtr->cmdPtr);







<







993
994
995
996
997
998
999

1000
1001
1002
1003
1004
1005
1006

static int
SendEventProc(
    Tcl_Event *eventPtr,
    int flags)
{
    SendEvent *evPtr = (SendEvent *)eventPtr;


    TRACE("SendEventProc\n");

    Tcl_EvalObjEx(evPtr->interp, evPtr->cmdPtr,
	    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);

    Tcl_DecrRefCount(evPtr->cmdPtr);
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
SendTrace(
    const char *format, ...)
{
    va_list args;
    static char buffer[1024];

    va_start(args, format);
    _vsnprintf(buffer, 1023, format, args);
    OutputDebugStringA(buffer);
    va_end(args);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|










1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
SendTrace(
    const char *format, ...)
{
    va_list args;
    static char buffer[1024];

    va_start(args, format);
    vsnprintf(buffer, 1023, format, args);
    OutputDebugString(buffer);
    va_end(args);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinSendCom.c.

96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125



126
127
128
129
130
131
132
    };
    static ISupportErrorInfoVtbl vtbl2 = {
	ISupportErrorInfo_QueryInterface,
	ISupportErrorInfo_AddRef,
	ISupportErrorInfo_Release,
	ISupportErrorInfo_InterfaceSupportsErrorInfo,
    };

    TkWinSendCom *obj = NULL;

    /*
     * This had probably better always be globally visible memory so we shall
     * use the COM Task allocator.
     */

    obj = (TkWinSendCom *) CoTaskMemAlloc(sizeof(TkWinSendCom));
    if (obj == NULL) {
	*ppv = NULL;
	return E_OUTOFMEMORY;
    }

    obj->lpVtbl = &vtbl;
    obj->lpVtbl2 = &vtbl2;
    obj->refcount = 0;
    obj->interp = interp;

    /*
     * lock the interp? Tcl_AddRef/Retain?
     */

    return obj->lpVtbl->QueryInterface((IDispatch *) obj, riid, ppv);



}

/*
 * ----------------------------------------------------------------------
 *
 * TkWinSendCom_Destroy --
 *







>










|
<
|
|
|
|
|

|
|
|

|
>
>
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    };
    static ISupportErrorInfoVtbl vtbl2 = {
	ISupportErrorInfo_QueryInterface,
	ISupportErrorInfo_AddRef,
	ISupportErrorInfo_Release,
	ISupportErrorInfo_InterfaceSupportsErrorInfo,
    };
    HRESULT hr = S_OK;
    TkWinSendCom *obj = NULL;

    /*
     * This had probably better always be globally visible memory so we shall
     * use the COM Task allocator.
     */

    obj = (TkWinSendCom *) CoTaskMemAlloc(sizeof(TkWinSendCom));
    if (obj == NULL) {
	*ppv = NULL;
	hr = E_OUTOFMEMORY;

    } else {
	obj->lpVtbl = &vtbl;
	obj->lpVtbl2 = &vtbl2;
	obj->refcount = 0;
	obj->interp = interp;

	/*
	 * lock the interp? Tcl_AddRef/Retain?
	 */

	hr = obj->lpVtbl->QueryInterface((IDispatch*)obj, riid, ppv);
    }

    return hr;
}

/*
 * ----------------------------------------------------------------------
 *
 * TkWinSendCom_Destroy --
 *
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 *
 * ----------------------------------------------------------------------
 */
static void
TkWinSendCom_Destroy(
    LPDISPATCH pdisp)
{
    CoTaskMemFree((void *) pdisp);
}

/*
 * ----------------------------------------------------------------------
 *
 * IDispatch --
 *







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
 *
 * ----------------------------------------------------------------------
 */
static void
TkWinSendCom_Destroy(
    LPDISPATCH pdisp)
{
    CoTaskMemFree((void*)pdisp);
}

/*
 * ----------------------------------------------------------------------
 *
 * IDispatch --
 *
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
static STDMETHODIMP
WinSendCom_QueryInterface(
    IDispatch *This,
    REFIID riid,
    void **ppvObject)
{
    HRESULT hr = E_NOINTERFACE;
    TkWinSendCom *sendCom = (TkWinSendCom *) This;
    *ppvObject = NULL;

    if (memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0
	    || memcmp(riid, &IID_IDispatch, sizeof(IID)) == 0) {
	*ppvObject = (void **) sendCom;
	sendCom->lpVtbl->AddRef(This);
	hr = S_OK;
    } else if (memcmp(riid, &IID_ISupportErrorInfo, sizeof(IID)) == 0) {
	*ppvObject = (void **) (sendCom + 1);
	sendCom->lpVtbl2->AddRef((ISupportErrorInfo *) (sendCom + 1));
	hr = S_OK;
    }
    return hr;
}

static STDMETHODIMP_(ULONG)
WinSendCom_AddRef(
    IDispatch *This)
{
    TkWinSendCom *sendCom = (TkWinSendCom*)This;

    return InterlockedIncrement(&sendCom->refcount);
}

static STDMETHODIMP_(ULONG)
WinSendCom_Release(
    IDispatch *This)
{
    long r = 0;
    TkWinSendCom *sendCom = (TkWinSendCom*)This;

    if ((r = InterlockedDecrement(&sendCom->refcount)) == 0) {
	TkWinSendCom_Destroy(This);
    }
    return r;
}

static STDMETHODIMP
WinSendCom_GetTypeInfoCount(
    IDispatch *This,
    UINT *pctinfo)
{
    HRESULT hr = E_POINTER;
    (void)This;

    if (pctinfo != NULL) {
	*pctinfo = 0;
	hr = S_OK;
    }
    return hr;
}

static STDMETHODIMP
WinSendCom_GetTypeInfo(
    IDispatch *This,
    UINT iTInfo,
    LCID lcid,
    ITypeInfo **ppTI)
{
    HRESULT hr = E_POINTER;
    (void)This;
    (void)iTInfo;
    (void)lcid;

    if (ppTI) {
	*ppTI = NULL;
	hr = E_NOTIMPL;
    }
    return hr;
}

static STDMETHODIMP
WinSendCom_GetIDsOfNames(
    IDispatch *This,
    REFIID riid,
    LPOLESTR *rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID *rgDispId)
{
    HRESULT hr = E_POINTER;
    (void)This;
    (void)riid;
    (void)cNames;
    (void)lcid;

    if (rgDispId) {
	hr = DISP_E_UNKNOWNNAME;
	if (_wcsicmp(*rgszNames, L"Send") == 0) {
	    *rgDispId = TKWINSENDCOM_DISPID_SEND, hr = S_OK;
	} else if (_wcsicmp(*rgszNames, L"Async") == 0) {
	    *rgDispId = TKWINSENDCOM_DISPID_ASYNC, hr = S_OK;







|




|
|


|
|









|

|







|

|











<
















<
<
<


















<
<
<
<







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249




250
251
252
253
254
255
256
static STDMETHODIMP
WinSendCom_QueryInterface(
    IDispatch *This,
    REFIID riid,
    void **ppvObject)
{
    HRESULT hr = E_NOINTERFACE;
    TkWinSendCom *this = (TkWinSendCom*)This;
    *ppvObject = NULL;

    if (memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0
	    || memcmp(riid, &IID_IDispatch, sizeof(IID)) == 0) {
	*ppvObject = (void**)this;
	this->lpVtbl->AddRef(This);
	hr = S_OK;
    } else if (memcmp(riid, &IID_ISupportErrorInfo, sizeof(IID)) == 0) {
	*ppvObject = (void**)(this + 1);
	this->lpVtbl2->AddRef((ISupportErrorInfo*)(this + 1));
	hr = S_OK;
    }
    return hr;
}

static STDMETHODIMP_(ULONG)
WinSendCom_AddRef(
    IDispatch *This)
{
    TkWinSendCom *this = (TkWinSendCom*)This;

    return InterlockedIncrement(&this->refcount);
}

static STDMETHODIMP_(ULONG)
WinSendCom_Release(
    IDispatch *This)
{
    long r = 0;
    TkWinSendCom *this = (TkWinSendCom*)This;

    if ((r = InterlockedDecrement(&this->refcount)) == 0) {
	TkWinSendCom_Destroy(This);
    }
    return r;
}

static STDMETHODIMP
WinSendCom_GetTypeInfoCount(
    IDispatch *This,
    UINT *pctinfo)
{
    HRESULT hr = E_POINTER;


    if (pctinfo != NULL) {
	*pctinfo = 0;
	hr = S_OK;
    }
    return hr;
}

static STDMETHODIMP
WinSendCom_GetTypeInfo(
    IDispatch *This,
    UINT iTInfo,
    LCID lcid,
    ITypeInfo **ppTI)
{
    HRESULT hr = E_POINTER;




    if (ppTI) {
	*ppTI = NULL;
	hr = E_NOTIMPL;
    }
    return hr;
}

static STDMETHODIMP
WinSendCom_GetIDsOfNames(
    IDispatch *This,
    REFIID riid,
    LPOLESTR *rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID *rgDispId)
{
    HRESULT hr = E_POINTER;





    if (rgDispId) {
	hr = DISP_E_UNKNOWNNAME;
	if (_wcsicmp(*rgszNames, L"Send") == 0) {
	    *rgDispId = TKWINSENDCOM_DISPID_SEND, hr = S_OK;
	} else if (_wcsicmp(*rgszNames, L"Async") == 0) {
	    *rgDispId = TKWINSENDCOM_DISPID_ASYNC, hr = S_OK;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    WORD wFlags,
    DISPPARAMS *pDispParams,
    VARIANT *pvarResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = DISP_E_MEMBERNOTFOUND;
    TkWinSendCom *sendCom = (TkWinSendCom*)This;
    (void)riid;
    (void)lcid;

    switch (dispidMember) {
    case TKWINSENDCOM_DISPID_SEND:
	if (wFlags | DISPATCH_METHOD) {
	    if (pDispParams->cArgs != 1) {
		hr = DISP_E_BADPARAMCOUNT;
	    } else {
		hr = Send(sendCom, pDispParams->rgvarg[0], pvarResult,
			pExcepInfo, puArgErr);
	    }
	}
	break;

    case TKWINSENDCOM_DISPID_ASYNC:
	if (wFlags | DISPATCH_METHOD) {
	    if (pDispParams->cArgs != 1) {
		hr = DISP_E_BADPARAMCOUNT;
	    } else {
		hr = Async(sendCom, pDispParams->rgvarg[0], pExcepInfo, puArgErr);
	    }
	}
	break;
    }
    return hr;
}








|
<
<







|










|







268
269
270
271
272
273
274
275


276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
    WORD wFlags,
    DISPPARAMS *pDispParams,
    VARIANT *pvarResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = DISP_E_MEMBERNOTFOUND;
    TkWinSendCom *this = (TkWinSendCom*)This;



    switch (dispidMember) {
    case TKWINSENDCOM_DISPID_SEND:
	if (wFlags | DISPATCH_METHOD) {
	    if (pDispParams->cArgs != 1) {
		hr = DISP_E_BADPARAMCOUNT;
	    } else {
		hr = Send(this, pDispParams->rgvarg[0], pvarResult,
			pExcepInfo, puArgErr);
	    }
	}
	break;

    case TKWINSENDCOM_DISPID_ASYNC:
	if (wFlags | DISPATCH_METHOD) {
	    if (pDispParams->cArgs != 1) {
		hr = DISP_E_BADPARAMCOUNT;
	    } else {
		hr = Async(this, pDispParams->rgvarg[0], pExcepInfo, puArgErr);
	    }
	}
	break;
    }
    return hr;
}

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

static STDMETHODIMP
ISupportErrorInfo_QueryInterface(
    ISupportErrorInfo *This,
    REFIID riid,
    void **ppvObject)
{
    TkWinSendCom *sendCom = (TkWinSendCom *)(This - 1);

    return sendCom->lpVtbl->QueryInterface((IDispatch *) sendCom, riid, ppvObject);
}

static STDMETHODIMP_(ULONG)
ISupportErrorInfo_AddRef(
    ISupportErrorInfo *This)
{
    TkWinSendCom *sendCom = (TkWinSendCom *)(This - 1);

    return InterlockedIncrement(&sendCom->refcount);
}

static STDMETHODIMP_(ULONG)
ISupportErrorInfo_Release(
    ISupportErrorInfo *This)
{
    TkWinSendCom *sendCom = (TkWinSendCom *)(This - 1);

    return sendCom->lpVtbl->Release((IDispatch *) sendCom);
}

static STDMETHODIMP
ISupportErrorInfo_InterfaceSupportsErrorInfo(
    ISupportErrorInfo *This,
    REFIID riid)
{
    (void)This;
    (void)riid;

    /*TkWinSendCom *sendCom = (TkWinSendCom*)(This - 1);*/
    return S_OK; /* or S_FALSE */
}

/*
 * ----------------------------------------------------------------------
 *
 * Async --







|

|






|

|






|

|







<
<
<
|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346



347
348
349
350
351
352
353
354

static STDMETHODIMP
ISupportErrorInfo_QueryInterface(
    ISupportErrorInfo *This,
    REFIID riid,
    void **ppvObject)
{
    TkWinSendCom *this = (TkWinSendCom*)(This - 1);

    return this->lpVtbl->QueryInterface((IDispatch*)this, riid, ppvObject);
}

static STDMETHODIMP_(ULONG)
ISupportErrorInfo_AddRef(
    ISupportErrorInfo *This)
{
    TkWinSendCom *this = (TkWinSendCom*)(This - 1);

    return InterlockedIncrement(&this->refcount);
}

static STDMETHODIMP_(ULONG)
ISupportErrorInfo_Release(
    ISupportErrorInfo *This)
{
    TkWinSendCom *this = (TkWinSendCom*)(This - 1);

    return this->lpVtbl->Release((IDispatch*)this);
}

static STDMETHODIMP
ISupportErrorInfo_InterfaceSupportsErrorInfo(
    ISupportErrorInfo *This,
    REFIID riid)
{



    /*TkWinSendCom *this = (TkWinSendCom*)(This - 1);*/
    return S_OK; /* or S_FALSE */
}

/*
 * ----------------------------------------------------------------------
 *
 * Async --
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407

408
409
410

411
412
413
414
415
416
417
    TkWinSendCom *obj,
    VARIANT Cmd,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    VARIANT vCmd;
    Tcl_DString ds;
    (void)puArgErr;

    VariantInit(&vCmd);

    hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR);
    if (FAILED(hr)) {
	Tcl_SetObjResult(obj->interp, Tcl_NewStringObj(
		"invalid args: Async(command)", -1));
	TkWinSend_SetExcepInfo(obj->interp, pExcepInfo);
	hr = DISP_E_EXCEPTION;
    }

    if (SUCCEEDED(hr) && obj->interp) {

	Tcl_Obj *scriptPtr;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(vCmd.bstrVal, SysStringLen(vCmd.bstrVal), &ds);
	scriptPtr =
		Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
	TkWinSend_QueueCommand(obj->interp, scriptPtr);

    }

    VariantClear(&vCmd);

    return hr;
}

/*
 * ----------------------------------------------------------------------
 *
 * Send --







<
<





|
|
|



|
>
|
<
<
|
<
<
<
|
>



>







369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384
385
386
387
388
389


390



391
392
393
394
395
396
397
398
399
400
401
402
403
    TkWinSendCom *obj,
    VARIANT Cmd,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    VARIANT vCmd;



    VariantInit(&vCmd);

    hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR);
    if (FAILED(hr)) {
	Tcl_SetStringObj(Tcl_GetObjResult(obj->interp),
		"invalid args: Async(command)", -1);
	SetExcepInfo(obj->interp, pExcepInfo);
	hr = DISP_E_EXCEPTION;
    }

    if (SUCCEEDED(hr)) {
	if (obj->interp) {
	    Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(vCmd.bstrVal,


		    (int)SysStringLen(vCmd.bstrVal));



	    TkWinSend_QueueCommand(obj->interp, scriptPtr);
	}
    }

    VariantClear(&vCmd);

    return hr;
}

/*
 * ----------------------------------------------------------------------
 *
 * Send --
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484

485
486
487
488
489
490
491
492
493
494
 *	The interpreters state and result will be modified.
 *
 * ----------------------------------------------------------------------
 */

static HRESULT
Send(
    TkWinSendCom *comobj,
    VARIANT vCmd,
    VARIANT *pvResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    int result = TCL_OK;
    VARIANT v;
    Tcl_Interp *interp = comobj->interp;
    Tcl_Obj *scriptPtr;
    Tcl_DString ds;
    (void)puArgErr;

    if (interp == NULL) {
	return S_OK;
    }
    VariantInit(&v);
    hr = VariantChangeType(&v, &vCmd, 0, VT_BSTR);
    if (!SUCCEEDED(hr)) {
	return hr;
    }

    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(v.bstrVal, SysStringLen(v.bstrVal), &ds);
    scriptPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    Tcl_Preserve(interp);
    Tcl_IncrRefCount(scriptPtr);
    result = Tcl_EvalObjEx(interp, scriptPtr,
	    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(scriptPtr);
    if (pvResult != NULL) {
	Tcl_Obj *obj;
	const char *src;

	VariantInit(pvResult);
	pvResult->vt = VT_BSTR;
	obj = Tcl_GetObjResult(interp);
	src = Tcl_GetString(obj);
	Tcl_DStringInit(&ds);
	pvResult->bstrVal = SysAllocString(Tcl_UtfToWCharDString(src, obj->length, &ds));
	Tcl_DStringFree(&ds);
    }
    if (result == TCL_ERROR) {
	hr = DISP_E_EXCEPTION;
	TkWinSend_SetExcepInfo(interp, pExcepInfo);
    }
    Tcl_Release(interp);

    VariantClear(&v);

    return hr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|








<
<
<
<

<
<
<


|
<
<
|
|
|
|
<
<
<
|
|
<
|
<
<
<
|
|
<
<
<
|
|
|
|
|
|
|
<
>
|
>










414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429




430



431
432
433


434
435
436
437



438
439

440



441
442



443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
 *	The interpreters state and result will be modified.
 *
 * ----------------------------------------------------------------------
 */

static HRESULT
Send(
    TkWinSendCom *obj,
    VARIANT vCmd,
    VARIANT *pvResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    int result = TCL_OK;
    VARIANT v;








    VariantInit(&v);
    hr = VariantChangeType(&v, &vCmd, 0, VT_BSTR);
    if (SUCCEEDED(hr)) {


	if (obj->interp) {
	    Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(v.bstrVal,
		    (int)SysStringLen(v.bstrVal));




	    result = Tcl_EvalObjEx(obj->interp, scriptPtr,
		    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);

	    if (pvResult) {



		VariantInit(pvResult);
		pvResult->vt = VT_BSTR;



		pvResult->bstrVal = SysAllocString(
			Tcl_GetUnicode(Tcl_GetObjResult(obj->interp)));
	    }
	    if (result == TCL_ERROR) {
		hr = DISP_E_EXCEPTION;
		SetExcepInfo(obj->interp, pExcepInfo);
	    }

	}
	VariantClear(&v);
    }
    return hr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinSendCom.h.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define TKWINSENDCOM_DISPID_SEND   1
#define TKWINSENDCOM_DISPID_ASYNC  2

/*
 * TkWinSendCom public functions
 */

MODULE_SCOPE HRESULT    TkWinSendCom_CreateInstance(Tcl_Interp *interp,
                            REFIID riid, void **ppv);
MODULE_SCOPE int        TkWinSend_QueueCommand(Tcl_Interp *interp,
                            Tcl_Obj *cmdPtr);
MODULE_SCOPE void       TkWinSend_SetExcepInfo(Tcl_Interp *interp,
                            EXCEPINFO *pExcepInfo);

#endif /* _tkWinSendCom_h_INCLUDE */

/*
 * Local Variables:
 * mode: c







|

|

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define TKWINSENDCOM_DISPID_SEND   1
#define TKWINSENDCOM_DISPID_ASYNC  2

/*
 * TkWinSendCom public functions
 */

HRESULT                 TkWinSendCom_CreateInstance(Tcl_Interp *interp,
                            REFIID riid, void **ppv);
int                     TkWinSend_QueueCommand(Tcl_Interp *interp,
                            Tcl_Obj *cmdPtr);
void                    SetExcepInfo(Tcl_Interp *interp,
                            EXCEPINFO *pExcepInfo);

#endif /* _tkWinSendCom_h_INCLUDE */

/*
 * Local Variables:
 * mode: c

Changes to win/tkWinTest.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 * Copyright (c) 2000 by Scriptics Corporation.
 * Copyright (c) 2001 by ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#undef USE_TCL_STUBS
#define USE_TCL_STUBS
#undef USE_TK_STUBS
#define USE_TK_STUBS
#include "tkWinInt.h"

HWND tkWinCurrentDialog;

/*
 * Forward declarations of functions defined later in this file:
 */

static int		TestclipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwineventObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestfindwindowObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestgetwindowinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwinlocaleObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static Tk_GetSelProc		SetSelectionResult;

/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for Windows







<
<
<
<











|
|
<









|







8
9
10
11
12
13
14




15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 * Copyright (c) 2000 by Scriptics Corporation.
 * Copyright (c) 2001 by ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */





#include "tkWinInt.h"

HWND tkWinCurrentDialog;

/*
 * Forward declarations of functions defined later in this file:
 */

static int		TestclipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwineventCmd(ClientData clientData,
			    Tcl_Interp *interp, int argc, const char **argv);

static int		TestfindwindowObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestgetwindowinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwinlocaleObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkplatformtestInit(Tcl_Interp *interp);

/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for Windows
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    Tcl_Interp *interp)		/* Interpreter to add commands to. */
{
    /*
     * Add commands for platform specific tests on MacOS here.
     */

    Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwinevent", TestwineventObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfindwindow", TestfindwindowObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testgetwindowinfo", TestgetwindowinfoObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwinlocale", TestwinlocaleObjCmd,
	    Tk_MainWindow(interp), NULL);
    return TCL_OK;
}

struct TestFindControlState {
    int  id;
    HWND control;
};

/* Callback for window enumeration - used for TestFindControl */
BOOL CALLBACK TestFindControlCallback(
    HWND hwnd,
    LPARAM lParam
)
{
    struct TestFindControlState *fcsPtr = (struct TestFindControlState *)lParam;
    fcsPtr->control = GetDlgItem(hwnd, fcsPtr->id);
    /* If we have found the control, return FALSE to stop the enumeration */
    return fcsPtr->control == NULL ? TRUE : FALSE;
}

/*
 * Finds the descendent control window with the specified ID and returns
 * its HWND.
 */
HWND TestFindControl(HWND root, int id)
{
    struct TestFindControlState fcs;

    fcs.control = GetDlgItem(root, id);
    if (fcs.control == NULL) {
        /* Control is not a direct child. Look in descendents */
        fcs.id = id;
        fcs.control = NULL;
        EnumChildWindows(root, TestFindControlCallback, (LPARAM) &fcs);
    }
    return fcs.control;
}


/*
 *----------------------------------------------------------------------
 *
 * AppendSystemError --
 *
 *	This routine formats a Windows system error message and places it into







|
|
|

|

|

|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75




































76
77
78
79
80
81
82
    Tcl_Interp *interp)		/* Interpreter to add commands to. */
{
    /*
     * Add commands for platform specific tests on MacOS here.
     */

    Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateCommand(interp, "testwinevent", TestwineventCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfindwindow", TestfindwindowObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testgetwindowinfo", TestgetwindowinfoObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwinlocale", TestwinlocaleObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    return TCL_OK;
}





































/*
 *----------------------------------------------------------------------
 *
 * AppendSystemError --
 *
 *	This routine formats a Windows system error message and places it into
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181

182
183
184
185
186
187
188
    Tcl_DString ds;
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);

    if (Tcl_IsShared(resultPtr)) {
	resultPtr = Tcl_DuplicateObj(resultPtr);
    }
    length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
	    | FORMAT_MESSAGE_IGNORE_INSERTS
	    | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr,
	    0, NULL);
    if (length == 0) {
	char *msgPtr;

	length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
		| FORMAT_MESSAGE_IGNORE_INSERTS
		| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr,
		0, NULL);
	if (length > 0) {
	    wMsgPtr = (WCHAR *) LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
	    MultiByteToWideChar(CP_ACP, 0, msgPtr, length + 1, wMsgPtr,
		    length + 1);
	    LocalFree(msgPtr);
	}
    }
    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    strcpy(msgBuf, "function not supported under Win32s");
	} else {
	    sprintf(msgBuf, "unknown error: %ld", error);
	}
	msg = msgBuf;
    } else {

	char *msgPtr;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(wMsgPtr, wcslen(wMsgPtr), &ds);

	LocalFree(wMsgPtr);

	msgPtr = Tcl_DStringValue(&ds);
	length = Tcl_DStringLength(&ds);

	/*
	 * Trim the trailing CR/LF from the system message.







<







<


















>


|
|
>







103
104
105
106
107
108
109

110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    Tcl_DString ds;
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);

    if (Tcl_IsShared(resultPtr)) {
	resultPtr = Tcl_DuplicateObj(resultPtr);
    }
    length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM

	    | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr,
	    0, NULL);
    if (length == 0) {
	char *msgPtr;

	length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM

		| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr,
		0, NULL);
	if (length > 0) {
	    wMsgPtr = (WCHAR *) LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
	    MultiByteToWideChar(CP_ACP, 0, msgPtr, length + 1, wMsgPtr,
		    length + 1);
	    LocalFree(msgPtr);
	}
    }
    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    strcpy(msgBuf, "function not supported under Win32s");
	} else {
	    sprintf(msgBuf, "unknown error: %ld", error);
	}
	msg = msgBuf;
    } else {
	Tcl_Encoding encoding;
	char *msgPtr;

	encoding = Tcl_GetEncoding(NULL, "unicode");
	Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds);
	Tcl_FreeEncoding(encoding);
	LocalFree(wMsgPtr);

	msgPtr = Tcl_DStringValue(&ds);
	length = Tcl_DStringLength(&ds);

	/*
	 * Trim the trailing CR/LF from the system message.
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

247

248
249
250
251
252

















253

254




255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539





540
541
542
543
544
545
546
547
548
549
550
551
552
553
554



555
556
557

558

559
560
561
562


563

564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SetSelectionResult(
    ClientData dummy,
    Tcl_Interp *interp,
    const char *selection)
{
    (void)dummy;

    Tcl_AppendResult(interp, selection, NULL);
    return TCL_OK;
}

static int
TestclipboardObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{

    Tk_Window tkwin = (Tk_Window)clientData;


    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }

















    return TkSelGetSelection(interp, tkwin, Tk_InternAtom(tkwin, "CLIPBOARD"),

	    XA_STRING, SetSelectionResult, NULL);




}

/*
 *----------------------------------------------------------------------
 *
 * TestwineventObjCmd --
 *
 *	This function implements the testwinevent command. It provides a way
 *	to send messages to windows dialogs.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwineventObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    HWND hwnd = 0;
    HWND child = 0;
    HWND control;
    int id;
    char *rest;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    LRESULT result;
    static const TkStateMap messageMap[] = {
	{WM_LBUTTONDOWN,	"WM_LBUTTONDOWN"},
	{WM_LBUTTONUP,		"WM_LBUTTONUP"},
	{WM_LBUTTONDBLCLK,		"WM_LBUTTONDBLCLK"},
	{WM_MBUTTONDOWN,	"WM_MBUTTONDOWN"},
	{WM_MBUTTONUP,		"WM_MBUTTONUP"},
	{WM_MBUTTONDBLCLK,		"WM_MBUTTONDBLCLK"},
	{WM_RBUTTONDOWN,	"WM_RBUTTONDOWN"},
	{WM_RBUTTONUP,		"WM_RBUTTONUP"},
	{WM_RBUTTONDBLCLK,		"WM_RBUTTONDBLCLK"},
	{WM_XBUTTONDOWN,	"WM_XBUTTONDOWN"},
	{WM_XBUTTONUP,		"WM_XBUTTONUP"},
	{WM_XBUTTONDBLCLK,		"WM_XBUTTONDBLCLK"},
	{WM_CHAR,		"WM_CHAR"},
	{WM_GETTEXT,		"WM_GETTEXT"},
	{WM_SETTEXT,		"WM_SETTEXT"},
	{WM_COMMAND,            "WM_COMMAND"},
	{-1,			NULL}
    };
    (void)dummy;

    if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]), "debug") == 0)) {
	int b;

	if (Tcl_GetBoolean(interp, Tcl_GetString(objv[2]), &b) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWinDialogDebug(b);
	return TCL_OK;
    }

    if (objc < 4) {
	return TCL_ERROR;
    }

    hwnd = (HWND)INT2PTR(strtol(Tcl_GetString(objv[1]), &rest, 0));
    if (rest == Tcl_GetString(objv[1])) {
	hwnd = FindWindowA(NULL, Tcl_GetString(objv[1]));
	if (hwnd == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("no such window", -1));
	    return TCL_ERROR;
	}
    }
    UpdateWindow(hwnd);

    id = strtol(Tcl_GetString(objv[2]), &rest, 0);
    if (rest == Tcl_GetString(objv[2])) {
	char buf[256];

	child = GetWindow(hwnd, GW_CHILD);
	while (child != NULL) {
	    SendMessageA(child, WM_GETTEXT, (WPARAM) sizeof(buf), (LPARAM) buf);
	    if (strcasecmp(buf, Tcl_GetString(objv[2])) == 0) {
		id = GetDlgCtrlID(child);
		break;
	    }
	    child = GetWindow(child, GW_HWNDNEXT);
	}
	if (child == NULL) {
	    Tcl_AppendResult(interp, "could not find a control matching \"",
		Tcl_GetString(objv[2]), "\"", NULL);
	    return TCL_ERROR;
	}
    }

    message = TkFindStateNum(NULL, NULL, messageMap, Tcl_GetString(objv[3]));
    wParam = 0;
    lParam = 0;

    if (objc > 4) {
	wParam = strtol(Tcl_GetString(objv[4]), NULL, 0);
    }
    if (objc > 5) {
	lParam = strtol(Tcl_GetString(objv[5]), NULL, 0);
    }

    switch (message) {
    case WM_GETTEXT: {
	Tcl_DString ds;
	char buf[256];

#if 0
	GetDlgItemTextA(hwnd, id, buf, 256);
#else
        control = TestFindControl(hwnd, id);
        if (control == NULL) {
            Tcl_SetObjResult(interp,
                             Tcl_ObjPrintf("Could not find control with id %d", id));
            return TCL_ERROR;
        }
        buf[0] = 0;
        SendMessageA(control, WM_GETTEXT, (WPARAM)sizeof(buf),
                     (LPARAM) buf);
#endif
	Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
	Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
	Tcl_DStringFree(&ds);
	break;
    }
    case WM_SETTEXT: {
	Tcl_DString ds;

	control = TestFindControl(hwnd, id);
	if (control == NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_ObjPrintf("Could not find control with id %d", id));
	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[4]), -1, &ds);
	result = SendMessageA(control, WM_SETTEXT, 0,
		(LPARAM) Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
	if (result == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1));
	    AppendSystemError(interp, GetLastError());
	    return TCL_ERROR;
	}
	break;
    }
    case WM_COMMAND: {
	char buf[TCL_INTEGER_SPACE];
	if (objc < 5) {
	    wParam = MAKEWPARAM(id, 0);
	    lParam = (LPARAM)child;
	}
	sprintf(buf, "%d", (int) SendMessageA(hwnd, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
	break;
    }
    default: {
	char buf[TCL_INTEGER_SPACE];

	sprintf(buf, "%d",
		(int) SendDlgItemMessageA(hwnd, id, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
	break;
    }
    }
    return TCL_OK;
}

/*
 *  testfindwindow title ?class?
 *	Find a Windows window using the FindWindow API call. This takes the window
 *	title and optionally the window class and if found returns the HWND and
 *	raises an error if the window is not found.
 *	eg: testfindwindow Console TkTopLevel
 *	    Can find the console window if it is visible.
 *	eg: testfindwindow "TkTest #10201" "#32770"
 *	    Can find a messagebox window with this title.
 */

static int
TestfindwindowObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
	LPCWSTR title = NULL, windowClass = NULL;
    Tcl_DString titleString, classString;
    HWND hwnd = NULL;
    int r = TCL_OK;
    DWORD myPid;
    (void)dummy;

    Tcl_DStringInit(&classString);
    Tcl_DStringInit(&titleString);

    if (objc < 2 || objc > 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "title ?class?");
        return TCL_ERROR;
    }

    Tcl_DStringInit(&titleString);
    title = Tcl_UtfToWCharDString(Tcl_GetString(objv[1]), -1, &titleString);
    if (objc == 3) {
	Tcl_DStringInit(&classString);
	windowClass = Tcl_UtfToWCharDString(Tcl_GetString(objv[2]), -1, &classString);
    }
    if (title[0] == 0)
        title = NULL;
    /* We want find a window the belongs to us and not some other process */
    hwnd = NULL;
    myPid = GetCurrentProcessId();
    while (1) {
        DWORD pid, tid;
        hwnd = FindWindowExW(NULL, hwnd, windowClass, title);
        if (hwnd == NULL)
            break;
        tid = GetWindowThreadProcessId(hwnd, &pid);
        if (tid == 0) {
            /* Window has gone */
            hwnd = NULL;
            break;
        }
        if (pid == myPid)
            break;              /* Found it */
    }

    if (hwnd == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", -1));
	AppendSystemError(interp, GetLastError());
	r = TCL_ERROR;
    } else {
        Tcl_SetObjResult(interp, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    }

    Tcl_DStringFree(&titleString);
    Tcl_DStringFree(&classString);
    return r;

}

static BOOL CALLBACK
EnumChildrenProc(
    HWND hwnd,
    LPARAM lParam)
{
    Tcl_Obj *listObj = (Tcl_Obj *) lParam;

    Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    return TRUE;
}

static int
TestgetwindowinfoObjCmd(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_WideInt hwnd;
    Tcl_Obj *dictObj = NULL, *classObj = NULL, *textObj = NULL;
    Tcl_Obj *childrenObj = NULL;
    WCHAR buf[512];
    int cch, cchBuf = 256;
    Tcl_DString ds;
    (void)dummy;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "hwnd");
	return TCL_ERROR;
    }

    if (Tcl_GetWideIntFromObj(interp, objv[1], &hwnd) != TCL_OK)
	return TCL_ERROR;


    cch = GetClassNameW((HWND)INT2PTR(hwnd), buf, cchBuf);





    if (cch == 0) {
    	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to get class name: ", -1));
    	AppendSystemError(interp, GetLastError());
    	return TCL_ERROR;
    } else {
	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(buf, wcslen(buf), &ds);
	classObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
    }

    dictObj = Tcl_NewDictObj();
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("class", 5), classObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("id", 2),
	Tcl_NewWideIntObj(GetWindowLongPtr((HWND)(size_t)hwnd, GWL_ID)));




    cch = GetWindowTextW((HWND)INT2PTR(hwnd), buf, cchBuf);
	Tcl_DStringInit(&ds);

    Tcl_WCharToUtfDString(buf, cch, &ds);

    textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);

    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj);


    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6),

	Tcl_NewWideIntObj(PTR2INT(GetParent((HWND)(size_t)hwnd))));

    childrenObj = Tcl_NewListObj(0, NULL);
    EnumChildWindows((HWND)(size_t)hwnd, EnumChildrenProc, (LPARAM)childrenObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("children", -1), childrenObj);


    Tcl_SetObjResult(interp, dictObj);
    return TCL_OK;
}

static int
TestwinlocaleObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    (void)dummy;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetThreadLocale()));
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<







>
|
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>





|














|
|

|
|



<





<



<
<
<
<
<
<
<
<
<
<






<

|


|






|



|
|
|

|





|
|




|
|







|



<
|



|
|

|
|







<
|
<
<
<
<
<
<
<
<
<
<
<







|
<
<
<
<
<
|
<
|
<
|


|
|
|





|



|
|






|
|



















|




|
<


<
<
<
<
<





<
<
|
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<






|

<
<
<

<









|





|




|
|

|
|
<
<






|


>
|
>
>
>
>
>

|


<
<
<
<
<


|
|
|
|
>
>
>

|
<
>
|
>
|
<
|
|
>
>
|
>
|


|
|
>

|





|




<
<




|










180
181
182
183
184
185
186












187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258

259
260
261










262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328











329
330
331
332
333
334
335
336





337

338

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390





391
392
393
394
395


396
397

398








399











400
401
402
403
404
405
406
407



408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453





454
455
456
457
458
459
460
461
462
463
464

465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492


493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */













static int
TestclipboardObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    HGLOBAL handle;
    char *data;
    int code = TCL_OK;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    if (OpenClipboard(NULL)) {
	/*
	 * We could consider using CF_UNICODETEXT on NT, but then we
	 * would have to convert it from External.  Instead we'll just
	 * take this and do "bytestring" at the Tcl level for Unicode
	 * inclusive text
	 */
	handle = GetClipboardData(CF_TEXT);
	if (handle != NULL) {
	    data = GlobalLock(handle);
	    Tcl_AppendResult(interp, data, NULL);
	    GlobalUnlock(handle);
	} else {
	    Tcl_AppendResult(interp, "null clipboard handle", NULL);
	    code = TCL_ERROR;
	}
	CloseClipboard();
	return code;
    } else {
	Tcl_AppendResult(interp, "couldn't open clipboard: ", NULL);
	AppendSystemError(interp, GetLastError());
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestwineventCmd --
 *
 *	This function implements the testwinevent command. It provides a way
 *	to send messages to windows dialogs.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwineventCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char **argv)		/* Argument strings. */
{
    HWND hwnd = 0;
    HWND child = 0;

    int id;
    char *rest;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;

    static const TkStateMap messageMap[] = {
	{WM_LBUTTONDOWN,	"WM_LBUTTONDOWN"},
	{WM_LBUTTONUP,		"WM_LBUTTONUP"},










	{WM_CHAR,		"WM_CHAR"},
	{WM_GETTEXT,		"WM_GETTEXT"},
	{WM_SETTEXT,		"WM_SETTEXT"},
	{WM_COMMAND,            "WM_COMMAND"},
	{-1,			NULL}
    };


    if ((argc == 3) && (strcmp(argv[1], "debug") == 0)) {
	int b;

	if (Tcl_GetBoolean(interp, argv[2], &b) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWinDialogDebug(b);
	return TCL_OK;
    }

    if (argc < 4) {
	return TCL_ERROR;
    }

    hwnd = INT2PTR(strtol(argv[1], &rest, 0));
    if (rest == argv[1]) {
	hwnd = FindWindow(NULL, argv[1]);
	if (hwnd == NULL) {
	    Tcl_SetResult(interp, "no such window", TCL_STATIC);
	    return TCL_ERROR;
	}
    }
    UpdateWindow(hwnd);

    id = strtol(argv[2], &rest, 0);
    if (rest == argv[2]) {
	char buf[256];

	child = GetWindow(hwnd, GW_CHILD);
	while (child != NULL) {
	    SendMessage(child, WM_GETTEXT, (WPARAM) sizeof(buf), (LPARAM) buf);
	    if (strcasecmp(buf, argv[2]) == 0) {
		id = GetDlgCtrlID(child);
		break;
	    }
	    child = GetWindow(child, GW_HWNDNEXT);
	}
	if (child == NULL) {
	    Tcl_AppendResult(interp, "could not find a control matching \"",
		argv[2], "\"", NULL);
	    return TCL_ERROR;
	}
    }

    message = TkFindStateNum(NULL, NULL, messageMap, argv[3]);
    wParam = 0;
    lParam = 0;

    if (argc > 4) {
	wParam = strtol(argv[4], NULL, 0);
    }
    if (argc > 5) {
	lParam = strtol(argv[5], NULL, 0);
    }

    switch (message) {
    case WM_GETTEXT: {
	Tcl_DString ds;
	char buf[256];


	GetDlgItemText(hwnd, id, buf, 256);











	Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
	Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
	Tcl_DStringFree(&ds);
	break;
    }
    case WM_SETTEXT: {
	Tcl_DString ds;
	BOOL result;







	Tcl_UtfToExternalDString(NULL, argv[4], -1, &ds);

	result = SetDlgItemText(hwnd, id, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
	if (result == 0) {
    	Tcl_SetResult(interp, "failed to send text to dialog: ", TCL_STATIC);
    	AppendSystemError(interp, GetLastError());
		return TCL_ERROR;
	}
	break;
    }
    case WM_COMMAND: {
	char buf[TCL_INTEGER_SPACE];
	if (argc < 5) {
	    wParam = MAKEWPARAM(id, 0);
	    lParam = (LPARAM)child;
	}
	sprintf(buf, "%d", (int) SendMessage(hwnd, message, wParam, lParam));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    default: {
	char buf[TCL_INTEGER_SPACE];

	sprintf(buf, "%d",
		(int) SendDlgItemMessage(hwnd, id, message, wParam, lParam));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	break;
    }
    }
    return TCL_OK;
}

/*
 *  testfindwindow title ?class?
 *	Find a Windows window using the FindWindow API call. This takes the window
 *	title and optionally the window class and if found returns the HWND and
 *	raises an error if the window is not found.
 *	eg: testfindwindow Console TkTopLevel
 *	    Can find the console window if it is visible.
 *	eg: testfindwindow "TkTest #10201" "#32770"
 *	    Can find a messagebox window with this title.
 */

static int
TestfindwindowObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    const char *title = NULL, *class = NULL;

    HWND hwnd = NULL;
    int r = TCL_OK;






    if (objc < 2 || objc > 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "title ?class?");
        return TCL_ERROR;
    }


    title = Tcl_GetString(objv[1]);
    if (objc == 3)

        class = Tcl_GetString(objv[2]);








    hwnd = FindWindowA(class, title);












    if (hwnd == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", -1));
	AppendSystemError(interp, GetLastError());
	r = TCL_ERROR;
    } else {
        Tcl_SetObjResult(interp, Tcl_NewLongObj(PTR2INT(hwnd)));
    }



    return r;

}

static BOOL CALLBACK
EnumChildrenProc(
    HWND hwnd,
    LPARAM lParam)
{
    Tcl_Obj *listObj = (Tcl_Obj *) lParam;

    Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewLongObj(PTR2INT(hwnd)));
    return TRUE;
}

static int
TestgetwindowinfoObjCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    long hwnd;
    Tcl_Obj *resObj = NULL, *classObj = NULL, *textObj = NULL;
    Tcl_Obj *childrenObj = NULL;
    char buf[512];
    int cch, cchBuf = tkWinProcs->useWide ? 256 : 512;



    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "hwnd");
	return TCL_ERROR;
    }

    if (Tcl_GetLongFromObj(interp, objv[1], &hwnd) != TCL_OK)
	return TCL_ERROR;

    if (tkWinProcs->useWide) {
	cch = GetClassNameW(INT2PTR(hwnd), (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR));
	classObj = Tcl_NewUnicodeObj((LPWSTR)buf, cch);
    } else {
	cch = GetClassNameA(INT2PTR(hwnd), (LPSTR)buf, sizeof(buf));
	classObj = Tcl_NewStringObj((LPSTR)buf, cch);
    }
    if (cch == 0) {
    	Tcl_SetResult(interp, "failed to get class name: ", TCL_STATIC);
    	AppendSystemError(interp, GetLastError());
    	return TCL_ERROR;





    }

    resObj = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("class", -1));
    Tcl_ListObjAppendElement(interp, resObj, classObj);

    Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("id", -1));
    Tcl_ListObjAppendElement(interp, resObj,
	Tcl_NewLongObj(GetWindowLong(INT2PTR(hwnd), GWL_ID)));

    cch = tkWinProcs->getWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf);

    if (tkWinProcs->useWide) {
	textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch);
    } else {
	textObj = Tcl_NewStringObj((LPCSTR)buf, cch);

    }

    Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("text", -1));
    Tcl_ListObjAppendElement(interp, resObj, textObj);
    Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("parent", -1));
    Tcl_ListObjAppendElement(interp, resObj,
	Tcl_NewLongObj(PTR2INT(GetParent(INT2PTR(hwnd)))));

    childrenObj = Tcl_NewListObj(0, NULL);
    EnumChildWindows(INT2PTR(hwnd), EnumChildrenProc, (LPARAM)childrenObj);
    Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("children", -1));
    Tcl_ListObjAppendElement(interp, resObj, childrenObj);

    Tcl_SetObjResult(interp, resObj);
    return TCL_OK;
}

static int
TestwinlocaleObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{


    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewIntObj((int)GetSystemDefaultLCID()));
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinWindow.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkWinWindow.c --
 *
 *	Xlib emulation routines for Windows related to creating, displaying
 *	and destroying windows.
 *
 * Copyright (c) 1995-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.
 */

#include "tkWinInt.h"
#include "tkBusy.h"

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */
    Tcl_HashTable windowTable;  /* The windowTable maps from HWND to Tk_Window
				 * handles. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*













<

|







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
/*
 * tkWinWindow.c --
 *
 *	Xlib emulation routines for Windows related to creating, displaying
 *	and destroying windows.
 *
 * Copyright (c) 1995-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.
 */

#include "tkWinInt.h"


typedef struct ThreadSpecificData {
    int initialized;		/* 0 means table below needs initializing. */
    Tcl_HashTable windowTable;  /* The windowTable maps from HWND to Tk_Window
				 * handles. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 */

Window
Tk_AttachHWND(
    Tk_Window tkwin,
    HWND hwnd)
{
    int isNew;
    Tcl_HashEntry *entryPtr;
    TkWinDrawable *twdPtr = (TkWinDrawable *) Tk_WindowId(tkwin);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
	tsdPtr->initialized = 1;
    }

    /*
     * Allocate a new drawable if necessary. Otherwise, remove the previous
     * HWND from from the window table.
     */

    if (twdPtr == NULL) {
	twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));
	twdPtr->type = TWD_WINDOW;
	twdPtr->window.winPtr = (TkWindow *) tkwin;
    } else if (twdPtr->window.handle != NULL) {
	entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable,
		twdPtr->window.handle);
	Tcl_DeleteHashEntry(entryPtr);
    }

    /*
     * Insert the new HWND into the window table.
     */

    twdPtr->window.handle = hwnd;
    entryPtr = Tcl_CreateHashEntry(&tsdPtr->windowTable, (char *)hwnd, &isNew);
    Tcl_SetHashValue(entryPtr, tkwin);

    return (Window)twdPtr;
}

/*
 *----------------------------------------------------------------------
 *







|
















|




|








|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 */

Window
Tk_AttachHWND(
    Tk_Window tkwin,
    HWND hwnd)
{
    int new;
    Tcl_HashEntry *entryPtr;
    TkWinDrawable *twdPtr = (TkWinDrawable *) Tk_WindowId(tkwin);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
	tsdPtr->initialized = 1;
    }

    /*
     * Allocate a new drawable if necessary. Otherwise, remove the previous
     * HWND from from the window table.
     */

    if (twdPtr == NULL) {
	twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
	twdPtr->type = TWD_WINDOW;
	twdPtr->window.winPtr = (TkWindow *) tkwin;
    } else if (twdPtr->window.handle != NULL) {
	entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable,
		(char *)twdPtr->window.handle);
	Tcl_DeleteHashEntry(entryPtr);
    }

    /*
     * Insert the new HWND into the window table.
     */

    twdPtr->window.handle = hwnd;
    entryPtr = Tcl_CreateHashEntry(&tsdPtr->windowTable, (char *)hwnd, &new);
    Tcl_SetHashValue(entryPtr, (ClientData)tkwin);

    return (Window)twdPtr;
}

/*
 *----------------------------------------------------------------------
 *
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
	tsdPtr->initialized = 1;
    }
    entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, hwnd);
    if (entryPtr != NULL) {
	return (Tk_Window) Tcl_GetHashValue(entryPtr);
    }
    return NULL;
}

/*







|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
	tsdPtr->initialized = 1;
    }
    entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char *) hwnd);
    if (entryPtr != NULL) {
	return (Tk_Window) Tcl_GetHashValue(entryPtr);
    }
    return NULL;
}

/*
166
167
168
169
170
171
172






173


174
175
176
177
178
179
180
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold the
				 * hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    HWND hwnd = (window) ? Tk_GetHWND(window) : 0;







    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);


}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *







>
>
>
>
>
>
|
>
>







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold the
				 * hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    HWND hwnd = (window) ? Tk_GetHWND(window) : 0;

    /*
     * Use pointer representation, because Win64 is P64 (*not* LP64). Windows
     * doesn't print the 0x for %p, so we do it.
     * bug #2026405: cygwin does output 0x for %p so test and recover.
     */

    sprintf(buf, "0x%p", hwnd);
    if (buf[2] == '0' && buf[3] == 'x')
	sprintf(buf, "%p", hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    const char *string,		/* String containing a (possibly signed)
				 * integer in a form acceptable to strtol. */
    Window *idPtr)		/* Place to store converted result. */
{
    Tk_Window tkwin;
    union {
	HWND hwnd;
	int number;
    } win;

    /*
     * We want sscanf for the 64-bit check, but if that doesn't work, then
     * Tcl_GetInt manages the error correctly.
     */

    if (
#ifdef _WIN64
	    (sscanf(string, "0x%p", &win.hwnd) != 1) &&
#endif
	    Tcl_GetInt(interp, string, &win.number) != TCL_OK) {
	return TCL_ERROR;
    }

    tkwin = Tk_HWNDToWindow(win.hwnd);
    if (tkwin) {
	*idPtr = Tk_WindowId(tkwin);
    } else {
	*idPtr = None;
    }
    return TCL_OK;
}







|




<
<
|
<








|

|



|







200
201
202
203
204
205
206
207
208
209
210
211


212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 *
 *----------------------------------------------------------------------
 */

int
TkpScanWindowId(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    CONST char *string,		/* String containing a (possibly signed)
				 * integer in a form acceptable to strtol. */
    Window *idPtr)		/* Place to store converted result. */
{
    Tk_Window tkwin;


    void *number, *numberPtr = &number;


    /*
     * We want sscanf for the 64-bit check, but if that doesn't work, then
     * Tcl_GetInt manages the error correctly.
     */

    if (
#ifdef _WIN64
	    (sscanf(string, "0x%p", &number) != 1) &&
#endif
	    Tcl_GetInt(interp, string, (int *) numberPtr) != TCL_OK) {
	return TCL_ERROR;
    }

    tkwin = Tk_HWNDToWindow((HWND) number);
    if (tkwin) {
	*idPtr = Tk_WindowId(tkwin);
    } else {
	*idPtr = None;
    }
    return TCL_OK;
}
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    }

    /*
     * Create the window, then ensure that it is at the top of the stacking
     * order.
     */

    hwnd = CreateWindowExW(WS_EX_NOPARENTNOTIFY, TK_WIN_CHILD_CLASS_NAME, NULL,
	    (DWORD) style, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr),
	    Tk_Height(winPtr), parentWin, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
	    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    return Tk_AttachHWND((Tk_Window)winPtr, hwnd);
}








|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    }

    /*
     * Create the window, then ensure that it is at the top of the stacking
     * order.
     */

    hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, TK_WIN_CHILD_CLASS_NAME, NULL,
	    (DWORD) style, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr),
	    Tk_Height(winPtr), parentWin, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
	    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    return Tk_AttachHWND((Tk_Window)winPtr, hwnd);
}

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    /*
     * Remove references to the window in the pointer module then release the
     * drawable.
     */

    TkPointerDeadWindow(winPtr);

    entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, hwnd);
    if (entryPtr != NULL) {
	Tcl_DeleteHashEntry(entryPtr);
    }

    ckfree(twdPtr);

    /*
     * Don't bother destroying the window if we are going to destroy the
     * parent later.
     */

    if (hwnd != NULL && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) {







|




|







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
    /*
     * Remove references to the window in the pointer module then release the
     * drawable.
     */

    TkPointerDeadWindow(winPtr);

    entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char*)hwnd);
    if (entryPtr != NULL) {
	Tcl_DeleteHashEntry(entryPtr);
    }

    ckfree((char *)twdPtr);

    /*
     * Don't bother destroying the window if we are going to destroy the
     * parent later.
     */

    if (hwnd != NULL && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) {
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
	    (int)height, TRUE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XRaiseWindow, XLowerWindow --
 *
 *	Change the stacking order of a window.
 *
 * Results:
 *	None.
 *
 * Side effects:







|







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
	    (int)height, TRUE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XRaiseWindow --
 *
 *	Change the stacking order of a window.
 *
 * Results:
 *	None.
 *
 * Side effects:
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

int
XLowerWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XConfigureWindow --
 *
 *	Change the size, position, stacking, or border of the specified







<
<
<
<
<
<
<
<
<
<
<
<







605
606
607
608
609
610
611












612
613
614
615
616
617
618
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}













/*
 *----------------------------------------------------------------------
 *
 * XConfigureWindow --
 *
 *	Change the size, position, stacking, or border of the specified
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0,
	    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpShowBusyWindow --
 *
 *	Makes a busy window "appear".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arranges for the busy window to start intercepting events and the
 *	cursor to change to the configured "hey, I'm busy!" setting.
 *
 *----------------------------------------------------------------------
 */

void
TkpShowBusyWindow(
    TkBusy busy)
{
    Busy *busyPtr = (Busy *) busy;
    HWND hWnd;
    POINT point;
    Display *display;
    Window window;

    if (busyPtr->tkBusy != NULL) {
	Tk_MapWindow(busyPtr->tkBusy);
	window = Tk_WindowId(busyPtr->tkBusy);
	display = Tk_Display(busyPtr->tkBusy);
	hWnd = Tk_GetHWND(window);
	display->request++;
	SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }

    /*
     * Under Win32, cursors aren't associated with windows. Tk fakes this by
     * watching Motion events on its windows. So Tk will automatically change
     * the cursor when the pointer enters the Busy window. But Windows does
     * not immediately change the cursor; it waits for the cursor position to
     * change or a system call. We need to change the cursor before the
     * application starts processing, so set the cursor position redundantly
     * back to the current position.
     */

    GetCursorPos(&point);
    TkSetCursorPos(point.x, point.y);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpHideBusyWindow --
 *
 *	Makes a busy window "disappear".
 *
 * Results:
 *	None.

 *
 * Side effects:
 *	Arranges for the busy window to stop intercepting events, and the
 *	cursor to change back to its normal setting.
 *
 *----------------------------------------------------------------------
 */

void
TkpHideBusyWindow(
    TkBusy busy)
{
    Busy *busyPtr = (Busy *) busy;
    POINT point;

    if (busyPtr->tkBusy != NULL) {
	Tk_UnmapWindow(busyPtr->tkBusy);
    }

    /*
     * Under Win32, cursors aren't associated with windows. Tk fakes this by
     * watching Motion events on its windows. So Tk will automatically change
     * the cursor when the pointer enters the Busy window. But Windows does
     * not immediately change the cursor: it waits for the cursor position to
     * change or a system call. We need to change the cursor before the
     * application starts processing, so set the cursor position redundantly
     * back to the current position.
     */

    GetCursorPos(&point);
    TkSetCursorPos(point.x, point.y);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeTransparentWindowExist --
 *
 *	Construct the platform-specific resources for a transparent window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Moves the specified window in the stacking order.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent)		/* Parent window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    HWND hParent = (HWND) parent, hWnd;
    int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    DWORD exStyle = WS_EX_TRANSPARENT | WS_EX_TOPMOST;

    hWnd = CreateWindowExW(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    hParent, NULL, Tk_GetHINSTANCE(), NULL);
    winPtr->window = Tk_AttachHWND(tkwin, hWnd);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateBusy --
 *
 *	Construct the platform-specific parts of a busy window. Note that this
 *	postpones the actual creation of the window resource until later.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets up part of the busy window structure.
 *
 *----------------------------------------------------------------------
 */

void
TkpCreateBusy(
    Tk_FakeWin *winPtr,
    Tk_Window tkRef,
    Window *parentPtr,
    Tk_Window tkParent,
    TkBusy busy)
{
    Busy *busyPtr = (Busy *) busy;

    if (winPtr->flags & TK_REPARENTED) {
	/*
	 * This works around a bug in the implementation of menubars for
	 * non-Macintosh window systems (Win32 and X11). Tk doesn't reset the
	 * pointers to the parent window when the menu is reparented
	 * (winPtr->parentPtr points to the wrong window). We get around this
	 * by determining the parent via the native API calls.
	 */

	HWND hWnd = GetParent(Tk_GetHWND(Tk_WindowId(tkRef)));
	RECT rect;

	if (GetWindowRect(hWnd, &rect)) {
	    busyPtr->width = rect.right - rect.left;
	    busyPtr->height = rect.bottom - rect.top;
	}
    } else {
	*parentPtr = Tk_WindowId(tkParent);
	*parentPtr = (Window) Tk_GetHWND(*parentPtr);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|

<
<

<
>


<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<


|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<









790
791
792
793
794
795
796













797









798








799









800







801
802


803

804
805
806





807




















808





809












810
811
812








813



























814




815








816


817








818
819
820
821
822
823
824
825
826
    SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0,
	    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}

/*
 *----------------------------------------------------------------------
 *













 * TkpWindowWasRecentlyDeleted --









 *








 *	Determines whether we know if the window given as argument was









 *	recently deleted. Called by the generic code error handler to handle







 *	BadWindow events.
 *


 * Results:

 *	Always 0. We do not keep this information on Windows.
 *
 * Side effects:





 *	None.




















 *





 *----------------------------------------------------------------------












 */

int








TkpWindowWasRecentlyDeleted(



























    Window win,




    TkDisplay *dispPtr)








{


    return 0;








}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinWm.c.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;	/* Interpreter in which to invoke command. */
    char command[TKFLEXARRAY];	/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
    (offsetof(ProtocolHandler, command) + 1 + cmdLength)

/*
 * Helper type passed via lParam to TkWmStackorderToplevelEnumProc
 */

typedef struct TkWmStackorderToplevelPair {
    Tcl_HashTable *table;
    TkWindow **windowPtr;
} TkWmStackorderToplevelPair;

/*
 * This structure represents the contents of a icon, in terms of its image.
 * The HICON is an internal Windows format. Most of these icon-specific
 * structures originated with the Winico extension. We stripped out unused
 * parts of that code, and integrated the code more naturally with Tcl.







|
|







|







|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[4];		/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
    ((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))

/*
 * Helper type passed via lParam to TkWmStackorderToplevelEnumProc
 */

typedef struct TkWmStackorderToplevelPair {
    Tcl_HashTable *table;
    TkWindow **window_ptr;
} TkWmStackorderToplevelPair;

/*
 * This structure represents the contents of a icon, in terms of its image.
 * The HICON is an internal Windows format. Most of these icon-specific
 * structures originated with the Winico extension. We stripped out unused
 * parts of that code, and integrated the code more naturally with Tcl.
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
 * latter is for the global default icon choice.
 *
 * Icons loaded from .icr/.icr use the iconBlock field, icons loaded from
 * .exe/.dll use the hIcon field.
 */

typedef struct WinIconInstance {
    size_t refCount;	/* Number of instances that share this data
				 * structure. */
    BlockOfIconImagesPtr iconBlock;
				/* Pointer to icon resource data for image */
} WinIconInstance;

typedef struct WinIconInstance *WinIconPtr;








|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
 * latter is for the global default icon choice.
 *
 * Icons loaded from .icr/.icr use the iconBlock field, icons loaded from
 * .exe/.dll use the hIcon field.
 */

typedef struct WinIconInstance {
    int refCount;		/* Number of instances that share this data
				 * structure. */
    BlockOfIconImagesPtr iconBlock;
				/* Pointer to icon resource data for image */
} WinIconInstance;

typedef struct WinIconInstance *WinIconPtr;

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *containerPtr;	/* Container window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */

    /*







|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *masterPtr;	/* Master window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */

    /*
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	Non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		Non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the container.
 * WM_FULLSCREEN -		Non-zero means that this window has been placed
 *				in the full screen mode. It should be mapped at
 *				0,0 and be the width and height of the screen.
 */

#define WM_NEVER_MAPPED			(1<<0)
#define WM_UPDATE_PENDING		(1<<1)







|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	Non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		Non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the master.
 * WM_FULLSCREEN -		Non-zero means that this window has been placed
 *				in the full screen mode. It should be mapped at
 *				0,0 and be the width and height of the screen.
 */

#define WM_NEVER_MAPPED			(1<<0)
#define WM_UPDATE_PENDING		(1<<1)
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};

typedef struct {
    HPALETTE systemPalette;	/* System palette; refers to the currently
				 * installed foreground logical palette. */
    TkWindow *createWindow;	/* Window that is being constructed. This
				 * value is set immediately before a call to
				 * CreateWindowEx, and is used by SetLimits.
				 * This is a gross hack needed to work around
				 * Windows brain damage where it sends the







|


|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostSlaveProc */
};

typedef struct ThreadSpecificData {
    HPALETTE systemPalette;	/* System palette; refers to the currently
				 * installed foreground logical palette. */
    TkWindow *createWindow;	/* Window that is being constructed. This
				 * value is set immediately before a call to
				 * CreateWindowEx, and is used by SetLimits.
				 * This is a gross hack needed to work around
				 * Windows brain damage where it sends the
391
392
393
394
395
396
397

















398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
 * The following variables cannot be placed in thread local storage because
 * they must be shared across threads.
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */


















TCL_DECLARE_MUTEX(winWmMutex)

/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);
static void		GenerateActivateEvent(TkWindow *winPtr, const int *flagPtr);
static void		GetMaxSize(WmInfo *wmPtr,
			    int *maxWidthPtr, int *maxHeightPtr);
static void		GetMinSize(WmInfo *wmPtr,
			    int *minWidthPtr, int *minHeightPtr);
static TkWindow *	GetTopLevel(HWND hwnd);
static void		InitWm(void);
static int		InstallColormaps(HWND hwnd, int message,
			    int isForemost);
static void		InvalidateSubTree(TkWindow *winPtr, Colormap colormap);
static void		InvalidateSubTreeDepth(TkWindow *winPtr);
static int		ParseGeometry(Tcl_Interp *interp, const char *string,
			    TkWindow *winPtr);
static void		RefreshColormap(Colormap colormap, TkDisplay *dispPtr);
static void		SetLimits(HWND hwnd, MINMAXINFO *info);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static LRESULT CALLBACK	TopLevelProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
 * The following variables cannot be placed in thread local storage because
 * they must be shared across threads.
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */

/*
 * A pointer to a shell proc which allows us to extract icons from any file.
 * We just initialize this when we start up (if we can) and then it never
 * changes
 */

DWORD* (WINAPI *shgetfileinfoProc) (LPCTSTR pszPath, DWORD dwFileAttributes,
	SHFILEINFO* psfi, UINT cbFileInfo, UINT uFlags) = NULL;

/*
 * A pointer to SetLayeredWindowAttributes (user32.dll) which we retrieve
 * dynamically because it is only valid on Win2K+.
 */

BOOL (WINAPI *setLayeredWindowAttributesProc) (HWND hwnd, COLORREF crKey,
	BYTE bAlpha, DWORD dwFlags) = NULL;

TCL_DECLARE_MUTEX(winWmMutex)

/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);
static void		GenerateActivateEvent(TkWindow *winPtr, const int *flagPtr);
static void		GetMaxSize(WmInfo *wmPtr,
			    int *maxWidthPtr, int *maxHeightPtr);
static void		GetMinSize(WmInfo *wmPtr,
			    int *minWidthPtr, int *minHeightPtr);
static TkWindow *	GetTopLevel(HWND hwnd);
static void		InitWm(void);
static int		InstallColormaps(HWND hwnd, int message,
			    int isForemost);
static void		InvalidateSubTree(TkWindow *winPtr, Colormap colormap);
static void		InvalidateSubTreeDepth(TkWindow *winPtr);
static int		ParseGeometry(Tcl_Interp *interp, char *string,
			    TkWindow *winPtr);
static void		RefreshColormap(Colormap colormap, TkDisplay *dispPtr);
static void		SetLimits(HWND hwnd, MINMAXINFO *info);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static LRESULT CALLBACK	TopLevelProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
 *----------------------------------------------------------------------
 */

static LPSTR
FindDIBBits(
    LPSTR lpbi)
{
    return lpbi + *((LPDWORD) lpbi) + PaletteSize(lpbi);
}

/*
 *----------------------------------------------------------------------
 *
 * BytesPerLine --
 *







|







646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
 *----------------------------------------------------------------------
 */

static LPSTR
FindDIBBits(
    LPSTR lpbi)
{
    return lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi);
}

/*
 *----------------------------------------------------------------------
 *
 * BytesPerLine --
 *
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
	return FALSE;
    }

    /*
     * BITMAPINFO is at beginning of bits.
     */

    lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits;

    /*
     * Width - simple enough.
     */

    lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;








|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
	return FALSE;
    }

    /*
     * BITMAPINFO is at beginning of bits.
     */

    lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;

    /*
     * Width - simple enough.
     */

    lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;

711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes
	    * lpImage->lpbi->bmiHeader.biBitCount;

    /*
     * XOR bits follow the header and color table.
     */

    lpImage->lpXOR = (LPBYTE) FindDIBBits((LPSTR) lpImage->lpbi);

    /*
     * AND bits follow the XOR bits.
     */

    lpImage->lpAND = lpImage->lpXOR +
	    lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER) lpImage->lpbi);
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeIconOrCursorFromResource --







|





|
|







728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
    lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes
	    * lpImage->lpbi->bmiHeader.biBitCount;

    /*
     * XOR bits follow the header and color table.
     */

    lpImage->lpXOR = (LPBYTE)FindDIBBits(((LPSTR)lpImage->lpbi));

    /*
     * AND bits follow the XOR bits.
     */

    lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*
	    BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeIconOrCursorFromResource --
741
742
743
744
745
746
747
748


749
750
751
752
753
754
755
756













757
758
759
760
761
762

763
764
765



766
767
768
769
770
771
772
773
774
775
776
777
778
 */

static HICON
MakeIconOrCursorFromResource(
    LPICONIMAGE lpIcon,
    BOOL isIcon)
{
    HICON hIcon;



    /*
     * Sanity Check
     */

    if (lpIcon == NULL || lpIcon->lpBits == NULL) {
	return NULL;
    }














    /*
     * Let the OS do the real work :)
     */

    hIcon = (HICON) CreateIconFromResourceEx(lpIcon->lpBits,

	    lpIcon->dwNumBytes, isIcon, 0x00030000,
	    (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biWidth,
	    (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biHeight/2, 0);




    /*
     * It failed, odds are good we're on NT so try the non-Ex way.
     */

    if (hIcon == NULL) {
	/*
	 * We would break on NT if we try with a 16bpp image.
	 */

	if (lpIcon->lpbi->bmiHeader.biBitCount != 16) {
	    hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes,
		    isIcon, 0x00030000);







|
>
>





|


>
>
>
>
>
>
>
>
>
>
>
>
>





|
>
|
|
|
>
>
>





|







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
 */

static HICON
MakeIconOrCursorFromResource(
    LPICONIMAGE lpIcon,
    BOOL isIcon)
{
    HICON hIcon ;
    static FARPROC pfnCreateIconFromResourceEx=NULL;
    static int initinfo=0;

    /*
     * Sanity Check
     */

    if (lpIcon == NULL) {
	return NULL;
    }
    if (lpIcon->lpBits == NULL) {
	return NULL;
    }

    if (!initinfo) {
	HMODULE hMod = GetModuleHandleA("USER32.DLL");

	initinfo = 1;
	if (hMod) {
	    pfnCreateIconFromResourceEx =
		    GetProcAddress(hMod, "CreateIconFromResourceEx");
	}
    }

    /*
     * Let the OS do the real work :)
     */

    if (pfnCreateIconFromResourceEx != NULL) {
	hIcon = (HICON) (pfnCreateIconFromResourceEx) (lpIcon->lpBits,
		lpIcon->dwNumBytes, isIcon, 0x00030000,
		(*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth,
		(*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight/2, 0);
    } else {
	 hIcon = NULL;
    }

    /*
     * It failed, odds are good we're on NT so try the non-Ex way.
     */

    if (hIcon == NULL)    {
	/*
	 * We would break on NT if we try with a 16bpp image.
	 */

	if (lpIcon->lpbi->bmiHeader.biBitCount != 16) {
	    hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes,
		    isIcon, 0x00030000);
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869

870

871



















872




873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899


900
901
902
903
904
905
906
static int
InitWindowClass(
    WinIconPtr titlebaricon)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	tsdPtr->firstWindow = 1;
	tsdPtr->iconPtr = NULL;
    }
    if (!initialized) {
	Tcl_MutexLock(&winWmMutex);
	if (!initialized) {

	    WNDCLASSW windowClass;





















	    initialized = 1;





	    ZeroMemory(&windowClass, sizeof(WNDCLASSW));

	    windowClass.style = CS_HREDRAW | CS_VREDRAW;
	    windowClass.hInstance = Tk_GetHINSTANCE();
	    windowClass.lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME;

	    windowClass.lpfnWndProc = WmProc;
	    if (titlebaricon == NULL) {
		windowClass.hIcon = LoadIconW(Tk_GetHINSTANCE(), L"tk");
	    } else {
		windowClass.hIcon = GetIcon(titlebaricon, ICON_BIG);
		if (windowClass.hIcon == NULL) {
		    return TCL_ERROR;
		}

		/*
		 * Store pointer to default icon so we know when we need to
		 * free that information
		 */

		tsdPtr->iconPtr = titlebaricon;
	    }
	    windowClass.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);

	    if (!RegisterClassW(&windowClass)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }


	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}

/*







|




|

|
>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>

|

|
|
|
>
|

|

|
|










|

|


>
>







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
static int
InitWindowClass(
    WinIconPtr titlebaricon)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (! tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	tsdPtr->firstWindow = 1;
	tsdPtr->iconPtr = NULL;
    }
    if (! initialized) {
	Tcl_MutexLock(&winWmMutex);
	if (! initialized) {
	    Tcl_DString classString;
	    WNDCLASS class;
	    initialized = 1;

	    if (shgetfileinfoProc == NULL) {
		HINSTANCE hInstance = LoadLibraryA("shell32");
		if (hInstance != NULL) {
		    shgetfileinfoProc = (DWORD* (WINAPI *) (LPCTSTR pszPath,
			    DWORD dwFileAttributes, SHFILEINFO* psfi,
			    UINT cbFileInfo, UINT uFlags))
			(void *)GetProcAddress(hInstance, "SHGetFileInfo");
		    FreeLibrary(hInstance);
		}
	    }
	    if (setLayeredWindowAttributesProc == NULL) {
		HINSTANCE hInstance = LoadLibraryA("user32");
		if (hInstance != NULL) {
		    setLayeredWindowAttributesProc = (BOOL (WINAPI*)(HWND hwnd,
			    COLORREF crKey, BYTE bAlpha, DWORD dwFlags))
			(void *)GetProcAddress(hInstance,"SetLayeredWindowAttributes");
		    FreeLibrary(hInstance);
		}
	    }

	    /*
	     * The only difference between WNDCLASSW and WNDCLASSA are in
	     * pointers, so we can use the generic structure WNDCLASS.
	     */

	    ZeroMemory(&class, sizeof(WNDCLASS));

	    class.style = CS_HREDRAW | CS_VREDRAW;
	    class.hInstance = Tk_GetHINSTANCE();
	    Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString);
	    class.lpszClassName = (LPCTSTR) Tcl_DStringValue(&classString);
	    class.lpfnWndProc = WmProc;
	    if (titlebaricon == NULL) {
		class.hIcon = LoadIcon(Tk_GetHINSTANCE(), "tk");
	    } else {
		class.hIcon = GetIcon(titlebaricon, ICON_BIG);
		if (class.hIcon == NULL) {
		    return TCL_ERROR;
		}

		/*
		 * Store pointer to default icon so we know when we need to
		 * free that information
		 */

		tsdPtr->iconPtr = titlebaricon;
	    }
	    class.hCursor = LoadCursor(NULL, IDC_ARROW);

	    if (!(*tkWinProcs->registerClass)(&class)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }

	    Tcl_DStringFree(&classString);
	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}

/*
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991

    if (tkw == NULL) {
	tkw = Tk_MainWindow(interp);
	application = 1;
    }

    if (!(Tk_IsTopLevel(tkw))) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", Tk_PathName(tkw)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", Tk_PathName(tkw),
		NULL);
	return TCL_ERROR;
    }
    if (Tk_WindowId(tkw) == None) {
	Tk_MakeWindowExist(tkw);
    }

    /*
     * We must get the window's wrapper, not the window itself.
     */

    wmPtr = ((TkWindow *) tkw)->wmInfoPtr;
    hwnd = wmPtr->wrapper;

    if (application) {
	if (hwnd == NULL) {
	    /*
	     * I don't actually think this is ever the correct thing, unless
	     * perhaps the window doesn't have a wrapper. But I believe all







|
|
<
<










|







1027
1028
1029
1030
1031
1032
1033
1034
1035


1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

    if (tkw == NULL) {
	tkw = Tk_MainWindow(interp);
	application = 1;
    }

    if (!(Tk_IsTopLevel(tkw))) {
	Tcl_AppendResult(interp, "window \"", Tk_PathName(tkw),
		"\" isn't a top-level window", NULL);


	return TCL_ERROR;
    }
    if (Tk_WindowId(tkw) == None) {
	Tk_MakeWindowExist(tkw);
    }

    /*
     * We must get the window's wrapper, not the window itself.
     */

    wmPtr = ((TkWindow*)tkw)->wmInfoPtr;
    hwnd = wmPtr->wrapper;

    if (application) {
	if (hwnd == NULL) {
	    /*
	     * I don't actually think this is ever the correct thing, unless
	     * perhaps the window doesn't have a wrapper. But I believe all
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
	 * If we aren't initialised, then just initialise with the user's
	 * icon. Otherwise our icon choice will be ignored moments later when
	 * Tk finishes initialising.
	 */

	if (!initialized) {
	    if (InitWindowClass(titlebaricon) != TCL_OK) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Unable to set icon", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FAILED", NULL);
		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*
	     * Don't check return result of SetClassLong() or
	     * SetClassLongPtrW() since they return the previously set value
	     * which is zero on the initial call or in an error case. The MSDN
	     * documentation does not indicate that the result needs to be
	     * checked.
	     */

	    SetClassLongPtrW(hwnd, GCLP_HICONSM,
		    (LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	    SetClassLongPtrW(hwnd, GCLP_HICON,
		    (LPARAM) GetIcon(titlebaricon, ICON_BIG));
	    tsdPtr = (ThreadSpecificData *)
		    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
	    if (tsdPtr->iconPtr != NULL) {
		DecrIconRefCount(tsdPtr->iconPtr);
	    }
	    tsdPtr->iconPtr = titlebaricon;







<
|
<







|





|

|







1061
1062
1063
1064
1065
1066
1067

1068

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
	 * If we aren't initialised, then just initialise with the user's
	 * icon. Otherwise our icon choice will be ignored moments later when
	 * Tk finishes initialising.
	 */

	if (!initialized) {
	    if (InitWindowClass(titlebaricon) != TCL_OK) {

		Tcl_AppendResult(interp, "Unable to set icon", NULL);

		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*
	     * Don't check return result of SetClassLong() or
	     * SetClassLongPtr() since they return the previously set value
	     * which is zero on the initial call or in an error case. The MSDN
	     * documentation does not indicate that the result needs to be
	     * checked.
	     */

	    SetClassLongPtr(hwnd, GCLP_HICONSM,
		    (LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	    SetClassLongPtr(hwnd, GCLP_HICON,
		    (LPARAM) GetIcon(titlebaricon, ICON_BIG));
	    tsdPtr = (ThreadSpecificData *)
		    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
	    if (tsdPtr->iconPtr != NULL) {
		DecrIconRefCount(tsdPtr->iconPtr);
	    }
	    tsdPtr->iconPtr = titlebaricon;
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

	    (void) InitWindowClass(NULL);
	}

	/*
	 * The following code is exercised if you do
	 *
	 *	toplevel .t ; wm titlebaricon .t foo.icr
	 *
	 * i.e. the wm hasn't had time to properly create the '.t' window
	 * before you set the icon.
	 */

	if (hwnd == NULL) {
	    /*
	     * This little snippet is copied from the 'Map' function, and
	     * should probably be placed in one proper location.
	     */

	    UpdateWrapper(wmPtr->winPtr);
	    wmPtr = ((TkWindow *) tkw)->wmInfoPtr;
	    hwnd = wmPtr->wrapper;
	    if (hwnd == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Can't set icon; window has no wrapper.", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL);
		return TCL_ERROR;
	    }
	}
	SendMessageW(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessageW(hwnd, WM_SETICON, ICON_BIG,
		(LPARAM) GetIcon(titlebaricon, ICON_BIG));

	/*
	 * Update the iconPtr we keep for each WmInfo structure.
	 */

	if (wmPtr->iconPtr != NULL) {







|












|


|
|
<



|

|







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137

	    (void) InitWindowClass(NULL);
	}

	/*
	 * The following code is exercised if you do
	 *
	 *   toplevel .t ; wm titlebaricon .t foo.icr
	 *
	 * i.e. the wm hasn't had time to properly create the '.t' window
	 * before you set the icon.
	 */

	if (hwnd == NULL) {
	    /*
	     * This little snippet is copied from the 'Map' function, and
	     * should probably be placed in one proper location.
	     */

	    UpdateWrapper(wmPtr->winPtr);
	    wmPtr = ((TkWindow*)tkw)->wmInfoPtr;
	    hwnd = wmPtr->wrapper;
	    if (hwnd == NULL) {
		Tcl_AppendResult(interp,
			"Can't set icon; window has no wrapper.", NULL);

		return TCL_ERROR;
	    }
	}
	SendMessage(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessage(hwnd, WM_SETICON, ICON_BIG,
		(LPARAM) GetIcon(titlebaricon, ICON_BIG));

	/*
	 * Update the iconPtr we keep for each WmInfo structure.
	 */

	if (wmPtr->iconPtr != NULL) {
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->iconPtr != NULL) {
	/*
	 * return default toplevel icon
	 */

	return GetIcon(tsdPtr->iconPtr, (int) iconsize);
    }

    /*
     * Ensure we operate on the toplevel, that has the icon refs.
     */

    while (!Tk_IsTopLevel(tkwin)) {







|







1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->iconPtr != NULL) {
	/*
	 * return default toplevel icon
	 */

	return GetIcon(tsdPtr->iconPtr, (int)iconsize);
    }

    /*
     * Ensure we operate on the toplevel, that has the icon refs.
     */

    while (!Tk_IsTopLevel(tkwin)) {
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170

    wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    if (wmPtr->iconPtr != NULL) {
	/*
	 * return window toplevel icon
	 */

	return GetIcon(wmPtr->iconPtr, (int) iconsize);
    }

    /*
     * Find the icon otherwise associated with the toplevel, or finally with
     * the window class.
     */

    icon = (HICON) SendMessageW(wmPtr->wrapper, WM_GETICON, iconsize,
	    (LPARAM) NULL);
    if (icon == (HICON) NULL) {
	icon = (HICON) GetClassLongPtrW(wmPtr->wrapper,
		(iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM);
    }
    return icon;
}

/*
 *----------------------------------------------------------------------







|







|


|







1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

    wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    if (wmPtr->iconPtr != NULL) {
	/*
	 * return window toplevel icon
	 */

	return GetIcon(wmPtr->iconPtr, (int)iconsize);
    }

    /*
     * Find the icon otherwise associated with the toplevel, or finally with
     * the window class.
     */

    icon = (HICON) SendMessage(wmPtr->wrapper, WM_GETICON, iconsize,
	    (LPARAM) NULL);
    if (icon == (HICON) NULL) {
	icon = (HICON) GetClassLongPtr(wmPtr->wrapper,
		(iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM);
    }
    return icon;
}

/*
 *----------------------------------------------------------------------
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
ReadIconFromFile(
    Tcl_Interp *interp,
    Tcl_Obj *fileName)
{
    WinIconPtr titlebaricon = NULL;
    BlockOfIconImagesPtr lpIR;

#if 0 /* TODO: Dead code? */
    if (0 /* If we already have an icon for this filename */) {
	titlebaricon = NULL; /* Get the real value from a lookup */
	titlebaricon->refCount++;
	return titlebaricon;
    }
#endif

    /*
     * First check if it is a .ico file.
     */

    lpIR = ReadIconOrCursorFromFile(interp, fileName, TRUE);

    /*
     * Then see if we can ask the shell for the icon for this file. We
     * want both the regular and small icons so that the Alt-Tab (task-
     * switching) display uses the right icon.
     */

    if (lpIR == NULL) {
	SHFILEINFOW sfiSM;
	Tcl_DString ds, ds2;
	DWORD *res;
	const char *file;

	file = Tcl_TranslateFileName(interp, Tcl_GetString(fileName), &ds);
	if (file == NULL) {
	    return NULL;
	}

	Tcl_DStringInit(&ds2);
	res = (DWORD *)SHGetFileInfoW(Tcl_UtfToWCharDString(file, -1, &ds2), 0, &sfiSM,
		sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
	Tcl_DStringFree(&ds);

	if (res != 0) {
	    SHFILEINFOW sfi;
	    unsigned size;

	    Tcl_ResetResult(interp);
	    res = (DWORD *)SHGetFileInfoW((WCHAR *)Tcl_DStringValue(&ds2), 0, &sfi,
		    sizeof(SHFILEINFO), SHGFI_ICON);

	    /*
	     * Account for extra icon, if necessary.
	     */

	    size = sizeof(BlockOfIconImages)
		    + ((res != 0) ? sizeof(ICONIMAGE) : 0);
	    lpIR = (BlockOfIconImagesPtr)ckalloc(size);
	    if (lpIR == NULL) {
		if (res != 0) {
		    DestroyIcon(sfi.hIcon);
		}
		DestroyIcon(sfiSM.hIcon);
		Tcl_DStringFree(&ds2);
		return NULL;







<





<













|
|








>
|
|

<


|



|








|







1266
1267
1268
1269
1270
1271
1272

1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304

1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
ReadIconFromFile(
    Tcl_Interp *interp,
    Tcl_Obj *fileName)
{
    WinIconPtr titlebaricon = NULL;
    BlockOfIconImagesPtr lpIR;


    if (0 /* If we already have an icon for this filename */) {
	titlebaricon = NULL; /* Get the real value from a lookup */
	titlebaricon->refCount++;
	return titlebaricon;
    }


    /*
     * First check if it is a .ico file.
     */

    lpIR = ReadIconOrCursorFromFile(interp, fileName, TRUE);

    /*
     * Then see if we can ask the shell for the icon for this file. We
     * want both the regular and small icons so that the Alt-Tab (task-
     * switching) display uses the right icon.
     */

    if (lpIR == NULL && shgetfileinfoProc != NULL) {
	SHFILEINFO sfiSM;
	Tcl_DString ds, ds2;
	DWORD *res;
	const char *file;

	file = Tcl_TranslateFileName(interp, Tcl_GetString(fileName), &ds);
	if (file == NULL) {
	    return NULL;
	}
	Tcl_UtfToExternalDString(NULL, file, -1, &ds2);
	Tcl_DStringFree(&ds);
	res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfiSM,
		sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);


	if (res != 0) {
	    SHFILEINFO sfi;
	    unsigned size;

	    Tcl_ResetResult(interp);
	    res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfi,
		    sizeof(SHFILEINFO), SHGFI_ICON);

	    /*
	     * Account for extra icon, if necessary.
	     */

	    size = sizeof(BlockOfIconImages)
		    + ((res != 0) ? sizeof(ICONIMAGE) : 0);
	    lpIR = (BlockOfIconImagesPtr) ckalloc(size);
	    if (lpIR == NULL) {
		if (res != 0) {
		    DestroyIcon(sfi.hIcon);
		}
		DestroyIcon(sfiSM.hIcon);
		Tcl_DStringFree(&ds2);
		return NULL;
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
		lpIR->IconImages[1].Colors	= 4;
		lpIR->IconImages[1].hIcon	= sfi.hIcon;
	    }
	}
	Tcl_DStringFree(&ds2);
    }
    if (lpIR != NULL) {
	titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
	titlebaricon->iconBlock = lpIR;
	titlebaricon->refCount = 1;
    }
    return titlebaricon;
}

/*







|







1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
		lpIR->IconImages[1].Colors	= 4;
		lpIR->IconImages[1].hIcon	= sfi.hIcon;
	    }
	}
	Tcl_DStringFree(&ds2);
    }
    if (lpIR != NULL) {
	titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
	titlebaricon->iconBlock = lpIR;
	titlebaricon->refCount = 1;
    }
    return titlebaricon;
}

/*
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

static WinIconPtr
GetIconFromPixmap(
    Display *dsPtr,
    Pixmap pixmap)
{
    WinIconPtr titlebaricon = NULL;
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;
    BlockOfIconImagesPtr lpIR;
    ICONINFO icon;
    HICON hIcon;
    int width, height;

    if (twdPtr == NULL) {
	return NULL;
    }

#if 0 /* TODO: Dead code?*/
    if (0 /* If we already have an icon for this pixmap */) {
	titlebaricon = NULL; /* Get the real value from a lookup */
	titlebaricon->refCount++;
	return titlebaricon;
    }
#endif

    Tk_SizeOfBitmap(dsPtr, pixmap, &width, &height);

    icon.fIcon = TRUE;
    icon.xHotspot = 0;
    icon.yHotspot = 0;
    icon.hbmMask = twdPtr->bitmap.handle;
    icon.hbmColor = twdPtr->bitmap.handle;

    hIcon = CreateIconIndirect(&icon);
    if (hIcon == NULL) {
	return NULL;
    }

    lpIR = (BlockOfIconImagesPtr)ckalloc(sizeof(BlockOfIconImages));
    if (lpIR == NULL) {
	DestroyIcon(hIcon);
	return NULL;
    }

    lpIR->nNumImages = 1;
    lpIR->IconImages[0].Width = width;
    lpIR->IconImages[0].Height = height;
    lpIR->IconImages[0].Colors = 1 << twdPtr->bitmap.depth;
    lpIR->IconImages[0].hIcon = hIcon;

    /*
     * These fields are ignored.
     */

    lpIR->IconImages[0].lpBits = 0;
    lpIR->IconImages[0].dwNumBytes = 0;
    lpIR->IconImages[0].lpXOR = 0;
    lpIR->IconImages[0].lpAND = 0;

    titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    return titlebaricon;
}

/*
 *----------------------------------------------------------------------







|









<





<














|




















|







1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

static WinIconPtr
GetIconFromPixmap(
    Display *dsPtr,
    Pixmap pixmap)
{
    WinIconPtr titlebaricon = NULL;
    TkWinDrawable *twdPtr = (TkWinDrawable*) pixmap;
    BlockOfIconImagesPtr lpIR;
    ICONINFO icon;
    HICON hIcon;
    int width, height;

    if (twdPtr == NULL) {
	return NULL;
    }


    if (0 /* If we already have an icon for this pixmap */) {
	titlebaricon = NULL; /* Get the real value from a lookup */
	titlebaricon->refCount++;
	return titlebaricon;
    }


    Tk_SizeOfBitmap(dsPtr, pixmap, &width, &height);

    icon.fIcon = TRUE;
    icon.xHotspot = 0;
    icon.yHotspot = 0;
    icon.hbmMask = twdPtr->bitmap.handle;
    icon.hbmColor = twdPtr->bitmap.handle;

    hIcon = CreateIconIndirect(&icon);
    if (hIcon == NULL) {
	return NULL;
    }

    lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages));
    if (lpIR == NULL) {
	DestroyIcon(hIcon);
	return NULL;
    }

    lpIR->nNumImages = 1;
    lpIR->IconImages[0].Width = width;
    lpIR->IconImages[0].Height = height;
    lpIR->IconImages[0].Colors = 1 << twdPtr->bitmap.depth;
    lpIR->IconImages[0].hIcon = hIcon;

    /*
     * These fields are ignored.
     */

    lpIR->IconImages[0].lpBits = 0;
    lpIR->IconImages[0].dwNumBytes = 0;
    lpIR->IconImages[0].lpXOR = 0;
    lpIR->IconImages[0].lpAND = 0;

    titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    return titlebaricon;
}

/*
 *----------------------------------------------------------------------
1412
1413
1414
1415
1416
1417
1418


1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
 *----------------------------------------------------------------------
 */

static void
DecrIconRefCount(
    WinIconPtr titlebaricon)
{


    if (titlebaricon->refCount-- <= 1) {
	if (titlebaricon->iconBlock != NULL) {
	    FreeIconBlock(titlebaricon->iconBlock);
	}
	titlebaricon->iconBlock = NULL;

	ckfree(titlebaricon);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeIconBlock --







>
>
|





|







1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
 *----------------------------------------------------------------------
 */

static void
DecrIconRefCount(
    WinIconPtr titlebaricon)
{
    titlebaricon->refCount--;

    if (titlebaricon->refCount <= 0) {
	if (titlebaricon->iconBlock != NULL) {
	    FreeIconBlock(titlebaricon->iconBlock);
	}
	titlebaricon->iconBlock = NULL;

	ckfree((char*)titlebaricon);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeIconBlock --
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
{
    int i;

    /*
     * Free all the bits.
     */

    for (i=0 ; i<lpIR->nNumImages ; i++) {
	if (lpIR->IconImages[i].lpBits != NULL) {
	    ckfree(lpIR->IconImages[i].lpBits);
	}
	if (lpIR->IconImages[i].hIcon != NULL) {
	    DestroyIcon(lpIR->IconImages[i].hIcon);
	}
    }
    ckfree(lpIR);
}

/*
 *----------------------------------------------------------------------
 *
 * GetIcon --
 *







|

|





|







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
{
    int i;

    /*
     * Free all the bits.
     */

    for (i=0; i< lpIR->nNumImages; i++) {
	if (lpIR->IconImages[i].lpBits != NULL) {
	    ckfree((char*)lpIR->IconImages[i].lpBits);
	}
	if (lpIR->IconImages[i].hIcon != NULL) {
	    DestroyIcon(lpIR->IconImages[i].hIcon);
	}
    }
    ckfree ((char*)lpIR);
}

/*
 *----------------------------------------------------------------------
 *
 * GetIcon --
 *
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496


1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541

static HICON
GetIcon(
    WinIconPtr titlebaricon,
    int icon_size)
{
    BlockOfIconImagesPtr lpIR;
    unsigned int size = (icon_size == 0 ? 16 : 32);
    int i;

    if (titlebaricon == NULL) {
	return NULL;
    }

    lpIR = titlebaricon->iconBlock;
    if (lpIR == NULL) {
	return NULL;
    }



    for (i=0 ; i<lpIR->nNumImages ; i++) {
	/*
	 * Take the first or a 32x32 16 color icon
	 */

	if ((lpIR->IconImages[i].Height == size)
		&& (lpIR->IconImages[i].Width == size)
		&& (lpIR->IconImages[i].Colors >= 4)) {
	    return lpIR->IconImages[i].hIcon;
	}
    }

    /*
     * If we get here, then just return the first one, it will have to do!
     */

    if (lpIR->nNumImages >= 1) {
	return lpIR->IconImages[0].hIcon;

    }
    return NULL;
}

#if 0 /* UNUSED */
static HCURSOR
TclWinReadCursorFromFile(
    Tcl_Interp* interp,
    Tcl_Obj* fileName)
{
    BlockOfIconImagesPtr lpIR;
    HICON res = NULL;

    lpIR = ReadIconOrCursorFromFile(interp, fileName, FALSE);
    if (lpIR == NULL) {
	return NULL;
    }
    if (lpIR->nNumImages >= 1) {
	res = CopyImage(lpIR->IconImages[0].hIcon, IMAGE_CURSOR, 0, 0, 0);
    }
    FreeIconBlock(lpIR);
    return res;
}
#endif

/*







<
<








|
>
>

|
|
|
|

|
|
|
|
|
|

|
|
|

|
|
>


















|







1536
1537
1538
1539
1540
1541
1542


1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

static HICON
GetIcon(
    WinIconPtr titlebaricon,
    int icon_size)
{
    BlockOfIconImagesPtr lpIR;



    if (titlebaricon == NULL) {
	return NULL;
    }

    lpIR = titlebaricon->iconBlock;
    if (lpIR == NULL) {
	return NULL;
    } else {
	unsigned int size = (icon_size == 0 ? 16 : 32);
	int i;

	for (i = 0; i < lpIR->nNumImages; i++) {
	    /*
	     * Take the first or a 32x32 16 color icon
	     */

	    if ((lpIR->IconImages[i].Height == size)
		    && (lpIR->IconImages[i].Width == size)
		    && (lpIR->IconImages[i].Colors >= 4)) {
		return lpIR->IconImages[i].hIcon;
	    }
	}

	/*
	 * If we get here, then just return the first one, it will have to do!
	 */

	if (lpIR->nNumImages >= 1) {
	    return lpIR->IconImages[0].hIcon;
	}
    }
    return NULL;
}

#if 0 /* UNUSED */
static HCURSOR
TclWinReadCursorFromFile(
    Tcl_Interp* interp,
    Tcl_Obj* fileName)
{
    BlockOfIconImagesPtr lpIR;
    HICON res = NULL;

    lpIR = ReadIconOrCursorFromFile(interp, fileName, FALSE);
    if (lpIR == NULL) {
	return NULL;
    }
    if (lpIR->nNumImages >= 1) {
	res = CopyImage(lpIR->IconImages[0].hIcon, IMAGE_CURSOR,0,0,0);
    }
    FreeIconBlock(lpIR);
    return res;
}
#endif

/*
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700





1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718

    /*
     * Open the file.
     */

    channel = Tcl_FSOpenFileChannel(interp, fileName, "r", 0);
    if (channel == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error opening file \"%s\" for reading: %s",
		Tcl_GetString(fileName), Tcl_PosixError(interp)));
	return NULL;
    }
    if (Tcl_SetChannelOption(interp, channel, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, channel);
	return NULL;
    }
    if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, channel);
	return NULL;
    }

    /*
     * Allocate memory for the resource structure
     */

    lpIR = (BlockOfIconImagesPtr)ckalloc(sizeof(BlockOfIconImages));

    /*
     * Read in the header
     */

    lpIR->nNumImages = ReadICOHeader(channel);
    if (lpIR->nNumImages == -1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("Invalid file header", -1));
	Tcl_Close(NULL, channel);
	ckfree(lpIR);
	return NULL;
    }

    /*
     * Adjust the size of the struct to account for the images.
     */

    lpIR = (BlockOfIconImagesPtr)ckrealloc(lpIR, sizeof(BlockOfIconImages)

	    + (lpIR->nNumImages - 1) * sizeof(ICONIMAGE));

    /*
     * Allocate enough memory for the icon directory entries.
     */

    lpIDE = (LPICONDIRENTRY)ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY));

    /*
     * Read in the icon directory entries.
     */

    dwBytesRead = Tcl_Read(channel, (char *) lpIDE,
	    (int) (lpIR->nNumImages * sizeof(ICONDIRENTRY)));
    if (dwBytesRead != lpIR->nNumImages * sizeof(ICONDIRENTRY)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file: %s", Tcl_PosixError(interp)));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "READ", NULL);
	Tcl_Close(NULL, channel);
	ckfree(lpIDE);
	ckfree(lpIR);
	return NULL;
    }

    /*
     * NULL-out everything to make memory management easier.
     */

    for (i = 0; i < lpIR->nNumImages; i++) {
	lpIR->IconImages[i].lpBits = NULL;
    }

    /*
     * Loop through and read in each image.
     */

    for (i=0 ; i<lpIR->nNumImages ; i++) {
	/*
	 * Allocate memory for the resource.
	 */

	lpIR->IconImages[i].lpBits = (LPBYTE)ckalloc(lpIDE[i].dwBytesInRes);
	lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes;

	/*
	 * Seek to beginning of this image.
	 */

	if (Tcl_Seek(channel, lpIDE[i].dwImageOffset, FILE_BEGIN) == -1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error seeking in file: %s", Tcl_PosixError(interp)));
	    goto readError;
	}

	/*
	 * Read it in.
	 */

	dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits,
		(int) lpIDE[i].dwBytesInRes);
	if (dwBytesRead != lpIDE[i].dwBytesInRes) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading file: %s", Tcl_PosixError(interp)));
	    goto readError;
	}

	/*
	 * Set the internal pointers appropriately.
	 */

	if (!AdjustIconImagePointers(&lpIR->IconImages[i])) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Error converting to internal format", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FORMAT", NULL);
	    goto readError;
	}
	lpIR->IconImages[i].hIcon =
		MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon);
    }

    /*
     * Clean up
     */

    ckfree(lpIDE);
    Tcl_Close(NULL, channel);





    return lpIR;

  readError:
    Tcl_Close(NULL, channel);
    for (i = 0; i < lpIR->nNumImages; i++) {
	if (lpIR->IconImages[i].lpBits != NULL) {
	    ckfree(lpIR->IconImages[i].lpBits);
	}
    }
    ckfree(lpIDE);
    ckfree(lpIR);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * GetTopLevel --







<
|
|

















|





|
<
|

|







|
>
|





|





|
|

|
<
<

|
|




















|







<
|







|


|
<







|
<
|
|



|






|

>
>
>
>
>






|


|
|







1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687


1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730

1731
1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775

    /*
     * Open the file.
     */

    channel = Tcl_FSOpenFileChannel(interp, fileName, "r", 0);
    if (channel == NULL) {

	Tcl_AppendResult(interp,"Error opening file \"",
		Tcl_GetString(fileName), "\" for reading", NULL);
	return NULL;
    }
    if (Tcl_SetChannelOption(interp, channel, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, channel);
	return NULL;
    }
    if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, channel);
	return NULL;
    }

    /*
     * Allocate memory for the resource structure
     */

    lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages));

    /*
     * Read in the header
     */

    if ((lpIR->nNumImages = ReadICOHeader(channel)) == -1) {

	Tcl_AppendResult(interp, "Invalid file header", NULL);
	Tcl_Close(NULL, channel);
	ckfree((char*) lpIR);
	return NULL;
    }

    /*
     * Adjust the size of the struct to account for the images.
     */

    lpIR = (BlockOfIconImagesPtr) ckrealloc((char*) lpIR,
	    sizeof(BlockOfIconImages)
	    + ((lpIR->nNumImages - 1) * sizeof(ICONIMAGE)));

    /*
     * Allocate enough memory for the icon directory entries.
     */

    lpIDE = (LPICONDIRENTRY) ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY));

    /*
     * Read in the icon directory entries.
     */

    dwBytesRead = Tcl_Read(channel, (char*) lpIDE,
	    (int)(lpIR->nNumImages * sizeof(ICONDIRENTRY)));
    if (dwBytesRead != lpIR->nNumImages * sizeof(ICONDIRENTRY)) {
	Tcl_AppendResult(interp, "Error reading file", NULL);


	Tcl_Close(NULL, channel);
	ckfree((char *) lpIDE);
	ckfree((char *) lpIR);
	return NULL;
    }

    /*
     * NULL-out everything to make memory management easier.
     */

    for (i = 0; i < lpIR->nNumImages; i++) {
	lpIR->IconImages[i].lpBits = NULL;
    }

    /*
     * Loop through and read in each image.
     */

    for (i=0 ; i<lpIR->nNumImages ; i++) {
	/*
	 * Allocate memory for the resource.
	 */

	lpIR->IconImages[i].lpBits = (LPBYTE) ckalloc(lpIDE[i].dwBytesInRes);
	lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes;

	/*
	 * Seek to beginning of this image.
	 */

	if (Tcl_Seek(channel, lpIDE[i].dwImageOffset, FILE_BEGIN) == -1) {

	    Tcl_AppendResult(interp, "Error seeking in file", NULL);
	    goto readError;
	}

	/*
	 * Read it in.
	 */

	dwBytesRead = Tcl_Read(channel, (char *) lpIR->IconImages[i].lpBits,
		(int) lpIDE[i].dwBytesInRes);
	if (dwBytesRead != lpIDE[i].dwBytesInRes) {
	    Tcl_AppendResult(interp, "Error reading file", NULL);

	    goto readError;
	}

	/*
	 * Set the internal pointers appropriately.
	 */

	if (!AdjustIconImagePointers( &(lpIR->IconImages[i]))) {

	    Tcl_AppendResult(interp, "Error converting to internal format",
		    NULL);
	    goto readError;
	}
	lpIR->IconImages[i].hIcon =
		MakeIconOrCursorFromResource(&(lpIR->IconImages[i]), isIcon);
    }

    /*
     * Clean up
     */

    ckfree((char *) lpIDE);
    Tcl_Close(NULL, channel);
    if (lpIR == NULL){
	Tcl_AppendResult(interp, "Reading of ", Tcl_GetString(fileName),
		" failed!", NULL);
	return NULL;
    }
    return lpIR;

  readError:
    Tcl_Close(NULL, channel);
    for (i = 0; i < lpIR->nNumImages; i++) {
	if (lpIR->IconImages[i].lpBits != NULL) {
	    ckfree((char *) lpIR->IconImages[i].lpBits);
	}
    }
    ckfree((char *) lpIDE);
    ckfree((char *) lpIR);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * GetTopLevel --
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
     * completed, then the user data slot will not have been set yet, so we
     * use the global createWindow variable.
     */

    if (tsdPtr->createWindow) {
	return tsdPtr->createWindow;
    }
    return (TkWindow *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
}

/*
 *----------------------------------------------------------------------
 *
 * SetLimits --
 *







|







1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
     * completed, then the user data slot will not have been set yet, so we
     * use the global createWindow variable.
     */

    if (tsdPtr->createWindow) {
	return tsdPtr->createWindow;
    }
    return (TkWindow *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
}

/*
 *----------------------------------------------------------------------
 *
 * SetLimits --
 *
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
 */

static void
SetLimits(
    HWND hwnd,
    MINMAXINFO *info)
{
    WmInfo *wmPtr;
    int maxWidth, maxHeight;
    int minWidth, minHeight;
    int base;
    TkWindow *winPtr = GetTopLevel(hwnd);

    if (winPtr == NULL) {
	return;







|







1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
 */

static void
SetLimits(
    HWND hwnd,
    MINMAXINFO *info)
{
    register WmInfo *wmPtr;
    int maxWidth, maxHeight;
    int minWidth, minHeight;
    int base;
    TkWindow *winPtr = GetTopLevel(hwnd);

    if (winPtr == NULL) {
	return;
1870
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
#endif

    if (!initialized) {
	return;
    }
    initialized = 0;

    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;

    UnregisterClassW(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --
 *







|
>






|







1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
#endif

    if (!initialized) {
	return;
    }
    initialized = 0;

    tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;

    UnregisterClass(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
1901
1902
1903
1904
1905
1906
1907


1908
1909
1910
1911
1912
1913
1914
1915
 *--------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{


    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    /*
     * Initialize full structure, then set what isn't NULL
     */

    ZeroMemory(wmPtr, sizeof(WmInfo));
    winPtr->wmInfoPtr = wmPtr;







>
>
|







1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
 *--------------------------------------------------------------
 */

void
TkWmNewWindow(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    register WmInfo *wmPtr;

    wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));

    /*
     * Initialize full structure, then set what isn't NULL
     */

    ZeroMemory(wmPtr, sizeof(WmInfo));
    winPtr->wmInfoPtr = wmPtr;
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
    wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1;
    wmPtr->gravity = NorthWestGravity;
    wmPtr->width = -1;
    wmPtr->height = -1;
    wmPtr->x = winPtr->changes.x;
    wmPtr->y = winPtr->changes.y;
    wmPtr->crefObj = NULL;
    wmPtr->colorref = (COLORREF) 0;
    wmPtr->alpha = 1.0;

    wmPtr->configWidth = -1;
    wmPtr->configHeight = -1;
    wmPtr->flags = WM_NEVER_MAPPED;
    wmPtr->nextPtr = winPtr->dispPtr->firstWmPtr;
    winPtr->dispPtr->firstWmPtr = wmPtr;

    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateWrapper --
 *







|














|






|







1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
    wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1;
    wmPtr->gravity = NorthWestGravity;
    wmPtr->width = -1;
    wmPtr->height = -1;
    wmPtr->x = winPtr->changes.x;
    wmPtr->y = winPtr->changes.y;
    wmPtr->crefObj = NULL;
    wmPtr->colorref = (COLORREF)0;
    wmPtr->alpha = 1.0;

    wmPtr->configWidth = -1;
    wmPtr->configHeight = -1;
    wmPtr->flags = WM_NEVER_MAPPED;
    wmPtr->nextPtr = winPtr->dispPtr->firstWmPtr;
    winPtr->dispPtr->firstWmPtr = wmPtr;

    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
	    TopLevelEventProc, (ClientData) winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateWrapper --
 *
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
 *----------------------------------------------------------------------
 */

static void
UpdateWrapper(
    TkWindow *winPtr)		/* Top-level window to redecorate. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND parentHWND, oldWrapper = wmPtr->wrapper;
    HWND child, nextHWND, focusHWND;
    int x, y, width, height, state;
    WINDOWPLACEMENT place;
    HICON hSmallIcon = NULL;
    HICON hBigIcon = NULL;
    Tcl_DString titleString;
    int *childStateInfo = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window == None) {
	/*
	 * Ensure existence of the window to update the wrapper for.







|






|







2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
 *----------------------------------------------------------------------
 */

static void
UpdateWrapper(
    TkWindow *winPtr)		/* Top-level window to redecorate. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND parentHWND, oldWrapper = wmPtr->wrapper;
    HWND child, nextHWND, focusHWND;
    int x, y, width, height, state;
    WINDOWPLACEMENT place;
    HICON hSmallIcon = NULL;
    HICON hBigIcon = NULL;
    Tcl_DString titleString, classString;
    int *childStateInfo = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window == None) {
	/*
	 * Ensure existence of the window to update the wrapper for.
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
	wmPtr->wrapper = (HWND) winPtr->privatePtr;
	if (wmPtr->wrapper == NULL) {
	    Tcl_Panic("UpdateWrapper: Cannot find container window");
	}
	if (!IsWindow(wmPtr->wrapper)) {
	    Tcl_Panic("UpdateWrapper: Container was destroyed");
	}

    } else {
	/*
	 * Pick the decorative frame style. Override redirect windows get
	 * created as undecorated popups if they have no transient parent,
	 * otherwise they are children. This allows splash screens to operate
	 * as an independent window, while having dropdowns (like for a
	 * combobox) not grab focus away from their parent. Transient windows
	 * get a modal dialog frame. Neither override, nor transient windows
	 * appear in the Windows taskbar. Note that a transient window does
	 * not resize by default, so we need to explicitly add the
	 * WS_THICKFRAME style if we want it to be resizeable.
	 */

	if (winPtr->atts.override_redirect) {
	    wmPtr->style = WM_OVERRIDE_STYLE;
	    wmPtr->exStyle = EX_OVERRIDE_STYLE;

	    /*
	     * Parent must be desktop even if we have a transient parent.
	     */

	    parentHWND = GetDesktopWindow();
	    if (wmPtr->containerPtr) {
		wmPtr->style |= WS_CHILD;
	    } else {
		wmPtr->style |= WS_POPUP;
	    }
	} else if (wmPtr->flags & WM_FULLSCREEN) {
	    wmPtr->style = WM_FULLSCREEN_STYLE;
	    wmPtr->exStyle = EX_FULLSCREEN_STYLE;
	} else if (wmPtr->containerPtr) {
	    wmPtr->style = WM_TRANSIENT_STYLE;
	    wmPtr->exStyle = EX_TRANSIENT_STYLE;
	    parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->containerPtr));
	    if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
		    && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) {
		wmPtr->style |= WS_THICKFRAME;
	    }
	} else {
	    wmPtr->style = WM_TOPLEVEL_STYLE;
	    wmPtr->exStyle = EX_TOPLEVEL_STYLE;
	}

	wmPtr->style |= wmPtr->styleConfig;
	wmPtr->exStyle |= wmPtr->exStyleConfig;

	if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
		&& (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
	    wmPtr->style &= ~ (WS_MAXIMIZEBOX | WS_SIZEBOX);
	}

	/*
	 * Compute the geometry of the parent and child windows.
	 */

	wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING;
	UpdateGeometryInfo(winPtr);
	wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING);

	width = wmPtr->borderWidth + winPtr->changes.width;
	height = wmPtr->borderHeight + winPtr->changes.height;

	/*
	 * Set the initial position from the user or program specified







>





|
















|







|


|
|
|




















|







2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
	wmPtr->wrapper = (HWND) winPtr->privatePtr;
	if (wmPtr->wrapper == NULL) {
	    Tcl_Panic("UpdateWrapper: Cannot find container window");
	}
	if (!IsWindow(wmPtr->wrapper)) {
	    Tcl_Panic("UpdateWrapper: Container was destroyed");
	}

    } else {
	/*
	 * Pick the decorative frame style. Override redirect windows get
	 * created as undecorated popups if they have no transient parent,
	 * otherwise they are children. This allows splash screens to operate
	 * as an independent window, while having dropdows (like for a
	 * combobox) not grab focus away from their parent. Transient windows
	 * get a modal dialog frame. Neither override, nor transient windows
	 * appear in the Windows taskbar. Note that a transient window does
	 * not resize by default, so we need to explicitly add the
	 * WS_THICKFRAME style if we want it to be resizeable.
	 */

	if (winPtr->atts.override_redirect) {
	    wmPtr->style = WM_OVERRIDE_STYLE;
	    wmPtr->exStyle = EX_OVERRIDE_STYLE;

	    /*
	     * Parent must be desktop even if we have a transient parent.
	     */

	    parentHWND = GetDesktopWindow();
	    if (wmPtr->masterPtr) {
		wmPtr->style |= WS_CHILD;
	    } else {
		wmPtr->style |= WS_POPUP;
	    }
	} else if (wmPtr->flags & WM_FULLSCREEN) {
	    wmPtr->style = WM_FULLSCREEN_STYLE;
	    wmPtr->exStyle = EX_FULLSCREEN_STYLE;
	} else if (wmPtr->masterPtr) {
	    wmPtr->style = WM_TRANSIENT_STYLE;
	    wmPtr->exStyle = EX_TRANSIENT_STYLE;
	    parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->masterPtr));
	    if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
		    (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) {
		wmPtr->style |= WS_THICKFRAME;
	    }
	} else {
	    wmPtr->style = WM_TOPLEVEL_STYLE;
	    wmPtr->exStyle = EX_TOPLEVEL_STYLE;
	}

	wmPtr->style |= wmPtr->styleConfig;
	wmPtr->exStyle |= wmPtr->exStyleConfig;

	if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
		&& (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
	    wmPtr->style &= ~ (WS_MAXIMIZEBOX | WS_SIZEBOX);
	}

	/*
	 * Compute the geometry of the parent and child windows.
	 */

	wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING;
	UpdateGeometryInfo((ClientData)winPtr);
	wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING);

	width = wmPtr->borderWidth + winPtr->changes.width;
	height = wmPtr->borderHeight + winPtr->changes.height;

	/*
	 * Set the initial position from the user or program specified
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129



2130
2131
2132

2133
2134
2135
2136
2137

2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212

2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318

	/*
	 * Create the containing window, and set the user data to point to the
	 * TkWindow.
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_DStringInit(&titleString);
	Tcl_UtfToWCharDString(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), -1, &titleString);

	wmPtr->wrapper = CreateWindowExW(wmPtr->exStyle,
		TK_WIN_TOPLEVEL_CLASS_NAME,



		(LPCWSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);

	Tcl_DStringFree(&titleString);
	SetWindowLongPtrW(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr);
	tsdPtr->createWindow = NULL;

	if (wmPtr->exStyleConfig & WS_EX_LAYERED) {

	    /*
	     * The user supplies a double from [0..1], but Windows wants an
	     * int (transparent) 0..255 (opaque), so do the translation. Add
	     * the 0.5 to round the value.
	     */

	    SetLayeredWindowAttributes((HWND) wmPtr->wrapper,
		    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
		    (unsigned)(LWA_ALPHA | (wmPtr->crefObj?LWA_COLORKEY:0)));
	} else {
	    /*
	     * Layering not used or supported.
	     */

	    wmPtr->alpha = 1.0;
	    if (wmPtr->crefObj) {
		Tcl_DecrRefCount(wmPtr->crefObj);
		wmPtr->crefObj = NULL;
	    }
	}

	place.length = sizeof(WINDOWPLACEMENT);
	GetWindowPlacement(wmPtr->wrapper, &place);
	wmPtr->x = place.rcNormalPosition.left;
	wmPtr->y = place.rcNormalPosition.top;

	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    TkInstallFrameMenu((Tk_Window) winPtr);
	}

	if (oldWrapper && (oldWrapper != wmPtr->wrapper)
		&& !(wmPtr->exStyle & WS_EX_TOPMOST)) {
	    /*
	     * We will adjust wrapper to have the same Z order as oldWrapper
	     * if it isn't a TOPMOST window.
	     */

	    nextHWND = GetNextWindow(oldWrapper, GW_HWNDPREV);
	}
    }

    /*
     * Now we need to reparent the contained window and set its style
     * appropriately. Be sure to update the style first so that Windows
     * doesn't try to set the focus to the child window.
     */

    SetWindowLongPtrW(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

    if (winPtr->flags & TK_EMBEDDED) {
	SetWindowLongPtrW(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc);
    }

    SetParent(child, wmPtr->wrapper);
    if (oldWrapper) {
	hSmallIcon = (HICON)
		SendMessageW(oldWrapper, WM_GETICON, ICON_SMALL, (LPARAM)NULL);
	hBigIcon = (HICON)
		SendMessageW(oldWrapper, WM_GETICON, ICON_BIG, (LPARAM) NULL);
    }

    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
	SetWindowLongPtrW(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0);

	if (wmPtr->numTransients > 0) {
	    /*
	     * Unset the current wrapper as the parent for all transient
	     * children for whom this is the container
	     */

	    WmInfo *wmPtr2;

	    childStateInfo = (int *)ckalloc(wmPtr->numTransients * sizeof(int));

	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->containerPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    childStateInfo[state++] = wmPtr2->hints.initial_state;
		    SetParent(TkWinGetHWND(wmPtr2->winPtr->window), NULL);
		}
	    }
	}

	/*
	 * Remove the menubar before destroying the window so the menubar
	 * isn't destroyed.
	 */

	SetMenu(oldWrapper, NULL);
	DestroyWindow(oldWrapper);
    }

    wmPtr->flags &= ~WM_NEVER_MAPPED;
    if (winPtr->flags & TK_EMBEDDED &&
	    SendMessageW(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0)) {
	SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ,
		Tk_ReqWidth((Tk_Window) winPtr),
		Tk_ReqHeight((Tk_Window) winPtr));
	SendMessageW(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu,
		(LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr));
    }

    /*
     * Force an initial transition from withdrawn to the real initial state.
     * Set the Z order based on previous wrapper before we set the state.
     */

    state = wmPtr->hints.initial_state;
    wmPtr->hints.initial_state = WithdrawnState;
    if (nextHWND) {
	SetWindowPos(wmPtr->wrapper, nextHWND, 0, 0, 0, 0,
		SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		|SWP_NOOWNERZORDER);
    }
    TkpWmSetState(winPtr, state);
    wmPtr->hints.initial_state = state;

    if (hSmallIcon != NULL) {
	SendMessageW(wmPtr->wrapper, WM_SETICON, ICON_SMALL,
		(LPARAM) hSmallIcon);
    }
    if (hBigIcon != NULL) {
	SendMessageW(wmPtr->wrapper, WM_SETICON, ICON_BIG, (LPARAM) hBigIcon);
    }

    /*
     * If we are embedded then force a mapping of the window now, because we
     * do not necessarily own the wrapper and may not get another opportunity
     * to map ourselves. We should not be in either iconified or zoomed states
     * when we get here, so it is safe to just check for TK_EMBEDDED without
     * checking what state we are supposed to be in (default to NormalState).
     */

    if (winPtr->flags & TK_EMBEDDED) {
	if (state+1 != SendMessageW(wmPtr->wrapper, TK_STATE, state, 0)) {
	    TkpWmSetState(winPtr, NormalState);
	    wmPtr->hints.initial_state = NormalState;
	}
	XMapWindow(winPtr->display, winPtr->window);
    }

    /*
     * Set up menus on the wrapper if required.
     */

    if (wmPtr->hMenu != NULL) {
	wmPtr->flags |= WM_SYNC_PENDING;
	SetMenu(wmPtr->wrapper, wmPtr->hMenu);
	wmPtr->flags &= ~WM_SYNC_PENDING;
    }

    if (childStateInfo) {
	if (wmPtr->numTransients > 0) {
	    /*
	     * Reset all transient children for whom this is the container.
	     */

	    WmInfo *wmPtr2;

	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->containerPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    UpdateWrapper(wmPtr2->winPtr);
		    TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
		}
	    }
	}

	ckfree(childStateInfo);
    }

    /*
     * If this is the first window created by the application, then we should
     * activate the initial window. Otherwise, if this had the focus, we need
     * to restore that.
     * XXX: Rewrapping generates a <FocusOut> and <FocusIn> that would best be







<
|


<
|
>
>
>
|


>

|


|
>






|






<












|

<


















|



|




|
|
|
|




|




|




|
>



|

















|
|
|
|
|
|



















|
<


|











|



















|







|







|







2178
2179
2180
2181
2182
2183
2184

2185
2186
2187

2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228

2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322

2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380

	/*
	 * Create the containing window, and set the user data to point to the
	 * TkWindow.
	 */

	tsdPtr->createWindow = winPtr;

	Tcl_WinUtfToTChar(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), -1, &titleString);


	Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString);

	wmPtr->wrapper = (*tkWinProcs->createWindowEx)(wmPtr->exStyle,
		(LPCTSTR) Tcl_DStringValue(&classString),
		(LPCTSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&classString);
	Tcl_DStringFree(&titleString);
	SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (INT_PTR) winPtr);
	tsdPtr->createWindow = NULL;

	if ((wmPtr->exStyleConfig & WS_EX_LAYERED)
		&& setLayeredWindowAttributesProc != NULL) {
	    /*
	     * The user supplies a double from [0..1], but Windows wants an
	     * int (transparent) 0..255 (opaque), so do the translation. Add
	     * the 0.5 to round the value.
	     */

	    setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
		    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
		    (unsigned)(LWA_ALPHA | (wmPtr->crefObj?LWA_COLORKEY:0)));
	} else {
	    /*
	     * Layering not used or supported.
	     */

	    wmPtr->alpha = 1.0;
	    if (wmPtr->crefObj) {
		Tcl_DecrRefCount(wmPtr->crefObj);
		wmPtr->crefObj = NULL;
	    }
	}

	place.length = sizeof(WINDOWPLACEMENT);
	GetWindowPlacement(wmPtr->wrapper, &place);
	wmPtr->x = place.rcNormalPosition.left;
	wmPtr->y = place.rcNormalPosition.top;

	if( !(winPtr->flags & TK_ALREADY_DEAD) )
	    TkInstallFrameMenu((Tk_Window) winPtr);


	if (oldWrapper && (oldWrapper != wmPtr->wrapper)
		&& !(wmPtr->exStyle & WS_EX_TOPMOST)) {
	    /*
	     * We will adjust wrapper to have the same Z order as oldWrapper
	     * if it isn't a TOPMOST window.
	     */

	    nextHWND = GetNextWindow(oldWrapper, GW_HWNDPREV);
	}
    }

    /*
     * Now we need to reparent the contained window and set its style
     * appropriately. Be sure to update the style first so that Windows
     * doesn't try to set the focus to the child window.
     */

    SetWindowLongPtr(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

    if (winPtr->flags & TK_EMBEDDED) {
	SetWindowLongPtr(child, GWLP_WNDPROC, (INT_PTR) TopLevelProc);
    }

    SetParent(child, wmPtr->wrapper);
    if (oldWrapper) {
	hSmallIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_SMALL,
		(LPARAM) NULL);
	hBigIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_BIG,
		(LPARAM) NULL);
    }

    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
	SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG) 0);

	if (wmPtr->numTransients > 0) {
	    /*
	     * Unset the current wrapper as the parent for all transient
	     * children for whom this is the master
	     */

	    WmInfo *wmPtr2;

	    childStateInfo = (int *)
		    ckalloc((unsigned) wmPtr->numTransients * sizeof(int));
	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    childStateInfo[state++] = wmPtr2->hints.initial_state;
		    SetParent(TkWinGetHWND(wmPtr2->winPtr->window), NULL);
		}
	    }
	}

	/*
	 * Remove the menubar before destroying the window so the menubar
	 * isn't destroyed.
	 */

	SetMenu(oldWrapper, NULL);
	DestroyWindow(oldWrapper);
    }

    wmPtr->flags &= ~WM_NEVER_MAPPED;
    if (winPtr->flags & TK_EMBEDDED
	    && SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM)child, 0)){
	SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ,
		Tk_ReqWidth((Tk_Window)winPtr),
		Tk_ReqHeight((Tk_Window)winPtr));
	SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu,
		(LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr));
    }

    /*
     * Force an initial transition from withdrawn to the real initial state.
     * Set the Z order based on previous wrapper before we set the state.
     */

    state = wmPtr->hints.initial_state;
    wmPtr->hints.initial_state = WithdrawnState;
    if (nextHWND) {
	SetWindowPos(wmPtr->wrapper, nextHWND, 0, 0, 0, 0,
		SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		|SWP_NOOWNERZORDER);
    }
    TkpWmSetState(winPtr, state);
    wmPtr->hints.initial_state = state;

    if (hSmallIcon != NULL) {
	SendMessage(wmPtr->wrapper,WM_SETICON,ICON_SMALL,(LPARAM)hSmallIcon);

    }
    if (hBigIcon != NULL) {
	SendMessage(wmPtr->wrapper,WM_SETICON,ICON_BIG,(LPARAM)hBigIcon);
    }

    /*
     * If we are embedded then force a mapping of the window now, because we
     * do not necessarily own the wrapper and may not get another opportunity
     * to map ourselves. We should not be in either iconified or zoomed states
     * when we get here, so it is safe to just check for TK_EMBEDDED without
     * checking what state we are supposed to be in (default to NormalState).
     */

    if (winPtr->flags & TK_EMBEDDED) {
	if(state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) {
	    TkpWmSetState(winPtr, NormalState);
	    wmPtr->hints.initial_state = NormalState;
	}
	XMapWindow(winPtr->display, winPtr->window);
    }

    /*
     * Set up menus on the wrapper if required.
     */

    if (wmPtr->hMenu != NULL) {
	wmPtr->flags |= WM_SYNC_PENDING;
	SetMenu(wmPtr->wrapper, wmPtr->hMenu);
	wmPtr->flags &= ~WM_SYNC_PENDING;
    }

    if (childStateInfo) {
	if (wmPtr->numTransients > 0) {
	    /*
	     * Reset all transient children for whom this is the master.
	     */

	    WmInfo *wmPtr2;

	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    UpdateWrapper(wmPtr2->winPtr);
		    TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
		}
	    }
	}

	ckfree((char *) childStateInfo);
    }

    /*
     * If this is the first window created by the application, then we should
     * activate the initial window. Otherwise, if this had the focus, we need
     * to restore that.
     * XXX: Rewrapping generates a <FocusOut> and <FocusIn> that would best be
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370

2371
2372
2373
2374
2375
2376
2377
2378
 */

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	InitWm();
    }

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Don't map a transient if the container is not mapped.
	 */


	if (wmPtr->containerPtr != NULL && !Tk_IsMapped(wmPtr->containerPtr)) {
	    wmPtr->hints.initial_state = WithdrawnState;
	    return;
	}
    } else {
	if (wmPtr->hints.initial_state == WithdrawnState) {
	    return;
	}







|









|


>
|







2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
 */

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	InitWm();
    }

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Don't map a transient if the master is not mapped.
	 */

	if (wmPtr->masterPtr != NULL &&
		!Tk_IsMapped(wmPtr->masterPtr)) {
	    wmPtr->hints.initial_state = WithdrawnState;
	    return;
	}
    } else {
	if (wmPtr->hints.initial_state == WithdrawnState) {
	    return;
	}
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
    } else if (state == IconicState) {
	cmd = SW_SHOWMINNOACTIVE;
    } else if (state == NormalState) {
	cmd = SW_SHOWNOACTIVATE;
    } else if (state == ZoomState) {
	cmd = SW_SHOWMAXIMIZED;
    } else {
    	goto setStateEnd;
    }

    ShowWindow(wmPtr->wrapper, cmd);
    wmPtr->flags &= ~WM_SYNC_PENDING;
setStateEnd:
    return 1;
}







|







2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
    } else if (state == IconicState) {
	cmd = SW_SHOWMINNOACTIVE;
    } else if (state == NormalState) {
	cmd = SW_SHOWNOACTIVATE;
    } else if (state == ZoomState) {
	cmd = SW_SHOWMAXIMIZED;
    } else {
	goto setStateEnd;
    }

    ShowWindow(wmPtr->wrapper, cmd);
    wmPtr->flags &= ~WM_SYNC_PENDING;
setStateEnd:
    return 1;
}
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
 *--------------------------------------------------------------
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    WmInfo *wmPtr2;

    if (wmPtr == NULL) {
	return;
    }

    /*
     * Clean up event related window info.
     */

    if (winPtr->dispPtr->firstWmPtr == wmPtr) {
	winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr;
    } else {
	WmInfo *prevPtr;

	for (prevPtr = winPtr->dispPtr->firstWmPtr; ;
		prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("couldn't unlink window in TkWmDeadWindow");
	    }
	    if (prevPtr->nextPtr == wmPtr) {
		prevPtr->nextPtr = wmPtr->nextPtr;
		break;
	    }
	}
    }

    /*
     * Reset all transient windows whose container is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	 wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->containerPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, wmPtr2->winPtr);
	    wmPtr2->containerPtr = NULL;
	    if ((wmPtr2->wrapper != NULL)
		    && !(wmPtr2->flags & (WM_NEVER_MAPPED))) {
		UpdateWrapper(wmPtr2->winPtr);
	    }
	}
    }
    if (wmPtr->numTransients != 0)







|













|
<













|




|

|

|
|







2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661

2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
 *--------------------------------------------------------------
 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    WmInfo *wmPtr2;

    if (wmPtr == NULL) {
	return;
    }

    /*
     * Clean up event related window info.
     */

    if (winPtr->dispPtr->firstWmPtr == wmPtr) {
	winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr;
    } else {
	register WmInfo *prevPtr;

	for (prevPtr = winPtr->dispPtr->firstWmPtr; ;
		prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("couldn't unlink window in TkWmDeadWindow");
	    }
	    if (prevPtr->nextPtr == wmPtr) {
		prevPtr->nextPtr = wmPtr->nextPtr;
		break;
	    }
	}
    }

    /*
     * Reset all transient windows whose master is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	 wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->masterPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, (ClientData) wmPtr2->winPtr);
	    wmPtr2->masterPtr = NULL;
	    if ((wmPtr2->wrapper != NULL)
		    && !(wmPtr2->flags & (WM_NEVER_MAPPED))) {
		UpdateWrapper(wmPtr2->winPtr);
	    }
	}
    }
    if (wmPtr->numTransients != 0)
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr;

	protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree(wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    if (wmPtr->containerPtr != NULL) {
	wmPtr2 = wmPtr->containerPtr->wmInfoPtr;

	/*
	 * If we had a container, tell them that we aren't tied to them anymore.
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
		VisibilityChangeMask|StructureNotifyMask,
		WmWaitVisibilityOrMapProc, winPtr);
	wmPtr->containerPtr = NULL;
    }
    if (wmPtr->crefObj != NULL) {
	Tcl_DecrRefCount(wmPtr->crefObj);
	wmPtr->crefObj = NULL;
    }

    /*
     * Destroy the decorative frame window.
     */

    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (wmPtr->wrapper != NULL) {
	    DestroyWindow(wmPtr->wrapper);
	} else if (winPtr->window) {
	    DestroyWindow(Tk_GetHWND(winPtr->window));
	}
    } else {
	if (wmPtr->wrapper != NULL) {
	    SendMessageW(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	}
    }
    if (wmPtr->iconPtr != NULL) {
	/*
	 * This may delete the icon resource data. I believe we should do this
	 * after destroying the decorative frame, because the decorative frame
	 * is using this icon.
	 */

	DecrIconRefCount(wmPtr->iconPtr);
    }

    ckfree(wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * TkWmSetClass --







|


|


|


|

|
|


|





|

|
|


















|












|







2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr;

	protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
    }
    if (wmPtr->masterPtr != NULL) {
	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;

	/*
	 * If we had a master, tell them that we aren't tied to them anymore.
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
		VisibilityChangeMask|StructureNotifyMask,
		WmWaitVisibilityOrMapProc, (ClientData) winPtr);
	wmPtr->masterPtr = NULL;
    }
    if (wmPtr->crefObj != NULL) {
	Tcl_DecrRefCount(wmPtr->crefObj);
	wmPtr->crefObj = NULL;
    }

    /*
     * Destroy the decorative frame window.
     */

    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (wmPtr->wrapper != NULL) {
	    DestroyWindow(wmPtr->wrapper);
	} else if (winPtr->window) {
	    DestroyWindow(Tk_GetHWND(winPtr->window));
	}
    } else {
	if (wmPtr->wrapper != NULL) {
	    SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	}
    }
    if (wmPtr->iconPtr != NULL) {
	/*
	 * This may delete the icon resource data. I believe we should do this
	 * after destroying the decorative frame, because the decorative frame
	 * is using this icon.
	 */

	DecrIconRefCount(wmPtr->iconPtr);
    }

    ckfree((char *) wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * TkWmSetClass --
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
 *--------------------------------------------------------------
 */

void
TkWmSetClass(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    (void)winPtr;

    /* Do nothing */
    return;
}

/*
 *----------------------------------------------------------------------
 *







<
<







2800
2801
2802
2803
2804
2805
2806


2807
2808
2809
2810
2811
2812
2813
 *--------------------------------------------------------------
 */

void
TkWmSetClass(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{


    /* Do nothing */
    return;
}

/*
 *----------------------------------------------------------------------
 *
2761
2762
2763
2764
2765
2766
2767

2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823

2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */


int
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 = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE,
	WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index;
    TkSizeT length;
    const char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = TkGetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && !strncmp(argv1, "tracing", length)
	    && (length >= 3)) {
	int wmTracing;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (dispPtr->flags & TK_DISPLAY_WM_TRACING) != 0));

	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (wmTracing) {
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr) && (index != WMOPT_MANAGE)
	    && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:







>







|
|












|
<



|
<




|
<
|









|
|








|
|
>













|
|











|
|
|
|
<
<







2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850

2851
2852
2853
2854

2855
2856
2857
2858
2859

2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912


2913
2914
2915
2916
2917
2918
2919
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
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 = (Tk_Window) clientData;
    static const char *optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, WMOPT_FRAME,

	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,

	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index, length;

    char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && !strncmp(argv1, "tracing", (unsigned) length)
	    && (length >= 3)) {
	int wmTracing;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetResult(interp,
		    ((dispPtr->flags & TK_DISPLAY_WM_TRACING) ? "on" : "off"),
		    TCL_STATIC);
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (wmTracing) {
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr) &&
	    (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", NULL);


	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case WMOPT_ASPECT:
	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ATTRIBUTES:
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;
    (void)tkwin;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewWideIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewWideIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;







|

<








|

|
|
<
|
|













<
|
<







3005
3006
3007
3008
3009
3010
3011
3012
3013

3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025

3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040

3041

3042
3043
3044
3045
3046
3047
3048
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;


    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PAspect) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
		    wmPtr->minAspect.y, wmPtr->maxAspect.x,

		    wmPtr->maxAspect.y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) {

	    Tcl_SetResult(interp, "aspect number can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
	wmPtr->sizeHintsFlags |= PAspect;
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    const char *string;
    int i, boolean;
    TkSizeT length;
    int config_fullscreen = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;

    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"







|

|
|
<







3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082

3083
3084
3085
3086
3087
3088
3089
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    char *string;
    int i, boolean, length;

    int config_fullscreen = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;

    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-transparentcolor", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-disabled", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((style & WS_DISABLED) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-fullscreen", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((wmPtr->flags & WM_FULLSCREEN) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = TkGetStringFromObj(objv[i], &length);
	if ((length < 2) || (string[0] != '-')) {
	    goto configArgs;
	}
	if (strncmp(string, "-disabled", length) == 0) {
	    stylePtr = &style;
	    styleBit = WS_DISABLED;
	} else if ((strncmp(string, "-alpha", length) == 0)
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			length) == 0))) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_LAYERED;
	} else if (strncmp(string, "-fullscreen", length) == 0) {
	    config_fullscreen = 1;
	    styleBit = 0;
	} else if ((length > 3)
		&& (strncmp(string, "-toolwindow", length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOOLWINDOW;
	    if (objc != 4) {
		/*
		 * Changes to toolwindow style require an update
		 */
		updatewrapper = 1;
	    }
	} else if ((length > 3)
		&& (strncmp(string, "-topmost", length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOPMOST;
	    if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set topmost flag on %s: it is an embedded window",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "TOPMOST", NULL);
		return TCL_ERROR;
	    }
	} else {
	    goto configArgs;
	}
	if (styleBit == WS_EX_LAYERED) {
	    if (objc == 4) {







|



|



|



|




|



|


|

|


|



|









|



<
|
|
<







3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158

3159
3160

3161
3162
3163
3164
3165
3166
3167
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-transparentcolor", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-disabled", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((style & WS_DISABLED)));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-fullscreen", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((wmPtr->flags & WM_FULLSCREEN)));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((exStyle & WS_EX_TOOLWINDOW)));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((exStyle & WS_EX_TOPMOST)));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = Tcl_GetStringFromObj(objv[i], &length);
	if ((length < 2) || (string[0] != '-')) {
	    goto configArgs;
	}
	if (strncmp(string, "-disabled", (unsigned) length) == 0) {
	    stylePtr = &style;
	    styleBit = WS_DISABLED;
	} else if ((strncmp(string, "-alpha", (unsigned) length) == 0)
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			(unsigned) length) == 0))) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_LAYERED;
	} else if (strncmp(string, "-fullscreen", (unsigned) length) == 0) {
	    config_fullscreen = 1;
	    styleBit = 0;
	} else if ((length > 3)
		&& (strncmp(string, "-toolwindow", (unsigned) length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOOLWINDOW;
	    if (objc != 4) {
		/*
		 * Changes to toolwindow style require an update
		 */
		updatewrapper = 1;
	    }
	} else if ((length > 3)
		&& (strncmp(string, "-topmost", (unsigned) length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOPMOST;
	    if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {

		Tcl_AppendResult(interp, "can't set topmost flag on ",
			winPtr->pathName, ": it is an embedded window", NULL);

		return TCL_ERROR;
	    }
	} else {
	    goto configArgs;
	}
	if (styleBit == WS_EX_LAYERED) {
	    if (objc == 4) {
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
		    if (dval < 0.0) {
			dval = 0;
		    } else if (dval > 1.0) {
			dval = 1;
		    }
		    wmPtr->alpha = dval;
		} else {			/* -transparentcolor */
		    const char *crefstr = TkGetStringFromObj(objv[i+1], &length);

		    if (length == 0) {
			/* reset to no transparent color */
			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			    wmPtr->crefObj = NULL;
			}







|







3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
		    if (dval < 0.0) {
			dval = 0;
		    } else if (dval > 1.0) {
			dval = 1;
		    }
		    wmPtr->alpha = dval;
		} else {			/* -transparentcolor */
		    char *crefstr = Tcl_GetStringFromObj(objv[i+1], &length);

		    if (length == 0) {
			/* reset to no transparent color */
			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			    wmPtr->crefObj = NULL;
			}
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181

3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
				(BYTE) (cPtr->blue >> 8));
			Tk_FreeColor(cPtr);
		    }
		}

		/*
		 * Only ever add the WS_EX_LAYERED bit, as it can cause
		 * flashing to change this window style. This allows things
		 * like fading tooltips to avoid flash ugliness without
		 * forcing all window to be layered.
		 */

		if ((wmPtr->alpha < 1.0) || (wmPtr->crefObj != NULL)) {
		    *stylePtr |= styleBit;
		}

		if (wmPtr->wrapper != NULL) {
		    /*
		     * Set the window directly regardless of UpdateWrapper.
		     * The user supplies a double from [0..1], but Windows
		     * wants an int (transparent) 0..255 (opaque), so do the
		     * translation. Add the 0.5 to round the value.
		     */

		    if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) {
			SetWindowLongPtrW(wmPtr->wrapper, GWL_EXSTYLE,
				*stylePtr);
		    }
		    SetLayeredWindowAttributes((HWND) wmPtr->wrapper,
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
	    }
	} else {
	    if ((i < objc-1)
		    && Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean)
			    != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (config_fullscreen) {
		if (objc == 4) {
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		}
		config_fullscreen = 0;
	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
	    }
	}
	if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) {
	    /*
	     * Force the topmost position aspect to ensure that switching
	     * between (no)topmost reflects properly when rewrapped.
	     */

	    SetWindowPos(wmPtr->wrapper,
		    ((exStyle & WS_EX_TOPMOST) ?
			    HWND_TOPMOST : HWND_NOTOPMOST), 0, 0, 0, 0,
		    SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		    |SWP_NOOWNERZORDER);
	}
    }







|



<



>
|








|


|






|
|
|




|
|






|
|











<







3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227

3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278

3279
3280
3281
3282
3283
3284
3285
				(BYTE) (cPtr->blue >> 8));
			Tk_FreeColor(cPtr);
		    }
		}

		/*
		 * Only ever add the WS_EX_LAYERED bit, as it can cause
		 * flashing to change this window style.  This allows things
		 * like fading tooltips to avoid flash ugliness without
		 * forcing all window to be layered.
		 */

		if ((wmPtr->alpha < 1.0) || (wmPtr->crefObj != NULL)) {
		    *stylePtr |= styleBit;
		}
		if ((setLayeredWindowAttributesProc != NULL)
			&& (wmPtr->wrapper != NULL)) {
		    /*
		     * Set the window directly regardless of UpdateWrapper.
		     * The user supplies a double from [0..1], but Windows
		     * wants an int (transparent) 0..255 (opaque), so do the
		     * translation. Add the 0.5 to round the value.
		     */

		    if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) {
			SetWindowLongPtr(wmPtr->wrapper, GWL_EXSTYLE,
				*stylePtr);
		    }
		    setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
	    }
	} else {
	    if ((i < objc-1) &&
		    (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean)
			    != TCL_OK)) {
		return TCL_ERROR;
	    }
	    if (config_fullscreen) {
		if (objc == 4) {
		    Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
			(wmPtr->flags & WM_FULLSCREEN));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		}
		config_fullscreen = 0;
	    } else if (objc == 4) {
		Tcl_SetIntObj(Tcl_GetObjResult(interp),
			((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
	    }
	}
	if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) {
	    /*
	     * Force the topmost position aspect to ensure that switching
	     * between (no)topmost reflects properly when rewrapped.
	     */

	    SetWindowPos(wmPtr->wrapper,
		    ((exStyle & WS_EX_TOPMOST) ?
			    HWND_TOPMOST : HWND_NOTOPMOST), 0, 0, 0, 0,
		    SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		    |SWP_NOOWNERZORDER);
	}
    }
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
		UpdateWrapper(winPtr);
	    }
	}
    }
    if (fullscreen_attr_changed) {
	if (fullscreen_attr) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\":"
			" override-redirect flag is set", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Check max width and height if set by the user, don't worry
	     * about the default values since they will likely be smaller than
	     * screen width/height.
	     */

	    if (((wmPtr->maxWidth > 0) &&
		    (WidthOfScreen(Tk_Screen(winPtr)) > wmPtr->maxWidth)) ||
		    ((wmPtr->maxHeight > 0) &&
		    (HeightOfScreen(Tk_Screen(winPtr)) > wmPtr->maxHeight))) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\":"
			" max width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "SMALL_MAX", NULL);
		return TCL_ERROR;
	    }
	}

	TkpWmSetFullScreen(winPtr, fullscreen_attr);
    }








|
|
|
<
|













|
|
|
|







3307
3308
3309
3310
3311
3312
3313
3314
3315
3316

3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
		UpdateWrapper(winPtr);
	    }
	}
    }
    if (fullscreen_attr_changed) {
	if (fullscreen_attr) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_AppendResult(interp,
			"can't set fullscreen attribute for \"",
			winPtr->pathName, "\": override-redirect flag is set",

			NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Check max width and height if set by the user, don't worry
	     * about the default values since they will likely be smaller than
	     * screen width/height.
	     */

	    if (((wmPtr->maxWidth > 0) &&
		    (WidthOfScreen(Tk_Screen(winPtr)) > wmPtr->maxWidth)) ||
		    ((wmPtr->maxHeight > 0) &&
		    (HeightOfScreen(Tk_Screen(winPtr)) > wmPtr->maxHeight))) {
		Tcl_AppendResult(interp,
			"can't set fullscreen attribute for \"",
			winPtr->pathName, "\": max width/height is too small",
			NULL);
		return TCL_ERROR;
	    }
	}

	TkpWmSetFullScreen(winPtr, fullscreen_attr);
    }

3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360
3361
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = TkGetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE"));
	    }
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)ckalloc(length + 1);

    memcpy(wmPtr->clientMachine, argv3, length + 1);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;

	if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
		!= 0) {
	    XSetWMClientMachine(winPtr->display, winPtr->window,
		    &textProp);







|
|
|
<







<
|



|


|









|

|
>
|







3363
3364
3365
3366
3367
3368
3369
3370
3371
3372

3373
3374
3375
3376
3377
3378
3379

3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {

	    Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree((char *) wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE"));
	    }
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)
	    ckalloc((unsigned) (length + 1));
    strcpy(wmPtr->clientMachine, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;

	if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
		!= 0) {
	    XSetWMClientMachine(winPtr->display, winPtr->window,
		    &textProp);
3386
3387
3388
3389
3390
3391
3392
3393
3394

3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420

3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2, **winPtr2Ptr = &winPtr2;

    int i, windowObjc, gotToplevel;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	resultObj = Tcl_NewObj();
	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj((Tk_Window) wmPtr->cmapList[i]));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow**)ckalloc((windowObjc + 1) * sizeof(TkWindow*));

    gotToplevel = 0;
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) winPtr2Ptr) != TCL_OK) {
	    ckfree(cmapList);
	    return TCL_ERROR;
	}
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
	    Tk_MakeWindowExist((Tk_Window) winPtr2);
	}
	cmapList[i] = winPtr2;
    }
    if (!gotToplevel) {
	wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
	cmapList[windowObjc] = winPtr;
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    if (wmPtr->cmapList != NULL) {
	ckfree(wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * Now we need to force the updated colormaps to be installed.
     */







|
|
>

|







<





<
|

<






|
>




|



















|







3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451

3452
3453
3454
3455
3456

3457
3458

3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList;
    TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
    int i, windowObjc, gotToplevel;
    Tcl_Obj **windowObjv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window) winPtr);

	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }

	    Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
	}

	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **) ckalloc((unsigned)
	    ((windowObjc+1)*sizeof(TkWindow*)));
    gotToplevel = 0;
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) winPtr2Ptr) != TCL_OK) {
	    ckfree((char *) cmapList);
	    return TCL_ERROR;
	}
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
	    Tk_MakeWindowExist((Tk_Window) winPtr2);
	}
	cmapList[i] = winPtr2;
    }
    if (!gotToplevel) {
	wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
	cmapList[windowObjc] = winPtr;
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    if (wmPtr->cmapList != NULL) {
	ckfree((char *)wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * Now we need to force the updated colormaps to be installed.
     */
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int cmdArgc;
    const char **cmdArgv;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {

	    char *merged = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(merged, -1));
	    ckfree(merged);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree(wmPtr->cmdArgv);
	    wmPtr->cmdArgv = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
	    }
	}
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree(wmPtr->cmdArgv);
    }
    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = cmdArgv;
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XSetCommand(winPtr->display, winPtr->window, (char **) cmdArgv, cmdArgc);
    }
    return TCL_OK;







|
|


<







>
|
<
<
<






|












|







3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536

3537
3538
3539
3540
3541
3542
3543
3544
3545



3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int cmdArgc;
    const char **cmdArgv;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    Tcl_SetResult(interp,
		    Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv), TCL_DYNAMIC);



	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree((char *) wmPtr->cmdArgv);
	    wmPtr->cmdArgv = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
	    }
	}
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = cmdArgv;
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XSetCommand(winPtr->display, winPtr->window, (char **) cmdArgv, cmdArgc);
    }
    return TCL_OK;
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't deiconify %s: the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
	return TCL_OK;
    }
    TkpWinToplevelDeiconify(winPtr);
    return TCL_OK;
}







|
<






<
|
|
<



|
|
|
<
<







3593
3594
3595
3596
3597
3598
3599
3600

3601
3602
3603
3604
3605
3606

3607
3608

3609
3610
3611
3612
3613
3614


3615
3616
3617
3618
3619
3620
3621
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessage(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
	    Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		    ": the container does not support the request", NULL);


	    return TCL_ERROR;
	}
	return TCL_OK;
    }
    TkpWinToplevelDeiconify(winPtr);
    return TCL_OK;
}
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626

3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL
    };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));

	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0,&index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }







|
|






<






<
|
>



|
|







3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655

3656
3657
3658
3659
3660
3661

3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *optionStrings[] = {
	"active", "passive", NULL
    };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {

	Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		TCL_STATIC);
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *dummy,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    (void)tkwin;
    (void)dummy;
    (void)objc;
    (void)objv;

    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFrameCmd --
 *
 *	This function is invoked to process the "wm frame" Tcl command. See
 *	the user documentation for details on what it does.







|
|
|
|
|
|

|
<
<
<
<






<
<
<
<
<
<








|
<







3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704




3705
3706
3707
3708
3709
3710






3711
3712
3713
3714
3715
3716
3717
3718
3719

3720
3721
3722
3723
3724
3725
3726
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel or Frame to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *const objv[];	/* Argument objects. */
{
    register Tk_Window frameWin = (Tk_Window)winPtr;





    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));






	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFrameCmd --
 *
 *	This function is invoked to process the "wm frame" Tcl command. See
 *	the user documentation for details on what it does.
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND hwnd;
    char buf[TCL_INTEGER_SPACE];
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_WindowId((Tk_Window) winPtr) == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    hwnd = wmPtr->wrapper;
    if (hwnd == NULL) {
	hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr));
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|


<












|
|







3738
3739
3740
3741
3742
3743
3744
3745
3746
3747

3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND hwnd;
    char buf[TCL_INTEGER_SPACE];


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_WindowId((Tk_Window) winPtr) == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    hwnd = wmPtr->wrapper;
    if (hwnd == NULL) {
	hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr));
    }
    sprintf(buf, "0x%x", PTR2INT(hwnd));
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776



3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794

3795

3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    const char *argv3;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }

    if (objc == 3) {



	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
	ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    int result = SendMessageW(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1);

	    wmPtr->x = result >> 16;
	    wmPtr->y = result & 0x0000ffff;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d",

		width, height, xSign, wmPtr->x, ySign, wmPtr->y));

	return TCL_OK;
    }

    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);
	return TCL_OK;
    }







|


|
<





<

>
>
>











|
|
<



|
>
|
>


<







3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793

3794
3795
3796
3797
3798

3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815

3816
3817
3818
3819
3820
3821
3822
3823
3824

3825
3826
3827
3828
3829
3830
3831
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    char *argv3;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	char buf[16 + TCL_INTEGER_SPACE * 4];
	int x, y;

	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
	ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
	if (wmPtr->gridWin != NULL) {
	    width = wmPtr->reqGridWidth + (winPtr->changes.width
		    - winPtr->reqWidth)/wmPtr->widthInc;
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	if(winPtr->flags & TK_EMBEDDED) {
	    int result = SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1);

	    wmPtr->x = result >> 16;
	    wmPtr->y = result & 0x0000ffff;
	}
	x = wmPtr->x;
	y = wmPtr->y;
	sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, x, ySign, y);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }

    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->width = -1;
	wmPtr->height = -1;
	WmUpdateGeom(wmPtr, winPtr);
	return TCL_OK;
    }
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;
    (void)tkwin;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    Tcl_Obj *results[4];

	    results[0] = Tcl_NewWideIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewWideIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewWideIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewWideIntObj(wmPtr->heightInc);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.







|

<








|

|
|
<
|
|







3853
3854
3855
3856
3857
3858
3859
3860
3861

3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873

3874
3875
3876
3877
3878
3879
3880
3881
3882
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;


    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & PBaseSize) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
		    wmPtr->reqGridHeight, wmPtr->widthInc,

		    wmPtr->heightInc);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;







<
|
<



<
|
<



<
|
<



<
|
<







3895
3896
3897
3898
3899
3900
3901

3902

3903
3904
3905

3906

3907
3908
3909

3910

3911
3912
3913

3914

3915
3916
3917
3918
3919
3920
3921
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {

	    Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (reqHeight < 0) {

	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (widthInc <= 0) {

	    Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	if (heightInc <= 0) {

	    Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);

	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    const char *argv3;
    TkSizeT length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }
    argv3 = TkGetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin2);
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = (char *)ckalloc(length + 1);
	memcpy(wmPtr->leaderName, argv3, length + 1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

|
|







|



|
















|
|







3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(tkwin2);
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->leaderName, argv3);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    const char *string;
    (void)tkwin;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?");
	return TCL_ERROR;
    } else if (objc == 5) {
	/*
	 * If we have 5 arguments, we must have a '-default' flag.
	 */

	const char *argv3 = Tcl_GetString(objv[3]);

	if (strcmp(argv3, "-default")) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "illegal option \"%s\" must be \"-default\"", argv3));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONBITMAP", "OPTION",NULL);
	    return TCL_ERROR;
	}
	useWinPtr = NULL;
    } else if (objc == 3) {
	/*
	 * No arguments were given.
	 */

	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
		    -1));
	}
	return TCL_OK;
    }

    string = Tcl_GetString(objv[objc-1]);
    if (*string == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {







|

|
<









|


|
|
<









|

|







4005
4006
4007
4008
4009
4010
4011
4012
4013
4014

4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028

4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    char *string;


    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?");
	return TCL_ERROR;
    } else if (objc == 5) {
	/*
	 * If we have 5 arguments, we must have a '-default' flag.
	 */

	char *argv3 = Tcl_GetString(objv[3]);

	if (strcmp(argv3, "-default")) {
	    Tcl_AppendResult(interp, "illegal option \"", argv3,
		    "\" must be \"-default\"", NULL);

	    return TCL_ERROR;
	}
	useWinPtr = NULL;
    } else if (objc == 3) {
	/*
	 * No arguments were given.
	 */

	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
		    TCL_STATIC);
	}
	return TCL_OK;
    }

    string = Tcl_GetString(objv[objc-1]);
    if (*string == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
	    /*
	     * We didn't manage to handle the argument as a valid icon. Try as
	     * a bitmap. First we must clear the error message which was
	     * placed in the interpreter.
	     */

	    Pixmap pixmap;

	    Tcl_ResetResult(interp);
	    pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, string);
	    if (pixmap == None) {
		return TCL_ERROR;
	    }
	    wmPtr->hints.icon_pixmap = pixmap;
	    wmPtr->hints.flags |= IconPixmapHint;







<







4092
4093
4094
4095
4096
4097
4098

4099
4100
4101
4102
4103
4104
4105
	    /*
	     * We didn't manage to handle the argument as a valid icon. Try as
	     * a bitmap. First we must clear the error message which was
	     * placed in the interpreter.
	     */

	    Pixmap pixmap;

	    Tcl_ResetResult(interp);
	    pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, string);
	    if (pixmap == None) {
		return TCL_ERROR;
	    }
	    wmPtr->hints.icon_pixmap = pixmap;
	    wmPtr->hints.flags |= IconPixmapHint;
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't iconify \"%s\": the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	    return TCL_ERROR;
	}
    }
    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;
    }
    if (wmPtr->containerPtr != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is a transient",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is an icon for \"%s\"",
		winPtr->pathName, Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    TkpWmSetState(winPtr, IconicState);
    return TCL_OK;
}

/*







|
<
<





|
|
|
<
<




|
|
<
<
<


|
|
|
<
<



|
<
|
<







4139
4140
4141
4142
4143
4144
4145
4146


4147
4148
4149
4150
4151
4152
4153
4154


4155
4156
4157
4158
4159
4160



4161
4162
4163
4164
4165


4166
4167
4168
4169

4170

4171
4172
4173
4174
4175
4176
4177
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if(!SendMessage(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
	    Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		    ": the container does not support the request", NULL);


	    return TCL_ERROR;
	}
    }
    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", NULL);



	return TCL_ERROR;
    }
    if (wmPtr->masterPtr != NULL) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", NULL);


	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,

		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }
    TkpWmSetState(winPtr, IconicState);
    return TCL_OK;
}

/*
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);







|

|







|

|







4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269

4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(wmPtr->iconName ? wmPtr->iconName : ""), -1));

	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = TkGetStringFromObj(objv[3], &length);
	wmPtr->iconName = (char *)ckalloc(length + 1);
	memcpy(wmPtr->iconName, argv3, length + 1);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    return TCL_OK;
}








|
|
|
<






|
|
>



|

|
|
|







4253
4254
4255
4256
4257
4258
4259
4260
4261
4262

4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetResult(interp,
		((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree((char *) wmPtr->iconName);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    return TCL_OK;
}

4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i, width, height, idx, bufferSize, startObj = 3;
    union {unsigned char *ptr; void *voidPtr;} bgraPixel;
    union {unsigned char *ptr; void *voidPtr;} bgraMask;
    BlockOfIconImagesPtr lpIR;
    WinIconPtr titlebaricon = NULL;
    HICON hIcon;
    unsigned size;
    BITMAPINFO bmInfo;
    ICONINFO iconInfo;
    (void)tkwin;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }








|






<







4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323

4324
4325
4326
4327
4328
4329
4330
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i, width, height, idx, bufferSize, startObj = 3;
    union {unsigned char *ptr; void *voidPtr;} bgraPixel;
    void *bgraMaskPtr;
    BlockOfIconImagesPtr lpIR;
    WinIconPtr titlebaricon = NULL;
    HICON hIcon;
    unsigned size;
    BITMAPINFO bmInfo;
    ICONINFO iconInfo;


    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }

4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }
    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use \"%s\" as iconphoto: not a photo image",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
	    return TCL_ERROR;
	}
    }

    /*
     * We have calculated the size of the data. Try to allocate the needed
     * memory space.
     */

    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr)attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }
    ZeroMemory(lpIR, size);

    lpIR->nNumImages = objc - startObj;

    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Don't use CreateIcon to create the icon, as it requires color
	 * bitmap data in device-dependent format. Instead we use
	 * CreateIconIndirect which takes device-independent bitmaps and
	 * converts them as required. Initialise icon info structure.
	 */

	ZeroMemory(&iconInfo, sizeof(iconInfo));
	iconInfo.fIcon = TRUE;

	/*
	 * Create device-independent color bitmap.
	 */

	ZeroMemory(&bmInfo, sizeof bmInfo);
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmInfo.bmiHeader.biWidth = width;
	bmInfo.bmiHeader.biHeight = -height;
	bmInfo.bmiHeader.biPlanes = 1;
	bmInfo.bmiHeader.biBitCount = 32;
	bmInfo.bmiHeader.biCompression = BI_RGB;

	iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraPixel.voidPtr, NULL, 0);
	if (!iconInfo.hbmColor) {
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create an iconphoto with image \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Convert the photo image data into BGRA format (RGBQUAD).
	 */

	bufferSize = height * width * 4;
	for (idx = 0 ; idx < bufferSize ; idx += 4) {
	    bgraPixel.ptr[idx] = block.pixelPtr[idx+2];
	    bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1];
	    bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0];
	    bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3];
	}

	/*
	 * Create a dummy mask bitmap. The contents of this don't appear to
	 * matter, as CreateIconIndirect will setup the icon mask based on the
	 * alpha channel in our color bitmap.
	 */

	bmInfo.bmiHeader.biBitCount = 1;

	iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraMask.voidPtr, NULL, 0);
	if (!iconInfo.hbmMask) {
	    DeleteObject(iconInfo.hbmColor);
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create mask bitmap for \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "MASK", NULL);
	    return TCL_ERROR;
	}

	ZeroMemory(bgraMask.ptr, width*height/8);

	/*
	 * Create an icon from the bitmaps.
	 */

	hIcon = CreateIconIndirect(&iconInfo);
	DeleteObject(iconInfo.hbmColor);
	DeleteObject(iconInfo.hbmMask);
	if (hIcon == NULL) {
	    /*
	     * XXX should free up created icons.
	     */

	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create icon for \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "ICON", NULL);
	    return TCL_ERROR;
	}
	lpIR->IconImages[i-startObj].Width = width;
	lpIR->IconImages[i-startObj].Height = height;
	lpIR->IconImages[i-startObj].Colors = 4;
	lpIR->IconImages[i-startObj].hIcon = hIcon;
    }

    titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) {
	/*
	 * We didn't use the titlebaricon after all.
	 */








|
|
<
<










|














|
|
|


|



|

<
|







|
|
|
|
<
|
|
<






<









|
|
|

<


|
|
|

|
<
|
|
<



|




<
|







|
<
|
|
<








|







4340
4341
4342
4343
4344
4345
4346
4347
4348


4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384

4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396

4397
4398

4399
4400
4401
4402
4403
4404

4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417

4418
4419
4420
4421
4422
4423
4424

4425
4426

4427
4428
4429
4430
4431
4432
4433
4434

4435
4436
4437
4438
4439
4440
4441
4442
4443

4444
4445

4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }
    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]),
		    "\" as iconphoto: not a photo image", NULL);


	    return TCL_ERROR;
	}
    }

    /*
     * We have calculated the size of the data. Try to allocate the needed
     * memory space.
     */

    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr) attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }
    ZeroMemory(lpIR, size);

    lpIR->nNumImages = objc - startObj;

    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Don't use CreateIcon to create the icon, as it requires color
	 * bitmap data in device-dependent format.  Instead we use
	 * CreateIconIndirect which takes device-independent bitmaps
	 * and converts them as required.  Initialise icon info structure.
	 */

	ZeroMemory( &iconInfo, sizeof iconInfo );
	iconInfo.fIcon = TRUE;

	/*
	 * Create device-independant color bitmap.
	 */

	ZeroMemory(&bmInfo,sizeof bmInfo);
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmInfo.bmiHeader.biWidth = width;
	bmInfo.bmiHeader.biHeight = -height;
	bmInfo.bmiHeader.biPlanes = 1;
	bmInfo.bmiHeader.biBitCount = 32;
	bmInfo.bmiHeader.biCompression = BI_RGB;

	iconInfo.hbmColor = CreateDIBSection( NULL, &bmInfo,
	    DIB_RGB_COLORS, &bgraPixel.voidPtr, NULL, 0 );
	if ( !iconInfo.hbmColor ) {
	    ckfree((char *) lpIR);

	    Tcl_AppendResult(interp, "failed to create color bitmap for \"",
		    Tcl_GetString(objv[i]), "\"", NULL);

	    return TCL_ERROR;
	}

	/*
	 * Convert the photo image data into BGRA format (RGBQUAD).
	 */

	bufferSize = height * width * 4;
	for (idx = 0 ; idx < bufferSize ; idx += 4) {
	    bgraPixel.ptr[idx] = block.pixelPtr[idx+2];
	    bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1];
	    bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0];
	    bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3];
	}

	/*
	 * Create a dummy mask bitmap.  The contents of this don't
	 * appear to matter, as CreateIconIndirect will setup the icon
	 * mask based on the alpha channel in our color bitmap.
	 */

	bmInfo.bmiHeader.biBitCount = 1;

	iconInfo.hbmMask = CreateDIBSection( NULL, &bmInfo,
	    DIB_RGB_COLORS, &bgraMaskPtr, NULL, 0 );
	if ( !iconInfo.hbmMask ) {
	    DeleteObject(iconInfo.hbmColor);
	    ckfree((char *) lpIR);

	    Tcl_AppendResult(interp, "failed to create mask bitmap for \"",
		    Tcl_GetString(objv[i]), "\"", NULL);

	    return TCL_ERROR;
	}

	ZeroMemory( bgraMaskPtr, width*height/8 );

	/*
	 * Create an icon from the bitmaps.
	 */

	hIcon = CreateIconIndirect( &iconInfo);
	DeleteObject(iconInfo.hbmColor);
	DeleteObject(iconInfo.hbmMask);
	if (hIcon == NULL) {
	    /*
	     * XXX should free up created icons.
	     */

	    ckfree((char *) lpIR);

	    Tcl_AppendResult(interp, "failed to create icon for \"",
		    Tcl_GetString(objv[i]), "\"", NULL);

	    return TCL_ERROR;
	}
	lpIR->IconImages[i-startObj].Width = width;
	lpIR->IconImages[i-startObj].Height = height;
	lpIR->IconImages[i-startObj].Colors = 4;
	lpIR->IconImages[i-startObj].hIcon = hIcon;
    }

    titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) {
	/*
	 * We didn't use the titlebaricon after all.
	 */

4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
	    Tcl_Obj *results[2];

	    results[0] = Tcl_NewWideIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewWideIntObj(wmPtr->hints.icon_y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    return TCL_OK;







|

<







|

|
|
|







|







4486
4487
4488
4489
4490
4491
4492
4493
4494

4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
	    char buf[TCL_INTEGER_SPACE * 2];

	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
		    wmPtr->hints.icon_y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_x = x;
	wmPtr->hints.icon_y = y;
	wmPtr->hints.flags |= IconPositionHint;
    }
    return TCL_OK;
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*







|










|







4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->icon != NULL) {
	    Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use %s as icon window: not at top level",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "INNER", NULL);
	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is already an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	    wmPtr3->iconFor = NULL;

	    /*







|
|
<
<




|
|
<
|







4578
4579
4580
4581
4582
4583
4584
4585
4586


4587
4588
4589
4590
4591
4592

4593
4594
4595
4596
4597
4598
4599
4600
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
		    " as icon window: not at top level", NULL);


	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
		    " is already an icon for ", Tk_PathName(wmPtr2->iconFor),

		    NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	    wmPtr3->iconFor = NULL;

	    /*
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;
    (void)objc;
    (void)objv;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a frame,"
		    " labelframe or toplevel", Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	winPtr->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
	RemapWindows(winPtr, NULL);
	if (wmPtr == NULL) {







|
|
|
|
|
|

|
|
<
<
<



|
|
|
<







4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657



4658
4659
4660
4661
4662
4663

4664
4665
4666
4667
4668
4669
4670
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel or Frame to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *const objv[];	/* Argument objects. */
{
    register Tk_Window frameWin = (Tk_Window)winPtr;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;




    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_AppendResult(interp, "window \"",
		Tk_PathName(frameWin), "\" is not manageable: must be "
		"a frame, labelframe or toplevel", NULL);

	    return TCL_ERROR;
	}
	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	winPtr->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
	RemapWindows(winPtr, NULL);
	if (wmPtr == NULL) {
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;







|

<






|


<
|
|







4702
4703
4704
4705
4706
4707
4708
4709
4710

4711
4712
4713
4714
4715
4716
4717
4718
4719

4720
4721
4722
4723
4724
4725
4726
4727
4728
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];

	GetMaxSize(wmPtr, &width, &height);

	sprintf(buf, "%d %d", width, height);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;







|

<






|


<
|
|







4752
4753
4754
4755
4756
4757
4758
4759
4760

4761
4762
4763
4764
4765
4766
4767
4768
4769

4770
4771
4772
4773
4774
4775
4776
4777
4778
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];

	GetMinSize(wmPtr, &width, &height);

	sprintf(buf, "%d %d", width, height);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolean, curValue;
    XSetWindowAttributes atts;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Container does not support overrideredirect", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
	curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = (boolean) ? True : False;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    if (!(wmPtr->flags & (WM_NEVER_MAPPED))
		    && !(winPtr->flags & TK_EMBEDDED)) {
		UpdateWrapper(winPtr);
	    }
	}
    }
    return TCL_OK;
}








|


<





|
|

|
|
<






|






|
|










|







4802
4803
4804
4805
4806
4807
4808
4809
4810
4811

4812
4813
4814
4815
4816
4817
4818
4819
4820
4821

4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolean, curValue;
    XSetWindowAttributes atts;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if(winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_AppendResult(interp,
		    "Container does not support overrideredirect", NULL);

	    return TCL_ERROR;
	}
    } else {
	curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    }
    if (objc == 3) {
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue);
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	if(winPtr->flags & TK_EMBEDDED) {
	    SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = (boolean) ? True : False;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    if (!(wmPtr->flags & (WM_NEVER_MAPPED))
		&& !(winPtr->flags & TK_EMBEDDED)) {
		UpdateWrapper(winPtr);
	    }
	}
    }
    return TCL_OK;
}

4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;







|
|






<






<
<

|

|

<





|
|







4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887

4888
4889
4890
4891
4892
4893


4894
4895
4896
4897
4898

4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {


	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}

	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    TkSizeT cmdLength;
    Tcl_Obj *resultObj;
    (void)tkwin;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */

	resultObj = Tcl_NewObj();
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol), -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = TkGetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
    }
    return TCL_OK;







|
|

|
|
<
<










<


|
|

<











|
<



















|



|

|







4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949


4950
4951
4952
4953
4954
4955
4956
4957
4958
4959

4960
4961
4962
4963
4964

4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976

4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    register ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    int cmdLength;



    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */


	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_AppendElement(interp,
		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	}

	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetResult(interp, protPtr->command, TCL_STATIC);

		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
     */

    for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
	if (protPtr->protocol == protocol) {
	    if (prevPtr == NULL) {
		wmPtr->protPtr = protPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
    }
    return TCL_OK;
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081

5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];


	results[0] = Tcl_NewWideIntObj(!(wmPtr->flags&WM_WIDTH_NOT_RESIZABLE));
	results[1] = Tcl_NewWideIntObj(!(wmPtr->flags&WM_HEIGHT_NOT_RESIZABLE));
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {







|

<






|

>
|
|
|







5030
5031
5032
5033
5034
5035
5036
5037
5038

5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d",
		(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	return TCL_OK;
    }
    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;







|
|






<






<
<

|

|

<






|
|







5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107

5108
5109
5110
5111
5112
5113


5114
5115
5116
5117
5118

5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {


	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}

	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222

5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269

5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286

5287
5288
5289
5290
5291
5292

5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304

5305
5306
5307
5308
5309
5310
5311
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW
    };
    Tcl_Obj *resultObj;
    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    resultObj = Tcl_NewObj();

	    for (windowPtr = windows; *windowPtr ; windowPtr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tk_NewWindowObj((Tk_Window) *windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
    } else {
	TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
	int index1 = -1, index2 = -1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4],
		(Tk_Window *) winPtr2Ptr) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't a top-level window",
		    winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't mapped", winPtr2->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);

	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = (windowPtr - windows);
	    }
	    if (*windowPtr == winPtr2) {
		index2 = (windowPtr - windows);
	    }
	}
	if (index1 == -1) {
	    Tcl_Panic("winPtr window not found");

	} else if (index2 == -1) {
	    Tcl_Panic("winPtr2 window not found");
	}

	ckfree(windows);


	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
	return TCL_OK;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * WmStateCmd --
 *







|
|





<









|
|
>
|
|
<

<
|

<
<



|







|
|
<
<




|
|
<




|
|
<









>

<
|
<

<
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|

|
|
>
|
|







|


>







5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172

5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186

5187

5188
5189


5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202


5203
5204
5205
5206
5207
5208

5209
5210
5211
5212
5213
5214

5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225

5226

5227

5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static const char *optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW
    };

    int index;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows == NULL) {
	    Tcl_Panic("TkWmStackorderToplevel failed");
	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_AppendElement(interp, (*window_ptr)->pathName);

	    }

	    ckfree((char *) windows);
	    return TCL_OK;


	}
    } else {
	TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
	int index1=-1, index2=-1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4],
		(Tk_Window *) winPtr2Ptr) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", NULL);


	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", NULL);

	    return TCL_ERROR;
	}

	/*
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);

	if (windows == NULL) {

	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);

	    return TCL_ERROR;

	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		if (*window_ptr == winPtr) {
		    index1 = (window_ptr - windows);
		}
		if (*window_ptr == winPtr2) {
		    index2 = (window_ptr - windows);
		}
	    }
	    if (index1 == -1) {
		Tcl_Panic("winPtr window not found");
	    }
	    if (index2 == -1) {
		Tcl_Panic("winPtr2 window not found");
	    }

	    ckfree((char *) windows);
	}

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmStateCmd --
 *
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL
    };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED
    };
    int index;
    (void)tkwin;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of %s: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (winPtr->flags & TK_EMBEDDED) {
	    int state = 0;

	    switch (index) {







|
|






<







|
|
|
<


|
|







5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294

5295
5296
5297
5298
5299
5300
5301
5302
5303
5304

5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL
    };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED
    };
    int index;


    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]), ": it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);

	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (winPtr->flags & TK_EMBEDDED) {
	    int state = 0;

	    switch (index) {
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437


5438


5439


5440


5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
	    case OPT_ZOOMED:
		state = ZoomState;
		break;
	    default:
		Tcl_Panic("unexpected index");
	    }

	    if (state+1 != SendMessageW(wmPtr->wrapper, TK_STATE, state, 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't change state of %s: the container does not support the request",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}

	if (index == OPT_NORMAL) {
	    wmPtr->flags &= ~WM_WITHDRAWN;
	    TkpWmSetState(winPtr, NormalState);

	    /*
	     * This varies from 'wm deiconify' because it does not force the
	     * window to be raised and receive focus.
	     */
	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->containerPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);
	} else if (index == OPT_WITHDRAWN) {
	    wmPtr->flags |= WM_WITHDRAWN;
	    TkpWmSetState(winPtr, WithdrawnState);
	} else if (index == OPT_ZOOMED) {
	    TkpWmSetState(winPtr, ZoomState);
	} else {
	    Tcl_Panic("wm state not matched");
	}
    } else {
	const char *stateStr = "";

	if (wmPtr->iconFor != NULL) {
	    stateStr = "icon";
	} else {
	    int state;

	    if (winPtr->flags & TK_EMBEDDED) {
		state = SendMessageW(wmPtr->wrapper, TK_STATE, -1, -1) - 1;
	    } else {
		state = wmPtr->hints.initial_state;
	    }
	    switch (state) {
	    case NormalState:	stateStr = "normal";	break;


	    case IconicState:	stateStr = "iconic";	break;


	    case WithdrawnState: stateStr = "withdrawn"; break;


	    case ZoomState:	stateStr = "zoomed";	break;


	    }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(stateStr, -1));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|
<
|
|
|















|
|
<
<
<


|
<
|
|
<
<












<
<

|




|




|
>
>
|
>
>
|
>
>
|
>
>


<







5325
5326
5327
5328
5329
5330
5331
5332

5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352



5353
5354
5355

5356
5357


5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369


5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394

5395
5396
5397
5398
5399
5400
5401
	    case OPT_ZOOMED:
		state = ZoomState;
		break;
	    default:
		Tcl_Panic("unexpected index");
	    }

	    if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) {

		Tcl_AppendResult(interp, "can't change state of ",
			winPtr->pathName,
			": the container does not support the request", NULL);
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}

	if (index == OPT_NORMAL) {
	    wmPtr->flags &= ~WM_WITHDRAWN;
	    TkpWmSetState(winPtr, NormalState);

	    /*
	     * This varies from 'wm deiconify' because it does not force the
	     * window to be raised and receive focus.
	     */
	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
			"\": override-redirect flag is set", NULL);



		return TCL_ERROR;
	    }
	    if (wmPtr->masterPtr != NULL) {

		Tcl_AppendResult(interp, "can't iconify \"",
			winPtr->pathName, "\": it is a transient", NULL);


		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);
	} else if (index == OPT_WITHDRAWN) {
	    wmPtr->flags |= WM_WITHDRAWN;
	    TkpWmSetState(winPtr, WithdrawnState);
	} else if (index == OPT_ZOOMED) {
	    TkpWmSetState(winPtr, ZoomState);
	} else {
	    Tcl_Panic("wm state not matched");
	}
    } else {


	if (wmPtr->iconFor != NULL) {
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
	} else {
	    int state;

	    if (winPtr->flags & TK_EMBEDDED) {
		state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1)-1;
	    } else {
		state = wmPtr->hints.initial_state;
	    }
	    switch (state) {
	    case NormalState:
		Tcl_SetResult(interp, "normal", TCL_STATIC);
		break;
	    case IconicState:
		Tcl_SetResult(interp, "iconic", TCL_STATIC);
		break;
	    case WithdrawnState:
		Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
		break;
	    case ZoomState:
		Tcl_SetResult(interp, "zoomed", TCL_STATIC);
		break;
	    }
	}

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504

5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518

5519
5520
5521
5522
5523
5524
5525
5526
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    HWND wrapper;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	wrapper = (HWND) SendMessageW(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0);
    } else {
	wrapper = wmPtr->wrapper;
    }
    if (objc == 3) {
	if (wrapper) {
	    WCHAR buf[256];
	    Tcl_DString titleString;
	    int size = 256;

	    GetWindowTextW(wrapper, buf, size);
	    Tcl_DStringInit(&titleString);
	    Tcl_WCharToUtfDString(buf, wcslen(buf), &titleString);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tcl_DStringValue(&titleString),
		    Tcl_DStringLength(&titleString)));
	    Tcl_DStringFree(&titleString);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (wmPtr->title ? wmPtr->title : winPtr->nameUid), -1));

	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	argv3 = TkGetStringFromObj(objv[3], &length);
	wmPtr->title = (char *)ckalloc(length + 1);
	memcpy(wmPtr->title, argv3, length + 1);

	if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) {
	    Tcl_DString titleString;

	    Tcl_DStringInit(&titleString);
	    Tcl_UtfToWCharDString(wmPtr->title, -1, &titleString);

	    SetWindowTextW(wrapper, (LPCWSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}

/*







|
|
|

<






|
|





|

|

|
|
<
<
|
<


|
|
>



|

|
|
|



<
<
|
>
|







5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427

5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446


5447

5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463


5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;
    HWND wrapper;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if(winPtr->flags & TK_EMBEDDED) {
	wrapper = (HWND)SendMessage(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0);
    } else {
	wrapper = wmPtr->wrapper;
    }
    if (objc == 3) {
	if (wrapper) {
	    char buf[512];
	    Tcl_DString titleString;
	    int size = tkWinProcs->useWide ? 256 : 512;

	    (*tkWinProcs->getWindowText)(wrapper, (LPCTSTR)buf, size);
	    Tcl_WinTCharToUtf(buf, -1, &titleString);


	    Tcl_SetResult(interp, Tcl_DStringValue(&titleString),TCL_VOLATILE);

	    Tcl_DStringFree(&titleString);
	} else {
	    Tcl_SetResult(interp, (char *)
		    ((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),
		    TCL_STATIC);
	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree((char *) wmPtr->title);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->title = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->title, argv3);

	if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) {
	    Tcl_DString titleString;


	    Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString);
	    (*tkWinProcs->setWindowText)(wrapper,
		    (LPCTSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}

/*
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, **containerPtrPtr = &containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (containerPtr != NULL) {
	    /*
	     * If we had a container, tell them that we aren't tied to them
	     * anymore.
	     */

	    containerPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, winPtr);
	}

	wmPtr->containerPtr = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3],
		(Tk_Window *) containerPtrPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
	while (!Tk_TopWinHierarchy(containerPtr)) {
	    /*
	     * Ensure that the container window is actually a Tk toplevel.
	     */

	    containerPtr = containerPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = containerPtr->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}
	if (containerPtr != wmPtr->containerPtr) {
	    /*
	     * Remove old container map/unmap binding before setting the new
	     * container. The event handler will ensure that transient states
	     * reflect the state of the container.
	     */

	    if (wmPtr->containerPtr != NULL) {
		wmPtr->containerPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
			VisibilityChangeMask|StructureNotifyMask,
			WmWaitVisibilityOrMapProc, winPtr);
	    }

	    containerPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, winPtr);

	    wmPtr->containerPtr = containerPtr;
	}
    }
    if (!((wmPtr->flags & WM_NEVER_MAPPED)
	    && !(winPtr->flags & TK_EMBEDDED))) {
	if (wmPtr->containerPtr != NULL
		&& !Tk_IsMapped(wmPtr->containerPtr)) {
	    TkpWmSetState(winPtr, WithdrawnState);
	} else {
	    UpdateWrapper(winPtr);
	}
    }
    return TCL_OK;
}







|
|



|



|
|




|

|



|
|

|


|


|


|

|


|

|


|
|
|
<



|


|
|
|
<


|
<
|
|
<
<
|
|
<
<
|

|
|
|


|
|
|

|


|
|

|

|




|
|







5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543

5544
5545
5546
5547
5548
5549
5550
5551
5552

5553
5554
5555

5556
5557


5558
5559


5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (masterPtr != NULL) {
	    Tcl_SetResult(interp, Tk_PathName(masterPtr), TCL_STATIC);
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (masterPtr != NULL) {
	    /*
	     * If we had a master, tell them that we aren't tied to them
	     * anymore.
	     */

	    masterPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) masterPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, (ClientData) winPtr);
	}

	wmPtr->masterPtr = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3],
		(Tk_Window *) masterPtrPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
	while (!Tk_TopWinHierarchy(masterPtr)) {
	    /*
	     * Ensure that the master window is actually a Tk toplevel.
	     */

	    masterPtr = masterPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) masterPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor), NULL);

	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor), NULL);

	    return TCL_ERROR;
	}


	if (masterPtr == winPtr) {
	    Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),


		    "\" its own master", NULL);
	    return TCL_ERROR;


	} else if (masterPtr != wmPtr->masterPtr) {
	    /*
	     * Remove old master map/unmap binding before setting the new
	     * master. The event handler will ensure that transient states
	     * reflect the state of the master.
	     */

	    if (wmPtr->masterPtr != NULL) {
		wmPtr->masterPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
			VisibilityChangeMask|StructureNotifyMask,
			WmWaitVisibilityOrMapProc, (ClientData) winPtr);
	    }

	    masterPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) masterPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, (ClientData) winPtr);

	    wmPtr->masterPtr = masterPtr;
	}
    }
    if (!((wmPtr->flags & WM_NEVER_MAPPED)
	    && !(winPtr->flags & TK_EMBEDDED))) {
	if (wmPtr->masterPtr != NULL &&
		!Tk_IsMapped(wmPtr->masterPtr)) {
	    TkpWmSetState(winPtr, WithdrawnState);
	} else {
	    UpdateWrapper(winPtr);
	}
    }
    return TCL_OK;
}
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724

5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	if (SendMessageW(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't withdraw %s: the container does not support the request",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
	wmPtr->flags |= WM_WITHDRAWN;
	TkpWmSetState(winPtr, WithdrawnState);
    }
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry. Schedules a geometry
 * update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}


static void
WmWaitVisibilityOrMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL)
	return;

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    TkpWmSetState(winPtr, NormalState);
	}
    } else if (eventPtr->type == UnmapNotify) {
	TkpWmSetState(winPtr, WithdrawnState);
    }

    if (eventPtr->type == VisibilityNotify) {
	int state = containerPtr->wmInfoPtr->hints.initial_state;

	if ((state == NormalState) || (state == ZoomState)) {
	    state = winPtr->wmInfoPtr->hints.initial_state;
	    if ((state == NormalState) || (state == ZoomState)) {
		UpdateWrapper(winPtr);
	    }
	}







|
<






<
|
|
<




|
|
|
<
<




















|




>





|
|

|











|







5612
5613
5614
5615
5616
5617
5618
5619

5620
5621
5622
5623
5624
5625

5626
5627

5628
5629
5630
5631
5632
5633
5634


5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {

	Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);

	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	if (SendMessage(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) {
	    Tcl_AppendResult(interp, "can't withdraw", Tcl_GetString(objv[2]),
		    ": the container does not support the request", NULL);


	    return TCL_ERROR;
	}
    } else {
	wmPtr->flags |= WM_WITHDRAWN;
	TkpWmSetState(winPtr, WithdrawnState);
    }
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry. Schedules a geometry
 * update.
 */

static void
WmUpdateGeom(
    WmInfo *wmPtr,
    TkWindow *winPtr)
{
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

	/*ARGSUSED*/
static void
WmWaitVisibilityOrMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;
    TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;

    if (masterPtr == NULL)
	return;

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    TkpWmSetState(winPtr, NormalState);
	}
    } else if (eventPtr->type == UnmapNotify) {
	TkpWmSetState(winPtr, WithdrawnState);
    }

    if (eventPtr->type == VisibilityNotify) {
	int state = masterPtr->wmInfoPtr->hints.initial_state;

	if ((state == NormalState) || (state == ZoomState)) {
	    state = winPtr->wmInfoPtr->hints.initial_state;
	    if ((state == NormalState) || (state == ZoomState)) {
		UpdateWrapper(winPtr);
	    }
	}
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
	widthInc = 1;







|







5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
	widthInc = 1;
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {







|







5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
    wmPtr->heightInc = 1;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
    wmPtr->heightInc = 1;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    /*
	     * A top-level window was deleted externally (e.g., by the window
	     * manager). This is probably not a good thing, but cleanup as
	     * best we can. The error handler is needed because
	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
		    NULL, NULL);
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
    }
}

/*







|














|







5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    register TkWindow *winPtr = (TkWindow *) clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    /*
	     * A top-level window was deleted externally (e.g., by the window
	     * manager). This is probably not a good thing, but cleanup as
	     * best we can. The error handler is needed because
	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
		    (Tk_ErrorProc *) NULL, (ClientData) NULL);
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
    }
}

/*
5980
5981
5982
5983
5984
5985
5986

5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */


static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;
    (void)dummy;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING;
	}
    }







>







<




|







5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930

5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request (this
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;


    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING;
	}
    }
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    int x, y;			/* Position of border on desktop. */
    int width, height;		/* Size of client area. */
    int min, max;
    RECT rect;
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * If the window is minimized or maximized, we should not update our
     * geometry since it will end up with the wrong values. ConfigureToplevel
     * will reschedule UpdateGeometryInfo when the state of the window







|
|







5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    int x, y;			/* Position of border on desktop. */
    int width, height;		/* Size of client area. */
    int min, max;
    RECT rect;
    register TkWindow *winPtr = (TkWindow *) clientData;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * If the window is minimized or maximized, we should not update our
     * geometry since it will end up with the wrong values. ConfigureToplevel
     * will reschedule UpdateGeometryInfo when the state of the window
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
	/*
	 * The wrapper window is in a different process, so we need to send it
	 * a geometry request. This protocol assumes that the other process
	 * understands this Tk message, otherwise our requested geometry will
	 * be ignored.
	 */

	SendMessageW(wmPtr->wrapper, TK_MOVEWINDOW, x, y);
	SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ, width, height);
    } else {
	int reqHeight, reqWidth;
	RECT windowRect;
	int menuInc = GetSystemMetrics(SM_CYMENU);
	int newHeight;

	/*







|
|







6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
	/*
	 * The wrapper window is in a different process, so we need to send it
	 * a geometry request. This protocol assumes that the other process
	 * understands this Tk message, otherwise our requested geometry will
	 * be ignored.
	 */

	SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, x, y);
	SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, width, height);
    } else {
	int reqHeight, reqWidth;
	RECT windowRect;
	int menuInc = GetSystemMetrics(SM_CYMENU);
	int newHeight;

	/*
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
 *
 *--------------------------------------------------------------
 */

static int
ParseGeometry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    const char *string,		/* String containing new geometry. Has the
				 * standard form "=wxh+x+y". */
    TkWindow *winPtr)		/* Pointer to top-level window whose geometry
				 * is to be changed. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, flags;
    char *end;
    const char *p = string;

    /*
     * The leading "=" is optional.
     */

    if (*p == '=') {
	p++;







|




|


|







6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
 *
 *--------------------------------------------------------------
 */

static int
ParseGeometry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    char *string,		/* String containing new geometry. Has the
				 * standard form "=wxh+x+y". */
    TkWindow *winPtr)		/* Pointer to top-level window whose geometry
				 * is to be changed. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, flags;
    char *end;
    register char *p = string;

    /*
     * The leading "=" is optional.
     */

    if (*p == '=') {
	p++;
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	    wmPtr->sizeHintsFlags |= USPosition;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.
     */

    wmPtr->width = width;
    wmPtr->height = height;
    wmPtr->x = x;
    wmPtr->y = y;
    flags |= WM_MOVE_PENDING;
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad geometry specifier \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "GEOMETRY", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --







|


















|





<
|
<







6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355

6356

6357
6358
6359
6360
6361
6362
6363
	/*
	 * Assume that the geometry information came from the user, unless an
	 * explicit source has been specified. Otherwise most window managers
	 * assume that the size hints were program-specified and they ignore
	 * them.
	 */

	if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	    wmPtr->sizeHintsFlags |= USPosition;
	}
    }

    /*
     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
     * the appropriate information to be percolated out to the window manager
     * at the next idle moment.
     */

    wmPtr->width = width;
    wmPtr->height = height;
    wmPtr->x = x;
    wmPtr->y = y;
    flags |= WM_MOVE_PENDING;
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

  error:

    Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRootCoords --
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458

void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * If the window is mapped, let Windows figure out the translation.
     */

    if (winPtr->window != None) {
	HWND hwnd = Tk_GetHWND(winPtr->window);







|







6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392

void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    register TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * If the window is mapped, let Windows figure out the translation.
     */

    if (winPtr->window != None) {
	HWND hwnd = Tk_GetHWND(winPtr->window);
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
    Tk_Window tkwin,		/* Window whose virtual root is to be
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr, int *heightPtr)
				/* Store dimensions of virtual root here. */
{
    (void)tkwin;

    *xPtr = GetSystemMetrics(SM_XVIRTUALSCREEN);
    *yPtr = GetSystemMetrics(SM_YVIRTUALSCREEN);
    *widthPtr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    *heightPtr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

/*







<
<







6475
6476
6477
6478
6479
6480
6481


6482
6483
6484
6485
6486
6487
6488
    Tk_Window tkwin,		/* Window whose virtual root is to be
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr, int *heightPtr)
				/* Store dimensions of virtual root here. */
{


    *xPtr = GetSystemMetrics(SM_XVIRTUALSCREEN);
    *yPtr = GetSystemMetrics(SM_YVIRTUALSCREEN);
    *widthPtr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    *heightPtr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

/*
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;
    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
    if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) {
	wmPtr->sizeHintsFlags |= USPosition;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server
     * that would overwrite wmPtr->x and wmPtr->y and lose the new position.
     */

    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
	}
	UpdateGeometryInfo(winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmProtocolEventProc --







|








|











|

|







6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
    wmPtr->flags |= WM_MOVE_PENDING;
    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
    if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
	wmPtr->sizeHintsFlags |= USPosition;
    }

    /*
     * If the window has already been mapped, must bring its geometry
     * up-to-date immediately, otherwise an event might arrive from the server
     * that would overwrite wmPtr->x and wmPtr->y and lose the new position.
     */

    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->flags & WM_UPDATE_PENDING) {
	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
	}
	UpdateGeometryInfo((ClientData) winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmProtocolEventProc --
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657

6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671

void
TkWmProtocolEventProc(
    TkWindow *winPtr,		/* Window to which the event was sent. */
    XEvent *eventPtr)		/* X event. */
{
    WmInfo *wmPtr;
    ProtocolHandler *protPtr;
    Atom protocol;
    int result;
    Tcl_Interp *interp;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return;
    }
    protocol = (Atom) eventPtr->xclient.data.l[0];
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    /*
	     * Cache atom name, as we might destroy the window as a result of
	     * the eval.
	     */

	    const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol);

	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {

		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			name));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
	    Tcl_Release(protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.







|



















|

|


>
|
|
<
|

|
|







6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592

6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603

void
TkWmProtocolEventProc(
    TkWindow *winPtr,		/* Window to which the event was sent. */
    XEvent *eventPtr)		/* X event. */
{
    WmInfo *wmPtr;
    register ProtocolHandler *protPtr;
    Atom protocol;
    int result;
    Tcl_Interp *interp;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return;
    }
    protocol = (Atom) eventPtr->xclient.data.l[0];
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    /*
	     * Cache atom name, as we might destroy the window as a result of
	     * the eval.
	     */

	    const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol);

	    Tcl_Preserve((ClientData) protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve((ClientData) interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(interp, "\n    (command for \"");
		Tcl_AddErrorInfo(interp, name);
		Tcl_AddErrorInfo(interp, "\" window manager protocol)");

		Tcl_BackgroundError(interp);
	    }
	    Tcl_Release((ClientData) interp);
	    Tcl_Release((ClientData) protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
    TkWindow *childWinPtr;

    TkWmStackorderToplevelPair *pair =
	    (TkWmStackorderToplevelPair *) lParam;

    /*fprintf(stderr, "Looking up HWND %d\n", hwnd);*/

    hPtr = Tcl_FindHashEntry(pair->table, hwnd);
    if (hPtr != NULL) {
	childWinPtr = (TkWindow *)Tcl_GetHashValue(hPtr);

	/*
	 * Double check that same HWND does not get passed twice.
	 */

	if (childWinPtr == NULL) {
	    Tcl_Panic("duplicate HWND in TkWmStackorderToplevelEnumProc");
	} else {
	    Tcl_SetHashValue(hPtr, NULL);
	}
	/*
	fprintf(stderr, "Found mapped HWND %d -> %x (%s)\n", hwnd,
		childWinPtr, childWinPtr->pathName);
	*/
	*(pair->windowPtr)-- = childWinPtr;
    }
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *







|

|














|







6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
    TkWindow *childWinPtr;

    TkWmStackorderToplevelPair *pair =
	    (TkWmStackorderToplevelPair *) lParam;

    /*fprintf(stderr, "Looking up HWND %d\n", hwnd);*/

    hPtr = Tcl_FindHashEntry(pair->table, (char *) hwnd);
    if (hPtr != NULL) {
	childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);

	/*
	 * Double check that same HWND does not get passed twice.
	 */

	if (childWinPtr == NULL) {
	    Tcl_Panic("duplicate HWND in TkWmStackorderToplevelEnumProc");
	} else {
	    Tcl_SetHashValue(hPtr, NULL);
	}
	/*
	fprintf(stderr, "Found mapped HWND %d -> %x (%s)\n", hwnd,
		childWinPtr, childWinPtr->pathName);
	*/
	*(pair->window_ptr)-- = childWinPtr;
    }
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
    Tcl_HashTable *table)	/* Table to maps HWND to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    HWND wrapper;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)
	    && !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) {
	wrapper = TkWinGetWrapperWindow((Tk_Window) winPtr);

	/*
	fprintf(stderr, "Mapped HWND %d to %x (%s)\n", wrapper,
		winPtr, winPtr->pathName);
	*/








|
|







6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
    Tcl_HashTable *table)	/* Table to maps HWND to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    HWND wrapper;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) &&
	    !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) {
	wrapper = TkWinGetWrapperWindow((Tk_Window) winPtr);

	/*
	fprintf(stderr, "Mapped HWND %d to %x (%s)\n", wrapper,
		winPtr, winPtr->pathName);
	*/

6804
6805
6806
6807
6808
6809
6810

6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842


6843
6844
6845
6846
6847
6848
6849
    /*
     * Map HWND ids to a TkWindow of the wrapped toplevel.
     */

    Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
    TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);


    windows = (TkWindow **)ckalloc((table.numEntries+1) * sizeof(TkWindow *));

    /*
     * Special cases: If zero or one toplevels were mapped there is no need to
     * call EnumWindows.
     */

    switch (table.numEntries) {
    case 0:
	windows[0] = NULL;
	goto done;
    case 1:
	hPtr = Tcl_FirstHashEntry(&table, &search);
	windows[0] = (TkWindow *)Tcl_GetHashValue(hPtr);
	windows[1] = NULL;
	goto done;
    }

    /*
     * We will be inserting into the array starting at the end and working our
     * way to the beginning since EnumWindows returns windows in highest to
     * lowest order.
     */

    pair.table = &table;
    pair.windowPtr = windows + table.numEntries;
    *pair.windowPtr-- = NULL;

    if (EnumWindows((WNDENUMPROC) TkWmStackorderToplevelEnumProc,
	    (LPARAM) &pair) == 0) {
	ckfree(windows);
	windows = NULL;


    }

  done:
    Tcl_DeleteHashTable(&table);
    return windows;
}








>
|












|











|
|



|

>
>







6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
    /*
     * Map HWND ids to a TkWindow of the wrapped toplevel.
     */

    Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
    TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);

    windows = (TkWindow **) ckalloc((table.numEntries+1)
	* sizeof(TkWindow *));

    /*
     * Special cases: If zero or one toplevels were mapped there is no need to
     * call EnumWindows.
     */

    switch (table.numEntries) {
    case 0:
	windows[0] = NULL;
	goto done;
    case 1:
	hPtr = Tcl_FirstHashEntry(&table, &search);
	windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
	windows[1] = NULL;
	goto done;
    }

    /*
     * We will be inserting into the array starting at the end and working our
     * way to the beginning since EnumWindows returns windows in highest to
     * lowest order.
     */

    pair.table = &table;
    pair.window_ptr = windows + table.numEntries;
    *pair.window_ptr-- = NULL;

    if (EnumWindows((WNDENUMPROC) TkWmStackorderToplevelEnumProc,
	    (LPARAM) &pair) == 0) {
	ckfree((char *) windows);
	windows = NULL;
    } else if (pair.window_ptr != (windows-1)) {
	Tcl_Panic("num matched toplevel windows does not equal num children");
    }

  done:
    Tcl_DeleteHashTable(&table);
    return windows;
}

6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
	insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL)
		? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
    } else {
	insertAfter = NULL;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	SendMessageW(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW,
		(WPARAM) insertAfter, aboveBelow);
    } else {
	TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
    }
}

/*
 *----------------------------------------------------------------------







|
|







6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
	insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL)
		? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
    } else {
	insertAfter = NULL;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW,
		(WPARAM)insertAfter, aboveBelow);
    } else {
	TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
    }
}

/*
 *----------------------------------------------------------------------
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
    }

    /*
     * Make a new bigger array and use it to reset the property.
     * Automatically add the toplevel itself as the last element of the list.
     */

    newPtr = (TkWindow **)ckalloc((count+2) * sizeof(TkWindow *));
    if (count > 0) {
	memcpy(newPtr, oldPtr, count * sizeof(TkWindow*));
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr;
    newPtr[count] = topPtr;
    if (oldPtr != NULL) {
	ckfree(oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * Now we need to force the updated colormaps to be installed.







|









|







6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
    }

    /*
     * Make a new bigger array and use it to reset the property.
     * Automatically add the toplevel itself as the last element of the list.
     */

    newPtr = (TkWindow **) ckalloc((unsigned) ((count+2)*sizeof(TkWindow*)));
    if (count > 0) {
	memcpy(newPtr, oldPtr, count * sizeof(TkWindow*));
    }
    if (count == 0) {
	count++;
    }
    newPtr[count-1] = winPtr;
    newPtr[count] = topPtr;
    if (oldPtr != NULL) {
	ckfree((char *) oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * Now we need to force the updated colormaps to be installed.
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
	SetMenu(wmPtr->wrapper, hMenu);
	if (!syncPending) {
	    wmPtr->flags &= ~WM_SYNC_PENDING;
	}
    }
    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
	}
    } else {
	SendMessageW(wmPtr->wrapper, TK_SETMENU, (WPARAM) hMenu,
		(LPARAM) Tk_GetMenuHWND(tkwin));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureTopLevel --







|



|
|







7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
	SetMenu(wmPtr->wrapper, hMenu);
	if (!syncPending) {
	    wmPtr->flags &= ~WM_SYNC_PENDING;
	}
    }
    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
	}
    } else {
	SendMessage(wmPtr->wrapper, TK_SETMENU,
		(WPARAM)hMenu, (LPARAM)Tk_GetMenuHWND(tkwin));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureTopLevel --
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
	case NormalState:
	    /*
	     * Schedule a geometry update. Since we ignore geometry requests
	     * while in any other state, the geometry info may be stale.
	     */

	    if (!(wmPtr->flags & WM_UPDATE_PENDING)) {
		Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
		wmPtr->flags |= WM_UPDATE_PENDING;
	    }
	    /* fall through */
	case ZoomState:
	    XMapWindow(winPtr->display, winPtr->window);
	    pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
	    break;







|







7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
	case NormalState:
	    /*
	     * Schedule a geometry update. Since we ignore geometry requests
	     * while in any other state, the geometry info may be stale.
	     */

	    if (!(wmPtr->flags & WM_UPDATE_PENDING)) {
		Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
		wmPtr->flags |= WM_UPDATE_PENDING;
	    }
	    /* fall through */
	case ZoomState:
	    XMapWindow(winPtr->display, winPtr->window);
	    pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
	    break;
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
    HDC dc;
    HPALETTE oldPalette;
    TkWindow *winPtr = GetTopLevel(hwnd);
    WmInfo *wmPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD)) {
	return 0;
    }

    wmPtr = winPtr->wmInfoPtr;

    if (message == WM_QUERYNEWPALETTE) {
	/*







|







7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
    HDC dc;
    HPALETTE oldPalette;
    TkWindow *winPtr = GetTopLevel(hwnd);
    WmInfo *wmPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD) ) {
	return 0;
    }

    wmPtr = winPtr->wmInfoPtr;

    if (message == WM_QUERYNEWPALETTE) {
	/*
7440
7441
7442
7443
7444
7445
7446
7447

7448
7449

7450
7451
7452
7453
7454
7455
7456
	oldPalette = SelectPalette(dc, tsdPtr->systemPalette, FALSE);
	if (RealizePalette(dc)) {
	    RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr);
	} else if (wmPtr->cmapCount > 1) {
	    SelectPalette(dc, oldPalette, TRUE);
	    RealizePalette(dc);
	    ReleaseDC(hwnd, dc);
	    SendMessageW(hwnd, WM_PALETTECHANGED, (WPARAM) hwnd, (LPARAM) NULL);

	    return TRUE;
	}

    } else {
	/*
	 * Window is being notified of a change in the system palette. If this
	 * window is the foreground window, then we should only install the
	 * secondary palettes, since the primary was installed in response to
	 * the WM_QUERYPALETTE message. Otherwise, install all of the
	 * palettes.







|
>


>







7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
	oldPalette = SelectPalette(dc, tsdPtr->systemPalette, FALSE);
	if (RealizePalette(dc)) {
	    RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr);
	} else if (wmPtr->cmapCount > 1) {
	    SelectPalette(dc, oldPalette, TRUE);
	    RealizePalette(dc);
	    ReleaseDC(hwnd, dc);
	    SendMessage(hwnd, WM_PALETTECHANGED, (WPARAM)hwnd,
		    (LPARAM)NULL);
	    return TRUE;
	}

    } else {
	/*
	 * Window is being notified of a change in the system palette. If this
	 * window is the foreground window, then we should only install the
	 * secondary palettes, since the primary was installed in response to
	 * the WM_QUERYPALETTE message. Otherwise, install all of the
	 * palettes.
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
	 */

	if (!(pos->flags & SWP_NOSIZE)) {
	    winPtr->changes.width = pos->cx;
	    winPtr->changes.height = pos->cy;
	}
	if (!(pos->flags & SWP_NOMOVE)) {
	    long result = SendMessageW(winPtr->wmInfoPtr->wrapper,
		    TK_MOVEWINDOW, -1, -1);
	    winPtr->wmInfoPtr->x = winPtr->changes.x = result >> 16;
	    winPtr->wmInfoPtr->y = winPtr->changes.y = result & 0xffff;
	}

	GenerateConfigureNotify(winPtr);








|







7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
	 */

	if (!(pos->flags & SWP_NOSIZE)) {
	    winPtr->changes.width = pos->cx;
	    winPtr->changes.height = pos->cy;
	}
	if (!(pos->flags & SWP_NOMOVE)) {
	    long result = SendMessage(winPtr->wmInfoPtr->wrapper,
		    TK_MOVEWINDOW, -1, -1);
	    winPtr->wmInfoPtr->x = winPtr->changes.x = result >> 16;
	    winPtr->wmInfoPtr->y = winPtr->changes.y = result & 0xffff;
	}

	GenerateConfigureNotify(winPtr);

7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918

	TkWinCancelMouseTimer();

	oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	break;

    case WM_ACTIVATE:
	if (WA_ACTIVE == LOWORD(wParam)) {
	    winPtr = GetTopLevel(hwnd);
	    if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
		/*
		 * There is a grab in progress so queue an Activate event
		 */

		GenerateActivateEvent(winPtr, &inMoveSize);







|







7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855

	TkWinCancelMouseTimer();

	oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
	break;

    case WM_ACTIVATE:
	if ( WA_ACTIVE == LOWORD(wParam) ) {
	    winPtr = GetTopLevel(hwnd);
	    if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
		/*
		 * There is a grab in progress so queue an Activate event
		 */

		GenerateActivateEvent(winPtr, &inMoveSize);
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
	 * widgets that use a system color.
	 */

	break;

    case WM_PALETTECHANGED:
	result = InstallColormaps(hwnd, WM_PALETTECHANGED,
		hwnd == (HWND) wParam);
	goto done;

    case WM_QUERYNEWPALETTE:
	result = InstallColormaps(hwnd, WM_QUERYNEWPALETTE, TRUE);
	goto done;

    case WM_SETTINGCHANGE:







|







7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
	 * widgets that use a system color.
	 */

	break;

    case WM_PALETTECHANGED:
	result = InstallColormaps(hwnd, WM_PALETTECHANGED,
		hwnd == (HWND)wParam);
	goto done;

    case WM_QUERYNEWPALETTE:
	result = InstallColormaps(hwnd, WM_QUERYNEWPALETTE, TRUE);
	goto done;

    case WM_SETTINGCHANGE:
8027
8028
8029
8030
8031
8032
8033

8034
8035
8036
8037
8038
8039
8040
8041
	winPtr = GetTopLevel((HWND) wParam);
	if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
	    /*
	     * This allows us to pass the message onto the native menus [Bug:
	     * 2272]
	     */


	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	    goto done;
	}

	/*
	 * Don't activate the window yet since there is a grab that takes
	 * precedence. Instead we need to queue an event so we can check the
	 * grab state right before we handle the mouse event.







>
|







7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
	winPtr = GetTopLevel((HWND) wParam);
	if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
	    /*
	     * This allows us to pass the message onto the native menus [Bug:
	     * 2272]
	     */

	    result = (*tkWinProcs->defWindowProc)(hwnd, message,
		    wParam, lParam);
	    goto done;
	}

	/*
	 * Don't activate the window yet since there is a grab that takes
	 * precedence. Instead we need to queue an event so we can check the
	 * grab state right before we handle the mouse event.
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129

8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
    case WM_MENUCHAR:
    case WM_MEASUREITEM:
    case WM_DRAWITEM:
    case WM_MENUSELECT:
    case WM_ENTERIDLE:
    case WM_INITMENUPOPUP:
	if (winPtr) {
	    HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window) winPtr);

	    if (hMenuHWnd) {
		if (SendMessageW(hMenuHWnd, message, wParam, lParam)) {
		    goto done;
		}
	    } else if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		    &result)) {
		goto done;
	    }
	}
	break;
    }

    if (winPtr && winPtr->window) {
	HWND child = Tk_GetHWND(winPtr->window);

	if (message == WM_SETFOCUS) {
	    SetFocus(child);
	    result = 0;
	} else if (!TkTranslateWinEvent(child, message, wParam, lParam,
		&result)) {

	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
    } else {
	result = DefWindowProcW(hwnd, message, wParam, lParam);
    }

  done:
    Tcl_ServiceAll();
    return result;
}








|


|
















|

>
|


|







8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
    case WM_MENUCHAR:
    case WM_MEASUREITEM:
    case WM_DRAWITEM:
    case WM_MENUSELECT:
    case WM_ENTERIDLE:
    case WM_INITMENUPOPUP:
	if (winPtr) {
	    HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window)winPtr);

	    if (hMenuHWnd) {
		if (SendMessage(hMenuHWnd, message, wParam, lParam)) {
		    goto done;
		}
	    } else if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		    &result)) {
		goto done;
	    }
	}
	break;
    }

    if (winPtr && winPtr->window) {
	HWND child = Tk_GetHWND(winPtr->window);

	if (message == WM_SETFOCUS) {
	    SetFocus(child);
	    result = 0;
	} else if (!Tk_TranslateWinEvent(child, message, wParam, lParam,
		&result)) {
	    result = (*tkWinProcs->defWindowProc)(hwnd, message,
		    wParam, lParam);
	}
    } else {
	result = (*tkWinProcs->defWindowProc)(hwnd, message, wParam, lParam);
    }

  done:
    Tcl_ServiceAll();
    return result;
}

8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
    } else {
	atts.override_redirect = False;
	atts.save_under = False;
    }

    if ((atts.override_redirect != Tk_Attributes(tkwin)->override_redirect)
	    || (atts.save_under != Tk_Attributes(tkwin)->save_under)) {
	Tk_ChangeWindowAttributes(tkwin, CWOverrideRedirect|CWSaveUnder,
		&atts);
    }

}

/*
 *----------------------------------------------------------------------
 *







|
|







8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
    } else {
	atts.override_redirect = False;
	atts.save_under = False;
    }

    if ((atts.override_redirect != Tk_Attributes(tkwin)->override_redirect)
	    || (atts.save_under != Tk_Attributes(tkwin)->save_under)) {
	Tk_ChangeWindowAttributes(tkwin,
		CWOverrideRedirect|CWSaveUnder, &atts);
    }

}

/*
 *----------------------------------------------------------------------
 *
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
 *----------------------------------------------------------------------
 */

HWND
TkWinGetWrapperWindow(
    Tk_Window tkwin)		/* The window we need the wrapper from */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    return winPtr->wmInfoPtr->wrapper;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmFocusToplevel --
 *







|
<
|







8137
8138
8139
8140
8141
8142
8143
8144

8145
8146
8147
8148
8149
8150
8151
8152
 *----------------------------------------------------------------------
 */

HWND
TkWinGetWrapperWindow(
    Tk_Window tkwin)		/* The window we need the wrapper from */
{
    TkWindow *winPtr = (TkWindow *)tkwin;

    return (winPtr->wmInfoPtr->wrapper);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmFocusToplevel --
 *
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
 *
 *	This function is called to activate a Tk window.
 */

static void
GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr)
{
    ActivateEvent *eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent));

    eventPtr->ev.proc = ActivateWindow;
    eventPtr->winPtr = winPtr;
    eventPtr->flagPtr = flagPtr;
    eventPtr->hwnd = Tk_GetHWND(winPtr->window);
    Tcl_QueueEvent((Tcl_Event *)eventPtr, TCL_QUEUE_TAIL);
}








|
|







8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
 *
 *	This function is called to activate a Tk window.
 */

static void
GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr)
{
    ActivateEvent *eventPtr;
    eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent));
    eventPtr->ev.proc = ActivateWindow;
    eventPtr->winPtr = winPtr;
    eventPtr->flagPtr = flagPtr;
    eventPtr->hwnd = Tk_GetHWND(winPtr->window);
    Tcl_QueueEvent((Tcl_Event *)eventPtr, TCL_QUEUE_TAIL);
}

8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
 *----------------------------------------------------------------------
 */

void
TkWinSetForegroundWindow(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->wrapper != NULL) {
	SetForegroundWindow(wmPtr->wrapper);
    } else {
	SetForegroundWindow(Tk_GetHWND(winPtr->window));
    }
}







|







8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
 *----------------------------------------------------------------------
 */

void
TkWinSetForegroundWindow(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->wrapper != NULL) {
	SetForegroundWindow(wmPtr->wrapper);
    } else {
	SetForegroundWindow(Tk_GetHWND(winPtr->window));
    }
}
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelWithDraw(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags |= WM_WITHDRAWN;
    TkpWmSetState(winPtr, WithdrawnState);
}

/*
 *----------------------------------------------------------------------
 *







|
<







8347
8348
8349
8350
8351
8352
8353
8354

8355
8356
8357
8358
8359
8360
8361
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelWithDraw(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags |= WM_WITHDRAWN;
    TkpWmSetState(winPtr, WithdrawnState);
}

/*
 *----------------------------------------------------------------------
 *
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelDeiconify(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags &= ~WM_WITHDRAWN;

    /*
     * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may need to
     * be called first to update a withdrawn toplevel's geometry before it is
     * deiconified by TkpWmSetState. Don't bother if we've never been mapped.
     */

    if ((wmPtr->flags & WM_UPDATE_PENDING)
	    && !(wmPtr->flags & WM_NEVER_MAPPED)) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
	UpdateGeometryInfo(winPtr);
    }

    /*
     * If we were in the ZoomState (maximized), 'wm deiconify' should not
     * cause the window to shrink
     */








|









|
|
|
|







8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelDeiconify(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags &= ~WM_WITHDRAWN;

    /*
     * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may need to
     * be called first to update a withdrawn toplevel's geometry before it is
     * deiconified by TkpWmSetState. Don't bother if we've never been mapped.
     */

    if ((wmPtr->flags & WM_UPDATE_PENDING) &&
	    !(wmPtr->flags & WM_NEVER_MAPPED)) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
	UpdateGeometryInfo((ClientData) winPtr);
    }

    /*
     * If we were in the ZoomState (maximized), 'wm deiconify' should not
     * cause the window to shrink
     */

8528
8529
8530
8531
8532
8533
8534
8535
8536
8537


8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
 *----------------------------------------------------------------------
 */

long
TkpWinToplevelIsControlledByWm(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!wmPtr) {


	return 0;
    }
    return ((wmPtr->width != -1) && (wmPtr->height != -1)) ? 1 : 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelMove --
 *







|

|
>
>


<







8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478

8479
8480
8481
8482
8483
8484
8485
 *----------------------------------------------------------------------
 */

long
TkpWinToplevelIsControlledByWm(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr) {
	return ((wmPtr->width != -1) && (wmPtr->height != -1))? 1:0;
    } else {
	return 0;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelMove --
 *
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
 */

long
TkpWinToplevelMove(
    TkWindow *winPtr,
    int x, int y)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr && x >= 0 && y >= 0 && !TkpWinToplevelIsControlledByWm(winPtr)) {
	Tk_MoveToplevelWindow((Tk_Window) winPtr, x, y);
    }
    return ((winPtr->changes.x << 16) & 0xffff0000)
	    | (winPtr->changes.y & 0xffff);
}

/*
 *----------------------------------------------------------------------







|


|







8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
 */

long
TkpWinToplevelMove(
    TkWindow *winPtr,
    int x, int y)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr && x >= 0 && y >= 0 && !TkpWinToplevelIsControlledByWm(winPtr)) {
	Tk_MoveToplevelWindow((Tk_Window)winPtr, x, y);
    }
    return ((winPtr->changes.x << 16) & 0xffff0000)
	    | (winPtr->changes.y & 0xffff);
}

/*
 *----------------------------------------------------------------------
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609

long
TkpWinToplevelOverrideRedirect(
    TkWindow *winPtr,
    int reqValue)
{
    int curValue;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (reqValue < 0) {
	return curValue;
    }

    if (curValue != reqValue) {
	XSetWindowAttributes atts;

	/*
	 * Only do this if we are really changing value, because it causes
	 * some funky stuff to occur







|


<
|
<







8528
8529
8530
8531
8532
8533
8534
8535
8536
8537

8538

8539
8540
8541
8542
8543
8544
8545

long
TkpWinToplevelOverrideRedirect(
    TkWindow *winPtr,
    int reqValue)
{
    int curValue;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;

    if(reqValue < 0) return curValue;


    if (curValue != reqValue) {
	XSetWindowAttributes atts;

	/*
	 * Only do this if we are really changing value, because it causes
	 * some funky stuff to occur
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668

8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelDetachWindow(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (winPtr->flags & TK_EMBEDDED) {
	int state = SendMessageW(wmPtr->wrapper, TK_STATE, -1, -1) - 1;

	SendMessageW(wmPtr->wrapper, TK_SETMENU, 0, 0);
	SendMessageW(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	winPtr->flags &= ~TK_EMBEDDED;
	winPtr->privatePtr = NULL;
	wmPtr->wrapper = NULL;
	if (state >= 0 && state <= 3) {
	    wmPtr->hints.initial_state = state;
	}
    }
    if (winPtr->flags & TK_TOP_LEVEL) {
	TkpWinToplevelOverrideRedirect(winPtr, 1);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RemapWindows
 *
 *	Adjust parent/child relation ships of the given window hierarchy.

 *
 * Results:
 *	none
 *
 * Side effects:
 *	keeps windowing system happy
 *
 *----------------------------------------------------------------------
 */

static void
RemapWindows(
    TkWindow *winPtr,
    HWND parentHWND)
{
    TkWindow *childPtr;
    const char *className = Tk_Class(winPtr);

    /*
     * Skip menus as they are handled differently.
     */

    if (className != NULL && strcmp(className, "Menu") == 0) {
	return;
    }
    if (winPtr->window) {
	SetParent(Tk_GetHWND(winPtr->window), parentHWND);
    }

    /*
     * Repeat for all the children.
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr,
		winPtr->window ? Tk_GetHWND(winPtr->window) : NULL);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


|

|
|

















|
>











|
|
|




<
|
<
<







<
|
<
<

|












8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623

8624


8625
8626
8627
8628
8629
8630
8631

8632


8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
 *----------------------------------------------------------------------
 */

void
TkpWinToplevelDetachWindow(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (winPtr->flags & TK_EMBEDDED) {
	int state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1) - 1;

	SendMessage(wmPtr->wrapper, TK_SETMENU, 0, 0);
	SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	winPtr->flags &= ~TK_EMBEDDED;
	winPtr->privatePtr = NULL;
	wmPtr->wrapper = NULL;
	if (state >= 0 && state <= 3) {
	    wmPtr->hints.initial_state = state;
	}
    }
    if (winPtr->flags & TK_TOP_LEVEL) {
	TkpWinToplevelOverrideRedirect(winPtr, 1);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RemapWindows
 *
 *	Adjust parent/child relation ships of
 *	the given window hierarchy.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	keeps windowing system happy
 *
 *----------------------------------------------------------------------
 */

static void
RemapWindows(winPtr, parentHWND)
     TkWindow *winPtr;
     HWND parentHWND;
{
    TkWindow *childPtr;
    const char *className = Tk_Class(winPtr);


    /* Skip Menus as they are handled differently */


    if (className != NULL && strcmp(className, "Menu") == 0) {
	return;
    }
    if (winPtr->window) {
	SetParent(Tk_GetHWND(winPtr->window), parentHWND);
    }


    /* Repeat for all the children */


    for (childPtr = winPtr->childList; childPtr != NULL;
	 childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr,
		winPtr->window ? Tk_GetHWND(winPtr->window) : NULL);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinX.c.

1
2
3
4
5
6
7
8
9
10
11
12
13








14
15










16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54






































55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * tkWinX.c --
 *
 *	This file contains Windows emulation procedures for X routines.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright (c) 1994 Software Research Associates, 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.
 */









#include "tkWinInt.h"











#include <commctrl.h>
#ifdef _MSC_VER
#   pragma comment (lib, "comctl32.lib")
#   pragma comment (lib, "advapi32.lib")
#endif

/*
 * The zmouse.h file includes the definition for WM_MOUSEWHEEL.
 */

#include <zmouse.h>

/*
 * WM_MOUSEHWHEEL is normally defined by Winuser.h for Vista/2008 or later,
 * but is also usable on 2000/XP if IntelliPoint drivers are installed.
 */

#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif

/*
 * imm.h is needed by HandleIMEComposition
 */

#include <imm.h>
#ifdef _MSC_VER
#   pragma comment (lib, "imm32.lib")
#endif

/*
 * WM_UNICHAR is a message for Unicode input on all windows systems.
 * Perhaps this definition should be moved in another file.
 */
#ifndef WM_UNICHAR
#define WM_UNICHAR     0x0109
#define UNICODE_NOCHAR 0xFFFF
#endif







































/*
 * Declarations of static variables used in this file.
 */

static const char winScreenName[] = ":0"; /* Default name of windows display. */
static HINSTANCE tkInstance = NULL;	/* Application instance handle. */
static int childClassInitialized;	/* Registered child class? */
static WNDCLASSW childClass;		/* Window class for child windows. */

static int tkWinTheme = 0;		/* See TkWinGetPlatformTheme */
static Tcl_Encoding keyInputEncoding = NULL;
					/* The current character encoding for
					 * keyboard input */
static int keyInputCharset = -1;	/* The Win32 CHARSET for the keyboard
					 * encoding */
static Tcl_Encoding unicodeEncoding = NULL;
					/* The UNICODE encoding */

/*
 * Thread local storage. Notice that now each thread must have its own
 * TkDisplay structure, since this structure contains most of the thread-
 * specific date for threads.
 */

typedef struct {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */
    int surrogateBuffer;	/* Buffer for first of surrogate pair. */
    DWORD vWheelTickPrev;	/* For high resolution wheels (vertical). */
    DWORD hWheelTickPrev;	/* For high resolution wheels (horizontal). */
    short vWheelAcc;		/* For high resolution wheels (vertical). */
    short hWheelAcc;		/* For high resolution wheels (horizontal). */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */

static void		GenerateXEvent(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static unsigned int	GetState(UINT message, WPARAM wParam, LPARAM lParam);
static void 		GetTranslatedKey(TkKeyEvent *xkey, UINT type);
static void		UpdateInputLanguage(int charset);
static int		HandleIMEComposition(HWND hwnd, LPARAM lParam);

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --













>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>












<
<
<
<
<
<
<
<
<


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|


|
>















|



<
<
<
<
<










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45









46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129





130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * tkWinX.c --
 *
 *	This file contains Windows emulation procedures for X routines.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright (c) 1994 Software Research Associates, 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.
 */

/*
 * Make sure the SendInput API is available (NT SP 3):
 */
#if (_WIN32_WINNT <= 0x0400)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0403
#endif

#include "tkWinInt.h"

/*
 * The w32api 1.1 package (included in Mingw 1.1) does not define _WIN32_IE by
 * default. Define it here to gain access to the InitCommonControlsEx API in
 * commctrl.h.
 */

#ifndef _WIN32_IE
#define _WIN32_IE 0x0501 /* IE 5 */
#endif

#include <commctrl.h>
#ifdef _MSC_VER
#   pragma comment (lib, "comctl32.lib")
#   pragma comment (lib, "advapi32.lib")
#endif

/*
 * The zmouse.h file includes the definition for WM_MOUSEWHEEL.
 */

#include <zmouse.h>










/*
 * imm.h is needed by HandleIMEComposition
 */

#include <imm.h>
#ifdef _MSC_VER
#   pragma comment (lib, "imm32.lib")
#endif

/*
 * WM_UNICHAR is a message for Unicode input on all windows systems.
 * Perhaps this definition should be moved in another file.
 */
#ifndef WM_UNICHAR
#define WM_UNICHAR     0x0109
#define UNICODE_NOCHAR 0xFFFF
#endif

static TkWinProcs asciiProcs = {
    0,

    (LRESULT (WINAPI *)(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg,
	    WPARAM wParam, LPARAM lParam)) CallWindowProcA,
    (LRESULT (WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam,
	    LPARAM lParam)) DefWindowProcA,
    (ATOM (WINAPI *)(CONST WNDCLASS *lpWndClass)) RegisterClassA,
    (BOOL (WINAPI *)(HWND hWnd, LPCTSTR lpString)) SetWindowTextA,
    (HWND (WINAPI *)(DWORD dwExStyle, LPCTSTR lpClassName,
	    LPCTSTR lpWindowName, DWORD dwStyle, int x, int y,
	    int nWidth, int nHeight, HWND hWndParent, HMENU hMenu,
	    HINSTANCE hInstance, LPVOID lpParam)) CreateWindowExA,
    (BOOL (WINAPI *)(HMENU hMenu, UINT uPosition, UINT uFlags,
	    UINT uIDNewItem, LPCTSTR lpNewItem))(void *)InsertMenuA,
    (int (WINAPI *)(HWND hWnd, LPCTSTR lpString, int nMaxCount)) GetWindowTextA,
};

static TkWinProcs unicodeProcs = {
    1,

    (LRESULT (WINAPI *)(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg,
	    WPARAM wParam, LPARAM lParam)) CallWindowProcW,
    (LRESULT (WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam,
	    LPARAM lParam)) DefWindowProcW,
    (ATOM (WINAPI *)(CONST WNDCLASS *lpWndClass)) RegisterClassW,
    (BOOL (WINAPI *)(HWND hWnd, LPCTSTR lpString)) SetWindowTextW,
    (HWND (WINAPI *)(DWORD dwExStyle, LPCTSTR lpClassName,
	    LPCTSTR lpWindowName, DWORD dwStyle, int x, int y,
	    int nWidth, int nHeight, HWND hWndParent, HMENU hMenu,
	    HINSTANCE hInstance, LPVOID lpParam)) CreateWindowExW,
    (BOOL (WINAPI *)(HMENU hMenu, UINT uPosition, UINT uFlags,
	    UINT uIDNewItem, LPCTSTR lpNewItem))(void *)InsertMenuW,
    (int (WINAPI *)(HWND hWnd, LPCTSTR lpString, int nMaxCount)) GetWindowTextW,
};

TkWinProcs *tkWinProcs;

/*
 * Declarations of static variables used in this file.
 */

static char winScreenName[] = ":0";	/* Default name of windows display. */
static HINSTANCE tkInstance = NULL;	/* Application instance handle. */
static int childClassInitialized;	/* Registered child class? */
static WNDCLASS childClass;		/* Window class for child windows. */
static int tkPlatformId = 0;		/* version of Windows platform */
static int tkWinTheme = 0;		/* See TkWinGetPlatformTheme */
static Tcl_Encoding keyInputEncoding = NULL;
					/* The current character encoding for
					 * keyboard input */
static int keyInputCharset = -1;	/* The Win32 CHARSET for the keyboard
					 * encoding */
static Tcl_Encoding unicodeEncoding = NULL;
					/* The UNICODE encoding */

/*
 * Thread local storage. Notice that now each thread must have its own
 * TkDisplay structure, since this structure contains most of the thread-
 * specific date for threads.
 */

typedef struct ThreadSpecificData {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */





} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */

static void		GenerateXEvent(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static unsigned int	GetState(UINT message, WPARAM wParam, LPARAM lParam);
static void 		GetTranslatedKey(XKeyEvent *xkey, UINT type);
static void		UpdateInputLanguage(int charset);
static int		HandleIMEComposition(HWND hwnd, LPARAM lParam);

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    Tk_Window tkwin)		/* Token for window; this selects a particular
				 * display and server. */
{
    static char buffer[32]; /* Empty string means not initialized yet. */
    OSVERSIONINFOW os;
    (void)tkwin;

    if (!buffer[0]) {
	HMODULE handle = GetModuleHandleW(L"NTDLL");
	int(__stdcall *getversion)(void *) = (int(__stdcall *)(void *))
		(void *)GetProcAddress(handle, "RtlGetVersion");
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	if (!getversion || getversion(&os)) {
	    GetVersionExW(&os);
	}



	/* Write the first character last, preventing multi-thread issues. */
	sprintf(buffer+1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
#endif
	);
	buffer[0] = 'W';
    }
    Tcl_AppendResult(interp, buffer, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetHINSTANCE --
 *







<


|
|
|




>
>
>











|







164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    Tk_Window tkwin)		/* Token for window; this selects a particular
				 * display and server. */
{
    static char buffer[32]; /* Empty string means not initialized yet. */
    OSVERSIONINFOW os;


    if (!buffer[0]) {
	HANDLE handle = LoadLibraryW(L"NTDLL");
	int(__stdcall *getversion)(void *) =
		(int(__stdcall *)(void *))(void *)GetProcAddress(handle, "RtlGetVersion");
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	if (!getversion || getversion(&os)) {
	    GetVersionExW(&os);
	}
	if (handle) {
	    FreeLibrary(handle);
	}
	/* Write the first character last, preventing multi-thread issues. */
	sprintf(buffer+1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
#endif
	);
	buffer[0] = 'W';
    }
    Tcl_SetResult(interp, buffer, TCL_STATIC);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetHINSTANCE --
 *
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
 *----------------------------------------------------------------------
 */

HINSTANCE
Tk_GetHINSTANCE(void)
{
    if (tkInstance == NULL) {
	tkInstance = GetModuleHandleW(NULL);
    }
    return tkInstance;
}

/*
 *----------------------------------------------------------------------
 *







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
 *----------------------------------------------------------------------
 */

HINSTANCE
Tk_GetHINSTANCE(void)
{
    if (tkInstance == NULL) {
	tkInstance = GetModuleHandle(NULL);
    }
    return tkInstance;
}

/*
 *----------------------------------------------------------------------
 *
228
229
230
231
232
233
234






235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    childClassInitialized = 1;

    comctl.dwSize = sizeof(INITCOMMONCONTROLSEX);
    comctl.dwICC = ICC_WIN95_CLASSES;
    if (!InitCommonControlsEx(&comctl)) {
	Tcl_Panic("Unable to load common controls?!");
    }







    childClass.style = CS_HREDRAW | CS_VREDRAW;
    childClass.cbClsExtra = 0;
    childClass.cbWndExtra = 0;
    childClass.hInstance = hInstance;
    childClass.hbrBackground = NULL;
    childClass.lpszMenuName = NULL;

    /*
     * Register the Child window class.
     */

    childClass.lpszClassName = TK_WIN_CHILD_CLASS_NAME;
    childClass.lpfnWndProc = TkWinChildProc;
    childClass.hIcon = NULL;
    childClass.hCursor = NULL;

    if (!RegisterClassW(&childClass)) {
	Tcl_Panic("Unable to register TkChild class");
    }

    /*
     * Initialize input language info
     */

    if (GetLocaleInfoW(LANGIDFROMLCID(PTR2INT(GetKeyboardLayout(0))),
	       LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
	       (LPWSTR) &lpCP, sizeof(lpCP)/sizeof(WCHAR))
	    && TranslateCharsetInfo((DWORD *)INT2PTR(lpCP), &lpCs, TCI_SRCCODEPAGE)) {
	UpdateInputLanguage((int) lpCs.ciCharset);
    }

    /*
     * Make sure we cleanup on finalize.
     */

    TkCreateExitHandler(TkWinXCleanup, hInstance);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinXCleanup --
 *







>
>
>
>
>
>

















|







|

|
|







|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    childClassInitialized = 1;

    comctl.dwSize = sizeof(INITCOMMONCONTROLSEX);
    comctl.dwICC = ICC_WIN95_CLASSES;
    if (!InitCommonControlsEx(&comctl)) {
	Tcl_Panic("Unable to load common controls?!");
    }

    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
	tkWinProcs = &unicodeProcs;
    } else {
	tkWinProcs = &asciiProcs;
    }

    childClass.style = CS_HREDRAW | CS_VREDRAW;
    childClass.cbClsExtra = 0;
    childClass.cbWndExtra = 0;
    childClass.hInstance = hInstance;
    childClass.hbrBackground = NULL;
    childClass.lpszMenuName = NULL;

    /*
     * Register the Child window class.
     */

    childClass.lpszClassName = TK_WIN_CHILD_CLASS_NAME;
    childClass.lpfnWndProc = TkWinChildProc;
    childClass.hIcon = NULL;
    childClass.hCursor = NULL;

    if (!RegisterClass(&childClass)) {
	Tcl_Panic("Unable to register TkChild class");
    }

    /*
     * Initialize input language info
     */

    if (GetLocaleInfo(LANGIDFROMLCID(PTR2INT(GetKeyboardLayout(0))),
	       LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
	       (LPTSTR) &lpCP, sizeof(lpCP)/sizeof(TCHAR))
	    && TranslateCharsetInfo(INT2PTR(lpCP), &lpCs, TCI_SRCCODEPAGE)) {
	UpdateInputLanguage((int) lpCs.ciCharset);
    }

    /*
     * Make sure we cleanup on finalize.
     */

    TkCreateExitHandler(TkWinXCleanup, (ClientData) hInstance);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinXCleanup --
 *
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
































































321
322
323
324
325
326
327
328
329



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
 *----------------------------------------------------------------------
 */

void
TkWinXCleanup(
    ClientData clientData)
{
    HINSTANCE hInstance = (HINSTANCE)clientData;

    /*
     * Clean up our own class.
     */

    if (childClassInitialized) {
	childClassInitialized = 0;
	UnregisterClassW(TK_WIN_CHILD_CLASS_NAME, hInstance);
    }

    if (unicodeEncoding != NULL) {
	Tcl_FreeEncoding(unicodeEncoding);
	unicodeEncoding = NULL;
    }

    /*
     * And let the window manager clean up its own class(es).
     */

    TkWinWmCleanup(hInstance);
    TkWinCleanupContainerList();
}

/*
 *----------------------------------------------------------------------
 *
































































 * TkWinGetPlatformTheme --
 *
 *	Return the Windows drawing style we should be using.
 *
 * Results:
 *	The return value is one of:
 *	    TK_THEME_WIN_CLASSIC	95/98/NT or XP in classic mode
 *	    TK_THEME_WIN_XP		XP not in classic mode
 *	    TK_THEME_WIN_VISTA	Vista or higher



 *
 *----------------------------------------------------------------------
 */

int
TkWinGetPlatformTheme(void)
{
    if (tkWinTheme == 0) {
	OSVERSIONINFOW os;

	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	GetVersionExW(&os);

	if (os.dwPlatformId != VER_PLATFORM_WIN32_NT) {
	    Tcl_Panic("Windows NT is the only supported platform");
	}

	/*
	 * Set tkWinTheme to be TK_THEME_WIN_(CLASSIC|XP|VISTA). The
	 * TK_THEME_WIN_CLASSIC could be set even when running under XP if the
	 * windows classic theme was selected.
	 */
	if (os.dwMajorVersion == 5 && os.dwMinorVersion >= 1) {
	    HKEY hKey;
	    LPCWSTR szSubKey = L"Control Panel\\Appearance";
	    LPCWSTR szCurrent = L"Current";
	    DWORD dwSize = 200;
	    WCHAR pBuffer[200];

	    memset(pBuffer, 0, dwSize);
	    if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0L,
		    KEY_READ, &hKey) != ERROR_SUCCESS) {
		tkWinTheme = TK_THEME_WIN_XP;
	    } else {
		RegQueryValueExW(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize);
		RegCloseKey(hKey);
		if (wcscmp(pBuffer, L"Windows Standard") == 0) {
		    tkWinTheme = TK_THEME_WIN_CLASSIC;
		} else {
		    tkWinTheme = TK_THEME_WIN_XP;
		}
	    }
	} else if (os.dwMajorVersion > 5) {
	    tkWinTheme = TK_THEME_WIN_VISTA;
	} else {
	    tkWinTheme = TK_THEME_WIN_CLASSIC;
	}
    }
    return tkWinTheme;
}

/*
 *----------------------------------------------------------------------
 *







|







|


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<
>
>
>







<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453


454


455


































456
457
458
459
460
461
462
 *----------------------------------------------------------------------
 */

void
TkWinXCleanup(
    ClientData clientData)
{
    HINSTANCE hInstance = (HINSTANCE) clientData;

    /*
     * Clean up our own class.
     */

    if (childClassInitialized) {
	childClassInitialized = 0;
	UnregisterClass(TK_WIN_CHILD_CLASS_NAME, hInstance);
    }

    if (unicodeEncoding != NULL) {
	Tcl_FreeEncoding(unicodeEncoding);
	unicodeEncoding = NULL;
    }

    /*
     * And let the window manager clean up its own class(es).
     */

    TkWinWmCleanup(hInstance);
    TkWinCleanupContainerList();
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinGetPlatformId --
 *
 *	Determines whether running under NT, 95, or Win32s, to allow runtime
 *	conditional code. Win32s is no longer supported.
 *
 * Results:
 *	The return value is one of:
 *	    VER_PLATFORM_WIN32s		Win32s on Windows 3.1.
 *	    VER_PLATFORM_WIN32_WINDOWS	Win32 on Windows 95.
 *	    VER_PLATFORM_WIN32_NT	Win32 on Windows NT
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkWinGetPlatformId(void)
{
    if (tkPlatformId == 0) {
	OSVERSIONINFOW os;

	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	GetVersionExW(&os);
	tkPlatformId = os.dwPlatformId;

	/*
	 * Set tkWinTheme to be TK_THEME_WIN_XP or TK_THEME_WIN_CLASSIC. The
	 * TK_THEME_WIN_CLASSIC could be set even when running under XP if the
	 * windows classic theme was selected.
	 */

	if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
		(os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) {
	    HKEY hKey;
	    LPCSTR szSubKey = TEXT("Control Panel\\Appearance");
	    LPCSTR szCurrent = TEXT("Current");
	    DWORD dwSize = 200;
	    char pBuffer[200];

	    memset(pBuffer, 0, dwSize);
	    if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0L,
		    KEY_READ, &hKey) != ERROR_SUCCESS) {
		tkWinTheme = TK_THEME_WIN_XP;
	    } else {
		RegQueryValueEx(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize);
		RegCloseKey(hKey);
		if (strcmp(pBuffer, "Windows Standard") == 0) {
		    tkWinTheme = TK_THEME_WIN_CLASSIC;
		} else {
		    tkWinTheme = TK_THEME_WIN_XP;
		}
	    }
	} else {
	    tkWinTheme = TK_THEME_WIN_CLASSIC;
	}
    }
    return tkPlatformId;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinGetPlatformTheme --
 *
 *	Return the Windows drawing style we should be using.
 *
 * Results:
 *	The return value is one of:
 *	    TK_THEME_WIN_CLASSIC	95/98/NT or XP in classic mode
 *	    TK_THEME_WIN_XP		XP not in classic mode

 *
 * Side effects:
 *	Could invoke TkWinGetPlatformId.
 *
 *----------------------------------------------------------------------
 */

int
TkWinGetPlatformTheme(void)
{


    if (tkPlatformId == 0) {


	TkWinGetPlatformId();


































    }
    return tkWinTheme;
}

/*
 *----------------------------------------------------------------------
 *
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *dummy,		/* Not used. */
    const char *screenName)	/* If NULL, use default string. */
{
    (void)dummy;

    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = winScreenName;
    }
    return screenName;
}

/*







|

|
|

<
<







470
471
472
473
474
475
476
477
478
479
480
481


482
483
484
485
486
487
488
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CONST char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Not used. */
    CONST char *screenName)	/* If NULL, use default string. */
{


    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = winScreenName;
    }
    return screenName;
}

/*
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555


556
557
558
559

560
561
562


563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
     * information: the number of color planes and the number of pixels per
     * plane. Need to remember both quantities so that when constructing an
     * HBITMAP for offscreen rendering, we can specify the correct value for
     * the number of planes. Otherwise the HBITMAP won't be compatible with
     * the HWND and we'll just get blank spots copied onto the screen.
     */

    screen->ext_data = (XExtData *)INT2PTR(GetDeviceCaps(dc, PLANES));
    screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);

    if (screen->root_visual != NULL) {
	ckfree(screen->root_visual);
    }
    screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
    screen->root_visual->visualid = 0;
    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
	screen->root_visual->c_class = PseudoColor;
	screen->root_visual->red_mask = 0x0;
	screen->root_visual->green_mask = 0x0;
	screen->root_visual->blue_mask = 0x0;
    } else if (screen->root_depth == 4) {
	screen->root_visual->c_class = StaticColor;
	screen->root_visual->map_entries = 16;
    } else if (screen->root_depth == 8) {
	screen->root_visual->c_class = StaticColor;
	screen->root_visual->map_entries = 256;
    } else if (screen->root_depth == 12) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 32;
	screen->root_visual->red_mask = 0xf0;
	screen->root_visual->green_mask = 0xf000;
	screen->root_visual->blue_mask = 0xf00000;
    } else if (screen->root_depth == 16) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 64;
	screen->root_visual->red_mask = 0xf8;
	screen->root_visual->green_mask = 0xfc00;
	screen->root_visual->blue_mask = 0xf80000;
    } else if (screen->root_depth >= 24) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 256;
	screen->root_visual->red_mask = 0xff;
	screen->root_visual->green_mask = 0xff00;
	screen->root_visual->blue_mask = 0xff0000;
    }
    screen->root_visual->bits_per_rgb = screen->root_depth;
    ReleaseDC(NULL, dc);

    if (screen->cmap != None) {
	XFreeColormap(display, screen->cmap);
    }
    screen->cmap = XCreateColormap(display, None, screen->root_visual,
	    AllocNone);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --
 *
 *	Create the Display structure and fill it with device specific
 *	information.
 *
 * Results:
 *	Returns a TkDisplay structure on success or NULL on failure.
 *
 * Side effects:
 *	Allocates a new TkDisplay structure.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{


    Display *display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    DWORD initialWheelTick;

    if (tsdPtr->winDisplay != NULL) {
	if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) {
	    return tsdPtr->winDisplay;
	} else {
	    return NULL;
	}
    }

    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);
    TkWinDisplayChanged(display);

    tsdPtr->winDisplay =(TkDisplay *) ckalloc(sizeof(TkDisplay));
    ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay));
    tsdPtr->winDisplay->display = display;
    tsdPtr->updatingClipboard = FALSE;

    initialWheelTick = GetTickCount();
    tsdPtr->vWheelTickPrev = initialWheelTick;
    tsdPtr->hWheelTickPrev = initialWheelTick;
    tsdPtr->vWheelAcc = 0;
    tsdPtr->hWheelAcc = 0;

    /*
     * Key map info must be available immediately, because of "send event".
     */


    TkpInitKeymapInfo(tsdPtr->winDisplay);

    /*
     * Key map info must be available immediately, because of "send event".

     */
    TkpInitKeymapInfo(tsdPtr->winDisplay);



    return tsdPtr->winDisplay;
}

Display *
XkbOpenDisplay(
	const char *name,
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    Display *display = (Display *)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    TkWinDrawable *twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));

    ZeroMemory(screen, sizeof(Screen));
    ZeroMemory(display, sizeof(Display));

    /*
     * Note that these pixel values are not palette relative.
     */

    screen->white_pixel = RGB(255, 255, 255);
    screen->black_pixel = RGB(0, 0, 0);
    screen->cmap = None;

    display->screens		= screen;
    display->nscreens		= 1;
    display->default_screen	= 0;

    twdPtr->type = TWD_WINDOW;
    twdPtr->window.winPtr = NULL;
    twdPtr->window.handle = NULL;
    screen->root = (Window)twdPtr;
    screen->display = display;

    display->display_name = (char  *)ckalloc(strlen(name) + 1);
    strcpy(display->display_name, name);

    display->cursor_font = 1;
    display->nscreens = 1;
    display->request = 1;
    display->qlen = 0;

    if (ev_rtrn) *ev_rtrn = 0;
    if (err_rtrn) *err_rtrn = 0;
    if (major_rtrn) *major_rtrn = 0;
    if (minor_rtrn) *minor_rtrn = 0;
    if (reason) *reason = 0;

    return display;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *







|



|

|



|




|


|


|





|





|


















|















|

>
>



<









|
|

|
<
|
|
>
|
<
<
|
|

<
<
<
>
>
|


<
>

<

>
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<













<
<
<
<
|

<
<
|
<
<
|
|
|
<
<
<
<
<

|







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
621

622
623
624
625


626
627
628



629
630
631
632
633

634
635

636
637
638
639
640
641











642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657




658
659


660


661
662
663





664
665
666
667
668
669
670
671
672
     * information: the number of color planes and the number of pixels per
     * plane. Need to remember both quantities so that when constructing an
     * HBITMAP for offscreen rendering, we can specify the correct value for
     * the number of planes. Otherwise the HBITMAP won't be compatible with
     * the HWND and we'll just get blank spots copied onto the screen.
     */

    screen->ext_data = INT2PTR(GetDeviceCaps(dc, PLANES));
    screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);

    if (screen->root_visual != NULL) {
	ckfree((char *) screen->root_visual);
    }
    screen->root_visual = (Visual *) ckalloc(sizeof(Visual));
    screen->root_visual->visualid = 0;
    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
	screen->root_visual->class = PseudoColor;
	screen->root_visual->red_mask = 0x0;
	screen->root_visual->green_mask = 0x0;
	screen->root_visual->blue_mask = 0x0;
    } else if (screen->root_depth == 4) {
	screen->root_visual->class = StaticColor;
	screen->root_visual->map_entries = 16;
    } else if (screen->root_depth == 8) {
	screen->root_visual->class = StaticColor;
	screen->root_visual->map_entries = 256;
    } else if (screen->root_depth == 12) {
	screen->root_visual->class = TrueColor;
	screen->root_visual->map_entries = 32;
	screen->root_visual->red_mask = 0xf0;
	screen->root_visual->green_mask = 0xf000;
	screen->root_visual->blue_mask = 0xf00000;
    } else if (screen->root_depth == 16) {
	screen->root_visual->class = TrueColor;
	screen->root_visual->map_entries = 64;
	screen->root_visual->red_mask = 0xf8;
	screen->root_visual->green_mask = 0xfc00;
	screen->root_visual->blue_mask = 0xf80000;
    } else if (screen->root_depth >= 24) {
	screen->root_visual->class = TrueColor;
	screen->root_visual->map_entries = 256;
	screen->root_visual->red_mask = 0xff;
	screen->root_visual->green_mask = 0xff00;
	screen->root_visual->blue_mask = 0xff0000;
    }
    screen->root_visual->bits_per_rgb = screen->root_depth;
    ReleaseDC(NULL, dc);

    if (screen->cmap != None) {
	XFreeColormap(display, screen->cmap);
    }
    screen->cmap = XCreateColormap(display, None, screen->root_visual,
	    AllocNone);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay --
 *
 *	Create the Display structure and fill it with device specific
 *	information.
 *
 * Results:
 *	Returns a TkDisplay structure on success or NULL on failure.
 *
 * Side effects:
 *	Allocates a new TkDisplay structure.
 *
 *----------------------------------------------------------------------
 */

TkDisplay *
TkpOpenDisplay(
    CONST char *display_name)
{
    Screen *screen;
    TkWinDrawable *twdPtr;
    Display *display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (tsdPtr->winDisplay != NULL) {
	if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) {
	    return tsdPtr->winDisplay;
	} else {
	    return NULL;
	}
    }

    display = (Display *) ckalloc(sizeof(Display));
    ZeroMemory(display, sizeof(Display));

    display->display_name = (char *) ckalloc(strlen(display_name)+1);

    strcpy(display->display_name, display_name);

    display->cursor_font = 1;
    display->nscreens = 1;


    display->request = 1;
    display->qlen = 0;




    screen = (Screen *) ckalloc(sizeof(Screen));
    ZeroMemory(screen, sizeof(Screen));
    screen->display = display;

    /*

     * Set up the root window.
     */


    twdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
    if (twdPtr == NULL) {
	return NULL;
    }
    twdPtr->type = TWD_WINDOW;











    twdPtr->window.winPtr = NULL;
    twdPtr->window.handle = NULL;
    screen->root = (Window)twdPtr;


    /*
     * Note that these pixel values are not palette relative.
     */

    screen->white_pixel = RGB(255, 255, 255);
    screen->black_pixel = RGB(0, 0, 0);
    screen->cmap = None;

    display->screens		= screen;
    display->nscreens		= 1;
    display->default_screen	= 0;





    TkWinDisplayChanged(display);



    tsdPtr->winDisplay = (TkDisplay *) ckalloc(sizeof(TkDisplay));


    ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay));
    tsdPtr->winDisplay->display = display;
    tsdPtr->updatingClipboard = FALSE;






    return tsdPtr->winDisplay;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
    tsdPtr->winDisplay = NULL;

    if (display->display_name != NULL) {
	ckfree(display->display_name);
    }
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree(display->screens->root_visual);
	}
	if (display->screens->root != None) {
	    ckfree((char *)display->screens->root);
	}
	if (display->screens->cmap != None) {
	    XFreeColormap(display, display->screens->cmap);
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipCleanup --
 *







|


|




|

|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    tsdPtr->winDisplay = NULL;

    if (display->display_name != NULL) {
	ckfree(display->display_name);
    }
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree((char *) display->screens->root_visual);
	}
	if (display->screens->root != None) {
	    ckfree((char *) display->screens->root);
	}
	if (display->screens->cmap != None) {
	    XFreeColormap(display, display->screens->cmap);
	}
	ckfree((char *) display->screens);
    }
    ckfree((char *) display);
}

/*
 *----------------------------------------------------------------------
 *
 * TkClipCleanup --
 *
684
685
686
687
688
689
690













691
692
693
694
695
696
697
698
699
700
701
702
703
704
 */

void
TkClipCleanup(
    TkDisplay *dispPtr)		/* Display associated with clipboard. */
{
    if (dispPtr->clipWindow != NULL) {













	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->applicationAtom);
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->windowAtom);

	Tk_DestroyWindow(dispPtr->clipWindow);
	Tcl_Release(dispPtr->clipWindow);
	dispPtr->clipWindow = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>
>
>
>
>
>
>
>
>






|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
 */

void
TkClipCleanup(
    TkDisplay *dispPtr)		/* Display associated with clipboard. */
{
    if (dispPtr->clipWindow != NULL) {
	/*
	 * Force the clipboard to be rendered if we are the clipboard owner.
	 */

	HWND hwnd = Tk_GetHWND(Tk_WindowId(dispPtr->clipWindow));

	if (GetClipboardOwner() == hwnd) {
	    OpenClipboard(hwnd);
	    EmptyClipboard();
	    TkWinClipboardRender(dispPtr, CF_TEXT);
	    CloseClipboard();
	}

	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->applicationAtom);
	Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
		dispPtr->windowAtom);

	Tk_DestroyWindow(dispPtr->clipWindow);
	Tcl_Release((ClientData) dispPtr->clipWindow);
	dispPtr->clipWindow = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
 */

int
XBell(
    Display *display,
    int percent)
{
    (void)display;
    (void)percent;

    MessageBeep(MB_OK);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<







780
781
782
783
784
785
786



787
788
789
790
791
792
793
 */

int
XBell(
    Display *display,
    int percent)
{



    MessageBeep(MB_OK);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;
	if (HandleIMEComposition(hwnd, lParam) == 0) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
	break;

    case WM_SETCURSOR:
	/*
	 * Short circuit the WM_SETCURSOR message since we set the cursor
	 * elsewhere.
	 */

	result = TRUE;
	break;

    case WM_CREATE:
    case WM_ERASEBKGND:
	result = 0;
	break;

    case WM_PAINT:
	GenerateXEvent(hwnd, message, wParam, lParam);
	result = DefWindowProcW(hwnd, message, wParam, lParam);
	break;

    case TK_CLAIMFOCUS:
    case TK_GEOMETRYREQ:
    case TK_ATTACHWINDOW:
    case TK_DETACHWINDOW:
    case TK_ICONIFY:







|



















|







818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;
	if (HandleIMEComposition(hwnd, lParam) == 0) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
	}
	break;

    case WM_SETCURSOR:
	/*
	 * Short circuit the WM_SETCURSOR message since we set the cursor
	 * elsewhere.
	 */

	result = TRUE;
	break;

    case WM_CREATE:
    case WM_ERASEBKGND:
	result = 0;
	break;

    case WM_PAINT:
	GenerateXEvent(hwnd, message, wParam, lParam);
	result = DefWindowProc(hwnd, message, wParam, lParam);
	break;

    case TK_CLAIMFOCUS:
    case TK_GEOMETRYREQ:
    case TK_ATTACHWINDOW:
    case TK_DETACHWINDOW:
    case TK_ICONIFY:
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
948
949
950
951
    case WM_UNICHAR:
        if (wParam == UNICODE_NOCHAR) {
	    /* If wParam is UNICODE_NOCHAR and the application processes
	     * this message, then return TRUE. */
	    result = 1;
	} else {
	    /* If the event was translated, we must return 0 */
            if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
                result = 0;
	    } else {
	        result = 1;
	    }
	}
	break;

    default:
	if (!TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
	break;
    }

    /*
     * Handle any newly queued events before returning control to Windows.
     */

    Tcl_ServiceAll();
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTranslateWinEvent --
 *
 *	This function is called by widget window functions to handle the
 *	translation from Win32 events to Tk events.
 *
 * Results:
 *	Returns 1 if the event was handled, else 0.
 *
 * Side effects:
 *	Depends on the event.
 *
 *----------------------------------------------------------------------
 */

int
TkTranslateWinEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam,
    LRESULT *resultPtr)
{
    *resultPtr = 0;
    switch (message) {
    case WM_RENDERFORMAT: {
	TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	if (winPtr) {
	    TkWinClipboardRender(winPtr->dispPtr, wParam);
	}
	return 1;
    }

    case WM_RENDERALLFORMATS: {
        TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

        if (winPtr && OpenClipboard(hwnd)) {
            /*
             * Make sure that nobody had taken ownership of the clipboard
             * before we opened it.
             */

            if (GetClipboardOwner() == hwnd) {
                TkWinClipboardRender(winPtr->dispPtr, CF_TEXT);
            }
            CloseClipboard();
        }
        return 1;
    }

    case WM_COMMAND:
    case WM_NOTIFY:
    case WM_VSCROLL:
    case WM_HSCROLL: {
	/*
	 * Reflect these messages back to the sender so that they can be
	 * handled by the window proc for the control. Note that we need to be
	 * careful not to reflect a message that is targeted to this window,
	 * or we will loop.
	 */

	HWND target = (message == WM_NOTIFY)
		? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam;

	if (target && target != hwnd) {
	    *resultPtr = SendMessageW(target, message, wParam, lParam);
	    return 1;
	}
	break;
    }

    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
    case WM_XBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_XBUTTONUP:
    case WM_MOUSEMOVE:
	TkWinPointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
	return 1;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
	if (wParam == VK_PACKET) {
	    /*
	     * This will trigger WM_CHAR event(s) with unicode data.
	     */
	    *resultPtr =
		PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam));
	    return 1;
	}
	/* else fall through */
    case WM_CLOSE:
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
    case WM_DESTROYCLIPBOARD:
    case WM_UNICHAR:
    case WM_CHAR:

    case WM_SYSKEYUP:
    case WM_KEYUP:
    case WM_MOUSEWHEEL:
    case WM_MOUSEHWHEEL:
	GenerateXEvent(hwnd, message, wParam, lParam);
	return 1;
    case WM_MENUCHAR:
	GenerateXEvent(hwnd, message, wParam, lParam);

	/*
	 * MNC_CLOSE is the only one that looks right. This is a hack.







|








|
|















|














|

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















|











<
<



<

|


<
<
<
<
<
<
<
<
<
<
<






>

|
|
|







865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

















931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957


958
959
960

961
962
963
964











965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
    case WM_UNICHAR:
        if (wParam == UNICODE_NOCHAR) {
	    /* If wParam is UNICODE_NOCHAR and the application processes
	     * this message, then return TRUE. */
	    result = 1;
	} else {
	    /* If the event was translated, we must return 0 */
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
                result = 0;
	    } else {
	        result = 1;
	    }
	}
	break;

    default:
	if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
	}
	break;
    }

    /*
     * Handle any newly queued events before returning control to Windows.
     */

    Tcl_ServiceAll();
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_TranslateWinEvent --
 *
 *	This function is called by widget window functions to handle the
 *	translation from Win32 events to Tk events.
 *
 * Results:
 *	Returns 1 if the event was handled, else 0.
 *
 * Side effects:
 *	Depends on the event.
 *
 *----------------------------------------------------------------------
 */

int
Tk_TranslateWinEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam,
    LRESULT *resultPtr)
{
    *resultPtr = 0;
    switch (message) {
    case WM_RENDERFORMAT: {
	TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	if (winPtr) {
	    TkWinClipboardRender(winPtr->dispPtr, wParam);
	}
	return 1;
    }


















    case WM_COMMAND:
    case WM_NOTIFY:
    case WM_VSCROLL:
    case WM_HSCROLL: {
	/*
	 * Reflect these messages back to the sender so that they can be
	 * handled by the window proc for the control. Note that we need to be
	 * careful not to reflect a message that is targeted to this window,
	 * or we will loop.
	 */

	HWND target = (message == WM_NOTIFY)
		? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam;

	if (target && target != hwnd) {
	    *resultPtr = SendMessage(target, message, wParam, lParam);
	    return 1;
	}
	break;
    }

    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONDBLCLK:


    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:

    case WM_MOUSEMOVE:
	Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
	return 1;












    case WM_CLOSE:
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
    case WM_DESTROYCLIPBOARD:
    case WM_UNICHAR:
    case WM_CHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_MOUSEWHEEL:
	GenerateXEvent(hwnd, message, wParam, lParam);
	return 1;
    case WM_MENUCHAR:
	GenerateXEvent(hwnd, message, wParam, lParam);

	/*
	 * MNC_CLOSE is the only one that looks right. This is a hack.
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
static void
GenerateXEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    union {XEvent x; TkKeyEvent key;} event;
    TkWindow *winPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if ((message == WM_MOUSEWHEEL) || (message == WM_MOUSEHWHEEL)) {
	union {LPARAM lParam; POINTS point;} root;
	POINT pos;
	root.lParam = lParam;

	/*
	 * Redirect mousewheel events to the window containing the cursor.
	 * That feels much less strange to users, and is how all the other
	 * platforms work.
	 */

	pos.x = root.point.x;
	pos.y = root.point.y;
	hwnd = WindowFromPoint(pos);
    }

    winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    if (!winPtr || winPtr->window == None) {
	return;
    }

    memset(&event.x, 0, sizeof(XEvent));
    event.x.xany.serial = winPtr->display->request++;
    event.x.xany.send_event = False;
    event.x.xany.display = winPtr->display;
    event.x.xany.window = winPtr->window;

    switch (message) {
    case WM_PAINT: {
	PAINTSTRUCT ps;

	event.x.type = Expose;
	BeginPaint(hwnd, &ps);
	event.x.xexpose.x = ps.rcPaint.left;
	event.x.xexpose.y = ps.rcPaint.top;
	event.x.xexpose.width = ps.rcPaint.right - ps.rcPaint.left;
	event.x.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top;
	EndPaint(hwnd, &ps);
	event.x.xexpose.count = 0;
	break;
    }

    case WM_CLOSE:
	event.x.type = ClientMessage;
	event.x.xclient.message_type =
		Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS");
	event.x.xclient.format = 32;
	event.x.xclient.data.l[0] =
		Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW");
	break;

    case WM_SETFOCUS:
    case WM_KILLFOCUS: {
	TkWindow *otherWinPtr = (TkWindow *) Tk_HWNDToWindow((HWND) wParam);








|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|




|
|
|
|
|





|

|
|
|
|

|




|
|

|
|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
















1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
static void
GenerateXEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    XEvent event;
    TkWindow *winPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

















    winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd);
    if (!winPtr || winPtr->window == None) {
	return;
    }

    memset(&event, 0, sizeof(XEvent));
    event.xany.serial = winPtr->display->request++;
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xany.window = winPtr->window;

    switch (message) {
    case WM_PAINT: {
	PAINTSTRUCT ps;

	event.type = Expose;
	BeginPaint(hwnd, &ps);
	event.xexpose.x = ps.rcPaint.left;
	event.xexpose.y = ps.rcPaint.top;
	event.xexpose.width = ps.rcPaint.right - ps.rcPaint.left;
	event.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top;
	EndPaint(hwnd, &ps);
	event.xexpose.count = 0;
	break;
    }

    case WM_CLOSE:
	event.type = ClientMessage;
	event.xclient.message_type =
		Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS");
	event.xclient.format = 32;
	event.xclient.data.l[0] =
		Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW");
	break;

    case WM_SETFOCUS:
    case WM_KILLFOCUS: {
	TkWindow *otherWinPtr = (TkWindow *) Tk_HWNDToWindow((HWND) wParam);

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
	    Tk_SetCaretPos((Tk_Window) winPtr, 0, 0, 0);
	}

	if (otherWinPtr == winPtr) {
	    return;
	}

	event.x.xany.window = winPtr->window;
	event.x.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut;
	event.x.xfocus.mode = NotifyNormal;
	event.x.xfocus.detail = NotifyNonlinear;

	/*
	 * Destroy the caret if we own it. If we are moving to another Tk
	 * window, it will reclaim and reposition it with Tk_SetCaretPos.
	 */

	if (message == WM_KILLFOCUS) {







|
|
|
|







1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
	    Tk_SetCaretPos((Tk_Window) winPtr, 0, 0, 0);
	}

	if (otherWinPtr == winPtr) {
	    return;
	}

	event.xany.window = winPtr->window;
	event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut;
	event.xfocus.mode = NotifyNormal;
	event.xfocus.detail = NotifyNonlinear;

	/*
	 * Destroy the caret if we own it. If we are moving to another Tk
	 * window, it will reclaim and reposition it with Tk_SetCaretPos.
	 */

	if (message == WM_KILLFOCUS) {
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103




1104
1105
1106
1107
1108
1109
1110
1111
	    /*
	     * We want to avoid this event if we are the ones that caused this
	     * event.
	     */

	    return;
	}
	event.x.type = SelectionClear;
	event.x.xselectionclear.selection =
		Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD");
	event.x.xselectionclear.time = TkpGetMS();
	break;

    case WM_MOUSEWHEEL:




    case WM_MOUSEHWHEEL:
    case WM_CHAR:
    case WM_UNICHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP: {
	unsigned int state = GetState(message, wParam, lParam);







|
|

|



>
>
>
>
|







1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
	    /*
	     * We want to avoid this event if we are the ones that caused this
	     * event.
	     */

	    return;
	}
	event.type = SelectionClear;
	event.xselectionclear.selection =
		Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD");
	event.xselectionclear.time = TkpGetMS();
	break;

    case WM_MOUSEWHEEL:
	/*
	 * The mouse wheel event is closer to a key event than a mouse event
	 * in that the message is sent to the window that has focus.
	 */

    case WM_CHAR:
    case WM_UNICHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP: {
	unsigned int state = GetState(message, wParam, lParam);
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
	clientPoint.y = root.point.y;
	ScreenToClient(hwnd, &clientPoint);

	/*
	 * Set up the common event fields.
	 */

	event.x.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.x.xbutton.subwindow = None;
	event.x.xbutton.x = clientPoint.x;
	event.x.xbutton.y = clientPoint.y;
	event.x.xbutton.x_root = root.point.x;
	event.x.xbutton.y_root = root.point.y;
	event.x.xbutton.state = state;
	event.x.xbutton.time = time;
	event.x.xbutton.same_screen = True;

	/*
	 * Now set up event specific fields.
	 */

	switch (message) {
	case WM_MOUSEWHEEL: {
	    /*
	     * Support for high resolution wheels (vertical).
	     */

	    DWORD wheelTick = GetTickCount();

	    if (wheelTick - tsdPtr->vWheelTickPrev < 1500) {
		tsdPtr->vWheelAcc += (short) HIWORD(wParam);
	    } else {
		tsdPtr->vWheelAcc = (short) HIWORD(wParam);
	    }
	    tsdPtr->vWheelTickPrev = wheelTick;
	    if (abs(tsdPtr->vWheelAcc) < WHEEL_DELTA) {
		return;
	    }

	    /*
	     * We have invented a new X event type to handle this event. It
	     * still uses the KeyPress struct. However, the keycode field has
	     * been overloaded to hold the zDelta of the wheel. Set nbytes to
	     * 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */

	    event.x.type = MouseWheelEvent;
	    event.x.xany.send_event = -1;
	    event.key.nbytes = 0;
	    event.x.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
	    tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA;
	    break;
	}
	case WM_MOUSEHWHEEL: {
	    /*
	     * Support for high resolution wheels (horizontal).
	     */

	    DWORD wheelTick = GetTickCount();

	    if (wheelTick - tsdPtr->hWheelTickPrev < 1500) {
		tsdPtr->hWheelAcc -= (short) HIWORD(wParam);
	    } else {
		tsdPtr->hWheelAcc = -((short) HIWORD(wParam));
	    }
	    tsdPtr->hWheelTickPrev = wheelTick;
	    if (abs(tsdPtr->hWheelAcc) < WHEEL_DELTA) {
		return;
	    }

	    /*
	     * We have invented a new X event type to handle this event. It
	     * still uses the KeyPress struct. However, the keycode field has
	     * been overloaded to hold the zDelta of the wheel. Set nbytes to
	     * 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */

	    event.x.type = MouseWheelEvent;
	    event.x.xany.send_event = -1;
	    event.key.nbytes = 0;
	    event.x.xkey.state |= ShiftMask;
	    event.x.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
	    tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA;
	    break;
	}
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	    /*
	     * Check for translated characters in the event queue. Setting
	     * xany.send_event to -1 indicates to the Windows implementation
	     * of TkpGetString() that this event was generated by windows and
	     * that the Windows extension xkey.trans_chars is filled with the
	     * MBCS characters that came from the TranslateMessage call.
	     */

	    event.x.type = KeyPress;
	    event.x.xany.send_event = -1;
	    event.x.xkey.keycode = wParam;
	    GetTranslatedKey(&event.key, (message == WM_KEYDOWN) ? WM_CHAR :
	            WM_SYSCHAR);
	    break;

	case WM_SYSKEYUP:
	case WM_KEYUP:
	    /*
	     * We don't check for translated characters on keyup because Tk
	     * won't know what to do with them. Instead, we wait for the
	     * WM_CHAR messages which will follow.
	     */

	    event.x.type = KeyRelease;
	    event.x.xkey.keycode = wParam;
	    event.key.nbytes = 0;
	    break;

	case WM_CHAR:
	    /*
	     * Synthesize both a KeyPress and a KeyRelease. Strings generated
	     * by Input Method Editor are handled in the following manner:
	     * 1. A series of WM_KEYDOWN & WM_KEYUP messages that cause







|
|
|
|
|
|
|
|
|






|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<










|
|
|
|











|
|
|







1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
















1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174












1175






















1176

1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
	clientPoint.y = root.point.y;
	ScreenToClient(hwnd, &clientPoint);

	/*
	 * Set up the common event fields.
	 */

	event.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.xbutton.subwindow = None;
	event.xbutton.x = clientPoint.x;
	event.xbutton.y = clientPoint.y;
	event.xbutton.x_root = root.point.x;
	event.xbutton.y_root = root.point.y;
	event.xbutton.state = state;
	event.xbutton.time = time;
	event.xbutton.same_screen = True;

	/*
	 * Now set up event specific fields.
	 */

	switch (message) {
	case WM_MOUSEWHEEL:
















	    /*
	     * We have invented a new X event type to handle this event. It
	     * still uses the KeyPress struct. However, the keycode field has
	     * been overloaded to hold the zDelta of the wheel. Set nbytes to
	     * 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */

	    event.type = MouseWheelEvent;
	    event.xany.send_event = -1;
	    event.xkey.nbytes = 0;












	    event.xkey.keycode = (short) HIWORD(wParam);






















	    break;

	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	    /*
	     * Check for translated characters in the event queue. Setting
	     * xany.send_event to -1 indicates to the Windows implementation
	     * of TkpGetString() that this event was generated by windows and
	     * that the Windows extension xkey.trans_chars is filled with the
	     * MBCS characters that came from the TranslateMessage call.
	     */

	    event.type = KeyPress;
	    event.xany.send_event = -1;
	    event.xkey.keycode = wParam;
	    GetTranslatedKey(&event.xkey, (message == WM_KEYDOWN) ? WM_CHAR :
	            WM_SYSCHAR);
	    break;

	case WM_SYSKEYUP:
	case WM_KEYUP:
	    /*
	     * We don't check for translated characters on keyup because Tk
	     * won't know what to do with them. Instead, we wait for the
	     * WM_CHAR messages which will follow.
	     */

	    event.type = KeyRelease;
	    event.xkey.keycode = wParam;
	    event.xkey.nbytes = 0;
	    break;

	case WM_CHAR:
	    /*
	     * Synthesize both a KeyPress and a KeyRelease. Strings generated
	     * by Input Method Editor are handled in the following manner:
	     * 1. A series of WM_KEYDOWN & WM_KEYUP messages that cause
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308


1309
1310
1311
1312



1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
	     *	  event. It is the event-consumer's responsibility to convert
	     *	  the string returned from XLookupString from system encoding
	     *	  to UTF-8.
	     * 5. And finally we get the WM_KEYUP for the "confirm typing"
	     *    character.
	     */

	    event.x.type = KeyPress;
	    event.x.xany.send_event = -1;
	    event.x.xkey.keycode = 0;
	    if ((int)wParam & 0xff00) {
		int ch1 = wParam & 0xffff;

		if ((ch1 & 0xfc00) == 0xd800) {
		    tsdPtr->surrogateBuffer = ch1;
		    return;
		}
		if ((ch1 & 0xfc00) == 0xdc00) {
		    ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) |
			    (ch1 & 0x3ff) | 0x10000;
		    tsdPtr->surrogateBuffer = 0;
		}
		event.x.xany.send_event = -3;
		event.key.nbytes = 0;
		event.x.xkey.keycode = ch1;
	    } else {
		event.key.nbytes = 1;
		event.key.trans_chars[0] = (char) wParam;

		if (IsDBCSLeadByte((BYTE) wParam)) {
		    MSG msg;

		    if ((PeekMessageW(&msg, NULL, WM_CHAR, WM_CHAR,
		            PM_NOREMOVE) != 0)
			    && (msg.message == WM_CHAR)) {
			GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR);
			event.key.nbytes = 2;
			event.key.trans_chars[1] = (char) msg.wParam;
		   }
		}
	    }
	    Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
	    event.x.type = KeyRelease;
	    break;

	case WM_UNICHAR: {


	    event.x.type = KeyPress;
	    event.x.xany.send_event = -3;
	    event.x.xkey.keycode = wParam;
	    event.key.nbytes = 0;



	    Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
	    event.x.type = KeyRelease;
	    break;
	}

	}
	break;
    }

    default:
	/*
	 * Don't know how to translate this event, so ignore it. (It probably
	 * should not have got here, but ignoring it should be harmless.)
	 */

	return;
    }

    /*
     * Post the translated event to the main Tk event queue.
     */

    Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * GetState --
 *
 *	This function constructs a state mask for the mouse buttons and
 *	modifier keys as they were before the event occurred.
 *
 * Results:
 *	Returns a composite value of all the modifier and button state flags
 *	that were set at the time the event occurred.
 *
 * Side effects:
 *	None.







|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

|
|

|
|
|
|
|
|
|
|
<
|
|



>
>
|
|
|
|
>
>
>
|
|




















|








|







1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
















1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
	     *	  event. It is the event-consumer's responsibility to convert
	     *	  the string returned from XLookupString from system encoding
	     *	  to UTF-8.
	     * 5. And finally we get the WM_KEYUP for the "confirm typing"
	     *    character.
	     */

	    event.type = KeyPress;
	    event.xany.send_event = -1;
	    event.xkey.keycode = 0;
















	    event.xkey.nbytes = 1;
	    event.xkey.trans_chars[0] = (char) wParam;

	    if (IsDBCSLeadByte((BYTE) wParam)) {
		MSG msg;

		if ((PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR,
			PM_NOREMOVE) != 0)
			&& (msg.message == WM_CHAR)) {
		    GetMessage(&msg, NULL, WM_CHAR, WM_CHAR);
		    event.xkey.nbytes = 2;
		    event.xkey.trans_chars[1] = (char) msg.wParam;
		}
	    }

	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
	    break;

	case WM_UNICHAR: {
	    char buffer[TCL_UTF_MAX+1];
	    int i;
	    event.type = KeyPress;
	    event.xany.send_event = -3;
	    event.xkey.keycode = wParam;
	    event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer);
	    for (i=0; i<event.xkey.nbytes && i<TCL_UTF_MAX; ++i) {
		event.xkey.trans_chars[i] = buffer[i];
	    }
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
	    break;
	}

	}
	break;
    }

    default:
	/*
	 * Don't know how to translate this event, so ignore it. (It probably
	 * should not have got here, but ignoring it should be harmless.)
	 */

	return;
    }

    /*
     * Post the translated event to the main Tk event queue.
     */

    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * GetState --
 *
 *	This function constructs a state mask for the mouse buttons and
 *	modifier keys as they were before the event occured.
 *
 * Results:
 *	Returns a composite value of all the modifier and button state flags
 *	that were set at the time the event occurred.
 *
 * Side effects:
 *	None.
1403
1404
1405
1406
1407
1408
1409

1410



1411
1412
1413
1414
1415
1416
1417
	}
	if (prevState) {
	    state |= mask;
	} else {
	    state &= ~mask;
	}
	if (HIWORD(lParam) & KF_EXTENDED) {

	    state |= EXTENDED_MASK;



	}
    }
    return state;
}

/*
 *----------------------------------------------------------------------







>
|
>
>
>







1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
	}
	if (prevState) {
	    state |= mask;
	} else {
	    state &= ~mask;
	}
	if (HIWORD(lParam) & KF_EXTENDED) {
	    if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) {
		state |= EXTENDED_MASK;
	    } else {
		state &= ~EXTENDED_MASK;
	    }
	}
    }
    return state;
}

/*
 *----------------------------------------------------------------------
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462

1463
1464
1465
1466
1467
1468
1469
 *	queue.
 *
 *----------------------------------------------------------------------
 */

static void
GetTranslatedKey(
    TkKeyEvent *xkey,
    UINT type)
{
    MSG msg;

    xkey->nbytes = 0;

    while ((xkey->nbytes < XMaxTransChars)
	    && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) {
	if (msg.message != type) {
	    break;
	}

	GetMessageA(&msg, NULL, type, type);

	/*
	 * If this is a normal character message, we may need to strip off the
	 * Alt modifier (e.g. Alt-digits). Note that we don't want to do this
	 * for system messages, because those were presumably generated as an
	 * Alt-char sequence (e.g. accelerator keys).
	 */

	if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) {
	    xkey->keyEvent.state = 0;
	}
	xkey->trans_chars[xkey->nbytes++] = (char) msg.wParam;


	if (((unsigned short) msg.wParam) > ((unsigned short) 0xff)) {
	    /*
	     * Some "addon" input devices, such as the popular PenPower
	     * Chinese writing pad, generate 16 bit values in WM_CHAR messages
	     * (instead of passing them in two separate WM_CHAR messages
	     * containing two 8-bit values.







|







|




|









|

|
>







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
 *	queue.
 *
 *----------------------------------------------------------------------
 */

static void
GetTranslatedKey(
    XKeyEvent *xkey,
    UINT type)
{
    MSG msg;

    xkey->nbytes = 0;

    while ((xkey->nbytes < XMaxTransChars)
	    && PeekMessage(&msg, NULL, type, type, PM_NOREMOVE)) {
	if (msg.message != type) {
	    break;
	}

	GetMessage(&msg, NULL, type, type);

	/*
	 * If this is a normal character message, we may need to strip off the
	 * Alt modifier (e.g. Alt-digits). Note that we don't want to do this
	 * for system messages, because those were presumably generated as an
	 * Alt-char sequence (e.g. accelerator keys).
	 */

	if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) {
	    xkey->state = 0;
	}
	xkey->trans_chars[xkey->nbytes] = (char) msg.wParam;
	xkey->nbytes++;

	if (((unsigned short) msg.wParam) > ((unsigned short) 0xff)) {
	    /*
	     * Some "addon" input devices, such as the popular PenPower
	     * Chinese writing pad, generate 16 bit values in WM_CHAR messages
	     * (instead of passing them in two separate WM_CHAR messages
	     * containing two 8-bit values.
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
    CHARSETINFO charsetInfo;
    Tcl_Encoding encoding;
    char codepage[4 + TCL_INTEGER_SPACE];

    if (keyInputCharset == charset) {
	return;
    }
    if (TranslateCharsetInfo((DWORD*)INT2PTR(charset), &charsetInfo,
	    TCI_SRCCHARSET) == 0) {
	/*
	 * Some mysterious failure.
	 */

	return;
    }

    if (charsetInfo.ciACP == CP_UTF8) {
	strcpy(codepage, "utf-8");
    } else {
	sprintf(codepage, "cp%d", charsetInfo.ciACP);
    }

    if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
	/*
	 * The encoding is not supported by Tcl.
	 */

	return;







|








<
<
<
|
<







1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479



1480

1481
1482
1483
1484
1485
1486
1487
    CHARSETINFO charsetInfo;
    Tcl_Encoding encoding;
    char codepage[4 + TCL_INTEGER_SPACE];

    if (keyInputCharset == charset) {
	return;
    }
    if (TranslateCharsetInfo(INT2PTR(charset), &charsetInfo,
	    TCI_SRCCHARSET) == 0) {
	/*
	 * Some mysterious failure.
	 */

	return;
    }




    wsprintfA(codepage, "cp%d", charsetInfo.ciACP);


    if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
	/*
	 * The encoding is not supported by Tcl.
	 */

	return;
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
 *----------------------------------------------------------------------
 */

Tcl_Encoding
TkWinGetUnicodeEncoding(void)
{
    if (unicodeEncoding == NULL) {
	unicodeEncoding = Tcl_GetEncoding(NULL, "utf-16");
	if (unicodeEncoding == NULL) {
	    unicodeEncoding = Tcl_GetEncoding(NULL, "unicode");
	}
    }
    return unicodeEncoding;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleIMEComposition --
 *
 *	This function works around a deficiency in some versions of Windows
 *	2000 to make it possible to entry multi-lingual characters under all
 *	versions of Windows 2000.
 *
 *	When an Input Method Editor (IME) is ready to send input characters to
 *	an application, it sends a WM_IME_COMPOSITION message with the
 *	GCS_RESULTSTR. However, The DefWindowProcW() on English Windows 2000
 *	arbitrarily converts all non-Latin-1 characters in the composition to
 *	"?".
 *
 *	This function correctly processes the composition data and sends the
 *	UNICODE values of the composed characters to TK's event queue.
 *
 * Results:







<
<
|
<









|





|







1534
1535
1536
1537
1538
1539
1540


1541

1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
 *----------------------------------------------------------------------
 */

Tcl_Encoding
TkWinGetUnicodeEncoding(void)
{
    if (unicodeEncoding == NULL) {


	unicodeEncoding = Tcl_GetEncoding(NULL, "unicode");

    }
    return unicodeEncoding;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleIMEComposition --
 *
 *	This function works around a definciency in some versions of Windows
 *	2000 to make it possible to entry multi-lingual characters under all
 *	versions of Windows 2000.
 *
 *	When an Input Method Editor (IME) is ready to send input characters to
 *	an application, it sends a WM_IME_COMPOSITION message with the
 *	GCS_RESULTSTR. However, The DefWindowProc() on English Windows 2000
 *	arbitrarily converts all non-Latin-1 characters in the composition to
 *	"?".
 *
 *	This function correctly processes the composition data and sends the
 *	UNICODE values of the composed characters to TK's event queue.
 *
 * Results:
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641

1642


1643

1644
1645
1646
1647
1648
1649

1650




1651








1652















1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674


1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
























1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
static int
HandleIMEComposition(
    HWND hwnd,			/* Window receiving the message. */
    LPARAM lParam)		/* Flags for the WM_IME_COMPOSITION message */
{
    HIMC hIMC;
    int n;
    int high = 0;

    if ((lParam & GCS_RESULTSTR) == 0) {
	/*
	 * Composition is not finished yet.
	 */

	return 0;
    }

    hIMC = ImmGetContext(hwnd);
    if (!hIMC) {
	return 0;
    }


    n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);




    if (n > 0) {
	WCHAR *buff = (WCHAR *) ckalloc(n);
	TkWindow *winPtr;
	XEvent event;
	int i;


	n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2;













	/*















	 * Set up the fields pertinent to key event.
	 *
	 * We set send_event to the special value of -3, so that TkpGetString
	 * in tkWinKey.c knows that keycode already contains a UNICODE
	 * char and there's no need to do encoding conversion.
	 *
	 * Note that the event *must* be zeroed out first; Tk plays cunning
	 * games with the overalls structure. [Bug 2992129]
	 */

	winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	memset(&event, 0, sizeof(XEvent));
	event.xkey.serial = winPtr->display->request++;
	event.xkey.send_event = -3;
	event.xkey.display = winPtr->display;
	event.xkey.window = winPtr->window;
	event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.xkey.subwindow = None;
	event.xkey.state = TkWinGetModifierState();
	event.xkey.time = TkpGetMS();
	event.xkey.same_screen = True;



	for (i=0; i<n; ) {
	    /*
	     * Simulate a pair of KeyPress and KeyRelease events for each
	     * UNICODE character in the composition.
	     */

	    event.xkey.keycode = buff[i++];

	    if ((event.xkey.keycode & 0xfc00) == 0xd800) {
		high = ((event.xkey.keycode & 0x3ff) << 10) + 0x10000;
		break;
	    } else if (high && (event.xkey.keycode & 0xfc00) == 0xdc00) {
		event.xkey.keycode &= 0x3ff;
		event.xkey.keycode += high;
		high = 0;
	    }
	    event.type = KeyPress;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

	    event.type = KeyRelease;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	}

	ckfree(buff);
    }
    ImmReleaseContext(hwnd, hIMC);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
























 * TkWinResendEvent --
 *
 *	This function converts an X event into a Windows event and invokes the
 *	specified window function.
 *
 * Results:
 *	A standard Windows result.
 *
 * Side effects:
 *	Invokes the window function
 *







|














>
|
>
>
|
>

|




>
|
>
>
>
>

>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|










|







>
>







<
|
<
<
<
<
|
<
<
|
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669

1670




1671


1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
static int
HandleIMEComposition(
    HWND hwnd,			/* Window receiving the message. */
    LPARAM lParam)		/* Flags for the WM_IME_COMPOSITION message */
{
    HIMC hIMC;
    int n;
    BOOL isWinNT = (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT);

    if ((lParam & GCS_RESULTSTR) == 0) {
	/*
	 * Composition is not finished yet.
	 */

	return 0;
    }

    hIMC = ImmGetContext(hwnd);
    if (!hIMC) {
	return 0;
    }

    if (isWinNT) {
	n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
    } else {
	n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, NULL, 0);
    }

    if (n > 0) {
	char *buff = ckalloc((unsigned) n);
	TkWindow *winPtr;
	XEvent event;
	int i;

	if (isWinNT) {
	    n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff,
		    (unsigned) n);
	} else {
	    Tcl_DString utfString, unicodeString;
	    Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();

	    n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, buff,
		    (unsigned) n);
	    Tcl_DStringInit(&utfString);
	    Tcl_ExternalToUtfDString(keyInputEncoding, buff, n, &utfString);
	    Tcl_UtfToExternalDString(unicodeEncoding,
		    Tcl_DStringValue(&utfString), -1, &unicodeString);
	    i = Tcl_DStringLength(&unicodeString);
	    if (n < i) {
		/*
		 * Only alloc more space if we need, otherwise just use what
		 * we've created. Don't realloc as that may copy data we no
		 * longer need.
		 */

		ckfree((char *) buff);
		buff = (char *) ckalloc((unsigned) i);
	    }
	    n = i;
	    memcpy(buff, Tcl_DStringValue(&unicodeString), (unsigned) n);
	    Tcl_DStringFree(&utfString);
	    Tcl_DStringFree(&unicodeString);
	}

	/*
	 * Set up the fields pertinent to key event.
	 *
	 * We set send_event to the special value of -2, so that TkpGetString
	 * in tkWinKey.c knows that trans_chars[] already contains a UNICODE
	 * char and there's no need to do encoding conversion.
	 *
	 * Note that the event *must* be zeroed out first; Tk plays cunning
	 * games with the overalls structure. [Bug 2992129]
	 */

	winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	memset(&event, 0, sizeof(XEvent));
	event.xkey.serial = winPtr->display->request++;
	event.xkey.send_event = -2;
	event.xkey.display = winPtr->display;
	event.xkey.window = winPtr->window;
	event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.xkey.subwindow = None;
	event.xkey.state = TkWinGetModifierState();
	event.xkey.time = TkpGetMS();
	event.xkey.same_screen = True;
	event.xkey.keycode = 0;
	event.xkey.nbytes = 2;

	for (i=0; i<n; ) {
	    /*
	     * Simulate a pair of KeyPress and KeyRelease events for each
	     * UNICODE character in the composition.
	     */


	    event.xkey.trans_chars[0] = (char) buff[i++];




	    event.xkey.trans_chars[1] = (char) buff[i++];



	    event.type = KeyPress;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

	    event.type = KeyRelease;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	}

	ckfree(buff);
    }
    ImmReleaseContext(hwnd, hIMC);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeXId --
 *
 *	This interface is not needed under Windows.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeXId(
    Display *display,
    XID xid)
{
    /* Do nothing */
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinResendEvent --
 *
 *	This function converts an X event into a Windows event and invokes the
 *	specified windo function.
 *
 * Results:
 *	A standard Windows result.
 *
 * Side effects:
 *	Invokes the window function
 *
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
	msg = WM_MBUTTONDOWN;
	wparam = MK_MBUTTON;
	break;
    case Button3:
	msg = WM_RBUTTONDOWN;
	wparam = MK_RBUTTON;
	break;
    case Button8:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
	break;
    case Button9:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
	break;
    default:
	return 0;
    }

    if (eventPtr->xbutton.state & Button1Mask) {
	wparam |= MK_LBUTTON;
    }
    if (eventPtr->xbutton.state & Button2Mask) {
	wparam |= MK_MBUTTON;
    }
    if (eventPtr->xbutton.state & Button3Mask) {
	wparam |= MK_RBUTTON;
    }
    if (eventPtr->xbutton.state & Button4Mask) {
	wparam |= MK_XBUTTON1;
    }
    if (eventPtr->xbutton.state & Button5Mask) {
	wparam |= MK_XBUTTON2;
    }
    if (eventPtr->xbutton.state & ShiftMask) {
	wparam |= MK_SHIFT;
    }
    if (eventPtr->xbutton.state & ControlMask) {
	wparam |= MK_CONTROL;
    }
    lparam = MAKELPARAM((short) eventPtr->xbutton.x,
	    (short) eventPtr->xbutton.y);
    return CallWindowProcW(wndproc, hwnd, msg, wparam, lparam);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetMS --
 *







<
<
<
<
<
<
<
<













<
<
<
<
<
<








|







1747
1748
1749
1750
1751
1752
1753








1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766






1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
	msg = WM_MBUTTONDOWN;
	wparam = MK_MBUTTON;
	break;
    case Button3:
	msg = WM_RBUTTONDOWN;
	wparam = MK_RBUTTON;
	break;








    default:
	return 0;
    }

    if (eventPtr->xbutton.state & Button1Mask) {
	wparam |= MK_LBUTTON;
    }
    if (eventPtr->xbutton.state & Button2Mask) {
	wparam |= MK_MBUTTON;
    }
    if (eventPtr->xbutton.state & Button3Mask) {
	wparam |= MK_RBUTTON;
    }






    if (eventPtr->xbutton.state & ShiftMask) {
	wparam |= MK_SHIFT;
    }
    if (eventPtr->xbutton.state & ControlMask) {
	wparam |= MK_CONTROL;
    }
    lparam = MAKELPARAM((short) eventPtr->xbutton.x,
	    (short) eventPtr->xbutton.y);
    return CallWindowProc(wndproc, hwnd, msg, wparam, lparam);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetMS --
 *
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958



1959




1960














1961
1962
1963
1964
1965
1966
1967
1968
1969
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
 *	Return the number of milliseconds the user was inactive.
 *
 * Results:
 *	Milliseconds of user inactive time or -1 if GetLastInputInfo
 *	returns an error.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
     Display *dpy)		/* Ignored on Windows */
{
    LASTINPUTINFO li;



    (void)dpy;



















    li.cbSize = sizeof(li);
    if (!GetLastInputInfo(&li)) {
	return -1;
    }

    /*
     * Last input info is in milliseconds, since restart time.
     */








|
|











|
>
>
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
 *	Return the number of milliseconds the user was inactive.
 *
 * Results:
 *	Milliseconds of user inactive time or -1 if the user32.dll doesn't
 *	have the symbol GetLastInputInfo or GetLastInputInfo returns an error.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
     Display *dpy)		/* Ignored on Windows */
{
    struct tagLASTINPUTINFO {
	UINT cbSize;
	DWORD dwTime;
    } li;

    /*
     * Multiple settings of either of these variables should be OK; any thread
     * hazards should just cause inefficiency...
     */

    static FARPROC pfnGetLastInputInfo = NULL;
    static int initinfo = 0;

    if (!initinfo) {
	HMODULE hMod = GetModuleHandleA("USER32.DLL");

	initinfo = 1;
	if (hMod){
	    pfnGetLastInputInfo = GetProcAddress(hMod, "GetLastInputInfo");
	}
    }
    if (pfnGetLastInputInfo == NULL) {
	return -1;
    }
    li.cbSize = sizeof(li);
    if (!(BOOL)(pfnGetLastInputInfo)(&li)) {
	return -1;
    }

    /*
     * Last input info is in milliseconds, since restart time.
     */

1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
 *
 *	Reset the user inactivity timer
 *
 * Results:
 *	none
 *
 * Side effects:
 *	The user inactivity timer of the underlying windowing system is reset
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    INPUT inp;
    (void)dpy;

    inp.type = INPUT_MOUSE;
    inp.mi.dx = 0;
    inp.mi.dy = 0;
    inp.mi.mouseData = 0;
    inp.mi.dwFlags = MOUSEEVENTF_MOVE;
    inp.mi.time = 0;







|










<







1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006

2007
2008
2009
2010
2011
2012
2013
 *
 *	Reset the user inactivity timer
 *
 * Results:
 *	none
 *
 * Side effects:
 *	The user inactivity timer of the underlaying windowing system is reset
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    INPUT inp;


    inp.type = INPUT_MOUSE;
    inp.mi.dx = 0;
    inp.mi.dy = 0;
    inp.mi.mouseData = 0;
    inp.mi.dwFlags = MOUSEEVENTF_MOVE;
    inp.mi.time = 0;

Changes to win/ttkWinMonitor.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 */

typedef struct {
    const char *name;
    int index;
} SystemColorEntry;

static const SystemColorEntry sysColors[] = {
	{ "System3dDarkShadow",		COLOR_3DDKSHADOW },
	{ "System3dLight",		COLOR_3DLIGHT },
	{ "SystemActiveBorder",		COLOR_ACTIVEBORDER },
	{ "SystemActiveCaption",	COLOR_ACTIVECAPTION },
	{ "SystemAppWorkspace",		COLOR_APPWORKSPACE },
	{ "SystemBackground",		COLOR_BACKGROUND },
	{ "SystemButtonFace",		COLOR_BTNFACE },







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 */

typedef struct {
    const char *name;
    int index;
} SystemColorEntry;

static SystemColorEntry sysColors[] = {
	{ "System3dDarkShadow",		COLOR_3DDKSHADOW },
	{ "System3dLight",		COLOR_3DLIGHT },
	{ "SystemActiveBorder",		COLOR_ACTIVEBORDER },
	{ "SystemActiveCaption",	COLOR_ACTIVECAPTION },
	{ "SystemAppWorkspace",		COLOR_APPWORKSPACE },
	{ "SystemBackground",		COLOR_BACKGROUND },
	{ "SystemButtonFace",		COLOR_BTNFACE },
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
	{ "SystemWindowText",		COLOR_WINDOWTEXT },
	{ NULL, 0 }
};

static void RegisterSystemColors(Tcl_Interp *interp)
{
    Ttk_ResourceCache cache = Ttk_GetResourceCache(interp);
    const SystemColorEntry *sysColor;

    for (sysColor = sysColors; sysColor->name; ++sysColor) {
	DWORD pixel = GetSysColor(sysColor->index);
	XColor colorSpec;
	colorSpec.red = GetRValue(pixel) * 257;
	colorSpec.green = GetGValue(pixel) * 257;
	colorSpec.blue = GetBValue(pixel) * 257;
	Ttk_RegisterNamedColor(cache, sysColor->name, &colorSpec);
    }
}

static HWND
CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp)
{
    WNDCLASSEXW wc;
    HWND       hwnd = NULL;
    WCHAR      title[32] = L"TtkMonitorWindow";
    WCHAR      name[32] = L"TtkMonitorClass";

    wc.cbSize        = sizeof(WNDCLASSEXW);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hinst;
    wc.hIcon         = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wc.hIconSm       = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wc.hCursor       = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszMenuName  = name;
    wc.lpszClassName = name;

    if (RegisterClassExW(&wc)) {
	hwnd = CreateWindowW( name, title, WS_OVERLAPPEDWINDOW,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
	    NULL, NULL, hinst, NULL );
	SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) interp);
	ShowWindow(hwnd, SW_HIDE);
	UpdateWindow(hwnd);
    }
    return hwnd;
}

static void
DestroyThemeMonitorWindow(void *clientData)
{
    HWND hwnd = (HWND)clientData;
    DestroyWindow(hwnd);
}

static LRESULT WINAPI
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
    Ttk_Theme theme;

    switch (msg) {
    case WM_DESTROY:
	break;

    case WM_SYSCOLORCHANGE:
	RegisterSystemColors(interp);
	break;

    case WM_THEMECHANGED:
	/*
         * Reset the application theme.
         * On windows, it is possible to sign in as a second user, change
         * the theme to 'winnative' (by setting the ui to 'best performance'),
         * which is a machine-wide change, and then sign back on to the original user.
         * Ttk_UseTheme needs to be executed again in order to process the fallback
         * from vista/xpnative to winnative.

	 */

	theme = Ttk_GetCurrentTheme(interp);
	if (theme) {
	    Ttk_UseTheme(interp, theme);
	    /* @@@ What to do about errors here? */
	}
	break;
    }
    return DefWindowProcW(hwnd, msg, wp, lp);
}

/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd);

MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp)
{
    HWND hwnd;

    hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp);
    Ttk_RegisterCleanup(interp, hwnd, DestroyThemeMonitorWindow);

    TtkWinTheme_Init(interp, hwnd);
    TtkXPTheme_Init(interp, hwnd);

    return TCL_OK;
}







|














|

|
|

|





|
|
|




|
|


|
















|












|
<
|
<
<
<
>


|






|














|






51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
	{ "SystemWindowText",		COLOR_WINDOWTEXT },
	{ NULL, 0 }
};

static void RegisterSystemColors(Tcl_Interp *interp)
{
    Ttk_ResourceCache cache = Ttk_GetResourceCache(interp);
    SystemColorEntry *sysColor;

    for (sysColor = sysColors; sysColor->name; ++sysColor) {
	DWORD pixel = GetSysColor(sysColor->index);
	XColor colorSpec;
	colorSpec.red = GetRValue(pixel) * 257;
	colorSpec.green = GetGValue(pixel) * 257;
	colorSpec.blue = GetBValue(pixel) * 257;
	Ttk_RegisterNamedColor(cache, sysColor->name, &colorSpec);
    }
}

static HWND
CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp)
{
    WNDCLASSEX wc;
    HWND       hwnd = NULL;
    TCHAR      title[32] = TEXT("TtkMonitorWindow");
    TCHAR      name[32] = TEXT("TtkMonitorClass");

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hinst;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszMenuName  = name;
    wc.lpszClassName = name;

    if (RegisterClassEx(&wc)) {
	hwnd = CreateWindow( name, title, WS_OVERLAPPEDWINDOW,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
	    NULL, NULL, hinst, NULL );
	SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)interp);
	ShowWindow(hwnd, SW_HIDE);
	UpdateWindow(hwnd);
    }
    return hwnd;
}

static void
DestroyThemeMonitorWindow(void *clientData)
{
    HWND hwnd = (HWND)clientData;
    DestroyWindow(hwnd);
}

static LRESULT WINAPI
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    Ttk_Theme theme;

    switch (msg) {
    case WM_DESTROY:
	break;

    case WM_SYSCOLORCHANGE:
	RegisterSystemColors(interp);
	break;

    case WM_THEMECHANGED:
	/*
	 * Reset the application theme to 'xpnative' if present,

	 * which will in turn fall back to 'winnative' if XP theming



	 * is disabled.
	 */

	theme = Ttk_GetTheme(interp, "xpnative");
	if (theme) {
	    Ttk_UseTheme(interp, theme);
	    /* @@@ What to do about errors here? */
	}
	break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd);

MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp)
{
    HWND hwnd;

    hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp);
    Ttk_RegisterCleanup(interp, (ClientData)hwnd, DestroyThemeMonitorWindow);

    TtkWinTheme_Init(interp, hwnd);
    TtkXPTheme_Init(interp, hwnd);

    return TCL_OK;
}

Changes to win/ttkWinTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* winTheme.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net>
 */

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>

#ifndef DFCS_HOT	/* Windows 98/Me, Windows 2000/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

/*
 * BoxToRect --









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* winTheme.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net>
 */

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>

#ifndef DFCS_HOT	/* Windows 98/Me, Windows 200/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

/*
 * BoxToRect --
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    }
}

/*------------------------------------------------------------------------
 * +++ State tables for FrameControlElements.
 */

static const Ttk_StateTable checkbutton_statemap[] = { /* see also SF#1865898 */
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_INACTIVE,
    	TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_PUSHED,
    	TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_HOT,
    	TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED,
    	TTK_STATE_ALTERNATE, 0 },

    { DFCS_CHECKED|DFCS_INACTIVE, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
    { DFCS_CHECKED|DFCS_PUSHED,   TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0 },
    { DFCS_CHECKED|DFCS_HOT,      TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 },
    { DFCS_CHECKED,	          TTK_STATE_SELECTED, 0 },

    { DFCS_INACTIVE, TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED,   TTK_STATE_PRESSED, 0 },
    { DFCS_HOT,      TTK_STATE_ACTIVE, 0 },
    { 0, 0, 0 },
};

static const Ttk_StateTable pushbutton_statemap[] = {
    { DFCS_INACTIVE,	  TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED,	  TTK_STATE_PRESSED, 0 },
    { DFCS_HOT,		  TTK_STATE_ACTIVE, 0 },
    { 0, 0, 0 }
};

static const Ttk_StateTable arrow_statemap[] = {
    { DFCS_INACTIVE,            TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED | DFCS_FLAT,  TTK_STATE_PRESSED,  0 },
    { 0, 0, 0 }
};

/*------------------------------------------------------------------------
 * +++ FrameControlElement --
 * 	General-purpose element for things drawn with DrawFrameControl
 */
typedef struct {
    const char *name;		/* element name */
    int classId;		/* class id for DrawFrameControl */
    int partId;			/* part id for DrawFrameControl  */
    unsigned cxId;			/* system metric ids for width/height... */
    unsigned cyId;			/* ... or size if FIXEDSIZE bit set */
    const Ttk_StateTable *stateMap;	/* map Tk states to Win32 flags */
    Ttk_Padding margins;	/* additional placement padding */
} FrameControlElementData;

#define _FIXEDSIZE  0x80000000UL
#define _HALFMETRIC 0x40000000UL
#define FIXEDSIZE(id) (id|_FIXEDSIZE)
#define HALFMETRIC(id) (id|_HALFMETRIC)
#define GETMETRIC(m) \
    ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0xFFFFFFF))

static const FrameControlElementData FrameControlElements[] = {
    { "Checkbutton.indicator",
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "Radiobutton.indicator",
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "uparrow",







|




















|






|













|
|
|



|
|



|

|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    }
}

/*------------------------------------------------------------------------
 * +++ State tables for FrameControlElements.
 */

static Ttk_StateTable checkbutton_statemap[] = { /* see also SF#1865898 */
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_INACTIVE,
    	TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_PUSHED,
    	TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_HOT,
    	TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0 },
    { DFCS_BUTTON3STATE|DFCS_CHECKED,
    	TTK_STATE_ALTERNATE, 0 },

    { DFCS_CHECKED|DFCS_INACTIVE, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
    { DFCS_CHECKED|DFCS_PUSHED,   TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0 },
    { DFCS_CHECKED|DFCS_HOT,      TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 },
    { DFCS_CHECKED,	          TTK_STATE_SELECTED, 0 },

    { DFCS_INACTIVE, TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED,   TTK_STATE_PRESSED, 0 },
    { DFCS_HOT,      TTK_STATE_ACTIVE, 0 },
    { 0, 0, 0 },
};

static Ttk_StateTable pushbutton_statemap[] = {
    { DFCS_INACTIVE,	  TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED,	  TTK_STATE_PRESSED, 0 },
    { DFCS_HOT,		  TTK_STATE_ACTIVE, 0 },
    { 0, 0, 0 }
};

static Ttk_StateTable arrow_statemap[] = {
    { DFCS_INACTIVE,            TTK_STATE_DISABLED, 0 },
    { DFCS_PUSHED | DFCS_FLAT,  TTK_STATE_PRESSED,  0 },
    { 0, 0, 0 }
};

/*------------------------------------------------------------------------
 * +++ FrameControlElement --
 * 	General-purpose element for things drawn with DrawFrameControl
 */
typedef struct {
    const char *name;		/* element name */
    int classId;		/* class id for DrawFrameControl */
    int partId;			/* part id for DrawFrameControl  */
    int cxId;			/* system metric ids for width/height... */
    int cyId;			/* ... or size if FIXEDSIZE bit set */
    Ttk_StateTable *stateMap;	/* map Tk states to Win32 flags */
    Ttk_Padding margins;	/* additional placement padding */
} FrameControlElementData;

#define _FIXEDSIZE  0x80000000L
#define _HALFMETRIC 0x40000000L
#define FIXEDSIZE(id) (id|_FIXEDSIZE)
#define HALFMETRIC(id) (id|_HALFMETRIC)
#define GETMETRIC(m) \
    ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0x0fffffff))

static FrameControlElementData FrameControlElements[] = {
    { "Checkbutton.indicator",
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "Radiobutton.indicator",
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "uparrow",
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

/* ---------------------------------------------------------------------- */

static void FrameControlElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FrameControlElementData *p = (FrameControlElementData *)clientData;
    int cx = GETMETRIC(p->cxId);
    int cy = GETMETRIC(p->cyId);
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    if (p->cxId & _HALFMETRIC) cx /= 2;
    if (p->cyId & _HALFMETRIC) cy /= 2;
    *widthPtr = cx + Ttk_PaddingWidth(p->margins);
    *heightPtr = cy + Ttk_PaddingHeight(p->margins);
}

static void FrameControlElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FrameControlElementData *elementData = (FrameControlElementData *)clientData;
    RECT rc = BoxToRect(Ttk_PadBox(b, elementData->margins));
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    (void)elementRecord;

    DrawFrameControl(hdc, &rc,
	elementData->classId,
	elementData->partId|Ttk_StateTableLookup(elementData->stateMap, state));
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec FrameControlElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    FrameControlElementSize,
    FrameControlElementDraw
};

/*----------------------------------------------------------------------
 * +++ Border element implementation.
 */

typedef struct {
    Tcl_Obj	*reliefObj;
} BorderElement;

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj), "flat" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void BorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void BorderElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    BorderElement *border = (BorderElement *)elementRecord;
    RECT rc = BoxToRect(b);
    int relief = TK_RELIEF_FLAT;
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)state;

    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);

    if (relief != TK_RELIEF_FLAT) {
	UINT xFlags = (relief == TK_RELIEF_SOLID) ? BF_FLAT : 0;
	hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
	DrawEdge(hdc, &rc, ReliefToEdge(relief), BF_RECT | xFlags);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

static const Ttk_ElementSpec BorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BorderElement),
    BorderElementOptions,
    BorderElementSize,
    BorderElementDraw
};

/*
 * Entry field borders:
 * Sunken border; also fill with window color.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
    	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void FieldElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)state;

    Tk_Fill3DRectangle(
	tkwin, d, bg, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*------------------------------------------------------------------------
 * +++ Button borders.
 *	Drawn with DrawFrameControl instead of DrawEdge;
 *	Also draw default indicator and focus ring.
 */
typedef struct {
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*highlightColorObj;
    Tcl_Obj	*defaultStateObj;
} ButtonBorderElement;

static const Ttk_ElementOptionSpec ButtonBorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF,
	offsetof(ButtonBorderElement,reliefObj), "flat" },
    { "-highlightcolor",TK_OPTION_COLOR,
	offsetof(ButtonBorderElement,highlightColorObj), "black" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void ButtonBorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_RAISED;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    short int cx, cy;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
    cx = GetSystemMetrics(SM_CXEDGE);
    cy = GetSystemMetrics(SM_CYEDGE);

    /* Space for default indicator:







|


<
<
<
<










|



<







|















|
|
|



|


<
<
<
<
<
<





|


|




<
<











|
















|

|
|



|


<
<
<
<
<
<





|


|




<
<









|


















|

|

|

|
|



|


|

|

<
<
<
<







143
144
145
146
147
148
149
150
151
152




153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198






199
200
201
202
203
204
205
206
207
208
209
210
211


212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249






250
251
252
253
254
255
256
257
258
259
260
261
262


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308




309
310
311
312
313
314
315

/* ---------------------------------------------------------------------- */

static void FrameControlElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FrameControlElementData *p = clientData;
    int cx = GETMETRIC(p->cxId);
    int cy = GETMETRIC(p->cyId);




    if (p->cxId & _HALFMETRIC) cx /= 2;
    if (p->cyId & _HALFMETRIC) cy /= 2;
    *widthPtr = cx + Ttk_PaddingWidth(p->margins);
    *heightPtr = cy + Ttk_PaddingHeight(p->margins);
}

static void FrameControlElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FrameControlElementData *elementData = clientData;
    RECT rc = BoxToRect(Ttk_PadBox(b, elementData->margins));
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);


    DrawFrameControl(hdc, &rc,
	elementData->classId,
	elementData->partId|Ttk_StateTableLookup(elementData->stateMap, state));
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec FrameControlElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    FrameControlElementSize,
    FrameControlElementDraw
};

/*----------------------------------------------------------------------
 * +++ Border element implementation.
 */

typedef struct {
    Tcl_Obj	*reliefObj;
} BorderElement;

static Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-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)
{






    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void BorderElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    BorderElement *border = elementRecord;
    RECT rc = BoxToRect(b);
    int relief = TK_RELIEF_FLAT;
    TkWinDCState dcState;
    HDC hdc;



    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);

    if (relief != TK_RELIEF_FLAT) {
	UINT xFlags = (relief == TK_RELIEF_SOLID) ? BF_FLAT : 0;
	hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
	DrawEdge(hdc, &rc, ReliefToEdge(relief), BF_RECT | xFlags);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

static Ttk_ElementSpec BorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BorderElement),
    BorderElementOptions,
    BorderElementSize,
    BorderElementDraw
};

/*
 * Entry field borders:
 * Sunken border; also fill with window color.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;
} FieldElement;

static Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-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->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void FieldElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;



    Tk_Fill3DRectangle(
	tkwin, d, bg, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*------------------------------------------------------------------------
 * +++ Button borders.
 *	Drawn with DrawFrameControl instead of DrawEdge;
 *	Also draw default indicator and focus ring.
 */
typedef struct {
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*highlightColorObj;
    Tcl_Obj	*defaultStateObj;
} ButtonBorderElement;

static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF,
	Tk_Offset(ButtonBorderElement,reliefObj), "flat" },
    { "-highlightcolor",TK_OPTION_COLOR,
	Tk_Offset(ButtonBorderElement,highlightColorObj), "black" },
    { "-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 relief = TK_RELIEF_RAISED;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    short int cx, cy;





    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
    cx = GetSystemMetrics(SM_CXEDGE);
    cy = GetSystemMetrics(SM_CYEDGE);

    /* Space for default indicator:
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    cx += 2;
    cy += 2;

    *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy);
}

static void ButtonBorderElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    TkWinDCState dcState;
    HDC hdc;
    RECT rc;
    (void)dummy;

    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
	XColor *highlightColor =
	    Tk_GetColorFromObj(tkwin, bd->highlightColorObj);







|


|

|



<







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
    cx += 2;
    cy += 2;

    *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy);
}

static void ButtonBorderElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    ButtonBorderElement *bd = elementRecord;
    int relief = TK_RELIEF_FLAT;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    TkWinDCState dcState;
    HDC hdc;
    RECT rc;


    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
	XColor *highlightColor =
	    Tk_GetColorFromObj(tkwin, bd->highlightColorObj);
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
	short int borderWidth = 3;	/* @@@ Use GetSystemMetrics?*/
	rc = BoxToRect(Ttk_PadBox(b, Ttk_UniformPadding(borderWidth)));
    	DrawFocusRect(hdc, &rc);
    }
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ButtonBorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ButtonBorderElement),
    ButtonBorderElementOptions,
    ButtonBorderElementSize,
    ButtonBorderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Focus element.
 * 	Draw dashed focus rectangle.
 */

static void FocusElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    *paddingPtr = Ttk_UniformPadding(1);
}

static void FocusElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    (void)dummy;
    (void)elementRecord;

    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

static const Ttk_ElementSpec FocusElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    FocusElementSize,
    FocusElementDraw
};

/* FillFocusElement --
 * 	Draws a focus ring filled with the selection color
 */

typedef struct {
    Tcl_Obj *fillColorObj;
} FillFocusElement;

static const Ttk_ElementOptionSpec FillFocusElementOptions[] = {
    { "-focusfill", TK_OPTION_COLOR,
	offsetof(FillFocusElement,fillColorObj), "white" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

	/* @@@ FIX THIS */
static void FillFocusElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FillFocusElement *focus = (FillFocusElement *)elementRecord;
    (void)dummy;

    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj);
	GC gc = Tk_GCForColor(fillColor, d);
	HDC hdc;








|













|


<
<
<
<
<
<




|


<
<
<









|















|

|
|




|


|
<
<







363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386






387
388
389
390
391
392
393



394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430


431
432
433
434
435
436
437
	short int borderWidth = 3;	/* @@@ Use GetSystemMetrics?*/
	rc = BoxToRect(Ttk_PadBox(b, Ttk_UniformPadding(borderWidth)));
    	DrawFocusRect(hdc, &rc);
    }
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec ButtonBorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ButtonBorderElement),
    ButtonBorderElementOptions,
    ButtonBorderElementSize,
    ButtonBorderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Focus element.
 * 	Draw dashed focus rectangle.
 */

static void FocusElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{






    *paddingPtr = Ttk_UniformPadding(1);
}

static void FocusElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{



    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

static Ttk_ElementSpec FocusElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    FocusElementSize,
    FocusElementDraw
};

/* FillFocusElement --
 * 	Draws a focus ring filled with the selection color
 */

typedef struct {
    Tcl_Obj *fillColorObj;
} FillFocusElement;

static Ttk_ElementOptionSpec FillFocusElementOptions[] = {
    { "-focusfill", TK_OPTION_COLOR,
	Tk_Offset(FillFocusElement,fillColorObj), "white" },
    {NULL, 0, 0, NULL}
};

	/* @@@ FIX THIS */
static void FillFocusElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FillFocusElement *focus = elementRecord;


    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj);
	GC gc = Tk_GCForColor(fillColor, d);
	HDC hdc;

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (state & TTK_STATE_READONLY) {
    	FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state);
    }
}

static const Ttk_ElementSpec ComboboxFocusElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FillFocusElement),
    FillFocusElementOptions,
    FocusElementSize,
    ComboboxFocusElementDraw
};








|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (state & TTK_STATE_READONLY) {
    	FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state);
    }
}

static Ttk_ElementSpec ComboboxFocusElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FillFocusElement),
    FillFocusElementOptions,
    FocusElementSize,
    ComboboxFocusElementDraw
};

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

static const WORD Pattern[] = {
    0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa
};

static void TroughClientDataDeleteProc(void *clientData)
{
    TroughClientData *cd = (TroughClientData *)clientData;
    DeleteObject(cd->PatternBrush);
    DeleteObject(cd->PatternBitmap);
    ckfree(clientData);
}

static TroughClientData *TroughClientDataInit(Tcl_Interp *interp)
{
    TroughClientData *cd = (TroughClientData *)ckalloc(sizeof(*cd));
    cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern);
    cd->PatternBrush  = CreatePatternBrush(cd->PatternBitmap);
    Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc);
    return cd;
}

static void TroughElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughClientData *cd = (TroughClientData *)clientData;
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    HBRUSH hbr;
    COLORREF bk, oldbk, oldtxt;
    (void)elementRecord;
    (void)state;

    hbr = (HBRUSH)SelectObject(hdc, GetSysColorBrush(COLOR_SCROLLBAR));
    bk = GetSysColor(COLOR_3DHIGHLIGHT);
    oldtxt = SetTextColor(hdc, GetSysColor(COLOR_3DFACE));
    oldbk = SetBkColor(hdc, bk);

    /* WAS: if (bk (COLOR_3DHIGHLIGHT) == GetSysColor(COLOR_WINDOW)) ... */
    if (GetSysColor(COLOR_SCROLLBAR) == GetSysColor(COLOR_BTNFACE)) {
	/* Draw using the pattern brush */
	SelectObject(hdc, cd->PatternBrush);
    }

    PatBlt(hdc, b.x, b.y, b.width, b.height, PATCOPY);
    SetBkColor(hdc, oldbk);
    SetTextColor(hdc, oldtxt);
    SelectObject(hdc, hbr);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

/*------------------------------------------------------------------------
 * +++ Thumb element.
 */

typedef struct {
    Tcl_Obj *orientObj;
} ThumbElement;

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThumbElement *thumbPtr = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, thumbPtr->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = GetSystemMetrics(SM_CXHTHUMB);
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = GetSystemMetrics(SM_CYVTHUMB);
    }
}

static void ThumbElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)elementRecord;

    /* Windows doesn't show a thumb when the scrollbar is disabled */
    if (state & TTK_STATE_DISABLED)
	return;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/* ----------------------------------------------------------------------
 * The slider element is the shaped thumb used in the slider widget.
 * Windows likes to call this a trackbar.
 */

typedef struct {
    Tcl_Obj *orientObj;  /* orientation of the slider widget */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
      "horizontal" },
      { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = (GetSystemMetrics(SM_CXHTHUMB) / 2) | 1;
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = (GetSystemMetrics(SM_CYVTHUMB) / 2) | 1;
    }
}

static void SliderElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)elementRecord;
    (void)state;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 */

static void ClientElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void ClientElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    (void)dummy;
    (void)elementRecord;
    (void)state;

    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_SOFT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ClientElementSize,
    ClientElementDraw
};








|







|










|




<
<

|

















|















|
|
|



|


|
|
<
<
<

|










|





<
<










|
















|
|

|



|


|
|
<
<
<

|










|





<
<
<






|












|


<
<
<
<
<
<





|





<
<
<
<




|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508


509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554



555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611



612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629



630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651






652
653
654
655
656
657
658
659
660
661
662




663
664
665
666
667
668
669
670
671
672
673
674

static const WORD Pattern[] = {
    0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa
};

static void TroughClientDataDeleteProc(void *clientData)
{
    TroughClientData *cd = clientData;
    DeleteObject(cd->PatternBrush);
    DeleteObject(cd->PatternBitmap);
    ckfree(clientData);
}

static TroughClientData *TroughClientDataInit(Tcl_Interp *interp)
{
    TroughClientData *cd = (TroughClientData*)ckalloc(sizeof(*cd));
    cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern);
    cd->PatternBrush  = CreatePatternBrush(cd->PatternBitmap);
    Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc);
    return cd;
}

static void TroughElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughClientData *cd = clientData;
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    HBRUSH hbr;
    COLORREF bk, oldbk, oldtxt;



    hbr = SelectObject(hdc, GetSysColorBrush(COLOR_SCROLLBAR));
    bk = GetSysColor(COLOR_3DHIGHLIGHT);
    oldtxt = SetTextColor(hdc, GetSysColor(COLOR_3DFACE));
    oldbk = SetBkColor(hdc, bk);

    /* WAS: if (bk (COLOR_3DHIGHLIGHT) == GetSysColor(COLOR_WINDOW)) ... */
    if (GetSysColor(COLOR_SCROLLBAR) == GetSysColor(COLOR_BTNFACE)) {
	/* Draw using the pattern brush */
	SelectObject(hdc, cd->PatternBrush);
    }

    PatBlt(hdc, b.x, b.y, b.width, b.height, PATCOPY);
    SetBkColor(hdc, oldbk);
    SetTextColor(hdc, oldtxt);
    SelectObject(hdc, hbr);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

/*------------------------------------------------------------------------
 * +++ Thumb element.
 */

typedef struct {
    Tcl_Obj *orientObj;
} ThumbElement;

static Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-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 *thumbPtr = elementRecord;
    int orient;




    Ttk_GetOrientFromObj(NULL, thumbPtr->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = GetSystemMetrics(SM_CXHTHUMB);
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = GetSystemMetrics(SM_CYVTHUMB);
    }
}

static void ThumbElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;



    /* Windows doesn't show a thumb when the scrollbar is disabled */
    if (state & TTK_STATE_DISABLED)
	return;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/* ----------------------------------------------------------------------
 * The slider element is the shaped thumb used in the slider widget.
 * Windows likes to call this a trackbar.
 */

typedef struct {
    Tcl_Obj *orientObj;  /* orientation of the slider widget */
} SliderElement;

static Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-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;




    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = (GetSystemMetrics(SM_CXHTHUMB) / 2) | 1;
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = (GetSystemMetrics(SM_CYVTHUMB) / 2) | 1;
    }
}

static void SliderElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;




    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 */

static void ClientElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{






    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void ClientElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);




    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_SOFT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ClientElementSize,
    ClientElementDraw
};

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
    TTK_GROUP("Button.border", TTK_FILL_BOTH,
	TTK_GROUP("Button.padding", TTK_FILL_BOTH,
	    TTK_NODE("Button.label", TTK_FILL_BOTH))))

TTK_LAYOUT("TCombobox",
    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_GROUP("Combobox.focus", TTK_FILL_BOTH,
		TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* ---------------------------------------------------------------------- */

MODULE_SCOPE
int TtkWinTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    Ttk_Theme themePtr, parentPtr;
    const FrameControlElementData *fce = FrameControlElements;
    (void)hwnd;

    parentPtr = Ttk_GetTheme(interp, "alt");
    themePtr = Ttk_CreateTheme(interp, "winnative", parentPtr);
    if (!themePtr) {
        return TCL_ERROR;
    }








|
|










|
<







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
    TTK_GROUP("Button.border", TTK_FILL_BOTH,
	TTK_GROUP("Button.padding", TTK_FILL_BOTH,
	    TTK_NODE("Button.label", TTK_FILL_BOTH))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
	TTK_GROUP("Combobox.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_GROUP("Combobox.focus", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH,
		TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* ---------------------------------------------------------------------- */

MODULE_SCOPE
int TtkWinTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    Ttk_Theme themePtr, parentPtr;
    FrameControlElementData *fce = FrameControlElements;


    parentPtr = Ttk_GetTheme(interp, "alt");
    themePtr = Ttk_CreateTheme(interp, "winnative", parentPtr);
    if (!themePtr) {
        return TCL_ERROR;
    }

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
    Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec,
    	TroughClientDataInit(interp));

    Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL);

    for (fce = FrameControlElements; fce->name != 0; ++fce) {
	Ttk_RegisterElementSpec(themePtr, fce->name,
		&FrameControlElementSpec, (void *)fce);
    }

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::winnative", TTK_VERSION);
    return TCL_OK;
}








|








718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
    Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec,
    	TroughClientDataInit(interp));

    Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL);

    for (fce = FrameControlElements; fce->name != 0; ++fce) {
	Ttk_RegisterElementSpec(themePtr, fce->name,
		&FrameControlElementSpec, fce);
    }

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::winnative", TTK_VERSION);
    return TCL_OK;
}

Changes to win/ttkWinXPTheme.c.

11
12
13
14
15
16
17
18
19
20

21
22


23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
 *
 * See also:
 *
 * <URL: http://msdn.microsoft.com/library/en-us/
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#include <tkWinInt.h>
#ifndef HAVE_UXTHEME_H
/* Stub for platforms that lack the XP theme API headers: */

int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; }
#else



#include <windows.h>
#include <uxtheme.h>
#if defined(HAVE_VSSYM32_H) || _MSC_VER > 1500
#   include <vssym32.h>
#else
#   include <tmschema.h>
#endif



#include "ttk/ttkTheme.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,







<


>


>
>








>
>







11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 *
 * See also:
 *
 * <URL: http://msdn.microsoft.com/library/en-us/
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */


#ifndef HAVE_UXTHEME_H
/* Stub for platforms that lack the XP theme API headers: */
#include <tkWinInt.h>
int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; }
#else

#define WINVER 0x0501	/* Requires Windows XP APIs */

#include <windows.h>
#include <uxtheme.h>
#if defined(HAVE_VSSYM32_H) || _MSC_VER > 1500
#   include <vssym32.h>
#else
#   include <tmschema.h>
#endif

#include <tkWinInt.h>

#include "ttk/ttkTheme.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{
    /*
     * Load the library "uxtheme.dll", where the native widget
     * drawing routines are implemented.  This will only succeed
     * if we are running at least on Windows XP.
     */
    HINSTANCE handle;
    *phlib = handle = LoadLibraryW(L"uxtheme.dll");
    if (handle != 0)
    {
	/*
	 * We have successfully loaded the library. Proceed in storing the
	 * addresses of the functions we want to use.
	 */
	XPThemeProcs *procs = (XPThemeProcs *)ckalloc(sizeof(XPThemeProcs));







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
{
    /*
     * Load the library "uxtheme.dll", where the native widget
     * drawing routines are implemented.  This will only succeed
     * if we are running at least on Windows XP.
     */
    HINSTANCE handle;
    *phlib = handle = LoadLibrary(TEXT("uxtheme.dll"));
    if (handle != 0)
    {
	/*
	 * We have successfully loaded the library. Proceed in storing the
	 * addresses of the functions we want to use.
	 */
	XPThemeProcs *procs = (XPThemeProcs *)ckalloc(sizeof(XPThemeProcs));
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	    && LOADPROC(IsThemeActive)
	    && LOADPROC(IsAppThemed)
	)
	{
	    return procs;
	}
#undef LOADPROC
	ckfree(procs);
    }
    return 0;
}

/*
 * XPThemeDeleteProc --
 *







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
	    && LOADPROC(IsThemeActive)
	    && LOADPROC(IsAppThemed)
	)
	{
	    return procs;
	}
#undef LOADPROC
	ckfree((char*)procs);
    }
    return 0;
}

/*
 * XPThemeDeleteProc --
 *
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
    rc.right = b.x + b.width;
    return rc;
}

/*
 * Map Tk state bitmaps to XP style enumerated values.
 */
static const Ttk_StateTable null_statemap[] = { {0,0,0} };

/*
 * Pushbuttons (Tk: "Button")
 */
static const Ttk_StateTable pushbutton_statemap[] =
{
    { PBS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { PBS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { PBS_HOT,		TTK_STATE_ACTIVE, 0 },
    { PBS_DEFAULTED,	TTK_STATE_ALTERNATE, 0 },
    { PBS_NORMAL, 	0, 0 }
};

/*
 * Checkboxes (Tk: "Checkbutton")
 */
static const Ttk_StateTable checkbox_statemap[] =
{
{CBS_MIXEDDISABLED, 	TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0},
{CBS_MIXEDPRESSED, 	TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0},
{CBS_MIXEDHOT,  	TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0},
{CBS_MIXEDNORMAL, 	TTK_STATE_ALTERNATE, 0},
{CBS_CHECKEDDISABLED,	TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0},
{CBS_CHECKEDPRESSED,	TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0},
{CBS_CHECKEDHOT,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0},
{CBS_CHECKEDNORMAL,	TTK_STATE_SELECTED, 0},
{CBS_UNCHECKEDDISABLED,	TTK_STATE_DISABLED, 0},
{CBS_UNCHECKEDPRESSED,	TTK_STATE_PRESSED, 0},
{CBS_UNCHECKEDHOT,	TTK_STATE_ACTIVE, 0},
{CBS_UNCHECKEDNORMAL,	0,0 }
};

/*
 * Radiobuttons:
 */
static const Ttk_StateTable radiobutton_statemap[] =
{
{RBS_UNCHECKEDDISABLED,	TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0},
{RBS_UNCHECKEDNORMAL,	TTK_STATE_ALTERNATE, 0},
{RBS_CHECKEDDISABLED,	TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0},
{RBS_CHECKEDPRESSED,	TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0},
{RBS_CHECKEDHOT,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0},
{RBS_CHECKEDNORMAL,	TTK_STATE_SELECTED, 0},
{RBS_UNCHECKEDDISABLED,	TTK_STATE_DISABLED, 0},
{RBS_UNCHECKEDPRESSED,	TTK_STATE_PRESSED, 0},
{RBS_UNCHECKEDHOT,	TTK_STATE_ACTIVE, 0},
{RBS_UNCHECKEDNORMAL,	0,0 }
};

/*
 * Groupboxes (tk: "frame")
 */
static const Ttk_StateTable groupbox_statemap[] =
{
{GBS_DISABLED,	TTK_STATE_DISABLED, 0},
{GBS_NORMAL,	0,0 }
};

/*
 * Edit fields (tk: "entry")
 */
static const Ttk_StateTable edittext_statemap[] =
{
    { ETS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { ETS_READONLY,	TTK_STATE_READONLY, 0 },
    { ETS_FOCUSED,	TTK_STATE_FOCUS, 0 },
    { ETS_HOT,		TTK_STATE_ACTIVE, 0 },
    { ETS_NORMAL,	0, 0 }
/* NOT USED: ETS_ASSIST, ETS_SELECTED */
};

/*
 * Combobox text field statemap:
 * Same as edittext_statemap, but doesn't use ETS_READONLY
 * (fixes: #1032409)
 */
static const Ttk_StateTable combotext_statemap[] =
{
    { ETS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { ETS_FOCUSED,	TTK_STATE_FOCUS, 0 },
    { ETS_HOT,		TTK_STATE_ACTIVE, 0 },
    { ETS_NORMAL,	0, 0 }
};

/*
 * Combobox button: (CBP_DROPDOWNBUTTON)
 */
static const Ttk_StateTable combobox_statemap[] = {
    { CBXS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { CBXS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { CBXS_HOT, 	TTK_STATE_ACTIVE, 0 },
    { CBXS_HOT, 	TTK_STATE_HOVER, 0 },
    { CBXS_NORMAL, 	0, 0 }
};

/*
 * Toolbar buttons (TP_BUTTON):
 */
static const Ttk_StateTable toolbutton_statemap[] =  {
    { TS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TS_PRESSED,	TTK_STATE_PRESSED, 0 },
    { TS_HOTCHECKED,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 },
    { TS_CHECKED, 	TTK_STATE_SELECTED, 0 },
    { TS_HOT,  		TTK_STATE_ACTIVE, 0 },
    { TS_NORMAL, 	0,0 }
};

/*
 * Scrollbars (Tk: "Scrollbar.thumb")
 */
static const Ttk_StateTable scrollbar_statemap[] =
{
    { SCRBS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { SCRBS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { SCRBS_HOT,	TTK_STATE_ACTIVE, 0 },
    { SCRBS_NORMAL, 	0, 0 }
};

static const Ttk_StateTable uparrow_statemap[] =
{
    { ABS_UPDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_UPPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_UPHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_UPNORMAL, 	0, 0 }
};

static const Ttk_StateTable downarrow_statemap[] =
{
    { ABS_DOWNDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_DOWNPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_DOWNHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_DOWNNORMAL, 	0, 0 }
};

static const Ttk_StateTable leftarrow_statemap[] =
{
    { ABS_LEFTDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_LEFTPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_LEFTHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_LEFTNORMAL, 	0, 0 }
};

static const Ttk_StateTable rightarrow_statemap[] =
{
    { ABS_RIGHTDISABLED,TTK_STATE_DISABLED, 0 },
    { ABS_RIGHTPRESSED, TTK_STATE_PRESSED, 0 },
    { ABS_RIGHTHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_RIGHTNORMAL, 	0, 0 }
};

static const Ttk_StateTable spinbutton_statemap[] =
{
    { DNS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { DNS_PRESSED,	TTK_STATE_PRESSED,  0 },
    { DNS_HOT,		TTK_STATE_ACTIVE,   0 },
    { DNS_NORMAL,	0,		    0 },
};

/*
 * Trackbar thumb: (Tk: "scale slider")
 */
static const Ttk_StateTable scale_statemap[] =
{
    { TUS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TUS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { TUS_FOCUSED, 	TTK_STATE_FOCUS, 0 },
    { TUS_HOT,		TTK_STATE_ACTIVE, 0 },
    { TUS_NORMAL, 	0, 0 }
};

static const Ttk_StateTable tabitem_statemap[] =
{
    { TIS_DISABLED,     TTK_STATE_DISABLED, 0 },
    { TIS_SELECTED,     TTK_STATE_SELECTED, 0 },
    { TIS_HOT,          TTK_STATE_ACTIVE,   0 },
    { TIS_FOCUSED,      TTK_STATE_FOCUS,    0 },
    { TIS_NORMAL,       0,                  0 },
};







|




|











|


















|

<
<













|








|














|










|










|











|







|







|







|







|







|










|








|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
    rc.right = b.x + b.width;
    return rc;
}

/*
 * Map Tk state bitmaps to XP style enumerated values.
 */
static Ttk_StateTable null_statemap[] = { {0,0,0} };

/*
 * Pushbuttons (Tk: "Button")
 */
static Ttk_StateTable pushbutton_statemap[] =
{
    { PBS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { PBS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { PBS_HOT,		TTK_STATE_ACTIVE, 0 },
    { PBS_DEFAULTED,	TTK_STATE_ALTERNATE, 0 },
    { PBS_NORMAL, 	0, 0 }
};

/*
 * Checkboxes (Tk: "Checkbutton")
 */
static Ttk_StateTable checkbox_statemap[] =
{
{CBS_MIXEDDISABLED, 	TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0},
{CBS_MIXEDPRESSED, 	TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0},
{CBS_MIXEDHOT,  	TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0},
{CBS_MIXEDNORMAL, 	TTK_STATE_ALTERNATE, 0},
{CBS_CHECKEDDISABLED,	TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0},
{CBS_CHECKEDPRESSED,	TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0},
{CBS_CHECKEDHOT,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0},
{CBS_CHECKEDNORMAL,	TTK_STATE_SELECTED, 0},
{CBS_UNCHECKEDDISABLED,	TTK_STATE_DISABLED, 0},
{CBS_UNCHECKEDPRESSED,	TTK_STATE_PRESSED, 0},
{CBS_UNCHECKEDHOT,	TTK_STATE_ACTIVE, 0},
{CBS_UNCHECKEDNORMAL,	0,0 }
};

/*
 * Radiobuttons:
 */
static Ttk_StateTable radiobutton_statemap[] =
{


{RBS_CHECKEDDISABLED,	TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0},
{RBS_CHECKEDPRESSED,	TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0},
{RBS_CHECKEDHOT,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0},
{RBS_CHECKEDNORMAL,	TTK_STATE_SELECTED, 0},
{RBS_UNCHECKEDDISABLED,	TTK_STATE_DISABLED, 0},
{RBS_UNCHECKEDPRESSED,	TTK_STATE_PRESSED, 0},
{RBS_UNCHECKEDHOT,	TTK_STATE_ACTIVE, 0},
{RBS_UNCHECKEDNORMAL,	0,0 }
};

/*
 * Groupboxes (tk: "frame")
 */
static Ttk_StateTable groupbox_statemap[] =
{
{GBS_DISABLED,	TTK_STATE_DISABLED, 0},
{GBS_NORMAL,	0,0 }
};

/*
 * Edit fields (tk: "entry")
 */
static Ttk_StateTable edittext_statemap[] =
{
    { ETS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { ETS_READONLY,	TTK_STATE_READONLY, 0 },
    { ETS_FOCUSED,	TTK_STATE_FOCUS, 0 },
    { ETS_HOT,		TTK_STATE_ACTIVE, 0 },
    { ETS_NORMAL,	0, 0 }
/* NOT USED: ETS_ASSIST, ETS_SELECTED */
};

/*
 * Combobox text field statemap:
 * Same as edittext_statemap, but doesn't use ETS_READONLY
 * (fixes: #1032409)
 */
static Ttk_StateTable combotext_statemap[] =
{
    { ETS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { ETS_FOCUSED,	TTK_STATE_FOCUS, 0 },
    { ETS_HOT,		TTK_STATE_ACTIVE, 0 },
    { ETS_NORMAL,	0, 0 }
};

/*
 * Combobox button: (CBP_DROPDOWNBUTTON)
 */
static Ttk_StateTable combobox_statemap[] = {
    { CBXS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { CBXS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { CBXS_HOT, 	TTK_STATE_ACTIVE, 0 },
    { CBXS_HOT, 	TTK_STATE_HOVER, 0 },
    { CBXS_NORMAL, 	0, 0 }
};

/*
 * Toolbar buttons (TP_BUTTON):
 */
static Ttk_StateTable toolbutton_statemap[] =  {
    { TS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TS_PRESSED,	TTK_STATE_PRESSED, 0 },
    { TS_HOTCHECKED,	TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 },
    { TS_CHECKED, 	TTK_STATE_SELECTED, 0 },
    { TS_HOT,  		TTK_STATE_ACTIVE, 0 },
    { TS_NORMAL, 	0,0 }
};

/*
 * Scrollbars (Tk: "Scrollbar.thumb")
 */
static Ttk_StateTable scrollbar_statemap[] =
{
    { SCRBS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { SCRBS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { SCRBS_HOT,	TTK_STATE_ACTIVE, 0 },
    { SCRBS_NORMAL, 	0, 0 }
};

static Ttk_StateTable uparrow_statemap[] =
{
    { ABS_UPDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_UPPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_UPHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_UPNORMAL, 	0, 0 }
};

static Ttk_StateTable downarrow_statemap[] =
{
    { ABS_DOWNDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_DOWNPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_DOWNHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_DOWNNORMAL, 	0, 0 }
};

static Ttk_StateTable leftarrow_statemap[] =
{
    { ABS_LEFTDISABLED,	TTK_STATE_DISABLED, 0 },
    { ABS_LEFTPRESSED, 	TTK_STATE_PRESSED, 0 },
    { ABS_LEFTHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_LEFTNORMAL, 	0, 0 }
};

static Ttk_StateTable rightarrow_statemap[] =
{
    { ABS_RIGHTDISABLED,TTK_STATE_DISABLED, 0 },
    { ABS_RIGHTPRESSED, TTK_STATE_PRESSED, 0 },
    { ABS_RIGHTHOT,	TTK_STATE_ACTIVE, 0 },
    { ABS_RIGHTNORMAL, 	0, 0 }
};

static Ttk_StateTable spinbutton_statemap[] =
{
    { DNS_DISABLED,	TTK_STATE_DISABLED, 0 },
    { DNS_PRESSED,	TTK_STATE_PRESSED,  0 },
    { DNS_HOT,		TTK_STATE_ACTIVE,   0 },
    { DNS_NORMAL,	0,		    0 },
};

/*
 * Trackbar thumb: (Tk: "scale slider")
 */
static Ttk_StateTable scale_statemap[] =
{
    { TUS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TUS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { TUS_FOCUSED, 	TTK_STATE_FOCUS, 0 },
    { TUS_HOT,		TTK_STATE_ACTIVE, 0 },
    { TUS_NORMAL, 	0, 0 }
};

static Ttk_StateTable tabitem_statemap[] =
{
    { TIS_DISABLED,     TTK_STATE_DISABLED, 0 },
    { TIS_SELECTED,     TTK_STATE_SELECTED, 0 },
    { TIS_HOT,          TTK_STATE_ACTIVE,   0 },
    { TIS_FOCUSED,      TTK_STATE_FOCUS,    0 },
    { TIS_NORMAL,       0,                  0 },
};
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
 *	This gives bogus metrics for some parts (in particular,
 *	BP_PUSHBUTTONS).  Set the IGNORE_THEMESIZE flag to skip this call.
 */

typedef struct 	/* XP element specifications */
{
    const char	*elementName;	/* Tk theme engine element name */
    const Ttk_ElementSpec *elementSpec;
    				/* Element spec (usually GenericElementSpec) */
    LPCWSTR	className;	/* Windows window class name */
    int 	partId;		/* BP_PUSHBUTTON, BP_CHECKBUTTON, etc. */
    const Ttk_StateTable *statemap;	/* Map Tk states to XP states */
    Ttk_Padding	padding;	/* See NOTE-GetThemeMargins */
    unsigned  	flags;
#   define 	IGNORE_THEMESIZE 0x80000000U /* See NOTE-GetThemePartSize */
#   define 	PAD_MARGINS	 0x40000000U /* See NOTE-GetThemeMargins */
#   define 	HEAP_ELEMENT	 0x20000000U /* ElementInfo is on heap */
#   define 	HALF_HEIGHT	 0x10000000U /* Used by GenericSizedElements */
#   define 	HALF_WIDTH	 0x08000000U /* Used by GenericSizedElements */
} ElementInfo;

typedef struct
{
    /*
     * Static data, initialized when element is registered:
     */
    const ElementInfo	*info;
    XPThemeProcs *procs;	/* Pointer to theme procedure table */

    /*
     * Dynamic data, allocated by InitElementData:
     */
    HTHEME	hTheme;
    HDC		hDC;
    HWND	hwnd;

    /* For TkWinDrawableReleaseDC: */
    Drawable	drawable;
    TkWinDCState dcState;
} ElementData;

static ElementData *
NewElementData(XPThemeProcs *procs, const ElementInfo *info)
{
    ElementData *elementData = (ElementData *)ckalloc(sizeof(ElementData));

    elementData->procs = procs;
    elementData->info = info;
    elementData->hTheme = elementData->hDC = 0;








|



|

|
|
|
|
|
|







|















|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
 *	This gives bogus metrics for some parts (in particular,
 *	BP_PUSHBUTTONS).  Set the IGNORE_THEMESIZE flag to skip this call.
 */

typedef struct 	/* XP element specifications */
{
    const char	*elementName;	/* Tk theme engine element name */
    Ttk_ElementSpec *elementSpec;
    				/* Element spec (usually GenericElementSpec) */
    LPCWSTR	className;	/* Windows window class name */
    int 	partId;		/* BP_PUSHBUTTON, BP_CHECKBUTTON, etc. */
    Ttk_StateTable *statemap;	/* Map Tk states to XP states */
    Ttk_Padding	padding;	/* See NOTE-GetThemeMargins */
    int  	flags;
#   define 	IGNORE_THEMESIZE 0x80000000 /* See NOTE-GetThemePartSize */
#   define 	PAD_MARGINS	 0x40000000 /* See NOTE-GetThemeMargins */
#   define 	HEAP_ELEMENT	 0x20000000 /* ElementInfo is on heap */
#   define 	HALF_HEIGHT	 0x10000000 /* Used by GenericSizedElements */
#   define 	HALF_WIDTH	 0x08000000 /* Used by GenericSizedElements */
} ElementInfo;

typedef struct
{
    /*
     * Static data, initialized when element is registered:
     */
    ElementInfo	*info;
    XPThemeProcs *procs;	/* Pointer to theme procedure table */

    /*
     * Dynamic data, allocated by InitElementData:
     */
    HTHEME	hTheme;
    HDC		hDC;
    HWND	hwnd;

    /* For TkWinDrawableReleaseDC: */
    Drawable	drawable;
    TkWinDCState dcState;
} ElementData;

static ElementData *
NewElementData(XPThemeProcs *procs, ElementInfo *info)
{
    ElementData *elementData = (ElementData *)ckalloc(sizeof(ElementData));

    elementData->procs = procs;
    elementData->info = info;
    elementData->hTheme = elementData->hDC = 0;

502
503
504
505
506
507
508
509

510
511
512
513
514
515
516

    if (!InitElementData(elementData, tkwin, 0))
	return;

    if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
	result = elementData->procs->GetThemePartSize(
	    elementData->hTheme,
	    NULL,

	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, 0),
	    NULL /*RECT *prc*/,
	    TS_TRUE,
	    &size);

	if (SUCCEEDED(result)) {







<
>







504
505
506
507
508
509
510

511
512
513
514
515
516
517
518

    if (!InitElementData(elementData, tkwin, 0))
	return;

    if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
	result = elementData->procs->GetThemePartSize(
	    elementData->hTheme,

	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, 0),
	    NULL /*RECT *prc*/,
	    TS_TRUE,
	    &size);

	if (SUCCEEDED(result)) {
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
	Ttk_StateTableLookup(elementData->info->statemap, state),
	&rc,
	NULL/*pContentRect*/);

    FreeElementData(elementData);
}

static const Ttk_ElementSpec GenericElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    GenericElementDraw
};







|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
	Ttk_StateTableLookup(elementData->info->statemap, state),
	&rc,
	NULL/*pContentRect*/);

    FreeElementData(elementData);
}

static Ttk_ElementSpec GenericElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    GenericElementDraw
};
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
	elementData->info->flags & 0xff);
    if (elementData->info->flags & HALF_HEIGHT)
	*heightPtr /= 2;
    if (elementData->info->flags & HALF_WIDTH)
	*widthPtr /= 2;
}

static const Ttk_ElementSpec GenericSizedElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericSizedElementSize,
    GenericElementDraw
};








|







594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
	elementData->info->flags & 0xff);
    if (elementData->info->flags & HALF_HEIGHT)
	*heightPtr /= 2;
    if (elementData->info->flags & HALF_WIDTH)
	*widthPtr /= 2;
}

static Ttk_ElementSpec GenericSizedElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericSizedElementSize,
    GenericElementDraw
};

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    GenericSizedElementSize(clientData, elementRecord, tkwin,
	widthPtr, heightPtr, paddingPtr);

    /* force the arrow button height to half size */
    *heightPtr /= 2;
}

static const Ttk_ElementSpec SpinboxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinboxArrowElementSize,
    GenericElementDraw
};








|







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
    GenericSizedElementSize(clientData, elementRecord, tkwin,
	widthPtr, heightPtr, paddingPtr);

    /* force the arrow button height to half size */
    *heightPtr /= 2;
}

static Ttk_ElementSpec SpinboxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinboxArrowElementSize,
    GenericElementDraw
};

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
    elementData->procs->DrawThemeBackground(elementData->hTheme,
	elementData->hDC, elementData->info->partId, stateId,
	&rc, NULL);

    FreeElementData(elementData);
}

static const Ttk_ElementSpec ThumbElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    ThumbElementDraw
};







|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
    elementData->procs->DrawThemeBackground(elementData->hTheme,
	elementData->hDC, elementData->info->partId, stateId,
	&rc, NULL);

    FreeElementData(elementData);
}

static Ttk_ElementSpec ThumbElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    ThumbElementDraw
};
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
    if (elementData->info->partId == PP_CHUNK) {
    	*widthPtr *= nBars;
    } else if (elementData->info->partId == PP_CHUNKVERT) {
    	*heightPtr *= nBars;
    }
}

static const Ttk_ElementSpec PbarElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    PbarElementSize,
    GenericElementDraw
};







|







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
    if (elementData->info->partId == PP_CHUNK) {
    	*widthPtr *= nBars;
    } else if (elementData->info->partId == PP_CHUNKVERT) {
    	*heightPtr *= nBars;
    }
}

static Ttk_ElementSpec PbarElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    PbarElementSize,
    GenericElementDraw
};
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
	partId = TABP_TABITEMLEFTEDGE;
    elementData->procs->DrawThemeBackground(
	elementData->hTheme, elementData->hDC, partId,
	Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL);
    FreeElementData(elementData);
}

static const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TabElementDraw
};

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set
 */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

static const Ttk_StateTable header_statemap[] =
{
    { HIS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { HIS_HOT,  	TTK_STATE_ACTIVE, 0 },
    { HIS_NORMAL, 	0,0 },
};

static const Ttk_StateTable treeview_statemap[] =
{
    { TREIS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TREIS_SELECTED,	TTK_STATE_SELECTED, 0},
    { TREIS_HOT, 	TTK_STATE_ACTIVE, 0 },
    { TREIS_NORMAL, 	0,0 },
};

static const Ttk_StateTable tvpglyph_statemap[] =
{
    { GLPS_OPENED, 	TTK_STATE_OPEN, 0 },
    { GLPS_CLOSED, 	0,0 },
};

static void TreeIndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (!(state & TTK_STATE_LEAF)) {
        GenericElementDraw(clientData,elementRecord,tkwin,d,b,state);
    }
}

static const Ttk_ElementSpec TreeIndicatorElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TreeIndicatorElementDraw
};







|

















|






|







|














|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
	partId = TABP_TABITEMLEFTEDGE;
    elementData->procs->DrawThemeBackground(
	elementData->hTheme, elementData->hDC, partId,
	Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL);
    FreeElementData(elementData);
}

static Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TabElementDraw
};

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set
 */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

static Ttk_StateTable header_statemap[] =
{
    { HIS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { HIS_HOT,  	TTK_STATE_ACTIVE, 0 },
    { HIS_NORMAL, 	0,0 },
};

static Ttk_StateTable treeview_statemap[] =
{
    { TREIS_DISABLED, 	TTK_STATE_DISABLED, 0 },
    { TREIS_SELECTED,	TTK_STATE_SELECTED, 0},
    { TREIS_HOT, 	TTK_STATE_ACTIVE, 0 },
    { TREIS_NORMAL, 	0,0 },
};

static Ttk_StateTable tvpglyph_statemap[] =
{
    { GLPS_OPENED, 	TTK_STATE_OPEN, 0 },
    { GLPS_CLOSED, 	0,0 },
};

static void TreeIndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (!(state & TTK_STATE_LEAF)) {
        GenericElementDraw(clientData,elementRecord,tkwin,d,b,state);
    }
}

static Ttk_ElementSpec TreeIndicatorElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TreeIndicatorElementDraw
};
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904

typedef struct
{
    Tcl_Obj *textObj;
    Tcl_Obj *fontObj;
} TextElement;

static const Ttk_ElementOptionSpec TextElementOptions[] =
{
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_FONT },
    { NULL }
};

static void TextElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = {0, 0};
    HRESULT hr = S_OK;
    const char *src;
    TkSizeT len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    Tcl_DStringInit(&ds);
    hr = elementData->procs->GetThemeTextExtent(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, 0),
	    Tcl_UtfToWCharDString(src, len, &ds),
	    -1,
	    DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX,
	    NULL,
	    &rc);

    if (SUCCEEDED(hr)) {
	*widthPtr = rc.right - rc.left;
	*heightPtr = rc.bottom - rc.top;
    }
    if (*widthPtr < 80) *widthPtr = 80;
    if (*heightPtr < 20) *heightPtr = 20;

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

static void TextElementDraw(
    ClientData clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = BoxToRect(b);
    HRESULT hr = S_OK;
    const char *src;
    TkSizeT len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, d))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    Tcl_DStringInit(&ds);
    hr = elementData->procs->DrawThemeText(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, state),
	    Tcl_UtfToWCharDString(src, len, &ds),
	    -1,
	    DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX,
	    (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0,
	    &rc);

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

static const Ttk_ElementSpec TextElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};







|


|

|











<
<
<




<
<





|

|










<











<
<
<




<
<





|

|


<
<



|







812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835



836
837
838
839


840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857

858
859
860
861
862
863
864
865
866
867
868



869
870
871
872


873
874
875
876
877
878
879
880
881
882


883
884
885
886
887
888
889
890
891
892
893

typedef struct
{
    Tcl_Obj *textObj;
    Tcl_Obj *fontObj;
} TextElement;

static Ttk_ElementOptionSpec TextElementOptions[] =
{
    { "-text", TK_OPTION_STRING,
	Tk_Offset(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	Tk_Offset(TextElement,fontObj), DEFAULT_FONT },
    { NULL }
};

static void TextElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = {0, 0};
    HRESULT hr = S_OK;




    if (!InitElementData(elementData, tkwin, 0))
	return;



    hr = elementData->procs->GetThemeTextExtent(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, 0),
	    Tcl_GetUnicode(element->textObj),
	    -1,
	    DT_LEFT /* | DT_BOTTOM | DT_NOPREFIX */,
	    NULL,
	    &rc);

    if (SUCCEEDED(hr)) {
	*widthPtr = rc.right - rc.left;
	*heightPtr = rc.bottom - rc.top;
    }
    if (*widthPtr < 80) *widthPtr = 80;
    if (*heightPtr < 20) *heightPtr = 20;


    FreeElementData(elementData);
}

static void TextElementDraw(
    ClientData clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = BoxToRect(b);
    HRESULT hr = S_OK;




    if (!InitElementData(elementData, tkwin, d))
	return;



    hr = elementData->procs->DrawThemeText(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, state),
	    Tcl_GetUnicode(element->textObj),
	    -1,
	    DT_LEFT /* | DT_BOTTOM | DT_NOPREFIX */,
	    (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0,
	    &rc);


    FreeElementData(elementData);
}

static Ttk_ElementSpec TextElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
    TTK_GROUP("Button.button", TTK_FILL_BOTH,
	TTK_GROUP("Button.focus", TTK_FILL_BOTH,
	    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
		TTK_NODE("Button.label", TTK_FILL_BOTH)))))

TTK_LAYOUT("TMenubutton",
    TTK_NODE("Menubutton.dropdown", TTK_PACK_RIGHT|TTK_FILL_Y)
    TTK_GROUP("Menubutton.button", TTK_FILL_BOTH,
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", 0))))

TTK_LAYOUT("Horizontal.TScrollbar",
    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_GROUP("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Horizontal.Scrollbar.grip", 0))))

TTK_LAYOUT("Vertical.TScrollbar",
    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_GROUP("Vertical.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Vertical.Scrollbar.grip", 0))))

TTK_LAYOUT("Horizontal.TScale",
    TTK_GROUP("Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Horizontal.Scale.track", TTK_FILL_X)
	    TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )))

TTK_LAYOUT("Vertical.TScale",
    TTK_GROUP("Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Vertical.Scale.track", TTK_FILL_Y)
	    TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ XP element info table:
 */

#define PAD(l,t,r,b) {l,t,r,b}
#define NOPAD {0,0,0,0}

/* name spec className partId statemap padding flags */

static const ElementInfo ElementInfoTable[] = {
    { "Checkbutton.indicator", &GenericElementSpec, L"BUTTON",
    	BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
    { "Radiobutton.indicator", &GenericElementSpec, L"BUTTON",
    	BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
    { "Button.button", &GenericElementSpec, L"BUTTON",
    	BP_PUSHBUTTON, pushbutton_statemap, PAD(3, 3, 3, 3), IGNORE_THEMESIZE },
    { "Labelframe.border", &GenericElementSpec, L"BUTTON",







|
|

















|
|




|
|














|







904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
    TTK_GROUP("Button.button", TTK_FILL_BOTH,
	TTK_GROUP("Button.focus", TTK_FILL_BOTH,
	    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
		TTK_NODE("Button.label", TTK_FILL_BOTH)))))

TTK_LAYOUT("TMenubutton",
    TTK_NODE("Menubutton.dropdown", TTK_PACK_RIGHT|TTK_FILL_Y)
    TTK_GROUP("Menubutton.button", TTK_PACK_RIGHT|TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
	        TTK_NODE("Menubutton.label", 0))))

TTK_LAYOUT("Horizontal.TScrollbar",
    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_GROUP("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Horizontal.Scrollbar.grip", 0))))

TTK_LAYOUT("Vertical.TScrollbar",
    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_GROUP("Vertical.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Vertical.Scrollbar.grip", 0))))

TTK_LAYOUT("Horizontal.TScale",
    TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_NODE("Horizontal.Scale.track", TTK_FILL_X)
	    TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )))

TTK_LAYOUT("Vertical.TScale",
    TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_NODE("Vertical.Scale.track", TTK_FILL_Y)
	    TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ XP element info table:
 */

#define PAD(l,t,r,b) {l,t,r,b}
#define NOPAD {0,0,0,0}

/* name spec className partId statemap padding flags */

static ElementInfo ElementInfoTable[] = {
    { "Checkbutton.indicator", &GenericElementSpec, L"BUTTON",
    	BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
    { "Radiobutton.indicator", &GenericElementSpec, L"BUTTON",
    	BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
    { "Button.button", &GenericElementSpec, L"BUTTON",
    	BP_PUSHBUTTON, pushbutton_statemap, PAD(3, 3, 3, 3), IGNORE_THEMESIZE },
    { "Labelframe.border", &GenericElementSpec, L"BUTTON",
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
    { "Toolbutton.border", &GenericElementSpec, L"TOOLBAR",
    	TP_BUTTON, toolbutton_statemap, NOPAD,0 },
    { "Menubutton.button", &GenericElementSpec, L"TOOLBAR",
    	TP_SPLITBUTTON,toolbutton_statemap, NOPAD,0 },
    { "Menubutton.dropdown", &GenericElementSpec, L"TOOLBAR",
    	TP_SPLITBUTTONDROPDOWN,toolbutton_statemap, NOPAD,0 },
    { "Treeview.field", &GenericElementSpec, L"TREEVIEW",
	TVP_TREEITEM, treeview_statemap, PAD(1, 1, 1, 1), IGNORE_THEMESIZE },
    { "Treeitem.indicator", &TreeIndicatorElementSpec, L"TREEVIEW",
    	TVP_GLYPH, tvpglyph_statemap, PAD(1,1,6,0), PAD_MARGINS },
    { "Treeheading.border", &GenericElementSpec, L"HEADER",
    	HP_HEADERITEM, header_statemap, PAD(4,0,4,0),0 },
    { "sizegrip", &GenericElementSpec, L"STATUS",
    	SP_GRIPPER, null_statemap, NOPAD,0 },
    { "Spinbox.field", &GenericElementSpec, L"EDIT",







|







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
    { "Toolbutton.border", &GenericElementSpec, L"TOOLBAR",
    	TP_BUTTON, toolbutton_statemap, NOPAD,0 },
    { "Menubutton.button", &GenericElementSpec, L"TOOLBAR",
    	TP_SPLITBUTTON,toolbutton_statemap, NOPAD,0 },
    { "Menubutton.dropdown", &GenericElementSpec, L"TOOLBAR",
    	TP_SPLITBUTTONDROPDOWN,toolbutton_statemap, NOPAD,0 },
    { "Treeview.field", &GenericElementSpec, L"TREEVIEW",
	TVP_TREEITEM, treeview_statemap, PAD(1, 1, 1, 1), 0 },
    { "Treeitem.indicator", &TreeIndicatorElementSpec, L"TREEVIEW",
    	TVP_GLYPH, tvpglyph_statemap, PAD(1,1,6,0), PAD_MARGINS },
    { "Treeheading.border", &GenericElementSpec, L"HEADER",
    	HP_HEADERITEM, header_statemap, PAD(4,0,4,0),0 },
    { "sizegrip", &GenericElementSpec, L"STATUS",
    	SP_GRIPPER, null_statemap, NOPAD,0 },
    { "Spinbox.field", &GenericElementSpec, L"EDIT",
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
};
#undef PAD


static int
GetSysFlagFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
{
    static const char *const names[] = {
	"SM_CXBORDER", "SM_CYBORDER", "SM_CXVSCROLL", "SM_CYVSCROLL",
	"SM_CXHSCROLL", "SM_CYHSCROLL", "SM_CXMENUCHECK", "SM_CYMENUCHECK",
	"SM_CXMENUSIZE", "SM_CYMENUSIZE", "SM_CXSIZE", "SM_CYSIZE", "SM_CXSMSIZE",
	"SM_CYSMSIZE", NULL
    };
    int flags[] = {
	SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL,
	SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK,
	SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE,
	SM_CYSMSIZE
    };

    Tcl_Obj **objv;
    int i, objc;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;
    if (objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args", -1));
	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	return TCL_ERROR;
    }
    for (i = 0; i < objc; ++i) {
	int option;
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], names,
		sizeof(char *), "system constant", 0, &option) != TCL_OK)
	    return TCL_ERROR;
	*resultPtr |= (flags[option] << (8 * (1 - i)));
    }
    return TCL_OK;
}

/*----------------------------------------------------------------------







|



|














|
<




|
|







1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
};
#undef PAD


static int
GetSysFlagFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
{
    static const char *names[] = {
	"SM_CXBORDER", "SM_CYBORDER", "SM_CXVSCROLL", "SM_CYVSCROLL",
	"SM_CXHSCROLL", "SM_CYHSCROLL", "SM_CXMENUCHECK", "SM_CYMENUCHECK",
	"SM_CXMENUSIZE", "SM_CYMENUSIZE", "SM_CXSIZE", "SM_CYSIZE", "SM_CXSMSIZE",
	"SM_CYSMSIZE"
    };
    int flags[] = {
	SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL,
	SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK,
	SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE,
	SM_CYSMSIZE
    };

    Tcl_Obj **objv;
    int i, objc;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;
    if (objc != 2) {
	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);

	return TCL_ERROR;
    }
    for (i = 0; i < objc; ++i) {
	int option;
	if (Tcl_GetIndexFromObj(interp, objv[i], names, "system constant", 0, &option)
		!= TCL_OK)
	    return TCL_ERROR;
	*resultPtr |= (flags[option] << (8 * (1 - i)));
    }
    return TCL_OK;
}

/*----------------------------------------------------------------------
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285




1286
1287
1288
1289
1290
1291
1292
    const char *elementName,
    int objc,
    Tcl_Obj *const objv[])
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    ElementInfo *elementPtr = NULL;
    ClientData elementData;
    LPCWSTR className;
    int partId = 0;
    Ttk_StateTable *stateTable;
    Ttk_Padding pad = {0, 0, 0, 0};
    int flags = 0;
    TkSizeT length = 0;
    char *name;
    LPWSTR wname;
    const Ttk_ElementSpec *elementSpec = &GenericElementSpec;
    Tcl_DString classBuf;

    static const char *const optionStrings[] =
	{ "-padding","-width","-height","-margins", "-syssize",
	  "-halfheight", "-halfwidth", NULL };
    enum { O_PADDING, O_WIDTH, O_HEIGHT, O_MARGINS, O_SYSSIZE,
	   O_HALFHEIGHT, O_HALFWIDTH };

    if (objc < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing required arguments 'class' and/or 'partId'", -1));
	Tcl_SetErrorCode(interp, "TTK", "VSAPI", "REQUIRED", NULL);
	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) {
	return TCL_ERROR;
    }
    name = TkGetStringFromObj(objv[0], &length);
    Tcl_DStringInit(&classBuf);
    className = Tcl_UtfToWCharDString(name, length, &classBuf);

    /* flags or padding */
    if (objc > 3) {
	int i = 3, option = 0;
	for (i = 3; i < objc; i += 2) {
	    int tmp = 0;
	    if (i == objc -1) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Missing value for \"%s\".",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TTK", "VSAPI", "MISSING", NULL);
		goto retErr;
	    }
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &option) != TCL_OK)
		goto retErr;
	    switch (option) {
	    case O_PADDING:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    goto retErr;
		}
		break;
	    case O_MARGINS:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    goto retErr;
		}
		flags |= PAD_MARGINS;
		break;
	    case O_WIDTH:
		if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    goto retErr;
		}
		pad.left = pad.right = tmp;
		flags |= IGNORE_THEMESIZE;
		break;
	    case O_HEIGHT:
		if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    goto retErr;
		}
		pad.top = pad.bottom = tmp;
		flags |= IGNORE_THEMESIZE;
		break;
	    case O_SYSSIZE:
		if (GetSysFlagFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    goto retErr;
		}
		elementSpec = &GenericSizedElementSpec;
		flags |= (tmp & 0xFFFF);
		break;
	    case O_HALFHEIGHT:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    goto retErr;
		}
		if (tmp)
		    flags |= HALF_HEIGHT;
		break;
	    case O_HALFWIDTH:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    goto retErr;
		}
		if (tmp)
		    flags |= HALF_WIDTH;
		break;
	    }
	}
    }

    /* convert a statemap into a state table */
    if (objc > 2) {
	Tcl_Obj **specs;
	int n,j,count, status = TCL_OK;
	if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK)
	    goto retErr;
	/* we over-allocate to ensure there is a terminating entry */
	stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable) * (count + 1));

	memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1));
	for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) {
	    Ttk_StateSpec spec = {0,0};
	    status = Ttk_GetStateSpecFromObj(interp, specs[n], &spec);
	    if (status == TCL_OK) {
		stateTable[j].onBits = spec.onbits;
		stateTable[j].offBits = spec.offbits;
		status = Tcl_GetIntFromObj(interp, specs[n+1],
			&stateTable[j].index);
	    }
	}
	if (status != TCL_OK) {
	    ckfree(stateTable);
	    Tcl_DStringFree(&classBuf);
	    return status;
	}
    } else {
	stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable));
	memset(stateTable, 0, sizeof(Ttk_StateTable));
    }

    elementPtr = (ElementInfo *)ckalloc(sizeof(ElementInfo));
    elementPtr->elementSpec = elementSpec;
    elementPtr->partId = partId;
    elementPtr->statemap = stateTable;
    elementPtr->padding = pad;
    elementPtr->flags = HEAP_ELEMENT | flags;

    /* set the element name to an allocated copy */
    name = (char *)ckalloc(strlen(elementName) + 1);
    strcpy(name, elementName);
    elementPtr->elementName = name;

    /* set the class name to an allocated copy */
    wname = (LPWSTR)ckalloc(Tcl_DStringLength(&classBuf) + sizeof(WCHAR));
    wcscpy(wname, className);
    elementPtr->className = wname;

    elementData = NewElementData(themeData->procs, elementPtr);
    Ttk_RegisterElementSpec(
	theme, elementName, elementPtr->elementSpec, elementData);

    Ttk_RegisterCleanup(interp, elementData, DestroyElementData);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
    Tcl_DStringFree(&classBuf);
    return TCL_OK;

retErr:
    Tcl_DStringFree(&classBuf);
    return TCL_ERROR;
}

/*----------------------------------------------------------------------
 * +++ Initialization routine:
 */

MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    XPThemeData *themeData;
    XPThemeProcs *procs;
    HINSTANCE hlibrary;
    Ttk_Theme themePtr, parentPtr, vistaPtr;
    const ElementInfo *infoPtr;





    procs = LoadXPThemeProcs(&hlibrary);
    if (!procs)
	return TCL_ERROR;
    procs->stubWindow = hwnd;

    /*







|




|


|
<

|






|
|
<






|
<
<







<
|
|
<
|

|
|
|



|




|





|






|






|






|






|













|

|
>












|
<




















|









<

<
<
<
<












|
>
>
>
>







1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131


1132
1133
1134
1135
1136
1137
1138

1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248

1249




1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
    const char *elementName,
    int objc,
    Tcl_Obj *const objv[])
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    ElementInfo *elementPtr = NULL;
    ClientData elementData;
    Tcl_UniChar *className;
    int partId = 0;
    Ttk_StateTable *stateTable;
    Ttk_Padding pad = {0, 0, 0, 0};
    int flags = 0;
    int length = 0;
    char *name;
    LPWSTR wname;
    Ttk_ElementSpec *elementSpec = &GenericElementSpec;


    static const char *optionStrings[] =
	{ "-padding","-width","-height","-margins", "-syssize",
	  "-halfheight", "-halfwidth", NULL };
    enum { O_PADDING, O_WIDTH, O_HEIGHT, O_MARGINS, O_SYSSIZE,
	   O_HALFHEIGHT, O_HALFWIDTH };

    if (objc < 2) {
	Tcl_AppendResult(interp,
	    "missing required arguments 'class' and/or 'partId'", NULL);

	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) {
	return TCL_ERROR;
    }
    className = Tcl_GetUnicodeFromObj(objv[0], &length);



    /* flags or padding */
    if (objc > 3) {
	int i = 3, option = 0;
	for (i = 3; i < objc; i += 2) {
	    int tmp = 0;
	    if (i == objc -1) {

		Tcl_AppendResult(interp, "Missing value for \"",
			Tcl_GetString(objv[i]), "\".", NULL);

		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		    "option", 0, &option) != TCL_OK)
		return TCL_ERROR;
	    switch (option) {
	    case O_PADDING:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case O_MARGINS:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    return TCL_ERROR;
		}
		flags |= PAD_MARGINS;
		break;
	    case O_WIDTH:
		if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		pad.left = pad.right = tmp;
		flags |= IGNORE_THEMESIZE;
		break;
	    case O_HEIGHT:
		if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		pad.top = pad.bottom = tmp;
		flags |= IGNORE_THEMESIZE;
		break;
	    case O_SYSSIZE:
		if (GetSysFlagFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		elementSpec = &GenericSizedElementSpec;
		flags |= (tmp & 0xFFFF);
		break;
	    case O_HALFHEIGHT:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tmp)
		    flags |= HALF_HEIGHT;
		break;
	    case O_HALFWIDTH:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tmp)
		    flags |= HALF_WIDTH;
		break;
	    }
	}
    }

    /* convert a statemap into a state table */
    if (objc > 2) {
	Tcl_Obj **specs;
	int n,j,count, status = TCL_OK;
	if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK)
	    return TCL_ERROR;
	/* we over-allocate to ensure there is a terminating entry */
	stateTable = (Ttk_StateTable *)
		ckalloc(sizeof(Ttk_StateTable) * (count + 1));
	memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1));
	for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) {
	    Ttk_StateSpec spec = {0,0};
	    status = Ttk_GetStateSpecFromObj(interp, specs[n], &spec);
	    if (status == TCL_OK) {
		stateTable[j].onBits = spec.onbits;
		stateTable[j].offBits = spec.offbits;
		status = Tcl_GetIntFromObj(interp, specs[n+1],
			&stateTable[j].index);
	    }
	}
	if (status != TCL_OK) {
	    ckfree((char *)stateTable);

	    return status;
	}
    } else {
	stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable));
	memset(stateTable, 0, sizeof(Ttk_StateTable));
    }

    elementPtr = (ElementInfo *)ckalloc(sizeof(ElementInfo));
    elementPtr->elementSpec = elementSpec;
    elementPtr->partId = partId;
    elementPtr->statemap = stateTable;
    elementPtr->padding = pad;
    elementPtr->flags = HEAP_ELEMENT | flags;

    /* set the element name to an allocated copy */
    name = (char *)ckalloc(strlen(elementName) + 1);
    strcpy(name, elementName);
    elementPtr->elementName = name;

    /* set the class name to an allocated copy */
    wname = (LPWSTR) ckalloc(sizeof(WCHAR) * (length + 1));
    wcscpy(wname, className);
    elementPtr->className = wname;

    elementData = NewElementData(themeData->procs, elementPtr);
    Ttk_RegisterElementSpec(
	theme, elementName, elementPtr->elementSpec, elementData);

    Ttk_RegisterCleanup(interp, elementData, DestroyElementData);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));

    return TCL_OK;




}

/*----------------------------------------------------------------------
 * +++ Initialization routine:
 */

MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    XPThemeData *themeData;
    XPThemeProcs *procs;
    HINSTANCE hlibrary;
    Ttk_Theme themePtr, parentPtr, vistaPtr;
    ElementInfo *infoPtr;
    OSVERSIONINFOW os;

    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
    GetVersionExW(&os);

    procs = LoadXPThemeProcs(&hlibrary);
    if (!procs)
	return TCL_ERROR;
    procs->stubWindow = hwnd;

    /*
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
    Ttk_RegisterElementFactory(interp, "vsapi", Ttk_CreateVsapiElement, themeData);

    /*
     * Create the vista theme on suitable platform versions and set the theme
     * enable function. The theme itself is defined in script.
     */

    if (TkWinGetPlatformTheme() == TK_THEME_WIN_VISTA) {
	vistaPtr = Ttk_CreateTheme(interp, "vista", themePtr);
	if (vistaPtr) {
	    Ttk_SetThemeEnabledProc(vistaPtr, XPThemeEnabled, themeData);
	}
    }

    /*







|







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
    Ttk_RegisterElementFactory(interp, "vsapi", Ttk_CreateVsapiElement, themeData);

    /*
     * Create the vista theme on suitable platform versions and set the theme
     * enable function. The theme itself is defined in script.
     */

    if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && os.dwMajorVersion > 5) {
	vistaPtr = Ttk_CreateTheme(interp, "vista", themePtr);
	if (vistaPtr) {
	    Ttk_SetThemeEnabledProc(vistaPtr, XPThemeEnabled, themeData);
	}
    }

    /*

Changes to win/winMain.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26




27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * winMain.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for wish and other Tk-based applications.
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tk.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <locale.h>
#include <stdlib.h>
#include <tchar.h>

#if defined(__GNUC__)
int _CRT_glob = 0;
#endif /* __GNUC__ */





#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus
}
#endif
#endif /* TK_TEST */

#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
extern Tcl_PackageInitProc Registry_Init;
extern Tcl_PackageInitProc Dde_Init;
extern Tcl_PackageInitProc Dde_SafeInit;
#endif

#ifdef TCL_BROKEN_MAINARGS
static void setargv(int *argcPtr, TCHAR ***argvPtr);
#endif

/*
 * Forward declarations for procedures defined later in this file:
 */



static BOOL consoleRequired = TRUE;

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   define MODULE_SCOPE extern
#endif
MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tk_Main()
 */

#ifdef TK_LOCAL_MAIN_HOOK
MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv);
#endif

/* Make sure the stubbed variants of those are never used. */
#undef Tcl_ObjSetVar2
#undef Tcl_NewStringObj

/*
 *----------------------------------------------------------------------
 *
 * _tWinMain --
 *
 *	Main entry point from Windows.
 *
 * Results:
 *	Returns false if initialization fails, otherwise it never returns.
 *
 * Side effects:
 *	Just about anything, since from here we call arbitrary Tcl code.
 *
 *----------------------------------------------------------------------
 */

int APIENTRY
#ifdef TCL_BROKEN_MAINARGS
WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine,
    int nCmdShow)
#else
_tWinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR lpszCmdLine,
    int nCmdShow)
#endif
{
    TCHAR **argv;
    int argc;
    TCHAR *p;
    (void)hInstance;
    (void)hPrevInstance;
    (void)lpszCmdLine;
    (void)nCmdShow;


    /*
     * 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.
     */

    consoleRequired = TRUE;

    /*
     * Set up the default locale to be standard "C" locale so parsing is
     * performed correctly.
     */

    setlocale(LC_ALL, "C");

    /*
     * Get our args from the c-runtime. Ignore lpszCmdLine.
     */

#if defined(TCL_BROKEN_MAINARGS)
    setargv(&argc, &argv);
#else
    argc = __argc;
    argv = __targv;
#endif

    /*
     * Forward slashes substituted for backslashes.
     */

    for (p = argv[0]; *p != '\0'; p++) {
	if (*p == '\\') {
	    *p = '/';
	}
    }

#ifdef TK_LOCAL_MAIN_HOOK
    TK_LOCAL_MAIN_HOOK(&argc, &argv);
#elif defined(UNICODE) && ((TCL_MAJOR_VERSION > 8) || (TCL_MINOR_VERSION > 6))
    /* This doesn't work on Windows without UNICODE, neither does it work with Tcl 8.6 */
    TclZipfs_AppHook(&argc, &argv);
#endif

    Tk_Main(argc, argv, TK_LOCAL_APPINIT);
    return 0;			/* Needed only to prevent compiler warning. */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *



<
|

<
|
|





|




<
<





>
>
>
>

<
<
<

<
<
<


|





<
<
<
<



>
>












<
<
<
|








|

<
<
<
<




|













<





<
<
<
<
<
<
<

|

|
|
<
<
<
>




















<
<
<

|
<













<
<
<



|







1
2
3

4
5

6
7
8
9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24
25
26
27



28



29
30
31
32
33
34
35
36




37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53



54
55
56
57
58
59
60
61
62
63
64




65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87







88
89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113



114
115

116
117
118
119
120
121
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136
137
138
139
/*
 * winMain.c --
 *

 *	Main entry point for wish and other Tk-based applications.
 *

 * Copyright (c) 1995-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.
 */

#include "tkInt.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <locale.h>



#if defined(__GNUC__)
int _CRT_glob = 0;
#endif /* __GNUC__ */

/*
 * The following declarations refer to internal Tk routines. These interfaces
 * are available for use, but are not supported.
 */
#ifdef TK_TEST



extern Tcl_PackageInitProc Tktest_Init;



#endif /* TK_TEST */

#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES) && TCL_USE_STATIC_PACKAGES
extern Tcl_PackageInitProc Registry_Init;
extern Tcl_PackageInitProc Dde_Init;
extern Tcl_PackageInitProc Dde_SafeInit;
#endif





/*
 * Forward declarations for procedures defined later in this file:
 */

static void		WishPanic(CONST char *format, ...);

static BOOL consoleRequired = TRUE;

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif



extern int TK_LOCAL_APPINIT(Tcl_Interp *interp);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tk_Main()
 */

#ifdef TK_LOCAL_MAIN_HOOK
extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif





/*
 *----------------------------------------------------------------------
 *
 * WinMain --
 *
 *	Main entry point from Windows.
 *
 * Results:
 *	Returns false if initialization fails, otherwise it never returns.
 *
 * Side effects:
 *	Just about anything, since from here we call arbitrary Tcl code.
 *
 *----------------------------------------------------------------------
 */

int APIENTRY

WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine,
    int nCmdShow)







{
    char **argv;
    int argc;
    char *p;




    Tcl_SetPanicProc(WishPanic);

    /*
     * 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.
     */

    consoleRequired = TRUE;

    /*
     * Set up the default locale to be standard "C" locale so parsing is
     * performed correctly.
     */

    setlocale(LC_ALL, "C");

    /*
     * Get our args from the c-runtime. Ignore lpszCmdLine.
     */




    argc = __argc;
    argv = __argv;


    /*
     * Forward slashes substituted for backslashes.
     */

    for (p = argv[0]; *p != '\0'; p++) {
	if (*p == '\\') {
	    *p = '/';
	}
    }

#ifdef TK_LOCAL_MAIN_HOOK
    TK_LOCAL_MAIN_HOOK(&argc, &argv);



#endif

    Tk_Main(argc, argv, TK_LOCAL_APPINIT);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *
183
184
185
186
187
188
189


190
191

192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


251












252




253
254
255










































256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
 *----------------------------------------------------------------------
 */

int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{


    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;

    }
    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;

    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

    /*
     * Initialize the console only if we are running as an interactive
     * application.
     */

    if (consoleRequired) {
	if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }
#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
    if (Registry_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "registry", Registry_Init, 0);

    if (Dde_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
     *     return TCL_ERROR;
     * }
     *
     * where "Mod" is the name of the module. (Dynamically-loadable packages
     * should have the same entry-point name.)
     */

    /*
     * Call Tcl_CreateObjCommand for application-specific commands, if they
     * weren't already created by the init procedures called above.
     */

    /*
     * Specify a user-specific startup file to invoke if the application is
     * run interactively. Typically the startup file is "~/.apprc" where "app"
     * is the name of the application. If this line is deleted then no user-
     * specific startup file will be run under any conditions.
     */



    Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,












	    Tcl_NewStringObj("~/wishrc.tcl", -1), TCL_GLOBAL_ONLY);




    return TCL_OK;
}











































#if defined(TK_TEST)
/*
 *----------------------------------------------------------------------
 *
 * _tmain --
 *
 *	Main entry point from the console.
 *
 * Results:
 *	None: Tk_Main never returns here, so this procedure never returns
 *	either.
 *
 * Side effects:
 *	Whatever the applications does.
 *
 *----------------------------------------------------------------------
 */

#ifdef TCL_BROKEN_MAINARGS
int
main(
    int argc,
    char **dummy)
{
    TCHAR **argv;
    (void)dummy;
#else
int
_tmain(
    int argc,
    TCHAR **argv)
{
#endif
    /*
     * Set up the default locale to be standard "C" locale so parsing is
     * performed correctly.
     */

    setlocale(LC_ALL, "C");

#ifdef TCL_BROKEN_MAINARGS
    /*
     * Get our args from the c-runtime. Ignore argc/argv.
     */

    setargv(&argc, &argv);
#endif
    /*
     * Console emulation widget not required as this entry is from the
     * console subsystem, thus stdin,out,err already have end-points.
     */

    consoleRequired = FALSE;

#ifdef TK_LOCAL_MAIN_HOOK
    TK_LOCAL_MAIN_HOOK(&argc, &argv);
#endif

    Tk_Main(argc, argv, Tcl_AppInit);
    return 0;
}
#endif /* !__GNUC__ || TK_TEST */


/*
 *-------------------------------------------------------------------------
 *
 * setargv --
 *
 *	Parse the Windows command line string into argc/argv. Done here
 *	because we don't trust the builtin argument parser in crt0. Windows
 *	applications are responsible for breaking their command line into
 *	arguments.
 *
 *	2N backslashes + quote -> N backslashes + begin quoted string
 *	2N + 1 backslashes + quote -> literal
 *	N backslashes + non-quote -> literal
 *	quote + quote in a quoted string -> single quote
 *	quote + quote not in quoted string -> empty string
 *	quote -> begin quoted string
 *
 * Results:
 *	Fills argcPtr with the number of arguments and argvPtr with the array
 *	of arguments.
 *
 * Side effects:
 *	Memory allocated.
 *
 *--------------------------------------------------------------------------
 */

#ifdef TCL_BROKEN_MAINARGS
static void
setargv(
    int *argcPtr,		/* Filled with number of argument strings. */
    TCHAR ***argvPtr)		/* Filled with argument strings (malloc'd). */
{
    TCHAR *cmdLine, *p, *arg, *argSpace;
    TCHAR **argv;
    int argc, size, inquote, copy, slashes;

    cmdLine = GetCommandLine();

    /*
     * Precompute an overly pessimistic guess at the number of arguments in
     * the command line by counting non-space spans.
     */

    size = 2;
    for (p = cmdLine; *p != '\0'; p++) {
	if ((*p == ' ') || (*p == '\t')) {	/* INTL: ISO space. */
	    size++;
	    while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
		p++;
	    }
	    if (*p == '\0') {
		break;
	    }
	}
    }

    /* Make sure we don't call ckalloc through the (not yet initialized) stub table */
    #undef Tcl_Alloc
    #undef Tcl_DbCkalloc

    argSpace = (TCHAR *)ckalloc(size * sizeof(char *)
	    + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR));
    argv = (TCHAR **) argSpace;
    argSpace += size * (sizeof(char *)/sizeof(TCHAR));
    size--;

    p = cmdLine;
    for (argc = 0; argc < size; argc++) {
	argv[argc] = arg = argSpace;
	while ((*p == ' ') || (*p == '\t')) {	/* INTL: ISO space. */
	    p++;
	}
	if (*p == '\0') {
	    break;
	}

	inquote = 0;
	slashes = 0;
	while (1) {
	    copy = 1;
	    while (*p == '\\') {
		slashes++;
		p++;
	    }
	    if (*p == '"') {
		if ((slashes & 1) == 0) {
		    copy = 0;
		    if ((inquote) && (p[1] == '"')) {
			p++;
			copy = 1;
		    } else {
			inquote = !inquote;
		    }
		}
		slashes >>= 1;
	    }

	    while (slashes) {
		*arg = '\\';
		arg++;
		slashes--;
	    }

	    if ((*p == '\0') || (!inquote &&
		    ((*p == ' ') || (*p == '\t')))) {	/* INTL: ISO space. */
		break;
	    }
	    if (copy != 0) {
		*arg = *p;
		arg++;
	    }
	    p++;
	}
	*arg = '\0';
	argSpace = arg + 1;
    }
    argv[argc] = NULL;

    *argcPtr = argc;
    *argvPtr = argv;
}
#endif /* TCL_BROKEN_MAINARGS */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
|
|
>


<
>










|


|

|

|


|

|




|

|















|










>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|













<



|

|
<
<
<
<
<
<
|
<







<
<
<
<
<
<
<







<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<







151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310






311

312
313
314
315
316
317
318







319
320
321
322
323
324
325




326
327
328





























































































































329

330
331
332
333
334
335
336
 *----------------------------------------------------------------------
 */

int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
#define TK_MAX_WARN_LEN 1024
    WCHAR msgString[TK_MAX_WARN_LEN + 5];

    if (Tcl_Init(interp) == TCL_ERROR) {
	goto error;
    }
    if (Tk_Init(interp) == TCL_ERROR) {

	goto error;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

    /*
     * Initialize the console only if we are running as an interactive
     * application.
     */

    if (consoleRequired) {
	if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
	    goto error;
	}
    }
#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES) && TCL_USE_STATIC_PACKAGES
    if (Registry_Init(interp) == TCL_ERROR) {
	goto error;
    }
    Tcl_StaticPackage(interp, "Registry", Registry_Init, NULL);

    if (Dde_Init(interp) == TCL_ERROR) {
	goto error;
    }
    Tcl_StaticPackage(interp, "Dde", Dde_Init, NULL);
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	goto error;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, NULL);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
     *     return TCL_ERROR;
     * }
     *
     * where "Mod" is the name of the module. (Dynamically-loadable packages
     * should have the same entry-point name.)
     */

    /*
     * Call Tcl_CreateCommand for application-specific commands, if they
     * weren't already created by the init procedures called above.
     */

    /*
     * Specify a user-specific startup file to invoke if the application is
     * run interactively. Typically the startup file is "~/.apprc" where "app"
     * is the name of the application. If this line is deleted then no user-
     * specific startup file will be run under any conditions.
     */

    Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
    return TCL_OK;

error:
    MultiByteToWideChar(CP_UTF8, 0, Tcl_GetStringResult(interp), -1,
	    msgString, TK_MAX_WARN_LEN);
    /*
     * Truncate MessageBox string if it is too long to not overflow the screen
     * and cause possible oversized window error.
     */
	memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
    MessageBeep(MB_ICONEXCLAMATION);
    MessageBoxW(NULL, msgString, L"Error in Wish",
	    MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
    ExitProcess(1);

    /*
     * We won't reach this, but we need the return.
     */

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * WishPanic --
 *
 *	Display a message and exit.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Exits the program.
 *
 *----------------------------------------------------------------------
 */

void
WishPanic(
    CONST char *format, ...)
{
    va_list argList;
    char buf[TK_MAX_WARN_LEN];
    WCHAR msgString[TK_MAX_WARN_LEN + 5];

    va_start(argList, format);
    vsprintf(buf, format, argList);

    MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TK_MAX_WARN_LEN);
    /*
     * Truncate MessageBox string if it is too long to not overflow the screen
     * and cause possible oversized window error.
     */
	memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
    MessageBeep(MB_ICONEXCLAMATION);
    MessageBoxW(NULL, msgString, L"Fatal Error in Wish",
	    MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
#ifdef _MSC_VER
    DebugBreak();
#endif
    ExitProcess(1);
}

#if defined(TK_TEST)
/*
 *----------------------------------------------------------------------
 *
 * main --
 *
 *	Main entry point from the console.
 *
 * Results:
 *	None: Tk_Main never returns here, so this procedure never returns
 *	either.
 *
 * Side effects:
 *	Whatever the applications does.
 *
 *----------------------------------------------------------------------
 */


int
main(
    int argc,
    char **argv)
{
    Tcl_SetPanicProc(WishPanic);








    /*
     * Set up the default locale to be standard "C" locale so parsing is
     * performed correctly.
     */

    setlocale(LC_ALL, "C");








    /*
     * Console emulation widget not required as this entry is from the
     * console subsystem, thus stdin,out,err already have end-points.
     */

    consoleRequired = FALSE;





    Tk_Main(argc, argv, Tcl_AppInit);
    return 0;
}





























































































































#endif /* TK_TEST */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Deleted xlib/X11/DECkeysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/***********************************************************

Copyright 1988, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.


Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts.

                        All Rights Reserved

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, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

/*
 * DEC private keysyms
 * (29th bit set)
 */

/* two-key compose sequence initiators, chosen to map to Latin1 characters */

#define DXK_ring_accent         0x1000FEB0
#define DXK_circumflex_accent   0x1000FE5E
#define DXK_cedilla_accent      0x1000FE2C
#define DXK_acute_accent        0x1000FE27
#define DXK_grave_accent        0x1000FE60
#define DXK_tilde               0x1000FE7E
#define DXK_diaeresis           0x1000FE22

/* special keysym for LK2** "Remove" key on editing keypad */

#define DXK_Remove	0x1000FF00   /* Remove */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































Deleted xlib/X11/HPkeysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*

Copyright 1987, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from The Open Group.

Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,

                        All Rights Reserved

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, and that the names of Hewlett Packard
or Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

*/

#ifndef _HPKEYSYM_H

#define _HPKEYSYM_H

#define hpXK_ClearLine		0x1000FF6F
#define hpXK_InsertLine		0x1000FF70
#define hpXK_DeleteLine		0x1000FF71
#define hpXK_InsertChar		0x1000FF72
#define hpXK_DeleteChar		0x1000FF73
#define hpXK_BackTab		0x1000FF74
#define hpXK_KP_BackTab		0x1000FF75
#define hpXK_Modelock1		0x1000FF48
#define hpXK_Modelock2		0x1000FF49
#define hpXK_Reset		0x1000FF6C
#define hpXK_System		0x1000FF6D
#define hpXK_User		0x1000FF6E
#define hpXK_mute_acute		0x100000A8
#define hpXK_mute_grave		0x100000A9
#define hpXK_mute_asciicircum	0x100000AA
#define hpXK_mute_diaeresis	0x100000AB
#define hpXK_mute_asciitilde	0x100000AC
#define hpXK_lira		0x100000AF
#define hpXK_guilder		0x100000BE
#define hpXK_Ydiaeresis		0x100000EE
#define hpXK_IO			0x100000EE
#define hpXK_longminus		0x100000F6
#define hpXK_block		0x100000FC


#ifndef _OSF_Keysyms
#define _OSF_Keysyms

#define osfXK_Copy		0x1004FF02
#define osfXK_Cut		0x1004FF03
#define osfXK_Paste		0x1004FF04
#define osfXK_BackTab		0x1004FF07
#define osfXK_BackSpace		0x1004FF08
#define osfXK_Clear		0x1004FF0B
#define osfXK_Escape		0x1004FF1B
#define osfXK_AddMode		0x1004FF31
#define osfXK_PrimaryPaste	0x1004FF32
#define osfXK_QuickPaste	0x1004FF33
#define osfXK_PageLeft		0x1004FF40
#define osfXK_PageUp		0x1004FF41
#define osfXK_PageDown		0x1004FF42
#define osfXK_PageRight		0x1004FF43
#define osfXK_Activate		0x1004FF44
#define osfXK_MenuBar		0x1004FF45
#define osfXK_Left		0x1004FF51
#define osfXK_Up		0x1004FF52
#define osfXK_Right		0x1004FF53
#define osfXK_Down		0x1004FF54
#define osfXK_EndLine		0x1004FF57
#define osfXK_BeginLine		0x1004FF58
#define osfXK_EndData		0x1004FF59
#define osfXK_BeginData		0x1004FF5A
#define osfXK_PrevMenu		0x1004FF5B
#define osfXK_NextMenu		0x1004FF5C
#define osfXK_PrevField		0x1004FF5D
#define osfXK_NextField		0x1004FF5E
#define osfXK_Select		0x1004FF60
#define osfXK_Insert		0x1004FF63
#define osfXK_Undo		0x1004FF65
#define osfXK_Menu		0x1004FF67
#define osfXK_Cancel		0x1004FF69
#define osfXK_Help		0x1004FF6A
#define osfXK_SelectAll		0x1004FF71
#define osfXK_DeselectAll	0x1004FF72
#define osfXK_Reselect		0x1004FF73
#define osfXK_Extend		0x1004FF74
#define osfXK_Restore		0x1004FF78
#define osfXK_Delete		0x1004FFFF

#endif /* _OSF_Keysyms */


/**************************************************************
 * The use of the following macros is deprecated.
 * They are listed below only for backwards compatibility.
 */
#define XK_Reset                0x1000FF6C
#define XK_System               0x1000FF6D
#define XK_User                 0x1000FF6E
#define XK_ClearLine            0x1000FF6F
#define XK_InsertLine           0x1000FF70
#define XK_DeleteLine           0x1000FF71
#define XK_InsertChar           0x1000FF72
#define XK_DeleteChar           0x1000FF73
#define XK_BackTab              0x1000FF74
#define XK_KP_BackTab           0x1000FF75
#define XK_Ext16bit_L           0x1000FF76
#define XK_Ext16bit_R           0x1000FF77
#define XK_mute_acute           0x100000a8
#define XK_mute_grave           0x100000a9
#define XK_mute_asciicircum     0x100000aa
#define XK_mute_diaeresis       0x100000ab
#define XK_mute_asciitilde      0x100000ac
#define XK_lira                 0x100000af
#define XK_guilder              0x100000be
#ifndef XK_Ydiaeresis
#define XK_Ydiaeresis           0x100000ee
#endif
#define XK_IO                   0x100000ee
#define XK_longminus            0x100000f6
#define XK_block                0x100000fc

#endif /* _HPKEYSYM_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































Deleted xlib/X11/Sunkeysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
/************************************************************

Copyright 1991, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.

***********************************************************/

/*
 * Floating Accent
 */

#define	SunXK_FA_Grave		0x1005FF00
#define	SunXK_FA_Circum		0x1005FF01
#define	SunXK_FA_Tilde		0x1005FF02
#define	SunXK_FA_Acute		0x1005FF03
#define	SunXK_FA_Diaeresis	0x1005FF04
#define	SunXK_FA_Cedilla	0x1005FF05

/*
 * Miscellaneous Functions
 */

#define	SunXK_F36		0x1005FF10	/* Labeled F11 */
#define	SunXK_F37		0x1005FF11	/* Labeled F12 */

#define SunXK_Sys_Req   	0x1005FF60
#define SunXK_Print_Screen	0x0000FF61	/* Same as XK_Print */

/*
 * International & Multi-Key Character Composition
 */

#define SunXK_Compose		0x0000FF20	/* Same as XK_Multi_key */
#define SunXK_AltGraph		0x0000FF7E	/* Same as XK_Mode_switch */

/*
 * Cursor Control
 */

#define SunXK_PageUp		0x0000FF55 	/* Same as XK_Prior */
#define SunXK_PageDown		0x0000FF56	/* Same as XK_Next */

/*
 * Open Look Functions
 */

#define SunXK_Undo		0x0000FF65	/* Same as XK_Undo */
#define SunXK_Again		0x0000FF66	/* Same as XK_Redo */
#define SunXK_Find		0x0000FF68	/* Same as XK_Find */
#define SunXK_Stop		0x0000FF69	/* Same as XK_Cancel */
#define SunXK_Props		0x1005FF70
#define SunXK_Front		0x1005FF71
#define SunXK_Copy		0x1005FF72
#define SunXK_Open		0x1005FF73
#define SunXK_Paste		0x1005FF74
#define SunXK_Cut		0x1005FF75

#define SunXK_PowerSwitch		0x1005FF76
#define SunXK_AudioLowerVolume		0x1005FF77
#define SunXK_AudioMute			0x1005FF78
#define SunXK_AudioRaiseVolume		0x1005FF79
#define SunXK_VideoDegauss		0x1005FF7A
#define SunXK_VideoLowerBrightness	0x1005FF7B
#define SunXK_VideoRaiseBrightness	0x1005FF7C
#define SunXK_PowerSwitchShift		0x1005FF7D
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































Changes to xlib/X11/X.h.





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54





55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94

95
96
97
98
99
100
101




/* Definitions for the X window system likely to be used by applications */

#ifndef X_H
#define X_H

/***********************************************************

Copyright 1987, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.


Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.


                        All Rights Reserved

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, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

#define X_PROTOCOL	11		/* current protocol version */
#define X_PROTOCOL_REVISION 0		/* current minor version */






/* Resources */

#ifdef _WIN64
typedef unsigned __int64 XID;
#else
typedef unsigned long XID;
#endif

typedef XID Window;
typedef XID Drawable;
#ifndef _XTYPEDEF_FONT
#  define _XTYPEDEF_FONT
typedef XID Font;
#endif
typedef XID Pixmap;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;

typedef unsigned long Mask;

typedef unsigned long Atom;

typedef unsigned long VisualID;

typedef unsigned long Time;

typedef unsigned int KeyCode;	/* In order to use IME, the Macintosh needs
				 * to pack 3 bytes into the keyCode field in
				 * the XEvent.  In the real X.h, a KeyCode is
				 * defined as a short, which wouldn't be big
				 * enough. */

/*****************************************************************
 * RESERVED RESOURCE AND CONSTANT DEFINITIONS
 *****************************************************************/


/* #define None              0L      See bug [9e31fd9449] and below */


#define ParentRelative       1L	/* background pixmap in CreateWindow
				    and ChangeWindowAttributes */

#define CopyFromParent       0L	/* border pixmap in CreateWindow
				       and ChangeWindowAttributes
				   special VisualID and special window
>
>
>
>






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>







|












<


>
>
>
>
>




|






<
<

<














|









>
|
>







1
2
3
4
5
6
7
8
9
10
























11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50


51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 *	$XConsortium: X.h,v 1.66 88/09/06 15:55:56 jim Exp $
 */

/* Definitions for the X window system likely to be used by applications */

#ifndef X_H
#define X_H

/***********************************************************
























Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

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, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

#define X_PROTOCOL	11		/* current protocol version */
#define X_PROTOCOL_REVISION 0		/* current minor version */

#if defined(MAC_OSX_TK)
#   define Cursor XCursor
#   define Region XRegion
#endif

/* Resources */

#ifdef _WIN64
typedef __int64 XID;
#else
typedef unsigned long XID;
#endif

typedef XID Window;
typedef XID Drawable;


typedef XID Font;

typedef XID Pixmap;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;

typedef unsigned long Mask;

typedef unsigned long Atom;

typedef unsigned long VisualID;

typedef unsigned long Time;

typedef unsigned long KeyCode;	/* In order to use IME, the Macintosh needs
				 * to pack 3 bytes into the keyCode field in
				 * the XEvent.  In the real X.h, a KeyCode is
				 * defined as a short, which wouldn't be big
				 * enough. */

/*****************************************************************
 * RESERVED RESOURCE AND CONSTANT DEFINITIONS
 *****************************************************************/

#ifndef _WIN32
#   define None              0L      /* See bug [9e31fd9449] and below */
#endif

#define ParentRelative       1L	/* background pixmap in CreateWindow
				    and ChangeWindowAttributes */

#define CopyFromParent       0L	/* border pixmap in CreateWindow
				       and ChangeWindowAttributes
				   special VisualID and special window
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201

202
203
204
205
206
207
208

209

210
211
212
213
214
215
216
#define PropertyNotify		28
#define SelectionClear		29
#define SelectionRequest	30
#define SelectionNotify		31
#define ColormapNotify		32
#define ClientMessage		33
#define MappingNotify		34
#define GenericEvent		35
#define LASTEvent		36	/* must be bigger than any event # */


/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
   state in various key-, mouse-, and button-related events. */

#define ShiftMask		(1<<0)
#define LockMask		(1<<1)

/* #define ControlMask		(1<<2) See bug [9e31fd9449] and below */

#define Mod1Mask		(1<<3)
#define Mod2Mask		(1<<4)
#define Mod3Mask		(1<<5)
#define Mod4Mask		(1<<6)
#define Mod5Mask		(1<<7)

/* See bug [9e31fd9449], this way prevents conflicts with Win32 headers */

enum _Bug9e31fd9449 { None = 0, ControlMask = (1<<2) };


/* modifier names.  Used to build a SetModifierMapping request or
   to read a GetModifierMapping request.  These correspond to the
   masks defined above. */
#define ShiftMapIndex		0
#define LockMapIndex		1
#define ControlMapIndex		2







<
|







>
|
>







>

>







169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#define PropertyNotify		28
#define SelectionClear		29
#define SelectionRequest	30
#define SelectionNotify		31
#define ColormapNotify		32
#define ClientMessage		33
#define MappingNotify		34

#define LASTEvent		35	/* must be bigger than any event # */


/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
   state in various key-, mouse-, and button-related events. */

#define ShiftMask		(1<<0)
#define LockMask		(1<<1)
#ifndef _WIN32
#   define ControlMask		(1<<2) /* See bug [9e31fd9449] and below */
#endif
#define Mod1Mask		(1<<3)
#define Mod2Mask		(1<<4)
#define Mod3Mask		(1<<5)
#define Mod4Mask		(1<<6)
#define Mod5Mask		(1<<7)

/* See bug [9e31fd9449], this way prevents conflicts with Win32 headers */
#ifdef _WIN32
enum _Bug9e31fd9449 { None = 0, ControlMask = (1<<2) };
#endif

/* modifier names.  Used to build a SetModifierMapping request or
   to read a GetModifierMapping request.  These correspond to the
   masks defined above. */
#define ShiftMapIndex		0
#define LockMapIndex		1
#define ControlMapIndex		2
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/* Circulation request */

#define PlaceOnTop		0
#define PlaceOnBottom		1

/* protocol families */

#define FamilyInternet		0	/* IPv4 */
#define FamilyDECnet		1
#define FamilyChaos		2
#define FamilyInternet6		6	/* IPv6 */

/* authentication families not tied to a specific protocol */
#define FamilyServerInterpreted 5

/* Property notification */

#define PropertyNewValue	0
#define PropertyDelete		1

/* Color Map notification */







|


<
<
<
<







259
260
261
262
263
264
265
266
267
268




269
270
271
272
273
274
275
/* Circulation request */

#define PlaceOnTop		0
#define PlaceOnBottom		1

/* protocol families */

#define FamilyInternet		0
#define FamilyDECnet		1
#define FamilyChaos		2





/* Property notification */

#define PropertyNewValue	0
#define PropertyDelete		1

/* Color Map notification */
690
691
692
693
694
695
696
697





698
#define DirectColor		5


/* Byte order  used in imageByteOrder and bitmapBitOrder */

#define LSBFirst		0
#define MSBFirst		1






#endif /* X_H */








>
>
>
>
>

673
674
675
676
677
678
679
680
681
682
683
684
685
686
#define DirectColor		5


/* Byte order  used in imageByteOrder and bitmapBitOrder */

#define LSBFirst		0
#define MSBFirst		1

#if defined(MAC_OSX_TK)
#   undef Cursor
#   undef Region
#endif

#endif /* X_H */

Deleted xlib/X11/XF86keysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
 * XFree86 vendor specific keysyms.
 *
 * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
 *
 * X.Org will not be adding to the XF86 set of keysyms, though they have
 * been adopted and are considered a "standard" part of X keysym definitions.
 * XFree86 never properly commented these keysyms, so we have done our
 * best to explain the semantic meaning of these keys.
 *
 * XFree86 has removed their mail archives of the period, that might have
 * shed more light on some of these definitions. Until/unless we resurrect
 * these archives, these are from memory and usage.
 */

/*
 * ModeLock
 *
 * This one is old, and not really used any more since XKB offers this
 * functionality.
 */

#define XF86XK_ModeLock		0x1008FF01	/* Mode Switch Lock */

/* Backlight controls. */
#define XF86XK_MonBrightnessUp    0x1008FF02  /* Monitor/panel brightness */
#define XF86XK_MonBrightnessDown  0x1008FF03  /* Monitor/panel brightness */
#define XF86XK_KbdLightOnOff      0x1008FF04  /* Keyboards may be lit     */
#define XF86XK_KbdBrightnessUp    0x1008FF05  /* Keyboards may be lit     */
#define XF86XK_KbdBrightnessDown  0x1008FF06  /* Keyboards may be lit     */
#define XF86XK_MonBrightnessCycle 0x1008FF07  /* Monitor/panel brightness */

/*
 * Keys found on some "Internet" keyboards.
 */
#define XF86XK_Standby		0x1008FF10   /* System into standby mode   */
#define XF86XK_AudioLowerVolume	0x1008FF11   /* Volume control down        */
#define XF86XK_AudioMute	0x1008FF12   /* Mute sound from the system */
#define XF86XK_AudioRaiseVolume	0x1008FF13   /* Volume control up          */
#define XF86XK_AudioPlay	0x1008FF14   /* Start playing of audio >   */
#define XF86XK_AudioStop	0x1008FF15   /* Stop playing audio         */
#define XF86XK_AudioPrev	0x1008FF16   /* Previous track             */
#define XF86XK_AudioNext	0x1008FF17   /* Next track                 */
#define XF86XK_HomePage		0x1008FF18   /* Display user's home page   */
#define XF86XK_Mail		0x1008FF19   /* Invoke user's mail program */
#define XF86XK_Start		0x1008FF1A   /* Start application          */
#define XF86XK_Search		0x1008FF1B   /* Search                     */
#define XF86XK_AudioRecord	0x1008FF1C   /* Record audio application   */

/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere)   */
#define XF86XK_Calculator	0x1008FF1D   /* Invoke calculator program  */
#define XF86XK_Memo		0x1008FF1E   /* Invoke Memo taking program */
#define XF86XK_ToDoList		0x1008FF1F   /* Invoke To Do List program  */
#define XF86XK_Calendar		0x1008FF20   /* Invoke Calendar program    */
#define XF86XK_PowerDown	0x1008FF21   /* Deep sleep the system      */
#define XF86XK_ContrastAdjust	0x1008FF22   /* Adjust screen contrast     */
#define XF86XK_RockerUp		0x1008FF23   /* Rocker switches exist up   */
#define XF86XK_RockerDown	0x1008FF24   /* and down                   */
#define XF86XK_RockerEnter	0x1008FF25   /* and let you press them     */

/* Some more "Internet" keyboard symbols */
#define XF86XK_Back		0x1008FF26   /* Like back on a browser     */
#define XF86XK_Forward		0x1008FF27   /* Like forward on a browser  */
#define XF86XK_Stop		0x1008FF28   /* Stop current operation     */
#define XF86XK_Refresh		0x1008FF29   /* Refresh the page           */
#define XF86XK_PowerOff		0x1008FF2A   /* Power off system entirely  */
#define XF86XK_WakeUp		0x1008FF2B   /* Wake up system from sleep  */
#define XF86XK_Eject            0x1008FF2C   /* Eject device (e.g. DVD)    */
#define XF86XK_ScreenSaver      0x1008FF2D   /* Invoke screensaver         */
#define XF86XK_WWW              0x1008FF2E   /* Invoke web browser         */
#define XF86XK_Sleep            0x1008FF2F   /* Put system to sleep        */
#define XF86XK_Favorites	0x1008FF30   /* Show favorite locations    */
#define XF86XK_AudioPause	0x1008FF31   /* Pause audio playing        */
#define XF86XK_AudioMedia	0x1008FF32   /* Launch media collection app */
#define XF86XK_MyComputer	0x1008FF33   /* Display "My Computer" window */
#define XF86XK_VendorHome	0x1008FF34   /* Display vendor home web site */
#define XF86XK_LightBulb	0x1008FF35   /* Light bulb keys exist       */
#define XF86XK_Shop		0x1008FF36   /* Display shopping web site   */
#define XF86XK_History		0x1008FF37   /* Show history of web surfing */
#define XF86XK_OpenURL		0x1008FF38   /* Open selected URL           */
#define XF86XK_AddFavorite	0x1008FF39   /* Add URL to favorites list   */
#define XF86XK_HotLinks		0x1008FF3A   /* Show "hot" links            */
#define XF86XK_BrightnessAdjust	0x1008FF3B   /* Invoke brightness adj. UI   */
#define XF86XK_Finance		0x1008FF3C   /* Display financial site      */
#define XF86XK_Community	0x1008FF3D   /* Display user's community    */
#define XF86XK_AudioRewind	0x1008FF3E   /* "rewind" audio track        */
#define XF86XK_BackForward	0x1008FF3F   /* ??? */
#define XF86XK_Launch0		0x1008FF40   /* Launch Application          */
#define XF86XK_Launch1		0x1008FF41   /* Launch Application          */
#define XF86XK_Launch2		0x1008FF42   /* Launch Application          */
#define XF86XK_Launch3		0x1008FF43   /* Launch Application          */
#define XF86XK_Launch4		0x1008FF44   /* Launch Application          */
#define XF86XK_Launch5		0x1008FF45   /* Launch Application          */
#define XF86XK_Launch6		0x1008FF46   /* Launch Application          */
#define XF86XK_Launch7		0x1008FF47   /* Launch Application          */
#define XF86XK_Launch8		0x1008FF48   /* Launch Application          */
#define XF86XK_Launch9		0x1008FF49   /* Launch Application          */
#define XF86XK_LaunchA		0x1008FF4A   /* Launch Application          */
#define XF86XK_LaunchB		0x1008FF4B   /* Launch Application          */
#define XF86XK_LaunchC		0x1008FF4C   /* Launch Application          */
#define XF86XK_LaunchD		0x1008FF4D   /* Launch Application          */
#define XF86XK_LaunchE		0x1008FF4E   /* Launch Application          */
#define XF86XK_LaunchF		0x1008FF4F   /* Launch Application          */

#define XF86XK_ApplicationLeft	0x1008FF50   /* switch to application, left */
#define XF86XK_ApplicationRight	0x1008FF51   /* switch to application, right*/
#define XF86XK_Book		0x1008FF52   /* Launch bookreader           */
#define XF86XK_CD		0x1008FF53   /* Launch CD/DVD player        */
#define XF86XK_Calculater	0x1008FF54   /* Launch Calculater           */
#define XF86XK_Clear		0x1008FF55   /* Clear window, screen        */
#define XF86XK_Close		0x1008FF56   /* Close window                */
#define XF86XK_Copy		0x1008FF57   /* Copy selection              */
#define XF86XK_Cut		0x1008FF58   /* Cut selection               */
#define XF86XK_Display		0x1008FF59   /* Output switch key           */
#define XF86XK_DOS		0x1008FF5A   /* Launch DOS (emulation)      */
#define XF86XK_Documents	0x1008FF5B   /* Open documents window       */
#define XF86XK_Excel		0x1008FF5C   /* Launch spread sheet         */
#define XF86XK_Explorer		0x1008FF5D   /* Launch file explorer        */
#define XF86XK_Game		0x1008FF5E   /* Launch game                 */
#define XF86XK_Go		0x1008FF5F   /* Go to URL                   */
#define XF86XK_iTouch		0x1008FF60   /* Logitech iTouch- don't use  */
#define XF86XK_LogOff		0x1008FF61   /* Log off system              */
#define XF86XK_Market		0x1008FF62   /* ??                          */
#define XF86XK_Meeting		0x1008FF63   /* enter meeting in calendar   */
#define XF86XK_MenuKB		0x1008FF65   /* distinguish keyboard from PB */
#define XF86XK_MenuPB		0x1008FF66   /* distinguish PB from keyboard */
#define XF86XK_MySites		0x1008FF67   /* Favourites                  */
#define XF86XK_New		0x1008FF68   /* New (folder, document...    */
#define XF86XK_News		0x1008FF69   /* News                        */
#define XF86XK_OfficeHome	0x1008FF6A   /* Office home (old Staroffice)*/
#define XF86XK_Open		0x1008FF6B   /* Open                        */
#define XF86XK_Option		0x1008FF6C   /* ?? */
#define XF86XK_Paste		0x1008FF6D   /* Paste                       */
#define XF86XK_Phone		0x1008FF6E   /* Launch phone; dial number   */
#define XF86XK_Q		0x1008FF70   /* Compaq's Q - don't use      */
#define XF86XK_Reply		0x1008FF72   /* Reply e.g., mail            */
#define XF86XK_Reload		0x1008FF73   /* Reload web page, file, etc. */
#define XF86XK_RotateWindows	0x1008FF74   /* Rotate windows e.g. xrandr  */
#define XF86XK_RotationPB	0x1008FF75   /* don't use                   */
#define XF86XK_RotationKB	0x1008FF76   /* don't use                   */
#define XF86XK_Save		0x1008FF77   /* Save (file, document, state */
#define XF86XK_ScrollUp		0x1008FF78   /* Scroll window/contents up   */
#define XF86XK_ScrollDown	0x1008FF79   /* Scrool window/contentd down */
#define XF86XK_ScrollClick	0x1008FF7A   /* Use XKB mousekeys instead   */
#define XF86XK_Send		0x1008FF7B   /* Send mail, file, object     */
#define XF86XK_Spell		0x1008FF7C   /* Spell checker               */
#define XF86XK_SplitScreen	0x1008FF7D   /* Split window or screen      */
#define XF86XK_Support		0x1008FF7E   /* Get support (??)            */
#define XF86XK_TaskPane		0x1008FF7F   /* Show tasks */
#define XF86XK_Terminal		0x1008FF80   /* Launch terminal emulator    */
#define XF86XK_Tools		0x1008FF81   /* toolbox of desktop/app.     */
#define XF86XK_Travel		0x1008FF82   /* ?? */
#define XF86XK_UserPB		0x1008FF84   /* ?? */
#define XF86XK_User1KB		0x1008FF85   /* ?? */
#define XF86XK_User2KB		0x1008FF86   /* ?? */
#define XF86XK_Video		0x1008FF87   /* Launch video player       */
#define XF86XK_WheelButton	0x1008FF88   /* button from a mouse wheel */
#define XF86XK_Word		0x1008FF89   /* Launch word processor     */
#define XF86XK_Xfer		0x1008FF8A
#define XF86XK_ZoomIn		0x1008FF8B   /* zoom in view, map, etc.   */
#define XF86XK_ZoomOut		0x1008FF8C   /* zoom out view, map, etc.  */

#define XF86XK_Away		0x1008FF8D   /* mark yourself as away     */
#define XF86XK_Messenger	0x1008FF8E   /* as in instant messaging   */
#define XF86XK_WebCam		0x1008FF8F   /* Launch web camera app.    */
#define XF86XK_MailForward	0x1008FF90   /* Forward in mail           */
#define XF86XK_Pictures		0x1008FF91   /* Show pictures             */
#define XF86XK_Music		0x1008FF92   /* Launch music application  */

#define XF86XK_Battery		0x1008FF93   /* Display battery information */
#define XF86XK_Bluetooth	0x1008FF94   /* Enable/disable Bluetooth    */
#define XF86XK_WLAN		0x1008FF95   /* Enable/disable WLAN         */
#define XF86XK_UWB		0x1008FF96   /* Enable/disable UWB	    */

#define XF86XK_AudioForward	0x1008FF97   /* fast-forward audio track    */
#define XF86XK_AudioRepeat	0x1008FF98   /* toggle repeat mode          */
#define XF86XK_AudioRandomPlay	0x1008FF99   /* toggle shuffle mode         */
#define XF86XK_Subtitle		0x1008FF9A   /* cycle through subtitle      */
#define XF86XK_AudioCycleTrack	0x1008FF9B   /* cycle through audio tracks  */
#define XF86XK_CycleAngle	0x1008FF9C   /* cycle through angles        */
#define XF86XK_FrameBack	0x1008FF9D   /* video: go one frame back    */
#define XF86XK_FrameForward	0x1008FF9E   /* video: go one frame forward */
#define XF86XK_Time		0x1008FF9F   /* display, or shows an entry for time seeking */
#define XF86XK_Select		0x1008FFA0   /* Select button on joypads and remotes */
#define XF86XK_View		0x1008FFA1   /* Show a view options/properties */
#define XF86XK_TopMenu		0x1008FFA2   /* Go to a top-level menu in a video */

#define XF86XK_Red		0x1008FFA3   /* Red button                  */
#define XF86XK_Green		0x1008FFA4   /* Green button                */
#define XF86XK_Yellow		0x1008FFA5   /* Yellow button               */
#define XF86XK_Blue             0x1008FFA6   /* Blue button                 */

#define XF86XK_Suspend		0x1008FFA7   /* Sleep to RAM                */
#define XF86XK_Hibernate	0x1008FFA8   /* Sleep to disk               */
#define XF86XK_TouchpadToggle	0x1008FFA9   /* Toggle between touchpad/trackstick */
#define XF86XK_TouchpadOn	0x1008FFB0   /* The touchpad got switched on */
#define XF86XK_TouchpadOff	0x1008FFB1   /* The touchpad got switched off */

#define XF86XK_AudioMicMute	0x1008FFB2   /* Mute the Mic from the system */

#define XF86XK_Keyboard		0x1008FFB3   /* User defined keyboard related action */

#define XF86XK_WWAN		0x1008FFB4   /* Toggle WWAN (LTE, UMTS, etc.) radio */
#define XF86XK_RFKill		0x1008FFB5   /* Toggle radios on/off */

#define XF86XK_AudioPreset	0x1008FFB6   /* Select equalizer preset, e.g. theatre-mode */

#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */

/* Keys for special action keys (hot keys) */
/* Virtual terminals on some operating systems */
#define XF86XK_Switch_VT_1	0x1008FE01
#define XF86XK_Switch_VT_2	0x1008FE02
#define XF86XK_Switch_VT_3	0x1008FE03
#define XF86XK_Switch_VT_4	0x1008FE04
#define XF86XK_Switch_VT_5	0x1008FE05
#define XF86XK_Switch_VT_6	0x1008FE06
#define XF86XK_Switch_VT_7	0x1008FE07
#define XF86XK_Switch_VT_8	0x1008FE08
#define XF86XK_Switch_VT_9	0x1008FE09
#define XF86XK_Switch_VT_10	0x1008FE0A
#define XF86XK_Switch_VT_11	0x1008FE0B
#define XF86XK_Switch_VT_12	0x1008FE0C

#define XF86XK_Ungrab		0x1008FE20   /* force ungrab               */
#define XF86XK_ClearGrab	0x1008FE21   /* kill application with grab */
#define XF86XK_Next_VMode	0x1008FE22   /* next video mode available  */
#define XF86XK_Prev_VMode	0x1008FE23   /* prev. video mode available */
#define XF86XK_LogWindowTree	0x1008FE24   /* print window tree to log   */
#define XF86XK_LogGrabInfo	0x1008FE25   /* print all active grabs to log */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































Changes to xlib/X11/Xfuncproto.h.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

/*
 *
Copyright 1989, 1991, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
 *
 */

/* Definitions to make function prototypes manageable */

#ifndef _XFUNCPROTO_H_
#define _XFUNCPROTO_H_

#ifndef NeedFunctionPrototypes
#define NeedFunctionPrototypes 1
#endif /* NeedFunctionPrototypes */

#ifndef NeedVarargsPrototypes
#define NeedVarargsPrototypes 1
#endif /* NeedVarargsPrototypes */

#if NeedFunctionPrototypes

#ifndef NeedNestedPrototypes
#define NeedNestedPrototypes 1
#endif /* NeedNestedPrototypes */

#ifndef _Xconst
#define _Xconst const
#endif /* _Xconst */

/* Function prototype configuration (see configure for more info) */
#if !defined(NARROWPROTO) && \
    (defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__))
#define NARROWPROTO
#endif
#ifndef FUNCPROTO
#define FUNCPROTO 15
#endif

#ifndef NeedWidePrototypes
#ifdef NARROWPROTO
#define NeedWidePrototypes 0
#else
#define NeedWidePrototypes 1		/* default to make interropt. easier */
#endif
#endif /* NeedWidePrototypes */

#endif /* NeedFunctionPrototypes */

#ifndef _XFUNCPROTOBEGIN
#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
#define _XFUNCPROTOBEGIN extern "C" {	/* do not leave open across includes */
#define _XFUNCPROTOEND }
#else


#define _XFUNCPROTOBEGIN
#define _XFUNCPROTOEND
#endif
#endif /* _XFUNCPROTOBEGIN */

/* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */
#ifndef __has_attribute
# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
#endif
#ifndef __has_feature
# define __has_feature(x) 0    /* Compatibility with non-clang compilers. */
#endif
#ifndef __has_extension
# define __has_extension(x) 0  /* Compatibility with non-clang compilers. */
#endif

/* Added in X11R6.9, so available in any version of modular xproto */
#if __has_attribute(__sentinel__) || (defined(__GNUC__) && (__GNUC__ >= 4))
# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x)))
#else
# define _X_SENTINEL(x)
#endif /* GNUC >= 4 */

/* Added in X11R6.9, so available in any version of modular xproto */
#if (__has_attribute(visibility) || (defined(__GNUC__) && (__GNUC__ >= 4))) \
    && !defined(__CYGWIN__) && !defined(__MINGW32__)
# define _X_EXPORT      __attribute__((visibility("default")))
# define _X_HIDDEN      __attribute__((visibility("hidden")))
# define _X_INTERNAL    __attribute__((visibility("internal")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define _X_EXPORT      __global
# define _X_HIDDEN      __hidden
# define _X_INTERNAL    __hidden
#else /* not gcc >= 4 and not Sun Studio >= 8 */
# define _X_EXPORT
# define _X_HIDDEN
# define _X_INTERNAL
#endif /* GNUC >= 4 */

/* Branch prediction hints for individual conditionals */
/* requires xproto >= 7.0.9 */
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
# define _X_LIKELY(x)   __builtin_expect(!!(x), 1)
# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else /* not gcc >= 3.3 */
# define _X_LIKELY(x)   (x)
# define _X_UNLIKELY(x) (x)
#endif

/* Bulk branch prediction hints via marking error path functions as "cold" */
/* requires xproto >= 7.0.25 */
#if __has_attribute(__cold__) || \
    (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) /* 4.3+ */
# define _X_COLD __attribute__((__cold__))
#else
# define _X_COLD /* nothing */
#endif

/* Added in X11R6.9, so available in any version of modular xproto */
#if __has_attribute(deprecated) \
    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
# define _X_DEPRECATED  __attribute__((deprecated))
#else /* not gcc >= 3.1 */
# define _X_DEPRECATED
#endif

/* requires xproto >= 7.0.30 */
#if __has_extension(attribute_deprecated_with_message) || \
                (defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))))
# define _X_DEPRECATED_MSG(_msg) __attribute__((deprecated(_msg)))
#else
# define _X_DEPRECATED_MSG(_msg) _X_DEPRECATED
#endif

/* requires xproto >= 7.0.17 */
#if __has_attribute(noreturn) \
    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define _X_NORETURN __attribute((noreturn))
#else
# define _X_NORETURN
#endif /* GNUC  */

/* Added in X11R6.9, so available in any version of modular xproto */
#if __has_attribute(__format__) \
    || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
#else /* not gcc >= 2.3 */
# define _X_ATTRIBUTE_PRINTF(x,y)
#endif

/* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable
   argument macros, must be only used inside #ifdef _X_NONNULL guards, as
   many legacy X clients are compiled in C89 mode still. */
#if __has_attribute(nonnull) \
    && defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
#define _X_NONNULL(...)  __attribute__((nonnull(__VA_ARGS__)))
#elif __has_attribute(nonnull) \
    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
#define _X_NONNULL(args...)  __attribute__((nonnull(args)))
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
#define _X_NONNULL(...)  /* */
#endif

/* requires xproto >= 7.0.22 */
#if __has_attribute(__unused__) \
    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)
#define _X_UNUSED  __attribute__((__unused__))
#else
#define _X_UNUSED  /* */
#endif

/* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */
/* requires xproto >= 7.0.9
   (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */
#if defined(inline) /* assume autoconf set it correctly */ || \
   (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \
   (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550))
# define _X_INLINE inline
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
# define _X_INLINE __inline__
#else
# define _X_INLINE
#endif

/* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */
/* requires xproto >= 7.0.21 */
#ifndef _X_RESTRICT_KYWD
# if defined(restrict) /* assume autoconf set it correctly */ || \
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \
     && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */
#  define _X_RESTRICT_KYWD  restrict
# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
#  define _X_RESTRICT_KYWD __restrict__
# else
#  define _X_RESTRICT_KYWD
# endif
#endif

/* requires xproto >= 7.0.30 */
#if __has_attribute(no_sanitize_thread)
# define _X_NOTSAN __attribute__((no_sanitize_thread))
#else
# define _X_NOTSAN
#endif

#endif /* _XFUNCPROTO_H_ */
>

<
|
|
|
|
|
|
|
|
<
<
|
<
<
<
<
<
<
|
<
<
|













|












<
<
<
<
<
<
<
<
<










<
|
|

|
>
>


<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

1
2

3
4
5
6
7
8
9
10


11






12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39









40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59














































































































































60
/* $XConsortium: Xfuncproto.h,v 1.7 91/05/13 20:49:21 rws Exp $ */
/*

 * Copyright 1989, 1991 by the Massachusetts Institute of Technology
 *
 * 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, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,


 * written prior permission. M.I.T. makes no representations about the






 * suitability of this software for any purpose.  It is provided "as is"


 * without express or implied warranty.
 *
 */

/* Definitions to make function prototypes manageable */

#ifndef _XFUNCPROTO_H_
#define _XFUNCPROTO_H_

#ifndef NeedFunctionPrototypes
#define NeedFunctionPrototypes 1
#endif /* NeedFunctionPrototypes */

#ifndef NeedVarargsPrototypes
#define NeedVarargsPrototypes 0
#endif /* NeedVarargsPrototypes */

#if NeedFunctionPrototypes

#ifndef NeedNestedPrototypes
#define NeedNestedPrototypes 1
#endif /* NeedNestedPrototypes */

#ifndef _Xconst
#define _Xconst const
#endif /* _Xconst */










#ifndef NeedWidePrototypes
#ifdef NARROWPROTO
#define NeedWidePrototypes 0
#else
#define NeedWidePrototypes 1		/* default to make interropt. easier */
#endif
#endif /* NeedWidePrototypes */

#endif /* NeedFunctionPrototypes */


#ifdef __cplusplus
#define _XFUNCPROTOBEGIN extern "C" {
#define _XFUNCPROTOEND }
#endif

#ifndef _XFUNCPROTOBEGIN
#define _XFUNCPROTOBEGIN
#define _XFUNCPROTOEND

#endif /* _XFUNCPROTOBEGIN */















































































































































#endif /* _XFUNCPROTO_H_ */

Changes to xlib/X11/Xlib.h.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44



45
46
47






48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

/*

Copyright 1985, 1986, 1987, 1991, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.


*/


/*
 *	Xlib.h - Header definition and support file for the C subroutine
 *	interface library (Xlib) to the X Window System Protocol (V11).
 *	Structures and symbols starting with "_" are private to the library.
 */
#ifndef _X11_XLIB_H_
#define _X11_XLIB_H_

#define XlibSpecificationRelease 6

#include <sys/types.h>

#if defined(__SCO__) || defined(__UNIXWARE__)
#include <stdint.h>
#endif

#include <X11/X.h>




/* applications should not depend on these two headers being included! */
#include <X11/Xfuncproto.h>







#ifndef X_WCHAR
#include <stddef.h>
#else
#ifdef __UNIXOS2__
#include <stdlib.h>
#else
/* replace this with #include or typedef appropriate for your system */
typedef unsigned long wchar_t;
#endif
#endif

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif
#if defined(STATIC_BUILD) || !defined(_WIN32)
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS
# endif
#elif defined(BUILD_tk)
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS __declspec(dllexport)
#elif !defined(TCL_STORAGE_CLASS)
# define TCL_STORAGE_CLASS __declspec(dllimport)
#endif

EXTERN int
_Xmblen(
    char *str,
    int len
    );

/* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in
   November 2000. Its presence is indicated through the following macro. */
#define X_HAVE_UTF8_STRING 1

/* The Xlib structs are full of implicit padding to properly align members.
   We can't clean that up without breaking ABI, so tell clang not to bother
   complaining about it. */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

typedef char *XPointer;

#define Bool int
#if defined(MAC_OSX_TK)
/* Use define rather than typedef, since may need to undefine this later */
#define Status int
>

<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
|
<
<
<
>
|
|







|
|

|

<
|
<
|

|
|
>
>
>



>
>
>
>
>
>




<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2

3
4
5
6
7
8
9
10
11
12
13






14



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50



51
52
53

































54
55
56
57
58
59
60
/* $XConsortium: Xlib.h,v 11.221 93/07/02 14:13:28 gildea Exp $ */
/*

 * Copyright 1985, 1986, 1987, 1991 by the Massachusetts Institute of Technology
 *
 * 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, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission. M.I.T. makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.






 *



 * X Window System is a Trademark of MIT.
 *
 */


/*
 *	Xlib.h - Header definition and support file for the C subroutine
 *	interface library (Xlib) to the X Window System Protocol (V11).
 *	Structures and symbols starting with "_" are private to the library.
 */
#ifndef _XLIB_H_
#define _XLIB_H_

#define XlibSpecificationRelease 5


#if !defined(MAC_OSX_TK)

#   include <X11/X.h>
#endif
#ifdef MAC_OSX_TK
#   include <X11/X.h>
#   define Cursor XCursor
#   define Region XRegion
#endif

/* applications should not depend on these two headers being included! */
#include <X11/Xfuncproto.h>

#ifndef X_WCHAR
#ifdef X_NOT_STDC_ENV
#define X_WCHAR
#endif
#endif

#ifndef X_WCHAR
#include <stddef.h>
#else



/* replace this with #include or typedef appropriate for your system */
typedef unsigned long wchar_t;
#endif


































typedef char *XPointer;

#define Bool int
#if defined(MAC_OSX_TK)
/* Use define rather than typedef, since may need to undefine this later */
#define Status int
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

/*
 * Extensions need a way to hang private data on some structures.
 */
typedef struct _XExtData {
	int number;		/* number returned by XRegisterExtension */
	struct _XExtData *next;	/* next item on list of data for structure */
	int (*free_private)(	/* called to free private storage */
	struct _XExtData *extension
	);
	XPointer private_data;	/* data private to this extension. */
} XExtData;

/*
 * This file contains structures used by the extension mechanism.
 */
typedef struct {		/* public to extension, cannot be changed */







|
<
<







124
125
126
127
128
129
130
131


132
133
134
135
136
137
138

/*
 * Extensions need a way to hang private data on some structures.
 */
typedef struct _XExtData {
	int number;		/* number returned by XRegisterExtension */
	struct _XExtData *next;	/* next item on list of data for structure */
	int (*free_private)();	/* called to free private storage */


	XPointer private_data;	/* data private to this extension. */
} XExtData;

/*
 * This file contains structures used by the extension mechanism.
 */
typedef struct {		/* public to extension, cannot be changed */
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
} Depth;

/*
 * Information about the screen.  The contents of this structure are
 * implementation dependent.  A Screen should be treated as opaque
 * by application code.
 */

struct _XDisplay;		/* Forward declare before use for C++ */

typedef struct {
	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XDisplay *display;/* back pointer to display structure */
	Window root;		/* Root window id. */
	int width, height;	/* width and height of screen */
	int mwidth, mheight;	/* width and height of  in millimeters */
	int ndepths;		/* number of depths possible */







<
<
<







217
218
219
220
221
222
223



224
225
226
227
228
229
230
} Depth;

/*
 * Information about the screen.  The contents of this structure are
 * implementation dependent.  A Screen should be treated as opaque
 * by application code.
 */



typedef struct {
	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XDisplay *display;/* back pointer to display structure */
	Window root;		/* Root window id. */
	int width, height;	/* width and height of screen */
	int mwidth, mheight;	/* width and height of  in millimeters */
	int ndepths;		/* number of depths possible */
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401







402
403
404
405
406
407
408

typedef struct {
	int family;		/* for example FamilyInternet */
	int length;		/* length of address, in bytes */
	char *address;		/* pointer to where to find the bytes */
} XHostAddress;

/*
 * Data structure for ServerFamilyInterpreted addresses in host routines
 */
typedef struct {
	int typelength;		/* length of type string, in bytes */
	int valuelength;	/* length of value string, in bytes */
	char *type;		/* pointer to where to find the type string */
	char *value;		/* pointer to where to find the address */
} XServerInterpretedAddress;

/*
 * Data structure for "image" data, used by image manipulation routines.
 */
typedef struct _XImage {
    int width, height;		/* size of image */
    int xoffset;		/* number of pixels offset in X direction */
    int format;			/* XYBitmap, XYPixmap, ZPixmap */
    char *data;			/* pointer to image data */
    int byte_order;		/* data byte order, LSBFirst, MSBFirst */
    int bitmap_unit;		/* quant. of scanline 8, 16, 32 */
    int bitmap_bit_order;	/* LSBFirst, MSBFirst */
    int bitmap_pad;		/* 8, 16, 32 either XY or ZPixmap */
    int depth;			/* depth of image */
    int bytes_per_line;		/* accelarator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)(
		struct _XDisplay* /* display */,
		Visual*		/* visual */,
		unsigned int	/* depth */,
		int		/* format */,
		int		/* offset */,
		char*		/* data */,
		unsigned int	/* width */,
		unsigned int	/* height */,
		int		/* bitmap_pad */,
		int		/* bytes_per_line */);
	int (*destroy_image)        (struct _XImage *);
	unsigned long (*get_pixel)  (struct _XImage *, int, int);
	int (*put_pixel)            (struct _XImage *, int, int, unsigned long);
	struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int);
	int (*add_pixel)            (struct _XImage *, long);







	} f;
} XImage;

/*
 * Data structure for XReconfigureWindow
 */
typedef struct {







<
<
<
<
<
<
<
<
<
<




















|
|
<
<
<
<
<
<
<
<
<





>
>
>
>
>
>
>







307
308
309
310
311
312
313










314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335









336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

typedef struct {
	int family;		/* for example FamilyInternet */
	int length;		/* length of address, in bytes */
	char *address;		/* pointer to where to find the bytes */
} XHostAddress;











/*
 * Data structure for "image" data, used by image manipulation routines.
 */
typedef struct _XImage {
    int width, height;		/* size of image */
    int xoffset;		/* number of pixels offset in X direction */
    int format;			/* XYBitmap, XYPixmap, ZPixmap */
    char *data;			/* pointer to image data */
    int byte_order;		/* data byte order, LSBFirst, MSBFirst */
    int bitmap_unit;		/* quant. of scanline 8, 16, 32 */
    int bitmap_bit_order;	/* LSBFirst, MSBFirst */
    int bitmap_pad;		/* 8, 16, 32 either XY or ZPixmap */
    int depth;			/* depth of image */
    int bytes_per_line;		/* accelarator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)();
#if NeedFunctionPrototypes









	int (*destroy_image)        (struct _XImage *);
	unsigned long (*get_pixel)  (struct _XImage *, int, int);
	int (*put_pixel)            (struct _XImage *, int, int, unsigned long);
	struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int);
	int (*add_pixel)            (struct _XImage *, long);
#else
	int (*destroy_image)();
	unsigned long (*get_pixel)();
	int (*put_pixel)();
	struct _XImage *(*sub_image)();
	int (*add_pixel)();
#endif
	} f;
} XImage;

/*
 * Data structure for XReconfigureWindow
 */
typedef struct {
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607



608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
/*
 * Display datatype maintaining display specific data.
 * The contents of this structure are implementation dependent.
 * A Display should be treated as opaque by application code.
 */
typedef struct _XDisplay {
	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XPrivate *private1;
	int fd;			/* Network socket. */
	int private2;
	int proto_major_version;/* major version of server's X protocol */
	int proto_minor_version;/* minor version of servers X protocol */
	char *vendor;		/* vendor of the server hardware */
        XID private3;
	XID private4;
	XID private5;
	int private6;
	XID (*resource_alloc)(	/* allocator function */
		struct _XDisplay*
	);
	int byte_order;		/* screen byte order, LSBFirst, MSBFirst */
	int bitmap_unit;	/* padding and data requirements */
	int bitmap_pad;		/* padding requirements on bitmaps */
	int bitmap_bit_order;	/* LeastSignificant or MostSignificant */
	int nformats;		/* number of pixmap formats in list */
	ScreenFormat *pixmap_format;	/* pixmap format list */
	int private8;
	int release;		/* release of the server */
	struct _XPrivate *private9, *private10;
	int qlen;		/* Length of input event queue */
	unsigned long last_request_read; /* seq number of last event read */
	unsigned long request;	/* sequence number of last request. */

	XPointer private11;
	XPointer private12;
	XPointer private13;
	XPointer private14;
	unsigned max_request_size; /* maximum number 32 bit words in request*/
	struct _XrmHashBucketRec *db;
	int (*private15)(
		struct _XDisplay*
		);
	char *display_name;	/* "host:display" string used on this connect*/
	int default_screen;	/* default screen for operations */
	int nscreens;		/* number of screens on this server*/
	Screen *screens;	/* pointer to list of screens */
	unsigned long motion_buffer;	/* size of motion buffer */
	unsigned long private16;
	int min_keycode;	/* minimum defined keycode */
	int max_keycode;	/* maximum defined keycode */
	XPointer private17;
	XPointer private18;
	int private19;
	char *xdefaults;	/* contents of defaults from server */
	char *scratch_buffer;	/* place to hang scratch buffer */
	unsigned long scratch_length;	/* length of scratch buffer */
	int ext_number;		/* extension number on this display */
	struct _XExten *ext_procs; /* extensions initialized on this display */
	/*
	 * the following can be fixed size, as the protocol defines how
	 * much address space is available.
	 * While this could be done using the extension vector, there
	 * may be MANY events processed, so a search through the extension
	 * list to find the right procedure for each event might be
	 * expensive if many extensions are being used.
	 */
	Bool (*event_vec[128])(void);  /* vector for wire to event */
	Status (*wire_vec[128])(void); /* vector for event to wire */
	KeySym lock_meaning;	   /* for XLookupString */
	struct _XLockInfo *lock;   /* multi-thread state, display lock */
	struct _XInternalAsync *async_handlers; /* for internal async */
	unsigned long bigreq_size; /* max size of big requests */
	struct _XLockPtrs *lock_fns; /* pointers to threads functions */
	/* things above this line should not move, for binary compatibility */
	struct _XKeytrans *key_bindings; /* for XLookupString */
	Font cursor_font;	   /* for XCreateFontCursor */
	struct _XDisplayAtoms *atoms; /* for XInternAtom */
	unsigned int mode_switch;  /* keyboard group modifiers */
	struct _XContextDB *context_db; /* context database */
	Bool (**error_vec)(void);      /* vector for wire to error */
	/*
	 * Xcms information
	 */
	struct {
	   XPointer defaultCCCs;  /* pointer to an array of default XcmsCCC */
	   XPointer clientCmaps;  /* pointer to linked list of XcmsCmapRec */
	   XPointer perVisualIntensityMaps;
				  /* linked list of XcmsIntensityMap */
	} cms;
	struct _XIMFilter *im_filters;
	struct _XSQEvent *qfree; /* unallocated event queue elements */
	unsigned long next_event_serial_num; /* inserted into next queue elt */
	int (*savedsynchandler)(void); /* user synchandler when Xlib usurps */
} Display;

#if NeedFunctionPrototypes	/* prototypes require event type definitions */
#undef _XEVENT_
#endif
#ifndef _XEVENT_

#define XMaxTransChars 7

/*
 * Definitions of specific events.
 */
typedef struct {
	int type;		/* of event */
	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;	        /* "event" window it is reported relative to */
	Window root;	        /* root window that the event occurred 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 */
	unsigned int keycode;	/* detail */
	Bool same_screen;	/* same screen flag */



} XKeyEvent;
typedef XKeyEvent XKeyPressedEvent;
typedef XKeyEvent XKeyReleasedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window it is reported relative to */
	Window root;	        /* root window that the event occurred 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 */
	unsigned int button;	/* detail */
	Bool same_screen;	/* same screen flag */
} XButtonEvent;
typedef XButtonEvent XButtonPressedEvent;
typedef XButtonEvent XButtonReleasedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window reported relative to */
	Window root;	        /* root window that the event occurred 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 */
	char is_hint;		/* detail */
	Bool same_screen;	/* same screen flag */
} XMotionEvent;
typedef XMotionEvent XPointerMovedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window reported relative to */
	Window root;	        /* root window that the event occurred 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 */
	int mode;		/* NotifyNormal, NotifyGrab, NotifyUngrab */
	int detail;
	/*







|

|
|


|
|
|
|
|
<
<






|

|

<

>
|
|
|
<


|
<
<





|


|
|
|













|
|











|












|







|










|







>
>
>










|

















|
















|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453


454
455
456
457
458
459
460
461
462
463

464
465
466
467
468

469
470
471


472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
/*
 * Display datatype maintaining display specific data.
 * The contents of this structure are implementation dependent.
 * A Display should be treated as opaque by application code.
 */
typedef struct _XDisplay {
	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XFreeFuncs *free_funcs; /* internal free functions */
	int fd;			/* Network socket. */
	int conn_checker;         /* ugly thing used by _XEventsQueued */
	int proto_major_version;/* maj. version of server's X protocol */
	int proto_minor_version;/* minor version of servers X protocol */
	char *vendor;		/* vendor of the server hardware */
        XID resource_base;	/* resource ID base */
	XID resource_mask;	/* resource ID mask bits */
	XID resource_id;	/* allocator current ID */
	int resource_shift;	/* allocator shift to correct bits */
	XID (*resource_alloc)(); /* allocator function */


	int byte_order;		/* screen byte order, LSBFirst, MSBFirst */
	int bitmap_unit;	/* padding and data requirements */
	int bitmap_pad;		/* padding requirements on bitmaps */
	int bitmap_bit_order;	/* LeastSignificant or MostSignificant */
	int nformats;		/* number of pixmap formats in list */
	ScreenFormat *pixmap_format;	/* pixmap format list */
	int vnumber;		/* Xlib's X protocol version number. */
	int release;		/* release of the server */
	struct _XSQEvent *head, *tail;	/* Input event queue. */
	int qlen;		/* Length of input event queue */

	unsigned long request;	/* sequence number of last request. */
	char *last_req;		/* beginning of last request, or dummy */
	char *buffer;		/* Output buffer starting address. */
	char *bufptr;		/* Output buffer index pointer. */
	char *bufmax;		/* Output buffer maximum+1 address. */

	unsigned max_request_size; /* maximum number 32 bit words in request*/
	struct _XrmHashBucketRec *db;
	int (*synchandler)();	/* Synchronization handler */


	char *display_name;	/* "host:display" string used on this connect*/
	int default_screen;	/* default screen for operations */
	int nscreens;		/* number of screens on this server*/
	Screen *screens;	/* pointer to list of screens */
	unsigned long motion_buffer;	/* size of motion buffer */
	unsigned long flags;	/* internal connection flags */
	int min_keycode;	/* minimum defined keycode */
	int max_keycode;	/* maximum defined keycode */
	KeySym *keysyms;	/* This server's keysyms */
	XModifierKeymap *modifiermap;	/* This server's modifier keymap */
	int keysyms_per_keycode;/* number of rows */
	char *xdefaults;	/* contents of defaults from server */
	char *scratch_buffer;	/* place to hang scratch buffer */
	unsigned long scratch_length;	/* length of scratch buffer */
	int ext_number;		/* extension number on this display */
	struct _XExten *ext_procs; /* extensions initialized on this display */
	/*
	 * the following can be fixed size, as the protocol defines how
	 * much address space is available.
	 * While this could be done using the extension vector, there
	 * may be MANY events processed, so a search through the extension
	 * list to find the right procedure for each event might be
	 * expensive if many extensions are being used.
	 */
	Bool (*event_vec[128])();  /* vector for wire to event */
	Status (*wire_vec[128])(); /* vector for event to wire */
	KeySym lock_meaning;	   /* for XLookupString */
	struct _XLockInfo *lock;   /* multi-thread state, display lock */
	struct _XInternalAsync *async_handlers; /* for internal async */
	unsigned long bigreq_size; /* max size of big requests */
	struct _XLockPtrs *lock_fns; /* pointers to threads functions */
	/* things above this line should not move, for binary compatibility */
	struct _XKeytrans *key_bindings; /* for XLookupString */
	Font cursor_font;	   /* for XCreateFontCursor */
	struct _XDisplayAtoms *atoms; /* for XInternAtom */
	unsigned int mode_switch;  /* keyboard group modifiers */
	struct _XContextDB *context_db; /* context database */
	Bool (**error_vec)();      /* vector for wire to error */
	/*
	 * Xcms information
	 */
	struct {
	   XPointer defaultCCCs;  /* pointer to an array of default XcmsCCC */
	   XPointer clientCmaps;  /* pointer to linked list of XcmsCmapRec */
	   XPointer perVisualIntensityMaps;
				  /* linked list of XcmsIntensityMap */
	} cms;
	struct _XIMFilter *im_filters;
	struct _XSQEvent *qfree; /* unallocated event queue elements */
	unsigned long next_event_serial_num; /* inserted into next queue elt */
	int (*savedsynchandler)(); /* user synchandler when Xlib usurps */
} Display;

#if NeedFunctionPrototypes	/* prototypes require event type definitions */
#undef _XEVENT_
#endif
#ifndef _XEVENT_

#define XMaxTransChars 4

/*
 * Definitions of specific events.
 */
typedef struct {
	int type;		/* of event */
	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;	        /* "event" window it is reported relative to */
	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 */
	unsigned int keycode;	/* detail */
	Bool same_screen;	/* same screen flag */
        char trans_chars[XMaxTransChars];
				/* translated characters */
	int nbytes;
} XKeyEvent;
typedef XKeyEvent XKeyPressedEvent;
typedef XKeyEvent XKeyReleasedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window it is reported relative to */
	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 */
	unsigned int button;	/* detail */
	Bool same_screen;	/* same screen flag */
} XButtonEvent;
typedef XButtonEvent XButtonPressedEvent;
typedef XButtonEvent XButtonReleasedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window reported relative to */
	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 */
	char is_hint;		/* detail */
	Bool same_screen;	/* same screen flag */
} XMotionEvent;
typedef XMotionEvent XPointerMovedEvent;

typedef struct {
	int type;		/* of event */
	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;	        /* "event" window reported relative to */
	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 */
	int mode;		/* NotifyNormal, NotifyGrab, NotifyUngrab */
	int detail;
	/*
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

typedef struct {
	int type;		/* FocusIn or FocusOut */
	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 of event */
	int mode;		/* NotifyNormal, NotifyWhileGrabbed,
				   NotifyGrab, NotifyUngrab */
	int detail;
	/*
	 * NotifyAncestor, NotifyVirtual, NotifyInferior,
	 * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer,
	 * NotifyPointerRoot, NotifyDetailNone
	 */
} XFocusChangeEvent;







|
<







614
615
616
617
618
619
620
621

622
623
624
625
626
627
628

typedef struct {
	int type;		/* FocusIn or FocusOut */
	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 of event */
	int mode;		/* NotifyNormal, NotifyGrab, NotifyUngrab */

	int detail;
	/*
	 * NotifyAncestor, NotifyVirtual, NotifyInferior,
	 * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer,
	 * NotifyPointerRoot, NotifyDetailNone
	 */
} XFocusChangeEvent;
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
	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 on which event was requested in event mask */
} XAnyEvent;


/***************************************************************
 *
 * GenericEvent.  This event is the standard event for all newer extensions.
 */

typedef struct
    {
    int            type;         /* of event. Always GenericEvent */
    unsigned long  serial;       /* # of last request processed */
    Bool           send_event;   /* true if from SendEvent request */
    Display        *display;     /* Display the event was read from */
    int            extension;    /* major opcode of extension that caused the event */
    int            evtype;       /* actual event type. */
    } XGenericEvent;

typedef struct {
    int            type;         /* of event. Always GenericEvent */
    unsigned long  serial;       /* # of last request processed */
    Bool           send_event;   /* true if from SendEvent request */
    Display        *display;     /* Display the event was read from */
    int            extension;    /* major opcode of extension that caused the event */
    int            evtype;       /* actual event type. */
    unsigned int   cookie;
    void           *data;
} XGenericEventCookie;

/*
 * this union is defined so Xlib can always use the same sized
 * event structure internally, to avoid memory fragmentation.
 */
typedef union _XEvent {
        int type;		/* must not be changed; first element */
	XAnyEvent xany;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







915
916
917
918
919
920
921



























922
923
924
925
926
927
928
	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 on which event was requested in event mask */
} XAnyEvent;




























/*
 * this union is defined so Xlib can always use the same sized
 * event structure internally, to avoid memory fragmentation.
 */
typedef union _XEvent {
        int type;		/* must not be changed; first element */
	XAnyEvent xany;
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
	XSelectionRequestEvent xselectionrequest;
	XSelectionEvent xselection;
	XColormapEvent xcolormap;
	XClientMessageEvent xclient;
	XMappingEvent xmapping;
	XErrorEvent xerror;
	XKeymapEvent xkeymap;
	XGenericEvent xgeneric;
	XGenericEventCookie xcookie;
	XID pad[24];
} XEvent;
#endif

#define XAllocID(dpy) ((*(dpy)->resource_alloc)((dpy)))

/*







<
<







952
953
954
955
956
957
958


959
960
961
962
963
964
965
	XSelectionRequestEvent xselectionrequest;
	XSelectionEvent xselection;
	XColormapEvent xcolormap;
	XClientMessageEvent xclient;
	XMappingEvent xmapping;
	XErrorEvent xerror;
	XKeymapEvent xkeymap;


	XID pad[24];
} XEvent;
#endif

#define XAllocID(dpy) ((*(dpy)->resource_alloc)((dpy)))

/*
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270



1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
		XFontStruct *font; } XEDataObject;

typedef struct {
    XRectangle      max_ink_extent;
    XRectangle      max_logical_extent;
} XFontSetExtents;

/* unused:
typedef void (*XOMProc)();
 */

typedef struct _XOM *XOM;
typedef struct _XOC *XOC, *XFontSet;

typedef struct {
    char           *chars;
    int             nchars;
    int             delta;
    XFontSet        font_set;
} XmbTextItem;

typedef struct {
    wchar_t        *chars;
    int             nchars;
    int             delta;
    XFontSet        font_set;
} XwcTextItem;

#define XNRequiredCharSet "requiredCharSet"
#define XNQueryOrientation "queryOrientation"
#define XNBaseFontName "baseFontName"
#define XNOMAutomatic "omAutomatic"
#define XNMissingCharSet "missingCharSet"
#define XNDefaultString "defaultString"
#define XNOrientation "orientation"
#define XNDirectionalDependentDrawing "directionalDependentDrawing"
#define XNContextualDrawing "contextualDrawing"
#define XNFontInfo "fontInfo"

typedef struct {
    int charset_count;
    char **charset_list;
} XOMCharSetList;

typedef enum {
    XOMOrientation_LTR_TTB,
    XOMOrientation_RTL_TTB,
    XOMOrientation_TTB_LTR,
    XOMOrientation_TTB_RTL,
    XOMOrientation_Context
} XOrientation;

typedef struct {
    int num_orientation;
    XOrientation *orientation;	/* Input Text description */
} XOMOrientation;

typedef struct {
    int num_font;
    XFontStruct **font_struct_list;
    char **font_name_list;
} XOMFontInfo;

typedef struct _XIM *XIM;
typedef struct _XIC *XIC;

typedef void (*XIMProc)(
    XIM,
    XPointer,
    XPointer
);

typedef Bool (*XICProc)(
    XIC,
    XPointer,
    XPointer
);

typedef void (*XIDProc)(
    Display*,
    XPointer,
    XPointer
);

typedef unsigned long XIMStyle;

typedef struct {
    unsigned short count_styles;
    XIMStyle *supported_styles;
} XIMStyles;

#define XIMPreeditArea		0x0001L
#define XIMPreeditCallbacks	0x0002L
#define XIMPreeditPosition	0x0004L
#define XIMPreeditNothing	0x0008L
#define XIMPreeditNone		0x0010L
#define XIMStatusArea		0x0100L
#define XIMStatusCallbacks	0x0200L
#define XIMStatusNothing	0x0400L
#define XIMStatusNone		0x0800L

#define XNVaNestedList "XNVaNestedList"
#define XNQueryInputStyle "queryInputStyle"
#define XNClientWindow "clientWindow"
#define XNInputStyle "inputStyle"
#define XNFocusWindow "focusWindow"
#define XNResourceName "resourceName"
#define XNResourceClass "resourceClass"
#define XNGeometryCallback "geometryCallback"
#define XNDestroyCallback "destroyCallback"
#define XNFilterEvents "filterEvents"
#define XNPreeditStartCallback "preeditStartCallback"
#define XNPreeditDoneCallback "preeditDoneCallback"
#define XNPreeditDrawCallback "preeditDrawCallback"
#define XNPreeditCaretCallback "preeditCaretCallback"
#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback"
#define XNPreeditAttributes "preeditAttributes"
#define XNStatusStartCallback "statusStartCallback"
#define XNStatusDoneCallback "statusDoneCallback"
#define XNStatusDrawCallback "statusDrawCallback"
#define XNStatusAttributes "statusAttributes"
#define XNArea "area"
#define XNAreaNeeded "areaNeeded"
#define XNSpotLocation "spotLocation"
#define XNColormap "colorMap"
#define XNStdColormap "stdColorMap"
#define XNForeground "foreground"
#define XNBackground "background"
#define XNBackgroundPixmap "backgroundPixmap"
#define XNFontSet "fontSet"
#define XNLineSpace "lineSpace"
#define XNCursor "cursor"

#define XNQueryIMValuesList "queryIMValuesList"
#define XNQueryICValuesList "queryICValuesList"
#define XNVisiblePosition "visiblePosition"
#define XNR6PreeditCallback "r6PreeditCallback"
#define XNStringConversionCallback "stringConversionCallback"
#define XNStringConversion "stringConversion"
#define XNResetState "resetState"
#define XNHotKey "hotKey"
#define XNHotKeyState "hotKeyState"
#define XNPreeditState "preeditState"
#define XNSeparatorofNestedList "separatorofNestedList"

#define XBufferOverflow		-1
#define XLookupNone		1
#define XLookupChars		2
#define XLookupKeySym		3
#define XLookupBoth		4


typedef void *XVaNestedList;




typedef struct {
    XPointer client_data;
    XIMProc callback;
} XIMCallback;

typedef struct {
    XPointer client_data;
    XICProc callback;
} XICCallback;

typedef unsigned long XIMFeedback;

#define XIMReverse		1L
#define XIMUnderline		(1L<<1)
#define XIMHighlight		(1L<<2)
#define XIMPrimary	 	(1L<<5)
#define XIMSecondary		(1L<<6)
#define XIMTertiary	 	(1L<<7)
#define XIMVisibleToForward 	(1L<<8)
#define XIMVisibleToBackword 	(1L<<9)
#define XIMVisibleToCenter 	(1L<<10)

typedef struct _XIMText {
    unsigned short length;
    XIMFeedback *feedback;
    Bool encoding_is_wchar;
    union {
	char *multi_byte;
	wchar_t *wide_char;
    } string;
} XIMText;

typedef	unsigned long	 XIMPreeditState;

#define	XIMPreeditUnKnown	0L
#define	XIMPreeditEnable	1L
#define	XIMPreeditDisable	(1L<<1)

typedef	struct	_XIMPreeditStateNotifyCallbackStruct {
    XIMPreeditState state;
} XIMPreeditStateNotifyCallbackStruct;

typedef	unsigned long	 XIMResetState;

#define	XIMInitialState		1L
#define	XIMPreserveState	(1L<<1)

typedef unsigned long XIMStringConversionFeedback;

#define	XIMStringConversionLeftEdge	(0x00000001)
#define	XIMStringConversionRightEdge	(0x00000002)
#define	XIMStringConversionTopEdge	(0x00000004)
#define	XIMStringConversionBottomEdge	(0x00000008)
#define	XIMStringConversionConcealed	(0x00000010)
#define	XIMStringConversionWrapped	(0x00000020)

typedef struct _XIMStringConversionText {
    unsigned short length;
    XIMStringConversionFeedback *feedback;
    Bool encoding_is_wchar;
    union {
	char *mbs;
	wchar_t *wcs;
    } string;
} XIMStringConversionText;

typedef	unsigned short	XIMStringConversionPosition;

typedef	unsigned short	XIMStringConversionType;

#define	XIMStringConversionBuffer	(0x0001)
#define	XIMStringConversionLine		(0x0002)
#define	XIMStringConversionWord		(0x0003)
#define	XIMStringConversionChar		(0x0004)

typedef	unsigned short	XIMStringConversionOperation;

#define	XIMStringConversionSubstitution	(0x0001)
#define	XIMStringConversionRetrieval	(0x0002)

typedef enum {
    XIMForwardChar, XIMBackwardChar,
    XIMForwardWord, XIMBackwardWord,
    XIMCaretUp, XIMCaretDown,
    XIMNextLine, XIMPreviousLine,
    XIMLineStart, XIMLineEnd,
    XIMAbsolutePosition,
    XIMDontChange
} XIMCaretDirection;

typedef struct _XIMStringConversionCallbackStruct {
    XIMStringConversionPosition position;
    XIMCaretDirection direction;
    XIMStringConversionOperation operation;
    unsigned short factor;
    XIMStringConversionText *text;
} XIMStringConversionCallbackStruct;

typedef struct _XIMPreeditDrawCallbackStruct {
    int caret;		/* Cursor offset within pre-edit string */
    int chg_first;	/* Starting change position */
    int chg_length;	/* Length of the change in character count */
    XIMText *text;
} XIMPreeditDrawCallbackStruct;

typedef enum {
    XIMIsInvisible,	/* Disable caret feedback */
    XIMIsPrimary,	/* UI defined caret feedback */
    XIMIsSecondary	/* UI defined caret feedback */
} XIMCaretStyle;

typedef struct _XIMPreeditCaretCallbackStruct {







<
<
<
<
|
<















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















<






<





<

















<
<
<
<
<
<
<
<
<
<
<
<






>

>
>
>






<
<
<
<
<


|
|
|
|
|
|
<
<
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
|
<
|
<
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1033
1034
1035
1036
1037
1038
1039




1040

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
















1056






1057











1058
1059
1060


















1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106












1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123





1124
1125
1126
1127
1128
1129
1130
1131



1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
























1143








1144

1145

1146




1147

1148


1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159















1160
1161
1162
1163
1164
1165
1166
		XFontStruct *font; } XEDataObject;

typedef struct {
    XRectangle      max_ink_extent;
    XRectangle      max_logical_extent;
} XFontSetExtents;





typedef struct _XFontSet *XFontSet;


typedef struct {
    char           *chars;
    int             nchars;
    int             delta;
    XFontSet        font_set;
} XmbTextItem;

typedef struct {
    wchar_t        *chars;
    int             nchars;
    int             delta;
    XFontSet        font_set;
} XwcTextItem;

















typedef void (*XIMProc)();


















typedef struct _XIM *XIM;
typedef struct _XIC *XIC;



















typedef unsigned long XIMStyle;

typedef struct {
    unsigned short count_styles;
    XIMStyle *supported_styles;
} XIMStyles;

#define XIMPreeditArea		0x0001L
#define XIMPreeditCallbacks	0x0002L
#define XIMPreeditPosition	0x0004L
#define XIMPreeditNothing	0x0008L
#define XIMPreeditNone		0x0010L
#define XIMStatusArea		0x0100L
#define XIMStatusCallbacks	0x0200L
#define XIMStatusNothing	0x0400L
#define XIMStatusNone		0x0800L

#define XNVaNestedList "XNVaNestedList"

#define XNClientWindow "clientWindow"
#define XNInputStyle "inputStyle"
#define XNFocusWindow "focusWindow"
#define XNResourceName "resourceName"
#define XNResourceClass "resourceClass"
#define XNGeometryCallback "geometryCallback"

#define XNFilterEvents "filterEvents"
#define XNPreeditStartCallback "preeditStartCallback"
#define XNPreeditDoneCallback "preeditDoneCallback"
#define XNPreeditDrawCallback "preeditDrawCallback"
#define XNPreeditCaretCallback "preeditCaretCallback"

#define XNPreeditAttributes "preeditAttributes"
#define XNStatusStartCallback "statusStartCallback"
#define XNStatusDoneCallback "statusDoneCallback"
#define XNStatusDrawCallback "statusDrawCallback"
#define XNStatusAttributes "statusAttributes"
#define XNArea "area"
#define XNAreaNeeded "areaNeeded"
#define XNSpotLocation "spotLocation"
#define XNColormap "colorMap"
#define XNStdColormap "stdColorMap"
#define XNForeground "foreground"
#define XNBackground "background"
#define XNBackgroundPixmap "backgroundPixmap"
#define XNFontSet "fontSet"
#define XNLineSpace "lineSpace"
#define XNCursor "cursor"













#define XBufferOverflow		-1
#define XLookupNone		1
#define XLookupChars		2
#define XLookupKeySym		3
#define XLookupBoth		4

#if NeedFunctionPrototypes
typedef void *XVaNestedList;
#else
typedef XPointer XVaNestedList;
#endif

typedef struct {
    XPointer client_data;
    XIMProc callback;
} XIMCallback;






typedef unsigned long XIMFeedback;

#define XIMReverse	1
#define XIMUnderline	(1<<1)
#define XIMHighlight	(1<<2)
#define XIMPrimary 	(1<<5)
#define XIMSecondary	(1<<6)
#define XIMTertiary 	(1<<7)




typedef struct _XIMText {
    unsigned short length;
    XIMFeedback *feedback;
    Bool encoding_is_wchar;
    union {
	char *multi_byte;
	wchar_t *wide_char;
    } string;
} XIMText;

























typedef struct _XIMPreeditDrawCallbackStruct {








    int caret;		/* Cursor offset within pre-edit string */

    int chg_first;	/* Starting change position */

    int chg_length;	/* Length of the change in character count */




    XIMText *text;

} XIMPreeditDrawCallbackStruct;



typedef enum {
    XIMForwardChar, XIMBackwardChar,
    XIMForwardWord, XIMBackwardWord,
    XIMCaretUp, XIMCaretDown,
    XIMNextLine, XIMPreviousLine,
    XIMLineStart, XIMLineEnd,
    XIMAbsolutePosition,
    XIMDontChange
} XIMCaretDirection;
















typedef enum {
    XIMIsInvisible,	/* Disable caret feedback */
    XIMIsPrimary,	/* UI defined caret feedback */
    XIMIsSecondary	/* UI defined caret feedback */
} XIMCaretStyle;

typedef struct _XIMPreeditCaretCallbackStruct {
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048



4049
4050
4051
4052
4053
    XIMStatusDataType type;
    union {
	XIMText *text;
	Pixmap  bitmap;
    } data;
} XIMStatusDrawCallbackStruct;

typedef struct _XIMHotKeyTrigger {
    KeySym	 keysym;
    int		 modifier;
    int		 modifier_mask;
} XIMHotKeyTrigger;

typedef struct _XIMHotKeyTriggers {
    int			 num_hot_key;
    XIMHotKeyTrigger	*key;
} XIMHotKeyTriggers;

typedef	unsigned long	 XIMHotKeyState;

#define	XIMHotKeyStateON	(0x0001L)
#define	XIMHotKeyStateOFF	(0x0002L)

typedef struct {
    unsigned short count_values;
    char **supported_values;
} XIMValuesList;

_XFUNCPROTOBEGIN

#if defined(WIN32) && !defined(_XLIBINT_)
#define _Xdebug *_Xdebug_p
#endif

EXTERN int _Xdebug;

EXTERN XFontStruct *XLoadQueryFont(
    Display*		/* display */,
    _Xconst char*	/* name */
);

EXTERN XFontStruct *XQueryFont(
    Display*		/* display */,
    XID			/* font_ID */
);


EXTERN XTimeCoord *XGetMotionEvents(
    Display*		/* display */,
    Window		/* w */,
    Time		/* start */,
    Time		/* stop */,
    int*		/* nevents_return */
);

EXTERN XModifierKeymap *XDeleteModifiermapEntry(
    XModifierKeymap*	/* modmap */,
#if NeedWidePrototypes
    unsigned int	/* keycode_entry */,
#else
    KeyCode		/* keycode_entry */,
#endif
    int			/* modifier */
);

EXTERN XModifierKeymap	*XGetModifierMapping(
    Display*		/* display */
);

EXTERN XModifierKeymap	*XInsertModifiermapEntry(
    XModifierKeymap*	/* modmap */,
#if NeedWidePrototypes
    unsigned int	/* keycode_entry */,
#else
    KeyCode		/* keycode_entry */,
#endif
    int			/* modifier */
);

EXTERN XModifierKeymap *XNewModifiermap(
    int			/* max_keys_per_mod */
);

EXTERN XImage *XCreateImage(
    Display*		/* display */,
    Visual*		/* visual */,
    unsigned int	/* depth */,
    int			/* format */,
    int			/* offset */,
    char*		/* data */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* bitmap_pad */,
    int			/* bytes_per_line */
);
EXTERN Status XInitImage(
    XImage*		/* image */
);
EXTERN XImage *XGetImage(
    Display*		/* display */,
    Drawable		/* d */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned long	/* plane_mask */,
    int			/* format */
);
EXTERN XImage *XGetSubImage(
    Display*		/* display */,
    Drawable		/* d */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned long	/* plane_mask */,
    int			/* format */,
    XImage*		/* dest_image */,
    int			/* dest_x */,
    int			/* dest_y */
);

/*
 * X function declarations.
 */
EXTERN Display *XOpenDisplay(
    _Xconst char*	/* display_name */
);

EXTERN void XrmInitialize(
    void
);

EXTERN char *XFetchBytes(
    Display*		/* display */,
    int*		/* nbytes_return */
);
EXTERN char *XFetchBuffer(
    Display*		/* display */,
    int*		/* nbytes_return */,
    int			/* buffer */
);
EXTERN char *XGetAtomName(
    Display*		/* display */,
    Atom		/* atom */
);
EXTERN Status XGetAtomNames(
    Display*		/* dpy */,
    Atom*		/* atoms */,
    int			/* count */,
    char**		/* names_return */
);
EXTERN char *XGetDefault(
    Display*		/* display */,
    _Xconst char*	/* program */,
    _Xconst char*	/* option */
);
EXTERN char *XDisplayName(
    _Xconst char*	/* string */
);
EXTERN char *XKeysymToString(
    KeySym		/* keysym */
);

EXTERN int (*XSynchronize(
    Display*		/* display */,
    Bool		/* onoff */
))(
    Display*		/* display */
);
EXTERN int (*XSetAfterFunction(
    Display*		/* display */,
    int (*) (
	     Display*	/* display */
            )		/* procedure */
))(
    Display*		/* display */
);
EXTERN Atom XInternAtom(
    Display*		/* display */,
    _Xconst char*	/* atom_name */,
    Bool		/* only_if_exists */
);
EXTERN Status XInternAtoms(
    Display*		/* dpy */,
    char**		/* names */,
    int			/* count */,
    Bool		/* onlyIfExists */,
    Atom*		/* atoms_return */
);
EXTERN Colormap XCopyColormapAndFree(
    Display*		/* display */,
    Colormap		/* colormap */
);
EXTERN Colormap XCreateColormap(
    Display*		/* display */,
    Window		/* w */,
    Visual*		/* visual */,
    int			/* alloc */
);
EXTERN Cursor XCreatePixmapCursor(
    Display*		/* display */,
    Pixmap		/* source */,
    Pixmap		/* mask */,
    XColor*		/* foreground_color */,
    XColor*		/* background_color */,
    unsigned int	/* x */,
    unsigned int	/* y */
);
EXTERN Cursor XCreateGlyphCursor(
    Display*		/* display */,
    Font		/* source_font */,
    Font		/* mask_font */,
    unsigned int	/* source_char */,
    unsigned int	/* mask_char */,
    XColor _Xconst *	/* foreground_color */,
    XColor _Xconst *	/* background_color */
);
EXTERN Cursor XCreateFontCursor(
    Display*		/* display */,
    unsigned int	/* shape */
);
EXTERN Font XLoadFont(
    Display*		/* display */,
    _Xconst char*	/* name */
);
EXTERN GC XCreateGC(
    Display*		/* display */,
    Drawable		/* d */,
    unsigned long	/* valuemask */,
    XGCValues*		/* values */
);
EXTERN GContext XGContextFromGC(
    GC			/* gc */
);
EXTERN void XFlushGC(
    Display*		/* display */,
    GC			/* gc */
);
EXTERN Pixmap XCreatePixmap(
    Display*		/* display */,
    Drawable		/* d */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int	/* depth */
);
EXTERN Pixmap XCreateBitmapFromData(
    Display*		/* display */,
    Drawable		/* d */,
    _Xconst char*	/* data */,
    unsigned int	/* width */,
    unsigned int	/* height */
);
EXTERN Pixmap XCreatePixmapFromBitmapData(
    Display*		/* display */,
    Drawable		/* d */,
    char*		/* data */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned long	/* fg */,
    unsigned long	/* bg */,
    unsigned int	/* depth */
);
EXTERN Window XCreateSimpleWindow(
    Display*		/* display */,
    Window		/* parent */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int	/* border_width */,
    unsigned long	/* border */,
    unsigned long	/* background */
);
EXTERN Window XGetSelectionOwner(
    Display*		/* display */,
    Atom		/* selection */
);
EXTERN Window XCreateWindow(
    Display*		/* display */,
    Window		/* parent */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int	/* border_width */,
    int			/* depth */,
    unsigned int	/* class */,
    Visual*		/* visual */,
    unsigned long	/* valuemask */,
    XSetWindowAttributes*	/* attributes */
);
EXTERN Colormap *XListInstalledColormaps(
    Display*		/* display */,
    Window		/* w */,
    int*		/* num_return */
);
EXTERN char **XListFonts(
    Display*		/* display */,
    _Xconst char*	/* pattern */,
    int			/* maxnames */,
    int*		/* actual_count_return */
);
EXTERN char **XListFontsWithInfo(
    Display*		/* display */,
    _Xconst char*	/* pattern */,
    int			/* maxnames */,
    int*		/* count_return */,
    XFontStruct**	/* info_return */
);
EXTERN char **XGetFontPath(
    Display*		/* display */,
    int*		/* npaths_return */
);
EXTERN char **XListExtensions(
    Display*		/* display */,
    int*		/* nextensions_return */
);
EXTERN Atom *XListProperties(
    Display*		/* display */,
    Window		/* w */,
    int*		/* num_prop_return */
);
EXTERN XHostAddress *XListHosts(
    Display*		/* display */,
    int*		/* nhosts_return */,
    Bool*		/* state_return */
);
EXTERN _X_DEPRECATED KeySym XKeycodeToKeysym(
    Display*		/* display */,
#if NeedWidePrototypes
    unsigned int	/* keycode */,
#else
    KeyCode		/* keycode */,
#endif
    int			/* index */
);
EXTERN KeySym XLookupKeysym(
    XKeyEvent*		/* key_event */,
    int			/* index */
);
EXTERN KeySym *XGetKeyboardMapping(
    Display*		/* display */,
#if NeedWidePrototypes
    unsigned int	/* first_keycode */,
#else
    KeyCode		/* first_keycode */,
#endif
    int			/* keycode_count */,
    int*		/* keysyms_per_keycode_return */
);
EXTERN KeySym XStringToKeysym(
    _Xconst char*	/* string */
);
EXTERN long XMaxRequestSize(
    Display*		/* display */
);
EXTERN long XExtendedMaxRequestSize(
    Display*		/* display */
);
EXTERN char *XResourceManagerString(
    Display*		/* display */
);
EXTERN char *XScreenResourceString(
	Screen*		/* screen */
);
EXTERN unsigned long XDisplayMotionBufferSize(
    Display*		/* display */
);
EXTERN VisualID XVisualIDFromVisual(
    Visual*		/* visual */
);

/* multithread routines */

EXTERN Status XInitThreads(
    void
);

EXTERN void XLockDisplay(
    Display*		/* display */
);

EXTERN void XUnlockDisplay(
    Display*		/* display */
);

/* routines for dealing with extensions */

EXTERN XExtCodes *XInitExtension(
    Display*		/* display */,
    _Xconst char*	/* name */
);

EXTERN XExtCodes *XAddExtension(
    Display*		/* display */
);
EXTERN XExtData *XFindOnExtensionList(
    XExtData**		/* structure */,
    int			/* number */
);
EXTERN XExtData **XEHeadOfExtensionList(
    XEDataObject	/* object */
);

/* these are routines for which there are also macros */
EXTERN Window XRootWindow(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN Window XDefaultRootWindow(
    Display*		/* display */
);
EXTERN Window XRootWindowOfScreen(
    Screen*		/* screen */
);
EXTERN Visual *XDefaultVisual(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN Visual *XDefaultVisualOfScreen(
    Screen*		/* screen */
);
EXTERN GC XDefaultGC(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN GC XDefaultGCOfScreen(
    Screen*		/* screen */
);
EXTERN unsigned long XBlackPixel(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN unsigned long XWhitePixel(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN unsigned long XAllPlanes(
    void
);
EXTERN unsigned long XBlackPixelOfScreen(
    Screen*		/* screen */
);
EXTERN unsigned long XWhitePixelOfScreen(
    Screen*		/* screen */
);
EXTERN unsigned long XNextRequest(
    Display*		/* display */
);
EXTERN unsigned long XLastKnownRequestProcessed(
    Display*		/* display */
);
EXTERN char *XServerVendor(
    Display*		/* display */
);
EXTERN char *XDisplayString(
    Display*		/* display */
);
EXTERN Colormap XDefaultColormap(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN Colormap XDefaultColormapOfScreen(
    Screen*		/* screen */
);
EXTERN Display *XDisplayOfScreen(
    Screen*		/* screen */
);
EXTERN Screen *XScreenOfDisplay(
    Display*		/* display */,
    int			/* screen_number */
);
EXTERN Screen *XDefaultScreenOfDisplay(
    Display*		/* display */
);
EXTERN long XEventMaskOfScreen(
    Screen*		/* screen */
);

EXTERN int XScreenNumberOfScreen(
    Screen*		/* screen */
);

typedef int (*XErrorHandler) (	    /* WARNING, this type not in Xlib spec */
    Display*		/* display */,
    XErrorEvent*	/* error_event */
);

EXTERN XErrorHandler XSetErrorHandler (
    XErrorHandler	/* handler */
);


typedef int (*XIOErrorHandler) (    /* WARNING, this type not in Xlib spec */
    Display*		/* display */
);

EXTERN XIOErrorHandler XSetIOErrorHandler (
    XIOErrorHandler	/* handler */
);


EXTERN XPixmapFormatValues *XListPixmapFormats(
    Display*		/* display */,
    int*		/* count_return */
);
EXTERN int *XListDepths(
    Display*		/* display */,
    int			/* screen_number */,
    int*		/* count_return */
);

/* ICCCM routines for things that don't require special include files; */
/* other declarations are given in Xutil.h                             */
EXTERN Status XReconfigureWMWindow(
    Display*		/* display */,
    Window		/* w */,
    int			/* screen_number */,
    unsigned int	/* mask */,
    XWindowChanges*	/* changes */
);

EXTERN Status XGetWMProtocols(
    Display*		/* display */,
    Window		/* w */,
    Atom**		/* protocols_return */,
    int*		/* count_return */
);
EXTERN Status XSetWMProtocols(
    Display*		/* display */,
    Window		/* w */,
    Atom*		/* protocols */,
    int			/* count */
);
EXTERN Status XIconifyWindow(
    Display*		/* display */,
    Window		/* w */,
    int			/* screen_number */
);
EXTERN Status XWithdrawWindow(
    Display*		/* display */,
    Window		/* w */,
    int			/* screen_number */
);
EXTERN Status XGetCommand(
    Display*		/* display */,
    Window		/* w */,
    char***		/* argv_return */,
    int*		/* argc_return */
);
EXTERN Status XGetWMColormapWindows(
    Display*		/* display */,
    Window		/* w */,
    Window**		/* windows_return */,
    int*		/* count_return */
);
EXTERN Status XSetWMColormapWindows(
    Display*		/* display */,
    Window		/* w */,
    Window*		/* colormap_windows */,
    int			/* count */
);
EXTERN void XFreeStringList(
    char**		/* list */
);
EXTERN int XSetTransientForHint(
    Display*		/* display */,
    Window		/* w */,
    Window		/* prop_window */
);

/* The following are given in alphabetical order */

EXTERN int XActivateScreenSaver(
    Display*		/* display */
);

EXTERN int XAddHost(
    Display*		/* display */,
    XHostAddress*	/* host */
);

EXTERN int XAddHosts(
    Display*		/* display */,
    XHostAddress*	/* hosts */,
    int			/* num_hosts */
);

EXTERN int XAddToExtensionList(
    struct _XExtData**	/* structure */,
    XExtData*		/* ext_data */
);

EXTERN int XAddToSaveSet(
    Display*		/* display */,
    Window		/* w */
);

EXTERN Status XAllocColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    XColor*		/* screen_in_out */
);

EXTERN Status XAllocColorCells(
    Display*		/* display */,
    Colormap		/* colormap */,
    Bool	        /* contig */,
    unsigned long*	/* plane_masks_return */,
    unsigned int	/* nplanes */,
    unsigned long*	/* pixels_return */,
    unsigned int 	/* npixels */
);

EXTERN Status XAllocColorPlanes(
    Display*		/* display */,
    Colormap		/* colormap */,
    Bool		/* contig */,
    unsigned long*	/* pixels_return */,
    int			/* ncolors */,
    int			/* nreds */,
    int			/* ngreens */,
    int			/* nblues */,
    unsigned long*	/* rmask_return */,
    unsigned long*	/* gmask_return */,
    unsigned long*	/* bmask_return */
);

EXTERN Status XAllocNamedColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    _Xconst char*	/* color_name */,
    XColor*		/* screen_def_return */,
    XColor*		/* exact_def_return */
);

EXTERN int XAllowEvents(
    Display*		/* display */,
    int			/* event_mode */,
    Time		/* time */
);

EXTERN int XAutoRepeatOff(
    Display*		/* display */
);

EXTERN int XAutoRepeatOn(
    Display*		/* display */
);

EXTERN int XBell(
    Display*		/* display */,
    int			/* percent */
);

EXTERN int XBitmapBitOrder(
    Display*		/* display */
);

EXTERN int XBitmapPad(
    Display*		/* display */
);

EXTERN int XBitmapUnit(
    Display*		/* display */
);

EXTERN int XCellsOfScreen(
    Screen*		/* screen */
);

EXTERN int XChangeActivePointerGrab(
    Display*		/* display */,
    unsigned int	/* event_mask */,
    Cursor		/* cursor */,
    Time		/* time */
);

EXTERN int XChangeGC(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long	/* valuemask */,
    XGCValues*		/* values */
);

EXTERN int XChangeKeyboardControl(
    Display*		/* display */,
    unsigned long	/* value_mask */,
    XKeyboardControl*	/* values */
);

EXTERN int XChangeKeyboardMapping(
    Display*		/* display */,
    int			/* first_keycode */,
    int			/* keysyms_per_keycode */,
    KeySym*		/* keysyms */,
    int			/* num_codes */
);

EXTERN int XChangePointerControl(
    Display*		/* display */,
    Bool		/* do_accel */,
    Bool		/* do_threshold */,
    int			/* accel_numerator */,
    int			/* accel_denominator */,
    int			/* threshold */
);

EXTERN int XChangeProperty(
    Display*		/* display */,
    Window		/* w */,
    Atom		/* property */,
    Atom		/* type */,
    int			/* format */,
    int			/* mode */,
    _Xconst unsigned char*	/* data */,
    int			/* nelements */
);

EXTERN int XChangeSaveSet(
    Display*		/* display */,
    Window		/* w */,
    int			/* change_mode */
);

EXTERN int XChangeWindowAttributes(
    Display*		/* display */,
    Window		/* w */,
    unsigned long	/* valuemask */,
    XSetWindowAttributes* /* attributes */
);

EXTERN Bool XCheckIfEvent(
    Display*		/* display */,
    XEvent*		/* event_return */,
    Bool (*) (
	       Display*			/* display */,
               XEvent*			/* event */,
               XPointer			/* arg */
             )		/* predicate */,
    XPointer		/* arg */
);

EXTERN Bool XCheckMaskEvent(
    Display*		/* display */,
    long		/* event_mask */,
    XEvent*		/* event_return */
);

EXTERN Bool XCheckTypedEvent(
    Display*		/* display */,
    int			/* event_type */,
    XEvent*		/* event_return */
);

EXTERN Bool XCheckTypedWindowEvent(
    Display*		/* display */,
    Window		/* w */,
    int			/* event_type */,
    XEvent*		/* event_return */
);

EXTERN Bool XCheckWindowEvent(
    Display*		/* display */,
    Window		/* w */,
    long		/* event_mask */,
    XEvent*		/* event_return */
);

EXTERN int XCirculateSubwindows(
    Display*		/* display */,
    Window		/* w */,
    int			/* direction */
);

EXTERN int XCirculateSubwindowsDown(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XCirculateSubwindowsUp(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XClearArea(
    Display*		/* display */,
    Window		/* w */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    Bool		/* exposures */
);

EXTERN int XClearWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XCloseDisplay(
    Display*		/* display */
);

EXTERN int XConfigureWindow(
    Display*		/* display */,
    Window		/* w */,
    unsigned int	/* value_mask */,
    XWindowChanges*	/* values */
);

EXTERN int XConnectionNumber(
    Display*		/* display */
);

EXTERN int XConvertSelection(
    Display*		/* display */,
    Atom		/* selection */,
    Atom 		/* target */,
    Atom		/* property */,
    Window		/* requestor */,
    Time		/* time */
);

EXTERN int XCopyArea(
    Display*		/* display */,
    Drawable		/* src */,
    Drawable		/* dest */,
    GC			/* gc */,
    int			/* src_x */,
    int			/* src_y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* dest_x */,
    int			/* dest_y */
);

EXTERN int XCopyGC(
    Display*		/* display */,
    GC			/* src */,
    unsigned long	/* valuemask */,
    GC			/* dest */
);

EXTERN int XCopyPlane(
    Display*		/* display */,
    Drawable		/* src */,
    Drawable		/* dest */,
    GC			/* gc */,
    int			/* src_x */,
    int			/* src_y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* dest_x */,
    int			/* dest_y */,
    unsigned long	/* plane */
);

EXTERN int XDefaultDepth(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDefaultDepthOfScreen(
    Screen*		/* screen */
);

EXTERN int XDefaultScreen(
    Display*		/* display */
);

EXTERN int XDefineCursor(
    Display*		/* display */,
    Window		/* w */,
    Cursor		/* cursor */
);

EXTERN int XDeleteProperty(
    Display*		/* display */,
    Window		/* w */,
    Atom		/* property */
);

EXTERN int XDestroyWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XDestroySubwindows(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XDoesBackingStore(
    Screen*		/* screen */
);

EXTERN Bool XDoesSaveUnders(
    Screen*		/* screen */
);

EXTERN int XDisableAccessControl(
    Display*		/* display */
);


EXTERN int XDisplayCells(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDisplayHeight(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDisplayHeightMM(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDisplayKeycodes(
    Display*		/* display */,
    int*		/* min_keycodes_return */,
    int*		/* max_keycodes_return */
);

EXTERN int XDisplayPlanes(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDisplayWidth(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDisplayWidthMM(
    Display*		/* display */,
    int			/* screen_number */
);

EXTERN int XDrawArc(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* angle1 */,
    int			/* angle2 */
);

EXTERN int XDrawArcs(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XArc*		/* arcs */,
    int			/* narcs */
);

EXTERN int XDrawImageString(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* string */,
    int			/* length */
);

EXTERN int XDrawImageString16(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst XChar2b*	/* string */,
    int			/* length */
);

EXTERN int XDrawLine(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x1 */,
    int			/* y1 */,
    int			/* x2 */,
    int			/* y2 */
);

EXTERN int XDrawLines(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XPoint*		/* points */,
    int			/* npoints */,
    int			/* mode */
);

EXTERN int XDrawPoint(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */
);

EXTERN int XDrawPoints(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XPoint*		/* points */,
    int			/* npoints */,
    int			/* mode */
);

EXTERN int XDrawRectangle(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */
);

EXTERN int XDrawRectangles(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XRectangle*		/* rectangles */,
    int			/* nrectangles */
);

EXTERN int XDrawSegments(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XSegment*		/* segments */,
    int			/* nsegments */
);

EXTERN int XDrawString(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* string */,
    int			/* length */
);

EXTERN int XDrawString16(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst XChar2b*	/* string */,
    int			/* length */
);

EXTERN int XDrawText(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    XTextItem*		/* items */,
    int			/* nitems */
);

EXTERN int XDrawText16(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    XTextItem16*	/* items */,
    int			/* nitems */
);

EXTERN int XEnableAccessControl(
    Display*		/* display */
);

EXTERN int XEventsQueued(
    Display*		/* display */,
    int			/* mode */
);

EXTERN Status XFetchName(
    Display*		/* display */,
    Window		/* w */,
    char**		/* window_name_return */
);

EXTERN int XFillArc(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* angle1 */,
    int			/* angle2 */
);

EXTERN int XFillArcs(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XArc*		/* arcs */,
    int			/* narcs */
);

EXTERN int XFillPolygon(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XPoint*		/* points */,
    int			/* npoints */,
    int			/* shape */,
    int			/* mode */
);

EXTERN int XFillRectangle(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */
);

EXTERN int XFillRectangles(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    XRectangle*		/* rectangles */,
    int			/* nrectangles */
);

EXTERN int XFlush(
    Display*		/* display */
);

EXTERN int XForceScreenSaver(
    Display*		/* display */,
    int			/* mode */
);

EXTERN int XFree(
    void*		/* data */
);

EXTERN int XFreeColormap(
    Display*		/* display */,
    Colormap		/* colormap */
);

EXTERN int XFreeColors(
    Display*		/* display */,
    Colormap		/* colormap */,
    unsigned long*	/* pixels */,
    int			/* npixels */,
    unsigned long	/* planes */
);

EXTERN int XFreeCursor(
    Display*		/* display */,
    Cursor		/* cursor */
);

EXTERN int XFreeExtensionList(
    char**		/* list */
);

EXTERN int XFreeFont(
    Display*		/* display */,
    XFontStruct*	/* font_struct */
);

EXTERN int XFreeFontInfo(
    char**		/* names */,
    XFontStruct*	/* free_info */,
    int			/* actual_count */
);

EXTERN int XFreeFontNames(
    char**		/* list */
);

EXTERN int XFreeFontPath(
    char**		/* list */
);

EXTERN int XFreeGC(
    Display*		/* display */,
    GC			/* gc */
);

EXTERN int XFreeModifiermap(
    XModifierKeymap*	/* modmap */
);

EXTERN int XFreePixmap(
    Display*		/* display */,
    Pixmap		/* pixmap */
);

EXTERN int XGeometry(
    Display*		/* display */,
    int			/* screen */,
    _Xconst char*	/* position */,
    _Xconst char*	/* default_position */,
    unsigned int	/* bwidth */,
    unsigned int	/* fwidth */,
    unsigned int	/* fheight */,
    int			/* xadder */,
    int			/* yadder */,
    int*		/* x_return */,
    int*		/* y_return */,
    int*		/* width_return */,
    int*		/* height_return */
);

EXTERN int XGetErrorDatabaseText(
    Display*		/* display */,
    _Xconst char*	/* name */,
    _Xconst char*	/* message */,
    _Xconst char*	/* default_string */,
    char*		/* buffer_return */,
    int			/* length */
);

EXTERN int XGetErrorText(
    Display*		/* display */,
    int			/* code */,
    char*		/* buffer_return */,
    int			/* length */
);

EXTERN Bool XGetFontProperty(
    XFontStruct*	/* font_struct */,
    Atom		/* atom */,
    unsigned long*	/* value_return */
);

EXTERN Status XGetGCValues(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long	/* valuemask */,
    XGCValues*		/* values_return */
);

EXTERN Status XGetGeometry(
    Display*		/* display */,
    Drawable		/* d */,
    Window*		/* root_return */,
    int*		/* x_return */,
    int*		/* y_return */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */,
    unsigned int*	/* border_width_return */,
    unsigned int*	/* depth_return */
);

EXTERN Status XGetIconName(
    Display*		/* display */,
    Window		/* w */,
    char**		/* icon_name_return */
);

EXTERN int XGetInputFocus(
    Display*		/* display */,
    Window*		/* focus_return */,
    int*		/* revert_to_return */
);

EXTERN int XGetKeyboardControl(
    Display*		/* display */,
    XKeyboardState*	/* values_return */
);

EXTERN int XGetPointerControl(
    Display*		/* display */,
    int*		/* accel_numerator_return */,
    int*		/* accel_denominator_return */,
    int*		/* threshold_return */
);

EXTERN int XGetPointerMapping(
    Display*		/* display */,
    unsigned char*	/* map_return */,
    int			/* nmap */
);

EXTERN int XGetScreenSaver(
    Display*		/* display */,
    int*		/* timeout_return */,
    int*		/* interval_return */,
    int*		/* prefer_blanking_return */,
    int*		/* allow_exposures_return */
);

EXTERN Status XGetTransientForHint(
    Display*		/* display */,
    Window		/* w */,
    Window*		/* prop_window_return */
);

EXTERN int XGetWindowProperty(
    Display*		/* display */,
    Window		/* w */,
    Atom		/* property */,
    long		/* long_offset */,
    long		/* long_length */,
    Bool		/* delete */,
    Atom		/* req_type */,
    Atom*		/* actual_type_return */,
    int*		/* actual_format_return */,
    unsigned long*	/* nitems_return */,
    unsigned long*	/* bytes_after_return */,
    unsigned char**	/* prop_return */
);

EXTERN Status XGetWindowAttributes(
    Display*		/* display */,
    Window		/* w */,
    XWindowAttributes*	/* window_attributes_return */
);

EXTERN int XGrabButton(
    Display*		/* display */,
    unsigned int	/* button */,
    unsigned int	/* modifiers */,
    Window		/* grab_window */,
    Bool		/* owner_events */,
    unsigned int	/* event_mask */,
    int			/* pointer_mode */,
    int			/* keyboard_mode */,
    Window		/* confine_to */,
    Cursor		/* cursor */
);

EXTERN int XGrabKey(
    Display*		/* display */,
    int			/* keycode */,
    unsigned int	/* modifiers */,
    Window		/* grab_window */,
    Bool		/* owner_events */,
    int			/* pointer_mode */,
    int			/* keyboard_mode */
);

EXTERN int XGrabKeyboard(
    Display*		/* display */,
    Window		/* grab_window */,
    Bool		/* owner_events */,
    int			/* pointer_mode */,
    int			/* keyboard_mode */,
    Time		/* time */
);

EXTERN int 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 */
);

EXTERN int XGrabServer(
    Display*		/* display */
);

EXTERN int XHeightMMOfScreen(
    Screen*		/* screen */
);

EXTERN int XHeightOfScreen(
    Screen*		/* screen */
);

EXTERN int XIfEvent(
    Display*		/* display */,
    XEvent*		/* event_return */,
    Bool (*) (
	       Display*			/* display */,
               XEvent*			/* event */,
               XPointer			/* arg */
             )		/* predicate */,
    XPointer		/* arg */
);

EXTERN int XImageByteOrder(
    Display*		/* display */
);

EXTERN int XInstallColormap(
    Display*		/* display */,
    Colormap		/* colormap */
);

EXTERN KeyCode XKeysymToKeycode(
    Display*		/* display */,
    KeySym		/* keysym */
);

EXTERN int XKillClient(
    Display*		/* display */,
    XID			/* resource */
);

EXTERN Status XLookupColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    _Xconst char*	/* color_name */,
    XColor*		/* exact_def_return */,
    XColor*		/* screen_def_return */
);

EXTERN int XLowerWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XMapRaised(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XMapSubwindows(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XMapWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XMaskEvent(
    Display*		/* display */,
    long		/* event_mask */,
    XEvent*		/* event_return */
);

EXTERN int XMaxCmapsOfScreen(
    Screen*		/* screen */
);

EXTERN int XMinCmapsOfScreen(
    Screen*		/* screen */
);

EXTERN int XMoveResizeWindow(
    Display*		/* display */,
    Window		/* w */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */
);

EXTERN int XMoveWindow(
    Display*		/* display */,
    Window		/* w */,
    int			/* x */,
    int			/* y */
);

EXTERN int XNextEvent(
    Display*		/* display */,
    XEvent*		/* event_return */
);

EXTERN int XNoOp(
    Display*		/* display */
);

EXTERN Status XParseColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    _Xconst char*	/* spec */,
    XColor*		/* exact_def_return */
);

EXTERN int XParseGeometry(
    _Xconst char*	/* parsestring */,
    int*		/* x_return */,
    int*		/* y_return */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */
);

EXTERN int XPeekEvent(
    Display*		/* display */,
    XEvent*		/* event_return */
);

EXTERN int XPeekIfEvent(
    Display*		/* display */,
    XEvent*		/* event_return */,
    Bool (*) (
	       Display*		/* display */,
               XEvent*		/* event */,
               XPointer		/* arg */
             )		/* predicate */,
    XPointer		/* arg */
);

EXTERN int XPending(
    Display*		/* display */
);

EXTERN int XPlanesOfScreen(
    Screen*		/* screen */
);

EXTERN int XProtocolRevision(
    Display*		/* display */
);

EXTERN int XProtocolVersion(
    Display*		/* display */
);


EXTERN int XPutBackEvent(
    Display*		/* display */,
    XEvent*		/* event */
);

EXTERN int XPutImage(
    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 */
);

EXTERN int XQLength(
    Display*		/* display */
);

EXTERN Status XQueryBestCursor(
    Display*		/* display */,
    Drawable		/* d */,
    unsigned int        /* width */,
    unsigned int	/* height */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */
);

EXTERN Status XQueryBestSize(
    Display*		/* display */,
    int			/* class */,
    Drawable		/* which_screen */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */
);

EXTERN Status XQueryBestStipple(
    Display*		/* display */,
    Drawable		/* which_screen */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */
);

EXTERN Status XQueryBestTile(
    Display*		/* display */,
    Drawable		/* which_screen */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */
);

EXTERN int XQueryColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    XColor*		/* def_in_out */
);

EXTERN int XQueryColors(
    Display*		/* display */,
    Colormap		/* colormap */,
    XColor*		/* defs_in_out */,
    int			/* ncolors */
);

EXTERN Bool XQueryExtension(
    Display*		/* display */,
    _Xconst char*	/* name */,
    int*		/* major_opcode_return */,
    int*		/* first_event_return */,
    int*		/* first_error_return */
);

EXTERN int XQueryKeymap(
    Display*		/* display */,
    char [32]		/* keys_return */
);

EXTERN Bool XQueryPointer(
    Display*		/* display */,
    Window		/* w */,
    Window*		/* root_return */,
    Window*		/* child_return */,
    int*		/* root_x_return */,
    int*		/* root_y_return */,
    int*		/* win_x_return */,
    int*		/* win_y_return */,
    unsigned int*       /* mask_return */
);

EXTERN int XQueryTextExtents(
    Display*		/* display */,
    XID			/* font_ID */,
    _Xconst char*	/* string */,
    int			/* nchars */,
    int*		/* direction_return */,
    int*		/* font_ascent_return */,
    int*		/* font_descent_return */,
    XCharStruct*	/* overall_return */
);

EXTERN int XQueryTextExtents16(
    Display*		/* display */,
    XID			/* font_ID */,
    _Xconst XChar2b*	/* string */,
    int			/* nchars */,
    int*		/* direction_return */,
    int*		/* font_ascent_return */,
    int*		/* font_descent_return */,
    XCharStruct*	/* overall_return */
);

EXTERN Status XQueryTree(
    Display*		/* display */,
    Window		/* w */,
    Window*		/* root_return */,
    Window*		/* parent_return */,
    Window**		/* children_return */,
    unsigned int*	/* nchildren_return */
);

EXTERN int XRaiseWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XReadBitmapFile(
    Display*		/* display */,
    Drawable 		/* d */,
    _Xconst char*	/* filename */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */,
    Pixmap*		/* bitmap_return */,
    int*		/* x_hot_return */,
    int*		/* y_hot_return */
);

EXTERN int XReadBitmapFileData(
    _Xconst char*	/* filename */,
    unsigned int*	/* width_return */,
    unsigned int*	/* height_return */,
    unsigned char**	/* data_return */,
    int*		/* x_hot_return */,
    int*		/* y_hot_return */
);

EXTERN int XRebindKeysym(
    Display*		/* display */,
    KeySym		/* keysym */,
    KeySym*		/* list */,
    int			/* mod_count */,
    _Xconst unsigned char*	/* string */,
    int			/* bytes_string */
);

EXTERN int XRecolorCursor(
    Display*		/* display */,
    Cursor		/* cursor */,
    XColor*		/* foreground_color */,
    XColor*		/* background_color */
);

EXTERN int XRefreshKeyboardMapping(
    XMappingEvent*	/* event_map */
);

EXTERN int XRemoveFromSaveSet(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XRemoveHost(
    Display*		/* display */,
    XHostAddress*	/* host */
);

EXTERN int XRemoveHosts(
    Display*		/* display */,
    XHostAddress*	/* hosts */,
    int			/* num_hosts */
);

EXTERN int XReparentWindow(
    Display*		/* display */,
    Window		/* w */,
    Window		/* parent */,
    int			/* x */,
    int			/* y */
);

EXTERN int XResetScreenSaver(
    Display*		/* display */
);

EXTERN int XResizeWindow(
    Display*		/* display */,
    Window		/* w */,
    unsigned int	/* width */,
    unsigned int	/* height */
);

EXTERN int XRestackWindows(
    Display*		/* display */,
    Window*		/* windows */,
    int			/* nwindows */
);

EXTERN int XRotateBuffers(
    Display*		/* display */,
    int			/* rotate */
);

EXTERN int XRotateWindowProperties(
    Display*		/* display */,
    Window		/* w */,
    Atom*		/* properties */,
    int			/* num_prop */,
    int			/* npositions */
);

EXTERN int XScreenCount(
    Display*		/* display */
);

EXTERN int XSelectInput(
    Display*		/* display */,
    Window		/* w */,
    long		/* event_mask */
);

EXTERN Status XSendEvent(
    Display*		/* display */,
    Window		/* w */,
    Bool		/* propagate */,
    long		/* event_mask */,
    XEvent*		/* event_send */
);

EXTERN int XSetAccessControl(
    Display*		/* display */,
    int			/* mode */
);

EXTERN int XSetArcMode(
    Display*		/* display */,
    GC			/* gc */,
    int			/* arc_mode */
);

EXTERN int XSetBackground(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long	/* background */
);

EXTERN int XSetClipMask(
    Display*		/* display */,
    GC			/* gc */,
    Pixmap		/* pixmap */
);

EXTERN int XSetClipOrigin(
    Display*		/* display */,
    GC			/* gc */,
    int			/* clip_x_origin */,
    int			/* clip_y_origin */
);

EXTERN int XSetClipRectangles(
    Display*		/* display */,
    GC			/* gc */,
    int			/* clip_x_origin */,
    int			/* clip_y_origin */,
    XRectangle*		/* rectangles */,
    int			/* n */,
    int			/* ordering */
);

EXTERN int XSetCloseDownMode(
    Display*		/* display */,
    int			/* close_mode */
);

EXTERN int XSetCommand(
    Display*		/* display */,
    Window		/* w */,
    char**		/* argv */,
    int			/* argc */
);

EXTERN int XSetDashes(
    Display*		/* display */,
    GC			/* gc */,
    int			/* dash_offset */,
    _Xconst char*	/* dash_list */,
    int			/* n */
);

EXTERN int XSetFillRule(
    Display*		/* display */,
    GC			/* gc */,
    int			/* fill_rule */
);

EXTERN int XSetFillStyle(
    Display*		/* display */,
    GC			/* gc */,
    int			/* fill_style */
);

EXTERN int XSetFont(
    Display*		/* display */,
    GC			/* gc */,
    Font		/* font */
);

EXTERN int XSetFontPath(
    Display*		/* display */,
    char**		/* directories */,
    int			/* ndirs */
);

EXTERN int XSetForeground(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long	/* foreground */
);

EXTERN int XSetFunction(
    Display*		/* display */,
    GC			/* gc */,
    int			/* function */
);

EXTERN int XSetGraphicsExposures(
    Display*		/* display */,
    GC			/* gc */,
    Bool		/* graphics_exposures */
);

EXTERN int XSetIconName(
    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* icon_name */
);

EXTERN int XSetInputFocus(
    Display*		/* display */,
    Window		/* focus */,
    int			/* revert_to */,
    Time		/* time */
);

EXTERN int XSetLineAttributes(
    Display*		/* display */,
    GC			/* gc */,
    unsigned int	/* line_width */,
    int			/* line_style */,
    int			/* cap_style */,
    int			/* join_style */
);

EXTERN int XSetModifierMapping(
    Display*		/* display */,
    XModifierKeymap*	/* modmap */
);

EXTERN int XSetPlaneMask(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long	/* plane_mask */
);

EXTERN int XSetPointerMapping(
    Display*		/* display */,
    _Xconst unsigned char*	/* map */,
    int			/* nmap */
);

EXTERN int XSetScreenSaver(
    Display*		/* display */,
    int			/* timeout */,
    int			/* interval */,
    int			/* prefer_blanking */,
    int			/* allow_exposures */
);

EXTERN int XSetSelectionOwner(
    Display*		/* display */,
    Atom	        /* selection */,
    Window		/* owner */,
    Time		/* time */
);

EXTERN int XSetState(
    Display*		/* display */,
    GC			/* gc */,
    unsigned long 	/* foreground */,
    unsigned long	/* background */,
    int			/* function */,
    unsigned long	/* plane_mask */
);

EXTERN int XSetStipple(
    Display*		/* display */,
    GC			/* gc */,
    Pixmap		/* stipple */
);

EXTERN int XSetSubwindowMode(
    Display*		/* display */,
    GC			/* gc */,
    int			/* subwindow_mode */
);

EXTERN int XSetTSOrigin(
    Display*		/* display */,
    GC			/* gc */,
    int			/* ts_x_origin */,
    int			/* ts_y_origin */
);

EXTERN int XSetTile(
    Display*		/* display */,
    GC			/* gc */,
    Pixmap		/* tile */
);

EXTERN int XSetWindowBackground(
    Display*		/* display */,
    Window		/* w */,
    unsigned long	/* background_pixel */
);

EXTERN int XSetWindowBackgroundPixmap(
    Display*		/* display */,
    Window		/* w */,
    Pixmap		/* background_pixmap */
);

EXTERN int XSetWindowBorder(
    Display*		/* display */,
    Window		/* w */,
    unsigned long	/* border_pixel */
);

EXTERN int XSetWindowBorderPixmap(
    Display*		/* display */,
    Window		/* w */,
    Pixmap		/* border_pixmap */
);

EXTERN int XSetWindowBorderWidth(
    Display*		/* display */,
    Window		/* w */,
    unsigned int	/* width */
);

EXTERN int XSetWindowColormap(
    Display*		/* display */,
    Window		/* w */,
    Colormap		/* colormap */
);

EXTERN int XStoreBuffer(
    Display*		/* display */,
    _Xconst char*	/* bytes */,
    int			/* nbytes */,
    int			/* buffer */
);

EXTERN int XStoreBytes(
    Display*		/* display */,
    _Xconst char*	/* bytes */,
    int			/* nbytes */
);

EXTERN int XStoreColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    XColor*		/* color */
);

EXTERN int XStoreColors(
    Display*		/* display */,
    Colormap		/* colormap */,
    XColor*		/* color */,
    int			/* ncolors */
);

EXTERN int XStoreName(
    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */
);

EXTERN int XStoreNamedColor(
    Display*		/* display */,
    Colormap		/* colormap */,
    _Xconst char*	/* color */,
    unsigned long	/* pixel */,
    int			/* flags */
);

EXTERN int XSync(
    Display*		/* display */,
    Bool		/* discard */
);

EXTERN int XTextExtents(
    XFontStruct*	/* font_struct */,
    _Xconst char*	/* string */,
    int			/* nchars */,
    int*		/* direction_return */,
    int*		/* font_ascent_return */,
    int*		/* font_descent_return */,
    XCharStruct*	/* overall_return */
);

EXTERN int XTextExtents16(
    XFontStruct*	/* font_struct */,
    _Xconst XChar2b*	/* string */,
    int			/* nchars */,
    int*		/* direction_return */,
    int*		/* font_ascent_return */,
    int*		/* font_descent_return */,
    XCharStruct*	/* overall_return */
);

EXTERN int XTextWidth(
    XFontStruct*	/* font_struct */,
    _Xconst char*	/* string */,
    int			/* count */
);

EXTERN int XTextWidth16(
    XFontStruct*	/* font_struct */,
    _Xconst XChar2b*	/* string */,
    int			/* count */
);

EXTERN Bool XTranslateCoordinates(
    Display*		/* display */,
    Window		/* src_w */,
    Window		/* dest_w */,
    int			/* src_x */,
    int			/* src_y */,
    int*		/* dest_x_return */,
    int*		/* dest_y_return */,
    Window*		/* child_return */
);

EXTERN int XUndefineCursor(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XUngrabButton(
    Display*		/* display */,
    unsigned int	/* button */,
    unsigned int	/* modifiers */,
    Window		/* grab_window */
);

EXTERN int XUngrabKey(
    Display*		/* display */,
    int			/* keycode */,
    unsigned int	/* modifiers */,
    Window		/* grab_window */
);

EXTERN int XUngrabKeyboard(
    Display*		/* display */,
    Time		/* time */
);

EXTERN int XUngrabPointer(
    Display*		/* display */,
    Time		/* time */
);

EXTERN int XUngrabServer(
    Display*		/* display */
);

EXTERN int XUninstallColormap(
    Display*		/* display */,
    Colormap		/* colormap */
);

EXTERN int XUnloadFont(
    Display*		/* display */,
    Font		/* font */
);

EXTERN int XUnmapSubwindows(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XUnmapWindow(
    Display*		/* display */,
    Window		/* w */
);

EXTERN int XVendorRelease(
    Display*		/* display */
);

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 */
);

EXTERN int XWidthMMOfScreen(
    Screen*		/* screen */
);

EXTERN int XWidthOfScreen(
    Screen*		/* screen */
);

EXTERN int XWindowEvent(
    Display*		/* display */,
    Window		/* w */,
    long		/* event_mask */,
    XEvent*		/* event_return */
);

EXTERN int XWriteBitmapFile(
    Display*		/* display */,
    _Xconst char*	/* filename */,
    Pixmap		/* bitmap */,
    unsigned int	/* width */,
    unsigned int	/* height */,
    int			/* x_hot */,
    int			/* y_hot */
);

EXTERN Bool XSupportsLocale (void);

EXTERN char *XSetLocaleModifiers(
    const char*		/* modifier_list */
);

EXTERN XOM XOpenOM(
    Display*			/* display */,
    struct _XrmHashBucketRec*	/* rdb */,
    _Xconst char*		/* res_name */,
    _Xconst char*		/* res_class */
);

EXTERN Status XCloseOM(
    XOM			/* om */
);

EXTERN char *XSetOMValues(
    XOM			/* om */,
    ...
) _X_SENTINEL(0);

EXTERN char *XGetOMValues(
    XOM			/* om */,
    ...
) _X_SENTINEL(0);

EXTERN Display *XDisplayOfOM(
    XOM			/* om */
);

EXTERN char *XLocaleOfOM(
    XOM			/* om */
);

EXTERN XOC XCreateOC(
    XOM			/* om */,
    ...
) _X_SENTINEL(0);

EXTERN void XDestroyOC(
    XOC			/* oc */
);

EXTERN XOM XOMOfOC(
    XOC			/* oc */
);

EXTERN char *XSetOCValues(
    XOC			/* oc */,
    ...
) _X_SENTINEL(0);

EXTERN char *XGetOCValues(
    XOC			/* oc */,
    ...
) _X_SENTINEL(0);

EXTERN XFontSet XCreateFontSet(
    Display*		/* display */,
    _Xconst char*	/* base_font_name_list */,
    char***		/* missing_charset_list */,
    int*		/* missing_charset_count */,
    char**		/* def_string */
);

EXTERN void XFreeFontSet(
    Display*		/* display */,
    XFontSet		/* font_set */
);

EXTERN int XFontsOfFontSet(
    XFontSet		/* font_set */,
    XFontStruct***	/* font_struct_list */,
    char***		/* font_name_list */
);

EXTERN char *XBaseFontNameListOfFontSet(
    XFontSet		/* font_set */
);

EXTERN char *XLocaleOfFontSet(
    XFontSet		/* font_set */
);

EXTERN Bool XContextDependentDrawing(
    XFontSet		/* font_set */
);

EXTERN Bool XDirectionalDependentDrawing(
    XFontSet		/* font_set */
);

EXTERN Bool XContextualDrawing(
    XFontSet		/* font_set */
);

EXTERN XFontSetExtents *XExtentsOfFontSet(
    XFontSet		/* font_set */
);

EXTERN int XmbTextEscapement(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN int XwcTextEscapement(
    XFontSet		/* font_set */,
    _Xconst wchar_t*	/* text */,
    int			/* num_wchars */
);

EXTERN int Xutf8TextEscapement(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN int XmbTextExtents(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN int XwcTextExtents(
    XFontSet		/* font_set */,
    _Xconst wchar_t*	/* text */,
    int			/* num_wchars */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN int Xutf8TextExtents(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN Status XmbTextPerCharExtents(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */,
    XRectangle*		/* ink_extents_buffer */,
    XRectangle*		/* logical_extents_buffer */,
    int			/* buffer_size */,
    int*		/* num_chars */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN Status XwcTextPerCharExtents(
    XFontSet		/* font_set */,
    _Xconst wchar_t*	/* text */,
    int			/* num_wchars */,
    XRectangle*		/* ink_extents_buffer */,
    XRectangle*		/* logical_extents_buffer */,
    int			/* buffer_size */,
    int*		/* num_chars */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN Status Xutf8TextPerCharExtents(
    XFontSet		/* font_set */,
    _Xconst char*	/* text */,
    int			/* bytes_text */,
    XRectangle*		/* ink_extents_buffer */,
    XRectangle*		/* logical_extents_buffer */,
    int			/* buffer_size */,
    int*		/* num_chars */,
    XRectangle*		/* overall_ink_return */,
    XRectangle*		/* overall_logical_return */
);

EXTERN void XmbDrawText(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    XmbTextItem*	/* text_items */,
    int			/* nitems */
);

EXTERN void XwcDrawText(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    XwcTextItem*	/* text_items */,
    int			/* nitems */
);

EXTERN void Xutf8DrawText(
    Display*		/* display */,
    Drawable		/* d */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    XmbTextItem*	/* text_items */,
    int			/* nitems */
);

EXTERN void XmbDrawString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN void XwcDrawString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst wchar_t*	/* text */,
    int			/* num_wchars */
);

EXTERN void Xutf8DrawString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN void XmbDrawImageString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN void XwcDrawImageString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst wchar_t*	/* text */,
    int			/* num_wchars */
);

EXTERN void Xutf8DrawImageString(
    Display*		/* display */,
    Drawable		/* d */,
    XFontSet		/* font_set */,
    GC			/* gc */,
    int			/* x */,
    int			/* y */,
    _Xconst char*	/* text */,
    int			/* bytes_text */
);

EXTERN XIM XOpenIM(
    Display*			/* dpy */,
    struct _XrmHashBucketRec*	/* rdb */,
    char*			/* res_name */,
    char*			/* res_class */
);

EXTERN Status XCloseIM(
    XIM /* im */
);

EXTERN char *XGetIMValues(
    XIM /* im */, ...
) _X_SENTINEL(0);

EXTERN char *XSetIMValues(
    XIM /* im */, ...
) _X_SENTINEL(0);

EXTERN Display *XDisplayOfIM(
    XIM /* im */
);

EXTERN char *XLocaleOfIM(
    XIM /* im*/
);

EXTERN XIC XCreateIC(
    XIM /* im */, ...
) _X_SENTINEL(0);

EXTERN void XDestroyIC(
    XIC /* ic */
);

EXTERN void XSetICFocus(
    XIC /* ic */
);

EXTERN void XUnsetICFocus(
    XIC /* ic */
);

EXTERN wchar_t *XwcResetIC(
    XIC /* ic */
);

EXTERN char *XmbResetIC(
    XIC /* ic */
);

EXTERN char *Xutf8ResetIC(
    XIC /* ic */
);

EXTERN char *XSetICValues(
    XIC /* ic */, ...
) _X_SENTINEL(0);

EXTERN char *XGetICValues(
    XIC /* ic */, ...
) _X_SENTINEL(0);

EXTERN XIM XIMOfIC(
    XIC /* ic */
);

EXTERN Bool XFilterEvent(
    XEvent*	/* event */,
    Window	/* window */
);

EXTERN int XmbLookupString(
    XIC			/* ic */,
    XKeyPressedEvent*	/* event */,
    char*		/* buffer_return */,
    int			/* bytes_buffer */,
    KeySym*		/* keysym_return */,
    Status*		/* status_return */
);

EXTERN int XwcLookupString(
    XIC			/* ic */,
    XKeyPressedEvent*	/* event */,
    wchar_t*		/* buffer_return */,
    int			/* wchars_buffer */,
    KeySym*		/* keysym_return */,
    Status*		/* status_return */
);

EXTERN int Xutf8LookupString(
    XIC			/* ic */,
    XKeyPressedEvent*	/* event */,
    char*		/* buffer_return */,
    int			/* bytes_buffer */,
    KeySym*		/* keysym_return */,
    Status*		/* status_return */
);

EXTERN XVaNestedList XVaCreateNestedList(
    int /*unused*/, ...
) _X_SENTINEL(0);

/* internal connections for IMs */

EXTERN Bool XRegisterIMInstantiateCallback(
    Display*			/* dpy */,
    struct _XrmHashBucketRec*	/* rdb */,
    char*			/* res_name */,
    char*			/* res_class */,
    XIDProc			/* callback */,
    XPointer			/* client_data */
);

EXTERN Bool XUnregisterIMInstantiateCallback(
    Display*			/* dpy */,
    struct _XrmHashBucketRec*	/* rdb */,
    char*			/* res_name */,
    char*			/* res_class */,
    XIDProc			/* callback */,
    XPointer			/* client_data */
);

typedef void (*XConnectionWatchProc)(
    Display*			/* dpy */,
    XPointer			/* client_data */,
    int				/* fd */,
    Bool			/* opening */,	 /* open or close flag */
    XPointer*			/* watch_data */ /* open sets, close uses */
);


EXTERN Status XInternalConnectionNumbers(
    Display*			/* dpy */,
    int**			/* fd_return */,
    int*			/* count_return */
);

EXTERN void XProcessInternalConnection(
    Display*			/* dpy */,
    int				/* fd */
);

EXTERN Status XAddConnectionWatch(
    Display*			/* dpy */,
    XConnectionWatchProc	/* callback */,
    XPointer			/* client_data */
);

EXTERN void XRemoveConnectionWatch(
    Display*			/* dpy */,
    XConnectionWatchProc	/* callback */,
    XPointer			/* client_data */
);

EXTERN void XSetAuthorization(
    char *			/* name */,
    int				/* namelen */,
    char *			/* data */,
    int				/* datalen */
);

EXTERN int _Xmbtowc(
    wchar_t *			/* wstr */,
    char *			/* str */,
    int				/* len */
);

EXTERN int _Xwctomb(
    char *			/* str */,
    wchar_t			/* wc */
);

EXTERN Bool XGetEventData(
    Display*			/* dpy */,
    XGenericEventCookie*	/* cookie*/
);

EXTERN void XFreeEventData(
    Display*			/* dpy */,
    XGenericEventCookie*	/* cookie*/
);

#include "tkIntXlibDecls.h"

#ifdef __clang__
#pragma clang diagnostic pop



#endif

_XFUNCPROTOEND

#endif /* _X11_XLIB_H_ */







|
<
|
<
<
|
<
<
<
<
|
<
|
<
<
|
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|
>
>
>


<
<
|
1178
1179
1180
1181
1182
1183
1184
1185

1186


1187




1188

1189


1190




1191
1192
1193















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1194











































































































































































































































































































































































































































































































































































































































































1195
1196
1197
1198
1199
1200
1201
1202
1203
1204


1205
    XIMStatusDataType type;
    union {
	XIMText *text;
	Pixmap  bitmap;
    } data;
} XIMStatusDrawCallbackStruct;

typedef int (*XErrorHandler) (	    /* WARNING, this type not in Xlib spec */

#if NeedFunctionPrototypes


    Display*		/* display */,




    XErrorEvent*	/* error_event */

#endif


);





_XFUNCPROTOBEGIN





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































#include "tkIntXlibDecls.h"

_XFUNCPROTOEND

#if defined(MAC_OSX_TK)
#   undef Cursor
#   undef Region
#endif



#endif /* _XLIB_H_ */

Changes to xlib/X11/Xutil.h.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68


/***********************************************************

Copyright 1987, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.


Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.


                        All Rights Reserved

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, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

#ifndef _X11_XUTIL_H_
#define _X11_XUTIL_H_

/* You must include <X11/Xlib.h> before including this file */
#include <X11/Xlib.h>
#include <X11/keysym.h>

/* The Xlib structs are full of implicit padding to properly align members.
   We can't clean that up without breaking ABI, so tell clang not to bother
   complaining about it. */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"

#endif

/*
 * Bitmask returned by XParseGeometry().  Each bit tells if the corresponding
 * value (x, y, width, height) was found in the parsed string.
 */
#define NoValue		0x0000
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>







|













|
|


<
<

<
<
<
|
<
<
>







1
2
3
























4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


31



32


33
34
35
36
37
38
39
40
/* $XConsortium: Xutil.h,v 11.73 91/07/30 16:21:37 rws Exp $ */

/***********************************************************
























Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

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, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

#ifndef _XUTIL_H_
#define _XUTIL_H_

/* You must include <X11/Xlib.h> before including this file */






#if defined(MAC_OSX_TK)


#   define Region XRegion
#endif

/*
 * Bitmask returned by XParseGeometry().  Each bit tells if the corresponding
 * value (x, y, width, height) was found in the parsed string.
 */
#define NoValue		0x0000
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#define IconPixmapHint		(1L << 2)
#define IconWindowHint		(1L << 3)
#define IconPositionHint 	(1L << 4)
#define IconMaskHint		(1L << 5)
#define WindowGroupHint		(1L << 6)
#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \
IconPositionHint|IconMaskHint|WindowGroupHint)
#define XUrgencyHint		(1L << 8)

/* definitions for initial window state */
#define WithdrawnState 0	/* for windows that are not mapped */
#define NormalState 1	/* most applications want to start this way */
#define IconicState 3	/* application wants to start as an icon */

/*







<







108
109
110
111
112
113
114

115
116
117
118
119
120
121
#define IconPixmapHint		(1L << 2)
#define IconWindowHint		(1L << 3)
#define IconPositionHint 	(1L << 4)
#define IconMaskHint		(1L << 5)
#define WindowGroupHint		(1L << 6)
#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \
IconPositionHint|IconMaskHint|WindowGroupHint)


/* definitions for initial window state */
#define WithdrawnState 0	/* for windows that are not mapped */
#define NormalState 1	/* most applications want to start this way */
#define IconicState 3	/* application wants to start as an icon */

/*
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#define XLocaleNotSupported -2
#define XConverterNotFound -3

typedef enum {
    XStringStyle,		/* STRING */
    XCompoundTextStyle,		/* COMPOUND_TEXT */
    XTextStyle,			/* text in owner's encoding (current locale)*/
    XStdICCTextStyle,		/* STRING, else COMPOUND_TEXT */
    /* The following is an XFree86 extension, introduced in November 2000 */
    XUTF8StringStyle		/* UTF8_STRING */
} XICCEncodingStyle;

typedef struct {
	int min_width, min_height;
	int max_width, max_height;
	int width_inc, height_inc;
} XIconSize;

typedef struct {
	char *res_name;
	char *res_class;
} XClassHint;

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif
#if defined(STATIC_BUILD) || !defined(_WIN32)
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS
# endif
#elif defined(BUILD_tk)
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS __declspec(dllexport)
#elif !defined(TCL_STORAGE_CLASS)
# define TCL_STORAGE_CLASS __declspec(dllimport)
#endif

#ifdef XUTIL_DEFINE_FUNCTIONS
EXTERN int XDestroyImage(
        XImage *ximage);
EXTERN unsigned long XGetPixel(
        XImage *ximage,
        int x, int y);
EXTERN int XPutPixel(
        XImage *ximage,
        int x, int y,
        unsigned long pixel);
EXTERN XImage *XSubImage(
        XImage *ximage,
        int x, int y,
        unsigned int width, unsigned int height);
EXTERN int XAddPixel(
        XImage *ximage,
        long value);
#else
/*
 * These macros are used to give some sugar to the image routines so that
 * naive people are more comfortable with them.
 */
#define XDestroyImage(ximage) \
	((*((ximage)->f.destroy_image))((ximage)))
#define XGetPixel(ximage, x, y) \
	((*((ximage)->f.get_pixel))((ximage), (x), (y)))
#define XPutPixel(ximage, x, y, pixel) \
	((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel)))
#define XSubImage(ximage, x, y, width, height)  \
	((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height)))
#define XAddPixel(ximage, value) \
	((*((ximage)->f.add_pixel))((ximage), (value)))
#endif

/*
 * Compose sequence status structure, used in calling XLookupString.
 */
typedef struct _XComposeStatus {
    XPointer compose_ptr;	/* state table pointer */
    int chars_matched;		/* match state */
} XComposeStatus;

/*
 * Keysym macros, used on Keysyms to test for classes of symbols
 */
#define IsKeypadKey(keysym) \
  (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal))

#define IsPrivateKeypadKey(keysym) \
  (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))

#define IsCursorKey(keysym) \
  (((KeySym)(keysym) >= XK_Home)     && ((KeySym)(keysym) <  XK_Select))

#define IsPFKey(keysym) \
  (((KeySym)(keysym) >= XK_KP_F1)     && ((KeySym)(keysym) <= XK_KP_F4))

#define IsFunctionKey(keysym) \
  (((KeySym)(keysym) >= XK_F1)       && ((KeySym)(keysym) <= XK_F35))

#define IsMiscFunctionKey(keysym) \
  (((KeySym)(keysym) >= XK_Select)   && ((KeySym)(keysym) <= XK_Break))

#ifdef XK_XKB_KEYS
#define IsModifierKey(keysym) \
  ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \
   || (((KeySym)(keysym) >= XK_ISO_Lock) && \
       ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) \
   || ((KeySym)(keysym) == XK_Mode_switch) \
   || ((KeySym)(keysym) == XK_Num_Lock))
#else
#define IsModifierKey(keysym) \
  ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \
   || ((KeySym)(keysym) == XK_Mode_switch) \
   || ((KeySym)(keysym) == XK_Num_Lock))
#endif
/*
 * opaque reference to Region data type
 */
typedef struct _XRegion *Region;

/* Return values from XRectInRegion() */








|
<
<













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














<













|

<
<
<

|


|


|


|

<

|
<
<
|
|
<
<
<
<
<
<







142
143
144
145
146
147
148
149


150
151
152
153
154
155
156
157
158
159
160
161
162
































163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191



192
193
194
195
196
197
198
199
200
201
202
203

204
205


206
207






208
209
210
211
212
213
214
#define XLocaleNotSupported -2
#define XConverterNotFound -3

typedef enum {
    XStringStyle,		/* STRING */
    XCompoundTextStyle,		/* COMPOUND_TEXT */
    XTextStyle,			/* text in owner's encoding (current locale)*/
    XStdICCTextStyle		/* STRING, else COMPOUND_TEXT */


} XICCEncodingStyle;

typedef struct {
	int min_width, min_height;
	int max_width, max_height;
	int width_inc, height_inc;
} XIconSize;

typedef struct {
	char *res_name;
	char *res_class;
} XClassHint;

































/*
 * These macros are used to give some sugar to the image routines so that
 * naive people are more comfortable with them.
 */
#define XDestroyImage(ximage) \
	((*((ximage)->f.destroy_image))((ximage)))
#define XGetPixel(ximage, x, y) \
	((*((ximage)->f.get_pixel))((ximage), (x), (y)))
#define XPutPixel(ximage, x, y, pixel) \
	((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel)))
#define XSubImage(ximage, x, y, width, height)  \
	((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height)))
#define XAddPixel(ximage, value) \
	((*((ximage)->f.add_pixel))((ximage), (value)))


/*
 * Compose sequence status structure, used in calling XLookupString.
 */
typedef struct _XComposeStatus {
    XPointer compose_ptr;	/* state table pointer */
    int chars_matched;		/* match state */
} XComposeStatus;

/*
 * Keysym macros, used on Keysyms to test for classes of symbols
 */
#define IsKeypadKey(keysym) \
  (((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal))




#define IsCursorKey(keysym) \
  (((unsigned)(keysym) >= XK_Home)     && ((unsigned)(keysym) <  XK_Select))

#define IsPFKey(keysym) \
  (((unsigned)(keysym) >= XK_KP_F1)     && ((unsigned)(keysym) <= XK_KP_F4))

#define IsFunctionKey(keysym) \
  (((unsigned)(keysym) >= XK_F1)       && ((unsigned)(keysym) <= XK_F35))

#define IsMiscFunctionKey(keysym) \
  (((unsigned)(keysym) >= XK_Select)   && ((unsigned)(keysym) <= XK_Break))


#define IsModifierKey(keysym) \
  ((((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) \


   || ((unsigned)(keysym) == XK_Mode_switch) \
   || ((unsigned)(keysym) == XK_Num_Lock))






/*
 * opaque reference to Region data type
 */
typedef struct _XRegion *Region;

/* Return values from XRectInRegion() */

373
374
375
376
377
378
379
380

381

382
383
384

385

386
387
388

389

390
391
392

393

394
395
396

397

398
399
400

401
402

403
404
405







406

407
408
409
410
411

412
413
414

415
416
417

418

419
420
421

422

423
424
425

426
427

428
429
430

431
432
433
434

435
436
437

438
439
440

441
442
443

444
445
446
447

448
449
450

451
452
453

454
455
456

457
458
459
460
461

462
463
464

465
466
467
468

469
470
471

472
473
474
475

476
477
478

479
480
481
482

483
484
485
486
487
488
489
490
491
492

493
494
495

496
497
498

499
500

501
502
503

504
505
506

507
508
509

510
511
512

513
514
515

516
517
518
519

520
521
522

523
524
525
526
527

528
529
530

531
532
533

534
535
536

537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553

554
555
556

557
558
559
560
561

562
563
564

565
566
567

568
569
570

571
572
573

574
575
576

577
578
579

580
581
582

583
584
585
586
587

588
589
590

591
592
593
594

595
596
597

598
599
600

601
602
603

604
605
606
607

608
609
610

611
612
613

614
615
616

617
618
619
620
621

622
623
624

625
626
627
628

629
630
631

632
633
634
635
636
637
638
639

640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658

659
660
661

662
663
664

665
666
667

668
669
670

671
672
673

674
675
676

677
678
679

680
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

713
714
715

716
717
718
719

720
721
722

723
724
725

726
727
728

729
730
731
732

733
734
735

736
737
738

739
740
741

742
743
744
745
746
747
748
749
750
751
752
753

754
755
756

757
758
759

760
761
762
763
764

765
766
767

768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784

785
786
787










788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810
811
812
813
814

815
816
817

818
819
820

821
822
823

824
825
826

827
828
829
830
831
832
833
834
835
836
837

838
839
840

841
842
843
844
845
846
847
848

849
850
851




852
#define XUniqueContext()       ((XContext) XrmUniqueQuark())
#define XStringToContext(string)   ((XContext) XrmStringToQuark(string))

_XFUNCPROTOBEGIN

/* The following declarations are alphabetized. */

EXTERN XClassHint *XAllocClassHint (

    void

);

EXTERN XIconSize *XAllocIconSize (

    void

);

EXTERN XSizeHints *XAllocSizeHints (

    void

);

EXTERN XStandardColormap *XAllocStandardColormap (

    void

);

EXTERN XWMHints *XAllocWMHints (

    void

);

EXTERN int XClipBox(

    Region		/* r */,
    XRectangle*		/* rect_return */

);

EXTERN Region XCreateRegion(







    void

);

EXTERN const char *XDefaultString (void);

EXTERN int XDeleteContext(

    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */

);

EXTERN int XDestroyRegion(

    Region		/* r */

);

EXTERN int XEmptyRegion(

    Region		/* r */

);

EXTERN int XEqualRegion(

    Region		/* r1 */,
    Region		/* r2 */

);

EXTERN int XFindContext(

    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    XPointer*		/* data_return */

);

EXTERN Status XGetClassHint(

    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints_return */

);

EXTERN Status XGetIconSizes(

    Display*		/* display */,
    Window		/* w */,
    XIconSize**		/* size_list_return */,
    int*		/* count_return */

);

EXTERN Status XGetNormalHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */

);

EXTERN Status XGetRGBColormaps(

    Display*		/* display */,
    Window		/* w */,
    XStandardColormap** /* stdcmap_return */,
    int*		/* count_return */,
    Atom		/* property */

);

EXTERN Status XGetSizeHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    Atom		/* property */

);

EXTERN Status XGetStandardColormap(

    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap_return */,
    Atom		/* property */

);

EXTERN Status XGetTextProperty(

    Display*		/* display */,
    Window		/* window */,
    XTextProperty*	/* text_prop_return */,
    Atom		/* property */

);

EXTERN XVisualInfo *XGetVisualInfo(
    Display*		/* display */,
    long		/* vinfo_mask */,
    XVisualInfo*	/* vinfo_template */,
    int*		/* nitems_return */
);

EXTERN Status XGetWMClientMachine(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */

);

EXTERN XWMHints *XGetWMHints(

    Display*		/* display */,
    Window		/* w */

);

EXTERN Status XGetWMIconName(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */

);

EXTERN Status XGetWMName(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */

);

EXTERN Status XGetWMNormalHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */

);

EXTERN Status XGetWMSizeHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */,
    Atom		/* property */

);

EXTERN Status XGetZoomHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints_return */

);

EXTERN int XIntersectRegion(

    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

EXTERN void XConvertCase(
    KeySym		/* sym */,
    KeySym*		/* lower */,
    KeySym*		/* upper */
);

EXTERN int XLookupString(

    XKeyEvent*		/* event_struct */,
    char*		/* buffer_return */,
    int			/* bytes_buffer */,
    KeySym*		/* keysym_return */,
    XComposeStatus*	/* status_in_out */

);

EXTERN Status XMatchVisualInfo(

    Display*		/* display */,
    int			/* screen */,
    int			/* depth */,
    int			/* class */,
    XVisualInfo*	/* vinfo_return */

);

EXTERN int XOffsetRegion(

    Region		/* r */,
    int			/* dx */,
    int			/* dy */

);

EXTERN Bool XPointInRegion(

    Region		/* r */,
    int			/* x */,
    int			/* y */

);

EXTERN Region XPolygonRegion(

    XPoint*		/* points */,
    int			/* n */,
    int			/* fill_rule */

);

EXTERN int XRectInRegion(

    Region		/* r */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */

);

EXTERN int XSaveContext(

    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    _Xconst char*	/* data */

);

EXTERN int XSetClassHint(

    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints */

);

EXTERN int XSetIconSizes(

    Display*		/* display */,
    Window		/* w */,
    XIconSize*		/* size_list */,
    int			/* count */

);

EXTERN int XSetNormalHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */

);

EXTERN void XSetRGBColormaps(

    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* stdcmaps */,
    int			/* count */,
    Atom		/* property */

);

EXTERN int XSetSizeHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */

);

EXTERN int XSetStandardProperties(

    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */,
    _Xconst char*	/* icon_name */,
    Pixmap		/* icon_pixmap */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* hints */

);

EXTERN void XSetTextProperty(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */,
    Atom		/* property */
);

EXTERN void XSetWMClientMachine(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
);

EXTERN int XSetWMHints(

    Display*		/* display */,
    Window		/* w */,
    XWMHints*		/* wm_hints */

);

EXTERN void XSetWMIconName(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */

);

EXTERN void XSetWMName(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */

);

EXTERN void XSetWMNormalHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */

);

EXTERN void XSetWMProperties(

    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* window_name */,
    XTextProperty*	/* icon_name */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* normal_hints */,
    XWMHints*		/* wm_hints */,
    XClassHint*		/* class_hints */

);

EXTERN void XmbSetWMProperties(
    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */,
    _Xconst char*	/* icon_name */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* normal_hints */,
    XWMHints*		/* wm_hints */,
    XClassHint*		/* class_hints */
);

EXTERN void Xutf8SetWMProperties(
    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */,
    _Xconst char*	/* icon_name */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* normal_hints */,
    XWMHints*		/* wm_hints */,
    XClassHint*		/* class_hints */

);

EXTERN void XSetWMSizeHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */

);

EXTERN int XSetRegion(

    Display*		/* display */,
    GC			/* gc */,
    Region		/* r */

);

EXTERN void XSetStandardColormap(

    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap */,
    Atom		/* property */

);

EXTERN int XSetZoomHints(

    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints */

);

EXTERN int XShrinkRegion(

    Region		/* r */,
    int			/* dx */,
    int			/* dy */
);

EXTERN Status XStringListToTextProperty(
    char**		/* list */,
    int			/* count */,
    XTextProperty*	/* text_prop_return */
);

EXTERN int XSubtractRegion(

    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */

);

EXTERN int XmbTextListToTextProperty(

    Display*		display,
    char**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return

);

EXTERN int XwcTextListToTextProperty(

    Display*		display,
    wchar_t**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return
);

EXTERN int Xutf8TextListToTextProperty(
    Display*		display,
    char**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return
);

EXTERN void XwcFreeStringList(

    wchar_t**		list

);

EXTERN Status XTextPropertyToStringList(










    XTextProperty*	/* text_prop */,
    char***		/* list_return */,
    int*		/* count_return */
);

EXTERN int XmbTextPropertyToTextList(
    Display*		display,
    const XTextProperty* text_prop,
    char***		list_return,
    int*		count_return
);

EXTERN int XwcTextPropertyToTextList(

    Display*		display,
    const XTextProperty* text_prop,
    wchar_t***		list_return,
    int*		count_return
);

EXTERN int Xutf8TextPropertyToTextList(
    Display*		display,
    const XTextProperty* text_prop,
    char***		list_return,
    int*		count_return
);

EXTERN int XUnionRectWithRegion(

    XRectangle*		/* rectangle */,
    Region		/* src_region */,
    Region		/* dest_region_return */

);

EXTERN int XUnionRegion(

    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */

);

EXTERN int XWMGeometry(

    Display*		/* display */,
    int			/* screen_number */,
    _Xconst char*	/* user_geometry */,
    _Xconst char*	/* default_geometry */,
    unsigned int	/* border_width */,
    XSizeHints*		/* hints */,
    int*		/* x_return */,
    int*		/* y_return */,
    int*		/* width_return */,
    int*		/* height_return */,
    int*		/* gravity_return */

);

EXTERN int XXorRegion(

    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

#ifdef __clang__
#pragma clang diagnostic pop
#endif


_XFUNCPROTOEND





#endif /* _X11_XUTIL_H_ */







|
>

>


|
>

>


|
>

>


|
>

>


|
>

>


|
>


>


|
>
>
>
>
>
>
>

>


<
<
|
>



>


|
>

>


|
>

>


|
>


>


|
>




>


|
>



>


|
>




>


|
>



>


|
>





>


|
>




>


|
>




>


|
>




>


<
<
<
<
<
<

|
>



>


|
>


>


|
>



>


|
>



>


|
>




>


|
>





>


|
>



>


|
>



<
|
<
<
<
<


|
>





>


|
>





>


|
>



>


|
>



>


|
>



>


|
>





>


|
>




>


|
>



>


|
>




>


|
>



>


|
>





>


|
>




>


|
>








>


|
>




<
|
<
<
<
<


|
>



>


|
>



>


|
>



>


|
>



>


|
>









>


|
<
<
<
<
<
<
<
<
<
<
|
<









>


|
>




>


|
>



>


|
>




>


|
>



>


|
>



<
|
<
<
<
<


|
>



>


|
>
|
|
|
|
|
>


|
>
|
|
|
|
|
<
|
<
<
<
<
<
<


|
>
|
>


|
>
>
>
>
>
>
>
>
>
>



<
|
<
<
<
<
<


|
>
|
|
|
|
<
|
<
<
<
<
<


|
>



>


|
>



>


|
>











>


|
>



<
<
<
<

>



>
>
>
>
|
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450






451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

515




516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644




645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693










694

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745

746




747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774






775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

797





798
799
800
801
802
803
804
805

806





807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845




846
847
848
849
850
851
852
853
854
855
#define XUniqueContext()       ((XContext) XrmUniqueQuark())
#define XStringToContext(string)   ((XContext) XrmStringToQuark(string))

_XFUNCPROTOBEGIN

/* The following declarations are alphabetized. */

extern XClassHint *XAllocClassHint (
#if NeedFunctionPrototypes
    void
#endif
);

extern XIconSize *XAllocIconSize (
#if NeedFunctionPrototypes
    void
#endif
);

extern XSizeHints *XAllocSizeHints (
#if NeedFunctionPrototypes
    void
#endif
);

extern XStandardColormap *XAllocStandardColormap (
#if NeedFunctionPrototypes
    void
#endif
);

extern XWMHints *XAllocWMHints (
#if NeedFunctionPrototypes
    void
#endif
);

extern void XClipBox(
#if NeedFunctionPrototypes
    Region		/* r */,
    XRectangle*		/* rect_return */
#endif
);

extern Region XCreateRegion(
#if NeedFunctionPrototypes
    void
#endif
);

extern char *XDefaultString(
#if NeedFunctionPrototypes
    void
#endif
);



extern int XDeleteContext(
#if NeedFunctionPrototypes
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */
#endif
);

extern void XDestroyRegion(
#if NeedFunctionPrototypes
    Region		/* r */
#endif
);

extern Bool XEmptyRegion(
#if NeedFunctionPrototypes
    Region		/* r */
#endif
);

extern Bool XEqualRegion(
#if NeedFunctionPrototypes
    Region		/* r1 */,
    Region		/* r2 */
#endif
);

extern int XFindContext(
#if NeedFunctionPrototypes
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    XPointer*		/* data_return */
#endif
);

extern Status XGetClassHint(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints_return */
#endif
);

extern Status XGetIconSizes(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XIconSize**		/* size_list_return */,
    int*		/* count_return */
#endif
);

extern Status XGetNormalHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */
#endif
);

extern Status XGetRGBColormaps(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap** /* stdcmap_return */,
    int*		/* count_return */,
    Atom		/* property */
#endif
);

extern Status XGetSizeHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    Atom		/* property */
#endif
);

extern Status XGetStandardColormap(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap_return */,
    Atom		/* property */
#endif
);

extern Status XGetTextProperty(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* window */,
    XTextProperty*	/* text_prop_return */,
    Atom		/* property */
#endif
);








extern Status XGetWMClientMachine(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
#endif
);

extern XWMHints *XGetWMHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */
#endif
);

extern Status XGetWMIconName(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
#endif
);

extern Status XGetWMName(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
#endif
);

extern Status XGetWMNormalHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */
#endif
);

extern Status XGetWMSizeHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */,
    Atom		/* property */
#endif
);

extern Status XGetZoomHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints_return */
#endif
);

extern void XIntersectRegion(
#if NeedFunctionPrototypes
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */

#endif




);

extern int XLookupString(
#if NeedFunctionPrototypes
    XKeyEvent*		/* event_struct */,
    char*		/* buffer_return */,
    int			/* bytes_buffer */,
    KeySym*		/* keysym_return */,
    XComposeStatus*	/* status_in_out */
#endif
);

extern Status XMatchVisualInfo(
#if NeedFunctionPrototypes
    Display*		/* display */,
    int			/* screen */,
    int			/* depth */,
    int			/* class */,
    XVisualInfo*	/* vinfo_return */
#endif
);

extern int XOffsetRegion(
#if NeedFunctionPrototypes
    Region		/* r */,
    int			/* dx */,
    int			/* dy */
#endif
);

extern Bool XPointInRegion(
#if NeedFunctionPrototypes
    Region		/* r */,
    int			/* x */,
    int			/* y */
#endif
);

extern Region XPolygonRegion(
#if NeedFunctionPrototypes
    XPoint*		/* points */,
    int			/* n */,
    int			/* fill_rule */
#endif
);

extern int XRectInRegion(
#if NeedFunctionPrototypes
    Region		/* r */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */
#endif
);

extern int XSaveContext(
#if NeedFunctionPrototypes
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    _Xconst char*	/* data */
#endif
);

extern void XSetClassHint(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints */
#endif
);

extern void XSetIconSizes(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XIconSize*		/* size_list */,
    int			/* count */
#endif
);

extern void XSetNormalHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */
#endif
);

extern void XSetRGBColormaps(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* stdcmaps */,
    int			/* count */,
    Atom		/* property */
#endif
);

extern void XSetSizeHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */
#endif
);

extern void XSetStandardProperties(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */,
    _Xconst char*	/* icon_name */,
    Pixmap		/* icon_pixmap */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* hints */
#endif
);

extern void XSetTextProperty(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */,
    Atom		/* property */

#endif




);

extern void XSetWMHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XWMHints*		/* wm_hints */
#endif
);

extern void XSetWMIconName(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
#endif
);

extern void XSetWMName(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
#endif
);

extern void XSetWMNormalHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */
#endif
);

extern void XSetWMProperties(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* window_name */,
    XTextProperty*	/* icon_name */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* normal_hints */,
    XWMHints*		/* wm_hints */,
    XClassHint*		/* class_hints */
#endif
);

extern void XmbSetWMProperties(










#if NeedFunctionPrototypes

    Display*		/* display */,
    Window		/* w */,
    _Xconst char*	/* window_name */,
    _Xconst char*	/* icon_name */,
    char**		/* argv */,
    int			/* argc */,
    XSizeHints*		/* normal_hints */,
    XWMHints*		/* wm_hints */,
    XClassHint*		/* class_hints */
#endif
);

extern void XSetWMSizeHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */
#endif
);

extern void XSetRegion(
#if NeedFunctionPrototypes
    Display*		/* display */,
    GC			/* gc */,
    Region		/* r */
#endif
);

extern void XSetStandardColormap(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap */,
    Atom		/* property */
#endif
);

extern void XSetZoomHints(
#if NeedFunctionPrototypes
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints */
#endif
);

extern void XShrinkRegion(
#if NeedFunctionPrototypes
    Region		/* r */,
    int			/* dx */,
    int			/* dy */

#endif




);

extern void XSubtractRegion(
#if NeedFunctionPrototypes
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
#endif
);

extern int XmbTextListToTextProperty(
#if NeedFunctionPrototypes
    Display*		/* display */,
    char**		/* list */,
    int			/* count */,
    XICCEncodingStyle	/* style */,
    XTextProperty*	/* text_prop_return */
#endif
);

extern int XwcTextListToTextProperty(
#if NeedFunctionPrototypes
    Display*		/* display */,
    wchar_t**		/* list */,
    int			/* count */,
    XICCEncodingStyle	/* style */,
    XTextProperty*	/* text_prop_return */

#endif






);

extern void XwcFreeStringList(
#if NeedFunctionPrototypes
    wchar_t**		/* list */
#endif
);

extern Status XTextPropertyToStringList(
#if NeedFunctionPrototypes
    XTextProperty*	/* text_prop */,
    char***		/* list_return */,
    int*		/* count_return */
#endif
);

extern int XmbTextPropertyToTextList(
#if NeedFunctionPrototypes
    Display*		/* display */,
    XTextProperty*	/* text_prop */,
    char***		/* list_return */,
    int*		/* count_return */

#endif





);

extern int XwcTextPropertyToTextList(
#if NeedFunctionPrototypes
    Display*		/* display */,
    XTextProperty*	/* text_prop */,
    wchar_t***		/* list_return */,
    int*		/* count_return */

#endif





);

extern void XUnionRectWithRegion(
#if NeedFunctionPrototypes
    XRectangle*		/* rectangle */,
    Region		/* src_region */,
    Region		/* dest_region_return */
#endif
);

extern int XUnionRegion(
#if NeedFunctionPrototypes
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
#endif
);

extern int XWMGeometry(
#if NeedFunctionPrototypes
    Display*		/* display */,
    int			/* screen_number */,
    _Xconst char*	/* user_geometry */,
    _Xconst char*	/* default_geometry */,
    unsigned int	/* border_width */,
    XSizeHints*		/* hints */,
    int*		/* x_return */,
    int*		/* y_return */,
    int*		/* width_return */,
    int*		/* height_return */,
    int*		/* gravity_return */
#endif
);

extern void XXorRegion(
#if NeedFunctionPrototypes
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */




#endif
);

_XFUNCPROTOEND

#if defined(MAC_OSX_TK)
#   undef Region
#endif

#endif /* _XUTIL_H_ */

Deleted xlib/X11/ap_keysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/******************************************************************
Copyright 1987 by Apollo Computer Inc., Chelmsford, Massachusetts.
Copyright 1989 by Hewlett-Packard Company.

                        All Rights Reserved

Permission to use, duplicate, change, and distribute this software and
its documentation for any purpose and without fee is granted, provided
that the above copyright notice appear in such copy and that this
copyright notice appear in all supporting documentation, and that the
names of Apollo Computer Inc., the Hewlett-Packard Company, or the X
Consortium not be used in advertising or publicity pertaining to
distribution of the software without written prior permission.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

This software is not subject to any license of the American
Telephone and Telegraph Company or of the Regents of the
University of California.
******************************************************************/

#define apXK_LineDel            0x1000FF00
#define apXK_CharDel            0x1000FF01
#define apXK_Copy               0x1000FF02
#define apXK_Cut                0x1000FF03
#define apXK_Paste              0x1000FF04
#define apXK_Move               0x1000FF05
#define apXK_Grow               0x1000FF06
#define apXK_Cmd                0x1000FF07
#define apXK_Shell              0x1000FF08
#define apXK_LeftBar            0x1000FF09
#define apXK_RightBar           0x1000FF0A
#define apXK_LeftBox            0x1000FF0B
#define apXK_RightBox           0x1000FF0C
#define apXK_UpBox              0x1000FF0D
#define apXK_DownBox            0x1000FF0E
#define apXK_Pop                0x1000FF0F
#define apXK_Read               0x1000FF10
#define apXK_Edit               0x1000FF11
#define apXK_Save               0x1000FF12
#define apXK_Exit               0x1000FF13
#define apXK_Repeat             0x1000FF14

#define apXK_KP_parenleft       0x1000FFA8
#define apXK_KP_parenright      0x1000FFA9
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































Changes to xlib/X11/cursorfont.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*

Copyright 1987, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from The Open Group.

*/

#ifndef _X11_CURSORFONT_H_
#define _X11_CURSORFONT_H_

#define XC_num_glyphs 154
#define XC_X_cursor 0
#define XC_arrow 2
#define XC_based_arrow_down 4
#define XC_based_arrow_up 6
#define XC_boat 8
#define XC_bogosity 10
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1





























2
3
4
5
6
7
8

/* $XConsortium: cursorfont.h,v 1.2 88/09/06 16:44:27 jim Exp $ */





























#define XC_num_glyphs 154
#define XC_X_cursor 0
#define XC_arrow 2
#define XC_based_arrow_down 4
#define XC_based_arrow_up 6
#define XC_boat 8
#define XC_bogosity 10
103
104
105
106
107
108
109
110
111
#define XC_top_tee 140
#define XC_trek 142
#define XC_ul_angle 144
#define XC_umbrella 146
#define XC_ur_angle 148
#define XC_watch 150
#define XC_xterm 152

#endif /* _X11_CURSORFONT_H_ */







<
<
73
74
75
76
77
78
79


#define XC_top_tee 140
#define XC_trek 142
#define XC_ul_angle 144
#define XC_umbrella 146
#define XC_ur_angle 148
#define XC_watch 150
#define XC_xterm 152


Changes to xlib/X11/keysym.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/***********************************************************

Copyright 1987, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.


Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.


                        All Rights Reserved

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, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

/* default keysyms */
#define XK_MISCELLANY
#define XK_XKB_KEYS
#define XK_LATIN1
#define XK_LATIN2
#define XK_LATIN3
#define XK_LATIN4
#define XK_LATIN8
#define XK_LATIN9
#define XK_CAUCASUS
#define XK_GREEK
#define XK_KATAKANA
#define XK_ARABIC
#define XK_CYRILLIC
#define XK_HEBREW
#define XK_THAI
#define XK_KOREAN
#define XK_ARMENIAN
#define XK_GEORGIAN
#define XK_VIETNAMESE
#define XK_CURRENCY
#define XK_MATHEMATICAL
#define XK_BRAILLE
#define XK_SINHALA

#include <X11/keysymdef.h>

<
|
<

<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>







|















<




<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<


<

1

2





3















4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32



33













34
35


/* $XConsortium: keysym.h,v 1.13 91/03/13 20:09:49 rws Exp $ */







/***********************************************************















Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

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, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

/* default keysyms */
#define XK_MISCELLANY

#define XK_LATIN1
#define XK_LATIN2
#define XK_LATIN3
#define XK_LATIN4



#define XK_GREEK














#include <X11/keysymdef.h>

Changes to xlib/X11/keysymdef.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
/***********************************************************
Copyright 1987, 1994, 1998  The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from The Open Group.


Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts


                        All Rights Reserved

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, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

/*
 * The "X11 Window System Protocol" standard defines in Appendix A the
 * keysym codes. These 29-bit integer values identify characters or
 * functions associated with each key (e.g., via the visible
 * engraving) of a keyboard layout. This file assigns mnemonic macro
 * names for these keysyms.
 *
 * This file is also compiled (by src/util/makekeys.c in libX11) into
 * hash tables that can be accessed with X11 library functions such as
 * XStringToKeysym() and XKeysymToString().
 *
 * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode
 * character, this is noted in a comment that provides both the U+xxxx
 * Unicode position, as well as the official Unicode name of the
 * character.
 *
 * Where the correspondence is either not one-to-one or semantically
 * unclear, the Unicode position and name are enclosed in
 * parentheses. Such legacy keysyms should be considered deprecated
 * and are not recommended for use in future keyboard mappings.
 *
 * For any future extension of the keysyms with characters already
 * found in ISO 10646 / Unicode, the following algorithm shall be
 * used. The new keysym code position will simply be the character's
 * Unicode number plus 0x01000000. The keysym values in the range
 * 0x01000100 to 0x0110ffff are reserved to represent Unicode
 * characters in the range U+0100 to U+10FFFF.
 *
 * While most newer Unicode-based X11 clients do already accept
 * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it
 * will remain necessary for clients -- in the interest of
 * compatibility with existing servers -- to also understand the
 * existing legacy keysym values in the range 0x0100 to 0x20ff.
 *
 * Where several mnemonic names are defined for the same keysym in this
 * file, all but the first one listed should be considered deprecated.
 *
 * Mnemonic names for keysyms are defined in this file with lines
 * that match one of these Perl regular expressions:
 *
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U+([0-9A-F]{4,6}) (.*) \*\/\s*$/
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/
 *
 * Before adding new keysyms, please do consider the following: In
 * addition to the keysym names defined in this file, the
 * XStringToKeysym() and XKeysymToString() functions will also handle
 * any keysym string of the form "U0020" to "U007E" and "U00A0" to
 * "U10FFFF" for all possible Unicode characters. In other words,
 * every possible Unicode character has already a keysym string
 * defined algorithmically, even if it is not listed here. Therefore,
 * defining an additional keysym macro is only necessary where a
 * non-hexadecimal mnemonic name is needed, or where the new keysym
 * does not represent any existing Unicode character.
 *
 * When adding new keysyms to this file, do not forget to also update the
 * following as needed:
 *
 *   - the mappings in src/KeyBind.c in the libX11 repo
 *     https://gitlab.freedesktop.org/xorg/lib/libx11
 *
 *   - the protocol specification in specs/keysyms.xml in this repo
 *     https://gitlab.freedesktop.org/xorg/proto/xorgproto
 *
 */

#define XK_VoidSymbol                  0xffffff  /* Void symbol */

#ifdef XK_MISCELLANY
/*
 * TTY function keys, cleverly chosen to map to ASCII, for convenience of
 * programming, but could have been arbitrary (at the cost of lookup
 * tables in client code).
 */

#define XK_BackSpace                     0xff08  /* Back space, back char */
#define XK_Tab                           0xff09
#define XK_Linefeed                      0xff0a  /* Linefeed, LF */
#define XK_Clear                         0xff0b
#define XK_Return                        0xff0d  /* Return, enter */
#define XK_Pause                         0xff13  /* Pause, hold */
#define XK_Scroll_Lock                   0xff14
#define XK_Sys_Req                       0xff15
#define XK_Escape                        0xff1b
#define XK_Delete                        0xffff  /* Delete, rubout */



/* International & multi-key character composition */

#define XK_Multi_key                     0xff20  /* Multi-key character compose */
#define XK_Codeinput                     0xff37
#define XK_SingleCandidate               0xff3c
#define XK_MultipleCandidate             0xff3d
#define XK_PreviousCandidate             0xff3e

/* Japanese keyboard support */

#define XK_Kanji                         0xff21  /* Kanji, Kanji convert */
#define XK_Muhenkan                      0xff22  /* Cancel Conversion */
#define XK_Henkan_Mode                   0xff23  /* Start/Stop Conversion */
#define XK_Henkan                        0xff23  /* Alias for Henkan_Mode */
#define XK_Romaji                        0xff24  /* to Romaji */
#define XK_Hiragana                      0xff25  /* to Hiragana */
#define XK_Katakana                      0xff26  /* to Katakana */
#define XK_Hiragana_Katakana             0xff27  /* Hiragana/Katakana toggle */
#define XK_Zenkaku                       0xff28  /* to Zenkaku */
#define XK_Hankaku                       0xff29  /* to Hankaku */
#define XK_Zenkaku_Hankaku               0xff2a  /* Zenkaku/Hankaku toggle */
#define XK_Touroku                       0xff2b  /* Add to Dictionary */
#define XK_Massyo                        0xff2c  /* Delete from Dictionary */
#define XK_Kana_Lock                     0xff2d  /* Kana Lock */
#define XK_Kana_Shift                    0xff2e  /* Kana Shift */
#define XK_Eisu_Shift                    0xff2f  /* Alphanumeric Shift */
#define XK_Eisu_toggle                   0xff30  /* Alphanumeric toggle */
#define XK_Kanji_Bangou                  0xff37  /* Codeinput */
#define XK_Zen_Koho                      0xff3d  /* Multiple/All Candidate(s) */
#define XK_Mae_Koho                      0xff3e  /* Previous Candidate */

/* 0xff31 thru 0xff3f are under XK_KOREAN */

/* Cursor control & motion */

#define XK_Home                          0xff50
#define XK_Left                          0xff51  /* Move left, left arrow */
#define XK_Up                            0xff52  /* Move up, up arrow */
#define XK_Right                         0xff53  /* Move right, right arrow */
#define XK_Down                          0xff54  /* Move down, down arrow */
#define XK_Prior                         0xff55  /* Prior, previous */
#define XK_Page_Up                       0xff55
#define XK_Next                          0xff56  /* Next */
#define XK_Page_Down                     0xff56
#define XK_End                           0xff57  /* EOL */
#define XK_Begin                         0xff58  /* BOL */

/* Special Windows keyboard keys */

#define XK_Win_L		0xFF5B	/* Left-hand Windows */
#define XK_Win_R		0xFF5C	/* Right-hand Windows */
#define XK_App			0xFF5D	/* Menu key */

/* Misc functions */

#define XK_Select                        0xff60  /* Select, mark */
#define XK_Print                         0xff61
#define XK_Execute                       0xff62  /* Execute, run, do */
#define XK_Insert                        0xff63  /* Insert, insert here */
#define XK_Undo                          0xff65
#define XK_Redo                          0xff66  /* Redo, again */
#define XK_Menu                          0xff67
#define XK_Find                          0xff68  /* Find, search */
#define XK_Cancel                        0xff69  /* Cancel, stop, abort, exit */
#define XK_Help                          0xff6a  /* Help */
#define XK_Break                         0xff6b
#define XK_Mode_switch                   0xff7e  /* Character set switch */
#define XK_script_switch                 0xff7e  /* Alias for mode_switch */
#define XK_Num_Lock                      0xff7f

/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */

#define XK_KP_Space                      0xff80  /* Space */
#define XK_KP_Tab                        0xff89
#define XK_KP_Enter                      0xff8d  /* Enter */
#define XK_KP_F1                         0xff91  /* PF1, KP_A, ... */
#define XK_KP_F2                         0xff92
#define XK_KP_F3                         0xff93
#define XK_KP_F4                         0xff94
#define XK_KP_Home                       0xff95
#define XK_KP_Left                       0xff96
#define XK_KP_Up                         0xff97
#define XK_KP_Right                      0xff98
#define XK_KP_Down                       0xff99
#define XK_KP_Prior                      0xff9a
#define XK_KP_Page_Up                    0xff9a
#define XK_KP_Next                       0xff9b
#define XK_KP_Page_Down                  0xff9b
#define XK_KP_End                        0xff9c
#define XK_KP_Begin                      0xff9d
#define XK_KP_Insert                     0xff9e
#define XK_KP_Delete                     0xff9f
#define XK_KP_Equal                      0xffbd  /* Equals */
#define XK_KP_Multiply                   0xffaa
#define XK_KP_Add                        0xffab
#define XK_KP_Separator                  0xffac  /* Separator, often comma */
#define XK_KP_Subtract                   0xffad
#define XK_KP_Decimal                    0xffae
#define XK_KP_Divide                     0xffaf

#define XK_KP_0                          0xffb0
#define XK_KP_1                          0xffb1
#define XK_KP_2                          0xffb2
#define XK_KP_3                          0xffb3
#define XK_KP_4                          0xffb4
#define XK_KP_5                          0xffb5
#define XK_KP_6                          0xffb6
#define XK_KP_7                          0xffb7
#define XK_KP_8                          0xffb8
#define XK_KP_9                          0xffb9



/*
 * Auxiliary functions; note the duplicate definitions for left and right
 * function keys;  Sun keyboards and a few other manufacturers have such
 * function key groups on the left and/or right sides of the keyboard.
 * We've not found a keyboard with more than 35 function keys total.
 */

#define XK_F1                            0xffbe
#define XK_F2                            0xffbf
#define XK_F3                            0xffc0
#define XK_F4                            0xffc1
#define XK_F5                            0xffc2
#define XK_F6                            0xffc3
#define XK_F7                            0xffc4
#define XK_F8                            0xffc5
#define XK_F9                            0xffc6
#define XK_F10                           0xffc7
#define XK_F11                           0xffc8
#define XK_L1                            0xffc8
#define XK_F12                           0xffc9
#define XK_L2                            0xffc9
#define XK_F13                           0xffca
#define XK_L3                            0xffca
#define XK_F14                           0xffcb
#define XK_L4                            0xffcb
#define XK_F15                           0xffcc
#define XK_L5                            0xffcc
#define XK_F16                           0xffcd
#define XK_L6                            0xffcd
#define XK_F17                           0xffce
#define XK_L7                            0xffce
#define XK_F18                           0xffcf
#define XK_L8                            0xffcf
#define XK_F19                           0xffd0
#define XK_L9                            0xffd0
#define XK_F20                           0xffd1
#define XK_L10                           0xffd1
#define XK_F21                           0xffd2
#define XK_R1                            0xffd2
#define XK_F22                           0xffd3
#define XK_R2                            0xffd3
#define XK_F23                           0xffd4
#define XK_R3                            0xffd4
#define XK_F24                           0xffd5
#define XK_R4                            0xffd5
#define XK_F25                           0xffd6
#define XK_R5                            0xffd6
#define XK_F26                           0xffd7
#define XK_R6                            0xffd7
#define XK_F27                           0xffd8
#define XK_R7                            0xffd8
#define XK_F28                           0xffd9
#define XK_R8                            0xffd9
#define XK_F29                           0xffda
#define XK_R9                            0xffda
#define XK_F30                           0xffdb
#define XK_R10                           0xffdb
#define XK_F31                           0xffdc
#define XK_R11                           0xffdc
#define XK_F32                           0xffdd
#define XK_R12                           0xffdd
#define XK_F33                           0xffde
#define XK_R13                           0xffde
#define XK_F34                           0xffdf
#define XK_R14                           0xffdf
#define XK_F35                           0xffe0
#define XK_R15                           0xffe0

/* Modifiers */

#define XK_Shift_L                       0xffe1  /* Left shift */
#define XK_Shift_R                       0xffe2  /* Right shift */
#define XK_Control_L                     0xffe3  /* Left control */
#define XK_Control_R                     0xffe4  /* Right control */
#define XK_Caps_Lock                     0xffe5  /* Caps lock */
#define XK_Shift_Lock                    0xffe6  /* Shift lock */

#define XK_Meta_L                        0xffe7  /* Left meta */
#define XK_Meta_R                        0xffe8  /* Right meta */
#define XK_Alt_L                         0xffe9  /* Left alt */
#define XK_Alt_R                         0xffea  /* Right alt */
#define XK_Super_L                       0xffeb  /* Left super */
#define XK_Super_R                       0xffec  /* Right super */
#define XK_Hyper_L                       0xffed  /* Left hyper */
#define XK_Hyper_R                       0xffee  /* Right hyper */
#endif /* XK_MISCELLANY */

/*
 * Keyboard (XKB) Extension function and modifier keys
 * (from Appendix C of "The X Keyboard Extension: Protocol Specification")
 * Byte 3 = 0xfe
 */

#ifdef XK_XKB_KEYS
#define XK_ISO_Lock                      0xfe01
#define XK_ISO_Level2_Latch              0xfe02
#define XK_ISO_Level3_Shift              0xfe03
#define XK_ISO_Level3_Latch              0xfe04
#define XK_ISO_Level3_Lock               0xfe05
#define XK_ISO_Level5_Shift              0xfe11
#define XK_ISO_Level5_Latch              0xfe12
#define XK_ISO_Level5_Lock               0xfe13
#define XK_ISO_Group_Shift               0xff7e  /* Alias for mode_switch */
#define XK_ISO_Group_Latch               0xfe06
#define XK_ISO_Group_Lock                0xfe07
#define XK_ISO_Next_Group                0xfe08
#define XK_ISO_Next_Group_Lock           0xfe09
#define XK_ISO_Prev_Group                0xfe0a
#define XK_ISO_Prev_Group_Lock           0xfe0b
#define XK_ISO_First_Group               0xfe0c
#define XK_ISO_First_Group_Lock          0xfe0d
#define XK_ISO_Last_Group                0xfe0e
#define XK_ISO_Last_Group_Lock           0xfe0f

#define XK_ISO_Left_Tab                  0xfe20
#define XK_ISO_Move_Line_Up              0xfe21
#define XK_ISO_Move_Line_Down            0xfe22
#define XK_ISO_Partial_Line_Up           0xfe23
#define XK_ISO_Partial_Line_Down         0xfe24
#define XK_ISO_Partial_Space_Left        0xfe25
#define XK_ISO_Partial_Space_Right       0xfe26
#define XK_ISO_Set_Margin_Left           0xfe27
#define XK_ISO_Set_Margin_Right          0xfe28
#define XK_ISO_Release_Margin_Left       0xfe29
#define XK_ISO_Release_Margin_Right      0xfe2a
#define XK_ISO_Release_Both_Margins      0xfe2b
#define XK_ISO_Fast_Cursor_Left          0xfe2c
#define XK_ISO_Fast_Cursor_Right         0xfe2d
#define XK_ISO_Fast_Cursor_Up            0xfe2e
#define XK_ISO_Fast_Cursor_Down          0xfe2f
#define XK_ISO_Continuous_Underline      0xfe30
#define XK_ISO_Discontinuous_Underline   0xfe31
#define XK_ISO_Emphasize                 0xfe32
#define XK_ISO_Center_Object             0xfe33
#define XK_ISO_Enter                     0xfe34

#define XK_dead_grave                    0xfe50
#define XK_dead_acute                    0xfe51
#define XK_dead_circumflex               0xfe52
#define XK_dead_tilde                    0xfe53
#define XK_dead_perispomeni              0xfe53  /* alias for dead_tilde */
#define XK_dead_macron                   0xfe54
#define XK_dead_breve                    0xfe55
#define XK_dead_abovedot                 0xfe56
#define XK_dead_diaeresis                0xfe57
#define XK_dead_abovering                0xfe58
#define XK_dead_doubleacute              0xfe59
#define XK_dead_caron                    0xfe5a
#define XK_dead_cedilla                  0xfe5b
#define XK_dead_ogonek                   0xfe5c
#define XK_dead_iota                     0xfe5d
#define XK_dead_voiced_sound             0xfe5e
#define XK_dead_semivoiced_sound         0xfe5f
#define XK_dead_belowdot                 0xfe60
#define XK_dead_hook                     0xfe61
#define XK_dead_horn                     0xfe62
#define XK_dead_stroke                   0xfe63
#define XK_dead_abovecomma               0xfe64
#define XK_dead_psili                    0xfe64  /* alias for dead_abovecomma */
#define XK_dead_abovereversedcomma       0xfe65
#define XK_dead_dasia                    0xfe65  /* alias for dead_abovereversedcomma */
#define XK_dead_doublegrave              0xfe66
#define XK_dead_belowring                0xfe67
#define XK_dead_belowmacron              0xfe68
#define XK_dead_belowcircumflex          0xfe69
#define XK_dead_belowtilde               0xfe6a
#define XK_dead_belowbreve               0xfe6b
#define XK_dead_belowdiaeresis           0xfe6c
#define XK_dead_invertedbreve            0xfe6d
#define XK_dead_belowcomma               0xfe6e
#define XK_dead_currency                 0xfe6f

/* extra dead elements for German T3 layout */
#define XK_dead_lowline                  0xfe90
#define XK_dead_aboveverticalline        0xfe91
#define XK_dead_belowverticalline        0xfe92
#define XK_dead_longsolidusoverlay       0xfe93

/* dead vowels for universal syllable entry */
#define XK_dead_a                        0xfe80
#define XK_dead_A                        0xfe81
#define XK_dead_e                        0xfe82
#define XK_dead_E                        0xfe83
#define XK_dead_i                        0xfe84
#define XK_dead_I                        0xfe85
#define XK_dead_o                        0xfe86
#define XK_dead_O                        0xfe87
#define XK_dead_u                        0xfe88
#define XK_dead_U                        0xfe89
#define XK_dead_small_schwa              0xfe8a
#define XK_dead_capital_schwa            0xfe8b

#define XK_dead_greek                    0xfe8c

#define XK_First_Virtual_Screen          0xfed0
#define XK_Prev_Virtual_Screen           0xfed1
#define XK_Next_Virtual_Screen           0xfed2
#define XK_Last_Virtual_Screen           0xfed4
#define XK_Terminate_Server              0xfed5

#define XK_AccessX_Enable                0xfe70
#define XK_AccessX_Feedback_Enable       0xfe71
#define XK_RepeatKeys_Enable             0xfe72
#define XK_SlowKeys_Enable               0xfe73
#define XK_BounceKeys_Enable             0xfe74
#define XK_StickyKeys_Enable             0xfe75
#define XK_MouseKeys_Enable              0xfe76
#define XK_MouseKeys_Accel_Enable        0xfe77
#define XK_Overlay1_Enable               0xfe78
#define XK_Overlay2_Enable               0xfe79
#define XK_AudibleBell_Enable            0xfe7a

#define XK_Pointer_Left                  0xfee0
#define XK_Pointer_Right                 0xfee1
#define XK_Pointer_Up                    0xfee2
#define XK_Pointer_Down                  0xfee3
#define XK_Pointer_UpLeft                0xfee4
#define XK_Pointer_UpRight               0xfee5
#define XK_Pointer_DownLeft              0xfee6
#define XK_Pointer_DownRight             0xfee7
#define XK_Pointer_Button_Dflt           0xfee8
#define XK_Pointer_Button1               0xfee9
#define XK_Pointer_Button2               0xfeea
#define XK_Pointer_Button3               0xfeeb
#define XK_Pointer_Button4               0xfeec
#define XK_Pointer_Button5               0xfeed
#define XK_Pointer_DblClick_Dflt         0xfeee
#define XK_Pointer_DblClick1             0xfeef
#define XK_Pointer_DblClick2             0xfef0
#define XK_Pointer_DblClick3             0xfef1
#define XK_Pointer_DblClick4             0xfef2
#define XK_Pointer_DblClick5             0xfef3
#define XK_Pointer_Drag_Dflt             0xfef4
#define XK_Pointer_Drag1                 0xfef5
#define XK_Pointer_Drag2                 0xfef6
#define XK_Pointer_Drag3                 0xfef7
#define XK_Pointer_Drag4                 0xfef8
#define XK_Pointer_Drag5                 0xfefd

#define XK_Pointer_EnableKeys            0xfef9
#define XK_Pointer_Accelerate            0xfefa
#define XK_Pointer_DfltBtnNext           0xfefb
#define XK_Pointer_DfltBtnPrev           0xfefc

/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */

#define XK_ch                            0xfea0
#define XK_Ch                            0xfea1
#define XK_CH                            0xfea2
#define XK_c_h                           0xfea3
#define XK_C_h                           0xfea4
#define XK_C_H                           0xfea5

#endif /* XK_XKB_KEYS */

/*
 * 3270 Terminal Keys
 * Byte 3 = 0xfd
 */

#ifdef XK_3270
#define XK_3270_Duplicate                0xfd01
#define XK_3270_FieldMark                0xfd02
#define XK_3270_Right2                   0xfd03
#define XK_3270_Left2                    0xfd04
#define XK_3270_BackTab                  0xfd05
#define XK_3270_EraseEOF                 0xfd06
#define XK_3270_EraseInput               0xfd07
#define XK_3270_Reset                    0xfd08
#define XK_3270_Quit                     0xfd09
#define XK_3270_PA1                      0xfd0a
#define XK_3270_PA2                      0xfd0b
#define XK_3270_PA3                      0xfd0c
#define XK_3270_Test                     0xfd0d
#define XK_3270_Attn                     0xfd0e
#define XK_3270_CursorBlink              0xfd0f
#define XK_3270_AltCursor                0xfd10
#define XK_3270_KeyClick                 0xfd11
#define XK_3270_Jump                     0xfd12
#define XK_3270_Ident                    0xfd13
#define XK_3270_Rule                     0xfd14
#define XK_3270_Copy                     0xfd15
#define XK_3270_Play                     0xfd16
#define XK_3270_Setup                    0xfd17
#define XK_3270_Record                   0xfd18
#define XK_3270_ChangeScreen             0xfd19
#define XK_3270_DeleteWord               0xfd1a
#define XK_3270_ExSelect                 0xfd1b
#define XK_3270_CursorSelect             0xfd1c
#define XK_3270_PrintScreen              0xfd1d
#define XK_3270_Enter                    0xfd1e
#endif /* XK_3270 */

/*
 * Latin 1
 * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
 * Byte 3 = 0
 */
#ifdef XK_LATIN1
#define XK_space                         0x0020  /* U+0020 SPACE */
#define XK_exclam                        0x0021  /* U+0021 EXCLAMATION MARK */
#define XK_quotedbl                      0x0022  /* U+0022 QUOTATION MARK */
#define XK_numbersign                    0x0023  /* U+0023 NUMBER SIGN */
#define XK_dollar                        0x0024  /* U+0024 DOLLAR SIGN */
#define XK_percent                       0x0025  /* U+0025 PERCENT SIGN */
#define XK_ampersand                     0x0026  /* U+0026 AMPERSAND */
#define XK_apostrophe                    0x0027  /* U+0027 APOSTROPHE */
#define XK_quoteright                    0x0027  /* deprecated */
#define XK_parenleft                     0x0028  /* U+0028 LEFT PARENTHESIS */
#define XK_parenright                    0x0029  /* U+0029 RIGHT PARENTHESIS */
#define XK_asterisk                      0x002a  /* U+002A ASTERISK */
#define XK_plus                          0x002b  /* U+002B PLUS SIGN */
#define XK_comma                         0x002c  /* U+002C COMMA */
#define XK_minus                         0x002d  /* U+002D HYPHEN-MINUS */
#define XK_period                        0x002e  /* U+002E FULL STOP */
#define XK_slash                         0x002f  /* U+002F SOLIDUS */
#define XK_0                             0x0030  /* U+0030 DIGIT ZERO */
#define XK_1                             0x0031  /* U+0031 DIGIT ONE */
#define XK_2                             0x0032  /* U+0032 DIGIT TWO */
#define XK_3                             0x0033  /* U+0033 DIGIT THREE */
#define XK_4                             0x0034  /* U+0034 DIGIT FOUR */
#define XK_5                             0x0035  /* U+0035 DIGIT FIVE */
#define XK_6                             0x0036  /* U+0036 DIGIT SIX */
#define XK_7                             0x0037  /* U+0037 DIGIT SEVEN */
#define XK_8                             0x0038  /* U+0038 DIGIT EIGHT */
#define XK_9                             0x0039  /* U+0039 DIGIT NINE */
#define XK_colon                         0x003a  /* U+003A COLON */
#define XK_semicolon                     0x003b  /* U+003B SEMICOLON */
#define XK_less                          0x003c  /* U+003C LESS-THAN SIGN */
#define XK_equal                         0x003d  /* U+003D EQUALS SIGN */
#define XK_greater                       0x003e  /* U+003E GREATER-THAN SIGN */
#define XK_question                      0x003f  /* U+003F QUESTION MARK */
#define XK_at                            0x0040  /* U+0040 COMMERCIAL AT */
#define XK_A                             0x0041  /* U+0041 LATIN CAPITAL LETTER A */
#define XK_B                             0x0042  /* U+0042 LATIN CAPITAL LETTER B */
#define XK_C                             0x0043  /* U+0043 LATIN CAPITAL LETTER C */
#define XK_D                             0x0044  /* U+0044 LATIN CAPITAL LETTER D */
#define XK_E                             0x0045  /* U+0045 LATIN CAPITAL LETTER E */
#define XK_F                             0x0046  /* U+0046 LATIN CAPITAL LETTER F */
#define XK_G                             0x0047  /* U+0047 LATIN CAPITAL LETTER G */
#define XK_H                             0x0048  /* U+0048 LATIN CAPITAL LETTER H */
#define XK_I                             0x0049  /* U+0049 LATIN CAPITAL LETTER I */
#define XK_J                             0x004a  /* U+004A LATIN CAPITAL LETTER J */
#define XK_K                             0x004b  /* U+004B LATIN CAPITAL LETTER K */
#define XK_L                             0x004c  /* U+004C LATIN CAPITAL LETTER L */
#define XK_M                             0x004d  /* U+004D LATIN CAPITAL LETTER M */
#define XK_N                             0x004e  /* U+004E LATIN CAPITAL LETTER N */
#define XK_O                             0x004f  /* U+004F LATIN CAPITAL LETTER O */
#define XK_P                             0x0050  /* U+0050 LATIN CAPITAL LETTER P */
#define XK_Q                             0x0051  /* U+0051 LATIN CAPITAL LETTER Q */
#define XK_R                             0x0052  /* U+0052 LATIN CAPITAL LETTER R */
#define XK_S                             0x0053  /* U+0053 LATIN CAPITAL LETTER S */
#define XK_T                             0x0054  /* U+0054 LATIN CAPITAL LETTER T */
#define XK_U                             0x0055  /* U+0055 LATIN CAPITAL LETTER U */
#define XK_V                             0x0056  /* U+0056 LATIN CAPITAL LETTER V */
#define XK_W                             0x0057  /* U+0057 LATIN CAPITAL LETTER W */
#define XK_X                             0x0058  /* U+0058 LATIN CAPITAL LETTER X */
#define XK_Y                             0x0059  /* U+0059 LATIN CAPITAL LETTER Y */
#define XK_Z                             0x005a  /* U+005A LATIN CAPITAL LETTER Z */
#define XK_bracketleft                   0x005b  /* U+005B LEFT SQUARE BRACKET */
#define XK_backslash                     0x005c  /* U+005C REVERSE SOLIDUS */
#define XK_bracketright                  0x005d  /* U+005D RIGHT SQUARE BRACKET */
#define XK_asciicircum                   0x005e  /* U+005E CIRCUMFLEX ACCENT */
#define XK_underscore                    0x005f  /* U+005F LOW LINE */
#define XK_grave                         0x0060  /* U+0060 GRAVE ACCENT */
#define XK_quoteleft                     0x0060  /* deprecated */
#define XK_a                             0x0061  /* U+0061 LATIN SMALL LETTER A */
#define XK_b                             0x0062  /* U+0062 LATIN SMALL LETTER B */
#define XK_c                             0x0063  /* U+0063 LATIN SMALL LETTER C */
#define XK_d                             0x0064  /* U+0064 LATIN SMALL LETTER D */
#define XK_e                             0x0065  /* U+0065 LATIN SMALL LETTER E */
#define XK_f                             0x0066  /* U+0066 LATIN SMALL LETTER F */
#define XK_g                             0x0067  /* U+0067 LATIN SMALL LETTER G */
#define XK_h                             0x0068  /* U+0068 LATIN SMALL LETTER H */
#define XK_i                             0x0069  /* U+0069 LATIN SMALL LETTER I */
#define XK_j                             0x006a  /* U+006A LATIN SMALL LETTER J */
#define XK_k                             0x006b  /* U+006B LATIN SMALL LETTER K */
#define XK_l                             0x006c  /* U+006C LATIN SMALL LETTER L */
#define XK_m                             0x006d  /* U+006D LATIN SMALL LETTER M */
#define XK_n                             0x006e  /* U+006E LATIN SMALL LETTER N */
#define XK_o                             0x006f  /* U+006F LATIN SMALL LETTER O */
#define XK_p                             0x0070  /* U+0070 LATIN SMALL LETTER P */
#define XK_q                             0x0071  /* U+0071 LATIN SMALL LETTER Q */
#define XK_r                             0x0072  /* U+0072 LATIN SMALL LETTER R */
#define XK_s                             0x0073  /* U+0073 LATIN SMALL LETTER S */
#define XK_t                             0x0074  /* U+0074 LATIN SMALL LETTER T */
#define XK_u                             0x0075  /* U+0075 LATIN SMALL LETTER U */
#define XK_v                             0x0076  /* U+0076 LATIN SMALL LETTER V */
#define XK_w                             0x0077  /* U+0077 LATIN SMALL LETTER W */
#define XK_x                             0x0078  /* U+0078 LATIN SMALL LETTER X */
#define XK_y                             0x0079  /* U+0079 LATIN SMALL LETTER Y */
#define XK_z                             0x007a  /* U+007A LATIN SMALL LETTER Z */
#define XK_braceleft                     0x007b  /* U+007B LEFT CURLY BRACKET */
#define XK_bar                           0x007c  /* U+007C VERTICAL LINE */
#define XK_braceright                    0x007d  /* U+007D RIGHT CURLY BRACKET */
#define XK_asciitilde                    0x007e  /* U+007E TILDE */

#define XK_nobreakspace                  0x00a0  /* U+00A0 NO-BREAK SPACE */
#define XK_exclamdown                    0x00a1  /* U+00A1 INVERTED EXCLAMATION MARK */
#define XK_cent                          0x00a2  /* U+00A2 CENT SIGN */
#define XK_sterling                      0x00a3  /* U+00A3 POUND SIGN */
#define XK_currency                      0x00a4  /* U+00A4 CURRENCY SIGN */
#define XK_yen                           0x00a5  /* U+00A5 YEN SIGN */
#define XK_brokenbar                     0x00a6  /* U+00A6 BROKEN BAR */
#define XK_section                       0x00a7  /* U+00A7 SECTION SIGN */
#define XK_diaeresis                     0x00a8  /* U+00A8 DIAERESIS */
#define XK_copyright                     0x00a9  /* U+00A9 COPYRIGHT SIGN */
#define XK_ordfeminine                   0x00aa  /* U+00AA FEMININE ORDINAL INDICATOR */
#define XK_guillemotleft                 0x00ab  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_notsign                       0x00ac  /* U+00AC NOT SIGN */
#define XK_hyphen                        0x00ad  /* U+00AD SOFT HYPHEN */
#define XK_registered                    0x00ae  /* U+00AE REGISTERED SIGN */
#define XK_macron                        0x00af  /* U+00AF MACRON */
#define XK_degree                        0x00b0  /* U+00B0 DEGREE SIGN */
#define XK_plusminus                     0x00b1  /* U+00B1 PLUS-MINUS SIGN */
#define XK_twosuperior                   0x00b2  /* U+00B2 SUPERSCRIPT TWO */
#define XK_threesuperior                 0x00b3  /* U+00B3 SUPERSCRIPT THREE */
#define XK_acute                         0x00b4  /* U+00B4 ACUTE ACCENT */
#define XK_mu                            0x00b5  /* U+00B5 MICRO SIGN */
#define XK_paragraph                     0x00b6  /* U+00B6 PILCROW SIGN */
#define XK_periodcentered                0x00b7  /* U+00B7 MIDDLE DOT */
#define XK_cedilla                       0x00b8  /* U+00B8 CEDILLA */
#define XK_onesuperior                   0x00b9  /* U+00B9 SUPERSCRIPT ONE */
#define XK_masculine                     0x00ba  /* U+00BA MASCULINE ORDINAL INDICATOR */
#define XK_guillemotright                0x00bb  /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_onequarter                    0x00bc  /* U+00BC VULGAR FRACTION ONE QUARTER */
#define XK_onehalf                       0x00bd  /* U+00BD VULGAR FRACTION ONE HALF */
#define XK_threequarters                 0x00be  /* U+00BE VULGAR FRACTION THREE QUARTERS */
#define XK_questiondown                  0x00bf  /* U+00BF INVERTED QUESTION MARK */
#define XK_Agrave                        0x00c0  /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
#define XK_Aacute                        0x00c1  /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
#define XK_Acircumflex                   0x00c2  /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
#define XK_Atilde                        0x00c3  /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
#define XK_Adiaeresis                    0x00c4  /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
#define XK_Aring                         0x00c5  /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
#define XK_AE                            0x00c6  /* U+00C6 LATIN CAPITAL LETTER AE */
#define XK_Ccedilla                      0x00c7  /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
#define XK_Egrave                        0x00c8  /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
#define XK_Eacute                        0x00c9  /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
#define XK_Ecircumflex                   0x00ca  /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
#define XK_Ediaeresis                    0x00cb  /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
#define XK_Igrave                        0x00cc  /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
#define XK_Iacute                        0x00cd  /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
#define XK_Icircumflex                   0x00ce  /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
#define XK_Idiaeresis                    0x00cf  /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
#define XK_ETH                           0x00d0  /* U+00D0 LATIN CAPITAL LETTER ETH */
#define XK_Eth                           0x00d0  /* deprecated */
#define XK_Ntilde                        0x00d1  /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
#define XK_Ograve                        0x00d2  /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
#define XK_Oacute                        0x00d3  /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
#define XK_Ocircumflex                   0x00d4  /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
#define XK_Otilde                        0x00d5  /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
#define XK_Odiaeresis                    0x00d6  /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
#define XK_multiply                      0x00d7  /* U+00D7 MULTIPLICATION SIGN */
#define XK_Oslash                        0x00d8  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
#define XK_Ooblique                      0x00d8  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
#define XK_Ugrave                        0x00d9  /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
#define XK_Uacute                        0x00da  /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
#define XK_Ucircumflex                   0x00db  /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
#define XK_Udiaeresis                    0x00dc  /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
#define XK_Yacute                        0x00dd  /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
#define XK_THORN                         0x00de  /* U+00DE LATIN CAPITAL LETTER THORN */
#define XK_Thorn                         0x00de  /* deprecated */
#define XK_ssharp                        0x00df  /* U+00DF LATIN SMALL LETTER SHARP S */
#define XK_agrave                        0x00e0  /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
#define XK_aacute                        0x00e1  /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
#define XK_acircumflex                   0x00e2  /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
#define XK_atilde                        0x00e3  /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
#define XK_adiaeresis                    0x00e4  /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
#define XK_aring                         0x00e5  /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
#define XK_ae                            0x00e6  /* U+00E6 LATIN SMALL LETTER AE */
#define XK_ccedilla                      0x00e7  /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
#define XK_egrave                        0x00e8  /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
#define XK_eacute                        0x00e9  /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
#define XK_ecircumflex                   0x00ea  /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
#define XK_ediaeresis                    0x00eb  /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
#define XK_igrave                        0x00ec  /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
#define XK_iacute                        0x00ed  /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
#define XK_icircumflex                   0x00ee  /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
#define XK_idiaeresis                    0x00ef  /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
#define XK_eth                           0x00f0  /* U+00F0 LATIN SMALL LETTER ETH */
#define XK_ntilde                        0x00f1  /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
#define XK_ograve                        0x00f2  /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
#define XK_oacute                        0x00f3  /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
#define XK_ocircumflex                   0x00f4  /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
#define XK_otilde                        0x00f5  /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
#define XK_odiaeresis                    0x00f6  /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
#define XK_division                      0x00f7  /* U+00F7 DIVISION SIGN */
#define XK_oslash                        0x00f8  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
#define XK_ooblique                      0x00f8  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
#define XK_ugrave                        0x00f9  /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
#define XK_uacute                        0x00fa  /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
#define XK_ucircumflex                   0x00fb  /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
#define XK_udiaeresis                    0x00fc  /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
#define XK_yacute                        0x00fd  /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
#define XK_thorn                         0x00fe  /* U+00FE LATIN SMALL LETTER THORN */
#define XK_ydiaeresis                    0x00ff  /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
#endif /* XK_LATIN1 */

/*
 * Latin 2
 * Byte 3 = 1
 */

#ifdef XK_LATIN2
#define XK_Aogonek                       0x01a1  /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */
#define XK_breve                         0x01a2  /* U+02D8 BREVE */
#define XK_Lstroke                       0x01a3  /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
#define XK_Lcaron                        0x01a5  /* U+013D LATIN CAPITAL LETTER L WITH CARON */
#define XK_Sacute                        0x01a6  /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */
#define XK_Scaron                        0x01a9  /* U+0160 LATIN CAPITAL LETTER S WITH CARON */
#define XK_Scedilla                      0x01aa  /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */
#define XK_Tcaron                        0x01ab  /* U+0164 LATIN CAPITAL LETTER T WITH CARON */
#define XK_Zacute                        0x01ac  /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */
#define XK_Zcaron                        0x01ae  /* U+017D LATIN CAPITAL LETTER Z WITH CARON */
#define XK_Zabovedot                     0x01af  /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */
#define XK_aogonek                       0x01b1  /* U+0105 LATIN SMALL LETTER A WITH OGONEK */
#define XK_ogonek                        0x01b2  /* U+02DB OGONEK */
#define XK_lstroke                       0x01b3  /* U+0142 LATIN SMALL LETTER L WITH STROKE */
#define XK_lcaron                        0x01b5  /* U+013E LATIN SMALL LETTER L WITH CARON */
#define XK_sacute                        0x01b6  /* U+015B LATIN SMALL LETTER S WITH ACUTE */
#define XK_caron                         0x01b7  /* U+02C7 CARON */
#define XK_scaron                        0x01b9  /* U+0161 LATIN SMALL LETTER S WITH CARON */
#define XK_scedilla                      0x01ba  /* U+015F LATIN SMALL LETTER S WITH CEDILLA */
#define XK_tcaron                        0x01bb  /* U+0165 LATIN SMALL LETTER T WITH CARON */
#define XK_zacute                        0x01bc  /* U+017A LATIN SMALL LETTER Z WITH ACUTE */
#define XK_doubleacute                   0x01bd  /* U+02DD DOUBLE ACUTE ACCENT */
#define XK_zcaron                        0x01be  /* U+017E LATIN SMALL LETTER Z WITH CARON */
#define XK_zabovedot                     0x01bf  /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */
#define XK_Racute                        0x01c0  /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */
#define XK_Abreve                        0x01c3  /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */
#define XK_Lacute                        0x01c5  /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */
#define XK_Cacute                        0x01c6  /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */
#define XK_Ccaron                        0x01c8  /* U+010C LATIN CAPITAL LETTER C WITH CARON */
#define XK_Eogonek                       0x01ca  /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */
#define XK_Ecaron                        0x01cc  /* U+011A LATIN CAPITAL LETTER E WITH CARON */
#define XK_Dcaron                        0x01cf  /* U+010E LATIN CAPITAL LETTER D WITH CARON */
#define XK_Dstroke                       0x01d0  /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */
#define XK_Nacute                        0x01d1  /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */
#define XK_Ncaron                        0x01d2  /* U+0147 LATIN CAPITAL LETTER N WITH CARON */
#define XK_Odoubleacute                  0x01d5  /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
#define XK_Rcaron                        0x01d8  /* U+0158 LATIN CAPITAL LETTER R WITH CARON */
#define XK_Uring                         0x01d9  /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */
#define XK_Udoubleacute                  0x01db  /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
#define XK_Tcedilla                      0x01de  /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */
#define XK_racute                        0x01e0  /* U+0155 LATIN SMALL LETTER R WITH ACUTE */
#define XK_abreve                        0x01e3  /* U+0103 LATIN SMALL LETTER A WITH BREVE */
#define XK_lacute                        0x01e5  /* U+013A LATIN SMALL LETTER L WITH ACUTE */
#define XK_cacute                        0x01e6  /* U+0107 LATIN SMALL LETTER C WITH ACUTE */
#define XK_ccaron                        0x01e8  /* U+010D LATIN SMALL LETTER C WITH CARON */
#define XK_eogonek                       0x01ea  /* U+0119 LATIN SMALL LETTER E WITH OGONEK */
#define XK_ecaron                        0x01ec  /* U+011B LATIN SMALL LETTER E WITH CARON */
#define XK_dcaron                        0x01ef  /* U+010F LATIN SMALL LETTER D WITH CARON */
#define XK_dstroke                       0x01f0  /* U+0111 LATIN SMALL LETTER D WITH STROKE */
#define XK_nacute                        0x01f1  /* U+0144 LATIN SMALL LETTER N WITH ACUTE */
#define XK_ncaron                        0x01f2  /* U+0148 LATIN SMALL LETTER N WITH CARON */
#define XK_odoubleacute                  0x01f5  /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */

#define XK_rcaron                        0x01f8  /* U+0159 LATIN SMALL LETTER R WITH CARON */
#define XK_uring                         0x01f9  /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */
#define XK_udoubleacute                  0x01fb  /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */
#define XK_tcedilla                      0x01fe  /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */
#define XK_abovedot                      0x01ff  /* U+02D9 DOT ABOVE */
#endif /* XK_LATIN2 */

/*
 * Latin 3
 * Byte 3 = 2
 */

#ifdef XK_LATIN3
#define XK_Hstroke                       0x02a1  /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */
#define XK_Hcircumflex                   0x02a6  /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
#define XK_Iabovedot                     0x02a9  /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
#define XK_Gbreve                        0x02ab  /* U+011E LATIN CAPITAL LETTER G WITH BREVE */
#define XK_Jcircumflex                   0x02ac  /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
#define XK_hstroke                       0x02b1  /* U+0127 LATIN SMALL LETTER H WITH STROKE */
#define XK_hcircumflex                   0x02b6  /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */
#define XK_idotless                      0x02b9  /* U+0131 LATIN SMALL LETTER DOTLESS I */
#define XK_gbreve                        0x02bb  /* U+011F LATIN SMALL LETTER G WITH BREVE */
#define XK_jcircumflex                   0x02bc  /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */
#define XK_Cabovedot                     0x02c5  /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */
#define XK_Ccircumflex                   0x02c6  /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
#define XK_Gabovedot                     0x02d5  /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */
#define XK_Gcircumflex                   0x02d8  /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
#define XK_Ubreve                        0x02dd  /* U+016C LATIN CAPITAL LETTER U WITH BREVE */
#define XK_Scircumflex                   0x02de  /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
#define XK_cabovedot                     0x02e5  /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */
#define XK_ccircumflex                   0x02e6  /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */
#define XK_gabovedot                     0x02f5  /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */
#define XK_gcircumflex                   0x02f8  /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */
#define XK_ubreve                        0x02fd  /* U+016D LATIN SMALL LETTER U WITH BREVE */
#define XK_scircumflex                   0x02fe  /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */
#endif /* XK_LATIN3 */


/*
 * Latin 4
 * Byte 3 = 3
 */

#ifdef XK_LATIN4
#define XK_kra                           0x03a2  /* U+0138 LATIN SMALL LETTER KRA */
#define XK_kappa                         0x03a2  /* deprecated */
#define XK_Rcedilla                      0x03a3  /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */
#define XK_Itilde                        0x03a5  /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */
#define XK_Lcedilla                      0x03a6  /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */
#define XK_Emacron                       0x03aa  /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */
#define XK_Gcedilla                      0x03ab  /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */
#define XK_Tslash                        0x03ac  /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */
#define XK_rcedilla                      0x03b3  /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */
#define XK_itilde                        0x03b5  /* U+0129 LATIN SMALL LETTER I WITH TILDE */
#define XK_lcedilla                      0x03b6  /* U+013C LATIN SMALL LETTER L WITH CEDILLA */
#define XK_emacron                       0x03ba  /* U+0113 LATIN SMALL LETTER E WITH MACRON */
#define XK_gcedilla                      0x03bb  /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */
#define XK_tslash                        0x03bc  /* U+0167 LATIN SMALL LETTER T WITH STROKE */
#define XK_ENG                           0x03bd  /* U+014A LATIN CAPITAL LETTER ENG */
#define XK_eng                           0x03bf  /* U+014B LATIN SMALL LETTER ENG */
#define XK_Amacron                       0x03c0  /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */
#define XK_Iogonek                       0x03c7  /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */
#define XK_Eabovedot                     0x03cc  /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */
#define XK_Imacron                       0x03cf  /* U+012A LATIN CAPITAL LETTER I WITH MACRON */
#define XK_Ncedilla                      0x03d1  /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */
#define XK_Omacron                       0x03d2  /* U+014C LATIN CAPITAL LETTER O WITH MACRON */
#define XK_Kcedilla                      0x03d3  /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */
#define XK_Uogonek                       0x03d9  /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */
#define XK_Utilde                        0x03dd  /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */
#define XK_Umacron                       0x03de  /* U+016A LATIN CAPITAL LETTER U WITH MACRON */
#define XK_amacron                       0x03e0  /* U+0101 LATIN SMALL LETTER A WITH MACRON */
#define XK_iogonek                       0x03e7  /* U+012F LATIN SMALL LETTER I WITH OGONEK */
#define XK_eabovedot                     0x03ec  /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */
#define XK_imacron                       0x03ef  /* U+012B LATIN SMALL LETTER I WITH MACRON */
#define XK_ncedilla                      0x03f1  /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */
#define XK_omacron                       0x03f2  /* U+014D LATIN SMALL LETTER O WITH MACRON */
#define XK_kcedilla                      0x03f3  /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
#define XK_uogonek                       0x03f9  /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
#define XK_utilde                        0x03fd  /* U+0169 LATIN SMALL LETTER U WITH TILDE */
#define XK_umacron                       0x03fe  /* U+016B LATIN SMALL LETTER U WITH MACRON */
#endif /* XK_LATIN4 */

/*
 * Latin 8
 */
#ifdef XK_LATIN8
#define XK_Wcircumflex                0x1000174  /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
#define XK_wcircumflex                0x1000175  /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */
#define XK_Ycircumflex                0x1000176  /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
#define XK_ycircumflex                0x1000177  /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
#define XK_Babovedot                  0x1001e02  /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */
#define XK_babovedot                  0x1001e03  /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */
#define XK_Dabovedot                  0x1001e0a  /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */
#define XK_dabovedot                  0x1001e0b  /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */
#define XK_Fabovedot                  0x1001e1e  /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
#define XK_fabovedot                  0x1001e1f  /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */
#define XK_Mabovedot                  0x1001e40  /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */
#define XK_mabovedot                  0x1001e41  /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */
#define XK_Pabovedot                  0x1001e56  /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */
#define XK_pabovedot                  0x1001e57  /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */
#define XK_Sabovedot                  0x1001e60  /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */
#define XK_sabovedot                  0x1001e61  /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */
#define XK_Tabovedot                  0x1001e6a  /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */
#define XK_tabovedot                  0x1001e6b  /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */
#define XK_Wgrave                     0x1001e80  /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */
#define XK_wgrave                     0x1001e81  /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */
#define XK_Wacute                     0x1001e82  /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */
#define XK_wacute                     0x1001e83  /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */
#define XK_Wdiaeresis                 0x1001e84  /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */
#define XK_wdiaeresis                 0x1001e85  /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
#define XK_Ygrave                     0x1001ef2  /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
#define XK_ygrave                     0x1001ef3  /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */
#endif /* XK_LATIN8 */

/*
 * Latin 9
 * Byte 3 = 0x13
 */

#ifdef XK_LATIN9
#define XK_OE                            0x13bc  /* U+0152 LATIN CAPITAL LIGATURE OE */
#define XK_oe                            0x13bd  /* U+0153 LATIN SMALL LIGATURE OE */
#define XK_Ydiaeresis                    0x13be  /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */
#endif /* XK_LATIN9 */

/*
 * Katakana
 * Byte 3 = 4
 */

#ifdef XK_KATAKANA
#define XK_overline                      0x047e  /* U+203E OVERLINE */
#define XK_kana_fullstop                 0x04a1  /* U+3002 IDEOGRAPHIC FULL STOP */
#define XK_kana_openingbracket           0x04a2  /* U+300C LEFT CORNER BRACKET */
#define XK_kana_closingbracket           0x04a3  /* U+300D RIGHT CORNER BRACKET */
#define XK_kana_comma                    0x04a4  /* U+3001 IDEOGRAPHIC COMMA */
#define XK_kana_conjunctive              0x04a5  /* U+30FB KATAKANA MIDDLE DOT */
#define XK_kana_middledot                0x04a5  /* deprecated */
#define XK_kana_WO                       0x04a6  /* U+30F2 KATAKANA LETTER WO */
#define XK_kana_a                        0x04a7  /* U+30A1 KATAKANA LETTER SMALL A */
#define XK_kana_i                        0x04a8  /* U+30A3 KATAKANA LETTER SMALL I */
#define XK_kana_u                        0x04a9  /* U+30A5 KATAKANA LETTER SMALL U */
#define XK_kana_e                        0x04aa  /* U+30A7 KATAKANA LETTER SMALL E */
#define XK_kana_o                        0x04ab  /* U+30A9 KATAKANA LETTER SMALL O */
#define XK_kana_ya                       0x04ac  /* U+30E3 KATAKANA LETTER SMALL YA */
#define XK_kana_yu                       0x04ad  /* U+30E5 KATAKANA LETTER SMALL YU */
#define XK_kana_yo                       0x04ae  /* U+30E7 KATAKANA LETTER SMALL YO */
#define XK_kana_tsu                      0x04af  /* U+30C3 KATAKANA LETTER SMALL TU */
#define XK_kana_tu                       0x04af  /* deprecated */
#define XK_prolongedsound                0x04b0  /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */
#define XK_kana_A                        0x04b1  /* U+30A2 KATAKANA LETTER A */
#define XK_kana_I                        0x04b2  /* U+30A4 KATAKANA LETTER I */
#define XK_kana_U                        0x04b3  /* U+30A6 KATAKANA LETTER U */
#define XK_kana_E                        0x04b4  /* U+30A8 KATAKANA LETTER E */
#define XK_kana_O                        0x04b5  /* U+30AA KATAKANA LETTER O */
#define XK_kana_KA                       0x04b6  /* U+30AB KATAKANA LETTER KA */
#define XK_kana_KI                       0x04b7  /* U+30AD KATAKANA LETTER KI */
#define XK_kana_KU                       0x04b8  /* U+30AF KATAKANA LETTER KU */
#define XK_kana_KE                       0x04b9  /* U+30B1 KATAKANA LETTER KE */
#define XK_kana_KO                       0x04ba  /* U+30B3 KATAKANA LETTER KO */
#define XK_kana_SA                       0x04bb  /* U+30B5 KATAKANA LETTER SA */
#define XK_kana_SHI                      0x04bc  /* U+30B7 KATAKANA LETTER SI */
#define XK_kana_SU                       0x04bd  /* U+30B9 KATAKANA LETTER SU */
#define XK_kana_SE                       0x04be  /* U+30BB KATAKANA LETTER SE */
#define XK_kana_SO                       0x04bf  /* U+30BD KATAKANA LETTER SO */
#define XK_kana_TA                       0x04c0  /* U+30BF KATAKANA LETTER TA */
#define XK_kana_CHI                      0x04c1  /* U+30C1 KATAKANA LETTER TI */
#define XK_kana_TI                       0x04c1  /* deprecated */
#define XK_kana_TSU                      0x04c2  /* U+30C4 KATAKANA LETTER TU */
#define XK_kana_TU                       0x04c2  /* deprecated */
#define XK_kana_TE                       0x04c3  /* U+30C6 KATAKANA LETTER TE */
#define XK_kana_TO                       0x04c4  /* U+30C8 KATAKANA LETTER TO */
#define XK_kana_NA                       0x04c5  /* U+30CA KATAKANA LETTER NA */
#define XK_kana_NI                       0x04c6  /* U+30CB KATAKANA LETTER NI */
#define XK_kana_NU                       0x04c7  /* U+30CC KATAKANA LETTER NU */
#define XK_kana_NE                       0x04c8  /* U+30CD KATAKANA LETTER NE */
#define XK_kana_NO                       0x04c9  /* U+30CE KATAKANA LETTER NO */
#define XK_kana_HA                       0x04ca  /* U+30CF KATAKANA LETTER HA */
#define XK_kana_HI                       0x04cb  /* U+30D2 KATAKANA LETTER HI */
#define XK_kana_FU                       0x04cc  /* U+30D5 KATAKANA LETTER HU */
#define XK_kana_HU                       0x04cc  /* deprecated */
#define XK_kana_HE                       0x04cd  /* U+30D8 KATAKANA LETTER HE */
#define XK_kana_HO                       0x04ce  /* U+30DB KATAKANA LETTER HO */
#define XK_kana_MA                       0x04cf  /* U+30DE KATAKANA LETTER MA */
#define XK_kana_MI                       0x04d0  /* U+30DF KATAKANA LETTER MI */
#define XK_kana_MU                       0x04d1  /* U+30E0 KATAKANA LETTER MU */
#define XK_kana_ME                       0x04d2  /* U+30E1 KATAKANA LETTER ME */
#define XK_kana_MO                       0x04d3  /* U+30E2 KATAKANA LETTER MO */
#define XK_kana_YA                       0x04d4  /* U+30E4 KATAKANA LETTER YA */
#define XK_kana_YU                       0x04d5  /* U+30E6 KATAKANA LETTER YU */
#define XK_kana_YO                       0x04d6  /* U+30E8 KATAKANA LETTER YO */
#define XK_kana_RA                       0x04d7  /* U+30E9 KATAKANA LETTER RA */
#define XK_kana_RI                       0x04d8  /* U+30EA KATAKANA LETTER RI */
#define XK_kana_RU                       0x04d9  /* U+30EB KATAKANA LETTER RU */
#define XK_kana_RE                       0x04da  /* U+30EC KATAKANA LETTER RE */
#define XK_kana_RO                       0x04db  /* U+30ED KATAKANA LETTER RO */
#define XK_kana_WA                       0x04dc  /* U+30EF KATAKANA LETTER WA */
#define XK_kana_N                        0x04dd  /* U+30F3 KATAKANA LETTER N */
#define XK_voicedsound                   0x04de  /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */
#define XK_semivoicedsound               0x04df  /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
#define XK_kana_switch                   0xff7e  /* Alias for mode_switch */
#endif /* XK_KATAKANA */

/*
 * Arabic
 * Byte 3 = 5
 */

#ifdef XK_ARABIC
#define XK_Farsi_0                    0x10006f0  /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */
#define XK_Farsi_1                    0x10006f1  /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */
#define XK_Farsi_2                    0x10006f2  /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */
#define XK_Farsi_3                    0x10006f3  /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */
#define XK_Farsi_4                    0x10006f4  /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */
#define XK_Farsi_5                    0x10006f5  /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */
#define XK_Farsi_6                    0x10006f6  /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */
#define XK_Farsi_7                    0x10006f7  /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */
#define XK_Farsi_8                    0x10006f8  /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */
#define XK_Farsi_9                    0x10006f9  /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */
#define XK_Arabic_percent             0x100066a  /* U+066A ARABIC PERCENT SIGN */
#define XK_Arabic_superscript_alef    0x1000670  /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */
#define XK_Arabic_tteh                0x1000679  /* U+0679 ARABIC LETTER TTEH */
#define XK_Arabic_peh                 0x100067e  /* U+067E ARABIC LETTER PEH */
#define XK_Arabic_tcheh               0x1000686  /* U+0686 ARABIC LETTER TCHEH */
#define XK_Arabic_ddal                0x1000688  /* U+0688 ARABIC LETTER DDAL */
#define XK_Arabic_rreh                0x1000691  /* U+0691 ARABIC LETTER RREH */
#define XK_Arabic_comma                  0x05ac  /* U+060C ARABIC COMMA */
#define XK_Arabic_fullstop            0x10006d4  /* U+06D4 ARABIC FULL STOP */
#define XK_Arabic_0                   0x1000660  /* U+0660 ARABIC-INDIC DIGIT ZERO */
#define XK_Arabic_1                   0x1000661  /* U+0661 ARABIC-INDIC DIGIT ONE */
#define XK_Arabic_2                   0x1000662  /* U+0662 ARABIC-INDIC DIGIT TWO */
#define XK_Arabic_3                   0x1000663  /* U+0663 ARABIC-INDIC DIGIT THREE */
#define XK_Arabic_4                   0x1000664  /* U+0664 ARABIC-INDIC DIGIT FOUR */
#define XK_Arabic_5                   0x1000665  /* U+0665 ARABIC-INDIC DIGIT FIVE */
#define XK_Arabic_6                   0x1000666  /* U+0666 ARABIC-INDIC DIGIT SIX */
#define XK_Arabic_7                   0x1000667  /* U+0667 ARABIC-INDIC DIGIT SEVEN */
#define XK_Arabic_8                   0x1000668  /* U+0668 ARABIC-INDIC DIGIT EIGHT */
#define XK_Arabic_9                   0x1000669  /* U+0669 ARABIC-INDIC DIGIT NINE */
#define XK_Arabic_semicolon              0x05bb  /* U+061B ARABIC SEMICOLON */
#define XK_Arabic_question_mark          0x05bf  /* U+061F ARABIC QUESTION MARK */
#define XK_Arabic_hamza                  0x05c1  /* U+0621 ARABIC LETTER HAMZA */
#define XK_Arabic_maddaonalef            0x05c2  /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
#define XK_Arabic_hamzaonalef            0x05c3  /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
#define XK_Arabic_hamzaonwaw             0x05c4  /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
#define XK_Arabic_hamzaunderalef         0x05c5  /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
#define XK_Arabic_hamzaonyeh             0x05c6  /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
#define XK_Arabic_alef                   0x05c7  /* U+0627 ARABIC LETTER ALEF */
#define XK_Arabic_beh                    0x05c8  /* U+0628 ARABIC LETTER BEH */
#define XK_Arabic_tehmarbuta             0x05c9  /* U+0629 ARABIC LETTER TEH MARBUTA */
#define XK_Arabic_teh                    0x05ca  /* U+062A ARABIC LETTER TEH */
#define XK_Arabic_theh                   0x05cb  /* U+062B ARABIC LETTER THEH */
#define XK_Arabic_jeem                   0x05cc  /* U+062C ARABIC LETTER JEEM */
#define XK_Arabic_hah                    0x05cd  /* U+062D ARABIC LETTER HAH */
#define XK_Arabic_khah                   0x05ce  /* U+062E ARABIC LETTER KHAH */
#define XK_Arabic_dal                    0x05cf  /* U+062F ARABIC LETTER DAL */
#define XK_Arabic_thal                   0x05d0  /* U+0630 ARABIC LETTER THAL */
#define XK_Arabic_ra                     0x05d1  /* U+0631 ARABIC LETTER REH */
#define XK_Arabic_zain                   0x05d2  /* U+0632 ARABIC LETTER ZAIN */
#define XK_Arabic_seen                   0x05d3  /* U+0633 ARABIC LETTER SEEN */
#define XK_Arabic_sheen                  0x05d4  /* U+0634 ARABIC LETTER SHEEN */
#define XK_Arabic_sad                    0x05d5  /* U+0635 ARABIC LETTER SAD */
#define XK_Arabic_dad                    0x05d6  /* U+0636 ARABIC LETTER DAD */
#define XK_Arabic_tah                    0x05d7  /* U+0637 ARABIC LETTER TAH */
#define XK_Arabic_zah                    0x05d8  /* U+0638 ARABIC LETTER ZAH */
#define XK_Arabic_ain                    0x05d9  /* U+0639 ARABIC LETTER AIN */
#define XK_Arabic_ghain                  0x05da  /* U+063A ARABIC LETTER GHAIN */
#define XK_Arabic_tatweel                0x05e0  /* U+0640 ARABIC TATWEEL */
#define XK_Arabic_feh                    0x05e1  /* U+0641 ARABIC LETTER FEH */
#define XK_Arabic_qaf                    0x05e2  /* U+0642 ARABIC LETTER QAF */
#define XK_Arabic_kaf                    0x05e3  /* U+0643 ARABIC LETTER KAF */
#define XK_Arabic_lam                    0x05e4  /* U+0644 ARABIC LETTER LAM */
#define XK_Arabic_meem                   0x05e5  /* U+0645 ARABIC LETTER MEEM */
#define XK_Arabic_noon                   0x05e6  /* U+0646 ARABIC LETTER NOON */
#define XK_Arabic_ha                     0x05e7  /* U+0647 ARABIC LETTER HEH */
#define XK_Arabic_heh                    0x05e7  /* deprecated */
#define XK_Arabic_waw                    0x05e8  /* U+0648 ARABIC LETTER WAW */
#define XK_Arabic_alefmaksura            0x05e9  /* U+0649 ARABIC LETTER ALEF MAKSURA */
#define XK_Arabic_yeh                    0x05ea  /* U+064A ARABIC LETTER YEH */
#define XK_Arabic_fathatan               0x05eb  /* U+064B ARABIC FATHATAN */
#define XK_Arabic_dammatan               0x05ec  /* U+064C ARABIC DAMMATAN */
#define XK_Arabic_kasratan               0x05ed  /* U+064D ARABIC KASRATAN */
#define XK_Arabic_fatha                  0x05ee  /* U+064E ARABIC FATHA */
#define XK_Arabic_damma                  0x05ef  /* U+064F ARABIC DAMMA */
#define XK_Arabic_kasra                  0x05f0  /* U+0650 ARABIC KASRA */
#define XK_Arabic_shadda                 0x05f1  /* U+0651 ARABIC SHADDA */
#define XK_Arabic_sukun                  0x05f2  /* U+0652 ARABIC SUKUN */
#define XK_Arabic_madda_above         0x1000653  /* U+0653 ARABIC MADDAH ABOVE */
#define XK_Arabic_hamza_above         0x1000654  /* U+0654 ARABIC HAMZA ABOVE */
#define XK_Arabic_hamza_below         0x1000655  /* U+0655 ARABIC HAMZA BELOW */
#define XK_Arabic_jeh                 0x1000698  /* U+0698 ARABIC LETTER JEH */
#define XK_Arabic_veh                 0x10006a4  /* U+06A4 ARABIC LETTER VEH */
#define XK_Arabic_keheh               0x10006a9  /* U+06A9 ARABIC LETTER KEHEH */
#define XK_Arabic_gaf                 0x10006af  /* U+06AF ARABIC LETTER GAF */
#define XK_Arabic_noon_ghunna         0x10006ba  /* U+06BA ARABIC LETTER NOON GHUNNA */
#define XK_Arabic_heh_doachashmee     0x10006be  /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
#define XK_Farsi_yeh                  0x10006cc  /* U+06CC ARABIC LETTER FARSI YEH */
#define XK_Arabic_farsi_yeh           0x10006cc  /* U+06CC ARABIC LETTER FARSI YEH */
#define XK_Arabic_yeh_baree           0x10006d2  /* U+06D2 ARABIC LETTER YEH BARREE */
#define XK_Arabic_heh_goal            0x10006c1  /* U+06C1 ARABIC LETTER HEH GOAL */
#define XK_Arabic_switch                 0xff7e  /* Alias for mode_switch */
#endif /* XK_ARABIC */

/*
 * Cyrillic
 * Byte 3 = 6
 */
#ifdef XK_CYRILLIC
#define XK_Cyrillic_GHE_bar           0x1000492  /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */
#define XK_Cyrillic_ghe_bar           0x1000493  /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */
#define XK_Cyrillic_ZHE_descender     0x1000496  /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
#define XK_Cyrillic_zhe_descender     0x1000497  /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */
#define XK_Cyrillic_KA_descender      0x100049a  /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
#define XK_Cyrillic_ka_descender      0x100049b  /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */
#define XK_Cyrillic_KA_vertstroke     0x100049c  /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
#define XK_Cyrillic_ka_vertstroke     0x100049d  /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */
#define XK_Cyrillic_EN_descender      0x10004a2  /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
#define XK_Cyrillic_en_descender      0x10004a3  /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */
#define XK_Cyrillic_U_straight        0x10004ae  /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */
#define XK_Cyrillic_u_straight        0x10004af  /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */
#define XK_Cyrillic_U_straight_bar    0x10004b0  /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
#define XK_Cyrillic_u_straight_bar    0x10004b1  /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */
#define XK_Cyrillic_HA_descender      0x10004b2  /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
#define XK_Cyrillic_ha_descender      0x10004b3  /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */
#define XK_Cyrillic_CHE_descender     0x10004b6  /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
#define XK_Cyrillic_che_descender     0x10004b7  /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */
#define XK_Cyrillic_CHE_vertstroke    0x10004b8  /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
#define XK_Cyrillic_che_vertstroke    0x10004b9  /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */
#define XK_Cyrillic_SHHA              0x10004ba  /* U+04BA CYRILLIC CAPITAL LETTER SHHA */
#define XK_Cyrillic_shha              0x10004bb  /* U+04BB CYRILLIC SMALL LETTER SHHA */

#define XK_Cyrillic_SCHWA             0x10004d8  /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */
#define XK_Cyrillic_schwa             0x10004d9  /* U+04D9 CYRILLIC SMALL LETTER SCHWA */
#define XK_Cyrillic_I_macron          0x10004e2  /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */
#define XK_Cyrillic_i_macron          0x10004e3  /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */
#define XK_Cyrillic_O_bar             0x10004e8  /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */
#define XK_Cyrillic_o_bar             0x10004e9  /* U+04E9 CYRILLIC SMALL LETTER BARRED O */
#define XK_Cyrillic_U_macron          0x10004ee  /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */
#define XK_Cyrillic_u_macron          0x10004ef  /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */

#define XK_Serbian_dje                   0x06a1  /* U+0452 CYRILLIC SMALL LETTER DJE */
#define XK_Macedonia_gje                 0x06a2  /* U+0453 CYRILLIC SMALL LETTER GJE */
#define XK_Cyrillic_io                   0x06a3  /* U+0451 CYRILLIC SMALL LETTER IO */
#define XK_Ukrainian_ie                  0x06a4  /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */
#define XK_Ukranian_je                   0x06a4  /* deprecated */
#define XK_Macedonia_dse                 0x06a5  /* U+0455 CYRILLIC SMALL LETTER DZE */
#define XK_Ukrainian_i                   0x06a6  /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
#define XK_Ukranian_i                    0x06a6  /* deprecated */
#define XK_Ukrainian_yi                  0x06a7  /* U+0457 CYRILLIC SMALL LETTER YI */
#define XK_Ukranian_yi                   0x06a7  /* deprecated */
#define XK_Cyrillic_je                   0x06a8  /* U+0458 CYRILLIC SMALL LETTER JE */
#define XK_Serbian_je                    0x06a8  /* deprecated */
#define XK_Cyrillic_lje                  0x06a9  /* U+0459 CYRILLIC SMALL LETTER LJE */
#define XK_Serbian_lje                   0x06a9  /* deprecated */
#define XK_Cyrillic_nje                  0x06aa  /* U+045A CYRILLIC SMALL LETTER NJE */
#define XK_Serbian_nje                   0x06aa  /* deprecated */
#define XK_Serbian_tshe                  0x06ab  /* U+045B CYRILLIC SMALL LETTER TSHE */
#define XK_Macedonia_kje                 0x06ac  /* U+045C CYRILLIC SMALL LETTER KJE */
#define XK_Ukrainian_ghe_with_upturn     0x06ad  /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */
#define XK_Byelorussian_shortu           0x06ae  /* U+045E CYRILLIC SMALL LETTER SHORT U */
#define XK_Cyrillic_dzhe                 0x06af  /* U+045F CYRILLIC SMALL LETTER DZHE */
#define XK_Serbian_dze                   0x06af  /* deprecated */
#define XK_numerosign                    0x06b0  /* U+2116 NUMERO SIGN */
#define XK_Serbian_DJE                   0x06b1  /* U+0402 CYRILLIC CAPITAL LETTER DJE */
#define XK_Macedonia_GJE                 0x06b2  /* U+0403 CYRILLIC CAPITAL LETTER GJE */
#define XK_Cyrillic_IO                   0x06b3  /* U+0401 CYRILLIC CAPITAL LETTER IO */
#define XK_Ukrainian_IE                  0x06b4  /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */
#define XK_Ukranian_JE                   0x06b4  /* deprecated */
#define XK_Macedonia_DSE                 0x06b5  /* U+0405 CYRILLIC CAPITAL LETTER DZE */
#define XK_Ukrainian_I                   0x06b6  /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
#define XK_Ukranian_I                    0x06b6  /* deprecated */
#define XK_Ukrainian_YI                  0x06b7  /* U+0407 CYRILLIC CAPITAL LETTER YI */
#define XK_Ukranian_YI                   0x06b7  /* deprecated */
#define XK_Cyrillic_JE                   0x06b8  /* U+0408 CYRILLIC CAPITAL LETTER JE */
#define XK_Serbian_JE                    0x06b8  /* deprecated */
#define XK_Cyrillic_LJE                  0x06b9  /* U+0409 CYRILLIC CAPITAL LETTER LJE */
#define XK_Serbian_LJE                   0x06b9  /* deprecated */
#define XK_Cyrillic_NJE                  0x06ba  /* U+040A CYRILLIC CAPITAL LETTER NJE */
#define XK_Serbian_NJE                   0x06ba  /* deprecated */
#define XK_Serbian_TSHE                  0x06bb  /* U+040B CYRILLIC CAPITAL LETTER TSHE */
#define XK_Macedonia_KJE                 0x06bc  /* U+040C CYRILLIC CAPITAL LETTER KJE */
#define XK_Ukrainian_GHE_WITH_UPTURN     0x06bd  /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
#define XK_Byelorussian_SHORTU           0x06be  /* U+040E CYRILLIC CAPITAL LETTER SHORT U */
#define XK_Cyrillic_DZHE                 0x06bf  /* U+040F CYRILLIC CAPITAL LETTER DZHE */
#define XK_Serbian_DZE                   0x06bf  /* deprecated */
#define XK_Cyrillic_yu                   0x06c0  /* U+044E CYRILLIC SMALL LETTER YU */
#define XK_Cyrillic_a                    0x06c1  /* U+0430 CYRILLIC SMALL LETTER A */
#define XK_Cyrillic_be                   0x06c2  /* U+0431 CYRILLIC SMALL LETTER BE */
#define XK_Cyrillic_tse                  0x06c3  /* U+0446 CYRILLIC SMALL LETTER TSE */
#define XK_Cyrillic_de                   0x06c4  /* U+0434 CYRILLIC SMALL LETTER DE */
#define XK_Cyrillic_ie                   0x06c5  /* U+0435 CYRILLIC SMALL LETTER IE */
#define XK_Cyrillic_ef                   0x06c6  /* U+0444 CYRILLIC SMALL LETTER EF */
#define XK_Cyrillic_ghe                  0x06c7  /* U+0433 CYRILLIC SMALL LETTER GHE */
#define XK_Cyrillic_ha                   0x06c8  /* U+0445 CYRILLIC SMALL LETTER HA */
#define XK_Cyrillic_i                    0x06c9  /* U+0438 CYRILLIC SMALL LETTER I */
#define XK_Cyrillic_shorti               0x06ca  /* U+0439 CYRILLIC SMALL LETTER SHORT I */
#define XK_Cyrillic_ka                   0x06cb  /* U+043A CYRILLIC SMALL LETTER KA */
#define XK_Cyrillic_el                   0x06cc  /* U+043B CYRILLIC SMALL LETTER EL */
#define XK_Cyrillic_em                   0x06cd  /* U+043C CYRILLIC SMALL LETTER EM */
#define XK_Cyrillic_en                   0x06ce  /* U+043D CYRILLIC SMALL LETTER EN */
#define XK_Cyrillic_o                    0x06cf  /* U+043E CYRILLIC SMALL LETTER O */
#define XK_Cyrillic_pe                   0x06d0  /* U+043F CYRILLIC SMALL LETTER PE */
#define XK_Cyrillic_ya                   0x06d1  /* U+044F CYRILLIC SMALL LETTER YA */
#define XK_Cyrillic_er                   0x06d2  /* U+0440 CYRILLIC SMALL LETTER ER */
#define XK_Cyrillic_es                   0x06d3  /* U+0441 CYRILLIC SMALL LETTER ES */
#define XK_Cyrillic_te                   0x06d4  /* U+0442 CYRILLIC SMALL LETTER TE */
#define XK_Cyrillic_u                    0x06d5  /* U+0443 CYRILLIC SMALL LETTER U */
#define XK_Cyrillic_zhe                  0x06d6  /* U+0436 CYRILLIC SMALL LETTER ZHE */
#define XK_Cyrillic_ve                   0x06d7  /* U+0432 CYRILLIC SMALL LETTER VE */
#define XK_Cyrillic_softsign             0x06d8  /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */
#define XK_Cyrillic_yeru                 0x06d9  /* U+044B CYRILLIC SMALL LETTER YERU */
#define XK_Cyrillic_ze                   0x06da  /* U+0437 CYRILLIC SMALL LETTER ZE */
#define XK_Cyrillic_sha                  0x06db  /* U+0448 CYRILLIC SMALL LETTER SHA */
#define XK_Cyrillic_e                    0x06dc  /* U+044D CYRILLIC SMALL LETTER E */
#define XK_Cyrillic_shcha                0x06dd  /* U+0449 CYRILLIC SMALL LETTER SHCHA */
#define XK_Cyrillic_che                  0x06de  /* U+0447 CYRILLIC SMALL LETTER CHE */
#define XK_Cyrillic_hardsign             0x06df  /* U+044A CYRILLIC SMALL LETTER HARD SIGN */
#define XK_Cyrillic_YU                   0x06e0  /* U+042E CYRILLIC CAPITAL LETTER YU */
#define XK_Cyrillic_A                    0x06e1  /* U+0410 CYRILLIC CAPITAL LETTER A */
#define XK_Cyrillic_BE                   0x06e2  /* U+0411 CYRILLIC CAPITAL LETTER BE */
#define XK_Cyrillic_TSE                  0x06e3  /* U+0426 CYRILLIC CAPITAL LETTER TSE */
#define XK_Cyrillic_DE                   0x06e4  /* U+0414 CYRILLIC CAPITAL LETTER DE */
#define XK_Cyrillic_IE                   0x06e5  /* U+0415 CYRILLIC CAPITAL LETTER IE */
#define XK_Cyrillic_EF                   0x06e6  /* U+0424 CYRILLIC CAPITAL LETTER EF */
#define XK_Cyrillic_GHE                  0x06e7  /* U+0413 CYRILLIC CAPITAL LETTER GHE */
#define XK_Cyrillic_HA                   0x06e8  /* U+0425 CYRILLIC CAPITAL LETTER HA */
#define XK_Cyrillic_I                    0x06e9  /* U+0418 CYRILLIC CAPITAL LETTER I */
#define XK_Cyrillic_SHORTI               0x06ea  /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */
#define XK_Cyrillic_KA                   0x06eb  /* U+041A CYRILLIC CAPITAL LETTER KA */
#define XK_Cyrillic_EL                   0x06ec  /* U+041B CYRILLIC CAPITAL LETTER EL */
#define XK_Cyrillic_EM                   0x06ed  /* U+041C CYRILLIC CAPITAL LETTER EM */
#define XK_Cyrillic_EN                   0x06ee  /* U+041D CYRILLIC CAPITAL LETTER EN */
#define XK_Cyrillic_O                    0x06ef  /* U+041E CYRILLIC CAPITAL LETTER O */
#define XK_Cyrillic_PE                   0x06f0  /* U+041F CYRILLIC CAPITAL LETTER PE */
#define XK_Cyrillic_YA                   0x06f1  /* U+042F CYRILLIC CAPITAL LETTER YA */
#define XK_Cyrillic_ER                   0x06f2  /* U+0420 CYRILLIC CAPITAL LETTER ER */
#define XK_Cyrillic_ES                   0x06f3  /* U+0421 CYRILLIC CAPITAL LETTER ES */
#define XK_Cyrillic_TE                   0x06f4  /* U+0422 CYRILLIC CAPITAL LETTER TE */
#define XK_Cyrillic_U                    0x06f5  /* U+0423 CYRILLIC CAPITAL LETTER U */
#define XK_Cyrillic_ZHE                  0x06f6  /* U+0416 CYRILLIC CAPITAL LETTER ZHE */
#define XK_Cyrillic_VE                   0x06f7  /* U+0412 CYRILLIC CAPITAL LETTER VE */
#define XK_Cyrillic_SOFTSIGN             0x06f8  /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */
#define XK_Cyrillic_YERU                 0x06f9  /* U+042B CYRILLIC CAPITAL LETTER YERU */
#define XK_Cyrillic_ZE                   0x06fa  /* U+0417 CYRILLIC CAPITAL LETTER ZE */
#define XK_Cyrillic_SHA                  0x06fb  /* U+0428 CYRILLIC CAPITAL LETTER SHA */
#define XK_Cyrillic_E                    0x06fc  /* U+042D CYRILLIC CAPITAL LETTER E */
#define XK_Cyrillic_SHCHA                0x06fd  /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
#define XK_Cyrillic_CHE                  0x06fe  /* U+0427 CYRILLIC CAPITAL LETTER CHE */
#define XK_Cyrillic_HARDSIGN             0x06ff  /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */
#endif /* XK_CYRILLIC */

/*
 * Greek
 * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7)
 * Byte 3 = 7
 */

#ifdef XK_GREEK
#define XK_Greek_ALPHAaccent             0x07a1  /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */
#define XK_Greek_EPSILONaccent           0x07a2  /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */
#define XK_Greek_ETAaccent               0x07a3  /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */
#define XK_Greek_IOTAaccent              0x07a4  /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */
#define XK_Greek_IOTAdieresis            0x07a5  /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
#define XK_Greek_IOTAdiaeresis           0x07a5  /* old typo */
#define XK_Greek_OMICRONaccent           0x07a7  /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */
#define XK_Greek_UPSILONaccent           0x07a8  /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */
#define XK_Greek_UPSILONdieresis         0x07a9  /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
#define XK_Greek_OMEGAaccent             0x07ab  /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */
#define XK_Greek_accentdieresis          0x07ae  /* U+0385 GREEK DIALYTIKA TONOS */
#define XK_Greek_horizbar                0x07af  /* U+2015 HORIZONTAL BAR */
#define XK_Greek_alphaaccent             0x07b1  /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */
#define XK_Greek_epsilonaccent           0x07b2  /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */
#define XK_Greek_etaaccent               0x07b3  /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */
#define XK_Greek_iotaaccent              0x07b4  /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */
#define XK_Greek_iotadieresis            0x07b5  /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */
#define XK_Greek_iotaaccentdieresis      0x07b6  /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
#define XK_Greek_omicronaccent           0x07b7  /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */
#define XK_Greek_upsilonaccent           0x07b8  /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */
#define XK_Greek_upsilondieresis         0x07b9  /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
#define XK_Greek_upsilonaccentdieresis   0x07ba  /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
#define XK_Greek_omegaaccent             0x07bb  /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */
#define XK_Greek_ALPHA                   0x07c1  /* U+0391 GREEK CAPITAL LETTER ALPHA */
#define XK_Greek_BETA                    0x07c2  /* U+0392 GREEK CAPITAL LETTER BETA */
#define XK_Greek_GAMMA                   0x07c3  /* U+0393 GREEK CAPITAL LETTER GAMMA */
#define XK_Greek_DELTA                   0x07c4  /* U+0394 GREEK CAPITAL LETTER DELTA */
#define XK_Greek_EPSILON                 0x07c5  /* U+0395 GREEK CAPITAL LETTER EPSILON */
#define XK_Greek_ZETA                    0x07c6  /* U+0396 GREEK CAPITAL LETTER ZETA */
#define XK_Greek_ETA                     0x07c7  /* U+0397 GREEK CAPITAL LETTER ETA */
#define XK_Greek_THETA                   0x07c8  /* U+0398 GREEK CAPITAL LETTER THETA */
#define XK_Greek_IOTA                    0x07c9  /* U+0399 GREEK CAPITAL LETTER IOTA */
#define XK_Greek_KAPPA                   0x07ca  /* U+039A GREEK CAPITAL LETTER KAPPA */
#define XK_Greek_LAMDA                   0x07cb  /* U+039B GREEK CAPITAL LETTER LAMDA */
#define XK_Greek_LAMBDA                  0x07cb  /* U+039B GREEK CAPITAL LETTER LAMDA */
#define XK_Greek_MU                      0x07cc  /* U+039C GREEK CAPITAL LETTER MU */
#define XK_Greek_NU                      0x07cd  /* U+039D GREEK CAPITAL LETTER NU */
#define XK_Greek_XI                      0x07ce  /* U+039E GREEK CAPITAL LETTER XI */
#define XK_Greek_OMICRON                 0x07cf  /* U+039F GREEK CAPITAL LETTER OMICRON */
#define XK_Greek_PI                      0x07d0  /* U+03A0 GREEK CAPITAL LETTER PI */
#define XK_Greek_RHO                     0x07d1  /* U+03A1 GREEK CAPITAL LETTER RHO */
#define XK_Greek_SIGMA                   0x07d2  /* U+03A3 GREEK CAPITAL LETTER SIGMA */
#define XK_Greek_TAU                     0x07d4  /* U+03A4 GREEK CAPITAL LETTER TAU */
#define XK_Greek_UPSILON                 0x07d5  /* U+03A5 GREEK CAPITAL LETTER UPSILON */
#define XK_Greek_PHI                     0x07d6  /* U+03A6 GREEK CAPITAL LETTER PHI */
#define XK_Greek_CHI                     0x07d7  /* U+03A7 GREEK CAPITAL LETTER CHI */
#define XK_Greek_PSI                     0x07d8  /* U+03A8 GREEK CAPITAL LETTER PSI */
#define XK_Greek_OMEGA                   0x07d9  /* U+03A9 GREEK CAPITAL LETTER OMEGA */
#define XK_Greek_alpha                   0x07e1  /* U+03B1 GREEK SMALL LETTER ALPHA */
#define XK_Greek_beta                    0x07e2  /* U+03B2 GREEK SMALL LETTER BETA */
#define XK_Greek_gamma                   0x07e3  /* U+03B3 GREEK SMALL LETTER GAMMA */
#define XK_Greek_delta                   0x07e4  /* U+03B4 GREEK SMALL LETTER DELTA */
#define XK_Greek_epsilon                 0x07e5  /* U+03B5 GREEK SMALL LETTER EPSILON */
#define XK_Greek_zeta                    0x07e6  /* U+03B6 GREEK SMALL LETTER ZETA */
#define XK_Greek_eta                     0x07e7  /* U+03B7 GREEK SMALL LETTER ETA */
#define XK_Greek_theta                   0x07e8  /* U+03B8 GREEK SMALL LETTER THETA */
#define XK_Greek_iota                    0x07e9  /* U+03B9 GREEK SMALL LETTER IOTA */
#define XK_Greek_kappa                   0x07ea  /* U+03BA GREEK SMALL LETTER KAPPA */
#define XK_Greek_lamda                   0x07eb  /* U+03BB GREEK SMALL LETTER LAMDA */
#define XK_Greek_lambda                  0x07eb  /* U+03BB GREEK SMALL LETTER LAMDA */
#define XK_Greek_mu                      0x07ec  /* U+03BC GREEK SMALL LETTER MU */
#define XK_Greek_nu                      0x07ed  /* U+03BD GREEK SMALL LETTER NU */
#define XK_Greek_xi                      0x07ee  /* U+03BE GREEK SMALL LETTER XI */
#define XK_Greek_omicron                 0x07ef  /* U+03BF GREEK SMALL LETTER OMICRON */
#define XK_Greek_pi                      0x07f0  /* U+03C0 GREEK SMALL LETTER PI */
#define XK_Greek_rho                     0x07f1  /* U+03C1 GREEK SMALL LETTER RHO */
#define XK_Greek_sigma                   0x07f2  /* U+03C3 GREEK SMALL LETTER SIGMA */
#define XK_Greek_finalsmallsigma         0x07f3  /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */
#define XK_Greek_tau                     0x07f4  /* U+03C4 GREEK SMALL LETTER TAU */
#define XK_Greek_upsilon                 0x07f5  /* U+03C5 GREEK SMALL LETTER UPSILON */
#define XK_Greek_phi                     0x07f6  /* U+03C6 GREEK SMALL LETTER PHI */
#define XK_Greek_chi                     0x07f7  /* U+03C7 GREEK SMALL LETTER CHI */
#define XK_Greek_psi                     0x07f8  /* U+03C8 GREEK SMALL LETTER PSI */
#define XK_Greek_omega                   0x07f9  /* U+03C9 GREEK SMALL LETTER OMEGA */
#define XK_Greek_switch                  0xff7e  /* Alias for mode_switch */
#endif /* XK_GREEK */

/*
 * Technical
 * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html)
 * Byte 3 = 8
 */

#ifdef XK_TECHNICAL
#define XK_leftradical                   0x08a1  /* U+23B7 RADICAL SYMBOL BOTTOM */
#define XK_topleftradical                0x08a2  /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/
#define XK_horizconnector                0x08a3  /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/
#define XK_topintegral                   0x08a4  /* U+2320 TOP HALF INTEGRAL */
#define XK_botintegral                   0x08a5  /* U+2321 BOTTOM HALF INTEGRAL */
#define XK_vertconnector                 0x08a6  /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/
#define XK_topleftsqbracket              0x08a7  /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */
#define XK_botleftsqbracket              0x08a8  /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */
#define XK_toprightsqbracket             0x08a9  /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */
#define XK_botrightsqbracket             0x08aa  /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */
#define XK_topleftparens                 0x08ab  /* U+239B LEFT PARENTHESIS UPPER HOOK */
#define XK_botleftparens                 0x08ac  /* U+239D LEFT PARENTHESIS LOWER HOOK */
#define XK_toprightparens                0x08ad  /* U+239E RIGHT PARENTHESIS UPPER HOOK */
#define XK_botrightparens                0x08ae  /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */
#define XK_leftmiddlecurlybrace          0x08af  /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */
#define XK_rightmiddlecurlybrace         0x08b0  /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */
#define XK_topleftsummation              0x08b1
#define XK_botleftsummation              0x08b2
#define XK_topvertsummationconnector     0x08b3
#define XK_botvertsummationconnector     0x08b4
#define XK_toprightsummation             0x08b5
#define XK_botrightsummation             0x08b6
#define XK_rightmiddlesummation          0x08b7
#define XK_lessthanequal                 0x08bc  /* U+2264 LESS-THAN OR EQUAL TO */
#define XK_notequal                      0x08bd  /* U+2260 NOT EQUAL TO */
#define XK_greaterthanequal              0x08be  /* U+2265 GREATER-THAN OR EQUAL TO */
#define XK_integral                      0x08bf  /* U+222B INTEGRAL */
#define XK_therefore                     0x08c0  /* U+2234 THEREFORE */
#define XK_variation                     0x08c1  /* U+221D PROPORTIONAL TO */
#define XK_infinity                      0x08c2  /* U+221E INFINITY */
#define XK_nabla                         0x08c5  /* U+2207 NABLA */
#define XK_approximate                   0x08c8  /* U+223C TILDE OPERATOR */
#define XK_similarequal                  0x08c9  /* U+2243 ASYMPTOTICALLY EQUAL TO */
#define XK_ifonlyif                      0x08cd  /* U+21D4 LEFT RIGHT DOUBLE ARROW */
#define XK_implies                       0x08ce  /* U+21D2 RIGHTWARDS DOUBLE ARROW */
#define XK_identical                     0x08cf  /* U+2261 IDENTICAL TO */
#define XK_radical                       0x08d6  /* U+221A SQUARE ROOT */
#define XK_includedin                    0x08da  /* U+2282 SUBSET OF */
#define XK_includes                      0x08db  /* U+2283 SUPERSET OF */
#define XK_intersection                  0x08dc  /* U+2229 INTERSECTION */
#define XK_union                         0x08dd  /* U+222A UNION */
#define XK_logicaland                    0x08de  /* U+2227 LOGICAL AND */
#define XK_logicalor                     0x08df  /* U+2228 LOGICAL OR */
#define XK_partialderivative             0x08ef  /* U+2202 PARTIAL DIFFERENTIAL */
#define XK_function                      0x08f6  /* U+0192 LATIN SMALL LETTER F WITH HOOK */
#define XK_leftarrow                     0x08fb  /* U+2190 LEFTWARDS ARROW */
#define XK_uparrow                       0x08fc  /* U+2191 UPWARDS ARROW */
#define XK_rightarrow                    0x08fd  /* U+2192 RIGHTWARDS ARROW */
#define XK_downarrow                     0x08fe  /* U+2193 DOWNWARDS ARROW */
#endif /* XK_TECHNICAL */

/*
 * Special
 * (from the DEC VT100 Special Graphics Character Set)
 * Byte 3 = 9
 */

#ifdef XK_SPECIAL
#define XK_blank                         0x09df
#define XK_soliddiamond                  0x09e0  /* U+25C6 BLACK DIAMOND */
#define XK_checkerboard                  0x09e1  /* U+2592 MEDIUM SHADE */
#define XK_ht                            0x09e2  /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */
#define XK_ff                            0x09e3  /* U+240C SYMBOL FOR FORM FEED */
#define XK_cr                            0x09e4  /* U+240D SYMBOL FOR CARRIAGE RETURN */
#define XK_lf                            0x09e5  /* U+240A SYMBOL FOR LINE FEED */
#define XK_nl                            0x09e8  /* U+2424 SYMBOL FOR NEWLINE */
#define XK_vt                            0x09e9  /* U+240B SYMBOL FOR VERTICAL TABULATION */
#define XK_lowrightcorner                0x09ea  /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */
#define XK_uprightcorner                 0x09eb  /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */
#define XK_upleftcorner                  0x09ec  /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */
#define XK_lowleftcorner                 0x09ed  /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */
#define XK_crossinglines                 0x09ee  /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
#define XK_horizlinescan1                0x09ef  /* U+23BA HORIZONTAL SCAN LINE-1 */
#define XK_horizlinescan3                0x09f0  /* U+23BB HORIZONTAL SCAN LINE-3 */
#define XK_horizlinescan5                0x09f1  /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */
#define XK_horizlinescan7                0x09f2  /* U+23BC HORIZONTAL SCAN LINE-7 */
#define XK_horizlinescan9                0x09f3  /* U+23BD HORIZONTAL SCAN LINE-9 */
#define XK_leftt                         0x09f4  /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
#define XK_rightt                        0x09f5  /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */
#define XK_bott                          0x09f6  /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */
#define XK_topt                          0x09f7  /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
#define XK_vertbar                       0x09f8  /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
#endif /* XK_SPECIAL */

/*
 * Publishing
 * (these are probably from a long forgotten DEC Publishing
 * font that once shipped with DECwrite)
 * Byte 3 = 0x0a
 */

#ifdef XK_PUBLISHING
#define XK_emspace                       0x0aa1  /* U+2003 EM SPACE */
#define XK_enspace                       0x0aa2  /* U+2002 EN SPACE */
#define XK_em3space                      0x0aa3  /* U+2004 THREE-PER-EM SPACE */
#define XK_em4space                      0x0aa4  /* U+2005 FOUR-PER-EM SPACE */
#define XK_digitspace                    0x0aa5  /* U+2007 FIGURE SPACE */
#define XK_punctspace                    0x0aa6  /* U+2008 PUNCTUATION SPACE */
#define XK_thinspace                     0x0aa7  /* U+2009 THIN SPACE */
#define XK_hairspace                     0x0aa8  /* U+200A HAIR SPACE */
#define XK_emdash                        0x0aa9  /* U+2014 EM DASH */
#define XK_endash                        0x0aaa  /* U+2013 EN DASH */
#define XK_signifblank                   0x0aac  /*(U+2423 OPEN BOX)*/
#define XK_ellipsis                      0x0aae  /* U+2026 HORIZONTAL ELLIPSIS */
#define XK_doubbaselinedot               0x0aaf  /* U+2025 TWO DOT LEADER */
#define XK_onethird                      0x0ab0  /* U+2153 VULGAR FRACTION ONE THIRD */
#define XK_twothirds                     0x0ab1  /* U+2154 VULGAR FRACTION TWO THIRDS */
#define XK_onefifth                      0x0ab2  /* U+2155 VULGAR FRACTION ONE FIFTH */
#define XK_twofifths                     0x0ab3  /* U+2156 VULGAR FRACTION TWO FIFTHS */
#define XK_threefifths                   0x0ab4  /* U+2157 VULGAR FRACTION THREE FIFTHS */
#define XK_fourfifths                    0x0ab5  /* U+2158 VULGAR FRACTION FOUR FIFTHS */
#define XK_onesixth                      0x0ab6  /* U+2159 VULGAR FRACTION ONE SIXTH */
#define XK_fivesixths                    0x0ab7  /* U+215A VULGAR FRACTION FIVE SIXTHS */
#define XK_careof                        0x0ab8  /* U+2105 CARE OF */
#define XK_figdash                       0x0abb  /* U+2012 FIGURE DASH */
#define XK_leftanglebracket              0x0abc  /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/
#define XK_decimalpoint                  0x0abd  /*(U+002E FULL STOP)*/
#define XK_rightanglebracket             0x0abe  /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/
#define XK_marker                        0x0abf
#define XK_oneeighth                     0x0ac3  /* U+215B VULGAR FRACTION ONE EIGHTH */
#define XK_threeeighths                  0x0ac4  /* U+215C VULGAR FRACTION THREE EIGHTHS */
#define XK_fiveeighths                   0x0ac5  /* U+215D VULGAR FRACTION FIVE EIGHTHS */
#define XK_seveneighths                  0x0ac6  /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
#define XK_trademark                     0x0ac9  /* U+2122 TRADE MARK SIGN */
#define XK_signaturemark                 0x0aca  /*(U+2613 SALTIRE)*/
#define XK_trademarkincircle             0x0acb
#define XK_leftopentriangle              0x0acc  /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/
#define XK_rightopentriangle             0x0acd  /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/
#define XK_emopencircle                  0x0ace  /*(U+25CB WHITE CIRCLE)*/
#define XK_emopenrectangle               0x0acf  /*(U+25AF WHITE VERTICAL RECTANGLE)*/
#define XK_leftsinglequotemark           0x0ad0  /* U+2018 LEFT SINGLE QUOTATION MARK */
#define XK_rightsinglequotemark          0x0ad1  /* U+2019 RIGHT SINGLE QUOTATION MARK */
#define XK_leftdoublequotemark           0x0ad2  /* U+201C LEFT DOUBLE QUOTATION MARK */
#define XK_rightdoublequotemark          0x0ad3  /* U+201D RIGHT DOUBLE QUOTATION MARK */
#define XK_prescription                  0x0ad4  /* U+211E PRESCRIPTION TAKE */
#define XK_permille                      0x0ad5  /* U+2030 PER MILLE SIGN */
#define XK_minutes                       0x0ad6  /* U+2032 PRIME */
#define XK_seconds                       0x0ad7  /* U+2033 DOUBLE PRIME */
#define XK_latincross                    0x0ad9  /* U+271D LATIN CROSS */
#define XK_hexagram                      0x0ada
#define XK_filledrectbullet              0x0adb  /*(U+25AC BLACK RECTANGLE)*/
#define XK_filledlefttribullet           0x0adc  /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/
#define XK_filledrighttribullet          0x0add  /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/
#define XK_emfilledcircle                0x0ade  /*(U+25CF BLACK CIRCLE)*/
#define XK_emfilledrect                  0x0adf  /*(U+25AE BLACK VERTICAL RECTANGLE)*/
#define XK_enopencircbullet              0x0ae0  /*(U+25E6 WHITE BULLET)*/
#define XK_enopensquarebullet            0x0ae1  /*(U+25AB WHITE SMALL SQUARE)*/
#define XK_openrectbullet                0x0ae2  /*(U+25AD WHITE RECTANGLE)*/
#define XK_opentribulletup               0x0ae3  /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/
#define XK_opentribulletdown             0x0ae4  /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/
#define XK_openstar                      0x0ae5  /*(U+2606 WHITE STAR)*/
#define XK_enfilledcircbullet            0x0ae6  /*(U+2022 BULLET)*/
#define XK_enfilledsqbullet              0x0ae7  /*(U+25AA BLACK SMALL SQUARE)*/
#define XK_filledtribulletup             0x0ae8  /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/
#define XK_filledtribulletdown           0x0ae9  /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/
#define XK_leftpointer                   0x0aea  /*(U+261C WHITE LEFT POINTING INDEX)*/
#define XK_rightpointer                  0x0aeb  /*(U+261E WHITE RIGHT POINTING INDEX)*/
#define XK_club                          0x0aec  /* U+2663 BLACK CLUB SUIT */
#define XK_diamond                       0x0aed  /* U+2666 BLACK DIAMOND SUIT */
#define XK_heart                         0x0aee  /* U+2665 BLACK HEART SUIT */
#define XK_maltesecross                  0x0af0  /* U+2720 MALTESE CROSS */
#define XK_dagger                        0x0af1  /* U+2020 DAGGER */
#define XK_doubledagger                  0x0af2  /* U+2021 DOUBLE DAGGER */
#define XK_checkmark                     0x0af3  /* U+2713 CHECK MARK */
#define XK_ballotcross                   0x0af4  /* U+2717 BALLOT X */
#define XK_musicalsharp                  0x0af5  /* U+266F MUSIC SHARP SIGN */
#define XK_musicalflat                   0x0af6  /* U+266D MUSIC FLAT SIGN */
#define XK_malesymbol                    0x0af7  /* U+2642 MALE SIGN */
#define XK_femalesymbol                  0x0af8  /* U+2640 FEMALE SIGN */
#define XK_telephone                     0x0af9  /* U+260E BLACK TELEPHONE */
#define XK_telephonerecorder             0x0afa  /* U+2315 TELEPHONE RECORDER */
#define XK_phonographcopyright           0x0afb  /* U+2117 SOUND RECORDING COPYRIGHT */
#define XK_caret                         0x0afc  /* U+2038 CARET */
#define XK_singlelowquotemark            0x0afd  /* U+201A SINGLE LOW-9 QUOTATION MARK */
#define XK_doublelowquotemark            0x0afe  /* U+201E DOUBLE LOW-9 QUOTATION MARK */
#define XK_cursor                        0x0aff
#endif /* XK_PUBLISHING */

/*
 * APL
 * Byte 3 = 0x0b
 */

#ifdef XK_APL
#define XK_leftcaret                     0x0ba3  /*(U+003C LESS-THAN SIGN)*/
#define XK_rightcaret                    0x0ba6  /*(U+003E GREATER-THAN SIGN)*/
#define XK_downcaret                     0x0ba8  /*(U+2228 LOGICAL OR)*/
#define XK_upcaret                       0x0ba9  /*(U+2227 LOGICAL AND)*/
#define XK_overbar                       0x0bc0  /*(U+00AF MACRON)*/
#define XK_downtack                      0x0bc2  /* U+22A4 DOWN TACK */
#define XK_upshoe                        0x0bc3  /*(U+2229 INTERSECTION)*/
#define XK_downstile                     0x0bc4  /* U+230A LEFT FLOOR */
#define XK_underbar                      0x0bc6  /*(U+005F LOW LINE)*/
#define XK_jot                           0x0bca  /* U+2218 RING OPERATOR */
#define XK_quad                          0x0bcc  /* U+2395 APL FUNCTIONAL SYMBOL QUAD */
#define XK_uptack                        0x0bce  /* U+22A5 UP TACK */
#define XK_circle                        0x0bcf  /* U+25CB WHITE CIRCLE */
#define XK_upstile                       0x0bd3  /* U+2308 LEFT CEILING */
#define XK_downshoe                      0x0bd6  /*(U+222A UNION)*/
#define XK_rightshoe                     0x0bd8  /*(U+2283 SUPERSET OF)*/
#define XK_leftshoe                      0x0bda  /*(U+2282 SUBSET OF)*/
#define XK_lefttack                      0x0bdc  /* U+22A3 LEFT TACK */
#define XK_righttack                     0x0bfc  /* U+22A2 RIGHT TACK */
#endif /* XK_APL */

/*
 * Hebrew
 * Byte 3 = 0x0c
 */

#ifdef XK_HEBREW
#define XK_hebrew_doublelowline          0x0cdf  /* U+2017 DOUBLE LOW LINE */
#define XK_hebrew_aleph                  0x0ce0  /* U+05D0 HEBREW LETTER ALEF */
#define XK_hebrew_bet                    0x0ce1  /* U+05D1 HEBREW LETTER BET */
#define XK_hebrew_beth                   0x0ce1  /* deprecated */
#define XK_hebrew_gimel                  0x0ce2  /* U+05D2 HEBREW LETTER GIMEL */
#define XK_hebrew_gimmel                 0x0ce2  /* deprecated */
#define XK_hebrew_dalet                  0x0ce3  /* U+05D3 HEBREW LETTER DALET */
#define XK_hebrew_daleth                 0x0ce3  /* deprecated */
#define XK_hebrew_he                     0x0ce4  /* U+05D4 HEBREW LETTER HE */
#define XK_hebrew_waw                    0x0ce5  /* U+05D5 HEBREW LETTER VAV */
#define XK_hebrew_zain                   0x0ce6  /* U+05D6 HEBREW LETTER ZAYIN */
#define XK_hebrew_zayin                  0x0ce6  /* deprecated */
#define XK_hebrew_chet                   0x0ce7  /* U+05D7 HEBREW LETTER HET */
#define XK_hebrew_het                    0x0ce7  /* deprecated */
#define XK_hebrew_tet                    0x0ce8  /* U+05D8 HEBREW LETTER TET */
#define XK_hebrew_teth                   0x0ce8  /* deprecated */
#define XK_hebrew_yod                    0x0ce9  /* U+05D9 HEBREW LETTER YOD */
#define XK_hebrew_finalkaph              0x0cea  /* U+05DA HEBREW LETTER FINAL KAF */
#define XK_hebrew_kaph                   0x0ceb  /* U+05DB HEBREW LETTER KAF */
#define XK_hebrew_lamed                  0x0cec  /* U+05DC HEBREW LETTER LAMED */
#define XK_hebrew_finalmem               0x0ced  /* U+05DD HEBREW LETTER FINAL MEM */
#define XK_hebrew_mem                    0x0cee  /* U+05DE HEBREW LETTER MEM */
#define XK_hebrew_finalnun               0x0cef  /* U+05DF HEBREW LETTER FINAL NUN */
#define XK_hebrew_nun                    0x0cf0  /* U+05E0 HEBREW LETTER NUN */
#define XK_hebrew_samech                 0x0cf1  /* U+05E1 HEBREW LETTER SAMEKH */
#define XK_hebrew_samekh                 0x0cf1  /* deprecated */
#define XK_hebrew_ayin                   0x0cf2  /* U+05E2 HEBREW LETTER AYIN */
#define XK_hebrew_finalpe                0x0cf3  /* U+05E3 HEBREW LETTER FINAL PE */
#define XK_hebrew_pe                     0x0cf4  /* U+05E4 HEBREW LETTER PE */
#define XK_hebrew_finalzade              0x0cf5  /* U+05E5 HEBREW LETTER FINAL TSADI */
#define XK_hebrew_finalzadi              0x0cf5  /* deprecated */
#define XK_hebrew_zade                   0x0cf6  /* U+05E6 HEBREW LETTER TSADI */
#define XK_hebrew_zadi                   0x0cf6  /* deprecated */
#define XK_hebrew_qoph                   0x0cf7  /* U+05E7 HEBREW LETTER QOF */
#define XK_hebrew_kuf                    0x0cf7  /* deprecated */
#define XK_hebrew_resh                   0x0cf8  /* U+05E8 HEBREW LETTER RESH */
#define XK_hebrew_shin                   0x0cf9  /* U+05E9 HEBREW LETTER SHIN */
#define XK_hebrew_taw                    0x0cfa  /* U+05EA HEBREW LETTER TAV */
#define XK_hebrew_taf                    0x0cfa  /* deprecated */
#define XK_Hebrew_switch                 0xff7e  /* Alias for mode_switch */
#endif /* XK_HEBREW */

/*
 * Thai
 * Byte 3 = 0x0d
 */

#ifdef XK_THAI
#define XK_Thai_kokai                    0x0da1  /* U+0E01 THAI CHARACTER KO KAI */
#define XK_Thai_khokhai                  0x0da2  /* U+0E02 THAI CHARACTER KHO KHAI */
#define XK_Thai_khokhuat                 0x0da3  /* U+0E03 THAI CHARACTER KHO KHUAT */
#define XK_Thai_khokhwai                 0x0da4  /* U+0E04 THAI CHARACTER KHO KHWAI */
#define XK_Thai_khokhon                  0x0da5  /* U+0E05 THAI CHARACTER KHO KHON */
#define XK_Thai_khorakhang               0x0da6  /* U+0E06 THAI CHARACTER KHO RAKHANG */
#define XK_Thai_ngongu                   0x0da7  /* U+0E07 THAI CHARACTER NGO NGU */
#define XK_Thai_chochan                  0x0da8  /* U+0E08 THAI CHARACTER CHO CHAN */
#define XK_Thai_choching                 0x0da9  /* U+0E09 THAI CHARACTER CHO CHING */
#define XK_Thai_chochang                 0x0daa  /* U+0E0A THAI CHARACTER CHO CHANG */
#define XK_Thai_soso                     0x0dab  /* U+0E0B THAI CHARACTER SO SO */
#define XK_Thai_chochoe                  0x0dac  /* U+0E0C THAI CHARACTER CHO CHOE */
#define XK_Thai_yoying                   0x0dad  /* U+0E0D THAI CHARACTER YO YING */
#define XK_Thai_dochada                  0x0dae  /* U+0E0E THAI CHARACTER DO CHADA */
#define XK_Thai_topatak                  0x0daf  /* U+0E0F THAI CHARACTER TO PATAK */
#define XK_Thai_thothan                  0x0db0  /* U+0E10 THAI CHARACTER THO THAN */
#define XK_Thai_thonangmontho            0x0db1  /* U+0E11 THAI CHARACTER THO NANGMONTHO */
#define XK_Thai_thophuthao               0x0db2  /* U+0E12 THAI CHARACTER THO PHUTHAO */
#define XK_Thai_nonen                    0x0db3  /* U+0E13 THAI CHARACTER NO NEN */
#define XK_Thai_dodek                    0x0db4  /* U+0E14 THAI CHARACTER DO DEK */
#define XK_Thai_totao                    0x0db5  /* U+0E15 THAI CHARACTER TO TAO */
#define XK_Thai_thothung                 0x0db6  /* U+0E16 THAI CHARACTER THO THUNG */
#define XK_Thai_thothahan                0x0db7  /* U+0E17 THAI CHARACTER THO THAHAN */
#define XK_Thai_thothong                 0x0db8  /* U+0E18 THAI CHARACTER THO THONG */
#define XK_Thai_nonu                     0x0db9  /* U+0E19 THAI CHARACTER NO NU */
#define XK_Thai_bobaimai                 0x0dba  /* U+0E1A THAI CHARACTER BO BAIMAI */
#define XK_Thai_popla                    0x0dbb  /* U+0E1B THAI CHARACTER PO PLA */
#define XK_Thai_phophung                 0x0dbc  /* U+0E1C THAI CHARACTER PHO PHUNG */
#define XK_Thai_fofa                     0x0dbd  /* U+0E1D THAI CHARACTER FO FA */
#define XK_Thai_phophan                  0x0dbe  /* U+0E1E THAI CHARACTER PHO PHAN */
#define XK_Thai_fofan                    0x0dbf  /* U+0E1F THAI CHARACTER FO FAN */
#define XK_Thai_phosamphao               0x0dc0  /* U+0E20 THAI CHARACTER PHO SAMPHAO */
#define XK_Thai_moma                     0x0dc1  /* U+0E21 THAI CHARACTER MO MA */
#define XK_Thai_yoyak                    0x0dc2  /* U+0E22 THAI CHARACTER YO YAK */
#define XK_Thai_rorua                    0x0dc3  /* U+0E23 THAI CHARACTER RO RUA */
#define XK_Thai_ru                       0x0dc4  /* U+0E24 THAI CHARACTER RU */
#define XK_Thai_loling                   0x0dc5  /* U+0E25 THAI CHARACTER LO LING */
#define XK_Thai_lu                       0x0dc6  /* U+0E26 THAI CHARACTER LU */
#define XK_Thai_wowaen                   0x0dc7  /* U+0E27 THAI CHARACTER WO WAEN */
#define XK_Thai_sosala                   0x0dc8  /* U+0E28 THAI CHARACTER SO SALA */
#define XK_Thai_sorusi                   0x0dc9  /* U+0E29 THAI CHARACTER SO RUSI */
#define XK_Thai_sosua                    0x0dca  /* U+0E2A THAI CHARACTER SO SUA */
#define XK_Thai_hohip                    0x0dcb  /* U+0E2B THAI CHARACTER HO HIP */
#define XK_Thai_lochula                  0x0dcc  /* U+0E2C THAI CHARACTER LO CHULA */
#define XK_Thai_oang                     0x0dcd  /* U+0E2D THAI CHARACTER O ANG */
#define XK_Thai_honokhuk                 0x0dce  /* U+0E2E THAI CHARACTER HO NOKHUK */
#define XK_Thai_paiyannoi                0x0dcf  /* U+0E2F THAI CHARACTER PAIYANNOI */
#define XK_Thai_saraa                    0x0dd0  /* U+0E30 THAI CHARACTER SARA A */
#define XK_Thai_maihanakat               0x0dd1  /* U+0E31 THAI CHARACTER MAI HAN-AKAT */
#define XK_Thai_saraaa                   0x0dd2  /* U+0E32 THAI CHARACTER SARA AA */
#define XK_Thai_saraam                   0x0dd3  /* U+0E33 THAI CHARACTER SARA AM */
#define XK_Thai_sarai                    0x0dd4  /* U+0E34 THAI CHARACTER SARA I */
#define XK_Thai_saraii                   0x0dd5  /* U+0E35 THAI CHARACTER SARA II */
#define XK_Thai_saraue                   0x0dd6  /* U+0E36 THAI CHARACTER SARA UE */
#define XK_Thai_sarauee                  0x0dd7  /* U+0E37 THAI CHARACTER SARA UEE */
#define XK_Thai_sarau                    0x0dd8  /* U+0E38 THAI CHARACTER SARA U */
#define XK_Thai_sarauu                   0x0dd9  /* U+0E39 THAI CHARACTER SARA UU */
#define XK_Thai_phinthu                  0x0dda  /* U+0E3A THAI CHARACTER PHINTHU */
#define XK_Thai_maihanakat_maitho        0x0dde
#define XK_Thai_baht                     0x0ddf  /* U+0E3F THAI CURRENCY SYMBOL BAHT */
#define XK_Thai_sarae                    0x0de0  /* U+0E40 THAI CHARACTER SARA E */
#define XK_Thai_saraae                   0x0de1  /* U+0E41 THAI CHARACTER SARA AE */
#define XK_Thai_sarao                    0x0de2  /* U+0E42 THAI CHARACTER SARA O */
#define XK_Thai_saraaimaimuan            0x0de3  /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */
#define XK_Thai_saraaimaimalai           0x0de4  /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */
#define XK_Thai_lakkhangyao              0x0de5  /* U+0E45 THAI CHARACTER LAKKHANGYAO */
#define XK_Thai_maiyamok                 0x0de6  /* U+0E46 THAI CHARACTER MAIYAMOK */
#define XK_Thai_maitaikhu                0x0de7  /* U+0E47 THAI CHARACTER MAITAIKHU */
#define XK_Thai_maiek                    0x0de8  /* U+0E48 THAI CHARACTER MAI EK */
#define XK_Thai_maitho                   0x0de9  /* U+0E49 THAI CHARACTER MAI THO */
#define XK_Thai_maitri                   0x0dea  /* U+0E4A THAI CHARACTER MAI TRI */
#define XK_Thai_maichattawa              0x0deb  /* U+0E4B THAI CHARACTER MAI CHATTAWA */
#define XK_Thai_thanthakhat              0x0dec  /* U+0E4C THAI CHARACTER THANTHAKHAT */
#define XK_Thai_nikhahit                 0x0ded  /* U+0E4D THAI CHARACTER NIKHAHIT */
#define XK_Thai_leksun                   0x0df0  /* U+0E50 THAI DIGIT ZERO */
#define XK_Thai_leknung                  0x0df1  /* U+0E51 THAI DIGIT ONE */
#define XK_Thai_leksong                  0x0df2  /* U+0E52 THAI DIGIT TWO */
#define XK_Thai_leksam                   0x0df3  /* U+0E53 THAI DIGIT THREE */
#define XK_Thai_leksi                    0x0df4  /* U+0E54 THAI DIGIT FOUR */
#define XK_Thai_lekha                    0x0df5  /* U+0E55 THAI DIGIT FIVE */
#define XK_Thai_lekhok                   0x0df6  /* U+0E56 THAI DIGIT SIX */
#define XK_Thai_lekchet                  0x0df7  /* U+0E57 THAI DIGIT SEVEN */
#define XK_Thai_lekpaet                  0x0df8  /* U+0E58 THAI DIGIT EIGHT */
#define XK_Thai_lekkao                   0x0df9  /* U+0E59 THAI DIGIT NINE */
#endif /* XK_THAI */

/*
 * Korean
 * Byte 3 = 0x0e
 */

#ifdef XK_KOREAN

#define XK_Hangul                        0xff31  /* Hangul start/stop(toggle) */
#define XK_Hangul_Start                  0xff32  /* Hangul start */
#define XK_Hangul_End                    0xff33  /* Hangul end, English start */
#define XK_Hangul_Hanja                  0xff34  /* Start Hangul->Hanja Conversion */
#define XK_Hangul_Jamo                   0xff35  /* Hangul Jamo mode */
#define XK_Hangul_Romaja                 0xff36  /* Hangul Romaja mode */
#define XK_Hangul_Codeinput              0xff37  /* Hangul code input mode */
#define XK_Hangul_Jeonja                 0xff38  /* Jeonja mode */
#define XK_Hangul_Banja                  0xff39  /* Banja mode */
#define XK_Hangul_PreHanja               0xff3a  /* Pre Hanja conversion */
#define XK_Hangul_PostHanja              0xff3b  /* Post Hanja conversion */
#define XK_Hangul_SingleCandidate        0xff3c  /* Single candidate */
#define XK_Hangul_MultipleCandidate      0xff3d  /* Multiple candidate */
#define XK_Hangul_PreviousCandidate      0xff3e  /* Previous candidate */
#define XK_Hangul_Special                0xff3f  /* Special symbols */
#define XK_Hangul_switch                 0xff7e  /* Alias for mode_switch */

/* Hangul Consonant Characters */
#define XK_Hangul_Kiyeog                 0x0ea1
#define XK_Hangul_SsangKiyeog            0x0ea2
#define XK_Hangul_KiyeogSios             0x0ea3
#define XK_Hangul_Nieun                  0x0ea4
#define XK_Hangul_NieunJieuj             0x0ea5
#define XK_Hangul_NieunHieuh             0x0ea6
#define XK_Hangul_Dikeud                 0x0ea7
#define XK_Hangul_SsangDikeud            0x0ea8
#define XK_Hangul_Rieul                  0x0ea9
#define XK_Hangul_RieulKiyeog            0x0eaa
#define XK_Hangul_RieulMieum             0x0eab
#define XK_Hangul_RieulPieub             0x0eac
#define XK_Hangul_RieulSios              0x0ead
#define XK_Hangul_RieulTieut             0x0eae
#define XK_Hangul_RieulPhieuf            0x0eaf
#define XK_Hangul_RieulHieuh             0x0eb0
#define XK_Hangul_Mieum                  0x0eb1
#define XK_Hangul_Pieub                  0x0eb2
#define XK_Hangul_SsangPieub             0x0eb3
#define XK_Hangul_PieubSios              0x0eb4
#define XK_Hangul_Sios                   0x0eb5
#define XK_Hangul_SsangSios              0x0eb6
#define XK_Hangul_Ieung                  0x0eb7
#define XK_Hangul_Jieuj                  0x0eb8
#define XK_Hangul_SsangJieuj             0x0eb9
#define XK_Hangul_Cieuc                  0x0eba
#define XK_Hangul_Khieuq                 0x0ebb
#define XK_Hangul_Tieut                  0x0ebc
#define XK_Hangul_Phieuf                 0x0ebd
#define XK_Hangul_Hieuh                  0x0ebe

/* Hangul Vowel Characters */
#define XK_Hangul_A                      0x0ebf
#define XK_Hangul_AE                     0x0ec0
#define XK_Hangul_YA                     0x0ec1
#define XK_Hangul_YAE                    0x0ec2
#define XK_Hangul_EO                     0x0ec3
#define XK_Hangul_E                      0x0ec4
#define XK_Hangul_YEO                    0x0ec5
#define XK_Hangul_YE                     0x0ec6
#define XK_Hangul_O                      0x0ec7
#define XK_Hangul_WA                     0x0ec8
#define XK_Hangul_WAE                    0x0ec9
#define XK_Hangul_OE                     0x0eca
#define XK_Hangul_YO                     0x0ecb
#define XK_Hangul_U                      0x0ecc
#define XK_Hangul_WEO                    0x0ecd
#define XK_Hangul_WE                     0x0ece
#define XK_Hangul_WI                     0x0ecf
#define XK_Hangul_YU                     0x0ed0
#define XK_Hangul_EU                     0x0ed1
#define XK_Hangul_YI                     0x0ed2
#define XK_Hangul_I                      0x0ed3

/* Hangul syllable-final (JongSeong) Characters */
#define XK_Hangul_J_Kiyeog               0x0ed4
#define XK_Hangul_J_SsangKiyeog          0x0ed5
#define XK_Hangul_J_KiyeogSios           0x0ed6
#define XK_Hangul_J_Nieun                0x0ed7
#define XK_Hangul_J_NieunJieuj           0x0ed8
#define XK_Hangul_J_NieunHieuh           0x0ed9
#define XK_Hangul_J_Dikeud               0x0eda
#define XK_Hangul_J_Rieul                0x0edb
#define XK_Hangul_J_RieulKiyeog          0x0edc
#define XK_Hangul_J_RieulMieum           0x0edd
#define XK_Hangul_J_RieulPieub           0x0ede
#define XK_Hangul_J_RieulSios            0x0edf
#define XK_Hangul_J_RieulTieut           0x0ee0
#define XK_Hangul_J_RieulPhieuf          0x0ee1
#define XK_Hangul_J_RieulHieuh           0x0ee2
#define XK_Hangul_J_Mieum                0x0ee3
#define XK_Hangul_J_Pieub                0x0ee4
#define XK_Hangul_J_PieubSios            0x0ee5
#define XK_Hangul_J_Sios                 0x0ee6
#define XK_Hangul_J_SsangSios            0x0ee7
#define XK_Hangul_J_Ieung                0x0ee8
#define XK_Hangul_J_Jieuj                0x0ee9
#define XK_Hangul_J_Cieuc                0x0eea
#define XK_Hangul_J_Khieuq               0x0eeb
#define XK_Hangul_J_Tieut                0x0eec
#define XK_Hangul_J_Phieuf               0x0eed
#define XK_Hangul_J_Hieuh                0x0eee

/* Ancient Hangul Consonant Characters */
#define XK_Hangul_RieulYeorinHieuh       0x0eef
#define XK_Hangul_SunkyeongeumMieum      0x0ef0
#define XK_Hangul_SunkyeongeumPieub      0x0ef1
#define XK_Hangul_PanSios                0x0ef2
#define XK_Hangul_KkogjiDalrinIeung      0x0ef3
#define XK_Hangul_SunkyeongeumPhieuf     0x0ef4
#define XK_Hangul_YeorinHieuh            0x0ef5

/* Ancient Hangul Vowel Characters */
#define XK_Hangul_AraeA                  0x0ef6
#define XK_Hangul_AraeAE                 0x0ef7

/* Ancient Hangul syllable-final (JongSeong) Characters */
#define XK_Hangul_J_PanSios              0x0ef8
#define XK_Hangul_J_KkogjiDalrinIeung    0x0ef9
#define XK_Hangul_J_YeorinHieuh          0x0efa

/* Korean currency symbol */
#define XK_Korean_Won                    0x0eff  /*(U+20A9 WON SIGN)*/

#endif /* XK_KOREAN */

/*
 * Armenian
 */

#ifdef XK_ARMENIAN
#define XK_Armenian_ligature_ew       0x1000587  /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */
#define XK_Armenian_full_stop         0x1000589  /* U+0589 ARMENIAN FULL STOP */
#define XK_Armenian_verjaket          0x1000589  /* U+0589 ARMENIAN FULL STOP */
#define XK_Armenian_separation_mark   0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_but               0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_hyphen            0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_yentamna          0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_exclam            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_amanak            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_accent            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_shesht            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_question          0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_paruyk            0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_AYB               0x1000531  /* U+0531 ARMENIAN CAPITAL LETTER AYB */
#define XK_Armenian_ayb               0x1000561  /* U+0561 ARMENIAN SMALL LETTER AYB */
#define XK_Armenian_BEN               0x1000532  /* U+0532 ARMENIAN CAPITAL LETTER BEN */
#define XK_Armenian_ben               0x1000562  /* U+0562 ARMENIAN SMALL LETTER BEN */
#define XK_Armenian_GIM               0x1000533  /* U+0533 ARMENIAN CAPITAL LETTER GIM */
#define XK_Armenian_gim               0x1000563  /* U+0563 ARMENIAN SMALL LETTER GIM */
#define XK_Armenian_DA                0x1000534  /* U+0534 ARMENIAN CAPITAL LETTER DA */
#define XK_Armenian_da                0x1000564  /* U+0564 ARMENIAN SMALL LETTER DA */
#define XK_Armenian_YECH              0x1000535  /* U+0535 ARMENIAN CAPITAL LETTER ECH */
#define XK_Armenian_yech              0x1000565  /* U+0565 ARMENIAN SMALL LETTER ECH */
#define XK_Armenian_ZA                0x1000536  /* U+0536 ARMENIAN CAPITAL LETTER ZA */
#define XK_Armenian_za                0x1000566  /* U+0566 ARMENIAN SMALL LETTER ZA */
#define XK_Armenian_E                 0x1000537  /* U+0537 ARMENIAN CAPITAL LETTER EH */
#define XK_Armenian_e                 0x1000567  /* U+0567 ARMENIAN SMALL LETTER EH */
#define XK_Armenian_AT                0x1000538  /* U+0538 ARMENIAN CAPITAL LETTER ET */
#define XK_Armenian_at                0x1000568  /* U+0568 ARMENIAN SMALL LETTER ET */
#define XK_Armenian_TO                0x1000539  /* U+0539 ARMENIAN CAPITAL LETTER TO */
#define XK_Armenian_to                0x1000569  /* U+0569 ARMENIAN SMALL LETTER TO */
#define XK_Armenian_ZHE               0x100053a  /* U+053A ARMENIAN CAPITAL LETTER ZHE */
#define XK_Armenian_zhe               0x100056a  /* U+056A ARMENIAN SMALL LETTER ZHE */
#define XK_Armenian_INI               0x100053b  /* U+053B ARMENIAN CAPITAL LETTER INI */
#define XK_Armenian_ini               0x100056b  /* U+056B ARMENIAN SMALL LETTER INI */
#define XK_Armenian_LYUN              0x100053c  /* U+053C ARMENIAN CAPITAL LETTER LIWN */
#define XK_Armenian_lyun              0x100056c  /* U+056C ARMENIAN SMALL LETTER LIWN */
#define XK_Armenian_KHE               0x100053d  /* U+053D ARMENIAN CAPITAL LETTER XEH */
#define XK_Armenian_khe               0x100056d  /* U+056D ARMENIAN SMALL LETTER XEH */
#define XK_Armenian_TSA               0x100053e  /* U+053E ARMENIAN CAPITAL LETTER CA */
#define XK_Armenian_tsa               0x100056e  /* U+056E ARMENIAN SMALL LETTER CA */
#define XK_Armenian_KEN               0x100053f  /* U+053F ARMENIAN CAPITAL LETTER KEN */
#define XK_Armenian_ken               0x100056f  /* U+056F ARMENIAN SMALL LETTER KEN */
#define XK_Armenian_HO                0x1000540  /* U+0540 ARMENIAN CAPITAL LETTER HO */
#define XK_Armenian_ho                0x1000570  /* U+0570 ARMENIAN SMALL LETTER HO */
#define XK_Armenian_DZA               0x1000541  /* U+0541 ARMENIAN CAPITAL LETTER JA */
#define XK_Armenian_dza               0x1000571  /* U+0571 ARMENIAN SMALL LETTER JA */
#define XK_Armenian_GHAT              0x1000542  /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
#define XK_Armenian_ghat              0x1000572  /* U+0572 ARMENIAN SMALL LETTER GHAD */
#define XK_Armenian_TCHE              0x1000543  /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
#define XK_Armenian_tche              0x1000573  /* U+0573 ARMENIAN SMALL LETTER CHEH */
#define XK_Armenian_MEN               0x1000544  /* U+0544 ARMENIAN CAPITAL LETTER MEN */
#define XK_Armenian_men               0x1000574  /* U+0574 ARMENIAN SMALL LETTER MEN */
#define XK_Armenian_HI                0x1000545  /* U+0545 ARMENIAN CAPITAL LETTER YI */
#define XK_Armenian_hi                0x1000575  /* U+0575 ARMENIAN SMALL LETTER YI */
#define XK_Armenian_NU                0x1000546  /* U+0546 ARMENIAN CAPITAL LETTER NOW */
#define XK_Armenian_nu                0x1000576  /* U+0576 ARMENIAN SMALL LETTER NOW */
#define XK_Armenian_SHA               0x1000547  /* U+0547 ARMENIAN CAPITAL LETTER SHA */
#define XK_Armenian_sha               0x1000577  /* U+0577 ARMENIAN SMALL LETTER SHA */
#define XK_Armenian_VO                0x1000548  /* U+0548 ARMENIAN CAPITAL LETTER VO */
#define XK_Armenian_vo                0x1000578  /* U+0578 ARMENIAN SMALL LETTER VO */
#define XK_Armenian_CHA               0x1000549  /* U+0549 ARMENIAN CAPITAL LETTER CHA */
#define XK_Armenian_cha               0x1000579  /* U+0579 ARMENIAN SMALL LETTER CHA */
#define XK_Armenian_PE                0x100054a  /* U+054A ARMENIAN CAPITAL LETTER PEH */
#define XK_Armenian_pe                0x100057a  /* U+057A ARMENIAN SMALL LETTER PEH */
#define XK_Armenian_JE                0x100054b  /* U+054B ARMENIAN CAPITAL LETTER JHEH */
#define XK_Armenian_je                0x100057b  /* U+057B ARMENIAN SMALL LETTER JHEH */
#define XK_Armenian_RA                0x100054c  /* U+054C ARMENIAN CAPITAL LETTER RA */
#define XK_Armenian_ra                0x100057c  /* U+057C ARMENIAN SMALL LETTER RA */
#define XK_Armenian_SE                0x100054d  /* U+054D ARMENIAN CAPITAL LETTER SEH */
#define XK_Armenian_se                0x100057d  /* U+057D ARMENIAN SMALL LETTER SEH */
#define XK_Armenian_VEV               0x100054e  /* U+054E ARMENIAN CAPITAL LETTER VEW */
#define XK_Armenian_vev               0x100057e  /* U+057E ARMENIAN SMALL LETTER VEW */
#define XK_Armenian_TYUN              0x100054f  /* U+054F ARMENIAN CAPITAL LETTER TIWN */
#define XK_Armenian_tyun              0x100057f  /* U+057F ARMENIAN SMALL LETTER TIWN */
#define XK_Armenian_RE                0x1000550  /* U+0550 ARMENIAN CAPITAL LETTER REH */
#define XK_Armenian_re                0x1000580  /* U+0580 ARMENIAN SMALL LETTER REH */
#define XK_Armenian_TSO               0x1000551  /* U+0551 ARMENIAN CAPITAL LETTER CO */
#define XK_Armenian_tso               0x1000581  /* U+0581 ARMENIAN SMALL LETTER CO */
#define XK_Armenian_VYUN              0x1000552  /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
#define XK_Armenian_vyun              0x1000582  /* U+0582 ARMENIAN SMALL LETTER YIWN */
#define XK_Armenian_PYUR              0x1000553  /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
#define XK_Armenian_pyur              0x1000583  /* U+0583 ARMENIAN SMALL LETTER PIWR */
#define XK_Armenian_KE                0x1000554  /* U+0554 ARMENIAN CAPITAL LETTER KEH */
#define XK_Armenian_ke                0x1000584  /* U+0584 ARMENIAN SMALL LETTER KEH */
#define XK_Armenian_O                 0x1000555  /* U+0555 ARMENIAN CAPITAL LETTER OH */
#define XK_Armenian_o                 0x1000585  /* U+0585 ARMENIAN SMALL LETTER OH */
#define XK_Armenian_FE                0x1000556  /* U+0556 ARMENIAN CAPITAL LETTER FEH */
#define XK_Armenian_fe                0x1000586  /* U+0586 ARMENIAN SMALL LETTER FEH */
#define XK_Armenian_apostrophe        0x100055a  /* U+055A ARMENIAN APOSTROPHE */
#endif /* XK_ARMENIAN */

/*
 * Georgian
 */

#ifdef XK_GEORGIAN
#define XK_Georgian_an                0x10010d0  /* U+10D0 GEORGIAN LETTER AN */
#define XK_Georgian_ban               0x10010d1  /* U+10D1 GEORGIAN LETTER BAN */
#define XK_Georgian_gan               0x10010d2  /* U+10D2 GEORGIAN LETTER GAN */
#define XK_Georgian_don               0x10010d3  /* U+10D3 GEORGIAN LETTER DON */
#define XK_Georgian_en                0x10010d4  /* U+10D4 GEORGIAN LETTER EN */
#define XK_Georgian_vin               0x10010d5  /* U+10D5 GEORGIAN LETTER VIN */
#define XK_Georgian_zen               0x10010d6  /* U+10D6 GEORGIAN LETTER ZEN */
#define XK_Georgian_tan               0x10010d7  /* U+10D7 GEORGIAN LETTER TAN */
#define XK_Georgian_in                0x10010d8  /* U+10D8 GEORGIAN LETTER IN */
#define XK_Georgian_kan               0x10010d9  /* U+10D9 GEORGIAN LETTER KAN */
#define XK_Georgian_las               0x10010da  /* U+10DA GEORGIAN LETTER LAS */
#define XK_Georgian_man               0x10010db  /* U+10DB GEORGIAN LETTER MAN */
#define XK_Georgian_nar               0x10010dc  /* U+10DC GEORGIAN LETTER NAR */
#define XK_Georgian_on                0x10010dd  /* U+10DD GEORGIAN LETTER ON */
#define XK_Georgian_par               0x10010de  /* U+10DE GEORGIAN LETTER PAR */
#define XK_Georgian_zhar              0x10010df  /* U+10DF GEORGIAN LETTER ZHAR */
#define XK_Georgian_rae               0x10010e0  /* U+10E0 GEORGIAN LETTER RAE */
#define XK_Georgian_san               0x10010e1  /* U+10E1 GEORGIAN LETTER SAN */
#define XK_Georgian_tar               0x10010e2  /* U+10E2 GEORGIAN LETTER TAR */
#define XK_Georgian_un                0x10010e3  /* U+10E3 GEORGIAN LETTER UN */
#define XK_Georgian_phar              0x10010e4  /* U+10E4 GEORGIAN LETTER PHAR */
#define XK_Georgian_khar              0x10010e5  /* U+10E5 GEORGIAN LETTER KHAR */
#define XK_Georgian_ghan              0x10010e6  /* U+10E6 GEORGIAN LETTER GHAN */
#define XK_Georgian_qar               0x10010e7  /* U+10E7 GEORGIAN LETTER QAR */
#define XK_Georgian_shin              0x10010e8  /* U+10E8 GEORGIAN LETTER SHIN */
#define XK_Georgian_chin              0x10010e9  /* U+10E9 GEORGIAN LETTER CHIN */
#define XK_Georgian_can               0x10010ea  /* U+10EA GEORGIAN LETTER CAN */
#define XK_Georgian_jil               0x10010eb  /* U+10EB GEORGIAN LETTER JIL */
#define XK_Georgian_cil               0x10010ec  /* U+10EC GEORGIAN LETTER CIL */
#define XK_Georgian_char              0x10010ed  /* U+10ED GEORGIAN LETTER CHAR */
#define XK_Georgian_xan               0x10010ee  /* U+10EE GEORGIAN LETTER XAN */
#define XK_Georgian_jhan              0x10010ef  /* U+10EF GEORGIAN LETTER JHAN */
#define XK_Georgian_hae               0x10010f0  /* U+10F0 GEORGIAN LETTER HAE */
#define XK_Georgian_he                0x10010f1  /* U+10F1 GEORGIAN LETTER HE */
#define XK_Georgian_hie               0x10010f2  /* U+10F2 GEORGIAN LETTER HIE */
#define XK_Georgian_we                0x10010f3  /* U+10F3 GEORGIAN LETTER WE */
#define XK_Georgian_har               0x10010f4  /* U+10F4 GEORGIAN LETTER HAR */
#define XK_Georgian_hoe               0x10010f5  /* U+10F5 GEORGIAN LETTER HOE */
#define XK_Georgian_fi                0x10010f6  /* U+10F6 GEORGIAN LETTER FI */
#endif /* XK_GEORGIAN */

/*
 * Azeri (and other Turkic or Caucasian languages)
 */

#ifdef XK_CAUCASUS
/* latin */
#define XK_Xabovedot                  0x1001e8a  /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
#define XK_Ibreve                     0x100012c  /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
#define XK_Zstroke                    0x10001b5  /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
#define XK_Gcaron                     0x10001e6  /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
#define XK_Ocaron                     0x10001d1  /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */
#define XK_Obarred                    0x100019f  /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
#define XK_xabovedot                  0x1001e8b  /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
#define XK_ibreve                     0x100012d  /* U+012D LATIN SMALL LETTER I WITH BREVE */
#define XK_zstroke                    0x10001b6  /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
#define XK_gcaron                     0x10001e7  /* U+01E7 LATIN SMALL LETTER G WITH CARON */
#define XK_ocaron                     0x10001d2  /* U+01D2 LATIN SMALL LETTER O WITH CARON */
#define XK_obarred                    0x1000275  /* U+0275 LATIN SMALL LETTER BARRED O */
#define XK_SCHWA                      0x100018f  /* U+018F LATIN CAPITAL LETTER SCHWA */
#define XK_schwa                      0x1000259  /* U+0259 LATIN SMALL LETTER SCHWA */
#define XK_EZH                        0x10001b7  /* U+01B7 LATIN CAPITAL LETTER EZH */
#define XK_ezh                        0x1000292  /* U+0292 LATIN SMALL LETTER EZH */
/* those are not really Caucasus */
/* For Inupiak */
#define XK_Lbelowdot                  0x1001e36  /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
#define XK_lbelowdot                  0x1001e37  /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
#endif /* XK_CAUCASUS */

/*
 * Vietnamese
 */

#ifdef XK_VIETNAMESE
#define XK_Abelowdot                  0x1001ea0  /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
#define XK_abelowdot                  0x1001ea1  /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
#define XK_Ahook                      0x1001ea2  /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
#define XK_ahook                      0x1001ea3  /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
#define XK_Acircumflexacute           0x1001ea4  /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_acircumflexacute           0x1001ea5  /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_Acircumflexgrave           0x1001ea6  /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_acircumflexgrave           0x1001ea7  /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_Acircumflexhook            0x1001ea8  /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_acircumflexhook            0x1001ea9  /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Acircumflextilde           0x1001eaa  /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_acircumflextilde           0x1001eab  /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_Acircumflexbelowdot        0x1001eac  /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_acircumflexbelowdot        0x1001ead  /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Abreveacute                0x1001eae  /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
#define XK_abreveacute                0x1001eaf  /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
#define XK_Abrevegrave                0x1001eb0  /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
#define XK_abrevegrave                0x1001eb1  /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
#define XK_Abrevehook                 0x1001eb2  /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_abrevehook                 0x1001eb3  /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_Abrevetilde                0x1001eb4  /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
#define XK_abrevetilde                0x1001eb5  /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
#define XK_Abrevebelowdot             0x1001eb6  /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
#define XK_abrevebelowdot             0x1001eb7  /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
#define XK_Ebelowdot                  0x1001eb8  /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
#define XK_ebelowdot                  0x1001eb9  /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
#define XK_Ehook                      0x1001eba  /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
#define XK_ehook                      0x1001ebb  /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
#define XK_Etilde                     0x1001ebc  /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
#define XK_etilde                     0x1001ebd  /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
#define XK_Ecircumflexacute           0x1001ebe  /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_ecircumflexacute           0x1001ebf  /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_Ecircumflexgrave           0x1001ec0  /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_ecircumflexgrave           0x1001ec1  /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_Ecircumflexhook            0x1001ec2  /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ecircumflexhook            0x1001ec3  /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ecircumflextilde           0x1001ec4  /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_ecircumflextilde           0x1001ec5  /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_Ecircumflexbelowdot        0x1001ec6  /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ecircumflexbelowdot        0x1001ec7  /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ihook                      0x1001ec8  /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
#define XK_ihook                      0x1001ec9  /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
#define XK_Ibelowdot                  0x1001eca  /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
#define XK_ibelowdot                  0x1001ecb  /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
#define XK_Obelowdot                  0x1001ecc  /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
#define XK_obelowdot                  0x1001ecd  /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
#define XK_Ohook                      0x1001ece  /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
#define XK_ohook                      0x1001ecf  /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
#define XK_Ocircumflexacute           0x1001ed0  /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_ocircumflexacute           0x1001ed1  /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_Ocircumflexgrave           0x1001ed2  /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_ocircumflexgrave           0x1001ed3  /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_Ocircumflexhook            0x1001ed4  /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ocircumflexhook            0x1001ed5  /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ocircumflextilde           0x1001ed6  /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_ocircumflextilde           0x1001ed7  /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_Ocircumflexbelowdot        0x1001ed8  /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ocircumflexbelowdot        0x1001ed9  /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ohornacute                 0x1001eda  /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
#define XK_ohornacute                 0x1001edb  /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
#define XK_Ohorngrave                 0x1001edc  /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
#define XK_ohorngrave                 0x1001edd  /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
#define XK_Ohornhook                  0x1001ede  /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_ohornhook                  0x1001edf  /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_Ohorntilde                 0x1001ee0  /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
#define XK_ohorntilde                 0x1001ee1  /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
#define XK_Ohornbelowdot              0x1001ee2  /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
#define XK_ohornbelowdot              0x1001ee3  /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
#define XK_Ubelowdot                  0x1001ee4  /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
#define XK_ubelowdot                  0x1001ee5  /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
#define XK_Uhook                      0x1001ee6  /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
#define XK_uhook                      0x1001ee7  /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
#define XK_Uhornacute                 0x1001ee8  /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
#define XK_uhornacute                 0x1001ee9  /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
#define XK_Uhorngrave                 0x1001eea  /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
#define XK_uhorngrave                 0x1001eeb  /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
#define XK_Uhornhook                  0x1001eec  /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_uhornhook                  0x1001eed  /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_Uhorntilde                 0x1001eee  /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
#define XK_uhorntilde                 0x1001eef  /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
#define XK_Uhornbelowdot              0x1001ef0  /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
#define XK_uhornbelowdot              0x1001ef1  /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
#define XK_Ybelowdot                  0x1001ef4  /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
#define XK_ybelowdot                  0x1001ef5  /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
#define XK_Yhook                      0x1001ef6  /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
#define XK_yhook                      0x1001ef7  /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
#define XK_Ytilde                     0x1001ef8  /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
#define XK_ytilde                     0x1001ef9  /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
#define XK_Ohorn                      0x10001a0  /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
#define XK_ohorn                      0x10001a1  /* U+01A1 LATIN SMALL LETTER O WITH HORN */
#define XK_Uhorn                      0x10001af  /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
#define XK_uhorn                      0x10001b0  /* U+01B0 LATIN SMALL LETTER U WITH HORN */

#endif /* XK_VIETNAMESE */

#ifdef XK_CURRENCY
#define XK_EcuSign                    0x10020a0  /* U+20A0 EURO-CURRENCY SIGN */
#define XK_ColonSign                  0x10020a1  /* U+20A1 COLON SIGN */
#define XK_CruzeiroSign               0x10020a2  /* U+20A2 CRUZEIRO SIGN */
#define XK_FFrancSign                 0x10020a3  /* U+20A3 FRENCH FRANC SIGN */
#define XK_LiraSign                   0x10020a4  /* U+20A4 LIRA SIGN */
#define XK_MillSign                   0x10020a5  /* U+20A5 MILL SIGN */
#define XK_NairaSign                  0x10020a6  /* U+20A6 NAIRA SIGN */
#define XK_PesetaSign                 0x10020a7  /* U+20A7 PESETA SIGN */
#define XK_RupeeSign                  0x10020a8  /* U+20A8 RUPEE SIGN */
#define XK_WonSign                    0x10020a9  /* U+20A9 WON SIGN */
#define XK_NewSheqelSign              0x10020aa  /* U+20AA NEW SHEQEL SIGN */
#define XK_DongSign                   0x10020ab  /* U+20AB DONG SIGN */
#define XK_EuroSign                      0x20ac  /* U+20AC EURO SIGN */
#endif /* XK_CURRENCY */

#ifdef XK_MATHEMATICAL
/* one, two and three are defined above. */
#define XK_zerosuperior               0x1002070  /* U+2070 SUPERSCRIPT ZERO */
#define XK_foursuperior               0x1002074  /* U+2074 SUPERSCRIPT FOUR */
#define XK_fivesuperior               0x1002075  /* U+2075 SUPERSCRIPT FIVE */
#define XK_sixsuperior                0x1002076  /* U+2076 SUPERSCRIPT SIX */
#define XK_sevensuperior              0x1002077  /* U+2077 SUPERSCRIPT SEVEN */
#define XK_eightsuperior              0x1002078  /* U+2078 SUPERSCRIPT EIGHT */
#define XK_ninesuperior               0x1002079  /* U+2079 SUPERSCRIPT NINE */
#define XK_zerosubscript              0x1002080  /* U+2080 SUBSCRIPT ZERO */
#define XK_onesubscript               0x1002081  /* U+2081 SUBSCRIPT ONE */
#define XK_twosubscript               0x1002082  /* U+2082 SUBSCRIPT TWO */
#define XK_threesubscript             0x1002083  /* U+2083 SUBSCRIPT THREE */
#define XK_foursubscript              0x1002084  /* U+2084 SUBSCRIPT FOUR */
#define XK_fivesubscript              0x1002085  /* U+2085 SUBSCRIPT FIVE */
#define XK_sixsubscript               0x1002086  /* U+2086 SUBSCRIPT SIX */
#define XK_sevensubscript             0x1002087  /* U+2087 SUBSCRIPT SEVEN */
#define XK_eightsubscript             0x1002088  /* U+2088 SUBSCRIPT EIGHT */
#define XK_ninesubscript              0x1002089  /* U+2089 SUBSCRIPT NINE */
#define XK_partdifferential           0x1002202  /* U+2202 PARTIAL DIFFERENTIAL */
#define XK_emptyset                   0x1002205  /* U+2205 NULL SET */
#define XK_elementof                  0x1002208  /* U+2208 ELEMENT OF */
#define XK_notelementof               0x1002209  /* U+2209 NOT AN ELEMENT OF */
#define XK_containsas                 0x100220B  /* U+220B CONTAINS AS MEMBER */
#define XK_squareroot                 0x100221A  /* U+221A SQUARE ROOT */
#define XK_cuberoot                   0x100221B  /* U+221B CUBE ROOT */
#define XK_fourthroot                 0x100221C  /* U+221C FOURTH ROOT */
#define XK_dintegral                  0x100222C  /* U+222C DOUBLE INTEGRAL */
#define XK_tintegral                  0x100222D  /* U+222D TRIPLE INTEGRAL */
#define XK_because                    0x1002235  /* U+2235 BECAUSE */
#define XK_approxeq                   0x1002248  /* U+2245 ALMOST EQUAL TO */
#define XK_notapproxeq                0x1002247  /* U+2247 NOT ALMOST EQUAL TO */
#define XK_notidentical               0x1002262  /* U+2262 NOT IDENTICAL TO */
#define XK_stricteq                   0x1002263  /* U+2263 STRICTLY EQUIVALENT TO */
#endif /* XK_MATHEMATICAL */

#ifdef XK_BRAILLE
#define XK_braille_dot_1                 0xfff1
#define XK_braille_dot_2                 0xfff2
#define XK_braille_dot_3                 0xfff3
#define XK_braille_dot_4                 0xfff4
#define XK_braille_dot_5                 0xfff5
#define XK_braille_dot_6                 0xfff6
#define XK_braille_dot_7                 0xfff7
#define XK_braille_dot_8                 0xfff8
#define XK_braille_dot_9                 0xfff9
#define XK_braille_dot_10                0xfffa
#define XK_braille_blank              0x1002800  /* U+2800 BRAILLE PATTERN BLANK */
#define XK_braille_dots_1             0x1002801  /* U+2801 BRAILLE PATTERN DOTS-1 */
#define XK_braille_dots_2             0x1002802  /* U+2802 BRAILLE PATTERN DOTS-2 */
#define XK_braille_dots_12            0x1002803  /* U+2803 BRAILLE PATTERN DOTS-12 */
#define XK_braille_dots_3             0x1002804  /* U+2804 BRAILLE PATTERN DOTS-3 */
#define XK_braille_dots_13            0x1002805  /* U+2805 BRAILLE PATTERN DOTS-13 */
#define XK_braille_dots_23            0x1002806  /* U+2806 BRAILLE PATTERN DOTS-23 */
#define XK_braille_dots_123           0x1002807  /* U+2807 BRAILLE PATTERN DOTS-123 */
#define XK_braille_dots_4             0x1002808  /* U+2808 BRAILLE PATTERN DOTS-4 */
#define XK_braille_dots_14            0x1002809  /* U+2809 BRAILLE PATTERN DOTS-14 */
#define XK_braille_dots_24            0x100280a  /* U+280a BRAILLE PATTERN DOTS-24 */
#define XK_braille_dots_124           0x100280b  /* U+280b BRAILLE PATTERN DOTS-124 */
#define XK_braille_dots_34            0x100280c  /* U+280c BRAILLE PATTERN DOTS-34 */
#define XK_braille_dots_134           0x100280d  /* U+280d BRAILLE PATTERN DOTS-134 */
#define XK_braille_dots_234           0x100280e  /* U+280e BRAILLE PATTERN DOTS-234 */
#define XK_braille_dots_1234          0x100280f  /* U+280f BRAILLE PATTERN DOTS-1234 */
#define XK_braille_dots_5             0x1002810  /* U+2810 BRAILLE PATTERN DOTS-5 */
#define XK_braille_dots_15            0x1002811  /* U+2811 BRAILLE PATTERN DOTS-15 */
#define XK_braille_dots_25            0x1002812  /* U+2812 BRAILLE PATTERN DOTS-25 */
#define XK_braille_dots_125           0x1002813  /* U+2813 BRAILLE PATTERN DOTS-125 */
#define XK_braille_dots_35            0x1002814  /* U+2814 BRAILLE PATTERN DOTS-35 */
#define XK_braille_dots_135           0x1002815  /* U+2815 BRAILLE PATTERN DOTS-135 */
#define XK_braille_dots_235           0x1002816  /* U+2816 BRAILLE PATTERN DOTS-235 */
#define XK_braille_dots_1235          0x1002817  /* U+2817 BRAILLE PATTERN DOTS-1235 */
#define XK_braille_dots_45            0x1002818  /* U+2818 BRAILLE PATTERN DOTS-45 */
#define XK_braille_dots_145           0x1002819  /* U+2819 BRAILLE PATTERN DOTS-145 */
#define XK_braille_dots_245           0x100281a  /* U+281a BRAILLE PATTERN DOTS-245 */
#define XK_braille_dots_1245          0x100281b  /* U+281b BRAILLE PATTERN DOTS-1245 */
#define XK_braille_dots_345           0x100281c  /* U+281c BRAILLE PATTERN DOTS-345 */
#define XK_braille_dots_1345          0x100281d  /* U+281d BRAILLE PATTERN DOTS-1345 */
#define XK_braille_dots_2345          0x100281e  /* U+281e BRAILLE PATTERN DOTS-2345 */
#define XK_braille_dots_12345         0x100281f  /* U+281f BRAILLE PATTERN DOTS-12345 */
#define XK_braille_dots_6             0x1002820  /* U+2820 BRAILLE PATTERN DOTS-6 */
#define XK_braille_dots_16            0x1002821  /* U+2821 BRAILLE PATTERN DOTS-16 */
#define XK_braille_dots_26            0x1002822  /* U+2822 BRAILLE PATTERN DOTS-26 */
#define XK_braille_dots_126           0x1002823  /* U+2823 BRAILLE PATTERN DOTS-126 */
#define XK_braille_dots_36            0x1002824  /* U+2824 BRAILLE PATTERN DOTS-36 */
#define XK_braille_dots_136           0x1002825  /* U+2825 BRAILLE PATTERN DOTS-136 */
#define XK_braille_dots_236           0x1002826  /* U+2826 BRAILLE PATTERN DOTS-236 */
#define XK_braille_dots_1236          0x1002827  /* U+2827 BRAILLE PATTERN DOTS-1236 */
#define XK_braille_dots_46            0x1002828  /* U+2828 BRAILLE PATTERN DOTS-46 */
#define XK_braille_dots_146           0x1002829  /* U+2829 BRAILLE PATTERN DOTS-146 */
#define XK_braille_dots_246           0x100282a  /* U+282a BRAILLE PATTERN DOTS-246 */
#define XK_braille_dots_1246          0x100282b  /* U+282b BRAILLE PATTERN DOTS-1246 */
#define XK_braille_dots_346           0x100282c  /* U+282c BRAILLE PATTERN DOTS-346 */
#define XK_braille_dots_1346          0x100282d  /* U+282d BRAILLE PATTERN DOTS-1346 */
#define XK_braille_dots_2346          0x100282e  /* U+282e BRAILLE PATTERN DOTS-2346 */
#define XK_braille_dots_12346         0x100282f  /* U+282f BRAILLE PATTERN DOTS-12346 */
#define XK_braille_dots_56            0x1002830  /* U+2830 BRAILLE PATTERN DOTS-56 */
#define XK_braille_dots_156           0x1002831  /* U+2831 BRAILLE PATTERN DOTS-156 */
#define XK_braille_dots_256           0x1002832  /* U+2832 BRAILLE PATTERN DOTS-256 */
#define XK_braille_dots_1256          0x1002833  /* U+2833 BRAILLE PATTERN DOTS-1256 */
#define XK_braille_dots_356           0x1002834  /* U+2834 BRAILLE PATTERN DOTS-356 */
#define XK_braille_dots_1356          0x1002835  /* U+2835 BRAILLE PATTERN DOTS-1356 */
#define XK_braille_dots_2356          0x1002836  /* U+2836 BRAILLE PATTERN DOTS-2356 */
#define XK_braille_dots_12356         0x1002837  /* U+2837 BRAILLE PATTERN DOTS-12356 */
#define XK_braille_dots_456           0x1002838  /* U+2838 BRAILLE PATTERN DOTS-456 */
#define XK_braille_dots_1456          0x1002839  /* U+2839 BRAILLE PATTERN DOTS-1456 */
#define XK_braille_dots_2456          0x100283a  /* U+283a BRAILLE PATTERN DOTS-2456 */
#define XK_braille_dots_12456         0x100283b  /* U+283b BRAILLE PATTERN DOTS-12456 */
#define XK_braille_dots_3456          0x100283c  /* U+283c BRAILLE PATTERN DOTS-3456 */
#define XK_braille_dots_13456         0x100283d  /* U+283d BRAILLE PATTERN DOTS-13456 */
#define XK_braille_dots_23456         0x100283e  /* U+283e BRAILLE PATTERN DOTS-23456 */
#define XK_braille_dots_123456        0x100283f  /* U+283f BRAILLE PATTERN DOTS-123456 */
#define XK_braille_dots_7             0x1002840  /* U+2840 BRAILLE PATTERN DOTS-7 */
#define XK_braille_dots_17            0x1002841  /* U+2841 BRAILLE PATTERN DOTS-17 */
#define XK_braille_dots_27            0x1002842  /* U+2842 BRAILLE PATTERN DOTS-27 */
#define XK_braille_dots_127           0x1002843  /* U+2843 BRAILLE PATTERN DOTS-127 */
#define XK_braille_dots_37            0x1002844  /* U+2844 BRAILLE PATTERN DOTS-37 */
#define XK_braille_dots_137           0x1002845  /* U+2845 BRAILLE PATTERN DOTS-137 */
#define XK_braille_dots_237           0x1002846  /* U+2846 BRAILLE PATTERN DOTS-237 */
#define XK_braille_dots_1237          0x1002847  /* U+2847 BRAILLE PATTERN DOTS-1237 */
#define XK_braille_dots_47            0x1002848  /* U+2848 BRAILLE PATTERN DOTS-47 */
#define XK_braille_dots_147           0x1002849  /* U+2849 BRAILLE PATTERN DOTS-147 */
#define XK_braille_dots_247           0x100284a  /* U+284a BRAILLE PATTERN DOTS-247 */
#define XK_braille_dots_1247          0x100284b  /* U+284b BRAILLE PATTERN DOTS-1247 */
#define XK_braille_dots_347           0x100284c  /* U+284c BRAILLE PATTERN DOTS-347 */
#define XK_braille_dots_1347          0x100284d  /* U+284d BRAILLE PATTERN DOTS-1347 */
#define XK_braille_dots_2347          0x100284e  /* U+284e BRAILLE PATTERN DOTS-2347 */
#define XK_braille_dots_12347         0x100284f  /* U+284f BRAILLE PATTERN DOTS-12347 */
#define XK_braille_dots_57            0x1002850  /* U+2850 BRAILLE PATTERN DOTS-57 */
#define XK_braille_dots_157           0x1002851  /* U+2851 BRAILLE PATTERN DOTS-157 */
#define XK_braille_dots_257           0x1002852  /* U+2852 BRAILLE PATTERN DOTS-257 */
#define XK_braille_dots_1257          0x1002853  /* U+2853 BRAILLE PATTERN DOTS-1257 */
#define XK_braille_dots_357           0x1002854  /* U+2854 BRAILLE PATTERN DOTS-357 */
#define XK_braille_dots_1357          0x1002855  /* U+2855 BRAILLE PATTERN DOTS-1357 */
#define XK_braille_dots_2357          0x1002856  /* U+2856 BRAILLE PATTERN DOTS-2357 */
#define XK_braille_dots_12357         0x1002857  /* U+2857 BRAILLE PATTERN DOTS-12357 */
#define XK_braille_dots_457           0x1002858  /* U+2858 BRAILLE PATTERN DOTS-457 */
#define XK_braille_dots_1457          0x1002859  /* U+2859 BRAILLE PATTERN DOTS-1457 */
#define XK_braille_dots_2457          0x100285a  /* U+285a BRAILLE PATTERN DOTS-2457 */
#define XK_braille_dots_12457         0x100285b  /* U+285b BRAILLE PATTERN DOTS-12457 */
#define XK_braille_dots_3457          0x100285c  /* U+285c BRAILLE PATTERN DOTS-3457 */
#define XK_braille_dots_13457         0x100285d  /* U+285d BRAILLE PATTERN DOTS-13457 */
#define XK_braille_dots_23457         0x100285e  /* U+285e BRAILLE PATTERN DOTS-23457 */
#define XK_braille_dots_123457        0x100285f  /* U+285f BRAILLE PATTERN DOTS-123457 */
#define XK_braille_dots_67            0x1002860  /* U+2860 BRAILLE PATTERN DOTS-67 */
#define XK_braille_dots_167           0x1002861  /* U+2861 BRAILLE PATTERN DOTS-167 */
#define XK_braille_dots_267           0x1002862  /* U+2862 BRAILLE PATTERN DOTS-267 */
#define XK_braille_dots_1267          0x1002863  /* U+2863 BRAILLE PATTERN DOTS-1267 */
#define XK_braille_dots_367           0x1002864  /* U+2864 BRAILLE PATTERN DOTS-367 */
#define XK_braille_dots_1367          0x1002865  /* U+2865 BRAILLE PATTERN DOTS-1367 */
#define XK_braille_dots_2367          0x1002866  /* U+2866 BRAILLE PATTERN DOTS-2367 */
#define XK_braille_dots_12367         0x1002867  /* U+2867 BRAILLE PATTERN DOTS-12367 */
#define XK_braille_dots_467           0x1002868  /* U+2868 BRAILLE PATTERN DOTS-467 */
#define XK_braille_dots_1467          0x1002869  /* U+2869 BRAILLE PATTERN DOTS-1467 */
#define XK_braille_dots_2467          0x100286a  /* U+286a BRAILLE PATTERN DOTS-2467 */
#define XK_braille_dots_12467         0x100286b  /* U+286b BRAILLE PATTERN DOTS-12467 */
#define XK_braille_dots_3467          0x100286c  /* U+286c BRAILLE PATTERN DOTS-3467 */
#define XK_braille_dots_13467         0x100286d  /* U+286d BRAILLE PATTERN DOTS-13467 */
#define XK_braille_dots_23467         0x100286e  /* U+286e BRAILLE PATTERN DOTS-23467 */
#define XK_braille_dots_123467        0x100286f  /* U+286f BRAILLE PATTERN DOTS-123467 */
#define XK_braille_dots_567           0x1002870  /* U+2870 BRAILLE PATTERN DOTS-567 */
#define XK_braille_dots_1567          0x1002871  /* U+2871 BRAILLE PATTERN DOTS-1567 */
#define XK_braille_dots_2567          0x1002872  /* U+2872 BRAILLE PATTERN DOTS-2567 */
#define XK_braille_dots_12567         0x1002873  /* U+2873 BRAILLE PATTERN DOTS-12567 */
#define XK_braille_dots_3567          0x1002874  /* U+2874 BRAILLE PATTERN DOTS-3567 */
#define XK_braille_dots_13567         0x1002875  /* U+2875 BRAILLE PATTERN DOTS-13567 */
#define XK_braille_dots_23567         0x1002876  /* U+2876 BRAILLE PATTERN DOTS-23567 */
#define XK_braille_dots_123567        0x1002877  /* U+2877 BRAILLE PATTERN DOTS-123567 */
#define XK_braille_dots_4567          0x1002878  /* U+2878 BRAILLE PATTERN DOTS-4567 */
#define XK_braille_dots_14567         0x1002879  /* U+2879 BRAILLE PATTERN DOTS-14567 */
#define XK_braille_dots_24567         0x100287a  /* U+287a BRAILLE PATTERN DOTS-24567 */
#define XK_braille_dots_124567        0x100287b  /* U+287b BRAILLE PATTERN DOTS-124567 */
#define XK_braille_dots_34567         0x100287c  /* U+287c BRAILLE PATTERN DOTS-34567 */
#define XK_braille_dots_134567        0x100287d  /* U+287d BRAILLE PATTERN DOTS-134567 */
#define XK_braille_dots_234567        0x100287e  /* U+287e BRAILLE PATTERN DOTS-234567 */
#define XK_braille_dots_1234567       0x100287f  /* U+287f BRAILLE PATTERN DOTS-1234567 */
#define XK_braille_dots_8             0x1002880  /* U+2880 BRAILLE PATTERN DOTS-8 */
#define XK_braille_dots_18            0x1002881  /* U+2881 BRAILLE PATTERN DOTS-18 */
#define XK_braille_dots_28            0x1002882  /* U+2882 BRAILLE PATTERN DOTS-28 */
#define XK_braille_dots_128           0x1002883  /* U+2883 BRAILLE PATTERN DOTS-128 */
#define XK_braille_dots_38            0x1002884  /* U+2884 BRAILLE PATTERN DOTS-38 */
#define XK_braille_dots_138           0x1002885  /* U+2885 BRAILLE PATTERN DOTS-138 */
#define XK_braille_dots_238           0x1002886  /* U+2886 BRAILLE PATTERN DOTS-238 */
#define XK_braille_dots_1238          0x1002887  /* U+2887 BRAILLE PATTERN DOTS-1238 */
#define XK_braille_dots_48            0x1002888  /* U+2888 BRAILLE PATTERN DOTS-48 */
#define XK_braille_dots_148           0x1002889  /* U+2889 BRAILLE PATTERN DOTS-148 */
#define XK_braille_dots_248           0x100288a  /* U+288a BRAILLE PATTERN DOTS-248 */
#define XK_braille_dots_1248          0x100288b  /* U+288b BRAILLE PATTERN DOTS-1248 */
#define XK_braille_dots_348           0x100288c  /* U+288c BRAILLE PATTERN DOTS-348 */
#define XK_braille_dots_1348          0x100288d  /* U+288d BRAILLE PATTERN DOTS-1348 */
#define XK_braille_dots_2348          0x100288e  /* U+288e BRAILLE PATTERN DOTS-2348 */
#define XK_braille_dots_12348         0x100288f  /* U+288f BRAILLE PATTERN DOTS-12348 */
#define XK_braille_dots_58            0x1002890  /* U+2890 BRAILLE PATTERN DOTS-58 */
#define XK_braille_dots_158           0x1002891  /* U+2891 BRAILLE PATTERN DOTS-158 */
#define XK_braille_dots_258           0x1002892  /* U+2892 BRAILLE PATTERN DOTS-258 */
#define XK_braille_dots_1258          0x1002893  /* U+2893 BRAILLE PATTERN DOTS-1258 */
#define XK_braille_dots_358           0x1002894  /* U+2894 BRAILLE PATTERN DOTS-358 */
#define XK_braille_dots_1358          0x1002895  /* U+2895 BRAILLE PATTERN DOTS-1358 */
#define XK_braille_dots_2358          0x1002896  /* U+2896 BRAILLE PATTERN DOTS-2358 */
#define XK_braille_dots_12358         0x1002897  /* U+2897 BRAILLE PATTERN DOTS-12358 */
#define XK_braille_dots_458           0x1002898  /* U+2898 BRAILLE PATTERN DOTS-458 */
#define XK_braille_dots_1458          0x1002899  /* U+2899 BRAILLE PATTERN DOTS-1458 */
#define XK_braille_dots_2458          0x100289a  /* U+289a BRAILLE PATTERN DOTS-2458 */
#define XK_braille_dots_12458         0x100289b  /* U+289b BRAILLE PATTERN DOTS-12458 */
#define XK_braille_dots_3458          0x100289c  /* U+289c BRAILLE PATTERN DOTS-3458 */
#define XK_braille_dots_13458         0x100289d  /* U+289d BRAILLE PATTERN DOTS-13458 */
#define XK_braille_dots_23458         0x100289e  /* U+289e BRAILLE PATTERN DOTS-23458 */
#define XK_braille_dots_123458        0x100289f  /* U+289f BRAILLE PATTERN DOTS-123458 */
#define XK_braille_dots_68            0x10028a0  /* U+28a0 BRAILLE PATTERN DOTS-68 */
#define XK_braille_dots_168           0x10028a1  /* U+28a1 BRAILLE PATTERN DOTS-168 */
#define XK_braille_dots_268           0x10028a2  /* U+28a2 BRAILLE PATTERN DOTS-268 */
#define XK_braille_dots_1268          0x10028a3  /* U+28a3 BRAILLE PATTERN DOTS-1268 */
#define XK_braille_dots_368           0x10028a4  /* U+28a4 BRAILLE PATTERN DOTS-368 */
#define XK_braille_dots_1368          0x10028a5  /* U+28a5 BRAILLE PATTERN DOTS-1368 */
#define XK_braille_dots_2368          0x10028a6  /* U+28a6 BRAILLE PATTERN DOTS-2368 */
#define XK_braille_dots_12368         0x10028a7  /* U+28a7 BRAILLE PATTERN DOTS-12368 */
#define XK_braille_dots_468           0x10028a8  /* U+28a8 BRAILLE PATTERN DOTS-468 */
#define XK_braille_dots_1468          0x10028a9  /* U+28a9 BRAILLE PATTERN DOTS-1468 */
#define XK_braille_dots_2468          0x10028aa  /* U+28aa BRAILLE PATTERN DOTS-2468 */
#define XK_braille_dots_12468         0x10028ab  /* U+28ab BRAILLE PATTERN DOTS-12468 */
#define XK_braille_dots_3468          0x10028ac  /* U+28ac BRAILLE PATTERN DOTS-3468 */
#define XK_braille_dots_13468         0x10028ad  /* U+28ad BRAILLE PATTERN DOTS-13468 */
#define XK_braille_dots_23468         0x10028ae  /* U+28ae BRAILLE PATTERN DOTS-23468 */
#define XK_braille_dots_123468        0x10028af  /* U+28af BRAILLE PATTERN DOTS-123468 */
#define XK_braille_dots_568           0x10028b0  /* U+28b0 BRAILLE PATTERN DOTS-568 */
#define XK_braille_dots_1568          0x10028b1  /* U+28b1 BRAILLE PATTERN DOTS-1568 */
#define XK_braille_dots_2568          0x10028b2  /* U+28b2 BRAILLE PATTERN DOTS-2568 */
#define XK_braille_dots_12568         0x10028b3  /* U+28b3 BRAILLE PATTERN DOTS-12568 */
#define XK_braille_dots_3568          0x10028b4  /* U+28b4 BRAILLE PATTERN DOTS-3568 */
#define XK_braille_dots_13568         0x10028b5  /* U+28b5 BRAILLE PATTERN DOTS-13568 */
#define XK_braille_dots_23568         0x10028b6  /* U+28b6 BRAILLE PATTERN DOTS-23568 */
#define XK_braille_dots_123568        0x10028b7  /* U+28b7 BRAILLE PATTERN DOTS-123568 */
#define XK_braille_dots_4568          0x10028b8  /* U+28b8 BRAILLE PATTERN DOTS-4568 */
#define XK_braille_dots_14568         0x10028b9  /* U+28b9 BRAILLE PATTERN DOTS-14568 */
#define XK_braille_dots_24568         0x10028ba  /* U+28ba BRAILLE PATTERN DOTS-24568 */
#define XK_braille_dots_124568        0x10028bb  /* U+28bb BRAILLE PATTERN DOTS-124568 */
#define XK_braille_dots_34568         0x10028bc  /* U+28bc BRAILLE PATTERN DOTS-34568 */
#define XK_braille_dots_134568        0x10028bd  /* U+28bd BRAILLE PATTERN DOTS-134568 */
#define XK_braille_dots_234568        0x10028be  /* U+28be BRAILLE PATTERN DOTS-234568 */
#define XK_braille_dots_1234568       0x10028bf  /* U+28bf BRAILLE PATTERN DOTS-1234568 */
#define XK_braille_dots_78            0x10028c0  /* U+28c0 BRAILLE PATTERN DOTS-78 */
#define XK_braille_dots_178           0x10028c1  /* U+28c1 BRAILLE PATTERN DOTS-178 */
#define XK_braille_dots_278           0x10028c2  /* U+28c2 BRAILLE PATTERN DOTS-278 */
#define XK_braille_dots_1278          0x10028c3  /* U+28c3 BRAILLE PATTERN DOTS-1278 */
#define XK_braille_dots_378           0x10028c4  /* U+28c4 BRAILLE PATTERN DOTS-378 */
#define XK_braille_dots_1378          0x10028c5  /* U+28c5 BRAILLE PATTERN DOTS-1378 */
#define XK_braille_dots_2378          0x10028c6  /* U+28c6 BRAILLE PATTERN DOTS-2378 */
#define XK_braille_dots_12378         0x10028c7  /* U+28c7 BRAILLE PATTERN DOTS-12378 */
#define XK_braille_dots_478           0x10028c8  /* U+28c8 BRAILLE PATTERN DOTS-478 */
#define XK_braille_dots_1478          0x10028c9  /* U+28c9 BRAILLE PATTERN DOTS-1478 */
#define XK_braille_dots_2478          0x10028ca  /* U+28ca BRAILLE PATTERN DOTS-2478 */
#define XK_braille_dots_12478         0x10028cb  /* U+28cb BRAILLE PATTERN DOTS-12478 */
#define XK_braille_dots_3478          0x10028cc  /* U+28cc BRAILLE PATTERN DOTS-3478 */
#define XK_braille_dots_13478         0x10028cd  /* U+28cd BRAILLE PATTERN DOTS-13478 */
#define XK_braille_dots_23478         0x10028ce  /* U+28ce BRAILLE PATTERN DOTS-23478 */
#define XK_braille_dots_123478        0x10028cf  /* U+28cf BRAILLE PATTERN DOTS-123478 */
#define XK_braille_dots_578           0x10028d0  /* U+28d0 BRAILLE PATTERN DOTS-578 */
#define XK_braille_dots_1578          0x10028d1  /* U+28d1 BRAILLE PATTERN DOTS-1578 */
#define XK_braille_dots_2578          0x10028d2  /* U+28d2 BRAILLE PATTERN DOTS-2578 */
#define XK_braille_dots_12578         0x10028d3  /* U+28d3 BRAILLE PATTERN DOTS-12578 */
#define XK_braille_dots_3578          0x10028d4  /* U+28d4 BRAILLE PATTERN DOTS-3578 */
#define XK_braille_dots_13578         0x10028d5  /* U+28d5 BRAILLE PATTERN DOTS-13578 */
#define XK_braille_dots_23578         0x10028d6  /* U+28d6 BRAILLE PATTERN DOTS-23578 */
#define XK_braille_dots_123578        0x10028d7  /* U+28d7 BRAILLE PATTERN DOTS-123578 */
#define XK_braille_dots_4578          0x10028d8  /* U+28d8 BRAILLE PATTERN DOTS-4578 */
#define XK_braille_dots_14578         0x10028d9  /* U+28d9 BRAILLE PATTERN DOTS-14578 */
#define XK_braille_dots_24578         0x10028da  /* U+28da BRAILLE PATTERN DOTS-24578 */
#define XK_braille_dots_124578        0x10028db  /* U+28db BRAILLE PATTERN DOTS-124578 */
#define XK_braille_dots_34578         0x10028dc  /* U+28dc BRAILLE PATTERN DOTS-34578 */
#define XK_braille_dots_134578        0x10028dd  /* U+28dd BRAILLE PATTERN DOTS-134578 */
#define XK_braille_dots_234578        0x10028de  /* U+28de BRAILLE PATTERN DOTS-234578 */
#define XK_braille_dots_1234578       0x10028df  /* U+28df BRAILLE PATTERN DOTS-1234578 */
#define XK_braille_dots_678           0x10028e0  /* U+28e0 BRAILLE PATTERN DOTS-678 */
#define XK_braille_dots_1678          0x10028e1  /* U+28e1 BRAILLE PATTERN DOTS-1678 */
#define XK_braille_dots_2678          0x10028e2  /* U+28e2 BRAILLE PATTERN DOTS-2678 */
#define XK_braille_dots_12678         0x10028e3  /* U+28e3 BRAILLE PATTERN DOTS-12678 */
#define XK_braille_dots_3678          0x10028e4  /* U+28e4 BRAILLE PATTERN DOTS-3678 */
#define XK_braille_dots_13678         0x10028e5  /* U+28e5 BRAILLE PATTERN DOTS-13678 */
#define XK_braille_dots_23678         0x10028e6  /* U+28e6 BRAILLE PATTERN DOTS-23678 */
#define XK_braille_dots_123678        0x10028e7  /* U+28e7 BRAILLE PATTERN DOTS-123678 */
#define XK_braille_dots_4678          0x10028e8  /* U+28e8 BRAILLE PATTERN DOTS-4678 */
#define XK_braille_dots_14678         0x10028e9  /* U+28e9 BRAILLE PATTERN DOTS-14678 */
#define XK_braille_dots_24678         0x10028ea  /* U+28ea BRAILLE PATTERN DOTS-24678 */
#define XK_braille_dots_124678        0x10028eb  /* U+28eb BRAILLE PATTERN DOTS-124678 */
#define XK_braille_dots_34678         0x10028ec  /* U+28ec BRAILLE PATTERN DOTS-34678 */
#define XK_braille_dots_134678        0x10028ed  /* U+28ed BRAILLE PATTERN DOTS-134678 */
#define XK_braille_dots_234678        0x10028ee  /* U+28ee BRAILLE PATTERN DOTS-234678 */
#define XK_braille_dots_1234678       0x10028ef  /* U+28ef BRAILLE PATTERN DOTS-1234678 */
#define XK_braille_dots_5678          0x10028f0  /* U+28f0 BRAILLE PATTERN DOTS-5678 */
#define XK_braille_dots_15678         0x10028f1  /* U+28f1 BRAILLE PATTERN DOTS-15678 */
#define XK_braille_dots_25678         0x10028f2  /* U+28f2 BRAILLE PATTERN DOTS-25678 */
#define XK_braille_dots_125678        0x10028f3  /* U+28f3 BRAILLE PATTERN DOTS-125678 */
#define XK_braille_dots_35678         0x10028f4  /* U+28f4 BRAILLE PATTERN DOTS-35678 */
#define XK_braille_dots_135678        0x10028f5  /* U+28f5 BRAILLE PATTERN DOTS-135678 */
#define XK_braille_dots_235678        0x10028f6  /* U+28f6 BRAILLE PATTERN DOTS-235678 */
#define XK_braille_dots_1235678       0x10028f7  /* U+28f7 BRAILLE PATTERN DOTS-1235678 */
#define XK_braille_dots_45678         0x10028f8  /* U+28f8 BRAILLE PATTERN DOTS-45678 */
#define XK_braille_dots_145678        0x10028f9  /* U+28f9 BRAILLE PATTERN DOTS-145678 */
#define XK_braille_dots_245678        0x10028fa  /* U+28fa BRAILLE PATTERN DOTS-245678 */
#define XK_braille_dots_1245678       0x10028fb  /* U+28fb BRAILLE PATTERN DOTS-1245678 */
#define XK_braille_dots_345678        0x10028fc  /* U+28fc BRAILLE PATTERN DOTS-345678 */
#define XK_braille_dots_1345678       0x10028fd  /* U+28fd BRAILLE PATTERN DOTS-1345678 */
#define XK_braille_dots_2345678       0x10028fe  /* U+28fe BRAILLE PATTERN DOTS-2345678 */
#define XK_braille_dots_12345678      0x10028ff  /* U+28ff BRAILLE PATTERN DOTS-12345678 */
#endif /* XK_BRAILLE */

/*
 * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf)
 * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html
 */

#ifdef XK_SINHALA
#define XK_Sinh_ng            0x1000d82  /* U+0D82 SINHALA ANUSVARAYA */
#define XK_Sinh_h2            0x1000d83  /* U+0D83 SINHALA VISARGAYA */
#define XK_Sinh_a             0x1000d85  /* U+0D85 SINHALA AYANNA */
#define XK_Sinh_aa            0x1000d86  /* U+0D86 SINHALA AAYANNA */
#define XK_Sinh_ae            0x1000d87  /* U+0D87 SINHALA AEYANNA */
#define XK_Sinh_aee           0x1000d88  /* U+0D88 SINHALA AEEYANNA */
#define XK_Sinh_i             0x1000d89  /* U+0D89 SINHALA IYANNA */
#define XK_Sinh_ii            0x1000d8a  /* U+0D8A SINHALA IIYANNA */
#define XK_Sinh_u             0x1000d8b  /* U+0D8B SINHALA UYANNA */
#define XK_Sinh_uu            0x1000d8c  /* U+0D8C SINHALA UUYANNA */
#define XK_Sinh_ri            0x1000d8d  /* U+0D8D SINHALA IRUYANNA */
#define XK_Sinh_rii           0x1000d8e  /* U+0D8E SINHALA IRUUYANNA */
#define XK_Sinh_lu            0x1000d8f  /* U+0D8F SINHALA ILUYANNA */
#define XK_Sinh_luu           0x1000d90  /* U+0D90 SINHALA ILUUYANNA */
#define XK_Sinh_e             0x1000d91  /* U+0D91 SINHALA EYANNA */
#define XK_Sinh_ee            0x1000d92  /* U+0D92 SINHALA EEYANNA */
#define XK_Sinh_ai            0x1000d93  /* U+0D93 SINHALA AIYANNA */
#define XK_Sinh_o             0x1000d94  /* U+0D94 SINHALA OYANNA */
#define XK_Sinh_oo            0x1000d95  /* U+0D95 SINHALA OOYANNA */
#define XK_Sinh_au            0x1000d96  /* U+0D96 SINHALA AUYANNA */
#define XK_Sinh_ka            0x1000d9a  /* U+0D9A SINHALA KAYANNA */
#define XK_Sinh_kha           0x1000d9b  /* U+0D9B SINHALA MAHA. KAYANNA */
#define XK_Sinh_ga            0x1000d9c  /* U+0D9C SINHALA GAYANNA */
#define XK_Sinh_gha           0x1000d9d  /* U+0D9D SINHALA MAHA. GAYANNA */
#define XK_Sinh_ng2           0x1000d9e  /* U+0D9E SINHALA KANTAJA NAASIKYAYA */
#define XK_Sinh_nga           0x1000d9f  /* U+0D9F SINHALA SANYAKA GAYANNA */
#define XK_Sinh_ca            0x1000da0  /* U+0DA0 SINHALA CAYANNA */
#define XK_Sinh_cha           0x1000da1  /* U+0DA1 SINHALA MAHA. CAYANNA */
#define XK_Sinh_ja            0x1000da2  /* U+0DA2 SINHALA JAYANNA */
#define XK_Sinh_jha           0x1000da3  /* U+0DA3 SINHALA MAHA. JAYANNA */
#define XK_Sinh_nya           0x1000da4  /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */
#define XK_Sinh_jnya          0x1000da5  /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */
#define XK_Sinh_nja           0x1000da6  /* U+0DA6 SINHALA SANYAKA JAYANNA */
#define XK_Sinh_tta           0x1000da7  /* U+0DA7 SINHALA TTAYANNA */
#define XK_Sinh_ttha          0x1000da8  /* U+0DA8 SINHALA MAHA. TTAYANNA */
#define XK_Sinh_dda           0x1000da9  /* U+0DA9 SINHALA DDAYANNA */
#define XK_Sinh_ddha          0x1000daa  /* U+0DAA SINHALA MAHA. DDAYANNA */
#define XK_Sinh_nna           0x1000dab  /* U+0DAB SINHALA MUURDHAJA NAYANNA */
#define XK_Sinh_ndda          0x1000dac  /* U+0DAC SINHALA SANYAKA DDAYANNA */
#define XK_Sinh_tha           0x1000dad  /* U+0DAD SINHALA TAYANNA */
#define XK_Sinh_thha          0x1000dae  /* U+0DAE SINHALA MAHA. TAYANNA */
#define XK_Sinh_dha           0x1000daf  /* U+0DAF SINHALA DAYANNA */
#define XK_Sinh_dhha          0x1000db0  /* U+0DB0 SINHALA MAHA. DAYANNA */
#define XK_Sinh_na            0x1000db1  /* U+0DB1 SINHALA DANTAJA NAYANNA */
#define XK_Sinh_ndha          0x1000db3  /* U+0DB3 SINHALA SANYAKA DAYANNA */
#define XK_Sinh_pa            0x1000db4  /* U+0DB4 SINHALA PAYANNA */
#define XK_Sinh_pha           0x1000db5  /* U+0DB5 SINHALA MAHA. PAYANNA */
#define XK_Sinh_ba            0x1000db6  /* U+0DB6 SINHALA BAYANNA */
#define XK_Sinh_bha           0x1000db7  /* U+0DB7 SINHALA MAHA. BAYANNA */
#define XK_Sinh_ma            0x1000db8  /* U+0DB8 SINHALA MAYANNA */
#define XK_Sinh_mba           0x1000db9  /* U+0DB9 SINHALA AMBA BAYANNA */
#define XK_Sinh_ya            0x1000dba  /* U+0DBA SINHALA YAYANNA */
#define XK_Sinh_ra            0x1000dbb  /* U+0DBB SINHALA RAYANNA */
#define XK_Sinh_la            0x1000dbd  /* U+0DBD SINHALA DANTAJA LAYANNA */
#define XK_Sinh_va            0x1000dc0  /* U+0DC0 SINHALA VAYANNA */
#define XK_Sinh_sha           0x1000dc1  /* U+0DC1 SINHALA TAALUJA SAYANNA */
#define XK_Sinh_ssha          0x1000dc2  /* U+0DC2 SINHALA MUURDHAJA SAYANNA */
#define XK_Sinh_sa            0x1000dc3  /* U+0DC3 SINHALA DANTAJA SAYANNA */
#define XK_Sinh_ha            0x1000dc4  /* U+0DC4 SINHALA HAYANNA */
#define XK_Sinh_lla           0x1000dc5  /* U+0DC5 SINHALA MUURDHAJA LAYANNA */
#define XK_Sinh_fa            0x1000dc6  /* U+0DC6 SINHALA FAYANNA */
#define XK_Sinh_al            0x1000dca  /* U+0DCA SINHALA AL-LAKUNA */
#define XK_Sinh_aa2           0x1000dcf  /* U+0DCF SINHALA AELA-PILLA */
#define XK_Sinh_ae2           0x1000dd0  /* U+0DD0 SINHALA AEDA-PILLA */
#define XK_Sinh_aee2          0x1000dd1  /* U+0DD1 SINHALA DIGA AEDA-PILLA */
#define XK_Sinh_i2            0x1000dd2  /* U+0DD2 SINHALA IS-PILLA */
#define XK_Sinh_ii2           0x1000dd3  /* U+0DD3 SINHALA DIGA IS-PILLA */
#define XK_Sinh_u2            0x1000dd4  /* U+0DD4 SINHALA PAA-PILLA */
#define XK_Sinh_uu2           0x1000dd6  /* U+0DD6 SINHALA DIGA PAA-PILLA */
#define XK_Sinh_ru2           0x1000dd8  /* U+0DD8 SINHALA GAETTA-PILLA */
#define XK_Sinh_e2            0x1000dd9  /* U+0DD9 SINHALA KOMBUVA */
#define XK_Sinh_ee2           0x1000dda  /* U+0DDA SINHALA DIGA KOMBUVA */
#define XK_Sinh_ai2           0x1000ddb  /* U+0DDB SINHALA KOMBU DEKA */
#define XK_Sinh_o2            0x1000ddc  /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/
#define XK_Sinh_oo2           0x1000ddd  /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/
#define XK_Sinh_au2           0x1000dde  /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */
#define XK_Sinh_lu2           0x1000ddf  /* U+0DDF SINHALA GAYANUKITTA */
#define XK_Sinh_ruu2          0x1000df2  /* U+0DF2 SINHALA DIGA GAETTA-PILLA */
#define XK_Sinh_luu2          0x1000df3  /* U+0DF3 SINHALA DIGA GAYANUKITTA */
#define XK_Sinh_kunddaliya    0x1000df4  /* U+0DF4 SINHALA KUNDDALIYA */
#endif /* XK_SINHALA */

/* Multimedia keys, defined same as on Linux
 * /usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon-keysyms.h
 */

#ifndef TK_NO_DEPRECATED
#define XK_XF86AudioLowerVolume	0x1008FF11   /* Volume control down        */
#define XK_XF86AudioMute	0x1008FF12   /* Mute sound from the system */
#define XK_XF86AudioRaiseVolume	0x1008FF13   /* Volume control up          */
#define XK_XF86AudioPlay	0x1008FF14   /* Start playing of audio >   */
#define XK_XF86AudioStop	0x1008FF15   /* Stop playing audio         */
#define XK_XF86AudioPrev	0x1008FF16   /* Previous track             */
#define XK_XF86AudioNext	0x1008FF17   /* Next track                 */
#endif /* !TK_NO_DEPRECATED */

<
<
|
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>







|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|

|


|
|
|
|
|
|
|
|
|
|





|
<
<
<
<



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<



|
|
|
|
|
|
|
|
|
|
|







|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|




|
|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|

|
|
|
|
|
|
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|



|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
<
|
|



|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
|
|
|
<
<
<
<
<
<
|
<
<
<
<
|
<
|
|
<
|







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




<




|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




<




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
<
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
<
<
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|



|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





<







<



1





2


3














4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


































































27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51




52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71





72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240














































































































































































































241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562





























563
564
565
566
567
568
569
570
571
572
573


574
575
576






577




578

579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

















667











668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715













716
717
718
719
720
721
722
723
































724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916

917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005


1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

































































































































1132




1133

1134
















1135































1136






















1137




























1138








1139



1140




1141





































































































1142



1143









































1144



1145























1146



1147





























































































1148

1149















1150



































1151


1152
1153
1154
1155
1156

















































































































1157
1158
1159
1160
1161
1162














































































































































1163




1164


1165
1166
1167












































































1168
1169
1170
1171
1172
1173

1174
1175
1176
1177
1178
1179
1180

1181


/* $XConsortium: keysymdef.h,v 1.15 93/04/02 10:57:36 rws Exp $ */








/***********************************************************














Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

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, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/



































































#define XK_VoidSymbol		0xFFFFFF	/* void symbol */

#ifdef XK_MISCELLANY
/*
 * TTY Functions, cleverly chosen to map to ascii, for convenience of
 * programming, but could have been arbitrary (at the cost of lookup
 * tables in client code.
 */

#define XK_BackSpace		0xFF08	/* back space, back char */
#define XK_Tab			0xFF09
#define XK_Linefeed		0xFF0A	/* Linefeed, LF */
#define XK_Clear		0xFF0B
#define XK_Return		0xFF0D	/* Return, enter */
#define XK_Pause		0xFF13	/* Pause, hold */
#define XK_Scroll_Lock		0xFF14
#define XK_Sys_Req		0xFF15
#define XK_Escape		0xFF1B
#define XK_Delete		0xFFFF	/* Delete, rubout */



/* International & multi-key character composition */

#define XK_Multi_key		0xFF20  /* Multi-key character compose */





/* Japanese keyboard support */

#define XK_Kanji		0xFF21	/* Kanji, Kanji convert */
#define XK_Muhenkan		0xFF22  /* Cancel Conversion */
#define XK_Henkan_Mode		0xFF23  /* Start/Stop Conversion */
#define XK_Henkan		0xFF23  /* Alias for Henkan_Mode */
#define XK_Romaji		0xFF24  /* to Romaji */
#define XK_Hiragana		0xFF25  /* to Hiragana */
#define XK_Katakana		0xFF26  /* to Katakana */
#define XK_Hiragana_Katakana	0xFF27  /* Hiragana/Katakana toggle */
#define XK_Zenkaku		0xFF28  /* to Zenkaku */
#define XK_Hankaku		0xFF29  /* to Hankaku */
#define XK_Zenkaku_Hankaku	0xFF2A  /* Zenkaku/Hankaku toggle */
#define XK_Touroku		0xFF2B  /* Add to Dictionary */
#define XK_Massyo		0xFF2C  /* Delete from Dictionary */
#define XK_Kana_Lock		0xFF2D  /* Kana Lock */
#define XK_Kana_Shift		0xFF2E  /* Kana Shift */
#define XK_Eisu_Shift		0xFF2F  /* Alphanumeric Shift */
#define XK_Eisu_toggle		0xFF30  /* Alphanumeric toggle */






/* Cursor control & motion */

#define XK_Home			0xFF50
#define XK_Left			0xFF51	/* Move left, left arrow */
#define XK_Up			0xFF52	/* Move up, up arrow */
#define XK_Right		0xFF53	/* Move right, right arrow */
#define XK_Down			0xFF54	/* Move down, down arrow */
#define XK_Prior		0xFF55	/* Prior, previous */
#define XK_Page_Up		0xFF55
#define XK_Next			0xFF56	/* Next */
#define XK_Page_Down		0xFF56
#define XK_End			0xFF57	/* EOL */
#define XK_Begin		0xFF58	/* BOL */

/* Special Windows keyboard keys */

#define XK_Win_L		0xFF5B	/* Left-hand Windows */
#define XK_Win_R		0xFF5C	/* Right-hand Windows */
#define XK_App			0xFF5D	/* Menu key */

/* Misc Functions */

#define XK_Select		0xFF60	/* Select, mark */
#define XK_Print		0xFF61
#define XK_Execute		0xFF62	/* Execute, run, do */
#define XK_Insert		0xFF63	/* Insert, insert here */
#define XK_Undo			0xFF65	/* Undo, oops */
#define XK_Redo			0xFF66	/* redo, again */
#define XK_Menu			0xFF67
#define XK_Find			0xFF68	/* Find, search */
#define XK_Cancel		0xFF69	/* Cancel, stop, abort, exit */
#define XK_Help			0xFF6A	/* Help, ? */
#define XK_Break		0xFF6B
#define XK_Mode_switch		0xFF7E	/* Character set switch */
#define XK_script_switch        0xFF7E  /* Alias for mode_switch */
#define XK_Num_Lock		0xFF7F

/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */

#define XK_KP_Space		0xFF80	/* space */
#define XK_KP_Tab		0xFF89
#define XK_KP_Enter		0xFF8D	/* enter */
#define XK_KP_F1		0xFF91	/* PF1, KP_A, ... */
#define XK_KP_F2		0xFF92
#define XK_KP_F3		0xFF93
#define XK_KP_F4		0xFF94
#define XK_KP_Home		0xFF95
#define XK_KP_Left		0xFF96
#define XK_KP_Up		0xFF97
#define XK_KP_Right		0xFF98
#define XK_KP_Down		0xFF99
#define XK_KP_Prior		0xFF9A
#define XK_KP_Page_Up		0xFF9A
#define XK_KP_Next		0xFF9B
#define XK_KP_Page_Down		0xFF9B
#define XK_KP_End		0xFF9C
#define XK_KP_Begin		0xFF9D
#define XK_KP_Insert		0xFF9E
#define XK_KP_Delete		0xFF9F
#define XK_KP_Equal		0xFFBD	/* equals */
#define XK_KP_Multiply		0xFFAA
#define XK_KP_Add		0xFFAB
#define XK_KP_Separator		0xFFAC	/* separator, often comma */
#define XK_KP_Subtract		0xFFAD
#define XK_KP_Decimal		0xFFAE
#define XK_KP_Divide		0xFFAF

#define XK_KP_0			0xFFB0
#define XK_KP_1			0xFFB1
#define XK_KP_2			0xFFB2
#define XK_KP_3			0xFFB3
#define XK_KP_4			0xFFB4
#define XK_KP_5			0xFFB5
#define XK_KP_6			0xFFB6
#define XK_KP_7			0xFFB7
#define XK_KP_8			0xFFB8
#define XK_KP_9			0xFFB9



/*
 * Auxilliary Functions; note the duplicate definitions for left and right
 * function keys;  Sun keyboards and a few other manufactures have such
 * function key groups on the left and/or right sides of the keyboard.
 * We've not found a keyboard with more than 35 function keys total.
 */

#define XK_F1			0xFFBE
#define XK_F2			0xFFBF
#define XK_F3			0xFFC0
#define XK_F4			0xFFC1
#define XK_F5			0xFFC2
#define XK_F6			0xFFC3
#define XK_F7			0xFFC4
#define XK_F8			0xFFC5
#define XK_F9			0xFFC6
#define XK_F10			0xFFC7
#define XK_F11			0xFFC8
#define XK_L1			0xFFC8
#define XK_F12			0xFFC9
#define XK_L2			0xFFC9
#define XK_F13			0xFFCA
#define XK_L3			0xFFCA
#define XK_F14			0xFFCB
#define XK_L4			0xFFCB
#define XK_F15			0xFFCC
#define XK_L5			0xFFCC
#define XK_F16			0xFFCD
#define XK_L6			0xFFCD
#define XK_F17			0xFFCE
#define XK_L7			0xFFCE
#define XK_F18			0xFFCF
#define XK_L8			0xFFCF
#define XK_F19			0xFFD0
#define XK_L9			0xFFD0
#define XK_F20			0xFFD1
#define XK_L10			0xFFD1
#define XK_F21			0xFFD2
#define XK_R1			0xFFD2
#define XK_F22			0xFFD3
#define XK_R2			0xFFD3
#define XK_F23			0xFFD4
#define XK_R3			0xFFD4
#define XK_F24			0xFFD5
#define XK_R4			0xFFD5
#define XK_F25			0xFFD6
#define XK_R5			0xFFD6
#define XK_F26			0xFFD7
#define XK_R6			0xFFD7
#define XK_F27			0xFFD8
#define XK_R7			0xFFD8
#define XK_F28			0xFFD9
#define XK_R8			0xFFD9
#define XK_F29			0xFFDA
#define XK_R9			0xFFDA
#define XK_F30			0xFFDB
#define XK_R10			0xFFDB
#define XK_F31			0xFFDC
#define XK_R11			0xFFDC
#define XK_F32			0xFFDD
#define XK_R12			0xFFDD
#define XK_F33			0xFFDE
#define XK_R13			0xFFDE
#define XK_F34			0xFFDF
#define XK_R14			0xFFDF
#define XK_F35			0xFFE0
#define XK_R15			0xFFE0

/* Modifiers */

#define XK_Shift_L		0xFFE1	/* Left shift */
#define XK_Shift_R		0xFFE2	/* Right shift */
#define XK_Control_L		0xFFE3	/* Left control */
#define XK_Control_R		0xFFE4	/* Right control */
#define XK_Caps_Lock		0xFFE5	/* Caps lock */
#define XK_Shift_Lock		0xFFE6	/* Shift lock */

#define XK_Meta_L		0xFFE7	/* Left meta */
#define XK_Meta_R		0xFFE8	/* Right meta */
#define XK_Alt_L		0xFFE9	/* Left alt */
#define XK_Alt_R		0xFFEA	/* Right alt */
#define XK_Super_L		0xFFEB	/* Left super */
#define XK_Super_R		0xFFEC	/* Right super */
#define XK_Hyper_L		0xFFED	/* Left hyper */
#define XK_Hyper_R		0xFFEE	/* Right hyper */
#endif /* XK_MISCELLANY */

/*














































































































































































































 *  Latin 1

 *  Byte 3 = 0
 */
#ifdef XK_LATIN1
#define XK_space               0x020
#define XK_exclam              0x021
#define XK_quotedbl            0x022
#define XK_numbersign          0x023
#define XK_dollar              0x024
#define XK_percent             0x025
#define XK_ampersand           0x026
#define XK_apostrophe          0x027
#define XK_quoteright          0x027	/* deprecated */
#define XK_parenleft           0x028
#define XK_parenright          0x029
#define XK_asterisk            0x02a
#define XK_plus                0x02b
#define XK_comma               0x02c
#define XK_minus               0x02d
#define XK_period              0x02e
#define XK_slash               0x02f
#define XK_0                   0x030
#define XK_1                   0x031
#define XK_2                   0x032
#define XK_3                   0x033
#define XK_4                   0x034
#define XK_5                   0x035
#define XK_6                   0x036
#define XK_7                   0x037
#define XK_8                   0x038
#define XK_9                   0x039
#define XK_colon               0x03a
#define XK_semicolon           0x03b
#define XK_less                0x03c
#define XK_equal               0x03d
#define XK_greater             0x03e
#define XK_question            0x03f
#define XK_at                  0x040
#define XK_A                   0x041
#define XK_B                   0x042
#define XK_C                   0x043
#define XK_D                   0x044
#define XK_E                   0x045
#define XK_F                   0x046
#define XK_G                   0x047
#define XK_H                   0x048
#define XK_I                   0x049
#define XK_J                   0x04a
#define XK_K                   0x04b
#define XK_L                   0x04c
#define XK_M                   0x04d
#define XK_N                   0x04e
#define XK_O                   0x04f
#define XK_P                   0x050
#define XK_Q                   0x051
#define XK_R                   0x052
#define XK_S                   0x053
#define XK_T                   0x054
#define XK_U                   0x055
#define XK_V                   0x056
#define XK_W                   0x057
#define XK_X                   0x058
#define XK_Y                   0x059
#define XK_Z                   0x05a
#define XK_bracketleft         0x05b
#define XK_backslash           0x05c
#define XK_bracketright        0x05d
#define XK_asciicircum         0x05e
#define XK_underscore          0x05f
#define XK_grave               0x060
#define XK_quoteleft           0x060	/* deprecated */
#define XK_a                   0x061
#define XK_b                   0x062
#define XK_c                   0x063
#define XK_d                   0x064
#define XK_e                   0x065
#define XK_f                   0x066
#define XK_g                   0x067
#define XK_h                   0x068
#define XK_i                   0x069
#define XK_j                   0x06a
#define XK_k                   0x06b
#define XK_l                   0x06c
#define XK_m                   0x06d
#define XK_n                   0x06e
#define XK_o                   0x06f
#define XK_p                   0x070
#define XK_q                   0x071
#define XK_r                   0x072
#define XK_s                   0x073
#define XK_t                   0x074
#define XK_u                   0x075
#define XK_v                   0x076
#define XK_w                   0x077
#define XK_x                   0x078
#define XK_y                   0x079
#define XK_z                   0x07a
#define XK_braceleft           0x07b
#define XK_bar                 0x07c
#define XK_braceright          0x07d
#define XK_asciitilde          0x07e

#define XK_nobreakspace        0x0a0
#define XK_exclamdown          0x0a1
#define XK_cent        	       0x0a2
#define XK_sterling            0x0a3
#define XK_currency            0x0a4
#define XK_yen                 0x0a5
#define XK_brokenbar           0x0a6
#define XK_section             0x0a7
#define XK_diaeresis           0x0a8
#define XK_copyright           0x0a9
#define XK_ordfeminine         0x0aa
#define XK_guillemotleft       0x0ab	/* left angle quotation mark */
#define XK_notsign             0x0ac
#define XK_hyphen              0x0ad
#define XK_registered          0x0ae
#define XK_macron              0x0af
#define XK_degree              0x0b0
#define XK_plusminus           0x0b1
#define XK_twosuperior         0x0b2
#define XK_threesuperior       0x0b3
#define XK_acute               0x0b4
#define XK_mu                  0x0b5
#define XK_paragraph           0x0b6
#define XK_periodcentered      0x0b7
#define XK_cedilla             0x0b8
#define XK_onesuperior         0x0b9
#define XK_masculine           0x0ba
#define XK_guillemotright      0x0bb	/* right angle quotation mark */
#define XK_onequarter          0x0bc
#define XK_onehalf             0x0bd
#define XK_threequarters       0x0be
#define XK_questiondown        0x0bf
#define XK_Agrave              0x0c0
#define XK_Aacute              0x0c1
#define XK_Acircumflex         0x0c2
#define XK_Atilde              0x0c3
#define XK_Adiaeresis          0x0c4
#define XK_Aring               0x0c5
#define XK_AE                  0x0c6
#define XK_Ccedilla            0x0c7
#define XK_Egrave              0x0c8
#define XK_Eacute              0x0c9
#define XK_Ecircumflex         0x0ca
#define XK_Ediaeresis          0x0cb
#define XK_Igrave              0x0cc
#define XK_Iacute              0x0cd
#define XK_Icircumflex         0x0ce
#define XK_Idiaeresis          0x0cf
#define XK_ETH                 0x0d0
#define XK_Eth                 0x0d0	/* deprecated */
#define XK_Ntilde              0x0d1
#define XK_Ograve              0x0d2
#define XK_Oacute              0x0d3
#define XK_Ocircumflex         0x0d4
#define XK_Otilde              0x0d5
#define XK_Odiaeresis          0x0d6
#define XK_multiply            0x0d7

#define XK_Ooblique            0x0d8
#define XK_Ugrave              0x0d9
#define XK_Uacute              0x0da
#define XK_Ucircumflex         0x0db
#define XK_Udiaeresis          0x0dc
#define XK_Yacute              0x0dd
#define XK_THORN               0x0de
#define XK_Thorn               0x0de	/* deprecated */
#define XK_ssharp              0x0df
#define XK_agrave              0x0e0
#define XK_aacute              0x0e1
#define XK_acircumflex         0x0e2
#define XK_atilde              0x0e3
#define XK_adiaeresis          0x0e4
#define XK_aring               0x0e5
#define XK_ae                  0x0e6
#define XK_ccedilla            0x0e7
#define XK_egrave              0x0e8
#define XK_eacute              0x0e9
#define XK_ecircumflex         0x0ea
#define XK_ediaeresis          0x0eb
#define XK_igrave              0x0ec
#define XK_iacute              0x0ed
#define XK_icircumflex         0x0ee
#define XK_idiaeresis          0x0ef
#define XK_eth                 0x0f0
#define XK_ntilde              0x0f1
#define XK_ograve              0x0f2
#define XK_oacute              0x0f3
#define XK_ocircumflex         0x0f4
#define XK_otilde              0x0f5
#define XK_odiaeresis          0x0f6
#define XK_division            0x0f7
#define XK_oslash              0x0f8

#define XK_ugrave              0x0f9
#define XK_uacute              0x0fa
#define XK_ucircumflex         0x0fb
#define XK_udiaeresis          0x0fc
#define XK_yacute              0x0fd
#define XK_thorn               0x0fe
#define XK_ydiaeresis          0x0ff
#endif /* XK_LATIN1 */

/*
 *   Latin 2
 *   Byte 3 = 1
 */

#ifdef XK_LATIN2
#define XK_Aogonek             0x1a1
#define XK_breve               0x1a2
#define XK_Lstroke             0x1a3
#define XK_Lcaron              0x1a5
#define XK_Sacute              0x1a6
#define XK_Scaron              0x1a9
#define XK_Scedilla            0x1aa
#define XK_Tcaron              0x1ab
#define XK_Zacute              0x1ac
#define XK_Zcaron              0x1ae
#define XK_Zabovedot           0x1af
#define XK_aogonek             0x1b1
#define XK_ogonek              0x1b2
#define XK_lstroke             0x1b3
#define XK_lcaron              0x1b5
#define XK_sacute              0x1b6
#define XK_caron               0x1b7
#define XK_scaron              0x1b9
#define XK_scedilla            0x1ba
#define XK_tcaron              0x1bb
#define XK_zacute              0x1bc
#define XK_doubleacute         0x1bd
#define XK_zcaron              0x1be
#define XK_zabovedot           0x1bf
#define XK_Racute              0x1c0
#define XK_Abreve              0x1c3
#define XK_Lacute              0x1c5
#define XK_Cacute              0x1c6
#define XK_Ccaron              0x1c8
#define XK_Eogonek             0x1ca
#define XK_Ecaron              0x1cc
#define XK_Dcaron              0x1cf
#define XK_Dstroke             0x1d0
#define XK_Nacute              0x1d1
#define XK_Ncaron              0x1d2
#define XK_Odoubleacute        0x1d5
#define XK_Rcaron              0x1d8
#define XK_Uring               0x1d9
#define XK_Udoubleacute        0x1db
#define XK_Tcedilla            0x1de
#define XK_racute              0x1e0
#define XK_abreve              0x1e3
#define XK_lacute              0x1e5
#define XK_cacute              0x1e6
#define XK_ccaron              0x1e8
#define XK_eogonek             0x1ea
#define XK_ecaron              0x1ec
#define XK_dcaron              0x1ef
#define XK_dstroke             0x1f0
#define XK_nacute              0x1f1
#define XK_ncaron              0x1f2
#define XK_odoubleacute        0x1f5
#define XK_udoubleacute        0x1fb
#define XK_rcaron              0x1f8
#define XK_uring               0x1f9

#define XK_tcedilla            0x1fe
#define XK_abovedot            0x1ff
#endif /* XK_LATIN2 */

/*
 *   Latin 3
 *   Byte 3 = 2
 */

#ifdef XK_LATIN3
#define XK_Hstroke             0x2a1
#define XK_Hcircumflex         0x2a6
#define XK_Iabovedot           0x2a9
#define XK_Gbreve              0x2ab
#define XK_Jcircumflex         0x2ac
#define XK_hstroke             0x2b1
#define XK_hcircumflex         0x2b6
#define XK_idotless            0x2b9
#define XK_gbreve              0x2bb
#define XK_jcircumflex         0x2bc
#define XK_Cabovedot           0x2c5
#define XK_Ccircumflex         0x2c6
#define XK_Gabovedot           0x2d5
#define XK_Gcircumflex         0x2d8
#define XK_Ubreve              0x2dd
#define XK_Scircumflex         0x2de
#define XK_cabovedot           0x2e5
#define XK_ccircumflex         0x2e6
#define XK_gabovedot           0x2f5
#define XK_gcircumflex         0x2f8
#define XK_ubreve              0x2fd
#define XK_scircumflex         0x2fe
#endif /* XK_LATIN3 */


/*
 *   Latin 4
 *   Byte 3 = 3
 */

#ifdef XK_LATIN4
#define XK_kra                 0x3a2
#define XK_kappa               0x3a2	/* deprecated */
#define XK_Rcedilla            0x3a3
#define XK_Itilde              0x3a5
#define XK_Lcedilla            0x3a6
#define XK_Emacron             0x3aa
#define XK_Gcedilla            0x3ab
#define XK_Tslash              0x3ac
#define XK_rcedilla            0x3b3
#define XK_itilde              0x3b5
#define XK_lcedilla            0x3b6
#define XK_emacron             0x3ba
#define XK_gcedilla            0x3bb
#define XK_tslash              0x3bc
#define XK_ENG                 0x3bd
#define XK_eng                 0x3bf
#define XK_Amacron             0x3c0
#define XK_Iogonek             0x3c7





























#define XK_Eabovedot           0x3cc
#define XK_Imacron             0x3cf
#define XK_Ncedilla            0x3d1
#define XK_Omacron             0x3d2
#define XK_Kcedilla            0x3d3
#define XK_Uogonek             0x3d9
#define XK_Utilde              0x3dd
#define XK_Umacron             0x3de
#define XK_amacron             0x3e0
#define XK_iogonek             0x3e7
#define XK_eabovedot           0x3ec


#define XK_imacron             0x3ef
#define XK_ncedilla            0x3f1
#define XK_omacron             0x3f2






#define XK_kcedilla            0x3f3




#define XK_uogonek             0x3f9

#define XK_utilde              0x3fd
#define XK_umacron             0x3fe

#endif /* XK_LATIN4 */

/*
 * Katakana
 * Byte 3 = 4
 */

#ifdef XK_KATAKANA
#define XK_overline				       0x47e
#define XK_kana_fullstop                               0x4a1
#define XK_kana_openingbracket                         0x4a2
#define XK_kana_closingbracket                         0x4a3
#define XK_kana_comma                                  0x4a4
#define XK_kana_conjunctive                            0x4a5
#define XK_kana_middledot                              0x4a5  /* deprecated */
#define XK_kana_WO                                     0x4a6
#define XK_kana_a                                      0x4a7
#define XK_kana_i                                      0x4a8
#define XK_kana_u                                      0x4a9
#define XK_kana_e                                      0x4aa
#define XK_kana_o                                      0x4ab
#define XK_kana_ya                                     0x4ac
#define XK_kana_yu                                     0x4ad
#define XK_kana_yo                                     0x4ae
#define XK_kana_tsu                                    0x4af
#define XK_kana_tu                                     0x4af  /* deprecated */
#define XK_prolongedsound                              0x4b0
#define XK_kana_A                                      0x4b1
#define XK_kana_I                                      0x4b2
#define XK_kana_U                                      0x4b3
#define XK_kana_E                                      0x4b4
#define XK_kana_O                                      0x4b5
#define XK_kana_KA                                     0x4b6
#define XK_kana_KI                                     0x4b7
#define XK_kana_KU                                     0x4b8
#define XK_kana_KE                                     0x4b9
#define XK_kana_KO                                     0x4ba
#define XK_kana_SA                                     0x4bb
#define XK_kana_SHI                                    0x4bc
#define XK_kana_SU                                     0x4bd
#define XK_kana_SE                                     0x4be
#define XK_kana_SO                                     0x4bf
#define XK_kana_TA                                     0x4c0
#define XK_kana_CHI                                    0x4c1
#define XK_kana_TI                                     0x4c1  /* deprecated */
#define XK_kana_TSU                                    0x4c2
#define XK_kana_TU                                     0x4c2  /* deprecated */
#define XK_kana_TE                                     0x4c3
#define XK_kana_TO                                     0x4c4
#define XK_kana_NA                                     0x4c5
#define XK_kana_NI                                     0x4c6
#define XK_kana_NU                                     0x4c7
#define XK_kana_NE                                     0x4c8
#define XK_kana_NO                                     0x4c9
#define XK_kana_HA                                     0x4ca
#define XK_kana_HI                                     0x4cb
#define XK_kana_FU                                     0x4cc
#define XK_kana_HU                                     0x4cc  /* deprecated */
#define XK_kana_HE                                     0x4cd
#define XK_kana_HO                                     0x4ce
#define XK_kana_MA                                     0x4cf
#define XK_kana_MI                                     0x4d0
#define XK_kana_MU                                     0x4d1
#define XK_kana_ME                                     0x4d2
#define XK_kana_MO                                     0x4d3
#define XK_kana_YA                                     0x4d4
#define XK_kana_YU                                     0x4d5
#define XK_kana_YO                                     0x4d6
#define XK_kana_RA                                     0x4d7
#define XK_kana_RI                                     0x4d8
#define XK_kana_RU                                     0x4d9
#define XK_kana_RE                                     0x4da
#define XK_kana_RO                                     0x4db
#define XK_kana_WA                                     0x4dc
#define XK_kana_N                                      0x4dd
#define XK_voicedsound                                 0x4de
#define XK_semivoicedsound                             0x4df
#define XK_kana_switch          0xFF7E  /* Alias for mode_switch */
#endif /* XK_KATAKANA */

/*
 *  Arabic
 *  Byte 3 = 5
 */

#ifdef XK_ARABIC

















#define XK_Arabic_comma                                0x5ac











#define XK_Arabic_semicolon                            0x5bb
#define XK_Arabic_question_mark                        0x5bf
#define XK_Arabic_hamza                                0x5c1
#define XK_Arabic_maddaonalef                          0x5c2
#define XK_Arabic_hamzaonalef                          0x5c3
#define XK_Arabic_hamzaonwaw                           0x5c4
#define XK_Arabic_hamzaunderalef                       0x5c5
#define XK_Arabic_hamzaonyeh                           0x5c6
#define XK_Arabic_alef                                 0x5c7
#define XK_Arabic_beh                                  0x5c8
#define XK_Arabic_tehmarbuta                           0x5c9
#define XK_Arabic_teh                                  0x5ca
#define XK_Arabic_theh                                 0x5cb
#define XK_Arabic_jeem                                 0x5cc
#define XK_Arabic_hah                                  0x5cd
#define XK_Arabic_khah                                 0x5ce
#define XK_Arabic_dal                                  0x5cf
#define XK_Arabic_thal                                 0x5d0
#define XK_Arabic_ra                                   0x5d1
#define XK_Arabic_zain                                 0x5d2
#define XK_Arabic_seen                                 0x5d3
#define XK_Arabic_sheen                                0x5d4
#define XK_Arabic_sad                                  0x5d5
#define XK_Arabic_dad                                  0x5d6
#define XK_Arabic_tah                                  0x5d7
#define XK_Arabic_zah                                  0x5d8
#define XK_Arabic_ain                                  0x5d9
#define XK_Arabic_ghain                                0x5da
#define XK_Arabic_tatweel                              0x5e0
#define XK_Arabic_feh                                  0x5e1
#define XK_Arabic_qaf                                  0x5e2
#define XK_Arabic_kaf                                  0x5e3
#define XK_Arabic_lam                                  0x5e4
#define XK_Arabic_meem                                 0x5e5
#define XK_Arabic_noon                                 0x5e6
#define XK_Arabic_ha                                   0x5e7
#define XK_Arabic_heh                                  0x5e7  /* deprecated */
#define XK_Arabic_waw                                  0x5e8
#define XK_Arabic_alefmaksura                          0x5e9
#define XK_Arabic_yeh                                  0x5ea
#define XK_Arabic_fathatan                             0x5eb
#define XK_Arabic_dammatan                             0x5ec
#define XK_Arabic_kasratan                             0x5ed
#define XK_Arabic_fatha                                0x5ee
#define XK_Arabic_damma                                0x5ef
#define XK_Arabic_kasra                                0x5f0
#define XK_Arabic_shadda                               0x5f1
#define XK_Arabic_sukun                                0x5f2













#define XK_Arabic_switch        0xFF7E  /* Alias for mode_switch */
#endif /* XK_ARABIC */

/*
 * Cyrillic
 * Byte 3 = 6
 */
#ifdef XK_CYRILLIC
































#define XK_Serbian_dje                                 0x6a1
#define XK_Macedonia_gje                               0x6a2
#define XK_Cyrillic_io                                 0x6a3
#define XK_Ukrainian_ie                                0x6a4
#define XK_Ukranian_je                                 0x6a4  /* deprecated */
#define XK_Macedonia_dse                               0x6a5
#define XK_Ukrainian_i                                 0x6a6
#define XK_Ukranian_i                                  0x6a6  /* deprecated */
#define XK_Ukrainian_yi                                0x6a7
#define XK_Ukranian_yi                                 0x6a7  /* deprecated */
#define XK_Cyrillic_je                                 0x6a8
#define XK_Serbian_je                                  0x6a8  /* deprecated */
#define XK_Cyrillic_lje                                0x6a9
#define XK_Serbian_lje                                 0x6a9  /* deprecated */
#define XK_Cyrillic_nje                                0x6aa
#define XK_Serbian_nje                                 0x6aa  /* deprecated */
#define XK_Serbian_tshe                                0x6ab
#define XK_Macedonia_kje                               0x6ac

#define XK_Byelorussian_shortu                         0x6ae
#define XK_Cyrillic_dzhe                               0x6af
#define XK_Serbian_dze                                 0x6af  /* deprecated */
#define XK_numerosign                                  0x6b0
#define XK_Serbian_DJE                                 0x6b1
#define XK_Macedonia_GJE                               0x6b2
#define XK_Cyrillic_IO                                 0x6b3
#define XK_Ukrainian_IE                                0x6b4
#define XK_Ukranian_JE                                 0x6b4  /* deprecated */
#define XK_Macedonia_DSE                               0x6b5
#define XK_Ukrainian_I                                 0x6b6
#define XK_Ukranian_I                                  0x6b6  /* deprecated */
#define XK_Ukrainian_YI                                0x6b7
#define XK_Ukranian_YI                                 0x6b7  /* deprecated */
#define XK_Cyrillic_JE                                 0x6b8
#define XK_Serbian_JE                                  0x6b8  /* deprecated */
#define XK_Cyrillic_LJE                                0x6b9
#define XK_Serbian_LJE                                 0x6b9  /* deprecated */
#define XK_Cyrillic_NJE                                0x6ba
#define XK_Serbian_NJE                                 0x6ba  /* deprecated */
#define XK_Serbian_TSHE                                0x6bb
#define XK_Macedonia_KJE                               0x6bc

#define XK_Byelorussian_SHORTU                         0x6be
#define XK_Cyrillic_DZHE                               0x6bf
#define XK_Serbian_DZE                                 0x6bf  /* deprecated */
#define XK_Cyrillic_yu                                 0x6c0
#define XK_Cyrillic_a                                  0x6c1
#define XK_Cyrillic_be                                 0x6c2
#define XK_Cyrillic_tse                                0x6c3
#define XK_Cyrillic_de                                 0x6c4
#define XK_Cyrillic_ie                                 0x6c5
#define XK_Cyrillic_ef                                 0x6c6
#define XK_Cyrillic_ghe                                0x6c7
#define XK_Cyrillic_ha                                 0x6c8
#define XK_Cyrillic_i                                  0x6c9
#define XK_Cyrillic_shorti                             0x6ca
#define XK_Cyrillic_ka                                 0x6cb
#define XK_Cyrillic_el                                 0x6cc
#define XK_Cyrillic_em                                 0x6cd
#define XK_Cyrillic_en                                 0x6ce
#define XK_Cyrillic_o                                  0x6cf
#define XK_Cyrillic_pe                                 0x6d0
#define XK_Cyrillic_ya                                 0x6d1
#define XK_Cyrillic_er                                 0x6d2
#define XK_Cyrillic_es                                 0x6d3
#define XK_Cyrillic_te                                 0x6d4
#define XK_Cyrillic_u                                  0x6d5
#define XK_Cyrillic_zhe                                0x6d6
#define XK_Cyrillic_ve                                 0x6d7
#define XK_Cyrillic_softsign                           0x6d8
#define XK_Cyrillic_yeru                               0x6d9
#define XK_Cyrillic_ze                                 0x6da
#define XK_Cyrillic_sha                                0x6db
#define XK_Cyrillic_e                                  0x6dc
#define XK_Cyrillic_shcha                              0x6dd
#define XK_Cyrillic_che                                0x6de
#define XK_Cyrillic_hardsign                           0x6df
#define XK_Cyrillic_YU                                 0x6e0
#define XK_Cyrillic_A                                  0x6e1
#define XK_Cyrillic_BE                                 0x6e2
#define XK_Cyrillic_TSE                                0x6e3
#define XK_Cyrillic_DE                                 0x6e4
#define XK_Cyrillic_IE                                 0x6e5
#define XK_Cyrillic_EF                                 0x6e6
#define XK_Cyrillic_GHE                                0x6e7
#define XK_Cyrillic_HA                                 0x6e8
#define XK_Cyrillic_I                                  0x6e9
#define XK_Cyrillic_SHORTI                             0x6ea
#define XK_Cyrillic_KA                                 0x6eb
#define XK_Cyrillic_EL                                 0x6ec
#define XK_Cyrillic_EM                                 0x6ed
#define XK_Cyrillic_EN                                 0x6ee
#define XK_Cyrillic_O                                  0x6ef
#define XK_Cyrillic_PE                                 0x6f0
#define XK_Cyrillic_YA                                 0x6f1
#define XK_Cyrillic_ER                                 0x6f2
#define XK_Cyrillic_ES                                 0x6f3
#define XK_Cyrillic_TE                                 0x6f4
#define XK_Cyrillic_U                                  0x6f5
#define XK_Cyrillic_ZHE                                0x6f6
#define XK_Cyrillic_VE                                 0x6f7
#define XK_Cyrillic_SOFTSIGN                           0x6f8
#define XK_Cyrillic_YERU                               0x6f9
#define XK_Cyrillic_ZE                                 0x6fa
#define XK_Cyrillic_SHA                                0x6fb
#define XK_Cyrillic_E                                  0x6fc
#define XK_Cyrillic_SHCHA                              0x6fd
#define XK_Cyrillic_CHE                                0x6fe
#define XK_Cyrillic_HARDSIGN                           0x6ff
#endif /* XK_CYRILLIC */

/*
 * Greek

 * Byte 3 = 7
 */

#ifdef XK_GREEK
#define XK_Greek_ALPHAaccent                           0x7a1
#define XK_Greek_EPSILONaccent                         0x7a2
#define XK_Greek_ETAaccent                             0x7a3
#define XK_Greek_IOTAaccent                            0x7a4

#define XK_Greek_IOTAdiaeresis                         0x7a5
#define XK_Greek_OMICRONaccent                         0x7a7
#define XK_Greek_UPSILONaccent                         0x7a8
#define XK_Greek_UPSILONdieresis                       0x7a9
#define XK_Greek_OMEGAaccent                           0x7ab
#define XK_Greek_accentdieresis                        0x7ae
#define XK_Greek_horizbar                              0x7af
#define XK_Greek_alphaaccent                           0x7b1
#define XK_Greek_epsilonaccent                         0x7b2
#define XK_Greek_etaaccent                             0x7b3
#define XK_Greek_iotaaccent                            0x7b4
#define XK_Greek_iotadieresis                          0x7b5
#define XK_Greek_iotaaccentdieresis                    0x7b6
#define XK_Greek_omicronaccent                         0x7b7
#define XK_Greek_upsilonaccent                         0x7b8
#define XK_Greek_upsilondieresis                       0x7b9
#define XK_Greek_upsilonaccentdieresis                 0x7ba
#define XK_Greek_omegaaccent                           0x7bb
#define XK_Greek_ALPHA                                 0x7c1
#define XK_Greek_BETA                                  0x7c2
#define XK_Greek_GAMMA                                 0x7c3
#define XK_Greek_DELTA                                 0x7c4
#define XK_Greek_EPSILON                               0x7c5
#define XK_Greek_ZETA                                  0x7c6
#define XK_Greek_ETA                                   0x7c7
#define XK_Greek_THETA                                 0x7c8
#define XK_Greek_IOTA                                  0x7c9
#define XK_Greek_KAPPA                                 0x7ca
#define XK_Greek_LAMDA                                 0x7cb
#define XK_Greek_LAMBDA                                0x7cb
#define XK_Greek_MU                                    0x7cc
#define XK_Greek_NU                                    0x7cd
#define XK_Greek_XI                                    0x7ce
#define XK_Greek_OMICRON                               0x7cf
#define XK_Greek_PI                                    0x7d0
#define XK_Greek_RHO                                   0x7d1
#define XK_Greek_SIGMA                                 0x7d2
#define XK_Greek_TAU                                   0x7d4
#define XK_Greek_UPSILON                               0x7d5
#define XK_Greek_PHI                                   0x7d6
#define XK_Greek_CHI                                   0x7d7
#define XK_Greek_PSI                                   0x7d8
#define XK_Greek_OMEGA                                 0x7d9
#define XK_Greek_alpha                                 0x7e1
#define XK_Greek_beta                                  0x7e2
#define XK_Greek_gamma                                 0x7e3
#define XK_Greek_delta                                 0x7e4
#define XK_Greek_epsilon                               0x7e5
#define XK_Greek_zeta                                  0x7e6
#define XK_Greek_eta                                   0x7e7
#define XK_Greek_theta                                 0x7e8
#define XK_Greek_iota                                  0x7e9
#define XK_Greek_kappa                                 0x7ea
#define XK_Greek_lamda                                 0x7eb
#define XK_Greek_lambda                                0x7eb
#define XK_Greek_mu                                    0x7ec
#define XK_Greek_nu                                    0x7ed
#define XK_Greek_xi                                    0x7ee
#define XK_Greek_omicron                               0x7ef
#define XK_Greek_pi                                    0x7f0
#define XK_Greek_rho                                   0x7f1
#define XK_Greek_sigma                                 0x7f2
#define XK_Greek_finalsmallsigma                       0x7f3
#define XK_Greek_tau                                   0x7f4
#define XK_Greek_upsilon                               0x7f5
#define XK_Greek_phi                                   0x7f6
#define XK_Greek_chi                                   0x7f7
#define XK_Greek_psi                                   0x7f8
#define XK_Greek_omega                                 0x7f9
#define XK_Greek_switch         0xFF7E  /* Alias for mode_switch */
#endif /* XK_GREEK */

/*
 * Technical

 * Byte 3 = 8
 */

#ifdef XK_TECHNICAL
#define XK_leftradical                                 0x8a1
#define XK_topleftradical                              0x8a2
#define XK_horizconnector                              0x8a3
#define XK_topintegral                                 0x8a4
#define XK_botintegral                                 0x8a5
#define XK_vertconnector                               0x8a6
#define XK_topleftsqbracket                            0x8a7
#define XK_botleftsqbracket                            0x8a8
#define XK_toprightsqbracket                           0x8a9
#define XK_botrightsqbracket                           0x8aa
#define XK_topleftparens                               0x8ab
#define XK_botleftparens                               0x8ac
#define XK_toprightparens                              0x8ad
#define XK_botrightparens                              0x8ae
#define XK_leftmiddlecurlybrace                        0x8af
#define XK_rightmiddlecurlybrace                       0x8b0
#define XK_topleftsummation                            0x8b1
#define XK_botleftsummation                            0x8b2
#define XK_topvertsummationconnector                   0x8b3
#define XK_botvertsummationconnector                   0x8b4
#define XK_toprightsummation                           0x8b5
#define XK_botrightsummation                           0x8b6
#define XK_rightmiddlesummation                        0x8b7
#define XK_lessthanequal                               0x8bc
#define XK_notequal                                    0x8bd
#define XK_greaterthanequal                            0x8be
#define XK_integral                                    0x8bf
#define XK_therefore                                   0x8c0
#define XK_variation                                   0x8c1
#define XK_infinity                                    0x8c2
#define XK_nabla                                       0x8c5
#define XK_approximate                                 0x8c8
#define XK_similarequal                                0x8c9
#define XK_ifonlyif                                    0x8cd
#define XK_implies                                     0x8ce
#define XK_identical                                   0x8cf
#define XK_radical                                     0x8d6
#define XK_includedin                                  0x8da
#define XK_includes                                    0x8db
#define XK_intersection                                0x8dc
#define XK_union                                       0x8dd
#define XK_logicaland                                  0x8de
#define XK_logicalor                                   0x8df
#define XK_partialderivative                           0x8ef
#define XK_function                                    0x8f6
#define XK_leftarrow                                   0x8fb
#define XK_uparrow                                     0x8fc
#define XK_rightarrow                                  0x8fd
#define XK_downarrow                                   0x8fe
#endif /* XK_TECHNICAL */

/*
 *  Special

 *  Byte 3 = 9
 */

#ifdef XK_SPECIAL
#define XK_blank                                       0x9df
#define XK_soliddiamond                                0x9e0
#define XK_checkerboard                                0x9e1
#define XK_ht                                          0x9e2
#define XK_ff                                          0x9e3
#define XK_cr                                          0x9e4
#define XK_lf                                          0x9e5
#define XK_nl                                          0x9e8
#define XK_vt                                          0x9e9
#define XK_lowrightcorner                              0x9ea
#define XK_uprightcorner                               0x9eb
#define XK_upleftcorner                                0x9ec
#define XK_lowleftcorner                               0x9ed
#define XK_crossinglines                               0x9ee
#define XK_horizlinescan1                              0x9ef
#define XK_horizlinescan3                              0x9f0
#define XK_horizlinescan5                              0x9f1
#define XK_horizlinescan7                              0x9f2
#define XK_horizlinescan9                              0x9f3
#define XK_leftt                                       0x9f4
#define XK_rightt                                      0x9f5
#define XK_bott                                        0x9f6
#define XK_topt                                        0x9f7
#define XK_vertbar                                     0x9f8
#endif /* XK_SPECIAL */

/*
 *  Publishing


 *  Byte 3 = a
 */

#ifdef XK_PUBLISHING
#define XK_emspace                                     0xaa1
#define XK_enspace                                     0xaa2
#define XK_em3space                                    0xaa3
#define XK_em4space                                    0xaa4
#define XK_digitspace                                  0xaa5
#define XK_punctspace                                  0xaa6
#define XK_thinspace                                   0xaa7
#define XK_hairspace                                   0xaa8
#define XK_emdash                                      0xaa9
#define XK_endash                                      0xaaa
#define XK_signifblank                                 0xaac
#define XK_ellipsis                                    0xaae
#define XK_doubbaselinedot                             0xaaf
#define XK_onethird                                    0xab0
#define XK_twothirds                                   0xab1
#define XK_onefifth                                    0xab2
#define XK_twofifths                                   0xab3
#define XK_threefifths                                 0xab4
#define XK_fourfifths                                  0xab5
#define XK_onesixth                                    0xab6
#define XK_fivesixths                                  0xab7
#define XK_careof                                      0xab8
#define XK_figdash                                     0xabb
#define XK_leftanglebracket                            0xabc
#define XK_decimalpoint                                0xabd
#define XK_rightanglebracket                           0xabe
#define XK_marker                                      0xabf
#define XK_oneeighth                                   0xac3
#define XK_threeeighths                                0xac4
#define XK_fiveeighths                                 0xac5
#define XK_seveneighths                                0xac6
#define XK_trademark                                   0xac9
#define XK_signaturemark                               0xaca
#define XK_trademarkincircle                           0xacb
#define XK_leftopentriangle                            0xacc
#define XK_rightopentriangle                           0xacd
#define XK_emopencircle                                0xace
#define XK_emopenrectangle                             0xacf
#define XK_leftsinglequotemark                         0xad0
#define XK_rightsinglequotemark                        0xad1
#define XK_leftdoublequotemark                         0xad2
#define XK_rightdoublequotemark                        0xad3
#define XK_prescription                                0xad4

#define XK_minutes                                     0xad6
#define XK_seconds                                     0xad7
#define XK_latincross                                  0xad9
#define XK_hexagram                                    0xada
#define XK_filledrectbullet                            0xadb
#define XK_filledlefttribullet                         0xadc
#define XK_filledrighttribullet                        0xadd
#define XK_emfilledcircle                              0xade
#define XK_emfilledrect                                0xadf
#define XK_enopencircbullet                            0xae0
#define XK_enopensquarebullet                          0xae1
#define XK_openrectbullet                              0xae2
#define XK_opentribulletup                             0xae3
#define XK_opentribulletdown                           0xae4
#define XK_openstar                                    0xae5
#define XK_enfilledcircbullet                          0xae6
#define XK_enfilledsqbullet                            0xae7
#define XK_filledtribulletup                           0xae8
#define XK_filledtribulletdown                         0xae9
#define XK_leftpointer                                 0xaea
#define XK_rightpointer                                0xaeb
#define XK_club                                        0xaec
#define XK_diamond                                     0xaed
#define XK_heart                                       0xaee
#define XK_maltesecross                                0xaf0
#define XK_dagger                                      0xaf1
#define XK_doubledagger                                0xaf2
#define XK_checkmark                                   0xaf3
#define XK_ballotcross                                 0xaf4
#define XK_musicalsharp                                0xaf5
#define XK_musicalflat                                 0xaf6
#define XK_malesymbol                                  0xaf7
#define XK_femalesymbol                                0xaf8
#define XK_telephone                                   0xaf9
#define XK_telephonerecorder                           0xafa
#define XK_phonographcopyright                         0xafb
#define XK_caret                                       0xafc
#define XK_singlelowquotemark                          0xafd
#define XK_doublelowquotemark                          0xafe
#define XK_cursor                                      0xaff
#endif /* XK_PUBLISHING */

/*
 *  APL
 *  Byte 3 = b
 */

#ifdef XK_APL
#define XK_leftcaret                                   0xba3
#define XK_rightcaret                                  0xba6
#define XK_downcaret                                   0xba8
#define XK_upcaret                                     0xba9
#define XK_overbar                                     0xbc0
#define XK_downtack                                    0xbc2
#define XK_upshoe                                      0xbc3
#define XK_downstile                                   0xbc4
#define XK_underbar                                    0xbc6
#define XK_jot                                         0xbca
#define XK_quad                                        0xbcc
#define XK_uptack                                      0xbce
#define XK_circle                                      0xbcf
#define XK_upstile                                     0xbd3
#define XK_downshoe                                    0xbd6
#define XK_rightshoe                                   0xbd8
#define XK_leftshoe                                    0xbda
#define XK_lefttack                                    0xbdc
#define XK_righttack                                   0xbfc
#endif /* XK_APL */

/*
 * Hebrew
 * Byte 3 = c
 */

#ifdef XK_HEBREW
#define XK_hebrew_doublelowline                        0xcdf
#define XK_hebrew_aleph                                0xce0
#define XK_hebrew_bet                                  0xce1
#define XK_hebrew_beth                                 0xce1  /* deprecated */

































































































































#define XK_hebrew_gimel                                0xce2




#define XK_hebrew_gimmel                               0xce2  /* deprecated */

#define XK_hebrew_dalet                                0xce3
















#define XK_hebrew_daleth                               0xce3  /* deprecated */































#define XK_hebrew_he                                   0xce4






















#define XK_hebrew_waw                                  0xce5




























#define XK_hebrew_zain                                 0xce6








#define XK_hebrew_zayin                                0xce6  /* deprecated */



#define XK_hebrew_chet                                 0xce7




#define XK_hebrew_het                                  0xce7  /* deprecated */





































































































#define XK_hebrew_tet                                  0xce8



#define XK_hebrew_teth                                 0xce8  /* deprecated */









































#define XK_hebrew_yod                                  0xce9



#define XK_hebrew_finalkaph                            0xcea























#define XK_hebrew_kaph                                 0xceb



#define XK_hebrew_lamed                                0xcec





























































































#define XK_hebrew_finalmem                             0xced

#define XK_hebrew_mem                                  0xcee















#define XK_hebrew_finalnun                             0xcef



































#define XK_hebrew_nun                                  0xcf0


#define XK_hebrew_samech                               0xcf1
#define XK_hebrew_samekh                               0xcf1  /* deprecated */
#define XK_hebrew_ayin                                 0xcf2
#define XK_hebrew_finalpe                              0xcf3
#define XK_hebrew_pe                                   0xcf4

















































































































#define XK_hebrew_finalzade                            0xcf5
#define XK_hebrew_finalzadi                            0xcf5  /* deprecated */
#define XK_hebrew_zade                                 0xcf6
#define XK_hebrew_zadi                                 0xcf6  /* deprecated */
#define XK_hebrew_qoph                                 0xcf7
#define XK_hebrew_kuf                                  0xcf7  /* deprecated */














































































































































#define XK_hebrew_resh                                 0xcf8




#define XK_hebrew_shin                                 0xcf9


#define XK_hebrew_taw                                  0xcfa
#define XK_hebrew_taf                                  0xcfa  /* deprecated */
#define XK_Hebrew_switch        0xFF7E  /* Alias for mode_switch */












































































#endif /* XK_HEBREW */

/* Multimedia keys, defined same as on Linux
 * /usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon-keysyms.h
 */


#define XK_XF86AudioLowerVolume	0x1008FF11   /* Volume control down        */
#define XK_XF86AudioMute	0x1008FF12   /* Mute sound from the system */
#define XK_XF86AudioRaiseVolume	0x1008FF13   /* Volume control up          */
#define XK_XF86AudioPlay	0x1008FF14   /* Start playing of audio >   */
#define XK_XF86AudioStop	0x1008FF15   /* Stop playing audio         */
#define XK_XF86AudioPrev	0x1008FF16   /* Previous track             */
#define XK_XF86AudioNext	0x1008FF17   /* Next track                 */


Changes to xlib/rgb.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
!      Changes compared to Xorg:rgb.txt
!      name       old value       new value
!      aqua           -            0 255 255
!      crimson        -          220  20  60
!      fuchsia        -          255   0 255
!      gray      190 190 190     128 128 128
!      green       0 255   0       0 128   0
!      grey      190 190 190     128 128 128
!      indigo         -           75   0 130
!      lime           -            0 255   0
!      maroon    176  48  96     128   0   0
!      olive          -          128 128   0
!      purple    160  32 240     128   0 128
!      silver         -          192 192 192
!      teal           -            0 128 128
!
240 248 255		aliceBlue
250 235 215		antiqueWhite
255 239 219		antiqueWhite1
238 223 204		antiqueWhite2





<
<
<


<

<







1
2
3
4
5



6
7

8

9
10
11
12
13
14
15
!      Changes compared to Xorg:rgb.txt
!      name       old value       new value
!      aqua           -            0 255 255
!      crimson        -          220  20  60
!      fuchsia        -          255   0 255



!      indigo         -           75   0 130
!      lime           -            0 255   0

!      olive          -          128 128   0

!      silver         -          192 192 192
!      teal           -            0 128 128
!
240 248 255		aliceBlue
250 235 215		antiqueWhite
255 239 219		antiqueWhite1
238 223 204		antiqueWhite2
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
205 173   0		gold3
139 117   0		gold4
218 165  32		goldenrod
255 193  37		goldenrod1
238 180  34		goldenrod2
205 155  29		goldenrod3
139 105  20		goldenrod4
128 128 128		gray
  3   3   3		gray1
  5   5   5		gray2
  8   8   8		gray3
 10  10  10		gray4
 13  13  13		gray5
 15  15  15		gray6
 18  18  18		gray7







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
205 173   0		gold3
139 117   0		gold4
218 165  32		goldenrod
255 193  37		goldenrod1
238 180  34		goldenrod2
205 155  29		goldenrod3
139 105  20		goldenrod4
190 190 190		gray
  3   3   3		gray1
  5   5   5		gray2
  8   8   8		gray3
 10  10  10		gray4
 13  13  13		gray5
 15  15  15		gray6
 18  18  18		gray7
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
242 242 242		gray95
245 245 245		gray96
247 247 247		gray97
250 250 250		gray98
252 252 252		gray99
255 255 255		gray100
  0   0   0		gray0
  0 128   0		green
  0 255   0		green1
  0 238   0		green2
  0 205   0		green3
  0 139   0		green4
173 255  47		greenYellow
128 128 128		grey
  3   3   3		grey1
  5   5   5		grey2
  8   8   8		grey3
 10  10  10		grey4
 13  13  13		grey5
 15  15  15		grey6
 18  18  18		grey7







|





|







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
242 242 242		gray95
245 245 245		gray96
247 247 247		gray97
250 250 250		gray98
252 252 252		gray99
255 255 255		gray100
  0   0   0		gray0
  0 255   0		green
  0 255   0		green1
  0 238   0		green2
  0 205   0		green3
  0 139   0		green4
173 255  47		greenYellow
190 190 190		grey
  3   3   3		grey1
  5   5   5		grey2
  8   8   8		grey3
 10  10  10		grey4
 13  13  13		grey5
 15  15  15		grey6
 18  18  18		grey7
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
 50 205  50		limeGreen
250 240 230		linen
255   0 255		magenta
255   0 255		magenta1
238   0 238		magenta2
205   0 205		magenta3
139   0 139		magenta4
128   0   0		maroon
255  52 179		maroon1
238  48 167		maroon2
205  41 144		maroon3
139  28  98		maroon4
102 205 170		mediumAquamarine
  0   0 205		mediumBlue
186  85 211		mediumOrchid







|







463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 50 205  50		limeGreen
250 240 230		linen
255   0 255		magenta
255   0 255		magenta1
238   0 238		magenta2
205   0 205		magenta3
139   0 139		magenta4
176  48  96		maroon
255  52 179		maroon1
238  48 167		maroon2
205  41 144		maroon3
139  28  98		maroon4
102 205 170		mediumAquamarine
  0   0 205		mediumBlue
186  85 211		mediumOrchid
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
139  99 108		pink4
221 160 221		plum
255 187 255		plum1
238 174 238		plum2
205 150 205		plum3
139 102 139		plum4
176 224 230		powderBlue
128   0 128		purple
155  48 255		purple1
145  44 238		purple2
125  38 205		purple3
 85  26 139		purple4
255   0   0		red
255   0   0		red1
238   0   0		red2







|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
139  99 108		pink4
221 160 221		plum
255 187 255		plum1
238 174 238		plum2
205 150 205		plum3
139 102 139		plum4
176 224 230		powderBlue
160  32 240		purple
155  48 255		purple1
145  44 238		purple2
125  38 205		purple3
 85  26 139		purple4
255   0   0		red
255   0   0		red1
238   0   0		red2

Changes to xlib/xcolors.c.

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 * are handled by this table, above that is handled especially.
 */

typedef char elem[32];

static const elem xColors[] = {
    /* Colors starting with 'a' */
    "liceBlue\0                   \360\370\377\0",
    "ntiqueWhite\0    \213\203\170\315\300\260\356\337\314\377\357\333\372\353\327\4",
    "qua\0                        \000\377\377\0",
    "quamarine\0      \105\213\164\146\315\252\166\356\306\177\377\324\177\377\324\4",
    "zure\0           \203\213\213\301\315\315\340\356\356\360\377\377\360\377\377\4",
    /* Colors starting with 'b' */
    "eige\0                       \365\365\334\0",
    "isque\0          \213\175\153\315\267\236\356\325\267\377\344\304\377\344\304\4",
    "lack\0                       \000\000\000\0",
    "lanchedAlmond\0              \377\353\315\0",
    "lue\0            \000\000\213\000\000\315\000\000\356\000\000\377\000\000\377\4",
    "lueViolet\0                  \212\053\342\0",
    "rown\0           \213\043\043\315\063\063\356\073\073\377\100\100\245\052\052\4",
    "urlywood\0       \213\163\125\315\252\175\356\305\221\377\323\233\336\270\207\4",
    /* Colors starting with 'c' */
    "adetBlue\0       \123\206\213\172\305\315\216\345\356\230\365\377\137\236\240\4",
    "hartreuse\0      \105\213\000\146\315\000\166\356\000\177\377\000\177\377\000\4",
    "hocolate\0       \213\105\023\315\146\035\356\166\041\377\177\044\322\151\036\4",
    "oral\0           \213\076\057\315\133\105\356\152\120\377\162\126\377\177\120\4",
    "ornflowerBlue\0              \144\225\355\0",
    "ornsilk\0        \213\210\170\315\310\261\356\350\315\377\370\334\377\370\334\4",
    "rimson\0                     \334\024\074\0",
    "yan\0            \000\213\213\000\315\315\000\356\356\000\377\377\000\377\377\4",
    /* Colors starting with 'd' */
    "arkBlue\0                    \000\000\213\0",
    "arkCyan\0                    \000\213\213\0",
    "arkGoldenrod\0   \213\145\010\315\225\014\356\255\016\377\271\017\270\206\013\4",
    "arkGray\0                    \251\251\251\0",
    "arkGreen\0                   \000\144\000\0",
    "arkGrey\0                    \251\251\251\0",
    "arkKhaki\0                   \275\267\153\0",
    "arkMagenta\0                 \213\000\213\0",
    "arkOliveGreen\0  \156\213\075\242\315\132\274\356\150\312\377\160\125\153\057\4",
    "arkOrange\0      \213\105\000\315\146\000\356\166\000\377\177\000\377\214\000\4",
    "arkOrchid\0      \150\042\213\232\062\315\262\072\356\277\076\377\231\062\314\4",
    "arkRed\0                     \213\000\000\0",
    "arkSalmon\0                  \351\226\172\0",
    "arkSeaGreen\0    \151\213\151\233\315\233\264\356\264\301\377\301\217\274\217\4",
    "arkSlateBlue\0               \110\075\213\0",
    "arkSlateGray\0   \122\213\213\171\315\315\215\356\356\227\377\377\057\117\117\4",
    "arkSlateGrey\0               \057\117\117\0",
    "arkTurquoise\0               \000\316\321\0",
    "arkViolet\0                  \224\000\323\0",
    "eepPink\0        \213\012\120\315\020\166\356\022\211\377\024\223\377\024\223\4",
    "eepSkyBlue\0     \000\150\213\000\232\315\000\262\356\000\277\377\000\277\377\4",
    "imGray\0                     \151\151\151\0",
    "imGrey\0                     \151\151\151\0",
    "odgerBlue\0      \020\116\213\030\164\315\034\206\356\036\220\377\036\220\377\4",
    /* Colors starting with 'e' */
    "\377                              \0" /* placeholder */,
    /* Colors starting with 'f' */
    "irebrick\0       \213\032\032\315\046\046\356\054\054\377\060\060\262\042\042\4",
    "loralWhite\0                 \377\372\360\0",
    "orestGreen\0                 \042\213\042\0",
    "uchsia\0                     \377\000\377\0",
    /* Colors starting with 'g' */
    "ainsboro\0                   \334\334\334\0",
    "hostWhite\0                  \370\370\377\0",
    "old\0            \213\165\000\315\255\000\356\311\000\377\327\000\377\327\000\4",
    "oldenrod\0       \213\151\024\315\233\035\356\264\042\377\301\045\332\245\040\4",
    "ray\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\200\200\200\10",
    "ray0\0                       \000\000\000\0",
    "reen\0           \000\213\000\000\315\000\000\356\000\000\377\000\000\200\000\4",
    "reenYellow\0                 \255\377\057\0",
    "rey\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\200\200\200\10",
    "rey0\0                       \000\000\000\0",
    /* Colors starting with 'h' */
    "oneydew\0        \203\213\203\301\315\301\340\356\340\360\377\360\360\377\360\4",
    "otPink\0         \213\072\142\315\140\220\356\152\247\377\156\264\377\151\264\4",
    /* Colors starting with 'i' */
    "ndianRed\0       \213\072\072\315\125\125\356\143\143\377\152\152\315\134\134\4",
    "ndigo\0                      \113\000\202\0",
    "vory\0           \213\213\203\315\315\301\356\356\340\377\377\360\377\377\360\4",
    /* Colors starting with 'j' */
    "\377                              \0" /* placeholder */,
    /* Colors starting with 'k' */
    "haki\0           \213\206\116\315\306\163\356\346\205\377\366\217\360\346\214\4",
    /* Colors starting with 'l' */
    "avender\0                    \346\346\372\0",
    "avenderBlush\0   \213\203\206\315\301\305\356\340\345\377\360\365\377\360\365\4",
    "awnGreen\0                   \174\374\000\0",
    "emonChiffon\0    \213\211\160\315\311\245\356\351\277\377\372\315\377\372\315\4",
    "ightBlue\0       \150\203\213\232\300\315\262\337\356\277\357\377\255\330\346\4",
    "ightCoral\0                  \360\200\200\0",
    "ightCyan\0       \172\213\213\264\315\315\321\356\356\340\377\377\340\377\377\4",
    "ightGoldenrod\0  \213\201\114\315\276\160\356\334\202\377\354\213\356\335\202\4",
    "ightGoldenrodYellow\0        \372\372\322\0",
    "ightGray\0                   \323\323\323\0",
    "ightGreen\0                  \220\356\220\0",
    "ightGrey\0                   \323\323\323\0",
    "ightPink\0       \213\137\145\315\214\225\356\242\255\377\256\271\377\266\301\4",
    "ightSalmon\0     \213\127\102\315\201\142\356\225\162\377\240\172\377\240\172\4",
    "ightSeaGreen\0               \040\262\252\0",
    "ightSkyBlue\0    \140\173\213\215\266\315\244\323\356\260\342\377\207\316\372\4",
    "ightSlateBlue\0              \204\160\377\0",
    "ightSlateGray\0              \167\210\231\0",
    "ightSlateGrey\0              \167\210\231\0",
    "ightSteelBlue\0  \156\173\213\242\265\315\274\322\356\312\341\377\260\304\336\4",
    "ightYellow\0     \213\213\172\315\315\264\356\356\321\377\377\340\377\377\340\4",
    "ime\0                        \000\377\000\0",
    "imeGreen\0                   \062\315\062\0",
    "inen\0                       \372\360\346\0",
    /* Colors starting with 'm' */
    "agenta\0         \213\000\213\315\000\315\356\000\356\377\000\377\377\000\377\4",
    "aroon\0          \213\034\142\315\051\220\356\060\247\377\064\263\200\000\000\4",
    "ediumAquamarine\0            \146\315\252\0",
    "ediumBlue\0                  \000\000\315\0",
    "ediumOrchid\0    \172\067\213\264\122\315\321\137\356\340\146\377\272\125\323\4",
    "ediumPurple\0    \135\107\213\211\150\315\237\171\356\253\202\377\223\160\333\4",
    "ediumSeaGreen\0              \074\263\161\0",
    "ediumSlateBlue\0             \173\150\356\0",
    "ediumSpringGreen\0           \000\372\232\0",
    "ediumTurquoise\0             \110\321\314\0",
    "ediumVioletRed\0             \307\025\205\0",
    "idnightBlue\0                \031\031\160\0",
    "intCream\0                   \365\377\372\0",
    "istyRose\0       \213\175\173\315\267\265\356\325\322\377\344\341\377\344\341\4",
    "occasin\0                    \377\344\265\0",
    /* Colors starting with 'n' */
    "avajoWhite\0     \213\171\136\315\263\213\356\317\241\377\336\255\377\336\255\4",
    "avy\0                        \000\000\200\0",
    "avyBlue\0                    \000\000\200\0",
    /* Colors starting with 'o' */
    "ldLace\0                     \375\365\346\0",
    "live\0                       \200\200\000\0",
    "liveDrab\0       \151\213\042\232\315\062\263\356\072\300\377\076\153\216\043\4",
    "range\0          \213\132\000\315\205\000\356\232\000\377\245\000\377\245\000\4",
    "rangeRed\0       \213\045\000\315\067\000\356\100\000\377\105\000\377\105\000\4",
    "rchid\0          \213\107\211\315\151\311\356\172\351\377\203\372\332\160\326\4",
    /* Colors starting with 'p' */
    "aleGoldenrod\0               \356\350\252\0",
    "aleGreen\0       \124\213\124\174\315\174\220\356\220\232\377\232\230\373\230\4",
    "aleTurquoise\0   \146\213\213\226\315\315\256\356\356\273\377\377\257\356\356\4",
    "aleVioletRed\0   \213\107\135\315\150\211\356\171\237\377\202\253\333\160\223\4",
    "apayaWhip\0                  \377\357\325\0",
    "eachPuff\0       \213\167\145\315\257\225\356\313\255\377\332\271\377\332\271\4",
    "eru\0                        \315\205\077\0",
    "ink\0            \213\143\154\315\221\236\356\251\270\377\265\305\377\300\313\4",
    "lum\0            \213\146\213\315\226\315\356\256\356\377\273\377\335\240\335\4",
    "owderBlue\0                  \260\340\346\0",
    "urple\0          \125\032\213\175\046\315\221\054\356\233\060\377\200\000\200\4",
    /* Colors starting with 'q' */
    "\377                              \0" /* placeholder */,
    /* Colors starting with 'r' */
    "ed\0             \213\000\000\315\000\000\356\000\000\377\000\000\377\000\000\4",
    "osyBrown\0       \213\151\151\315\233\233\356\264\264\377\301\301\274\217\217\4",
    "oyalBlue\0       \047\100\213\072\137\315\103\156\356\110\166\377\101\151\341\4",
    /* Colors starting with 's' */
    "addleBrown\0                 \213\105\023\0",
    "almon\0          \213\114\071\315\160\124\356\202\142\377\214\151\372\200\162\4",
    "andyBrown\0                  \364\244\140\0",
    "eaGreen\0        \056\213\127\103\315\200\116\356\224\124\377\237\056\213\127\4",
    "eashell\0        \213\206\202\315\305\277\356\345\336\377\365\356\377\365\356\4",
    "ienna\0          \213\107\046\315\150\071\356\171\102\377\202\107\240\122\055\4",
    "ilver\0                      \300\300\300\0",
    "kyBlue\0         \112\160\213\154\246\315\176\300\356\207\316\377\207\316\353\4",
    "lateBlue\0       \107\074\213\151\131\315\172\147\356\203\157\377\152\132\315\4",
    "lateGray\0       \154\173\213\237\266\315\271\323\356\306\342\377\160\200\220\4",
    "lateGrey\0                   \160\200\220\0",
    "now\0            \213\211\211\315\311\311\356\351\351\377\372\372\377\372\372\4",
    "pringGreen\0     \000\213\105\000\315\146\000\356\166\000\377\177\000\377\177\4",
    "teelBlue\0       \066\144\213\117\224\315\134\254\356\143\270\377\106\202\264\4",
    /* Colors starting with 't' */
    "an\0             \213\132\053\315\205\077\356\232\111\377\245\117\322\264\214\4",
    "eal\0                        \000\200\200\0",
    "histle\0         \213\173\213\315\265\315\356\322\356\377\341\377\330\277\330\4",
    "omato\0          \213\066\046\315\117\071\356\134\102\377\143\107\377\143\107\4",
    "urquoise\0       \000\206\213\000\305\315\000\345\356\000\365\377\100\340\320\4",
    /* Colors starting with 'u' */
    "\377                              \0" /* placeholder */,
    /* Colors starting with 'v' */
    "iolet\0                      \356\202\356\0",
    "ioletRed\0       \213\042\122\315\062\170\356\072\214\377\076\226\320\040\220\4",
    /* Colors starting with 'w' */
    "heat\0           \213\176\146\315\272\226\356\330\256\377\347\272\365\336\263\4",
    "hite\0                       \377\377\377\0",
    "hiteSmoke\0                  \365\365\365\0",
    /* Colors starting with 'x' */
    "\377                              \0" /* placeholder */,
    /* Colors starting with 'y' */
    "ellow\0          \213\213\000\315\315\000\356\356\000\377\377\000\377\377\000\4",
    "ellowGreen\0                 \232\315\062\0"
};

/*
 *----------------------------------------------------------------------







|

|



|

|
|

|







|

|


|
|

|
|
|
|
|



|
|

|

|
|
|


|
|


|


|
|
|

|
|



|
|
|
|

|
|





|


|



|

|


|


|
|
|
|


|

|
|
|


|
|
|


|
|
|


|
|
|
|
|
|
|

|


|
|

|
|





|



|

|


|
|

|





|

|



|



|





|




|

|



|
|

|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 * are handled by this table, above that is handled especially.
 */

typedef char elem[32];

static const elem xColors[] = {
    /* Colors starting with 'a' */
    "liceBlue\0                   \360\370\377",
    "ntiqueWhite\0    \213\203\170\315\300\260\356\337\314\377\357\333\372\353\327\4",
    "qua\0                        \000\377\377",
    "quamarine\0      \105\213\164\146\315\252\166\356\306\177\377\324\177\377\324\4",
    "zure\0           \203\213\213\301\315\315\340\356\356\360\377\377\360\377\377\4",
    /* Colors starting with 'b' */
    "eige\0                       \365\365\334",
    "isque\0          \213\175\153\315\267\236\356\325\267\377\344\304\377\344\304\4",
    "lack\0                       \000\000\000",
    "lanchedAlmond\0              \377\353\315",
    "lue\0            \000\000\213\000\000\315\000\000\356\000\000\377\000\000\377\4",
    "lueViolet\0                  \212\053\342",
    "rown\0           \213\043\043\315\063\063\356\073\073\377\100\100\245\052\052\4",
    "urlywood\0       \213\163\125\315\252\175\356\305\221\377\323\233\336\270\207\4",
    /* Colors starting with 'c' */
    "adetBlue\0       \123\206\213\172\305\315\216\345\356\230\365\377\137\236\240\4",
    "hartreuse\0      \105\213\000\146\315\000\166\356\000\177\377\000\177\377\000\4",
    "hocolate\0       \213\105\023\315\146\035\356\166\041\377\177\044\322\151\036\4",
    "oral\0           \213\076\057\315\133\105\356\152\120\377\162\126\377\177\120\4",
    "ornflowerBlue\0              \144\225\355",
    "ornsilk\0        \213\210\170\315\310\261\356\350\315\377\370\334\377\370\334\4",
    "rimson\0                     \334\024\074",
    "yan\0            \000\213\213\000\315\315\000\356\356\000\377\377\000\377\377\4",
    /* Colors starting with 'd' */
    "arkBlue\0                    \000\000\213",
    "arkCyan\0                    \000\213\213",
    "arkGoldenrod\0   \213\145\010\315\225\014\356\255\016\377\271\017\270\206\013\4",
    "arkGray\0                    \251\251\251",
    "arkGreen\0                   \000\144\000",
    "arkGrey\0                    \251\251\251",
    "arkKhaki\0                   \275\267\153",
    "arkMagenta\0                 \213\000\213",
    "arkOliveGreen\0  \156\213\075\242\315\132\274\356\150\312\377\160\125\153\057\4",
    "arkOrange\0      \213\105\000\315\146\000\356\166\000\377\177\000\377\214\000\4",
    "arkOrchid\0      \150\042\213\232\062\315\262\072\356\277\076\377\231\062\314\4",
    "arkRed\0                     \213\000\000",
    "arkSalmon\0                  \351\226\172",
    "arkSeaGreen\0    \151\213\151\233\315\233\264\356\264\301\377\301\217\274\217\4",
    "arkSlateBlue\0               \110\075\213",
    "arkSlateGray\0   \122\213\213\171\315\315\215\356\356\227\377\377\057\117\117\4",
    "arkSlateGrey\0               \057\117\117",
    "arkTurquoise\0               \000\316\321",
    "arkViolet\0                  \224\000\323",
    "eepPink\0        \213\012\120\315\020\166\356\022\211\377\024\223\377\024\223\4",
    "eepSkyBlue\0     \000\150\213\000\232\315\000\262\356\000\277\377\000\277\377\4",
    "imGray\0                     \151\151\151",
    "imGrey\0                     \151\151\151",
    "odgerBlue\0      \020\116\213\030\164\315\034\206\356\036\220\377\036\220\377\4",
    /* Colors starting with 'e' */
    "\377" /* placeholder */,
    /* Colors starting with 'f' */
    "irebrick\0       \213\032\032\315\046\046\356\054\054\377\060\060\262\042\042\4",
    "loralWhite\0                 \377\372\360",
    "orestGreen\0                 \042\213\042",
    "uchsia\0                     \377\000\377",
    /* Colors starting with 'g' */
    "ainsboro\0                   \334\334\334",
    "hostWhite\0                  \370\370\377",
    "old\0            \213\165\000\315\255\000\356\311\000\377\327\000\377\327\000\4",
    "oldenrod\0       \213\151\024\315\233\035\356\264\042\377\301\045\332\245\040\4",
    "ray\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "ray0\0                       \000\000\000",
    "reen\0           \000\213\000\000\315\000\000\356\000\000\377\000\000\377\000\4",
    "reenYellow\0                 \255\377\057",
    "rey\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "rey0\0                       \000\000\000",
    /* Colors starting with 'h' */
    "oneydew\0        \203\213\203\301\315\301\340\356\340\360\377\360\360\377\360\4",
    "otPink\0         \213\072\142\315\140\220\356\152\247\377\156\264\377\151\264\4",
    /* Colors starting with 'i' */
    "ndianRed\0       \213\072\072\315\125\125\356\143\143\377\152\152\315\134\134\4",
    "ndigo\0                      \113\000\202",
    "vory\0           \213\213\203\315\315\301\356\356\340\377\377\360\377\377\360\4",
    /* Colors starting with 'j' */
    "\377" /* placeholder */,
    /* Colors starting with 'k' */
    "haki\0           \213\206\116\315\306\163\356\346\205\377\366\217\360\346\214\4",
    /* Colors starting with 'l' */
    "avender\0                    \346\346\372",
    "avenderBlush\0   \213\203\206\315\301\305\356\340\345\377\360\365\377\360\365\4",
    "awnGreen\0                   \174\374\000",
    "emonChiffon\0    \213\211\160\315\311\245\356\351\277\377\372\315\377\372\315\4",
    "ightBlue\0       \150\203\213\232\300\315\262\337\356\277\357\377\255\330\346\4",
    "ightCoral\0                  \360\200\200",
    "ightCyan\0       \172\213\213\264\315\315\321\356\356\340\377\377\340\377\377\4",
    "ightGoldenrod\0  \213\201\114\315\276\160\356\334\202\377\354\213\356\335\202\4",
    "ightGoldenrodYellow\0        \372\372\322",
    "ightGray\0                   \323\323\323",
    "ightGreen\0                  \220\356\220",
    "ightGrey\0                   \323\323\323",
    "ightPink\0       \213\137\145\315\214\225\356\242\255\377\256\271\377\266\301\4",
    "ightSalmon\0     \213\127\102\315\201\142\356\225\162\377\240\172\377\240\172\4",
    "ightSeaGreen\0               \040\262\252",
    "ightSkyBlue\0    \140\173\213\215\266\315\244\323\356\260\342\377\207\316\372\4",
    "ightSlateBlue\0              \204\160\377",
    "ightSlateGray\0              \167\210\231",
    "ightSlateGrey\0              \167\210\231",
    "ightSteelBlue\0  \156\173\213\242\265\315\274\322\356\312\341\377\260\304\336\4",
    "ightYellow\0     \213\213\172\315\315\264\356\356\321\377\377\340\377\377\340\4",
    "ime\0                        \000\377\000",
    "imeGreen\0                   \062\315\062",
    "inen\0                       \372\360\346",
    /* Colors starting with 'm' */
    "agenta\0         \213\000\213\315\000\315\356\000\356\377\000\377\377\000\377\4",
    "aroon\0          \213\034\142\315\051\220\356\060\247\377\064\263\260\060\140\4",
    "ediumAquamarine\0            \146\315\252",
    "ediumBlue\0                  \000\000\315",
    "ediumOrchid\0    \172\067\213\264\122\315\321\137\356\340\146\377\272\125\323\4",
    "ediumPurple\0    \135\107\213\211\150\315\237\171\356\253\202\377\223\160\333\4",
    "ediumSeaGreen\0              \074\263\161",
    "ediumSlateBlue\0             \173\150\356",
    "ediumSpringGreen\0           \000\372\232",
    "ediumTurquoise\0             \110\321\314",
    "ediumVioletRed\0             \307\025\205",
    "idnightBlue\0                \031\031\160",
    "intCream\0                   \365\377\372",
    "istyRose\0       \213\175\173\315\267\265\356\325\322\377\344\341\377\344\341\4",
    "occasin\0                    \377\344\265",
    /* Colors starting with 'n' */
    "avajoWhite\0     \213\171\136\315\263\213\356\317\241\377\336\255\377\336\255\4",
    "avy\0                        \000\000\200",
    "avyBlue\0                    \000\000\200",
    /* Colors starting with 'o' */
    "ldLace\0                     \375\365\346",
    "live\0                       \200\200\000",
    "liveDrab\0       \151\213\042\232\315\062\263\356\072\300\377\076\153\216\043\4",
    "range\0          \213\132\000\315\205\000\356\232\000\377\245\000\377\245\000\4",
    "rangeRed\0       \213\045\000\315\067\000\356\100\000\377\105\000\377\105\000\4",
    "rchid\0          \213\107\211\315\151\311\356\172\351\377\203\372\332\160\326\4",
    /* Colors starting with 'p' */
    "aleGoldenrod\0               \356\350\252",
    "aleGreen\0       \124\213\124\174\315\174\220\356\220\232\377\232\230\373\230\4",
    "aleTurquoise\0   \146\213\213\226\315\315\256\356\356\273\377\377\257\356\356\4",
    "aleVioletRed\0   \213\107\135\315\150\211\356\171\237\377\202\253\333\160\223\4",
    "apayaWhip\0                  \377\357\325",
    "eachPuff\0       \213\167\145\315\257\225\356\313\255\377\332\271\377\332\271\4",
    "eru\0                        \315\205\077",
    "ink\0            \213\143\154\315\221\236\356\251\270\377\265\305\377\300\313\4",
    "lum\0            \213\146\213\315\226\315\356\256\356\377\273\377\335\240\335\4",
    "owderBlue\0                  \260\340\346",
    "urple\0          \125\032\213\175\046\315\221\054\356\233\060\377\240\040\360\4",
    /* Colors starting with 'q' */
    "\377" /* placeholder */,
    /* Colors starting with 'r' */
    "ed\0             \213\000\000\315\000\000\356\000\000\377\000\000\377\000\000\4",
    "osyBrown\0       \213\151\151\315\233\233\356\264\264\377\301\301\274\217\217\4",
    "oyalBlue\0       \047\100\213\072\137\315\103\156\356\110\166\377\101\151\341\4",
    /* Colors starting with 's' */
    "addleBrown\0                 \213\105\023",
    "almon\0          \213\114\071\315\160\124\356\202\142\377\214\151\372\200\162\4",
    "andyBrown\0                  \364\244\140",
    "eaGreen\0        \056\213\127\103\315\200\116\356\224\124\377\237\056\213\127\4",
    "eashell\0        \213\206\202\315\305\277\356\345\336\377\365\356\377\365\356\4",
    "ienna\0          \213\107\046\315\150\071\356\171\102\377\202\107\240\122\055\4",
    "ilver\0                      \300\300\300",
    "kyBlue\0         \112\160\213\154\246\315\176\300\356\207\316\377\207\316\353\4",
    "lateBlue\0       \107\074\213\151\131\315\172\147\356\203\157\377\152\132\315\4",
    "lateGray\0       \154\173\213\237\266\315\271\323\356\306\342\377\160\200\220\4",
    "lateGrey\0                   \160\200\220",
    "now\0            \213\211\211\315\311\311\356\351\351\377\372\372\377\372\372\4",
    "pringGreen\0     \000\213\105\000\315\146\000\356\166\000\377\177\000\377\177\4",
    "teelBlue\0       \066\144\213\117\224\315\134\254\356\143\270\377\106\202\264\4",
    /* Colors starting with 't' */
    "an\0             \213\132\053\315\205\077\356\232\111\377\245\117\322\264\214\4",
    "eal\0                        \000\200\200",
    "histle\0         \213\173\213\315\265\315\356\322\356\377\341\377\330\277\330\4",
    "omato\0          \213\066\046\315\117\071\356\134\102\377\143\107\377\143\107\4",
    "urquoise\0       \000\206\213\000\305\315\000\345\356\000\365\377\100\340\320\4",
    /* Colors starting with 'u' */
    "\377" /* placeholder */,
    /* Colors starting with 'v' */
    "iolet\0                      \356\202\356",
    "ioletRed\0       \213\042\122\315\062\170\356\072\214\377\076\226\320\040\220\4",
    /* Colors starting with 'w' */
    "heat\0           \213\176\146\315\272\226\356\330\256\377\347\272\365\336\263\4",
    "hite\0                       \377\377\377",
    "hiteSmoke\0                  \365\365\365",
    /* Colors starting with 'x' */
    "\377" /* placeholder */,
    /* Colors starting with 'y' */
    "ellow\0          \213\213\000\315\315\000\356\356\000\377\377\000\377\377\000\4",
    "ellowGreen\0                 \232\315\062\0"
};

/*
 *----------------------------------------------------------------------
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
Status
XParseColor(
    Display *display,
    Colormap map,
    const char *spec,
    XColor *colorPtr)
{
    (void)display;
    (void)map;

    if (spec[0] == '#') {
	char *p;
	Tcl_WideInt value = parseHex64bit(++spec, &p);

	/*
	 * If *p does not point to the end of the string, there were invalid
	 * digits in the spec. Ergo, it is not a valid color string.







<
<
<







337
338
339
340
341
342
343



344
345
346
347
348
349
350
Status
XParseColor(
    Display *display,
    Colormap map,
    const char *spec,
    XColor *colorPtr)
{



    if (spec[0] == '#') {
	char *p;
	Tcl_WideInt value = parseHex64bit(++spec, &p);

	/*
	 * If *p does not point to the end of the string, there were invalid
	 * digits in the spec. Ergo, it is not a valid color string.

Changes to xlib/xgc.c.

8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59




60
61
62
63
64
65
66
 * Copyright (c) 2002-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if !defined(MAC_OSX_TK)
#   include <X11/Xlib.h>

#   define TkpInitGCCache(gc)
#   define TkpFreeGCCache(gc)
#   define TkpGetGCCache(gc)
#else
#   include <tkMacOSXInt.h>
#   include <X11/Xlib.h>
#   include <X11/X.h>



#endif


#define MAX_DASH_LIST_SIZE 10
typedef struct {
    XGCValues gc;
    char dash[MAX_DASH_LIST_SIZE];
#ifdef MAC_OSX_TK
    TkpGCCache cache;
#endif
} XGCValuesWithCache;

/*
 *----------------------------------------------------------------------
 *
 * AllocClipMask --
 *
 *	Static helper proc to allocate new or clear existing TkpClipMask.
 *
 * Results:
 *	Returns ptr to the new/cleared TkpClipMask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkpClipMask *AllocClipMask(GC gc) {
    TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;

    if (clip_mask == NULL) {
	clip_mask = (TkpClipMask *)ckalloc(sizeof(TkpClipMask));
	gc->clip_mask = (Pixmap) clip_mask;




    }
    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *







|



>







>
>
>


|
<
<
<
<
<
<
<
<
|




















|

>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32








33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 * Copyright (c) 2002-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tkInt.h>

#if !defined(MAC_OSX_TK)
#   include <X11/Xlib.h>
#   define gcCacheSize 0
#   define TkpInitGCCache(gc)
#   define TkpFreeGCCache(gc)
#   define TkpGetGCCache(gc)
#else
#   include <tkMacOSXInt.h>
#   include <X11/Xlib.h>
#   include <X11/X.h>
#   define Cursor XCursor
#   define Region XRegion
#   define gcCacheSize sizeof(TkpGCCache)
#endif

#undef TkSetRegion









/*
 *----------------------------------------------------------------------
 *
 * AllocClipMask --
 *
 *	Static helper proc to allocate new or clear existing TkpClipMask.
 *
 * Results:
 *	Returns ptr to the new/cleared TkpClipMask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkpClipMask *AllocClipMask(GC gc) {
    TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;

    if (clip_mask == NULL) {
	clip_mask = (TkpClipMask*) ckalloc(sizeof(TkpClipMask));
	gc->clip_mask = (Pixmap) clip_mask;
#ifdef MAC_OSX_TK
    } else if (clip_mask->type == TKP_CLIP_REGION) {
	TkpReleaseRegion(clip_mask->value.region);
#endif
    }
    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *
75
76
77
78
79
80
81





82
83
84
85
86
87
88
89
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    if (gc->clip_mask != None) {





	ckfree((char *)gc->clip_mask);
	gc->clip_mask = None;
    }
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>
|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    if (gc->clip_mask != None) {
#ifdef MAC_OSX_TK
	if (((TkpClipMask*) gc->clip_mask)->type == TKP_CLIP_REGION) {
	    TkpReleaseRegion(((TkpClipMask*) gc->clip_mask)->value.region);
	}
#endif
	ckfree((char*) gc->clip_mask);
	gc->clip_mask = None;
    }
}

/*
 *----------------------------------------------------------------------
 *
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119


120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
XCreateGC(
    Display *display,
    Drawable d,
    unsigned long mask,
    XGCValues *values)
{
    GC gp;
    (void)d;

    /*
     * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars
     * are defined, which is invisible from the outside. The list is assumed
     * to end with a 0-char, so this must be set explicitly during
     * initialization.
     */



    gp = (GC)ckalloc(sizeof(XGCValuesWithCache));

    if (!gp) {
	return NULL;
    }

#define InitField(name,maskbit,default) \
	(gp->name = (mask & (maskbit)) ? values->name : (default))

    InitField(function,		  GCFunction,		GXcopy);
    InitField(plane_mask,	  GCPlaneMask,		(unsigned long)(~0));
    InitField(foreground,	  GCForeground,
	    BlackPixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(background,	  GCBackground,
	    WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(line_width,	  GCLineWidth,		1);
    InitField(line_style,	  GCLineStyle,		LineSolid);
    InitField(cap_style,	  GCCapStyle,		0);
    InitField(join_style,	  GCJoinStyle,		0);
    InitField(fill_style,	  GCFillStyle,		FillSolid);
    InitField(fill_rule,	  GCFillRule,		WindingRule);
    InitField(arc_mode,		  GCArcMode,		ArcPieSlice);
    InitField(tile,		  GCTile,		0);
    InitField(stipple,		  GCStipple,		0);
    InitField(ts_x_origin,	  GCTileStipXOrigin,	0);
    InitField(ts_y_origin,	  GCTileStipYOrigin,	0);
    InitField(font,		  GCFont,		0);
    InitField(subwindow_mode,	  GCSubwindowMode,	ClipByChildren);
    InitField(graphics_exposures, GCGraphicsExposures,	True);
    InitField(clip_x_origin,	  GCClipXOrigin,	0);
    InitField(clip_y_origin,	  GCClipYOrigin,	0);
    InitField(dash_offset,	  GCDashOffset,		0);
    InitField(dashes,		  GCDashList,		4);
    (&(gp->dashes))[1] = 0;







<




|



>
>
|
>




















|
|


|







109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
XCreateGC(
    Display *display,
    Drawable d,
    unsigned long mask,
    XGCValues *values)
{
    GC gp;


    /*
     * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars
     * are defined, which is invisible from the outside. The list is assumed
     * to end with a 0-char, so this must be set explicitely during
     * initialization.
     */

#define MAX_DASH_LIST_SIZE 10

    gp = (XGCValues *) ckalloc(sizeof(XGCValues) + MAX_DASH_LIST_SIZE +
	    gcCacheSize);
    if (!gp) {
	return NULL;
    }

#define InitField(name,maskbit,default) \
	(gp->name = (mask & (maskbit)) ? values->name : (default))

    InitField(function,		  GCFunction,		GXcopy);
    InitField(plane_mask,	  GCPlaneMask,		(unsigned long)(~0));
    InitField(foreground,	  GCForeground,
	    BlackPixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(background,	  GCBackground,
	    WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(line_width,	  GCLineWidth,		1);
    InitField(line_style,	  GCLineStyle,		LineSolid);
    InitField(cap_style,	  GCCapStyle,		0);
    InitField(join_style,	  GCJoinStyle,		0);
    InitField(fill_style,	  GCFillStyle,		FillSolid);
    InitField(fill_rule,	  GCFillRule,		WindingRule);
    InitField(arc_mode,		  GCArcMode,		ArcPieSlice);
    InitField(tile,		  GCTile,		None);
    InitField(stipple,		  GCStipple,		None);
    InitField(ts_x_origin,	  GCTileStipXOrigin,	0);
    InitField(ts_y_origin,	  GCTileStipYOrigin,	0);
    InitField(font,		  GCFont,		None);
    InitField(subwindow_mode,	  GCSubwindowMode,	ClipByChildren);
    InitField(graphics_exposures, GCGraphicsExposures,	True);
    InitField(clip_x_origin,	  GCClipXOrigin,	0);
    InitField(clip_y_origin,	  GCClipYOrigin,	0);
    InitField(dash_offset,	  GCDashOffset,		0);
    InitField(dashes,		  GCDashList,		4);
    (&(gp->dashes))[1] = 0;
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkpGCCache*
TkpGetGCCache(GC gc) {
    return (gc ? &((XGCValuesWithCache *)gc)->cache : NULL);

}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --







|
>







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkpGCCache*
TkpGetGCCache(GC gc) {
    return (gc ? (TkpGCCache*)(((char*) gc) + sizeof(XGCValues) +
	    MAX_DASH_LIST_SIZE) : NULL);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
 *----------------------------------------------------------------------
 */

int XFreeGC(
    Display *d,
    GC gc)
{
    (void)d;

    if (gc != NULL) {
	FreeClipMask(gc);
	TkpFreeGCCache(gc);
	ckfree(gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







<
<



|







265
266
267
268
269
270
271


272
273
274
275
276
277
278
279
280
281
282
 *----------------------------------------------------------------------
 */

int XFreeGC(
    Display *d,
    GC gc)
{


    if (gc != NULL) {
	FreeClipMask(gc);
	TkpFreeGCCache(gc);
	ckfree((char *) gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

int
XSetForeground(
    Display *display,
    GC gc,
    unsigned long foreground)
{
    (void)display;

    gc->foreground = foreground;
    return Success;
}

int
XSetBackground(
    Display *display,
    GC gc,
    unsigned long background)
{
    (void)display;

    gc->background = background;
    return Success;
}

int
XSetDashes(
    Display *display,
    GC gc,
    int dash_offset,
    _Xconst char *dash_list,
    int n)
{
    char *p = &(gc->dashes);
    (void)display;

#ifdef TkWinDeleteBrush
    TkWinDeleteBrush(gc->fgBrush);
    TkWinDeletePen(gc->fgPen);
    TkWinDeleteBrush(gc->bgBrush);
    TkWinDeletePen(gc->fgExtPen);
#endif







<
<










<
<













<







296
297
298
299
300
301
302


303
304
305
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332

int
XSetForeground(
    Display *display,
    GC gc,
    unsigned long foreground)
{


    gc->foreground = foreground;
    return Success;
}

int
XSetBackground(
    Display *display,
    GC gc,
    unsigned long background)
{


    gc->background = background;
    return Success;
}

int
XSetDashes(
    Display *display,
    GC gc,
    int dash_offset,
    _Xconst char *dash_list,
    int n)
{
    char *p = &(gc->dashes);


#ifdef TkWinDeleteBrush
    TkWinDeleteBrush(gc->fgBrush);
    TkWinDeletePen(gc->fgPen);
    TkWinDeleteBrush(gc->bgBrush);
    TkWinDeletePen(gc->fgExtPen);
#endif
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

int
XSetFunction(
    Display *display,
    GC gc,
    int function)
{
    (void)display;

    gc->function = function;
    return Success;
}

int
XSetFillRule(
    Display *display,
    GC gc,
    int fill_rule)
{
    (void)display;

    gc->fill_rule = fill_rule;
    return Success;
}

int
XSetFillStyle(
    Display *display,
    GC gc,
    int fill_style)
{
    (void)display;

    gc->fill_style = fill_style;
    return Success;
}

int
XSetTSOrigin(
    Display *display,
    GC gc,
    int x, int y)
{
    (void)display;

    gc->ts_x_origin = x;
    gc->ts_y_origin = y;
    return Success;
}

int
XSetFont(
    Display *display,
    GC gc,
    Font font)
{
    (void)display;

    gc->font = font;
    return Success;
}

int
XSetArcMode(
    Display *display,
    GC gc,
    int arc_mode)
{
    (void)display;

    gc->arc_mode = arc_mode;
    return Success;
}

int
XSetStipple(
    Display *display,
    GC gc,
    Pixmap stipple)
{
    (void)display;

    gc->stipple = stipple;
    return Success;
}

int
XSetLineAttributes(
    Display *display,
    GC gc,
    unsigned int line_width,
    int line_style,
    int cap_style,
    int join_style)
{
    (void)display;

    gc->line_width = line_width;
    gc->line_style = line_style;
    gc->cap_style = cap_style;
    gc->join_style = join_style;
    return Success;
}

int
XSetClipOrigin(
    Display *display,
    GC gc,
    int clip_x_origin,
    int clip_y_origin)
{
    (void)display;

    gc->clip_x_origin = clip_x_origin;
    gc->clip_y_origin = clip_y_origin;
    return Success;
}

/*
 *----------------------------------------------------------------------







<
<










<
<










<
<










<
<











<
<










<
<










<
<













<
<














<
<







341
342
343
344
345
346
347


348
349
350
351
352
353
354
355
356
357


358
359
360
361
362
363
364
365
366
367


368
369
370
371
372
373
374
375
376
377


378
379
380
381
382
383
384
385
386
387
388


389
390
391
392
393
394
395
396
397
398


399
400
401
402
403
404
405
406
407
408


409
410
411
412
413
414
415
416
417
418
419
420
421


422
423
424
425
426
427
428
429
430
431
432
433
434
435


436
437
438
439
440
441
442

int
XSetFunction(
    Display *display,
    GC gc,
    int function)
{


    gc->function = function;
    return Success;
}

int
XSetFillRule(
    Display *display,
    GC gc,
    int fill_rule)
{


    gc->fill_rule = fill_rule;
    return Success;
}

int
XSetFillStyle(
    Display *display,
    GC gc,
    int fill_style)
{


    gc->fill_style = fill_style;
    return Success;
}

int
XSetTSOrigin(
    Display *display,
    GC gc,
    int x, int y)
{


    gc->ts_x_origin = x;
    gc->ts_y_origin = y;
    return Success;
}

int
XSetFont(
    Display *display,
    GC gc,
    Font font)
{


    gc->font = font;
    return Success;
}

int
XSetArcMode(
    Display *display,
    GC gc,
    int arc_mode)
{


    gc->arc_mode = arc_mode;
    return Success;
}

int
XSetStipple(
    Display *display,
    GC gc,
    Pixmap stipple)
{


    gc->stipple = stipple;
    return Success;
}

int
XSetLineAttributes(
    Display *display,
    GC gc,
    unsigned int line_width,
    int line_style,
    int cap_style,
    int join_style)
{


    gc->line_width = line_width;
    gc->line_style = line_style;
    gc->cap_style = cap_style;
    gc->join_style = join_style;
    return Success;
}

int
XSetClipOrigin(
    Display *display,
    GC gc,
    int clip_x_origin,
    int clip_y_origin)
{


    gc->clip_x_origin = clip_x_origin;
    gc->clip_y_origin = clip_y_origin;
    return Success;
}

/*
 *----------------------------------------------------------------------
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
 *	uses of TkSetRegion are currently in DisplayFrame and in
 *	ImgPhotoDisplay, which use the GC immediately.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates or deallocates a TkpClipMask.
 *
 *----------------------------------------------------------------------
 */

int
TkSetRegion(
    Display *display,
    GC gc,
    TkRegion r)
{
    (void)display;

    if (r == NULL) {
	Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_REGION;
	clip_mask->value.region = r;



    }
    return Success;
}

int
XSetClipMask(
    Display *display,
    GC gc,
    Pixmap pixmap)
{
    (void)display;

    if (pixmap == None) {
	FreeClipMask(gc);
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = pixmap;







|




|





<
<







>
>
>

<








<
<







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467


468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486


487
488
489
490
491
492
493
 *	uses of TkSetRegion are currently in DisplayFrame and in
 *	ImgPhotoDisplay, which use the GC immediately.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates or dealloates a TkpClipMask.
 *
 *----------------------------------------------------------------------
 */

void
TkSetRegion(
    Display *display,
    GC gc,
    TkRegion r)
{


    if (r == NULL) {
	Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_REGION;
	clip_mask->value.region = r;
#ifdef MAC_OSX_TK
	TkpRetainRegion(r);
#endif
    }

}

int
XSetClipMask(
    Display *display,
    GC gc,
    Pixmap pixmap)
{


    if (pixmap == None) {
	FreeClipMask(gc);
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = pixmap;
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637

638
639











640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676


677


678
679





680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    int mode)
{
    int res = Success;
    (void)mode;

    while (npoints-- > 0) {
	res = XDrawLine(display, d, gc,
		points[0].x, points[0].y, points[0].x, points[0].y);
	if (res != Success) break;
	++points;
    }
    return res;
}

#if !defined(MAC_OSX_TK)
int
XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{
    (void)display;
    (void)d;
    (void)gc;
    (void)segments;
    (void)nsegments;

    return BadDrawable;
}
#endif


char *
XFetchBuffer(
    Display *display,
    int *nbytes_return,
    int buffer)
{
    (void)display;
    (void)nbytes_return;
    (void)buffer;

    return (char *) 0;
}

Status
XFetchName(
    Display *display,
    Window w,
    char **window_name_return)
{
    (void)display;
    (void)w;
    (void)window_name_return;

    return Success;
}

Atom *
XListProperties(
    Display* display,
    Window w,
    int *num_prop_return)
{
    (void)display;
    (void)w;
    (void)num_prop_return;

    return (Atom *) 0;
}

int
XMapRaised(
    Display *display,
    Window w)
{

    (void)display;
    (void)w;












    return Success;
}

int
XQueryTextExtents(
    Display *display,
    XID font_ID,
    _Xconst char *string,
    int nchars,
    int *direction_return,
    int *font_ascent_return,
    int *font_descent_return,
    XCharStruct *overall_return)
{
    (void)display;
    (void)font_ID;
    (void)string;
    (void)nchars;
    (void)direction_return;
    (void)font_ascent_return;
    (void)font_descent_return;
    (void)overall_return;

    return Success;
}

int
XReparentWindow(
    Display *display,
    Window w,
    Window parent,
    int x,
    int y)
{

    (void)display;
    (void)w;


    (void)parent;


    (void)x;
    (void)y;






    return BadWindow;
}

int
XUndefineCursor(
    Display *display,
    Window w)
{
    (void)display;
    (void)w;

    return Success;
}

XVaNestedList
XVaCreateNestedList(
    int unused, ...)
{
    (void)unused;
    return NULL;
}

char *
XSetICValues(
    XIC xic, ...)
{
    (void)xic;
    return NULL;
}

char *
XGetICValues(
    XIC xic, ...)
{
    (void)xic;
    return NULL;
}

void
XSetICFocus(
    XIC xic)
{
    (void)xic;
}

Window
XCreateWindow(
    Display *display,
	Window parent,
	int x,
	int y,
    unsigned int width,
	unsigned int height,
    unsigned int border_width,
	int depth,
	unsigned int clazz,
    Visual *visual,
	unsigned long value_mask,
    XSetWindowAttributes *attributes)
{
    (void)display;
    (void)parent;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)border_width;
    (void)depth;
    (void)clazz;
    (void)visual;
    (void)value_mask;
    (void)attributes;

	return 0;
}

int
XPointInRegion(
    Region rgn,
	int x,
	int y)
{
    (void)rgn;
    (void)x;
    (void)y;

	return 0;
}

int
XUnionRegion(
    Region srca,
	Region srcb,
	Region dr_return)
{
    (void)srca;
    (void)srcb;
    (void)dr_return;

	return 0;
}

Region
XPolygonRegion(
    XPoint *pts,
	int n,
	int rule)
{
    (void)pts;
    (void)n;
    (void)rule;

    return 0;
}

void
XDestroyIC(
    XIC ic)
{
    (void)ic;
}

Cursor
XCreatePixmapCursor(
    Display *display,
    Pixmap source,
    Pixmap mask,
    XColor *foreground_color,
    XColor *background_color,
    unsigned int x,
    unsigned int y)
{
    (void)display;
    (void)source;
    (void)mask;
    (void)foreground_color;
    (void)background_color;
    (void)x;
    (void)y;

    return (Cursor) NULL;
}

Cursor
XCreateGlyphCursor(
    Display *display,
    Font source_font,
    Font mask_font,
    unsigned int source_char,
    unsigned int mask_char,
    XColor _Xconst *foreground_color,
    XColor _Xconst *background_color)
{
    (void)display;
    (void)source_font;
    (void)mask_font;
    (void)source_char;
    (void)mask_char;
    (void)foreground_color;
    (void)background_color;

    return (Cursor) NULL;
}

XFontSet
XCreateFontSet(
    Display *display		/* display */,
    _Xconst char *base_font_name_list	/* base_font_name_list */,
    char ***missing_charset_list		/* missing_charset_list */,
    int *missing_charset_count		/* missing_charset_count */,
    char **def_string		/* def_string */
) {
    (void)display;
    (void)base_font_name_list;
    (void)missing_charset_list;
    (void)missing_charset_count;
    (void)def_string;

    return (XFontSet)0;
}

void
XFreeFontSet(
    Display *display,		/* display */
    XFontSet fontset		/* font_set */
) {
    (void)display;
    (void)fontset;
}

void
XFreeStringList(
    char **list		/* list */
) {
    (void)list;
}

Status
XCloseIM(
    XIM im /* im */
) {
    (void)im;

    return Success;
}

Bool
XRegisterIMInstantiateCallback(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */,
    XIDProc callback			/* callback */,
    XPointer client_data			/* client_data */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;
    (void)callback;
    (void)client_data;

    return False;
}

Bool
XUnregisterIMInstantiateCallback(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */,
    XIDProc callback			/* callback */,
    XPointer client_data			/* client_data */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;
    (void)callback;
    (void)client_data;

    return False;
}

char *
XSetLocaleModifiers(
    const char *modifier_list		/* modifier_list */
) {
    (void)modifier_list;

    return NULL;
}

XIM XOpenIM(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;

    return NULL;
}

char *
XGetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}

char *
XSetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<



















<
<
<
<
<
<
|



>






<
<
<
<









<
<
<
<
|








<
<
<
<



|




>
|
|
>
>
>
>
>
>
>
>
>
>
>
|
<


|










<
<
<
<
<
<
<
<
|
<
|
|
<







>
|
|
>
>
|
>
>
|
|
>
>
>
>
>
|
<


|




<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563






564
565
566
567
568
569
570
571
572
573
574




575
576
577
578
579
580
581
582
583




584
585
586
587
588
589
590
591
592




593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627
628








629

630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661


662


663














































































































































































































































































664
665
666
667
668
669
670
671
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    int mode)
{
    int res = Success;


    while (npoints-- > 0) {
	res = XDrawLine(display, d, gc,
		points[0].x, points[0].y, points[0].x, points[0].y);
	if (res != Success) break;
	++points;
    }
    return res;
}

#if !defined(MAC_OSX_TK)
int
XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{






    return Success;
}
#endif

#if 0
char *
XFetchBuffer(
    Display *display,
    int *nbytes_return,
    int buffer)
{




    return (char *) 0;
}

Status
XFetchName(
    Display *display,
    Window w,
    char **window_name_return)
{




    return (Status) 0;
}

Atom *
XListProperties(
    Display* display,
    Window w,
    int *num_prop_return)
{




    return (Atom *) 0;
}

void
XMapRaised(
    Display *display,
    Window w)
{
}

void
XPutImage(
    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)
{

}

void
XQueryTextExtents(
    Display *display,
    XID font_ID,
    _Xconst char *string,
    int nchars,
    int *direction_return,
    int *font_ascent_return,
    int *font_descent_return,
    XCharStruct *overall_return)
{








}


void

XReparentWindow(
    Display *display,
    Window w,
    Window parent,
    int x,
    int y)
{
}

void
XRotateBuffers(
    Display *display,
    int rotate)
{
}

void
XStoreBuffer(
    Display *display,
    _Xconst char *bytes,
    int nbytes,
    int buffer)
{

}

void
XUndefineCursor(
    Display *display,
    Window w)
{


}


#endif















































































































































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to xlib/xutil.c.

1
2
3
4
5
6
7
8
9
10
11

12



13
14
15
16
17
18
19
/*
 * xutil.c --
 *
 *	This function contains generic X emulation routines.
 *
 * 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.
 */


#include "tkInt.h"




/*
 *----------------------------------------------------------------------
 *
 * XInternAtom --
 *
 *	This procedure simulates the XInternAtom function by calling Tk_Uid to











>
|
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * xutil.c --
 *
 *	This function contains generic X emulation routines.
 *
 * 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.
 */

#include <stdlib.h>
#include <tk.h>

#include <X11/Xutil.h>
#include <X11/Xatom.h>

/*
 *----------------------------------------------------------------------
 *
 * XInternAtom --
 *
 *	This procedure simulates the XInternAtom function by calling Tk_Uid to
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Atom
XInternAtom(
    Display *display,
    _Xconst char *atom_name,
    Bool only_if_exists)
{
    static Atom atom = XA_LAST_PREDEFINED;
    (void)atom_name;
    (void)only_if_exists;

    display->request++;
    return ++atom;
}

/*
 *----------------------------------------------------------------------







<
<







36
37
38
39
40
41
42


43
44
45
46
47
48
49
Atom
XInternAtom(
    Display *display,
    _Xconst char *atom_name,
    Bool only_if_exists)
{
    static Atom atom = XA_LAST_PREDEFINED;



    display->request++;
    return ++atom;
}

/*
 *----------------------------------------------------------------------
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
XVisualInfo *
XGetVisualInfo(
    Display *display,
    long vinfo_mask,
    XVisualInfo *vinfo_template,
    int *nitems_return)
{
    XVisualInfo *info = (XVisualInfo *)ckalloc(sizeof(XVisualInfo));

    info->visual = DefaultVisual(display, 0);
    info->visualid = info->visual->visualid;
    info->screen = 0;
    info->depth = info->visual->bits_per_rgb;
    info->c_class = info->visual->c_class;
    info->colormap_size = info->visual->map_entries;
    info->bits_per_rgb = info->visual->bits_per_rgb;
    info->red_mask = info->visual->red_mask;
    info->green_mask = info->visual->green_mask;
    info->blue_mask = info->visual->blue_mask;

    if (((vinfo_mask & VisualIDMask)
	    && (vinfo_template->visualid != info->visualid))
	    || ((vinfo_mask & VisualScreenMask)
		    && (vinfo_template->screen != info->screen))
	    || ((vinfo_mask & VisualDepthMask)
		    && (vinfo_template->depth != info->depth))
	    || ((vinfo_mask & VisualClassMask)
		    && (vinfo_template->c_class != info->c_class))
	    || ((vinfo_mask & VisualColormapSizeMask)
		    && (vinfo_template->colormap_size != info->colormap_size))
	    || ((vinfo_mask & VisualBitsPerRGBMask)
		    && (vinfo_template->bits_per_rgb != info->bits_per_rgb))
	    || ((vinfo_mask & VisualRedMaskMask)
		    && (vinfo_template->red_mask != info->red_mask))
	    || ((vinfo_mask & VisualGreenMaskMask)
		    && (vinfo_template->green_mask != info->green_mask))
	    || ((vinfo_mask & VisualBlueMaskMask)
		    && (vinfo_template->blue_mask != info->blue_mask))
	) {
	ckfree(info);
	return NULL;
    }

    *nitems_return = 1;
    return info;
}








|
<




|













|











|







64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
XVisualInfo *
XGetVisualInfo(
    Display *display,
    long vinfo_mask,
    XVisualInfo *vinfo_template,
    int *nitems_return)
{
    XVisualInfo *info = (XVisualInfo *) ckalloc(sizeof(XVisualInfo));

    info->visual = DefaultVisual(display, 0);
    info->visualid = info->visual->visualid;
    info->screen = 0;
    info->depth = info->visual->bits_per_rgb;
    info->class = info->visual->class;
    info->colormap_size = info->visual->map_entries;
    info->bits_per_rgb = info->visual->bits_per_rgb;
    info->red_mask = info->visual->red_mask;
    info->green_mask = info->visual->green_mask;
    info->blue_mask = info->visual->blue_mask;

    if (((vinfo_mask & VisualIDMask)
	    && (vinfo_template->visualid != info->visualid))
	    || ((vinfo_mask & VisualScreenMask)
		    && (vinfo_template->screen != info->screen))
	    || ((vinfo_mask & VisualDepthMask)
		    && (vinfo_template->depth != info->depth))
	    || ((vinfo_mask & VisualClassMask)
		    && (vinfo_template->class != info->class))
	    || ((vinfo_mask & VisualColormapSizeMask)
		    && (vinfo_template->colormap_size != info->colormap_size))
	    || ((vinfo_mask & VisualBitsPerRGBMask)
		    && (vinfo_template->bits_per_rgb != info->bits_per_rgb))
	    || ((vinfo_mask & VisualRedMaskMask)
		    && (vinfo_template->red_mask != info->red_mask))
	    || ((vinfo_mask & VisualGreenMaskMask)
		    && (vinfo_template->green_mask != info->green_mask))
	    || ((vinfo_mask & VisualBlueMaskMask)
		    && (vinfo_template->blue_mask != info->blue_mask))
	) {
	ckfree((char *) info);
	return NULL;
    }

    *nitems_return = 1;
    return info;
}